summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnas Nashif <anas.nashif@intel.com>2012-10-30 15:39:57 -0700
committerAnas Nashif <anas.nashif@intel.com>2012-10-30 15:39:57 -0700
commit035c7fabc3b82cbc9a346c11abe2e9462b4c0379 (patch)
tree7e40f5a790eae329a8c5d3e59f046451767956ff
downloadcmake-035c7fabc3b82cbc9a346c11abe2e9462b4c0379.tar.gz
cmake-035c7fabc3b82cbc9a346c11abe2e9462b4c0379.tar.bz2
cmake-035c7fabc3b82cbc9a346c11abe2e9462b4c0379.zip
Imported Upstream version 2.8.9upstream/2.8.9
-rw-r--r--.gitattributes22
-rw-r--r--.hooks-config.bash18
-rw-r--r--CMakeCPack.cmake123
-rw-r--r--CMakeCPackOptions.cmake.in53
-rw-r--r--CMakeGraphVizOptions.cmake1
-rw-r--r--CMakeLists.txt634
-rw-r--r--CMakeLogo.gifbin0 -> 4481 bytes
-rw-r--r--CTestConfig.cmake25
-rw-r--r--CTestCustom.cmake.in85
-rw-r--r--CTestCustom.ctest.in3
-rw-r--r--ChangeLog.manual3522
-rw-r--r--ChangeLog.txt86670
-rw-r--r--CompileFlags.cmake64
-rw-r--r--Copyright.txt56
-rw-r--r--DartConfig.cmake18
-rw-r--r--DartLocal.conf.in121
-rw-r--r--Docs/CMakeLists.txt4
-rw-r--r--Docs/bash-completion/CMakeLists.txt8
-rw-r--r--Docs/bash-completion/cmake149
-rw-r--r--Docs/bash-completion/cpack61
-rw-r--r--Docs/bash-completion/ctest81
-rw-r--r--Docs/cmake-help.vim21
-rw-r--r--Docs/cmake-indent.vim93
-rw-r--r--Docs/cmake-mode.el340
-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--Modules/AddFileDependencies.cmake29
-rw-r--r--Modules/AutomocInfo.cmake.in16
-rw-r--r--Modules/BasicConfigVersion-AnyNewerVersion.cmake.in31
-rw-r--r--Modules/BasicConfigVersion-ExactVersion.cmake.in47
-rw-r--r--Modules/BasicConfigVersion-SameMajorVersion.cmake.in46
-rw-r--r--Modules/BundleUtilities.cmake786
-rw-r--r--Modules/CMake.cmake17
-rw-r--r--Modules/CMakeASM-ATTInformation.cmake25
-rw-r--r--Modules/CMakeASMCompiler.cmake.in12
-rw-r--r--Modules/CMakeASMInformation.cmake130
-rw-r--r--Modules/CMakeASM_MASMInformation.cmake24
-rw-r--r--Modules/CMakeASM_NASMInformation.cmake46
-rw-r--r--Modules/CMakeAddFortranSubdirectory.cmake206
-rw-r--r--Modules/CMakeAddFortranSubdirectory/build_mingw.cmake.in2
-rw-r--r--Modules/CMakeAddFortranSubdirectory/config_mingw.cmake.in9
-rw-r--r--Modules/CMakeAddNewLanguage.txt17
-rw-r--r--Modules/CMakeBackwardCompatibilityC.cmake100
-rw-r--r--Modules/CMakeBackwardCompatibilityCXX.cmake54
-rw-r--r--Modules/CMakeBorlandFindMake.cmake17
-rw-r--r--Modules/CMakeBuildSettings.cmake.in13
-rw-r--r--Modules/CMakeCCompiler.cmake.in53
-rw-r--r--Modules/CMakeCCompilerABI.c28
-rw-r--r--Modules/CMakeCCompilerId.c.in204
-rw-r--r--Modules/CMakeCInformation.cmake219
-rw-r--r--Modules/CMakeCXXCompiler.cmake.in54
-rw-r--r--Modules/CMakeCXXCompilerABI.cpp20
-rw-r--r--Modules/CMakeCXXCompilerId.cpp.in187
-rw-r--r--Modules/CMakeCXXInformation.cmake299
-rw-r--r--Modules/CMakeClDeps.cmake37
-rw-r--r--Modules/CMakeCommonLanguageInclude.cmake107
-rw-r--r--Modules/CMakeCompilerABI.h36
-rw-r--r--Modules/CMakeConfigurableFile.in2
-rw-r--r--Modules/CMakeDependentOption.cmake51
-rw-r--r--Modules/CMakeDetermineASM-ATTCompiler.cmake20
-rw-r--r--Modules/CMakeDetermineASMCompiler.cmake182
-rw-r--r--Modules/CMakeDetermineASM_MASMCompiler.cmake27
-rw-r--r--Modules/CMakeDetermineASM_NASMCompiler.cmake27
-rw-r--r--Modules/CMakeDetermineCCompiler.cmake179
-rw-r--r--Modules/CMakeDetermineCXXCompiler.cmake188
-rw-r--r--Modules/CMakeDetermineCompilerABI.cmake131
-rw-r--r--Modules/CMakeDetermineCompilerId.cmake323
-rw-r--r--Modules/CMakeDetermineFortranCompiler.cmake228
-rw-r--r--Modules/CMakeDetermineJavaCompiler.cmake102
-rw-r--r--Modules/CMakeDetermineRCCompiler.cmake67
-rw-r--r--Modules/CMakeDetermineSystem.cmake176
-rw-r--r--Modules/CMakeDetermineVSServicePack.cmake187
-rw-r--r--Modules/CMakeExpandImportedTargets.cmake129
-rw-r--r--Modules/CMakeExportBuildSettings.cmake36
-rw-r--r--Modules/CMakeExtraGeneratorDetermineCompilerMacrosAndIncludeDirs.cmake109
-rw-r--r--Modules/CMakeFindBinUtils.cmake75
-rw-r--r--Modules/CMakeFindCodeBlocks.cmake25
-rw-r--r--Modules/CMakeFindEclipseCDT4.cmake79
-rw-r--r--Modules/CMakeFindFrameworks.cmake32
-rw-r--r--Modules/CMakeFindKDevelop3.cmake23
-rw-r--r--Modules/CMakeFindPackageMode.cmake188
-rw-r--r--Modules/CMakeFindWMake.cmake17
-rw-r--r--Modules/CMakeFindXCode.cmake20
-rw-r--r--Modules/CMakeForceCompiler.cmake82
-rw-r--r--Modules/CMakeFortranCompiler.cmake.in52
-rw-r--r--Modules/CMakeFortranCompilerABI.F38
-rw-r--r--Modules/CMakeFortranCompilerId.F.in123
-rw-r--r--Modules/CMakeFortranInformation.cmake245
-rw-r--r--Modules/CMakeGenericSystem.cmake187
-rw-r--r--Modules/CMakeImportBuildSettings.cmake24
-rw-r--r--Modules/CMakeJOMFindMake.cmake18
-rw-r--r--Modules/CMakeJavaCompiler.cmake.in13
-rw-r--r--Modules/CMakeJavaInformation.cmake59
-rw-r--r--Modules/CMakeMSYSFindMake.cmake20
-rw-r--r--Modules/CMakeMinGWFindMake.cmake24
-rw-r--r--Modules/CMakeNMakeFindMake.cmake18
-rw-r--r--Modules/CMakeNinjaFindMake.cmake17
-rw-r--r--Modules/CMakePackageConfigHelpers.cmake227
-rw-r--r--Modules/CMakeParseArguments.cmake138
-rw-r--r--Modules/CMakeParseImplicitLinkInfo.cmake128
-rw-r--r--Modules/CMakePlatformId.h.in157
-rw-r--r--Modules/CMakePrintSystemInformation.cmake46
-rw-r--r--Modules/CMakePushCheckState.cmake61
-rw-r--r--Modules/CMakeRCCompiler.cmake.in6
-rw-r--r--Modules/CMakeRCInformation.cmake53
-rw-r--r--Modules/CMakeSystem.cmake.in15
-rw-r--r--Modules/CMakeSystemSpecificInformation.cmake69
-rw-r--r--Modules/CMakeTestASM-ATTCompiler.cmake23
-rw-r--r--Modules/CMakeTestASMCompiler.cmake35
-rw-r--r--Modules/CMakeTestASM_MASMCompiler.cmake23
-rw-r--r--Modules/CMakeTestASM_NASMCompiler.cmake23
-rw-r--r--Modules/CMakeTestCCompiler.cmake87
-rw-r--r--Modules/CMakeTestCXXCompiler.cmake80
-rw-r--r--Modules/CMakeTestCompilerCommon.cmake21
-rw-r--r--Modules/CMakeTestForFreeVC.cxx3
-rw-r--r--Modules/CMakeTestFortranCompiler.cmake101
-rw-r--r--Modules/CMakeTestGNU.c9
-rw-r--r--Modules/CMakeTestJavaCompiler.cmake20
-rw-r--r--Modules/CMakeTestNMakeCLVersion.c2
-rw-r--r--Modules/CMakeTestRCCompiler.cmake23
-rw-r--r--Modules/CMakeTestWatcomVersion.c1
-rw-r--r--Modules/CMakeUnixFindMake.cmake16
-rw-r--r--Modules/CMakeVS10FindMake.cmake54
-rw-r--r--Modules/CMakeVS11FindMake.cmake54
-rw-r--r--Modules/CMakeVS6BackwardCompatibility.cmake26
-rw-r--r--Modules/CMakeVS6FindMake.cmake25
-rw-r--r--Modules/CMakeVS71FindMake.cmake26
-rw-r--r--Modules/CMakeVS7BackwardCompatibility.cmake26
-rw-r--r--Modules/CMakeVS7FindMake.cmake25
-rw-r--r--Modules/CMakeVS8FindMake.cmake34
-rw-r--r--Modules/CMakeVS9FindMake.cmake39
-rw-r--r--Modules/CMakeVerifyManifest.cmake115
-rw-r--r--Modules/CPack.DS_Store.inbin0 -> 12292 bytes
-rw-r--r--Modules/CPack.Description.plist.in12
-rw-r--r--Modules/CPack.Info.plist.in37
-rwxr-xr-xModules/CPack.OSXScriptLauncher.inbin0 -> 29592 bytes
-rw-r--r--Modules/CPack.OSXScriptLauncher.rsrc.inbin0 -> 362 bytes
-rw-r--r--Modules/CPack.OSXX11.Info.plist.in49
-rw-r--r--Modules/CPack.OSXX11.main.scpt.inbin0 -> 1870 bytes
-rwxr-xr-xModules/CPack.RuntimeScript.in87
-rwxr-xr-xModules/CPack.STGZ_Header.sh.in141
-rw-r--r--Modules/CPack.VolumeIcon.icns.inbin0 -> 45739 bytes
-rw-r--r--Modules/CPack.background.png.inbin0 -> 47076 bytes
-rw-r--r--Modules/CPack.cmake579
-rw-r--r--Modules/CPack.distribution.dist.in9
-rw-r--r--Modules/CPackBundle.cmake48
-rw-r--r--Modules/CPackComponent.cmake513
-rw-r--r--Modules/CPackCygwin.cmake33
-rw-r--r--Modules/CPackDMG.cmake70
-rw-r--r--Modules/CPackDeb.cmake421
-rw-r--r--Modules/CPackNSIS.cmake147
-rw-r--r--Modules/CPackPackageMaker.cmake35
-rw-r--r--Modules/CPackRPM.cmake925
-rw-r--r--Modules/CPackZIP.cmake41
-rw-r--r--Modules/CTest.cmake286
-rw-r--r--Modules/CTestScriptMode.cmake24
-rw-r--r--Modules/CTestTargets.cmake95
-rw-r--r--Modules/CheckCCompilerFlag.cmake45
-rw-r--r--Modules/CheckCSourceCompiles.cmake95
-rw-r--r--Modules/CheckCSourceRuns.cmake91
-rw-r--r--Modules/CheckCXXCompilerFlag.cmake48
-rw-r--r--Modules/CheckCXXSourceCompiles.cmake96
-rw-r--r--Modules/CheckCXXSourceRuns.cmake91
-rw-r--r--Modules/CheckCXXSymbolExists.cmake42
-rw-r--r--Modules/CheckForPthreads.c38
-rw-r--r--Modules/CheckFortranFunctionExists.cmake69
-rw-r--r--Modules/CheckFunctionExists.c23
-rw-r--r--Modules/CheckFunctionExists.cmake74
-rw-r--r--Modules/CheckIncludeFile.c.in13
-rw-r--r--Modules/CheckIncludeFile.cmake77
-rw-r--r--Modules/CheckIncludeFile.cxx.in6
-rw-r--r--Modules/CheckIncludeFileCXX.cmake77
-rw-r--r--Modules/CheckIncludeFiles.cmake82
-rw-r--r--Modules/CheckLanguage.cmake65
-rw-r--r--Modules/CheckLibraryExists.cmake70
-rw-r--r--Modules/CheckLibraryExists.lists.in8
-rw-r--r--Modules/CheckPrototypeDefinition.c.in29
-rw-r--r--Modules/CheckPrototypeDefinition.cmake101
-rw-r--r--Modules/CheckSizeOf.cmake18
-rw-r--r--Modules/CheckStructHasMember.cmake51
-rw-r--r--Modules/CheckSymbolExists.cmake101
-rw-r--r--Modules/CheckTypeSize.c.in37
-rw-r--r--Modules/CheckTypeSize.cmake196
-rw-r--r--Modules/CheckTypeSizeMap.cmake.in1
-rw-r--r--Modules/CheckVariableExists.c20
-rw-r--r--Modules/CheckVariableExists.cmake66
-rw-r--r--Modules/Compiler/Absoft-Fortran.cmake10
-rw-r--r--Modules/Compiler/Clang-C.cmake1
-rw-r--r--Modules/Compiler/Clang-CXX.cmake1
-rw-r--r--Modules/Compiler/Cray-C.cmake1
-rw-r--r--Modules/Compiler/Cray-CXX.cmake1
-rw-r--r--Modules/Compiler/Cray-Fortran.cmake6
-rw-r--r--Modules/Compiler/G95-Fortran.cmake9
-rw-r--r--Modules/Compiler/GNU-ASM.cmake6
-rw-r--r--Modules/Compiler/GNU-C.cmake2
-rw-r--r--Modules/Compiler/GNU-CXX.cmake2
-rw-r--r--Modules/Compiler/GNU-Fortran.cmake17
-rw-r--r--Modules/Compiler/GNU.cmake54
-rw-r--r--Modules/Compiler/HP-ASM.cmake3
-rw-r--r--Modules/Compiler/HP-C.cmake4
-rw-r--r--Modules/Compiler/HP-CXX.cmake4
-rw-r--r--Modules/Compiler/HP-Fortran.cmake3
-rw-r--r--Modules/Compiler/Intel-ASM.cmake13
-rw-r--r--Modules/Compiler/Intel-C.cmake10
-rw-r--r--Modules/Compiler/Intel-CXX.cmake10
-rw-r--r--Modules/Compiler/Intel-Fortran.cmake9
-rw-r--r--Modules/Compiler/MIPSpro-C.cmake1
-rw-r--r--Modules/Compiler/MIPSpro-CXX.cmake1
-rw-r--r--Modules/Compiler/MIPSpro-Fortran.cmake3
-rw-r--r--Modules/Compiler/NAG-Fortran.cmake34
-rw-r--r--Modules/Compiler/PGI-C.cmake4
-rw-r--r--Modules/Compiler/PGI-CXX.cmake4
-rw-r--r--Modules/Compiler/PGI-Fortran.cmake15
-rw-r--r--Modules/Compiler/PGI.cmake35
-rw-r--r--Modules/Compiler/PathScale-C.cmake4
-rw-r--r--Modules/Compiler/PathScale-CXX.cmake4
-rw-r--r--Modules/Compiler/PathScale-Fortran.cmake6
-rw-r--r--Modules/Compiler/PathScale.cmake31
-rw-r--r--Modules/Compiler/SCO-C.cmake2
-rw-r--r--Modules/Compiler/SCO-CXX.cmake2
-rw-r--r--Modules/Compiler/SCO.cmake28
-rw-r--r--Modules/Compiler/SunPro-ASM.cmake24
-rw-r--r--Modules/Compiler/SunPro-C.cmake27
-rw-r--r--Modules/Compiler/SunPro-CXX.cmake33
-rw-r--r--Modules/Compiler/SunPro-Fortran.cmake18
-rw-r--r--Modules/Compiler/TinyCC-C.cmake8
-rw-r--r--Modules/Compiler/VisualAge-C.cmake1
-rw-r--r--Modules/Compiler/VisualAge-CXX.cmake1
-rw-r--r--Modules/Compiler/VisualAge-Fortran.cmake1
-rw-r--r--Modules/Compiler/XL-ASM.cmake13
-rw-r--r--Modules/Compiler/XL-C.cmake9
-rw-r--r--Modules/Compiler/XL-CXX.cmake11
-rw-r--r--Modules/Compiler/XL-Fortran.cmake17
-rw-r--r--Modules/Compiler/XL.cmake53
-rw-r--r--Modules/Dart.cmake124
-rw-r--r--Modules/DartConfiguration.tcl.in93
-rw-r--r--Modules/DeployQt4.cmake301
-rw-r--r--Modules/Documentation.cmake52
-rw-r--r--Modules/DummyCXXFile.cxx4
-rw-r--r--Modules/ExternalProject.cmake1553
-rw-r--r--Modules/FLTKCompatibility.cmake15
-rw-r--r--Modules/FeatureSummary.cmake466
-rw-r--r--Modules/FindALSA.cmake55
-rw-r--r--Modules/FindASPELL.cmake37
-rw-r--r--Modules/FindAVIFile.cmake48
-rw-r--r--Modules/FindArmadillo.cmake95
-rw-r--r--Modules/FindBISON.cmake175
-rw-r--r--Modules/FindBLAS.cmake606
-rw-r--r--Modules/FindBZip2.cmake56
-rw-r--r--Modules/FindBoost.cmake1211
-rw-r--r--Modules/FindBullet.cmake84
-rw-r--r--Modules/FindCABLE.cmake81
-rw-r--r--Modules/FindCUDA.cmake1367
-rw-r--r--Modules/FindCUDA/make2cmake.cmake93
-rw-r--r--Modules/FindCUDA/parse_cubin.cmake112
-rw-r--r--Modules/FindCUDA/run_nvcc.cmake280
-rw-r--r--Modules/FindCURL.cmake59
-rw-r--r--Modules/FindCVS.cmake69
-rw-r--r--Modules/FindCoin3D.cmake84
-rw-r--r--Modules/FindCups.cmake69
-rw-r--r--Modules/FindCurses.cmake176
-rw-r--r--Modules/FindCxxTest.cmake200
-rw-r--r--Modules/FindCygwin.cmake28
-rw-r--r--Modules/FindDCMTK.cmake154
-rw-r--r--Modules/FindDart.cmake36
-rw-r--r--Modules/FindDevIL.cmake74
-rw-r--r--Modules/FindDoxygen.cmake144
-rw-r--r--Modules/FindEXPAT.cmake60
-rw-r--r--Modules/FindFLEX.cmake161
-rw-r--r--Modules/FindFLTK.cmake309
-rw-r--r--Modules/FindFLTK2.cmake267
-rw-r--r--Modules/FindFreetype.cmake110
-rw-r--r--Modules/FindGCCXML.cmake27
-rw-r--r--Modules/FindGDAL.cmake107
-rw-r--r--Modules/FindGIF.cmake80
-rw-r--r--Modules/FindGLU.cmake28
-rw-r--r--Modules/FindGLUT.cmake90
-rw-r--r--Modules/FindGTK.cmake165
-rw-r--r--Modules/FindGTK2.cmake590
-rw-r--r--Modules/FindGTest.cmake158
-rw-r--r--Modules/FindGettext.cmake220
-rw-r--r--Modules/FindGit.cmake62
-rw-r--r--Modules/FindGnuTLS.cmake69
-rw-r--r--Modules/FindGnuplot.cmake57
-rw-r--r--Modules/FindHDF5.cmake385
-rw-r--r--Modules/FindHSPELL.cmake46
-rw-r--r--Modules/FindHTMLHelp.cmake54
-rw-r--r--Modules/FindITK.cmake57
-rw-r--r--Modules/FindImageMagick.cmake237
-rw-r--r--Modules/FindJNI.cmake261
-rw-r--r--Modules/FindJPEG.cmake43
-rw-r--r--Modules/FindJasper.cmake53
-rw-r--r--Modules/FindJava.cmake204
-rw-r--r--Modules/FindKDE3.cmake299
-rw-r--r--Modules/FindKDE4.cmake100
-rw-r--r--Modules/FindLAPACK.cmake336
-rw-r--r--Modules/FindLATEX.cmake126
-rw-r--r--Modules/FindLibArchive.cmake67
-rw-r--r--Modules/FindLibLZMA.cmake69
-rw-r--r--Modules/FindLibXml2.cmake66
-rw-r--r--Modules/FindLibXslt.cmake74
-rw-r--r--Modules/FindLua50.cmake90
-rw-r--r--Modules/FindLua51.cmake81
-rw-r--r--Modules/FindMFC.cmake60
-rw-r--r--Modules/FindMPEG.cmake44
-rw-r--r--Modules/FindMPEG2.cmake54
-rw-r--r--Modules/FindMPI.cmake631
-rw-r--r--Modules/FindMatlab.cmake120
-rw-r--r--Modules/FindMotif.cmake44
-rw-r--r--Modules/FindOpenAL.cmake99
-rw-r--r--Modules/FindOpenGL.cmake160
-rw-r--r--Modules/FindOpenMP.cmake167
-rw-r--r--Modules/FindOpenSSL.cmake304
-rw-r--r--Modules/FindOpenSceneGraph.cmake246
-rw-r--r--Modules/FindOpenThreads.cmake123
-rw-r--r--Modules/FindPHP4.cmake85
-rw-r--r--Modules/FindPNG.cmake75
-rw-r--r--Modules/FindPackageHandleStandardArgs.cmake296
-rw-r--r--Modules/FindPackageMessage.cmake49
-rw-r--r--Modules/FindPerl.cmake83
-rw-r--r--Modules/FindPerlLibs.cmake255
-rw-r--r--Modules/FindPhysFS.cmake57
-rw-r--r--Modules/FindPike.cmake37
-rw-r--r--Modules/FindPkgConfig.cmake373
-rw-r--r--Modules/FindPostgreSQL.cmake172
-rw-r--r--Modules/FindProducer.cmake78
-rw-r--r--Modules/FindProtobuf.cmake218
-rw-r--r--Modules/FindPythonInterp.cmake141
-rw-r--r--Modules/FindPythonLibs.cmake275
-rw-r--r--Modules/FindQt.cmake160
-rw-r--r--Modules/FindQt3.cmake302
-rw-r--r--Modules/FindQt4.cmake1216
-rw-r--r--Modules/FindQuickTime.cmake47
-rw-r--r--Modules/FindRTI.cmake102
-rw-r--r--Modules/FindRuby.cmake243
-rw-r--r--Modules/FindSDL.cmake173
-rw-r--r--Modules/FindSDL_image.cmake70
-rw-r--r--Modules/FindSDL_mixer.cmake70
-rw-r--r--Modules/FindSDL_net.cmake69
-rw-r--r--Modules/FindSDL_sound.cmake401
-rw-r--r--Modules/FindSDL_ttf.cmake70
-rw-r--r--Modules/FindSWIG.cmake68
-rw-r--r--Modules/FindSelfPackers.cmake68
-rw-r--r--Modules/FindSquish.cmake125
-rw-r--r--Modules/FindSubversion.cmake131
-rw-r--r--Modules/FindTCL.cmake215
-rw-r--r--Modules/FindTIFF.cmake48
-rw-r--r--Modules/FindTclStub.cmake130
-rw-r--r--Modules/FindTclsh.cmake100
-rw-r--r--Modules/FindThreads.cmake166
-rw-r--r--Modules/FindUnixCommands.cmake93
-rw-r--r--Modules/FindVTK.cmake141
-rw-r--r--Modules/FindWget.cmake36
-rw-r--r--Modules/FindWish.cmake85
-rw-r--r--Modules/FindX11.cmake492
-rw-r--r--Modules/FindXMLRPC.cmake146
-rw-r--r--Modules/FindZLIB.cmake92
-rw-r--r--Modules/Findosg.cmake54
-rw-r--r--Modules/FindosgAnimation.cmake51
-rw-r--r--Modules/FindosgDB.cmake51
-rw-r--r--Modules/FindosgFX.cmake51
-rw-r--r--Modules/FindosgGA.cmake51
-rw-r--r--Modules/FindosgIntrospection.cmake51
-rw-r--r--Modules/FindosgManipulator.cmake51
-rw-r--r--Modules/FindosgParticle.cmake51
-rw-r--r--Modules/FindosgPresentation.cmake52
-rw-r--r--Modules/FindosgProducer.cmake51
-rw-r--r--Modules/FindosgQt.cmake52
-rw-r--r--Modules/FindosgShadow.cmake51
-rw-r--r--Modules/FindosgSim.cmake51
-rw-r--r--Modules/FindosgTerrain.cmake51
-rw-r--r--Modules/FindosgText.cmake51
-rw-r--r--Modules/FindosgUtil.cmake51
-rw-r--r--Modules/FindosgViewer.cmake51
-rw-r--r--Modules/FindosgVolume.cmake51
-rw-r--r--Modules/FindosgWidget.cmake51
-rw-r--r--Modules/Findosg_functions.cmake105
-rw-r--r--Modules/FindwxWidgets.cmake1044
-rw-r--r--Modules/FindwxWindows.cmake706
-rw-r--r--Modules/FortranCInterface.cmake293
-rw-r--r--Modules/FortranCInterface/CMakeLists.txt108
-rw-r--r--Modules/FortranCInterface/Detect.cmake183
-rw-r--r--Modules/FortranCInterface/Input.cmake.in3
-rw-r--r--Modules/FortranCInterface/Macro.h.in4
-rw-r--r--Modules/FortranCInterface/Output.cmake.in33
-rw-r--r--Modules/FortranCInterface/Verify/CMakeLists.txt34
-rw-r--r--Modules/FortranCInterface/Verify/VerifyC.c5
-rw-r--r--Modules/FortranCInterface/Verify/VerifyCXX.cxx4
-rw-r--r--Modules/FortranCInterface/Verify/VerifyFortran.f3
-rw-r--r--Modules/FortranCInterface/Verify/main.c16
-rw-r--r--Modules/FortranCInterface/call_mod.f906
-rw-r--r--Modules/FortranCInterface/call_sub.f4
-rw-r--r--Modules/FortranCInterface/main.F6
-rw-r--r--Modules/FortranCInterface/my_module.f908
-rw-r--r--Modules/FortranCInterface/my_module_.c1
-rw-r--r--Modules/FortranCInterface/my_sub.f2
-rw-r--r--Modules/FortranCInterface/mymodule.f908
-rw-r--r--Modules/FortranCInterface/mymodule_.c1
-rw-r--r--Modules/FortranCInterface/mysub.f2
-rw-r--r--Modules/FortranCInterface/symbol.c.in4
-rw-r--r--Modules/GNUInstallDirs.cmake188
-rw-r--r--Modules/GenerateExportHeader.cmake351
-rw-r--r--Modules/GetPrerequisites.cmake877
-rw-r--r--Modules/ITKCompatibility.cmake17
-rw-r--r--Modules/InstallRequiredSystemLibraries.cmake401
-rw-r--r--Modules/IntelVSImplicitPath/CMakeLists.txt7
-rw-r--r--Modules/IntelVSImplicitPath/detect.cmake9
-rw-r--r--Modules/IntelVSImplicitPath/hello.f0
-rw-r--r--Modules/KDE3Macros.cmake411
-rw-r--r--Modules/MacOSXBundleInfo.plist.in36
-rw-r--r--Modules/MacOSXFrameworkInfo.plist.in26
-rw-r--r--Modules/MacroAddFileDependencies.cmake33
-rw-r--r--Modules/NSIS.InstallOptions.ini.in46
-rw-r--r--Modules/NSIS.template.in972
-rw-r--r--Modules/Platform/AIX-GNU-ASM.cmake2
-rw-r--r--Modules/Platform/AIX-GNU-C.cmake2
-rw-r--r--Modules/Platform/AIX-GNU-CXX.cmake2
-rw-r--r--Modules/Platform/AIX-GNU-Fortran.cmake2
-rw-r--r--Modules/Platform/AIX-GNU.cmake26
-rw-r--r--Modules/Platform/AIX-VisualAge-C.cmake1
-rw-r--r--Modules/Platform/AIX-VisualAge-CXX.cmake1
-rw-r--r--Modules/Platform/AIX-VisualAge-Fortran.cmake1
-rw-r--r--Modules/Platform/AIX-XL-ASM.cmake2
-rw-r--r--Modules/Platform/AIX-XL-C.cmake2
-rw-r--r--Modules/Platform/AIX-XL-CXX.cmake2
-rw-r--r--Modules/Platform/AIX-XL-Fortran.cmake2
-rw-r--r--Modules/Platform/AIX-XL.cmake28
-rw-r--r--Modules/Platform/AIX.cmake29
-rw-r--r--Modules/Platform/BSDOS.cmake2
-rw-r--r--Modules/Platform/BeOS.cmake12
-rw-r--r--Modules/Platform/BlueGeneL.cmake40
-rw-r--r--Modules/Platform/BlueGeneP-base.cmake125
-rw-r--r--Modules/Platform/BlueGeneP-dynamic-GNU-C.cmake16
-rw-r--r--Modules/Platform/BlueGeneP-dynamic-GNU-CXX.cmake16
-rw-r--r--Modules/Platform/BlueGeneP-dynamic-GNU-Fortran.cmake16
-rw-r--r--Modules/Platform/BlueGeneP-dynamic-XL-C.cmake16
-rw-r--r--Modules/Platform/BlueGeneP-dynamic-XL-CXX.cmake16
-rw-r--r--Modules/Platform/BlueGeneP-dynamic-XL-Fortran.cmake16
-rw-r--r--Modules/Platform/BlueGeneP-dynamic.cmake19
-rw-r--r--Modules/Platform/BlueGeneP-static-GNU-C.cmake16
-rw-r--r--Modules/Platform/BlueGeneP-static-GNU-CXX.cmake16
-rw-r--r--Modules/Platform/BlueGeneP-static-GNU-Fortran.cmake16
-rw-r--r--Modules/Platform/BlueGeneP-static-XL-C.cmake16
-rw-r--r--Modules/Platform/BlueGeneP-static-XL-CXX.cmake16
-rw-r--r--Modules/Platform/BlueGeneP-static-XL-Fortran.cmake16
-rw-r--r--Modules/Platform/BlueGeneP-static.cmake19
-rw-r--r--Modules/Platform/CYGWIN-GNU-C.cmake2
-rw-r--r--Modules/Platform/CYGWIN-GNU-CXX.cmake2
-rw-r--r--Modules/Platform/CYGWIN-GNU-Fortran.cmake2
-rw-r--r--Modules/Platform/CYGWIN-GNU.cmake56
-rw-r--r--Modules/Platform/CYGWIN-windres.cmake1
-rw-r--r--Modules/Platform/CYGWIN.cmake64
-rw-r--r--Modules/Platform/Catamount.cmake26
-rw-r--r--Modules/Platform/Darwin-Absoft-Fortran.cmake1
-rw-r--r--Modules/Platform/Darwin-GNU-C.cmake4
-rw-r--r--Modules/Platform/Darwin-GNU-CXX.cmake4
-rw-r--r--Modules/Platform/Darwin-GNU-Fortran.cmake2
-rw-r--r--Modules/Platform/Darwin-GNU.cmake64
-rw-r--r--Modules/Platform/Darwin-NAG-Fortran.cmake5
-rw-r--r--Modules/Platform/Darwin-VisualAge-C.cmake1
-rw-r--r--Modules/Platform/Darwin-VisualAge-CXX.cmake1
-rw-r--r--Modules/Platform/Darwin-XL-C.cmake5
-rw-r--r--Modules/Platform/Darwin-XL-CXX.cmake5
-rw-r--r--Modules/Platform/Darwin-icc.cmake131
-rw-r--r--Modules/Platform/Darwin-icpc.cmake3
-rw-r--r--Modules/Platform/Darwin.cmake268
-rw-r--r--Modules/Platform/DragonFly.cmake5
-rw-r--r--Modules/Platform/FreeBSD.cmake28
-rw-r--r--Modules/Platform/GNU.cmake13
-rw-r--r--Modules/Platform/GNUtoMS_lib.bat.in3
-rw-r--r--Modules/Platform/GNUtoMS_lib.cmake10
-rw-r--r--Modules/Platform/Generic-ADSP-ASM.cmake7
-rw-r--r--Modules/Platform/Generic-ADSP-C.cmake20
-rw-r--r--Modules/Platform/Generic-ADSP-CXX.cmake18
-rw-r--r--Modules/Platform/Generic-ADSP-Common.cmake120
-rw-r--r--Modules/Platform/Generic-SDCC-C.cmake54
-rw-r--r--Modules/Platform/Generic.cmake17
-rw-r--r--Modules/Platform/HP-UX-GNU-C.cmake2
-rw-r--r--Modules/Platform/HP-UX-GNU-CXX.cmake2
-rw-r--r--Modules/Platform/HP-UX-GNU-Fortran.cmake2
-rw-r--r--Modules/Platform/HP-UX-GNU.cmake27
-rw-r--r--Modules/Platform/HP-UX-HP-ASM.cmake2
-rw-r--r--Modules/Platform/HP-UX-HP-C.cmake6
-rw-r--r--Modules/Platform/HP-UX-HP-CXX.cmake14
-rw-r--r--Modules/Platform/HP-UX-HP-Fortran.cmake2
-rw-r--r--Modules/Platform/HP-UX-HP.cmake31
-rw-r--r--Modules/Platform/HP-UX.cmake50
-rw-r--r--Modules/Platform/Haiku.cmake24
-rw-r--r--Modules/Platform/IRIX.cmake45
-rw-r--r--Modules/Platform/IRIX64.cmake73
-rw-r--r--Modules/Platform/Linux-Absoft-Fortran.cmake1
-rw-r--r--Modules/Platform/Linux-Clang-C.cmake1
-rw-r--r--Modules/Platform/Linux-Clang-CXX.cmake1
-rw-r--r--Modules/Platform/Linux-GNU-C.cmake2
-rw-r--r--Modules/Platform/Linux-GNU-CXX.cmake2
-rw-r--r--Modules/Platform/Linux-GNU-Fortran.cmake2
-rw-r--r--Modules/Platform/Linux-GNU.cmake25
-rw-r--r--Modules/Platform/Linux-Intel-C.cmake2
-rw-r--r--Modules/Platform/Linux-Intel-CXX.cmake2
-rw-r--r--Modules/Platform/Linux-Intel-Fortran.cmake4
-rw-r--r--Modules/Platform/Linux-Intel.cmake50
-rw-r--r--Modules/Platform/Linux-NAG-Fortran.cmake10
-rw-r--r--Modules/Platform/Linux-PGI-C.cmake2
-rw-r--r--Modules/Platform/Linux-PGI-CXX.cmake2
-rw-r--r--Modules/Platform/Linux-PGI-Fortran.cmake2
-rw-r--r--Modules/Platform/Linux-PGI.cmake27
-rw-r--r--Modules/Platform/Linux-PathScale-C.cmake2
-rw-r--r--Modules/Platform/Linux-PathScale-CXX.cmake2
-rw-r--r--Modules/Platform/Linux-PathScale-Fortran.cmake2
-rw-r--r--Modules/Platform/Linux-PathScale.cmake27
-rw-r--r--Modules/Platform/Linux-SunPro-CXX.cmake9
-rw-r--r--Modules/Platform/Linux-TinyCC-C.cmake4
-rw-r--r--Modules/Platform/Linux-VisualAge-C.cmake1
-rw-r--r--Modules/Platform/Linux-VisualAge-CXX.cmake1
-rw-r--r--Modules/Platform/Linux-VisualAge-Fortran.cmake1
-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-como.cmake17
-rw-r--r--Modules/Platform/Linux.cmake57
-rw-r--r--Modules/Platform/MP-RAS.cmake14
-rw-r--r--Modules/Platform/NetBSD.cmake15
-rw-r--r--Modules/Platform/OSF1.cmake47
-rw-r--r--Modules/Platform/OpenBSD.cmake18
-rw-r--r--Modules/Platform/OpenVMS.cmake8
-rw-r--r--Modules/Platform/QNX.cmake33
-rw-r--r--Modules/Platform/RISCos.cmake6
-rw-r--r--Modules/Platform/SCO_SV.cmake2
-rw-r--r--Modules/Platform/SINIX.cmake4
-rw-r--r--Modules/Platform/SunOS-GNU-C.cmake2
-rw-r--r--Modules/Platform/SunOS-GNU-CXX.cmake2
-rw-r--r--Modules/Platform/SunOS-GNU-Fortran.cmake2
-rw-r--r--Modules/Platform/SunOS-GNU.cmake34
-rw-r--r--Modules/Platform/SunOS.cmake32
-rw-r--r--Modules/Platform/Tru64.cmake2
-rw-r--r--Modules/Platform/ULTRIX.cmake5
-rw-r--r--Modules/Platform/UNIX_SV.cmake5
-rw-r--r--Modules/Platform/UnixPaths.cmake88
-rw-r--r--Modules/Platform/UnixWare.cmake5
-rw-r--r--Modules/Platform/Windows-Borland-C.cmake1
-rw-r--r--Modules/Platform/Windows-Borland-CXX.cmake1
-rw-r--r--Modules/Platform/Windows-Embarcadero-C.cmake3
-rw-r--r--Modules/Platform/Windows-Embarcadero-CXX.cmake3
-rw-r--r--Modules/Platform/Windows-Embarcadero.cmake130
-rw-r--r--Modules/Platform/Windows-G95-Fortran.cmake1
-rw-r--r--Modules/Platform/Windows-GNU-C-ABI.cmake1
-rw-r--r--Modules/Platform/Windows-GNU-C.cmake2
-rw-r--r--Modules/Platform/Windows-GNU-CXX-ABI.cmake1
-rw-r--r--Modules/Platform/Windows-GNU-CXX.cmake2
-rw-r--r--Modules/Platform/Windows-GNU-Fortran-ABI.cmake1
-rw-r--r--Modules/Platform/Windows-GNU-Fortran.cmake5
-rw-r--r--Modules/Platform/Windows-GNU.cmake187
-rw-r--r--Modules/Platform/Windows-Intel-ASM.cmake2
-rw-r--r--Modules/Platform/Windows-Intel-C.cmake2
-rw-r--r--Modules/Platform/Windows-Intel-CXX.cmake4
-rw-r--r--Modules/Platform/Windows-Intel-Fortran.cmake11
-rw-r--r--Modules/Platform/Windows-Intel.cmake108
-rw-r--r--Modules/Platform/Windows-NMcl.cmake4
-rw-r--r--Modules/Platform/Windows-cl.cmake253
-rw-r--r--Modules/Platform/Windows-cl.cmake.in14
-rw-r--r--Modules/Platform/Windows-df.cmake70
-rw-r--r--Modules/Platform/Windows-wcl386.cmake122
-rw-r--r--Modules/Platform/Windows-windres.cmake1
-rw-r--r--Modules/Platform/Windows.cmake36
-rw-r--r--Modules/Platform/WindowsPaths.cmake96
-rw-r--r--Modules/Platform/Xenix.cmake2
-rw-r--r--Modules/Platform/cl.cmake62
-rw-r--r--Modules/Platform/eCos.cmake65
-rw-r--r--Modules/Platform/gas.cmake19
-rw-r--r--Modules/Platform/kFreeBSD.cmake4
-rw-r--r--Modules/Platform/syllable.cmake33
-rw-r--r--Modules/ProcessorCount.cmake183
-rw-r--r--Modules/Qt4ConfigDependentSettings.cmake295
-rw-r--r--Modules/Qt4Macros.cmake441
-rw-r--r--Modules/RepositoryInfo.txt.in3
-rw-r--r--Modules/SelectLibraryConfigurations.cmake81
-rwxr-xr-xModules/SquishRunTestCase.bat11
-rwxr-xr-xModules/SquishRunTestCase.sh13
-rw-r--r--Modules/SquishTestScript.cmake72
-rw-r--r--Modules/SystemInformation.cmake103
-rw-r--r--Modules/SystemInformation.in88
-rw-r--r--Modules/TestBigEndian.cmake112
-rw-r--r--Modules/TestCXXAcceptsFlag.cmake43
-rw-r--r--Modules/TestEndianess.c.in23
-rw-r--r--Modules/TestForANSIForScope.cmake44
-rw-r--r--Modules/TestForANSIStreamHeaders.cmake34
-rw-r--r--Modules/TestForANSIStreamHeaders.cxx6
-rw-r--r--Modules/TestForAnsiForScope.cxx7
-rw-r--r--Modules/TestForSSTREAM.cmake43
-rw-r--r--Modules/TestForSSTREAM.cxx11
-rw-r--r--Modules/TestForSTDNamespace.cmake43
-rw-r--r--Modules/TestForSTDNamespace.cxx6
-rw-r--r--Modules/UseEcos.cmake236
-rw-r--r--Modules/UseJava.cmake881
-rw-r--r--Modules/UseJavaClassFilelist.cmake52
-rw-r--r--Modules/UseJavaSymlinks.cmake32
-rw-r--r--Modules/UsePkgConfig.cmake78
-rw-r--r--Modules/UseQt4.cmake108
-rw-r--r--Modules/UseSWIG.cmake253
-rw-r--r--Modules/UseVTK40.cmake29
-rw-r--r--Modules/UseVTKBuildSettings40.cmake38
-rw-r--r--Modules/UseVTKConfig40.cmake409
-rw-r--r--Modules/Use_wxWindows.cmake64
-rw-r--r--Modules/UsewxWidgets.cmake89
-rw-r--r--Modules/VTKCompatibility.cmake52
-rw-r--r--Modules/WriteBasicConfigVersionFile.cmake44
-rw-r--r--Modules/ecos_clean.cmake26
-rw-r--r--Modules/exportheader.cmake.in35
-rw-r--r--Modules/kde3init_dummy.cpp.in6
-rw-r--r--Modules/kde3uic.cmake33
-rw-r--r--Modules/readme.txt151
-rw-r--r--Readme.txt53
-rw-r--r--Source/.cvsignore5
-rw-r--r--Source/.gitattributes2
-rw-r--r--Source/CMakeLists.txt564
-rwxr-xr-xSource/CMakeVersion.bash7
-rw-r--r--Source/CMakeVersion.cmake6
-rw-r--r--Source/CMakeVersionSource.cmake37
-rw-r--r--Source/CPack/OSXLauncherScript.scptbin0 -> 3102 bytes
-rw-r--r--Source/CPack/OSXScriptLauncher.cxx147
-rw-r--r--Source/CPack/bills-comments.txt68
-rw-r--r--Source/CPack/cmCPackArchiveGenerator.cxx314
-rw-r--r--Source/CPack/cmCPackArchiveGenerator.h74
-rw-r--r--Source/CPack/cmCPackBundleGenerator.cxx174
-rw-r--r--Source/CPack/cmCPackBundleGenerator.h40
-rw-r--r--Source/CPack/cmCPackComponentGroup.cxx44
-rw-r--r--Source/CPack/cmCPackComponentGroup.h138
-rw-r--r--Source/CPack/cmCPackConfigure.h.in11
-rw-r--r--Source/CPack/cmCPackCygwinBinaryGenerator.cxx92
-rw-r--r--Source/CPack/cmCPackCygwinBinaryGenerator.h38
-rw-r--r--Source/CPack/cmCPackCygwinSourceGenerator.cxx182
-rw-r--r--Source/CPack/cmCPackCygwinSourceGenerator.h40
-rw-r--r--Source/CPack/cmCPackDebGenerator.cxx833
-rw-r--r--Source/CPack/cmCPackDebGenerator.h77
-rw-r--r--Source/CPack/cmCPackDocumentMacros.cxx16
-rw-r--r--Source/CPack/cmCPackDocumentMacros.h21
-rw-r--r--Source/CPack/cmCPackDocumentVariables.cxx111
-rw-r--r--Source/CPack/cmCPackDocumentVariables.h21
-rw-r--r--Source/CPack/cmCPackDragNDropGenerator.cxx588
-rw-r--r--Source/CPack/cmCPackDragNDropGenerator.h47
-rw-r--r--Source/CPack/cmCPackGenerator.cxx1685
-rw-r--r--Source/CPack/cmCPackGenerator.h329
-rw-r--r--Source/CPack/cmCPackGeneratorFactory.cxx183
-rw-r--r--Source/CPack/cmCPackGeneratorFactory.h59
-rw-r--r--Source/CPack/cmCPackLog.cxx225
-rw-r--r--Source/CPack/cmCPackLog.h155
-rw-r--r--Source/CPack/cmCPackNSISGenerator.cxx1004
-rw-r--r--Source/CPack/cmCPackNSISGenerator.h82
-rw-r--r--Source/CPack/cmCPackOSXX11Generator.cxx311
-rw-r--r--Source/CPack/cmCPackOSXX11Generator.h46
-rw-r--r--Source/CPack/cmCPackPackageMakerGenerator.cxx982
-rw-r--r--Source/CPack/cmCPackPackageMakerGenerator.h119
-rw-r--r--Source/CPack/cmCPackRPMGenerator.cxx275
-rw-r--r--Source/CPack/cmCPackRPMGenerator.h77
-rw-r--r--Source/CPack/cmCPackSTGZGenerator.cxx138
-rw-r--r--Source/CPack/cmCPackSTGZGenerator.h41
-rw-r--r--Source/CPack/cmCPackTGZGenerator.cxx26
-rw-r--r--Source/CPack/cmCPackTGZGenerator.h35
-rw-r--r--Source/CPack/cmCPackTarBZip2Generator.cxx25
-rw-r--r--Source/CPack/cmCPackTarBZip2Generator.h34
-rw-r--r--Source/CPack/cmCPackTarCompressGenerator.cxx26
-rw-r--r--Source/CPack/cmCPackTarCompressGenerator.h35
-rw-r--r--Source/CPack/cmCPackZIPGenerator.cxx26
-rw-r--r--Source/CPack/cmCPackZIPGenerator.h36
-rw-r--r--Source/CPack/cpack.cxx601
-rw-r--r--Source/CPack/cygwin.readme69
-rw-r--r--Source/CTest/cmCTestBZR.cxx523
-rw-r--r--Source/CTest/cmCTestBZR.h55
-rw-r--r--Source/CTest/cmCTestBatchTestHandler.cxx143
-rw-r--r--Source/CTest/cmCTestBatchTestHandler.h41
-rw-r--r--Source/CTest/cmCTestBuildAndTestHandler.cxx526
-rw-r--r--Source/CTest/cmCTestBuildAndTestHandler.h78
-rw-r--r--Source/CTest/cmCTestBuildCommand.cxx193
-rw-r--r--Source/CTest/cmCTestBuildCommand.h98
-rw-r--r--Source/CTest/cmCTestBuildHandler.cxx1310
-rw-r--r--Source/CTest/cmCTestBuildHandler.h152
-rw-r--r--Source/CTest/cmCTestCVS.cxx319
-rw-r--r--Source/CTest/cmCTestCVS.h51
-rw-r--r--Source/CTest/cmCTestCommand.h40
-rw-r--r--Source/CTest/cmCTestConfigureCommand.cxx172
-rw-r--r--Source/CTest/cmCTestConfigureCommand.h84
-rw-r--r--Source/CTest/cmCTestConfigureHandler.cxx132
-rw-r--r--Source/CTest/cmCTestConfigureHandler.h39
-rw-r--r--Source/CTest/cmCTestCoverageCommand.cxx73
-rw-r--r--Source/CTest/cmCTestCoverageCommand.h90
-rw-r--r--Source/CTest/cmCTestCoverageHandler.cxx2144
-rw-r--r--Source/CTest/cmCTestCoverageHandler.h139
-rw-r--r--Source/CTest/cmCTestEmptyBinaryDirectoryCommand.cxx36
-rw-r--r--Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h78
-rw-r--r--Source/CTest/cmCTestGIT.cxx652
-rw-r--r--Source/CTest/cmCTestGIT.h57
-rw-r--r--Source/CTest/cmCTestGenericHandler.cxx171
-rw-r--r--Source/CTest/cmCTestGenericHandler.h107
-rw-r--r--Source/CTest/cmCTestGlobalVC.cxx142
-rw-r--r--Source/CTest/cmCTestGlobalVC.h68
-rw-r--r--Source/CTest/cmCTestHG.cxx338
-rw-r--r--Source/CTest/cmCTestHG.h47
-rw-r--r--Source/CTest/cmCTestHandlerCommand.cxx197
-rw-r--r--Source/CTest/cmCTestHandlerCommand.h77
-rw-r--r--Source/CTest/cmCTestLaunch.cxx719
-rw-r--r--Source/CTest/cmCTestLaunch.h104
-rw-r--r--Source/CTest/cmCTestMemCheckCommand.cxx32
-rw-r--r--Source/CTest/cmCTestMemCheckCommand.h88
-rw-r--r--Source/CTest/cmCTestMemCheckHandler.cxx955
-rw-r--r--Source/CTest/cmCTestMemCheckHandler.h125
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.cxx691
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.h116
-rw-r--r--Source/CTest/cmCTestReadCustomFilesCommand.cxx35
-rw-r--r--Source/CTest/cmCTestReadCustomFilesCommand.h75
-rw-r--r--Source/CTest/cmCTestRunScriptCommand.cxx65
-rw-r--r--Source/CTest/cmCTestRunScriptCommand.h80
-rw-r--r--Source/CTest/cmCTestRunTest.cxx735
-rw-r--r--Source/CTest/cmCTestRunTest.h112
-rw-r--r--Source/CTest/cmCTestSVN.cxx450
-rw-r--r--Source/CTest/cmCTestSVN.h68
-rw-r--r--Source/CTest/cmCTestScriptHandler.cxx1095
-rw-r--r--Source/CTest/cmCTestScriptHandler.h172
-rw-r--r--Source/CTest/cmCTestSleepCommand.cxx55
-rw-r--r--Source/CTest/cmCTestSleepCommand.h77
-rw-r--r--Source/CTest/cmCTestStartCommand.cxx170
-rw-r--r--Source/CTest/cmCTestStartCommand.h92
-rw-r--r--Source/CTest/cmCTestSubmitCommand.cxx255
-rw-r--r--Source/CTest/cmCTestSubmitCommand.h118
-rw-r--r--Source/CTest/cmCTestSubmitHandler.cxx1508
-rw-r--r--Source/CTest/cmCTestSubmitHandler.h98
-rw-r--r--Source/CTest/cmCTestTestCommand.cxx112
-rw-r--r--Source/CTest/cmCTestTestCommand.h107
-rw-r--r--Source/CTest/cmCTestTestHandler.cxx2267
-rw-r--r--Source/CTest/cmCTestTestHandler.h273
-rw-r--r--Source/CTest/cmCTestUpdateCommand.cxx78
-rw-r--r--Source/CTest/cmCTestUpdateCommand.h73
-rw-r--r--Source/CTest/cmCTestUpdateHandler.cxx404
-rw-r--r--Source/CTest/cmCTestUpdateHandler.h76
-rw-r--r--Source/CTest/cmCTestUploadCommand.cxx69
-rw-r--r--Source/CTest/cmCTestUploadCommand.h85
-rw-r--r--Source/CTest/cmCTestUploadHandler.cxx77
-rw-r--r--Source/CTest/cmCTestUploadHandler.h45
-rw-r--r--Source/CTest/cmCTestVC.cxx241
-rw-r--r--Source/CTest/cmCTestVC.h133
-rw-r--r--Source/CTest/cmParseCacheCoverage.cxx220
-rw-r--r--Source/CTest/cmParseCacheCoverage.h42
-rw-r--r--Source/CTest/cmParseGTMCoverage.cxx272
-rw-r--r--Source/CTest/cmParseGTMCoverage.h49
-rw-r--r--Source/CTest/cmParseMumpsCoverage.cxx165
-rw-r--r--Source/CTest/cmParseMumpsCoverage.h52
-rw-r--r--Source/CTest/cmParsePHPCoverage.cxx253
-rw-r--r--Source/CTest/cmParsePHPCoverage.h45
-rw-r--r--Source/CTest/cmProcess.cxx272
-rw-r--r--Source/CTest/cmProcess.h82
-rw-r--r--Source/CursesDialog/.NoDartCoverage1
-rw-r--r--Source/CursesDialog/CMakeLists.txt37
-rw-r--r--Source/CursesDialog/ccmake.cxx217
-rw-r--r--Source/CursesDialog/cmCursesBoolWidget.cxx74
-rw-r--r--Source/CursesDialog/cmCursesBoolWidget.h40
-rw-r--r--Source/CursesDialog/cmCursesCacheEntryComposite.cxx103
-rw-r--r--Source/CursesDialog/cmCursesCacheEntryComposite.h42
-rw-r--r--Source/CursesDialog/cmCursesDummyWidget.cxx26
-rw-r--r--Source/CursesDialog/cmCursesDummyWidget.h36
-rw-r--r--Source/CursesDialog/cmCursesFilePathWidget.cxx20
-rw-r--r--Source/CursesDialog/cmCursesFilePathWidget.h28
-rw-r--r--Source/CursesDialog/cmCursesForm.cxx57
-rw-r--r--Source/CursesDialog/cmCursesForm.h75
-rw-r--r--Source/CursesDialog/cmCursesLabelWidget.cxx33
-rw-r--r--Source/CursesDialog/cmCursesLabelWidget.h38
-rw-r--r--Source/CursesDialog/cmCursesLongMessageForm.cxx207
-rw-r--r--Source/CursesDialog/cmCursesLongMessageForm.h58
-rw-r--r--Source/CursesDialog/cmCursesMainForm.cxx1303
-rw-r--r--Source/CursesDialog/cmCursesMainForm.h164
-rw-r--r--Source/CursesDialog/cmCursesPathWidget.cxx94
-rw-r--r--Source/CursesDialog/cmCursesPathWidget.h40
-rw-r--r--Source/CursesDialog/cmCursesStandardIncludes.h83
-rw-r--r--Source/CursesDialog/cmCursesStringWidget.cxx249
-rw-r--r--Source/CursesDialog/cmCursesStringWidget.h76
-rw-r--r--Source/CursesDialog/cmCursesWidget.cxx58
-rw-r--r--Source/CursesDialog/cmCursesWidget.h87
-rw-r--r--Source/CursesDialog/form/.NoDartCoverage1
-rw-r--r--Source/CursesDialog/form/CMakeLists.txt66
-rw-r--r--Source/CursesDialog/form/READ.ME15
-rw-r--r--Source/CursesDialog/form/cmFormConfigure.h.in21
-rw-r--r--Source/CursesDialog/form/eti.h52
-rw-r--r--Source/CursesDialog/form/fld_arg.c91
-rw-r--r--Source/CursesDialog/form/fld_attr.c116
-rw-r--r--Source/CursesDialog/form/fld_current.c124
-rw-r--r--Source/CursesDialog/form/fld_def.c346
-rw-r--r--Source/CursesDialog/form/fld_dup.c97
-rw-r--r--Source/CursesDialog/form/fld_ftchoice.c62
-rw-r--r--Source/CursesDialog/form/fld_ftlink.c83
-rw-r--r--Source/CursesDialog/form/fld_info.c91
-rw-r--r--Source/CursesDialog/form/fld_just.c81
-rw-r--r--Source/CursesDialog/form/fld_link.c90
-rw-r--r--Source/CursesDialog/form/fld_max.c74
-rw-r--r--Source/CursesDialog/form/fld_move.c62
-rw-r--r--Source/CursesDialog/form/fld_newftyp.c125
-rw-r--r--Source/CursesDialog/form/fld_opts.c124
-rw-r--r--Source/CursesDialog/form/fld_pad.c78
-rw-r--r--Source/CursesDialog/form/fld_page.c76
-rw-r--r--Source/CursesDialog/form/fld_stat.c73
-rw-r--r--Source/CursesDialog/form/fld_type.c51
-rw-r--r--Source/CursesDialog/form/fld_user.c67
-rw-r--r--Source/CursesDialog/form/form.h401
-rw-r--r--Source/CursesDialog/form/form.priv.h134
-rw-r--r--Source/CursesDialog/form/frm_cursor.c66
-rw-r--r--Source/CursesDialog/form/frm_data.c183
-rw-r--r--Source/CursesDialog/form/frm_def.c376
-rw-r--r--Source/CursesDialog/form/frm_driver.c3898
-rw-r--r--Source/CursesDialog/form/frm_hook.c140
-rw-r--r--Source/CursesDialog/form/frm_opts.c116
-rw-r--r--Source/CursesDialog/form/frm_page.c100
-rw-r--r--Source/CursesDialog/form/frm_post.c124
-rw-r--r--Source/CursesDialog/form/frm_req_name.c169
-rw-r--r--Source/CursesDialog/form/frm_scale.c63
-rw-r--r--Source/CursesDialog/form/frm_sub.c69
-rw-r--r--Source/CursesDialog/form/frm_user.c67
-rw-r--r--Source/CursesDialog/form/frm_win.c70
-rw-r--r--Source/CursesDialog/form/fty_alnum.c138
-rw-r--r--Source/CursesDialog/form/fty_alpha.c139
-rw-r--r--Source/CursesDialog/form/fty_enum.c295
-rw-r--r--Source/CursesDialog/form/fty_int.c161
-rw-r--r--Source/CursesDialog/form/fty_ipv4.c84
-rw-r--r--Source/CursesDialog/form/fty_num.c192
-rw-r--r--Source/CursesDialog/form/fty_regex.c264
-rw-r--r--Source/CursesDialog/form/llib-lform694
-rw-r--r--Source/CursesDialog/form/mf_common.h93
-rw-r--r--Source/CursesDialog/form/nc_alloc.h83
-rw-r--r--Source/QtDialog/AddCacheEntry.cxx83
-rw-r--r--Source/QtDialog/AddCacheEntry.h36
-rw-r--r--Source/QtDialog/AddCacheEntry.ui97
-rw-r--r--Source/QtDialog/CMake.desktop12
-rw-r--r--Source/QtDialog/CMakeLists.txt123
-rw-r--r--Source/QtDialog/CMakeSetup.cxx205
-rw-r--r--Source/QtDialog/CMakeSetup.icnsbin0 -> 138205 bytes
-rw-r--r--Source/QtDialog/CMakeSetup.icobin0 -> 24542 bytes
-rw-r--r--Source/QtDialog/CMakeSetup.qrc8
-rw-r--r--Source/QtDialog/CMakeSetup.rc1
-rw-r--r--Source/QtDialog/CMakeSetup128.pngbin0 -> 13269 bytes
-rw-r--r--Source/QtDialog/CMakeSetup32.pngbin0 -> 358 bytes
-rw-r--r--Source/QtDialog/CMakeSetupDialog.cxx1152
-rw-r--r--Source/QtDialog/CMakeSetupDialog.h132
-rw-r--r--Source/QtDialog/CMakeSetupDialog.ui310
-rw-r--r--Source/QtDialog/Compilers.h21
-rw-r--r--Source/QtDialog/Compilers.ui87
-rw-r--r--Source/QtDialog/CrossCompiler.ui213
-rw-r--r--Source/QtDialog/Delete16.pngbin0 -> 731 bytes
-rw-r--r--Source/QtDialog/FirstConfigure.cxx509
-rw-r--r--Source/QtDialog/FirstConfigure.h177
-rw-r--r--Source/QtDialog/MacInstallDialog.ui103
-rw-r--r--Source/QtDialog/Plus16.pngbin0 -> 358 bytes
-rw-r--r--Source/QtDialog/QCMake.cxx448
-rw-r--r--Source/QtDialog/QCMake.h154
-rw-r--r--Source/QtDialog/QCMakeCacheView.cxx735
-rw-r--r--Source/QtDialog/QCMakeCacheView.h172
-rw-r--r--Source/QtDialog/QCMakeWidgets.cxx134
-rw-r--r--Source/QtDialog/QCMakeWidgets.h87
-rw-r--r--Source/QtDialog/QMacInstallDialog.cxx121
-rw-r--r--Source/QtDialog/QMacInstallDialog.h20
-rw-r--r--Source/QtDialog/QtDialogCPack.cmake.in18
-rw-r--r--Source/QtDialog/cmakecache.xml8
-rwxr-xr-xSource/QtDialog/postflight.sh.in3
-rwxr-xr-xSource/QtDialog/postupgrade.sh.in2
-rw-r--r--Source/cmAddCustomCommandCommand.cxx387
-rw-r--r--Source/cmAddCustomCommandCommand.h187
-rw-r--r--Source/cmAddCustomTargetCommand.cxx192
-rw-r--r--Source/cmAddCustomTargetCommand.h108
-rw-r--r--Source/cmAddDefinitionsCommand.cxx31
-rw-r--r--Source/cmAddDefinitionsCommand.h82
-rw-r--r--Source/cmAddDependenciesCommand.cxx46
-rw-r--r--Source/cmAddDependenciesCommand.h78
-rw-r--r--Source/cmAddExecutableCommand.cxx136
-rw-r--r--Source/cmAddExecutableCommand.h117
-rw-r--r--Source/cmAddLibraryCommand.cxx193
-rw-r--r--Source/cmAddLibraryCommand.h142
-rw-r--r--Source/cmAddSubDirectoryCommand.cxx123
-rw-r--r--Source/cmAddSubDirectoryCommand.h99
-rw-r--r--Source/cmAddTestCommand.cxx180
-rw-r--r--Source/cmAddTestCommand.h101
-rw-r--r--Source/cmArchiveWrite.cxx308
-rw-r--r--Source/cmArchiveWrite.h94
-rw-r--r--Source/cmAuxSourceDirectoryCommand.cxx89
-rw-r--r--Source/cmAuxSourceDirectoryCommand.h86
-rw-r--r--Source/cmBootstrapCommands.cxx171
-rw-r--r--Source/cmBreakCommand.cxx21
-rw-r--r--Source/cmBreakCommand.h73
-rw-r--r--Source/cmBuildCommand.cxx161
-rw-r--r--Source/cmBuildCommand.h97
-rw-r--r--Source/cmBuildNameCommand.cxx77
-rw-r--r--Source/cmBuildNameCommand.h82
-rw-r--r--Source/cmCMakeMinimumRequired.cxx139
-rw-r--r--Source/cmCMakeMinimumRequired.h90
-rw-r--r--Source/cmCMakePolicyCommand.cxx172
-rw-r--r--Source/cmCMakePolicyCommand.h142
-rw-r--r--Source/cmCPluginAPI.cxx934
-rw-r--r--Source/cmCPluginAPI.h243
-rw-r--r--Source/cmCTest.cxx3225
-rw-r--r--Source/cmCTest.h598
-rw-r--r--Source/cmCacheManager.cxx1003
-rw-r--r--Source/cmCacheManager.h189
-rw-r--r--Source/cmCallVisualStudioMacro.cxx540
-rw-r--r--Source/cmCallVisualStudioMacro.h45
-rw-r--r--Source/cmCommand.h195
-rw-r--r--Source/cmCommandArgumentLexer.cxx2077
-rw-r--r--Source/cmCommandArgumentLexer.h333
-rw-r--r--Source/cmCommandArgumentLexer.in.l161
-rw-r--r--Source/cmCommandArgumentParser.cxx1835
-rw-r--r--Source/cmCommandArgumentParser.y245
-rw-r--r--Source/cmCommandArgumentParserHelper.cxx367
-rw-r--r--Source/cmCommandArgumentParserHelper.h110
-rw-r--r--Source/cmCommandArgumentParserTokens.h92
-rw-r--r--Source/cmCommandArgumentsHelper.cxx307
-rw-r--r--Source/cmCommandArgumentsHelper.h204
-rw-r--r--Source/cmCommands.cxx75
-rw-r--r--Source/cmCommands.h28
-rw-r--r--Source/cmComputeComponentGraph.cxx159
-rw-r--r--Source/cmComputeComponentGraph.h83
-rw-r--r--Source/cmComputeLinkDepends.cxx998
-rw-r--r--Source/cmComputeLinkDepends.h168
-rw-r--r--Source/cmComputeLinkInformation.cxx1869
-rw-r--r--Source/cmComputeLinkInformation.h185
-rw-r--r--Source/cmComputeTargetDepends.cxx537
-rw-r--r--Source/cmComputeTargetDepends.h82
-rw-r--r--Source/cmConfigure.cmake.h.in22
-rw-r--r--Source/cmConfigureFileCommand.cxx141
-rw-r--r--Source/cmConfigureFileCommand.h109
-rw-r--r--Source/cmCoreTryCompile.cxx483
-rw-r--r--Source/cmCoreTryCompile.h60
-rw-r--r--Source/cmCreateTestSourceList.cxx189
-rw-r--r--Source/cmCreateTestSourceList.h90
-rw-r--r--Source/cmCryptoHash.cxx130
-rw-r--r--Source/cmCryptoHash.h65
-rw-r--r--Source/cmCustomCommand.cxx172
-rw-r--r--Source/cmCustomCommand.h93
-rw-r--r--Source/cmCustomCommandGenerator.cxx72
-rw-r--r--Source/cmCustomCommandGenerator.h40
-rw-r--r--Source/cmDefinePropertyCommand.cxx137
-rw-r--r--Source/cmDefinePropertyCommand.h93
-rw-r--r--Source/cmDefinitions.cxx178
-rw-r--r--Source/cmDefinitions.h86
-rw-r--r--Source/cmDepends.cxx286
-rw-r--r--Source/cmDepends.h121
-rw-r--r--Source/cmDependsC.cxx581
-rw-r--r--Source/cmDependsC.h99
-rw-r--r--Source/cmDependsFortran.cxx1258
-rw-r--r--Source/cmDependsFortran.h92
-rw-r--r--Source/cmDependsFortranLexer.cxx2414
-rw-r--r--Source/cmDependsFortranLexer.h348
-rw-r--r--Source/cmDependsFortranLexer.in.l189
-rw-r--r--Source/cmDependsFortranParser.cxx2094
-rw-r--r--Source/cmDependsFortranParser.h96
-rw-r--r--Source/cmDependsFortranParser.y287
-rw-r--r--Source/cmDependsFortranParserTokens.h122
-rw-r--r--Source/cmDependsJava.cxx45
-rw-r--r--Source/cmDependsJava.h42
-rw-r--r--Source/cmDependsJavaLexer.cxx2542
-rw-r--r--Source/cmDependsJavaLexer.h334
-rw-r--r--Source/cmDependsJavaLexer.in.l188
-rw-r--r--Source/cmDependsJavaParser.cxx6021
-rw-r--r--Source/cmDependsJavaParser.y3226
-rw-r--r--Source/cmDependsJavaParserHelper.cxx429
-rw-r--r--Source/cmDependsJavaParserHelper.h128
-rw-r--r--Source/cmDependsJavaParserTokens.h254
-rw-r--r--Source/cmDocumentCompileDefinitions.h34
-rw-r--r--Source/cmDocumentGeneratorExpressions.h30
-rw-r--r--Source/cmDocumentLocationUndefined.h24
-rw-r--r--Source/cmDocumentVariables.cxx1753
-rw-r--r--Source/cmDocumentVariables.h21
-rw-r--r--Source/cmDocumentation.cxx1978
-rw-r--r--Source/cmDocumentation.h271
-rw-r--r--Source/cmDocumentationFormatter.cxx156
-rw-r--r--Source/cmDocumentationFormatter.h67
-rw-r--r--Source/cmDocumentationFormatterDocbook.cxx255
-rw-r--r--Source/cmDocumentationFormatterDocbook.h41
-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.cxx81
-rw-r--r--Source/cmDocumentationSection.h68
-rw-r--r--Source/cmDynamicLoader.cxx112
-rw-r--r--Source/cmDynamicLoader.h47
-rw-r--r--Source/cmELF.cxx920
-rw-r--r--Source/cmELF.h108
-rw-r--r--Source/cmElseCommand.cxx21
-rw-r--r--Source/cmElseCommand.h72
-rw-r--r--Source/cmElseIfCommand.cxx20
-rw-r--r--Source/cmElseIfCommand.h72
-rw-r--r--Source/cmEnableLanguageCommand.cxx43
-rw-r--r--Source/cmEnableLanguageCommand.h76
-rw-r--r--Source/cmEnableTestingCommand.cxx22
-rw-r--r--Source/cmEnableTestingCommand.h79
-rw-r--r--Source/cmEndForEachCommand.cxx23
-rw-r--r--Source/cmEndForEachCommand.h79
-rw-r--r--Source/cmEndFunctionCommand.cxx23
-rw-r--r--Source/cmEndFunctionCommand.h79
-rw-r--r--Source/cmEndIfCommand.cxx29
-rw-r--r--Source/cmEndIfCommand.h72
-rw-r--r--Source/cmEndMacroCommand.cxx23
-rw-r--r--Source/cmEndMacroCommand.h79
-rw-r--r--Source/cmEndWhileCommand.cxx32
-rw-r--r--Source/cmEndWhileCommand.h79
-rw-r--r--Source/cmExecProgramCommand.cxx145
-rw-r--r--Source/cmExecProgramCommand.h95
-rw-r--r--Source/cmExecuteProcessCommand.cxx422
-rw-r--r--Source/cmExecuteProcessCommand.h113
-rw-r--r--Source/cmExecutionStatus.h55
-rw-r--r--Source/cmExportBuildFileGenerator.cxx152
-rw-r--r--Source/cmExportBuildFileGenerator.h61
-rw-r--r--Source/cmExportCommand.cxx347
-rw-r--r--Source/cmExportCommand.h121
-rw-r--r--Source/cmExportFileGenerator.cxx443
-rw-r--r--Source/cmExportFileGenerator.h105
-rw-r--r--Source/cmExportInstallFileGenerator.cxx333
-rw-r--r--Source/cmExportInstallFileGenerator.h124
-rw-r--r--Source/cmExportLibraryDependencies.cxx204
-rw-r--r--Source/cmExportLibraryDependencies.h100
-rw-r--r--Source/cmExprLexer.cxx1928
-rw-r--r--Source/cmExprLexer.h334
-rw-r--r--Source/cmExprLexer.in.l73
-rw-r--r--Source/cmExprParser.cxx1433
-rw-r--r--Source/cmExprParser.y169
-rw-r--r--Source/cmExprParserHelper.cxx112
-rw-r--r--Source/cmExprParserHelper.h71
-rw-r--r--Source/cmExprParserTokens.h76
-rw-r--r--Source/cmExternalMakefileProjectGenerator.cxx64
-rw-r--r--Source/cmExternalMakefileProjectGenerator.h70
-rw-r--r--Source/cmExtraCodeBlocksGenerator.cxx819
-rw-r--r--Source/cmExtraCodeBlocksGenerator.h62
-rw-r--r--Source/cmExtraEclipseCDT4Generator.cxx1367
-rw-r--r--Source/cmExtraEclipseCDT4Generator.h121
-rw-r--r--Source/cmFLTKWrapUICommand.cxx173
-rw-r--r--Source/cmFLTKWrapUICommand.h94
-rw-r--r--Source/cmFileCommand.cxx3180
-rw-r--r--Source/cmFileCommand.h254
-rw-r--r--Source/cmFileTimeComparison.cxx274
-rw-r--r--Source/cmFileTimeComparison.h51
-rw-r--r--Source/cmFindBase.cxx598
-rw-r--r--Source/cmFindBase.h76
-rw-r--r--Source/cmFindCommon.cxx505
-rw-r--r--Source/cmFindCommon.h101
-rw-r--r--Source/cmFindFileCommand.cxx30
-rw-r--r--Source/cmFindFileCommand.h53
-rw-r--r--Source/cmFindLibraryCommand.cxx527
-rw-r--r--Source/cmFindLibraryCommand.h75
-rw-r--r--Source/cmFindPackageCommand.cxx2636
-rw-r--r--Source/cmFindPackageCommand.h154
-rw-r--r--Source/cmFindPathCommand.cxx240
-rw-r--r--Source/cmFindPathCommand.h76
-rw-r--r--Source/cmFindProgramCommand.cxx191
-rw-r--r--Source/cmFindProgramCommand.h75
-rw-r--r--Source/cmForEachCommand.cxx246
-rw-r--r--Source/cmForEachCommand.h116
-rw-r--r--Source/cmFunctionBlocker.h48
-rw-r--r--Source/cmFunctionCommand.cxx300
-rw-r--r--Source/cmFunctionCommand.h104
-rw-r--r--Source/cmGeneratedFileStream.cxx260
-rw-r--r--Source/cmGeneratedFileStream.h152
-rw-r--r--Source/cmGeneratorExpression.cxx193
-rw-r--r--Source/cmGeneratorExpression.h58
-rw-r--r--Source/cmGeneratorTarget.cxx177
-rw-r--r--Source/cmGeneratorTarget.h63
-rw-r--r--Source/cmGetCMakePropertyCommand.cxx77
-rw-r--r--Source/cmGetCMakePropertyCommand.h72
-rw-r--r--Source/cmGetDirectoryPropertyCommand.cxx96
-rw-r--r--Source/cmGetDirectoryPropertyCommand.h78
-rw-r--r--Source/cmGetFilenameComponentCommand.cxx139
-rw-r--r--Source/cmGetFilenameComponentCommand.h91
-rw-r--r--Source/cmGetPropertyCommand.cxx381
-rw-r--r--Source/cmGetPropertyCommand.h117
-rw-r--r--Source/cmGetSourceFilePropertyCommand.cxx52
-rw-r--r--Source/cmGetSourceFilePropertyCommand.h66
-rw-r--r--Source/cmGetTargetPropertyCommand.cxx39
-rw-r--r--Source/cmGetTargetPropertyCommand.h68
-rw-r--r--Source/cmGetTestPropertyCommand.cxx42
-rw-r--r--Source/cmGetTestPropertyCommand.h65
-rw-r--r--Source/cmGlobalBorlandMakefileGenerator.cxx63
-rw-r--r--Source/cmGlobalBorlandMakefileGenerator.h48
-rw-r--r--Source/cmGlobalGenerator.cxx2510
-rw-r--r--Source/cmGlobalGenerator.h407
-rw-r--r--Source/cmGlobalJOMMakefileGenerator.cxx69
-rw-r--r--Source/cmGlobalJOMMakefileGenerator.h49
-rw-r--r--Source/cmGlobalKdevelopGenerator.cxx619
-rw-r--r--Source/cmGlobalKdevelopGenerator.h92
-rw-r--r--Source/cmGlobalMSYSMakefileGenerator.cxx115
-rw-r--r--Source/cmGlobalMSYSMakefileGenerator.h51
-rw-r--r--Source/cmGlobalMinGWMakefileGenerator.cxx80
-rw-r--r--Source/cmGlobalMinGWMakefileGenerator.h47
-rw-r--r--Source/cmGlobalNMakeMakefileGenerator.cxx69
-rw-r--r--Source/cmGlobalNMakeMakefileGenerator.h47
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx1076
-rw-r--r--Source/cmGlobalNinjaGenerator.h370
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.cxx1059
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.h189
-rw-r--r--Source/cmGlobalVisualStudio10Generator.cxx286
-rw-r--r--Source/cmGlobalVisualStudio10Generator.h105
-rw-r--r--Source/cmGlobalVisualStudio10IA64Generator.cxx51
-rw-r--r--Source/cmGlobalVisualStudio10IA64Generator.h40
-rw-r--r--Source/cmGlobalVisualStudio10Win64Generator.cxx51
-rw-r--r--Source/cmGlobalVisualStudio10Win64Generator.h40
-rw-r--r--Source/cmGlobalVisualStudio11ARMGenerator.cxx32
-rw-r--r--Source/cmGlobalVisualStudio11ARMGenerator.h37
-rw-r--r--Source/cmGlobalVisualStudio11Generator.cxx56
-rw-r--r--Source/cmGlobalVisualStudio11Generator.h46
-rw-r--r--Source/cmGlobalVisualStudio11Win64Generator.cxx33
-rw-r--r--Source/cmGlobalVisualStudio11Win64Generator.h37
-rw-r--r--Source/cmGlobalVisualStudio6Generator.cxx424
-rw-r--r--Source/cmGlobalVisualStudio6Generator.h102
-rw-r--r--Source/cmGlobalVisualStudio71Generator.cxx329
-rw-r--r--Source/cmGlobalVisualStudio71Generator.h79
-rw-r--r--Source/cmGlobalVisualStudio7Generator.cxx821
-rw-r--r--Source/cmGlobalVisualStudio7Generator.h156
-rw-r--r--Source/cmGlobalVisualStudio8Generator.cxx376
-rw-r--r--Source/cmGlobalVisualStudio8Generator.h88
-rw-r--r--Source/cmGlobalVisualStudio8Win64Generator.cxx51
-rw-r--r--Source/cmGlobalVisualStudio8Win64Generator.h50
-rw-r--r--Source/cmGlobalVisualStudio9Generator.cxx99
-rw-r--r--Source/cmGlobalVisualStudio9Generator.h66
-rw-r--r--Source/cmGlobalVisualStudio9IA64Generator.cxx48
-rw-r--r--Source/cmGlobalVisualStudio9IA64Generator.h50
-rw-r--r--Source/cmGlobalVisualStudio9Win64Generator.cxx48
-rw-r--r--Source/cmGlobalVisualStudio9Win64Generator.h50
-rw-r--r--Source/cmGlobalVisualStudioGenerator.cxx861
-rw-r--r--Source/cmGlobalVisualStudioGenerator.h121
-rw-r--r--Source/cmGlobalWatcomWMakeGenerator.cxx66
-rw-r--r--Source/cmGlobalWatcomWMakeGenerator.h46
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx3757
-rw-r--r--Source/cmGlobalXCodeGenerator.h239
-rw-r--r--Source/cmGraphAdjacencyList.h40
-rw-r--r--Source/cmGraphVizWriter.cxx587
-rw-r--r--Source/cmGraphVizWriter.h89
-rw-r--r--Source/cmHexFileConverter.cxx265
-rw-r--r--Source/cmHexFileConverter.h28
-rw-r--r--Source/cmIDEFlagTable.h40
-rw-r--r--Source/cmIDEOptions.cxx179
-rw-r--r--Source/cmIDEOptions.h60
-rw-r--r--Source/cmIfCommand.cxx947
-rw-r--r--Source/cmIfCommand.h261
-rw-r--r--Source/cmIncludeCommand.cxx116
-rw-r--r--Source/cmIncludeCommand.h92
-rw-r--r--Source/cmIncludeDirectoryCommand.cxx120
-rw-r--r--Source/cmIncludeDirectoryCommand.h89
-rw-r--r--Source/cmIncludeExternalMSProjectCommand.cxx101
-rw-r--r--Source/cmIncludeExternalMSProjectCommand.h84
-rw-r--r--Source/cmIncludeRegularExpressionCommand.cxx32
-rw-r--r--Source/cmIncludeRegularExpressionCommand.h75
-rw-r--r--Source/cmInstallCommand.cxx1335
-rw-r--r--Source/cmInstallCommand.h352
-rw-r--r--Source/cmInstallCommandArguments.cxx205
-rw-r--r--Source/cmInstallCommandArguments.h68
-rw-r--r--Source/cmInstallDirectoryGenerator.cxx52
-rw-r--r--Source/cmInstallDirectoryGenerator.h42
-rw-r--r--Source/cmInstallExportGenerator.cxx229
-rw-r--r--Source/cmInstallExportGenerator.h58
-rw-r--r--Source/cmInstallFilesCommand.cxx181
-rw-r--r--Source/cmInstallFilesCommand.h114
-rw-r--r--Source/cmInstallFilesGenerator.cxx50
-rw-r--r--Source/cmInstallFilesGenerator.h41
-rw-r--r--Source/cmInstallGenerator.cxx182
-rw-r--r--Source/cmInstallGenerator.h63
-rw-r--r--Source/cmInstallProgramsCommand.cxx142
-rw-r--r--Source/cmInstallProgramsCommand.h108
-rw-r--r--Source/cmInstallScriptGenerator.cxx47
-rw-r--r--Source/cmInstallScriptGenerator.h33
-rw-r--r--Source/cmInstallTargetGenerator.cxx738
-rw-r--r--Source/cmInstallTargetGenerator.h102
-rw-r--r--Source/cmInstallTargetsCommand.cxx66
-rw-r--r--Source/cmInstallTargetsCommand.h81
-rw-r--r--Source/cmInstallType.h29
-rw-r--r--Source/cmLinkDirectoriesCommand.cxx70
-rw-r--r--Source/cmLinkDirectoriesCommand.h84
-rw-r--r--Source/cmLinkLibrariesCommand.cxx59
-rw-r--r--Source/cmLinkLibrariesCommand.h83
-rw-r--r--Source/cmListCommand.cxx608
-rw-r--r--Source/cmListCommand.h128
-rw-r--r--Source/cmListFileCache.cxx314
-rw-r--r--Source/cmListFileCache.h79
-rw-r--r--Source/cmListFileLexer.c2316
-rw-r--r--Source/cmListFileLexer.h59
-rw-r--r--Source/cmListFileLexer.in.l417
-rw-r--r--Source/cmLoadCacheCommand.cxx196
-rw-r--r--Source/cmLoadCacheCommand.h89
-rw-r--r--Source/cmLoadCommandCommand.cxx315
-rw-r--r--Source/cmLoadCommandCommand.h75
-rw-r--r--Source/cmLocalGenerator.cxx3278
-rw-r--r--Source/cmLocalGenerator.h441
-rw-r--r--Source/cmLocalNinjaGenerator.cxx395
-rw-r--r--Source/cmLocalNinjaGenerator.h133
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx2258
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.h383
-rw-r--r--Source/cmLocalVisualStudio10Generator.cxx124
-rw-r--r--Source/cmLocalVisualStudio10Generator.h46
-rw-r--r--Source/cmLocalVisualStudio6Generator.cxx1904
-rw-r--r--Source/cmLocalVisualStudio6Generator.h103
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx2215
-rw-r--r--Source/cmLocalVisualStudio7Generator.h131
-rw-r--r--Source/cmLocalVisualStudioGenerator.cxx206
-rw-r--r--Source/cmLocalVisualStudioGenerator.h74
-rw-r--r--Source/cmLocalXCodeGenerator.cxx35
-rw-r--r--Source/cmLocalXCodeGenerator.h36
-rw-r--r--Source/cmMacroCommand.cxx350
-rw-r--r--Source/cmMacroCommand.h110
-rw-r--r--Source/cmMakeDepend.cxx352
-rw-r--r--Source/cmMakeDepend.h150
-rw-r--r--Source/cmMakeDirectoryCommand.cxx34
-rw-r--r--Source/cmMakeDirectoryCommand.h85
-rw-r--r--Source/cmMakefile.cxx4309
-rw-r--r--Source/cmMakefile.h1014
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx448
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.h31
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx808
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.h45
-rw-r--r--Source/cmMakefileTargetGenerator.cxx2009
-rw-r--r--Source/cmMakefileTargetGenerator.h279
-rw-r--r--Source/cmMakefileUtilityTargetGenerator.cxx123
-rw-r--r--Source/cmMakefileUtilityTargetGenerator.h32
-rw-r--r--Source/cmMarkAsAdvancedCommand.cxx62
-rw-r--r--Source/cmMarkAsAdvancedCommand.h85
-rw-r--r--Source/cmMathCommand.cxx61
-rw-r--r--Source/cmMathCommand.h76
-rw-r--r--Source/cmMessageCommand.cxx82
-rw-r--r--Source/cmMessageCommand.h91
-rw-r--r--Source/cmNewLineStyle.cxx95
-rw-r--r--Source/cmNewLineStyle.h46
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx636
-rw-r--r--Source/cmNinjaNormalTargetGenerator.h52
-rw-r--r--Source/cmNinjaTargetGenerator.cxx689
-rw-r--r--Source/cmNinjaTargetGenerator.h151
-rw-r--r--Source/cmNinjaTypes.h19
-rw-r--r--Source/cmNinjaUtilityTargetGenerator.cxx116
-rw-r--r--Source/cmNinjaUtilityTargetGenerator.h30
-rw-r--r--Source/cmOSXBundleGenerator.cxx236
-rw-r--r--Source/cmOSXBundleGenerator.h71
-rw-r--r--Source/cmObject.h51
-rw-r--r--Source/cmOptionCommand.cxx71
-rw-r--r--Source/cmOptionCommand.h78
-rw-r--r--Source/cmOrderDirectories.cxx611
-rw-r--r--Source/cmOrderDirectories.h88
-rw-r--r--Source/cmOutputRequiredFilesCommand.cxx240
-rw-r--r--Source/cmOutputRequiredFilesCommand.h88
-rw-r--r--Source/cmPolicies.cxx859
-rw-r--r--Source/cmPolicies.h130
-rw-r--r--Source/cmProcessTools.cxx90
-rw-r--r--Source/cmProcessTools.h82
-rw-r--r--Source/cmProjectCommand.cxx100
-rw-r--r--Source/cmProjectCommand.h82
-rw-r--r--Source/cmProperty.cxx40
-rw-r--r--Source/cmProperty.h41
-rw-r--r--Source/cmPropertyDefinition.cxx47
-rw-r--r--Source/cmPropertyDefinition.h70
-rw-r--r--Source/cmPropertyDefinitionMap.cxx125
-rw-r--r--Source/cmPropertyDefinitionMap.h41
-rw-r--r--Source/cmPropertyMap.cxx123
-rw-r--r--Source/cmPropertyMap.h43
-rw-r--r--Source/cmQTWrapCPPCommand.cxx115
-rw-r--r--Source/cmQTWrapCPPCommand.h74
-rw-r--r--Source/cmQTWrapUICommand.cxx166
-rw-r--r--Source/cmQTWrapUICommand.h75
-rw-r--r--Source/cmQtAutomoc.cxx1086
-rw-r--r--Source/cmQtAutomoc.h92
-rw-r--r--Source/cmRemoveCommand.cxx76
-rw-r--r--Source/cmRemoveCommand.h81
-rw-r--r--Source/cmRemoveDefinitionsCommand.cxx31
-rw-r--r--Source/cmRemoveDefinitionsCommand.h71
-rw-r--r--Source/cmReturnCommand.cxx21
-rw-r--r--Source/cmReturnCommand.h81
-rw-r--r--Source/cmScriptGenerator.cxx237
-rw-r--r--Source/cmScriptGenerator.h96
-rw-r--r--Source/cmSeparateArgumentsCommand.cxx109
-rw-r--r--Source/cmSeparateArgumentsCommand.h92
-rw-r--r--Source/cmSetCommand.cxx177
-rw-r--r--Source/cmSetCommand.h163
-rw-r--r--Source/cmSetDirectoryPropertiesCommand.cxx70
-rw-r--r--Source/cmSetDirectoryPropertiesCommand.h78
-rw-r--r--Source/cmSetPropertyCommand.cxx483
-rw-r--r--Source/cmSetPropertyCommand.h116
-rw-r--r--Source/cmSetSourceFilesPropertiesCommand.cxx170
-rw-r--r--Source/cmSetSourceFilesPropertiesCommand.h74
-rw-r--r--Source/cmSetTargetPropertiesCommand.cxx110
-rw-r--r--Source/cmSetTargetPropertiesCommand.h168
-rw-r--r--Source/cmSetTestsPropertiesCommand.cxx117
-rw-r--r--Source/cmSetTestsPropertiesCommand.h81
-rw-r--r--Source/cmSiteNameCommand.cxx95
-rw-r--r--Source/cmSiteNameCommand.h72
-rw-r--r--Source/cmSourceFile.cxx557
-rw-r--r--Source/cmSourceFile.h122
-rw-r--r--Source/cmSourceFileLocation.cxx289
-rw-r--r--Source/cmSourceFileLocation.h101
-rw-r--r--Source/cmSourceGroup.cxx204
-rw-r--r--Source/cmSourceGroup.h132
-rw-r--r--Source/cmSourceGroupCommand.cxx102
-rw-r--r--Source/cmSourceGroupCommand.h81
-rw-r--r--Source/cmStandardIncludes.cxx16
-rw-r--r--Source/cmStandardIncludes.h384
-rw-r--r--Source/cmStandardLexer.h73
-rw-r--r--Source/cmStringCommand.cxx881
-rw-r--r--Source/cmStringCommand.h181
-rw-r--r--Source/cmSubdirCommand.cxx74
-rw-r--r--Source/cmSubdirCommand.h92
-rw-r--r--Source/cmSubdirDependsCommand.cxx20
-rw-r--r--Source/cmSubdirDependsCommand.h77
-rw-r--r--Source/cmSystemTools.cxx2948
-rw-r--r--Source/cmSystemTools.h480
-rw-r--r--Source/cmTarget.cxx4825
-rw-r--r--Source/cmTarget.h646
-rw-r--r--Source/cmTargetDepend.h48
-rw-r--r--Source/cmTargetLinkLibrariesCommand.cxx304
-rw-r--r--Source/cmTargetLinkLibrariesCommand.h167
-rw-r--r--Source/cmTest.cxx205
-rw-r--r--Source/cmTest.h80
-rw-r--r--Source/cmTestGenerator.cxx184
-rw-r--r--Source/cmTestGenerator.h45
-rw-r--r--Source/cmTryCompileCommand.cxx42
-rw-r--r--Source/cmTryCompileCommand.h119
-rw-r--r--Source/cmTryRunCommand.cxx387
-rw-r--r--Source/cmTryRunCommand.h118
-rw-r--r--Source/cmUnsetCommand.cxx59
-rw-r--r--Source/cmUnsetCommand.h79
-rw-r--r--Source/cmUseMangledMesaCommand.cxx131
-rw-r--r--Source/cmUseMangledMesaCommand.h88
-rw-r--r--Source/cmUtilitySourceCommand.cxx127
-rw-r--r--Source/cmUtilitySourceCommand.h90
-rw-r--r--Source/cmVS10CLFlagTable.h270
-rw-r--r--Source/cmVS10LibFlagTable.h102
-rw-r--r--Source/cmVS10LinkFlagTable.h305
-rw-r--r--Source/cmVariableRequiresCommand.cxx76
-rw-r--r--Source/cmVariableRequiresCommand.h82
-rw-r--r--Source/cmVariableWatch.cxx93
-rw-r--r--Source/cmVariableWatch.h80
-rw-r--r--Source/cmVariableWatchCommand.cxx140
-rw-r--r--Source/cmVariableWatchCommand.h98
-rw-r--r--Source/cmVersion.cxx24
-rw-r--r--Source/cmVersion.h39
-rw-r--r--Source/cmVersionConfig.h.in16
-rw-r--r--Source/cmVersionMacros.h22
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx1684
-rw-r--r--Source/cmVisualStudio10TargetGenerator.h114
-rw-r--r--Source/cmVisualStudioGeneratorOptions.cxx370
-rw-r--r--Source/cmVisualStudioGeneratorOptions.h79
-rw-r--r--Source/cmWhileCommand.cxx142
-rw-r--r--Source/cmWhileCommand.h101
-rw-r--r--Source/cmWin32ProcessExecution.cxx940
-rw-r--r--Source/cmWin32ProcessExecution.h169
-rw-r--r--Source/cmWriteFileCommand.cxx93
-rw-r--r--Source/cmWriteFileCommand.h85
-rw-r--r--Source/cmXCode21Object.cxx105
-rw-r--r--Source/cmXCode21Object.h28
-rw-r--r--Source/cmXCodeObject.cxx273
-rw-r--r--Source/cmXCodeObject.h179
-rw-r--r--Source/cmXMLParser.cxx237
-rw-r--r--Source/cmXMLParser.h112
-rw-r--r--Source/cmXMLSafe.cxx102
-rw-r--r--Source/cmXMLSafe.h44
-rw-r--r--Source/cm_sha2.c1613
-rw-r--r--Source/cm_sha2.h140
-rw-r--r--Source/cm_sha2_mangle.h51
-rw-r--r--Source/cm_utf8.c84
-rw-r--r--Source/cm_utf8.h29
-rw-r--r--Source/cmake.cxx4529
-rw-r--r--Source/cmake.h545
-rw-r--r--Source/cmakemain.cxx658
-rw-r--r--Source/cmaketest.h.in16
-rw-r--r--Source/cmakewizard.cxx158
-rw-r--r--Source/cmakewizard.h42
-rw-r--r--Source/cmakexbuild.cxx92
-rw-r--r--Source/cmcldeps.cxx285
-rwxr-xr-xSource/cmparseMSBuildXML.py329
-rw-r--r--Source/cmw9xcom.cxx45
-rw-r--r--Source/ctest.cxx343
-rw-r--r--Source/kwsys/Base64.c279
-rw-r--r--Source/kwsys/Base64.h.in120
-rw-r--r--Source/kwsys/CMakeEmptyInputFile.in1
-rw-r--r--Source/kwsys/CMakeLists.txt1042
-rw-r--r--Source/kwsys/CPU.h.in117
-rw-r--r--Source/kwsys/CTestConfig.cmake18
-rw-r--r--Source/kwsys/CommandLineArguments.cxx859
-rw-r--r--Source/kwsys/CommandLineArguments.hxx.in286
-rw-r--r--Source/kwsys/Configure.h.in145
-rw-r--r--Source/kwsys/Configure.hxx.in175
-rw-r--r--Source/kwsys/Copyright.txt31
-rw-r--r--Source/kwsys/Directory.cxx250
-rw-r--r--Source/kwsys/Directory.hxx.in80
-rw-r--r--Source/kwsys/DynamicLoader.cxx482
-rw-r--r--Source/kwsys/DynamicLoader.hxx.in101
-rw-r--r--Source/kwsys/EncodeExecutable.c114
-rw-r--r--Source/kwsys/ExtraTest.cmake.in1
-rw-r--r--Source/kwsys/FundamentalType.h.in146
-rw-r--r--Source/kwsys/Glob.cxx516
-rw-r--r--Source/kwsys/Glob.hxx.in117
-rw-r--r--Source/kwsys/IOStream.cxx281
-rw-r--r--Source/kwsys/IOStream.hxx.in146
-rw-r--r--Source/kwsys/MD5.c518
-rw-r--r--Source/kwsys/MD5.h.in107
-rw-r--r--Source/kwsys/Process.h.in428
-rw-r--r--Source/kwsys/ProcessFwd9x.c211
-rw-r--r--Source/kwsys/ProcessUNIX.c2753
-rw-r--r--Source/kwsys/ProcessWin32.c2952
-rw-r--r--Source/kwsys/README.txt10
-rw-r--r--Source/kwsys/Registry.cxx818
-rw-r--r--Source/kwsys/Registry.hxx.in107
-rw-r--r--Source/kwsys/RegularExpression.cxx1251
-rw-r--r--Source/kwsys/RegularExpression.hxx.in414
-rw-r--r--Source/kwsys/SharedForward.h.in922
-rw-r--r--Source/kwsys/String.c115
-rw-r--r--Source/kwsys/String.h.in67
-rw-r--r--Source/kwsys/String.hxx.in65
-rw-r--r--Source/kwsys/System.c856
-rw-r--r--Source/kwsys/System.h.in162
-rw-r--r--Source/kwsys/SystemInformation.cxx3675
-rw-r--r--Source/kwsys/SystemInformation.hxx.in88
-rw-r--r--Source/kwsys/SystemTools.cxx4856
-rw-r--r--Source/kwsys/SystemTools.hxx.in904
-rw-r--r--Source/kwsys/Terminal.c432
-rw-r--r--Source/kwsys/Terminal.h.in159
-rw-r--r--Source/kwsys/auto_ptr.hxx.in201
-rw-r--r--Source/kwsys/hash_fun.hxx.in149
-rw-r--r--Source/kwsys/hash_map.hxx.in461
-rw-r--r--Source/kwsys/hash_set.hxx.in445
-rw-r--r--Source/kwsys/hashtable.hxx.in1275
-rwxr-xr-xSource/kwsys/kwsysHeaderDump.pl50
-rw-r--r--Source/kwsys/kwsysPlatformTests.cmake216
-rw-r--r--Source/kwsys/kwsysPlatformTestsC.c100
-rw-r--r--Source/kwsys/kwsysPlatformTestsCXX.cxx516
-rw-r--r--Source/kwsys/kwsysPrivate.h41
-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/testAutoPtr.cxx166
-rw-r--r--Source/kwsys/testCommandLineArguments.cxx187
-rw-r--r--Source/kwsys/testCommandLineArguments1.cxx106
-rw-r--r--Source/kwsys/testDynamicLoader.cxx133
-rw-r--r--Source/kwsys/testDynload.c22
-rw-r--r--Source/kwsys/testEncode.c76
-rw-r--r--Source/kwsys/testFail.c35
-rw-r--r--Source/kwsys/testHashSTL.cxx75
-rw-r--r--Source/kwsys/testIOS.cxx167
-rw-r--r--Source/kwsys/testProcess.c526
-rw-r--r--Source/kwsys/testRegistry.cxx109
-rw-r--r--Source/kwsys/testSharedForward.c.in36
-rw-r--r--Source/kwsys/testSystemInformation.cxx65
-rw-r--r--Source/kwsys/testSystemTools.binbin0 -> 766 bytes
-rw-r--r--Source/kwsys/testSystemTools.cxx414
-rw-r--r--Source/kwsys/testSystemTools.h.in20
-rw-r--r--Source/kwsys/testTerminal.c31
-rw-r--r--Templates/AppleInfo.plist36
-rw-r--r--Templates/CMakeVSMacros1.vsmacrosbin0 -> 88064 bytes
-rw-r--r--Templates/CMakeVSMacros2.vsmacrosbin0 -> 63488 bytes
-rw-r--r--Templates/CMakeVisualStudio6Configurations.cmake3
-rw-r--r--Templates/CPack.GenericDescription.txt5
-rw-r--r--Templates/CPack.GenericLicense.txt5
-rw-r--r--Templates/CPack.GenericWelcome.txt1
-rw-r--r--Templates/CPackConfig.cmake.in12
-rw-r--r--Templates/CTestScript.cmake.in33
-rw-r--r--Templates/DLLFooter.dsptemplate4
-rw-r--r--Templates/DLLHeader.dsptemplate192
-rw-r--r--Templates/EXEFooter.dsptemplate4
-rw-r--r--Templates/EXEHeader.dsptemplate183
-rw-r--r--Templates/EXEWinHeader.dsptemplate187
-rw-r--r--Templates/TestDriver.cxx.in155
-rw-r--r--Templates/UtilityFooter.dsptemplate2
-rw-r--r--Templates/UtilityHeader.dsptemplate95
-rwxr-xr-xTemplates/cygwin-package.sh.in103
-rw-r--r--Templates/staticLibFooter.dsptemplate4
-rw-r--r--Templates/staticLibHeader.dsptemplate173
-rw-r--r--Tests/.NoDartCoverage1
-rw-r--r--Tests/Architecture/CMakeLists.txt59
-rw-r--r--Tests/Architecture/bar.c2
-rw-r--r--Tests/Architecture/foo.c1
-rw-r--r--Tests/ArgumentExpansion/CMakeLists.txt60
-rw-r--r--Tests/Assembler/CMakeLists.txt33
-rw-r--r--Tests/Assembler/main-linux-x86-gas.s28
-rw-r--r--Tests/Assembler/main.c12
-rw-r--r--Tests/BuildDepends/CMakeLists.txt225
-rw-r--r--Tests/BuildDepends/Project/CMakeLists.txt109
-rw-r--r--Tests/BuildDepends/Project/bar.cxx25
-rw-r--r--Tests/BuildDepends/Project/dep.cxx1
-rw-r--r--Tests/BuildDepends/Project/dep_custom.cxx1
-rw-r--r--Tests/BuildDepends/Project/generator.cxx24
-rw-r--r--Tests/BuildDepends/Project/linkdep.cxx4
-rw-r--r--Tests/BuildDepends/Project/zot.cxx14
-rw-r--r--Tests/BuildDepends/Project/zot_macro_dir.cxx7
-rw-r--r--Tests/BuildDepends/Project/zot_macro_tgt.cxx7
-rw-r--r--Tests/BundleGeneratorTest/BundleIcon.icnsbin0 -> 33452 bytes
-rw-r--r--Tests/BundleGeneratorTest/CMakeLists.txt33
-rw-r--r--Tests/BundleGeneratorTest/CustomVolumeIcon.icnsbin0 -> 37827 bytes
-rw-r--r--Tests/BundleGeneratorTest/Executable.cxx8
-rw-r--r--Tests/BundleGeneratorTest/Info.plist14
-rw-r--r--Tests/BundleGeneratorTest/Library.cxx7
-rwxr-xr-xTests/BundleGeneratorTest/StartupCommand12
-rw-r--r--Tests/BundleTest/BundleLib.cxx70
-rw-r--r--Tests/BundleTest/BundleSubDir/CMakeLists.txt36
-rw-r--r--Tests/BundleTest/BundleTest.cxx20
-rw-r--r--Tests/BundleTest/CMakeLists.txt104
-rw-r--r--Tests/BundleTest/SomeRandomFile.txt0
-rw-r--r--Tests/BundleTest/randomResourceFile.plist.in9
-rw-r--r--Tests/BundleUtilities/CMakeLists.txt133
-rw-r--r--Tests/BundleUtilities/bundleutils.cmake45
-rw-r--r--Tests/BundleUtilities/framework.cpp8
-rw-r--r--Tests/BundleUtilities/framework.h17
-rw-r--r--Tests/BundleUtilities/module.cpp10
-rw-r--r--Tests/BundleUtilities/module.h7
-rw-r--r--Tests/BundleUtilities/shared.cpp8
-rw-r--r--Tests/BundleUtilities/shared.h17
-rw-r--r--Tests/BundleUtilities/shared2.cpp8
-rw-r--r--Tests/BundleUtilities/shared2.h17
-rw-r--r--Tests/BundleUtilities/testbundleutils1.cpp33
-rw-r--r--Tests/BundleUtilities/testbundleutils2.cpp33
-rw-r--r--Tests/BundleUtilities/testbundleutils3.cpp33
-rw-r--r--Tests/CFBundleTest/CMakeLists.txt56
-rw-r--r--Tests/CFBundleTest/ExportList_plugin.txt3
-rw-r--r--Tests/CFBundleTest/Info.plist.in54
-rw-r--r--Tests/CFBundleTest/InfoPlist.strings.in4
-rw-r--r--Tests/CFBundleTest/Localized.r18
-rw-r--r--Tests/CFBundleTest/Localized.rsrcbin0 -> 496 bytes
-rw-r--r--Tests/CFBundleTest/PluginConfig.cmake21
-rw-r--r--Tests/CFBundleTest/README.txt16
-rw-r--r--Tests/CFBundleTest/VerifyResult.cmake32
-rw-r--r--Tests/CFBundleTest/np_macmain.cpp49
-rw-r--r--Tests/CMakeBuildTest.cmake.in59
-rw-r--r--Tests/CMakeCommands/target_link_libraries/CMakeLists.txt58
-rw-r--r--Tests/CMakeCommands/target_link_libraries/depA.cpp7
-rw-r--r--Tests/CMakeCommands/target_link_libraries/depA.h7
-rw-r--r--Tests/CMakeCommands/target_link_libraries/depB.cpp11
-rw-r--r--Tests/CMakeCommands/target_link_libraries/depB.h7
-rw-r--r--Tests/CMakeCommands/target_link_libraries/depC.cpp13
-rw-r--r--Tests/CMakeCommands/target_link_libraries/depC.h12
-rw-r--r--Tests/CMakeCommands/target_link_libraries/targetA.cpp12
-rw-r--r--Tests/CMakeInstall.cmake51
-rw-r--r--Tests/CMakeLib/CMakeLists.txt39
-rw-r--r--Tests/CMakeLib/run_compile_commands.cxx141
-rw-r--r--Tests/CMakeLib/testGeneratedFileStream.cxx100
-rw-r--r--Tests/CMakeLib/testSystemTools.cxx33
-rw-r--r--Tests/CMakeLib/testUTF8.cxx125
-rw-r--r--Tests/CMakeLib/testXMLParser.cxx17
-rw-r--r--Tests/CMakeLib/testXMLParser.h.in6
-rw-r--r--Tests/CMakeLib/testXMLParser.xml4
-rw-r--r--Tests/CMakeLib/testXMLSafe.cxx47
-rw-r--r--Tests/CMakeLists.txt2404
-rw-r--r--Tests/CMakeOnly/AllFindModules/CMakeLists.txt84
-rw-r--r--Tests/CMakeOnly/CMakeLists.txt30
-rw-r--r--Tests/CMakeOnly/CheckCXXCompilerFlag/CMakeLists.txt58
-rw-r--r--Tests/CMakeOnly/CheckCXXSymbolExists/CMakeLists.txt62
-rw-r--r--Tests/CMakeOnly/CheckLanguage/CMakeLists.txt22
-rw-r--r--Tests/CMakeOnly/CheckSymbolExists/CMakeLists.txt51
-rw-r--r--Tests/CMakeOnly/CheckSymbolExists/cm_cse.h6
-rw-r--r--Tests/CMakeOnly/LinkInterfaceLoop/CMakeLists.txt27
-rw-r--r--Tests/CMakeOnly/LinkInterfaceLoop/lib.c1
-rw-r--r--Tests/CMakeOnly/LinkInterfaceLoop/main.c1
-rw-r--r--Tests/CMakeOnly/ProjectInclude/CMakeLists.txt4
-rw-r--r--Tests/CMakeOnly/ProjectInclude/include.cmake1
-rw-r--r--Tests/CMakeOnly/TargetScope/CMakeLists.txt13
-rw-r--r--Tests/CMakeOnly/TargetScope/Sib/CMakeLists.txt6
-rw-r--r--Tests/CMakeOnly/TargetScope/Sub/CMakeLists.txt9
-rw-r--r--Tests/CMakeOnly/TargetScope/Sub/Sub/CMakeLists.txt6
-rw-r--r--Tests/CMakeOnly/Test.cmake.in13
-rw-r--r--Tests/CMakeTestAllGenerators/RunCMake.cmake117
-rw-r--r--Tests/CMakeTestBadCommandLines/RunCMake.cmake79
-rw-r--r--Tests/CMakeTestMultipleConfigures/RunCMake.cmake165
-rw-r--r--Tests/CMakeTests/.gitattributes1
-rw-r--r--Tests/CMakeTests/A/include/cmake_i_do_not_exist_in_the_system.h1
-rw-r--r--Tests/CMakeTests/CMakeLists.txt69
-rw-r--r--Tests/CMakeTests/CMakeMinimumRequiredTest.cmake.in18
-rw-r--r--Tests/CMakeTests/CMakeMinimumRequiredTestScript.cmake31
-rw-r--r--Tests/CMakeTests/CheckCMakeTest.cmake30
-rw-r--r--Tests/CMakeTests/CheckSourceTreeTest.cmake.in357
-rw-r--r--Tests/CMakeTests/CompilerIdVendorTest.cmake.in31
-rw-r--r--Tests/CMakeTests/ConfigureFile-BadArg.cmake1
-rw-r--r--Tests/CMakeTests/ConfigureFile-DirInput.cmake1
-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/DummyToolchain.cmake8
-rw-r--r--Tests/CMakeTests/ELF/elf32lsb.binbin0 -> 2824 bytes
-rw-r--r--Tests/CMakeTests/ELF/elf32msb.binbin0 -> 17984 bytes
-rw-r--r--Tests/CMakeTests/ELF/elf64lsb.binbin0 -> 4320 bytes
-rw-r--r--Tests/CMakeTests/ELF/elf64msb.binbin0 -> 18704 bytes
-rw-r--r--Tests/CMakeTests/ELFTest.cmake.in48
-rw-r--r--Tests/CMakeTests/EndStuffTest.cmake.in18
-rw-r--r--Tests/CMakeTests/EndStuffTestScript.cmake70
-rw-r--r--Tests/CMakeTests/ExecuteScriptTests.cmake63
-rw-r--r--Tests/CMakeTests/File-Copy-BadArg.cmake1
-rw-r--r--Tests/CMakeTests/File-Copy-BadPerm.cmake1
-rw-r--r--Tests/CMakeTests/File-Copy-BadRegex.cmake1
-rw-r--r--Tests/CMakeTests/File-Copy-EarlyArg.cmake1
-rw-r--r--Tests/CMakeTests/File-Copy-LateArg.cmake1
-rw-r--r--Tests/CMakeTests/File-Copy-NoDest.cmake1
-rw-r--r--Tests/CMakeTests/File-Copy-NoFile.cmake1
-rw-r--r--Tests/CMakeTests/File-HASH-Input.txt1
-rw-r--r--Tests/CMakeTests/File-MD5-BadArg1.cmake1
-rw-r--r--Tests/CMakeTests/File-MD5-BadArg2.cmake1
-rw-r--r--Tests/CMakeTests/File-MD5-BadArg4.cmake1
-rw-r--r--Tests/CMakeTests/File-MD5-NoFile.cmake1
-rw-r--r--Tests/CMakeTests/File-MD5-Works.cmake2
-rw-r--r--Tests/CMakeTests/File-SHA1-Works.cmake2
-rw-r--r--Tests/CMakeTests/File-SHA224-Works.cmake2
-rw-r--r--Tests/CMakeTests/File-SHA256-Works.cmake2
-rw-r--r--Tests/CMakeTests/File-SHA384-Works.cmake2
-rw-r--r--Tests/CMakeTests/File-SHA512-Works.cmake2
-rw-r--r--Tests/CMakeTests/FileDownloadInput.pngbin0 -> 358 bytes
-rw-r--r--Tests/CMakeTests/FileDownloadTest.cmake.in43
-rw-r--r--Tests/CMakeTests/FileTest.cmake.in74
-rw-r--r--Tests/CMakeTests/FileTestScript.cmake227
-rw-r--r--Tests/CMakeTests/FileUploadTest.cmake.in49
-rw-r--r--Tests/CMakeTests/FindBaseTest.cmake.in62
-rw-r--r--Tests/CMakeTests/GetFilenameComponentRealpathTest.cmake.in72
-rw-r--r--Tests/CMakeTests/GetPrerequisitesTest.cmake.in159
-rw-r--r--Tests/CMakeTests/GetProperty-Bad-Argument.cmake1
-rw-r--r--Tests/CMakeTests/GetProperty-Bad-Directory.cmake1
-rw-r--r--Tests/CMakeTests/GetProperty-Bad-Scope.cmake1
-rw-r--r--Tests/CMakeTests/GetProperty-Bad-Target.cmake1
-rw-r--r--Tests/CMakeTests/GetProperty-Bad-Test.cmake1
-rw-r--r--Tests/CMakeTests/GetProperty-Doc-Properties.cmake10
-rw-r--r--Tests/CMakeTests/GetProperty-Global-Name.cmake1
-rw-r--r--Tests/CMakeTests/GetProperty-Missing-Argument.cmake1
-rw-r--r--Tests/CMakeTests/GetProperty-No-Cache.cmake1
-rw-r--r--Tests/CMakeTests/GetProperty-No-Property.cmake1
-rw-r--r--Tests/CMakeTests/GetProperty-No-Source.cmake1
-rw-r--r--Tests/CMakeTests/GetProperty-No-Target.cmake1
-rw-r--r--Tests/CMakeTests/GetProperty-No-Test.cmake1
-rw-r--r--Tests/CMakeTests/GetProperty-Variable-Name.cmake1
-rw-r--r--Tests/CMakeTests/GetPropertyTest.cmake.in98
-rw-r--r--Tests/CMakeTests/If-Invalid-Argument.cmake2
-rw-r--r--Tests/CMakeTests/IfTest.cmake.in166
-rw-r--r--Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in420
-rw-r--r--Tests/CMakeTests/IncludeTest.cmake.in41
-rw-r--r--Tests/CMakeTests/ListTest.cmake.in88
-rw-r--r--Tests/CMakeTests/MathTest.cmake.in18
-rw-r--r--Tests/CMakeTests/MathTestScript.cmake18
-rw-r--r--Tests/CMakeTests/MessageTest.cmake.in30
-rw-r--r--Tests/CMakeTests/MessageTestScript.cmake4
-rw-r--r--Tests/CMakeTests/ModuleNoticesTest.cmake.in46
-rw-r--r--Tests/CMakeTests/ProcessorCountTest.cmake.in72
-rw-r--r--Tests/CMakeTests/PushCheckStateTest.cmake.in30
-rw-r--r--Tests/CMakeTests/SeparateArgumentsTest.cmake.in25
-rw-r--r--Tests/CMakeTests/String-MD5-BadArg1.cmake1
-rw-r--r--Tests/CMakeTests/String-MD5-BadArg2.cmake1
-rw-r--r--Tests/CMakeTests/String-MD5-BadArg4.cmake1
-rw-r--r--Tests/CMakeTests/String-MD5-Works.cmake2
-rw-r--r--Tests/CMakeTests/String-SHA1-Works.cmake2
-rw-r--r--Tests/CMakeTests/String-SHA224-Works.cmake2
-rw-r--r--Tests/CMakeTests/String-SHA256-Works.cmake2
-rw-r--r--Tests/CMakeTests/String-SHA384-Works.cmake2
-rw-r--r--Tests/CMakeTests/String-SHA512-Works.cmake2
-rw-r--r--Tests/CMakeTests/StringTest.cmake.in50
-rw-r--r--Tests/CMakeTests/StringTestScript.cmake279
-rw-r--r--Tests/CMakeTests/ToolchainTest.cmake.in139
-rw-r--r--Tests/CMakeTests/VariableWatchTest.cmake.in31
-rw-r--r--Tests/CMakeTests/VersionTest.cmake.in9
-rw-r--r--Tests/CMakeTests/While-Endwhile-Alone-Args.cmake1
-rw-r--r--Tests/CMakeTests/While-Endwhile-Alone.cmake1
-rw-r--r--Tests/CMakeTests/While-Endwhile-Mismatch.cmake2
-rw-r--r--Tests/CMakeTests/While-Missing-Argument.cmake1
-rw-r--r--Tests/CMakeTests/While-Missing-Endwhile.cmake1
-rw-r--r--Tests/CMakeTests/WhileTest.cmake.in53
-rw-r--r--Tests/CMakeTests/include/cmake_i_do_not_exist_in_the_system.h1
-rw-r--r--Tests/CMakeWizardTest.cmake52
-rw-r--r--Tests/COnly/CMakeLists.txt23
-rw-r--r--Tests/COnly/conly.c23
-rw-r--r--Tests/COnly/foo.c1
-rw-r--r--Tests/COnly/foo.h1
-rw-r--r--Tests/COnly/libc1.c4
-rw-r--r--Tests/COnly/libc1.h1
-rw-r--r--Tests/COnly/libc2.c6
-rw-r--r--Tests/COnly/libc2.h11
-rw-r--r--Tests/COnly/testCModule.c6
-rw-r--r--Tests/CPackComponents/CMakeLists.txt128
-rw-r--r--Tests/CPackComponents/Issue 7470.html9
-rw-r--r--Tests/CPackComponents/VerifyResult.cmake48
-rw-r--r--Tests/CPackComponents/mylib.cpp7
-rw-r--r--Tests/CPackComponents/mylib.h1
-rw-r--r--Tests/CPackComponents/mylibapp.cpp6
-rw-r--r--Tests/CPackComponentsForAll/CMakeLists.txt123
-rw-r--r--Tests/CPackComponentsForAll/MyLibCPackConfig-AllInOne.cmake.in22
-rw-r--r--Tests/CPackComponentsForAll/MyLibCPackConfig-IgnoreGroup.cmake.in23
-rw-r--r--Tests/CPackComponentsForAll/MyLibCPackConfig-OnePackPerGroup.cmake.in27
-rw-r--r--Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake126
-rw-r--r--Tests/CPackComponentsForAll/mylib.cpp7
-rw-r--r--Tests/CPackComponentsForAll/mylib.h1
-rw-r--r--Tests/CPackComponentsForAll/mylibapp.cpp6
-rw-r--r--Tests/CPackTestAllGenerators/CMakeLists.txt5
-rw-r--r--Tests/CPackTestAllGenerators/RunCPack.cmake55
-rw-r--r--Tests/CTestConfig/CMakeLists.txt47
-rw-r--r--Tests/CTestConfig/CTestConfig.cxx20
-rw-r--r--Tests/CTestConfig/ScriptWithArgs.cmake16
-rw-r--r--Tests/CTestConfig/dashboard.cmake.in43
-rw-r--r--Tests/CTestConfig/script.cmake.in21
-rw-r--r--Tests/CTestScriptMode/CTestTestScriptMode.cmake.in14
-rw-r--r--Tests/CTestTest/SmallAndFast/CMakeLists.txt25
-rw-r--r--Tests/CTestTest/SmallAndFast/echoargs.c11
-rw-r--r--Tests/CTestTest/SmallAndFast/intentional_compile_error.cxx1
-rw-r--r--Tests/CTestTest/SmallAndFast/intentional_compile_warning.cxx11
-rw-r--r--Tests/CTestTest/test.cmake.in68
-rw-r--r--Tests/CTestTest2/test.cmake.in60
-rw-r--r--Tests/CTestTestBadExe/CMakeLists.txt7
-rw-r--r--Tests/CTestTestBadExe/CTestConfig.cmake7
-rw-r--r--Tests/CTestTestBadExe/notAnExe.txt1
-rw-r--r--Tests/CTestTestBadExe/test.cmake.in21
-rw-r--r--Tests/CTestTestChecksum/test.cmake.in25
-rw-r--r--Tests/CTestTestConfigFileInBuildDir/CMakeLists.txt3
-rw-r--r--Tests/CTestTestConfigFileInBuildDir/CTestConfig.cmake7
-rw-r--r--Tests/CTestTestConfigFileInBuildDir/test1.cmake.in17
-rw-r--r--Tests/CTestTestConfigFileInBuildDir/test2.cmake.in17
-rw-r--r--Tests/CTestTestCostSerial/CMakeLists.txt13
-rw-r--r--Tests/CTestTestCostSerial/CTestConfig.cmake7
-rw-r--r--Tests/CTestTestCostSerial/sleep.c16
-rw-r--r--Tests/CTestTestCostSerial/test.cmake.in28
-rw-r--r--Tests/CTestTestCrash/CMakeLists.txt7
-rw-r--r--Tests/CTestTestCrash/CTestConfig.cmake7
-rw-r--r--Tests/CTestTestCrash/crash.cxx6
-rw-r--r--Tests/CTestTestCrash/test.cmake.in22
-rw-r--r--Tests/CTestTestCycle/CMakeLists.txt13
-rw-r--r--Tests/CTestTestCycle/CTestConfig.cmake7
-rw-r--r--Tests/CTestTestCycle/simple.cxx5
-rw-r--r--Tests/CTestTestCycle/test.cmake.in19
-rw-r--r--Tests/CTestTestDepends/CMakeLists.txt12
-rw-r--r--Tests/CTestTestDepends/CTestConfig.cmake7
-rw-r--r--Tests/CTestTestDepends/simple.cxx5
-rw-r--r--Tests/CTestTestDepends/test.cmake.in19
-rw-r--r--Tests/CTestTestFailedSubmits/test.cmake.in47
-rw-r--r--Tests/CTestTestFailure/CMakeLists.txt8
-rw-r--r--Tests/CTestTestFailure/CTestConfig.cmake7
-rw-r--r--Tests/CTestTestFailure/badCode.cxx4
-rw-r--r--Tests/CTestTestFailure/testNoBuild.cmake.in21
-rw-r--r--Tests/CTestTestFailure/testNoExe.cmake.in19
-rw-r--r--Tests/CTestTestParallel/CMakeLists.txt15
-rw-r--r--Tests/CTestTestParallel/CTestConfig.cmake7
-rw-r--r--Tests/CTestTestParallel/lockFile.c20
-rw-r--r--Tests/CTestTestParallel/test.cmake.in21
-rw-r--r--Tests/CTestTestResourceLock/CMakeLists.txt13
-rw-r--r--Tests/CTestTestResourceLock/CTestConfig.cmake7
-rw-r--r--Tests/CTestTestResourceLock/lockFile.c31
-rw-r--r--Tests/CTestTestResourceLock/test.cmake.in19
-rw-r--r--Tests/CTestTestRunScript/hello.cmake.in2
-rw-r--r--Tests/CTestTestRunScript/test.cmake.in2
-rw-r--r--Tests/CTestTestScheduler/CMakeLists.txt9
-rw-r--r--Tests/CTestTestScheduler/CTestConfig.cmake7
-rw-r--r--Tests/CTestTestScheduler/sleep.c21
-rw-r--r--Tests/CTestTestScheduler/test.cmake.in28
-rw-r--r--Tests/CTestTestStopTime/CMakeLists.txt11
-rw-r--r--Tests/CTestTestStopTime/CTestConfig.cmake7
-rw-r--r--Tests/CTestTestStopTime/GetDate.cmake233
-rw-r--r--Tests/CTestTestStopTime/sleep.c21
-rw-r--r--Tests/CTestTestStopTime/test.cmake.in31
-rw-r--r--Tests/CTestTestSubdir/CMakeLists.txt7
-rw-r--r--Tests/CTestTestSubdir/CTestConfig.cmake7
-rw-r--r--Tests/CTestTestSubdir/subdir/CMakeLists.txt2
-rw-r--r--Tests/CTestTestSubdir/subdir/main.c4
-rw-r--r--Tests/CTestTestSubdir/subdir2/CMakeLists.txt2
-rw-r--r--Tests/CTestTestSubdir/subdir2/main.c4
-rw-r--r--Tests/CTestTestSubdir/subdir3/CMakeLists.txt2
-rw-r--r--Tests/CTestTestSubdir/subdir3/main.c4
-rw-r--r--Tests/CTestTestSubdir/test.cmake.in21
-rw-r--r--Tests/CTestTestTimeout/CMakeLists.txt28
-rw-r--r--Tests/CTestTestTimeout/CTestConfig.cmake7
-rw-r--r--Tests/CTestTestTimeout/check.cmake9
-rw-r--r--Tests/CTestTestTimeout/test.cmake.in25
-rw-r--r--Tests/CTestTestTimeout/timeout.c18
-rw-r--r--Tests/CTestTestTimeout/timeout.cmake6
-rw-r--r--Tests/CTestTestUpload/CMakeLists.txt4
-rw-r--r--Tests/CTestTestUpload/CTestConfig.cmake7
-rw-r--r--Tests/CTestTestUpload/sleep.c21
-rw-r--r--Tests/CTestTestUpload/test.cmake.in17
-rw-r--r--Tests/CTestTestZeroTimeout/CMakeLists.txt8
-rw-r--r--Tests/CTestTestZeroTimeout/CTestConfig.cmake7
-rw-r--r--Tests/CTestTestZeroTimeout/sleep.c16
-rw-r--r--Tests/CTestTestZeroTimeout/test.cmake.in20
-rw-r--r--Tests/CTestUpdateBZR.cmake.in153
-rw-r--r--Tests/CTestUpdateCVS.cmake.in172
-rw-r--r--Tests/CTestUpdateCommon.cmake234
-rw-r--r--Tests/CTestUpdateGIT.cmake.in317
-rwxr-xr-xTests/CTestUpdateGIT.sh.in6
-rw-r--r--Tests/CTestUpdateHG.cmake.in166
-rw-r--r--Tests/CTestUpdateSVN.cmake.in149
-rw-r--r--Tests/CheckCompilerRelatedVariables/CMakeLists.txt90
-rw-r--r--Tests/CheckFortran.cmake50
-rw-r--r--Tests/CommandLineTest/CMakeLists.txt79
-rw-r--r--Tests/CommandLineTest/CommandLineTest.cxx4
-rw-r--r--Tests/CommandLineTest/PreLoad.cmake1
-rw-r--r--Tests/CompileCommandOutput/CMakeLists.txt16
-rw-r--r--Tests/CompileCommandOutput/compile_command_output.cxx9
-rw-r--r--Tests/CompileCommandOutput/file with spaces.cxx1
-rw-r--r--Tests/CompileCommandOutput/file_with_underscores.cxx3
-rw-r--r--Tests/CompileCommandOutput/file_with_underscores.h1
-rw-r--r--Tests/CompileCommandOutput/relative.cxx3
-rw-r--r--Tests/CompileCommandOutput/relative.h11
-rw-r--r--Tests/Complex/CMakeLists.txt406
-rw-r--r--Tests/Complex/Cache/CMakeCache.txt34
-rw-r--r--Tests/Complex/Executable/A.cxx9
-rw-r--r--Tests/Complex/Executable/A.h4
-rw-r--r--Tests/Complex/Executable/A.hh2
-rw-r--r--Tests/Complex/Executable/A.txt1
-rw-r--r--Tests/Complex/Executable/CMakeLists.txt170
-rw-r--r--Tests/Complex/Executable/Included.cmake2
-rw-r--r--Tests/Complex/Executable/Sub1/NameConflictTest.c4
-rw-r--r--Tests/Complex/Executable/Sub2/NameConflictTest.c4
-rw-r--r--Tests/Complex/Executable/Temp/CMakeLists.txt8
-rw-r--r--Tests/Complex/Executable/cmVersion.h.in1
-rw-r--r--Tests/Complex/Executable/complex.cxx1026
-rw-r--r--Tests/Complex/Executable/complex.file.cxx8
-rw-r--r--Tests/Complex/Executable/complex_nobuild.c1
-rw-r--r--Tests/Complex/Executable/complex_nobuild.cxx1
-rw-r--r--Tests/Complex/Executable/notInAllExe.cxx10
-rw-r--r--Tests/Complex/Executable/testSystemDir.cxx3
-rw-r--r--Tests/Complex/Executable/testcflags.c26
-rw-r--r--Tests/Complex/Library/CMakeLists.txt140
-rw-r--r--Tests/Complex/Library/ExtraSources/file1.cxx4
-rw-r--r--Tests/Complex/Library/ExtraSources/file1.h1
-rw-r--r--Tests/Complex/Library/SystemDir/testSystemDir.h2
-rw-r--r--Tests/Complex/Library/TestLink.c8
-rw-r--r--Tests/Complex/Library/create_file.cxx28
-rw-r--r--Tests/Complex/Library/dummy0
-rw-r--r--Tests/Complex/Library/empty.h0
-rw-r--r--Tests/Complex/Library/file2.cxx10
-rw-r--r--Tests/Complex/Library/file2.h1
-rw-r--r--Tests/Complex/Library/notInAllLib.cxx5
-rw-r--r--Tests/Complex/Library/sharedFile.cxx6
-rw-r--r--Tests/Complex/Library/sharedFile.h12
-rw-r--r--Tests/Complex/Library/testConly.c13
-rw-r--r--Tests/Complex/Library/testConly.h13
-rw-r--r--Tests/Complex/Library/test_preprocess.cmake7
-rw-r--r--Tests/Complex/VarTests.cmake198
-rw-r--r--Tests/Complex/cmTestConfigure.h.in85
-rw-r--r--Tests/Complex/cmTestConfigureEscape.h.in1
-rw-r--r--Tests/Complex/cmTestGeneratedHeader.h.in1
-rw-r--r--Tests/ComplexOneConfig/CMakeLists.txt376
-rw-r--r--Tests/ComplexOneConfig/Cache/CMakeCache.txt34
-rw-r--r--Tests/ComplexOneConfig/Executable/A.cxx9
-rw-r--r--Tests/ComplexOneConfig/Executable/A.h4
-rw-r--r--Tests/ComplexOneConfig/Executable/A.hh2
-rw-r--r--Tests/ComplexOneConfig/Executable/A.txt1
-rw-r--r--Tests/ComplexOneConfig/Executable/CMakeLists.txt170
-rw-r--r--Tests/ComplexOneConfig/Executable/Included.cmake2
-rw-r--r--Tests/ComplexOneConfig/Executable/Sub1/NameConflictTest.c4
-rw-r--r--Tests/ComplexOneConfig/Executable/Sub2/NameConflictTest.c4
-rw-r--r--Tests/ComplexOneConfig/Executable/Temp/CMakeLists.txt8
-rw-r--r--Tests/ComplexOneConfig/Executable/cmVersion.h.in1
-rw-r--r--Tests/ComplexOneConfig/Executable/complex.cxx1026
-rw-r--r--Tests/ComplexOneConfig/Executable/complex.file.cxx8
-rw-r--r--Tests/ComplexOneConfig/Executable/complex_nobuild.c1
-rw-r--r--Tests/ComplexOneConfig/Executable/complex_nobuild.cxx1
-rw-r--r--Tests/ComplexOneConfig/Executable/notInAllExe.cxx10
-rw-r--r--Tests/ComplexOneConfig/Executable/testSystemDir.cxx3
-rw-r--r--Tests/ComplexOneConfig/Executable/testcflags.c26
-rw-r--r--Tests/ComplexOneConfig/Library/CMakeLists.txt140
-rw-r--r--Tests/ComplexOneConfig/Library/ExtraSources/file1.cxx4
-rw-r--r--Tests/ComplexOneConfig/Library/ExtraSources/file1.h1
-rw-r--r--Tests/ComplexOneConfig/Library/SystemDir/testSystemDir.h2
-rw-r--r--Tests/ComplexOneConfig/Library/TestLink.c8
-rw-r--r--Tests/ComplexOneConfig/Library/create_file.cxx28
-rw-r--r--Tests/ComplexOneConfig/Library/dummy0
-rw-r--r--Tests/ComplexOneConfig/Library/empty.h0
-rw-r--r--Tests/ComplexOneConfig/Library/file2.cxx10
-rw-r--r--Tests/ComplexOneConfig/Library/file2.h1
-rw-r--r--Tests/ComplexOneConfig/Library/notInAllLib.cxx5
-rw-r--r--Tests/ComplexOneConfig/Library/sharedFile.cxx6
-rw-r--r--Tests/ComplexOneConfig/Library/sharedFile.h12
-rw-r--r--Tests/ComplexOneConfig/Library/testConly.c13
-rw-r--r--Tests/ComplexOneConfig/Library/testConly.h13
-rw-r--r--Tests/ComplexOneConfig/Library/test_preprocess.cmake7
-rw-r--r--Tests/ComplexOneConfig/VarTests.cmake198
-rw-r--r--Tests/ComplexOneConfig/cmTestConfigure.h.in85
-rw-r--r--Tests/ComplexOneConfig/cmTestConfigureEscape.h.in1
-rw-r--r--Tests/ComplexOneConfig/cmTestGeneratedHeader.h.in1
-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/EnvScript.cmake32
-rw-r--r--Tests/Contracts/Trilinos-10-6/Patch.cmake38
-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/cse-snapshot/CMakeLists.txt114
-rw-r--r--Tests/Contracts/cse-snapshot/Dashboard.cmake.in76
-rw-r--r--Tests/Contracts/cse-snapshot/RunTest.cmake3
-rw-r--r--Tests/Contracts/vtk542/CMakeLists.txt30
-rw-r--r--Tests/Contracts/vtk542/RunTest.cmake1
-rw-r--r--Tests/CrossCompile/CMakeLists.txt13
-rw-r--r--Tests/CrossCompile/main.c4
-rw-r--r--Tests/CustComDepend/CMakeLists.txt14
-rw-r--r--Tests/CustComDepend/bar.h9
-rw-r--r--Tests/CustComDepend/foo.cxx15
-rw-r--r--Tests/CustomCommand/CMakeLists.txt438
-rw-r--r--Tests/CustomCommand/GeneratedHeader/CMakeLists.txt13
-rw-r--r--Tests/CustomCommand/GeneratedHeader/generated.h.in1
-rw-r--r--Tests/CustomCommand/GeneratedHeader/main.cpp5
-rw-r--r--Tests/CustomCommand/GeneratorInExtraDir/CMakeLists.txt8
-rw-r--r--Tests/CustomCommand/check_command_line.c.in36
-rw-r--r--Tests/CustomCommand/check_mark.cmake5
-rw-r--r--Tests/CustomCommand/config.h.in1
-rw-r--r--Tests/CustomCommand/doc1.tex1
-rw-r--r--Tests/CustomCommand/foo.h.in1
-rw-r--r--Tests/CustomCommand/foo.in28
-rw-r--r--Tests/CustomCommand/gen_redirect_in.c5
-rw-r--r--Tests/CustomCommand/generator.cxx19
-rw-r--r--Tests/CustomCommand/main.cxx6
-rw-r--r--Tests/CustomCommand/tcat.cxx11
-rw-r--r--Tests/CustomCommand/wrapped.h1
-rw-r--r--Tests/CustomCommand/wrapper.cxx36
-rw-r--r--Tests/CustomCommandWorkingDirectory/CMakeLists.txt42
-rw-r--r--Tests/CustomCommandWorkingDirectory/customTarget.c4
-rw-r--r--Tests/CustomCommandWorkingDirectory/working.c.in7
-rw-r--r--Tests/CxxOnly/CMakeLists.txt13
-rw-r--r--Tests/CxxOnly/cxxonly.cxx25
-rw-r--r--Tests/CxxOnly/libcxx1.cxx6
-rw-r--r--Tests/CxxOnly/libcxx1.h5
-rw-r--r--Tests/CxxOnly/libcxx2.cxx6
-rw-r--r--Tests/CxxOnly/libcxx2.h15
-rw-r--r--Tests/CxxOnly/test.CPP1
-rw-r--r--Tests/CxxOnly/testCxxModule.cxx6
-rw-r--r--Tests/Dependency/1/CMakeLists.txt3
-rw-r--r--Tests/Dependency/1/OneSrc.c3
-rw-r--r--Tests/Dependency/CMakeLists.txt53
-rw-r--r--Tests/Dependency/Case1/CMakeLists.txt19
-rw-r--r--Tests/Dependency/Case1/a.c5
-rw-r--r--Tests/Dependency/Case1/b.c6
-rw-r--r--Tests/Dependency/Case1/b2.c4
-rw-r--r--Tests/Dependency/Case1/c.c6
-rw-r--r--Tests/Dependency/Case1/c2.c6
-rw-r--r--Tests/Dependency/Case1/d.c7
-rw-r--r--Tests/Dependency/Case1/main.c10
-rw-r--r--Tests/Dependency/Case2/CMakeLists.txt22
-rw-r--r--Tests/Dependency/Case2/bar1.c4
-rw-r--r--Tests/Dependency/Case2/bar2.c2
-rw-r--r--Tests/Dependency/Case2/bar3.c2
-rw-r--r--Tests/Dependency/Case2/foo1.c2
-rw-r--r--Tests/Dependency/Case2/foo1b.c2
-rw-r--r--Tests/Dependency/Case2/foo1c.c2
-rw-r--r--Tests/Dependency/Case2/foo2.c2
-rw-r--r--Tests/Dependency/Case2/foo2b.c2
-rw-r--r--Tests/Dependency/Case2/foo2c.c2
-rw-r--r--Tests/Dependency/Case2/foo3.c2
-rw-r--r--Tests/Dependency/Case2/foo3b.c2
-rw-r--r--Tests/Dependency/Case2/foo3c.c1
-rw-r--r--Tests/Dependency/Case2/zot.c5
-rw-r--r--Tests/Dependency/Case3/CMakeLists.txt10
-rw-r--r--Tests/Dependency/Case3/bar.c5
-rw-r--r--Tests/Dependency/Case3/foo1.c2
-rw-r--r--Tests/Dependency/Case3/foo1b.c1
-rw-r--r--Tests/Dependency/Case3/foo2.c2
-rw-r--r--Tests/Dependency/Case4/CMakeLists.txt19
-rw-r--r--Tests/Dependency/Case4/bar.c2
-rw-r--r--Tests/Dependency/Case4/foo.c1
-rw-r--r--Tests/Dependency/Eight/CMakeLists.txt3
-rw-r--r--Tests/Dependency/Eight/EightSrc.c6
-rw-r--r--Tests/Dependency/Exec/CMakeLists.txt7
-rw-r--r--Tests/Dependency/Exec/ExecMain.c18
-rw-r--r--Tests/Dependency/Exec2/CMakeLists.txt12
-rw-r--r--Tests/Dependency/Exec2/ExecMain.c14
-rw-r--r--Tests/Dependency/Exec3/CMakeLists.txt6
-rw-r--r--Tests/Dependency/Exec3/ExecMain.c14
-rw-r--r--Tests/Dependency/Exec4/CMakeLists.txt6
-rw-r--r--Tests/Dependency/Exec4/ExecMain.c14
-rw-r--r--Tests/Dependency/Five/CMakeLists.txt3
-rw-r--r--Tests/Dependency/Five/FiveSrc.c6
-rw-r--r--Tests/Dependency/Four/CMakeLists.txt6
-rw-r--r--Tests/Dependency/Four/FourSrc.c15
-rw-r--r--Tests/Dependency/NoDepA/CMakeLists.txt1
-rw-r--r--Tests/Dependency/NoDepA/NoDepASrc.c3
-rw-r--r--Tests/Dependency/NoDepB/CMakeLists.txt3
-rw-r--r--Tests/Dependency/NoDepB/NoDepBSrc.c6
-rw-r--r--Tests/Dependency/NoDepC/CMakeLists.txt3
-rw-r--r--Tests/Dependency/NoDepC/NoDepCSrc.c6
-rw-r--r--Tests/Dependency/Seven/CMakeLists.txt3
-rw-r--r--Tests/Dependency/Seven/SevenSrc.c6
-rw-r--r--Tests/Dependency/Six/CMakeLists.txt12
-rw-r--r--Tests/Dependency/Six/SixASrc.c8
-rw-r--r--Tests/Dependency/Six/SixBSrc.c10
-rw-r--r--Tests/Dependency/Three/CMakeLists.txt3
-rw-r--r--Tests/Dependency/Three/ThreeSrc.c12
-rw-r--r--Tests/Dependency/Two/CMakeLists.txt20
-rw-r--r--Tests/Dependency/Two/TwoCustomSrc.c10
-rw-r--r--Tests/Dependency/Two/TwoSrc.c10
-rw-r--r--Tests/Dependency/Two/two-test.h.in1
-rw-r--r--Tests/DocTest/CMakeLists.txt7
-rw-r--r--Tests/DocTest/DocTest.cxx33
-rw-r--r--Tests/DoubleProject/CMakeLists.txt3
-rw-r--r--Tests/DoubleProject/silly.c4
-rw-r--r--Tests/EmptyLibrary/CMakeLists.txt4
-rw-r--r--Tests/EmptyLibrary/subdir/CMakeLists.txt1
-rw-r--r--Tests/EmptyLibrary/subdir/test.h1
-rw-r--r--Tests/EnforceConfig.cmake.in26
-rw-r--r--Tests/Environment/CMakeLists.txt26
-rw-r--r--Tests/Environment/main.cxx16
-rw-r--r--Tests/ExportImport/CMakeLists.txt75
-rw-r--r--Tests/ExportImport/Export/CMakeLists.txt145
-rw-r--r--Tests/ExportImport/Export/testExe1.c26
-rw-r--r--Tests/ExportImport/Export/testExe1lib.c1
-rw-r--r--Tests/ExportImport/Export/testExe2.c12
-rw-r--r--Tests/ExportImport/Export/testExe2lib.c10
-rw-r--r--Tests/ExportImport/Export/testExe2libImp.c7
-rw-r--r--Tests/ExportImport/Export/testExe3.c24
-rw-r--r--Tests/ExportImport/Export/testLib1.c1
-rw-r--r--Tests/ExportImport/Export/testLib2.c4
-rw-r--r--Tests/ExportImport/Export/testLib3.c10
-rw-r--r--Tests/ExportImport/Export/testLib3Imp.c10
-rw-r--r--Tests/ExportImport/Export/testLib3ImpDep.c7
-rw-r--r--Tests/ExportImport/Export/testLib4.c7
-rw-r--r--Tests/ExportImport/Export/testLib4lib.c4
-rw-r--r--Tests/ExportImport/Export/testLib4libdbg.c14
-rw-r--r--Tests/ExportImport/Export/testLib4libdbg1.c1
-rw-r--r--Tests/ExportImport/Export/testLib4libopt.c14
-rw-r--r--Tests/ExportImport/Export/testLib4libopt1.c1
-rw-r--r--Tests/ExportImport/Export/testLib5.c7
-rw-r--r--Tests/ExportImport/Export/testLib6.cxx6
-rw-r--r--Tests/ExportImport/Export/testLib6c.c5
-rw-r--r--Tests/ExportImport/Export/testLibCycleA1.c2
-rw-r--r--Tests/ExportImport/Export/testLibCycleA2.c2
-rw-r--r--Tests/ExportImport/Export/testLibCycleA3.c2
-rw-r--r--Tests/ExportImport/Export/testLibCycleB1.c2
-rw-r--r--Tests/ExportImport/Export/testLibCycleB2.c2
-rw-r--r--Tests/ExportImport/Export/testLibCycleB3.c1
-rw-r--r--Tests/ExportImport/Import/A/CMakeLists.txt150
-rw-r--r--Tests/ExportImport/Import/A/imp_lib1.c6
-rw-r--r--Tests/ExportImport/Import/A/imp_mod1.c13
-rw-r--r--Tests/ExportImport/Import/A/imp_testExe1.c25
-rw-r--r--Tests/ExportImport/Import/CMakeLists.txt19
-rw-r--r--Tests/ExportImport/Import/imp_testTransExe1.c6
-rw-r--r--Tests/ExportImport/InitialCache.cmake.in15
-rw-r--r--Tests/ExportImport/main.c4
-rw-r--r--Tests/ExternalOBJ/CMakeLists.txt63
-rw-r--r--Tests/ExternalOBJ/Object/CMakeLists.txt13
-rw-r--r--Tests/ExternalOBJ/Object/external_main.cxx4
-rw-r--r--Tests/ExternalOBJ/Object/external_object.cxx4
-rw-r--r--Tests/ExternalOBJ/Sub/CMakeLists.txt3
-rw-r--r--Tests/ExternalOBJ/executable.cxx5
-rw-r--r--Tests/ExternalProject/CMakeLists.txt585
-rw-r--r--Tests/ExternalProject/Example/CMakeLists.txt11
-rw-r--r--Tests/ExternalProject/Step1.tarbin0 -> 5632 bytes
-rw-r--r--Tests/ExternalProject/Step1.tar.bz2bin0 -> 904 bytes
-rw-r--r--Tests/ExternalProject/Step1.tgzbin0 -> 791 bytes
-rw-r--r--Tests/ExternalProject/Step1.zipbin0 -> 1074 bytes
-rw-r--r--Tests/ExternalProject/Step1NoDir.tarbin0 -> 5120 bytes
-rw-r--r--Tests/ExternalProject/Step1NoDir.tar.bz2bin0 -> 852 bytes
-rw-r--r--Tests/ExternalProject/Step1NoDir.tgzbin0 -> 770 bytes
-rw-r--r--Tests/ExternalProject/Step1NoDir.zipbin0 -> 1038 bytes
-rw-r--r--Tests/ExternalProject/Step1Patch.cmake25
-rw-r--r--Tests/ExternalProject/TryCheckout.cmake54
-rw-r--r--Tests/ExternalProject/cvsrepo.tgzbin0 -> 1317 bytes
-rw-r--r--Tests/ExternalProject/gitrepo.tgzbin0 -> 1934 bytes
-rw-r--r--Tests/ExternalProject/svnrepo.tgzbin0 -> 3673 bytes
-rw-r--r--Tests/FindModulesExecuteAll/CMakeLists.txt30
-rw-r--r--Tests/FindModulesExecuteAll/main.c4
-rw-r--r--Tests/FindPackageModeMakefileTest/CMakeLists.txt31
-rw-r--r--Tests/FindPackageModeMakefileTest/FindFoo.cmake.in9
-rw-r--r--Tests/FindPackageModeMakefileTest/Makefile.in29
-rw-r--r--Tests/FindPackageModeMakefileTest/foo.cpp4
-rw-r--r--Tests/FindPackageModeMakefileTest/foo.h6
-rw-r--r--Tests/FindPackageModeMakefileTest/main.cpp8
-rw-r--r--Tests/FindPackageTest/A/wibble-config.cmake1
-rw-r--r--Tests/FindPackageTest/B/wibble-config.cmake1
-rw-r--r--Tests/FindPackageTest/Baz 1.1/BazConfig.cmake1
-rw-r--r--Tests/FindPackageTest/Baz 1.1/BazConfigVersion.cmake8
-rw-r--r--Tests/FindPackageTest/Baz 1.2/CMake/BazConfig.cmake1
-rw-r--r--Tests/FindPackageTest/Baz 1.2/CMake/BazConfigVersion.cmake8
-rw-r--r--Tests/FindPackageTest/CMakeLists.txt533
-rw-r--r--Tests/FindPackageTest/Exporter/CMakeLists.txt12
-rw-r--r--Tests/FindPackageTest/Exporter/CMakeTestExportPackageConfig.cmake.in1
-rw-r--r--Tests/FindPackageTest/Exporter/CMakeTestExportPackageConfigVersion.cmake.in6
-rw-r--r--Tests/FindPackageTest/Exporter/dummy.c1
-rw-r--r--Tests/FindPackageTest/FindLotsOfComponents.cmake10
-rw-r--r--Tests/FindPackageTest/FindPackageHandleStandardArgs.cmake1
-rw-r--r--Tests/FindPackageTest/FindPackageTest.cxx4
-rw-r--r--Tests/FindPackageTest/FindRecursiveA.cmake1
-rw-r--r--Tests/FindPackageTest/FindRecursiveB.cmake1
-rw-r--r--Tests/FindPackageTest/FindRecursiveC.cmake1
-rw-r--r--Tests/FindPackageTest/FindVersionTestA.cmake18
-rw-r--r--Tests/FindPackageTest/FindVersionTestB.cmake18
-rw-r--r--Tests/FindPackageTest/FindVersionTestC.cmake18
-rw-r--r--Tests/FindPackageTest/FindVersionTestD.cmake18
-rw-r--r--Tests/FindPackageTest/RelocatableConfig.cmake.in11
-rw-r--r--Tests/FindPackageTest/SystemPackage/CMakeTestSystemPackageConfig.cmake1
-rw-r--r--Tests/FindPackageTest/TApp.app/Contents/Resources/TAppConfig.cmake1
-rw-r--r--Tests/FindPackageTest/TApp.app/Contents/Resources/cmake/tapp-config.cmake1
-rw-r--r--Tests/FindPackageTest/TFramework.framework/Versions/A/Resources/CMake/TFrameworkConfig.cmake1
-rw-r--r--Tests/FindPackageTest/TFramework.framework/Versions/A/Resources/tframework-config.cmake1
-rw-r--r--Tests/FindPackageTest/cmake/SetFoundFALSEConfig.cmake1
-rw-r--r--Tests/FindPackageTest/cmake/SetFoundTRUEConfig.cmake1
-rw-r--r--Tests/FindPackageTest/include/foo.h1
-rw-r--r--Tests/FindPackageTest/lib/Bar/BarConfig.cmake1
-rw-r--r--Tests/FindPackageTest/lib/Bar/cmake/bar-config.cmake1
-rw-r--r--Tests/FindPackageTest/lib/Blub/BlubConfig.cmake1
-rw-r--r--Tests/FindPackageTest/lib/RecursiveA/recursivea-config.cmake4
-rw-r--r--Tests/FindPackageTest/lib/TApp/TAppConfig.cmake2
-rw-r--r--Tests/FindPackageTest/lib/arch/Bar/BarConfig.cmake1
-rw-r--r--Tests/FindPackageTest/lib/arch/cmake/zot-4.0/zot-config-version.cmake7
-rw-r--r--Tests/FindPackageTest/lib/arch/cmake/zot-4.0/zot-config.cmake1
-rw-r--r--Tests/FindPackageTest/lib/arch/foo-1.2/CMake/FooConfig.cmake1
-rw-r--r--Tests/FindPackageTest/lib/arch/zot-3.1/zot-config-version.cmake7
-rw-r--r--Tests/FindPackageTest/lib/arch/zot-3.1/zot-config.cmake1
-rw-r--r--Tests/FindPackageTest/lib/cmake/zot-3.1/zot-config-version.cmake4
-rw-r--r--Tests/FindPackageTest/lib/cmake/zot-3.1/zot-config.cmake2
-rw-r--r--Tests/FindPackageTest/lib/cmake/zot-4.0/zot-config-version.cmake8
-rw-r--r--Tests/FindPackageTest/lib/cmake/zot-4.0/zot-config.cmake1
-rw-r--r--Tests/FindPackageTest/lib/foo-1.2/CMake/FooConfig.cmake1
-rw-r--r--Tests/FindPackageTest/lib/foo-1.2/foo-config.cmake1
-rw-r--r--Tests/FindPackageTest/lib/suffix/test/SuffixTestConfig.cmake1
-rw-r--r--Tests/FindPackageTest/lib/suffix/test/SuffixTestConfigVersion.cmake7
-rw-r--r--Tests/FindPackageTest/lib/zot-1.0/zot-config.cmake1
-rw-r--r--Tests/FindPackageTest/lib/zot-2.0/zot-config-version.cmake5
-rw-r--r--Tests/FindPackageTest/lib/zot-2.0/zot-config.cmake1
-rw-r--r--Tests/FindPackageTest/lib/zot-3.0/zot-config-version.cmake5
-rw-r--r--Tests/FindPackageTest/lib/zot-3.0/zot-config.cmake1
-rw-r--r--Tests/FindPackageTest/lib/zot-3.1/zot-config-version.cmake8
-rw-r--r--Tests/FindPackageTest/lib/zot-3.1/zot-config.cmake1
-rw-r--r--Tests/FindPackageTest/lib/zot/zot-config-version.cmake10
-rw-r--r--Tests/FindPackageTest/lib/zot/zot-config.cmake2
-rw-r--r--Tests/ForceInclude/CMakeLists.txt10
-rw-r--r--Tests/ForceInclude/foo.c7
-rw-r--r--Tests/ForceInclude/foo1.h1
-rw-r--r--Tests/ForceInclude/foo2.h1
-rw-r--r--Tests/Fortran/CMakeLists.txt220
-rw-r--r--Tests/Fortran/Executable/CMakeLists.txt8
-rw-r--r--Tests/Fortran/Executable/main.f906
-rw-r--r--Tests/Fortran/External/CMakeLists.txt4
-rw-r--r--Tests/Fortran/External/a.f907
-rw-r--r--Tests/Fortran/Library/CMakeLists.txt11
-rw-r--r--Tests/Fortran/Library/a.f903
-rw-r--r--Tests/Fortran/Library/b.f902
-rw-r--r--Tests/Fortran/Library/main.f903
-rw-r--r--Tests/Fortran/foo.f9
-rw-r--r--Tests/Fortran/hello.f6
-rw-r--r--Tests/Fortran/in_interface/main.f903
-rw-r--r--Tests/Fortran/in_interface/module.f9012
-rw-r--r--Tests/Fortran/include/test_preprocess.h5
-rw-r--r--Tests/Fortran/mainc.c5
-rw-r--r--Tests/Fortran/maincxx.c6
-rw-r--r--Tests/Fortran/myc.c12
-rw-r--r--Tests/Fortran/mycxx.cxx6
-rw-r--r--Tests/Fortran/mysub.f5
-rw-r--r--Tests/Fortran/test_module_implementation.f906
-rw-r--r--Tests/Fortran/test_module_interface.f909
-rw-r--r--Tests/Fortran/test_module_main.f904
-rw-r--r--Tests/Fortran/test_preprocess.F9051
-rw-r--r--Tests/Fortran/test_use_in_comment_fixedform.f7
-rw-r--r--Tests/Fortran/test_use_in_comment_freeform.f907
-rw-r--r--Tests/Fortran/testf.f7
-rw-r--r--Tests/Fortran/world.f6
-rw-r--r--Tests/Fortran/world_gnu.def2
-rw-r--r--Tests/Fortran/world_icl.def2
-rw-r--r--Tests/FortranC/CMakeLists.txt25
-rw-r--r--Tests/FortranC/Flags.cmake.in28
-rwxr-xr-xTests/FortranC/test_opt.sh.in18
-rw-r--r--Tests/FortranOnly/CMakeLists.txt45
-rw-r--r--Tests/FortranOnly/checksayhello.cmake7
-rw-r--r--Tests/FortranOnly/checktestf2.cmake8
-rw-r--r--Tests/FortranOnly/hello.f5
-rw-r--r--Tests/FortranOnly/testf.f6
-rw-r--r--Tests/FortranOnly/world.f4
-rw-r--r--Tests/Framework/CMakeLists.txt80
-rw-r--r--Tests/Framework/bar.cxx6
-rw-r--r--Tests/Framework/foo.cxx10
-rw-r--r--Tests/Framework/foo.h1
-rw-r--r--Tests/Framework/foo2.h1
-rw-r--r--Tests/Framework/fooBoth.h1
-rw-r--r--Tests/Framework/fooDeepPublic.h1
-rw-r--r--Tests/Framework/fooExtensionlessResource1
-rw-r--r--Tests/Framework/fooNeither.h1
-rw-r--r--Tests/Framework/fooPrivate.h1
-rw-r--r--Tests/Framework/fooPrivateExtensionlessHeader1
-rw-r--r--Tests/Framework/fooPublic.h1
-rw-r--r--Tests/Framework/fooPublicExtensionlessHeader1
-rw-r--r--Tests/Framework/test.lua1
-rw-r--r--Tests/FunctionTest/CMakeLists.txt176
-rw-r--r--Tests/FunctionTest/SubDirScope/CMakeLists.txt14
-rw-r--r--Tests/FunctionTest/Util.cmake3
-rw-r--r--Tests/FunctionTest/functionTest.c7
-rw-r--r--Tests/IPO/CMakeLists.txt7
-rw-r--r--Tests/IncludeDirectories/CMakeLists.txt49
-rw-r--r--Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt24
-rw-r--r--Tests/IncludeDirectories/TargetIncludeDirectories/main.cpp10
-rw-r--r--Tests/IncludeDirectories/main.cpp9
-rw-r--r--Tests/JCTest/CMakeLists.txt9
-rw-r--r--Tests/JCTest/TestTime.cxx12
-rw-r--r--Tests/Java/A.java11
-rw-r--r--Tests/Java/CMakeLists.txt9
-rw-r--r--Tests/Java/HelloWorld.java11
-rw-r--r--Tests/Jump/CMakeLists.txt6
-rw-r--r--Tests/Jump/Executable/CMakeLists.txt6
-rw-r--r--Tests/Jump/Executable/jumpExecutable.cxx12
-rw-r--r--Tests/Jump/Library/CMakeLists.txt2
-rw-r--r--Tests/Jump/Library/Shared/CMakeLists.txt26
-rw-r--r--Tests/Jump/Library/Shared/jumpShared.cxx7
-rw-r--r--Tests/Jump/Library/Static/CMakeLists.txt1
-rw-r--r--Tests/Jump/Library/Static/jumpStatic.cxx1
-rwxr-xr-xTests/KDE4StableBranchTest/test_kde4.sh.in62
-rw-r--r--Tests/LibName/CMakeLists.txt26
-rw-r--r--Tests/LibName/bar.c7
-rw-r--r--Tests/LibName/foo.c11
-rw-r--r--Tests/LibName/foobar.c10
-rw-r--r--Tests/LinkDirectory/CMakeLists.txt47
-rw-r--r--Tests/LinkDirectory/External/CMakeLists.txt14
-rw-r--r--Tests/LinkDirectory/External/myexe.c3
-rw-r--r--Tests/LinkDirectory/mylibA.c1
-rw-r--r--Tests/LinkDirectory/mylibB.c1
-rw-r--r--Tests/LinkFlags/CMakeLists.txt28
-rw-r--r--Tests/LinkFlags/LinkFlags.c1
-rw-r--r--Tests/LinkFlags/LinkFlagsExe.c6
-rw-r--r--Tests/LinkFlags/LinkFlagsLib.c6
-rw-r--r--Tests/LinkLanguage/CMakeLists.txt15
-rw-r--r--Tests/LinkLanguage/LinkLanguage.c6
-rw-r--r--Tests/LinkLanguage/foo.cxx6
-rw-r--r--Tests/LinkLine/CMakeLists.txt12
-rw-r--r--Tests/LinkLine/Exec.c9
-rw-r--r--Tests/LinkLine/One.c10
-rw-r--r--Tests/LinkLine/Two.c10
-rw-r--r--Tests/LinkLineOrder/CMakeLists.txt36
-rw-r--r--Tests/LinkLineOrder/Exec1.c8
-rw-r--r--Tests/LinkLineOrder/Exec2.c8
-rw-r--r--Tests/LinkLineOrder/NoDepA.c7
-rw-r--r--Tests/LinkLineOrder/NoDepB.c4
-rw-r--r--Tests/LinkLineOrder/NoDepC.c7
-rw-r--r--Tests/LinkLineOrder/NoDepE.c11
-rw-r--r--Tests/LinkLineOrder/NoDepF.c11
-rw-r--r--Tests/LinkLineOrder/NoDepX.c7
-rw-r--r--Tests/LinkLineOrder/NoDepY.c4
-rw-r--r--Tests/LinkLineOrder/NoDepZ.c7
-rw-r--r--Tests/LinkLineOrder/One.c10
-rw-r--r--Tests/LinkLineOrder/Two.c8
-rw-r--r--Tests/LinkStatic/CMakeLists.txt27
-rw-r--r--Tests/LinkStatic/LinkStatic.c5
-rw-r--r--Tests/LoadCommand/CMakeCommands/CMakeLists.txt14
-rw-r--r--Tests/LoadCommand/CMakeCommands/cmTestCommand.c219
-rw-r--r--Tests/LoadCommand/CMakeLists.txt63
-rw-r--r--Tests/LoadCommand/LoadedCommand.cxx.in41
-rw-r--r--Tests/LoadCommand/LoadedCommand.h.in7
-rw-r--r--Tests/LoadCommandOneConfig/CMakeCommands/CMakeLists.txt17
-rw-r--r--Tests/LoadCommandOneConfig/CMakeCommands/cmTestCommand.c219
-rw-r--r--Tests/LoadCommandOneConfig/CMakeLists.txt69
-rw-r--r--Tests/LoadCommandOneConfig/LoadedCommand.cxx.in41
-rw-r--r--Tests/LoadCommandOneConfig/LoadedCommand.h.in13
-rw-r--r--Tests/MFC/CMakeLists.txt61
-rw-r--r--Tests/MFC/CMakeLists.txt.in62
-rw-r--r--Tests/MFC/ValidateBuild.cmake.in68
-rw-r--r--Tests/MFC/mfc1/.gitattributes6
-rw-r--r--Tests/MFC/mfc1/ChildFrm.cpp59
-rw-r--r--Tests/MFC/mfc1/ChildFrm.h34
-rw-r--r--Tests/MFC/mfc1/MainFrm.cpp98
-rw-r--r--Tests/MFC/mfc1/MainFrm.h38
-rw-r--r--Tests/MFC/mfc1/ReadMe.txt135
-rw-r--r--Tests/MFC/mfc1/Resource.h20
-rw-r--r--Tests/MFC/mfc1/mfc1.cpp144
-rw-r--r--Tests/MFC/mfc1/mfc1.h31
-rw-r--r--Tests/MFC/mfc1/mfc1.rc393
-rw-r--r--Tests/MFC/mfc1/mfc1.reg13
-rw-r--r--Tests/MFC/mfc1/mfc1.sln21
-rw-r--r--Tests/MFC/mfc1/mfc1.vcproj216
-rw-r--r--Tests/MFC/mfc1/mfc1Doc.cpp78
-rw-r--r--Tests/MFC/mfc1/mfc1Doc.h37
-rw-r--r--Tests/MFC/mfc1/mfc1View.cpp99
-rw-r--r--Tests/MFC/mfc1/mfc1View.h48
-rw-r--r--Tests/MFC/mfc1/res/Toolbar.bmpbin0 -> 1078 bytes
-rw-r--r--Tests/MFC/mfc1/res/mfc1.icobin0 -> 21630 bytes
-rw-r--r--Tests/MFC/mfc1/res/mfc1.manifest22
-rw-r--r--Tests/MFC/mfc1/res/mfc1.rc213
-rw-r--r--Tests/MFC/mfc1/res/mfc1Doc.icobin0 -> 1078 bytes
-rw-r--r--Tests/MFC/mfc1/stdafx.cpp5
-rw-r--r--Tests/MFC/mfc1/stdafx.h56
-rw-r--r--Tests/MFC/try_compile/CMakeLists.txt15
-rw-r--r--Tests/MacroTest/CMakeLists.txt91
-rw-r--r--Tests/MacroTest/context.cmake10
-rw-r--r--Tests/MacroTest/macroTest.c7
-rw-r--r--Tests/MakeClean/CMakeLists.txt57
-rw-r--r--Tests/MakeClean/ToClean/CMakeLists.txt31
-rw-r--r--Tests/MakeClean/ToClean/ToCleanFiles.cmake.in1
-rw-r--r--Tests/MakeClean/ToClean/toclean.cxx4
-rw-r--r--Tests/MakeClean/check_clean.c.in26
-rw-r--r--Tests/MathTest/CMakeLists.txt29
-rw-r--r--Tests/MathTest/MathTestExec.cxx26
-rw-r--r--Tests/MathTest/MathTestTests.h.in1
-rw-r--r--Tests/MissingSourceFile/CMakeLists.txt3
-rw-r--r--Tests/Module/CheckTypeSize/CMakeLists.txt18
-rw-r--r--Tests/Module/CheckTypeSize/CheckTypeSize.c122
-rw-r--r--Tests/Module/CheckTypeSize/config.h.in39
-rw-r--r--Tests/Module/GenerateExportHeader/CMakeLists.txt184
-rw-r--r--Tests/Module/GenerateExportHeader/exportheader_test.cpp82
-rw-r--r--Tests/Module/GenerateExportHeader/lib_shared_and_static/CMakeLists.txt23
-rw-r--r--Tests/Module/GenerateExportHeader/lib_shared_and_static/libshared_and_static.cpp91
-rw-r--r--Tests/Module/GenerateExportHeader/lib_shared_and_static/libshared_and_static.h54
-rw-r--r--Tests/Module/GenerateExportHeader/lib_shared_and_statictest/CMakeLists.txt33
-rw-r--r--Tests/Module/GenerateExportHeader/libshared/CMakeLists.txt16
-rw-r--r--Tests/Module/GenerateExportHeader/libshared/libshared.cpp91
-rw-r--r--Tests/Module/GenerateExportHeader/libshared/libshared.h54
-rw-r--r--Tests/Module/GenerateExportHeader/libsharedtest/CMakeLists.txt44
-rw-r--r--Tests/Module/GenerateExportHeader/libstatic/CMakeLists.txt18
-rw-r--r--Tests/Module/GenerateExportHeader/libstatic/libstatic.cpp87
-rw-r--r--Tests/Module/GenerateExportHeader/libstatic/libstatic.h54
-rw-r--r--Tests/Module/GenerateExportHeader/libstatictest/CMakeLists.txt18
-rw-r--r--Tests/Module/GenerateExportHeader/nodeprecated/CMakeLists.txt26
-rw-r--r--Tests/Module/GenerateExportHeader/nodeprecated/CMakeLists.txt.in15
-rw-r--r--Tests/Module/GenerateExportHeader/nodeprecated/src/main.cpp9
-rw-r--r--Tests/Module/GenerateExportHeader/nodeprecated/src/someclass.cpp9
-rw-r--r--Tests/Module/GenerateExportHeader/nodeprecated/src/someclass.h10
-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/ModuleDefinition/CMakeLists.txt31
-rw-r--r--Tests/ModuleDefinition/example_dll.c1
-rw-r--r--Tests/ModuleDefinition/example_dll.def2
-rw-r--r--Tests/ModuleDefinition/example_dll_2.c1
-rw-r--r--Tests/ModuleDefinition/example_dll_2.def2
-rw-r--r--Tests/ModuleDefinition/example_dll_gen.c1
-rw-r--r--Tests/ModuleDefinition/example_dll_gen.def.in2
-rw-r--r--Tests/ModuleDefinition/example_exe.c16
-rw-r--r--Tests/ModuleDefinition/example_exe.def2
-rw-r--r--Tests/ModuleDefinition/example_mod_1.c21
-rw-r--r--Tests/MumpsCoverage/.gitattributes2
-rw-r--r--Tests/MumpsCoverage/Accounts_ReceivableTest.cmcov304
-rw-r--r--Tests/MumpsCoverage/Accounts_ReceivableTest.mcov1445
-rw-r--r--Tests/MumpsCoverage/DartConfiguration.cache.tcl.in8
-rw-r--r--Tests/MumpsCoverage/DartConfiguration.tcl.in8
-rw-r--r--Tests/MumpsCoverage/VistA-FOIA/Packages/Toolkit/Routines/XINDEX.m144
-rw-r--r--Tests/MumpsCoverage/cache_coverage.cmcov.in2
-rw-r--r--Tests/MumpsCoverage/gtm_coverage.mcov.in2
-rw-r--r--Tests/NewlineArgs/CMakeLists.txt16
-rw-r--r--Tests/NewlineArgs/cxxonly.cxx19
-rw-r--r--Tests/NewlineArgs/libcxx1.cxx10
-rw-r--r--Tests/NewlineArgs/libcxx1.h9
-rw-r--r--Tests/NewlineArgs/libcxx2.h.in6
-rw-r--r--Tests/ObjC++/CMakeLists.txt6
-rw-r--r--Tests/ObjC++/objc++.mm23
-rw-r--r--Tests/ObjectLibrary/A/CMakeLists.txt17
-rw-r--r--Tests/ObjectLibrary/A/a.h6
-rw-r--r--Tests/ObjectLibrary/A/a1.c.in2
-rw-r--r--Tests/ObjectLibrary/A/a2.c2
-rw-r--r--Tests/ObjectLibrary/AB.def5
-rw-r--r--Tests/ObjectLibrary/B/CMakeLists.txt15
-rw-r--r--Tests/ObjectLibrary/B/b.h11
-rw-r--r--Tests/ObjectLibrary/B/b1.c2
-rw-r--r--Tests/ObjectLibrary/B/b1_vs6.c1
-rw-r--r--Tests/ObjectLibrary/B/b2.c2
-rw-r--r--Tests/ObjectLibrary/B/b2_vs6.c1
-rw-r--r--Tests/ObjectLibrary/CMakeLists.txt52
-rw-r--r--Tests/ObjectLibrary/c.c19
-rw-r--r--Tests/ObjectLibrary/dummy.c1
-rw-r--r--Tests/ObjectLibrary/dummy.objbin0 -> 498 bytes
-rw-r--r--Tests/ObjectLibrary/main.c16
-rw-r--r--Tests/ObjectLibrary/mainAB.c22
-rw-r--r--Tests/OutDir/CMakeLists.txt35
-rw-r--r--Tests/OutDir/OutDir.c24
-rw-r--r--Tests/OutDir/OutDir.cmake28
-rw-r--r--Tests/OutOfBinary/CMakeLists.txt2
-rw-r--r--Tests/OutOfBinary/outlib.c2
-rw-r--r--Tests/OutOfSource/CMakeLists.txt18
-rw-r--r--Tests/OutOfSource/OutOfSourceSubdir/CMakeLists.txt62
-rw-r--r--Tests/OutOfSource/OutOfSourceSubdir/simple.cxx39
-rw-r--r--Tests/OutOfSource/OutOfSourceSubdir/simple.cxx.in1
-rw-r--r--Tests/OutOfSource/OutOfSourceSubdir/testlib.cxx6
-rw-r--r--Tests/OutOfSource/OutOfSourceSubdir/testlib.h11
-rw-r--r--Tests/OutOfSource/SubDir/CMakeLists.txt8
-rw-r--r--Tests/OutOfSource/simple.cxx1
-rw-r--r--Tests/OutOfSource/testdp.h.in1
-rw-r--r--Tests/PerConfig/CMakeLists.txt34
-rw-r--r--Tests/PerConfig/pcShared.c5
-rw-r--r--Tests/PerConfig/pcShared.h16
-rw-r--r--Tests/PerConfig/pcStatic.c4
-rw-r--r--Tests/PerConfig/perconfig.c8
-rw-r--r--Tests/PerConfig/perconfig.cmake40
-rw-r--r--Tests/Plugin/CMakeLists.txt88
-rw-r--r--Tests/Plugin/check_mod_soname.cmake14
-rw-r--r--Tests/Plugin/include/example.h25
-rw-r--r--Tests/Plugin/src/example_exe.cxx60
-rw-r--r--Tests/Plugin/src/example_exe.h.in6
-rw-r--r--Tests/Plugin/src/example_mod_1.c22
-rw-r--r--Tests/Policy0002/A/CMakeLists.txt1
-rw-r--r--Tests/Policy0002/CMakeLists.txt5
-rw-r--r--Tests/Policy0002/policy0002.c4
-rw-r--r--Tests/PolicyScope/Bar.cmake8
-rw-r--r--Tests/PolicyScope/CMakeLists.txt104
-rw-r--r--Tests/PolicyScope/FindFoo.cmake2
-rw-r--r--Tests/PolicyScope/main.c4
-rw-r--r--Tests/PositionIndependentTargets/CMakeLists.txt13
-rw-r--r--Tests/PositionIndependentTargets/global/CMakeLists.txt37
-rw-r--r--Tests/PositionIndependentTargets/main.cpp2
-rw-r--r--Tests/PositionIndependentTargets/pic_lib.cpp12
-rw-r--r--Tests/PositionIndependentTargets/pic_main.cpp4
-rw-r--r--Tests/PositionIndependentTargets/pic_test.h20
-rw-r--r--Tests/PositionIndependentTargets/targets/CMakeLists.txt20
-rw-r--r--Tests/PreOrder/CMakeLists.txt6
-rw-r--r--Tests/PreOrder/Library/CMakeLists.txt2
-rw-r--r--Tests/PreOrder/Library/simpleLib.cxx3
-rw-r--r--Tests/PreOrder/simple.cxx6
-rw-r--r--Tests/PrecompiledHeader/CMakeLists.txt59
-rw-r--r--Tests/PrecompiledHeader/foo1.c8
-rw-r--r--Tests/PrecompiledHeader/foo2.c9
-rw-r--r--Tests/PrecompiledHeader/foo_precompile.c5
-rw-r--r--Tests/PrecompiledHeader/include/foo.h4
-rw-r--r--Tests/PrecompiledHeader/include/foo_precompiled.h1
-rw-r--r--Tests/Preprocess/CMakeLists.txt269
-rw-r--r--Tests/Preprocess/file_def.h1
-rw-r--r--Tests/Preprocess/preprocess.c198
-rw-r--r--Tests/Preprocess/preprocess.cxx225
-rw-r--r--Tests/Preprocess/preprocess.h.in16
-rw-r--r--Tests/Preprocess/preprocess_vs6.cxx3
-rw-r--r--Tests/Preprocess/target_def.h1
-rw-r--r--Tests/Properties/CMakeLists.txt147
-rw-r--r--Tests/Properties/SubDir/properties3.cxx9
-rw-r--r--Tests/Properties/properties.h.in1
-rw-r--r--Tests/Properties/properties2.h1
-rw-r--r--Tests/Qt4Deploy/CMakeLists.txt70
-rw-r--r--Tests/Qt4Deploy/testdeploy.cpp29
-rw-r--r--Tests/QtAutomoc/CMakeLists.txt23
-rw-r--r--Tests/QtAutomoc/abc.cpp49
-rw-r--r--Tests/QtAutomoc/abc.h28
-rw-r--r--Tests/QtAutomoc/abc_p.h30
-rw-r--r--Tests/QtAutomoc/bar.cpp28
-rw-r--r--Tests/QtAutomoc/blub.cpp40
-rw-r--r--Tests/QtAutomoc/blub.h26
-rw-r--r--Tests/QtAutomoc/calwidget.cpp424
-rw-r--r--Tests/QtAutomoc/calwidget.h121
-rw-r--r--Tests/QtAutomoc/codeeditor.cpp153
-rw-r--r--Tests/QtAutomoc/codeeditor.h99
-rw-r--r--Tests/QtAutomoc/foo.cpp39
-rw-r--r--Tests/QtAutomoc/foo.h28
-rw-r--r--Tests/QtAutomoc/main.cpp82
-rw-r--r--Tests/QtAutomoc/private_slot.cpp21
-rw-r--r--Tests/QtAutomoc/private_slot.h20
-rw-r--r--Tests/QtAutomoc/sub/bar.h28
-rw-r--r--Tests/QtAutomoc/xyz.cpp28
-rw-r--r--Tests/QtAutomoc/xyz.h28
-rw-r--r--Tests/QtAutomoc/yaf.cpp32
-rw-r--r--Tests/QtAutomoc/yaf.h25
-rw-r--r--Tests/QtAutomoc/yaf_p.h30
-rw-r--r--Tests/README39
-rw-r--r--Tests/ReturnTest/CMakeLists.txt147
-rw-r--r--Tests/ReturnTest/include_return.cmake3
-rw-r--r--Tests/ReturnTest/returnTest.c7
-rw-r--r--Tests/ReturnTest/subdir/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CMakeLists.txt58
-rw-r--r--Tests/RunCMake/Languages/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/Languages/NoLangSHARED-result.txt1
-rw-r--r--Tests/RunCMake/Languages/NoLangSHARED-stderr.txt1
-rw-r--r--Tests/RunCMake/Languages/NoLangSHARED.cmake1
-rw-r--r--Tests/RunCMake/Languages/RunCMakeTest.cmake3
-rw-r--r--Tests/RunCMake/Languages/foo.nolang0
-rw-r--r--Tests/RunCMake/ObjectLibrary/BadObjSource1-result.txt1
-rw-r--r--Tests/RunCMake/ObjectLibrary/BadObjSource1-stderr.txt8
-rw-r--r--Tests/RunCMake/ObjectLibrary/BadObjSource1.cmake1
-rw-r--r--Tests/RunCMake/ObjectLibrary/BadObjSource2-result.txt1
-rw-r--r--Tests/RunCMake/ObjectLibrary/BadObjSource2-stderr.txt8
-rw-r--r--Tests/RunCMake/ObjectLibrary/BadObjSource2.cmake1
-rw-r--r--Tests/RunCMake/ObjectLibrary/BadSourceExpression1-result.txt1
-rw-r--r--Tests/RunCMake/ObjectLibrary/BadSourceExpression1-stderr.txt6
-rw-r--r--Tests/RunCMake/ObjectLibrary/BadSourceExpression1.cmake1
-rw-r--r--Tests/RunCMake/ObjectLibrary/BadSourceExpression2-result.txt1
-rw-r--r--Tests/RunCMake/ObjectLibrary/BadSourceExpression2-stderr.txt4
-rw-r--r--Tests/RunCMake/ObjectLibrary/BadSourceExpression2.cmake1
-rw-r--r--Tests/RunCMake/ObjectLibrary/BadSourceExpression3-result.txt1
-rw-r--r--Tests/RunCMake/ObjectLibrary/BadSourceExpression3-stderr.txt4
-rw-r--r--Tests/RunCMake/ObjectLibrary/BadSourceExpression3.cmake2
-rw-r--r--Tests/RunCMake/ObjectLibrary/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/ObjectLibrary/Export-result.txt1
-rw-r--r--Tests/RunCMake/ObjectLibrary/Export-stderr.txt4
-rw-r--r--Tests/RunCMake/ObjectLibrary/Export.cmake2
-rw-r--r--Tests/RunCMake/ObjectLibrary/ExportLanguages.cmake15
-rw-r--r--Tests/RunCMake/ObjectLibrary/Import-result.txt1
-rw-r--r--Tests/RunCMake/ObjectLibrary/Import-stderr.txt4
-rw-r--r--Tests/RunCMake/ObjectLibrary/Import.cmake1
-rw-r--r--Tests/RunCMake/ObjectLibrary/Install-result.txt1
-rw-r--r--Tests/RunCMake/ObjectLibrary/Install-stderr.txt4
-rw-r--r--Tests/RunCMake/ObjectLibrary/Install.cmake2
-rw-r--r--Tests/RunCMake/ObjectLibrary/LinkObjLHS-result.txt1
-rw-r--r--Tests/RunCMake/ObjectLibrary/LinkObjLHS-stderr.txt4
-rw-r--r--Tests/RunCMake/ObjectLibrary/LinkObjLHS.cmake2
-rw-r--r--Tests/RunCMake/ObjectLibrary/LinkObjRHS1-result.txt1
-rw-r--r--Tests/RunCMake/ObjectLibrary/LinkObjRHS1-stderr.txt6
-rw-r--r--Tests/RunCMake/ObjectLibrary/LinkObjRHS1.cmake3
-rw-r--r--Tests/RunCMake/ObjectLibrary/LinkObjRHS2-result.txt1
-rw-r--r--Tests/RunCMake/ObjectLibrary/LinkObjRHS2-stderr.txt6
-rw-r--r--Tests/RunCMake/ObjectLibrary/LinkObjRHS2.cmake3
-rw-r--r--Tests/RunCMake/ObjectLibrary/ObjWithObj-result.txt1
-rw-r--r--Tests/RunCMake/ObjectLibrary/ObjWithObj-stderr.txt4
-rw-r--r--Tests/RunCMake/ObjectLibrary/ObjWithObj.cmake2
-rw-r--r--Tests/RunCMake/ObjectLibrary/PostBuild-result.txt1
-rw-r--r--Tests/RunCMake/ObjectLibrary/PostBuild-stderr.txt5
-rw-r--r--Tests/RunCMake/ObjectLibrary/PostBuild.cmake4
-rw-r--r--Tests/RunCMake/ObjectLibrary/PreBuild-result.txt1
-rw-r--r--Tests/RunCMake/ObjectLibrary/PreBuild-stderr.txt5
-rw-r--r--Tests/RunCMake/ObjectLibrary/PreBuild.cmake4
-rw-r--r--Tests/RunCMake/ObjectLibrary/PreLink-result.txt1
-rw-r--r--Tests/RunCMake/ObjectLibrary/PreLink-stderr.txt5
-rw-r--r--Tests/RunCMake/ObjectLibrary/PreLink.cmake4
-rw-r--r--Tests/RunCMake/ObjectLibrary/RunCMakeTest.cmake18
-rw-r--r--Tests/RunCMake/ObjectLibrary/a.c1
-rw-r--r--Tests/RunCMake/ObjectLibrary/a.cxx1
-rw-r--r--Tests/RunCMake/ObjectLibrary/bad.def0
-rw-r--r--Tests/RunCMake/ObjectLibrary/bad.obj0
-rw-r--r--Tests/RunCMake/RunCMake.cmake74
-rw-r--r--Tests/RunCMake/build_command/CMakeLists.txt59
-rw-r--r--Tests/RunCMake/build_command/ErrorsOFF-stderr.txt1
-rw-r--r--Tests/RunCMake/build_command/ErrorsOFF-stdout.txt1
-rw-r--r--Tests/RunCMake/build_command/ErrorsOFF.cmake1
-rw-r--r--Tests/RunCMake/build_command/ErrorsON-result.txt1
-rw-r--r--Tests/RunCMake/build_command/ErrorsON-stderr.txt12
-rw-r--r--Tests/RunCMake/build_command/ErrorsON-stdout.txt1
-rw-r--r--Tests/RunCMake/build_command/ErrorsON.cmake1
-rw-r--r--Tests/RunCMake/build_command/RunCMakeTest.cmake4
-rw-r--r--Tests/RunCMake/find_package/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/find_package/ComponentRequiredAndOptional-result.txt1
-rw-r--r--Tests/RunCMake/find_package/ComponentRequiredAndOptional-stderr.txt8
-rw-r--r--Tests/RunCMake/find_package/ComponentRequiredAndOptional.cmake1
-rw-r--r--Tests/RunCMake/find_package/MissingConfig-stderr.txt19
-rw-r--r--Tests/RunCMake/find_package/MissingConfig.cmake2
-rw-r--r--Tests/RunCMake/find_package/MissingConfigOneName-stderr.txt10
-rw-r--r--Tests/RunCMake/find_package/MissingConfigOneName.cmake1
-rw-r--r--Tests/RunCMake/find_package/MissingConfigRequired-result.txt1
-rw-r--r--Tests/RunCMake/find_package/MissingConfigRequired-stderr.txt13
-rw-r--r--Tests/RunCMake/find_package/MissingConfigRequired.cmake2
-rw-r--r--Tests/RunCMake/find_package/MissingConfigVersion-stderr.txt13
-rw-r--r--Tests/RunCMake/find_package/MissingConfigVersion.cmake1
-rw-r--r--Tests/RunCMake/find_package/MissingModule-stderr.txt26
-rw-r--r--Tests/RunCMake/find_package/MissingModule.cmake2
-rw-r--r--Tests/RunCMake/find_package/MissingModuleRequired-result.txt1
-rw-r--r--Tests/RunCMake/find_package/MissingModuleRequired-stderr.txt21
-rw-r--r--Tests/RunCMake/find_package/MissingModuleRequired.cmake2
-rw-r--r--Tests/RunCMake/find_package/MissingNormal-stderr.txt23
-rw-r--r--Tests/RunCMake/find_package/MissingNormal.cmake2
-rw-r--r--Tests/RunCMake/find_package/MissingNormalRequired-result.txt1
-rw-r--r--Tests/RunCMake/find_package/MissingNormalRequired-stderr.txt17
-rw-r--r--Tests/RunCMake/find_package/MissingNormalRequired.cmake2
-rw-r--r--Tests/RunCMake/find_package/MissingNormalVersion-stderr.txt17
-rw-r--r--Tests/RunCMake/find_package/MissingNormalVersion.cmake1
-rw-r--r--Tests/RunCMake/find_package/MissingNormalWarnNoModuleNew-stderr.txt30
-rw-r--r--Tests/RunCMake/find_package/MissingNormalWarnNoModuleNew.cmake3
-rw-r--r--Tests/RunCMake/find_package/MissingNormalWarnNoModuleOld-stderr.txt29
-rw-r--r--Tests/RunCMake/find_package/MissingNormalWarnNoModuleOld.cmake2
-rw-r--r--Tests/RunCMake/find_package/MixedModeOptions-result.txt1
-rw-r--r--Tests/RunCMake/find_package/MixedModeOptions-stderr.txt14
-rw-r--r--Tests/RunCMake/find_package/MixedModeOptions.cmake1
-rw-r--r--Tests/RunCMake/find_package/RunCMakeTest.cmake16
-rw-r--r--Tests/RunCMake/find_package/SetFoundFALSE-stderr.txt9
-rw-r--r--Tests/RunCMake/find_package/SetFoundFALSE.cmake2
-rw-r--r--Tests/RunCMake/find_package/SetFoundFALSEConfig.cmake1
-rw-r--r--Tests/RunCMake/include/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/include/EmptyString-stderr.txt5
-rw-r--r--Tests/RunCMake/include/EmptyString.cmake1
-rw-r--r--Tests/RunCMake/include/EmptyStringOptional-stderr.txt5
-rw-r--r--Tests/RunCMake/include/EmptyStringOptional.cmake1
-rw-r--r--Tests/RunCMake/include/RunCMakeTest.cmake4
-rw-r--r--Tests/RunCMake/include_external_msproject/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/include_external_msproject/CustomGuid-check.cmake1
-rw-r--r--Tests/RunCMake/include_external_msproject/CustomGuid.cmake2
-rw-r--r--Tests/RunCMake/include_external_msproject/CustomGuidTypePlatform-check.cmake1
-rw-r--r--Tests/RunCMake/include_external_msproject/CustomGuidTypePlatform.cmake5
-rw-r--r--Tests/RunCMake/include_external_msproject/CustomTypePlatform-check.cmake1
-rw-r--r--Tests/RunCMake/include_external_msproject/CustomTypePlatform.cmake3
-rw-r--r--Tests/RunCMake/include_external_msproject/RunCMakeTest.cmake6
-rw-r--r--Tests/RunCMake/include_external_msproject/check_utils.cmake109
-rw-r--r--Tests/RunCMake/include_external_msproject/main.cpp3
-rw-r--r--Tests/RunCMake/list/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/list/EmptyGet0-result.txt1
-rw-r--r--Tests/RunCMake/list/EmptyGet0-stderr.txt4
-rw-r--r--Tests/RunCMake/list/EmptyGet0.cmake2
-rw-r--r--Tests/RunCMake/list/EmptyInsert-1-result.txt1
-rw-r--r--Tests/RunCMake/list/EmptyInsert-1-stderr.txt4
-rw-r--r--Tests/RunCMake/list/EmptyInsert-1.cmake2
-rw-r--r--Tests/RunCMake/list/EmptyRemoveAt0-result.txt1
-rw-r--r--Tests/RunCMake/list/EmptyRemoveAt0-stderr.txt4
-rw-r--r--Tests/RunCMake/list/EmptyRemoveAt0.cmake2
-rw-r--r--Tests/RunCMake/list/RunCMakeTest.cmake5
-rw-r--r--Tests/RuntimePath/CMakeLists.txt33
-rw-r--r--Tests/RuntimePath/bar1.c2
-rw-r--r--Tests/RuntimePath/bar2.c2
-rw-r--r--Tests/RuntimePath/foo1.c1
-rw-r--r--Tests/RuntimePath/foo2.c1
-rw-r--r--Tests/RuntimePath/main.c5
-rw-r--r--Tests/SBCS/CMakeLists.txt6
-rw-r--r--Tests/SBCS/SBCS.cxx22
-rw-r--r--Tests/SameName/CMakeLists.txt7
-rw-r--r--Tests/SameName/Exe1/CMakeLists.txt11
-rw-r--r--Tests/SameName/Exe1/conly.c12
-rw-r--r--Tests/SameName/Lib1/CMakeLists.txt1
-rw-r--r--Tests/SameName/Lib1/libc1.c4
-rw-r--r--Tests/SameName/Lib1/libc1.h1
-rw-r--r--Tests/SetLang/CMakeLists.txt10
-rw-r--r--Tests/SetLang/bar.c21
-rw-r--r--Tests/SetLang/foo.c7
-rw-r--r--Tests/Simple/CMakeLists.txt17
-rw-r--r--Tests/Simple/simple.cxx11
-rw-r--r--Tests/Simple/simpleCLib.c12
-rw-r--r--Tests/Simple/simpleLib.cxx3
-rw-r--r--Tests/Simple/simpleWe.cpp17
-rw-r--r--Tests/SimpleCOnly/CMakeLists.txt17
-rw-r--r--Tests/SimpleCOnly/bar.c1
-rw-r--r--Tests/SimpleCOnly/foo.c1
-rw-r--r--Tests/SimpleCOnly/main.c12
-rw-r--r--Tests/SimpleExclude/CMakeLists.txt11
-rw-r--r--Tests/SimpleExclude/dirC/CMakeLists.txt3
-rw-r--r--Tests/SimpleExclude/dirC/dirA/CMakeLists.txt10
-rw-r--r--Tests/SimpleExclude/dirC/dirA/t1.c8
-rw-r--r--Tests/SimpleExclude/dirC/dirA/t2.c7
-rw-r--r--Tests/SimpleExclude/dirC/dirA/t3.c7
-rw-r--r--Tests/SimpleExclude/dirC/dirA/t4.c17
-rw-r--r--Tests/SimpleExclude/dirC/dirA/t5.c7
-rw-r--r--Tests/SimpleExclude/dirC/dirB/CMakeLists.txt5
-rw-r--r--Tests/SimpleExclude/dirC/dirB/t6.c8
-rw-r--r--Tests/SimpleExclude/dirC/dirB/t7.c16
-rw-r--r--Tests/SimpleExclude/dirD/CMakeLists.txt7
-rw-r--r--Tests/SimpleExclude/dirD/t8.c7
-rw-r--r--Tests/SimpleExclude/dirD/t9.c24
-rw-r--r--Tests/SimpleExclude/run.cmake.in13
-rw-r--r--Tests/SimpleInstall/CMakeLists.txt398
-rw-r--r--Tests/SimpleInstall/InstallScript1.cmake5
-rw-r--r--Tests/SimpleInstall/InstallScript2.cmake14
-rw-r--r--Tests/SimpleInstall/InstallScript3.cmake12
-rw-r--r--Tests/SimpleInstall/InstallScript4.cmake22
-rw-r--r--Tests/SimpleInstall/PackageScript.cmake10
-rw-r--r--Tests/SimpleInstall/PostInstall.cmake6
-rw-r--r--Tests/SimpleInstall/PreInstall.cmake2
-rw-r--r--Tests/SimpleInstall/TestSubDir/CMakeLists.txt3
-rw-r--r--Tests/SimpleInstall/TestSubDir/TSD.cxx10
-rw-r--r--Tests/SimpleInstall/TestSubDir/TSD.h1
-rw-r--r--Tests/SimpleInstall/TestSubDir/TSD_utils.cxx10
-rw-r--r--Tests/SimpleInstall/foo.c6
-rw-r--r--Tests/SimpleInstall/foo.h11
-rw-r--r--Tests/SimpleInstall/inst.cxx37
-rw-r--r--Tests/SimpleInstall/inst2.cxx2
-rw-r--r--Tests/SimpleInstall/lib1.cxx6
-rw-r--r--Tests/SimpleInstall/lib1.h1
-rw-r--r--Tests/SimpleInstall/lib2.cxx6
-rw-r--r--Tests/SimpleInstall/lib2.h11
-rw-r--r--Tests/SimpleInstall/lib3.cxx6
-rw-r--r--Tests/SimpleInstall/lib3.h11
-rw-r--r--Tests/SimpleInstall/lib4.cxx7
-rw-r--r--Tests/SimpleInstall/lib4.h12
-rw-r--r--Tests/SimpleInstall/scripts/.gitattributes1
-rw-r--r--Tests/SimpleInstall/scripts/CMakeLists.txt1
-rwxr-xr-xTests/SimpleInstall/scripts/sample_script2
-rwxr-xr-xTests/SimpleInstall/scripts/sample_script.bat1
-rw-r--r--Tests/SimpleInstallS2/CMakeLists.txt398
-rw-r--r--Tests/SimpleInstallS2/InstallScript1.cmake5
-rw-r--r--Tests/SimpleInstallS2/InstallScript2.cmake14
-rw-r--r--Tests/SimpleInstallS2/InstallScript3.cmake12
-rw-r--r--Tests/SimpleInstallS2/InstallScript4.cmake22
-rw-r--r--Tests/SimpleInstallS2/PackageScript.cmake10
-rw-r--r--Tests/SimpleInstallS2/PostInstall.cmake6
-rw-r--r--Tests/SimpleInstallS2/PreInstall.cmake2
-rw-r--r--Tests/SimpleInstallS2/TestSubDir/CMakeLists.txt3
-rw-r--r--Tests/SimpleInstallS2/TestSubDir/TSD.cxx10
-rw-r--r--Tests/SimpleInstallS2/TestSubDir/TSD.h1
-rw-r--r--Tests/SimpleInstallS2/TestSubDir/TSD_utils.cxx10
-rw-r--r--Tests/SimpleInstallS2/foo.c6
-rw-r--r--Tests/SimpleInstallS2/foo.h11
-rw-r--r--Tests/SimpleInstallS2/inst.cxx37
-rw-r--r--Tests/SimpleInstallS2/inst2.cxx2
-rw-r--r--Tests/SimpleInstallS2/lib1.cxx6
-rw-r--r--Tests/SimpleInstallS2/lib1.h1
-rw-r--r--Tests/SimpleInstallS2/lib2.cxx6
-rw-r--r--Tests/SimpleInstallS2/lib2.h11
-rw-r--r--Tests/SimpleInstallS2/lib3.cxx6
-rw-r--r--Tests/SimpleInstallS2/lib3.h11
-rw-r--r--Tests/SimpleInstallS2/lib4.cxx7
-rw-r--r--Tests/SimpleInstallS2/lib4.h12
-rw-r--r--Tests/SimpleInstallS2/scripts/.gitattributes1
-rw-r--r--Tests/SimpleInstallS2/scripts/CMakeLists.txt1
-rwxr-xr-xTests/SimpleInstallS2/scripts/sample_script2
-rwxr-xr-xTests/SimpleInstallS2/scripts/sample_script.bat1
-rw-r--r--Tests/SourceGroups/CMakeLists.txt35
-rw-r--r--Tests/SourceGroups/README.txt1
-rw-r--r--Tests/SourceGroups/bar.c4
-rw-r--r--Tests/SourceGroups/baz.c4
-rw-r--r--Tests/SourceGroups/foo.c4
-rw-r--r--Tests/SourceGroups/main.c13
-rw-r--r--Tests/SourceGroups/sub1/foo.c4
-rw-r--r--Tests/SourceGroups/sub1/foobar.c4
-rw-r--r--Tests/StringFileTest/CMakeLists.txt282
-rw-r--r--Tests/StringFileTest/InputFile.h.in38
-rw-r--r--Tests/StringFileTest/StringFile.cxx31
-rw-r--r--Tests/StringFileTest/main.ihx21
-rw-r--r--Tests/StringFileTest/main.srec21
-rw-r--r--Tests/StringFileTest/test.binbin0 -> 5 bytes
-rw-r--r--Tests/SubDir/AnotherSubdir/pair+int.int.c6
-rw-r--r--Tests/SubDir/AnotherSubdir/pair_int.int.c6
-rw-r--r--Tests/SubDir/AnotherSubdir/secondone.c6
-rw-r--r--Tests/SubDir/AnotherSubdir/testfromsubdir.c14
-rw-r--r--Tests/SubDir/CMakeLists.txt46
-rw-r--r--Tests/SubDir/Examples/CMakeLists.txt3
-rw-r--r--Tests/SubDir/Examples/example1/CMakeLists.txt7
-rw-r--r--Tests/SubDir/Examples/example1/example1.cxx7
-rw-r--r--Tests/SubDir/Examples/example2/CMakeLists.txt2
-rw-r--r--Tests/SubDir/Examples/example2/example2.cxx7
-rw-r--r--Tests/SubDir/Executable/CMakeLists.txt1
-rw-r--r--Tests/SubDir/Executable/test.cxx49
-rw-r--r--Tests/SubDir/ThirdSubDir/pair+int.int1.c6
-rw-r--r--Tests/SubDir/ThirdSubDir/pair_int.int1.c6
-rw-r--r--Tests/SubDir/ThirdSubDir/pair_p_int.int1.c6
-rw-r--r--Tests/SubDir/ThirdSubDir/testfromauxsubdir.c16
-rw-r--r--Tests/SubDir/ThirdSubDir/thirdone.c6
-rw-r--r--Tests/SubDir/vcl_algorithm+vcl_pair+double.foo.c6
-rw-r--r--Tests/SubDir/vcl_algorithm_vcl_pair_double.foo.c6
-rw-r--r--Tests/SubDirSpaces/Another Subdir/pair+int.int.c6
-rw-r--r--Tests/SubDirSpaces/Another Subdir/pair_int.int.c6
-rw-r--r--Tests/SubDirSpaces/Another Subdir/secondone.c6
-rw-r--r--Tests/SubDirSpaces/Another Subdir/testfromsubdir.c14
-rw-r--r--Tests/SubDirSpaces/CMakeLists.txt77
-rw-r--r--Tests/SubDirSpaces/Executable Sources/CMakeLists.txt1
-rw-r--r--Tests/SubDirSpaces/Executable Sources/test.cxx49
-rw-r--r--Tests/SubDirSpaces/Executable/CMakeLists.txt1
-rw-r--r--Tests/SubDirSpaces/Executable/test.cxx49
-rw-r--r--Tests/SubDirSpaces/Some Examples/CMakeLists.txt3
-rw-r--r--Tests/SubDirSpaces/Some Examples/example1/CMakeLists.txt7
-rw-r--r--Tests/SubDirSpaces/Some Examples/example1/example1.cxx7
-rw-r--r--Tests/SubDirSpaces/Some Examples/example2/CMakeLists.txt2
-rw-r--r--Tests/SubDirSpaces/Some Examples/example2/example2.cxx7
-rw-r--r--Tests/SubDirSpaces/Some(x86) Sources/CMakeLists.txt1
-rw-r--r--Tests/SubDirSpaces/Some(x86) Sources/test.c3
-rw-r--r--Tests/SubDirSpaces/ThirdSubDir/pair+int.int1.c6
-rw-r--r--Tests/SubDirSpaces/ThirdSubDir/pair_int.int1.c6
-rw-r--r--Tests/SubDirSpaces/ThirdSubDir/pair_p_int.int1.c6
-rw-r--r--Tests/SubDirSpaces/ThirdSubDir/testfromauxsubdir.c21
-rw-r--r--Tests/SubDirSpaces/ThirdSubDir/thirdone.c6
-rw-r--r--Tests/SubDirSpaces/vcl_algorithm+vcl_pair+double.foo.c6
-rw-r--r--Tests/SubDirSpaces/vcl_algorithm_vcl_pair_double.foo.c6
-rw-r--r--Tests/SubProject/CMakeLists.txt6
-rw-r--r--Tests/SubProject/bar.cxx4
-rw-r--r--Tests/SubProject/car.cxx6
-rw-r--r--Tests/SubProject/foo/CMakeLists.txt3
-rw-r--r--Tests/SubProject/foo/foo.cxx15
-rw-r--r--Tests/SwigTest/CMakeLists.txt50
-rw-r--r--Tests/SwigTest/example.cxx28
-rw-r--r--Tests/SwigTest/example.h39
-rw-r--r--Tests/SwigTest/example.i10
-rw-r--r--Tests/SwigTest/runme.php458
-rwxr-xr-xTests/SwigTest/runme.pike53
-rw-r--r--Tests/SwigTest/runme.pl57
-rw-r--r--Tests/SwigTest/runme.py51
-rw-r--r--Tests/SwigTest/runme.rb49
-rw-r--r--Tests/SwigTest/runme.tcl50
-rw-r--r--Tests/SwigTest/runme2.tcl70
-rw-r--r--Tests/SystemInformation/CMakeLists.txt61
-rw-r--r--Tests/SystemInformation/DumpInformation.cxx80
-rw-r--r--Tests/SystemInformation/DumpInformation.h.in6
-rw-r--r--Tests/SystemInformation/SystemInformation.in102
-rw-r--r--Tests/TarTest/CMakeLists.txt69
-rw-r--r--Tests/TarTest/TestTarExec.cxx5
-rw-r--r--Tests/TargetName/CMakeLists.txt5
-rw-r--r--Tests/TargetName/executables/CMakeLists.txt1
-rw-r--r--Tests/TargetName/executables/hello_world.c5
-rw-r--r--Tests/TargetName/scripts/.gitattributes1
-rw-r--r--Tests/TargetName/scripts/CMakeLists.txt13
-rwxr-xr-xTests/TargetName/scripts/hello_world2
-rw-r--r--Tests/TestDriver/CMakeLists.txt15
-rw-r--r--Tests/TestDriver/subdir/test3.cxx8
-rw-r--r--Tests/TestDriver/test1.cxx25
-rw-r--r--Tests/TestDriver/test2.cxx8
-rw-r--r--Tests/TestDriver/testArgs.h20
-rw-r--r--Tests/TestDriver/testExtraStuff.cxx4
-rw-r--r--Tests/TestDriver/testExtraStuff2.cxx4
-rw-r--r--Tests/TestDriver/testExtraStuff3.cxx4
-rwxr-xr-xTests/TestInstall.sh.in63
-rw-r--r--Tests/Testing/CMakeLists.txt59
-rw-r--r--Tests/Testing/DartConfig.cmake24
-rw-r--r--Tests/Testing/Sub/Sub2/CMakeLists.txt17
-rw-r--r--Tests/Testing/Sub/Sub2/testing2.cxx4
-rw-r--r--Tests/Testing/testing.cxx4
-rw-r--r--Tests/TestsWorkingDirectory/CMakeLists.txt42
-rw-r--r--Tests/TestsWorkingDirectory/main.c64
-rw-r--r--Tests/TestsWorkingDirectory/subdir/CMakeLists.txt31
-rw-r--r--Tests/TryCompile/CMakeLists.txt247
-rw-r--r--Tests/TryCompile/Inner/CMakeLists.txt15
-rw-r--r--Tests/TryCompile/Inner/innerexe.c2
-rw-r--r--Tests/TryCompile/Inner/innerlib.c1
-rw-r--r--Tests/TryCompile/exit_success.c7
-rw-r--r--Tests/TryCompile/exit_with_error.c7
-rw-r--r--Tests/TryCompile/expect_arg.c22
-rw-r--r--Tests/TryCompile/fail.c1
-rw-r--r--Tests/TryCompile/pass.c6
-rw-r--r--Tests/Tutorial/Step1/CMakeLists.txt20
-rw-r--r--Tests/Tutorial/Step1/TutorialConfig.h.in4
-rw-r--r--Tests/Tutorial/Step1/tutorial.cxx23
-rw-r--r--Tests/Tutorial/Step2/CMakeLists.txt31
-rw-r--r--Tests/Tutorial/Step2/MathFunctions/CMakeLists.txt1
-rw-r--r--Tests/Tutorial/Step2/MathFunctions/MathFunctions.h1
-rw-r--r--Tests/Tutorial/Step2/MathFunctions/mysqrt.cxx29
-rw-r--r--Tests/Tutorial/Step2/TutorialConfig.h.in5
-rw-r--r--Tests/Tutorial/Step2/tutorial.cxx34
-rw-r--r--Tests/Tutorial/Step3/CMakeLists.txt68
-rw-r--r--Tests/Tutorial/Step3/MathFunctions/CMakeLists.txt4
-rw-r--r--Tests/Tutorial/Step3/MathFunctions/MathFunctions.h1
-rw-r--r--Tests/Tutorial/Step3/MathFunctions/mysqrt.cxx29
-rw-r--r--Tests/Tutorial/Step3/TutorialConfig.h.in5
-rw-r--r--Tests/Tutorial/Step3/tutorial.cxx34
-rw-r--r--Tests/Tutorial/Step4/CMakeLists.txt68
-rw-r--r--Tests/Tutorial/Step4/MathFunctions/CMakeLists.txt4
-rw-r--r--Tests/Tutorial/Step4/MathFunctions/MathFunctions.h1
-rw-r--r--Tests/Tutorial/Step4/MathFunctions/mysqrt.cxx39
-rw-r--r--Tests/Tutorial/Step4/TutorialConfig.h.in9
-rw-r--r--Tests/Tutorial/Step4/tutorial.cxx34
-rw-r--r--Tests/Tutorial/Step5/CMakeLists.txt72
-rw-r--r--Tests/Tutorial/Step5/MathFunctions/CMakeLists.txt17
-rw-r--r--Tests/Tutorial/Step5/MathFunctions/MakeTable.cxx35
-rw-r--r--Tests/Tutorial/Step5/MathFunctions/MathFunctions.h1
-rw-r--r--Tests/Tutorial/Step5/MathFunctions/mysqrt.cxx44
-rw-r--r--Tests/Tutorial/Step5/TutorialConfig.h.in9
-rw-r--r--Tests/Tutorial/Step5/tutorial.cxx34
-rw-r--r--Tests/Tutorial/Step6/CMakeLists.txt78
-rw-r--r--Tests/Tutorial/Step6/License.txt2
-rw-r--r--Tests/Tutorial/Step6/MathFunctions/CMakeLists.txt26
-rw-r--r--Tests/Tutorial/Step6/MathFunctions/MakeTable.cxx35
-rw-r--r--Tests/Tutorial/Step6/MathFunctions/MathFunctions.h1
-rw-r--r--Tests/Tutorial/Step6/MathFunctions/mysqrt.cxx44
-rw-r--r--Tests/Tutorial/Step6/TutorialConfig.h.in9
-rw-r--r--Tests/Tutorial/Step6/tutorial.cxx34
-rw-r--r--Tests/Tutorial/Step7/CMakeLists.txt82
-rw-r--r--Tests/Tutorial/Step7/CTestConfig.cmake1
-rw-r--r--Tests/Tutorial/Step7/License.txt2
-rw-r--r--Tests/Tutorial/Step7/MathFunctions/CMakeLists.txt26
-rw-r--r--Tests/Tutorial/Step7/MathFunctions/MakeTable.cxx35
-rw-r--r--Tests/Tutorial/Step7/MathFunctions/MathFunctions.h1
-rw-r--r--Tests/Tutorial/Step7/MathFunctions/mysqrt.cxx44
-rw-r--r--Tests/Tutorial/Step7/TutorialConfig.h.in9
-rw-r--r--Tests/Tutorial/Step7/build1.cmake5
-rw-r--r--Tests/Tutorial/Step7/build2.cmake9
-rw-r--r--Tests/Tutorial/Step7/tutorial.cxx34
-rw-r--r--Tests/Unset/CMakeLists.txt55
-rw-r--r--Tests/Unset/unset.c4
-rw-r--r--Tests/VSExternalInclude/CMakeLists.txt60
-rw-r--r--Tests/VSExternalInclude/Lib1/CMakeLists.txt5
-rw-r--r--Tests/VSExternalInclude/Lib1/lib1.cpp7
-rw-r--r--Tests/VSExternalInclude/Lib1/lib1.h8
-rw-r--r--Tests/VSExternalInclude/Lib2/CMakeLists.txt7
-rw-r--r--Tests/VSExternalInclude/Lib2/lib2.cpp9
-rw-r--r--Tests/VSExternalInclude/Lib2/lib2.h10
-rw-r--r--Tests/VSExternalInclude/main.cpp9
-rw-r--r--Tests/VSGNUFortran/CMakeLists.txt26
-rw-r--r--Tests/VSGNUFortran/c_code/CMakeLists.txt2
-rw-r--r--Tests/VSGNUFortran/c_code/main.c7
-rw-r--r--Tests/VSGNUFortran/runtest.cmake.in23
-rw-r--r--Tests/VSGNUFortran/subdir/CMakeLists.txt16
-rw-r--r--Tests/VSGNUFortran/subdir/fortran/CMakeLists.txt46
-rw-r--r--Tests/VSGNUFortran/subdir/fortran/hello.f7
-rw-r--r--Tests/VSGNUFortran/subdir/fortran/world.f6
-rw-r--r--Tests/VSMidl/CMakeLists.txt81
-rw-r--r--Tests/VSMidl/src/CMakeLists.txt12
-rw-r--r--Tests/VSMidl/src/main.cpp17
-rw-r--r--Tests/VSMidl/src/test.idl30
-rw-r--r--Tests/VSResource/CMakeLists.txt40
-rw-r--r--Tests/VSResource/main.cpp80
-rw-r--r--Tests/VSResource/test.rc17
-rw-r--r--Tests/VSResource/test.txt1
-rw-r--r--Tests/VariableUnusedViaSet/CMakeLists.txt4
-rw-r--r--Tests/VariableUnusedViaUnset/CMakeLists.txt8
-rw-r--r--Tests/VariableUsage/CMakeLists.txt1
-rw-r--r--Tests/Wrapping/CMakeLists.txt107
-rw-r--r--Tests/Wrapping/Wrap.c23
-rw-r--r--Tests/Wrapping/dummy0
-rw-r--r--Tests/Wrapping/fakefluid.cxx17
-rw-r--r--Tests/Wrapping/fltk1.fl0
-rw-r--r--Tests/Wrapping/foo.ui.in44
-rw-r--r--Tests/Wrapping/hints0
-rw-r--r--Tests/Wrapping/itkWrapperConfig.cxx0
-rw-r--r--Tests/Wrapping/qtnoqtmain.cxx5
-rw-r--r--Tests/Wrapping/qtwrapping.ui44
-rw-r--r--Tests/Wrapping/qtwrappingmain.cxx29
-rw-r--r--Tests/Wrapping/vtkExcluded.cxx0
-rw-r--r--Tests/Wrapping/vtkExcluded.h2
-rw-r--r--Tests/Wrapping/vtkIncluded.cxx0
-rw-r--r--Tests/Wrapping/vtkIncluded.h2
-rw-r--r--Tests/Wrapping/vtkTestMoc.h8
-rw-r--r--Tests/Wrapping/wrapping.cxx4
-rw-r--r--Tests/X11/CMakeLists.txt40
-rw-r--r--Tests/X11/HelloWorldX11.cxx146
-rw-r--r--Tests/X11/X11.c21
-rw-r--r--Tests/bootstrap.bat.in2
-rw-r--r--Tests/iOSNavApp/CMakeLists.txt38
-rw-r--r--Tests/iOSNavApp/Classes/NavApp3AppDelegate.h20
-rw-r--r--Tests/iOSNavApp/Classes/NavApp3AppDelegate.m88
-rw-r--r--Tests/iOSNavApp/Classes/RootViewController.h14
-rw-r--r--Tests/iOSNavApp/Classes/RootViewController.m168
-rw-r--r--Tests/iOSNavApp/Info.plist.in32
-rw-r--r--Tests/iOSNavApp/MainWindow.xib542
-rw-r--r--Tests/iOSNavApp/NavApp3_Prefix.pch14
-rw-r--r--Tests/iOSNavApp/RootViewController.xib384
-rw-r--r--Tests/iOSNavApp/TotalFunction.c14
-rw-r--r--Tests/iOSNavApp/TotalFunction.h14
-rw-r--r--Tests/iOSNavApp/main.m17
-rw-r--r--Tests/test_clean.cmake.in2
-rw-r--r--Utilities/.NoDartCoverage1
-rw-r--r--Utilities/.gitattributes2
-rw-r--r--Utilities/CMakeLists.txt158
-rw-r--r--Utilities/Doxygen/CMakeLists.txt39
-rw-r--r--Utilities/Doxygen/authors.txt17
-rwxr-xr-xUtilities/Doxygen/doc_makeall.sh.in248
-rw-r--r--Utilities/Doxygen/doxyfile.in79
-rwxr-xr-xUtilities/Git/commit-msg23
-rwxr-xr-xUtilities/Git/pre-commit67
-rwxr-xr-xUtilities/Git/prepare-commit-msg15
-rw-r--r--Utilities/GitSetup/.gitattributes7
-rw-r--r--Utilities/GitSetup/LICENSE202
-rw-r--r--Utilities/GitSetup/NOTICE5
-rw-r--r--Utilities/GitSetup/README80
-rw-r--r--Utilities/GitSetup/config9
-rw-r--r--Utilities/GitSetup/config.sample22
-rwxr-xr-xUtilities/GitSetup/setup-gerrit142
-rwxr-xr-xUtilities/GitSetup/setup-hooks63
-rwxr-xr-xUtilities/GitSetup/setup-ssh111
-rwxr-xr-xUtilities/GitSetup/setup-stage79
-rwxr-xr-xUtilities/GitSetup/setup-user39
-rwxr-xr-xUtilities/GitSetup/tips55
-rw-r--r--Utilities/KWIML/ABI.h.in478
-rw-r--r--Utilities/KWIML/CMakeLists.txt79
-rw-r--r--Utilities/KWIML/Copyright.txt30
-rw-r--r--Utilities/KWIML/INT.h.in861
-rw-r--r--Utilities/KWIML/README.txt29
-rw-r--r--Utilities/KWIML/test/CMakeLists.txt70
-rw-r--r--Utilities/KWIML/test/test.c39
-rw-r--r--Utilities/KWIML/test/test.cxx12
-rw-r--r--Utilities/KWIML/test/test.h37
-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_include_C.c22
-rw-r--r--Utilities/KWIML/test/test_include_CXX.cxx28
-rw-r--r--Utilities/KWStyle/CMake.kws.xml.in11
-rw-r--r--Utilities/KWStyle/CMakeFiles.txt.in15
-rw-r--r--Utilities/KWStyle/CMakeLists.txt78
-rw-r--r--Utilities/KWStyle/CMakeMoreChecks.kws.xml.in30
-rw-r--r--Utilities/KWStyle/CMakeOverwrite.txt0
-rw-r--r--Utilities/KWStyle/Headers/CMakeHeader.h11
-rw-r--r--Utilities/Release/CMakeInstall.bmpbin0 -> 25820 bytes
-rw-r--r--Utilities/Release/CMakeLogo.icobin0 -> 24542 bytes
-rw-r--r--Utilities/Release/Cygwin/CMakeLists.txt25
-rw-r--r--Utilities/Release/Cygwin/README.cygwin.in42
-rwxr-xr-xUtilities/Release/Cygwin/cygwin-package.sh.in90
-rw-r--r--Utilities/Release/Cygwin/cygwin-patch.diff.in0
-rw-r--r--Utilities/Release/Cygwin/cygwin-setup.hint.in5
-rw-r--r--Utilities/Release/README21
-rw-r--r--Utilities/Release/create-cmake-release.cmake42
-rw-r--r--Utilities/Release/dash2win64_cygwin.cmake19
-rw-r--r--Utilities/Release/dash2win64_release.cmake19
-rw-r--r--Utilities/Release/dashmacmini2_release.cmake18
-rw-r--r--Utilities/Release/dashmacmini5_release.cmake20
-rw-r--r--Utilities/Release/ferrari_sgi64_release.cmake16
-rw-r--r--Utilities/Release/ferrari_sgi_release.cmake11
-rw-r--r--Utilities/Release/hythloth_release.cmake10
-rw-r--r--Utilities/Release/magrathea_release.cmake16
-rw-r--r--Utilities/Release/release_cmake.cmake136
-rwxr-xr-xUtilities/Release/release_cmake.sh.in154
-rw-r--r--Utilities/Release/upload_release.cmake30
-rw-r--r--Utilities/Release/v20n250_aix_release.cmake21
-rwxr-xr-xUtilities/SetupForDevelopment.sh13
-rw-r--r--Utilities/cmThirdParty.h.in23
-rw-r--r--Utilities/cm_bzlib.h23
-rw-r--r--Utilities/cm_curl.h23
-rw-r--r--Utilities/cm_expat.h23
-rw-r--r--Utilities/cm_libarchive.h25
-rw-r--r--Utilities/cm_xmlrpc.h22
-rw-r--r--Utilities/cm_zlib.h23
-rw-r--r--Utilities/cmake.m453
-rw-r--r--Utilities/cmbzip2/CHANGES319
-rw-r--r--Utilities/cmbzip2/CMakeLists.txt4
-rw-r--r--Utilities/cmbzip2/LICENSE42
-rw-r--r--Utilities/cmbzip2/Makefile-libbz2_so59
-rw-r--r--Utilities/cmbzip2/README210
-rw-r--r--Utilities/cmbzip2/README.COMPILATION.PROBLEMS58
-rw-r--r--Utilities/cmbzip2/README.XML.STUFF45
-rw-r--r--Utilities/cmbzip2/blocksort.c1094
-rw-r--r--Utilities/cmbzip2/bz-common.xsl39
-rw-r--r--Utilities/cmbzip2/bz-fo.xsl276
-rw-r--r--Utilities/cmbzip2/bz-html.xsl20
-rw-r--r--Utilities/cmbzip2/bzdiff76
-rw-r--r--Utilities/cmbzip2/bzdiff.147
-rw-r--r--Utilities/cmbzip2/bzgrep75
-rw-r--r--Utilities/cmbzip2/bzgrep.156
-rw-r--r--Utilities/cmbzip2/bzip.css74
-rw-r--r--Utilities/cmbzip2/bzip2.1454
-rw-r--r--Utilities/cmbzip2/bzip2.1.preformatted399
-rw-r--r--Utilities/cmbzip2/bzip2.c2034
-rw-r--r--Utilities/cmbzip2/bzip2.txt391
-rw-r--r--Utilities/cmbzip2/bzip2recover.c514
-rw-r--r--Utilities/cmbzip2/bzlib.c1575
-rw-r--r--Utilities/cmbzip2/bzlib.h282
-rw-r--r--Utilities/cmbzip2/bzlib_private.h526
-rw-r--r--Utilities/cmbzip2/bzmore61
-rw-r--r--Utilities/cmbzip2/bzmore.1152
-rw-r--r--Utilities/cmbzip2/compress.c672
-rw-r--r--Utilities/cmbzip2/crctable.c104
-rw-r--r--Utilities/cmbzip2/decompress.c626
-rw-r--r--Utilities/cmbzip2/dlltest.c175
-rw-r--r--Utilities/cmbzip2/dlltest.dsp93
-rw-r--r--Utilities/cmbzip2/entities.xml9
-rwxr-xr-xUtilities/cmbzip2/format.pl68
-rw-r--r--Utilities/cmbzip2/huffman.c205
-rw-r--r--Utilities/cmbzip2/libbz2.def27
-rw-r--r--Utilities/cmbzip2/libbz2.dsp130
-rw-r--r--Utilities/cmbzip2/libbz2.libbin0 -> 60774 bytes
-rw-r--r--Utilities/cmbzip2/makefile.msc63
-rw-r--r--Utilities/cmbzip2/manual.html2540
-rw-r--r--Utilities/cmbzip2/manual.pdfbin0 -> 289422 bytes
-rw-r--r--Utilities/cmbzip2/manual.ps82900
-rw-r--r--Utilities/cmbzip2/manual.xml2964
-rw-r--r--Utilities/cmbzip2/mk251.c31
-rw-r--r--Utilities/cmbzip2/randtable.c84
-rw-r--r--Utilities/cmbzip2/sample1.rb2bin0 -> 32558 bytes
-rw-r--r--Utilities/cmbzip2/sample1.refbin0 -> 98869 bytes
-rw-r--r--Utilities/cmbzip2/sample1.tstbin0 -> 98869 bytes
-rw-r--r--Utilities/cmbzip2/sample2.rb2bin0 -> 74143 bytes
-rw-r--r--Utilities/cmbzip2/sample2.refbin0 -> 212610 bytes
-rw-r--r--Utilities/cmbzip2/sample2.tstbin0 -> 212610 bytes
-rw-r--r--Utilities/cmbzip2/sample3.rb2bin0 -> 237 bytes
-rw-r--r--Utilities/cmbzip2/sample3.ref30007
-rw-r--r--Utilities/cmbzip2/sample3.tst30007
-rw-r--r--Utilities/cmbzip2/spewG.c54
-rw-r--r--Utilities/cmbzip2/unzcrash.c141
-rw-r--r--Utilities/cmbzip2/words09
-rw-r--r--Utilities/cmbzip2/words14
-rw-r--r--Utilities/cmbzip2/words25
-rw-r--r--Utilities/cmbzip2/words330
-rwxr-xr-xUtilities/cmbzip2/xmlproc.sh114
-rw-r--r--Utilities/cmcompress/CMakeLists.txt5
-rw-r--r--Utilities/cmcompress/Copyright.txt34
-rw-r--r--Utilities/cmcompress/cmcompress.c551
-rw-r--r--Utilities/cmcompress/cmcompress.h195
-rw-r--r--Utilities/cmcompress/compress.c.original1308
-rw-r--r--Utilities/cmcurl/CMake/CMakeConfigurableFile.in2
-rw-r--r--Utilities/cmcurl/CMake/CurlCheckCSourceCompiles.cmake75
-rw-r--r--Utilities/cmcurl/CMake/CurlCheckCSourceRuns.cmake83
-rw-r--r--Utilities/cmcurl/CMake/CurlTests.c526
-rw-r--r--Utilities/cmcurl/CMake/OtherTests.cmake242
-rw-r--r--Utilities/cmcurl/CMakeLists.txt722
-rw-r--r--Utilities/cmcurl/COPYING21
-rw-r--r--Utilities/cmcurl/Platforms/WindowsCache.cmake121
-rw-r--r--Utilities/cmcurl/Platforms/config-aix.h486
-rw-r--r--Utilities/cmcurl/Testing/CMakeLists.txt19
-rw-r--r--Utilities/cmcurl/Testing/curlgtk.c95
-rw-r--r--Utilities/cmcurl/Testing/curltest.c159
-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.c78
-rw-r--r--Utilities/cmcurl/Testing/simple.c28
-rw-r--r--Utilities/cmcurl/Testing/simplessl.c118
-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.in726
-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.c1017
-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/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/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/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.c585
-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.c1945
-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.c143
-rw-r--r--Utilities/cmcurl/strequal.h43
-rw-r--r--Utilities/cmcurl/strerror.c748
-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/cmexpat/.NoDartCoverage1
-rw-r--r--Utilities/cmexpat/CMakeLists.txt34
-rw-r--r--Utilities/cmexpat/COPYING21
-rw-r--r--Utilities/cmexpat/ascii.h86
-rw-r--r--Utilities/cmexpat/asciitab.h37
-rw-r--r--Utilities/cmexpat/cm_expat_mangle.h87
-rw-r--r--Utilities/cmexpat/expat.h740
-rw-r--r--Utilities/cmexpat/expatConfig.h.in43
-rw-r--r--Utilities/cmexpat/expatDllConfig.h.in6
-rw-r--r--Utilities/cmexpat/iasciitab.h38
-rw-r--r--Utilities/cmexpat/latin1tab.h37
-rw-r--r--Utilities/cmexpat/nametab.h150
-rw-r--r--Utilities/cmexpat/utf8tab.h38
-rw-r--r--Utilities/cmexpat/xmlparse.c4622
-rw-r--r--Utilities/cmexpat/xmlrole.c1401
-rw-r--r--Utilities/cmexpat/xmlrole.h100
-rw-r--r--Utilities/cmexpat/xmltok.c1584
-rw-r--r--Utilities/cmexpat/xmltok.h299
-rw-r--r--Utilities/cmexpat/xmltok_impl.c1775
-rw-r--r--Utilities/cmexpat/xmltok_impl.h46
-rw-r--r--Utilities/cmexpat/xmltok_ns.c98
-rw-r--r--Utilities/cmlibarchive/.gitattributes2
-rw-r--r--Utilities/cmlibarchive/CMakeLists.txt1114
-rw-r--r--Utilities/cmlibarchive/COPYING60
-rw-r--r--Utilities/cmlibarchive/CTestConfig.cmake11
-rw-r--r--Utilities/cmlibarchive/README-CMake.txt66
-rw-r--r--Utilities/cmlibarchive/build/cmake/CheckFileOffsetBits.c14
-rw-r--r--Utilities/cmlibarchive/build/cmake/CheckFileOffsetBits.cmake44
-rw-r--r--Utilities/cmlibarchive/build/cmake/CheckFuncs.cmake49
-rw-r--r--Utilities/cmlibarchive/build/cmake/CheckFuncs_stub.c.in16
-rw-r--r--Utilities/cmlibarchive/build/cmake/CheckHeaderDirent.cmake32
-rw-r--r--Utilities/cmlibarchive/build/cmake/CheckStructMember.cmake43
-rw-r--r--Utilities/cmlibarchive/build/cmake/CheckTypeExists.cmake42
-rw-r--r--Utilities/cmlibarchive/build/cmake/FindLZMA.cmake48
-rw-r--r--Utilities/cmlibarchive/build/cmake/config.h.in1110
-rw-r--r--Utilities/cmlibarchive/build/pkgconfig/libarchive.pc.in11
-rw-r--r--Utilities/cmlibarchive/build/utils/gen_archive_string_composition_h.sh418
-rw-r--r--Utilities/cmlibarchive/build/version1
-rw-r--r--Utilities/cmlibarchive/libarchive/CMakeLists.txt152
-rw-r--r--Utilities/cmlibarchive/libarchive/archive.h826
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_acl.c1264
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_acl_private.h87
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_check_magic.c174
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_crc32.h78
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_crypto.c1427
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_crypto_private.h376
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_endian.h168
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry.3148
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry.c1651
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry.h620
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_acl.3233
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_copy_bhfi.c75
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_copy_stat.c79
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_link_resolver.c444
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_linkify.3224
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_locale.h88
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_paths.3151
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_perms.3207
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_private.h176
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_sparse.c156
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_stat.3272
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_stat.c118
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_strmode.c87
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_time.3127
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_xattr.c158
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_options.c164
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_options_private.h47
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_platform.h170
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_ppmd7.c1164
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_ppmd7_private.h119
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_ppmd_private.h158
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_private.h150
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_rb.c701
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_rb.h100
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read.3250
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read.c1342
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_data.3128
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_data_into_fd.c139
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_disk.3315
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_disk_entry_from_file.c1008
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c2318
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_disk_private.h71
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_disk_set_standard_lookup.c311
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_disk_windows.c1983
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_extract.3135
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_extract.c183
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_filter.3127
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_format.3175
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_free.391
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_header.389
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_new.357
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_open.3231
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_open_fd.c181
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_open_file.c177
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_open_filename.c509
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_open_memory.c186
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_private.h210
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_set_options.3207
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_set_options.c148
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_all.c75
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_bzip2.c370
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_compress.c454
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_gzip.c476
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_none.c52
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_program.c476
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_rpm.c288
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_uu.c680
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_xz.c985
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c3706
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_all.c87
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_ar.c625
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_by_code.c74
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c3315
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_cpio.c1048
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_empty.c93
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c3213
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c2745
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c1744
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c2574
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_raw.c187
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c2692
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c3324
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c1266
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_string.c4237
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_string.h237
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_string_composition.h1351
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_string_sprintf.c186
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_util.3222
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_util.c465
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_virtual.c147
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_windows.c813
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_windows.h297
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write.3261
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write.c709
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter_bzip2.c335
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter_compress.c445
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter_gzip.c356
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter_none.c43
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter_program.c327
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter_xz.c502
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_blocksize.3112
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_data.360
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_disk.3401
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c2844
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_disk_private.h38
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_disk_set_standard_lookup.c262
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c2551
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_filter.398
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_finish_entry.374
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_format.398
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_free.381
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_header.371
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_new.356
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_open.3233
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_open_fd.c144
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_open_file.c109
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_open_filename.c248
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_open_memory.c114
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_private.h136
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format.c76
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_7zip.c2303
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_ar.c564
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_by_name.c86
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio.c464
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio_newc.c420
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_gnutar.c684
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_iso9660.c8114
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_mtree.c1468
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_pax.c1833
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_shar.c642
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_ustar.c692
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_xar.c3171
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_zip.c820
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_options.3437
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_options.c124
-rw-r--r--Utilities/cmlibarchive/libarchive/config_freebsd.h160
-rw-r--r--Utilities/cmlibarchive/libarchive/cpio.5325
-rw-r--r--Utilities/cmlibarchive/libarchive/filter_fork.c161
-rw-r--r--Utilities/cmlibarchive/libarchive/filter_fork.h41
-rw-r--r--Utilities/cmlibarchive/libarchive/filter_fork_windows.c117
-rw-r--r--Utilities/cmlibarchive/libarchive/libarchive-formats.5361
-rw-r--r--Utilities/cmlibarchive/libarchive/libarchive.3256
-rw-r--r--Utilities/cmlibarchive/libarchive/libarchive_changes.3341
-rw-r--r--Utilities/cmlibarchive/libarchive/libarchive_internals.3365
-rw-r--r--Utilities/cmlibarchive/libarchive/mtree.5269
-rw-r--r--Utilities/cmlibarchive/libarchive/tar.5947
-rw-r--r--Utilities/cmzlib/.NoDartCoverage1
-rw-r--r--Utilities/cmzlib/CMakeLists.txt43
-rw-r--r--Utilities/cmzlib/ChangeLog855
-rw-r--r--Utilities/cmzlib/Copyright.txt23
-rw-r--r--Utilities/cmzlib/FAQ339
-rw-r--r--Utilities/cmzlib/INDEX51
-rw-r--r--Utilities/cmzlib/README125
-rw-r--r--Utilities/cmzlib/README.Kitware.txt40
-rw-r--r--Utilities/cmzlib/adler32.c149
-rw-r--r--Utilities/cmzlib/cm_zlib_mangle.h93
-rw-r--r--Utilities/cmzlib/compress.c79
-rw-r--r--Utilities/cmzlib/crc32.c423
-rw-r--r--Utilities/cmzlib/crc32.h441
-rw-r--r--Utilities/cmzlib/deflate.c1743
-rw-r--r--Utilities/cmzlib/deflate.h331
-rw-r--r--Utilities/cmzlib/gzio.c1026
-rw-r--r--Utilities/cmzlib/inffast.c318
-rw-r--r--Utilities/cmzlib/inffast.h11
-rw-r--r--Utilities/cmzlib/inffixed.h94
-rw-r--r--Utilities/cmzlib/inflate.c1368
-rw-r--r--Utilities/cmzlib/inflate.h115
-rw-r--r--Utilities/cmzlib/inftrees.c329
-rw-r--r--Utilities/cmzlib/inftrees.h55
-rw-r--r--Utilities/cmzlib/trees.c1219
-rw-r--r--Utilities/cmzlib/trees.h128
-rw-r--r--Utilities/cmzlib/uncompr.c61
-rw-r--r--Utilities/cmzlib/zconf.h351
-rw-r--r--Utilities/cmzlib/zlib.def47
-rw-r--r--Utilities/cmzlib/zlib.h1357
-rw-r--r--Utilities/cmzlib/zlib.rc32
-rw-r--r--Utilities/cmzlib/zlibDllConfig.h.in6
-rw-r--r--Utilities/cmzlib/zutil.c318
-rw-r--r--Utilities/cmzlib/zutil.h275
-rw-r--r--Utilities/xml/xhtml-lat1.ent196
-rw-r--r--Utilities/xml/xhtml-special.ent80
-rw-r--r--Utilities/xml/xhtml-symbol.ent237
-rw-r--r--Utilities/xml/xhtml1-strict.dtd977
-rwxr-xr-xbootstrap1564
-rw-r--r--cmake_uninstall.cmake.in22
-rwxr-xr-xconfigure3
-rw-r--r--doxygen.config697
3416 files changed, 782279 insertions, 0 deletions
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 000000000..d21f1dda0
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,22 @@
+.gitattributes export-ignore
+.hooks* export-ignore
+
+bootstrap crlf=input
+configure crlf=input
+*.[1-9] crlf=input
+*.sh crlf=input
+*.sh.in crlf=input
+
+*.bat -crlf
+*.bat.in -crlf
+*.dsp -crlf
+*.dsptemplate -crlf
+*.dsw -crlf
+*.sln -crlf
+*.vcproj -crlf
+
+*.c whitespace=tab-in-indent
+*.h whitespace=tab-in-indent
+*.cxx whitespace=tab-in-indent
+*.txt whitespace=tab-in-indent
+*.cmake whitespace=tab-in-indent
diff --git a/.hooks-config.bash b/.hooks-config.bash
new file mode 100644
index 000000000..97152f651
--- /dev/null
+++ b/.hooks-config.bash
@@ -0,0 +1,18 @@
+#=============================================================================
+# 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.
+#=============================================================================
+
+# Loaded by .git/hooks/(pre-commit|commit-msg|prepare-commit-msg)
+# during git commit after local hooks have been installed.
+
+hooks_chain_pre_commit="Utilities/Git/pre-commit"
+hooks_chain_commit_msg="Utilities/Git/commit-msg"
+hooks_chain_prepare_commit_msg="Utilities/Git/prepare-commit-msg"
diff --git a/CMakeCPack.cmake b/CMakeCPack.cmake
new file mode 100644
index 000000000..c3c25f560
--- /dev/null
+++ b/CMakeCPack.cmake
@@ -0,0 +1,123 @@
+#=============================================================================
+# 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.
+#=============================================================================
+
+# If the cmake version includes cpack, use it
+IF(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake")
+ IF(EXISTS "${CMAKE_ROOT}/Modules/InstallRequiredSystemLibraries.cmake")
+ OPTION(CMAKE_INSTALL_DEBUG_LIBRARIES
+ "Install Microsoft runtime debug libraries with CMake." FALSE)
+ MARK_AS_ADVANCED(CMAKE_INSTALL_DEBUG_LIBRARIES)
+
+ # By default, do not warn when built on machines using only VS Express:
+ IF(NOT DEFINED CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS)
+ SET(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS ON)
+ ENDIF()
+
+ INCLUDE(${CMake_SOURCE_DIR}/Modules/InstallRequiredSystemLibraries.cmake)
+ ENDIF(EXISTS "${CMAKE_ROOT}/Modules/InstallRequiredSystemLibraries.cmake")
+
+ 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_VERSION "${CMake_VERSION}")
+ SET(CPACK_PACKAGE_INSTALL_DIRECTORY "CMake ${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}")
+ 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)")
+ 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}")
+ ENDIF()
+
+ 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")
+ SET(CPACK_SYSTEM_NAME Cygwin)
+ ELSE("${CMAKE_SYSTEM_NAME}" STREQUAL "CYGWIN")
+ SET(CPACK_SYSTEM_NAME ${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR})
+ ENDIF("${CMAKE_SYSTEM_NAME}" STREQUAL "CYGWIN")
+ ENDIF(NOT DEFINED CPACK_SYSTEM_NAME)
+ IF(${CPACK_SYSTEM_NAME} MATCHES Windows)
+ IF(CMAKE_CL_64)
+ SET(CPACK_SYSTEM_NAME win64-x64)
+ ELSE(CMAKE_CL_64)
+ SET(CPACK_SYSTEM_NAME win32-x86)
+ ENDIF(CMAKE_CL_64)
+ ENDIF(${CPACK_SYSTEM_NAME} MATCHES Windows)
+
+ 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
+ # needed
+ IF(CYGWIN)
+ SET(CPACK_PACKAGE_FILE_NAME "${CPACK_SOURCE_PACKAGE_FILE_NAME}")
+ ELSE(CYGWIN)
+ SET(CPACK_PACKAGE_FILE_NAME
+ "${CPACK_SOURCE_PACKAGE_FILE_NAME}-${CPACK_SYSTEM_NAME}")
+ ENDIF(CYGWIN)
+ ENDIF(NOT DEFINED CPACK_PACKAGE_FILE_NAME)
+
+ SET(CPACK_PACKAGE_CONTACT "cmake@cmake.org")
+
+ IF(UNIX)
+ SET(CPACK_STRIP_FILES "bin/ccmake;bin/cmake;bin/cpack;bin/ctest")
+ SET(CPACK_SOURCE_STRIP_FILES "")
+ SET(CPACK_PACKAGE_EXECUTABLES "ccmake" "CMake")
+ ENDIF(UNIX)
+
+ # cygwin specific packaging stuff
+ IF(CYGWIN)
+ # setup the cygwin package name
+ SET(CPACK_PACKAGE_NAME cmake)
+ # setup the name of the package for cygwin cmake-2.4.3
+ SET(CPACK_PACKAGE_FILE_NAME
+ "${CPACK_PACKAGE_NAME}-${CMake_VERSION}")
+ # the source has the same name as the binary
+ SET(CPACK_SOURCE_PACKAGE_FILE_NAME ${CPACK_PACKAGE_FILE_NAME})
+ # Create a cygwin version number in case there are changes for cygwin
+ # that are not reflected upstream in CMake
+ SET(CPACK_CYGWIN_PATCH_NUMBER 1)
+ # These files are required by the cmCPackCygwinSourceGenerator and the files
+ # put into the release tar files.
+ SET(CPACK_CYGWIN_BUILD_SCRIPT
+ "${CMake_BINARY_DIR}/@CPACK_PACKAGE_FILE_NAME@-@CPACK_CYGWIN_PATCH_NUMBER@.sh")
+ SET(CPACK_CYGWIN_PATCH_FILE
+ "${CMake_BINARY_DIR}/@CPACK_PACKAGE_FILE_NAME@-@CPACK_CYGWIN_PATCH_NUMBER@.patch")
+ # include the sub directory cmake file for cygwin that
+ # configures some files and adds some install targets
+ # this file uses some of the package file name variables
+ INCLUDE(Utilities/Release/Cygwin/CMakeLists.txt)
+ ENDIF(CYGWIN)
+
+ # 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"
+ "${CMake_BINARY_DIR}/CMakeCPackOptions.cmake" @ONLY)
+ SET(CPACK_PROJECT_CONFIG_FILE "${CMake_BINARY_DIR}/CMakeCPackOptions.cmake")
+
+ # include CPack model once all variables are set
+ INCLUDE(CPack)
+ENDIF(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake")
diff --git a/CMakeCPackOptions.cmake.in b/CMakeCPackOptions.cmake.in
new file mode 100644
index 000000000..69a150851
--- /dev/null
+++ b/CMakeCPackOptions.cmake.in
@@ -0,0 +1,53 @@
+# This file is configured at cmake time, and loaded at cpack time.
+# To pass variables to cpack from cmake, they must be configured
+# in this file.
+
+if(CPACK_GENERATOR MATCHES "NSIS")
+ SET(CPACK_NSIS_INSTALL_ROOT "@CPACK_NSIS_INSTALL_ROOT@")
+
+ # set the install/unistall icon used for the installer itself
+ # There is a bug in NSI that does not handle full unix paths properly.
+ SET(CPACK_NSIS_MUI_ICON "@CMake_SOURCE_DIR@/Utilities/Release\\CMakeLogo.ico")
+ SET(CPACK_NSIS_MUI_UNIICON "@CMake_SOURCE_DIR@/Utilities/Release\\CMakeLogo.ico")
+ # set the package header icon for MUI
+ 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"
+ )
+ # 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_URL_INFO_ABOUT "http://www.kitware.com")
+ SET(CPACK_NSIS_CONTACT @CPACK_PACKAGE_CONTACT@)
+ SET(CPACK_NSIS_MODIFY_PATH ON)
+endif(CPACK_GENERATOR MATCHES "NSIS")
+
+# include the cpack options for qt dialog if they exisit
+# they might not if qt was not enabled for the build
+INCLUDE("@QT_DIALOG_CPACK_OPTIONS_FILE@" OPTIONAL)
+
+if(CPACK_GENERATOR MATCHES "CygwinSource")
+ # when packaging source make sure the .build directory is not included
+ SET(CPACK_SOURCE_IGNORE_FILES
+ "/CVS/" "/\\.build/" "/\\.svn/" "\\.swp$" "\\.#" "/#" "~$")
+endif(CPACK_GENERATOR MATCHES "CygwinSource")
+
+if("${CPACK_GENERATOR}" STREQUAL "PackageMaker")
+ if(CMAKE_PACKAGE_QTGUI)
+ set(CPACK_PACKAGE_DEFAULT_LOCATION "/Applications")
+ else(CMAKE_PACKAGE_QTGUI)
+ set(CPACK_PACKAGE_DEFAULT_LOCATION "/usr")
+ endif(CMAKE_PACKAGE_QTGUI)
+endif("${CPACK_GENERATOR}" STREQUAL "PackageMaker")
diff --git a/CMakeGraphVizOptions.cmake b/CMakeGraphVizOptions.cmake
new file mode 100644
index 000000000..038f17e9b
--- /dev/null
+++ b/CMakeGraphVizOptions.cmake
@@ -0,0 +1 @@
+SET(GRAPHVIZ_IGNORE_TARGETS "tartest;testSystemTools;testRegistry;testProcess;testIOS;testHashSTL;testFail;testCommandLineArguments;xrtest;LIBCURL;foo")
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 000000000..8522cad28
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,634 @@
+#=============================================================================
+# CMake - Cross Platform Makefile Generator
+# Copyright 2000-2012 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_MINIMUM_REQUIRED(VERSION 2.8.2 FATAL_ERROR)
+SET(CMAKE_LEGACY_CYGWIN_WIN32 0) # Remove when CMake >= 2.8.4 is required
+PROJECT(CMake)
+
+IF(CMAKE_BOOTSTRAP)
+ # Running from bootstrap script. Set local variable and remove from cache.
+ SET(CMAKE_BOOTSTRAP 1)
+ UNSET(CMAKE_BOOTSTRAP CACHE)
+ENDIF()
+
+SET(CMake_BIN_DIR ${CMake_BINARY_DIR}/bin)
+
+IF("${CMake_SOURCE_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}")
+ # Disallow architecture-specific try_run. It may not run on the host.
+ MACRO(TRY_RUN)
+ IF(CMAKE_TRY_COMPILE_OSX_ARCHITECTURES)
+ MESSAGE(FATAL_ERROR "TRY_RUN not allowed with CMAKE_TRY_COMPILE_OSX_ARCHITECTURES=[${CMAKE_TRY_COMPILE_OSX_ARCHITECTURES}]")
+ ELSE()
+ _TRY_RUN(${ARGV})
+ ENDIF()
+ ENDMACRO()
+ENDIF()
+
+#-----------------------------------------------------------------------
+# a macro to deal with system libraries, implemented as a macro
+# simply to improve readability of the main script
+#-----------------------------------------------------------------------
+MACRO(CMAKE_HANDLE_SYSTEM_LIBRARIES)
+ # Options have dependencies.
+ INCLUDE(CMakeDependentOption)
+
+ # Optionally use system xmlrpc. We no longer build or use it by default.
+ OPTION(CTEST_USE_XMLRPC "Enable xmlrpc submission method in CTest." OFF)
+ MARK_AS_ADVANCED(CTEST_USE_XMLRPC)
+
+ # 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)
+ FOREACH(util ${UTILITIES})
+ IF(NOT DEFINED CMAKE_USE_SYSTEM_LIBRARY_${util}
+ AND DEFINED CMAKE_USE_SYSTEM_LIBRARIES)
+ SET(CMAKE_USE_SYSTEM_LIBRARY_${util} "${CMAKE_USE_SYSTEM_LIBRARIES}")
+ ENDIF()
+ IF(DEFINED CMAKE_USE_SYSTEM_LIBRARY_${util})
+ IF(CMAKE_USE_SYSTEM_LIBRARY_${util})
+ SET(CMAKE_USE_SYSTEM_LIBRARY_${util} ON)
+ ELSE()
+ SET(CMAKE_USE_SYSTEM_LIBRARY_${util} OFF)
+ ENDIF()
+ IF(CMAKE_BOOTSTRAP)
+ UNSET(CMAKE_USE_SYSTEM_LIBRARY_${util} CACHE)
+ ENDIF()
+ STRING(TOLOWER "${util}" lutil)
+ SET(CMAKE_USE_SYSTEM_${util} "${CMAKE_USE_SYSTEM_LIBRARY_${util}}"
+ CACHE BOOL "Use system-installed ${lutil}" FORCE)
+ ELSE()
+ SET(CMAKE_USE_SYSTEM_LIBRARY_${util} OFF)
+ ENDIF()
+ ENDFOREACH(util)
+ IF(CMAKE_BOOTSTRAP)
+ UNSET(CMAKE_USE_SYSTEM_LIBRARIES CACHE)
+ ENDIF()
+
+ # Optionally use system utility libraries.
+ OPTION(CMAKE_USE_SYSTEM_LIBARCHIVE "Use system-installed libarchive" "${CMAKE_USE_SYSTEM_LIBRARY_LIBARCHIVE}")
+ CMAKE_DEPENDENT_OPTION(CMAKE_USE_SYSTEM_CURL "Use system-installed curl"
+ "${CMAKE_USE_SYSTEM_LIBRARY_CURL}" "NOT CTEST_USE_XMLRPC" ON)
+ CMAKE_DEPENDENT_OPTION(CMAKE_USE_SYSTEM_EXPAT "Use system-installed expat"
+ "${CMAKE_USE_SYSTEM_LIBRARY_EXPAT}" "NOT CTEST_USE_XMLRPC" ON)
+ CMAKE_DEPENDENT_OPTION(CMAKE_USE_SYSTEM_ZLIB "Use system-installed zlib"
+ "${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)
+
+ # Mention to the user what system libraries are being used.
+ FOREACH(util ${UTILITIES})
+ IF(CMAKE_USE_SYSTEM_${util})
+ MESSAGE(STATUS "Using system-installed ${util}")
+ ENDIF(CMAKE_USE_SYSTEM_${util})
+ ENDFOREACH(util)
+
+ # Inform utility library header wrappers whether to use system versions.
+ CONFIGURE_FILE(${CMake_SOURCE_DIR}/Utilities/cmThirdParty.h.in
+ ${CMake_BINARY_DIR}/Utilities/cmThirdParty.h
+ @ONLY)
+
+ENDMACRO(CMAKE_HANDLE_SYSTEM_LIBRARIES)
+
+
+
+
+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(WIN32 AND NOT UNIX AND NOT BORLAND AND NOT MINGW )
+
+
+#-----------------------------------------------------------------------
+# 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 (NOT DART_ROOT)
+
+ 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_MAKEPROGRAM "${MAKEPROGRAM}")
+ ELSE(NOT CMAKE_TEST_GENERATOR)
+ SET(CMAKE_TEST_DIFFERENT_GENERATOR TRUE)
+ ENDIF(NOT CMAKE_TEST_GENERATOR)
+
+ # 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(MSVC AND NOT CMAKE_TEST_DIFFERENT_GENERATOR)
+ IF("${CMAKE_TEST_GENERATOR}" MATCHES "NMake" OR
+ "${CMAKE_TEST_GENERATOR}" MATCHES "Visual Studio")
+ SET(CMAKE_TEST_MSVC 1)
+ ENDIF("${CMAKE_TEST_GENERATOR}" MATCHES "NMake" OR
+ "${CMAKE_TEST_GENERATOR}" MATCHES "Visual Studio")
+ ENDIF(MSVC AND NOT CMAKE_TEST_DIFFERENT_GENERATOR)
+
+ SET(CMAKE_TEST_SYSTEM_LIBRARIES 0)
+ FOREACH(util CURL EXPAT XMLRPC ZLIB)
+ IF(CMAKE_USE_SYSTEM_${util})
+ SET(CMAKE_TEST_SYSTEM_LIBRARIES 1)
+ ENDIF(CMAKE_USE_SYSTEM_${util})
+ ENDFOREACH(util)
+
+ # This variable is set by cmake, however to
+ # test cmake we want to make sure that
+ # 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")
+ ENDIF(BUILD_TESTING)
+
+ # configure some files for testing
+ CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/Templates/CTestScript.cmake.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/CTestScript.cmake"
+ @ONLY)
+ CONFIGURE_FILE(${CMake_SOURCE_DIR}/Tests/.NoDartCoverage
+ ${CMake_BINARY_DIR}/Tests/.NoDartCoverage)
+ CONFIGURE_FILE(${CMake_SOURCE_DIR}/Tests/.NoDartCoverage
+ ${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)
+ ENDIF(BUILD_TESTING AND DART_ROOT)
+ MARK_AS_ADVANCED(DART_ROOT)
+ MARK_AS_ADVANCED(CURL_TESTING)
+ENDMACRO(CMAKE_SETUP_TESTING)
+
+
+# Provide a way for Visual Studio Express users to turn OFF the new FOLDER
+# organization feature. Default to ON for non-Express users. Express users must
+# explicitly turn off this option to build CMake in the Express IDE...
+#
+OPTION(CMAKE_USE_FOLDERS "Enable folder grouping of projects in IDEs." ON)
+MARK_AS_ADVANCED(CMAKE_USE_FOLDERS)
+
+
+#-----------------------------------------------------------------------
+# a macro that only sets the FOLDER target property if it's
+# "appropriate"
+#-----------------------------------------------------------------------
+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()
+ ENDIF()
+ ELSE()
+ SET_PROPERTY(GLOBAL PROPERTY USE_FOLDERS OFF)
+ ENDIF()
+ENDMACRO(CMAKE_SET_TARGET_FOLDER)
+
+
+#-----------------------------------------------------------------------
+# a macro to build the utilities used by CMake
+# Simply to improve readability of the main script.
+#-----------------------------------------------------------------------
+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)
+ SET(KWSYS_USE_Directory 1)
+ SET(KWSYS_USE_RegularExpression 1)
+ SET(KWSYS_USE_Base64 1)
+ SET(KWSYS_USE_MD5 1)
+ SET(KWSYS_USE_Process 1)
+ SET(KWSYS_USE_CommandLineArguments 1)
+ SET(KWSYS_HEADER_ROOT ${CMake_BINARY_DIR}/Source)
+ SET(KWSYS_INSTALL_DOC_DIR "${CMake_DOC_DEST}")
+ ADD_SUBDIRECTORY(Source/kwsys)
+ SET(kwsys_folder "Utilities/KWSys")
+ CMAKE_SET_TARGET_FOLDER(${KWSYS_NAMESPACE} "${kwsys_folder}")
+ CMAKE_SET_TARGET_FOLDER(${KWSYS_NAMESPACE}_c "${kwsys_folder}")
+ CMAKE_SET_TARGET_FOLDER(${KWSYS_NAMESPACE}EncodeExecutable "${kwsys_folder}")
+ CMAKE_SET_TARGET_FOLDER(${KWSYS_NAMESPACE}ProcessFwd9x "${kwsys_folder}")
+ if(BUILD_TESTING)
+ CMAKE_SET_TARGET_FOLDER(${KWSYS_NAMESPACE}TestDynload "${kwsys_folder}")
+ CMAKE_SET_TARGET_FOLDER(${KWSYS_NAMESPACE}TestProcess "${kwsys_folder}")
+ CMAKE_SET_TARGET_FOLDER(${KWSYS_NAMESPACE}TestsC "${kwsys_folder}")
+ CMAKE_SET_TARGET_FOLDER(${KWSYS_NAMESPACE}TestsCxx "${kwsys_folder}")
+ CMAKE_SET_TARGET_FOLDER(${KWSYS_NAMESPACE}TestSharedForward "${kwsys_folder}")
+ endif()
+
+ #---------------------------------------------------------------------
+ # Setup third-party libraries.
+ # Everything in the tree should be able to include files from the
+ # Utilities directory.
+ INCLUDE_DIRECTORIES(
+ ${CMake_BINARY_DIR}/Utilities
+ ${CMake_SOURCE_DIR}/Utilities
+ )
+
+ # check for the use of system libraries versus builtin ones
+ # (a macro defined in this file)
+ CMAKE_HANDLE_SYSTEM_LIBRARIES()
+
+ #---------------------------------------------------------------------
+ # Build zlib library for Curl, CMake, and CTest.
+ SET(CMAKE_ZLIB_HEADER "cm_zlib.h")
+ IF(CMAKE_USE_SYSTEM_ZLIB)
+ FIND_PACKAGE(ZLIB)
+ IF(NOT ZLIB_FOUND)
+ MESSAGE(FATAL_ERROR
+ "CMAKE_USE_SYSTEM_ZLIB is ON but a zlib is not found!")
+ ENDIF(NOT ZLIB_FOUND)
+ SET(CMAKE_ZLIB_INCLUDES ${ZLIB_INCLUDE_DIR})
+ SET(CMAKE_ZLIB_LIBRARIES ${ZLIB_LIBRARIES})
+ ELSE(CMAKE_USE_SYSTEM_ZLIB)
+ SET(CMAKE_ZLIB_INCLUDES ${CMake_SOURCE_DIR}/Utilities)
+ SET(CMAKE_ZLIB_LIBRARIES cmzlib)
+ ADD_SUBDIRECTORY(Utilities/cmzlib)
+ CMAKE_SET_TARGET_FOLDER(cmzlib "Utilities/3rdParty")
+ ENDIF(CMAKE_USE_SYSTEM_ZLIB)
+
+ #---------------------------------------------------------------------
+ # Build Curl library for CTest.
+ IF(CMAKE_USE_SYSTEM_CURL)
+ FIND_PACKAGE(CURL)
+ IF(NOT CURL_FOUND)
+ MESSAGE(FATAL_ERROR
+ "CMAKE_USE_SYSTEM_CURL is ON but a curl is not found!")
+ ENDIF(NOT CURL_FOUND)
+ SET(CMAKE_CURL_INCLUDES ${CURL_INCLUDE_DIRS})
+ SET(CMAKE_CURL_LIBRARIES ${CURL_LIBRARIES})
+ ELSE(CMAKE_USE_SYSTEM_CURL)
+ 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(NOT CMAKE_BUILD_CURL_SHARED)
+ 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(CMAKE_TESTS_CDASH_SERVER)
+ ADD_SUBDIRECTORY(Utilities/cmcurl)
+ CMAKE_SET_TARGET_FOLDER(cmcurl "Utilities/3rdParty")
+ CMAKE_SET_TARGET_FOLDER(LIBCURL "Utilities/3rdParty")
+ ENDIF(CMAKE_USE_SYSTEM_CURL)
+
+ #---------------------------------------------------------------------
+ # Build Compress library for CTest.
+ SET(CMAKE_COMPRESS_INCLUDES
+ "${CMAKE_CURRENT_BINARY_DIR}/Utilities/cmcompress")
+ SET(CMAKE_COMPRESS_LIBRARIES "cmcompress")
+ ADD_SUBDIRECTORY(Utilities/cmcompress)
+ CMAKE_SET_TARGET_FOLDER(cmcompress "Utilities/3rdParty")
+ IF(CMAKE_USE_SYSTEM_BZIP2)
+ FIND_PACKAGE(BZip2)
+ ELSE()
+ SET(BZIP2_INCLUDE_DIR
+ "${CMAKE_CURRENT_SOURCE_DIR}/Utilities/cmbzip2")
+ SET(BZIP2_LIBRARIES cmbzip2)
+ ADD_SUBDIRECTORY(Utilities/cmbzip2)
+ CMAKE_SET_TARGET_FOLDER(cmbzip2 "Utilities/3rdParty")
+ 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()
+ IF(NOT LibArchive_FOUND)
+ MESSAGE(FATAL_ERROR "CMAKE_USE_SYSTEM_LIBARCHIVE is ON but LibArchive is not found!")
+ ENDIF()
+ SET(CMAKE_TAR_INCLUDES ${LibArchive_INCLUDE_DIRS})
+ SET(CMAKE_TAR_LIBRARIES ${LibArchive_LIBRARIES})
+ ELSE(CMAKE_USE_SYSTEM_LIBARCHIVE)
+ SET(ZLIB_INCLUDE_DIR ${CMAKE_ZLIB_INCLUDES})
+ SET(ZLIB_LIBRARY ${CMAKE_ZLIB_LIBRARIES})
+ 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_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")
+ ADD_SUBDIRECTORY(Utilities/cmlibarchive)
+ CMAKE_SET_TARGET_FOLDER(cmlibarchive "Utilities/3rdParty")
+ SET(CMAKE_TAR_LIBRARIES cmlibarchive ${BZIP2_LIBRARIES})
+ ENDIF(CMAKE_USE_SYSTEM_LIBARCHIVE)
+
+ #---------------------------------------------------------------------
+ # Build expat library for CMake and CTest.
+ IF(CMAKE_USE_SYSTEM_EXPAT)
+ FIND_PACKAGE(EXPAT)
+ IF(NOT EXPAT_FOUND)
+ MESSAGE(FATAL_ERROR
+ "CMAKE_USE_SYSTEM_EXPAT is ON but a expat is not found!")
+ ENDIF(NOT EXPAT_FOUND)
+ SET(CMAKE_EXPAT_INCLUDES ${EXPAT_INCLUDE_DIRS})
+ SET(CMAKE_EXPAT_LIBRARIES ${EXPAT_LIBRARIES})
+ ELSE(CMAKE_USE_SYSTEM_EXPAT)
+ SET(CMAKE_EXPAT_INCLUDES)
+ SET(CMAKE_EXPAT_LIBRARIES cmexpat)
+ ADD_SUBDIRECTORY(Utilities/cmexpat)
+ CMAKE_SET_TARGET_FOLDER(cmexpat "Utilities/3rdParty")
+ ENDIF(CMAKE_USE_SYSTEM_EXPAT)
+
+ #---------------------------------------------------------------------
+ # Build XMLRPC library for CMake and CTest.
+ IF(CTEST_USE_XMLRPC)
+ FIND_PACKAGE(XMLRPC QUIET REQUIRED libwww-client)
+ IF(NOT XMLRPC_FOUND)
+ MESSAGE(FATAL_ERROR
+ "CTEST_USE_XMLRPC is ON but xmlrpc is not found!")
+ ENDIF(NOT XMLRPC_FOUND)
+ SET(CMAKE_XMLRPC_INCLUDES ${XMLRPC_INCLUDE_DIRS})
+ SET(CMAKE_XMLRPC_LIBRARIES ${XMLRPC_LIBRARIES})
+ ENDIF(CTEST_USE_XMLRPC)
+
+ #---------------------------------------------------------------------
+ # 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)
+ SET(CURSES_NEED_NCURSES TRUE)
+ FIND_PACKAGE(Curses QUIET)
+ IF (CURSES_LIBRARY)
+ OPTION(BUILD_CursesDialog "Build the CMake Curses Dialog ccmake" ON)
+ ELSE (CURSES_LIBRARY)
+ MESSAGE("Curses libraries were not found. Curses GUI for CMake will not be built.")
+ SET(BUILD_CursesDialog 0)
+ ENDIF (CURSES_LIBRARY)
+ ELSE(NOT "${CMAKE_SYSTEM_NAME}" MATCHES syllable)
+ SET(BUILD_CursesDialog 0)
+ ENDIF(NOT "${CMAKE_SYSTEM_NAME}" MATCHES syllable)
+ ELSE (UNIX)
+ SET(BUILD_CursesDialog 0)
+ ENDIF (UNIX)
+ IF(BUILD_CursesDialog)
+ ADD_SUBDIRECTORY(Source/CursesDialog/form)
+ ENDIF(BUILD_CursesDialog)
+ENDMACRO (CMAKE_BUILD_UTILITIES)
+
+#-----------------------------------------------------------------------
+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()
+
+#-----------------------------------------------------------------------
+# 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()
+
+# Include the standard Dart testing module
+ENABLE_TESTING()
+INCLUDE (${CMAKE_ROOT}/Modules/Dart.cmake)
+
+# Set up test-time configuration.
+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_DEST "${CMAKE_DATA_DIR}")
+STRING(REGEX REPLACE "^/" "" CMake_DOC_DEST "${CMAKE_DOC_DIR}")
+
+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)
+
+# 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.
+#
+# If set explicitly to "NOTFOUND", curl tests and ctest tests that use
+# the network are skipped.
+#
+# If set to something starting with "http://localhost/", the CDash is
+# expected to be an instance of CDash used for CDash testing, pointing
+# to a cdash4simpletest database. In these cases, the CDash dashboards
+# should be run first.
+#
+IF("x${CMAKE_TESTS_CDASH_SERVER}" STREQUAL "x")
+ SET(CMAKE_TESTS_CDASH_SERVER "http://www.cdash.org/CDash")
+ENDIF("x${CMAKE_TESTS_CDASH_SERVER}" STREQUAL "x")
+
+# 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(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")
+ENDIF(BUILD_CursesDialog)
+
+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}/")
+ ENDIF(NOT "${ENDCH}" STREQUAL "/")
+ SET(CMAKE_INSTALL_PREFIX
+ "${CMAKE_INSTALL_PREFIX}${CMAKE_BUNDLE_NAME}.app/Contents")
+ ENDIF(APPLE)
+
+ 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(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")
+ENDIF(BUILD_QtDialog)
+
+
+# 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(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)
+ENDIF (UNIX)
+
+
+# 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)
+
+# 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)
+
+
+# build the remaining subdirectories
+ADD_SUBDIRECTORY(Source)
+ADD_SUBDIRECTORY(Utilities)
+ADD_SUBDIRECTORY(Tests)
+
+if(BUILD_TESTING)
+ CMAKE_SET_TARGET_FOLDER(CMakeLibTests "Tests")
+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_DEST})
+
+# Install script directories.
+INSTALL(
+ DIRECTORY Modules Templates
+ DESTINATION "${CMake_DATA_DEST}"
+ 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
+#-----------------------------------------------------------------------
+
+# 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})
diff --git a/CMakeLogo.gif b/CMakeLogo.gif
new file mode 100644
index 000000000..8426402a7
--- /dev/null
+++ b/CMakeLogo.gif
Binary files differ
diff --git a/CTestConfig.cmake b/CTestConfig.cmake
new file mode 100644
index 000000000..39032220e
--- /dev/null
+++ b/CTestConfig.cmake
@@ -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.
+#=============================================================================
+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_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
new file mode 100644
index 000000000..982919198
--- /dev/null
+++ b/CTestCustom.cmake.in
@@ -0,0 +1,85 @@
+SET(CTEST_CUSTOM_ERROR_MATCH
+ ${CTEST_CUSTOM_ERROR_MATCH}
+ "ERROR:")
+
+SET(CTEST_CUSTOM_WARNING_EXCEPTION
+ ${CTEST_CUSTOM_WARNING_EXCEPTION}
+ "xtree.[0-9]+. : warning C4702: unreachable code"
+ "warning LNK4221"
+ "warning LNK4204" # Occurs by race condition with objects in small libs
+ "variable .var_args[2]*. is used before its value is set"
+ "jobserver unavailable"
+ "warning: \\(Long double usage is reported only once for each file"
+ "warning: To disable this warning use"
+ "could not be inlined"
+ "libcmcurl.*has no symbols"
+ "not sorted slower link editing will result"
+ "stl_deque.h:479"
+ "Utilities.cmzlib."
+ "Utilities.cmbzip2."
+ "Source.CTest.Curl"
+ "Source.CursesDialog.form"
+ "Utilities.cmcurl"
+ "Utilities.cmexpat."
+ "Utilities.cmlibarchive"
+ "/usr/include.*warning.*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"
+ "Clock skew detected"
+ "remark\\(1209"
+ "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.*USER32.dll.*discarded by /OPT:REF"
+ "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.*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"
+ "PGC-W-0095-Type cast required for this conversion.*ProcessUNIX.c"
+ "[Qq]t([Cc]ore|[Gg]ui).*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)"
+ "warning.*This version of Mac OS X is unsupported"
+ "clang.*: warning: argument unused during compilation: .-g"
+
+ # Ignore clang's summary warning, assuming prior text has matched some
+ # other warning expression:
+ "[0-9,]+ warnings? generated."
+ )
+
+IF(NOT "@CMAKE_GENERATOR@" MATCHES "Xcode")
+ SET(CTEST_CUSTOM_COVERAGE_EXCLUDE
+ ${CTEST_CUSTOM_COVERAGE_EXCLUDE}
+ "XCode"
+ )
+ENDIF (NOT "@CMAKE_GENERATOR@" MATCHES "Xcode")
+
+IF(NOT "@CMAKE_GENERATOR@" MATCHES "KDevelop")
+ SET(CTEST_CUSTOM_COVERAGE_EXCLUDE
+ ${CTEST_CUSTOM_COVERAGE_EXCLUDE}
+ "Kdevelop"
+ )
+ENDIF (NOT "@CMAKE_GENERATOR@" MATCHES "KDevelop")
+
+SET(CTEST_CUSTOM_COVERAGE_EXCLUDE
+ ${CTEST_CUSTOM_COVERAGE_EXCLUDE}
+
+ # Exclude kwsys files from coverage results. They are reported
+ # (with better coverage results) on kwsys dashboards...
+ "/Source/(cm|kw)sys/"
+
+ # Exclude try_compile sources from coverage results:
+ "/CMakeFiles/CMakeTmp/"
+
+ # Exclude Qt source files from coverage results:
+ "[A-Za-z]./[Qq]t/qt-.+-opensource-src"
+ )
diff --git a/CTestCustom.ctest.in b/CTestCustom.ctest.in
new file mode 100644
index 000000000..6127843f6
--- /dev/null
+++ b/CTestCustom.ctest.in
@@ -0,0 +1,3 @@
+# 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
new file mode 100644
index 000000000..cdab4422d
--- /dev/null
+++ b/ChangeLog.manual
@@ -0,0 +1,3522 @@
+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
new file mode 100644
index 000000000..81b90e0c6
--- /dev/null
+++ b/ChangeLog.txt
@@ -0,0 +1,86670 @@
+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
new file mode 100644
index 000000000..3b455b96f
--- /dev/null
+++ b/CompileFlags.cmake
@@ -0,0 +1,64 @@
+#=============================================================================
+# 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.
+#=============================================================================
+
+#-----------------------------------------------------------------------------
+# set some special flags for different compilers
+#
+IF(CMAKE_GENERATOR MATCHES "Visual Studio 7")
+ SET(CMAKE_SKIP_COMPATIBILITY_TESTS 1)
+ENDIF(CMAKE_GENERATOR MATCHES "Visual Studio 7")
+IF(CMAKE_GENERATOR MATCHES "Visual Studio 6")
+ SET(CMAKE_SKIP_COMPATIBILITY_TESTS 1)
+ENDIF(CMAKE_GENERATOR MATCHES "Visual Studio 6")
+INCLUDE (${CMAKE_ROOT}/Modules/CMakeBackwardCompatibilityCXX.cmake)
+
+IF(WIN32 AND "${CMAKE_C_COMPILER_ID}" MATCHES "^(Intel)$")
+ SET(_INTEL_WINDOWS 1)
+ENDIF()
+
+# Disable deprecation warnings for standard C functions.
+# really only needed for newer versions of VS, but should
+# not hurt other versions, and this will work into the
+# future
+IF(MSVC OR _INTEL_WINDOWS)
+ ADD_DEFINITIONS(-D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE)
+ELSE()
+ENDIF()
+
+#silence duplicate symbol warnings on AIX
+IF(CMAKE_SYSTEM MATCHES "AIX.*")
+ IF(NOT CMAKE_COMPILER_IS_GNUCXX)
+ SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -bhalt:5 ")
+ ENDIF(NOT CMAKE_COMPILER_IS_GNUCXX)
+ENDIF(CMAKE_SYSTEM MATCHES "AIX.*")
+
+IF(CMAKE_SYSTEM 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(NOT CMAKE_COMPILER_IS_GNUCXX)
+ENDIF(CMAKE_SYSTEM MATCHES "IRIX.*")
+
+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(NOT CMAKE_COMPILER_IS_GNUCXX)
+ENDIF(CMAKE_SYSTEM MATCHES "OSF1-V.*")
+
+# use the ansi CXX compile flag for building cmake
+IF (CMAKE_ANSI_CXXFLAGS)
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_ANSI_CXXFLAGS}")
+ENDIF (CMAKE_ANSI_CXXFLAGS)
+
+IF (CMAKE_ANSI_CFLAGS)
+ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_ANSI_CFLAGS}")
+ENDIF (CMAKE_ANSI_CFLAGS)
diff --git a/Copyright.txt b/Copyright.txt
new file mode 100644
index 000000000..83a2482c0
--- /dev/null
+++ b/Copyright.txt
@@ -0,0 +1,56 @@
+CMake - Cross Platform Makefile Generator
+Copyright 2000-2011 Kitware, Inc., Insight Software Consortium
+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 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.
+
+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.
+
+------------------------------------------------------------------------------
+
+The above copyright and license notice applies to distributions of
+CMake in source and binary form. Some source files contain additional
+notices of original copyright by their contributors; see each source
+for details. Third-party software packages supplied with CMake under
+compatible licenses provide their own copyright notices documented in
+corresponding subdirectories.
+
+------------------------------------------------------------------------------
+
+CMake was initially developed by Kitware with the following sponsorship:
+
+ * National Library of Medicine at the National Institutes of Health
+ as part of the Insight Segmentation and Registration Toolkit (ITK).
+
+ * US National Labs (Los Alamos, Livermore, Sandia) ASC Parallel
+ Visualization Initiative.
+
+ * National Alliance for Medical Image Computing (NAMIC) is funded by the
+ National Institutes of Health through the NIH Roadmap for Medical Research,
+ Grant U54 EB005149.
+
+ * Kitware, Inc.
diff --git a/DartConfig.cmake b/DartConfig.cmake
new file mode 100644
index 000000000..37f66c7c1
--- /dev/null
+++ b/DartConfig.cmake
@@ -0,0 +1,18 @@
+#=============================================================================
+# 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.
+#=============================================================================
+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_CDASH TRUE)
diff --git a/DartLocal.conf.in b/DartLocal.conf.in
new file mode 100644
index 000000000..e28cb187f
--- /dev/null
+++ b/DartLocal.conf.in
@@ -0,0 +1,121 @@
+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
new file mode 100644
index 000000000..b04b32d5e
--- /dev/null
+++ b/Docs/CMakeLists.txt
@@ -0,0 +1,4 @@
+string(REGEX REPLACE "^/(.*)" "\\1" REL_CMAKE_DATA_DIR "${CMAKE_DATA_DIR}")
+install(FILES cmake-help.vim cmake-indent.vim cmake-syntax.vim DESTINATION ${REL_CMAKE_DATA_DIR}/editors/vim)
+install(FILES cmake-mode.el DESTINATION ${REL_CMAKE_DATA_DIR}/editors/emacs)
+ADD_SUBDIRECTORY (bash-completion)
diff --git a/Docs/bash-completion/CMakeLists.txt b/Docs/bash-completion/CMakeLists.txt
new file mode 100644
index 000000000..592b71e93
--- /dev/null
+++ b/Docs/bash-completion/CMakeLists.txt
@@ -0,0 +1,8 @@
+# Always install completion file in local dir
+# in order to be sure to always be able to install
+# in a local user directory rooted in a single directory.
+# packager should either patch that out or
+# add symlinks to the files in appropriate places
+# /etc/bash_completion.d/
+# DATADIR/completions (may be /usr/share/<package>/completions
+install(FILES cmake cpack ctest DESTINATION ${REL_CMAKE_DATA_DIR}/completions)
diff --git a/Docs/bash-completion/cmake b/Docs/bash-completion/cmake
new file mode 100644
index 000000000..59b565ac0
--- /dev/null
+++ b/Docs/bash-completion/cmake
@@ -0,0 +1,149 @@
+# 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)
+ # FIXME: doesn't work properly
+ local IFS=$'\n'
+ COMPREPLY=( $( compgen -W '$( cmake --help 2>/dev/null | sed -n \
+ "/^.*[^ ].*= Generates/{s|^ *\(.*[^ ]\) *= Generates.*$|\1|;s| |\\\\ |g;p}" \
+ 2>/dev/null )' -- "$cur" ) )
+ return
+ ;;
+ --help-command)
+ COMPREPLY=( $( compgen -W '$( cmake --help-command-list 2>/dev/null|
+ tail -n +2 )' -- "$cur" ) )
+ return
+ ;;
+ --help-module)
+ COMPREPLY=( $( compgen -W '$( cmake --help-module-list 2>/dev/null|
+ tail -n +2 )' -- "$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 | tail -n +2 )' -- "$cur" ) )
+ return
+ ;;
+ --help-variable)
+ COMPREPLY=( $( compgen -W '$( cmake --help-variable-list \
+ 2>/dev/null | tail -n +2 )' -- "$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
new file mode 100644
index 000000000..84dcfd534
--- /dev/null
+++ b/Docs/bash-completion/cpack
@@ -0,0 +1,61 @@
+# 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 |
+ grep "^ .*=\ .*" 2> /dev/null | grep -v "^ -" 2>/dev/null |
+ cut -d" " -f 3 )' -- "$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 | tail -n +2 )' -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|
+ tail -n +2 )' -- "$cur" ) )
+ return
+ ;;
+ --help-variable)
+ COMPREPLY=( $( compgen -W '$( cpack --help-variable-list \
+ 2>/dev/null | tail -n +2 )' -- "$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
new file mode 100644
index 000000000..9707f6269
--- /dev/null
+++ b/Docs/bash-completion/ctest
@@ -0,0 +1,81 @@
+# 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)
+ # FIXME ?
+ return
+ ;;
+ --interactive-debug-mode)
+ COMPREPLY=( $( compgen -W '0 1' -- "$cur" ) )
+ return
+ ;;
+ --help-command)
+ COMPREPLY=( $( compgen -W '$( ctest --help-command-list 2>/dev/null|
+ tail -n +2 )' -- "$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/Docs/cmake-help.vim
new file mode 100644
index 000000000..17cfa838e
--- /dev/null
+++ b/Docs/cmake-help.vim
@@ -0,0 +1,21 @@
+nmap ,hc :call OpenCmakeHelp()<CR>
+
+function! OpenCmakeHelp()
+ let s = getline( '.' )
+ let i = col( '.' ) - 1
+ while i > 0 && strpart( s, i, 1 ) =~ '[A-Za-z0-9_]'
+ let i = i - 1
+ endwhile
+ while i < col('$') && strpart( s, i, 1 ) !~ '[A-Za-z0-9_]'
+ let i = i + 1
+ endwhile
+ let start = match( s, '[A-Za-z0-9_]\+', i )
+ let end = matchend( s, '[A-Za-z0-9_]\+', i )
+ let ident = strpart( s, start, end - start )
+ execute "vertical new"
+ execute "%!cmake --help-command ".ident
+ set nomodified
+ set readonly
+endfunction
+
+autocmd BufRead,BufNewFile *.cmake,CMakeLists.txt,*.cmake.in nmap <F1> :call OpenCmakeHelp()<CR>
diff --git a/Docs/cmake-indent.vim b/Docs/cmake-indent.vim
new file mode 100644
index 000000000..f149873ed
--- /dev/null
+++ b/Docs/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
+" 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
new file mode 100644
index 000000000..951745515
--- /dev/null
+++ b/Docs/cmake-mode.el
@@ -0,0 +1,340 @@
+;=============================================================================
+; 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
+ "^\\([iI][fF]\\|[mM][aA][cC][rR][oO]\\|[fF][oO][rR][eE][aA][cC][hH]\\|[eE][lL][sS][eE]\\|[eE][lL][sS][eE][iI][fF]\\|[wW][hH][iI][lL][eE]\\|[fF][uU][nN][cC][tT][iI][oO][nN]\\)$")
+(defconst cmake-regex-block-close
+ "^[ \t]*\\([eE][nN][dD][iI][fF]\\|[eE][nN][dD][fF][oO][rR][eE][aA][cC][hH]\\|[eE][nN][dD][mM][aA][cC][rR][oO]\\|[eE][lL][sS][eE]\\|[eE][lL][sS][eE][iI][fF]\\|[eE][nN][dD][wW][hH][iI][lL][eE]\\|[eE][nN][dD][fF][uU][nN][cC][tT][iI][oO][nN]\\)[ \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))
+ 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)
+
+;------------------------------------------------------------------------------
+
+;;
+;; CMake mode startup function.
+;;
+(defun cmake-mode ()
+ "Major mode for editing CMake listfiles."
+ (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 "#")
+
+ ; 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
new file mode 100644
index 000000000..80b348eef
--- /dev/null
+++ b/Docs/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
+" 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
new file mode 100644
index 000000000..8ee7d721e
--- /dev/null
+++ b/Example/CMakeLists.txt
@@ -0,0 +1,10 @@
+# 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
new file mode 100644
index 000000000..477700fab
--- /dev/null
+++ b/Example/Demo/CMakeLists.txt
@@ -0,0 +1,12 @@
+# 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
new file mode 100644
index 000000000..31de0386c
--- /dev/null
+++ b/Example/Demo/demo.cxx
@@ -0,0 +1,10 @@
+#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
new file mode 100644
index 000000000..08a232913
--- /dev/null
+++ b/Example/Demo/demo_b.cxx
@@ -0,0 +1,3 @@
+#include "hello.h"
+
+Hello hello;
diff --git a/Example/Hello/CMakeLists.txt b/Example/Hello/CMakeLists.txt
new file mode 100644
index 000000000..879f4e5b1
--- /dev/null
+++ b/Example/Hello/CMakeLists.txt
@@ -0,0 +1,3 @@
+# 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
new file mode 100644
index 000000000..7107cc555
--- /dev/null
+++ b/Example/Hello/hello.cxx
@@ -0,0 +1,7 @@
+#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
new file mode 100644
index 000000000..b17d68343
--- /dev/null
+++ b/Example/Hello/hello.h
@@ -0,0 +1,11 @@
+#ifndef _hello_h
+#define _hello_h
+
+
+class Hello
+{
+public:
+ void Print();
+};
+
+#endif
diff --git a/Modules/AddFileDependencies.cmake b/Modules/AddFileDependencies.cmake
new file mode 100644
index 000000000..f971e37f5
--- /dev/null
+++ b/Modules/AddFileDependencies.cmake
@@ -0,0 +1,29 @@
+# - ADD_FILE_DEPENDENCIES(source_file depend_files...)
+# Adds the given files as dependencies to source_file
+#
+
+#=============================================================================
+# Copyright 2006-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(ADD_FILE_DEPENDENCIES _file)
+
+ GET_SOURCE_FILE_PROPERTY(_deps ${_file} OBJECT_DEPENDS)
+ IF (_deps)
+ SET(_deps ${_deps} ${ARGN})
+ ELSE (_deps)
+ SET(_deps ${ARGN})
+ ENDIF (_deps)
+
+ SET_SOURCE_FILES_PROPERTIES(${_file} PROPERTIES OBJECT_DEPENDS "${_deps}")
+
+ENDMACRO(ADD_FILE_DEPENDENCIES)
diff --git a/Modules/AutomocInfo.cmake.in b/Modules/AutomocInfo.cmake.in
new file mode 100644
index 000000000..13f21617b
--- /dev/null
+++ b/Modules/AutomocInfo.cmake.in
@@ -0,0 +1,16 @@
+set(AM_SOURCES @_moc_files@ )
+set(AM_HEADERS @_moc_headers@ )
+set(AM_MOC_COMPILE_DEFINITIONS @_moc_compile_defs@)
+set(AM_MOC_DEFINITIONS @_moc_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 "@QT_VERSION_MAJOR@" )
+set(AM_Qt5Core_VERSION_MAJOR "@Qt5Core_VERSION_MAJOR@" )
+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
new file mode 100644
index 000000000..9f7f03e27
--- /dev/null
+++ b/Modules/BasicConfigVersion-AnyNewerVersion.cmake.in
@@ -0,0 +1,31 @@
+# This is a basic version file for the Config-mode of find_package().
+# It is used by WriteBasicConfigVersionFile.cmake as input file for configure_file()
+# to create a version-file which can be installed along a config.cmake file.
+#
+# The created file sets PACKAGE_VERSION_EXACT if the current version string and
+# the requested version string are exactly the same and it sets
+# PACKAGE_VERSION_COMPATIBLE if the current version is >= requested version.
+# The variable CVF_VERSION must be set before calling configure_file().
+
+set(PACKAGE_VERSION "@CVF_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}")
+ 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 "")
+ 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@")
+ math(EXPR installedBits "@CMAKE_SIZEOF_VOID_P@ * 8")
+ set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)")
+ set(PACKAGE_VERSION_UNSUITABLE TRUE)
+endif()
diff --git a/Modules/BasicConfigVersion-ExactVersion.cmake.in b/Modules/BasicConfigVersion-ExactVersion.cmake.in
new file mode 100644
index 000000000..63f3f0339
--- /dev/null
+++ b/Modules/BasicConfigVersion-ExactVersion.cmake.in
@@ -0,0 +1,47 @@
+# This is a basic version file for the Config-mode of find_package().
+# It is used by write_basic_package_version_file() as input file for configure_file()
+# to create a version-file which can be installed along a config.cmake file.
+#
+# The created file sets PACKAGE_VERSION_EXACT if the current version string and
+# the requested version string are exactly the same and it sets
+# PACKAGE_VERSION_COMPATIBLE if the current version is equal to the requested version.
+# The tweak version component is ignored.
+# The variable CVF_VERSION must be set before calling configure_file().
+
+
+set(PACKAGE_VERSION "@CVF_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
+ 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}")
+ set(PACKAGE_VERSION_COMPATIBLE TRUE)
+else()
+ set(PACKAGE_VERSION_COMPATIBLE FALSE)
+endif()
+
+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 "")
+ 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@")
+ math(EXPR installedBits "@CMAKE_SIZEOF_VOID_P@ * 8")
+ set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)")
+ set(PACKAGE_VERSION_UNSUITABLE TRUE)
+endif()
diff --git a/Modules/BasicConfigVersion-SameMajorVersion.cmake.in b/Modules/BasicConfigVersion-SameMajorVersion.cmake.in
new file mode 100644
index 000000000..7bcea88a5
--- /dev/null
+++ b/Modules/BasicConfigVersion-SameMajorVersion.cmake.in
@@ -0,0 +1,46 @@
+# This is a basic version file for the Config-mode of find_package().
+# It is used by WriteBasicConfigVersionFile.cmake as input file for configure_file()
+# to create a version-file which can be installed along a config.cmake file.
+#
+# The created file sets PACKAGE_VERSION_EXACT if the current version string and
+# the requested version string are exactly the same and it sets
+# PACKAGE_VERSION_COMPATIBLE if the current version is >= requested version,
+# but only if the requested major version is the same as the current one.
+# The variable CVF_VERSION must be set before calling configure_file().
+
+
+set(PACKAGE_VERSION "@CVF_VERSION@")
+
+if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" )
+ set(PACKAGE_VERSION_COMPATIBLE FALSE)
+else()
+
+ if("@CVF_VERSION@" MATCHES "^([0-9]+)\\.")
+ set(CVF_VERSION_MAJOR "${CMAKE_MATCH_1}")
+ else()
+ set(CVF_VERSION_MAJOR "@CVF_VERSION@")
+ endif()
+
+ 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}")
+ 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 "")
+ 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@")
+ math(EXPR installedBits "@CMAKE_SIZEOF_VOID_P@ * 8")
+ set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)")
+ set(PACKAGE_VERSION_UNSUITABLE TRUE)
+endif()
diff --git a/Modules/BundleUtilities.cmake b/Modules/BundleUtilities.cmake
new file mode 100644
index 000000000..0143d593d
--- /dev/null
+++ b/Modules/BundleUtilities.cmake
@@ -0,0 +1,786 @@
+# - 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
+# Requires CMake 2.6 or greater because it uses function, break and
+# PARENT_SCOPE. Also depends on GetPrerequisites.cmake.
+#
+# 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.
+#
+# 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>)
+# Makes a copy of the bundle <src> at location <dst> and then fixes up the
+# new copied bundle in-place at <dst>...
+#
+# 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_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>)
+# 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_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>)
+# 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.
+#
+# 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,
+# 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.
+#
+# 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.
+#
+# 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_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.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software 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 functions defined in this file depend on the get_prerequisites function
+# (and possibly others) found in:
+#
+get_filename_component(BundleUtilities_cmake_dir "${CMAKE_CURRENT_LIST_FILE}" PATH)
+include("${BundleUtilities_cmake_dir}/GetPrerequisites.cmake")
+
+
+function(get_bundle_main_executable bundle result_var)
+ set(result "error: '${bundle}/Contents/Info.plist' file does not exist")
+
+ if(EXISTS "${bundle}/Contents/Info.plist")
+ set(result "error: no CFBundleExecutable in '${bundle}/Contents/Info.plist' file")
+ set(line_is_main_executable 0)
+ set(bundle_executable "")
+
+ # Read Info.plist as a list of lines:
+ #
+ 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}")
+
+ # Scan the lines for "<key>CFBundleExecutable</key>" - the line after that
+ # is the name of the main executable.
+ #
+ foreach(line ${info_plist})
+ if(line_is_main_executable)
+ string(REGEX REPLACE "^.*<string>(.*)</string>.*$" "\\1" bundle_executable "${line}")
+ break()
+ endif(line_is_main_executable)
+
+ if(line MATCHES "^.*<key>CFBundleExecutable</key>.*$")
+ set(line_is_main_executable 1)
+ endif(line MATCHES "^.*<key>CFBundleExecutable</key>.*$")
+ endforeach(line)
+
+ if(NOT "${bundle_executable}" STREQUAL "")
+ if(EXISTS "${bundle}/Contents/MacOS/${bundle_executable}")
+ set(result "${bundle}/Contents/MacOS/${bundle_executable}")
+ else(EXISTS "${bundle}/Contents/MacOS/${bundle_executable}")
+
+ # Ultimate goal:
+ # If not in "Contents/MacOS" then scan the bundle for matching files. If
+ # there is only one executable file that matches, then use it, otherwise
+ # it's an error...
+ #
+ #file(GLOB_RECURSE file_list "${bundle}/${bundle_executable}")
+
+ # But for now, pragmatically, it's an error. Expect the main executable
+ # for the bundle to be in Contents/MacOS, it's an error if it's not:
+ #
+ set(result "error: '${bundle}/Contents/MacOS/${bundle_executable}' does not exist")
+ endif(EXISTS "${bundle}/Contents/MacOS/${bundle_executable}")
+ endif(NOT "${bundle_executable}" STREQUAL "")
+ else(EXISTS "${bundle}/Contents/Info.plist")
+ #
+ # More inclusive technique... (This one would work on Windows and Linux
+ # too, if a developer followed the typical Mac bundle naming convention...)
+ #
+ # If there is no Info.plist file, try to find an executable with the same
+ # base name as the .app directory:
+ #
+ endif(EXISTS "${bundle}/Contents/Info.plist")
+
+ set(${result_var} "${result}" PARENT_SCOPE)
+endfunction(get_bundle_main_executable)
+
+
+function(get_dotapp_dir exe dotapp_dir_var)
+ set(s "${exe}")
+
+ if(s MATCHES "^.*/.*\\.app/.*$")
+ # If there is a ".app" parent directory,
+ # ascend until we hit it:
+ # (typical of a Mac bundle executable)
+ #
+ set(done 0)
+ while(NOT ${done})
+ get_filename_component(snamewe "${s}" NAME_WE)
+ get_filename_component(sname "${s}" NAME)
+ get_filename_component(sdir "${s}" PATH)
+ set(s "${sdir}")
+ if(sname MATCHES "\\.app$")
+ set(done 1)
+ set(dotapp_dir "${sdir}/${sname}")
+ endif(sname MATCHES "\\.app$")
+ endwhile(NOT ${done})
+ else(s MATCHES "^.*/.*\\.app/.*$")
+ # Otherwise use a directory containing the exe
+ # (typical of a non-bundle executable on Mac, Windows or Linux)
+ #
+ is_file_executable("${s}" is_executable)
+ if(is_executable)
+ get_filename_component(sdir "${s}" PATH)
+ set(dotapp_dir "${sdir}")
+ else(is_executable)
+ set(dotapp_dir "${s}")
+ endif(is_executable)
+ endif(s MATCHES "^.*/.*\\.app/.*$")
+
+
+ set(${dotapp_dir_var} "${dotapp_dir}" PARENT_SCOPE)
+endfunction(get_dotapp_dir)
+
+
+function(get_bundle_and_executable app bundle_var executable_var valid_var)
+ set(valid 0)
+
+ if(EXISTS "${app}")
+ # Is it a directory ending in .app?
+ if(IS_DIRECTORY "${app}")
+ if(app MATCHES "\\.app$")
+ get_bundle_main_executable("${app}" executable)
+ if(EXISTS "${app}" AND EXISTS "${executable}")
+ set(${bundle_var} "${app}" PARENT_SCOPE)
+ set(${executable_var} "${executable}" PARENT_SCOPE)
+ set(valid 1)
+ #message(STATUS "info: handled .app directory case...")
+ else(EXISTS "${app}" AND EXISTS "${executable}")
+ message(STATUS "warning: *NOT* handled - .app directory case...")
+ endif(EXISTS "${app}" AND EXISTS "${executable}")
+ else(app MATCHES "\\.app$")
+ message(STATUS "warning: *NOT* handled - directory but not .app case...")
+ endif(app MATCHES "\\.app$")
+ else(IS_DIRECTORY "${app}")
+ # Is it an executable file?
+ is_file_executable("${app}" is_executable)
+ if(is_executable)
+ get_dotapp_dir("${app}" dotapp_dir)
+ if(EXISTS "${dotapp_dir}")
+ set(${bundle_var} "${dotapp_dir}" PARENT_SCOPE)
+ set(${executable_var} "${app}" PARENT_SCOPE)
+ set(valid 1)
+ #message(STATUS "info: handled executable file in .app dir case...")
+ else()
+ get_filename_component(app_dir "${app}" PATH)
+ set(${bundle_var} "${app_dir}" PARENT_SCOPE)
+ set(${executable_var} "${app}" PARENT_SCOPE)
+ set(valid 1)
+ #message(STATUS "info: handled executable file in any dir case...")
+ endif()
+ else(is_executable)
+ message(STATUS "warning: *NOT* handled - not .app dir, not executable file...")
+ endif(is_executable)
+ endif(IS_DIRECTORY "${app}")
+ else(EXISTS "${app}")
+ message(STATUS "warning: *NOT* handled - directory/file does not exist...")
+ endif(EXISTS "${app}")
+
+ if(NOT valid)
+ set(${bundle_var} "error: not a bundle" PARENT_SCOPE)
+ set(${executable_var} "error: not a bundle" PARENT_SCOPE)
+ endif(NOT valid)
+
+ set(${valid_var} ${valid} PARENT_SCOPE)
+endfunction(get_bundle_and_executable)
+
+
+function(get_bundle_all_executables bundle exes_var)
+ set(exes "")
+
+ file(GLOB_RECURSE file_list "${bundle}/*")
+ foreach(f ${file_list})
+ is_file_executable("${f}" is_executable)
+ if(is_executable)
+ set(exes ${exes} "${f}")
+ endif(is_executable)
+ endforeach(f)
+
+ set(${exes_var} "${exes}" PARENT_SCOPE)
+endfunction(get_bundle_all_executables)
+
+
+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}")
+ set(${key_var} ${${key_var}} PARENT_SCOPE)
+endfunction(get_item_key)
+
+
+function(clear_bundle_keys keys_var)
+ foreach(key ${${keys_var}})
+ set(${key}_ITEM PARENT_SCOPE)
+ set(${key}_RESOLVED_ITEM PARENT_SCOPE)
+ set(${key}_DEFAULT_EMBEDDED_PATH PARENT_SCOPE)
+ set(${key}_EMBEDDED_ITEM PARENT_SCOPE)
+ set(${key}_RESOLVED_EMBEDDED_ITEM PARENT_SCOPE)
+ set(${key}_COPYFLAG PARENT_SCOPE)
+ endforeach(key)
+ set(${keys_var} PARENT_SCOPE)
+endfunction(clear_bundle_keys)
+
+
+function(set_bundle_key_values keys_var context item exepath dirs copyflag)
+ get_filename_component(item_name "${item}" NAME)
+
+ get_item_key("${item}" key)
+
+ list(LENGTH ${keys_var} length_before)
+ gp_append_unique(${keys_var} "${key}")
+ list(LENGTH ${keys_var} length_after)
+
+ if(NOT length_before EQUAL length_after)
+ gp_resolve_item("${context}" "${item}" "${exepath}" "${dirs}" resolved_item)
+
+ gp_item_default_embedded_path("${item}" default_embedded_path)
+
+ if(item MATCHES "[^/]+\\.framework/")
+ # For frameworks, construct the name under the embedded path from the
+ # opening "${item_name}.framework/" to the closing "/${item_name}":
+ #
+ string(REGEX REPLACE "^.*(${item_name}.framework/.*/${item_name}).*$" "${default_embedded_path}/\\1" embedded_item "${item}")
+ else(item MATCHES "[^/]+\\.framework/")
+ # For other items, just use the same name as the original, but in the
+ # embedded path:
+ #
+ set(embedded_item "${default_embedded_path}/${item_name}")
+ endif(item MATCHES "[^/]+\\.framework/")
+
+ # Replace @executable_path and resolve ".." references:
+ #
+ string(REPLACE "@executable_path" "${exepath}" resolved_embedded_item "${embedded_item}")
+ get_filename_component(resolved_embedded_item "${resolved_embedded_item}" ABSOLUTE)
+
+ # *But* -- if we are not copying, then force resolved_embedded_item to be
+ # the same as resolved_item. In the case of multiple executables in the
+ # original bundle, using the default_embedded_path results in looking for
+ # the resolved executable next to the main bundle executable. This is here
+ # so that exes in the other sibling directories (like "bin") get fixed up
+ # properly...
+ #
+ if(NOT copyflag)
+ set(resolved_embedded_item "${resolved_item}")
+ endif(NOT copyflag)
+
+ set(${keys_var} ${${keys_var}} PARENT_SCOPE)
+ set(${key}_ITEM "${item}" PARENT_SCOPE)
+ set(${key}_RESOLVED_ITEM "${resolved_item}" PARENT_SCOPE)
+ set(${key}_DEFAULT_EMBEDDED_PATH "${default_embedded_path}" PARENT_SCOPE)
+ set(${key}_EMBEDDED_ITEM "${embedded_item}" PARENT_SCOPE)
+ set(${key}_RESOLVED_EMBEDDED_ITEM "${resolved_embedded_item}" PARENT_SCOPE)
+ set(${key}_COPYFLAG "${copyflag}" PARENT_SCOPE)
+ else(NOT length_before EQUAL length_after)
+ #message("warning: item key '${key}' already in the list, subsequent references assumed identical to first")
+ endif(NOT length_before EQUAL length_after)
+endfunction(set_bundle_key_values)
+
+
+function(get_bundle_keys app libs dirs keys_var)
+ set(${keys_var} PARENT_SCOPE)
+
+ get_bundle_and_executable("${app}" bundle executable valid)
+ if(valid)
+ # Always use the exepath of the main bundle executable for @executable_path
+ # replacements:
+ #
+ get_filename_component(exepath "${executable}" PATH)
+
+ # But do fixups on all executables in the bundle:
+ #
+ get_bundle_all_executables("${bundle}" exes)
+
+ # 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(prereqs "")
+ get_prerequisites("${lib}" prereqs 1 1 "${exepath}" "${dirs}")
+ foreach(pr ${prereqs})
+ set_bundle_key_values(${keys_var} "${lib}" "${pr}" "${exepath}" "${dirs}" 1)
+ endforeach(pr)
+ endforeach(lib)
+
+ # For each executable found in the bundle, accumulate keys as we go.
+ # The list of keys should be complete when all prerequisites of all
+ # binaries in the bundle have been analyzed.
+ #
+ foreach(exe ${exes})
+ # Add the exe itself to the keys:
+ #
+ set_bundle_key_values(${keys_var} "${exe}" "${exe}" "${exepath}" "${dirs}" 0)
+
+ # Add each prerequisite to the keys:
+ #
+ set(prereqs "")
+ get_prerequisites("${exe}" prereqs 1 1 "${exepath}" "${dirs}")
+ foreach(pr ${prereqs})
+ set_bundle_key_values(${keys_var} "${exe}" "${pr}" "${exepath}" "${dirs}" 1)
+ endforeach(pr)
+ endforeach(exe)
+
+ # Propagate values to caller's scope:
+ #
+ set(${keys_var} ${${keys_var}} PARENT_SCOPE)
+ foreach(key ${${keys_var}})
+ set(${key}_ITEM "${${key}_ITEM}" PARENT_SCOPE)
+ set(${key}_RESOLVED_ITEM "${${key}_RESOLVED_ITEM}" PARENT_SCOPE)
+ set(${key}_DEFAULT_EMBEDDED_PATH "${${key}_DEFAULT_EMBEDDED_PATH}" PARENT_SCOPE)
+ 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)
+ endforeach(key)
+ endif(valid)
+endfunction(get_bundle_keys)
+
+
+function(copy_resolved_item_into_bundle resolved_item resolved_embedded_item)
+ if(WIN32)
+ # ignore case on Windows
+ string(TOLOWER "${resolved_item}" resolved_item_compare)
+ string(TOLOWER "${resolved_embedded_item}" resolved_embedded_item_compare)
+ else()
+ set(resolved_item_compare "${resolved_item}")
+ set(resolved_embedded_item_compare "${resolved_embedded_item}")
+ endif()
+
+ if("${resolved_item_compare}" STREQUAL "${resolved_embedded_item_compare}")
+ message(STATUS "warning: resolved_item == resolved_embedded_item - not copying...")
+ else()
+ #message(STATUS "copying COMMAND ${CMAKE_COMMAND} -E copy ${resolved_item} ${resolved_embedded_item}")
+ execute_process(COMMAND ${CMAKE_COMMAND} -E copy "${resolved_item}" "${resolved_embedded_item}")
+ if(UNIX AND NOT APPLE)
+ file(RPATH_REMOVE FILE "${resolved_embedded_item}")
+ endif(UNIX AND NOT APPLE)
+ endif()
+
+endfunction(copy_resolved_item_into_bundle)
+
+
+function(copy_resolved_framework_into_bundle resolved_item resolved_embedded_item)
+ if(WIN32)
+ # ignore case on Windows
+ string(TOLOWER "${resolved_item}" resolved_item_compare)
+ string(TOLOWER "${resolved_embedded_item}" resolved_embedded_item_compare)
+ else()
+ set(resolved_item_compare "${resolved_item}")
+ set(resolved_embedded_item_compare "${resolved_embedded_item}")
+ endif()
+
+ if("${resolved_item_compare}" STREQUAL "${resolved_embedded_item_compare}")
+ message(STATUS "warning: resolved_item == resolved_embedded_item - not copying...")
+ else()
+ if(BU_COPY_FULL_FRAMEWORK_CONTENTS)
+ # Full Framework (everything):
+ get_filename_component(resolved_dir "${resolved_item}" PATH)
+ get_filename_component(resolved_dir "${resolved_dir}/../.." ABSOLUTE)
+ get_filename_component(resolved_embedded_dir "${resolved_embedded_item}" PATH)
+ get_filename_component(resolved_embedded_dir "${resolved_embedded_dir}/../.." ABSOLUTE)
+ #message(STATUS "copying COMMAND ${CMAKE_COMMAND} -E copy_directory '${resolved_dir}' '${resolved_embedded_dir}'")
+ execute_process(COMMAND ${CMAKE_COMMAND} -E copy_directory "${resolved_dir}" "${resolved_embedded_dir}")
+ else()
+ # Framework lib itself:
+ #message(STATUS "copying COMMAND ${CMAKE_COMMAND} -E copy ${resolved_item} ${resolved_embedded_item}")
+ 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}")
+ 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()
+ endif()
+ if(UNIX AND NOT APPLE)
+ file(RPATH_REMOVE FILE "${resolved_embedded_item}")
+ endif(UNIX AND NOT APPLE)
+ endif()
+
+endfunction(copy_resolved_framework_into_bundle)
+
+
+function(fixup_bundle_item resolved_embedded_item exepath dirs)
+ # This item's key is "ikey":
+ #
+ get_item_key("${resolved_embedded_item}" ikey)
+
+ # Ensure the item is "inside the .app bundle" -- it should not be fixed up if
+ # it is not in the .app bundle... Otherwise, we'll modify files in the build
+ # tree, or in other varied locations around the file system, with our call to
+ # install_name_tool. Make sure that doesn't happen here:
+ #
+ get_dotapp_dir("${exepath}" exe_dotapp_dir)
+ string(LENGTH "${exe_dotapp_dir}/" exe_dotapp_dir_length)
+ string(LENGTH "${resolved_embedded_item}" resolved_embedded_item_length)
+ set(path_too_short 0)
+ set(is_embedded 0)
+ if(${resolved_embedded_item_length} LESS ${exe_dotapp_dir_length})
+ set(path_too_short 1)
+ endif()
+ if(NOT path_too_short)
+ string(SUBSTRING "${resolved_embedded_item}" 0 ${exe_dotapp_dir_length} item_substring)
+ if("${exe_dotapp_dir}/" STREQUAL "${item_substring}")
+ set(is_embedded 1)
+ endif()
+ endif()
+ if(NOT is_embedded)
+ message(" exe_dotapp_dir/='${exe_dotapp_dir}/'")
+ message(" item_substring='${item_substring}'")
+ message(" resolved_embedded_item='${resolved_embedded_item}'")
+ message("")
+ message("Install or copy the item into the bundle before calling fixup_bundle.")
+ message("Or maybe there's a typo or incorrect path in one of the args to fixup_bundle?")
+ message("")
+ message(FATAL_ERROR "cannot fixup an item that is not in the bundle...")
+ endif()
+
+ set(prereqs "")
+ get_prerequisites("${resolved_embedded_item}" prereqs 1 0 "${exepath}" "${dirs}")
+
+ set(changes "")
+
+ foreach(pr ${prereqs})
+ # Each referenced item's key is "rkey" in the loop:
+ #
+ get_item_key("${pr}" rkey)
+
+ if(NOT "${${rkey}_EMBEDDED_ITEM}" STREQUAL "")
+ set(changes ${changes} "-change" "${pr}" "${${rkey}_EMBEDDED_ITEM}")
+ else(NOT "${${rkey}_EMBEDDED_ITEM}" STREQUAL "")
+ message("warning: unexpected reference to '${pr}'")
+ endif(NOT "${${rkey}_EMBEDDED_ITEM}" STREQUAL "")
+ endforeach(pr)
+
+ if(BU_CHMOD_BUNDLE_ITEMS)
+ execute_process(COMMAND chmod u+w "${resolved_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}"
+ )
+endfunction(fixup_bundle_item)
+
+
+function(fixup_bundle app libs dirs)
+ message(STATUS "fixup_bundle")
+ message(STATUS " app='${app}'")
+ message(STATUS " libs='${libs}'")
+ message(STATUS " dirs='${dirs}'")
+
+ get_bundle_and_executable("${app}" bundle executable valid)
+ if(valid)
+ get_filename_component(exepath "${executable}" PATH)
+
+ message(STATUS "fixup_bundle: preparing...")
+ get_bundle_keys("${app}" "${libs}" "${dirs}" keys)
+
+ message(STATUS "fixup_bundle: copying...")
+ list(LENGTH keys n)
+ math(EXPR n ${n}*2)
+
+ set(i 0)
+ foreach(key ${keys})
+ math(EXPR i ${i}+1)
+ if(${${key}_COPYFLAG})
+ message(STATUS "${i}/${n}: copying '${${key}_RESOLVED_ITEM}'")
+ else(${${key}_COPYFLAG})
+ message(STATUS "${i}/${n}: *NOT* copying '${${key}_RESOLVED_ITEM}'")
+ endif(${${key}_COPYFLAG})
+
+ set(show_status 0)
+ if(show_status)
+ message(STATUS "key='${key}'")
+ message(STATUS "item='${${key}_ITEM}'")
+ message(STATUS "resolved_item='${${key}_RESOLVED_ITEM}'")
+ message(STATUS "default_embedded_path='${${key}_DEFAULT_EMBEDDED_PATH}'")
+ message(STATUS "embedded_item='${${key}_EMBEDDED_ITEM}'")
+ message(STATUS "resolved_embedded_item='${${key}_RESOLVED_EMBEDDED_ITEM}'")
+ message(STATUS "copyflag='${${key}_COPYFLAG}'")
+ message(STATUS "")
+ endif(show_status)
+
+ if(${${key}_COPYFLAG})
+ set(item "${${key}_ITEM}")
+ if(item MATCHES "[^/]+\\.framework/")
+ copy_resolved_framework_into_bundle("${${key}_RESOLVED_ITEM}"
+ "${${key}_RESOLVED_EMBEDDED_ITEM}")
+ else()
+ copy_resolved_item_into_bundle("${${key}_RESOLVED_ITEM}"
+ "${${key}_RESOLVED_EMBEDDED_ITEM}")
+ endif()
+ endif(${${key}_COPYFLAG})
+ endforeach(key)
+
+ message(STATUS "fixup_bundle: fixing...")
+ foreach(key ${keys})
+ math(EXPR i ${i}+1)
+ if(APPLE)
+ message(STATUS "${i}/${n}: fixing up '${${key}_RESOLVED_EMBEDDED_ITEM}'")
+ fixup_bundle_item("${${key}_RESOLVED_EMBEDDED_ITEM}" "${exepath}" "${dirs}")
+ else(APPLE)
+ message(STATUS "${i}/${n}: fix-up not required on this platform '${${key}_RESOLVED_EMBEDDED_ITEM}'")
+ endif(APPLE)
+ endforeach(key)
+
+ message(STATUS "fixup_bundle: cleaning up...")
+ clear_bundle_keys(keys)
+
+ message(STATUS "fixup_bundle: verifying...")
+ verify_app("${app}")
+ else(valid)
+ message(SEND_ERROR "error: fixup_bundle: not a valid bundle")
+ endif(valid)
+
+ message(STATUS "fixup_bundle: done")
+endfunction(fixup_bundle)
+
+
+function(copy_and_fixup_bundle src dst libs dirs)
+ execute_process(COMMAND ${CMAKE_COMMAND} -E copy_directory "${src}" "${dst}")
+ fixup_bundle("${dst}" "${libs}" "${dirs}")
+endfunction(copy_and_fixup_bundle)
+
+
+function(verify_bundle_prerequisites bundle result_var info_var)
+ set(result 1)
+ set(info "")
+ set(count 0)
+
+ get_bundle_main_executable("${bundle}" main_bundle_exe)
+
+ file(GLOB_RECURSE file_list "${bundle}/*")
+ foreach(f ${file_list})
+ is_file_executable("${f}" is_executable)
+ if(is_executable)
+ get_filename_component(exepath "${f}" PATH)
+ math(EXPR count "${count} + 1")
+
+ message(STATUS "executable file ${count}: ${f}")
+
+ set(prereqs "")
+ get_prerequisites("${f}" prereqs 1 1 "${exepath}" "")
+
+ # On the Mac,
+ # "embedded" and "system" prerequisites are fine... anything else means
+ # the bundle's prerequisites are not verified (i.e., the bundle is not
+ # really "standalone")
+ #
+ # On Windows (and others? Linux/Unix/...?)
+ # "local" and "system" prereqs are fine...
+ #
+ set(external_prereqs "")
+
+ foreach(p ${prereqs})
+ set(p_type "")
+ gp_file_type("${f}" "${p}" p_type)
+
+ if(APPLE)
+ if(NOT "${p_type}" STREQUAL "embedded" AND NOT "${p_type}" STREQUAL "system")
+ set(external_prereqs ${external_prereqs} "${p}")
+ endif()
+ else()
+ if(NOT "${p_type}" STREQUAL "local" AND NOT "${p_type}" STREQUAL "system")
+ set(external_prereqs ${external_prereqs} "${p}")
+ endif()
+ endif()
+ endforeach(p)
+
+ if(external_prereqs)
+ # Found non-system/somehow-unacceptable prerequisites:
+ set(result 0)
+ set(info ${info} "external prerequisites found:\nf='${f}'\nexternal_prereqs='${external_prereqs}'\n")
+ endif(external_prereqs)
+ endif(is_executable)
+ endforeach(f)
+
+ if(result)
+ set(info "Verified ${count} executable files in '${bundle}'")
+ endif(result)
+
+ set(${result_var} "${result}" PARENT_SCOPE)
+ set(${info_var} "${info}" PARENT_SCOPE)
+endfunction(verify_bundle_prerequisites)
+
+
+function(verify_bundle_symlinks bundle result_var info_var)
+ set(result 1)
+ set(info "")
+ set(count 0)
+
+ # TODO: implement this function for real...
+ # Right now, it is just a stub that verifies unconditionally...
+
+ set(${result_var} "${result}" PARENT_SCOPE)
+ set(${info_var} "${info}" PARENT_SCOPE)
+endfunction(verify_bundle_symlinks)
+
+
+function(verify_app app)
+ set(verified 0)
+ set(info "")
+
+ get_bundle_and_executable("${app}" bundle executable valid)
+
+ message(STATUS "===========================================================================")
+ message(STATUS "Analyzing app='${app}'")
+ message(STATUS "bundle='${bundle}'")
+ message(STATUS "executable='${executable}'")
+ message(STATUS "valid='${valid}'")
+
+ # Verify that the bundle does not have any "external" prerequisites:
+ #
+ verify_bundle_prerequisites("${bundle}" verified info)
+ message(STATUS "verified='${verified}'")
+ message(STATUS "info='${info}'")
+ message(STATUS "")
+
+ if(verified)
+ # Verify that the bundle does not have any symlinks to external files:
+ #
+ verify_bundle_symlinks("${bundle}" verified info)
+ message(STATUS "verified='${verified}'")
+ message(STATUS "info='${info}'")
+ message(STATUS "")
+ endif(verified)
+
+ if(NOT verified)
+ message(FATAL_ERROR "error: verify_app failed")
+ endif(NOT verified)
+endfunction(verify_app)
diff --git a/Modules/CMake.cmake b/Modules/CMake.cmake
new file mode 100644
index 000000000..53a0ddf99
--- /dev/null
+++ b/Modules/CMake.cmake
@@ -0,0 +1,17 @@
+
+#=============================================================================
+# 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.)
+
+# This file is used by cmake.cxx to compute the CMAKE_ROOT location.
+# Do not remove this file from cvs without updating cmake.cxx to look
+# for a different file.
diff --git a/Modules/CMakeASM-ATTInformation.cmake b/Modules/CMakeASM-ATTInformation.cmake
new file mode 100644
index 000000000..cb1f5d69c
--- /dev/null
+++ b/Modules/CMakeASM-ATTInformation.cmake
@@ -0,0 +1,25 @@
+
+#=============================================================================
+# 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.)
+
+# support for AT&T syntax assemblers, e.g. GNU as
+
+SET(ASM_DIALECT "-ATT")
+# *.S files are supposed to be preprocessed, so they should not be passed to
+# assembler but should be processed by gcc
+SET(CMAKE_ASM${ASM_DIALECT}_SOURCE_FILE_EXTENSIONS s;asm)
+
+SET(CMAKE_ASM${ASM_DIALECT}_COMPILE_OBJECT "<CMAKE_ASM${ASM_DIALECT}_COMPILER> <FLAGS> -o <OBJECT> <SOURCE>")
+
+INCLUDE(CMakeASMInformation)
+SET(ASM_DIALECT)
diff --git a/Modules/CMakeASMCompiler.cmake.in b/Modules/CMakeASMCompiler.cmake.in
new file mode 100644
index 000000000..2dc24b06d
--- /dev/null
+++ b/Modules/CMakeASMCompiler.cmake.in
@@ -0,0 +1,12 @@
+SET(CMAKE_ASM@ASM_DIALECT@_COMPILER "@_CMAKE_ASM_COMPILER@")
+SET(CMAKE_ASM@ASM_DIALECT@_COMPILER_ARG1 "@_CMAKE_ASM_COMPILER_ARG1@")
+SET(CMAKE_AR "@CMAKE_AR@")
+SET(CMAKE_RANLIB "@CMAKE_RANLIB@")
+SET(CMAKE_LINKER "@CMAKE_LINKER@")
+SET(CMAKE_ASM@ASM_DIALECT@_COMPILER_LOADED 1)
+SET(CMAKE_ASM@ASM_DIALECT@_COMPILER_ID "@_CMAKE_ASM_COMPILER_ID@")
+SET(CMAKE_ASM@ASM_DIALECT@_COMPILER_ENV_VAR "@_CMAKE_ASM_COMPILER_ENV_VAR@")
+
+SET(CMAKE_ASM@ASM_DIALECT@_IGNORE_EXTENSIONS h;H;o;O;obj;OBJ;def;DEF;rc;RC)
+SET(CMAKE_ASM@ASM_DIALECT@_LINKER_PREFERENCE 0)
+
diff --git a/Modules/CMakeASMInformation.cmake b/Modules/CMakeASMInformation.cmake
new file mode 100644
index 000000000..b5f242033
--- /dev/null
+++ b/Modules/CMakeASMInformation.cmake
@@ -0,0 +1,130 @@
+
+#=============================================================================
+# 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.)
+
+IF(UNIX)
+ SET(CMAKE_ASM${ASM_DIALECT}_OUTPUT_EXTENSION .o)
+ELSE(UNIX)
+ SET(CMAKE_ASM${ASM_DIALECT}_OUTPUT_EXTENSION .obj)
+ENDIF(UNIX)
+
+SET(CMAKE_INCLUDE_FLAG_ASM${ASM_DIALECT} "-I") # -I
+SET(CMAKE_BASE_NAME)
+GET_FILENAME_COMPONENT(CMAKE_BASE_NAME "${CMAKE_ASM${ASM_DIALECT}_COMPILER}" NAME_WE)
+
+IF("${CMAKE_BASE_NAME}" STREQUAL "as")
+ SET(CMAKE_BASE_NAME gas)
+ENDIF("${CMAKE_BASE_NAME}" STREQUAL "as")
+
+# Load compiler-specific information.
+SET(_INCLUDED_FILE "")
+IF(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID)
+ INCLUDE(Compiler/${CMAKE_ASM${ASM_DIALECT}_COMPILER_ID}-ASM${ASM_DIALECT} OPTIONAL RESULT_VARIABLE _INCLUDED_FILE)
+ENDIF(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID)
+IF(NOT _INCLUDED_FILE)
+ IF("ASM${ASM_DIALECT}" STREQUAL "ASM")
+ MESSAGE(STATUS "Warning: Did not find file Compiler/${CMAKE_ASM${ASM_DIALECT}_COMPILER_ID}-ASM${ASM_DIALECT}")
+ ENDIF("ASM${ASM_DIALECT}" STREQUAL "ASM")
+ INCLUDE(Platform/${CMAKE_BASE_NAME} OPTIONAL)
+ENDIF(NOT _INCLUDED_FILE)
+
+IF(CMAKE_SYSTEM_PROCESSOR)
+ INCLUDE(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_ASM${ASM_DIALECT}_COMPILER_ID}-ASM${ASM_DIALECT}-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL RESULT_VARIABLE _INCLUDED_FILE)
+ IF(NOT _INCLUDED_FILE)
+ INCLUDE(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_BASE_NAME}-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL)
+ ENDIF(NOT _INCLUDED_FILE)
+ENDIF(CMAKE_SYSTEM_PROCESSOR)
+
+INCLUDE(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_ASM${ASM_DIALECT}_COMPILER_ID}-ASM${ASM_DIALECT} OPTIONAL RESULT_VARIABLE _INCLUDED_FILE)
+IF(NOT _INCLUDED_FILE)
+ INCLUDE(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_BASE_NAME} OPTIONAL)
+ENDIF(NOT _INCLUDED_FILE)
+
+# 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)
+ENDIF(NOT CMAKE_ASM${ASM_DIALECT}_SOURCE_FILE_EXTENSIONS)
+
+
+# Support for CMAKE_ASM${ASM_DIALECT}_FLAGS_INIT and friends:
+SET(CMAKE_ASM${ASM_DIALECT}_FLAGS_INIT "$ENV{ASM${ASM_DIALECT}FLAGS} ${CMAKE_ASM${ASM_DIALECT}_FLAGS_INIT}")
+# avoid just having a space as the initial value for the cache
+IF(CMAKE_ASM${ASM_DIALECT}_FLAGS_INIT STREQUAL " ")
+ SET(CMAKE_ASM${ASM_DIALECT}_FLAGS_INIT)
+ENDIF(CMAKE_ASM${ASM_DIALECT}_FLAGS_INIT STREQUAL " ")
+SET (CMAKE_ASM${ASM_DIALECT}_FLAGS "${CMAKE_ASM${ASM_DIALECT}_FLAGS_INIT}" CACHE STRING
+ "Flags used by the assembler during all build types.")
+
+IF(NOT CMAKE_NOT_USING_CONFIG_FLAGS)
+# default build type is none
+ IF(NOT CMAKE_NO_BUILD_TYPE)
+ SET (CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE_INIT} CACHE STRING
+ "Choose the type of build, options are: None, Debug Release RelWithDebInfo MinSizeRel.")
+ ENDIF(NOT CMAKE_NO_BUILD_TYPE)
+ SET (CMAKE_ASM${ASM_DIALECT}_FLAGS_DEBUG "${CMAKE_ASM${ASM_DIALECT}_FLAGS_DEBUG_INIT}" CACHE STRING
+ "Flags used by the assembler during debug builds.")
+ SET (CMAKE_ASM${ASM_DIALECT}_FLAGS_MINSIZEREL "${CMAKE_ASM${ASM_DIALECT}_FLAGS_MINSIZEREL_INIT}" CACHE STRING
+ "Flags used by the assembler during release minsize builds.")
+ SET (CMAKE_ASM${ASM_DIALECT}_FLAGS_RELEASE "${CMAKE_ASM${ASM_DIALECT}_FLAGS_RELEASE_INIT}" CACHE STRING
+ "Flags used by the assembler during release builds.")
+ SET (CMAKE_ASM${ASM_DIALECT}_FLAGS_RELWITHDEBINFO "${CMAKE_ASM${ASM_DIALECT}_FLAGS_RELWITHDEBINFO_INIT}" CACHE STRING
+ "Flags used by the assembler during Release with Debug Info builds.")
+ENDIF(NOT CMAKE_NOT_USING_CONFIG_FLAGS)
+
+MARK_AS_ADVANCED(CMAKE_ASM${ASM_DIALECT}_FLAGS
+ CMAKE_ASM${ASM_DIALECT}_FLAGS_DEBUG
+ CMAKE_ASM${ASM_DIALECT}_FLAGS_MINSIZEREL
+ CMAKE_ASM${ASM_DIALECT}_FLAGS_RELEASE
+ CMAKE_ASM${ASM_DIALECT}_FLAGS_RELWITHDEBINFO
+ )
+
+
+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>")
+ENDIF(NOT CMAKE_ASM${ASM_DIALECT}_COMPILE_OBJECT)
+
+IF(NOT CMAKE_ASM${ASM_DIALECT}_CREATE_STATIC_LIBRARY)
+ SET(CMAKE_ASM${ASM_DIALECT}_CREATE_STATIC_LIBRARY
+ "<CMAKE_AR> cr <TARGET> <LINK_FLAGS> <OBJECTS> "
+ "<CMAKE_RANLIB> <TARGET> ")
+ENDIF(NOT CMAKE_ASM${ASM_DIALECT}_CREATE_STATIC_LIBRARY)
+
+IF(NOT CMAKE_ASM${ASM_DIALECT}_LINK_EXECUTABLE)
+ SET(CMAKE_ASM${ASM_DIALECT}_LINK_EXECUTABLE
+ "<CMAKE_ASM${ASM_DIALECT}_COMPILER> <FLAGS> <CMAKE_ASM${ASM_DIALECT}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
+ENDIF(NOT CMAKE_ASM${ASM_DIALECT}_LINK_EXECUTABLE)
+
+IF(NOT CMAKE_EXECUTABLE_RUNTIME_ASM${ASM_DIALECT}_FLAG)
+ SET(CMAKE_EXECUTABLE_RUNTIME_ASM${ASM_DIALECT}_FLAG ${CMAKE_SHARED_LIBRARY_RUNTIME_ASM${ASM_DIALECT}_FLAG})
+ENDIF()
+
+IF(NOT CMAKE_EXECUTABLE_RUNTIME_ASM${ASM_DIALECT}_FLAG_SEP)
+ SET(CMAKE_EXECUTABLE_RUNTIME_ASM${ASM_DIALECT}_FLAG_SEP ${CMAKE_SHARED_LIBRARY_RUNTIME_ASM${ASM_DIALECT}_FLAG_SEP})
+ENDIF()
+
+IF(NOT CMAKE_EXECUTABLE_RPATH_LINK_ASM${ASM_DIALECT}_FLAG)
+ SET(CMAKE_EXECUTABLE_RPATH_LINK_ASM${ASM_DIALECT}_FLAG ${CMAKE_SHARED_LIBRARY_RPATH_LINK_ASM${ASM_DIALECT}_FLAG})
+ENDIF()
+
+# to be done
+IF(NOT CMAKE_ASM${ASM_DIALECT}_CREATE_SHARED_LIBRARY)
+ SET(CMAKE_ASM${ASM_DIALECT}_CREATE_SHARED_LIBRARY)
+ENDIF(NOT CMAKE_ASM${ASM_DIALECT}_CREATE_SHARED_LIBRARY)
+
+IF(NOT CMAKE_ASM${ASM_DIALECT}_CREATE_SHARED_MODULE)
+ SET(CMAKE_ASM${ASM_DIALECT}_CREATE_SHARED_MODULE)
+ENDIF(NOT CMAKE_ASM${ASM_DIALECT}_CREATE_SHARED_MODULE)
+
+
+SET(CMAKE_ASM${ASM_DIALECT}_INFOMATION_LOADED 1)
+
diff --git a/Modules/CMakeASM_MASMInformation.cmake b/Modules/CMakeASM_MASMInformation.cmake
new file mode 100644
index 000000000..4e1386fab
--- /dev/null
+++ b/Modules/CMakeASM_MASMInformation.cmake
@@ -0,0 +1,24 @@
+
+#=============================================================================
+# Copyright 2008-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.)
+
+# support for the MS assembler, masm and masm64
+
+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>")
+
+INCLUDE(CMakeASMInformation)
+SET(ASM_DIALECT)
diff --git a/Modules/CMakeASM_NASMInformation.cmake b/Modules/CMakeASM_NASMInformation.cmake
new file mode 100644
index 000000000..9da7d306c
--- /dev/null
+++ b/Modules/CMakeASM_NASMInformation.cmake
@@ -0,0 +1,46 @@
+
+#=============================================================================
+# Copyright 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.)
+
+# support for the nasm assembler
+
+set(CMAKE_ASM_NASM_SOURCE_FILE_EXTENSIONS nasm asm)
+
+if(NOT CMAKE_ASM_NASM_OBJECT_FORMAT)
+ if(WIN32)
+ if(CMAKE_C_SIZEOF_DATA_PTR EQUAL 8)
+ SET(CMAKE_ASM_NASM_OBJECT_FORMAT win64)
+ else()
+ SET(CMAKE_ASM_NASM_OBJECT_FORMAT win32)
+ endif()
+ elseif(APPLE)
+ if(CMAKE_C_SIZEOF_DATA_PTR EQUAL 8)
+ SET(CMAKE_ASM_NASM_OBJECT_FORMAT macho64)
+ else()
+ SET(CMAKE_ASM_NASM_OBJECT_FORMAT macho)
+ endif()
+ else()
+ if(CMAKE_C_SIZEOF_DATA_PTR EQUAL 8)
+ SET(CMAKE_ASM_NASM_OBJECT_FORMAT elf64)
+ else()
+ SET(CMAKE_ASM_NASM_OBJECT_FORMAT elf)
+ endif()
+ endif()
+endif()
+
+set(CMAKE_ASM_NASM_COMPILE_OBJECT "<CMAKE_ASM_NASM_COMPILER> <FLAGS> -f ${CMAKE_ASM_NASM_OBJECT_FORMAT} -o <OBJECT> <SOURCE>")
+
+# Load the generic ASMInformation file:
+set(ASM_DIALECT "_NASM")
+include(CMakeASMInformation)
+set(ASM_DIALECT)
diff --git a/Modules/CMakeAddFortranSubdirectory.cmake b/Modules/CMakeAddFortranSubdirectory.cmake
new file mode 100644
index 000000000..abd910055
--- /dev/null
+++ b/Modules/CMakeAddFortranSubdirectory.cmake
@@ -0,0 +1,206 @@
+# - 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:
+#
+# NO_EXTERNAL_INSTALL is required for forward compatibility with a
+# future version that supports installation of the external project
+# binaries during "make install".
+
+#=============================================================================
+# Copyright 2011-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.)
+
+
+set(_MS_MINGW_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR})
+include(CheckLanguage)
+include(ExternalProject)
+include(CMakeParseArguments)
+
+function(_setup_mingw_config_and_build source_dir build_dir)
+ # Look for a MinGW gfortran.
+ find_program(MINGW_GFORTRAN
+ NAMES gfortran
+ PATHS
+ c:/MinGW/bin
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\MinGW;InstallLocation]/bin"
+ )
+ if(NOT MINGW_GFORTRAN)
+ message(FATAL_ERROR
+ "gfortran not found, please install MinGW with the gfortran option."
+ "Or set the cache variable MINGW_GFORTRAN to the full path. "
+ " This is required to build")
+ endif()
+
+ # Validate the MinGW gfortran we found.
+ if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set(_mingw_target "Target:.*64.*mingw")
+ else()
+ set(_mingw_target "Target:.*mingw32")
+ endif()
+ execute_process(COMMAND "${MINGW_GFORTRAN}" -v
+ ERROR_VARIABLE out ERROR_STRIP_TRAILING_WHITESPACE)
+ if(NOT "${out}" MATCHES "${_mingw_target}")
+ string(REPLACE "\n" "\n " out " ${out}")
+ message(FATAL_ERROR
+ "MINGW_GFORTRAN is set to\n"
+ " ${MINGW_GFORTRAN}\n"
+ "which is not a MinGW gfortran for this architecture. "
+ "The output from -v does not match \"${_mingw_target}\":\n"
+ "${out}\n"
+ "Set MINGW_GFORTRAN to a proper MinGW gfortran for this architecture."
+ )
+ endif()
+
+ # Configure scripts to run MinGW tools with the proper PATH.
+ get_filename_component(MINGW_PATH ${MINGW_GFORTRAN} PATH)
+ file(TO_NATIVE_PATH "${MINGW_PATH}" MINGW_PATH)
+ string(REPLACE "\\" "\\\\" MINGW_PATH "${MINGW_PATH}")
+ configure_file(
+ ${_MS_MINGW_SOURCE_DIR}/CMakeAddFortranSubdirectory/config_mingw.cmake.in
+ ${build_dir}/config_mingw.cmake
+ @ONLY)
+ configure_file(
+ ${_MS_MINGW_SOURCE_DIR}/CMakeAddFortranSubdirectory/build_mingw.cmake.in
+ ${build_dir}/build_mingw.cmake
+ @ONLY)
+endfunction()
+
+function(_add_fortran_library_link_interface library depend_library)
+ set_target_properties(${library} PROPERTIES
+ IMPORTED_LINK_INTERFACE_LIBRARIES_NOCONFIG "${depend_library}")
+endfunction()
+
+
+function(cmake_add_fortran_subdirectory subdir)
+ # Parse arguments to function
+ set(options NO_EXTERNAL_INSTALL)
+ set(oneValueArgs PROJECT ARCHIVE_DIR RUNTIME_DIR)
+ set(multiValueArgs LIBRARIES LINK_LIBRARIES CMAKE_COMMAND_LINE)
+ cmake_parse_arguments(ARGS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+ if(NOT ARGS_NO_EXTERNAL_INSTALL)
+ message(FATAL_ERROR
+ "Option NO_EXTERNAL_INSTALL is required (for forward compatibility) "
+ "but was not given."
+ )
+ endif()
+
+ # if we are not using MSVC without fortran support
+ # then just use the usual add_subdirectory to build
+ # the fortran library
+ check_language(Fortran)
+ if(NOT (MSVC AND (NOT CMAKE_Fortran_COMPILER)))
+ add_subdirectory(${subdir})
+ return()
+ endif()
+
+ # if we have MSVC without Intel fortran then setup
+ # external projects to build with mingw fortran
+
+ set(source_dir "${CMAKE_CURRENT_SOURCE_DIR}/${subdir}")
+ set(project_name "${ARGS_PROJECT}")
+ set(library_dir "${ARGS_ARCHIVE_DIR}")
+ set(binary_dir "${ARGS_RUNTIME_DIR}")
+ set(libraries ${ARGS_LIBRARIES})
+ # use the same directory that add_subdirectory would have used
+ set(build_dir "${CMAKE_CURRENT_BINARY_DIR}/${subdir}")
+ foreach(dir_var library_dir binary_dir)
+ if(NOT IS_ABSOLUTE "${${dir_var}}")
+ get_filename_component(${dir_var}
+ "${CMAKE_CURRENT_BINARY_DIR}/${${dir_var}}" ABSOLUTE)
+ endif()
+ endforeach()
+ # create build and configure wrapper scripts
+ _setup_mingw_config_and_build("${source_dir}" "${build_dir}")
+ # create the external project
+ externalproject_add(${project_name}_build
+ SOURCE_DIR ${source_dir}
+ BINARY_DIR ${build_dir}
+ CONFIGURE_COMMAND ${CMAKE_COMMAND}
+ -P ${build_dir}/config_mingw.cmake
+ BUILD_COMMAND ${CMAKE_COMMAND}
+ -P ${build_dir}/build_mingw.cmake
+ INSTALL_COMMAND ""
+ )
+ # make the external project always run make with each build
+ externalproject_add_step(${project_name}_build forcebuild
+ COMMAND ${CMAKE_COMMAND}
+ -E remove
+ ${CMAKE_CURRENT_BUILD_DIR}/${project_name}-prefix/src/${project_name}-stamp/${project_name}-build
+ DEPENDEES configure
+ DEPENDERS build
+ ALWAYS 1
+ )
+ # create imported targets for all libraries
+ foreach(lib ${libraries})
+ add_library(${lib} SHARED IMPORTED GLOBAL)
+ set_property(TARGET ${lib} APPEND PROPERTY IMPORTED_CONFIGURATIONS NOCONFIG)
+ set_target_properties(${lib} PROPERTIES
+ IMPORTED_IMPLIB_NOCONFIG "${library_dir}/lib${lib}.lib"
+ IMPORTED_LOCATION_NOCONFIG "${binary_dir}/lib${lib}.dll"
+ )
+ add_dependencies(${lib} ${project_name}_build)
+ endforeach()
+
+ # now setup link libraries for targets
+ set(start FALSE)
+ set(target)
+ foreach(lib ${ARGS_LINK_LIBRARIES})
+ if("${lib}" STREQUAL "LINK_LIBS")
+ set(start TRUE)
+ else()
+ if(start)
+ if(DEFINED target)
+ # process current target and target_libs
+ _add_fortran_library_link_interface(${target} "${target_libs}")
+ # zero out target and target_libs
+ set(target)
+ set(target_libs)
+ endif()
+ # save the current target and set start to FALSE
+ set(target ${lib})
+ set(start FALSE)
+ else()
+ # append the lib to target_libs
+ list(APPEND target_libs "${lib}")
+ endif()
+ endif()
+ endforeach()
+ # process anything that is left in target and target_libs
+ if(DEFINED target)
+ _add_fortran_library_link_interface(${target} "${target_libs}")
+ endif()
+endfunction()
diff --git a/Modules/CMakeAddFortranSubdirectory/build_mingw.cmake.in b/Modules/CMakeAddFortranSubdirectory/build_mingw.cmake.in
new file mode 100644
index 000000000..55b271a2d
--- /dev/null
+++ b/Modules/CMakeAddFortranSubdirectory/build_mingw.cmake.in
@@ -0,0 +1,2 @@
+set(ENV{PATH} "@MINGW_PATH@\;$ENV{PATH}")
+execute_process(COMMAND "@CMAKE_COMMAND@" --build . )
diff --git a/Modules/CMakeAddFortranSubdirectory/config_mingw.cmake.in b/Modules/CMakeAddFortranSubdirectory/config_mingw.cmake.in
new file mode 100644
index 000000000..97f67693a
--- /dev/null
+++ b/Modules/CMakeAddFortranSubdirectory/config_mingw.cmake.in
@@ -0,0 +1,9 @@
+set(ENV{PATH} "@MINGW_PATH@\;$ENV{PATH}")
+set(CMAKE_COMMAND_LINE "@ARGS_CMAKE_COMMAND_LINE@")
+execute_process(
+ COMMAND "@CMAKE_COMMAND@" "-GMinGW Makefiles"
+ -DCMAKE_Fortran_COMPILER:PATH=@MINGW_GFORTRAN@
+ -DBUILD_SHARED_LIBS=ON
+ -DCMAKE_GNUtoMS=ON
+ ${CMAKE_COMMAND_LINE}
+ "@source_dir@")
diff --git a/Modules/CMakeAddNewLanguage.txt b/Modules/CMakeAddNewLanguage.txt
new file mode 100644
index 000000000..203c39dfe
--- /dev/null
+++ b/Modules/CMakeAddNewLanguage.txt
@@ -0,0 +1,17 @@
+CMakeDetermine(LANG)Compiler.cmake -> this should find the compiler for LANG and configure CMake(LANG)Compiler.cmake.in
+
+CMake(LANG)Compiler.cmake.in -> used by CMakeDetermine(LANG)Compiler.cmake
+ This file is used to store compiler information and is copied down into try
+ compile directories so that try compiles do not need to re-determine and test the LANG
+
+CMakeTest(LANG)Compiler.cmake -> test the compiler and set:
+ SET(CMAKE_(LANG)_COMPILER_WORKS 1 CACHE INTERNAL "")
+
+CMake(LANG)Information.cmake -> set up rule variables for LANG :
+ CMAKE_(LANG)_CREATE_SHARED_LIBRARY
+ CMAKE_(LANG)_CREATE_SHARED_MODULE
+ CMAKE_(LANG)_CREATE_STATIC_LIBRARY
+ CMAKE_(LANG)_COMPILE_OBJECT
+ CMAKE_(LANG)_LINK_EXECUTABLE
+
+
diff --git a/Modules/CMakeBackwardCompatibilityC.cmake b/Modules/CMakeBackwardCompatibilityC.cmake
new file mode 100644
index 000000000..00e568830
--- /dev/null
+++ b/Modules/CMakeBackwardCompatibilityC.cmake
@@ -0,0 +1,100 @@
+
+#=============================================================================
+# 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.)
+
+# Nothing here yet
+IF(CMAKE_GENERATOR MATCHES "Visual Studio 7")
+ INCLUDE(CMakeVS7BackwardCompatibility)
+ SET(CMAKE_SKIP_COMPATIBILITY_TESTS 1)
+ENDIF(CMAKE_GENERATOR MATCHES "Visual Studio 7")
+IF(CMAKE_GENERATOR MATCHES "Visual Studio 6")
+ INCLUDE(CMakeVS6BackwardCompatibility)
+ SET(CMAKE_SKIP_COMPATIBILITY_TESTS 1)
+ENDIF(CMAKE_GENERATOR MATCHES "Visual Studio 6")
+
+IF(NOT CMAKE_SKIP_COMPATIBILITY_TESTS)
+ # Old CMake versions did not support OS X universal binaries anyway,
+ # so just get through this with at least some size for the types.
+ LIST(LENGTH CMAKE_OSX_ARCHITECTURES NUM_ARCHS)
+ IF(${NUM_ARCHS} GREATER 1)
+ IF(NOT DEFINED CMAKE_TRY_COMPILE_OSX_ARCHITECTURES)
+ MESSAGE(WARNING "This module does not work with OS X universal binaries.")
+ SET(__ERASE_CMAKE_TRY_COMPILE_OSX_ARCHITECTURES 1)
+ LIST(GET CMAKE_OSX_ARCHITECTURES 0 CMAKE_TRY_COMPILE_OSX_ARCHITECTURES)
+ ENDIF()
+ ENDIF()
+
+ INCLUDE (CheckTypeSize)
+ CHECK_TYPE_SIZE(int CMAKE_SIZEOF_INT)
+ CHECK_TYPE_SIZE(long CMAKE_SIZEOF_LONG)
+ CHECK_TYPE_SIZE("void*" CMAKE_SIZEOF_VOID_P)
+ CHECK_TYPE_SIZE(char CMAKE_SIZEOF_CHAR)
+ CHECK_TYPE_SIZE(short CMAKE_SIZEOF_SHORT)
+ CHECK_TYPE_SIZE(float CMAKE_SIZEOF_FLOAT)
+ CHECK_TYPE_SIZE(double CMAKE_SIZEOF_DOUBLE)
+
+ INCLUDE (CheckIncludeFile)
+ CHECK_INCLUDE_FILE("limits.h" CMAKE_HAVE_LIMITS_H)
+ CHECK_INCLUDE_FILE("unistd.h" CMAKE_HAVE_UNISTD_H)
+ CHECK_INCLUDE_FILE("pthread.h" CMAKE_HAVE_PTHREAD_H)
+
+ INCLUDE (CheckIncludeFiles)
+ CHECK_INCLUDE_FILES("sys/types.h;sys/prctl.h" CMAKE_HAVE_SYS_PRCTL_H)
+
+ INCLUDE (TestBigEndian)
+ TEST_BIG_ENDIAN(CMAKE_WORDS_BIGENDIAN)
+ INCLUDE (FindX11)
+
+ IF("${X11_X11_INCLUDE_PATH}" MATCHES "^/usr/include$")
+ SET (CMAKE_X_CFLAGS "" CACHE STRING "X11 extra flags.")
+ ELSE("${X11_X11_INCLUDE_PATH}" MATCHES "^/usr/include$")
+ SET (CMAKE_X_CFLAGS "-I${X11_X11_INCLUDE_PATH}" CACHE STRING
+ "X11 extra flags.")
+ ENDIF("${X11_X11_INCLUDE_PATH}" MATCHES "^/usr/include$")
+ SET (CMAKE_X_LIBS "${X11_LIBRARIES}" CACHE STRING
+ "Libraries and options used in X11 programs.")
+ SET (CMAKE_HAS_X "${X11_FOUND}" CACHE INTERNAL "Is X11 around.")
+
+ INCLUDE (FindThreads)
+
+ SET (CMAKE_THREAD_LIBS "${CMAKE_THREAD_LIBS_INIT}" CACHE STRING
+ "Thread library used.")
+
+ SET (CMAKE_USE_PTHREADS "${CMAKE_USE_PTHREADS_INIT}" CACHE BOOL
+ "Use the pthreads library.")
+
+ SET (CMAKE_USE_WIN32_THREADS "${CMAKE_USE_WIN32_THREADS_INIT}" CACHE BOOL
+ "Use the win32 thread library.")
+
+ SET (CMAKE_HP_PTHREADS ${CMAKE_HP_PTHREADS_INIT} CACHE BOOL
+ "Use HP pthreads.")
+
+ SET (CMAKE_USE_SPROC ${CMAKE_USE_SPROC_INIT} CACHE BOOL
+ "Use sproc libs.")
+
+ IF(__ERASE_CMAKE_TRY_COMPILE_OSX_ARCHITECTURES)
+ SET(CMAKE_TRY_COMPILE_OSX_ARCHITECTURES)
+ SET(__ERASE_CMAKE_TRY_COMPILE_OSX_ARCHITECTURES)
+ ENDIF()
+ENDIF(NOT CMAKE_SKIP_COMPATIBILITY_TESTS)
+
+MARK_AS_ADVANCED(
+CMAKE_HP_PTHREADS
+CMAKE_THREAD_LIBS
+CMAKE_USE_PTHREADS
+CMAKE_USE_SPROC
+CMAKE_USE_WIN32_THREADS
+CMAKE_X_CFLAGS
+CMAKE_X_LIBS
+)
+
diff --git a/Modules/CMakeBackwardCompatibilityCXX.cmake b/Modules/CMakeBackwardCompatibilityCXX.cmake
new file mode 100644
index 000000000..707bbde50
--- /dev/null
+++ b/Modules/CMakeBackwardCompatibilityCXX.cmake
@@ -0,0 +1,54 @@
+# - 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.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software 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(NOT CMAKE_SKIP_COMPATIBILITY_TESTS)
+ # check for some ANSI flags in the CXX compiler if it is not gnu
+ IF(NOT CMAKE_COMPILER_IS_GNUCXX)
+ INCLUDE(TestCXXAcceptsFlag)
+ SET(CMAKE_TRY_ANSI_CXX_FLAGS "")
+ IF(CMAKE_SYSTEM MATCHES "IRIX.*")
+ SET(CMAKE_TRY_ANSI_CXX_FLAGS "-LANG:std")
+ ENDIF(CMAKE_SYSTEM MATCHES "IRIX.*")
+ IF(CMAKE_SYSTEM MATCHES "OSF.*")
+ SET(CMAKE_TRY_ANSI_CXX_FLAGS "-std strict_ansi -nopure_cname")
+ ENDIF(CMAKE_SYSTEM MATCHES "OSF.*")
+ # if CMAKE_TRY_ANSI_CXX_FLAGS has something in it, see
+ # if the compiler accepts it
+ IF( CMAKE_TRY_ANSI_CXX_FLAGS MATCHES ".+")
+ 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
+ IF(CMAKE_CXX_ACCEPTS_FLAGS)
+ SET(CMAKE_ANSI_CXXFLAGS ${CMAKE_TRY_ANSI_CXX_FLAGS} CACHE INTERNAL
+ "What flags are required by the c++ compiler to make it ansi." )
+ ENDIF(CMAKE_CXX_ACCEPTS_FLAGS)
+ ENDIF( CMAKE_TRY_ANSI_CXX_FLAGS MATCHES ".+")
+ ENDIF(NOT CMAKE_COMPILER_IS_GNUCXX)
+ SET(CMAKE_CXX_FLAGS_SAVE ${CMAKE_CXX_FLAGS})
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_ANSI_CXXFLAGS}")
+ INCLUDE(TestForANSIStreamHeaders)
+ INCLUDE(CheckIncludeFileCXX)
+ INCLUDE(TestForSTDNamespace)
+ INCLUDE(TestForANSIForScope)
+ INCLUDE(TestForSSTREAM)
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_SAVE}")
+ENDIF(NOT CMAKE_SKIP_COMPATIBILITY_TESTS)
+
diff --git a/Modules/CMakeBorlandFindMake.cmake b/Modules/CMakeBorlandFindMake.cmake
new file mode 100644
index 000000000..1ef28df83
--- /dev/null
+++ b/Modules/CMakeBorlandFindMake.cmake
@@ -0,0 +1,17 @@
+
+#=============================================================================
+# 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.)
+
+SET (CMAKE_MAKE_PROGRAM "make" CACHE STRING
+ "Program used to build from makefiles.")
+MARK_AS_ADVANCED(CMAKE_MAKE_PROGRAM)
diff --git a/Modules/CMakeBuildSettings.cmake.in b/Modules/CMakeBuildSettings.cmake.in
new file mode 100644
index 000000000..7c4aa148a
--- /dev/null
+++ b/Modules/CMakeBuildSettings.cmake.in
@@ -0,0 +1,13 @@
+
+# The command CMAKE_EXPORT_BUILD_SETTINGS(...) was used by
+# @PROJECT_NAME@ to generate this file. As of CMake 2.8 the
+# functionality of this command has been dropped as it was deemed
+# harmful (confusing users by changing their compiler).
+
+# CMake 2.6 and below do not support loading their equivalent of this
+# file if it was produced by a newer version of CMake. CMake 2.8 and
+# above simply do not load this file. Therefore we simply error out.
+message(FATAL_ERROR
+ "This @PROJECT_NAME@ was built by CMake @CMAKE_VERSION@, but this is CMake "
+ "${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}. "
+ "Please upgrade CMake to a more recent version.")
diff --git a/Modules/CMakeCCompiler.cmake.in b/Modules/CMakeCCompiler.cmake.in
new file mode 100644
index 000000000..ded8cf6ab
--- /dev/null
+++ b/Modules/CMakeCCompiler.cmake.in
@@ -0,0 +1,53 @@
+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_PLATFORM_ID "@CMAKE_C_PLATFORM_ID@")
+@SET_MSVC_C_ARCHITECTURE_ID@
+SET(CMAKE_AR "@CMAKE_AR@")
+SET(CMAKE_RANLIB "@CMAKE_RANLIB@")
+SET(CMAKE_LINKER "@CMAKE_LINKER@")
+SET(CMAKE_COMPILER_IS_GNUCC @CMAKE_COMPILER_IS_GNUCC@)
+SET(CMAKE_C_COMPILER_LOADED 1)
+SET(CMAKE_COMPILER_IS_MINGW @CMAKE_COMPILER_IS_MINGW@)
+SET(CMAKE_COMPILER_IS_CYGWIN @CMAKE_COMPILER_IS_CYGWIN@)
+IF(CMAKE_COMPILER_IS_CYGWIN)
+ SET(CYGWIN 1)
+ SET(UNIX 1)
+ENDIF(CMAKE_COMPILER_IS_CYGWIN)
+
+SET(CMAKE_C_COMPILER_ENV_VAR "CC")
+
+IF(CMAKE_COMPILER_IS_MINGW)
+ SET(MINGW 1)
+ENDIF(CMAKE_COMPILER_IS_MINGW)
+SET(CMAKE_C_COMPILER_ID_RUN 1)
+SET(CMAKE_C_SOURCE_FILE_EXTENSIONS c)
+SET(CMAKE_C_IGNORE_EXTENSIONS h;H;o;O;obj;OBJ;def;DEF;rc;RC)
+SET(CMAKE_C_LINKER_PREFERENCE 10)
+
+# Save compiler ABI information.
+SET(CMAKE_C_SIZEOF_DATA_PTR "@CMAKE_C_SIZEOF_DATA_PTR@")
+SET(CMAKE_C_COMPILER_ABI "@CMAKE_C_COMPILER_ABI@")
+SET(CMAKE_C_LIBRARY_ARCHITECTURE "@CMAKE_C_LIBRARY_ARCHITECTURE@")
+
+IF(CMAKE_C_SIZEOF_DATA_PTR)
+ SET(CMAKE_SIZEOF_VOID_P "${CMAKE_C_SIZEOF_DATA_PTR}")
+ENDIF(CMAKE_C_SIZEOF_DATA_PTR)
+
+IF(CMAKE_C_COMPILER_ABI)
+ SET(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_C_COMPILER_ABI}")
+ENDIF(CMAKE_C_COMPILER_ABI)
+
+IF(CMAKE_C_LIBRARY_ARCHITECTURE)
+ SET(CMAKE_LIBRARY_ARCHITECTURE "@CMAKE_C_LIBRARY_ARCHITECTURE@")
+ENDIF()
+
+SET(CMAKE_C_HAS_ISYSROOT "@CMAKE_C_HAS_ISYSROOT@")
+@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_CMCLDEPS_EXECUTABLE@
+@SET_CMAKE_CL_SHOWINCLUDE_PREFIX@
diff --git a/Modules/CMakeCCompilerABI.c b/Modules/CMakeCCompilerABI.c
new file mode 100644
index 000000000..e6a07f4c4
--- /dev/null
+++ b/Modules/CMakeCCompilerABI.c
@@ -0,0 +1,28 @@
+#ifdef __cplusplus
+# error "A C++ compiler has been selected for C."
+#endif
+
+#ifdef __CLASSIC_C__
+# define const
+#endif
+
+/*--------------------------------------------------------------------------*/
+
+#include "CMakeCompilerABI.h"
+
+/*--------------------------------------------------------------------------*/
+
+#ifdef __CLASSIC_C__
+int main(argc, argv) int argc; char *argv[];
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ int require = 0;
+ require += info_sizeof_dptr[argc];
+#if defined(ABI_ID)
+ require += info_abi[argc];
+#endif
+ (void)argv;
+ return require;
+}
diff --git a/Modules/CMakeCCompilerId.c.in b/Modules/CMakeCCompilerId.c.in
new file mode 100644
index 000000000..06aa9bf06
--- /dev/null
+++ b/Modules/CMakeCCompilerId.c.in
@@ -0,0 +1,204 @@
+#ifdef __cplusplus
+# 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(__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"
+
+#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(__PATHSCALE__)
+# define COMPILER_ID "PathScale"
+
+#elif defined(_CRAYC)
+# define COMPILER_ID "Cray"
+
+#elif defined(__TI_COMPILER_VERSION__)
+# define COMPILER_ID "TI_DSP"
+
+#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
+
+#elif defined(__ADSPBLACKFIN__) || defined(__ADSPTS__) || defined(__ADSP21000__)
+/* Analog Devices C++ compiler for Blackfin, TigerSHARC and
+ SHARC (21000) DSPs */
+# define COMPILER_ID "ADSP"
+
+/* IAR Systems compiler for embedded systems.
+ http://www.iar.com
+ Not supported yet by CMake
+#elif 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"
+
+#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
+
+/* 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 "]";
+
+@CMAKE_C_COMPILER_ID_PLATFORM_CONTENT@
+
+/*--------------------------------------------------------------------------*/
+
+#ifdef ID_VOID_MAIN
+void main() {}
+#else
+int main(int argc, char* argv[])
+{
+ int require = 0;
+ require += info_compiler[argc];
+ require += info_platform[argc];
+ require += info_arch[argc];
+#ifdef COMPILER_VERSION_MAJOR
+ require += info_version[argc];
+#endif
+ (void)argv;
+ return require;
+}
+#endif
diff --git a/Modules/CMakeCInformation.cmake b/Modules/CMakeCInformation.cmake
new file mode 100644
index 000000000..afac7a452
--- /dev/null
+++ b/Modules/CMakeCInformation.cmake
@@ -0,0 +1,219 @@
+
+#=============================================================================
+# Copyright 2004-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.)
+
+# This file sets the basic flags for the C language in CMake.
+# It also loads the available platform file for the system-compiler
+# if it exists.
+# It also loads a system - compiler - processor (or target hardware)
+# specific file, which is mainly useful for crosscompiling and embedded systems.
+
+# 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)
+ SET(CMAKE_C_OUTPUT_EXTENSION .o)
+ELSE(UNIX)
+ SET(CMAKE_C_OUTPUT_EXTENSION .obj)
+ENDIF(UNIX)
+
+SET(_INCLUDED_FILE 0)
+
+# Load compiler-specific information.
+IF(CMAKE_C_COMPILER_ID)
+ INCLUDE(Compiler/${CMAKE_C_COMPILER_ID}-C OPTIONAL)
+ENDIF(CMAKE_C_COMPILER_ID)
+
+SET(CMAKE_BASE_NAME)
+GET_FILENAME_COMPONENT(CMAKE_BASE_NAME ${CMAKE_C_COMPILER} NAME_WE)
+IF(CMAKE_COMPILER_IS_GNUCC)
+ SET(CMAKE_BASE_NAME gcc)
+ENDIF(CMAKE_COMPILER_IS_GNUCC)
+
+
+# load a hardware specific file, mostly useful for embedded compilers
+IF(CMAKE_SYSTEM_PROCESSOR)
+ IF(CMAKE_C_COMPILER_ID)
+ INCLUDE(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_C_COMPILER_ID}-C-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL RESULT_VARIABLE _INCLUDED_FILE)
+ ENDIF(CMAKE_C_COMPILER_ID)
+ IF (NOT _INCLUDED_FILE)
+ INCLUDE(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_BASE_NAME}-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL)
+ ENDIF (NOT _INCLUDED_FILE)
+ENDIF(CMAKE_SYSTEM_PROCESSOR)
+
+
+# load the system- and compiler specific files
+IF(CMAKE_C_COMPILER_ID)
+ INCLUDE(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_C_COMPILER_ID}-C
+ OPTIONAL RESULT_VARIABLE _INCLUDED_FILE)
+ENDIF(CMAKE_C_COMPILER_ID)
+IF (NOT _INCLUDED_FILE)
+ INCLUDE(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_BASE_NAME}
+ OPTIONAL RESULT_VARIABLE _INCLUDED_FILE)
+ENDIF (NOT _INCLUDED_FILE)
+# 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.
+# Remove this when all compiler info is removed from system files.
+IF (NOT _INCLUDED_FILE)
+ INCLUDE(Platform/${CMAKE_SYSTEM_NAME} OPTIONAL)
+ENDIF (NOT _INCLUDED_FILE)
+
+IF(CMAKE_C_SIZEOF_DATA_PTR)
+ FOREACH(f ${CMAKE_C_ABI_FILES})
+ INCLUDE(${f})
+ ENDFOREACH()
+ UNSET(CMAKE_C_ABI_FILES)
+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_C)
+ # Save the full path of the file so try_compile can use it.
+ INCLUDE(${CMAKE_USER_MAKE_RULES_OVERRIDE_C} RESULT_VARIABLE _override)
+ SET(CMAKE_USER_MAKE_RULES_OVERRIDE_C "${_override}")
+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_C_FLAGS ${CMAKE_SHARED_LIBRARY_C_FLAGS})
+ SET(CMAKE_SHARED_MODULE_CREATE_C_FLAGS ${CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS})
+ENDIF(NOT CMAKE_MODULE_EXISTS)
+
+SET(CMAKE_C_FLAGS_INIT "$ENV{CFLAGS} ${CMAKE_C_FLAGS_INIT}")
+# avoid just having a space as the initial value for the cache
+IF(CMAKE_C_FLAGS_INIT STREQUAL " ")
+ SET(CMAKE_C_FLAGS_INIT)
+ENDIF(CMAKE_C_FLAGS_INIT STREQUAL " ")
+SET (CMAKE_C_FLAGS "${CMAKE_C_FLAGS_INIT}" CACHE STRING
+ "Flags used by the compiler during all build types.")
+
+IF(NOT CMAKE_NOT_USING_CONFIG_FLAGS)
+# default build type is none
+ IF(NOT CMAKE_NO_BUILD_TYPE)
+ SET (CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE_INIT} CACHE STRING
+ "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel.")
+ ENDIF(NOT CMAKE_NO_BUILD_TYPE)
+ 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.")
+ 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).")
+ SET (CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO_INIT}" CACHE STRING
+ "Flags used by the compiler during Release with Debug Info builds.")
+ENDIF(NOT CMAKE_NOT_USING_CONFIG_FLAGS)
+
+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.")
+ MARK_AS_ADVANCED(CMAKE_C_STANDARD_LIBRARIES)
+ENDIF(CMAKE_C_STANDARD_LIBRARIES_INIT)
+
+INCLUDE(CMakeCommonLanguageInclude)
+
+# now define the following rule variables
+
+# CMAKE_C_CREATE_SHARED_LIBRARY
+# CMAKE_C_CREATE_SHARED_MODULE
+# CMAKE_C_COMPILE_OBJECT
+# CMAKE_C_LINK_EXECUTABLE
+
+# variables supplied by the generator at use time
+# <TARGET>
+# <TARGET_BASE> the target without the suffix
+# <OBJECTS>
+# <OBJECT>
+# <LINK_LIBRARIES>
+# <FLAGS>
+# <LINK_FLAGS>
+
+# C compiler information
+# <CMAKE_C_COMPILER>
+# <CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS>
+# <CMAKE_SHARED_MODULE_CREATE_C_FLAGS>
+# <CMAKE_C_LINK_FLAGS>
+
+# Static library tools
+# <CMAKE_AR>
+# <CMAKE_RANLIB>
+
+
+# create a C shared library
+IF(NOT CMAKE_C_CREATE_SHARED_LIBRARY)
+ SET(CMAKE_C_CREATE_SHARED_LIBRARY
+ "<CMAKE_C_COMPILER> <CMAKE_SHARED_LIBRARY_C_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>")
+ENDIF(NOT CMAKE_C_CREATE_SHARED_LIBRARY)
+
+# create a C shared module just copy the shared library rule
+IF(NOT CMAKE_C_CREATE_SHARED_MODULE)
+ SET(CMAKE_C_CREATE_SHARED_MODULE ${CMAKE_C_CREATE_SHARED_LIBRARY})
+ENDIF(NOT CMAKE_C_CREATE_SHARED_MODULE)
+
+# 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>")
+ENDIF()
+IF(NOT DEFINED CMAKE_C_ARCHIVE_APPEND)
+ SET(CMAKE_C_ARCHIVE_APPEND "<CMAKE_AR> r <TARGET> <LINK_FLAGS> <OBJECTS>")
+ENDIF()
+IF(NOT DEFINED CMAKE_C_ARCHIVE_FINISH)
+ SET(CMAKE_C_ARCHIVE_FINISH "<CMAKE_RANLIB> <TARGET>")
+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>")
+ENDIF(NOT CMAKE_C_COMPILE_OBJECT)
+
+IF(NOT CMAKE_C_LINK_EXECUTABLE)
+ SET(CMAKE_C_LINK_EXECUTABLE
+ "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
+ENDIF(NOT CMAKE_C_LINK_EXECUTABLE)
+
+IF(NOT CMAKE_EXECUTABLE_RUNTIME_C_FLAG)
+ SET(CMAKE_EXECUTABLE_RUNTIME_C_FLAG ${CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG})
+ENDIF(NOT CMAKE_EXECUTABLE_RUNTIME_C_FLAG)
+
+IF(NOT CMAKE_EXECUTABLE_RUNTIME_C_FLAG_SEP)
+ SET(CMAKE_EXECUTABLE_RUNTIME_C_FLAG_SEP ${CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP})
+ENDIF(NOT CMAKE_EXECUTABLE_RUNTIME_C_FLAG_SEP)
+
+IF(NOT CMAKE_EXECUTABLE_RPATH_LINK_C_FLAG)
+ SET(CMAKE_EXECUTABLE_RPATH_LINK_C_FLAG ${CMAKE_SHARED_LIBRARY_RPATH_LINK_C_FLAG})
+ENDIF(NOT CMAKE_EXECUTABLE_RPATH_LINK_C_FLAG)
+
+MARK_AS_ADVANCED(
+CMAKE_C_FLAGS
+CMAKE_C_FLAGS_DEBUG
+CMAKE_C_FLAGS_MINSIZEREL
+CMAKE_C_FLAGS_RELEASE
+CMAKE_C_FLAGS_RELWITHDEBINFO
+)
+SET(CMAKE_C_INFORMATION_LOADED 1)
+
+
diff --git a/Modules/CMakeCXXCompiler.cmake.in b/Modules/CMakeCXXCompiler.cmake.in
new file mode 100644
index 000000000..5b6376a32
--- /dev/null
+++ b/Modules/CMakeCXXCompiler.cmake.in
@@ -0,0 +1,54 @@
+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_PLATFORM_ID "@CMAKE_CXX_PLATFORM_ID@")
+@SET_MSVC_CXX_ARCHITECTURE_ID@
+SET(CMAKE_AR "@CMAKE_AR@")
+SET(CMAKE_RANLIB "@CMAKE_RANLIB@")
+SET(CMAKE_LINKER "@CMAKE_LINKER@")
+SET(CMAKE_COMPILER_IS_GNUCXX @CMAKE_COMPILER_IS_GNUCXX@)
+SET(CMAKE_CXX_COMPILER_LOADED 1)
+SET(CMAKE_COMPILER_IS_MINGW @CMAKE_COMPILER_IS_MINGW@)
+SET(CMAKE_COMPILER_IS_CYGWIN @CMAKE_COMPILER_IS_CYGWIN@)
+IF(CMAKE_COMPILER_IS_CYGWIN)
+ SET(CYGWIN 1)
+ SET(UNIX 1)
+ENDIF(CMAKE_COMPILER_IS_CYGWIN)
+
+SET(CMAKE_CXX_COMPILER_ENV_VAR "CXX")
+
+IF(CMAKE_COMPILER_IS_MINGW)
+ SET(MINGW 1)
+ENDIF(CMAKE_COMPILER_IS_MINGW)
+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_LINKER_PREFERENCE 30)
+SET(CMAKE_CXX_LINKER_PREFERENCE_PROPAGATES 1)
+
+# Save compiler ABI information.
+SET(CMAKE_CXX_SIZEOF_DATA_PTR "@CMAKE_CXX_SIZEOF_DATA_PTR@")
+SET(CMAKE_CXX_COMPILER_ABI "@CMAKE_CXX_COMPILER_ABI@")
+SET(CMAKE_CXX_LIBRARY_ARCHITECTURE "@CMAKE_CXX_LIBRARY_ARCHITECTURE@")
+
+IF(CMAKE_CXX_SIZEOF_DATA_PTR)
+ SET(CMAKE_SIZEOF_VOID_P "${CMAKE_CXX_SIZEOF_DATA_PTR}")
+ENDIF(CMAKE_CXX_SIZEOF_DATA_PTR)
+
+IF(CMAKE_CXX_COMPILER_ABI)
+ SET(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_CXX_COMPILER_ABI}")
+ENDIF(CMAKE_CXX_COMPILER_ABI)
+
+IF(CMAKE_CXX_LIBRARY_ARCHITECTURE)
+ SET(CMAKE_LIBRARY_ARCHITECTURE "@CMAKE_CXX_LIBRARY_ARCHITECTURE@")
+ENDIF()
+
+SET(CMAKE_CXX_HAS_ISYSROOT "@CMAKE_CXX_HAS_ISYSROOT@")
+@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_CMCLDEPS_EXECUTABLE@
+@SET_CMAKE_CL_SHOWINCLUDE_PREFIX@
diff --git a/Modules/CMakeCXXCompilerABI.cpp b/Modules/CMakeCXXCompilerABI.cpp
new file mode 100644
index 000000000..c9b0440b8
--- /dev/null
+++ b/Modules/CMakeCXXCompilerABI.cpp
@@ -0,0 +1,20 @@
+#ifndef __cplusplus
+# error "A C compiler has been selected for C++."
+#endif
+
+/*--------------------------------------------------------------------------*/
+
+#include "CMakeCompilerABI.h"
+
+/*--------------------------------------------------------------------------*/
+
+int main(int argc, char* argv[])
+{
+ int require = 0;
+ require += info_sizeof_dptr[argc];
+#if defined(ABI_ID)
+ require += info_abi[argc];
+#endif
+ (void)argv;
+ return require;
+}
diff --git a/Modules/CMakeCXXCompilerId.cpp.in b/Modules/CMakeCXXCompilerId.cpp.in
new file mode 100644
index 000000000..95fc852d6
--- /dev/null
+++ b/Modules/CMakeCXXCompilerId.cpp.in
@@ -0,0 +1,187 @@
+/* This source file must have a .cpp extension so that all C++ compilers
+ recognize the extension without flags. Borland does not know .cxx for
+ example. */
+#ifndef __cplusplus
+# 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"
+
+#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(__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"
+
+#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(__PATHSCALE__)
+# define COMPILER_ID "PathScale"
+
+#elif defined(_CRAYC)
+# define COMPILER_ID "Cray"
+
+#elif defined(__TI_COMPILER_VERSION__)
+# define COMPILER_ID "TI_DSP"
+
+#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
+
+#elif defined(__ADSPBLACKFIN__) || defined(__ADSPTS__) || defined(__ADSP21000__)
+/* Analog Devices C++ compiler for Blackfin, TigerSHARC and
+ SHARC (21000) DSPs */
+# define COMPILER_ID "ADSP"
+
+#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
+
+/* 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 "]";
+
+@CMAKE_CXX_COMPILER_ID_PLATFORM_CONTENT@
+
+/*--------------------------------------------------------------------------*/
+
+int main(int argc, char* argv[])
+{
+ int require = 0;
+ require += info_compiler[argc];
+ require += info_platform[argc];
+#ifdef COMPILER_VERSION_MAJOR
+ require += info_version[argc];
+#endif
+ (void)argv;
+ return require;
+}
diff --git a/Modules/CMakeCXXInformation.cmake b/Modules/CMakeCXXInformation.cmake
new file mode 100644
index 000000000..9dc9cbd30
--- /dev/null
+++ b/Modules/CMakeCXXInformation.cmake
@@ -0,0 +1,299 @@
+
+#=============================================================================
+# Copyright 2004-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.)
+
+# This file sets the basic flags for the C++ language in CMake.
+# It also loads the available platform file for the system-compiler
+# if it exists.
+# It also loads a system - compiler - processor (or target hardware)
+# specific file, which is mainly useful for crosscompiling and embedded systems.
+
+# 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)
+ SET(CMAKE_CXX_OUTPUT_EXTENSION .o)
+ELSE(UNIX)
+ SET(CMAKE_CXX_OUTPUT_EXTENSION .obj)
+ENDIF(UNIX)
+
+SET(_INCLUDED_FILE 0)
+
+# Load compiler-specific information.
+IF(CMAKE_CXX_COMPILER_ID)
+ INCLUDE(Compiler/${CMAKE_CXX_COMPILER_ID}-CXX OPTIONAL)
+ENDIF(CMAKE_CXX_COMPILER_ID)
+
+SET(CMAKE_BASE_NAME)
+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++)
+ENDIF(CMAKE_COMPILER_IS_GNUCXX)
+
+
+# load a hardware specific file, mostly useful for embedded compilers
+IF(CMAKE_SYSTEM_PROCESSOR)
+ IF(CMAKE_CXX_COMPILER_ID)
+ INCLUDE(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_CXX_COMPILER_ID}-CXX-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL RESULT_VARIABLE _INCLUDED_FILE)
+ ENDIF(CMAKE_CXX_COMPILER_ID)
+ IF (NOT _INCLUDED_FILE)
+ INCLUDE(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_BASE_NAME}-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL)
+ ENDIF (NOT _INCLUDED_FILE)
+ENDIF(CMAKE_SYSTEM_PROCESSOR)
+
+# load the system- and compiler specific files
+IF(CMAKE_CXX_COMPILER_ID)
+ INCLUDE(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_CXX_COMPILER_ID}-CXX OPTIONAL RESULT_VARIABLE _INCLUDED_FILE)
+ENDIF(CMAKE_CXX_COMPILER_ID)
+IF (NOT _INCLUDED_FILE)
+ INCLUDE(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_BASE_NAME} OPTIONAL
+ RESULT_VARIABLE _INCLUDED_FILE)
+ENDIF (NOT _INCLUDED_FILE)
+# 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.
+# Remove this when all compiler info is removed from system files.
+IF (NOT _INCLUDED_FILE)
+ INCLUDE(Platform/${CMAKE_SYSTEM_NAME} OPTIONAL)
+ENDIF (NOT _INCLUDED_FILE)
+
+IF(CMAKE_CXX_SIZEOF_DATA_PTR)
+ FOREACH(f ${CMAKE_CXX_ABI_FILES})
+ INCLUDE(${f})
+ ENDFOREACH()
+ UNSET(CMAKE_CXX_ABI_FILES)
+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_CXX)
+ # Save the full path of the file so try_compile can use it.
+ INCLUDE(${CMAKE_USER_MAKE_RULES_OVERRIDE_CXX} RESULT_VARIABLE _override)
+ SET(CMAKE_USER_MAKE_RULES_OVERRIDE_CXX "${_override}")
+ENDIF()
+
+
+# Create a set of shared library variable specific to C++
+# For 90% of the systems, these are the same flags as the C versions
+# so if these are not set just copy the flags from the c version
+IF(NOT CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS)
+ SET(CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS ${CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS})
+ENDIF(NOT CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS)
+
+IF(NOT CMAKE_CXX_COMPILE_OPTIONS_PIC)
+ SET(CMAKE_CXX_COMPILE_OPTIONS_PIC ${CMAKE_C_COMPILE_OPTIONS_PIC})
+ENDIF(NOT CMAKE_CXX_COMPILE_OPTIONS_PIC)
+
+IF(NOT CMAKE_CXX_COMPILE_OPTIONS_PIE)
+ SET(CMAKE_CXX_COMPILE_OPTIONS_PIE ${CMAKE_C_COMPILE_OPTIONS_PIE})
+ENDIF(NOT CMAKE_CXX_COMPILE_OPTIONS_PIE)
+
+IF(NOT CMAKE_CXX_COMPILE_OPTIONS_DLL)
+ SET(CMAKE_CXX_COMPILE_OPTIONS_DLL ${CMAKE_C_COMPILE_OPTIONS_DLL})
+ENDIF(NOT CMAKE_CXX_COMPILE_OPTIONS_DLL)
+
+IF(NOT CMAKE_SHARED_LIBRARY_CXX_FLAGS)
+ SET(CMAKE_SHARED_LIBRARY_CXX_FLAGS ${CMAKE_SHARED_LIBRARY_C_FLAGS})
+ENDIF(NOT CMAKE_SHARED_LIBRARY_CXX_FLAGS)
+
+IF(NOT DEFINED CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS)
+ SET(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS ${CMAKE_SHARED_LIBRARY_LINK_C_FLAGS})
+ENDIF(NOT DEFINED CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS)
+
+IF(NOT CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG)
+ SET(CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG ${CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG})
+ENDIF(NOT CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG)
+
+IF(NOT CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG_SEP)
+ SET(CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG_SEP ${CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP})
+ENDIF(NOT CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG_SEP)
+
+IF(NOT CMAKE_SHARED_LIBRARY_RPATH_LINK_CXX_FLAG)
+ SET(CMAKE_SHARED_LIBRARY_RPATH_LINK_CXX_FLAG ${CMAKE_SHARED_LIBRARY_RPATH_LINK_C_FLAG})
+ENDIF(NOT CMAKE_SHARED_LIBRARY_RPATH_LINK_CXX_FLAG)
+
+IF(NOT DEFINED CMAKE_EXE_EXPORTS_CXX_FLAG)
+ SET(CMAKE_EXE_EXPORTS_CXX_FLAG ${CMAKE_EXE_EXPORTS_C_FLAG})
+ENDIF()
+
+IF(NOT DEFINED CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG)
+ SET(CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG ${CMAKE_SHARED_LIBRARY_SONAME_C_FLAG})
+ENDIF()
+
+IF(NOT CMAKE_EXECUTABLE_RUNTIME_CXX_FLAG)
+ SET(CMAKE_EXECUTABLE_RUNTIME_CXX_FLAG ${CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG})
+ENDIF(NOT CMAKE_EXECUTABLE_RUNTIME_CXX_FLAG)
+
+IF(NOT CMAKE_EXECUTABLE_RUNTIME_CXX_FLAG_SEP)
+ SET(CMAKE_EXECUTABLE_RUNTIME_CXX_FLAG_SEP ${CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG_SEP})
+ENDIF(NOT CMAKE_EXECUTABLE_RUNTIME_CXX_FLAG_SEP)
+
+IF(NOT CMAKE_EXECUTABLE_RPATH_LINK_CXX_FLAG)
+ SET(CMAKE_EXECUTABLE_RPATH_LINK_CXX_FLAG ${CMAKE_SHARED_LIBRARY_RPATH_LINK_CXX_FLAG})
+ENDIF(NOT CMAKE_EXECUTABLE_RPATH_LINK_CXX_FLAG)
+
+IF(NOT DEFINED CMAKE_SHARED_LIBRARY_LINK_CXX_WITH_RUNTIME_PATH)
+ SET(CMAKE_SHARED_LIBRARY_LINK_CXX_WITH_RUNTIME_PATH ${CMAKE_SHARED_LIBRARY_LINK_C_WITH_RUNTIME_PATH})
+ENDIF(NOT DEFINED CMAKE_SHARED_LIBRARY_LINK_CXX_WITH_RUNTIME_PATH)
+
+IF(NOT CMAKE_INCLUDE_FLAG_CXX)
+ SET(CMAKE_INCLUDE_FLAG_CXX ${CMAKE_INCLUDE_FLAG_C})
+ENDIF(NOT CMAKE_INCLUDE_FLAG_CXX)
+
+IF(NOT CMAKE_INCLUDE_FLAG_SEP_CXX)
+ SET(CMAKE_INCLUDE_FLAG_SEP_CXX ${CMAKE_INCLUDE_FLAG_SEP_C})
+ENDIF(NOT CMAKE_INCLUDE_FLAG_SEP_CXX)
+
+# 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_CXX_FLAGS ${CMAKE_SHARED_LIBRARY_CXX_FLAGS})
+ SET(CMAKE_SHARED_MODULE_CREATE_CXX_FLAGS ${CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS})
+ENDIF(NOT CMAKE_MODULE_EXISTS)
+
+# repeat for modules
+IF(NOT CMAKE_SHARED_MODULE_CREATE_CXX_FLAGS)
+ SET(CMAKE_SHARED_MODULE_CREATE_CXX_FLAGS ${CMAKE_SHARED_MODULE_CREATE_C_FLAGS})
+ENDIF(NOT CMAKE_SHARED_MODULE_CREATE_CXX_FLAGS)
+
+IF(NOT CMAKE_SHARED_MODULE_CXX_FLAGS)
+ SET(CMAKE_SHARED_MODULE_CXX_FLAGS ${CMAKE_SHARED_MODULE_C_FLAGS})
+ENDIF(NOT CMAKE_SHARED_MODULE_CXX_FLAGS)
+
+# Initialize CXX link type selection flags from C versions.
+FOREACH(type SHARED_LIBRARY SHARED_MODULE EXE)
+ IF(NOT CMAKE_${type}_LINK_STATIC_CXX_FLAGS)
+ SET(CMAKE_${type}_LINK_STATIC_CXX_FLAGS
+ ${CMAKE_${type}_LINK_STATIC_C_FLAGS})
+ ENDIF(NOT CMAKE_${type}_LINK_STATIC_CXX_FLAGS)
+ IF(NOT CMAKE_${type}_LINK_DYNAMIC_CXX_FLAGS)
+ SET(CMAKE_${type}_LINK_DYNAMIC_CXX_FLAGS
+ ${CMAKE_${type}_LINK_DYNAMIC_C_FLAGS})
+ ENDIF(NOT CMAKE_${type}_LINK_DYNAMIC_CXX_FLAGS)
+ENDFOREACH(type)
+
+# add the flags to the cache based
+# on the initial values computed in the platform/*.cmake files
+# use _INIT variables so that this only happens the first time
+# and you can set these flags in the cmake cache
+SET(CMAKE_CXX_FLAGS_INIT "$ENV{CXXFLAGS} ${CMAKE_CXX_FLAGS_INIT}")
+# avoid just having a space as the initial value for the cache
+IF(CMAKE_CXX_FLAGS_INIT STREQUAL " ")
+ SET(CMAKE_CXX_FLAGS_INIT)
+ENDIF(CMAKE_CXX_FLAGS_INIT STREQUAL " ")
+SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_INIT}" CACHE STRING
+ "Flags used by the compiler during all build types.")
+
+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.")
+ 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).")
+ SET (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT}" CACHE STRING
+ "Flags used by the compiler during Release with Debug Info builds.")
+
+ENDIF(NOT CMAKE_NOT_USING_CONFIG_FLAGS)
+
+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.")
+ MARK_AS_ADVANCED(CMAKE_CXX_STANDARD_LIBRARIES)
+ENDIF(CMAKE_CXX_STANDARD_LIBRARIES_INIT)
+
+INCLUDE(CMakeCommonLanguageInclude)
+
+# now define the following rules:
+# CMAKE_CXX_CREATE_SHARED_LIBRARY
+# CMAKE_CXX_CREATE_SHARED_MODULE
+# CMAKE_CXX_COMPILE_OBJECT
+# CMAKE_CXX_LINK_EXECUTABLE
+
+# variables supplied by the generator at use time
+# <TARGET>
+# <TARGET_BASE> the target without the suffix
+# <OBJECTS>
+# <OBJECT>
+# <LINK_LIBRARIES>
+# <FLAGS>
+# <LINK_FLAGS>
+
+# CXX compiler information
+# <CMAKE_CXX_COMPILER>
+# <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS>
+# <CMAKE_CXX_SHARED_MODULE_CREATE_FLAGS>
+# <CMAKE_CXX_LINK_FLAGS>
+
+# Static library tools
+# <CMAKE_AR>
+# <CMAKE_RANLIB>
+
+
+# create a shared C++ library
+IF(NOT CMAKE_CXX_CREATE_SHARED_LIBRARY)
+ SET(CMAKE_CXX_CREATE_SHARED_LIBRARY
+ "<CMAKE_CXX_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>")
+ENDIF(NOT CMAKE_CXX_CREATE_SHARED_LIBRARY)
+
+# create a c++ shared module copy the shared library rule by default
+IF(NOT CMAKE_CXX_CREATE_SHARED_MODULE)
+ SET(CMAKE_CXX_CREATE_SHARED_MODULE ${CMAKE_CXX_CREATE_SHARED_LIBRARY})
+ENDIF(NOT CMAKE_CXX_CREATE_SHARED_MODULE)
+
+
+# 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>")
+ENDIF()
+IF(NOT DEFINED CMAKE_CXX_ARCHIVE_APPEND)
+ SET(CMAKE_CXX_ARCHIVE_APPEND "<CMAKE_AR> r <TARGET> <LINK_FLAGS> <OBJECTS>")
+ENDIF()
+IF(NOT DEFINED CMAKE_CXX_ARCHIVE_FINISH)
+ SET(CMAKE_CXX_ARCHIVE_FINISH "<CMAKE_RANLIB> <TARGET>")
+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>")
+ENDIF(NOT CMAKE_CXX_COMPILE_OBJECT)
+
+IF(NOT CMAKE_CXX_LINK_EXECUTABLE)
+ SET(CMAKE_CXX_LINK_EXECUTABLE
+ "<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
+ENDIF(NOT CMAKE_CXX_LINK_EXECUTABLE)
+
+MARK_AS_ADVANCED(
+CMAKE_BUILD_TOOL
+CMAKE_VERBOSE_MAKEFILE
+CMAKE_CXX_FLAGS
+CMAKE_CXX_FLAGS_RELEASE
+CMAKE_CXX_FLAGS_RELWITHDEBINFO
+CMAKE_CXX_FLAGS_MINSIZEREL
+CMAKE_CXX_FLAGS_DEBUG)
+
+SET(CMAKE_CXX_INFORMATION_LOADED 1)
+
diff --git a/Modules/CMakeClDeps.cmake b/Modules/CMakeClDeps.cmake
new file mode 100644
index 000000000..6815e2b75
--- /dev/null
+++ b/Modules/CMakeClDeps.cmake
@@ -0,0 +1,37 @@
+
+#=============================================================================
+# 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 showOut)
+ STRING(REPLACE main.c "" showOut1 ${showOut})
+ STRING(REPLACE "/" "\\" header1 ${showdir}/foo.h)
+ STRING(TOLOWER ${header1} header2)
+ STRING(REPLACE ${header2} "" showOut2 ${showOut1})
+ STRING(REPLACE "\n" "" showOut3 ${showOut2})
+ SET(SET_CMAKE_CMCLDEPS_EXECUTABLE "SET(CMAKE_CMCLDEPS_EXECUTABLE \"${CMAKE_CMCLDEPS_EXECUTABLE}\")")
+ SET(SET_CMAKE_CL_SHOWINCLUDE_PREFIX "SET(CMAKE_CL_SHOWINCLUDE_PREFIX \"${showOut3}\")")
+ENDIF()
diff --git a/Modules/CMakeCommonLanguageInclude.cmake b/Modules/CMakeCommonLanguageInclude.cmake
new file mode 100644
index 000000000..a2929f1ea
--- /dev/null
+++ b/Modules/CMakeCommonLanguageInclude.cmake
@@ -0,0 +1,107 @@
+
+#=============================================================================
+# 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.)
+
+# this file has flags that are shared across languages and sets
+# 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 CMAKE_NOT_USING_CONFIG_FLAGS)
+# default build type is none
+ IF(NOT CMAKE_NO_BUILD_TYPE)
+ SET (CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE_INIT} CACHE STRING
+ "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel.")
+ ENDIF(NOT CMAKE_NO_BUILD_TYPE)
+
+ SET (CMAKE_EXE_LINKER_FLAGS_DEBUG ${CMAKE_EXE_LINKER_FLAGS_DEBUG_INIT} CACHE STRING
+ "Flags used by the linker during debug builds.")
+
+ SET (CMAKE_EXE_LINKER_FLAGS_MINSIZEREL ${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL_INIT} CACHE STRING
+ "Flags used by the linker during release minsize builds.")
+
+ SET (CMAKE_EXE_LINKER_FLAGS_RELEASE ${CMAKE_EXE_LINKER_FLAGS_RELEASE_INIT} CACHE STRING
+ "Flags used by the linker during release builds.")
+
+ SET (CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO
+ ${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO_INIT} CACHE STRING
+ "Flags used by the linker during Release with Debug Info builds.")
+
+ SET (CMAKE_SHARED_LINKER_FLAGS_DEBUG ${CMAKE_SHARED_LINKER_FLAGS_DEBUG_INIT} CACHE STRING
+ "Flags used by the linker during debug builds.")
+
+ SET (CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL ${CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL_INIT}
+ CACHE STRING
+ "Flags used by the linker during release minsize builds.")
+
+ SET (CMAKE_SHARED_LINKER_FLAGS_RELEASE ${CMAKE_SHARED_LINKER_FLAGS_RELEASE_INIT} CACHE STRING
+ "Flags used by the linker during release builds.")
+
+ SET (CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO
+ ${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO_INIT} CACHE STRING
+ "Flags used by the linker during Release with Debug Info builds.")
+
+ SET (CMAKE_MODULE_LINKER_FLAGS_DEBUG ${CMAKE_MODULE_LINKER_FLAGS_DEBUG_INIT} CACHE STRING
+ "Flags used by the linker during debug builds.")
+
+ SET (CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL ${CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL_INIT}
+ CACHE STRING
+ "Flags used by the linker during release minsize builds.")
+
+ SET (CMAKE_MODULE_LINKER_FLAGS_RELEASE ${CMAKE_MODULE_LINKER_FLAGS_RELEASE_INIT} CACHE STRING
+ "Flags used by the linker during release builds.")
+
+ SET (CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO
+ ${CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO_INIT} CACHE STRING
+ "Flags used by the linker during Release with Debug Info builds.")
+
+ENDIF(NOT CMAKE_NOT_USING_CONFIG_FLAGS)
+# shared linker flags
+SET (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS_INIT} $ENV{LDFLAGS}"
+ 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}"
+ CACHE STRING "Flags used by the linker during the creation of modules.")
+
+SET(CMAKE_BUILD_TOOL ${CMAKE_MAKE_PROGRAM} CACHE INTERNAL
+ "What is the target build tool cmake is generating for.")
+
+
+MARK_AS_ADVANCED(
+CMAKE_BUILD_TOOL
+CMAKE_VERBOSE_MAKEFILE
+
+CMAKE_EXE_LINKER_FLAGS
+CMAKE_EXE_LINKER_FLAGS_DEBUG
+CMAKE_EXE_LINKER_FLAGS_MINSIZEREL
+CMAKE_EXE_LINKER_FLAGS_RELEASE
+CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO
+
+CMAKE_SHARED_LINKER_FLAGS
+CMAKE_SHARED_LINKER_FLAGS_DEBUG
+CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL
+CMAKE_SHARED_LINKER_FLAGS_RELEASE
+CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO
+
+CMAKE_MODULE_LINKER_FLAGS
+CMAKE_MODULE_LINKER_FLAGS_DEBUG
+CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL
+CMAKE_MODULE_LINKER_FLAGS_RELEASE
+CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO
+
+)
+
diff --git a/Modules/CMakeCompilerABI.h b/Modules/CMakeCompilerABI.h
new file mode 100644
index 000000000..26ae4db6a
--- /dev/null
+++ b/Modules/CMakeCompilerABI.h
@@ -0,0 +1,36 @@
+/*--------------------------------------------------------------------------*/
+
+/* Size of a pointer-to-data in bytes. */
+#define SIZEOF_DPTR (sizeof(void*))
+const char info_sizeof_dptr[] = {
+ 'I', 'N', 'F', 'O', ':', 's', 'i', 'z', 'e', 'o', 'f', '_', 'd', 'p', 't', 'r', '[',
+ ('0' + ((SIZEOF_DPTR / 10)%10)),
+ ('0' + (SIZEOF_DPTR % 10)),
+ ']','\0'};
+
+/*--------------------------------------------------------------------------*/
+
+/* Application Binary Interface. */
+#if defined(__sgi) && defined(_ABIO32)
+# define ABI_ID "ELF O32"
+#elif defined(__sgi) && defined(_ABIN32)
+# define ABI_ID "ELF N32"
+#elif defined(__sgi) && defined(_ABI64)
+# define ABI_ID "ELF 64"
+
+/* Check for (some) ARM ABIs.
+ * See e.g. http://wiki.debian.org/ArmEabiPort for some information on this. */
+#elif defined(__GNU__) && defined(__ELF__) && defined(__ARM_EABI__)
+# define ABI_ID "ELF ARMEABI"
+#elif defined(__GNU__) && defined(__ELF__) && defined(__ARMEB__)
+# define ABI_ID "ELF ARM"
+#elif defined(__GNU__) && defined(__ELF__) && defined(__ARMEL__)
+# define ABI_ID "ELF ARM"
+
+#elif defined(__ELF__)
+# define ABI_ID "ELF"
+#endif
+
+#if defined(ABI_ID)
+static char const info_abi[] = "INFO:abi[" ABI_ID "]";
+#endif
diff --git a/Modules/CMakeConfigurableFile.in b/Modules/CMakeConfigurableFile.in
new file mode 100644
index 000000000..4cf74a12b
--- /dev/null
+++ b/Modules/CMakeConfigurableFile.in
@@ -0,0 +1,2 @@
+@CMAKE_CONFIGURABLE_FILE_CONTENT@
+
diff --git a/Modules/CMakeDependentOption.cmake b/Modules/CMakeDependentOption.cmake
new file mode 100644
index 000000000..8b8dc07fb
--- /dev/null
+++ b/Modules/CMakeDependentOption.cmake
@@ -0,0 +1,51 @@
+# - 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
+# retains its old value.
+
+#=============================================================================
+# Copyright 2006-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(CMAKE_DEPENDENT_OPTION option doc default depends force)
+ IF(${option}_ISSET MATCHES "^${option}_ISSET$")
+ SET(${option}_AVAILABLE 1)
+ FOREACH(d ${depends})
+ STRING(REGEX REPLACE " +" ";" CMAKE_DEPENDENT_OPTION_DEP "${d}")
+ IF(${CMAKE_DEPENDENT_OPTION_DEP})
+ ELSE(${CMAKE_DEPENDENT_OPTION_DEP})
+ SET(${option}_AVAILABLE 0)
+ ENDIF(${CMAKE_DEPENDENT_OPTION_DEP})
+ ENDFOREACH(d)
+ IF(${option}_AVAILABLE)
+ OPTION(${option} "${doc}" "${default}")
+ SET(${option} "${${option}}" CACHE BOOL "${doc}" FORCE)
+ ELSE(${option}_AVAILABLE)
+ IF(${option} MATCHES "^${option}$")
+ ELSE(${option} MATCHES "^${option}$")
+ SET(${option} "${${option}}" CACHE INTERNAL "${doc}")
+ ENDIF(${option} MATCHES "^${option}$")
+ SET(${option} ${force})
+ ENDIF(${option}_AVAILABLE)
+ ELSE(${option}_ISSET MATCHES "^${option}_ISSET$")
+ SET(${option} "${${option}_ISSET}")
+ ENDIF(${option}_ISSET MATCHES "^${option}_ISSET$")
+ENDMACRO(CMAKE_DEPENDENT_OPTION)
diff --git a/Modules/CMakeDetermineASM-ATTCompiler.cmake b/Modules/CMakeDetermineASM-ATTCompiler.cmake
new file mode 100644
index 000000000..9dd2f11de
--- /dev/null
+++ b/Modules/CMakeDetermineASM-ATTCompiler.cmake
@@ -0,0 +1,20 @@
+
+#=============================================================================
+# 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.)
+
+# determine the compiler to use for ASM using AT&T syntax, e.g. GNU as
+
+SET(ASM_DIALECT "-ATT")
+SET(CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT ${_CMAKE_TOOLCHAIN_PREFIX}gas ${_CMAKE_TOOLCHAIN_PREFIX}as)
+INCLUDE(CMakeDetermineASMCompiler)
+SET(ASM_DIALECT)
diff --git a/Modules/CMakeDetermineASMCompiler.cmake b/Modules/CMakeDetermineASMCompiler.cmake
new file mode 100644
index 000000000..0a70d0a82
--- /dev/null
+++ b/Modules/CMakeDetermineASMCompiler.cmake
@@ -0,0 +1,182 @@
+
+#=============================================================================
+# 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.)
+
+# determine the compiler to use for ASM programs
+
+IF(NOT CMAKE_ASM${ASM_DIALECT}_COMPILER)
+ # prefer the environment variable ASM
+ IF($ENV{ASM${ASM_DIALECT}} MATCHES ".+")
+ SET(CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT "$ENV{ASM${ASM_DIALECT}}")
+ ENDIF($ENV{ASM${ASM_DIALECT}} MATCHES ".+")
+
+ # finally list compilers to try
+ IF("ASM${ASM_DIALECT}" STREQUAL "ASM") # the generic assembler support
+
+ IF(CMAKE_ASM_COMPILER_INIT)
+ SET(CMAKE_ASM_COMPILER_LIST ${CMAKE_ASM_COMPILER_INIT})
+ ELSE(CMAKE_ASM_COMPILER_INIT)
+
+ IF(CMAKE_C_COMPILER)
+ SET(CMAKE_ASM_COMPILER "${CMAKE_C_COMPILER}" CACHE FILEPATH "The ASM compiler")
+ SET(CMAKE_ASM_COMPILER_ID "${CMAKE_C_COMPILER_ID}")
+ ELSEIF(CMAKE_CXX_COMPILER)
+ SET(CMAKE_ASM_COMPILER "${CMAKE_CXX_COMPILER}" CACHE FILEPATH "The ASM compiler")
+ SET(CMAKE_ASM_COMPILER_ID "${CMAKE_CXX_COMPILER_ID}")
+ ELSE(CMAKE_CXX_COMPILER)
+ # List all default C and CXX compilers
+ SET(CMAKE_ASM${ASM_DIALECT}_COMPILER_LIST ${_CMAKE_TOOLCHAIN_PREFIX}gcc ${_CMAKE_TOOLCHAIN_PREFIX}cc cl bcc xlc
+ ${_CMAKE_TOOLCHAIN_PREFIX}c++ ${_CMAKE_TOOLCHAIN_PREFIX}g++ CC aCC cl bcc xlC)
+ ENDIF(CMAKE_C_COMPILER)
+
+ ENDIF(CMAKE_ASM_COMPILER_INIT)
+
+
+ ELSE("ASM${ASM_DIALECT}" STREQUAL "ASM") # some specific assembler "dialect"
+
+ IF(CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT)
+ SET(CMAKE_ASM${ASM_DIALECT}_COMPILER_LIST ${CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT})
+ ELSE(CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT)
+ MESSAGE(FATAL_ERROR "CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT must be preset !")
+ ENDIF(CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT)
+
+ ENDIF("ASM${ASM_DIALECT}" STREQUAL "ASM")
+
+
+ # Find the compiler.
+ IF (_CMAKE_USER_CXX_COMPILER_PATH OR _CMAKE_USER_C_COMPILER_PATH)
+ FIND_PROGRAM(CMAKE_ASM${ASM_DIALECT}_COMPILER NAMES ${CMAKE_ASM${ASM_DIALECT}_COMPILER_LIST} PATHS ${_CMAKE_USER_C_COMPILER_PATH} ${_CMAKE_USER_CXX_COMPILER_PATH} DOC "Assembler" NO_DEFAULT_PATH)
+ ENDIF (_CMAKE_USER_CXX_COMPILER_PATH OR _CMAKE_USER_C_COMPILER_PATH)
+ FIND_PROGRAM(CMAKE_ASM${ASM_DIALECT}_COMPILER NAMES ${CMAKE_ASM${ASM_DIALECT}_COMPILER_LIST} PATHS ${_CMAKE_TOOLCHAIN_LOCATION} DOC "Assembler")
+
+ELSE(NOT CMAKE_ASM${ASM_DIALECT}_COMPILER)
+
+ # 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(CMAKE_ASM${ASM_DIALECT}_COMPILER_WITH_PATH)
+ ENDIF(NOT _CMAKE_USER_ASM${ASM_DIALECT}_COMPILER_PATH)
+ENDIF(NOT CMAKE_ASM${ASM_DIALECT}_COMPILER)
+MARK_AS_ADVANCED(CMAKE_ASM${ASM_DIALECT}_COMPILER)
+
+IF (NOT _CMAKE_TOOLCHAIN_LOCATION)
+ GET_FILENAME_COMPONENT(_CMAKE_TOOLCHAIN_LOCATION "${CMAKE_ASM${ASM_DIALECT}_COMPILER}" PATH)
+ENDIF (NOT _CMAKE_TOOLCHAIN_LOCATION)
+
+
+IF(NOT CMAKE_ASM${ASM_DIALECT}_COMPILER_ID)
+
+ # Table of per-vendor compiler id flags with expected output.
+ LIST(APPEND CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDORS GNU )
+ SET(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_FLAGS_GNU "--version")
+ SET(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_REGEX_GNU "(GNU assembler)|(GCC)|(Free Software Foundation)")
+
+ LIST(APPEND CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDORS HP )
+ SET(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_FLAGS_HP "-V")
+ SET(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_REGEX_HP "HP C")
+
+ LIST(APPEND CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDORS Intel )
+ SET(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_FLAGS_Intel "--version")
+ SET(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_REGEX_Intel "(ICC)")
+
+ LIST(APPEND CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDORS SunPro )
+ SET(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_FLAGS_SunPro "-V")
+ SET(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_REGEX_SunPro "Sun C")
+
+ LIST(APPEND CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDORS XL )
+ SET(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_FLAGS_XL "-qversion")
+ SET(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_REGEX_XL "XL C")
+
+ LIST(APPEND CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDORS MSVC )
+ SET(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_FLAGS_MSVC "/?")
+ SET(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_REGEX_MSVC "Microsoft")
+
+ LIST(APPEND CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDORS TI_DSP )
+ SET(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_FLAGS_TI_DSP "-h")
+ SET(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_REGEX_TI_DSP "Texas Instruments")
+
+ INCLUDE(CMakeDetermineCompilerId)
+ CMAKE_DETERMINE_COMPILER_ID_VENDOR(ASM${ASM_DIALECT})
+
+ENDIF()
+
+IF(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID)
+ MESSAGE(STATUS "The ASM${ASM_DIALECT} compiler identification is ${CMAKE_ASM${ASM_DIALECT}_COMPILER_ID}")
+ELSE(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID)
+ MESSAGE(STATUS "The ASM${ASM_DIALECT} compiler identification is unknown")
+ENDIF(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID)
+
+
+
+# If we have a gas/as cross compiler, they have usually some prefix, like
+# 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
+# "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)
+ GET_FILENAME_COMPONENT(COMPILER_BASENAME "${CMAKE_ASM${ASM_DIALECT}_COMPILER}" NAME)
+ IF (COMPILER_BASENAME MATCHES "^(.+-)g?as(-[0-9]+\\.[0-9]+\\.[0-9]+)?(\\.exe)?$")
+ SET(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
+ ENDIF (COMPILER_BASENAME MATCHES "^(.+-)g?as(-[0-9]+\\.[0-9]+\\.[0-9]+)?(\\.exe)?$")
+ENDIF (NOT _CMAKE_TOOLCHAIN_PREFIX)
+
+# Now try the C compiler regexp:
+IF (NOT _CMAKE_TOOLCHAIN_PREFIX)
+ IF (COMPILER_BASENAME MATCHES "^(.+-)g?cc(-[0-9]+\\.[0-9]+\\.[0-9]+)?(\\.exe)?$")
+ SET(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
+ ENDIF (COMPILER_BASENAME MATCHES "^(.+-)g?cc(-[0-9]+\\.[0-9]+\\.[0-9]+)?(\\.exe)?$")
+ENDIF (NOT _CMAKE_TOOLCHAIN_PREFIX)
+
+# Finally try the CXX compiler regexp:
+IF (NOT _CMAKE_TOOLCHAIN_PREFIX)
+ IF (COMPILER_BASENAME MATCHES "^(.+-)[gc]\\+\\+(-[0-9]+\\.[0-9]+\\.[0-9]+)?(\\.exe)?$")
+ SET(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
+ ENDIF (COMPILER_BASENAME MATCHES "^(.+-)[gc]\\+\\+(-[0-9]+\\.[0-9]+\\.[0-9]+)?(\\.exe)?$")
+ENDIF (NOT _CMAKE_TOOLCHAIN_PREFIX)
+
+
+INCLUDE(CMakeFindBinUtils)
+
+SET(CMAKE_ASM${ASM_DIALECT}_COMPILER_ENV_VAR "ASM${ASM_DIALECT}")
+
+IF(CMAKE_ASM${ASM_DIALECT}_COMPILER)
+ MESSAGE(STATUS "Found assembler: ${CMAKE_ASM${ASM_DIALECT}_COMPILER}")
+ELSE(CMAKE_ASM${ASM_DIALECT}_COMPILER)
+ MESSAGE(STATUS "Didn't find assembler")
+ENDIF(CMAKE_ASM${ASM_DIALECT}_COMPILER)
+
+
+SET(_CMAKE_ASM_COMPILER "${CMAKE_ASM${ASM_DIALECT}_COMPILER}")
+SET(_CMAKE_ASM_COMPILER_ID "${CMAKE_ASM${ASM_DIALECT}_COMPILER_ID}")
+SET(_CMAKE_ASM_COMPILER_ARG1 "${CMAKE_ASM${ASM_DIALECT}_COMPILER_ARG1}")
+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_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeASM${ASM_DIALECT}Compiler.cmake IMMEDIATE @ONLY)
+
+SET(_CMAKE_ASM_COMPILER)
+SET(_CMAKE_ASM_COMPILER_ARG1)
+SET(_CMAKE_ASM_COMPILER_ENV_VAR)
diff --git a/Modules/CMakeDetermineASM_MASMCompiler.cmake b/Modules/CMakeDetermineASM_MASMCompiler.cmake
new file mode 100644
index 000000000..e23f7db4c
--- /dev/null
+++ b/Modules/CMakeDetermineASM_MASMCompiler.cmake
@@ -0,0 +1,27 @@
+
+#=============================================================================
+# Copyright 2008-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 the MS assembler (masm or masm64)
+
+SET(ASM_DIALECT "_MASM")
+
+# if we are using the 64bit cl compiler, assume we also want the 64bit assembler
+IF(CMAKE_CL_64)
+ SET(CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT ml64)
+ELSE(CMAKE_CL_64)
+ SET(CMAKE_ASM${ASM_DIALECT}_COMPILER_INIT ml)
+ENDIF(CMAKE_CL_64)
+
+INCLUDE(CMakeDetermineASMCompiler)
+SET(ASM_DIALECT)
diff --git a/Modules/CMakeDetermineASM_NASMCompiler.cmake b/Modules/CMakeDetermineASM_NASMCompiler.cmake
new file mode 100644
index 000000000..d184c0a81
--- /dev/null
+++ b/Modules/CMakeDetermineASM_NASMCompiler.cmake
@@ -0,0 +1,27 @@
+
+#=============================================================================
+# Copyright 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.)
+
+# Find the nasm assembler. yasm (http://www.tortall.net/projects/yasm/) is nasm compatible
+
+SET(CMAKE_ASM_NASM_COMPILER_INIT nasm yasm)
+
+IF(NOT CMAKE_ASM_NASM_COMPILER)
+ FIND_PROGRAM(CMAKE_ASM_NASM_COMPILER nasm
+ "$ENV{ProgramFiles}/NASM")
+ENDIF(NOT CMAKE_ASM_NASM_COMPILER)
+
+# Load the generic DetermineASM compiler file with the DIALECT set properly:
+SET(ASM_DIALECT "_NASM")
+INCLUDE(CMakeDetermineASMCompiler)
+SET(ASM_DIALECT)
diff --git a/Modules/CMakeDetermineCCompiler.cmake b/Modules/CMakeDetermineCCompiler.cmake
new file mode 100644
index 000000000..9028e8e06
--- /dev/null
+++ b/Modules/CMakeDetermineCCompiler.cmake
@@ -0,0 +1,179 @@
+
+#=============================================================================
+# 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.)
+
+# determine the compiler to use for C programs
+# NOTE, a generator may set CMAKE_C_COMPILER before
+# loading this file to force a compiler.
+# use environment variable CC first if defined by user, next use
+# the cmake variable CMAKE_GENERATOR_CC which can be defined by a generator
+# as a default compiler
+# If the internal cmake variable _CMAKE_TOOLCHAIN_PREFIX is set, this is used
+# as prefix for the tools (e.g. arm-elf-gcc, arm-elf-ar etc.). This works
+# currently with the GNU crosscompilers.
+#
+# Sets the following variables:
+# CMAKE_C_COMPILER
+# CMAKE_AR
+# CMAKE_RANLIB
+# CMAKE_COMPILER_IS_GNUCC
+#
+# If not already set before, it also sets
+# _CMAKE_TOOLCHAIN_PREFIX
+
+IF(NOT CMAKE_C_COMPILER)
+ SET(CMAKE_C_COMPILER_INIT NOTFOUND)
+
+ # prefer the environment variable CC
+ IF($ENV{CC} MATCHES ".+")
+ 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")
+ ENDIF(CMAKE_C_FLAGS_ENV_INIT)
+ IF(NOT EXISTS ${CMAKE_C_COMPILER_INIT})
+ MESSAGE(FATAL_ERROR "Could not find compiler set in environment variable CC:\n$ENV{CC}.")
+ ENDIF(NOT EXISTS ${CMAKE_C_COMPILER_INIT})
+ ENDIF($ENV{CC} MATCHES ".+")
+
+ # next try prefer the compiler specified by the generator
+ IF(CMAKE_GENERATOR_CC)
+ IF(NOT CMAKE_C_COMPILER_INIT)
+ SET(CMAKE_C_COMPILER_INIT ${CMAKE_GENERATOR_CC})
+ ENDIF(NOT CMAKE_C_COMPILER_INIT)
+ ENDIF(CMAKE_GENERATOR_CC)
+
+ # finally list compilers to try
+ IF(CMAKE_C_COMPILER_INIT)
+ SET(CMAKE_C_COMPILER_LIST ${CMAKE_C_COMPILER_INIT})
+ ELSE(CMAKE_C_COMPILER_INIT)
+ SET(CMAKE_C_COMPILER_LIST ${_CMAKE_TOOLCHAIN_PREFIX}gcc ${_CMAKE_TOOLCHAIN_PREFIX}cc cl bcc xlc)
+ ENDIF(CMAKE_C_COMPILER_INIT)
+
+ # Find the compiler.
+ IF (_CMAKE_USER_CXX_COMPILER_PATH)
+ FIND_PROGRAM(CMAKE_C_COMPILER NAMES ${CMAKE_C_COMPILER_LIST} PATHS ${_CMAKE_USER_CXX_COMPILER_PATH} DOC "C compiler" NO_DEFAULT_PATH)
+ ENDIF (_CMAKE_USER_CXX_COMPILER_PATH)
+ FIND_PROGRAM(CMAKE_C_COMPILER NAMES ${CMAKE_C_COMPILER_LIST} DOC "C compiler")
+
+ IF(CMAKE_C_COMPILER_INIT AND NOT CMAKE_C_COMPILER)
+ SET(CMAKE_C_COMPILER "${CMAKE_C_COMPILER_INIT}" CACHE FILEPATH "C compiler" FORCE)
+ ENDIF(CMAKE_C_COMPILER_INIT AND NOT CMAKE_C_COMPILER)
+ELSE(NOT CMAKE_C_COMPILER)
+
+ # 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("${_CMAKE_C_COMPILER_LIST_LENGTH}" EQUAL 2)
+
+ # 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(CMAKE_C_COMPILER_WITH_PATH)
+ ENDIF(NOT _CMAKE_USER_C_COMPILER_PATH)
+ENDIF(NOT CMAKE_C_COMPILER)
+MARK_AS_ADVANCED(CMAKE_C_COMPILER)
+
+IF (NOT _CMAKE_TOOLCHAIN_LOCATION)
+ GET_FILENAME_COMPONENT(_CMAKE_TOOLCHAIN_LOCATION "${CMAKE_C_COMPILER}" PATH)
+ENDIF (NOT _CMAKE_TOOLCHAIN_LOCATION)
+
+# Build a small source file to identify the compiler.
+IF(${CMAKE_GENERATOR} MATCHES "Visual Studio")
+ SET(CMAKE_C_COMPILER_ID_RUN 1)
+ SET(CMAKE_C_PLATFORM_ID "Windows")
+ SET(CMAKE_C_COMPILER_ID "MSVC")
+ENDIF(${CMAKE_GENERATOR} MATCHES "Visual Studio")
+
+IF(NOT CMAKE_C_COMPILER_ID_RUN)
+ SET(CMAKE_C_COMPILER_ID_RUN 1)
+
+ # 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
+ # Try compiling to an object file only.
+ "-c"
+
+ # Try enabling ANSI mode on HP.
+ "-Aa"
+ )
+
+ # Try to identify the compiler.
+ SET(CMAKE_C_COMPILER_ID)
+ FILE(READ ${CMAKE_ROOT}/Modules/CMakePlatformId.h.in
+ CMAKE_C_COMPILER_ID_PLATFORM_CONTENT)
+ 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")
+ SET(CMAKE_COMPILER_IS_GNUCC 1)
+ ENDIF("${CMAKE_C_COMPILER_ID}" MATCHES "GNU")
+ IF("${CMAKE_C_PLATFORM_ID}" MATCHES "MinGW")
+ SET(CMAKE_COMPILER_IS_MINGW 1)
+ ELSEIF("${CMAKE_C_PLATFORM_ID}" MATCHES "Cygwin")
+ SET(CMAKE_COMPILER_IS_CYGWIN 1)
+ ENDIF("${CMAKE_C_PLATFORM_ID}" MATCHES "MinGW")
+ENDIF(NOT CMAKE_C_COMPILER_ID_RUN)
+
+# If we have a gcc cross compiler, they have usually some prefix, like
+# 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
+# "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 "${CMAKE_C_COMPILER_ID}" MATCHES "GNU"
+ AND NOT _CMAKE_TOOLCHAIN_PREFIX)
+ GET_FILENAME_COMPONENT(COMPILER_BASENAME "${CMAKE_C_COMPILER}" NAME)
+ IF (COMPILER_BASENAME MATCHES "^(.+-)g?cc(-[0-9]+\\.[0-9]+\\.[0-9]+)?(\\.exe)?$")
+ SET(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
+ ENDIF (COMPILER_BASENAME MATCHES "^(.+-)g?cc(-[0-9]+\\.[0-9]+\\.[0-9]+)?(\\.exe)?$")
+
+ # if "llvm-" is part of the prefix, remove it, since llvm doesn't have its own binutils
+ # but uses the regular ar, objcopy, etc. (instead of llvm-objcopy etc.)
+ IF ("${_CMAKE_TOOLCHAIN_PREFIX}" MATCHES "(.+-)?llvm-$")
+ SET(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
+ ENDIF ("${_CMAKE_TOOLCHAIN_PREFIX}" MATCHES "(.+-)?llvm-$")
+
+ENDIF (CMAKE_CROSSCOMPILING
+ AND "${CMAKE_C_COMPILER_ID}" MATCHES "GNU"
+ AND NOT _CMAKE_TOOLCHAIN_PREFIX)
+
+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(MSVC_C_ARCHITECTURE_ID)
+# configure variables set in this file for fast reload later on
+CONFIGURE_FILE(${CMAKE_ROOT}/Modules/CMakeCCompiler.cmake.in
+ "${CMAKE_PLATFORM_ROOT_BIN}/CMakeCCompiler.cmake"
+ @ONLY IMMEDIATE # IMMEDIATE must be here for compatibility mode <= 2.0
+ )
+SET(CMAKE_C_COMPILER_ENV_VAR "CC")
diff --git a/Modules/CMakeDetermineCXXCompiler.cmake b/Modules/CMakeDetermineCXXCompiler.cmake
new file mode 100644
index 000000000..7f8f3ec8b
--- /dev/null
+++ b/Modules/CMakeDetermineCXXCompiler.cmake
@@ -0,0 +1,188 @@
+
+#=============================================================================
+# 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.)
+
+# determine the compiler to use for C++ programs
+# NOTE, a generator may set CMAKE_CXX_COMPILER before
+# loading this file to force a compiler.
+# use environment variable CXX first if defined by user, next use
+# the cmake variable CMAKE_GENERATOR_CXX which can be defined by a generator
+# as a default compiler
+# If the internal cmake variable _CMAKE_TOOLCHAIN_PREFIX is set, this is used
+# as prefix for the tools (e.g. arm-elf-g++, arm-elf-ar etc.)
+#
+# Sets the following variables:
+# CMAKE_CXX_COMPILER
+# CMAKE_COMPILER_IS_GNUCXX
+# CMAKE_AR
+# CMAKE_RANLIB
+#
+# If not already set before, it also sets
+# _CMAKE_TOOLCHAIN_PREFIX
+
+IF(NOT CMAKE_CXX_COMPILER)
+ SET(CMAKE_CXX_COMPILER_INIT NOTFOUND)
+
+ # prefer the environment variable CXX
+ IF($ENV{CXX} MATCHES ".+")
+ 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")
+ ENDIF(CMAKE_CXX_FLAGS_ENV_INIT)
+ IF(NOT EXISTS ${CMAKE_CXX_COMPILER_INIT})
+ MESSAGE(FATAL_ERROR "Could not find compiler set in environment variable CXX:\n$ENV{CXX}.\n${CMAKE_CXX_COMPILER_INIT}")
+ ENDIF(NOT EXISTS ${CMAKE_CXX_COMPILER_INIT})
+ ENDIF($ENV{CXX} MATCHES ".+")
+
+ # next prefer the generator specified compiler
+ IF(CMAKE_GENERATOR_CXX)
+ IF(NOT CMAKE_CXX_COMPILER_INIT)
+ SET(CMAKE_CXX_COMPILER_INIT ${CMAKE_GENERATOR_CXX})
+ ENDIF(NOT CMAKE_CXX_COMPILER_INIT)
+ ENDIF(CMAKE_GENERATOR_CXX)
+
+ # finally list compilers to try
+ IF(CMAKE_CXX_COMPILER_INIT)
+ SET(CMAKE_CXX_COMPILER_LIST ${CMAKE_CXX_COMPILER_INIT})
+ ELSE(CMAKE_CXX_COMPILER_INIT)
+ SET(CMAKE_CXX_COMPILER_LIST ${_CMAKE_TOOLCHAIN_PREFIX}c++ ${_CMAKE_TOOLCHAIN_PREFIX}g++ CC aCC cl bcc xlC)
+ ENDIF(CMAKE_CXX_COMPILER_INIT)
+
+ # Find the compiler.
+ IF (_CMAKE_USER_C_COMPILER_PATH)
+ FIND_PROGRAM(CMAKE_CXX_COMPILER NAMES ${CMAKE_CXX_COMPILER_LIST} PATHS ${_CMAKE_USER_C_COMPILER_PATH} DOC "C++ compiler" NO_DEFAULT_PATH)
+ ENDIF (_CMAKE_USER_C_COMPILER_PATH)
+ FIND_PROGRAM(CMAKE_CXX_COMPILER NAMES ${CMAKE_CXX_COMPILER_LIST} DOC "C++ compiler")
+
+ IF(CMAKE_CXX_COMPILER_INIT AND NOT CMAKE_CXX_COMPILER)
+ SET(CMAKE_CXX_COMPILER "${CMAKE_CXX_COMPILER_INIT}" CACHE FILEPATH "C++ compiler" FORCE)
+ ENDIF(CMAKE_CXX_COMPILER_INIT AND NOT CMAKE_CXX_COMPILER)
+ELSE(NOT CMAKE_CXX_COMPILER)
+
+# 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("${_CMAKE_CXX_COMPILER_LIST_LENGTH}" EQUAL 2)
+
+# 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(CMAKE_CXX_COMPILER_WITH_PATH)
+ ENDIF(NOT _CMAKE_USER_CXX_COMPILER_PATH)
+ENDIF(NOT CMAKE_CXX_COMPILER)
+MARK_AS_ADVANCED(CMAKE_CXX_COMPILER)
+
+IF (NOT _CMAKE_TOOLCHAIN_LOCATION)
+ GET_FILENAME_COMPONENT(_CMAKE_TOOLCHAIN_LOCATION "${CMAKE_CXX_COMPILER}" PATH)
+ENDIF (NOT _CMAKE_TOOLCHAIN_LOCATION)
+
+# This block was used before the compiler was identified by building a
+# source file. Unless g++ crashes when building a small C++
+# executable this should no longer be needed.
+#
+# The g++ that comes with BeOS 5 segfaults if you run "g++ -E"
+# ("gcc -E" is fine), which throws up a system dialog box that hangs cmake
+# until the user clicks "OK"...so for now, we just assume it's g++.
+# IF(BEOS)
+# SET(CMAKE_COMPILER_IS_GNUCXX 1)
+# SET(CMAKE_COMPILER_IS_GNUCXX_RUN 1)
+# ENDIF(BEOS)
+
+# Build a small source file to identify the compiler.
+IF(${CMAKE_GENERATOR} MATCHES "Visual Studio")
+ SET(CMAKE_CXX_COMPILER_ID_RUN 1)
+ SET(CMAKE_CXX_PLATFORM_ID "Windows")
+ SET(CMAKE_CXX_COMPILER_ID "MSVC")
+ENDIF(${CMAKE_GENERATOR} MATCHES "Visual Studio")
+IF(NOT CMAKE_CXX_COMPILER_ID_RUN)
+ SET(CMAKE_CXX_COMPILER_ID_RUN 1)
+
+ # 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
+ # Try compiling to an object file only.
+ "-c"
+ )
+
+ # Try to identify the compiler.
+ SET(CMAKE_CXX_COMPILER_ID)
+ FILE(READ ${CMAKE_ROOT}/Modules/CMakePlatformId.h.in
+ CMAKE_CXX_COMPILER_ID_PLATFORM_CONTENT)
+ 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")
+ SET(CMAKE_COMPILER_IS_GNUCXX 1)
+ ENDIF("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
+ IF("${CMAKE_CXX_PLATFORM_ID}" MATCHES "MinGW")
+ SET(CMAKE_COMPILER_IS_MINGW 1)
+ ELSEIF("${CMAKE_CXX_PLATFORM_ID}" MATCHES "Cygwin")
+ SET(CMAKE_COMPILER_IS_CYGWIN 1)
+ ENDIF("${CMAKE_CXX_PLATFORM_ID}" MATCHES "MinGW")
+ENDIF(NOT CMAKE_CXX_COMPILER_ID_RUN)
+
+# if we have a g++ cross compiler, they have usually some prefix, like
+# 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
+# "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 "${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU"
+ AND NOT _CMAKE_TOOLCHAIN_PREFIX)
+ GET_FILENAME_COMPONENT(COMPILER_BASENAME "${CMAKE_CXX_COMPILER}" NAME)
+ IF (COMPILER_BASENAME MATCHES "^(.+-)[gc]\\+\\+(-[0-9]+\\.[0-9]+\\.[0-9]+)?(\\.exe)?$")
+ SET(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
+ ENDIF (COMPILER_BASENAME MATCHES "^(.+-)[gc]\\+\\+(-[0-9]+\\.[0-9]+\\.[0-9]+)?(\\.exe)?$")
+
+ # if "llvm-" is part of the prefix, remove it, since llvm doesn't have its own binutils
+ # but uses the regular ar, objcopy, etc. (instead of llvm-objcopy etc.)
+ IF ("${_CMAKE_TOOLCHAIN_PREFIX}" MATCHES "(.+-)?llvm-$")
+ SET(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
+ ENDIF ("${_CMAKE_TOOLCHAIN_PREFIX}" MATCHES "(.+-)?llvm-$")
+
+ENDIF (CMAKE_CROSSCOMPILING
+ AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU"
+ AND NOT _CMAKE_TOOLCHAIN_PREFIX)
+
+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(MSVC_CXX_ARCHITECTURE_ID)
+# configure all variables set in this file
+CONFIGURE_FILE(${CMAKE_ROOT}/Modules/CMakeCXXCompiler.cmake.in
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeCXXCompiler.cmake
+ @ONLY IMMEDIATE # IMMEDIATE must be here for compatibility mode <= 2.0
+ )
+
+SET(CMAKE_CXX_COMPILER_ENV_VAR "CXX")
diff --git a/Modules/CMakeDetermineCompilerABI.cmake b/Modules/CMakeDetermineCompilerABI.cmake
new file mode 100644
index 000000000..1c9899e64
--- /dev/null
+++ b/Modules/CMakeDetermineCompilerABI.cmake
@@ -0,0 +1,131 @@
+
+#=============================================================================
+# Copyright 2008-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.)
+
+# Function to compile a source file to identify the compiler ABI.
+# This is used internally by CMake and should not be included by user
+# code.
+
+INCLUDE(${CMAKE_ROOT}/Modules/CMakeParseImplicitLinkInfo.cmake)
+
+FUNCTION(CMAKE_DETERMINE_COMPILER_ABI lang src)
+ IF(NOT DEFINED CMAKE_DETERMINE_${lang}_ABI_COMPILED)
+ MESSAGE(STATUS "Detecting ${lang} compiler ABI info")
+
+ # Compile the ABI identification source.
+ SET(BIN "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeDetermineCompilerABI_${lang}.bin")
+ SET(CMAKE_FLAGS )
+ IF(DEFINED CMAKE_${lang}_VERBOSE_FLAG)
+ SET(CMAKE_FLAGS "-DCMAKE_EXE_LINKER_FLAGS=${CMAKE_${lang}_VERBOSE_FLAG}")
+ ENDIF()
+ TRY_COMPILE(CMAKE_DETERMINE_${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.
+ "--no-warn-unused-cli"
+ OUTPUT_VARIABLE OUTPUT
+ COPY_FILE "${BIN}"
+ )
+
+ # Load the resulting information strings.
+ IF(CMAKE_DETERMINE_${lang}_ABI_COMPILED)
+ 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:[^[]*\\[")
+ FOREACH(info ${ABI_STRINGS})
+ IF("${info}" MATCHES ".*INFO:sizeof_dptr\\[0*([^]]*)\\].*")
+ STRING(REGEX REPLACE ".*INFO:sizeof_dptr\\[0*([^]]*)\\].*" "\\1" ABI_SIZEOF_DPTR "${info}")
+ ENDIF("${info}" MATCHES ".*INFO:sizeof_dptr\\[0*([^]]*)\\].*")
+ IF("${info}" MATCHES ".*INFO:abi\\[([^]]*)\\].*")
+ STRING(REGEX REPLACE ".*INFO:abi\\[([^]]*)\\].*" "\\1" ABI_NAME "${info}")
+ ENDIF("${info}" MATCHES ".*INFO:abi\\[([^]]*)\\].*")
+ ENDFOREACH(info)
+
+ IF(ABI_SIZEOF_DPTR)
+ SET(CMAKE_${lang}_SIZEOF_DATA_PTR "${ABI_SIZEOF_DPTR}" PARENT_SCOPE)
+ ELSEIF(CMAKE_${lang}_SIZEOF_DATA_PTR_DEFAULT)
+ SET(CMAKE_${lang}_SIZEOF_DATA_PTR "${CMAKE_${lang}_SIZEOF_DATA_PTR_DEFAULT}" PARENT_SCOPE)
+ ENDIF(ABI_SIZEOF_DPTR)
+
+ IF(ABI_NAME)
+ SET(CMAKE_${lang}_COMPILER_ABI "${ABI_NAME}" PARENT_SCOPE)
+ ENDIF(ABI_NAME)
+
+ # Parse implicit linker information for this language, if available.
+ SET(implicit_dirs "")
+ SET(implicit_libs "")
+ SET(MULTI_ARCH FALSE)
+ IF(DEFINED CMAKE_OSX_ARCHITECTURES)
+ IF( "${CMAKE_OSX_ARCHITECTURES}" MATCHES ";" )
+ SET(MULTI_ARCH TRUE)
+ ENDIF()
+ ENDIF()
+ IF(CMAKE_${lang}_VERBOSE_FLAG
+ # Implicit link information cannot be used explicitly for
+ # multiple OS X architectures, so we skip it.
+ AND NOT MULTI_ARCH
+ # Skip this with Xcode for now.
+ AND NOT "${CMAKE_GENERATOR}" MATCHES Xcode)
+ CMAKE_PARSE_IMPLICIT_LINK_INFO("${OUTPUT}" implicit_libs implicit_dirs log
+ "${CMAKE_${lang}_IMPLICIT_OBJECT_REGEX}")
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "Parsed ${lang} implicit link information from above output:\n${log}\n\n")
+ ENDIF()
+ # for VS IDE Intel Fortran we have to figure out the
+ # implicit link path for the fortran run time using
+ # a try-compile
+ IF("${lang}" MATCHES "Fortran"
+ AND "${CMAKE_GENERATOR}" MATCHES "Visual Studio")
+ SET(_desc "Determine Intel Fortran Compiler Implicit Link Path")
+ MESSAGE(STATUS "${_desc}")
+ # Build a sample project which reports symbols.
+ TRY_COMPILE(IFORT_LIB_PATH_COMPILED
+ ${CMAKE_BINARY_DIR}/CMakeFiles/IntelVSImplicitPath
+ ${CMAKE_ROOT}/Modules/IntelVSImplicitPath
+ IntelFortranImplicit
+ CMAKE_FLAGS
+ "-DCMAKE_Fortran_FLAGS:STRING=${CMAKE_Fortran_FLAGS}"
+ OUTPUT_VARIABLE _output)
+ FILE(WRITE
+ "${CMAKE_BINARY_DIR}/CMakeFiles/IntelVSImplicitPath/output.txt"
+ "${_output}")
+ INCLUDE(${CMAKE_BINARY_DIR}/CMakeFiles/IntelVSImplicitPath/output.cmake OPTIONAL)
+ SET(_desc "Determine Intel Fortran Compiler Implicit Link Path -- done")
+ MESSAGE(STATUS "${_desc}")
+ ENDIF()
+
+ SET(CMAKE_${lang}_IMPLICIT_LINK_LIBRARIES "${implicit_libs}" PARENT_SCOPE)
+ SET(CMAKE_${lang}_IMPLICIT_LINK_DIRECTORIES "${implicit_dirs}" PARENT_SCOPE)
+
+ # Detect library architecture directory name.
+ IF(CMAKE_LIBRARY_ARCHITECTURE_REGEX)
+ FOREACH(dir ${implicit_dirs})
+ IF("${dir}" MATCHES "/lib/${CMAKE_LIBRARY_ARCHITECTURE_REGEX}$")
+ GET_FILENAME_COMPONENT(arch "${dir}" NAME)
+ SET(CMAKE_${lang}_LIBRARY_ARCHITECTURE "${arch}" PARENT_SCOPE)
+ BREAK()
+ ENDIF()
+ ENDFOREACH()
+ ENDIF()
+
+ ELSE(CMAKE_DETERMINE_${lang}_ABI_COMPILED)
+ MESSAGE(STATUS "Detecting ${lang} compiler ABI info - failed")
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Detecting ${lang} compiler ABI info failed to compile with the following output:\n${OUTPUT}\n\n")
+ ENDIF(CMAKE_DETERMINE_${lang}_ABI_COMPILED)
+ ENDIF(NOT DEFINED CMAKE_DETERMINE_${lang}_ABI_COMPILED)
+ENDFUNCTION(CMAKE_DETERMINE_COMPILER_ABI)
diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake
new file mode 100644
index 000000000..67f5a5906
--- /dev/null
+++ b/Modules/CMakeDetermineCompilerId.cmake
@@ -0,0 +1,323 @@
+
+#=============================================================================
+# 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.)
+
+# Function to compile a source file to identify the compiler. This is
+# used internally by CMake and should not be included by user code.
+# If successful, sets CMAKE_<lang>_COMPILER_ID and CMAKE_<lang>_PLATFORM_ID
+
+FUNCTION(CMAKE_DETERMINE_COMPILER_ID lang flagvar src)
+ # Make sure the compiler arguments are clean.
+ STRING(STRIP "${CMAKE_${lang}_COMPILER_ARG1}" CMAKE_${lang}_COMPILER_ID_ARG1)
+ STRING(REGEX REPLACE " +" ";" CMAKE_${lang}_COMPILER_ID_ARG1 "${CMAKE_${lang}_COMPILER_ID_ARG1}")
+
+ # Make sure user-specified compiler flags are used.
+ IF(CMAKE_${lang}_FLAGS)
+ SET(CMAKE_${lang}_COMPILER_ID_FLAGS ${CMAKE_${lang}_FLAGS})
+ ELSE(CMAKE_${lang}_FLAGS)
+ SET(CMAKE_${lang}_COMPILER_ID_FLAGS $ENV{${flagvar}})
+ ENDIF(CMAKE_${lang}_FLAGS)
+ STRING(REGEX 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_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/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(file)
+ ENDIF(NOT CMAKE_${lang}_COMPILER_ID)
+ ENDFOREACH(flags)
+
+ # If the compiler is still unknown, try to query its vendor.
+ IF(NOT CMAKE_${lang}_COMPILER_ID)
+ CMAKE_DETERMINE_COMPILER_ID_VENDOR(${lang})
+ 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(NOT CMAKE_EXECUTABLE_FORMAT)
+
+ # Display the final identification result.
+ IF(CMAKE_${lang}_COMPILER_ID)
+ IF(CMAKE_${lang}_COMPILER_VERSION)
+ SET(_version " ${CMAKE_${lang}_COMPILER_VERSION}")
+ ELSE()
+ SET(_version "")
+ ENDIF()
+ MESSAGE(STATUS "The ${lang} compiler identification is "
+ "${CMAKE_${lang}_COMPILER_ID}${_version}")
+ ELSE(CMAKE_${lang}_COMPILER_ID)
+ MESSAGE(STATUS "The ${lang} compiler identification is unknown")
+ ENDIF(CMAKE_${lang}_COMPILER_ID)
+
+ 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}_COMPILER_VERSION "${CMAKE_${lang}_COMPILER_VERSION}" PARENT_SCOPE)
+ENDFUNCTION(CMAKE_DETERMINE_COMPILER_ID)
+
+#-----------------------------------------------------------------------------
+# 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)
+ STRING(CONFIGURE "${ID_CONTENT_IN}" ID_CONTENT_OUT @ONLY)
+ FILE(WRITE ${CMAKE_${lang}_COMPILER_ID_DIR}/${src} "${ID_CONTENT_OUT}")
+ENDFUNCTION(CMAKE_DETERMINE_COMPILER_ID_WRITE)
+
+#-----------------------------------------------------------------------------
+# Function to build the compiler id source file and look for output
+# files.
+FUNCTION(CMAKE_DETERMINE_COMPILER_ID_BUILD lang testflags src)
+ # Create a clean working directory.
+ FILE(REMOVE_RECURSE ${CMAKE_${lang}_COMPILER_ID_DIR})
+ FILE(MAKE_DIRECTORY ${CMAKE_${lang}_COMPILER_ID_DIR})
+ CMAKE_DETERMINE_COMPILER_ID_WRITE("${lang}" "${src}")
+
+ # Construct a description of this test case.
+ SET(COMPILER_DESCRIPTION
+ "Compiler: ${CMAKE_${lang}_COMPILER} ${CMAKE_${lang}_COMPILER_ID_ARG1}
+Build flags: ${CMAKE_${lang}_COMPILER_ID_FLAGS_LIST}
+Id flags: ${testflags}
+")
+
+ # Compile the compiler identification source.
+ 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(COMMAND EXECUTE_PROCESS)
+ 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(COMMAND EXECUTE_PROCESS)
+
+ # Check the result of compilation.
+ IF(CMAKE_${lang}_COMPILER_ID_RESULT)
+ # Compilation failed.
+ SET(MSG
+ "Compiling the ${lang} compiler identification source file \"${src}\" failed.
+${COMPILER_DESCRIPTION}
+The output was:
+${CMAKE_${lang}_COMPILER_ID_RESULT}
+${CMAKE_${lang}_COMPILER_ID_OUTPUT}
+
+")
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "${MSG}")
+ #IF(NOT CMAKE_${lang}_COMPILER_ID_ALLOW_FAIL)
+ # MESSAGE(FATAL_ERROR "${MSG}")
+ #ENDIF(NOT CMAKE_${lang}_COMPILER_ID_ALLOW_FAIL)
+
+ # No output files should be inspected.
+ SET(COMPILER_${lang}_PRODUCED_FILES)
+ ELSE(CMAKE_${lang}_COMPILER_ID_RESULT)
+ # Compilation succeeded.
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "Compiling the ${lang} compiler identification source file \"${src}\" succeeded.
+${COMPILER_DESCRIPTION}
+The output was:
+${CMAKE_${lang}_COMPILER_ID_RESULT}
+${CMAKE_${lang}_COMPILER_ID_OUTPUT}
+
+")
+
+ # Find the executable produced by the compiler, try all files in the
+ # binary dir.
+ FILE(GLOB COMPILER_${lang}_PRODUCED_FILES
+ RELATIVE ${CMAKE_${lang}_COMPILER_ID_DIR}
+ ${CMAKE_${lang}_COMPILER_ID_DIR}/*)
+ LIST(REMOVE_ITEM COMPILER_${lang}_PRODUCED_FILES "${src}")
+ FOREACH(file ${COMPILER_${lang}_PRODUCED_FILES})
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "Compilation of the ${lang} compiler identification source \""
+ "${src}\" produced \"${file}\"\n\n")
+ ENDFOREACH(file)
+
+ IF(NOT COMPILER_${lang}_PRODUCED_FILES)
+ # No executable was found.
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Compilation of the ${lang} compiler identification source \""
+ "${src}\" did not produce an executable in \""
+ "${CMAKE_${lang}_COMPILER_ID_DIR}\".\n\n")
+ ENDIF(NOT COMPILER_${lang}_PRODUCED_FILES)
+ ENDIF(CMAKE_${lang}_COMPILER_ID_RESULT)
+
+ # Return the files produced by the compilation.
+ SET(COMPILER_${lang}_PRODUCED_FILES "${COMPILER_${lang}_PRODUCED_FILES}" PARENT_SCOPE)
+ENDFUNCTION(CMAKE_DETERMINE_COMPILER_ID_BUILD lang testflags src)
+
+#-----------------------------------------------------------------------------
+# Function to extract the compiler id from an executable.
+FUNCTION(CMAKE_DETERMINE_COMPILER_ID_CHECK lang file)
+ # Look for a compiler id if not yet known.
+ IF(NOT CMAKE_${lang}_COMPILER_ID)
+ # Read the compiler identification string from the executable file.
+ SET(COMPILER_ID)
+ SET(COMPILER_VERSION)
+ SET(PLATFORM_ID)
+ FILE(STRINGS ${file}
+ CMAKE_${lang}_COMPILER_ID_STRINGS LIMIT_COUNT 4 REGEX "INFO:")
+ SET(HAVE_COMPILER_TWICE 0)
+ FOREACH(info ${CMAKE_${lang}_COMPILER_ID_STRINGS})
+ IF("${info}" MATCHES ".*INFO:compiler\\[([^]\"]*)\\].*")
+ IF(COMPILER_ID)
+ SET(COMPILER_ID_TWICE 1)
+ ENDIF(COMPILER_ID)
+ STRING(REGEX REPLACE ".*INFO:compiler\\[([^]]*)\\].*" "\\1"
+ COMPILER_ID "${info}")
+ ENDIF("${info}" MATCHES ".*INFO:compiler\\[([^]\"]*)\\].*")
+ IF("${info}" MATCHES ".*INFO:platform\\[([^]\"]*)\\].*")
+ STRING(REGEX REPLACE ".*INFO:platform\\[([^]]*)\\].*" "\\1"
+ PLATFORM_ID "${info}")
+ ENDIF("${info}" MATCHES ".*INFO:platform\\[([^]\"]*)\\].*")
+ IF("${info}" MATCHES ".*INFO:arch\\[([^]\"]*)\\].*")
+ STRING(REGEX REPLACE ".*INFO:arch\\[([^]]*)\\].*" "\\1"
+ ARCHITECTURE_ID "${info}")
+ ENDIF("${info}" MATCHES ".*INFO:arch\\[([^]\"]*)\\].*")
+ 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}")
+ STRING(REGEX REPLACE "\\.0+([0-9])" ".\\1" COMPILER_VERSION "${COMPILER_VERSION}")
+ ENDIF("${info}" MATCHES ".*INFO:compiler_version\\[([^]\"]*)\\].*")
+ ENDFOREACH(info)
+
+ # Check if a valid compiler and platform were found.
+ IF(COMPILER_ID AND NOT COMPILER_ID_TWICE)
+ SET(CMAKE_${lang}_COMPILER_ID "${COMPILER_ID}")
+ SET(CMAKE_${lang}_PLATFORM_ID "${PLATFORM_ID}")
+ SET(MSVC_${lang}_ARCHITECTURE_ID "${ARCHITECTURE_ID}")
+ SET(CMAKE_${lang}_COMPILER_VERSION "${COMPILER_VERSION}")
+ ENDIF(COMPILER_ID AND NOT COMPILER_ID_TWICE)
+
+ # Check the compiler identification string.
+ IF(CMAKE_${lang}_COMPILER_ID)
+ # The compiler identification was found.
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "The ${lang} compiler identification is ${CMAKE_${lang}_COMPILER_ID}, found in \""
+ "${file}\"\n\n")
+ ELSE(CMAKE_${lang}_COMPILER_ID)
+ # The compiler identification could not be found.
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "The ${lang} compiler identification could not be found in \""
+ "${file}\"\n\n")
+ ENDIF(CMAKE_${lang}_COMPILER_ID)
+ ENDIF(NOT CMAKE_${lang}_COMPILER_ID)
+
+ # try to figure out the executable format: ELF, COFF, Mach-O
+ IF(NOT CMAKE_EXECUTABLE_FORMAT)
+ FILE(READ ${file} CMAKE_EXECUTABLE_MAGIC LIMIT 4 HEX)
+
+ # ELF files start with 0x7f"ELF"
+ IF("${CMAKE_EXECUTABLE_MAGIC}" STREQUAL "7f454c46")
+ SET(CMAKE_EXECUTABLE_FORMAT "ELF" CACHE INTERNAL "Executable file format")
+ ENDIF("${CMAKE_EXECUTABLE_MAGIC}" STREQUAL "7f454c46")
+
+# # COFF (.exe) files start with "MZ"
+# IF("${CMAKE_EXECUTABLE_MAGIC}" MATCHES "4d5a....")
+# SET(CMAKE_EXECUTABLE_FORMAT "COFF" CACHE STRING "Executable file format")
+# ENDIF("${CMAKE_EXECUTABLE_MAGIC}" MATCHES "4d5a....")
+#
+# # Mach-O files start with CAFEBABE or FEEDFACE, according to http://radio.weblogs.com/0100490/2003/01/28.html
+# IF("${CMAKE_EXECUTABLE_MAGIC}" MATCHES "cafebabe")
+# SET(CMAKE_EXECUTABLE_FORMAT "MACHO" CACHE STRING "Executable file format")
+# ENDIF("${CMAKE_EXECUTABLE_MAGIC}" MATCHES "cafebabe")
+# IF("${CMAKE_EXECUTABLE_MAGIC}" MATCHES "feedface")
+# SET(CMAKE_EXECUTABLE_FORMAT "MACHO" CACHE STRING "Executable file format")
+# ENDIF("${CMAKE_EXECUTABLE_MAGIC}" MATCHES "feedface")
+
+ ENDIF(NOT CMAKE_EXECUTABLE_FORMAT)
+ IF(NOT DEFINED CMAKE_EXECUTABLE_FORMAT)
+ SET(CMAKE_EXECUTABLE_FORMAT)
+ ENDIF()
+ # Return the information extracted.
+ 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}_COMPILER_VERSION "${CMAKE_${lang}_COMPILER_VERSION}" PARENT_SCOPE)
+ SET(CMAKE_EXECUTABLE_FORMAT "${CMAKE_EXECUTABLE_FORMAT}" PARENT_SCOPE)
+ENDFUNCTION(CMAKE_DETERMINE_COMPILER_ID_CHECK lang)
+
+#-----------------------------------------------------------------------------
+# Function to query the compiler vendor.
+# This uses a table with entries of the form
+# list(APPEND CMAKE_${lang}_COMPILER_ID_VENDORS ${vendor})
+# set(CMAKE_${lang}_COMPILER_ID_VENDOR_FLAGS_${vendor} -some-vendor-flag)
+# set(CMAKE_${lang}_COMPILER_ID_VENDOR_REGEX_${vendor} "Some Vendor Output")
+# We try running the compiler with the flag for each vendor and
+# matching its regular expression in the output.
+FUNCTION(CMAKE_DETERMINE_COMPILER_ID_VENDOR lang)
+
+ IF(NOT CMAKE_${lang}_COMPILER_ID_DIR)
+ # We get here when this function is called not from within CMAKE_DETERMINE_COMPILER_ID()
+ # This is done e.g. for detecting the compiler ID for assemblers.
+ # Compute the directory in which to run the test and Create a clean working directory.
+ SET(CMAKE_${lang}_COMPILER_ID_DIR ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CompilerId${lang})
+ FILE(REMOVE_RECURSE ${CMAKE_${lang}_COMPILER_ID_DIR})
+ FILE(MAKE_DIRECTORY ${CMAKE_${lang}_COMPILER_ID_DIR})
+ ENDIF(NOT CMAKE_${lang}_COMPILER_ID_DIR)
+
+
+ FOREACH(vendor ${CMAKE_${lang}_COMPILER_ID_VENDORS})
+ SET(flags ${CMAKE_${lang}_COMPILER_ID_VENDOR_FLAGS_${vendor}})
+ SET(regex ${CMAKE_${lang}_COMPILER_ID_VENDOR_REGEX_${vendor}})
+ EXECUTE_PROCESS(
+ COMMAND ${CMAKE_${lang}_COMPILER}
+ ${CMAKE_${lang}_COMPILER_ID_ARG1}
+ ${CMAKE_${lang}_COMPILER_ID_FLAGS_LIST}
+ ${flags}
+ WORKING_DIRECTORY ${CMAKE_${lang}_COMPILER_ID_DIR}
+ OUTPUT_VARIABLE output ERROR_VARIABLE output
+ RESULT_VARIABLE result
+ TIMEOUT 10
+ )
+
+ IF("${output}" MATCHES "${regex}")
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "Checking whether the ${lang} compiler is ${vendor} using \"${flags}\" "
+ "matched \"${regex}\":\n${output}")
+ SET(CMAKE_${lang}_COMPILER_ID "${vendor}" PARENT_SCOPE)
+ BREAK()
+ ELSE()
+ IF("${result}" MATCHES "timeout")
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Checking whether the ${lang} compiler is ${vendor} using \"${flags}\" "
+ "terminated after 10 s due to timeout.")
+ ELSE()
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Checking whether the ${lang} compiler is ${vendor} using \"${flags}\" "
+ "did not match \"${regex}\":\n${output}")
+ ENDIF()
+ ENDIF()
+ ENDFOREACH()
+ENDFUNCTION(CMAKE_DETERMINE_COMPILER_ID_VENDOR)
diff --git a/Modules/CMakeDetermineFortranCompiler.cmake b/Modules/CMakeDetermineFortranCompiler.cmake
new file mode 100644
index 000000000..ade6d586c
--- /dev/null
+++ b/Modules/CMakeDetermineFortranCompiler.cmake
@@ -0,0 +1,228 @@
+
+#=============================================================================
+# 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.)
+
+# determine the compiler to use for Fortran programs
+# NOTE, a generator may set CMAKE_Fortran_COMPILER before
+# loading this file to force a compiler.
+# use environment variable FC first if defined by user, next use
+# the cmake variable CMAKE_GENERATOR_FC which can be defined by a generator
+# as a default compiler
+
+IF(NOT CMAKE_Fortran_COMPILER)
+ # prefer the environment variable CC
+ IF($ENV{FC} MATCHES ".+")
+ 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")
+ ENDIF(CMAKE_Fortran_FLAGS_ENV_INIT)
+ IF(EXISTS ${CMAKE_Fortran_COMPILER_INIT})
+ ELSE(EXISTS ${CMAKE_Fortran_COMPILER_INIT})
+ MESSAGE(FATAL_ERROR "Could not find compiler set in environment variable FC:\n$ENV{FC}.")
+ ENDIF(EXISTS ${CMAKE_Fortran_COMPILER_INIT})
+ ENDIF($ENV{FC} MATCHES ".+")
+
+ # next try prefer the compiler specified by the generator
+ IF(CMAKE_GENERATOR_FC)
+ IF(NOT CMAKE_Fortran_COMPILER_INIT)
+ SET(CMAKE_Fortran_COMPILER_INIT ${CMAKE_GENERATOR_FC})
+ ENDIF(NOT CMAKE_Fortran_COMPILER_INIT)
+ ENDIF(CMAKE_GENERATOR_FC)
+
+ # finally list compilers to try
+ IF(CMAKE_Fortran_COMPILER_INIT)
+ SET(CMAKE_Fortran_COMPILER_LIST ${CMAKE_Fortran_COMPILER_INIT})
+ ELSE(CMAKE_Fortran_COMPILER_INIT)
+ # Known compilers:
+ # f77/f90/f95: generic compiler names
+ # g77: GNU Fortran 77 compiler
+ # gfortran: putative GNU Fortran 95+ compiler (in progress)
+ # fort77: native F77 compiler under HP-UX (and some older Crays)
+ # frt: Fujitsu F77 compiler
+ # pathf90/pathf95/pathf2003: PathScale Fortran compiler
+ # pgf77/pgf90/pgf95/pgfortran: Portland Group F77/F90/F95 compilers
+ # xlf/xlf90/xlf95: IBM (AIX) F77/F90/F95 compilers
+ # lf95: Lahey-Fujitsu F95 compiler
+ # fl32: Microsoft Fortran 77 "PowerStation" compiler
+ # af77: Apogee F77 compiler for Intergraph hardware running CLIX
+ # epcf90: "Edinburgh Portable Compiler" F90
+ # fort: Compaq (now HP) Fortran 90/95 compiler for Tru64 and Linux/Alpha
+ # ifc: Intel Fortran 95 compiler for Linux/x86
+ # efc: Intel Fortran 95 compiler for IA64
+ #
+ # The order is 95 or newer compilers first, then 90,
+ # 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
+ 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
+ )
+
+ # Vendor-specific compiler names.
+ SET(_Fortran_COMPILER_NAMES_GNU gfortran gfortran-4 g95 g77)
+ SET(_Fortran_COMPILER_NAMES_Intel ifort ifc efc)
+ SET(_Fortran_COMPILER_NAMES_Absoft af95 af90 af77)
+ SET(_Fortran_COMPILER_NAMES_PGI pgf95 pgfortran pgf90 pgf77)
+ SET(_Fortran_COMPILER_NAMES_PathScale pathf2003 pathf95 pathf90)
+ SET(_Fortran_COMPILER_NAMES_XL xlf)
+ SET(_Fortran_COMPILER_NAMES_VisualAge xlf95 xlf90 xlf)
+
+ # Prefer vendors matching the C and C++ compilers.
+ SET(CMAKE_Fortran_COMPILER_LIST
+ ${_Fortran_COMPILER_NAMES_${CMAKE_C_COMPILER_ID}}
+ ${_Fortran_COMPILER_NAMES_${CMAKE_CXX_COMPILER_ID}}
+ ${CMAKE_Fortran_COMPILER_LIST})
+ LIST(REMOVE_DUPLICATES CMAKE_Fortran_COMPILER_LIST)
+ ENDIF(CMAKE_Fortran_COMPILER_INIT)
+
+ # Look for directories containing the C and C++ compilers.
+ SET(_Fortran_COMPILER_HINTS)
+ FOREACH(lang C CXX)
+ IF(CMAKE_${lang}_COMPILER AND IS_ABSOLUTE "${CMAKE_${lang}_COMPILER}")
+ GET_FILENAME_COMPONENT(_hint "${CMAKE_${lang}_COMPILER}" PATH)
+ IF(IS_DIRECTORY "${_hint}")
+ LIST(APPEND _Fortran_COMPILER_HINTS "${_hint}")
+ ENDIF()
+ SET(_hint)
+ ENDIF()
+ ENDFOREACH()
+
+ # Find the compiler.
+ IF(_Fortran_COMPILER_HINTS)
+ # Prefer directories containing C and C++ compilers.
+ LIST(REMOVE_DUPLICATES _Fortran_COMPILER_HINTS)
+ FIND_PROGRAM(CMAKE_Fortran_COMPILER
+ NAMES ${CMAKE_Fortran_COMPILER_LIST}
+ PATHS ${_Fortran_COMPILER_HINTS}
+ NO_DEFAULT_PATH
+ DOC "Fortran compiler")
+ ENDIF()
+ FIND_PROGRAM(CMAKE_Fortran_COMPILER NAMES ${CMAKE_Fortran_COMPILER_LIST} DOC "Fortran compiler")
+ IF(CMAKE_Fortran_COMPILER_INIT AND NOT CMAKE_Fortran_COMPILER)
+ SET(CMAKE_Fortran_COMPILER "${CMAKE_Fortran_COMPILER_INIT}" CACHE FILEPATH "Fortran compiler" FORCE)
+ ENDIF(CMAKE_Fortran_COMPILER_INIT AND NOT CMAKE_Fortran_COMPILER)
+ELSE(NOT CMAKE_Fortran_COMPILER)
+ # 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("${_CMAKE_Fortran_COMPILER_LIST_LENGTH}" EQUAL 2)
+
+ # 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(CMAKE_Fortran_COMPILER_WITH_PATH)
+ ENDIF(NOT _CMAKE_USER_Fortran_COMPILER_PATH)
+ENDIF(NOT CMAKE_Fortran_COMPILER)
+
+MARK_AS_ADVANCED(CMAKE_Fortran_COMPILER)
+
+# Build a small source file to identify the compiler.
+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")
+ENDIF(${CMAKE_GENERATOR} MATCHES "Visual Studio")
+
+IF(NOT CMAKE_Fortran_COMPILER_ID_RUN)
+ SET(CMAKE_Fortran_COMPILER_ID_RUN 1)
+
+ # 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
+ # Try compiling to an object file only.
+ "-c"
+
+ # Intel on windows does not preprocess by default.
+ "-fpp"
+ )
+
+ # 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")
+ SET(CMAKE_Fortran_COMPILER_ID_VENDOR_REGEX_Compaq "Compaq Visual Fortran")
+ LIST(APPEND CMAKE_Fortran_COMPILER_ID_VENDORS NAG) # Numerical Algorithms Group
+ SET(CMAKE_Fortran_COMPILER_ID_VENDOR_FLAGS_NAG "-V")
+ SET(CMAKE_Fortran_COMPILER_ID_VENDOR_REGEX_NAG "NAG Fortran Compiler")
+
+ # Try to identify the compiler.
+ SET(CMAKE_Fortran_COMPILER_ID)
+ INCLUDE(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake)
+ CMAKE_DETERMINE_COMPILER_ID(Fortran FFLAGS CMakeFortranCompilerId.F)
+
+ # Fall back to old is-GNU test.
+ IF(NOT CMAKE_Fortran_COMPILER_ID)
+ EXEC_PROGRAM(${CMAKE_Fortran_COMPILER}
+ 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.*" )
+ 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 "
+ "the following output:\n${CMAKE_COMPILER_OUTPUT}\n\n")
+ ELSE("${CMAKE_COMPILER_OUTPUT}" MATCHES ".*THIS_IS_GNU.*" )
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "Determining if the Fortran compiler is GNU failed with "
+ "the following output:\n${CMAKE_COMPILER_OUTPUT}\n\n")
+ ENDIF("${CMAKE_COMPILER_OUTPUT}" MATCHES ".*THIS_IS_GNU.*" )
+ IF(NOT CMAKE_Fortran_PLATFORM_ID)
+ IF("${CMAKE_COMPILER_OUTPUT}" MATCHES ".*THIS_IS_MINGW.*" )
+ SET(CMAKE_Fortran_PLATFORM_ID "MinGW")
+ ENDIF("${CMAKE_COMPILER_OUTPUT}" MATCHES ".*THIS_IS_MINGW.*" )
+ IF("${CMAKE_COMPILER_OUTPUT}" MATCHES ".*THIS_IS_CYGWIN.*" )
+ SET(CMAKE_Fortran_PLATFORM_ID "Cygwin")
+ ENDIF("${CMAKE_COMPILER_OUTPUT}" MATCHES ".*THIS_IS_CYGWIN.*" )
+ ENDIF(NOT CMAKE_Fortran_PLATFORM_ID)
+ ENDIF(NOT CMAKE_COMPILER_RETURN)
+ ENDIF(NOT CMAKE_Fortran_COMPILER_ID)
+
+ # Set old compiler and platform id variables.
+ IF("${CMAKE_Fortran_COMPILER_ID}" MATCHES "GNU")
+ SET(CMAKE_COMPILER_IS_GNUG77 1)
+ ENDIF("${CMAKE_Fortran_COMPILER_ID}" MATCHES "GNU")
+ IF("${CMAKE_Fortran_PLATFORM_ID}" MATCHES "MinGW")
+ SET(CMAKE_COMPILER_IS_MINGW 1)
+ ELSEIF("${CMAKE_Fortran_PLATFORM_ID}" MATCHES "Cygwin")
+ SET(CMAKE_COMPILER_IS_CYGWIN 1)
+ ENDIF("${CMAKE_Fortran_PLATFORM_ID}" MATCHES "MinGW")
+ENDIF(NOT CMAKE_Fortran_COMPILER_ID_RUN)
+
+INCLUDE(CMakeFindBinUtils)
+
+IF(MSVC_Fortran_ARCHITECTURE_ID)
+ SET(SET_MSVC_Fortran_ARCHITECTURE_ID
+ "SET(MSVC_Fortran_ARCHITECTURE_ID ${MSVC_Fortran_ARCHITECTURE_ID})")
+ENDIF()
+# configure variables set in this file for fast reload later on
+CONFIGURE_FILE(${CMAKE_ROOT}/Modules/CMakeFortranCompiler.cmake.in
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeFortranCompiler.cmake
+ @ONLY IMMEDIATE # IMMEDIATE must be here for compatibility mode <= 2.0
+ )
+SET(CMAKE_Fortran_COMPILER_ENV_VAR "FC")
diff --git a/Modules/CMakeDetermineJavaCompiler.cmake b/Modules/CMakeDetermineJavaCompiler.cmake
new file mode 100644
index 000000000..aefcaba36
--- /dev/null
+++ b/Modules/CMakeDetermineJavaCompiler.cmake
@@ -0,0 +1,102 @@
+
+#=============================================================================
+# 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.)
+
+# determine the compiler to use for Java programs
+# NOTE, a generator may set CMAKE_Java_COMPILER before
+# loading this file to force a compiler.
+
+IF(NOT CMAKE_Java_COMPILER)
+ # prefer the environment variable CC
+ IF($ENV{JAVA_COMPILER} MATCHES ".+")
+ 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")
+ ENDIF(CMAKE_Java_FLAGS_ENV_INIT)
+ IF(NOT EXISTS ${CMAKE_Java_COMPILER_INIT})
+ MESSAGE(SEND_ERROR "Could not find compiler set in environment variable JAVA_COMPILER:\n$ENV{JAVA_COMPILER}.")
+ ENDIF(NOT EXISTS ${CMAKE_Java_COMPILER_INIT})
+ ENDIF($ENV{JAVA_COMPILER} MATCHES ".+")
+
+ IF($ENV{JAVA_RUNTIME} MATCHES ".+")
+ 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(NOT EXISTS ${CMAKE_Java_RUNTIME_INIT})
+ ENDIF($ENV{JAVA_RUNTIME} MATCHES ".+")
+
+ IF($ENV{JAVA_ARCHIVE} MATCHES ".+")
+ 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}.")
+ ENDIF(NOT EXISTS ${CMAKE_Java_ARCHIVE_INIT})
+ ENDIF($ENV{JAVA_ARCHIVE} MATCHES ".+")
+
+ SET(Java_BIN_PATH
+ "[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"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.7;JavaHome]/bin"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.6;JavaHome]/bin"
+ "[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
+ /usr/bin
+ /usr/lib/java/bin
+ /usr/share/java/bin
+ /usr/local/bin
+ /usr/local/java/bin
+ /usr/local/java/share/bin
+ /usr/java/j2sdk1.4.2_04
+ /usr/lib/j2sdk1.4-sun/bin
+ /usr/java/j2sdk1.4.2_09/bin
+ /usr/lib/j2sdk1.5-sun/bin
+ /opt/sun-jdk-1.5.0.04/bin
+ )
+ # if no compiler has been specified yet, then look for one
+ IF(CMAKE_Java_COMPILER_INIT)
+ SET(CMAKE_Java_COMPILER ${CMAKE_Java_COMPILER_INIT} CACHE PATH "Java Compiler")
+ ELSE(CMAKE_Java_COMPILER_INIT)
+ FIND_PROGRAM(CMAKE_Java_COMPILER
+ NAMES javac
+ PATHS ${Java_BIN_PATH}
+ )
+ ENDIF(CMAKE_Java_COMPILER_INIT)
+
+ # if no runtime has been specified yet, then look for one
+ IF(CMAKE_Java_RUNTIME_INIT)
+ SET(CMAKE_Java_RUNTIME ${CMAKE_Java_RUNTIME_INIT} CACHE PATH "Java Compiler")
+ ELSE(CMAKE_Java_RUNTIME_INIT)
+ FIND_PROGRAM(CMAKE_Java_RUNTIME
+ NAMES java
+ PATHS ${Java_BIN_PATH}
+ )
+ ENDIF(CMAKE_Java_RUNTIME_INIT)
+
+ # if no archive has been specified yet, then look for one
+ IF(CMAKE_Java_ARCHIVE_INIT)
+ SET(CMAKE_Java_ARCHIVE ${CMAKE_Java_ARCHIVE_INIT} CACHE PATH "Java Compiler")
+ ELSE(CMAKE_Java_ARCHIVE_INIT)
+ FIND_PROGRAM(CMAKE_Java_ARCHIVE
+ NAMES jar
+ PATHS ${Java_BIN_PATH}
+ )
+ ENDIF(CMAKE_Java_ARCHIVE_INIT)
+ENDIF(NOT CMAKE_Java_COMPILER)
+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_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeJavaCompiler.cmake IMMEDIATE @ONLY)
+SET(CMAKE_Java_COMPILER_ENV_VAR "JAVA_COMPILER")
diff --git a/Modules/CMakeDetermineRCCompiler.cmake b/Modules/CMakeDetermineRCCompiler.cmake
new file mode 100644
index 000000000..8e085af7a
--- /dev/null
+++ b/Modules/CMakeDetermineRCCompiler.cmake
@@ -0,0 +1,67 @@
+
+#=============================================================================
+# 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.)
+
+# determine the compiler to use for C programs
+# NOTE, a generator may set CMAKE_C_COMPILER before
+# loading this file to force a compiler.
+# use environment variable CCC first if defined by user, next use
+# the cmake variable CMAKE_GENERATOR_CC which can be defined by a generator
+# as a default compiler
+IF(NOT CMAKE_RC_COMPILER)
+ # prefer the environment variable CC
+ IF($ENV{RC} MATCHES ".+")
+ 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")
+ ENDIF(CMAKE_RC_FLAGS_ENV_INIT)
+ IF(EXISTS ${CMAKE_RC_COMPILER_INIT})
+ ELSE(EXISTS ${CMAKE_RC_COMPILER_INIT})
+ MESSAGE(FATAL_ERROR "Could not find compiler set in environment variable RC:\n$ENV{RC}.")
+ ENDIF(EXISTS ${CMAKE_RC_COMPILER_INIT})
+ ENDIF($ENV{RC} MATCHES ".+")
+
+ # next try prefer the compiler specified by the generator
+ IF(CMAKE_GENERATOR_RC)
+ IF(NOT CMAKE_RC_COMPILER_INIT)
+ SET(CMAKE_RC_COMPILER_INIT ${CMAKE_GENERATOR_RC})
+ ENDIF(NOT CMAKE_RC_COMPILER_INIT)
+ ENDIF(CMAKE_GENERATOR_RC)
+
+ # finally list compilers to try
+ IF(CMAKE_RC_COMPILER_INIT)
+ SET(CMAKE_RC_COMPILER_LIST ${CMAKE_RC_COMPILER_INIT})
+ ELSE(CMAKE_RC_COMPILER_INIT)
+ SET(CMAKE_RC_COMPILER_LIST rc)
+ ENDIF(CMAKE_RC_COMPILER_INIT)
+
+ # Find the compiler.
+ FIND_PROGRAM(CMAKE_RC_COMPILER NAMES ${CMAKE_RC_COMPILER_LIST} DOC "RC compiler")
+ IF(CMAKE_RC_COMPILER_INIT AND NOT CMAKE_RC_COMPILER)
+ SET(CMAKE_RC_COMPILER "${CMAKE_RC_COMPILER_INIT}" CACHE FILEPATH "RC compiler" FORCE)
+ ENDIF(CMAKE_RC_COMPILER_INIT AND NOT CMAKE_RC_COMPILER)
+ENDIF(NOT CMAKE_RC_COMPILER)
+
+MARK_AS_ADVANCED(CMAKE_RC_COMPILER)
+
+GET_FILENAME_COMPONENT(_CMAKE_RC_COMPILER_NAME_WE ${CMAKE_RC_COMPILER} NAME_WE)
+IF(_CMAKE_RC_COMPILER_NAME_WE STREQUAL "windres")
+ SET(CMAKE_RC_OUTPUT_EXTENSION .obj)
+ELSE()
+ SET(CMAKE_RC_OUTPUT_EXTENSION .res)
+ENDIF()
+
+# configure variables set in this file for fast reload later on
+CONFIGURE_FILE(${CMAKE_ROOT}/Modules/CMakeRCCompiler.cmake.in
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeRCCompiler.cmake IMMEDIATE)
+SET(CMAKE_RC_COMPILER_ENV_VAR "RC")
diff --git a/Modules/CMakeDetermineSystem.cmake b/Modules/CMakeDetermineSystem.cmake
new file mode 100644
index 000000000..7ae377517
--- /dev/null
+++ b/Modules/CMakeDetermineSystem.cmake
@@ -0,0 +1,176 @@
+
+#=============================================================================
+# 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 module is used by the Makefile generator to determin the following variables:
+# CMAKE_SYSTEM_NAME - on unix this is uname -s, for windows it is Windows
+# CMAKE_SYSTEM_VERSION - on unix this is uname -r, for windows it is empty
+# CMAKE_SYSTEM - ${CMAKE_SYSTEM}-${CMAKE_SYSTEM_VERSION}, for windows: ${CMAKE_SYSTEM}
+#
+# Expected uname -s output:
+#
+# AIX AIX
+# BSD/OS BSD/OS
+# FreeBSD FreeBSD
+# HP-UX HP-UX
+# IRIX IRIX
+# Linux Linux
+# GNU/kFreeBSD GNU/kFreeBSD
+# NetBSD NetBSD
+# OpenBSD OpenBSD
+# OFS/1 (Digital Unix) OSF1
+# SCO OpenServer 5 SCO_SV
+# SCO UnixWare 7 UnixWare
+# SCO UnixWare (pre release 7) UNIX_SV
+# SCO XENIX Xenix
+# Solaris SunOS
+# SunOS SunOS
+# Tru64 Tru64
+# Ultrix ULTRIX
+# cygwin CYGWIN_NT-5.1
+# MacOSX Darwin
+
+
+# find out on which system cmake runs
+IF(CMAKE_HOST_UNIX)
+ FIND_PROGRAM(CMAKE_UNAME uname /bin /usr/bin /usr/local/bin )
+ 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.*")
+ EXEC_PROGRAM(uname ARGS -m OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR
+ RETURN_VALUE val)
+ ELSEIF(CMAKE_HOST_SYSTEM_NAME MATCHES "OpenBSD")
+ EXEC_PROGRAM(arch ARGS -s OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR
+ RETURN_VALUE val)
+ ELSE()
+ EXEC_PROGRAM(uname ARGS -p OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR
+ RETURN_VALUE val)
+ IF("${val}" GREATER 0)
+ EXEC_PROGRAM(uname ARGS -m OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR
+ RETURN_VALUE val)
+ ENDIF("${val}" GREATER 0)
+ ENDIF()
+ # check the return of the last uname -m or -p
+ IF("${val}" GREATER 0)
+ SET(CMAKE_HOST_SYSTEM_PROCESSOR "unknown")
+ ENDIF("${val}" GREATER 0)
+ 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}")
+ ENDIF(CMAKE_UNAME)
+ELSE(CMAKE_HOST_UNIX)
+ IF(CMAKE_HOST_WIN32)
+ SET (CMAKE_HOST_SYSTEM_NAME "Windows")
+ SET (CMAKE_HOST_SYSTEM_PROCESSOR "$ENV{PROCESSOR_ARCHITECTURE}")
+ ENDIF(CMAKE_HOST_WIN32)
+ENDIF(CMAKE_HOST_UNIX)
+
+# if a toolchain file is used, the user wants to cross compile.
+# in this case read the toolchain file and keep the CMAKE_HOST_SYSTEM_*
+# variables around so they can be used in CMakeLists.txt.
+# In all other cases, the host and target platform are the same.
+IF(CMAKE_TOOLCHAIN_FILE)
+ # at first try to load it as path relative to the directory from which cmake has been run
+ INCLUDE("${CMAKE_BINARY_DIR}/${CMAKE_TOOLCHAIN_FILE}" OPTIONAL RESULT_VARIABLE _INCLUDED_TOOLCHAIN_FILE)
+ IF(NOT _INCLUDED_TOOLCHAIN_FILE)
+ # if the file isn't found there, check the default locations
+ INCLUDE("${CMAKE_TOOLCHAIN_FILE}" OPTIONAL RESULT_VARIABLE _INCLUDED_TOOLCHAIN_FILE)
+ ENDIF(NOT _INCLUDED_TOOLCHAIN_FILE)
+
+ IF(_INCLUDED_TOOLCHAIN_FILE)
+ SET(CMAKE_TOOLCHAIN_FILE "${_INCLUDED_TOOLCHAIN_FILE}" CACHE FILEPATH "The CMake toolchain file" FORCE)
+ ELSE(_INCLUDED_TOOLCHAIN_FILE)
+ MESSAGE(FATAL_ERROR "Could not find toolchain file: ${CMAKE_TOOLCHAIN_FILE}")
+ SET(CMAKE_TOOLCHAIN_FILE "NOTFOUND" CACHE FILEPATH "The CMake toolchain file" FORCE)
+ ENDIF(_INCLUDED_TOOLCHAIN_FILE)
+ENDIF(CMAKE_TOOLCHAIN_FILE)
+
+
+# if CMAKE_SYSTEM_NAME is here already set, either it comes from a toolchain file
+# or it was set via -DCMAKE_SYSTEM_NAME=...
+# if that's the case, assume we are crosscompiling
+IF(CMAKE_SYSTEM_NAME)
+ IF(NOT DEFINED CMAKE_CROSSCOMPILING)
+ SET(CMAKE_CROSSCOMPILING TRUE)
+ ENDIF(NOT DEFINED CMAKE_CROSSCOMPILING)
+ SET(PRESET_CMAKE_SYSTEM_NAME TRUE)
+ELSE(CMAKE_SYSTEM_NAME)
+ SET(CMAKE_SYSTEM_NAME "${CMAKE_HOST_SYSTEM_NAME}")
+ SET(CMAKE_SYSTEM_VERSION "${CMAKE_HOST_SYSTEM_VERSION}")
+ SET(CMAKE_SYSTEM_PROCESSOR "${CMAKE_HOST_SYSTEM_PROCESSOR}")
+ SET(CMAKE_CROSSCOMPILING FALSE)
+ SET(PRESET_CMAKE_SYSTEM_NAME FALSE)
+ENDIF(CMAKE_SYSTEM_NAME)
+
+
+MACRO(ADJUST_CMAKE_SYSTEM_VARIABLES _PREFIX)
+ IF(NOT ${_PREFIX}_NAME)
+ SET(${_PREFIX}_NAME "UnknownOS")
+ ENDIF(NOT ${_PREFIX}_NAME)
+
+ # fix for BSD/OS , remove the /
+ IF(${_PREFIX}_NAME MATCHES BSD.OS)
+ SET(${_PREFIX}_NAME BSDOS)
+ ENDIF(${_PREFIX}_NAME MATCHES BSD.OS)
+
+ # fix for GNU/kFreeBSD, remove the GNU/
+ IF(${_PREFIX}_NAME MATCHES kFreeBSD)
+ SET(${_PREFIX}_NAME kFreeBSD)
+ ENDIF(${_PREFIX}_NAME MATCHES kFreeBSD)
+
+ # fix for CYGWIN which has windows version in it
+ IF(${_PREFIX}_NAME MATCHES CYGWIN)
+ SET(${_PREFIX}_NAME CYGWIN)
+ ENDIF(${_PREFIX}_NAME MATCHES CYGWIN)
+
+ # set CMAKE_SYSTEM to the CMAKE_SYSTEM_NAME
+ SET(${_PREFIX} ${${_PREFIX}_NAME})
+ # if there is a CMAKE_SYSTEM_VERSION then add a -${CMAKE_SYSTEM_VERSION}
+ IF(${_PREFIX}_VERSION)
+ SET(${_PREFIX} ${${_PREFIX}}-${${_PREFIX}_VERSION})
+ ENDIF(${_PREFIX}_VERSION)
+
+ENDMACRO(ADJUST_CMAKE_SYSTEM_VARIABLES _PREFIX)
+
+ADJUST_CMAKE_SYSTEM_VARIABLES(CMAKE_SYSTEM)
+ADJUST_CMAKE_SYSTEM_VARIABLES(CMAKE_HOST_SYSTEM)
+
+# this file is also executed from cpack, then we don't need to generate these files
+# in this case there is no CMAKE_BINARY_DIR
+IF(CMAKE_BINARY_DIR)
+ # write entry to the log file
+ IF(PRESET_CMAKE_SYSTEM_NAME)
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "The target system is: ${CMAKE_SYSTEM_NAME} - ${CMAKE_SYSTEM_VERSION} - ${CMAKE_SYSTEM_PROCESSOR}\n")
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "The host system is: ${CMAKE_HOST_SYSTEM_NAME} - ${CMAKE_HOST_SYSTEM_VERSION} - ${CMAKE_HOST_SYSTEM_PROCESSOR}\n")
+ ELSE(PRESET_CMAKE_SYSTEM_NAME)
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "The system is: ${CMAKE_SYSTEM_NAME} - ${CMAKE_SYSTEM_VERSION} - ${CMAKE_SYSTEM_PROCESSOR}\n")
+ ENDIF(PRESET_CMAKE_SYSTEM_NAME)
+
+ # 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)
+ SET(INCLUDE_CMAKE_TOOLCHAIN_FILE_IF_REQUIRED "INCLUDE(\"${CMAKE_TOOLCHAIN_FILE}\")")
+ ENDIF(DEFINED CMAKE_TOOLCHAIN_FILE)
+
+ # 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_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeSystem.cmake
+ IMMEDIATE @ONLY)
+
+ENDIF(CMAKE_BINARY_DIR)
diff --git a/Modules/CMakeDetermineVSServicePack.cmake b/Modules/CMakeDetermineVSServicePack.cmake
new file mode 100644
index 000000000..33f01415e
--- /dev/null
+++ b/Modules/CMakeDetermineVSServicePack.cmake
@@ -0,0 +1,187 @@
+# - Includes a public function for assisting users in trying to determine the
+# Visual Studio service pack in use.
+#
+# Sets the passed in variable to one of the following values or an empty
+# string if unknown.
+# vc80
+# vc80sp1
+# vc90
+# vc90sp1
+# vc100
+# vc100sp1
+#
+# Usage:
+# ===========================
+#
+# if(MSVC)
+# include(CMakeDetermineVSServicePack)
+# DetermineVSServicePack( my_service_pack )
+#
+# if( my_service_pack )
+# message(STATUS "Detected: ${my_service_pack}")
+# endif()
+# endif()
+#
+# ===========================
+
+#=============================================================================
+# Copyright 2009-2011 Kitware, Inc.
+# Copyright 2009-2010 Philip Lowman <philip@yhbt.com>
+# Copyright 2010-2011 Aaron C. meadows <cmake@shadowguarddev.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.)
+
+# [INTERNAL]
+# Please do not call this function directly
+function(_DetermineVSServicePackFromCompiler _OUT_VAR _cl_version)
+ if (${_cl_version} VERSION_EQUAL "14.00.50727.42")
+ set(_version "vc80")
+ elseif(${_cl_version} VERSION_EQUAL "14.00.50727.762")
+ set(_version "vc80sp1")
+ elseif(${_cl_version} VERSION_EQUAL "15.00.21022.08")
+ set(_version "vc90")
+ elseif(${_cl_version} VERSION_EQUAL "15.00.30729.01")
+ set(_version "vc90sp1")
+ elseif(${_cl_version} VERSION_EQUAL "16.00.30319.01")
+ set(_version "vc100")
+ elseif(${_cl_version} VERSION_EQUAL "16.00.40219.01")
+ set(_version "vc100sp1")
+ else()
+ set(_version "")
+ endif()
+ set(${_OUT_VAR} ${_version} PARENT_SCOPE)
+endfunction()
+
+
+############################################################
+# [INTERNAL]
+# Please do not call this function directly
+function(_DetermineVSServicePack_FastCheckVersionWithCompiler _SUCCESS_VAR _VERSION_VAR)
+ if(EXISTS ${CMAKE_CXX_COMPILER})
+ execute_process(
+ COMMAND ${CMAKE_CXX_COMPILER} /?
+ ERROR_VARIABLE _output
+ 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("${_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()
+endfunction()
+
+############################################################
+# [INTERNAL]
+# Please do not call this function directly
+function(_DetermineVSServicePack_CheckVersionWithTryCompile _SUCCESS_VAR _VERSION_VAR)
+ file(WRITE "${CMAKE_BINARY_DIR}/return0.cc"
+ "int main() { return 0; }\n")
+
+ try_compile(
+ _CompileResult
+ "${CMAKE_BINARY_DIR}"
+ "${CMAKE_BINARY_DIR}/return0.cc"
+ OUTPUT_VARIABLE _output
+ COPY_FILE "${CMAKE_BINARY_DIR}/return0.cc")
+
+ 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)
+
+ set(${_SUCCESS_VAR} true PARENT_SCOPE)
+ set(${_VERSION_VAR} ${_major}.${_minor}.${_patch}.${_tweak} PARENT_SCOPE)
+ endif()
+endfunction()
+
+############################################################
+# [INTERNAL]
+# Please do not call this function directly
+function(_DetermineVSServicePack_CheckVersionWithTryRun _SUCCESS_VAR _VERSION_VAR)
+ file(WRITE "${CMAKE_BINARY_DIR}/return0.cc"
+ "#include <stdio.h>\n\nconst unsigned int CompilerVersion=_MSC_FULL_VER;\n\nint main(int argc, char* argv[])\n{\n int M( CompilerVersion/10000000);\n int m((CompilerVersion%10000000)/100000);\n int b(CompilerVersion%100000);\n\n printf(\"%d.%02d.%05d.01\",M,m,b);\n return 0;\n}\n")
+
+ try_run(
+ _RunResult
+ _CompileResult
+ "${CMAKE_BINARY_DIR}"
+ "${CMAKE_BINARY_DIR}/return0.cc"
+ RUN_OUTPUT_VARIABLE _runoutput
+ )
+
+ file(REMOVE "${CMAKE_BINARY_DIR}/return0.cc")
+
+ string(REGEX MATCH "[0-9]+.[0-9]+.[0-9]+.[0-9]+"
+ _cl_version "${_runoutput}")
+
+ if(_cl_version)
+ set(${_SUCCESS_VAR} true PARENT_SCOPE)
+ set(${_VERSION_VAR} ${_cl_version} PARENT_SCOPE)
+ endif()
+endfunction()
+
+
+#
+# A function to call to determine the Visual Studio service pack
+# in use. See documentation above.
+function(DetermineVSServicePack _pack)
+ if(NOT DETERMINED_VS_SERVICE_PACK OR NOT ${_pack})
+
+ _DetermineVSServicePack_FastCheckVersionWithCompiler(DETERMINED_VS_SERVICE_PACK _cl_version)
+ if(NOT DETERMINED_VS_SERVICE_PACK)
+ _DetermineVSServicePack_CheckVersionWithTryCompile(DETERMINED_VS_SERVICE_PACK _cl_version)
+ if(NOT DETERMINED_VS_SERVICE_PACK)
+ _DetermineVSServicePack_CheckVersionWithTryRun(DETERMINED_VS_SERVICE_PACK _cl_version)
+ endif()
+ endif()
+
+ if(DETERMINED_VS_SERVICE_PACK)
+
+ if(_cl_version)
+ # Call helper function to determine VS version
+ _DetermineVSServicePackFromCompiler(_sp "${_cl_version}")
+ if(_sp)
+ set(${_pack} ${_sp} CACHE INTERNAL
+ "The Visual Studio Release with Service Pack")
+ endif()
+ endif()
+ endif()
+ endif()
+endfunction()
+
diff --git a/Modules/CMakeExpandImportedTargets.cmake b/Modules/CMakeExpandImportedTargets.cmake
new file mode 100644
index 000000000..fba071a06
--- /dev/null
+++ b/Modules/CMakeExpandImportedTargets.cmake
@@ -0,0 +1,129 @@
+# 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}" )
+
+
+#=============================================================================
+# Copyright 2012 Kitware, Inc.
+# Copyright 2009-2012 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.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+include(CMakeParseArguments)
+
+function(CMAKE_EXPAND_IMPORTED_TARGETS _RESULT )
+
+ set(options )
+ set(oneValueArgs CONFIGURATION )
+ set(multiValueArgs LIBRARIES )
+
+ cmake_parse_arguments(CEIT "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+ if(CEIT_UNPARSED_ARGUMENTS)
+ message(FATAL_ERROR "Unknown keywords given to CMAKE_EXPAND_IMPORTED_TARGETS(): \"${CEIT_UNPARSED_ARGUMENTS}\"")
+ endif()
+
+ if(NOT CEIT_CONFIGURATION)
+ if(CMAKE_CONFIGURATION_TYPES)
+ list(GET CMAKE_CONFIGURATION_TYPES 0 CEIT_CONFIGURATION)
+ else()
+ set(CEIT_CONFIGURATION ${CMAKE_BUILD_TYPE})
+ endif()
+ endif()
+
+ # handle imported library targets
+
+ set(_CCSR_REQ_LIBS ${CEIT_LIBRARIES})
+
+ set(_CHECK_FOR_IMPORTED_TARGETS TRUE)
+ set(_CCSR_LOOP_COUNTER 0)
+ while(_CHECK_FOR_IMPORTED_TARGETS)
+ math(EXPR _CCSR_LOOP_COUNTER "${_CCSR_LOOP_COUNTER} + 1 ")
+ 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 (_importedConfigs)
+# message(STATUS "Detected imported target ${_CURRENT_LIB}")
+ # Ok, so this is an imported target.
+ # First we get the imported configurations.
+ # Then we get the location of the actual library on disk of the first configuration.
+ # then we'll get its link interface libraries property,
+ # iterate through it and replace all imported targets we find there
+ # with there actual location.
+
+ # guard against infinite loop: abort after 100 iterations ( 100 is arbitrary chosen)
+ if ("${_CCSR_LOOP_COUNTER}" LESS 100)
+ set(_CHECK_FOR_IMPORTED_TARGETS TRUE)
+# else ("${_CCSR_LOOP_COUNTER}" LESS 1)
+# message(STATUS "********* aborting loop, counter : ${_CCSR_LOOP_COUNTER}")
+ endif ("${_CCSR_LOOP_COUNTER}" LESS 100)
+
+ # if one of the imported configurations equals ${CMAKE_TRY_COMPILE_CONFIGURATION},
+ # use it, otherwise simply use the first one:
+ list(FIND _importedConfigs "${CEIT_CONFIGURATION}" _configIndexToUse)
+ if("${_configIndexToUse}" EQUAL -1)
+ set(_configIndexToUse 0)
+ endif("${_configIndexToUse}" EQUAL -1)
+ list(GET _importedConfigs ${_configIndexToUse} _importedConfigToUse)
+
+ get_target_property(_importedLocation "${_CURRENT_LIB}" IMPORTED_LOCATION_${_importedConfigToUse})
+ get_target_property(_linkInterfaceLibs "${_CURRENT_LIB}" IMPORTED_LINK_INTERFACE_LIBRARIES_${_importedConfigToUse} )
+
+ list(APPEND _CCSR_NEW_REQ_LIBS "${_importedLocation}")
+# message(STATUS "Appending lib ${_CURRENT_LIB} as ${_importedLocation}")
+ if(_linkInterfaceLibs)
+ foreach(_currentLinkInterfaceLib ${_linkInterfaceLibs})
+# message(STATUS "Appending link interface lib ${_currentLinkInterfaceLib}")
+ if(_currentLinkInterfaceLib)
+ list(APPEND _CCSR_NEW_REQ_LIBS "${_currentLinkInterfaceLib}" )
+ endif(_currentLinkInterfaceLib)
+ endforeach(_currentLinkInterfaceLib "${_linkInterfaceLibs}")
+ endif(_linkInterfaceLibs)
+ else(_importedConfigs)
+ # "Normal" libraries are just used as they are.
+ list(APPEND _CCSR_NEW_REQ_LIBS "${_CURRENT_LIB}" )
+# message(STATUS "Appending lib directly: ${_CURRENT_LIB}")
+ endif(_importedConfigs)
+ endforeach(_CURRENT_LIB ${_CCSR_REQ_LIBS})
+
+ set(_CCSR_REQ_LIBS ${_CCSR_NEW_REQ_LIBS} )
+ endwhile(_CHECK_FOR_IMPORTED_TARGETS)
+
+ # Finally we iterate once more over all libraries. This loop only removes
+ # 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 (NOT _importedConfigs)
+ list(APPEND _CCSR_NEW_REQ_LIBS "${_CURRENT_LIB}" )
+# message(STATUS "final: appending ${_CURRENT_LIB}")
+ else (NOT _importedConfigs)
+# message(STATUS "final: skipping ${_CURRENT_LIB}")
+ endif (NOT _importedConfigs)
+ endforeach(_CURRENT_LIB ${_CCSR_REQ_LIBS})
+# message(STATUS "setting -${_RESULT}- to -${_CCSR_NEW_REQ_LIBS}-")
+ set(${_RESULT} "${_CCSR_NEW_REQ_LIBS}" PARENT_SCOPE)
+
+endfunction()
diff --git a/Modules/CMakeExportBuildSettings.cmake b/Modules/CMakeExportBuildSettings.cmake
new file mode 100644
index 000000000..8d316b941
--- /dev/null
+++ b/Modules/CMakeExportBuildSettings.cmake
@@ -0,0 +1,36 @@
+
+#=============================================================================
+# 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 module is purposely no longer documented. It does nothing useful.
+IF(NOT "${CMAKE_MINIMUM_REQUIRED_VERSION}" VERSION_LESS 2.7)
+ MESSAGE(FATAL_ERROR
+ "The functionality of this module has been dropped as of CMake 2.8. "
+ "It was deemed harmful (confusing users by changing their compiler). "
+ "Please remove calls to the CMAKE_EXPORT_BUILD_SETTINGS macro and "
+ "stop including this module. "
+ "If this project generates any files for use by external projects, "
+ "remove any use of the CMakeImportBuildSettings module from them.")
+ENDIF()
+
+# This macro used to store build settings of a project in a file to be
+# 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 ".+")
+ CONFIGURE_FILE(${CMAKE_ROOT}/Modules/CMakeBuildSettings.cmake.in
+ ${SETTINGS_FILE} @ONLY IMMEDIATE)
+ ELSE(${SETTINGS_FILE} MATCHES ".+")
+ MESSAGE(SEND_ERROR "CMAKE_EXPORT_BUILD_SETTINGS called with no argument.")
+ ENDIF(${SETTINGS_FILE} MATCHES ".+")
+ENDMACRO(CMAKE_EXPORT_BUILD_SETTINGS)
diff --git a/Modules/CMakeExtraGeneratorDetermineCompilerMacrosAndIncludeDirs.cmake b/Modules/CMakeExtraGeneratorDetermineCompilerMacrosAndIncludeDirs.cmake
new file mode 100644
index 000000000..455f95fe3
--- /dev/null
+++ b/Modules/CMakeExtraGeneratorDetermineCompilerMacrosAndIncludeDirs.cmake
@@ -0,0 +1,109 @@
+
+#=============================================================================
+# 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 by CMakeFindEclipseCDT4.cmake and CMakeFindCodeBlocks.cmake
+
+# The Eclipse and the CodeBlocks generators need to know the standard include path
+# so that they can find the headers at runtime and parsing etc. works better
+# This is done here by actually running gcc with the options so it prints its
+# system include directories, which are parsed then and stored in the cache.
+MACRO(_DETERMINE_GCC_SYSTEM_INCLUDE_DIRS _lang _resultIncludeDirs _resultDefines)
+ SET(${_resultIncludeDirs})
+ SET(_gccOutput)
+ FILE(WRITE "${CMAKE_BINARY_DIR}/CMakeFiles/dummy" "\n" )
+
+ IF (${_lang} STREQUAL "c++")
+ SET(_compilerExecutable "${CMAKE_CXX_COMPILER}")
+ SET(_arg1 "${CMAKE_CXX_COMPILER_ARG1}")
+ ELSE ()
+ SET(_compilerExecutable "${CMAKE_C_COMPILER}")
+ SET(_arg1 "${CMAKE_C_COMPILER_ARG1}")
+ ENDIF ()
+ EXECUTE_PROCESS(COMMAND ${_compilerExecutable} ${_arg1} -v -E -x ${_lang} -dD dummy
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/CMakeFiles
+ ERROR_VARIABLE _gccOutput
+ OUTPUT_VARIABLE _gccStdout )
+ FILE(REMOVE "${CMAKE_BINARY_DIR}/CMakeFiles/dummy")
+
+ # First find the system include dirs:
+ IF( "${_gccOutput}" MATCHES "> search starts here[^\n]+\n *(.+ *\n) *End of (search) list" )
+
+ # split the output into lines and then remove leading and trailing spaces from each of them:
+ STRING(REGEX MATCHALL "[^\n]+\n" _includeLines "${CMAKE_MATCH_1}")
+ FOREACH(nextLine ${_includeLines})
+ STRING(STRIP "${nextLine}" _includePath)
+ LIST(APPEND ${_resultIncludeDirs} "${_includePath}")
+ ENDFOREACH(nextLine)
+
+ ENDIF()
+
+
+ # now find the builtin macros:
+ STRING(REGEX MATCHALL "#define[^\n]+\n" _defineLines "${_gccStdout}")
+# A few example lines which the regexp below has to match properly:
+# #define MAX(a,b) ((a) > (b) ? (a) : (b))
+# #define __fastcall __attribute__((__fastcall__))
+# #define FOO (23)
+# #define __UINTMAX_TYPE__ long long unsigned int
+# #define __UINTMAX_TYPE__ long long unsigned int
+# #define __i386__ 1
+
+ FOREACH(nextLine ${_defineLines})
+ STRING(REGEX MATCH "^#define +([A-Za-z_][A-Za-z0-9_]*)(\\([^\\)]+\\))? +(.+) *$" _dummy "${nextLine}")
+ SET(_name "${CMAKE_MATCH_1}${CMAKE_MATCH_2}")
+ STRING(STRIP "${CMAKE_MATCH_3}" _value)
+ #MESSAGE(STATUS "m1: -${CMAKE_MATCH_1}- m2: -${CMAKE_MATCH_2}- m3: -${CMAKE_MATCH_3}-")
+
+ LIST(APPEND ${_resultDefines} "${_name}")
+ IF(_value)
+ LIST(APPEND ${_resultDefines} "${_value}")
+ ELSE()
+ LIST(APPEND ${_resultDefines} " ")
+ ENDIF()
+ ENDFOREACH(nextLine)
+
+ENDMACRO(_DETERMINE_GCC_SYSTEM_INCLUDE_DIRS _lang)
+
+# Save the current LC_ALL, LC_MESSAGES, and LANG environment variables and set them
+# to "C" that way GCC's "search starts here" text is in English and we can grok it.
+SET(_orig_lc_all $ENV{LC_ALL})
+SET(_orig_lc_messages $ENV{LC_MESSAGES})
+SET(_orig_lang $ENV{LANG})
+
+SET(ENV{LC_ALL} C)
+SET(ENV{LC_MESSAGES} C)
+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)
+ _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")
+ ENDIF ()
+ENDIF ()
+
+# And now the same for C++
+IF (NOT CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_INCLUDE_DIRS)
+ IF ("${CMAKE_CXX_COMPILER_ID}" MATCHES GNU OR "${CMAKE_CXX_COMPILER_ID}" MATCHES Intel)
+ _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")
+ ENDIF ()
+ENDIF ()
+
+# Restore original LC_ALL, LC_MESSAGES, and LANG
+SET(ENV{LC_ALL} ${_orig_lc_all})
+SET(ENV{LC_MESSAGES} ${_orig_lc_messages})
+SET(ENV{LANG} ${_orig_lang})
diff --git a/Modules/CMakeFindBinUtils.cmake b/Modules/CMakeFindBinUtils.cmake
new file mode 100644
index 000000000..64ec403ad
--- /dev/null
+++ b/Modules/CMakeFindBinUtils.cmake
@@ -0,0 +1,75 @@
+
+# search for additional tools required for C/C++ (and other languages ?)
+#
+# If the internal cmake variable _CMAKE_TOOLCHAIN_PREFIX is set, this is used
+# as prefix for the tools (e.g. arm-elf-gcc etc.)
+# If the cmake variable _CMAKE_TOOLCHAIN_LOCATION is set, the compiler is
+# searched only there. The other tools are at first searched there, then
+# also in the default locations.
+#
+# Sets the following variables:
+# CMAKE_AR
+# CMAKE_RANLIB
+# CMAKE_LINKER
+# CMAKE_STRIP
+# CMAKE_INSTALL_NAME_TOOL
+
+# on UNIX, cygwin and mingw
+
+#=============================================================================
+# 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.)
+
+# 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")
+
+ FIND_PROGRAM(CMAKE_LINKER NAMES link HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
+
+ MARK_AS_ADVANCED(CMAKE_LINKER)
+
+# in all other cases search for ar, ranlib, etc.
+ELSE("${CMAKE_CXX_COMPILER_ID}" MATCHES "MSVC"
+ OR "${CMAKE_C_COMPILER_ID}" MATCHES "MSVC"
+ OR "${CMAKE_GENERATOR}" MATCHES "Visual Studio")
+
+ FIND_PROGRAM(CMAKE_AR NAMES ${_CMAKE_TOOLCHAIN_PREFIX}ar HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
+
+ FIND_PROGRAM(CMAKE_RANLIB NAMES ${_CMAKE_TOOLCHAIN_PREFIX}ranlib HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
+ IF(NOT CMAKE_RANLIB)
+ SET(CMAKE_RANLIB : CACHE INTERNAL "noop for ranlib")
+ ENDIF(NOT CMAKE_RANLIB)
+
+ FIND_PROGRAM(CMAKE_STRIP NAMES ${_CMAKE_TOOLCHAIN_PREFIX}strip HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
+ FIND_PROGRAM(CMAKE_LINKER NAMES ${_CMAKE_TOOLCHAIN_PREFIX}ld HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
+ FIND_PROGRAM(CMAKE_NM NAMES ${_CMAKE_TOOLCHAIN_PREFIX}nm HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
+ FIND_PROGRAM(CMAKE_OBJDUMP NAMES ${_CMAKE_TOOLCHAIN_PREFIX}objdump HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
+ FIND_PROGRAM(CMAKE_OBJCOPY NAMES ${_CMAKE_TOOLCHAIN_PREFIX}objcopy HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
+
+ MARK_AS_ADVANCED(CMAKE_AR CMAKE_RANLIB CMAKE_STRIP CMAKE_LINKER CMAKE_NM CMAKE_OBJDUMP CMAKE_OBJCOPY)
+
+ENDIF("${CMAKE_CXX_COMPILER_ID}" MATCHES "MSVC"
+ OR "${CMAKE_C_COMPILER_ID}" MATCHES "MSVC"
+ OR "${CMAKE_GENERATOR}" MATCHES "Visual Studio")
+
+
+# on Apple there really should be install_name_tool
+IF(APPLE)
+ FIND_PROGRAM(CMAKE_INSTALL_NAME_TOOL NAMES install_name_tool HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
+
+ IF(NOT CMAKE_INSTALL_NAME_TOOL)
+ MESSAGE(FATAL_ERROR "Could not find install_name_tool, please check your installation.")
+ ENDIF(NOT CMAKE_INSTALL_NAME_TOOL)
+
+ MARK_AS_ADVANCED(CMAKE_INSTALL_NAME_TOOL)
+ENDIF(APPLE)
diff --git a/Modules/CMakeFindCodeBlocks.cmake b/Modules/CMakeFindCodeBlocks.cmake
new file mode 100644
index 000000000..23f2c821d
--- /dev/null
+++ b/Modules/CMakeFindCodeBlocks.cmake
@@ -0,0 +1,25 @@
+
+#=============================================================================
+# 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 CodeBlocks extra generator has been selected.
+
+FIND_PROGRAM(CMAKE_CODEBLOCKS_EXECUTABLE NAMES codeblocks DOC "The CodeBlocks executable")
+
+IF(CMAKE_CODEBLOCKS_EXECUTABLE)
+ SET(CMAKE_OPEN_PROJECT_COMMAND "${CMAKE_CODEBLOCKS_EXECUTABLE} <PROJECT_FILE>" )
+ENDIF(CMAKE_CODEBLOCKS_EXECUTABLE)
+
+# Determine builtin macros and include dirs:
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/CMakeExtraGeneratorDetermineCompilerMacrosAndIncludeDirs.cmake)
diff --git a/Modules/CMakeFindEclipseCDT4.cmake b/Modules/CMakeFindEclipseCDT4.cmake
new file mode 100644
index 000000000..a4264e78e
--- /dev/null
+++ b/Modules/CMakeFindEclipseCDT4.cmake
@@ -0,0 +1,79 @@
+
+#=============================================================================
+# 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.
+
+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("${_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" )
+ SET(_ECLIPSE_VERSION_NAME_3.2 "Callisto" )
+ SET(_ECLIPSE_VERSION_NAME_3.3 "Europa" )
+ SET(_ECLIPSE_VERSION_NAME_3.4 "Ganymede" )
+ SET(_ECLIPSE_VERSION_NAME_3.5 "Galileo" )
+ SET(_ECLIPSE_VERSION_NAME_3.6 "Helios" )
+ SET(_ECLIPSE_VERSION_NAME_3.7 "Indigo" )
+
+ 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()
+
+ 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})"
+ "3.5 (${_ECLIPSE_VERSION_NAME_3.5})"
+ "3.6 (${_ECLIPSE_VERSION_NAME_3.6})"
+ "3.7 (${_ECLIPSE_VERSION_NAME_3.7})")
+ENDFUNCTION()
+
+_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)
+
+# 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)
+ SET(_CMAKE_ECLIPSE_INITIAL_MAKE_ARGS "-j${_CMAKE_ECLIPSE_PROCESSOR_COUNT}")
+ENDIF()
+
+# This variable is used by the Eclipse generator and appended to the make invocation commands.
+SET(CMAKE_ECLIPSE_MAKE_ARGUMENTS "${_CMAKE_ECLIPSE_INITIAL_MAKE_ARGS}" CACHE STRING "Additional command line arguments when Eclipse invokes make. Enter e.g. -j<some_number> to get parallel builds")
+
+# This variable is used by the Eclipse generator in out-of-source builds only.
+SET(CMAKE_ECLIPSE_GENERATE_SOURCE_PROJECT FALSE CACHE BOOL "If enabled, CMake will generate a source project for Eclipse in CMAKE_SOURCE_DIR")
+MARK_AS_ADVANCED(CMAKE_ECLIPSE_GENERATE_SOURCE_PROJECT)
+
+# Determine builtin macros and include dirs:
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/CMakeExtraGeneratorDetermineCompilerMacrosAndIncludeDirs.cmake)
diff --git a/Modules/CMakeFindFrameworks.cmake b/Modules/CMakeFindFrameworks.cmake
new file mode 100644
index 000000000..001da20f3
--- /dev/null
+++ b/Modules/CMakeFindFrameworks.cmake
@@ -0,0 +1,32 @@
+# - helper module to find OSX frameworks
+
+#=============================================================================
+# 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.)
+
+IF(NOT CMAKE_FIND_FRAMEWORKS_INCLUDED)
+ SET(CMAKE_FIND_FRAMEWORKS_INCLUDED 1)
+ MACRO(CMAKE_FIND_FRAMEWORKS fwk)
+ SET(${fwk}_FRAMEWORKS)
+ IF(APPLE)
+ FOREACH(dir
+ ~/Library/Frameworks/${fwk}.framework
+ /Library/Frameworks/${fwk}.framework
+ /System/Library/Frameworks/${fwk}.framework
+ /Network/Library/Frameworks/${fwk}.framework)
+ IF(EXISTS ${dir})
+ SET(${fwk}_FRAMEWORKS ${${fwk}_FRAMEWORKS} ${dir})
+ ENDIF(EXISTS ${dir})
+ ENDFOREACH(dir)
+ ENDIF(APPLE)
+ ENDMACRO(CMAKE_FIND_FRAMEWORKS)
+ENDIF(NOT CMAKE_FIND_FRAMEWORKS_INCLUDED)
diff --git a/Modules/CMakeFindKDevelop3.cmake b/Modules/CMakeFindKDevelop3.cmake
new file mode 100644
index 000000000..331dc6ef9
--- /dev/null
+++ b/Modules/CMakeFindKDevelop3.cmake
@@ -0,0 +1,23 @@
+
+#=============================================================================
+# 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 KDevelop3 extra generator has been selected.
+
+FIND_PROGRAM(CMAKE_KDEVELOP3_EXECUTABLE NAMES kdevelop DOC "The KDevelop3 executable")
+
+IF(CMAKE_KDEVELOP3_EXECUTABLE)
+ SET(CMAKE_OPEN_PROJECT_COMMAND "${CMAKE_KDEVELOP3_EXECUTABLE} <PROJECT_FILE>" )
+ENDIF(CMAKE_KDEVELOP3_EXECUTABLE)
+
diff --git a/Modules/CMakeFindPackageMode.cmake b/Modules/CMakeFindPackageMode.cmake
new file mode 100644
index 000000000..59c7ba5ee
--- /dev/null
+++ b/Modules/CMakeFindPackageMode.cmake
@@ -0,0 +1,188 @@
+# 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 existance 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>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software 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(NOT NAME)
+ message(FATAL_ERROR "Name of the package to be searched not specified. Set the CMake variable NAME, e.g. -DNAME=JPEG .")
+endif()
+
+if(NOT COMPILER_ID)
+ message(FATAL_ERROR "COMPILER_ID argument not specified. In doubt, use GNU.")
+endif()
+
+if(NOT LANGUAGE)
+ message(FATAL_ERROR "LANGUAGE argument not specified. Use C, CXX or Fortran.")
+endif()
+
+if(NOT MODE)
+ message(FATAL_ERROR "MODE argument not specified. Use either EXIST, COMPILE or LINK.")
+endif()
+
+# require the current version. If we don't do this, Platforms/CYGWIN.cmake complains because
+# it doesn't know whether it should set WIN32 or not:
+cmake_minimum_required(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION} )
+
+macro(ENABLE_LANGUAGE)
+ # disable the enable_language() command, otherwise --find-package breaks on Windows.
+ # On Windows, enable_language(RC) is called in the platform files unconditionally.
+ # But in --find-package mode, we don't want (and can't) enable any language.
+endmacro()
+
+include(CMakeDetermineSystem)
+
+# short-cut some tests on Darwin, see Darwin-GNU.cmake:
+if("${CMAKE_SYSTEM_NAME}" MATCHES Darwin AND "${COMPILER_ID}" MATCHES GNU)
+ set(${CMAKE_${LANGUAGE}_HAS_ISYSROOT} 0 )
+ set(CMAKE_${lang}_OSX_DEPLOYMENT_TARGET_FLAG "")
+endif()
+
+# Also load the system specific file, which sets up e.g. the search paths.
+# This makes the FIND_XXX() calls work much better
+include(CMakeSystemSpecificInformation)
+
+if(UNIX)
+
+ # try to guess whether we have a 64bit system, if it has not been set
+ # from the outside
+ if(NOT CMAKE_SIZEOF_VOID_P)
+ set(CMAKE_SIZEOF_VOID_P 4)
+ if(EXISTS /usr/lib64)
+ set(CMAKE_SIZEOF_VOID_P 8)
+ else()
+ # use the file utility to check whether itself is 64 bit:
+ find_program(FILE_EXECUTABLE file)
+ if(FILE_EXECUTABLE)
+ get_filename_component(FILE_ABSPATH "${FILE_EXECUTABLE}" ABSOLUTE)
+ execute_process(COMMAND "${FILE_ABSPATH}" "${FILE_ABSPATH}" OUTPUT_VARIABLE fileOutput ERROR_QUIET)
+ if("${fileOutput}" MATCHES "64-bit")
+ set(CMAKE_SIZEOF_VOID_P 8)
+ endif()
+ endif()
+ endif()
+ endif()
+
+ # guess Debian multiarch if it has not been set:
+ if(EXISTS /etc/debian_version)
+ if(NOT CMAKE_${LANGUAGE}_LANGUAGE_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})
+ break()
+ endif()
+ endforeach()
+ endif()
+ endif()
+
+endif()
+
+set(CMAKE_${LANGUAGE}_COMPILER "dummy")
+set(CMAKE_${LANGUAGE}_COMPILER_ID "${COMPILER_ID}")
+include(CMake${LANGUAGE}Information)
+
+
+function(set_compile_flags_var _packageName)
+ string(TOUPPER "${_packageName}" PACKAGE_NAME)
+ # Check the following variables:
+ # FOO_INCLUDE_DIRS
+ # Foo_INCLUDE_DIRS
+ # FOO_INCLUDES
+ # Foo_INCLUDES
+ # FOO_INCLUDE_DIR
+ # Foo_INCLUDE_DIR
+ set(includes)
+ if(DEFINED ${_packageName}_INCLUDE_DIRS)
+ set(includes ${_packageName}_INCLUDE_DIRS)
+ elseif(DEFINED ${PACKAGE_NAME}_INCLUDE_DIRS)
+ set(includes ${PACKAGE_NAME}_INCLUDE_DIRS)
+ elseif(DEFINED ${_packageName}_INCLUDES)
+ set(includes ${_packageName}_INCLUDES)
+ elseif(DEFINED ${PACKAGE_NAME}_INCLUDES)
+ set(includes ${PACKAGE_NAME}_INCLUDES)
+ elseif(DEFINED ${_packageName}_INCLUDE_DIR)
+ set(includes ${_packageName}_INCLUDE_DIR)
+ elseif(DEFINED ${PACKAGE_NAME}_INCLUDE_DIR)
+ set(includes ${PACKAGE_NAME}_INCLUDE_DIR)
+ endif()
+
+ set(PACKAGE_INCLUDE_DIRS "${${includes}}" PARENT_SCOPE)
+
+ # Check the following variables:
+ # FOO_DEFINITIONS
+ # Foo_DEFINITIONS
+ set(definitions)
+ if(DEFINED ${_packageName}_DEFINITIONS)
+ set(definitions ${_packageName}_DEFINITIONS)
+ elseif(DEFINED ${PACKAGE_NAME}_DEFINITIONS)
+ set(definitions ${PACKAGE_NAME}_DEFINITIONS)
+ endif()
+
+ set(PACKAGE_DEFINITIONS "${${definitions}}" )
+
+endfunction()
+
+
+function(set_link_flags_var _packageName)
+ string(TOUPPER "${_packageName}" PACKAGE_NAME)
+ # Check the following variables:
+ # FOO_LIBRARIES
+ # Foo_LIBRARIES
+ # FOO_LIBS
+ # Foo_LIBS
+ set(libs)
+ if(DEFINED ${_packageName}_LIBRARIES)
+ set(libs ${_packageName}_LIBRARIES)
+ elseif(DEFINED ${PACKAGE_NAME}_LIBRARIES)
+ set(libs ${PACKAGE_NAME}_LIBRARIES)
+ elseif(DEFINED ${_packageName}_LIBS)
+ set(libs ${_packageName}_LIBS)
+ elseif(DEFINED ${PACKAGE_NAME}_LIBS)
+ set(libs ${PACKAGE_NAME}_LIBS)
+ endif()
+
+ set(PACKAGE_LIBRARIES "${${libs}}" PARENT_SCOPE )
+
+endfunction()
+
+
+find_package("${NAME}" QUIET)
+
+set(PACKAGE_FOUND FALSE)
+
+string(TOUPPER "${NAME}" UPPERCASE_NAME)
+
+if(${NAME}_FOUND OR ${UPPERCASE_NAME}_FOUND)
+ set(PACKAGE_FOUND TRUE)
+
+ if("${MODE}" STREQUAL "EXIST")
+ # do nothing
+ elseif("${MODE}" STREQUAL "COMPILE")
+ set_compile_flags_var(${NAME})
+ elseif("${MODE}" STREQUAL "LINK")
+ set_link_flags_var(${NAME})
+ else("${MODE}" STREQUAL "LINK")
+ message(FATAL_ERROR "Invalid mode argument ${MODE} given.")
+ endif()
+
+endif()
+
+set(PACKAGE_QUIET ${SILENT} )
diff --git a/Modules/CMakeFindWMake.cmake b/Modules/CMakeFindWMake.cmake
new file mode 100644
index 000000000..6972c4c40
--- /dev/null
+++ b/Modules/CMakeFindWMake.cmake
@@ -0,0 +1,17 @@
+
+#=============================================================================
+# Copyright 2006-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.)
+
+SET (CMAKE_MAKE_PROGRAM "wmake" CACHE STRING
+ "Program used to build from makefiles.")
+MARK_AS_ADVANCED(CMAKE_MAKE_PROGRAM)
diff --git a/Modules/CMakeFindXCode.cmake b/Modules/CMakeFindXCode.cmake
new file mode 100644
index 000000000..53967b52a
--- /dev/null
+++ b/Modules/CMakeFindXCode.cmake
@@ -0,0 +1,20 @@
+
+#=============================================================================
+# 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.)
+
+FIND_PROGRAM(CMAKE_MAKE_PROGRAM
+ NAMES xcodebuild
+ PATHS
+ /usr/bin
+ )
+MARK_AS_ADVANCED(CMAKE_MAKE_PROGRAM)
diff --git a/Modules/CMakeForceCompiler.cmake b/Modules/CMakeForceCompiler.cmake
new file mode 100644
index 000000000..2a839fd93
--- /dev/null
+++ b/Modules/CMakeForceCompiler.cmake
@@ -0,0 +1,82 @@
+# This module defines macros intended for use by cross-compiling
+# toolchain files when CMake is not able to automatically detect the
+# compiler identification.
+#
+# 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.
+#
+# Macro CMAKE_FORCE_CXX_COMPILER has the following signature:
+# 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
+# information tests.
+#
+# Macro CMAKE_FORCE_Fortran_COMPILER has the following signature:
+# 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)
+
+#=============================================================================
+# 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.)
+
+MACRO(CMAKE_FORCE_C_COMPILER compiler id)
+ SET(CMAKE_C_COMPILER "${compiler}")
+ SET(CMAKE_C_COMPILER_ID_RUN TRUE)
+ SET(CMAKE_C_COMPILER_ID ${id})
+ SET(CMAKE_C_COMPILER_WORKS TRUE)
+ SET(CMAKE_C_COMPILER_FORCED TRUE)
+
+ # Set old compiler id variables.
+ IF("${CMAKE_C_COMPILER_ID}" MATCHES "GNU")
+ SET(CMAKE_COMPILER_IS_GNUCC 1)
+ ENDIF("${CMAKE_C_COMPILER_ID}" MATCHES "GNU")
+ENDMACRO(CMAKE_FORCE_C_COMPILER)
+
+MACRO(CMAKE_FORCE_CXX_COMPILER compiler id)
+ SET(CMAKE_CXX_COMPILER "${compiler}")
+ SET(CMAKE_CXX_COMPILER_ID_RUN TRUE)
+ SET(CMAKE_CXX_COMPILER_ID ${id})
+ SET(CMAKE_CXX_COMPILER_WORKS TRUE)
+ SET(CMAKE_CXX_COMPILER_FORCED TRUE)
+
+ # Set old compiler id variables.
+ IF("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
+ SET(CMAKE_COMPILER_IS_GNUCXX 1)
+ ENDIF("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
+ENDMACRO(CMAKE_FORCE_CXX_COMPILER)
+
+MACRO(CMAKE_FORCE_Fortran_COMPILER compiler id)
+ SET(CMAKE_Fortran_COMPILER "${compiler}")
+ SET(CMAKE_Fortran_COMPILER_ID_RUN TRUE)
+ SET(CMAKE_Fortran_COMPILER_ID ${id})
+ SET(CMAKE_Fortran_COMPILER_WORKS TRUE)
+ SET(CMAKE_Fortran_COMPILER_FORCED TRUE)
+
+ # Set old compiler id variables.
+ IF("${CMAKE_Fortran_COMPILER_ID}" MATCHES "GNU")
+ SET(CMAKE_COMPILER_IS_GNUG77 1)
+ ENDIF("${CMAKE_Fortran_COMPILER_ID}" MATCHES "GNU")
+ENDMACRO(CMAKE_FORCE_Fortran_COMPILER)
diff --git a/Modules/CMakeFortranCompiler.cmake.in b/Modules/CMakeFortranCompiler.cmake.in
new file mode 100644
index 000000000..53d95525f
--- /dev/null
+++ b/Modules/CMakeFortranCompiler.cmake.in
@@ -0,0 +1,52 @@
+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_PLATFORM_ID "@CMAKE_Fortran_PLATFORM_ID@")
+@SET_MSVC_Fortran_ARCHITECTURE_ID@
+SET(CMAKE_AR "@CMAKE_AR@")
+SET(CMAKE_RANLIB "@CMAKE_RANLIB@")
+SET(CMAKE_COMPILER_IS_GNUG77 @CMAKE_COMPILER_IS_GNUG77@)
+SET(CMAKE_Fortran_COMPILER_LOADED 1)
+SET(CMAKE_COMPILER_IS_MINGW @CMAKE_COMPILER_IS_MINGW@)
+SET(CMAKE_COMPILER_IS_CYGWIN @CMAKE_COMPILER_IS_CYGWIN@)
+IF(CMAKE_COMPILER_IS_CYGWIN)
+ SET(CYGWIN 1)
+ SET(UNIX 1)
+ENDIF(CMAKE_COMPILER_IS_CYGWIN)
+
+SET(CMAKE_Fortran_COMPILER_ENV_VAR "FC")
+
+SET(CMAKE_Fortran_COMPILER_SUPPORTS_F90 @CMAKE_Fortran_COMPILER_SUPPORTS_F90@)
+
+IF(CMAKE_COMPILER_IS_MINGW)
+ SET(MINGW 1)
+ENDIF(CMAKE_COMPILER_IS_MINGW)
+SET(CMAKE_Fortran_COMPILER_ID_RUN 1)
+SET(CMAKE_Fortran_SOURCE_FILE_EXTENSIONS f;F;f77;F77;f90;F90;for;For;FOR;f95;F95)
+SET(CMAKE_Fortran_IGNORE_EXTENSIONS h;H;o;O;obj;OBJ;def;DEF;rc;RC)
+SET(CMAKE_Fortran_LINKER_PREFERENCE 20)
+IF(UNIX)
+ SET(CMAKE_Fortran_OUTPUT_EXTENSION .o)
+ELSE(UNIX)
+ SET(CMAKE_Fortran_OUTPUT_EXTENSION .obj)
+ENDIF(UNIX)
+
+# Save compiler ABI information.
+SET(CMAKE_Fortran_SIZEOF_DATA_PTR "@CMAKE_Fortran_SIZEOF_DATA_PTR@")
+SET(CMAKE_Fortran_COMPILER_ABI "@CMAKE_Fortran_COMPILER_ABI@")
+SET(CMAKE_Fortran_LIBRARY_ARCHITECTURE "@CMAKE_Fortran_LIBRARY_ARCHITECTURE@")
+
+IF(CMAKE_Fortran_SIZEOF_DATA_PTR AND NOT CMAKE_SIZEOF_VOID_P)
+ SET(CMAKE_SIZEOF_VOID_P "${CMAKE_Fortran_SIZEOF_DATA_PTR}")
+ENDIF()
+
+IF(CMAKE_Fortran_COMPILER_ABI)
+ SET(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_Fortran_COMPILER_ABI}")
+ENDIF(CMAKE_Fortran_COMPILER_ABI)
+
+IF(CMAKE_Fortran_LIBRARY_ARCHITECTURE)
+ SET(CMAKE_LIBRARY_ARCHITECTURE "@CMAKE_Fortran_LIBRARY_ARCHITECTURE@")
+ENDIF()
+
+SET(CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES "@CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES@")
+SET(CMAKE_Fortran_IMPLICIT_LINK_DIRECTORIES "@CMAKE_Fortran_IMPLICIT_LINK_DIRECTORIES@")
diff --git a/Modules/CMakeFortranCompilerABI.F b/Modules/CMakeFortranCompilerABI.F
new file mode 100644
index 000000000..7e24553fb
--- /dev/null
+++ b/Modules/CMakeFortranCompilerABI.F
@@ -0,0 +1,38 @@
+ PROGRAM CMakeFortranCompilerABI
+#if 0
+! Address Size
+#endif
+#if defined(_LP64)
+ PRINT *, 'INFO:sizeof_dptr[8]'
+#elif defined(_M_IA64)
+ PRINT *, 'INFO:sizeof_dptr[8]'
+#elif defined(_M_X64)
+ PRINT *, 'INFO:sizeof_dptr[8]'
+#elif defined(_M_AMD64)
+ PRINT *, 'INFO:sizeof_dptr[8]'
+
+#elif defined(_ILP32)
+ PRINT *, 'INFO:sizeof_dptr[4]'
+#elif defined(_M_IX86)
+ 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]'
+#endif
+
+#if 0
+! Application Binary Interface
+#endif
+#if defined(__sgi) && defined(_ABIO32)
+ PRINT *, 'INFO:abi[ELF O32]'
+#elif defined(__sgi) && defined(_ABIN32)
+ PRINT *, 'INFO:abi[ELF N32]'
+#elif defined(__sgi) && defined(_ABI64)
+ PRINT *, 'INFO:abi[ELF 64]'
+#elif defined(__ELF__)
+ PRINT *, 'INFO:abi[ELF]'
+#endif
+ PRINT *, 'ABI Detection'
+ END
diff --git a/Modules/CMakeFortranCompilerId.F.in b/Modules/CMakeFortranCompilerId.F.in
new file mode 100644
index 000000000..4d25de0ba
--- /dev/null
+++ b/Modules/CMakeFortranCompilerId.F.in
@@ -0,0 +1,123 @@
+ PROGRAM CMakeFortranCompilerId
+#if 0
+! Identify the compiler
+#endif
+#if defined(__INTEL_COMPILER) || defined(__ICC)
+ PRINT *, 'INFO:compiler[Intel]'
+#elif defined(__SUNPRO_F90) || defined(__SUNPRO_F95)
+ PRINT *, 'INFO:compiler[SunPro]'
+#elif defined(_CRAYFTN)
+ PRINT *, 'INFO:compiler[Cray]'
+#elif defined(__G95__)
+ PRINT *, 'INFO:compiler[G95]'
+#elif defined(__PATHSCALE__)
+ PRINT *, 'INFO:compiler[PathScale]'
+#elif defined(__ABSOFT__)
+ PRINT *, 'INFO:compiler[Absoft]'
+#elif defined(__GNUC__)
+ PRINT *, 'INFO:compiler[GNU]'
+#elif defined(__IBMC__)
+# if defined(__COMPILER_VER__)
+ PRINT *, 'INFO:compiler[zOS]'
+# elif __IBMC__ >= 800
+ PRINT *, 'INFO:compiler[XL]'
+# else
+ PRINT *, 'INFO:compiler[VisualAge]'
+# endif
+#elif defined(__PGI)
+ PRINT *, 'INFO:compiler[PGI]'
+#elif defined(_SGI_COMPILER_VERSION) || defined(_COMPILER_VERSION)
+ PRINT *, 'INFO:compiler[MIPSpro]'
+# if 0
+! 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.
+# endif
+#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__)
+ PRINT *, 'INFO:compiler[VisualAge]'
+#elif defined(__sgi) || defined(__sgi__) || defined(_SGI)
+ PRINT *, 'INFO:compiler[MIPSpro]'
+#elif defined(__hpux) || defined(__hpux__)
+ PRINT *, 'INFO:compiler[HP]'
+#elif 1
+# if 0
+! The above 'elif 1' instead of 'else' is to work around a bug in the
+! SGI preprocessor which produces both the __sgi and else blocks.
+# endif
+ PRINT *, 'INFO:compiler[]'
+#endif
+
+#if 0
+! Identify the platform
+#endif
+#if defined(__linux) || defined(__linux__) || defined(linux)
+ PRINT *, 'INFO:platform[Linux]'
+#elif defined(__CYGWIN__)
+ PRINT *, 'INFO:platform[Cygwin]'
+#elif defined(__MINGW32__)
+ PRINT *, 'INFO:platform[MinGW]'
+#elif defined(__APPLE__)
+ PRINT *, 'INFO:platform[Darwin]'
+#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
+ PRINT *, 'INFO:platform[Windows]'
+#elif defined(__FreeBSD__) || defined(__FreeBSD)
+ PRINT *, 'INFO:platform[FreeBSD]'
+#elif defined(__NetBSD__) || defined(__NetBSD)
+ PRINT *, 'INFO:platform[NetBSD]'
+#elif defined(__OpenBSD__) || defined(__OPENBSD)
+ PRINT *, 'INFO:platform[OpenBSD]'
+#elif defined(__sun) || defined(sun)
+ PRINT *, 'INFO:platform[SunOS]'
+#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__)
+ PRINT *, 'INFO:platform[AIX]'
+#elif defined(__sgi) || defined(__sgi__) || defined(_SGI)
+ PRINT *, 'INFO:platform[IRIX]'
+#elif defined(__hpux) || defined(__hpux__)
+ PRINT *, 'INFO:platform[HP-UX]'
+#elif defined(__HAIKU) || defined(__HAIKU__) || defined(_HAIKU)
+ PRINT *, 'INFO:platform[Haiku]'
+# if 0
+! Haiku also defines __BEOS__ so we must
+! put it prior to the check for __BEOS__
+# endif
+#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS)
+ PRINT *, 'INFO:platform[BeOS]'
+#elif defined(__QNX__) || defined(__QNXNTO__)
+ PRINT *, 'INFO:platform[QNX]'
+#elif defined(__tru64) || defined(_tru64) || defined(__TRU64__)
+ PRINT *, 'INFO:platform[Tru64]'
+#elif defined(__riscos) || defined(__riscos__)
+ PRINT *, 'INFO:platform[RISCos]'
+#elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__)
+ PRINT *, 'INFO:platform[SINIX]'
+#elif defined(__UNIX_SV__)
+ PRINT *, 'INFO:platform[UNIX_SV]'
+#elif defined(__bsdos__)
+ PRINT *, 'INFO:platform[BSDOS]'
+#elif defined(_MPRAS) || defined(MPRAS)
+ PRINT *, 'INFO:platform[MP-RAS]'
+#elif defined(__osf) || defined(__osf__)
+ PRINT *, 'INFO:platform[OSF1]'
+#elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv)
+ PRINT *, 'INFO:platform[SCO_SV]'
+#elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX)
+ PRINT *, 'INFO:platform[ULTRIX]'
+#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX)
+ PRINT *, 'INFO:platform[Xenix]'
+#elif 1
+# if 0
+! The above 'elif 1' instead of 'else' is to work around a bug in the
+! SGI preprocessor which produces both the __sgi and else blocks.
+# endif
+ PRINT *, 'INFO:platform[]'
+#endif
+#if defined(_WIN32) && (defined(__INTEL_COMPILER) || defined(__ICC))
+# if defined(_M_IA64)
+ PRINT *, 'INFO:arch[IA64]'
+# elif defined(_M_X64) || defined(_M_AMD64)
+ PRINT *, 'INFO:arch[x64]'
+# elif defined(_M_IX86)
+ PRINT *, 'INFO:arch[X86]'
+# endif
+#endif
+ END
diff --git a/Modules/CMakeFortranInformation.cmake b/Modules/CMakeFortranInformation.cmake
new file mode 100644
index 000000000..d962f4cb5
--- /dev/null
+++ b/Modules/CMakeFortranInformation.cmake
@@ -0,0 +1,245 @@
+
+#=============================================================================
+# Copyright 2004-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.)
+
+# 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.
+
+SET(_INCLUDED_FILE 0)
+
+# Load compiler-specific information.
+IF(CMAKE_Fortran_COMPILER_ID)
+ INCLUDE(Compiler/${CMAKE_Fortran_COMPILER_ID}-Fortran OPTIONAL)
+ENDIF(CMAKE_Fortran_COMPILER_ID)
+
+SET(CMAKE_BASE_NAME)
+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)
+ENDIF(CMAKE_COMPILER_IS_GNUG77)
+IF(CMAKE_Fortran_COMPILER_ID)
+ INCLUDE(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_Fortran_COMPILER_ID}-Fortran OPTIONAL RESULT_VARIABLE _INCLUDED_FILE)
+ENDIF(CMAKE_Fortran_COMPILER_ID)
+IF (NOT _INCLUDED_FILE)
+ INCLUDE(Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_BASE_NAME} OPTIONAL
+ RESULT_VARIABLE _INCLUDED_FILE)
+ENDIF (NOT _INCLUDED_FILE)
+# 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.
+# Remove this when all compiler info is removed from system files.
+IF (NOT _INCLUDED_FILE)
+ INCLUDE(Platform/${CMAKE_SYSTEM_NAME} OPTIONAL)
+ENDIF (NOT _INCLUDED_FILE)
+
+IF(CMAKE_Fortran_SIZEOF_DATA_PTR)
+ FOREACH(f ${CMAKE_Fortran_ABI_FILES})
+ INCLUDE(${f})
+ ENDFOREACH()
+ UNSET(CMAKE_Fortran_ABI_FILES)
+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_Fortran)
+ # Save the full path of the file so try_compile can use it.
+ INCLUDE(${CMAKE_USER_MAKE_RULES_OVERRIDE_Fortran} RESULT_VARIABLE _override)
+ SET(CMAKE_USER_MAKE_RULES_OVERRIDE_Fortran "${_override}")
+ENDIF()
+
+
+# Fortran needs cmake to do a requires step during its build process to
+# catch any modules
+SET(CMAKE_NEEDS_REQUIRES_STEP_Fortran_FLAG 1)
+
+IF(NOT CMAKE_Fortran_COMPILE_OPTIONS_PIC)
+ SET(CMAKE_Fortran_COMPILE_OPTIONS_PIC ${CMAKE_C_COMPILE_OPTIONS_PIC})
+ENDIF(NOT CMAKE_Fortran_COMPILE_OPTIONS_PIC)
+
+IF(NOT CMAKE_Fortran_COMPILE_OPTIONS_PIE)
+ SET(CMAKE_Fortran_COMPILE_OPTIONS_PIE ${CMAKE_C_COMPILE_OPTIONS_PIE})
+ENDIF(NOT CMAKE_Fortran_COMPILE_OPTIONS_PIE)
+
+IF(NOT CMAKE_Fortran_COMPILE_OPTIONS_DLL)
+ SET(CMAKE_Fortran_COMPILE_OPTIONS_DLL ${CMAKE_C_COMPILE_OPTIONS_DLL})
+ENDIF(NOT CMAKE_Fortran_COMPILE_OPTIONS_DLL)
+
+# Create a set of shared library variable specific to Fortran
+# For 90% of the systems, these are the same flags as the C versions
+# so if these are not set just copy the flags from the c version
+IF(NOT DEFINED CMAKE_SHARED_LIBRARY_CREATE_Fortran_FLAGS)
+ SET(CMAKE_SHARED_LIBRARY_CREATE_Fortran_FLAGS ${CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS})
+ENDIF()
+
+IF(NOT DEFINED CMAKE_SHARED_LIBRARY_Fortran_FLAGS)
+ SET(CMAKE_SHARED_LIBRARY_Fortran_FLAGS ${CMAKE_SHARED_LIBRARY_C_FLAGS})
+ENDIF()
+
+IF(NOT DEFINED CMAKE_SHARED_LIBRARY_LINK_Fortran_FLAGS)
+ SET(CMAKE_SHARED_LIBRARY_LINK_Fortran_FLAGS ${CMAKE_SHARED_LIBRARY_LINK_C_FLAGS})
+ENDIF()
+
+IF(NOT DEFINED CMAKE_SHARED_LIBRARY_RUNTIME_Fortran_FLAG)
+ SET(CMAKE_SHARED_LIBRARY_RUNTIME_Fortran_FLAG ${CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG})
+ENDIF()
+
+IF(NOT DEFINED CMAKE_SHARED_LIBRARY_RUNTIME_Fortran_FLAG_SEP)
+ SET(CMAKE_SHARED_LIBRARY_RUNTIME_Fortran_FLAG_SEP ${CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP})
+ENDIF()
+
+IF(NOT DEFINED CMAKE_SHARED_LIBRARY_RPATH_LINK_Fortran_FLAG)
+ SET(CMAKE_SHARED_LIBRARY_RPATH_LINK_Fortran_FLAG ${CMAKE_SHARED_LIBRARY_RPATH_LINK_C_FLAG})
+ENDIF()
+
+IF(NOT DEFINED CMAKE_EXE_EXPORTS_Fortran_FLAG)
+ SET(CMAKE_EXE_EXPORTS_Fortran_FLAG ${CMAKE_EXE_EXPORTS_C_FLAG})
+ENDIF()
+
+IF(NOT DEFINED CMAKE_SHARED_LIBRARY_SONAME_Fortran_FLAG)
+ SET(CMAKE_SHARED_LIBRARY_SONAME_Fortran_FLAG ${CMAKE_SHARED_LIBRARY_SONAME_C_FLAG})
+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_Fortran_FLAGS ${CMAKE_SHARED_LIBRARY_Fortran_FLAGS})
+ SET(CMAKE_SHARED_MODULE_CREATE_Fortran_FLAGS ${CMAKE_SHARED_LIBRARY_CREATE_Fortran_FLAGS})
+ENDIF(NOT CMAKE_MODULE_EXISTS)
+
+# repeat for modules
+IF(NOT DEFINED CMAKE_SHARED_MODULE_CREATE_Fortran_FLAGS)
+ SET(CMAKE_SHARED_MODULE_CREATE_Fortran_FLAGS ${CMAKE_SHARED_MODULE_CREATE_C_FLAGS})
+ENDIF()
+
+IF(NOT DEFINED CMAKE_SHARED_MODULE_Fortran_FLAGS)
+ SET(CMAKE_SHARED_MODULE_Fortran_FLAGS ${CMAKE_SHARED_MODULE_C_FLAGS})
+ENDIF()
+
+IF(NOT DEFINED CMAKE_EXECUTABLE_RUNTIME_Fortran_FLAG)
+ SET(CMAKE_EXECUTABLE_RUNTIME_Fortran_FLAG ${CMAKE_SHARED_LIBRARY_RUNTIME_Fortran_FLAG})
+ENDIF()
+
+IF(NOT DEFINED CMAKE_EXECUTABLE_RUNTIME_Fortran_FLAG_SEP)
+ SET(CMAKE_EXECUTABLE_RUNTIME_Fortran_FLAG_SEP ${CMAKE_SHARED_LIBRARY_RUNTIME_Fortran_FLAG_SEP})
+ENDIF()
+
+IF(NOT DEFINED CMAKE_EXECUTABLE_RPATH_LINK_Fortran_FLAG)
+ SET(CMAKE_EXECUTABLE_RPATH_LINK_Fortran_FLAG ${CMAKE_SHARED_LIBRARY_RPATH_LINK_Fortran_FLAG})
+ENDIF()
+
+IF(NOT DEFINED CMAKE_SHARED_LIBRARY_LINK_Fortran_WITH_RUNTIME_PATH)
+ SET(CMAKE_SHARED_LIBRARY_LINK_Fortran_WITH_RUNTIME_PATH ${CMAKE_SHARED_LIBRARY_LINK_C_WITH_RUNTIME_PATH})
+ENDIF(NOT DEFINED CMAKE_SHARED_LIBRARY_LINK_Fortran_WITH_RUNTIME_PATH)
+
+IF(NOT CMAKE_INCLUDE_FLAG_Fortran)
+ SET(CMAKE_INCLUDE_FLAG_Fortran ${CMAKE_INCLUDE_FLAG_C})
+ENDIF(NOT CMAKE_INCLUDE_FLAG_Fortran)
+
+IF(NOT CMAKE_INCLUDE_FLAG_SEP_Fortran)
+ SET(CMAKE_INCLUDE_FLAG_SEP_Fortran ${CMAKE_INCLUDE_FLAG_SEP_C})
+ENDIF(NOT CMAKE_INCLUDE_FLAG_SEP_Fortran)
+
+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.")
+
+SET(CMAKE_Fortran_FLAGS_INIT "$ENV{FFLAGS} ${CMAKE_Fortran_FLAGS_INIT}")
+# avoid just having a space as the initial value for the cache
+IF(CMAKE_Fortran_FLAGS_INIT STREQUAL " ")
+ SET(CMAKE_Fortran_FLAGS_INIT)
+ENDIF(CMAKE_Fortran_FLAGS_INIT STREQUAL " ")
+SET (CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS_INIT}" CACHE STRING
+ "Flags for Fortran compiler.")
+
+INCLUDE(CMakeCommonLanguageInclude)
+
+# now define the following rule variables
+# CMAKE_Fortran_CREATE_SHARED_LIBRARY
+# CMAKE_Fortran_CREATE_SHARED_MODULE
+# CMAKE_Fortran_COMPILE_OBJECT
+# CMAKE_Fortran_LINK_EXECUTABLE
+
+# create a Fortran shared library
+IF(NOT CMAKE_Fortran_CREATE_SHARED_LIBRARY)
+ SET(CMAKE_Fortran_CREATE_SHARED_LIBRARY
+ "<CMAKE_Fortran_COMPILER> <CMAKE_SHARED_LIBRARY_Fortran_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_Fortran_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>")
+ENDIF(NOT CMAKE_Fortran_CREATE_SHARED_LIBRARY)
+
+# create a Fortran shared module just copy the shared library rule
+IF(NOT CMAKE_Fortran_CREATE_SHARED_MODULE)
+ SET(CMAKE_Fortran_CREATE_SHARED_MODULE ${CMAKE_Fortran_CREATE_SHARED_LIBRARY})
+ENDIF(NOT CMAKE_Fortran_CREATE_SHARED_MODULE)
+
+# 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>")
+ENDIF()
+IF(NOT DEFINED CMAKE_Fortran_ARCHIVE_APPEND)
+ SET(CMAKE_Fortran_ARCHIVE_APPEND "<CMAKE_AR> r <TARGET> <LINK_FLAGS> <OBJECTS>")
+ENDIF()
+IF(NOT DEFINED CMAKE_Fortran_ARCHIVE_FINISH)
+ SET(CMAKE_Fortran_ARCHIVE_FINISH "<CMAKE_RANLIB> <TARGET>")
+ENDIF()
+
+# compile a Fortran file into an object file
+# (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>")
+ENDIF(NOT CMAKE_Fortran_COMPILE_OBJECT)
+
+# link a fortran program
+IF(NOT CMAKE_Fortran_LINK_EXECUTABLE)
+ SET(CMAKE_Fortran_LINK_EXECUTABLE
+ "<CMAKE_Fortran_COMPILER> <CMAKE_Fortran_LINK_FLAGS> <LINK_FLAGS> <FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
+ENDIF(NOT CMAKE_Fortran_LINK_EXECUTABLE)
+
+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.")
+ MARK_AS_ADVANCED(CMAKE_Fortran_STANDARD_LIBRARIES)
+ENDIF(CMAKE_Fortran_STANDARD_LIBRARIES_INIT)
+
+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.")
+ 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).")
+ SET (CMAKE_Fortran_FLAGS_RELWITHDEBINFO "${CMAKE_Fortran_FLAGS_RELWITHDEBINFO_INIT}" CACHE STRING
+ "Flags used by the compiler during Release with Debug Info builds.")
+
+ENDIF(NOT CMAKE_NOT_USING_CONFIG_FLAGS)
+
+MARK_AS_ADVANCED(
+CMAKE_Fortran_FLAGS
+CMAKE_Fortran_FLAGS_DEBUG
+CMAKE_Fortran_FLAGS_MINSIZEREL
+CMAKE_Fortran_FLAGS_RELEASE
+CMAKE_Fortran_FLAGS_RELWITHDEBINFO)
+
+# set this variable so we can avoid loading this more than once.
+SET(CMAKE_Fortran_INFORMATION_LOADED 1)
diff --git a/Modules/CMakeGenericSystem.cmake b/Modules/CMakeGenericSystem.cmake
new file mode 100644
index 000000000..0ccbfac56
--- /dev/null
+++ b/Modules/CMakeGenericSystem.cmake
@@ -0,0 +1,187 @@
+
+#=============================================================================
+# 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.)
+
+SET(CMAKE_SHARED_LIBRARY_C_FLAGS "") # -pic
+SET(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-shared") # -shared
+SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") # +s, flag for exe link to use shared lib
+SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "") # -rpath
+SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP "") # : or empty
+SET(CMAKE_INCLUDE_FLAG_C "-I") # -I
+SET(CMAKE_INCLUDE_FLAG_C_SEP "") # , or empty
+SET(CMAKE_LIBRARY_PATH_FLAG "-L")
+SET(CMAKE_LIBRARY_PATH_TERMINATOR "") # for the Digital Mars D compiler the link paths have to be terminated with a "/"
+SET(CMAKE_LINK_LIBRARY_FLAG "-l")
+
+SET(CMAKE_LINK_LIBRARY_SUFFIX "")
+SET(CMAKE_STATIC_LIBRARY_PREFIX "lib")
+SET(CMAKE_STATIC_LIBRARY_SUFFIX ".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")
+
+SET(CMAKE_FIND_LIBRARY_PREFIXES "lib")
+SET(CMAKE_FIND_LIBRARY_SUFFIXES ".so" ".a")
+
+# basically all general purpose OSs support shared libs
+SET_PROPERTY(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS TRUE)
+
+SET (CMAKE_SKIP_RPATH "NO" CACHE BOOL
+ "If set, runtime paths are not added when using shared libraries.")
+SET (CMAKE_SKIP_INSTALL_RPATH "NO" CACHE BOOL
+ "If set, runtime paths are not added when installing shared libraries, but are added when building.")
+
+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")
+ SET(CMAKE_COLOR_MAKEFILE ON CACHE BOOL
+ "Enable/Disable color output during build."
+ )
+ MARK_AS_ADVANCED(CMAKE_COLOR_MAKEFILE)
+ IF(DEFINED CMAKE_RULE_MESSAGES)
+ SET_PROPERTY(GLOBAL PROPERTY RULE_MESSAGES ${CMAKE_RULE_MESSAGES})
+ ENDIF(DEFINED CMAKE_RULE_MESSAGES)
+ IF(CMAKE_GENERATOR MATCHES "Unix Makefiles")
+ SET(CMAKE_EXPORT_COMPILE_COMMANDS OFF CACHE BOOL
+ "Enable/Disable output of compile commands during generation."
+ )
+ MARK_AS_ADVANCED(CMAKE_EXPORT_COMPILE_COMMANDS)
+ ENDIF(CMAKE_GENERATOR MATCHES "Unix Makefiles")
+ENDIF(CMAKE_GENERATOR MATCHES "Makefiles")
+
+IF(CMAKE_GENERATOR MATCHES "Ninja")
+ SET(CMAKE_EXPORT_COMPILE_COMMANDS OFF CACHE BOOL
+ "Enable/Disable output of compile commands during generation."
+ )
+ MARK_AS_ADVANCED(CMAKE_EXPORT_COMPILE_COMMANDS)
+ENDIF(CMAKE_GENERATOR MATCHES "Ninja")
+
+# GetDefaultWindowsPrefixBase
+#
+# Compute the base directory for CMAKE_INSTALL_PREFIX based on:
+# - is this 32-bit or 64-bit Windows
+# - is this 32-bit or 64-bit CMake running
+# - what architecture targets will be built
+#
+function(GetDefaultWindowsPrefixBase var)
+
+ # Try to guess what architecture targets will end up being built as,
+ # even if CMAKE_SIZEOF_VOID_P is not computed yet... We need to know
+ # the architecture of the targets being built to choose the right
+ # default value for CMAKE_INSTALL_PREFIX.
+ #
+ if("${CMAKE_GENERATOR}" MATCHES "(Win64|IA64)")
+ set(arch_hint "x64")
+ elseif("${CMAKE_GENERATOR}" MATCHES "ARM")
+ set(arch_hint "ARM")
+ elseif("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
+ set(arch_hint "x64")
+ elseif("$ENV{LIB}" MATCHES "(amd64|ia64)")
+ set(arch_hint "x64")
+ endif()
+
+ if(NOT arch_hint)
+ set(arch_hint "x86")
+ endif()
+
+ # default env in a 64-bit app on Win64:
+ # ProgramFiles=C:\Program Files
+ # ProgramFiles(x86)=C:\Program Files (x86)
+ # ProgramW6432=C:\Program Files
+ #
+ # default env in a 32-bit app on Win64:
+ # ProgramFiles=C:\Program Files (x86)
+ # ProgramFiles(x86)=C:\Program Files (x86)
+ # ProgramW6432=C:\Program Files
+ #
+ # default env in a 32-bit app on Win32:
+ # ProgramFiles=C:\Program Files
+ # ProgramFiles(x86) NOT DEFINED
+ # ProgramW6432 NOT DEFINED
+
+ # By default, use the ProgramFiles env var as the base value of
+ # CMAKE_INSTALL_PREFIX:
+ #
+ set(_PREFIX_ENV_VAR "ProgramFiles")
+
+ if ("$ENV{ProgramW6432}" STREQUAL "")
+ # running on 32-bit Windows
+ # must be a 32-bit CMake, too...
+ #message("guess: this is a 32-bit CMake running on 32-bit Windows")
+ else()
+ # running on 64-bit Windows
+ if ("$ENV{ProgramW6432}" STREQUAL "$ENV{ProgramFiles}")
+ # 64-bit CMake
+ #message("guess: this is a 64-bit CMake running on 64-bit Windows")
+ if(NOT "${arch_hint}" STREQUAL "x64")
+ # building 32-bit targets
+ set(_PREFIX_ENV_VAR "ProgramFiles(x86)")
+ endif()
+ else()
+ # 32-bit CMake
+ #message("guess: this is a 32-bit CMake running on 64-bit Windows")
+ if("${arch_hint}" STREQUAL "x64")
+ # building 64-bit targets
+ set(_PREFIX_ENV_VAR "ProgramW6432")
+ endif()
+ endif()
+ endif()
+
+ #if("${arch_hint}" STREQUAL "x64")
+ # message("guess: you are building a 64-bit app")
+ #else()
+ # message("guess: you are building a 32-bit app")
+ #endif()
+
+ if(NOT "$ENV{${_PREFIX_ENV_VAR}}" STREQUAL "")
+ file(TO_CMAKE_PATH "$ENV{${_PREFIX_ENV_VAR}}" _base)
+ elseif(NOT "$ENV{SystemDrive}" STREQUAL "")
+ set(_base "$ENV{SystemDrive}/Program Files")
+ else()
+ set(_base "C:/Program Files")
+ endif()
+
+ set(${var} "${_base}" PARENT_SCOPE)
+endfunction()
+
+
+# Set a variable to indicate whether the value of CMAKE_INSTALL_PREFIX
+# was initialized by the block below. This is useful for user
+# projects to change the default prefix while still allowing the
+# command line to override it.
+IF(NOT DEFINED CMAKE_INSTALL_PREFIX)
+ SET(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT 1)
+ENDIF(NOT DEFINED CMAKE_INSTALL_PREFIX)
+
+# Choose a default install prefix for this platform.
+IF(CMAKE_HOST_UNIX)
+ SET(CMAKE_INSTALL_PREFIX "/usr/local"
+ CACHE PATH "Install path prefix, prepended onto install directories.")
+ELSE(CMAKE_HOST_UNIX)
+ GetDefaultWindowsPrefixBase(CMAKE_GENERIC_PROGRAM_FILES)
+ SET(CMAKE_INSTALL_PREFIX
+ "${CMAKE_GENERIC_PROGRAM_FILES}/${PROJECT_NAME}"
+ CACHE PATH "Install path prefix, prepended onto install directories.")
+ SET(CMAKE_GENERIC_PROGRAM_FILES)
+ENDIF(CMAKE_HOST_UNIX)
+
+# Set a variable which will be used as component name in install() commands
+# where no COMPONENT has been given:
+SET(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME "Unspecified")
+
+MARK_AS_ADVANCED(
+ CMAKE_SKIP_RPATH
+ CMAKE_SKIP_INSTALL_RPATH
+ CMAKE_VERBOSE_MAKEFILE
+)
diff --git a/Modules/CMakeImportBuildSettings.cmake b/Modules/CMakeImportBuildSettings.cmake
new file mode 100644
index 000000000..848d89445
--- /dev/null
+++ b/Modules/CMakeImportBuildSettings.cmake
@@ -0,0 +1,24 @@
+
+#=============================================================================
+# 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 module is purposely no longer documented. It does nothing useful.
+
+# 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(${SETTINGS_FILE} MATCHES ".+")
+ MESSAGE(SEND_ERROR "CMAKE_IMPORT_BUILD_SETTINGS called with no argument.")
+ ENDIF(${SETTINGS_FILE} MATCHES ".+")
+ENDMACRO(CMAKE_IMPORT_BUILD_SETTINGS)
diff --git a/Modules/CMakeJOMFindMake.cmake b/Modules/CMakeJOMFindMake.cmake
new file mode 100644
index 000000000..617f3bb90
--- /dev/null
+++ b/Modules/CMakeJOMFindMake.cmake
@@ -0,0 +1,18 @@
+
+#=============================================================================
+# 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.)
+
+
+SET (CMAKE_MAKE_PROGRAM "jom" CACHE STRING
+ "Program used to build from makefiles.")
+MARK_AS_ADVANCED(CMAKE_MAKE_PROGRAM)
diff --git a/Modules/CMakeJavaCompiler.cmake.in b/Modules/CMakeJavaCompiler.cmake.in
new file mode 100644
index 000000000..79c9288bc
--- /dev/null
+++ b/Modules/CMakeJavaCompiler.cmake.in
@@ -0,0 +1,13 @@
+SET(CMAKE_Java_COMPILER "@CMAKE_Java_COMPILER@")
+SET(CMAKE_Java_COMPILER_ARG1 "@CMAKE_Java_COMPILER_ARG1@")
+SET(CMAKE_Java_RUNTIME "@CMAKE_Java_RUNTIME@")
+SET(CMAKE_Java_ARCHIVE "@CMAKE_Java_ARCHIVE@")
+SET(CMAKE_Java_COMPILER_LOADED 1)
+
+SET(CMAKE_Java_SOURCE_FILE_EXTENSIONS java)
+SET(CMAKE_Java_LINKER_PREFERENCE 40)
+SET(CMAKE_Java_OUTPUT_EXTENSION .class)
+SET(CMAKE_Java_OUTPUT_EXTENSION_REPLACE 1)
+SET(CMAKE_STATIC_LIBRARY_PREFIX_Java "")
+SET(CMAKE_STATIC_LIBRARY_SUFFIX_Java ".jar")
+SET(CMAKE_Java_COMPILER_ENV_VAR "JAVA_COMPILER")
diff --git a/Modules/CMakeJavaInformation.cmake b/Modules/CMakeJavaInformation.cmake
new file mode 100644
index 000000000..e192db100
--- /dev/null
+++ b/Modules/CMakeJavaInformation.cmake
@@ -0,0 +1,59 @@
+
+#=============================================================================
+# Copyright 2004-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.)
+
+# 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_Java)
+ # Save the full path of the file so try_compile can use it.
+ INCLUDE(${CMAKE_USER_MAKE_RULES_OVERRIDE_Java} RESULT_VARIABLE _override)
+ SET(CMAKE_USER_MAKE_RULES_OVERRIDE_Java "${_override}")
+ENDIF()
+
+# this is a place holder if java needed flags for javac they would go here.
+IF(NOT CMAKE_Java_CREATE_STATIC_LIBRARY)
+# IF(WIN32)
+# SET(class_files_mask "*.class")
+# ELSE(WIN32)
+ SET(class_files_mask ".")
+# ENDIF(WIN32)
+
+ SET(CMAKE_Java_CREATE_STATIC_LIBRARY
+ "<CMAKE_Java_ARCHIVE> -cf <TARGET> -C <OBJECT_DIR> ${class_files_mask}")
+ # "${class_files_mask}" should really be "<OBJECTS>" but compling a *.java
+ # file can create more than one *.class file...
+ENDIF(NOT CMAKE_Java_CREATE_STATIC_LIBRARY)
+
+# compile a Java file into an object file
+IF(NOT CMAKE_Java_COMPILE_OBJECT)
+ SET(CMAKE_Java_COMPILE_OBJECT
+ "<CMAKE_Java_COMPILER> <FLAGS> <SOURCE> -d <OBJECT_DIR>")
+ENDIF(NOT CMAKE_Java_COMPILE_OBJECT)
+
+# set java include flag option and the separator for multiple include paths
+SET(CMAKE_INCLUDE_FLAG_Java "-classpath ")
+IF(WIN32 AND NOT CYGWIN)
+ SET(CMAKE_INCLUDE_FLAG_SEP_Java ";")
+ELSE(WIN32 AND NOT CYGWIN)
+ SET(CMAKE_INCLUDE_FLAG_SEP_Java ":")
+ENDIF(WIN32 AND NOT CYGWIN)
diff --git a/Modules/CMakeMSYSFindMake.cmake b/Modules/CMakeMSYSFindMake.cmake
new file mode 100644
index 000000000..95492a0b0
--- /dev/null
+++ b/Modules/CMakeMSYSFindMake.cmake
@@ -0,0 +1,20 @@
+
+#=============================================================================
+# 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.)
+
+FIND_PROGRAM(CMAKE_MAKE_PROGRAM make
+ PATHS
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\MSYS-1.0_is1;Inno Setup: App Path]/bin"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\MinGW;InstallLocation]/bin"
+ c:/msys/1.0/bin /msys/1.0/bin)
+MARK_AS_ADVANCED(CMAKE_MAKE_PROGRAM)
diff --git a/Modules/CMakeMinGWFindMake.cmake b/Modules/CMakeMinGWFindMake.cmake
new file mode 100644
index 000000000..f760d74d4
--- /dev/null
+++ b/Modules/CMakeMinGWFindMake.cmake
@@ -0,0 +1,24 @@
+
+#=============================================================================
+# 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.)
+
+FIND_PROGRAM(CMAKE_MAKE_PROGRAM mingw32-make.exe PATHS
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\MinGW;InstallLocation]/bin"
+ c:/MinGW/bin /MinGW/bin)
+FIND_PROGRAM(CMAKE_SH sh.exe )
+IF(CMAKE_SH)
+ MESSAGE(FATAL_ERROR "sh.exe was found in your PATH, here:\n${CMAKE_SH}\nFor MinGW make to work correctly sh.exe must NOT be in your path.\nRun cmake from a shell that does not have sh.exe in your PATH.\nIf you want to use a UNIX shell, then use MSYS Makefiles.\n")
+ SET(CMAKE_MAKE_PROGRAM NOTFOUND)
+ENDIF(CMAKE_SH)
+
+MARK_AS_ADVANCED(CMAKE_MAKE_PROGRAM CMAKE_SH)
diff --git a/Modules/CMakeNMakeFindMake.cmake b/Modules/CMakeNMakeFindMake.cmake
new file mode 100644
index 000000000..f6472170c
--- /dev/null
+++ b/Modules/CMakeNMakeFindMake.cmake
@@ -0,0 +1,18 @@
+
+#=============================================================================
+# 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.)
+
+
+SET (CMAKE_MAKE_PROGRAM "nmake" CACHE STRING
+ "Program used to build from makefiles.")
+MARK_AS_ADVANCED(CMAKE_MAKE_PROGRAM)
diff --git a/Modules/CMakeNinjaFindMake.cmake b/Modules/CMakeNinjaFindMake.cmake
new file mode 100644
index 000000000..f15c3e0d4
--- /dev/null
+++ b/Modules/CMakeNinjaFindMake.cmake
@@ -0,0 +1,17 @@
+
+#=============================================================================
+# Copyright 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.)
+
+FIND_PROGRAM(CMAKE_MAKE_PROGRAM 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
new file mode 100644
index 000000000..48039e522
--- /dev/null
+++ b/Modules/CMakePackageConfigHelpers.cmake
@@ -0,0 +1,227 @@
+# - 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)
+
+
+#=============================================================================
+# Copyright 2012 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.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+include(CMakeParseArguments)
+
+include(WriteBasicConfigVersionFile)
+
+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(multiValueArgs PATH_VARS )
+
+ cmake_parse_arguments(CCF "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+ if(CCF_UNPARSED_ARGUMENTS)
+ message(FATAL_ERROR "Unknown keywords given to CONFIGURE_PACKAGE_CONFIG_FILE(): \"${CCF_UNPARSED_ARGUMENTS}\"")
+ endif()
+
+ if(NOT CCF_INSTALL_DESTINATION)
+ message(FATAL_ERROR "No INSTALL_DESTINATION given to CONFIGURE_PACKAGE_CONFIG_FILE()")
+ endif()
+
+ if(IS_ABSOLUTE "${CCF_INSTALL_DESTINATION}")
+ set(absInstallDir "${CCF_INSTALL_DESTINATION}")
+ else()
+ set(absInstallDir "${CMAKE_INSTALL_PREFIX}/${CCF_INSTALL_DESTINATION}")
+ endif()
+ file(RELATIVE_PATH PACKAGE_RELATIVE_PATH "${absInstallDir}" "${CMAKE_INSTALL_PREFIX}" )
+
+ 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}"
+ PACKAGE_${var} "${${var}}")
+ else()
+ set(PACKAGE_${var} "\${PACKAGE_PREFIX_DIR}/${${var}}")
+ endif()
+ endif()
+ endforeach()
+
+ set(PACKAGE_INIT "
+####### Expanded from @PACKAGE_INIT@ by configure_package_config_file() #######
+get_filename_component(PACKAGE_PREFIX_DIR \"\${CMAKE_CURRENT_LIST_DIR}/${PACKAGE_RELATIVE_PATH}\" ABSOLUTE)
+")
+
+ if(NOT CCF_NO_SET_AND_CHECK_MACRO)
+ set(PACKAGE_INIT "${PACKAGE_INIT}
+macro(set_and_check _var _file)
+ set(\${_var} \"\${_file}\")
+ if(NOT EXISTS \"\${_file}\")
+ message(FATAL_ERROR \"File or directory \${_file} referenced by variable \${_var} does not exist !\")
+ endif()
+endmacro()
+")
+ endif()
+
+
+ if(NOT CCF_NO_CHECK_REQUIRED_COMPONENTS_MACRO)
+ set(PACKAGE_INIT "${PACKAGE_INIT}
+macro(check_required_components _NAME)
+ foreach(comp \${\${_NAME}_FIND_COMPONENTS})
+ if(NOT \${_NAME}_\${comp}_FOUND)
+ if(\${_NAME}_FIND_REQUIRED_\${comp})
+ set(\${_NAME}_FOUND FALSE)
+ endif()
+ endif()
+ endforeach(comp)
+endmacro()
+")
+ endif()
+
+ set(PACKAGE_INIT "${PACKAGE_INIT}
+####################################################################################")
+
+ configure_file("${_inputFile}" "${_outputFile}" @ONLY)
+
+endfunction()
diff --git a/Modules/CMakeParseArguments.cmake b/Modules/CMakeParseArguments.cmake
new file mode 100644
index 000000000..7ce4c49ae
--- /dev/null
+++ b/Modules/CMakeParseArguments.cmake
@@ -0,0 +1,138 @@
+# CMAKE_PARSE_ARGUMENTS(<prefix> <options> <one_value_keywords> <multi_value_keywords> args...)
+#
+# 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 the 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.
+
+#=============================================================================
+# 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.
+#=============================================================================
+# (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(arg_name)
+
+ foreach(option ${_optionNames})
+ set(${prefix}_${option} FALSE)
+ endforeach(option)
+
+ 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(insideValues)
+ list(APPEND ${prefix}_UNPARSED_ARGUMENTS ${currentArg})
+ endif(insideValues)
+ 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(currentArg)
+
+ # propagate the result variables to the caller:
+ foreach(arg_name ${_singleArgNames} ${_multiArgNames} ${_optionNames})
+ set(${prefix}_${arg_name} ${${prefix}_${arg_name}} PARENT_SCOPE)
+ endforeach(arg_name)
+ set(${prefix}_UNPARSED_ARGUMENTS ${${prefix}_UNPARSED_ARGUMENTS} PARENT_SCOPE)
+
+endfunction(CMAKE_PARSE_ARGUMENTS _options _singleArgs _multiArgs)
diff --git a/Modules/CMakeParseImplicitLinkInfo.cmake b/Modules/CMakeParseImplicitLinkInfo.cmake
new file mode 100644
index 000000000..ecb20dc6b
--- /dev/null
+++ b/Modules/CMakeParseImplicitLinkInfo.cmake
@@ -0,0 +1,128 @@
+
+#=============================================================================
+# 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.)
+
+# Function parse implicit linker options.
+# This is used internally by CMake and should not be included by user
+# code.
+
+function(CMAKE_PARSE_IMPLICIT_LINK_INFO text lib_var dir_var log_var obj_regex)
+ set(implicit_libs_tmp "")
+ set(implicit_dirs_tmp)
+ set(log "")
+
+ # Parse implicit linker arguments.
+ set(linker "CMAKE_LINKER-NOTFOUND")
+ if(CMAKE_LINKER)
+ get_filename_component(linker ${CMAKE_LINKER} NAME)
+ endif()
+ # 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(log "${log} link line regex: [${linker_regex}]\n")
+ string(REGEX REPLACE "\r?\n" ";" output_lines "${text}")
+ foreach(line IN LISTS output_lines)
+ set(cmd)
+ if("${line}" MATCHES "${linker_regex}" AND
+ NOT "${line}" MATCHES "${linker_exclude_regex}")
+ if(UNIX)
+ separate_arguments(args UNIX_COMMAND "${line}")
+ else()
+ separate_arguments(args WINDOWS_COMMAND "${line}")
+ endif()
+ list(GET args 0 cmd)
+ endif()
+ if("${cmd}" MATCHES "${linker_regex}")
+ set(log "${log} link line: [${line}]\n")
+ string(REGEX REPLACE ";-([LYz]);" ";-\\1" args "${args}")
+ foreach(arg IN LISTS args)
+ if("${arg}" MATCHES "^-L(.:)?[/\\]")
+ # Unix search path.
+ string(REGEX REPLACE "^-L" "" dir "${arg}")
+ list(APPEND implicit_dirs_tmp ${dir})
+ set(log "${log} arg [${arg}] ==> dir [${dir}]\n")
+ elseif("${arg}" MATCHES "^-l[^:]")
+ # Unix library.
+ string(REGEX REPLACE "^-l" "" lib "${arg}")
+ list(APPEND implicit_libs_tmp ${lib})
+ set(log "${log} arg [${arg}] ==> lib [${lib}]\n")
+ elseif("${arg}" MATCHES "^(.:)?[/\\].*\\.a$")
+ # Unix library full path.
+ list(APPEND implicit_libs_tmp ${arg})
+ set(log "${log} arg [${arg}] ==> lib [${arg}]\n")
+ elseif("${arg}" MATCHES "^(.:)?[/\\].*\\.o$"
+ AND obj_regex AND "${arg}" MATCHES "${obj_regex}")
+ # Object file full path.
+ list(APPEND implicit_libs_tmp ${arg})
+ set(log "${log} arg [${arg}] ==> obj [${arg}]\n")
+ elseif("${arg}" MATCHES "^-Y(P,)?[^0-9]")
+ # Sun search path ([^0-9] avoids conflict with Mac -Y<num>).
+ string(REGEX REPLACE "^-Y(P,)?" "" dirs "${arg}")
+ string(REPLACE ":" ";" dirs "${dirs}")
+ list(APPEND implicit_dirs_tmp ${dirs})
+ set(log "${log} arg [${arg}] ==> dirs [${dirs}]\n")
+ elseif("${arg}" MATCHES "^-l:")
+ # HP named library.
+ list(APPEND implicit_libs_tmp ${arg})
+ set(log "${log} arg [${arg}] ==> lib [${arg}]\n")
+ elseif("${arg}" MATCHES "^-z(all|default|weak)extract")
+ # Link editor option.
+ list(APPEND implicit_libs_tmp ${arg})
+ set(log "${log} arg [${arg}] ==> opt [${arg}]\n")
+ else()
+ set(log "${log} arg [${arg}] ==> ignore\n")
+ endif()
+ endforeach()
+ break()
+ 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}")
+ list(APPEND implicit_dirs_tmp ${paths})
+ set(log "${log} dirs [${paths}]\n")
+ else()
+ set(log "${log} ignore line: [${line}]\n")
+ endif()
+ endforeach()
+
+ # Cleanup list of libraries and flags.
+ # 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.*)$")
+ set(log "${log} remove lib [${lib}]\n")
+ else()
+ list(APPEND implicit_libs "${lib}")
+ endif()
+ endforeach()
+
+ # Cleanup list of directories.
+ set(implicit_dirs "")
+ foreach(d IN LISTS implicit_dirs_tmp)
+ get_filename_component(dir "${d}" ABSOLUTE)
+ list(APPEND implicit_dirs "${dir}")
+ set(log "${log} collapse dir [${d}] ==> [${dir}]\n")
+ endforeach()
+ list(REMOVE_DUPLICATES implicit_dirs)
+
+ # Log results.
+ set(log "${log} implicit libs: [${implicit_libs}]\n")
+ set(log "${log} implicit dirs: [${implicit_dirs}]\n")
+
+ # Return results.
+ set(${lib_var} "${implicit_libs}" PARENT_SCOPE)
+ set(${dir_var} "${implicit_dirs}" PARENT_SCOPE)
+ set(${log_var} "${log}" PARENT_SCOPE)
+endfunction()
diff --git a/Modules/CMakePlatformId.h.in b/Modules/CMakePlatformId.h.in
new file mode 100644
index 000000000..6341dca9a
--- /dev/null
+++ b/Modules/CMakePlatformId.h.in
@@ -0,0 +1,157 @@
+/* Identify known platforms by name. */
+#if defined(__linux) || defined(__linux__) || defined(linux)
+# define PLATFORM_ID "Linux"
+
+#elif defined(__CYGWIN__)
+# define PLATFORM_ID "Cygwin"
+
+#elif defined(__MINGW32__)
+# define PLATFORM_ID "MinGW"
+
+#elif defined(__APPLE__)
+# define PLATFORM_ID "Darwin"
+
+#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
+# define PLATFORM_ID "Windows"
+
+#elif defined(__FreeBSD__) || defined(__FreeBSD)
+# define PLATFORM_ID "FreeBSD"
+
+#elif defined(__NetBSD__) || defined(__NetBSD)
+# define PLATFORM_ID "NetBSD"
+
+#elif defined(__OpenBSD__) || defined(__OPENBSD)
+# define PLATFORM_ID "OpenBSD"
+
+#elif defined(__sun) || defined(sun)
+# define PLATFORM_ID "SunOS"
+
+#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__)
+# define PLATFORM_ID "AIX"
+
+#elif defined(__sgi) || defined(__sgi__) || defined(_SGI)
+# define PLATFORM_ID "IRIX"
+
+#elif defined(__hpux) || defined(__hpux__)
+# define PLATFORM_ID "HP-UX"
+
+#elif defined(__HAIKU) || defined(__HAIKU__) || defined(_HAIKU)
+# define PLATFORM_ID "Haiku"
+/* Haiku also defines __BEOS__ so we must
+ put it prior to the check for __BEOS__
+*/
+
+#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS)
+# define PLATFORM_ID "BeOS"
+
+#elif defined(__QNX__) || defined(__QNXNTO__)
+# define PLATFORM_ID "QNX"
+
+#elif defined(__tru64) || defined(_tru64) || defined(__TRU64__)
+# define PLATFORM_ID "Tru64"
+
+#elif defined(__riscos) || defined(__riscos__)
+# define PLATFORM_ID "RISCos"
+
+#elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__)
+# define PLATFORM_ID "SINIX"
+
+#elif defined(__UNIX_SV__)
+# define PLATFORM_ID "UNIX_SV"
+
+#elif defined(__bsdos__)
+# define PLATFORM_ID "BSDOS"
+
+#elif defined(_MPRAS) || defined(MPRAS)
+# define PLATFORM_ID "MP-RAS"
+
+#elif defined(__osf) || defined(__osf__)
+# define PLATFORM_ID "OSF1"
+
+#elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv)
+# define PLATFORM_ID "SCO_SV"
+
+#elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX)
+# define PLATFORM_ID "ULTRIX"
+
+#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX)
+# define PLATFORM_ID "Xenix"
+
+#else /* unknown platform */
+# define PLATFORM_ID ""
+
+#endif
+
+/* For windows compilers MSVC and Intel we can determine
+ the architecture of the compiler being used. This is because
+ the compilers do not have flags that can change the architecture,
+ but rather depend on which compiler is being used
+*/
+#if defined(_WIN32) && defined(_MSC_VER)
+# if defined(_M_IA64)
+# define ARCHITECTURE_ID "IA64"
+
+# elif defined(_M_X64) || defined(_M_AMD64)
+# define ARCHITECTURE_ID "x64"
+
+# elif defined(_M_IX86)
+# define ARCHITECTURE_ID "X86"
+
+# elif defined(_M_ARM)
+# define ARCHITECTURE_ID "ARM"
+
+# else /* unknown architecture */
+# define ARCHITECTURE_ID ""
+# endif
+
+#else
+# define ARCHITECTURE_ID ""
+#endif
+
+/* Convert integer to decimal digit literals. */
+#define DEC(n) \
+ ('0' + (((n) / 10000000)%10)), \
+ ('0' + (((n) / 1000000)%10)), \
+ ('0' + (((n) / 100000)%10)), \
+ ('0' + (((n) / 10000)%10)), \
+ ('0' + (((n) / 1000)%10)), \
+ ('0' + (((n) / 100)%10)), \
+ ('0' + (((n) / 10)%10)), \
+ ('0' + ((n) % 10))
+
+/* Convert integer to hex digit literals. */
+#define HEX(n) \
+ ('0' + ((n)>>28 & 0xF)), \
+ ('0' + ((n)>>24 & 0xF)), \
+ ('0' + ((n)>>20 & 0xF)), \
+ ('0' + ((n)>>16 & 0xF)), \
+ ('0' + ((n)>>12 & 0xF)), \
+ ('0' + ((n)>>8 & 0xF)), \
+ ('0' + ((n)>>4 & 0xF)), \
+ ('0' + ((n) & 0xF))
+
+/* Construct a string literal encoding the version number components. */
+#ifdef COMPILER_VERSION_MAJOR
+char const info_version[] = {
+ 'I', 'N', 'F', 'O', ':',
+ 'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','[',
+ COMPILER_VERSION_MAJOR,
+# ifdef COMPILER_VERSION_MINOR
+ '.', COMPILER_VERSION_MINOR,
+# ifdef COMPILER_VERSION_PATCH
+ '.', COMPILER_VERSION_PATCH,
+# ifdef COMPILER_VERSION_TWEAK
+ '.', COMPILER_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
+ array rather than assigning a pointer to a static array. */
+char const* info_platform = "INFO" ":" "platform[" PLATFORM_ID "]";
+char const* info_arch = "INFO" ":" "arch[" ARCHITECTURE_ID "]";
+
diff --git a/Modules/CMakePrintSystemInformation.cmake b/Modules/CMakePrintSystemInformation.cmake
new file mode 100644
index 000000000..2c5d0f2ae
--- /dev/null
+++ b/Modules/CMakePrintSystemInformation.cmake
@@ -0,0 +1,46 @@
+# - 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.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software 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.)
+
+MESSAGE("CMAKE_SYSTEM is ${CMAKE_SYSTEM} ${CMAKE_SYSTEM_NAME} ${CMAKE_SYSTEM_VERSION}")
+MESSAGE("CMAKE_SYSTEM file is ${CMAKE_SYSTEM_INFO_FILE}")
+MESSAGE("CMAKE_C_COMPILER is ${CMAKE_C_COMPILER}")
+MESSAGE("CMAKE_CXX_COMPILER is ${CMAKE_CXX_COMPILER}")
+
+
+MESSAGE("CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS is ${CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS}")
+MESSAGE("CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS is ${CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS}")
+MESSAGE("CMAKE_DL_LIBS is ${CMAKE_DL_LIBS}")
+MESSAGE("CMAKE_SHARED_LIBRARY_PREFIX is ${CMAKE_SHARED_LIBRARY_PREFIX}")
+MESSAGE("CMAKE_SHARED_LIBRARY_SUFFIX is ${CMAKE_SHARED_LIBRARY_SUFFIX}")
+MESSAGE("CMAKE_COMPILER_IS_GNUCC = ${CMAKE_COMPILER_IS_GNUCC}")
+MESSAGE("CMAKE_COMPILER_IS_GNUCXX = ${CMAKE_COMPILER_IS_GNUCXX}")
+
+MESSAGE("CMAKE_CXX_CREATE_SHARED_LIBRARY is ${CMAKE_CXX_CREATE_SHARED_LIBRARY}")
+MESSAGE("CMAKE_CXX_CREATE_SHARED_MODULE is ${CMAKE_CXX_CREATE_SHARED_MODULE}")
+MESSAGE("CMAKE_CXX_CREATE_STATIC_LIBRARY is ${CMAKE_CXX_CREATE_STATIC_LIBRARY}")
+MESSAGE("CMAKE_CXX_COMPILE_OBJECT is ${CMAKE_CXX_COMPILE_OBJECT}")
+MESSAGE("CMAKE_CXX_LINK_EXECUTABLE ${CMAKE_CXX_LINK_EXECUTABLE}")
+
+MESSAGE("CMAKE_C_CREATE_SHARED_LIBRARY is ${CMAKE_C_CREATE_SHARED_LIBRARY}")
+MESSAGE("CMAKE_C_CREATE_SHARED_MODULE is ${CMAKE_C_CREATE_SHARED_MODULE}")
+MESSAGE("CMAKE_C_CREATE_STATIC_LIBRARY is ${CMAKE_C_CREATE_STATIC_LIBRARY}")
+MESSAGE("CMAKE_C_COMPILE_OBJECT is ${CMAKE_C_COMPILE_OBJECT}")
+MESSAGE("CMAKE_C_LINK_EXECUTABLE ${CMAKE_C_LINK_EXECUTABLE}")
+
+MESSAGE("CMAKE_SYSTEM_AND_CXX_COMPILER_INFO_FILE ${CMAKE_SYSTEM_AND_CXX_COMPILER_INFO_FILE}")
+MESSAGE("CMAKE_SYSTEM_AND_C_COMPILER_INFO_FILE ${CMAKE_SYSTEM_AND_C_COMPILER_INFO_FILE}")
diff --git a/Modules/CMakePushCheckState.cmake b/Modules/CMakePushCheckState.cmake
new file mode 100644
index 000000000..0a4212818
--- /dev/null
+++ b/Modules/CMakePushCheckState.cmake
@@ -0,0 +1,61 @@
+# This module defines two macros:
+# CMAKE_PUSH_CHECK_STATE()
+# and
+# CMAKE_POP_CHECK_STATE()
+# These two macros can be used to save and restore 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.
+#
+# Usage:
+# cmake_push_check_state()
+# set(CMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} -DSOME_MORE_DEF)
+# check_function_exists(...)
+# cmake_pop_check_state()
+
+#=============================================================================
+# Copyright 2006-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.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+
+MACRO(CMAKE_PUSH_CHECK_STATE)
+
+ IF(NOT DEFINED _CMAKE_PUSH_CHECK_STATE_COUNTER)
+ SET(_CMAKE_PUSH_CHECK_STATE_COUNTER 0)
+ ENDIF()
+
+ MATH(EXPR _CMAKE_PUSH_CHECK_STATE_COUNTER "${_CMAKE_PUSH_CHECK_STATE_COUNTER}+1")
+
+ SET(_CMAKE_REQUIRED_INCLUDES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER} ${CMAKE_REQUIRED_INCLUDES})
+ 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})
+ENDMACRO(CMAKE_PUSH_CHECK_STATE)
+
+MACRO(CMAKE_POP_CHECK_STATE)
+
+# don't pop more than we pushed
+ IF("${_CMAKE_PUSH_CHECK_STATE_COUNTER}" GREATER "0")
+
+ SET(CMAKE_REQUIRED_INCLUDES ${_CMAKE_REQUIRED_INCLUDES_SAVE_${_CMAKE_PUSH_CHECK_STATE_COUNTER}})
+ 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}})
+
+ MATH(EXPR _CMAKE_PUSH_CHECK_STATE_COUNTER "${_CMAKE_PUSH_CHECK_STATE_COUNTER}-1")
+ ENDIF()
+
+ENDMACRO(CMAKE_POP_CHECK_STATE)
diff --git a/Modules/CMakeRCCompiler.cmake.in b/Modules/CMakeRCCompiler.cmake.in
new file mode 100644
index 000000000..83428e2eb
--- /dev/null
+++ b/Modules/CMakeRCCompiler.cmake.in
@@ -0,0 +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_OUTPUT_EXTENSION @CMAKE_RC_OUTPUT_EXTENSION@)
+SET(CMAKE_RC_COMPILER_ENV_VAR "RC")
diff --git a/Modules/CMakeRCInformation.cmake b/Modules/CMakeRCInformation.cmake
new file mode 100644
index 000000000..859fe1158
--- /dev/null
+++ b/Modules/CMakeRCInformation.cmake
@@ -0,0 +1,53 @@
+
+#=============================================================================
+# 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.)
+
+
+# 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.
+
+# 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")
+ENDIF()
+SET(CMAKE_SYSTEM_AND_RC_COMPILER_INFO_FILE
+ ${CMAKE_ROOT}/Modules/Platform/${CMAKE_SYSTEM_NAME}-${CMAKE_BASE_NAME}.cmake)
+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.")
+
+# 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
+# to filter out any other flags
+SET(CMAKE_RC_FLAG_REGEX "^[-/](D|I)")
+
+# now define the following rule variables
+# CMAKE_RC_COMPILE_OBJECT
+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>")
+ENDIF(NOT CMAKE_RC_COMPILE_OBJECT)
+
+MARK_AS_ADVANCED(
+CMAKE_RC_FLAGS
+)
+# set this variable so we can avoid loading this more than once.
+SET(CMAKE_RC_INFORMATION_LOADED 1)
diff --git a/Modules/CMakeSystem.cmake.in b/Modules/CMakeSystem.cmake.in
new file mode 100644
index 000000000..a9f3a552d
--- /dev/null
+++ b/Modules/CMakeSystem.cmake.in
@@ -0,0 +1,15 @@
+@INCLUDE_CMAKE_TOOLCHAIN_FILE_IF_REQUIRED@
+
+SET(CMAKE_SYSTEM "@CMAKE_SYSTEM@")
+SET(CMAKE_SYSTEM_NAME "@CMAKE_SYSTEM_NAME@")
+SET(CMAKE_SYSTEM_VERSION "@CMAKE_SYSTEM_VERSION@")
+SET(CMAKE_SYSTEM_PROCESSOR "@CMAKE_SYSTEM_PROCESSOR@")
+
+SET(CMAKE_HOST_SYSTEM "@CMAKE_HOST_SYSTEM@")
+SET(CMAKE_HOST_SYSTEM_NAME "@CMAKE_HOST_SYSTEM_NAME@")
+SET(CMAKE_HOST_SYSTEM_VERSION "@CMAKE_HOST_SYSTEM_VERSION@")
+SET(CMAKE_HOST_SYSTEM_PROCESSOR "@CMAKE_HOST_SYSTEM_PROCESSOR@")
+
+SET(CMAKE_CROSSCOMPILING "@CMAKE_CROSSCOMPILING@")
+
+SET(CMAKE_SYSTEM_LOADED 1)
diff --git a/Modules/CMakeSystemSpecificInformation.cmake b/Modules/CMakeSystemSpecificInformation.cmake
new file mode 100644
index 000000000..faa9e3625
--- /dev/null
+++ b/Modules/CMakeSystemSpecificInformation.cmake
@@ -0,0 +1,69 @@
+
+#=============================================================================
+# 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 file is included by cmGlobalGenerator::EnableLanguage.
+# It is included after the compiler has been determined, so
+# we know things like the compiler name and if the compiler is gnu.
+
+# before cmake 2.6 these variables were set in cmMakefile.cxx. This is still
+# done to keep scripts and custom language and compiler modules working.
+# But they are reset here and set again in the platform files for the target
+# platform, so they can be used for testing the target platform instead
+# of testing the host platform.
+SET(APPLE )
+SET(UNIX )
+SET(CYGWIN )
+SET(WIN32 )
+
+
+# include Generic system information
+INCLUDE(CMakeGenericSystem)
+
+# 2. now include SystemName.cmake file to set the system specific information
+SET(CMAKE_SYSTEM_INFO_FILE Platform/${CMAKE_SYSTEM_NAME})
+
+INCLUDE(${CMAKE_SYSTEM_INFO_FILE} OPTIONAL RESULT_VARIABLE _INCLUDED_SYSTEM_INFO_FILE)
+
+IF(NOT _INCLUDED_SYSTEM_INFO_FILE)
+ MESSAGE("System is unknown to cmake, create:\n${CMAKE_SYSTEM_INFO_FILE}"
+ " to use this system, please send your config file to "
+ "cmake@www.cmake.org so it can be added to cmake")
+ IF(EXISTS ${CMAKE_BINARY_DIR}/CMakeCache.txt)
+ CONFIGURE_FILE(${CMAKE_BINARY_DIR}/CMakeCache.txt
+ ${CMAKE_BINARY_DIR}/CopyOfCMakeCache.txt COPYONLY)
+ MESSAGE("Your CMakeCache.txt file was copied to CopyOfCMakeCache.txt. "
+ "Please send that file to cmake@www.cmake.org.")
+ ENDIF(EXISTS ${CMAKE_BINARY_DIR}/CMakeCache.txt)
+ENDIF(NOT _INCLUDED_SYSTEM_INFO_FILE)
+
+
+# optionally include a file which can do extra-generator specific things, e.g.
+# CMakeFindEclipseCDT4.cmake asks gcc for the system include dirs for the Eclipse CDT4 generator
+IF(CMAKE_EXTRA_GENERATOR)
+ STRING(REPLACE " " "" _CMAKE_EXTRA_GENERATOR_NO_SPACES ${CMAKE_EXTRA_GENERATOR} )
+ INCLUDE("CMakeFind${_CMAKE_EXTRA_GENERATOR_NO_SPACES}" OPTIONAL)
+ENDIF(CMAKE_EXTRA_GENERATOR)
+
+
+# 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
+# this has to be done after the system information has been loaded
+IF(NOT CMAKE_MODULE_EXISTS)
+ SET(CMAKE_SHARED_MODULE_PREFIX "${CMAKE_SHARED_LIBRARY_PREFIX}")
+ SET(CMAKE_SHARED_MODULE_SUFFIX "${CMAKE_SHARED_LIBRARY_SUFFIX}")
+ENDIF(NOT CMAKE_MODULE_EXISTS)
+
+
+SET(CMAKE_SYSTEM_SPECIFIC_INFORMATION_LOADED 1)
diff --git a/Modules/CMakeTestASM-ATTCompiler.cmake b/Modules/CMakeTestASM-ATTCompiler.cmake
new file mode 100644
index 000000000..581ad0c23
--- /dev/null
+++ b/Modules/CMakeTestASM-ATTCompiler.cmake
@@ -0,0 +1,23 @@
+
+#=============================================================================
+# 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.)
+
+# This file is used by EnableLanguage in cmGlobalGenerator to
+# determine that the selected ASM-ATT "compiler" works.
+# For assembler this can only check whether the compiler has been found,
+# because otherwise there would have to be a separate assembler source file
+# for each assembler on every architecture.
+
+SET(ASM_DIALECT "-ATT")
+INCLUDE(CMakeTestASMCompiler)
+SET(ASM_DIALECT)
diff --git a/Modules/CMakeTestASMCompiler.cmake b/Modules/CMakeTestASMCompiler.cmake
new file mode 100644
index 000000000..294511d89
--- /dev/null
+++ b/Modules/CMakeTestASMCompiler.cmake
@@ -0,0 +1,35 @@
+
+#=============================================================================
+# 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.)
+
+# This file is used by EnableLanguage in cmGlobalGenerator to
+# determine that the selected ASM compiler works.
+# For assembler this can only check whether the compiler has been found,
+# because otherwise there would have to be a separate assembler source file
+# for each assembler on every architecture.
+
+
+SET(_ASM_COMPILER_WORKS 0)
+
+IF(CMAKE_ASM${ASM_DIALECT}_COMPILER)
+ SET(_ASM_COMPILER_WORKS 1)
+ENDIF()
+
+# when using generic "ASM" support, we must have detected the compiler ID, fail otherwise:
+IF("ASM${ASM_DIALECT}" STREQUAL "ASM")
+ IF(NOT CMAKE_ASM${ASM_DIALECT}_COMPILER_ID)
+ SET(_ASM_COMPILER_WORKS 0)
+ ENDIF()
+ENDIF()
+
+SET(CMAKE_ASM${ASM_DIALECT}_COMPILER_WORKS ${_ASM_COMPILER_WORKS} CACHE INTERNAL "")
diff --git a/Modules/CMakeTestASM_MASMCompiler.cmake b/Modules/CMakeTestASM_MASMCompiler.cmake
new file mode 100644
index 000000000..8369b942c
--- /dev/null
+++ b/Modules/CMakeTestASM_MASMCompiler.cmake
@@ -0,0 +1,23 @@
+
+#=============================================================================
+# Copyright 2008-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 used by EnableLanguage in cmGlobalGenerator to
+# determine that the selected ASM_MASM "compiler" (should be masm or masm64)
+# works. For assembler this can only check whether the compiler has been found,
+# because otherwise there would have to be a separate assembler source file
+# for each assembler on every architecture.
+
+SET(ASM_DIALECT "_MASM")
+INCLUDE(CMakeTestASMCompiler)
+SET(ASM_DIALECT)
diff --git a/Modules/CMakeTestASM_NASMCompiler.cmake b/Modules/CMakeTestASM_NASMCompiler.cmake
new file mode 100644
index 000000000..a5e2bea0a
--- /dev/null
+++ b/Modules/CMakeTestASM_NASMCompiler.cmake
@@ -0,0 +1,23 @@
+
+#=============================================================================
+# Copyright 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.)
+
+# This file is used by EnableLanguage in cmGlobalGenerator to
+# determine that the selected ASM_NASM "compiler" works.
+# For assembler this can only check whether the compiler has been found,
+# because otherwise there would have to be a separate assembler source file
+# for each assembler on every architecture.
+
+SET(ASM_DIALECT "_NASM")
+INCLUDE(CMakeTestASMCompiler)
+SET(ASM_DIALECT)
diff --git a/Modules/CMakeTestCCompiler.cmake b/Modules/CMakeTestCCompiler.cmake
new file mode 100644
index 000000000..779b2f007
--- /dev/null
+++ b/Modules/CMakeTestCCompiler.cmake
@@ -0,0 +1,87 @@
+
+#=============================================================================
+# 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.)
+
+INCLUDE(CMakeTestCompilerCommon)
+
+# 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_C_COMPILER_WORKS)
+ PrintTestCompilerStatus("C" "")
+ FILE(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testCCompiler.c
+ "#ifdef __cplusplus\n"
+ "# error \"The CMAKE_C_COMPILER is set to a C++ compiler\"\n"
+ "#endif\n"
+ "#if defined(__CLASSIC_C__)\n"
+ "int main(argc, argv)\n"
+ " int argc;\n"
+ " char* argv[];\n"
+ "#else\n"
+ "int main(int argc, char* argv[])\n"
+ "#endif\n"
+ "{ (void)argv; return argc-1;}\n")
+ TRY_COMPILE(CMAKE_C_COMPILER_WORKS ${CMAKE_BINARY_DIR}
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testCCompiler.c
+ OUTPUT_VARIABLE __CMAKE_C_COMPILER_OUTPUT)
+ SET(C_TEST_WAS_RUN 1)
+ENDIF(NOT CMAKE_C_COMPILER_WORKS)
+
+IF(NOT CMAKE_C_COMPILER_WORKS)
+ PrintTestCompilerStatus("C" " -- broken")
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Determining if the C compiler works failed with "
+ "the following output:\n${__CMAKE_C_COMPILER_OUTPUT}\n\n")
+ # if the compiler is broken make sure to remove the platform file
+ # since Windows-cl configures both c/cxx files both need to be removed
+ # when c or c++ fails
+ FILE(REMOVE ${CMAKE_PLATFORM_ROOT_BIN}/CMakeCPlatform.cmake )
+ FILE(REMOVE ${CMAKE_PLATFORM_ROOT_BIN}/CMakeCXXPlatform.cmake )
+ MESSAGE(FATAL_ERROR "The C compiler \"${CMAKE_C_COMPILER}\" "
+ "is not able to compile a simple test program.\nIt fails "
+ "with the following output:\n ${__CMAKE_C_COMPILER_OUTPUT}\n\n"
+ "CMake will not be able to correctly generate this project.")
+ELSE(NOT CMAKE_C_COMPILER_WORKS)
+ IF(C_TEST_WAS_RUN)
+ PrintTestCompilerStatus("C" " -- works")
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "Determining if the C compiler works passed with "
+ "the following output:\n${__CMAKE_C_COMPILER_OUTPUT}\n\n")
+ ENDIF(C_TEST_WAS_RUN)
+ SET(CMAKE_C_COMPILER_WORKS 1 CACHE INTERNAL "")
+
+ IF(CMAKE_C_COMPILER_FORCED)
+ # The compiler configuration was forced by the user.
+ # Assume the user has configured all compiler information.
+ ELSE(CMAKE_C_COMPILER_FORCED)
+ # 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)
+ CONFIGURE_FILE(
+ ${CMAKE_ROOT}/Modules/CMakeCCompiler.cmake.in
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeCCompiler.cmake
+ @ONLY IMMEDIATE # IMMEDIATE must be here for compatibility mode <= 2.0
+ )
+ INCLUDE(${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeCCompiler.cmake)
+ ENDIF(CMAKE_C_COMPILER_FORCED)
+ IF(CMAKE_C_SIZEOF_DATA_PTR)
+ FOREACH(f ${CMAKE_C_ABI_FILES})
+ INCLUDE(${f})
+ ENDFOREACH()
+ UNSET(CMAKE_C_ABI_FILES)
+ ENDIF()
+ENDIF(NOT CMAKE_C_COMPILER_WORKS)
+
+UNSET(__CMAKE_C_COMPILER_OUTPUT)
diff --git a/Modules/CMakeTestCXXCompiler.cmake b/Modules/CMakeTestCXXCompiler.cmake
new file mode 100644
index 000000000..87022e9f9
--- /dev/null
+++ b/Modules/CMakeTestCXXCompiler.cmake
@@ -0,0 +1,80 @@
+
+#=============================================================================
+# 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.)
+
+INCLUDE(CMakeTestCompilerCommon)
+
+# 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_CXX_COMPILER_WORKS)
+ PrintTestCompilerStatus("CXX" "")
+ FILE(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testCXXCompiler.cxx
+ "#ifndef __cplusplus\n"
+ "# error \"The CMAKE_CXX_COMPILER is set to a C compiler\"\n"
+ "#endif\n"
+ "int main(){return 0;}\n")
+ TRY_COMPILE(CMAKE_CXX_COMPILER_WORKS ${CMAKE_BINARY_DIR}
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testCXXCompiler.cxx
+ OUTPUT_VARIABLE __CMAKE_CXX_COMPILER_OUTPUT)
+ SET(CXX_TEST_WAS_RUN 1)
+ENDIF(NOT CMAKE_CXX_COMPILER_WORKS)
+
+IF(NOT CMAKE_CXX_COMPILER_WORKS)
+ PrintTestCompilerStatus("CXX" " -- broken")
+ # if the compiler is broken make sure to remove the platform file
+ # since Windows-cl configures both c/cxx files both need to be removed
+ # when c or c++ fails
+ FILE(REMOVE ${CMAKE_PLATFORM_ROOT_BIN}/CMakeCPlatform.cmake )
+ FILE(REMOVE ${CMAKE_PLATFORM_ROOT_BIN}/CMakeCXXPlatform.cmake )
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Determining if the CXX compiler works failed with "
+ "the following output:\n${__CMAKE_CXX_COMPILER_OUTPUT}\n\n")
+ MESSAGE(FATAL_ERROR "The C++ compiler \"${CMAKE_CXX_COMPILER}\" "
+ "is not able to compile a simple test program.\nIt fails "
+ "with the following output:\n ${__CMAKE_CXX_COMPILER_OUTPUT}\n\n"
+ "CMake will not be able to correctly generate this project.")
+ELSE(NOT CMAKE_CXX_COMPILER_WORKS)
+ IF(CXX_TEST_WAS_RUN)
+ PrintTestCompilerStatus("CXX" " -- works")
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "Determining if the CXX compiler works passed with "
+ "the following output:\n${__CMAKE_CXX_COMPILER_OUTPUT}\n\n")
+ ENDIF(CXX_TEST_WAS_RUN)
+ SET(CMAKE_CXX_COMPILER_WORKS 1 CACHE INTERNAL "")
+
+ IF(CMAKE_CXX_COMPILER_FORCED)
+ # The compiler configuration was forced by the user.
+ # Assume the user has configured all compiler information.
+ ELSE(CMAKE_CXX_COMPILER_FORCED)
+ # 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)
+ CONFIGURE_FILE(
+ ${CMAKE_ROOT}/Modules/CMakeCXXCompiler.cmake.in
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeCXXCompiler.cmake
+ @ONLY IMMEDIATE # IMMEDIATE must be here for compatibility mode <= 2.0
+ )
+ INCLUDE(${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeCXXCompiler.cmake)
+ ENDIF(CMAKE_CXX_COMPILER_FORCED)
+ IF(CMAKE_CXX_SIZEOF_DATA_PTR)
+ FOREACH(f ${CMAKE_CXX_ABI_FILES})
+ INCLUDE(${f})
+ ENDFOREACH()
+ UNSET(CMAKE_CXX_ABI_FILES)
+ ENDIF()
+ENDIF(NOT CMAKE_CXX_COMPILER_WORKS)
+
+UNSET(__CMAKE_CXX_COMPILER_OUTPUT)
diff --git a/Modules/CMakeTestCompilerCommon.cmake b/Modules/CMakeTestCompilerCommon.cmake
new file mode 100644
index 000000000..fd8a105b2
--- /dev/null
+++ b/Modules/CMakeTestCompilerCommon.cmake
@@ -0,0 +1,21 @@
+
+#=============================================================================
+# Copyright 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.)
+
+function(PrintTestCompilerStatus LANG MSG)
+ IF(CMAKE_GENERATOR MATCHES Make)
+ MESSAGE(STATUS "Check for working ${LANG} compiler: ${CMAKE_${LANG}_COMPILER}${MSG}")
+ ELSE()
+ MESSAGE(STATUS "Check for working ${LANG} compiler using: ${CMAKE_GENERATOR}${MSG}")
+ ENDIF()
+endfunction()
diff --git a/Modules/CMakeTestForFreeVC.cxx b/Modules/CMakeTestForFreeVC.cxx
new file mode 100644
index 000000000..e580c1f6b
--- /dev/null
+++ b/Modules/CMakeTestForFreeVC.cxx
@@ -0,0 +1,3 @@
+#include<iostream>
+
+int main(){return 0;}
diff --git a/Modules/CMakeTestFortranCompiler.cmake b/Modules/CMakeTestFortranCompiler.cmake
new file mode 100644
index 000000000..b4dcea634
--- /dev/null
+++ b/Modules/CMakeTestFortranCompiler.cmake
@@ -0,0 +1,101 @@
+
+#=============================================================================
+# 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.)
+
+INCLUDE(CMakeTestCompilerCommon)
+
+# This file is used by EnableLanguage in cmGlobalGenerator to
+# determine that that selected Fortran 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_Fortran_COMPILER_WORKS)
+ PrintTestCompilerStatus("Fortran" "")
+ FILE(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testFortranCompiler.f "
+ PROGRAM TESTFortran
+ PRINT *, 'Hello'
+ END
+ ")
+ TRY_COMPILE(CMAKE_Fortran_COMPILER_WORKS ${CMAKE_BINARY_DIR}
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testFortranCompiler.f
+ OUTPUT_VARIABLE OUTPUT)
+ SET(FORTRAN_TEST_WAS_RUN 1)
+ENDIF(NOT CMAKE_Fortran_COMPILER_WORKS)
+
+IF(NOT CMAKE_Fortran_COMPILER_WORKS)
+ PrintTestCompilerStatus("Fortran" " -- broken")
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Determining if the Fortran compiler works failed with "
+ "the following output:\n${OUTPUT}\n\n")
+ MESSAGE(FATAL_ERROR "The Fortran compiler \"${CMAKE_Fortran_COMPILER}\" "
+ "is not able to compile a simple test program.\nIt fails "
+ "with the following output:\n ${OUTPUT}\n\n"
+ "CMake will not be able to correctly generate this project.")
+ELSE(NOT CMAKE_Fortran_COMPILER_WORKS)
+ IF(FORTRAN_TEST_WAS_RUN)
+ PrintTestCompilerStatus("Fortran" " -- works")
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "Determining if the Fortran compiler works passed with "
+ "the following output:\n${OUTPUT}\n\n")
+ ENDIF(FORTRAN_TEST_WAS_RUN)
+ SET(CMAKE_Fortran_COMPILER_WORKS 1 CACHE INTERNAL "")
+
+ IF(CMAKE_Fortran_COMPILER_FORCED)
+ # The compiler configuration was forced by the user.
+ # Assume the user has configured all compiler information.
+ ELSE(CMAKE_Fortran_COMPILER_FORCED)
+ # Try to identify the ABI and configure it into CMakeFortranCompiler.cmake
+ INCLUDE(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerABI.cmake)
+ CMAKE_DETERMINE_COMPILER_ABI(Fortran ${CMAKE_ROOT}/Modules/CMakeFortranCompilerABI.F)
+
+ # Test for Fortran 90 support by using an f90-specific construct.
+ IF(NOT DEFINED CMAKE_Fortran_COMPILER_SUPPORTS_F90)
+ MESSAGE(STATUS "Checking whether ${CMAKE_Fortran_COMPILER} supports Fortran 90")
+ FILE(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testFortranCompilerF90.f90 "
+ PROGRAM TESTFortran90
+ stop = 1 ; do while ( stop .eq. 0 ) ; end do
+ END PROGRAM TESTFortran90
+")
+ TRY_COMPILE(CMAKE_Fortran_COMPILER_SUPPORTS_F90 ${CMAKE_BINARY_DIR}
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testFortranCompilerF90.f90
+ OUTPUT_VARIABLE OUTPUT)
+ IF(CMAKE_Fortran_COMPILER_SUPPORTS_F90)
+ MESSAGE(STATUS "Checking whether ${CMAKE_Fortran_COMPILER} supports Fortran 90 -- yes")
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "Determining if the Fortran compiler supports Fortran 90 passed with "
+ "the following output:\n${OUTPUT}\n\n")
+ SET(CMAKE_Fortran_COMPILER_SUPPORTS_F90 1)
+ ELSE(CMAKE_Fortran_COMPILER_SUPPORTS_F90)
+ MESSAGE(STATUS "Checking whether ${CMAKE_Fortran_COMPILER} supports Fortran 90 -- no")
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Determining if the Fortran compiler supports Fortran 90 failed with "
+ "the following output:\n${OUTPUT}\n\n")
+ SET(CMAKE_Fortran_COMPILER_SUPPORTS_F90 0)
+ ENDIF(CMAKE_Fortran_COMPILER_SUPPORTS_F90)
+ UNSET(CMAKE_Fortran_COMPILER_SUPPORTS_F90 CACHE)
+ ENDIF(NOT DEFINED CMAKE_Fortran_COMPILER_SUPPORTS_F90)
+
+ CONFIGURE_FILE(
+ ${CMAKE_ROOT}/Modules/CMakeFortranCompiler.cmake.in
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeFortranCompiler.cmake
+ @ONLY IMMEDIATE # IMMEDIATE must be here for compatibility mode <= 2.0
+ )
+ INCLUDE(${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeFortranCompiler.cmake)
+ ENDIF(CMAKE_Fortran_COMPILER_FORCED)
+ IF(CMAKE_Fortran_SIZEOF_DATA_PTR)
+ FOREACH(f ${CMAKE_Fortran_ABI_FILES})
+ INCLUDE(${f})
+ ENDFOREACH()
+ UNSET(CMAKE_Fortran_ABI_FILES)
+ ENDIF()
+ENDIF(NOT CMAKE_Fortran_COMPILER_WORKS)
diff --git a/Modules/CMakeTestGNU.c b/Modules/CMakeTestGNU.c
new file mode 100644
index 000000000..933e5a212
--- /dev/null
+++ b/Modules/CMakeTestGNU.c
@@ -0,0 +1,9 @@
+#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
+void THIS_IS_GNU();
+#endif
+#ifdef __MINGW32__
+void THIS_IS_MINGW();
+#endif
+#ifdef __CYGWIN__
+void THIS_IS_CYGWIN();
+#endif
diff --git a/Modules/CMakeTestJavaCompiler.cmake b/Modules/CMakeTestJavaCompiler.cmake
new file mode 100644
index 000000000..cfd3e24b6
--- /dev/null
+++ b/Modules/CMakeTestJavaCompiler.cmake
@@ -0,0 +1,20 @@
+
+#=============================================================================
+# 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.)
+
+# This file is used by EnableLanguage in cmGlobalGenerator to
+# determine that that selected Fortran 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.
+SET(CMAKE_Java_COMPILER_WORKS 1 CACHE INTERNAL "")
diff --git a/Modules/CMakeTestNMakeCLVersion.c b/Modules/CMakeTestNMakeCLVersion.c
new file mode 100644
index 000000000..3cece2a63
--- /dev/null
+++ b/Modules/CMakeTestNMakeCLVersion.c
@@ -0,0 +1,2 @@
+VERSION=_MSC_VER
+
diff --git a/Modules/CMakeTestRCCompiler.cmake b/Modules/CMakeTestRCCompiler.cmake
new file mode 100644
index 000000000..a5c8d1149
--- /dev/null
+++ b/Modules/CMakeTestRCCompiler.cmake
@@ -0,0 +1,23 @@
+
+#=============================================================================
+# 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.)
+
+# This file is used by EnableLanguage in cmGlobalGenerator to
+# determine that that selected RC 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.
+
+# For now there is no way to do a try compile on just a .rc file
+# so just do nothing in here.
+SET(CMAKE_RC_COMPILER_WORKS 1 CACHE INTERNAL "")
diff --git a/Modules/CMakeTestWatcomVersion.c b/Modules/CMakeTestWatcomVersion.c
new file mode 100644
index 000000000..0343fb127
--- /dev/null
+++ b/Modules/CMakeTestWatcomVersion.c
@@ -0,0 +1 @@
+VERSION=__WATCOMC__
diff --git a/Modules/CMakeUnixFindMake.cmake b/Modules/CMakeUnixFindMake.cmake
new file mode 100644
index 000000000..39962c0d3
--- /dev/null
+++ b/Modules/CMakeUnixFindMake.cmake
@@ -0,0 +1,16 @@
+
+#=============================================================================
+# 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 gmake make smake)
+MARK_AS_ADVANCED(CMAKE_MAKE_PROGRAM)
diff --git a/Modules/CMakeVS10FindMake.cmake b/Modules/CMakeVS10FindMake.cmake
new file mode 100644
index 000000000..695e92f52
--- /dev/null
+++ b/Modules/CMakeVS10FindMake.cmake
@@ -0,0 +1,54 @@
+
+#=============================================================================
+# 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
new file mode 100644
index 000000000..302efaa59
--- /dev/null
+++ b/Modules/CMakeVS11FindMake.cmake
@@ -0,0 +1,54 @@
+
+#=============================================================================
+# 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. 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\\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/CMakeVS6BackwardCompatibility.cmake b/Modules/CMakeVS6BackwardCompatibility.cmake
new file mode 100644
index 000000000..438f64f6c
--- /dev/null
+++ b/Modules/CMakeVS6BackwardCompatibility.cmake
@@ -0,0 +1,26 @@
+
+#=============================================================================
+# 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.)
+
+# hard code these for fast backwards compatibility tests
+SET (CMAKE_SIZEOF_INT 4 CACHE INTERNAL "Size of int data type")
+SET (CMAKE_SIZEOF_LONG 4 CACHE INTERNAL "Size of long data type")
+SET (CMAKE_SIZEOF_VOID_P 4 CACHE INTERNAL "Size of void* data type")
+SET (CMAKE_SIZEOF_CHAR 1 CACHE INTERNAL "Size of char data type")
+SET (CMAKE_SIZEOF_SHORT 2 CACHE INTERNAL "Size of short data type")
+SET (CMAKE_SIZEOF_FLOAT 4 CACHE INTERNAL "Size of float data type")
+SET (CMAKE_SIZEOF_DOUBLE 8 CACHE INTERNAL "Size of double data type")
+SET (CMAKE_NO_ANSI_FOR_SCOPE 1 CACHE INTERNAL
+ "Does the compiler support ansi for scope.")
+SET (CMAKE_USE_WIN32_THREADS TRUE CACHE BOOL "Use the win32 thread library.")
+SET (CMAKE_WORDS_BIGENDIAN 0 CACHE INTERNAL "endianness of bytes")
diff --git a/Modules/CMakeVS6FindMake.cmake b/Modules/CMakeVS6FindMake.cmake
new file mode 100644
index 000000000..dccf8c462
--- /dev/null
+++ b/Modules/CMakeVS6FindMake.cmake
@@ -0,0 +1,25 @@
+
+#=============================================================================
+# 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
new file mode 100644
index 000000000..2381adb55
--- /dev/null
+++ b/Modules/CMakeVS71FindMake.cmake
@@ -0,0 +1,26 @@
+
+#=============================================================================
+# 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/CMakeVS7BackwardCompatibility.cmake b/Modules/CMakeVS7BackwardCompatibility.cmake
new file mode 100644
index 000000000..df0b3bb97
--- /dev/null
+++ b/Modules/CMakeVS7BackwardCompatibility.cmake
@@ -0,0 +1,26 @@
+
+#=============================================================================
+# 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.)
+
+# hard code these for fast backwards compatibility tests
+SET (CMAKE_SIZEOF_INT 4 CACHE INTERNAL "Size of int data type")
+SET (CMAKE_SIZEOF_LONG 4 CACHE INTERNAL "Size of long data type")
+SET (CMAKE_SIZEOF_VOID_P 4 CACHE INTERNAL "Size of void* data type")
+SET (CMAKE_SIZEOF_CHAR 1 CACHE INTERNAL "Size of char data type")
+SET (CMAKE_SIZEOF_SHORT 2 CACHE INTERNAL "Size of short data type")
+SET (CMAKE_SIZEOF_FLOAT 4 CACHE INTERNAL "Size of float data type")
+SET (CMAKE_SIZEOF_DOUBLE 8 CACHE INTERNAL "Size of double data type")
+SET (CMAKE_NO_ANSI_FOR_SCOPE 0 CACHE INTERNAL
+ "Does the compiler support ansi for scope.")
+SET (CMAKE_USE_WIN32_THREADS TRUE CACHE BOOL "Use the win32 thread library.")
+SET (CMAKE_WORDS_BIGENDIAN 0 CACHE INTERNAL "endianness of bytes")
diff --git a/Modules/CMakeVS7FindMake.cmake b/Modules/CMakeVS7FindMake.cmake
new file mode 100644
index 000000000..665158c88
--- /dev/null
+++ b/Modules/CMakeVS7FindMake.cmake
@@ -0,0 +1,25 @@
+
+#=============================================================================
+# 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
new file mode 100644
index 000000000..bb0818014
--- /dev/null
+++ b/Modules/CMakeVS8FindMake.cmake
@@ -0,0 +1,34 @@
+
+#=============================================================================
+# 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(NOT CMAKE_CROSSCOMPILING)
+
+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
new file mode 100644
index 000000000..9e3c39ef3
--- /dev/null
+++ b/Modules/CMakeVS9FindMake.cmake
@@ -0,0 +1,39 @@
+
+#=============================================================================
+# 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(NOT CMAKE_CROSSCOMPILING)
+
+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
new file mode 100644
index 000000000..75783691f
--- /dev/null
+++ b/Modules/CMakeVerifyManifest.cmake
@@ -0,0 +1,115 @@
+# 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 first recursively globs *.manifest files from
+# the current directory. Then globs *.exe and *.dll. Each
+# .exe and .dll is scanned for embeded manifests and the versions
+# of CRT are compared to those found in the .manifest files
+# from the first glob.
+
+#=============================================================================
+# Copyright 2008-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.)
+
+
+# crt_version:
+# function to extract the CRT version from a file
+# this can be passed a .exe, .dll, or a .manifest file
+# it will put the list of versions found into the variable
+# specified by list_var
+function(crt_version file list_var)
+ file(STRINGS "${file}" strings REGEX "Microsoft.VC...CRT" NEWLINE_CONSUME)
+ foreach(s ${strings})
+ set(has_match 1)
+ string(REGEX
+ REPLACE ".*<assembly.*\"Microsoft.VC...CRT\".*version=\"([^\"]*)\".*</assembly>.*$" "\\1"
+ version "${s}")
+ if(NOT "${version}" STREQUAL "")
+ list(APPEND version_list ${version})
+ else()
+ message(FATAL_ERROR "Parse error could not find version in [${s}]")
+ endif()
+ endforeach(s)
+ if(NOT DEFINED has_match)
+ message("Information: no embeded manifest in: ${file}")
+ return()
+ endif()
+ list(APPEND version_list ${${list_var}})
+ list(REMOVE_DUPLICATES version_list)
+ if(version_list)
+ set(${list_var} ${version_list} PARENT_SCOPE)
+ endif()
+endfunction(crt_version)
+set(fatal_error FALSE)
+
+# check_version:
+#
+# test a file against the shipped manifest versions
+# for a directory
+function(check_version file manifest_versions)
+ set(manifest_versions ${manifest_versions} ${allow_versions})
+ # collect versions for a given file
+ crt_version(${file} file_versions)
+ # see if the versions
+ foreach(ver ${file_versions})
+ list(FIND manifest_versions "${ver}" found_version)
+ if("${found_version}" EQUAL -1)
+ message("ERROR: ${file} uses ${ver} not found in shipped manifests:[${manifest_versions}].")
+ set(fatal_error TRUE PARENT_SCOPE)
+ endif()
+ endforeach(ver)
+ list(LENGTH file_versions len)
+ if(${len} GREATER 1)
+ message("WARNING: found more than one version of MICROSOFT.VC80.CRT referenced in ${file}: [${file_versions}]")
+ endif()
+endfunction()
+
+# collect up the versions of CRT that are shipped
+# in .manifest files
+set(manifest_version_list )
+file(GLOB_RECURSE manifest_files "*.manifest")
+foreach(f ${manifest_files})
+ crt_version("${f}" manifest_version_list)
+endforeach(f)
+list(LENGTH manifest_version_list LEN)
+if(LEN EQUAL 0)
+ message(FATAL_ERROR "No .manifest files found, no version check can be done.")
+endif()
+message("Versions found in ${manifest_files}: ${manifest_version_list}")
+if(DEFINED allow_versions)
+ message("Extra versions allowed: ${allow_versions}")
+endif()
+
+# now find all .exe and .dll files
+# and call check_version on each of them
+file(GLOB_RECURSE exe_files "*.exe")
+file(GLOB_RECURSE dll_files "*.dll")
+set(exe_files ${exe_files} ${dll_files})
+foreach(f ${exe_files})
+ check_version(${f} "${manifest_version_list}")
+endforeach()
+
+# report a fatal error if there were any so that cmake will return
+# a non zero value
+if(fatal_error)
+ message(FATAL_ERROR "This distribution embeds dll "
+ " versions that it does not ship, and may not work on other machines.")
+endif()
diff --git a/Modules/CPack.DS_Store.in b/Modules/CPack.DS_Store.in
new file mode 100644
index 000000000..5be0eeb18
--- /dev/null
+++ b/Modules/CPack.DS_Store.in
Binary files differ
diff --git a/Modules/CPack.Description.plist.in b/Modules/CPack.Description.plist.in
new file mode 100644
index 000000000..3d1147686
--- /dev/null
+++ b/Modules/CPack.Description.plist.in
@@ -0,0 +1,12 @@
+<?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.4">
+<dict>
+ <key>IFPkgDescriptionTitle</key>
+ <string>@CPACK_PACKAGE_NAME@</string>
+ <key>IFPkgDescriptionVersion</key>
+ <string>@CPACK_PACKAGE_VERSION@</string>
+ <key>IFPkgDescriptionDescription</key>
+ <string>@CPACK_PACKAGE_DESCRIPTION@</string>
+</dict>
+</plist>
diff --git a/Modules/CPack.Info.plist.in b/Modules/CPack.Info.plist.in
new file mode 100644
index 000000000..6e325001c
--- /dev/null
+++ b/Modules/CPack.Info.plist.in
@@ -0,0 +1,37 @@
+<?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>IFMajorVersion</key>
+<integer>@CPACK_PACKAGE_VERSION_MAJOR@</integer>
+<key>IFMinorVersion</key>
+<integer>@CPACK_PACKAGE_VERSION_MINOR@</integer>
+<key>IFPkgFlagAllowBackRev</key>
+<false/>
+<key>IFPkgFlagAuthorizationAction</key>
+<string>AdminAuthorization</string>
+<key>IFPkgFlagDefaultLocation</key>
+<string>@CPACK_PACKAGE_DEFAULT_LOCATION@</string>
+<key>IFPkgFlagInstallFat</key>
+<false/>
+<key>IFPkgFlagIsRequired</key>
+<false/>
+<key>IFPkgFlagOverwritePermissions</key>
+<true/>
+<key>IFPkgFlagRelocatable</key>
+<@CPACK_PACKAGE_RELOCATABLE@/>
+<key>IFPkgFlagRestartAction</key>
+<string>NoRestart</string>
+<key>IFPkgFlagRootVolumeOnly</key>
+<false/>
+<key>IFPkgFlagUpdateInstalledLanguages</key>
+<false/>
+<key>IFPkgFlagUseUserMask</key>
+<false/>
+<key>IFPkgFormatVersion</key>
+<real>0.10000000149011612</real>
+<key>CFBundleIdentifier</key>
+<string>com.@CPACK_PACKAGE_VENDOR@.@CPACK_PACKAGE_NAME@@CPACK_MODULE_VERSION_SUFFIX@</string>
+</dict>
+</plist>
diff --git a/Modules/CPack.OSXScriptLauncher.in b/Modules/CPack.OSXScriptLauncher.in
new file mode 100755
index 000000000..c71586046
--- /dev/null
+++ b/Modules/CPack.OSXScriptLauncher.in
Binary files differ
diff --git a/Modules/CPack.OSXScriptLauncher.rsrc.in b/Modules/CPack.OSXScriptLauncher.rsrc.in
new file mode 100644
index 000000000..5f5f17a1c
--- /dev/null
+++ b/Modules/CPack.OSXScriptLauncher.rsrc.in
Binary files differ
diff --git a/Modules/CPack.OSXX11.Info.plist.in b/Modules/CPack.OSXX11.Info.plist.in
new file mode 100644
index 000000000..851b67ba8
--- /dev/null
+++ b/Modules/CPack.OSXX11.Info.plist.in
@@ -0,0 +1,49 @@
+<?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>CFBundleDocumentTypes</key>
+ <array>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>@CPACK_FILE_ASSOCIATION_EXTENSION@</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>@CPACK_FILE_ASSOCIATION_TYPE@</string>
+ <key>CFBundleTypeRole</key>
+ <string>Editor</string>
+ </dict>
+ </array>
+ <key>CFBundleExecutable</key>
+ <string>@CPACK_PACKAGE_FILE_NAME@</string>
+ <key>CFBundleGetInfoString</key>
+ <string>@CPACK_APPLE_GUI_INFO_STRING@</string>
+ <key>CFBundleIconFile</key>
+ <string>@CPACK_APPLE_GUI_ICON@</string>
+ <key>CFBundleIdentifier</key>
+ <string>@CPACK_APPLE_GUI_IDENTIFIER@</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleLongVersionString</key>
+ <string>@CPACK_APPLE_GUI_LONG_VERSION_STRING@</string>
+ <key>CFBundleName</key>
+ <string>@CPACK_APPLE_GUI_BUNDLE_NAME@</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>@CPACK_APPLE_GUI_SHORT_VERSION_STRING@</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>@CPACK_APPLE_GUI_BUNDLE_VERSION@</string>
+ <key>CSResourcesFileMapped</key>
+ <true/>
+ <key>LSRequiresCarbon</key>
+ <true/>
+ <key>NSHumanReadableCopyright</key>
+ <string>@CPACK_APPLE_GUI_COPYRIGHT@</string>
+</dict>
+</plist>
diff --git a/Modules/CPack.OSXX11.main.scpt.in b/Modules/CPack.OSXX11.main.scpt.in
new file mode 100644
index 000000000..de30ea11b
--- /dev/null
+++ b/Modules/CPack.OSXX11.main.scpt.in
Binary files differ
diff --git a/Modules/CPack.RuntimeScript.in b/Modules/CPack.RuntimeScript.in
new file mode 100755
index 000000000..f27444fd9
--- /dev/null
+++ b/Modules/CPack.RuntimeScript.in
@@ -0,0 +1,87 @@
+#!/bin/sh
+#
+# Modified from: Aaron Voisine <aaron@voisine.org>
+
+CWD="`dirname \"$0\"`"
+TMP=/tmp/$(id -ru)/TemporaryItems
+
+version=`sw_vers -productVersion`
+if [ "$?" = "0" ]; then
+ major=${version%%\.*}
+ rest=${version#*\.}
+ minor=${rest%%\.*}
+ build=${rest#*\.}
+else
+ major=10
+ minor=4
+ build=0
+fi
+
+echo $version
+echo "Major = $major"
+echo "Minor = $minor"
+echo "Build = $build"
+
+
+# if 10.5 or greater, then all the open-x11 stuff need not occur
+if [ "$major" -lt 10 ] || ([ "$major" -eq 10 ] && [ "$minor" -lt 5 ]); then
+version=`sw_vers -productVersion`
+if [ "$?" = "0" ]; then
+ major=${version%%\.*}
+ rest=${version#*\.}
+ minor=${rest%%\.*}
+ build=${rest#*\.}
+else
+ major=10
+ minor=4
+ build=0
+fi
+
+echo $version
+echo "Major = $major"
+echo "Minor = $minor"
+echo "Build = $build"
+
+
+# if 10.5 or greater, then all the open-x11 stuff need not occur
+if [ "$major" -lt 10 ] || ([ "$major" -eq 10 ] && [ "$minor" -lt 5 ]); then
+ps -wx -ocommand | grep -e '[X]11.app' > /dev/null
+if [ "$?" != "0" -a ! -f ~/.xinitrc ]; then
+ echo "rm -f ~/.xinitrc" > ~/.xinitrc
+ sed 's/xterm/# xterm/' /usr/X11R6/lib/X11/xinit/xinitrc >> ~/.xinitrc
+fi
+
+mkdir -p $TMP
+cat << __END_OF_GETDISPLAY_SCRIPT__ > "$TMP/getdisplay.sh"
+#!/bin/sh
+mkdir -p "$TMP"
+
+if [ "\$DISPLAY"x = "x" ]; then
+ echo :0 > "$TMP/display"
+else
+ echo \$DISPLAY > "$TMP/display"
+fi
+__END_OF_GETDISPLAY_SCRIPT__
+fi
+chmod +x "$TMP/getdisplay.sh"
+rm -f $TMP/display
+open-x11 $TMP/getdisplay.sh || \
+open -a XDarwin $TMP/getdisplay.sh || \
+echo ":0" > $TMP/display
+
+while [ "$?" = "0" -a ! -f $TMP/display ];
+do
+ #echo "Waiting for display $TMP/display"
+ sleep 1;
+done
+export "DISPLAY=`cat $TMP/display`"
+
+ps -wx -ocommand | grep -e '[X]11' > /dev/null || exit 11
+
+cd ~/
+echo "$@" > /tmp/arguments.log
+if echo $1 | grep -- "^-psn_"; then
+ shift
+fi
+fi
+exec "$CWD/bin/@CPACK_EXECUTABLE_NAME@" "$@" > /tmp/slicer.output 2>&1
diff --git a/Modules/CPack.STGZ_Header.sh.in b/Modules/CPack.STGZ_Header.sh.in
new file mode 100755
index 000000000..dee576fb5
--- /dev/null
+++ b/Modules/CPack.STGZ_Header.sh.in
@@ -0,0 +1,141 @@
+#!/bin/sh
+
+# Display usage
+cpack_usage()
+{
+ cat <<EOF
+Usage: $0 [options]
+Options: [defaults in brackets after descriptions]
+ --help print this message
+ --prefix=dir directory in which to install
+ --include-subdir include the @CPACK_PACKAGE_FILE_NAME@ subdirectory
+ --exclude-subdir exclude the @CPACK_PACKAGE_FILE_NAME@ subdirectory
+EOF
+ exit 1
+}
+
+cpack_echo_exit()
+{
+ echo $1
+ exit 1
+}
+
+# Display version
+cpack_version()
+{
+ echo "@CPACK_PACKAGE_NAME@ Installer Version: @CPACK_PACKAGE_VERSION@, Copyright (c) @CPACK_PACKAGE_VENDOR@"
+}
+
+# Helper function to fix windows paths.
+cpack_fix_slashes ()
+{
+ echo "$1" | sed 's/\\/\//g'
+}
+
+interactive=TRUE
+cpack_skip_license=FALSE
+cpack_include_subdir=""
+for a in "$@CPACK_AT_SIGN@"; do
+ if echo $a | grep "^--prefix=" > /dev/null 2> /dev/null; then
+ cpack_prefix_dir=`echo $a | sed "s/^--prefix=//"`
+ cpack_prefix_dir=`cpack_fix_slashes "${cpack_prefix_dir}"`
+ fi
+ if echo $a | grep "^--help" > /dev/null 2> /dev/null; then
+ cpack_usage
+ fi
+ if echo $a | grep "^--version" > /dev/null 2> /dev/null; then
+ cpack_version
+ exit 2
+ fi
+ if echo $a | grep "^--include-subdir" > /dev/null 2> /dev/null; then
+ cpack_include_subdir=TRUE
+ fi
+ if echo $a | grep "^--exclude-subdir" > /dev/null 2> /dev/null; then
+ cpack_include_subdir=FALSE
+ fi
+ if echo $a | grep "^--skip-license" > /dev/null 2> /dev/null; then
+ cpack_skip_license=TRUE
+ fi
+done
+
+if [ "x${cpack_include_subdir}x" != "xx" -o "x${cpack_skip_license}x" = "xTRUEx" ]
+then
+ interactive=FALSE
+fi
+
+cpack_version
+echo "This is a self-extracting archive."
+toplevel="`pwd`"
+if [ "x${cpack_prefix_dir}x" != "xx" ]
+then
+ toplevel="${cpack_prefix_dir}"
+fi
+
+echo "The archive will be extracted to: ${toplevel}"
+
+if [ "x${interactive}x" = "xTRUEx" ]
+then
+ echo ""
+ echo "If you want to stop extracting, please press <ctrl-C>."
+
+ if [ "x${cpack_skip_license}x" != "xTRUEx" ]
+ then
+ more << '____cpack__here_doc____'
+@CPACK_RESOURCE_FILE_LICENSE_CONTENT@
+____cpack__here_doc____
+ echo
+ echo "Do you accept the license? [yN]: "
+ read line leftover
+ case ${line} in
+ y* | Y*)
+ cpack_license_accepted=TRUE;;
+ *)
+ echo "License not accepted. Exiting ..."
+ exit 1;;
+ esac
+ fi
+
+ if [ "x${cpack_include_subdir}x" = "xx" ]
+ then
+ echo "By default the @CPACK_PACKAGE_NAME@ will be installed in:"
+ echo " \"${toplevel}/@CPACK_PACKAGE_FILE_NAME@\""
+ echo "Do you want to include the subdirectory @CPACK_PACKAGE_FILE_NAME@?"
+ echo "Saying no will install in: \"${toplevel}\" [Yn]: "
+ read line leftover
+ cpack_include_subdir=TRUE
+ case ${line} in
+ n* | N*)
+ cpack_include_subdir=FALSE
+ esac
+ fi
+fi
+
+if [ "x${cpack_include_subdir}x" = "xTRUEx" ]
+then
+ toplevel="${toplevel}/@CPACK_PACKAGE_FILE_NAME@"
+ mkdir -p "${toplevel}"
+fi
+echo
+echo "Using target directory: ${toplevel}"
+echo "Extracting, please wait..."
+echo ""
+
+# take the archive portion of this file and pipe it to tar
+# the NUMERIC parameter in this command should be one more
+# than the number of lines in this header file
+# there are tails which don't understand the "-n" argument, e.g. on SunOS
+# OTOH there are tails which complain when not using the "-n" argument (e.g. GNU)
+# so at first try to tail some file to see if tail fails if used with "-n"
+# if so, don't use "-n"
+use_new_tail_syntax="-n"
+tail $use_new_tail_syntax +1 "$0" > /dev/null 2> /dev/null || use_new_tail_syntax=""
+
+tail $use_new_tail_syntax +###CPACK_HEADER_LENGTH### "$0" | gunzip | (cd "${toplevel}" && tar xf -) || cpack_echo_exit "Problem unpacking the @CPACK_PACKAGE_FILE_NAME@"
+
+echo "Unpacking finished successfully"
+
+exit 0
+#-----------------------------------------------------------
+# Start of TAR.GZ file
+#-----------------------------------------------------------;
+
diff --git a/Modules/CPack.VolumeIcon.icns.in b/Modules/CPack.VolumeIcon.icns.in
new file mode 100644
index 000000000..c59217eae
--- /dev/null
+++ b/Modules/CPack.VolumeIcon.icns.in
Binary files differ
diff --git a/Modules/CPack.background.png.in b/Modules/CPack.background.png.in
new file mode 100644
index 000000000..9339e7cad
--- /dev/null
+++ b/Modules/CPack.background.png.in
Binary files differ
diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake
new file mode 100644
index 000000000..657595731
--- /dev/null
+++ b/Modules/CPack.cmake
@@ -0,0 +1,579 @@
+##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
+# package_source, which build the binary and source installers,
+# 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.
+#
+# 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.
+#
+# 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.
+#
+# 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
+# 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
+# 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
+#
+# 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
+#
+# 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.
+##end
+##variable
+# CPACK_CREATE_DESKTOP_LINKS - List of desktop links to create.
+##end
+#
+
+#=============================================================================
+# Copyright 2006-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.)
+
+# Define this var in order to avoid (or warn) concerning multiple inclusion
+IF(CPack_CMake_INCLUDED)
+ MESSAGE(WARNING "CPack.cmake has already been included!!")
+ELSE(CPack_CMake_INCLUDED)
+ SET(CPack_CMake_INCLUDED 1)
+ENDIF(CPack_CMake_INCLUDED)
+
+# Pick a configuration file
+SET(cpack_input_file "${CMAKE_ROOT}/Templates/CPackConfig.cmake.in")
+IF(EXISTS "${CMAKE_SOURCE_DIR}/CPackConfig.cmake.in")
+ SET(cpack_input_file "${CMAKE_SOURCE_DIR}/CPackConfig.cmake.in")
+ENDIF(EXISTS "${CMAKE_SOURCE_DIR}/CPackConfig.cmake.in")
+SET(cpack_source_input_file "${CMAKE_ROOT}/Templates/CPackConfig.cmake.in")
+IF(EXISTS "${CMAKE_SOURCE_DIR}/CPackSourceConfig.cmake.in")
+ SET(cpack_source_input_file "${CMAKE_SOURCE_DIR}/CPackSourceConfig.cmake.in")
+ENDIF(EXISTS "${CMAKE_SOURCE_DIR}/CPackSourceConfig.cmake.in")
+
+# Backward compatibility
+# Include CPackComponent macros if it has not already been included before.
+include(CPackComponent)
+
+# Macro for setting values if a user did not overwrite them
+MACRO(cpack_set_if_not_set name value)
+ IF(NOT DEFINED "${name}")
+ SET(${name} "${value}")
+ ENDIF(NOT DEFINED "${name}")
+ENDMACRO(cpack_set_if_not_set)
+
+# cpack_encode_variables - Macro 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_)
+ GET_CMAKE_PROPERTY(res VARIABLES)
+ FOREACH(var ${res})
+ IF("xxx${var}" MATCHES "xxxCPACK")
+ SET(_CPACK_OTHER_VARIABLES_
+ "${_CPACK_OTHER_VARIABLES_}\nSET(${var} \"${${var}}\")")
+ ENDIF("xxx${var}" MATCHES "xxxCPACK")
+ ENDFOREACH(var ${res})
+ENDMACRO(cpack_encode_variables)
+
+# 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_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
+ "${CMAKE_PROJECT_NAME} built using CMake")
+
+cpack_set_if_not_set(CPACK_PACKAGE_DESCRIPTION_FILE
+ "${CMAKE_ROOT}/Templates/CPack.GenericDescription.txt")
+cpack_set_if_not_set(CPACK_RESOURCE_FILE_LICENSE
+ "${CMAKE_ROOT}/Templates/CPack.GenericLicense.txt")
+cpack_set_if_not_set(CPACK_RESOURCE_FILE_README
+ "${CMAKE_ROOT}/Templates/CPack.GenericDescription.txt")
+cpack_set_if_not_set(CPACK_RESOURCE_FILE_WELCOME
+ "${CMAKE_ROOT}/Templates/CPack.GenericWelcome.txt")
+
+cpack_set_if_not_set(CPACK_MODULE_PATH "${CMAKE_MODULE_PATH}")
+
+IF(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL)
+ SET(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON)
+ENDIF(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL)
+
+IF(CPACK_NSIS_MODIFY_PATH)
+ SET(CPACK_NSIS_MODIFY_PATH ON)
+ENDIF(CPACK_NSIS_MODIFY_PATH)
+
+SET(__cpack_system_name ${CMAKE_SYSTEM_NAME})
+IF(${__cpack_system_name} MATCHES Windows)
+ IF(CMAKE_CL_64)
+ SET(__cpack_system_name win64)
+ ELSE(CMAKE_CL_64)
+ SET(__cpack_system_name win32)
+ ENDIF(CMAKE_CL_64)
+ENDIF(${__cpack_system_name} MATCHES Windows)
+cpack_set_if_not_set(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}")
+
+# <project>-<major>.<minor>.<patch>-<release>-<platform>.<pkgtype>
+cpack_set_if_not_set(CPACK_PACKAGE_FILE_NAME
+ "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CPACK_SYSTEM_NAME}")
+cpack_set_if_not_set(CPACK_PACKAGE_INSTALL_DIRECTORY
+ "${CPACK_PACKAGE_NAME} ${CPACK_PACKAGE_VERSION}")
+cpack_set_if_not_set(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")
+
+# always force to exactly "true" or "false" for CPack.Info.plist.in:
+if(CPACK_PACKAGE_RELOCATABLE)
+ set(CPACK_PACKAGE_RELOCATABLE "true")
+else(CPACK_PACKAGE_RELOCATABLE)
+ set(CPACK_PACKAGE_RELOCATABLE "false")
+endif(CPACK_PACKAGE_RELOCATABLE)
+
+macro(cpack_check_file_exists file description)
+ if(NOT EXISTS "${file}")
+ message(SEND_ERROR "CPack ${description} file: \"${file}\" could not be found.")
+ endif(NOT EXISTS "${file}")
+endmacro(cpack_check_file_exists)
+
+cpack_check_file_exists("${CPACK_PACKAGE_DESCRIPTION_FILE}" "package description")
+cpack_check_file_exists("${CPACK_RESOURCE_FILE_LICENSE}" "license resource")
+cpack_check_file_exists("${CPACK_RESOURCE_FILE_README}" "readme resource")
+cpack_check_file_exists("${CPACK_RESOURCE_FILE_WELCOME}" "welcome resource")
+
+macro(cpack_optional_append _list _cond _item)
+ if(${_cond})
+ set(${_list} ${${_list}} ${_item})
+ endif(${_cond})
+endmacro(cpack_optional_append _list _cond _item)
+
+##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
+if(NOT CPACK_GENERATOR)
+ if(UNIX)
+ if(CYGWIN)
+ option(CPACK_BINARY_CYGWIN "Enable to build Cygwin binary packages" ON)
+ else(CYGWIN)
+ 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)
+ else(APPLE)
+ option(CPACK_BINARY_TZ "Enable to build TZ packages" ON)
+ endif(APPLE)
+ 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)
+ endif(CYGWIN)
+ else(UNIX)
+ option(CPACK_BINARY_NSIS "Enable to build NSIS packages" ON)
+ option(CPACK_BINARY_ZIP "Enable to build ZIP packages" OFF)
+ endif(UNIX)
+
+ 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_NSIS NSIS)
+ 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_TZ TZ)
+ cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_ZIP ZIP)
+
+endif(NOT CPACK_GENERATOR)
+
+# Provide options to choose source generators
+if(NOT CPACK_SOURCE_GENERATOR)
+ if(UNIX)
+ if(CYGWIN)
+ option(CPACK_SOURCE_CYGWIN "Enable to build Cygwin source packages" ON)
+ else(CYGWIN)
+ 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_TZ "Enable to build TZ source packages" ON)
+ option(CPACK_SOURCE_ZIP "Enable to build ZIP source packages" OFF)
+ endif(CYGWIN)
+ else(UNIX)
+ option(CPACK_SOURCE_ZIP "Enable to build ZIP source packages" ON)
+ endif(UNIX)
+
+ 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_TZ TZ)
+ cpack_optional_append(CPACK_SOURCE_GENERATOR CPACK_SOURCE_ZIP ZIP)
+endif(NOT CPACK_SOURCE_GENERATOR)
+
+# 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_ZIP CPACK_BINARY_BUNDLE
+ CPACK_SOURCE_CYGWIN CPACK_SOURCE_TBZ2 CPACK_SOURCE_TGZ
+ CPACK_SOURCE_TZ CPACK_SOURCE_ZIP CPACK_BINARY_DRAGNDROP)
+
+# Set some other variables
+cpack_set_if_not_set(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}")
+# if the user has set CPACK_NSIS_DISPLAY_NAME remember it
+if(DEFINED CPACK_NSIS_DISPLAY_NAME)
+ SET(CPACK_NSIS_DISPLAY_NAME_SET TRUE)
+endif()
+# if the user has set CPACK_NSIS_DISPLAY
+# 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}")
+
+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}")
+else()
+ cpack_set_if_not_set(CPACK_NSIS_PACKAGE_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY}")
+endif()
+
+cpack_set_if_not_set(CPACK_OUTPUT_CONFIG_FILE
+ "${CMAKE_BINARY_DIR}/CPackConfig.cmake")
+
+cpack_set_if_not_set(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_if_not_set(CPACK_NSIS_INSTALLER_ICON_CODE "")
+cpack_set_if_not_set(CPACK_NSIS_INSTALLER_MUI_ICON_CODE "")
+
+IF(DEFINED CPACK_COMPONENTS_ALL)
+ IF(CPACK_MONOLITHIC_INSTALL)
+ MESSAGE("CPack warning: both CPACK_COMPONENTS_ALL and CPACK_MONOLITHIC_INSTALL have been set.\nDefaulting to a monolithic installation.")
+ SET(CPACK_COMPONENTS_ALL)
+ ELSE(CPACK_MONOLITHIC_INSTALL)
+ # The user has provided the set of components to be installed as
+ # part of a component-based installation; trust her.
+ SET(CPACK_COMPONENTS_ALL_SET_BY_USER TRUE)
+ ENDIF(CPACK_MONOLITHIC_INSTALL)
+ELSE(DEFINED CPACK_COMPONENTS_ALL)
+ # If the user has not specifically requested a monolithic installer
+ # but has specified components in various "install" commands, tell
+ # CPack about those components.
+ IF(NOT CPACK_MONOLITHIC_INSTALL)
+ GET_CMAKE_PROPERTY(CPACK_COMPONENTS_ALL COMPONENTS)
+ LIST(LENGTH CPACK_COMPONENTS_ALL CPACK_COMPONENTS_LEN)
+ IF(CPACK_COMPONENTS_LEN EQUAL 1)
+ # Only one component: this is not a component-based installation
+ # (at least, it isn't a component-based installation, but may
+ # become one later if the user uses the cpack_add_* commands).
+ SET(CPACK_COMPONENTS_ALL)
+ ENDIF(CPACK_COMPONENTS_LEN EQUAL 1)
+ SET(CPACK_COMPONENTS_LEN)
+ ENDIF(NOT CPACK_MONOLITHIC_INSTALL)
+ENDIF(DEFINED CPACK_COMPONENTS_ALL)
+
+# CMake always generates a component named "Unspecified", which is
+# used to install everything that doesn't have an explicitly-provided
+# component. Since these files should always be installed, we'll make
+# them hidden and required.
+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)
+
+# Generate source file
+cpack_set_if_not_set(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_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-Source")
+cpack_set_if_not_set(CPACK_SOURCE_IGNORE_FILES
+ "/CVS/;/\\\\\\\\.svn/;/\\\\\\\\.bzr/;/\\\\\\\\.hg/;/\\\\\\\\.git/;\\\\\\\\.swp$;\\\\\\\\.#;/#")
+SET(CPACK_INSTALL_CMAKE_PROJECTS "${CPACK_SOURCE_INSTALL_CMAKE_PROJECTS}")
+SET(CPACK_INSTALLED_DIRECTORIES "${CPACK_SOURCE_INSTALLED_DIRECTORIES}")
+SET(CPACK_GENERATOR "${CPACK_SOURCE_GENERATOR}")
+SET(CPACK_TOPLEVEL_TAG "${CPACK_SOURCE_TOPLEVEL_TAG}")
+SET(CPACK_PACKAGE_FILE_NAME "${CPACK_SOURCE_PACKAGE_FILE_NAME}")
+SET(CPACK_IGNORE_FILES "${CPACK_SOURCE_IGNORE_FILES}")
+SET(CPACK_STRIP_FILES "${CPACK_SOURCE_STRIP_FILES}")
+
+cpack_encode_variables()
+configure_file("${cpack_source_input_file}"
+ "${CPACK_SOURCE_OUTPUT_CONFIG_FILE}" @ONLY IMMEDIATE)
diff --git a/Modules/CPack.distribution.dist.in b/Modules/CPack.distribution.dist.in
new file mode 100644
index 000000000..f20e66c17
--- /dev/null
+++ b/Modules/CPack.distribution.dist.in
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<installer-gui-script minSpecVersion="1.0">
+ <title>@CPACK_PACKAGE_NAME@</title>
+ <welcome file="@CPACK_RESOURCE_FILE_WELCOME_NOPATH@"/>
+ <readme file="@CPACK_RESOURCE_FILE_README_NOPATH@"/>
+ <license file="@CPACK_RESOURCE_FILE_LICENSE_NOPATH@"/>
+ <options allow-external-scripts="no" customize="allow" rootVolumeOnly="false"></options>
+ @CPACK_PACKAGEMAKER_CHOICES@
+</installer-gui-script>
diff --git a/Modules/CPackBundle.cmake b/Modules/CPackBundle.cmake
new file mode 100644
index 000000000..0da51e30b
--- /dev/null
+++ b/Modules/CPackBundle.cmake
@@ -0,0 +1,48 @@
+##section Variables specific to CPack Bundle generator
+##end
+##module
+# - CPack Bundle generator (Mac OS X) specific options
+#
+# 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
+
+#=============================================================================
+# Copyright 2006-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.)
+
+#Bundle Generator specific code should be put here
diff --git a/Modules/CPackComponent.cmake b/Modules/CPackComponent.cmake
new file mode 100644
index 000000000..15987030e
--- /dev/null
+++ b/Modules/CPackComponent.cmake
@@ -0,0 +1,513 @@
+##section Variables concerning CPack Components
+##end
+##module
+# - Build binary and source package installers
+#
+# 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.
+#
+# 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
+# inconsitent 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
+
+#=============================================================================
+# Copyright 2006-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.)
+
+# Define var in order to avoid multiple inclusion
+IF(NOT CPackComponent_CMake_INCLUDED)
+SET(CPackComponent_CMake_INCLUDED 1)
+
+# Argument-parsing macro from http://www.cmake.org/Wiki/CMakeMacroParseArguments
+MACRO(cpack_parse_arguments prefix arg_names option_names)
+ SET(${prefix}_DEFAULT_ARGS)
+ FOREACH(arg_name ${arg_names})
+ SET(${prefix}_${arg_name})
+ ENDFOREACH(arg_name)
+ FOREACH(option ${option_names})
+ SET(${prefix}_${option} FALSE)
+ ENDFOREACH(option)
+
+ SET(current_arg_name DEFAULT_ARGS)
+ SET(current_arg_list)
+ FOREACH(arg ${ARGN})
+ SET(larg_names ${arg_names})
+ LIST(FIND larg_names "${arg}" is_arg_name)
+ IF (is_arg_name GREATER -1)
+ SET(${prefix}_${current_arg_name} ${current_arg_list})
+ SET(current_arg_name ${arg})
+ SET(current_arg_list)
+ ELSE (is_arg_name GREATER -1)
+ SET(loption_names ${option_names})
+ LIST(FIND loption_names "${arg}" is_option)
+ IF (is_option GREATER -1)
+ SET(${prefix}_${arg} TRUE)
+ ELSE (is_option GREATER -1)
+ SET(current_arg_list ${current_arg_list} ${arg})
+ ENDIF (is_option GREATER -1)
+ ENDIF (is_arg_name GREATER -1)
+ ENDFOREACH(arg)
+ SET(${prefix}_${current_arg_name} ${current_arg_list})
+ENDMACRO(cpack_parse_arguments)
+
+# Macro that appends a SET command for the given variable name (var)
+# to the macro named strvar, but only if the variable named "var"
+# has been defined. The string will eventually be appended to a CPack
+# configuration file.
+MACRO(cpack_append_variable_set_command var strvar)
+ IF (DEFINED ${var})
+ SET(${strvar} "${${strvar}}SET(${var}")
+ FOREACH(APPENDVAL ${${var}})
+ SET(${strvar} "${${strvar}} ${APPENDVAL}")
+ ENDFOREACH(APPENDVAL)
+ SET(${strvar} "${${strvar}})\n")
+ ENDIF (DEFINED ${var})
+ENDMACRO(cpack_append_variable_set_command)
+
+# Macro that appends a SET command for the given variable name (var)
+# to the macro named strvar, but only if the variable named "var"
+# has been defined and is a string. The string will eventually be
+# appended to a CPack configuration file.
+MACRO(cpack_append_string_variable_set_command var strvar)
+ IF (DEFINED ${var})
+ LIST(LENGTH ${var} CPACK_APP_VALUE_LEN)
+ IF(${CPACK_APP_VALUE_LEN} EQUAL 1)
+ SET(${strvar} "${${strvar}}SET(${var} \"${${var}}\")\n")
+ ENDIF(${CPACK_APP_VALUE_LEN} EQUAL 1)
+ ENDIF (DEFINED ${var})
+ENDMACRO(cpack_append_string_variable_set_command)
+
+# Macro that appends a SET command for the given variable name (var)
+# to the macro named strvar, but only if the variable named "var"
+# has been set to true. The string will eventually be
+# appended to a CPack configuration file.
+MACRO(cpack_append_option_set_command var strvar)
+ IF (${var})
+ LIST(LENGTH ${var} CPACK_APP_VALUE_LEN)
+ IF(${CPACK_APP_VALUE_LEN} EQUAL 1)
+ SET(${strvar} "${${strvar}}SET(${var} TRUE)\n")
+ ENDIF(${CPACK_APP_VALUE_LEN} EQUAL 1)
+ ENDIF (${var})
+ENDMACRO(cpack_append_option_set_command)
+
+# 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}
+ "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")
+ else ()
+ SET(CPACK_ADDCOMP_STR "\n# Configuration for component \"${compname}\"\n")
+ endif ()
+
+ IF(NOT CPACK_MONOLITHIC_INSTALL)
+ # If the user didn't set CPACK_COMPONENTS_ALL explicitly, update the
+ # value of CPACK_COMPONENTS_ALL in the configuration file. This will
+ # 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}")
+ ENDFOREACH(COMP)
+ SET(CPACK_ADDCOMP_STR "${CPACK_ADDCOMP_STR})\n")
+ ENDIF(NOT CPACK_COMPONENTS_ALL_SET_BY_USER)
+ ENDIF(NOT CPACK_MONOLITHIC_INSTALL)
+
+ cpack_append_string_variable_set_command(
+ 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_append_variable_set_command(
+ CPACK_COMPONENT_${CPACK_ADDCOMP_UNAME}_GROUP
+ CPACK_ADDCOMP_STR)
+ cpack_append_variable_set_command(
+ 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_append_string_variable_set_command(
+ 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_append_option_set_command(
+ CPACK_COMPONENT_${CPACK_ADDCOMP_UNAME}_REQUIRED
+ CPACK_ADDCOMP_STR)
+ cpack_append_option_set_command(
+ CPACK_COMPONENT_${CPACK_ADDCOMP_UNAME}_DISABLED
+ CPACK_ADDCOMP_STR)
+ cpack_append_option_set_command(
+ 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}")
+ ENDIF(CPack_CMake_INCLUDED)
+ENDMACRO(cpack_add_component)
+
+# Macro that adds a component group to the CPack installer
+MACRO(cpack_add_component_group grpname)
+ STRING(TOUPPER ${grpname} CPACK_ADDGRP_UNAME)
+ cpack_parse_arguments(CPACK_COMPONENT_GROUP_${CPACK_ADDGRP_UNAME}
+ "DISPLAY_NAME;DESCRIPTION"
+ "EXPANDED;BOLD_TITLE"
+ ${ARGN}
+ )
+
+ SET(CPACK_ADDGRP_STR "\n# Configuration for component group \"${grpname}\"\n")
+ cpack_append_string_variable_set_command(
+ CPACK_COMPONENT_GROUP_${CPACK_ADDGRP_UNAME}_DISPLAY_NAME
+ CPACK_ADDGRP_STR)
+ cpack_append_string_variable_set_command(
+ CPACK_COMPONENT_GROUP_${CPACK_ADDGRP_UNAME}_DESCRIPTION
+ CPACK_ADDGRP_STR)
+ cpack_append_option_set_command(
+ CPACK_COMPONENT_GROUP_${CPACK_ADDGRP_UNAME}_EXPANDED
+ CPACK_ADDGRP_STR)
+ cpack_append_option_set_command(
+ CPACK_COMPONENT_GROUP_${CPACK_ADDGRP_UNAME}_BOLD_TITLE
+ CPACK_ADDGRP_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_ADDGRP_STR}")
+ ENDIF(CPack_CMake_INCLUDED)
+ENDMACRO(cpack_add_component_group)
+
+# Macro that adds an installation type to the CPack installer
+MACRO(cpack_add_install_type insttype)
+ STRING(TOUPPER ${insttype} CPACK_INSTTYPE_UNAME)
+ cpack_parse_arguments(CPACK_INSTALL_TYPE_${CPACK_INSTTYPE_UNAME}
+ "DISPLAY_NAME"
+ ""
+ ${ARGN}
+ )
+
+ SET(CPACK_INSTTYPE_STR
+ "\n# Configuration for installation type \"${insttype}\"\n")
+ SET(CPACK_INSTTYPE_STR
+ "${CPACK_INSTTYPE_STR}LIST(APPEND CPACK_ALL_INSTALL_TYPES ${insttype})\n")
+ cpack_append_string_variable_set_command(
+ CPACK_INSTALL_TYPE_${CPACK_INSTTYPE_UNAME}_DISPLAY_NAME
+ CPACK_INSTTYPE_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_INSTTYPE_STR}")
+ ENDIF(CPack_CMake_INCLUDED)
+ENDMACRO(cpack_add_install_type)
+
+MACRO(cpack_configure_downloads site)
+ cpack_parse_arguments(CPACK_DOWNLOAD
+ "UPLOAD_DIRECTORY"
+ "ALL;ADD_REMOVE;NO_ADD_REMOVE"
+ ${ARGN}
+ )
+
+ SET(CPACK_CONFIG_DL_STR
+ "\n# Downloaded components configuration\n")
+ SET(CPACK_UPLOAD_DIRECTORY ${CPACK_DOWNLOAD_UPLOAD_DIRECTORY})
+ SET(CPACK_DOWNLOAD_SITE ${site})
+ cpack_append_string_variable_set_command(
+ CPACK_DOWNLOAD_SITE
+ CPACK_CONFIG_DL_STR)
+ cpack_append_string_variable_set_command(
+ CPACK_UPLOAD_DIRECTORY
+ CPACK_CONFIG_DL_STR)
+ cpack_append_option_set_command(
+ CPACK_DOWNLOAD_ALL
+ CPACK_CONFIG_DL_STR)
+ IF (${CPACK_DOWNLOAD_ALL} AND NOT ${CPACK_DOWNLOAD_NO_ADD_REMOVE})
+ SET(CPACK_DOWNLOAD_ADD_REMOVE ON)
+ ENDIF (${CPACK_DOWNLOAD_ALL} AND NOT ${CPACK_DOWNLOAD_NO_ADD_REMOVE})
+ SET(CPACK_ADD_REMOVE ${CPACK_DOWNLOAD_ADD_REMOVE})
+ cpack_append_option_set_command(
+ CPACK_ADD_REMOVE
+ CPACK_CONFIG_DL_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_CONFIG_DL_STR}")
+ ENDIF(CPack_CMake_INCLUDED)
+ENDMACRO(cpack_configure_downloads)
+ENDIF(NOT CPackComponent_CMake_INCLUDED)
diff --git a/Modules/CPackCygwin.cmake b/Modules/CPackCygwin.cmake
new file mode 100644
index 000000000..7ed7f678b
--- /dev/null
+++ b/Modules/CPackCygwin.cmake
@@ -0,0 +1,33 @@
+##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
+
+#=============================================================================
+# Copyright 2006-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.)
diff --git a/Modules/CPackDMG.cmake b/Modules/CPackDMG.cmake
new file mode 100644
index 000000000..e866bab80
--- /dev/null
+++ b/Modules/CPackDMG.cmake
@@ -0,0 +1,70 @@
+##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
+# automatically detected command (or specify its location if the
+# auto-detection fails to find it.)
+##end
+
+#=============================================================================
+# Copyright 2006-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.)
diff --git a/Modules/CPackDeb.cmake b/Modules/CPackDeb.cmake
new file mode 100644
index 000000000..bd3b94d74
--- /dev/null
+++ b/Modules/CPackDeb.cmake
@@ -0,0 +1,421 @@
+##section Variables specific to CPack Debian (DEB) generator
+##end
+##module
+# - The builtin (binary) CPack Deb generator (Unix only)
+# 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
+# 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
+
+
+#=============================================================================
+# Copyright 2007-2009 Kitware, Inc.
+# Copyright 2007-2009 Mathieu Malaterre <mathieu.malaterre@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.)
+
+# CPack script for creating Debian package
+# Author: Mathieu Malaterre
+#
+# http://wiki.debian.org/HowToPackageForDebian
+
+IF(CMAKE_BINARY_DIR)
+ MESSAGE(FATAL_ERROR "CPackDeb.cmake may only be used by CPack internally.")
+ENDIF(CMAKE_BINARY_DIR)
+
+IF(NOT UNIX)
+ MESSAGE(FATAL_ERROR "CPackDeb.cmake may only be used under UNIX.")
+ENDIF(NOT UNIX)
+
+# 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(NOT DEFINED CPACK_DEBIAN_PACKAGE_SHLIBDEPS)
+
+FIND_PROGRAM(FAKEROOT_EXECUTABLE fakeroot)
+IF(FAKEROOT_EXECUTABLE)
+ SET(CPACK_DEBIAN_FAKEROOT_EXECUTABLE ${FAKEROOT_EXECUTABLE})
+ENDIF(FAKEROOT_EXECUTABLE)
+
+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}>")
+ ENDIF(CPACK_DEBIAN_PACKAGE_DEBUG)
+
+ # 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})
+ 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(CPACK_DEBIAN_PACKAGE_DEBUG)
+ IF (NOT SHLIBDEPS_RESULT EQUAL 0)
+ MESSAGE (FATAL_ERROR "CPackDeb: dpkg-shlibdeps: ${SHLIBDEPS_ERROR}")
+ ENDIF (NOT SHLIBDEPS_RESULT EQUAL 0)
+
+ #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}")
+ ENDIF(CPACK_DEBIAN_PACKAGE_DEBUG)
+
+ # Remove blank control file
+ # Might not be safe if package actual contain file or directory named debian
+ FILE(REMOVE_RECURSE "${CPACK_TEMPORARY_DIRECTORY}/debian")
+
+ # 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 (CPACK_DEBIAN_PACKAGE_DEPENDS)
+ SET (CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_AUTO_DEPENDS}")
+ ENDIF (CPACK_DEBIAN_PACKAGE_DEPENDS)
+
+ ELSE (SHLIBDEPS_EXECUTABLE)
+ IF(CPACK_DEBIAN_PACKAGE_DEBUG)
+ MESSAGE( "CPackDeb Debug: Using only user-provided depends because dpkg-shlibdeps is not found.")
+ ENDIF(CPACK_DEBIAN_PACKAGE_DEBUG)
+ ENDIF(SHLIBDEPS_EXECUTABLE)
+
+ELSE (CPACK_DEBIAN_PACKAGE_SHLIBDEPS)
+ IF(CPACK_DEBIAN_PACKAGE_DEBUG)
+ MESSAGE( "CPackDeb Debug: Using only user-provided depends")
+ ENDIF(CPACK_DEBIAN_PACKAGE_DEBUG)
+ENDIF(CPACK_DEBIAN_PACKAGE_SHLIBDEPS)
+
+# Let's define the control file found in debian package:
+
+# Binary package:
+# http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-binarycontrolfiles
+
+# 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(NOT CPACK_DEBIAN_PACKAGE_NAME)
+
+# Version: (mandatory)
+IF(NOT CPACK_DEBIAN_PACKAGE_VERSION)
+ IF(NOT CPACK_PACKAGE_VERSION)
+ MESSAGE(FATAL_ERROR "CPackDeb: Debian package requires a package version")
+ ENDIF(NOT CPACK_PACKAGE_VERSION)
+ SET(CPACK_DEBIAN_PACKAGE_VERSION ${CPACK_PACKAGE_VERSION})
+ENDIF(NOT CPACK_DEBIAN_PACKAGE_VERSION)
+
+# 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(NOT DPKG_CMD)
+ EXECUTE_PROCESS(COMMAND "${DPKG_CMD}" --print-architecture
+ OUTPUT_VARIABLE CPACK_DEBIAN_PACKAGE_ARCHITECTURE
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+ENDIF(NOT CPACK_DEBIAN_PACKAGE_ARCHITECTURE)
+
+# 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(NOT CPACK_DEBIAN_PACKAGE_DEPENDS)
+
+# 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(NOT CPACK_PACKAGE_CONTACT)
+ SET(CPACK_DEBIAN_PACKAGE_MAINTAINER ${CPACK_PACKAGE_CONTACT})
+ENDIF(NOT CPACK_DEBIAN_PACKAGE_MAINTAINER)
+
+# 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")
+ ENDIF(NOT CPACK_PACKAGE_DESCRIPTION_SUMMARY)
+ SET(CPACK_DEBIAN_PACKAGE_DESCRIPTION ${CPACK_PACKAGE_DESCRIPTION_SUMMARY})
+ENDIF(NOT CPACK_DEBIAN_PACKAGE_DESCRIPTION)
+
+# Section: (recommended)
+IF(NOT CPACK_DEBIAN_PACKAGE_SECTION)
+ SET(CPACK_DEBIAN_PACKAGE_SECTION "devel")
+ENDIF(NOT CPACK_DEBIAN_PACKAGE_SECTION)
+
+# Priority: (recommended)
+IF(NOT CPACK_DEBIAN_PACKAGE_PRIORITY)
+ SET(CPACK_DEBIAN_PACKAGE_PRIORITY "optional")
+ENDIF(NOT CPACK_DEBIAN_PACKAGE_PRIORITY )
+
+# 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}")
+ SET(CPACK_DEB_PACKAGE_COMPONENT_PART_PATH "/${CPACK_DEB_PACKAGE_COMPONENT}")
+ SET(WDIR "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}/${CPACK_DEB_PACKAGE_COMPONENT}")
+ STRING(TOLOWER "${CPACK_PACKAGE_NAME}${CPACK_DEB_PACKAGE_COMPONENT_PART_NAME}" CPACK_DEBIAN_PACKAGE_NAME)
+ELSE(CPACK_DEB_PACKAGE_COMPONENT)
+ SET(CPACK_DEB_PACKAGE_COMPONENT_PART_NAME "")
+ SET(CPACK_DEB_PACKAGE_COMPONENT_PART_PATH "")
+ SET(WDIR "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}")
+ENDIF(CPACK_DEB_PACKAGE_COMPONENT)
+
+# 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(CPACK_DEBIAN_PACKAGE_DEBUG)
+
+# 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(NOT CPACK_DEBIAN_PACKAGE_BUILDS_DEPENDS)
diff --git a/Modules/CPackNSIS.cmake b/Modules/CPackNSIS.cmake
new file mode 100644
index 000000000..d14005369
--- /dev/null
+++ b/Modules/CPackNSIS.cmake
@@ -0,0 +1,147 @@
+##section Variables specific to CPack NSIS generator
+##end
+##module
+# - CPack NSIS generator specific options
+#
+# 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
+
+#=============================================================================
+# Copyright 2006-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.)
+
+#FIXME we should put NSIS specific code here
+#FIXME but I'm not doing it because I'm not able to test it...
diff --git a/Modules/CPackPackageMaker.cmake b/Modules/CPackPackageMaker.cmake
new file mode 100644
index 000000000..45ba465cc
--- /dev/null
+++ b/Modules/CPackPackageMaker.cmake
@@ -0,0 +1,35 @@
+##section Variables specific to CPack PackageMaker generator
+##end
+##module
+# - PackageMaker CPack generator (Mac OS X).
+# The following variable is specific to installers build on Mac OS X
+# using PackageMaker:
+##end
+#
+##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
+
+#=============================================================================
+# Copyright 2006-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.)
diff --git a/Modules/CPackRPM.cmake b/Modules/CPackRPM.cmake
new file mode 100644
index 000000000..ae9351273
--- /dev/null
+++ b/Modules/CPackRPM.cmake
@@ -0,0 +1,925 @@
+##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
+# 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
+# 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).
+##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
+
+#=============================================================================
+# 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.)
+
+# Author: Eric Noulard with the help of Alexander Neundorf.
+
+IF(CMAKE_BINARY_DIR)
+ MESSAGE(FATAL_ERROR "CPackRPM.cmake may only be used by CPack internally.")
+ENDIF(CMAKE_BINARY_DIR)
+
+IF(NOT UNIX)
+ MESSAGE(FATAL_ERROR "CPackRPM.cmake may only be used under UNIX.")
+ENDIF(NOT UNIX)
+
+# 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(CPACK_RPM_PACKAGE_DEBUG)
+ENDIF(RPMBUILD_EXECUTABLE)
+
+IF(NOT RPMBUILD_EXECUTABLE)
+ MESSAGE(FATAL_ERROR "RPM package requires rpmbuild executable")
+ENDIF(NOT RPMBUILD_EXECUTABLE)
+
+# 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 (LSB_RELEASE_EXECUTABLE)
+ set(LSB_RELEASE_OUTPUT "lsb_release not installed/found!")
+ endif(LSB_RELEASE_EXECUTABLE)
+ MESSAGE("CPackRPM:Debug: LSB_RELEASE = ${LSB_RELEASE_OUTPUT}")
+ENDIF(CPACK_RPM_PACKAGE_DEBUG)
+
+# 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(CPACK_TOPLEVEL_DIRECTORY MATCHES ".* .*")
+
+# 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(ALIEN_EXECUTABLE)
+
+# Are we packaging components ?
+IF(CPACK_RPM_PACKAGE_COMPONENT)
+ SET(CPACK_RPM_PACKAGE_COMPONENT_PART_NAME "-${CPACK_RPM_PACKAGE_COMPONENT}")
+ SET(CPACK_RPM_PACKAGE_COMPONENT_PART_PATH "/${CPACK_RPM_PACKAGE_COMPONENT}")
+ SET(WDIR "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}/${CPACK_RPM_PACKAGE_COMPONENT}")
+ELSE(CPACK_RPM_PACKAGE_COMPONENT)
+ SET(CPACK_RPM_PACKAGE_COMPONENT_PART_NAME "")
+ SET(CPACK_RPM_PACKAGE_COMPONENT_PART_PATH "")
+ SET(WDIR "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}")
+ENDIF(CPACK_RPM_PACKAGE_COMPONENT)
+
+#
+# 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:
+#
+
+# 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)
+ ELSE(NOT CPACK_PACKAGE_DESCRIPTION_SUMMARY)
+ SET(CPACK_RPM_PACKAGE_SUMMARY ${CPACK_PACKAGE_DESCRIPTION_SUMMARY})
+ ENDIF(NOT CPACK_PACKAGE_DESCRIPTION_SUMMARY)
+ENDIF(NOT CPACK_RPM_PACKAGE_SUMMARY)
+
+# CPACK_RPM_PACKAGE_NAME (mandatory)
+IF(NOT CPACK_RPM_PACKAGE_NAME)
+ STRING(TOLOWER "${CPACK_PACKAGE_NAME}" CPACK_RPM_PACKAGE_NAME)
+ENDIF(NOT CPACK_RPM_PACKAGE_NAME)
+
+# 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(NOT CPACK_PACKAGE_VERSION)
+ SET(CPACK_RPM_PACKAGE_VERSION ${CPACK_PACKAGE_VERSION})
+ENDIF(NOT CPACK_RPM_PACKAGE_VERSION)
+# 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}")
+ ENDIF(CPACK_RPM_PACKAGE_DEBUG)
+ELSE(CPACK_RPM_PACKAGE_ARCHITECTURE)
+ SET(TMP_RPM_BUILDARCH "")
+ENDIF(CPACK_RPM_PACKAGE_ARCHITECTURE)
+
+# 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(NOT CPACK_RPM_PACKAGE_RELEASE)
+
+# CPACK_RPM_PACKAGE_LICENSE
+IF(NOT CPACK_RPM_PACKAGE_LICENSE)
+ SET(CPACK_RPM_PACKAGE_LICENSE "unknown")
+ENDIF(NOT CPACK_RPM_PACKAGE_LICENSE)
+
+# CPACK_RPM_PACKAGE_GROUP
+IF(NOT CPACK_RPM_PACKAGE_GROUP)
+ SET(CPACK_RPM_PACKAGE_GROUP "unknown")
+ENDIF(NOT 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(CPACK_PACKAGE_VENDOR)
+ SET(CPACK_RPM_PACKAGE_VENDOR "unknown")
+ ENDIF(CPACK_PACKAGE_VENDOR)
+ENDIF(NOT CPACK_RPM_PACKAGE_VENDOR)
+
+# 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 (CPACK_PACKAGE_DESCRIPTION_FILE)
+ SET(CPACK_RPM_PACKAGE_DESCRIPTION "no package description available")
+ ENDIF (CPACK_PACKAGE_DESCRIPTION_FILE)
+ENDIF (NOT CPACK_RPM_PACKAGE_DESCRIPTION)
+
+# 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(CPACK_RPM_PACKAGE_DEBUG)
+ IF(CPACK_RPM_COMPRESSION_TYPE STREQUAL "lzma")
+ SET(CPACK_RPM_COMPRESSION_TYPE_TMP "%define _binary_payload w9.lzdio")
+ ENDIF(CPACK_RPM_COMPRESSION_TYPE STREQUAL "lzma")
+ IF(CPACK_RPM_COMPRESSION_TYPE STREQUAL "xz")
+ SET(CPACK_RPM_COMPRESSION_TYPE_TMP "%define _binary_payload w7.xzdio")
+ ENDIF(CPACK_RPM_COMPRESSION_TYPE STREQUAL "xz")
+ IF(CPACK_RPM_COMPRESSION_TYPE STREQUAL "bzip2")
+ SET(CPACK_RPM_COMPRESSION_TYPE_TMP "%define _binary_payload w9.bzdio")
+ ENDIF(CPACK_RPM_COMPRESSION_TYPE STREQUAL "bzip2")
+ IF(CPACK_RPM_COMPRESSION_TYPE STREQUAL "gzip")
+ SET(CPACK_RPM_COMPRESSION_TYPE_TMP "%define _binary_payload w9.gzdio")
+ ENDIF(CPACK_RPM_COMPRESSION_TYPE STREQUAL "gzip")
+ELSE(CPACK_RPM_COMPRESSION_TYPE)
+ SET(CPACK_RPM_COMPRESSION_TYPE_TMP "")
+ENDIF(CPACK_RPM_COMPRESSION_TYPE)
+
+if(CPACK_PACKAGE_RELOCATABLE)
+ set(CPACK_RPM_PACKAGE_RELOCATABLE TRUE)
+endif(CPACK_PACKAGE_RELOCATABLE)
+if(CPACK_RPM_PACKAGE_RELOCATABLE)
+ if(CPACK_RPM_PACKAGE_DEBUG)
+ message("CPackRPM:Debug: Trying to build a relocatable package")
+ endif(CPACK_RPM_PACKAGE_DEBUG)
+ 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.")
+ else(CPACK_SET_DESTDIR AND (NOT CPACK_SET_DESTDIR STREQUAL "I_ON"))
+ set(CPACK_RPM_PACKAGE_PREFIX ${CPACK_PACKAGING_INSTALL_PREFIX})
+ endif(CPACK_SET_DESTDIR AND (NOT CPACK_SET_DESTDIR STREQUAL "I_ON"))
+endif(CPACK_RPM_PACKAGE_RELOCATABLE)
+
+# Check if additional fields for RPM spec header are given
+# There may be some COMPONENT specific variables as well
+FOREACH(_RPM_SPEC_HEADER URL REQUIRES SUGGESTS PROVIDES OBSOLETES PREFIX CONFLICTS AUTOPROV AUTOREQ AUTOREQPROV)
+ IF(CPACK_RPM_PACKAGE_DEBUG)
+ message("CPackRPM:Debug: processing ${_RPM_SPEC_HEADER}")
+ ENDIF(CPACK_RPM_PACKAGE_DEBUG)
+ if(CPACK_RPM_PACKAGE_COMPONENT)
+ if(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(CPACK_RPM_PACKAGE_DEBUG)
+ set(CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_${_RPM_SPEC_HEADER}})
+ else()
+ 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(CPACK_RPM_PACKAGE_DEBUG)
+ set(CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP ${CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}})
+ endif()
+ else()
+ IF(CPACK_RPM_PACKAGE_DEBUG)
+ message("CPackRPM:Debug: using CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}")
+ ENDIF(CPACK_RPM_PACKAGE_DEBUG)
+ set(CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP ${CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}})
+ endif()
+
+ IF(CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP)
+ 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}")
+ IF(CPACK_RPM_PACKAGE_DEBUG)
+ MESSAGE("CPackRPM:Debug: User defined ${_PACKAGE_HEADER_NAME}:\n ${CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP}")
+ ENDIF(CPACK_RPM_PACKAGE_DEBUG)
+ SET(TMP_RPM_${_RPM_SPEC_HEADER} "${_PACKAGE_HEADER_NAME}: ${CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP}")
+ ELSE(CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP)
+ # Do not forget to unset previously set header (from previous component)
+ UNSET(TMP_RPM_${_RPM_SPEC_HEADER})
+ ENDIF(CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP)
+ENDFOREACH(_RPM_SPEC_HEADER)
+
+# 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(CPACK_RPM_PACKAGE_DEBUG)
+ SET(TMP_RPM_SPEC_INSTALL_POST "%define __spec_install_post ${CPACK_RPM_SPEC_INSTALL_POST}")
+ENDIF(CPACK_RPM_SPEC_INSTALL_POST)
+
+# 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(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_POST_UNINSTALL_SCRIPT_FILE)
+ set(CPACK_RPM_POST_UNINSTALL_READ_FILE ${CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE})
+ endif(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_POST_UNINSTALL_SCRIPT_FILE)
+else(CPACK_RPM_PACKAGE_COMPONENT)
+ 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(CPACK_RPM_PACKAGE_COMPONENT)
+
+# 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(EXISTS ${CPACK_RPM_POST_INSTALL_READ_FILE})
+ message("CPackRPM:Warning: CPACK_RPM_POST_INSTALL_SCRIPT_FILE <${CPACK_RPM_POST_INSTALL_READ_FILE}> does not exists - ignoring")
+ endif(EXISTS ${CPACK_RPM_POST_INSTALL_READ_FILE})
+else(CPACK_RPM_POST_INSTALL_READ_FILE)
+ # reset SPEC var value if no post install file has been specified
+ # (either globally or component-wise)
+ set(CPACK_RPM_SPEC_POSTINSTALL "")
+endif(CPACK_RPM_POST_INSTALL_READ_FILE)
+
+# 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(EXISTS ${CPACK_RPM_POST_UNINSTALL_READ_FILE})
+ message("CPackRPM:Warning: CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE <${CPACK_RPM_POST_UNINSTALL_READ_FILE}> does not exists - ignoring")
+ endif(EXISTS ${CPACK_RPM_POST_UNINSTALL_READ_FILE})
+else(CPACK_RPM_POST_UNINSTALL_READ_FILE)
+ # 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_POST_UNINSTALL_READ_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(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PRE_INSTALL_SCRIPT_FILE)
+ set(CPACK_RPM_PRE_INSTALL_READ_FILE ${CPACK_RPM_PRE_INSTALL_SCRIPT_FILE})
+ endif(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PRE_INSTALL_SCRIPT_FILE)
+ 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(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PRE_UNINSTALL_SCRIPT_FILE)
+ set(CPACK_RPM_PRE_UNINSTALL_READ_FILE ${CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE})
+ endif(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PRE_UNINSTALL_SCRIPT_FILE)
+else(CPACK_RPM_PACKAGE_COMPONENT)
+ 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(CPACK_RPM_PACKAGE_COMPONENT)
+
+# 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(EXISTS ${CPACK_RPM_PRE_INSTALL_READ_FILE})
+ message("CPackRPM:Warning: CPACK_RPM_PRE_INSTALL_SCRIPT_FILE <${CPACK_RPM_PRE_INSTALL_READ_FILE}> does not exists - ignoring")
+ endif(EXISTS ${CPACK_RPM_PRE_INSTALL_READ_FILE})
+else(CPACK_RPM_PRE_INSTALL_READ_FILE)
+ # reset SPEC var value if no pre-install file has been specified
+ # (either globally or component-wise)
+ set(CPACK_RPM_SPEC_PREINSTALL "")
+endif(CPACK_RPM_PRE_INSTALL_READ_FILE)
+
+# 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(EXISTS ${CPACK_RPM_PRE_UNINSTALL_READ_FILE})
+ message("CPackRPM:Warning: CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE <${CPACK_RPM_PRE_UNINSTALL_READ_FILE}> does not exists - ignoring")
+ endif(EXISTS ${CPACK_RPM_PRE_UNINSTALL_READ_FILE})
+else(CPACK_RPM_PRE_UNINSTALL_READ_FILE)
+ # 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_PRE_UNINSTALL_READ_FILE)
+
+# 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(EXISTS ${CPACK_RPM_CHANGELOG_FILE})
+ message(SEND_ERROR "CPackRPM:Warning: CPACK_RPM_CHANGELOG_FILE <${CPACK_RPM_CHANGELOG_FILE}> does not exists - ignoring")
+ endif(EXISTS ${CPACK_RPM_CHANGELOG_FILE})
+else(CPACK_RPM_CHANGELOG_FILE)
+ set(CPACK_RPM_SPEC_CHANGELOG "* Sun Jul 4 2010 Erk <eric.noulard@gmail.com>\n Generated by CPack RPM (no Changelog file were provided)")
+endif(CPACK_RPM_CHANGELOG_FILE)
+
+# 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(CPACK_RPM_PACKAGE_DEBUG)
+ENDIF(CPACK_RPM_SPEC_MORE_DEFINE)
+
+# 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}")
+
+# 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 ".")
+ 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(CPACK_RPM_PACKAGE_DEBUG)
+ endif()
+else()
+ if(CPACK_ABSOLUTE_DESTINATION_FILES)
+ set(CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL "${CPACK_ABSOLUTE_DESTINATION_FILES}")
+ 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})
+ 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(CPACK_RPM_PACKAGE_DEBUG)
+ 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}>")
+ ENDIF(CPACK_RPM_PACKAGE_DEBUG)
+
+ # 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-z\(\)]* " "" F_PATH ${F})
+ string(REGEX MATCH "%[A-Za-z\(\)]*" F_PREFIX ${F})
+
+ 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})
+ list(REMOVE_ITEM CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL ${F_PATH})
+
+ 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(F)
+else()
+ set(CPACK_RPM_USER_INSTALL_FILES "")
+endif()
+
+if (CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL)
+ IF(CPACK_RPM_PACKAGE_DEBUG)
+ message("CPackRPM:Debug: Handling Absolute Destination Files: ${CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL}")
+ ENDIF(CPACK_RPM_PACKAGE_DEBUG)
+ # 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(F)
+ # 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(F)
+ 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(CPACK_RPM_PACKAGE_DEBUG)
+else()
+ # reset vars in order to avoid leakage of value(s) from one component to another
+ set(CPACK_RPM_ABSOLUTE_INSTALL_FILES "")
+endif(CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL)
+
+# 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(F)
+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(CPACK_RPM_PACKAGE_DEBUG)
+
+# USER generated spec file handling.
+# We should generate a 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\@
+Version: \@CPACK_RPM_PACKAGE_VERSION\@
+Release: \@CPACK_RPM_PACKAGE_RELEASE\@
+License: \@CPACK_RPM_PACKAGE_LICENSE\@
+Group: \@CPACK_RPM_PACKAGE_GROUP\@
+Vendor: \@CPACK_RPM_PACKAGE_VENDOR\@
+\@TMP_RPM_URL\@
+\@TMP_RPM_REQUIRES\@
+\@TMP_RPM_PROVIDES\@
+\@TMP_RPM_OBSOLETES\@
+\@TMP_RPM_CONFLICTS\@
+\@TMP_RPM_AUTOPROV\@
+\@TMP_RPM_AUTOREQ\@
+\@TMP_RPM_AUTOREQPROV\@
+\@TMP_RPM_BUILDARCH\@
+\@TMP_RPM_PREFIX\@
+
+%define _rpmdir \@CPACK_RPM_DIRECTORY\@
+%define _rpmfilename \@CPACK_RPM_FILE_NAME\@
+%define _unpackaged_files_terminate_build 0
+%define _topdir \@CPACK_RPM_DIRECTORY\@
+\@TMP_RPM_SPEC_INSTALL_POST\@
+\@CPACK_RPM_SPEC_MORE_DEFINE\@
+\@CPACK_RPM_COMPRESSION_TYPE_TMP\@
+
+%description
+\@CPACK_RPM_PACKAGE_DESCRIPTION\@
+
+# This is a shortcutted spec file generated by CMake RPM generator
+# we skip _install step because CPack does that for us.
+# We do only save CPack installed tree in _prepr
+# and then restore it in build.
+%prep
+mv $RPM_BUILD_ROOT \"\@CPACK_TOPLEVEL_DIRECTORY\@/tmpBBroot\"
+
+#p build
+
+%install
+if [ -e $RPM_BUILD_ROOT ];
+then
+ rm -rf $RPM_BUILD_ROOT
+fi
+mv \"\@CPACK_TOPLEVEL_DIRECTORY\@/tmpBBroot\" $RPM_BUILD_ROOT
+
+%clean
+
+%post
+\@CPACK_RPM_SPEC_POSTINSTALL\@
+
+%postun
+\@CPACK_RPM_SPEC_POSTUNINSTALL\@
+
+%pre
+\@CPACK_RPM_SPEC_PREINSTALL\@
+
+%preun
+\@CPACK_RPM_SPEC_PREUNINSTALL\@
+
+%files
+%defattr(-,root,root,-)
+${CPACK_RPM_INSTALL_FILES}
+${CPACK_RPM_ABSOLUTE_INSTALL_FILES}
+${CPACK_RPM_USER_INSTALL_FILES}
+
+%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")
+ ENDIF(CPACK_RPM_GENERATE_USER_BINARY_SPECFILE_TEMPLATE)
+ENDIF(CPACK_RPM_GENERATE_USER_BINARY_SPECFILE_TEMPLATE OR NOT CPACK_RPM_USER_BINARY_SPECFILE)
+
+# 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(CPACK_RPM_USER_BINARY_SPECFILE)
+ # 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(CPACK_RPM_USER_BINARY_SPECFILE)
+
+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(CPACK_RPM_PACKAGE_DEBUG OR CPACK_RPMBUILD_EXEC_RESULT)
+ELSE(RPMBUILD_EXECUTABLE)
+ IF(ALIEN_EXECUTABLE)
+ MESSAGE(FATAL_ERROR "RPM packaging through alien not done (yet)")
+ ENDIF(ALIEN_EXECUTABLE)
+ENDIF(RPMBUILD_EXECUTABLE)
diff --git a/Modules/CPackZIP.cmake b/Modules/CPackZIP.cmake
new file mode 100644
index 000000000..99963cf91
--- /dev/null
+++ b/Modules/CPackZIP.cmake
@@ -0,0 +1,41 @@
+
+#=============================================================================
+# 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.)
+
+IF(CMAKE_BINARY_DIR)
+ MESSAGE(FATAL_ERROR "CPackZIP.cmake may only be used by CPack internally.")
+ENDIF(CMAKE_BINARY_DIR)
+
+FIND_PROGRAM(ZIP_EXECUTABLE wzzip PATHS "$ENV{ProgramFiles}/WinZip")
+IF(ZIP_EXECUTABLE)
+ SET(CPACK_ZIP_COMMAND "\"${ZIP_EXECUTABLE}\" -P \"<ARCHIVE>\" @<FILELIST>")
+ SET(CPACK_ZIP_NEED_QUOTES TRUE)
+ENDIF(ZIP_EXECUTABLE)
+
+IF(NOT ZIP_EXECUTABLE)
+ FIND_PROGRAM(ZIP_EXECUTABLE 7z PATHS "$ENV{ProgramFiles}/7-Zip")
+ IF(ZIP_EXECUTABLE)
+ SET(CPACK_ZIP_COMMAND "\"${ZIP_EXECUTABLE}\" a -tzip \"<ARCHIVE>\" @<FILELIST>")
+ SET(CPACK_ZIP_NEED_QUOTES TRUE)
+ ENDIF(ZIP_EXECUTABLE)
+ENDIF(NOT ZIP_EXECUTABLE)
+
+IF(NOT ZIP_EXECUTABLE)
+ FIND_PACKAGE(Cygwin)
+ FIND_PROGRAM(ZIP_EXECUTABLE zip PATHS "${CYGWIN_INSTALL_PATH}/bin")
+ IF(ZIP_EXECUTABLE)
+ SET(CPACK_ZIP_COMMAND "\"${ZIP_EXECUTABLE}\" -r \"<ARCHIVE>\" . -i@<FILELIST>")
+ SET(CPACK_ZIP_NEED_QUOTES FALSE)
+ ENDIF(ZIP_EXECUTABLE)
+ENDIF(NOT ZIP_EXECUTABLE)
+
diff --git a/Modules/CTest.cmake b/Modules/CTest.cmake
new file mode 100644
index 000000000..ec9dbeb79
--- /dev/null
+++ b/Modules/CTest.cmake
@@ -0,0 +1,286 @@
+# - 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.)
+
+#=============================================================================
+# 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.)
+
+OPTION(BUILD_TESTING "Build the testing tree." ON)
+
+# function to turn generator name into a version string
+# like vs7 vs71 vs8 vs9
+FUNCTION(GET_VS_VERSION_STRING generator var)
+ STRING(REGEX REPLACE "Visual Studio ([0-9][0-9]?)($|.*)" "\\1"
+ NUMBER "${generator}")
+ IF("${generator}" MATCHES "Visual Studio 7 .NET 2003")
+ SET(ver_string "vs71")
+ ELSE("${generator}" MATCHES "Visual Studio 7 .NET 2003")
+ SET(ver_string "vs${NUMBER}")
+ ENDIF("${generator}" MATCHES "Visual Studio 7 .NET 2003")
+ SET(${var} ${ver_string} PARENT_SCOPE)
+ENDFUNCTION(GET_VS_VERSION_STRING)
+
+IF(BUILD_TESTING)
+ # Setup some auxilary macros
+ MACRO(SET_IF_NOT_SET var val)
+ IF(NOT DEFINED "${var}")
+ SET("${var}" "${val}")
+ ENDIF(NOT DEFINED "${var}")
+ ENDMACRO(SET_IF_NOT_SET)
+
+ MACRO(SET_IF_SET var val)
+ IF(NOT "${val}" MATCHES "^$")
+ SET("${var}" "${val}")
+ ENDIF(NOT "${val}" MATCHES "^$")
+ ENDMACRO(SET_IF_SET)
+
+ MACRO(SET_IF_SET_AND_NOT_SET var val)
+ IF(NOT "${val}" MATCHES "^$")
+ SET_IF_NOT_SET("${var}" "${val}")
+ ENDIF(NOT "${val}" MATCHES "^$")
+ ENDMACRO(SET_IF_SET_AND_NOT_SET)
+
+ # Make sure testing is enabled
+ ENABLE_TESTING()
+
+ IF(EXISTS "${PROJECT_SOURCE_DIR}/CTestConfig.cmake")
+ INCLUDE("${PROJECT_SOURCE_DIR}/CTestConfig.cmake")
+ SET_IF_SET_AND_NOT_SET(NIGHTLY_START_TIME "${CTEST_NIGHTLY_START_TIME}")
+ SET_IF_SET_AND_NOT_SET(DROP_METHOD "${CTEST_DROP_METHOD}")
+ SET_IF_SET_AND_NOT_SET(DROP_SITE "${CTEST_DROP_SITE}")
+ SET_IF_SET_AND_NOT_SET(DROP_SITE_USER "${CTEST_DROP_SITE_USER}")
+ SET_IF_SET_AND_NOT_SET(DROP_SITE_PASSWORD "${CTEST_DROP_SITE_PASWORD}")
+ SET_IF_SET_AND_NOT_SET(DROP_SITE_MODE "${CTEST_DROP_SITE_MODE}")
+ SET_IF_SET_AND_NOT_SET(DROP_LOCATION "${CTEST_DROP_LOCATION}")
+ SET_IF_SET_AND_NOT_SET(TRIGGER_SITE "${CTEST_TRIGGER_SITE}")
+ SET_IF_SET_AND_NOT_SET(UPDATE_TYPE "${CTEST_UPDATE_TYPE}")
+ ENDIF(EXISTS "${PROJECT_SOURCE_DIR}/CTestConfig.cmake")
+
+ # the project can have a DartConfig.cmake file
+ IF(EXISTS "${PROJECT_SOURCE_DIR}/DartConfig.cmake")
+ INCLUDE("${PROJECT_SOURCE_DIR}/DartConfig.cmake")
+ ELSE(EXISTS "${PROJECT_SOURCE_DIR}/DartConfig.cmake")
+ # Dashboard is opened for submissions for a 24 hour period starting at
+ # the specified NIGHTLY_START_TIME. Time is specified in 24 hour format.
+ SET_IF_NOT_SET (NIGHTLY_START_TIME "00:00:00 EDT")
+ SET_IF_NOT_SET(DROP_METHOD "http")
+ SET_IF_NOT_SET (COMPRESS_SUBMISSION ON)
+ ENDIF(EXISTS "${PROJECT_SOURCE_DIR}/DartConfig.cmake")
+ SET_IF_NOT_SET (NIGHTLY_START_TIME "00:00:00 EDT")
+
+ FIND_PROGRAM(CVSCOMMAND cvs )
+ SET(CVS_UPDATE_OPTIONS "-d -A -P" CACHE STRING
+ "Options passed to the cvs update command.")
+ FIND_PROGRAM(SVNCOMMAND svn)
+ FIND_PROGRAM(BZRCOMMAND bzr)
+ FIND_PROGRAM(HGCOMMAND hg)
+ FIND_PROGRAM(GITCOMMAND git)
+
+ IF(NOT UPDATE_TYPE)
+ IF(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/CVS")
+ SET(UPDATE_TYPE cvs)
+ ELSEIF(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.svn")
+ SET(UPDATE_TYPE svn)
+ ELSEIF(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.bzr")
+ SET(UPDATE_TYPE bzr)
+ ELSEIF(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.hg")
+ SET(UPDATE_TYPE hg)
+ ELSEIF(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.git")
+ SET(UPDATE_TYPE git)
+ ENDIF()
+ ENDIF(NOT UPDATE_TYPE)
+
+ STRING(TOLOWER "${UPDATE_TYPE}" _update_type)
+ IF("${_update_type}" STREQUAL "cvs")
+ SET(UPDATE_COMMAND "${CVSCOMMAND}")
+ SET(UPDATE_OPTIONS "${CVS_UPDATE_OPTIONS}")
+ ELSEIF("${_update_type}" STREQUAL "svn")
+ SET(UPDATE_COMMAND "${SVNCOMMAND}")
+ SET(UPDATE_OPTIONS "${SVN_UPDATE_OPTIONS}")
+ ELSEIF("${_update_type}" STREQUAL "bzr")
+ SET(UPDATE_COMMAND "${BZRCOMMAND}")
+ SET(UPDATE_OPTIONS "${BZR_UPDATE_OPTIONS}")
+ ELSEIF("${_update_type}" STREQUAL "hg")
+ SET(UPDATE_COMMAND "${HGCOMMAND}")
+ SET(UPDATE_OPTIONS "${HG_UPDATE_OPTIONS}")
+ ELSEIF("${_update_type}" STREQUAL "git")
+ SET(UPDATE_COMMAND "${GITCOMMAND}")
+ SET(UPDATE_OPTIONS "${GIT_UPDATE_OPTIONS}")
+ ENDIF()
+
+ SET(DART_TESTING_TIMEOUT 1500 CACHE STRING
+ "Maximum time allowed before CTest will kill the test.")
+
+ SET(CTEST_SUBMIT_RETRY_DELAY 5 CACHE STRING
+ "How long to wait between timed-out CTest submissions.")
+ SET(CTEST_SUBMIT_RETRY_COUNT 3 CACHE STRING
+ "How many times to retry timed-out CTest submissions.")
+
+ FIND_PROGRAM(MEMORYCHECK_COMMAND
+ NAMES purify valgrind boundscheck
+ PATHS
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Rational Software\\Purify\\Setup;InstallFolder]"
+ DOC "Path to the memory checking command, used for memory error detection."
+ )
+ FIND_PROGRAM(SLURM_SBATCH_COMMAND sbatch DOC
+ "Path to the SLURM sbatch executable"
+ )
+ FIND_PROGRAM(SLURM_SRUN_COMMAND srun DOC
+ "Path to the SLURM srun executable"
+ )
+ SET(MEMORYCHECK_SUPPRESSIONS_FILE "" CACHE FILEPATH
+ "File that contains suppressions for the memory checker")
+ FIND_PROGRAM(SCPCOMMAND scp DOC
+ "Path to scp command, used by CTest for submitting results to a Dart server"
+ )
+ FIND_PROGRAM(COVERAGE_COMMAND gcov DOC
+ "Path to the coverage program that CTest uses for performing coverage inspection"
+ )
+ SET(COVERAGE_EXTRA_FLAGS "-l" CACHE STRING
+ "Extra command line flags to pass to the coverage tool")
+
+ # set the site name
+ SITE_NAME(SITE)
+ # set the build name
+ IF(NOT BUILDNAME)
+ SET(DART_COMPILER "${CMAKE_CXX_COMPILER}")
+ IF(NOT DART_COMPILER)
+ SET(DART_COMPILER "${CMAKE_C_COMPILER}")
+ ENDIF(NOT DART_COMPILER)
+ IF(NOT DART_COMPILER)
+ SET(DART_COMPILER "unknown")
+ ENDIF(NOT DART_COMPILER)
+ IF(WIN32)
+ SET(DART_NAME_COMPONENT "NAME_WE")
+ ELSE(WIN32)
+ SET(DART_NAME_COMPONENT "NAME")
+ ENDIF(WIN32)
+ IF(NOT BUILD_NAME_SYSTEM_NAME)
+ SET(BUILD_NAME_SYSTEM_NAME "${CMAKE_SYSTEM_NAME}")
+ ENDIF(NOT BUILD_NAME_SYSTEM_NAME)
+ IF(WIN32)
+ SET(BUILD_NAME_SYSTEM_NAME "Win32")
+ ENDIF(WIN32)
+ IF(UNIX OR BORLAND)
+ GET_FILENAME_COMPONENT(DART_CXX_NAME
+ "${CMAKE_CXX_COMPILER}" ${DART_NAME_COMPONENT})
+ ELSE(UNIX OR BORLAND)
+ GET_FILENAME_COMPONENT(DART_CXX_NAME
+ "${CMAKE_BUILD_TOOL}" ${DART_NAME_COMPONENT})
+ ENDIF(UNIX OR BORLAND)
+ IF(DART_CXX_NAME MATCHES "msdev")
+ SET(DART_CXX_NAME "vs60")
+ ENDIF(DART_CXX_NAME MATCHES "msdev")
+ IF(DART_CXX_NAME MATCHES "devenv")
+ GET_VS_VERSION_STRING("${CMAKE_GENERATOR}" DART_CXX_NAME)
+ ENDIF(DART_CXX_NAME MATCHES "devenv")
+ SET(BUILDNAME "${BUILD_NAME_SYSTEM_NAME}-${DART_CXX_NAME}")
+ ENDIF(NOT BUILDNAME)
+
+ # the build command
+ BUILD_COMMAND(MAKECOMMAND_DEFAULT_VALUE
+ CONFIGURATION "\${CTEST_CONFIGURATION_TYPE}")
+ SET(MAKECOMMAND ${MAKECOMMAND_DEFAULT_VALUE}
+ CACHE STRING "Command to build the project")
+
+ # the default build configuration the ctest build handler will use
+ # if there is no -C arg given to ctest:
+ SET(DEFAULT_CTEST_CONFIGURATION_TYPE "$ENV{CMAKE_CONFIG_TYPE}")
+ IF(DEFAULT_CTEST_CONFIGURATION_TYPE STREQUAL "")
+ SET(DEFAULT_CTEST_CONFIGURATION_TYPE "Release")
+ ENDIF(DEFAULT_CTEST_CONFIGURATION_TYPE STREQUAL "")
+
+ IF(NOT "${CMAKE_GENERATOR}" MATCHES "Make")
+ SET(CTEST_USE_LAUNCHERS 0)
+ ENDIF(NOT "${CMAKE_GENERATOR}" MATCHES "Make")
+ 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_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}")
+ ENDIF(CTEST_USE_LAUNCHERS)
+
+ MARK_AS_ADVANCED(
+ BZRCOMMAND
+ BZR_UPDATE_OPTIONS
+ COVERAGE_COMMAND
+ COVERAGE_EXTRA_FLAGS
+ CTEST_SUBMIT_RETRY_DELAY
+ CTEST_SUBMIT_RETRY_COUNT
+ CVSCOMMAND
+ CVS_UPDATE_OPTIONS
+ DART_TESTING_TIMEOUT
+ GITCOMMAND
+ HGCOMMAND
+ MAKECOMMAND
+ MEMORYCHECK_COMMAND
+ MEMORYCHECK_SUPPRESSIONS_FILE
+ PURIFYCOMMAND
+ SCPCOMMAND
+ SLURM_SBATCH_COMMAND
+ SLURM_SRUN_COMMAND
+ SITE
+ SVNCOMMAND
+ SVN_UPDATE_OPTIONS
+ )
+ IF(NOT RUN_FROM_DART)
+ SET(RUN_FROM_CTEST_OR_DART 1)
+ INCLUDE(CTestTargets)
+ SET(RUN_FROM_CTEST_OR_DART)
+ ENDIF(NOT RUN_FROM_DART)
+ENDIF(BUILD_TESTING)
diff --git a/Modules/CTestScriptMode.cmake b/Modules/CTestScriptMode.cmake
new file mode 100644
index 000000000..e459c1d59
--- /dev/null
+++ b/Modules/CTestScriptMode.cmake
@@ -0,0 +1,24 @@
+# This file is read by ctest in script mode (-S)
+
+#=============================================================================
+# Copyright 2009 Kitware, Inc.
+# Copyright 2009 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.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+# Determine the current system, so this information can be used
+# in ctest scripts
+include(CMakeDetermineSystem)
+
+# Also load the system specific file, which sets up e.g. the search paths.
+# This makes the FIND_XXX() calls work much better
+include(CMakeSystemSpecificInformation)
+
diff --git a/Modules/CTestTargets.cmake b/Modules/CTestTargets.cmake
new file mode 100644
index 000000000..bc4d9646a
--- /dev/null
+++ b/Modules/CTestTargets.cmake
@@ -0,0 +1,95 @@
+
+#=============================================================================
+# 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.)
+
+IF(NOT RUN_FROM_CTEST_OR_DART)
+ MESSAGE(FATAL_ERROR "Do not incldue CTestTargets.cmake directly")
+ENDIF(NOT RUN_FROM_CTEST_OR_DART)
+
+# make directories in the binary tree
+FILE(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/Testing/Temporary)
+GET_FILENAME_COMPONENT(CMAKE_HOST_PATH ${CMAKE_COMMAND} PATH)
+SET(CMAKE_TARGET_PATH ${EXECUTABLE_OUTPUT_PATH})
+FIND_PROGRAM(CMAKE_CTEST_COMMAND ctest ${CMAKE_HOST_PATH} ${CMAKE_TARGET_PATH})
+MARK_AS_ADVANCED(CMAKE_CTEST_COMMAND)
+
+# Use CTest
+# configure files
+
+IF(CTEST_NEW_FORMAT)
+ CONFIGURE_FILE(
+ ${CMAKE_ROOT}/Modules/DartConfiguration.tcl.in
+ ${PROJECT_BINARY_DIR}/CTestConfiguration.ini )
+ELSE(CTEST_NEW_FORMAT)
+ CONFIGURE_FILE(
+ ${CMAKE_ROOT}/Modules/DartConfiguration.tcl.in
+ ${PROJECT_BINARY_DIR}/DartConfiguration.tcl )
+ENDIF(CTEST_NEW_FORMAT)
+
+#
+# Section 3:
+#
+# Custom targets to perform dashboard builds and submissions.
+# These should NOT need to be modified from project to project.
+#
+
+SET(__conf_types "")
+IF(CMAKE_CONFIGURATION_TYPES)
+ # We need to pass the configuration type on the test command line.
+ SET(__conf_types -C "${CMAKE_CFG_INTDIR}")
+ENDIF(CMAKE_CONFIGURATION_TYPES)
+
+# Add convenience targets. Do this at most once in case of nested
+# projects.
+DEFINE_PROPERTY(GLOBAL PROPERTY CTEST_TARGETS_ADDED
+ BRIEF_DOCS "Internal property used by CTestTargets module."
+ FULL_DOCS "Set by the CTestTargets module to track addition of testing targets."
+ )
+GET_PROPERTY(_CTEST_TARGETS_ADDED GLOBAL PROPERTY CTEST_TARGETS_ADDED)
+IF(NOT _CTEST_TARGETS_ADDED)
+ SET_PROPERTY(GLOBAL PROPERTY CTEST_TARGETS_ADDED 1)
+
+ # For all generators add basic testing targets.
+ FOREACH(mode Experimental Nightly Continuous NightlyMemoryCheck)
+ ADD_CUSTOM_TARGET(${mode}
+ ${CMAKE_CTEST_COMMAND} ${__conf_types} -D ${mode}
+ )
+ SET_PROPERTY(TARGET ${mode} PROPERTY RULE_LAUNCH_CUSTOM "")
+ SET_PROPERTY(TARGET ${mode} PROPERTY FOLDER "CTestDashboardTargets")
+ ENDFOREACH(mode)
+
+ # For Makefile generators add more granular targets.
+ IF("${CMAKE_GENERATOR}" MATCHES "(Ninja|Make)")
+ # Make targets for Experimental builds
+ FOREACH(mode Nightly Experimental Continuous)
+ FOREACH(testtype
+ Start Update Configure Build Test Coverage MemCheck Submit
+ # missing purify
+ )
+ ADD_CUSTOM_TARGET(${mode}${testtype}
+ ${CMAKE_CTEST_COMMAND} ${__conf_types} -D ${mode}${testtype}
+ )
+ SET_PROPERTY(TARGET ${mode}${testtype} PROPERTY RULE_LAUNCH_CUSTOM "")
+ SET_PROPERTY(TARGET ${mode}${testtype} PROPERTY FOLDER "CTestDashboardTargets")
+ ENDFOREACH(testtype)
+ ENDFOREACH(mode)
+ ENDIF("${CMAKE_GENERATOR}" MATCHES "(Ninja|Make)")
+
+ # If requested, add an alias that is the equivalent of the built-in "test"
+ # or "RUN_TESTS" target:
+ IF(CTEST_TEST_TARGET_ALIAS)
+ ADD_CUSTOM_TARGET(${CTEST_TEST_TARGET_ALIAS}
+ ${CMAKE_CTEST_COMMAND} ${__conf_types}
+ )
+ ENDIF()
+ENDIF(NOT _CTEST_TARGETS_ADDED)
diff --git a/Modules/CheckCCompilerFlag.cmake b/Modules/CheckCCompilerFlag.cmake
new file mode 100644
index 000000000..90d04ac66
--- /dev/null
+++ b/Modules/CheckCCompilerFlag.cmake
@@ -0,0 +1,45 @@
+# - 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.
+# See help for CheckCSourceCompiles for a listing of variables
+# that can modify the build.
+
+#=============================================================================
+# 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(CheckCSourceCompiles)
+
+MACRO (CHECK_C_COMPILER_FLAG _FLAG _RESULT)
+ SET(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}")
+ SET(CMAKE_REQUIRED_DEFINITIONS "${_FLAG}")
+ 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
+ )
+ SET (CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}")
+ENDMACRO (CHECK_C_COMPILER_FLAG)
diff --git a/Modules/CheckCSourceCompiles.cmake b/Modules/CheckCSourceCompiles.cmake
new file mode 100644
index 000000000..266933634
--- /dev/null
+++ b/Modules/CheckCSourceCompiles.cmake
@@ -0,0 +1,95 @@
+# - 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
+
+#=============================================================================
+# 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.)
+
+INCLUDE("${CMAKE_CURRENT_LIST_DIR}/CMakeExpandImportedTargets.cmake")
+
+
+MACRO(CHECK_C_SOURCE_COMPILES SOURCE VAR)
+ IF("${VAR}" MATCHES "^${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)
+ # this one translates potentially used imported library targets to their files on disk
+ CMAKE_EXPAND_IMPORTED_TARGETS(_ADJUSTED_CMAKE_REQUIRED_LIBRARIES LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}")
+ SET(CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES
+ "-DLINK_LIBRARIES:STRING=${_ADJUSTED_CMAKE_REQUIRED_LIBRARIES}")
+ ELSE(CMAKE_REQUIRED_LIBRARIES)
+ SET(CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES)
+ ENDIF(CMAKE_REQUIRED_LIBRARIES)
+ IF(CMAKE_REQUIRED_INCLUDES)
+ SET(CHECK_C_SOURCE_COMPILES_ADD_INCLUDES
+ "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
+ ELSE(CMAKE_REQUIRED_INCLUDES)
+ SET(CHECK_C_SOURCE_COMPILES_ADD_INCLUDES)
+ ENDIF(CMAKE_REQUIRED_INCLUDES)
+ FILE(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c"
+ "${SOURCE}\n")
+
+ MESSAGE(STATUS "Performing Test ${VAR}")
+ 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}
+ "${CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES}"
+ "${CHECK_C_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}")
+ MESSAGE(STATUS "Performing Test ${VAR} - Success")
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "Performing C SOURCE FILE Test ${VAR} succeded with the following output:\n"
+ "${OUTPUT}\n"
+ "Source file was:\n${SOURCE}\n")
+ ELSE(${VAR})
+ MESSAGE(STATUS "Performing Test ${VAR} - Failed")
+ 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"
+ "${OUTPUT}\n"
+ "Source file was:\n${SOURCE}\n")
+ ENDIF(${VAR})
+ ENDIF("${VAR}" MATCHES "^${VAR}$")
+ENDMACRO(CHECK_C_SOURCE_COMPILES)
+
diff --git a/Modules/CheckCSourceRuns.cmake b/Modules/CheckCSourceRuns.cmake
new file mode 100644
index 000000000..feee93a71
--- /dev/null
+++ b/Modules/CheckCSourceRuns.cmake
@@ -0,0 +1,91 @@
+# - 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
+
+#=============================================================================
+# Copyright 2006-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.)
+
+INCLUDE("${CMAKE_CURRENT_LIST_DIR}/CMakeExpandImportedTargets.cmake")
+
+
+MACRO(CHECK_C_SOURCE_RUNS SOURCE VAR)
+ IF("${VAR}" MATCHES "^${VAR}$")
+ SET(MACRO_CHECK_FUNCTION_DEFINITIONS
+ "-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
+ IF(CMAKE_REQUIRED_LIBRARIES)
+ # this one translates potentially used imported library targets to their files on disk
+ CMAKE_EXPAND_IMPORTED_TARGETS(_ADJUSTED_CMAKE_REQUIRED_LIBRARIES LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}")
+ SET(CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES
+ "-DLINK_LIBRARIES:STRING=${_ADJUSTED_CMAKE_REQUIRED_LIBRARIES}")
+ ELSE(CMAKE_REQUIRED_LIBRARIES)
+ SET(CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES)
+ ENDIF(CMAKE_REQUIRED_LIBRARIES)
+ IF(CMAKE_REQUIRED_INCLUDES)
+ SET(CHECK_C_SOURCE_COMPILES_ADD_INCLUDES
+ "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
+ ELSE(CMAKE_REQUIRED_INCLUDES)
+ SET(CHECK_C_SOURCE_COMPILES_ADD_INCLUDES)
+ ENDIF(CMAKE_REQUIRED_INCLUDES)
+ FILE(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c"
+ "${SOURCE}\n")
+
+ MESSAGE(STATUS "Performing Test ${VAR}")
+ TRY_RUN(${VAR}_EXITCODE ${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}
+ -DCMAKE_SKIP_RPATH:BOOL=${CMAKE_SKIP_RPATH}
+ "${CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES}"
+ "${CHECK_C_SOURCE_COMPILES_ADD_INCLUDES}"
+ COMPILE_OUTPUT_VARIABLE OUTPUT)
+ # if it did not compile make the return value fail code of 1
+ IF(NOT ${VAR}_COMPILED)
+ SET(${VAR}_EXITCODE 1)
+ ENDIF(NOT ${VAR}_COMPILED)
+ # 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")
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "Performing C SOURCE FILE Test ${VAR} succeded with the following output:\n"
+ "${OUTPUT}\n"
+ "Return value: ${${VAR}}\n"
+ "Source file was:\n${SOURCE}\n")
+ ELSE("${${VAR}_EXITCODE}" EQUAL 0)
+ IF(CMAKE_CROSSCOMPILING AND "${${VAR}_EXITCODE}" MATCHES "FAILED_TO_RUN")
+ SET(${VAR} "${${VAR}_EXITCODE}")
+ ELSE(CMAKE_CROSSCOMPILING AND "${${VAR}_EXITCODE}" MATCHES "FAILED_TO_RUN")
+ SET(${VAR} "" CACHE INTERNAL "Test ${VAR}")
+ ENDIF(CMAKE_CROSSCOMPILING AND "${${VAR}_EXITCODE}" MATCHES "FAILED_TO_RUN")
+
+ MESSAGE(STATUS "Performing Test ${VAR} - Failed")
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Performing C SOURCE FILE Test ${VAR} failed with the following output:\n"
+ "${OUTPUT}\n"
+ "Return value: ${${VAR}_EXITCODE}\n"
+ "Source file was:\n${SOURCE}\n")
+
+ ENDIF("${${VAR}_EXITCODE}" EQUAL 0)
+ ENDIF("${VAR}" MATCHES "^${VAR}$")
+ENDMACRO(CHECK_C_SOURCE_RUNS)
+
diff --git a/Modules/CheckCXXCompilerFlag.cmake b/Modules/CheckCXXCompilerFlag.cmake
new file mode 100644
index 000000000..19963ea4c
--- /dev/null
+++ b/Modules/CheckCXXCompilerFlag.cmake
@@ -0,0 +1,48 @@
+# - 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. See help
+# for CheckCXXSourceCompiles for a listing of variables that can
+# modify the build.
+
+#=============================================================================
+# Copyright 2006-2010 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(CheckCXXSourceCompiles)
+
+MACRO (CHECK_CXX_COMPILER_FLAG _FLAG _RESULT)
+ SET(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}")
+ SET(CMAKE_REQUIRED_DEFINITIONS "${_FLAG}")
+ 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
+ )
+ SET (CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}")
+ENDMACRO (CHECK_CXX_COMPILER_FLAG)
+
diff --git a/Modules/CheckCXXSourceCompiles.cmake b/Modules/CheckCXXSourceCompiles.cmake
new file mode 100644
index 000000000..7f7336e5b
--- /dev/null
+++ b/Modules/CheckCXXSourceCompiles.cmake
@@ -0,0 +1,96 @@
+# - 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
+
+#=============================================================================
+# 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.)
+
+INCLUDE("${CMAKE_CURRENT_LIST_DIR}/CMakeExpandImportedTargets.cmake")
+
+
+MACRO(CHECK_CXX_SOURCE_COMPILES SOURCE VAR)
+ IF("${VAR}" MATCHES "^${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)
+ # this one translates potentially used imported library targets to their files on disk
+ CMAKE_EXPAND_IMPORTED_TARGETS(_ADJUSTED_CMAKE_REQUIRED_LIBRARIES LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}")
+ SET(CHECK_CXX_SOURCE_COMPILES_ADD_LIBRARIES
+ "-DLINK_LIBRARIES:STRING=${_ADJUSTED_CMAKE_REQUIRED_LIBRARIES}")
+ ELSE(CMAKE_REQUIRED_LIBRARIES)
+ SET(CHECK_CXX_SOURCE_COMPILES_ADD_LIBRARIES)
+ ENDIF(CMAKE_REQUIRED_LIBRARIES)
+ IF(CMAKE_REQUIRED_INCLUDES)
+ SET(CHECK_CXX_SOURCE_COMPILES_ADD_INCLUDES
+ "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
+ ELSE(CMAKE_REQUIRED_INCLUDES)
+ SET(CHECK_CXX_SOURCE_COMPILES_ADD_INCLUDES)
+ ENDIF(CMAKE_REQUIRED_INCLUDES)
+ FILE(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.cxx"
+ "${SOURCE}\n")
+
+ MESSAGE(STATUS "Performing Test ${VAR}")
+ TRY_COMPILE(${VAR}
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.cxx
+ COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+ CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
+ "${CHECK_CXX_SOURCE_COMPILES_ADD_LIBRARIES}"
+ "${CHECK_CXX_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}")
+ MESSAGE(STATUS "Performing Test ${VAR} - Success")
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "Performing C++ SOURCE FILE Test ${VAR} succeded with the following output:\n"
+ "${OUTPUT}\n"
+ "Source file was:\n${SOURCE}\n")
+ ELSE(${VAR})
+ MESSAGE(STATUS "Performing Test ${VAR} - Failed")
+ 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"
+ "${OUTPUT}\n"
+ "Source file was:\n${SOURCE}\n")
+ ENDIF(${VAR})
+ ENDIF("${VAR}" MATCHES "^${VAR}$")
+ENDMACRO(CHECK_CXX_SOURCE_COMPILES)
+
diff --git a/Modules/CheckCXXSourceRuns.cmake b/Modules/CheckCXXSourceRuns.cmake
new file mode 100644
index 000000000..cd68d5706
--- /dev/null
+++ b/Modules/CheckCXXSourceRuns.cmake
@@ -0,0 +1,91 @@
+# - 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
+
+#=============================================================================
+# Copyright 2006-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.)
+
+INCLUDE("${CMAKE_CURRENT_LIST_DIR}/CMakeExpandImportedTargets.cmake")
+
+
+MACRO(CHECK_CXX_SOURCE_RUNS SOURCE VAR)
+ IF("${VAR}" MATCHES "^${VAR}$")
+ SET(MACRO_CHECK_FUNCTION_DEFINITIONS
+ "-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
+ IF(CMAKE_REQUIRED_LIBRARIES)
+ # this one translates potentially used imported library targets to their files on disk
+ CMAKE_EXPAND_IMPORTED_TARGETS(_ADJUSTED_CMAKE_REQUIRED_LIBRARIES LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}")
+ SET(CHECK_CXX_SOURCE_COMPILES_ADD_LIBRARIES
+ "-DLINK_LIBRARIES:STRING=${_ADJUSTED_CMAKE_REQUIRED_LIBRARIES}")
+ ELSE(CMAKE_REQUIRED_LIBRARIES)
+ SET(CHECK_CXX_SOURCE_COMPILES_ADD_LIBRARIES)
+ ENDIF(CMAKE_REQUIRED_LIBRARIES)
+ IF(CMAKE_REQUIRED_INCLUDES)
+ SET(CHECK_CXX_SOURCE_COMPILES_ADD_INCLUDES
+ "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
+ ELSE(CMAKE_REQUIRED_INCLUDES)
+ SET(CHECK_CXX_SOURCE_COMPILES_ADD_INCLUDES)
+ ENDIF(CMAKE_REQUIRED_INCLUDES)
+ FILE(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.cxx"
+ "${SOURCE}\n")
+
+ MESSAGE(STATUS "Performing Test ${VAR}")
+ TRY_RUN(${VAR}_EXITCODE ${VAR}_COMPILED
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.cxx
+ COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+ CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
+ -DCMAKE_SKIP_RPATH:BOOL=${CMAKE_SKIP_RPATH}
+ "${CHECK_CXX_SOURCE_COMPILES_ADD_LIBRARIES}"
+ "${CHECK_CXX_SOURCE_COMPILES_ADD_INCLUDES}"
+ COMPILE_OUTPUT_VARIABLE OUTPUT)
+
+ # if it did not compile make the return value fail code of 1
+ IF(NOT ${VAR}_COMPILED)
+ SET(${VAR}_EXITCODE 1)
+ ENDIF(NOT ${VAR}_COMPILED)
+ # 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")
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "Performing C++ SOURCE FILE Test ${VAR} succeded with the following output:\n"
+ "${OUTPUT}\n"
+ "Return value: ${${VAR}}\n"
+ "Source file was:\n${SOURCE}\n")
+ ELSE("${${VAR}_EXITCODE}" EQUAL 0)
+ IF(CMAKE_CROSSCOMPILING AND "${${VAR}_EXITCODE}" MATCHES "FAILED_TO_RUN")
+ SET(${VAR} "${${VAR}_EXITCODE}")
+ ELSE(CMAKE_CROSSCOMPILING AND "${${VAR}_EXITCODE}" MATCHES "FAILED_TO_RUN")
+ SET(${VAR} "" CACHE INTERNAL "Test ${VAR}")
+ ENDIF(CMAKE_CROSSCOMPILING AND "${${VAR}_EXITCODE}" MATCHES "FAILED_TO_RUN")
+
+ MESSAGE(STATUS "Performing Test ${VAR} - Failed")
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Performing C++ SOURCE FILE Test ${VAR} failed with the following output:\n"
+ "${OUTPUT}\n"
+ "Return value: ${${VAR}_EXITCODE}\n"
+ "Source file was:\n${SOURCE}\n")
+ ENDIF("${${VAR}_EXITCODE}" EQUAL 0)
+ ENDIF("${VAR}" MATCHES "^${VAR}$")
+ENDMACRO(CHECK_CXX_SOURCE_RUNS)
+
diff --git a/Modules/CheckCXXSymbolExists.cmake b/Modules/CheckCXXSymbolExists.cmake
new file mode 100644
index 000000000..1b012aefd
--- /dev/null
+++ b/Modules/CheckCXXSymbolExists.cmake
@@ -0,0 +1,42 @@
+# - 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.
+#
+# 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
+
+#=============================================================================
+# Copyright 2003-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.)
+
+INCLUDE(CheckSymbolExists)
+
+MACRO(CHECK_CXX_SYMBOL_EXISTS SYMBOL FILES VARIABLE)
+ _CHECK_SYMBOL_EXISTS("${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckSymbolExists.cxx" "${SYMBOL}" "${FILES}" "${VARIABLE}" )
+ENDMACRO(CHECK_CXX_SYMBOL_EXISTS)
diff --git a/Modules/CheckForPthreads.c b/Modules/CheckForPthreads.c
new file mode 100644
index 000000000..d83107851
--- /dev/null
+++ b/Modules/CheckForPthreads.c
@@ -0,0 +1,38 @@
+#include <stdio.h>
+#include <pthread.h>
+#include <unistd.h>
+
+void* runner(void*);
+
+int res = 0;
+#ifdef __CLASSIC_C__
+int main(){
+ int ac;
+ char*av[];
+#else
+int main(int ac, char*av[]){
+#endif
+ pthread_t tid[2];
+ pthread_create(&tid[0], 0, runner, (void*)1);
+ pthread_create(&tid[1], 0, runner, (void*)2);
+
+#if defined(__BEOS__) && !defined(__ZETA__) && !defined(__HAIKU__) // (no usleep on BeOS 5.)
+ usleep(1); // for strange behavior on single-processor sun
+#endif
+
+ pthread_join(tid[0], 0);
+ pthread_join(tid[1], 0);
+ if(ac > 1000){return *av[0];}
+ return res;
+}
+
+void* runner(void* args)
+{
+ int cc;
+ for ( cc = 0; cc < 10; cc ++ )
+ {
+ printf("%d CC: %d\n", (int)args, cc);
+ }
+ res ++;
+ return 0;
+}
diff --git a/Modules/CheckFortranFunctionExists.cmake b/Modules/CheckFortranFunctionExists.cmake
new file mode 100644
index 000000000..abec9f738
--- /dev/null
+++ b/Modules/CheckFortranFunctionExists.cmake
@@ -0,0 +1,69 @@
+# - Check 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:
+#
+# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
+
+#=============================================================================
+# 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.)
+
+INCLUDE("${CMAKE_CURRENT_LIST_DIR}/CMakeExpandImportedTargets.cmake")
+
+
+macro(CHECK_FORTRAN_FUNCTION_EXISTS FUNCTION VARIABLE)
+ if(NOT DEFINED ${VARIABLE})
+ message(STATUS "Looking for Fortran ${FUNCTION}")
+ if(CMAKE_REQUIRED_LIBRARIES)
+ # this one translates potentially used imported library targets to their files on disk
+ cmake_expand_imported_targets(_ADJUSTED_CMAKE_REQUIRED_LIBRARIES LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}")
+ set(CHECK_FUNCTION_EXISTS_ADD_LIBRARIES
+ "-DLINK_LIBRARIES:STRING=${_ADJUSTED_CMAKE_REQUIRED_LIBRARIES}")
+ else(CMAKE_REQUIRED_LIBRARIES)
+ set(CHECK_FUNCTION_EXISTS_ADD_LIBRARIES)
+ endif(CMAKE_REQUIRED_LIBRARIES)
+ FILE(WRITE
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testFortranCompiler.f
+ "
+ program TESTFortran
+ external ${FUNCTION}
+ call ${FUNCTION}()
+ end program TESTFortran
+ "
+ )
+ try_compile(${VARIABLE}
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testFortranCompiler.f
+ CMAKE_FLAGS "${CHECK_FUNCTION_EXISTS_ADD_LIBRARIES}"
+ OUTPUT_VARIABLE OUTPUT
+ )
+# message(STATUS "${OUTPUT}")
+ if(${VARIABLE})
+ set(${VARIABLE} 1 CACHE INTERNAL "Have Fortran function ${FUNCTION}")
+ message(STATUS "Looking for Fortran ${FUNCTION} - found")
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "Determining if the Fortran ${FUNCTION} exists passed with the following output:\n"
+ "${OUTPUT}\n\n")
+ else(${VARIABLE})
+ message(STATUS "Looking for Fortran ${FUNCTION} - not found")
+ set(${VARIABLE} "" CACHE INTERNAL "Have Fortran function ${FUNCTION}")
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Determining if the Fortran ${FUNCTION} exists failed with the following output:\n"
+ "${OUTPUT}\n\n")
+ endif(${VARIABLE})
+ endif(NOT DEFINED ${VARIABLE})
+endmacro(CHECK_FORTRAN_FUNCTION_EXISTS)
diff --git a/Modules/CheckFunctionExists.c b/Modules/CheckFunctionExists.c
new file mode 100644
index 000000000..607b3e8c6
--- /dev/null
+++ b/Modules/CheckFunctionExists.c
@@ -0,0 +1,23 @@
+#ifdef CHECK_FUNCTION_EXISTS
+
+char CHECK_FUNCTION_EXISTS();
+#ifdef __CLASSIC_C__
+int main(){
+ int ac;
+ char*av[];
+#else
+int main(int ac, char*av[]){
+#endif
+ CHECK_FUNCTION_EXISTS();
+ if(ac > 1000)
+ {
+ return *av[0];
+ }
+ return 0;
+}
+
+#else /* CHECK_FUNCTION_EXISTS */
+
+# error "CHECK_FUNCTION_EXISTS has to specify the function"
+
+#endif /* CHECK_FUNCTION_EXISTS */
diff --git a/Modules/CheckFunctionExists.cmake b/Modules/CheckFunctionExists.cmake
new file mode 100644
index 000000000..8c469f012
--- /dev/null
+++ b/Modules/CheckFunctionExists.cmake
@@ -0,0 +1,74 @@
+# - 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 (considure using CheckSymbolExists).
+#
+# 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
+
+#=============================================================================
+# Copyright 2002-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.)
+
+INCLUDE("${CMAKE_CURRENT_LIST_DIR}/CMakeExpandImportedTargets.cmake")
+
+
+MACRO(CHECK_FUNCTION_EXISTS FUNCTION VARIABLE)
+ IF("${VARIABLE}" MATCHES "^${VARIABLE}$")
+ SET(MACRO_CHECK_FUNCTION_DEFINITIONS
+ "-DCHECK_FUNCTION_EXISTS=${FUNCTION} ${CMAKE_REQUIRED_FLAGS}")
+ MESSAGE(STATUS "Looking for ${FUNCTION}")
+ IF(CMAKE_REQUIRED_LIBRARIES)
+ # this one translates potentially used imported library targets to their files on disk
+ CMAKE_EXPAND_IMPORTED_TARGETS(_ADJUSTED_CMAKE_REQUIRED_LIBRARIES LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}")
+ SET(CHECK_FUNCTION_EXISTS_ADD_LIBRARIES
+ "-DLINK_LIBRARIES:STRING=${_ADJUSTED_CMAKE_REQUIRED_LIBRARIES}")
+ ELSE(CMAKE_REQUIRED_LIBRARIES)
+ SET(CHECK_FUNCTION_EXISTS_ADD_LIBRARIES)
+ ENDIF(CMAKE_REQUIRED_LIBRARIES)
+ IF(CMAKE_REQUIRED_INCLUDES)
+ SET(CHECK_FUNCTION_EXISTS_ADD_INCLUDES
+ "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
+ ELSE(CMAKE_REQUIRED_INCLUDES)
+ SET(CHECK_FUNCTION_EXISTS_ADD_INCLUDES)
+ ENDIF(CMAKE_REQUIRED_INCLUDES)
+ TRY_COMPILE(${VARIABLE}
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_ROOT}/Modules/CheckFunctionExists.c
+ COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+ CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
+ "${CHECK_FUNCTION_EXISTS_ADD_LIBRARIES}"
+ "${CHECK_FUNCTION_EXISTS_ADD_INCLUDES}"
+ OUTPUT_VARIABLE OUTPUT)
+ IF(${VARIABLE})
+ SET(${VARIABLE} 1 CACHE INTERNAL "Have function ${FUNCTION}")
+ MESSAGE(STATUS "Looking for ${FUNCTION} - found")
+ 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(${VARIABLE})
+ MESSAGE(STATUS "Looking for ${FUNCTION} - not found")
+ 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"
+ "${OUTPUT}\n\n")
+ ENDIF(${VARIABLE})
+ ENDIF("${VARIABLE}" MATCHES "^${VARIABLE}$")
+ENDMACRO(CHECK_FUNCTION_EXISTS)
diff --git a/Modules/CheckIncludeFile.c.in b/Modules/CheckIncludeFile.c.in
new file mode 100644
index 000000000..ddfbee8be
--- /dev/null
+++ b/Modules/CheckIncludeFile.c.in
@@ -0,0 +1,13 @@
+#include <${CHECK_INCLUDE_FILE_VAR}>
+
+#ifdef __CLASSIC_C__
+int main()
+{
+ return 0;
+}
+#else
+int main(void)
+{
+ return 0;
+}
+#endif
diff --git a/Modules/CheckIncludeFile.cmake b/Modules/CheckIncludeFile.cmake
new file mode 100644
index 000000000..eb732d28b
--- /dev/null
+++ b/Modules/CheckIncludeFile.cmake
@@ -0,0 +1,77 @@
+# - 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
+#
+# an optional third argument is the CFlags to add to the compile line
+# or you can use CMAKE_REQUIRED_FLAGS
+#
+# 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
+#
+
+#=============================================================================
+# 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.)
+
+MACRO(CHECK_INCLUDE_FILE INCLUDE VARIABLE)
+ IF("${VARIABLE}" MATCHES "^${VARIABLE}$")
+ IF(CMAKE_REQUIRED_INCLUDES)
+ SET(CHECK_INCLUDE_FILE_C_INCLUDE_DIRS "-DINCLUDE_DIRECTORIES=${CMAKE_REQUIRED_INCLUDES}")
+ ELSE(CMAKE_REQUIRED_INCLUDES)
+ SET(CHECK_INCLUDE_FILE_C_INCLUDE_DIRS)
+ ENDIF(CMAKE_REQUIRED_INCLUDES)
+ 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}")
+ IF(${ARGC} EQUAL 3)
+ SET(CMAKE_C_FLAGS_SAVE ${CMAKE_C_FLAGS})
+ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${ARGV2}")
+ ENDIF(${ARGC} EQUAL 3)
+
+ TRY_COMPILE(${VARIABLE}
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.c
+ COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+ CMAKE_FLAGS
+ -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_INCLUDE_FILE_FLAGS}
+ "${CHECK_INCLUDE_FILE_C_INCLUDE_DIRS}"
+ OUTPUT_VARIABLE OUTPUT)
+
+ IF(${ARGC} EQUAL 3)
+ SET(CMAKE_C_FLAGS ${CMAKE_C_FLAGS_SAVE})
+ ENDIF(${ARGC} EQUAL 3)
+
+ IF(${VARIABLE})
+ MESSAGE(STATUS "Looking for ${INCLUDE} - found")
+ 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(${VARIABLE})
+ MESSAGE(STATUS "Looking for ${INCLUDE} - not found")
+ SET(${VARIABLE} "" CACHE INTERNAL "Have include ${INCLUDE}")
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Determining if the include file ${INCLUDE} "
+ "exists failed with the following output:\n"
+ "${OUTPUT}\n\n")
+ ENDIF(${VARIABLE})
+ ENDIF("${VARIABLE}" MATCHES "^${VARIABLE}$")
+ENDMACRO(CHECK_INCLUDE_FILE)
diff --git a/Modules/CheckIncludeFile.cxx.in b/Modules/CheckIncludeFile.cxx.in
new file mode 100644
index 000000000..40441f15a
--- /dev/null
+++ b/Modules/CheckIncludeFile.cxx.in
@@ -0,0 +1,6 @@
+#include <${CHECK_INCLUDE_FILE_VAR}>
+
+int main()
+{
+ return 0;
+}
diff --git a/Modules/CheckIncludeFileCXX.cmake b/Modules/CheckIncludeFileCXX.cmake
new file mode 100644
index 000000000..c5d8f9aa2
--- /dev/null
+++ b/Modules/CheckIncludeFileCXX.cmake
@@ -0,0 +1,77 @@
+# - Check if the include file exists.
+# CHECK_INCLUDE_FILE_CXX(INCLUDE VARIABLE)
+#
+# INCLUDE - name of include file
+# VARIABLE - variable to return result
+#
+# An optional third argument is the CFlags to add to the compile line
+# or you can use CMAKE_REQUIRED_FLAGS.
+#
+# 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
+#
+
+#=============================================================================
+# 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.)
+
+MACRO(CHECK_INCLUDE_FILE_CXX INCLUDE VARIABLE)
+ IF("${VARIABLE}" MATCHES "^${VARIABLE}$")
+ IF(CMAKE_REQUIRED_INCLUDES)
+ SET(CHECK_INCLUDE_FILE_CXX_INCLUDE_DIRS "-DINCLUDE_DIRECTORIES=${CMAKE_REQUIRED_INCLUDES}")
+ ELSE(CMAKE_REQUIRED_INCLUDES)
+ SET(CHECK_INCLUDE_FILE_CXX_INCLUDE_DIRS)
+ ENDIF(CMAKE_REQUIRED_INCLUDES)
+ 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}")
+ IF(${ARGC} EQUAL 3)
+ SET(CMAKE_CXX_FLAGS_SAVE ${CMAKE_CXX_FLAGS})
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARGV2}")
+ ENDIF(${ARGC} EQUAL 3)
+
+ TRY_COMPILE(${VARIABLE}
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.cxx
+ COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+ CMAKE_FLAGS
+ -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_INCLUDE_FILE_FLAGS}
+ "${CHECK_INCLUDE_FILE_CXX_INCLUDE_DIRS}"
+ OUTPUT_VARIABLE OUTPUT)
+
+ IF(${ARGC} EQUAL 3)
+ SET(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS_SAVE})
+ ENDIF(${ARGC} EQUAL 3)
+
+ IF(${VARIABLE})
+ MESSAGE(STATUS "Looking for C++ include ${INCLUDE} - found")
+ 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(${VARIABLE})
+ MESSAGE(STATUS "Looking for C++ include ${INCLUDE} - not found")
+ SET(${VARIABLE} "" CACHE INTERNAL "Have include ${INCLUDE}")
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Determining if the include file ${INCLUDE} "
+ "exists failed with the following output:\n"
+ "${OUTPUT}\n\n")
+ ENDIF(${VARIABLE})
+ ENDIF("${VARIABLE}" MATCHES "^${VARIABLE}$")
+ENDMACRO(CHECK_INCLUDE_FILE_CXX)
diff --git a/Modules/CheckIncludeFiles.cmake b/Modules/CheckIncludeFiles.cmake
new file mode 100644
index 000000000..a94644e6a
--- /dev/null
+++ b/Modules/CheckIncludeFiles.cmake
@@ -0,0 +1,82 @@
+# - Check if the files can be included
+#
+# CHECK_INCLUDE_FILES(INCLUDE VARIABLE)
+#
+# INCLUDE - list of files to include
+# VARIABLE - variable to return result
+#
+# 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
+
+#=============================================================================
+# Copyright 2003-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.)
+
+MACRO(CHECK_INCLUDE_FILES INCLUDE VARIABLE)
+ IF("${VARIABLE}" MATCHES "^${VARIABLE}$")
+ SET(CMAKE_CONFIGURABLE_FILE_CONTENT "/* */\n")
+ IF(CMAKE_REQUIRED_INCLUDES)
+ SET(CHECK_INCLUDE_FILES_INCLUDE_DIRS "-DINCLUDE_DIRECTORIES=${CMAKE_REQUIRED_INCLUDES}")
+ ELSE(CMAKE_REQUIRED_INCLUDES)
+ SET(CHECK_INCLUDE_FILES_INCLUDE_DIRS)
+ ENDIF(CMAKE_REQUIRED_INCLUDES)
+ SET(CHECK_INCLUDE_FILES_CONTENT "/* */\n")
+ SET(MACRO_CHECK_INCLUDE_FILES_FLAGS ${CMAKE_REQUIRED_FLAGS})
+ FOREACH(FILE ${INCLUDE})
+ SET(CMAKE_CONFIGURABLE_FILE_CONTENT
+ "${CMAKE_CONFIGURABLE_FILE_CONTENT}#include <${FILE}>\n")
+ ENDFOREACH(FILE)
+ SET(CMAKE_CONFIGURABLE_FILE_CONTENT
+ "${CMAKE_CONFIGURABLE_FILE_CONTENT}\n\nint main(){return 0;}\n")
+ CONFIGURE_FILE("${CMAKE_ROOT}/Modules/CMakeConfigurableFile.in"
+ "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFiles.c" @ONLY IMMEDIATE)
+
+ SET(_INCLUDE ${INCLUDE}) # remove empty elements
+ IF("${_INCLUDE}" MATCHES "^([^;]+);.+;([^;]+)$")
+ LIST(LENGTH _INCLUDE _INCLUDE_LEN)
+ SET(_description "${_INCLUDE_LEN} include files ${CMAKE_MATCH_1}, ..., ${CMAKE_MATCH_2}")
+ ELSEIF("${_INCLUDE}" MATCHES "^([^;]+);([^;]+)$")
+ SET(_description "include files ${CMAKE_MATCH_1}, ${CMAKE_MATCH_2}")
+ ELSE()
+ SET(_description "include file ${_INCLUDE}")
+ ENDIF()
+
+ MESSAGE(STATUS "Looking for ${_description}")
+ TRY_COMPILE(${VARIABLE}
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFiles.c
+ COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+ CMAKE_FLAGS
+ -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_INCLUDE_FILES_FLAGS}
+ "${CHECK_INCLUDE_FILES_INCLUDE_DIRS}"
+ OUTPUT_VARIABLE OUTPUT)
+ IF(${VARIABLE})
+ MESSAGE(STATUS "Looking for ${_description} - found")
+ 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(${VARIABLE})
+ MESSAGE(STATUS "Looking for ${_description} - not found.")
+ SET(${VARIABLE} "" CACHE INTERNAL "Have includes ${INCLUDE}")
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Determining if files ${INCLUDE} "
+ "exist failed with the following output:\n"
+ "${OUTPUT}\nSource:\n${CMAKE_CONFIGURABLE_FILE_CONTENT}\n")
+ ENDIF(${VARIABLE})
+ ENDIF("${VARIABLE}" MATCHES "^${VARIABLE}$")
+ENDMACRO(CHECK_INCLUDE_FILES)
diff --git a/Modules/CheckLanguage.cmake b/Modules/CheckLanguage.cmake
new file mode 100644
index 000000000..87a401813
--- /dev/null
+++ b/Modules/CheckLanguage.cmake
@@ -0,0 +1,65 @@
+# - Check if a language can be enabled
+# Usage:
+# 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.
+#
+# Example:
+# check_language(Fortran)
+# if(CMAKE_Fortran_COMPILER)
+# enable_language(Fortran)
+# else()
+# message(STATUS "No Fortran support")
+# endif()
+
+#=============================================================================
+# Copyright 2009-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.)
+
+macro(check_language lang)
+ if(NOT DEFINED CMAKE_${lang}_COMPILER)
+ set(_desc "Looking for a ${lang} compiler")
+ 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)
+project(Check${lang} ${lang})
+file(WRITE \"\${CMAKE_CURRENT_BINARY_DIR}/result.cmake\"
+ \"set(CMAKE_${lang}_COMPILER \\\"\${CMAKE_${lang}_COMPILER}\\\")\\n\"
+ )
+")
+ execute_process(
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/Check${lang}
+ COMMAND ${CMAKE_COMMAND} . -G ${CMAKE_GENERATOR}
+ OUTPUT_VARIABLE output
+ ERROR_VARIABLE output
+ RESULT_VARIABLE result
+ )
+ include(${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/Check${lang}/result.cmake OPTIONAL)
+ if(CMAKE_${lang}_COMPILER AND "${result}" STREQUAL "0")
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "${_desc} passed with the following output:\n"
+ "${output}\n")
+ else()
+ set(CMAKE_${lang}_COMPILER NOTFOUND)
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "${_desc} failed with the following output:\n"
+ "${output}\n")
+ endif()
+ message(STATUS "${_desc} - ${CMAKE_${lang}_COMPILER}")
+ set(CMAKE_${lang}_COMPILER "${CMAKE_${lang}_COMPILER}" CACHE FILEPATH "${lang} compiler")
+ mark_as_advanced(CMAKE_${lang}_COMPILER)
+ endif()
+endmacro()
diff --git a/Modules/CheckLibraryExists.cmake b/Modules/CheckLibraryExists.cmake
new file mode 100644
index 000000000..59fca0a32
--- /dev/null
+++ b/Modules/CheckLibraryExists.cmake
@@ -0,0 +1,70 @@
+# - 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
+#
+# 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
+
+#=============================================================================
+# 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.)
+
+INCLUDE("${CMAKE_CURRENT_LIST_DIR}/CMakeExpandImportedTargets.cmake")
+
+
+MACRO(CHECK_LIBRARY_EXISTS LIBRARY FUNCTION LOCATION VARIABLE)
+ IF("${VARIABLE}" MATCHES "^${VARIABLE}$")
+ SET(MACRO_CHECK_LIBRARY_EXISTS_DEFINITION
+ "-DCHECK_FUNCTION_EXISTS=${FUNCTION} ${CMAKE_REQUIRED_FLAGS}")
+ MESSAGE(STATUS "Looking for ${FUNCTION} in ${LIBRARY}")
+ SET(CHECK_LIBRARY_EXISTS_LIBRARIES ${LIBRARY})
+ IF(CMAKE_REQUIRED_LIBRARIES)
+ # this one translates potentially used imported library targets to their files on disk
+ CMAKE_EXPAND_IMPORTED_TARGETS(_ADJUSTED_CMAKE_REQUIRED_LIBRARIES LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}")
+ SET(CHECK_LIBRARY_EXISTS_LIBRARIES
+ ${CHECK_LIBRARY_EXISTS_LIBRARIES} ${_ADJUSTED_CMAKE_REQUIRED_LIBRARIES})
+ ENDIF(CMAKE_REQUIRED_LIBRARIES)
+ TRY_COMPILE(${VARIABLE}
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_ROOT}/Modules/CheckFunctionExists.c
+ COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+ CMAKE_FLAGS
+ -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_LIBRARY_EXISTS_DEFINITION}
+ -DLINK_DIRECTORIES:STRING=${LOCATION}
+ "-DLINK_LIBRARIES:STRING=${CHECK_LIBRARY_EXISTS_LIBRARIES}"
+ OUTPUT_VARIABLE OUTPUT)
+
+ IF(${VARIABLE})
+ MESSAGE(STATUS "Looking for ${FUNCTION} in ${LIBRARY} - found")
+ 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(${VARIABLE})
+ MESSAGE(STATUS "Looking for ${FUNCTION} in ${LIBRARY} - not found")
+ 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} "
+ "failed with the following output:\n"
+ "${OUTPUT}\n\n")
+ ENDIF(${VARIABLE})
+ ENDIF("${VARIABLE}" MATCHES "^${VARIABLE}$")
+ENDMACRO(CHECK_LIBRARY_EXISTS)
diff --git a/Modules/CheckLibraryExists.lists.in b/Modules/CheckLibraryExists.lists.in
new file mode 100644
index 000000000..741b87d72
--- /dev/null
+++ b/Modules/CheckLibraryExists.lists.in
@@ -0,0 +1,8 @@
+PROJECT(CHECK_LIBRARY_EXISTS)
+
+
+ADD_DEFINITIONS(-DCHECK_FUNCTION_EXISTS=${CHECK_LIBRARY_EXISTS_FUNCTION})
+LINK_DIRECTORIES(${CHECK_LIBRARY_EXISTS_LOCATION})
+ADD_EXECUTABLE(CheckLibraryExists ${CHECK_LIBRARY_EXISTS_SOURCE})
+TARGET_LINK_LIBRARIES(CheckLibraryExists ${CHECK_LIBRARY_EXISTS_LIBRARY})
+
diff --git a/Modules/CheckPrototypeDefinition.c.in b/Modules/CheckPrototypeDefinition.c.in
new file mode 100644
index 000000000..a97344ac3
--- /dev/null
+++ b/Modules/CheckPrototypeDefinition.c.in
@@ -0,0 +1,29 @@
+@CHECK_PROTOTYPE_DEFINITION_HEADER@
+
+static void cmakeRequireSymbol(int dummy, ...) {
+ (void) dummy;
+}
+
+static void checkSymbol(void) {
+#ifndef @CHECK_PROTOTYPE_DEFINITION_SYMBOL@
+ cmakeRequireSymbol(0, &@CHECK_PROTOTYPE_DEFINITION_SYMBOL@);
+#endif
+}
+
+@CHECK_PROTOTYPE_DEFINITION_PROTO@ {
+ return @CHECK_PROTOTYPE_DEFINITION_RETURN@;
+}
+
+#ifdef __CLASSIC_C__
+int main() {
+ int ac;
+ char*av[];
+#else
+int main(int ac, char *av[]) {
+#endif
+ checkSymbol();
+ if (ac > 1000) {
+ return *av[0];
+ }
+ return 0;
+}
diff --git a/Modules/CheckPrototypeDefinition.cmake b/Modules/CheckPrototypeDefinition.cmake
new file mode 100644
index 000000000..63d424237
--- /dev/null
+++ b/Modules/CheckPrototypeDefinition.cmake
@@ -0,0 +1,101 @@
+# - 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.
+# 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
+
+#=============================================================================
+# Copyright 2005-2009 Kitware, Inc.
+# Copyright 2010-2011 Andreas Schneider <asn@cryptomilk.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("${CMAKE_CURRENT_LIST_DIR}/CMakeExpandImportedTargets.cmake")
+
+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}$")
+ set(CHECK_PROTOTYPE_DEFINITION_CONTENT "/* */\n")
+
+ set(CHECK_PROTOTYPE_DEFINITION_FLAGS ${CMAKE_REQUIRED_FLAGS})
+ if (CMAKE_REQUIRED_LIBRARIES)
+ # this one translates potentially used imported library targets to their files on disk
+ cmake_expand_imported_targets(_ADJUSTED_CMAKE_REQUIRED_LIBRARIES LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}")
+ set(CHECK_PROTOTYPE_DEFINITION_LIBS
+ "-DLINK_LIBRARIES:STRING=${_ADJUSTED_CMAKE_REQUIRED_LIBRARIES}")
+ else(CMAKE_REQUIRED_LIBRARIES)
+ set(CHECK_PROTOTYPE_DEFINITION_LIBS)
+ endif(CMAKE_REQUIRED_LIBRARIES)
+ if (CMAKE_REQUIRED_INCLUDES)
+ set(CMAKE_SYMBOL_EXISTS_INCLUDES
+ "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
+ else(CMAKE_REQUIRED_INCLUDES)
+ set(CMAKE_SYMBOL_EXISTS_INCLUDES)
+ endif(CMAKE_REQUIRED_INCLUDES)
+
+ foreach(_FILE ${_HEADER})
+ set(CHECK_PROTOTYPE_DEFINITION_HEADER
+ "${CHECK_PROTOTYPE_DEFINITION_HEADER}#include <${_FILE}>\n")
+ endforeach(_FILE)
+
+ set(CHECK_PROTOTYPE_DEFINITION_SYMBOL ${_FUNCTION})
+ set(CHECK_PROTOTYPE_DEFINITION_PROTO ${_PROTOTYPE})
+ set(CHECK_PROTOTYPE_DEFINITION_RETURN ${_RETURN})
+
+ configure_file("${__check_proto_def_dir}/CheckPrototypeDefinition.c.in"
+ "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckPrototypeDefinition.c" @ONLY)
+
+ file(READ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckPrototypeDefinition.c _SOURCE)
+
+ try_compile(${_VARIABLE}
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckPrototypeDefinition.c
+ COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+ CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${CHECK_PROTOTYPE_DEFINITION_FLAGS}
+ "${CHECK_PROTOTYPE_DEFINITION_LIBS}"
+ "${CMAKE_SYMBOL_EXISTS_INCLUDES}"
+ OUTPUT_VARIABLE OUTPUT)
+
+ if (${_VARIABLE})
+ set(${_VARIABLE} 1 CACHE INTERNAL "Have correct prototype for ${_FUNCTION}")
+ message(STATUS "Checking prototype ${_FUNCTION} for ${_VARIABLE} - True")
+ 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 (${_VARIABLE})
+ message(STATUS "Checking prototype ${_FUNCTION} for ${_VARIABLE} - False")
+ 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"
+ "${OUTPUT}\n\n${_SOURCE}\n\n")
+ endif (${_VARIABLE})
+ endif("${_VARIABLE}" MATCHES "^${_VARIABLE}$")
+
+endfunction(CHECK_PROTOTYPE_DEFINITION)
diff --git a/Modules/CheckSizeOf.cmake b/Modules/CheckSizeOf.cmake
new file mode 100644
index 000000000..f6d6636e5
--- /dev/null
+++ b/Modules/CheckSizeOf.cmake
@@ -0,0 +1,18 @@
+
+#=============================================================================
+# 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.)
+
+MESSAGE(SEND_ERROR
+ "Modules/CheckSizeOf.cmake has been removed. "
+ "Use Modules/CheckTypeSize.cmake instead. This "
+ "compatability check may be removed before the next release!")
diff --git a/Modules/CheckStructHasMember.cmake b/Modules/CheckStructHasMember.cmake
new file mode 100644
index 000000000..18e80e3c0
--- /dev/null
+++ b/Modules/CheckStructHasMember.cmake
@@ -0,0 +1,51 @@
+# - Check if the given struct or class has the specified member variable
+# CHECK_STRUCT_HAS_MEMBER (STRUCT MEMBER HEADER VARIABLE)
+#
+# 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
+#
+# 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
+#
+# Example: CHECK_STRUCT_HAS_MEMBER("struct timeval" tv_sec sys/select.h HAVE_TIMEVAL_TV_SEC)
+
+#=============================================================================
+# 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.)
+
+INCLUDE(CheckCSourceCompiles)
+
+MACRO (CHECK_STRUCT_HAS_MEMBER _STRUCT _MEMBER _HEADER _RESULT)
+ SET(_INCLUDE_FILES)
+ FOREACH (it ${_HEADER})
+ SET(_INCLUDE_FILES "${_INCLUDE_FILES}#include <${it}>\n")
+ ENDFOREACH (it)
+
+ SET(_CHECK_STRUCT_MEMBER_SOURCE_CODE "
+${_INCLUDE_FILES}
+int main()
+{
+ ${_STRUCT}* tmp;
+ tmp->${_MEMBER};
+ return 0;
+}
+")
+ CHECK_C_SOURCE_COMPILES("${_CHECK_STRUCT_MEMBER_SOURCE_CODE}" ${_RESULT})
+
+ENDMACRO (CHECK_STRUCT_HAS_MEMBER)
+
diff --git a/Modules/CheckSymbolExists.cmake b/Modules/CheckSymbolExists.cmake
new file mode 100644
index 000000000..e6e677d4f
--- /dev/null
+++ b/Modules/CheckSymbolExists.cmake
@@ -0,0 +1,101 @@
+# - 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.
+#
+# 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++.
+#
+# 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
+
+#=============================================================================
+# Copyright 2003-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.)
+
+INCLUDE("${CMAKE_CURRENT_LIST_DIR}/CMakeExpandImportedTargets.cmake")
+
+
+MACRO(CHECK_SYMBOL_EXISTS SYMBOL FILES VARIABLE)
+ _CHECK_SYMBOL_EXISTS("${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckSymbolExists.c" "${SYMBOL}" "${FILES}" "${VARIABLE}" )
+ENDMACRO(CHECK_SYMBOL_EXISTS)
+
+MACRO(_CHECK_SYMBOL_EXISTS SOURCEFILE SYMBOL FILES VARIABLE)
+ IF("${VARIABLE}" MATCHES "^${VARIABLE}$")
+ SET(CMAKE_CONFIGURABLE_FILE_CONTENT "/* */\n")
+ SET(MACRO_CHECK_SYMBOL_EXISTS_FLAGS ${CMAKE_REQUIRED_FLAGS})
+ IF(CMAKE_REQUIRED_LIBRARIES)
+ # this one translates potentially used imported library targets to their files on disk
+ CMAKE_EXPAND_IMPORTED_TARGETS(_ADJUSTED_CMAKE_REQUIRED_LIBRARIES LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}")
+ SET(CHECK_SYMBOL_EXISTS_LIBS
+ "-DLINK_LIBRARIES:STRING=${_ADJUSTED_CMAKE_REQUIRED_LIBRARIES}")
+ ELSE(CMAKE_REQUIRED_LIBRARIES)
+ SET(CHECK_SYMBOL_EXISTS_LIBS)
+ ENDIF(CMAKE_REQUIRED_LIBRARIES)
+ IF(CMAKE_REQUIRED_INCLUDES)
+ SET(CMAKE_SYMBOL_EXISTS_INCLUDES
+ "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
+ ELSE(CMAKE_REQUIRED_INCLUDES)
+ SET(CMAKE_SYMBOL_EXISTS_INCLUDES)
+ ENDIF(CMAKE_REQUIRED_INCLUDES)
+ FOREACH(FILE ${FILES})
+ SET(CMAKE_CONFIGURABLE_FILE_CONTENT
+ "${CMAKE_CONFIGURABLE_FILE_CONTENT}#include <${FILE}>\n")
+ ENDFOREACH(FILE)
+ SET(CMAKE_CONFIGURABLE_FILE_CONTENT
+ "${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)
+
+ MESSAGE(STATUS "Looking for ${SYMBOL}")
+ TRY_COMPILE(${VARIABLE}
+ ${CMAKE_BINARY_DIR}
+ "${SOURCEFILE}"
+ COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+ CMAKE_FLAGS
+ -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_SYMBOL_EXISTS_FLAGS}
+ "${CHECK_SYMBOL_EXISTS_LIBS}"
+ "${CMAKE_SYMBOL_EXISTS_INCLUDES}"
+ OUTPUT_VARIABLE OUTPUT)
+ IF(${VARIABLE})
+ MESSAGE(STATUS "Looking for ${SYMBOL} - found")
+ SET(${VARIABLE} 1 CACHE INTERNAL "Have symbol ${SYMBOL}")
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "Determining if the ${SYMBOL} "
+ "exist passed with the following output:\n"
+ "${OUTPUT}\nFile ${SOURCEFILE}:\n"
+ "${CMAKE_CONFIGURABLE_FILE_CONTENT}\n")
+ ELSE(${VARIABLE})
+ MESSAGE(STATUS "Looking for ${SYMBOL} - not found.")
+ SET(${VARIABLE} "" CACHE INTERNAL "Have symbol ${SYMBOL}")
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Determining if the ${SYMBOL} "
+ "exist failed with the following output:\n"
+ "${OUTPUT}\nFile ${SOURCEFILE}:\n"
+ "${CMAKE_CONFIGURABLE_FILE_CONTENT}\n")
+ ENDIF(${VARIABLE})
+ ENDIF("${VARIABLE}" MATCHES "^${VARIABLE}$")
+ENDMACRO(_CHECK_SYMBOL_EXISTS)
diff --git a/Modules/CheckTypeSize.c.in b/Modules/CheckTypeSize.c.in
new file mode 100644
index 000000000..b6c368801
--- /dev/null
+++ b/Modules/CheckTypeSize.c.in
@@ -0,0 +1,37 @@
+@headers@
+
+#undef KEY
+#if defined(__i386)
+# define KEY '_','_','i','3','8','6'
+#elif defined(__x86_64)
+# define KEY '_','_','x','8','6','_','6','4'
+#elif defined(__ppc__)
+# define KEY '_','_','p','p','c','_','_'
+#elif defined(__ppc64__)
+# define KEY '_','_','p','p','c','6','4','_','_'
+#endif
+
+#define SIZE (sizeof(@type@))
+char info_size[] = {'I', 'N', 'F', 'O', ':', 's','i','z','e','[',
+ ('0' + ((SIZE / 10000)%10)),
+ ('0' + ((SIZE / 1000)%10)),
+ ('0' + ((SIZE / 100)%10)),
+ ('0' + ((SIZE / 10)%10)),
+ ('0' + (SIZE % 10)),
+ ']',
+#ifdef KEY
+ ' ','k','e','y','[', KEY, ']',
+#endif
+ '\0'};
+
+#ifdef __CLASSIC_C__
+int main(argc, argv) int argc; char *argv[];
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ int require = 0;
+ require += info_size[argc];
+ (void)argv;
+ return require;
+}
diff --git a/Modules/CheckTypeSize.cmake b/Modules/CheckTypeSize.cmake
new file mode 100644
index 000000000..1717718c9
--- /dev/null
+++ b/Modules/CheckTypeSize.cmake
@@ -0,0 +1,196 @@
+# - 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}".
+#
+# 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.
+#
+# 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
+
+#=============================================================================
+# 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.)
+
+include(CheckIncludeFile)
+include("${CMAKE_CURRENT_LIST_DIR}/CMakeExpandImportedTargets.cmake")
+
+cmake_policy(PUSH)
+cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
+
+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}")
+
+ # Include header files.
+ set(headers)
+ if(builtin)
+ if(HAVE_SYS_TYPES_H)
+ set(headers "${headers}#include <sys/types.h>\n")
+ endif()
+ if(HAVE_STDINT_H)
+ set(headers "${headers}#include <stdint.h>\n")
+ endif()
+ if(HAVE_STDDEF_H)
+ set(headers "${headers}#include <stddef.h>\n")
+ endif()
+ endif()
+ foreach(h ${CMAKE_EXTRA_INCLUDE_FILES})
+ set(headers "${headers}#include \"${h}\"\n")
+ endforeach()
+
+ # Perform the check.
+
+ # this one translates potentially used imported library targets to their files on disk
+ cmake_expand_imported_targets(_ADJUSTED_CMAKE_REQUIRED_LIBRARIES LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}")
+
+ set(src ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckTypeSize/${var}.c)
+ 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}
+ COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+ CMAKE_FLAGS
+ "-DCOMPILE_DEFINITIONS:STRING=${CMAKE_REQUIRED_FLAGS}"
+ "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}"
+ "-DLINK_LIBRARIES:STRING=${_ADJUSTED_CMAKE_REQUIRED_LIBRARIES}"
+ OUTPUT_VARIABLE output
+ COPY_FILE ${bin}
+ )
+
+ if(HAVE_${var})
+ # The check compiled. Load information from the binary.
+ file(STRINGS ${bin} strings LIMIT_COUNT 10 REGEX "INFO:size")
+
+ # Parse the information strings.
+ set(regex_size ".*INFO:size\\[0*([^]]*)\\].*")
+ set(regex_key " key\\[([^]]*)\\]")
+ set(keys)
+ set(code)
+ set(mismatch)
+ set(first 1)
+ foreach(info ${strings})
+ if("${info}" MATCHES "${regex_size}")
+ # Get the type size.
+ string(REGEX REPLACE "${regex_size}" "\\1" size "${info}")
+ if(first)
+ set(${var} ${size})
+ elseif(NOT "${size}" STREQUAL "${${var}}")
+ set(mismatch 1)
+ endif()
+ set(first 0)
+
+ # Get the architecture map key.
+ string(REGEX MATCH "${regex_key}" key "${info}")
+ string(REGEX REPLACE "${regex_key}" "\\1" key "${key}")
+ if(key)
+ set(code "${code}\nset(${var}-${key} \"${size}\")")
+ list(APPEND keys ${key})
+ endif()
+ endif()
+ endforeach()
+
+ # Update the architecture-to-size map.
+ if(mismatch AND keys)
+ configure_file(${__check_type_size_dir}/CheckTypeSizeMap.cmake.in ${map} @ONLY)
+ set(${var} 0)
+ else()
+ file(REMOVE ${map})
+ endif()
+
+ if(mismatch AND NOT keys)
+ 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")
+ 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(HAVE_${var})
+ # The check failed to compile.
+ message(STATUS "Check size of ${type} - failed")
+ 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")
+ set(${var} "" CACHE INTERNAL "CHECK_TYPE_SIZE: ${type} unknown")
+ file(REMOVE ${map})
+ endif(HAVE_${var})
+endfunction()
+
+#-----------------------------------------------------------------------------
+macro(CHECK_TYPE_SIZE TYPE VARIABLE)
+ # Optionally check for standard headers.
+ if("${ARGV2}" STREQUAL "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)
+ endif()
+
+ # 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})
+ endif()
+ include(${_map_file} OPTIONAL)
+ set(_map_file)
+ set(_builtin)
+
+ # Create preprocessor code.
+ if(${VARIABLE}_KEYS)
+ set(${VARIABLE}_CODE)
+ set(_if if)
+ foreach(key ${${VARIABLE}_KEYS})
+ set(${VARIABLE}_CODE "${${VARIABLE}_CODE}#${_if} defined(${key})\n# define ${VARIABLE} ${${VARIABLE}-${key}}\n")
+ set(_if elif)
+ endforeach()
+ set(${VARIABLE}_CODE "${${VARIABLE}_CODE}#else\n# error ${VARIABLE} unknown\n#endif")
+ set(_if)
+ elseif(${VARIABLE})
+ set(${VARIABLE}_CODE "#define ${VARIABLE} ${${VARIABLE}}")
+ else()
+ set(${VARIABLE}_CODE "/* #undef ${VARIABLE} */")
+ endif()
+endmacro()
+
+#-----------------------------------------------------------------------------
+cmake_policy(POP)
diff --git a/Modules/CheckTypeSizeMap.cmake.in b/Modules/CheckTypeSizeMap.cmake.in
new file mode 100644
index 000000000..1e73cfff1
--- /dev/null
+++ b/Modules/CheckTypeSizeMap.cmake.in
@@ -0,0 +1 @@
+set(@var@_KEYS "@keys@")@code@
diff --git a/Modules/CheckVariableExists.c b/Modules/CheckVariableExists.c
new file mode 100644
index 000000000..752f6e486
--- /dev/null
+++ b/Modules/CheckVariableExists.c
@@ -0,0 +1,20 @@
+#ifdef CHECK_VARIABLE_EXISTS
+
+extern int CHECK_VARIABLE_EXISTS;
+
+#ifdef __CLASSIC_C__
+int main(){
+ int ac;
+ char*av[];
+#else
+int main(int ac, char*av[]){
+#endif
+ if(ac > 1000){return *av[0];}
+ return CHECK_VARIABLE_EXISTS;
+}
+
+#else /* CHECK_VARIABLE_EXISTS */
+
+# error "CHECK_VARIABLE_EXISTS has to specify the variable"
+
+#endif /* CHECK_VARIABLE_EXISTS */
diff --git a/Modules/CheckVariableExists.cmake b/Modules/CheckVariableExists.cmake
new file mode 100644
index 000000000..7d6c7945d
--- /dev/null
+++ b/Modules/CheckVariableExists.cmake
@@ -0,0 +1,66 @@
+# - Check if the variable exists.
+# CHECK_VARIABLE_EXISTS(VAR 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:
+#
+# 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
+
+#=============================================================================
+# 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.)
+
+INCLUDE("${CMAKE_CURRENT_LIST_DIR}/CMakeExpandImportedTargets.cmake")
+
+
+MACRO(CHECK_VARIABLE_EXISTS VAR VARIABLE)
+ IF("${VARIABLE}" MATCHES "^${VARIABLE}$")
+ SET(MACRO_CHECK_VARIABLE_DEFINITIONS
+ "-DCHECK_VARIABLE_EXISTS=${VAR} ${CMAKE_REQUIRED_FLAGS}")
+ MESSAGE(STATUS "Looking for ${VAR}")
+ IF(CMAKE_REQUIRED_LIBRARIES)
+ # this one translates potentially used imported library targets to their files on disk
+ CMAKE_EXPAND_IMPORTED_TARGETS(_ADJUSTED_CMAKE_REQUIRED_LIBRARIES LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}")
+ SET(CHECK_VARIABLE_EXISTS_ADD_LIBRARIES
+ "-DLINK_LIBRARIES:STRING=${_ADJUSTED_CMAKE_REQUIRED_LIBRARIES}")
+ ELSE(CMAKE_REQUIRED_LIBRARIES)
+ SET(CHECK_VARIABLE_EXISTS_ADD_LIBRARIES)
+ ENDIF(CMAKE_REQUIRED_LIBRARIES)
+ TRY_COMPILE(${VARIABLE}
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_ROOT}/Modules/CheckVariableExists.c
+ COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+ CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_VARIABLE_DEFINITIONS}
+ "${CHECK_VARIABLE_EXISTS_ADD_LIBRARIES}"
+ OUTPUT_VARIABLE OUTPUT)
+ IF(${VARIABLE})
+ SET(${VARIABLE} 1 CACHE INTERNAL "Have variable ${VAR}")
+ MESSAGE(STATUS "Looking for ${VAR} - found")
+ 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(${VARIABLE})
+ SET(${VARIABLE} "" CACHE INTERNAL "Have variable ${VAR}")
+ MESSAGE(STATUS "Looking for ${VAR} - not found")
+ 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")
+ ENDIF(${VARIABLE})
+ ENDIF("${VARIABLE}" MATCHES "^${VARIABLE}$")
+ENDMACRO(CHECK_VARIABLE_EXISTS)
diff --git a/Modules/Compiler/Absoft-Fortran.cmake b/Modules/Compiler/Absoft-Fortran.cmake
new file mode 100644
index 000000000..1bb7b1f82
--- /dev/null
+++ b/Modules/Compiler/Absoft-Fortran.cmake
@@ -0,0 +1,10 @@
+SET(CMAKE_Fortran_FLAGS_INIT "")
+SET(CMAKE_Fortran_FLAGS_DEBUG_INIT "-g")
+SET(CMAKE_Fortran_FLAGS_MINSIZEREL_INIT "")
+SET(CMAKE_Fortran_FLAGS_RELEASE_INIT "-O3")
+SET(CMAKE_Fortran_FLAGS_RELWITHDEBINFO_INIT "-O2 -g")
+SET(CMAKE_Fortran_MODDIR_FLAG "-YMOD_OUT_DIR=")
+SET(CMAKE_Fortran_MODPATH_FLAG "-p")
+SET(CMAKE_Fortran_VERBOSE_FLAG "-v")
+set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-ffixed")
+set(CMAKE_Fortran_FORMAT_FREE_FLAG "-ffree")
diff --git a/Modules/Compiler/Clang-C.cmake b/Modules/Compiler/Clang-C.cmake
new file mode 100644
index 000000000..f7baf686a
--- /dev/null
+++ b/Modules/Compiler/Clang-C.cmake
@@ -0,0 +1 @@
+include(Compiler/GNU-C)
diff --git a/Modules/Compiler/Clang-CXX.cmake b/Modules/Compiler/Clang-CXX.cmake
new file mode 100644
index 000000000..d3c403a69
--- /dev/null
+++ b/Modules/Compiler/Clang-CXX.cmake
@@ -0,0 +1 @@
+include(Compiler/GNU-CXX)
diff --git a/Modules/Compiler/Cray-C.cmake b/Modules/Compiler/Cray-C.cmake
new file mode 100644
index 000000000..675560c2a
--- /dev/null
+++ b/Modules/Compiler/Cray-C.cmake
@@ -0,0 +1 @@
+set(CMAKE_C_VERBOSE_FLAG "-v")
diff --git a/Modules/Compiler/Cray-CXX.cmake b/Modules/Compiler/Cray-CXX.cmake
new file mode 100644
index 000000000..9fb191c75
--- /dev/null
+++ b/Modules/Compiler/Cray-CXX.cmake
@@ -0,0 +1 @@
+set(CMAKE_CXX_VERBOSE_FLAG "-v")
diff --git a/Modules/Compiler/Cray-Fortran.cmake b/Modules/Compiler/Cray-Fortran.cmake
new file mode 100644
index 000000000..5d81bb02c
--- /dev/null
+++ b/Modules/Compiler/Cray-Fortran.cmake
@@ -0,0 +1,6 @@
+set(CMAKE_Fortran_VERBOSE_FLAG "-v")
+set(CMAKE_Fortran_MODOUT_FLAG -em)
+set(CMAKE_Fortran_MODDIR_FLAG -J)
+set(CMAKE_Fortran_MODDIR_DEFAULT .)
+set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-f fixed")
+set(CMAKE_Fortran_FORMAT_FREE_FLAG "-f free")
diff --git a/Modules/Compiler/G95-Fortran.cmake b/Modules/Compiler/G95-Fortran.cmake
new file mode 100644
index 000000000..fd84848b4
--- /dev/null
+++ b/Modules/Compiler/G95-Fortran.cmake
@@ -0,0 +1,9 @@
+set(CMAKE_Fortran_FLAGS_INIT "")
+set(CMAKE_Fortran_FLAGS_DEBUG_INIT "-g")
+set(CMAKE_Fortran_FLAGS_MINSIZEREL_INIT "-Os")
+set(CMAKE_Fortran_FLAGS_RELEASE_INIT "-O3")
+set(CMAKE_Fortran_FLAGS_RELWITHDEBINFO_INIT "-O2 -g")
+set(CMAKE_Fortran_MODDIR_FLAG "-fmod=")
+set(CMAKE_Fortran_VERBOSE_FLAG "-v")
+set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-ffixed-form")
+set(CMAKE_Fortran_FORMAT_FREE_FLAG "-ffree-form")
diff --git a/Modules/Compiler/GNU-ASM.cmake b/Modules/Compiler/GNU-ASM.cmake
new file mode 100644
index 000000000..e07401d54
--- /dev/null
+++ b/Modules/Compiler/GNU-ASM.cmake
@@ -0,0 +1,6 @@
+# This file is loaded when gcc/g++ is used for assembler files (the "ASM" cmake language)
+include(Compiler/GNU)
+
+set(CMAKE_ASM_SOURCE_FILE_EXTENSIONS s;S;asm)
+
+__compiler_gnu(ASM)
diff --git a/Modules/Compiler/GNU-C.cmake b/Modules/Compiler/GNU-C.cmake
new file mode 100644
index 000000000..9a5137a4b
--- /dev/null
+++ b/Modules/Compiler/GNU-C.cmake
@@ -0,0 +1,2 @@
+include(Compiler/GNU)
+__compiler_gnu(C)
diff --git a/Modules/Compiler/GNU-CXX.cmake b/Modules/Compiler/GNU-CXX.cmake
new file mode 100644
index 000000000..879ab8f80
--- /dev/null
+++ b/Modules/Compiler/GNU-CXX.cmake
@@ -0,0 +1,2 @@
+include(Compiler/GNU)
+__compiler_gnu(CXX)
diff --git a/Modules/Compiler/GNU-Fortran.cmake b/Modules/Compiler/GNU-Fortran.cmake
new file mode 100644
index 000000000..c710e8698
--- /dev/null
+++ b/Modules/Compiler/GNU-Fortran.cmake
@@ -0,0 +1,17 @@
+include(Compiler/GNU)
+__compiler_gnu(Fortran)
+
+set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-ffixed-form")
+set(CMAKE_Fortran_FORMAT_FREE_FLAG "-ffree-form")
+
+# No -DNDEBUG for Fortran.
+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)
+
+# Fortran-specific feature flags.
+SET(CMAKE_Fortran_MODDIR_FLAG -J)
diff --git a/Modules/Compiler/GNU.cmake b/Modules/Compiler/GNU.cmake
new file mode 100644
index 000000000..6aecf90e8
--- /dev/null
+++ b/Modules/Compiler/GNU.cmake
@@ -0,0 +1,54 @@
+
+#=============================================================================
+# 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 module is shared by multiple languages; use include blocker.
+if(__COMPILER_GNU)
+ return()
+endif()
+set(__COMPILER_GNU 1)
+
+macro(__compiler_gnu lang)
+ # Feature flags.
+ set(CMAKE_${lang}_VERBOSE_FLAG "-v")
+ set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "-fPIC")
+ if(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 3.4)
+ set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-fPIE")
+ endif()
+ set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "-fPIC")
+ set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-shared")
+
+ # 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
+ # tests to always succeed. Work around this by disabling dependency tracking
+ # in try_compile mode.
+ GET_PROPERTY(_IN_TC GLOBAL PROPERTY IN_TRY_COMPILE)
+ if(NOT _IN_TC OR CMAKE_FORCE_DEPFILES)
+ # distcc does not transform -o to -MT when invoking the preprocessor
+ # internally, as it ought to. Work around this bug by setting -MT here
+ # even though it isn't strictly necessary.
+ set(CMAKE_DEPFILE_FLAGS_${lang} "-MMD -MT <OBJECT> -MF <DEPFILE>")
+ endif()
+
+ # Initial configuration flags.
+ set(CMAKE_${lang}_FLAGS_INIT "")
+ set(CMAKE_${lang}_FLAGS_DEBUG_INIT "-g")
+ set(CMAKE_${lang}_FLAGS_MINSIZEREL_INIT "-Os -DNDEBUG")
+ set(CMAKE_${lang}_FLAGS_RELEASE_INIT "-O3 -DNDEBUG")
+ set(CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT "-O2 -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>")
+ if(NOT APPLE)
+ set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-isystem ")
+ endif(NOT APPLE)
+endmacro()
diff --git a/Modules/Compiler/HP-ASM.cmake b/Modules/Compiler/HP-ASM.cmake
new file mode 100644
index 000000000..8aa7bdb7d
--- /dev/null
+++ b/Modules/Compiler/HP-ASM.cmake
@@ -0,0 +1,3 @@
+SET(CMAKE_ASM_VERBOSE_FLAG "-v")
+
+set(CMAKE_ASM_SOURCE_FILE_EXTENSIONS s )
diff --git a/Modules/Compiler/HP-C.cmake b/Modules/Compiler/HP-C.cmake
new file mode 100644
index 000000000..dc7fbb21d
--- /dev/null
+++ b/Modules/Compiler/HP-C.cmake
@@ -0,0 +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>")
diff --git a/Modules/Compiler/HP-CXX.cmake b/Modules/Compiler/HP-CXX.cmake
new file mode 100644
index 000000000..82c1a861e
--- /dev/null
+++ b/Modules/Compiler/HP-CXX.cmake
@@ -0,0 +1,4 @@
+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>")
diff --git a/Modules/Compiler/HP-Fortran.cmake b/Modules/Compiler/HP-Fortran.cmake
new file mode 100644
index 000000000..04fb96ea4
--- /dev/null
+++ b/Modules/Compiler/HP-Fortran.cmake
@@ -0,0 +1,3 @@
+SET(CMAKE_Fortran_VERBOSE_FLAG "-v")
+set(CMAKE_Fortran_FORMAT_FIXED_FLAG "+source=fixed")
+set(CMAKE_Fortran_FORMAT_FREE_FLAG "+source=free")
diff --git a/Modules/Compiler/Intel-ASM.cmake b/Modules/Compiler/Intel-ASM.cmake
new file mode 100644
index 000000000..59b50a15c
--- /dev/null
+++ b/Modules/Compiler/Intel-ASM.cmake
@@ -0,0 +1,13 @@
+SET(CMAKE_ASM_VERBOSE_FLAG "-v")
+
+SET(CMAKE_ASM_FLAGS_INIT "")
+SET(CMAKE_ASM_FLAGS_DEBUG_INIT "-g")
+SET(CMAKE_ASM_FLAGS_MINSIZEREL_INIT "-Os -DNDEBUG")
+SET(CMAKE_ASM_FLAGS_RELEASE_INIT "-O3 -DNDEBUG")
+SET(CMAKE_ASM_FLAGS_RELWITHDEBINFO_INIT "-O2 -g")
+
+IF(UNIX)
+ SET(CMAKE_ASM_SOURCE_FILE_EXTENSIONS s;S)
+ELSE(UNIX)
+ SET(CMAKE_ASM_SOURCE_FILE_EXTENSIONS asm)
+ENDIF(UNIX)
diff --git a/Modules/Compiler/Intel-C.cmake b/Modules/Compiler/Intel-C.cmake
new file mode 100644
index 000000000..4be91d084
--- /dev/null
+++ b/Modules/Compiler/Intel-C.cmake
@@ -0,0 +1,10 @@
+SET(CMAKE_C_VERBOSE_FLAG "-v")
+
+SET(CMAKE_C_FLAGS_INIT "")
+SET(CMAKE_C_FLAGS_DEBUG_INIT "-g")
+SET(CMAKE_C_FLAGS_MINSIZEREL_INIT "-Os -DNDEBUG")
+SET(CMAKE_C_FLAGS_RELEASE_INIT "-O3 -DNDEBUG")
+SET(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "-O2 -g")
+
+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>")
diff --git a/Modules/Compiler/Intel-CXX.cmake b/Modules/Compiler/Intel-CXX.cmake
new file mode 100644
index 000000000..ff01a81f6
--- /dev/null
+++ b/Modules/Compiler/Intel-CXX.cmake
@@ -0,0 +1,10 @@
+SET(CMAKE_CXX_VERBOSE_FLAG "-v")
+
+SET(CMAKE_CXX_FLAGS_INIT "")
+SET(CMAKE_CXX_FLAGS_DEBUG_INIT "-g")
+SET(CMAKE_CXX_FLAGS_MINSIZEREL_INIT "-Os -DNDEBUG")
+SET(CMAKE_CXX_FLAGS_RELEASE_INIT "-O3 -DNDEBUG")
+SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "-O2 -g")
+
+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>")
diff --git a/Modules/Compiler/Intel-Fortran.cmake b/Modules/Compiler/Intel-Fortran.cmake
new file mode 100644
index 000000000..467abdcf5
--- /dev/null
+++ b/Modules/Compiler/Intel-Fortran.cmake
@@ -0,0 +1,9 @@
+SET(CMAKE_Fortran_FLAGS_INIT "")
+SET(CMAKE_Fortran_FLAGS_DEBUG_INIT "-g")
+SET(CMAKE_Fortran_FLAGS_MINSIZEREL_INIT "-Os")
+SET(CMAKE_Fortran_FLAGS_RELEASE_INIT "-O3")
+SET(CMAKE_Fortran_FLAGS_RELWITHDEBINFO_INIT "-O2 -g")
+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")
diff --git a/Modules/Compiler/MIPSpro-C.cmake b/Modules/Compiler/MIPSpro-C.cmake
new file mode 100644
index 000000000..abf384ab8
--- /dev/null
+++ b/Modules/Compiler/MIPSpro-C.cmake
@@ -0,0 +1 @@
+SET(CMAKE_C_VERBOSE_FLAG "-v")
diff --git a/Modules/Compiler/MIPSpro-CXX.cmake b/Modules/Compiler/MIPSpro-CXX.cmake
new file mode 100644
index 000000000..f3c6b5f82
--- /dev/null
+++ b/Modules/Compiler/MIPSpro-CXX.cmake
@@ -0,0 +1 @@
+SET(CMAKE_CXX_VERBOSE_FLAG "-v")
diff --git a/Modules/Compiler/MIPSpro-Fortran.cmake b/Modules/Compiler/MIPSpro-Fortran.cmake
new file mode 100644
index 000000000..9220d3bf0
--- /dev/null
+++ b/Modules/Compiler/MIPSpro-Fortran.cmake
@@ -0,0 +1,3 @@
+SET(CMAKE_Fortran_VERBOSE_FLAG "-v")
+set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-fixedform")
+set(CMAKE_Fortran_FORMAT_FREE_FLAG "-freeform")
diff --git a/Modules/Compiler/NAG-Fortran.cmake b/Modules/Compiler/NAG-Fortran.cmake
new file mode 100644
index 000000000..9a89746b5
--- /dev/null
+++ b/Modules/Compiler/NAG-Fortran.cmake
@@ -0,0 +1,34 @@
+# Help CMAKE_PARSE_IMPLICIT_LINK_INFO detect NAG Fortran object files.
+if(NOT CMAKE_Fortran_COMPILER_WORKS AND NOT CMAKE_Fortran_COMPILER_FORCED)
+ message(STATUS "Detecting NAG Fortran directory")
+ # Run with -dryrun to see sample "link" line.
+ execute_process(
+ COMMAND ${CMAKE_Fortran_COMPILER} dummy.o -dryrun
+ OUTPUT_VARIABLE _dryrun
+ ERROR_VARIABLE _dryrun
+ )
+ # Match an object file.
+ string(REGEX MATCH "/[^ ]*/[^ /][^ /]*\\.o" _nag_obj "${_dryrun}")
+ if(_nag_obj)
+ # Parse object directory and convert to a regex.
+ string(REGEX REPLACE "/[^/]*$" "" _nag_dir "${_nag_obj}")
+ string(REGEX REPLACE "([][+.*()^])" "\\\\\\1" _nag_regex "${_nag_dir}")
+ set(CMAKE_Fortran_IMPLICIT_OBJECT_REGEX "^${_nag_regex}/")
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "Detecting NAG Fortran directory with -dryrun found\n"
+ " object: ${_nag_obj}\n"
+ " directory: ${_nag_dir}\n"
+ " regex: ${CMAKE_Fortran_IMPLICIT_OBJECT_REGEX}\n"
+ "from output:\n${_dryrun}\n\n")
+ message(STATUS "Detecting NAG Fortran directory - ${_nag_dir}")
+ else()
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Detecting NAG Fortran directory with -dryrun failed:\n${_dryrun}\n\n")
+ message(STATUS "Detecting NAG Fortran directory - failed")
+ endif()
+endif()
+
+set(CMAKE_Fortran_MODDIR_FLAG "-mdir ")
+set(CMAKE_SHARED_LIBRARY_Fortran_FLAGS "-PIC")
+set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-fixed")
+set(CMAKE_Fortran_FORMAT_FREE_FLAG "-free")
diff --git a/Modules/Compiler/PGI-C.cmake b/Modules/Compiler/PGI-C.cmake
new file mode 100644
index 000000000..da88c0116
--- /dev/null
+++ b/Modules/Compiler/PGI-C.cmake
@@ -0,0 +1,4 @@
+include(Compiler/PGI)
+__compiler_pgi(C)
+set(CMAKE_C_FLAGS_MINSIZEREL_INIT "${CMAKE_C_FLAGS_MINSIZEREL_INIT} -DNDEBUG")
+set(CMAKE_C_FLAGS_RELEASE_INIT "${CMAKE_C_FLAGS_RELEASE_INIT} -DNDEBUG")
diff --git a/Modules/Compiler/PGI-CXX.cmake b/Modules/Compiler/PGI-CXX.cmake
new file mode 100644
index 000000000..97c9555b1
--- /dev/null
+++ b/Modules/Compiler/PGI-CXX.cmake
@@ -0,0 +1,4 @@
+include(Compiler/PGI)
+__compiler_pgi(CXX)
+set(CMAKE_CXX_FLAGS_MINSIZEREL_INIT "${CMAKE_CXX_FLAGS_MINSIZEREL_INIT} -DNDEBUG")
+set(CMAKE_CXX_FLAGS_RELEASE_INIT "${CMAKE_CXX_FLAGS_RELEASE_INIT} -DNDEBUG")
diff --git a/Modules/Compiler/PGI-Fortran.cmake b/Modules/Compiler/PGI-Fortran.cmake
new file mode 100644
index 000000000..aebc7b1c2
--- /dev/null
+++ b/Modules/Compiler/PGI-Fortran.cmake
@@ -0,0 +1,15 @@
+include(Compiler/PGI)
+__compiler_pgi(Fortran)
+
+set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-Mnofreeform")
+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
new file mode 100644
index 000000000..162e3c9b8
--- /dev/null
+++ b/Modules/Compiler/PGI.cmake
@@ -0,0 +1,35 @@
+
+#=============================================================================
+# 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 module is shared by multiple languages; use include blocker.
+if(__COMPILER_PGI)
+ return()
+endif()
+set(__COMPILER_PGI 1)
+
+macro(__compiler_pgi lang)
+ # Feature flags.
+ set(CMAKE_${lang}_VERBOSE_FLAG "-v")
+
+ # Initial configuration flags.
+ set(CMAKE_${lang}_FLAGS_INIT "")
+ set(CMAKE_${lang}_FLAGS_DEBUG_INIT "-g -O0")
+ set(CMAKE_${lang}_FLAGS_MINSIZEREL_INIT "-O2 -s")
+ set(CMAKE_${lang}_FLAGS_RELEASE_INIT "-fast -O3 -Mipa=fast")
+ 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>")
+endmacro()
diff --git a/Modules/Compiler/PathScale-C.cmake b/Modules/Compiler/PathScale-C.cmake
new file mode 100644
index 000000000..9db54afa0
--- /dev/null
+++ b/Modules/Compiler/PathScale-C.cmake
@@ -0,0 +1,4 @@
+include(Compiler/PathScale)
+__compiler_pathscale(C)
+set(CMAKE_C_FLAGS_MINSIZEREL_INIT "${CMAKE_C_FLAGS_MINSIZEREL_INIT} -DNDEBUG")
+set(CMAKE_C_FLAGS_RELEASE_INIT "${CMAKE_C_FLAGS_RELEASE_INIT} -DNDEBUG")
diff --git a/Modules/Compiler/PathScale-CXX.cmake b/Modules/Compiler/PathScale-CXX.cmake
new file mode 100644
index 000000000..4dd766048
--- /dev/null
+++ b/Modules/Compiler/PathScale-CXX.cmake
@@ -0,0 +1,4 @@
+include(Compiler/PathScale)
+__compiler_pathscale(CXX)
+set(CMAKE_CXX_FLAGS_MINSIZEREL_INIT "${CMAKE_CXX_FLAGS_MINSIZEREL_INIT} -DNDEBUG")
+set(CMAKE_CXX_FLAGS_RELEASE_INIT "${CMAKE_CXX_FLAGS_RELEASE_INIT} -DNDEBUG")
diff --git a/Modules/Compiler/PathScale-Fortran.cmake b/Modules/Compiler/PathScale-Fortran.cmake
new file mode 100644
index 000000000..e05bf2afc
--- /dev/null
+++ b/Modules/Compiler/PathScale-Fortran.cmake
@@ -0,0 +1,6 @@
+include(Compiler/PathScale)
+__compiler_pathscale(Fortran)
+
+SET(CMAKE_Fortran_MODDIR_FLAG "-module ")
+set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-fixedform")
+set(CMAKE_Fortran_FORMAT_FREE_FLAG "-freeform")
diff --git a/Modules/Compiler/PathScale.cmake b/Modules/Compiler/PathScale.cmake
new file mode 100644
index 000000000..107f779a9
--- /dev/null
+++ b/Modules/Compiler/PathScale.cmake
@@ -0,0 +1,31 @@
+
+#=============================================================================
+# Copyright 2002-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.)
+
+# This module is shared by multiple languages; use include blocker.
+if(__COMPILER_PATHSCALE)
+ return()
+endif()
+set(__COMPILER_PATHSCALE 1)
+
+macro(__compiler_pathscale lang)
+ # Feature flags.
+ set(CMAKE_${lang}_VERBOSE_FLAG "-v")
+
+ # Initial configuration flags.
+ set(CMAKE_${lang}_FLAGS_INIT "")
+ set(CMAKE_${lang}_FLAGS_DEBUG_INIT "-g -O0")
+ set(CMAKE_${lang}_FLAGS_MINSIZEREL_INIT "-Os")
+ set(CMAKE_${lang}_FLAGS_RELEASE_INIT "-O3")
+ set(CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT "-g -O2")
+endmacro()
diff --git a/Modules/Compiler/SCO-C.cmake b/Modules/Compiler/SCO-C.cmake
new file mode 100644
index 000000000..6e762ccae
--- /dev/null
+++ b/Modules/Compiler/SCO-C.cmake
@@ -0,0 +1,2 @@
+include(Compiler/SCO)
+__compiler_sco(C)
diff --git a/Modules/Compiler/SCO-CXX.cmake b/Modules/Compiler/SCO-CXX.cmake
new file mode 100644
index 000000000..5b713a0df
--- /dev/null
+++ b/Modules/Compiler/SCO-CXX.cmake
@@ -0,0 +1,2 @@
+include(Compiler/SCO)
+__compiler_sco(CXX)
diff --git a/Modules/Compiler/SCO.cmake b/Modules/Compiler/SCO.cmake
new file mode 100644
index 000000000..f673c8f80
--- /dev/null
+++ b/Modules/Compiler/SCO.cmake
@@ -0,0 +1,28 @@
+
+#=============================================================================
+# Copyright 2002-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.)
+
+# This module is shared by multiple languages; use include blocker.
+if(__COMPILER_SCO)
+ return()
+endif()
+set(__COMPILER_SCO 1)
+
+macro(__compiler_sco lang)
+ # Feature flags.
+ set(CMAKE_${lang}_COMPILE_OPTIONS_PIC -Kpic)
+ set(CMAKE_${lang}_COMPILE_OPTIONS_PIE -Kpie)
+ set(CMAKE_${lang}_COMPILE_OPTIONS_DLL -belf)
+ set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "-Kpic -belf")
+ set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-belf -Wl,-Bexport")
+endmacro()
diff --git a/Modules/Compiler/SunPro-ASM.cmake b/Modules/Compiler/SunPro-ASM.cmake
new file mode 100644
index 000000000..dfc5702ee
--- /dev/null
+++ b/Modules/Compiler/SunPro-ASM.cmake
@@ -0,0 +1,24 @@
+set(CMAKE_ASM_SOURCE_FILE_EXTENSIONS s )
+
+SET(CMAKE_ASM_VERBOSE_FLAG "-#")
+
+SET(CMAKE_SHARED_LIBRARY_ASM_FLAGS "-KPIC")
+SET(CMAKE_SHARED_LIBRARY_CREATE_ASM_FLAGS "-G")
+SET(CMAKE_SHARED_LIBRARY_RUNTIME_ASM_FLAG "-R")
+SET(CMAKE_SHARED_LIBRARY_RUNTIME_ASM_FLAG_SEP ":")
+SET(CMAKE_SHARED_LIBRARY_SONAME_ASM_FLAG "-h")
+
+SET(CMAKE_ASM_FLAGS_INIT "")
+SET(CMAKE_ASM_FLAGS_DEBUG_INIT "-g")
+SET(CMAKE_ASM_FLAGS_MINSIZEREL_INIT "-xO2 -xspace -DNDEBUG")
+SET(CMAKE_ASM_FLAGS_RELEASE_INIT "-xO3 -DNDEBUG")
+SET(CMAKE_ASM_FLAGS_RELWITHDEBINFO_INIT "-g -xO2")
+
+# Initialize ASM 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.
+FOREACH(type SHARED_LIBRARY SHARED_MODULE EXE)
+ SET(CMAKE_${type}_LINK_STATIC_ASM_FLAGS "-Bstatic")
+ SET(CMAKE_${type}_LINK_DYNAMIC_ASM_FLAGS "-Bdynamic")
+ENDFOREACH(type)
diff --git a/Modules/Compiler/SunPro-C.cmake b/Modules/Compiler/SunPro-C.cmake
new file mode 100644
index 000000000..a1a3ae118
--- /dev/null
+++ b/Modules/Compiler/SunPro-C.cmake
@@ -0,0 +1,27 @@
+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")
+SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP ":")
+SET(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "-h")
+
+SET(CMAKE_C_FLAGS_INIT "")
+SET(CMAKE_C_FLAGS_DEBUG_INIT "-g")
+SET(CMAKE_C_FLAGS_MINSIZEREL_INIT "-xO2 -xspace -DNDEBUG")
+SET(CMAKE_C_FLAGS_RELEASE_INIT "-xO3 -DNDEBUG")
+SET(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "-g -xO2")
+
+# 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
+# versions of the libraries.
+FOREACH(type SHARED_LIBRARY SHARED_MODULE EXE)
+ SET(CMAKE_${type}_LINK_STATIC_C_FLAGS "-Bstatic")
+ SET(CMAKE_${type}_LINK_DYNAMIC_C_FLAGS "-Bdynamic")
+ENDFOREACH(type)
+
+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>")
diff --git a/Modules/Compiler/SunPro-CXX.cmake b/Modules/Compiler/SunPro-CXX.cmake
new file mode 100644
index 000000000..702e42458
--- /dev/null
+++ b/Modules/Compiler/SunPro-CXX.cmake
@@ -0,0 +1,33 @@
+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")
+SET(CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG_SEP ":")
+SET(CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG "-h")
+
+SET(CMAKE_CXX_FLAGS_INIT "")
+SET(CMAKE_CXX_FLAGS_DEBUG_INIT "-g")
+SET(CMAKE_CXX_FLAGS_MINSIZEREL_INIT "-xO2 -xspace -DNDEBUG")
+SET(CMAKE_CXX_FLAGS_RELEASE_INIT "-xO3 -DNDEBUG")
+SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "-g -xO2")
+
+# 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
+# versions of the libraries.
+FOREACH(type SHARED_LIBRARY SHARED_MODULE EXE)
+ SET(CMAKE_${type}_LINK_STATIC_CXX_FLAGS "-Bstatic")
+ SET(CMAKE_${type}_LINK_DYNAMIC_CXX_FLAGS "-Bdynamic")
+ENDFOREACH(type)
+
+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>")
+
+# 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> ")
diff --git a/Modules/Compiler/SunPro-Fortran.cmake b/Modules/Compiler/SunPro-Fortran.cmake
new file mode 100644
index 000000000..86d6def34
--- /dev/null
+++ b/Modules/Compiler/SunPro-Fortran.cmake
@@ -0,0 +1,18 @@
+SET(CMAKE_Fortran_VERBOSE_FLAG "-v")
+set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-fixed")
+set(CMAKE_Fortran_FORMAT_FREE_FLAG "-free")
+
+SET(CMAKE_SHARED_LIBRARY_Fortran_FLAGS "-KPIC")
+SET(CMAKE_SHARED_LIBRARY_CREATE_Fortran_FLAGS "-G")
+SET(CMAKE_SHARED_LIBRARY_RUNTIME_Fortran_FLAG "-R")
+SET(CMAKE_SHARED_LIBRARY_RUNTIME_Fortran_FLAG_SEP ":")
+SET(CMAKE_SHARED_LIBRARY_SONAME_Fortran_FLAG "-h")
+set(CMAKE_EXECUTABLE_RUNTIME_Fortran_FLAG "-R")
+
+SET(CMAKE_Fortran_FLAGS_INIT "")
+SET(CMAKE_Fortran_FLAGS_DEBUG_INIT "-g")
+SET(CMAKE_Fortran_FLAGS_MINSIZEREL_INIT "-xO2 -xspace -DNDEBUG")
+SET(CMAKE_Fortran_FLAGS_RELEASE_INIT "-xO3 -DNDEBUG")
+SET(CMAKE_Fortran_FLAGS_RELWITHDEBINFO_INIT "-g -xO2")
+SET(CMAKE_Fortran_MODDIR_FLAG "-moddir=")
+SET(CMAKE_Fortran_MODPATH_FLAG "-M")
diff --git a/Modules/Compiler/TinyCC-C.cmake b/Modules/Compiler/TinyCC-C.cmake
new file mode 100644
index 000000000..4a48c0af5
--- /dev/null
+++ b/Modules/Compiler/TinyCC-C.cmake
@@ -0,0 +1,8 @@
+SET(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-shared")
+
+# no optimization in tcc:
+SET (CMAKE_C_FLAGS_INIT "")
+SET (CMAKE_C_FLAGS_DEBUG_INIT "-g")
+SET (CMAKE_C_FLAGS_MINSIZEREL_INIT "-DNDEBUG")
+SET (CMAKE_C_FLAGS_RELEASE_INIT "-DNDEBUG")
+SET (CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "-g")
diff --git a/Modules/Compiler/VisualAge-C.cmake b/Modules/Compiler/VisualAge-C.cmake
new file mode 100644
index 000000000..40b609e9a
--- /dev/null
+++ b/Modules/Compiler/VisualAge-C.cmake
@@ -0,0 +1 @@
+include(Compiler/XL-C)
diff --git a/Modules/Compiler/VisualAge-CXX.cmake b/Modules/Compiler/VisualAge-CXX.cmake
new file mode 100644
index 000000000..2509b4396
--- /dev/null
+++ b/Modules/Compiler/VisualAge-CXX.cmake
@@ -0,0 +1 @@
+include(Compiler/XL-CXX)
diff --git a/Modules/Compiler/VisualAge-Fortran.cmake b/Modules/Compiler/VisualAge-Fortran.cmake
new file mode 100644
index 000000000..3ef3178d9
--- /dev/null
+++ b/Modules/Compiler/VisualAge-Fortran.cmake
@@ -0,0 +1 @@
+include(Compiler/XL-Fortran)
diff --git a/Modules/Compiler/XL-ASM.cmake b/Modules/Compiler/XL-ASM.cmake
new file mode 100644
index 000000000..e5d4ffa85
--- /dev/null
+++ b/Modules/Compiler/XL-ASM.cmake
@@ -0,0 +1,13 @@
+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_DEBUG_INIT "-g")
+SET(CMAKE_ASM_FLAGS_RELEASE_INIT "-O -DNDEBUG")
+SET(CMAKE_ASM_FLAGS_MINSIZEREL_INIT "-O -DNDEBUG")
+SET(CMAKE_ASM_FLAGS_RELWITHDEBINFO_INIT "-g")
+
+SET(CMAKE_ASM_SOURCE_FILE_EXTENSIONS s )
diff --git a/Modules/Compiler/XL-C.cmake b/Modules/Compiler/XL-C.cmake
new file mode 100644
index 000000000..ae869e37e
--- /dev/null
+++ b/Modules/Compiler/XL-C.cmake
@@ -0,0 +1,9 @@
+include(Compiler/XL)
+__compiler_xl(C)
+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")
diff --git a/Modules/Compiler/XL-CXX.cmake b/Modules/Compiler/XL-CXX.cmake
new file mode 100644
index 000000000..29c4b5e37
--- /dev/null
+++ b/Modules/Compiler/XL-CXX.cmake
@@ -0,0 +1,11 @@
+include(Compiler/XL)
+__compiler_xl(CXX)
+set(CMAKE_CXX_FLAGS_RELEASE_INIT "${CMAKE_CXX_FLAGS_RELEASE_INIT} -DNDEBUG")
+set(CMAKE_CXX_FLAGS_MINSIZEREL_INIT "${CMAKE_CXX_FLAGS_MINSIZEREL_INIT} -DNDEBUG")
+
+# -qthreaded = Ensures that all optimizations will be thread-safe
+# -qhalt=e = Halt on error messages (rather than just severe errors)
+SET(CMAKE_CXX_FLAGS_INIT "-qthreaded -qhalt=e")
+
+SET(CMAKE_CXX_COMPILE_OBJECT
+ "<CMAKE_CXX_COMPILER> -+ <DEFINES> <FLAGS> -o <OBJECT> -c <SOURCE>")
diff --git a/Modules/Compiler/XL-Fortran.cmake b/Modules/Compiler/XL-Fortran.cmake
new file mode 100644
index 000000000..e7026f11a
--- /dev/null
+++ b/Modules/Compiler/XL-Fortran.cmake
@@ -0,0 +1,17 @@
+include(Compiler/XL)
+__compiler_xl(Fortran)
+
+set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-qfixed") # [=<right_margin>]
+set(CMAKE_Fortran_FORMAT_FREE_FLAG "-qfree") # [=f90|ibm]
+
+SET(CMAKE_Fortran_MODDIR_FLAG "-qmoddir=")
+
+SET(CMAKE_Fortran_DEFINE_FLAG "-WF,-D")
+
+# -qthreaded = Ensures that all optimizations will be thread-safe
+# -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.
+SET(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE)
+SET(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE)
diff --git a/Modules/Compiler/XL.cmake b/Modules/Compiler/XL.cmake
new file mode 100644
index 000000000..d293610c3
--- /dev/null
+++ b/Modules/Compiler/XL.cmake
@@ -0,0 +1,53 @@
+
+#=============================================================================
+# Copyright 2002-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.)
+
+# This module is shared by multiple languages; use include blocker.
+if(__COMPILER_XL)
+ return()
+endif()
+set(__COMPILER_XL 1)
+
+# Find the CreateExportList program that comes with this toolchain.
+find_program(CMAKE_XL_CreateExportList
+ NAMES CreateExportList
+ DOC "IBM XL CreateExportList tool"
+ )
+
+macro(__compiler_xl lang)
+ # Feature flags.
+ set(CMAKE_${lang}_VERBOSE_FLAG "-V")
+
+ set(CMAKE_${lang}_FLAGS_DEBUG_INIT "-g")
+ 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>")
+
+ # 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
+ # create shared library compile line.
+ if (CMAKE_XL_CreateExportList)
+ # The compiler front-end passes all object files, archive files, and shared
+ # library files named on the command line to CreateExportList to create a
+ # list of all symbols to be exported from the shared library. This causes
+ # all archive members to be copied into the shared library whether they are
+ # needed or not. Instead we run the tool ourselves to pass only the object
+ # files so that we export only the symbols actually provided by the sources.
+ set(CMAKE_${lang}_CREATE_SHARED_LIBRARY
+ "${CMAKE_XL_CreateExportList} <OBJECT_DIR>/objects.exp <OBJECTS>"
+ "<CMAKE_${lang}_COMPILER> <CMAKE_SHARED_LIBRARY_${lang}_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS> -Wl,-bE:<OBJECT_DIR>/objects.exp <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>"
+ )
+ endif()
+endmacro()
diff --git a/Modules/Dart.cmake b/Modules/Dart.cmake
new file mode 100644
index 000000000..870545471
--- /dev/null
+++ b/Modules/Dart.cmake
@@ -0,0 +1,124 @@
+# - 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(BUILD_TESTING)
+# The BUILD_TESTING option is created by the Dart module to determine
+# whether testing support should be enabled. The default is ON.
+
+# This file configures a project to use the Dart testing/dashboard process.
+# It is broken into 3 sections.
+#
+# Section #1: Locate programs on the client and determine site and build name
+# Section #2: Configure or copy Tcl scripts from the source tree to build tree
+# Section #3: Custom targets for performing dashboard builds.
+#
+#
+
+#=============================================================================
+# 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.)
+
+OPTION(BUILD_TESTING "Build the testing tree." ON)
+
+IF(BUILD_TESTING)
+ FIND_PACKAGE(Dart QUIET)
+
+ #
+ # Section #1:
+ #
+ # CMake commands that will not vary from project to project. Locates programs
+ # on the client and configure site name and build name.
+ #
+
+ SET(RUN_FROM_DART 1)
+ INCLUDE(CTest)
+ SET(RUN_FROM_DART)
+
+ FIND_PROGRAM(COMPRESSIONCOMMAND NAMES gzip compress zip
+ DOC "Path to program used to compress files for transfer to the dart server")
+ FIND_PROGRAM(GUNZIPCOMMAND gunzip DOC "Path to gunzip executable")
+ FIND_PROGRAM(JAVACOMMAND java DOC "Path to java command, used by the Dart server to create html.")
+ OPTION(DART_VERBOSE_BUILD "Show the actual output of the build, or if off show a . for each 1024 bytes."
+ OFF)
+ OPTION(DART_BUILD_ERROR_REPORT_LIMIT "Limit of reported errors, -1 reports all." -1 )
+ OPTION(DART_BUILD_WARNING_REPORT_LIMIT "Limit of reported warnings, -1 reports all." -1 )
+
+ SET(VERBOSE_BUILD ${DART_VERBOSE_BUILD})
+ SET(BUILD_ERROR_REPORT_LIMIT ${DART_BUILD_ERROR_REPORT_LIMIT})
+ SET(BUILD_WARNING_REPORT_LIMIT ${DART_BUILD_WARNING_REPORT_LIMIT})
+ SET (DELIVER_CONTINUOUS_EMAIL "Off" CACHE BOOL "Should Dart server send email when build errors are found in Continuous builds?")
+
+ MARK_AS_ADVANCED(
+ COMPRESSIONCOMMAND
+ DART_BUILD_ERROR_REPORT_LIMIT
+ DART_BUILD_WARNING_REPORT_LIMIT
+ DART_TESTING_TIMEOUT
+ DART_VERBOSE_BUILD
+ DELIVER_CONTINUOUS_EMAIL
+ GUNZIPCOMMAND
+ JAVACOMMAND
+ )
+
+ SET(HAVE_DART)
+ IF(EXISTS "${DART_ROOT}/Source/Client/Dart.conf.in")
+ SET(HAVE_DART 1)
+ ENDIF(EXISTS "${DART_ROOT}/Source/Client/Dart.conf.in")
+
+ #
+ # Section #2:
+ #
+ # Make necessary directories and configure testing scripts
+ #
+ # find a tcl shell command
+ IF(HAVE_DART)
+ FIND_PACKAGE(Tclsh)
+ ENDIF(HAVE_DART)
+
+
+ IF (HAVE_DART)
+ # make directories in the binary tree
+ FILE(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/Testing/HTML/TestingResults/Dashboard"
+ "${PROJECT_BINARY_DIR}/Testing/HTML/TestingResults/Sites/${SITE}/${BUILDNAME}")
+
+ # configure files
+ CONFIGURE_FILE(
+ "${DART_ROOT}/Source/Client/Dart.conf.in"
+ "${PROJECT_BINARY_DIR}/DartConfiguration.tcl" )
+
+ #
+ # Section 3:
+ #
+ # Custom targets to perform dashboard builds and submissions.
+ # These should NOT need to be modified from project to project.
+ #
+
+ # add testing targets
+ SET(DART_EXPERIMENTAL_NAME Experimental)
+ IF(DART_EXPERIMENTAL_USE_PROJECT_NAME)
+ SET(DART_EXPERIMENTAL_NAME "${DART_EXPERIMENTAL_NAME}${PROJECT_NAME}")
+ ENDIF(DART_EXPERIMENTAL_USE_PROJECT_NAME)
+ ENDIF (HAVE_DART)
+
+ SET(RUN_FROM_CTEST_OR_DART 1)
+ INCLUDE(CTestTargets)
+ SET(RUN_FROM_CTEST_OR_DART)
+ENDIF(BUILD_TESTING)
+
+#
+# End of Dart.cmake
+#
+
diff --git a/Modules/DartConfiguration.tcl.in b/Modules/DartConfiguration.tcl.in
new file mode 100644
index 000000000..ad7f80517
--- /dev/null
+++ b/Modules/DartConfiguration.tcl.in
@@ -0,0 +1,93 @@
+# 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: @PROJECT_SOURCE_DIR@
+BuildDirectory: @PROJECT_BINARY_DIR@
+
+# Where to place the cost data store
+CostDataFile: @CTEST_COST_DATA_FILE@
+
+# Site is something like machine.domain, i.e. pragmatic.crd
+Site: @SITE@
+
+# Build name is osname-revision-compiler, i.e. Linux-2.4.2-2smp-c++
+BuildName: @BUILDNAME@
+
+# Submission information
+IsCDash: @CTEST_DROP_SITE_CDASH@
+CDashVersion: @CTEST_CDASH_VERSION@
+QueryCDashVersion: @CTEST_CDASH_QUERY_VERSION@
+DropSite: @DROP_SITE@
+DropLocation: @DROP_LOCATION@
+DropSiteUser: @DROP_SITE_USER@
+DropSitePassword: @DROP_SITE_PASSWORD@
+DropSiteMode: @DROP_SITE_MODE@
+DropMethod: @DROP_METHOD@
+TriggerSite: @TRIGGER_SITE@
+ScpCommand: @SCPCOMMAND@
+
+# Dashboard start time
+NightlyStartTime: @NIGHTLY_START_TIME@
+
+# Commands for the build/test/submit cycle
+ConfigureCommand: "@CMAKE_COMMAND@" "@PROJECT_SOURCE_DIR@"
+MakeCommand: @MAKECOMMAND@
+DefaultCTestConfigurationType: @DEFAULT_CTEST_CONFIGURATION_TYPE@
+
+# CVS options
+# Default is "-d -P -A"
+CVSCommand: @CVSCOMMAND@
+CVSUpdateOptions: @CVS_UPDATE_OPTIONS@
+
+# Subversion options
+SVNCommand: @SVNCOMMAND@
+SVNUpdateOptions: @SVN_UPDATE_OPTIONS@
+
+# Git options
+GITCommand: @GITCOMMAND@
+GITUpdateOptions: @GIT_UPDATE_OPTIONS@
+GITUpdateCustom: @CTEST_GIT_UPDATE_CUSTOM@
+
+# Generic update command
+UpdateCommand: @UPDATE_COMMAND@
+UpdateOptions: @UPDATE_OPTIONS@
+UpdateType: @UPDATE_TYPE@
+
+# Compiler info
+Compiler: @CMAKE_CXX_COMPILER@
+
+# Dynamic analysis (MemCheck)
+PurifyCommand: @PURIFYCOMMAND@
+ValgrindCommand: @VALGRIND_COMMAND@
+ValgrindCommandOptions: @VALGRIND_COMMAND_OPTIONS@
+MemoryCheckCommand: @MEMORYCHECK_COMMAND@
+MemoryCheckCommandOptions: @MEMORYCHECK_COMMAND_OPTIONS@
+MemoryCheckSuppressionFile: @MEMORYCHECK_SUPPRESSIONS_FILE@
+
+# Coverage
+CoverageCommand: @COVERAGE_COMMAND@
+CoverageExtraFlags: @COVERAGE_EXTRA_FLAGS@
+
+# Cluster commands
+SlurmBatchCommand: @SLURM_SBATCH_COMMAND@
+SlurmRunCommand: @SLURM_SRUN_COMMAND@
+
+# Testing options
+# TimeOut is the amount of time in seconds to wait for processes
+# to complete during testing. After TimeOut seconds, the
+# process will be summarily terminated.
+# Currently set to 25 minutes
+TimeOut: @DART_TESTING_TIMEOUT@
+
+UseLaunchers: @CTEST_USE_LAUNCHERS@
+CurlOptions: @CTEST_CURL_OPTIONS@
+# warning, if you add new options here that have to do with submit,
+# you have to update cmCTestSubmitCommand.cxx
+
+# For CTest submissions that timeout, these options
+# specify behavior for retrying the submission
+CTestSubmitRetryDelay: @CTEST_SUBMIT_RETRY_DELAY@
+CTestSubmitRetryCount: @CTEST_SUBMIT_RETRY_COUNT@
diff --git a/Modules/DeployQt4.cmake b/Modules/DeployQt4.cmake
new file mode 100644
index 000000000..edf4b4e76
--- /dev/null
+++ b/Modules/DeployQt4.cmake
@@ -0,0 +1,301 @@
+# - 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
+# Requires CMake 2.6 or greater because it uses function and
+# PARENT_SCOPE. Also depends on BundleUtilities.cmake.
+#
+# 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>])
+# 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.
+#
+# 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.
+#
+# <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.
+#
+# <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.
+#
+# 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.
+#
+# 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.
+
+#=============================================================================
+# Copyright 2011 Mike McQuaid <mike@mikemcquaid.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.)
+
+# The functions defined in this file depend on the fixup_bundle function
+# (and others) found in BundleUtilities.cmake
+
+include(BundleUtilities)
+set(DeployQt4_cmake_dir "${CMAKE_CURRENT_LIST_DIR}")
+set(DeployQt4_apple_plugins_dir "PlugIns")
+
+function(write_qt4_conf qt_conf_dir qt_conf_contents)
+ set(qt_conf_path "${qt_conf_dir}/qt.conf")
+ message(STATUS "Writing ${qt_conf_path}")
+ file(WRITE "${qt_conf_path}" "${qt_conf_contents}")
+endfunction()
+
+function(resolve_qt4_paths paths_var)
+ set(executable_path ${ARGV1})
+
+ set(paths_resolved)
+ foreach(path ${${paths_var}})
+ if(EXISTS "${path}")
+ list(APPEND paths_resolved "${path}")
+ else()
+ if(${executable_path})
+ list(APPEND paths_resolved "${executable_path}/${path}")
+ else()
+ list(APPEND paths_resolved "\${CMAKE_INSTALL_PREFIX}/${path}")
+ endif()
+ endif()
+ endforeach()
+ set(${paths_var} ${paths_resolved} PARENT_SCOPE)
+endfunction()
+
+function(fixup_qt4_executable executable)
+ set(qtplugins ${ARGV1})
+ set(libs ${ARGV2})
+ set(dirs ${ARGV3})
+ set(plugins_dir ${ARGV4})
+ set(request_qt_conf ${ARGV5})
+
+ message(STATUS "fixup_qt4_executable")
+ message(STATUS " executable='${executable}'")
+ message(STATUS " qtplugins='${qtplugins}'")
+ message(STATUS " libs='${libs}'")
+ message(STATUS " dirs='${dirs}'")
+ message(STATUS " plugins_dir='${plugins_dir}'")
+ message(STATUS " request_qt_conf='${request_qt_conf}'")
+
+ if(QT_LIBRARY_DIR)
+ list(APPEND dirs "${QT_LIBRARY_DIR}")
+ endif()
+ if(QT_BINARY_DIR)
+ list(APPEND dirs "${QT_BINARY_DIR}")
+ endif()
+
+ if(APPLE)
+ set(qt_conf_dir "${executable}/Contents/Resources")
+ set(executable_path "${executable}")
+ set(write_qt_conf TRUE)
+ if(NOT plugins_dir)
+ set(plugins_dir "${DeployQt4_apple_plugins_dir}")
+ endif()
+ else()
+ get_filename_component(executable_path "${executable}" PATH)
+ if(NOT executable_path)
+ set(executable_path ".")
+ endif()
+ set(qt_conf_dir "${executable_path}")
+ set(write_qt_conf ${request_qt_conf})
+ endif()
+
+ foreach(plugin ${qtplugins})
+ set(installed_plugin_path "")
+ install_qt4_plugin("${plugin}" "${executable}" 1 installed_plugin_path)
+ list(APPEND libs ${installed_plugin_path})
+ endforeach()
+
+ foreach(lib ${libs})
+ if(NOT EXISTS "${lib}")
+ message(FATAL_ERROR "Library does not exist: ${lib}")
+ endif()
+ endforeach()
+
+ resolve_qt4_paths(libs "${executable_path}")
+
+ if(write_qt_conf)
+ set(qt_conf_contents "[Paths]\nPlugins = ${plugins_dir}")
+ write_qt4_conf("${qt_conf_dir}" "${qt_conf_contents}")
+ endif()
+
+ fixup_bundle("${executable}" "${libs}" "${dirs}")
+endfunction()
+
+function(install_qt4_plugin_path plugin executable copy installed_plugin_path_var)
+ set(plugins_dir ${ARGV4})
+ set(component ${ARGV5})
+ set(configurations ${ARGV6})
+ if(EXISTS "${plugin}")
+ if(APPLE)
+ if(NOT plugins_dir)
+ set(plugins_dir "${DeployQt4_apple_plugins_dir}")
+ endif()
+ set(plugins_path "${executable}/Contents/${plugins_dir}")
+ else()
+ get_filename_component(plugins_path "${executable}" PATH)
+ if(NOT plugins_path)
+ set(plugins_path ".")
+ endif()
+ if(plugins_dir)
+ set(plugins_path "${plugins_path}/${plugins_dir}")
+ endif()
+ endif()
+
+ set(plugin_group "")
+
+ get_filename_component(plugin_path "${plugin}" PATH)
+ get_filename_component(plugin_parent_path "${plugin_path}" PATH)
+ get_filename_component(plugin_parent_dir_name "${plugin_parent_path}" NAME)
+ get_filename_component(plugin_name "${plugin}" NAME)
+ string(TOLOWER "${plugin_parent_dir_name}" plugin_parent_dir_name)
+
+ if("${plugin_parent_dir_name}" STREQUAL "plugins")
+ get_filename_component(plugin_group "${plugin_path}" NAME)
+ set(${plugin_group_var} "${plugin_group}")
+ endif()
+ set(plugins_path "${plugins_path}/${plugin_group}")
+
+ if(${copy})
+ file(MAKE_DIRECTORY "${plugins_path}")
+ file(COPY "${plugin}" DESTINATION "${plugins_path}")
+ else()
+ if(configurations AND (CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE))
+ set(configurations CONFIGURATIONS ${configurations})
+ else()
+ unset(configurations)
+ endif()
+ install(FILES "${plugin}" DESTINATION "${plugins_path}" ${configurations} ${component})
+ endif()
+ set(${installed_plugin_path_var} "${plugins_path}/${plugin_name}" PARENT_SCOPE)
+ endif()
+endfunction()
+
+function(install_qt4_plugin plugin executable copy installed_plugin_path_var)
+ set(plugins_dir ${ARGV4})
+ set(component ${ARGV5})
+ if(EXISTS "${plugin}")
+ install_qt4_plugin_path("${plugin}" "${executable}" "${copy}" "${installed_plugin_path_var}" "${plugins_dir}" "${component}")
+ else()
+ string(TOUPPER "QT_${plugin}_PLUGIN" plugin_var)
+ set(plugin_release_var "${plugin_var}_RELEASE")
+ set(plugin_debug_var "${plugin_var}_DEBUG")
+ set(plugin_release "${${plugin_release_var}}")
+ set(plugin_debug "${${plugin_debug_var}}")
+ if(DEFINED "${plugin_release_var}" AND DEFINED "${plugin_debug_var}" AND NOT EXISTS "${plugin_release}" AND NOT EXISTS "${plugin_debug}")
+ message(WARNING "Qt plugin \"${plugin}\" not recognized or found.")
+ endif()
+ if(NOT EXISTS "${${plugin_debug_var}}")
+ set(plugin_debug "${plugin_release}")
+ endif()
+
+ if(CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE)
+ install_qt4_plugin_path("${plugin_release}" "${executable}" "${copy}" "${installed_plugin_path_var}_release" "${plugins_dir}" "${component}" "Release|RelWithDebInfo|MinSizeRel")
+ install_qt4_plugin_path("${plugin_debug}" "${executable}" "${copy}" "${installed_plugin_path_var}_debug" "${plugins_dir}" "${component}" "Debug")
+
+ if(CMAKE_BUILD_TYPE MATCHES "^Debug$")
+ set(${installed_plugin_path_var} ${${installed_plugin_path_var}_debug})
+ else()
+ set(${installed_plugin_path_var} ${${installed_plugin_path_var}_release})
+ endif()
+ else()
+ install_qt4_plugin_path("${plugin_release}" "${executable}" "${copy}" "${installed_plugin_path_var}" "${plugins_dir}" "${component}")
+ endif()
+ endif()
+ set(${installed_plugin_path_var} ${${installed_plugin_path_var}} PARENT_SCOPE)
+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})
+ if(QT_LIBRARY_DIR)
+ list(APPEND dirs "${QT_LIBRARY_DIR}")
+ endif()
+ if(QT_BINARY_DIR)
+ list(APPEND dirs "${QT_BINARY_DIR}")
+ endif()
+ if(component)
+ set(component COMPONENT ${component})
+ else()
+ unset(component)
+ endif()
+
+ get_filename_component(executable_absolute "${executable}" ABSOLUTE)
+ if(EXISTS "${QT_QTCORE_LIBRARY_RELEASE}")
+ gp_file_type("${executable_absolute}" "${QT_QTCORE_LIBRARY_RELEASE}" qtcore_type)
+ elseif(EXISTS "${QT_QTCORE_LIBRARY_DEBUG}")
+ gp_file_type("${executable_absolute}" "${QT_QTCORE_LIBRARY_DEBUG}" qtcore_type)
+ endif()
+ if(qtcore_type STREQUAL "system")
+ set(qt_plugins_dir "")
+ endif()
+
+ if(QT_IS_STATIC)
+ message(WARNING "Qt built statically: not installing plugins.")
+ else()
+ foreach(plugin ${qtplugins})
+ set(installed_plugin_paths "")
+ install_qt4_plugin("${plugin}" "${executable}" 0 installed_plugin_paths "${plugins_dir}" "${component}")
+ list(APPEND libs ${installed_plugin_paths})
+ endforeach()
+ endif()
+
+ resolve_qt4_paths(libs "")
+
+ install(CODE
+ "INCLUDE(\"${DeployQt4_cmake_dir}/DeployQt4.cmake\")
+ SET(BU_CHMOD_BUNDLE_ITEMS TRUE)
+ FIXUP_QT4_EXECUTABLE(\"\${CMAKE_INSTALL_PREFIX}/${executable}\" \"\" \"${libs}\" \"${dirs}\" \"${plugins_dir}\" \"${request_qt_conf}\")"
+ ${component}
+ )
+endfunction()
diff --git a/Modules/Documentation.cmake b/Modules/Documentation.cmake
new file mode 100644
index 000000000..ffeb371cc
--- /dev/null
+++ b/Modules/Documentation.cmake
@@ -0,0 +1,52 @@
+# - DocumentationVTK.cmake
+# This file provides support for the VTK documentation framework.
+# It relies on several tools (Doxygen, Perl, etc).
+
+#=============================================================================
+# 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.)
+
+#
+# Build the documentation ?
+#
+OPTION(BUILD_DOCUMENTATION "Build the documentation (Doxygen)." OFF)
+MARK_AS_ADVANCED(BUILD_DOCUMENTATION)
+
+IF (BUILD_DOCUMENTATION)
+
+ #
+ # Check for the tools
+ #
+ FIND_PACKAGE(UnixCommands)
+ FIND_PACKAGE(Doxygen)
+ FIND_PACKAGE(Gnuplot)
+ FIND_PACKAGE(HTMLHelp)
+ FIND_PACKAGE(Perl)
+ FIND_PACKAGE(Wget)
+
+ OPTION(DOCUMENTATION_HTML_HELP
+ "Build the HTML Help file (CHM)." OFF)
+
+ OPTION(DOCUMENTATION_HTML_TARZ
+ "Build a compressed tar archive of the HTML doc." OFF)
+
+ MARK_AS_ADVANCED(
+ DOCUMENTATION_HTML_HELP
+ DOCUMENTATION_HTML_TARZ
+ )
+
+ #
+ # The documentation process is controled by a batch file.
+ # We will probably need bash to create the custom target
+ #
+
+ENDIF (BUILD_DOCUMENTATION)
diff --git a/Modules/DummyCXXFile.cxx b/Modules/DummyCXXFile.cxx
new file mode 100644
index 000000000..f8b643afb
--- /dev/null
+++ b/Modules/DummyCXXFile.cxx
@@ -0,0 +1,4 @@
+int main()
+{
+ return 0;
+}
diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake
new file mode 100644
index 000000000..a0a9aead5
--- /dev/null
+++ b/Modules/ExternalProject.cmake
@@ -0,0 +1,1553 @@
+# - 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_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
+# [URL /.../src.tgz] # Full path or URL of source
+# [URL_MD5 md5] # MD5 checksum of file at URL
+# [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_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.
+#
+# 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)
+
+#=============================================================================
+# Copyright 2008-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.)
+
+# Pre-compute a regex to match documented keywords for each command.
+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_]+\\()")
+foreach(line IN LISTS lines)
+ if("${line}" MATCHES "^# [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}")
+ #message("function [${_ep_func}]")
+ set(_ep_keywords_${_ep_func} "^(")
+ set(_ep_keyword_sep)
+ else()
+ string(REGEX REPLACE "^# \\[([A-Z0-9_]+) .*" "\\1" _ep_key "${line}")
+ #message(" keyword [${_ep_key}]")
+ set(_ep_keywords_${_ep_func}
+ "${_ep_keywords_${_ep_func}}${_ep_keyword_sep}${_ep_key}")
+ set(_ep_keyword_sep "|")
+ endif()
+endforeach()
+if(_ep_func)
+ set(_ep_keywords_${_ep_func} "${_ep_keywords_${_ep_func}})$")
+endif()
+
+
+function(_ep_parse_arguments f name ns args)
+ # Transfer the arguments to this function into target properties for the
+ # new custom target we just added so that we can set up all the build steps
+ # correctly based on target properties.
+ #
+ # We loop through ARGN and consider the namespace starting with an
+ # upper-case letter followed by at least two more upper-case letters,
+ # numbers or underscores to be keywords.
+ set(key)
+
+ foreach(arg IN LISTS 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 arg MATCHES "^(TRUE|FALSE)$")
+ if(_ep_keywords_${f} AND arg MATCHES "${_ep_keywords_${f}}")
+ set(is_value 0)
+ endif()
+ endif()
+
+ if(is_value)
+ if(key)
+ # Value
+ if(NOT arg STREQUAL "")
+ set_property(TARGET ${name} APPEND PROPERTY ${ns}${key} "${arg}")
+ else()
+ get_property(have_key TARGET ${name} PROPERTY ${ns}${key} SET)
+ if(have_key)
+ get_property(value TARGET ${name} PROPERTY ${ns}${key})
+ set_property(TARGET ${name} PROPERTY ${ns}${key} "${value};${arg}")
+ else()
+ set_property(TARGET ${name} PROPERTY ${ns}${key} "${arg}")
+ endif()
+ endif()
+ else()
+ # Missing Keyword
+ message(AUTHOR_WARNING "value '${arg}' with no previous keyword in ${f}")
+ endif()
+ else()
+ set(key "${arg}")
+ endif()
+ endforeach()
+endfunction(_ep_parse_arguments)
+
+
+define_property(DIRECTORY PROPERTY "EP_BASE" INHERITED
+ BRIEF_DOCS "Base directory for External Project storage."
+ FULL_DOCS
+ "See documentation of the ExternalProject_Add() function in the "
+ "ExternalProject module."
+ )
+
+define_property(DIRECTORY PROPERTY "EP_PREFIX" INHERITED
+ BRIEF_DOCS "Top prefix for External Project storage."
+ FULL_DOCS
+ "See documentation of the ExternalProject_Add() function in the "
+ "ExternalProject module."
+ )
+
+define_property(DIRECTORY PROPERTY "EP_STEP_TARGETS" INHERITED
+ BRIEF_DOCS
+ "List of ExternalProject steps that automatically get corresponding targets"
+ FULL_DOCS
+ "See documentation of the ExternalProject_Add_StepTargets() 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)
+ file(WRITE ${script_filename}
+"if(\"${git_tag}\" STREQUAL \"\")
+ message(FATAL_ERROR \"Tag for git checkout should not be empty.\")
+endif()
+
+set(run 0)
+
+if(\"${gitclone_infofile}\" IS_NEWER_THAN \"${gitclone_stampfile}\")
+ set(run 1)
+endif()
+
+if(NOT run)
+ message(STATUS \"Avoiding repeated git clone, stamp file is up to date: '${gitclone_stampfile}'\")
+ return()
+endif()
+
+execute_process(
+ COMMAND \${CMAKE_COMMAND} -E remove_directory \"${source_dir}\"
+ RESULT_VARIABLE error_code
+ )
+if(error_code)
+ message(FATAL_ERROR \"Failed to remove directory: '${source_dir}'\")
+endif()
+
+execute_process(
+ COMMAND \"${git_EXECUTABLE}\" clone \"${git_repository}\" \"${src_name}\"
+ WORKING_DIRECTORY \"${work_dir}\"
+ RESULT_VARIABLE error_code
+ )
+if(error_code)
+ message(FATAL_ERROR \"Failed to clone repository: '${git_repository}'\")
+endif()
+
+execute_process(
+ COMMAND \"${git_EXECUTABLE}\" checkout ${git_tag}
+ WORKING_DIRECTORY \"${work_dir}/${src_name}\"
+ RESULT_VARIABLE error_code
+ )
+if(error_code)
+ message(FATAL_ERROR \"Failed to checkout tag: '${git_tag}'\")
+endif()
+
+execute_process(
+ COMMAND \"${git_EXECUTABLE}\" submodule init
+ WORKING_DIRECTORY \"${work_dir}/${src_name}\"
+ RESULT_VARIABLE error_code
+ )
+if(error_code)
+ message(FATAL_ERROR \"Failed to init submodules in: '${work_dir}/${src_name}'\")
+endif()
+
+execute_process(
+ COMMAND \"${git_EXECUTABLE}\" submodule update --recursive
+ WORKING_DIRECTORY \"${work_dir}/${src_name}\"
+ RESULT_VARIABLE error_code
+ )
+if(error_code)
+ message(FATAL_ERROR \"Failed to update submodules in: '${work_dir}/${src_name}'\")
+endif()
+
+# Complete success, update the script-last-run stamp file:
+#
+execute_process(
+ COMMAND \${CMAKE_COMMAND} -E copy
+ \"${gitclone_infofile}\"
+ \"${gitclone_stampfile}\"
+ WORKING_DIRECTORY \"${work_dir}/${src_name}\"
+ RESULT_VARIABLE error_code
+ )
+if(error_code)
+ message(FATAL_ERROR \"Failed to copy script-last-run stamp file: '${gitclone_stampfile}'\")
+endif()
+
+"
+)
+
+endfunction(_ep_write_gitclone_script)
+
+
+function(_ep_write_downloadfile_script script_filename remote local timeout md5)
+ if(timeout)
+ set(timeout_args TIMEOUT ${timeout})
+ set(timeout_msg "${timeout} seconds")
+ else()
+ set(timeout_args "# no TIMEOUT")
+ set(timeout_msg "none")
+ endif()
+
+ if(md5)
+ set(md5_args EXPECTED_MD5 ${md5})
+ else()
+ set(md5_args "# no EXPECTED_MD5")
+ endif()
+
+ file(WRITE ${script_filename}
+"message(STATUS \"downloading...
+ src='${remote}'
+ dst='${local}'
+ timeout='${timeout_msg}'\")
+
+file(DOWNLOAD
+ \"${remote}\"
+ \"${local}\"
+ SHOW_PROGRESS
+ ${md5_args}
+ ${timeout_args}
+ STATUS status
+ LOG log)
+
+list(GET status 0 status_code)
+list(GET status 1 status_string)
+
+if(NOT status_code EQUAL 0)
+ message(FATAL_ERROR \"error: downloading '${remote}' failed
+ status_code: \${status_code}
+ status_string: \${status_string}
+ log: \${log}
+\")
+endif()
+
+message(STATUS \"downloading... done\")
+"
+)
+
+endfunction(_ep_write_downloadfile_script)
+
+
+function(_ep_write_verifyfile_script script_filename local md5)
+ file(WRITE ${script_filename}
+"message(STATUS \"verifying file...
+ file='${local}'\")
+
+set(verified 0)
+
+# If an expected md5 checksum exists, compare against it:
+#
+if(NOT \"${md5}\" STREQUAL \"\")
+ execute_process(COMMAND \${CMAKE_COMMAND} -E md5sum \"${local}\"
+ OUTPUT_VARIABLE ov
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ RESULT_VARIABLE rv)
+
+ if(NOT rv EQUAL 0)
+ message(FATAL_ERROR \"error: computing md5sum of '${local}' failed\")
+ endif()
+
+ string(REGEX MATCH \"^([0-9A-Fa-f]+)\" md5_actual \"\${ov}\")
+
+ string(TOLOWER \"\${md5_actual}\" md5_actual)
+ string(TOLOWER \"${md5}\" md5)
+
+ if(NOT \"\${md5}\" STREQUAL \"\${md5_actual}\")
+ message(FATAL_ERROR \"error: md5sum of '${local}' does not match expected value
+ md5_expected: \${md5}
+ md5_actual: \${md5_actual}
+\")
+ endif()
+
+ set(verified 1)
+endif()
+
+if(verified)
+ message(STATUS \"verifying file... done\")
+else()
+ message(STATUS \"verifying file... warning: did not verify file - no URL_MD5 checksum argument? corrupt file?\")
+endif()
+"
+)
+
+endfunction(_ep_write_verifyfile_script)
+
+
+function(_ep_write_extractfile_script script_filename name filename directory)
+ set(args "")
+
+ if(filename MATCHES "(\\.|=)(bz2|tar\\.gz|tgz|zip)$")
+ set(args xfz)
+ endif()
+
+ if(filename MATCHES "(\\.|=)tar$")
+ set(args xf)
+ 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")
+ return()
+ endif()
+
+ file(WRITE ${script_filename}
+"# Make file names absolute:
+#
+get_filename_component(filename \"${filename}\" ABSOLUTE)
+get_filename_component(directory \"${directory}\" ABSOLUTE)
+
+message(STATUS \"extracting...
+ src='\${filename}'
+ dst='\${directory}'\")
+
+if(NOT EXISTS \"\${filename}\")
+ message(FATAL_ERROR \"error: file to extract does not exist: '\${filename}'\")
+endif()
+
+# Prepare a space for extracting:
+#
+set(i 1234)
+while(EXISTS \"\${directory}/../ex-${name}\${i}\")
+ math(EXPR i \"\${i} + 1\")
+endwhile()
+set(ut_dir \"\${directory}/../ex-${name}\${i}\")
+file(MAKE_DIRECTORY \"\${ut_dir}\")
+
+# Extract it:
+#
+message(STATUS \"extracting... [tar ${args}]\")
+execute_process(COMMAND \${CMAKE_COMMAND} -E tar ${args} \${filename}
+ WORKING_DIRECTORY \${ut_dir}
+ RESULT_VARIABLE rv)
+
+if(NOT rv EQUAL 0)
+ message(STATUS \"extracting... [error clean up]\")
+ file(REMOVE_RECURSE \"\${ut_dir}\")
+ message(FATAL_ERROR \"error: extract of '\${filename}' failed\")
+endif()
+
+# Analyze what came out of the tar file:
+#
+message(STATUS \"extracting... [analysis]\")
+file(GLOB contents \"\${ut_dir}/*\")
+list(LENGTH contents n)
+if(NOT n EQUAL 1 OR NOT IS_DIRECTORY \"\${contents}\")
+ set(contents \"\${ut_dir}\")
+endif()
+
+# Move \"the one\" directory to the final directory:
+#
+message(STATUS \"extracting... [rename]\")
+file(REMOVE_RECURSE \${directory})
+get_filename_component(contents \${contents} ABSOLUTE)
+file(RENAME \${contents} \${directory})
+
+# Clean up:
+#
+message(STATUS \"extracting... [clean up]\")
+file(REMOVE_RECURSE \"\${ut_dir}\")
+
+message(STATUS \"extracting... done\")
+"
+)
+
+endfunction(_ep_write_extractfile_script)
+
+
+function(_ep_set_directories name)
+ get_property(prefix TARGET ${name} PROPERTY _EP_PREFIX)
+ if(NOT prefix)
+ get_property(prefix DIRECTORY PROPERTY EP_PREFIX)
+ if(NOT prefix)
+ get_property(base DIRECTORY PROPERTY EP_BASE)
+ if(NOT base)
+ set(prefix "${name}-prefix")
+ endif()
+ endif()
+ endif()
+ if(prefix)
+ set(tmp_default "${prefix}/tmp")
+ set(download_default "${prefix}/src")
+ set(source_default "${prefix}/src/${name}")
+ set(binary_default "${prefix}/src/${name}-build")
+ set(stamp_default "${prefix}/src/${name}-stamp")
+ set(install_default "${prefix}")
+ else() # assert(base)
+ set(tmp_default "${base}/tmp/${name}")
+ set(download_default "${base}/Download/${name}")
+ set(source_default "${base}/Source/${name}")
+ set(binary_default "${base}/Build/${name}")
+ set(stamp_default "${base}/Stamp/${name}")
+ set(install_default "${base}/Install/${name}")
+ endif()
+ get_property(build_in_source TARGET ${name} PROPERTY _EP_BUILD_IN_SOURCE)
+ if(build_in_source)
+ get_property(have_binary_dir TARGET ${name} PROPERTY _EP_BINARY_DIR SET)
+ if(have_binary_dir)
+ message(FATAL_ERROR
+ "External project ${name} has both BINARY_DIR and BUILD_IN_SOURCE!")
+ endif()
+ endif()
+ set(top "${CMAKE_CURRENT_BINARY_DIR}")
+ set(places stamp download source binary install tmp)
+ foreach(var ${places})
+ string(TOUPPER "${var}" VAR)
+ get_property(${var}_dir TARGET ${name} PROPERTY _EP_${VAR}_DIR)
+ if(NOT ${var}_dir)
+ set(${var}_dir "${${var}_default}")
+ endif()
+ if(NOT IS_ABSOLUTE "${${var}_dir}")
+ get_filename_component(${var}_dir "${top}/${${var}_dir}" ABSOLUTE)
+ endif()
+ set_property(TARGET ${name} PROPERTY _EP_${VAR}_DIR "${${var}_dir}")
+ endforeach()
+ if(build_in_source)
+ get_property(source_dir TARGET ${name} PROPERTY _EP_SOURCE_DIR)
+ set_property(TARGET ${name} PROPERTY _EP_BINARY_DIR "${source_dir}")
+ endif()
+
+ # Make the directories at CMake configure time *and* add a custom command
+ # to make them at build time. They need to exist at makefile generation
+ # time for Borland make and wmake so that CMake may generate makefiles
+ # with "cd C:\short\paths\with\no\spaces" commands in them.
+ #
+ # Additionally, the add_custom_command is still used in case somebody
+ # removes one of the necessary directories and tries to rebuild without
+ # re-running cmake.
+ foreach(var ${places})
+ string(TOUPPER "${var}" VAR)
+ get_property(dir TARGET ${name} PROPERTY _EP_${VAR}_DIR)
+ file(MAKE_DIRECTORY "${dir}")
+ if(NOT EXISTS "${dir}")
+ message(FATAL_ERROR "dir '${dir}' does not exist after file(MAKE_DIRECTORY)")
+ endif()
+ endforeach()
+endfunction(_ep_set_directories)
+
+
+# IMPORTANT: this MUST be a macro and not a function because of the
+# in-place replacements that occur in each ${var}
+#
+macro(_ep_replace_location_tags target_name)
+ set(vars ${ARGN})
+ foreach(var ${vars})
+ if(${var})
+ foreach(dir SOURCE_DIR BINARY_DIR INSTALL_DIR TMP_DIR)
+ get_property(val TARGET ${target_name} PROPERTY _EP_${dir})
+ string(REPLACE "<${dir}>" "${val}" ${var} "${${var}}")
+ endforeach()
+ endif()
+ endforeach()
+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
+ set(script_initial_cache "")
+ set(regex "^([^:]+):([^=]+)=(.*)$")
+ set(setArg "")
+ foreach(line ${args})
+ if("${line}" MATCHES "^-D")
+ 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(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}")
+ set(setArg "set(${name} \"${value}")
+ else()
+ message(WARNING "Line '${line}' does not match regex. Ignoring.")
+ endif()
+ else()
+ # Assume this is a list to append to the last var
+ set(accumulator "${accumulator};${line}")
+ endif()
+ endforeach()
+ # Catch the final line of the args
+ if(setArg)
+ set(setArg "${setArg}${accumulator}\" CACHE ${type} \"Initial cache\" FORCE)")
+ set(script_initial_cache "${script_initial_cache}\n${setArg}")
+ endif()
+ # 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}")
+endfunction(_ep_write_initial_cache)
+
+
+function(ExternalProject_Get_Property name)
+ foreach(var ${ARGN})
+ string(TOUPPER "${var}" VAR)
+ get_property(${var} TARGET ${name} PROPERTY _EP_${VAR})
+ if(NOT ${var})
+ message(FATAL_ERROR "External project \"${name}\" has no ${var}")
+ endif()
+ set(${var} "${${var}}" PARENT_SCOPE)
+ endforeach()
+endfunction(ExternalProject_Get_Property)
+
+
+function(_ep_get_configure_command_id name cfg_cmd_id_var)
+ get_target_property(cmd ${name} _EP_CONFIGURE_COMMAND)
+
+ if(cmd STREQUAL "")
+ # Explicit empty string means no configure step for this project
+ set(${cfg_cmd_id_var} "none" PARENT_SCOPE)
+ else()
+ if(NOT cmd)
+ # Default is "use cmake":
+ set(${cfg_cmd_id_var} "cmake" PARENT_SCOPE)
+ else()
+ # Otherwise we have to analyze the value:
+ if(cmd MATCHES "^[^;]*/configure")
+ set(${cfg_cmd_id_var} "configure" PARENT_SCOPE)
+ elseif(cmd MATCHES "^[^;]*/cmake" AND NOT cmd MATCHES ";-[PE];")
+ set(${cfg_cmd_id_var} "cmake" PARENT_SCOPE)
+ elseif(cmd MATCHES "config")
+ set(${cfg_cmd_id_var} "configure" PARENT_SCOPE)
+ else()
+ set(${cfg_cmd_id_var} "unknown:${cmd}" PARENT_SCOPE)
+ endif()
+ endif()
+ endif()
+endfunction(_ep_get_configure_command_id)
+
+
+function(_ep_get_build_command name step cmd_var)
+ set(cmd "${${cmd_var}}")
+ if(NOT cmd)
+ set(args)
+ _ep_get_configure_command_id(${name} cfg_cmd_id)
+ if(cfg_cmd_id STREQUAL "cmake")
+ # CMake project. Select build command based on generator.
+ get_target_property(cmake_generator ${name} _EP_CMAKE_GENERATOR)
+ if("${CMAKE_GENERATOR}" MATCHES "Make" AND
+ ("${cmake_generator}" MATCHES "Make" OR NOT cmake_generator))
+ # The project uses the same Makefile generator. Use recursive make.
+ set(cmd "$(MAKE)")
+ if(step STREQUAL "INSTALL")
+ set(args install)
+ endif()
+ if(step STREQUAL "TEST")
+ set(args test)
+ endif()
+ else()
+ # Drive the project with "cmake --build".
+ get_target_property(cmake_command ${name} _EP_CMAKE_COMMAND)
+ if(cmake_command)
+ set(cmd "${cmake_command}")
+ else()
+ set(cmd "${CMAKE_COMMAND}")
+ endif()
+ set(args --build ${binary_dir} --config ${CMAKE_CFG_INTDIR})
+ if(step STREQUAL "INSTALL")
+ list(APPEND args --target install)
+ endif()
+ # But for "TEST" drive the project with corresponding "ctest".
+ if(step STREQUAL "TEST")
+ string(REGEX REPLACE "^(.*/)cmake([^/]*)$" "\\1ctest\\2" cmd "${cmd}")
+ set(args "")
+ endif()
+ endif()
+ else() # if(cfg_cmd_id STREQUAL "configure")
+ # Non-CMake project. Guess "make" and "make install" and "make test".
+ if("${CMAKE_GENERATOR}" MATCHES "Makefiles")
+ # Try to get the parallel arguments
+ set(cmd "$(MAKE)")
+ else()
+ set(cmd "make")
+ endif()
+ if(step STREQUAL "INSTALL")
+ set(args install)
+ endif()
+ if(step STREQUAL "TEST")
+ set(args test)
+ endif()
+ endif()
+
+ # Use user-specified arguments instead of default arguments, if any.
+ get_property(have_args TARGET ${name} PROPERTY _EP_${step}_ARGS SET)
+ if(have_args)
+ get_target_property(args ${name} _EP_${step}_ARGS)
+ endif()
+
+ list(APPEND cmd ${args})
+ endif()
+
+ set(${cmd_var} "${cmd}" PARENT_SCOPE)
+endfunction(_ep_get_build_command)
+
+function(_ep_write_log_script name step cmd_var)
+ ExternalProject_Get_Property(${name} stamp_dir)
+ set(command "${${cmd_var}}")
+
+ set(make "")
+ set(code_cygpath_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}")
+ set(make "-Dmake=$(MAKE)")
+
+ if(WIN32 AND NOT CYGWIN)
+ set(code_cygpath_make "
+if(\${make} MATCHES \"^/\")
+ execute_process(
+ COMMAND cygpath -w \${make}
+ OUTPUT_VARIABLE cygpath_make
+ ERROR_VARIABLE cygpath_make
+ RESULT_VARIABLE cygpath_error
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+ if(NOT cygpath_error)
+ set(make \${cygpath_make})
+ endif()
+endif()
+")
+ endif()
+ endif()
+
+ set(config "")
+ if("${CMAKE_CFG_INTDIR}" MATCHES "^\\$")
+ string(REPLACE "${CMAKE_CFG_INTDIR}" "\${config}" command "${command}")
+ set(config "-Dconfig=${CMAKE_CFG_INTDIR}")
+ 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;")
+ set(code_execute_process "
+${code_cygpath_make}
+execute_process(COMMAND \${command} RESULT_VARIABLE result)
+if(result)
+ set(msg \"Command failed (\${result}):\\n\")
+ foreach(arg IN LISTS command)
+ set(msg \"\${msg} '\${arg}'\")
+ endforeach(arg)
+ message(FATAL_ERROR \"\${msg}\")
+endif()
+")
+ set(code "")
+ set(cmd "")
+ set(sep "")
+ foreach(arg IN LISTS command)
+ if("x${arg}" STREQUAL "xCOMMAND")
+ set(code "${code}set(command \"${cmd}\")${code_execute_process}")
+ set(cmd "")
+ set(sep "")
+ else()
+ set(cmd "${cmd}${sep}${arg}")
+ set(sep ";")
+ endif()
+ endforeach()
+ set(code "set(ENV{VS_UNICODE_OUTPUT} \"\")\n${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)
+ endif()
+
+ # Wrap the command in a script to log output to files.
+ set(script ${stamp_dir}/${name}-${step}.cmake)
+ set(logbase ${stamp_dir}/${name}-${step})
+ file(WRITE ${script} "
+${code_cygpath_make}
+set(ENV{VS_UNICODE_OUTPUT} \"\")
+set(command \"${command}\")
+execute_process(
+ COMMAND \${command}
+ RESULT_VARIABLE result
+ OUTPUT_FILE \"${logbase}-out.log\"
+ ERROR_FILE \"${logbase}-err.log\"
+ )
+if(result)
+ set(msg \"Command failed: \${result}\\n\")
+ foreach(arg IN LISTS command)
+ set(msg \"\${msg} '\${arg}'\")
+ endforeach(arg)
+ set(msg \"\${msg}\\nSee also\\n ${logbase}-*.log\\n\")
+ message(FATAL_ERROR \"\${msg}\")
+else()
+ set(msg \"${name} ${step} command succeeded. See also ${logbase}-*.log\\n\")
+ message(STATUS \"\${msg}\")
+endif()
+")
+ set(command ${CMAKE_COMMAND} ${make} ${config} -P ${script})
+ set(${cmd_var} "${command}" PARENT_SCOPE)
+endfunction(_ep_write_log_script)
+
+# This module used to use "/${CMAKE_CFG_INTDIR}" directly and produced
+# makefiles with "/./" in paths for custom command dependencies. Which
+# resulted in problems with parallel make -j invocations.
+#
+# This function was added so that the suffix (search below for ${cfgdir}) is
+# only set to "/${CMAKE_CFG_INTDIR}" when ${CMAKE_CFG_INTDIR} is not going to
+# be "." (multi-configuration build systems like Visual Studio and Xcode...)
+#
+function(_ep_get_configuration_subdir_suffix suffix_var)
+ set(suffix "")
+ if(CMAKE_CONFIGURATION_TYPES)
+ set(suffix "/${CMAKE_CFG_INTDIR}")
+ endif()
+ set(${suffix_var} "${suffix}" PARENT_SCOPE)
+endfunction(_ep_get_configuration_subdir_suffix)
+
+
+function(_ep_get_step_stampfile name step stampfile_var)
+ ExternalProject_Get_Property(${name} stamp_dir)
+
+ _ep_get_configuration_subdir_suffix(cfgdir)
+ set(stampfile "${stamp_dir}${cfgdir}/${name}-${step}")
+
+ set(${stampfile_var} "${stampfile}" PARENT_SCOPE)
+endfunction()
+
+
+function(ExternalProject_Add_StepTargets name)
+ set(steps ${ARGN})
+
+ foreach(step ${steps})
+ _ep_get_step_stampfile(${name} ${step} stamp_file)
+ add_custom_target(${name}-${step}
+ DEPENDS ${stamp_file})
+
+ # 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()
+ endforeach()
+endfunction(ExternalProject_Add_StepTargets)
+
+
+function(ExternalProject_Add_Step name step)
+ set(cmf_dir ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles)
+ _ep_get_configuration_subdir_suffix(cfgdir)
+
+ 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}")
+
+ # Steps depending on this step.
+ get_property(dependers TARGET ${name} PROPERTY _EP_${step}_DEPENDERS)
+ foreach(depender IN LISTS dependers)
+ _ep_get_step_stampfile(${name} ${depender} depender_stamp_file)
+ add_custom_command(APPEND
+ OUTPUT ${depender_stamp_file}
+ DEPENDS ${stamp_file}
+ )
+ endforeach()
+
+ # Dependencies on files.
+ get_property(depends TARGET ${name} PROPERTY _EP_${step}_DEPENDS)
+
+ # Dependencies on steps.
+ get_property(dependees TARGET ${name} PROPERTY _EP_${step}_DEPENDEES)
+ foreach(dependee IN LISTS dependees)
+ _ep_get_step_stampfile(${name} ${dependee} dependee_stamp_file)
+ list(APPEND depends ${dependee_stamp_file})
+ endforeach()
+
+ # The command to run.
+ get_property(command TARGET ${name} PROPERTY _EP_${step}_COMMAND)
+ if(command)
+ set(comment "Performing ${step} step for '${name}'")
+ else()
+ set(comment "No ${step} step for '${name}'")
+ endif()
+ get_property(work_dir TARGET ${name} PROPERTY _EP_${step}_WORKING_DIRECTORY)
+
+ # Replace list separators.
+ get_property(sep TARGET ${name} PROPERTY _EP_LIST_SEPARATOR)
+ if(sep AND command)
+ string(REPLACE "${sep}" "\\;" command "${command}")
+ endif()
+
+ # Replace location tags.
+ _ep_replace_location_tags(${name} comment command work_dir)
+
+ # Custom comment?
+ get_property(comment_set TARGET ${name} PROPERTY _EP_${step}_COMMENT SET)
+ if(comment_set)
+ get_property(comment TARGET ${name} PROPERTY _EP_${step}_COMMENT)
+ 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)
+ else()
+ set(touch ${CMAKE_COMMAND} -E touch ${stamp_file})
+ endif()
+
+ # Wrap with log script?
+ get_property(log TARGET ${name} PROPERTY _EP_${step}_LOG)
+ if(command AND log)
+ _ep_write_log_script(${name} ${step} command)
+ endif()
+
+ add_custom_command(
+ OUTPUT ${stamp_file}
+ COMMENT ${comment}
+ COMMAND ${command}
+ COMMAND ${touch}
+ DEPENDS ${depends}
+ WORKING_DIRECTORY ${work_dir}
+ VERBATIM
+ )
+
+ # Add custom "step target"?
+ get_property(step_targets TARGET ${name} PROPERTY _EP_STEP_TARGETS)
+ if(NOT step_targets)
+ get_property(step_targets DIRECTORY PROPERTY EP_STEP_TARGETS)
+ endif()
+ foreach(st ${step_targets})
+ if("${st}" STREQUAL "${step}")
+ ExternalProject_Add_StepTargets(${name} ${step})
+ break()
+ endif()
+ endforeach()
+endfunction(ExternalProject_Add_Step)
+
+
+function(_ep_add_mkdir_command name)
+ ExternalProject_Get_Property(${name}
+ source_dir binary_dir install_dir stamp_dir download_dir tmp_dir)
+
+ _ep_get_configuration_subdir_suffix(cfgdir)
+
+ ExternalProject_Add_Step(${name} mkdir
+ COMMENT "Creating directories for '${name}'"
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${source_dir}
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${binary_dir}
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${install_dir}
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${tmp_dir}
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${stamp_dir}${cfgdir}
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${download_dir}
+ )
+endfunction(_ep_add_mkdir_command)
+
+
+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 "")
+ set(${empty_var} 1 PARENT_SCOPE)
+ else()
+ set(${empty_var} 0 PARENT_SCOPE)
+ endif()
+endfunction()
+
+
+function(_ep_add_download_command name)
+ ExternalProject_Get_Property(${name} source_dir stamp_dir download_dir tmp_dir)
+
+ get_property(cmd_set TARGET ${name} PROPERTY _EP_DOWNLOAD_COMMAND SET)
+ get_property(cmd TARGET ${name} PROPERTY _EP_DOWNLOAD_COMMAND)
+ get_property(cvs_repository TARGET ${name} PROPERTY _EP_CVS_REPOSITORY)
+ get_property(svn_repository TARGET ${name} PROPERTY _EP_SVN_REPOSITORY)
+ get_property(git_repository TARGET ${name} PROPERTY _EP_GIT_REPOSITORY)
+ get_property(url TARGET ${name} PROPERTY _EP_URL)
+
+ # TODO: Perhaps file:// should be copied to download dir before extraction.
+ string(REGEX REPLACE "^file://" "" url "${url}")
+
+ set(depends)
+ set(comment)
+ set(work_dir)
+
+ if(cmd_set)
+ set(work_dir ${download_dir})
+ elseif(cvs_repository)
+ find_package(CVS)
+ if(NOT CVS_EXECUTABLE)
+ message(FATAL_ERROR "error: could not find cvs for checkout of ${name}")
+ endif()
+
+ get_target_property(cvs_module ${name} _EP_CVS_MODULE)
+ if(NOT cvs_module)
+ message(FATAL_ERROR "error: no CVS_MODULE")
+ endif()
+
+ get_property(cvs_tag TARGET ${name} PROPERTY _EP_CVS_TAG)
+
+ set(repository ${cvs_repository})
+ set(module ${cvs_module})
+ set(tag ${cvs_tag})
+ configure_file(
+ "${CMAKE_ROOT}/Modules/RepositoryInfo.txt.in"
+ "${stamp_dir}/${name}-cvsinfo.txt"
+ @ONLY
+ )
+
+ get_filename_component(src_name "${source_dir}" NAME)
+ get_filename_component(work_dir "${source_dir}" PATH)
+ set(comment "Performing download step (CVS checkout) for '${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)
+ if(NOT Subversion_SVN_EXECUTABLE)
+ message(FATAL_ERROR "error: could not find svn for checkout of ${name}")
+ endif()
+
+ get_property(svn_revision TARGET ${name} PROPERTY _EP_SVN_REVISION)
+ get_property(svn_username TARGET ${name} PROPERTY _EP_SVN_USERNAME)
+ get_property(svn_password TARGET ${name} PROPERTY _EP_SVN_PASSWORD)
+ get_property(svn_trust_cert TARGET ${name} PROPERTY _EP_SVN_TRUST_CERT)
+
+ set(repository "${svn_repository} user=${svn_username} password=${svn_password}")
+ set(module)
+ set(tag ${svn_revision})
+ configure_file(
+ "${CMAKE_ROOT}/Modules/RepositoryInfo.txt.in"
+ "${stamp_dir}/${name}-svninfo.txt"
+ @ONLY
+ )
+
+ get_filename_component(src_name "${source_dir}" NAME)
+ get_filename_component(work_dir "${source_dir}" PATH)
+ set(comment "Performing download step (SVN checkout) for '${name}'")
+ set(svn_user_pw_args "")
+ if(svn_username)
+ set(svn_user_pw_args ${svn_user_pw_args} "--username=${svn_username}")
+ endif()
+ if(svn_password)
+ set(svn_user_pw_args ${svn_user_pw_args} "--password=${svn_password}")
+ endif()
+ if(svn_trust_cert)
+ set(svn_trust_cert_args --trust-server-cert)
+ endif()
+ set(cmd ${Subversion_SVN_EXECUTABLE} co ${svn_repository} ${svn_revision}
+ --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)
+ 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}'")
+ endif()
+
+ get_property(git_tag TARGET ${name} PROPERTY _EP_GIT_TAG)
+ if(NOT git_tag)
+ set(git_tag "master")
+ endif()
+
+ # For the download step, and the git clone operation, only the repository
+ # should be recorded in a configured RepositoryInfo file. If the repo
+ # changes, the clone script should be run again. But if only the tag
+ # changes, avoid running the clone script again. Let the 'always' running
+ # update step checkout the new tag.
+ #
+ set(repository ${git_repository})
+ set(module)
+ set(tag)
+ configure_file(
+ "${CMAKE_ROOT}/Modules/RepositoryInfo.txt.in"
+ "${stamp_dir}/${name}-gitinfo.txt"
+ @ONLY
+ )
+
+ get_filename_component(src_name "${source_dir}" NAME)
+ get_filename_component(work_dir "${source_dir}" PATH)
+
+ # Since git clone doesn't succeed if the non-empty source_dir exists,
+ # create a cmake script to invoke as download command.
+ # 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}
+ ${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(url)
+ get_filename_component(work_dir "${source_dir}" PATH)
+ get_property(md5 TARGET ${name} PROPERTY _EP_URL_MD5)
+ set(repository "external project URL")
+ set(module "${url}")
+ set(tag "${md5}")
+ configure_file(
+ "${CMAKE_ROOT}/Modules/RepositoryInfo.txt.in"
+ "${stamp_dir}/${name}-urlinfo.txt"
+ @ONLY
+ )
+ list(APPEND depends ${stamp_dir}/${name}-urlinfo.txt)
+ if(IS_DIRECTORY "${url}")
+ get_filename_component(abs_dir "${url}" ABSOLUTE)
+ set(comment "Performing download step (DIR copy) for '${name}'")
+ set(cmd ${CMAKE_COMMAND} -E remove_directory ${source_dir}
+ COMMAND ${CMAKE_COMMAND} -E copy_directory ${abs_dir} ${source_dir})
+ else()
+ if("${url}" MATCHES "^[a-z]+://")
+ # TODO: Should download and extraction be different steps?
+ string(REGEX MATCH "[^/\\?]*$" fname "${url}")
+ if(NOT "${fname}" MATCHES "(\\.|=)(bz2|tar|tgz|tar\\.gz|zip)$")
+ string(REGEX MATCH "([^/\\?]+(\\.|=)(bz2|tar|tgz|tar\\.gz|zip))/.*$" match_result "${url}")
+ set(fname "${CMAKE_MATCH_1}")
+ endif()
+ if(NOT "${fname}" MATCHES "(\\.|=)(bz2|tar|tgz|tar\\.gz|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)
+ _ep_write_downloadfile_script("${stamp_dir}/download-${name}.cmake" "${url}" "${file}" "${timeout}" "${md5}")
+ set(cmd ${CMAKE_COMMAND} -P ${stamp_dir}/download-${name}.cmake
+ COMMAND)
+ 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}" "${md5}")
+ 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}")
+ list(APPEND cmd ${CMAKE_COMMAND} -P ${stamp_dir}/extract-${name}.cmake)
+ endif()
+ 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 or DOWNLOAD_COMMAND")
+ endif()
+ endif()
+
+ get_property(log TARGET ${name} PROPERTY _EP_LOG_DOWNLOAD)
+ if(log)
+ set(log LOG 1)
+ else()
+ set(log "")
+ endif()
+
+ ExternalProject_Add_Step(${name} download
+ COMMENT ${comment}
+ COMMAND ${cmd}
+ WORKING_DIRECTORY ${work_dir}
+ DEPENDS ${depends}
+ DEPENDEES mkdir
+ ${log}
+ )
+endfunction(_ep_add_download_command)
+
+
+function(_ep_add_update_command name)
+ ExternalProject_Get_Property(${name} source_dir)
+
+ get_property(cmd_set TARGET ${name} PROPERTY _EP_UPDATE_COMMAND SET)
+ get_property(cmd TARGET ${name} PROPERTY _EP_UPDATE_COMMAND)
+ get_property(cvs_repository TARGET ${name} PROPERTY _EP_CVS_REPOSITORY)
+ get_property(svn_repository TARGET ${name} PROPERTY _EP_SVN_REPOSITORY)
+ get_property(git_repository TARGET ${name} PROPERTY _EP_GIT_REPOSITORY)
+
+ set(work_dir)
+ set(comment)
+ set(always)
+
+ if(cmd_set)
+ set(work_dir ${source_dir})
+ elseif(cvs_repository)
+ if(NOT CVS_EXECUTABLE)
+ message(FATAL_ERROR "error: could not find cvs for update of ${name}")
+ endif()
+ set(work_dir ${source_dir})
+ set(comment "Performing update step (CVS update) for '${name}'")
+ get_property(cvs_tag TARGET ${name} PROPERTY _EP_CVS_TAG)
+ set(cmd ${CVS_EXECUTABLE} -d ${cvs_repository} -q up -dP ${cvs_tag})
+ set(always 1)
+ elseif(svn_repository)
+ if(NOT Subversion_SVN_EXECUTABLE)
+ message(FATAL_ERROR "error: could not find svn for update of ${name}")
+ endif()
+ set(work_dir ${source_dir})
+ set(comment "Performing update step (SVN update) for '${name}'")
+ get_property(svn_revision TARGET ${name} PROPERTY _EP_SVN_REVISION)
+ get_property(svn_username TARGET ${name} PROPERTY _EP_SVN_USERNAME)
+ get_property(svn_password TARGET ${name} PROPERTY _EP_SVN_PASSWORD)
+ get_property(svn_trust_cert TARGET ${name} PROPERTY _EP_SVN_TRUST_CERT)
+ set(svn_user_pw_args "")
+ if(svn_username)
+ set(svn_user_pw_args ${svn_user_pw_args} "--username=${svn_username}")
+ endif()
+ if(svn_password)
+ set(svn_user_pw_args ${svn_user_pw_args} "--password=${svn_password}")
+ endif()
+ if(svn_trust_cert)
+ set(svn_trust_cert_args --trust-server-cert)
+ endif()
+ set(cmd ${Subversion_SVN_EXECUTABLE} up ${svn_revision}
+ --non-interactive ${svn_trust_cert_args} ${svn_user_pw_args})
+ set(always 1)
+ elseif(git_repository)
+ if(NOT GIT_EXECUTABLE)
+ message(FATAL_ERROR "error: could not find git for fetch of ${name}")
+ endif()
+ set(work_dir ${source_dir})
+ set(comment "Performing update step (git fetch) for '${name}'")
+ get_property(git_tag TARGET ${name} PROPERTY _EP_GIT_TAG)
+ if(NOT git_tag)
+ set(git_tag "master")
+ endif()
+ set(cmd ${GIT_EXECUTABLE} fetch
+ COMMAND ${GIT_EXECUTABLE} checkout ${git_tag}
+ COMMAND ${GIT_EXECUTABLE} submodule update --recursive
+ )
+ set(always 1)
+ endif()
+
+ get_property(log TARGET ${name} PROPERTY _EP_LOG_UPDATE)
+ if(log)
+ set(log LOG 1)
+ else()
+ set(log "")
+ endif()
+
+ ExternalProject_Add_Step(${name} update
+ COMMENT ${comment}
+ COMMAND ${cmd}
+ ALWAYS ${always}
+ WORKING_DIRECTORY ${work_dir}
+ DEPENDEES download
+ ${log}
+ )
+endfunction(_ep_add_update_command)
+
+
+function(_ep_add_patch_command name)
+ ExternalProject_Get_Property(${name} source_dir)
+
+ get_property(cmd_set TARGET ${name} PROPERTY _EP_PATCH_COMMAND SET)
+ get_property(cmd TARGET ${name} PROPERTY _EP_PATCH_COMMAND)
+
+ set(work_dir)
+
+ if(cmd_set)
+ set(work_dir ${source_dir})
+ endif()
+
+ ExternalProject_Add_Step(${name} patch
+ COMMAND ${cmd}
+ WORKING_DIRECTORY ${work_dir}
+ DEPENDEES download
+ )
+endfunction(_ep_add_patch_command)
+
+
+# TODO: Make sure external projects use the proper compiler
+function(_ep_add_configure_command name)
+ ExternalProject_Get_Property(${name} source_dir binary_dir tmp_dir)
+
+ # Depend on other external projects (file-level).
+ set(file_deps)
+ get_property(deps TARGET ${name} PROPERTY _EP_DEPENDS)
+ foreach(dep IN LISTS deps)
+ _ep_get_step_stampfile(${dep} "done" done_stamp_file)
+ list(APPEND file_deps ${done_stamp_file})
+ endforeach()
+
+ get_property(cmd_set TARGET ${name} PROPERTY _EP_CONFIGURE_COMMAND SET)
+ if(cmd_set)
+ get_property(cmd TARGET ${name} PROPERTY _EP_CONFIGURE_COMMAND)
+ else()
+ get_target_property(cmake_command ${name} _EP_CMAKE_COMMAND)
+ if(cmake_command)
+ set(cmd "${cmake_command}")
+ else()
+ set(cmd "${CMAKE_COMMAND}")
+ endif()
+
+ 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
+ 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}")
+ list(APPEND cmd "-C${_ep_cache_args_script}")
+ endif()
+
+ get_target_property(cmake_generator ${name} _EP_CMAKE_GENERATOR)
+ if(cmake_generator)
+ list(APPEND cmd "-G${cmake_generator}" "${source_dir}")
+ else()
+ if(CMAKE_EXTRA_GENERATOR)
+ list(APPEND cmd "-G${CMAKE_EXTRA_GENERATOR} - ${CMAKE_GENERATOR}"
+ "${source_dir}")
+ else()
+ list(APPEND cmd "-G${CMAKE_GENERATOR}" "${source_dir}")
+ endif()
+ endif()
+ endif()
+
+ # If anything about the configure command changes, (command itself, cmake
+ # used, cmake args or cmake generator) then re-run the configure step.
+ # Fixes issue http://public.kitware.com/Bug/view.php?id=10258
+ #
+ if(NOT EXISTS ${tmp_dir}/${name}-cfgcmd.txt.in)
+ file(WRITE ${tmp_dir}/${name}-cfgcmd.txt.in "cmd='\@cmd\@'\n")
+ endif()
+ configure_file(${tmp_dir}/${name}-cfgcmd.txt.in ${tmp_dir}/${name}-cfgcmd.txt)
+ list(APPEND file_deps ${tmp_dir}/${name}-cfgcmd.txt)
+ list(APPEND file_deps ${_ep_cache_args_script})
+
+ get_property(log TARGET ${name} PROPERTY _EP_LOG_CONFIGURE)
+ if(log)
+ set(log LOG 1)
+ else()
+ set(log "")
+ endif()
+
+ ExternalProject_Add_Step(${name} configure
+ COMMAND ${cmd}
+ WORKING_DIRECTORY ${binary_dir}
+ DEPENDEES update patch
+ DEPENDS ${file_deps}
+ ${log}
+ )
+endfunction(_ep_add_configure_command)
+
+
+function(_ep_add_build_command name)
+ ExternalProject_Get_Property(${name} binary_dir)
+
+ get_property(cmd_set TARGET ${name} PROPERTY _EP_BUILD_COMMAND SET)
+ if(cmd_set)
+ get_property(cmd TARGET ${name} PROPERTY _EP_BUILD_COMMAND)
+ else()
+ _ep_get_build_command(${name} BUILD cmd)
+ endif()
+
+ get_property(log TARGET ${name} PROPERTY _EP_LOG_BUILD)
+ if(log)
+ set(log LOG 1)
+ else()
+ set(log "")
+ endif()
+
+ ExternalProject_Add_Step(${name} build
+ COMMAND ${cmd}
+ WORKING_DIRECTORY ${binary_dir}
+ DEPENDEES configure
+ ${log}
+ )
+endfunction(_ep_add_build_command)
+
+
+function(_ep_add_install_command name)
+ ExternalProject_Get_Property(${name} binary_dir)
+
+ get_property(cmd_set TARGET ${name} PROPERTY _EP_INSTALL_COMMAND SET)
+ if(cmd_set)
+ get_property(cmd TARGET ${name} PROPERTY _EP_INSTALL_COMMAND)
+ else()
+ _ep_get_build_command(${name} INSTALL cmd)
+ endif()
+
+ get_property(log TARGET ${name} PROPERTY _EP_LOG_INSTALL)
+ if(log)
+ set(log LOG 1)
+ else()
+ set(log "")
+ endif()
+
+ ExternalProject_Add_Step(${name} install
+ COMMAND ${cmd}
+ WORKING_DIRECTORY ${binary_dir}
+ DEPENDEES build
+ ${log}
+ )
+endfunction(_ep_add_install_command)
+
+
+function(_ep_add_test_command name)
+ ExternalProject_Get_Property(${name} binary_dir)
+
+ get_property(before TARGET ${name} PROPERTY _EP_TEST_BEFORE_INSTALL)
+ get_property(after TARGET ${name} PROPERTY _EP_TEST_AFTER_INSTALL)
+ 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)
+ get_property(cmd TARGET ${name} PROPERTY _EP_TEST_COMMAND)
+ else()
+ _ep_get_build_command(${name} TEST cmd)
+ endif()
+
+ if(before)
+ set(dep_args DEPENDEES build DEPENDERS install)
+ else()
+ set(dep_args DEPENDEES install)
+ endif()
+
+ get_property(log TARGET ${name} PROPERTY _EP_LOG_TEST)
+ if(log)
+ set(log LOG 1)
+ else()
+ set(log "")
+ endif()
+
+ ExternalProject_Add_Step(${name} test
+ COMMAND ${cmd}
+ WORKING_DIRECTORY ${binary_dir}
+ ${dep_args}
+ ${log}
+ )
+ endif()
+endfunction(_ep_add_test_command)
+
+
+function(ExternalProject_Add name)
+ _ep_get_configuration_subdir_suffix(cfgdir)
+
+ # Add a custom target for the external project.
+ set(cmf_dir ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles)
+ set(complete_stamp_file "${cmf_dir}${cfgdir}/${name}-complete")
+
+ add_custom_target(${name} ALL DEPENDS ${complete_stamp_file})
+ set_property(TARGET ${name} PROPERTY _EP_IS_EXTERNAL_PROJECT 1)
+ _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)
+
+ # 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
+ # rebuilds. It is important that 'done' is not the output of any
+ # custom command so that CMake does not propagate build rules to
+ # other external project targets, which may cause problems during
+ # parallel builds. However, the Ninja generator needs to see the entire
+ # dependency graph, and can cope with custom commands belonging to
+ # multiple targets, so we add the 'done' mark as an output for Ninja only.
+ set(complete_outputs ${complete_stamp_file})
+ if(${CMAKE_GENERATOR} MATCHES "Ninja")
+ set(complete_outputs ${complete_outputs} ${done_stamp_file})
+ endif()
+
+ add_custom_command(
+ OUTPUT ${complete_outputs}
+ COMMENT "Completed '${name}'"
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${cmf_dir}${cfgdir}
+ COMMAND ${CMAKE_COMMAND} -E touch ${complete_stamp_file}
+ COMMAND ${CMAKE_COMMAND} -E touch ${done_stamp_file}
+ DEPENDS ${install_stamp_file}
+ VERBATIM
+ )
+
+
+ # Depend on other external projects (target-level).
+ get_property(deps TARGET ${name} PROPERTY _EP_DEPENDS)
+ foreach(arg IN LISTS deps)
+ add_dependencies(${name} ${arg})
+ endforeach()
+
+ # Set up custom build steps based on the target properties.
+ # Each step depends on the previous one.
+ #
+ # The target depends on the output of the final step.
+ # (Already set up above in the DEPENDS of the add_custom_target command.)
+ #
+ _ep_add_mkdir_command(${name})
+ _ep_add_download_command(${name})
+ _ep_add_update_command(${name})
+ _ep_add_patch_command(${name})
+ _ep_add_configure_command(${name})
+ _ep_add_build_command(${name})
+ _ep_add_install_command(${name})
+
+ # Test is special in that it might depend on build, or it might depend
+ # on install.
+ #
+ _ep_add_test_command(${name})
+endfunction(ExternalProject_Add)
diff --git a/Modules/FLTKCompatibility.cmake b/Modules/FLTKCompatibility.cmake
new file mode 100644
index 000000000..6b6f9607b
--- /dev/null
+++ b/Modules/FLTKCompatibility.cmake
@@ -0,0 +1,15 @@
+
+#=============================================================================
+# 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.)
+
+INCLUDE(CheckIncludeFile)
diff --git a/Modules/FeatureSummary.cmake b/Modules/FeatureSummary.cmake
new file mode 100644
index 000000000..a5b94d199
--- /dev/null
+++ b/Modules/FeatureSummary.cmake
@@ -0,0 +1,466 @@
+# - 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.
+#
+# 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.
+# 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.
+#
+# 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.")
+#
+#
+# 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.
+#
+# 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:")
+#
+# SET_FEATURE_INFO(<name> <description> [<url>] )
+# Does the same as SET_PACKAGE_INFO(<name> <description> <url> )
+
+#=============================================================================
+# 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.)
+
+INCLUDE(CMakeParseArguments)
+
+
+FUNCTION(ADD_FEATURE_INFO _name _enabled _desc)
+ IF (${_enabled})
+ SET_PROPERTY(GLOBAL APPEND PROPERTY ENABLED_FEATURES "${_name}")
+ ELSE ()
+ SET_PROPERTY(GLOBAL APPEND PROPERTY DISABLED_FEATURES "${_name}")
+ ENDIF ()
+
+ SET_PROPERTY(GLOBAL PROPERTY _CMAKE_${_name}_DESCRIPTION "${_desc}" )
+ENDFUNCTION(ADD_FEATURE_INFO)
+
+
+
+FUNCTION(SET_PACKAGE_PROPERTIES _name _props)
+ IF(NOT "${_props}" STREQUAL "PROPERTIES")
+ MESSAGE(FATAL_ERROR "PROPERTIES keyword is missing in SET_PACKAGE_PROPERTIES() call.")
+ ENDIF()
+
+ SET(options ) # none
+ SET(oneValueArgs DESCRIPTION URL TYPE PURPOSE )
+ SET(multiValueArgs ) # none
+
+ CMAKE_PARSE_ARGUMENTS(_SPP "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+ IF(_SPP_UNPARSED_ARGUMENTS)
+ MESSAGE(FATAL_ERROR "Unknown keywords given to SET_PACKAGE_PROPERTIES(): \"${_SPP_UNPARSED_ARGUMENTS}\"")
+ ENDIF()
+
+ IF(_SPP_DESCRIPTION)
+ GET_PROPERTY(_info GLOBAL PROPERTY _CMAKE_${_name}_DESCRIPTION)
+ IF(_info AND NOT "${_info}" STREQUAL "${_SPP_DESCRIPTION}")
+ MESSAGE(STATUS "Warning: Property DESCRIPTION for package ${_name} already set to \"${_info}\", overriding it with \"${_SPP_DESCRIPTION}\"")
+ ENDIF()
+
+ SET_PROPERTY(GLOBAL PROPERTY _CMAKE_${_name}_DESCRIPTION "${_SPP_DESCRIPTION}" )
+ ENDIF()
+
+
+ IF(_SPP_URL)
+ GET_PROPERTY(_info GLOBAL PROPERTY _CMAKE_${_name}_URL)
+ IF(_info AND NOT "${_info}" STREQUAL "${_SPP_URL}")
+ MESSAGE(STATUS "Warning: Property URL already set to \"${_info}\", overriding it with \"${_SPP_URL}\"")
+ ENDIF()
+
+ SET_PROPERTY(GLOBAL PROPERTY _CMAKE_${_name}_URL "${_SPP_URL}" )
+ ENDIF()
+
+
+ # handle the PURPOSE: use APPEND, since there can be multiple purposes for one package inside a project
+ IF(_SPP_PURPOSE)
+ SET_PROPERTY(GLOBAL APPEND PROPERTY _CMAKE_${_name}_PURPOSE "${_SPP_PURPOSE}" )
+ ENDIF()
+
+ # handle the TYPE
+ IF(NOT _SPP_TYPE)
+ SET(_SPP_TYPE OPTIONAL)
+ ENDIF()
+
+ # List the supported types, according to their priority
+ SET(validTypes "RUNTIME" "OPTIONAL" "RECOMMENDED" "REQUIRED" )
+ LIST(FIND validTypes ${_SPP_TYPE} _typeIndexInList)
+ IF("${_typeIndexInList}" STREQUAL "-1" )
+ MESSAGE(FATAL_ERROR "Bad package property type ${_SPP_TYPE} used in SET_PACKAGE_PROPERTIES(). "
+ "Valid types are OPTIONAL, RECOMMENDED, REQUIRED and RUNTIME." )
+ ENDIF()
+
+ GET_PROPERTY(_previousType GLOBAL PROPERTY _CMAKE_${_name}_TYPE)
+ LIST(FIND validTypes "${_previousType}" _prevTypeIndexInList)
+
+ # make sure a previously set TYPE is not overridden with a lower new TYPE:
+ IF("${_typeIndexInList}" GREATER "${_prevTypeIndexInList}")
+ SET_PROPERTY(GLOBAL PROPERTY _CMAKE_${_name}_TYPE "${_SPP_TYPE}" )
+ ENDIF()
+
+ENDFUNCTION(SET_PACKAGE_PROPERTIES)
+
+
+
+FUNCTION(_FS_GET_FEATURE_SUMMARY _property _var _includeQuiet)
+
+ SET(_type "ANY")
+ IF("${_property}" MATCHES "REQUIRED_")
+ SET(_type "REQUIRED")
+ ELSEIF("${_property}" MATCHES "RECOMMENDED_")
+ SET(_type "RECOMMENDED")
+ ELSEIF("${_property}" MATCHES "RUNTIME_")
+ SET(_type "RUNTIME")
+ ELSEIF("${_property}" MATCHES "OPTIONAL_")
+ SET(_type "OPTIONAL")
+ ENDIF()
+
+ IF("${_property}" MATCHES "PACKAGES_FOUND")
+ SET(_property "PACKAGES_FOUND")
+ ELSEIF("${_property}" MATCHES "PACKAGES_NOT_FOUND")
+ SET(_property "PACKAGES_NOT_FOUND")
+ ENDIF()
+
+
+ SET(_currentFeatureText "")
+ GET_PROPERTY(_EnabledFeatures GLOBAL PROPERTY ${_property})
+
+ FOREACH(_currentFeature ${_EnabledFeatures})
+
+ # does this package belong to the type we currently want to list ?
+ GET_PROPERTY(_currentType GLOBAL PROPERTY _CMAKE_${_currentFeature}_TYPE)
+ IF(NOT _currentType)
+ SET(_currentType OPTIONAL)
+ ENDIF()
+
+ IF("${_type}" STREQUAL ANY OR "${_type}" STREQUAL "${_currentType}")
+
+ # check whether the current feature/package should be in the output depending on whether it was QUIET or not
+ SET(includeThisOne TRUE)
+ # skip QUIET packages, except if they are REQUIRED or INCLUDE_QUIET_PACKAGES has been set
+ IF((NOT "${_currentType}" STREQUAL "REQUIRED") AND NOT _includeQuiet)
+ GET_PROPERTY(_isQuiet GLOBAL PROPERTY _CMAKE_${_currentFeature}_QUIET)
+ IF(_isQuiet)
+ SET(includeThisOne FALSE)
+ ENDIF()
+ ENDIF()
+
+ IF(includeThisOne)
+
+ SET(_currentFeatureText "${_currentFeatureText}\n * ${_currentFeature}")
+ GET_PROPERTY(_info GLOBAL PROPERTY _CMAKE_${_currentFeature}_REQUIRED_VERSION)
+ IF(_info)
+ SET(_currentFeatureText "${_currentFeatureText} (required version ${_info})")
+ ENDIF(_info)
+ GET_PROPERTY(_info GLOBAL PROPERTY _CMAKE_${_currentFeature}_DESCRIPTION)
+ IF(_info)
+ SET(_currentFeatureText "${_currentFeatureText} , ${_info}")
+ ENDIF(_info)
+ GET_PROPERTY(_info GLOBAL PROPERTY _CMAKE_${_currentFeature}_URL)
+ IF(_info)
+ SET(_currentFeatureText "${_currentFeatureText} , <${_info}>")
+ ENDIF(_info)
+
+ GET_PROPERTY(_info GLOBAL PROPERTY _CMAKE_${_currentFeature}_PURPOSE)
+ FOREACH(_purpose ${_info})
+ SET(_currentFeatureText "${_currentFeatureText}\n ${_purpose}")
+ ENDFOREACH()
+
+ ENDIF(includeThisOne)
+
+ ENDIF("${_type}" STREQUAL ANY OR "${_type}" STREQUAL "${_currentType}")
+
+ ENDFOREACH(_currentFeature)
+ SET(${_var} "${_currentFeatureText}" PARENT_SCOPE)
+ENDFUNCTION(_FS_GET_FEATURE_SUMMARY)
+
+
+
+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
+
+ CMAKE_PARSE_ARGUMENTS(_FS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${_FIRST_ARG} ${ARGN})
+
+ IF(_FS_UNPARSED_ARGUMENTS)
+ MESSAGE(FATAL_ERROR "Unknown keywords given to FEATURE_SUMMARY(): \"${_FS_UNPARSED_ARGUMENTS}\"")
+ ENDIF()
+
+ IF(NOT _FS_WHAT)
+ MESSAGE(FATAL_ERROR "The call to FEATURE_SUMMARY() doesn't set the required WHAT argument.")
+ ENDIF()
+
+ SET(validWhatParts "ENABLED_FEATURES"
+ "DISABLED_FEATURES"
+ "PACKAGES_FOUND"
+ "PACKAGES_NOT_FOUND"
+ "OPTIONAL_PACKAGES_FOUND"
+ "OPTIONAL_PACKAGES_NOT_FOUND"
+ "RECOMMENDED_PACKAGES_FOUND"
+ "RECOMMENDED_PACKAGES_NOT_FOUND"
+ "REQUIRED_PACKAGES_FOUND"
+ "REQUIRED_PACKAGES_NOT_FOUND"
+ "RUNTIME_PACKAGES_FOUND"
+ "RUNTIME_PACKAGES_NOT_FOUND")
+
+ LIST(FIND validWhatParts "${_FS_WHAT}" indexInList)
+ IF(NOT "${indexInList}" STREQUAL "-1")
+ _FS_GET_FEATURE_SUMMARY( ${_FS_WHAT} _featureSummary ${_FS_INCLUDE_QUIET_PACKAGES} )
+ SET(_fullText "${_FS_DESCRIPTION}${_featureSummary}\n")
+ IF (("${_FS_WHAT}" STREQUAL "REQUIRED_PACKAGES_NOT_FOUND") AND _featureSummary)
+ SET(requiredPackagesNotFound TRUE)
+ ENDIF()
+
+ ELSEIF("${_FS_WHAT}" STREQUAL "ALL")
+
+ 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"
+ )
+
+ SET(title_ENABLED_FEATURES "The following features have been enabled:")
+ SET(title_DISABLED_FEATURES "The following features have been disabled:")
+ 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:")
+ SET(title_RECOMMENDED_PACKAGES_NOT_FOUND "The following RECOMMENDED packages have not been found:")
+ SET(title_REQUIRED_PACKAGES_FOUND "The following REQUIRED packages have been found:")
+ SET(title_REQUIRED_PACKAGES_NOT_FOUND "The following REQUIRED packages have not been found:")
+ SET(title_RUNTIME_PACKAGES_FOUND "The following RUNTIME packages have been found:")
+ SET(title_RUNTIME_PACKAGES_NOT_FOUND "The following RUNTIME packages have not been found:")
+
+ SET(_fullText "${_FS_DESCRIPTION}")
+ FOREACH(part ${allWhatParts})
+ SET(_tmp)
+ _FS_GET_FEATURE_SUMMARY( ${part} _tmp ${_FS_INCLUDE_QUIET_PACKAGES})
+ IF(_tmp)
+ SET(_fullText "${_fullText}\n-- ${title_${part}}\n${_tmp}\n")
+ IF("${part}" STREQUAL "REQUIRED_PACKAGES_NOT_FOUND")
+ SET(requiredPackagesNotFound TRUE)
+ 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)
+ IF(_FS_APPEND)
+ FILE(APPEND "${_FS_FILENAME}" "${_fullText}")
+ ELSE(_FS_APPEND)
+ FILE(WRITE "${_FS_FILENAME}" "${_fullText}")
+ ENDIF()
+
+ ELSE(_FS_FILENAME)
+ IF(NOT _FS_VAR)
+ MESSAGE(STATUS "${_fullText}")
+ ENDIF()
+ ENDIF()
+
+ IF(_FS_VAR)
+ SET(${_FS_VAR} "${_fullText}" PARENT_SCOPE)
+ ENDIF()
+
+ IF(requiredPackagesNotFound AND _FS_FATAL_ON_MISSING_REQUIRED_PACKAGES)
+ MESSAGE(FATAL_ERROR "feature_summary() Error: REQUIRED package(s) are missing, aborting CMake run.")
+ ENDIF()
+
+ENDFUNCTION(FEATURE_SUMMARY)
+
+
+# The stuff below is only kept for compatibility
+
+FUNCTION(SET_PACKAGE_INFO _name _desc)
+ SET(_url "${ARGV2}")
+ SET(_purpose "${ARGV3}")
+ SET_PROPERTY(GLOBAL PROPERTY _CMAKE_${_name}_DESCRIPTION "${_desc}" )
+ IF(_url MATCHES ".+")
+ SET_PROPERTY(GLOBAL PROPERTY _CMAKE_${_name}_URL "${_url}" )
+ ENDIF()
+ IF(_purpose MATCHES ".+")
+ SET_PROPERTY(GLOBAL APPEND PROPERTY _CMAKE_${_name}_PURPOSE "${_purpose}" )
+ ENDIF()
+ENDFUNCTION(SET_PACKAGE_INFO)
+
+
+
+FUNCTION(SET_FEATURE_INFO)
+ SET_PACKAGE_INFO(${ARGN})
+ENDFUNCTION(SET_FEATURE_INFO)
+
+
+
+FUNCTION(PRINT_ENABLED_FEATURES)
+ FEATURE_SUMMARY(WHAT ENABLED_FEATURES DESCRIPTION "Enabled features:")
+ENDFUNCTION(PRINT_ENABLED_FEATURES)
+
+
+
+FUNCTION(PRINT_DISABLED_FEATURES)
+ FEATURE_SUMMARY(WHAT DISABLED_FEATURES DESCRIPTION "Disabled features:")
+ENDFUNCTION(PRINT_DISABLED_FEATURES)
diff --git a/Modules/FindALSA.cmake b/Modules/FindALSA.cmake
new file mode 100644
index 000000000..4a0b69303
--- /dev/null
+++ b/Modules/FindALSA.cmake
@@ -0,0 +1,55 @@
+# - 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
+#
+# 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.
+# Copyright 2009-2011 Philip Lowman <philip@yhbt.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.)
+
+find_path(ALSA_INCLUDE_DIR NAMES alsa/asoundlib.h
+ DOC "The ALSA (asound) include directory"
+)
+
+find_library(ALSA_LIBRARY NAMES asound
+ DOC "The ALSA (asound) library"
+)
+
+if(ALSA_INCLUDE_DIR AND EXISTS "${ALSA_INCLUDE_DIR}/alsa/version.h")
+ file(STRINGS "${ALSA_INCLUDE_DIR}/alsa/version.h" alsa_version_str REGEX "^#define[\t ]+SND_LIB_VERSION_STR[\t ]+\".*\"")
+
+ string(REGEX REPLACE "^.*SND_LIB_VERSION_STR[\t ]+\"([^\"]*)\".*$" "\\1" ALSA_VERSION_STRING "${alsa_version_str}")
+ unset(alsa_version_str)
+endif()
+
+# handle the QUIETLY and REQUIRED arguments and set ALSA_FOUND to TRUE if
+# all listed variables are TRUE
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(ALSA
+ REQUIRED_VARS ALSA_LIBRARY ALSA_INCLUDE_DIR
+ VERSION_VAR ALSA_VERSION_STRING)
+
+if(ALSA_FOUND)
+ set( ALSA_LIBRARIES ${ALSA_LIBRARY} )
+ set( ALSA_INCLUDE_DIRS ${ALSA_INCLUDE_DIR} )
+endif()
+
+mark_as_advanced(ALSA_INCLUDE_DIR ALSA_LIBRARY)
diff --git a/Modules/FindASPELL.cmake b/Modules/FindASPELL.cmake
new file mode 100644
index 000000000..713ab7e19
--- /dev/null
+++ b/Modules/FindASPELL.cmake
@@ -0,0 +1,37 @@
+# - 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
+
+#=============================================================================
+# Copyright 2006-2009 Kitware, Inc.
+# Copyright 2006 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.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+FIND_PATH(ASPELL_INCLUDE_DIR aspell.h )
+
+FIND_PROGRAM(ASPELL_EXECUTABLE
+ NAMES aspell
+)
+
+FIND_LIBRARY(ASPELL_LIBRARIES NAMES aspell aspell-15 libaspell-15 libaspell)
+
+# handle the QUIETLY and REQUIRED arguments and set ASPELL_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(ASPELL DEFAULT_MSG ASPELL_LIBRARIES ASPELL_INCLUDE_DIR ASPELL_EXECUTABLE)
+
+MARK_AS_ADVANCED(ASPELL_INCLUDE_DIR ASPELL_LIBRARIES ASPELL_EXECUTABLE)
diff --git a/Modules/FindAVIFile.cmake b/Modules/FindAVIFile.cmake
new file mode 100644
index 000000000..8b5b05ae3
--- /dev/null
+++ b/Modules/FindAVIFile.cmake
@@ -0,0 +1,48 @@
+# - 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
+
+#=============================================================================
+# 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.)
+
+IF (UNIX)
+
+ FIND_PATH(AVIFILE_INCLUDE_DIR avifile.h
+ /usr/local/avifile/include
+ /usr/local/include/avifile
+ )
+
+ FIND_LIBRARY(AVIFILE_AVIPLAY_LIBRARY aviplay
+ /usr/local/avifile/lib
+ )
+
+ENDIF (UNIX)
+
+# handle the QUIETLY and REQUIRED arguments and set AVIFILE_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(AVIFile DEFAULT_MSG AVIFILE_INCLUDE_DIR AVIFILE_AVIPLAY_LIBRARY)
+
+IF (AVIFILE_FOUND)
+ SET(AVIFILE_LIBRARIES ${AVIFILE_AVIPLAY_LIBRARY})
+ SET(AVIFILE_DEFINITIONS "")
+ENDIF()
+
+MARK_AS_ADVANCED(AVIFILE_INCLUDE_DIR AVIFILE_AVIPLAY_LIBRARY)
diff --git a/Modules/FindArmadillo.cmake b/Modules/FindArmadillo.cmake
new file mode 100644
index 000000000..84ed3cab6
--- /dev/null
+++ b/Modules/FindArmadillo.cmake
@@ -0,0 +1,95 @@
+# - 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})
+# 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")
+
+#=============================================================================
+# Copyright 2011 Clement Creusot <creusot@cs.york.ac.uk>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software 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.)
+
+
+# UNIX paths are standard, no need to write.
+find_library(ARMADILLO_LIBRARY
+ NAMES armadillo
+ PATHS "$ENV{ProgramFiles}/Armadillo/lib" "$ENV{ProgramFiles}/Armadillo/lib64" "$ENV{ProgramFiles}/Armadillo"
+ )
+find_path(ARMADILLO_INCLUDE_DIR
+ NAMES armadillo
+ PATHS "$ENV{ProgramFiles}/Armadillo/include"
+ )
+
+
+if(ARMADILLO_INCLUDE_DIR)
+
+ # ------------------------------------------------------------------------
+ # Extract version information from <armadillo>
+ # ------------------------------------------------------------------------
+
+ # WARNING: Early releases of Armadillo didn't have the arma_version.hpp file.
+ # (e.g. v.0.9.8-1 in ubuntu maverick packages (2001-03-15))
+ # If the file is missing, set all values to 0
+ set(ARMADILLO_VERSION_MAJOR 0)
+ set(ARMADILLO_VERSION_MINOR 0)
+ set(ARMADILLO_VERSION_PATCH 0)
+ set(ARMADILLO_VERSION_NAME "EARLY RELEASE")
+
+ if(EXISTS "${ARMADILLO_INCLUDE_DIR}/armadillo_bits/arma_version.hpp")
+
+ # Read and parse armdillo version header file for version number
+ file(READ "${ARMADILLO_INCLUDE_DIR}/armadillo_bits/arma_version.hpp" _armadillo_HEADER_CONTENTS)
+ string(REGEX REPLACE ".*#define ARMA_VERSION_MAJOR ([0-9]+).*" "\\1" ARMADILLO_VERSION_MAJOR "${_armadillo_HEADER_CONTENTS}")
+ string(REGEX REPLACE ".*#define ARMA_VERSION_MINOR ([0-9]+).*" "\\1" ARMADILLO_VERSION_MINOR "${_armadillo_HEADER_CONTENTS}")
+ string(REGEX REPLACE ".*#define ARMA_VERSION_PATCH ([0-9]+).*" "\\1" ARMADILLO_VERSION_PATCH "${_armadillo_HEADER_CONTENTS}")
+
+ # WARNING: The number of spaces before the version name is not one.
+ string(REGEX REPLACE ".*#define ARMA_VERSION_NAME\ +\"([0-9a-zA-Z\ _-]+)\".*" "\\1" ARMADILLO_VERSION_NAME "${_armadillo_HEADER_CONTENTS}")
+
+ endif(EXISTS "${ARMADILLO_INCLUDE_DIR}/armadillo_bits/arma_version.hpp")
+
+ set(ARMADILLO_VERSION_STRING "${ARMADILLO_VERSION_MAJOR}.${ARMADILLO_VERSION_MINOR}.${ARMADILLO_VERSION_PATCH}")
+endif (ARMADILLO_INCLUDE_DIR)
+
+#======================
+
+
+# Checks 'REQUIRED', 'QUIET' and versions.
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Armadillo
+ REQUIRED_VARS ARMADILLO_LIBRARY ARMADILLO_INCLUDE_DIR
+ VERSION_VAR ARMADILLO_VERSION_STRING)
+# version_var fails with cmake < 2.8.4.
+
+if (ARMADILLO_FOUND)
+ set(ARMADILLO_INCLUDE_DIRS ${ARMADILLO_INCLUDE_DIR})
+ set(ARMADILLO_LIBRARIES ${ARMADILLO_LIBRARY})
+endif (ARMADILLO_FOUND)
+
+
+# Hide internal variables
+mark_as_advanced(
+ ARMADILLO_INCLUDE_DIR
+ ARMADILLO_LIBRARY)
+
+#======================
diff --git a/Modules/FindBISON.cmake b/Modules/FindBISON.cmake
new file mode 100644
index 000000000..7af336788
--- /dev/null
+++ b/Modules/FindBISON.cmake
@@ -0,0 +1,175 @@
+# - Find bison executable and provides macros 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:
+#
+# find_package(BISON)
+# BISON_TARGET(MyParser parser.y ${CMAKE_CURRENT_BINARY_DIR}/parser.cpp)
+# add_executable(Foo main.cpp ${BISON_MyParser_OUTPUTS})
+# ====================================================================
+
+#=============================================================================
+# Copyright 2009 Kitware, Inc.
+# Copyright 2006 Tristan Carel
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software 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(BISON_EXECUTABLE bison DOC "path to the bison executable")
+MARK_AS_ADVANCED(BISON_EXECUTABLE)
+
+IF(BISON_EXECUTABLE)
+ # the bison commands should be executed with the C locale, otherwise
+ # the message (which are parsed) may be translated
+ SET(_Bison_SAVED_LC_ALL "$ENV{LC_ALL}")
+ SET(ENV{LC_ALL} C)
+
+ EXECUTE_PROCESS(COMMAND ${BISON_EXECUTABLE} --version
+ OUTPUT_VARIABLE BISON_version_output
+ ERROR_VARIABLE BISON_version_error
+ RESULT_VARIABLE BISON_version_result
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ SET(ENV{LC_ALL} ${_Bison_SAVED_LC_ALL})
+
+ IF(NOT ${BISON_version_result} EQUAL 0)
+ 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}")
+ # 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}")
+ ENDIF()
+ ENDIF()
+
+ # internal macro
+ MACRO(BISON_TARGET_option_verbose Name BisonOutput filename)
+ LIST(APPEND BISON_TARGET_cmdopt "--verbose")
+ GET_FILENAME_COMPONENT(BISON_TARGET_output_path "${BisonOutput}" PATH)
+ GET_FILENAME_COMPONENT(BISON_TARGET_output_name "${BisonOutput}" NAME_WE)
+ ADD_CUSTOM_COMMAND(OUTPUT ${filename}
+ COMMAND ${CMAKE_COMMAND}
+ ARGS -E copy
+ "${BISON_TARGET_output_path}/${BISON_TARGET_output_name}.output"
+ "${filename}"
+ DEPENDS
+ "${BISON_TARGET_output_path}/${BISON_TARGET_output_name}.output"
+ COMMENT "[BISON][${Name}] Copying bison verbose table to ${filename}"
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
+ SET(BISON_${Name}_VERBOSE_FILE ${filename})
+ LIST(APPEND BISON_TARGET_extraoutputs
+ "${BISON_TARGET_output_path}/${BISON_TARGET_output_name}.output")
+ ENDMACRO(BISON_TARGET_option_verbose)
+
+ # internal macro
+ MACRO(BISON_TARGET_option_extraopts Options)
+ SET(BISON_TARGET_extraopts "${Options}")
+ SEPARATE_ARGUMENTS(BISON_TARGET_extraopts)
+ LIST(APPEND BISON_TARGET_cmdopt ${BISON_TARGET_extraopts})
+ ENDMACRO(BISON_TARGET_option_extraopts)
+
+ #============================================================
+ # BISON_TARGET (public macro)
+ #============================================================
+ #
+ MACRO(BISON_TARGET Name BisonInput BisonOutput)
+ 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)
+ 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()
+ 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()
+ 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}")
+
+ ADD_CUSTOM_COMMAND(OUTPUT ${BISON_TARGET_outputs}
+ ${BISON_TARGET_extraoutputs}
+ COMMAND ${BISON_EXECUTABLE}
+ ARGS ${BISON_TARGET_cmdopt} -o ${ARGV2} ${ARGV1}
+ DEPENDS ${ARGV1}
+ 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}_OUTPUTS ${BISON_TARGET_outputs})
+ SET(BISON_${Name}_COMPILE_FLAGS ${BISON_TARGET_cmdopt})
+ SET(BISON_${Name}_OUTPUT_SOURCE "${BisonOutput}")
+
+ ENDIF(NOT ${ARGC} EQUAL 3 AND NOT ${ARGC} EQUAL 5 AND NOT ${ARGC} EQUAL 7)
+ ENDMACRO(BISON_TARGET)
+ #
+ #============================================================
+
+ENDIF(BISON_EXECUTABLE)
+
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(BISON REQUIRED_VARS BISON_EXECUTABLE
+ VERSION_VAR BISON_VERSION)
+
+# FindBISON.cmake ends here
diff --git a/Modules/FindBLAS.cmake b/Modules/FindBLAS.cmake
new file mode 100644
index 000000000..1cf31c4a6
--- /dev/null
+++ b/Modules/FindBLAS.cmake
@@ -0,0 +1,606 @@
+# - 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
+
+#=============================================================================
+# 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.)
+
+include(CheckFunctionExists)
+include(CheckFortranFunctionExists)
+
+set(_blas_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
+
+# Check the language being used
+get_property( _LANGUAGES_ GLOBAL PROPERTY ENABLED_LANGUAGES )
+if( _LANGUAGES_ MATCHES Fortran )
+ set( _CHECK_FORTRAN TRUE )
+elseif( (_LANGUAGES_ MATCHES C) OR (_LANGUAGES_ MATCHES CXX) )
+ set( _CHECK_FORTRAN FALSE )
+else()
+ if(BLAS_FIND_REQUIRED)
+ message(FATAL_ERROR "FindBLAS requires Fortran, C, or C++ to be enabled.")
+ else(BLAS_FIND_REQUIRED)
+ message(STATUS "Looking for BLAS... - NOT found (Unsupported languages)")
+ return()
+ endif(BLAS_FIND_REQUIRED)
+endif( )
+
+macro(Check_Fortran_Libraries LIBRARIES _prefix _name _flags _list _thread)
+# This macro checks for the existence of the combination of fortran libraries
+# given by _list. If the combination is found, this macro checks (using the
+# Check_Fortran_Function_Exists macro) whether can link against that library
+# combination using the name of a routine given by _name using the linker
+# flags given by _flags. If the combination of libraries is found and passes
+# the link test, LIBRARIES is set to the list of complete library paths that
+# have been found. Otherwise, LIBRARIES is set to FALSE.
+
+# N.B. _prefix is the prefix applied to the names of all cached variables that
+# are generated internally and marked advanced by this macro.
+
+set(_libdir ${ARGN})
+
+set(_libraries_work TRUE)
+set(${LIBRARIES})
+set(_combined_name)
+if (NOT _libdir)
+ if (WIN32)
+ set(_libdir ENV LIB)
+ elseif (APPLE)
+ set(_libdir /usr/local/lib /usr/lib /usr/local/lib64 /usr/lib64 ENV DYLD_LIBRARY_PATH)
+ else ()
+ set(_libdir /usr/local/lib /usr/lib /usr/local/lib64 /usr/lib64 ENV LD_LIBRARY_PATH)
+ endif ()
+endif ()
+
+foreach(_library ${_list})
+ set(_combined_name ${_combined_name}_${_library})
+
+ if(_libraries_work)
+ if (BLA_STATIC)
+ if (WIN32)
+ set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES})
+ endif ( WIN32 )
+ if (APPLE)
+ set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES})
+ else (APPLE)
+ set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
+ endif (APPLE)
+ else (BLA_STATIC)
+ if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ # for ubuntu's libblas3gf and liblapack3gf packages
+ set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES} .so.3gf)
+ endif ()
+ endif (BLA_STATIC)
+ find_library(${_prefix}_${_library}_LIBRARY
+ NAMES ${_library}
+ PATHS ${_libdir}
+ )
+ mark_as_advanced(${_prefix}_${_library}_LIBRARY)
+ set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY})
+ set(_libraries_work ${${_prefix}_${_library}_LIBRARY})
+ endif(_libraries_work)
+endforeach(_library ${_list})
+if(_libraries_work)
+ # Test this combination of libraries.
+ set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}} ${_thread})
+# message("DEBUG: CMAKE_REQUIRED_LIBRARIES = ${CMAKE_REQUIRED_LIBRARIES}")
+ if (_CHECK_FORTRAN)
+ check_fortran_function_exists("${_name}" ${_prefix}${_combined_name}_WORKS)
+ else()
+ check_function_exists("${_name}_" ${_prefix}${_combined_name}_WORKS)
+ endif()
+ set(CMAKE_REQUIRED_LIBRARIES)
+ mark_as_advanced(${_prefix}${_combined_name}_WORKS)
+ set(_libraries_work ${${_prefix}${_combined_name}_WORKS})
+endif(_libraries_work)
+if(NOT _libraries_work)
+ set(${LIBRARIES} FALSE)
+endif(NOT _libraries_work)
+#message("DEBUG: ${LIBRARIES} = ${${LIBRARIES}}")
+endmacro(Check_Fortran_Libraries)
+
+set(BLAS_LINKER_FLAGS)
+set(BLAS_LIBRARIES)
+set(BLAS95_LIBRARIES)
+if ($ENV{BLA_VENDOR} MATCHES ".+")
+ set(BLA_VENDOR $ENV{BLA_VENDOR})
+else ($ENV{BLA_VENDOR} MATCHES ".+")
+ if(NOT BLA_VENDOR)
+ set(BLA_VENDOR "All")
+ endif(NOT BLA_VENDOR)
+endif ($ENV{BLA_VENDOR} MATCHES ".+")
+
+if (BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All")
+ if(NOT BLAS_LIBRARIES)
+ # gotoblas (http://www.tacc.utexas.edu/tacc-projects/gotoblas2)
+ check_fortran_libraries(
+ BLAS_LIBRARIES
+ BLAS
+ sgemm
+ ""
+ "goto2"
+ ""
+ )
+ endif(NOT BLAS_LIBRARIES)
+endif (BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All")
+
+if (BLA_VENDOR STREQUAL "ATLAS" OR BLA_VENDOR STREQUAL "All")
+ if(NOT BLAS_LIBRARIES)
+ # BLAS in ATLAS library? (http://math-atlas.sourceforge.net/)
+ check_fortran_libraries(
+ BLAS_LIBRARIES
+ BLAS
+ dgemm
+ ""
+ "f77blas;atlas"
+ ""
+ )
+ endif(NOT BLAS_LIBRARIES)
+endif (BLA_VENDOR STREQUAL "ATLAS" OR BLA_VENDOR STREQUAL "All")
+
+# BLAS in PhiPACK libraries? (requires generic BLAS lib, too)
+if (BLA_VENDOR STREQUAL "PhiPACK" OR BLA_VENDOR STREQUAL "All")
+ if(NOT BLAS_LIBRARIES)
+ check_fortran_libraries(
+ BLAS_LIBRARIES
+ BLAS
+ sgemm
+ ""
+ "sgemm;dgemm;blas"
+ ""
+ )
+ endif(NOT BLAS_LIBRARIES)
+endif (BLA_VENDOR STREQUAL "PhiPACK" OR BLA_VENDOR STREQUAL "All")
+
+# BLAS in Alpha CXML library?
+if (BLA_VENDOR STREQUAL "CXML" OR BLA_VENDOR STREQUAL "All")
+ if(NOT BLAS_LIBRARIES)
+ check_fortran_libraries(
+ BLAS_LIBRARIES
+ BLAS
+ sgemm
+ ""
+ "cxml"
+ ""
+ )
+ endif(NOT BLAS_LIBRARIES)
+endif (BLA_VENDOR STREQUAL "CXML" OR BLA_VENDOR STREQUAL "All")
+
+# BLAS in Alpha DXML library? (now called CXML, see above)
+if (BLA_VENDOR STREQUAL "DXML" OR BLA_VENDOR STREQUAL "All")
+ if(NOT BLAS_LIBRARIES)
+ check_fortran_libraries(
+ BLAS_LIBRARIES
+ BLAS
+ sgemm
+ ""
+ "dxml"
+ ""
+ )
+ endif(NOT BLAS_LIBRARIES)
+endif (BLA_VENDOR STREQUAL "DXML" OR BLA_VENDOR STREQUAL "All")
+
+# BLAS in Sun Performance library?
+if (BLA_VENDOR STREQUAL "SunPerf" OR BLA_VENDOR STREQUAL "All")
+ if(NOT BLAS_LIBRARIES)
+ check_fortran_libraries(
+ BLAS_LIBRARIES
+ BLAS
+ sgemm
+ "-xlic_lib=sunperf"
+ "sunperf;sunmath"
+ ""
+ )
+ if(BLAS_LIBRARIES)
+ set(BLAS_LINKER_FLAGS "-xlic_lib=sunperf")
+ endif(BLAS_LIBRARIES)
+ endif(NOT BLAS_LIBRARIES)
+endif (BLA_VENDOR STREQUAL "SunPerf" OR BLA_VENDOR STREQUAL "All")
+
+# BLAS in SCSL library? (SGI/Cray Scientific Library)
+if (BLA_VENDOR STREQUAL "SCSL" OR BLA_VENDOR STREQUAL "All")
+ if(NOT BLAS_LIBRARIES)
+ check_fortran_libraries(
+ BLAS_LIBRARIES
+ BLAS
+ sgemm
+ ""
+ "scsl"
+ ""
+ )
+ endif(NOT BLAS_LIBRARIES)
+endif (BLA_VENDOR STREQUAL "SCSL" OR BLA_VENDOR STREQUAL "All")
+
+# BLAS in SGIMATH library?
+if (BLA_VENDOR STREQUAL "SGIMATH" OR BLA_VENDOR STREQUAL "All")
+ if(NOT BLAS_LIBRARIES)
+ check_fortran_libraries(
+ BLAS_LIBRARIES
+ BLAS
+ sgemm
+ ""
+ "complib.sgimath"
+ ""
+ )
+ endif(NOT BLAS_LIBRARIES)
+endif (BLA_VENDOR STREQUAL "SGIMATH" OR BLA_VENDOR STREQUAL "All")
+
+# BLAS in IBM ESSL library? (requires generic BLAS lib, too)
+if (BLA_VENDOR STREQUAL "IBMESSL" OR BLA_VENDOR STREQUAL "All")
+ if(NOT BLAS_LIBRARIES)
+ check_fortran_libraries(
+ BLAS_LIBRARIES
+ BLAS
+ sgemm
+ ""
+ "essl;blas"
+ ""
+ )
+ endif(NOT BLAS_LIBRARIES)
+endif (BLA_VENDOR STREQUAL "IBMESSL" OR BLA_VENDOR STREQUAL "All")
+
+#BLAS in acml library?
+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))
+ )
+ # try to find acml in "standard" paths
+ if( WIN32 )
+ file( GLOB _ACML_ROOT "C:/AMD/acml*/ACML-EULA.txt" )
+ else()
+ file( GLOB _ACML_ROOT "/opt/acml*/ACML-EULA.txt" )
+ endif()
+ if( WIN32 )
+ file( GLOB _ACML_GPU_ROOT "C:/AMD/acml*/GPGPUexamples" )
+ else()
+ file( GLOB _ACML_GPU_ROOT "/opt/acml*/GPGPUexamples" )
+ endif()
+ list(GET _ACML_ROOT 0 _ACML_ROOT)
+ list(GET _ACML_GPU_ROOT 0 _ACML_GPU_ROOT)
+ if( _ACML_ROOT )
+ get_filename_component( _ACML_ROOT ${_ACML_ROOT} PATH )
+ if( SIZEOF_INTEGER EQUAL 8 )
+ set( _ACML_PATH_SUFFIX "_int64" )
+ else()
+ set( _ACML_PATH_SUFFIX "" )
+ endif()
+ if( CMAKE_Fortran_COMPILER_ID STREQUAL "Intel" )
+ set( _ACML_COMPILER32 "ifort32" )
+ set( _ACML_COMPILER64 "ifort64" )
+ elseif( CMAKE_Fortran_COMPILER_ID STREQUAL "SunPro" )
+ set( _ACML_COMPILER32 "sun32" )
+ set( _ACML_COMPILER64 "sun64" )
+ elseif( CMAKE_Fortran_COMPILER_ID STREQUAL "PGI" )
+ set( _ACML_COMPILER32 "pgi32" )
+ if( WIN32 )
+ set( _ACML_COMPILER64 "win64" )
+ else()
+ set( _ACML_COMPILER64 "pgi64" )
+ endif()
+ elseif( CMAKE_Fortran_COMPILER_ID STREQUAL "Open64" )
+ # 32 bit builds not supported on Open64 but for code simplicity
+ # We'll just use the same directory twice
+ set( _ACML_COMPILER32 "open64_64" )
+ set( _ACML_COMPILER64 "open64_64" )
+ elseif( CMAKE_Fortran_COMPILER_ID STREQUAL "NAG" )
+ set( _ACML_COMPILER32 "nag32" )
+ set( _ACML_COMPILER64 "nag64" )
+ else() #if( CMAKE_Fortran_COMPILER_ID STREQUAL "GNU" )
+ set( _ACML_COMPILER32 "gfortran32" )
+ set( _ACML_COMPILER64 "gfortran64" )
+ endif()
+
+ if( BLA_VENDOR STREQUAL "ACML_MP" )
+ set(_ACML_MP_LIB_DIRS
+ "${_ACML_ROOT}/${_ACML_COMPILER32}_mp${_ACML_PATH_SUFFIX}/lib"
+ "${_ACML_ROOT}/${_ACML_COMPILER64}_mp${_ACML_PATH_SUFFIX}/lib" )
+ else() #if( _BLAS_VENDOR STREQUAL "ACML" )
+ set(_ACML_LIB_DIRS
+ "${_ACML_ROOT}/${_ACML_COMPILER32}${_ACML_PATH_SUFFIX}/lib"
+ "${_ACML_ROOT}/${_ACML_COMPILER64}${_ACML_PATH_SUFFIX}/lib" )
+ endif()
+ endif()
+ elseif(BLAS_${BLA_VENDOR}_LIB_DIRS)
+ set(_${BLA_VENDOR}_LIB_DIRS ${BLAS_${BLA_VENDOR}_LIB_DIRS})
+ endif()
+
+ if( BLA_VENDOR STREQUAL "ACML_MP" )
+ foreach( BLAS_ACML_MP_LIB_DIRS ${_ACML_MP_LIB_DIRS})
+ check_fortran_libraries (
+ BLAS_LIBRARIES
+ BLAS
+ sgemm
+ "" "acml_mp;acml_mv" "" ${BLAS_ACML_MP_LIB_DIRS}
+ )
+ if( BLAS_LIBRARIES )
+ break()
+ endif()
+ endforeach()
+ elseif( BLA_VENDOR STREQUAL "ACML_GPU" )
+ foreach( BLAS_ACML_GPU_LIB_DIRS ${_ACML_GPU_LIB_DIRS})
+ check_fortran_libraries (
+ BLAS_LIBRARIES
+ BLAS
+ sgemm
+ "" "acml;acml_mv;CALBLAS" "" ${BLAS_ACML_GPU_LIB_DIRS}
+ )
+ if( BLAS_LIBRARIES )
+ break()
+ endif()
+ endforeach()
+ else() #if( _BLAS_VENDOR STREQUAL "ACML" )
+ foreach( BLAS_ACML_LIB_DIRS ${_ACML_LIB_DIRS} )
+ check_fortran_libraries (
+ BLAS_LIBRARIES
+ BLAS
+ sgemm
+ "" "acml;acml_mv" "" ${BLAS_ACML_LIB_DIRS}
+ )
+ if( BLAS_LIBRARIES )
+ break()
+ endif()
+ endforeach()
+ endif()
+
+ # Either acml or acml_mp should be in LD_LIBRARY_PATH but not both
+ if(NOT BLAS_LIBRARIES)
+ check_fortran_libraries(
+ BLAS_LIBRARIES
+ BLAS
+ sgemm
+ ""
+ "acml;acml_mv"
+ ""
+ )
+ endif(NOT BLAS_LIBRARIES)
+ if(NOT BLAS_LIBRARIES)
+ check_fortran_libraries(
+ BLAS_LIBRARIES
+ BLAS
+ sgemm
+ ""
+ "acml_mp;acml_mv"
+ ""
+ )
+ endif(NOT BLAS_LIBRARIES)
+ if(NOT BLAS_LIBRARIES)
+ check_fortran_libraries(
+ BLAS_LIBRARIES
+ BLAS
+ sgemm
+ ""
+ "acml;acml_mv;CALBLAS"
+ ""
+ )
+ endif(NOT BLAS_LIBRARIES)
+endif () # ACML
+
+# Apple BLAS library?
+if (BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All")
+if(NOT BLAS_LIBRARIES)
+ check_fortran_libraries(
+ BLAS_LIBRARIES
+ BLAS
+ dgemm
+ ""
+ "Accelerate"
+ ""
+ )
+ endif(NOT BLAS_LIBRARIES)
+endif (BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All")
+
+if (BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All")
+ if ( NOT BLAS_LIBRARIES )
+ check_fortran_libraries(
+ BLAS_LIBRARIES
+ BLAS
+ dgemm
+ ""
+ "vecLib"
+ ""
+ )
+ endif ( NOT BLAS_LIBRARIES )
+endif (BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All")
+# Generic BLAS library?
+if (BLA_VENDOR STREQUAL "Generic" OR BLA_VENDOR STREQUAL "All")
+ if(NOT BLAS_LIBRARIES)
+ check_fortran_libraries(
+ BLAS_LIBRARIES
+ BLAS
+ sgemm
+ ""
+ "blas"
+ ""
+ )
+ endif(NOT BLAS_LIBRARIES)
+endif (BLA_VENDOR STREQUAL "Generic" OR BLA_VENDOR STREQUAL "All")
+
+#BLAS in intel mkl 10 library? (em64t 64bit)
+if (BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All")
+ if (NOT WIN32)
+ set(LM "-lm")
+ endif ()
+ if (_LANGUAGES_ MATCHES C OR _LANGUAGES_ MATCHES CXX)
+ if(BLAS_FIND_QUIETLY OR NOT BLAS_FIND_REQUIRED)
+ find_package(Threads)
+ else(BLAS_FIND_QUIETLY OR NOT BLAS_FIND_REQUIRED)
+ find_package(Threads REQUIRED)
+ endif(BLAS_FIND_QUIETLY OR NOT BLAS_FIND_REQUIRED)
+
+ set(BLAS_SEARCH_LIBS "")
+
+ if(BLA_F95)
+ 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")
+ else (WIN32)
+ if (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
+ list(APPEND BLAS_SEARCH_LIBS
+ "mkl_blas95 mkl_intel mkl_intel_thread mkl_core guide")
+ endif ()
+ if (BLA_VENDOR STREQUAL "Intel10_64lp" OR BLA_VENDOR STREQUAL "All")
+ # old version
+ list(APPEND BLAS_SEARCH_LIBS
+ "mkl_blas95 mkl_intel_lp64 mkl_intel_thread mkl_core guide")
+
+ # mkl >= 10.3
+ if (CMAKE_C_COMPILER MATCHES ".+gcc.*")
+ list(APPEND BLAS_SEARCH_LIBS
+ "mkl_blas95_lp64 mkl_intel_lp64 mkl_gnu_thread mkl_core gomp")
+ else ()
+ list(APPEND BLAS_SEARCH_LIBS
+ "mkl_blas95_lp64 mkl_intel_lp64 mkl_intel_thread mkl_core iomp5")
+ endif ()
+ endif ()
+ endif (WIN32)
+ 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")
+ endif ()
+ else (BLA_F95)
+ 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")
+ else (WIN32)
+ if (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
+ list(APPEND BLAS_SEARCH_LIBS
+ "mkl_intel mkl_intel_thread mkl_core guide")
+ endif ()
+ if (BLA_VENDOR STREQUAL "Intel10_64lp" OR BLA_VENDOR STREQUAL "All")
+
+ # old version
+ list(APPEND BLAS_SEARCH_LIBS
+ "mkl_intel_lp64 mkl_intel_thread mkl_core guide")
+
+ # mkl >= 10.3
+ if (CMAKE_C_COMPILER MATCHES ".+gcc.*")
+ list(APPEND BLAS_SEARCH_LIBS
+ "mkl_intel_lp64 mkl_gnu_thread mkl_core gomp")
+ else ()
+ list(APPEND BLAS_SEARCH_LIBS
+ "mkl_intel_lp64 mkl_intel_thread mkl_core iomp5")
+ endif ()
+ endif ()
+
+ #older vesions of intel mkl libs
+ if (BLA_VENDOR STREQUAL "Intel" OR BLA_VENDOR STREQUAL "All")
+ list(APPEND BLAS_SEARCH_LIBS
+ "mkl")
+ list(APPEND BLAS_SEARCH_LIBS
+ "mkl_ia32")
+ list(APPEND BLAS_SEARCH_LIBS
+ "mkl_em64t")
+ endif ()
+ endif (WIN32)
+ 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 (BLA_F95)
+
+ foreach (IT ${BLAS_SEARCH_LIBS})
+ string(REPLACE " " ";" SEARCH_LIBS ${IT})
+ if (${_LIBRARIES})
+ else ()
+ check_fortran_libraries(
+ ${_LIBRARIES}
+ BLAS
+ ${BLAS_mkl_SEARCH_SYMBOL}
+ ""
+ "${SEARCH_LIBS}"
+ "${CMAKE_THREAD_LIBS_INIT};${LM}"
+ )
+ endif ()
+ endforeach ()
+
+ endif (_LANGUAGES_ MATCHES C OR _LANGUAGES_ MATCHES CXX)
+endif (BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All")
+
+
+if(BLA_F95)
+ if(BLAS95_LIBRARIES)
+ set(BLAS95_FOUND TRUE)
+ else(BLAS95_LIBRARIES)
+ set(BLAS95_FOUND FALSE)
+ endif(BLAS95_LIBRARIES)
+
+ if(NOT BLAS_FIND_QUIETLY)
+ if(BLAS95_FOUND)
+ message(STATUS "A library with BLAS95 API found.")
+ else(BLAS95_FOUND)
+ if(BLAS_FIND_REQUIRED)
+ message(FATAL_ERROR
+ "A required library with BLAS95 API not found. Please specify library location.")
+ else(BLAS_FIND_REQUIRED)
+ message(STATUS
+ "A library with BLAS95 API not found. Please specify library location.")
+ endif(BLAS_FIND_REQUIRED)
+ endif(BLAS95_FOUND)
+ endif(NOT BLAS_FIND_QUIETLY)
+ set(BLAS_FOUND TRUE)
+ set(BLAS_LIBRARIES "${BLAS95_LIBRARIES}")
+else(BLA_F95)
+ if(BLAS_LIBRARIES)
+ set(BLAS_FOUND TRUE)
+ else(BLAS_LIBRARIES)
+ set(BLAS_FOUND FALSE)
+ endif(BLAS_LIBRARIES)
+
+ if(NOT BLAS_FIND_QUIETLY)
+ if(BLAS_FOUND)
+ message(STATUS "A library with BLAS API found.")
+ else(BLAS_FOUND)
+ if(BLAS_FIND_REQUIRED)
+ message(FATAL_ERROR
+ "A required library with BLAS API not found. Please specify library location."
+ )
+ else(BLAS_FIND_REQUIRED)
+ message(STATUS
+ "A library with BLAS API not found. Please specify library location."
+ )
+ endif(BLAS_FIND_REQUIRED)
+ endif(BLAS_FOUND)
+ endif(NOT BLAS_FIND_QUIETLY)
+endif(BLA_F95)
+
+set(CMAKE_FIND_LIBRARY_SUFFIXES ${_blas_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
diff --git a/Modules/FindBZip2.cmake b/Modules/FindBZip2.cmake
new file mode 100644
index 000000000..ce7f2555d
--- /dev/null
+++ b/Modules/FindBZip2.cmake
@@ -0,0 +1,56 @@
+# - 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)
+
+#=============================================================================
+# Copyright 2006-2012 Kitware, Inc.
+# Copyright 2006 Alexander Neundorf <neundorf@kde.org>
+# Copyright 2012 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.)
+
+SET(_BZIP2_PATHS PATHS
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\GnuWin32\\Bzip2;InstallPath]"
+ )
+
+FIND_PATH(BZIP2_INCLUDE_DIR bzlib.h ${_BZIP2_PATHS} PATH_SUFFIXES include)
+
+IF (NOT BZIP2_LIBRARIES)
+ FIND_LIBRARY(BZIP2_LIBRARY_RELEASE NAMES bz2 bzip2 ${_BZIP2_PATHS} PATH_SUFFIXES lib)
+ FIND_LIBRARY(BZIP2_LIBRARY_DEBUG NAMES bzip2d ${_BZIP2_PATHS} PATH_SUFFIXES lib)
+
+ INCLUDE(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
+ SELECT_LIBRARY_CONFIGURATIONS(BZIP2)
+ENDIF (NOT BZIP2_LIBRARIES)
+
+IF (BZIP2_INCLUDE_DIR AND EXISTS "${BZIP2_INCLUDE_DIR}/bzlib.h")
+ FILE(STRINGS "${BZIP2_INCLUDE_DIR}/bzlib.h" BZLIB_H REGEX "bzip2/libbzip2 version [0-9]+\\.[^ ]+ of [0-9]+ ")
+ STRING(REGEX REPLACE ".* bzip2/libbzip2 version ([0-9]+\\.[^ ]+) of [0-9]+ .*" "\\1" BZIP2_VERSION_STRING "${BZLIB_H}")
+ENDIF (BZIP2_INCLUDE_DIR AND EXISTS "${BZIP2_INCLUDE_DIR}/bzlib.h")
+
+# handle the QUIETLY and REQUIRED arguments and set BZip2_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(BZip2
+ REQUIRED_VARS BZIP2_LIBRARIES BZIP2_INCLUDE_DIR
+ VERSION_VAR BZIP2_VERSION_STRING)
+
+IF (BZIP2_FOUND)
+ INCLUDE(CheckLibraryExists)
+ CHECK_LIBRARY_EXISTS("${BZIP2_LIBRARIES}" BZ2_bzCompressInit "" BZIP2_NEED_PREFIX)
+ENDIF (BZIP2_FOUND)
+
+MARK_AS_ADVANCED(BZIP2_INCLUDE_DIR)
diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake
new file mode 100644
index 000000000..ad6b1598d
--- /dev/null
+++ b/Modules/FindBoost.cmake
@@ -0,0 +1,1211 @@
+# - Try to find Boost include dirs and libraries
+# Usage of this module as follows:
+#
+# NOTE: Take note of the Boost_ADDITIONAL_VERSIONS variable below.
+# Due to Boost naming conventions and limitations in CMake this find
+# module is NOT future safe with respect to Boost version numbers,
+# and may break.
+#
+# == Using Header-Only libraries from within Boost: ==
+#
+# find_package( Boost 1.36.0 )
+# if(Boost_FOUND)
+# include_directories(${Boost_INCLUDE_DIRS})
+# add_executable(foo foo.cc)
+# endif()
+#
+#
+# == Using actual libraries from within Boost: ==
+#
+# 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()
+#
+#
+# The components list needs to contain actual names of boost libraries only,
+# such as "date_time" for "libboost_date_time". If you're using parts of
+# Boost that contain header files only (e.g. foreach) you do not need to
+# specify COMPONENTS.
+#
+# You should provide a minimum version number that should be used. If you provide this
+# version number and specify the REQUIRED attribute, this module will fail if it
+# can't find the specified or a later version. If you specify a version number this is
+# automatically put into the considered list of version numbers and thus doesn't need
+# to be specified in the Boost_ADDITIONAL_VERSIONS variable (see below).
+#
+# NOTE for Visual Studio Users:
+# Automatic linking is used on MSVC & Borland compilers by default when
+# #including things in Boost. It's important to note that setting
+# Boost_USE_STATIC_LIBS to OFF is NOT enough to get you dynamic linking,
+# should you need this feature. Automatic linking typically uses static
+# libraries with a few exceptions (Boost.Python is one).
+#
+# Please see the section below near Boost_LIB_DIAGNOSTIC_DEFINITIONS for
+# more details. Adding a TARGET_LINK_LIBRARIES() as shown in the example
+# above appears to cause VS to link dynamically if Boost_USE_STATIC_LIBS
+# gets set to OFF. It is suggested you avoid automatic linking since it
+# will make your application less portable.
+#
+# =========== The mess that is Boost_ADDITIONAL_VERSIONS (sorry?) ============
+#
+# OK, so the Boost_ADDITIONAL_VERSIONS variable can be used to specify a list of
+# boost version numbers that should be taken into account when searching
+# for Boost. Unfortunately boost puts the version number into the
+# actual filename for the libraries, so this variable will certainly be needed
+# in the future when new Boost versions are released.
+#
+# Currently this module searches for the following version numbers:
+# 1.33, 1.33.0, 1.33.1, 1.34, 1.34.0, 1.34.1, 1.35, 1.35.0, 1.35.1,
+# 1.36, 1.36.0, 1.36.1, 1.37, 1.37.0, 1.38, 1.38.0, 1.39, 1.39.0,
+# 1.40, 1.40.0, 1.41, 1.41.0, 1.42, 1.42.0, 1.43, 1.43.0, 1.44, 1.44.0,
+# 1.45, 1.45.0, 1.46, 1.46.0, 1.46.1, 1.47, 1.47.0, 1.48, 1.48.0,
+# 1.49, 1.49.0, 1.50, 1.50.0, 1.51, 1.51.0, 1.52, 1.52.0,
+# 1.53, 1.53.0, 1.54, 1.54.0, 1.55, 1.55.0, 1.56, 1.56.0
+#
+# NOTE: If you add a new major 1.x version in Boost_ADDITIONAL_VERSIONS you should
+# add both 1.x and 1.x.0 as shown above. Official Boost include directories
+# omit the 3rd version number from include paths if it is 0 although not all
+# binary Boost releases do so.
+#
+# set(Boost_ADDITIONAL_VERSIONS "1.78" "1.78.0" "1.79" "1.79.0")
+#
+# ===================================== ============= ========================
+#
+# Variables used by this module, they can change the default behaviour and
+# need to be set before calling find_package:
+#
+# Boost_USE_MULTITHREADED Can be set to OFF to use the non-multithreaded
+# boost libraries. If not specified, defaults
+# to ON.
+#
+# Boost_USE_STATIC_LIBS Can be set to ON to force the use of the static
+# boost libraries. Defaults to OFF.
+#
+# Boost_NO_SYSTEM_PATHS Set to TRUE to suppress searching in system
+# paths (or other locations outside of BOOST_ROOT
+# or BOOST_INCLUDEDIR). Useful when specifying
+# BOOST_ROOT. Defaults to OFF.
+# [Since CMake 2.8.3]
+#
+# Boost_NO_BOOST_CMAKE Do not do a find_package call in config mode
+# before searching for a regular boost install.
+# This will avoid finding boost-cmake installs.
+# Defaults to OFF.
+# [Since CMake 2.8.6]
+#
+# Boost_USE_STATIC_RUNTIME If enabled, searches for boost libraries
+# linked against a static C++ standard library
+# ('s' ABI tag). This option should be set to
+# ON or OFF because the default behavior
+# if not specified is platform dependent
+# for backwards compatibility.
+# [Since CMake 2.8.3]
+#
+# Boost_USE_DEBUG_PYTHON If enabled, searches for boost libraries
+# compiled against a special debug build of
+# Python ('y' ABI tag). Defaults to OFF.
+# [Since CMake 2.8.3]
+#
+# Boost_USE_STLPORT If enabled, searches for boost libraries
+# compiled against the STLPort standard
+# library ('p' ABI tag). Defaults to OFF.
+# [Since CMake 2.8.3]
+#
+# Boost_USE_STLPORT_DEPRECATED_NATIVE_IOSTREAMS
+# If enabled, searches for boost libraries
+# compiled against the deprecated STLPort
+# "native iostreams" feature ('n' ABI tag).
+# Defaults to OFF.
+# [Since CMake 2.8.3]
+#
+# Other Variables used by this module which you may want to set.
+#
+# Boost_ADDITIONAL_VERSIONS A list of version numbers to use for searching
+# the boost include directory. Please see
+# the documentation above regarding this
+# annoying, but necessary variable :(
+#
+# Boost_DEBUG Set this to TRUE to enable debugging output
+# of FindBoost.cmake if you are having problems.
+# Please enable this before filing any bug
+# reports.
+#
+# Boost_DETAILED_FAILURE_MSG FindBoost doesn't output detailed information
+# about why it failed or how to fix the problem
+# unless this is set to TRUE or the REQUIRED
+# keyword is specified in find_package().
+# [Since CMake 2.8.0]
+#
+# Boost_COMPILER Set this to the compiler suffix used by Boost
+# (e.g. "-gcc43") if FindBoost has problems finding
+# the proper Boost installation
+#
+# Boost_THREADAPI When building boost.thread, sometimes the name of the
+# library contains an additional "pthread" or "win32"
+# string known as the threadapi. This can happen when
+# compiling against pthreads on Windows or win32 threads
+# on Cygwin. You may specify this variable and if set
+# when FindBoost searches for the Boost threading library
+# it will first try to match the threadapi you specify.
+# For Example: libboost_thread_win32-mgw45-mt-1_43.a
+# might be found if you specified "win32" here before
+# falling back on libboost_thread-mgw45-mt-1_43.a.
+# [Since CMake 2.8.3]
+#
+# Boost_REALPATH Resolves symbolic links for discovered boost libraries
+# to assist with packaging. For example, instead of
+# Boost_SYSTEM_LIBRARY_RELEASE being resolved to
+# "/usr/lib/libboost_system.so" it would be
+# "/usr/lib/libboost_system.so.1.42.0" instead.
+# This does not affect linking and should not be
+# enabled unless the user needs this information.
+# [Since CMake 2.8.3]
+#
+
+
+#
+# These last three variables are available also as environment variables:
+# Also, note they are completely UPPERCASE, except Boost_DIR.
+#
+# Boost_DIR or The preferred installation prefix for searching for
+# BOOST_ROOT or BOOSTROOT Boost. Set this if the module has problems finding
+# the proper Boost installation.
+#
+# Note that Boost_DIR behaves exactly as <package>_DIR
+# variables are documented to behave in find_package's
+# Config mode. That is, if it is set as a -D argument
+# to CMake, it must point to the location of the
+# BoostConfig.cmake or Boost-config.cmake file. If it
+# is set as an environment variable, it must point to
+# the root of the boost installation. BOOST_ROOT and
+# BOOSTROOT, on the other hand, will point to the root
+# in either case.
+#
+# To prevent falling back on the system paths, set
+# Boost_NO_SYSTEM_PATHS to true.
+#
+# To avoid finding boost-cmake installations, set
+# Boost_NO_BOOST_CMAKE to true.
+#
+# BOOST_INCLUDEDIR Set this to the include directory of Boost, if the
+# module has problems finding the proper Boost installation
+#
+# BOOST_LIBRARYDIR Set this to the lib directory of Boost, if the
+# module has problems finding the proper Boost installation
+#
+# Variables defined by this module:
+#
+# Boost_FOUND System has Boost, this means the include dir was
+# found, as well as all the libraries specified in
+# the COMPONENTS list.
+#
+# Boost_INCLUDE_DIRS Boost include directories: not cached
+#
+# Boost_INCLUDE_DIR This is almost the same as above, but this one is
+# cached and may be modified by advanced users
+#
+# Boost_LIBRARIES Link to these to use the Boost libraries that you
+# specified: not cached
+#
+# Boost_LIBRARY_DIRS The path to where the Boost library files are.
+#
+# Boost_VERSION The version number of the boost libraries that
+# have been found, same as in version.hpp from Boost
+#
+# Boost_LIB_VERSION The version number in filename form as
+# it's appended to the library filenames
+#
+# Boost_MAJOR_VERSION major version number of boost
+# Boost_MINOR_VERSION minor version number of boost
+# Boost_SUBMINOR_VERSION subminor version number of boost
+#
+# Boost_LIB_DIAGNOSTIC_DEFINITIONS [WIN32 Only] You can call
+# add_definitions(${Boost_LIB_DIAGNOSTIC_DEFINITIONS})
+# to have diagnostic information about Boost's
+# automatic linking outputted during compilation time.
+#
+# For each component you specify in find_package(), the following (UPPER-CASE)
+# variables are set. You can use these variables if you would like to pick and
+# choose components for your targets instead of just using Boost_LIBRARIES.
+#
+# Boost_${COMPONENT}_FOUND True IF the Boost library "component" was found.
+#
+# Boost_${COMPONENT}_LIBRARY Contains the libraries for the specified Boost
+# "component" (includes debug and optimized keywords
+# when needed).
+
+#=============================================================================
+# Copyright 2006-2009 Kitware, Inc.
+# Copyright 2006-2008 Andreas Schneider <mail@cynapses.org>
+# Copyright 2007 Wengo
+# Copyright 2007 Mike Jackson
+# Copyright 2008 Andreas Pakulat <apaku@gmx.de>
+# Copyright 2008-2012 Philip Lowman <philip@yhbt.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.)
+
+
+#-------------------------------------------------------------------------------
+# Before we go searching, check whether boost-cmake is avaialble, unless the
+# user specifically asked NOT to search for boost-cmake.
+#
+# If Boost_DIR is set, this behaves as any find_package call would. If not,
+# it looks at BOOST_ROOT and BOOSTROOT to find Boost.
+#
+if (NOT Boost_NO_BOOST_CMAKE)
+ # If Boost_DIR is not set, look for BOOSTROOT and BOOST_ROOT as alternatives,
+ # since these are more conventional for Boost.
+ if ("$ENV{Boost_DIR}" STREQUAL "")
+ if (NOT "$ENV{BOOST_ROOT}" STREQUAL "")
+ set(ENV{Boost_DIR} $ENV{BOOST_ROOT})
+ elseif (NOT "$ENV{BOOSTROOT}" STREQUAL "")
+ set(ENV{Boost_DIR} $ENV{BOOSTROOT})
+ endif()
+ endif()
+
+ # Do the same find_package call but look specifically for the CMake version.
+ # Note that args are passed in the Boost_FIND_xxxxx variables, so there is no
+ # need to delegate them to this find_package call.
+ find_package(Boost QUIET NO_MODULE)
+
+ # If we found boost-cmake, then we're done. Print out what we found.
+ # Otherwise let the rest of the module try to find it.
+ if (Boost_FOUND)
+ message("Boost ${Boost_FIND_VERSION} found.")
+ if (Boost_FIND_COMPONENTS)
+ message("Found Boost components:")
+ message(" ${Boost_FIND_COMPONENTS}")
+ endif()
+ return()
+ endif()
+endif()
+
+
+#-------------------------------------------------------------------------------
+# FindBoost functions & macros
+#
+
+############################################
+#
+# Check the existence of the libraries.
+#
+############################################
+# This macro was taken directly from the FindQt4.cmake file that is included
+# with the CMake distribution. This is NOT my work. All work was done by the
+# original authors of the FindQt4.cmake file. Only minor modifications were
+# made to remove references to Qt and make this file more generally applicable
+# And ELSE/ENDIF pairs were removed for readability.
+#########################################################################
+
+macro(_Boost_ADJUST_LIB_VARS basename)
+ if(Boost_INCLUDE_DIR )
+ if(Boost_${basename}_LIBRARY_DEBUG AND Boost_${basename}_LIBRARY_RELEASE)
+ # if the generator supports configuration types then set
+ # optimized and debug libraries, or if the CMAKE_BUILD_TYPE has a value
+ if(CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE)
+ set(Boost_${basename}_LIBRARY optimized ${Boost_${basename}_LIBRARY_RELEASE} debug ${Boost_${basename}_LIBRARY_DEBUG})
+ else()
+ # if there are no configuration types and CMAKE_BUILD_TYPE has no value
+ # then just use the release libraries
+ set(Boost_${basename}_LIBRARY ${Boost_${basename}_LIBRARY_RELEASE} )
+ endif()
+ # FIXME: This probably should be set for both cases
+ set(Boost_${basename}_LIBRARIES optimized ${Boost_${basename}_LIBRARY_RELEASE} debug ${Boost_${basename}_LIBRARY_DEBUG})
+ endif()
+
+ # if only the release version was found, set the debug variable also to the release version
+ if(Boost_${basename}_LIBRARY_RELEASE AND NOT Boost_${basename}_LIBRARY_DEBUG)
+ set(Boost_${basename}_LIBRARY_DEBUG ${Boost_${basename}_LIBRARY_RELEASE})
+ set(Boost_${basename}_LIBRARY ${Boost_${basename}_LIBRARY_RELEASE})
+ set(Boost_${basename}_LIBRARIES ${Boost_${basename}_LIBRARY_RELEASE})
+ endif()
+
+ # if only the debug version was found, set the release variable also to the debug version
+ if(Boost_${basename}_LIBRARY_DEBUG AND NOT Boost_${basename}_LIBRARY_RELEASE)
+ set(Boost_${basename}_LIBRARY_RELEASE ${Boost_${basename}_LIBRARY_DEBUG})
+ set(Boost_${basename}_LIBRARY ${Boost_${basename}_LIBRARY_DEBUG})
+ set(Boost_${basename}_LIBRARIES ${Boost_${basename}_LIBRARY_DEBUG})
+ endif()
+
+ # If the debug & release library ends up being the same, omit the keywords
+ if(${Boost_${basename}_LIBRARY_RELEASE} STREQUAL ${Boost_${basename}_LIBRARY_DEBUG})
+ set(Boost_${basename}_LIBRARY ${Boost_${basename}_LIBRARY_RELEASE} )
+ set(Boost_${basename}_LIBRARIES ${Boost_${basename}_LIBRARY_RELEASE} )
+ endif()
+
+ if(Boost_${basename}_LIBRARY)
+ set(Boost_${basename}_LIBRARY ${Boost_${basename}_LIBRARY} CACHE FILEPATH "The Boost ${basename} library")
+
+ # Remove superfluous "debug" / "optimized" keywords from
+ # Boost_LIBRARY_DIRS
+ foreach(_boost_my_lib ${Boost_${basename}_LIBRARY})
+ get_filename_component(_boost_my_lib_path "${_boost_my_lib}" PATH)
+ list(APPEND Boost_LIBRARY_DIRS ${_boost_my_lib_path})
+ endforeach()
+ list(REMOVE_DUPLICATES Boost_LIBRARY_DIRS)
+
+ set(Boost_LIBRARY_DIRS ${Boost_LIBRARY_DIRS} CACHE FILEPATH "Boost library directory")
+ set(Boost_${basename}_FOUND ON CACHE INTERNAL "Whether the Boost ${basename} library found")
+ endif(Boost_${basename}_LIBRARY)
+
+ endif(Boost_INCLUDE_DIR )
+ # Make variables changeble to the advanced user
+ mark_as_advanced(
+ Boost_${basename}_LIBRARY
+ Boost_${basename}_LIBRARY_RELEASE
+ Boost_${basename}_LIBRARY_DEBUG
+ )
+endmacro(_Boost_ADJUST_LIB_VARS)
+
+#-------------------------------------------------------------------------------
+
+#
+# Runs compiler with "-dumpversion" and parses major/minor
+# version with a regex.
+#
+function(_Boost_COMPILER_DUMPVERSION _OUTPUT_VERSION)
+
+ exec_program(${CMAKE_CXX_COMPILER}
+ ARGS ${CMAKE_CXX_COMPILER_ARG1} -dumpversion
+ OUTPUT_VARIABLE _boost_COMPILER_VERSION
+ )
+ string(REGEX REPLACE "([0-9])\\.([0-9])(\\.[0-9])?" "\\1\\2"
+ _boost_COMPILER_VERSION ${_boost_COMPILER_VERSION})
+
+ set(${_OUTPUT_VERSION} ${_boost_COMPILER_VERSION} PARENT_SCOPE)
+endfunction()
+
+#
+# A convenience function for marking desired components
+# as found or not
+#
+function(_Boost_MARK_COMPONENTS_FOUND _yes_or_no)
+ foreach(COMPONENT ${Boost_FIND_COMPONENTS})
+ string(TOUPPER ${COMPONENT} UPPERCOMPONENT)
+ set(Boost_${UPPERCOMPONENT}_FOUND ${_yes_or_no} CACHE INTERNAL "Whether the Boost ${COMPONENT} library found" FORCE)
+ endforeach()
+endfunction()
+
+#
+# Take a list of libraries with "thread" in it
+# and prepend duplicates with "thread_${Boost_THREADAPI}"
+# at the front of the list
+#
+function(_Boost_PREPEND_LIST_WITH_THREADAPI _output)
+ set(_orig_libnames ${ARGN})
+ string(REPLACE "thread" "thread_${Boost_THREADAPI}" _threadapi_libnames "${_orig_libnames}")
+ set(${_output} ${_threadapi_libnames} ${_orig_libnames} PARENT_SCOPE)
+endfunction()
+
+#
+# If a library is found, replace its cache entry with its REALPATH
+#
+function(_Boost_SWAP_WITH_REALPATH _library _docstring)
+ if(${_library})
+ get_filename_component(_boost_filepathreal ${${_library}} REALPATH)
+ unset(${_library} CACHE)
+ set(${_library} ${_boost_filepathreal} CACHE FILEPATH "${_docstring}")
+ endif()
+endfunction()
+
+function(_Boost_CHECK_SPELLING _var)
+ if(${_var})
+ string(TOUPPER ${_var} _var_UC)
+ message(FATAL_ERROR "ERROR: ${_var} is not the correct spelling. The proper spelling is ${_var_UC}.")
+ endif()
+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(WIN32)
+ set (_boost_COMPILER "-iw")
+ else()
+ set (_boost_COMPILER "-il")
+ endif()
+ elseif (MSVC11)
+ set(_boost_COMPILER "-vc110")
+ elseif (MSVC10)
+ set(_boost_COMPILER "-vc100")
+ elseif (MSVC90)
+ set(_boost_COMPILER "-vc90")
+ elseif (MSVC80)
+ set(_boost_COMPILER "-vc80")
+ elseif (MSVC71)
+ set(_boost_COMPILER "-vc71")
+ elseif (MSVC70) # Good luck!
+ set(_boost_COMPILER "-vc7") # yes, this is correct
+ elseif (MSVC60) # Good luck!
+ set(_boost_COMPILER "-vc6") # yes, this is correct
+ elseif (BORLAND)
+ set(_boost_COMPILER "-bcb")
+ elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "SunPro")
+ set(_boost_COMPILER "-sw")
+ elseif (MINGW)
+ if(${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION} VERSION_LESS 1.34)
+ set(_boost_COMPILER "-mgw") # no GCC version encoding prior to 1.34
+ else()
+ _Boost_COMPILER_DUMPVERSION(_boost_COMPILER_VERSION)
+ set(_boost_COMPILER "-mgw${_boost_COMPILER_VERSION}")
+ endif()
+ elseif (UNIX)
+ if (CMAKE_COMPILER_IS_GNUCXX)
+ if(${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION} VERSION_LESS 1.34)
+ set(_boost_COMPILER "-gcc") # no GCC version encoding prior to 1.34
+ else()
+ _Boost_COMPILER_DUMPVERSION(_boost_COMPILER_VERSION)
+ # Determine which version of GCC we have.
+ if(APPLE)
+ if(Boost_MINOR_VERSION)
+ if(${Boost_MINOR_VERSION} GREATER 35)
+ # In Boost 1.36.0 and newer, the mangled compiler name used
+ # on Mac OS X/Darwin is "xgcc".
+ set(_boost_COMPILER "-xgcc${_boost_COMPILER_VERSION}")
+ else(${Boost_MINOR_VERSION} GREATER 35)
+ # In Boost <= 1.35.0, there is no mangled compiler name for
+ # the Mac OS X/Darwin version of GCC.
+ set(_boost_COMPILER "")
+ endif(${Boost_MINOR_VERSION} GREATER 35)
+ else(Boost_MINOR_VERSION)
+ # We don't know the Boost version, so assume it's
+ # pre-1.36.0.
+ set(_boost_COMPILER "")
+ endif(Boost_MINOR_VERSION)
+ else()
+ set(_boost_COMPILER "-gcc${_boost_COMPILER_VERSION}")
+ endif()
+ endif()
+ endif (CMAKE_COMPILER_IS_GNUCXX)
+ else()
+ # TODO at least Boost_DEBUG here?
+ set(_boost_COMPILER "")
+ endif()
+ set(${_ret} ${_boost_COMPILER} PARENT_SCOPE)
+endfunction()
+
+#
+# End functions/macros
+#
+#-------------------------------------------------------------------------------
+
+#-------------------------------------------------------------------------------
+# main.
+#-------------------------------------------------------------------------------
+
+if(NOT DEFINED Boost_USE_MULTITHREADED)
+ set(Boost_USE_MULTITHREADED TRUE)
+endif()
+
+# Check the version of Boost against the requested version.
+if(Boost_FIND_VERSION AND NOT Boost_FIND_VERSION_MINOR)
+ message(SEND_ERROR "When requesting a specific version of Boost, you must provide at least the major and minor version numbers, e.g., 1.34")
+endif()
+
+if(Boost_FIND_VERSION_EXACT)
+ # The version may appear in a directory with or without the patch
+ # level, even when the patch level is non-zero.
+ set(_boost_TEST_VERSIONS
+ "${Boost_FIND_VERSION_MAJOR}.${Boost_FIND_VERSION_MINOR}.${Boost_FIND_VERSION_PATCH}"
+ "${Boost_FIND_VERSION_MAJOR}.${Boost_FIND_VERSION_MINOR}")
+else(Boost_FIND_VERSION_EXACT)
+ # The user has not requested an exact version. Among known
+ # versions, find those that are acceptable to the user request.
+ 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.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}")
+ # Select acceptable versions.
+ foreach(version ${_Boost_KNOWN_VERSIONS})
+ if(NOT "${version}" VERSION_LESS "${Boost_FIND_VERSION}")
+ # This version is high enough.
+ list(APPEND _boost_TEST_VERSIONS "${version}")
+ elseif("${version}.99" VERSION_EQUAL "${_Boost_FIND_VERSION_SHORT}.99")
+ # This version is a short-form for the requested version with
+ # the patch level dropped.
+ list(APPEND _boost_TEST_VERSIONS "${version}")
+ endif()
+ endforeach(version)
+ else(Boost_FIND_VERSION)
+ # Any version is acceptable.
+ set(_boost_TEST_VERSIONS "${_Boost_KNOWN_VERSIONS}")
+ endif(Boost_FIND_VERSION)
+endif(Boost_FIND_VERSION_EXACT)
+
+# The reason that we failed to find Boost. This will be set to a
+# user-friendly message when we fail to find some necessary piece of
+# Boost.
+set(Boost_ERROR_REASON)
+
+ if(Boost_DEBUG)
+ # Output some of their choices
+ message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+ "_boost_TEST_VERSIONS = ${_boost_TEST_VERSIONS}")
+ message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+ "Boost_USE_MULTITHREADED = ${Boost_USE_MULTITHREADED}")
+ message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+ "Boost_USE_STATIC_LIBS = ${Boost_USE_STATIC_LIBS}")
+ message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+ "Boost_USE_STATIC_RUNTIME = ${Boost_USE_STATIC_RUNTIME}")
+ message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+ "Boost_ADDITIONAL_VERSIONS = ${Boost_ADDITIONAL_VERSIONS}")
+ message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+ "Boost_NO_SYSTEM_PATHS = ${Boost_NO_SYSTEM_PATHS}")
+ 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
+ # runtime, then you can choose to link to either a static or a
+ # dynamic Boost library, the default is to do a static link. You
+ # can alter this for a specific library "whatever" by defining
+ # BOOST_WHATEVER_DYN_LINK to force Boost library "whatever" to be
+ # linked dynamically. Alternatively you can force all Boost
+ # libraries to dynamic link by defining BOOST_ALL_DYN_LINK.
+
+ # This feature can be disabled for Boost library "whatever" by
+ # defining BOOST_WHATEVER_NO_LIB, or for all of Boost by defining
+ # BOOST_ALL_NO_LIB.
+
+ # If you want to observe which libraries are being linked against
+ # then defining BOOST_LIB_DIAGNOSTIC will cause the auto-linking
+ # code to emit a #pragma message each time a library is selected
+ # for linking.
+ set(Boost_LIB_DIAGNOSTIC_DEFINITIONS
+ "-DBOOST_LIB_DIAGNOSTIC" CACHE STRING "Boost diagnostic define")
+ endif(WIN32)
+
+ set(_boost_INCLUDE_SEARCH_DIRS_SYSTEM
+ C:/boost/include
+ C:/boost
+ "$ENV{ProgramFiles}/boost/include"
+ "$ENV{ProgramFiles}/boost"
+ /sw/local/include
+ )
+
+ _Boost_CHECK_SPELLING(Boost_ROOT)
+ _Boost_CHECK_SPELLING(Boost_LIBRARYDIR)
+ _Boost_CHECK_SPELLING(Boost_INCLUDEDIR)
+
+ # If BOOST_ROOT was defined in the environment, use it.
+ if (NOT BOOST_ROOT AND NOT $ENV{Boost_DIR} STREQUAL "")
+ set(BOOST_ROOT $ENV{Boost_DIR})
+ endif()
+
+ # If BOOST_ROOT was defined in the environment, use it.
+ if (NOT BOOST_ROOT AND NOT $ENV{BOOST_ROOT} STREQUAL "")
+ set(BOOST_ROOT $ENV{BOOST_ROOT})
+ endif()
+
+ # If BOOSTROOT was defined in the environment, use it.
+ if (NOT BOOST_ROOT AND NOT $ENV{BOOSTROOT} STREQUAL "")
+ set(BOOST_ROOT $ENV{BOOSTROOT})
+ endif()
+
+ # If BOOST_INCLUDEDIR was defined in the environment, use it.
+ if( NOT $ENV{BOOST_INCLUDEDIR} STREQUAL "" )
+ set(BOOST_INCLUDEDIR $ENV{BOOST_INCLUDEDIR})
+ endif()
+
+ # If BOOST_LIBRARYDIR was defined in the environment, use it.
+ if( NOT $ENV{BOOST_LIBRARYDIR} STREQUAL "" )
+ set(BOOST_LIBRARYDIR $ENV{BOOST_LIBRARYDIR})
+ endif()
+
+ if( BOOST_ROOT )
+ file(TO_CMAKE_PATH ${BOOST_ROOT} BOOST_ROOT)
+ endif()
+
+ if(Boost_DEBUG)
+ message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+ "Declared as CMake or Environmental Variables:")
+ message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+ " BOOST_ROOT = ${BOOST_ROOT}")
+ message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+ " BOOST_INCLUDEDIR = ${BOOST_INCLUDEDIR}")
+ message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+ " BOOST_LIBRARYDIR = ${BOOST_LIBRARYDIR}")
+ message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+ "_boost_TEST_VERSIONS = ${_boost_TEST_VERSIONS}")
+ endif()
+
+ if( Boost_NO_SYSTEM_PATHS)
+ set(_boost_FIND_OPTIONS NO_CMAKE_SYSTEM_PATH)
+ else()
+ set(_boost_INCLUDE_SEARCH_DIRS ${_boost_INCLUDE_SEARCH_DIRS_SYSTEM})
+ endif()
+
+ if( BOOST_ROOT )
+ set(_boost_INCLUDE_SEARCH_DIRS
+ ${BOOST_ROOT}/include
+ ${BOOST_ROOT}
+ ${_boost_INCLUDE_SEARCH_DIRS})
+ endif()
+
+ # prepend BOOST_INCLUDEDIR to search path if specified
+ if( BOOST_INCLUDEDIR )
+ file(TO_CMAKE_PATH ${BOOST_INCLUDEDIR} BOOST_INCLUDEDIR)
+ set(_boost_INCLUDE_SEARCH_DIRS
+ ${BOOST_INCLUDEDIR} ${_boost_INCLUDE_SEARCH_DIRS})
+ endif( BOOST_INCLUDEDIR )
+
+ # ------------------------------------------------------------------------
+ # Search for Boost include DIR
+ # ------------------------------------------------------------------------
+ # Try to find Boost by stepping backwards through the Boost versions
+ # we know about.
+ if( NOT Boost_INCLUDE_DIR )
+ # Build a list of path suffixes for each version.
+ set(_boost_PATH_SUFFIXES)
+ foreach(_boost_VER ${_boost_TEST_VERSIONS})
+ # Add in a path suffix, based on the required version, ideally
+ # we could read this from version.hpp, but for that to work we'd
+ # need to know the include dir already
+ 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})
+ endif()
+
+ list(APPEND _boost_PATH_SUFFIXES "boost-${_boost_BOOSTIFIED_VERSION}")
+ list(APPEND _boost_PATH_SUFFIXES "boost_${_boost_BOOSTIFIED_VERSION}")
+
+ endforeach(_boost_VER)
+
+ if(Boost_DEBUG)
+ message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+ "Include debugging info:")
+ message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+ " _boost_INCLUDE_SEARCH_DIRS = ${_boost_INCLUDE_SEARCH_DIRS}")
+ message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+ " _boost_PATH_SUFFIXES = ${_boost_PATH_SUFFIXES}")
+ endif()
+
+ # Look for a standard boost header file.
+ find_path(Boost_INCLUDE_DIR
+ NAMES boost/config.hpp
+ HINTS ${_boost_INCLUDE_SEARCH_DIRS}
+ PATH_SUFFIXES ${_boost_PATH_SUFFIXES}
+ ${_boost_FIND_OPTIONS}
+ )
+ endif( NOT Boost_INCLUDE_DIR )
+
+ # ------------------------------------------------------------------------
+ # Extract version information from version.hpp
+ # ------------------------------------------------------------------------
+
+ if(Boost_INCLUDE_DIR)
+ # Extract Boost_VERSION and Boost_LIB_VERSION from version.hpp
+ # Read the whole file:
+ #
+ set(BOOST_VERSION 0)
+ set(BOOST_LIB_VERSION "")
+ file(READ "${Boost_INCLUDE_DIR}/boost/version.hpp" _boost_VERSION_HPP_CONTENTS)
+ if(Boost_DEBUG)
+ message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+ "location of version.hpp: ${Boost_INCLUDE_DIR}/boost/version.hpp")
+ endif()
+
+ string(REGEX REPLACE ".*#define BOOST_VERSION ([0-9]+).*" "\\1" Boost_VERSION "${_boost_VERSION_HPP_CONTENTS}")
+ string(REGEX REPLACE ".*#define BOOST_LIB_VERSION \"([0-9_]+)\".*" "\\1" Boost_LIB_VERSION "${_boost_VERSION_HPP_CONTENTS}")
+
+ set(Boost_LIB_VERSION ${Boost_LIB_VERSION} CACHE INTERNAL "The library version string for boost libraries")
+ set(Boost_VERSION ${Boost_VERSION} CACHE INTERNAL "The version number for boost libraries")
+
+ if(NOT "${Boost_VERSION}" STREQUAL "0")
+ math(EXPR Boost_MAJOR_VERSION "${Boost_VERSION} / 100000")
+ math(EXPR Boost_MINOR_VERSION "${Boost_VERSION} / 100 % 1000")
+ math(EXPR Boost_SUBMINOR_VERSION "${Boost_VERSION} % 100")
+
+ set(Boost_ERROR_REASON
+ "${Boost_ERROR_REASON}Boost version: ${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}\nBoost include path: ${Boost_INCLUDE_DIR}")
+ endif(NOT "${Boost_VERSION}" STREQUAL "0")
+ if(Boost_DEBUG)
+ message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+ "version.hpp reveals boost "
+ "${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}")
+ endif()
+ else(Boost_INCLUDE_DIR)
+ set(Boost_ERROR_REASON
+ "${Boost_ERROR_REASON}Unable to find the Boost header files. Please set BOOST_ROOT to the root directory containing Boost or BOOST_INCLUDEDIR to the directory containing Boost's headers.")
+ endif(Boost_INCLUDE_DIR)
+
+ # ------------------------------------------------------------------------
+ # Suffix initialization and compiler suffix detection.
+ # ------------------------------------------------------------------------
+
+ # 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)
+ message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+ "using user-specified Boost_COMPILER = ${_boost_COMPILER}")
+ endif()
+ else()
+ # Attempt to guess the compiler suffix
+ # NOTE: this is not perfect yet, if you experience any issues
+ # please report them and use the Boost_COMPILER variable
+ # to work around the problems.
+ _Boost_GUESS_COMPILER_PREFIX(_boost_COMPILER)
+ if(Boost_DEBUG)
+ message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+ "guessed _boost_COMPILER = ${_boost_COMPILER}")
+ endif()
+ endif()
+
+ set (_boost_MULTITHREADED "-mt")
+ if( NOT Boost_USE_MULTITHREADED )
+ set (_boost_MULTITHREADED "")
+ endif()
+ if(Boost_DEBUG)
+ message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+ "_boost_MULTITHREADED = ${_boost_MULTITHREADED}")
+ endif()
+
+ #======================
+ # Systematically build up the Boost ABI tag
+ # http://boost.org/doc/libs/1_41_0/more/getting_started/windows.html#library-naming
+ set( _boost_RELEASE_ABI_TAG "-")
+ set( _boost_DEBUG_ABI_TAG "-")
+ # Key Use this library when:
+ # s linking statically to the C++ standard library and
+ # compiler runtime support libraries.
+ if(Boost_USE_STATIC_RUNTIME)
+ set( _boost_RELEASE_ABI_TAG "${_boost_RELEASE_ABI_TAG}s")
+ set( _boost_DEBUG_ABI_TAG "${_boost_DEBUG_ABI_TAG}s")
+ endif()
+ # g using debug versions of the standard and runtime
+ # support libraries
+ if(WIN32)
+ if(MSVC OR "${CMAKE_CXX_COMPILER}" MATCHES "icl"
+ OR "${CMAKE_CXX_COMPILER}" MATCHES "icpc")
+ set(_boost_DEBUG_ABI_TAG "${_boost_DEBUG_ABI_TAG}g")
+ endif()
+ endif()
+ # y using special debug build of python
+ if(Boost_USE_DEBUG_PYTHON)
+ set(_boost_DEBUG_ABI_TAG "${_boost_DEBUG_ABI_TAG}y")
+ endif()
+ # d using a debug version of your code
+ set(_boost_DEBUG_ABI_TAG "${_boost_DEBUG_ABI_TAG}d")
+ # p using the STLport standard library rather than the
+ # default one supplied with your compiler
+ if(Boost_USE_STLPORT)
+ set( _boost_RELEASE_ABI_TAG "${_boost_RELEASE_ABI_TAG}p")
+ set( _boost_DEBUG_ABI_TAG "${_boost_DEBUG_ABI_TAG}p")
+ endif()
+ # n using the STLport deprecated "native iostreams" feature
+ if(Boost_USE_STLPORT_DEPRECATED_NATIVE_IOSTREAMS)
+ set( _boost_RELEASE_ABI_TAG "${_boost_RELEASE_ABI_TAG}n")
+ set( _boost_DEBUG_ABI_TAG "${_boost_DEBUG_ABI_TAG}n")
+ endif()
+
+ if(Boost_DEBUG)
+ message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+ "_boost_RELEASE_ABI_TAG = ${_boost_RELEASE_ABI_TAG}")
+ message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+ "_boost_DEBUG_ABI_TAG = ${_boost_DEBUG_ABI_TAG}")
+ endif()
+
+ # ------------------------------------------------------------------------
+ # Begin finding boost libraries
+ # ------------------------------------------------------------------------
+
+ if(BOOST_ROOT)
+ set(_boost_LIBRARY_SEARCH_DIRS_ALWAYS
+ ${BOOST_ROOT}/lib
+ ${BOOST_ROOT}/stage/lib)
+ endif()
+ set(_boost_LIBRARY_SEARCH_DIRS_ALWAYS
+ ${_boost_LIBRARY_SEARCH_DIRS_ALWAYS}
+ ${Boost_INCLUDE_DIR}/lib
+ ${Boost_INCLUDE_DIR}/../lib
+ ${Boost_INCLUDE_DIR}/stage/lib
+ )
+ set(_boost_LIBRARY_SEARCH_DIRS_SYSTEM
+ C:/boost/lib
+ C:/boost
+ "$ENV{ProgramFiles}/boost/boost_${Boost_MAJOR_VERSION}_${Boost_MINOR_VERSION}_${Boost_SUBMINOR_VERSION}/lib"
+ "$ENV{ProgramFiles}/boost/boost_${Boost_MAJOR_VERSION}_${Boost_MINOR_VERSION}/lib"
+ "$ENV{ProgramFiles}/boost/lib"
+ "$ENV{ProgramFiles}/boost"
+ /sw/local/lib
+ )
+ set(_boost_LIBRARY_SEARCH_DIRS ${_boost_LIBRARY_SEARCH_DIRS_ALWAYS})
+ if( Boost_NO_SYSTEM_PATHS )
+ set(_boost_FIND_OPTIONS NO_CMAKE_SYSTEM_PATH)
+ else()
+ list(APPEND _boost_LIBRARY_SEARCH_DIRS ${_boost_LIBRARY_SEARCH_DIRS_SYSTEM})
+ endif()
+
+ # prepend BOOST_LIBRARYDIR to search path if specified
+ if( BOOST_LIBRARYDIR )
+ file(TO_CMAKE_PATH ${BOOST_LIBRARYDIR} BOOST_LIBRARYDIR)
+ set(_boost_LIBRARY_SEARCH_DIRS
+ ${BOOST_LIBRARYDIR} ${_boost_LIBRARY_SEARCH_DIRS})
+ endif()
+
+ if(Boost_DEBUG)
+ message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+ "_boost_LIBRARY_SEARCH_DIRS = ${_boost_LIBRARY_SEARCH_DIRS}")
+ endif()
+
+ # Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES
+ if( Boost_USE_STATIC_LIBS )
+ set( _boost_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()
+
+ # We want to use the tag inline below without risking double dashes
+ if(_boost_RELEASE_ABI_TAG)
+ if(${_boost_RELEASE_ABI_TAG} STREQUAL "-")
+ set(_boost_RELEASE_ABI_TAG "")
+ endif()
+ endif()
+ if(_boost_DEBUG_ABI_TAG)
+ if(${_boost_DEBUG_ABI_TAG} STREQUAL "-")
+ set(_boost_DEBUG_ABI_TAG "")
+ endif()
+ endif()
+
+ # The previous behavior of FindBoost when Boost_USE_STATIC_LIBS was enabled
+ # on WIN32 was to:
+ # 1. Search for static libs compiled against a SHARED C++ standard runtime library (use if found)
+ # 2. Search for static libs compiled against a STATIC C++ standard runtime library (use if found)
+ # We maintain this behavior since changing it could break people's builds.
+ # To disable the ambiguous behavior, the user need only
+ # set Boost_USE_STATIC_RUNTIME either ON or OFF.
+ set(_boost_STATIC_RUNTIME_WORKAROUND false)
+ if(WIN32 AND Boost_USE_STATIC_LIBS)
+ if(NOT DEFINED Boost_USE_STATIC_RUNTIME)
+ set(_boost_STATIC_RUNTIME_WORKAROUND true)
+ endif()
+ endif()
+
+ # On versions < 1.35, remove the System library from the considered list
+ # since it wasn't added until 1.35.
+ if(Boost_VERSION AND Boost_FIND_COMPONENTS)
+ if(Boost_VERSION LESS 103500)
+ list(REMOVE_ITEM Boost_FIND_COMPONENTS system)
+ endif()
+ endif()
+
+ foreach(COMPONENT ${Boost_FIND_COMPONENTS})
+ string(TOUPPER ${COMPONENT} UPPERCOMPONENT)
+ set( Boost_${UPPERCOMPONENT}_LIBRARY "Boost_${UPPERCOMPONENT}_LIBRARY-NOTFOUND" )
+ set( Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE "Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE-NOTFOUND" )
+ set( Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG "Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG-NOTFOUND")
+
+ set( _boost_docstring_release "Boost ${COMPONENT} library (release)")
+ set( _boost_docstring_debug "Boost ${COMPONENT} library (debug)")
+
+ #
+ # 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} )
+ 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} )
+ endif()
+ if(Boost_THREADAPI AND ${COMPONENT} STREQUAL "thread")
+ _Boost_PREPEND_LIST_WITH_THREADAPI(_boost_RELEASE_NAMES ${_boost_RELEASE_NAMES})
+ endif()
+ if(Boost_DEBUG)
+ message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+ "Searching for ${UPPERCOMPONENT}_LIBRARY_RELEASE: ${_boost_RELEASE_NAMES}")
+ endif()
+ find_library(Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE
+ NAMES ${_boost_RELEASE_NAMES}
+ HINTS ${_boost_LIBRARY_SEARCH_DIRS}
+ ${_boost_FIND_OPTIONS}
+ DOC "${_boost_docstring_release}"
+ )
+
+ #
+ # 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} )
+ 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} )
+ endif()
+ if(Boost_THREADAPI AND ${COMPONENT} STREQUAL "thread")
+ _Boost_PREPEND_LIST_WITH_THREADAPI(_boost_DEBUG_NAMES ${_boost_DEBUG_NAMES})
+ endif()
+ if(Boost_DEBUG)
+ message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+ "Searching for ${UPPERCOMPONENT}_LIBRARY_DEBUG: ${_boost_DEBUG_NAMES}")
+ endif()
+ find_library(Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG
+ NAMES ${_boost_DEBUG_NAMES}
+ HINTS ${_boost_LIBRARY_SEARCH_DIRS}
+ ${_boost_FIND_OPTIONS}
+ DOC "${_boost_docstring_debug}"
+ )
+
+ if(Boost_REALPATH)
+ _Boost_SWAP_WITH_REALPATH(Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE "${_boost_docstring_release}")
+ _Boost_SWAP_WITH_REALPATH(Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG "${_boost_docstring_debug}" )
+ endif()
+
+ _Boost_ADJUST_LIB_VARS(${UPPERCOMPONENT})
+
+ endforeach(COMPONENT)
+
+ # Restore the original find library ordering
+ if( Boost_USE_STATIC_LIBS )
+ set(CMAKE_FIND_LIBRARY_SUFFIXES ${_boost_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
+ endif()
+
+ # ------------------------------------------------------------------------
+ # End finding boost libraries
+ # ------------------------------------------------------------------------
+
+ # ------------------------------------------------------------------------
+ # Begin long process of determining Boost_FOUND, starting with version
+ # number checks, followed by
+ # TODO: Ideally the version check logic should happen prior to searching
+ # for libraries...
+ # ------------------------------------------------------------------------
+
+ set(Boost_INCLUDE_DIRS
+ ${Boost_INCLUDE_DIR}
+ )
+
+ set(Boost_FOUND FALSE)
+ if(Boost_INCLUDE_DIR)
+ set( Boost_FOUND TRUE )
+
+ if(Boost_MAJOR_VERSION LESS "${Boost_FIND_VERSION_MAJOR}" )
+ set( Boost_FOUND FALSE )
+ set(_Boost_VERSION_AGE "old")
+ elseif(Boost_MAJOR_VERSION EQUAL "${Boost_FIND_VERSION_MAJOR}" )
+ if(Boost_MINOR_VERSION LESS "${Boost_FIND_VERSION_MINOR}" )
+ set( Boost_FOUND FALSE )
+ set(_Boost_VERSION_AGE "old")
+ elseif(Boost_MINOR_VERSION EQUAL "${Boost_FIND_VERSION_MINOR}" )
+ if( Boost_FIND_VERSION_PATCH AND Boost_SUBMINOR_VERSION LESS "${Boost_FIND_VERSION_PATCH}" )
+ set( Boost_FOUND FALSE )
+ set(_Boost_VERSION_AGE "old")
+ endif( Boost_FIND_VERSION_PATCH AND Boost_SUBMINOR_VERSION LESS "${Boost_FIND_VERSION_PATCH}" )
+ endif( Boost_MINOR_VERSION LESS "${Boost_FIND_VERSION_MINOR}" )
+ endif( Boost_MAJOR_VERSION LESS "${Boost_FIND_VERSION_MAJOR}" )
+
+ if (NOT Boost_FOUND)
+ _Boost_MARK_COMPONENTS_FOUND(OFF)
+ endif()
+
+ if (Boost_FOUND AND Boost_FIND_VERSION_EXACT)
+ # If the user requested an exact version of Boost, check
+ # that. We already know that the Boost version we have is >= the
+ # requested version.
+ set(_Boost_VERSION_AGE "new")
+
+ # If the user didn't specify a patchlevel, it's 0.
+ if (NOT Boost_FIND_VERSION_PATCH)
+ set(Boost_FIND_VERSION_PATCH 0)
+ endif (NOT Boost_FIND_VERSION_PATCH)
+
+ # We'll set Boost_FOUND true again if we have an exact version match.
+ set(Boost_FOUND FALSE)
+ _Boost_MARK_COMPONENTS_FOUND(OFF)
+ if(Boost_MAJOR_VERSION EQUAL "${Boost_FIND_VERSION_MAJOR}" )
+ if(Boost_MINOR_VERSION EQUAL "${Boost_FIND_VERSION_MINOR}" )
+ if(Boost_SUBMINOR_VERSION EQUAL "${Boost_FIND_VERSION_PATCH}" )
+ set( Boost_FOUND TRUE )
+ _Boost_MARK_COMPONENTS_FOUND(ON)
+ endif(Boost_SUBMINOR_VERSION EQUAL "${Boost_FIND_VERSION_PATCH}" )
+ endif( Boost_MINOR_VERSION EQUAL "${Boost_FIND_VERSION_MINOR}" )
+ endif( Boost_MAJOR_VERSION EQUAL "${Boost_FIND_VERSION_MAJOR}" )
+ endif (Boost_FOUND AND Boost_FIND_VERSION_EXACT)
+
+ if(NOT Boost_FOUND)
+ # State that we found a version of Boost that is too new or too old.
+ set(Boost_ERROR_REASON
+ "${Boost_ERROR_REASON}\nDetected version of Boost is too ${_Boost_VERSION_AGE}. Requested version was ${Boost_FIND_VERSION_MAJOR}.${Boost_FIND_VERSION_MINOR}")
+ if (Boost_FIND_VERSION_PATCH)
+ set(Boost_ERROR_REASON
+ "${Boost_ERROR_REASON}.${Boost_FIND_VERSION_PATCH}")
+ endif (Boost_FIND_VERSION_PATCH)
+ if (NOT Boost_FIND_VERSION_EXACT)
+ set(Boost_ERROR_REASON "${Boost_ERROR_REASON} (or newer)")
+ endif (NOT Boost_FIND_VERSION_EXACT)
+ set(Boost_ERROR_REASON "${Boost_ERROR_REASON}.")
+ endif (NOT Boost_FOUND)
+
+ # Always check for missing components
+ set(_boost_CHECKED_COMPONENT FALSE)
+ set(_Boost_MISSING_COMPONENTS "")
+ foreach(COMPONENT ${Boost_FIND_COMPONENTS})
+ string(TOUPPER ${COMPONENT} COMPONENT)
+ set(_boost_CHECKED_COMPONENT TRUE)
+ if(NOT Boost_${COMPONENT}_FOUND)
+ string(TOLOWER ${COMPONENT} COMPONENT)
+ list(APPEND _Boost_MISSING_COMPONENTS ${COMPONENT})
+ set( Boost_FOUND FALSE)
+ endif()
+ endforeach(COMPONENT)
+
+ if(Boost_DEBUG)
+ message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] Boost_FOUND = ${Boost_FOUND}")
+ endif()
+
+ if (_Boost_MISSING_COMPONENTS)
+ # We were unable to find some libraries, so generate a sensible
+ # error message that lists the libraries we were unable to find.
+ set(Boost_ERROR_REASON
+ "${Boost_ERROR_REASON}\nThe following Boost libraries could not be found:\n")
+ foreach(COMPONENT ${_Boost_MISSING_COMPONENTS})
+ set(Boost_ERROR_REASON
+ "${Boost_ERROR_REASON} boost_${COMPONENT}\n")
+ endforeach(COMPONENT)
+
+ list(LENGTH Boost_FIND_COMPONENTS Boost_NUM_COMPONENTS_WANTED)
+ list(LENGTH _Boost_MISSING_COMPONENTS Boost_NUM_MISSING_COMPONENTS)
+ if (${Boost_NUM_COMPONENTS_WANTED} EQUAL ${Boost_NUM_MISSING_COMPONENTS})
+ set(Boost_ERROR_REASON
+ "${Boost_ERROR_REASON}No Boost libraries were found. You may need to set BOOST_LIBRARYDIR to the directory containing Boost libraries or BOOST_ROOT to the location of Boost.")
+ else (${Boost_NUM_COMPONENTS_WANTED} EQUAL ${Boost_NUM_MISSING_COMPONENTS})
+ set(Boost_ERROR_REASON
+ "${Boost_ERROR_REASON}Some (but not all) of the required Boost libraries were found. You may need to install these additional Boost libraries. Alternatively, set BOOST_LIBRARYDIR to the directory containing Boost libraries or BOOST_ROOT to the location of Boost.")
+ endif (${Boost_NUM_COMPONENTS_WANTED} EQUAL ${Boost_NUM_MISSING_COMPONENTS})
+ endif (_Boost_MISSING_COMPONENTS)
+
+ if( NOT Boost_LIBRARY_DIRS AND NOT _boost_CHECKED_COMPONENT )
+ # Compatibility Code for backwards compatibility with CMake
+ # 2.4's FindBoost module.
+
+ # Look for the boost library path.
+ # Note that the user may not have installed any libraries
+ # so it is quite possible the Boost_LIBRARY_DIRS may not exist.
+ set(_boost_LIB_DIR ${Boost_INCLUDE_DIR})
+
+ if("${_boost_LIB_DIR}" MATCHES "boost-[0-9]+")
+ get_filename_component(_boost_LIB_DIR ${_boost_LIB_DIR} PATH)
+ endif()
+
+ if("${_boost_LIB_DIR}" MATCHES "/include$")
+ # Strip off the trailing "/include" in the path.
+ get_filename_component(_boost_LIB_DIR ${_boost_LIB_DIR} PATH)
+ endif()
+
+ if(EXISTS "${_boost_LIB_DIR}/lib")
+ set(_boost_LIB_DIR ${_boost_LIB_DIR}/lib)
+ else()
+ if(EXISTS "${_boost_LIB_DIR}/stage/lib")
+ set(_boost_LIB_DIR ${_boost_LIB_DIR}/stage/lib)
+ else()
+ set(_boost_LIB_DIR "")
+ endif()
+ endif()
+
+ if(_boost_LIB_DIR AND EXISTS "${_boost_LIB_DIR}")
+ set(Boost_LIBRARY_DIRS ${_boost_LIB_DIR} CACHE FILEPATH "Boost library directory")
+ endif()
+
+ endif( NOT Boost_LIBRARY_DIRS AND NOT _boost_CHECKED_COMPONENT )
+
+ else(Boost_INCLUDE_DIR)
+ set( Boost_FOUND FALSE)
+ endif(Boost_INCLUDE_DIR)
+
+ # ------------------------------------------------------------------------
+ # Notification to end user about what was found
+ # ------------------------------------------------------------------------
+
+ if(Boost_FOUND)
+ if(NOT Boost_FIND_QUIETLY)
+ message(STATUS "Boost version: ${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}")
+ if(Boost_FIND_COMPONENTS)
+ message(STATUS "Found the following Boost libraries:")
+ endif()
+ endif(NOT Boost_FIND_QUIETLY)
+ foreach( COMPONENT ${Boost_FIND_COMPONENTS} )
+ string( TOUPPER ${COMPONENT} UPPERCOMPONENT )
+ if( Boost_${UPPERCOMPONENT}_FOUND )
+ if(NOT Boost_FIND_QUIETLY)
+ message (STATUS " ${COMPONENT}")
+ endif(NOT Boost_FIND_QUIETLY)
+ set(Boost_LIBRARIES ${Boost_LIBRARIES} ${Boost_${UPPERCOMPONENT}_LIBRARY})
+ endif( Boost_${UPPERCOMPONENT}_FOUND )
+ endforeach(COMPONENT)
+ else()
+ if(Boost_FIND_REQUIRED)
+ message(SEND_ERROR "Unable to find the requested Boost libraries.\n${Boost_ERROR_REASON}")
+ else()
+ if(NOT Boost_FIND_QUIETLY)
+ # we opt not to automatically output Boost_ERROR_REASON here as
+ # it could be quite lengthy and somewhat imposing in its requests
+ # Since Boost is not always a required dependency we'll leave this
+ # up to the end-user.
+ if(Boost_DEBUG OR Boost_DETAILED_FAILURE_MSG)
+ message(STATUS "Could NOT find Boost\n${Boost_ERROR_REASON}")
+ else()
+ message(STATUS "Could NOT find Boost")
+ endif()
+ endif()
+ endif(Boost_FIND_REQUIRED)
+ endif()
+
+ # show the Boost_INCLUDE_DIRS AND Boost_LIBRARIES variables only in the advanced view
+ mark_as_advanced(Boost_INCLUDE_DIR
+ Boost_INCLUDE_DIRS
+ Boost_LIBRARY_DIRS
+ )
diff --git a/Modules/FindBullet.cmake b/Modules/FindBullet.cmake
new file mode 100644
index 000000000..c96755fa4
--- /dev/null
+++ b/Modules/FindBullet.cmake
@@ -0,0 +1,84 @@
+# - Try to find the Bullet physics engine
+#
+# 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.
+# Copyright 2009 Philip Lowman <philip@yhbt.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_BULLET_LIBRARY _var)
+ find_library(${_var}
+ NAMES
+ ${ARGN}
+ HINTS
+ ${BULLET_ROOT}
+ ${BULLET_ROOT}/out/release8/libs
+ ${BULLET_ROOT}/out/debug8/libs
+ PATH_SUFFIXES lib
+ )
+ mark_as_advanced(${_var})
+endmacro()
+
+macro(_BULLET_APPEND_LIBRARIES _list _release)
+ set(_debug ${_release}_DEBUG)
+ if(${_debug})
+ set(${_list} ${${_list}} optimized ${${_release}} debug ${${_debug}})
+ else()
+ set(${_list} ${${_list}} ${${_release}})
+ endif()
+endmacro()
+
+find_path(BULLET_INCLUDE_DIR NAMES btBulletCollisionCommon.h
+ HINTS
+ ${BULLET_ROOT}/include
+ ${BULLET_ROOT}/src
+ PATH_SUFFIXES bullet
+)
+
+# Find the libraries
+
+_FIND_BULLET_LIBRARY(BULLET_DYNAMICS_LIBRARY BulletDynamics)
+_FIND_BULLET_LIBRARY(BULLET_DYNAMICS_LIBRARY_DEBUG BulletDynamics_Debug BulletDynamics_d)
+_FIND_BULLET_LIBRARY(BULLET_COLLISION_LIBRARY BulletCollision)
+_FIND_BULLET_LIBRARY(BULLET_COLLISION_LIBRARY_DEBUG BulletCollision_Debug BulletCollision_d)
+_FIND_BULLET_LIBRARY(BULLET_MATH_LIBRARY BulletMath LinearMath)
+_FIND_BULLET_LIBRARY(BULLET_MATH_LIBRARY_DEBUG BulletMath_Debug BulletMath_d LinearMath_Debug LinearMath_d)
+_FIND_BULLET_LIBRARY(BULLET_SOFTBODY_LIBRARY BulletSoftBody)
+_FIND_BULLET_LIBRARY(BULLET_SOFTBODY_LIBRARY_DEBUG BulletSoftBody_Debug BulletSoftBody_d)
+
+
+# handle the QUIETLY and REQUIRED arguments and set BULLET_FOUND to TRUE if
+# all listed variables are TRUE
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Bullet DEFAULT_MSG
+ BULLET_DYNAMICS_LIBRARY BULLET_COLLISION_LIBRARY BULLET_MATH_LIBRARY
+ BULLET_SOFTBODY_LIBRARY BULLET_INCLUDE_DIR)
+
+set(BULLET_INCLUDE_DIRS ${BULLET_INCLUDE_DIR})
+if(BULLET_FOUND)
+ _BULLET_APPEND_LIBRARIES(BULLET_LIBRARIES BULLET_DYNAMICS_LIBRARY)
+ _BULLET_APPEND_LIBRARIES(BULLET_LIBRARIES BULLET_COLLISION_LIBRARY)
+ _BULLET_APPEND_LIBRARIES(BULLET_LIBRARIES BULLET_MATH_LIBRARY)
+ _BULLET_APPEND_LIBRARIES(BULLET_LIBRARIES BULLET_SOFTBODY_LIBRARY)
+endif()
diff --git a/Modules/FindCABLE.cmake b/Modules/FindCABLE.cmake
new file mode 100644
index 000000000..678fb07ca
--- /dev/null
+++ b/Modules/FindCABLE.cmake
@@ -0,0 +1,81 @@
+# - Find CABLE
+# This module finds if CABLE is installed and determines where the
+# 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
+#
+# 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.
+
+#=============================================================================
+# 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.)
+
+IF(NOT CABLE)
+ FIND_PATH(CABLE_BUILD_DIR cableVersion.h)
+ENDIF(NOT CABLE)
+
+IF(CABLE_BUILD_DIR)
+ LOAD_CACHE(${CABLE_BUILD_DIR}
+ EXCLUDE
+ BUILD_SHARED_LIBS
+ LIBRARY_OUTPUT_PATH
+ EXECUTABLE_OUTPUT_PATH
+ MAKECOMMAND
+ CMAKE_INSTALL_PREFIX
+ INCLUDE_INTERNALS
+ CABLE_LIBRARY_PATH
+ CABLE_EXECUTABLE_PATH)
+
+ IF(CABLE_LIBRARY_PATH)
+ FIND_LIBRARY(CABLE_TCL_LIBRARY NAMES CableTclFacility PATHS
+ ${CABLE_LIBRARY_PATH}
+ ${CABLE_LIBRARY_PATH}/*)
+ ELSE(CABLE_LIBRARY_PATH)
+ FIND_LIBRARY(CABLE_TCL_LIBRARY NAMES CableTclFacility PATHS
+ ${CABLE_BINARY_DIR}/CableTclFacility
+ ${CABLE_BINARY_DIR}/CableTclFacility/*)
+ ENDIF(CABLE_LIBRARY_PATH)
+
+ IF(CABLE_EXECUTABLE_PATH)
+ FIND_PROGRAM(CABLE NAMES cable PATHS
+ ${CABLE_EXECUTABLE_PATH}
+ ${CABLE_EXECUTABLE_PATH}/*)
+ ELSE(CABLE_EXECUTABLE_PATH)
+ FIND_PROGRAM(CABLE NAMES cable PATHS
+ ${CABLE_BINARY_DIR}/Executables
+ ${CABLE_BINARY_DIR}/Executables/*)
+ ENDIF(CABLE_EXECUTABLE_PATH)
+
+ FIND_PATH(CABLE_INCLUDE_DIR CableTclFacility/ctCalls.h
+ ${CABLE_SOURCE_DIR})
+ELSE(CABLE_BUILD_DIR)
+ # Find the cable executable in the path.
+ FIND_PROGRAM(CABLE NAMES cable)
+
+ # Get the path where the executable sits, but without the executable
+ # name on it.
+ GET_FILENAME_COMPONENT(CABLE_ROOT_BIN ${CABLE} PATH)
+
+ # Find the cable include directory in a path relative to the cable
+ # executable.
+ FIND_PATH(CABLE_INCLUDE_DIR CableTclFacility/ctCalls.h
+ ${CABLE_ROOT_BIN}/../include/Cable)
+
+ # Find the WrapTclFacility library in a path relative to the cable
+ # executable.
+ FIND_LIBRARY(CABLE_TCL_LIBRARY NAMES CableTclFacility PATHS
+ ${CABLE_ROOT_BIN}/../lib/Cable)
+ENDIF(CABLE_BUILD_DIR)
diff --git a/Modules/FindCUDA.cmake b/Modules/FindCUDA.cmake
new file mode 100644
index 000000000..56a92c199
--- /dev/null
+++ b/Modules/FindCUDA.cmake
@@ -0,0 +1,1367 @@
+# - 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.
+#
+# 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.
+#
+# 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_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.
+#
+# 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_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_HOST_COMPILATION_CPP (Default ON)
+# -- Set to OFF for C compilation of host code.
+#
+# 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_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_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.
+#
+# The script creates the following macros (in alphebetical order):
+#
+# 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_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_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_LIBRARY( cuda_target file0 file1 ...
+# [STATIC | SHARED | MODULE] [EXCLUDE_FROM_ALL] [OPTIONS ...] )
+# -- Same as CUDA_ADD_EXECUTABLE except that a library is created.
+#
+# 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( 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_PTX( generated_files file0 file1 ... [OPTIONS ...] )
+# -- Returns a list of PTX files generated from the input source 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_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.
+#
+# 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
+#
+# 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.
+#
+# 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.
+#
+# 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.
+#
+# 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_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_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.
+#
+#
+# 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
+#
+# This code is licensed under the MIT License. See the FindCUDA.cmake script
+# for the text of the license.
+
+# The MIT License
+#
+# License for the specific language governing rights and limitations under
+# 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.
+#
+###############################################################################
+
+# 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}")
+ # CMAKE_CURRENT_LIST_FILE contains the full path to the file currently being
+ # processed. Using this variable, we can pull out the current path, and
+ # provide a way to get access to the other files we need local to here.
+ get_filename_component(CMAKE_CURRENT_LIST_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
+ set(CUDA_${_name} "${CMAKE_CURRENT_LIST_DIR}/FindCUDA/${_full_name}")
+ if(NOT EXISTS "${CUDA_${_name}}")
+ set(error_message "${_full_name} not found in ${CMAKE_CURRENT_LIST_DIR}/FindCUDA")
+ if(CUDA_FIND_REQUIRED)
+ message(FATAL_ERROR "${error_message}")
+ else()
+ if(NOT CUDA_FIND_QUIETLY)
+ message(STATUS "${error_message}")
+ endif()
+ endif()
+ endif()
+ # Set this variable as internal, so the user isn't bugged with it.
+ set(CUDA_${_name} ${CUDA_${_name}} CACHE INTERNAL "Location of ${_full_name}" FORCE)
+endmacro(CUDA_FIND_HELPER_FILE)
+
+#####################################################################
+## CUDA_INCLUDE_NVCC_DEPENDENCIES
+##
+
+# So we want to try and include the dependency file if it exists. If
+# it doesn't exist then we need to create an empty one, so we can
+# include it.
+
+# If it does exist, then we need to check to see if all the files it
+# depends on exist. If they don't then we should clear the dependency
+# file and regenerate it later. This covers the case where a header
+# file has disappeared or moved.
+
+macro(CUDA_INCLUDE_NVCC_DEPENDENCIES dependency_file)
+ set(CUDA_NVCC_DEPEND)
+ set(CUDA_NVCC_DEPEND_REGENERATE FALSE)
+
+
+ # Include the dependency file. Create it first if it doesn't exist . The
+ # INCLUDE puts a dependency that will force CMake to rerun and bring in the
+ # new info when it changes. DO NOT REMOVE THIS (as I did and spent a few
+ # hours figuring out why it didn't work.
+ if(NOT EXISTS ${dependency_file})
+ file(WRITE ${dependency_file} "#FindCUDA.cmake generated file. Do not edit.\n")
+ endif()
+ # Always include this file to force CMake to run again next
+ # invocation and rebuild the dependencies.
+ #message("including dependency_file = ${dependency_file}")
+ include(${dependency_file})
+
+ # Now we need to verify the existence of all the included files
+ # here. If they aren't there we need to just blank this variable and
+ # make the file regenerate again.
+# if(DEFINED CUDA_NVCC_DEPEND)
+# message("CUDA_NVCC_DEPEND set")
+# else()
+# message("CUDA_NVCC_DEPEND NOT set")
+# endif()
+ if(CUDA_NVCC_DEPEND)
+ #message("CUDA_NVCC_DEPEND found")
+ foreach(f ${CUDA_NVCC_DEPEND})
+ # message("searching for ${f}")
+ if(NOT EXISTS ${f})
+ #message("file ${f} not found")
+ set(CUDA_NVCC_DEPEND_REGENERATE TRUE)
+ endif()
+ endforeach(f)
+ else(CUDA_NVCC_DEPEND)
+ #message("CUDA_NVCC_DEPEND false")
+ # No dependencies, so regenerate the file.
+ set(CUDA_NVCC_DEPEND_REGENERATE TRUE)
+ endif(CUDA_NVCC_DEPEND)
+
+ #message("CUDA_NVCC_DEPEND_REGENERATE = ${CUDA_NVCC_DEPEND_REGENERATE}")
+ # No incoming dependencies, so we need to generate them. Make the
+ # output depend on the dependency file itself, which should cause the
+ # rule to re-run.
+ if(CUDA_NVCC_DEPEND_REGENERATE)
+ set(CUDA_NVCC_DEPEND ${dependency_file})
+ #message("Generating an empty dependency_file: ${dependency_file}")
+ file(WRITE ${dependency_file} "#FindCUDA.cmake generated file. Do not edit.\n")
+ endif(CUDA_NVCC_DEPEND_REGENERATE)
+
+endmacro(CUDA_INCLUDE_NVCC_DEPENDENCIES)
+
+###############################################################################
+###############################################################################
+# Setup variables' defaults
+###############################################################################
+###############################################################################
+
+# Allow the user to specify if the device code is supposed to be 32 or 64 bit.
+if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set(CUDA_64_BIT_DEVICE_CODE_DEFAULT ON)
+else()
+ set(CUDA_64_BIT_DEVICE_CODE_DEFAULT OFF)
+endif()
+option(CUDA_64_BIT_DEVICE_CODE "Compile device code in 64 bit mode" ${CUDA_64_BIT_DEVICE_CODE_DEFAULT})
+
+# Attach the build rule to the source file in VS. This option
+option(CUDA_ATTACH_VS_BUILD_RULE_TO_CUDA_FILE "Attach the build rule to the CUDA source file. Enable only when the CUDA source file is added to at most one target." ON)
+
+# Prints out extra information about the cuda file during compilation
+option(CUDA_BUILD_CUBIN "Generate and parse .cubin files in Device mode." OFF)
+
+# Set whether we are using emulation or device mode.
+option(CUDA_BUILD_EMULATION "Build in Emulation mode" OFF)
+
+# Where to put the generated output.
+set(CUDA_GENERATED_OUTPUT_DIR "" CACHE PATH "Directory to put all the output files. If blank it will default to the CMAKE_CURRENT_BINARY_DIR")
+
+# Parse HOST_COMPILATION mode.
+option(CUDA_HOST_COMPILATION_CPP "Generated file extension" ON)
+
+# Extra user settable flags
+set(CUDA_NVCC_FLAGS "" CACHE STRING "Semi-colon delimit multiple arguments.")
+
+# Propagate the host flags to the host compiler via -Xcompiler
+option(CUDA_PROPAGATE_HOST_FLAGS "Propage C/CXX_FLAGS and friends to the host compiler via -Xcompile" ON)
+
+# Specifies whether the commands used when compiling the .cu file will be printed out.
+option(CUDA_VERBOSE_BUILD "Print out the commands run while compiling the CUDA source file. With the Makefile generator this defaults to VERBOSE variable specified on the command line, but can be forced on with this option." OFF)
+
+mark_as_advanced(
+ CUDA_64_BIT_DEVICE_CODE
+ CUDA_ATTACH_VS_BUILD_RULE_TO_CUDA_FILE
+ CUDA_GENERATED_OUTPUT_DIR
+ CUDA_HOST_COMPILATION_CPP
+ CUDA_NVCC_FLAGS
+ CUDA_PROPAGATE_HOST_FLAGS
+ )
+
+# Makefile and similar generators don't define CMAKE_CONFIGURATION_TYPES, so we
+# need to add another entry for the CMAKE_BUILD_TYPE. We also need to add the
+# standerd set of 4 build types (Debug, MinSizeRel, Release, and RelWithDebInfo)
+# for completeness. We need run this loop in order to accomodate the addition
+# of extra configuration types. Duplicate entries will be removed by
+# REMOVE_DUPLICATES.
+set(CUDA_configuration_types ${CMAKE_CONFIGURATION_TYPES} ${CMAKE_BUILD_TYPE} Debug MinSizeRel Release RelWithDebInfo)
+list(REMOVE_DUPLICATES CUDA_configuration_types)
+foreach(config ${CUDA_configuration_types})
+ string(TOUPPER ${config} config_upper)
+ set(CUDA_NVCC_FLAGS_${config_upper} "" CACHE STRING "Semi-colon delimit multiple arguments.")
+ mark_as_advanced(CUDA_NVCC_FLAGS_${config_upper})
+endforeach()
+
+###############################################################################
+###############################################################################
+# Locate CUDA, Set Build Type, etc.
+###############################################################################
+###############################################################################
+
+# 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)
+ unset(CUDA_TOOLKIT_INCLUDE CACHE)
+ unset(CUDA_CUDART_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_cublas_LIBRARY CACHE)
+ unset(CUDA_cublasemu_LIBRARY CACHE)
+ unset(CUDA_cufft_LIBRARY CACHE)
+ unset(CUDA_cufftemu_LIBRARY CACHE)
+ unset(CUDA_curand_LIBRARY CACHE)
+ unset(CUDA_cusparse_LIBRARY CACHE)
+ unset(CUDA_npp_LIBRARY CACHE)
+ unset(CUDA_nvcuvenc_LIBRARY CACHE)
+ unset(CUDA_nvcuvid_LIBRARY CACHE)
+endif()
+
+if(NOT "${CUDA_SDK_ROOT_DIR}" STREQUAL "${CUDA_SDK_ROOT_DIR_INTERNAL}")
+ # No specific variables to catch. Use this kind of code before calling
+ # find_package(CUDA) to clean up any variables that may depend on this path.
+
+ # unset(MY_SPECIAL_CUDA_SDK_INCLUDE_DIR CACHE)
+ # unset(MY_SPECIAL_CUDA_SDK_LIBRARY CACHE)
+endif()
+
+# Search for the cuda distribution.
+if(NOT CUDA_TOOLKIT_ROOT_DIR)
+
+ # Search in the CUDA_BIN_PATH first.
+ find_path(CUDA_TOOLKIT_ROOT_DIR
+ NAMES nvcc nvcc.exe
+ PATHS
+ ENV CUDA_PATH
+ ENV CUDA_BIN_PATH
+ PATH_SUFFIXES bin bin64
+ DOC "Toolkit location."
+ NO_DEFAULT_PATH
+ )
+ # Now search default paths
+ find_path(CUDA_TOOLKIT_ROOT_DIR
+ NAMES nvcc nvcc.exe
+ PATHS /usr/local/bin
+ /usr/local/cuda/bin
+ DOC "Toolkit location."
+ )
+
+ if (CUDA_TOOLKIT_ROOT_DIR)
+ string(REGEX REPLACE "[/\\\\]?bin[64]*[/\\\\]?$" "" CUDA_TOOLKIT_ROOT_DIR ${CUDA_TOOLKIT_ROOT_DIR})
+ # We need to force this back into the cache.
+ set(CUDA_TOOLKIT_ROOT_DIR ${CUDA_TOOLKIT_ROOT_DIR} CACHE PATH "Toolkit location." FORCE)
+ endif(CUDA_TOOLKIT_ROOT_DIR)
+ if (NOT EXISTS ${CUDA_TOOLKIT_ROOT_DIR})
+ if(CUDA_FIND_REQUIRED)
+ message(FATAL_ERROR "Specify CUDA_TOOLKIT_ROOT_DIR")
+ elseif(NOT CUDA_FIND_QUIETLY)
+ message("CUDA_TOOLKIT_ROOT_DIR not found or specified")
+ endif()
+ endif (NOT EXISTS ${CUDA_TOOLKIT_ROOT_DIR})
+endif (NOT CUDA_TOOLKIT_ROOT_DIR)
+
+# CUDA_NVCC_EXECUTABLE
+find_program(CUDA_NVCC_EXECUTABLE
+ NAMES nvcc
+ PATHS "${CUDA_TOOLKIT_ROOT_DIR}"
+ ENV CUDA_PATH
+ ENV CUDA_BIN_PATH
+ PATH_SUFFIXES bin bin64
+ NO_DEFAULT_PATH
+ )
+# Search default search paths, after we search our own set of paths.
+find_program(CUDA_NVCC_EXECUTABLE nvcc)
+mark_as_advanced(CUDA_NVCC_EXECUTABLE)
+
+if(CUDA_NVCC_EXECUTABLE AND NOT CUDA_VERSION)
+ # Compute the version.
+ execute_process (COMMAND ${CUDA_NVCC_EXECUTABLE} "--version" OUTPUT_VARIABLE NVCC_OUT)
+ string(REGEX REPLACE ".*release ([0-9]+)\\.([0-9]+).*" "\\1" CUDA_VERSION_MAJOR ${NVCC_OUT})
+ string(REGEX REPLACE ".*release ([0-9]+)\\.([0-9]+).*" "\\2" CUDA_VERSION_MINOR ${NVCC_OUT})
+ set(CUDA_VERSION "${CUDA_VERSION_MAJOR}.${CUDA_VERSION_MINOR}" CACHE STRING "Version of CUDA as computed from nvcc.")
+ mark_as_advanced(CUDA_VERSION)
+else()
+ # Need to set these based off of the cached value
+ string(REGEX REPLACE "([0-9]+)\\.([0-9]+).*" "\\1" CUDA_VERSION_MAJOR "${CUDA_VERSION}")
+ string(REGEX REPLACE "([0-9]+)\\.([0-9]+).*" "\\2" CUDA_VERSION_MINOR "${CUDA_VERSION}")
+endif()
+
+# Always set this convenience variable
+set(CUDA_VERSION_STRING "${CUDA_VERSION}")
+
+# CUDA_TOOLKIT_INCLUDE
+find_path(CUDA_TOOLKIT_INCLUDE
+ device_functions.h # Header included in toolkit
+ PATHS "${CUDA_TOOLKIT_ROOT_DIR}"
+ ENV CUDA_PATH
+ ENV CUDA_INC_PATH
+ PATH_SUFFIXES include
+ NO_DEFAULT_PATH
+ )
+# Search default search paths, after we search our own set of paths.
+find_path(CUDA_TOOLKIT_INCLUDE device_functions.h)
+mark_as_advanced(CUDA_TOOLKIT_INCLUDE)
+
+# Set the user list of include dir to nothing to initialize it.
+set (CUDA_NVCC_INCLUDE_ARGS_USER "")
+set (CUDA_INCLUDE_DIRS ${CUDA_TOOLKIT_INCLUDE})
+
+macro(FIND_LIBRARY_LOCAL_FIRST _var _names _doc)
+ if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ # CUDA 3.2+ on Windows moved the library directories, so we need the new
+ # and old paths.
+ set(_cuda_64bit_lib_dir "lib/x64" "lib64" )
+ endif()
+ # CUDA 3.2+ on Windows moved the library directories, so we need to new
+ # (lib/Win32) and the old path (lib).
+ find_library(${_var}
+ NAMES ${_names}
+ PATHS "${CUDA_TOOLKIT_ROOT_DIR}"
+ ENV CUDA_PATH
+ ENV CUDA_LIB_PATH
+ PATH_SUFFIXES ${_cuda_64bit_lib_dir} "lib/Win32" "lib"
+ DOC ${_doc}
+ NO_DEFAULT_PATH
+ )
+ # Search default search paths, after we search our own set of paths.
+ find_library(${_var} NAMES ${_names} DOC ${_doc})
+endmacro()
+
+# CUDA_LIBRARIES
+find_library_local_first(CUDA_CUDART_LIBRARY cudart "\"cudart\" library")
+if(CUDA_VERSION VERSION_EQUAL "3.0")
+ # The cudartemu library only existed for the 3.0 version of CUDA.
+ find_library_local_first(CUDA_CUDARTEMU_LIBRARY cudartemu "\"cudartemu\" library")
+ mark_as_advanced(
+ CUDA_CUDARTEMU_LIBRARY
+ )
+endif()
+# 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)
+ endif()
+ if(_cuda_path_to_cudart)
+ list(APPEND CUDA_LIBRARIES -Wl,-rpath "-Wl,${_cuda_path_to_cudart}")
+ endif()
+endif()
+
+# 1.1 toolkit on linux doesn't appear to have a separate library on
+# some platforms.
+find_library_local_first(CUDA_CUDA_LIBRARY cuda "\"cuda\" library (older versions only).")
+
+# Add cuda library to the link line only if it is found.
+if (CUDA_CUDA_LIBRARY)
+ set(CUDA_LIBRARIES ${CUDA_LIBRARIES} ${CUDA_CUDA_LIBRARY})
+endif(CUDA_CUDA_LIBRARY)
+
+mark_as_advanced(
+ CUDA_CUDA_LIBRARY
+ CUDA_CUDART_LIBRARY
+ )
+
+#######################
+# Look for some of the toolkit helper libraries
+macro(FIND_CUDA_HELPER_LIBS _name)
+ find_library_local_first(CUDA_${_name}_LIBRARY ${_name} "\"${_name}\" library")
+ mark_as_advanced(CUDA_${_name}_LIBRARY)
+endmacro(FIND_CUDA_HELPER_LIBS)
+
+#######################
+# Disable emulation for v3.1 onward
+if(CUDA_VERSION VERSION_GREATER "3.0")
+ if(CUDA_BUILD_EMULATION)
+ message(FATAL_ERROR "CUDA_BUILD_EMULATION is not supported in version 3.1 and onwards. You must disable it to proceed. You have version ${CUDA_VERSION}.")
+ endif()
+endif()
+
+# Search for additional CUDA toolkit libraries.
+if(CUDA_VERSION VERSION_LESS "3.1")
+ # Emulation libraries aren't available in version 3.1 onward.
+ find_cuda_helper_libs(cufftemu)
+ find_cuda_helper_libs(cublasemu)
+endif()
+find_cuda_helper_libs(cufft)
+find_cuda_helper_libs(cublas)
+if(NOT CUDA_VERSION VERSION_LESS "3.2")
+ # cusparse showed up in version 3.2
+ find_cuda_helper_libs(cusparse)
+ find_cuda_helper_libs(curand)
+ if (WIN32)
+ find_cuda_helper_libs(nvcuvenc)
+ find_cuda_helper_libs(nvcuvid)
+ endif()
+endif()
+if(NOT CUDA_VERSION VERSION_LESS "4.0")
+ find_cuda_helper_libs(npp)
+endif()
+
+if (CUDA_BUILD_EMULATION)
+ set(CUDA_CUFFT_LIBRARIES ${CUDA_cufftemu_LIBRARY})
+ set(CUDA_CUBLAS_LIBRARIES ${CUDA_cublasemu_LIBRARY})
+else()
+ set(CUDA_CUFFT_LIBRARIES ${CUDA_cufft_LIBRARY})
+ set(CUDA_CUBLAS_LIBRARIES ${CUDA_cublas_LIBRARY})
+endif()
+
+########################
+# Look for the SDK stuff. As of CUDA 3.0 NVSDKCUDA_ROOT has been replaced with
+# NVSDKCOMPUTE_ROOT with the old CUDA C contents moved into the C subdirectory
+find_path(CUDA_SDK_ROOT_DIR common/inc/cutil.h
+ "$ENV{NVSDKCOMPUTE_ROOT}/C"
+ "$ENV{NVSDKCUDA_ROOT}"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\NVIDIA Corporation\\Installed Products\\NVIDIA SDK 10\\Compute;InstallDir]"
+ "/Developer/GPU\ Computing/C"
+ )
+
+# Keep the CUDA_SDK_ROOT_DIR first in order to be able to override the
+# environment variables.
+set(CUDA_SDK_SEARCH_PATH
+ "${CUDA_SDK_ROOT_DIR}"
+ "${CUDA_TOOLKIT_ROOT_DIR}/local/NVSDK0.2"
+ "${CUDA_TOOLKIT_ROOT_DIR}/NVSDK0.2"
+ "${CUDA_TOOLKIT_ROOT_DIR}/NV_CUDA_SDK"
+ "$ENV{HOME}/NVIDIA_CUDA_SDK"
+ "$ENV{HOME}/NVIDIA_CUDA_SDK_MACOSX"
+ "/Developer/CUDA"
+ )
+
+# Example of how to find an include file from the CUDA_SDK_ROOT_DIR
+
+# find_path(CUDA_CUT_INCLUDE_DIR
+# cutil.h
+# PATHS ${CUDA_SDK_SEARCH_PATH}
+# PATH_SUFFIXES "common/inc"
+# DOC "Location of cutil.h"
+# NO_DEFAULT_PATH
+# )
+# # Now search system paths
+# find_path(CUDA_CUT_INCLUDE_DIR cutil.h DOC "Location of cutil.h")
+
+# mark_as_advanced(CUDA_CUT_INCLUDE_DIR)
+
+
+# Example of how to find a library in the CUDA_SDK_ROOT_DIR
+
+# # cutil library is called cutil64 for 64 bit builds on windows. We don't want
+# # to get these confused, so we are setting the name based on the word size of
+# # the build.
+
+# if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+# set(cuda_cutil_name cutil64)
+# else(CMAKE_SIZEOF_VOID_P EQUAL 8)
+# set(cuda_cutil_name cutil32)
+# endif(CMAKE_SIZEOF_VOID_P EQUAL 8)
+
+# find_library(CUDA_CUT_LIBRARY
+# NAMES cutil ${cuda_cutil_name}
+# PATHS ${CUDA_SDK_SEARCH_PATH}
+# # The new version of the sdk shows up in common/lib, but the old one is in lib
+# PATH_SUFFIXES "common/lib" "lib"
+# DOC "Location of cutil library"
+# NO_DEFAULT_PATH
+# )
+# # Now search system paths
+# find_library(CUDA_CUT_LIBRARY NAMES cutil ${cuda_cutil_name} DOC "Location of cutil library")
+# mark_as_advanced(CUDA_CUT_LIBRARY)
+# set(CUDA_CUT_LIBRARIES ${CUDA_CUT_LIBRARY})
+
+
+
+#############################
+# Check for required components
+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_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)
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+find_package_handle_standard_args(CUDA
+ REQUIRED_VARS
+ CUDA_TOOLKIT_ROOT_DIR
+ CUDA_NVCC_EXECUTABLE
+ CUDA_INCLUDE_DIRS
+ CUDA_CUDART_LIBRARY
+ VERSION_VAR
+ CUDA_VERSION
+ )
+
+
+
+###############################################################################
+###############################################################################
+# Macros
+###############################################################################
+###############################################################################
+
+###############################################################################
+# Add include directories to pass to the nvcc command.
+macro(CUDA_INCLUDE_DIRECTORIES)
+ foreach(dir ${ARGN})
+ list(APPEND CUDA_NVCC_INCLUDE_ARGS_USER -I${dir})
+ endforeach(dir ${ARGN})
+endmacro(CUDA_INCLUDE_DIRECTORIES)
+
+
+##############################################################################
+cuda_find_helper_file(parse_cubin cmake)
+cuda_find_helper_file(make2cmake cmake)
+cuda_find_helper_file(run_nvcc cmake)
+
+##############################################################################
+# Separate the OPTIONS out from the sources
+#
+macro(CUDA_GET_SOURCES_AND_OPTIONS _sources _cmake_options _options)
+ set( ${_sources} )
+ set( ${_cmake_options} )
+ set( ${_options} )
+ set( _found_options FALSE )
+ foreach(arg ${ARGN})
+ if(arg STREQUAL "OPTIONS")
+ 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"
+ )
+ list(APPEND ${_cmake_options} ${arg})
+ else()
+ if ( _found_options )
+ list(APPEND ${_options} ${arg})
+ else()
+ # Assume this is a file
+ list(APPEND ${_sources} ${arg})
+ endif()
+ endif()
+ endforeach()
+endmacro()
+
+##############################################################################
+# Parse the OPTIONS from ARGN and set the variables prefixed by _option_prefix
+#
+macro(CUDA_PARSE_NVCC_OPTIONS _option_prefix)
+ set( _found_config )
+ foreach(arg ${ARGN})
+ # Determine if we are dealing with a perconfiguration flag
+ foreach(config ${CUDA_configuration_types})
+ string(TOUPPER ${config} config_upper)
+ if (arg STREQUAL "${config_upper}")
+ set( _found_config _${arg})
+ # Set arg to nothing to keep it from being processed further
+ set( arg )
+ endif()
+ endforeach()
+
+ if ( arg )
+ list(APPEND ${_option_prefix}${_found_config} "${arg}")
+ endif()
+ endforeach()
+endmacro()
+
+##############################################################################
+# Helper to add the include directory for CUDA only once
+function(CUDA_ADD_CUDA_INCLUDE_ONCE)
+ get_directory_property(_include_directories INCLUDE_DIRECTORIES)
+ set(_add TRUE)
+ if(_include_directories)
+ foreach(dir ${_include_directories})
+ if("${dir}" STREQUAL "${CUDA_INCLUDE_DIRS}")
+ set(_add FALSE)
+ endif()
+ endforeach()
+ endif()
+ if(_add)
+ include_directories(${CUDA_INCLUDE_DIRS})
+ endif()
+endfunction()
+
+function(CUDA_BUILD_SHARED_LIBRARY shared_flag)
+ set(cmake_args ${ARGN})
+ # If SHARED, MODULE, or STATIC aren't already in the list of arguments, then
+ # add SHARED or STATIC based on the value of BUILD_SHARED_LIBS.
+ list(FIND cmake_args SHARED _cuda_found_SHARED)
+ list(FIND cmake_args MODULE _cuda_found_MODULE)
+ list(FIND cmake_args STATIC _cuda_found_STATIC)
+ if( _cuda_found_SHARED GREATER -1 OR
+ _cuda_found_MODULE GREATER -1 OR
+ _cuda_found_STATIC GREATER -1)
+ set(_cuda_build_shared_libs)
+ else()
+ if (BUILD_SHARED_LIBS)
+ set(_cuda_build_shared_libs SHARED)
+ else()
+ set(_cuda_build_shared_libs STATIC)
+ endif()
+ endif()
+ set(${shared_flag} ${_cuda_build_shared_libs} PARENT_SCOPE)
+endfunction()
+
+##############################################################################
+# Helper to avoid clashes of files with the same basename but different paths.
+# This doesn't attempt to do exactly what CMake internals do, which is to only
+# add this path when there is a conflict, since by the time a second collision
+# in names is detected it's already too late to fix the first one. For
+# consistency sake the relative path will be added to all files.
+function(CUDA_COMPUTE_BUILD_PATH path build_path)
+ #message("CUDA_COMPUTE_BUILD_PATH([${path}] ${build_path})")
+ # Only deal with CMake style paths from here on out
+ file(TO_CMAKE_PATH "${path}" bpath)
+ if (IS_ABSOLUTE "${bpath}")
+ # Absolute paths are generally unnessary, especially if something like
+ # FILE(GLOB_RECURSE) is used to pick up the files.
+ file(RELATIVE_PATH bpath "${CMAKE_CURRENT_SOURCE_DIR}" "${bpath}")
+ endif()
+
+ # This recipie is from cmLocalGenerator::CreateSafeUniqueObjectFileName in the
+ # CMake source.
+
+ # Remove leading /
+ string(REGEX REPLACE "^[/]+" "" bpath "${bpath}")
+ # Avoid absolute paths by removing ':'
+ string(REPLACE ":" "_" bpath "${bpath}")
+ # Avoid relative paths that go up the tree
+ string(REPLACE "../" "__/" bpath "${bpath}")
+ # Avoid spaces
+ string(REPLACE " " "_" bpath "${bpath}")
+
+ # Strip off the filename. I wait until here to do it, since removin the
+ # basename can make a path that looked like path/../basename turn into
+ # path/.. (notice the trailing slash).
+ get_filename_component(bpath "${bpath}" PATH)
+
+ set(${build_path} "${bpath}" PARENT_SCOPE)
+ #message("${build_path} = ${bpath}")
+endfunction()
+
+##############################################################################
+# This helper macro populates the following variables and setups up custom
+# commands and targets to invoke the nvcc compiler to generate C or PTX source
+# dependent upon the format parameter. The compiler is invoked once with -M
+# to generate a dependency file and a second time with -cuda or -ptx to generate
+# a .cpp or .ptx file.
+# INPUT:
+# cuda_target - Target name
+# format - PTX or OBJ
+# FILE1 .. FILEN - The remaining arguments are the sources to be wrapped.
+# OPTIONS - Extra options to NVCC
+# OUTPUT:
+# generated_files - List of generated files
+##############################################################################
+##############################################################################
+
+macro(CUDA_WRAP_SRCS cuda_target format generated_files)
+
+ if( ${format} MATCHES "PTX" )
+ set( compile_to_ptx ON )
+ elseif( ${format} MATCHES "OBJ")
+ set( compile_to_ptx OFF )
+ else()
+ message( FATAL_ERROR "Invalid format flag passed to CUDA_WRAP_SRCS: '${format}'. Use OBJ or PTX.")
+ endif()
+
+ # Set up all the command line flags here, so that they can be overridden on a per target basis.
+
+ set(nvcc_flags "")
+
+ # Emulation if the card isn't present.
+ if (CUDA_BUILD_EMULATION)
+ # Emulation.
+ set(nvcc_flags ${nvcc_flags} --device-emulation -D_DEVICEEMU -g)
+ else(CUDA_BUILD_EMULATION)
+ # Device mode. No flags necessary.
+ endif(CUDA_BUILD_EMULATION)
+
+ if(CUDA_HOST_COMPILATION_CPP)
+ set(CUDA_C_OR_CXX CXX)
+ else(CUDA_HOST_COMPILATION_CPP)
+ if(CUDA_VERSION VERSION_LESS "3.0")
+ set(nvcc_flags ${nvcc_flags} --host-compilation C)
+ else()
+ message(WARNING "--host-compilation flag is deprecated in CUDA version >= 3.0. Removing --host-compilation C flag" )
+ endif()
+ set(CUDA_C_OR_CXX C)
+ endif(CUDA_HOST_COMPILATION_CPP)
+
+ set(generated_extension ${CMAKE_${CUDA_C_OR_CXX}_OUTPUT_EXTENSION})
+
+ if(CUDA_64_BIT_DEVICE_CODE)
+ set(nvcc_flags ${nvcc_flags} -m64)
+ else()
+ set(nvcc_flags ${nvcc_flags} -m32)
+ endif()
+
+ # This needs to be passed in at this stage, because VS needs to fill out the
+ # value of VCInstallDir from within VS.
+ if(CMAKE_GENERATOR MATCHES "Visual Studio")
+ if( CMAKE_SIZEOF_VOID_P EQUAL 8 )
+ # Add nvcc flag for 64b Windows
+ set(ccbin_flags -D "\"CCBIN:PATH=$(VCInstallDir)bin\"" )
+ endif()
+ endif()
+
+ # Figure out which configure we will use and pass that in as an argument to
+ # the script. We need to defer the decision until compilation time, because
+ # for VS projects we won't know if we are making a debug or release build
+ # until build time.
+ if(CMAKE_GENERATOR MATCHES "Visual Studio")
+ set( CUDA_build_configuration "$(ConfigurationName)" )
+ else()
+ set( CUDA_build_configuration "${CMAKE_BUILD_TYPE}")
+ endif()
+
+ # Initialize our list of includes with the user ones followed by the CUDA system ones.
+ set(CUDA_NVCC_INCLUDE_ARGS ${CUDA_NVCC_INCLUDE_ARGS_USER} "-I${CUDA_INCLUDE_DIRS}")
+ # Get the include directories for this directory and use them for our nvcc command.
+ get_directory_property(CUDA_NVCC_INCLUDE_DIRECTORIES INCLUDE_DIRECTORIES)
+ if(CUDA_NVCC_INCLUDE_DIRECTORIES)
+ foreach(dir ${CUDA_NVCC_INCLUDE_DIRECTORIES})
+ list(APPEND CUDA_NVCC_INCLUDE_ARGS -I${dir})
+ endforeach()
+ endif()
+
+ # Reset these variables
+ set(CUDA_WRAP_OPTION_NVCC_FLAGS)
+ foreach(config ${CUDA_configuration_types})
+ string(TOUPPER ${config} config_upper)
+ set(CUDA_WRAP_OPTION_NVCC_FLAGS_${config_upper})
+ endforeach()
+
+ CUDA_GET_SOURCES_AND_OPTIONS(_cuda_wrap_sources _cuda_wrap_cmake_options _cuda_wrap_options ${ARGN})
+ CUDA_PARSE_NVCC_OPTIONS(CUDA_WRAP_OPTION_NVCC_FLAGS ${_cuda_wrap_options})
+
+ # Figure out if we are building a shared library. BUILD_SHARED_LIBS is
+ # respected in CUDA_ADD_LIBRARY.
+ set(_cuda_build_shared_libs FALSE)
+ # SHARED, MODULE
+ list(FIND _cuda_wrap_cmake_options SHARED _cuda_found_SHARED)
+ list(FIND _cuda_wrap_cmake_options MODULE _cuda_found_MODULE)
+ if(_cuda_found_SHARED GREATER -1 OR _cuda_found_MODULE GREATER -1)
+ set(_cuda_build_shared_libs TRUE)
+ endif()
+ # STATIC
+ list(FIND _cuda_wrap_cmake_options STATIC _cuda_found_STATIC)
+ if(_cuda_found_STATIC GREATER -1)
+ set(_cuda_build_shared_libs FALSE)
+ endif()
+
+ # CUDA_HOST_FLAGS
+ if(_cuda_build_shared_libs)
+ # If we are setting up code for a shared library, then we need to add extra flags for
+ # compiling objects for shared libraries.
+ set(CUDA_HOST_SHARED_FLAGS ${CMAKE_SHARED_LIBRARY_${CUDA_C_OR_CXX}_FLAGS})
+ else()
+ set(CUDA_HOST_SHARED_FLAGS)
+ endif()
+ # Only add the CMAKE_{C,CXX}_FLAGS if we are propagating host flags. We
+ # always need to set the SHARED_FLAGS, though.
+ if(CUDA_PROPAGATE_HOST_FLAGS)
+ set(CUDA_HOST_FLAGS "set(CMAKE_HOST_FLAGS ${CMAKE_${CUDA_C_OR_CXX}_FLAGS} ${CUDA_HOST_SHARED_FLAGS})")
+ else()
+ set(CUDA_HOST_FLAGS "set(CMAKE_HOST_FLAGS ${CUDA_HOST_SHARED_FLAGS})")
+ endif()
+
+ set(CUDA_NVCC_FLAGS_CONFIG "# Build specific configuration flags")
+ # Loop over all the configuration types to generate appropriate flags for run_nvcc.cmake
+ foreach(config ${CUDA_configuration_types})
+ string(TOUPPER ${config} config_upper)
+ # CMAKE_FLAGS are strings and not lists. By not putting quotes around CMAKE_FLAGS
+ # we convert the strings to lists (like we want).
+
+ if(CUDA_PROPAGATE_HOST_FLAGS)
+ # nvcc chokes on -g3 in versions previous to 3.0, so replace it with -g
+ if(CMAKE_COMPILER_IS_GNUCC AND CUDA_VERSION VERSION_LESS "3.0")
+ string(REPLACE "-g3" "-g" _cuda_C_FLAGS "${CMAKE_${CUDA_C_OR_CXX}_FLAGS_${config_upper}}")
+ else()
+ set(_cuda_C_FLAGS "${CMAKE_${CUDA_C_OR_CXX}_FLAGS_${config_upper}}")
+ endif()
+
+ set(CUDA_HOST_FLAGS "${CUDA_HOST_FLAGS}\nset(CMAKE_HOST_FLAGS_${config_upper} ${_cuda_C_FLAGS})")
+ endif()
+
+ # Note that if we ever want CUDA_NVCC_FLAGS_<CONFIG> to be string (instead of a list
+ # like it is currently), we can remove the quotes around the
+ # ${CUDA_NVCC_FLAGS_${config_upper}} variable like the CMAKE_HOST_FLAGS_<CONFIG> variable.
+ 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()
+
+ if(compile_to_ptx)
+ # Don't use any of the host compilation flags for PTX targets.
+ set(CUDA_HOST_FLAGS)
+ set(CUDA_NVCC_FLAGS_CONFIG)
+ endif()
+
+ # Get the list of definitions from the directory property
+ get_directory_property(CUDA_NVCC_DEFINITIONS COMPILE_DEFINITIONS)
+ if(CUDA_NVCC_DEFINITIONS)
+ foreach(_definition ${CUDA_NVCC_DEFINITIONS})
+ list(APPEND nvcc_flags "-D${_definition}")
+ endforeach()
+ endif()
+
+ if(_cuda_build_shared_libs)
+ list(APPEND nvcc_flags "-D${cuda_target}_EXPORTS")
+ endif()
+
+ # Reset the output variable
+ set(_cuda_wrap_generated_files "")
+
+ # Iterate over the macro arguments and create custom
+ # commands for all the .cu 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)
+
+ # Determine output directory
+ cuda_compute_build_path("${file}" cuda_build_path)
+ set(cuda_compile_intermediate_directory "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${cuda_target}.dir/${cuda_build_path}")
+ if(CUDA_GENERATED_OUTPUT_DIR)
+ set(cuda_compile_output_dir "${CUDA_GENERATED_OUTPUT_DIR}")
+ else()
+ if ( compile_to_ptx )
+ set(cuda_compile_output_dir "${CMAKE_CURRENT_BINARY_DIR}")
+ else()
+ set(cuda_compile_output_dir "${cuda_compile_intermediate_directory}")
+ endif()
+ endif()
+
+ # Add a custom target to generate a c or ptx file. ######################
+
+ get_filename_component( basename ${file} NAME )
+ if( compile_to_ptx )
+ set(generated_file_path "${cuda_compile_output_dir}")
+ set(generated_file_basename "${cuda_target}_generated_${basename}.ptx")
+ set(format_flag "-ptx")
+ file(MAKE_DIRECTORY "${cuda_compile_output_dir}")
+ else( compile_to_ptx )
+ set(generated_file_path "${cuda_compile_output_dir}/${CMAKE_CFG_INTDIR}")
+ set(generated_file_basename "${cuda_target}_generated_${basename}${generated_extension}")
+ set(format_flag "-c")
+ endif( compile_to_ptx )
+
+ # Set all of our file names. Make sure that whatever filenames that have
+ # generated_file_path in them get passed in through as a command line
+ # argument, so that the ${CMAKE_CFG_INTDIR} gets expanded at run time
+ # instead of configure time.
+ set(generated_file "${generated_file_path}/${generated_file_basename}")
+ set(cmake_dependency_file "${cuda_compile_intermediate_directory}/${generated_file_basename}.depend")
+ set(NVCC_generated_dependency_file "${cuda_compile_intermediate_directory}/${generated_file_basename}.NVCC-depend")
+ set(generated_cubin_file "${generated_file_path}/${generated_file_basename}.cubin.txt")
+ set(custom_target_script "${cuda_compile_intermediate_directory}/${generated_file_basename}.cmake")
+
+ # Setup properties for obj files:
+ if( NOT compile_to_ptx )
+ set_source_files_properties("${generated_file}"
+ PROPERTIES
+ EXTERNAL_OBJECT true # This is an object file not to be compiled, but only be linked.
+ )
+ endif()
+
+ # Don't add CMAKE_CURRENT_SOURCE_DIR if the path is already an absolute path.
+ get_filename_component(file_path "${file}" PATH)
+ if(IS_ABSOLUTE "${file_path}")
+ set(source_file "${file}")
+ else()
+ set(source_file "${CMAKE_CURRENT_SOURCE_DIR}/${file}")
+ endif()
+
+ # Bring in the dependencies. Creates a variable CUDA_NVCC_DEPEND #######
+ cuda_include_nvcc_dependencies(${cmake_dependency_file})
+
+ # Convience string for output ###########################################
+ if(CUDA_BUILD_EMULATION)
+ set(cuda_build_type "Emulation")
+ else(CUDA_BUILD_EMULATION)
+ set(cuda_build_type "Device")
+ endif(CUDA_BUILD_EMULATION)
+
+ # Build the NVCC made dependency file ###################################
+ set(build_cubin OFF)
+ if ( NOT CUDA_BUILD_EMULATION AND CUDA_BUILD_CUBIN )
+ if ( NOT compile_to_ptx )
+ set ( build_cubin ON )
+ endif( NOT compile_to_ptx )
+ endif( NOT CUDA_BUILD_EMULATION AND CUDA_BUILD_CUBIN )
+
+ # Configure the build script
+ configure_file("${CUDA_run_nvcc}" "${custom_target_script}" @ONLY)
+
+ # So if a user specifies the same cuda file as input more than once, you
+ # can have bad things happen with dependencies. Here we check an option
+ # to see if this is the behavior they want.
+ if(CUDA_ATTACH_VS_BUILD_RULE_TO_CUDA_FILE)
+ set(main_dep MAIN_DEPENDENCY ${source_file})
+ else()
+ set(main_dep DEPENDS ${source_file})
+ endif()
+
+ if(CUDA_VERBOSE_BUILD)
+ set(verbose_output ON)
+ elseif(CMAKE_GENERATOR MATCHES "Makefiles")
+ set(verbose_output "$(VERBOSE)")
+ else()
+ set(verbose_output OFF)
+ endif()
+
+ # 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}")
+ else()
+ set(cuda_build_comment_string "Building NVCC (${cuda_build_type}) object ${generated_file_relative_path}")
+ endif()
+
+ # Build the generated file and dependency file ##########################
+ add_custom_command(
+ OUTPUT ${generated_file}
+ # These output files depend on the source_file and the contents of cmake_dependency_file
+ ${main_dep}
+ DEPENDS ${CUDA_NVCC_DEPEND}
+ DEPENDS ${custom_target_script}
+ # Make sure the output directory exists before trying to write to it.
+ COMMAND ${CMAKE_COMMAND} -E make_directory "${generated_file_path}"
+ COMMAND ${CMAKE_COMMAND} ARGS
+ -D verbose:BOOL=${verbose_output}
+ ${ccbin_flags}
+ -D build_configuration:STRING=${CUDA_build_configuration}
+ -D "generated_file:STRING=${generated_file}"
+ -D "generated_cubin_file:STRING=${generated_cubin_file}"
+ -P "${custom_target_script}"
+ WORKING_DIRECTORY "${cuda_compile_intermediate_directory}"
+ COMMENT "${cuda_build_comment_string}"
+ )
+
+ # Make sure the build system knows the file is generated.
+ set_source_files_properties(${generated_file} PROPERTIES GENERATED TRUE)
+
+ # Don't add the object file to the list of generated files if we are using
+ # visual studio and we are attaching the build rule to the cuda file. VS
+ # will add our object file to the linker automatically for us.
+ set(cuda_add_generated_file TRUE)
+
+ if(NOT compile_to_ptx AND CMAKE_GENERATOR MATCHES "Visual Studio" AND CUDA_ATTACH_VS_BUILD_RULE_TO_CUDA_FILE)
+ # Visual Studio 8 crashes when you close the solution when you don't add the object file.
+ if(NOT CMAKE_GENERATOR MATCHES "Visual Studio 8")
+ #message("Not adding ${generated_file}")
+ set(cuda_add_generated_file FALSE)
+ endif()
+ endif()
+
+ if(cuda_add_generated_file)
+ list(APPEND _cuda_wrap_generated_files ${generated_file})
+ endif()
+
+ # Add the other files that we want cmake to clean on a cleanup ##########
+ list(APPEND CUDA_ADDITIONAL_CLEAN_FILES "${cmake_dependency_file}")
+ list(REMOVE_DUPLICATES CUDA_ADDITIONAL_CLEAN_FILES)
+ set(CUDA_ADDITIONAL_CLEAN_FILES ${CUDA_ADDITIONAL_CLEAN_FILES} CACHE INTERNAL "List of intermediate files that are part of the cuda dependency scanning.")
+
+ endif(${file} MATCHES ".*\\.cu$" AND NOT _is_header)
+ endforeach(file)
+
+ # Set the return parameter
+ set(${generated_files} ${_cuda_wrap_generated_files})
+endmacro(CUDA_WRAP_SRCS)
+
+
+###############################################################################
+###############################################################################
+# ADD LIBRARY
+###############################################################################
+###############################################################################
+macro(CUDA_ADD_LIBRARY cuda_target)
+
+ CUDA_ADD_CUDA_INCLUDE_ONCE()
+
+ # Separate the sources from the options
+ CUDA_GET_SOURCES_AND_OPTIONS(_sources _cmake_options _options ${ARGN})
+ CUDA_BUILD_SHARED_LIBRARY(_cuda_shared_flag ${ARGN})
+ # Create custom commands and targets for each file.
+ CUDA_WRAP_SRCS( ${cuda_target} OBJ _generated_files ${_sources}
+ ${_cmake_options} ${_cuda_shared_flag}
+ OPTIONS ${_options} )
+
+ # Add the library.
+ add_library(${cuda_target} ${_cmake_options}
+ ${_generated_files}
+ ${_sources}
+ )
+
+ target_link_libraries(${cuda_target}
+ ${CUDA_LIBRARIES}
+ )
+
+ # We need to set the linker language based on what the expected generated file
+ # would be. CUDA_C_OR_CXX is computed based on CUDA_HOST_COMPILATION_CPP.
+ set_target_properties(${cuda_target}
+ PROPERTIES
+ LINKER_LANGUAGE ${CUDA_C_OR_CXX}
+ )
+
+endmacro(CUDA_ADD_LIBRARY cuda_target)
+
+
+###############################################################################
+###############################################################################
+# ADD EXECUTABLE
+###############################################################################
+###############################################################################
+macro(CUDA_ADD_EXECUTABLE cuda_target)
+
+ CUDA_ADD_CUDA_INCLUDE_ONCE()
+
+ # 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_target} OBJ _generated_files ${_sources} OPTIONS ${_options} )
+
+ # Add the library.
+ add_executable(${cuda_target} ${_cmake_options}
+ ${_generated_files}
+ ${_sources}
+ )
+
+ target_link_libraries(${cuda_target}
+ ${CUDA_LIBRARIES}
+ )
+
+ # We need to set the linker language based on what the expected generated file
+ # would be. CUDA_C_OR_CXX is computed based on CUDA_HOST_COMPILATION_CPP.
+ set_target_properties(${cuda_target}
+ PROPERTIES
+ LINKER_LANGUAGE ${CUDA_C_OR_CXX}
+ )
+
+endmacro(CUDA_ADD_EXECUTABLE cuda_target)
+
+
+###############################################################################
+###############################################################################
+# CUDA COMPILE
+###############################################################################
+###############################################################################
+macro(CUDA_COMPILE 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}
+ OPTIONS ${_options} )
+
+ set( ${generated_files} ${_generated_files})
+
+endmacro(CUDA_COMPILE)
+
+
+###############################################################################
+###############################################################################
+# CUDA COMPILE PTX
+###############################################################################
+###############################################################################
+macro(CUDA_COMPILE_PTX 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_ptx PTX _generated_files ${_sources} ${_cmake_options}
+ OPTIONS ${_options} )
+
+ set( ${generated_files} ${_generated_files})
+
+endmacro(CUDA_COMPILE_PTX)
+
+###############################################################################
+###############################################################################
+# CUDA ADD CUFFT TO TARGET
+###############################################################################
+###############################################################################
+macro(CUDA_ADD_CUFFT_TO_TARGET target)
+ if (CUDA_BUILD_EMULATION)
+ target_link_libraries(${target} ${CUDA_cufftemu_LIBRARY})
+ else()
+ target_link_libraries(${target} ${CUDA_cufft_LIBRARY})
+ endif()
+endmacro()
+
+###############################################################################
+###############################################################################
+# CUDA ADD CUBLAS TO TARGET
+###############################################################################
+###############################################################################
+macro(CUDA_ADD_CUBLAS_TO_TARGET target)
+ if (CUDA_BUILD_EMULATION)
+ target_link_libraries(${target} ${CUDA_cublasemu_LIBRARY})
+ else()
+ target_link_libraries(${target} ${CUDA_cublas_LIBRARY})
+ endif()
+endmacro()
+
+###############################################################################
+###############################################################################
+# CUDA BUILD CLEAN TARGET
+###############################################################################
+###############################################################################
+macro(CUDA_BUILD_CLEAN_TARGET)
+ # Call this after you add all your CUDA targets, and you will get a convience
+ # target. You should also make clean after running this target to get the
+ # build system to generate all the code again.
+
+ set(cuda_clean_target_name clean_cuda_depends)
+ if (CMAKE_GENERATOR MATCHES "Visual Studio")
+ string(TOUPPER ${cuda_clean_target_name} cuda_clean_target_name)
+ endif()
+ add_custom_target(${cuda_clean_target_name}
+ COMMAND ${CMAKE_COMMAND} -E remove ${CUDA_ADDITIONAL_CLEAN_FILES})
+
+ # Clear out the variable, so the next time we configure it will be empty.
+ # This is useful so that the files won't persist in the list after targets
+ # have been removed.
+ set(CUDA_ADDITIONAL_CLEAN_FILES "" CACHE INTERNAL "List of intermediate files that are part of the cuda dependency scanning.")
+endmacro(CUDA_BUILD_CLEAN_TARGET)
diff --git a/Modules/FindCUDA/make2cmake.cmake b/Modules/FindCUDA/make2cmake.cmake
new file mode 100644
index 000000000..d41b72dc2
--- /dev/null
+++ b/Modules/FindCUDA/make2cmake.cmake
@@ -0,0 +1,93 @@
+# 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
+#
+# This code is licensed under the MIT License. See the FindCUDA.cmake script
+# for the text of the license.
+
+# The MIT License
+#
+# License for the specific language governing rights and limitations under
+# 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.
+#
+
+#######################################################################
+# This converts a file written in makefile syntax into one that can be included
+# by CMake.
+
+file(READ ${input_file} depend_text)
+
+if (${depend_text} MATCHES ".+")
+
+ # message("FOUND DEPENDS")
+
+ # Remember, four backslashes is escaped to one backslash in the string.
+ string(REGEX REPLACE "\\\\ " " " depend_text ${depend_text})
+
+ # This works for the nvcc -M generated dependency files.
+ string(REGEX REPLACE "^.* : " "" depend_text ${depend_text})
+ string(REGEX REPLACE "[ \\\\]*\n" ";" depend_text ${depend_text})
+
+ set(dependency_list "")
+
+ foreach(file ${depend_text})
+
+ string(REGEX REPLACE "^ +" "" file ${file})
+
+ # OK, now if we had a UNC path, nvcc has a tendency to only output the first '/'
+ # instead of '//'. Here we will test to see if the file exists, if it doesn't then
+ # try to prepend another '/' to the path and test again. If it still fails remove the
+ # path.
+
+ if(NOT EXISTS "${file}")
+ if (EXISTS "/${file}")
+ set(file "/${file}")
+ else()
+ message(WARNING " Removing non-existant dependency file: ${file}")
+ set(file "")
+ endif()
+ endif()
+
+ if(NOT IS_DIRECTORY "${file}")
+ # If softlinks start to matter, we should change this to REALPATH. For now we need
+ # to flatten paths, because nvcc can generate stuff like /bin/../include instead of
+ # just /include.
+ get_filename_component(file_absolute "${file}" ABSOLUTE)
+ list(APPEND dependency_list "${file_absolute}")
+ endif()
+
+ endforeach(file)
+
+else()
+ # message("FOUND NO DEPENDS")
+endif()
+
+# Remove the duplicate entries and sort them.
+list(REMOVE_DUPLICATES dependency_list)
+list(SORT dependency_list)
+
+foreach(file ${dependency_list})
+ set(cuda_nvcc_depend "${cuda_nvcc_depend} \"${file}\"\n")
+endforeach()
+
+file(WRITE ${output_file} "# Generated by: make2cmake.cmake\nSET(CUDA_NVCC_DEPEND\n ${cuda_nvcc_depend})\n\n")
diff --git a/Modules/FindCUDA/parse_cubin.cmake b/Modules/FindCUDA/parse_cubin.cmake
new file mode 100644
index 000000000..2518c6852
--- /dev/null
+++ b/Modules/FindCUDA/parse_cubin.cmake
@@ -0,0 +1,112 @@
+# 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
+#
+# This code is licensed under the MIT License. See the FindCUDA.cmake script
+# for the text of the license.
+
+# The MIT License
+#
+# License for the specific language governing rights and limitations under
+# 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.
+#
+
+#######################################################################
+# Parses a .cubin file produced by nvcc and reports statistics about the file.
+
+
+file(READ ${input_file} file_text)
+
+if (${file_text} MATCHES ".+")
+
+ # 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})
+
+ list(LENGTH file_text len)
+
+ foreach(line ${file_text})
+
+ # Only look at "code { }" blocks.
+ if(line MATCHES "^code")
+
+ # Break into individual lines.
+ string(REGEX REPLACE "\n" ";" line ${line})
+
+ foreach(entry ${line})
+
+ # Extract kernel names.
+ if (${entry} MATCHES "[^g]name = ([^ ]+)")
+ string(REGEX REPLACE ".* = ([^ ]+)" "\\1" entry ${entry})
+
+ # Check to see if the kernel name starts with "_"
+ set(skip FALSE)
+ # if (${entry} MATCHES "^_")
+ # Skip the rest of this block.
+ # message("Skipping ${entry}")
+ # set(skip TRUE)
+ # else (${entry} MATCHES "^_")
+ message("Kernel: ${entry}")
+ # endif (${entry} MATCHES "^_")
+
+ endif(${entry} MATCHES "[^g]name = ([^ ]+)")
+
+ # Skip the rest of the block if necessary
+ if(NOT skip)
+
+ # Registers
+ if (${entry} MATCHES "reg([ ]+)=([ ]+)([^ ]+)")
+ string(REGEX REPLACE ".*([ ]+)=([ ]+)([^ ]+)" "\\3" entry ${entry})
+ message("Registers: ${entry}")
+ endif()
+
+ # Local memory
+ if (${entry} MATCHES "lmem([ ]+)=([ ]+)([^ ]+)")
+ string(REGEX REPLACE ".*([ ]+)=([ ]+)([^ ]+)" "\\3" entry ${entry})
+ message("Local: ${entry}")
+ endif()
+
+ # Shared memory
+ if (${entry} MATCHES "smem([ ]+)=([ ]+)([^ ]+)")
+ string(REGEX REPLACE ".*([ ]+)=([ ]+)([^ ]+)" "\\3" entry ${entry})
+ message("Shared: ${entry}")
+ endif()
+
+ if (${entry} MATCHES "^}")
+ message("")
+ endif()
+
+ endif(NOT skip)
+
+
+ endforeach(entry)
+
+ endif(line MATCHES "^code")
+
+ endforeach(line)
+
+else()
+ # message("FOUND NO DEPENDS")
+endif()
+
+
diff --git a/Modules/FindCUDA/run_nvcc.cmake b/Modules/FindCUDA/run_nvcc.cmake
new file mode 100644
index 000000000..b31011c0e
--- /dev/null
+++ b/Modules/FindCUDA/run_nvcc.cmake
@@ -0,0 +1,280 @@
+# James Bigler, NVIDIA Corp (nvidia.com - jbigler)
+#
+# Copyright (c) 2008 - 2009 NVIDIA Corporation. All rights reserved.
+#
+# This code is licensed under the MIT License. See the FindCUDA.cmake script
+# for the text of the license.
+
+# The MIT License
+#
+# License for the specific language governing rights and limitations under
+# 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.
+
+
+##########################################################################
+# This file runs the nvcc commands to produce the desired output file along with
+# the dependency file needed by CMake to compute dependencies. In addition the
+# file checks the output of each command and if the command fails it deletes the
+# output files.
+
+# Input variables
+#
+# verbose:BOOL=<> OFF: Be as quiet as possible (default)
+# ON : Describe each step
+#
+# build_configuration:STRING=<> Typically one of Debug, MinSizeRel, Release, or
+# RelWithDebInfo, but it should match one of the
+# entries in CUDA_HOST_FLAGS. This is the build
+# configuration used when compiling the code. If
+# blank or unspecified Debug is assumed as this is
+# what CMake does.
+#
+# generated_file:STRING=<> File to generate. This argument must be passed in.
+#
+# generated_cubin_file:STRING=<> File to generate. This argument must be passed
+# in if build_cubin is true.
+
+if(NOT generated_file)
+ message(FATAL_ERROR "You must specify generated_file on the command line")
+endif()
+
+# Set these up as variables to make reading the generated file easier
+set(CMAKE_COMMAND "@CMAKE_COMMAND@") # path
+set(source_file "@source_file@") # path
+set(NVCC_generated_dependency_file "@NVCC_generated_dependency_file@") # path
+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
+# 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
+set(generated_file_internal "@generated_file@") # path
+set(generated_cubin_file_internal "@generated_cubin_file@") # path
+
+set(CUDA_NVCC_EXECUTABLE "@CUDA_NVCC_EXECUTABLE@") # path
+set(CUDA_NVCC_FLAGS @CUDA_NVCC_FLAGS@ ;; @CUDA_WRAP_OPTION_NVCC_FLAGS@) # list
+@CUDA_NVCC_FLAGS_CONFIG@
+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
+
+if(build_cubin AND NOT generated_cubin_file)
+ message(FATAL_ERROR "You must specify generated_cubin_file on the command line")
+endif()
+
+# This is the list of host compilation flags. It C or CXX should already have
+# been chosen by FindCUDA.cmake.
+@CUDA_HOST_FLAGS@
+
+# Take the compiler flags and package them up to be sent to the compiler via -Xcompiler
+set(nvcc_host_compiler_flags "")
+# If we weren't given a build_configuration, use Debug.
+if(NOT build_configuration)
+ set(build_configuration Debug)
+endif()
+string(TOUPPER "${build_configuration}" build_configuration)
+#message("CUDA_NVCC_HOST_COMPILER_FLAGS = ${CUDA_NVCC_HOST_COMPILER_FLAGS}")
+foreach(flag ${CMAKE_HOST_FLAGS} ${CMAKE_HOST_FLAGS_${build_configuration}})
+ # Extra quotes are added around each flag to help nvcc parse out flags with spaces.
+ set(nvcc_host_compiler_flags "${nvcc_host_compiler_flags},\"${flag}\"")
+endforeach()
+if (nvcc_host_compiler_flags)
+ set(nvcc_host_compiler_flags "-Xcompiler" ${nvcc_host_compiler_flags})
+endif()
+#message("nvcc_host_compiler_flags = \"${nvcc_host_compiler_flags}\"")
+# Add the build specific configuration flags
+list(APPEND CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS_${build_configuration}})
+
+if(DEFINED CCBIN)
+ set(CCBIN -ccbin "${CCBIN}")
+endif()
+
+# cuda_execute_process - Executes a command with optional command echo and status message.
+#
+# status - Status message to print if verbose is true
+# command - COMMAND argument from the usual execute_process argument structure
+# ARGN - Remaining arguments are the command with arguments
+#
+# CUDA_result - return value from running the command
+#
+# Make this a macro instead of a function, so that things like RESULT_VARIABLE
+# and other return variables are present after executing the process.
+macro(cuda_execute_process status command)
+ set(_command ${command})
+ if(NOT _command STREQUAL "COMMAND")
+ message(FATAL_ERROR "Malformed call to cuda_execute_process. Missing COMMAND as second argument. (command = ${command})")
+ endif()
+ if(verbose)
+ execute_process(COMMAND "${CMAKE_COMMAND}" -E echo -- ${status})
+ # Now we need to build up our command string. We are accounting for quotes
+ # and spaces, anything else is left up to the user to fix if they want to
+ # copy and paste a runnable command line.
+ set(cuda_execute_process_string)
+ foreach(arg ${ARGN})
+ # If there are quotes, excape them, so they come through.
+ string(REPLACE "\"" "\\\"" arg ${arg})
+ # Args with spaces need quotes around them to get them to be parsed as a single argument.
+ if(arg MATCHES " ")
+ list(APPEND cuda_execute_process_string "\"${arg}\"")
+ else()
+ list(APPEND cuda_execute_process_string ${arg})
+ endif()
+ endforeach()
+ # Echo the command
+ execute_process(COMMAND ${CMAKE_COMMAND} -E echo ${cuda_execute_process_string})
+ endif(verbose)
+ # Run the command
+ execute_process(COMMAND ${ARGN} RESULT_VARIABLE CUDA_result )
+endmacro()
+
+# Delete the target file
+cuda_execute_process(
+ "Removing ${generated_file}"
+ COMMAND "${CMAKE_COMMAND}" -E remove "${generated_file}"
+ )
+
+# For CUDA 2.3 and below, -G -M doesn't work, so remove the -G flag
+# for dependency generation and hope for the best.
+set(depends_CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS}")
+set(CUDA_VERSION @CUDA_VERSION@)
+if(CUDA_VERSION VERSION_LESS "3.0")
+ cmake_policy(PUSH)
+ # CMake policy 0007 NEW states that empty list elements are not
+ # ignored. I'm just setting it to avoid the warning that's printed.
+ cmake_policy(SET CMP0007 NEW)
+ # Note that this will remove all occurances of -G.
+ list(REMOVE_ITEM depends_CUDA_NVCC_FLAGS "-G")
+ cmake_policy(POP)
+endif()
+
+# nvcc doesn't define __CUDACC__ for some reason when generating dependency files. This
+# can cause incorrect dependencies when #including files based on this macro which is
+# defined in the generating passes of nvcc invokation. We will go ahead and manually
+# define this for now until a future version fixes this bug.
+set(CUDACC_DEFINE -D__CUDACC__)
+
+# Generate the dependency file
+cuda_execute_process(
+ "Generating dependency file: ${NVCC_generated_dependency_file}"
+ COMMAND "${CUDA_NVCC_EXECUTABLE}"
+ -M
+ ${CUDACC_DEFINE}
+ "${source_file}"
+ -o "${NVCC_generated_dependency_file}"
+ ${CCBIN}
+ ${nvcc_flags}
+ ${nvcc_host_compiler_flags}
+ ${depends_CUDA_NVCC_FLAGS}
+ -DNVCC
+ ${CUDA_NVCC_INCLUDE_ARGS}
+ )
+
+if(CUDA_result)
+ message(FATAL_ERROR "Error generating ${generated_file}")
+endif()
+
+# Generate the cmake readable dependency file to a temp file. Don't put the
+# quotes just around the filenames for the input_file and output_file variables.
+# CMake will pass the quotes through and not be able to find the file.
+cuda_execute_process(
+ "Generating temporary cmake readable file: ${cmake_dependency_file}.tmp"
+ COMMAND "${CMAKE_COMMAND}"
+ -D "input_file:FILEPATH=${NVCC_generated_dependency_file}"
+ -D "output_file:FILEPATH=${cmake_dependency_file}.tmp"
+ -P "${CUDA_make2cmake}"
+ )
+
+if(CUDA_result)
+ message(FATAL_ERROR "Error generating ${generated_file}")
+endif()
+
+# Copy the file if it is different
+cuda_execute_process(
+ "Copy if different ${cmake_dependency_file}.tmp to ${cmake_dependency_file}"
+ COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${cmake_dependency_file}.tmp" "${cmake_dependency_file}"
+ )
+
+if(CUDA_result)
+ message(FATAL_ERROR "Error generating ${generated_file}")
+endif()
+
+# Delete the temporary file
+cuda_execute_process(
+ "Removing ${cmake_dependency_file}.tmp and ${NVCC_generated_dependency_file}"
+ COMMAND "${CMAKE_COMMAND}" -E remove "${cmake_dependency_file}.tmp" "${NVCC_generated_dependency_file}"
+ )
+
+if(CUDA_result)
+ message(FATAL_ERROR "Error generating ${generated_file}")
+endif()
+
+# Generate the code
+cuda_execute_process(
+ "Generating ${generated_file}"
+ COMMAND "${CUDA_NVCC_EXECUTABLE}"
+ "${source_file}"
+ ${format_flag} -o "${generated_file}"
+ ${CCBIN}
+ ${nvcc_flags}
+ ${nvcc_host_compiler_flags}
+ ${CUDA_NVCC_FLAGS}
+ -DNVCC
+ ${CUDA_NVCC_INCLUDE_ARGS}
+ )
+
+if(CUDA_result)
+ # Since nvcc can sometimes leave half done files make sure that we delete the output file.
+ cuda_execute_process(
+ "Removing ${generated_file}"
+ COMMAND "${CMAKE_COMMAND}" -E remove "${generated_file}"
+ )
+ message(FATAL_ERROR "Error generating file ${generated_file}")
+else()
+ if(verbose)
+ message("Generated ${generated_file} successfully.")
+ endif()
+endif()
+
+# Cubin resource report commands.
+if( build_cubin )
+ # Run with -cubin to produce resource usage report.
+ cuda_execute_process(
+ "Generating ${generated_cubin_file}"
+ COMMAND "${CUDA_NVCC_EXECUTABLE}"
+ "${source_file}"
+ ${CUDA_NVCC_FLAGS}
+ ${nvcc_flags}
+ ${CCBIN}
+ ${nvcc_host_compiler_flags}
+ -DNVCC
+ -cubin
+ -o "${generated_cubin_file}"
+ ${CUDA_NVCC_INCLUDE_ARGS}
+ )
+
+ # Execute the parser script.
+ cuda_execute_process(
+ "Executing the parser script"
+ COMMAND "${CMAKE_COMMAND}"
+ -D "input_file:STRING=${generated_cubin_file}"
+ -P "${CUDA_parse_cubin}"
+ )
+
+endif( build_cubin )
diff --git a/Modules/FindCURL.cmake b/Modules/FindCURL.cmake
new file mode 100644
index 000000000..cc00d53f4
--- /dev/null
+++ b/Modules/FindCURL.cmake
@@ -0,0 +1,59 @@
+# - 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)
+
+#=============================================================================
+# Copyright 2006-2009 Kitware, Inc.
+# Copyright 2012 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.)
+
+# Look for the header file.
+FIND_PATH(CURL_INCLUDE_DIR NAMES curl/curl.h)
+MARK_AS_ADVANCED(CURL_INCLUDE_DIR)
+
+# Look for the library.
+FIND_LIBRARY(CURL_LIBRARY NAMES
+ curl
+ # Windows MSVC prebuilts:
+ curllib
+ libcurl_imp
+ curllib_static
+)
+MARK_AS_ADVANCED(CURL_LIBRARY)
+
+IF(CURL_INCLUDE_DIR)
+ FOREACH(_curl_version_header curlver.h curl.h)
+ IF(EXISTS "${CURL_INCLUDE_DIR}/curl/${_curl_version_header}")
+ FILE(STRINGS "${CURL_INCLUDE_DIR}/curl/${_curl_version_header}" curl_version_str REGEX "^#define[\t ]+LIBCURL_VERSION[\t ]+\".*\"")
+
+ STRING(REGEX REPLACE "^#define[\t ]+LIBCURL_VERSION[\t ]+\"([^\"]*)\".*" "\\1" CURL_VERSION_STRING "${curl_version_str}")
+ UNSET(curl_version_str)
+ BREAK()
+ ENDIF()
+ ENDFOREACH(_curl_version_header)
+ENDIF()
+
+# handle the QUIETLY and REQUIRED arguments and set CURL_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(CURL
+ REQUIRED_VARS CURL_LIBRARY CURL_INCLUDE_DIR
+ VERSION_VAR CURL_VERSION_STRING)
+
+IF(CURL_FOUND)
+ SET(CURL_LIBRARIES ${CURL_LIBRARY})
+ SET(CURL_INCLUDE_DIRS ${CURL_INCLUDE_DIR})
+ENDIF(CURL_FOUND)
diff --git a/Modules/FindCVS.cmake b/Modules/FindCVS.cmake
new file mode 100644
index 000000000..57680bd97
--- /dev/null
+++ b/Modules/FindCVS.cmake
@@ -0,0 +1,69 @@
+# The module defines the following variables:
+# 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(CVS_FOUND)
+
+#=============================================================================
+# Copyright 2008-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.)
+
+# CVSNT
+
+get_filename_component(
+ CVSNT_TypeLib_Win32
+ "[HKEY_CLASSES_ROOT\\TypeLib\\{2BDF7A65-0BFE-4B1A-9205-9AB900C7D0DA}\\1.0\\0\\win32]"
+ PATH)
+
+get_filename_component(
+ CVSNT_Services_EventMessagePath
+ "[HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Services\\Eventlog\\Application\\cvsnt;EventMessageFile]"
+ PATH)
+
+# WinCVS (in case CVSNT was installed in the same directory)
+
+get_filename_component(
+ WinCVS_Folder_Command
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\Folder\\shell\\wincvs\\command]"
+ PATH)
+
+# TortoiseCVS (in case CVSNT was installed in the same directory)
+
+get_filename_component(
+ TortoiseCVS_Folder_Command
+ "[HKEY_CLASSES_ROOT\\CVS\\shell\\open\\command]"
+ PATH)
+
+get_filename_component(
+ TortoiseCVS_DefaultIcon
+ "[HKEY_CLASSES_ROOT\\CVS\\DefaultIcon]"
+ PATH)
+
+find_program(CVS_EXECUTABLE cvs
+ ${TortoiseCVS_DefaultIcon}
+ ${TortoiseCVS_Folder_Command}
+ ${WinCVS_Folder_Command}
+ ${CVSNT_Services_EventMessagePath}
+ ${CVSNT_TypeLib_Win32}
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\CVS\\Pserver;InstallPath]"
+ DOC "CVS command line client"
+ )
+mark_as_advanced(CVS_EXECUTABLE)
+
+# Handle the QUIETLY and REQUIRED arguments and set CVS_FOUND to TRUE if
+# all listed variables are TRUE
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+find_package_handle_standard_args(CVS DEFAULT_MSG CVS_EXECUTABLE)
diff --git a/Modules/FindCoin3D.cmake b/Modules/FindCoin3D.cmake
new file mode 100644
index 000000000..8bfe97acc
--- /dev/null
+++ b/Modules/FindCoin3D.cmake
@@ -0,0 +1,84 @@
+# - 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/
+#
+# 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
+#
+
+#=============================================================================
+# Copyright 2008-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.)
+
+IF (WIN32)
+ IF (CYGWIN)
+
+ FIND_PATH(COIN3D_INCLUDE_DIRS Inventor/So.h)
+ FIND_LIBRARY(COIN3D_LIBRARIES Coin)
+
+ ELSE (CYGWIN)
+
+ FIND_PATH(COIN3D_INCLUDE_DIRS Inventor/So.h
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\SIM\\Coin3D\\2;Installation Path]/include"
+ )
+
+ FIND_LIBRARY(COIN3D_LIBRARY_DEBUG coin2d
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\SIM\\Coin3D\\2;Installation Path]/lib"
+ )
+
+ FIND_LIBRARY(COIN3D_LIBRARY_RELEASE coin2
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\SIM\\Coin3D\\2;Installation Path]/lib"
+ )
+
+ IF (COIN3D_LIBRARY_DEBUG AND COIN3D_LIBRARY_RELEASE)
+ SET(COIN3D_LIBRARIES optimized ${COIN3D_LIBRARY_RELEASE}
+ debug ${COIN3D_LIBRARY_DEBUG})
+ ELSE (COIN3D_LIBRARY_DEBUG AND COIN3D_LIBRARY_RELEASE)
+ IF (COIN3D_LIBRARY_DEBUG)
+ SET (COIN3D_LIBRARIES ${COIN3D_LIBRARY_DEBUG})
+ ENDIF (COIN3D_LIBRARY_DEBUG)
+ IF (COIN3D_LIBRARY_RELEASE)
+ SET (COIN3D_LIBRARIES ${COIN3D_LIBRARY_RELEASE})
+ ENDIF (COIN3D_LIBRARY_RELEASE)
+ ENDIF (COIN3D_LIBRARY_DEBUG AND COIN3D_LIBRARY_RELEASE)
+
+ ENDIF (CYGWIN)
+
+ELSE (WIN32)
+ IF(APPLE)
+ FIND_PATH(COIN3D_INCLUDE_DIRS Inventor/So.h
+ /Library/Frameworks/Inventor.framework/Headers
+ )
+ FIND_LIBRARY(COIN3D_LIBRARIES Coin
+ /Library/Frameworks/Inventor.framework/Libraries
+ )
+ SET(COIN3D_LIBRARIES "-framework Coin3d" CACHE STRING "Coin3D library for OSX")
+ ELSE(APPLE)
+
+ FIND_PATH(COIN3D_INCLUDE_DIRS Inventor/So.h)
+ FIND_LIBRARY(COIN3D_LIBRARIES Coin)
+
+ ENDIF(APPLE)
+
+ENDIF (WIN32)
+
+# handle the QUIETLY and REQUIRED arguments and set COIN3D_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Coin3D DEFAULT_MSG COIN3D_LIBRARIES COIN3D_INCLUDE_DIRS)
+
+MARK_AS_ADVANCED(COIN3D_INCLUDE_DIRS COIN3D_LIBRARIES )
+
+
diff --git a/Modules/FindCups.cmake b/Modules/FindCups.cmake
new file mode 100644
index 000000000..3862f7ddf
--- /dev/null
+++ b/Modules/FindCups.cmake
@@ -0,0 +1,69 @@
+# - 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)
+
+#=============================================================================
+# Copyright 2006-2009 Kitware, Inc.
+# Copyright 2006 Alexander Neundorf <neundorf@kde.org>
+# Copyright 2012 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.)
+
+find_path(CUPS_INCLUDE_DIR cups/cups.h )
+
+find_library(CUPS_LIBRARIES NAMES cups )
+
+if (CUPS_INCLUDE_DIR AND CUPS_LIBRARIES AND CUPS_REQUIRE_IPP_DELETE_ATTRIBUTE)
+ include(CheckLibraryExists)
+
+ # ippDeleteAttribute is new in cups-1.1.19 (and used by kdeprint)
+ CHECK_LIBRARY_EXISTS(cups ippDeleteAttribute "" CUPS_HAS_IPP_DELETE_ATTRIBUTE)
+endif (CUPS_INCLUDE_DIR AND CUPS_LIBRARIES AND CUPS_REQUIRE_IPP_DELETE_ATTRIBUTE)
+
+if (CUPS_INCLUDE_DIR AND EXISTS "${CUPS_INCLUDE_DIR}/cups/cups.h")
+ file(STRINGS "${CUPS_INCLUDE_DIR}/cups/cups.h" cups_version_str
+ REGEX "^#[\t ]*define[\t ]+CUPS_VERSION_(MAJOR|MINOR|PATCH)[\t ]+[0-9]+$")
+
+ 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(CUPS_VERSION_STRING)
+ set(CUPS_VERSION_STRING "${CUPS_VERSION_STRING}.${CUPS_VERSION_PART}")
+ else(CUPS_VERSION_STRING)
+ set(CUPS_VERSION_STRING "${CUPS_VERSION_PART}")
+ endif(CUPS_VERSION_STRING)
+ endif()
+ endforeach(VLINE)
+ endforeach(VPART)
+endif (CUPS_INCLUDE_DIR AND EXISTS "${CUPS_INCLUDE_DIR}/cups/cups.h")
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+
+if (CUPS_REQUIRE_IPP_DELETE_ATTRIBUTE)
+ FIND_PACKAGE_HANDLE_STANDARD_ARGS(Cups
+ REQUIRED_VARS CUPS_LIBRARIES CUPS_INCLUDE_DIR CUPS_HAS_IPP_DELETE_ATTRIBUTE
+ VERSION_VAR CUPS_VERSION_STRING)
+else (CUPS_REQUIRE_IPP_DELETE_ATTRIBUTE)
+ FIND_PACKAGE_HANDLE_STANDARD_ARGS(Cups
+ REQUIRED_VARS CUPS_LIBRARIES CUPS_INCLUDE_DIR
+ VERSION_VAR CUPS_VERSION_STRING)
+endif (CUPS_REQUIRE_IPP_DELETE_ATTRIBUTE)
+
+mark_as_advanced(CUPS_INCLUDE_DIR CUPS_LIBRARIES)
diff --git a/Modules/FindCurses.cmake b/Modules/FindCurses.cmake
new file mode 100644
index 000000000..d1e13116d
--- /dev/null
+++ b/Modules/FindCurses.cmake
@@ -0,0 +1,176 @@
+# - Find the curses include file and library
+#
+# 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
+#
+# Set CURSES_NEED_NCURSES to TRUE before the FIND_PACKAGE() command if NCurses
+# functionality is required.
+
+#=============================================================================
+# 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.)
+
+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)
+ SET(CURSES_USE_NCURSES TRUE)
+ENDIF(CURSES_NCURSES_LIBRARY AND NOT CURSES_CURSES_LIBRARY)
+# http://cygwin.com/ml/cygwin-announce/2010-01/msg00002.html
+# cygwin ncurses stopped providing curses.h symlinks see above
+# message. Cygwin is an ncurses package, so force ncurses on
+# cygwin if the curses.h is missing
+IF(CYGWIN)
+ IF(NOT EXISTS /usr/include/curses.h)
+ SET(CURSES_USE_NCURSES TRUE)
+ ENDIF()
+ENDIF()
+
+
+# Not sure the logic is correct here.
+# If NCurses is required, use the function wsyncup() to check if the library
+# has NCurses functionality (at least this is where it breaks on NetBSD).
+# If wsyncup is in curses, use this one.
+# If not, try to find ncurses and check if this has the symbol.
+# Once the ncurses library is found, search the ncurses.h header first, but
+# some web pages also say that even with ncurses there is not always a ncurses.h:
+# http://osdir.com/ml/gnome.apps.mc.devel/2002-06/msg00029.html
+# So at first try ncurses.h, if not found, try to find curses.h under the same
+# 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(CheckLibraryExists)
+ CHECK_LIBRARY_EXISTS("${CURSES_CURSES_LIBRARY}"
+ wsyncup "" CURSES_CURSES_HAS_WSYNCUP)
+
+ IF(CURSES_NCURSES_LIBRARY AND NOT CURSES_CURSES_HAS_WSYNCUP)
+ CHECK_LIBRARY_EXISTS("${CURSES_NCURSES_LIBRARY}"
+ wsyncup "" CURSES_NCURSES_HAS_WSYNCUP)
+ IF( CURSES_NCURSES_HAS_WSYNCUP)
+ SET(CURSES_USE_NCURSES TRUE)
+ ENDIF( CURSES_NCURSES_HAS_WSYNCUP)
+ ENDIF(CURSES_NCURSES_LIBRARY AND NOT CURSES_CURSES_HAS_WSYNCUP)
+
+ENDIF(CURSES_CURSES_LIBRARY AND CURSES_NEED_NCURSES)
+
+
+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)
+ 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")
+ELSE(NOT CURSES_USE_NCURSES)
+# we need to find ncurses
+ GET_FILENAME_COMPONENT(_cursesLibDir "${CURSES_NCURSES_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)
+ ENDIF(NOT CURSES_NCURSES_INCLUDE_PATH AND CURSES_HAVE_NCURSES_NCURSES_H)
+ IF(CURSES_NCURSES_INCLUDE_PATH AND CURSES_NCURSES_LIBRARY)
+ SET( FORCE_IT )
+ IF(CURSES_INCLUDE_PATH MATCHES NOTFOUND)
+ SET(FORCE_IT FORCE)
+ ENDIF(CURSES_INCLUDE_PATH MATCHES NOTFOUND)
+ 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(CURSES_LIBRARY MATCHES NOTFOUND)
+ SET(CURSES_LIBRARY "${CURSES_NCURSES_LIBRARY}"
+ CACHE FILEPATH "The curses library" ${FORCE_IT})
+ ENDIF(CURSES_NCURSES_INCLUDE_PATH AND CURSES_NCURSES_LIBRARY)
+
+ENDIF(NOT CURSES_USE_NCURSES)
+
+FIND_LIBRARY(CURSES_EXTRA_LIBRARY cur_colr HINTS "${_cursesLibDir}")
+FIND_LIBRARY(CURSES_EXTRA_LIBRARY cur_colr )
+
+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")
+
+# Need to provide the *_LIBRARIES
+SET(CURSES_LIBRARIES ${CURSES_LIBRARY})
+
+IF(CURSES_EXTRA_LIBRARY)
+ SET(CURSES_LIBRARIES ${CURSES_LIBRARIES} ${CURSES_EXTRA_LIBRARY})
+ENDIF(CURSES_EXTRA_LIBRARY)
+
+IF(CURSES_FORM_LIBRARY)
+ SET(CURSES_LIBRARIES ${CURSES_LIBRARIES} ${CURSES_FORM_LIBRARY})
+ENDIF(CURSES_FORM_LIBRARY)
+
+# Proper name is *_INCLUDE_DIR
+SET(CURSES_INCLUDE_DIR ${CURSES_INCLUDE_PATH})
+
+# handle the QUIETLY and REQUIRED arguments and set CURSES_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Curses DEFAULT_MSG
+ CURSES_LIBRARY CURSES_INCLUDE_PATH)
+
+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
new file mode 100644
index 000000000..a4d150493
--- /dev/null
+++ b/Modules/FindCxxTest.cmake
@@ -0,0 +1,200 @@
+# - 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.
+#
+# 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
+#
+# 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 );
+# }
+# };
+#
+
+#=============================================================================
+# Copyright 2008-2010 Kitware, Inc.
+# Copyright 2008-2010 Philip Lowman <philip@yhbt.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.)
+
+# Version 1.4 (11/18/10) (CMake 2.8.4)
+# Issue 11384: Added support to the CXX_ADD_TEST macro so header
+# files (containing the tests themselves) show up in
+# Visual Studio and other IDEs.
+#
+# Version 1.3 (8/19/10) (CMake 2.8.3)
+# Included patch by Simone Rossetto to check if either Python or Perl
+# are present in the system. Whichever intepreter that is detected
+# is now used to run the test generator program. If both interpreters
+# are detected, the CXXTEST_USE_PYTHON variable is obeyed.
+#
+# Also added support for CXXTEST_TESTGEN_ARGS, for manually specifying
+# options to the CxxTest code generator.
+# Version 1.2 (3/2/08)
+# Included patch from Tyler Roscoe to have the perl & python binaries
+# detected based on CXXTEST_INCLUDE_DIR
+# Version 1.1 (2/9/08)
+# Clarified example to illustrate need to call target_link_libraries()
+# Changed commands to lowercase
+# Added licensing info
+# Version 1.0 (1/8/08)
+# Fixed CXXTEST_INCLUDE_DIRS so it will work properly
+# Eliminated superfluous CXXTEST_FOUND assignment
+# Cleaned up and added more documentation
+
+#=============================================================
+# CXXTEST_ADD_TEST (public macro)
+#=============================================================
+macro(CXXTEST_ADD_TEST _cxxtest_testname _cxxtest_outfname)
+ set(_cxxtest_real_outfname ${CMAKE_CURRENT_BINARY_DIR}/${_cxxtest_outfname})
+
+ add_custom_command(
+ OUTPUT ${_cxxtest_real_outfname}
+ DEPENDS ${ARGN}
+ COMMAND ${CXXTEST_TESTGEN_INTERPRETER}
+ ${CXXTEST_TESTGEN_EXECUTABLE} ${CXXTEST_TESTGEN_ARGS} -o ${_cxxtest_real_outfname} ${ARGN}
+ )
+
+ set_source_files_properties(${_cxxtest_real_outfname} PROPERTIES GENERATED true)
+ add_executable(${_cxxtest_testname} ${_cxxtest_real_outfname} ${ARGN})
+
+ if(CMAKE_RUNTIME_OUTPUT_DIRECTORY)
+ add_test(${_cxxtest_testname} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${_cxxtest_testname})
+ elseif(EXECUTABLE_OUTPUT_PATH)
+ add_test(${_cxxtest_testname} ${EXECUTABLE_OUTPUT_PATH}/${_cxxtest_testname})
+ else()
+ add_test(${_cxxtest_testname} ${CMAKE_CURRENT_BINARY_DIR}/${_cxxtest_testname})
+ endif()
+
+endmacro(CXXTEST_ADD_TEST)
+
+#=============================================================
+# main()
+#=============================================================
+if(NOT DEFINED CXXTEST_TESTGEN_ARGS)
+ set(CXXTEST_TESTGEN_ARGS --error-printer)
+endif()
+
+find_package(PythonInterp QUIET)
+find_package(Perl QUIET)
+
+find_path(CXXTEST_INCLUDE_DIR cxxtest/TestSuite.h)
+find_program(CXXTEST_PYTHON_TESTGEN_EXECUTABLE
+ NAMES cxxtestgen cxxtestgen.py
+ PATHS ${CXXTEST_INCLUDE_DIR})
+find_program(CXXTEST_PERL_TESTGEN_EXECUTABLE cxxtestgen.pl
+ PATHS ${CXXTEST_INCLUDE_DIR})
+
+if(PYTHONINTERP_FOUND OR PERL_FOUND)
+ include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+
+ if(PYTHONINTERP_FOUND AND (CXXTEST_USE_PYTHON OR NOT PERL_FOUND OR NOT DEFINED CXXTEST_USE_PYTHON))
+ set(CXXTEST_TESTGEN_EXECUTABLE ${CXXTEST_PYTHON_TESTGEN_EXECUTABLE})
+ set(CXXTEST_TESTGEN_INTERPRETER ${PYTHON_EXECUTABLE})
+ FIND_PACKAGE_HANDLE_STANDARD_ARGS(CxxTest DEFAULT_MSG
+ CXXTEST_INCLUDE_DIR CXXTEST_PYTHON_TESTGEN_EXECUTABLE)
+
+ elseif(PERL_FOUND)
+ set(CXXTEST_TESTGEN_EXECUTABLE ${CXXTEST_PERL_TESTGEN_EXECUTABLE})
+ set(CXXTEST_TESTGEN_INTERPRETER ${PERL_EXECUTABLE})
+ FIND_PACKAGE_HANDLE_STANDARD_ARGS(CxxTest DEFAULT_MSG
+ CXXTEST_INCLUDE_DIR CXXTEST_PERL_TESTGEN_EXECUTABLE)
+ endif()
+
+ if(CXXTEST_FOUND)
+ set(CXXTEST_INCLUDE_DIRS ${CXXTEST_INCLUDE_DIR})
+ endif()
+
+else()
+
+ set(CXXTEST_FOUND false)
+ if(NOT CxxTest_FIND_QUIETLY)
+ if(CxxTest_FIND_REQUIRED)
+ message(FATAL_ERROR "Neither Python nor Perl found, cannot use CxxTest, aborting!")
+ else()
+ message(STATUS "Neither Python nor Perl found, CxxTest will not be used.")
+ endif()
+ endif()
+
+endif()
diff --git a/Modules/FindCygwin.cmake b/Modules/FindCygwin.cmake
new file mode 100644
index 000000000..28f55ba0c
--- /dev/null
+++ b/Modules/FindCygwin.cmake
@@ -0,0 +1,28 @@
+# - this module looks for Cygwin
+#
+
+#=============================================================================
+# 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.)
+
+IF (WIN32)
+ FIND_PATH(CYGWIN_INSTALL_PATH
+ cygwin.bat
+ "C:/Cygwin"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Cygwin\\setup;rootdir]"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Cygnus Solutions\\Cygwin\\mounts v2\\/;native]"
+ )
+
+ MARK_AS_ADVANCED(
+ CYGWIN_INSTALL_PATH
+ )
+ENDIF (WIN32)
diff --git a/Modules/FindDCMTK.cmake b/Modules/FindDCMTK.cmake
new file mode 100644
index 000000000..361d09e8b
--- /dev/null
+++ b/Modules/FindDCMTK.cmake
@@ -0,0 +1,154 @@
+# - find DCMTK libraries and applications
+#
+
+# 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/)
+
+#=============================================================================
+# Copyright 2004-2009 Kitware, Inc.
+# Copyright 2009-2010 Mathieu Malaterre <mathieu.malaterre@gmail.com>
+# Copyright 2010 Thomas Sondergaard <ts@medical-insight.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.)
+
+#
+# Written for VXL by Amitha Perera.
+# Upgraded for GDCM by Mathieu Malaterre.
+# 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)
+endif()
+
+
+foreach(lib
+ dcmdata
+ dcmimage
+ dcmimgle
+ dcmjpeg
+ dcmnet
+ dcmpstat
+ dcmqrdb
+ dcmsign
+ dcmsr
+ dcmtls
+ ijg12
+ ijg16
+ ijg8
+ ofstd)
+
+ find_library(DCMTK_${lib}_LIBRARY
+ ${lib}
+ PATHS
+ ${DCMTK_DIR}/${lib}/libsrc
+ ${DCMTK_DIR}/${lib}/libsrc/Release
+ ${DCMTK_DIR}/${lib}/libsrc/Debug
+ ${DCMTK_DIR}/${lib}/Release
+ ${DCMTK_DIR}/${lib}/Debug
+ ${DCMTK_DIR}/lib)
+
+ mark_as_advanced(DCMTK_${lib}_LIBRARY)
+
+ if(DCMTK_${lib}_LIBRARY)
+ list(APPEND DCMTK_LIBRARIES ${DCMTK_${lib}_LIBRARY})
+ endif()
+
+endforeach()
+
+
+set(DCMTK_config_TEST_HEADER osconfig.h)
+set(DCMTK_dcmdata_TEST_HEADER dctypes.h)
+set(DCMTK_dcmimage_TEST_HEADER dicoimg.h)
+set(DCMTK_dcmimgle_TEST_HEADER dcmimage.h)
+set(DCMTK_dcmjpeg_TEST_HEADER djdecode.h)
+set(DCMTK_dcmnet_TEST_HEADER assoc.h)
+set(DCMTK_dcmpstat_TEST_HEADER dcmpstat.h)
+set(DCMTK_dcmqrdb_TEST_HEADER dcmqrdba.h)
+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)
+
+foreach(dir
+ config
+ dcmdata
+ dcmimage
+ dcmimgle
+ dcmjpeg
+ dcmnet
+ dcmpstat
+ dcmqrdb
+ dcmsign
+ dcmsr
+ dcmtls
+ ofstd)
+ 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}
+ )
+ mark_as_advanced(DCMTK_${dir}_INCLUDE_DIR)
+
+ if(DCMTK_${dir}_INCLUDE_DIR)
+ list(APPEND
+ DCMTK_INCLUDE_DIRS
+ ${DCMTK_${dir}_INCLUDE_DIR})
+ endif()
+endforeach()
+
+if(WIN32)
+ list(APPEND DCMTK_LIBRARIES netapi32 wsock32)
+endif()
+
+if(DCMTK_ofstd_INCLUDE_DIR)
+ get_filename_component(DCMTK_dcmtk_INCLUDE_DIR
+ ${DCMTK_ofstd_INCLUDE_DIR}
+ PATH
+ CACHE)
+ list(APPEND DCMTK_INCLUDE_DIRS ${DCMTK_dcmtk_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()
diff --git a/Modules/FindDart.cmake b/Modules/FindDart.cmake
new file mode 100644
index 000000000..f7c54df43
--- /dev/null
+++ b/Modules/FindDart.cmake
@@ -0,0 +1,36 @@
+# - 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.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software 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(DART_ROOT README.INSTALL
+ $ENV{DART_ROOT}
+ ${PROJECT_SOURCE_DIR}/Dart
+ /usr/share/Dart
+ C:/Dart
+ "$ENV{ProgramFiles}/Dart"
+ "C:/Program Files/Dart"
+ ${PROJECT_SOURCE_DIR}/../Dart
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\Dart\\InstallPath]
+ DOC "If you have Dart installed, where is it located?"
+ )
+
+# handle the QUIETLY and REQUIRED arguments and set DART_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Dart DEFAULT_MSG DART_ROOT)
+
+MARK_AS_ADVANCED(DART_ROOT)
diff --git a/Modules/FindDevIL.cmake b/Modules/FindDevIL.cmake
new file mode 100644
index 000000000..4a0fbe064
--- /dev/null
+++ b/Modules/FindDevIL.cmake
@@ -0,0 +1,74 @@
+# 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.
+
+#=============================================================================
+# Copyright 2008-2009 Kitware, Inc.
+# Copyright 2008 Christopher Harvey
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software 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.)
+
+# TODO: Add version support.
+# Tested under Linux and Windows (MSVC)
+
+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"
+)
+
+#MESSAGE("IL_INCLUDE_DIR is ${IL_INCLUDE_DIR}")
+
+FIND_LIBRARY(IL_LIBRARIES
+ NAMES IL DEVIL
+ PATH_SUFFIXES lib64 lib lib32
+ DOC "The file that corresponds to the base il library."
+)
+
+#MESSAGE("IL_LIBRARIES is ${IL_LIBRARIES}")
+
+FIND_LIBRARY(ILUT_LIBRARIES
+ NAMES ILUT
+ PATH_SUFFIXES lib64 lib lib32
+ DOC "The file that corresponds to the il (system?) utility library."
+)
+
+#MESSAGE("ILUT_LIBRARIES is ${ILUT_LIBRARIES}")
+
+FIND_LIBRARY(ILU_LIBRARIES
+ NAMES ILU
+ PATH_SUFFIXES lib64 lib lib32
+ DOC "The file that corresponds to the il utility library."
+)
+
+#MESSAGE("ILU_LIBRARIES is ${ILU_LIBRARIES}")
+
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(IL DEFAULT_MSG
+ IL_LIBRARIES ILU_LIBRARIES
+ ILUT_LIBRARIES IL_INCLUDE_DIR)
diff --git a/Modules/FindDoxygen.cmake b/Modules/FindDoxygen.cmake
new file mode 100644
index 000000000..6cc9efb18
--- /dev/null
+++ b/Modules/FindDoxygen.cmake
@@ -0,0 +1,144 @@
+# - 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)
+#
+# 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
+#
+#
+
+#=============================================================================
+# 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.)
+
+# For backwards compatibility support
+IF(Doxygen_FIND_QUIETLY)
+ SET(DOXYGEN_FIND_QUIETLY TRUE)
+ENDIF(Doxygen_FIND_QUIETLY)
+
+# ===== Rationale for OS X AppBundle mods below =====
+# With the OS X GUI version, Doxygen likes to be installed to /Applications and
+# it contains the doxygen executable in the bundle. In the versions I've
+# seen, it is located in Resources, but in general, more often binaries are
+# located in MacOS.
+#
+# NOTE: The official Doxygen.app that is distributed for OS X uses non-standard
+# conventions. Instead of the command-line "doxygen" tool being placed in
+# Doxygen.app/Contents/MacOS, "Doxywizard" is placed there instead and
+# "doxygen" is placed in Contents/Resources. This is most likely done
+# so that something happens when people double-click on the Doxygen.app
+# package. Unfortunately, CMake gets confused by this as when it sees the
+# bundle it uses "Doxywizard" as the executable to use instead of
+# "doxygen". Therefore to work-around this issue we temporarily disable
+# the app-bundle feature, just for this CMake module:
+if(APPLE)
+ # Save the old setting
+ SET(TEMP_DOXYGEN_SAVE_CMAKE_FIND_APPBUNDLE ${CMAKE_FIND_APPBUNDLE})
+ # Disable the App-bundle detection feature
+ SET(CMAKE_FIND_APPBUNDLE "NEVER")
+endif()
+# FYI:
+# In the older versions of OS X Doxygen, dot was included with the
+# Doxygen bundle. But the new versions require you to download
+# Graphviz.app which contains "dot" in it's bundle.
+# ============== End OSX stuff ================
+
+#
+# Find Doxygen...
+#
+
+FIND_PROGRAM(DOXYGEN_EXECUTABLE
+ NAMES doxygen
+ PATHS
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\doxygen_is1;Inno Setup: App Path]/bin"
+ /Applications/Doxygen.app/Contents/Resources
+ /Applications/Doxygen.app/Contents/MacOS
+ DOC "Doxygen documentation generation tool (http://www.doxygen.org)"
+)
+
+IF(DOXYGEN_EXECUTABLE)
+ EXECUTE_PROCESS(COMMAND ${DOXYGEN_EXECUTABLE} "--version" OUTPUT_VARIABLE DOXYGEN_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE)
+ENDIF()
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Doxygen REQUIRED_VARS DOXYGEN_EXECUTABLE VERSION_VAR DOXYGEN_VERSION)
+
+#
+# Find Dot...
+#
+
+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"
+ "$ENV{ProgramFiles}/ATT/Graphviz/bin"
+ "C:/Program Files/ATT/Graphviz/bin"
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\ATT\\Graphviz;InstallPath]/bin
+ /Applications/Graphviz.app/Contents/MacOS
+ /Applications/Doxygen.app/Contents/Resources
+ /Applications/Doxygen.app/Contents/MacOS
+ DOC "Graphviz Dot tool for using Doxygen"
+ )
+
+ 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)
+ endif()
+
+endif(NOT DOXYGEN_SKIP_DOT)
+
+#
+# Backwards compatibility...
+#
+
+if(APPLE)
+ # Restore the old app-bundle setting setting
+ SET(CMAKE_FIND_APPBUNDLE ${TEMP_DOXYGEN_SAVE_CMAKE_FIND_APPBUNDLE})
+endif()
+
+# Maintain the _FOUND variables as "YES" or "NO" for backwards compatibility
+# (allows people to stuff them directly into Doxyfile with configure_file())
+if(DOXYGEN_FOUND)
+ set(DOXYGEN_FOUND "YES")
+else()
+ set(DOXYGEN_FOUND "NO")
+endif()
+if(DOXYGEN_DOT_FOUND)
+ set(DOXYGEN_DOT_FOUND "YES")
+else()
+ set(DOXYGEN_DOT_FOUND "NO")
+endif()
+
+# For backwards compatibility support
+SET (DOXYGEN ${DOXYGEN_EXECUTABLE} )
+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
new file mode 100644
index 000000000..1bf074357
--- /dev/null
+++ b/Modules/FindEXPAT.cmake
@@ -0,0 +1,60 @@
+# - 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.
+
+#=============================================================================
+# Copyright 2006-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 the header file.
+FIND_PATH(EXPAT_INCLUDE_DIR NAMES expat.h)
+
+# Look for the library.
+FIND_LIBRARY(EXPAT_LIBRARY NAMES expat libexpat)
+
+if (EXPAT_INCLUDE_DIR AND EXISTS "${EXPAT_INCLUDE_DIR}/expat.h")
+ file(STRINGS "${EXPAT_INCLUDE_DIR}/expat.h" expat_version_str
+ REGEX "^#[\t ]*define[\t ]+XML_(MAJOR|MINOR|MICRO)_VERSION[\t ]+[0-9]+$")
+
+ 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(EXPAT_VERSION_STRING)
+ set(EXPAT_VERSION_STRING "${EXPAT_VERSION_STRING}.${EXPAT_VERSION_PART}")
+ else(EXPAT_VERSION_STRING)
+ set(EXPAT_VERSION_STRING "${EXPAT_VERSION_PART}")
+ endif(EXPAT_VERSION_STRING)
+ endif()
+ endforeach(VLINE)
+ endforeach(VPART)
+endif (EXPAT_INCLUDE_DIR AND EXISTS "${EXPAT_INCLUDE_DIR}/expat.h")
+
+# handle the QUIETLY and REQUIRED arguments and set EXPAT_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(EXPAT
+ REQUIRED_VARS EXPAT_LIBRARY EXPAT_INCLUDE_DIR
+ VERSION_VAR EXPAT_VERSION_STRING)
+
+# Copy the results to the output variables.
+IF(EXPAT_FOUND)
+ SET(EXPAT_LIBRARIES ${EXPAT_LIBRARY})
+ SET(EXPAT_INCLUDE_DIRS ${EXPAT_INCLUDE_DIR})
+ENDIF(EXPAT_FOUND)
+
+MARK_AS_ADVANCED(EXPAT_INCLUDE_DIR EXPAT_LIBRARY)
diff --git a/Modules/FindFLEX.cmake b/Modules/FindFLEX.cmake
new file mode 100644
index 000000000..586f77a6e
--- /dev/null
+++ b/Modules/FindFLEX.cmake
@@ -0,0 +1,161 @@
+# - 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
+#
+# The minimum required version of flex can be specified using the
+# 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
+# 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
+# respectively FLEX_TARGET and BISON_TARGET macros.
+#
+# ====================================================================
+# Example:
+#
+# 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)
+#
+# include_directories(${CMAKE_CURRENT_BINARY_DIR})
+# add_executable(Foo
+# Foo.cc
+# ${BISON_MyParser_OUTPUTS}
+# ${FLEX_MyScanner_OUTPUTS}
+# )
+# ====================================================================
+
+#=============================================================================
+# Copyright 2009 Kitware, Inc.
+# Copyright 2006 Tristan Carel
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software 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(FLEX_EXECUTABLE flex DOC "path to the flex executable")
+MARK_AS_ADVANCED(FLEX_EXECUTABLE)
+
+FIND_LIBRARY(FL_LIBRARY NAMES fl
+ DOC "Path to the fl library")
+
+FIND_PATH(FLEX_INCLUDE_DIR FlexLexer.h
+ DOC "Path to the flex headers")
+
+MARK_AS_ADVANCED(FL_LIBRARY FLEX_INCLUDE_DIR)
+
+SET(FLEX_INCLUDE_DIRS ${FLEX_INCLUDE_DIR})
+SET(FLEX_LIBRARIES ${FL_LIBRARY})
+
+IF(FLEX_EXECUTABLE)
+
+ EXECUTE_PROCESS(COMMAND ${FLEX_EXECUTABLE} --version
+ OUTPUT_VARIABLE FLEX_version_output
+ ERROR_VARIABLE FLEX_version_error
+ RESULT_VARIABLE FLEX_version_result
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ IF(NOT ${FLEX_version_result} EQUAL 0)
+ IF(FLEX_FIND_REQUIRED)
+ MESSAGE(SEND_ERROR "Command \"${FLEX_EXECUTABLE} --version\" failed with output:\n${FLEX_version_output}\n${FLEX_version_error}")
+ ELSE()
+ MESSAGE("Command \"${FLEX_EXECUTABLE} --version\" failed with output:\n${FLEX_version_output}\n${FLEX_version_error}\nFLEX_VERSION will not be available")
+ ENDIF()
+ ELSE()
+ # older versions of flex printed "/full/path/to/executable version X.Y"
+ # newer versions use "basename(executable) X.Y"
+ GET_FILENAME_COMPONENT(FLEX_EXE_NAME "${FLEX_EXECUTABLE}" NAME)
+ STRING(REGEX REPLACE "^.*${FLEX_EXE_NAME}\"? (version )?([0-9]+[^ ]*)$" "\\2"
+ FLEX_VERSION "${FLEX_version_output}")
+ UNSET(FLEX_EXE_NAME)
+ ENDIF()
+
+ #============================================================
+ # FLEX_TARGET (public macro)
+ #============================================================
+ #
+ 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()
+ ELSE()
+ MESSAGE(SEND_ERROR ${FLEX_TARGET_usage})
+ 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(FLEX_TARGET)
+ #============================================================
+
+
+ #============================================================
+ # ADD_FLEX_BISON_DEPENDENCY (public macro)
+ #============================================================
+ #
+ MACRO(ADD_FLEX_BISON_DEPENDENCY FlexTarget BisonTarget)
+
+ IF(NOT FLEX_${FlexTarget}_OUTPUTS)
+ MESSAGE(SEND_ERROR "Flex target `${FlexTarget}' does not exists.")
+ ENDIF()
+
+ IF(NOT BISON_${BisonTarget}_OUTPUT_HEADER)
+ MESSAGE(SEND_ERROR "Bison target `${BisonTarget}' does not exists.")
+ ENDIF()
+
+ SET_SOURCE_FILES_PROPERTIES(${FLEX_${FlexTarget}_OUTPUTS}
+ PROPERTIES OBJECT_DEPENDS ${BISON_${BisonTarget}_OUTPUT_HEADER})
+ ENDMACRO(ADD_FLEX_BISON_DEPENDENCY)
+ #============================================================
+
+ENDIF(FLEX_EXECUTABLE)
+
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(FLEX REQUIRED_VARS FLEX_EXECUTABLE
+ VERSION_VAR FLEX_VERSION)
+
+# FindFLEX.cmake ends here
diff --git a/Modules/FindFLTK.cmake b/Modules/FindFLTK.cmake
new file mode 100644
index 000000000..bdea95bdc
--- /dev/null
+++ b/Modules/FindFLTK.cmake
@@ -0,0 +1,309 @@
+# - Find the native FLTK includes and library
+#
+# 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
+#
+# 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
+
+#=============================================================================
+# 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.)
+
+IF(NOT FLTK_SKIP_OPENGL)
+ FIND_PACKAGE(OpenGL)
+ENDIF()
+
+# Platform dependent libraries required by FLTK
+IF(WIN32)
+ IF(NOT CYGWIN)
+ IF(BORLAND)
+ SET( FLTK_PLATFORM_DEPENDENT_LIBS import32 )
+ ELSE(BORLAND)
+ SET( FLTK_PLATFORM_DEPENDENT_LIBS wsock32 comctl32 )
+ ENDIF(BORLAND)
+ ENDIF(NOT CYGWIN)
+ENDIF(WIN32)
+
+IF(UNIX)
+ INCLUDE(FindX11)
+ FIND_LIBRARY(FLTK_MATH_LIBRARY m)
+ SET( FLTK_PLATFORM_DEPENDENT_LIBS ${X11_LIBRARIES} ${FLTK_MATH_LIBRARY})
+ENDIF(UNIX)
+
+IF(APPLE)
+ SET( FLTK_PLATFORM_DEPENDENT_LIBS "-framework Carbon -framework Cocoa -framework ApplicationServices -lz")
+ENDIF(APPLE)
+
+# If FLTK_INCLUDE_DIR is already defined we assigne its value to FLTK_DIR
+IF(FLTK_INCLUDE_DIR)
+ SET(FLTK_DIR ${FLTK_INCLUDE_DIR})
+ENDIF(FLTK_INCLUDE_DIR)
+
+
+# If FLTK has been built using CMake we try to find everything directly
+SET(FLTK_DIR_STRING "directory containing FLTKConfig.cmake. This is either the root of the build tree, or PREFIX/lib/fltk for an installation.")
+
+# Search only if the location is not already known.
+IF(NOT FLTK_DIR)
+ # Get the system search path as a list.
+ FILE(TO_CMAKE_PATH "$ENV{PATH}" FLTK_DIR_SEARCH2)
+
+ # Construct a set of paths relative to the system search path.
+ SET(FLTK_DIR_SEARCH "")
+ FOREACH(dir ${FLTK_DIR_SEARCH2})
+ SET(FLTK_DIR_SEARCH ${FLTK_DIR_SEARCH} "${dir}/../lib/fltk")
+ ENDFOREACH(dir)
+ STRING(REPLACE "//" "/" FLTK_DIR_SEARCH "${FLTK_DIR_SEARCH}")
+
+ #
+ # Look for an installation or build tree.
+ #
+ FIND_PATH(FLTK_DIR FLTKConfig.cmake
+ # Look for an environment variable FLTK_DIR.
+ $ENV{FLTK_DIR}
+
+ # Look in places relative to the system executable search path.
+ ${FLTK_DIR_SEARCH}
+
+ # Look in standard UNIX install locations.
+ /usr/local/lib/fltk
+ /usr/lib/fltk
+ /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}"
+ )
+ENDIF(NOT FLTK_DIR)
+
+ # Check if FLTK was built using CMake
+ IF(EXISTS ${FLTK_DIR}/FLTKConfig.cmake)
+ SET(FLTK_BUILT_WITH_CMAKE 1)
+ ENDIF(EXISTS ${FLTK_DIR}/FLTKConfig.cmake)
+
+ IF(FLTK_BUILT_WITH_CMAKE)
+ SET(FLTK_FOUND 1)
+ INCLUDE(${FLTK_DIR}/FLTKConfig.cmake)
+
+ # Fluid
+ IF(FLUID_COMMAND)
+ SET(FLTK_FLUID_EXECUTABLE ${FLUID_COMMAND} CACHE FILEPATH "Fluid executable")
+ ELSE(FLUID_COMMAND)
+ FIND_PROGRAM(FLTK_FLUID_EXECUTABLE fluid PATHS
+ ${FLTK_EXECUTABLE_DIRS}
+ ${FLTK_EXECUTABLE_DIRS}/RelWithDebInfo
+ ${FLTK_EXECUTABLE_DIRS}/Debug
+ ${FLTK_EXECUTABLE_DIRS}/Release
+ NO_SYSTEM_PATH)
+ ENDIF(FLUID_COMMAND)
+ # MARK_AS_ADVANCED(FLTK_FLUID_EXECUTABLE)
+
+ SET(FLTK_INCLUDE_DIR ${FLTK_DIR})
+ LINK_DIRECTORIES(${FLTK_LIBRARY_DIRS})
+
+ SET(FLTK_BASE_LIBRARY fltk)
+ SET(FLTK_GL_LIBRARY fltk_gl)
+ SET(FLTK_FORMS_LIBRARY fltk_forms)
+ SET(FLTK_IMAGES_LIBRARY fltk_images)
+
+ # Add the extra libraries
+ LOAD_CACHE(${FLTK_DIR}
+ READ_WITH_PREFIX
+ FL FLTK_USE_SYSTEM_JPEG
+ FL FLTK_USE_SYSTEM_PNG
+ FL FLTK_USE_SYSTEM_ZLIB
+ )
+
+ SET(FLTK_IMAGES_LIBS "")
+ IF(FLFLTK_USE_SYSTEM_JPEG)
+ SET(FLTK_IMAGES_LIBS ${FLTK_IMAGES_LIBS} fltk_jpeg)
+ ENDIF(FLFLTK_USE_SYSTEM_JPEG)
+ IF(FLFLTK_USE_SYSTEM_PNG)
+ SET(FLTK_IMAGES_LIBS ${FLTK_IMAGES_LIBS} fltk_png)
+ ENDIF(FLFLTK_USE_SYSTEM_PNG)
+ IF(FLFLTK_USE_SYSTEM_ZLIB)
+ SET(FLTK_IMAGES_LIBS ${FLTK_IMAGES_LIBS} fltk_zlib)
+ ENDIF(FLFLTK_USE_SYSTEM_ZLIB)
+ SET(FLTK_IMAGES_LIBS "${FLTK_IMAGES_LIBS}" CACHE INTERNAL
+ "Extra libraries for fltk_images library.")
+
+ ELSE(FLTK_BUILT_WITH_CMAKE)
+
+ # if FLTK was not built using CMake
+ # Find fluid executable.
+ FIND_PROGRAM(FLTK_FLUID_EXECUTABLE fluid ${FLTK_INCLUDE_DIR}/fluid)
+
+ # Use location of fluid to help find everything else.
+ SET(FLTK_INCLUDE_SEARCH_PATH "")
+ SET(FLTK_LIBRARY_SEARCH_PATH "")
+ IF(FLTK_FLUID_EXECUTABLE)
+ GET_FILENAME_COMPONENT(FLTK_BIN_DIR "${FLTK_FLUID_EXECUTABLE}" PATH)
+ SET(FLTK_INCLUDE_SEARCH_PATH ${FLTK_INCLUDE_SEARCH_PATH}
+ ${FLTK_BIN_DIR}/../include ${FLTK_BIN_DIR}/..)
+ SET(FLTK_LIBRARY_SEARCH_PATH ${FLTK_LIBRARY_SEARCH_PATH}
+ ${FLTK_BIN_DIR}/../lib)
+ SET(FLTK_WRAP_UI 1)
+ ENDIF(FLTK_FLUID_EXECUTABLE)
+
+ #
+ # Try to find FLTK include dir using fltk-config
+ #
+ IF(UNIX)
+ # Use fltk-config to generate a list of possible include directories
+ FIND_PROGRAM(FLTK_CONFIG_SCRIPT fltk-config PATHS ${FLTK_BIN_DIR})
+ IF(FLTK_CONFIG_SCRIPT)
+ IF(NOT FLTK_INCLUDE_DIR)
+ EXEC_PROGRAM(${FLTK_CONFIG_SCRIPT} ARGS --cxxflags OUTPUT_VARIABLE FLTK_CXXFLAGS)
+ IF(FLTK_CXXFLAGS)
+ STRING(REGEX MATCHALL "-I[^ ]*" _fltk_temp_dirs ${FLTK_CXXFLAGS})
+ STRING(REPLACE "-I" "" _fltk_temp_dirs "${_fltk_temp_dirs}")
+ FOREACH(_dir ${_fltk_temp_dirs})
+ STRING(STRIP ${_dir} _output)
+ LIST(APPEND _FLTK_POSSIBLE_INCLUDE_DIRS ${_output})
+ ENDFOREACH()
+ ENDIF(FLTK_CXXFLAGS)
+ ENDIF()
+ ENDIF()
+ ENDIF()
+
+ SET(FLTK_INCLUDE_SEARCH_PATH ${FLTK_INCLUDE_SEARCH_PATH}
+ /usr/local/fltk
+ /usr/X11R6/include
+ ${_FLTK_POSSIBLE_INCLUDE_DIRS}
+ )
+
+ FIND_PATH(FLTK_INCLUDE_DIR
+ NAMES FL/Fl.h FL/Fl.H # fltk 1.1.9 has Fl.H (#8376)
+ PATHS ${FLTK_INCLUDE_SEARCH_PATH})
+
+ #
+ # Try to find FLTK library
+ IF(UNIX)
+ IF(FLTK_CONFIG_SCRIPT)
+ EXEC_PROGRAM(${FLTK_CONFIG_SCRIPT} ARGS --libs OUTPUT_VARIABLE _FLTK_POSSIBLE_LIBS)
+ IF(_FLTK_POSSIBLE_LIBS)
+ GET_FILENAME_COMPONENT(_FLTK_POSSIBLE_LIBRARY_DIR ${_FLTK_POSSIBLE_LIBS} PATH)
+ ENDIF()
+ ENDIF()
+ ENDIF()
+
+ SET(FLTK_LIBRARY_SEARCH_PATH ${FLTK_LIBRARY_SEARCH_PATH}
+ /usr/local/fltk/lib
+ /usr/X11R6/lib
+ ${FLTK_INCLUDE_DIR}/lib
+ ${_FLTK_POSSIBLE_LIBRARY_DIR}
+ )
+
+ FIND_LIBRARY(FLTK_BASE_LIBRARY NAMES fltk fltkd
+ PATHS ${FLTK_LIBRARY_SEARCH_PATH})
+ FIND_LIBRARY(FLTK_GL_LIBRARY NAMES fltkgl fltkgld fltk_gl
+ PATHS ${FLTK_LIBRARY_SEARCH_PATH})
+ FIND_LIBRARY(FLTK_FORMS_LIBRARY NAMES fltkforms fltkformsd fltk_forms
+ PATHS ${FLTK_LIBRARY_SEARCH_PATH})
+ FIND_LIBRARY(FLTK_IMAGES_LIBRARY NAMES fltkimages fltkimagesd fltk_images
+ PATHS ${FLTK_LIBRARY_SEARCH_PATH})
+
+ # Find the extra libraries needed for the fltk_images library.
+ IF(UNIX)
+ IF(FLTK_CONFIG_SCRIPT)
+ EXEC_PROGRAM(${FLTK_CONFIG_SCRIPT} ARGS --use-images --ldflags
+ 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}")
+ # 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
+ "Extra libraries for fltk_images library.")
+ ENDIF("${FLTK_IMAGES_LDFLAGS}" MATCHES "${FLTK_LIBS_EXTRACT_REGEX}")
+ ENDIF(FLTK_CONFIG_SCRIPT)
+ ENDIF(UNIX)
+
+ ENDIF(FLTK_BUILT_WITH_CMAKE)
+
+ # Append all of the required libraries together (by default, everything)
+ SET(FLTK_LIBRARIES)
+ IF(NOT FLTK_SKIP_IMAGES)
+ LIST(APPEND FLTK_LIBRARIES ${FLTK_IMAGES_LIBRARY})
+ ENDIF()
+ IF(NOT FLTK_SKIP_FORMS)
+ LIST(APPEND FLTK_LIBRARIES ${FLTK_FORMS_LIBRARY})
+ ENDIF()
+ IF(NOT FLTK_SKIP_OPENGL)
+ LIST(APPEND FLTK_LIBRARIES ${FLTK_GL_LIBRARY} ${OPENGL_gl_LIBRARY})
+ LIST(APPEND FLTK_INCLUDE_DIR ${OPENGL_INCLUDE_DIR})
+ LIST(REMOVE_DUPLICATES FLTK_INCLUDE_DIR)
+ ENDIF()
+ LIST(APPEND FLTK_LIBRARIES ${FLTK_BASE_LIBRARY})
+
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+IF(FLTK_SKIP_FLUID)
+ FIND_PACKAGE_HANDLE_STANDARD_ARGS(FLTK DEFAULT_MSG FLTK_LIBRARIES FLTK_INCLUDE_DIR)
+ELSE()
+ FIND_PACKAGE_HANDLE_STANDARD_ARGS(FLTK DEFAULT_MSG FLTK_LIBRARIES FLTK_INCLUDE_DIR FLTK_FLUID_EXECUTABLE)
+ENDIF()
+
+IF(FLTK_FOUND)
+ IF(APPLE)
+ SET(FLTK_LIBRARIES ${FLTK_PLATFORM_DEPENDENT_LIBS} ${FLTK_LIBRARIES})
+ ELSE(APPLE)
+ SET(FLTK_LIBRARIES ${FLTK_LIBRARIES} ${FLTK_PLATFORM_DEPENDENT_LIBS})
+ ENDIF(APPLE)
+
+ # The following deprecated settings are for compatibility with CMake 1.4
+ SET (HAS_FLTK ${FLTK_FOUND})
+ SET (FLTK_INCLUDE_PATH ${FLTK_INCLUDE_DIR})
+ SET (FLTK_FLUID_EXE ${FLTK_FLUID_EXECUTABLE})
+ SET (FLTK_LIBRARY ${FLTK_LIBRARIES})
+ENDIF(FLTK_FOUND)
+
diff --git a/Modules/FindFLTK2.cmake b/Modules/FindFLTK2.cmake
new file mode 100644
index 000000000..916474579
--- /dev/null
+++ b/Modules/FindFLTK2.cmake
@@ -0,0 +1,267 @@
+# - 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.
+# 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
+
+#=============================================================================
+# 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.)
+
+SET (FLTK2_DIR $ENV{FLTK2_DIR} )
+
+# Platform dependent libraries required by FLTK2
+IF(WIN32)
+ IF(NOT CYGWIN)
+ IF(BORLAND)
+ SET( FLTK2_PLATFORM_DEPENDENT_LIBS import32 )
+ ELSE(BORLAND)
+ SET( FLTK2_PLATFORM_DEPENDENT_LIBS wsock32 comctl32 )
+ ENDIF(BORLAND)
+ ENDIF(NOT CYGWIN)
+ENDIF(WIN32)
+
+IF(UNIX)
+ INCLUDE(${CMAKE_ROOT}/Modules/FindX11.cmake)
+ SET( FLTK2_PLATFORM_DEPENDENT_LIBS ${X11_LIBRARIES} -lm)
+ENDIF(UNIX)
+
+IF(APPLE)
+ SET( FLTK2_PLATFORM_DEPENDENT_LIBS "-framework Carbon -framework Cocoa -framework ApplicationServices -lz")
+ENDIF(APPLE)
+
+# If FLTK2_INCLUDE_DIR is already defined we assigne its value to FLTK2_DIR
+IF(FLTK2_INCLUDE_DIR)
+ SET(FLTK2_DIR ${FLTK2_INCLUDE_DIR})
+ELSE(FLTK2_INCLUDE_DIR)
+ SET(FLTK2_INCLUDE_DIR ${FLTK2_DIR})
+ENDIF(FLTK2_INCLUDE_DIR)
+
+
+# If FLTK2 has been built using CMake we try to find everything directly
+SET(FLTK2_DIR_STRING "directory containing FLTK2Config.cmake. This is either the root of the build tree, or PREFIX/lib/fltk for an installation.")
+
+# Search only if the location is not already known.
+IF(NOT FLTK2_DIR)
+ # Get the system search path as a list.
+ FILE(TO_CMAKE_PATH "$ENV{PATH}" FLTK2_DIR_SEARCH2)
+
+ # Construct a set of paths relative to the system search path.
+ SET(FLTK2_DIR_SEARCH "")
+ FOREACH(dir ${FLTK2_DIR_SEARCH2})
+ SET(FLTK2_DIR_SEARCH ${FLTK2_DIR_SEARCH} "${dir}/../lib/fltk")
+ ENDFOREACH(dir)
+ STRING(REPLACE "//" "/" FLTK2_DIR_SEARCH "${FLTK2_DIR_SEARCH}")
+
+ #
+ # Look for an installation or build tree.
+ #
+ FIND_PATH(FLTK2_DIR FLTK2Config.cmake
+ # Look for an environment variable FLTK2_DIR.
+ $ENV{FLTK2_DIR}
+
+ # Look in places relative to the system executable search path.
+ ${FLTK2_DIR_SEARCH}
+
+ # Look in standard UNIX install locations.
+ /usr/local/lib/fltk2
+ /usr/lib/fltk2
+ /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}"
+ )
+
+ IF(NOT FLTK2_DIR)
+ FIND_PATH(FLTK2_DIR fltk/run.h ${FLTK2_INCLUDE_SEARCH_PATH})
+ ENDIF(NOT FLTK2_DIR)
+
+ENDIF(NOT FLTK2_DIR)
+
+
+# If FLTK2 was found, load the configuration file to get the rest of the
+# settings.
+IF(FLTK2_DIR)
+
+ # Check if FLTK2 was built using CMake
+ IF(EXISTS ${FLTK2_DIR}/FLTK2Config.cmake)
+ SET(FLTK2_BUILT_WITH_CMAKE 1)
+ ENDIF(EXISTS ${FLTK2_DIR}/FLTK2Config.cmake)
+
+ IF(FLTK2_BUILT_WITH_CMAKE)
+ SET(FLTK2_FOUND 1)
+ INCLUDE(${FLTK2_DIR}/FLTK2Config.cmake)
+
+ # Fluid
+ IF(FLUID_COMMAND)
+ SET(FLTK2_FLUID_EXECUTABLE ${FLUID_COMMAND} CACHE FILEPATH "Fluid executable")
+ ELSE(FLUID_COMMAND)
+ FIND_PROGRAM(FLTK2_FLUID_EXECUTABLE fluid2 PATHS
+ ${FLTK2_EXECUTABLE_DIRS}
+ ${FLTK2_EXECUTABLE_DIRS}/RelWithDebInfo
+ ${FLTK2_EXECUTABLE_DIRS}/Debug
+ ${FLTK2_EXECUTABLE_DIRS}/Release
+ NO_SYSTEM_PATH)
+ ENDIF(FLUID_COMMAND)
+
+ MARK_AS_ADVANCED(FLTK2_FLUID_EXECUTABLE)
+ SET( FLTK_FLUID_EXECUTABLE ${FLTK2_FLUID_EXECUTABLE} )
+
+
+
+
+ SET(FLTK2_INCLUDE_DIR ${FLTK2_DIR})
+ LINK_DIRECTORIES(${FLTK2_LIBRARY_DIRS})
+
+ SET(FLTK2_BASE_LIBRARY fltk2)
+ SET(FLTK2_GL_LIBRARY fltk2_gl)
+ SET(FLTK2_IMAGES_LIBRARY fltk2_images)
+
+ # Add the extra libraries
+ LOAD_CACHE(${FLTK2_DIR}
+ READ_WITH_PREFIX
+ FL FLTK2_USE_SYSTEM_JPEG
+ FL FLTK2_USE_SYSTEM_PNG
+ FL FLTK2_USE_SYSTEM_ZLIB
+ )
+
+ SET(FLTK2_IMAGES_LIBS "")
+ IF(FLFLTK2_USE_SYSTEM_JPEG)
+ SET(FLTK2_IMAGES_LIBS ${FLTK2_IMAGES_LIBS} fltk2_jpeg)
+ ENDIF(FLFLTK2_USE_SYSTEM_JPEG)
+ IF(FLFLTK2_USE_SYSTEM_PNG)
+ SET(FLTK2_IMAGES_LIBS ${FLTK2_IMAGES_LIBS} fltk2_png)
+ ENDIF(FLFLTK2_USE_SYSTEM_PNG)
+ IF(FLFLTK2_USE_SYSTEM_ZLIB)
+ SET(FLTK2_IMAGES_LIBS ${FLTK2_IMAGES_LIBS} fltk2_zlib)
+ ENDIF(FLFLTK2_USE_SYSTEM_ZLIB)
+ SET(FLTK2_IMAGES_LIBS "${FLTK2_IMAGES_LIBS}" CACHE INTERNAL
+ "Extra libraries for fltk2_images library.")
+
+ ELSE(FLTK2_BUILT_WITH_CMAKE)
+
+ # if FLTK2 was not built using CMake
+ # Find fluid executable.
+ FIND_PROGRAM(FLTK2_FLUID_EXECUTABLE fluid2 ${FLTK2_INCLUDE_DIR}/fluid)
+
+ # Use location of fluid to help find everything else.
+ SET(FLTK2_INCLUDE_SEARCH_PATH "")
+ SET(FLTK2_LIBRARY_SEARCH_PATH "")
+ IF(FLTK2_FLUID_EXECUTABLE)
+ SET( FLTK_FLUID_EXECUTABLE ${FLTK2_FLUID_EXECUTABLE} )
+ GET_FILENAME_COMPONENT(FLTK2_BIN_DIR "${FLTK2_FLUID_EXECUTABLE}" PATH)
+ SET(FLTK2_INCLUDE_SEARCH_PATH ${FLTK2_INCLUDE_SEARCH_PATH}
+ ${FLTK2_BIN_DIR}/../include ${FLTK2_BIN_DIR}/..)
+ SET(FLTK2_LIBRARY_SEARCH_PATH ${FLTK2_LIBRARY_SEARCH_PATH}
+ ${FLTK2_BIN_DIR}/../lib)
+ SET(FLTK2_WRAP_UI 1)
+ ENDIF(FLTK2_FLUID_EXECUTABLE)
+
+ SET(FLTK2_INCLUDE_SEARCH_PATH ${FLTK2_INCLUDE_SEARCH_PATH}
+ /usr/local/fltk2
+ /usr/X11R6/include
+ )
+
+ FIND_PATH(FLTK2_INCLUDE_DIR fltk/run.h ${FLTK2_INCLUDE_SEARCH_PATH})
+
+ SET(FLTK2_LIBRARY_SEARCH_PATH ${FLTK2_LIBRARY_SEARCH_PATH}
+ /usr/local/fltk2/lib
+ /usr/X11R6/lib
+ ${FLTK2_INCLUDE_DIR}/lib
+ )
+
+ FIND_LIBRARY(FLTK2_BASE_LIBRARY NAMES fltk2
+ PATHS ${FLTK2_LIBRARY_SEARCH_PATH})
+ FIND_LIBRARY(FLTK2_GL_LIBRARY NAMES fltk2_gl
+ PATHS ${FLTK2_LIBRARY_SEARCH_PATH})
+ FIND_LIBRARY(FLTK2_IMAGES_LIBRARY NAMES fltk2_images
+ PATHS ${FLTK2_LIBRARY_SEARCH_PATH})
+
+ # Find the extra libraries needed for the fltk_images library.
+ IF(UNIX)
+ FIND_PROGRAM(FLTK2_CONFIG_SCRIPT fltk2-config PATHS ${FLTK2_BIN_DIR})
+ IF(FLTK2_CONFIG_SCRIPT)
+ EXEC_PROGRAM(${FLTK2_CONFIG_SCRIPT} ARGS --use-images --ldflags
+ 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}")
+ # 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
+ "Extra libraries for fltk_images library.")
+ ENDIF("${FLTK2_IMAGES_LDFLAGS}" MATCHES "${FLTK2_LIBS_EXTRACT_REGEX}")
+ ENDIF(FLTK2_CONFIG_SCRIPT)
+ ENDIF(UNIX)
+
+ ENDIF(FLTK2_BUILT_WITH_CMAKE)
+ENDIF(FLTK2_DIR)
+
+
+SET(FLTK2_FOUND 1)
+FOREACH(var FLTK2_FLUID_EXECUTABLE FLTK2_INCLUDE_DIR
+ FLTK2_BASE_LIBRARY FLTK2_GL_LIBRARY
+ FLTK2_IMAGES_LIBRARY)
+ IF(NOT ${var})
+ MESSAGE( STATUS "${var} not found" )
+ SET(FLTK2_FOUND 0)
+ ENDIF(NOT ${var})
+ENDFOREACH(var)
+
+
+IF(FLTK2_FOUND)
+ SET(FLTK2_LIBRARIES ${FLTK2_IMAGES_LIBRARY} ${FLTK2_IMAGES_LIBS} ${FLTK2_BASE_LIBRARY} ${FLTK2_GL_LIBRARY} )
+ IF(APPLE)
+ SET(FLTK2_LIBRARIES ${FLTK2_PLATFORM_DEPENDENT_LIBS} ${FLTK2_LIBRARIES})
+ ELSE(APPLE)
+ SET(FLTK2_LIBRARIES ${FLTK2_LIBRARIES} ${FLTK2_PLATFORM_DEPENDENT_LIBS})
+ ENDIF(APPLE)
+
+ # The following deprecated settings are for compatibility with CMake 1.4
+ SET (HAS_FLTK2 ${FLTK2_FOUND})
+ SET (FLTK2_INCLUDE_PATH ${FLTK2_INCLUDE_DIR})
+ SET (FLTK2_FLUID_EXE ${FLTK2_FLUID_EXECUTABLE})
+ SET (FLTK2_LIBRARY ${FLTK2_LIBRARIES})
+ELSE(FLTK2_FOUND)
+ # make FIND_PACKAGE friendly
+ IF(NOT FLTK2_FIND_QUIETLY)
+ IF(FLTK2_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR
+ "FLTK2 required, please specify its location with FLTK2_DIR.")
+ ELSE(FLTK2_FIND_REQUIRED)
+ MESSAGE(STATUS "FLTK2 was not found.")
+ ENDIF(FLTK2_FIND_REQUIRED)
+ ENDIF(NOT FLTK2_FIND_QUIETLY)
+ENDIF(FLTK2_FOUND)
+
diff --git a/Modules/FindFreetype.cmake b/Modules/FindFreetype.cmake
new file mode 100644
index 000000000..e6f670256
--- /dev/null
+++ b/Modules/FindFreetype.cmake
@@ -0,0 +1,110 @@
+# - 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.
+
+#=============================================================================
+# 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.)
+
+# Created by Eric Wing.
+# Modifications by Alexander Neundorf.
+# This file has been renamed to "FindFreetype.cmake" instead of the correct
+# "FindFreeType.cmake" in order to be compatible with the one from KDE4, Alex.
+
+# Ugh, FreeType seems to use some #include trickery which
+# makes this harder than it should be. It looks like they
+# put ft2build.h in a common/easier-to-find location which
+# then contains a #include to a more specific header in a
+# more specific location (#include <freetype/config/ftheader.h>).
+# Then from there, they need to set a bunch of #define's
+# so you can do something like:
+# #include FT_FREETYPE_H
+# Unfortunately, using CMake's mechanisms like INCLUDE_DIRECTORIES()
+# 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
+ HINTS
+ $ENV{FREETYPE_DIR}
+ PATHS
+ /usr/local/X11R6/include
+ /usr/local/X11/include
+ /usr/freeware/include
+)
+
+FIND_PATH(FREETYPE_INCLUDE_DIR_freetype2 freetype/config/ftheader.h
+ HINTS
+ $ENV{FREETYPE_DIR}/include/freetype2
+ PATHS
+ /usr/local/X11R6/include
+ /usr/local/X11/include
+ /usr/freeware/include
+ PATH_SUFFIXES freetype2
+)
+
+FIND_LIBRARY(FREETYPE_LIBRARY
+ NAMES freetype libfreetype freetype219
+ HINTS
+ $ENV{FREETYPE_DIR}
+ PATH_SUFFIXES lib64 lib
+ PATHS
+ /usr/local/X11R6
+ /usr/local/X11
+ /usr/freeware
+)
+
+# 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}")
+ENDIF(FREETYPE_INCLUDE_DIR_ft2build AND FREETYPE_INCLUDE_DIR_freetype2)
+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]+$")
+
+ 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(FREETYPE_VERSION_STRING)
+ SET(FREETYPE_VERSION_STRING "${FREETYPE_VERSION_PART}")
+ ENDIF(FREETYPE_VERSION_STRING)
+ UNSET(FREETYPE_VERSION_PART)
+ ENDIF()
+ ENDFOREACH(VLINE)
+ ENDFOREACH(VPART)
+ENDIF(FREETYPE_INCLUDE_DIR_freetype2 AND EXISTS "${FREETYPE_INCLUDE_DIR_freetype2}/freetype/freetype.h")
+
+
+# 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)
diff --git a/Modules/FindGCCXML.cmake b/Modules/FindGCCXML.cmake
new file mode 100644
index 000000000..261a5d180
--- /dev/null
+++ b/Modules/FindGCCXML.cmake
@@ -0,0 +1,27 @@
+# - Find the GCC-XML front-end executable.
+#
+# This module will define the following variables:
+# GCCXML - the GCC-XML front-end executable.
+
+#=============================================================================
+# 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.)
+
+FIND_PROGRAM(GCCXML
+ NAMES gccxml
+ ../GCC_XML/gccxml
+ PATHS [HKEY_CURRENT_USER\\Software\\Kitware\\GCC_XML;loc]
+ "$ENV{ProgramFiles}/GCC_XML"
+ "C:/Program Files/GCC_XML"
+)
+
+MARK_AS_ADVANCED(GCCXML)
diff --git a/Modules/FindGDAL.cmake b/Modules/FindGDAL.cmake
new file mode 100644
index 000000000..c31bef5ca
--- /dev/null
+++ b/Modules/FindGDAL.cmake
@@ -0,0 +1,107 @@
+# Locate gdal
+#
+# This module accepts the following environment variables:
+#
+# 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
+
+#=============================================================================
+# 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.)
+
+#
+# $GDALDIR is an environment variable that would
+# correspond to the ./configure --prefix=$GDAL_DIR
+# used in building gdal.
+#
+# Created by Eric Wing. I'm not a gdal user, but OpenSceneGraph uses it
+# for osgTerrain so I whipped this module together for completeness.
+# I actually don't know the conventions or where files are typically
+# placed in distros.
+# Any real gdal users are encouraged to correct this (but please don't
+# break the OS X framework stuff when doing so which is what usually seems
+# to happen).
+
+# This makes the presumption that you are include gdal.h like
+#
+#include "gdal.h"
+
+FIND_PATH(GDAL_INCLUDE_DIR gdal.h
+ HINTS
+ $ENV{GDAL_DIR}
+ $ENV{GDAL_ROOT}
+ PATH_SUFFIXES
+ include/gdal
+ include/GDAL
+ include
+ PATHS
+ ~/Library/Frameworks/gdal.framework/Headers
+ /Library/Frameworks/gdal.framework/Headers
+ /sw # Fink
+ /opt/local # DarwinPorts
+ /opt/csw # Blastwave
+ /opt
+)
+
+IF(UNIX)
+ # Use gdal-config to obtain the library version (this should hopefully
+ # allow us to -lgdal1.x.y where x.y are correct version)
+ # For some reason, libgdal development packages do not contain
+ # libgdal.so...
+ FIND_PROGRAM(GDAL_CONFIG gdal-config
+ HINTS
+ $ENV{GDAL_DIR}
+ $ENV{GDAL_ROOT}
+ PATH_SUFFIXES bin
+ PATHS
+ /sw # Fink
+ /opt/local # DarwinPorts
+ /opt/csw # Blastwave
+ /opt
+ )
+
+ if(GDAL_CONFIG)
+ 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(REGEX MATCHALL "-L[^ ]+" _gdal_dashL ${GDAL_CONFIG_LIBS})
+ string(REGEX REPLACE "-L" "" _gdal_libpath "${_gdal_dashL}")
+ endif()
+ endif()
+endif()
+
+FIND_LIBRARY(GDAL_LIBRARY
+ NAMES ${_gdal_lib} gdal gdal_i gdal1.5.0 gdal1.4.0 gdal1.3.2 GDAL
+ HINTS
+ $ENV{GDAL_DIR}
+ $ENV{GDAL_ROOT}
+ ${_gdal_libpath}
+ PATH_SUFFIXES lib64 lib
+ PATHS
+ /sw
+ /opt/local
+ /opt/csw
+ /opt
+ /usr/freeware
+)
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(GDAL DEFAULT_MSG GDAL_LIBRARY GDAL_INCLUDE_DIR)
+
+set(GDAL_LIBRARIES ${GDAL_LIBRARY})
+set(GDAL_INCLUDE_DIRS ${GDAL_INCLUDE_DIR})
diff --git a/Modules/FindGIF.cmake b/Modules/FindGIF.cmake
new file mode 100644
index 000000000..41e909805
--- /dev/null
+++ b/Modules/FindGIF.cmake
@@ -0,0 +1,80 @@
+# 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)
+#
+# $GIF_DIR is an environment variable that would
+# correspond to the ./configure --prefix=$GIF_DIR
+
+#=============================================================================
+# 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.)
+
+# Created by Eric Wing.
+# Modifications by Alexander Neundorf
+
+FIND_PATH(GIF_INCLUDE_DIR gif_lib.h
+ HINTS
+ $ENV{GIF_DIR}
+ PATH_SUFFIXES include
+ PATHS
+ ~/Library/Frameworks
+ /usr/freeware
+)
+
+# the gif library can have many names :-/
+SET(POTENTIAL_GIF_LIBS gif libgif ungif libungif giflib giflib4)
+
+FIND_LIBRARY(GIF_LIBRARY
+ NAMES ${POTENTIAL_GIF_LIBS}
+ HINTS
+ $ENV{GIF_DIR}
+ PATH_SUFFIXES lib64 lib
+ PATHS
+ ~/Library/Frameworks
+ /usr/freeware
+)
+
+# see readme.txt
+SET(GIF_LIBRARIES ${GIF_LIBRARY})
+
+# Very basic version detection.
+# The GIF_LIB_VERSION string in gif_lib.h seems to be unreliable, since it seems
+# to be always " Version 2.0, " in versions 3.x of giflib.
+# In version 4 the member UserData was added to GifFileType, so we check for this
+# one.
+# http://giflib.sourcearchive.com/documentation/4.1.4/files.html
+IF(GIF_INCLUDE_DIR)
+ INCLUDE(CMakePushCheckState)
+ INCLUDE(CheckStructHasMember)
+ CMAKE_PUSH_CHECK_STATE()
+ SET(GIF_VERSION 3)
+ SET(CMAKE_REQUIRED_INCLUDES "${GIF_INCLUDE_DIR}")
+ CHECK_STRUCT_HAS_MEMBER(GifFileType UserData gif_lib.h GIF_GifFileType_UserData )
+ IF(GIF_GifFileType_UserData)
+ SET(GIF_VERSION 4)
+ ENDIF()
+ CMAKE_POP_CHECK_STATE()
+ENDIF()
+
+
+# handle the QUIETLY and REQUIRED arguments and set GIF_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(GIF REQUIRED_VARS GIF_LIBRARY GIF_INCLUDE_DIR
+ VERSION_VAR GIF_VERSION )
+
+MARK_AS_ADVANCED(GIF_INCLUDE_DIR GIF_LIBRARY)
diff --git a/Modules/FindGLU.cmake b/Modules/FindGLU.cmake
new file mode 100644
index 000000000..5198f11e1
--- /dev/null
+++ b/Modules/FindGLU.cmake
@@ -0,0 +1,28 @@
+
+#=============================================================================
+# 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.)
+
+# Use of this file is deprecated, and is here for backwards compatibility with CMake 1.4
+# GLU library is now found by FindOpenGL.cmake
+#
+
+MESSAGE(STATUS
+ "WARNING: you are using the obsolete 'GLU' package, please use 'OpenGL' instead")
+
+INCLUDE(FindOpenGL)
+
+IF (OPENGL_GLU_FOUND)
+ SET (GLU_LIBRARY ${OPENGL_LIBRARIES})
+ SET (GLU_INCLUDE_PATH ${OPENGL_INCLUDE_DIR})
+ENDIF (OPENGL_GLU_FOUND)
+
diff --git a/Modules/FindGLUT.cmake b/Modules/FindGLUT.cmake
new file mode 100644
index 000000000..82057792d
--- /dev/null
+++ b/Modules/FindGLUT.cmake
@@ -0,0 +1,90 @@
+# - 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.
+# 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.
+
+#=============================================================================
+# 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.)
+
+IF (WIN32)
+ FIND_PATH( GLUT_INCLUDE_DIR NAMES GL/glut.h
+ PATHS ${GLUT_ROOT_PATH}/include )
+ FIND_LIBRARY( GLUT_glut_LIBRARY NAMES glut glut32 freeglut
+ PATHS
+ ${OPENGL_LIBRARY_DIR}
+ ${GLUT_ROOT_PATH}/Release
+ )
+ELSE (WIN32)
+
+ 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")
+ ELSE (APPLE)
+
+ FIND_PATH( GLUT_INCLUDE_DIR GL/glut.h
+ /usr/include/GL
+ /usr/openwin/share/include
+ /usr/openwin/include
+ /opt/graphics/OpenGL/include
+ /opt/graphics/OpenGL/contrib/libglut
+ )
+
+ FIND_LIBRARY( GLUT_glut_LIBRARY glut
+ /usr/openwin/lib
+ )
+
+ FIND_LIBRARY( GLUT_Xi_LIBRARY Xi
+ /usr/openwin/lib
+ )
+
+ FIND_LIBRARY( GLUT_Xmu_LIBRARY Xmu
+ /usr/openwin/lib
+ )
+
+ ENDIF (APPLE)
+
+ENDIF (WIN32)
+
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(GLUT REQUIRED_VARS GLUT_glut_LIBRARY GLUT_INCLUDE_DIR)
+
+IF (GLUT_FOUND)
+ # Is -lXi and -lXmu required on all platforms that have it?
+ # If not, we need some way to figure out what platform we are on.
+ SET( GLUT_LIBRARIES
+ ${GLUT_glut_LIBRARY}
+ ${GLUT_Xmu_LIBRARY}
+ ${GLUT_Xi_LIBRARY}
+ ${GLUT_cocoa_LIBRARY}
+ )
+
+ #The following deprecated settings are for backwards compatibility with CMake1.4
+ SET (GLUT_LIBRARY ${GLUT_LIBRARIES})
+ SET (GLUT_INCLUDE_PATH ${GLUT_INCLUDE_DIR})
+ENDIF(GLUT_FOUND)
+
+MARK_AS_ADVANCED(
+ GLUT_INCLUDE_DIR
+ GLUT_glut_LIBRARY
+ GLUT_Xmu_LIBRARY
+ GLUT_Xi_LIBRARY
+ )
diff --git a/Modules/FindGTK.cmake b/Modules/FindGTK.cmake
new file mode 100644
index 000000000..e9cc62f20
--- /dev/null
+++ b/Modules/FindGTK.cmake
@@ -0,0 +1,165 @@
+# - 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.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software 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.)
+
+# don't even bother under WIN32
+IF(UNIX)
+
+ FIND_PATH( GTK_gtk_INCLUDE_PATH NAMES gtk/gtk.h
+ PATH_SUFFIXES gtk-1.2 gtk12
+ PATHS
+ /usr/openwin/share/include
+ /usr/openwin/include
+ /opt/gnome/include
+ )
+
+ # Some Linux distributions (e.g. Red Hat) have glibconfig.h
+ # and glib.h in different directories, so we need to look
+ # for both.
+ # - Atanas Georgiev <atanas@cs.columbia.edu>
+
+ FIND_PATH( GTK_glibconfig_INCLUDE_PATH NAMES glibconfig.h
+ PATHS
+ /usr/openwin/share/include
+ /usr/local/include/glib12
+ /usr/lib/glib/include
+ /usr/local/lib/glib/include
+ /opt/gnome/include
+ /opt/gnome/lib/glib/include
+ )
+
+ FIND_PATH( GTK_glib_INCLUDE_PATH NAMES glib.h
+ PATH_SUFFIXES gtk-1.2 glib-1.2 glib12
+ PATHS
+ /usr/openwin/share/include
+ /usr/lib/glib/include
+ /opt/gnome/include
+ )
+
+ FIND_PATH( GTK_gtkgl_INCLUDE_PATH NAMES gtkgl/gtkglarea.h
+ PATHS /usr/openwin/share/include
+ /opt/gnome/include
+ )
+
+ FIND_LIBRARY( GTK_gtkgl_LIBRARY gtkgl
+ /usr/openwin/lib
+ /opt/gnome/lib
+ )
+
+ #
+ # The 12 suffix is thanks to the FreeBSD ports collection
+ #
+
+ FIND_LIBRARY( GTK_gtk_LIBRARY
+ NAMES gtk gtk12
+ PATHS /usr/openwin/lib
+ /opt/gnome/lib
+ )
+
+ FIND_LIBRARY( GTK_gdk_LIBRARY
+ NAMES gdk gdk12
+ PATHS /usr/openwin/lib
+ /opt/gnome/lib
+ )
+
+ FIND_LIBRARY( GTK_gmodule_LIBRARY
+ NAMES gmodule gmodule12
+ PATHS /usr/openwin/lib
+ /opt/gnome/lib
+ )
+
+ FIND_LIBRARY( GTK_glib_LIBRARY
+ NAMES glib glib12
+ PATHS /usr/openwin/lib
+ /opt/gnome/lib
+ )
+
+ FIND_LIBRARY( GTK_Xi_LIBRARY
+ NAMES Xi
+ PATHS /usr/openwin/lib
+ /opt/gnome/lib
+ )
+
+ FIND_LIBRARY( GTK_gthread_LIBRARY
+ NAMES gthread gthread12
+ PATHS /usr/openwin/lib
+ /opt/gnome/lib
+ )
+
+ IF(GTK_gtk_INCLUDE_PATH
+ AND GTK_glibconfig_INCLUDE_PATH
+ AND GTK_glib_INCLUDE_PATH
+ AND GTK_gtk_LIBRARY
+ AND GTK_glib_LIBRARY)
+
+ # Assume that if gtk and glib were found, the other
+ # supporting libraries have also been found.
+
+ SET( GTK_FOUND "YES" )
+ SET( GTK_INCLUDE_DIR ${GTK_gtk_INCLUDE_PATH}
+ ${GTK_glibconfig_INCLUDE_PATH}
+ ${GTK_glib_INCLUDE_PATH} )
+ SET( GTK_LIBRARIES ${GTK_gtk_LIBRARY}
+ ${GTK_gdk_LIBRARY}
+ ${GTK_glib_LIBRARY} )
+
+ IF(GTK_gmodule_LIBRARY)
+ SET(GTK_LIBRARIES ${GTK_LIBRARIES} ${GTK_gmodule_LIBRARY})
+ ENDIF(GTK_gmodule_LIBRARY)
+ IF(GTK_gthread_LIBRARY)
+ SET(GTK_LIBRARIES ${GTK_LIBRARIES} ${GTK_gthread_LIBRARY})
+ ENDIF(GTK_gthread_LIBRARY)
+ IF(GTK_Xi_LIBRARY)
+ SET(GTK_LIBRARIES ${GTK_LIBRARIES} ${GTK_Xi_LIBRARY})
+ ENDIF(GTK_Xi_LIBRARY)
+
+ IF(GTK_gtkgl_INCLUDE_PATH AND GTK_gtkgl_LIBRARY)
+ SET( GTK_GL_FOUND "YES" )
+ SET( GTK_INCLUDE_DIR ${GTK_INCLUDE_DIR}
+ ${GTK_gtkgl_INCLUDE_PATH} )
+ SET( GTK_LIBRARIES ${GTK_gtkgl_LIBRARY} ${GTK_LIBRARIES} )
+ MARK_AS_ADVANCED(
+ GTK_gtkgl_LIBRARY
+ GTK_gtkgl_INCLUDE_PATH
+ )
+ ENDIF(GTK_gtkgl_INCLUDE_PATH AND GTK_gtkgl_LIBRARY)
+
+ ENDIF(GTK_gtk_INCLUDE_PATH
+ AND GTK_glibconfig_INCLUDE_PATH
+ AND GTK_glib_INCLUDE_PATH
+ AND GTK_gtk_LIBRARY
+ AND GTK_glib_LIBRARY)
+
+ MARK_AS_ADVANCED(
+ GTK_gdk_LIBRARY
+ GTK_glib_INCLUDE_PATH
+ GTK_glib_LIBRARY
+ GTK_glibconfig_INCLUDE_PATH
+ GTK_gmodule_LIBRARY
+ GTK_gthread_LIBRARY
+ GTK_Xi_LIBRARY
+ GTK_gtk_INCLUDE_PATH
+ GTK_gtk_LIBRARY
+ GTK_gtkgl_INCLUDE_PATH
+ GTK_gtkgl_LIBRARY
+ )
+
+ENDIF(UNIX)
+
+
+
diff --git a/Modules/FindGTK2.cmake b/Modules/FindGTK2.cmake
new file mode 100644
index 000000000..a03c023e4
--- /dev/null
+++ b/Modules/FindGTK2.cmake
@@ -0,0 +1,590 @@
+# - 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.
+#
+# 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_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_SKIP_MARK_AS_ADVANCED - Disable marking cache variables as advanced
+# 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:
+#
+# 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()
+#
+
+#=============================================================================
+# Copyright 2009 Kitware, Inc.
+# Copyright 2008-2009 Philip Lowman <philip@yhbt.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.)
+
+# Version 1.3 (11/9/2010) (CMake 2.8.4)
+# * 11429: Add support for detecting GTK2 built with Visual Studio 10.
+# Thanks to Vincent Levesque for the patch.
+
+# Version 1.2 (8/30/2010) (CMake 2.8.3)
+# * Merge patch for detecting gdk-pixbuf library (split off
+# from core GTK in 2.21). Thanks to Vincent Untz for the patch
+# and Ricardo Cruz for the heads up.
+# Version 1.1 (8/19/2010) (CMake 2.8.3)
+# * Add support for detecting GTK2 under macports (thanks to Gary Kramlich)
+# Version 1.0 (8/12/2010) (CMake 2.8.3)
+# * Add support for detecting new pangommconfig.h header file
+# (Thanks to Sune Vuorela & the Debian Project for the patch)
+# * Add support for detecting fontconfig.h header
+# * Call find_package(Freetype) since it's required
+# * Add support for allowing users to add additional library directories
+# via the GTK2_ADDITIONAL_SUFFIXES variable (kind of a future-kludge in
+# case the GTK developers change versions on any of the directories in the
+# future).
+# Version 0.8 (1/4/2010)
+# * Get module working under MacOSX fink by adding /sw/include, /sw/lib
+# to PATHS and the gobject library
+# Version 0.7 (3/22/09)
+# * Checked into CMake CVS
+# * Added versioning support
+# * Module now defaults to searching for GTK if COMPONENTS not specified.
+# * Added HKCU prior to HKLM registry key and GTKMM specific environment
+# variable as per mailing list discussion.
+# * Added lib64 to include search path and a few other search paths where GTK
+# may be installed on Unix systems.
+# * Switched to lowercase CMake commands
+# * Prefaced internal variables with _GTK2 to prevent collision
+# * Changed internal macros to functions
+# * Enhanced documentation
+# Version 0.6 (1/8/08)
+# Added GTK2_SKIP_MARK_AS_ADVANCED option
+# Version 0.5 (12/19/08)
+# Second release to cmake mailing list
+
+#=============================================================
+# _GTK2_GET_VERSION
+# Internal function to parse the version number in gtkversion.h
+# _OUT_major = Major version number
+# _OUT_minor = Minor version number
+# _OUT_micro = Micro version number
+# _gtkversion_hdr = Header file to parse
+#=============================================================
+function(_GTK2_GET_VERSION _OUT_major _OUT_minor _OUT_micro _gtkversion_hdr)
+ file(READ ${_gtkversion_hdr} _contents)
+ if(_contents)
+ string(REGEX REPLACE ".*#define GTK_MAJOR_VERSION[ \t]+\\(([0-9]+)\\).*" "\\1" ${_OUT_major} "${_contents}")
+ string(REGEX REPLACE ".*#define GTK_MINOR_VERSION[ \t]+\\(([0-9]+)\\).*" "\\1" ${_OUT_minor} "${_contents}")
+ string(REGEX REPLACE ".*#define GTK_MICRO_VERSION[ \t]+\\(([0-9]+)\\).*" "\\1" ${_OUT_micro} "${_contents}")
+
+ if(NOT ${_OUT_major} MATCHES "[0-9]+")
+ message(FATAL_ERROR "Version parsing failed for GTK2_MAJOR_VERSION!")
+ endif()
+ if(NOT ${_OUT_minor} MATCHES "[0-9]+")
+ message(FATAL_ERROR "Version parsing failed for GTK2_MINOR_VERSION!")
+ endif()
+ if(NOT ${_OUT_micro} MATCHES "[0-9]+")
+ message(FATAL_ERROR "Version parsing failed for GTK2_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
+# _var = variable to set
+# _hdr = header file to look for
+#=============================================================
+function(_GTK2_FIND_INCLUDE_DIR _var _hdr)
+
+ if(GTK2_DEBUG)
+ message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
+ "_GTK2_FIND_INCLUDE_DIR( ${_var} ${_hdr} )")
+ endif()
+
+ set(_relatives
+ # If these ever change, things will break.
+ ${GTK2_ADDITIONAL_SUFFIXES}
+ glibmm-2.4
+ glib-2.0
+ atk-1.0
+ atkmm-1.6
+ cairo
+ cairomm-1.0
+ gdk-pixbuf-2.0
+ gdkmm-2.4
+ giomm-2.4
+ gtk-2.0
+ gtkmm-2.4
+ libglade-2.0
+ libglademm-2.4
+ pango-1.0
+ pangomm-1.4
+ sigc++-2.0
+ )
+
+ set(_suffixes)
+ foreach(_d ${_relatives})
+ list(APPEND _suffixes ${_d})
+ list(APPEND _suffixes ${_d}/include) # for /usr/lib/gtk-2.0/include
+ endforeach()
+
+ if(GTK2_DEBUG)
+ message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
+ "include suffixes = ${_suffixes}")
+ endif()
+
+ find_path(${_var} ${_hdr}
+ PATHS
+ /usr/local/lib64
+ /usr/local/lib
+ /usr/lib64
+ /usr/lib
+ /opt/gnome/include
+ /opt/gnome/lib
+ /opt/openwin/include
+ /usr/openwin/lib
+ /sw/include
+ /sw/lib
+ /opt/local/include
+ /opt/local/lib
+ $ENV{GTKMM_BASEPATH}/include
+ $ENV{GTKMM_BASEPATH}/lib
+ [HKEY_CURRENT_USER\\SOFTWARE\\gtkmm\\2.4;Path]/include
+ [HKEY_CURRENT_USER\\SOFTWARE\\gtkmm\\2.4;Path]/lib
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\gtkmm\\2.4;Path]/include
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\gtkmm\\2.4;Path]/lib
+ PATH_SUFFIXES
+ ${_suffixes}
+ )
+
+ if(${_var})
+ set(GTK2_INCLUDE_DIRS ${GTK2_INCLUDE_DIRS} ${${_var}} PARENT_SCOPE)
+ if(NOT GTK2_SKIP_MARK_AS_ADVANCED)
+ mark_as_advanced(${_var})
+ endif()
+ endif()
+
+endfunction(_GTK2_FIND_INCLUDE_DIR)
+
+#=============================================================
+# _GTK2_FIND_LIBRARY
+# Internal function to find libraries packaged with GTK2
+# _var = library variable to create
+#=============================================================
+function(_GTK2_FIND_LIBRARY _var _lib _expand_vc _append_version)
+
+ if(GTK2_DEBUG)
+ message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
+ "_GTK2_FIND_LIBRARY( ${_var} ${_lib} ${_expand_vc} ${_append_version} )")
+ endif()
+
+ # Not GTK versions per se but the versions encoded into Windows
+ # import libraries (GtkMM 2.14.1 has a gtkmm-vc80-2_4.lib for example)
+ # Also the MSVC libraries use _ for . (this is handled below)
+ set(_versions 2.20 2.18 2.16 2.14 2.12
+ 2.10 2.8 2.6 2.4 2.2 2.0
+ 1.20 1.18 1.16 1.14 1.12
+ 1.10 1.8 1.6 1.4 1.2 1.0)
+
+ set(_library)
+ set(_library_d)
+
+ set(_library ${_lib})
+
+ if(_expand_vc AND MSVC)
+ # Add vc80/vc90/vc100 midfixes
+ if(MSVC80)
+ set(_library ${_library}-vc80)
+ elseif(MSVC90)
+ set(_library ${_library}-vc90)
+ elseif(MSVC10)
+ set(_library ${_library}-vc100)
+ endif()
+ set(_library_d ${_library}-d)
+ endif()
+
+ if(GTK2_DEBUG)
+ message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
+ "After midfix addition = ${_library} and ${_library_d}")
+ endif()
+
+ set(_lib_list)
+ set(_libd_list)
+ if(_append_version)
+ foreach(_ver ${_versions})
+ list(APPEND _lib_list "${_library}-${_ver}")
+ list(APPEND _libd_list "${_library_d}-${_ver}")
+ endforeach()
+ else()
+ set(_lib_list ${_library})
+ set(_libd_list ${_library_d})
+ endif()
+
+ if(GTK2_DEBUG)
+ message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
+ "library list = ${_lib_list} and library debug list = ${_libd_list}")
+ endif()
+
+ # For some silly reason the MSVC libraries use _ instead of .
+ # in the version fields
+ if(_expand_vc AND MSVC)
+ set(_no_dots_lib_list)
+ set(_no_dots_libd_list)
+ foreach(_l ${_lib_list})
+ string(REPLACE "." "_" _no_dots_library ${_l})
+ list(APPEND _no_dots_lib_list ${_no_dots_library})
+ endforeach()
+ # And for debug
+ set(_no_dots_libsd_list)
+ foreach(_l ${_libd_list})
+ string(REPLACE "." "_" _no_dots_libraryd ${_l})
+ list(APPEND _no_dots_libd_list ${_no_dots_libraryd})
+ endforeach()
+
+ # Copy list back to original names
+ set(_lib_list ${_no_dots_lib_list})
+ set(_libd_list ${_no_dots_libd_list})
+ endif()
+
+ if(GTK2_DEBUG)
+ message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
+ "While searching for ${_var}, our proposed library list is ${_lib_list}")
+ endif()
+
+ find_library(${_var}
+ NAMES ${_lib_list}
+ PATHS
+ /opt/gnome/lib
+ /opt/gnome/lib64
+ /usr/openwin/lib
+ /usr/openwin/lib64
+ /sw/lib
+ $ENV{GTKMM_BASEPATH}/lib
+ [HKEY_CURRENT_USER\\SOFTWARE\\gtkmm\\2.4;Path]/lib
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\gtkmm\\2.4;Path]/lib
+ )
+
+ if(_expand_vc AND MSVC)
+ if(GTK2_DEBUG)
+ message(STATUS "[FindGTK2.cmake:${CMAKE_CURRENT_LIST_LINE}] "
+ "While searching for ${_var}_DEBUG our proposed library list is ${_libd_list}")
+ endif()
+
+ find_library(${_var}_DEBUG
+ NAMES ${_libd_list}
+ PATHS
+ $ENV{GTKMM_BASEPATH}/lib
+ [HKEY_CURRENT_USER\\SOFTWARE\\gtkmm\\2.4;Path]/lib
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\gtkmm\\2.4;Path]/lib
+ )
+
+ if(${_var} AND ${_var}_DEBUG)
+ if(NOT GTK2_SKIP_MARK_AS_ADVANCED)
+ mark_as_advanced(${_var}_DEBUG)
+ endif()
+ set(GTK2_LIBRARIES ${GTK2_LIBRARIES} optimized ${${_var}} debug ${${_var}_DEBUG})
+ set(GTK2_LIBRARIES ${GTK2_LIBRARIES} PARENT_SCOPE)
+ endif()
+ else()
+ if(NOT GTK2_SKIP_MARK_AS_ADVANCED)
+ mark_as_advanced(${_var})
+ endif()
+ set(GTK2_LIBRARIES ${GTK2_LIBRARIES} ${${_var}})
+ set(GTK2_LIBRARIES ${GTK2_LIBRARIES} PARENT_SCOPE)
+ # Set debug to release
+ set(${_var}_DEBUG ${${_var}})
+ set(${_var}_DEBUG ${${_var}} PARENT_SCOPE)
+ endif()
+endfunction(_GTK2_FIND_LIBRARY)
+
+#=============================================================
+
+#
+# main()
+#
+
+set(GTK2_FOUND)
+set(GTK2_INCLUDE_DIRS)
+set(GTK2_LIBRARIES)
+
+if(NOT GTK2_FIND_COMPONENTS)
+ # Assume they only want GTK
+ set(GTK2_FIND_COMPONENTS gtk)
+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_INCLUDE_DIR gtk/gtk.h)
+ if(GTK2_GTK_INCLUDE_DIR)
+ _GTK2_GET_VERSION(GTK2_MAJOR_VERSION
+ GTK2_MINOR_VERSION
+ GTK2_PATCH_VERSION
+ ${GTK2_GTK_INCLUDE_DIR}/gtk/gtkversion.h)
+ set(GTK2_VERSION
+ ${GTK2_MAJOR_VERSION}.${GTK2_MINOR_VERSION}.${GTK2_PATCH_VERSION})
+ if(GTK2_FIND_VERSION_EXACT)
+ if(GTK2_VERSION VERSION_EQUAL GTK2_FIND_VERSION)
+ set(GTK2_FAILED_VERSION_CHECK false)
+ endif()
+ else()
+ if(GTK2_VERSION VERSION_EQUAL GTK2_FIND_VERSION OR
+ GTK2_VERSION VERSION_GREATER GTK2_FIND_VERSION)
+ set(GTK2_FAILED_VERSION_CHECK false)
+ endif()
+ endif()
+ else()
+ # If we can't find the GTK include dir, we can't do version checking
+ if(GTK2_FIND_REQUIRED AND NOT GTK2_FIND_QUIETLY)
+ message(FATAL_ERROR "Could not find GTK2 include directory")
+ endif()
+ return()
+ endif()
+
+ if(GTK2_FAILED_VERSION_CHECK)
+ if(GTK2_FIND_REQUIRED AND NOT GTK2_FIND_QUIETLY)
+ if(GTK2_FIND_VERSION_EXACT)
+ message(FATAL_ERROR "GTK2 version check failed. Version ${GTK2_VERSION} was found, version ${GTK2_FIND_VERSION} is needed exactly.")
+ else()
+ message(FATAL_ERROR "GTK2 version check failed. Version ${GTK2_VERSION} was found, at least version ${GTK2_FIND_VERSION} is required")
+ endif()
+ endif()
+
+ # If the version check fails, exit out of the module here
+ return()
+ endif()
+endif()
+
+#
+# Find all components
+#
+
+find_package(Freetype)
+list(APPEND GTK2_INCLUDE_DIRS ${FREETYPE_INCLUDE_DIRS})
+list(APPEND GTK2_LIBRARIES ${FREETYPE_LIBRARIES})
+
+foreach(_GTK2_component ${GTK2_FIND_COMPONENTS})
+ if(_GTK2_component STREQUAL "gtk")
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GLIB_INCLUDE_DIR glib.h)
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GLIBCONFIG_INCLUDE_DIR glibconfig.h)
+ _GTK2_FIND_LIBRARY (GTK2_GLIB_LIBRARY glib false true)
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GOBJECT_INCLUDE_DIR gobject/gobject.h)
+ _GTK2_FIND_LIBRARY (GTK2_GOBJECT_LIBRARY gobject false true)
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GDK_PIXBUF_INCLUDE_DIR gdk-pixbuf/gdk-pixbuf.h)
+ _GTK2_FIND_LIBRARY (GTK2_GDK_PIXBUF_LIBRARY gdk_pixbuf false true)
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GDK_INCLUDE_DIR gdk/gdk.h)
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GDKCONFIG_INCLUDE_DIR gdkconfig.h)
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GTK_INCLUDE_DIR gtk/gtk.h)
+
+ if(UNIX)
+ _GTK2_FIND_LIBRARY (GTK2_GDK_LIBRARY gdk-x11 false true)
+ _GTK2_FIND_LIBRARY (GTK2_GTK_LIBRARY gtk-x11 false true)
+ else()
+ _GTK2_FIND_LIBRARY (GTK2_GDK_LIBRARY gdk-win32 false true)
+ _GTK2_FIND_LIBRARY (GTK2_GTK_LIBRARY gtk-win32 false true)
+ endif()
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_CAIRO_INCLUDE_DIR cairo.h)
+ _GTK2_FIND_LIBRARY (GTK2_CAIRO_LIBRARY cairo false false)
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_FONTCONFIG_INCLUDE_DIR fontconfig/fontconfig.h)
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_PANGO_INCLUDE_DIR pango/pango.h)
+ _GTK2_FIND_LIBRARY (GTK2_PANGO_LIBRARY pango false true)
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_ATK_INCLUDE_DIR atk/atk.h)
+ _GTK2_FIND_LIBRARY (GTK2_ATK_LIBRARY atk false true)
+
+
+ elseif(_GTK2_component STREQUAL "gtkmm")
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GLIBMM_INCLUDE_DIR glibmm.h)
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GLIBMMCONFIG_INCLUDE_DIR glibmmconfig.h)
+ _GTK2_FIND_LIBRARY (GTK2_GLIBMM_LIBRARY glibmm true true)
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GDKMM_INCLUDE_DIR gdkmm.h)
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GDKMMCONFIG_INCLUDE_DIR gdkmmconfig.h)
+ _GTK2_FIND_LIBRARY (GTK2_GDKMM_LIBRARY gdkmm true true)
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GTKMM_INCLUDE_DIR gtkmm.h)
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GTKMMCONFIG_INCLUDE_DIR gtkmmconfig.h)
+ _GTK2_FIND_LIBRARY (GTK2_GTKMM_LIBRARY gtkmm true true)
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_CAIROMM_INCLUDE_DIR cairomm/cairomm.h)
+ _GTK2_FIND_LIBRARY (GTK2_CAIROMM_LIBRARY cairomm true true)
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_PANGOMM_INCLUDE_DIR pangomm.h)
+ _GTK2_FIND_INCLUDE_DIR(GTK2_PANGOMMCONFIG_INCLUDE_DIR pangommconfig.h)
+ _GTK2_FIND_LIBRARY (GTK2_PANGOMM_LIBRARY pangomm true true)
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_SIGC++_INCLUDE_DIR sigc++/sigc++.h)
+ _GTK2_FIND_INCLUDE_DIR(GTK2_SIGC++CONFIG_INCLUDE_DIR sigc++config.h)
+ _GTK2_FIND_LIBRARY (GTK2_SIGC++_LIBRARY sigc true true)
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GIOMM_INCLUDE_DIR giomm.h)
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GIOMMCONFIG_INCLUDE_DIR giommconfig.h)
+ _GTK2_FIND_LIBRARY (GTK2_GIOMM_LIBRARY giomm true true)
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_ATKMM_INCLUDE_DIR atkmm.h)
+ _GTK2_FIND_LIBRARY (GTK2_ATKMM_LIBRARY atkmm true true)
+
+ elseif(_GTK2_component STREQUAL "glade")
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GLADE_INCLUDE_DIR glade/glade.h)
+ _GTK2_FIND_LIBRARY (GTK2_GLADE_LIBRARY glade false true)
+
+ elseif(_GTK2_component STREQUAL "glademm")
+
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GLADEMM_INCLUDE_DIR libglademm.h)
+ _GTK2_FIND_INCLUDE_DIR(GTK2_GLADEMMCONFIG_INCLUDE_DIR libglademmconfig.h)
+ _GTK2_FIND_LIBRARY (GTK2_GLADEMM_LIBRARY glademm true true)
+
+ else()
+ message(FATAL_ERROR "Unknown GTK2 component ${_component}")
+ endif()
+endforeach()
+
+#
+# Solve for the GTK2 version if we haven't already
+#
+if(NOT GTK2_FIND_VERSION AND GTK2_GTK_INCLUDE_DIR)
+ _GTK2_GET_VERSION(GTK2_MAJOR_VERSION
+ GTK2_MINOR_VERSION
+ GTK2_PATCH_VERSION
+ ${GTK2_GTK_INCLUDE_DIR}/gtk/gtkversion.h)
+ set(GTK2_VERSION ${GTK2_MAJOR_VERSION}.${GTK2_MINOR_VERSION}.${GTK2_PATCH_VERSION})
+endif()
+
+#
+# Try to enforce components
+#
+
+set(_GTK2_did_we_find_everything true) # This gets set to GTK2_FOUND
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+
+foreach(_GTK2_component ${GTK2_FIND_COMPONENTS})
+ string(TOUPPER ${_GTK2_component} _COMPONENT_UPPER)
+
+ 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
+ GTK2_GTK_INCLUDE_DIR
+
+ GTK2_GLIB_INCLUDE_DIR
+ GTK2_GLIBCONFIG_INCLUDE_DIR
+ GTK2_GLIB_LIBRARY
+
+ GTK2_GDK_INCLUDE_DIR
+ GTK2_GDKCONFIG_INCLUDE_DIR
+ GTK2_GDK_LIBRARY
+ )
+ elseif(_GTK2_component STREQUAL "gtkmm")
+ FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK2_${_COMPONENT_UPPER} "Some or all of the gtkmm libraries were not found."
+ GTK2_GTKMM_LIBRARY
+ GTK2_GTKMM_INCLUDE_DIR
+ GTK2_GTKMMCONFIG_INCLUDE_DIR
+
+ GTK2_GLIBMM_INCLUDE_DIR
+ GTK2_GLIBMMCONFIG_INCLUDE_DIR
+ GTK2_GLIBMM_LIBRARY
+
+ GTK2_GDKMM_INCLUDE_DIR
+ GTK2_GDKMMCONFIG_INCLUDE_DIR
+ GTK2_GDKMM_LIBRARY
+ )
+ elseif(_GTK2_component STREQUAL "glade")
+ FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK2_${_COMPONENT_UPPER} "The glade library was not found."
+ GTK2_GLADE_LIBRARY
+ GTK2_GLADE_INCLUDE_DIR
+ )
+ elseif(_GTK2_component STREQUAL "glademm")
+ FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK2_${_COMPONENT_UPPER} "The glademm library was not found."
+ GTK2_GLADEMM_LIBRARY
+ GTK2_GLADEMM_INCLUDE_DIR
+ GTK2_GLADEMMCONFIG_INCLUDE_DIR
+ )
+ endif()
+
+ if(NOT GTK2_${_COMPONENT_UPPER}_FOUND)
+ set(_GTK2_did_we_find_everything false)
+ endif()
+endforeach()
+
+if(_GTK2_did_we_find_everything AND NOT GTK2_VERSION_CHECK_FAILED)
+ set(GTK2_FOUND true)
+else()
+ # Unset our variables.
+ set(GTK2_FOUND false)
+ set(GTK2_VERSION)
+ set(GTK2_VERSION_MAJOR)
+ set(GTK2_VERSION_MINOR)
+ set(GTK2_VERSION_PATCH)
+ set(GTK2_INCLUDE_DIRS)
+ set(GTK2_LIBRARIES)
+endif()
+
+if(GTK2_INCLUDE_DIRS)
+ list(REMOVE_DUPLICATES GTK2_INCLUDE_DIRS)
+endif()
+
diff --git a/Modules/FindGTest.cmake b/Modules/FindGTest.cmake
new file mode 100644
index 000000000..6cffb5c59
--- /dev/null
+++ b/Modules/FindGTest.cmake
@@ -0,0 +1,158 @@
+# Locate the Google C++ Testing Framework.
+#
+# Defines the following variables:
+#
+# GTEST_FOUND - Found the Google Testing framework
+# GTEST_INCLUDE_DIRS - Include directories
+#
+# Also defines the library variables below as normal
+# variables. These contain debug/optimized keywords when
+# a debugging library is found.
+#
+# GTEST_BOTH_LIBRARIES - Both libgtest & libgtest-main
+# GTEST_LIBRARIES - libgtest
+# GTEST_MAIN_LIBRARIES - libgtest-main
+#
+# Accepts the following variables as input:
+#
+# GTEST_ROOT - (as a CMake or environment variable)
+# The root directory of the gtest install prefix
+#
+# 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)
+# include_directories(${GTEST_INCLUDE_DIRS})
+#
+# add_executable(foo foo.cc)
+# target_link_libraries(foo ${GTEST_BOTH_LIBRARIES})
+#
+# add_test(AllTestsInFoo foo)
+#
+#-----------------------
+#
+# 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.
+#
+# 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.
+#
+# Example:
+# set(FooTestArgs --foo 1 --bar 2)
+# add_executable(FooTest FooUnitTest.cc)
+# GTEST_ADD_TESTS(FooTest "${FooTestArgs}" FooUnitTest.cc)
+
+#=============================================================================
+# Copyright 2009 Kitware, Inc.
+# Copyright 2009 Philip Lowman <philip@yhbt.com>
+# Copyright 2009 Daniel Blezek <blezek@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.)
+#
+# Thanks to Daniel Blezek <blezek@gmail.com> for the GTEST_ADD_TESTS code
+
+function(GTEST_ADD_TESTS executable extra_args)
+ if(NOT ARGN)
+ message(FATAL_ERROR "Missing ARGN: Read the documentation for GTEST_ADD_TESTS")
+ endif()
+ foreach(source ${ARGN})
+ file(READ "${source}" contents)
+ string(REGEX MATCHALL "TEST_?F?\\(([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})
+ endforeach()
+ endforeach()
+endfunction()
+
+function(_gtest_append_debugs _endvar _library)
+ if(${_library} AND ${_library}_DEBUG)
+ set(_output optimized ${${_library}} debug ${${_library}_DEBUG})
+ else()
+ set(_output ${${_library}})
+ endif()
+ set(${_endvar} ${_output} PARENT_SCOPE)
+endfunction()
+
+function(_gtest_find_library _name)
+ find_library(${_name}
+ NAMES ${ARGN}
+ HINTS
+ $ENV{GTEST_ROOT}
+ ${GTEST_ROOT}
+ PATH_SUFFIXES ${_gtest_libpath_suffixes}
+ )
+ mark_as_advanced(${_name})
+endfunction()
+
+#
+
+if(NOT DEFINED GTEST_MSVC_SEARCH)
+ set(GTEST_MSVC_SEARCH MD)
+endif()
+
+set(_gtest_libpath_suffixes lib)
+if(MSVC)
+ if(GTEST_MSVC_SEARCH STREQUAL "MD")
+ list(APPEND _gtest_libpath_suffixes
+ msvc/gtest-md/Debug
+ msvc/gtest-md/Release)
+ elseif(GTEST_MSVC_SEARCH STREQUAL "MT")
+ list(APPEND _gtest_libpath_suffixes
+ msvc/gtest/Debug
+ msvc/gtest/Release)
+ endif()
+endif()
+
+
+find_path(GTEST_INCLUDE_DIR gtest/gtest.h
+ HINTS
+ $ENV{GTEST_ROOT}/include
+ ${GTEST_ROOT}/include
+)
+mark_as_advanced(GTEST_INCLUDE_DIR)
+
+if(MSVC AND GTEST_MSVC_SEARCH STREQUAL "MD")
+ # The provided /MD project files for Google Test add -md suffixes to the
+ # library names.
+ _gtest_find_library(GTEST_LIBRARY gtest-md gtest)
+ _gtest_find_library(GTEST_LIBRARY_DEBUG gtest-mdd gtestd)
+ _gtest_find_library(GTEST_MAIN_LIBRARY gtest_main-md gtest_main)
+ _gtest_find_library(GTEST_MAIN_LIBRARY_DEBUG gtest_main-mdd gtest_maind)
+else()
+ _gtest_find_library(GTEST_LIBRARY gtest)
+ _gtest_find_library(GTEST_LIBRARY_DEBUG gtestd)
+ _gtest_find_library(GTEST_MAIN_LIBRARY gtest_main)
+ _gtest_find_library(GTEST_MAIN_LIBRARY_DEBUG gtest_maind)
+endif()
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTest DEFAULT_MSG GTEST_LIBRARY GTEST_INCLUDE_DIR GTEST_MAIN_LIBRARY)
+
+if(GTEST_FOUND)
+ set(GTEST_INCLUDE_DIRS ${GTEST_INCLUDE_DIR})
+ _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()
+
diff --git a/Modules/FindGettext.cmake b/Modules/FindGettext.cmake
new file mode 100644
index 000000000..6dbc02618
--- /dev/null
+++ b/Modules/FindGettext.cmake
@@ -0,0 +1,220 @@
+# - 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)
+#
+# 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".
+
+#=============================================================================
+# Copyright 2007-2009 Kitware, Inc.
+# Copyright 2007 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.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+FIND_PROGRAM(GETTEXT_MSGMERGE_EXECUTABLE msgmerge)
+
+FIND_PROGRAM(GETTEXT_MSGFMT_EXECUTABLE msgfmt)
+
+IF(GETTEXT_MSGMERGE_EXECUTABLE)
+ EXECUTE_PROCESS(COMMAND ${GETTEXT_MSGMERGE_EXECUTABLE} --version
+ 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}")
+ ENDIF()
+ UNSET(gettext_version)
+ENDIF(GETTEXT_MSGMERGE_EXECUTABLE)
+
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Gettext
+ REQUIRED_VARS GETTEXT_MSGMERGE_EXECUTABLE GETTEXT_MSGFMT_EXECUTABLE
+ VERSION_VAR GETTEXT_VERSION_STRING)
+
+INCLUDE(CMakeParseArguments)
+
+FUNCTION(_GETTEXT_GET_UNIQUE_TARGET_NAME _name _unique_name)
+ SET(propertyName "_GETTEXT_UNIQUE_COUNTER_${_name}")
+ GET_PROPERTY(currentCounter GLOBAL PROPERTY "${propertyName}")
+ IF(NOT currentCounter)
+ SET(currentCounter 1)
+ ENDIF()
+ SET(${_unique_name} "${_name}_${currentCounter}" PARENT_SCOPE)
+ MATH(EXPR currentCounter "${currentCounter} + 1")
+ SET_PROPERTY(GLOBAL PROPERTY ${propertyName} ${currentCounter} )
+ENDFUNCTION()
+
+MACRO(GETTEXT_CREATE_TRANSLATIONS _potFile _firstPoFileArg)
+ # make it a real variable, so we can modify it here
+ SET(_firstPoFile "${_firstPoFileArg}")
+
+ SET(_gmoFiles)
+ GET_FILENAME_COMPONENT(_potName ${_potFile} NAME)
+ STRING(REGEX REPLACE "^(.+)(\\.[^.]+)$" "\\1" _potBasename ${_potName})
+ GET_FILENAME_COMPONENT(_absPotFile ${_potFile} ABSOLUTE)
+
+ SET(_addToAll)
+ IF(${_firstPoFile} STREQUAL "ALL")
+ SET(_addToAll "ALL")
+ SET(_firstPoFile)
+ ENDIF(${_firstPoFile} STREQUAL "ALL")
+
+ FOREACH (_currentPoFile ${_firstPoFile} ${ARGN})
+ GET_FILENAME_COMPONENT(_absFile ${_currentPoFile} ABSOLUTE)
+ GET_FILENAME_COMPONENT(_abs_PATH ${_absFile} PATH)
+ GET_FILENAME_COMPONENT(_lang ${_absFile} NAME_WE)
+ SET(_gmoFile ${CMAKE_CURRENT_BINARY_DIR}/${_lang}.gmo)
+
+ ADD_CUSTOM_COMMAND(
+ OUTPUT ${_gmoFile}
+ COMMAND ${GETTEXT_MSGMERGE_EXECUTABLE} --quiet --update --backup=none -s ${_absFile} ${_absPotFile}
+ COMMAND ${GETTEXT_MSGFMT_EXECUTABLE} -o ${_gmoFile} ${_absFile}
+ DEPENDS ${_absPotFile} ${_absFile}
+ )
+
+ INSTALL(FILES ${_gmoFile} DESTINATION share/locale/${_lang}/LC_MESSAGES RENAME ${_potBasename}.mo)
+ SET(_gmoFiles ${_gmoFiles} ${_gmoFile})
+
+ ENDFOREACH (_currentPoFile )
+
+ IF(NOT TARGET translations)
+ ADD_CUSTOM_TARGET(translations)
+ ENDIF()
+
+ _GETTEXT_GET_UNIQUE_TARGET_NAME(translations uniqueTargetName)
+
+ ADD_CUSTOM_TARGET(${uniqueTargetName} ${_addToAll} DEPENDS ${_gmoFiles})
+
+ ADD_DEPENDENCIES(translations ${uniqueTargetName})
+
+ENDMACRO(GETTEXT_CREATE_TRANSLATIONS )
+
+
+FUNCTION(GETTEXT_PROCESS_POT_FILE _potFile)
+ SET(_gmoFiles)
+ SET(_options ALL)
+ SET(_oneValueArgs INSTALL_DESTINATION)
+ SET(_multiValueArgs LANGUAGES)
+
+ CMAKE_PARSE_ARGUMENTS(_parsedArguments "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
+
+ GET_FILENAME_COMPONENT(_potName ${_potFile} NAME)
+ STRING(REGEX REPLACE "^(.+)(\\.[^.]+)$" "\\1" _potBasename ${_potName})
+ GET_FILENAME_COMPONENT(_absPotFile ${_potFile} ABSOLUTE)
+
+ FOREACH (_lang ${_parsedArguments_LANGUAGES})
+ SET(_poFile "${CMAKE_CURRENT_BINARY_DIR}/${_lang}.po")
+ SET(_gmoFile "${CMAKE_CURRENT_BINARY_DIR}/${_lang}.gmo")
+
+ ADD_CUSTOM_COMMAND(
+ OUTPUT "${_poFile}"
+ COMMAND ${GETTEXT_MSGMERGE_EXECUTABLE} --quiet --update --backup=none -s ${_poFile} ${_absPotFile}
+ DEPENDS ${_absPotFile}
+ )
+
+ ADD_CUSTOM_COMMAND(
+ OUTPUT "${_gmoFile}"
+ COMMAND ${GETTEXT_MSGFMT_EXECUTABLE} -o ${_gmoFile} ${_poFile}
+ DEPENDS ${_absPotFile} ${_poFile}
+ )
+
+ IF(_parsedArguments_INSTALL_DESTINATION)
+ INSTALL(FILES ${_gmoFile} DESTINATION ${_parsedArguments_INSTALL_DESTINATION}/${_lang}/LC_MESSAGES RENAME ${_potBasename}.mo)
+ ENDIF(_parsedArguments_INSTALL_DESTINATION)
+ LIST(APPEND _gmoFiles ${_gmoFile})
+ ENDFOREACH (_lang )
+
+ IF(NOT TARGET potfiles)
+ ADD_CUSTOM_TARGET(potfiles)
+ ENDIF()
+
+ _GETTEXT_GET_UNIQUE_TARGET_NAME( potfiles uniqueTargetName)
+
+ IF(_parsedArguments_ALL)
+ ADD_CUSTOM_TARGET(${uniqueTargetName} ALL DEPENDS ${_gmoFiles})
+ ELSE(_parsedArguments_ALL)
+ ADD_CUSTOM_TARGET(${uniqueTargetName} DEPENDS ${_gmoFiles})
+ ENDIF(_parsedArguments_ALL)
+
+ ADD_DEPENDENCIES(potfiles ${uniqueTargetName})
+
+ENDFUNCTION(GETTEXT_PROCESS_POT_FILE)
+
+
+FUNCTION(GETTEXT_PROCESS_PO_FILES _lang)
+ SET(_options ALL)
+ SET(_oneValueArgs INSTALL_DESTINATION)
+ SET(_multiValueArgs PO_FILES)
+ SET(_gmoFiles)
+
+ CMAKE_PARSE_ARGUMENTS(_parsedArguments "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN})
+
+ FOREACH(_current_PO_FILE ${_parsedArguments_PO_FILES})
+ GET_FILENAME_COMPONENT(_name ${_current_PO_FILE} NAME)
+ STRING(REGEX REPLACE "^(.+)(\\.[^.]+)$" "\\1" _basename ${_name})
+ SET(_gmoFile ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.gmo)
+ ADD_CUSTOM_COMMAND(OUTPUT ${_gmoFile}
+ COMMAND ${GETTEXT_MSGFMT_EXECUTABLE} -o ${_gmoFile} ${_current_PO_FILE}
+ WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
+ DEPENDS ${_current_PO_FILE}
+ )
+
+ IF(_parsedArguments_INSTALL_DESTINATION)
+ INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.gmo DESTINATION ${_parsedArguments_INSTALL_DESTINATION}/${_lang}/LC_MESSAGES/ RENAME ${_basename}.mo)
+ ENDIF(_parsedArguments_INSTALL_DESTINATION)
+ LIST(APPEND _gmoFiles ${_gmoFile})
+ ENDFOREACH(_current_PO_FILE)
+
+
+ IF(NOT TARGET pofiles)
+ ADD_CUSTOM_TARGET(pofiles)
+ ENDIF()
+
+ _GETTEXT_GET_UNIQUE_TARGET_NAME( pofiles uniqueTargetName)
+
+ IF(_parsedArguments_ALL)
+ ADD_CUSTOM_TARGET(${uniqueTargetName} ALL DEPENDS ${_gmoFiles})
+ ELSE(_parsedArguments_ALL)
+ ADD_CUSTOM_TARGET(${uniqueTargetName} DEPENDS ${_gmoFiles})
+ ENDIF(_parsedArguments_ALL)
+
+ ADD_DEPENDENCIES(pofiles ${uniqueTargetName})
+
+ENDFUNCTION(GETTEXT_PROCESS_PO_FILES)
+
+IF (GETTEXT_MSGMERGE_EXECUTABLE AND GETTEXT_MSGFMT_EXECUTABLE )
+ SET(GETTEXT_FOUND TRUE)
+ELSE (GETTEXT_MSGMERGE_EXECUTABLE AND GETTEXT_MSGFMT_EXECUTABLE )
+ SET(GETTEXT_FOUND FALSE)
+ IF (GetText_REQUIRED)
+ MESSAGE(FATAL_ERROR "GetText not found")
+ ENDIF (GetText_REQUIRED)
+ENDIF (GETTEXT_MSGMERGE_EXECUTABLE AND GETTEXT_MSGFMT_EXECUTABLE )
diff --git a/Modules/FindGit.cmake b/Modules/FindGit.cmake
new file mode 100644
index 000000000..f89d1afa3
--- /dev/null
+++ b/Modules/FindGit.cmake
@@ -0,0 +1,62 @@
+# 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)
+# Example usage:
+# find_package(Git)
+# if(GIT_FOUND)
+# message("git found: ${GIT_EXECUTABLE}")
+# endif()
+
+#=============================================================================
+# Copyright 2010 Kitware, Inc.
+# Copyright 2012 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.)
+
+# Look for 'git' or 'eg' (easy git)
+#
+set(git_names git eg)
+
+# Prefer .cmd variants on Windows unless running in a Makefile
+# in the MSYS shell.
+#
+if(WIN32)
+ if(NOT CMAKE_GENERATOR MATCHES "MSYS")
+ set(git_names git.cmd git eg.cmd eg)
+ endif()
+endif()
+
+find_program(GIT_EXECUTABLE
+ NAMES ${git_names}
+ PATH_SUFFIXES Git/cmd Git/bin
+ DOC "git command line client"
+ )
+mark_as_advanced(GIT_EXECUTABLE)
+
+if(GIT_EXECUTABLE)
+ execute_process(COMMAND ${GIT_EXECUTABLE} --version
+ OUTPUT_VARIABLE git_version
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if (git_version MATCHES "^git version [0-9]")
+ string(REPLACE "git version " "" GIT_VERSION_STRING "${git_version}")
+ endif()
+ unset(git_version)
+endif(GIT_EXECUTABLE)
+
+# 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)
+find_package_handle_standard_args(Git
+ REQUIRED_VARS GIT_EXECUTABLE
+ VERSION_VAR GIT_VERSION_STRING)
diff --git a/Modules/FindGnuTLS.cmake b/Modules/FindGnuTLS.cmake
new file mode 100644
index 000000000..02f29648a
--- /dev/null
+++ b/Modules/FindGnuTLS.cmake
@@ -0,0 +1,69 @@
+# - 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
+
+#=============================================================================
+# Copyright 2009 Kitware, Inc.
+# Copyright 2009 Philip Lowman <philip@yhbt.com>
+# Copyright 2009 Brad Hards <bradh@kde.org>
+# Copyright 2006 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.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+# Note that this doesn't try to find the gnutls-extra package.
+
+
+IF (GNUTLS_INCLUDE_DIR AND GNUTLS_LIBRARY)
+ # in cache already
+ SET(gnutls_FIND_QUIETLY TRUE)
+ENDIF (GNUTLS_INCLUDE_DIR AND GNUTLS_LIBRARY)
+
+IF (NOT WIN32)
+ # try using pkg-config to get the directories and then use these values
+ # in the FIND_PATH() and FIND_LIBRARY() calls
+ # also fills in GNUTLS_DEFINITIONS, although that isn't normally useful
+ FIND_PACKAGE(PkgConfig QUIET)
+ PKG_CHECK_MODULES(PC_GNUTLS QUIET gnutls)
+ SET(GNUTLS_DEFINITIONS ${PC_GNUTLS_CFLAGS_OTHER})
+ SET(GNUTLS_VERSION_STRING ${PC_GNUTLS_VERSION})
+ENDIF (NOT WIN32)
+
+FIND_PATH(GNUTLS_INCLUDE_DIR gnutls/gnutls.h
+ HINTS
+ ${PC_GNUTLS_INCLUDEDIR}
+ ${PC_GNUTLS_INCLUDE_DIRS}
+ )
+
+FIND_LIBRARY(GNUTLS_LIBRARY NAMES gnutls libgnutls
+ HINTS
+ ${PC_GNUTLS_LIBDIR}
+ ${PC_GNUTLS_LIBRARY_DIRS}
+ )
+
+MARK_AS_ADVANCED(GNUTLS_INCLUDE_DIR GNUTLS_LIBRARY)
+
+# handle the QUIETLY and REQUIRED arguments and set GNUTLS_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(GnuTLS
+ REQUIRED_VARS GNUTLS_LIBRARY GNUTLS_INCLUDE_DIR
+ VERSION_VAR GNUTLS_VERSION_STRING)
+
+IF(GNUTLS_FOUND)
+ SET(GNUTLS_LIBRARIES ${GNUTLS_LIBRARY})
+ SET(GNUTLS_INCLUDE_DIRS ${GNUTLS_INCLUDE_DIR})
+ENDIF()
+
diff --git a/Modules/FindGnuplot.cmake b/Modules/FindGnuplot.cmake
new file mode 100644
index 000000000..b8dc3f49a
--- /dev/null
+++ b/Modules/FindGnuplot.cmake
@@ -0,0 +1,57 @@
+# - 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_VERSION_STRING will not work for old versions like 3.7.1.
+
+#=============================================================================
+# 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.)
+
+INCLUDE(FindCygwin)
+
+FIND_PROGRAM(GNUPLOT_EXECUTABLE
+ NAMES
+ gnuplot
+ pgnuplot
+ wgnupl32
+ PATHS
+ ${CYGWIN_INSTALL_PATH}/bin
+)
+
+IF (GNUPLOT_EXECUTABLE)
+ EXECUTE_PROCESS(COMMAND "${GNUPLOT_EXECUTABLE}" --version
+ OUTPUT_VARIABLE GNUPLOT_OUTPUT_VARIABLE
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ STRING(REGEX REPLACE "^gnuplot ([0-9\\.]+)( patchlevel )?" "\\1." GNUPLOT_VERSION_STRING "${GNUPLOT_OUTPUT_VARIABLE}")
+ STRING(REGEX REPLACE "\\.$" "" GNUPLOT_VERSION_STRING "${GNUPLOT_VERSION_STRING}")
+ UNSET(GNUPLOT_OUTPUT_VARIABLE)
+ENDIF()
+
+# for compatibility
+SET(GNUPLOT ${GNUPLOT_EXECUTABLE})
+
+# handle the QUIETLY and REQUIRED arguments and set GNUPLOT_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Gnuplot
+ REQUIRED_VARS GNUPLOT_EXECUTABLE
+ VERSION_VAR GNUPLOT_VERSION_STRING)
+
+MARK_AS_ADVANCED( GNUPLOT_EXECUTABLE )
+
diff --git a/Modules/FindHDF5.cmake b/Modules/FindHDF5.cmake
new file mode 100644
index 000000000..bc606389b
--- /dev/null
+++ b/Modules/FindHDF5.cmake
@@ -0,0 +1,385 @@
+# - 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.
+#
+# 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.
+#
+# 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.
+#
+# 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
+
+#=============================================================================
+# 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 module is maintained by Will Dicharry <wdicharry@stellarscience.com>.
+
+include(SelectLibraryConfigurations)
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+
+# List of the valid HDF5 components
+set( HDF5_VALID_COMPONENTS
+ C
+ CXX
+ Fortran
+ HL
+ Fortran_HL
+)
+
+# Validate the list of find components.
+if( NOT HDF5_FIND_COMPONENTS )
+ set( HDF5_LANGUAGE_BINDINGS "C" )
+else()
+ # add the extra specified components, ensuring that they are valid.
+ foreach( component ${HDF5_FIND_COMPONENTS} )
+ list( FIND HDF5_VALID_COMPONENTS ${component} component_location )
+ if( ${component_location} EQUAL -1 )
+ message( FATAL_ERROR
+ "\"${component}\" is not a valid HDF5 component." )
+ else()
+ list( APPEND HDF5_LANGUAGE_BINDINGS ${component} )
+ endif()
+ endforeach()
+endif()
+
+# try to find the HDF5 wrapper compilers
+find_program( HDF5_C_COMPILER_EXECUTABLE
+ NAMES h5cc h5pcc
+ 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++
+ 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
+ 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 )
+
+find_program( HDF5_DIFF_EXECUTABLE
+ NAMES h5diff
+ HINTS ENV HDF5_ROOT
+ PATH_SUFFIXES bin Bin
+ DOC "HDF5 file differencing tool." )
+mark_as_advanced( HDF5_DIFF_EXECUTABLE )
+
+# Invoke the HDF5 wrapper compiler. The compiler return value is stored to the
+# return_value argument, the text output is stored to the output variable.
+macro( _HDF5_invoke_compiler language output return_value )
+ if( HDF5_${language}_COMPILER_EXECUTABLE )
+ exec_program( ${HDF5_${language}_COMPILER_EXECUTABLE}
+ ARGS -show
+ OUTPUT_VARIABLE ${output}
+ RETURN_VALUE ${return_value}
+ )
+ if( ${${return_value}} EQUAL 0 )
+ # do nothing
+ else()
+ message( STATUS
+ "Unable to determine HDF5 ${language} flags from HDF5 wrapper." )
+ endif()
+ endif()
+endmacro()
+
+# Parse a compile line for definitions, includes, library paths, and libraries.
+macro( _HDF5_parse_compile_line
+ compile_line_var
+ include_paths
+ definitions
+ library_paths
+ libraries )
+
+ # Match the include paths
+ string( REGEX MATCHALL "-I([^\" ]+)" include_path_flags
+ "${${compile_line_var}}"
+ )
+ foreach( IPATH ${include_path_flags} )
+ string( REGEX REPLACE "^-I" "" IPATH ${IPATH} )
+ string( REGEX REPLACE "//" "/" IPATH ${IPATH} )
+ list( APPEND ${include_paths} ${IPATH} )
+ endforeach()
+
+ # Match the definitions
+ string( REGEX MATCHALL "-D[^ ]*" definition_flags "${${compile_line_var}}" )
+ foreach( DEF ${definition_flags} )
+ list( APPEND ${definitions} ${DEF} )
+ endforeach()
+
+ # Match the library paths
+ string( REGEX MATCHALL "-L([^\" ]+|\"[^\"]+\")" library_path_flags
+ "${${compile_line_var}}"
+ )
+
+ foreach( LPATH ${library_path_flags} )
+ string( REGEX REPLACE "^-L" "" LPATH ${LPATH} )
+ string( REGEX REPLACE "//" "/" LPATH ${LPATH} )
+ list( APPEND ${library_paths} ${LPATH} )
+ endforeach()
+
+ # now search for the library names specified in the compile line (match -l...)
+ # match only -l's preceded by a space or comma
+ # this is to exclude directory names like xxx-linux/
+ string( REGEX MATCHALL "[, ]-l([^\", ]+)" library_name_flags
+ "${${compile_line_var}}" )
+ # strip the -l from all of the library flags and add to the search list
+ foreach( LIB ${library_name_flags} )
+ string( REGEX REPLACE "^[, ]-l" "" LIB ${LIB} )
+ list( APPEND ${libraries} ${LIB} )
+ endforeach()
+endmacro()
+
+# Try to find HDF5 using an installed hdf5-config.cmake
+if( NOT HDF5_FOUND )
+ find_package( HDF5 QUIET NO_MODULE )
+ if( HDF5_FOUND )
+ set( HDF5_INCLUDE_DIRS ${HDF5_INCLUDE_DIR} )
+ set( HDF5_LIBRARIES )
+ set( HDF5_C_TARGET hdf5 )
+ set( HDF5_CXX_TARGET hdf5_cpp )
+ set( HDF5_HL_TARGET hdf5_hl )
+ set( HDF5_Fortran_TARGET hdf5_fortran )
+ set( HDF5_Fortran_HL_TARGET hdf5_hl_fortran )
+ foreach( _component ${HDF5_LANGUAGE_BINDINGS} )
+ list( FIND HDF5_VALID_COMPONENTS ${_component} _component_location )
+ get_target_property( _comp_location ${HDF5_${_component}_TARGET} LOCATION )
+ if( _comp_location )
+ set( HDF5_${_component}_LIBRARY ${_comp_location} CACHE PATH
+ "HDF5 ${_component} library" )
+ mark_as_advanced( HDF5_${_component}_LIBRARY )
+ list( APPEND HDF5_LIBRARIES ${HDF5_${_component}_LIBRARY} )
+ endif()
+ endforeach()
+ endif()
+endif()
+
+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 )
+
+ # seed the initial lists of libraries to find with items we know we need
+ set( HDF5_C_LIBRARY_NAMES_INIT hdf5 )
+ set( HDF5_HL_LIBRARY_NAMES_INIT hdf5_hl ${HDF5_C_LIBRARY_NAMES_INIT} )
+ 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
+ ${HDF5_Fortran_LIBRARY_NAMES_INIT} )
+
+ foreach( LANGUAGE ${HDF5_LANGUAGE_BINDINGS} )
+ if( HDF5_${LANGUAGE}_COMPILE_LINE )
+ _HDF5_parse_compile_line( HDF5_${LANGUAGE}_COMPILE_LINE
+ HDF5_${LANGUAGE}_INCLUDE_FLAGS
+ HDF5_${LANGUAGE}_DEFINITIONS
+ HDF5_${LANGUAGE}_LIBRARY_DIRS
+ HDF5_${LANGUAGE}_LIBRARY_NAMES
+ )
+
+ # take a guess that the includes may be in the 'include' sibling
+ # directory of a library directory.
+ foreach( dir ${HDF5_${LANGUAGE}_LIBRARY_DIRS} )
+ list( APPEND HDF5_${LANGUAGE}_INCLUDE_FLAGS ${dir}/../include )
+ endforeach()
+ endif()
+
+ # set the definitions for the language bindings.
+ list( APPEND HDF5_DEFINITIONS ${HDF5_${LANGUAGE}_DEFINITIONS} )
+
+ # find the HDF5 include directories
+ if(${LANGUAGE} MATCHES "Fortran.*")
+ set(HDF5_INCLUDE_FILENAME hdf5.mod)
+ else()
+ set(HDF5_INCLUDE_FILENAME hdf5.h)
+ endif()
+
+ find_path( HDF5_${LANGUAGE}_INCLUDE_DIR ${HDF5_INCLUDE_FILENAME}
+ HINTS
+ ${HDF5_${LANGUAGE}_INCLUDE_FLAGS}
+ ENV
+ HDF5_ROOT
+ PATHS
+ $ENV{HOME}/.local/include
+ PATH_SUFFIXES
+ include
+ Include
+ )
+ mark_as_advanced( HDF5_${LANGUAGE}_INCLUDE_DIR )
+ list( APPEND HDF5_INCLUDE_DIRS ${HDF5_${LANGUAGE}_INCLUDE_DIR} )
+
+ set( HDF5_${LANGUAGE}_LIBRARY_NAMES
+ ${HDF5_${LANGUAGE}_LIBRARY_NAMES_INIT}
+ ${HDF5_${LANGUAGE}_LIBRARY_NAMES} )
+
+ # find the HDF5 libraries
+ foreach( LIB ${HDF5_${LANGUAGE}_LIBRARY_NAMES} )
+ 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
+ # 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 )
+ set( THIS_LIBRARY_SEARCH_RELEASE lib${LIB}.a ${LIB} )
+ else()
+ set( THIS_LIBRARY_SEARCH_DEBUG ${LIB}d )
+ set( THIS_LIBRARY_SEARCH_RELEASE ${LIB} )
+ endif()
+ find_library( HDF5_${LIB}_LIBRARY_DEBUG
+ NAMES ${THIS_LIBRARY_SEARCH_DEBUG}
+ HINTS ${HDF5_${LANGUAGE}_LIBRARY_DIRS}
+ ENV HDF5_ROOT
+ PATH_SUFFIXES lib Lib )
+ find_library( HDF5_${LIB}_LIBRARY_RELEASE
+ NAMES ${THIS_LIBRARY_SEARCH_RELEASE}
+ HINTS ${HDF5_${LANGUAGE}_LIBRARY_DIRS}
+ ENV HDF5_ROOT
+ PATH_SUFFIXES lib Lib )
+ select_library_configurations( HDF5_${LIB} )
+ # even though we adjusted the individual library names in
+ # select_library_configurations, we still need to distinguish
+ # between debug and release variants because HDF5_LIBRARIES will
+ # need to specify different lists for debug and optimized builds.
+ # We can't just use the HDF5_${LIB}_LIBRARY variable (which was set
+ # up by the selection macro above) because it may specify debug and
+ # optimized variants for a particular library, but a list of
+ # libraries is allowed to specify debug and optimized only once.
+ list( APPEND HDF5_${LANGUAGE}_LIBRARIES_DEBUG
+ ${HDF5_${LIB}_LIBRARY_DEBUG} )
+ list( APPEND HDF5_${LANGUAGE}_LIBRARIES_RELEASE
+ ${HDF5_${LIB}_LIBRARY_RELEASE} )
+ endforeach()
+ list( APPEND HDF5_LIBRARY_DIRS ${HDF5_${LANGUAGE}_LIBRARY_DIRS} )
+
+ # Append the libraries for this language binding to the list of all
+ # required libraries.
+ list( APPEND HDF5_LIBRARIES_DEBUG
+ ${HDF5_${LANGUAGE}_LIBRARIES_DEBUG} )
+ list( APPEND HDF5_LIBRARIES_RELEASE
+ ${HDF5_${LANGUAGE}_LIBRARIES_RELEASE} )
+ endforeach()
+
+ # We may have picked up some duplicates in various lists during the above
+ # process for the language bindings (both the C and C++ bindings depend on
+ # libz for example). Remove the duplicates. It appears that the default
+ # CMake behavior is to remove duplicates from the end of a list. However,
+ # for link lines, this is incorrect since unresolved symbols are searched
+ # for down the link line. Therefore, we reverse the list, remove the
+ # duplicates, and then reverse it again to get the duplicates removed from
+ # the beginning.
+ macro( _remove_duplicates_from_beginning _list_name )
+ list( REVERSE ${_list_name} )
+ list( REMOVE_DUPLICATES ${_list_name} )
+ list( REVERSE ${_list_name} )
+ endmacro()
+
+ if( HDF5_INCLUDE_DIRS )
+ _remove_duplicates_from_beginning( HDF5_INCLUDE_DIRS )
+ endif()
+ if( HDF5_LIBRARIES_DEBUG )
+ _remove_duplicates_from_beginning( HDF5_LIBRARIES_DEBUG )
+ endif()
+ if( HDF5_LIBRARIES_RELEASE )
+ _remove_duplicates_from_beginning( HDF5_LIBRARIES_RELEASE )
+ endif()
+ if( HDF5_LIBRARY_DIRS )
+ _remove_duplicates_from_beginning( HDF5_LIBRARY_DIRS )
+ endif()
+
+ # Construct the complete list of HDF5 libraries with debug and optimized
+ # variants when the generator supports them.
+ if( CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE )
+ set( HDF5_LIBRARIES )
+ foreach( _lib ${HDF5_LIBRARIES_DEBUG} )
+ list( APPEND HDF5_LIBRARIES debug ${_lib} )
+ endforeach()
+ foreach( _lib ${HDF5_LIBRARIES_RELEASE} )
+ list( APPEND HDF5_LIBRARIES optimized ${_lib} )
+ endforeach()
+ else()
+ set( HDF5_LIBRARIES ${HDF5_LIBRARIES_RELEASE} )
+ endif()
+
+ # 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 )
+ foreach( _dir IN LISTS HDF5_INCLUDE_DIRS )
+ if( EXISTS "${_dir}/H5pubconf.h" )
+ file( STRINGS "${_dir}/H5pubconf.h"
+ HDF5_HAVE_PARALLEL_DEFINE
+ REGEX "HAVE_PARALLEL 1" )
+ if( HDF5_HAVE_PARALLEL_DEFINE )
+ set( HDF5_IS_PARALLEL TRUE )
+ endif()
+ endif()
+ endforeach()
+ set( HDF5_IS_PARALLEL ${HDF5_IS_PARALLEL} CACHE BOOL
+ "HDF5 library compiled with parallel IO support" )
+ mark_as_advanced( HDF5_IS_PARALLEL )
+
+ # For backwards compatibility we set HDF5_INCLUDE_DIR to the value of
+ # HDF5_INCLUDE_DIRS
+ if( HDF5_INCLUDE_DIRS )
+ set( HDF5_INCLUDE_DIR "${HDF5_INCLUDE_DIRS}" )
+ endif()
+
+endif()
+
+find_package_handle_standard_args( HDF5 DEFAULT_MSG
+ HDF5_LIBRARIES
+ HDF5_INCLUDE_DIRS
+)
+
diff --git a/Modules/FindHSPELL.cmake b/Modules/FindHSPELL.cmake
new file mode 100644
index 000000000..ca5709b62
--- /dev/null
+++ b/Modules/FindHSPELL.cmake
@@ -0,0 +1,46 @@
+# - 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_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.
+# Copyright 2006 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.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+FIND_PATH(HSPELL_INCLUDE_DIR hspell.h)
+
+FIND_LIBRARY(HSPELL_LIBRARIES NAMES hspell)
+
+IF (HSPELL_INCLUDE_DIR)
+ FILE(READ "${HSPELL_INCLUDE_DIR}/hspell.h" HSPELL_H)
+ STRING(REGEX REPLACE ".*#define HSPELL_VERSION_MAJOR ([0-9]+).*" "\\1" HSPELL_VERSION_MAJOR "${HSPELL_H}")
+ STRING(REGEX REPLACE ".*#define HSPELL_VERSION_MINOR ([0-9]+).*" "\\1" HSPELL_VERSION_MINOR "${HSPELL_H}")
+ SET(HSPELL_VERSION_STRING "${HSPELL_VERSION_MAJOR}.${HSPELL_VERSION_MINOR}")
+ENDIF()
+
+# handle the QUIETLY and REQUIRED arguments and set HSPELL_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(HSPELL
+ REQUIRED_VARS HSPELL_LIBRARIES HSPELL_INCLUDE_DIR
+ VERSION_VAR HSPELL_VERSION_STRING)
+
+MARK_AS_ADVANCED(HSPELL_INCLUDE_DIR HSPELL_LIBRARIES)
+
diff --git a/Modules/FindHTMLHelp.cmake b/Modules/FindHTMLHelp.cmake
new file mode 100644
index 000000000..4455b0797
--- /dev/null
+++ b/Modules/FindHTMLHelp.cmake
@@ -0,0 +1,54 @@
+# - 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)
+#
+
+#=============================================================================
+# 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.)
+
+IF(WIN32)
+
+ FIND_PROGRAM(HTML_HELP_COMPILER
+ hhc
+ "[HKEY_CURRENT_USER\\Software\\Microsoft\\HTML Help Workshop;InstallDir]"
+ "$ENV{ProgramFiles}/HTML Help Workshop"
+ "C:/Program Files/HTML Help Workshop"
+ )
+
+ GET_FILENAME_COMPONENT(HTML_HELP_COMPILER_PATH "${HTML_HELP_COMPILER}" PATH)
+
+ FIND_PATH(HTML_HELP_INCLUDE_PATH
+ htmlhelp.h
+ "${HTML_HELP_COMPILER_PATH}/include"
+ "[HKEY_CURRENT_USER\\Software\\Microsoft\\HTML Help Workshop;InstallDir]/include"
+ "$ENV{ProgramFiles}/HTML Help Workshop/include"
+ "C:/Program Files/HTML Help Workshop/include"
+ )
+
+ FIND_LIBRARY(HTML_HELP_LIBRARY
+ htmlhelp
+ "${HTML_HELP_COMPILER_PATH}/lib"
+ "[HKEY_CURRENT_USER\\Software\\Microsoft\\HTML Help Workshop;InstallDir]/lib"
+ "$ENV{ProgramFiles}/HTML Help Workshop/lib"
+ "C:/Program Files/HTML Help Workshop/lib"
+ )
+
+ MARK_AS_ADVANCED(
+ HTML_HELP_COMPILER
+ HTML_HELP_INCLUDE_PATH
+ HTML_HELP_LIBRARY
+ )
+
+ENDIF(WIN32)
diff --git a/Modules/FindITK.cmake b/Modules/FindITK.cmake
new file mode 100644
index 000000000..a3ca99899
--- /dev/null
+++ b/Modules/FindITK.cmake
@@ -0,0 +1,57 @@
+# - 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
+# compatability. 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-compatability.
+ SET(USE_ITK_FILE ${ITK_USE_FILE})
+ENDIF()
diff --git a/Modules/FindImageMagick.cmake b/Modules/FindImageMagick.cmake
new file mode 100644
index 000000000..f21b63008
--- /dev/null
+++ b/Modules/FindImageMagick.cmake
@@ -0,0 +1,237 @@
+# - 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
+#
+# If no component is specified in the FIND_PACKAGE call, then it only
+# 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_VERSION_STRING will not work for old versions like 5.2.3.
+#
+# There are also components for the following ImageMagick APIs:
+#
+# 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.
+#
+# 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.).
+
+#=============================================================================
+# Copyright 2007-2009 Kitware, Inc.
+# Copyright 2007-2008 Miguel A. Figueroa-Villanueva <miguelf at ieee dot org>
+# Copyright 2012 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.)
+
+#---------------------------------------------------------------------
+# Helper functions
+#---------------------------------------------------------------------
+FUNCTION(FIND_IMAGEMAGICK_API component header)
+ SET(ImageMagick_${component}_FOUND FALSE PARENT_SCOPE)
+
+ FIND_PATH(ImageMagick_${component}_INCLUDE_DIR
+ NAMES ${header}
+ PATHS
+ ${ImageMagick_INCLUDE_DIRS}
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\ImageMagick\\Current;BinPath]/include"
+ PATH_SUFFIXES
+ ImageMagick
+ DOC "Path to the ImageMagick include dir."
+ )
+ FIND_LIBRARY(ImageMagick_${component}_LIBRARY
+ NAMES ${ARGN}
+ PATHS
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\ImageMagick\\Current;BinPath]/lib"
+ DOC "Path to the ImageMagick Magick++ library."
+ )
+
+ IF(ImageMagick_${component}_INCLUDE_DIR AND ImageMagick_${component}_LIBRARY)
+ SET(ImageMagick_${component}_FOUND TRUE PARENT_SCOPE)
+
+ LIST(APPEND ImageMagick_INCLUDE_DIRS
+ ${ImageMagick_${component}_INCLUDE_DIR}
+ )
+ LIST(REMOVE_DUPLICATES ImageMagick_INCLUDE_DIRS)
+ SET(ImageMagick_INCLUDE_DIRS ${ImageMagick_INCLUDE_DIRS} PARENT_SCOPE)
+
+ LIST(APPEND ImageMagick_LIBRARIES
+ ${ImageMagick_${component}_LIBRARY}
+ )
+ SET(ImageMagick_LIBRARIES ${ImageMagick_LIBRARIES} PARENT_SCOPE)
+ ENDIF(ImageMagick_${component}_INCLUDE_DIR AND ImageMagick_${component}_LIBRARY)
+ENDFUNCTION(FIND_IMAGEMAGICK_API)
+
+FUNCTION(FIND_IMAGEMAGICK_EXE component)
+ SET(_IMAGEMAGICK_EXECUTABLE
+ ${ImageMagick_EXECUTABLE_DIR}/${component}${CMAKE_EXECUTABLE_SUFFIX})
+ IF(EXISTS ${_IMAGEMAGICK_EXECUTABLE})
+ SET(ImageMagick_${component}_EXECUTABLE
+ ${_IMAGEMAGICK_EXECUTABLE}
+ PARENT_SCOPE
+ )
+ SET(ImageMagick_${component}_FOUND TRUE PARENT_SCOPE)
+ ELSE(EXISTS ${_IMAGEMAGICK_EXECUTABLE})
+ SET(ImageMagick_${component}_FOUND FALSE PARENT_SCOPE)
+ ENDIF(EXISTS ${_IMAGEMAGICK_EXECUTABLE})
+ENDFUNCTION(FIND_IMAGEMAGICK_EXE)
+
+#---------------------------------------------------------------------
+# Start Actual Work
+#---------------------------------------------------------------------
+# Try to find a ImageMagick installation binary path.
+FIND_PATH(ImageMagick_EXECUTABLE_DIR
+ NAMES mogrify${CMAKE_EXECUTABLE_SUFFIX}
+ PATHS
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\ImageMagick\\Current;BinPath]"
+ DOC "Path to the ImageMagick binary directory."
+ NO_DEFAULT_PATH
+ )
+FIND_PATH(ImageMagick_EXECUTABLE_DIR
+ NAMES mogrify${CMAKE_EXECUTABLE_SUFFIX}
+ )
+
+# Find each component. Search for all tools in same dir
+# <ImageMagick_EXECUTABLE_DIR>; otherwise they should be found
+# independently and not in a cohesive module such as this one.
+UNSET(ImageMagick_REQUIRED_VARS)
+UNSET(ImageMagick_DEFAULT_EXECUTABLES)
+FOREACH(component ${ImageMagick_FIND_COMPONENTS}
+ # DEPRECATED: forced components for backward compatibility
+ convert mogrify import montage composite
+ )
+ IF(component STREQUAL "Magick++")
+ FIND_IMAGEMAGICK_API(Magick++ Magick++.h
+ Magick++ CORE_RL_Magick++_
+ )
+ LIST(APPEND ImageMagick_REQUIRED_VARS ImageMagick_Magick++_LIBRARY)
+ ELSEIF(component STREQUAL "MagickWand")
+ FIND_IMAGEMAGICK_API(MagickWand wand/MagickWand.h
+ Wand MagickWand CORE_RL_wand_
+ )
+ LIST(APPEND ImageMagick_REQUIRED_VARS ImageMagick_MagickWand_LIBRARY)
+ ELSEIF(component STREQUAL "MagickCore")
+ FIND_IMAGEMAGICK_API(MagickCore magick/MagickCore.h
+ Magick MagickCore CORE_RL_magick_
+ )
+ LIST(APPEND ImageMagick_REQUIRED_VARS ImageMagick_MagickCore_LIBRARY)
+ ELSE(component STREQUAL "Magick++")
+ IF(ImageMagick_EXECUTABLE_DIR)
+ FIND_IMAGEMAGICK_EXE(${component})
+ ENDIF(ImageMagick_EXECUTABLE_DIR)
+
+ IF(ImageMagick_FIND_COMPONENTS)
+ LIST(FIND ImageMagick_FIND_COMPONENTS ${component} is_requested)
+ IF(is_requested GREATER -1)
+ LIST(APPEND ImageMagick_REQUIRED_VARS ImageMagick_${component}_EXECUTABLE)
+ ENDIF(is_requested GREATER -1)
+ ELSEIF(ImageMagick_${component}_EXECUTABLE)
+ # if no components were requested explicitly put all (default) executables
+ # in the list
+ LIST(APPEND ImageMagick_DEFAULT_EXECUTABLES ImageMagick_${component}_EXECUTABLE)
+ ENDIF(ImageMagick_FIND_COMPONENTS)
+ ENDIF(component STREQUAL "Magick++")
+ENDFOREACH(component)
+
+IF(NOT ImageMagick_FIND_COMPONENTS AND NOT ImageMagick_DEFAULT_EXECUTABLES)
+ # No components were requested, and none of the default components were
+ # found. Just insert mogrify into the list of the default components to
+ # find so FPHSA below has something to check
+ LIST(APPEND ImageMagick_REQUIRED_VARS ImageMagick_mogrify_EXECUTABLE)
+ELSEIF(ImageMagick_DEFAULT_EXECUTABLES)
+ LIST(APPEND ImageMagick_REQUIRED_VARS ${ImageMagick_DEFAULT_EXECUTABLES})
+ENDIF()
+
+SET(ImageMagick_INCLUDE_DIRS ${ImageMagick_INCLUDE_DIRS})
+SET(ImageMagick_LIBRARIES ${ImageMagick_LIBRARIES})
+
+IF(ImageMagick_mogrify_EXECUTABLE)
+ EXECUTE_PROCESS(COMMAND ${ImageMagick_mogrify_EXECUTABLE} -version
+ 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}")
+ ENDIF()
+ UNSET(imagemagick_version)
+ENDIF(ImageMagick_mogrify_EXECUTABLE)
+
+#---------------------------------------------------------------------
+# Standard Package Output
+#---------------------------------------------------------------------
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(ImageMagick
+ REQUIRED_VARS ${ImageMagick_REQUIRED_VARS}
+ VERSION_VAR ImageMagick_VERSION_STRING
+ )
+# Maintain consistency with all other variables.
+SET(ImageMagick_FOUND ${IMAGEMAGICK_FOUND})
+
+#---------------------------------------------------------------------
+# DEPRECATED: Setting variables for backward compatibility.
+#---------------------------------------------------------------------
+SET(IMAGEMAGICK_BINARY_PATH ${ImageMagick_EXECUTABLE_DIR}
+ CACHE PATH "Path to the ImageMagick binary directory.")
+SET(IMAGEMAGICK_CONVERT_EXECUTABLE ${ImageMagick_convert_EXECUTABLE}
+ CACHE FILEPATH "Path to ImageMagick's convert executable.")
+SET(IMAGEMAGICK_MOGRIFY_EXECUTABLE ${ImageMagick_mogrify_EXECUTABLE}
+ CACHE FILEPATH "Path to ImageMagick's mogrify executable.")
+SET(IMAGEMAGICK_IMPORT_EXECUTABLE ${ImageMagick_import_EXECUTABLE}
+ CACHE FILEPATH "Path to ImageMagick's import executable.")
+SET(IMAGEMAGICK_MONTAGE_EXECUTABLE ${ImageMagick_montage_EXECUTABLE}
+ CACHE FILEPATH "Path to ImageMagick's montage executable.")
+SET(IMAGEMAGICK_COMPOSITE_EXECUTABLE ${ImageMagick_composite_EXECUTABLE}
+ CACHE FILEPATH "Path to ImageMagick's composite executable.")
+MARK_AS_ADVANCED(
+ IMAGEMAGICK_BINARY_PATH
+ IMAGEMAGICK_CONVERT_EXECUTABLE
+ IMAGEMAGICK_MOGRIFY_EXECUTABLE
+ IMAGEMAGICK_IMPORT_EXECUTABLE
+ IMAGEMAGICK_MONTAGE_EXECUTABLE
+ IMAGEMAGICK_COMPOSITE_EXECUTABLE
+ )
diff --git a/Modules/FindJNI.cmake b/Modules/FindJNI.cmake
new file mode 100644
index 000000000..d49b44a55
--- /dev/null
+++ b/Modules/FindJNI.cmake
@@ -0,0 +1,261 @@
+# - 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:
+#
+# 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.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software 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.)
+
+# Expand {libarch} occurences to java_libarch subdirectory(-ies) and set ${_var}
+MACRO(java_append_library_directories _var)
+ # Determine java arch-specific library subdir
+ # Mostly based on openjdk/jdk/make/common/shared/Platform.gmk as of openjdk
+ # 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")
+ ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES "^i.86$")
+ SET(_java_libarch "i386")
+ ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES "^alpha")
+ SET(_java_libarch "alpha")
+ ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm")
+ # Subdir is "arm" for both big-endian (arm) and little-endian (armel).
+ SET(_java_libarch "arm")
+ 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")
+ ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)64")
+ SET(_java_libarch "ppc64")
+ ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)")
+ SET(_java_libarch "ppc")
+ ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES "^sparc")
+ # Both flavours can run on the same processor
+ SET(_java_libarch "${CMAKE_SYSTEM_PROCESSOR}" "sparc" "sparcv9")
+ ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES "^(parisc|hppa)")
+ SET(_java_libarch "parisc" "parisc64")
+ ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES "^s390")
+ # s390 binaries can run on s390x machines
+ SET(_java_libarch "${CMAKE_SYSTEM_PROCESSOR}" "s390" "s390x")
+ ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES "^sh")
+ SET(_java_libarch "sh")
+ ELSE(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
+ SET(_java_libarch "${CMAKE_SYSTEM_PROCESSOR}")
+ ENDIF(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
+
+ # Append default list architectures if CMAKE_SYSTEM_PROCESSOR was empty or
+ # system is non-Linux (where the code above has not been well tested)
+ IF(NOT _java_libarch OR NOT (CMAKE_SYSTEM_NAME MATCHES "Linux"))
+ LIST(APPEND _java_libarch "i386" "amd64" "ppc")
+ ENDIF(NOT _java_libarch OR NOT (CMAKE_SYSTEM_NAME MATCHES "Linux"))
+
+ # Sometimes ${CMAKE_SYSTEM_PROCESSOR} is added to the list to prefer
+ # current value to a hardcoded list. Remove possible duplicates.
+ LIST(REMOVE_DUPLICATES _java_libarch)
+
+ FOREACH(_path ${ARGN})
+ IF(_path MATCHES "{libarch}")
+ FOREACH(_libarch ${_java_libarch})
+ STRING(REPLACE "{libarch}" "${_libarch}" _newpath "${_path}")
+ LIST(APPEND ${_var} "${_newpath}")
+ ENDFOREACH(_libarch)
+ ELSE(_path MATCHES "{libarch}")
+ LIST(APPEND ${_var} "${_path}")
+ ENDIF(_path MATCHES "{libarch}")
+ ENDFOREACH(_path)
+ENDMACRO(java_append_library_directories)
+
+GET_FILENAME_COMPONENT(java_install_version
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit;CurrentVersion]" NAME)
+
+SET(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
+ /usr/lib/java/jre/lib/{libarch}
+ /usr/lib/jvm/jre/lib/{libarch}
+ /usr/local/lib/java/jre/lib/{libarch}
+ /usr/local/share/java/jre/lib/{libarch}
+ /usr/lib/j2sdk1.4-sun/jre/lib/{libarch}
+ /usr/lib/j2sdk1.5-sun/jre/lib/{libarch}
+ /opt/sun-jdk-1.5.0.04/jre/lib/{libarch}
+ /usr/lib/jvm/java-6-sun/jre/lib/{libarch}
+ /usr/lib/jvm/java-1.5.0-sun/jre/lib/{libarch}
+ /usr/lib/jvm/java-6-sun-1.6.0.00/jre/lib/{libarch} # can this one be removed according to #8821 ? Alex
+ /usr/lib/jvm/java-6-openjdk/jre/lib/{libarch}
+ /usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0/jre/lib/{libarch} # fedora
+ # Debian specific paths for default JVM
+ /usr/lib/jvm/default-java/jre/lib/{libarch}
+ /usr/lib/jvm/default-java/jre/lib
+ /usr/lib/jvm/default-java/lib
+ )
+
+SET(JAVA_JVM_LIBRARY_DIRECTORIES)
+FOREACH(dir ${JAVA_AWT_LIBRARY_DIRECTORIES})
+ SET(JAVA_JVM_LIBRARY_DIRECTORIES
+ ${JAVA_JVM_LIBRARY_DIRECTORIES}
+ "${dir}"
+ "${dir}/client"
+ "${dir}/server"
+ )
+ENDFOREACH(dir)
+
+
+SET(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
+ /usr/local/lib/java/include
+ /usr/lib/jvm/java/include
+ /usr/lib/jvm/java-6-sun/include
+ /usr/lib/jvm/java-1.5.0-sun/include
+ /usr/lib/jvm/java-6-sun-1.6.0.00/include # can this one be removed according to #8821 ? Alex
+ /usr/lib/jvm/java-6-openjdk/include
+ /usr/local/share/java/include
+ /usr/lib/j2sdk1.4-sun/include
+ /usr/lib/j2sdk1.5-sun/include
+ /opt/sun-jdk-1.5.0.04/include
+ # Debian specific path for default JVM
+ /usr/lib/jvm/default-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}")
+ ENDIF(EXISTS ${jpath}/${JAVA_INC_PATH})
+ ENDFOREACH(JAVA_INC_PATH)
+ FOREACH(JAVA_LIB_PATH
+ ../lib ../jre/lib ../jre/lib/i386
+ ../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}")
+ ENDIF(EXISTS ${jpath}/${JAVA_LIB_PATH})
+ ENDFOREACH(JAVA_LIB_PATH)
+ENDFOREACH(JAVA_PROG)
+
+IF(APPLE)
+ IF(EXISTS ~/Library/Frameworks/JavaVM.framework)
+ SET(JAVA_HAVE_FRAMEWORK 1)
+ ENDIF(EXISTS ~/Library/Frameworks/JavaVM.framework)
+ IF(EXISTS /Library/Frameworks/JavaVM.framework)
+ SET(JAVA_HAVE_FRAMEWORK 1)
+ ENDIF(EXISTS /Library/Frameworks/JavaVM.framework)
+ IF(EXISTS /System/Library/Frameworks/JavaVM.framework)
+ SET(JAVA_HAVE_FRAMEWORK 1)
+ ENDIF(EXISTS /System/Library/Frameworks/JavaVM.framework)
+
+ IF(JAVA_HAVE_FRAMEWORK)
+ IF(NOT JAVA_AWT_LIBRARY)
+ SET (JAVA_AWT_LIBRARY "-framework JavaVM" CACHE FILEPATH "Java Frameworks" FORCE)
+ ENDIF(NOT JAVA_AWT_LIBRARY)
+
+ IF(NOT JAVA_JVM_LIBRARY)
+ SET (JAVA_JVM_LIBRARY "-framework JavaVM" CACHE FILEPATH "Java Frameworks" FORCE)
+ ENDIF(NOT JAVA_JVM_LIBRARY)
+
+ 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(EXISTS /System/Library/Frameworks/JavaVM.framework/Headers/jawt.h)
+ ENDIF(NOT JAVA_AWT_INCLUDE_PATH)
+
+ # 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}
+ )
+ ENDIF(JAVA_HAVE_FRAMEWORK)
+ELSE(APPLE)
+ FIND_LIBRARY(JAVA_AWT_LIBRARY jawt
+ PATHS ${JAVA_AWT_LIBRARY_DIRECTORIES}
+ )
+ FIND_LIBRARY(JAVA_JVM_LIBRARY NAMES jvm JavaVM
+ PATHS ${JAVA_JVM_LIBRARY_DIRECTORIES}
+ )
+ENDIF(APPLE)
+
+# add in the include path
+FIND_PATH(JAVA_INCLUDE_PATH jni.h
+ ${JAVA_AWT_INCLUDE_DIRECTORIES}
+)
+
+FIND_PATH(JAVA_INCLUDE_PATH2 jni_md.h
+ ${JAVA_INCLUDE_PATH}
+ ${JAVA_INCLUDE_PATH}/win32
+ ${JAVA_INCLUDE_PATH}/linux
+ ${JAVA_INCLUDE_PATH}/freebsd
+ ${JAVA_INCLUDE_PATH}/solaris
+ ${JAVA_INCLUDE_PATH}/hp-ux
+ ${JAVA_INCLUDE_PATH}/alpha
+)
+
+FIND_PATH(JAVA_AWT_INCLUDE_PATH jawt.h
+ ${JAVA_INCLUDE_PATH}
+)
+
+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)
+
+MARK_AS_ADVANCED(
+ JAVA_AWT_LIBRARY
+ JAVA_JVM_LIBRARY
+ JAVA_AWT_INCLUDE_PATH
+ JAVA_INCLUDE_PATH
+ JAVA_INCLUDE_PATH2
+)
+
+SET(JNI_LIBRARIES
+ ${JAVA_AWT_LIBRARY}
+ ${JAVA_JVM_LIBRARY}
+)
+
+SET(JNI_INCLUDE_DIRS
+ ${JAVA_INCLUDE_PATH}
+ ${JAVA_INCLUDE_PATH2}
+ ${JAVA_AWT_INCLUDE_PATH}
+)
+
diff --git a/Modules/FindJPEG.cmake b/Modules/FindJPEG.cmake
new file mode 100644
index 000000000..349e7e175
--- /dev/null
+++ b/Modules/FindJPEG.cmake
@@ -0,0 +1,43 @@
+# - 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.
+
+#=============================================================================
+# 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.)
+
+FIND_PATH(JPEG_INCLUDE_DIR jpeglib.h)
+
+SET(JPEG_NAMES ${JPEG_NAMES} jpeg)
+FIND_LIBRARY(JPEG_LIBRARY NAMES ${JPEG_NAMES} )
+
+# handle the QUIETLY and REQUIRED arguments and set JPEG_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(JPEG DEFAULT_MSG JPEG_LIBRARY JPEG_INCLUDE_DIR)
+
+IF(JPEG_FOUND)
+ SET(JPEG_LIBRARIES ${JPEG_LIBRARY})
+ENDIF(JPEG_FOUND)
+
+# Deprecated declarations.
+SET (NATIVE_JPEG_INCLUDE_PATH ${JPEG_INCLUDE_DIR} )
+IF(JPEG_LIBRARY)
+ GET_FILENAME_COMPONENT (NATIVE_JPEG_LIB_PATH ${JPEG_LIBRARY} PATH)
+ENDIF(JPEG_LIBRARY)
+
+MARK_AS_ADVANCED(JPEG_LIBRARY JPEG_INCLUDE_DIR )
diff --git a/Modules/FindJasper.cmake b/Modules/FindJasper.cmake
new file mode 100644
index 000000000..6dc7e4db7
--- /dev/null
+++ b/Modules/FindJasper.cmake
@@ -0,0 +1,53 @@
+# - 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)
+
+#=============================================================================
+# Copyright 2006-2009 Kitware, Inc.
+# Copyright 2006 Alexander Neundorf <neundorf@kde.org>
+# Copyright 2012 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.)
+
+FIND_PATH(JASPER_INCLUDE_DIR jasper/jasper.h)
+
+IF (NOT JASPER_LIBRARIES)
+ FIND_PACKAGE(JPEG)
+
+ FIND_LIBRARY(JASPER_LIBRARY_RELEASE NAMES jasper libjasper)
+ FIND_LIBRARY(JASPER_LIBRARY_DEBUG NAMES jasperd)
+
+ INCLUDE(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
+ SELECT_LIBRARY_CONFIGURATIONS(JASPER)
+ENDIF (NOT JASPER_LIBRARIES)
+
+IF (JASPER_INCLUDE_DIR AND EXISTS "${JASPER_INCLUDE_DIR}/jasper/jas_config.h")
+ FILE(STRINGS "${JASPER_INCLUDE_DIR}/jasper/jas_config.h" jasper_version_str REGEX "^#define[\t ]+JAS_VERSION[\t ]+\".*\".*")
+
+ STRING(REGEX REPLACE "^#define[\t ]+JAS_VERSION[\t ]+\"([^\"]+)\".*" "\\1" JASPER_VERSION_STRING "${jasper_version_str}")
+ENDIF (JASPER_INCLUDE_DIR AND EXISTS "${JASPER_INCLUDE_DIR}/jasper/jas_config.h")
+
+# handle the QUIETLY and REQUIRED arguments and set JASPER_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Jasper
+ REQUIRED_VARS JASPER_LIBRARIES JASPER_INCLUDE_DIR JPEG_LIBRARIES
+ VERSION_VAR JASPER_VERSION_STRING)
+
+IF (JASPER_FOUND)
+ SET(JASPER_LIBRARIES ${JASPER_LIBRARIES} ${JPEG_LIBRARIES} )
+ENDIF (JASPER_FOUND)
+
+MARK_AS_ADVANCED(JASPER_INCLUDE_DIR)
diff --git a/Modules/FindJava.cmake b/Modules/FindJava.cmake
new file mode 100644
index 000000000..345702122
--- /dev/null
+++ b/Modules/FindJava.cmake
@@ -0,0 +1,204 @@
+# - 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)
+#
+# The minimum required version of Java can be specified using the
+# 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
+#
+# 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.
+#
+# Example Usages:
+# FIND_PACKAGE(Java)
+# FIND_PACKAGE(Java COMPONENTS Runtime)
+# FIND_PACKAGE(Java COMPONENTS Development)
+#
+
+#=============================================================================
+# Copyright 2002-2009 Kitware, Inc.
+# Copyright 2009-2011 Mathieu Malaterre <mathieu.malaterre@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.)
+
+# The HINTS option should only be used for values computed from the system.
+SET(_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"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.7;JavaHome]/bin"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.6;JavaHome]/bin"
+ "[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.
+SET(_JAVA_PATHS
+ /usr/lib/java/bin
+ /usr/share/java/bin
+ /usr/local/java/bin
+ /usr/local/java/share/bin
+ /usr/java/j2sdk1.4.2_04
+ /usr/lib/j2sdk1.4-sun/bin
+ /usr/java/j2sdk1.4.2_09/bin
+ /usr/lib/j2sdk1.5-sun/bin
+ /opt/sun-jdk-1.5.0.04/bin
+ )
+FIND_PROGRAM(Java_JAVA_EXECUTABLE
+ NAMES java
+ HINTS ${_JAVA_HINTS}
+ PATHS ${_JAVA_PATHS}
+)
+
+IF(Java_JAVA_EXECUTABLE)
+ EXECUTE_PROCESS(COMMAND ${Java_JAVA_EXECUTABLE} -version
+ RESULT_VARIABLE res
+ OUTPUT_VARIABLE var
+ ERROR_VARIABLE var # sun-java output to stderr
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_STRIP_TRAILING_WHITESPACE)
+ IF( res )
+ IF(${Java_FIND_REQUIRED})
+ MESSAGE( FATAL_ERROR "Error executing java -version" )
+ ELSE()
+ MESSAGE( STATUS "Warning, could not run java --version")
+ ENDIF()
+ ELSE()
+ # extract major/minor version and patch level from "java -version" output
+ # Tested on linux using
+ # 1. Sun / Sun OEM
+ # 2. OpenJDK 1.6
+ # 3. GCJ 1.5
+ # 4. Kaffe 1.4.2
+ 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_]+\".*")
+ # Kaffe style
+ STRING( REGEX REPLACE "java full version \"kaffe-([0-9]+\\.[0-9]+\\.[0-9_]+).*"
+ "\\1" Java_VERSION_STRING "${var}" )
+ ELSE()
+ IF(NOT Java_FIND_QUIETLY)
+ message(WARNING "regex not supported: ${var}. Please report")
+ ENDIF(NOT Java_FIND_QUIETLY)
+ ENDIF()
+ STRING( REGEX REPLACE "([0-9]+).*" "\\1" Java_VERSION_MAJOR "${Java_VERSION_STRING}" )
+ STRING( REGEX REPLACE "[0-9]+\\.([0-9]+).*" "\\1" Java_VERSION_MINOR "${Java_VERSION_STRING}" )
+ STRING( REGEX REPLACE "[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" Java_VERSION_PATCH "${Java_VERSION_STRING}" )
+ # warning tweak version can be empty:
+ STRING( REGEX REPLACE "[0-9]+\\.[0-9]+\\.[0-9]+[_\\.]?([0-9]*).*$" "\\1" Java_VERSION_TWEAK "${Java_VERSION_STRING}" )
+ if( Java_VERSION_TWEAK STREQUAL "" ) # check case where tweak is not defined
+ set(Java_VERSION ${Java_VERSION_MAJOR}.${Java_VERSION_MINOR}.${Java_VERSION_PATCH})
+ else( )
+ set(Java_VERSION ${Java_VERSION_MAJOR}.${Java_VERSION_MINOR}.${Java_VERSION_PATCH}.${Java_VERSION_TWEAK})
+ endif( )
+ ENDIF()
+
+ENDIF(Java_JAVA_EXECUTABLE)
+
+
+FIND_PROGRAM(Java_JAR_EXECUTABLE
+ NAMES jar
+ HINTS ${_JAVA_HINTS}
+ PATHS ${_JAVA_PATHS}
+)
+
+FIND_PROGRAM(Java_JAVAC_EXECUTABLE
+ NAMES javac
+ HINTS ${_JAVA_HINTS}
+ PATHS ${_JAVA_PATHS}
+)
+
+FIND_PROGRAM(Java_JAVAH_EXECUTABLE
+ NAMES javah
+ HINTS ${_JAVA_HINTS}
+ PATHS ${_JAVA_PATHS}
+)
+
+FIND_PROGRAM(Java_JAVADOC_EXECUTABLE
+ NAMES javadoc
+ HINTS ${_JAVA_HINTS}
+ PATHS ${_JAVA_PATHS}
+)
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+if(Java_FIND_COMPONENTS)
+ 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
+ )
+ 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
+ )
+ else()
+ message(FATAL_ERROR "Comp: ${component} is not handled")
+ endif()
+ set(Java_${component}_FOUND TRUE)
+ endforeach(component)
+else()
+ # Check for everything
+ 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
+ )
+endif()
+
+
+MARK_AS_ADVANCED(
+ Java_JAVA_EXECUTABLE
+ Java_JAR_EXECUTABLE
+ Java_JAVAC_EXECUTABLE
+ Java_JAVAH_EXECUTABLE
+ Java_JAVADOC_EXECUTABLE
+ )
+
+# LEGACY
+SET(JAVA_RUNTIME ${Java_JAVA_EXECUTABLE})
+SET(JAVA_ARCHIVE ${Java_JAR_EXECUTABLE})
+SET(JAVA_COMPILE ${Java_JAVAC_EXECUTABLE})
+
diff --git a/Modules/FindKDE3.cmake b/Modules/FindKDE3.cmake
new file mode 100644
index 000000000..9d1081405
--- /dev/null
+++ b/Modules/FindKDE3.cmake
@@ -0,0 +1,299 @@
+# - 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
+#
+# The following user adjustable options are provided:
+#
+# 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.
+#
+# 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.
+#
+# 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.
+#
+#
+# Author: Alexander Neundorf <neundorf@kde.org>
+
+#=============================================================================
+# Copyright 2006-2009 Kitware, Inc.
+# Copyright 2006 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.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+IF(NOT UNIX AND KDE3_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR "Compiling KDE3 applications and libraries under Windows is not supported")
+ENDIF(NOT UNIX AND KDE3_FIND_REQUIRED)
+
+# If Qt4 has already been found, fail.
+IF(QT4_FOUND)
+ IF(KDE3_FIND_REQUIRED)
+ MESSAGE( FATAL_ERROR "KDE3/Qt3 and Qt4 cannot be used together in one project.")
+ ELSE(KDE3_FIND_REQUIRED)
+ IF(NOT KDE3_FIND_QUIETLY)
+ MESSAGE( STATUS "KDE3/Qt3 and Qt4 cannot be used together in one project.")
+ ENDIF(NOT KDE3_FIND_QUIETLY)
+ RETURN()
+ ENDIF(KDE3_FIND_REQUIRED)
+ENDIF(QT4_FOUND)
+
+
+SET(QT_MT_REQUIRED TRUE)
+#SET(QT_MIN_VERSION "3.0.0")
+
+#this line includes FindQt.cmake, which searches the Qt library and headers
+IF(KDE3_FIND_REQUIRED)
+ SET(_REQ_STRING_KDE3 "REQUIRED")
+ENDIF(KDE3_FIND_REQUIRED)
+
+FIND_PACKAGE(Qt3 ${_REQ_STRING_KDE3})
+FIND_PACKAGE(X11 ${_REQ_STRING_KDE3})
+
+
+#now try to find some kde stuff
+FIND_PROGRAM(KDECONFIG_EXECUTABLE NAMES kde-config
+ HINTS
+ $ENV{KDEDIR}/bin
+ PATHS
+ /opt/kde3/bin
+ /opt/kde/bin
+ )
+
+SET(KDE3PREFIX)
+IF(KDECONFIG_EXECUTABLE)
+ EXECUTE_PROCESS(COMMAND ${KDECONFIG_EXECUTABLE} --version
+ OUTPUT_VARIABLE kde_config_version )
+
+ STRING(REGEX MATCH "KDE: .\\." kde_version "${kde_config_version}")
+ IF ("${kde_version}" MATCHES "KDE: 3\\.")
+ EXECUTE_PROCESS(COMMAND ${KDECONFIG_EXECUTABLE} --prefix
+ OUTPUT_VARIABLE kdedir )
+ STRING(REGEX REPLACE "\n" "" KDE3PREFIX "${kdedir}")
+
+ ENDIF ("${kde_version}" MATCHES "KDE: 3\\.")
+ENDIF(KDECONFIG_EXECUTABLE)
+
+
+
+# at first the KDE include direcory
+# kpassdlg.h comes from kdeui and doesn't exist in KDE4 anymore
+FIND_PATH(KDE3_INCLUDE_DIR kpassdlg.h
+ HINTS
+ $ENV{KDEDIR}/include
+ ${KDE3PREFIX}/include
+ PATHS
+ /opt/kde3/include
+ /opt/kde/include
+ /usr/include/kde
+ /usr/local/include/kde
+ )
+
+#now the KDE library directory
+FIND_LIBRARY(KDE3_KDECORE_LIBRARY NAMES kdecore
+ HINTS
+ $ENV{KDEDIR}/lib
+ ${KDE3PREFIX}/lib
+ PATHS
+ /opt/kde3/lib
+ /opt/kde/lib
+)
+
+SET(QT_AND_KDECORE_LIBS ${QT_LIBRARIES} ${KDE3_KDECORE_LIBRARY})
+
+GET_FILENAME_COMPONENT(KDE3_LIB_DIR ${KDE3_KDECORE_LIBRARY} PATH )
+
+IF(NOT KDE3_LIBTOOL_DIR)
+ IF(KDE3_KDECORE_LIBRARY MATCHES lib64)
+ SET(KDE3_LIBTOOL_DIR /lib64/kde3)
+ ELSE(KDE3_KDECORE_LIBRARY MATCHES lib64)
+ SET(KDE3_LIBTOOL_DIR /lib/kde3)
+ ENDIF(KDE3_KDECORE_LIBRARY MATCHES lib64)
+ENDIF(NOT KDE3_LIBTOOL_DIR)
+
+#now search for the dcop utilities
+FIND_PROGRAM(KDE3_DCOPIDL_EXECUTABLE NAMES dcopidl
+ HINTS
+ $ENV{KDEDIR}/bin
+ ${KDE3PREFIX}/bin
+ PATHS
+ /opt/kde3/bin
+ /opt/kde/bin
+ )
+
+FIND_PROGRAM(KDE3_DCOPIDL2CPP_EXECUTABLE NAMES dcopidl2cpp
+ HINTS
+ $ENV{KDEDIR}/bin
+ ${KDE3PREFIX}/bin
+ PATHS
+ /opt/kde3/bin
+ /opt/kde/bin
+ )
+
+FIND_PROGRAM(KDE3_KCFGC_EXECUTABLE NAMES kconfig_compiler
+ HINTS
+ $ENV{KDEDIR}/bin
+ ${KDE3PREFIX}/bin
+ PATHS
+ /opt/kde3/bin
+ /opt/kde/bin
+ )
+
+
+#SET KDE3_FOUND
+IF (KDE3_INCLUDE_DIR AND KDE3_LIB_DIR AND KDE3_DCOPIDL_EXECUTABLE AND KDE3_DCOPIDL2CPP_EXECUTABLE AND KDE3_KCFGC_EXECUTABLE)
+ SET(KDE3_FOUND TRUE)
+ELSE (KDE3_INCLUDE_DIR AND KDE3_LIB_DIR AND KDE3_DCOPIDL_EXECUTABLE AND KDE3_DCOPIDL2CPP_EXECUTABLE AND KDE3_KCFGC_EXECUTABLE)
+ SET(KDE3_FOUND FALSE)
+ENDIF (KDE3_INCLUDE_DIR AND KDE3_LIB_DIR AND KDE3_DCOPIDL_EXECUTABLE AND KDE3_DCOPIDL2CPP_EXECUTABLE AND KDE3_KCFGC_EXECUTABLE)
+
+# add some KDE specific stuff
+SET(KDE3_DEFINITIONS -DQT_CLEAN_NAMESPACE -D_GNU_SOURCE)
+
+# set compiler flags only if KDE3 has actually been found
+IF(KDE3_FOUND)
+ SET(_KDE3_USE_FLAGS FALSE)
+ IF(CMAKE_COMPILER_IS_GNUCXX)
+ SET(_KDE3_USE_FLAGS TRUE) # use flags for gnu compiler
+ EXECUTE_PROCESS(COMMAND ${CMAKE_CXX_COMPILER} --version
+ OUTPUT_VARIABLE out)
+ # gnu gcc 2.96 does not work with flags
+ # I guess 2.95 also doesn't then
+ IF("${out}" MATCHES "2.9[56]")
+ SET(_KDE3_USE_FLAGS FALSE)
+ ENDIF("${out}" MATCHES "2.9[56]")
+ ENDIF(CMAKE_COMPILER_IS_GNUCXX)
+
+ #only on linux, but NOT e.g. on FreeBSD:
+ IF(CMAKE_SYSTEM_NAME MATCHES "Linux" AND _KDE3_USE_FLAGS)
+ SET (KDE3_DEFINITIONS ${KDE3_DEFINITIONS} -D_XOPEN_SOURCE=500 -D_BSD_SOURCE)
+ SET ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-long-long -ansi -Wundef -Wcast-align -Wconversion -Wchar-subscripts -Wall -W -Wpointer-arith -Wwrite-strings -Wformat-security -Wmissing-format-attribute -fno-common")
+ SET ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wnon-virtual-dtor -Wno-long-long -ansi -Wundef -Wcast-align -Wconversion -Wchar-subscripts -Wall -W -Wpointer-arith -Wwrite-strings -Wformat-security -fno-exceptions -fno-check-new -fno-common")
+ ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux" AND _KDE3_USE_FLAGS)
+
+ # works on FreeBSD, NOT tested on NetBSD and OpenBSD
+ IF (CMAKE_SYSTEM_NAME MATCHES BSD AND _KDE3_USE_FLAGS)
+ SET ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-long-long -ansi -Wundef -Wcast-align -Wconversion -Wchar-subscripts -Wall -W -Wpointer-arith -Wwrite-strings -Wformat-security -Wmissing-format-attribute -fno-common")
+ SET ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wnon-virtual-dtor -Wno-long-long -Wundef -Wcast-align -Wconversion -Wchar-subscripts -Wall -W -Wpointer-arith -Wwrite-strings -Wformat-security -Wmissing-format-attribute -fno-exceptions -fno-check-new -fno-common")
+ ENDIF (CMAKE_SYSTEM_NAME MATCHES BSD AND _KDE3_USE_FLAGS)
+
+ # if no special buildtype is selected, add -O2 as default optimization
+ IF (NOT CMAKE_BUILD_TYPE AND _KDE3_USE_FLAGS)
+ SET ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2")
+ SET ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2")
+ ENDIF (NOT CMAKE_BUILD_TYPE AND _KDE3_USE_FLAGS)
+
+#SET(CMAKE_SHARED_LINKER_FLAGS "-avoid-version -module -Wl,--no-undefined -Wl,--allow-shlib-undefined")
+#SET(CMAKE_SHARED_LINKER_FLAGS "-Wl,--fatal-warnings -avoid-version -Wl,--no-undefined -lc")
+#SET(CMAKE_MODULE_LINKER_FLAGS "-Wl,--fatal-warnings -avoid-version -Wl,--no-undefined -lc")
+ENDIF(KDE3_FOUND)
+
+
+# KDE3Macros.cmake contains all the KDE specific macros
+INCLUDE(KDE3Macros)
+
+
+MACRO (KDE3_PRINT_RESULTS)
+ IF(KDE3_INCLUDE_DIR)
+ MESSAGE(STATUS "Found KDE3 include dir: ${KDE3_INCLUDE_DIR}")
+ ELSE(KDE3_INCLUDE_DIR)
+ MESSAGE(STATUS "Didn't find KDE3 headers")
+ ENDIF(KDE3_INCLUDE_DIR)
+
+ IF(KDE3_LIB_DIR)
+ MESSAGE(STATUS "Found KDE3 library dir: ${KDE3_LIB_DIR}")
+ ELSE(KDE3_LIB_DIR)
+ MESSAGE(STATUS "Didn't find KDE3 core library")
+ ENDIF(KDE3_LIB_DIR)
+
+ IF(KDE3_DCOPIDL_EXECUTABLE)
+ MESSAGE(STATUS "Found KDE3 dcopidl preprocessor: ${KDE3_DCOPIDL_EXECUTABLE}")
+ ELSE(KDE3_DCOPIDL_EXECUTABLE)
+ MESSAGE(STATUS "Didn't find the KDE3 dcopidl preprocessor")
+ ENDIF(KDE3_DCOPIDL_EXECUTABLE)
+
+ IF(KDE3_DCOPIDL2CPP_EXECUTABLE)
+ MESSAGE(STATUS "Found KDE3 dcopidl2cpp preprocessor: ${KDE3_DCOPIDL2CPP_EXECUTABLE}")
+ ELSE(KDE3_DCOPIDL2CPP_EXECUTABLE)
+ MESSAGE(STATUS "Didn't find the KDE3 dcopidl2cpp preprocessor")
+ ENDIF(KDE3_DCOPIDL2CPP_EXECUTABLE)
+
+ IF(KDE3_KCFGC_EXECUTABLE)
+ MESSAGE(STATUS "Found KDE3 kconfig_compiler preprocessor: ${KDE3_KCFGC_EXECUTABLE}")
+ ELSE(KDE3_KCFGC_EXECUTABLE)
+ MESSAGE(STATUS "Didn't find the KDE3 kconfig_compiler preprocessor")
+ ENDIF(KDE3_KCFGC_EXECUTABLE)
+
+ENDMACRO (KDE3_PRINT_RESULTS)
+
+
+IF (KDE3_FIND_REQUIRED AND NOT KDE3_FOUND)
+ #bail out if something wasn't found
+ KDE3_PRINT_RESULTS()
+ MESSAGE(FATAL_ERROR "Could NOT find everything required for compiling KDE 3 programs")
+
+ENDIF (KDE3_FIND_REQUIRED AND NOT KDE3_FOUND)
+
+
+IF (NOT KDE3_FIND_QUIETLY)
+ KDE3_PRINT_RESULTS()
+ENDIF (NOT KDE3_FIND_QUIETLY)
+
+#add the found Qt and KDE include directories to the current include path
+SET(KDE3_INCLUDE_DIRS ${QT_INCLUDE_DIR} ${KDE3_INCLUDE_DIR})
+
diff --git a/Modules/FindKDE4.cmake b/Modules/FindKDE4.cmake
new file mode 100644
index 000000000..ed4f270b0
--- /dev/null
+++ b/Modules/FindKDE4.cmake
@@ -0,0 +1,100 @@
+# 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>
+
+#=============================================================================
+# Copyright 2006-2009 Kitware, Inc.
+# Copyright 2006 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.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+# If Qt3 has already been found, fail.
+IF(QT_QT_LIBRARY)
+ IF(KDE4_FIND_REQUIRED)
+ MESSAGE( FATAL_ERROR "KDE4/Qt4 and Qt3 cannot be used together in one project.")
+ ELSE(KDE4_FIND_REQUIRED)
+ IF(NOT KDE4_FIND_QUIETLY)
+ MESSAGE( STATUS "KDE4/Qt4 and Qt3 cannot be used together in one project.")
+ ENDIF(NOT KDE4_FIND_QUIETLY)
+ RETURN()
+ ENDIF(KDE4_FIND_REQUIRED)
+ENDIF(QT_QT_LIBRARY)
+
+FILE(TO_CMAKE_PATH "$ENV{KDEDIRS}" _KDEDIRS)
+
+# when cross compiling, searching kde4-config in order to run it later on
+# doesn't make a lot of sense. We'll have to do something about this.
+# Searching always in the target environment ? Then we get at least the correct one,
+# still it can't be used to run it. Alex
+
+# For KDE4 kde-config has been renamed to kde4-config
+FIND_PROGRAM(KDE4_KDECONFIG_EXECUTABLE NAMES kde4-config
+ # the suffix must be used since KDEDIRS can be a list of directories which don't have bin/ appended
+ PATH_SUFFIXES bin
+ HINTS
+ ${CMAKE_INSTALL_PREFIX}
+ ${_KDEDIRS}
+ /opt/kde4
+ ONLY_CMAKE_FIND_ROOT_PATH
+ )
+
+IF (NOT KDE4_KDECONFIG_EXECUTABLE)
+ IF (KDE4_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR "ERROR: Could not find KDE4 kde4-config")
+ ENDIF (KDE4_FIND_REQUIRED)
+ENDIF (NOT KDE4_KDECONFIG_EXECUTABLE)
+
+
+# when cross compiling, KDE4_DATA_DIR may be already preset
+IF(NOT KDE4_DATA_DIR)
+ IF(CMAKE_CROSSCOMPILING)
+ # when cross compiling, don't run kde4-config but use its location as install dir
+ GET_FILENAME_COMPONENT(KDE4_DATA_DIR "${KDE4_KDECONFIG_EXECUTABLE}" PATH)
+ GET_FILENAME_COMPONENT(KDE4_DATA_DIR "${KDE4_DATA_DIR}" PATH)
+ ELSE(CMAKE_CROSSCOMPILING)
+ # then ask kde4-config for the kde data dirs
+
+ IF(KDE4_KDECONFIG_EXECUTABLE)
+ EXECUTE_PROCESS(COMMAND "${KDE4_KDECONFIG_EXECUTABLE}" --path data OUTPUT_VARIABLE _data_DIR ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
+ FILE(TO_CMAKE_PATH "${_data_DIR}" _data_DIR)
+ # then check the data dirs for FindKDE4Internal.cmake
+ FIND_PATH(KDE4_DATA_DIR cmake/modules/FindKDE4Internal.cmake HINTS ${_data_DIR})
+ ENDIF(KDE4_KDECONFIG_EXECUTABLE)
+ ENDIF(CMAKE_CROSSCOMPILING)
+ENDIF(NOT KDE4_DATA_DIR)
+
+# if it has been found...
+IF (KDE4_DATA_DIR)
+
+ SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${KDE4_DATA_DIR}/cmake/modules)
+
+ IF (KDE4_FIND_QUIETLY)
+ SET(_quiet QUIET)
+ ENDIF (KDE4_FIND_QUIETLY)
+
+ IF (KDE4_FIND_REQUIRED)
+ SET(_req REQUIRED)
+ ENDIF (KDE4_FIND_REQUIRED)
+
+ # use FindKDE4Internal.cmake to do the rest
+ FIND_PACKAGE(KDE4Internal ${_req} ${_quiet})
+ELSE (KDE4_DATA_DIR)
+ IF (KDE4_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR "ERROR: cmake/modules/FindKDE4Internal.cmake not found in ${_data_DIR}")
+ ENDIF (KDE4_FIND_REQUIRED)
+ENDIF (KDE4_DATA_DIR)
diff --git a/Modules/FindLAPACK.cmake b/Modules/FindLAPACK.cmake
new file mode 100644
index 000000000..0ae98dfa7
--- /dev/null
+++ b/Modules/FindLAPACK.cmake
@@ -0,0 +1,336 @@
+# - 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
+
+#=============================================================================
+# 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.)
+
+set(_lapack_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
+
+get_property(_LANGUAGES_ GLOBAL PROPERTY ENABLED_LANGUAGES)
+if (NOT _LANGUAGES_ MATCHES Fortran)
+include(CheckFunctionExists)
+else (NOT _LANGUAGES_ MATCHES Fortran)
+include(CheckFortranFunctionExists)
+endif (NOT _LANGUAGES_ MATCHES Fortran)
+
+set(LAPACK_FOUND FALSE)
+set(LAPACK95_FOUND FALSE)
+
+# TODO: move this stuff to separate module
+
+macro(Check_Lapack_Libraries LIBRARIES _prefix _name _flags _list _blas _threads)
+# This macro checks for the existence of the combination of fortran libraries
+# given by _list. If the combination is found, this macro checks (using the
+# Check_Fortran_Function_Exists macro) whether can link against that library
+# combination using the name of a routine given by _name using the linker
+# flags given by _flags. If the combination of libraries is found and passes
+# the link test, LIBRARIES is set to the list of complete library paths that
+# have been found. Otherwise, LIBRARIES is set to FALSE.
+
+# N.B. _prefix is the prefix applied to the names of all cached variables that
+# are generated internally and marked advanced by this macro.
+
+set(_libraries_work TRUE)
+set(${LIBRARIES})
+set(_combined_name)
+if (NOT _libdir)
+ if (WIN32)
+ set(_libdir ENV LIB)
+ elseif (APPLE)
+ set(_libdir /usr/local/lib /usr/lib /usr/local/lib64 /usr/lib64 ENV DYLD_LIBRARY_PATH)
+ else ()
+ set(_libdir /usr/local/lib /usr/lib /usr/local/lib64 /usr/lib64 ENV LD_LIBRARY_PATH)
+ endif ()
+endif ()
+foreach(_library ${_list})
+ set(_combined_name ${_combined_name}_${_library})
+
+ if(_libraries_work)
+ if (BLA_STATIC)
+ if (WIN32)
+ set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES})
+ endif ( WIN32 )
+ if (APPLE)
+ set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES})
+ else (APPLE)
+ set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
+ endif (APPLE)
+ else (BLA_STATIC)
+ if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ # for ubuntu's libblas3gf and liblapack3gf packages
+ set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES} .so.3gf)
+ endif ()
+ endif (BLA_STATIC)
+ find_library(${_prefix}_${_library}_LIBRARY
+ NAMES ${_library}
+ PATHS ${_libdir}
+ )
+ mark_as_advanced(${_prefix}_${_library}_LIBRARY)
+ set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY})
+ set(_libraries_work ${${_prefix}_${_library}_LIBRARY})
+ endif(_libraries_work)
+endforeach(_library ${_list})
+
+if(_libraries_work)
+ # Test this combination of libraries.
+ if(UNIX AND BLA_STATIC)
+ set(CMAKE_REQUIRED_LIBRARIES ${_flags} "-Wl,--start-group" ${${LIBRARIES}} ${_blas} "-Wl,--end-group" ${_threads})
+ else(UNIX AND BLA_STATIC)
+ set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}} ${_blas} ${_threads})
+ endif(UNIX AND BLA_STATIC)
+# message("DEBUG: CMAKE_REQUIRED_LIBRARIES = ${CMAKE_REQUIRED_LIBRARIES}")
+ if (NOT _LANGUAGES_ MATCHES Fortran)
+ check_function_exists("${_name}_" ${_prefix}${_combined_name}_WORKS)
+ else (NOT _LANGUAGES_ MATCHES Fortran)
+ check_fortran_function_exists(${_name} ${_prefix}${_combined_name}_WORKS)
+ endif (NOT _LANGUAGES_ MATCHES Fortran)
+ set(CMAKE_REQUIRED_LIBRARIES)
+ mark_as_advanced(${_prefix}${_combined_name}_WORKS)
+ set(_libraries_work ${${_prefix}${_combined_name}_WORKS})
+ #message("DEBUG: ${LIBRARIES} = ${${LIBRARIES}}")
+endif(_libraries_work)
+
+ if(_libraries_work)
+ set(${LIBRARIES} ${${LIBRARIES}} ${_blas} ${_threads})
+ else(_libraries_work)
+ set(${LIBRARIES} FALSE)
+ endif(_libraries_work)
+
+endmacro(Check_Lapack_Libraries)
+
+
+set(LAPACK_LINKER_FLAGS)
+set(LAPACK_LIBRARIES)
+set(LAPACK95_LIBRARIES)
+
+
+if(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED)
+ find_package(BLAS)
+else(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED)
+ find_package(BLAS REQUIRED)
+endif(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED)
+
+
+if(BLAS_FOUND)
+ set(LAPACK_LINKER_FLAGS ${BLAS_LINKER_FLAGS})
+ if ($ENV{BLA_VENDOR} MATCHES ".+")
+ set(BLA_VENDOR $ENV{BLA_VENDOR})
+ else ($ENV{BLA_VENDOR} MATCHES ".+")
+ if(NOT BLA_VENDOR)
+ set(BLA_VENDOR "All")
+ endif(NOT BLA_VENDOR)
+ endif ($ENV{BLA_VENDOR} MATCHES ".+")
+
+if (BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All")
+ if(NOT LAPACK_LIBRARIES)
+ check_lapack_libraries(
+ LAPACK_LIBRARIES
+ LAPACK
+ cheev
+ ""
+ "goto2"
+ "${BLAS_LIBRARIES}"
+ ""
+ )
+ endif(NOT LAPACK_LIBRARIES)
+endif (BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All")
+
+
+#acml lapack
+ if (BLA_VENDOR MATCHES "ACML.*" OR BLA_VENDOR STREQUAL "All")
+ if (BLAS_LIBRARIES MATCHES ".+acml.+")
+ set (LAPACK_LIBRARIES ${BLAS_LIBRARIES})
+ endif ()
+ endif ()
+
+# Apple LAPACK library?
+if (BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All")
+ if(NOT LAPACK_LIBRARIES)
+ check_lapack_libraries(
+ LAPACK_LIBRARIES
+ LAPACK
+ cheev
+ ""
+ "Accelerate"
+ "${BLAS_LIBRARIES}"
+ ""
+ )
+ endif(NOT LAPACK_LIBRARIES)
+endif (BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All")
+if (BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All")
+ if ( NOT LAPACK_LIBRARIES )
+ check_lapack_libraries(
+ LAPACK_LIBRARIES
+ LAPACK
+ cheev
+ ""
+ "vecLib"
+ "${BLAS_LIBRARIES}"
+ ""
+ )
+ endif ( NOT LAPACK_LIBRARIES )
+endif (BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All")
+# Generic LAPACK library?
+if (BLA_VENDOR STREQUAL "Generic" OR
+ BLA_VENDOR STREQUAL "ATLAS" OR
+ BLA_VENDOR STREQUAL "All")
+ if ( NOT LAPACK_LIBRARIES )
+ check_lapack_libraries(
+ LAPACK_LIBRARIES
+ LAPACK
+ cheev
+ ""
+ "lapack"
+ "${BLAS_LIBRARIES}"
+ ""
+ )
+ endif ( NOT LAPACK_LIBRARIES )
+endif ()
+#intel lapack
+if (BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All")
+ if (NOT WIN32)
+ set(LM "-lm")
+ endif ()
+ if (_LANGUAGES_ MATCHES C OR _LANGUAGES_ MATCHES CXX)
+ if(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED)
+ find_PACKAGE(Threads)
+ else(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED)
+ find_package(Threads REQUIRED)
+ endif(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED)
+ 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(NOT LAPACK95_LIBRARIES)
+ 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(NOT LAPACK95_LIBRARIES)
+ else(BLA_F95)
+ if(NOT LAPACK_LIBRARIES)
+ # old
+ check_lapack_libraries(
+ LAPACK_LIBRARIES
+ LAPACK
+ cheev
+ ""
+ "mkl_lapack"
+ "${BLAS_LIBRARIES}"
+ "${CMAKE_THREAD_LIBS_INIT};${LM}"
+ )
+ endif(NOT LAPACK_LIBRARIES)
+ if(NOT LAPACK_LIBRARIES)
+ # new >= 10.3
+ check_lapack_libraries(
+ LAPACK_LIBRARIES
+ LAPACK
+ cheev
+ ""
+ "mkl_gf_lp64"
+ "${BLAS_LIBRARIES}"
+ "${CMAKE_THREAD_LIBS_INIT};${LM}"
+ )
+ endif(NOT LAPACK_LIBRARIES)
+ endif(BLA_F95)
+ endif (_LANGUAGES_ MATCHES C OR _LANGUAGES_ MATCHES CXX)
+endif(BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All")
+else(BLAS_FOUND)
+ message(STATUS "LAPACK requires BLAS")
+endif(BLAS_FOUND)
+
+if(BLA_F95)
+ if(LAPACK95_LIBRARIES)
+ set(LAPACK95_FOUND TRUE)
+ else(LAPACK95_LIBRARIES)
+ set(LAPACK95_FOUND FALSE)
+ endif(LAPACK95_LIBRARIES)
+ if(NOT LAPACK_FIND_QUIETLY)
+ if(LAPACK95_FOUND)
+ message(STATUS "A library with LAPACK95 API found.")
+ else(LAPACK95_FOUND)
+ if(LAPACK_FIND_REQUIRED)
+ message(FATAL_ERROR
+ "A required library with LAPACK95 API not found. Please specify library location."
+ )
+ else(LAPACK_FIND_REQUIRED)
+ message(STATUS
+ "A library with LAPACK95 API not found. Please specify library location."
+ )
+ endif(LAPACK_FIND_REQUIRED)
+ endif(LAPACK95_FOUND)
+ endif(NOT LAPACK_FIND_QUIETLY)
+ set(LAPACK_FOUND "${LAPACK95_FOUND}")
+ set(LAPACK_LIBRARIES "${LAPACK95_LIBRARIES}")
+else(BLA_F95)
+ if(LAPACK_LIBRARIES)
+ set(LAPACK_FOUND TRUE)
+ else(LAPACK_LIBRARIES)
+ set(LAPACK_FOUND FALSE)
+ endif(LAPACK_LIBRARIES)
+
+ if(NOT LAPACK_FIND_QUIETLY)
+ if(LAPACK_FOUND)
+ message(STATUS "A library with LAPACK API found.")
+ else(LAPACK_FOUND)
+ if(LAPACK_FIND_REQUIRED)
+ message(FATAL_ERROR
+ "A required library with LAPACK API not found. Please specify library location."
+ )
+ else(LAPACK_FIND_REQUIRED)
+ message(STATUS
+ "A library with LAPACK API not found. Please specify library location."
+ )
+ endif(LAPACK_FIND_REQUIRED)
+ endif(LAPACK_FOUND)
+ endif(NOT LAPACK_FIND_QUIETLY)
+endif(BLA_F95)
+
+set(CMAKE_FIND_LIBRARY_SUFFIXES ${_lapack_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
diff --git a/Modules/FindLATEX.cmake b/Modules/FindLATEX.cmake
new file mode 100644
index 000000000..950daca5a
--- /dev/null
+++ b/Modules/FindLATEX.cmake
@@ -0,0 +1,126 @@
+# - Find Latex
+# This module finds if Latex is installed and determines where the
+# executables are. This code sets the following variables:
+#
+# 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
+#
+
+#=============================================================================
+# 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.)
+
+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
+ "Path to the MikTex binary directory."
+ )
+ 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
+ )
+
+ GET_FILENAME_COMPONENT(GHOSTSCRIPT_BINARY_PATH_FROM_REGISTERY_7_04
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\AFPL Ghostscript\\7.04;GS_DLL]" PATH
+ )
+
+ FIND_PATH(GHOSTSCRIPT_BINARY_PATH gswin32.exe
+ ${GHOSTSCRIPT_BINARY_PATH_FROM_REGISTERY_8_00}
+ ${GHOSTSCRIPT_BINARY_PATH_FROM_REGISTERY_7_04}
+ DOC "Path to the GhostScript binary directory."
+ )
+ MARK_AS_ADVANCED(GHOSTSCRIPT_BINARY_PATH)
+
+ FIND_PATH(GHOSTSCRIPT_LIBRARY_PATH ps2pdf13.bat
+ "${GHOSTSCRIPT_BINARY_PATH}/../lib"
+ DOC "Path to the GhostScript library directory."
+ )
+ MARK_AS_ADVANCED(GHOSTSCRIPT_LIBRARY_PATH)
+
+ENDIF (WIN32)
+
+FIND_PROGRAM(LATEX_COMPILER
+ NAMES latex
+ PATHS ${MIKTEX_BINARY_PATH}
+ /usr/bin
+)
+
+FIND_PROGRAM(PDFLATEX_COMPILER
+ NAMES pdflatex
+ PATHS ${MIKTEX_BINARY_PATH}
+ /usr/bin
+)
+
+FIND_PROGRAM(BIBTEX_COMPILER
+ NAMES bibtex
+ PATHS ${MIKTEX_BINARY_PATH}
+ /usr/bin
+)
+
+FIND_PROGRAM(MAKEINDEX_COMPILER
+ NAMES makeindex
+ PATHS ${MIKTEX_BINARY_PATH}
+ /usr/bin
+)
+
+FIND_PROGRAM(DVIPS_CONVERTER
+ NAMES dvips
+ PATHS ${MIKTEX_BINARY_PATH}
+ /usr/bin
+)
+
+FIND_PROGRAM(DVIPDF_CONVERTER
+ NAMES dvipdfm dvipdft dvipdf
+ PATHS ${MIKTEX_BINARY_PATH}
+ /usr/bin
+)
+
+IF (WIN32)
+ FIND_PROGRAM(PS2PDF_CONVERTER
+ NAMES ps2pdf14.bat
+ PATHS ${GHOSTSCRIPT_LIBRARY_PATH}
+ )
+ELSE (WIN32)
+ FIND_PROGRAM(PS2PDF_CONVERTER
+ NAMES ps2pdf14 ps2pdf
+ )
+ENDIF (WIN32)
+
+FIND_PROGRAM(LATEX2HTML_CONVERTER
+ NAMES latex2html
+ PATHS ${MIKTEX_BINARY_PATH}
+ /usr/bin
+)
+
+
+MARK_AS_ADVANCED(
+ LATEX_COMPILER
+ PDFLATEX_COMPILER
+ BIBTEX_COMPILER
+ MAKEINDEX_COMPILER
+ DVIPS_CONVERTER
+ DVIPDF_CONVERTER
+ PS2PDF_CONVERTER
+ LATEX2HTML_CONVERTER
+)
diff --git a/Modules/FindLibArchive.cmake b/Modules/FindLibArchive.cmake
new file mode 100644
index 000000000..be931c525
--- /dev/null
+++ b/Modules/FindLibArchive.cmake
@@ -0,0 +1,67 @@
+# - 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
+
+#=============================================================================
+# Copyright 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.)
+
+find_path(LibArchive_INCLUDE_DIR
+ NAMES archive.h
+ PATHS
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\GnuWin32\\LibArchive;InstallPath]/include"
+ )
+
+find_library(LibArchive_LIBRARY
+ NAMES archive libarchive
+ PATHS
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\GnuWin32\\LibArchive;InstallPath]/lib"
+ )
+
+mark_as_advanced(LibArchive_INCLUDE_DIR LibArchive_LIBRARY)
+
+# Extract the version number from the header.
+if(LibArchive_INCLUDE_DIR AND EXISTS "${LibArchive_INCLUDE_DIR}/archive.h")
+ # The version string appears in one of two known formats in the header:
+ # #define ARCHIVE_LIBRARY_VERSION "libarchive 2.4.12"
+ # #define ARCHIVE_VERSION_STRING "libarchive 2.8.4"
+ # Match either format.
+ set(_LibArchive_VERSION_REGEX "^#define[ \t]+ARCHIVE[_A-Z]+VERSION[_A-Z]*[ \t]+\"libarchive +([0-9]+)\\.([0-9]+)\\.([0-9]+)[^\"]*\".*$")
+ file(STRINGS "${LibArchive_INCLUDE_DIR}/archive.h" _LibArchive_VERSION_STRING LIMIT_COUNT 1 REGEX "${_LibArchive_VERSION_REGEX}")
+ if(_LibArchive_VERSION_STRING)
+ string(REGEX REPLACE "${_LibArchive_VERSION_REGEX}" "\\1.\\2.\\3" LibArchive_VERSION "${_LibArchive_VERSION_STRING}")
+ endif()
+ unset(_LibArchive_VERSION_REGEX)
+ unset(_LibArchive_VERSION_STRING)
+endif()
+
+# Handle the QUIETLY and REQUIRED arguments and set LIBARCHIVE_FOUND
+# to TRUE if all listed variables are TRUE.
+# (Use ${CMAKE_ROOT}/Modules instead of ${CMAKE_CURRENT_LIST_DIR} because CMake
+# itself includes this FindLibArchive when built with an older CMake that does
+# not provide it. The older CMake also does not have CMAKE_CURRENT_LIST_DIR.)
+include(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake)
+find_package_handle_standard_args(LibArchive
+ REQUIRED_VARS LibArchive_LIBRARY LibArchive_INCLUDE_DIR
+ VERSION_VAR LibArchive_VERSION
+ )
+set(LibArchive_FOUND ${LIBARCHIVE_FOUND})
+unset(LIBARCHIVE_FOUND)
+
+if(LibArchive_FOUND)
+ set(LibArchive_INCLUDE_DIRS ${LibArchive_INCLUDE_DIR})
+ set(LibArchive_LIBRARIES ${LibArchive_LIBRARY})
+endif()
diff --git a/Modules/FindLibLZMA.cmake b/Modules/FindLibLZMA.cmake
new file mode 100644
index 000000000..729f5ce73
--- /dev/null
+++ b/Modules/FindLibLZMA.cmake
@@ -0,0 +1,69 @@
+# - 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")
+
+#=============================================================================
+# Copyright 2008 Per Øyvind Karlsen <peroyvind@mandriva.org>
+# Copyright 2009 Alexander Neundorf <neundorf@kde.org>
+# Copyright 2009 Helio Chissini de Castro <helio@kde.org>
+# Copyright 2012 Mario Bensi <mbensi@ipsquad.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_PATH(LIBLZMA_INCLUDE_DIR lzma.h )
+FIND_LIBRARY(LIBLZMA_LIBRARY lzma)
+
+IF(LIBLZMA_INCLUDE_DIR AND EXISTS "${LIBLZMA_INCLUDE_DIR}/lzma/version.h")
+ FILE(READ "${LIBLZMA_INCLUDE_DIR}/lzma/version.h" LIBLZMA_HEADER_CONTENTS)
+
+ STRING(REGEX REPLACE ".*#define LZMA_VERSION_MAJOR ([0-9]+).*" "\\1" LIBLZMA_VERSION_MAJOR "${LIBLZMA_HEADER_CONTENTS}")
+ STRING(REGEX REPLACE ".*#define LZMA_VERSION_MINOR ([0-9]+).*" "\\1" LIBLZMA_VERSION_MINOR "${LIBLZMA_HEADER_CONTENTS}")
+ STRING(REGEX REPLACE ".*#define LZMA_VERSION_PATCH ([0-9]+).*" "\\1" LIBLZMA_VERSION_PATCH "${LIBLZMA_HEADER_CONTENTS}")
+
+ SET(LIBLZMA_VERSION_STRING "${LIBLZMA_VERSION_MAJOR}.${LIBLZMA_VERSION_MINOR}.${LIBLZMA_VERSION_PATCH}")
+ENDIF(LIBLZMA_INCLUDE_DIR AND EXISTS "${LIBLZMA_INCLUDE_DIR}/lzma/version.h")
+
+# We're using new code known now as XZ, even library still been called LZMA
+# it can be found in http://tukaani.org/xz/
+# Avoid using old codebase
+IF (LIBLZMA_LIBRARY)
+ INCLUDE(CheckLibraryExists)
+ 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)
+ENDIF (LIBLZMA_LIBRARY)
+
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibLZMA REQUIRED_VARS LIBLZMA_INCLUDE_DIR
+ LIBLZMA_LIBRARY
+ LIBLZMA_HAS_AUTO_DECODER
+ LIBLZMA_HAS_EASY_ENCODER
+ LIBLZMA_HAS_LZMA_PRESET
+ VERSION_VAR LIBLZMA_VERSION_STRING
+ )
+
+IF (LIBLZMA_FOUND)
+ SET(LIBLZMA_LIBRARIES ${LIBLZMA_LIBRARY})
+ SET(LIBLZMA_INCLUDE_DIRS ${LIBLZMA_INCLUDE_DIR})
+ENDIF (LIBLZMA_FOUND)
+
+MARK_AS_ADVANCED( LIBLZMA_INCLUDE_DIR LIBLZMA_LIBRARY )
diff --git a/Modules/FindLibXml2.cmake b/Modules/FindLibXml2.cmake
new file mode 100644
index 000000000..48a549806
--- /dev/null
+++ b/Modules/FindLibXml2.cmake
@@ -0,0 +1,66 @@
+# - 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)
+
+#=============================================================================
+# Copyright 2006-2009 Kitware, Inc.
+# Copyright 2006 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.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+# use pkg-config to get the directories and then use these values
+# in the FIND_PATH() and FIND_LIBRARY() calls
+FIND_PACKAGE(PkgConfig QUIET)
+PKG_CHECK_MODULES(PC_LIBXML QUIET libxml-2.0)
+SET(LIBXML2_DEFINITIONS ${PC_LIBXML_CFLAGS_OTHER})
+
+FIND_PATH(LIBXML2_INCLUDE_DIR NAMES libxml/xpath.h
+ HINTS
+ ${PC_LIBXML_INCLUDEDIR}
+ ${PC_LIBXML_INCLUDE_DIRS}
+ PATH_SUFFIXES libxml2
+ )
+
+FIND_LIBRARY(LIBXML2_LIBRARIES NAMES xml2 libxml2
+ HINTS
+ ${PC_LIBXML_LIBDIR}
+ ${PC_LIBXML_LIBRARY_DIRS}
+ )
+
+FIND_PROGRAM(LIBXML2_XMLLINT_EXECUTABLE xmllint)
+# for backwards compat. with KDE 4.0.x:
+SET(XMLLINT_EXECUTABLE "${LIBXML2_XMLLINT_EXECUTABLE}")
+
+IF(PC_LIBXML_VERSION)
+ SET(LIBXML2_VERSION_STRING ${PC_LIBXML_VERSION})
+ELSEIF(LIBXML2_INCLUDE_DIR AND EXISTS "${LIBXML2_INCLUDE_DIR}/libxml/xmlversion.h")
+ FILE(STRINGS "${LIBXML2_INCLUDE_DIR}/libxml/xmlversion.h" libxml2_version_str
+ REGEX "^#define[\t ]+LIBXML_DOTTED_VERSION[\t ]+\".*\"")
+
+ STRING(REGEX REPLACE "^#define[\t ]+LIBXML_DOTTED_VERSION[\t ]+\"([^\"]*)\".*" "\\1"
+ LIBXML2_VERSION_STRING "${libxml2_version_str}")
+ UNSET(libxml2_version_str)
+ENDIF()
+
+# handle the QUIETLY and REQUIRED arguments and set LIBXML2_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibXml2
+ REQUIRED_VARS LIBXML2_LIBRARIES LIBXML2_INCLUDE_DIR
+ VERSION_VAR LIBXML2_VERSION_STRING)
+
+MARK_AS_ADVANCED(LIBXML2_INCLUDE_DIR LIBXML2_LIBRARIES LIBXML2_XMLLINT_EXECUTABLE)
diff --git a/Modules/FindLibXslt.cmake b/Modules/FindLibXslt.cmake
new file mode 100644
index 000000000..dd5aac461
--- /dev/null
+++ b/Modules/FindLibXslt.cmake
@@ -0,0 +1,74 @@
+# - 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
+
+#=============================================================================
+# Copyright 2006-2009 Kitware, Inc.
+# Copyright 2006 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.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+# use pkg-config to get the directories and then use these values
+# in the FIND_PATH() and FIND_LIBRARY() calls
+FIND_PACKAGE(PkgConfig QUIET)
+PKG_CHECK_MODULES(PC_LIBXSLT QUIET libxslt)
+SET(LIBXSLT_DEFINITIONS ${PC_LIBXSLT_CFLAGS_OTHER})
+
+FIND_PATH(LIBXSLT_INCLUDE_DIR NAMES libxslt/xslt.h
+ HINTS
+ ${PC_LIBXSLT_INCLUDEDIR}
+ ${PC_LIBXSLT_INCLUDE_DIRS}
+ )
+
+FIND_LIBRARY(LIBXSLT_LIBRARIES NAMES xslt libxslt
+ HINTS
+ ${PC_LIBXSLT_LIBDIR}
+ ${PC_LIBXSLT_LIBRARY_DIRS}
+ )
+
+FIND_LIBRARY(LIBXSLT_EXSLT_LIBRARY NAMES exslt libexslt
+ HINTS
+ ${PC_LIBXSLT_LIBDIR}
+ ${PC_LIBXSLT_LIBRARY_DIRS}
+ )
+
+SET(LIBXSLT_EXSLT_LIBRARIES ${LIBXSLT_EXSLT_LIBRARY} )
+
+FIND_PROGRAM(LIBXSLT_XSLTPROC_EXECUTABLE xsltproc)
+
+IF(PC_LIBXSLT_VERSION)
+ SET(LIBXSLT_VERSION_STRING ${PC_LIBXSLT_VERSION})
+ELSEIF(LIBXSLT_INCLUDE_DIR AND EXISTS "${LIBXSLT_INCLUDE_DIR}/libxslt/xsltconfig.h")
+ FILE(STRINGS "${LIBXSLT_INCLUDE_DIR}/libxslt/xsltconfig.h" libxslt_version_str
+ REGEX "^#define[\t ]+LIBXSLT_DOTTED_VERSION[\t ]+\".*\"")
+
+ STRING(REGEX REPLACE "^#define[\t ]+LIBXSLT_DOTTED_VERSION[\t ]+\"([^\"]*)\".*" "\\1"
+ LIBXSLT_VERSION_STRING "${libxslt_version_str}")
+ UNSET(libxslt_version_str)
+ENDIF()
+
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibXslt
+ REQUIRED_VARS LIBXSLT_LIBRARIES LIBXSLT_INCLUDE_DIR
+ VERSION_VAR LIBXSLT_VERSION_STRING)
+
+MARK_AS_ADVANCED(LIBXSLT_INCLUDE_DIR
+ LIBXSLT_LIBRARIES
+ LIBXSLT_EXSLT_LIBRARY
+ LIBXSLT_XSLTPROC_EXECUTABLE)
diff --git a/Modules/FindLua50.cmake b/Modules/FindLua50.cmake
new file mode 100644
index 000000000..9a5cc1703
--- /dev/null
+++ b/Modules/FindLua50.cmake
@@ -0,0 +1,90 @@
+# 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"
+# 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.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software 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(LUA_INCLUDE_DIR lua.h
+ HINTS
+ $ENV{LUA_DIR}
+ PATH_SUFFIXES include/lua50 include/lua5.0 include/lua5 include/lua include
+ PATHS
+ ~/Library/Frameworks
+ /Library/Frameworks
+ /sw # Fink
+ /opt/local # DarwinPorts
+ /opt/csw # Blastwave
+ /opt
+)
+
+FIND_LIBRARY(LUA_LIBRARY_lua
+ NAMES lua50 lua5.0 lua-5.0 lua5 lua
+ HINTS
+ $ENV{LUA_DIR}
+ PATH_SUFFIXES lib64 lib
+ PATHS
+ ~/Library/Frameworks
+ /Library/Frameworks
+ /sw
+ /opt/local
+ /opt/csw
+ /opt
+)
+
+# In an OS X framework, lualib is usually included as part of the framework
+# (like GLU in OpenGL.framework)
+IF(${LUA_LIBRARY_lua} MATCHES "framework")
+ SET( LUA_LIBRARIES "${LUA_LIBRARY_lua}" CACHE STRING "Lua framework")
+ELSE(${LUA_LIBRARY_lua} MATCHES "framework")
+ FIND_LIBRARY(LUA_LIBRARY_lualib
+ NAMES lualib50 lualib5.0 lualib5 lualib
+ HINTS
+ $ENV{LUALIB_DIR}
+ $ENV{LUA_DIR}
+ PATH_SUFFIXES lib64 lib
+ PATHS
+ /sw
+ /opt/local
+ /opt/csw
+ /opt
+ )
+ IF(LUA_LIBRARY_lualib AND LUA_LIBRARY_lua)
+ # include the math library for Unix
+ IF(UNIX AND NOT APPLE)
+ FIND_LIBRARY(MATH_LIBRARY_FOR_LUA m)
+ SET( LUA_LIBRARIES "${LUA_LIBRARY_lualib};${LUA_LIBRARY_lua};${MATH_LIBRARY_FOR_LUA}" CACHE STRING "This is the concatentation of lua and lualib libraries")
+ # For Windows and Mac, don't need to explicitly include the math library
+ ELSE(UNIX AND NOT APPLE)
+ SET( LUA_LIBRARIES "${LUA_LIBRARY_lualib};${LUA_LIBRARY_lua}" CACHE STRING "This is the concatentation of lua and lualib libraries")
+ ENDIF(UNIX AND NOT APPLE)
+ ENDIF(LUA_LIBRARY_lualib AND LUA_LIBRARY_lua)
+ENDIF(${LUA_LIBRARY_lua} MATCHES "framework")
+
+
+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(Lua50 DEFAULT_MSG LUA_LIBRARIES LUA_INCLUDE_DIR)
+
+MARK_AS_ADVANCED(LUA_INCLUDE_DIR LUA_LIBRARIES)
+
diff --git a/Modules/FindLua51.cmake b/Modules/FindLua51.cmake
new file mode 100644
index 000000000..e111d3624
--- /dev/null
+++ b/Modules/FindLua51.cmake
@@ -0,0 +1,81 @@
+# 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"
+# 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.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software 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(LUA_INCLUDE_DIR lua.h
+ HINTS
+ $ENV{LUA_DIR}
+ PATH_SUFFIXES include/lua51 include/lua5.1 include/lua include
+ PATHS
+ ~/Library/Frameworks
+ /Library/Frameworks
+ /sw # Fink
+ /opt/local # DarwinPorts
+ /opt/csw # Blastwave
+ /opt
+)
+
+FIND_LIBRARY(LUA_LIBRARY
+ NAMES lua51 lua5.1 lua-5.1 lua
+ HINTS
+ $ENV{LUA_DIR}
+ PATH_SUFFIXES lib64 lib
+ PATHS
+ ~/Library/Frameworks
+ /Library/Frameworks
+ /sw
+ /opt/local
+ /opt/csw
+ /opt
+)
+
+IF(LUA_LIBRARY)
+ # include the math library for Unix
+ IF(UNIX AND NOT APPLE)
+ 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
+ ELSE(UNIX AND NOT APPLE)
+ SET( LUA_LIBRARIES "${LUA_LIBRARY}" CACHE STRING "Lua Libraries")
+ ENDIF(UNIX AND NOT APPLE)
+ENDIF(LUA_LIBRARY)
+
+IF(LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/lua.h")
+ FILE(STRINGS "${LUA_INCLUDE_DIR}/lua.h" lua_version_str REGEX "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua .+\"")
+
+ STRING(REGEX REPLACE "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([^\"]+)\".*" "\\1" LUA_VERSION_STRING "${lua_version_str}")
+ UNSET(lua_version_str)
+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(Lua51
+ REQUIRED_VARS LUA_LIBRARIES LUA_INCLUDE_DIR
+ VERSION_VAR LUA_VERSION_STRING)
+
+MARK_AS_ADVANCED(LUA_INCLUDE_DIR LUA_LIBRARIES LUA_LIBRARY LUA_MATH_LIBRARY)
+
diff --git a/Modules/FindMFC.cmake b/Modules/FindMFC.cmake
new file mode 100644
index 000000000..3df284241
--- /dev/null
+++ b/Modules/FindMFC.cmake
@@ -0,0 +1,60 @@
+# - 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.
+
+#=============================================================================
+# 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.)
+
+# Assume no MFC support
+SET(MFC_FOUND "NO")
+
+# Only attempt the try_compile call if it has a chance to succeed:
+SET(MFC_ATTEMPT_TRY_COMPILE 0)
+IF(WIN32 AND NOT UNIX AND NOT BORLAND AND NOT MINGW)
+ SET(MFC_ATTEMPT_TRY_COMPILE 1)
+ENDIF(WIN32 AND NOT UNIX AND NOT BORLAND AND NOT MINGW)
+
+IF(MFC_ATTEMPT_TRY_COMPILE)
+ IF("MFC_HAVE_MFC" MATCHES "^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)
+ MESSAGE(STATUS "Looking for MFC")
+ TRY_COMPILE(MFC_HAVE_MFC
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.cxx
+ CMAKE_FLAGS
+ -DCMAKE_MFC_FLAG:STRING=2
+ -DCOMPILE_DEFINITIONS:STRING=-D_AFXDLL
+ OUTPUT_VARIABLE OUTPUT)
+ IF(MFC_HAVE_MFC)
+ MESSAGE(STATUS "Looking for MFC - found")
+ SET(MFC_HAVE_MFC 1 CACHE INTERNAL "Have MFC?")
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "Determining if MFC exists passed with the following output:\n"
+ "${OUTPUT}\n\n")
+ ELSE(MFC_HAVE_MFC)
+ MESSAGE(STATUS "Looking for MFC - not found")
+ SET(MFC_HAVE_MFC 0 CACHE INTERNAL "Have MFC?")
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Determining if MFC exists failed with the following output:\n"
+ "${OUTPUT}\n\n")
+ ENDIF(MFC_HAVE_MFC)
+ ENDIF("MFC_HAVE_MFC" MATCHES "^MFC_HAVE_MFC$")
+
+ IF(MFC_HAVE_MFC)
+ SET(MFC_FOUND "YES")
+ ENDIF(MFC_HAVE_MFC)
+ENDIF(MFC_ATTEMPT_TRY_COMPILE)
diff --git a/Modules/FindMPEG.cmake b/Modules/FindMPEG.cmake
new file mode 100644
index 000000000..cf4ef58f8
--- /dev/null
+++ b/Modules/FindMPEG.cmake
@@ -0,0 +1,44 @@
+# - 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.
+# 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.
+
+#=============================================================================
+# 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_PATH(MPEG_INCLUDE_DIR mpeg2dec/include/video_out.h
+ /usr/local/livid
+)
+
+FIND_LIBRARY(MPEG_mpeg2_LIBRARY mpeg2
+ /usr/local/livid/mpeg2dec/libmpeg2/.libs
+)
+
+FIND_LIBRARY( MPEG_vo_LIBRARY vo
+ /usr/local/livid/mpeg2dec/libvo/.libs
+)
+
+# handle the QUIETLY and REQUIRED arguments and set MPEG2_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(MPEG DEFAULT_MSG MPEG_INCLUDE_DIR MPEG_mpeg2_LIBRARY MPEG_vo_LIBRARY)
+
+IF(MPEG_FOUND)
+ SET( MPEG_LIBRARIES ${MPEG_mpeg2_LIBRARY} ${MPEG_vo_LIBRARY} )
+ENDIF(MPEG_FOUND)
+
+MARK_AS_ADVANCED(MPEG_INCLUDE_DIR MPEG_mpeg2_LIBRARY MPEG_vo_LIBRARY)
diff --git a/Modules/FindMPEG2.cmake b/Modules/FindMPEG2.cmake
new file mode 100644
index 000000000..fab37cf54
--- /dev/null
+++ b/Modules/FindMPEG2.cmake
@@ -0,0 +1,54 @@
+# - 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.
+# 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.
+
+#=============================================================================
+# 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_PATH(MPEG2_INCLUDE_DIR
+ NAMES mpeg2.h mpeg2dec/mpeg2.h
+ PATHS /usr/local/livid
+)
+
+FIND_LIBRARY(MPEG2_mpeg2_LIBRARY mpeg2
+ /usr/local/livid/mpeg2dec/libmpeg2/.libs
+)
+
+FIND_LIBRARY( MPEG2_vo_LIBRARY vo
+ /usr/local/livid/mpeg2dec/libvo/.libs
+)
+
+
+# handle the QUIETLY and REQUIRED arguments and set MPEG2_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(MPEG2 DEFAULT_MSG MPEG2_mpeg2_LIBRARY MPEG2_INCLUDE_DIR)
+
+IF(MPEG2_FOUND)
+ SET( MPEG2_LIBRARIES ${MPEG2_mpeg2_LIBRARY}
+ ${MPEG2_vo_LIBRARY})
+
+ #some native mpeg2 installations will depend
+ #on libSDL, if found, add it in.
+ INCLUDE( FindSDL )
+ IF(SDL_FOUND)
+ SET( MPEG2_LIBRARIES ${MPEG2_LIBRARIES} ${SDL_LIBRARY})
+ ENDIF(SDL_FOUND)
+ENDIF(MPEG2_FOUND)
+
+MARK_AS_ADVANCED(MPEG2_INCLUDE_DIR MPEG2_mpeg2_LIBRARY MPEG2_vo_LIBRARY)
diff --git a/Modules/FindMPI.cmake b/Modules/FindMPI.cmake
new file mode 100644
index 000000000..ae50ca7b9
--- /dev/null
+++ b/Modules/FindMPI.cmake
@@ -0,0 +1,631 @@
+# - 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.
+#
+# === 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
+# 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
+# === 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.
+#
+# === 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
+# In new projects, please use the MPI_<lang>_XXX equivalents.
+
+#=============================================================================
+# Copyright 2001-2011 Kitware, Inc.
+# Copyright 2010-2011 Todd Gamblin tgamblin@llnl.gov
+# Copyright 2001-2009 Dave Partyka
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software 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 this to handle the QUIETLY and REQUIRED arguments
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+include(GetPrerequisites)
+
+#
+# This part detects MPI compilers, attempting to wade through the mess of compiler names in
+# a sensible way.
+#
+# The compilers are detected in this order:
+#
+# 1. Try to find the most generic availble MPI compiler, as this is usually set up by
+# cluster admins. e.g., if plain old mpicc is available, we'll use it and assume it's
+# the right compiler.
+#
+# 2. If a generic mpicc is NOT found, then we attempt to find one that matches
+# CMAKE_<lang>_COMPILER_ID. e.g. if you are using XL compilers, we'll try to find mpixlc
+# and company, but not mpiicc. This hopefully prevents toolchain mismatches.
+#
+# If you want to force a particular MPI compiler other than what we autodetect (e.g. if you
+# want to compile regular stuff with GNU and parallel stuff with Intel), you can always set
+# your favorite MPI_<lang>_COMPILER explicitly and this stuff will be ignored.
+#
+
+# Start out with the generic MPI compiler names, as these are most commonly used.
+set(_MPI_C_COMPILER_NAMES mpicc mpcc mpicc_r mpcc_r)
+set(_MPI_CXX_COMPILER_NAMES mpicxx mpiCC mpcxx mpCC mpic++ mpc++
+ mpicxx_r mpiCC_r mpcxx_r mpCC_r mpic++_r mpc++_r)
+set(_MPI_Fortran_COMPILER_NAMES mpif95 mpif95_r mpf95 mpf95_r
+ mpif90 mpif90_r mpf90 mpf90_r
+ mpif77 mpif77_r mpf77 mpf77_r)
+
+# GNU compiler names
+set(_MPI_GNU_C_COMPILER_NAMES mpigcc mpgcc mpigcc_r mpgcc_r)
+set(_MPI_GNU_CXX_COMPILER_NAMES mpig++ mpg++ mpig++_r mpg++_r)
+set(_MPI_GNU_Fortran_COMPILER_NAMES mpigfortran mpgfortran mpigfortran_r mpgfortran_r
+ mpig77 mpig77_r mpg77 mpg77_r)
+
+# Intel MPI compiler names
+set(_MPI_Intel_C_COMPILER_NAMES mpiicc)
+set(_MPI_Intel_CXX_COMPILER_NAMES mpiicpc mpiicxx mpiic++ mpiiCC)
+set(_MPI_Intel_Fortran_COMPILER_NAMES mpiifort mpiif95 mpiif90 mpiif77)
+
+# PGI compiler names
+set(_MPI_PGI_C_COMPILER_NAMES mpipgcc mppgcc)
+set(_MPI_PGI_CXX_COMPILER_NAMES mpipgCC mppgCC)
+set(_MPI_PGI_Fortran_COMPILER_NAMES mpipgf95 mpipgf90 mppgf95 mppgf90 mpipgf77 mppgf77)
+
+# XLC MPI Compiler names
+set(_MPI_XL_C_COMPILER_NAMES mpxlc mpxlc_r mpixlc mpixlc_r)
+set(_MPI_XL_CXX_COMPILER_NAMES mpixlcxx mpixlC mpixlc++ mpxlcxx mpxlc++ mpixlc++ mpxlCC
+ mpixlcxx_r mpixlC_r mpixlc++_r mpxlcxx_r mpxlc++_r mpixlc++_r mpxlCC_r)
+set(_MPI_XL_Fortran_COMPILER_NAMES mpixlf95 mpixlf95_r mpxlf95 mpxlf95_r
+ mpixlf90 mpixlf90_r mpxlf90 mpxlf90_r
+ mpixlf77 mpixlf77_r mpxlf77 mpxlf77_r
+ mpixlf mpixlf_r mpxlf mpxlf_r)
+
+# append vendor-specific compilers to the list if we either don't know the compiler id,
+# 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}")
+ list(APPEND _MPI_${lang}_COMPILER_NAMES ${_MPI_${id}_${lang}_COMPILER_NAMES})
+ endif()
+ unset(_MPI_${id}_${lang}_COMPILER_NAMES) # clean up the namespace here
+ endforeach()
+endforeach()
+
+
+# Names to try for MPI exec
+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)
+ 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/")
+endif()
+
+# Build a list of prefixes to search for MPI.
+foreach(SystemPrefixDir ${CMAKE_SYSTEM_PREFIX_PATH})
+ foreach(MpiPackageDir ${_MPI_PREFIX_PATH})
+ if(EXISTS ${SystemPrefixDir}/${MpiPackageDir})
+ list(APPEND _MPI_PREFIX_PATH "${SystemPrefixDir}/${MpiPackageDir}")
+ endif()
+ endforeach()
+endforeach()
+
+
+#
+# interrogate_mpi_compiler(lang try_libs)
+#
+# Attempts to extract compiler and linker args from an MPI compiler. The arguments set
+# by this function are:
+#
+# MPI_<lang>_INCLUDE_PATH MPI_<lang>_LINK_FLAGS MPI_<lang>_FOUND
+# MPI_<lang>_COMPILE_FLAGS MPI_<lang>_LIBRARIES
+#
+# MPI_<lang>_COMPILER must be set beforehand to the absolute path to an MPI compiler for
+# <lang>. Additionally, MPI_<lang>_INCLUDE_PATH and MPI_<lang>_LIBRARIES may be set
+# to skip autodetection.
+#
+# If try_libs is TRUE, this will also attempt to find plain MPI libraries in the usual
+# way. In general, this is not as effective as interrogating the compilers, as it
+# ignores language-specific flags and libraries. However, some MPI implementations
+# (Windows implementations) do not have compiler wrappers, so this approach must be used.
+#
+function (interrogate_mpi_compiler lang try_libs)
+ # MPI_${lang}_NO_INTERROGATE will be set to a compiler name when the *regular* compiler was
+ # discovered to be the MPI compiler. This happens on machines like the Cray XE6 that use
+ # modules to set cc, CC, and ftn to the MPI compilers. If the user force-sets another MPI
+ # compiler, MPI_${lang}_COMPILER won't be equal to MPI_${lang}_NO_INTERROGATE, and we'll
+ # inspect that compiler anew. This allows users to set new compilers w/o rm'ing cache.
+ string(COMPARE NOTEQUAL "${MPI_${lang}_NO_INTERROGATE}" "${MPI_${lang}_COMPILER}" interrogate)
+
+ # If MPI is set already in the cache, don't bother with interrogating the compiler.
+ if (interrogate AND ((NOT MPI_${lang}_INCLUDE_PATH) OR (NOT MPI_${lang}_LIBRARIES)))
+ 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)
+
+ if (MPI_COMPILER_RETURN EQUAL 0)
+ # If we appear to have -showme:compile, then we should
+ # also have -showme:link. Try it.
+ execute_process(
+ COMMAND ${MPI_${lang}_COMPILER} -showme:link
+ OUTPUT_VARIABLE MPI_LINK_CMDLINE OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_VARIABLE MPI_LINK_CMDLINE ERROR_STRIP_TRAILING_WHITESPACE
+ RESULT_VARIABLE MPI_COMPILER_RETURN)
+
+ if (MPI_COMPILER_RETURN EQUAL 0)
+ # We probably have -showme:incdirs and -showme:libdirs as well,
+ # so grab that while we're at it.
+ execute_process(
+ COMMAND ${MPI_${lang}_COMPILER} -showme:incdirs
+ OUTPUT_VARIABLE MPI_INCDIRS OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_VARIABLE MPI_INCDIRS ERROR_STRIP_TRAILING_WHITESPACE)
+
+ execute_process(
+ COMMAND ${MPI_${lang}_COMPILER} -showme:libdirs
+ OUTPUT_VARIABLE MPI_LIBDIRS OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_VARIABLE MPI_LIBDIRS ERROR_STRIP_TRAILING_WHITESPACE)
+
+ else()
+ # reset things here if something went wrong.
+ set(MPI_COMPILE_CMDLINE)
+ set(MPI_LINK_CMDLINE)
+ endif()
+ endif ()
+
+ # 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)
+ 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)
+
+ # If we have compile-info, also have link-info.
+ if (MPI_COMPILER_RETURN EQUAL 0)
+ execute_process(
+ COMMAND ${MPI_${lang}_COMPILER} -link-info
+ OUTPUT_VARIABLE MPI_LINK_CMDLINE OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_VARIABLE MPI_LINK_CMDLINE ERROR_STRIP_TRAILING_WHITESPACE
+ RESULT_VARIABLE MPI_COMPILER_RETURN)
+ endif()
+
+ # make sure we got compile and link. Reset vars if something's wrong.
+ if (NOT MPI_COMPILER_RETURN EQUAL 0)
+ set(MPI_COMPILE_CMDLINE)
+ set(MPI_LINK_CMDLINE)
+ endif()
+ endif()
+
+ # 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)
+ endif()
+
+ if (MPI_COMPILER_RETURN EQUAL 0)
+ # We have our command lines, but we might need to copy MPI_COMPILE_CMDLINE
+ # into MPI_LINK_CMDLINE, if we didn't find the link line.
+ if (NOT MPI_LINK_CMDLINE)
+ set(MPI_LINK_CMDLINE ${MPI_COMPILE_CMDLINE})
+ endif()
+ else()
+ message(STATUS "Unable to determine MPI from MPI driver ${MPI_${lang}_COMPILER}")
+ set(MPI_COMPILE_CMDLINE)
+ set(MPI_LINK_CMDLINE)
+ endif()
+
+ # Here, we're done with the interrogation part, and we'll try to extract args we care
+ # about from what we learned from the compiler wrapper scripts.
+
+ # If interrogation came back with something, extract our variable from the MPI command line
+ if (MPI_COMPILE_CMDLINE OR MPI_LINK_CMDLINE)
+ # Extract compile flags from the compile command line.
+ string(REGEX MATCHALL "(^| )-[Df]([^\" ]+|\"[^\"]+\")" MPI_ALL_COMPILE_FLAGS "${MPI_COMPILE_CMDLINE}")
+ set(MPI_COMPILE_FLAGS_WORK)
+
+ foreach(FLAG ${MPI_ALL_COMPILE_FLAGS})
+ if (MPI_COMPILE_FLAGS_WORK)
+ set(MPI_COMPILE_FLAGS_WORK "${MPI_COMPILE_FLAGS_WORK} ${FLAG}")
+ else()
+ set(MPI_COMPILE_FLAGS_WORK ${FLAG})
+ endif()
+ endforeach()
+
+ # Extract include paths from compile command line
+ 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})
+ list(APPEND MPI_INCLUDE_PATH_WORK ${IPATH})
+ endforeach()
+
+ # try using showme:incdirs if extracting didn't work.
+ if (NOT MPI_INCLUDE_PATH_WORK)
+ set(MPI_INCLUDE_PATH_WORK ${MPI_INCDIRS})
+ separate_arguments(MPI_INCLUDE_PATH_WORK)
+ endif()
+
+ # If all else fails, just search for mpi.h in the normal include paths.
+ if (NOT MPI_INCLUDE_PATH_WORK)
+ set(MPI_HEADER_PATH "MPI_HEADER_PATH-NOTFOUND" CACHE FILEPATH "Cleared" FORCE)
+ find_path(MPI_HEADER_PATH mpi.h
+ HINTS ${_MPI_BASE_DIR} ${_MPI_PREFIX_PATH}
+ PATH_SUFFIXES include)
+ set(MPI_INCLUDE_PATH_WORK ${MPI_HEADER_PATH})
+ endif()
+
+ # Extract linker paths from the link command line
+ string(REGEX MATCHALL "(^| |-Wl,)-L([^\" ]+|\"[^\"]+\")" MPI_ALL_LINK_PATHS "${MPI_LINK_CMDLINE}")
+ set(MPI_LINK_PATH)
+ foreach(LPATH ${MPI_ALL_LINK_PATHS})
+ string(REGEX REPLACE "^(| |-Wl,)-L" "" LPATH ${LPATH})
+ string(REGEX REPLACE "//" "/" LPATH ${LPATH})
+ list(APPEND MPI_LINK_PATH ${LPATH})
+ endforeach()
+
+ # try using showme:libdirs if extracting didn't work.
+ if (NOT MPI_LINK_PATH)
+ set(MPI_LINK_PATH ${MPI_LIBDIRS})
+ separate_arguments(MPI_LINK_PATH)
+ endif()
+
+ # Extract linker flags from the link command line
+ string(REGEX MATCHALL "(^| )-Wl,([^\" ]+|\"[^\"]+\")" MPI_ALL_LINK_FLAGS "${MPI_LINK_CMDLINE}")
+ set(MPI_LINK_FLAGS_WORK)
+ foreach(FLAG ${MPI_ALL_LINK_FLAGS})
+ if (MPI_LINK_FLAGS_WORK)
+ set(MPI_LINK_FLAGS_WORK "${MPI_LINK_FLAGS_WORK} ${FLAG}")
+ else()
+ set(MPI_LINK_FLAGS_WORK ${FLAG})
+ endif()
+ endforeach()
+
+ # 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)
+ set(MPI_LINK_PATH
+ "${MPI_LINK_PATH};${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}")
+ endif ()
+
+ # Determine full path names for all of the libraries that one needs
+ # to link against in an MPI program
+ foreach(LIB ${MPI_LIBNAMES})
+ string(REGEX REPLACE "^ ?-l" "" LIB ${LIB})
+ # MPI_LIB is cached by find_library, but we don't want that. Clear it first.
+ set(MPI_LIB "MPI_LIB-NOTFOUND" CACHE FILEPATH "Cleared" FORCE)
+ find_library(MPI_LIB NAMES ${LIB} HINTS ${MPI_LINK_PATH})
+
+ if (MPI_LIB)
+ list(APPEND MPI_LIBRARIES_WORK ${MPI_LIB})
+ elseif (NOT MPI_FIND_QUIETLY)
+ message(WARNING "Unable to find MPI library ${LIB}")
+ endif()
+ endforeach()
+
+ # Sanity check MPI_LIBRARIES to make sure there are enough libraries
+ list(LENGTH MPI_LIBRARIES_WORK MPI_NUMLIBS)
+ list(LENGTH MPI_LIBNAMES MPI_NUMLIBS_EXPECTED)
+ if (NOT MPI_NUMLIBS EQUAL MPI_NUMLIBS_EXPECTED)
+ set(MPI_LIBRARIES_WORK "MPI_${lang}_LIBRARIES-NOTFOUND")
+ endif()
+ endif()
+
+ elseif(try_libs)
+ # If we didn't have an MPI compiler script to interrogate, attempt to find everything
+ # with plain old find functions. This is nasty because MPI implementations have LOTS of
+ # different library names, so this section isn't going to be very generic. We need to
+ # make sure it works for MS MPI, though, since there are no compiler wrappers for that.
+ find_path(MPI_HEADER_PATH mpi.h
+ HINTS ${_MPI_BASE_DIR} ${_MPI_PREFIX_PATH}
+ PATH_SUFFIXES include Inc)
+ set(MPI_INCLUDE_PATH_WORK ${MPI_HEADER_PATH})
+
+ # 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)
+ else()
+ set(MS_MPI_ARCH_DIR 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})
+ set(MPI_LIBRARIES_WORK ${MPI_LIB})
+
+ # Right now, we only know about the extra libs for C++.
+ # We could add Fortran here (as there is usually libfmpich, etc.), but
+ # this really only has to work with MS MPI on Windows.
+ # Assume that other MPI's are covered by the compiler wrappers.
+ if (${lang} STREQUAL CXX)
+ set(MPI_LIB "MPI_LIB-NOTFOUND" CACHE FILEPATH "Cleared" FORCE)
+ find_library(MPI_LIB
+ NAMES mpi++ mpicxx cxx mpi_cxx
+ HINTS ${_MPI_BASE_DIR} ${_MPI_PREFIX_PATH}
+ PATH_SUFFIXES lib)
+ if (MPI_LIBRARIES_WORK AND MPI_LIB)
+ list(APPEND MPI_LIBRARIES_WORK ${MPI_LIB})
+ endif()
+ endif()
+
+ if (NOT MPI_LIBRARIES_WORK)
+ set(MPI_LIBRARIES_WORK "MPI_${lang}_LIBRARIES-NOTFOUND")
+ endif()
+ endif()
+
+ # If we found MPI, set up all of the appropriate cache entries
+ set(MPI_${lang}_COMPILE_FLAGS ${MPI_COMPILE_FLAGS_WORK} CACHE STRING "MPI ${lang} compilation flags" FORCE)
+ set(MPI_${lang}_INCLUDE_PATH ${MPI_INCLUDE_PATH_WORK} CACHE STRING "MPI ${lang} include path" FORCE)
+ set(MPI_${lang}_LINK_FLAGS ${MPI_LINK_FLAGS_WORK} CACHE STRING "MPI ${lang} linking flags" FORCE)
+ set(MPI_${lang}_LIBRARIES ${MPI_LIBRARIES_WORK} CACHE STRING "MPI ${lang} libraries to link against" FORCE)
+ mark_as_advanced(MPI_${lang}_COMPILE_FLAGS MPI_${lang}_INCLUDE_PATH MPI_${lang}_LINK_FLAGS MPI_${lang}_LIBRARIES)
+
+ # clear out our temporary lib/header detectionv variable here.
+ set(MPI_LIB "MPI_LIB-NOTFOUND" CACHE INTERNAL "Scratch variable for MPI lib detection" FORCE)
+ set(MPI_HEADER_PATH "MPI_HEADER_PATH-NOTFOUND" CACHE INTERNAL "Scratch variable for MPI header detection" FORCE)
+ endif()
+
+ # finally set a found variable for each MPI language
+ if (MPI_${lang}_INCLUDE_PATH AND MPI_${lang}_LIBRARIES)
+ set(MPI_${lang}_FOUND TRUE PARENT_SCOPE)
+ else()
+ set(MPI_${lang}_FOUND FALSE PARENT_SCOPE)
+ endif()
+endfunction()
+
+
+# This function attempts to compile with the regular compiler, to see if MPI programs
+# work with it. This is a last ditch attempt after we've tried interrogating mpicc and
+# friends, and after we've tried to find generic libraries. Works on machines like
+# Cray XE6, where the modules environment changes what MPI version cc, CC, and ftn use.
+function(try_regular_compiler lang success)
+ set(scratch_directory ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY})
+ if (${lang} STREQUAL Fortran)
+ set(test_file ${scratch_directory}/cmake_mpi_test.f90)
+ file(WRITE ${test_file}
+ "program hello\n"
+ "include 'mpif.h'\n"
+ "integer ierror\n"
+ "call MPI_INIT(ierror)\n"
+ "call MPI_FINALIZE(ierror)\n"
+ "end\n")
+ else()
+ if (${lang} STREQUAL CXX)
+ set(test_file ${scratch_directory}/cmake_mpi_test.cpp)
+ else()
+ set(test_file ${scratch_directory}/cmake_mpi_test.c)
+ endif()
+ file(WRITE ${test_file}
+ "#include <mpi.h>\n"
+ "int main(int argc, char **argv) {\n"
+ " MPI_Init(&argc, &argv);\n"
+ " MPI_Finalize();\n"
+ "}\n")
+ endif()
+ try_compile(compiler_has_mpi ${scratch_directory} ${test_file})
+ if (compiler_has_mpi)
+ set(MPI_${lang}_NO_INTERROGATE ${CMAKE_${lang}_COMPILER} CACHE STRING "Whether to interrogate MPI ${lang} compiler" FORCE)
+ set(MPI_${lang}_COMPILER ${CMAKE_${lang}_COMPILER} CACHE STRING "MPI ${lang} compiler" FORCE)
+ set(MPI_${lang}_COMPILE_FLAGS "" CACHE STRING "MPI ${lang} compilation flags" FORCE)
+ set(MPI_${lang}_INCLUDE_PATH "" CACHE STRING "MPI ${lang} include path" FORCE)
+ set(MPI_${lang}_LINK_FLAGS "" CACHE STRING "MPI ${lang} linking flags" FORCE)
+ set(MPI_${lang}_LIBRARIES "" CACHE STRING "MPI ${lang} libraries to link against" FORCE)
+ endif()
+ set(${success} ${compiler_has_mpi} PARENT_SCOPE)
+ unset(compiler_has_mpi CACHE)
+endfunction()
+
+# End definitions, commence real work here.
+
+# Most mpi distros have some form of mpiexec which gives us something we can reliably look for.
+find_program(MPIEXEC
+ NAMES ${_MPI_EXEC_NAMES}
+ PATHS ${_MPI_PREFIX_PATH}
+ PATH_SUFFIXES bin
+ DOC "Executable for running MPI programs.")
+
+# call get_filename_component twice to remove mpiexec and the directory it exists in (typically bin).
+# This gives us a fairly reliable base directory to search for /bin /lib and /include from.
+get_filename_component(_MPI_BASE_DIR "${MPIEXEC}" PATH)
+get_filename_component(_MPI_BASE_DIR "${_MPI_BASE_DIR}" PATH)
+
+set(MPIEXEC_NUMPROC_FLAG "-np" CACHE STRING "Flag used by MPI to specify the number of processes for MPIEXEC; the next option will be the number of processes.")
+set(MPIEXEC_PREFLAGS "" CACHE STRING "These flags will be directly before the executable that is being run by MPIEXEC.")
+set(MPIEXEC_POSTFLAGS "" CACHE STRING "These flags will come after all flags given to MPIEXEC.")
+set(MPIEXEC_MAX_NUMPROCS "2" CACHE STRING "Maximum number of processors available to run MPI applications.")
+mark_as_advanced(MPIEXEC MPIEXEC_NUMPROC_FLAG MPIEXEC_PREFLAGS MPIEXEC_POSTFLAGS MPIEXEC_MAX_NUMPROCS)
+
+
+#=============================================================================
+# Backward compatibility input hacks. Propagate the FindMPI hints to C and
+# CXX if the respective new versions are not defined. Translate the old
+# MPI_LIBRARY and MPI_EXTRA_LIBRARY to respective MPI_${lang}_LIBRARIES.
+#
+# Once we find the new variables, we translate them back into their old
+# equivalents below.
+foreach (lang C CXX)
+ # Old input variables.
+ set(_MPI_OLD_INPUT_VARS COMPILER COMPILE_FLAGS INCLUDE_PATH LINK_FLAGS)
+
+ # Set new vars based on their old equivalents, if the new versions are not already set.
+ foreach (var ${_MPI_OLD_INPUT_VARS})
+ if (NOT MPI_${lang}_${var} AND MPI_${var})
+ set(MPI_${lang}_${var} "${MPI_${var}}")
+ endif()
+ endforeach()
+
+ # Special handling for MPI_LIBRARY and MPI_EXTRA_LIBRARY, which we nixed in the
+ # new FindMPI. These need to be merged into MPI_<lang>_LIBRARIES
+ if (NOT MPI_${lang}_LIBRARIES AND (MPI_LIBRARY OR MPI_EXTRA_LIBRARY))
+ set(MPI_${lang}_LIBRARIES ${MPI_LIBRARY} ${MPI_EXTRA_LIBRARY})
+ endif()
+endforeach()
+#=============================================================================
+
+
+# This loop finds the compilers and sends them off for interrogation.
+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)
+ # 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()
+ 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})
+ interrogate_mpi_compiler(${lang} ${try_libs})
+ mark_as_advanced(MPI_${lang}_COMPILER)
+
+ # last ditch try -- if nothing works so far, just try running the regular compiler and
+ # see if we can create an MPI executable.
+ set(regular_compiler_worked 0)
+ if (NOT MPI_${lang}_LIBRARIES OR NOT MPI_${lang}_INCLUDE_PATH)
+ try_regular_compiler(${lang} regular_compiler_worked)
+ endif()
+
+ if (regular_compiler_worked)
+ find_package_handle_standard_args(MPI_${lang} DEFAULT_MSG MPI_${lang}_COMPILER)
+ else()
+ find_package_handle_standard_args(MPI_${lang} DEFAULT_MSG MPI_${lang}_LIBRARIES MPI_${lang}_INCLUDE_PATH)
+ endif()
+ endif()
+endforeach()
+
+
+#=============================================================================
+# More backward compatibility stuff
+#
+# Bare MPI sans ${lang} vars are set to CXX then C, depending on what was found.
+# This mimics the behavior of the old language-oblivious FindMPI.
+set(_MPI_OLD_VARS FOUND COMPILER INCLUDE_PATH COMPILE_FLAGS LINK_FLAGS LIBRARIES)
+if (MPI_CXX_FOUND)
+ foreach (var ${_MPI_OLD_VARS})
+ set(MPI_${var} ${MPI_CXX_${var}})
+ endforeach()
+elseif (MPI_C_FOUND)
+ foreach (var ${_MPI_OLD_VARS})
+ set(MPI_${var} ${MPI_C_${var}})
+ endforeach()
+else()
+ # Note that we might still have found Fortran, but you'll need to use MPI_Fortran_FOUND
+ set(MPI_FOUND FALSE)
+endif()
+
+# Chop MPI_LIBRARIES into the old-style MPI_LIBRARY and MPI_EXTRA_LIBRARY, and set them in cache.
+if (MPI_LIBRARIES)
+ list(GET MPI_LIBRARIES 0 MPI_LIBRARY_WORK)
+ set(MPI_LIBRARY ${MPI_LIBRARY_WORK} CACHE FILEPATH "MPI library to link against" FORCE)
+else()
+ set(MPI_LIBRARY "MPI_LIBRARY-NOTFOUND" CACHE FILEPATH "MPI library to link against" FORCE)
+endif()
+
+list(LENGTH MPI_LIBRARIES MPI_NUMLIBS)
+if (MPI_NUMLIBS GREATER 1)
+ set(MPI_EXTRA_LIBRARY_WORK ${MPI_LIBRARIES})
+ list(REMOVE_AT MPI_EXTRA_LIBRARY_WORK 0)
+ set(MPI_EXTRA_LIBRARY ${MPI_EXTRA_LIBRARY_WORK} CACHE STRING "Extra MPI libraries to link against" FORCE)
+else()
+ set(MPI_EXTRA_LIBRARY "MPI_EXTRA_LIBRARY-NOTFOUND" CACHE STRING "Extra MPI libraries to link against" FORCE)
+endif()
+#=============================================================================
+
+# unset these vars to cleanup namespace
+unset(_MPI_OLD_VARS)
+unset(_MPI_PREFIX_PATH)
+unset(_MPI_BASE_DIR)
+foreach (lang C CXX Fortran)
+ unset(_MPI_${lang}_COMPILER_NAMES)
+endforeach()
diff --git a/Modules/FindMatlab.cmake b/Modules/FindMatlab.cmake
new file mode 100644
index 000000000..1cdb07174
--- /dev/null
+++ b/Modules/FindMatlab.cmake
@@ -0,0 +1,120 @@
+# - 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
+
+#=============================================================================
+# 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.)
+
+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")
+ ELSE(${CMAKE_GENERATOR} MATCHES "Visual Studio 6")
+ 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(${CMAKE_GENERATOR} MATCHES "Visual Studio 7")
+ 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(${CMAKE_GENERATOR} MATCHES "Borland")
+ IF(MATLAB_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR "Generator not compatible: ${CMAKE_GENERATOR}")
+ ENDIF(MATLAB_FIND_REQUIRED)
+ ENDIF(${CMAKE_GENERATOR} MATCHES "Borland")
+ ENDIF(${CMAKE_GENERATOR} MATCHES "Visual Studio 7")
+ ENDIF(${CMAKE_GENERATOR} MATCHES "Visual Studio 6")
+ FIND_LIBRARY(MATLAB_MEX_LIBRARY
+ libmex
+ ${MATLAB_ROOT}
+ )
+ FIND_LIBRARY(MATLAB_MX_LIBRARY
+ libmx
+ ${MATLAB_ROOT}
+ )
+ FIND_LIBRARY(MATLAB_ENG_LIBRARY
+ libeng
+ ${MATLAB_ROOT}
+ )
+
+ FIND_PATH(MATLAB_INCLUDE_DIR
+ "mex.h"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MathWorks\\MATLAB\\7.0;MATLABROOT]/extern/include"
+ )
+ELSE( WIN32 )
+ 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/
+ )
+ ELSE(CMAKE_SIZEOF_VOID_P EQUAL 4)
+ # 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/
+ )
+ ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 4)
+ 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(WIN32)
+
+# This is common to UNIX and Win32:
+SET(MATLAB_LIBRARIES
+ ${MATLAB_MEX_LIBRARY}
+ ${MATLAB_MX_LIBRARY}
+ ${MATLAB_ENG_LIBRARY}
+)
+
+IF(MATLAB_INCLUDE_DIR AND MATLAB_LIBRARIES)
+ SET(MATLAB_FOUND 1)
+ENDIF(MATLAB_INCLUDE_DIR AND MATLAB_LIBRARIES)
+
+MARK_AS_ADVANCED(
+ MATLAB_LIBRARIES
+ MATLAB_MEX_LIBRARY
+ MATLAB_MX_LIBRARY
+ MATLAB_ENG_LIBRARY
+ MATLAB_INCLUDE_DIR
+ MATLAB_FOUND
+ MATLAB_ROOT
+)
+
diff --git a/Modules/FindMotif.cmake b/Modules/FindMotif.cmake
new file mode 100644
index 000000000..e35411272
--- /dev/null
+++ b/Modules/FindMotif.cmake
@@ -0,0 +1,44 @@
+# - 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
+
+#=============================================================================
+# 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.)
+
+SET(MOTIF_FOUND 0)
+
+IF(UNIX)
+ FIND_PATH(MOTIF_INCLUDE_DIR
+ Xm/Xm.h
+ /usr/openwin/include
+ )
+
+ FIND_LIBRARY(MOTIF_LIBRARIES
+ Xm
+ /usr/openwin/lib
+ )
+
+ENDIF(UNIX)
+
+# handle the QUIETLY and REQUIRED arguments and set MOTIF_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Motif DEFAULT_MSG MOTIF_LIBRARIES MOTIF_INCLUDE_DIR)
+
+
+MARK_AS_ADVANCED(
+ MOTIF_INCLUDE_DIR
+ MOTIF_LIBRARIES
+)
diff --git a/Modules/FindOpenAL.cmake b/Modules/FindOpenAL.cmake
new file mode 100644
index 000000000..cb3ce4813
--- /dev/null
+++ b/Modules/FindOpenAL.cmake
@@ -0,0 +1,99 @@
+# 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.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software 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 makes the presumption that you are include al.h like
+# #include "al.h"
+# and not
+# #include <AL/al.h>
+# The reason for this is that the latter is not entirely portable.
+# Windows/Creative Labs does not by default put their headers in AL/ and
+# OS X uses the convention <OpenAL/al.h>.
+#
+# For Windows, Creative Labs seems to have added a registry key for their
+# OpenAL 1.1 installer. I have added that key to the list of search paths,
+# however, the key looks like it could be a little fragile depending on
+# if they decide to change the 1.00.0000 number for bug fix releases.
+# Also, they seem to have laid down groundwork for multiple library platforms
+# which puts the library in an extra subdirectory. Currently there is only
+# Win32 and I have hardcoded that here. This may need to be adjusted as
+# platforms are introduced.
+# The OpenAL 1.0 installer doesn't seem to have a useful key I can use.
+# I do not know if the Nvidia OpenAL SDK has a registry key.
+#
+# For OS X, remember that OpenAL was added by Apple in 10.4 (Tiger).
+# To support the framework, I originally wrote special framework detection
+# code in this module which I have now removed with CMake's introduction
+# of native support for frameworks.
+# In addition, OpenAL is open source, and it is possible to compile on Panther.
+# Furthermore, due to bugs in the initial OpenAL release, and the
+# transition to OpenAL 1.1, it is common to need to override the built-in
+# framework.
+# Per my request, CMake should search for frameworks first in
+# the following order:
+# ~/Library/Frameworks/OpenAL.framework/Headers
+# /Library/Frameworks/OpenAL.framework/Headers
+# /System/Library/Frameworks/OpenAL.framework/Headers
+#
+# On OS X, this will prefer the Framework version (if found) over others.
+# People will have to manually change the cache values of
+# OPENAL_LIBRARY to override this selection or set the CMake environment
+# CMAKE_INCLUDE_PATH to modify the search paths.
+
+FIND_PATH(OPENAL_INCLUDE_DIR al.h
+ HINTS
+ $ENV{OPENALDIR}
+ PATH_SUFFIXES include/AL include/OpenAL include
+ PATHS
+ ~/Library/Frameworks
+ /Library/Frameworks
+ /sw # Fink
+ /opt/local # DarwinPorts
+ /opt/csw # Blastwave
+ /opt
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\Creative\ Labs\\OpenAL\ 1.1\ Software\ Development\ Kit\\1.00.0000;InstallDir]
+)
+
+FIND_LIBRARY(OPENAL_LIBRARY
+ NAMES OpenAL al openal OpenAL32
+ HINTS
+ $ENV{OPENALDIR}
+ PATH_SUFFIXES lib64 lib libs64 libs libs/Win32 libs/Win64
+ PATHS
+ ~/Library/Frameworks
+ /Library/Frameworks
+ /sw
+ /opt/local
+ /opt/csw
+ /opt
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\Creative\ Labs\\OpenAL\ 1.1\ Software\ Development\ Kit\\1.00.0000;InstallDir]
+)
+
+
+# handle the QUIETLY and REQUIRED arguments and set OPENAL_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenAL DEFAULT_MSG OPENAL_LIBRARY OPENAL_INCLUDE_DIR)
+
+MARK_AS_ADVANCED(OPENAL_LIBRARY OPENAL_INCLUDE_DIR)
diff --git a/Modules/FindOpenGL.cmake b/Modules/FindOpenGL.cmake
new file mode 100644
index 000000000..98d8808c0
--- /dev/null
+++ b/Modules/FindOpenGL.cmake
@@ -0,0 +1,160 @@
+# - Try to find OpenGL
+# Once done this will define
+#
+# 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
+#
+# 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
+#
+# 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.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software 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 (WIN32)
+ IF (CYGWIN)
+
+ FIND_PATH(OPENGL_INCLUDE_DIR GL/gl.h )
+
+ FIND_LIBRARY(OPENGL_gl_LIBRARY opengl32 )
+
+ FIND_LIBRARY(OPENGL_glu_LIBRARY glu32 )
+
+ ELSE (CYGWIN)
+
+ IF(BORLAND)
+ SET (OPENGL_gl_LIBRARY import32 CACHE STRING "OpenGL library for win32")
+ SET (OPENGL_glu_LIBRARY import32 CACHE STRING "GLU library for win32")
+ ELSE(BORLAND)
+ SET (OPENGL_gl_LIBRARY opengl32 CACHE STRING "OpenGL library for win32")
+ SET (OPENGL_glu_LIBRARY glu32 CACHE STRING "GLU library for win32")
+ ENDIF(BORLAND)
+
+ ENDIF (CYGWIN)
+
+ELSE (WIN32)
+
+ IF (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")
+
+ ELSE(APPLE)
+ # Handle HP-UX cases where we only want to find OpenGL in either hpux64
+ # or hpux32 depending on if we're doing a 64 bit build.
+ IF(CMAKE_SIZEOF_VOID_P EQUAL 4)
+ SET(HPUX_IA_OPENGL_LIB_PATH /opt/graphics/OpenGL/lib/hpux32/)
+ ELSE(CMAKE_SIZEOF_VOID_P EQUAL 4)
+ SET(HPUX_IA_OPENGL_LIB_PATH
+ /opt/graphics/OpenGL/lib/hpux64/
+ /opt/graphics/OpenGL/lib/pa20_64)
+ ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 4)
+
+ # The first line below is to make sure that the proper headers
+ # are used on a Linux machine with the NVidia drivers installed.
+ # They replace Mesa with NVidia's own library but normally do not
+ # install headers and that causes the linking to
+ # fail since the compiler finds the Mesa headers but NVidia's library.
+ # Make sure the NVIDIA directory comes BEFORE the others.
+ # - Atanas Georgiev <atanas@cs.columbia.edu>
+
+ FIND_PATH(OPENGL_INCLUDE_DIR GL/gl.h
+ /usr/share/doc/NVIDIA_GLX-1.0/include
+ /usr/openwin/share/include
+ /opt/graphics/OpenGL/include /usr/X11R6/include
+ )
+
+ FIND_PATH(OPENGL_xmesa_INCLUDE_DIR GL/xmesa.h
+ /usr/share/doc/NVIDIA_GLX-1.0/include
+ /usr/openwin/share/include
+ /opt/graphics/OpenGL/include /usr/X11R6/include
+ )
+
+ FIND_LIBRARY(OPENGL_gl_LIBRARY
+ NAMES GL MesaGL
+ PATHS /opt/graphics/OpenGL/lib
+ /usr/openwin/lib
+ /usr/shlib /usr/X11R6/lib
+ ${HPUX_IA_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.
+ # It's not true on OSX.
+
+ IF (OPENGL_gl_LIBRARY)
+ IF(NOT X11_FOUND)
+ INCLUDE(FindX11)
+ ENDIF(NOT X11_FOUND)
+ IF (X11_FOUND)
+ IF (NOT APPLE)
+ SET (OPENGL_LIBRARIES ${X11_LIBRARIES})
+ ENDIF (NOT APPLE)
+ ENDIF (X11_FOUND)
+ ENDIF (OPENGL_gl_LIBRARY)
+
+ FIND_LIBRARY(OPENGL_glu_LIBRARY
+ NAMES GLU MesaGLU
+ PATHS ${OPENGL_gl_LIBRARY}
+ /opt/graphics/OpenGL/lib
+ /usr/openwin/lib
+ /usr/shlib /usr/X11R6/lib
+ )
+
+ ENDIF(APPLE)
+ENDIF (WIN32)
+
+IF(OPENGL_gl_LIBRARY)
+
+ IF(OPENGL_xmesa_INCLUDE_DIR)
+ SET( OPENGL_XMESA_FOUND "YES" )
+ ELSE(OPENGL_xmesa_INCLUDE_DIR)
+ SET( OPENGL_XMESA_FOUND "NO" )
+ ENDIF(OPENGL_xmesa_INCLUDE_DIR)
+
+ 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} )
+ ELSE(OPENGL_glu_LIBRARY)
+ SET( OPENGL_GLU_FOUND "NO" )
+ ENDIF(OPENGL_glu_LIBRARY)
+
+ # This deprecated setting is for backward compatibility with CMake1.4
+ SET (OPENGL_LIBRARY ${OPENGL_LIBRARIES})
+
+ENDIF(OPENGL_gl_LIBRARY)
+
+# This deprecated setting is for backward compatibility with CMake1.4
+SET(OPENGL_INCLUDE_PATH ${OPENGL_INCLUDE_DIR})
+
+# handle the QUIETLY and REQUIRED arguments and set OPENGL_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenGL DEFAULT_MSG OPENGL_gl_LIBRARY)
+
+MARK_AS_ADVANCED(
+ OPENGL_INCLUDE_DIR
+ OPENGL_xmesa_INCLUDE_DIR
+ OPENGL_glu_LIBRARY
+ OPENGL_gl_LIBRARY
+)
diff --git a/Modules/FindOpenMP.cmake b/Modules/FindOpenMP.cmake
new file mode 100644
index 000000000..b96a2ecfb
--- /dev/null
+++ b/Modules/FindOpenMP.cmake
@@ -0,0 +1,167 @@
+# - 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 set.
+#
+# 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/
+
+#=============================================================================
+# Copyright 2009 Kitware, Inc.
+# Copyright 2008-2009 André Rigland Brodtkorb <Andre.Brodtkorb@ifi.uio.no>
+# Copyright 2012 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.)
+
+set(_OPENMP_REQUIRED_VARS)
+
+function(_OPENMP_FLAG_CANDIDATES LANG)
+ set(OpenMP_FLAG_CANDIDATES
+ #GNU
+ "-fopenmp"
+ #Microsoft Visual Studio
+ "/openmp"
+ #Intel windows
+ "-Qopenmp"
+ #PathScale, Intel
+ "-openmp"
+ #Empty, if compiler automatically accepts openmp
+ " "
+ #Sun
+ "-xopenmp"
+ #HP
+ "+Oopenmp"
+ #IBM XL C/c++
+ "-qsmp"
+ #Portland Group, MIPSpro
+ "-mp"
+ )
+
+ set(OMP_FLAG_GNU "-fopenmp")
+ set(OMP_FLAG_HP "+Oopenmp")
+ if(WIN32)
+ set(OMP_FLAG_Intel "-Qopenmp")
+ else()
+ set(OMP_FLAG_Intel "-openmp")
+ endif()
+ set(OMP_FLAG_MIPSpro "-mp")
+ set(OMP_FLAG_MSVC "/openmp")
+ set(OMP_FLAG_PathScale "-openmp")
+ set(OMP_FLAG_PGI "-mp")
+ set(OMP_FLAG_SunPro "-xopenmp")
+ set(OMP_FLAG_XL "-qsmp")
+
+ # Move the flag that matches the compiler to the head of the list,
+ # this is faster and doesn't clutter the output that much. If that
+ # flag doesn't work we will still try all.
+ if(OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID})
+ list(REMOVE_ITEM OpenMP_FLAG_CANDIDATES "${OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID}}")
+ list(INSERT OpenMP_FLAG_CANDIDATES 0 "${OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID}}")
+ endif()
+
+ set(OpenMP_${LANG}_FLAG_CANDIDATES "${OpenMP_FLAG_CANDIDATES}" PARENT_SCOPE)
+endfunction(_OPENMP_FLAG_CANDIDATES)
+
+# sample openmp source code to test
+set(OpenMP_C_TEST_SOURCE
+"
+#include <omp.h>
+int main() {
+#ifdef _OPENMP
+ return 0;
+#else
+ breaks_on_purpose
+#endif
+}
+")
+
+# check c compiler
+if(CMAKE_C_COMPILER_LOADED)
+ # if these are set then do not try to find them again,
+ # by avoiding any try_compiles for the flags
+ if(OpenMP_C_FLAGS)
+ unset(OpenMP_C_FLAG_CANDIDATES)
+ else()
+ _OPENMP_FLAG_CANDIDATES("C")
+ include(CheckCSourceCompiles)
+ endif()
+
+ foreach(FLAG ${OpenMP_C_FLAG_CANDIDATES})
+ 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}]")
+ check_c_source_compiles("${OpenMP_C_TEST_SOURCE}" OpenMP_FLAG_DETECTED)
+ set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}")
+ if(OpenMP_FLAG_DETECTED)
+ set(OpenMP_C_FLAGS_INTERNAL "${FLAG}")
+ break()
+ endif(OpenMP_FLAG_DETECTED)
+ endforeach(FLAG ${OpenMP_C_FLAG_CANDIDATES})
+
+ set(OpenMP_C_FLAGS "${OpenMP_C_FLAGS_INTERNAL}"
+ CACHE STRING "C compiler flags for OpenMP parallization")
+
+ list(APPEND _OPENMP_REQUIRED_VARS OpenMP_C_FLAGS)
+ unset(OpenMP_C_FLAG_CANDIDATES)
+endif()
+
+# check cxx compiler
+if(CMAKE_CXX_COMPILER_LOADED)
+ # if these are set then do not try to find them again,
+ # by avoiding any try_compiles for the flags
+ if(OpenMP_CXX_FLAGS)
+ unset(OpenMP_CXX_FLAG_CANDIDATES)
+ else()
+ _OPENMP_FLAG_CANDIDATES("CXX")
+ include(CheckCXXSourceCompiles)
+
+ # use the same source for CXX as C for now
+ set(OpenMP_CXX_TEST_SOURCE ${OpenMP_C_TEST_SOURCE})
+ endif()
+
+ foreach(FLAG ${OpenMP_CXX_FLAG_CANDIDATES})
+ 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}]")
+ check_cxx_source_compiles("${OpenMP_CXX_TEST_SOURCE}" OpenMP_FLAG_DETECTED)
+ set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}")
+ if(OpenMP_FLAG_DETECTED)
+ set(OpenMP_CXX_FLAGS_INTERNAL "${FLAG}")
+ break()
+ endif(OpenMP_FLAG_DETECTED)
+ endforeach(FLAG ${OpenMP_CXX_FLAG_CANDIDATES})
+
+ set(OpenMP_CXX_FLAGS "${OpenMP_CXX_FLAGS_INTERNAL}"
+ CACHE STRING "C++ compiler flags for OpenMP parallization")
+
+ list(APPEND _OPENMP_REQUIRED_VARS OpenMP_CXX_FLAGS)
+ unset(OpenMP_CXX_FLAG_CANDIDATES)
+ unset(OpenMP_CXX_TEST_SOURCE)
+endif()
+
+if(_OPENMP_REQUIRED_VARS)
+ include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+
+ find_package_handle_standard_args(OpenMP
+ REQUIRED_VARS ${_OPENMP_REQUIRED_VARS})
+
+ mark_as_advanced(${_OPENMP_REQUIRED_VARS})
+
+ unset(_OPENMP_REQUIRED_VARS)
+else()
+ message(SEND_ERROR "FindOpenMP requires C or CXX language to be enabled")
+endif()
diff --git a/Modules/FindOpenSSL.cmake b/Modules/FindOpenSSL.cmake
new file mode 100644
index 000000000..d1fc2d259
--- /dev/null
+++ b/Modules/FindOpenSSL.cmake
@@ -0,0 +1,304 @@
+# - Try to find the OpenSSL encryption library
+# Once done this will define
+#
+# OPENSSL_ROOT_DIR - Set this variable to the root installation of OpenSSL
+#
+# 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)
+
+#=============================================================================
+# Copyright 2006-2009 Kitware, Inc.
+# Copyright 2006 Alexander Neundorf <neundorf@kde.org>
+# Copyright 2009-2011 Mathieu Malaterre <mathieu.malaterre@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.)
+
+if (UNIX)
+ find_package(PkgConfig QUIET)
+ pkg_check_modules(_OPENSSL QUIET openssl)
+endif (UNIX)
+
+# http://www.slproweb.com/products/Win32OpenSSL.html
+SET(_OPENSSL_ROOT_HINTS
+ $ENV{OPENSSL_ROOT_DIR}
+ ${OPENSSL_ROOT_DIR}
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (32-bit)_is1;Inno Setup: App Path]"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (64-bit)_is1;Inno Setup: App Path]"
+ )
+SET(_OPENSSL_ROOT_PATHS
+ "$ENV{PROGRAMFILES}/OpenSSL"
+ "$ENV{PROGRAMFILES}/OpenSSL-Win32"
+ "$ENV{PROGRAMFILES}/OpenSSL-Win64"
+ "C:/OpenSSL/"
+ "C:/OpenSSL-Win32/"
+ "C:/OpenSSL-Win64/"
+ )
+SET(_OPENSSL_ROOT_HINTS_AND_PATHS
+ HINTS ${_OPENSSL_ROOT_HINTS}
+ PATHS ${_OPENSSL_ROOT_PATHS}
+ )
+
+FIND_PATH(OPENSSL_INCLUDE_DIR
+ NAMES
+ openssl/ssl.h
+ HINTS
+ ${_OPENSSL_INCLUDEDIR}
+ ${_OPENSSL_ROOT_HINTS_AND_PATHS}
+ PATH_SUFFIXES
+ include
+)
+
+IF(WIN32 AND NOT CYGWIN)
+ # MINGW should go here too
+ IF(MSVC)
+ # /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
+ # 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
+ # * MT for static-release
+ # * MTd for static-debug
+
+ # Implementation details:
+ # 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
+ FIND_LIBRARY(LIB_EAY_DEBUG
+ NAMES
+ libeay32MDd
+ libeay32
+ ${_OPENSSL_ROOT_HINTS_AND_PATHS}
+ PATH_SUFFIXES
+ "lib"
+ "VC"
+ "lib/VC"
+ )
+
+ FIND_LIBRARY(LIB_EAY_RELEASE
+ NAMES
+ libeay32MD
+ libeay32
+ ${_OPENSSL_ROOT_HINTS_AND_PATHS}
+ PATH_SUFFIXES
+ "lib"
+ "VC"
+ "lib/VC"
+ )
+
+ FIND_LIBRARY(SSL_EAY_DEBUG
+ NAMES
+ ssleay32MDd
+ ssleay32
+ ssl
+ ${_OPENSSL_ROOT_HINTS_AND_PATHS}
+ PATH_SUFFIXES
+ "lib"
+ "VC"
+ "lib/VC"
+ )
+
+ FIND_LIBRARY(SSL_EAY_RELEASE
+ NAMES
+ ssleay32MD
+ ssleay32
+ ssl
+ ${_OPENSSL_ROOT_HINTS_AND_PATHS}
+ PATH_SUFFIXES
+ "lib"
+ "VC"
+ "lib/VC"
+ )
+
+ if( CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE )
+ set( OPENSSL_LIBRARIES
+ optimized ${SSL_EAY_RELEASE} debug ${SSL_EAY_DEBUG}
+ optimized ${LIB_EAY_RELEASE} debug ${LIB_EAY_DEBUG}
+ )
+ else()
+ set( OPENSSL_LIBRARIES ${SSL_EAY_RELEASE} ${LIB_EAY_RELEASE} )
+ endif()
+ MARK_AS_ADVANCED(SSL_EAY_DEBUG SSL_EAY_RELEASE)
+ MARK_AS_ADVANCED(LIB_EAY_DEBUG LIB_EAY_RELEASE)
+ ELSEIF(MINGW)
+ # same player, for MingW
+ FIND_LIBRARY(LIB_EAY
+ NAMES
+ libeay32
+ ${_OPENSSL_ROOT_HINTS_AND_PATHS}
+ PATH_SUFFIXES
+ "lib"
+ "lib/MinGW"
+ )
+
+ FIND_LIBRARY(SSL_EAY
+ NAMES
+ ssleay32
+ ${_OPENSSL_ROOT_HINTS_AND_PATHS}
+ PATH_SUFFIXES
+ "lib"
+ "lib/MinGW"
+ )
+
+ MARK_AS_ADVANCED(SSL_EAY LIB_EAY)
+ set( OPENSSL_LIBRARIES ${SSL_EAY} ${LIB_EAY} )
+ ELSE(MSVC)
+ # Not sure what to pick for -say- intel, let's use the toplevel ones and hope someone report issues:
+ FIND_LIBRARY(LIB_EAY
+ NAMES
+ libeay32
+ HINTS
+ ${_OPENSSL_LIBDIR}
+ ${_OPENSSL_ROOT_HINTS_AND_PATHS}
+ PATH_SUFFIXES
+ lib
+ )
+
+ FIND_LIBRARY(SSL_EAY
+ NAMES
+ ssleay32
+ 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} )
+ ENDIF(MSVC)
+ELSE(WIN32 AND NOT CYGWIN)
+
+ FIND_LIBRARY(OPENSSL_SSL_LIBRARY
+ NAMES
+ ssl
+ ssleay32
+ ssleay32MD
+ HINTS
+ ${_OPENSSL_LIBDIR}
+ ${_OPENSSL_ROOT_HINTS_AND_PATHS}
+ PATH_SUFFIXES
+ lib
+ )
+
+ FIND_LIBRARY(OPENSSL_CRYPTO_LIBRARY
+ NAMES
+ crypto
+ HINTS
+ ${_OPENSSL_LIBDIR}
+ ${_OPENSSL_ROOT_HINTS_AND_PATHS}
+ PATH_SUFFIXES
+ lib
+ )
+
+ MARK_AS_ADVANCED(OPENSSL_CRYPTO_LIBRARY OPENSSL_SSL_LIBRARY)
+
+ # compat defines
+ SET(OPENSSL_SSL_LIBRARIES ${OPENSSL_SSL_LIBRARY})
+ SET(OPENSSL_CRYPTO_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
+
+ SET(OPENSSL_LIBRARIES ${OPENSSL_SSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY})
+
+ENDIF(WIN32 AND NOT CYGWIN)
+
+function(from_hex HEX DEC)
+ string(TOUPPER "${HEX}" HEX)
+ set(_res 0)
+ string(LENGTH "${HEX}" _strlen)
+
+ while (_strlen GREATER 0)
+ math(EXPR _res "${_res} * 16")
+ string(SUBSTRING "${HEX}" 0 1 NIBBLE)
+ string(SUBSTRING "${HEX}" 1 -1 HEX)
+ if (NIBBLE STREQUAL "A")
+ math(EXPR _res "${_res} + 10")
+ elseif (NIBBLE STREQUAL "B")
+ math(EXPR _res "${_res} + 11")
+ elseif (NIBBLE STREQUAL "C")
+ math(EXPR _res "${_res} + 12")
+ elseif (NIBBLE STREQUAL "D")
+ math(EXPR _res "${_res} + 13")
+ elseif (NIBBLE STREQUAL "E")
+ math(EXPR _res "${_res} + 14")
+ elseif (NIBBLE STREQUAL "F")
+ math(EXPR _res "${_res} + 15")
+ else()
+ math(EXPR _res "${_res} + ${NIBBLE}")
+ endif()
+
+ string(LENGTH "${HEX}" _strlen)
+ endwhile()
+
+ set(${DEC} ${_res} PARENT_SCOPE)
+endfunction(from_hex)
+
+if (OPENSSL_INCLUDE_DIR)
+ if (_OPENSSL_VERSION)
+ set(OPENSSL_VERSION "${_OPENSSL_VERSION}")
+ elseif(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])+.*")
+
+ # 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.
+ # Major, minor, and fix directly translate into the version numbers shown in
+ # the string. The patch field translates to the single character suffix that
+ # indicates the bug fix state, which 00 -> nothing, 01 -> a, 02 -> b and so
+ # on.
+
+ string(REGEX REPLACE "^.*OPENSSL_VERSION_NUMBER[\t ]+0x([0-9a-fA-F])([0-9a-fA-F][0-9a-fA-F])([0-9a-fA-F][0-9a-fA-F])([0-9a-fA-F][0-9a-fA-F])([0-9a-fA-F]).*$"
+ "\\1;\\2;\\3;\\4;\\5" OPENSSL_VERSION_LIST "${openssl_version_str}")
+ list(GET OPENSSL_VERSION_LIST 0 OPENSSL_VERSION_MAJOR)
+ list(GET OPENSSL_VERSION_LIST 1 OPENSSL_VERSION_MINOR)
+ from_hex("${OPENSSL_VERSION_MINOR}" OPENSSL_VERSION_MINOR)
+ list(GET OPENSSL_VERSION_LIST 2 OPENSSL_VERSION_FIX)
+ from_hex("${OPENSSL_VERSION_FIX}" OPENSSL_VERSION_FIX)
+ list(GET OPENSSL_VERSION_LIST 3 OPENSSL_VERSION_PATCH)
+
+ if (NOT OPENSSL_VERSION_PATCH STREQUAL "00")
+ from_hex("${OPENSSL_VERSION_PATCH}" _tmp)
+ # 96 is the ASCII code of 'a' minus 1
+ math(EXPR OPENSSL_VERSION_PATCH_ASCII "${_tmp} + 96")
+ unset(_tmp)
+ # Once anyone knows how OpenSSL would call the patch versions beyond 'z'
+ # this should be updated to handle that, too. This has not happened yet
+ # so it is simply ignored here for now.
+ string(ASCII "${OPENSSL_VERSION_PATCH_ASCII}" OPENSSL_VERSION_PATCH_STRING)
+ endif (NOT OPENSSL_VERSION_PATCH STREQUAL "00")
+
+ set(OPENSSL_VERSION "${OPENSSL_VERSION_MAJOR}.${OPENSSL_VERSION_MINOR}.${OPENSSL_VERSION_FIX}${OPENSSL_VERSION_PATCH_STRING}")
+ endif (_OPENSSL_VERSION)
+endif (OPENSSL_INCLUDE_DIR)
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+
+if (OPENSSL_VERSION)
+ find_package_handle_standard_args(OpenSSL
+ REQUIRED_VARS
+ OPENSSL_LIBRARIES
+ OPENSSL_INCLUDE_DIR
+ VERSION_VAR
+ OPENSSL_VERSION
+ FAIL_MESSAGE
+ "Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the system variable OPENSSL_ROOT_DIR"
+ )
+else (OPENSSL_VERSION)
+ find_package_handle_standard_args(OpenSSL "Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the system variable OPENSSL_ROOT_DIR"
+ OPENSSL_LIBRARIES
+ OPENSSL_INCLUDE_DIR
+ )
+endif (OPENSSL_VERSION)
+
+MARK_AS_ADVANCED(OPENSSL_INCLUDE_DIR OPENSSL_LIBRARIES)
diff --git a/Modules/FindOpenSceneGraph.cmake b/Modules/FindOpenSceneGraph.cmake
new file mode 100644
index 000000000..52f931689
--- /dev/null
+++ b/Modules/FindOpenSceneGraph.cmake
@@ -0,0 +1,246 @@
+# - 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_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
+#
+# This module defines the following output variables:
+#
+# 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
+#
+#==================================
+# 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.
+# Copyright 2009 Philip Lowman <philip@yhbt.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.)
+
+#
+# Naming convention:
+# Local variables of the form _osg_foo
+# Input variables of the form OpenSceneGraph_FOO
+# Output variables of the form OPENSCENEGRAPH_FOO
+#
+
+include(Findosg_functions)
+
+set(_osg_modules_to_process)
+foreach(_osg_component ${OpenSceneGraph_FIND_COMPONENTS})
+ list(APPEND _osg_modules_to_process ${_osg_component})
+endforeach()
+list(APPEND _osg_modules_to_process "osg" "OpenThreads")
+list(REMOVE_DUPLICATES _osg_modules_to_process)
+
+if(OpenSceneGraph_DEBUG)
+ message(STATUS "[ FindOpenSceneGraph.cmake:${CMAKE_CURRENT_LIST_LINE} ] "
+ "Components = ${_osg_modules_to_process}")
+endif()
+
+#
+# First we need to find and parse osg/Version
+#
+OSG_FIND_PATH(OSG osg/Version)
+if(OpenSceneGraph_MARK_AS_ADVANCED)
+ OSG_MARK_AS_ADVANCED(OSG)
+endif()
+
+# Try to ascertain the version...
+if(OSG_INCLUDE_DIR)
+ if(OpenSceneGraph_DEBUG)
+ message(STATUS "[ FindOpenSceneGraph.cmake:${CMAKE_CURRENT_LIST_LINE} ] "
+ "Detected OSG_INCLUDE_DIR = ${OSG_INCLUDE_DIR}")
+ endif()
+
+ set(_osg_Version_file "${OSG_INCLUDE_DIR}/osg/Version")
+ if("${OSG_INCLUDE_DIR}" MATCHES "\\.framework$" AND NOT EXISTS "${_osg_Version_file}")
+ set(_osg_Version_file "${OSG_INCLUDE_DIR}/Headers/Version")
+ endif()
+
+ if(EXISTS "${_osg_Version_file}")
+ file(READ "${_osg_Version_file}" _osg_Version_contents)
+ else()
+ set(_osg_Version_contents "unknown")
+ endif()
+
+ string(REGEX MATCH ".*#define OSG_VERSION_MAJOR[ \t]+[0-9]+.*"
+ _osg_old_defines "${_osg_Version_contents}")
+ string(REGEX MATCH ".*#define OPENSCENEGRAPH_MAJOR_VERSION[ \t]+[0-9]+.*"
+ _osg_new_defines "${_osg_Version_contents}")
+ if(_osg_old_defines)
+ string(REGEX REPLACE ".*#define OSG_VERSION_MAJOR[ \t]+([0-9]+).*"
+ "\\1" _osg_VERSION_MAJOR ${_osg_Version_contents})
+ string(REGEX REPLACE ".*#define OSG_VERSION_MINOR[ \t]+([0-9]+).*"
+ "\\1" _osg_VERSION_MINOR ${_osg_Version_contents})
+ string(REGEX REPLACE ".*#define OSG_VERSION_PATCH[ \t]+([0-9]+).*"
+ "\\1" _osg_VERSION_PATCH ${_osg_Version_contents})
+ elseif(_osg_new_defines)
+ string(REGEX REPLACE ".*#define OPENSCENEGRAPH_MAJOR_VERSION[ \t]+([0-9]+).*"
+ "\\1" _osg_VERSION_MAJOR ${_osg_Version_contents})
+ string(REGEX REPLACE ".*#define OPENSCENEGRAPH_MINOR_VERSION[ \t]+([0-9]+).*"
+ "\\1" _osg_VERSION_MINOR ${_osg_Version_contents})
+ string(REGEX REPLACE ".*#define OPENSCENEGRAPH_PATCH_VERSION[ \t]+([0-9]+).*"
+ "\\1" _osg_VERSION_PATCH ${_osg_Version_contents})
+ else()
+ message(WARNING "[ FindOpenSceneGraph.cmake:${CMAKE_CURRENT_LIST_LINE} ] "
+ "Failed to parse version number, please report this as a bug")
+ endif()
+
+ set(OPENSCENEGRAPH_VERSION "${_osg_VERSION_MAJOR}.${_osg_VERSION_MINOR}.${_osg_VERSION_PATCH}"
+ CACHE INTERNAL "The version of OSG which was detected")
+ if(OpenSceneGraph_DEBUG)
+ message(STATUS "[ FindOpenSceneGraph.cmake:${CMAKE_CURRENT_LIST_LINE} ] "
+ "Detected version ${OPENSCENEGRAPH_VERSION}")
+ endif()
+endif()
+
+#
+# Version checking
+#
+if(OpenSceneGraph_FIND_VERSION AND OPENSCENEGRAPH_VERSION)
+ if(OpenSceneGraph_FIND_VERSION_EXACT)
+ if(NOT OPENSCENEGRAPH_VERSION VERSION_EQUAL ${OpenSceneGraph_FIND_VERSION})
+ set(_osg_version_not_exact TRUE)
+ endif()
+ else()
+ # version is too low
+ if(NOT OPENSCENEGRAPH_VERSION VERSION_EQUAL ${OpenSceneGraph_FIND_VERSION} AND
+ NOT OPENSCENEGRAPH_VERSION VERSION_GREATER ${OpenSceneGraph_FIND_VERSION})
+ set(_osg_version_not_high_enough TRUE)
+ endif()
+ endif()
+endif()
+
+set(_osg_quiet)
+if(OpenSceneGraph_FIND_QUIETLY)
+ set(_osg_quiet "QUIET")
+endif()
+#
+# Here we call FIND_PACKAGE() on all of the components
+#
+foreach(_osg_module ${_osg_modules_to_process})
+ if(OpenSceneGraph_DEBUG)
+ message(STATUS "[ FindOpenSceneGraph.cmake:${CMAKE_CURRENT_LIST_LINE} ] "
+ "Calling find_package(${_osg_module} ${_osg_required} ${_osg_quiet})")
+ endif()
+ 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})
+
+ if(OpenSceneGraph_MARK_AS_ADVANCED)
+ OSG_MARK_AS_ADVANCED(${_osg_module})
+ endif()
+endforeach()
+
+if(OPENSCENEGRAPH_INCLUDE_DIR)
+ list(REMOVE_DUPLICATES OPENSCENEGRAPH_INCLUDE_DIR)
+endif()
+
+#
+# Inform the users with an error message based on
+# what version they have vs. what version was
+# required.
+#
+if(OpenSceneGraph_FIND_REQUIRED)
+ set(_osg_version_output_type FATAL_ERROR)
+else()
+ set(_osg_version_output_type STATUS)
+endif()
+if(_osg_version_not_high_enough)
+ set(_osg_EPIC_FAIL TRUE)
+ if(NOT OpenSceneGraph_FIND_QUIETLY)
+ message(${_osg_version_output_type}
+ "ERROR: Version ${OpenSceneGraph_FIND_VERSION} or higher of the OSG "
+ "is required. Version ${OPENSCENEGRAPH_VERSION} was found.")
+ endif()
+elseif(_osg_version_not_exact)
+ set(_osg_EPIC_FAIL TRUE)
+ if(NOT OpenSceneGraph_FIND_QUIETLY)
+ message(${_osg_version_output_type}
+ "ERROR: Version ${OpenSceneGraph_FIND_VERSION} of the OSG is required "
+ "(exactly), version ${OPENSCENEGRAPH_VERSION} was found.")
+ endif()
+else()
+
+ #
+ # Check each module to see if it's found
+ #
+ if(OpenSceneGraph_FIND_REQUIRED)
+ set(_osg_missing_message)
+ foreach(_osg_module ${_osg_modules_to_process})
+ string(TOUPPER ${_osg_module} _osg_module_UC)
+ if(NOT ${_osg_module_UC}_FOUND)
+ set(_osg_missing_nodekit_fail true)
+ set(_osg_missing_message "${_osg_missing_message} ${_osg_module}")
+ endif()
+ endforeach()
+
+ if(_osg_missing_nodekit_fail)
+ message(FATAL_ERROR "ERROR: Missing the following osg "
+ "libraries: ${_osg_missing_message}.\n"
+ "Consider using CMAKE_PREFIX_PATH or the OSG_DIR "
+ "environment variable. See the "
+ "${CMAKE_CURRENT_LIST_FILE} for more details.")
+ endif()
+ endif()
+
+ include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+ FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenSceneGraph DEFAULT_MSG OPENSCENEGRAPH_LIBRARIES OPENSCENEGRAPH_INCLUDE_DIR)
+endif()
+
+if(_osg_EPIC_FAIL)
+ # Zero out everything, we didn't meet version requirements
+ set(OPENSCENEGRAPH_FOUND FALSE)
+ set(OPENSCENEGRAPH_LIBRARIES)
+ set(OPENSCENEGRAPH_INCLUDE_DIR)
+endif()
+
+set(OPENSCENEGRAPH_INCLUDE_DIRS ${OPENSCENEGRAPH_INCLUDE_DIR})
+
diff --git a/Modules/FindOpenThreads.cmake b/Modules/FindOpenThreads.cmake
new file mode 100644
index 000000000..6b81fbe3a
--- /dev/null
+++ b/Modules/FindOpenThreads.cmake
@@ -0,0 +1,123 @@
+# 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.
+#
+# 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.
+#
+# Created by Eric Wing.
+
+#=============================================================================
+# 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.)
+
+# Header files are presumed to be included like
+# #include <OpenThreads/Thread>
+
+# To make it easier for one-step automated configuration/builds,
+# we leverage environmental paths. This is preferable
+# to the -DVAR=value switches because it insulates the
+# users from changes we may make in this script.
+# It also offers a little more flexibility than setting
+# the CMAKE_*_PATH since we can target specific components.
+# However, the default CMake behavior will search system paths
+# before anything else. This is problematic in the cases
+# where you have an older (stable) version installed, but
+# are trying to build a newer version.
+# CMake doesn't offer a nice way to globally control this behavior
+# so we have to do a nasty "double FIND_" in this module.
+# The first FIND disables the CMAKE_ search paths and only checks
+# the environmental paths.
+# If nothing is found, then the second find will search the
+# standard install paths.
+# Explicit -DVAR=value arguments should still be able to override everything.
+
+find_path(OPENTHREADS_INCLUDE_DIR OpenThreads/Thread
+ HINTS
+ # enough environment variables?
+ $ENV{OPENTHREADS_INCLUDE_DIR}
+ $ENV{OPENTHREADS_DIR}
+ $ENV{OSG_INCLUDE_DIR}
+ $ENV{OSG_DIR}
+ $ENV{OSGDIR}
+ $ENV{OpenThreads_ROOT}
+ $ENV{OSG_ROOT}
+ PATHS
+ /sw # Fink
+ /opt/local # DarwinPorts
+ /opt/csw # Blastwave
+ /opt
+ /usr/freeware
+ PATH_SUFFIXES include
+)
+
+
+find_library(OPENTHREADS_LIBRARY
+ NAMES OpenThreads OpenThreadsWin32
+ HINTS
+ $ENV{OPENTHREADS_LIBRARY_DIR}
+ $ENV{OPENTHREADS_DIR}
+ $ENV{OSG_LIBRARY_DIR}
+ $ENV{OSG_DIR}
+ $ENV{OSGDIR}
+ $ENV{OpenThreads_ROOT}
+ $ENV{OSG_ROOT}
+ PATHS
+ /sw
+ /opt/local
+ /opt/csw
+ /opt
+ /usr/freeware
+ PATH_SUFFIXES lib64 lib
+)
+
+find_library(OPENTHREADS_LIBRARY_DEBUG
+ NAMES OpenThreadsd OpenThreadsWin32d
+ HINTS
+ $ENV{OPENTHREADS_DEBUG_LIBRARY_DIR}
+ $ENV{OPENTHREADS_LIBRARY_DIR}
+ $ENV{OPENTHREADS_DIR}
+ $ENV{OSG_LIBRARY_DIR}
+ $ENV{OSG_DIR}
+ $ENV{OSGDIR}
+ $ENV{OpenThreads_ROOT}
+ $ENV{OSG_ROOT}
+ PATHS
+ /sw
+ /opt/local
+ /opt/csw
+ /opt
+ /usr/freeware
+ PATH_SUFFIXES lib64 lib
+)
+
+if(OPENTHREADS_LIBRARY_DEBUG)
+ set(OPENTHREADS_LIBRARIES
+ optimized ${OPENTHREADS_LIBRARY}
+ debug ${OPENTHREADS_LIBRARY_DEBUG})
+else()
+ set(OPENTHREADS_LIBRARIES ${OPENTHREADS_LIBRARY})
+endif()
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenThreads DEFAULT_MSG
+ OPENTHREADS_LIBRARY OPENTHREADS_INCLUDE_DIR)
diff --git a/Modules/FindPHP4.cmake b/Modules/FindPHP4.cmake
new file mode 100644
index 000000000..6c2965a7a
--- /dev/null
+++ b/Modules/FindPHP4.cmake
@@ -0,0 +1,85 @@
+# - 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.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software 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(PHP4_POSSIBLE_INCLUDE_PATHS
+ /usr/include/php4
+ /usr/local/include/php4
+ /usr/include/php
+ /usr/local/include/php
+ /usr/local/apache/php
+ )
+
+SET(PHP4_POSSIBLE_LIB_PATHS
+ /usr/lib
+ )
+
+FIND_PATH(PHP4_FOUND_INCLUDE_PATH main/php.h
+ ${PHP4_POSSIBLE_INCLUDE_PATHS})
+
+IF(PHP4_FOUND_INCLUDE_PATH)
+ SET(php4_paths "${PHP4_POSSIBLE_INCLUDE_PATHS}")
+ FOREACH(php4_path Zend main TSRM)
+ SET(php4_paths ${php4_paths} "${PHP4_FOUND_INCLUDE_PATH}/${php4_path}")
+ ENDFOREACH(php4_path Zend main TSRM)
+ SET(PHP4_INCLUDE_PATH "${php4_paths}" INTERNAL "PHP4 include paths")
+ENDIF(PHP4_FOUND_INCLUDE_PATH)
+
+FIND_PROGRAM(PHP4_EXECUTABLE NAMES php4 php )
+
+MARK_AS_ADVANCED(
+ PHP4_EXECUTABLE
+ PHP4_FOUND_INCLUDE_PATH
+ )
+
+IF(APPLE)
+# this is a hack for now
+ SET(CMAKE_SHARED_MODULE_CREATE_C_FLAGS
+ "${CMAKE_SHARED_MODULE_CREATE_C_FLAGS} -Wl,-flat_namespace")
+ FOREACH(symbol
+ __efree
+ __emalloc
+ __estrdup
+ __object_init_ex
+ __zend_get_parameters_array_ex
+ __zend_list_find
+ __zval_copy_ctor
+ _add_property_zval_ex
+ _alloc_globals
+ _compiler_globals
+ _convert_to_double
+ _convert_to_long
+ _zend_error
+ _zend_hash_find
+ _zend_register_internal_class_ex
+ _zend_register_list_destructors_ex
+ _zend_register_resource
+ _zend_rsrc_list_get_rsrc_type
+ _zend_wrong_param_count
+ _zval_used_for_init
+ )
+ SET(CMAKE_SHARED_MODULE_CREATE_C_FLAGS
+ "${CMAKE_SHARED_MODULE_CREATE_C_FLAGS},-U,${symbol}")
+ ENDFOREACH(symbol)
+ENDIF(APPLE)
+
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(PHP4 DEFAULT_MSG PHP4_EXECUTABLE PHP4_INCLUDE_PATH)
diff --git a/Modules/FindPNG.cmake b/Modules/FindPNG.cmake
new file mode 100644
index 000000000..a6c181cb1
--- /dev/null
+++ b/Modules/FindPNG.cmake
@@ -0,0 +1,75 @@
+# - Find the native PNG includes and library
+#
+# This module searches libpng, the library for working with PNG images.
+#
+# 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.
+#
+# 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.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software 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(PNG_FIND_QUIETLY)
+ set(_FIND_ZLIB_ARG QUIET)
+endif(PNG_FIND_QUIETLY)
+find_package(ZLIB ${_FIND_ZLIB_ARG})
+
+if(ZLIB_FOUND)
+ find_path(PNG_PNG_INCLUDE_DIR png.h
+ /usr/local/include/libpng # OpenBSD
+ )
+
+ set(PNG_NAMES ${PNG_NAMES} png libpng png15 libpng15 png15d libpng15d png14 libpng14 png14d libpng14d png12 libpng12 png12d libpng12d)
+ find_library(PNG_LIBRARY NAMES ${PNG_NAMES} )
+
+ if (PNG_LIBRARY AND PNG_PNG_INCLUDE_DIR)
+ # png.h includes zlib.h. Sigh.
+ SET(PNG_INCLUDE_DIRS ${PNG_PNG_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR} )
+ SET(PNG_INCLUDE_DIR ${PNG_INCLUDE_DIRS} ) # for backward compatiblity
+ SET(PNG_LIBRARIES ${PNG_LIBRARY} ${ZLIB_LIBRARY})
+
+ if (CYGWIN)
+ if(BUILD_SHARED_LIBS)
+ # No need to define PNG_USE_DLL here, because it's default for Cygwin.
+ else(BUILD_SHARED_LIBS)
+ SET (PNG_DEFINITIONS -DPNG_STATIC)
+ endif(BUILD_SHARED_LIBS)
+ endif (CYGWIN)
+
+ endif (PNG_LIBRARY AND PNG_PNG_INCLUDE_DIR)
+
+ if (PNG_PNG_INCLUDE_DIR AND EXISTS "${PNG_PNG_INCLUDE_DIR}/png.h")
+ file(STRINGS "${PNG_PNG_INCLUDE_DIR}/png.h" png_version_str REGEX "^#define[ \t]+PNG_LIBPNG_VER_STRING[ \t]+\".+\"")
+
+ string(REGEX REPLACE "^#define[ \t]+PNG_LIBPNG_VER_STRING[ \t]+\"([^\"]+)\".*" "\\1" PNG_VERSION_STRING "${png_version_str}")
+ unset(png_version_str)
+ endif (PNG_PNG_INCLUDE_DIR AND EXISTS "${PNG_PNG_INCLUDE_DIR}/png.h")
+endif(ZLIB_FOUND)
+
+# handle the QUIETLY and REQUIRED arguments and set PNG_FOUND to TRUE if
+# all listed variables are TRUE
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+find_package_handle_standard_args(PNG
+ REQUIRED_VARS PNG_LIBRARY PNG_PNG_INCLUDE_DIR
+ VERSION_VAR PNG_VERSION_STRING)
+
+mark_as_advanced(PNG_PNG_INCLUDE_DIR PNG_LIBRARY )
diff --git a/Modules/FindPackageHandleStandardArgs.cmake b/Modules/FindPackageHandleStandardArgs.cmake
new file mode 100644
index 000000000..cdcf9ca7c
--- /dev/null
+++ b/Modules/FindPackageHandleStandardArgs.cmake
@@ -0,0 +1,296 @@
+# 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 <UPPERCASED_NAME>_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 [REQUIRED_VARS <var1>...<varN>]
+# [VERSION_VAR <versionvar>]
+# [HANDLE_COMPONENTS]
+# [CONFIG_MODE]
+# [FAIL_MESSAGE "Custom failure message"] )
+#
+# As above, if <var1> through <varN> are all valid, <UPPERCASED_NAME>_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 <NAME>_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(BISON REQUIRED_VARS BISON_EXECUTABLE
+# VERSION_VAR BISON_VERSION)
+# In this case, BISON is considered to be found if the variable(s) listed
+# after REQUIRED_VAR are all valid, i.e. BISON_EXECUTABLE in this case.
+# Also the version of BISON will be checked by using the version contained
+# in BISON_VERSION.
+# 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.
+# The following FIND_PACKAGE_HANDLE_STANDARD_ARGS() call produces a proper
+# success/error message.
+
+#=============================================================================
+# 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.)
+
+INCLUDE(FindPackageMessage)
+INCLUDE(CMakeParseArguments)
+
+# internal helper macro
+MACRO(_FPHSA_FAILURE_MESSAGE _msg)
+ IF (${_NAME}_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR "${_msg}")
+ ELSE (${_NAME}_FIND_REQUIRED)
+ IF (NOT ${_NAME}_FIND_QUIETLY)
+ MESSAGE(STATUS "${_msg}")
+ ENDIF (NOT ${_NAME}_FIND_QUIETLY)
+ ENDIF (${_NAME}_FIND_REQUIRED)
+ENDMACRO(_FPHSA_FAILURE_MESSAGE _msg)
+
+
+# internal helper macro to generate the failure message when used in CONFIG_MODE:
+MACRO(_FPHSA_HANDLE_FAILURE_CONFIG_MODE)
+ # <name>_CONFIG is set, but FOUND is false, this means that some other of the REQUIRED_VARS was not found:
+ IF(${_NAME}_CONFIG)
+ _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: missing: ${MISSING_VARS} (found ${${_NAME}_CONFIG} ${VERSION_MSG})")
+ ELSE(${_NAME}_CONFIG)
+ # If _CONSIDERED_CONFIGS is set, the config-file has been found, but no suitable version.
+ # List them all in the error message:
+ IF(${_NAME}_CONSIDERED_CONFIGS)
+ SET(configsText "")
+ LIST(LENGTH ${_NAME}_CONSIDERED_CONFIGS configsCount)
+ MATH(EXPR configsCount "${configsCount} - 1")
+ FOREACH(currentConfigIndex RANGE ${configsCount})
+ LIST(GET ${_NAME}_CONSIDERED_CONFIGS ${currentConfigIndex} filename)
+ LIST(GET ${_NAME}_CONSIDERED_VERSIONS ${currentConfigIndex} version)
+ SET(configsText "${configsText} ${filename} (version ${version})\n")
+ ENDFOREACH(currentConfigIndex)
+ _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} ${VERSION_MSG}, checked the following files:\n${configsText}")
+
+ ELSE(${_NAME}_CONSIDERED_CONFIGS)
+ # Simple case: No Config-file was found at all:
+ _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: found neither ${_NAME}Config.cmake nor ${_NAME_LOWER}-config.cmake ${VERSION_MSG}")
+ ENDIF(${_NAME}_CONSIDERED_CONFIGS)
+ ENDIF(${_NAME}_CONFIG)
+ENDMACRO(_FPHSA_HANDLE_FAILURE_CONFIG_MODE)
+
+
+FUNCTION(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG)
+
+# set up the arguments for CMAKE_PARSE_ARGUMENTS and check whether we are in
+# new extended or in the "old" mode:
+ SET(options CONFIG_MODE HANDLE_COMPONENTS)
+ SET(oneValueArgs FAIL_MESSAGE VERSION_VAR)
+ SET(multiValueArgs REQUIRED_VARS)
+ SET(_KEYWORDS_FOR_EXTENDED_MODE ${options} ${oneValueArgs} ${multiValueArgs} )
+ LIST(FIND _KEYWORDS_FOR_EXTENDED_MODE "${_FIRST_ARG}" INDEX)
+
+ IF(${INDEX} EQUAL -1)
+ SET(FPHSA_FAIL_MESSAGE ${_FIRST_ARG})
+ SET(FPHSA_REQUIRED_VARS ${ARGN})
+ SET(FPHSA_VERSION_VAR)
+ ELSE(${INDEX} EQUAL -1)
+
+ CMAKE_PARSE_ARGUMENTS(FPHSA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${_FIRST_ARG} ${ARGN})
+
+ IF(FPHSA_UNPARSED_ARGUMENTS)
+ MESSAGE(FATAL_ERROR "Unknown keywords given to FIND_PACKAGE_HANDLE_STANDARD_ARGS(): \"${FPHSA_UNPARSED_ARGUMENTS}\"")
+ ENDIF(FPHSA_UNPARSED_ARGUMENTS)
+
+ IF(NOT FPHSA_FAIL_MESSAGE)
+ SET(FPHSA_FAIL_MESSAGE "DEFAULT_MSG")
+ ENDIF(NOT FPHSA_FAIL_MESSAGE)
+ ENDIF(${INDEX} EQUAL -1)
+
+# now that we collected all arguments, process them
+
+ IF("${FPHSA_FAIL_MESSAGE}" STREQUAL "DEFAULT_MSG")
+ SET(FPHSA_FAIL_MESSAGE "Could NOT find ${_NAME}")
+ ENDIF("${FPHSA_FAIL_MESSAGE}" STREQUAL "DEFAULT_MSG")
+
+ # In config-mode, we rely on the variable <package>_CONFIG, which is set by find_package()
+ # when it successfully found the config-file, including version checking:
+ IF(FPHSA_CONFIG_MODE)
+ LIST(INSERT FPHSA_REQUIRED_VARS 0 ${_NAME}_CONFIG)
+ LIST(REMOVE_DUPLICATES FPHSA_REQUIRED_VARS)
+ SET(FPHSA_VERSION_VAR ${_NAME}_VERSION)
+ ENDIF(FPHSA_CONFIG_MODE)
+
+ IF(NOT FPHSA_REQUIRED_VARS)
+ MESSAGE(FATAL_ERROR "No REQUIRED_VARS specified for FIND_PACKAGE_HANDLE_STANDARD_ARGS()")
+ ENDIF(NOT FPHSA_REQUIRED_VARS)
+
+ LIST(GET FPHSA_REQUIRED_VARS 0 _FIRST_REQUIRED_VAR)
+
+ STRING(TOUPPER ${_NAME} _NAME_UPPER)
+ STRING(TOLOWER ${_NAME} _NAME_LOWER)
+
+ # collect all variables which were not found, so they can be printed, so the
+ # user knows better what went wrong (#6375)
+ SET(MISSING_VARS "")
+ SET(DETAILS "")
+ SET(${_NAME_UPPER}_FOUND TRUE)
+ # check if all passed variables are valid
+ FOREACH(_CURRENT_VAR ${FPHSA_REQUIRED_VARS})
+ IF(NOT ${_CURRENT_VAR})
+ SET(${_NAME_UPPER}_FOUND FALSE)
+ SET(MISSING_VARS "${MISSING_VARS} ${_CURRENT_VAR}")
+ ELSE(NOT ${_CURRENT_VAR})
+ SET(DETAILS "${DETAILS}[${${_CURRENT_VAR}}]")
+ ENDIF(NOT ${_CURRENT_VAR})
+ ENDFOREACH(_CURRENT_VAR)
+
+ # component handling
+ UNSET(FOUND_COMPONENTS_MSG)
+ UNSET(MISSING_COMPONENTS_MSG)
+
+ IF(FPHSA_HANDLE_COMPONENTS)
+ FOREACH(comp ${${_NAME}_FIND_COMPONENTS})
+ IF(${_NAME}_${comp}_FOUND)
+
+ IF(NOT DEFINED FOUND_COMPONENTS_MSG)
+ SET(FOUND_COMPONENTS_MSG "found components: ")
+ ENDIF()
+ SET(FOUND_COMPONENTS_MSG "${FOUND_COMPONENTS_MSG} ${comp}")
+
+ ELSE()
+
+ IF(NOT DEFINED MISSING_COMPONENTS_MSG)
+ SET(MISSING_COMPONENTS_MSG "missing components: ")
+ ENDIF()
+ SET(MISSING_COMPONENTS_MSG "${MISSING_COMPONENTS_MSG} ${comp}")
+
+ IF(${_NAME}_FIND_REQUIRED_${comp})
+ SET(${_NAME_UPPER}_FOUND FALSE)
+ SET(MISSING_VARS "${MISSING_VARS} ${comp}")
+ ENDIF()
+
+ ENDIF()
+ ENDFOREACH(comp)
+ SET(COMPONENT_MSG "${FOUND_COMPONENTS_MSG} ${MISSING_COMPONENTS_MSG}")
+ SET(DETAILS "${DETAILS}[c${COMPONENT_MSG}]")
+ ENDIF(FPHSA_HANDLE_COMPONENTS)
+
+ # version handling:
+ SET(VERSION_MSG "")
+ SET(VERSION_OK TRUE)
+ SET(VERSION ${${FPHSA_VERSION_VAR}} )
+ IF (${_NAME}_FIND_VERSION)
+
+ IF(VERSION)
+
+ 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)
+ ELSE (NOT "${${_NAME}_FIND_VERSION}" VERSION_EQUAL "${VERSION}")
+ SET(VERSION_MSG "(found suitable exact version \"${VERSION}\")")
+ ENDIF (NOT "${${_NAME}_FIND_VERSION}" VERSION_EQUAL "${VERSION}")
+
+ ELSE(${_NAME}_FIND_VERSION_EXACT) # minimum version specified:
+ 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 ("${${_NAME}_FIND_VERSION}" VERSION_GREATER "${VERSION}")
+ SET(VERSION_MSG "(found suitable version \"${VERSION}\", required is \"${${_NAME}_FIND_VERSION}\")")
+ ENDIF ("${${_NAME}_FIND_VERSION}" VERSION_GREATER "${VERSION}")
+ ENDIF(${_NAME}_FIND_VERSION_EXACT)
+
+ ELSE(VERSION)
+
+ # if the package was not found, but a version was given, add that to the output:
+ IF(${_NAME}_FIND_VERSION_EXACT)
+ SET(VERSION_MSG "(Required is exact version \"${${_NAME}_FIND_VERSION}\")")
+ ELSE(${_NAME}_FIND_VERSION_EXACT)
+ SET(VERSION_MSG "(Required is at least version \"${${_NAME}_FIND_VERSION}\")")
+ ENDIF(${_NAME}_FIND_VERSION_EXACT)
+
+ ENDIF(VERSION)
+ ELSE (${_NAME}_FIND_VERSION)
+ IF(VERSION)
+ SET(VERSION_MSG "(found version \"${VERSION}\")")
+ ENDIF(VERSION)
+ ENDIF (${_NAME}_FIND_VERSION)
+
+ IF(VERSION_OK)
+ SET(DETAILS "${DETAILS}[v${VERSION}(${${_NAME}_FIND_VERSION})]")
+ ELSE(VERSION_OK)
+ SET(${_NAME_UPPER}_FOUND FALSE)
+ ENDIF(VERSION_OK)
+
+
+ # print the result:
+ IF (${_NAME_UPPER}_FOUND)
+ FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG} ${COMPONENT_MSG}" "${DETAILS}")
+ ELSE (${_NAME_UPPER}_FOUND)
+
+ IF(FPHSA_CONFIG_MODE)
+ _FPHSA_HANDLE_FAILURE_CONFIG_MODE()
+ ELSE(FPHSA_CONFIG_MODE)
+ IF(NOT VERSION_OK)
+ _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (found ${${_FIRST_REQUIRED_VAR}})")
+ ELSE(NOT VERSION_OK)
+ _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} (missing: ${MISSING_VARS}) ${VERSION_MSG}")
+ ENDIF(NOT VERSION_OK)
+ ENDIF(FPHSA_CONFIG_MODE)
+
+ ENDIF (${_NAME_UPPER}_FOUND)
+
+ SET(${_NAME_UPPER}_FOUND ${${_NAME_UPPER}_FOUND} PARENT_SCOPE)
+
+ENDFUNCTION(FIND_PACKAGE_HANDLE_STANDARD_ARGS _FIRST_ARG)
diff --git a/Modules/FindPackageMessage.cmake b/Modules/FindPackageMessage.cmake
new file mode 100644
index 000000000..48d3472b5
--- /dev/null
+++ b/Modules/FindPackageMessage.cmake
@@ -0,0 +1,49 @@
+# 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.
+#
+# Example:
+#
+# IF(X11_FOUND)
+# FIND_PACKAGE_MESSAGE(X11 "Found X11: ${X11_X11_LIB}"
+# "[${X11_X11_LIB}][${X11_INCLUDE_DIR}]")
+# ELSE(X11_FOUND)
+# ...
+# ENDIF(X11_FOUND)
+
+#=============================================================================
+# Copyright 2008-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.)
+
+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}")
+ SET(DETAILS_VAR FIND_PACKAGE_MESSAGE_DETAILS_${pkg})
+ IF(NOT "${details}" STREQUAL "${${DETAILS_VAR}}")
+ # The message has not yet been printed.
+ MESSAGE(STATUS "${msg}")
+
+ # Save the find details in the cache to avoid printing the same
+ # message again.
+ SET("${DETAILS_VAR}" "${details}"
+ CACHE INTERNAL "Details about finding ${pkg}")
+ ENDIF(NOT "${details}" STREQUAL "${${DETAILS_VAR}}")
+ ENDIF(NOT ${pkg}_FIND_QUIETLY)
+ENDFUNCTION(FIND_PACKAGE_MESSAGE)
diff --git a/Modules/FindPerl.cmake b/Modules/FindPerl.cmake
new file mode 100644
index 000000000..ae686df75
--- /dev/null
+++ b/Modules/FindPerl.cmake
@@ -0,0 +1,83 @@
+# - 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)
+
+#=============================================================================
+# 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.)
+
+INCLUDE(FindCygwin)
+
+SET(PERL_POSSIBLE_BIN_PATHS
+ ${CYGWIN_INSTALL_PATH}/bin
+ )
+
+IF(WIN32)
+ GET_FILENAME_COMPONENT(
+ ActivePerl_CurrentVersion
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\ActiveState\\ActivePerl;CurrentVersion]"
+ NAME)
+ SET(PERL_POSSIBLE_BIN_PATHS ${PERL_POSSIBLE_BIN_PATHS}
+ "C:/Perl/bin"
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\ActiveState\\ActivePerl\\${ActivePerl_CurrentVersion}]/bin
+ )
+ENDIF(WIN32)
+
+FIND_PROGRAM(PERL_EXECUTABLE
+ NAMES perl
+ PATHS ${PERL_POSSIBLE_BIN_PATHS}
+ )
+
+IF(PERL_EXECUTABLE)
+ ### PERL_VERSION
+ EXECUTE_PROCESS(
+ COMMAND
+ ${PERL_EXECUTABLE} -V:version
+ OUTPUT_VARIABLE
+ PERL_VERSION_OUTPUT_VARIABLE
+ RESULT_VARIABLE
+ PERL_VERSION_RESULT_VARIABLE
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+ IF(NOT PERL_VERSION_RESULT_VARIABLE AND NOT PERL_VERSION_OUTPUT_VARIABLE MATCHES "^version='UNKNOWN'")
+ STRING(REGEX REPLACE "version='([^']+)'.*" "\\1" PERL_VERSION_STRING ${PERL_VERSION_OUTPUT_VARIABLE})
+ ELSE()
+ EXECUTE_PROCESS(
+ COMMAND ${PERL_EXECUTABLE} -v
+ OUTPUT_VARIABLE PERL_VERSION_OUTPUT_VARIABLE
+ RESULT_VARIABLE PERL_VERSION_RESULT_VARIABLE
+ ERROR_QUIET
+ 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})
+ 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})
+ ENDIF()
+ ENDIF()
+ENDIF(PERL_EXECUTABLE)
+
+# Deprecated settings for compatibility with CMake1.4
+SET(PERL ${PERL_EXECUTABLE})
+
+# handle the QUIETLY and REQUIRED arguments and set PERL_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Perl
+ REQUIRED_VARS PERL_EXECUTABLE
+ VERSION_VAR PERL_VERSION_STRING)
+
+MARK_AS_ADVANCED(PERL_EXECUTABLE)
diff --git a/Modules/FindPerlLibs.cmake b/Modules/FindPerlLibs.cmake
new file mode 100644
index 000000000..b2ffd3cf6
--- /dev/null
+++ b/Modules/FindPerlLibs.cmake
@@ -0,0 +1,255 @@
+# - 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
+#
+# The minimum required version of Perl can be specified using the
+# standard syntax, e.g. FIND_PACKAGE(PerlLibs 6.0)
+#
+# 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
+#
+
+#=============================================================================
+# Copyright 2004-2009 Kitware, Inc.
+# Copyright 2008 Andreas Schneider <asn@cryptomilk.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.)
+
+# find the perl executable
+include(FindPerl)
+
+if (PERL_EXECUTABLE)
+ ### PERL_PREFIX
+ execute_process(
+ COMMAND
+ ${PERL_EXECUTABLE} -V:prefix
+ OUTPUT_VARIABLE
+ PERL_PREFIX_OUTPUT_VARIABLE
+ RESULT_VARIABLE
+ PERL_PREFIX_RESULT_VARIABLE
+ )
+
+ if (NOT PERL_PREFIX_RESULT_VARIABLE)
+ string(REGEX REPLACE "prefix='([^']+)'.*" "\\1" PERL_PREFIX ${PERL_PREFIX_OUTPUT_VARIABLE})
+ endif (NOT PERL_PREFIX_RESULT_VARIABLE)
+
+ ### PERL_ARCHNAME
+ execute_process(
+ COMMAND
+ ${PERL_EXECUTABLE} -V:archname
+ OUTPUT_VARIABLE
+ PERL_ARCHNAME_OUTPUT_VARIABLE
+ RESULT_VARIABLE
+ PERL_ARCHNAME_RESULT_VARIABLE
+ )
+ if (NOT PERL_ARCHNAME_RESULT_VARIABLE)
+ string(REGEX REPLACE "archname='([^']+)'.*" "\\1" PERL_ARCHNAME ${PERL_ARCHNAME_OUTPUT_VARIABLE})
+ endif (NOT PERL_ARCHNAME_RESULT_VARIABLE)
+
+
+
+ ### PERL_EXTRA_C_FLAGS
+ execute_process(
+ COMMAND
+ ${PERL_EXECUTABLE} -V:cppflags
+ OUTPUT_VARIABLE
+ PERL_CPPFLAGS_OUTPUT_VARIABLE
+ RESULT_VARIABLE
+ PERL_CPPFLAGS_RESULT_VARIABLE
+ )
+ if (NOT PERL_CPPFLAGS_RESULT_VARIABLE)
+ string(REGEX REPLACE "cppflags='([^']+)'.*" "\\1" PERL_EXTRA_C_FLAGS ${PERL_CPPFLAGS_OUTPUT_VARIABLE})
+ endif (NOT PERL_CPPFLAGS_RESULT_VARIABLE)
+
+ ### PERL_SITESEARCH
+ execute_process(
+ COMMAND
+ ${PERL_EXECUTABLE} -V:installsitesearch
+ OUTPUT_VARIABLE
+ PERL_SITESEARCH_OUTPUT_VARIABLE
+ RESULT_VARIABLE
+ PERL_SITESEARCH_RESULT_VARIABLE
+ )
+ if (NOT PERL_SITESEARCH_RESULT_VARIABLE)
+ string(REGEX REPLACE "install[a-z]+='([^']+)'.*" "\\1" PERL_SITESEARCH ${PERL_SITESEARCH_OUTPUT_VARIABLE})
+ file(TO_CMAKE_PATH "${PERL_SITESEARCH}" PERL_SITESEARCH)
+ endif (NOT PERL_SITESEARCH_RESULT_VARIABLE)
+
+ ### PERL_SITELIB
+ execute_process(
+ COMMAND
+ ${PERL_EXECUTABLE} -V:installsitelib
+ OUTPUT_VARIABLE
+ PERL_SITELIB_OUTPUT_VARIABLE
+ RESULT_VARIABLE
+ PERL_SITELIB_RESULT_VARIABLE
+ )
+ if (NOT PERL_SITELIB_RESULT_VARIABLE)
+ string(REGEX REPLACE "install[a-z]+='([^']+)'.*" "\\1" PERL_SITELIB ${PERL_SITELIB_OUTPUT_VARIABLE})
+ file(TO_CMAKE_PATH "${PERL_SITELIB}" PERL_SITELIB)
+ endif (NOT PERL_SITELIB_RESULT_VARIABLE)
+
+ ### PERL_VENDORARCH
+ execute_process(
+ COMMAND
+ ${PERL_EXECUTABLE} -V:installvendorarch
+ OUTPUT_VARIABLE
+ PERL_VENDORARCH_OUTPUT_VARIABLE
+ RESULT_VARIABLE
+ PERL_VENDORARCH_RESULT_VARIABLE
+ )
+ if (NOT PERL_VENDORARCH_RESULT_VARIABLE)
+ string(REGEX REPLACE "install[a-z]+='([^']+)'.*" "\\1" PERL_VENDORARCH ${PERL_VENDORARCH_OUTPUT_VARIABLE})
+ file(TO_CMAKE_PATH "${PERL_VENDORARCH}" PERL_VENDORARCH)
+ endif (NOT PERL_VENDORARCH_RESULT_VARIABLE)
+
+ ### PERL_VENDORLIB
+ execute_process(
+ COMMAND
+ ${PERL_EXECUTABLE} -V:installvendorlib
+ OUTPUT_VARIABLE
+ PERL_VENDORLIB_OUTPUT_VARIABLE
+ RESULT_VARIABLE
+ PERL_VENDORLIB_RESULT_VARIABLE
+ )
+ if (NOT PERL_VENDORLIB_RESULT_VARIABLE)
+ string(REGEX REPLACE "install[a-z]+='([^']+)'.*" "\\1" PERL_VENDORLIB ${PERL_VENDORLIB_OUTPUT_VARIABLE})
+ file(TO_CMAKE_PATH "${PERL_VENDORLIB}" PERL_VENDORLIB)
+ endif (NOT PERL_VENDORLIB_RESULT_VARIABLE)
+
+ macro(perl_adjust_darwin_lib_variable varname)
+ string( TOUPPER PERL_${varname} FINDPERL_VARNAME )
+ string( TOLOWER install${varname} PERL_VARNAME )
+
+ if (NOT PERL_MINUSV_OUTPUT_VARIABLE)
+ execute_process(
+ COMMAND
+ ${PERL_EXECUTABLE} -V
+ OUTPUT_VARIABLE
+ PERL_MINUSV_OUTPUT_VARIABLE
+ RESULT_VARIABLE
+ PERL_MINUSV_RESULT_VARIABLE
+ )
+ endif()
+
+ if (NOT PERL_MINUSV_RESULT_VARIABLE)
+ string(REGEX MATCH "(${PERL_VARNAME}.*points? to the Updates directory)"
+ PERL_NEEDS_ADJUSTMENT ${PERL_MINUSV_OUTPUT_VARIABLE})
+
+ if (PERL_NEEDS_ADJUSTMENT)
+ string(REGEX REPLACE "(.*)/Updates/" "/System/\\1/" ${FINDPERL_VARNAME} ${${FINDPERL_VARNAME}})
+ endif (PERL_NEEDS_ADJUSTMENT)
+
+ endif (NOT PERL_MINUSV_RESULT_VARIABLE)
+ endmacro()
+
+ ### PERL_ARCHLIB
+ execute_process(
+ COMMAND
+ ${PERL_EXECUTABLE} -V:installarchlib
+ OUTPUT_VARIABLE
+ PERL_ARCHLIB_OUTPUT_VARIABLE
+ RESULT_VARIABLE
+ PERL_ARCHLIB_RESULT_VARIABLE
+ )
+ if (NOT PERL_ARCHLIB_RESULT_VARIABLE)
+ string(REGEX REPLACE "install[a-z]+='([^']+)'.*" "\\1" PERL_ARCHLIB ${PERL_ARCHLIB_OUTPUT_VARIABLE})
+ perl_adjust_darwin_lib_variable( ARCHLIB )
+ file(TO_CMAKE_PATH "${PERL_ARCHLIB}" PERL_ARCHLIB)
+ endif (NOT PERL_ARCHLIB_RESULT_VARIABLE)
+
+ ### PERL_PRIVLIB
+ execute_process(
+ COMMAND
+ ${PERL_EXECUTABLE} -V:installprivlib
+ OUTPUT_VARIABLE
+ PERL_PRIVLIB_OUTPUT_VARIABLE
+ RESULT_VARIABLE
+ PERL_PRIVLIB_RESULT_VARIABLE
+ )
+ if (NOT PERL_PRIVLIB_RESULT_VARIABLE)
+ string(REGEX REPLACE "install[a-z]+='([^']+)'.*" "\\1" PERL_PRIVLIB ${PERL_PRIVLIB_OUTPUT_VARIABLE})
+ perl_adjust_darwin_lib_variable( PRIVLIB )
+ file(TO_CMAKE_PATH "${PERL_PRIVLIB}" PERL_PRIVLIB)
+ endif (NOT PERL_PRIVLIB_RESULT_VARIABLE)
+
+ ### PERL_POSSIBLE_LIBRARY_NAMES
+ execute_process(
+ COMMAND
+ ${PERL_EXECUTABLE} -V:libperl
+ OUTPUT_VARIABLE
+ PERL_LIBRARY_OUTPUT_VARIABLE
+ RESULT_VARIABLE
+ PERL_LIBRARY_RESULT_VARIABLE
+ )
+ if (NOT PERL_LIBRARY_RESULT_VARIABLE)
+ string(REGEX REPLACE "libperl='([^']+)'.*" "\\1" PERL_POSSIBLE_LIBRARY_NAMES ${PERL_LIBRARY_OUTPUT_VARIABLE})
+ else (NOT PERL_LIBRARY_RESULT_VARIABLE)
+ set(PERL_POSSIBLE_LIBRARY_NAMES perl${PERL_VERSION_STRING} perl)
+ endif (NOT PERL_LIBRARY_RESULT_VARIABLE)
+
+ ### PERL_INCLUDE_PATH
+ find_path(PERL_INCLUDE_PATH
+ NAMES
+ perl.h
+ PATHS
+ ${PERL_ARCHLIB}/CORE
+ /usr/lib/perl5/${PERL_VERSION_STRING}/${PERL_ARCHNAME}/CORE
+ /usr/lib/perl/${PERL_VERSION_STRING}/${PERL_ARCHNAME}/CORE
+ /usr/lib/perl5/${PERL_VERSION_STRING}/CORE
+ /usr/lib/perl/${PERL_VERSION_STRING}/CORE
+ )
+
+ ### PERL_LIBRARY
+ find_library(PERL_LIBRARY
+ NAMES
+ ${PERL_POSSIBLE_LIBRARY_NAMES}
+ PATHS
+ ${PERL_ARCHLIB}/CORE
+ /usr/lib/perl5/${PERL_VERSION_STRING}/${PERL_ARCHNAME}/CORE
+ /usr/lib/perl/${PERL_VERSION_STRING}/${PERL_ARCHNAME}/CORE
+ /usr/lib/perl5/${PERL_VERSION_STRING}/CORE
+ /usr/lib/perl/${PERL_VERSION_STRING}/CORE
+ )
+
+endif (PERL_EXECUTABLE)
+
+# handle the QUIETLY and REQUIRED arguments and set PERLLIBS_FOUND to TRUE if
+# all listed variables are TRUE
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+find_package_handle_standard_args(PerlLibs REQUIRED_VARS PERL_LIBRARY PERL_INCLUDE_PATH
+ VERSION_VAR PERL_VERSION_STRING)
+
+# Introduced after CMake 2.6.4 to bring module into compliance
+set(PERL_INCLUDE_DIR ${PERL_INCLUDE_PATH})
+set(PERL_INCLUDE_DIRS ${PERL_INCLUDE_PATH})
+set(PERL_LIBRARIES ${PERL_LIBRARY})
+# For backward compatibility with CMake before 2.8.8
+set(PERL_VERSION ${PERL_VERSION_STRING})
+
+mark_as_advanced(
+ PERL_INCLUDE_PATH
+ PERL_LIBRARY
+)
diff --git a/Modules/FindPhysFS.cmake b/Modules/FindPhysFS.cmake
new file mode 100644
index 000000000..2e3ac1400
--- /dev/null
+++ b/Modules/FindPhysFS.cmake
@@ -0,0 +1,57 @@
+# 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.
+
+#=============================================================================
+# 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.)
+
+FIND_PATH(PHYSFS_INCLUDE_DIR physfs.h
+ HINTS
+ $ENV{PHYSFSDIR}
+ PATH_SUFFIXES include/physfs include
+ PATHS
+ ~/Library/Frameworks
+ /Library/Frameworks
+ /sw # Fink
+ /opt/local # DarwinPorts
+ /opt/csw # Blastwave
+ /opt
+)
+
+FIND_LIBRARY(PHYSFS_LIBRARY
+ NAMES physfs
+ HINTS
+ $ENV{PHYSFSDIR}
+ PATH_SUFFIXES lib64 lib
+ PATHS
+ ~/Library/Frameworks
+ /Library/Frameworks
+ /sw
+ /opt/local
+ /opt/csw
+ /opt
+)
+
+# handle the QUIETLY and REQUIRED arguments and set PHYSFS_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(PhysFS DEFAULT_MSG PHYSFS_LIBRARY PHYSFS_INCLUDE_DIR)
+
diff --git a/Modules/FindPike.cmake b/Modules/FindPike.cmake
new file mode 100644
index 000000000..125e42832
--- /dev/null
+++ b/Modules/FindPike.cmake
@@ -0,0 +1,37 @@
+# - 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.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software 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.)
+
+FILE(GLOB PIKE_POSSIBLE_INCLUDE_PATHS
+ /usr/include/pike/*
+ /usr/local/include/pike/*)
+
+FIND_PATH(PIKE_INCLUDE_PATH program.h
+ ${PIKE_POSSIBLE_INCLUDE_PATHS})
+
+FIND_PROGRAM(PIKE_EXECUTABLE
+ NAMES pike7.4
+ )
+
+MARK_AS_ADVANCED(
+ PIKE_EXECUTABLE
+ PIKE_INCLUDE_PATH
+ )
diff --git a/Modules/FindPkgConfig.cmake b/Modules/FindPkgConfig.cmake
new file mode 100644
index 000000000..39d3a76ab
--- /dev/null
+++ b/Modules/FindPkgConfig.cmake
@@ -0,0 +1,373 @@
+# - a pkg-config module for CMake
+#
+# 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
+#
+# pkg_check_modules (XRENDER REQUIRED xrender)
+# defines e.g.:
+# XRENDER_LIBRARIES=Xrender;X11
+# XRENDER_STATIC_LIBRARIES=Xrender;X11;pthread;Xau;Xdmcp
+#
+# pkg_search_module (BAR libxml-2.0 libxml2 libxml>=2)
+
+#=============================================================================
+# Copyright 2006-2009 Kitware, Inc.
+# 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.
+#
+# This software 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.)
+
+### Common stuff ####
+set(PKG_CONFIG_VERSION 1)
+
+find_program(PKG_CONFIG_EXECUTABLE NAMES pkg-config DOC "pkg-config executable")
+mark_as_advanced(PKG_CONFIG_EXECUTABLE)
+
+if (PKG_CONFIG_EXECUTABLE)
+ execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --version
+ OUTPUT_VARIABLE PKG_CONFIG_VERSION_STRING
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+endif (PKG_CONFIG_EXECUTABLE)
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+find_package_handle_standard_args(PkgConfig
+ REQUIRED_VARS PKG_CONFIG_EXECUTABLE
+ VERSION_VAR PKG_CONFIG_VERSION_STRING)
+
+# This is needed because the module name is "PkgConfig" but the name of
+# this variable has always been PKG_CONFIG_FOUND so this isn't automatically
+# handled by FPHSA.
+set(PKG_CONFIG_FOUND "${PKGCONFIG_FOUND}")
+
+# Unsets the given variables
+macro(_pkgconfig_unset var)
+ set(${var} "" CACHE INTERNAL "")
+endmacro(_pkgconfig_unset)
+
+macro(_pkgconfig_set var value)
+ set(${var} ${value} CACHE INTERNAL "")
+endmacro(_pkgconfig_set)
+
+# Invokes pkgconfig, cleans up the result and sets variables
+macro(_pkgconfig_invoke _pkglist _prefix _varname _regexp)
+ set(_pkgconfig_invoke_result)
+
+ execute_process(
+ COMMAND ${PKG_CONFIG_EXECUTABLE} ${ARGN} ${_pkglist}
+ OUTPUT_VARIABLE _pkgconfig_invoke_result
+ RESULT_VARIABLE _pkgconfig_failed)
+
+ if (_pkgconfig_failed)
+ set(_pkgconfig_${_varname} "")
+ _pkgconfig_unset(${_prefix}_${_varname})
+ else(_pkgconfig_failed)
+ 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}")
+ endif(NOT ${_regexp} STREQUAL "")
+
+ separate_arguments(_pkgconfig_invoke_result)
+
+ #message(STATUS " ${_varname} ... ${_pkgconfig_invoke_result}")
+ set(_pkgconfig_${_varname} ${_pkgconfig_invoke_result})
+ _pkgconfig_set(${_prefix}_${_varname} "${_pkgconfig_invoke_result}")
+ endif(_pkgconfig_failed)
+endmacro(_pkgconfig_invoke)
+
+# Invokes pkgconfig two times; once without '--static' and once with
+# '--static'
+macro(_pkgconfig_invoke_dyn _pkglist _prefix _varname cleanup_regexp)
+ _pkgconfig_invoke("${_pkglist}" ${_prefix} ${_varname} "${cleanup_regexp}" ${ARGN})
+ _pkgconfig_invoke("${_pkglist}" ${_prefix} STATIC_${_varname} "${cleanup_regexp}" --static ${ARGN})
+endmacro(_pkgconfig_invoke_dyn)
+
+# Splits given arguments into options and a package list
+macro(_pkgconfig_parse_options _result _is_req _is_silent)
+ set(${_is_req} 0)
+ set(${_is_silent} 0)
+
+ foreach(_pkg ${ARGN})
+ if (_pkg STREQUAL "REQUIRED")
+ set(${_is_req} 1)
+ endif (_pkg STREQUAL "REQUIRED")
+ if (_pkg STREQUAL "QUIET")
+ set(${_is_silent} 1)
+ endif (_pkg STREQUAL "QUIET")
+ endforeach(_pkg ${ARGN})
+
+ set(${_result} ${ARGN})
+ list(REMOVE_ITEM ${_result} "REQUIRED")
+ list(REMOVE_ITEM ${_result} "QUIET")
+endmacro(_pkgconfig_parse_options)
+
+###
+macro(_pkg_check_modules_internal _is_required _is_silent _prefix)
+ _pkgconfig_unset(${_prefix}_FOUND)
+ _pkgconfig_unset(${_prefix}_VERSION)
+ _pkgconfig_unset(${_prefix}_PREFIX)
+ _pkgconfig_unset(${_prefix}_INCLUDEDIR)
+ _pkgconfig_unset(${_prefix}_LIBDIR)
+ _pkgconfig_unset(${_prefix}_LIBS)
+ _pkgconfig_unset(${_prefix}_LIBS_L)
+ _pkgconfig_unset(${_prefix}_LIBS_PATHS)
+ _pkgconfig_unset(${_prefix}_LIBS_OTHER)
+ _pkgconfig_unset(${_prefix}_CFLAGS)
+ _pkgconfig_unset(${_prefix}_CFLAGS_I)
+ _pkgconfig_unset(${_prefix}_CFLAGS_OTHER)
+ _pkgconfig_unset(${_prefix}_STATIC_LIBDIR)
+ _pkgconfig_unset(${_prefix}_STATIC_LIBS)
+ _pkgconfig_unset(${_prefix}_STATIC_LIBS_L)
+ _pkgconfig_unset(${_prefix}_STATIC_LIBS_PATHS)
+ _pkgconfig_unset(${_prefix}_STATIC_LIBS_OTHER)
+ _pkgconfig_unset(${_prefix}_STATIC_CFLAGS)
+ _pkgconfig_unset(${_prefix}_STATIC_CFLAGS_I)
+ _pkgconfig_unset(${_prefix}_STATIC_CFLAGS_OTHER)
+
+ # create a better addressable variable of the modules and calculate its size
+ set(_pkg_check_modules_list ${ARGN})
+ list(LENGTH _pkg_check_modules_list _pkg_check_modules_cnt)
+
+ if(PKG_CONFIG_EXECUTABLE)
+ # 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}'")
+ else(_pkg_check_modules_cnt EQUAL 1)
+ message(STATUS "checking for modules '${_pkg_check_modules_list}'")
+ endif(_pkg_check_modules_cnt EQUAL 1)
+ endif(NOT ${_is_silent})
+
+ set(_pkg_check_modules_packages)
+ set(_pkg_check_modules_failed)
+
+ # 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}")
+ else(_pkg_check_modules_pkg MATCHES ".*(>=|=|<=).*")
+ set(_pkg_check_modules_pkg_name "${_pkg_check_modules_pkg}")
+ set(_pkg_check_modules_pkg_op)
+ set(_pkg_check_modules_pkg_ver)
+ endif(_pkg_check_modules_pkg MATCHES ".*(>=|=|<=).*")
+
+ # handle the operands
+ if (_pkg_check_modules_pkg_op STREQUAL ">=")
+ list(APPEND _pkg_check_modules_exist_query --atleast-version)
+ endif(_pkg_check_modules_pkg_op STREQUAL ">=")
+
+ if (_pkg_check_modules_pkg_op STREQUAL "=")
+ list(APPEND _pkg_check_modules_exist_query --exact-version)
+ endif(_pkg_check_modules_pkg_op STREQUAL "=")
+
+ if (_pkg_check_modules_pkg_op STREQUAL "<=")
+ list(APPEND _pkg_check_modules_exist_query --max-version)
+ endif(_pkg_check_modules_pkg_op STREQUAL "<=")
+
+ # create the final query which is of the format:
+ # * --atleast-version <version> <pkg-name>
+ # * --exact-version <version> <pkg-name>
+ # * --max-version <version> <pkg-name>
+ # * --exists <pkg-name>
+ if (_pkg_check_modules_pkg_op)
+ list(APPEND _pkg_check_modules_exist_query "${_pkg_check_modules_pkg_ver}")
+ else(_pkg_check_modules_pkg_op)
+ list(APPEND _pkg_check_modules_exist_query --exists)
+ endif(_pkg_check_modules_pkg_op)
+
+ _pkgconfig_unset(${_prefix}_${_pkg_check_modules_pkg_name}_VERSION)
+ _pkgconfig_unset(${_prefix}_${_pkg_check_modules_pkg_name}_PREFIX)
+ _pkgconfig_unset(${_prefix}_${_pkg_check_modules_pkg_name}_INCLUDEDIR)
+ _pkgconfig_unset(${_prefix}_${_pkg_check_modules_pkg_name}_LIBDIR)
+
+ list(APPEND _pkg_check_modules_exist_query "${_pkg_check_modules_pkg_name}")
+ list(APPEND _pkg_check_modules_packages "${_pkg_check_modules_pkg_name}")
+
+ # execute the query
+ execute_process(
+ COMMAND ${PKG_CONFIG_EXECUTABLE} ${_pkg_check_modules_exist_query}
+ RESULT_VARIABLE _pkgconfig_retval)
+
+ # evaluate result and tell failures
+ if (_pkgconfig_retval)
+ if(NOT ${_is_silent})
+ message(STATUS " package '${_pkg_check_modules_pkg}' not found")
+ endif(NOT ${_is_silent})
+
+ set(_pkg_check_modules_failed 1)
+ endif(_pkgconfig_retval)
+ endforeach(_pkg_check_modules_pkg)
+
+ if(_pkg_check_modules_failed)
+ # fail when requested
+ if (${_is_required})
+ message(SEND_ERROR "A required package was not found")
+ endif (${_is_required})
+ else(_pkg_check_modules_failed)
+ # when we are here, we checked whether requested modules
+ # exist. Now, go through them and set variables
+
+ _pkgconfig_set(${_prefix}_FOUND 1)
+ list(LENGTH _pkg_check_modules_packages pkg_count)
+
+ # iterate through all modules again and set individual variables
+ foreach (_pkg_check_modules_pkg ${_pkg_check_modules_packages})
+ # handle case when there is only one package required
+ if (pkg_count EQUAL 1)
+ set(_pkg_check_prefix "${_prefix}")
+ else(pkg_count EQUAL 1)
+ set(_pkg_check_prefix "${_prefix}_${_pkg_check_modules_pkg}")
+ endif(pkg_count EQUAL 1)
+
+ _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 )
+
+ if (NOT ${_is_silent})
+ message(STATUS " found ${_pkg_check_modules_pkg}, version ${_pkgconfig_VERSION}")
+ endif (NOT ${_is_silent})
+ endforeach(_pkg_check_modules_pkg)
+
+ # set variables which are combined for multiple modules
+ _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" LIBRARIES "(^| )-l" --libs-only-l )
+ _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" LIBRARY_DIRS "(^| )-L" --libs-only-L )
+ _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" LDFLAGS "" --libs )
+ _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" LDFLAGS_OTHER "" --libs-only-other )
+
+ _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" INCLUDE_DIRS "(^| )-I" --cflags-only-I )
+ _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" CFLAGS "" --cflags )
+ _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" CFLAGS_OTHER "" --cflags-only-other )
+ endif(_pkg_check_modules_failed)
+ else(PKG_CONFIG_EXECUTABLE)
+ if (${_is_required})
+ message(SEND_ERROR "pkg-config tool not found")
+ endif (${_is_required})
+ endif(PKG_CONFIG_EXECUTABLE)
+endmacro(_pkg_check_modules_internal)
+
+###
+### User visible macros start here
+###
+
+###
+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_set(__pkg_config_checked_${_prefix} ${PKG_CONFIG_VERSION})
+ endif(NOT DEFINED __pkg_config_checked_${_prefix} OR __pkg_config_checked_${_prefix} LESS ${PKG_CONFIG_VERSION} OR NOT ${_prefix}_FOUND)
+endmacro(pkg_check_modules)
+
+###
+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})
+
+ if (NOT ${_pkg_is_silent})
+ message(STATUS "checking for one of the modules '${_pkg_modules_alt}'")
+ endif (NOT ${_pkg_is_silent})
+
+ # 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}")
+ endif(NOT _pkg_modules_found)
+
+ if (${_prefix}_FOUND)
+ set(_pkg_modules_found 1)
+ endif(${_prefix}_FOUND)
+ endforeach(_pkg_alt)
+
+ if (NOT ${_prefix}_FOUND)
+ if(${_pkg_is_required})
+ message(SEND_ERROR "None of the required '${_pkg_modules_alt}' found")
+ endif(${_pkg_is_required})
+ endif(NOT ${_prefix}_FOUND)
+
+ _pkgconfig_set(__pkg_config_checked_${_prefix} ${PKG_CONFIG_VERSION})
+ endif(NOT DEFINED __pkg_config_checked_${_prefix} OR __pkg_config_checked_${_prefix} LESS ${PKG_CONFIG_VERSION} OR NOT ${_prefix}_FOUND)
+endmacro(pkg_search_module)
+
+### Local Variables:
+### mode: cmake
+### End:
diff --git a/Modules/FindPostgreSQL.cmake b/Modules/FindPostgreSQL.cmake
new file mode 100644
index 000000000..94e5676fe
--- /dev/null
+++ b/Modules/FindPostgreSQL.cmake
@@ -0,0 +1,172 @@
+# - 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.
+#
+# 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)
+
+#=============================================================================
+# 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.)
+
+# ----------------------------------------------------------------------------
+# History:
+# This module is derived from the module originally found in the VTK source tree.
+#
+# ----------------------------------------------------------------------------
+# Note:
+# PostgreSQL_ADDITIONAL_VERSIONS is a variable that can be used to set the
+# version mumber of the implementation of PostgreSQL.
+# 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"
+#
+# To use this variable just do something like this:
+# set(PostgreSQL_ADDITIONAL_VERSIONS "9.2" "8.4.4")
+# before calling FIND_PACKAGE(PostgreSQL) in your CMakeLists.txt file.
+# This will mean that the versions you set here will be found first in the order
+# specified before the default ones are searched.
+#
+# ----------------------------------------------------------------------------
+# You may need to manually set:
+# PostgreSQL_INCLUDE_DIR - the path to where the PostgreSQL include files are.
+# PostgreSQL_LIBRARY_DIR - The path to where the PostgreSQL library files are.
+# If FindPostgreSQL.cmake cannot find the include files or the library files.
+#
+# ----------------------------------------------------------------------------
+# The following variables are set if PostgreSQL is found:
+# PostgreSQL_FOUND - Set to true when PostgreSQL is found.
+# PostgreSQL_INCLUDE_DIRS - Include directories for PostgreSQL
+# PostgreSQL_LIBRARY_DIRS - Link directories for PostgreSQL libraries
+# PostgreSQL_LIBRARIES - The PostgreSQL libraries.
+#
+# ----------------------------------------------------------------------------
+# If you have installed PostgreSQL in a non-standard location.
+# (Please note that in the following comments, it is assumed that <Your Path>
+# points to the root directory of the include directory of PostgreSQL.)
+# Then you have three options.
+# 1) After CMake runs, set PostgreSQL_INCLUDE_DIR to <Your Path>/include and
+# PostgreSQL_LIBRARY_DIR to wherever the library pq (or libpq in windows) is
+# 2) Use CMAKE_INCLUDE_PATH to set a path to <Your Path>/PostgreSQL<-version>. This will allow find_path()
+# to locate PostgreSQL_INCLUDE_DIR by utilizing the PATH_SUFFIXES option. e.g. In your CMakeLists.txt file
+# SET(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "<Your Path>/include")
+# 3) Set an environment variable called ${PostgreSQL_ROOT} that points to the root of where you have
+# installed PostgreSQL, e.g. <Your Path>.
+#
+# ----------------------------------------------------------------------------
+
+set(PostgreSQL_INCLUDE_PATH_DESCRIPTION "top-level directory containing the PostgreSQL include directories. E.g /usr/local/include/PostgreSQL/8.4 or C:/Program Files/PostgreSQL/8.4/include")
+set(PostgreSQL_INCLUDE_DIR_MESSAGE "Set the PostgreSQL_INCLUDE_DIR cmake cache entry to the ${PostgreSQL_INCLUDE_PATH_DESCRIPTION}")
+set(PostgreSQL_LIBRARY_PATH_DESCRIPTION "top-level directory containing the PostgreSQL libraries.")
+set(PostgreSQL_LIBRARY_DIR_MESSAGE "Set the PostgreSQL_LIBRARY_DIR cmake cache entry to the ${PostgreSQL_LIBRARY_PATH_DESCRIPTION}")
+set(PostgreSQL_ROOT_DIR_MESSAGE "Set the PostgreSQL_ROOT system variable to where PostgreSQL is found on the machine E.g C:/Program Files/PostgreSQL/8.4")
+
+
+set(PostgreSQL_ROOT_DIRECTORIES $ENV{PostgreSQL_ROOT})
+if(PostgreSQL_ROOT_DIRECTORIES)
+ file(TO_CMAKE_PATH ${PostgreSQL_ROOT_DIRECTORIES} PostgreSQL_ROOT_DIRECTORIES)
+endif(PostgreSQL_ROOT_DIRECTORIES)
+
+set(PostgreSQL_KNOWN_VERSIONS ${PostgreSQL_ADDITIONAL_VERSIONS}
+ "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(suffix)
+endif( WIN32 )
+set( PostgreSQL_ROOT_DIRECTORIES
+ ${PostgreSQL_ROOT_DIRECTORIES}
+ ${PostgreSQL_ROOT}
+ ${PostgreSQL_ADDITIONAL_SEARCH_PATHS}
+)
+
+#
+# Look for an installation.
+#
+find_path(PostgreSQL_INCLUDE_DIR
+ NAMES libpq-fe.h
+ PATHS
+ # Look in other places.
+ ${PostgreSQL_ROOT_DIRECTORIES}
+ PATH_SUFFIXES
+ pgsql
+ postgresql
+ include
+ # Help the user find it if we cannot.
+ DOC "The ${PostgreSQL_INCLUDE_DIR_MESSAGE}"
+)
+
+find_path(PostgreSQL_TYPE_INCLUDE_DIR
+ NAMES catalog/pg_type.h
+ PATHS
+ # Look in other places.
+ ${PostgreSQL_ROOT_DIRECTORIES}
+ PATH_SUFFIXES
+ pgsql/server
+ postgresql/server
+ include/server
+ # Help the user find it if we cannot.
+ DOC "The ${PostgreSQL_INCLUDE_DIR_MESSAGE}"
+)
+
+# The PostgreSQL library.
+set (PostgreSQL_LIBRARY_TO_FIND pq)
+# Setting some more prefixes for the library
+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})
+endif()
+
+find_library( PostgreSQL_LIBRARY
+ NAMES ${PostgreSQL_LIBRARY_TO_FIND}
+ PATHS
+ ${PostgreSQL_ROOT_DIRECTORIES}
+ PATH_SUFFIXES
+ lib
+)
+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}")
+ unset(pgsql_version_str)
+endif()
+
+# Did we find anything?
+include(FindPackageHandleStandardArgs)
+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})
+
+# 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(PostgreSQL_FOUND)
+
+mark_as_advanced(PostgreSQL_INCLUDE_DIR PostgreSQL_TYPE_INCLUDE_DIR PostgreSQL_LIBRARY )
diff --git a/Modules/FindProducer.cmake b/Modules/FindProducer.cmake
new file mode 100644
index 000000000..26c804ac1
--- /dev/null
+++ b/Modules/FindProducer.cmake
@@ -0,0 +1,78 @@
+# 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).
+# If you want to use a more convenient module that includes everything,
+# 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
+#
+# $PRODUCER_DIR is an environment variable that would
+# correspond to the ./configure --prefix=$PRODUCER_DIR
+# used in building osg.
+#
+# Created by Eric Wing.
+
+#=============================================================================
+# 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.)
+
+# Header files are presumed to be included like
+# #include <Producer/CameraGroup>
+
+# Try the user's environment request before anything else.
+FIND_PATH(PRODUCER_INCLUDE_DIR Producer/CameraGroup
+ HINTS
+ $ENV{PRODUCER_DIR}
+ $ENV{OSG_DIR}
+ $ENV{OSGDIR}
+ PATH_SUFFIXES include
+ PATHS
+ ~/Library/Frameworks
+ /Library/Frameworks
+ /sw/include # Fink
+ /opt/local/include # DarwinPorts
+ /opt/csw/include # Blastwave
+ /opt/include
+ [HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session\ Manager\\Environment;OpenThreads_ROOT]/include
+ [HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session\ Manager\\Environment;OSG_ROOT]/include
+)
+
+FIND_LIBRARY(PRODUCER_LIBRARY
+ NAMES Producer
+ HINTS
+ $ENV{PRODUCER_DIR}
+ $ENV{OSG_DIR}
+ $ENV{OSGDIR}
+ PATH_SUFFIXES lib64 lib
+ PATHS
+ /sw
+ /opt/local
+ /opt/csw
+ /opt
+)
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Producer DEFAULT_MSG
+ PRODUCER_LIBRARY PRODUCER_INCLUDE_DIR)
diff --git a/Modules/FindProtobuf.cmake b/Modules/FindProtobuf.cmake
new file mode 100644
index 000000000..1e1e49301
--- /dev/null
+++ b/Modules/FindProtobuf.cmake
@@ -0,0 +1,218 @@
+# 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)
+#
+# 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
+#
+# 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:
+#
+# find_package(Protobuf REQUIRED)
+# include_directories(${PROTOBUF_INCLUDE_DIRS})
+#
+# include_directories(${CMAKE_CURRENT_BINARY_DIR})
+# PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS 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 macro & add_executable() or add_library()
+# calls only work properly within the same directory.
+#
+# ====================================================================
+#
+# PROTOBUF_GENERATE_CPP (public function)
+# SRCS = Variable to define with autogenerated
+# source files
+# HDRS = Variable to define with autogenerated
+# header files
+# ARGN = proto files
+#
+# ====================================================================
+
+
+#=============================================================================
+# Copyright 2009 Kitware, Inc.
+# Copyright 2009-2011 Philip Lowman <philip@yhbt.com>
+# Copyright 2008 Esben Mose Hansen, Ange Optimization ApS
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software 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(PROTOBUF_GENERATE_CPP SRCS HDRS)
+ if(NOT ARGN)
+ message(SEND_ERROR "Error: PROTOBUF_GENERATE_CPP() called without any proto files")
+ return()
+ endif(NOT ARGN)
+
+ 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})
+ set(${HDRS})
+ 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}.pb.cc")
+ list(APPEND ${HDRS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h")
+
+ add_custom_command(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc"
+ "${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}
+ COMMENT "Running C++ protocol buffer compiler on ${FIL}"
+ VERBATIM )
+ endforeach()
+
+ set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE)
+ set(${SRCS} ${${SRCS}} PARENT_SCOPE)
+ set(${HDRS} ${${HDRS}} PARENT_SCOPE)
+endfunction()
+
+# 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)
+ mark_as_advanced(${name}_LIBRARY)
+
+ find_library(${name}_LIBRARY_DEBUG
+ NAMES ${filename}
+ PATHS ${PROTOBUF_SRC_ROOT_FOLDER}/vsprojects/Debug)
+ mark_as_advanced(${name}_LIBRARY_DEBUG)
+
+ if(NOT ${name}_LIBRARY_DEBUG)
+ # There is no debug library
+ set(${name}_LIBRARY_DEBUG ${${name}_LIBRARY} PARENT_SCOPE)
+ set(${name}_LIBRARIES ${${name}_LIBRARY} PARENT_SCOPE)
+ else()
+ # There IS a debug library
+ set(${name}_LIBRARIES
+ optimized ${${name}_LIBRARY}
+ debug ${${name}_LIBRARY_DEBUG}
+ PARENT_SCOPE
+ )
+ endif()
+endfunction()
+
+#
+# Main.
+#
+
+# By default have PROTOBUF_GENERATE_CPP macro pass -I to protoc
+# for each directory where a proto file is referenced.
+if(NOT DEFINED PROTOBUF_GENERATE_CPP_APPEND_PATH)
+ set(PROTOBUF_GENERATE_CPP_APPEND_PATH TRUE)
+endif()
+
+
+# Google's provided vcproj files generate libraries with a "lib"
+# prefix on Windows
+if(MSVC)
+ set(PROTOBUF_ORIG_FIND_LIBRARY_PREFIXES "${CMAKE_FIND_LIBRARY_PREFIXES}")
+ set(CMAKE_FIND_LIBRARY_PREFIXES "lib" "")
+
+ find_path(PROTOBUF_SRC_ROOT_FOLDER protobuf.pc.in)
+endif()
+
+# The Protobuf library
+_protobuf_find_libraries(PROTOBUF protobuf)
+#DOC "The Google Protocol Buffers RELEASE Library"
+
+_protobuf_find_libraries(PROTOBUF_LITE protobuf-lite)
+
+# The Protobuf Protoc Library
+_protobuf_find_libraries(PROTOBUF_PROTOC protoc)
+
+# Restore original find library prefixes
+if(MSVC)
+ set(CMAKE_FIND_LIBRARY_PREFIXES "${PROTOBUF_ORIG_FIND_LIBRARY_PREFIXES}")
+endif()
+
+
+# Find the include directory
+find_path(PROTOBUF_INCLUDE_DIR
+ google/protobuf/service.h
+ PATHS ${PROTOBUF_SRC_ROOT_FOLDER}/src
+)
+mark_as_advanced(PROTOBUF_INCLUDE_DIR)
+
+# Find the protoc Executable
+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
+)
+mark_as_advanced(PROTOBUF_PROTOC_EXECUTABLE)
+
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(PROTOBUF DEFAULT_MSG
+ PROTOBUF_LIBRARY PROTOBUF_INCLUDE_DIR)
+
+if(PROTOBUF_FOUND)
+ set(PROTOBUF_INCLUDE_DIRS ${PROTOBUF_INCLUDE_DIR})
+endif()
diff --git a/Modules/FindPythonInterp.cmake b/Modules/FindPythonInterp.cmake
new file mode 100644
index 000000000..a131c5fde
--- /dev/null
+++ b/Modules/FindPythonInterp.cmake
@@ -0,0 +1,141 @@
+# - Find python interpreter
+# This module finds if Python interpreter is installed and determines where the
+# executables are. This code sets the following variables:
+#
+# 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).
+
+#=============================================================================
+# Copyright 2005-2010 Kitware, Inc.
+# Copyright 2011 Bjoern Ricks <bjoern.ricks@gmail.com>
+# Copyright 2012 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(_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)
+
+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})
+ unset(_PYTHON_FIND_OTHER_VERSIONS)
+ if(NOT PythonInterp_FIND_VERSION_EXACT)
+ foreach(_PYTHON_V ${_PYTHON${_PYTHON_FIND_MAJ}_VERSIONS})
+ if(NOT _PYTHON_V VERSION_LESS _PYTHON_FIND_MAJ_MIN)
+ list(APPEND _PYTHON_FIND_OTHER_VERSIONS ${_PYTHON_V})
+ endif()
+ endforeach()
+ endif(NOT PythonInterp_FIND_VERSION_EXACT)
+ unset(_PYTHON_FIND_MAJ_MIN)
+ unset(_PYTHON_FIND_MAJ)
+ else(PythonInterp_FIND_VERSION MATCHES "^[0-9]+\\.[0-9]+(\\.[0-9]+.*)?$")
+ list(APPEND _Python_NAMES python${PythonInterp_FIND_VERSION})
+ set(_PYTHON_FIND_OTHER_VERSIONS ${_PYTHON${PythonInterp_FIND_VERSION}_VERSIONS})
+ endif(PythonInterp_FIND_VERSION MATCHES "^[0-9]+\\.[0-9]+(\\.[0-9]+.*)?$")
+else(PythonInterp_FIND_VERSION)
+ set(_PYTHON_FIND_OTHER_VERSIONS ${_PYTHON3_VERSIONS} ${_PYTHON2_VERSIONS} ${_PYTHON1_VERSIONS})
+endif(PythonInterp_FIND_VERSION)
+
+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}
+ )
+
+unset(_PYTHON_FIND_OTHER_VERSIONS)
+unset(_PYTHON1_VERSIONS)
+unset(_PYTHON2_VERSIONS)
+unset(_PYTHON3_VERSIONS)
+
+# Search for newest python version if python executable isn't found
+if(NOT PYTHON_EXECUTABLE)
+ foreach(_CURRENT_VERSION ${_Python_VERSIONS})
+ set(_Python_NAMES python${_CURRENT_VERSION})
+ if(WIN32)
+ list(APPEND _Python_NAMES python)
+ endif()
+ find_program(PYTHON_EXECUTABLE
+ NAMES ${_Python_NAMES}
+ PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]
+ )
+ endforeach()
+endif()
+
+# determine python version string
+if(PYTHON_EXECUTABLE)
+ execute_process(COMMAND "${PYTHON_EXECUTABLE}" -c
+ "import sys; sys.stdout.write(';'.join([str(x) for x in sys.version_info[:3]]))"
+ OUTPUT_VARIABLE _VERSION
+ RESULT_VARIABLE _PYTHON_VERSION_RESULT
+ ERROR_QUIET)
+ if(NOT _PYTHON_VERSION_RESULT)
+ string(REPLACE ";" "." PYTHON_VERSION_STRING "${_VERSION}")
+ list(GET _VERSION 0 PYTHON_VERSION_MAJOR)
+ list(GET _VERSION 1 PYTHON_VERSION_MINOR)
+ list(GET _VERSION 2 PYTHON_VERSION_PATCH)
+ if(PYTHON_VERSION_PATCH EQUAL 0)
+ # it's called "Python 2.7", not "2.7.0"
+ string(REGEX REPLACE "\\.0$" "" PYTHON_VERSION_STRING "${PYTHON_VERSION_STRING}")
+ endif()
+ else()
+ # sys.version predates sys.version_info, so use that
+ execute_process(COMMAND "${PYTHON_EXECUTABLE}" -c "import sys; sys.stdout.write(sys.version)"
+ OUTPUT_VARIABLE _VERSION
+ RESULT_VARIABLE _PYTHON_VERSION_RESULT
+ ERROR_QUIET)
+ if(NOT _PYTHON_VERSION_RESULT)
+ 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}")
+ else()
+ set(PYTHON_VERSION_PATCH "0")
+ endif()
+ else()
+ # sys.version was first documented for Python 1.5, so assume
+ # this is older.
+ set(PYTHON_VERSION_STRING "1.4")
+ set(PYTHON_VERSION_MAJOR "1")
+ set(PYTHON_VERSION_MAJOR "4")
+ set(PYTHON_VERSION_MAJOR "0")
+ endif()
+ endif()
+ unset(_PYTHON_VERSION_RESULT)
+ unset(_VERSION)
+endif(PYTHON_EXECUTABLE)
+
+# handle the QUIETLY and REQUIRED arguments and set PYTHONINTERP_FOUND to TRUE if
+# all listed variables are TRUE
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(PythonInterp REQUIRED_VARS PYTHON_EXECUTABLE VERSION_VAR PYTHON_VERSION_STRING)
+
+mark_as_advanced(PYTHON_EXECUTABLE)
diff --git a/Modules/FindPythonLibs.cmake b/Modules/FindPythonLibs.cmake
new file mode 100644
index 000000000..11ff19623
--- /dev/null
+++ b/Modules/FindPythonLibs.cmake
@@ -0,0 +1,275 @@
+# - 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:
+#
+# 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).
+#
+# 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
+
+#=============================================================================
+# 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.)
+
+INCLUDE(CMakeFindFrameworks)
+# Search for the python framework on Apple.
+CMAKE_FIND_FRAMEWORKS(Python)
+
+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)
+
+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}")
+ UNSET(_PYTHON_FIND_OTHER_VERSIONS)
+ IF(PythonLibs_FIND_VERSION_EXACT)
+ IF(_PYTHON_FIND_MAJ_MIN STREQUAL PythonLibs_FIND_VERSION)
+ SET(_PYTHON_FIND_OTHER_VERSIONS "${PythonLibs_FIND_VERSION}")
+ ELSE(_PYTHON_FIND_MAJ_MIN STREQUAL PythonLibs_FIND_VERSION)
+ SET(_PYTHON_FIND_OTHER_VERSIONS "${PythonLibs_FIND_VERSION}" "${_PYTHON_FIND_MAJ_MIN}")
+ ENDIF(_PYTHON_FIND_MAJ_MIN STREQUAL PythonLibs_FIND_VERSION)
+ ELSE(PythonLibs_FIND_VERSION_EXACT)
+ FOREACH(_PYTHON_V ${_PYTHON${_PYTHON_FIND_MAJ}_VERSIONS})
+ IF(NOT _PYTHON_V VERSION_LESS _PYTHON_FIND_MAJ_MIN)
+ LIST(APPEND _PYTHON_FIND_OTHER_VERSIONS ${_PYTHON_V})
+ ENDIF()
+ ENDFOREACH()
+ ENDIF(PythonLibs_FIND_VERSION_EXACT)
+ UNSET(_PYTHON_FIND_MAJ_MIN)
+ UNSET(_PYTHON_FIND_MAJ)
+ ELSE(PythonLibs_FIND_VERSION MATCHES "^[0-9]+\\.[0-9]+(\\.[0-9]+.*)?$")
+ SET(_PYTHON_FIND_OTHER_VERSIONS ${_PYTHON${PythonLibs_FIND_VERSION}_VERSIONS})
+ ENDIF(PythonLibs_FIND_VERSION MATCHES "^[0-9]+\\.[0-9]+(\\.[0-9]+.*)?$")
+ELSE(PythonLibs_FIND_VERSION)
+ SET(_PYTHON_FIND_OTHER_VERSIONS ${_PYTHON3_VERSIONS} ${_PYTHON2_VERSIONS} ${_PYTHON1_VERSIONS})
+ENDIF(PythonLibs_FIND_VERSION)
+
+# 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}
+ )
+
+UNSET(_PYTHON_FIND_OTHER_VERSIONS)
+UNSET(_PYTHON1_VERSIONS)
+UNSET(_PYTHON2_VERSIONS)
+UNSET(_PYTHON3_VERSIONS)
+
+FOREACH(_CURRENT_VERSION ${_Python_VERSIONS})
+ STRING(REPLACE "." "" _CURRENT_VERSION_NO_DOTS ${_CURRENT_VERSION})
+ IF(WIN32)
+ FIND_LIBRARY(PYTHON_DEBUG_LIBRARY
+ NAMES python${_CURRENT_VERSION_NO_DOTS}_d python
+ PATHS
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs/Debug
+ [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs/Debug
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs
+ [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_CURRENT_VERSION}\\InstallPath]/libs
+ )
+ ENDIF(WIN32)
+
+ 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}
+ PATHS
+ [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.
+ NO_SYSTEM_ENVIRONMENT_PATH
+ )
+ # Look for the static library in the Python config directory
+ FIND_LIBRARY(PYTHON_LIBRARY
+ NAMES python${_CURRENT_VERSION_NO_DOTS} python${_CURRENT_VERSION}
+ # Avoid finding the .dll in the PATH. We want the .lib.
+ NO_SYSTEM_ENVIRONMENT_PATH
+ # This is where the static library is usually located
+ 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(DEFINED PYTHON_INCLUDE_PATH AND NOT DEFINED PYTHON_INCLUDE_DIR)
+
+ 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(dir)
+ ENDIF(Python_FRAMEWORKS AND NOT PYTHON_INCLUDE_DIR)
+
+ 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}
+ )
+
+ # For backward compatibility, set PYTHON_INCLUDE_PATH.
+ SET(PYTHON_INCLUDE_PATH "${PYTHON_INCLUDE_DIR}")
+
+ IF(PYTHON_INCLUDE_DIR AND EXISTS "${PYTHON_INCLUDE_DIR}/patchlevel.h")
+ FILE(STRINGS "${PYTHON_INCLUDE_DIR}/patchlevel.h" python_version_str
+ REGEX "^#define[ \t]+PY_VERSION[ \t]+\"[^\"]+\"")
+ STRING(REGEX REPLACE "^#define[ \t]+PY_VERSION[ \t]+\"([^\"]+)\".*" "\\1"
+ PYTHONLIBS_VERSION_STRING "${python_version_str}")
+ UNSET(python_version_str)
+ ENDIF(PYTHON_INCLUDE_DIR AND EXISTS "${PYTHON_INCLUDE_DIR}/patchlevel.h")
+
+ IF(PYTHON_LIBRARY AND PYTHON_INCLUDE_DIR)
+ BREAK()
+ ENDIF(PYTHON_LIBRARY AND PYTHON_INCLUDE_DIR)
+ENDFOREACH(_CURRENT_VERSION)
+
+MARK_AS_ADVANCED(
+ PYTHON_DEBUG_LIBRARY
+ PYTHON_LIBRARY
+ PYTHON_INCLUDE_DIR
+)
+
+# We use PYTHON_INCLUDE_DIR, PYTHON_LIBRARY and PYTHON_DEBUG_LIBRARY for the
+# cache entries because they are meant to specify the location of a single
+# library. We now set the variables listed by the documentation for this
+# module.
+SET(PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIR}")
+SET(PYTHON_DEBUG_LIBRARIES "${PYTHON_DEBUG_LIBRARY}")
+
+# These variables have been historically named in this module different from
+# what SELECT_LIBRARY_CONFIGURATIONS() expects.
+SET(PYTHON_LIBRARY_DEBUG "${PYTHON_DEBUG_LIBRARY}")
+SET(PYTHON_LIBRARY_RELEASE "${PYTHON_LIBRARY}")
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
+SELECT_LIBRARY_CONFIGURATIONS(PYTHON)
+# SELECT_LIBRARY_CONFIGURATIONS() sets ${PREFIX}_FOUND if it has a library.
+# Unset this, this prefix doesn't match the module prefix, they are different
+# for historical reasons.
+UNSET(PYTHON_FOUND)
+
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(PythonLibs
+ REQUIRED_VARS PYTHON_LIBRARIES PYTHON_INCLUDE_DIRS
+ VERSION_VAR PYTHONLIBS_VERSION_STRING)
+
+# PYTHON_ADD_MODULE(<name> src1 src2 ... srcN) is used to build modules for python.
+# PYTHON_WRITE_MODULES_HEADER(<filename>) writes a header file you can include
+# in your sources to initialize the static python modules
+FUNCTION(PYTHON_ADD_MODULE _NAME )
+ GET_PROPERTY(_TARGET_SUPPORTS_SHARED_LIBS
+ GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS)
+ OPTION(PYTHON_ENABLE_MODULE_${_NAME} "Add module ${_NAME}" TRUE)
+ OPTION(PYTHON_MODULE_${_NAME}_BUILD_SHARED
+ "Add module ${_NAME} shared" ${_TARGET_SUPPORTS_SHARED_LIBS})
+
+ # Mark these options as advanced
+ MARK_AS_ADVANCED(PYTHON_ENABLE_MODULE_${_NAME}
+ PYTHON_MODULE_${_NAME}_BUILD_SHARED)
+
+ IF(PYTHON_ENABLE_MODULE_${_NAME})
+ IF(PYTHON_MODULE_${_NAME}_BUILD_SHARED)
+ SET(PY_MODULE_TYPE MODULE)
+ ELSE(PYTHON_MODULE_${_NAME}_BUILD_SHARED)
+ SET(PY_MODULE_TYPE STATIC)
+ SET_PROPERTY(GLOBAL APPEND PROPERTY PY_STATIC_MODULES_LIST ${_NAME})
+ ENDIF(PYTHON_MODULE_${_NAME}_BUILD_SHARED)
+
+ SET_PROPERTY(GLOBAL APPEND PROPERTY PY_MODULES_LIST ${_NAME})
+ ADD_LIBRARY(${_NAME} ${PY_MODULE_TYPE} ${ARGN})
+# TARGET_LINK_LIBRARIES(${_NAME} ${PYTHON_LIBRARIES})
+
+ IF(PYTHON_MODULE_${_NAME}_BUILD_SHARED)
+ SET_TARGET_PROPERTIES(${_NAME} PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}")
+ IF(WIN32 AND NOT CYGWIN)
+ SET_TARGET_PROPERTIES(${_NAME} PROPERTIES SUFFIX ".pyd")
+ ENDIF(WIN32 AND NOT CYGWIN)
+ ENDIF(PYTHON_MODULE_${_NAME}_BUILD_SHARED)
+
+ ENDIF(PYTHON_ENABLE_MODULE_${_NAME})
+ENDFUNCTION(PYTHON_ADD_MODULE)
+
+FUNCTION(PYTHON_WRITE_MODULES_HEADER _filename)
+
+ GET_PROPERTY(PY_STATIC_MODULES_LIST GLOBAL PROPERTY PY_STATIC_MODULES_LIST)
+
+ GET_FILENAME_COMPONENT(_name "${_filename}" NAME)
+ STRING(REPLACE "." "_" _name "${_name}")
+ STRING(TOUPPER ${_name} _nameUpper)
+ SET(_filename ${CMAKE_CURRENT_BINARY_DIR}/${_filename})
+
+ SET(_filenameTmp "${_filename}.in")
+ FILE(WRITE ${_filenameTmp} "/*Created by cmake, do not edit, changes will be lost*/\n")
+ FILE(APPEND ${_filenameTmp}
+"#ifndef ${_nameUpper}
+#define ${_nameUpper}
+
+#include <Python.h>
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif /* __cplusplus */
+
+")
+
+ FOREACH(_currentModule ${PY_STATIC_MODULES_LIST})
+ FILE(APPEND ${_filenameTmp} "extern void init${PYTHON_MODULE_PREFIX}${_currentModule}(void);\n\n")
+ ENDFOREACH(_currentModule ${PY_STATIC_MODULES_LIST})
+
+ FILE(APPEND ${_filenameTmp}
+"#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+")
+
+
+ FOREACH(_currentModule ${PY_STATIC_MODULES_LIST})
+ FILE(APPEND ${_filenameTmp} "int ${_name}_${_currentModule}(void) \n{\n static char name[]=\"${PYTHON_MODULE_PREFIX}${_currentModule}\"; return PyImport_AppendInittab(name, init${PYTHON_MODULE_PREFIX}${_currentModule});\n}\n\n")
+ ENDFOREACH(_currentModule ${PY_STATIC_MODULES_LIST})
+
+ FILE(APPEND ${_filenameTmp} "void ${_name}_LoadAllPythonModules(void)\n{\n")
+ FOREACH(_currentModule ${PY_STATIC_MODULES_LIST})
+ FILE(APPEND ${_filenameTmp} " ${_name}_${_currentModule}();\n")
+ ENDFOREACH(_currentModule ${PY_STATIC_MODULES_LIST})
+ FILE(APPEND ${_filenameTmp} "}\n\n")
+ FILE(APPEND ${_filenameTmp} "#ifndef EXCLUDE_LOAD_ALL_FUNCTION\nvoid CMakeLoadAllPythonModules(void)\n{\n ${_name}_LoadAllPythonModules();\n}\n#endif\n\n#endif\n")
+
+# with CONFIGURE_FILE() cmake complains that you may not use a file created using FILE(WRITE) as input file for CONFIGURE_FILE()
+ EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${_filenameTmp}" "${_filename}" OUTPUT_QUIET ERROR_QUIET)
+
+ENDFUNCTION(PYTHON_WRITE_MODULES_HEADER)
diff --git a/Modules/FindQt.cmake b/Modules/FindQt.cmake
new file mode 100644
index 000000000..2b8dfd7fb
--- /dev/null
+++ b/Modules/FindQt.cmake
@@ -0,0 +1,160 @@
+# - 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.
+#
+# 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.
+
+#=============================================================================
+# 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.)
+
+# look for signs of qt3 installations
+FILE(GLOB GLOB_TEMP_VAR /usr/lib/qt-3*/bin/qmake)
+IF(GLOB_TEMP_VAR)
+ SET(QT3_INSTALLED TRUE)
+ENDIF(GLOB_TEMP_VAR)
+SET(GLOB_TEMP_VAR)
+
+FILE(GLOB GLOB_TEMP_VAR /usr/local/qt-x11-commercial-3*/bin/qmake)
+IF(GLOB_TEMP_VAR)
+ SET(QT3_INSTALLED TRUE)
+ENDIF(GLOB_TEMP_VAR)
+SET(GLOB_TEMP_VAR)
+
+# look for qt4 installations
+FILE(GLOB GLOB_TEMP_VAR /usr/local/qt-x11-commercial-4*/bin/qmake)
+IF(GLOB_TEMP_VAR)
+ SET(QT4_INSTALLED TRUE)
+ENDIF(GLOB_TEMP_VAR)
+SET(GLOB_TEMP_VAR)
+
+FILE(GLOB GLOB_TEMP_VAR /usr/local/Trolltech/Qt-4*/bin/qmake)
+IF(GLOB_TEMP_VAR)
+ SET(QT4_INSTALLED TRUE)
+ENDIF(GLOB_TEMP_VAR)
+SET(GLOB_TEMP_VAR)
+
+# now find qmake
+FIND_PROGRAM(QT_QMAKE_EXECUTABLE_FINDQT NAMES qmake PATHS "${QT_SEARCH_PATH}/bin" "$ENV{QTDIR}/bin")
+IF(QT_QMAKE_EXECUTABLE_FINDQT)
+ EXEC_PROGRAM(${QT_QMAKE_EXECUTABLE_FINDQT} ARGS "-query QT_VERSION"
+ OUTPUT_VARIABLE QTVERSION)
+ IF(QTVERSION MATCHES "4.*")
+ SET(QT_QMAKE_EXECUTABLE ${QT_QMAKE_EXECUTABLE_FINDQT} CACHE PATH "QT4 qmake program.")
+ SET(QT4_INSTALLED TRUE)
+ ENDIF(QTVERSION MATCHES "4.*")
+ IF(QTVERSION MATCHES "Unknown")
+ SET(QT3_INSTALLED TRUE)
+ ENDIF(QTVERSION MATCHES "Unknown")
+ENDIF(QT_QMAKE_EXECUTABLE_FINDQT)
+
+IF(QT_QMAKE_EXECUTABLE_FINDQT)
+ EXEC_PROGRAM( ${QT_QMAKE_EXECUTABLE_FINDQT}
+ ARGS "-query QT_INSTALL_HEADERS"
+ OUTPUT_VARIABLE qt_headers )
+ENDIF(QT_QMAKE_EXECUTABLE_FINDQT)
+
+FIND_FILE( QT4_QGLOBAL_H_FILE qglobal.h
+ "${QT_SEARCH_PATH}/Qt/include"
+ "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\4.0.0;InstallDir]/include/Qt"
+ "[HKEY_CURRENT_USER\\Software\\Trolltech\\Versions\\4.0.0;InstallDir]/include/Qt"
+ ${qt_headers}/Qt
+ $ENV{QTDIR}/include/Qt
+ /usr/local/qt/include/Qt
+ /usr/local/include/Qt
+ /usr/lib/qt/include/Qt
+ /usr/include/Qt
+ /usr/share/qt4/include/Qt
+ C:/Progra~1/qt/include/Qt )
+
+IF(QT4_QGLOBAL_H_FILE)
+ SET(QT4_INSTALLED TRUE)
+ENDIF(QT4_QGLOBAL_H_FILE)
+
+FIND_FILE( QT3_QGLOBAL_H_FILE qglobal.h
+ "${QT_SEARCH_PATH}/Qt/include"
+ "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\3.2.1;InstallDir]/include/Qt"
+ "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\3.2.0;InstallDir]/include/Qt"
+ "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\3.1.0;InstallDir]/include/Qt"
+ C:/Qt/3.3.3Educational/include
+ $ENV{QTDIR}/include
+ /usr/include/qt3/Qt
+ /usr/local/qt/include
+ /usr/local/include
+ /usr/lib/qt/include
+ /usr/include
+ /usr/share/qt3/include
+ C:/Progra~1/qt/include
+ /usr/include/qt3 )
+
+IF(QT3_QGLOBAL_H_FILE)
+ SET(QT3_INSTALLED TRUE)
+ENDIF(QT3_QGLOBAL_H_FILE)
+
+IF(QT3_INSTALLED AND QT4_INSTALLED )
+ # force user to pick if we have both
+ SET(DESIRED_QT_VERSION 0 CACHE STRING "Pick a version of QT to use: 3 or 4")
+ELSE(QT3_INSTALLED AND QT4_INSTALLED )
+ # if only one found then pick that one
+ IF(QT3_INSTALLED)
+ SET(DESIRED_QT_VERSION 3 CACHE STRING "Pick a version of QT to use: 3 or 4")
+ ENDIF(QT3_INSTALLED)
+ IF(QT4_INSTALLED)
+ SET(DESIRED_QT_VERSION 4 CACHE STRING "Pick a version of QT to use: 3 or 4")
+ ENDIF(QT4_INSTALLED)
+ENDIF(QT3_INSTALLED AND QT4_INSTALLED )
+
+IF(DESIRED_QT_VERSION MATCHES 3)
+ SET(Qt3_FIND_REQUIRED ${Qt_FIND_REQUIRED})
+ SET(Qt3_FIND_QUIETLY ${Qt_FIND_QUIETLY})
+ INCLUDE(FindQt3)
+ENDIF(DESIRED_QT_VERSION MATCHES 3)
+IF(DESIRED_QT_VERSION MATCHES 4)
+ SET(Qt4_FIND_REQUIRED ${Qt_FIND_REQUIRED})
+ SET(Qt4_FIND_QUIETLY ${Qt_FIND_QUIETLY})
+ INCLUDE(FindQt4)
+ENDIF(DESIRED_QT_VERSION MATCHES 4)
+
+IF(NOT QT3_INSTALLED AND NOT QT4_INSTALLED)
+ IF(QT_REQUIRED)
+ MESSAGE(SEND_ERROR "CMake was unable to find any QT versions, put qmake in your path, or set QT_QMAKE_EXECUTABLE.")
+ ENDIF(QT_REQUIRED)
+ELSE(NOT QT3_INSTALLED AND NOT QT4_INSTALLED)
+ IF(NOT QT_FOUND AND NOT DESIRED_QT_VERSION)
+ IF(QT_REQUIRED)
+ MESSAGE(SEND_ERROR "Multiple versions of QT found please set DESIRED_QT_VERSION")
+ ELSE(QT_REQUIRED)
+ MESSAGE("Multiple versions of QT found please set DESIRED_QT_VERSION")
+ ENDIF(QT_REQUIRED)
+ ENDIF(NOT QT_FOUND AND NOT DESIRED_QT_VERSION)
+ 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.")
+ ELSE(QT_REQUIRED)
+ 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.")
+ ENDIF(QT_REQUIRED)
+ ENDIF(NOT QT_FOUND AND DESIRED_QT_VERSION)
+ENDIF(NOT QT3_INSTALLED AND NOT QT4_INSTALLED)
+MARK_AS_ADVANCED(QT3_QGLOBAL_H_FILE QT4_QGLOBAL_H_FILE QT_QMAKE_EXECUTABLE_FINDQT)
diff --git a/Modules/FindQt3.cmake b/Modules/FindQt3.cmake
new file mode 100644
index 000000000..2d8dbde22
--- /dev/null
+++ b/Modules/FindQt3.cmake
@@ -0,0 +1,302 @@
+# - 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
+#
+# 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.
+
+# 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
+
+#=============================================================================
+# 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.)
+
+# If Qt4 has already been found, fail.
+IF(QT4_FOUND)
+ IF(Qt3_FIND_REQUIRED)
+ MESSAGE( FATAL_ERROR "Qt3 and Qt4 cannot be used together in one project.")
+ ELSE(Qt3_FIND_REQUIRED)
+ IF(NOT Qt3_FIND_QUIETLY)
+ MESSAGE( STATUS "Qt3 and Qt4 cannot be used together in one project.")
+ ENDIF(NOT Qt3_FIND_QUIETLY)
+ RETURN()
+ ENDIF(Qt3_FIND_REQUIRED)
+ENDIF(QT4_FOUND)
+
+
+FILE(GLOB GLOB_PATHS /usr/lib/qt-3*)
+FOREACH(GLOB_PATH ${GLOB_PATHS})
+ LIST(APPEND GLOB_PATHS_BIN "${GLOB_PATH}/bin")
+ENDFOREACH(GLOB_PATH)
+FIND_PATH(QT_INCLUDE_DIR qt.h
+ "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\3.2.1;InstallDir]/include/Qt"
+ "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\3.2.0;InstallDir]/include/Qt"
+ "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\3.1.0;InstallDir]/include/Qt"
+ $ENV{QTDIR}/include
+ ${GLOB_PATHS}
+ /usr/local/qt/include
+ /usr/lib/qt/include
+ /usr/lib/qt3/include
+ /usr/include/qt
+ /usr/share/qt3/include
+ C:/Progra~1/qt/include
+ /usr/include/qt3
+ )
+
+# if qglobal.h is not in the qt_include_dir then set
+# QT_INCLUDE_DIR to NOTFOUND
+IF(NOT EXISTS ${QT_INCLUDE_DIR}/qglobal.h)
+ SET(QT_INCLUDE_DIR QT_INCLUDE_DIR-NOTFOUND CACHE PATH "path to Qt3 include directory" FORCE)
+ENDIF(NOT EXISTS ${QT_INCLUDE_DIR}/qglobal.h)
+
+IF(QT_INCLUDE_DIR)
+ #extract the version string from qglobal.h
+ FILE(READ ${QT_INCLUDE_DIR}/qglobal.h QGLOBAL_H)
+ STRING(REGEX MATCH "#define[\t ]+QT_VERSION_STR[\t ]+\"[0-9]+.[0-9]+.[0-9]+[a-z]*\"" QGLOBAL_H "${QGLOBAL_H}")
+ STRING(REGEX REPLACE ".*\"([0-9]+.[0-9]+.[0-9]+[a-z]*)\".*" "\\1" qt_version_str "${QGLOBAL_H}")
+
+ # Under windows the qt library (MSVC) has the format qt-mtXYZ where XYZ is the
+ # version X.Y.Z, so we need to remove the dots from version
+ STRING(REGEX REPLACE "\\." "" qt_version_str_lib "${qt_version_str}")
+ SET(QT_VERSION_STRING "${qt_version_str}")
+ENDIF(QT_INCLUDE_DIR)
+
+FILE(GLOB GLOB_PATHS_LIB /usr/lib/qt-3*/lib/)
+IF (QT_MT_REQUIRED)
+ FIND_LIBRARY(QT_QT_LIBRARY
+ NAMES
+ qt-mt qt-mt${qt_version_str_lib} qt-mtnc${qt_version_str_lib}
+ qt-mtedu${qt_version_str_lib} qt-mt230nc qt-mtnc321 qt-mt3
+ PATHS
+ "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\3.2.1;InstallDir]/lib"
+ "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\3.2.0;InstallDir]/lib"
+ "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\3.1.0;InstallDir]/lib"
+ $ENV{QTDIR}/lib
+ ${GLOB_PATHS_LIB}
+ /usr/local/qt/lib
+ /usr/lib/qt/lib
+ /usr/lib/qt3/lib
+ /usr/lib/qt3/lib64
+ /usr/share/qt3/lib
+ C:/Progra~1/qt/lib
+ )
+
+ELSE (QT_MT_REQUIRED)
+ FIND_LIBRARY(QT_QT_LIBRARY
+ NAMES
+ qt qt-${qt_version_str_lib} qt-edu${qt_version_str_lib}
+ qt-mt qt-mt${qt_version_str_lib} qt-mtnc${qt_version_str_lib}
+ qt-mtedu${qt_version_str_lib} qt-mt230nc qt-mtnc321 qt-mt3
+ PATHS
+ "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\3.2.1;InstallDir]/lib"
+ "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\3.2.0;InstallDir]/lib"
+ "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\3.1.0;InstallDir]/lib"
+ $ENV{QTDIR}/lib
+ ${GLOB_PATHS_LIB}
+ /usr/local/qt/lib
+ /usr/lib/qt/lib
+ /usr/lib/qt3/lib
+ /usr/lib/qt3/lib64
+ /usr/share/qt3/lib
+ C:/Progra~1/qt/lib
+ )
+ENDIF (QT_MT_REQUIRED)
+
+
+FIND_LIBRARY(QT_QASSISTANTCLIENT_LIBRARY
+ NAMES qassistantclient
+ PATHS
+ "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\3.2.1;InstallDir]/lib"
+ "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\3.2.0;InstallDir]/lib"
+ "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\3.1.0;InstallDir]/lib"
+ $ENV{QTDIR}/lib
+ ${GLOB_PATHS_LIB}
+ /usr/local/qt/lib
+ /usr/lib/qt3/lib
+ /usr/lib/qt3/lib64
+ /usr/share/qt3/lib
+ C:/Progra~1/qt/lib
+ )
+
+# qt 3 should prefer QTDIR over the PATH
+FIND_PROGRAM(QT_MOC_EXECUTABLE
+ NAMES moc-qt3 moc
+ HINTS
+ $ENV{QTDIR}/bin
+ PATHS
+ "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\3.2.1;InstallDir]/include/Qt"
+ "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\3.2.0;InstallDir]/include/Qt"
+ "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\3.1.0;InstallDir]/include/Qt"
+ $ENV{QTDIR}/bin
+ ${GLOB_PATHS_BIN}
+ /usr/local/qt/bin
+ /usr/lib/qt/bin
+ /usr/lib/qt3/bin
+ /usr/share/qt3/bin
+ C:/Progra~1/qt/bin
+ /usr/X11R6/bin
+ )
+
+IF(QT_MOC_EXECUTABLE)
+ SET ( QT_WRAP_CPP "YES")
+ENDIF(QT_MOC_EXECUTABLE)
+
+# qt 3 should prefer QTDIR over the PATH
+FIND_PROGRAM(QT_UIC_EXECUTABLE
+ NAMES uic-qt3 uic
+ HINTS
+ $ENV{QTDIR}/bin
+ PATHS
+ "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\3.2.1;InstallDir]/include/Qt"
+ "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\3.2.0;InstallDir]/include/Qt"
+ "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\3.1.0;InstallDir]/include/Qt"
+ ${GLOB_PATHS_BIN}
+ /usr/local/qt/bin
+ /usr/lib/qt/bin
+ /usr/lib/qt3/bin
+ /usr/share/qt3/bin
+ C:/Progra~1/qt/bin
+ /usr/X11R6/bin
+ )
+
+IF(QT_UIC_EXECUTABLE)
+ SET ( QT_WRAP_UI "YES")
+ENDIF(QT_UIC_EXECUTABLE)
+
+IF (WIN32)
+ FIND_LIBRARY(QT_QTMAIN_LIBRARY qtmain
+ HINTS
+ $ENV{QTDIR}/lib
+ "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\3.2.1;InstallDir]/lib"
+ "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\3.2.0;InstallDir]/lib"
+ "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\3.1.0;InstallDir]/lib"
+ PATHS
+ "$ENV{ProgramFiles}/qt/lib"
+ "C:/Program Files/qt/lib"
+ DOC "This Library is only needed by and included with Qt3 on MSWindows. It should be NOTFOUND, undefined or IGNORE otherwise."
+ )
+ENDIF (WIN32)
+
+#support old QT_MIN_VERSION if set, but not if version is supplied by find_package()
+IF(NOT Qt3_FIND_VERSION AND QT_MIN_VERSION)
+ SET(Qt3_FIND_VERSION ${QT_MIN_VERSION})
+ENDIF(NOT Qt3_FIND_VERSION AND QT_MIN_VERSION)
+
+# if the include a library are found then we have it
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Qt3
+ REQUIRED_VARS QT_QT_LIBRARY QT_INCLUDE_DIR QT_MOC_EXECUTABLE
+ VERSION_VAR QT_VERSION_STRING)
+SET(QT_FOUND ${QT3_FOUND} )
+
+IF(QT_FOUND)
+ SET( QT_LIBRARIES ${QT_LIBRARIES} ${QT_QT_LIBRARY} )
+ SET( QT_DEFINITIONS "")
+
+ IF (WIN32 AND NOT CYGWIN)
+ IF (QT_QTMAIN_LIBRARY)
+ # for version 3
+ SET (QT_DEFINITIONS -DQT_DLL -DQT_THREAD_SUPPORT -DNO_DEBUG)
+ SET (QT_LIBRARIES imm32.lib ${QT_QT_LIBRARY} ${QT_QTMAIN_LIBRARY} )
+ SET (QT_LIBRARIES ${QT_LIBRARIES} winmm wsock32)
+ ELSE (QT_QTMAIN_LIBRARY)
+ # for version 2
+ SET (QT_LIBRARIES imm32.lib ws2_32.lib ${QT_QT_LIBRARY} )
+ ENDIF (QT_QTMAIN_LIBRARY)
+ ELSE (WIN32 AND NOT CYGWIN)
+ SET (QT_LIBRARIES ${QT_QT_LIBRARY} )
+
+ SET (QT_DEFINITIONS -DQT_SHARED -DQT_NO_DEBUG)
+ IF(QT_QT_LIBRARY MATCHES "qt-mt")
+ SET (QT_DEFINITIONS ${QT_DEFINITIONS} -DQT_THREAD_SUPPORT -D_REENTRANT)
+ ENDIF(QT_QT_LIBRARY MATCHES "qt-mt")
+
+ ENDIF (WIN32 AND NOT CYGWIN)
+
+ IF (QT_QASSISTANTCLIENT_LIBRARY)
+ SET (QT_LIBRARIES ${QT_QASSISTANTCLIENT_LIBRARY} ${QT_LIBRARIES})
+ ENDIF (QT_QASSISTANTCLIENT_LIBRARY)
+
+ # Backwards compatibility for CMake1.4 and 1.2
+ SET (QT_MOC_EXE ${QT_MOC_EXECUTABLE} )
+ SET (QT_UIC_EXE ${QT_UIC_EXECUTABLE} )
+ # for unix add X11 stuff
+ IF(UNIX)
+ FIND_PACKAGE(X11)
+ IF (X11_FOUND)
+ SET (QT_LIBRARIES ${QT_LIBRARIES} ${X11_LIBRARIES})
+ ENDIF (X11_FOUND)
+ IF (CMAKE_DL_LIBS)
+ SET (QT_LIBRARIES ${QT_LIBRARIES} ${CMAKE_DL_LIBS})
+ ENDIF (CMAKE_DL_LIBS)
+ ENDIF(UNIX)
+ IF(QT_QT_LIBRARY MATCHES "qt-mt")
+ FIND_PACKAGE(Threads)
+ SET(QT_LIBRARIES ${QT_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
+ ENDIF(QT_QT_LIBRARY MATCHES "qt-mt")
+ENDIF(QT_FOUND)
+
+IF(QT_MOC_EXECUTABLE)
+ EXECUTE_PROCESS(COMMAND ${QT_MOC_EXECUTABLE} "-v"
+ OUTPUT_VARIABLE QTVERSION_MOC
+ ERROR_QUIET)
+ENDIF(QT_MOC_EXECUTABLE)
+IF(QT_UIC_EXECUTABLE)
+ EXECUTE_PROCESS(COMMAND ${QT_UIC_EXECUTABLE} "-version"
+ OUTPUT_VARIABLE QTVERSION_UIC
+ ERROR_QUIET)
+ENDIF(QT_UIC_EXECUTABLE)
+
+SET(_QT_UIC_VERSION_3 FALSE)
+IF("${QTVERSION_UIC}" MATCHES ".* 3..*")
+ SET(_QT_UIC_VERSION_3 TRUE)
+ENDIF("${QTVERSION_UIC}" MATCHES ".* 3..*")
+
+SET(_QT_MOC_VERSION_3 FALSE)
+IF("${QTVERSION_MOC}" MATCHES ".* 3..*")
+ SET(_QT_MOC_VERSION_3 TRUE)
+ENDIF("${QTVERSION_MOC}" MATCHES ".* 3..*")
+
+SET(QT_WRAP_CPP FALSE)
+IF (QT_MOC_EXECUTABLE AND _QT_MOC_VERSION_3)
+ SET ( QT_WRAP_CPP TRUE)
+ENDIF (QT_MOC_EXECUTABLE AND _QT_MOC_VERSION_3)
+
+SET(QT_WRAP_UI FALSE)
+IF (QT_UIC_EXECUTABLE AND _QT_UIC_VERSION_3)
+ SET ( QT_WRAP_UI TRUE)
+ENDIF (QT_UIC_EXECUTABLE AND _QT_UIC_VERSION_3)
+
+MARK_AS_ADVANCED(
+ QT_INCLUDE_DIR
+ QT_QT_LIBRARY
+ QT_QTMAIN_LIBRARY
+ QT_QASSISTANTCLIENT_LIBRARY
+ QT_UIC_EXECUTABLE
+ QT_MOC_EXECUTABLE
+ QT_WRAP_CPP
+ QT_WRAP_UI
+ )
diff --git a/Modules/FindQt4.cmake b/Modules/FindQt4.cmake
new file mode 100644
index 000000000..2f1708d70
--- /dev/null
+++ b/Modules/FindQt4.cmake
@@ -0,0 +1,1216 @@
+# - 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.
+#
+# 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.
+#
+# 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-direcotry 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 ... )
+# 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 a 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 exists and are not updated in any way.
+#
+#
+# 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.
+#
+# 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
+#
+#
+# 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
+
+#=============================================================================
+# 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.)
+
+# Use FIND_PACKAGE( Qt4 COMPONENTS ... ) to enable modules
+IF( Qt4_FIND_COMPONENTS )
+ FOREACH( component ${Qt4_FIND_COMPONENTS} )
+ STRING( TOUPPER ${component} _COMPONENT )
+ SET( QT_USE_${_COMPONENT} 1 )
+ ENDFOREACH( component )
+
+ # To make sure we don't use QtCore or QtGui when not in COMPONENTS
+ IF(NOT QT_USE_QTCORE)
+ SET( QT_DONT_USE_QTCORE 1 )
+ ENDIF(NOT QT_USE_QTCORE)
+
+ IF(NOT QT_USE_QTGUI)
+ SET( QT_DONT_USE_QTGUI 1 )
+ ENDIF(NOT QT_USE_QTGUI)
+
+ENDIF( Qt4_FIND_COMPONENTS )
+
+# If Qt3 has already been found, fail.
+IF(QT_QT_LIBRARY)
+ IF(Qt4_FIND_REQUIRED)
+ MESSAGE( FATAL_ERROR "Qt3 and Qt4 cannot be used together in one project. If switching to Qt4, the CMakeCache.txt needs to be cleaned.")
+ ELSE(Qt4_FIND_REQUIRED)
+ IF(NOT Qt4_FIND_QUIETLY)
+ MESSAGE( STATUS "Qt3 and Qt4 cannot be used together in one project. If switching to Qt4, the CMakeCache.txt needs to be cleaned.")
+ ENDIF(NOT Qt4_FIND_QUIETLY)
+ RETURN()
+ ENDIF(Qt4_FIND_REQUIRED)
+ENDIF(QT_QT_LIBRARY)
+
+
+INCLUDE(CheckCXXSymbolExists)
+INCLUDE(MacroAddFileDependencies)
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+
+SET(QT_USE_FILE ${CMAKE_ROOT}/Modules/UseQt4.cmake)
+
+SET( QT_DEFINITIONS "")
+
+# convenience macro for dealing with debug/release library names
+MACRO (_QT4_ADJUST_LIB_VARS _camelCaseBasename)
+
+ STRING(TOUPPER "${_camelCaseBasename}" basename)
+
+ # The name of the imported targets, i.e. the prefix "Qt4::" must not change,
+ # since it is stored in EXPORT-files as name of a required library. If the name would change
+ # here, this would lead to the imported Qt4-library targets not being resolved by cmake anymore.
+ IF (QT_${basename}_LIBRARY_RELEASE OR QT_${basename}_LIBRARY_DEBUG)
+
+ IF(NOT TARGET Qt4::${_camelCaseBasename})
+ ADD_LIBRARY(Qt4::${_camelCaseBasename} UNKNOWN IMPORTED )
+
+ IF (QT_${basename}_LIBRARY_RELEASE)
+ SET_PROPERTY(TARGET Qt4::${_camelCaseBasename} APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
+ if(QT_USE_FRAMEWORKS)
+ SET_PROPERTY(TARGET Qt4::${_camelCaseBasename} PROPERTY IMPORTED_LOCATION_RELEASE "${QT_${basename}_LIBRARY_RELEASE}/${_camelCaseBasename}" )
+ else()
+ SET_PROPERTY(TARGET Qt4::${_camelCaseBasename} PROPERTY IMPORTED_LOCATION_RELEASE "${QT_${basename}_LIBRARY_RELEASE}" )
+ endif()
+ ENDIF (QT_${basename}_LIBRARY_RELEASE)
+
+ IF (QT_${basename}_LIBRARY_DEBUG)
+ SET_PROPERTY(TARGET Qt4::${_camelCaseBasename} APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
+ if(QT_USE_FRAMEWORKS)
+ SET_PROPERTY(TARGET Qt4::${_camelCaseBasename} PROPERTY IMPORTED_LOCATION_DEBUG "${QT_${basename}_LIBRARY_DEBUG}/${_camelCaseBasename}" )
+ else()
+ SET_PROPERTY(TARGET Qt4::${_camelCaseBasename} PROPERTY IMPORTED_LOCATION_DEBUG "${QT_${basename}_LIBRARY_DEBUG}" )
+ endif()
+ ENDIF (QT_${basename}_LIBRARY_DEBUG)
+ ENDIF(NOT TARGET Qt4::${_camelCaseBasename})
+
+ # If QT_USE_IMPORTED_TARGETS is enabled, the QT_QTFOO_LIBRARY variables are set to point at these
+ # imported targets. This works better in general, and is also in almost all cases fully
+ # backward compatible. The only issue is when a project A which had this enabled then exports its
+ # libraries via export or EXPORT_LIBRARY_DEPENDENCIES(). In this case the libraries from project
+ # A will depend on the imported Qt targets, and the names of these imported targets will be stored
+ # in the dependency files on disk. This means when a project B then uses project A, these imported
+ # targets must be created again, otherwise e.g. "Qt4__QtCore" will be interpreted as name of a
+ # library file on disk, and not as a target, and linking will fail:
+ IF(QT_USE_IMPORTED_TARGETS)
+ SET(QT_${basename}_LIBRARY Qt4::${_camelCaseBasename} )
+ SET(QT_${basename}_LIBRARIES Qt4::${_camelCaseBasename} )
+ ELSE(QT_USE_IMPORTED_TARGETS)
+
+ # if the release- as well as the debug-version of the library have been found:
+ IF (QT_${basename}_LIBRARY_DEBUG AND QT_${basename}_LIBRARY_RELEASE)
+ # if the generator supports configuration types then set
+ # optimized and debug libraries, or if the CMAKE_BUILD_TYPE has a value
+ IF (CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE)
+ SET(QT_${basename}_LIBRARY optimized ${QT_${basename}_LIBRARY_RELEASE} debug ${QT_${basename}_LIBRARY_DEBUG})
+ ELSE(CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE)
+ # if there are no configuration types and CMAKE_BUILD_TYPE has no value
+ # then just use the release libraries
+ SET(QT_${basename}_LIBRARY ${QT_${basename}_LIBRARY_RELEASE} )
+ ENDIF(CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE)
+ SET(QT_${basename}_LIBRARIES optimized ${QT_${basename}_LIBRARY_RELEASE} debug ${QT_${basename}_LIBRARY_DEBUG})
+ ENDIF (QT_${basename}_LIBRARY_DEBUG AND QT_${basename}_LIBRARY_RELEASE)
+
+ # if only the release version was found, set the debug variable also to the release version
+ IF (QT_${basename}_LIBRARY_RELEASE AND NOT QT_${basename}_LIBRARY_DEBUG)
+ SET(QT_${basename}_LIBRARY_DEBUG ${QT_${basename}_LIBRARY_RELEASE})
+ SET(QT_${basename}_LIBRARY ${QT_${basename}_LIBRARY_RELEASE})
+ SET(QT_${basename}_LIBRARIES ${QT_${basename}_LIBRARY_RELEASE})
+ ENDIF (QT_${basename}_LIBRARY_RELEASE AND NOT QT_${basename}_LIBRARY_DEBUG)
+
+ # if only the debug version was found, set the release variable also to the debug version
+ IF (QT_${basename}_LIBRARY_DEBUG AND NOT QT_${basename}_LIBRARY_RELEASE)
+ SET(QT_${basename}_LIBRARY_RELEASE ${QT_${basename}_LIBRARY_DEBUG})
+ SET(QT_${basename}_LIBRARY ${QT_${basename}_LIBRARY_DEBUG})
+ SET(QT_${basename}_LIBRARIES ${QT_${basename}_LIBRARY_DEBUG})
+ ENDIF (QT_${basename}_LIBRARY_DEBUG AND NOT QT_${basename}_LIBRARY_RELEASE)
+
+ # put the value in the cache:
+ SET(QT_${basename}_LIBRARY ${QT_${basename}_LIBRARY} CACHE STRING "The Qt ${basename} library" FORCE)
+
+ ENDIF(QT_USE_IMPORTED_TARGETS)
+
+ SET(QT_${basename}_FOUND 1)
+
+ ELSE (QT_${basename}_LIBRARY_RELEASE OR QT_${basename}_LIBRARY_DEBUG)
+
+ SET(QT_${basename}_LIBRARY "" CACHE STRING "The Qt ${basename} library" FORCE)
+
+ ENDIF (QT_${basename}_LIBRARY_RELEASE OR QT_${basename}_LIBRARY_DEBUG)
+
+ IF (QT_${basename}_INCLUDE_DIR)
+ #add the include directory to QT_INCLUDES
+ SET(QT_INCLUDES "${QT_${basename}_INCLUDE_DIR}" ${QT_INCLUDES})
+ ENDIF (QT_${basename}_INCLUDE_DIR)
+
+ # Make variables changeble to the advanced user
+ MARK_AS_ADVANCED(QT_${basename}_LIBRARY QT_${basename}_LIBRARY_RELEASE QT_${basename}_LIBRARY_DEBUG QT_${basename}_INCLUDE_DIR)
+ENDMACRO (_QT4_ADJUST_LIB_VARS)
+
+function(_QT4_QUERY_QMAKE VAR RESULT)
+ execute_process(COMMAND "${QT_QMAKE_EXECUTABLE}" -query ${VAR}
+ RESULT_VARIABLE return_code
+ OUTPUT_VARIABLE output ERROR_VARIABLE output
+ OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_STRIP_TRAILING_WHITESPACE)
+ if(NOT return_code)
+ file(TO_CMAKE_PATH "${output}" output)
+ set(${RESULT} ${output} PARENT_SCOPE)
+ endif(NOT return_code)
+endfunction(_QT4_QUERY_QMAKE)
+
+
+SET(QT4_INSTALLED_VERSION_TOO_OLD FALSE)
+
+GET_FILENAME_COMPONENT(qt_install_version "[HKEY_CURRENT_USER\\Software\\trolltech\\Versions;DefaultQtVersion]" NAME)
+# check for qmake
+# Debian uses qmake-qt4
+# macports' Qt uses qmake-mac
+FIND_PROGRAM(QT_QMAKE_EXECUTABLE NAMES qmake qmake4 qmake-qt4 qmake-mac PATHS
+ "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\4.0.0;InstallDir]/bin"
+ "[HKEY_CURRENT_USER\\Software\\Trolltech\\Versions\\4.0.0;InstallDir]/bin"
+ "[HKEY_CURRENT_USER\\Software\\Trolltech\\Versions\\${qt_install_version};InstallDir]/bin"
+ $ENV{QTDIR}/bin
+ DOC "The qmake executable for the Qt installation to use"
+)
+
+# double check that it was a Qt4 qmake, if not, re-find with different names
+IF (QT_QMAKE_EXECUTABLE)
+
+ IF(QT_QMAKE_EXECUTABLE_LAST)
+ STRING(COMPARE NOTEQUAL "${QT_QMAKE_EXECUTABLE_LAST}" "${QT_QMAKE_EXECUTABLE}" QT_QMAKE_CHANGED)
+ ENDIF(QT_QMAKE_EXECUTABLE_LAST)
+
+ SET(QT_QMAKE_EXECUTABLE_LAST "${QT_QMAKE_EXECUTABLE}" CACHE INTERNAL "" FORCE)
+
+ _qt4_query_qmake(QT_VERSION QTVERSION)
+
+ # check for qt3 qmake and then try and find qmake4 or qmake-qt4 in the path
+ IF(NOT QTVERSION)
+ SET(QT_QMAKE_EXECUTABLE NOTFOUND CACHE FILEPATH "" FORCE)
+ FIND_PROGRAM(QT_QMAKE_EXECUTABLE NAMES qmake4 qmake-qt4 PATHS
+ "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\4.0.0;InstallDir]/bin"
+ "[HKEY_CURRENT_USER\\Software\\Trolltech\\Versions\\4.0.0;InstallDir]/bin"
+ $ENV{QTDIR}/bin
+ DOC "The qmake executable for the Qt installation to use"
+ )
+ IF(QT_QMAKE_EXECUTABLE)
+ _qt4_query_qmake(QT_VERSION QTVERSION)
+ ENDIF(QT_QMAKE_EXECUTABLE)
+ ENDIF(NOT QTVERSION)
+
+ENDIF (QT_QMAKE_EXECUTABLE)
+
+IF (QT_QMAKE_EXECUTABLE AND QTVERSION)
+
+ # ask qmake for the mkspecs directory
+ # we do this first because QT_LIBINFIX might be set
+ IF (NOT QT_MKSPECS_DIR OR QT_QMAKE_CHANGED)
+ _qt4_query_qmake(QMAKE_MKSPECS qt_mkspecs_dirs)
+ # do not replace : on windows as it might be a drive letter
+ # and windows should already use ; as a separator
+ IF(NOT WIN32)
+ STRING(REPLACE ":" ";" qt_mkspecs_dirs "${qt_mkspecs_dirs}")
+ ENDIF(NOT WIN32)
+ set(qt_cross_paths)
+ foreach(qt_cross_path ${CMAKE_FIND_ROOT_PATH})
+ set(qt_cross_paths ${qt_cross_paths} "${qt_cross_path}/mkspecs")
+ endforeach(qt_cross_path)
+ 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")
+ ENDIF()
+
+ IF(EXISTS "${QT_MKSPECS_DIR}/qconfig.pri")
+ FILE(READ ${QT_MKSPECS_DIR}/qconfig.pri _qconfig_FILE_contents)
+ STRING(REGEX MATCH "QT_CONFIG[^\n]+" QT_QCONFIG "${_qconfig_FILE_contents}")
+ STRING(REGEX MATCH "CONFIG[^\n]+" QT_CONFIG "${_qconfig_FILE_contents}")
+ STRING(REGEX MATCH "EDITION[^\n]+" QT_EDITION "${_qconfig_FILE_contents}")
+ STRING(REGEX MATCH "QT_LIBINFIX[^\n]+" _qconfig_qt_libinfix "${_qconfig_FILE_contents}")
+ STRING(REGEX REPLACE "QT_LIBINFIX *= *([^\n]*)" "\\1" QT_LIBINFIX "${_qconfig_qt_libinfix}")
+ ENDIF(EXISTS "${QT_MKSPECS_DIR}/qconfig.pri")
+ IF("${QT_EDITION}" MATCHES "DesktopLight")
+ SET(QT_EDITION_DESKTOPLIGHT 1)
+ ENDIF("${QT_EDITION}" MATCHES "DesktopLight")
+
+ # ask qmake for the library dir as a hint, then search for QtCore library and use that as a reference for finding the
+ # others and for setting QT_LIBRARY_DIR
+ IF (NOT (QT_QTCORE_LIBRARY_RELEASE OR QT_QTCORE_LIBRARY_DEBUG) OR QT_QMAKE_CHANGED)
+ _qt4_query_qmake(QT_INSTALL_LIBS QT_LIBRARY_DIR_TMP)
+ SET(QT_QTCORE_LIBRARY_RELEASE NOTFOUND)
+ SET(QT_QTCORE_LIBRARY_DEBUG NOTFOUND)
+ FIND_LIBRARY(QT_QTCORE_LIBRARY_RELEASE
+ NAMES QtCore${QT_LIBINFIX} QtCore${QT_LIBINFIX}4
+ HINTS ${QT_LIBRARY_DIR_TMP}
+ NO_DEFAULT_PATH
+ )
+ FIND_LIBRARY(QT_QTCORE_LIBRARY_DEBUG
+ NAMES QtCore${QT_LIBINFIX}_debug QtCore${QT_LIBINFIX}d QtCore${QT_LIBINFIX}d4
+ HINTS ${QT_LIBRARY_DIR_TMP}
+ NO_DEFAULT_PATH
+ )
+
+ IF(NOT QT_QTCORE_LIBRARY_RELEASE AND NOT QT_QTCORE_LIBRARY_DEBUG)
+ FIND_LIBRARY(QT_QTCORE_LIBRARY_RELEASE
+ NAMES QtCore${QT_LIBINFIX} QtCore${QT_LIBINFIX}4
+ HINTS ${QT_LIBRARY_DIR_TMP}
+ )
+ FIND_LIBRARY(QT_QTCORE_LIBRARY_DEBUG
+ NAMES QtCore${QT_LIBINFIX}_debug QtCore${QT_LIBINFIX}d QtCore${QT_LIBINFIX}d4
+ HINTS ${QT_LIBRARY_DIR_TMP}
+ )
+ ENDIF(NOT QT_QTCORE_LIBRARY_RELEASE AND NOT QT_QTCORE_LIBRARY_DEBUG)
+
+ # try dropping a hint if trying to use Visual Studio with Qt built by mingw
+ IF(NOT QT_QTCORE_LIBRARY_RELEASE AND MSVC)
+ IF(EXISTS ${QT_LIBRARY_DIR_TMP}/libqtmain.a)
+ MESSAGE( FATAL_ERROR "It appears you're trying to use Visual Studio with Qt built by mingw. Those compilers do not produce code compatible with each other.")
+ ENDIF(EXISTS ${QT_LIBRARY_DIR_TMP}/libqtmain.a)
+ ENDIF(NOT QT_QTCORE_LIBRARY_RELEASE AND MSVC)
+
+ ENDIF ()
+
+ # set QT_LIBRARY_DIR based on location of QtCore found.
+ IF(QT_QTCORE_LIBRARY_RELEASE)
+ GET_FILENAME_COMPONENT(QT_LIBRARY_DIR_TMP "${QT_QTCORE_LIBRARY_RELEASE}" PATH)
+ SET(QT_LIBRARY_DIR ${QT_LIBRARY_DIR_TMP} CACHE INTERNAL "Qt library dir" FORCE)
+ SET(QT_QTCORE_FOUND 1)
+ ELSEIF(QT_QTCORE_LIBRARY_DEBUG)
+ GET_FILENAME_COMPONENT(QT_LIBRARY_DIR_TMP "${QT_QTCORE_LIBRARY_DEBUG}" PATH)
+ 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(Qt4_FIND_REQUIRED)
+ MESSAGE( FATAL_ERROR "Could NOT find QtCore. Check ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log for more details.")
+ ENDIF(Qt4_FIND_REQUIRED)
+ ENDIF()
+
+ # ask qmake for the binary dir
+ IF (NOT QT_BINARY_DIR OR QT_QMAKE_CHANGED)
+ _qt4_query_qmake(QT_INSTALL_BINS qt_bins)
+ SET(QT_BINARY_DIR ${qt_bins} CACHE INTERNAL "" FORCE)
+ ENDIF (NOT QT_BINARY_DIR OR QT_QMAKE_CHANGED)
+
+ IF (APPLE)
+ SET(CMAKE_FIND_FRAMEWORK_OLD ${CMAKE_FIND_FRAMEWORK})
+ IF (EXISTS ${QT_LIBRARY_DIR}/QtCore.framework)
+ SET(QT_USE_FRAMEWORKS ON CACHE INTERNAL "" FORCE)
+ SET(CMAKE_FIND_FRAMEWORK FIRST)
+ ELSE (EXISTS ${QT_LIBRARY_DIR}/QtCore.framework)
+ SET(QT_USE_FRAMEWORKS OFF CACHE INTERNAL "" FORCE)
+ SET(CMAKE_FIND_FRAMEWORK LAST)
+ ENDIF (EXISTS ${QT_LIBRARY_DIR}/QtCore.framework)
+ ENDIF (APPLE)
+
+ # ask qmake for the include dir
+ IF (QT_LIBRARY_DIR AND (NOT QT_QTCORE_INCLUDE_DIR OR NOT QT_HEADERS_DIR OR QT_QMAKE_CHANGED))
+ _qt4_query_qmake(QT_INSTALL_HEADERS qt_headers)
+ SET(QT_QTCORE_INCLUDE_DIR NOTFOUND)
+ FIND_PATH(QT_QTCORE_INCLUDE_DIR QtCore
+ HINTS ${qt_headers} ${QT_LIBRARY_DIR}
+ PATH_SUFFIXES QtCore qt4/QtCore
+ )
+
+ # Set QT_HEADERS_DIR based on finding QtCore header
+ IF(QT_QTCORE_INCLUDE_DIR)
+ IF(QT_USE_FRAMEWORKS)
+ SET(QT_HEADERS_DIR "${qt_headers}" CACHE INTERNAL "" FORCE)
+ ELSE(QT_USE_FRAMEWORKS)
+ GET_FILENAME_COMPONENT(qt_headers "${QT_QTCORE_INCLUDE_DIR}/../" ABSOLUTE)
+ SET(QT_HEADERS_DIR "${qt_headers}" CACHE INTERNAL "" FORCE)
+ ENDIF(QT_USE_FRAMEWORKS)
+ ELSEIF()
+ MESSAGE("Warning: QT_QMAKE_EXECUTABLE reported QT_INSTALL_HEADERS as ${qt_headers}")
+ MESSAGE("Warning: But QtCore couldn't be found. Qt must NOT be installed correctly.")
+ ENDIF()
+ ENDIF()
+
+ IF(APPLE)
+ SET(CMAKE_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK_OLD})
+ ENDIF(APPLE)
+
+ # Set QT_INCLUDE_DIR based on QT_HEADERS_DIR
+ IF(QT_HEADERS_DIR)
+ IF(QT_USE_FRAMEWORKS)
+ # Qt/Mac frameworks has two include dirs.
+ # One is the framework include for which CMake will add a -F flag
+ # and the other is an include dir for non-framework Qt modules
+ SET(QT_INCLUDE_DIR ${QT_HEADERS_DIR} ${QT_QTCORE_LIBRARY_RELEASE} )
+ ELSE(QT_USE_FRAMEWORKS)
+ SET(QT_INCLUDE_DIR ${QT_HEADERS_DIR})
+ ENDIF(QT_USE_FRAMEWORKS)
+ ENDIF(QT_HEADERS_DIR)
+
+ # Set QT_INCLUDES
+ SET( QT_INCLUDES ${QT_MKSPECS_DIR}/default ${QT_INCLUDE_DIR} ${QT_QTCORE_INCLUDE_DIR})
+
+
+ # ask qmake for the documentation directory
+ IF (QT_LIBRARY_DIR AND NOT QT_DOC_DIR OR QT_QMAKE_CHANGED)
+ _qt4_query_qmake(QT_INSTALL_DOCS qt_doc_dir)
+ SET(QT_DOC_DIR ${qt_doc_dir} CACHE PATH "The location of the Qt docs" FORCE)
+ ENDIF (QT_LIBRARY_DIR AND NOT QT_DOC_DIR OR QT_QMAKE_CHANGED)
+
+
+ # ask qmake for the plugins directory
+ IF (QT_LIBRARY_DIR AND NOT QT_PLUGINS_DIR OR QT_QMAKE_CHANGED)
+ _qt4_query_qmake(QT_INSTALL_PLUGINS qt_plugins_dir)
+ SET(QT_PLUGINS_DIR NOTFOUND)
+ foreach(qt_cross_path ${CMAKE_FIND_ROOT_PATH})
+ set(qt_cross_paths ${qt_cross_paths} "${qt_cross_path}/plugins")
+ endforeach(qt_cross_path)
+ 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")
+ ENDIF (QT_LIBRARY_DIR AND NOT QT_PLUGINS_DIR OR QT_QMAKE_CHANGED)
+
+ # ask qmake for the translations directory
+ IF (QT_LIBRARY_DIR AND NOT QT_TRANSLATIONS_DIR OR QT_QMAKE_CHANGED)
+ _qt4_query_qmake(QT_INSTALL_TRANSLATIONS qt_translations_dir)
+ SET(QT_TRANSLATIONS_DIR ${qt_translations_dir} CACHE PATH "The location of the Qt translations" FORCE)
+ ENDIF (QT_LIBRARY_DIR AND NOT QT_TRANSLATIONS_DIR OR QT_QMAKE_CHANGED)
+
+ # ask qmake for the imports directory
+ IF (QT_LIBRARY_DIR AND NOT QT_IMPORTS_DIR OR QT_QMAKE_CHANGED)
+ _qt4_query_qmake(QT_INSTALL_IMPORTS qt_imports_dir)
+ if(qt_imports_dir)
+ SET(QT_IMPORTS_DIR NOTFOUND)
+ foreach(qt_cross_path ${CMAKE_FIND_ROOT_PATH})
+ set(qt_cross_paths ${qt_cross_paths} "${qt_cross_path}/imports")
+ endforeach(qt_cross_path)
+ FIND_PATH(QT_IMPORTS_DIR NAMES Qt
+ HINTS ${qt_cross_paths} ${qt_imports_dir}
+ DOC "The location of the Qt imports"
+ NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH NO_SYSTEM_ENVIRONMENT_PATH
+ NO_CMAKE_SYSTEM_PATH)
+ mark_as_advanced(QT_IMPORTS_DIR)
+ endif(qt_imports_dir)
+ ENDIF (QT_LIBRARY_DIR AND NOT QT_IMPORTS_DIR OR QT_QMAKE_CHANGED)
+
+ # Make variables changeble to the advanced user
+ MARK_AS_ADVANCED( QT_LIBRARY_DIR QT_DOC_DIR QT_MKSPECS_DIR
+ QT_PLUGINS_DIR QT_TRANSLATIONS_DIR)
+
+
+
+
+ #############################################
+ #
+ # 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})
+ # Add QT_INCLUDE_DIR to CMAKE_REQUIRED_INCLUDES
+ SET(CMAKE_REQUIRED_INCLUDES "${CMAKE_REQUIRED_INCLUDES};${QT_INCLUDE_DIR}")
+ # 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)
+ CHECK_CXX_SYMBOL_EXISTS(Q_WS_QWS "QtCore/qglobal.h" Q_WS_QWS)
+ CHECK_CXX_SYMBOL_EXISTS(Q_WS_MAC "QtCore/qglobal.h" Q_WS_MAC)
+ IF(Q_WS_MAC)
+ IF(QT_QMAKE_CHANGED)
+ UNSET(QT_MAC_USE_COCOA CACHE)
+ ENDIF(QT_QMAKE_CHANGED)
+ CHECK_CXX_SYMBOL_EXISTS(QT_MAC_USE_COCOA "QtCore/qconfig.h" QT_MAC_USE_COCOA)
+ ENDIF(Q_WS_MAC)
+
+ IF (QT_QTCOPY_REQUIRED)
+ CHECK_CXX_SYMBOL_EXISTS(QT_IS_QTCOPY "QtCore/qglobal.h" QT_KDE_QT_COPY)
+ IF (NOT QT_IS_QTCOPY)
+ MESSAGE(FATAL_ERROR "qt-copy is required, but hasn't been found")
+ ENDIF (NOT QT_IS_QTCOPY)
+ ENDIF (QT_QTCOPY_REQUIRED)
+
+ # 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})
+ #
+ #############################################
+
+
+
+ ########################################
+ #
+ # Setting the INCLUDE-Variables
+ #
+ ########################################
+
+ SET(QT_MODULES QtGui Qt3Support QtSvg QtScript QtTest QtUiTools
+ QtHelp QtWebKit QtXmlPatterns phonon QtNetwork QtMultimedia
+ QtNsPlugin QtOpenGL QtSql QtXml QtDesigner QtDBus QtScriptTools
+ QtDeclarative)
+
+ IF(Q_WS_X11)
+ SET(QT_MODULES ${QT_MODULES} QtMotif)
+ ENDIF(Q_WS_X11)
+
+ IF(QT_QMAKE_CHANGED)
+ FOREACH(QT_MODULE ${QT_MODULES})
+ STRING(TOUPPER ${QT_MODULE} _upper_qt_module)
+ SET(QT_${_upper_qt_module}_INCLUDE_DIR NOTFOUND)
+ SET(QT_${_upper_qt_module}_LIBRARY_RELEASE NOTFOUND)
+ SET(QT_${_upper_qt_module}_LIBRARY_DEBUG NOTFOUND)
+ ENDFOREACH(QT_MODULE)
+ SET(QT_QTDESIGNERCOMPONENTS_INCLUDE_DIR NOTFOUND)
+ SET(QT_QTDESIGNERCOMPONENTS_LIBRARY_RELEASE NOTFOUND)
+ SET(QT_QTDESIGNERCOMPONENTS_LIBRARY_DEBUG NOTFOUND)
+ SET(QT_QTASSISTANTCLIENT_INCLUDE_DIR NOTFOUND)
+ SET(QT_QTASSISTANTCLIENT_LIBRARY_RELEASE NOTFOUND)
+ SET(QT_QTASSISTANTCLIENT_LIBRARY_DEBUG NOTFOUND)
+ SET(QT_QTASSISTANT_INCLUDE_DIR NOTFOUND)
+ SET(QT_QTASSISTANT_LIBRARY_RELEASE NOTFOUND)
+ SET(QT_QTASSISTANT_LIBRARY_DEBUG NOTFOUND)
+ SET(QT_QTCLUCENE_LIBRARY_RELEASE NOTFOUND)
+ SET(QT_QTCLUCENE_LIBRARY_DEBUG NOTFOUND)
+ SET(QT_QAXCONTAINER_INCLUDE_DIR NOTFOUND)
+ SET(QT_QAXCONTAINER_LIBRARY_RELEASE NOTFOUND)
+ SET(QT_QAXCONTAINER_LIBRARY_DEBUG NOTFOUND)
+ SET(QT_QAXSERVER_INCLUDE_DIR NOTFOUND)
+ SET(QT_QAXSERVER_LIBRARY_RELEASE NOTFOUND)
+ SET(QT_QAXSERVER_LIBRARY_DEBUG NOTFOUND)
+ IF(Q_WS_WIN)
+ SET(QT_QTMAIN_LIBRARY_DEBUG NOTFOUND)
+ SET(QT_QTMAIN_LIBRARY_RELEASE NOTFOUND)
+ ENDIF(Q_WS_WIN)
+ ENDIF(QT_QMAKE_CHANGED)
+
+ FOREACH(QT_MODULE ${QT_MODULES})
+ STRING(TOUPPER ${QT_MODULE} _upper_qt_module)
+ FIND_PATH(QT_${_upper_qt_module}_INCLUDE_DIR ${QT_MODULE}
+ PATHS
+ ${QT_HEADERS_DIR}/${QT_MODULE}
+ ${QT_LIBRARY_DIR}/${QT_MODULE}.framework/Headers
+ NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
+ )
+ # phonon doesn't seem consistent, let's try phonondefs.h for some
+ # installations
+ IF(${QT_MODULE} STREQUAL "phonon")
+ FIND_PATH(QT_${_upper_qt_module}_INCLUDE_DIR phonondefs.h
+ PATHS
+ ${QT_HEADERS_DIR}/${QT_MODULE}
+ ${QT_LIBRARY_DIR}/${QT_MODULE}.framework/Headers
+ NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
+ )
+ ENDIF(${QT_MODULE} STREQUAL "phonon")
+ ENDFOREACH(QT_MODULE)
+
+ IF(Q_WS_WIN)
+ SET(QT_MODULES ${QT_MODULES} QAxContainer QAxServer)
+ # Set QT_AXCONTAINER_INCLUDE_DIR and QT_AXSERVER_INCLUDE_DIR
+ FIND_PATH(QT_QAXCONTAINER_INCLUDE_DIR ActiveQt
+ PATHS ${QT_HEADERS_DIR}/ActiveQt
+ NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
+ )
+ FIND_PATH(QT_QAXSERVER_INCLUDE_DIR ActiveQt
+ PATHS ${QT_HEADERS_DIR}/ActiveQt
+ NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
+ )
+ ENDIF(Q_WS_WIN)
+
+ # Set QT_QTDESIGNERCOMPONENTS_INCLUDE_DIR
+ FIND_PATH(QT_QTDESIGNERCOMPONENTS_INCLUDE_DIR QDesignerComponents
+ PATHS
+ ${QT_HEADERS_DIR}/QtDesigner
+ ${QT_LIBRARY_DIR}/QtDesigner.framework/Headers
+ NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
+ )
+
+ # Set QT_QTASSISTANT_INCLUDE_DIR
+ FIND_PATH(QT_QTASSISTANT_INCLUDE_DIR QtAssistant
+ PATHS
+ ${QT_HEADERS_DIR}/QtAssistant
+ ${QT_LIBRARY_DIR}/QtAssistant.framework/Headers
+ NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
+ )
+
+ # Set QT_QTASSISTANTCLIENT_INCLUDE_DIR
+ FIND_PATH(QT_QTASSISTANTCLIENT_INCLUDE_DIR QAssistantClient
+ PATHS
+ ${QT_HEADERS_DIR}/QtAssistant
+ ${QT_LIBRARY_DIR}/QtAssistant.framework/Headers
+ NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
+ )
+
+ ########################################
+ #
+ # Setting the LIBRARY-Variables
+ #
+ ########################################
+
+ # find the libraries
+ FOREACH(QT_MODULE ${QT_MODULES})
+ STRING(TOUPPER ${QT_MODULE} _upper_qt_module)
+ FIND_LIBRARY(QT_${_upper_qt_module}_LIBRARY_RELEASE
+ NAMES ${QT_MODULE}${QT_LIBINFIX} ${QT_MODULE}${QT_LIBINFIX}4
+ PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
+ )
+ FIND_LIBRARY(QT_${_upper_qt_module}_LIBRARY_DEBUG
+ NAMES ${QT_MODULE}${QT_LIBINFIX}_debug ${QT_MODULE}${QT_LIBINFIX}d ${QT_MODULE}${QT_LIBINFIX}d4
+ PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
+ )
+ ENDFOREACH(QT_MODULE)
+
+ # QtUiTools is sometimes not in the same directory as the other found libraries
+ # e.g. on Mac, its never a framework like the others are
+ IF(QT_QTCORE_LIBRARY_RELEASE AND NOT QT_QTUITOOLS_LIBRARY_RELEASE)
+ FIND_LIBRARY(QT_QTUITOOLS_LIBRARY_RELEASE NAMES QtUiTools${QT_LIBINFIX} PATHS ${QT_LIBRARY_DIR})
+ ENDIF(QT_QTCORE_LIBRARY_RELEASE AND NOT QT_QTUITOOLS_LIBRARY_RELEASE)
+
+ # Set QT_QTDESIGNERCOMPONENTS_LIBRARY
+ FIND_LIBRARY(QT_QTDESIGNERCOMPONENTS_LIBRARY_RELEASE NAMES QtDesignerComponents${QT_LIBINFIX} QtDesignerComponents${QT_LIBINFIX}4 PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
+ FIND_LIBRARY(QT_QTDESIGNERCOMPONENTS_LIBRARY_DEBUG NAMES QtDesignerComponents${QT_LIBINFIX}_debug QtDesignerComponents${QT_LIBINFIX}d QtDesignerComponents${QT_LIBINFIX}d4 PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
+
+ # Set QT_QTMAIN_LIBRARY
+ IF(Q_WS_WIN)
+ FIND_LIBRARY(QT_QTMAIN_LIBRARY_RELEASE NAMES qtmain${QT_LIBINFIX} PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
+ FIND_LIBRARY(QT_QTMAIN_LIBRARY_DEBUG NAMES qtmain${QT_LIBINFIX}d PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
+ ENDIF(Q_WS_WIN)
+
+ # Set QT_QTASSISTANTCLIENT_LIBRARY
+ FIND_LIBRARY(QT_QTASSISTANTCLIENT_LIBRARY_RELEASE NAMES QtAssistantClient${QT_LIBINFIX} QtAssistantClient${QT_LIBINFIX}4 PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
+ FIND_LIBRARY(QT_QTASSISTANTCLIENT_LIBRARY_DEBUG NAMES QtAssistantClient${QT_LIBINFIX}_debug QtAssistantClient${QT_LIBINFIX}d QtAssistantClient${QT_LIBINFIX}d4 PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
+
+ # Set QT_QTASSISTANT_LIBRARY
+ FIND_LIBRARY(QT_QTASSISTANT_LIBRARY_RELEASE NAMES QtAssistantClient${QT_LIBINFIX} QtAssistantClient${QT_LIBINFIX}4 QtAssistant${QT_LIBINFIX} QtAssistant${QT_LIBINFIX}4 PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
+ FIND_LIBRARY(QT_QTASSISTANT_LIBRARY_DEBUG NAMES QtAssistantClient${QT_LIBINFIX}_debug QtAssistantClient${QT_LIBINFIX}d QtAssistantClient${QT_LIBINFIX}d4 QtAssistant${QT_LIBINFIX}_debug QtAssistant${QT_LIBINFIX}d4 PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
+
+ # Set QT_QTHELP_LIBRARY
+ FIND_LIBRARY(QT_QTCLUCENE_LIBRARY_RELEASE NAMES QtCLucene${QT_LIBINFIX} QtCLucene${QT_LIBINFIX}4 PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
+ FIND_LIBRARY(QT_QTCLUCENE_LIBRARY_DEBUG NAMES QtCLucene${QT_LIBINFIX}_debug QtCLucene${QT_LIBINFIX}d QtCLucene${QT_LIBINFIX}d4 PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
+ IF(Q_WS_MAC AND QT_QTCORE_LIBRARY_RELEASE AND NOT QT_QTCLUCENE_LIBRARY_RELEASE)
+ FIND_LIBRARY(QT_QTCLUCENE_LIBRARY_RELEASE NAMES QtCLucene${QT_LIBINFIX} PATHS ${QT_LIBRARY_DIR})
+ ENDIF(Q_WS_MAC AND QT_QTCORE_LIBRARY_RELEASE AND NOT QT_QTCLUCENE_LIBRARY_RELEASE)
+
+
+ ############################################
+ #
+ # Check the existence of the libraries.
+ #
+ ############################################
+
+
+ # Set QT_xyz_LIBRARY variable and add
+ # library include path to QT_INCLUDES
+ _QT4_ADJUST_LIB_VARS(QtCore)
+
+ FOREACH(QT_MODULE ${QT_MODULES})
+ _QT4_ADJUST_LIB_VARS(${QT_MODULE})
+ ENDFOREACH(QT_MODULE)
+
+ _QT4_ADJUST_LIB_VARS(QtAssistant)
+ _QT4_ADJUST_LIB_VARS(QtAssistantClient)
+ _QT4_ADJUST_LIB_VARS(QtCLucene)
+ _QT4_ADJUST_LIB_VARS(QtDesignerComponents)
+
+ # platform dependent libraries
+ IF(Q_WS_WIN)
+ _QT4_ADJUST_LIB_VARS(qtmain)
+ _QT4_ADJUST_LIB_VARS(QAxServer)
+ _QT4_ADJUST_LIB_VARS(QAxContainer)
+ ENDIF(Q_WS_WIN)
+
+
+ #######################################
+ #
+ # Check the executables of Qt
+ # ( moc, uic, rcc )
+ #
+ #######################################
+
+
+ IF(QT_QMAKE_CHANGED)
+ SET(QT_UIC_EXECUTABLE NOTFOUND)
+ SET(QT_MOC_EXECUTABLE NOTFOUND)
+ SET(QT_UIC3_EXECUTABLE NOTFOUND)
+ SET(QT_RCC_EXECUTABLE NOTFOUND)
+ SET(QT_DBUSCPP2XML_EXECUTABLE NOTFOUND)
+ SET(QT_DBUSXML2CPP_EXECUTABLE NOTFOUND)
+ SET(QT_LUPDATE_EXECUTABLE NOTFOUND)
+ SET(QT_LRELEASE_EXECUTABLE NOTFOUND)
+ SET(QT_QCOLLECTIONGENERATOR_EXECUTABLE NOTFOUND)
+ SET(QT_DESIGNER_EXECUTABLE NOTFOUND)
+ SET(QT_LINGUIST_EXECUTABLE NOTFOUND)
+ ENDIF(QT_QMAKE_CHANGED)
+
+ FIND_PROGRAM(QT_MOC_EXECUTABLE
+ NAMES moc-qt4 moc
+ PATHS ${QT_BINARY_DIR}
+ NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
+ )
+
+ FIND_PROGRAM(QT_UIC_EXECUTABLE
+ NAMES uic-qt4 uic
+ 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
+ PATHS ${QT_BINARY_DIR}
+ NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
+ )
+
+ FIND_PROGRAM(QT_LRELEASE_EXECUTABLE
+ NAMES lrelease-qt4 lrelease
+ 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
+ PATHS ${QT_BINARY_DIR}
+ NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
+ )
+
+ FIND_PROGRAM(QT_LINGUIST_EXECUTABLE
+ NAMES linguist-qt4 linguist
+ PATHS ${QT_BINARY_DIR}
+ NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
+ )
+
+ IF (QT_MOC_EXECUTABLE)
+ SET(QT_WRAP_CPP "YES")
+ ENDIF (QT_MOC_EXECUTABLE)
+
+ IF (QT_UIC_EXECUTABLE)
+ SET(QT_WRAP_UI "YES")
+ ENDIF (QT_UIC_EXECUTABLE)
+
+
+
+ MARK_AS_ADVANCED( QT_UIC_EXECUTABLE QT_UIC3_EXECUTABLE QT_MOC_EXECUTABLE
+ QT_RCC_EXECUTABLE QT_DBUSXML2CPP_EXECUTABLE QT_DBUSCPP2XML_EXECUTABLE
+ QT_LUPDATE_EXECUTABLE QT_LRELEASE_EXECUTABLE QT_QCOLLECTIONGENERATOR_EXECUTABLE
+ QT_DESIGNER_EXECUTABLE QT_LINGUIST_EXECUTABLE)
+
+
+ # get the directory of the current file, used later on in the file
+ GET_FILENAME_COMPONENT( _qt4_current_dir "${CMAKE_CURRENT_LIST_FILE}" PATH)
+
+
+ ###############################################
+ #
+ # configuration/system dependent settings
+ #
+ ###############################################
+
+ INCLUDE("${_qt4_current_dir}/Qt4ConfigDependentSettings.cmake")
+
+
+ #######################################
+ #
+ # Check the plugins of Qt
+ #
+ #######################################
+
+ 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_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_INPUTMETHODS_PLUGINS qimsw_multi )
+ SET( QT_MOUSEDRIVERS_PLUGINS qwstslibmousehandler )
+ IF(APPLE)
+ SET( QT_PHONON_BACKEND_PLUGINS phonon_qt7 )
+ ELSEIF(WIN32)
+ SET( QT_PHONON_BACKEND_PLUGINS phonon_ds9 )
+ ENDIF()
+ SET( QT_SCRIPT_PLUGINS qtscriptdbus )
+ SET( QT_SQLDRIVERS_PLUGINS qsqldb2 qsqlibase qsqlite qsqlite2 qsqlmysql qsqloci qsqlodbc qsqlpsql qsqltds )
+
+ 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_QTSCRIPT_PLUGINS ${QT_SCRIPT_PLUGINS} )
+ SET( QT_QTSQL_PLUGINS ${QT_SQLDRIVERS_PLUGINS} )
+ SET( QT_QTSVG_PLUGINS qsvg qsvgicon )
+
+ IF(QT_QMAKE_CHANGED)
+ FOREACH(QT_PLUGIN_TYPE ${QT_PLUGIN_TYPES})
+ STRING(TOUPPER ${QT_PLUGIN_TYPE} _upper_qt_plugin_type)
+ SET(QT_${_upper_qt_plugin_type}_PLUGINS_DIR ${QT_PLUGINS_DIR}/${QT_PLUGIN_TYPE})
+ FOREACH(QT_PLUGIN ${QT_${_upper_qt_plugin_type}_PLUGINS})
+ STRING(TOUPPER ${QT_PLUGIN} _upper_qt_plugin)
+ UNSET(QT_${_upper_qt_plugin}_LIBRARY_RELEASE CACHE)
+ UNSET(QT_${_upper_qt_plugin}_LIBRARY_DEBUG CACHE)
+ UNSET(QT_${_upper_qt_plugin}_LIBRARY CACHE)
+ UNSET(QT_${_upper_qt_plugin}_PLUGIN_RELEASE CACHE)
+ UNSET(QT_${_upper_qt_plugin}_PLUGIN_DEBUG CACHE)
+ UNSET(QT_${_upper_qt_plugin}_PLUGIN CACHE)
+ ENDFOREACH(QT_PLUGIN)
+ ENDFOREACH(QT_PLUGIN_TYPE)
+ ENDIF(QT_QMAKE_CHANGED)
+
+ # find_library works better than find_file but we need to set prefixes to only match plugins
+ FOREACH(QT_PLUGIN_TYPE ${QT_PLUGIN_TYPES})
+ STRING(TOUPPER ${QT_PLUGIN_TYPE} _upper_qt_plugin_type)
+ SET(QT_${_upper_qt_plugin_type}_PLUGINS_DIR ${QT_PLUGINS_DIR}/${QT_PLUGIN_TYPE})
+ FOREACH(QT_PLUGIN ${QT_${_upper_qt_plugin_type}_PLUGINS})
+ STRING(TOUPPER ${QT_PLUGIN} _upper_qt_plugin)
+ IF(QT_IS_STATIC)
+ FIND_LIBRARY(QT_${_upper_qt_plugin}_LIBRARY_RELEASE
+ NAMES ${QT_PLUGIN}${QT_LIBINFIX} ${QT_PLUGIN}${QT_LIBINFIX}4
+ PATHS ${QT_${_upper_qt_plugin_type}_PLUGINS_DIR} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
+ )
+ FIND_LIBRARY(QT_${_upper_qt_plugin}_LIBRARY_DEBUG
+ NAMES ${QT_PLUGIN}${QT_LIBINFIX}_debug ${QT_PLUGIN}${QT_LIBINFIX}d ${QT_PLUGIN}${QT_LIBINFIX}d4
+ PATHS ${QT_${_upper_qt_plugin_type}_PLUGINS_DIR} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
+ )
+ _QT4_ADJUST_LIB_VARS(${QT_PLUGIN})
+ ELSE(QT_IS_STATIC)
+ # find_library works easier/better than find_file but we need to set suffixes to only match plugins
+ SET(CMAKE_FIND_LIBRARY_SUFFIXES_DEFAULT ${CMAKE_FIND_LIBRARY_SUFFIXES})
+ SET(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_SHARED_MODULE_SUFFIX} ${CMAKE_SHARED_LIBRARY_SUFFIX})
+ FIND_LIBRARY(QT_${_upper_qt_plugin}_PLUGIN_RELEASE
+ NAMES ${QT_PLUGIN}${QT_LIBINFIX} ${QT_PLUGIN}${QT_LIBINFIX}4
+ PATHS ${QT_${_upper_qt_plugin_type}_PLUGINS_DIR} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
+ )
+ FIND_LIBRARY(QT_${_upper_qt_plugin}_PLUGIN_DEBUG
+ NAMES ${QT_PLUGIN}${QT_LIBINFIX}_debug ${QT_PLUGIN}${QT_LIBINFIX}d ${QT_PLUGIN}${QT_LIBINFIX}d4
+ PATHS ${QT_${_upper_qt_plugin_type}_PLUGINS_DIR} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH
+ )
+ MARK_AS_ADVANCED(QT_${_upper_qt_plugin}_PLUGIN_RELEASE QT_${_upper_qt_plugin}_PLUGIN_DEBUG)
+ SET(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES_DEFAULT})
+ ENDIF(QT_IS_STATIC)
+ ENDFOREACH(QT_PLUGIN)
+ ENDFOREACH(QT_PLUGIN_TYPE)
+
+
+ ######################################
+ #
+ # Macros for building Qt files
+ #
+ ######################################
+
+ INCLUDE("${_qt4_current_dir}/Qt4Macros.cmake")
+
+ # set version variables
+ STRING(REGEX REPLACE "^([0-9]+)\\.[0-9]+\\.[0-9]+.*" "\\1" QT_VERSION_MAJOR "${QTVERSION}")
+ STRING(REGEX REPLACE "^[0-9]+\\.([0-9])+\\.[0-9]+.*" "\\1" QT_VERSION_MINOR "${QTVERSION}")
+ STRING(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" QT_VERSION_PATCH "${QTVERSION}")
+
+ENDIF(QT_QMAKE_EXECUTABLE AND QTVERSION)
+
+#support old QT_MIN_VERSION if set, but not if version is supplied by find_package()
+IF(NOT Qt4_FIND_VERSION AND QT_MIN_VERSION)
+ SET(Qt4_FIND_VERSION ${QT_MIN_VERSION})
+ENDIF(NOT Qt4_FIND_VERSION AND QT_MIN_VERSION)
+
+IF( Qt4_FIND_COMPONENTS )
+
+ # if components specified in find_package(), make sure each of those pieces were found
+ SET(_QT4_FOUND_REQUIRED_VARS QT_QMAKE_EXECUTABLE QT_MOC_EXECUTABLE QT_RCC_EXECUTABLE QT_INCLUDE_DIR QT_LIBRARY_DIR)
+ FOREACH( component ${Qt4_FIND_COMPONENTS} )
+ STRING( TOUPPER ${component} _COMPONENT )
+ if(${_COMPONENT} STREQUAL "QTMAIN")
+ IF(Q_WS_WIN)
+ SET(_QT4_FOUND_REQUIRED_VARS ${_QT4_FOUND_REQUIRED_VARS} QT_${_COMPONENT}_LIBRARY)
+ ENDIF(Q_WS_WIN)
+ else(${_COMPONENT} STREQUAL "QTMAIN")
+ SET(_QT4_FOUND_REQUIRED_VARS ${_QT4_FOUND_REQUIRED_VARS} QT_${_COMPONENT}_INCLUDE_DIR QT_${_COMPONENT}_LIBRARY)
+ endif(${_COMPONENT} STREQUAL "QTMAIN")
+ ENDFOREACH( component )
+
+ if(Qt4_FIND_COMPONENTS MATCHES QtGui)
+ SET(_QT4_FOUND_REQUIRED_VARS ${_QT4_FOUND_REQUIRED_VARS} QT_UIC_EXECUTABLE)
+ endif(Qt4_FIND_COMPONENTS MATCHES QtGui)
+
+ELSE( Qt4_FIND_COMPONENTS )
+
+ # if no components specified, we'll make a default set of required variables to say Qt is found
+ SET(_QT4_FOUND_REQUIRED_VARS QT_QMAKE_EXECUTABLE QT_MOC_EXECUTABLE QT_RCC_EXECUTABLE QT_UIC_EXECUTABLE QT_INCLUDE_DIR
+ QT_LIBRARY_DIR QT_QTCORE_LIBRARY)
+
+ENDIF( Qt4_FIND_COMPONENTS )
+
+if (QT_VERSION_MAJOR GREATER 4)
+ SET(VERSION_MSG "Found unsuitable Qt version \"${QTVERSION}\" from ${QT_QMAKE_EXECUTABLE}")
+ SET(QT4_FOUND FALSE)
+ IF(Qt4_FIND_REQUIRED)
+ MESSAGE( FATAL_ERROR "${VERSION_MSG}, this code requires Qt 4.x")
+ ELSE(Qt4_FIND_REQUIRED)
+ IF(NOT Qt4_FIND_QUIETLY)
+ MESSAGE( STATUS "${VERSION_MSG}")
+ ENDIF(NOT Qt4_FIND_QUIETLY)
+ ENDIF(Qt4_FIND_REQUIRED)
+else()
+ FIND_PACKAGE_HANDLE_STANDARD_ARGS(Qt4
+ REQUIRED_VARS ${_QT4_FOUND_REQUIRED_VARS}
+ VERSION_VAR QTVERSION
+ )
+endif()
+
+#######################################
+#
+# compatibility settings
+#
+#######################################
+# Backwards compatibility for CMake1.4 and 1.2
+SET (QT_MOC_EXE ${QT_MOC_EXECUTABLE} )
+SET (QT_UIC_EXE ${QT_UIC_EXECUTABLE} )
+SET( QT_QT_LIBRARY "")
+SET(QT_FOUND ${QT4_FOUND})
+
diff --git a/Modules/FindQuickTime.cmake b/Modules/FindQuickTime.cmake
new file mode 100644
index 000000000..038c2dd65
--- /dev/null
+++ b/Modules/FindQuickTime.cmake
@@ -0,0 +1,47 @@
+# 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
+#
+# Created by Eric Wing.
+
+#=============================================================================
+# 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.)
+
+# QuickTime on OS X looks different than QuickTime for Windows,
+# so I am going to case the two.
+
+IF(APPLE)
+ FIND_PATH(QUICKTIME_INCLUDE_DIR QuickTime/QuickTime.h)
+ FIND_LIBRARY(QUICKTIME_LIBRARY QuickTime)
+ELSE(APPLE)
+ FIND_PATH(QUICKTIME_INCLUDE_DIR QuickTime.h
+ HINTS
+ $ENV{QUICKTIME_DIR}/include
+ $ENV{QUICKTIME_DIR}
+ )
+ FIND_LIBRARY(QUICKTIME_LIBRARY QuickTime
+ HINTS
+ $ENV{QUICKTIME_DIR}/lib
+ $ENV{QUICKTIME_DIR}
+ )
+ENDIF(APPLE)
+
+# handle the QUIETLY and REQUIRED arguments and set QUICKTIME_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(QuickTime DEFAULT_MSG QUICKTIME_LIBRARY QUICKTIME_INCLUDE_DIR)
diff --git a/Modules/FindRTI.cmake b/Modules/FindRTI.cmake
new file mode 100644
index 000000000..031c13854
--- /dev/null
+++ b/Modules/FindRTI.cmake
@@ -0,0 +1,102 @@
+# - 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)
+#
+# 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
+#
+# Report problems to <certi-devel@nongnu.org>
+
+#=============================================================================
+# Copyright 2008-2009 Kitware, Inc.
+# Copyright 2008 Petr Gotthard <gotthard@honeywell.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(RTI_MESSAGE_QUIETLY QUIET TYPE MSG)
+ IF(NOT ${QUIET})
+ MESSAGE(${TYPE} "${MSG}")
+ ENDIF(NOT ${QUIET})
+ENDMACRO(RTI_MESSAGE_QUIETLY QUIET TYPE MSG)
+
+# Detect the CERTI installation, http://www.cert.fr/CERTI
+IF ("$ENV{CERTI_HOME}" STRGREATER "")
+ FILE(TO_CMAKE_PATH "$ENV{CERTI_HOME}" CERTI_HOME)
+ RTI_MESSAGE_QUIETLY(RTI_FIND_QUIETLY STATUS "Using environment defined CERTI_HOME: ${CERTI_HOME}")
+ENDIF ("$ENV{CERTI_HOME}" STRGREATER "")
+
+SET(RTI_DEFINITIONS "-DRTI_USES_STD_FSTREAM")
+
+# Detect the MAK Technologies RTI installation, http://www.mak.com/products/rti.php
+# note: the following list is ordered to find the most recent version first
+SET(RTI_POSSIBLE_DIRS
+ ${CERTI_HOME}
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MAK Technologies\\MAK RTI 3.2 MSVC++ 8.0;Location]"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\MAK RTI 3.2-win32-msvc++8.0;InstallLocation]"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MAK Technologies\\MAK RTI 2.2;Location]"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\MAK RTI 2.2;InstallLocation]")
+
+SET(RTI_OLD_FIND_LIBRARY_PREFIXES "${CMAKE_FIND_LIBRARY_PREFIXES}")
+# The MAK RTI has the "lib" prefix even on Windows.
+SET(CMAKE_FIND_LIBRARY_PREFIXES "lib" "")
+
+FIND_LIBRARY(RTI_LIBRARY
+ NAMES RTI RTI-NG
+ PATHS ${RTI_POSSIBLE_DIRS}
+ PATH_SUFFIXES lib
+ DOC "The RTI Library")
+
+IF (RTI_LIBRARY)
+ SET(RTI_LIBRARIES ${RTI_LIBRARY})
+ RTI_MESSAGE_QUIETLY(RTI_FIND_QUIETLY STATUS "RTI library found: ${RTI_LIBRARY}")
+ELSE (RTI_LIBRARY)
+ RTI_MESSAGE_QUIETLY(RTI_FIND_QUIETLY STATUS "RTI library NOT found")
+ENDIF (RTI_LIBRARY)
+
+FIND_LIBRARY(RTI_FEDTIME_LIBRARY
+ NAMES FedTime
+ PATHS ${RTI_POSSIBLE_DIRS}
+ PATH_SUFFIXES lib
+ DOC "The FedTime Library")
+
+IF (RTI_FEDTIME_LIBRARY)
+ SET(RTI_LIBRARIES ${RTI_LIBRARIES} ${RTI_FEDTIME_LIBRARY})
+ RTI_MESSAGE_QUIETLY(RTI_FIND_QUIETLY STATUS "RTI FedTime found: ${RTI_FEDTIME_LIBRARY}")
+ENDIF (RTI_FEDTIME_LIBRARY)
+
+FIND_PATH(RTI_INCLUDE_DIR
+ NAMES RTI.hh
+ PATHS ${RTI_POSSIBLE_DIRS}
+ PATH_SUFFIXES include
+ DOC "The RTI Include Files")
+
+IF (RTI_INCLUDE_DIR)
+ RTI_MESSAGE_QUIETLY(RTI_FIND_QUIETLY STATUS "RTI headers found: ${RTI_INCLUDE_DIR}")
+ELSE (RTI_INCLUDE_DIR)
+ RTI_MESSAGE_QUIETLY(RTI_FIND_QUIETLY STATUS "RTI headers NOT found")
+ENDIF (RTI_INCLUDE_DIR)
+
+# Set the modified system variables back to the original value.
+SET(CMAKE_FIND_LIBRARY_PREFIXES "${RTI_OLD_FIND_LIBRARY_PREFIXES}")
+
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(RTI DEFAULT_MSG
+ RTI_LIBRARY RTI_INCLUDE_DIR)
+
+# $Id$
diff --git a/Modules/FindRuby.cmake b/Modules/FindRuby.cmake
new file mode 100644
index 000000000..5e973e485
--- /dev/null
+++ b/Modules/FindRuby.cmake
@@ -0,0 +1,243 @@
+# - 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.
+#
+# The minimum required version of Ruby can be specified using the
+# 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:
+#
+# 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
+
+#=============================================================================
+# Copyright 2004-2009 Kitware, Inc.
+# Copyright 2008-2009 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.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+# RUBY_ARCHDIR=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"archdir"@:>@)'`
+# RUBY_SITEARCHDIR=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"sitearchdir"@:>@)'`
+# RUBY_SITEDIR=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"sitelibdir"@:>@)'`
+# RUBY_LIBDIR=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"libdir"@:>@)'`
+# RUBY_LIBRUBYARG=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"LIBRUBYARG_SHARED"@:>@)'`
+
+# uncomment the following line to get debug output for this file
+# SET(_RUBY_DEBUG_OUTPUT TRUE)
+
+# Determine the list of possible names of the ruby executable depending
+# on which version of ruby is required
+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)
+ SET(Ruby_FIND_VERSION_SHORT_NODOT "${Ruby_FIND_VERSION_MAJOR}${RUBY_FIND_VERSION_MINOR}")
+ELSE(Ruby_FIND_VERSION_MAJOR AND Ruby_FIND_VERSION_MINOR)
+ SET(Ruby_FIND_VERSION_SHORT_NODOT "18")
+ENDIF(Ruby_FIND_VERSION_MAJOR AND Ruby_FIND_VERSION_MINOR)
+
+SET(_RUBY_POSSIBLE_EXECUTABLE_NAMES ${_RUBY_POSSIBLE_EXECUTABLE_NAMES} ruby1.9 ruby19)
+
+# if we want a version below 1.9, also look for ruby 1.8
+IF("${Ruby_FIND_VERSION_SHORT_NODOT}" VERSION_LESS "19")
+ SET(_RUBY_POSSIBLE_EXECUTABLE_NAMES ${_RUBY_POSSIBLE_EXECUTABLE_NAMES} ruby1.8 ruby18)
+ENDIF("${Ruby_FIND_VERSION_SHORT_NODOT}" VERSION_LESS "19")
+
+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)
+ EXECUTE_PROCESS(COMMAND ${RUBY_EXECUTABLE} -r rbconfig -e "print Config::CONFIG['${RBVAR}']"
+ RESULT_VARIABLE _RUBY_SUCCESS
+ OUTPUT_VARIABLE _RUBY_OUTPUT
+ ERROR_QUIET)
+ ENDIF(_RUBY_SUCCESS OR NOT _RUBY_OUTPUT)
+ SET(${OUTVAR} "${_RUBY_OUTPUT}" PARENT_SCOPE)
+ ENDFUNCTION(_RUBY_CONFIG_VAR)
+
+
+ # query the ruby version
+ _RUBY_CONFIG_VAR("MAJOR" RUBY_VERSION_MAJOR)
+ _RUBY_CONFIG_VAR("MINOR" RUBY_VERSION_MINOR)
+ _RUBY_CONFIG_VAR("TEENY" RUBY_VERSION_PATCH)
+
+ # query the different directories
+ _RUBY_CONFIG_VAR("archdir" RUBY_ARCH_DIR)
+ _RUBY_CONFIG_VAR("arch" RUBY_ARCH)
+ _RUBY_CONFIG_VAR("rubyhdrdir" RUBY_HDR_DIR)
+ _RUBY_CONFIG_VAR("libdir" RUBY_POSSIBLE_LIB_DIR)
+ _RUBY_CONFIG_VAR("rubylibdir" RUBY_RUBY_LIB_DIR)
+
+ # site_ruby
+ _RUBY_CONFIG_VAR("sitearchdir" RUBY_SITEARCH_DIR)
+ _RUBY_CONFIG_VAR("sitelibdir" RUBY_SITELIB_DIR)
+
+ # vendor_ruby available ?
+ EXECUTE_PROCESS(COMMAND ${RUBY_EXECUTABLE} -r vendor-specific -e "print 'true'"
+ OUTPUT_VARIABLE RUBY_HAS_VENDOR_RUBY ERROR_QUIET)
+
+ IF(RUBY_HAS_VENDOR_RUBY)
+ _RUBY_CONFIG_VAR("vendorlibdir" RUBY_VENDORLIB_DIR)
+ _RUBY_CONFIG_VAR("vendorarchdir" RUBY_VENDORARCH_DIR)
+ ENDIF(RUBY_HAS_VENDOR_RUBY)
+
+ # save the results in the cache so we don't have to run ruby the next time again
+ SET(RUBY_VERSION_MAJOR ${RUBY_VERSION_MAJOR} CACHE PATH "The Ruby major version" FORCE)
+ 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_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)
+ SET(RUBY_SITELIB_DIR ${RUBY_SITELIB_DIR} CACHE PATH "The Ruby site lib dir" FORCE)
+ SET(RUBY_HAS_VENDOR_RUBY ${RUBY_HAS_VENDOR_RUBY} CACHE BOOL "Vendor Ruby is available" FORCE)
+ SET(RUBY_VENDORARCH_DIR ${RUBY_VENDORARCH_DIR} CACHE PATH "The Ruby vendor arch dir" FORCE)
+ SET(RUBY_VENDORLIB_DIR ${RUBY_VENDORLIB_DIR} CACHE PATH "The Ruby vendor lib dir" FORCE)
+
+ MARK_AS_ADVANCED(
+ RUBY_ARCH_DIR
+ RUBY_ARCH
+ RUBY_HDR_DIR
+ RUBY_POSSIBLE_LIB_DIR
+ RUBY_RUBY_LIB_DIR
+ RUBY_SITEARCH_DIR
+ RUBY_SITELIB_DIR
+ RUBY_HAS_VENDOR_RUBY
+ RUBY_VENDORARCH_DIR
+ RUBY_VENDORLIB_DIR
+ RUBY_VERSION_MAJOR
+ RUBY_VERSION_MINOR
+ RUBY_VERSION_PATCH
+ )
+ENDIF(RUBY_EXECUTABLE AND NOT RUBY_VERSION_MAJOR)
+
+# In case RUBY_EXECUTABLE could not be executed (e.g. cross compiling)
+# try to detect which version we found. This is not too good.
+IF(RUBY_EXECUTABLE AND NOT RUBY_VERSION_MAJOR)
+ # by default assume 1.8.0
+ SET(RUBY_VERSION_MAJOR 1)
+ 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)
+ SET(RUBY_VERSION_MAJOR 1)
+ SET(RUBY_VERSION_MINOR 9)
+ ENDIF(${RUBY_EXECUTABLE} MATCHES "ruby1.?9" OR RUBY_HDR_DIR)
+ENDIF(RUBY_EXECUTABLE AND NOT RUBY_VERSION_MAJOR)
+
+IF(RUBY_VERSION_MAJOR)
+ SET(RUBY_VERSION "${RUBY_VERSION_MAJOR}.${RUBY_VERSION_MINOR}.${RUBY_VERSION_PATCH}")
+ SET(_RUBY_VERSION_SHORT "${RUBY_VERSION_MAJOR}.${RUBY_VERSION_MINOR}")
+ SET(_RUBY_VERSION_SHORT_NODOT "${RUBY_VERSION_MAJOR}${RUBY_VERSION_MINOR}")
+ SET(_RUBY_NODOT_VERSION "${RUBY_VERSION_MAJOR}${RUBY_VERSION_MINOR}${RUBY_VERSION_PATCH}")
+ENDIF(RUBY_VERSION_MAJOR)
+
+FIND_PATH(RUBY_INCLUDE_DIR
+ NAMES ruby.h
+ HINTS
+ ${RUBY_HDR_DIR}
+ ${RUBY_ARCH_DIR}
+ /usr/lib/ruby/${_RUBY_VERSION_SHORT}/i586-linux-gnu/ )
+
+SET(RUBY_INCLUDE_DIRS ${RUBY_INCLUDE_DIR} )
+
+# if ruby > 1.8 is required or if ruby > 1.8 was found, search for the config.h dir
+IF( "${Ruby_FIND_VERSION_SHORT_NODOT}" GREATER 18 OR "${_RUBY_VERSION_SHORT_NODOT}" GREATER 18 OR RUBY_HDR_DIR)
+ FIND_PATH(RUBY_CONFIG_INCLUDE_DIR
+ NAMES ruby/config.h config.h
+ HINTS
+ ${RUBY_HDR_DIR}/${RUBY_ARCH}
+ ${RUBY_ARCH_DIR}
+ )
+
+ SET(RUBY_INCLUDE_DIRS ${RUBY_INCLUDE_DIRS} ${RUBY_CONFIG_INCLUDE_DIR} )
+ENDIF( "${Ruby_FIND_VERSION_SHORT_NODOT}" GREATER 18 OR "${_RUBY_VERSION_SHORT_NODOT}" GREATER 18 OR RUBY_HDR_DIR)
+
+
+# Determine the list of possible names for the ruby library
+SET(_RUBY_POSSIBLE_LIB_NAMES ruby ruby-static ruby${_RUBY_VERSION_SHORT} ruby${_RUBY_VERSION_SHORT_NODOT} ruby-${_RUBY_VERSION_SHORT} ruby-${RUBY_VERSION})
+
+IF(WIN32)
+ SET( _RUBY_MSVC_RUNTIME "" )
+ IF( MSVC60 )
+ SET( _RUBY_MSVC_RUNTIME "60" )
+ ENDIF( MSVC60 )
+ IF( MSVC70 )
+ SET( _RUBY_MSVC_RUNTIME "70" )
+ ENDIF( MSVC70 )
+ IF( MSVC71 )
+ SET( _RUBY_MSVC_RUNTIME "71" )
+ ENDIF( MSVC71 )
+ IF( MSVC80 )
+ SET( _RUBY_MSVC_RUNTIME "80" )
+ ENDIF( MSVC80 )
+ IF( MSVC90 )
+ SET( _RUBY_MSVC_RUNTIME "90" )
+ ENDIF( MSVC90 )
+
+ 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" )
+ENDIF(WIN32)
+
+FIND_LIBRARY(RUBY_LIBRARY NAMES ${_RUBY_POSSIBLE_LIB_NAMES} HINTS ${RUBY_POSSIBLE_LIB_DIR} )
+
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+SET(_RUBY_REQUIRED_VARS RUBY_EXECUTABLE RUBY_INCLUDE_DIR RUBY_LIBRARY)
+IF(_RUBY_VERSION_SHORT_NODOT GREATER 18)
+ LIST(APPEND _RUBY_REQUIRED_VARS RUBY_CONFIG_INCLUDE_DIR)
+ENDIF(_RUBY_VERSION_SHORT_NODOT GREATER 18)
+
+IF(_RUBY_DEBUG_OUTPUT)
+ MESSAGE(STATUS "--------FindRuby.cmake debug------------")
+ MESSAGE(STATUS "_RUBY_POSSIBLE_EXECUTABLE_NAMES: ${_RUBY_POSSIBLE_EXECUTABLE_NAMES}")
+ MESSAGE(STATUS "_RUBY_POSSIBLE_LIB_NAMES: ${_RUBY_POSSIBLE_LIB_NAMES}")
+ MESSAGE(STATUS "RUBY_ARCH_DIR: ${RUBY_ARCH_DIR}")
+ MESSAGE(STATUS "RUBY_HDR_DIR: ${RUBY_HDR_DIR}")
+ MESSAGE(STATUS "RUBY_POSSIBLE_LIB_DIR: ${RUBY_POSSIBLE_LIB_DIR}")
+ MESSAGE(STATUS "Found RUBY_VERSION: \"${RUBY_VERSION}\" , short: \"${_RUBY_VERSION_SHORT}\", nodot: \"${_RUBY_VERSION_SHORT_NODOT}\"")
+ MESSAGE(STATUS "_RUBY_REQUIRED_VARS: ${_RUBY_REQUIRED_VARS}")
+ MESSAGE(STATUS "RUBY_EXECUTABLE: ${RUBY_EXECUTABLE}")
+ MESSAGE(STATUS "RUBY_LIBRARY: ${RUBY_LIBRARY}")
+ MESSAGE(STATUS "RUBY_INCLUDE_DIR: ${RUBY_INCLUDE_DIR}")
+ MESSAGE(STATUS "RUBY_CONFIG_INCLUDE_DIR: ${RUBY_CONFIG_INCLUDE_DIR}")
+ MESSAGE(STATUS "--------------------")
+ENDIF(_RUBY_DEBUG_OUTPUT)
+
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Ruby REQUIRED_VARS ${_RUBY_REQUIRED_VARS}
+ VERSION_VAR RUBY_VERSION )
+
+MARK_AS_ADVANCED(
+ RUBY_EXECUTABLE
+ RUBY_LIBRARY
+ RUBY_INCLUDE_DIR
+ RUBY_CONFIG_INCLUDE_DIR
+ )
+
+# Set some variables for compatibility with previous version of this file
+SET(RUBY_POSSIBLE_LIB_PATH ${RUBY_POSSIBLE_LIB_DIR})
+SET(RUBY_RUBY_LIB_PATH ${RUBY_RUBY_LIB_DIR})
+SET(RUBY_INCLUDE_PATH ${RUBY_INCLUDE_DIRS})
diff --git a/Modules/FindSDL.cmake b/Modules/FindSDL.cmake
new file mode 100644
index 000000000..1c04726ea
--- /dev/null
+++ b/Modules/FindSDL.cmake
@@ -0,0 +1,173 @@
+# 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
+#
+# 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.
+#
+# 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
+# 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.
+#
+#
+# $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
+# 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).
+
+#=============================================================================
+# 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_PATH(SDL_INCLUDE_DIR SDL.h
+ HINTS
+ $ENV{SDLDIR}
+ PATH_SUFFIXES include/SDL include
+ PATHS
+ ~/Library/Frameworks
+ /Library/Frameworks
+ /usr/local/include/SDL12
+ /usr/local/include/SDL11 # FreeBSD ports
+ /usr/include/SDL12
+ /usr/include/SDL11
+ /sw # Fink
+ /opt/local # DarwinPorts
+ /opt/csw # Blastwave
+ /opt
+)
+
+# 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 lib64 lib
+ PATHS
+ /sw
+ /opt/local
+ /opt/csw
+ /opt
+)
+
+IF(NOT SDL_BUILDING_LIBRARY)
+ 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
+ # necessarily need it.
+ FIND_LIBRARY(SDLMAIN_LIBRARY
+ NAMES SDLmain SDLmain-1.1
+ HINTS
+ $ENV{SDLDIR}
+ PATH_SUFFIXES lib64 lib
+ PATHS
+ /sw
+ /opt/local
+ /opt/csw
+ /opt
+ )
+ ENDIF(NOT ${SDL_INCLUDE_DIR} MATCHES ".framework")
+ENDIF(NOT SDL_BUILDING_LIBRARY)
+
+# SDL may require threads on your system.
+# The Apple build may not need an explicit flag because one of the
+# frameworks may already provide it.
+# But for non-OSX systems, I will use the CMake Threads package.
+IF(NOT APPLE)
+ FIND_PACKAGE(Threads)
+ENDIF(NOT APPLE)
+
+# MinGW needs an additional library, mwindows
+# It's total link flags should look like -lmingw32 -lSDLmain -lSDL -lmwindows
+# (Actually on second look, I think it only needs one of the m* libraries.)
+IF(MINGW)
+ SET(MINGW32_LIBRARY mingw32 CACHE STRING "mwindows for MinGW")
+ENDIF(MINGW)
+
+IF(SDL_LIBRARY_TEMP)
+ # For SDLmain
+ IF(NOT SDL_BUILDING_LIBRARY)
+ IF(SDLMAIN_LIBRARY)
+ SET(SDL_LIBRARY_TEMP ${SDLMAIN_LIBRARY} ${SDL_LIBRARY_TEMP})
+ ENDIF(SDLMAIN_LIBRARY)
+ ENDIF(NOT SDL_BUILDING_LIBRARY)
+
+ # For OS X, SDL uses Cocoa as a backend so it must link to Cocoa.
+ # CMake doesn't display the -framework Cocoa string in the UI even
+ # though it actually is there if I modify a pre-used variable.
+ # I think it has something to do with the CACHE STRING.
+ # So I use a temporary variable until the end so I can set the
+ # "real" variable in one-shot.
+ IF(APPLE)
+ SET(SDL_LIBRARY_TEMP ${SDL_LIBRARY_TEMP} "-framework Cocoa")
+ ENDIF(APPLE)
+
+ # For threads, as mentioned Apple doesn't need this.
+ # In fact, there seems to be a problem if I used the Threads package
+ # and try using this line, so I'm just skipping it entirely for OS X.
+ IF(NOT APPLE)
+ SET(SDL_LIBRARY_TEMP ${SDL_LIBRARY_TEMP} ${CMAKE_THREAD_LIBS_INIT})
+ ENDIF(NOT APPLE)
+
+ # For MinGW library
+ IF(MINGW)
+ SET(SDL_LIBRARY_TEMP ${MINGW32_LIBRARY} ${SDL_LIBRARY_TEMP})
+ ENDIF(MINGW)
+
+ # Set the final string here so the GUI reflects the final state.
+ SET(SDL_LIBRARY ${SDL_LIBRARY_TEMP} CACHE STRING "Where the SDL Library can be found")
+ # Set the temp variable to INTERNAL so it is not seen in the CMake GUI
+ SET(SDL_LIBRARY_TEMP "${SDL_LIBRARY_TEMP}" CACHE INTERNAL "")
+ENDIF(SDL_LIBRARY_TEMP)
+
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL
+ REQUIRED_VARS SDL_LIBRARY SDL_INCLUDE_DIR)
diff --git a/Modules/FindSDL_image.cmake b/Modules/FindSDL_image.cmake
new file mode 100644
index 000000000..f215bda47
--- /dev/null
+++ b/Modules/FindSDL_image.cmake
@@ -0,0 +1,70 @@
+# Locate SDL_image library
+# This module defines
+# SDLIMAGE_LIBRARY, the name of the library to link against
+# SDLIMAGE_FOUND, if false, do not try to link to SDL
+# SDLIMAGE_INCLUDE_DIR, where to find SDL/SDL.h
+#
+# $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).
+
+#=============================================================================
+# 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.)
+
+FIND_PATH(SDLIMAGE_INCLUDE_DIR SDL_image.h
+ HINTS
+ $ENV{SDLIMAGEDIR}
+ $ENV{SDLDIR}
+ PATH_SUFFIXES include
+ PATHS
+ ~/Library/Frameworks
+ /Library/Frameworks
+ /usr/local/include/SDL
+ /usr/include/SDL
+ /usr/local/include/SDL12
+ /usr/local/include/SDL11 # FreeBSD ports
+ /usr/include/SDL12
+ /usr/include/SDL11
+ /sw/include/SDL # Fink
+ /sw/include
+ /opt/local/include/SDL # DarwinPorts
+ /opt/local/include
+ /opt/csw/include/SDL # Blastwave
+ /opt/csw/include
+ /opt/include/SDL
+ /opt/include
+)
+
+FIND_LIBRARY(SDLIMAGE_LIBRARY
+ NAMES SDL_image
+ HINTS
+ $ENV{SDLIMAGEDIR}
+ $ENV{SDLDIR}
+ PATH_SUFFIXES lib64 lib
+ PATHS
+ ~/Library/Frameworks
+ /Library/Frameworks
+ /sw
+ /opt/local
+ /opt/csw
+ /opt
+)
+
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDLIMAGE
+ REQUIRED_VARS SDLIMAGE_LIBRARY SDLIMAGE_INCLUDE_DIR)
diff --git a/Modules/FindSDL_mixer.cmake b/Modules/FindSDL_mixer.cmake
new file mode 100644
index 000000000..7cc1a6b09
--- /dev/null
+++ b/Modules/FindSDL_mixer.cmake
@@ -0,0 +1,70 @@
+# Locate SDL_mixer library
+# This module defines
+# SDLMIXER_LIBRARY, the name of the library to link against
+# SDLMIXER_FOUND, if false, do not try to link to SDL
+# SDLMIXER_INCLUDE_DIR, where to find SDL/SDL.h
+#
+# $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).
+
+#=============================================================================
+# 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.)
+
+FIND_PATH(SDLMIXER_INCLUDE_DIR SDL_mixer.h
+ HINTS
+ $ENV{SDLMIXERDIR}
+ $ENV{SDLDIR}
+ PATH_SUFFIXES include
+ PATHS
+ ~/Library/Frameworks
+ /Library/Frameworks
+ /usr/local/include/SDL
+ /usr/include/SDL
+ /usr/local/include/SDL12
+ /usr/local/include/SDL11 # FreeBSD ports
+ /usr/include/SDL12
+ /usr/include/SDL11
+ /sw/include/SDL # Fink
+ /sw/include
+ /opt/local/include/SDL # DarwinPorts
+ /opt/local/include
+ /opt/csw/include/SDL # Blastwave
+ /opt/csw/include
+ /opt/include/SDL
+ /opt/include
+)
+
+FIND_LIBRARY(SDLMIXER_LIBRARY
+ NAMES SDL_mixer
+ HINTS
+ $ENV{SDLMIXERDIR}
+ $ENV{SDLDIR}
+ PATH_SUFFIXES lib64 lib
+ PATHS
+ ~/Library/Frameworks
+ /Library/Frameworks
+ /sw
+ /opt/local
+ /opt/csw
+ /opt
+)
+
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDLMIXER
+ REQUIRED_VARS SDLMIXER_LIBRARY SDLMIXER_INCLUDE_DIR)
diff --git a/Modules/FindSDL_net.cmake b/Modules/FindSDL_net.cmake
new file mode 100644
index 000000000..ca1de7977
--- /dev/null
+++ b/Modules/FindSDL_net.cmake
@@ -0,0 +1,69 @@
+# Locate SDL_net library
+# This module defines
+# SDLNET_LIBRARY, the name of the library to link against
+# SDLNET_FOUND, if false, do not try to link against
+# SDLNET_INCLUDE_DIR, where to find the headers
+#
+# $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).
+
+#=============================================================================
+# 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.)
+
+FIND_PATH(SDLNET_INCLUDE_DIR SDL_net.h
+ HINTS
+ $ENV{SDLNETDIR}
+ $ENV{SDLDIR}
+ PATH_SUFFIXES include
+ PATHS
+ ~/Library/Frameworks
+ /Library/Frameworks
+ /usr/local/include/SDL
+ /usr/include/SDL
+ /usr/local/include/SDL12
+ /usr/local/include/SDL11 # FreeBSD ports
+ /usr/include/SDL12
+ /usr/include/SDL11
+ /sw/include/SDL # Fink
+ /sw/include
+ /opt/local/include/SDL # DarwinPorts
+ /opt/local/include
+ /opt/csw/include/SDL # Blastwave
+ /opt/csw/include
+ /opt/include/SDL
+ /opt/include
+)
+FIND_LIBRARY(SDLNET_LIBRARY
+ NAMES SDL_net
+ HINTS
+ $ENV{SDLNETDIR}
+ $ENV{SDLDIR}
+ PATH_SUFFIXES lib64 lib
+ PATHS
+ ~/Library/Frameworks
+ /Library/Frameworks
+ /sw
+ /opt/local
+ /opt/csw
+ /opt
+)
+
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDLNET
+ REQUIRED_VARS SDLNET_LIBRARY SDLNET_INCLUDE_DIR)
diff --git a/Modules/FindSDL_sound.cmake b/Modules/FindSDL_sound.cmake
new file mode 100644
index 000000000..35294a5e4
--- /dev/null
+++ b/Modules/FindSDL_sound.cmake
@@ -0,0 +1,401 @@
+# 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
+# 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.
+
+#
+# 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.
+# 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 .
+#
+# 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.
+#
+# 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.
+#
+
+#=============================================================================
+# 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.)
+
+SET(SDL_SOUND_EXTRAS "" CACHE STRING "SDL_sound extra flags")
+MARK_AS_ADVANCED(SDL_SOUND_EXTRAS)
+
+# Find SDL_sound.h
+FIND_PATH(SDL_SOUND_INCLUDE_DIR SDL_sound.h
+ HINTS
+ $ENV{SDLSOUNDDIR}/include
+ $ENV{SDLSOUNDDIR}
+ $ENV{SDLDIR}/include
+ $ENV{SDLDIR}
+ PATHS
+ /usr/local/include/SDL
+ /usr/include/SDL
+ /usr/local/include/SDL12
+ /usr/local/include/SDL11 # FreeBSD ports
+ /usr/include/SDL12
+ /usr/include/SDL11
+ /sw/include/SDL # Fink
+ /sw/include
+ /opt/local/include/SDL # DarwinPorts
+ /opt/local/include
+ /opt/csw/include/SDL # Blastwave
+ /opt/csw/include
+ /opt/include/SDL
+ /opt/include
+ )
+
+FIND_LIBRARY(SDL_SOUND_LIBRARY
+ NAMES SDL_sound
+ HINTS
+ $ENV{SDLSOUNDDIR}/lib
+ $ENV{SDLSOUNDDIR}
+ $ENV{SDLDIR}/lib
+ $ENV{SDLDIR}
+ PATHS
+ /sw/lib
+ /opt/local/lib
+ /opt/csw/lib
+ /opt/lib
+ )
+
+IF(SDL_FOUND AND SDL_SOUND_INCLUDE_DIR AND SDL_SOUND_LIBRARY)
+
+ # CMake is giving me problems using TRY_COMPILE with the CMAKE_FLAGS
+ # for the :STRING syntax if I have multiple values contained in a
+ # single variable. This is a problem for the SDL_LIBRARY variable
+ # because it does just that. When I feed this variable to the command,
+ # only the first value gets the appropriate modifier (e.g. -I) and
+ # the rest get dropped.
+ # To get multiple single variables to work, I must separate them with a "\;"
+ # I could go back and modify the FindSDL.cmake module, but that's kind of painful.
+ # The solution would be to try something like:
+ # SET(SDL_TRY_COMPILE_LIBRARY_LIST "${SDL_TRY_COMPILE_LIBRARY_LIST}\;${CMAKE_THREAD_LIBS_INIT}")
+ # Instead, it was suggested on the mailing list to write a temporary CMakeLists.txt
+ # with a temporary test project and invoke that with TRY_COMPILE.
+ # See message thread "Figuring out dependencies for a library in order to build"
+ # 2005-07-16
+ # TRY_COMPILE(
+ # MY_RESULT
+ # ${CMAKE_BINARY_DIR}
+ # ${PROJECT_SOURCE_DIR}/DetermineSoundLibs.c
+ # CMAKE_FLAGS
+ # -DINCLUDE_DIRECTORIES:STRING=${SDL_INCLUDE_DIR}\;${SDL_SOUND_INCLUDE_DIR}
+ # -DLINK_LIBRARIES:STRING=${SDL_SOUND_LIBRARY}\;${SDL_LIBRARY}
+ # OUTPUT_VARIABLE MY_OUTPUT
+ # )
+
+ # To minimize external dependencies, create a sdlsound test program
+ # which will be used to figure out if additional link dependencies are
+ # required for the link phase.
+ FILE(WRITE ${PROJECT_BINARY_DIR}/CMakeTmp/DetermineSoundLibs.c
+ "#include \"SDL_sound.h\"
+ #include \"SDL.h\"
+ int main(int argc, char* argv[])
+ {
+ Sound_AudioInfo desired;
+ Sound_Sample* sample;
+
+ SDL_Init(0);
+ Sound_Init();
+
+ /* This doesn't actually have to work, but Init() is a no-op
+ * for some of the decoders, so this should force more symbols
+ * to be pulled in.
+ */
+ sample = Sound_NewSampleFromFile(argv[1], &desired, 4096);
+
+ Sound_Quit();
+ SDL_Quit();
+ return 0;
+ }"
+ )
+
+ # Calling
+ # TARGET_LINK_LIBRARIES(DetermineSoundLibs "${SDL_SOUND_LIBRARY} ${SDL_LIBRARY})
+ # causes problems when SDL_LIBRARY looks like
+ # /Library/Frameworks/SDL.framework;-framework Cocoa
+ # The ;-framework Cocoa seems to be confusing CMake once the OS X
+ # framework support was added. I was told that breaking up the list
+ # would fix the problem.
+ SET(TMP_TRY_LIBS)
+ FOREACH(lib ${SDL_SOUND_LIBRARY} ${SDL_LIBRARY})
+ SET(TMP_TRY_LIBS "${TMP_TRY_LIBS} \"${lib}\"")
+ ENDFOREACH(lib)
+
+ # MESSAGE("TMP_TRY_LIBS ${TMP_TRY_LIBS}")
+
+ # Write the CMakeLists.txt and test project
+ # Weird, this is still sketchy. If I don't quote the variables
+ # in the TARGET_LINK_LIBRARIES, I seem to loose everything
+ # 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
+ "PROJECT(DetermineSoundLibs)
+ INCLUDE_DIRECTORIES(${SDL_INCLUDE_DIR} ${SDL_SOUND_INCLUDE_DIR})
+ ADD_EXECUTABLE(DetermineSoundLibs DetermineSoundLibs.c)
+ TARGET_LINK_LIBRARIES(DetermineSoundLibs ${TMP_TRY_LIBS})"
+ )
+
+ TRY_COMPILE(
+ MY_RESULT
+ ${PROJECT_BINARY_DIR}/CMakeTmp
+ ${PROJECT_BINARY_DIR}/CMakeTmp
+ DetermineSoundLibs
+ OUTPUT_VARIABLE MY_OUTPUT
+ )
+
+ # MESSAGE("${MY_RESULT}")
+ # MESSAGE(${MY_OUTPUT})
+
+ IF(NOT MY_RESULT)
+
+ # I expect that MPGLIB, VOC, WAV, AIFF, and SHN are compiled in statically.
+ # I think Timidity is also compiled in statically.
+ # I've never had to explcitly link against Quicktime, so I'll skip that for now.
+
+ SET(SDL_SOUND_LIBRARIES_TMP ${SDL_SOUND_LIBRARY})
+
+ # Find MikMod
+ IF("${MY_OUTPUT}" MATCHES "MikMod_")
+ FIND_LIBRARY(MIKMOD_LIBRARY
+ NAMES libmikmod-coreaudio mikmod
+ PATHS
+ $ENV{MIKMODDIR}/lib
+ $ENV{MIKMODDIR}
+ $ENV{SDLSOUNDDIR}/lib
+ $ENV{SDLSOUNDDIR}
+ $ENV{SDLDIR}/lib
+ $ENV{SDLDIR}
+ /sw/lib
+ /opt/local/lib
+ /opt/csw/lib
+ /opt/lib
+ )
+ IF(MIKMOD_LIBRARY)
+ SET(SDL_SOUND_LIBRARIES_TMP ${SDL_SOUND_LIBRARIES_TMP} ${MIKMOD_LIBRARY})
+ ENDIF(MIKMOD_LIBRARY)
+ ENDIF("${MY_OUTPUT}" MATCHES "MikMod_")
+
+ # Find ModPlug
+ IF("${MY_OUTPUT}" MATCHES "MODPLUG_")
+ FIND_LIBRARY(MODPLUG_LIBRARY
+ NAMES modplug
+ PATHS
+ $ENV{MODPLUGDIR}/lib
+ $ENV{MODPLUGDIR}
+ $ENV{SDLSOUNDDIR}/lib
+ $ENV{SDLSOUNDDIR}
+ $ENV{SDLDIR}/lib
+ $ENV{SDLDIR}
+ /sw/lib
+ /opt/local/lib
+ /opt/csw/lib
+ /opt/lib
+ )
+ IF(MODPLUG_LIBRARY)
+ SET(SDL_SOUND_LIBRARIES_TMP ${SDL_SOUND_LIBRARIES_TMP} ${MODPLUG_LIBRARY})
+ ENDIF(MODPLUG_LIBRARY)
+ ENDIF("${MY_OUTPUT}" MATCHES "MODPLUG_")
+
+
+ # Find Ogg and Vorbis
+ IF("${MY_OUTPUT}" MATCHES "ov_")
+ FIND_LIBRARY(VORBIS_LIBRARY
+ NAMES vorbis Vorbis VORBIS
+ PATHS
+ $ENV{VORBISDIR}/lib
+ $ENV{VORBISDIR}
+ $ENV{OGGDIR}/lib
+ $ENV{OGGDIR}
+ $ENV{SDLSOUNDDIR}/lib
+ $ENV{SDLSOUNDDIR}
+ $ENV{SDLDIR}/lib
+ $ENV{SDLDIR}
+ /sw/lib
+ /opt/local/lib
+ /opt/csw/lib
+ /opt/lib
+ )
+ IF(VORBIS_LIBRARY)
+ SET(SDL_SOUND_LIBRARIES_TMP ${SDL_SOUND_LIBRARIES_TMP} ${VORBIS_LIBRARY})
+ ENDIF(VORBIS_LIBRARY)
+
+ FIND_LIBRARY(OGG_LIBRARY
+ NAMES ogg Ogg OGG
+ PATHS
+ $ENV{OGGDIR}/lib
+ $ENV{OGGDIR}
+ $ENV{VORBISDIR}/lib
+ $ENV{VORBISDIR}
+ $ENV{SDLSOUNDDIR}/lib
+ $ENV{SDLSOUNDDIR}
+ $ENV{SDLDIR}/lib
+ $ENV{SDLDIR}
+ /sw/lib
+ /opt/local/lib
+ /opt/csw/lib
+ /opt/lib
+ )
+ IF(OGG_LIBRARY)
+ SET(SDL_SOUND_LIBRARIES_TMP ${SDL_SOUND_LIBRARIES_TMP} ${OGG_LIBRARY})
+ ENDIF(OGG_LIBRARY)
+ ENDIF("${MY_OUTPUT}" MATCHES "ov_")
+
+
+ # Find SMPEG
+ IF("${MY_OUTPUT}" MATCHES "SMPEG_")
+ FIND_LIBRARY(SMPEG_LIBRARY
+ NAMES smpeg SMPEG Smpeg SMpeg
+ PATHS
+ $ENV{SMPEGDIR}/lib
+ $ENV{SMPEGDIR}
+ $ENV{SDLSOUNDDIR}/lib
+ $ENV{SDLSOUNDDIR}
+ $ENV{SDLDIR}/lib
+ $ENV{SDLDIR}
+ /sw/lib
+ /opt/local/lib
+ /opt/csw/lib
+ /opt/lib
+ )
+ IF(SMPEG_LIBRARY)
+ SET(SDL_SOUND_LIBRARIES_TMP ${SDL_SOUND_LIBRARIES_TMP} ${SMPEG_LIBRARY})
+ ENDIF(SMPEG_LIBRARY)
+ ENDIF("${MY_OUTPUT}" MATCHES "SMPEG_")
+
+
+ # Find FLAC
+ IF("${MY_OUTPUT}" MATCHES "FLAC_")
+ FIND_LIBRARY(FLAC_LIBRARY
+ NAMES flac FLAC
+ PATHS
+ $ENV{FLACDIR}/lib
+ $ENV{FLACDIR}
+ $ENV{SDLSOUNDDIR}/lib
+ $ENV{SDLSOUNDDIR}
+ $ENV{SDLDIR}/lib
+ $ENV{SDLDIR}
+ /sw/lib
+ /opt/local/lib
+ /opt/csw/lib
+ /opt/lib
+ )
+ IF(FLAC_LIBRARY)
+ SET(SDL_SOUND_LIBRARIES_TMP ${SDL_SOUND_LIBRARIES_TMP} ${FLAC_LIBRARY})
+ ENDIF(FLAC_LIBRARY)
+ ENDIF("${MY_OUTPUT}" MATCHES "FLAC_")
+
+
+ # Hmmm...Speex seems to depend on Ogg. This might be a problem if
+ # the TRY_COMPILE attempt gets blocked at SPEEX before it can pull
+ # in the Ogg symbols. I'm not sure if I should duplicate the ogg stuff
+ # above for here or if two ogg entries will screw up things.
+ IF("${MY_OUTPUT}" MATCHES "speex_")
+ FIND_LIBRARY(SPEEX_LIBRARY
+ NAMES speex SPEEX
+ PATHS
+ $ENV{SPEEXDIR}/lib
+ $ENV{SPEEXDIR}
+ $ENV{SDLSOUNDDIR}/lib
+ $ENV{SDLSOUNDDIR}
+ $ENV{SDLDIR}/lib
+ $ENV{SDLDIR}
+ /sw/lib
+ /opt/local/lib
+ /opt/csw/lib
+ /opt/lib
+ )
+ IF(SPEEX_LIBRARY)
+ SET(SDL_SOUND_LIBRARIES_TMP ${SDL_SOUND_LIBRARIES_TMP} ${SPEEX_LIBRARY})
+ ENDIF(SPEEX_LIBRARY)
+
+ # Find OGG (needed for Speex)
+ # We might have already found Ogg for Vorbis, so skip it if so.
+ IF(NOT OGG_LIBRARY)
+ FIND_LIBRARY(OGG_LIBRARY
+ NAMES ogg Ogg OGG
+ PATHS
+ $ENV{OGGDIR}/lib
+ $ENV{OGGDIR}
+ $ENV{VORBISDIR}/lib
+ $ENV{VORBISDIR}
+ $ENV{SPEEXDIR}/lib
+ $ENV{SPEEXDIR}
+ $ENV{SDLSOUNDDIR}/lib
+ $ENV{SDLSOUNDDIR}
+ $ENV{SDLDIR}/lib
+ $ENV{SDLDIR}
+ /sw/lib
+ /opt/local/lib
+ /opt/csw/lib
+ /opt/lib
+ )
+ IF(OGG_LIBRARY)
+ SET(SDL_SOUND_LIBRARIES_TMP ${SDL_SOUND_LIBRARIES_TMP} ${OGG_LIBRARY})
+ ENDIF(OGG_LIBRARY)
+ ENDIF(NOT OGG_LIBRARY)
+ ENDIF("${MY_OUTPUT}" MATCHES "speex_")
+
+ ELSE(NOT MY_RESULT)
+ SET(SDL_SOUND_LIBRARIES "${SDL_SOUND_EXTRAS} ${SDL_SOUND_LIBRARY}" CACHE INTERNAL "SDL_sound and dependent libraries")
+ ENDIF(NOT MY_RESULT)
+
+ SET(SDL_SOUND_LIBRARIES "${SDL_SOUND_EXTRAS} ${SDL_SOUND_LIBRARIES_TMP}" CACHE INTERNAL "SDL_sound and dependent libraries")
+ ENDIF(SDL_FOUND AND SDL_SOUND_INCLUDE_DIR AND SDL_SOUND_LIBRARY)
+
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL_SOUND
+ REQUIRED_VARS SDL_SOUND_LIBRARIES SDL_SOUND_INCLUDE_DIR)
diff --git a/Modules/FindSDL_ttf.cmake b/Modules/FindSDL_ttf.cmake
new file mode 100644
index 000000000..184b6c3f5
--- /dev/null
+++ b/Modules/FindSDL_ttf.cmake
@@ -0,0 +1,70 @@
+# Locate SDL_ttf library
+# This module defines
+# SDLTTF_LIBRARY, the name of the library to link against
+# SDLTTF_FOUND, if false, do not try to link to SDL
+# SDLTTF_INCLUDE_DIR, where to find SDL/SDL.h
+#
+# $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).
+
+#=============================================================================
+# 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.)
+
+FIND_PATH(SDLTTF_INCLUDE_DIR SDL_ttf.h
+ HINTS
+ $ENV{SDLTTFDIR}
+ $ENV{SDLDIR}
+ PATH_SUFFIXES include
+ PATHS
+ ~/Library/Frameworks
+ /Library/Frameworks
+ /usr/local/include/SDL
+ /usr/include/SDL
+ /usr/local/include/SDL12
+ /usr/local/include/SDL11 # FreeBSD ports
+ /usr/include/SDL12
+ /usr/include/SDL11
+ /sw/include/SDL # Fink
+ /sw/include
+ /opt/local/include/SDL # DarwinPorts
+ /opt/local/include
+ /opt/csw/include/SDL # Blastwave
+ /opt/csw/include
+ /opt/include/SDL
+ /opt/include
+)
+
+FIND_LIBRARY(SDLTTF_LIBRARY
+ NAMES SDL_ttf
+ HINTS
+ $ENV{SDLTTFDIR}
+ $ENV{SDLDIR}
+ PATHS
+ ~/Library/Frameworks
+ /Library/Frameworks
+ /sw
+ /opt/local
+ /opt/csw
+ /opt
+ PATH_SUFFIXES lib64 lib
+)
+
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDLTTF
+ REQUIRED_VARS SDLTTF_LIBRARY SDLTTF_INCLUDE_DIR)
diff --git a/Modules/FindSWIG.cmake b/Modules/FindSWIG.cmake
new file mode 100644
index 000000000..2e34eb1b4
--- /dev/null
+++ b/Modules/FindSWIG.cmake
@@ -0,0 +1,68 @@
+# - 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)
+#
+# 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>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software 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(SWIG_EXECUTABLE NAMES swig2.0 swig)
+
+IF(SWIG_EXECUTABLE)
+ EXECUTE_PROCESS(COMMAND ${SWIG_EXECUTABLE} -swiglib
+ OUTPUT_VARIABLE SWIG_swiglib_output
+ ERROR_VARIABLE SWIG_swiglib_error
+ RESULT_VARIABLE SWIG_swiglib_result)
+
+ IF(SWIG_swiglib_result)
+ IF(SWIG_FIND_REQUIRED)
+ MESSAGE(SEND_ERROR "Command \"${SWIG_EXECUTABLE} -swiglib\" failed with output:\n${SWIG_swiglib_error}")
+ ELSE(SWIG_FIND_REQUIRED)
+ MESSAGE(STATUS "Command \"${SWIG_EXECUTABLE} -swiglib\" failed with output:\n${SWIG_swiglib_error}")
+ ENDIF(SWIG_FIND_REQUIRED)
+ ELSE(SWIG_swiglib_result)
+ 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})
+ IF(SWIG_DIR)
+ SET(SWIG_USE_FILE ${CMAKE_ROOT}/Modules/UseSWIG.cmake)
+ EXECUTE_PROCESS(COMMAND ${SWIG_EXECUTABLE} -version
+ OUTPUT_VARIABLE SWIG_version_output
+ ERROR_VARIABLE SWIG_version_output
+ RESULT_VARIABLE SWIG_version_result)
+ IF(SWIG_version_result)
+ MESSAGE(SEND_ERROR "Command \"${SWIG_EXECUTABLE} -version\" failed with output:\n${SWIG_version_output}")
+ ELSE(SWIG_version_result)
+ STRING(REGEX REPLACE ".*SWIG Version[^0-9.]*\([0-9.]+\).*" "\\1"
+ SWIG_version_output "${SWIG_version_output}")
+ SET(SWIG_VERSION ${SWIG_version_output} CACHE STRING "Swig version" FORCE)
+ ENDIF(SWIG_version_result)
+ ENDIF(SWIG_DIR)
+ ENDIF(SWIG_swiglib_result)
+ENDIF(SWIG_EXECUTABLE)
+
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(SWIG REQUIRED_VARS SWIG_EXECUTABLE SWIG_DIR
+ VERSION_VAR SWIG_VERSION )
diff --git a/Modules/FindSelfPackers.cmake b/Modules/FindSelfPackers.cmake
new file mode 100644
index 000000000..ffca84200
--- /dev/null
+++ b/Modules/FindSelfPackers.cmake
@@ -0,0 +1,68 @@
+# - Find upx
+# This module looks for some executable packers (i.e. softwares 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
+
+#=============================================================================
+# 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.)
+
+INCLUDE(FindCygwin)
+
+FIND_PROGRAM(SELF_PACKER_FOR_EXECUTABLE
+ upx
+ ${CYGWIN_INSTALL_PATH}/bin
+ /bin
+ /usr/bin
+ /usr/local/bin
+ /sbin
+)
+
+FIND_PROGRAM(SELF_PACKER_FOR_SHARED_LIB
+ upx
+ ${CYGWIN_INSTALL_PATH}/bin
+ /bin
+ /usr/bin
+ /usr/local/bin
+ /sbin
+)
+
+MARK_AS_ADVANCED(
+ SELF_PACKER_FOR_EXECUTABLE
+ SELF_PACKER_FOR_SHARED_LIB
+)
+
+#
+# Set flags
+#
+IF (SELF_PACKER_FOR_EXECUTABLE MATCHES "upx")
+ SET (SELF_PACKER_FOR_EXECUTABLE_FLAGS "-q" CACHE STRING
+ "Flags for the executable self-packer.")
+ELSE (SELF_PACKER_FOR_EXECUTABLE MATCHES "upx")
+ SET (SELF_PACKER_FOR_EXECUTABLE_FLAGS "" CACHE STRING
+ "Flags for the executable self-packer.")
+ENDIF (SELF_PACKER_FOR_EXECUTABLE MATCHES "upx")
+
+IF (SELF_PACKER_FOR_SHARED_LIB MATCHES "upx")
+ SET (SELF_PACKER_FOR_SHARED_LIB_FLAGS "-q" CACHE STRING
+ "Flags for the shared lib self-packer.")
+ELSE (SELF_PACKER_FOR_SHARED_LIB MATCHES "upx")
+ SET (SELF_PACKER_FOR_SHARED_LIB_FLAGS "" CACHE STRING
+ "Flags for the shared lib self-packer.")
+ENDIF (SELF_PACKER_FOR_SHARED_LIB MATCHES "upx")
+
+MARK_AS_ADVANCED(
+ SELF_PACKER_FOR_EXECUTABLE_FLAGS
+ SELF_PACKER_FOR_SHARED_LIB_FLAGS
+)
diff --git a/Modules/FindSquish.cmake b/Modules/FindSquish.cmake
new file mode 100644
index 000000000..48d195a1e
--- /dev/null
+++ b/Modules/FindSquish.cmake
@@ -0,0 +1,125 @@
+#
+# ---- Find Squish
+# This module can be used to find Squish (currently support is aimed at version 3).
+#
+# ---- Variables and Macros
+# SQUISH_FOUND If false, don't try to use Squish
+#
+# 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?
+#
+# macro SQUISH_ADD_TEST(testName applicationUnderTest testSuite testCase)
+#
+# ---- Typical Use
+# ENABLE_TESTING()
+# FIND_PACKAGE(Squish)
+# IF (SQUISH_FOUND)
+# SQUISH_ADD_TEST(myTestName myApplication testSuiteName testCaseName)
+# ENDIF (SQUISH_FOUND)
+#
+
+#=============================================================================
+# Copyright 2008-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.)
+
+SET(SQUISH_INSTALL_DIR_STRING "Directory containing the bin, doc, and lib directories for Squish; this should be the root of the installation directory.")
+SET(SQUISH_SERVER_EXECUTABLE_STRING "The squishserver executable program.")
+SET(SQUISH_CLIENT_EXECUTABLE_STRING "The squishclient executable program.")
+
+# Search only if the location is not already known.
+IF(NOT SQUISH_INSTALL_DIR)
+ # Get the system search path as a list.
+ FILE(TO_CMAKE_PATH "$ENV{PATH}" SQUISH_INSTALL_DIR_SEARCH2)
+
+ # Construct a set of paths relative to the system search path.
+ SET(SQUISH_INSTALL_DIR_SEARCH "")
+ FOREACH(dir ${SQUISH_INSTALL_DIR_SEARCH2})
+ SET(SQUISH_INSTALL_DIR_SEARCH ${SQUISH_INSTALL_DIR_SEARCH} "${dir}/../lib/fltk")
+ ENDFOREACH(dir)
+ STRING(REPLACE "//" "/" SQUISH_INSTALL_DIR_SEARCH "${SQUISH_INSTALL_DIR_SEARCH}")
+
+ # Look for an installation
+ FIND_PATH(SQUISH_INSTALL_DIR bin/squishrunner
+ # Look for an environment variable SQUISH_INSTALL_DIR.
+ $ENV{SQUISH_INSTALL_DIR}
+
+ # Look in places relative to the system executable search path.
+ ${SQUISH_INSTALL_DIR_SEARCH}
+
+ # Look in standard UNIX install locations.
+ #/usr/local/squish
+
+ DOC "The ${SQUISH_INSTALL_DIR_STRING}"
+ )
+ENDIF(NOT SQUISH_INSTALL_DIR)
+
+# search for the executables
+IF(SQUISH_INSTALL_DIR)
+ SET(SQUISH_INSTALL_DIR_FOUND 1)
+
+ # find the client program
+ IF(NOT SQUISH_CLIENT_EXECUTABLE)
+ FIND_PROGRAM(SQUISH_CLIENT_EXECUTABLE ${SQUISH_INSTALL_DIR}/bin/squishrunner DOC "The ${SQUISH_CLIENT_EXECUTABLE_STRING}")
+ ENDIF(NOT SQUISH_CLIENT_EXECUTABLE)
+
+ # find the server program
+ IF(NOT SQUISH_SERVER_EXECUTABLE)
+ FIND_PROGRAM(SQUISH_SERVER_EXECUTABLE ${SQUISH_INSTALL_DIR}/bin/squishserver DOC "The ${SQUISH_SERVER_EXECUTABLE_STRING}")
+ ENDIF(NOT SQUISH_SERVER_EXECUTABLE)
+
+ELSE(SQUISH_INSTALL_DIR)
+ SET(SQUISH_INSTALL_DIR_FOUND 0)
+ENDIF(SQUISH_INSTALL_DIR)
+
+# record if executables are set
+IF(SQUISH_CLIENT_EXECUTABLE)
+ SET(SQUISH_CLIENT_EXECUTABLE_FOUND 1)
+ELSE(SQUISH_CLIENT_EXECUTABLE)
+ SET(SQUISH_CLIENT_EXECUTABLE_FOUND 0)
+ENDIF(SQUISH_CLIENT_EXECUTABLE)
+
+IF(SQUISH_SERVER_EXECUTABLE)
+ SET(SQUISH_SERVER_EXECUTABLE_FOUND 1)
+ELSE(SQUISH_SERVER_EXECUTABLE)
+ SET(SQUISH_SERVER_EXECUTABLE_FOUND 0)
+ENDIF(SQUISH_SERVER_EXECUTABLE)
+
+# record if Squish was found
+SET(SQUISH_FOUND 1)
+FOREACH(var SQUISH_INSTALL_DIR_FOUND SQUISH_CLIENT_EXECUTABLE_FOUND SQUISH_SERVER_EXECUTABLE_FOUND)
+ IF(NOT ${var})
+ SET(SQUISH_FOUND 0)
+ ENDIF(NOT ${var})
+ENDFOREACH(var)
+
+MACRO(SQUISH_ADD_TEST testName testAUT testCase envVars testWraper)
+ ADD_TEST(${testName}
+ ${CMAKE_COMMAND} -V -VV
+ "-Dsquish_aut:STRING=${testAUT}"
+ "-Dsquish_server_executable:STRING=${SQUISH_SERVER_EXECUTABLE}"
+ "-Dsquish_client_executable:STRING=${SQUISH_CLIENT_EXECUTABLE}"
+ "-Dsquish_libqtdir:STRING=${QT_LIBRARY_DIR}"
+ "-Dsquish_test_case:STRING=${testCase}"
+ "-Dsquish_env_vars:STRING=${envVars}"
+ "-Dsquish_wrapper:STRING=${testWraper}"
+ -P "${CMAKE_ROOT}/Modules/SquishTestScript.cmake"
+ )
+ SET_TESTS_PROPERTIES(${testName}
+ PROPERTIES FAIL_REGULAR_EXPRESSION "FAILED;ERROR;FATAL"
+ )
+ENDMACRO(SQUISH_ADD_TEST)
+
diff --git a/Modules/FindSubversion.cmake b/Modules/FindSubversion.cmake
new file mode 100644
index 000000000..4166d99ab
--- /dev/null
+++ b/Modules/FindSubversion.cmake
@@ -0,0 +1,131 @@
+# - 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
+#
+# The minimum required version of Subversion can be specified using the
+# 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_LOG retrieves the log message of the base revision of a
+# subversion working copy at a given location. This macro defines the
+# variable:
+# <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(SUBVERSION_FOUND)
+
+#=============================================================================
+# Copyright 2006-2009 Kitware, Inc.
+# Copyright 2006 Tristan Carel
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software 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(Subversion_SVN_EXECUTABLE svn
+ DOC "subversion command line client")
+MARK_AS_ADVANCED(Subversion_SVN_EXECUTABLE)
+
+IF(Subversion_SVN_EXECUTABLE)
+ # the subversion commands should be executed with the C locale, otherwise
+ # the message (which are parsed) may be translated, Alex
+ SET(_Subversion_SAVED_LC_ALL "$ENV{LC_ALL}")
+ SET(ENV{LC_ALL} C)
+
+ EXECUTE_PROCESS(COMMAND ${Subversion_SVN_EXECUTABLE} --version
+ OUTPUT_VARIABLE Subversion_VERSION_SVN
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ # restore the previous LC_ALL
+ SET(ENV{LC_ALL} ${_Subversion_SAVED_LC_ALL})
+
+ STRING(REGEX REPLACE "^(.*\n)?svn, version ([.0-9]+).*"
+ "\\2" Subversion_VERSION_SVN "${Subversion_VERSION_SVN}")
+
+ MACRO(Subversion_WC_INFO dir prefix)
+ # the subversion commands should be executed with the C locale, otherwise
+ # the message (which are parsed) may be translated, Alex
+ SET(_Subversion_SAVED_LC_ALL "$ENV{LC_ALL}")
+ SET(ENV{LC_ALL} C)
+
+ EXECUTE_PROCESS(COMMAND ${Subversion_SVN_EXECUTABLE} info ${dir}
+ OUTPUT_VARIABLE ${prefix}_WC_INFO
+ ERROR_VARIABLE Subversion_svn_info_error
+ RESULT_VARIABLE Subversion_svn_info_result
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ IF(NOT ${Subversion_svn_info_result} EQUAL 0)
+ MESSAGE(SEND_ERROR "Command \"${Subversion_SVN_EXECUTABLE} info ${dir}\" failed with output:\n${Subversion_svn_info_error}")
+ ELSE(NOT ${Subversion_svn_info_result} EQUAL 0)
+
+ STRING(REGEX REPLACE "^(.*\n)?URL: ([^\n]+).*"
+ "\\2" ${prefix}_WC_URL "${${prefix}_WC_INFO}")
+ STRING(REGEX REPLACE "^(.*\n)?Repository Root: ([^\n]+).*"
+ "\\2" ${prefix}_WC_ROOT "${${prefix}_WC_INFO}")
+ STRING(REGEX REPLACE "^(.*\n)?Revision: ([^\n]+).*"
+ "\\2" ${prefix}_WC_REVISION "${${prefix}_WC_INFO}")
+ STRING(REGEX REPLACE "^(.*\n)?Last Changed Author: ([^\n]+).*"
+ "\\2" ${prefix}_WC_LAST_CHANGED_AUTHOR "${${prefix}_WC_INFO}")
+ STRING(REGEX REPLACE "^(.*\n)?Last Changed Rev: ([^\n]+).*"
+ "\\2" ${prefix}_WC_LAST_CHANGED_REV "${${prefix}_WC_INFO}")
+ STRING(REGEX REPLACE "^(.*\n)?Last Changed Date: ([^\n]+).*"
+ "\\2" ${prefix}_WC_LAST_CHANGED_DATE "${${prefix}_WC_INFO}")
+
+ ENDIF(NOT ${Subversion_svn_info_result} EQUAL 0)
+
+ # restore the previous LC_ALL
+ SET(ENV{LC_ALL} ${_Subversion_SAVED_LC_ALL})
+
+ ENDMACRO(Subversion_WC_INFO)
+
+ MACRO(Subversion_WC_LOG dir prefix)
+ # This macro can block if the certificate is not signed:
+ # svn ask you to accept the certificate and wait for your answer
+ # This macro requires a svn server network access (Internet most of the time)
+ # and can also be slow since it access the svn server
+ EXECUTE_PROCESS(COMMAND
+ ${Subversion_SVN_EXECUTABLE} --non-interactive log -r BASE ${dir}
+ OUTPUT_VARIABLE ${prefix}_LAST_CHANGED_LOG
+ ERROR_VARIABLE Subversion_svn_log_error
+ RESULT_VARIABLE Subversion_svn_log_result
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ IF(NOT ${Subversion_svn_log_result} EQUAL 0)
+ MESSAGE(SEND_ERROR "Command \"${Subversion_SVN_EXECUTABLE} log -r BASE ${dir}\" failed with output:\n${Subversion_svn_log_error}")
+ ENDIF(NOT ${Subversion_svn_log_result} EQUAL 0)
+ ENDMACRO(Subversion_WC_LOG)
+
+ENDIF(Subversion_SVN_EXECUTABLE)
+
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Subversion REQUIRED_VARS Subversion_SVN_EXECUTABLE
+ VERSION_VAR Subversion_VERSION_SVN )
+
+# for compatibility
+SET(Subversion_FOUND ${SUBVERSION_FOUND})
+SET(Subversion_SVN_FOUND ${SUBVERSION_FOUND})
diff --git a/Modules/FindTCL.cmake b/Modules/FindTCL.cmake
new file mode 100644
index 000000000..7f6d3a7ee
--- /dev/null
+++ b/Modules/FindTCL.cmake
@@ -0,0 +1,215 @@
+# - 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
+#
+# 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.
+
+#=============================================================================
+# 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.)
+
+INCLUDE(CMakeFindFrameworks)
+INCLUDE(FindTclsh)
+INCLUDE(FindWish)
+
+IF(TCLSH_VERSION_STRING)
+ SET(TCL_TCLSH_VERSION "${TCLSH_VERSION_STRING}")
+ELSE(TCLSH_VERSION_STRING)
+ GET_FILENAME_COMPONENT(TCL_TCLSH_PATH "${TCL_TCLSH}" PATH)
+ GET_FILENAME_COMPONENT(TCL_TCLSH_PATH_PARENT "${TCL_TCLSH_PATH}" PATH)
+ STRING(REGEX REPLACE
+ "^.*tclsh([0-9]\\.*[0-9]).*$" "\\1" TCL_TCLSH_VERSION "${TCL_TCLSH}")
+ENDIF(TCLSH_VERSION_STRING)
+
+GET_FILENAME_COMPONENT(TK_WISH_PATH "${TK_WISH}" PATH)
+GET_FILENAME_COMPONENT(TK_WISH_PATH_PARENT "${TK_WISH_PATH}" PATH)
+STRING(REGEX REPLACE
+ "^.*wish([0-9]\\.*[0-9]).*$" "\\1" TK_WISH_VERSION "${TK_WISH}")
+
+GET_FILENAME_COMPONENT(TCL_INCLUDE_PATH_PARENT "${TCL_INCLUDE_PATH}" PATH)
+GET_FILENAME_COMPONENT(TK_INCLUDE_PATH_PARENT "${TK_INCLUDE_PATH}" PATH)
+
+GET_FILENAME_COMPONENT(TCL_LIBRARY_PATH "${TCL_LIBRARY}" PATH)
+GET_FILENAME_COMPONENT(TCL_LIBRARY_PATH_PARENT "${TCL_LIBRARY_PATH}" PATH)
+STRING(REGEX REPLACE
+ "^.*tcl([0-9]\\.*[0-9]).*$" "\\1" TCL_LIBRARY_VERSION "${TCL_LIBRARY}")
+
+GET_FILENAME_COMPONENT(TK_LIBRARY_PATH "${TK_LIBRARY}" PATH)
+GET_FILENAME_COMPONENT(TK_LIBRARY_PATH_PARENT "${TK_LIBRARY_PATH}" PATH)
+STRING(REGEX REPLACE
+ "^.*tk([0-9]\\.*[0-9]).*$" "\\1" TK_LIBRARY_VERSION "${TK_LIBRARY}")
+
+SET(TCLTK_POSSIBLE_LIB_PATHS
+ "${TCL_INCLUDE_PATH_PARENT}/lib"
+ "${TK_INCLUDE_PATH_PARENT}/lib"
+ "${TCL_LIBRARY_PATH}"
+ "${TK_LIBRARY_PATH}"
+ "${TCL_TCLSH_PATH_PARENT}/lib"
+ "${TK_WISH_PATH_PARENT}/lib"
+ )
+
+IF(WIN32)
+ GET_FILENAME_COMPONENT(
+ ActiveTcl_CurrentVersion
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\ActiveState\\ActiveTcl;CurrentVersion]"
+ NAME)
+ SET(TCLTK_POSSIBLE_LIB_PATHS ${TCLTK_POSSIBLE_LIB_PATHS}
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\ActiveState\\ActiveTcl\\${ActiveTcl_CurrentVersion}]/lib"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Scriptics\\Tcl\\8.6;Root]/lib"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Scriptics\\Tcl\\8.5;Root]/lib"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Scriptics\\Tcl\\8.4;Root]/lib"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Scriptics\\Tcl\\8.3;Root]/lib"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Scriptics\\Tcl\\8.2;Root]/lib"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Scriptics\\Tcl\\8.0;Root]/lib"
+ "$ENV{ProgramFiles}/Tcl/Lib"
+ "C:/Program Files/Tcl/lib"
+ "C:/Tcl/lib"
+ )
+ENDIF(WIN32)
+
+FIND_LIBRARY(TCL_LIBRARY
+ NAMES
+ tcl
+ tcl${TCL_LIBRARY_VERSION} tcl${TCL_TCLSH_VERSION} tcl${TK_WISH_VERSION}
+ tcl86 tcl8.6
+ tcl85 tcl8.5
+ tcl84 tcl8.4
+ tcl83 tcl8.3
+ tcl82 tcl8.2
+ tcl80 tcl8.0
+ PATHS ${TCLTK_POSSIBLE_LIB_PATHS}
+ )
+
+FIND_LIBRARY(TK_LIBRARY
+ NAMES
+ tk
+ tk${TK_LIBRARY_VERSION} tk${TCL_TCLSH_VERSION} tk${TK_WISH_VERSION}
+ tk86 tk8.6
+ tk85 tk8.5
+ tk84 tk8.4
+ tk83 tk8.3
+ tk82 tk8.2
+ tk80 tk8.0
+ PATHS ${TCLTK_POSSIBLE_LIB_PATHS}
+ )
+
+CMAKE_FIND_FRAMEWORKS(Tcl)
+CMAKE_FIND_FRAMEWORKS(Tk)
+
+SET(TCL_FRAMEWORK_INCLUDES)
+IF(Tcl_FRAMEWORKS)
+ IF(NOT TCL_INCLUDE_PATH)
+ FOREACH(dir ${Tcl_FRAMEWORKS})
+ SET(TCL_FRAMEWORK_INCLUDES ${TCL_FRAMEWORK_INCLUDES} ${dir}/Headers)
+ ENDFOREACH(dir)
+ ENDIF(NOT TCL_INCLUDE_PATH)
+ENDIF(Tcl_FRAMEWORKS)
+
+SET(TK_FRAMEWORK_INCLUDES)
+IF(Tk_FRAMEWORKS)
+ IF(NOT TK_INCLUDE_PATH)
+ FOREACH(dir ${Tk_FRAMEWORKS})
+ SET(TK_FRAMEWORK_INCLUDES ${TK_FRAMEWORK_INCLUDES}
+ ${dir}/Headers ${dir}/PrivateHeaders)
+ ENDFOREACH(dir)
+ ENDIF(NOT TK_INCLUDE_PATH)
+ENDIF(Tk_FRAMEWORKS)
+
+SET(TCLTK_POSSIBLE_INCLUDE_PATHS
+ "${TCL_LIBRARY_PATH_PARENT}/include"
+ "${TK_LIBRARY_PATH_PARENT}/include"
+ "${TCL_INCLUDE_PATH}"
+ "${TK_INCLUDE_PATH}"
+ ${TCL_FRAMEWORK_INCLUDES}
+ ${TK_FRAMEWORK_INCLUDES}
+ "${TCL_TCLSH_PATH_PARENT}/include"
+ "${TK_WISH_PATH_PARENT}/include"
+ /usr/include/tcl${TK_LIBRARY_VERSION}
+ /usr/include/tcl${TCL_LIBRARY_VERSION}
+ /usr/include/tcl8.6
+ /usr/include/tcl8.5
+ /usr/include/tcl8.4
+ /usr/include/tcl8.3
+ /usr/include/tcl8.2
+ /usr/include/tcl8.0
+ )
+
+IF(WIN32)
+ SET(TCLTK_POSSIBLE_INCLUDE_PATHS ${TCLTK_POSSIBLE_INCLUDE_PATHS}
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\ActiveState\\ActiveTcl\\${ActiveTcl_CurrentVersion}]/include"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Scriptics\\Tcl\\8.6;Root]/include"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Scriptics\\Tcl\\8.5;Root]/include"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Scriptics\\Tcl\\8.4;Root]/include"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Scriptics\\Tcl\\8.3;Root]/include"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Scriptics\\Tcl\\8.2;Root]/include"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Scriptics\\Tcl\\8.0;Root]/include"
+ "$ENV{ProgramFiles}/Tcl/include"
+ "C:/Program Files/Tcl/include"
+ "C:/Tcl/include"
+ )
+ENDIF(WIN32)
+
+FIND_PATH(TCL_INCLUDE_PATH
+ NAMES tcl.h
+ HINTS ${TCLTK_POSSIBLE_INCLUDE_PATHS}
+ )
+
+FIND_PATH(TK_INCLUDE_PATH
+ NAMES tk.h
+ HINTS ${TCLTK_POSSIBLE_INCLUDE_PATHS}
+ )
+
+# handle the QUIETLY and REQUIRED arguments and set TCL_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(TCL DEFAULT_MSG TCL_LIBRARY TCL_INCLUDE_PATH)
+SET(TCLTK_FIND_REQUIRED ${TCL_FIND_REQUIRED})
+SET(TCLTK_FIND_QUIETLY ${TCL_FIND_QUIETLY})
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(TCLTK DEFAULT_MSG TCL_LIBRARY TCL_INCLUDE_PATH TK_LIBRARY TK_INCLUDE_PATH)
+SET(TK_FIND_REQUIRED ${TCL_FIND_REQUIRED})
+SET(TK_FIND_QUIETLY ${TCL_FIND_QUIETLY})
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(TK DEFAULT_MSG TK_LIBRARY TK_INCLUDE_PATH)
+
+MARK_AS_ADVANCED(
+ TCL_INCLUDE_PATH
+ TK_INCLUDE_PATH
+ TCL_LIBRARY
+ TK_LIBRARY
+ )
diff --git a/Modules/FindTIFF.cmake b/Modules/FindTIFF.cmake
new file mode 100644
index 000000000..16f9e238a
--- /dev/null
+++ b/Modules/FindTIFF.cmake
@@ -0,0 +1,48 @@
+# - 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.
+
+#=============================================================================
+# 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_PATH(TIFF_INCLUDE_DIR tiff.h)
+
+SET(TIFF_NAMES ${TIFF_NAMES} tiff libtiff tiff3 libtiff3)
+FIND_LIBRARY(TIFF_LIBRARY NAMES ${TIFF_NAMES} )
+
+IF(TIFF_INCLUDE_DIR AND EXISTS "${TIFF_INCLUDE_DIR}/tiffvers.h")
+ FILE(STRINGS "${TIFF_INCLUDE_DIR}/tiffvers.h" tiff_version_str
+ REGEX "^#define[\t ]+TIFFLIB_VERSION_STR[\t ]+\"LIBTIFF, Version .*")
+
+ STRING(REGEX REPLACE "^#define[\t ]+TIFFLIB_VERSION_STR[\t ]+\"LIBTIFF, Version +([^ \\n]*).*"
+ "\\1" TIFF_VERSION_STRING "${tiff_version_str}")
+ UNSET(tiff_version_str)
+ENDIF()
+
+# handle the QUIETLY and REQUIRED arguments and set TIFF_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(TIFF
+ REQUIRED_VARS TIFF_LIBRARY TIFF_INCLUDE_DIR
+ VERSION_VAR TIFF_VERSION_STRING)
+
+IF(TIFF_FOUND)
+ SET( TIFF_LIBRARIES ${TIFF_LIBRARY} )
+ENDIF(TIFF_FOUND)
+
+MARK_AS_ADVANCED(TIFF_INCLUDE_DIR TIFF_LIBRARY)
diff --git a/Modules/FindTclStub.cmake b/Modules/FindTclStub.cmake
new file mode 100644
index 000000000..79d14aeb4
--- /dev/null
+++ b/Modules/FindTclStub.cmake
@@ -0,0 +1,130 @@
+# - 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
+# Using Stub Libraries:
+# 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.
+
+#=============================================================================
+# Copyright 2008-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.)
+
+INCLUDE(FindTCL)
+
+GET_FILENAME_COMPONENT(TCL_TCLSH_PATH "${TCL_TCLSH}" PATH)
+GET_FILENAME_COMPONENT(TCL_TCLSH_PATH_PARENT "${TCL_TCLSH_PATH}" PATH)
+STRING(REGEX REPLACE
+ "^.*tclsh([0-9]\\.*[0-9]).*$" "\\1" TCL_TCLSH_VERSION "${TCL_TCLSH}")
+
+GET_FILENAME_COMPONENT(TK_WISH_PATH "${TK_WISH}" PATH)
+GET_FILENAME_COMPONENT(TK_WISH_PATH_PARENT "${TK_WISH_PATH}" PATH)
+STRING(REGEX REPLACE
+ "^.*wish([0-9]\\.*[0-9]).*$" "\\1" TK_WISH_VERSION "${TK_WISH}")
+
+GET_FILENAME_COMPONENT(TCL_INCLUDE_PATH_PARENT "${TCL_INCLUDE_PATH}" PATH)
+GET_FILENAME_COMPONENT(TK_INCLUDE_PATH_PARENT "${TK_INCLUDE_PATH}" PATH)
+
+GET_FILENAME_COMPONENT(TCL_LIBRARY_PATH "${TCL_LIBRARY}" PATH)
+GET_FILENAME_COMPONENT(TCL_LIBRARY_PATH_PARENT "${TCL_LIBRARY_PATH}" PATH)
+STRING(REGEX REPLACE
+ "^.*tcl([0-9]\\.*[0-9]).*$" "\\1" TCL_LIBRARY_VERSION "${TCL_LIBRARY}")
+
+GET_FILENAME_COMPONENT(TK_LIBRARY_PATH "${TK_LIBRARY}" PATH)
+GET_FILENAME_COMPONENT(TK_LIBRARY_PATH_PARENT "${TK_LIBRARY_PATH}" PATH)
+STRING(REGEX REPLACE
+ "^.*tk([0-9]\\.*[0-9]).*$" "\\1" TK_LIBRARY_VERSION "${TK_LIBRARY}")
+
+SET(TCLTK_POSSIBLE_LIB_PATHS
+ "${TCL_INCLUDE_PATH_PARENT}/lib"
+ "${TK_INCLUDE_PATH_PARENT}/lib"
+ "${TCL_LIBRARY_PATH}"
+ "${TK_LIBRARY_PATH}"
+ "${TCL_TCLSH_PATH_PARENT}/lib"
+ "${TK_WISH_PATH_PARENT}/lib"
+)
+
+IF(WIN32)
+ GET_FILENAME_COMPONENT(
+ ActiveTcl_CurrentVersion
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\ActiveState\\ActiveTcl;CurrentVersion]"
+ NAME)
+ SET(TCLTK_POSSIBLE_LIB_PATHS ${TCLTK_POSSIBLE_LIB_PATHS}
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\ActiveState\\ActiveTcl\\${ActiveTcl_CurrentVersion}]/lib"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Scriptics\\Tcl\\8.6;Root]/lib"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Scriptics\\Tcl\\8.5;Root]/lib"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Scriptics\\Tcl\\8.4;Root]/lib"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Scriptics\\Tcl\\8.3;Root]/lib"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Scriptics\\Tcl\\8.2;Root]/lib"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Scriptics\\Tcl\\8.0;Root]/lib"
+ "$ENV{ProgramFiles}/Tcl/Lib"
+ "C:/Program Files/Tcl/lib"
+ "C:/Tcl/lib"
+ )
+ENDIF(WIN32)
+
+FIND_LIBRARY(TCL_STUB_LIBRARY
+ NAMES
+ tclstub
+ tclstub${TK_LIBRARY_VERSION} tclstub${TCL_TCLSH_VERSION} tclstub${TK_WISH_VERSION}
+ tclstub86 tclstub8.6
+ tclstub85 tclstub8.5
+ tclstub84 tclstub8.4
+ tclstub83 tclstub8.3
+ tclstub82 tclstub8.2
+ tclstub80 tclstub8.0
+ PATHS ${TCLTK_POSSIBLE_LIB_PATHS}
+)
+
+FIND_LIBRARY(TK_STUB_LIBRARY
+ NAMES
+ tkstub
+ tkstub${TCL_LIBRARY_VERSION} tkstub${TCL_TCLSH_VERSION} tkstub${TK_WISH_VERSION}
+ tkstub86 tkstub8.6
+ tkstub85 tkstub8.5
+ tkstub84 tkstub8.4
+ tkstub83 tkstub8.3
+ tkstub82 tkstub8.2
+ tkstub80 tkstub8.0
+ PATHS ${TCLTK_POSSIBLE_LIB_PATHS}
+)
+
+FIND_LIBRARY(TTK_STUB_LIBRARY
+ NAMES
+ ttkstub
+ ttkstub${TCL_LIBRARY_VERSION} ttkstub${TCL_TCLSH_VERSION} ttkstub${TK_WISH_VERSION}
+ ttkstub88 ttkstub8.8
+ ttkstub87 ttkstub8.7
+ ttkstub86 ttkstub8.6
+ ttkstub85 ttkstub8.5
+ PATHS ${TCLTK_POSSIBLE_LIB_PATHS}
+)
+
+MARK_AS_ADVANCED(
+ TCL_STUB_LIBRARY
+ TK_STUB_LIBRARY
+ )
diff --git a/Modules/FindTclsh.cmake b/Modules/FindTclsh.cmake
new file mode 100644
index 000000000..a45f28528
--- /dev/null
+++ b/Modules/FindTclsh.cmake
@@ -0,0 +1,100 @@
+# - 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.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software 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(CYGWIN)
+ FIND_PROGRAM(TCL_TCLSH NAMES cygtclsh83 cygtclsh80)
+ENDIF(CYGWIN)
+
+GET_FILENAME_COMPONENT(TK_WISH_PATH "${TK_WISH}" PATH)
+GET_FILENAME_COMPONENT(TK_WISH_PATH_PARENT "${TK_WISH_PATH}" PATH)
+STRING(REGEX REPLACE
+ "^.*wish([0-9]\\.*[0-9]).*$" "\\1" TK_WISH_VERSION "${TK_WISH}")
+
+GET_FILENAME_COMPONENT(TCL_INCLUDE_PATH_PARENT "${TCL_INCLUDE_PATH}" PATH)
+GET_FILENAME_COMPONENT(TK_INCLUDE_PATH_PARENT "${TK_INCLUDE_PATH}" PATH)
+
+GET_FILENAME_COMPONENT(TCL_LIBRARY_PATH "${TCL_LIBRARY}" PATH)
+GET_FILENAME_COMPONENT(TCL_LIBRARY_PATH_PARENT "${TCL_LIBRARY_PATH}" PATH)
+STRING(REGEX REPLACE
+ "^.*tcl([0-9]\\.*[0-9]).*$" "\\1" TCL_LIBRARY_VERSION "${TCL_LIBRARY}")
+
+GET_FILENAME_COMPONENT(TK_LIBRARY_PATH "${TK_LIBRARY}" PATH)
+GET_FILENAME_COMPONENT(TK_LIBRARY_PATH_PARENT "${TK_LIBRARY_PATH}" PATH)
+STRING(REGEX REPLACE
+ "^.*tk([0-9]\\.*[0-9]).*$" "\\1" TK_LIBRARY_VERSION "${TK_LIBRARY}")
+
+SET(TCLTK_POSSIBLE_BIN_PATHS
+ "${TCL_INCLUDE_PATH_PARENT}/bin"
+ "${TK_INCLUDE_PATH_PARENT}/bin"
+ "${TCL_LIBRARY_PATH_PARENT}/bin"
+ "${TK_LIBRARY_PATH_PARENT}/bin"
+ "${TK_WISH_PATH_PARENT}/bin"
+ )
+
+IF(WIN32)
+ GET_FILENAME_COMPONENT(
+ ActiveTcl_CurrentVersion
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\ActiveState\\ActiveTcl;CurrentVersion]"
+ NAME)
+ SET(TCLTK_POSSIBLE_BIN_PATHS ${TCLTK_POSSIBLE_BIN_PATHS}
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\ActiveState\\ActiveTcl\\${ActiveTcl_CurrentVersion}]/bin"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Scriptics\\Tcl\\8.6;Root]/bin"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Scriptics\\Tcl\\8.5;Root]/bin"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Scriptics\\Tcl\\8.4;Root]/bin"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Scriptics\\Tcl\\8.3;Root]/bin"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Scriptics\\Tcl\\8.2;Root]/bin"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Scriptics\\Tcl\\8.0;Root]/bin"
+ )
+ENDIF(WIN32)
+
+SET(TCL_TCLSH_NAMES
+ tclsh
+ tclsh${TCL_LIBRARY_VERSION} tclsh${TK_LIBRARY_VERSION} tclsh${TK_WISH_VERSION}
+ tclsh86 tclsh8.6
+ tclsh85 tclsh8.5
+ tclsh84 tclsh8.4
+ tclsh83 tclsh8.3
+ tclsh82 tclsh8.2
+ tclsh80 tclsh8.0
+ )
+
+FIND_PROGRAM(TCL_TCLSH
+ NAMES ${TCL_TCLSH_NAMES}
+ HINTS ${TCLTK_POSSIBLE_BIN_PATHS}
+ )
+
+IF(TCL_TCLSH)
+ EXECUTE_PROCESS(COMMAND "${CMAKE_COMMAND}" -E echo puts "\$tcl_version"
+ COMMAND "${TCL_TCLSH}"
+ OUTPUT_VARIABLE TCLSH_VERSION_STRING
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ENDIF(TCL_TCLSH)
+
+# handle the QUIETLY and REQUIRED arguments and set TIFF_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Tclsh
+ REQUIRED_VARS TCL_TCLSH
+ VERSION_VAR TCLSH_VERSION_STRING)
+
+MARK_AS_ADVANCED(TCL_TCLSH)
diff --git a/Modules/FindThreads.cmake b/Modules/FindThreads.cmake
new file mode 100644
index 000000000..21614fb66
--- /dev/null
+++ b/Modules/FindThreads.cmake
@@ -0,0 +1,166 @@
+# - 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
+# For systems with multiple thread libraries, caller can set
+# CMAKE_THREAD_PREFER_PTHREAD
+
+#=============================================================================
+# 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.)
+
+INCLUDE (CheckIncludeFiles)
+INCLUDE (CheckLibraryExists)
+INCLUDE (CheckSymbolExists)
+SET(Threads_FOUND FALSE)
+
+# Do we have sproc?
+IF(CMAKE_SYSTEM MATCHES IRIX AND NOT CMAKE_THREAD_PREFER_PTHREAD)
+ CHECK_INCLUDE_FILES("sys/types.h;sys/prctl.h" CMAKE_HAVE_SPROC_H)
+ENDIF()
+
+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_HAVE_PTHREAD_H)
+
+ #
+ # We have pthread.h
+ # Let's check for the library now.
+ #
+ SET(CMAKE_HAVE_THREADS_LIBRARY)
+ IF(NOT THREADS_HAVE_PTHREAD_ARG)
+ # Check if pthread functions are in normal C library
+ CHECK_SYMBOL_EXISTS(pthread_create pthread.h CMAKE_HAVE_LIBC_CREATE)
+ IF(CMAKE_HAVE_LIBC_CREATE)
+ 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()
+ ENDIF(CMAKE_SYSTEM MATCHES "SunOS.*")
+ ENDIF(NOT CMAKE_HAVE_THREADS_LIBRARY)
+ ENDIF(NOT THREADS_HAVE_PTHREAD_ARG)
+
+ 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 MATCHES "^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("THREADS_HAVE_PTHREAD_ARG" MATCHES "^THREADS_HAVE_PTHREAD_ARG")
+
+ IF(THREADS_HAVE_PTHREAD_ARG)
+ SET(Threads_FOUND TRUE)
+ SET(CMAKE_THREAD_LIBS_INIT "-pthread")
+ ENDIF()
+
+ ENDIF(NOT CMAKE_HAVE_THREADS_LIBRARY)
+ ENDIF(CMAKE_HAVE_PTHREAD_H)
+ENDIF()
+
+IF(CMAKE_THREAD_LIBS_INIT OR CMAKE_HAVE_LIBC_CREATE)
+ SET(CMAKE_USE_PTHREADS_INIT 1)
+ SET(Threads_FOUND TRUE)
+ENDIF()
+
+IF(CMAKE_SYSTEM 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-*")
+ # Use libcma if it exists and can be used. It provides more
+ # symbols than the plain pthread library. CMA threads
+ # have actually been deprecated:
+ # http://docs.hp.com/en/B3920-90091/ch12s03.html#d0e11395
+ # http://docs.hp.com/en/947/d8.html
+ # but we need to maintain compatibility here.
+ # The CMAKE_HP_PTHREADS setting actually indicates whether CMA threads
+ # are available.
+ CHECK_LIBRARY_EXISTS(cma pthread_attr_create "" CMAKE_HAVE_HP_CMA)
+ IF(CMAKE_HAVE_HP_CMA)
+ SET(CMAKE_THREAD_LIBS_INIT "-lcma")
+ SET(CMAKE_HP_PTHREADS_INIT 1)
+ SET(Threads_FOUND TRUE)
+ ENDIF(CMAKE_HAVE_HP_CMA)
+ SET(CMAKE_USE_PTHREADS_INIT 1)
+ ENDIF()
+
+ IF(CMAKE_SYSTEM MATCHES "OSF1-V*")
+ SET(CMAKE_USE_PTHREADS_INIT 0)
+ SET(CMAKE_THREAD_LIBS_INIT )
+ ENDIF()
+
+ IF(CMAKE_SYSTEM MATCHES "CYGWIN_NT*")
+ SET(CMAKE_USE_PTHREADS_INIT 1)
+ SET(Threads_FOUND TRUE)
+ SET(CMAKE_THREAD_LIBS_INIT )
+ SET(CMAKE_USE_WIN32_THREADS_INIT 0)
+ ENDIF()
+ENDIF(CMAKE_USE_PTHREADS_INIT)
+
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Threads DEFAULT_MSG Threads_FOUND)
diff --git a/Modules/FindUnixCommands.cmake b/Modules/FindUnixCommands.cmake
new file mode 100644
index 000000000..9c0264d22
--- /dev/null
+++ b/Modules/FindUnixCommands.cmake
@@ -0,0 +1,93 @@
+# - Find unix commands from cygwin
+# This module looks for some usual Unix commands.
+#
+
+#=============================================================================
+# 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.)
+
+INCLUDE(FindCygwin)
+
+FIND_PROGRAM(BASH
+ bash
+ ${CYGWIN_INSTALL_PATH}/bin
+ /bin
+ /usr/bin
+ /usr/local/bin
+ /sbin
+)
+MARK_AS_ADVANCED(
+ BASH
+)
+
+FIND_PROGRAM(CP
+ cp
+ ${CYGWIN_INSTALL_PATH}/bin
+ /bin
+ /usr/bin
+ /usr/local/bin
+ /sbin
+)
+MARK_AS_ADVANCED(
+ CP
+)
+
+FIND_PROGRAM(GZIP
+ gzip
+ ${CYGWIN_INSTALL_PATH}/bin
+ /bin
+ /usr/bin
+ /usr/local/bin
+ /sbin
+)
+MARK_AS_ADVANCED(
+ GZIP
+)
+
+FIND_PROGRAM(MV
+ mv
+ ${CYGWIN_INSTALL_PATH}/bin
+ /bin
+ /usr/bin
+ /usr/local/bin
+ /sbin
+)
+MARK_AS_ADVANCED(
+ MV
+)
+
+FIND_PROGRAM(RM
+ rm
+ ${CYGWIN_INSTALL_PATH}/bin
+ /bin
+ /usr/bin
+ /usr/local/bin
+ /sbin
+)
+MARK_AS_ADVANCED(
+ RM
+)
+
+FIND_PROGRAM(TAR
+ NAMES
+ tar
+ gtar
+ PATH
+ ${CYGWIN_INSTALL_PATH}/bin
+ /bin
+ /usr/bin
+ /usr/local/bin
+ /sbin
+)
+MARK_AS_ADVANCED(
+ TAR
+)
diff --git a/Modules/FindVTK.cmake b/Modules/FindVTK.cmake
new file mode 100644
index 000000000..6b1772fa4
--- /dev/null
+++ b/Modules/FindVTK.cmake
@@ -0,0 +1,141 @@
+# - 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 consitent 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(UseVTKConfig40) # 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(VTK_BINARY_PATH AND USE_BUILT_VTK)
+ IF(VTK_INSTALL_PATH AND USE_INSTALLED_VTK)
+ SET(VTK_DIR_SEARCH_LEGACY ${VTK_DIR_SEARCH_LEGACY}
+ ${VTK_INSTALL_PATH}/lib/vtk)
+ ENDIF(VTK_INSTALL_PATH AND USE_INSTALLED_VTK)
+
+ # 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(UseVTKConfig40) # 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-compatability.
+ SET(USE_VTK_FILE ${VTK_USE_FILE})
+ELSE(VTK_FOUND)
+ # VTK not found, explain to the user how to specify its location.
+ IF(VTK_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR ${VTK_DIR_MESSAGE})
+ ELSE(VTK_FIND_REQUIRED)
+ IF(NOT VTK_FIND_QUIETLY)
+ MESSAGE(STATUS ${VTK_DIR_MESSAGE})
+ ENDIF(NOT VTK_FIND_QUIETLY)
+ ENDIF(VTK_FIND_REQUIRED)
+ENDIF(VTK_FOUND)
diff --git a/Modules/FindWget.cmake b/Modules/FindWget.cmake
new file mode 100644
index 000000000..c94132c27
--- /dev/null
+++ b/Modules/FindWget.cmake
@@ -0,0 +1,36 @@
+# - 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.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software 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(FindCygwin)
+
+FIND_PROGRAM(WGET_EXECUTABLE
+ wget
+ ${CYGWIN_INSTALL_PATH}/bin
+)
+
+# handle the QUIETLY and REQUIRED arguments and set WGET_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Wget DEFAULT_MSG WGET_EXECUTABLE)
+
+MARK_AS_ADVANCED( WGET_EXECUTABLE )
+
+# WGET option is deprecated.
+# use WGET_EXECUTABLE instead.
+SET (WGET ${WGET_EXECUTABLE} )
diff --git a/Modules/FindWish.cmake b/Modules/FindWish.cmake
new file mode 100644
index 000000000..a4960cd17
--- /dev/null
+++ b/Modules/FindWish.cmake
@@ -0,0 +1,85 @@
+# - 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
+#
+# if UNIX is defined, then it will look for the cygwin version first
+
+#=============================================================================
+# 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.)
+
+IF(UNIX)
+ FIND_PROGRAM(TK_WISH cygwish80 )
+ENDIF(UNIX)
+
+GET_FILENAME_COMPONENT(TCL_TCLSH_PATH "${TCL_TCLSH}" PATH)
+GET_FILENAME_COMPONENT(TCL_TCLSH_PATH_PARENT "${TCL_TCLSH_PATH}" PATH)
+STRING(REGEX REPLACE
+ "^.*tclsh([0-9]\\.*[0-9]).*$" "\\1" TCL_TCLSH_VERSION "${TCL_TCLSH}")
+
+GET_FILENAME_COMPONENT(TCL_INCLUDE_PATH_PARENT "${TCL_INCLUDE_PATH}" PATH)
+GET_FILENAME_COMPONENT(TK_INCLUDE_PATH_PARENT "${TK_INCLUDE_PATH}" PATH)
+
+GET_FILENAME_COMPONENT(TCL_LIBRARY_PATH "${TCL_LIBRARY}" PATH)
+GET_FILENAME_COMPONENT(TCL_LIBRARY_PATH_PARENT "${TCL_LIBRARY_PATH}" PATH)
+STRING(REGEX REPLACE
+ "^.*tcl([0-9]\\.*[0-9]).*$" "\\1" TCL_LIBRARY_VERSION "${TCL_LIBRARY}")
+
+GET_FILENAME_COMPONENT(TK_LIBRARY_PATH "${TK_LIBRARY}" PATH)
+GET_FILENAME_COMPONENT(TK_LIBRARY_PATH_PARENT "${TK_LIBRARY_PATH}" PATH)
+STRING(REGEX REPLACE
+ "^.*tk([0-9]\\.*[0-9]).*$" "\\1" TK_LIBRARY_VERSION "${TK_LIBRARY}")
+
+SET(TCLTK_POSSIBLE_BIN_PATHS
+ "${TCL_INCLUDE_PATH_PARENT}/bin"
+ "${TK_INCLUDE_PATH_PARENT}/bin"
+ "${TCL_LIBRARY_PATH_PARENT}/bin"
+ "${TK_LIBRARY_PATH_PARENT}/bin"
+ "${TCL_TCLSH_PATH_PARENT}/bin"
+ )
+
+IF(WIN32)
+ GET_FILENAME_COMPONENT(
+ ActiveTcl_CurrentVersion
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\ActiveState\\ActiveTcl;CurrentVersion]"
+ NAME)
+ SET(TCLTK_POSSIBLE_BIN_PATHS ${TCLTK_POSSIBLE_BIN_PATHS}
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\ActiveState\\ActiveTcl\\${ActiveTcl_CurrentVersion}]/bin"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Scriptics\\Tcl\\8.6;Root]/bin"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Scriptics\\Tcl\\8.5;Root]/bin"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Scriptics\\Tcl\\8.4;Root]/bin"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Scriptics\\Tcl\\8.3;Root]/bin"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Scriptics\\Tcl\\8.2;Root]/bin"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Scriptics\\Tcl\\8.0;Root]/bin"
+ )
+ENDIF(WIN32)
+
+SET(TK_WISH_NAMES
+ wish
+ wish${TCL_LIBRARY_VERSION} wish${TK_LIBRARY_VERSION} wish${TCL_TCLSH_VERSION}
+ wish86 wish8.6
+ wish85 wish8.5
+ wish84 wish8.4
+ wish83 wish8.3
+ wish82 wish8.2
+ wish80 wish8.0
+ )
+
+FIND_PROGRAM(TK_WISH
+ NAMES ${TK_WISH_NAMES}
+ HINTS ${TCLTK_POSSIBLE_BIN_PATHS}
+ )
+
+MARK_AS_ADVANCED(TK_WISH)
diff --git a/Modules/FindX11.cmake b/Modules/FindX11.cmake
new file mode 100644
index 000000000..76fb3c911
--- /dev/null
+++ b/Modules/FindX11.cmake
@@ -0,0 +1,492 @@
+# - 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
+#
+# 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
+
+
+#=============================================================================
+# 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.)
+
+IF (UNIX)
+ SET(X11_FOUND 0)
+ # X11 is never a framework and some header files may be
+ # found in tcl on the mac
+ SET(CMAKE_FIND_FRAMEWORK_SAVE ${CMAKE_FIND_FRAMEWORK})
+ SET(CMAKE_FIND_FRAMEWORK NEVER)
+ SET(X11_INC_SEARCH_PATH
+ /usr/pkg/xorg/include
+ /usr/X11R6/include
+ /usr/X11R7/include
+ /usr/include/X11
+ /usr/openwin/include
+ /usr/openwin/share/include
+ /opt/graphics/OpenGL/include
+ )
+
+ SET(X11_LIB_SEARCH_PATH
+ /usr/pkg/xorg/lib
+ /usr/X11R6/lib
+ /usr/X11R7/lib
+ /usr/openwin/lib
+ )
+
+ FIND_PATH(X11_X11_INCLUDE_PATH X11/X.h ${X11_INC_SEARCH_PATH})
+ FIND_PATH(X11_Xlib_INCLUDE_PATH X11/Xlib.h ${X11_INC_SEARCH_PATH})
+
+ # Look for includes; keep the list sorted by name of the cmake *_INCLUDE_PATH
+ # variable (which doesn't need to match the include file name).
+
+ # Solaris lacks XKBrules.h, so we should skip kxkbd there.
+ FIND_PATH(X11_ICE_INCLUDE_PATH X11/ICE/ICE.h ${X11_INC_SEARCH_PATH})
+ FIND_PATH(X11_SM_INCLUDE_PATH X11/SM/SM.h ${X11_INC_SEARCH_PATH})
+ FIND_PATH(X11_Xaccessrules_INCLUDE_PATH X11/extensions/XKBrules.h ${X11_INC_SEARCH_PATH})
+ FIND_PATH(X11_Xaccessstr_INCLUDE_PATH X11/extensions/XKBstr.h ${X11_INC_SEARCH_PATH})
+ FIND_PATH(X11_Xau_INCLUDE_PATH X11/Xauth.h ${X11_INC_SEARCH_PATH})
+ FIND_PATH(X11_Xcomposite_INCLUDE_PATH X11/extensions/Xcomposite.h ${X11_INC_SEARCH_PATH})
+ FIND_PATH(X11_Xcursor_INCLUDE_PATH X11/Xcursor/Xcursor.h ${X11_INC_SEARCH_PATH})
+ FIND_PATH(X11_Xdamage_INCLUDE_PATH X11/extensions/Xdamage.h ${X11_INC_SEARCH_PATH})
+ FIND_PATH(X11_Xdmcp_INCLUDE_PATH X11/Xdmcp.h ${X11_INC_SEARCH_PATH})
+ FIND_PATH(X11_dpms_INCLUDE_PATH X11/extensions/dpms.h ${X11_INC_SEARCH_PATH})
+ FIND_PATH(X11_xf86misc_INCLUDE_PATH X11/extensions/xf86misc.h ${X11_INC_SEARCH_PATH})
+ FIND_PATH(X11_xf86vmode_INCLUDE_PATH X11/extensions/xf86vmode.h ${X11_INC_SEARCH_PATH})
+ FIND_PATH(X11_Xfixes_INCLUDE_PATH X11/extensions/Xfixes.h ${X11_INC_SEARCH_PATH})
+ FIND_PATH(X11_Xft_INCLUDE_PATH X11/Xft/Xft.h ${X11_INC_SEARCH_PATH})
+ FIND_PATH(X11_Xi_INCLUDE_PATH X11/extensions/XInput.h ${X11_INC_SEARCH_PATH})
+ FIND_PATH(X11_Xinerama_INCLUDE_PATH X11/extensions/Xinerama.h ${X11_INC_SEARCH_PATH})
+ FIND_PATH(X11_Xinput_INCLUDE_PATH X11/extensions/XInput.h ${X11_INC_SEARCH_PATH})
+ FIND_PATH(X11_Xkb_INCLUDE_PATH X11/extensions/XKB.h ${X11_INC_SEARCH_PATH})
+ FIND_PATH(X11_Xkblib_INCLUDE_PATH X11/XKBlib.h ${X11_INC_SEARCH_PATH})
+ FIND_PATH(X11_Xkbfile_INCLUDE_PATH X11/extensions/XKBfile.h ${X11_INC_SEARCH_PATH})
+ FIND_PATH(X11_Xmu_INCLUDE_PATH X11/Xmu/Xmu.h ${X11_INC_SEARCH_PATH})
+ FIND_PATH(X11_Xpm_INCLUDE_PATH X11/xpm.h ${X11_INC_SEARCH_PATH})
+ FIND_PATH(X11_XTest_INCLUDE_PATH X11/extensions/XTest.h ${X11_INC_SEARCH_PATH})
+ FIND_PATH(X11_XShm_INCLUDE_PATH X11/extensions/XShm.h ${X11_INC_SEARCH_PATH})
+ FIND_PATH(X11_Xrandr_INCLUDE_PATH X11/extensions/Xrandr.h ${X11_INC_SEARCH_PATH})
+ FIND_PATH(X11_Xrender_INCLUDE_PATH X11/extensions/Xrender.h ${X11_INC_SEARCH_PATH})
+ FIND_PATH(X11_XRes_INCLUDE_PATH X11/extensions/XRes.h ${X11_INC_SEARCH_PATH})
+ FIND_PATH(X11_Xscreensaver_INCLUDE_PATH X11/extensions/scrnsaver.h ${X11_INC_SEARCH_PATH})
+ FIND_PATH(X11_Xshape_INCLUDE_PATH X11/extensions/shape.h ${X11_INC_SEARCH_PATH})
+ FIND_PATH(X11_Xutil_INCLUDE_PATH X11/Xutil.h ${X11_INC_SEARCH_PATH})
+ FIND_PATH(X11_Xt_INCLUDE_PATH X11/Intrinsic.h ${X11_INC_SEARCH_PATH})
+ FIND_PATH(X11_Xv_INCLUDE_PATH X11/extensions/Xvlib.h ${X11_INC_SEARCH_PATH})
+ FIND_PATH(X11_XSync_INCLUDE_PATH X11/extensions/sync.h ${X11_INC_SEARCH_PATH})
+
+
+ FIND_LIBRARY(X11_X11_LIB X11 ${X11_LIB_SEARCH_PATH})
+
+ # Find additional X libraries. Keep list sorted by library name.
+ FIND_LIBRARY(X11_ICE_LIB ICE ${X11_LIB_SEARCH_PATH})
+ FIND_LIBRARY(X11_SM_LIB SM ${X11_LIB_SEARCH_PATH})
+ FIND_LIBRARY(X11_Xau_LIB Xau ${X11_LIB_SEARCH_PATH})
+ FIND_LIBRARY(X11_Xcomposite_LIB Xcomposite ${X11_LIB_SEARCH_PATH})
+ FIND_LIBRARY(X11_Xcursor_LIB Xcursor ${X11_LIB_SEARCH_PATH})
+ FIND_LIBRARY(X11_Xdamage_LIB Xdamage ${X11_LIB_SEARCH_PATH})
+ FIND_LIBRARY(X11_Xdmcp_LIB Xdmcp ${X11_LIB_SEARCH_PATH})
+ FIND_LIBRARY(X11_Xext_LIB Xext ${X11_LIB_SEARCH_PATH})
+ FIND_LIBRARY(X11_Xfixes_LIB Xfixes ${X11_LIB_SEARCH_PATH})
+ FIND_LIBRARY(X11_Xft_LIB Xft ${X11_LIB_SEARCH_PATH})
+ FIND_LIBRARY(X11_Xi_LIB Xi ${X11_LIB_SEARCH_PATH})
+ FIND_LIBRARY(X11_Xinerama_LIB Xinerama ${X11_LIB_SEARCH_PATH})
+ FIND_LIBRARY(X11_Xinput_LIB Xi ${X11_LIB_SEARCH_PATH})
+ FIND_LIBRARY(X11_Xkbfile_LIB xkbfile ${X11_LIB_SEARCH_PATH})
+ FIND_LIBRARY(X11_Xmu_LIB Xmu ${X11_LIB_SEARCH_PATH})
+ FIND_LIBRARY(X11_Xpm_LIB Xpm ${X11_LIB_SEARCH_PATH})
+ FIND_LIBRARY(X11_Xrandr_LIB Xrandr ${X11_LIB_SEARCH_PATH})
+ FIND_LIBRARY(X11_Xrender_LIB Xrender ${X11_LIB_SEARCH_PATH})
+ FIND_LIBRARY(X11_XRes_LIB XRes ${X11_LIB_SEARCH_PATH})
+ FIND_LIBRARY(X11_Xscreensaver_LIB Xss ${X11_LIB_SEARCH_PATH})
+ FIND_LIBRARY(X11_Xt_LIB Xt ${X11_LIB_SEARCH_PATH})
+ FIND_LIBRARY(X11_XTest_LIB Xtst ${X11_LIB_SEARCH_PATH})
+ FIND_LIBRARY(X11_Xv_LIB Xv ${X11_LIB_SEARCH_PATH})
+ FIND_LIBRARY(X11_Xxf86misc_LIB Xxf86misc ${X11_LIB_SEARCH_PATH})
+ FIND_LIBRARY(X11_Xxf86vm_LIB Xxf86vm ${X11_LIB_SEARCH_PATH})
+
+ SET(X11_LIBRARY_DIR "")
+ IF(X11_X11_LIB)
+ GET_FILENAME_COMPONENT(X11_LIBRARY_DIR ${X11_X11_LIB} PATH)
+ ENDIF(X11_X11_LIB)
+
+ SET(X11_INCLUDE_DIR) # start with empty list
+ IF(X11_X11_INCLUDE_PATH)
+ SET(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_X11_INCLUDE_PATH})
+ ENDIF(X11_X11_INCLUDE_PATH)
+
+ IF(X11_Xlib_INCLUDE_PATH)
+ SET(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xlib_INCLUDE_PATH})
+ ENDIF(X11_Xlib_INCLUDE_PATH)
+
+ IF(X11_Xutil_INCLUDE_PATH)
+ SET(X11_Xutil_FOUND TRUE)
+ SET(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xutil_INCLUDE_PATH})
+ ENDIF(X11_Xutil_INCLUDE_PATH)
+
+ IF(X11_Xshape_INCLUDE_PATH)
+ SET(X11_Xshape_FOUND TRUE)
+ SET(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xshape_INCLUDE_PATH})
+ ENDIF(X11_Xshape_INCLUDE_PATH)
+
+ SET(X11_LIBRARIES) # start with empty list
+ IF(X11_X11_LIB)
+ SET(X11_LIBRARIES ${X11_LIBRARIES} ${X11_X11_LIB})
+ ENDIF(X11_X11_LIB)
+
+ IF(X11_Xext_LIB)
+ SET(X11_Xext_FOUND TRUE)
+ SET(X11_LIBRARIES ${X11_LIBRARIES} ${X11_Xext_LIB})
+ ENDIF(X11_Xext_LIB)
+
+ IF(X11_Xt_LIB AND X11_Xt_INCLUDE_PATH)
+ SET(X11_Xt_FOUND TRUE)
+ ENDIF(X11_Xt_LIB AND X11_Xt_INCLUDE_PATH)
+
+ IF(X11_Xft_LIB AND X11_Xft_INCLUDE_PATH)
+ SET(X11_Xft_FOUND TRUE)
+ SET(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xft_INCLUDE_PATH})
+ ENDIF(X11_Xft_LIB AND X11_Xft_INCLUDE_PATH)
+
+ IF(X11_Xv_LIB AND X11_Xv_INCLUDE_PATH)
+ SET(X11_Xv_FOUND TRUE)
+ SET(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xv_INCLUDE_PATH})
+ ENDIF(X11_Xv_LIB AND X11_Xv_INCLUDE_PATH)
+
+ IF (X11_Xau_LIB AND X11_Xau_INCLUDE_PATH)
+ SET(X11_Xau_FOUND TRUE)
+ ENDIF (X11_Xau_LIB AND X11_Xau_INCLUDE_PATH)
+
+ IF (X11_Xdmcp_INCLUDE_PATH AND X11_Xdmcp_LIB)
+ SET(X11_Xdmcp_FOUND TRUE)
+ SET(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xdmcp_INCLUDE_PATH})
+ ENDIF (X11_Xdmcp_INCLUDE_PATH AND X11_Xdmcp_LIB)
+
+ IF (X11_Xaccessrules_INCLUDE_PATH AND X11_Xaccessstr_INCLUDE_PATH)
+ SET(X11_Xaccess_FOUND TRUE)
+ SET(X11_Xaccess_INCLUDE_PATH ${X11_Xaccessstr_INCLUDE_PATH})
+ SET(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xaccess_INCLUDE_PATH})
+ ENDIF (X11_Xaccessrules_INCLUDE_PATH AND X11_Xaccessstr_INCLUDE_PATH)
+
+ IF (X11_Xpm_INCLUDE_PATH AND X11_Xpm_LIB)
+ SET(X11_Xpm_FOUND TRUE)
+ SET(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xpm_INCLUDE_PATH})
+ ENDIF (X11_Xpm_INCLUDE_PATH AND X11_Xpm_LIB)
+
+ IF (X11_Xcomposite_INCLUDE_PATH AND X11_Xcomposite_LIB)
+ SET(X11_Xcomposite_FOUND TRUE)
+ SET(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xcomposite_INCLUDE_PATH})
+ ENDIF (X11_Xcomposite_INCLUDE_PATH AND X11_Xcomposite_LIB)
+
+ IF (X11_Xdamage_INCLUDE_PATH AND X11_Xdamage_LIB)
+ SET(X11_Xdamage_FOUND TRUE)
+ SET(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xdamage_INCLUDE_PATH})
+ ENDIF (X11_Xdamage_INCLUDE_PATH AND X11_Xdamage_LIB)
+
+ IF (X11_XShm_INCLUDE_PATH)
+ SET(X11_XShm_FOUND TRUE)
+ SET(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_XShm_INCLUDE_PATH})
+ ENDIF (X11_XShm_INCLUDE_PATH)
+
+ IF (X11_XTest_INCLUDE_PATH AND X11_XTest_LIB)
+ SET(X11_XTest_FOUND TRUE)
+ SET(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_XTest_INCLUDE_PATH})
+ ENDIF (X11_XTest_INCLUDE_PATH AND X11_XTest_LIB)
+
+ IF (X11_Xi_INCLUDE_PATH AND X11_Xi_LIB)
+ SET(X11_Xi_FOUND TRUE)
+ SET(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xi_INCLUDE_PATH})
+ ENDIF (X11_Xi_INCLUDE_PATH AND X11_Xi_LIB)
+
+ IF (X11_Xinerama_INCLUDE_PATH AND X11_Xinerama_LIB)
+ SET(X11_Xinerama_FOUND TRUE)
+ SET(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xinerama_INCLUDE_PATH})
+ ENDIF (X11_Xinerama_INCLUDE_PATH AND X11_Xinerama_LIB)
+
+ IF (X11_Xfixes_INCLUDE_PATH AND X11_Xfixes_LIB)
+ SET(X11_Xfixes_FOUND TRUE)
+ SET(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xfixes_INCLUDE_PATH})
+ ENDIF (X11_Xfixes_INCLUDE_PATH AND X11_Xfixes_LIB)
+
+ IF (X11_Xrender_INCLUDE_PATH AND X11_Xrender_LIB)
+ SET(X11_Xrender_FOUND TRUE)
+ SET(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xrender_INCLUDE_PATH})
+ ENDIF (X11_Xrender_INCLUDE_PATH AND X11_Xrender_LIB)
+
+ IF (X11_XRes_INCLUDE_PATH AND X11_XRes_LIB)
+ SET(X11_XRes_FOUND TRUE)
+ SET(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_XRes_INCLUDE_PATH})
+ ENDIF (X11_XRes_INCLUDE_PATH AND X11_XRes_LIB)
+
+ IF (X11_Xrandr_INCLUDE_PATH AND X11_Xrandr_LIB)
+ SET(X11_Xrandr_FOUND TRUE)
+ SET(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xrandr_INCLUDE_PATH})
+ ENDIF (X11_Xrandr_INCLUDE_PATH AND X11_Xrandr_LIB)
+
+ IF (X11_xf86misc_INCLUDE_PATH AND X11_Xxf86misc_LIB)
+ SET(X11_xf86misc_FOUND TRUE)
+ SET(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_xf86misc_INCLUDE_PATH})
+ ENDIF (X11_xf86misc_INCLUDE_PATH AND X11_Xxf86misc_LIB)
+
+ IF (X11_xf86vmode_INCLUDE_PATH AND X11_Xxf86vm_LIB)
+ SET(X11_xf86vmode_FOUND TRUE)
+ SET(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_xf86vmode_INCLUDE_PATH})
+ ENDIF (X11_xf86vmode_INCLUDE_PATH AND X11_Xxf86vm_LIB)
+
+ IF (X11_Xcursor_INCLUDE_PATH AND X11_Xcursor_LIB)
+ SET(X11_Xcursor_FOUND TRUE)
+ SET(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xcursor_INCLUDE_PATH})
+ ENDIF (X11_Xcursor_INCLUDE_PATH AND X11_Xcursor_LIB)
+
+ IF (X11_Xscreensaver_INCLUDE_PATH AND X11_Xscreensaver_LIB)
+ SET(X11_Xscreensaver_FOUND TRUE)
+ SET(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xscreensaver_INCLUDE_PATH})
+ ENDIF (X11_Xscreensaver_INCLUDE_PATH AND X11_Xscreensaver_LIB)
+
+ IF (X11_dpms_INCLUDE_PATH)
+ SET(X11_dpms_FOUND TRUE)
+ SET(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_dpms_INCLUDE_PATH})
+ ENDIF (X11_dpms_INCLUDE_PATH)
+
+ IF (X11_Xkb_INCLUDE_PATH AND X11_Xkblib_INCLUDE_PATH AND X11_Xlib_INCLUDE_PATH)
+ SET(X11_Xkb_FOUND TRUE)
+ SET(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xkb_INCLUDE_PATH} )
+ ENDIF (X11_Xkb_INCLUDE_PATH AND X11_Xkblib_INCLUDE_PATH AND X11_Xlib_INCLUDE_PATH)
+
+ IF (X11_Xkbfile_INCLUDE_PATH AND X11_Xkbfile_LIB AND X11_Xlib_INCLUDE_PATH)
+ SET(X11_Xkbfile_FOUND TRUE)
+ SET(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xkbfile_INCLUDE_PATH} )
+ ENDIF (X11_Xkbfile_INCLUDE_PATH AND X11_Xkbfile_LIB AND X11_Xlib_INCLUDE_PATH)
+
+ IF (X11_Xmu_INCLUDE_PATH AND X11_Xmu_LIB)
+ SET(X11_Xmu_FOUND TRUE)
+ SET(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xmu_INCLUDE_PATH})
+ ENDIF (X11_Xmu_INCLUDE_PATH AND X11_Xmu_LIB)
+
+ IF (X11_Xinput_INCLUDE_PATH AND X11_Xinput_LIB)
+ SET(X11_Xinput_FOUND TRUE)
+ SET(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xinput_INCLUDE_PATH})
+ ENDIF (X11_Xinput_INCLUDE_PATH AND X11_Xinput_LIB)
+
+ IF (X11_XSync_INCLUDE_PATH)
+ SET(X11_XSync_FOUND TRUE)
+ SET(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_XSync_INCLUDE_PATH})
+ ENDIF (X11_XSync_INCLUDE_PATH)
+
+ IF(X11_ICE_LIB AND X11_ICE_INCLUDE_PATH)
+ SET(X11_ICE_FOUND TRUE)
+ ENDIF(X11_ICE_LIB AND X11_ICE_INCLUDE_PATH)
+
+ IF(X11_SM_LIB AND X11_SM_INCLUDE_PATH)
+ SET(X11_SM_FOUND TRUE)
+ ENDIF(X11_SM_LIB AND X11_SM_INCLUDE_PATH)
+
+
+ # Deprecated variable for backwards compatibility with CMake 1.4
+ IF (X11_X11_INCLUDE_PATH AND X11_LIBRARIES)
+ SET(X11_FOUND 1)
+ ENDIF (X11_X11_INCLUDE_PATH AND X11_LIBRARIES)
+
+ IF(X11_FOUND)
+ INCLUDE(CheckFunctionExists)
+ INCLUDE(CheckLibraryExists)
+
+ # Translated from an autoconf-generated configure script.
+ # See libs.m4 in autoconf's m4 directory.
+ IF($ENV{ISC} MATCHES "^yes$")
+ SET(X11_X_EXTRA_LIBS -lnsl_s -linet)
+ ELSE($ENV{ISC} MATCHES "^yes$")
+ SET(X11_X_EXTRA_LIBS "")
+
+ # See if XOpenDisplay in X11 works by itself.
+ CHECK_LIBRARY_EXISTS("${X11_LIBRARIES}" "XOpenDisplay" "${X11_LIBRARY_DIR}" X11_LIB_X11_SOLO)
+ IF(NOT X11_LIB_X11_SOLO)
+ # Find library needed for dnet_ntoa.
+ CHECK_LIBRARY_EXISTS("dnet" "dnet_ntoa" "" X11_LIB_DNET_HAS_DNET_NTOA)
+ IF (X11_LIB_DNET_HAS_DNET_NTOA)
+ SET (X11_X_EXTRA_LIBS ${X11_X_EXTRA_LIBS} -ldnet)
+ ELSE (X11_LIB_DNET_HAS_DNET_NTOA)
+ CHECK_LIBRARY_EXISTS("dnet_stub" "dnet_ntoa" "" X11_LIB_DNET_STUB_HAS_DNET_NTOA)
+ IF (X11_LIB_DNET_STUB_HAS_DNET_NTOA)
+ SET (X11_X_EXTRA_LIBS ${X11_X_EXTRA_LIBS} -ldnet_stub)
+ ENDIF (X11_LIB_DNET_STUB_HAS_DNET_NTOA)
+ ENDIF (X11_LIB_DNET_HAS_DNET_NTOA)
+ ENDIF(NOT X11_LIB_X11_SOLO)
+
+ # Find library needed for gethostbyname.
+ CHECK_FUNCTION_EXISTS("gethostbyname" CMAKE_HAVE_GETHOSTBYNAME)
+ IF(NOT CMAKE_HAVE_GETHOSTBYNAME)
+ CHECK_LIBRARY_EXISTS("nsl" "gethostbyname" "" CMAKE_LIB_NSL_HAS_GETHOSTBYNAME)
+ IF (CMAKE_LIB_NSL_HAS_GETHOSTBYNAME)
+ SET (X11_X_EXTRA_LIBS ${X11_X_EXTRA_LIBS} -lnsl)
+ ELSE (CMAKE_LIB_NSL_HAS_GETHOSTBYNAME)
+ CHECK_LIBRARY_EXISTS("bsd" "gethostbyname" "" CMAKE_LIB_BSD_HAS_GETHOSTBYNAME)
+ IF (CMAKE_LIB_BSD_HAS_GETHOSTBYNAME)
+ SET (X11_X_EXTRA_LIBS ${X11_X_EXTRA_LIBS} -lbsd)
+ ENDIF (CMAKE_LIB_BSD_HAS_GETHOSTBYNAME)
+ ENDIF (CMAKE_LIB_NSL_HAS_GETHOSTBYNAME)
+ ENDIF(NOT CMAKE_HAVE_GETHOSTBYNAME)
+
+ # Find library needed for connect.
+ CHECK_FUNCTION_EXISTS("connect" CMAKE_HAVE_CONNECT)
+ IF(NOT CMAKE_HAVE_CONNECT)
+ CHECK_LIBRARY_EXISTS("socket" "connect" "" CMAKE_LIB_SOCKET_HAS_CONNECT)
+ IF (CMAKE_LIB_SOCKET_HAS_CONNECT)
+ SET (X11_X_EXTRA_LIBS -lsocket ${X11_X_EXTRA_LIBS})
+ ENDIF (CMAKE_LIB_SOCKET_HAS_CONNECT)
+ ENDIF(NOT CMAKE_HAVE_CONNECT)
+
+ # Find library needed for remove.
+ CHECK_FUNCTION_EXISTS("remove" CMAKE_HAVE_REMOVE)
+ IF(NOT CMAKE_HAVE_REMOVE)
+ CHECK_LIBRARY_EXISTS("posix" "remove" "" CMAKE_LIB_POSIX_HAS_REMOVE)
+ IF (CMAKE_LIB_POSIX_HAS_REMOVE)
+ SET (X11_X_EXTRA_LIBS ${X11_X_EXTRA_LIBS} -lposix)
+ ENDIF (CMAKE_LIB_POSIX_HAS_REMOVE)
+ ENDIF(NOT CMAKE_HAVE_REMOVE)
+
+ # Find library needed for shmat.
+ CHECK_FUNCTION_EXISTS("shmat" CMAKE_HAVE_SHMAT)
+ IF(NOT CMAKE_HAVE_SHMAT)
+ CHECK_LIBRARY_EXISTS("ipc" "shmat" "" CMAKE_LIB_IPS_HAS_SHMAT)
+ IF (CMAKE_LIB_IPS_HAS_SHMAT)
+ SET (X11_X_EXTRA_LIBS ${X11_X_EXTRA_LIBS} -lipc)
+ ENDIF (CMAKE_LIB_IPS_HAS_SHMAT)
+ ENDIF(NOT CMAKE_HAVE_SHMAT)
+ ENDIF($ENV{ISC} MATCHES "^yes$")
+
+ IF (X11_ICE_FOUND)
+ CHECK_LIBRARY_EXISTS("ICE" "IceConnectionNumber" "${X11_LIBRARY_DIR}"
+ CMAKE_LIB_ICE_HAS_ICECONNECTIONNUMBER)
+ IF(CMAKE_LIB_ICE_HAS_ICECONNECTIONNUMBER)
+ SET (X11_X_PRE_LIBS ${X11_ICE_LIB})
+ IF(X11_SM_LIB)
+ SET (X11_X_PRE_LIBS ${X11_SM_LIB} ${X11_X_PRE_LIBS})
+ ENDIF(X11_SM_LIB)
+ ENDIF(CMAKE_LIB_ICE_HAS_ICECONNECTIONNUMBER)
+ ENDIF (X11_ICE_FOUND)
+
+ # Build the final list of libraries.
+ SET(X11_LIBRARIES ${X11_X_PRE_LIBS} ${X11_LIBRARIES} ${X11_X_EXTRA_LIBS})
+
+ INCLUDE(FindPackageMessage)
+ FIND_PACKAGE_MESSAGE(X11 "Found X11: ${X11_X11_LIB}"
+ "[${X11_X11_LIB}][${X11_INCLUDE_DIR}]")
+ ELSE (X11_FOUND)
+ IF (X11_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR "Could not find X11")
+ ENDIF (X11_FIND_REQUIRED)
+ ENDIF (X11_FOUND)
+
+ MARK_AS_ADVANCED(
+ X11_X11_INCLUDE_PATH
+ X11_X11_LIB
+ X11_Xext_LIB
+ X11_Xau_LIB
+ X11_Xau_INCLUDE_PATH
+ X11_Xlib_INCLUDE_PATH
+ X11_Xutil_INCLUDE_PATH
+ X11_Xcomposite_INCLUDE_PATH
+ X11_Xcomposite_LIB
+ X11_Xaccess_INCLUDE_PATH
+ X11_Xfixes_LIB
+ X11_Xfixes_INCLUDE_PATH
+ X11_Xrandr_LIB
+ X11_Xrandr_INCLUDE_PATH
+ X11_Xdamage_LIB
+ X11_Xdamage_INCLUDE_PATH
+ X11_Xrender_LIB
+ X11_Xrender_INCLUDE_PATH
+ X11_XRes_LIB
+ X11_XRes_INCLUDE_PATH
+ X11_Xxf86misc_LIB
+ X11_xf86misc_INCLUDE_PATH
+ X11_Xxf86vm_LIB
+ X11_xf86vmode_INCLUDE_PATH
+ X11_Xi_LIB
+ X11_Xi_INCLUDE_PATH
+ X11_Xinerama_LIB
+ X11_Xinerama_INCLUDE_PATH
+ X11_XTest_LIB
+ X11_XTest_INCLUDE_PATH
+ X11_Xcursor_LIB
+ X11_Xcursor_INCLUDE_PATH
+ X11_dpms_INCLUDE_PATH
+ X11_Xt_LIB
+ X11_Xt_INCLUDE_PATH
+ X11_Xdmcp_LIB
+ X11_LIBRARIES
+ X11_Xaccessrules_INCLUDE_PATH
+ X11_Xaccessstr_INCLUDE_PATH
+ X11_Xdmcp_INCLUDE_PATH
+ X11_Xkb_INCLUDE_PATH
+ X11_Xkblib_INCLUDE_PATH
+ X11_Xkbfile_INCLUDE_PATH
+ X11_Xkbfile_LIB
+ X11_Xmu_INCLUDE_PATH
+ X11_Xmu_LIB
+ X11_Xscreensaver_INCLUDE_PATH
+ X11_Xscreensaver_LIB
+ X11_Xpm_INCLUDE_PATH
+ X11_Xpm_LIB
+ X11_Xinput_LIB
+ X11_Xinput_INCLUDE_PATH
+ X11_Xft_LIB
+ X11_Xft_INCLUDE_PATH
+ X11_Xshape_INCLUDE_PATH
+ X11_Xv_LIB
+ X11_Xv_INCLUDE_PATH
+ X11_XShm_INCLUDE_PATH
+ X11_ICE_LIB
+ X11_ICE_INCLUDE_PATH
+ X11_SM_LIB
+ X11_SM_INCLUDE_PATH
+ X11_XSync_INCLUDE_PATH
+ )
+ SET(CMAKE_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK_SAVE})
+ENDIF (UNIX)
+
+# X11_FIND_REQUIRED_<component> could be checked too
diff --git a/Modules/FindXMLRPC.cmake b/Modules/FindXMLRPC.cmake
new file mode 100644
index 000000000..eccfb487a
--- /dev/null
+++ b/Modules/FindXMLRPC.cmake
@@ -0,0 +1,146 @@
+# - 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 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
+# Typical usage:
+# FIND_PACKAGE(XMLRPC REQUIRED libwww-client)
+
+#=============================================================================
+# 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.)
+
+# First find the config script from which to obtain other values.
+FIND_PROGRAM(XMLRPC_C_CONFIG NAMES xmlrpc-c-config)
+
+# Check whether we found anything.
+IF(XMLRPC_C_CONFIG)
+ SET(XMLRPC_FOUND 1)
+ELSE(XMLRPC_C_CONFIG)
+ SET(XMLRPC_FOUND 0)
+ENDIF(XMLRPC_C_CONFIG)
+
+# Lookup the include directories needed for the components requested.
+IF(XMLRPC_FOUND)
+ # Use the newer EXECUTE_PROCESS command if it is available.
+ IF(COMMAND EXECUTE_PROCESS)
+ EXECUTE_PROCESS(
+ COMMAND ${XMLRPC_C_CONFIG} ${XMLRPC_FIND_COMPONENTS} --cflags
+ OUTPUT_VARIABLE XMLRPC_C_CONFIG_CFLAGS
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ RESULT_VARIABLE XMLRPC_C_CONFIG_RESULT
+ )
+ ELSE(COMMAND EXECUTE_PROCESS)
+ EXEC_PROGRAM(${XMLRPC_C_CONFIG} ARGS "${XMLRPC_FIND_COMPONENTS} --cflags"
+ OUTPUT_VARIABLE XMLRPC_C_CONFIG_CFLAGS
+ RETURN_VALUE XMLRPC_C_CONFIG_RESULT
+ )
+ ENDIF(COMMAND EXECUTE_PROCESS)
+
+ # Parse the include flags.
+ IF("${XMLRPC_C_CONFIG_RESULT}" MATCHES "^0$")
+ # Convert the compile flags to a CMake list.
+ STRING(REGEX REPLACE " +" ";"
+ XMLRPC_C_CONFIG_CFLAGS "${XMLRPC_C_CONFIG_CFLAGS}")
+
+ # 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}")
+ ENDIF("${flag}" MATCHES "^-I")
+ ENDFOREACH(flag)
+ ELSE("${XMLRPC_C_CONFIG_RESULT}" MATCHES "^0$")
+ MESSAGE("Error running ${XMLRPC_C_CONFIG}: [${XMLRPC_C_CONFIG_RESULT}]")
+ SET(XMLRPC_FOUND 0)
+ ENDIF("${XMLRPC_C_CONFIG_RESULT}" MATCHES "^0$")
+ENDIF(XMLRPC_FOUND)
+
+# Lookup the libraries needed for the components requested.
+IF(XMLRPC_FOUND)
+ # Use the newer EXECUTE_PROCESS command if it is available.
+ IF(COMMAND EXECUTE_PROCESS)
+ EXECUTE_PROCESS(
+ COMMAND ${XMLRPC_C_CONFIG} ${XMLRPC_FIND_COMPONENTS} --libs
+ OUTPUT_VARIABLE XMLRPC_C_CONFIG_LIBS
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ RESULT_VARIABLE XMLRPC_C_CONFIG_RESULT
+ )
+ ELSE(COMMAND EXECUTE_PROCESS)
+ EXEC_PROGRAM(${XMLRPC_C_CONFIG} ARGS "${XMLRPC_FIND_COMPONENTS} --libs"
+ OUTPUT_VARIABLE XMLRPC_C_CONFIG_LIBS
+ RETURN_VALUE XMLRPC_C_CONFIG_RESULT
+ )
+ ENDIF(COMMAND EXECUTE_PROCESS)
+
+ # Parse the library names and directories.
+ IF("${XMLRPC_C_CONFIG_RESULT}" MATCHES "^0$")
+ STRING(REGEX REPLACE " +" ";"
+ XMLRPC_C_CONFIG_LIBS "${XMLRPC_C_CONFIG_LIBS}")
+
+ # Look for -L flags for directories and -l flags for library names.
+ 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}")
+ ENDIF("${flag}" MATCHES "^-L")
+ ENDFOREACH(flag)
+
+ # Search for each library needed using the directories given.
+ FOREACH(name ${XMLRPC_LIBRARY_NAMES})
+ # Look for this library.
+ FIND_LIBRARY(XMLRPC_${name}_LIBRARY
+ NAMES ${name}
+ HINTS ${XMLRPC_LIBRARY_DIRS}
+ )
+ MARK_AS_ADVANCED(XMLRPC_${name}_LIBRARY)
+
+ # If any library is not found then the whole package is not found.
+ IF(NOT XMLRPC_${name}_LIBRARY)
+ SET(XMLRPC_FOUND 0)
+ ENDIF(NOT XMLRPC_${name}_LIBRARY)
+
+ # Build an ordered list of all the libraries needed.
+ SET(XMLRPC_LIBRARIES ${XMLRPC_LIBRARIES} "${XMLRPC_${name}_LIBRARY}")
+ ENDFOREACH(name)
+ ELSE("${XMLRPC_C_CONFIG_RESULT}" MATCHES "^0$")
+ MESSAGE("Error running ${XMLRPC_C_CONFIG}: [${XMLRPC_C_CONFIG_RESULT}]")
+ SET(XMLRPC_FOUND 0)
+ ENDIF("${XMLRPC_C_CONFIG_RESULT}" MATCHES "^0$")
+ENDIF(XMLRPC_FOUND)
+
+# Report the results.
+IF(NOT XMLRPC_FOUND)
+ SET(XMLRPC_DIR_MESSAGE
+ "XMLRPC was not found. Make sure the entries XMLRPC_* are set.")
+ IF(NOT XMLRPC_FIND_QUIETLY)
+ MESSAGE(STATUS "${XMLRPC_DIR_MESSAGE}")
+ ELSE(NOT XMLRPC_FIND_QUIETLY)
+ IF(XMLRPC_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR "${XMLRPC_DIR_MESSAGE}")
+ ENDIF(XMLRPC_FIND_REQUIRED)
+ ENDIF(NOT XMLRPC_FIND_QUIETLY)
+ENDIF(NOT XMLRPC_FOUND)
diff --git a/Modules/FindZLIB.cmake b/Modules/FindZLIB.cmake
new file mode 100644
index 000000000..166e29181
--- /dev/null
+++ b/Modules/FindZLIB.cmake
@@ -0,0 +1,92 @@
+# - Find zlib
+# 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.
+#
+# 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
+#
+# 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
+#
+# An includer may set ZLIB_ROOT to a zlib installation root to tell
+# this module where to look.
+
+#=============================================================================
+# Copyright 2001-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.)
+
+SET(_ZLIB_SEARCHES)
+
+# Search ZLIB_ROOT first if it is set.
+IF(ZLIB_ROOT)
+ SET(_ZLIB_SEARCH_ROOT PATHS ${ZLIB_ROOT} NO_DEFAULT_PATH)
+ LIST(APPEND _ZLIB_SEARCHES _ZLIB_SEARCH_ROOT)
+ENDIF()
+
+# Normal search.
+SET(_ZLIB_SEARCH_NORMAL
+ PATHS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\GnuWin32\\Zlib;InstallPath]"
+ "$ENV{PROGRAMFILES}/zlib"
+ )
+LIST(APPEND _ZLIB_SEARCHES _ZLIB_SEARCH_NORMAL)
+
+SET(ZLIB_NAMES z zlib zdll zlib1 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)
+ENDFOREACH()
+
+MARK_AS_ADVANCED(ZLIB_LIBRARY ZLIB_INCLUDE_DIR)
+
+IF(ZLIB_INCLUDE_DIR AND EXISTS "${ZLIB_INCLUDE_DIR}/zlib.h")
+ FILE(STRINGS "${ZLIB_INCLUDE_DIR}/zlib.h" ZLIB_H REGEX "^#define ZLIB_VERSION \"[^\"]*\"$")
+
+ STRING(REGEX REPLACE "^.*ZLIB_VERSION \"([0-9]+).*$" "\\1" ZLIB_VERSION_MAJOR "${ZLIB_H}")
+ STRING(REGEX REPLACE "^.*ZLIB_VERSION \"[0-9]+\\.([0-9]+).*$" "\\1" ZLIB_VERSION_MINOR "${ZLIB_H}")
+ STRING(REGEX REPLACE "^.*ZLIB_VERSION \"[0-9]+\\.[0-9]+\\.([0-9]+).*$" "\\1" ZLIB_VERSION_PATCH "${ZLIB_H}")
+ SET(ZLIB_VERSION_STRING "${ZLIB_VERSION_MAJOR}.${ZLIB_VERSION_MINOR}.${ZLIB_VERSION_PATCH}")
+
+ # 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]+).*$")
+ SET(ZLIB_VERSION_TWEAK "${CMAKE_MATCH_1}")
+ SET(ZLIB_VERSION_STRING "${ZLIB_VERSION_STRING}.${ZLIB_VERSION_TWEAK}")
+ ENDIF( "${ZLIB_H}" MATCHES "^.*ZLIB_VERSION \"[0-9]+\\.[0-9]+\\.[0-9]+\\.([0-9]+).*$")
+
+ SET(ZLIB_MAJOR_VERSION "${ZLIB_VERSION_MAJOR}")
+ SET(ZLIB_MINOR_VERSION "${ZLIB_VERSION_MINOR}")
+ SET(ZLIB_PATCH_VERSION "${ZLIB_VERSION_PATCH}")
+ENDIF()
+
+# handle the QUIETLY and REQUIRED arguments and set ZLIB_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(ZLIB REQUIRED_VARS ZLIB_LIBRARY ZLIB_INCLUDE_DIR
+ VERSION_VAR ZLIB_VERSION_STRING)
+
+IF(ZLIB_FOUND)
+ SET(ZLIB_INCLUDE_DIRS ${ZLIB_INCLUDE_DIR})
+ SET(ZLIB_LIBRARIES ${ZLIB_LIBRARY})
+ENDIF()
+
diff --git a/Modules/Findosg.cmake b/Modules/Findosg.cmake
new file mode 100644
index 000000000..0106372e3
--- /dev/null
+++ b/Modules/Findosg.cmake
@@ -0,0 +1,54 @@
+#
+# 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.
+
+#=============================================================================
+# 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.)
+
+# Header files are presumed to be included like
+# #include <osg/PositionAttitudeTransform>
+# #include <osgUtil/SceneView>
+
+include(Findosg_functions)
+OSG_FIND_PATH (OSG osg/PositionAttitudeTransform)
+OSG_FIND_LIBRARY(OSG osg)
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(osg DEFAULT_MSG OSG_LIBRARY OSG_INCLUDE_DIR)
diff --git a/Modules/FindosgAnimation.cmake b/Modules/FindosgAnimation.cmake
new file mode 100644
index 000000000..b9b44a081
--- /dev/null
+++ b/Modules/FindosgAnimation.cmake
@@ -0,0 +1,51 @@
+# 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.
+
+#=============================================================================
+# 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.)
+
+# Header files are presumed to be included like
+# #include <osg/PositionAttitudeTransform>
+# #include <osgAnimation/Animation>
+
+include(Findosg_functions)
+OSG_FIND_PATH (OSGANIMATION osgAnimation/Animation)
+OSG_FIND_LIBRARY(OSGANIMATION osgAnimation)
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(osgAnimation DEFAULT_MSG
+ OSGANIMATION_LIBRARY OSGANIMATION_INCLUDE_DIR)
diff --git a/Modules/FindosgDB.cmake b/Modules/FindosgDB.cmake
new file mode 100644
index 000000000..eabdde72d
--- /dev/null
+++ b/Modules/FindosgDB.cmake
@@ -0,0 +1,51 @@
+# 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.
+
+#=============================================================================
+# 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.)
+
+# Header files are presumed to be included like
+# #include <osg/PositionAttitudeTransform>
+# #include <osgDB/DatabasePager>
+
+include(Findosg_functions)
+OSG_FIND_PATH (OSGDB osgDB/DatabasePager)
+OSG_FIND_LIBRARY(OSGDB osgDB)
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(osgDB DEFAULT_MSG
+ OSGDB_LIBRARY OSGDB_INCLUDE_DIR)
diff --git a/Modules/FindosgFX.cmake b/Modules/FindosgFX.cmake
new file mode 100644
index 000000000..81d5af5a2
--- /dev/null
+++ b/Modules/FindosgFX.cmake
@@ -0,0 +1,51 @@
+# 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.
+
+#=============================================================================
+# 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.)
+
+# Header files are presumed to be included like
+# #include <osg/PositionAttitudeTransform>
+# #include <osgFX/BumpMapping>
+
+include(Findosg_functions)
+OSG_FIND_PATH (OSGFX osgFX/BumpMapping)
+OSG_FIND_LIBRARY(OSGFX osgFX)
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(osgFX DEFAULT_MSG
+ OSGFX_LIBRARY OSGFX_INCLUDE_DIR)
diff --git a/Modules/FindosgGA.cmake b/Modules/FindosgGA.cmake
new file mode 100644
index 000000000..a4fe79b0d
--- /dev/null
+++ b/Modules/FindosgGA.cmake
@@ -0,0 +1,51 @@
+# 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.
+
+#=============================================================================
+# 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.)
+
+# Header files are presumed to be included like
+# #include <osg/PositionAttitudeTransform>
+# #include <osgGA/FlightManipulator>
+
+include(Findosg_functions)
+OSG_FIND_PATH (OSGGA osgGA/FlightManipulator)
+OSG_FIND_LIBRARY(OSGGA osgGA)
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(osgGA DEFAULT_MSG
+ OSGGA_LIBRARY OSGGA_INCLUDE_DIR)
diff --git a/Modules/FindosgIntrospection.cmake b/Modules/FindosgIntrospection.cmake
new file mode 100644
index 000000000..24e6ed585
--- /dev/null
+++ b/Modules/FindosgIntrospection.cmake
@@ -0,0 +1,51 @@
+# 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_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.
+#
+# Created by Eric Wing.
+
+#=============================================================================
+# 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.)
+
+# Header files are presumed to be included like
+# #include <osg/PositionAttitudeTransform>
+# #include <osgIntrospection/Reflection>
+
+include(Findosg_functions)
+OSG_FIND_PATH (OSGINTROSPECTION osgIntrospection/Reflection)
+OSG_FIND_LIBRARY(OSGINTROSPECTION osgIntrospection)
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(osgIntrospection DEFAULT_MSG
+ OSGINTROSPECTION_LIBRARY OSGINTROSPECTION_INCLUDE_DIR)
diff --git a/Modules/FindosgManipulator.cmake b/Modules/FindosgManipulator.cmake
new file mode 100644
index 000000000..f71b5fd5c
--- /dev/null
+++ b/Modules/FindosgManipulator.cmake
@@ -0,0 +1,51 @@
+# 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_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.
+#
+# Created by Eric Wing.
+
+#=============================================================================
+# 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.)
+
+# Header files are presumed to be included like
+# #include <osg/PositionAttitudeTransform>
+# #include <osgManipulator/TrackballDragger>
+
+include(Findosg_functions)
+OSG_FIND_PATH (OSGMANIPULATOR osgManipulator/TrackballDragger)
+OSG_FIND_LIBRARY(OSGMANIPULATOR osgManipulator)
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(osgManipulator DEFAULT_MSG
+ OSGMANIPULATOR_LIBRARY OSGMANIPULATOR_INCLUDE_DIR)
diff --git a/Modules/FindosgParticle.cmake b/Modules/FindosgParticle.cmake
new file mode 100644
index 000000000..f23a83fdd
--- /dev/null
+++ b/Modules/FindosgParticle.cmake
@@ -0,0 +1,51 @@
+# 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.
+#
+# Created by Eric Wing.
+
+#=============================================================================
+# 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.)
+
+# Header files are presumed to be included like
+# #include <osg/PositionAttitudeTransform>
+# #include <osgParticle/FireEffect>
+
+include(Findosg_functions)
+OSG_FIND_PATH (OSGPARTICLE osgParticle/FireEffect)
+OSG_FIND_LIBRARY(OSGPARTICLE osgParticle)
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(osgParticle DEFAULT_MSG
+ OSGPARTICLE_LIBRARY OSGPARTICLE_INCLUDE_DIR)
diff --git a/Modules/FindosgPresentation.cmake b/Modules/FindosgPresentation.cmake
new file mode 100644
index 000000000..f89e25f9c
--- /dev/null
+++ b/Modules/FindosgPresentation.cmake
@@ -0,0 +1,52 @@
+# 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_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.
+#
+# Created by Eric Wing.
+# Modified to work with osgPresentation by Robert Osfield, January 2012.
+
+#=============================================================================
+# 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.)
+
+# Header files are presumed to be included like
+# #include <osg/PositionAttitudeTransform>
+# #include <osgPresentation/SlideEventHandler>
+
+include(Findosg_functions)
+OSG_FIND_PATH (OSGPRESENTATION osgPresentation/SlideEventHandler)
+OSG_FIND_LIBRARY(OSGPRESENTATION osgPresentation)
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(osgPresentation DEFAULT_MSG
+ OSGPRESENTATION_LIBRARY OSGPRESENTATION_INCLUDE_DIR)
diff --git a/Modules/FindosgProducer.cmake b/Modules/FindosgProducer.cmake
new file mode 100644
index 000000000..51f609064
--- /dev/null
+++ b/Modules/FindosgProducer.cmake
@@ -0,0 +1,51 @@
+# 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.
+#
+# Created by Eric Wing.
+
+#=============================================================================
+# 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.)
+
+# Header files are presumed to be included like
+# #include <osg/PositionAttitudeTransform>
+# #include <osgProducer/OsgSceneHandler>
+
+include(Findosg_functions)
+OSG_FIND_PATH (OSGPRODUCER osgProducer/OsgSceneHandler)
+OSG_FIND_LIBRARY(OSGPRODUCER osgProducer)
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(osgProducer DEFAULT_MSG
+ OSGPRODUCER_LIBRARY OSGPRODUCER_INCLUDE_DIR)
diff --git a/Modules/FindosgQt.cmake b/Modules/FindosgQt.cmake
new file mode 100644
index 000000000..ddc91287b
--- /dev/null
+++ b/Modules/FindosgQt.cmake
@@ -0,0 +1,52 @@
+# 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.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software 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.)
+
+# Header files are presumed to be included like
+# #include <osg/PositionAttitudeTransform>
+# #include <osgQt/GraphicsWindowQt>
+
+include(Findosg_functions)
+OSG_FIND_PATH (OSGQT osgQt/GraphicsWindowQt)
+OSG_FIND_LIBRARY(OSGQT osgQt)
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(osgQt DEFAULT_MSG
+ OSGQT_LIBRARY OSGQT_INCLUDE_DIR)
diff --git a/Modules/FindosgShadow.cmake b/Modules/FindosgShadow.cmake
new file mode 100644
index 000000000..278f8ae9e
--- /dev/null
+++ b/Modules/FindosgShadow.cmake
@@ -0,0 +1,51 @@
+# 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.
+
+#=============================================================================
+# 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.)
+
+# Header files are presumed to be included like
+# #include <osg/PositionAttitudeTransform>
+# #include <osgShadow/ShadowTexture>
+
+include(Findosg_functions)
+OSG_FIND_PATH (OSGSHADOW osgShadow/ShadowTexture)
+OSG_FIND_LIBRARY(OSGSHADOW osgShadow)
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(osgShadow DEFAULT_MSG
+ OSGSHADOW_LIBRARY OSGSHADOW_INCLUDE_DIR)
diff --git a/Modules/FindosgSim.cmake b/Modules/FindosgSim.cmake
new file mode 100644
index 000000000..15daf64fe
--- /dev/null
+++ b/Modules/FindosgSim.cmake
@@ -0,0 +1,51 @@
+# 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.
+
+#=============================================================================
+# 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.)
+
+# Header files are presumed to be included like
+# #include <osg/PositionAttitudeTransform>
+# #include <osgSim/ImpostorSprite>
+
+include(Findosg_functions)
+OSG_FIND_PATH (OSGSIM osgSim/ImpostorSprite)
+OSG_FIND_LIBRARY(OSGSIM osgSim)
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(osgSim DEFAULT_MSG
+ OSGSIM_LIBRARY OSGSIM_INCLUDE_DIR)
diff --git a/Modules/FindosgTerrain.cmake b/Modules/FindosgTerrain.cmake
new file mode 100644
index 000000000..fbf373e59
--- /dev/null
+++ b/Modules/FindosgTerrain.cmake
@@ -0,0 +1,51 @@
+# 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.
+
+#=============================================================================
+# 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.)
+
+# Header files are presumed to be included like
+# #include <osg/PositionAttitudeTransform>
+# #include <osgTerrain/Terrain>
+
+include(Findosg_functions)
+OSG_FIND_PATH (OSGTERRAIN osgTerrain/Terrain)
+OSG_FIND_LIBRARY(OSGTERRAIN osgTerrain)
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(osgTerrain DEFAULT_MSG
+ OSGTERRAIN_LIBRARY OSGTERRAIN_INCLUDE_DIR)
diff --git a/Modules/FindosgText.cmake b/Modules/FindosgText.cmake
new file mode 100644
index 000000000..22f825f54
--- /dev/null
+++ b/Modules/FindosgText.cmake
@@ -0,0 +1,51 @@
+# 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.
+
+#=============================================================================
+# 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.)
+
+# Header files are presumed to be included like
+# #include <osg/PositionAttitudeTransform>
+# #include <osgText/Text>
+
+include(Findosg_functions)
+OSG_FIND_PATH (OSGTEXT osgText/Text)
+OSG_FIND_LIBRARY(OSGTEXT osgText)
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(osgText DEFAULT_MSG
+ OSGTEXT_LIBRARY OSGTEXT_INCLUDE_DIR)
diff --git a/Modules/FindosgUtil.cmake b/Modules/FindosgUtil.cmake
new file mode 100644
index 000000000..05a74df84
--- /dev/null
+++ b/Modules/FindosgUtil.cmake
@@ -0,0 +1,51 @@
+# 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.
+
+#=============================================================================
+# 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.)
+
+# Header files are presumed to be included like
+# #include <osg/PositionAttitudeTransform>
+# #include <osgUtil/SceneView>
+
+include(Findosg_functions)
+OSG_FIND_PATH (OSGUTIL osgUtil/SceneView)
+OSG_FIND_LIBRARY(OSGUTIL osgUtil)
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(osgUtil DEFAULT_MSG
+ OSGUTIL_LIBRARY OSGUTIL_INCLUDE_DIR)
diff --git a/Modules/FindosgViewer.cmake b/Modules/FindosgViewer.cmake
new file mode 100644
index 000000000..650dbd7ef
--- /dev/null
+++ b/Modules/FindosgViewer.cmake
@@ -0,0 +1,51 @@
+# 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.
+
+#=============================================================================
+# 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.)
+
+# Header files are presumed to be included like
+# #include <osg/PositionAttitudeTransform>
+# #include <osgViewer/Viewer>
+
+include(Findosg_functions)
+OSG_FIND_PATH (OSGVIEWER osgViewer/Viewer)
+OSG_FIND_LIBRARY(OSGVIEWER osgViewer)
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(osgViewer DEFAULT_MSG
+ OSGVIEWER_LIBRARY OSGVIEWER_INCLUDE_DIR)
diff --git a/Modules/FindosgVolume.cmake b/Modules/FindosgVolume.cmake
new file mode 100644
index 000000000..3ad7edc24
--- /dev/null
+++ b/Modules/FindosgVolume.cmake
@@ -0,0 +1,51 @@
+# 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.
+
+#=============================================================================
+# 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.)
+
+# Header files are presumed to be included like
+# #include <osg/PositionAttitudeTransform>
+# #include <osgVolume/Volume>
+
+include(Findosg_functions)
+OSG_FIND_PATH (OSGVOLUME osgVolume/Volume)
+OSG_FIND_LIBRARY(OSGVOLUME osgVolume)
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(osgVolume DEFAULT_MSG
+ OSGVOLUME_LIBRARY OSGVOLUME_INCLUDE_DIR)
diff --git a/Modules/FindosgWidget.cmake b/Modules/FindosgWidget.cmake
new file mode 100644
index 000000000..206a8b7f5
--- /dev/null
+++ b/Modules/FindosgWidget.cmake
@@ -0,0 +1,51 @@
+# 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.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software 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.)
+
+# Header files are presumed to be included like
+# #include <osg/PositionAttitudeTransform>
+# #include <osgWidget/Widget>
+
+include(Findosg_functions)
+OSG_FIND_PATH (OSGWIDGET osgWidget/Widget)
+OSG_FIND_LIBRARY(OSGWIDGET osgWidget)
+
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(osgWidget DEFAULT_MSG
+ OSGWIDGET_LIBRARY OSGWIDGET_INCLUDE_DIR)
diff --git a/Modules/Findosg_functions.cmake b/Modules/Findosg_functions.cmake
new file mode 100644
index 000000000..ab836ff9f
--- /dev/null
+++ b/Modules/Findosg_functions.cmake
@@ -0,0 +1,105 @@
+#
+# This CMake file contains two macros to assist with searching for OSG
+# libraries and nodekits.
+#
+
+#=============================================================================
+# Copyright 2009 Kitware, Inc.
+# Copyright 2009 Philip Lowman <philip@yhbt.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.)
+
+#
+# OSG_FIND_PATH
+#
+function(OSG_FIND_PATH module header)
+ string(TOUPPER ${module} module_uc)
+
+ # Try the user's environment request before anything else.
+ find_path(${module_uc}_INCLUDE_DIR ${header}
+ HINTS
+ $ENV{${module_uc}_DIR}
+ $ENV{OSG_DIR}
+ $ENV{OSGDIR}
+ $ENV{OSG_ROOT}
+ PATH_SUFFIXES include
+ PATHS
+ /sw # Fink
+ /opt/local # DarwinPorts
+ /opt/csw # Blastwave
+ /opt
+ /usr/freeware
+ )
+endfunction(OSG_FIND_PATH module header)
+
+
+#
+# OSG_FIND_LIBRARY
+#
+function(OSG_FIND_LIBRARY module library)
+ string(TOUPPER ${module} module_uc)
+
+ find_library(${module_uc}_LIBRARY
+ NAMES ${library}
+ HINTS
+ $ENV{${module_uc}_DIR}
+ $ENV{OSG_DIR}
+ $ENV{OSGDIR}
+ $ENV{OSG_ROOT}
+ PATH_SUFFIXES lib64 lib
+ PATHS
+ /sw # Fink
+ /opt/local # DarwinPorts
+ /opt/csw # Blastwave
+ /opt
+ /usr/freeware
+ )
+
+ find_library(${module_uc}_LIBRARY_DEBUG
+ NAMES ${library}d
+ HINTS
+ $ENV{${module_uc}_DIR}
+ $ENV{OSG_DIR}
+ $ENV{OSGDIR}
+ $ENV{OSG_ROOT}
+ PATH_SUFFIXES lib64 lib
+ PATHS
+ /sw # Fink
+ /opt/local # DarwinPorts
+ /opt/csw # Blastwave
+ /opt
+ /usr/freeware
+ )
+
+ if(NOT ${module_uc}_LIBRARY_DEBUG)
+ # They don't have a debug library
+ set(${module_uc}_LIBRARY_DEBUG ${${module_uc}_LIBRARY} PARENT_SCOPE)
+ set(${module_uc}_LIBRARIES ${${module_uc}_LIBRARY} PARENT_SCOPE)
+ else()
+ # They really have a FOO_LIBRARY_DEBUG
+ set(${module_uc}_LIBRARIES
+ optimized ${${module_uc}_LIBRARY}
+ debug ${${module_uc}_LIBRARY_DEBUG}
+ PARENT_SCOPE
+ )
+ endif()
+endfunction(OSG_FIND_LIBRARY module library)
+
+#
+# OSG_MARK_AS_ADVANCED
+# Just a convenience function for calling MARK_AS_ADVANCED
+#
+function(OSG_MARK_AS_ADVANCED _module)
+ string(TOUPPER ${_module} _module_UC)
+ mark_as_advanced(${_module_UC}_INCLUDE_DIR)
+ mark_as_advanced(${_module_UC}_LIBRARY)
+ mark_as_advanced(${_module_UC}_LIBRARY_DEBUG)
+endfunction()
diff --git a/Modules/FindwxWidgets.cmake b/Modules/FindwxWidgets.cmake
new file mode 100644
index 000000000..865a6c5d1
--- /dev/null
+++ b/Modules/FindwxWidgets.cmake
@@ -0,0 +1,1044 @@
+# - 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:
+#
+# 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):
+#
+# 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
+# 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
+#
+# 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:
+#
+# 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.
+#
+# 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(wxWidgets_FOUND)
+#
+# 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})
+
+#=============================================================================
+# Copyright 2004-2009 Kitware, Inc.
+# Copyright 2007-2009 Miguel A. Figueroa-Villanueva <miguelf at ieee dot 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.)
+
+#
+# FIXME: check this and provide a correct sample usage...
+# Remember to connect back to the upper text.
+# Sample usage with monolithic wx build:
+#
+# FIND_PACKAGE(wxWidgets COMPONENTS mono)
+# ...
+
+# NOTES
+#
+# This module has been tested on the WIN32 platform with wxWidgets
+# 2.6.2, 2.6.3, and 2.5.3. However, it has been designed to
+# easily extend support to all possible builds, e.g., static/shared,
+# debug/release, unicode, universal, multilib/monolithic, etc..
+#
+# If you want to use the module and your build type is not supported
+# out-of-the-box, please contact me to exchange information on how
+# your system is setup and I'll try to add support for it.
+#
+# AUTHOR
+#
+# Miguel A. Figueroa-Villanueva (miguelf at ieee dot org).
+# Jan Woetzel (jw at mip.informatik.uni-kiel.de).
+#
+# Based on previous works of:
+# Jan Woetzel (FindwxWindows.cmake),
+# Jorgen Bodde and Jerry Fath (FindwxWin.cmake).
+
+# TODO/ideas
+#
+# (1) Option/Setting to use all available wx libs
+# In contrast to expert developer who lists the
+# minimal set of required libs in wxWidgets_USE_LIBS
+# there is the newbie user:
+# - who just wants to link against WX with more 'magic'
+# - doesn't know the internal structure of WX or how it was built,
+# in particular if it is monolithic or not
+# - want to link against all available WX libs
+# Basically, the intent here is to mimic what wx-config would do by
+# default (i.e., `wx-config --libs`).
+#
+# Possible solution:
+# Add a reserved keyword "std" that initializes to what wx-config
+# would default to. If the user has not set the wxWidgets_USE_LIBS,
+# default to "std" instead of "base core" as it is now. To implement
+# "std" will basically boil down to a FOR_EACH lib-FOUND, but maybe
+# checking whether a minimal set was found.
+
+
+# FIXME: This and all the DBG_MSG calls should be removed after the
+# module stabilizes.
+#
+# Helper macro to control the debugging output globally. There are
+# two versions for controlling how verbose your output should be.
+MACRO(DBG_MSG _MSG)
+# MESSAGE(STATUS
+# "${CMAKE_CURRENT_LIST_FILE}(${CMAKE_CURRENT_LIST_LINE}): ${_MSG}")
+ENDMACRO(DBG_MSG)
+MACRO(DBG_MSG_V _MSG)
+# MESSAGE(STATUS
+# "${CMAKE_CURRENT_LIST_FILE}(${CMAKE_CURRENT_LIST_LINE}): ${_MSG}")
+ENDMACRO(DBG_MSG_V)
+
+# Clear return values in case the module is loaded more than once.
+SET(wxWidgets_FOUND FALSE)
+SET(wxWidgets_INCLUDE_DIRS "")
+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.
+#
+# If wxWidgets_USE_LIBS is set:
+# - if using <components>, then override wxWidgets_USE_LIBS
+# - else set wxWidgets_FIND_COMPONENTS to wxWidgets_USE_LIBS
+IF(wxWidgets_USE_LIBS AND NOT wxWidgets_FIND_COMPONENTS)
+ SET(wxWidgets_FIND_COMPONENTS ${wxWidgets_USE_LIBS})
+ENDIF(wxWidgets_USE_LIBS AND NOT wxWidgets_FIND_COMPONENTS)
+DBG_MSG("wxWidgets_FIND_COMPONENTS : ${wxWidgets_FIND_COMPONENTS}")
+
+# Add the convenience use file if available.
+#
+# Get dir of this file which may reside in:
+# - CMAKE_MAKE_ROOT/Modules on CMake installation
+# - CMAKE_MODULE_PATH if user prefers his own specialized version
+SET(wxWidgets_USE_FILE "")
+GET_FILENAME_COMPONENT(
+ wxWidgets_CURRENT_LIST_DIR ${CMAKE_CURRENT_LIST_FILE} PATH)
+# Prefer an existing customized version, but the user might override
+# the FindwxWidgets module and not the UsewxWidgets one.
+IF(EXISTS "${wxWidgets_CURRENT_LIST_DIR}/UsewxWidgets.cmake")
+ SET(wxWidgets_USE_FILE
+ "${wxWidgets_CURRENT_LIST_DIR}/UsewxWidgets.cmake")
+ELSE(EXISTS "${wxWidgets_CURRENT_LIST_DIR}/UsewxWidgets.cmake")
+ SET(wxWidgets_USE_FILE UsewxWidgets)
+ENDIF(EXISTS "${wxWidgets_CURRENT_LIST_DIR}/UsewxWidgets.cmake")
+
+#=====================================================================
+#=====================================================================
+IF(WIN32 AND NOT CYGWIN AND NOT MSYS)
+ SET(wxWidgets_FIND_STYLE "win32")
+ELSE(WIN32 AND NOT CYGWIN AND NOT MSYS)
+ IF(UNIX OR MSYS)
+ SET(wxWidgets_FIND_STYLE "unix")
+ ENDIF(UNIX OR MSYS)
+ENDIF(WIN32 AND NOT CYGWIN AND NOT MSYS)
+
+#=====================================================================
+# WIN32_FIND_STYLE
+#=====================================================================
+IF(wxWidgets_FIND_STYLE STREQUAL "win32")
+ # Useful common wx libs needed by almost all components.
+ SET(wxWidgets_COMMON_LIBRARIES png tiff jpeg zlib regex expat)
+
+ # DEPRECATED: Use FIND_PACKAGE(wxWidgets COMPONENTS mono) instead.
+ IF(NOT wxWidgets_FIND_COMPONENTS)
+ IF(wxWidgets_USE_MONOLITHIC)
+ SET(wxWidgets_FIND_COMPONENTS mono)
+ ELSE(wxWidgets_USE_MONOLITHIC)
+ SET(wxWidgets_FIND_COMPONENTS core base) # this is default
+ ENDIF(wxWidgets_USE_MONOLITHIC)
+ ENDIF(NOT wxWidgets_FIND_COMPONENTS)
+
+ # Add the common (usually required libs) unless
+ # wxWidgets_EXCLUDE_COMMON_LIBRARIES has been set.
+ IF(NOT wxWidgets_EXCLUDE_COMMON_LIBRARIES)
+ LIST(APPEND wxWidgets_FIND_COMPONENTS
+ ${wxWidgets_COMMON_LIBRARIES})
+ ENDIF(NOT wxWidgets_EXCLUDE_COMMON_LIBRARIES)
+
+ #-------------------------------------------------------------------
+ # WIN32: Helper MACROS
+ #-------------------------------------------------------------------
+ #
+ # Get filename components for a configuration. For example,
+ # if _CONFIGURATION = mswunivud, then _UNV=univ, _UCD=u _DBG=d
+ # if _CONFIGURATION = mswu, then _UNV="", _UCD=u _DBG=""
+ #
+ MACRO(WX_GET_NAME_COMPONENTS _CONFIGURATION _UNV _UCD _DBG)
+ STRING(REGEX MATCH "univ" ${_UNV} "${_CONFIGURATION}")
+ STRING(REGEX REPLACE "msw.*(u)[d]*$" "u" ${_UCD} "${_CONFIGURATION}")
+ IF(${_UCD} STREQUAL ${_CONFIGURATION})
+ SET(${_UCD} "")
+ ENDIF(${_UCD} STREQUAL ${_CONFIGURATION})
+ STRING(REGEX MATCH "d$" ${_DBG} "${_CONFIGURATION}")
+ ENDMACRO(WX_GET_NAME_COMPONENTS)
+
+ #
+ # Find libraries associated to a configuration.
+ #
+ MACRO(WX_FIND_LIBS _UNV _UCD _DBG)
+ DBG_MSG_V("m_unv = ${_UNV}")
+ DBG_MSG_V("m_ucd = ${_UCD}")
+ DBG_MSG_V("m_dbg = ${_DBG}")
+
+ # FIXME: What if both regex libs are available. regex should be
+ # found outside the loop and only wx${LIB}${_UCD}${_DBG}.
+ # Find wxWidgets common libraries.
+ FOREACH(LIB ${wxWidgets_COMMON_LIBRARIES} scintilla)
+ FIND_LIBRARY(WX_${LIB}${_DBG}
+ NAMES
+ wx${LIB}${_UCD}${_DBG} # for regex
+ wx${LIB}${_DBG}
+ PATHS ${WX_LIB_DIR}
+ NO_DEFAULT_PATH
+ )
+ MARK_AS_ADVANCED(WX_${LIB}${_DBG})
+ ENDFOREACH(LIB)
+
+ # Find wxWidgets multilib base libraries.
+ FIND_LIBRARY(WX_base${_DBG}
+ NAMES
+ wxbase29${_UCD}${_DBG}
+ wxbase28${_UCD}${_DBG}
+ wxbase27${_UCD}${_DBG}
+ wxbase26${_UCD}${_DBG}
+ wxbase25${_UCD}${_DBG}
+ PATHS ${WX_LIB_DIR}
+ NO_DEFAULT_PATH
+ )
+ MARK_AS_ADVANCED(WX_base${_DBG})
+ FOREACH(LIB net odbc xml)
+ FIND_LIBRARY(WX_${LIB}${_DBG}
+ NAMES
+ wxbase29${_UCD}${_DBG}_${LIB}
+ wxbase28${_UCD}${_DBG}_${LIB}
+ wxbase27${_UCD}${_DBG}_${LIB}
+ wxbase26${_UCD}${_DBG}_${LIB}
+ wxbase25${_UCD}${_DBG}_${LIB}
+ PATHS ${WX_LIB_DIR}
+ NO_DEFAULT_PATH
+ )
+ MARK_AS_ADVANCED(WX_${LIB}${_DBG})
+ ENDFOREACH(LIB)
+
+ # Find wxWidgets monolithic library.
+ FIND_LIBRARY(WX_mono${_DBG}
+ NAMES
+ wxmsw${_UNV}29${_UCD}${_DBG}
+ wxmsw${_UNV}28${_UCD}${_DBG}
+ wxmsw${_UNV}27${_UCD}${_DBG}
+ wxmsw${_UNV}26${_UCD}${_DBG}
+ wxmsw${_UNV}25${_UCD}${_DBG}
+ PATHS ${WX_LIB_DIR}
+ NO_DEFAULT_PATH
+ )
+ MARK_AS_ADVANCED(WX_mono${_DBG})
+
+ # Find wxWidgets multilib libraries.
+ FOREACH(LIB core adv aui html media xrc dbgrid gl qa richtext
+ stc ribbon propgrid webview)
+ FIND_LIBRARY(WX_${LIB}${_DBG}
+ NAMES
+ wxmsw${_UNV}29${_UCD}${_DBG}_${LIB}
+ wxmsw${_UNV}28${_UCD}${_DBG}_${LIB}
+ wxmsw${_UNV}27${_UCD}${_DBG}_${LIB}
+ wxmsw${_UNV}26${_UCD}${_DBG}_${LIB}
+ wxmsw${_UNV}25${_UCD}${_DBG}_${LIB}
+ PATHS ${WX_LIB_DIR}
+ NO_DEFAULT_PATH
+ )
+ MARK_AS_ADVANCED(WX_${LIB}${_DBG})
+ ENDFOREACH(LIB)
+ ENDMACRO(WX_FIND_LIBS)
+
+ #
+ # Clear all library paths, so that FIND_LIBRARY refinds them.
+ #
+ # Clear a lib, reset its found flag, and mark as advanced.
+ MACRO(WX_CLEAR_LIB _LIB)
+ SET(${_LIB} "${_LIB}-NOTFOUND" CACHE FILEPATH "Cleared." FORCE)
+ SET(${_LIB}_FOUND FALSE)
+ MARK_AS_ADVANCED(${_LIB})
+ ENDMACRO(WX_CLEAR_LIB)
+ # Clear all debug or release library paths (arguments are "d" or "").
+ MACRO(WX_CLEAR_ALL_LIBS _DBG)
+ # Clear wxWidgets common libraries.
+ FOREACH(LIB ${wxWidgets_COMMON_LIBRARIES} scintilla)
+ WX_CLEAR_LIB(WX_${LIB}${_DBG})
+ ENDFOREACH(LIB)
+
+ # Clear wxWidgets multilib base libraries.
+ WX_CLEAR_LIB(WX_base${_DBG})
+ FOREACH(LIB net odbc xml)
+ WX_CLEAR_LIB(WX_${LIB}${_DBG})
+ ENDFOREACH(LIB)
+
+ # Clear wxWidgets monolithic library.
+ WX_CLEAR_LIB(WX_mono${_DBG})
+
+ # Clear wxWidgets multilib libraries.
+ FOREACH(LIB core adv aui html media xrc dbgrid gl qa richtext
+ stc ribbon propgrid)
+ WX_CLEAR_LIB(WX_${LIB}${_DBG})
+ ENDFOREACH(LIB)
+ ENDMACRO(WX_CLEAR_ALL_LIBS)
+ # Clear all wxWidgets debug libraries.
+ MACRO(WX_CLEAR_ALL_DBG_LIBS)
+ WX_CLEAR_ALL_LIBS("d")
+ ENDMACRO(WX_CLEAR_ALL_DBG_LIBS)
+ # Clear all wxWidgets release libraries.
+ MACRO(WX_CLEAR_ALL_REL_LIBS)
+ WX_CLEAR_ALL_LIBS("")
+ ENDMACRO(WX_CLEAR_ALL_REL_LIBS)
+
+ #
+ # Set the wxWidgets_LIBRARIES variable.
+ # Also, Sets output variable wxWidgets_FOUND to FALSE if it fails.
+ #
+ MACRO(WX_SET_LIBRARIES _LIBS _DBG)
+ DBG_MSG_V("Looking for ${${_LIBS}}")
+ IF(WX_USE_REL_AND_DBG)
+ FOREACH(LIB ${${_LIBS}})
+ DBG_MSG_V("Searching for ${LIB} and ${LIB}d")
+ DBG_MSG_V("WX_${LIB} : ${WX_${LIB}}")
+ DBG_MSG_V("WX_${LIB}d : ${WX_${LIB}d}")
+ IF(WX_${LIB} AND WX_${LIB}d)
+ DBG_MSG_V("Found ${LIB} and ${LIB}d")
+ LIST(APPEND wxWidgets_LIBRARIES
+ debug ${WX_${LIB}d} optimized ${WX_${LIB}}
+ )
+ ELSE(WX_${LIB} AND WX_${LIB}d)
+ DBG_MSG_V("- not found due to missing WX_${LIB}=${WX_${LIB}} or WX_${LIB}d=${WX_${LIB}d}")
+ SET(wxWidgets_FOUND FALSE)
+ ENDIF(WX_${LIB} AND WX_${LIB}d)
+ ENDFOREACH(LIB)
+ ELSE(WX_USE_REL_AND_DBG)
+ FOREACH(LIB ${${_LIBS}})
+ DBG_MSG_V("Searching for ${LIB}${_DBG}")
+ DBG_MSG_V("WX_${LIB}${_DBG} : ${WX_${LIB}${_DBG}}")
+ IF(WX_${LIB}${_DBG})
+ DBG_MSG_V("Found ${LIB}${_DBG}")
+ LIST(APPEND wxWidgets_LIBRARIES ${WX_${LIB}${_DBG}})
+ ELSE(WX_${LIB}${_DBG})
+ DBG_MSG_V(
+ "- not found due to missing WX_${LIB}${_DBG}=${WX_${LIB}${_DBG}}")
+ SET(wxWidgets_FOUND FALSE)
+ ENDIF(WX_${LIB}${_DBG})
+ ENDFOREACH(LIB)
+ ENDIF(WX_USE_REL_AND_DBG)
+
+ DBG_MSG_V("OpenGL")
+ LIST(FIND ${_LIBS} gl WX_USE_GL)
+ IF(NOT WX_USE_GL EQUAL -1)
+ DBG_MSG_V("- is required.")
+ LIST(APPEND wxWidgets_LIBRARIES opengl32 glu32)
+ ENDIF(NOT WX_USE_GL EQUAL -1)
+
+ LIST(APPEND wxWidgets_LIBRARIES winmm comctl32 rpcrt4 wsock32)
+ ENDMACRO(WX_SET_LIBRARIES)
+
+ #-------------------------------------------------------------------
+ # WIN32: Start actual work.
+ #-------------------------------------------------------------------
+
+ # Look for an installation tree.
+ FIND_PATH(wxWidgets_ROOT_DIR
+ NAMES include/wx/wx.h
+ PATHS
+ $ENV{wxWidgets_ROOT_DIR}
+ $ENV{WXWIN}
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\wxWidgets_is1;Inno Setup: App Path]" # WX 2.6.x
+ C:/
+ D:/
+ $ENV{ProgramFiles}
+ PATH_SUFFIXES
+ wxWidgets-2.9.4
+ wxWidgets-2.9.3
+ wxWidgets-2.9.2
+ wxWidgets-2.9.1
+ wxWidgets-2.9.0
+ wxWidgets-2.8.9
+ wxWidgets-2.8.8
+ wxWidgets-2.8.7
+ wxWidgets-2.8.6
+ wxWidgets-2.8.5
+ wxWidgets-2.8.4
+ wxWidgets-2.8.3
+ wxWidgets-2.8.2
+ wxWidgets-2.8.1
+ wxWidgets-2.8.0
+ wxWidgets-2.7.4
+ wxWidgets-2.7.3
+ wxWidgets-2.7.2
+ wxWidgets-2.7.1
+ wxWidgets-2.7.0
+ wxWidgets-2.7.0-1
+ wxWidgets-2.6.4
+ wxWidgets-2.6.3
+ wxWidgets-2.6.2
+ wxWidgets-2.6.1
+ wxWidgets-2.5.4
+ wxWidgets-2.5.3
+ wxWidgets-2.5.2
+ wxWidgets-2.5.1
+ wxWidgets
+ DOC "wxWidgets base/installation directory?"
+ )
+
+ # If wxWidgets_ROOT_DIR changed, clear lib dir.
+ IF(NOT WX_ROOT_DIR STREQUAL wxWidgets_ROOT_DIR)
+ SET(WX_ROOT_DIR ${wxWidgets_ROOT_DIR}
+ CACHE INTERNAL "wxWidgets_ROOT_DIR")
+ SET(wxWidgets_LIB_DIR "wxWidgets_LIB_DIR-NOTFOUND"
+ CACHE PATH "Cleared." FORCE)
+ ENDIF(NOT WX_ROOT_DIR STREQUAL wxWidgets_ROOT_DIR)
+
+ IF(WX_ROOT_DIR)
+ # Select one default tree inside the already determined wx tree.
+ # Prefer static/shared order usually consistent with build
+ # settings.
+ IF(MINGW)
+ SET(WX_LIB_DIR_PREFIX gcc)
+ ELSE(MINGW)
+ SET(WX_LIB_DIR_PREFIX vc)
+ ENDIF(MINGW)
+ IF(BUILD_SHARED_LIBS)
+ FIND_PATH(wxWidgets_LIB_DIR
+ NAMES
+ msw/wx/setup.h
+ mswd/wx/setup.h
+ mswu/wx/setup.h
+ mswud/wx/setup.h
+ mswuniv/wx/setup.h
+ mswunivd/wx/setup.h
+ mswunivu/wx/setup.h
+ mswunivud/wx/setup.h
+ PATHS
+ ${WX_ROOT_DIR}/lib/${WX_LIB_DIR_PREFIX}_dll # prefer shared
+ ${WX_ROOT_DIR}/lib/${WX_LIB_DIR_PREFIX}_lib
+ DOC "Path to wxWidgets libraries?"
+ NO_DEFAULT_PATH
+ )
+ ELSE(BUILD_SHARED_LIBS)
+ FIND_PATH(wxWidgets_LIB_DIR
+ NAMES
+ msw/wx/setup.h
+ mswd/wx/setup.h
+ mswu/wx/setup.h
+ mswud/wx/setup.h
+ mswuniv/wx/setup.h
+ mswunivd/wx/setup.h
+ mswunivu/wx/setup.h
+ mswunivud/wx/setup.h
+ PATHS
+ ${WX_ROOT_DIR}/lib/${WX_LIB_DIR_PREFIX}_lib # prefer static
+ ${WX_ROOT_DIR}/lib/${WX_LIB_DIR_PREFIX}_dll
+ DOC "Path to wxWidgets libraries?"
+ NO_DEFAULT_PATH
+ )
+ ENDIF(BUILD_SHARED_LIBS)
+
+ # If wxWidgets_LIB_DIR changed, clear all libraries.
+ IF(NOT WX_LIB_DIR STREQUAL wxWidgets_LIB_DIR)
+ SET(WX_LIB_DIR ${wxWidgets_LIB_DIR} CACHE INTERNAL "wxWidgets_LIB_DIR")
+ WX_CLEAR_ALL_DBG_LIBS()
+ WX_CLEAR_ALL_REL_LIBS()
+ ENDIF(NOT WX_LIB_DIR STREQUAL wxWidgets_LIB_DIR)
+
+ IF(WX_LIB_DIR)
+ # If building shared libs, define WXUSINGDLL to use dllimport.
+ 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(WX_LIB_DIR MATCHES ".*[dD][lL][lL].*")
+
+ # Search for available configuration types.
+ FOREACH(CFG mswunivud mswunivd mswud mswd mswunivu mswuniv mswu msw)
+ SET(WX_${CFG}_FOUND FALSE)
+ IF(EXISTS ${WX_LIB_DIR}/${CFG})
+ LIST(APPEND WX_CONFIGURATION_LIST ${CFG})
+ SET(WX_${CFG}_FOUND TRUE)
+ SET(WX_CONFIGURATION ${CFG})
+ ENDIF(EXISTS ${WX_LIB_DIR}/${CFG})
+ ENDFOREACH(CFG)
+ DBG_MSG_V("WX_CONFIGURATION_LIST=${WX_CONFIGURATION_LIST}")
+
+ IF(WX_CONFIGURATION)
+ SET(wxWidgets_FOUND TRUE)
+
+ # If the selected configuration wasn't found force the default
+ # one. Otherwise, use it but still force a refresh for
+ # updating the doc string with the current list of available
+ # configurations.
+ IF(NOT WX_${wxWidgets_CONFIGURATION}_FOUND)
+ SET(wxWidgets_CONFIGURATION ${WX_CONFIGURATION} CACHE STRING
+ "Set wxWidgets configuration (${WX_CONFIGURATION_LIST})" FORCE)
+ ELSE(NOT WX_${wxWidgets_CONFIGURATION}_FOUND)
+ SET(wxWidgets_CONFIGURATION ${wxWidgets_CONFIGURATION} CACHE STRING
+ "Set wxWidgets configuration (${WX_CONFIGURATION_LIST})" FORCE)
+ ENDIF(NOT WX_${wxWidgets_CONFIGURATION}_FOUND)
+
+ # If release config selected, and both release/debug exist.
+ IF(WX_${wxWidgets_CONFIGURATION}d_FOUND)
+ OPTION(wxWidgets_USE_REL_AND_DBG
+ "Use release and debug configurations?" TRUE)
+ SET(WX_USE_REL_AND_DBG ${wxWidgets_USE_REL_AND_DBG})
+ ELSE(WX_${wxWidgets_CONFIGURATION}d_FOUND)
+ # If the option exists (already in cache), force it false.
+ IF(wxWidgets_USE_REL_AND_DBG)
+ SET(wxWidgets_USE_REL_AND_DBG FALSE CACHE BOOL
+ "No ${wxWidgets_CONFIGURATION}d found." FORCE)
+ ENDIF(wxWidgets_USE_REL_AND_DBG)
+ SET(WX_USE_REL_AND_DBG FALSE)
+ ENDIF(WX_${wxWidgets_CONFIGURATION}d_FOUND)
+
+ # Get configuration parameters from the name.
+ WX_GET_NAME_COMPONENTS(${wxWidgets_CONFIGURATION} UNV UCD DBG)
+
+ # Set wxWidgets lib setup include directory.
+ IF(EXISTS ${WX_LIB_DIR}/${wxWidgets_CONFIGURATION}/wx/setup.h)
+ SET(wxWidgets_INCLUDE_DIRS
+ ${WX_LIB_DIR}/${wxWidgets_CONFIGURATION})
+ ELSE(EXISTS ${WX_LIB_DIR}/${wxWidgets_CONFIGURATION}/wx/setup.h)
+ DBG_MSG("wxWidgets_FOUND FALSE because ${WX_LIB_DIR}/${wxWidgets_CONFIGURATION}/wx/setup.h does not exists.")
+ SET(wxWidgets_FOUND FALSE)
+ ENDIF(EXISTS ${WX_LIB_DIR}/${wxWidgets_CONFIGURATION}/wx/setup.h)
+
+ # Set wxWidgets main include directory.
+ IF(EXISTS ${WX_ROOT_DIR}/include/wx/wx.h)
+ LIST(APPEND wxWidgets_INCLUDE_DIRS ${WX_ROOT_DIR}/include)
+ ELSE(EXISTS ${WX_ROOT_DIR}/include/wx/wx.h)
+ DBG_MSG("wxWidgets_FOUND FALSE because WX_ROOT_DIR=${WX_ROOT_DIR} has no ${WX_ROOT_DIR}/include/wx/wx.h")
+ SET(wxWidgets_FOUND FALSE)
+ ENDIF(EXISTS ${WX_ROOT_DIR}/include/wx/wx.h)
+
+ # Find wxWidgets libraries.
+ WX_FIND_LIBS("${UNV}" "${UCD}" "${DBG}")
+ IF(WX_USE_REL_AND_DBG)
+ WX_FIND_LIBS("${UNV}" "${UCD}" "d")
+ ENDIF(WX_USE_REL_AND_DBG)
+
+ # Settings for requested libs (i.e., include dir, libraries, etc.).
+ WX_SET_LIBRARIES(wxWidgets_FIND_COMPONENTS "${DBG}")
+
+ # Add necessary definitions for unicode builds
+ IF("${UCD}" STREQUAL "u")
+ LIST(APPEND wxWidgets_DEFINITIONS UNICODE _UNICODE)
+ ENDIF("${UCD}" STREQUAL "u")
+
+ # Add necessary definitions for debug builds
+ SET(wxWidgets_DEFINITIONS_DEBUG _DEBUG __WXDEBUG__)
+
+ ENDIF(WX_CONFIGURATION)
+ ENDIF(WX_LIB_DIR)
+ ENDIF(WX_ROOT_DIR)
+
+#=====================================================================
+# UNIX_FIND_STYLE
+#=====================================================================
+ELSE(wxWidgets_FIND_STYLE STREQUAL "win32")
+ IF(wxWidgets_FIND_STYLE STREQUAL "unix")
+ #-----------------------------------------------------------------
+ # UNIX: Helper MACROS
+ #-----------------------------------------------------------------
+ #
+ # Set the default values based on "wx-config --selected-config".
+ #
+ MACRO(WX_CONFIG_SELECT_GET_DEFAULT)
+ EXECUTE_PROCESS(
+ COMMAND sh "${wxWidgets_CONFIG_EXECUTABLE}"
+ ${wxWidgets_CONFIG_OPTIONS} --selected-config
+ OUTPUT_VARIABLE _wx_selected_config
+ RESULT_VARIABLE _wx_result
+ ERROR_QUIET
+ )
+ 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}.*")
+ SET(wxWidgets_DEFAULT_${_upper_opt_name} ON)
+ ELSE(_wx_selected_config MATCHES ".*${_opt_name}.*")
+ SET(wxWidgets_DEFAULT_${_upper_opt_name} OFF)
+ ENDIF(_wx_selected_config MATCHES ".*${_opt_name}.*")
+ ENDFOREACH(_opt_name)
+ ELSE(_wx_result EQUAL 0)
+ FOREACH(_upper_opt_name DEBUG STATIC UNICODE UNIVERSAL)
+ SET(wxWidgets_DEFAULT_${_upper_opt_name} OFF)
+ ENDFOREACH(_upper_opt_name)
+ ENDIF(_wx_result EQUAL 0)
+ ENDMACRO(WX_CONFIG_SELECT_GET_DEFAULT)
+
+ #
+ # Query a boolean configuration option to determine if the system
+ # has both builds available. If so, provide the selection option
+ # to the user.
+ #
+ MACRO(WX_CONFIG_SELECT_QUERY_BOOL _OPT_NAME _OPT_HELP)
+ EXECUTE_PROCESS(
+ COMMAND sh "${wxWidgets_CONFIG_EXECUTABLE}"
+ ${wxWidgets_CONFIG_OPTIONS} --${_OPT_NAME}=yes
+ RESULT_VARIABLE _wx_result_yes
+ OUTPUT_QUIET
+ ERROR_QUIET
+ )
+ EXECUTE_PROCESS(
+ COMMAND sh "${wxWidgets_CONFIG_EXECUTABLE}"
+ ${wxWidgets_CONFIG_OPTIONS} --${_OPT_NAME}=no
+ RESULT_VARIABLE _wx_result_no
+ OUTPUT_QUIET
+ ERROR_QUIET
+ )
+ STRING(TOUPPER ${_OPT_NAME} _UPPER_OPT_NAME)
+ IF(_wx_result_yes EQUAL 0 AND _wx_result_no EQUAL 0)
+ OPTION(wxWidgets_USE_${_UPPER_OPT_NAME}
+ ${_OPT_HELP} ${wxWidgets_DEFAULT_${_UPPER_OPT_NAME}})
+ ELSE(_wx_result_yes EQUAL 0 AND _wx_result_no EQUAL 0)
+ # If option exists (already in cache), force to available one.
+ IF(DEFINED wxWidgets_USE_${_UPPER_OPT_NAME})
+ IF(_wx_result_yes EQUAL 0)
+ SET(wxWidgets_USE_${_UPPER_OPT_NAME} ON CACHE BOOL ${_OPT_HELP} FORCE)
+ ELSE(_wx_result_yes EQUAL 0)
+ SET(wxWidgets_USE_${_UPPER_OPT_NAME} OFF CACHE BOOL ${_OPT_HELP} FORCE)
+ ENDIF(_wx_result_yes EQUAL 0)
+ ENDIF(DEFINED wxWidgets_USE_${_UPPER_OPT_NAME})
+ ENDIF(_wx_result_yes EQUAL 0 AND _wx_result_no EQUAL 0)
+ ENDMACRO(WX_CONFIG_SELECT_QUERY_BOOL)
+
+ #
+ # Set wxWidgets_SELECT_OPTIONS to wx-config options for selecting
+ # among multiple builds.
+ #
+ MACRO(WX_CONFIG_SELECT_SET_OPTIONS)
+ SET(wxWidgets_SELECT_OPTIONS ${wxWidgets_CONFIG_OPTIONS})
+ FOREACH(_opt_name debug static unicode universal)
+ STRING(TOUPPER ${_opt_name} _upper_opt_name)
+ IF(DEFINED wxWidgets_USE_${_upper_opt_name})
+ IF(wxWidgets_USE_${_upper_opt_name})
+ LIST(APPEND wxWidgets_SELECT_OPTIONS --${_opt_name}=yes)
+ ELSE(wxWidgets_USE_${_upper_opt_name})
+ LIST(APPEND wxWidgets_SELECT_OPTIONS --${_opt_name}=no)
+ ENDIF(wxWidgets_USE_${_upper_opt_name})
+ ENDIF(DEFINED wxWidgets_USE_${_upper_opt_name})
+ ENDFOREACH(_opt_name)
+ ENDMACRO(WX_CONFIG_SELECT_SET_OPTIONS)
+
+ #-----------------------------------------------------------------
+ # UNIX: Start actual work.
+ #-----------------------------------------------------------------
+ # Support cross-compiling, only search in the target platform.
+ FIND_PROGRAM(wxWidgets_CONFIG_EXECUTABLE wx-config
+ ONLY_CMAKE_FIND_ROOT_PATH
+ )
+
+ IF(wxWidgets_CONFIG_EXECUTABLE)
+ SET(wxWidgets_FOUND TRUE)
+
+ # get defaults based on "wx-config --selected-config"
+ WX_CONFIG_SELECT_GET_DEFAULT()
+
+ # for each option: if both builds are available, provide option
+ WX_CONFIG_SELECT_QUERY_BOOL(debug "Use debug build?")
+ WX_CONFIG_SELECT_QUERY_BOOL(unicode "Use unicode build?")
+ WX_CONFIG_SELECT_QUERY_BOOL(universal "Use universal build?")
+ WX_CONFIG_SELECT_QUERY_BOOL(static "Link libraries statically?")
+
+ # process selection to set wxWidgets_SELECT_OPTIONS
+ WX_CONFIG_SELECT_SET_OPTIONS()
+ DBG_MSG("wxWidgets_SELECT_OPTIONS=${wxWidgets_SELECT_OPTIONS}")
+
+ # run the wx-config program to get cxxflags
+ EXECUTE_PROCESS(
+ COMMAND sh "${wxWidgets_CONFIG_EXECUTABLE}"
+ ${wxWidgets_SELECT_OPTIONS} --cxxflags
+ OUTPUT_VARIABLE wxWidgets_CXX_FLAGS
+ RESULT_VARIABLE RET
+ ERROR_QUIET
+ )
+ IF(RET EQUAL 0)
+ STRING(STRIP "${wxWidgets_CXX_FLAGS}" wxWidgets_CXX_FLAGS)
+ SEPARATE_ARGUMENTS(wxWidgets_CXX_FLAGS)
+
+ DBG_MSG_V("wxWidgets_CXX_FLAGS=${wxWidgets_CXX_FLAGS}")
+
+ # parse definitions from cxxflags;
+ # drop -D* from CXXFLAGS and the -D prefix
+ STRING(REGEX MATCHALL "-D[^;]+"
+ wxWidgets_DEFINITIONS "${wxWidgets_CXX_FLAGS}")
+ STRING(REGEX REPLACE "-D[^;]+(;|$)" ""
+ wxWidgets_CXX_FLAGS "${wxWidgets_CXX_FLAGS}")
+ STRING(REGEX REPLACE ";$" ""
+ wxWidgets_CXX_FLAGS "${wxWidgets_CXX_FLAGS}")
+ STRING(REPLACE "-D" ""
+ wxWidgets_DEFINITIONS "${wxWidgets_DEFINITIONS}")
+
+ # parse include dirs from cxxflags; drop -I prefix
+ STRING(REGEX MATCHALL "-I[^;]+"
+ wxWidgets_INCLUDE_DIRS "${wxWidgets_CXX_FLAGS}")
+ STRING(REGEX REPLACE "-I[^;]+;" ""
+ wxWidgets_CXX_FLAGS "${wxWidgets_CXX_FLAGS}")
+ STRING(REPLACE "-I" ""
+ wxWidgets_INCLUDE_DIRS "${wxWidgets_INCLUDE_DIRS}")
+
+ DBG_MSG_V("wxWidgets_DEFINITIONS=${wxWidgets_DEFINITIONS}")
+ DBG_MSG_V("wxWidgets_INCLUDE_DIRS=${wxWidgets_INCLUDE_DIRS}")
+ DBG_MSG_V("wxWidgets_CXX_FLAGS=${wxWidgets_CXX_FLAGS}")
+
+ ELSE(RET EQUAL 0)
+ SET(wxWidgets_FOUND FALSE)
+ DBG_MSG_V(
+ "${wxWidgets_CONFIG_EXECUTABLE} --cxxflags FAILED with RET=${RET}")
+ ENDIF(RET EQUAL 0)
+
+ # run the wx-config program to get the libs
+ # - NOTE: wx-config doesn't verify that the libs requested exist
+ # it just produces the names. Maybe a TRY_COMPILE would
+ # be useful here...
+ STRING(REPLACE ";" ","
+ wxWidgets_FIND_COMPONENTS "${wxWidgets_FIND_COMPONENTS}")
+ EXECUTE_PROCESS(
+ COMMAND sh "${wxWidgets_CONFIG_EXECUTABLE}"
+ ${wxWidgets_SELECT_OPTIONS} --libs ${wxWidgets_FIND_COMPONENTS}
+ OUTPUT_VARIABLE wxWidgets_LIBRARIES
+ RESULT_VARIABLE RET
+ ERROR_QUIET
+ )
+ IF(RET EQUAL 0)
+ STRING(STRIP "${wxWidgets_LIBRARIES}" wxWidgets_LIBRARIES)
+ SEPARATE_ARGUMENTS(wxWidgets_LIBRARIES)
+ STRING(REPLACE "-framework;" "-framework "
+ wxWidgets_LIBRARIES "${wxWidgets_LIBRARIES}")
+ STRING(REPLACE "-arch;" "-arch "
+ wxWidgets_LIBRARIES "${wxWidgets_LIBRARIES}")
+ STRING(REPLACE "-isysroot;" "-isysroot "
+ wxWidgets_LIBRARIES "${wxWidgets_LIBRARIES}")
+
+ # extract linkdirs (-L) for rpath (i.e., LINK_DIRECTORIES)
+ STRING(REGEX MATCHALL "-L[^;]+"
+ wxWidgets_LIBRARY_DIRS "${wxWidgets_LIBRARIES}")
+ STRING(REPLACE "-L" ""
+ wxWidgets_LIBRARY_DIRS "${wxWidgets_LIBRARY_DIRS}")
+
+ DBG_MSG_V("wxWidgets_LIBRARIES=${wxWidgets_LIBRARIES}")
+ DBG_MSG_V("wxWidgets_LIBRARY_DIRS=${wxWidgets_LIBRARY_DIRS}")
+
+ ELSE(RET EQUAL 0)
+ SET(wxWidgets_FOUND FALSE)
+ DBG_MSG("${wxWidgets_CONFIG_EXECUTABLE} --libs ${wxWidgets_FIND_COMPONENTS} FAILED with RET=${RET}")
+ ENDIF(RET EQUAL 0)
+ ENDIF(wxWidgets_CONFIG_EXECUTABLE)
+
+#=====================================================================
+# Neither UNIX_FIND_STYLE, nor WIN32_FIND_STYLE
+#=====================================================================
+ ELSE(wxWidgets_FIND_STYLE STREQUAL "unix")
+ IF(NOT wxWidgets_FIND_QUIETLY)
+ MESSAGE(STATUS
+ "${CMAKE_CURRENT_LIST_FILE}(${CMAKE_CURRENT_LIST_LINE}): \n"
+ " Platform unknown/unsupported. It's neither WIN32 nor UNIX "
+ "find style."
+ )
+ ENDIF(NOT wxWidgets_FIND_QUIETLY)
+ ENDIF(wxWidgets_FIND_STYLE STREQUAL "unix")
+ENDIF(wxWidgets_FIND_STYLE STREQUAL "win32")
+
+# Debug output:
+DBG_MSG("wxWidgets_FOUND : ${wxWidgets_FOUND}")
+DBG_MSG("wxWidgets_INCLUDE_DIRS : ${wxWidgets_INCLUDE_DIRS}")
+DBG_MSG("wxWidgets_LIBRARY_DIRS : ${wxWidgets_LIBRARY_DIRS}")
+DBG_MSG("wxWidgets_LIBRARIES : ${wxWidgets_LIBRARIES}")
+DBG_MSG("wxWidgets_CXX_FLAGS : ${wxWidgets_CXX_FLAGS}")
+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})
+
+#=====================================================================
+# Macros for use in wxWidgets apps.
+# - This module will not fail to find wxWidgets based on the code
+# below. Hence, it's required to check for validity of:
+#
+# wxWidgets_wxrc_EXECUTABLE
+#=====================================================================
+
+# Resource file compiler.
+FIND_PROGRAM(wxWidgets_wxrc_EXECUTABLE wxrc
+ ${wxWidgets_ROOT_DIR}/utils/wxrc/vc_msw
+ )
+
+#
+# WX_SPLIT_ARGUMENTS_ON(<keyword> <left> <right> <arg1> <arg2> ...)
+#
+# Sets <left> and <right> to contain arguments to the left and right,
+# respectively, of <keyword>.
+#
+# Example usage:
+# FUNCTION(WXWIDGETS_ADD_RESOURCES outfiles)
+# WX_SPLIT_ARGUMENTS_ON(OPTIONS wxrc_files wxrc_options ${ARGN})
+# ...
+# ENDFUNCTION(WXWIDGETS_ADD_RESOURCES)
+#
+# WXWIDGETS_ADD_RESOURCES(sources ${xrc_files} OPTIONS -e -o file.C)
+#
+# NOTE: This is a generic piece of code that should be renamed to
+# SPLIT_ARGUMENTS_ON and put in a file serving the same purpose as
+# FindPackageStandardArgs.cmake. At the time of this writing
+# FindQt4.cmake has a QT4_EXTRACT_OPTIONS, which I basically copied
+# here a bit more generalized. So, there are already two find modules
+# using this approach.
+#
+FUNCTION(WX_SPLIT_ARGUMENTS_ON _keyword _leftvar _rightvar)
+ # FIXME: Document that the input variables will be cleared.
+ #LIST(APPEND ${_leftvar} "")
+ #LIST(APPEND ${_rightvar} "")
+ SET(${_leftvar} "")
+ SET(${_rightvar} "")
+
+ SET(_doing_right FALSE)
+ FOREACH(element ${ARGN})
+ IF("${element}" STREQUAL "${_keyword}")
+ SET(_doing_right TRUE)
+ ELSE("${element}" STREQUAL "${_keyword}")
+ IF(_doing_right)
+ LIST(APPEND ${_rightvar} "${element}")
+ ELSE(_doing_right)
+ LIST(APPEND ${_leftvar} "${element}")
+ ENDIF(_doing_right)
+ ENDIF("${element}" STREQUAL "${_keyword}")
+ ENDFOREACH(element)
+
+ SET(${_leftvar} ${${_leftvar}} PARENT_SCOPE)
+ SET(${_rightvar} ${${_rightvar}} PARENT_SCOPE)
+ENDFUNCTION(WX_SPLIT_ARGUMENTS_ON)
+
+#
+# WX_GET_DEPENDENCIES_FROM_XML(
+# <depends>
+# <match_pattern>
+# <clean_pattern>
+# <xml_contents>
+# <depends_path>
+# )
+#
+# FIXME: Add documentation here...
+#
+FUNCTION(WX_GET_DEPENDENCIES_FROM_XML
+ _depends
+ _match_patt
+ _clean_patt
+ _xml_contents
+ _depends_path
+ )
+
+ STRING(REGEX MATCHALL
+ ${_match_patt}
+ dep_file_list
+ "${${_xml_contents}}"
+ )
+ FOREACH(dep_file ${dep_file_list})
+ STRING(REGEX REPLACE ${_clean_patt} "" dep_file "${dep_file}")
+
+ # make the file have an absolute path
+ IF(NOT IS_ABSOLUTE "${dep_file}")
+ SET(dep_file "${${_depends_path}}/${dep_file}")
+ ENDIF(NOT IS_ABSOLUTE "${dep_file}")
+
+ # append file to dependency list
+ LIST(APPEND ${_depends} "${dep_file}")
+ ENDFOREACH(dep_file)
+
+ SET(${_depends} ${${_depends}} PARENT_SCOPE)
+ENDFUNCTION(WX_GET_DEPENDENCIES_FROM_XML)
+
+#
+# WXWIDGETS_ADD_RESOURCES(<sources> <xrc_files>
+# OPTIONS <options> [NO_CPP_CODE])
+#
+# Adds a custom command for resource file compilation of the
+# <xrc_files> and appends the output files to <sources>.
+#
+# Example usages:
+# WXWIDGETS_ADD_RESOURCES(sources xrc/main_frame.xrc)
+# WXWIDGETS_ADD_RESOURCES(sources ${xrc_files} OPTIONS -e -o altname.cxx)
+#
+FUNCTION(WXWIDGETS_ADD_RESOURCES _outfiles)
+ WX_SPLIT_ARGUMENTS_ON(OPTIONS rc_file_list rc_options ${ARGN})
+
+ # Parse files for dependencies.
+ SET(rc_file_list_abs "")
+ SET(rc_depends "")
+ FOREACH(rc_file ${rc_file_list})
+ GET_FILENAME_COMPONENT(depends_path ${rc_file} PATH)
+
+ GET_FILENAME_COMPONENT(rc_file_abs ${rc_file} ABSOLUTE)
+ LIST(APPEND rc_file_list_abs "${rc_file_abs}")
+
+ # All files have absolute paths or paths relative to the location
+ # of the rc file.
+ FILE(READ "${rc_file_abs}" rc_file_contents)
+
+ # get bitmap/bitmap2 files
+ WX_GET_DEPENDENCIES_FROM_XML(
+ rc_depends
+ "<bitmap[^<]+"
+ "^<bitmap[^>]*>"
+ rc_file_contents
+ depends_path
+ )
+
+ # get url files
+ WX_GET_DEPENDENCIES_FROM_XML(
+ rc_depends
+ "<url[^<]+"
+ "^<url[^>]*>"
+ rc_file_contents
+ depends_path
+ )
+
+ # get wxIcon files
+ WX_GET_DEPENDENCIES_FROM_XML(
+ rc_depends
+ "<object[^>]*class=\"wxIcon\"[^<]+"
+ "^<object[^>]*>"
+ rc_file_contents
+ depends_path
+ )
+ ENDFOREACH(rc_file)
+
+ #
+ # Parse options.
+ #
+ # If NO_CPP_CODE option specified, then produce .xrs file rather
+ # than a .cpp file (i.e., don't add the default --cpp-code option).
+ LIST(FIND rc_options NO_CPP_CODE index)
+ IF(index EQUAL -1)
+ LIST(APPEND rc_options --cpp-code)
+ # wxrc's default output filename for cpp code.
+ SET(outfile resource.cpp)
+ ELSE(index EQUAL -1)
+ LIST(REMOVE_AT rc_options ${index})
+ # wxrc's default output filename for xrs file.
+ SET(outfile resource.xrs)
+ ENDIF(index EQUAL -1)
+
+ # Get output name for use in ADD_CUSTOM_COMMAND.
+ # - short option scanning
+ LIST(FIND rc_options -o index)
+ IF(NOT index EQUAL -1)
+ MATH(EXPR filename_index "${index} + 1")
+ LIST(GET rc_options ${filename_index} outfile)
+ #LIST(REMOVE_AT rc_options ${index} ${filename_index})
+ ENDIF(NOT index EQUAL -1)
+ # - long option scanning
+ STRING(REGEX MATCH "--output=[^;]*" outfile_opt "${rc_options}")
+ IF(outfile_opt)
+ STRING(REPLACE "--output=" "" outfile "${outfile_opt}")
+ ENDIF(outfile_opt)
+ #STRING(REGEX REPLACE "--output=[^;]*;?" "" rc_options "${rc_options}")
+ #STRING(REGEX REPLACE ";$" "" rc_options "${rc_options}")
+
+ IF(NOT IS_ABSOLUTE "${outfile}")
+ SET(outfile "${CMAKE_CURRENT_BINARY_DIR}/${outfile}")
+ ENDIF(NOT IS_ABSOLUTE "${outfile}")
+ ADD_CUSTOM_COMMAND(
+ OUTPUT "${outfile}"
+ COMMAND ${wxWidgets_wxrc_EXECUTABLE} ${rc_options} ${rc_file_list_abs}
+ DEPENDS ${rc_file_list_abs} ${rc_depends}
+ )
+
+ # Add generated header to output file list.
+ LIST(FIND rc_options -e short_index)
+ LIST(FIND rc_options --extra-cpp-code long_index)
+ IF(NOT short_index EQUAL -1 OR NOT long_index EQUAL -1)
+ GET_FILENAME_COMPONENT(outfile_ext ${outfile} EXT)
+ STRING(REPLACE "${outfile_ext}" ".h" outfile_header "${outfile}")
+ LIST(APPEND ${_outfiles} "${outfile_header}")
+ SET_SOURCE_FILES_PROPERTIES(
+ "${outfile_header}" PROPERTIES GENERATED TRUE
+ )
+ ENDIF(NOT short_index EQUAL -1 OR NOT long_index EQUAL -1)
+
+ # Add generated file to output file list.
+ LIST(APPEND ${_outfiles} "${outfile}")
+
+ SET(${_outfiles} ${${_outfiles}} PARENT_SCOPE)
+ENDFUNCTION(WXWIDGETS_ADD_RESOURCES)
diff --git a/Modules/FindwxWindows.cmake b/Modules/FindwxWindows.cmake
new file mode 100644
index 000000000..dfb28ff90
--- /dev/null
+++ b/Modules/FindwxWindows.cmake
@@ -0,0 +1,706 @@
+# - 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++
+#
+# For convenience include Use_wxWindows.cmake in your project's
+# CMakeLists.txt using INCLUDE(Use_wxWindows).
+#
+# 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
+#
+# DEPRECATED
+#
+# 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)
+
+#=============================================================================
+# Copyright 2000-2009 Kitware, Inc.
+# Copyright 2003-2006 Jan Woetzel
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software 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.)
+
+# ------------------------------------------------------------------
+#
+# -removed OPTION for CMAKE_WXWINDOWS_USE_GL. Force the developer to SET it before calling this.
+# -major update for wx 2.6.2 and monolithic build option. (10/2005)
+#
+# STATUS
+# tested with:
+# cmake 1.6.7, Linux (Suse 7.3), wxWindows 2.4.0, gcc 2.95
+# cmake 1.6.7, Linux (Suse 8.2), wxWindows 2.4.0, gcc 3.3
+# cmake 1.6.7, Linux (Suse 8.2), wxWindows 2.4.1-patch1, gcc 3.3
+# cmake 1.6.7, MS Windows XP home, wxWindows 2.4.1, MS Visual Studio .net 7 2002 (static build)
+# cmake 2.0.5 on Windows XP and Suse Linux 9.2
+# cmake 2.0.6 on Windows XP and Suse Linux 9.2, wxWidgets 2.6.2 MONOLITHIC build
+# cmake 2.2.2 on Windows XP, MS Visual Studio .net 2003 7.1 wxWidgets 2.6.2 MONOLITHIC build
+#
+# TODO
+# -OPTION for unicode builds
+# -further testing of DLL linking under MS WIN32
+# -better support for non-monolithic builds
+#
+
+
+IF(WIN32)
+ SET(WIN32_STYLE_FIND 1)
+ENDIF(WIN32)
+IF(MINGW)
+ SET(WIN32_STYLE_FIND 0)
+ SET(UNIX_STYLE_FIND 1)
+ENDIF(MINGW)
+IF(UNIX)
+ SET(UNIX_STYLE_FIND 1)
+ENDIF(UNIX)
+
+
+IF(WIN32_STYLE_FIND)
+
+ ## ######################################################################
+ ##
+ ## Windows specific:
+ ##
+ ## candidates for root/base directory of wxwindows
+ ## should have subdirs include and lib containing include/wx/wx.h
+ ## fix the root dir to avoid mixing of headers/libs from different
+ ## versions/builds:
+
+ SET (WXWINDOWS_POSSIBLE_ROOT_PATHS
+ $ENV{WXWIN}
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\wxWidgets_is1;Inno Setup: App Path]" ## WX 2.6.x
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\wxWindows_is1;Inno Setup: App Path]" ## WX 2.4.x
+ C:\\wxWidgets-2.6.2
+ D:\\wxWidgets-2.6.2
+ C:\\wxWidgets-2.6.1
+ D:\\wxWidgets-2.6.1
+ C:\\wxWindows-2.4.2
+ D:\\wxWindows-2.4.2
+ )
+
+ ## WX supports monolithic and multiple smaller libs (since 2.5.x), we prefer monolithic for now.
+ ## monolithic = WX is built as a single big library
+ ## e.g. compile on WIN32 as "nmake -f makefile.vc MONOLITHIC=1 BUILD=debug SHARED=0 USE_OPENGL=1" (JW)
+ OPTION(WXWINDOWS_USE_MONOLITHIC "Use monolithic build of WX??" ON)
+ MARK_AS_ADVANCED(WXWINDOWS_USE_MONOLITHIC)
+
+ ## GL libs used?
+ OPTION(WXWINDOWS_USE_GL "Use Wx with GL support(glcanvas)?" ON)
+ MARK_AS_ADVANCED(WXWINDOWS_USE_GL)
+
+
+ ## avoid mixing of headers and libs between multiple installed WX versions,
+ ## select just one tree here:
+ FIND_PATH(WXWINDOWS_ROOT_DIR include/wx/wx.h
+ ${WXWINDOWS_POSSIBLE_ROOT_PATHS} )
+ # MESSAGE("DBG found WXWINDOWS_ROOT_DIR: ${WXWINDOWS_ROOT_DIR}")
+
+
+ ## find libs for combination of static/shared with release/debug
+ ## be careful if you add something here,
+ ## avoid mixing of headers and libs of different wx versions,
+ ## there may be multiple WX versions installed.
+ SET (WXWINDOWS_POSSIBLE_LIB_PATHS
+ "${WXWINDOWS_ROOT_DIR}/lib"
+ )
+
+ ## monolithic?
+ IF (WXWINDOWS_USE_MONOLITHIC)
+
+ FIND_LIBRARY(WXWINDOWS_STATIC_LIBRARY
+ NAMES wx wxmsw wxmsw26
+ PATHS
+ "${WXWINDOWS_ROOT_DIR}/lib/vc_lib"
+ ${WXWINDOWS_POSSIBLE_LIB_PATHS}
+ DOC "wxWindows static release build library" )
+
+ FIND_LIBRARY(WXWINDOWS_STATIC_DEBUG_LIBRARY
+ NAMES wxd wxmswd wxmsw26d
+ PATHS
+ "${WXWINDOWS_ROOT_DIR}/lib/vc_lib"
+ ${WXWINDOWS_POSSIBLE_LIB_PATHS}
+ DOC "wxWindows static debug build library" )
+
+ FIND_LIBRARY(WXWINDOWS_SHARED_LIBRARY
+ NAMES wxmsw26 wxmsw262 wxmsw24 wxmsw242 wxmsw241 wxmsw240 wx23_2 wx22_9
+ PATHS
+ "${WXWINDOWS_ROOT_DIR}/lib/vc_dll"
+ ${WXWINDOWS_POSSIBLE_LIB_PATHS}
+ DOC "wxWindows shared release build library" )
+
+ FIND_LIBRARY(WXWINDOWS_SHARED_DEBUG_LIBRARY
+ NAMES wxmsw26d wxmsw262d wxmsw24d wxmsw241d wxmsw240d wx23_2d wx22_9d
+ PATHS
+ "${WXWINDOWS_ROOT_DIR}/lib/vc_dll"
+ ${WXWINDOWS_POSSIBLE_LIB_PATHS}
+ DOC "wxWindows shared debug build library " )
+
+
+ ##
+ ## required for WXWINDOWS_USE_GL
+ ## gl lib is always build separate:
+ ##
+ FIND_LIBRARY(WXWINDOWS_STATIC_LIBRARY_GL
+ NAMES wx_gl wxmsw_gl wxmsw26_gl
+ PATHS
+ "${WXWINDOWS_ROOT_DIR}/lib/vc_lib"
+ ${WXWINDOWS_POSSIBLE_LIB_PATHS}
+ DOC "wxWindows static release build GL library" )
+
+ FIND_LIBRARY(WXWINDOWS_STATIC_DEBUG_LIBRARY_GL
+ NAMES wxd_gl wxmswd_gl wxmsw26d_gl
+ PATHS
+ "${WXWINDOWS_ROOT_DIR}/lib/vc_lib"
+ ${WXWINDOWS_POSSIBLE_LIB_PATHS}
+ DOC "wxWindows static debug build GL library" )
+
+
+ FIND_LIBRARY(WXWINDOWS_STATIC_DEBUG_LIBRARY_PNG
+ NAMES wxpngd
+ PATHS
+ "${WXWINDOWS_ROOT_DIR}/lib/vc_lib"
+ ${WXWINDOWS_POSSIBLE_LIB_PATHS}
+ DOC "wxWindows static debug png library" )
+
+ FIND_LIBRARY(WXWINDOWS_STATIC_LIBRARY_PNG
+ NAMES wxpng
+ PATHS
+ "${WXWINDOWS_ROOT_DIR}/lib/vc_lib"
+ ${WXWINDOWS_POSSIBLE_LIB_PATHS}
+ DOC "wxWindows static png library" )
+
+ FIND_LIBRARY(WXWINDOWS_STATIC_DEBUG_LIBRARY_TIFF
+ NAMES wxtiffd
+ PATHS
+ "${WXWINDOWS_ROOT_DIR}/lib/vc_lib"
+ ${WXWINDOWS_POSSIBLE_LIB_PATHS}
+ DOC "wxWindows static debug tiff library" )
+
+ FIND_LIBRARY(WXWINDOWS_STATIC_LIBRARY_TIFF
+ NAMES wxtiff
+ PATHS
+ "${WXWINDOWS_ROOT_DIR}/lib/vc_lib"
+ ${WXWINDOWS_POSSIBLE_LIB_PATHS}
+ DOC "wxWindows static tiff library" )
+
+ FIND_LIBRARY(WXWINDOWS_STATIC_DEBUG_LIBRARY_JPEG
+ NAMES wxjpegd wxjpgd
+ PATHS
+ "${WXWINDOWS_ROOT_DIR}/lib/vc_lib"
+ ${WXWINDOWS_POSSIBLE_LIB_PATHS}
+ DOC "wxWindows static debug jpeg library" )
+
+ FIND_LIBRARY(WXWINDOWS_STATIC_LIBRARY_JPEG
+ NAMES wxjpeg wxjpg
+ PATHS
+ "${WXWINDOWS_ROOT_DIR}/lib/vc_lib"
+ ${WXWINDOWS_POSSIBLE_LIB_PATHS}
+ DOC "wxWindows static jpeg library" )
+
+ FIND_LIBRARY(WXWINDOWS_STATIC_DEBUG_LIBRARY_ZLIB
+ NAMES wxzlibd
+ PATHS
+ "${WXWINDOWS_ROOT_DIR}/lib/vc_lib"
+ ${WXWINDOWS_POSSIBLE_LIB_PATHS}
+ DOC "wxWindows static debug zlib library" )
+
+ FIND_LIBRARY(WXWINDOWS_STATIC_LIBRARY_ZLIB
+ NAMES wxzlib
+ PATHS
+ "${WXWINDOWS_ROOT_DIR}/lib/vc_lib"
+ ${WXWINDOWS_POSSIBLE_LIB_PATHS}
+ DOC "wxWindows static zib library" )
+
+ FIND_LIBRARY(WXWINDOWS_STATIC_DEBUG_LIBRARY_REGEX
+ NAMES wxregexd
+ PATHS
+ "${WXWINDOWS_ROOT_DIR}/lib/vc_lib"
+ ${WXWINDOWS_POSSIBLE_LIB_PATHS}
+ DOC "wxWindows static debug regex library" )
+
+ FIND_LIBRARY(WXWINDOWS_STATIC_LIBRARY_REGEX
+ NAMES wxregex
+ PATHS
+ "${WXWINDOWS_ROOT_DIR}/lib/vc_lib"
+ ${WXWINDOWS_POSSIBLE_LIB_PATHS}
+ DOC "wxWindows static regex library" )
+
+
+
+ ## untested:
+ FIND_LIBRARY(WXWINDOWS_SHARED_LIBRARY_GL
+ NAMES wx_gl wxmsw_gl wxmsw26_gl
+ PATHS
+ "${WXWINDOWS_ROOT_DIR}/lib/vc_dll"
+ ${WXWINDOWS_POSSIBLE_LIB_PATHS}
+ DOC "wxWindows shared release build GL library" )
+
+ FIND_LIBRARY(WXWINDOWS_SHARED_DEBUG_LIBRARY_GL
+ NAMES wxd_gl wxmswd_gl wxmsw26d_gl
+ PATHS
+ "${WXWINDOWS_ROOT_DIR}/lib/vc_dll"
+ ${WXWINDOWS_POSSIBLE_LIB_PATHS}
+ DOC "wxWindows shared debug build GL library" )
+
+
+ ELSE (WXWINDOWS_USE_MONOLITHIC)
+ ## WX is built as multiple small pieces libraries instead of monolithic
+
+ ## DEPECATED (jw) replaced by more general WXWINDOWS_USE_MONOLITHIC ON/OFF
+ # OPTION(WXWINDOWS_SEPARATE_LIBS_BUILD "Is wxWindows build with separate libs?" OFF)
+
+ ## HACK: This is very dirty.
+ ## because the libs of a particular version are explicitly listed
+ ## and NOT searched/verified.
+ ## TODO: Really search for each lib, then decide for
+ ## monolithic x debug x shared x GL (=16 combinations) for at least 18 libs
+ ## --> about 288 combinations
+ ## thus we need a different approach so solve this correctly ...
+
+ MESSAGE(STATUS "Warning: You are trying to use wxWidgets without monolithic build (WXWINDOWS_SEPARATE_LIBS_BUILD). This is a HACK, libraries are not verified! (JW).")
+
+ SET(WXWINDOWS_STATIC_LIBS ${WXWINDOWS_STATIC_LIBS}
+ wxbase26
+ wxbase26_net
+ wxbase26_odbc
+ wxbase26_xml
+ wxmsw26_adv
+ wxmsw26_core
+ wxmsw26_dbgrid
+ wxmsw26_gl
+ wxmsw26_html
+ wxmsw26_media
+ wxmsw26_qa
+ wxmsw26_xrc
+ wxexpat
+ wxjpeg
+ wxpng
+ wxregex
+ wxtiff
+ wxzlib
+ comctl32
+ rpcrt4
+ wsock32
+ )
+ ## HACK: feed in to optimized / debug libaries if both were FOUND.
+ SET(WXWINDOWS_STATIC_DEBUG_LIBS ${WXWINDOWS_STATIC_DEBUG_LIBS}
+ wxbase26d
+ wxbase26d_net
+ wxbase26d_odbc
+ wxbase26d_xml
+ wxmsw26d_adv
+ wxmsw26d_core
+ wxmsw26d_dbgrid
+ wxmsw26d_gl
+ wxmsw26d_html
+ wxmsw26d_media
+ wxmsw26d_qa
+ wxmsw26d_xrc
+ wxexpatd
+ wxjpegd
+ wxpngd
+ wxregexd
+ wxtiffd
+ wxzlibd
+ comctl32
+ rpcrt4
+ wsock32
+ )
+ ENDIF (WXWINDOWS_USE_MONOLITHIC)
+
+
+ ##
+ ## now we should have found all WX libs available on the system.
+ ## let the user decide which of the available onse to use.
+ ##
+
+ ## if there is at least one shared lib available
+ ## let user choose wether to use shared or static wxwindows libs
+ IF(WXWINDOWS_SHARED_LIBRARY OR WXWINDOWS_SHARED_DEBUG_LIBRARY)
+ ## default value OFF because wxWindows MSVS default build is static
+ OPTION(WXWINDOWS_USE_SHARED_LIBS
+ "Use shared versions (dll) of wxWindows libraries?" OFF)
+ MARK_AS_ADVANCED(WXWINDOWS_USE_SHARED_LIBS)
+ ENDIF(WXWINDOWS_SHARED_LIBRARY OR WXWINDOWS_SHARED_DEBUG_LIBRARY)
+
+ ## add system libraries wxwindows always seems to depend on
+ SET(WXWINDOWS_LIBRARIES ${WXWINDOWS_LIBRARIES}
+ comctl32
+ rpcrt4
+ wsock32
+ )
+
+ IF (NOT WXWINDOWS_USE_SHARED_LIBS)
+ SET(WXWINDOWS_LIBRARIES ${WXWINDOWS_LIBRARIES}
+ ## these ones dont seem required, in particular ctl3d32 is not neccesary (Jan Woetzel 07/2003)
+ # ctl3d32
+ debug ${WXWINDOWS_STATIC_DEBUG_LIBRARY_ZLIB} optimized ${WXWINDOWS_STATIC_LIBRARY_ZLIB}
+ debug ${WXWINDOWS_STATIC_DEBUG_LIBRARY_REGEX} optimized ${WXWINDOWS_STATIC_LIBRARY_REGEX}
+ debug ${WXWINDOWS_STATIC_DEBUG_LIBRARY_PNG} optimized ${WXWINDOWS_STATIC_LIBRARY_PNG}
+ debug ${WXWINDOWS_STATIC_DEBUG_LIBRARY_JPEG} optimized ${WXWINDOWS_STATIC_LIBRARY_JPEG}
+ debug ${WXWINDOWS_STATIC_DEBUG_LIBRARY_TIFF} optimized ${WXWINDOWS_STATIC_LIBRARY_TIFF}
+ )
+ ENDIF (NOT WXWINDOWS_USE_SHARED_LIBS)
+
+ ## opengl/glu: TODO/FIXME: better use FindOpenGL.cmake here
+ ## assume release versions of glu an dopengl, here.
+ IF (WXWINDOWS_USE_GL)
+ SET(WXWINDOWS_LIBRARIES ${WXWINDOWS_LIBRARIES}
+ opengl32
+ glu32 )
+ ENDIF (WXWINDOWS_USE_GL)
+
+ ##
+ ## select between use of shared or static wxWindows lib then set libs to use
+ ## for debug and optimized build. so the user can switch between debug and
+ ## release build e.g. within MS Visual Studio without running cmake with a
+ ## different build directory again.
+ ##
+ ## then add the build specific include dir for wx/setup.h
+ ##
+
+ IF(WXWINDOWS_USE_SHARED_LIBS)
+ ##MESSAGE("DBG wxWindows use shared lib selected.")
+ ## assume that both builds use the same setup(.h) for simplicity
+
+ ## shared: both wx (debug and release) found?
+ ## assume that both builds use the same setup(.h) for simplicity
+ IF(WXWINDOWS_SHARED_DEBUG_LIBRARY AND WXWINDOWS_SHARED_LIBRARY)
+ ##MESSAGE("DBG wx shared: debug and optimized found.")
+ FIND_PATH(WXWINDOWS_INCLUDE_DIR_SETUPH wx/setup.h
+ ${WXWINDOWS_ROOT_DIR}/lib/mswdlld
+ ${WXWINDOWS_ROOT_DIR}/lib/mswdll
+ ${WXWINDOWS_ROOT_DIR}/lib/vc_dll/mswd
+ ${WXWINDOWS_ROOT_DIR}/lib/vc_dll/msw )
+ SET(WXWINDOWS_LIBRARIES ${WXWINDOWS_LIBRARIES}
+ debug ${WXWINDOWS_SHARED_DEBUG_LIBRARY}
+ optimized ${WXWINDOWS_SHARED_LIBRARY} )
+ IF (WXWINDOWS_USE_GL)
+ SET(WXWINDOWS_LIBRARIES ${WXWINDOWS_LIBRARIES}
+ debug ${WXWINDOWS_SHARED_DEBUG_LIBRARY_GL}
+ optimized ${WXWINDOWS_SHARED_LIBRARY_GL} )
+ ENDIF (WXWINDOWS_USE_GL)
+ ENDIF(WXWINDOWS_SHARED_DEBUG_LIBRARY AND WXWINDOWS_SHARED_LIBRARY)
+
+ ## shared: only debug wx lib found?
+ IF(WXWINDOWS_SHARED_DEBUG_LIBRARY)
+ IF(NOT WXWINDOWS_SHARED_LIBRARY)
+ ##MESSAGE("DBG wx shared: debug (but no optimized) found.")
+ FIND_PATH(WXWINDOWS_INCLUDE_DIR_SETUPH wx/setup.h
+ ${WXWINDOWS_ROOT_DIR}/lib/mswdlld
+ ${WXWINDOWS_ROOT_DIR}/lib/vc_dll/mswd )
+ SET(WXWINDOWS_LIBRARIES ${WXWINDOWS_LIBRARIES}
+ ${WXWINDOWS_SHARED_DEBUG_LIBRARY} )
+ IF (WXWINDOWS_USE_GL)
+ SET(WXWINDOWS_LIBRARIES ${WXWINDOWS_LIBRARIES}
+ ${WXWINDOWS_SHARED_DEBUG_LIBRARY_GL} )
+ ENDIF (WXWINDOWS_USE_GL)
+ ENDIF(NOT WXWINDOWS_SHARED_LIBRARY)
+ ENDIF(WXWINDOWS_SHARED_DEBUG_LIBRARY)
+
+ ## shared: only release wx lib found?
+ IF(NOT WXWINDOWS_SHARED_DEBUG_LIBRARY)
+ IF(WXWINDOWS_SHARED_LIBRARY)
+ ##MESSAGE("DBG wx shared: optimized (but no debug) found.")
+ FIND_PATH(WXWINDOWS_INCLUDE_DIR_SETUPH wx/setup.h
+ ${WXWINDOWS_ROOT_DIR}/lib/mswdll
+ ${WXWINDOWS_ROOT_DIR}/lib/vc_dll/msw )
+ SET(WXWINDOWS_LIBRARIES ${WXWINDOWS_LIBRARIES}
+ ${WXWINDOWS_SHARED_DEBUG_LIBRARY} )
+ IF (WXWINDOWS_USE_GL)
+ SET(WXWINDOWS_LIBRARIES ${WXWINDOWS_LIBRARIES}
+ ${WXWINDOWS_SHARED_DEBUG_LIBRARY_GL} )
+ ENDIF (WXWINDOWS_USE_GL)
+ ENDIF(WXWINDOWS_SHARED_LIBRARY)
+ ENDIF(NOT WXWINDOWS_SHARED_DEBUG_LIBRARY)
+
+ ## shared: none found?
+ IF(NOT WXWINDOWS_SHARED_DEBUG_LIBRARY)
+ IF(NOT WXWINDOWS_SHARED_LIBRARY)
+ MESSAGE(STATUS
+ "No shared wxWindows lib found, but WXWINDOWS_USE_SHARED_LIBS=${WXWINDOWS_USE_SHARED_LIBS}.")
+ ENDIF(NOT WXWINDOWS_SHARED_LIBRARY)
+ ENDIF(NOT WXWINDOWS_SHARED_DEBUG_LIBRARY)
+
+ #########################################################################################
+ ELSE(WXWINDOWS_USE_SHARED_LIBS)
+
+ ##jw: DEPRECATED IF(NOT WXWINDOWS_SEPARATE_LIBS_BUILD)
+
+ ## static: both wx (debug and release) found?
+ ## assume that both builds use the same setup(.h) for simplicity
+ IF(WXWINDOWS_STATIC_DEBUG_LIBRARY AND WXWINDOWS_STATIC_LIBRARY)
+ ##MESSAGE("DBG wx static: debug and optimized found.")
+ FIND_PATH(WXWINDOWS_INCLUDE_DIR_SETUPH wx/setup.h
+ ${WXWINDOWS_ROOT_DIR}/lib/mswd
+ ${WXWINDOWS_ROOT_DIR}/lib/msw
+ ${WXWINDOWS_ROOT_DIR}/lib/vc_lib/mswd
+ ${WXWINDOWS_ROOT_DIR}/lib/vc_lib/msw )
+ SET(WXWINDOWS_LIBRARIES ${WXWINDOWS_LIBRARIES}
+ debug ${WXWINDOWS_STATIC_DEBUG_LIBRARY}
+ optimized ${WXWINDOWS_STATIC_LIBRARY} )
+ IF (WXWINDOWS_USE_GL)
+ SET(WXWINDOWS_LIBRARIES ${WXWINDOWS_LIBRARIES}
+ debug ${WXWINDOWS_STATIC_DEBUG_LIBRARY_GL}
+ optimized ${WXWINDOWS_STATIC_LIBRARY_GL} )
+ ENDIF (WXWINDOWS_USE_GL)
+ ENDIF(WXWINDOWS_STATIC_DEBUG_LIBRARY AND WXWINDOWS_STATIC_LIBRARY)
+
+ ## static: only debug wx lib found?
+ IF(WXWINDOWS_STATIC_DEBUG_LIBRARY)
+ IF(NOT WXWINDOWS_STATIC_LIBRARY)
+ ##MESSAGE("DBG wx static: debug (but no optimized) found.")
+ FIND_PATH(WXWINDOWS_INCLUDE_DIR_SETUPH wx/setup.h
+ ${WXWINDOWS_ROOT_DIR}/lib/mswd
+ ${WXWINDOWS_ROOT_DIR}/lib/vc_lib/mswd )
+ SET(WXWINDOWS_LIBRARIES ${WXWINDOWS_LIBRARIES}
+ ${WXWINDOWS_STATIC_DEBUG_LIBRARY} )
+ IF (WXWINDOWS_USE_GL)
+ SET(WXWINDOWS_LIBRARIES ${WXWINDOWS_LIBRARIES}
+ ${WXWINDOWS_STATIC_DEBUG_LIBRARY_GL} )
+ ENDIF (WXWINDOWS_USE_GL)
+ ENDIF(NOT WXWINDOWS_STATIC_LIBRARY)
+ ENDIF(WXWINDOWS_STATIC_DEBUG_LIBRARY)
+
+ ## static: only release wx lib found?
+ IF(NOT WXWINDOWS_STATIC_DEBUG_LIBRARY)
+ IF(WXWINDOWS_STATIC_LIBRARY)
+ ##MESSAGE("DBG wx static: optimized (but no debug) found.")
+ FIND_PATH(WXWINDOWS_INCLUDE_DIR_SETUPH wx/setup.h
+ ${WXWINDOWS_ROOT_DIR}/lib/msw
+ ${WXWINDOWS_ROOT_DIR}/lib/vc_lib/msw )
+ SET(WXWINDOWS_LIBRARIES ${WXWINDOWS_LIBRARIES}
+ ${WXWINDOWS_STATIC_LIBRARY} )
+ IF (WXWINDOWS_USE_GL)
+ SET(WXWINDOWS_LIBRARIES ${WXWINDOWS_LIBRARIES}
+ ${WXWINDOWS_STATIC_LIBRARY_GL} )
+ ENDIF (WXWINDOWS_USE_GL)
+ ENDIF(WXWINDOWS_STATIC_LIBRARY)
+ ENDIF(NOT WXWINDOWS_STATIC_DEBUG_LIBRARY)
+
+ ## static: none found?
+ IF(NOT WXWINDOWS_STATIC_DEBUG_LIBRARY AND NOT WXWINDOWS_SEPARATE_LIBS_BUILD)
+ IF(NOT WXWINDOWS_STATIC_LIBRARY)
+ MESSAGE(STATUS
+ "No static wxWindows lib found, but WXWINDOWS_USE_SHARED_LIBS=${WXWINDOWS_USE_SHARED_LIBS}.")
+ ENDIF(NOT WXWINDOWS_STATIC_LIBRARY)
+ ENDIF(NOT WXWINDOWS_STATIC_DEBUG_LIBRARY AND NOT WXWINDOWS_SEPARATE_LIBS_BUILD)
+ ENDIF(WXWINDOWS_USE_SHARED_LIBS)
+
+
+ ## not neccessary in wxWindows 2.4.1 and 2.6.2
+ ## but it may fix a previous bug, see
+ ## http://lists.wxwindows.org/cgi-bin/ezmlm-cgi?8:mss:37574:200305:mpdioeneabobmgjenoap
+ OPTION(WXWINDOWS_SET_DEFINITIONS "Set additional defines for wxWindows" OFF)
+ MARK_AS_ADVANCED(WXWINDOWS_SET_DEFINITIONS)
+ IF (WXWINDOWS_SET_DEFINITIONS)
+ SET(WXWINDOWS_DEFINITIONS "-DWINVER=0x400")
+ ELSE (WXWINDOWS_SET_DEFINITIONS)
+ # clear:
+ SET(WXWINDOWS_DEFINITIONS "")
+ ENDIF (WXWINDOWS_SET_DEFINITIONS)
+
+
+
+ ## Find the include directories for wxwindows
+ ## the first, build specific for wx/setup.h was determined before.
+ ## add inc dir for general for "wx/wx.h"
+ FIND_PATH(WXWINDOWS_INCLUDE_DIR wx/wx.h
+ "${WXWINDOWS_ROOT_DIR}/include" )
+ ## append the build specific include dir for wx/setup.h:
+ IF (WXWINDOWS_INCLUDE_DIR_SETUPH)
+ SET(WXWINDOWS_INCLUDE_DIR ${WXWINDOWS_INCLUDE_DIR} ${WXWINDOWS_INCLUDE_DIR_SETUPH} )
+ ENDIF (WXWINDOWS_INCLUDE_DIR_SETUPH)
+
+
+
+ MARK_AS_ADVANCED(
+ WXWINDOWS_ROOT_DIR
+ WXWINDOWS_INCLUDE_DIR
+ WXWINDOWS_INCLUDE_DIR_SETUPH
+ WXWINDOWS_STATIC_LIBRARY
+ WXWINDOWS_STATIC_LIBRARY_GL
+ WXWINDOWS_STATIC_DEBUG_LIBRARY
+ WXWINDOWS_STATIC_DEBUG_LIBRARY_GL
+ WXWINDOWS_STATIC_LIBRARY_ZLIB
+ WXWINDOWS_STATIC_DEBUG_LIBRARY_ZLIB
+ WXWINDOWS_STATIC_LIBRARY_REGEX
+ WXWINDOWS_STATIC_DEBUG_LIBRARY_REGEX
+ WXWINDOWS_STATIC_LIBRARY_PNG
+ WXWINDOWS_STATIC_DEBUG_LIBRARY_PNG
+ WXWINDOWS_STATIC_LIBRARY_JPEG
+ WXWINDOWS_STATIC_DEBUG_LIBRARY_JPEG
+ WXWINDOWS_STATIC_DEBUG_LIBRARY_TIFF
+ WXWINDOWS_STATIC_LIBRARY_TIFF
+ WXWINDOWS_SHARED_LIBRARY
+ WXWINDOWS_SHARED_DEBUG_LIBRARY
+ WXWINDOWS_SHARED_LIBRARY_GL
+ WXWINDOWS_SHARED_DEBUG_LIBRARY_GL
+ )
+
+
+ELSE(WIN32_STYLE_FIND)
+
+ IF (UNIX_STYLE_FIND)
+ ## ######################################################################
+ ##
+ ## UNIX/Linux specific:
+ ##
+ ## use backquoted wx-config to query and set flags and libs:
+ ## 06/2003 Jan Woetzel
+ ##
+
+ OPTION(WXWINDOWS_USE_SHARED_LIBS "Use shared versions (.so) of wxWindows libraries" ON)
+ MARK_AS_ADVANCED(WXWINDOWS_USE_SHARED_LIBS)
+
+ # JW removed option and force the develper th SET it.
+ # OPTION(WXWINDOWS_USE_GL "use wxWindows with GL support (use additional
+ # --gl-libs for wx-config)?" OFF)
+
+ # wx-config should be in your path anyhow, usually no need to set WXWIN or
+ # search in ../wx or ../../wx
+ FIND_PROGRAM(CMAKE_WXWINDOWS_WXCONFIG_EXECUTABLE wx-config
+ $ENV{WXWIN}
+ $ENV{WXWIN}/bin
+ ../wx/bin
+ ../../wx/bin )
+
+ # check wether wx-config was found:
+ IF(CMAKE_WXWINDOWS_WXCONFIG_EXECUTABLE)
+
+ # use shared/static wx lib?
+ # remember: always link shared to use systems GL etc. libs (no static
+ # linking, just link *against* static .a libs)
+ IF(WXWINDOWS_USE_SHARED_LIBS)
+ SET(WX_CONFIG_ARGS_LIBS "--libs")
+ ELSE(WXWINDOWS_USE_SHARED_LIBS)
+ SET(WX_CONFIG_ARGS_LIBS "--static --libs")
+ ENDIF(WXWINDOWS_USE_SHARED_LIBS)
+
+ # do we need additionial wx GL stuff like GLCanvas ?
+ IF(WXWINDOWS_USE_GL)
+ SET(WX_CONFIG_ARGS_LIBS "${WX_CONFIG_ARGS_LIBS} --gl-libs" )
+ ENDIF(WXWINDOWS_USE_GL)
+ ##MESSAGE("DBG: WX_CONFIG_ARGS_LIBS=${WX_CONFIG_ARGS_LIBS}===")
+
+ # set CXXFLAGS to be fed into CMAKE_CXX_FLAGS by the user:
+ IF (HAVE_ISYSTEM) # does the compiler support -isystem ?
+ IF (NOT APPLE) # -isystem seem sto be unsuppored on Mac
+ IF(CMAKE_COMPILER_IS_GNUCC AND CMAKE_COMPILER_IS_GNUCXX )
+ IF (CMAKE_CXX_COMPILER MATCHES g\\+\\+)
+ SET(CMAKE_WXWINDOWS_CXX_FLAGS "`${CMAKE_WXWINDOWS_WXCONFIG_EXECUTABLE} --cxxflags|sed -e s/-I/-isystem/g`")
+ ELSE(CMAKE_CXX_COMPILER MATCHES g\\+\\+)
+ SET(CMAKE_WXWINDOWS_CXX_FLAGS "`${CMAKE_WXWINDOWS_WXCONFIG_EXECUTABLE} --cxxflags`")
+ ENDIF(CMAKE_CXX_COMPILER MATCHES g\\+\\+)
+ ENDIF(CMAKE_COMPILER_IS_GNUCC AND CMAKE_COMPILER_IS_GNUCXX )
+ ENDIF (NOT APPLE)
+ ENDIF (HAVE_ISYSTEM)
+ ##MESSAGE("DBG: for compilation:
+ ##CMAKE_WXWINDOWS_CXX_FLAGS=${CMAKE_WXWINDOWS_CXX_FLAGS}===")
+
+ # keep the back-quoted string for clarity
+ SET(WXWINDOWS_LIBRARIES "`${CMAKE_WXWINDOWS_WXCONFIG_EXECUTABLE} ${WX_CONFIG_ARGS_LIBS}`")
+ ##MESSAGE("DBG2: for linking:
+ ##WXWINDOWS_LIBRARIES=${WXWINDOWS_LIBRARIES}===")
+
+ # evaluate wx-config output to separate linker flags and linkdirs for
+ # rpath:
+ EXEC_PROGRAM(${CMAKE_WXWINDOWS_WXCONFIG_EXECUTABLE}
+ ARGS ${WX_CONFIG_ARGS_LIBS}
+ OUTPUT_VARIABLE WX_CONFIG_LIBS )
+
+ ## extract linkdirs (-L) for rpath
+ ## use regular expression to match wildcard equivalent "-L*<endchar>"
+ ## with <endchar> is a space or a semicolon
+ STRING(REGEX MATCHALL "[-][L]([^ ;])+" WXWINDOWS_LINK_DIRECTORIES_WITH_PREFIX "${WX_CONFIG_LIBS}" )
+ # MESSAGE("DBG WXWINDOWS_LINK_DIRECTORIES_WITH_PREFIX=${WXWINDOWS_LINK_DIRECTORIES_WITH_PREFIX}")
+
+ ## remove prefix -L because we need the pure directory for LINK_DIRECTORIES
+ ## replace -L by ; because the separator seems to be lost otherwise (bug or
+ ## feature?)
+ IF(WXWINDOWS_LINK_DIRECTORIES_WITH_PREFIX)
+ STRING(REGEX REPLACE "[-][L]" ";" WXWINDOWS_LINK_DIRECTORIES ${WXWINDOWS_LINK_DIRECTORIES_WITH_PREFIX} )
+ # MESSAGE("DBG WXWINDOWS_LINK_DIRECTORIES=${WXWINDOWS_LINK_DIRECTORIES}")
+ ENDIF(WXWINDOWS_LINK_DIRECTORIES_WITH_PREFIX)
+
+
+ ## replace space separated string by semicolon separated vector to make it
+ ## work with LINK_DIRECTORIES
+ SEPARATE_ARGUMENTS(WXWINDOWS_LINK_DIRECTORIES)
+
+ MARK_AS_ADVANCED(
+ CMAKE_WXWINDOWS_CXX_FLAGS
+ WXWINDOWS_INCLUDE_DIR
+ WXWINDOWS_LIBRARIES
+ CMAKE_WXWINDOWS_WXCONFIG_EXECUTABLE
+ )
+
+
+ ## we really need wx-config...
+ ELSE(CMAKE_WXWINDOWS_WXCONFIG_EXECUTABLE)
+ MESSAGE(STATUS "Cannot find wx-config anywhere on the system. Please put the file into your path or specify it in CMAKE_WXWINDOWS_WXCONFIG_EXECUTABLE.")
+ MARK_AS_ADVANCED(CMAKE_WXWINDOWS_WXCONFIG_EXECUTABLE)
+ ENDIF(CMAKE_WXWINDOWS_WXCONFIG_EXECUTABLE)
+
+
+
+ ELSE(UNIX_STYLE_FIND)
+ MESSAGE(STATUS "FindwxWindows.cmake: Platform unknown/unsupported by FindwxWindows.cmake. It's neither WIN32 nor UNIX")
+ ENDIF(UNIX_STYLE_FIND)
+ENDIF(WIN32_STYLE_FIND)
+
+
+IF(WXWINDOWS_LIBRARIES)
+ IF(WXWINDOWS_INCLUDE_DIR OR CMAKE_WXWINDOWS_CXX_FLAGS)
+ ## found all we need.
+ SET(WXWINDOWS_FOUND 1)
+
+ ## set deprecated variables for backward compatibility:
+ SET(CMAKE_WX_CAN_COMPILE ${WXWINDOWS_FOUND})
+ SET(WXWINDOWS_LIBRARY ${WXWINDOWS_LIBRARIES})
+ SET(WXWINDOWS_INCLUDE_PATH ${WXWINDOWS_INCLUDE_DIR})
+ SET(WXWINDOWS_LINK_DIRECTORIES ${WXWINDOWS_LINK_DIRECTORIES})
+ SET(CMAKE_WX_CXX_FLAGS ${CMAKE_WXWINDOWS_CXX_FLAGS})
+
+ ENDIF(WXWINDOWS_INCLUDE_DIR OR CMAKE_WXWINDOWS_CXX_FLAGS)
+ENDIF(WXWINDOWS_LIBRARIES)
diff --git a/Modules/FortranCInterface.cmake b/Modules/FortranCInterface.cmake
new file mode 100644
index 000000000..2455c5f8b
--- /dev/null
+++ b/Modules/FortranCInterface.cmake
@@ -0,0 +1,293 @@
+# - 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")
+# 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> ...])
+# 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()
+# 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_"
+# 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> ...
+# 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
+# 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_().
+#
+# Example usage:
+# 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.
+#
+# 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.)
+
+#=============================================================================
+# Copyright 2008-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.)
+
+#-----------------------------------------------------------------------------
+# Execute at most once in a project.
+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)
+
+#-----------------------------------------------------------------------------
+# Verify that C and Fortran are available.
+foreach(lang C Fortran)
+ if(NOT CMAKE_${lang}_COMPILER_LOADED)
+ message(FATAL_ERROR
+ "FortranCInterface requires the ${lang} language to be enabled.")
+ endif()
+endforeach()
+
+#-----------------------------------------------------------------------------
+set(FortranCInterface_SOURCE_DIR ${CMAKE_ROOT}/Modules/FortranCInterface)
+
+# MinGW's make tool does not always like () in the path
+if("${CMAKE_GENERATOR}" MATCHES "MinGW" AND
+ "${FortranCInterface_SOURCE_DIR}" MATCHES "[()]")
+ file(COPY ${FortranCInterface_SOURCE_DIR}/
+ DESTINATION ${CMAKE_BINARY_DIR}/CMakeFiles/FortranCInterfaceMinGW)
+ set(FortranCInterface_SOURCE_DIR ${CMAKE_BINARY_DIR}/CMakeFiles/FortranCInterfaceMinGW)
+endif()
+
+# Create the interface detection project if it does not exist.
+if(NOT FortranCInterface_BINARY_DIR)
+ set(FortranCInterface_BINARY_DIR ${CMAKE_BINARY_DIR}/CMakeFiles/FortranCInterface)
+ include(${FortranCInterface_SOURCE_DIR}/Detect.cmake)
+endif()
+
+# Load the detection results.
+include(${FortranCInterface_BINARY_DIR}/Output.cmake)
+
+#-----------------------------------------------------------------------------
+function(FortranCInterface_HEADER file)
+ # Parse arguments.
+ if(IS_ABSOLUTE "${file}")
+ set(FILE "${file}")
+ else()
+ set(FILE "${CMAKE_CURRENT_BINARY_DIR}/${file}")
+ endif()
+ set(MACRO_NAMESPACE "FortranCInterface_")
+ set(SYMBOL_NAMESPACE)
+ set(SYMBOLS)
+ set(doing)
+ foreach(arg ${ARGN})
+ if("x${arg}" MATCHES "^x(SYMBOLS|SYMBOL_NAMESPACE|MACRO_NAMESPACE)$")
+ set(doing "${arg}")
+ elseif("x${doing}" MATCHES "^x(SYMBOLS)$")
+ list(APPEND "${doing}" "${arg}")
+ elseif("x${doing}" MATCHES "^x(SYMBOL_NAMESPACE|MACRO_NAMESPACE)$")
+ set("${doing}" "${arg}")
+ set(doing)
+ else()
+ message(AUTHOR_WARNING "Unknown argument: \"${arg}\"")
+ endif()
+ endforeach()
+
+ # Generate macro definitions.
+ set(HEADER_CONTENT)
+ set(_desc_GLOBAL "/* Mangling for Fortran global symbols without underscores. */")
+ set(_desc_GLOBAL_ "/* Mangling for Fortran global symbols with underscores. */")
+ set(_desc_MODULE "/* Mangling for Fortran module symbols without underscores. */")
+ set(_desc_MODULE_ "/* Mangling for Fortran module symbols with underscores. */")
+ foreach(macro GLOBAL GLOBAL_ MODULE MODULE_)
+ if(FortranCInterface_${macro}_MACRO)
+ set(HEADER_CONTENT "${HEADER_CONTENT}
+${_desc_${macro}}
+#define ${MACRO_NAMESPACE}${macro}${FortranCInterface_${macro}_MACRO}
+")
+ endif()
+ endforeach()
+
+ # Generate symbol mangling definitions.
+ if(SYMBOLS)
+ set(HEADER_CONTENT "${HEADER_CONTENT}
+/*--------------------------------------------------------------------------*/
+/* Mangle some symbols automatically. */
+")
+ endif()
+ foreach(f ${SYMBOLS})
+ if("${f}" MATCHES ":")
+ # Module symbol name. Parse "<module>:<function>" syntax.
+ string(REPLACE ":" ";" pieces "${f}")
+ list(GET pieces 0 module)
+ list(GET pieces 1 function)
+ string(TOUPPER "${module}" m_upper)
+ string(TOLOWER "${module}" m_lower)
+ string(TOUPPER "${function}" f_upper)
+ string(TOLOWER "${function}" f_lower)
+ if("${function}" MATCHES "_")
+ set(form "_")
+ else()
+ set(form "")
+ endif()
+ if(FortranCInterface_MODULE${form}_MACRO)
+ set(HEADER_CONTENT "${HEADER_CONTENT}#define ${SYMBOL_NAMESPACE}${module}_${function} ${MACRO_NAMESPACE}MODULE${form}(${m_lower},${f_lower}, ${m_upper},${f_upper})\n")
+ else()
+ message(AUTHOR_WARNING "No FortranCInterface mangling known for ${f}")
+ endif()
+ else()
+ # Global symbol name.
+ if("${f}" MATCHES "_")
+ set(form "_")
+ else()
+ set(form "")
+ endif()
+ string(TOUPPER "${f}" f_upper)
+ string(TOLOWER "${f}" f_lower)
+ if(FortranCInterface_GLOBAL${form}_MACRO)
+ set(HEADER_CONTENT "${HEADER_CONTENT}#define ${SYMBOL_NAMESPACE}${f} ${MACRO_NAMESPACE}GLOBAL${form}(${f_lower}, ${f_upper})\n")
+ else()
+ message(AUTHOR_WARNING "No FortranCInterface mangling known for ${f}")
+ endif()
+ endif()
+ endforeach(f)
+
+ # Store the content.
+ configure_file(${FortranCInterface_SOURCE_DIR}/Macro.h.in ${FILE} @ONLY)
+endfunction()
+
+function(FortranCInterface_VERIFY)
+ # Check arguments.
+
+ set(lang C)
+ set(quiet 0)
+ set(verify_cxx 0)
+ foreach(arg ${ARGN})
+ if("${arg}" STREQUAL "QUIET")
+ set(quiet 1)
+ elseif("${arg}" STREQUAL "CXX")
+ set(lang CXX)
+ set(verify_cxx 1)
+ else()
+ message(FATAL_ERROR
+ "FortranCInterface_VERIFY - called with unknown argument:\n ${arg}")
+ endif()
+ endforeach()
+
+ if(NOT CMAKE_${lang}_COMPILER_LOADED)
+ message(FATAL_ERROR
+ "FortranCInterface_VERIFY(${lang}) requires ${lang} to be enabled.")
+ endif()
+
+ # Build the verification project if not yet built.
+ if(NOT DEFINED FortranCInterface_VERIFIED_${lang})
+ set(_desc "Verifying Fortran/${lang} Compiler Compatibility")
+ message(STATUS "${_desc}")
+
+ # Build a sample project which reports symbols.
+ try_compile(FortranCInterface_VERIFY_${lang}_COMPILED
+ ${FortranCInterface_BINARY_DIR}/Verify${lang}
+ ${FortranCInterface_SOURCE_DIR}/Verify
+ VerifyFortranC
+ CMAKE_FLAGS -DVERIFY_CXX=${verify_cxx}
+ -DCMAKE_VERBOSE_MAKEFILE=ON
+ "-DCMAKE_C_FLAGS:STRING=${CMAKE_C_FLAGS}"
+ "-DCMAKE_CXX_FLAGS:STRING=${CMAKE_CXX_FLAGS}"
+ "-DCMAKE_Fortran_FLAGS:STRING=${CMAKE_Fortran_FLAGS}"
+ OUTPUT_VARIABLE _output)
+ file(WRITE "${FortranCInterface_BINARY_DIR}/Verify${lang}/output.txt" "${_output}")
+
+ # Report results.
+ if(FortranCInterface_VERIFY_${lang}_COMPILED)
+ message(STATUS "${_desc} - Success")
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "${_desc} passed with the following output:\n${_output}\n\n")
+ set(FortranCInterface_VERIFIED_${lang} 1 CACHE INTERNAL "Fortran/${lang} compatibility")
+ else()
+ message(STATUS "${_desc} - Failed")
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "${_desc} failed with the following output:\n${_output}\n\n")
+ set(FortranCInterface_VERIFIED_${lang} 0 CACHE INTERNAL "Fortran/${lang} compatibility")
+ endif()
+ unset(FortranCInterface_VERIFY_${lang}_COMPILED CACHE)
+ endif()
+
+ # 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}")
+ message(FATAL_ERROR
+ "The Fortran compiler:\n ${CMAKE_Fortran_COMPILER}\n"
+ "and the ${lang} compiler:\n ${CMAKE_${lang}_COMPILER}\n"
+ "failed to compile a simple test project using both languages. "
+ "The output was:\n ${_output}")
+ endif()
+endfunction()
+
+# Restore including context policies.
+cmake_policy(POP)
diff --git a/Modules/FortranCInterface/CMakeLists.txt b/Modules/FortranCInterface/CMakeLists.txt
new file mode 100644
index 000000000..d35a72ce8
--- /dev/null
+++ b/Modules/FortranCInterface/CMakeLists.txt
@@ -0,0 +1,108 @@
+#=============================================================================
+# 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.
+#=============================================================================
+
+cmake_minimum_required(VERSION 2.6.3)
+project(FortranCInterface C Fortran)
+include(${FortranCInterface_BINARY_DIR}/Input.cmake OPTIONAL)
+
+# Check if the C compiler supports '$' in identifiers.
+include(CheckCSourceCompiles)
+check_c_source_compiles("
+extern int dollar$(void);
+int main() { return 0; }
+" C_SUPPORTS_DOLLAR)
+
+# List manglings of global symbol names to try.
+set(global_symbols
+ my_sub # VisualAge
+ my_sub_ # GNU, Intel, HP, SunPro, MIPSpro
+ my_sub__ # GNU g77
+ MY_SUB # Intel on Windows
+ mysub # VisualAge
+ mysub_ # GNU, Intel, HP, SunPro, MIPSpro
+ MYSUB # Intel on Windows
+ ${FortranCInterface_GLOBAL_SYMBOLS}
+ )
+list(REMOVE_DUPLICATES global_symbols)
+
+# List manglings of module symbol names to try.
+set(module_symbols
+ __my_module_MOD_my_sub # GNU 4.3
+ __my_module_NMOD_my_sub # VisualAge
+ __my_module__my_sub # GNU 4.2
+ __mymodule_MOD_mysub # GNU 4.3
+ __mymodule_NMOD_mysub # VisualAge
+ __mymodule__mysub # GNU 4.2
+ my_module$my_sub # HP
+ my_module_mp_my_sub_ # Intel
+ MY_MODULE_mp_MY_SUB # Intel on Windows
+ my_module_my_sub_ # PGI
+ my_module_MP_my_sub # NAG
+ mymodule$mysub # HP
+ mymodule_mp_mysub_ # Intel
+ MYMODULE_mp_MYSUB # Intel on Windows
+ mymodule_mysub_ # PGI
+ mymodule_MP_mysub # NAG
+ ${FortranCInterface_MODULE_SYMBOLS}
+ )
+list(REMOVE_DUPLICATES module_symbols)
+
+# Note that some compiler manglings cannot be invoked from C:
+# MIPSpro uses "MY_SUB.in.MY_MODULE"
+# SunPro uses "my_module.my_sub_"
+# PathScale uses "MY_SUB.in.MY_MODULE"
+
+# Add module symbols only with Fortran90.
+if(CMAKE_Fortran_COMPILER_SUPPORTS_F90)
+ set(myfort_modules mymodule.f90 my_module.f90)
+ set(call_mod call_mod.f90)
+ set_property(SOURCE main.F PROPERTY COMPILE_DEFINITIONS CALL_MOD)
+else()
+ set(module_symbols)
+endif()
+
+# Generate C symbol sources.
+set(symbol_sources)
+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:
+ # - PathScale Fortran uses module init symbols but module symbols
+ # use '.in.' so we cannot provide them anyway.
+ # - Cray Fortran >= 7.3.2 uses module init symbols but module symbols
+ # use 'mysub$mymodule_' so we cannot provide them anyway.
+ list(APPEND symbol_sources mymodule_.c my_module_.c)
+endif()
+foreach(symbol IN LISTS global_symbols module_symbols)
+ # Skip symbols with '$' if C cannot handle them.
+ if(C_SUPPORTS_DOLLAR OR NOT "${symbol}" MATCHES "\\$")
+ if("${symbol}" MATCHES "SUB")
+ set(upper "-UPPER")
+ else()
+ set(upper)
+ endif()
+ string(REPLACE "$" "S" name "${symbol}")
+ set(source ${CMAKE_CURRENT_BINARY_DIR}/symbols/${name}${upper}.c)
+ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/symbol.c.in ${source} @ONLY)
+ list(APPEND symbol_sources ${source})
+ endif()
+endforeach()
+
+# Provide symbols through Fortran.
+add_library(myfort STATIC mysub.f my_sub.f ${myfort_modules})
+
+# Provide symbols through C but fall back to Fortran.
+add_library(symbols STATIC ${symbol_sources})
+target_link_libraries(symbols myfort)
+
+# Require symbols through Fortran.
+add_executable(FortranCInterface main.F call_sub.f ${call_mod})
+target_link_libraries(FortranCInterface symbols)
diff --git a/Modules/FortranCInterface/Detect.cmake b/Modules/FortranCInterface/Detect.cmake
new file mode 100644
index 000000000..2ea43d132
--- /dev/null
+++ b/Modules/FortranCInterface/Detect.cmake
@@ -0,0 +1,183 @@
+#=============================================================================
+# 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.
+#=============================================================================
+
+configure_file(${FortranCInterface_SOURCE_DIR}/Input.cmake.in
+ ${FortranCInterface_BINARY_DIR}/Input.cmake @ONLY)
+
+# Detect the Fortran/C interface on the first run or when the
+# configuration changes.
+if(${FortranCInterface_BINARY_DIR}/Input.cmake
+ IS_NEWER_THAN ${FortranCInterface_BINARY_DIR}/Output.cmake
+ OR ${FortranCInterface_SOURCE_DIR}/Output.cmake.in
+ IS_NEWER_THAN ${FortranCInterface_BINARY_DIR}/Output.cmake
+ OR ${FortranCInterface_SOURCE_DIR}/CMakeLists.txt
+ IS_NEWER_THAN ${FortranCInterface_BINARY_DIR}/Output.cmake
+ OR ${CMAKE_CURRENT_LIST_FILE}
+ IS_NEWER_THAN ${FortranCInterface_BINARY_DIR}/Output.cmake
+ )
+ message(STATUS "Detecting Fortran/C Interface")
+else()
+ return()
+endif()
+
+# Invalidate verification results.
+unset(FortranCInterface_VERIFIED_C CACHE)
+unset(FortranCInterface_VERIFIED_CXX CACHE)
+
+set(_result)
+
+# Build a sample project which reports symbols.
+try_compile(FortranCInterface_COMPILED
+ ${FortranCInterface_BINARY_DIR}
+ ${FortranCInterface_SOURCE_DIR}
+ FortranCInterface
+ CMAKE_FLAGS
+ "-DCMAKE_C_FLAGS:STRING=${CMAKE_C_FLAGS}"
+ "-DCMAKE_Fortran_FLAGS:STRING=${CMAKE_Fortran_FLAGS}"
+ OUTPUT_VARIABLE FortranCInterface_OUTPUT)
+set(FortranCInterface_COMPILED ${FortranCInterface_COMPILED})
+unset(FortranCInterface_COMPILED CACHE)
+
+# Locate the sample project executable.
+if(FortranCInterface_COMPILED)
+ find_program(FortranCInterface_EXE
+ NAMES FortranCInterface
+ PATHS ${FortranCInterface_BINARY_DIR} ${FortranCInterface_BINARY_DIR}/Debug
+ NO_DEFAULT_PATH
+ )
+ set(FortranCInterface_EXE ${FortranCInterface_EXE})
+ unset(FortranCInterface_EXE CACHE)
+else()
+ set(_result "Failed to compile")
+ set(FortranCInterface_EXE)
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Fortran/C interface test project failed with the following output:\n"
+ "${FortranCInterface_OUTPUT}\n")
+endif()
+
+# Load symbols from INFO:symbol[] strings in the executable.
+set(FortranCInterface_SYMBOLS)
+if(FortranCInterface_EXE)
+ file(STRINGS "${FortranCInterface_EXE}" _info_strings
+ LIMIT_COUNT 8 REGEX "INFO:[^[]*\\[")
+ foreach(info ${_info_strings})
+ if("${info}" MATCHES ".*INFO:symbol\\[([^]]*)\\].*")
+ string(REGEX REPLACE ".*INFO:symbol\\[([^]]*)\\].*" "\\1" symbol "${info}")
+ list(APPEND FortranCInterface_SYMBOLS ${symbol})
+ endif()
+ endforeach()
+elseif(NOT _result)
+ set(_result "Failed to load sample executable")
+endif()
+
+set(_case_mysub "LOWER")
+set(_case_my_sub "LOWER")
+set(_case_MYSUB "UPPER")
+set(_case_MY_SUB "UPPER")
+set(_global_regex "^(_*)(mysub|MYSUB)([_$]*)$")
+set(_global__regex "^(_*)(my_sub|MY_SUB)([_$]*)$")
+set(_module_regex "^(_*)(mymodule|MYMODULE)([A-Za-z_$]*)(mysub|MYSUB)([_$]*)$")
+set(_module__regex "^(_*)(my_module|MY_MODULE)([A-Za-z_$]*)(my_sub|MY_SUB)([_$]*)$")
+
+# Parse the symbol names.
+foreach(symbol ${FortranCInterface_SYMBOLS})
+ foreach(form "" "_")
+ # Look for global symbols.
+ string(REGEX REPLACE "${_global_${form}regex}"
+ "\\1;\\2;\\3" pieces "${symbol}")
+ list(LENGTH pieces len)
+ if(len EQUAL 3)
+ set(FortranCInterface_GLOBAL_${form}SYMBOL "${symbol}")
+ list(GET pieces 0 FortranCInterface_GLOBAL_${form}PREFIX)
+ list(GET pieces 1 name)
+ list(GET pieces 2 FortranCInterface_GLOBAL_${form}SUFFIX)
+ set(FortranCInterface_GLOBAL_${form}CASE "${_case_${name}}")
+ endif()
+
+ # Look for module symbols.
+ string(REGEX REPLACE "${_module_${form}regex}"
+ "\\1;\\2;\\3;\\4;\\5" pieces "${symbol}")
+ list(LENGTH pieces len)
+ if(len EQUAL 5)
+ set(FortranCInterface_MODULE_${form}SYMBOL "${symbol}")
+ list(GET pieces 0 FortranCInterface_MODULE_${form}PREFIX)
+ list(GET pieces 1 module)
+ list(GET pieces 2 FortranCInterface_MODULE_${form}MIDDLE)
+ list(GET pieces 3 name)
+ list(GET pieces 4 FortranCInterface_MODULE_${form}SUFFIX)
+ set(FortranCInterface_MODULE_${form}CASE "${_case_${name}}")
+ endif()
+ endforeach()
+endforeach()
+
+# Construct mangling macro definitions.
+set(_name_LOWER "name")
+set(_name_UPPER "NAME")
+foreach(form "" "_")
+ if(FortranCInterface_GLOBAL_${form}SYMBOL)
+ if(FortranCInterface_GLOBAL_${form}PREFIX)
+ set(_prefix "${FortranCInterface_GLOBAL_${form}PREFIX}##")
+ else()
+ set(_prefix "")
+ endif()
+ if(FortranCInterface_GLOBAL_${form}SUFFIX)
+ set(_suffix "##${FortranCInterface_GLOBAL_${form}SUFFIX}")
+ else()
+ set(_suffix "")
+ endif()
+ set(_name "${_name_${FortranCInterface_GLOBAL_${form}CASE}}")
+ set(FortranCInterface_GLOBAL${form}_MACRO
+ "(name,NAME) ${_prefix}${_name}${_suffix}")
+ endif()
+ if(FortranCInterface_MODULE_${form}SYMBOL)
+ if(FortranCInterface_MODULE_${form}PREFIX)
+ set(_prefix "${FortranCInterface_MODULE_${form}PREFIX}##")
+ else()
+ set(_prefix "")
+ endif()
+ if(FortranCInterface_MODULE_${form}SUFFIX)
+ set(_suffix "##${FortranCInterface_MODULE_${form}SUFFIX}")
+ else()
+ set(_suffix "")
+ endif()
+ set(_name "${_name_${FortranCInterface_MODULE_${form}CASE}}")
+ set(_middle "##${FortranCInterface_MODULE_${form}MIDDLE}##")
+ set(FortranCInterface_MODULE${form}_MACRO
+ "(mod_name,name, mod_NAME,NAME) ${_prefix}mod_${_name}${_middle}${_name}${_suffix}")
+ endif()
+endforeach()
+
+# Summarize what is available.
+foreach(scope GLOBAL MODULE)
+ if(FortranCInterface_${scope}_SYMBOL AND
+ FortranCInterface_${scope}__SYMBOL)
+ set(FortranCInterface_${scope}_FOUND 1)
+ else()
+ set(FortranCInterface_${scope}_FOUND 0)
+ endif()
+endforeach()
+
+# Record the detection results.
+configure_file(${FortranCInterface_SOURCE_DIR}/Output.cmake.in
+ ${FortranCInterface_BINARY_DIR}/Output.cmake @ONLY)
+file(APPEND ${FortranCInterface_BINARY_DIR}/Output.cmake "\n")
+
+# Report the results.
+if(FortranCInterface_GLOBAL_FOUND)
+ if(FortranCInterface_MODULE_FOUND)
+ set(_result "Found GLOBAL and MODULE mangling")
+ else(FortranCInterface_MODULE_FOUND)
+ set(_result "Found GLOBAL but not MODULE mangling")
+ endif()
+elseif(NOT _result)
+ set(_result "Failed to recognize symbols")
+endif()
+message(STATUS "Detecting Fortran/C Interface - ${_result}")
diff --git a/Modules/FortranCInterface/Input.cmake.in b/Modules/FortranCInterface/Input.cmake.in
new file mode 100644
index 000000000..f261e3b45
--- /dev/null
+++ b/Modules/FortranCInterface/Input.cmake.in
@@ -0,0 +1,3 @@
+set(CMAKE_Fortran_COMPILER_ID "@CMAKE_Fortran_COMPILER_ID@")
+set(FortranCInterface_GLOBAL_SYMBOLS "@FortranCInterface_GLOBAL_SYMBOLS@")
+set(FortranCInterface_MODULE_SYMBOLS "@FortranCInterface_MODULE_SYMBOLS@")
diff --git a/Modules/FortranCInterface/Macro.h.in b/Modules/FortranCInterface/Macro.h.in
new file mode 100644
index 000000000..d015a6239
--- /dev/null
+++ b/Modules/FortranCInterface/Macro.h.in
@@ -0,0 +1,4 @@
+#ifndef @MACRO_NAMESPACE@HEADER_INCLUDED
+#define @MACRO_NAMESPACE@HEADER_INCLUDED
+@HEADER_CONTENT@
+#endif
diff --git a/Modules/FortranCInterface/Output.cmake.in b/Modules/FortranCInterface/Output.cmake.in
new file mode 100644
index 000000000..bce410e76
--- /dev/null
+++ b/Modules/FortranCInterface/Output.cmake.in
@@ -0,0 +1,33 @@
+# Global symbol without underscore.
+set(FortranCInterface_GLOBAL_SYMBOL "@FortranCInterface_GLOBAL_SYMBOL@")
+set(FortranCInterface_GLOBAL_PREFIX "@FortranCInterface_GLOBAL_PREFIX@")
+set(FortranCInterface_GLOBAL_SUFFIX "@FortranCInterface_GLOBAL_SUFFIX@")
+set(FortranCInterface_GLOBAL_CASE "@FortranCInterface_GLOBAL_CASE@")
+set(FortranCInterface_GLOBAL_MACRO "@FortranCInterface_GLOBAL_MACRO@")
+
+# Global symbol with underscore.
+set(FortranCInterface_GLOBAL__SYMBOL "@FortranCInterface_GLOBAL__SYMBOL@")
+set(FortranCInterface_GLOBAL__PREFIX "@FortranCInterface_GLOBAL__PREFIX@")
+set(FortranCInterface_GLOBAL__SUFFIX "@FortranCInterface_GLOBAL__SUFFIX@")
+set(FortranCInterface_GLOBAL__CASE "@FortranCInterface_GLOBAL__CASE@")
+set(FortranCInterface_GLOBAL__MACRO "@FortranCInterface_GLOBAL__MACRO@")
+
+# Module symbol without underscore.
+set(FortranCInterface_MODULE_SYMBOL "@FortranCInterface_MODULE_SYMBOL@")
+set(FortranCInterface_MODULE_PREFIX "@FortranCInterface_MODULE_PREFIX@")
+set(FortranCInterface_MODULE_MIDDLE "@FortranCInterface_MODULE_MIDDLE@")
+set(FortranCInterface_MODULE_SUFFIX "@FortranCInterface_MODULE_SUFFIX@")
+set(FortranCInterface_MODULE_CASE "@FortranCInterface_MODULE_CASE@")
+set(FortranCInterface_MODULE_MACRO "@FortranCInterface_MODULE_MACRO@")
+
+# Module symbol with underscore.
+set(FortranCInterface_MODULE__SYMBOL "@FortranCInterface_MODULE__SYMBOL@")
+set(FortranCInterface_MODULE__PREFIX "@FortranCInterface_MODULE__PREFIX@")
+set(FortranCInterface_MODULE__MIDDLE "@FortranCInterface_MODULE__MIDDLE@")
+set(FortranCInterface_MODULE__SUFFIX "@FortranCInterface_MODULE__SUFFIX@")
+set(FortranCInterface_MODULE__CASE "@FortranCInterface_MODULE__CASE@")
+set(FortranCInterface_MODULE__MACRO "@FortranCInterface_MODULE__MACRO@")
+
+# Summarize what was found.
+set(FortranCInterface_GLOBAL_FOUND @FortranCInterface_GLOBAL_FOUND@)
+set(FortranCInterface_MODULE_FOUND @FortranCInterface_MODULE_FOUND@)
diff --git a/Modules/FortranCInterface/Verify/CMakeLists.txt b/Modules/FortranCInterface/Verify/CMakeLists.txt
new file mode 100644
index 000000000..e969f2408
--- /dev/null
+++ b/Modules/FortranCInterface/Verify/CMakeLists.txt
@@ -0,0 +1,34 @@
+#=============================================================================
+# 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.
+#=============================================================================
+
+cmake_minimum_required(VERSION 2.7)
+project(VerifyFortranC C Fortran)
+
+option(VERIFY_CXX "Whether to verify C++ and Fortran" OFF)
+if(VERIFY_CXX)
+ enable_language(CXX)
+ set(VerifyCXX VerifyCXX.cxx)
+ add_definitions(-DVERIFY_CXX)
+endif()
+
+include(FortranCInterface)
+
+FortranCInterface_HEADER(VerifyFortran.h SYMBOLS VerifyFortran)
+include_directories(${VerifyFortranC_BINARY_DIR})
+
+add_library(VerifyFortran STATIC VerifyFortran.f)
+add_executable(VerifyFortranC main.c VerifyC.c ${VerifyCXX})
+target_link_libraries(VerifyFortranC VerifyFortran)
+
+if(NOT VERIFY_CXX)
+ # The entry point (main) is defined in C; link with the C compiler.
+ set_property(TARGET VerifyFortranC PROPERTY LINKER_LANGUAGE C)
+endif()
diff --git a/Modules/FortranCInterface/Verify/VerifyC.c b/Modules/FortranCInterface/Verify/VerifyC.c
new file mode 100644
index 000000000..7f847ef01
--- /dev/null
+++ b/Modules/FortranCInterface/Verify/VerifyC.c
@@ -0,0 +1,5 @@
+#include <stdio.h>
+void VerifyC(void)
+{
+ printf("VerifyC\n");
+}
diff --git a/Modules/FortranCInterface/Verify/VerifyCXX.cxx b/Modules/FortranCInterface/Verify/VerifyCXX.cxx
new file mode 100644
index 000000000..689fac53d
--- /dev/null
+++ b/Modules/FortranCInterface/Verify/VerifyCXX.cxx
@@ -0,0 +1,4 @@
+extern "C" void VerifyCXX(void)
+{
+ delete new int;
+}
diff --git a/Modules/FortranCInterface/Verify/VerifyFortran.f b/Modules/FortranCInterface/Verify/VerifyFortran.f
new file mode 100644
index 000000000..a17e48d1b
--- /dev/null
+++ b/Modules/FortranCInterface/Verify/VerifyFortran.f
@@ -0,0 +1,3 @@
+ subroutine VerifyFortran
+ print *, 'VerifyFortran'
+ end
diff --git a/Modules/FortranCInterface/Verify/main.c b/Modules/FortranCInterface/Verify/main.c
new file mode 100644
index 000000000..582ef1d90
--- /dev/null
+++ b/Modules/FortranCInterface/Verify/main.c
@@ -0,0 +1,16 @@
+extern void VerifyC(void);
+#ifdef VERIFY_CXX
+extern void VerifyCXX(void);
+#endif
+#include "VerifyFortran.h"
+extern void VerifyFortran(void);
+
+int main(void)
+{
+ VerifyC();
+#ifdef VERIFY_CXX
+ VerifyCXX();
+#endif
+ VerifyFortran();
+ return 0;
+}
diff --git a/Modules/FortranCInterface/call_mod.f90 b/Modules/FortranCInterface/call_mod.f90
new file mode 100644
index 000000000..9b6af640e
--- /dev/null
+++ b/Modules/FortranCInterface/call_mod.f90
@@ -0,0 +1,6 @@
+subroutine call_mod
+ use mymodule
+ use my_module
+ call mysub()
+ call my_sub()
+end subroutine call_mod
diff --git a/Modules/FortranCInterface/call_sub.f b/Modules/FortranCInterface/call_sub.f
new file mode 100644
index 000000000..ce3d50b14
--- /dev/null
+++ b/Modules/FortranCInterface/call_sub.f
@@ -0,0 +1,4 @@
+ subroutine call_sub
+ call mysub()
+ call my_sub()
+ end
diff --git a/Modules/FortranCInterface/main.F b/Modules/FortranCInterface/main.F
new file mode 100644
index 000000000..84991b0ee
--- /dev/null
+++ b/Modules/FortranCInterface/main.F
@@ -0,0 +1,6 @@
+ program main
+ call call_sub()
+#ifdef CALL_MOD
+ call call_mod()
+#endif
+ end
diff --git a/Modules/FortranCInterface/my_module.f90 b/Modules/FortranCInterface/my_module.f90
new file mode 100644
index 000000000..82713b43e
--- /dev/null
+++ b/Modules/FortranCInterface/my_module.f90
@@ -0,0 +1,8 @@
+module my_module
+ interface my_interface
+ module procedure my_sub
+ end interface
+contains
+ subroutine my_sub
+ end subroutine my_sub
+end module my_module
diff --git a/Modules/FortranCInterface/my_module_.c b/Modules/FortranCInterface/my_module_.c
new file mode 100644
index 000000000..6510ae977
--- /dev/null
+++ b/Modules/FortranCInterface/my_module_.c
@@ -0,0 +1 @@
+void my_module_(void) {}
diff --git a/Modules/FortranCInterface/my_sub.f b/Modules/FortranCInterface/my_sub.f
new file mode 100644
index 000000000..247ba0678
--- /dev/null
+++ b/Modules/FortranCInterface/my_sub.f
@@ -0,0 +1,2 @@
+ subroutine my_sub
+ end
diff --git a/Modules/FortranCInterface/mymodule.f90 b/Modules/FortranCInterface/mymodule.f90
new file mode 100644
index 000000000..ef6281a3f
--- /dev/null
+++ b/Modules/FortranCInterface/mymodule.f90
@@ -0,0 +1,8 @@
+module mymodule
+ interface myinterface
+ module procedure mysub
+ end interface
+contains
+ subroutine mysub
+ end subroutine mysub
+end module mymodule
diff --git a/Modules/FortranCInterface/mymodule_.c b/Modules/FortranCInterface/mymodule_.c
new file mode 100644
index 000000000..52706058e
--- /dev/null
+++ b/Modules/FortranCInterface/mymodule_.c
@@ -0,0 +1 @@
+void mymodule_(void) {}
diff --git a/Modules/FortranCInterface/mysub.f b/Modules/FortranCInterface/mysub.f
new file mode 100644
index 000000000..1c27ff452
--- /dev/null
+++ b/Modules/FortranCInterface/mysub.f
@@ -0,0 +1,2 @@
+ subroutine mysub
+ end
diff --git a/Modules/FortranCInterface/symbol.c.in b/Modules/FortranCInterface/symbol.c.in
new file mode 100644
index 000000000..369fa4597
--- /dev/null
+++ b/Modules/FortranCInterface/symbol.c.in
@@ -0,0 +1,4 @@
+const char* @symbol@(void)
+{
+ return "INFO:symbol[@symbol@]";
+}
diff --git a/Modules/GNUInstallDirs.cmake b/Modules/GNUInstallDirs.cmake
new file mode 100644
index 000000000..0302e4bef
--- /dev/null
+++ b/Modules/GNUInstallDirs.cmake
@@ -0,0 +1,188 @@
+# - 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
+# 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.
+
+#=============================================================================
+# Copyright 2011 Nikita Krupen'ko <krnekit@gmail.com>
+# Copyright 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.)
+
+# Installation directories
+#
+if(NOT DEFINED CMAKE_INSTALL_BINDIR)
+ set(CMAKE_INSTALL_BINDIR "bin" CACHE PATH "user executables (bin)")
+endif()
+
+if(NOT DEFINED CMAKE_INSTALL_SBINDIR)
+ set(CMAKE_INSTALL_SBINDIR "sbin" CACHE PATH "system admin executables (sbin)")
+endif()
+
+if(NOT DEFINED CMAKE_INSTALL_LIBEXECDIR)
+ set(CMAKE_INSTALL_LIBEXECDIR "libexec" CACHE PATH "program executables (libexec)")
+endif()
+
+if(NOT DEFINED CMAKE_INSTALL_SYSCONFDIR)
+ set(CMAKE_INSTALL_SYSCONFDIR "etc" CACHE PATH "read-only single-machine data (etc)")
+endif()
+
+if(NOT DEFINED CMAKE_INSTALL_SHAREDSTATEDIR)
+ set(CMAKE_INSTALL_SHAREDSTATEDIR "com" CACHE PATH "modifiable architecture-independent data (com)")
+endif()
+
+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)
+ set(_LIBDIR_DEFAULT "lib")
+ # Override this default 'lib' with 'lib64' iff:
+ # - we are on Linux system but NOT cross-compiling
+ # - we are NOT on debian
+ # - we are on a 64 bits system
+ # 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"
+ # See http://wiki.debian.org/Multiarch
+ if(CMAKE_SYSTEM_NAME MATCHES "Linux"
+ 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()
+ else() # not debian, rely on CMAKE_SIZEOF_VOID_P:
+ if(NOT DEFINED CMAKE_SIZEOF_VOID_P)
+ message(AUTHOR_WARNING
+ "Unable to determine default CMAKE_INSTALL_LIBDIR directory because no target architecture is known. "
+ "Please enable at least one language before including GNUInstallDirs.")
+ else()
+ if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
+ set(_LIBDIR_DEFAULT "lib64")
+ endif()
+ endif()
+ endif()
+ endif()
+ set(CMAKE_INSTALL_LIBDIR "${_LIBDIR_DEFAULT}" CACHE PATH "object code libraries (${_LIBDIR_DEFAULT})")
+endif()
+
+if(NOT DEFINED CMAKE_INSTALL_INCLUDEDIR)
+ set(CMAKE_INSTALL_INCLUDEDIR "include" CACHE PATH "C header files (include)")
+endif()
+
+if(NOT DEFINED CMAKE_INSTALL_OLDINCLUDEDIR)
+ set(CMAKE_INSTALL_OLDINCLUDEDIR "/usr/include" CACHE PATH "C header files for non-gcc (/usr/include)")
+endif()
+
+if(NOT DEFINED CMAKE_INSTALL_DATAROOTDIR)
+ set(CMAKE_INSTALL_DATAROOTDIR "share" CACHE PATH "read-only architecture-independent data root (share)")
+endif()
+
+#-----------------------------------------------------------------------------
+# Values whose defaults are relative to DATAROOTDIR. Store empty values in
+# the cache and store the defaults in local variables if the cache values are
+# not set explicitly. This auto-updates the defaults as DATAROOTDIR changes.
+
+if(NOT CMAKE_INSTALL_DATADIR)
+ set(CMAKE_INSTALL_DATADIR "" CACHE PATH "read-only architecture-independent data (DATAROOTDIR)")
+ 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")
+endif()
+
+if(NOT CMAKE_INSTALL_LOCALEDIR)
+ set(CMAKE_INSTALL_LOCALEDIR "" CACHE PATH "locale-dependent data (DATAROOTDIR/locale)")
+ 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}")
+endif()
+
+#-----------------------------------------------------------------------------
+
+mark_as_advanced(
+ CMAKE_INSTALL_BINDIR
+ CMAKE_INSTALL_SBINDIR
+ CMAKE_INSTALL_LIBEXECDIR
+ CMAKE_INSTALL_SYSCONFDIR
+ CMAKE_INSTALL_SHAREDSTATEDIR
+ CMAKE_INSTALL_LOCALSTATEDIR
+ CMAKE_INSTALL_LIBDIR
+ CMAKE_INSTALL_INCLUDEDIR
+ CMAKE_INSTALL_OLDINCLUDEDIR
+ CMAKE_INSTALL_DATAROOTDIR
+ CMAKE_INSTALL_DATADIR
+ CMAKE_INSTALL_INFODIR
+ CMAKE_INSTALL_LOCALEDIR
+ CMAKE_INSTALL_MANDIR
+ CMAKE_INSTALL_DOCDIR
+ )
+
+# Result directories
+#
+foreach(dir
+ BINDIR
+ SBINDIR
+ LIBEXECDIR
+ SYSCONFDIR
+ SHAREDSTATEDIR
+ LOCALSTATEDIR
+ LIBDIR
+ INCLUDEDIR
+ OLDINCLUDEDIR
+ DATAROOTDIR
+ DATADIR
+ INFODIR
+ LOCALEDIR
+ MANDIR
+ DOCDIR
+ )
+ if(NOT IS_ABSOLUTE ${CMAKE_INSTALL_${dir}})
+ set(CMAKE_INSTALL_FULL_${dir} "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_${dir}}")
+ else()
+ set(CMAKE_INSTALL_FULL_${dir} "${CMAKE_INSTALL_${dir}}")
+ endif()
+endforeach()
diff --git a/Modules/GenerateExportHeader.cmake b/Modules/GenerateExportHeader.cmake
new file mode 100644
index 000000000..ce23d5d25
--- /dev/null
+++ b/Modules/GenerateExportHeader.cmake
@@ -0,0 +1,351 @@
+# - 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}
+# )
+#
+# And in the ABI header files:
+#
+# #include "somelib_export.h"
+# class SOMELIB_EXPORT SomeClass {
+# ...
+# };
+#
+# The CMake fragment will generate a file in the ${CMAKE_CURRENT_BUILD_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.
+#
+# 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
+# )
+#
+# 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:
+#
+# 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.
+#
+# add_library(somelib someclass.cpp)
+# generate_export_header(somelib
+# DEPRECATED_MACRO_NAME KDE_DEPRECATED
+# )
+#
+# creates the macro KDE_DEPRECATED instead of SOMELIB_DEPRECATED.
+#
+# 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
+#
+# 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.
+#
+# 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.
+#
+# 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
+# };
+#
+# #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_)
+#
+# Generates the macros VTK_SOMELIB_EXPORT etc.
+
+#=============================================================================
+# Copyright 2011 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(CMakeParseArguments)
+include(CheckCXXCompilerFlag)
+
+# TODO: Install this macro separately?
+macro(_check_cxx_compiler_attribute _ATTRIBUTE _RESULT)
+ check_cxx_source_compiles("${_ATTRIBUTE} int somefunc() { return 0; }
+ int main() { return somefunc();}" ${_RESULT}
+ )
+endmacro()
+
+macro(_test_compiler_hidden_visibility)
+
+ if(CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.2")
+ set(GCC_TOO_OLD TRUE)
+ message(WARNING "GCC version older than 4.2")
+ elseif(CMAKE_COMPILER_IS_GNUC AND CMAKE_C_COMPILER_VERSION VERSION_LESS "4.2")
+ set(GCC_TOO_OLD TRUE)
+ message(WARNING "GCC version older than 4.2")
+ elseif(CMAKE_CXX_COMPILER_ID MATCHES Intel AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "12.0")
+ set(_INTEL_TOO_OLD TRUE)
+ message(WARNING "Intel compiler older than 12.0")
+ endif()
+
+
+ # 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)
+ check_cxx_compiler_flag(-fvisibility=hidden COMPILER_HAS_HIDDEN_VISIBILITY)
+ check_cxx_compiler_flag(-fvisibility-inlines-hidden
+ COMPILER_HAS_HIDDEN_INLINE_VISIBILITY)
+ option(USE_COMPILER_HIDDEN_VISIBILITY
+ "Use HIDDEN visibility support if available." ON)
+ mark_as_advanced(USE_COMPILER_HIDDEN_VISIBILITY)
+ endif()
+endmacro()
+
+macro(_test_compiler_has_deprecated)
+ if("${CMAKE_CXX_COMPILER_ID}" MATCHES Borland
+ 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)
+ set(COMPILER_HAS_DEPRECATED "" CACHE INTERNAL
+ "Compiler support for a deprecated attribute")
+ else()
+ _check_cxx_compiler_attribute("__attribute__((__deprecated__))"
+ COMPILER_HAS_DEPRECATED_ATTR)
+ if(COMPILER_HAS_DEPRECATED_ATTR)
+ set(COMPILER_HAS_DEPRECATED "${COMPILER_HAS_DEPRECATED_ATTR}"
+ CACHE INTERNAL "Compiler support for a deprecated attribute")
+ else()
+ _check_cxx_compiler_attribute("__declspec(deprecated)"
+ COMPILER_HAS_DEPRECATED)
+ endif()
+ endif()
+endmacro()
+
+get_filename_component(_GENERATE_EXPORT_HEADER_MODULE_DIR
+ "${CMAKE_CURRENT_LIST_FILE}" PATH)
+
+macro(_DO_SET_MACRO_VALUES TARGET_LIBRARY)
+ set(DEFINE_DEPRECATED)
+ set(DEFINE_EXPORT)
+ set(DEFINE_IMPORT)
+ set(DEFINE_NO_EXPORT)
+
+ if (COMPILER_HAS_DEPRECATED_ATTR)
+ set(DEFINE_DEPRECATED "__attribute__ ((__deprecated__))")
+ elseif(COMPILER_HAS_DEPRECATED)
+ set(DEFINE_DEPRECATED "__declspec(deprecated)")
+ endif()
+
+ get_property(type TARGET ${TARGET_LIBRARY} PROPERTY TYPE)
+
+ if(NOT ${type} STREQUAL "STATIC_LIBRARY")
+ if(WIN32)
+ set(DEFINE_EXPORT "__declspec(dllexport)")
+ set(DEFINE_IMPORT "__declspec(dllimport)")
+ elseif(COMPILER_HAS_HIDDEN_VISIBILITY AND USE_COMPILER_HIDDEN_VISIBILITY)
+ set(DEFINE_EXPORT "__attribute__((visibility(\"default\")))")
+ set(DEFINE_IMPORT "__attribute__((visibility(\"default\")))")
+ set(DEFINE_NO_EXPORT "__attribute__((visibility(\"hidden\")))")
+ endif()
+ endif()
+endmacro()
+
+macro(_DO_GENERATE_EXPORT_HEADER TARGET_LIBRARY)
+ # Option overrides
+ set(options DEFINE_NO_DEPRECATED)
+ set(oneValueArgs PREFIX_NAME BASE_NAME EXPORT_MACRO_NAME EXPORT_FILE_NAME
+ DEPRECATED_MACRO_NAME NO_EXPORT_MACRO_NAME STATIC_DEFINE
+ NO_DEPRECATED_MACRO_NAME)
+ set(multiValueArgs)
+
+ cmake_parse_arguments(_GEH "${options}" "${oneValueArgs}" "${multiValueArgs}"
+ ${ARGN})
+
+ set(BASE_NAME "${TARGET_LIBRARY}")
+
+ if(_GEH_BASE_NAME)
+ set(BASE_NAME ${_GEH_BASE_NAME})
+ endif()
+
+ string(TOUPPER ${BASE_NAME} BASE_NAME_UPPER)
+ string(TOLOWER ${BASE_NAME} BASE_NAME_LOWER)
+
+ # Default options
+ set(EXPORT_MACRO_NAME "${_GEH_PREFIX_NAME}${BASE_NAME_UPPER}_EXPORT")
+ set(NO_EXPORT_MACRO_NAME "${_GEH_PREFIX_NAME}${BASE_NAME_UPPER}_NO_EXPORT")
+ set(EXPORT_FILE_NAME "${CMAKE_CURRENT_BINARY_DIR}/${BASE_NAME_LOWER}_export.h")
+ set(DEPRECATED_MACRO_NAME "${_GEH_PREFIX_NAME}${BASE_NAME_UPPER}_DEPRECATED")
+ set(STATIC_DEFINE "${_GEH_PREFIX_NAME}${BASE_NAME_UPPER}_STATIC_DEFINE")
+ set(NO_DEPRECATED_MACRO_NAME
+ "${_GEH_PREFIX_NAME}${BASE_NAME_UPPER}_NO_DEPRECATED")
+
+ if(_GEH_UNPARSED_ARGUMENTS)
+ message(FATAL_ERROR "Unknown keywords given to GENERATE_EXPORT_HEADER(): \"${_GEH_UNPARSED_ARGUMENTS}\"")
+ endif()
+
+ if(_GEH_EXPORT_MACRO_NAME)
+ set(EXPORT_MACRO_NAME ${_GEH_PREFIX_NAME}${_GEH_EXPORT_MACRO_NAME})
+ endif()
+ if(_GEH_EXPORT_FILE_NAME)
+ if(IS_ABSOLUTE ${_GEH_EXPORT_FILE_NAME})
+ set(EXPORT_FILE_NAME ${_GEH_EXPORT_FILE_NAME})
+ else()
+ set(EXPORT_FILE_NAME "${CMAKE_CURRENT_BINARY_DIR}/${_GEH_EXPORT_FILE_NAME}")
+ endif()
+ endif()
+ if(_GEH_DEPRECATED_MACRO_NAME)
+ set(DEPRECATED_MACRO_NAME ${_GEH_PREFIX_NAME}${_GEH_DEPRECATED_MACRO_NAME})
+ endif()
+ if(_GEH_NO_EXPORT_MACRO_NAME)
+ set(NO_EXPORT_MACRO_NAME ${_GEH_PREFIX_NAME}${_GEH_NO_EXPORT_MACRO_NAME})
+ endif()
+ if(_GEH_STATIC_DEFINE)
+ set(STATIC_DEFINE ${_GEH_PREFIX_NAME}${_GEH_STATIC_DEFINE})
+ endif()
+
+ if(_GEH_DEFINE_NO_DEPRECATED)
+ set(DEFINE_NO_DEPRECATED TRUE)
+ endif()
+
+ if(_GEH_NO_DEPRECATED_MACRO_NAME)
+ set(NO_DEPRECATED_MACRO_NAME
+ ${_GEH_PREFIX_NAME}${_GEH_NO_DEPRECATED_MACRO_NAME})
+ endif()
+
+ set(INCLUDE_GUARD_NAME "${EXPORT_MACRO_NAME}_H")
+
+ get_target_property(EXPORT_IMPORT_CONDITION ${TARGET_LIBRARY} DEFINE_SYMBOL)
+
+ if(NOT EXPORT_IMPORT_CONDITION)
+ set(EXPORT_IMPORT_CONDITION ${TARGET_LIBRARY}_EXPORTS)
+ endif()
+
+ configure_file("${_GENERATE_EXPORT_HEADER_MODULE_DIR}/exportheader.cmake.in"
+ "${EXPORT_FILE_NAME}" @ONLY)
+endmacro()
+
+function(GENERATE_EXPORT_HEADER TARGET_LIBRARY)
+ get_property(type TARGET ${TARGET_LIBRARY} PROPERTY TYPE)
+ if(${type} STREQUAL "MODULE")
+ message(WARNING "This macro should not be used with libraries of type MODULE")
+ return()
+ endif()
+ if(NOT ${type} STREQUAL "STATIC_LIBRARY" AND NOT ${type} STREQUAL "SHARED_LIBRARY")
+ message(WARNING "This macro can only be used with libraries")
+ return()
+ endif()
+ _test_compiler_hidden_visibility()
+ _test_compiler_has_deprecated()
+ _do_set_macro_values(${TARGET_LIBRARY})
+ _do_generate_export_header(${TARGET_LIBRARY} ${ARGN})
+endfunction()
+
+function(add_compiler_export_flags)
+
+ _test_compiler_hidden_visibility()
+ _test_compiler_has_deprecated()
+
+ if(NOT (USE_COMPILER_HIDDEN_VISIBILITY AND COMPILER_HAS_HIDDEN_VISIBILITY))
+ # Just return if there are no flags to add.
+ return()
+ endif()
+
+ set (EXTRA_FLAGS "-fvisibility=hidden")
+
+ if(COMPILER_HAS_HIDDEN_INLINE_VISIBILITY)
+ set (EXTRA_FLAGS "${EXTRA_FLAGS} -fvisibility-inlines-hidden")
+ endif()
+
+ # Either return the extra flags needed in the supplied argument, or to the
+ # CMAKE_CXX_FLAGS if no argument is supplied.
+ if(ARGV0)
+ set(${ARGV0} "${EXTRA_FLAGS}" PARENT_SCOPE)
+ else()
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_FLAGS}" PARENT_SCOPE)
+ endif()
+endfunction()
diff --git a/Modules/GetPrerequisites.cmake b/Modules/GetPrerequisites.cmake
new file mode 100644
index 000000000..d215685dd
--- /dev/null
+++ b/Modules/GetPrerequisites.cmake
@@ -0,0 +1,877 @@
+# - 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)
+# 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
+# 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.
+#
+# IS_FILE_EXECUTABLE(<file> <result_var>)
+# Return 1 in <result_var> if <file> is a binary executable, 0 otherwise.
+#
+# 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>)
+# 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>.
+#
+# 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
+# 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>.
+#
+# Possible types are:
+# system
+# local
+# embedded
+# other
+
+#=============================================================================
+# Copyright 2008-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.)
+
+function(gp_append_unique list_var value)
+ set(contains 0)
+
+ foreach(item ${${list_var}})
+ if("${item}" STREQUAL "${value}")
+ set(contains 1)
+ break()
+ endif("${item}" STREQUAL "${value}")
+ endforeach(item)
+
+ if(NOT contains)
+ set(${list_var} ${${list_var}} "${value}" PARENT_SCOPE)
+ endif(NOT contains)
+endfunction(gp_append_unique)
+
+
+function(is_file_executable file result_var)
+ #
+ # A file is not executable until proven otherwise:
+ #
+ set(${result_var} 0 PARENT_SCOPE)
+
+ get_filename_component(file_full "${file}" ABSOLUTE)
+ string(TOLOWER "${file_full}" file_full_lower)
+
+ # If file name ends in .exe on Windows, *assume* executable:
+ #
+ if(WIN32 AND NOT UNIX)
+ if("${file_full_lower}" MATCHES "\\.exe$")
+ set(${result_var} 1 PARENT_SCOPE)
+ return()
+ endif("${file_full_lower}" MATCHES "\\.exe$")
+
+ # A clause could be added here that uses output or return value of dumpbin
+ # to determine ${result_var}. In 99%+? practical cases, the exe name
+ # match will be sufficient...
+ #
+ endif(WIN32 AND NOT UNIX)
+
+ # Use the information returned from the Unix shell command "file" to
+ # determine if ${file_full} should be considered an executable file...
+ #
+ # If the file command's output contains "executable" and does *not* contain
+ # "text" then it is likely an executable suitable for prerequisite analysis
+ # via the get_prerequisites macro.
+ #
+ if(UNIX)
+ if(NOT file_cmd)
+ find_program(file_cmd "file")
+ endif(NOT file_cmd)
+
+ if(file_cmd)
+ execute_process(COMMAND "${file_cmd}" "${file_full}"
+ OUTPUT_VARIABLE file_ov
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+
+ # 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
+ # the file contains the word "text" or "executable" we are not fooled
+ # into thinking "the wrong thing" because the file name matches the
+ # other 'file' command output we are looking for...
+ #
+ string(REPLACE "${file_full}" " _file_full_ " file_ov "${file_ov}")
+ string(TOLOWER "${file_ov}" file_ov)
+
+ #message(STATUS "file_ov='${file_ov}'")
+ if("${file_ov}" MATCHES "executable")
+ #message(STATUS "executable!")
+ if("${file_ov}" MATCHES "text")
+ #message(STATUS "but text, so *not* a binary executable!")
+ else("${file_ov}" MATCHES "text")
+ set(${result_var} 1 PARENT_SCOPE)
+ return()
+ endif("${file_ov}" MATCHES "text")
+ endif("${file_ov}" MATCHES "executable")
+
+ # Also detect position independent executables on Linux,
+ # where "file" gives "shared object ... (uses shared libraries)"
+ if("${file_ov}" MATCHES "shared object.*\(uses shared libs\)")
+ set(${result_var} 1 PARENT_SCOPE)
+ return()
+ endif()
+
+ else(file_cmd)
+ message(STATUS "warning: No 'file' command, skipping execute_process...")
+ endif(file_cmd)
+ endif(UNIX)
+endfunction(is_file_executable)
+
+
+function(gp_item_default_embedded_path item default_embedded_path_var)
+
+ # On Windows and Linux, "embed" prerequisites in the same directory
+ # as the executable by default:
+ #
+ set(path "@executable_path")
+ set(overridden 0)
+
+ # On the Mac, relative to the executable depending on the type
+ # of the thing we are embedding:
+ #
+ if(APPLE)
+ #
+ # The assumption here is that all executables in the bundle will be
+ # in same-level-directories inside the bundle. The parent directory
+ # of an executable inside the bundle should be MacOS or a sibling of
+ # MacOS and all embedded paths returned from here will begin with
+ # "@executable_path/../" and will work from all executables in all
+ # such same-level-directories inside the bundle.
+ #
+
+ # By default, embed things right next to the main bundle executable:
+ #
+ set(path "@executable_path/../../Contents/MacOS")
+
+ # Embed .dylibs right next to the main bundle executable:
+ #
+ if(item MATCHES "\\.dylib$")
+ set(path "@executable_path/../MacOS")
+ set(overridden 1)
+ endif(item MATCHES "\\.dylib$")
+
+ # Embed frameworks in the embedded "Frameworks" directory (sibling of MacOS):
+ #
+ if(NOT overridden)
+ if(item MATCHES "[^/]+\\.framework/")
+ set(path "@executable_path/../Frameworks")
+ set(overridden 1)
+ endif(item MATCHES "[^/]+\\.framework/")
+ endif(NOT overridden)
+ endif()
+
+ # Provide a hook so that projects can override the default embedded location
+ # of any given library by whatever logic they choose:
+ #
+ if(COMMAND gp_item_default_embedded_path_override)
+ gp_item_default_embedded_path_override("${item}" path)
+ endif(COMMAND gp_item_default_embedded_path_override)
+
+ set(${default_embedded_path_var} "${path}" PARENT_SCOPE)
+endfunction(gp_item_default_embedded_path)
+
+
+function(gp_resolve_item context item exepath dirs resolved_item_var)
+ set(resolved 0)
+ set(resolved_item "${item}")
+
+ # Is it already resolved?
+ #
+ if(IS_ABSOLUTE "${resolved_item}" AND EXISTS "${resolved_item}")
+ set(resolved 1)
+ endif(IS_ABSOLUTE "${resolved_item}" AND EXISTS "${resolved_item}")
+
+ if(NOT resolved)
+ if(item MATCHES "@executable_path")
+ #
+ # @executable_path references are assumed relative to exepath
+ #
+ string(REPLACE "@executable_path" "${exepath}" ri "${item}")
+ get_filename_component(ri "${ri}" ABSOLUTE)
+
+ if(EXISTS "${ri}")
+ #message(STATUS "info: embedded item exists (${ri})")
+ set(resolved 1)
+ set(resolved_item "${ri}")
+ else(EXISTS "${ri}")
+ message(STATUS "warning: embedded item does not exist '${ri}'")
+ endif(EXISTS "${ri}")
+ endif(item MATCHES "@executable_path")
+ endif(NOT resolved)
+
+ if(NOT resolved)
+ if(item MATCHES "@loader_path")
+ #
+ # @loader_path references are assumed relative to the
+ # PATH of the given "context" (presumably another library)
+ #
+ get_filename_component(contextpath "${context}" PATH)
+ string(REPLACE "@loader_path" "${contextpath}" ri "${item}")
+ get_filename_component(ri "${ri}" ABSOLUTE)
+
+ if(EXISTS "${ri}")
+ #message(STATUS "info: embedded item exists (${ri})")
+ set(resolved 1)
+ set(resolved_item "${ri}")
+ else(EXISTS "${ri}")
+ message(STATUS "warning: embedded item does not exist '${ri}'")
+ endif(EXISTS "${ri}")
+ endif(item MATCHES "@loader_path")
+ endif(NOT resolved)
+
+ if(NOT resolved)
+ 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
+ #
+ string(REPLACE "@rpath/" "" norpath_item "${item}")
+
+ set(ri "ri-NOTFOUND")
+ find_file(ri "${norpath_item}" ${exepath} ${dirs} NO_DEFAULT_PATH)
+ if(ri)
+ #message(STATUS "info: 'find_file' in exepath/dirs (${ri})")
+ set(resolved 1)
+ set(resolved_item "${ri}")
+ set(ri "ri-NOTFOUND")
+ endif(ri)
+
+ endif(item MATCHES "@rpath")
+ endif(NOT resolved)
+
+ if(NOT resolved)
+ set(ri "ri-NOTFOUND")
+ find_file(ri "${item}" ${exepath} ${dirs} NO_DEFAULT_PATH)
+ find_file(ri "${item}" ${exepath} ${dirs} /usr/lib)
+ if(ri)
+ #message(STATUS "info: 'find_file' in exepath/dirs (${ri})")
+ set(resolved 1)
+ set(resolved_item "${ri}")
+ set(ri "ri-NOTFOUND")
+ endif(ri)
+ endif(NOT resolved)
+
+ if(NOT resolved)
+ if(item MATCHES "[^/]+\\.framework/")
+ set(fw "fw-NOTFOUND")
+ find_file(fw "${item}"
+ "~/Library/Frameworks"
+ "/Library/Frameworks"
+ "/System/Library/Frameworks"
+ )
+ if(fw)
+ #message(STATUS "info: 'find_file' found framework (${fw})")
+ set(resolved 1)
+ set(resolved_item "${fw}")
+ set(fw "fw-NOTFOUND")
+ endif(fw)
+ endif(item MATCHES "[^/]+\\.framework/")
+ endif(NOT resolved)
+
+ # Using find_program on Windows will find dll files that are in the PATH.
+ # (Converting simple file names into full path names if found.)
+ #
+ if(WIN32 AND NOT UNIX)
+ if(NOT resolved)
+ set(ri "ri-NOTFOUND")
+ find_program(ri "${item}" PATHS "${exepath};${dirs}" NO_DEFAULT_PATH)
+ find_program(ri "${item}" PATHS "${exepath};${dirs}")
+ if(ri)
+ #message(STATUS "info: 'find_program' in exepath/dirs (${ri})")
+ set(resolved 1)
+ set(resolved_item "${ri}")
+ set(ri "ri-NOTFOUND")
+ endif(ri)
+ endif(NOT resolved)
+ endif(WIN32 AND NOT UNIX)
+
+ # Provide a hook so that projects can override item resolution
+ # by whatever logic they choose:
+ #
+ if(COMMAND gp_resolve_item_override)
+ gp_resolve_item_override("${context}" "${item}" "${exepath}" "${dirs}" resolved_item resolved)
+ endif(COMMAND gp_resolve_item_override)
+
+ if(NOT resolved)
+ message(STATUS "
+warning: cannot resolve item '${item}'
+
+ possible problems:
+ need more directories?
+ need to use InstallRequiredSystemLibraries?
+ run in install tree instead of build tree?
+")
+# message(STATUS "
+#******************************************************************************
+#warning: cannot resolve item '${item}'
+#
+# possible problems:
+# need more directories?
+# need to use InstallRequiredSystemLibraries?
+# run in install tree instead of build tree?
+#
+# context='${context}'
+# item='${item}'
+# exepath='${exepath}'
+# dirs='${dirs}'
+# resolved_item_var='${resolved_item_var}'
+#******************************************************************************
+#")
+ endif(NOT resolved)
+
+ set(${resolved_item_var} "${resolved_item}" PARENT_SCOPE)
+endfunction(gp_resolve_item)
+
+
+function(gp_resolved_file_type original_file file exepath dirs type_var)
+ #message(STATUS "**")
+
+ if(NOT IS_ABSOLUTE "${original_file}")
+ message(STATUS "warning: gp_resolved_file_type expects absolute full path for first arg original_file")
+ endif()
+
+ set(is_embedded 0)
+ set(is_local 0)
+ set(is_system 0)
+
+ set(resolved_file "${file}")
+
+ if("${file}" MATCHES "^@(executable|loader)_path")
+ set(is_embedded 1)
+ endif()
+
+ if(NOT is_embedded)
+ if(NOT IS_ABSOLUTE "${file}")
+ gp_resolve_item("${original_file}" "${file}" "${exepath}" "${dirs}" resolved_file)
+ endif()
+
+ string(TOLOWER "${original_file}" original_lower)
+ string(TOLOWER "${resolved_file}" lower)
+
+ if(UNIX)
+ if(resolved_file MATCHES "^(/lib/|/lib32/|/lib64/|/usr/lib/|/usr/lib32/|/usr/lib64/|/usr/X11R6/|/usr/bin/)")
+ set(is_system 1)
+ endif()
+ endif()
+
+ if(APPLE)
+ if(resolved_file MATCHES "^(/System/Library/|/usr/lib/)")
+ set(is_system 1)
+ endif()
+ endif()
+
+ if(WIN32)
+ string(TOLOWER "$ENV{SystemRoot}" sysroot)
+ string(REGEX REPLACE "\\\\" "/" sysroot "${sysroot}")
+
+ string(TOLOWER "$ENV{windir}" windir)
+ string(REGEX REPLACE "\\\\" "/" windir "${windir}")
+
+ if(lower MATCHES "^(${sysroot}/sys(tem|wow)|${windir}/sys(tem|wow)|(.*/)*msvc[^/]+dll)")
+ set(is_system 1)
+ endif()
+
+ if(UNIX)
+ # if cygwin, we can get the properly formed windows paths from cygpath
+ find_program(CYGPATH_EXECUTABLE cygpath)
+
+ if(CYGPATH_EXECUTABLE)
+ execute_process(COMMAND ${CYGPATH_EXECUTABLE} -W
+ OUTPUT_VARIABLE env_windir
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ execute_process(COMMAND ${CYGPATH_EXECUTABLE} -S
+ OUTPUT_VARIABLE env_sysdir
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ string(TOLOWER "${env_windir}" windir)
+ string(TOLOWER "${env_sysdir}" sysroot)
+
+ if(lower MATCHES "^(${sysroot}/sys(tem|wow)|${windir}/sys(tem|wow)|(.*/)*msvc[^/]+dll)")
+ set(is_system 1)
+ endif()
+ endif(CYGPATH_EXECUTABLE)
+ endif(UNIX)
+ endif(WIN32)
+
+ if(NOT is_system)
+ get_filename_component(original_path "${original_lower}" PATH)
+ get_filename_component(path "${lower}" 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}")
+ set(is_embedded 1)
+ endif()
+ endif()
+ endif()
+ endif()
+ endif()
+
+ # Return type string based on computed booleans:
+ #
+ set(type "other")
+
+ if(is_system)
+ set(type "system")
+ elseif(is_embedded)
+ set(type "embedded")
+ elseif(is_local)
+ set(type "local")
+ endif()
+
+ #message(STATUS "gp_resolved_file_type: '${file}' '${resolved_file}'")
+ #message(STATUS " type: '${type}'")
+
+ if(NOT is_embedded)
+ if(NOT IS_ABSOLUTE "${resolved_file}")
+ if(lower MATCHES "^msvc[^/]+dll" AND is_system)
+ message(STATUS "info: non-absolute msvc file '${file}' returning type '${type}'")
+ else()
+ message(STATUS "warning: gp_resolved_file_type non-absolute file '${file}' returning type '${type}' -- possibly incorrect")
+ endif()
+ endif()
+ endif()
+
+ # Provide a hook so that projects can override the decision on whether a
+ # library belongs to the system or not by whatever logic they choose:
+ #
+ if(COMMAND gp_resolved_file_type_override)
+ gp_resolved_file_type_override("${resolved_file}" type)
+ endif()
+
+ set(${type_var} "${type}" PARENT_SCOPE)
+
+ #message(STATUS "**")
+endfunction()
+
+
+function(gp_file_type original_file file type_var)
+ if(NOT IS_ABSOLUTE "${original_file}")
+ message(STATUS "warning: gp_file_type expects absolute full path for first arg original_file")
+ endif()
+
+ get_filename_component(exepath "${original_file}" PATH)
+
+ set(type "")
+ gp_resolved_file_type("${original_file}" "${file}" "${exepath}" "" type)
+
+ set(${type_var} "${type}" PARENT_SCOPE)
+endfunction(gp_file_type)
+
+
+function(get_prerequisites target prerequisites_var exclude_system recurse exepath dirs)
+ set(verbose 0)
+ set(eol_char "E")
+
+ if(NOT IS_ABSOLUTE "${target}")
+ message("warning: target '${target}' is not absolute...")
+ endif(NOT IS_ABSOLUTE "${target}")
+
+ if(NOT EXISTS "${target}")
+ message("warning: target '${target}' does not exist...")
+ endif(NOT EXISTS "${target}")
+
+ # <setup-gp_tool-vars>
+ #
+ # 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 "")
+ set(gp_tool "ldd")
+ if(APPLE)
+ set(gp_tool "otool")
+ endif(APPLE)
+ if(WIN32 AND NOT UNIX) # This is how to check for cygwin, har!
+ set(gp_tool "dumpbin")
+ endif(WIN32 AND NOT UNIX)
+ endif("${gp_tool}" STREQUAL "")
+
+ set(gp_tool_known 0)
+
+ 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("${gp_tool}" STREQUAL "ldd")
+
+ if("${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("${gp_tool}" STREQUAL "otool")
+
+ if("${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)
+ set(ENV{VS_UNICODE_OUTPUT} "") # Block extra output from inside VS IDE.
+ endif("${gp_tool}" STREQUAL "dumpbin")
+
+ if(NOT gp_tool_known)
+ 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 and otool.")
+ return()
+ endif(NOT gp_tool_known)
+
+ set(gp_cmd_paths ${gp_cmd_paths}
+ "C:/Program Files/Microsoft Visual Studio 9.0/VC/bin"
+ "C:/Program Files (x86)/Microsoft Visual Studio 9.0/VC/bin"
+ "C:/Program Files/Microsoft Visual Studio 8/VC/BIN"
+ "C:/Program Files (x86)/Microsoft Visual Studio 8/VC/BIN"
+ "C:/Program Files/Microsoft Visual Studio .NET 2003/VC7/BIN"
+ "C:/Program Files (x86)/Microsoft Visual Studio .NET 2003/VC7/BIN"
+ "/usr/local/bin"
+ "/usr/bin"
+ )
+
+ find_program(gp_cmd ${gp_tool} PATHS ${gp_cmd_paths})
+
+ if(NOT gp_cmd)
+ message(STATUS "warning: could not find '${gp_tool}' - cannot analyze prerequisites...")
+ return()
+ endif(NOT gp_cmd)
+
+ 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
+ # different command prompt.
+ #
+ get_filename_component(gp_cmd_dir "${gp_cmd}" PATH)
+ get_filename_component(gp_cmd_dlls_dir "${gp_cmd_dir}/../../Common7/IDE" ABSOLUTE)
+ # Use cmake paths as a user may have a PATH element ending with a backslash.
+ # This will escape the list delimiter and create havoc!
+ if(EXISTS "${gp_cmd_dlls_dir}")
+ # only add to the path if it is not already in the path
+ 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}")
+ set(gp_found_cmd_dlls_dir 1)
+ endif()
+ endforeach(gp_env_path_element)
+
+ if(NOT gp_found_cmd_dlls_dir)
+ file(TO_NATIVE_PATH "${gp_cmd_dlls_dir}" gp_cmd_dlls_dir)
+ set(ENV{PATH} "$ENV{PATH};${gp_cmd_dlls_dir}")
+ endif()
+ endif(EXISTS "${gp_cmd_dlls_dir}")
+ endif("${gp_tool}" STREQUAL "dumpbin")
+ #
+ # </setup-gp_tool-vars>
+
+ 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}")
+ endforeach(dir)
+ endif("${gp_tool}" STREQUAL "ldd")
+
+
+ # Track new prerequisites at each new level of recursion. Start with an
+ # empty list at each level:
+ #
+ set(unseen_prereqs)
+
+ # Run gp_cmd on the target:
+ #
+ execute_process(
+ COMMAND ${gp_cmd} ${gp_cmd_args} ${target}
+ OUTPUT_VARIABLE gp_cmd_ov
+ )
+
+ if("${gp_tool}" STREQUAL "ldd")
+ set(ENV{LD_LIBRARY_PATH} "${old_ld_env}")
+ endif("${gp_tool}" STREQUAL "ldd")
+
+ if(verbose)
+ message(STATUS "<RawOutput cmd='${gp_cmd} ${gp_cmd_args} ${target}'>")
+ message(STATUS "gp_cmd_ov='${gp_cmd_ov}'")
+ message(STATUS "</RawOutput>")
+ endif(verbose)
+
+ get_filename_component(target_dir "${target}" PATH)
+
+ # Convert to a list of lines:
+ #
+ string(REGEX REPLACE ";" "\\\\;" candidates "${gp_cmd_ov}")
+ string(REGEX 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")
+ execute_process(
+ COMMAND otool -D ${target}
+ OUTPUT_VARIABLE gp_install_id_ov
+ )
+ # second line is install name
+ string(REGEX REPLACE ".*:\n" "" gp_install_id "${gp_install_id_ov}")
+ if(gp_install_id)
+ # trim
+ string(REGEX MATCH "[^\n ].*[^\n ]" gp_install_id "${gp_install_id}")
+ #message("INSTALL ID is \"${gp_install_id}\"")
+ endif(gp_install_id)
+ endif("${gp_tool}" STREQUAL "otool")
+
+ # Analyze each line for file names that match the regular expression:
+ #
+ foreach(candidate ${candidates})
+ if("${candidate}" MATCHES "${gp_regex}")
+
+ # Extract information from each candidate:
+ if(gp_regex_error AND "${candidate}" MATCHES "${gp_regex_error}")
+ string(REGEX REPLACE "${gp_regex_fallback}" "\\1" raw_item "${candidate}")
+ else(gp_regex_error AND "${candidate}" MATCHES "${gp_regex_error}")
+ string(REGEX REPLACE "${gp_regex}" "\\1" raw_item "${candidate}")
+ endif(gp_regex_error AND "${candidate}" MATCHES "${gp_regex_error}")
+
+ if(gp_regex_cmp_count GREATER 1)
+ string(REGEX REPLACE "${gp_regex}" "\\2" raw_compat_version "${candidate}")
+ string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\1" compat_major_version "${raw_compat_version}")
+ string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\2" compat_minor_version "${raw_compat_version}")
+ string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\3" compat_patch_version "${raw_compat_version}")
+ endif(gp_regex_cmp_count GREATER 1)
+
+ if(gp_regex_cmp_count GREATER 2)
+ string(REGEX REPLACE "${gp_regex}" "\\3" raw_current_version "${candidate}")
+ string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\1" current_major_version "${raw_current_version}")
+ string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\2" current_minor_version "${raw_current_version}")
+ string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\3" current_patch_version "${raw_current_version}")
+ endif(gp_regex_cmp_count GREATER 2)
+
+ # Use the raw_item as the list entries returned by this function. Use the
+ # gp_resolve_item function to resolve it to an actual full path file if
+ # necessary.
+ #
+ set(item "${raw_item}")
+
+ # Add each item unless it is excluded:
+ #
+ set(add_item 1)
+
+ if("${item}" STREQUAL "${gp_install_id}")
+ set(add_item 0)
+ endif("${item}" STREQUAL "${gp_install_id}")
+
+ if(add_item AND ${exclude_system})
+ set(type "")
+ gp_resolved_file_type("${target}" "${item}" "${exepath}" "${dirs}" type)
+
+ if("${type}" STREQUAL "system")
+ set(add_item 0)
+ endif("${type}" STREQUAL "system")
+ endif(add_item AND ${exclude_system})
+
+ if(add_item)
+ list(LENGTH ${prerequisites_var} list_length_before_append)
+ gp_append_unique(${prerequisites_var} "${item}")
+ list(LENGTH ${prerequisites_var} list_length_after_append)
+
+ if(${recurse})
+ # If item was really added, this is the first time we have seen it.
+ # Add it to unseen_prereqs so that we can recursively add *its*
+ # prerequisites...
+ #
+ # But first: resolve its name to an absolute full path name such
+ # 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)
+ set(unseen_prereqs ${unseen_prereqs} "${resolved_item}")
+ endif(NOT list_length_before_append EQUAL list_length_after_append)
+ endif(${recurse})
+ endif(add_item)
+ else("${candidate}" MATCHES "${gp_regex}")
+ if(verbose)
+ message(STATUS "ignoring non-matching line: '${candidate}'")
+ endif(verbose)
+ endif("${candidate}" MATCHES "${gp_regex}")
+ endforeach(candidate)
+
+ list(LENGTH ${prerequisites_var} prerequisites_var_length)
+ if(prerequisites_var_length GREATER 0)
+ list(SORT ${prerequisites_var})
+ endif(prerequisites_var_length GREATER 0)
+ if(${recurse})
+ set(more_inputs ${unseen_prereqs})
+ foreach(input ${more_inputs})
+ get_prerequisites("${input}" ${prerequisites_var} ${exclude_system} ${recurse} "${exepath}" "${dirs}")
+ endforeach(input)
+ endif(${recurse})
+
+ set(${prerequisites_var} ${${prerequisites_var}} PARENT_SCOPE)
+endfunction(get_prerequisites)
+
+
+function(list_prerequisites target)
+ if("${ARGV1}" STREQUAL "")
+ set(all 1)
+ else("${ARGV1}" STREQUAL "")
+ set(all "${ARGV1}")
+ endif("${ARGV1}" STREQUAL "")
+
+ if("${ARGV2}" STREQUAL "")
+ set(exclude_system 0)
+ else("${ARGV2}" STREQUAL "")
+ set(exclude_system "${ARGV2}")
+ endif("${ARGV2}" STREQUAL "")
+
+ if("${ARGV3}" STREQUAL "")
+ set(verbose 0)
+ else("${ARGV3}" STREQUAL "")
+ set(verbose "${ARGV3}")
+ endif("${ARGV3}" STREQUAL "")
+
+ set(count 0)
+ set(count_str "")
+ set(print_count "${verbose}")
+ set(print_prerequisite_type "${verbose}")
+ set(print_target "${verbose}")
+ set(type_str "")
+
+ get_filename_component(exepath "${target}" PATH)
+
+ set(prereqs "")
+ get_prerequisites("${target}" prereqs ${exclude_system} ${all} "${exepath}" "")
+
+ if(print_target)
+ message(STATUS "File '${target}' depends on:")
+ endif(print_target)
+
+ foreach(d ${prereqs})
+ math(EXPR count "${count} + 1")
+
+ if(print_count)
+ set(count_str "${count}. ")
+ endif(print_count)
+
+ if(print_prerequisite_type)
+ gp_file_type("${target}" "${d}" type)
+ set(type_str " (${type})")
+ endif(print_prerequisite_type)
+
+ message(STATUS "${count_str}${d}${type_str}")
+ endforeach(d)
+endfunction(list_prerequisites)
+
+
+function(list_prerequisites_by_glob glob_arg glob_exp)
+ message(STATUS "=============================================================================")
+ message(STATUS "List prerequisites of executables matching ${glob_arg} '${glob_exp}'")
+ message(STATUS "")
+ file(${glob_arg} file_list ${glob_exp})
+ foreach(f ${file_list})
+ is_file_executable("${f}" is_f_executable)
+ if(is_f_executable)
+ message(STATUS "=============================================================================")
+ list_prerequisites("${f}" ${ARGN})
+ message(STATUS "")
+ endif(is_f_executable)
+ endforeach(f)
+endfunction(list_prerequisites_by_glob)
diff --git a/Modules/ITKCompatibility.cmake b/Modules/ITKCompatibility.cmake
new file mode 100644
index 000000000..efd9c284e
--- /dev/null
+++ b/Modules/ITKCompatibility.cmake
@@ -0,0 +1,17 @@
+
+#=============================================================================
+# Copyright 2006-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.)
+
+# work around an old bug in ITK prior to verison 3.0
+SET(TIFF_RIGHT_VERSION 1)
+
diff --git a/Modules/InstallRequiredSystemLibraries.cmake b/Modules/InstallRequiredSystemLibraries.cmake
new file mode 100644
index 000000000..65d254a4a
--- /dev/null
+++ b/Modules/InstallRequiredSystemLibraries.cmake
@@ -0,0 +1,401 @@
+# 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.
+
+#=============================================================================
+# Copyright 2006-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.)
+
+IF(MSVC)
+ FILE(TO_CMAKE_PATH "$ENV{SYSTEMROOT}" SYSTEMROOT)
+
+ IF(CMAKE_CL_64)
+ IF(MSVC_VERSION GREATER 1599)
+ # VS 10 and later:
+ SET(CMAKE_MSVC_ARCH x64)
+ ELSE()
+ # VS 9 and earlier:
+ SET(CMAKE_MSVC_ARCH amd64)
+ ENDIF()
+ ELSE(CMAKE_CL_64)
+ SET(CMAKE_MSVC_ARCH x86)
+ ENDIF(CMAKE_CL_64)
+
+ GET_FILENAME_COMPONENT(devenv_dir "${CMAKE_MAKE_PROGRAM}" PATH)
+ GET_FILENAME_COMPONENT(base_dir "${devenv_dir}/../.." ABSOLUTE)
+
+ IF(MSVC70)
+ SET(__install__libs
+ "${SYSTEMROOT}/system32/msvcp70.dll"
+ "${SYSTEMROOT}/system32/msvcr70.dll"
+ )
+ ENDIF(MSVC70)
+
+ IF(MSVC71)
+ SET(__install__libs
+ "${SYSTEMROOT}/system32/msvcp71.dll"
+ "${SYSTEMROOT}/system32/msvcr71.dll"
+ )
+ ENDIF(MSVC71)
+
+ IF(MSVC80)
+ # Find the runtime library redistribution directory.
+ GET_FILENAME_COMPONENT(msvc_install_dir
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\8.0;InstallDir]" ABSOLUTE)
+ FIND_PATH(MSVC80_REDIST_DIR NAMES ${CMAKE_MSVC_ARCH}/Microsoft.VC80.CRT/Microsoft.VC80.CRT.manifest
+ PATHS
+ "${msvc_install_dir}/../../VC/redist"
+ "${base_dir}/VC/redist"
+ )
+ MARK_AS_ADVANCED(MSVC80_REDIST_DIR)
+ SET(MSVC80_CRT_DIR "${MSVC80_REDIST_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.VC80.CRT")
+
+ # Install the manifest that allows DLLs to be loaded from the
+ # directory containing the executable.
+ IF(NOT CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY)
+ SET(__install__libs
+ "${MSVC80_CRT_DIR}/Microsoft.VC80.CRT.manifest"
+ "${MSVC80_CRT_DIR}/msvcm80.dll"
+ "${MSVC80_CRT_DIR}/msvcp80.dll"
+ "${MSVC80_CRT_DIR}/msvcr80.dll"
+ )
+ ENDIF(NOT CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY)
+
+ IF(CMAKE_INSTALL_DEBUG_LIBRARIES)
+ SET(MSVC80_CRT_DIR
+ "${MSVC80_REDIST_DIR}/Debug_NonRedist/${CMAKE_MSVC_ARCH}/Microsoft.VC80.DebugCRT")
+ SET(__install__libs ${__install__libs}
+ "${MSVC80_CRT_DIR}/Microsoft.VC80.DebugCRT.manifest"
+ "${MSVC80_CRT_DIR}/msvcm80d.dll"
+ "${MSVC80_CRT_DIR}/msvcp80d.dll"
+ "${MSVC80_CRT_DIR}/msvcr80d.dll"
+ )
+ ENDIF(CMAKE_INSTALL_DEBUG_LIBRARIES)
+ ENDIF(MSVC80)
+
+ IF(MSVC90)
+ # Find the runtime library redistribution directory.
+ GET_FILENAME_COMPONENT(msvc_install_dir
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\9.0;InstallDir]" ABSOLUTE)
+ GET_FILENAME_COMPONENT(msvc_express_install_dir
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\9.0;InstallDir]" ABSOLUTE)
+ FIND_PATH(MSVC90_REDIST_DIR NAMES ${CMAKE_MSVC_ARCH}/Microsoft.VC90.CRT/Microsoft.VC90.CRT.manifest
+ PATHS
+ "${msvc_install_dir}/../../VC/redist"
+ "${msvc_express_install_dir}/../../VC/redist"
+ "${base_dir}/VC/redist"
+ )
+ MARK_AS_ADVANCED(MSVC90_REDIST_DIR)
+ SET(MSVC90_CRT_DIR "${MSVC90_REDIST_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.VC90.CRT")
+
+ # Install the manifest that allows DLLs to be loaded from the
+ # directory containing the executable.
+ IF(NOT CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY)
+ SET(__install__libs
+ "${MSVC90_CRT_DIR}/Microsoft.VC90.CRT.manifest"
+ "${MSVC90_CRT_DIR}/msvcm90.dll"
+ "${MSVC90_CRT_DIR}/msvcp90.dll"
+ "${MSVC90_CRT_DIR}/msvcr90.dll"
+ )
+ ENDIF(NOT CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY)
+
+ IF(CMAKE_INSTALL_DEBUG_LIBRARIES)
+ SET(MSVC90_CRT_DIR
+ "${MSVC90_REDIST_DIR}/Debug_NonRedist/${CMAKE_MSVC_ARCH}/Microsoft.VC90.DebugCRT")
+ SET(__install__libs ${__install__libs}
+ "${MSVC90_CRT_DIR}/Microsoft.VC90.DebugCRT.manifest"
+ "${MSVC90_CRT_DIR}/msvcm90d.dll"
+ "${MSVC90_CRT_DIR}/msvcp90d.dll"
+ "${MSVC90_CRT_DIR}/msvcr90d.dll"
+ )
+ ENDIF(CMAKE_INSTALL_DEBUG_LIBRARIES)
+ ENDIF(MSVC90)
+
+ MACRO(MSVCRT_FILES_FOR_VERSION version)
+ SET(v "${version}")
+
+ # Find the runtime library redistribution directory.
+ GET_FILENAME_COMPONENT(msvc_install_dir
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\${v}.0;InstallDir]" ABSOLUTE)
+ FIND_PATH(MSVC${v}_REDIST_DIR NAMES ${CMAKE_MSVC_ARCH}/Microsoft.VC${v}0.CRT
+ PATHS
+ "${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"
+ )
+ MARK_AS_ADVANCED(MSVC${v}_REDIST_DIR)
+ SET(MSVC${v}_CRT_DIR "${MSVC${v}_REDIST_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.VC${v}0.CRT")
+
+ 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"
+ )
+ ENDIF(NOT CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY)
+
+ IF(CMAKE_INSTALL_DEBUG_LIBRARIES)
+ SET(MSVC${v}_CRT_DIR
+ "${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"
+ )
+ ENDIF(CMAKE_INSTALL_DEBUG_LIBRARIES)
+ ENDMACRO()
+
+ IF(MSVC10)
+ MSVCRT_FILES_FOR_VERSION(10)
+ ENDIF()
+
+ IF(MSVC11)
+ MSVCRT_FILES_FOR_VERSION(11)
+ ENDIF()
+
+ IF(CMAKE_INSTALL_MFC_LIBRARIES)
+ IF(MSVC70)
+ SET(__install__libs ${__install__libs}
+ "${SYSTEMROOT}/system32/mfc70.dll"
+ )
+ ENDIF(MSVC70)
+
+ IF(MSVC71)
+ SET(__install__libs ${__install__libs}
+ "${SYSTEMROOT}/system32/mfc71.dll"
+ )
+ ENDIF(MSVC71)
+
+ IF(MSVC80)
+ IF(CMAKE_INSTALL_DEBUG_LIBRARIES)
+ SET(MSVC80_MFC_DIR
+ "${MSVC80_REDIST_DIR}/Debug_NonRedist/${CMAKE_MSVC_ARCH}/Microsoft.VC80.DebugMFC")
+ SET(__install__libs ${__install__libs}
+ "${MSVC80_MFC_DIR}/Microsoft.VC80.DebugMFC.manifest"
+ "${MSVC80_MFC_DIR}/mfc80d.dll"
+ "${MSVC80_MFC_DIR}/mfc80ud.dll"
+ "${MSVC80_MFC_DIR}/mfcm80d.dll"
+ "${MSVC80_MFC_DIR}/mfcm80ud.dll"
+ )
+ ENDIF(CMAKE_INSTALL_DEBUG_LIBRARIES)
+
+ SET(MSVC80_MFC_DIR "${MSVC80_REDIST_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.VC80.MFC")
+ # Install the manifest that allows DLLs to be loaded from the
+ # directory containing the executable.
+ IF(NOT CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY)
+ SET(__install__libs ${__install__libs}
+ "${MSVC80_MFC_DIR}/Microsoft.VC80.MFC.manifest"
+ "${MSVC80_MFC_DIR}/mfc80.dll"
+ "${MSVC80_MFC_DIR}/mfc80u.dll"
+ "${MSVC80_MFC_DIR}/mfcm80.dll"
+ "${MSVC80_MFC_DIR}/mfcm80u.dll"
+ )
+ ENDIF(NOT CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY)
+
+ # include the language dll's for vs8 as well as the actuall dll's
+ SET(MSVC80_MFCLOC_DIR "${MSVC80_REDIST_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.VC80.MFCLOC")
+ # Install the manifest that allows DLLs to be loaded from the
+ # directory containing the executable.
+ SET(__install__libs ${__install__libs}
+ "${MSVC80_MFCLOC_DIR}/Microsoft.VC80.MFCLOC.manifest"
+ "${MSVC80_MFCLOC_DIR}/mfc80chs.dll"
+ "${MSVC80_MFCLOC_DIR}/mfc80cht.dll"
+ "${MSVC80_MFCLOC_DIR}/mfc80enu.dll"
+ "${MSVC80_MFCLOC_DIR}/mfc80esp.dll"
+ "${MSVC80_MFCLOC_DIR}/mfc80deu.dll"
+ "${MSVC80_MFCLOC_DIR}/mfc80fra.dll"
+ "${MSVC80_MFCLOC_DIR}/mfc80ita.dll"
+ "${MSVC80_MFCLOC_DIR}/mfc80jpn.dll"
+ "${MSVC80_MFCLOC_DIR}/mfc80kor.dll"
+ )
+ ENDIF(MSVC80)
+
+ IF(MSVC90)
+ IF(CMAKE_INSTALL_DEBUG_LIBRARIES)
+ SET(MSVC90_MFC_DIR
+ "${MSVC90_REDIST_DIR}/Debug_NonRedist/${CMAKE_MSVC_ARCH}/Microsoft.VC90.DebugMFC")
+ SET(__install__libs ${__install__libs}
+ "${MSVC90_MFC_DIR}/Microsoft.VC90.DebugMFC.manifest"
+ "${MSVC90_MFC_DIR}/mfc90d.dll"
+ "${MSVC90_MFC_DIR}/mfc90ud.dll"
+ "${MSVC90_MFC_DIR}/mfcm90d.dll"
+ "${MSVC90_MFC_DIR}/mfcm90ud.dll"
+ )
+ ENDIF(CMAKE_INSTALL_DEBUG_LIBRARIES)
+
+ SET(MSVC90_MFC_DIR "${MSVC90_REDIST_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.VC90.MFC")
+ # Install the manifest that allows DLLs to be loaded from the
+ # directory containing the executable.
+ IF(NOT CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY)
+ SET(__install__libs ${__install__libs}
+ "${MSVC90_MFC_DIR}/Microsoft.VC90.MFC.manifest"
+ "${MSVC90_MFC_DIR}/mfc90.dll"
+ "${MSVC90_MFC_DIR}/mfc90u.dll"
+ "${MSVC90_MFC_DIR}/mfcm90.dll"
+ "${MSVC90_MFC_DIR}/mfcm90u.dll"
+ )
+ ENDIF(NOT CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY)
+
+ # include the language dll's for vs9 as well as the actuall dll's
+ SET(MSVC90_MFCLOC_DIR "${MSVC90_REDIST_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.VC90.MFCLOC")
+ # Install the manifest that allows DLLs to be loaded from the
+ # directory containing the executable.
+ SET(__install__libs ${__install__libs}
+ "${MSVC90_MFCLOC_DIR}/Microsoft.VC90.MFCLOC.manifest"
+ "${MSVC90_MFCLOC_DIR}/mfc90chs.dll"
+ "${MSVC90_MFCLOC_DIR}/mfc90cht.dll"
+ "${MSVC90_MFCLOC_DIR}/mfc90enu.dll"
+ "${MSVC90_MFCLOC_DIR}/mfc90esp.dll"
+ "${MSVC90_MFCLOC_DIR}/mfc90deu.dll"
+ "${MSVC90_MFCLOC_DIR}/mfc90fra.dll"
+ "${MSVC90_MFCLOC_DIR}/mfc90ita.dll"
+ "${MSVC90_MFCLOC_DIR}/mfc90jpn.dll"
+ "${MSVC90_MFCLOC_DIR}/mfc90kor.dll"
+ )
+ ENDIF(MSVC90)
+
+ MACRO(MFC_FILES_FOR_VERSION version)
+ SET(v "${version}")
+
+ 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"
+ )
+ ENDIF(CMAKE_INSTALL_DEBUG_LIBRARIES)
+
+ 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"
+ )
+ ENDIF(NOT CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY)
+
+ # include the language dll's as well as the actuall dll's
+ SET(MSVC${v}_MFCLOC_DIR "${MSVC${v}_REDIST_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.VC${v}0.MFCLOC")
+ SET(__install__libs ${__install__libs}
+ "${MSVC${v}_MFCLOC_DIR}/mfc${v}0chs.dll"
+ "${MSVC${v}_MFCLOC_DIR}/mfc${v}0cht.dll"
+ "${MSVC${v}_MFCLOC_DIR}/mfc${v}0enu.dll"
+ "${MSVC${v}_MFCLOC_DIR}/mfc${v}0esp.dll"
+ "${MSVC${v}_MFCLOC_DIR}/mfc${v}0deu.dll"
+ "${MSVC${v}_MFCLOC_DIR}/mfc${v}0fra.dll"
+ "${MSVC${v}_MFCLOC_DIR}/mfc${v}0ita.dll"
+ "${MSVC${v}_MFCLOC_DIR}/mfc${v}0jpn.dll"
+ "${MSVC${v}_MFCLOC_DIR}/mfc${v}0kor.dll"
+ )
+ ENDMACRO()
+
+ IF(MSVC10)
+ MFC_FILES_FOR_VERSION(10)
+ ENDIF()
+
+ IF(MSVC11)
+ MFC_FILES_FOR_VERSION(11)
+ ENDIF()
+ ENDIF(CMAKE_INSTALL_MFC_LIBRARIES)
+
+ FOREACH(lib
+ ${__install__libs}
+ )
+ IF(EXISTS ${lib})
+ SET(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS
+ ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS} ${lib})
+ ELSE(EXISTS ${lib})
+ IF(NOT CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS)
+ MESSAGE(WARNING "system runtime library file does not exist: '${lib}'")
+ # This warning indicates an incomplete Visual Studio installation
+ # or a bug somewhere above here in this file.
+ # If you would like to avoid this warning, fix the real problem, or
+ # set CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS before including
+ # this file.
+ ENDIF()
+ ENDIF(EXISTS ${lib})
+ ENDFOREACH(lib)
+ENDIF(MSVC)
+
+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 )
+ ENDIF()
+ FOREACH(lib
+ ${__install__libs}
+ )
+ IF(EXISTS ${lib})
+ SET(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS
+ ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS} ${lib})
+ ELSE()
+ IF(NOT CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS)
+ MESSAGE(WARNING "system runtime library file does not exist: '${lib}'")
+ # This warning indicates an incomplete Watcom installation
+ # or a bug somewhere above here in this file.
+ # If you would like to avoid this warning, fix the real problem, or
+ # set CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS before including
+ # this file.
+ ENDIF()
+ ENDIF()
+ ENDFOREACH()
+ENDIF()
+
+
+# Include system runtime libraries in the installation if any are
+# specified by CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS.
+IF(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS)
+ IF(NOT CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP)
+ IF(NOT CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION)
+ IF(WIN32)
+ SET(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION bin)
+ ELSE(WIN32)
+ SET(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION lib)
+ ENDIF(WIN32)
+ ENDIF(NOT CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION)
+ INSTALL(PROGRAMS ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS}
+ DESTINATION ${CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION})
+ ENDIF(NOT CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP)
+ENDIF(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS)
diff --git a/Modules/IntelVSImplicitPath/CMakeLists.txt b/Modules/IntelVSImplicitPath/CMakeLists.txt
new file mode 100644
index 000000000..96dc4e612
--- /dev/null
+++ b/Modules/IntelVSImplicitPath/CMakeLists.txt
@@ -0,0 +1,7 @@
+cmake_minimum_required (VERSION 2.8)
+project(IntelFortranImplicit Fortran)
+add_custom_command(
+ OUTPUT output.cmake
+ COMMAND ${CMAKE_COMMAND} -P ${IntelFortranImplicit_SOURCE_DIR}/detect.cmake
+ )
+add_library(FortranLib hello.f output.cmake)
diff --git a/Modules/IntelVSImplicitPath/detect.cmake b/Modules/IntelVSImplicitPath/detect.cmake
new file mode 100644
index 000000000..20753bef4
--- /dev/null
+++ b/Modules/IntelVSImplicitPath/detect.cmake
@@ -0,0 +1,9 @@
+# look at each path and try to find ifconsol.lib
+set(LIB "$ENV{LIB}")
+foreach(dir ${LIB})
+ file(TO_CMAKE_PATH "${dir}" dir)
+ if(EXISTS "${dir}/ifconsol.lib")
+ file(WRITE output.cmake "list(APPEND implicit_dirs \"${dir}\")\n")
+ break()
+ endif()
+endforeach()
diff --git a/Modules/IntelVSImplicitPath/hello.f b/Modules/IntelVSImplicitPath/hello.f
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Modules/IntelVSImplicitPath/hello.f
diff --git a/Modules/KDE3Macros.cmake b/Modules/KDE3Macros.cmake
new file mode 100644
index 000000000..5b76000e8
--- /dev/null
+++ b/Modules/KDE3Macros.cmake
@@ -0,0 +1,411 @@
+#
+
+#=============================================================================
+# Copyright 2006-2009 Kitware, Inc.
+# Copyright 2006 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.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+# See FindKDE3.cmake for documentation.
+#
+# this file contains the following macros:
+# KDE3_ADD_DCOP_SKELS
+# KDE3_ADD_DCOP_STUBS
+# KDE3_ADD_MOC_FILES
+# KDE3_ADD_UI_FILES
+# KDE3_ADD_KCFG_FILES
+# KDE3_AUTOMOC
+# KDE3_INSTALL_LIBTOOL_FILE
+# KDE3_CREATE_FINAL_FILE
+# KDE3_ADD_KPART
+# KDE3_ADD_KDEINIT_EXECUTABLE
+# KDE3_ADD_EXECUTABLE
+
+
+#neundorf@kde.org
+
+INCLUDE(AddFileDependencies)
+
+#create the kidl and skeletion file for dcop stuff
+#usage: KDE_ADD_COP_SKELS(foo_SRCS ${dcop_headers})
+MACRO(KDE3_ADD_DCOP_SKELS _sources)
+ FOREACH (_current_FILE ${ARGN})
+
+ GET_FILENAME_COMPONENT(_tmp_FILE ${_current_FILE} ABSOLUTE)
+ GET_FILENAME_COMPONENT(_basename ${_tmp_FILE} NAME_WE)
+
+ SET(_skel ${CMAKE_CURRENT_BINARY_DIR}/${_basename}_skel.cpp)
+ SET(_kidl ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.kidl)
+
+ IF (NOT HAVE_${_basename}_KIDL_RULE)
+ SET(HAVE_${_basename}_KIDL_RULE ON)
+
+ ADD_CUSTOM_COMMAND(OUTPUT ${_kidl}
+ COMMAND ${KDE3_DCOPIDL_EXECUTABLE}
+ ARGS ${_tmp_FILE} > ${_kidl}
+ DEPENDS ${_tmp_FILE}
+ )
+
+ ENDIF (NOT HAVE_${_basename}_KIDL_RULE)
+
+ IF (NOT HAVE_${_basename}_SKEL_RULE)
+ SET(HAVE_${_basename}_SKEL_RULE ON)
+
+ ADD_CUSTOM_COMMAND(OUTPUT ${_skel}
+ COMMAND ${KDE3_DCOPIDL2CPP_EXECUTABLE}
+ ARGS --c++-suffix cpp --no-signals --no-stub ${_kidl}
+ DEPENDS ${_kidl}
+ )
+
+ ENDIF (NOT HAVE_${_basename}_SKEL_RULE)
+
+ SET(${_sources} ${${_sources}} ${_skel})
+
+ ENDFOREACH (_current_FILE)
+
+ENDMACRO(KDE3_ADD_DCOP_SKELS)
+
+
+MACRO(KDE3_ADD_DCOP_STUBS _sources)
+ FOREACH (_current_FILE ${ARGN})
+
+ GET_FILENAME_COMPONENT(_tmp_FILE ${_current_FILE} ABSOLUTE)
+
+ GET_FILENAME_COMPONENT(_basename ${_tmp_FILE} NAME_WE)
+
+ SET(_stub_CPP ${CMAKE_CURRENT_BINARY_DIR}/${_basename}_stub.cpp)
+ SET(_kidl ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.kidl)
+
+ IF (NOT HAVE_${_basename}_KIDL_RULE)
+ SET(HAVE_${_basename}_KIDL_RULE ON)
+
+
+ ADD_CUSTOM_COMMAND(OUTPUT ${_kidl}
+ COMMAND ${KDE3_DCOPIDL_EXECUTABLE}
+ ARGS ${_tmp_FILE} > ${_kidl}
+ DEPENDS ${_tmp_FILE}
+ )
+
+ ENDIF (NOT HAVE_${_basename}_KIDL_RULE)
+
+
+ IF (NOT HAVE_${_basename}_STUB_RULE)
+ SET(HAVE_${_basename}_STUB_RULE ON)
+
+ ADD_CUSTOM_COMMAND(OUTPUT ${_stub_CPP}
+ COMMAND ${KDE3_DCOPIDL2CPP_EXECUTABLE}
+ ARGS --c++-suffix cpp --no-signals --no-skel ${_kidl}
+ DEPENDS ${_kidl}
+ )
+
+ ENDIF (NOT HAVE_${_basename}_STUB_RULE)
+
+ SET(${_sources} ${${_sources}} ${_stub_CPP})
+
+ ENDFOREACH (_current_FILE)
+
+ENDMACRO(KDE3_ADD_DCOP_STUBS)
+
+
+MACRO(KDE3_ADD_KCFG_FILES _sources)
+ FOREACH (_current_FILE ${ARGN})
+
+ GET_FILENAME_COMPONENT(_tmp_FILE ${_current_FILE} ABSOLUTE)
+
+ GET_FILENAME_COMPONENT(_basename ${_tmp_FILE} NAME_WE)
+
+ FILE(READ ${_tmp_FILE} _contents)
+ STRING(REGEX REPLACE "^(.*\n)?File=([^\n]+)\n.*$" "\\2" _kcfg_FILE "${_contents}")
+
+ SET(_src_FILE ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.cpp)
+ SET(_header_FILE ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.h)
+
+ ADD_CUSTOM_COMMAND(OUTPUT ${_src_FILE}
+ COMMAND ${KDE3_KCFGC_EXECUTABLE}
+ ARGS ${CMAKE_CURRENT_SOURCE_DIR}/${_kcfg_FILE} ${_tmp_FILE}
+ DEPENDS ${_tmp_FILE} ${CMAKE_CURRENT_SOURCE_DIR}/${_kcfg_FILE} )
+
+ SET(${_sources} ${${_sources}} ${_src_FILE})
+
+ ENDFOREACH (_current_FILE)
+
+ENDMACRO(KDE3_ADD_KCFG_FILES)
+
+
+#create the moc files and add them to the list of sources
+#usage: KDE_ADD_MOC_FILES(foo_SRCS ${moc_headers})
+MACRO(KDE3_ADD_MOC_FILES _sources)
+ FOREACH (_current_FILE ${ARGN})
+
+ GET_FILENAME_COMPONENT(_tmp_FILE ${_current_FILE} ABSOLUTE)
+
+ GET_FILENAME_COMPONENT(_basename ${_tmp_FILE} NAME_WE)
+ SET(_moc ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.moc.cpp)
+
+ ADD_CUSTOM_COMMAND(OUTPUT ${_moc}
+ COMMAND ${QT_MOC_EXECUTABLE}
+ ARGS ${_tmp_FILE} -o ${_moc}
+ DEPENDS ${_tmp_FILE}
+ )
+
+ SET(${_sources} ${${_sources}} ${_moc})
+
+ ENDFOREACH (_current_FILE)
+ENDMACRO(KDE3_ADD_MOC_FILES)
+
+
+GET_FILENAME_COMPONENT( KDE3_MODULE_DIR ${CMAKE_CURRENT_LIST_FILE} PATH)
+
+#create the implementation files from the ui files and add them to the list of sources
+#usage: KDE_ADD_UI_FILES(foo_SRCS ${ui_files})
+MACRO(KDE3_ADD_UI_FILES _sources )
+ FOREACH (_current_FILE ${ARGN})
+
+ GET_FILENAME_COMPONENT(_tmp_FILE ${_current_FILE} ABSOLUTE)
+
+ GET_FILENAME_COMPONENT(_basename ${_tmp_FILE} NAME_WE)
+ SET(_header ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.h)
+ SET(_src ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.cpp)
+ SET(_moc ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.moc.cpp)
+
+ ADD_CUSTOM_COMMAND(OUTPUT ${_header}
+ COMMAND ${QT_UIC_EXECUTABLE}
+ ARGS -L ${KDE3_LIB_DIR}/kde3/plugins/designer -nounload -o ${_header} ${CMAKE_CURRENT_SOURCE_DIR}/${_current_FILE}
+ DEPENDS ${_tmp_FILE}
+ )
+
+ ADD_CUSTOM_COMMAND(OUTPUT ${_src}
+ COMMAND ${CMAKE_COMMAND}
+ ARGS
+ -DKDE_UIC_PLUGIN_DIR:FILEPATH=${KDE3_LIB_DIR}/kde3/plugins/designer
+ -DKDE_UIC_EXECUTABLE:FILEPATH=${QT_UIC_EXECUTABLE}
+ -DKDE_UIC_FILE:FILEPATH=${_tmp_FILE}
+ -DKDE_UIC_CPP_FILE:FILEPATH=${_src}
+ -DKDE_UIC_H_FILE:FILEPATH=${_header}
+ -P ${KDE3_MODULE_DIR}/kde3uic.cmake
+ DEPENDS ${_header}
+ )
+
+ ADD_CUSTOM_COMMAND(OUTPUT ${_moc}
+ COMMAND ${QT_MOC_EXECUTABLE}
+ ARGS ${_header} -o ${_moc}
+ DEPENDS ${_header}
+ )
+
+ SET(${_sources} ${${_sources}} ${_src} ${_moc} )
+
+ ENDFOREACH (_current_FILE)
+ENDMACRO(KDE3_ADD_UI_FILES)
+
+
+MACRO(KDE3_AUTOMOC)
+ SET(_matching_FILES )
+ FOREACH (_current_FILE ${ARGN})
+
+ GET_FILENAME_COMPONENT(_abs_FILE ${_current_FILE} ABSOLUTE)
+
+ # if "SKIP_AUTOMOC" is set to true, we will not handle this file here.
+ # here. this is required to make bouic work correctly:
+ # we need to add generated .cpp files to the sources (to compile them),
+ # but we cannot let automoc handle them, as the .cpp files don't exist yet when
+ # cmake is run for the very first time on them -> however the .cpp files might
+ # exist at a later run. at that time we need to skip them, so that we don't add two
+ # different rules for the same moc file
+ GET_SOURCE_FILE_PROPERTY(_skip ${_abs_FILE} SKIP_AUTOMOC)
+
+ IF (EXISTS ${_abs_FILE} AND NOT _skip)
+
+ FILE(READ ${_abs_FILE} _contents)
+
+ GET_FILENAME_COMPONENT(_abs_PATH ${_abs_FILE} PATH)
+
+ STRING(REGEX MATCHALL "#include +[^ ]+\\.moc[\">]" _match "${_contents}")
+ IF(_match)
+ FOREACH (_current_MOC_INC ${_match})
+ STRING(REGEX MATCH "[^ <\"]+\\.moc" _current_MOC "${_current_MOC_INC}")
+
+ GET_FILENAME_COMPONENT(_basename ${_current_MOC} NAME_WE)
+# SET(_header ${CMAKE_CURRENT_SOURCE_DIR}/${_basename}.h)
+ SET(_header ${_abs_PATH}/${_basename}.h)
+ SET(_moc ${CMAKE_CURRENT_BINARY_DIR}/${_current_MOC})
+
+ ADD_CUSTOM_COMMAND(OUTPUT ${_moc}
+ COMMAND ${QT_MOC_EXECUTABLE}
+ ARGS ${_header} -o ${_moc}
+ DEPENDS ${_header}
+ )
+
+ ADD_FILE_DEPENDENCIES(${_abs_FILE} ${_moc})
+
+ ENDFOREACH (_current_MOC_INC)
+ ENDIF(_match)
+
+ ENDIF (EXISTS ${_abs_FILE} AND NOT _skip)
+ ENDFOREACH (_current_FILE)
+ENDMACRO(KDE3_AUTOMOC)
+
+# only used internally by KDE3_INSTALL_ICONS
+MACRO (_KDE3_ADD_ICON_INSTALL_RULE _install_SCRIPT _install_PATH _group _orig_NAME _install_NAME)
+
+ # if the string doesn't match the pattern, the result is the full string, so all three have the same content
+ IF (NOT ${_group} STREQUAL ${_install_NAME} )
+ SET(_icon_GROUP "actions")
+
+ IF (${_group} STREQUAL "mime")
+ SET(_icon_GROUP "mimetypes")
+ ENDIF (${_group} STREQUAL "mime")
+
+ IF (${_group} STREQUAL "filesys")
+ SET(_icon_GROUP "filesystems")
+ ENDIF (${_group} STREQUAL "filesys")
+
+ IF (${_group} STREQUAL "device")
+ SET(_icon_GROUP "devices")
+ ENDIF (${_group} STREQUAL "device")
+
+ IF (${_group} STREQUAL "app")
+ SET(_icon_GROUP "apps")
+ ENDIF (${_group} STREQUAL "app")
+
+ IF (${_group} STREQUAL "action")
+ SET(_icon_GROUP "actions")
+ ENDIF (${_group} STREQUAL "action")
+
+# message(STATUS "icon: ${_current_ICON} size: ${_size} group: ${_group} name: ${_name}" )
+ INSTALL(FILES ${_orig_NAME} DESTINATION ${_install_PATH}/${_icon_GROUP}/ RENAME ${_install_NAME} )
+ ENDIF (NOT ${_group} STREQUAL ${_install_NAME} )
+
+ENDMACRO (_KDE3_ADD_ICON_INSTALL_RULE)
+
+
+MACRO (KDE3_INSTALL_ICONS _theme )
+ SET(_defaultpath "${CMAKE_INSTALL_PREFIX}/share/icons")
+ # first the png icons
+ FILE(GLOB _icons *.png)
+ FOREACH (_current_ICON ${_icons} )
+ STRING(REGEX REPLACE "^.*/[a-zA-Z]+([0-9]+)\\-([a-z]+)\\-(.+\\.png)$" "\\1" _size "${_current_ICON}")
+ STRING(REGEX REPLACE "^.*/[a-zA-Z]+([0-9]+)\\-([a-z]+)\\-(.+\\.png)$" "\\2" _group "${_current_ICON}")
+ STRING(REGEX REPLACE "^.*/[a-zA-Z]+([0-9]+)\\-([a-z]+)\\-(.+\\.png)$" "\\3" _name "${_current_ICON}")
+ _KDE3_ADD_ICON_INSTALL_RULE(${CMAKE_CURRENT_BINARY_DIR}/install_icons.cmake
+ ${_defaultpath}/${_theme}/${_size}x${_size}
+ ${_group} ${_current_ICON} ${_name})
+ ENDFOREACH (_current_ICON)
+
+ # and now the svg icons
+ FILE(GLOB _icons *.svgz)
+ FOREACH (_current_ICON ${_icons} )
+ STRING(REGEX REPLACE "^.*/crsc\\-([a-z]+)\\-(.+\\.svgz)$" "\\1" _group "${_current_ICON}")
+ STRING(REGEX REPLACE "^.*/crsc\\-([a-z]+)\\-(.+\\.svgz)$" "\\2" _name "${_current_ICON}")
+ _KDE3_ADD_ICON_INSTALL_RULE(${CMAKE_CURRENT_BINARY_DIR}/install_icons.cmake
+ ${_defaultpath}/${_theme}/scalable
+ ${_group} ${_current_ICON} ${_name})
+ ENDFOREACH (_current_ICON)
+
+ENDMACRO (KDE3_INSTALL_ICONS)
+
+MACRO(KDE3_INSTALL_LIBTOOL_FILE _target)
+ GET_TARGET_PROPERTY(_target_location ${_target} LOCATION)
+
+ GET_FILENAME_COMPONENT(_laname ${_target_location} NAME_WE)
+ GET_FILENAME_COMPONENT(_soname ${_target_location} NAME)
+ SET(_laname ${CMAKE_CURRENT_BINARY_DIR}/${_laname}.la)
+
+ FILE(WRITE ${_laname} "# ${_laname} - a libtool library file, generated by cmake \n")
+ FILE(APPEND ${_laname} "# The name that we can dlopen(3).\n")
+ FILE(APPEND ${_laname} "dlname='${_soname}'\n")
+ FILE(APPEND ${_laname} "# Names of this library\n")
+ IF(CYGWIN)
+ FILE(APPEND ${_laname} "library_names='${_soname}'\n")
+ ELSE(CYGWIN)
+ FILE(APPEND ${_laname} "library_names='${_soname} ${_soname} ${_soname}'\n")
+ ENDIF(CYGWIN)
+ FILE(APPEND ${_laname} "# The name of the static archive\n")
+ FILE(APPEND ${_laname} "old_library=''\n")
+ FILE(APPEND ${_laname} "# Libraries that this one depends upon.\n")
+ FILE(APPEND ${_laname} "dependency_libs=''\n")
+# FILE(APPEND ${_laname} "dependency_libs='${${_target}_LIB_DEPENDS}'\n")
+ FILE(APPEND ${_laname} "# Version information.\ncurrent=0\nage=0\nrevision=0\n")
+ FILE(APPEND ${_laname} "# Is this an already installed library?\ninstalled=yes\n")
+ FILE(APPEND ${_laname} "# Should we warn about portability when linking against -modules?\nshouldnotlink=yes\n")
+ FILE(APPEND ${_laname} "# Files to dlopen/dlpreopen\ndlopen=''\ndlpreopen=''\n")
+ FILE(APPEND ${_laname} "# Directory that this library needs to be installed in:\n")
+ FILE(APPEND ${_laname} "libdir='${CMAKE_INSTALL_PREFIX}/lib/kde3'\n")
+
+ INSTALL_FILES(${KDE3_LIBTOOL_DIR} FILES ${_laname})
+ENDMACRO(KDE3_INSTALL_LIBTOOL_FILE)
+
+
+MACRO(KDE3_CREATE_FINAL_FILE _filename)
+ FILE(WRITE ${_filename} "//autogenerated file\n")
+ FOREACH (_current_FILE ${ARGN})
+ FILE(APPEND ${_filename} "#include \"${_current_FILE}\"\n")
+ ENDFOREACH (_current_FILE)
+
+ENDMACRO(KDE3_CREATE_FINAL_FILE)
+
+
+# OPTION(KDE3_ENABLE_FINAL "Enable final all-in-one compilation")
+OPTION(KDE3_BUILD_TESTS "Build the tests")
+
+
+MACRO(KDE3_ADD_KPART _target_NAME _with_PREFIX)
+#is the first argument is "WITH_PREFIX" then keep the standard "lib" prefix, otherwise SET the prefix empty
+ IF (${_with_PREFIX} STREQUAL "WITH_PREFIX")
+ SET(_first_SRC)
+ ELSE (${_with_PREFIX} STREQUAL "WITH_PREFIX")
+ SET(_first_SRC ${_with_PREFIX})
+ ENDIF (${_with_PREFIX} STREQUAL "WITH_PREFIX")
+
+# IF (KDE3_ENABLE_FINAL)
+# KDE3_CREATE_FINAL_FILE(${_target_NAME}_final.cpp ${_first_SRC} ${ARGN})
+# ADD_LIBRARY(${_target_NAME} MODULE ${_target_NAME}_final.cpp)
+# ELSE (KDE3_ENABLE_FINAL)
+ ADD_LIBRARY(${_target_NAME} MODULE ${_first_SRC} ${ARGN})
+# ENDIF (KDE3_ENABLE_FINAL)
+
+ IF(_first_SRC)
+ SET_TARGET_PROPERTIES(${_target_NAME} PROPERTIES PREFIX "")
+ ENDIF(_first_SRC)
+
+ KDE3_INSTALL_LIBTOOL_FILE(${_target_NAME})
+
+ENDMACRO(KDE3_ADD_KPART)
+
+
+MACRO(KDE3_ADD_KDEINIT_EXECUTABLE _target_NAME )
+
+# IF (KDE3_ENABLE_FINAL)
+# KDE3_CREATE_FINAL_FILE(${_target_NAME}_final.cpp ${ARGN})
+# ADD_LIBRARY(kdeinit_${_target_NAME} SHARED ${_target_NAME}_final.cpp)
+# ELSE (KDE3_ENABLE_FINAL)
+ ADD_LIBRARY(kdeinit_${_target_NAME} SHARED ${ARGN} )
+# ENDIF (KDE3_ENABLE_FINAL)
+
+ CONFIGURE_FILE(${KDE3_MODULE_DIR}/kde3init_dummy.cpp.in ${CMAKE_CURRENT_BINARY_DIR}/${_target_NAME}_dummy.cpp)
+
+ ADD_EXECUTABLE( ${_target_NAME} ${CMAKE_CURRENT_BINARY_DIR}/${_target_NAME}_dummy.cpp )
+ TARGET_LINK_LIBRARIES( ${_target_NAME} kdeinit_${_target_NAME} )
+
+ENDMACRO(KDE3_ADD_KDEINIT_EXECUTABLE)
+
+
+MACRO(KDE3_ADD_EXECUTABLE _target_NAME )
+
+# IF (KDE3_ENABLE_FINAL)
+# KDE3_CREATE_FINAL_FILE(${_target_NAME}_final.cpp ${ARGN})
+# ADD_EXECUTABLE(${_target_NAME} ${_target_NAME}_final.cpp)
+# ELSE (KDE3_ENABLE_FINAL)
+ ADD_EXECUTABLE(${_target_NAME} ${ARGN} )
+# ENDIF (KDE3_ENABLE_FINAL)
+
+ENDMACRO(KDE3_ADD_EXECUTABLE)
+
+
diff --git a/Modules/MacOSXBundleInfo.plist.in b/Modules/MacOSXBundleInfo.plist.in
new file mode 100644
index 000000000..a466dc7c4
--- /dev/null
+++ b/Modules/MacOSXBundleInfo.plist.in
@@ -0,0 +1,36 @@
+<?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>CFBundleGetInfoString</key>
+ <string>${MACOSX_BUNDLE_INFO_STRING}</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>CFBundleLongVersionString</key>
+ <string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</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>LSRequiresCarbon</key>
+ <true/>
+ <key>NSHumanReadableCopyright</key>
+ <string>${MACOSX_BUNDLE_COPYRIGHT}</string>
+</dict>
+</plist>
diff --git a/Modules/MacOSXFrameworkInfo.plist.in b/Modules/MacOSXFrameworkInfo.plist.in
new file mode 100644
index 000000000..18eaef2f7
--- /dev/null
+++ b/Modules/MacOSXFrameworkInfo.plist.in
@@ -0,0 +1,26 @@
+<?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_FRAMEWORK_NAME}</string>
+ <key>CFBundleIconFile</key>
+ <string>${MACOSX_FRAMEWORK_ICON_FILE}</string>
+ <key>CFBundleIdentifier</key>
+ <string>${MACOSX_FRAMEWORK_IDENTIFIER}</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>FMWK</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>${MACOSX_FRAMEWORK_BUNDLE_VERSION}</string>
+ <key>CFBundleShortVersionString</key>
+ <string>${MACOSX_FRAMEWORK_SHORT_VERSION_STRING}</string>
+ <key>CSResourcesFileMapped</key>
+ <true/>
+</dict>
+</plist>
diff --git a/Modules/MacroAddFileDependencies.cmake b/Modules/MacroAddFileDependencies.cmake
new file mode 100644
index 000000000..527447b80
--- /dev/null
+++ b/Modules/MacroAddFileDependencies.cmake
@@ -0,0 +1,33 @@
+# - 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.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software 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 (MACRO_ADD_FILE_DEPENDENCIES _file)
+
+ GET_SOURCE_FILE_PROPERTY(_deps ${_file} OBJECT_DEPENDS)
+ IF (_deps)
+ SET(_deps ${_deps} ${ARGN})
+ ELSE (_deps)
+ SET(_deps ${ARGN})
+ ENDIF (_deps)
+
+ SET_SOURCE_FILES_PROPERTIES(${_file} PROPERTIES OBJECT_DEPENDS "${_deps}")
+
+ENDMACRO (MACRO_ADD_FILE_DEPENDENCIES)
diff --git a/Modules/NSIS.InstallOptions.ini.in b/Modules/NSIS.InstallOptions.ini.in
new file mode 100644
index 000000000..d92d77959
--- /dev/null
+++ b/Modules/NSIS.InstallOptions.ini.in
@@ -0,0 +1,46 @@
+[Settings]
+NumFields=5
+
+[Field 1]
+Type=label
+Text=By default @CPACK_PACKAGE_INSTALL_DIRECTORY@ does not add its directory to the system PATH.
+Left=0
+Right=-1
+Top=0
+Bottom=20
+
+[Field 2]
+Type=radiobutton
+Text=Do not add @CPACK_PACKAGE_NAME@ to the system PATH
+Left=0
+Right=-1
+Top=30
+Bottom=40
+State=1
+
+[Field 3]
+Type=radiobutton
+Text=Add @CPACK_PACKAGE_NAME@ to the system PATH for all users
+Left=0
+Right=-1
+Top=40
+Bottom=50
+State=0
+
+[Field 4]
+Type=radiobutton
+Text=Add @CPACK_PACKAGE_NAME@ to the system PATH for current user
+Left=0
+Right=-1
+Top=50
+Bottom=60
+State=0
+
+[Field 5]
+Type=CheckBox
+Text=Create @CPACK_PACKAGE_NAME@ Desktop Icon
+Left=0
+Right=-1
+Top=80
+Bottom=90
+State=0
diff --git a/Modules/NSIS.template.in b/Modules/NSIS.template.in
new file mode 100644
index 000000000..43f72f6aa
--- /dev/null
+++ b/Modules/NSIS.template.in
@@ -0,0 +1,972 @@
+; CPack install script designed for a nmake build
+
+;--------------------------------
+; You must define these values
+
+ !define VERSION "@CPACK_PACKAGE_VERSION@"
+ !define PATCH "@CPACK_PACKAGE_VERSION_PATCH@"
+ !define INST_DIR "@CPACK_TEMPORARY_DIRECTORY@"
+
+;--------------------------------
+;Variables
+
+ Var MUI_TEMP
+ Var STARTMENU_FOLDER
+ Var SV_ALLUSERS
+ Var START_MENU
+ Var DO_NOT_ADD_TO_PATH
+ Var ADD_TO_PATH_ALL_USERS
+ Var ADD_TO_PATH_CURRENT_USER
+ Var INSTALL_DESKTOP
+ Var IS_DEFAULT_INSTALLDIR
+;--------------------------------
+;Include Modern UI
+
+ !include "MUI.nsh"
+
+ ;Default installation folder
+ InstallDir "@CPACK_NSIS_INSTALL_ROOT@\@CPACK_PACKAGE_INSTALL_DIRECTORY@"
+
+;--------------------------------
+;General
+
+ ;Name and file
+ Name "@CPACK_NSIS_PACKAGE_NAME@"
+ OutFile "@CPACK_TOPLEVEL_DIRECTORY@/@CPACK_OUTPUT_FILE_NAME@"
+
+ ;Set compression
+ SetCompressor @CPACK_NSIS_COMPRESSOR@
+
+@CPACK_NSIS_DEFINES@
+
+ !include Sections.nsh
+
+;--- Component support macros: ---
+; The code for the add/remove functionality is from:
+; http://nsis.sourceforge.net/Add/Remove_Functionality
+; It has been modified slightly and extended to provide
+; inter-component dependencies.
+Var AR_SecFlags
+Var AR_RegFlags
+@CPACK_NSIS_SECTION_SELECTED_VARS@
+
+; Loads the "selected" flag for the section named SecName into the
+; variable VarName.
+!macro LoadSectionSelectedIntoVar SecName VarName
+ SectionGetFlags ${${SecName}} $${VarName}
+ IntOp $${VarName} $${VarName} & ${SF_SELECTED} ;Turn off all other bits
+!macroend
+
+; Loads the value of a variable... can we get around this?
+!macro LoadVar VarName
+ IntOp $R0 0 + $${VarName}
+!macroend
+
+; Sets the value of a variable
+!macro StoreVar VarName IntValue
+ IntOp $${VarName} 0 + ${IntValue}
+!macroend
+
+!macro InitSection SecName
+ ; This macro reads component installed flag from the registry and
+ ;changes checked state of the section on the components page.
+ ;Input: section index constant name specified in Section command.
+
+ ClearErrors
+ ;Reading component status from registry
+ ReadRegDWORD $AR_RegFlags HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@\Components\${SecName}" "Installed"
+ IfErrors "default_${SecName}"
+ ;Status will stay default if registry value not found
+ ;(component was never installed)
+ IntOp $AR_RegFlags $AR_RegFlags & ${SF_SELECTED} ;Turn off all other bits
+ SectionGetFlags ${${SecName}} $AR_SecFlags ;Reading default section flags
+ IntOp $AR_SecFlags $AR_SecFlags & 0xFFFE ;Turn lowest (enabled) bit off
+ IntOp $AR_SecFlags $AR_RegFlags | $AR_SecFlags ;Change lowest bit
+
+ ; Note whether this component was installed before
+ !insertmacro StoreVar ${SecName}_was_installed $AR_RegFlags
+ IntOp $R0 $AR_RegFlags & $AR_RegFlags
+
+ ;Writing modified flags
+ SectionSetFlags ${${SecName}} $AR_SecFlags
+
+ "default_${SecName}:"
+ !insertmacro LoadSectionSelectedIntoVar ${SecName} ${SecName}_selected
+!macroend
+
+!macro FinishSection SecName
+ ; This macro reads section flag set by user and removes the section
+ ;if it is not selected.
+ ;Then it writes component installed flag to registry
+ ;Input: section index constant name specified in Section command.
+
+ SectionGetFlags ${${SecName}} $AR_SecFlags ;Reading section flags
+ ;Checking lowest bit:
+ IntOp $AR_SecFlags $AR_SecFlags & ${SF_SELECTED}
+ IntCmp $AR_SecFlags 1 "leave_${SecName}"
+ ;Section is not selected:
+ ;Calling Section uninstall macro and writing zero installed flag
+ !insertmacro "Remove_${${SecName}}"
+ WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@\Components\${SecName}" \
+ "Installed" 0
+ Goto "exit_${SecName}"
+
+ "leave_${SecName}:"
+ ;Section is selected:
+ WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@\Components\${SecName}" \
+ "Installed" 1
+
+ "exit_${SecName}:"
+!macroend
+
+!macro RemoveSection SecName
+ ; This macro is used to call section's Remove_... macro
+ ;from the uninstaller.
+ ;Input: section index constant name specified in Section command.
+
+ !insertmacro "Remove_${${SecName}}"
+!macroend
+
+; Determine whether the selection of SecName changed
+!macro MaybeSelectionChanged SecName
+ !insertmacro LoadVar ${SecName}_selected
+ SectionGetFlags ${${SecName}} $R1
+ IntOp $R1 $R1 & ${SF_SELECTED} ;Turn off all other bits
+
+ ; See if the status has changed:
+ IntCmp $R0 $R1 "${SecName}_unchanged"
+ !insertmacro LoadSectionSelectedIntoVar ${SecName} ${SecName}_selected
+
+ IntCmp $R1 ${SF_SELECTED} "${SecName}_was_selected"
+ !insertmacro "Deselect_required_by_${SecName}"
+ goto "${SecName}_unchanged"
+
+ "${SecName}_was_selected:"
+ !insertmacro "Select_${SecName}_depends"
+
+ "${SecName}_unchanged:"
+!macroend
+;--- End of Add/Remove macros ---
+
+;--------------------------------
+;Interface Settings
+
+ !define MUI_HEADERIMAGE
+ !define MUI_ABORTWARNING
+
+;--------------------------------
+; path functions
+
+!verbose 3
+!include "WinMessages.NSH"
+!verbose 4
+
+;----------------------------------------
+; based upon a script of "Written by KiCHiK 2003-01-18 05:57:02"
+;----------------------------------------
+!verbose 3
+!include "WinMessages.NSH"
+!verbose 4
+;====================================================
+; get_NT_environment
+; Returns: the selected environment
+; Output : head of the stack
+;====================================================
+!macro select_NT_profile UN
+Function ${UN}select_NT_profile
+ StrCmp $ADD_TO_PATH_ALL_USERS "1" 0 environment_single
+ DetailPrint "Selected environment for all users"
+ Push "all"
+ Return
+ environment_single:
+ DetailPrint "Selected environment for current user only."
+ Push "current"
+ Return
+FunctionEnd
+!macroend
+!insertmacro select_NT_profile ""
+!insertmacro select_NT_profile "un."
+;----------------------------------------------------
+!define NT_current_env 'HKCU "Environment"'
+!define NT_all_env 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
+
+!ifndef WriteEnvStr_RegKey
+ !ifdef ALL_USERS
+ !define WriteEnvStr_RegKey \
+ 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
+ !else
+ !define WriteEnvStr_RegKey 'HKCU "Environment"'
+ !endif
+!endif
+
+; AddToPath - Adds the given dir to the search path.
+; Input - head of the stack
+; Note - Win9x systems requires reboot
+
+Function AddToPath
+ Exch $0
+ Push $1
+ Push $2
+ Push $3
+
+ # don't add if the path doesn't exist
+ IfFileExists "$0\*.*" "" AddToPath_done
+
+ ReadEnvStr $1 PATH
+ ; if the path is too long for a NSIS variable NSIS will return a 0
+ ; length string. If we find that, then warn and skip any path
+ ; modification as it will trash the existing path.
+ StrLen $2 $1
+ IntCmp $2 0 CheckPathLength_ShowPathWarning CheckPathLength_Done CheckPathLength_Done
+ CheckPathLength_ShowPathWarning:
+ Messagebox MB_OK|MB_ICONEXCLAMATION "Warning! PATH too long installer unable to modify PATH!"
+ Goto AddToPath_done
+ CheckPathLength_Done:
+ Push "$1;"
+ Push "$0;"
+ Call StrStr
+ Pop $2
+ StrCmp $2 "" "" AddToPath_done
+ Push "$1;"
+ Push "$0\;"
+ Call StrStr
+ Pop $2
+ StrCmp $2 "" "" AddToPath_done
+ GetFullPathName /SHORT $3 $0
+ Push "$1;"
+ Push "$3;"
+ Call StrStr
+ Pop $2
+ StrCmp $2 "" "" AddToPath_done
+ Push "$1;"
+ Push "$3\;"
+ Call StrStr
+ Pop $2
+ StrCmp $2 "" "" AddToPath_done
+
+ Call IsNT
+ Pop $1
+ StrCmp $1 1 AddToPath_NT
+ ; Not on NT
+ StrCpy $1 $WINDIR 2
+ FileOpen $1 "$1\autoexec.bat" a
+ FileSeek $1 -1 END
+ FileReadByte $1 $2
+ IntCmp $2 26 0 +2 +2 # DOS EOF
+ FileSeek $1 -1 END # write over EOF
+ FileWrite $1 "$\r$\nSET PATH=%PATH%;$3$\r$\n"
+ FileClose $1
+ SetRebootFlag true
+ Goto AddToPath_done
+
+ AddToPath_NT:
+ StrCmp $ADD_TO_PATH_ALL_USERS "1" ReadAllKey
+ ReadRegStr $1 ${NT_current_env} "PATH"
+ Goto DoTrim
+ ReadAllKey:
+ ReadRegStr $1 ${NT_all_env} "PATH"
+ DoTrim:
+ StrCmp $1 "" AddToPath_NTdoIt
+ Push $1
+ Call Trim
+ Pop $1
+ StrCpy $0 "$1;$0"
+ AddToPath_NTdoIt:
+ StrCmp $ADD_TO_PATH_ALL_USERS "1" WriteAllKey
+ WriteRegExpandStr ${NT_current_env} "PATH" $0
+ Goto DoSend
+ WriteAllKey:
+ WriteRegExpandStr ${NT_all_env} "PATH" $0
+ DoSend:
+ SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
+
+ AddToPath_done:
+ Pop $3
+ Pop $2
+ Pop $1
+ Pop $0
+FunctionEnd
+
+
+; RemoveFromPath - Remove a given dir from the path
+; Input: head of the stack
+
+Function un.RemoveFromPath
+ Exch $0
+ Push $1
+ Push $2
+ Push $3
+ Push $4
+ Push $5
+ Push $6
+
+ IntFmt $6 "%c" 26 # DOS EOF
+
+ Call un.IsNT
+ Pop $1
+ StrCmp $1 1 unRemoveFromPath_NT
+ ; Not on NT
+ StrCpy $1 $WINDIR 2
+ FileOpen $1 "$1\autoexec.bat" r
+ GetTempFileName $4
+ FileOpen $2 $4 w
+ GetFullPathName /SHORT $0 $0
+ StrCpy $0 "SET PATH=%PATH%;$0"
+ Goto unRemoveFromPath_dosLoop
+
+ unRemoveFromPath_dosLoop:
+ FileRead $1 $3
+ StrCpy $5 $3 1 -1 # read last char
+ StrCmp $5 $6 0 +2 # if DOS EOF
+ StrCpy $3 $3 -1 # remove DOS EOF so we can compare
+ StrCmp $3 "$0$\r$\n" unRemoveFromPath_dosLoopRemoveLine
+ StrCmp $3 "$0$\n" unRemoveFromPath_dosLoopRemoveLine
+ StrCmp $3 "$0" unRemoveFromPath_dosLoopRemoveLine
+ StrCmp $3 "" unRemoveFromPath_dosLoopEnd
+ FileWrite $2 $3
+ Goto unRemoveFromPath_dosLoop
+ unRemoveFromPath_dosLoopRemoveLine:
+ SetRebootFlag true
+ Goto unRemoveFromPath_dosLoop
+
+ unRemoveFromPath_dosLoopEnd:
+ FileClose $2
+ FileClose $1
+ StrCpy $1 $WINDIR 2
+ Delete "$1\autoexec.bat"
+ CopyFiles /SILENT $4 "$1\autoexec.bat"
+ Delete $4
+ Goto unRemoveFromPath_done
+
+ unRemoveFromPath_NT:
+ StrCmp $ADD_TO_PATH_ALL_USERS "1" unReadAllKey
+ ReadRegStr $1 ${NT_current_env} "PATH"
+ Goto unDoTrim
+ unReadAllKey:
+ ReadRegStr $1 ${NT_all_env} "PATH"
+ unDoTrim:
+ StrCpy $5 $1 1 -1 # copy last char
+ StrCmp $5 ";" +2 # if last char != ;
+ StrCpy $1 "$1;" # append ;
+ Push $1
+ Push "$0;"
+ Call un.StrStr ; Find `$0;` in $1
+ Pop $2 ; pos of our dir
+ StrCmp $2 "" unRemoveFromPath_done
+ ; else, it is in path
+ # $0 - path to add
+ # $1 - path var
+ StrLen $3 "$0;"
+ StrLen $4 $2
+ StrCpy $5 $1 -$4 # $5 is now the part before the path to remove
+ StrCpy $6 $2 "" $3 # $6 is now the part after the path to remove
+ StrCpy $3 $5$6
+
+ StrCpy $5 $3 1 -1 # copy last char
+ StrCmp $5 ";" 0 +2 # if last char == ;
+ StrCpy $3 $3 -1 # remove last char
+
+ StrCmp $ADD_TO_PATH_ALL_USERS "1" unWriteAllKey
+ WriteRegExpandStr ${NT_current_env} "PATH" $3
+ Goto unDoSend
+ unWriteAllKey:
+ WriteRegExpandStr ${NT_all_env} "PATH" $3
+ unDoSend:
+ SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
+
+ unRemoveFromPath_done:
+ Pop $6
+ Pop $5
+ Pop $4
+ Pop $3
+ Pop $2
+ Pop $1
+ Pop $0
+FunctionEnd
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Uninstall sutff
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+###########################################
+# Utility Functions #
+###########################################
+
+;====================================================
+; IsNT - Returns 1 if the current system is NT, 0
+; otherwise.
+; Output: head of the stack
+;====================================================
+; IsNT
+; no input
+; output, top of the stack = 1 if NT or 0 if not
+;
+; Usage:
+; Call IsNT
+; Pop $R0
+; ($R0 at this point is 1 or 0)
+
+!macro IsNT un
+Function ${un}IsNT
+ Push $0
+ ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion
+ StrCmp $0 "" 0 IsNT_yes
+ ; we are not NT.
+ Pop $0
+ Push 0
+ Return
+
+ IsNT_yes:
+ ; NT!!!
+ Pop $0
+ Push 1
+FunctionEnd
+!macroend
+!insertmacro IsNT ""
+!insertmacro IsNT "un."
+
+; StrStr
+; input, top of stack = string to search for
+; top of stack-1 = string to search in
+; output, top of stack (replaces with the portion of the string remaining)
+; modifies no other variables.
+;
+; Usage:
+; Push "this is a long ass string"
+; Push "ass"
+; Call StrStr
+; Pop $R0
+; ($R0 at this point is "ass string")
+
+!macro StrStr un
+Function ${un}StrStr
+Exch $R1 ; st=haystack,old$R1, $R1=needle
+ Exch ; st=old$R1,haystack
+ Exch $R2 ; st=old$R1,old$R2, $R2=haystack
+ Push $R3
+ Push $R4
+ Push $R5
+ StrLen $R3 $R1
+ StrCpy $R4 0
+ ; $R1=needle
+ ; $R2=haystack
+ ; $R3=len(needle)
+ ; $R4=cnt
+ ; $R5=tmp
+ loop:
+ StrCpy $R5 $R2 $R3 $R4
+ StrCmp $R5 $R1 done
+ StrCmp $R5 "" done
+ IntOp $R4 $R4 + 1
+ Goto loop
+done:
+ StrCpy $R1 $R2 "" $R4
+ Pop $R5
+ Pop $R4
+ Pop $R3
+ Pop $R2
+ Exch $R1
+FunctionEnd
+!macroend
+!insertmacro StrStr ""
+!insertmacro StrStr "un."
+
+Function Trim ; Added by Pelaca
+ Exch $R1
+ Push $R2
+Loop:
+ StrCpy $R2 "$R1" 1 -1
+ StrCmp "$R2" " " RTrim
+ StrCmp "$R2" "$\n" RTrim
+ StrCmp "$R2" "$\r" RTrim
+ StrCmp "$R2" ";" RTrim
+ GoTo Done
+RTrim:
+ StrCpy $R1 "$R1" -1
+ Goto Loop
+Done:
+ Pop $R2
+ Exch $R1
+FunctionEnd
+
+Function ConditionalAddToRegisty
+ Pop $0
+ Pop $1
+ StrCmp "$0" "" ConditionalAddToRegisty_EmptyString
+ WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" \
+ "$1" "$0"
+ ;MessageBox MB_OK "Set Registry: '$1' to '$0'"
+ DetailPrint "Set install registry entry: '$1' to '$0'"
+ ConditionalAddToRegisty_EmptyString:
+FunctionEnd
+
+;--------------------------------
+
+!ifdef CPACK_USES_DOWNLOAD
+Function DownloadFile
+ IfFileExists $INSTDIR\* +2
+ CreateDirectory $INSTDIR
+ Pop $0
+
+ ; Skip if already downloaded
+ IfFileExists $INSTDIR\$0 0 +2
+ Return
+
+ StrCpy $1 "@CPACK_DOWNLOAD_SITE@"
+
+ try_again:
+ NSISdl::download "$1/$0" "$INSTDIR\$0"
+
+ Pop $1
+ StrCmp $1 "success" success
+ StrCmp $1 "Cancelled" cancel
+ MessageBox MB_OK "Download failed: $1"
+ cancel:
+ Return
+ success:
+FunctionEnd
+!endif
+
+;--------------------------------
+; Installation types
+@CPACK_NSIS_INSTALLATION_TYPES@
+
+;--------------------------------
+; Component sections
+@CPACK_NSIS_COMPONENT_SECTIONS@
+
+;--------------------------------
+; Define some macro setting for the gui
+@CPACK_NSIS_INSTALLER_MUI_ICON_CODE@
+@CPACK_NSIS_INSTALLER_ICON_CODE@
+@CPACK_NSIS_INSTALLER_MUI_COMPONENTS_DESC@
+@CPACK_NSIS_INSTALLER_MUI_FINISHPAGE_RUN_CODE@
+
+;--------------------------------
+;Pages
+ !insertmacro MUI_PAGE_WELCOME
+
+ !insertmacro MUI_PAGE_LICENSE "@CPACK_RESOURCE_FILE_LICENSE@"
+ Page custom InstallOptionsPage
+ !insertmacro MUI_PAGE_DIRECTORY
+
+ ;Start Menu Folder Page Configuration
+ !define MUI_STARTMENUPAGE_REGISTRY_ROOT "SHCTX"
+ !define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@"
+ !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder"
+ !insertmacro MUI_PAGE_STARTMENU Application $STARTMENU_FOLDER
+
+ @CPACK_NSIS_PAGE_COMPONENTS@
+
+ !insertmacro MUI_PAGE_INSTFILES
+ !insertmacro MUI_PAGE_FINISH
+
+ !insertmacro MUI_UNPAGE_CONFIRM
+ !insertmacro MUI_UNPAGE_INSTFILES
+
+;--------------------------------
+;Languages
+
+ !insertmacro MUI_LANGUAGE "English" ;first language is the default language
+ !insertmacro MUI_LANGUAGE "Albanian"
+ !insertmacro MUI_LANGUAGE "Arabic"
+ !insertmacro MUI_LANGUAGE "Basque"
+ !insertmacro MUI_LANGUAGE "Belarusian"
+ !insertmacro MUI_LANGUAGE "Bosnian"
+ !insertmacro MUI_LANGUAGE "Breton"
+ !insertmacro MUI_LANGUAGE "Bulgarian"
+ !insertmacro MUI_LANGUAGE "Croatian"
+ !insertmacro MUI_LANGUAGE "Czech"
+ !insertmacro MUI_LANGUAGE "Danish"
+ !insertmacro MUI_LANGUAGE "Dutch"
+ !insertmacro MUI_LANGUAGE "Estonian"
+ !insertmacro MUI_LANGUAGE "Farsi"
+ !insertmacro MUI_LANGUAGE "Finnish"
+ !insertmacro MUI_LANGUAGE "French"
+ !insertmacro MUI_LANGUAGE "German"
+ !insertmacro MUI_LANGUAGE "Greek"
+ !insertmacro MUI_LANGUAGE "Hebrew"
+ !insertmacro MUI_LANGUAGE "Hungarian"
+ !insertmacro MUI_LANGUAGE "Icelandic"
+ !insertmacro MUI_LANGUAGE "Indonesian"
+ !insertmacro MUI_LANGUAGE "Irish"
+ !insertmacro MUI_LANGUAGE "Italian"
+ !insertmacro MUI_LANGUAGE "Japanese"
+ !insertmacro MUI_LANGUAGE "Korean"
+ !insertmacro MUI_LANGUAGE "Kurdish"
+ !insertmacro MUI_LANGUAGE "Latvian"
+ !insertmacro MUI_LANGUAGE "Lithuanian"
+ !insertmacro MUI_LANGUAGE "Luxembourgish"
+ !insertmacro MUI_LANGUAGE "Macedonian"
+ !insertmacro MUI_LANGUAGE "Malay"
+ !insertmacro MUI_LANGUAGE "Mongolian"
+ !insertmacro MUI_LANGUAGE "Norwegian"
+ !insertmacro MUI_LANGUAGE "Polish"
+ !insertmacro MUI_LANGUAGE "Portuguese"
+ !insertmacro MUI_LANGUAGE "PortugueseBR"
+ !insertmacro MUI_LANGUAGE "Romanian"
+ !insertmacro MUI_LANGUAGE "Russian"
+ !insertmacro MUI_LANGUAGE "Serbian"
+ !insertmacro MUI_LANGUAGE "SerbianLatin"
+ !insertmacro MUI_LANGUAGE "SimpChinese"
+ !insertmacro MUI_LANGUAGE "Slovak"
+ !insertmacro MUI_LANGUAGE "Slovenian"
+ !insertmacro MUI_LANGUAGE "Spanish"
+ !insertmacro MUI_LANGUAGE "Swedish"
+ !insertmacro MUI_LANGUAGE "Thai"
+ !insertmacro MUI_LANGUAGE "TradChinese"
+ !insertmacro MUI_LANGUAGE "Turkish"
+ !insertmacro MUI_LANGUAGE "Ukrainian"
+ !insertmacro MUI_LANGUAGE "Welsh"
+
+
+;--------------------------------
+;Reserve Files
+
+ ;These files should be inserted before other files in the data block
+ ;Keep these lines before any File command
+ ;Only for solid compression (by default, solid compression is enabled for BZIP2 and LZMA)
+
+ ReserveFile "NSIS.InstallOptions.ini"
+ !insertmacro MUI_RESERVEFILE_INSTALLOPTIONS
+
+;--------------------------------
+;Installer Sections
+
+Section "-Core installation"
+ ;Use the entire tree produced by the INSTALL target. Keep the
+ ;list of directories here in sync with the RMDir commands below.
+ SetOutPath "$INSTDIR"
+ @CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS@
+ @CPACK_NSIS_FULL_INSTALL@
+
+ ;Store installation folder
+ WriteRegStr SHCTX "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "" $INSTDIR
+
+ ;Create uninstaller
+ WriteUninstaller "$INSTDIR\Uninstall.exe"
+ Push "DisplayName"
+ Push "@CPACK_NSIS_DISPLAY_NAME@"
+ Call ConditionalAddToRegisty
+ Push "DisplayVersion"
+ Push "@CPACK_PACKAGE_VERSION@"
+ Call ConditionalAddToRegisty
+ Push "Publisher"
+ Push "@CPACK_PACKAGE_VENDOR@"
+ Call ConditionalAddToRegisty
+ Push "UninstallString"
+ Push "$INSTDIR\Uninstall.exe"
+ Call ConditionalAddToRegisty
+ Push "NoRepair"
+ Push "1"
+ Call ConditionalAddToRegisty
+
+ !ifdef CPACK_NSIS_ADD_REMOVE
+ ;Create add/remove functionality
+ Push "ModifyPath"
+ Push "$INSTDIR\AddRemove.exe"
+ Call ConditionalAddToRegisty
+ !else
+ Push "NoModify"
+ Push "1"
+ Call ConditionalAddToRegisty
+ !endif
+
+ ; Optional registration
+ Push "DisplayIcon"
+ Push "$INSTDIR\@CPACK_NSIS_INSTALLED_ICON_NAME@"
+ Call ConditionalAddToRegisty
+ Push "HelpLink"
+ Push "@CPACK_NSIS_HELP_LINK@"
+ Call ConditionalAddToRegisty
+ Push "URLInfoAbout"
+ Push "@CPACK_NSIS_URL_INFO_ABOUT@"
+ Call ConditionalAddToRegisty
+ Push "Contact"
+ Push "@CPACK_NSIS_CONTACT@"
+ Call ConditionalAddToRegisty
+ !insertmacro MUI_INSTALLOPTIONS_READ $INSTALL_DESKTOP "NSIS.InstallOptions.ini" "Field 5" "State"
+ !insertmacro MUI_STARTMENU_WRITE_BEGIN Application
+
+ ;Create shortcuts
+ CreateDirectory "$SMPROGRAMS\$STARTMENU_FOLDER"
+@CPACK_NSIS_CREATE_ICONS@
+@CPACK_NSIS_CREATE_ICONS_EXTRA@
+ CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Uninstall.lnk" "$INSTDIR\Uninstall.exe"
+
+ ;Read a value from an InstallOptions INI file
+ !insertmacro MUI_INSTALLOPTIONS_READ $DO_NOT_ADD_TO_PATH "NSIS.InstallOptions.ini" "Field 2" "State"
+ !insertmacro MUI_INSTALLOPTIONS_READ $ADD_TO_PATH_ALL_USERS "NSIS.InstallOptions.ini" "Field 3" "State"
+ !insertmacro MUI_INSTALLOPTIONS_READ $ADD_TO_PATH_CURRENT_USER "NSIS.InstallOptions.ini" "Field 4" "State"
+
+ ; Write special uninstall registry entries
+ Push "StartMenu"
+ Push "$STARTMENU_FOLDER"
+ Call ConditionalAddToRegisty
+ Push "DoNotAddToPath"
+ Push "$DO_NOT_ADD_TO_PATH"
+ Call ConditionalAddToRegisty
+ Push "AddToPathAllUsers"
+ Push "$ADD_TO_PATH_ALL_USERS"
+ Call ConditionalAddToRegisty
+ Push "AddToPathCurrentUser"
+ Push "$ADD_TO_PATH_CURRENT_USER"
+ Call ConditionalAddToRegisty
+ Push "InstallToDesktop"
+ Push "$INSTALL_DESKTOP"
+ Call ConditionalAddToRegisty
+
+ !insertmacro MUI_STARTMENU_WRITE_END
+
+@CPACK_NSIS_EXTRA_INSTALL_COMMANDS@
+
+SectionEnd
+
+Section "-Add to path"
+ Push $INSTDIR\bin
+ StrCmp "@CPACK_NSIS_MODIFY_PATH@" "ON" 0 doNotAddToPath
+ StrCmp $DO_NOT_ADD_TO_PATH "1" doNotAddToPath 0
+ Call AddToPath
+ doNotAddToPath:
+SectionEnd
+
+;--------------------------------
+; Create custom pages
+Function InstallOptionsPage
+ !insertmacro MUI_HEADER_TEXT "Install Options" "Choose options for installing @CPACK_NSIS_PACKAGE_NAME@"
+ !insertmacro MUI_INSTALLOPTIONS_DISPLAY "NSIS.InstallOptions.ini"
+
+FunctionEnd
+
+;--------------------------------
+; determine admin versus local install
+Function un.onInit
+
+ ClearErrors
+ UserInfo::GetName
+ IfErrors noLM
+ Pop $0
+ UserInfo::GetAccountType
+ Pop $1
+ StrCmp $1 "Admin" 0 +3
+ SetShellVarContext all
+ ;MessageBox MB_OK 'User "$0" is in the Admin group'
+ Goto done
+ StrCmp $1 "Power" 0 +3
+ SetShellVarContext all
+ ;MessageBox MB_OK 'User "$0" is in the Power Users group'
+ Goto done
+
+ noLM:
+ ;Get installation folder from registry if available
+
+ done:
+
+FunctionEnd
+
+;--- Add/Remove callback functions: ---
+!macro SectionList MacroName
+ ;This macro used to perform operation on multiple sections.
+ ;List all of your components in following manner here.
+@CPACK_NSIS_COMPONENT_SECTION_LIST@
+!macroend
+
+Section -FinishComponents
+ ;Removes unselected components and writes component status to registry
+ !insertmacro SectionList "FinishSection"
+
+!ifdef CPACK_NSIS_ADD_REMOVE
+ ; Get the name of the installer executable
+ System::Call 'kernel32::GetModuleFileNameA(i 0, t .R0, i 1024) i r1'
+ StrCpy $R3 $R0
+
+ ; Strip off the last 13 characters, to see if we have AddRemove.exe
+ StrLen $R1 $R0
+ IntOp $R1 $R0 - 13
+ StrCpy $R2 $R0 13 $R1
+ StrCmp $R2 "AddRemove.exe" addremove_installed
+
+ ; We're not running AddRemove.exe, so install it
+ CopyFiles $R3 $INSTDIR\AddRemove.exe
+
+ addremove_installed:
+!endif
+SectionEnd
+;--- End of Add/Remove callback functions ---
+
+;--------------------------------
+; Component dependencies
+Function .onSelChange
+ !insertmacro SectionList MaybeSelectionChanged
+FunctionEnd
+
+;--------------------------------
+;Uninstaller Section
+
+Section "Uninstall"
+ ReadRegStr $START_MENU SHCTX \
+ "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "StartMenu"
+ ;MessageBox MB_OK "Start menu is in: $START_MENU"
+ ReadRegStr $DO_NOT_ADD_TO_PATH SHCTX \
+ "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "DoNotAddToPath"
+ ReadRegStr $ADD_TO_PATH_ALL_USERS SHCTX \
+ "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "AddToPathAllUsers"
+ ReadRegStr $ADD_TO_PATH_CURRENT_USER SHCTX \
+ "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "AddToPathCurrentUser"
+ ;MessageBox MB_OK "Add to path: $DO_NOT_ADD_TO_PATH all users: $ADD_TO_PATH_ALL_USERS"
+ ReadRegStr $INSTALL_DESKTOP SHCTX \
+ "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "InstallToDesktop"
+ ;MessageBox MB_OK "Install to desktop: $INSTALL_DESKTOP "
+
+@CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS@
+
+ ;Remove files we installed.
+ ;Keep the list of directories here in sync with the File commands above.
+@CPACK_NSIS_DELETE_FILES@
+@CPACK_NSIS_DELETE_DIRECTORIES@
+
+!ifdef CPACK_NSIS_ADD_REMOVE
+ ;Remove the add/remove program
+ Delete "$INSTDIR\AddRemove.exe"
+!endif
+
+ ;Remove the uninstaller itself.
+ Delete "$INSTDIR\Uninstall.exe"
+ DeleteRegKey SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@"
+
+ ;Remove the installation directory if it is empty.
+ RMDir "$INSTDIR"
+
+ ; Remove the registry entries.
+ DeleteRegKey SHCTX "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@"
+
+ ; Removes all optional components
+ !insertmacro SectionList "RemoveSection"
+
+ !insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP
+
+ Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall.lnk"
+@CPACK_NSIS_DELETE_ICONS@
+@CPACK_NSIS_DELETE_ICONS_EXTRA@
+
+ ;Delete empty start menu parent diretories
+ StrCpy $MUI_TEMP "$SMPROGRAMS\$MUI_TEMP"
+
+ startMenuDeleteLoop:
+ ClearErrors
+ RMDir $MUI_TEMP
+ GetFullPathName $MUI_TEMP "$MUI_TEMP\.."
+
+ IfErrors startMenuDeleteLoopDone
+
+ StrCmp "$MUI_TEMP" "$SMPROGRAMS" startMenuDeleteLoopDone startMenuDeleteLoop
+ startMenuDeleteLoopDone:
+
+ ; If the user changed the shortcut, then untinstall may not work. This should
+ ; try to fix it.
+ StrCpy $MUI_TEMP "$START_MENU"
+ Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall.lnk"
+@CPACK_NSIS_DELETE_ICONS_EXTRA@
+
+ ;Delete empty start menu parent diretories
+ StrCpy $MUI_TEMP "$SMPROGRAMS\$MUI_TEMP"
+
+ secondStartMenuDeleteLoop:
+ ClearErrors
+ RMDir $MUI_TEMP
+ GetFullPathName $MUI_TEMP "$MUI_TEMP\.."
+
+ IfErrors secondStartMenuDeleteLoopDone
+
+ StrCmp "$MUI_TEMP" "$SMPROGRAMS" secondStartMenuDeleteLoopDone secondStartMenuDeleteLoop
+ secondStartMenuDeleteLoopDone:
+
+ DeleteRegKey /ifempty SHCTX "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@"
+
+ Push $INSTDIR\bin
+ StrCmp $DO_NOT_ADD_TO_PATH_ "1" doNotRemoveFromPath 0
+ Call un.RemoveFromPath
+ doNotRemoveFromPath:
+SectionEnd
+
+;--------------------------------
+; determine admin versus local install
+; Is install for "AllUsers" or "JustMe"?
+; Default to "JustMe" - set to "AllUsers" if admin or on Win9x
+; This function is used for the very first "custom page" of the installer.
+; This custom page does not show up visibly, but it executes prior to the
+; first visible page and sets up $INSTDIR properly...
+; Choose different default installation folder based on SV_ALLUSERS...
+; "Program Files" for AllUsers, "My Documents" for JustMe...
+
+Function .onInit
+ StrCmp "@CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL@" "ON" 0 inst
+
+ ReadRegStr $0 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_NAME@" "UninstallString"
+ StrCmp $0 "" inst
+
+ MessageBox MB_YESNOCANCEL|MB_ICONEXCLAMATION \
+ "@CPACK_NSIS_PACKAGE_NAME@ is already installed. $\n$\nDo you want to uninstall the old version before installing the new one?" \
+ IDYES uninst IDNO inst
+ Abort
+
+;Run the uninstaller
+uninst:
+ ClearErrors
+ ExecWait '$0 _?=$INSTDIR' ;Do not copy the uninstaller to a temp file
+
+ IfErrors uninst_failed inst
+uninst_failed:
+ MessageBox MB_OK|MB_ICONSTOP "Uninstall failed."
+ Abort
+
+
+inst:
+ ; Reads components status for registry
+ !insertmacro SectionList "InitSection"
+
+ ; check to see if /D has been used to change
+ ; the install directory by comparing it to the
+ ; install directory that is expected to be the
+ ; default
+ StrCpy $IS_DEFAULT_INSTALLDIR 0
+ StrCmp "$INSTDIR" "@CPACK_NSIS_INSTALL_ROOT@\@CPACK_PACKAGE_INSTALL_DIRECTORY@" 0 +2
+ StrCpy $IS_DEFAULT_INSTALLDIR 1
+
+ StrCpy $SV_ALLUSERS "JustMe"
+ ; if default install dir then change the default
+ ; if it is installed for JustMe
+ StrCmp "$IS_DEFAULT_INSTALLDIR" "1" 0 +2
+ StrCpy $INSTDIR "$DOCUMENTS\@CPACK_PACKAGE_INSTALL_DIRECTORY@"
+
+ ClearErrors
+ UserInfo::GetName
+ IfErrors noLM
+ Pop $0
+ UserInfo::GetAccountType
+ Pop $1
+ StrCmp $1 "Admin" 0 +4
+ SetShellVarContext all
+ ;MessageBox MB_OK 'User "$0" is in the Admin group'
+ StrCpy $SV_ALLUSERS "AllUsers"
+ Goto done
+ StrCmp $1 "Power" 0 +4
+ SetShellVarContext all
+ ;MessageBox MB_OK 'User "$0" is in the Power Users group'
+ StrCpy $SV_ALLUSERS "AllUsers"
+ Goto done
+
+ noLM:
+ StrCpy $SV_ALLUSERS "AllUsers"
+ ;Get installation folder from registry if available
+
+ done:
+ StrCmp $SV_ALLUSERS "AllUsers" 0 +3
+ StrCmp "$IS_DEFAULT_INSTALLDIR" "1" 0 +2
+ StrCpy $INSTDIR "@CPACK_NSIS_INSTALL_ROOT@\@CPACK_PACKAGE_INSTALL_DIRECTORY@"
+
+ StrCmp "@CPACK_NSIS_MODIFY_PATH@" "ON" 0 noOptionsPage
+ !insertmacro MUI_INSTALLOPTIONS_EXTRACT "NSIS.InstallOptions.ini"
+
+ noOptionsPage:
+FunctionEnd
diff --git a/Modules/Platform/AIX-GNU-ASM.cmake b/Modules/Platform/AIX-GNU-ASM.cmake
new file mode 100644
index 000000000..c256df6f9
--- /dev/null
+++ b/Modules/Platform/AIX-GNU-ASM.cmake
@@ -0,0 +1,2 @@
+include(Platform/AIX-GNU)
+__aix_compiler_gnu(ASM)
diff --git a/Modules/Platform/AIX-GNU-C.cmake b/Modules/Platform/AIX-GNU-C.cmake
new file mode 100644
index 000000000..f49d528b3
--- /dev/null
+++ b/Modules/Platform/AIX-GNU-C.cmake
@@ -0,0 +1,2 @@
+include(Platform/AIX-GNU)
+__aix_compiler_gnu(C)
diff --git a/Modules/Platform/AIX-GNU-CXX.cmake b/Modules/Platform/AIX-GNU-CXX.cmake
new file mode 100644
index 000000000..ec8e83fa1
--- /dev/null
+++ b/Modules/Platform/AIX-GNU-CXX.cmake
@@ -0,0 +1,2 @@
+include(Platform/AIX-GNU)
+__aix_compiler_gnu(CXX)
diff --git a/Modules/Platform/AIX-GNU-Fortran.cmake b/Modules/Platform/AIX-GNU-Fortran.cmake
new file mode 100644
index 000000000..07772a716
--- /dev/null
+++ b/Modules/Platform/AIX-GNU-Fortran.cmake
@@ -0,0 +1,2 @@
+include(Platform/AIX-GNU)
+__aix_compiler_gnu(Fortran)
diff --git a/Modules/Platform/AIX-GNU.cmake b/Modules/Platform/AIX-GNU.cmake
new file mode 100644
index 000000000..81ba3657f
--- /dev/null
+++ b/Modules/Platform/AIX-GNU.cmake
@@ -0,0 +1,26 @@
+
+#=============================================================================
+# 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 module is shared by multiple languages; use include blocker.
+if(__AIX_COMPILER_GNU)
+ return()
+endif()
+set(__AIX_COMPILER_GNU 1)
+
+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,-brtl,-bnoipath")
+ set(CMAKE_SHARED_LIBRARY_LINK_${lang}_FLAGS "-Wl,-brtl,-bnoipath,-bexpall") # +s, flag for exe link to use shared lib
+endmacro()
diff --git a/Modules/Platform/AIX-VisualAge-C.cmake b/Modules/Platform/AIX-VisualAge-C.cmake
new file mode 100644
index 000000000..67b3171dc
--- /dev/null
+++ b/Modules/Platform/AIX-VisualAge-C.cmake
@@ -0,0 +1 @@
+include(Platform/AIX-XL-C)
diff --git a/Modules/Platform/AIX-VisualAge-CXX.cmake b/Modules/Platform/AIX-VisualAge-CXX.cmake
new file mode 100644
index 000000000..7894d244f
--- /dev/null
+++ b/Modules/Platform/AIX-VisualAge-CXX.cmake
@@ -0,0 +1 @@
+include(Platform/AIX-XL-CXX)
diff --git a/Modules/Platform/AIX-VisualAge-Fortran.cmake b/Modules/Platform/AIX-VisualAge-Fortran.cmake
new file mode 100644
index 000000000..19e59d666
--- /dev/null
+++ b/Modules/Platform/AIX-VisualAge-Fortran.cmake
@@ -0,0 +1 @@
+include(Platform/AIX-XL-Fortran)
diff --git a/Modules/Platform/AIX-XL-ASM.cmake b/Modules/Platform/AIX-XL-ASM.cmake
new file mode 100644
index 000000000..ea0944ba4
--- /dev/null
+++ b/Modules/Platform/AIX-XL-ASM.cmake
@@ -0,0 +1,2 @@
+include(Platform/AIX-XL)
+__aix_compiler_xl(ASM)
diff --git a/Modules/Platform/AIX-XL-C.cmake b/Modules/Platform/AIX-XL-C.cmake
new file mode 100644
index 000000000..5e437fafd
--- /dev/null
+++ b/Modules/Platform/AIX-XL-C.cmake
@@ -0,0 +1,2 @@
+include(Platform/AIX-XL)
+__aix_compiler_xl(C)
diff --git a/Modules/Platform/AIX-XL-CXX.cmake b/Modules/Platform/AIX-XL-CXX.cmake
new file mode 100644
index 000000000..ef38a5f23
--- /dev/null
+++ b/Modules/Platform/AIX-XL-CXX.cmake
@@ -0,0 +1,2 @@
+include(Platform/AIX-XL)
+__aix_compiler_xl(CXX)
diff --git a/Modules/Platform/AIX-XL-Fortran.cmake b/Modules/Platform/AIX-XL-Fortran.cmake
new file mode 100644
index 000000000..6d4f6559f
--- /dev/null
+++ b/Modules/Platform/AIX-XL-Fortran.cmake
@@ -0,0 +1,2 @@
+include(Platform/AIX-XL)
+__aix_compiler_xl(Fortran)
diff --git a/Modules/Platform/AIX-XL.cmake b/Modules/Platform/AIX-XL.cmake
new file mode 100644
index 000000000..1f9415219
--- /dev/null
+++ b/Modules/Platform/AIX-XL.cmake
@@ -0,0 +1,28 @@
+
+#=============================================================================
+# Copyright 2002-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.)
+
+# This module is shared by multiple languages; use include blocker.
+if(__AIX_COMPILER_XL)
+ return()
+endif()
+set(__AIX_COMPILER_XL 1)
+
+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,-brtl,-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_${lang}_FLAGS " ")
+ set(CMAKE_SHARED_MODULE_${lang}_FLAGS " ")
+endmacro()
diff --git a/Modules/Platform/AIX.cmake b/Modules/Platform/AIX.cmake
new file mode 100644
index 000000000..a9f773ed1
--- /dev/null
+++ b/Modules/Platform/AIX.cmake
@@ -0,0 +1,29 @@
+SET(CMAKE_SHARED_LIBRARY_PREFIX "lib") # lib
+SET(CMAKE_SHARED_LIBRARY_SUFFIX ".so") # .so
+SET(CMAKE_DL_LIBS "-lld")
+
+# RPATH support on AIX is called libpath. By default the runtime
+# libpath is paths specified by -L followed by /usr/lib and /lib. In
+# order to prevent the -L paths from being used we must force use of
+# -Wl,-blibpath:/usr/lib:/lib whether RPATH support is on or not.
+# When our own RPATH is to be added it may be inserted before the
+# "always" paths.
+SET(CMAKE_PLATFORM_REQUIRED_RUNTIME_PATH /usr/lib /lib)
+
+# Files named "libfoo.a" may actually be shared libraries.
+SET_PROPERTY(GLOBAL PROPERTY TARGET_ARCHIVES_MAY_BE_SHARED_LIBS 1)
+
+# since .a can be a static or shared library on AIX, we can not do this.
+# at some point if we wanted it, we would have to figure out if a .a is
+# static or shared, then we could add this back:
+
+# 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
+# versions of the libraries.
+#FOREACH(type SHARED_LIBRARY SHARED_MODULE EXE)
+# SET(CMAKE_${type}_LINK_STATIC_C_FLAGS "-bstatic")
+# SET(CMAKE_${type}_LINK_DYNAMIC_C_FLAGS "-bdynamic")
+#ENDFOREACH(type)
+
+INCLUDE(Platform/UnixPaths)
diff --git a/Modules/Platform/BSDOS.cmake b/Modules/Platform/BSDOS.cmake
new file mode 100644
index 000000000..cf9d17bfd
--- /dev/null
+++ b/Modules/Platform/BSDOS.cmake
@@ -0,0 +1,2 @@
+INCLUDE(Platform/UnixPaths)
+
diff --git a/Modules/Platform/BeOS.cmake b/Modules/Platform/BeOS.cmake
new file mode 100644
index 000000000..3ffb67cb8
--- /dev/null
+++ b/Modules/Platform/BeOS.cmake
@@ -0,0 +1,12 @@
+SET(BEOS 1)
+
+SET(CMAKE_DL_LIBS root be)
+SET(CMAKE_C_COMPILE_OPTIONS_PIC "-fPIC")
+SET(CMAKE_C_COMPILE_OPTIONS_PIE "-fPIE")
+SET(CMAKE_SHARED_LIBRARY_C_FLAGS "-fPIC")
+SET(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-nostart")
+SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "-Wl,-rpath,")
+SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP ":")
+SET(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "-Wl,-soname,")
+
+INCLUDE(Platform/UnixPaths)
diff --git a/Modules/Platform/BlueGeneL.cmake b/Modules/Platform/BlueGeneL.cmake
new file mode 100644
index 000000000..7794a26cf
--- /dev/null
+++ b/Modules/Platform/BlueGeneL.cmake
@@ -0,0 +1,40 @@
+#the compute nodes on BlueGene/L don't support shared libs
+SET_PROPERTY(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE)
+
+SET(CMAKE_SHARED_LIBRARY_C_FLAGS "") # -pic
+SET(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "") # -shared
+SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") # +s, flag for exe link to use shared lib
+SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "") # -rpath
+SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP "") # : or empty
+
+SET(CMAKE_LINK_LIBRARY_SUFFIX "")
+SET(CMAKE_STATIC_LIBRARY_PREFIX "lib")
+SET(CMAKE_STATIC_LIBRARY_SUFFIX ".a")
+SET(CMAKE_SHARED_LIBRARY_PREFIX "lib") # lib
+SET(CMAKE_SHARED_LIBRARY_SUFFIX ".a") # .a
+SET(CMAKE_EXECUTABLE_SUFFIX "") # .exe
+SET(CMAKE_DL_LIBS "" )
+
+SET(CMAKE_FIND_LIBRARY_PREFIXES "lib")
+SET(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
+
+
+INCLUDE(Platform/UnixPaths)
+
+IF(CMAKE_COMPILER_IS_GNUCC)
+ SET(CMAKE_C_LINK_EXECUTABLE
+ "<CMAKE_C_COMPILER> -Wl,-relax <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Wl,-lgcc,-lc -lnss_files -lnss_dns -lresolv")
+ELSE(CMAKE_COMPILER_IS_GNUCC)
+ # when using IBM xlc we probably don't want to link to -lgcc
+ SET(CMAKE_C_LINK_EXECUTABLE
+ "<CMAKE_C_COMPILER> -Wl,-relax <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Wl,-lc -lnss_files -lnss_dns -lresolv")
+ENDIF(CMAKE_COMPILER_IS_GNUCC)
+
+IF(CMAKE_COMPILER_IS_GNUCXX)
+ SET(CMAKE_CXX_LINK_EXECUTABLE
+ "<CMAKE_CXX_COMPILER> -Wl,-relax <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Wl,-lstdc++,-lgcc,-lc -lnss_files -lnss_dns -lresolv")
+ELSE(CMAKE_COMPILER_IS_GNUCXX)
+ # when using the IBM xlC we probably don't want to link to -lgcc
+ SET(CMAKE_CXX_LINK_EXECUTABLE
+ "<CMAKE_CXX_COMPILER> -Wl,-relax <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Wl,-lstdc++,-lc -lnss_files -lnss_dns -lresolv")
+ENDIF(CMAKE_COMPILER_IS_GNUCXX)
diff --git a/Modules/Platform/BlueGeneP-base.cmake b/Modules/Platform/BlueGeneP-base.cmake
new file mode 100644
index 000000000..c0241e19d
--- /dev/null
+++ b/Modules/Platform/BlueGeneP-base.cmake
@@ -0,0 +1,125 @@
+
+#=============================================================================
+# 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.)
+
+#
+# BlueGeneP base platform file.
+#
+# NOTE: Do not set your platform to "BlueGeneP-base". This file is included
+# by the real platform files. Use one of these two platforms instead:
+#
+# BlueGeneP-dynamic For dynamically linked builds
+# BlueGeneP-static For statically linked builds
+#
+# This platform file tries its best to adhere to the behavior of the MPI
+# compiler wrappers included with the latest BG/P drivers.
+#
+
+
+#
+# For BGP 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 BGP 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.
+#
+set(CMAKE_SYSTEM_LIBRARY_PATH
+ /bgsys/drivers/ppcfloor/comm/default/lib # default comm layer (used by mpi compiler wrappers)
+ /bgsys/drivers/ppcfloor/comm/sys/lib # DCMF, other lower-level comm libraries
+ /bgsys/drivers/ppcfloor/runtime/SPI # other low-level stuff
+ /bgsys/drivers/ppcfloor/gnu-linux/lib # CNK python installation directory
+ /bgsys/drivers/ppcfloor/gnu-linux/powerpc-bgp-linux/lib # CNK Linux image -- standard runtime libs, pthread, etc.
+)
+
+#
+# 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")
+
+#
+# This macro needs to be called for dynamic library support. Unfortunately on BGP,
+# 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(__BlueGeneP_set_dynamic_flags compiler_id lang)
+ if (${compiler_id} STREQUAL XL)
+ # Flags for XL compilers if we explicitly detected XL
+ set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "-qpic")
+ set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-qpie")
+ set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "-qpic")
+ set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-qmkshrobj -qnostaticlink")
+ set(BGP_${lang}_DYNAMIC_EXE_FLAGS "-qnostaticlink -qnostaticlink=libgcc")
+ else()
+ # Assume flags for GNU compilers (if the ID is GNU *or* anything else).
+ set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "-fPIC")
+ set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-fPIE")
+ set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "-fPIC")
+ set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-shared")
+ set(BGP_${lang}_DYNAMIC_EXE_FLAGS "-dynamic")
+ 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
+
+ set(BGP_${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 ${BGP_${lang}_DYNAMIC_EXE_FLAGS} ${BGP_${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(__BlueGeneP_set_static_flags compiler_id lang)
+ set(BGP_${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 ${BGP_${lang}_DEFAULT_EXE_FLAGS}")
+endmacro()
diff --git a/Modules/Platform/BlueGeneP-dynamic-GNU-C.cmake b/Modules/Platform/BlueGeneP-dynamic-GNU-C.cmake
new file mode 100644
index 000000000..bd4696b6b
--- /dev/null
+++ b/Modules/Platform/BlueGeneP-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.)
+
+__BlueGeneP_set_dynamic_flags(GNU C)
diff --git a/Modules/Platform/BlueGeneP-dynamic-GNU-CXX.cmake b/Modules/Platform/BlueGeneP-dynamic-GNU-CXX.cmake
new file mode 100644
index 000000000..9c995dc7b
--- /dev/null
+++ b/Modules/Platform/BlueGeneP-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.)
+
+__BlueGeneP_set_dynamic_flags(GNU CXX)
diff --git a/Modules/Platform/BlueGeneP-dynamic-GNU-Fortran.cmake b/Modules/Platform/BlueGeneP-dynamic-GNU-Fortran.cmake
new file mode 100644
index 000000000..19d6be8ec
--- /dev/null
+++ b/Modules/Platform/BlueGeneP-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.)
+
+__BlueGeneP_set_dynamic_flags(GNU Fortran)
diff --git a/Modules/Platform/BlueGeneP-dynamic-XL-C.cmake b/Modules/Platform/BlueGeneP-dynamic-XL-C.cmake
new file mode 100644
index 000000000..2dbbbc0ec
--- /dev/null
+++ b/Modules/Platform/BlueGeneP-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.)
+
+__BlueGeneP_set_dynamic_flags(XL C)
diff --git a/Modules/Platform/BlueGeneP-dynamic-XL-CXX.cmake b/Modules/Platform/BlueGeneP-dynamic-XL-CXX.cmake
new file mode 100644
index 000000000..2bc51272b
--- /dev/null
+++ b/Modules/Platform/BlueGeneP-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.)
+
+__BlueGeneP_set_dynamic_flags(XL CXX)
diff --git a/Modules/Platform/BlueGeneP-dynamic-XL-Fortran.cmake b/Modules/Platform/BlueGeneP-dynamic-XL-Fortran.cmake
new file mode 100644
index 000000000..59da63da6
--- /dev/null
+++ b/Modules/Platform/BlueGeneP-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.)
+
+__BlueGeneP_set_dynamic_flags(XL Fortran)
diff --git a/Modules/Platform/BlueGeneP-dynamic.cmake b/Modules/Platform/BlueGeneP-dynamic.cmake
new file mode 100644
index 000000000..8f96f2f13
--- /dev/null
+++ b/Modules/Platform/BlueGeneP-dynamic.cmake
@@ -0,0 +1,19 @@
+
+#=============================================================================
+# 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/BlueGeneP-base)
+set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS TRUE)
+set(CMAKE_FIND_LIBRARY_PREFIXES "lib")
+set(CMAKE_FIND_LIBRARY_SUFFIXES ".so" ".a")
diff --git a/Modules/Platform/BlueGeneP-static-GNU-C.cmake b/Modules/Platform/BlueGeneP-static-GNU-C.cmake
new file mode 100644
index 000000000..412a7a3e5
--- /dev/null
+++ b/Modules/Platform/BlueGeneP-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.)
+
+__BlueGeneP_set_static_flags(GNU C)
diff --git a/Modules/Platform/BlueGeneP-static-GNU-CXX.cmake b/Modules/Platform/BlueGeneP-static-GNU-CXX.cmake
new file mode 100644
index 000000000..418f0d8d5
--- /dev/null
+++ b/Modules/Platform/BlueGeneP-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.)
+
+__BlueGeneP_set_static_flags(GNU CXX)
diff --git a/Modules/Platform/BlueGeneP-static-GNU-Fortran.cmake b/Modules/Platform/BlueGeneP-static-GNU-Fortran.cmake
new file mode 100644
index 000000000..119195b30
--- /dev/null
+++ b/Modules/Platform/BlueGeneP-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.)
+
+__BlueGeneP_set_static_flags(GNU Fortran)
diff --git a/Modules/Platform/BlueGeneP-static-XL-C.cmake b/Modules/Platform/BlueGeneP-static-XL-C.cmake
new file mode 100644
index 000000000..1f2095932
--- /dev/null
+++ b/Modules/Platform/BlueGeneP-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.)
+
+__BlueGeneP_set_static_flags(XL C)
diff --git a/Modules/Platform/BlueGeneP-static-XL-CXX.cmake b/Modules/Platform/BlueGeneP-static-XL-CXX.cmake
new file mode 100644
index 000000000..f027a533f
--- /dev/null
+++ b/Modules/Platform/BlueGeneP-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.)
+
+__BlueGeneP_set_static_flags(XL CXX)
diff --git a/Modules/Platform/BlueGeneP-static-XL-Fortran.cmake b/Modules/Platform/BlueGeneP-static-XL-Fortran.cmake
new file mode 100644
index 000000000..778d4bd91
--- /dev/null
+++ b/Modules/Platform/BlueGeneP-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.)
+
+__BlueGeneP_set_static_flags(XL Fortran)
diff --git a/Modules/Platform/BlueGeneP-static.cmake b/Modules/Platform/BlueGeneP-static.cmake
new file mode 100644
index 000000000..c4f5f21a6
--- /dev/null
+++ b/Modules/Platform/BlueGeneP-static.cmake
@@ -0,0 +1,19 @@
+
+#=============================================================================
+# 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/BlueGeneP-base)
+set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE)
+set(CMAKE_FIND_LIBRARY_PREFIXES "lib")
+set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
diff --git a/Modules/Platform/CYGWIN-GNU-C.cmake b/Modules/Platform/CYGWIN-GNU-C.cmake
new file mode 100644
index 000000000..9eb0ecf29
--- /dev/null
+++ b/Modules/Platform/CYGWIN-GNU-C.cmake
@@ -0,0 +1,2 @@
+include(Platform/CYGWIN-GNU)
+__cygwin_compiler_gnu(C)
diff --git a/Modules/Platform/CYGWIN-GNU-CXX.cmake b/Modules/Platform/CYGWIN-GNU-CXX.cmake
new file mode 100644
index 000000000..2603dcd49
--- /dev/null
+++ b/Modules/Platform/CYGWIN-GNU-CXX.cmake
@@ -0,0 +1,2 @@
+include(Platform/CYGWIN-GNU)
+__cygwin_compiler_gnu(CXX)
diff --git a/Modules/Platform/CYGWIN-GNU-Fortran.cmake b/Modules/Platform/CYGWIN-GNU-Fortran.cmake
new file mode 100644
index 000000000..d3b49b6f9
--- /dev/null
+++ b/Modules/Platform/CYGWIN-GNU-Fortran.cmake
@@ -0,0 +1,2 @@
+include(Platform/CYGWIN-GNU)
+__cygwin_compiler_gnu(Fortran)
diff --git a/Modules/Platform/CYGWIN-GNU.cmake b/Modules/Platform/CYGWIN-GNU.cmake
new file mode 100644
index 000000000..eae313a50
--- /dev/null
+++ b/Modules/Platform/CYGWIN-GNU.cmake
@@ -0,0 +1,56 @@
+
+#=============================================================================
+# 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 module is shared by multiple languages; use include blocker.
+if(__CYGWIN_COMPILER_GNU)
+ return()
+endif()
+set(__CYGWIN_COMPILER_GNU 1)
+
+# TODO: Is -Wl,--enable-auto-import now always default?
+set(CMAKE_EXE_LINKER_FLAGS_INIT "-Wl,--enable-auto-import")
+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
+ "<CMAKE_${lang}_COMPILER> <LANGUAGE_COMPILE_FLAGS> <CMAKE_SHARED_MODULE_${lang}_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> <LANGUAGE_COMPILE_FLAGS> <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>")
+ 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>")
+
+ # No -fPIC on cygwin
+ set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "")
+ set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "")
+ set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "")
+
+ # 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
+ # versions of the libraries.
+ FOREACH(type SHARED_LIBRARY SHARED_MODULE EXE)
+ SET(CMAKE_${type}_LINK_STATIC_${lang}_FLAGS "-Wl,-Bstatic")
+ SET(CMAKE_${type}_LINK_DYNAMIC_${lang}_FLAGS "-Wl,-Bdynamic")
+ ENDFOREACH(type)
+
+ set(CMAKE_EXE_EXPORTS_${lang}_FLAG "-Wl,--export-all-symbols")
+ # 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}")
+endmacro()
diff --git a/Modules/Platform/CYGWIN-windres.cmake b/Modules/Platform/CYGWIN-windres.cmake
new file mode 100644
index 000000000..8bc1b15e9
--- /dev/null
+++ b/Modules/Platform/CYGWIN-windres.cmake
@@ -0,0 +1 @@
+SET(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> -O coff <FLAGS> <DEFINES> <SOURCE> <OBJECT>")
diff --git a/Modules/Platform/CYGWIN.cmake b/Modules/Platform/CYGWIN.cmake
new file mode 100644
index 000000000..b7ad2cee1
--- /dev/null
+++ b/Modules/Platform/CYGWIN.cmake
@@ -0,0 +1,64 @@
+if("${CMAKE_MINIMUM_REQUIRED_VERSION}" VERSION_LESS "2.8.3.20101214")
+ set(__USE_CMAKE_LEGACY_CYGWIN_WIN32 1)
+endif()
+if(NOT DEFINED WIN32)
+ set(WIN32 0)
+ if(DEFINED __USE_CMAKE_LEGACY_CYGWIN_WIN32)
+ if(NOT DEFINED CMAKE_LEGACY_CYGWIN_WIN32
+ AND DEFINED ENV{CMAKE_LEGACY_CYGWIN_WIN32})
+ set(CMAKE_LEGACY_CYGWIN_WIN32 $ENV{CMAKE_LEGACY_CYGWIN_WIN32})
+ endif()
+ if(CMAKE_LEGACY_CYGWIN_WIN32)
+ message(STATUS "Defining WIN32 under Cygwin due to CMAKE_LEGACY_CYGWIN_WIN32")
+ set(WIN32 1)
+ elseif("x${CMAKE_LEGACY_CYGWIN_WIN32}" STREQUAL "x")
+ message(WARNING "CMake no longer defines WIN32 on Cygwin!"
+ "\n"
+ "(1) If you are just trying to build this project, ignore this warning "
+ "or quiet it by setting CMAKE_LEGACY_CYGWIN_WIN32=0 in your environment or "
+ "in the CMake cache. "
+ "If later configuration or build errors occur then this project may "
+ "have been written under the assumption that Cygwin is WIN32. "
+ "In that case, set CMAKE_LEGACY_CYGWIN_WIN32=1 instead."
+ "\n"
+ "(2) If you are developing this project, add the line\n"
+ " set(CMAKE_LEGACY_CYGWIN_WIN32 0) # Remove when CMake >= 2.8.4 is required\n"
+ "at the top of your top-level CMakeLists.txt file or set the minimum "
+ "required version of CMake to 2.8.4 or higher. "
+ "Then teach your project to build on Cygwin without WIN32.")
+ endif()
+ elseif(DEFINED CMAKE_LEGACY_CYGWIN_WIN32)
+ message(AUTHOR_WARNING "CMAKE_LEGACY_CYGWIN_WIN32 ignored because\n"
+ " cmake_minimum_required(VERSION ${CMAKE_MINIMUM_REQUIRED_VERSION})\n"
+ "is at least 2.8.4.")
+ endif()
+endif()
+if(DEFINED __USE_CMAKE_LEGACY_CYGWIN_WIN32)
+ # Pass WIN32 legacy setting to scripts.
+ if(WIN32)
+ set(ENV{CMAKE_LEGACY_CYGWIN_WIN32} 1)
+ else()
+ set(ENV{CMAKE_LEGACY_CYGWIN_WIN32} 0)
+ endif()
+ unset(__USE_CMAKE_LEGACY_CYGWIN_WIN32)
+endif()
+
+SET(CYGWIN 1)
+
+SET(CMAKE_SHARED_LIBRARY_PREFIX "cyg")
+SET(CMAKE_SHARED_LIBRARY_SUFFIX ".dll")
+SET(CMAKE_SHARED_MODULE_PREFIX "cyg")
+SET(CMAKE_SHARED_MODULE_SUFFIX ".dll")
+SET(CMAKE_IMPORT_LIBRARY_PREFIX "lib")
+SET(CMAKE_IMPORT_LIBRARY_SUFFIX ".dll.a")
+SET(CMAKE_EXECUTABLE_SUFFIX ".exe") # .exe
+# Modules have a different default prefix that shared libs.
+SET(CMAKE_MODULE_EXISTS 1)
+
+SET(CMAKE_FIND_LIBRARY_PREFIXES "lib")
+SET(CMAKE_FIND_LIBRARY_SUFFIXES ".dll.a" ".a")
+
+# Shared libraries on cygwin can be named with their version number.
+SET(CMAKE_SHARED_LIBRARY_NAME_WITH_VERSION 1)
+
+INCLUDE(Platform/UnixPaths)
diff --git a/Modules/Platform/Catamount.cmake b/Modules/Platform/Catamount.cmake
new file mode 100644
index 000000000..01493fc21
--- /dev/null
+++ b/Modules/Platform/Catamount.cmake
@@ -0,0 +1,26 @@
+#Catamount, which runs on the compute nodes of Cray machines, e.g. RedStorm, doesn't support shared libs
+SET_PROPERTY(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE)
+
+SET(CMAKE_SHARED_LIBRARY_C_FLAGS "") # -pic
+SET(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "") # -shared
+SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") # +s, flag for exe link to use shared lib
+SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "") # -rpath
+SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP "") # : or empty
+
+SET(CMAKE_LINK_LIBRARY_SUFFIX "")
+SET(CMAKE_STATIC_LIBRARY_PREFIX "lib")
+SET(CMAKE_STATIC_LIBRARY_SUFFIX ".a")
+SET(CMAKE_SHARED_LIBRARY_PREFIX "lib") # lib
+SET(CMAKE_SHARED_LIBRARY_SUFFIX ".a") # .a
+SET(CMAKE_EXECUTABLE_SUFFIX "") # .exe
+SET(CMAKE_DL_LIBS "" )
+
+SET(CMAKE_FIND_LIBRARY_PREFIXES "lib")
+SET(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
+
+INCLUDE(Platform/UnixPaths)
+
+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/Darwin-Absoft-Fortran.cmake b/Modules/Platform/Darwin-Absoft-Fortran.cmake
new file mode 100644
index 000000000..beb41a3b8
--- /dev/null
+++ b/Modules/Platform/Darwin-Absoft-Fortran.cmake
@@ -0,0 +1 @@
+set(CMAKE_Fortran_VERBOSE_FLAG "-X -v") # Runs gcc under the hood.
diff --git a/Modules/Platform/Darwin-GNU-C.cmake b/Modules/Platform/Darwin-GNU-C.cmake
new file mode 100644
index 000000000..4e326c4ca
--- /dev/null
+++ b/Modules/Platform/Darwin-GNU-C.cmake
@@ -0,0 +1,4 @@
+include(Platform/Darwin-GNU)
+__darwin_compiler_gnu(C)
+cmake_gnu_has_isysroot(C)
+cmake_gnu_set_osx_deployment_target_flag(C)
diff --git a/Modules/Platform/Darwin-GNU-CXX.cmake b/Modules/Platform/Darwin-GNU-CXX.cmake
new file mode 100644
index 000000000..b39487e58
--- /dev/null
+++ b/Modules/Platform/Darwin-GNU-CXX.cmake
@@ -0,0 +1,4 @@
+include(Platform/Darwin-GNU)
+__darwin_compiler_gnu(CXX)
+cmake_gnu_has_isysroot(CXX)
+cmake_gnu_set_osx_deployment_target_flag(CXX)
diff --git a/Modules/Platform/Darwin-GNU-Fortran.cmake b/Modules/Platform/Darwin-GNU-Fortran.cmake
new file mode 100644
index 000000000..8e8acc377
--- /dev/null
+++ b/Modules/Platform/Darwin-GNU-Fortran.cmake
@@ -0,0 +1,2 @@
+include(Platform/Darwin-GNU)
+__darwin_compiler_gnu(Fortran)
diff --git a/Modules/Platform/Darwin-GNU.cmake b/Modules/Platform/Darwin-GNU.cmake
new file mode 100644
index 000000000..8a50a6ab9
--- /dev/null
+++ b/Modules/Platform/Darwin-GNU.cmake
@@ -0,0 +1,64 @@
+
+#=============================================================================
+# 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 module is shared by multiple languages; use include blocker.
+if(__DARWIN_COMPILER_GNU)
+ return()
+endif()
+set(__DARWIN_COMPILER_GNU 1)
+
+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")
+endmacro()
+
+macro(cmake_gnu_has_isysroot lang)
+ if("x${CMAKE_${lang}_HAS_ISYSROOT}" STREQUAL "x")
+ set(_doc "${lang} compiler has -isysroot")
+ message(STATUS "Checking whether ${_doc}")
+ execute_process(
+ COMMAND ${CMAKE_${lang}_COMPILER} "-v" "--help"
+ OUTPUT_VARIABLE _gcc_help
+ ERROR_VARIABLE _gcc_help
+ )
+ if("${_gcc_help}" MATCHES "isysroot")
+ message(STATUS "Checking whether ${_doc} - yes")
+ set(CMAKE_${lang}_HAS_ISYSROOT 1)
+ else()
+ message(STATUS "Checking whether ${_doc} - no")
+ set(CMAKE_${lang}_HAS_ISYSROOT 0)
+ endif()
+ endif()
+endmacro()
+
+macro(cmake_gnu_set_osx_deployment_target_flag lang)
+ if(NOT DEFINED CMAKE_${lang}_OSX_DEPLOYMENT_TARGET_FLAG)
+ set(_doc "${lang} compiler supports OSX deployment target flag")
+ message(STATUS "Checking whether ${_doc}")
+ execute_process(
+ COMMAND ${CMAKE_${lang}_COMPILER} "-v" "--help"
+ OUTPUT_VARIABLE _gcc_help
+ ERROR_VARIABLE _gcc_help
+ )
+ if("${_gcc_help}" MATCHES "macosx-version-min")
+ message(STATUS "Checking whether ${_doc} - yes")
+ set(CMAKE_${lang}_OSX_DEPLOYMENT_TARGET_FLAG "-mmacosx-version-min=")
+ else()
+ message(STATUS "Checking whether ${_doc} - no")
+ set(CMAKE_${lang}_OSX_DEPLOYMENT_TARGET_FLAG "")
+ endif()
+ set(CMAKE_${lang}_OSX_DEPLOYMENT_TARGET_FLAG_CODE "SET(CMAKE_${lang}_OSX_DEPLOYMENT_TARGET_FLAG \"${CMAKE_${lang}_OSX_DEPLOYMENT_TARGET_FLAG}\")")
+ endif()
+endmacro()
diff --git a/Modules/Platform/Darwin-NAG-Fortran.cmake b/Modules/Platform/Darwin-NAG-Fortran.cmake
new file mode 100644
index 000000000..933f9e1a2
--- /dev/null
+++ b/Modules/Platform/Darwin-NAG-Fortran.cmake
@@ -0,0 +1,5 @@
+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>")
diff --git a/Modules/Platform/Darwin-VisualAge-C.cmake b/Modules/Platform/Darwin-VisualAge-C.cmake
new file mode 100644
index 000000000..859914f86
--- /dev/null
+++ b/Modules/Platform/Darwin-VisualAge-C.cmake
@@ -0,0 +1 @@
+include(Platform/Darwin-XL-C)
diff --git a/Modules/Platform/Darwin-VisualAge-CXX.cmake b/Modules/Platform/Darwin-VisualAge-CXX.cmake
new file mode 100644
index 000000000..46c1005df
--- /dev/null
+++ b/Modules/Platform/Darwin-VisualAge-CXX.cmake
@@ -0,0 +1 @@
+include(Platform/Darwin-XL-CXX)
diff --git a/Modules/Platform/Darwin-XL-C.cmake b/Modules/Platform/Darwin-XL-C.cmake
new file mode 100644
index 000000000..934ebcc8c
--- /dev/null
+++ b/Modules/Platform/Darwin-XL-C.cmake
@@ -0,0 +1,5 @@
+SET(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-qmkshrobj")
+SET(CMAKE_SHARED_MODULE_CREATE_C_FLAGS "-bundle")
+
+# Enable shared library versioning.
+SET(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "-Wl,-install_name")
diff --git a/Modules/Platform/Darwin-XL-CXX.cmake b/Modules/Platform/Darwin-XL-CXX.cmake
new file mode 100644
index 000000000..22ae0183a
--- /dev/null
+++ b/Modules/Platform/Darwin-XL-CXX.cmake
@@ -0,0 +1,5 @@
+SET(CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS "-qmkshrobj")
+SET(CMAKE_SHARED_MODULE_CREATE_CXX_FLAGS "-bundle")
+
+# Enable shared library versioning.
+SET(CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG "-Wl,-install_name")
diff --git a/Modules/Platform/Darwin-icc.cmake b/Modules/Platform/Darwin-icc.cmake
new file mode 100644
index 000000000..b592e5f55
--- /dev/null
+++ b/Modules/Platform/Darwin-icc.cmake
@@ -0,0 +1,131 @@
+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(CMAKE_COMPILER_IS_GNUCC)
+
+# 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(CMAKE_COMPILER_IS_GNUCXX)
+ENDIF ( _OSX_VERSION MATCHES "^10.4" )
+
+
+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(NOT "$ENV{CMAKE_OSX_ARCHITECTURES}" STREQUAL "")
+ # now put _CMAKE_OSX_MACHINE into the cache
+ SET(CMAKE_OSX_ARCHITECTURES ${_CMAKE_OSX_MACHINE}
+ CACHE STRING "Build architectures for OSX")
+ENDIF(EXISTS /Developer/SDKs/MacOSX10.4u.sdk)
+
+
+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("${CMAKE_BACKWARDS_COMPATIBILITY}" MATCHES "^1\\.[0-6]$")
+
+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(NOT XCODE)
+
+# Xcode does not support -isystem yet.
+IF(XCODE)
+ SET(CMAKE_INCLUDE_SYSTEM_FLAG_C)
+ SET(CMAKE_INCLUDE_SYSTEM_FLAG_CXX)
+ENDIF(XCODE)
+
+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
new file mode 100644
index 000000000..e247bae28
--- /dev/null
+++ b/Modules/Platform/Darwin-icpc.cmake
@@ -0,0 +1,3 @@
+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
new file mode 100644
index 000000000..eff07b295
--- /dev/null
+++ b/Modules/Platform/Darwin.cmake
@@ -0,0 +1,268 @@
+SET(APPLE 1)
+
+# Darwin versions:
+# 6.x == Mac OSX 10.2 (Jaguar)
+# 7.x == Mac OSX 10.3 (Panther)
+# 8.x == Mac OSX 10.4 (Tiger)
+# 9.x == Mac OSX 10.5 (Leopard)
+# 10.x == Mac OSX 10.6 (Snow Leopard)
+# 11.x == Mac OSX 10.7 (Lion)
+# 12.x == Mac OSX 10.8 (Mountain Lion)
+STRING(REGEX REPLACE "^([0-9]+)\\.([0-9]+).*$" "\\1" DARWIN_MAJOR_VERSION "${CMAKE_SYSTEM_VERSION}")
+STRING(REGEX REPLACE "^([0-9]+)\\.([0-9]+).*$" "\\2" DARWIN_MINOR_VERSION "${CMAKE_SYSTEM_VERSION}")
+
+# Do not use the "-Wl,-search_paths_first" flag with the OSX 10.2 compiler.
+# Done this way because it is too early to do a TRY_COMPILE.
+IF(NOT DEFINED HAVE_FLAG_SEARCH_PATHS_FIRST)
+ SET(HAVE_FLAG_SEARCH_PATHS_FIRST 0)
+ IF("${DARWIN_MAJOR_VERSION}" GREATER 6)
+ SET(HAVE_FLAG_SEARCH_PATHS_FIRST 1)
+ ENDIF("${DARWIN_MAJOR_VERSION}" GREATER 6)
+ENDIF(NOT DEFINED HAVE_FLAG_SEARCH_PATHS_FIRST)
+# More desirable, but does not work:
+ #INCLUDE(CheckCXXCompilerFlag)
+ #CHECK_CXX_COMPILER_FLAG("-Wl,-search_paths_first" HAVE_FLAG_SEARCH_PATHS_FIRST)
+
+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_OSX_COMPATIBILITY_VERSION_FLAG "-compatibility_version ")
+SET(CMAKE_C_OSX_CURRENT_VERSION_FLAG "-current_version ")
+SET(CMAKE_CXX_OSX_COMPATIBILITY_VERSION_FLAG "${CMAKE_C_OSX_COMPATIBILITY_VERSION_FLAG}")
+SET(CMAKE_CXX_OSX_CURRENT_VERSION_FLAG "${CMAKE_C_OSX_CURRENT_VERSION_FLAG}")
+
+SET(CMAKE_C_LINK_FLAGS "-Wl,-headerpad_max_install_names")
+SET(CMAKE_CXX_LINK_FLAGS "-Wl,-headerpad_max_install_names")
+
+IF(HAVE_FLAG_SEARCH_PATHS_FIRST)
+ SET(CMAKE_C_LINK_FLAGS "-Wl,-search_paths_first ${CMAKE_C_LINK_FLAGS}")
+ SET(CMAKE_CXX_LINK_FLAGS "-Wl,-search_paths_first ${CMAKE_CXX_LINK_FLAGS}")
+ENDIF(HAVE_FLAG_SEARCH_PATHS_FIRST)
+
+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_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")
+
+# 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
+# and still cmake didn't fail in CMakeFindBinUtils.cmake (because it isn't rerun)
+# hardcode CMAKE_INSTALL_NAME_TOOL here to install_name_tool, so it behaves as it did before, Alex
+IF(NOT DEFINED CMAKE_INSTALL_NAME_TOOL)
+ FIND_PROGRAM(CMAKE_INSTALL_NAME_TOOL install_name_tool)
+ MARK_AS_ADVANCED(CMAKE_INSTALL_NAME_TOOL)
+ENDIF(NOT DEFINED CMAKE_INSTALL_NAME_TOOL)
+
+# Set the assumed (Pre 10.5 or Default) location of the developer tools
+SET(OSX_DEVELOPER_ROOT "/Developer")
+
+# Use the xcode-select tool if it's available (Xcode >= 3.0 installations)
+FIND_PROGRAM(CMAKE_XCODE_SELECT xcode-select)
+MARK_AS_ADVANCED(CMAKE_XCODE_SELECT)
+IF(CMAKE_XCODE_SELECT)
+ EXECUTE_PROCESS(COMMAND ${CMAKE_XCODE_SELECT} "-print-path"
+ OUTPUT_VARIABLE OSX_DEVELOPER_ROOT
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ENDIF(CMAKE_XCODE_SELECT)
+
+# Find installed SDKs
+# Start with Xcode-4.3+ default SDKs directory
+SET(_CMAKE_OSX_SDKS_DIR
+ "${OSX_DEVELOPER_ROOT}/Platforms/MacOSX.platform/Developer/SDKs")
+FILE(GLOB _CMAKE_OSX_SDKS "${_CMAKE_OSX_SDKS_DIR}/*")
+
+# If not present, try pre-4.3 SDKs directory
+IF(NOT _CMAKE_OSX_SDKS)
+SET(_CMAKE_OSX_SDKS_DIR "${OSX_DEVELOPER_ROOT}/SDKs")
+ FILE(GLOB _CMAKE_OSX_SDKS "${_CMAKE_OSX_SDKS_DIR}/*")
+ENDIF(NOT _CMAKE_OSX_SDKS)
+
+EXECUTE_PROCESS(COMMAND sw_vers -productVersion
+ OUTPUT_VARIABLE CURRENT_OSX_VERSION
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+#----------------------------------------------------------------------------
+# _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(_CURRENT_OSX_VERSION VERSION_GREATER 10.3)
+
+#----------------------------------------------------------------------------
+# CMAKE_OSX_SYSROOT
+
+# Environment variable set by the user overrides our default.
+# Use the same environment variable that Xcode uses.
+SET(ENV_SDKROOT "$ENV{SDKROOT}")
+
+# Set CMAKE_OSX_SYSROOT_DEFAULT based on _CURRENT_OSX_VERSION,
+# accounting for the known specially named SDKs.
+SET(CMAKE_OSX_SYSROOT_DEFAULT
+ "${_CMAKE_OSX_SDKS_DIR}/MacOSX${_CURRENT_OSX_VERSION}.sdk")
+
+IF(_CURRENT_OSX_VERSION STREQUAL "10.4")
+ SET(CMAKE_OSX_SYSROOT_DEFAULT
+ "${_CMAKE_OSX_SDKS_DIR}/MacOSX10.4u.sdk")
+ENDIF(_CURRENT_OSX_VERSION STREQUAL "10.4")
+
+IF(_CURRENT_OSX_VERSION STREQUAL "10.3")
+ SET(CMAKE_OSX_SYSROOT_DEFAULT
+ "${_CMAKE_OSX_SDKS_DIR}/MacOSX10.3.9.sdk")
+ENDIF(_CURRENT_OSX_VERSION STREQUAL "10.3")
+
+# Use environment or default as initial cache value:
+IF(NOT ENV_SDKROOT STREQUAL "")
+ SET(CMAKE_OSX_SYSROOT_VALUE ${ENV_SDKROOT})
+ELSE(NOT ENV_SDKROOT STREQUAL "")
+ SET(CMAKE_OSX_SYSROOT_VALUE ${CMAKE_OSX_SYSROOT_DEFAULT})
+ENDIF(NOT ENV_SDKROOT STREQUAL "")
+
+# Set cache variable - end user may change this during ccmake or cmake-gui configure.
+SET(CMAKE_OSX_SYSROOT ${CMAKE_OSX_SYSROOT_VALUE} CACHE PATH
+ "The product will be built against the headers and libraries located inside the indicated SDK.")
+
+#----------------------------------------------------------------------------
+function(SanityCheckSDKAndDeployTarget _sdk_path _deploy)
+ if(_deploy STREQUAL "")
+ return()
+ endif()
+
+ if(_sdk_path STREQUAL "")
+ message(FATAL_ERROR "CMAKE_OSX_DEPLOYMENT_TARGET='${_deploy}' but CMAKE_OSX_SYSROOT is empty... - either set CMAKE_OSX_SYSROOT to a valid SDK or set CMAKE_OSX_DEPLOYMENT_TARGET to empty")
+ endif()
+
+ string(REGEX REPLACE "(.*MacOSX*)(....)(.*\\.sdk)" "\\2" SDK "${_sdk_path}")
+ if(_deploy GREATER "${SDK}")
+ message(FATAL_ERROR "CMAKE_OSX_DEPLOYMENT_TARGET (${_deploy}) is greater than CMAKE_OSX_SYSROOT SDK (${_sdk_path}). Please set CMAKE_OSX_DEPLOYMENT_TARGET to ${SDK} or lower")
+ endif()
+endfunction(SanityCheckSDKAndDeployTarget)
+#----------------------------------------------------------------------------
+
+# Make sure the combination of SDK and Deployment Target are allowed
+SanityCheckSDKAndDeployTarget("${CMAKE_OSX_SYSROOT}" "${CMAKE_OSX_DEPLOYMENT_TARGET}")
+
+# set _CMAKE_OSX_MACHINE to uname -m
+EXECUTE_PROCESS(COMMAND uname -m
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ OUTPUT_VARIABLE _CMAKE_OSX_MACHINE)
+
+# check for Power PC and change to ppc
+IF(_CMAKE_OSX_MACHINE MATCHES "Power")
+ SET(_CMAKE_OSX_MACHINE ppc)
+ENDIF(_CMAKE_OSX_MACHINE MATCHES "Power")
+
+# check for environment variable CMAKE_OSX_ARCHITECTURES
+# if it is set.
+IF(NOT "$ENV{CMAKE_OSX_ARCHITECTURES}" STREQUAL "")
+ SET(CMAKE_OSX_ARCHITECTURES_VALUE "$ENV{CMAKE_OSX_ARCHITECTURES}")
+ELSE(NOT "$ENV{CMAKE_OSX_ARCHITECTURES}" STREQUAL "")
+ SET(CMAKE_OSX_ARCHITECTURES_VALUE "")
+ENDIF(NOT "$ENV{CMAKE_OSX_ARCHITECTURES}" STREQUAL "")
+
+# now put _CMAKE_OSX_MACHINE into the cache
+SET(CMAKE_OSX_ARCHITECTURES ${CMAKE_OSX_ARCHITECTURES_VALUE} CACHE STRING
+ "Build architectures for OSX")
+
+
+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("${CMAKE_BACKWARDS_COMPATIBILITY}" MATCHES "^1\\.[0-6]$")
+
+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")
+ENDIF(NOT XCODE)
+
+# Xcode does not support -isystem yet.
+IF(XCODE)
+ SET(CMAKE_INCLUDE_SYSTEM_FLAG_C)
+ SET(CMAKE_INCLUDE_SYSTEM_FLAG_CXX)
+ENDIF(XCODE)
+
+IF("${_CURRENT_OSX_VERSION}" VERSION_LESS "10.5")
+ # Need to list dependent shared libraries on link line. When building
+ # with -isysroot (for universal binaries), the linker always looks for
+ # dependent libraries under the sysroot. Listing them on the link
+ # line works around the problem.
+ SET(CMAKE_LINK_DEPENDENT_LIBRARY_FILES 1)
+ENDIF()
+
+SET(CMAKE_C_CREATE_SHARED_LIBRARY_FORBIDDEN_FLAGS -w)
+SET(CMAKE_CXX_CREATE_SHARED_LIBRARY_FORBIDDEN_FLAGS -w)
+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>")
+
+SET(CMAKE_C_CREATE_MACOSX_FRAMEWORK
+ "<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_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>")
+
+
+# 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(_apps_paths)
+FOREACH(_path
+ "~/Applications"
+ "/Applications"
+ "${OSX_DEVELOPER_ROOT}/../Applications" # Xcode 4.3+
+ "${OSX_DEVELOPER_ROOT}/Applications" # pre-4.3
+ )
+ GET_FILENAME_COMPONENT(_apps "${_path}" ABSOLUTE)
+ IF(EXISTS "${_apps}")
+ LIST(APPEND _apps_paths "${_apps}")
+ ENDIF()
+ENDFOREACH()
+LIST(REMOVE_DUPLICATES _apps_paths)
+SET(CMAKE_SYSTEM_APPBUNDLE_PATH
+ ${_apps_paths})
+UNSET(_apps_paths)
+
+INCLUDE(Platform/UnixPaths)
+LIST(APPEND CMAKE_SYSTEM_PREFIX_PATH
+ /sw # Fink
+ /opt/local # MacPorts
+ )
diff --git a/Modules/Platform/DragonFly.cmake b/Modules/Platform/DragonFly.cmake
new file mode 100644
index 000000000..f6e0f810f
--- /dev/null
+++ b/Modules/Platform/DragonFly.cmake
@@ -0,0 +1,5 @@
+# DragonFly BSD was forked from FreeBSD and is still very close to it
+# http://www.dragonflybsd.org
+# see http://archive.netbsd.se/?ml=dfbsd-users&a=2007-07&m=4678361
+
+INCLUDE(Platform/FreeBSD)
diff --git a/Modules/Platform/FreeBSD.cmake b/Modules/Platform/FreeBSD.cmake
new file mode 100644
index 000000000..82fe961fb
--- /dev/null
+++ b/Modules/Platform/FreeBSD.cmake
@@ -0,0 +1,28 @@
+IF(EXISTS /usr/include/dlfcn.h)
+ SET(CMAKE_DL_LIBS "")
+ SET(CMAKE_C_COMPILE_OPTIONS_PIC "-fPIC")
+ SET(CMAKE_C_COMPILE_OPTIONS_PIE "-fPIE")
+ SET(CMAKE_SHARED_LIBRARY_C_FLAGS "-fPIC") # -pic
+ SET(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-shared") # -shared
+ SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") # +s, flag for exe link to use shared lib
+ SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "-Wl,-rpath,") # -rpath
+ SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP ":") # : or empty
+ 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")
+ENDIF(EXISTS /usr/include/dlfcn.h)
+
+# Shared libraries with no builtin soname may not be linked safely by
+# specifying the file path.
+SET(CMAKE_PLATFORM_USES_PATH_WHEN_NO_SONAME 1)
+
+# 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
+# versions of the libraries.
+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(type)
+
+INCLUDE(Platform/UnixPaths)
diff --git a/Modules/Platform/GNU.cmake b/Modules/Platform/GNU.cmake
new file mode 100644
index 000000000..4bcfd51ce
--- /dev/null
+++ b/Modules/Platform/GNU.cmake
@@ -0,0 +1,13 @@
+# GCC is the default compiler on GNU/Hurd.
+SET(CMAKE_DL_LIBS "dl")
+SET(CMAKE_SHARED_LIBRARY_C_FLAGS "-fPIC")
+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")
+
+SET(CMAKE_LIBRARY_ARCHITECTURE_REGEX "[a-z0-9_]+(-[a-z0-9_]+)?-gnu[a-z0-9_]*")
+
+INCLUDE(Platform/UnixPaths)
diff --git a/Modules/Platform/GNUtoMS_lib.bat.in b/Modules/Platform/GNUtoMS_lib.bat.in
new file mode 100644
index 000000000..2da920ab0
--- /dev/null
+++ b/Modules/Platform/GNUtoMS_lib.bat.in
@@ -0,0 +1,3 @@
+@echo off
+call "@CMAKE_GNUtoMS_BAT@"
+lib /machine:"@CMAKE_GNUtoMS_ARCH@" %*
diff --git a/Modules/Platform/GNUtoMS_lib.cmake b/Modules/Platform/GNUtoMS_lib.cmake
new file mode 100644
index 000000000..ca9b0f8da
--- /dev/null
+++ b/Modules/Platform/GNUtoMS_lib.cmake
@@ -0,0 +1,10 @@
+# Usage: cmake -Dlib=lib.bat -Ddef=out.def -Ddll=out.dll -Dimp=out.dll.a -P GNUtoMS_lib.cmake
+get_filename_component(name ${dll} NAME) # .dll file name
+string(REGEX REPLACE "\\.dll\\.a$" ".lib" out "${imp}") # .dll.a -> .lib
+execute_process(
+ COMMAND ${lib} /def:${def} /name:${name} /out:${out}
+ RESULT_VARIABLE res
+ )
+if(res)
+ message(FATAL_ERROR "lib failed: ${res}")
+endif()
diff --git a/Modules/Platform/Generic-ADSP-ASM.cmake b/Modules/Platform/Generic-ADSP-ASM.cmake
new file mode 100644
index 000000000..cec4c2f68
--- /dev/null
+++ b/Modules/Platform/Generic-ADSP-ASM.cmake
@@ -0,0 +1,7 @@
+INCLUDE(Platform/Generic-ADSP-Common)
+
+SET(CMAKE_ASM_SOURCE_FILE_EXTENSIONS asm)
+SET(CMAKE_ASM_OUTPUT_EXTENSION ".doj" )
+SET(CMAKE_ASM_COMPILE_OBJECT
+ "<CMAKE_ASM_COMPILER> <FLAGS> -proc ${ADSP_PROCESSOR} -si-revision ${ADSP_PROCESSOR_SILICIUM_REVISION} -o <OBJECT> <SOURCE>")
+
diff --git a/Modules/Platform/Generic-ADSP-C.cmake b/Modules/Platform/Generic-ADSP-C.cmake
new file mode 100644
index 000000000..f0644687f
--- /dev/null
+++ b/Modules/Platform/Generic-ADSP-C.cmake
@@ -0,0 +1,20 @@
+
+INCLUDE(Platform/Generic-ADSP-Common)
+
+
+SET(CMAKE_C_OUTPUT_EXTENSION ".doj")
+
+SET(CMAKE_C_FLAGS_DEBUG_INIT "-g")
+SET(CMAKE_C_FLAGS_MINSIZEREL_INIT "")
+SET(CMAKE_C_FLAGS_RELEASE_INIT "")
+SET(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "")
+
+SET(CMAKE_C_CREATE_STATIC_LIBRARY
+ "<CMAKE_C_COMPILER> -build-lib -proc ${ADSP_PROCESSOR} -si-revision ${ADSP_PROCESSOR_SILICIUM_REVISION} -o <TARGET> <CMAKE_C_LINK_FLAGS> <OBJECTS>")
+
+SET(CMAKE_C_LINK_EXECUTABLE
+ "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
+
+SET(CMAKE_C_CREATE_SHARED_LIBRARY)
+SET(CMAKE_C_CREATE_MODULE_LIBRARY)
+
diff --git a/Modules/Platform/Generic-ADSP-CXX.cmake b/Modules/Platform/Generic-ADSP-CXX.cmake
new file mode 100644
index 000000000..21daa81c9
--- /dev/null
+++ b/Modules/Platform/Generic-ADSP-CXX.cmake
@@ -0,0 +1,18 @@
+INCLUDE(Platform/Generic-ADSP-Common)
+
+SET(CMAKE_CXX_OUTPUT_EXTENSION ".doj")
+
+SET(CMAKE_CXX_FLAGS_DEBUG_INIT "-g")
+SET(CMAKE_CXX_FLAGS_MINSIZEREL_INIT "")
+SET(CMAKE_CXX_FLAGS_RELEASE_INIT "")
+SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "")
+
+SET(CMAKE_CXX_CREATE_STATIC_LIBRARY
+ "<CMAKE_CXX_COMPILER> -build-lib -proc ${ADSP_PROCESSOR} -si-revision ${ADSP_PROCESSOR_SILICIUM_REVISION} -o <TARGET> <CMAKE_CXX_LINK_FLAGS> <OBJECTS>")
+
+SET(CMAKE_CXX_LINK_EXECUTABLE
+ "<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
+
+SET(CMAKE_CXX_CREATE_SHARED_LIBRARY)
+SET(CMAKE_CXX_CREATE_MODULE_LIBRARY)
+
diff --git a/Modules/Platform/Generic-ADSP-Common.cmake b/Modules/Platform/Generic-ADSP-Common.cmake
new file mode 100644
index 000000000..10fb34e00
--- /dev/null
+++ b/Modules/Platform/Generic-ADSP-Common.cmake
@@ -0,0 +1,120 @@
+# support for the Analog Devices toolchain for their DSPs
+# Raphael Cotty" <raphael.cotty (AT) googlemail.com>
+#
+# it supports three architectures:
+# Blackfin
+# TS (TigerShark)
+# 21k (Sharc 21xxx)
+
+IF(NOT ADSP)
+
+ SET(ADSP TRUE)
+
+ SET(CMAKE_STATIC_LIBRARY_SUFFIX ".dlb")
+ SET(CMAKE_SHARED_LIBRARY_SUFFIX "")
+ SET(CMAKE_EXECUTABLE_SUFFIX ".dxe")
+
+ # if ADSP_PROCESSOR has not been set, but CMAKE_SYSTEM_PROCESSOR has,
+ # assume that this is the processor name to use for the compiler
+ IF(CMAKE_SYSTEM_PROCESSOR AND NOT ADSP_PROCESSOR)
+ SET(ADSP_PROCESSOR ${CMAKE_SYSTEM_PROCESSOR})
+ ENDIF(CMAKE_SYSTEM_PROCESSOR AND NOT ADSP_PROCESSOR)
+
+ # if ADSP_PROCESSOR_SILICIUM_REVISION has not been set, use "none"
+ IF(NOT ADSP_PROCESSOR_SILICIUM_REVISION)
+ SET(ADSP_PROCESSOR_SILICIUM_REVISION "none")
+ ENDIF(NOT ADSP_PROCESSOR_SILICIUM_REVISION)
+
+ # this file is included from the C and CXX files, so handle both here
+
+ GET_FILENAME_COMPONENT(_ADSP_DIR "${CMAKE_C_COMPILER}" PATH)
+ IF(NOT _ADSP_DIR)
+ GET_FILENAME_COMPONENT(_ADSP_DIR "${CMAKE_CXX_COMPILER}" PATH)
+ ENDIF(NOT _ADSP_DIR)
+ IF(NOT _ADSP_DIR)
+ GET_FILENAME_COMPONENT(_ADSP_DIR "${CMAKE_ASM_COMPILER}" PATH)
+ ENDIF(NOT _ADSP_DIR)
+
+ # detect architecture
+
+ IF(CMAKE_C_COMPILER MATCHES ccblkfn OR CMAKE_CXX_COMPILER MATCHES ccblkfn OR CMAKE_ASM_COMPILER MATCHES easmBLKFN)
+ IF(NOT ADSP_PROCESSOR)
+ SET(ADSP_PROCESSOR "ADSP-BF561")
+ ENDIF(NOT ADSP_PROCESSOR)
+ SET(ADSP_BLACKFIN TRUE)
+ SET(_ADSP_FAMILY_DIR "${_ADSP_DIR}/Blackfin")
+ ENDIF(CMAKE_C_COMPILER MATCHES ccblkfn OR CMAKE_CXX_COMPILER MATCHES ccblkfn OR CMAKE_ASM_COMPILER MATCHES easmBLKFN)
+
+ IF(CMAKE_C_COMPILER MATCHES ccts OR CMAKE_CXX_COMPILER MATCHES ccts OR CMAKE_ASM_COMPILER MATCHES easmTS)
+ IF(NOT ADSP_PROCESSOR)
+ SET(ADSP_PROCESSOR "ADSP-TS101")
+ ENDIF(NOT ADSP_PROCESSOR)
+ SET(ADSP_TS TRUE)
+ SET(_ADSP_FAMILY_DIR "${_ADSP_DIR}/TS")
+ ENDIF(CMAKE_C_COMPILER MATCHES ccts OR CMAKE_CXX_COMPILER MATCHES ccts OR CMAKE_ASM_COMPILER MATCHES easmTS)
+
+ IF(CMAKE_C_COMPILER MATCHES cc21k OR CMAKE_CXX_COMPILER MATCHES cc21k OR CMAKE_ASM_COMPILER MATCHES easm21k)
+ IF(NOT ADSP_PROCESSOR)
+ SET(ADSP_PROCESSOR "ADSP-21060")
+ ENDIF(NOT ADSP_PROCESSOR)
+ SET(ADSP_21K TRUE)
+
+ SET(_ADSP_FAMILY_DIR "${_ADSP_DIR}/21k") # default if nothing matches
+ IF (ADSP_PROCESSOR MATCHES "210..$")
+ SET(_ADSP_FAMILY_DIR "${_ADSP_DIR}/21k")
+ ENDIF(ADSP_PROCESSOR MATCHES "210..$")
+
+ IF (ADSP_PROCESSOR MATCHES "211..$")
+ SET(_ADSP_FAMILY_DIR "${_ADSP_DIR}/211k")
+ ENDIF(ADSP_PROCESSOR MATCHES "211..$")
+
+ IF (ADSP_PROCESSOR MATCHES "212..$")
+ SET(_ADSP_FAMILY_DIR "${_ADSP_DIR}/212k")
+ ENDIF(ADSP_PROCESSOR MATCHES "212..$")
+
+ IF (ADSP_PROCESSOR MATCHES "213..$")
+ SET(_ADSP_FAMILY_DIR "${_ADSP_DIR}/213k")
+ ENDIF(ADSP_PROCESSOR MATCHES "213..$")
+
+ SET(_ADSP_FAMILY_DIR "${_ADSP_DIR}/21k")
+ ENDIF(CMAKE_C_COMPILER MATCHES cc21k OR CMAKE_CXX_COMPILER MATCHES cc21k OR CMAKE_ASM_COMPILER MATCHES easm21k)
+
+
+ LINK_DIRECTORIES("${_ADSP_FAMILY_DIR}/lib")
+
+ # vdk support
+ FIND_PROGRAM( ADSP_VDKGEN_EXECUTABLE vdkgen "${_ADSP_FAMILY_DIR}/vdk" )
+
+ MACRO(ADSP_GENERATE_VDK VDK_GENERATED_HEADER VDK_GENERATED_SOURCE VDK_KERNEL_SUPPORT_FILE)
+ ADD_CUSTOM_COMMAND(
+ OUTPUT ${VDK_GENERATED_HEADER} ${VDK_GENERATED_SOURCE}
+ COMMAND ${ADSP_VDKGEN_EXECUTABLE} ${VDK_KERNEL_SUPPORT_FILE} -proc ${ADSP_PROCESSOR} -si-revision ${ADSP_PROCESSOR_SILICIUM_REVISION} -MM
+ DEPENDS ${VDK_KERNEL_SUPPORT_FILE}
+ )
+ ENDMACRO(ADSP_GENERATE_VDK VDK_GENERATED_HEADER VDK_GENERATED_SOURCE VDK_KERNEL_SUPPORT_FILE)
+
+ # loader support
+ FIND_PROGRAM( ADSP_ELFLOADER_EXECUTABLE elfloader "${_ADSP_FAMILY_DIR}" )
+
+ # BOOT_MODE: prom, flash, spi, spislave, UART, TWI, FIFO
+ # FORMAT: hex, ASCII, binary, include
+ # WIDTH: 8, 16
+ MACRO(ADSP_CREATE_LOADER_FILE TARGET_NAME BOOT_MODE FORMAT WIDTH)
+ ADD_CUSTOM_COMMAND(
+ TARGET ${TARGET_NAME}
+ POST_BUILD
+ COMMAND ${ADSP_ELFLOADER_EXECUTABLE} ${EXECUTABLE_OUTPUT_PATH}/${TARGET_NAME}.dxe -proc ${ADSP_PROCESSOR} -si-revision ${ADSP_PROCESSOR_SILICIUM_REVISION} -b ${BOOT_MODE} -f ${FORMAT} -width ${WIDTH} -o ${EXECUTABLE_OUTPUT_PATH}/${TARGET_NAME}.ldr
+ COMMENT "Building the loader file"
+ )
+ ENDMACRO(ADSP_CREATE_LOADER_FILE TARGET_NAME BOOT_MODE FORMAT WIDTH)
+
+ MACRO(ADSP_CREATE_LOADER_FILE_INIT TARGET_NAME BOOT_MODE FORMAT WIDTH INITIALIZATION_FILE)
+ ADD_CUSTOM_COMMAND(
+ TARGET ${TARGET_NAME}
+ POST_BUILD
+ COMMAND ${ADSP_ELFLOADER_EXECUTABLE} ${EXECUTABLE_OUTPUT_PATH}/${TARGET_NAME}.dxe -proc ${ADSP_PROCESSOR} -si-revision ${ADSP_PROCESSOR_SILICIUM_REVISION} -b ${BOOT_MODE} -f ${FORMAT} -width ${WIDTH} -o ${EXECUTABLE_OUTPUT_PATH}/${TARGET_NAME}.ldr -init ${INITIALIZATION_FILE}
+ COMMENT "Building the loader file"
+ )
+ ENDMACRO(ADSP_CREATE_LOADER_FILE_INIT TARGET_NAME BOOT_MODE FORMAT WIDTH INITIALIZATION_FILE)
+
+ENDIF(NOT ADSP)
diff --git a/Modules/Platform/Generic-SDCC-C.cmake b/Modules/Platform/Generic-SDCC-C.cmake
new file mode 100644
index 000000000..ac81c3560
--- /dev/null
+++ b/Modules/Platform/Generic-SDCC-C.cmake
@@ -0,0 +1,54 @@
+
+# This file implements basic support for sdcc (http://sdcc.sourceforge.net/)
+# a free C compiler for 8 and 16 bit microcontrollers.
+# To use it either a toolchain file is required or cmake has to be run like this:
+# cmake -DCMAKE_C_COMPILER=sdcc -DCMAKE_SYSTEM_NAME=Generic <dir...>
+# Since sdcc doesn't support C++, C++ support should be disabled in the
+# CMakeLists.txt using the PROJECT() command:
+# PROJECT(my_project C)
+
+SET(CMAKE_STATIC_LIBRARY_PREFIX "")
+SET(CMAKE_STATIC_LIBRARY_SUFFIX ".lib")
+SET(CMAKE_SHARED_LIBRARY_PREFIX "") # lib
+SET(CMAKE_SHARED_LIBRARY_SUFFIX ".lib") # .so
+SET(CMAKE_IMPORT_LIBRARY_PREFIX )
+SET(CMAKE_IMPORT_LIBRARY_SUFFIX )
+SET(CMAKE_EXECUTABLE_SUFFIX ".ihx") # intel hex file
+SET(CMAKE_LINK_LIBRARY_SUFFIX ".lib")
+SET(CMAKE_DL_LIBS "")
+
+SET(CMAKE_C_OUTPUT_EXTENSION ".rel")
+
+# find sdcclib as CMAKE_AR
+# since cmake may already have searched for "ar", sdcclib has to
+# be searched with a different variable name (SDCCLIB_EXECUTABLE)
+# and must then be forced into the cache
+GET_FILENAME_COMPONENT(SDCC_LOCATION "${CMAKE_C_COMPILER}" PATH)
+FIND_PROGRAM(SDCCLIB_EXECUTABLE sdcclib PATHS "${SDCC_LOCATION}" NO_DEFAULT_PATH)
+FIND_PROGRAM(SDCCLIB_EXECUTABLE sdcclib)
+SET(CMAKE_AR "${SDCCLIB_EXECUTABLE}" CACHE FILEPATH "The sdcc librarian" FORCE)
+
+# CMAKE_C_FLAGS_INIT and CMAKE_EXE_LINKER_FLAGS_INIT should be set in a CMAKE_SYSTEM_PROCESSOR file
+IF(NOT DEFINED CMAKE_C_FLAGS_INIT)
+ SET(CMAKE_C_FLAGS_INIT "-mmcs51 --model-small")
+ENDIF(NOT DEFINED CMAKE_C_FLAGS_INIT)
+
+IF(NOT DEFINED CMAKE_EXE_LINKER_FLAGS_INIT)
+ SET (CMAKE_EXE_LINKER_FLAGS_INIT --model-small)
+ENDIF(NOT DEFINED CMAKE_EXE_LINKER_FLAGS_INIT)
+
+# compile a C file into an object file
+SET(CMAKE_C_COMPILE_OBJECT "<CMAKE_C_COMPILER> <DEFINES> <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>")
+
+# needs sdcc 2.7.0 + sddclib from cvs
+SET(CMAKE_C_CREATE_STATIC_LIBRARY
+ "\"${CMAKE_COMMAND}\" -E remove <TARGET>"
+ "<CMAKE_AR> -a <TARGET> <LINK_FLAGS> <OBJECTS> ")
+
+# not supported by sdcc
+SET(CMAKE_C_CREATE_SHARED_LIBRARY "")
+SET(CMAKE_C_CREATE_MODULE_LIBRARY "")
+
diff --git a/Modules/Platform/Generic.cmake b/Modules/Platform/Generic.cmake
new file mode 100644
index 000000000..a4e2ec6c1
--- /dev/null
+++ b/Modules/Platform/Generic.cmake
@@ -0,0 +1,17 @@
+# This is a platform definition file for platforms without
+# operating system, typically embedded platforms.
+# It is used when CMAKE_SYSTEM_NAME is set to "Generic"
+#
+# It is intentionally empty, since nothing is known
+# about the platform. So everything has to be specified
+# in the system/compiler files ${CMAKE_SYSTEM_NAME}-<compiler_basename>.cmake
+# and/or ${CMAKE_SYSTEM_NAME}-<compiler_basename>-${CMAKE_SYSTEM_PROCESSOR}.cmake
+
+# (embedded) targets without operating system usually don't support shared libraries
+SET_PROPERTY(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE)
+
+# To help the find_xxx() commands, set at least the following so CMAKE_FIND_ROOT_PATH
+# works at least for some simple cases:
+SET(CMAKE_SYSTEM_INCLUDE_PATH /include )
+SET(CMAKE_SYSTEM_LIBRARY_PATH /lib )
+SET(CMAKE_SYSTEM_PROGRAM_PATH /bin )
diff --git a/Modules/Platform/HP-UX-GNU-C.cmake b/Modules/Platform/HP-UX-GNU-C.cmake
new file mode 100644
index 000000000..5f9ac4200
--- /dev/null
+++ b/Modules/Platform/HP-UX-GNU-C.cmake
@@ -0,0 +1,2 @@
+include(Platform/HP-UX-GNU)
+__hpux_compiler_gnu(C)
diff --git a/Modules/Platform/HP-UX-GNU-CXX.cmake b/Modules/Platform/HP-UX-GNU-CXX.cmake
new file mode 100644
index 000000000..689bed088
--- /dev/null
+++ b/Modules/Platform/HP-UX-GNU-CXX.cmake
@@ -0,0 +1,2 @@
+include(Platform/HP-UX-GNU)
+__hpux_compiler_gnu(CXX)
diff --git a/Modules/Platform/HP-UX-GNU-Fortran.cmake b/Modules/Platform/HP-UX-GNU-Fortran.cmake
new file mode 100644
index 000000000..ee0181fe4
--- /dev/null
+++ b/Modules/Platform/HP-UX-GNU-Fortran.cmake
@@ -0,0 +1,2 @@
+include(Platform/HP-UX-GNU)
+__hpux_compiler_gnu(Fortran)
diff --git a/Modules/Platform/HP-UX-GNU.cmake b/Modules/Platform/HP-UX-GNU.cmake
new file mode 100644
index 000000000..eb909fe99
--- /dev/null
+++ b/Modules/Platform/HP-UX-GNU.cmake
@@ -0,0 +1,27 @@
+
+#=============================================================================
+# 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 module is shared by multiple languages; use include blocker.
+if(__HPUX_COMPILER_GNU)
+ return()
+endif()
+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_RUNTIME_${lang}_FLAG "-Wl,+b")
+ set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG_SEP ":")
+ set(CMAKE_SHARED_LIBRARY_SONAME_${lang}_FLAG "-Wl,+h")
+endmacro()
diff --git a/Modules/Platform/HP-UX-HP-ASM.cmake b/Modules/Platform/HP-UX-HP-ASM.cmake
new file mode 100644
index 000000000..05c69e41b
--- /dev/null
+++ b/Modules/Platform/HP-UX-HP-ASM.cmake
@@ -0,0 +1,2 @@
+include(Platform/HP-UX-HP)
+__hpux_compiler_hp(ASM)
diff --git a/Modules/Platform/HP-UX-HP-C.cmake b/Modules/Platform/HP-UX-HP-C.cmake
new file mode 100644
index 000000000..100093590
--- /dev/null
+++ b/Modules/Platform/HP-UX-HP-C.cmake
@@ -0,0 +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>")
diff --git a/Modules/Platform/HP-UX-HP-CXX.cmake b/Modules/Platform/HP-UX-HP-CXX.cmake
new file mode 100644
index 000000000..dfa1e4e45
--- /dev/null
+++ b/Modules/Platform/HP-UX-HP-CXX.cmake
@@ -0,0 +1,14 @@
+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_ASSEMBLY_SOURCE
+ "<CMAKE_CXX_COMPILER> <DEFINES> <FLAGS> -S <SOURCE>"
+ "mv `basename \"<SOURCE>\" | sed 's/\\.[^./]*$$//'`.s <ASSEMBLY_SOURCE>"
+ "rm -f `basename \"<SOURCE>\" | sed 's/\\.[^./]*$$//'`.o"
+ )
+
+set(CMAKE_CXX_FLAGS_DEBUG_INIT "-g")
+set(CMAKE_CXX_FLAGS_MINSIZEREL_INIT "+O3 -DNDEBUG")
+set(CMAKE_CXX_FLAGS_RELEASE_INIT "+O2 -DNDEBUG")
+set(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "-g")
diff --git a/Modules/Platform/HP-UX-HP-Fortran.cmake b/Modules/Platform/HP-UX-HP-Fortran.cmake
new file mode 100644
index 000000000..30acab807
--- /dev/null
+++ b/Modules/Platform/HP-UX-HP-Fortran.cmake
@@ -0,0 +1,2 @@
+include(Platform/HP-UX-HP)
+__hpux_compiler_hp(Fortran)
diff --git a/Modules/Platform/HP-UX-HP.cmake b/Modules/Platform/HP-UX-HP.cmake
new file mode 100644
index 000000000..871ea1323
--- /dev/null
+++ b/Modules/Platform/HP-UX-HP.cmake
@@ -0,0 +1,31 @@
+
+#=============================================================================
+# Copyright 2002-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.)
+
+# This module is shared by multiple languages; use include blocker.
+if(__HPUX_COMPILER_HP)
+ return()
+endif()
+set(__HPUX_COMPILER_HP 1)
+
+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_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 "")
+endmacro()
diff --git a/Modules/Platform/HP-UX.cmake b/Modules/Platform/HP-UX.cmake
new file mode 100644
index 000000000..ab3dc2266
--- /dev/null
+++ b/Modules/Platform/HP-UX.cmake
@@ -0,0 +1,50 @@
+SET(CMAKE_PLATFORM_REQUIRED_RUNTIME_PATH /usr/lib)
+
+SET(CMAKE_SHARED_LIBRARY_SUFFIX ".sl") # .so
+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
+# link line with -L flags.
+SET(CMAKE_SHARED_LIBRARY_LINK_C_WITH_RUNTIME_PATH 1)
+SET(CMAKE_LINK_DEPENDENT_LIBRARY_DIRS 1)
+
+# Shared libraries with no builtin soname may not be linked safely by
+# specifying the file path.
+SET(CMAKE_PLATFORM_USES_PATH_WHEN_NO_SONAME 1)
+
+# set flags for gcc support
+INCLUDE(Platform/UnixPaths)
+
+# Look in both 32-bit and 64-bit implict link directories, but tell
+# CMake not to pass the paths to the linker. The linker will find the
+# library for the proper architecture. In the future we should detect
+# which path will be used by the linker. Since the pointer type size
+# CMAKE_SIZEOF_VOID_P is not set until after this file executes, we
+# would need to append to CMAKE_SYSTEM_LIBRARY_PATH at a later point
+# (after CMakeTest(LANG)Compiler.cmake runs for at least one language).
+LIST(APPEND CMAKE_SYSTEM_LIBRARY_PATH /usr/lib/hpux32)
+LIST(APPEND CMAKE_SYSTEM_LIBRARY_PATH /usr/lib/hpux64)
+LIST(APPEND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES
+ /usr/lib/hpux32 /usr/lib/hpux64)
+
+# 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(type)
+FOREACH(type EXE)
+ SET(CMAKE_${type}_LINK_STATIC_C_FLAGS "-Wl,-a,archive")
+ SET(CMAKE_${type}_LINK_DYNAMIC_C_FLAGS "-Wl,-a,default")
+ENDFOREACH(type)
+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")
+ENDFOREACH(type)
+
diff --git a/Modules/Platform/Haiku.cmake b/Modules/Platform/Haiku.cmake
new file mode 100644
index 000000000..9dda3c528
--- /dev/null
+++ b/Modules/Platform/Haiku.cmake
@@ -0,0 +1,24 @@
+SET(BEOS 1)
+
+SET(CMAKE_DL_LIBS root be)
+SET(CMAKE_C_COMPILE_OPTIONS_PIC "-fPIC")
+SET(CMAKE_C_COMPILE_OPTIONS_PIE "-fPIE")
+SET(CMAKE_SHARED_LIBRARY_C_FLAGS "-fPIC")
+SET(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-nostart")
+SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "-Wl,-rpath,")
+SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP ":")
+SET(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "-Wl,-soname,")
+
+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)
+
+IF(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
+ SET(CMAKE_INSTALL_PREFIX "/boot/common" CACHE PATH
+ "Install path prefix, prepended onto install directories." FORCE)
+ENDIF(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
diff --git a/Modules/Platform/IRIX.cmake b/Modules/Platform/IRIX.cmake
new file mode 100644
index 000000000..fac941f3b
--- /dev/null
+++ b/Modules/Platform/IRIX.cmake
@@ -0,0 +1,45 @@
+SET(CMAKE_DL_LIBS "")
+SET(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-shared -rdata_shared")
+SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "-Wl,-rpath,") # -rpath
+SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP "") # : or empty
+IF(NOT CMAKE_COMPILER_IS_GNUCXX)
+ SET(CMAKE_CXX_CREATE_STATIC_LIBRARY
+ "<CMAKE_CXX_COMPILER> -ar -o <TARGET> <OBJECTS>")
+ SET (CMAKE_CXX_FLAGS_INIT "")
+ SET (CMAKE_CXX_FLAGS_DEBUG_INIT "-g")
+ SET (CMAKE_CXX_FLAGS_MINSIZEREL_INIT "-O3 -DNDEBUG")
+ SET (CMAKE_CXX_FLAGS_RELEASE_INIT "-O2 -DNDEBUG")
+ SET (CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "-O2")
+ SET (CMAKE_C_FLAGS_INIT "")
+ENDIF(NOT CMAKE_COMPILER_IS_GNUCXX)
+# set flags for gcc support
+INCLUDE(Platform/UnixPaths)
+
+IF(NOT CMAKE_COMPILER_IS_GNUCC)
+ 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>"
+ "mv `basename \"<SOURCE>\" | sed 's/\\.[^./]*$$//'`.s <ASSEMBLY_SOURCE>"
+ )
+ENDIF(NOT CMAKE_COMPILER_IS_GNUCC)
+
+IF(NOT CMAKE_COMPILER_IS_GNUCXX)
+ 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>"
+ "mv `basename \"<SOURCE>\" | sed 's/\\.[^./]*$$//'`.s <ASSEMBLY_SOURCE>"
+ )
+ENDIF(NOT CMAKE_COMPILER_IS_GNUCXX)
+
+# 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
+# versions of the libraries.
+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(type)
+
+# The IRIX linker needs to find transitive shared library dependencies
+# in the -L path.
+SET(CMAKE_LINK_DEPENDENT_LIBRARY_DIRS 1)
diff --git a/Modules/Platform/IRIX64.cmake b/Modules/Platform/IRIX64.cmake
new file mode 100644
index 000000000..b60a7f297
--- /dev/null
+++ b/Modules/Platform/IRIX64.cmake
@@ -0,0 +1,73 @@
+SET(CMAKE_DL_LIBS "")
+SET(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-shared -rdata_shared")
+SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "-Wl,-rpath,") # -rpath
+SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP "") # : or empty
+SET(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "-Wl,-soname,")
+IF(NOT CMAKE_COMPILER_IS_GNUCC)
+ # Set default flags init.
+ SET(CMAKE_C_FLAGS_INIT "")
+ SET(CMAKE_CXX_FLAGS_INIT "")
+ SET(CMAKE_Fortran_FLAGS_INIT "")
+ SET(CMAKE_EXE_LINKER_FLAGS_INIT "")
+ SET(CMAKE_SHARED_LINKER_FLAGS_INIT "")
+ SET(CMAKE_MODULE_LINKER_FLAGS_INIT "")
+
+ # If no -o32, -n32, or -64 flag is given, set a reasonable default.
+ IF("$ENV{CFLAGS} $ENV{CXXFLAGS} $ENV{LDFLAGS}" MATCHES "-([no]32|64)")
+ ELSE("$ENV{CFLAGS} $ENV{CXXFLAGS} $ENV{LDFLAGS}" MATCHES "-([no]32|64)")
+ # Check if this is a 64-bit CMake.
+ IF(CMAKE_FILE_SELF MATCHES "^CMAKE_FILE_SELF$")
+ EXEC_PROGRAM(file ARGS ${CMAKE_COMMAND} OUTPUT_VARIABLE CMAKE_FILE_SELF)
+ SET(CMAKE_FILE_SELF "${CMAKE_FILE_SELF}" CACHE INTERNAL
+ "Output of file command on ${CMAKE_COMMAND}.")
+ ENDIF(CMAKE_FILE_SELF MATCHES "^CMAKE_FILE_SELF$")
+
+ # Set initial flags to match cmake executable.
+ IF(CMAKE_FILE_SELF MATCHES " 64-bit ")
+ SET(CMAKE_C_FLAGS_INIT "-64")
+ SET(CMAKE_CXX_FLAGS_INIT "-64")
+ SET(CMAKE_Fortran_FLAGS_INIT "-64")
+ SET(CMAKE_EXE_LINKER_FLAGS_INIT "-64")
+ SET(CMAKE_SHARED_LINKER_FLAGS_INIT "-64")
+ SET(CMAKE_MODULE_LINKER_FLAGS_INIT "-64")
+ ENDIF(CMAKE_FILE_SELF MATCHES " 64-bit ")
+ ENDIF("$ENV{CFLAGS} $ENV{CXXFLAGS} $ENV{LDFLAGS}" MATCHES "-([no]32|64)")
+
+ # Set remaining defaults.
+ SET(CMAKE_CXX_CREATE_STATIC_LIBRARY
+ "<CMAKE_CXX_COMPILER> -ar -o <TARGET> <OBJECTS>")
+ SET (CMAKE_CXX_FLAGS_DEBUG_INIT "-g")
+ SET (CMAKE_CXX_FLAGS_MINSIZEREL_INIT "-O3 -DNDEBUG")
+ SET (CMAKE_CXX_FLAGS_RELEASE_INIT "-O2 -DNDEBUG")
+ SET (CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "-O2")
+ENDIF(NOT CMAKE_COMPILER_IS_GNUCC)
+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_ASSEMBLY_SOURCE
+ "<CMAKE_C_COMPILER> <DEFINES> <FLAGS> -S <SOURCE>"
+ "mv `basename \"<SOURCE>\" | sed 's/\\.[^./]*$$//'`.s <ASSEMBLY_SOURCE>"
+ )
+ENDIF(NOT CMAKE_COMPILER_IS_GNUCC)
+
+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_ASSEMBLY_SOURCE
+ "<CMAKE_CXX_COMPILER> <DEFINES> <FLAGS> -S <SOURCE>"
+ "mv `basename \"<SOURCE>\" | sed 's/\\.[^./]*$$//'`.s <ASSEMBLY_SOURCE>"
+ )
+ENDIF(NOT CMAKE_COMPILER_IS_GNUCXX)
+
+# 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
+# versions of the libraries.
+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(type)
+
+# The IRIX linker needs to find transitive shared library dependencies
+# in the -L path.
+SET(CMAKE_LINK_DEPENDENT_LIBRARY_DIRS 1)
diff --git a/Modules/Platform/Linux-Absoft-Fortran.cmake b/Modules/Platform/Linux-Absoft-Fortran.cmake
new file mode 100644
index 000000000..beb41a3b8
--- /dev/null
+++ b/Modules/Platform/Linux-Absoft-Fortran.cmake
@@ -0,0 +1 @@
+set(CMAKE_Fortran_VERBOSE_FLAG "-X -v") # Runs gcc under the hood.
diff --git a/Modules/Platform/Linux-Clang-C.cmake b/Modules/Platform/Linux-Clang-C.cmake
new file mode 100644
index 000000000..dbf89564a
--- /dev/null
+++ b/Modules/Platform/Linux-Clang-C.cmake
@@ -0,0 +1 @@
+INCLUDE(Platform/Linux-GNU-C)
diff --git a/Modules/Platform/Linux-Clang-CXX.cmake b/Modules/Platform/Linux-Clang-CXX.cmake
new file mode 100644
index 000000000..8fe251c4d
--- /dev/null
+++ b/Modules/Platform/Linux-Clang-CXX.cmake
@@ -0,0 +1 @@
+INCLUDE(Platform/Linux-GNU-CXX)
diff --git a/Modules/Platform/Linux-GNU-C.cmake b/Modules/Platform/Linux-GNU-C.cmake
new file mode 100644
index 000000000..3ab142f13
--- /dev/null
+++ b/Modules/Platform/Linux-GNU-C.cmake
@@ -0,0 +1,2 @@
+INCLUDE(Platform/Linux-GNU)
+__linux_compiler_gnu(C)
diff --git a/Modules/Platform/Linux-GNU-CXX.cmake b/Modules/Platform/Linux-GNU-CXX.cmake
new file mode 100644
index 000000000..9e4f904f2
--- /dev/null
+++ b/Modules/Platform/Linux-GNU-CXX.cmake
@@ -0,0 +1,2 @@
+INCLUDE(Platform/Linux-GNU)
+__linux_compiler_gnu(CXX)
diff --git a/Modules/Platform/Linux-GNU-Fortran.cmake b/Modules/Platform/Linux-GNU-Fortran.cmake
new file mode 100644
index 000000000..e364c872a
--- /dev/null
+++ b/Modules/Platform/Linux-GNU-Fortran.cmake
@@ -0,0 +1,2 @@
+INCLUDE(Platform/Linux-GNU)
+__linux_compiler_gnu(Fortran)
diff --git a/Modules/Platform/Linux-GNU.cmake b/Modules/Platform/Linux-GNU.cmake
new file mode 100644
index 000000000..0e254c6ea
--- /dev/null
+++ b/Modules/Platform/Linux-GNU.cmake
@@ -0,0 +1,25 @@
+
+#=============================================================================
+# Copyright 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.)
+
+# This module is shared by multiple languages; use include blocker.
+if(__LINUX_COMPILER_GNU)
+ return()
+endif()
+set(__LINUX_COMPILER_GNU 1)
+
+macro(__linux_compiler_gnu lang)
+ # We pass this for historical reasons. Projects may have
+ # executables that use dlopen but do not set ENABLE_EXPORTS.
+ set(CMAKE_SHARED_LIBRARY_LINK_${lang}_FLAGS "-rdynamic")
+endmacro()
diff --git a/Modules/Platform/Linux-Intel-C.cmake b/Modules/Platform/Linux-Intel-C.cmake
new file mode 100644
index 000000000..c909e68fc
--- /dev/null
+++ b/Modules/Platform/Linux-Intel-C.cmake
@@ -0,0 +1,2 @@
+INCLUDE(Platform/Linux-Intel)
+__linux_compiler_intel(C)
diff --git a/Modules/Platform/Linux-Intel-CXX.cmake b/Modules/Platform/Linux-Intel-CXX.cmake
new file mode 100644
index 000000000..0b7daf475
--- /dev/null
+++ b/Modules/Platform/Linux-Intel-CXX.cmake
@@ -0,0 +1,2 @@
+INCLUDE(Platform/Linux-Intel)
+__linux_compiler_intel(CXX)
diff --git a/Modules/Platform/Linux-Intel-Fortran.cmake b/Modules/Platform/Linux-Intel-Fortran.cmake
new file mode 100644
index 000000000..342b5c2fa
--- /dev/null
+++ b/Modules/Platform/Linux-Intel-Fortran.cmake
@@ -0,0 +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")
diff --git a/Modules/Platform/Linux-Intel.cmake b/Modules/Platform/Linux-Intel.cmake
new file mode 100644
index 000000000..47bf24659
--- /dev/null
+++ b/Modules/Platform/Linux-Intel.cmake
@@ -0,0 +1,50 @@
+
+#=============================================================================
+# 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 module is shared by multiple languages; use include blocker.
+if(__LINUX_COMPILER_INTEL)
+ return()
+endif()
+set(__LINUX_COMPILER_INTEL 1)
+
+if(NOT XIAR)
+ set(_intel_xiar_hints)
+ foreach(lang C CXX Fortran)
+ if(IS_ABSOLUTE "${CMAKE_${lang}_COMPILER}")
+ get_filename_component(_hint "${CMAKE_${lang}_COMPILER}" PATH)
+ list(APPEND _intel_xiar_hints ${_hint})
+ endif()
+ endforeach()
+ find_program(XIAR NAMES xiar HINTS ${_intel_xiar_hints})
+ mark_as_advanced(XIAR)
+endif(NOT XIAR)
+
+macro(__linux_compiler_intel lang)
+ set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "-fPIC")
+ set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-fPIE")
+ set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "-fPIC")
+ set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-shared")
+
+ # We pass this for historical reasons. Projects may have
+ # executables that use dlopen but do not set ENABLE_EXPORTS.
+ set(CMAKE_SHARED_LIBRARY_LINK_${lang}_FLAGS "-rdynamic")
+
+ if(XIAR)
+ # INTERPROCEDURAL_OPTIMIZATION
+ set(CMAKE_${lang}_COMPILE_OPTIONS_IPO -ipo)
+ set(CMAKE_${lang}_CREATE_STATIC_LIBRARY_IPO
+ "${XIAR} cr <TARGET> <LINK_FLAGS> <OBJECTS> "
+ "${XIAR} -s <TARGET> ")
+ endif()
+endmacro()
diff --git a/Modules/Platform/Linux-NAG-Fortran.cmake b/Modules/Platform/Linux-NAG-Fortran.cmake
new file mode 100644
index 000000000..353bae6dd
--- /dev/null
+++ b/Modules/Platform/Linux-NAG-Fortran.cmake
@@ -0,0 +1,10 @@
+set(CMAKE_Fortran_VERBOSE_FLAG "-Wl,-v") # Runs gcc under the hood.
+
+# Need one "-Wl," level to send flag through to gcc.
+# Use "-Xlinker" to get through gcc to real linker.
+set(CMAKE_SHARED_LIBRARY_CREATE_Fortran_FLAGS "-Wl,-shared")
+set(CMAKE_SHARED_LIBRARY_RUNTIME_Fortran_FLAG "-Wl,-Xlinker,-rpath,-Xlinker,")
+set(CMAKE_SHARED_LIBRARY_RUNTIME_Fortran_FLAG_SEP ":")
+set(CMAKE_SHARED_LIBRARY_RPATH_LINK_Fortran_FLAG "-Wl,-Xlinker,-rpath-link,-Xlinker,")
+set(CMAKE_SHARED_LIBRARY_SONAME_Fortran_FLAG "-Wl,-Xlinker,-soname,-Xlinker,")
+set(CMAKE_SHARED_LIBRARY_LINK_Fortran_FLAGS "-Wl,-rdynamic")
diff --git a/Modules/Platform/Linux-PGI-C.cmake b/Modules/Platform/Linux-PGI-C.cmake
new file mode 100644
index 000000000..edf4f3f0e
--- /dev/null
+++ b/Modules/Platform/Linux-PGI-C.cmake
@@ -0,0 +1,2 @@
+include(Platform/Linux-PGI)
+__linux_compiler_pgi(C)
diff --git a/Modules/Platform/Linux-PGI-CXX.cmake b/Modules/Platform/Linux-PGI-CXX.cmake
new file mode 100644
index 000000000..d425f886e
--- /dev/null
+++ b/Modules/Platform/Linux-PGI-CXX.cmake
@@ -0,0 +1,2 @@
+include(Platform/Linux-PGI)
+__linux_compiler_pgi(CXX)
diff --git a/Modules/Platform/Linux-PGI-Fortran.cmake b/Modules/Platform/Linux-PGI-Fortran.cmake
new file mode 100644
index 000000000..e8731a384
--- /dev/null
+++ b/Modules/Platform/Linux-PGI-Fortran.cmake
@@ -0,0 +1,2 @@
+include(Platform/Linux-PGI)
+__linux_compiler_pgi(Fortran)
diff --git a/Modules/Platform/Linux-PGI.cmake b/Modules/Platform/Linux-PGI.cmake
new file mode 100644
index 000000000..3cbb35c72
--- /dev/null
+++ b/Modules/Platform/Linux-PGI.cmake
@@ -0,0 +1,27 @@
+
+#=============================================================================
+# 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 module is shared by multiple languages; use include blocker.
+if(__LINUX_COMPILER_PGI)
+ return()
+endif()
+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_SHARED_LIBRARY_${lang}_FLAGS "-fPIC")
+ set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-shared")
+endmacro()
diff --git a/Modules/Platform/Linux-PathScale-C.cmake b/Modules/Platform/Linux-PathScale-C.cmake
new file mode 100644
index 000000000..009f398fe
--- /dev/null
+++ b/Modules/Platform/Linux-PathScale-C.cmake
@@ -0,0 +1,2 @@
+include(Platform/Linux-PathScale)
+__linux_compiler_pathscale(C)
diff --git a/Modules/Platform/Linux-PathScale-CXX.cmake b/Modules/Platform/Linux-PathScale-CXX.cmake
new file mode 100644
index 000000000..b6a5771aa
--- /dev/null
+++ b/Modules/Platform/Linux-PathScale-CXX.cmake
@@ -0,0 +1,2 @@
+include(Platform/Linux-PathScale)
+__linux_compiler_pathscale(CXX)
diff --git a/Modules/Platform/Linux-PathScale-Fortran.cmake b/Modules/Platform/Linux-PathScale-Fortran.cmake
new file mode 100644
index 000000000..5662d3d88
--- /dev/null
+++ b/Modules/Platform/Linux-PathScale-Fortran.cmake
@@ -0,0 +1,2 @@
+include(Platform/Linux-PathScale)
+__linux_compiler_pathscale(Fortran)
diff --git a/Modules/Platform/Linux-PathScale.cmake b/Modules/Platform/Linux-PathScale.cmake
new file mode 100644
index 000000000..d230ab225
--- /dev/null
+++ b/Modules/Platform/Linux-PathScale.cmake
@@ -0,0 +1,27 @@
+
+#=============================================================================
+# Copyright 2002-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.)
+
+# This module is shared by multiple languages; use include blocker.
+if(__LINUX_COMPILER_PATHSCALE)
+ return()
+endif()
+set(__LINUX_COMPILER_PATHSCALE 1)
+
+macro(__linux_compiler_pathscale lang)
+ # Shared library compile and link flags.
+ set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "-fPIC")
+ set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-fPIE")
+ set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "-fPIC")
+ set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-shared")
+endmacro()
diff --git a/Modules/Platform/Linux-SunPro-CXX.cmake b/Modules/Platform/Linux-SunPro-CXX.cmake
new file mode 100644
index 000000000..8ee96586d
--- /dev/null
+++ b/Modules/Platform/Linux-SunPro-CXX.cmake
@@ -0,0 +1,9 @@
+# Sun C++ 5.9 does not support -Wl, but Sun C++ 5.11 does not work without it.
+# Query the compiler flags to detect whether to use -Wl.
+execute_process(COMMAND ${CMAKE_CXX_COMPILER} -flags OUTPUT_VARIABLE _cxx_flags ERROR_VARIABLE _cxx_error)
+if("${_cxx_flags}" MATCHES "\n-W[^\n]*component")
+ set(CMAKE_SHARED_LIBRARY_RPATH_LINK_CXX_FLAG "-Wl,-rpath-link,")
+else()
+ set(CMAKE_SHARED_LIBRARY_RPATH_LINK_CXX_FLAG "-rpath-link ")
+endif()
+SET(CMAKE_EXE_EXPORTS_CXX_FLAG "--export-dynamic")
diff --git a/Modules/Platform/Linux-TinyCC-C.cmake b/Modules/Platform/Linux-TinyCC-C.cmake
new file mode 100644
index 000000000..b753268ea
--- /dev/null
+++ b/Modules/Platform/Linux-TinyCC-C.cmake
@@ -0,0 +1,4 @@
+SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "")
+SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP "")
+SET(CMAKE_SHARED_LIBRARY_RPATH_LINK_C_FLAG "")
+SET(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "-soname ")
diff --git a/Modules/Platform/Linux-VisualAge-C.cmake b/Modules/Platform/Linux-VisualAge-C.cmake
new file mode 100644
index 000000000..0622b63c3
--- /dev/null
+++ b/Modules/Platform/Linux-VisualAge-C.cmake
@@ -0,0 +1 @@
+include(Platform/Linux-XL-C)
diff --git a/Modules/Platform/Linux-VisualAge-CXX.cmake b/Modules/Platform/Linux-VisualAge-CXX.cmake
new file mode 100644
index 000000000..b878ba02c
--- /dev/null
+++ b/Modules/Platform/Linux-VisualAge-CXX.cmake
@@ -0,0 +1 @@
+include(Platform/Linux-XL-CXX)
diff --git a/Modules/Platform/Linux-VisualAge-Fortran.cmake b/Modules/Platform/Linux-VisualAge-Fortran.cmake
new file mode 100644
index 000000000..1939a8a2f
--- /dev/null
+++ b/Modules/Platform/Linux-VisualAge-Fortran.cmake
@@ -0,0 +1 @@
+include(Platform/Linux-XL-Fortran)
diff --git a/Modules/Platform/Linux-XL-C.cmake b/Modules/Platform/Linux-XL-C.cmake
new file mode 100644
index 000000000..b1b07f617
--- /dev/null
+++ b/Modules/Platform/Linux-XL-C.cmake
@@ -0,0 +1 @@
+SET(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-qmkshrobj")
diff --git a/Modules/Platform/Linux-XL-CXX.cmake b/Modules/Platform/Linux-XL-CXX.cmake
new file mode 100644
index 000000000..071a975ed
--- /dev/null
+++ b/Modules/Platform/Linux-XL-CXX.cmake
@@ -0,0 +1 @@
+SET(CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS "-qmkshrobj")
diff --git a/Modules/Platform/Linux-XL-Fortran.cmake b/Modules/Platform/Linux-XL-Fortran.cmake
new file mode 100644
index 000000000..5da574e2e
--- /dev/null
+++ b/Modules/Platform/Linux-XL-Fortran.cmake
@@ -0,0 +1 @@
+SET(CMAKE_SHARED_LIBRARY_CREATE_Fortran_FLAGS "-qmkshrobj")
diff --git a/Modules/Platform/Linux-como.cmake b/Modules/Platform/Linux-como.cmake
new file mode 100644
index 000000000..7ea732082
--- /dev/null
+++ b/Modules/Platform/Linux-como.cmake
@@ -0,0 +1,17 @@
+# create a shared C++ library
+SET(CMAKE_CXX_CREATE_SHARED_LIBRARY
+ "<CMAKE_CXX_COMPILER> --prelink_objects <OBJECTS>"
+ "<CMAKE_CXX_COMPILER> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <LINK_FLAGS> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>")
+
+# create a C++ static library
+SET(CMAKE_CXX_CREATE_STATIC_LIBRARY
+ "<CMAKE_CXX_COMPILER> --prelink_objects <OBJECTS>"
+ "<CMAKE_AR> cr <TARGET> <LINK_FLAGS> <OBJECTS> "
+ "<CMAKE_RANLIB> <TARGET> ")
+
+SET(CMAKE_CXX_LINK_EXECUTABLE
+ "<CMAKE_CXX_COMPILER> --prelink_objects <OBJECTS>"
+ "<CMAKE_CXX_COMPILER> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
+
+SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "")
+SET(CMAKE_SHARED_LIBRARY_C_FLAGS "")
diff --git a/Modules/Platform/Linux.cmake b/Modules/Platform/Linux.cmake
new file mode 100644
index 000000000..38f469b33
--- /dev/null
+++ b/Modules/Platform/Linux.cmake
@@ -0,0 +1,57 @@
+SET(CMAKE_DL_LIBS "dl")
+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.
+SET(CMAKE_PLATFORM_USES_PATH_WHEN_NO_SONAME 1)
+
+# 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
+# versions of the libraries.
+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(type)
+
+# Debian policy requires that shared libraries be installed without
+# executable permission. Fedora policy requires that shared libraries
+# be installed with the executable permission. Since the native tools
+# create shared libraries with execute permission in the first place a
+# reasonable policy seems to be to install with execute permission by
+# default. In order to support debian packages we provide an option
+# here. The option default is based on the current distribution, but
+# packagers can set it explicitly on the command line.
+IF(DEFINED CMAKE_INSTALL_SO_NO_EXE)
+ # Store the decision variable in the cache. This preserves any
+ # setting the user provides on the command line.
+ SET(CMAKE_INSTALL_SO_NO_EXE "${CMAKE_INSTALL_SO_NO_EXE}" CACHE INTERNAL
+ "Install .so files without execute permission.")
+ELSE(DEFINED CMAKE_INSTALL_SO_NO_EXE)
+ # Store the decision variable as an internal cache entry to avoid
+ # checking the platform every time. This option is advanced enough
+ # that only package maintainers should need to adjust it. They are
+ # capable of providing a setting on the command line.
+ IF(EXISTS "/etc/debian_version")
+ SET(CMAKE_INSTALL_SO_NO_EXE 1 CACHE INTERNAL
+ "Install .so files without execute permission.")
+ ELSE(EXISTS "/etc/debian_version")
+ SET(CMAKE_INSTALL_SO_NO_EXE 0 CACHE INTERNAL
+ "Install .so files without execute permission.")
+ ENDIF(EXISTS "/etc/debian_version")
+ENDIF(DEFINED CMAKE_INSTALL_SO_NO_EXE)
+
+# Match multiarch library directory names.
+SET(CMAKE_LIBRARY_ARCHITECTURE_REGEX "[a-z0-9_]+(-[a-z0-9_]+)?-linux-gnu[a-z0-9_]*")
+
+INCLUDE(Platform/UnixPaths)
+
+# Debian has lib64 paths only for compatibility so they should not be
+# searched.
+IF(EXISTS "/etc/debian_version")
+ SET_PROPERTY(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS FALSE)
+ENDIF(EXISTS "/etc/debian_version")
diff --git a/Modules/Platform/MP-RAS.cmake b/Modules/Platform/MP-RAS.cmake
new file mode 100644
index 000000000..ff22a4fda
--- /dev/null
+++ b/Modules/Platform/MP-RAS.cmake
@@ -0,0 +1,14 @@
+IF(CMAKE_SYSTEM MATCHES "MP-RAS-02*.")
+ SET(CMAKE_C_COMPILE_OPTIONS_PIC -K PIC)
+ SET(CMAKE_C_COMPILE_OPTIONS_PIE -K PIE)
+ SET(CMAKE_SHARED_LIBRARY_C_FLAGS "-K PIC")
+ELSE(CMAKE_SYSTEM MATCHES "MP-RAS-02*.")
+ SET(CMAKE_C_COMPILE_OPTIONS_PIC -K PIC)
+ SET(CMAKE_C_COMPILE_OPTIONS_PIE -K PIE)
+ SET(CMAKE_SHARED_LIBRARY_C_FLAGS "-K PIC")
+ SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "-Wl,-Bexport")
+ENDIF(CMAKE_SYSTEM MATCHES "MP-RAS-02*.")
+
+INCLUDE(Platform/UnixPaths)
+
+
diff --git a/Modules/Platform/NetBSD.cmake b/Modules/Platform/NetBSD.cmake
new file mode 100644
index 000000000..e1b66b84c
--- /dev/null
+++ b/Modules/Platform/NetBSD.cmake
@@ -0,0 +1,15 @@
+IF(EXISTS /usr/include/dlfcn.h)
+ SET(CMAKE_DL_LIBS "")
+ SET(CMAKE_C_COMPILE_OPTIONS_PIC "-fPIC")
+ SET(CMAKE_C_COMPILE_OPTIONS_PIE "-fPIE")
+ SET(CMAKE_SHARED_LIBRARY_C_FLAGS "-fPIC") # -pic
+ SET(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-shared") # -shared
+ SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") # +s, flag for exe link to use shared lib
+ SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "-Wl,-rpath,") # -rpath
+ SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP ":") # : or empty
+ 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")
+ENDIF(EXISTS /usr/include/dlfcn.h)
+
+INCLUDE(Platform/UnixPaths)
diff --git a/Modules/Platform/OSF1.cmake b/Modules/Platform/OSF1.cmake
new file mode 100644
index 000000000..49a30e971
--- /dev/null
+++ b/Modules/Platform/OSF1.cmake
@@ -0,0 +1,47 @@
+SET(CMAKE_DL_LIBS "")
+
+IF(CMAKE_SYSTEM MATCHES "OSF1-1.[012]")
+ENDIF(CMAKE_SYSTEM MATCHES "OSF1-1.[012]")
+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")
+ SET(CMAKE_SHARED_LIBRARY_C_FLAGS "-fpic") # -pic
+ SET(CMAKE_SHARED_LIBRARY_CXX_FLAGS "-fpic") # -pic
+ENDIF(CMAKE_SYSTEM MATCHES "OSF1-1.*")
+
+
+
+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,")
+ ELSE(CMAKE_COMPILER_IS_GNUCXX)
+ SET(CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG "-rpath ")
+ ENDIF(CMAKE_COMPILER_IS_GNUCXX)
+ IF(CMAKE_COMPILER_IS_GNUCC)
+ SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "-Wl,-rpath,")
+ ELSE(CMAKE_COMPILER_IS_GNUCC)
+ SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "-rpath ")
+ ENDIF(CMAKE_COMPILER_IS_GNUCC)
+ SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP ":")
+ENDIF(CMAKE_SYSTEM MATCHES "OSF1-V.*")
+
+SET(CMAKE_MAKE_INCLUDE_FROM_ROOT 1) # include $(CMAKE_BINARY_DIR)/...
+
+IF(CMAKE_COMPILER_IS_GNUCXX)
+ # include the gcc flags
+ELSE (CMAKE_COMPILER_IS_GNUCXX)
+ # use default OSF compiler flags
+ SET (CMAKE_C_FLAGS_INIT "")
+ SET (CMAKE_C_FLAGS_DEBUG_INIT "-g")
+ SET (CMAKE_C_FLAGS_MINSIZEREL_INIT "-O2 -DNDEBUG")
+ SET (CMAKE_C_FLAGS_RELEASE_INIT "-O2 -DNDEBUG")
+ SET (CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "-O2")
+ SET (CMAKE_CXX_FLAGS_INIT "")
+ SET (CMAKE_CXX_FLAGS_DEBUG_INIT "-g")
+ SET (CMAKE_CXX_FLAGS_MINSIZEREL_INIT "-O2 -DNDEBUG")
+ SET (CMAKE_CXX_FLAGS_RELEASE_INIT "-O2 -DNDEBUG")
+ SET (CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "-O2")
+ENDIF(CMAKE_COMPILER_IS_GNUCXX)
+INCLUDE(Platform/UnixPaths)
diff --git a/Modules/Platform/OpenBSD.cmake b/Modules/Platform/OpenBSD.cmake
new file mode 100644
index 000000000..b4ed66fb0
--- /dev/null
+++ b/Modules/Platform/OpenBSD.cmake
@@ -0,0 +1,18 @@
+INCLUDE(Platform/NetBSD)
+
+# On OpenBSD, the compile time linker does not share it's configuration with
+# the runtime linker. This will extract the library search paths from the
+# system's ld.so.hints file which will allow CMake to set the appropriate
+# -rpath-link flags
+IF(NOT CMAKE_PLATFORM_RUNTIME_PATH)
+ EXECUTE_PROCESS(COMMAND /sbin/ldconfig -r
+ OUTPUT_VARIABLE LDCONFIG_HINTS
+ ERROR_QUIET)
+ STRING(REGEX REPLACE ".*search\\ directories:\\ ([^\n]*).*" "\\1"
+ LDCONFIG_HINTS "${LDCONFIG_HINTS}")
+ STRING(REGEX REPLACE ":" ";"
+ CMAKE_PLATFORM_RUNTIME_PATH
+ "${LDCONFIG_HINTS}")
+ENDIF()
+
+SET_PROPERTY(GLOBAL PROPERTY FIND_LIBRARY_USE_OPENBSD_VERSIONING 1)
diff --git a/Modules/Platform/OpenVMS.cmake b/Modules/Platform/OpenVMS.cmake
new file mode 100644
index 000000000..c52effab6
--- /dev/null
+++ b/Modules/Platform/OpenVMS.cmake
@@ -0,0 +1,8 @@
+INCLUDE(Platform/UnixPaths)
+
+SET(CMAKE_C_CREATE_STATIC_LIBRARY
+ "<CMAKE_AR> cr <TARGET> <LINK_FLAGS> <OBJECTS>"
+ "<CMAKE_RANLIB> <TARGET>"
+ )
+SET(CMAKE_CXX_CREATE_STATIC_LIBRARY ${CMAKE_C_CREATE_STATIC_LIBRARY})
+SET(CMAKE_EXECUTABLE_SUFFIX ".exe") # .exe
diff --git a/Modules/Platform/QNX.cmake b/Modules/Platform/QNX.cmake
new file mode 100644
index 000000000..8cdbe02c1
--- /dev/null
+++ b/Modules/Platform/QNX.cmake
@@ -0,0 +1,33 @@
+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)
+
+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.
+SET(CMAKE_PLATFORM_USES_PATH_WHEN_NO_SONAME 1)
+
+# 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
+# versions of the libraries.
+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(type)
+# 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/RISCos.cmake b/Modules/Platform/RISCos.cmake
new file mode 100644
index 000000000..3b2a092bf
--- /dev/null
+++ b/Modules/Platform/RISCos.cmake
@@ -0,0 +1,6 @@
+SET(CMAKE_SHARED_LIBRARY_C_FLAGS "-G 0")
+SET(CMAKE_SHARED_LIBRARY_SUFFIX "..o")
+SET(CMAKE_DL_LIBS "")
+SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "-Wl,-D,08000000")
+
+INCLUDE(Platform/UnixPaths)
diff --git a/Modules/Platform/SCO_SV.cmake b/Modules/Platform/SCO_SV.cmake
new file mode 100644
index 000000000..cbdcb7dae
--- /dev/null
+++ b/Modules/Platform/SCO_SV.cmake
@@ -0,0 +1,2 @@
+SET(CMAKE_DL_LIBS "")
+INCLUDE(Platform/UnixPaths)
diff --git a/Modules/Platform/SINIX.cmake b/Modules/Platform/SINIX.cmake
new file mode 100644
index 000000000..e0809f8e3
--- /dev/null
+++ b/Modules/Platform/SINIX.cmake
@@ -0,0 +1,4 @@
+SET(CMAKE_C_COMPILE_OPTIONS_PIC -K PIC)
+SET(CMAKE_C_COMPILE_OPTIONS_PIE "")
+SET(CMAKE_SHARED_LIBRARY_C_FLAGS "-K PIC")
+INCLUDE(Platform/UnixPaths)
diff --git a/Modules/Platform/SunOS-GNU-C.cmake b/Modules/Platform/SunOS-GNU-C.cmake
new file mode 100644
index 000000000..6a96c00ee
--- /dev/null
+++ b/Modules/Platform/SunOS-GNU-C.cmake
@@ -0,0 +1,2 @@
+include(Platform/SunOS-GNU)
+__sunos_compiler_gnu(C)
diff --git a/Modules/Platform/SunOS-GNU-CXX.cmake b/Modules/Platform/SunOS-GNU-CXX.cmake
new file mode 100644
index 000000000..6b9f6fa86
--- /dev/null
+++ b/Modules/Platform/SunOS-GNU-CXX.cmake
@@ -0,0 +1,2 @@
+include(Platform/SunOS-GNU)
+__sunos_compiler_gnu(CXX)
diff --git a/Modules/Platform/SunOS-GNU-Fortran.cmake b/Modules/Platform/SunOS-GNU-Fortran.cmake
new file mode 100644
index 000000000..c6b188836
--- /dev/null
+++ b/Modules/Platform/SunOS-GNU-Fortran.cmake
@@ -0,0 +1,2 @@
+include(Platform/SunOS-GNU)
+__sunos_compiler_gnu(Fortran)
diff --git a/Modules/Platform/SunOS-GNU.cmake b/Modules/Platform/SunOS-GNU.cmake
new file mode 100644
index 000000000..7169056de
--- /dev/null
+++ b/Modules/Platform/SunOS-GNU.cmake
@@ -0,0 +1,34 @@
+
+#=============================================================================
+# 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 module is shared by multiple languages; use include blocker.
+if(__SUNOS_COMPILER_GNU)
+ return()
+endif()
+set(__SUNOS_COMPILER_GNU 1)
+
+macro(__sunos_compiler_gnu lang)
+ set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG "-Wl,-R")
+ set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG_SEP ":")
+ set(CMAKE_SHARED_LIBRARY_SONAME_${lang}_FLAG "-Wl,-h")
+
+ # 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
+ # versions of the libraries.
+ foreach(type SHARED_LIBRARY SHARED_MODULE EXE)
+ set(CMAKE_${type}_LINK_STATIC_${lang}_FLAGS "-Wl,-Bstatic")
+ set(CMAKE_${type}_LINK_DYNAMIC_${lang}_FLAGS "-Wl,-Bdynamic")
+ endforeach()
+endmacro()
diff --git a/Modules/Platform/SunOS.cmake b/Modules/Platform/SunOS.cmake
new file mode 100644
index 000000000..de287aa70
--- /dev/null
+++ b/Modules/Platform/SunOS.cmake
@@ -0,0 +1,32 @@
+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")
+ SET(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-shared -Wl,-r")
+ SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "-Wl,-R")
+ SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP ":")
+ENDIF(CMAKE_SYSTEM MATCHES "SunOS-4.*")
+
+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(CMAKE_COMPILER_IS_GNUCC)
+ # Take default rule from CMakeDefaultMakeRuleVariables.cmake.
+ ENDIF(CMAKE_COMPILER_IS_GNUCC)
+ENDIF(CMAKE_COMPILER_IS_GNUCXX)
+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("${CMAKE_C_COMPILER_ID} ${CMAKE_CXX_COMPILER_ID}" MATCHES SunPro)
+
+# The Sun linker needs to find transitive shared library dependencies
+# in the -L path.
+SET(CMAKE_LINK_DEPENDENT_LIBRARY_DIRS 1)
+
+# Shared libraries with no builtin soname may not be linked safely by
+# specifying the file path.
+SET(CMAKE_PLATFORM_USES_PATH_WHEN_NO_SONAME 1)
diff --git a/Modules/Platform/Tru64.cmake b/Modules/Platform/Tru64.cmake
new file mode 100644
index 000000000..cf9d17bfd
--- /dev/null
+++ b/Modules/Platform/Tru64.cmake
@@ -0,0 +1,2 @@
+INCLUDE(Platform/UnixPaths)
+
diff --git a/Modules/Platform/ULTRIX.cmake b/Modules/Platform/ULTRIX.cmake
new file mode 100644
index 000000000..4d0cf755d
--- /dev/null
+++ b/Modules/Platform/ULTRIX.cmake
@@ -0,0 +1,5 @@
+SET(CMAKE_SHARED_LIBRARY_C_FLAGS "-G 0")
+SET(CMAKE_SHARED_LIBRARY_SUFFIX "..o")
+SET(CMAKE_DL_LIBS "")
+SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "-Wl,-D,08000000")
+INCLUDE(Platform/UnixPaths)
diff --git a/Modules/Platform/UNIX_SV.cmake b/Modules/Platform/UNIX_SV.cmake
new file mode 100644
index 000000000..869b3a6a0
--- /dev/null
+++ b/Modules/Platform/UNIX_SV.cmake
@@ -0,0 +1,5 @@
+SET(CMAKE_C_COMPILE_OPTIONS_PIC -K PIC)
+SET(CMAKE_C_COMPILE_OPTIONS_PIE "")
+SET(CMAKE_SHARED_LIBRARY_C_FLAGS "-K PIC")
+SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "-Wl,-Bexport")
+INCLUDE(Platform/UnixPaths)
diff --git a/Modules/Platform/UnixPaths.cmake b/Modules/Platform/UnixPaths.cmake
new file mode 100644
index 000000000..5ee7ddbd6
--- /dev/null
+++ b/Modules/Platform/UnixPaths.cmake
@@ -0,0 +1,88 @@
+
+#=============================================================================
+# Copyright 2006-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.)
+
+# Block multiple inclusion because "CMakeCInformation.cmake" includes
+# "Platform/${CMAKE_SYSTEM_NAME}" even though the generic module
+# "CMakeSystemSpecificInformation.cmake" already included it.
+# The extra inclusion is a work-around documented next to the include()
+# call, so this can be removed when the work-around is removed.
+IF(__UNIX_PATHS_INCLUDED)
+ RETURN()
+ENDIF()
+SET(__UNIX_PATHS_INCLUDED 1)
+
+SET(UNIX 1)
+
+# also add 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)
+
+# List common installation prefixes. These will be used for all
+# search types.
+LIST(APPEND CMAKE_SYSTEM_PREFIX_PATH
+ # Standard
+ /usr/local /usr /
+
+ # CMake install location
+ "${_CMAKE_INSTALL_DIR}"
+
+ # Project install destination.
+ "${CMAKE_INSTALL_PREFIX}"
+ )
+
+# List common include file locations not under the common prefixes.
+LIST(APPEND CMAKE_SYSTEM_INCLUDE_PATH
+ # Windows API on Cygwin
+ /usr/include/w32api
+
+ # X11
+ /usr/X11R6/include /usr/include/X11
+
+ # Other
+ /usr/pkg/include
+ /opt/csw/include /opt/include
+ /usr/openwin/include
+ )
+
+LIST(APPEND CMAKE_SYSTEM_LIBRARY_PATH
+ # Windows API on Cygwin
+ /usr/lib/w32api
+
+ # X11
+ /usr/X11R6/lib /usr/lib/X11
+
+ # Other
+ /usr/pkg/lib
+ /opt/csw/lib /opt/lib
+ /usr/openwin/lib
+ )
+
+LIST(APPEND CMAKE_SYSTEM_PROGRAM_PATH
+ /usr/pkg/bin
+ )
+
+LIST(APPEND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES
+ /lib /usr/lib /usr/lib32 /usr/lib64
+ )
+
+LIST(APPEND CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES
+ /usr/include
+ )
+LIST(APPEND CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES
+ /usr/include
+ )
+
+# Enable use of lib64 search path variants by default.
+SET_PROPERTY(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS TRUE)
diff --git a/Modules/Platform/UnixWare.cmake b/Modules/Platform/UnixWare.cmake
new file mode 100644
index 000000000..3112ee1ef
--- /dev/null
+++ b/Modules/Platform/UnixWare.cmake
@@ -0,0 +1,5 @@
+SET(CMAKE_C_COMPILE_OPTIONS_PIC -K PIC)
+SET(CMAKE_C_COMPILE_OPTIONS_PIE "")
+SET(CMAKE_SHARED_LIBRARY_C_FLAGS "-K PIC")
+SET(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-Wl,-Bexport")
+INCLUDE(Platform/UnixPaths)
diff --git a/Modules/Platform/Windows-Borland-C.cmake b/Modules/Platform/Windows-Borland-C.cmake
new file mode 100644
index 000000000..e2f76aacb
--- /dev/null
+++ b/Modules/Platform/Windows-Borland-C.cmake
@@ -0,0 +1 @@
+include(Platform/Windows-Embarcadero-C)
diff --git a/Modules/Platform/Windows-Borland-CXX.cmake b/Modules/Platform/Windows-Borland-CXX.cmake
new file mode 100644
index 000000000..809490f95
--- /dev/null
+++ b/Modules/Platform/Windows-Borland-CXX.cmake
@@ -0,0 +1 @@
+include(Platform/Windows-Embarcadero-CXX)
diff --git a/Modules/Platform/Windows-Embarcadero-C.cmake b/Modules/Platform/Windows-Embarcadero-C.cmake
new file mode 100644
index 000000000..607fd4ebe
--- /dev/null
+++ b/Modules/Platform/Windows-Embarcadero-C.cmake
@@ -0,0 +1,3 @@
+set(_lang C)
+include(Platform/Windows-Embarcadero)
+__embarcadero_language(C)
diff --git a/Modules/Platform/Windows-Embarcadero-CXX.cmake b/Modules/Platform/Windows-Embarcadero-CXX.cmake
new file mode 100644
index 000000000..279a4def4
--- /dev/null
+++ b/Modules/Platform/Windows-Embarcadero-CXX.cmake
@@ -0,0 +1,3 @@
+set(_lang CXX)
+include(Platform/Windows-Embarcadero)
+__embarcadero_language(CXX)
diff --git a/Modules/Platform/Windows-Embarcadero.cmake b/Modules/Platform/Windows-Embarcadero.cmake
new file mode 100644
index 000000000..62e8eb704
--- /dev/null
+++ b/Modules/Platform/Windows-Embarcadero.cmake
@@ -0,0 +1,130 @@
+
+#=============================================================================
+# Copyright 2002-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.)
+
+# This module is shared by multiple languages; use include blocker.
+if(__WINDOWS_EMBARCADERO)
+ return()
+endif()
+set(__WINDOWS_EMBARCADERO 1)
+
+SET(BORLAND 1)
+
+if("${CMAKE_${_lang}_COMPILER_VERSION}" VERSION_LESS 6.30)
+ # Borland target type flags (bcc32 -h -t):
+ set(_tW "-tW") # -tW GUI App (implies -U__CONSOLE__)
+ set(_tC "-tWC") # -tWC Console App (implies -D__CONSOLE__=1)
+ set(_tD "-tWD") # -tWD Build a DLL (implies -D__DLL__=1 -D_DLL=1)
+ set(_tM "-tWM") # -tWM Enable threads (implies -D__MT__=1 -D_MT=1)
+ set(_tR "-tWR -tW-") # -tWR Use DLL runtime (implies -D_RTLDLL, and '-tW' too!!)
+ # Notes:
+ # - The flags affect linking so we pass them to the linker.
+ # - The flags affect preprocessing so we pass them to the compiler.
+ # - Since '-tWR' implies '-tW' we use '-tWR -tW-' instead.
+ # - Since '-tW-' disables '-tWD' we use '-tWR -tW- -tWD' for DLLs.
+else()
+ set(EMBARCADERO 1)
+ set(_tC "-tC") # Target is a console application
+ set(_tD "-tD") # Target is a shared library
+ set(_tM "-tM") # Target is multi-threaded
+ set(_tR "-tR") # Target uses the dynamic RTL
+ set(_tW "-tW") # Target is a Windows application
+endif()
+set(_COMPILE_C "-c")
+set(_COMPILE_CXX "-P -c")
+
+SET(CMAKE_LIBRARY_PATH_FLAG "-L")
+SET(CMAKE_LINK_LIBRARY_FLAG "")
+
+SET(CMAKE_FIND_LIBRARY_SUFFIXES "-bcc.lib" ".lib")
+
+# uncomment these out to debug makefiles
+#SET(CMAKE_START_TEMP_FILE "")
+#SET(CMAKE_END_TEMP_FILE "")
+#SET(CMAKE_VERBOSE_MAKEFILE 1)
+
+# Borland cannot handle + in the file name, so mangle object file name
+SET (CMAKE_MANGLE_OBJECT_FILE_NAMES "ON")
+
+# extra flags for a win32 exe
+SET(CMAKE_CREATE_WIN32_EXE "${_tW}" )
+# extra flags for a console app
+SET(CMAKE_CREATE_CONSOLE_EXE "${_tC}" )
+
+SET (CMAKE_BUILD_TYPE Debug CACHE STRING
+ "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel.")
+
+SET (CMAKE_EXE_LINKER_FLAGS_INIT "${_tM} -lS:10000000 -lSc:10000000 ")
+SET (CMAKE_EXE_LINKER_FLAGS_DEBUG_INIT "-v")
+SET (CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO_INIT "-v")
+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_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_SHARED_LINKER_FLAGS_RELWITHDEBINFO_INIT})
+
+
+macro(__embarcadero_language lang)
+ set(CMAKE_${lang}_COMPILE_OPTIONS_DLL "${_tD}") # Note: This variable is a ';' separated list
+ set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "${_tD}") # ... while this is a space separated string.
+
+ # compile a source file into an object file
+ # 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> ${CMAKE_START_TEMP_FILE}-DWIN32 -o<OBJECT> <FLAGS> ${_COMPILE_${lang}} <SOURCE>${CMAKE_END_TEMP_FILE}"
+ )
+
+ set(CMAKE_${lang}_LINK_EXECUTABLE
+ "<CMAKE_${lang}_COMPILER> ${_tR} -e<TARGET> ${CMAKE_START_TEMP_FILE}<LINK_FLAGS> <FLAGS> <LINK_LIBRARIES> <OBJECTS>${CMAKE_END_TEMP_FILE}"
+ # "implib -c -w <TARGET_IMPLIB> <TARGET>"
+ )
+
+ # place <DEFINES> outside the response file because Borland refuses
+ # to parse quotes from the response file.
+ set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE
+ "cpp32 <DEFINES> ${CMAKE_START_TEMP_FILE}-DWIN32 <FLAGS> -o<PREPROCESSED_SOURCE> ${_COMPILE_${lang}} <SOURCE>${CMAKE_END_TEMP_FILE}"
+ )
+ # Borland >= 5.6 allows -P option for cpp32, <= 5.5 does not
+
+ # Create a module library.
+ set(CMAKE_${lang}_CREATE_SHARED_MODULE
+ "<CMAKE_${lang}_COMPILER> ${_tR} ${_tD} ${CMAKE_START_TEMP_FILE}-e<TARGET> <LINK_FLAGS> <LINK_LIBRARIES> <OBJECTS>${CMAKE_END_TEMP_FILE}"
+ )
+
+ # Create an import library for another target.
+ set(CMAKE_${lang}_CREATE_IMPORT_LIBRARY
+ "implib -c -w <TARGET_IMPLIB> <TARGET>"
+ )
+
+ # Create a shared library.
+ # First create a module and then its import library.
+ set(CMAKE_${lang}_CREATE_SHARED_LIBRARY
+ ${CMAKE_${lang}_CREATE_SHARED_MODULE}
+ ${CMAKE_${lang}_CREATE_IMPORT_LIBRARY}
+ )
+
+ # create a static library
+ set(CMAKE_${lang}_CREATE_STATIC_LIBRARY
+ "tlib ${CMAKE_START_TEMP_FILE}/p512 <LINK_FLAGS> /a <TARGET_QUOTED> <OBJECTS>${CMAKE_END_TEMP_FILE}"
+ )
+
+ # Initial configuration flags.
+ set(CMAKE_${lang}_FLAGS_INIT "${_tM}")
+ set(CMAKE_${lang}_FLAGS_DEBUG_INIT "-Od -v")
+ set(CMAKE_${lang}_FLAGS_MINSIZEREL_INIT "-O1 -DNDEBUG")
+ set(CMAKE_${lang}_FLAGS_RELEASE_INIT "-O2 -DNDEBUG")
+ set(CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT "-Od")
+ set(CMAKE_${lang}_STANDARD_LIBRARIES_INIT "import32.lib")
+endmacro()
diff --git a/Modules/Platform/Windows-G95-Fortran.cmake b/Modules/Platform/Windows-G95-Fortran.cmake
new file mode 100644
index 000000000..af0800825
--- /dev/null
+++ b/Modules/Platform/Windows-G95-Fortran.cmake
@@ -0,0 +1 @@
+include(Platform/Windows-GNU-Fortran)
diff --git a/Modules/Platform/Windows-GNU-C-ABI.cmake b/Modules/Platform/Windows-GNU-C-ABI.cmake
new file mode 100644
index 000000000..1189263fa
--- /dev/null
+++ b/Modules/Platform/Windows-GNU-C-ABI.cmake
@@ -0,0 +1 @@
+__windows_compiler_gnu_abi(C)
diff --git a/Modules/Platform/Windows-GNU-C.cmake b/Modules/Platform/Windows-GNU-C.cmake
new file mode 100644
index 000000000..ecf89dc1b
--- /dev/null
+++ b/Modules/Platform/Windows-GNU-C.cmake
@@ -0,0 +1,2 @@
+include(Platform/Windows-GNU)
+__windows_compiler_gnu(C)
diff --git a/Modules/Platform/Windows-GNU-CXX-ABI.cmake b/Modules/Platform/Windows-GNU-CXX-ABI.cmake
new file mode 100644
index 000000000..f3c701c3c
--- /dev/null
+++ b/Modules/Platform/Windows-GNU-CXX-ABI.cmake
@@ -0,0 +1 @@
+__windows_compiler_gnu_abi(CXX)
diff --git a/Modules/Platform/Windows-GNU-CXX.cmake b/Modules/Platform/Windows-GNU-CXX.cmake
new file mode 100644
index 000000000..23e655229
--- /dev/null
+++ b/Modules/Platform/Windows-GNU-CXX.cmake
@@ -0,0 +1,2 @@
+include(Platform/Windows-GNU)
+__windows_compiler_gnu(CXX)
diff --git a/Modules/Platform/Windows-GNU-Fortran-ABI.cmake b/Modules/Platform/Windows-GNU-Fortran-ABI.cmake
new file mode 100644
index 000000000..179280b4d
--- /dev/null
+++ b/Modules/Platform/Windows-GNU-Fortran-ABI.cmake
@@ -0,0 +1 @@
+__windows_compiler_gnu_abi(Fortran)
diff --git a/Modules/Platform/Windows-GNU-Fortran.cmake b/Modules/Platform/Windows-GNU-Fortran.cmake
new file mode 100644
index 000000000..b81b79679
--- /dev/null
+++ b/Modules/Platform/Windows-GNU-Fortran.cmake
@@ -0,0 +1,5 @@
+include(Platform/Windows-GNU)
+__windows_compiler_gnu(Fortran)
+
+# gfortran on 64-bit MinGW defines __SIZEOF_POINTER__
+set(CMAKE_Fortran_SIZEOF_DATA_PTR_DEFAULT 4)
diff --git a/Modules/Platform/Windows-GNU.cmake b/Modules/Platform/Windows-GNU.cmake
new file mode 100644
index 000000000..4a37eca87
--- /dev/null
+++ b/Modules/Platform/Windows-GNU.cmake
@@ -0,0 +1,187 @@
+
+#=============================================================================
+# 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 module is shared by multiple languages; use include blocker.
+if(__WINDOWS_GNU)
+ return()
+endif()
+set(__WINDOWS_GNU 1)
+
+set(CMAKE_IMPORT_LIBRARY_PREFIX "lib")
+set(CMAKE_SHARED_LIBRARY_PREFIX "lib")
+set(CMAKE_SHARED_MODULE_PREFIX "lib")
+set(CMAKE_STATIC_LIBRARY_PREFIX "lib")
+
+set(CMAKE_EXECUTABLE_SUFFIX ".exe")
+set(CMAKE_IMPORT_LIBRARY_SUFFIX ".dll.a")
+set(CMAKE_SHARED_LIBRARY_SUFFIX ".dll")
+set(CMAKE_SHARED_MODULE_SUFFIX ".dll")
+set(CMAKE_STATIC_LIBRARY_SUFFIX ".a")
+
+if(MSYS OR MINGW)
+ set(CMAKE_EXTRA_LINK_EXTENSIONS ".lib") # MinGW can also link to a MS .lib
+endif()
+
+if(MINGW)
+ set(CMAKE_FIND_LIBRARY_PREFIXES "lib" "")
+ set(CMAKE_FIND_LIBRARY_SUFFIXES ".dll" ".dll.a" ".a" ".lib")
+ set(CMAKE_C_STANDARD_LIBRARIES_INIT "-lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32")
+ set(CMAKE_CXX_STANDARD_LIBRARIES_INIT "${CMAKE_C_STANDARD_LIBRARIES_INIT}")
+endif()
+
+set(CMAKE_DL_LIBS "")
+set(CMAKE_LIBRARY_PATH_FLAG "-L")
+set(CMAKE_LINK_LIBRARY_FLAG "-l")
+set(CMAKE_LINK_DEF_FILE_FLAG "") # Empty string: passing the file is enough
+set(CMAKE_LINK_LIBRARY_SUFFIX "")
+set(CMAKE_CREATE_WIN32_EXE "-mwindows")
+
+set(CMAKE_GNULD_IMAGE_VERSION
+ "-Wl,--major-image-version,<TARGET_VERSION_MAJOR>,--minor-image-version,<TARGET_VERSION_MINOR>")
+
+# Check if GNU ld is too old to support @FILE syntax.
+set(__WINDOWS_GNU_LD_RESPONSE 1)
+execute_process(COMMAND ld -v OUTPUT_VARIABLE _help ERROR_VARIABLE _help)
+if("${_help}" MATCHES "GNU ld .* 2\\.1[1-6]")
+ set(__WINDOWS_GNU_LD_RESPONSE 0)
+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_FINISH "<CMAKE_RANLIB> <TARGET>")
+
+ # 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
+ # versions of the libraries.
+ foreach(type SHARED_LIBRARY SHARED_MODULE EXE)
+ set(CMAKE_${type}_LINK_STATIC_${lang}_FLAGS "-Wl,-Bstatic")
+ set(CMAKE_${type}_LINK_DYNAMIC_${lang}_FLAGS "-Wl,-Bdynamic")
+ endforeach(type)
+ endif()
+
+ # No -fPIC on Windows
+ set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "")
+ set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "")
+ 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_INCLUDES 1)
+
+ # We prefer "@" for response files but it is not supported by gcc 3.
+ execute_process(COMMAND ${CMAKE_${lang}_COMPILER} --version OUTPUT_VARIABLE _ver ERROR_VARIABLE _ver)
+ if("${_ver}" MATCHES "\\(GCC\\) 3\\.")
+ if("${lang}" STREQUAL "Fortran")
+ # The GNU Fortran compiler reports an error:
+ # no input files; unwilling to write output files
+ # when the response file is passed with "-Wl,@".
+ set(CMAKE_Fortran_USE_RESPONSE_FILE_FOR_OBJECTS 0)
+ else()
+ # Use "-Wl,@" to pass the response file to the linker.
+ set(CMAKE_${lang}_RESPONSE_FILE_LINK_FLAG "-Wl,@")
+ 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)
+ # 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>")
+ 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>")
+ 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>")
+
+ list(APPEND CMAKE_${lang}_ABI_FILES "Platform/Windows-GNU-${lang}-ABI")
+
+ # Support very long lists of object files.
+ # TODO: check for which gcc versions this is still needed, not needed for gcc >= 4.4.
+ # Ninja generator doesn't support this work around.
+ if("${CMAKE_${lang}_RESPONSE_FILE_LINK_FLAG}" STREQUAL "@" AND NOT CMAKE_GENERATOR MATCHES "Ninja")
+ foreach(rule CREATE_SHARED_MODULE CREATE_SHARED_LIBRARY LINK_EXECUTABLE)
+ # The gcc/collect2/ld toolchain does not use response files
+ # internally so we cannot pass long object lists. Instead pass
+ # the object file list in a response file to the archiver to put
+ # them in a temporary archive. Hand the archive to the linker.
+ string(REPLACE "<OBJECTS>" "-Wl,--whole-archive <OBJECT_DIR>/objects.a -Wl,--no-whole-archive"
+ CMAKE_${lang}_${rule} "${CMAKE_${lang}_${rule}}")
+ set(CMAKE_${lang}_${rule}
+ "<CMAKE_COMMAND> -E remove -f <OBJECT_DIR>/objects.a"
+ "<CMAKE_AR> cr <OBJECT_DIR>/objects.a <OBJECTS>"
+ "${CMAKE_${lang}_${rule}}"
+ )
+ endforeach()
+ endif()
+endmacro()
+
+macro(__windows_compiler_gnu_abi lang)
+ if(CMAKE_NO_GNUtoMS)
+ set(CMAKE_GNUtoMS 0)
+ else()
+ option(CMAKE_GNUtoMS "Convert GNU import libraries to MS format (requires Visual Studio)" OFF)
+ endif()
+
+ if(CMAKE_GNUtoMS AND NOT CMAKE_GNUtoMS_LIB)
+ # Find MS development environment setup script for this architecture.
+ if("${CMAKE_SIZEOF_VOID_P}" EQUAL 4)
+ find_program(CMAKE_GNUtoMS_VCVARS NAMES vcvars32.bat
+ DOC "Visual Studio vcvars32.bat"
+ PATHS
+ "[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"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\8.0\\Setup\\VC;ProductDir]/bin"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\7.1\\Setup\\VC;ProductDir]/bin"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\6.0\\Setup\\Microsoft Visual C++;ProductDir]/bin"
+ )
+ set(CMAKE_GNUtoMS_ARCH x86)
+ elseif("${CMAKE_SIZEOF_VOID_P}" EQUAL 8)
+ find_program(CMAKE_GNUtoMS_VCVARS NAMES vcvarsamd64.bat
+ DOC "Visual Studio vcvarsamd64.bat"
+ PATHS
+ "[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"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\8.0\\Setup\\VC;ProductDir]/bin/amd64"
+ )
+ set(CMAKE_GNUtoMS_ARCH amd64)
+ endif()
+ set_property(CACHE CMAKE_GNUtoMS_VCVARS PROPERTY ADVANCED 1)
+ if(CMAKE_GNUtoMS_VCVARS)
+ # Create helper script to run lib.exe from MS environment.
+ string(REPLACE "/" "\\" CMAKE_GNUtoMS_BAT "${CMAKE_GNUtoMS_VCVARS}")
+ set(CMAKE_GNUtoMS_LIB ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeGNUtoMS_lib.bat)
+ configure_file(${CMAKE_ROOT}/Modules/Platform/GNUtoMS_lib.bat.in ${CMAKE_GNUtoMS_LIB})
+ else()
+ message(WARNING "Disabling CMAKE_GNUtoMS option because CMAKE_GNUtoMS_VCVARS is not set.")
+ set(CMAKE_GNUtoMS 0)
+ endif()
+ endif()
+
+ if(CMAKE_GNUtoMS)
+ # Teach CMake how to create a MS import library at link time.
+ set(CMAKE_${lang}_GNUtoMS_RULE " -Wl,--output-def,<TARGET_NAME>.def"
+ "<CMAKE_COMMAND> -Dlib=\"${CMAKE_GNUtoMS_LIB}\" -Ddef=<TARGET_NAME>.def -Ddll=<TARGET> -Dimp=<TARGET_IMPLIB> -P \"${CMAKE_ROOT}/Modules/Platform/GNUtoMS_lib.cmake\""
+ )
+ endif()
+endmacro()
diff --git a/Modules/Platform/Windows-Intel-ASM.cmake b/Modules/Platform/Windows-Intel-ASM.cmake
new file mode 100644
index 000000000..31d08c7ad
--- /dev/null
+++ b/Modules/Platform/Windows-Intel-ASM.cmake
@@ -0,0 +1,2 @@
+include(Platform/Windows-Intel)
+__windows_compiler_intel(ASM)
diff --git a/Modules/Platform/Windows-Intel-C.cmake b/Modules/Platform/Windows-Intel-C.cmake
new file mode 100644
index 000000000..767fec541
--- /dev/null
+++ b/Modules/Platform/Windows-Intel-C.cmake
@@ -0,0 +1,2 @@
+include(Platform/Windows-Intel)
+__windows_compiler_intel(C)
diff --git a/Modules/Platform/Windows-Intel-CXX.cmake b/Modules/Platform/Windows-Intel-CXX.cmake
new file mode 100644
index 000000000..ec5f0aec6
--- /dev/null
+++ b/Modules/Platform/Windows-Intel-CXX.cmake
@@ -0,0 +1,4 @@
+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
new file mode 100644
index 000000000..5c016a8fd
--- /dev/null
+++ b/Modules/Platform/Windows-Intel-Fortran.cmake
@@ -0,0 +1,11 @@
+include(Platform/Windows-Intel)
+set(CMAKE_BUILD_TYPE_INIT Debug)
+set(_COMPILE_Fortran " /fpp")
+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_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
new file mode 100644
index 000000000..2a54a981b
--- /dev/null
+++ b/Modules/Platform/Windows-Intel.cmake
@@ -0,0 +1,108 @@
+
+#=============================================================================
+# Copyright 2002-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.)
+
+# This module is shared by multiple languages; use include blocker.
+if(__WINDOWS_INTEL)
+ return()
+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(CMAKE_VERBOSE_MAKEFILE)
+ SET(CMAKE_CL_NOLOGO "/nologo")
+ENDIF(CMAKE_VERBOSE_MAKEFILE)
+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 "/STACK:10000000 /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_ROOT_BIN}/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(_XILINK_HELP MATCHES MANIFEST)
+ IF(NOT EXISTS "${CMAKE_PLATFORM_ROOT_BIN}/CMakeIntelInformation.cmake")
+ FILE(WRITE ${CMAKE_PLATFORM_ROOT_BIN}/CMakeIntelInformation.cmake
+ "
+SET(_INTEL_XILINK_TEST_RUN 1)
+SET(_INTEL_COMPILER_SUPPORTS_MANIFEST ${_INTEL_COMPILER_SUPPORTS_MANIFEST})
+")
+ ENDIF(NOT EXISTS "${CMAKE_PLATFORM_ROOT_BIN}/CMakeIntelInformation.cmake")
+ENDIF(NOT _INTEL_XILINK_TEST_RUN)
+
+macro(__windows_compiler_intel lang)
+ set(CMAKE_${lang}_COMPILE_OBJECT
+ "<CMAKE_${lang}_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_CL_NOLOGO}${_COMPILE_${lang}} /Fo<OBJECT> <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}_LINK_EXECUTABLE
+ "<CMAKE_${lang}_COMPILER> ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} <FLAGS> <OBJECTS> /Fe<TARGET> -link /implib:<TARGET_IMPLIB> <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()
+endmacro()
diff --git a/Modules/Platform/Windows-NMcl.cmake b/Modules/Platform/Windows-NMcl.cmake
new file mode 100644
index 000000000..7add0b060
--- /dev/null
+++ b/Modules/Platform/Windows-NMcl.cmake
@@ -0,0 +1,4 @@
+# this is for the numega compiler which is really a front
+# end for visual studio, but adds memory checking code.
+
+include(Platform/Windows-cl)
diff --git a/Modules/Platform/Windows-cl.cmake b/Modules/Platform/Windows-cl.cmake
new file mode 100644
index 000000000..be6abb690
--- /dev/null
+++ b/Modules/Platform/Windows-cl.cmake
@@ -0,0 +1,253 @@
+# try to load any previously computed information for C on this platform
+INCLUDE( ${CMAKE_PLATFORM_ROOT_BIN}/CMakeCPlatform.cmake OPTIONAL)
+# try to load any previously computed information for CXX on this platform
+INCLUDE( ${CMAKE_PLATFORM_ROOT_BIN}/CMakeCXXPlatform.cmake OPTIONAL)
+
+SET(WIN32 1)
+
+INCLUDE(Platform/cl)
+
+SET(CMAKE_CREATE_WIN32_EXE /subsystem:windows)
+SET(CMAKE_CREATE_CONSOLE_EXE /subsystem:console)
+
+IF(CMAKE_GENERATOR MATCHES "Visual Studio 6")
+ SET (CMAKE_NO_BUILD_TYPE 1)
+ENDIF(CMAKE_GENERATOR MATCHES "Visual Studio 6")
+IF(NOT CMAKE_NO_BUILD_TYPE AND CMAKE_GENERATOR MATCHES "Visual Studio")
+ SET (CMAKE_NO_BUILD_TYPE 1)
+ SET (CMAKE_CONFIGURATION_TYPES "Debug;Release;MinSizeRel;RelWithDebInfo" CACHE STRING
+ "Semicolon separated list of supported configuration types, only supports Debug, Release, MinSizeRel, and RelWithDebInfo, anything else will be ignored.")
+ MARK_AS_ADVANCED(CMAKE_CONFIGURATION_TYPES)
+ENDIF(NOT CMAKE_NO_BUILD_TYPE AND CMAKE_GENERATOR MATCHES "Visual Studio")
+# does the compiler support pdbtype and is it the newer compiler
+IF(CMAKE_GENERATOR MATCHES "Visual Studio 8")
+ SET(CMAKE_COMPILER_2005 1)
+ENDIF(CMAKE_GENERATOR MATCHES "Visual Studio 8")
+
+# make sure to enable languages after setting configuration types
+ENABLE_LANGUAGE(RC)
+SET(CMAKE_COMPILE_RESOURCE "rc <FLAGS> /fo<OBJECT> <SOURCE>")
+
+# for nmake we need to compute some information about the compiler
+# that is being used.
+# the compiler may be free command line, 6, 7, or 71, and
+# each have properties that must be determined.
+# to avoid running these tests with each cmake run, the
+# test results are saved in CMakeCPlatform.cmake, a file
+# that is automatically copied into try_compile directories
+# by the global generator.
+SET(MSVC_IDE 1)
+IF(CMAKE_GENERATOR MATCHES "Makefiles" OR CMAKE_GENERATOR MATCHES "Ninja")
+ SET(MSVC_IDE 0)
+ IF(NOT CMAKE_VC_COMPILER_TESTS_RUN)
+ SET(CMAKE_VC_COMPILER_TESTS 1)
+ SET(testNmakeCLVersionFile
+ "${CMAKE_ROOT}/Modules/CMakeTestNMakeCLVersion.c")
+ STRING(REGEX REPLACE "/" "\\\\" testNmakeCLVersionFile "${testNmakeCLVersionFile}")
+ MESSAGE(STATUS "Check for CL compiler version")
+ SET(CMAKE_TEST_COMPILER ${CMAKE_C_COMPILER})
+ IF (NOT CMAKE_C_COMPILER)
+ SET(CMAKE_TEST_COMPILER ${CMAKE_CXX_COMPILER})
+ ENDIF(NOT CMAKE_C_COMPILER)
+ EXEC_PROGRAM(${CMAKE_TEST_COMPILER}
+ ARGS /nologo -EP \"${testNmakeCLVersionFile}\"
+ OUTPUT_VARIABLE CMAKE_COMPILER_OUTPUT
+ RETURN_VALUE CMAKE_COMPILER_RETURN
+ )
+ IF(NOT CMAKE_COMPILER_RETURN)
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "Determining the version of compiler passed with the following output:\n"
+ "${CMAKE_COMPILER_OUTPUT}\n\n")
+ STRING(REGEX REPLACE "\n" " " compilerVersion "${CMAKE_COMPILER_OUTPUT}")
+ STRING(REGEX REPLACE ".*VERSION=(.*)" "\\1"
+ compilerVersion "${compilerVersion}")
+ MESSAGE(STATUS "Check for CL compiler version - ${compilerVersion}")
+ SET(MSVC60)
+ SET(MSVC70)
+ SET(MSVC71)
+ SET(MSVC80)
+ SET(CMAKE_COMPILER_2005)
+ IF("${compilerVersion}" LESS 1300)
+ SET(MSVC60 1)
+ SET(CMAKE_COMPILER_SUPPORTS_PDBTYPE 1)
+ ENDIF("${compilerVersion}" LESS 1300)
+ IF("${compilerVersion}" EQUAL 1300)
+ SET(MSVC70 1)
+ SET(CMAKE_COMPILER_SUPPORTS_PDBTYPE 0)
+ ENDIF("${compilerVersion}" EQUAL 1300)
+ IF("${compilerVersion}" EQUAL 1310)
+ SET(MSVC71 1)
+ SET(CMAKE_COMPILER_SUPPORTS_PDBTYPE 0)
+ ENDIF("${compilerVersion}" EQUAL 1310)
+ IF("${compilerVersion}" EQUAL 1400)
+ SET(MSVC80 1)
+ SET(CMAKE_COMPILER_2005 1)
+ ENDIF("${compilerVersion}" EQUAL 1400)
+ IF("${compilerVersion}" EQUAL 1500)
+ SET(MSVC90 1)
+ ENDIF("${compilerVersion}" EQUAL 1500)
+ IF("${compilerVersion}" EQUAL 1600)
+ SET(MSVC10 1)
+ ENDIF("${compilerVersion}" EQUAL 1600)
+ SET(MSVC_VERSION "${compilerVersion}")
+ ELSE(NOT CMAKE_COMPILER_RETURN)
+ MESSAGE(STATUS "Check for CL compiler version - failed")
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Determining the version of compiler failed with the following output:\n"
+ "${CMAKE_COMPILER_OUTPUT}\n\n")
+ ENDIF(NOT CMAKE_COMPILER_RETURN)
+ # try to figure out if we are running the free command line
+ # tools from Microsoft. These tools do not provide debug libraries,
+ # so the link flags used have to be different.
+ MAKE_DIRECTORY("${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp2")
+ SET(testForFreeVCFile
+ "${CMAKE_ROOT}/Modules/CMakeTestForFreeVC.cxx")
+ STRING(REGEX REPLACE "/" "\\\\" testForFreeVCFile "${testForFreeVCFile}")
+ MESSAGE(STATUS "Check if this is a free VC compiler")
+ EXEC_PROGRAM(${CMAKE_TEST_COMPILER} ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp2
+ ARGS /nologo /MD /EHsc
+ \"${testForFreeVCFile}\"
+ OUTPUT_VARIABLE CMAKE_COMPILER_OUTPUT
+ RETURN_VALUE CMAKE_COMPILER_RETURN
+ )
+ IF(CMAKE_COMPILER_RETURN)
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Determining if this is a free VC compiler failed with the following output:\n"
+ "${CMAKE_COMPILER_OUTPUT}\n\n")
+ MESSAGE(STATUS "Check if this is a free VC compiler - yes")
+ SET(CMAKE_USING_VC_FREE_TOOLS 1)
+ ELSE(CMAKE_COMPILER_RETURN)
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "Determining if this is a free VC compiler passed with the following output:\n"
+ "${CMAKE_COMPILER_OUTPUT}\n\n")
+ MESSAGE(STATUS "Check if this is a free VC compiler - no")
+ SET(CMAKE_USING_VC_FREE_TOOLS 0)
+ ENDIF(CMAKE_COMPILER_RETURN)
+ MAKE_DIRECTORY("${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp3")
+ ENDIF(NOT CMAKE_VC_COMPILER_TESTS_RUN)
+ENDIF(CMAKE_GENERATOR MATCHES "Makefiles" OR CMAKE_GENERATOR MATCHES "Ninja")
+
+IF(MSVC_C_ARCHITECTURE_ID MATCHES 64)
+ SET(CMAKE_CL_64 1)
+ELSE(MSVC_C_ARCHITECTURE_ID MATCHES 64)
+ SET(CMAKE_CL_64 0)
+ENDIF(MSVC_C_ARCHITECTURE_ID MATCHES 64)
+IF(CMAKE_FORCE_WIN64 OR CMAKE_FORCE_IA64)
+ SET(CMAKE_CL_64 1)
+ENDIF(CMAKE_FORCE_WIN64 OR CMAKE_FORCE_IA64)
+
+IF("${MSVC_VERSION}" GREATER 1599)
+ SET(MSVC_INCREMENTAL_DEFAULT ON)
+ENDIF()
+
+# default to Debug builds
+IF(MSVC_VERSION GREATER 1310)
+ # for 2005 make sure the manifest is put in the dll with mt
+ SET(CMAKE_CXX_CREATE_SHARED_LIBRARY "<CMAKE_COMMAND> -E vs_link_dll ${CMAKE_CXX_CREATE_SHARED_LIBRARY}")
+ SET(CMAKE_CXX_CREATE_SHARED_MODULE "<CMAKE_COMMAND> -E vs_link_dll ${CMAKE_CXX_CREATE_SHARED_MODULE}")
+ # create a C shared library
+ SET(CMAKE_C_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY}")
+ # create a C shared module just copy the shared library rule
+ SET(CMAKE_C_CREATE_SHARED_MODULE "${CMAKE_CXX_CREATE_SHARED_MODULE}")
+ SET(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_COMMAND> -E vs_link_exe ${CMAKE_CXX_LINK_EXECUTABLE}")
+ SET(CMAKE_C_LINK_EXECUTABLE "<CMAKE_COMMAND> -E vs_link_exe ${CMAKE_C_LINK_EXECUTABLE}")
+
+ SET(CMAKE_BUILD_TYPE_INIT Debug)
+ SET (CMAKE_CXX_FLAGS_INIT "/DWIN32 /D_WINDOWS /W3 /Zm1000 /EHsc /GR")
+ SET (CMAKE_CXX_FLAGS_DEBUG_INIT "/D_DEBUG /MDd /Zi /Ob0 /Od /RTC1")
+ SET (CMAKE_CXX_FLAGS_MINSIZEREL_INIT "/MD /O1 /Ob1 /D NDEBUG")
+ SET (CMAKE_CXX_FLAGS_RELEASE_INIT "/MD /O2 /Ob2 /D NDEBUG")
+ SET (CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "/MD /Zi /O2 /Ob1 /D NDEBUG")
+ SET (CMAKE_C_FLAGS_INIT "/DWIN32 /D_WINDOWS /W3 /Zm1000")
+ SET (CMAKE_C_FLAGS_DEBUG_INIT "/D_DEBUG /MDd /Zi /Ob0 /Od /RTC1")
+ SET (CMAKE_C_FLAGS_MINSIZEREL_INIT "/MD /O1 /Ob1 /D NDEBUG")
+ SET (CMAKE_C_FLAGS_RELEASE_INIT "/MD /O2 /Ob2 /D NDEBUG")
+ SET (CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "/MD /Zi /O2 /Ob1 /D NDEBUG")
+ 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 ")
+ SET (CMAKE_EXE_LINKER_FLAGS_INIT "${CMAKE_EXE_LINKER_FLAGS_INIT}")
+ELSE(MSVC_VERSION GREATER 1310)
+ IF(CMAKE_USING_VC_FREE_TOOLS)
+ MESSAGE(STATUS "Using FREE VC TOOLS, NO DEBUG available")
+ SET(CMAKE_BUILD_TYPE_INIT Release)
+ SET (CMAKE_CXX_FLAGS_INIT "/DWIN32 /D_WINDOWS /W3 /Zm1000 /GX /GR")
+ SET (CMAKE_CXX_FLAGS_DEBUG_INIT "/D_DEBUG /MTd /Zi /Ob0 /Od /GZ")
+ SET (CMAKE_CXX_FLAGS_MINSIZEREL_INIT "/MT /O1 /Ob1 /D NDEBUG")
+ SET (CMAKE_CXX_FLAGS_RELEASE_INIT "/MT /O2 /Ob2 /D NDEBUG")
+ SET (CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "/MT /Zi /O2 /Ob1 /D NDEBUG")
+ SET (CMAKE_C_FLAGS_INIT "/DWIN32 /D_WINDOWS /W3 /Zm1000")
+ SET (CMAKE_C_FLAGS_DEBUG_INIT "/D_DEBUG /MTd /Zi /Ob0 /Od /GZ")
+ SET (CMAKE_C_FLAGS_MINSIZEREL_INIT "/MT /O1 /Ob1 /D NDEBUG")
+ SET (CMAKE_C_FLAGS_RELEASE_INIT "/MT /O2 /Ob2 /D NDEBUG")
+ SET (CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "/MT /Zi /O2 /Ob1 /D NDEBUG")
+ ELSE(CMAKE_USING_VC_FREE_TOOLS)
+ SET(CMAKE_BUILD_TYPE_INIT Debug)
+ SET (CMAKE_CXX_FLAGS_INIT "/DWIN32 /D_WINDOWS /W3 /Zm1000 /GX /GR")
+ SET (CMAKE_CXX_FLAGS_DEBUG_INIT "/D_DEBUG /MDd /Zi /Ob0 /Od /GZ")
+ SET (CMAKE_CXX_FLAGS_MINSIZEREL_INIT "/MD /O1 /Ob1 /D NDEBUG")
+ SET (CMAKE_CXX_FLAGS_RELEASE_INIT "/MD /O2 /Ob2 /D NDEBUG")
+ SET (CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "/MD /Zi /O2 /Ob1 /D NDEBUG")
+ SET (CMAKE_C_FLAGS_INIT "/DWIN32 /D_WINDOWS /W3 /Zm1000")
+ SET (CMAKE_C_FLAGS_DEBUG_INIT "/D_DEBUG /MDd /Zi /Ob0 /Od /GZ")
+ SET (CMAKE_C_FLAGS_MINSIZEREL_INIT "/MD /O1 /Ob1 /D NDEBUG")
+ SET (CMAKE_C_FLAGS_RELEASE_INIT "/MD /O2 /Ob2 /D NDEBUG")
+ SET (CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "/MD /Zi /O2 /Ob1 /D NDEBUG")
+ ENDIF(CMAKE_USING_VC_FREE_TOOLS)
+ 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(MSVC_VERSION GREATER 1310)
+
+SET(CMAKE_CXX_STANDARD_LIBRARIES_INIT "${CMAKE_C_STANDARD_LIBRARIES_INIT}")
+
+# executable linker flags
+SET (CMAKE_LINK_DEF_FILE_FLAG "/DEF:")
+# set the stack size and the machine type
+SET(_MACHINE_ARCH_FLAG ${MSVC_C_ARCHITECTURE_ID})
+IF(NOT _MACHINE_ARCH_FLAG)
+ SET(_MACHINE_ARCH_FLAG ${MSVC_CXX_ARCHITECTURE_ID})
+ENDIF(NOT _MACHINE_ARCH_FLAG)
+SET (CMAKE_EXE_LINKER_FLAGS_INIT
+ "${CMAKE_EXE_LINKER_FLAGS_INIT} /STACK:10000000 /machine:${_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" )
+ENDIF()
+
+IF (CMAKE_COMPILER_SUPPORTS_PDBTYPE)
+ SET (CMAKE_EXE_LINKER_FLAGS_DEBUG_INIT "/debug /pdbtype:sept ${MSVC_INCREMENTAL_YES_FLAG}")
+ SET (CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO_INIT "/debug /pdbtype:sept ${MSVC_INCREMENTAL_YES_FLAG}")
+ELSE (CMAKE_COMPILER_SUPPORTS_PDBTYPE)
+ SET (CMAKE_EXE_LINKER_FLAGS_DEBUG_INIT "/debug ${MSVC_INCREMENTAL_YES_FLAG}")
+ SET (CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO_INIT "/debug ${MSVC_INCREMENTAL_YES_FLAG}")
+ENDIF (CMAKE_COMPILER_SUPPORTS_PDBTYPE)
+# for release and minsize release default to no incremental linking
+SET(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL_INIT "/INCREMENTAL:NO")
+SET(CMAKE_EXE_LINKER_FLAGS_RELEASE_INIT "/INCREMENTAL:NO")
+
+# copy the EXE_LINKER flags to SHARED and MODULE linker flags
+# 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_RELEASE_INIT ${CMAKE_EXE_LINKER_FLAGS_RELEASE_INIT})
+SET (CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL_INIT ${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL_INIT})
+# module linker flags
+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})
+SET (CMAKE_MODULE_LINKER_FLAGS_RELEASE_INIT ${CMAKE_EXE_LINKER_FLAGS_RELEASE_INIT})
+SET (CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL_INIT ${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL_INIT})
+
+# save computed information for this platform
+IF(NOT EXISTS "${CMAKE_PLATFORM_ROOT_BIN}/CMakeCPlatform.cmake")
+ CONFIGURE_FILE(${CMAKE_ROOT}/Modules/Platform/Windows-cl.cmake.in
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeCPlatform.cmake IMMEDIATE)
+ENDIF(NOT EXISTS "${CMAKE_PLATFORM_ROOT_BIN}/CMakeCPlatform.cmake")
+
+IF(NOT EXISTS "${CMAKE_PLATFORM_ROOT_BIN}/CMakeCXXPlatform.cmake")
+ CONFIGURE_FILE(${CMAKE_ROOT}/Modules/Platform/Windows-cl.cmake.in
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeCXXPlatform.cmake IMMEDIATE)
+ENDIF(NOT EXISTS "${CMAKE_PLATFORM_ROOT_BIN}/CMakeCXXPlatform.cmake")
diff --git a/Modules/Platform/Windows-cl.cmake.in b/Modules/Platform/Windows-cl.cmake.in
new file mode 100644
index 000000000..82a0e595f
--- /dev/null
+++ b/Modules/Platform/Windows-cl.cmake.in
@@ -0,0 +1,14 @@
+SET(CMAKE_VC_COMPILER_TESTS_RUN 1)
+SET(CMAKE_COMPILER_SUPPORTS_PDBTYPE @CMAKE_COMPILER_SUPPORTS_PDBTYPE@)
+SET(CMAKE_COMPILER_2005 @CMAKE_COMPILER_2005@)
+SET(CMAKE_USING_VC_FREE_TOOLS @CMAKE_USING_VC_FREE_TOOLS@)
+SET(CMAKE_CL_64 @CMAKE_CL_64@)
+SET(MSVC60 @MSVC60@)
+SET(MSVC70 @MSVC70@)
+SET(MSVC71 @MSVC71@)
+SET(MSVC80 @MSVC80@)
+SET(MSVC90 @MSVC90@)
+SET(MSVC10 @MSVC10@)
+SET(MSVC_IDE @MSVC_IDE@)
+SET(MSVC_VERSION @MSVC_VERSION@)
+SET(WIN32 1)
diff --git a/Modules/Platform/Windows-df.cmake b/Modules/Platform/Windows-df.cmake
new file mode 100644
index 000000000..f5046bf35
--- /dev/null
+++ b/Modules/Platform/Windows-df.cmake
@@ -0,0 +1,70 @@
+# compiler support for fortran CVF compiler on windows
+
+SET(CMAKE_WINDOWS_OBJECT_PATH 1)
+SET(CMAKE_LIBRARY_PATH_FLAG "-LIBPATH:")
+SET(CMAKE_LINK_LIBRARY_FLAG "")
+SET(WIN32 1)
+IF(CMAKE_VERBOSE_MAKEFILE)
+ SET(CMAKE_CL_NOLOGO)
+ELSE(CMAKE_VERBOSE_MAKEFILE)
+ SET(CMAKE_CL_NOLOGO "/nologo")
+ENDIF(CMAKE_VERBOSE_MAKEFILE)
+
+SET(CMAKE_Fortran_MODDIR_FLAG "-module:")
+
+SET(CMAKE_Fortran_CREATE_SHARED_LIBRARY
+ "link ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} /out:<TARGET> /dll <LINK_FLAGS> <OBJECTS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
+
+SET(CMAKE_Fortran_CREATE_SHARED_MODULE ${CMAKE_Fortran_CREATE_SHARED_LIBRARY})
+
+# create a C++ static library
+SET(CMAKE_Fortran_CREATE_STATIC_LIBRARY "lib ${CMAKE_CL_NOLOGO} <LINK_FLAGS> /out:<TARGET> <OBJECTS> ")
+
+# compile a C++ file into an object file
+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_Fortran_LINK_EXECUTABLE
+ "<CMAKE_Fortran_COMPILER> ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} <FLAGS> <OBJECTS> /exe:<TARGET> /link <CMAKE_Fortran_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>${CMAKE_END_TEMP_FILE}")
+
+SET(CMAKE_CREATE_WIN32_EXE /winapp)
+SET(CMAKE_CREATE_CONSOLE_EXE )
+
+IF(CMAKE_GENERATOR MATCHES "Visual Studio 6")
+ SET (CMAKE_NO_BUILD_TYPE 1)
+ENDIF(CMAKE_GENERATOR MATCHES "Visual Studio 6")
+IF(CMAKE_GENERATOR MATCHES "Visual Studio 7" OR CMAKE_GENERATOR MATCHES "Visual Studio 8")
+ SET (CMAKE_NO_BUILD_TYPE 1)
+ SET (CMAKE_CONFIGURATION_TYPES "Debug;Release;MinSizeRel;RelWithDebInfo" CACHE STRING
+ "Semicolon separated list of supported configuration types, only supports Debug, Release, MinSizeRel, and RelWithDebInfo, anything else will be ignored.")
+ENDIF(CMAKE_GENERATOR MATCHES "Visual Studio 7" OR CMAKE_GENERATOR MATCHES "Visual Studio 8")
+# does the compiler support pdbtype and is it the newer compiler
+
+SET(CMAKE_BUILD_TYPE_INIT Debug)
+SET (CMAKE_Fortran_FLAGS_INIT "")
+SET (CMAKE_Fortran_FLAGS_DEBUG_INIT "/debug:full")
+SET (CMAKE_Fortran_FLAGS_MINSIZEREL_INIT "/Optimize:2 /Define:NDEBUG")
+SET (CMAKE_Fortran_FLAGS_RELEASE_INIT "/Optimize:1 /Define:NDEBUG")
+SET (CMAKE_Fortran_FLAGS_RELWITHDEBINFO_INIT "/Optimize:1 /debug:full /Define:NDEBUG")
+
+SET (CMAKE_Fortran_STANDARD_LIBRARIES_INIT "user32.lib")
+
+# executable linker flags
+SET (CMAKE_LINK_DEF_FILE_FLAG "/DEF:")
+SET (CMAKE_EXE_LINKER_FLAGS_INIT " /INCREMENTAL:YES")
+IF (CMAKE_COMPILER_SUPPORTS_PDBTYPE)
+ SET (CMAKE_EXE_LINKER_FLAGS_DEBUG_INIT "/debug /pdbtype:sept")
+ SET (CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO_INIT "/debug /pdbtype:sept")
+ELSE (CMAKE_COMPILER_SUPPORTS_PDBTYPE)
+ SET (CMAKE_EXE_LINKER_FLAGS_DEBUG_INIT "/debug")
+ SET (CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO_INIT "/debug")
+ENDIF (CMAKE_COMPILER_SUPPORTS_PDBTYPE)
+
+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})
diff --git a/Modules/Platform/Windows-wcl386.cmake b/Modules/Platform/Windows-wcl386.cmake
new file mode 100644
index 000000000..14b3b81d5
--- /dev/null
+++ b/Modules/Platform/Windows-wcl386.cmake
@@ -0,0 +1,122 @@
+SET(CMAKE_LIBRARY_PATH_FLAG "libpath ")
+SET(CMAKE_LINK_LIBRARY_FLAG "library ")
+SET(CMAKE_LINK_LIBRARY_FILE_FLAG "library")
+
+IF(CMAKE_VERBOSE_MAKEFILE)
+ SET(CMAKE_WCL_QUIET)
+ SET(CMAKE_WLINK_QUIET)
+ SET(CMAKE_LIB_QUIET)
+ELSE(CMAKE_VERBOSE_MAKEFILE)
+ SET(CMAKE_WCL_QUIET "-zq")
+ SET(CMAKE_WLINK_QUIET "option quiet")
+ SET(CMAKE_LIB_QUIET "-q")
+ENDIF(CMAKE_VERBOSE_MAKEFILE)
+
+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_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.
+
+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}")
+
+SET(CMAKE_C_CREATE_IMPORT_LIBRARY
+ "wlib -c -q -n -b <TARGET_IMPLIB> +'<TARGET_UNQUOTED>'")
+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}")
+
+
+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}")
+
+# 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}")
+
+# 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}")
+
+# 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}")
+
+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})
+
+# create a C shared library
+SET(CMAKE_C_CREATE_SHARED_LIBRARY ${CMAKE_CXX_CREATE_SHARED_LIBRARY})
+
+# create a C shared module
+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> ")
+
+# create a C static library
+SET(CMAKE_C_CREATE_STATIC_LIBRARY ${CMAKE_CXX_CREATE_STATIC_LIBRARY})
+
+IF(NOT CMAKE_WATCOM_COMPILER_TESTS_RUN)
+ SET(CMAKE_WATCOM_COMPILER_TESTS_RUN 1)
+ SET(testWatcomVersionFile
+ "${CMAKE_ROOT}/Modules/CMakeTestWatcomVersion.c")
+ STRING(REGEX REPLACE "/" "\\\\" testWatcomVersionFile "${testWatcomVersionFile}")
+ MESSAGE(STATUS "Check for Watcom compiler version")
+ SET(CMAKE_TEST_COMPILER ${CMAKE_C_COMPILER})
+ IF (NOT CMAKE_C_COMPILER)
+ SET(CMAKE_TEST_COMPILER ${CMAKE_CXX_COMPILER})
+ ENDIF()
+ EXECUTE_PROCESS(COMMAND ${CMAKE_TEST_COMPILER}
+ -q -pc \"${testWatcomVersionFile}\"
+ OUTPUT_VARIABLE CMAKE_COMPILER_OUTPUT
+ RESULT_VARIABLE CMAKE_COMPILER_RETURN
+ )
+ STRING(REGEX REPLACE "\n" " " compilerVersion "${CMAKE_COMPILER_OUTPUT}")
+ STRING(REGEX REPLACE ".*VERSION=(.*)" "\\1"
+ compilerVersion "${compilerVersion}")
+ IF("${CMAKE_COMPILER_RETURN}" STREQUAL "0")
+ SET(WATCOM16)
+ SET(WATCOM17)
+ SET(WATCOM18)
+ SET(WATCOM19)
+ IF("${compilerVersion}" LESS 1270)
+ SET(WATCOM16 1)
+ ENDIF()
+ IF("${compilerVersion}" EQUAL 1270)
+ SET(WATCOM17 1)
+ ENDIF()
+ IF("${compilerVersion}" EQUAL 1280)
+ SET(WATCOM18 1)
+ ENDIF()
+ IF("${compilerVersion}" EQUAL 1290)
+ SET(WATCOM19 1)
+ ENDIF()
+ ENDIF()
+ENDIF()
diff --git a/Modules/Platform/Windows-windres.cmake b/Modules/Platform/Windows-windres.cmake
new file mode 100644
index 000000000..8bc1b15e9
--- /dev/null
+++ b/Modules/Platform/Windows-windres.cmake
@@ -0,0 +1 @@
+SET(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> -O coff <FLAGS> <DEFINES> <SOURCE> <OBJECT>")
diff --git a/Modules/Platform/Windows.cmake b/Modules/Platform/Windows.cmake
new file mode 100644
index 000000000..09cb8d303
--- /dev/null
+++ b/Modules/Platform/Windows.cmake
@@ -0,0 +1,36 @@
+SET(WIN32 1)
+
+SET(CMAKE_STATIC_LIBRARY_PREFIX "")
+SET(CMAKE_STATIC_LIBRARY_SUFFIX ".lib")
+SET(CMAKE_SHARED_LIBRARY_PREFIX "") # lib
+SET(CMAKE_SHARED_LIBRARY_SUFFIX ".dll") # .so
+SET(CMAKE_IMPORT_LIBRARY_PREFIX "")
+SET(CMAKE_IMPORT_LIBRARY_SUFFIX ".lib")
+SET(CMAKE_EXECUTABLE_SUFFIX ".exe") # .exe
+SET(CMAKE_LINK_LIBRARY_SUFFIX ".lib")
+SET(CMAKE_DL_LIBS "")
+
+SET(CMAKE_FIND_LIBRARY_PREFIXES "")
+SET(CMAKE_FIND_LIBRARY_SUFFIXES ".lib")
+
+# for borland make long command lines are redirected to a file
+# with the following syntax, see Windows-bcc32.cmake for use
+IF(CMAKE_GENERATOR MATCHES "Borland")
+ SET(CMAKE_START_TEMP_FILE "@&&|\n")
+ SET(CMAKE_END_TEMP_FILE "\n|")
+ENDIF(CMAKE_GENERATOR MATCHES "Borland")
+
+# for nmake make long command lines are redirected to a file
+# with the following syntax, see Windows-bcc32.cmake for use
+IF(CMAKE_GENERATOR MATCHES "NMake")
+ SET(CMAKE_START_TEMP_FILE "@<<\n")
+ SET(CMAKE_END_TEMP_FILE "\n<<")
+ENDIF(CMAKE_GENERATOR MATCHES "NMake")
+
+INCLUDE(Platform/WindowsPaths)
+
+# uncomment these out to debug nmake and borland makefiles
+#SET(CMAKE_START_TEMP_FILE "")
+#SET(CMAKE_END_TEMP_FILE "")
+#SET(CMAKE_VERBOSE_MAKEFILE 1)
+
diff --git a/Modules/Platform/WindowsPaths.cmake b/Modules/Platform/WindowsPaths.cmake
new file mode 100644
index 000000000..c7b15b342
--- /dev/null
+++ b/Modules/Platform/WindowsPaths.cmake
@@ -0,0 +1,96 @@
+
+#=============================================================================
+# Copyright 2006-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.)
+
+# Block multiple inclusion because "CMakeCInformation.cmake" includes
+# "Platform/${CMAKE_SYSTEM_NAME}" even though the generic module
+# "CMakeSystemSpecificInformation.cmake" already included it.
+# The extra inclusion is a work-around documented next to the include()
+# call, so this can be removed when the work-around is removed.
+IF(__WINDOWS_PATHS_INCLUDED)
+ RETURN()
+ENDIF()
+SET(__WINDOWS_PATHS_INCLUDED 1)
+
+# Add the program-files folder(s) to the list of installation
+# prefixes.
+#
+# 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>
+#
+# Windows 32-bit Binary:
+# 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}")
+ 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)")
+ ENDIF()
+ ENDIF()
+ENDIF()
+
+# 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}"
+
+ # MinGW (useful when cross compiling from linux with CMAKE_FIND_ROOT_PATH set)
+ /
+ )
+
+LIST(APPEND CMAKE_SYSTEM_INCLUDE_PATH
+ )
+
+# mingw can also link against dlls which can also be in /bin, so list this too
+LIST(APPEND CMAKE_SYSTEM_LIBRARY_PATH
+ "${CMAKE_INSTALL_PREFIX}/bin"
+ "${_CMAKE_INSTALL_DIR}/bin"
+ /bin
+ )
+
+LIST(APPEND CMAKE_SYSTEM_PROGRAM_PATH
+ )
diff --git a/Modules/Platform/Xenix.cmake b/Modules/Platform/Xenix.cmake
new file mode 100644
index 000000000..cf9d17bfd
--- /dev/null
+++ b/Modules/Platform/Xenix.cmake
@@ -0,0 +1,2 @@
+INCLUDE(Platform/UnixPaths)
+
diff --git a/Modules/Platform/cl.cmake b/Modules/Platform/cl.cmake
new file mode 100644
index 000000000..c0f014b58
--- /dev/null
+++ b/Modules/Platform/cl.cmake
@@ -0,0 +1,62 @@
+SET(CMAKE_LIBRARY_PATH_FLAG "-LIBPATH:")
+SET(CMAKE_LINK_LIBRARY_FLAG "")
+SET(MSVC 1)
+
+# hack: if a new cmake (which uses CMAKE__LINKER) runs on an old build tree
+# (where link was hardcoded) and where CMAKE_LINKER isn't in the cache
+# and still cmake didn't fail in CMakeFindBinUtils.cmake (because it isn't rerun)
+# hardcode CMAKE_LINKER here to link, so it behaves as it did before, Alex
+IF(NOT DEFINED CMAKE_LINKER)
+ SET(CMAKE_LINKER link)
+ENDIF(NOT DEFINED CMAKE_LINKER)
+
+IF(CMAKE_VERBOSE_MAKEFILE)
+ SET(CMAKE_CL_NOLOGO)
+ELSE(CMAKE_VERBOSE_MAKEFILE)
+ SET(CMAKE_CL_NOLOGO "/nologo")
+ENDIF(CMAKE_VERBOSE_MAKEFILE)
+# create a shared C++ library
+SET(CMAKE_CXX_CREATE_SHARED_LIBRARY
+ "<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}")
+SET(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}")
+
+# create a C shared module
+SET(CMAKE_C_CREATE_SHARED_MODULE "${CMAKE_CXX_CREATE_SHARED_MODULE}")
+
+# create a C++ static library
+SET(CMAKE_CXX_CREATE_STATIC_LIBRARY "<CMAKE_LINKER> /lib ${CMAKE_CL_NOLOGO} <LINK_FLAGS> /out:<TARGET> <OBJECTS> ")
+
+# create a C static library
+SET(CMAKE_C_CREATE_STATIC_LIBRARY "${CMAKE_CXX_CREATE_STATIC_LIBRARY}")
+
+# compile a C++ file into an object file
+SET(CMAKE_CXX_COMPILE_OBJECT
+ "<CMAKE_CXX_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_CL_NOLOGO} <FLAGS> <DEFINES> /TP /Fo<OBJECT> /Fd<TARGET_PDB> -c <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_CL_NOLOGO} <FLAGS> <DEFINES> /Fo<OBJECT> /Fd<TARGET_PDB> -c <SOURCE>${CMAKE_END_TEMP_FILE}")
+
+SET(CMAKE_C_USE_RESPONSE_FILE_FOR_OBJECTS 1)
+SET(CMAKE_C_LINK_EXECUTABLE
+ "<CMAKE_C_COMPILER> ${CMAKE_CL_NOLOGO} <OBJECTS> ${CMAKE_START_TEMP_FILE} <FLAGS> /Fe<TARGET> /Fd<TARGET_PDB> -link /implib:<TARGET_IMPLIB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>${CMAKE_END_TEMP_FILE}")
+
+SET(CMAKE_CXX_USE_RESPONSE_FILE_FOR_OBJECTS 1)
+SET(CMAKE_CXX_LINK_EXECUTABLE
+ "<CMAKE_CXX_COMPILER> ${CMAKE_CL_NOLOGO} <OBJECTS> ${CMAKE_START_TEMP_FILE} <FLAGS> /Fe<TARGET> /Fd<TARGET_PDB> -link /implib:<TARGET_IMPLIB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>${CMAKE_END_TEMP_FILE}")
+
+SET(CMAKE_C_CREATE_PREPROCESSED_SOURCE
+ "<CMAKE_C_COMPILER> > <PREPROCESSED_SOURCE> ${CMAKE_START_TEMP_FILE} ${CMAKE_CL_NOLOGO} <FLAGS> <DEFINES> -E <SOURCE>${CMAKE_END_TEMP_FILE}")
+
+SET(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE
+ "<CMAKE_CXX_COMPILER> > <PREPROCESSED_SOURCE> ${CMAKE_START_TEMP_FILE} ${CMAKE_CL_NOLOGO} <FLAGS> <DEFINES> /TP -E <SOURCE>${CMAKE_END_TEMP_FILE}")
+
+SET(CMAKE_C_CREATE_ASSEMBLY_SOURCE
+ "<CMAKE_C_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_CL_NOLOGO} <FLAGS> /FAs /FoNUL /Fa<ASSEMBLY_SOURCE> /c <SOURCE>${CMAKE_END_TEMP_FILE}")
+
+SET(CMAKE_CXX_CREATE_ASSEMBLY_SOURCE
+ "<CMAKE_CXX_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_CL_NOLOGO} <FLAGS> /TP /FAs /FoNUL /Fa<ASSEMBLY_SOURCE> /c <SOURCE>${CMAKE_END_TEMP_FILE}")
+
diff --git a/Modules/Platform/eCos.cmake b/Modules/Platform/eCos.cmake
new file mode 100644
index 000000000..b437c1a9b
--- /dev/null
+++ b/Modules/Platform/eCos.cmake
@@ -0,0 +1,65 @@
+# support for eCos http://ecos.sourceware.org
+
+# Guard against multiple inclusion, which e.g. leads to multiple calls to add_definition() #12987
+IF(__ECOS_CMAKE_INCLUDED)
+ RETURN()
+ENDIF()
+SET(__ECOS_CMAKE_INCLUDED TRUE)
+
+SET(CMAKE_SHARED_LIBRARY_C_FLAGS "") # -pic
+SET(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "") # -shared
+SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") # +s, flag for exe link to use shared lib
+SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "") # -rpath
+SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP "") # : or empty
+
+SET(CMAKE_LINK_LIBRARY_SUFFIX "")
+SET(CMAKE_STATIC_LIBRARY_PREFIX "lib")
+SET(CMAKE_STATIC_LIBRARY_SUFFIX ".a")
+SET(CMAKE_SHARED_LIBRARY_PREFIX "lib") # lib
+SET(CMAKE_SHARED_LIBRARY_SUFFIX ".a") # .a
+SET(CMAKE_EXECUTABLE_SUFFIX ".elf") # same suffix as if built using UseEcos.cmake
+SET(CMAKE_DL_LIBS "" )
+
+SET(CMAKE_FIND_LIBRARY_PREFIXES "lib")
+SET(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
+
+
+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)
+ MESSAGE(FATAL_ERROR "GNU gcc is required for eCos")
+ENDIF(CMAKE_C_COMPILER AND NOT "${CMAKE_C_COMPILER_ID}" MATCHES "GNU" AND NOT _IN_TC)
+IF(CMAKE_CXX_COMPILER AND NOT "${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU" AND NOT _IN_TC)
+ MESSAGE(FATAL_ERROR "GNU g++ is required for eCos")
+ENDIF(CMAKE_CXX_COMPILER AND NOT "${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU" AND NOT _IN_TC)
+
+# find eCos system files
+FIND_PATH(ECOS_SYSTEM_CONFIG_HEADER_PATH NAMES pkgconf/system.h)
+FIND_LIBRARY(ECOS_SYSTEM_TARGET_LIBRARY NAMES libtarget.a)
+
+IF(NOT ECOS_SYSTEM_CONFIG_HEADER_PATH)
+ MESSAGE(FATAL_ERROR "Could not find eCos pkgconf/system.h. Build eCos first and set up CMAKE_FIND_ROOT_PATH correctly.")
+ENDIF(NOT ECOS_SYSTEM_CONFIG_HEADER_PATH)
+
+IF(NOT ECOS_SYSTEM_TARGET_LIBRARY)
+ MESSAGE(FATAL_ERROR "Could not find eCos \"libtarget.a\". Build eCos first and set up CMAKE_FIND_ROOT_PATH correctly.")
+ENDIF(NOT ECOS_SYSTEM_TARGET_LIBRARY)
+
+GET_FILENAME_COMPONENT(ECOS_LIBTARGET_DIRECTORY "${ECOS_SYSTEM_TARGET_LIBRARY}" PATH)
+INCLUDE_DIRECTORIES(${ECOS_SYSTEM_CONFIG_HEADER_PATH})
+ADD_DEFINITIONS(-D__ECOS__=1 -D__ECOS=1)
+
+# special link commands for eCos executables
+SET(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> -nostdlib -nostartfiles -L${ECOS_LIBTARGET_DIRECTORY} -Ttarget.ld <LINK_LIBRARIES>")
+SET(CMAKE_C_LINK_EXECUTABLE "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> -nostdlib -nostartfiles -L${ECOS_LIBTARGET_DIRECTORY} -Ttarget.ld <LINK_LIBRARIES>")
+
+# eCos doesn't 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/gas.cmake b/Modules/Platform/gas.cmake
new file mode 100644
index 000000000..c34aef17a
--- /dev/null
+++ b/Modules/Platform/gas.cmake
@@ -0,0 +1,19 @@
+IF(UNIX)
+ SET(CMAKE_ASM${ASM_DIALECT}_OUTPUT_EXTENSION .o)
+ELSE(UNIX)
+ SET(CMAKE_ASM${ASM_DIALECT}_OUTPUT_EXTENSION .obj)
+ENDIF(UNIX)
+
+SET(CMAKE_ASM${ASM_DIALECT}_COMPILE_OBJECT "<CMAKE_ASM${ASM_DIALECT}_COMPILER> <FLAGS> -o <OBJECT> <SOURCE>")
+
+SET(CMAKE_ASM${ASM_DIALECT}_CREATE_STATIC_LIBRARY
+ "<CMAKE_AR> cr <TARGET> <LINK_FLAGS> <OBJECTS> "
+ "<CMAKE_RANLIB> <TARGET> ")
+
+SET(CMAKE_ASM${ASM_DIALECT}_LINK_EXECUTABLE
+ "<CMAKE_LINKER> <FLAGS> <CMAKE_ASM${ASM_DIALECT}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
+
+# to be done
+SET(CMAKE_ASM${ASM_DIALECT}_CREATE_SHARED_LIBRARY)
+SET(CMAKE_ASM${ASM_DIALECT}_CREATE_SHARED_MODULE)
+
diff --git a/Modules/Platform/kFreeBSD.cmake b/Modules/Platform/kFreeBSD.cmake
new file mode 100644
index 000000000..c1295fb0d
--- /dev/null
+++ b/Modules/Platform/kFreeBSD.cmake
@@ -0,0 +1,4 @@
+# kFreeBSD looks just like Linux.
+INCLUDE(Platform/Linux)
+
+SET(CMAKE_LIBRARY_ARCHITECTURE_REGEX "[a-z0-9_]+(-[a-z0-9_]+)?-kfreebsd-gnu[a-z0-9_]*")
diff --git a/Modules/Platform/syllable.cmake b/Modules/Platform/syllable.cmake
new file mode 100644
index 000000000..2d11d08b3
--- /dev/null
+++ b/Modules/Platform/syllable.cmake
@@ -0,0 +1,33 @@
+# this is the platform file for the Syllable OS (http://www.syllable.org)
+# Syllable is a free OS (GPL), which is mostly POSIX conform
+# the linker accepts the rpath related arguments, but this is later on
+# ignored by the runtime linker
+# shared libs are found exclusively via the environment variable DLL_PATH,
+# which may contain also dirs containing the special variable @bindir@
+# by default @bindir@/lib is part of DLL_PATH
+# in order to run the cmake tests successfully it is required that also
+# @bindir@/. and @bindir@/../lib are in DLL_PATH
+
+
+SET(CMAKE_DL_LIBS "dl")
+SET(CMAKE_C_COMPILE_OPTIONS_PIC "-fPIC")
+SET(CMAKE_C_COMPILE_OPTIONS_PIE "-fPIE")
+SET(CMAKE_SHARED_LIBRARY_C_FLAGS "-fPIC") # -pic
+SET(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-shared") # -shared
+SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") # +s, flag for exe link to use shared lib
+SET(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "-Wl,-soname,")
+#SET(CMAKE_EXE_EXPORTS_C_FLAG "-Wl,--export-dynamic")
+
+# 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
+# versions of the libraries.
+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(type)
+
+INCLUDE(Platform/UnixPaths)
+
+# these are Syllable specific:
+LIST(APPEND CMAKE_SYSTEM_PREFIX_PATH /usr/indexes)
diff --git a/Modules/ProcessorCount.cmake b/Modules/ProcessorCount.cmake
new file mode 100644
index 000000000..eff4766b1
--- /dev/null
+++ b/Modules/ProcessorCount.cmake
@@ -0,0 +1,183 @@
+# - 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.
+#
+# 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.
+#
+# 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()
+#
+# 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
+# code.
+
+#=============================================================================
+# 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.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+function(ProcessorCount var)
+ # Unknown:
+ set(count 0)
+
+ if(WIN32)
+ # Windows:
+ set(count "$ENV{NUMBER_OF_PROCESSORS}")
+ #message("ProcessorCount: WIN32, trying environment variable")
+ endif()
+
+ if(NOT count)
+ # Mac, FreeBSD, OpenBSD (systems with sysctl):
+ find_program(ProcessorCount_cmd_sysctl sysctl
+ PATHS /usr/sbin /sbin)
+ if(ProcessorCount_cmd_sysctl)
+ execute_process(COMMAND ${ProcessorCount_cmd_sysctl} -n hw.ncpu
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ OUTPUT_VARIABLE count)
+ #message("ProcessorCount: trying sysctl '${ProcessorCount_cmd_sysctl}'")
+ endif()
+ endif()
+
+ if(NOT count)
+ # Linux (systems with getconf):
+ find_program(ProcessorCount_cmd_getconf getconf)
+ if(ProcessorCount_cmd_getconf)
+ execute_process(COMMAND ${ProcessorCount_cmd_getconf} _NPROCESSORS_ONLN
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ OUTPUT_VARIABLE count)
+ #message("ProcessorCount: trying getconf '${ProcessorCount_cmd_getconf}'")
+ endif()
+ endif()
+
+ if(NOT count)
+ # HPUX (systems with machinfo):
+ find_program(ProcessorCount_cmd_machinfo machinfo
+ PATHS /usr/contrib/bin)
+ if(ProcessorCount_cmd_machinfo)
+ execute_process(COMMAND ${ProcessorCount_cmd_machinfo}
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ OUTPUT_VARIABLE machinfo_output)
+ string(REGEX MATCHALL "Number of CPUs = ([0-9]+)" procs "${machinfo_output}")
+ set(count "${CMAKE_MATCH_1}")
+ #message("ProcessorCount: trying machinfo '${ProcessorCount_cmd_machinfo}'")
+ endif()
+ endif()
+
+ if(NOT count)
+ # IRIX (systems with hinv):
+ find_program(ProcessorCount_cmd_hinv hinv
+ PATHS /sbin)
+ if(ProcessorCount_cmd_hinv)
+ execute_process(COMMAND ${ProcessorCount_cmd_hinv}
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ OUTPUT_VARIABLE hinv_output)
+ string(REGEX MATCHALL "([0-9]+) .* Processors" procs "${hinv_output}")
+ set(count "${CMAKE_MATCH_1}")
+ #message("ProcessorCount: trying hinv '${ProcessorCount_cmd_hinv}'")
+ endif()
+ endif()
+
+ if(NOT count)
+ # AIX (systems with lsconf):
+ find_program(ProcessorCount_cmd_lsconf lsconf
+ PATHS /usr/sbin)
+ if(ProcessorCount_cmd_lsconf)
+ execute_process(COMMAND ${ProcessorCount_cmd_lsconf}
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ OUTPUT_VARIABLE lsconf_output)
+ string(REGEX MATCHALL "Number Of Processors: ([0-9]+)" procs "${lsconf_output}")
+ set(count "${CMAKE_MATCH_1}")
+ #message("ProcessorCount: trying lsconf '${ProcessorCount_cmd_lsconf}'")
+ endif()
+ endif()
+
+ if(NOT count)
+ # QNX (systems with pidin):
+ find_program(ProcessorCount_cmd_pidin pidin)
+ if(ProcessorCount_cmd_pidin)
+ execute_process(COMMAND ${ProcessorCount_cmd_pidin} info
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ OUTPUT_VARIABLE pidin_output)
+ string(REGEX MATCHALL "Processor[0-9]+: " procs "${pidin_output}")
+ list(LENGTH procs count)
+ #message("ProcessorCount: trying pidin '${ProcessorCount_cmd_pidin}'")
+ endif()
+ endif()
+
+ if(NOT count)
+ # Sun (systems where uname -X emits "NumCPU" in its output):
+ find_program(ProcessorCount_cmd_uname 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()
+
+ # Execute this code when all previously attempted methods return empty
+ # output:
+ #
+ if(NOT count)
+ # Systems with /proc/cpuinfo:
+ set(cpuinfo_file /proc/cpuinfo)
+ if(EXISTS "${cpuinfo_file}")
+ file(STRINGS "${cpuinfo_file}" procs REGEX "^processor.: [0-9]+$")
+ list(LENGTH procs count)
+ #message("ProcessorCount: trying cpuinfo '${cpuinfo_file}'")
+ 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:
+ #
+ if(NOT count)
+ set(count "$ENV{NUMBER_OF_PROCESSORS}")
+ #message("ProcessorCount: last fallback, trying environment variable")
+ endif()
+
+ # Ensure an integer return (avoid inadvertently returning an empty string
+ # or an error string)... If it's not a decimal integer, return 0:
+ #
+ if(NOT count MATCHES "^[0-9]+$")
+ set(count 0)
+ endif()
+
+ set(${var} ${count} PARENT_SCOPE)
+endfunction()
diff --git a/Modules/Qt4ConfigDependentSettings.cmake b/Modules/Qt4ConfigDependentSettings.cmake
new file mode 100644
index 000000000..10af3bc95
--- /dev/null
+++ b/Modules/Qt4ConfigDependentSettings.cmake
@@ -0,0 +1,295 @@
+# This file is included by FindQt4.cmake, don't include it directly.
+
+#=============================================================================
+# 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.)
+
+
+###############################################
+#
+# configuration/system dependent settings
+#
+###############################################
+
+# find dependencies for some Qt modules
+# when doing builds against a static Qt, they are required
+# when doing builds against a shared Qt, they are not required
+# if a user needs the dependencies, and they couldn't be found, they can set
+# the variables themselves.
+
+SET(QT_QTGUI_LIB_DEPENDENCIES "")
+SET(QT_QTCORE_LIB_DEPENDENCIES "")
+SET(QT_QTNETWORK_LIB_DEPENDENCIES "")
+SET(QT_QTOPENGL_LIB_DEPENDENCIES "")
+SET(QT_QTDBUS_LIB_DEPENDENCIES "")
+SET(QT_QTHELP_LIB_DEPENDENCIES ${QT_QTCLUCENE_LIBRARY})
+
+
+IF(Q_WS_WIN)
+ # On Windows, qconfig.pri has "shared" for shared library builds
+ IF(NOT QT_CONFIG MATCHES "shared")
+ SET(QT_IS_STATIC 1)
+ ENDIF(NOT QT_CONFIG MATCHES "shared")
+ELSE(Q_WS_WIN)
+ # On other platforms, check file extension to know if its static
+ IF(QT_QTCORE_LIBRARY_RELEASE)
+ GET_FILENAME_COMPONENT(qtcore_lib_ext "${QT_QTCORE_LIBRARY_RELEASE}" EXT)
+ IF("${qtcore_lib_ext}" STREQUAL "${CMAKE_STATIC_LIBRARY_SUFFIX}")
+ SET(QT_IS_STATIC 1)
+ ENDIF("${qtcore_lib_ext}" STREQUAL "${CMAKE_STATIC_LIBRARY_SUFFIX}")
+ ENDIF(QT_QTCORE_LIBRARY_RELEASE)
+ IF(QT_QTCORE_LIBRARY_DEBUG)
+ GET_FILENAME_COMPONENT(qtcore_lib_ext "${QT_QTCORE_LIBRARY_DEBUG}" EXT)
+ IF(${qtcore_lib_ext} STREQUAL ${CMAKE_STATIC_LIBRARY_SUFFIX})
+ SET(QT_IS_STATIC 1)
+ ENDIF(${qtcore_lib_ext} STREQUAL ${CMAKE_STATIC_LIBRARY_SUFFIX})
+ ENDIF(QT_QTCORE_LIBRARY_DEBUG)
+ENDIF(Q_WS_WIN)
+
+# build using shared Qt needs -DQT_DLL on Windows
+IF(Q_WS_WIN AND NOT QT_IS_STATIC)
+ SET(QT_DEFINITIONS ${QT_DEFINITIONS} -DQT_DLL)
+ENDIF(Q_WS_WIN AND NOT QT_IS_STATIC)
+
+IF(NOT QT_IS_STATIC)
+ RETURN()
+ENDIF(NOT QT_IS_STATIC)
+
+# QtOpenGL dependencies
+find_package(OpenGL)
+SET (QT_QTOPENGL_LIB_DEPENDENCIES ${OPENGL_glu_LIBRARY} ${OPENGL_gl_LIBRARY})
+
+
+## system png
+IF(QT_QCONFIG MATCHES "system-png")
+ find_package(PNG)
+ SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} ${PNG_LIBRARY})
+ENDIF(QT_QCONFIG MATCHES "system-png")
+
+## system jpeg
+IF(QT_QCONFIG MATCHES "system-jpeg")
+ find_package(JPEG)
+ SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} ${JPEG_LIBRARIES})
+ENDIF(QT_QCONFIG MATCHES "system-jpeg")
+
+## system tiff
+IF(QT_QCONFIG MATCHES "system-tiff")
+ find_package(TIFF)
+ SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} ${TIFF_LIBRARIES})
+ENDIF(QT_QCONFIG MATCHES "system-tiff")
+
+## system mng
+IF(QT_QCONFIG MATCHES "system-mng")
+ find_library(MNG_LIBRARY NAMES mng)
+ SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} ${MNG_LIBRARY})
+ENDIF(QT_QCONFIG MATCHES "system-mng")
+
+# for X11, get X11 library directory
+IF(Q_WS_X11)
+ FIND_PACKAGE(X11)
+ENDIF(Q_WS_X11)
+
+
+## X11 SM
+IF(QT_QCONFIG MATCHES "x11sm")
+ IF(X11_SM_LIB AND X11_ICE_LIB)
+ SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} ${X11_SM_LIB} ${X11_ICE_LIB})
+ ENDIF(X11_SM_LIB AND X11_ICE_LIB)
+ENDIF(QT_QCONFIG MATCHES "x11sm")
+
+
+## Xi
+IF(QT_QCONFIG MATCHES "tablet")
+ IF(X11_Xi_LIB)
+ SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} ${X11_Xi_LIB})
+ ENDIF(X11_Xi_LIB)
+ENDIF(QT_QCONFIG MATCHES "tablet")
+
+
+## Xrender
+IF(QT_QCONFIG MATCHES "xrender")
+ IF(X11_Xrender_LIB)
+ SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} ${X11_Xrender_LIB})
+ ENDIF(X11_Xrender_LIB)
+ENDIF(QT_QCONFIG MATCHES "xrender")
+
+
+## Xrandr
+IF(QT_QCONFIG MATCHES "xrandr")
+ IF(X11_Xrandr_LIB)
+ SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} ${X11_Xrandr_LIB})
+ ENDIF(X11_Xrandr_LIB)
+ENDIF(QT_QCONFIG MATCHES "xrandr")
+
+
+## Xcursor
+IF(QT_QCONFIG MATCHES "xcursor")
+ IF(X11_Xcursor_LIB)
+ SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} ${X11_Xcursor_LIB})
+ ENDIF(X11_Xcursor_LIB)
+ENDIF(QT_QCONFIG MATCHES "xcursor")
+
+
+## Xinerama
+IF(QT_QCONFIG MATCHES "xinerama")
+ IF(X11_Xinerama_LIB)
+ SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} ${X11_Xinerama_LIB})
+ ENDIF(X11_Xinerama_LIB)
+ENDIF(QT_QCONFIG MATCHES "xinerama")
+
+
+## Xfixes
+IF(QT_QCONFIG MATCHES "xfixes")
+ IF(X11_Xfixes_LIB)
+ SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} ${X11_Xfixes_LIB})
+ ENDIF(X11_Xfixes_LIB)
+ENDIF(QT_QCONFIG MATCHES "xfixes")
+
+
+## fontconfig
+IF(QT_QCONFIG MATCHES "fontconfig")
+ FIND_LIBRARY(QT_FONTCONFIG_LIBRARY NAMES fontconfig)
+ MARK_AS_ADVANCED(QT_FONTCONFIG_LIBRARY)
+ IF(QT_FONTCONFIG_LIBRARY)
+ SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} ${QT_FONTCONFIG_LIBRARY})
+ ENDIF(QT_FONTCONFIG_LIBRARY)
+ENDIF(QT_QCONFIG MATCHES "fontconfig")
+
+
+## system-freetype
+IF(QT_QCONFIG MATCHES "system-freetype")
+ find_package(Freetype)
+ if(FREETYPE_LIBRARIES)
+ SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} ${FREETYPE_LIBRARIES})
+ endif(FREETYPE_LIBRARIES)
+ENDIF(QT_QCONFIG MATCHES "system-freetype")
+
+
+## system-zlib
+IF(QT_QCONFIG MATCHES "system-zlib")
+ find_package(ZLIB)
+ SET(QT_QTCORE_LIB_DEPENDENCIES ${QT_QTCORE_LIB_DEPENDENCIES} ${ZLIB_LIBRARIES})
+ENDIF(QT_QCONFIG MATCHES "system-zlib")
+
+
+## openssl
+IF(NOT Q_WS_WIN)
+ SET(_QT_NEED_OPENSSL 0)
+ IF(QT_VERSION_MINOR LESS 4 AND QT_QCONFIG MATCHES "openssl")
+ SET(_QT_NEED_OPENSSL 1)
+ ENDIF(QT_VERSION_MINOR LESS 4 AND QT_QCONFIG MATCHES "openssl")
+ IF(QT_VERSION_MINOR GREATER 3 AND QT_QCONFIG MATCHES "openssl-linked")
+ SET(_QT_NEED_OPENSSL 1)
+ ENDIF(QT_VERSION_MINOR GREATER 3 AND QT_QCONFIG MATCHES "openssl-linked")
+ IF(_QT_NEED_OPENSSL)
+ FIND_PACKAGE(OpenSSL)
+ IF(OPENSSL_LIBRARIES)
+ SET(QT_QTNETWORK_LIB_DEPENDENCIES ${QT_QTNETWORK_LIB_DEPENDENCIES} ${OPENSSL_LIBRARIES})
+ ENDIF(OPENSSL_LIBRARIES)
+ ENDIF(_QT_NEED_OPENSSL)
+ENDIF(NOT Q_WS_WIN)
+
+
+## dbus
+IF(QT_QCONFIG MATCHES "dbus")
+
+ FIND_LIBRARY(QT_DBUS_LIBRARY NAMES dbus-1 )
+ IF(QT_DBUS_LIBRARY)
+ SET(QT_QTDBUS_LIB_DEPENDENCIES ${QT_QTDBUS_LIB_DEPENDENCIES} ${QT_DBUS_LIBRARY})
+ ENDIF(QT_DBUS_LIBRARY)
+ MARK_AS_ADVANCED(QT_DBUS_LIBRARY)
+
+ENDIF(QT_QCONFIG MATCHES "dbus")
+
+
+## glib
+IF(QT_QCONFIG MATCHES "glib")
+
+ # Qt 4.2.0+ uses glib-2.0
+ FIND_LIBRARY(QT_GLIB_LIBRARY NAMES glib-2.0 )
+ FIND_LIBRARY(QT_GTHREAD_LIBRARY NAMES gthread-2.0 )
+ MARK_AS_ADVANCED(QT_GLIB_LIBRARY)
+ MARK_AS_ADVANCED(QT_GTHREAD_LIBRARY)
+
+ IF(QT_GLIB_LIBRARY AND QT_GTHREAD_LIBRARY)
+ SET(QT_QTCORE_LIB_DEPENDENCIES ${QT_QTCORE_LIB_DEPENDENCIES}
+ ${QT_GTHREAD_LIBRARY} ${QT_GLIB_LIBRARY})
+ ENDIF(QT_GLIB_LIBRARY AND QT_GTHREAD_LIBRARY)
+
+
+ # Qt 4.5+ also links to gobject-2.0
+ IF(QT_VERSION_MINOR GREATER 4)
+ FIND_LIBRARY(QT_GOBJECT_LIBRARY NAMES gobject-2.0 PATHS ${_glib_query_output} )
+ MARK_AS_ADVANCED(QT_GOBJECT_LIBRARY)
+
+ IF(QT_GOBJECT_LIBRARY)
+ SET(QT_QTCORE_LIB_DEPENDENCIES ${QT_QTCORE_LIB_DEPENDENCIES}
+ ${QT_GOBJECT_LIBRARY})
+ ENDIF(QT_GOBJECT_LIBRARY)
+ ENDIF(QT_VERSION_MINOR GREATER 4)
+
+ENDIF(QT_QCONFIG MATCHES "glib")
+
+
+## clock-monotonic, just see if we need to link with rt
+IF(QT_QCONFIG MATCHES "clock-monotonic")
+ SET(CMAKE_REQUIRED_LIBRARIES_SAVE ${CMAKE_REQUIRED_LIBRARIES})
+ SET(CMAKE_REQUIRED_LIBRARIES rt)
+ CHECK_SYMBOL_EXISTS(_POSIX_TIMERS "unistd.h;time.h" QT_POSIX_TIMERS)
+ SET(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES_SAVE})
+ IF(QT_POSIX_TIMERS)
+ FIND_LIBRARY(QT_RT_LIBRARY NAMES rt)
+ MARK_AS_ADVANCED(QT_RT_LIBRARY)
+ IF(QT_RT_LIBRARY)
+ SET(QT_QTCORE_LIB_DEPENDENCIES ${QT_QTCORE_LIB_DEPENDENCIES} ${QT_RT_LIBRARY})
+ ENDIF(QT_RT_LIBRARY)
+ ENDIF(QT_POSIX_TIMERS)
+ENDIF(QT_QCONFIG MATCHES "clock-monotonic")
+
+
+IF(Q_WS_X11)
+ # X11 libraries Qt always depends on
+ SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} ${X11_Xext_LIB} ${X11_X11_LIB})
+
+ set(CMAKE_THREAD_PREFER_PTHREADS 1)
+ find_package(Threads)
+ if(CMAKE_USE_PTHREADS_INIT)
+ SET(QT_QTCORE_LIB_DEPENDENCIES ${QT_QTCORE_LIB_DEPENDENCIES} ${CMAKE_THREAD_LIBS_INIT})
+ endif(CMAKE_USE_PTHREADS_INIT)
+
+ SET (QT_QTCORE_LIB_DEPENDENCIES ${QT_QTCORE_LIB_DEPENDENCIES} ${CMAKE_DL_LIBS})
+
+ENDIF(Q_WS_X11)
+
+
+IF(Q_WS_WIN)
+ SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} imm32 winmm)
+ SET(QT_QTCORE_LIB_DEPENDENCIES ${QT_QTCORE_LIB_DEPENDENCIES} ws2_32)
+ENDIF(Q_WS_WIN)
+
+
+IF(Q_WS_MAC)
+ SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} "-framework Carbon")
+
+ # Qt 4.0, 4.1, 4.2 use QuickTime
+ IF(QT_VERSION_MINOR LESS 3)
+ SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} "-framework QuickTime")
+ ENDIF(QT_VERSION_MINOR LESS 3)
+
+ # Qt 4.2+ use AppKit
+ IF(QT_VERSION_MINOR GREATER 1)
+ SET(QT_QTGUI_LIB_DEPENDENCIES ${QT_QTGUI_LIB_DEPENDENCIES} "-framework AppKit")
+ ENDIF(QT_VERSION_MINOR GREATER 1)
+
+ SET(QT_QTCORE_LIB_DEPENDENCIES ${QT_QTCORE_LIB_DEPENDENCIES} "-framework ApplicationServices")
+ENDIF(Q_WS_MAC)
+
diff --git a/Modules/Qt4Macros.cmake b/Modules/Qt4Macros.cmake
new file mode 100644
index 000000000..68f3c8085
--- /dev/null
+++ b/Modules/Qt4Macros.cmake
@@ -0,0 +1,441 @@
+# This file is included by FindQt4.cmake, don't include it directly.
+
+#=============================================================================
+# 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.)
+
+
+######################################
+#
+# Macros for building Qt files
+#
+######################################
+
+
+MACRO (QT4_EXTRACT_OPTIONS _qt4_files _qt4_options)
+ SET(${_qt4_files})
+ SET(${_qt4_options})
+ SET(_QT4_DOING_OPTIONS FALSE)
+ FOREACH(_currentArg ${ARGN})
+ IF ("${_currentArg}" STREQUAL "OPTIONS")
+ SET(_QT4_DOING_OPTIONS TRUE)
+ ELSE ("${_currentArg}" STREQUAL "OPTIONS")
+ IF(_QT4_DOING_OPTIONS)
+ LIST(APPEND ${_qt4_options} "${_currentArg}")
+ ELSE(_QT4_DOING_OPTIONS)
+ LIST(APPEND ${_qt4_files} "${_currentArg}")
+ ENDIF(_QT4_DOING_OPTIONS)
+ ENDIF ("${_currentArg}" STREQUAL "OPTIONS")
+ ENDFOREACH(_currentArg)
+ENDMACRO (QT4_EXTRACT_OPTIONS)
+
+
+# macro used to create the names of output files preserving relative dirs
+MACRO (QT4_MAKE_OUTPUT_FILE infile prefix ext outfile )
+ STRING(LENGTH ${CMAKE_CURRENT_BINARY_DIR} _binlength)
+ STRING(LENGTH ${infile} _infileLength)
+ SET(_checkinfile ${CMAKE_CURRENT_SOURCE_DIR})
+ IF(_infileLength GREATER _binlength)
+ STRING(SUBSTRING "${infile}" 0 ${_binlength} _checkinfile)
+ IF(_checkinfile STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
+ FILE(RELATIVE_PATH rel ${CMAKE_CURRENT_BINARY_DIR} ${infile})
+ ELSE(_checkinfile STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
+ FILE(RELATIVE_PATH rel ${CMAKE_CURRENT_SOURCE_DIR} ${infile})
+ ENDIF(_checkinfile STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
+ ELSE(_infileLength GREATER _binlength)
+ FILE(RELATIVE_PATH rel ${CMAKE_CURRENT_SOURCE_DIR} ${infile})
+ ENDIF(_infileLength GREATER _binlength)
+ IF(WIN32 AND rel MATCHES "^[a-zA-Z]:") # absolute path
+ STRING(REGEX REPLACE "^([a-zA-Z]):(.*)$" "\\1_\\2" rel "${rel}")
+ ENDIF(WIN32 AND rel MATCHES "^[a-zA-Z]:")
+ SET(_outfile "${CMAKE_CURRENT_BINARY_DIR}/${rel}")
+ STRING(REPLACE ".." "__" _outfile ${_outfile})
+ GET_FILENAME_COMPONENT(outpath ${_outfile} PATH)
+ GET_FILENAME_COMPONENT(_outfile ${_outfile} NAME_WE)
+ FILE(MAKE_DIRECTORY ${outpath})
+ SET(${outfile} ${outpath}/${prefix}${_outfile}.${ext})
+ENDMACRO (QT4_MAKE_OUTPUT_FILE )
+
+
+MACRO (QT4_GET_MOC_FLAGS _moc_flags)
+ SET(${_moc_flags})
+ GET_DIRECTORY_PROPERTY(_inc_DIRS INCLUDE_DIRECTORIES)
+
+ FOREACH(_current ${_inc_DIRS})
+ IF("${_current}" MATCHES "\\.framework/?$")
+ STRING(REGEX REPLACE "/[^/]+\\.framework" "" framework_path "${_current}")
+ SET(${_moc_flags} ${${_moc_flags}} "-F${framework_path}")
+ ELSE("${_current}" MATCHES "\\.framework/?$")
+ SET(${_moc_flags} ${${_moc_flags}} "-I${_current}")
+ ENDIF("${_current}" MATCHES "\\.framework/?$")
+ ENDFOREACH(_current ${_inc_DIRS})
+
+ GET_DIRECTORY_PROPERTY(_defines COMPILE_DEFINITIONS)
+ FOREACH(_current ${_defines})
+ SET(${_moc_flags} ${${_moc_flags}} "-D${_current}")
+ ENDFOREACH(_current ${_defines})
+
+ IF(Q_WS_WIN)
+ SET(${_moc_flags} ${${_moc_flags}} -DWIN32)
+ ENDIF(Q_WS_WIN)
+
+ENDMACRO(QT4_GET_MOC_FLAGS)
+
+
+# helper macro to set up a moc rule
+MACRO (QT4_CREATE_MOC_COMMAND infile outfile moc_flags moc_options)
+ # For Windows, create a parameters file to work around command line length limit
+ IF (WIN32)
+ # Pass the parameters in a file. Set the working directory to
+ # be that containing the parameters file and reference it by
+ # just the file name. This is necessary because the moc tool on
+ # MinGW builds does not seem to handle spaces in the path to the
+ # file given with the @ syntax.
+ GET_FILENAME_COMPONENT(_moc_outfile_name "${outfile}" NAME)
+ GET_FILENAME_COMPONENT(_moc_outfile_dir "${outfile}" PATH)
+ IF(_moc_outfile_dir)
+ SET(_moc_working_dir WORKING_DIRECTORY ${_moc_outfile_dir})
+ ENDIF(_moc_outfile_dir)
+ SET (_moc_parameters_file ${outfile}_parameters)
+ SET (_moc_parameters ${moc_flags} ${moc_options} -o "${outfile}" "${infile}")
+ STRING (REPLACE ";" "\n" _moc_parameters "${_moc_parameters}")
+ FILE (WRITE ${_moc_parameters_file} "${_moc_parameters}")
+ ADD_CUSTOM_COMMAND(OUTPUT ${outfile}
+ COMMAND ${QT_MOC_EXECUTABLE} @${_moc_outfile_name}_parameters
+ DEPENDS ${infile}
+ ${_moc_working_dir}
+ VERBATIM)
+ ELSE (WIN32)
+ ADD_CUSTOM_COMMAND(OUTPUT ${outfile}
+ COMMAND ${QT_MOC_EXECUTABLE}
+ ARGS ${moc_flags} ${moc_options} -o ${outfile} ${infile}
+ DEPENDS ${infile} VERBATIM)
+ ENDIF (WIN32)
+ENDMACRO (QT4_CREATE_MOC_COMMAND)
+
+
+MACRO (QT4_GENERATE_MOC infile outfile )
+# get include dirs and flags
+ QT4_GET_MOC_FLAGS(moc_flags)
+ GET_FILENAME_COMPONENT(abs_infile ${infile} ABSOLUTE)
+ SET(_outfile "${outfile}")
+ IF(NOT IS_ABSOLUTE "${outfile}")
+ SET(_outfile "${CMAKE_CURRENT_BINARY_DIR}/${outfile}")
+ ENDIF(NOT IS_ABSOLUTE "${outfile}")
+ QT4_CREATE_MOC_COMMAND(${abs_infile} ${_outfile} "${moc_flags}" "")
+ SET_SOURCE_FILES_PROPERTIES(${outfile} PROPERTIES SKIP_AUTOMOC TRUE) # dont run automoc on this file
+ENDMACRO (QT4_GENERATE_MOC)
+
+
+# QT4_WRAP_CPP(outfiles inputfile ... )
+
+MACRO (QT4_WRAP_CPP outfiles )
+ # get include dirs
+ QT4_GET_MOC_FLAGS(moc_flags)
+ QT4_EXTRACT_OPTIONS(moc_files moc_options ${ARGN})
+
+ FOREACH (it ${moc_files})
+ GET_FILENAME_COMPONENT(it ${it} ABSOLUTE)
+ QT4_MAKE_OUTPUT_FILE(${it} moc_ cxx outfile)
+ QT4_CREATE_MOC_COMMAND(${it} ${outfile} "${moc_flags}" "${moc_options}")
+ SET(${outfiles} ${${outfiles}} ${outfile})
+ ENDFOREACH(it)
+
+ENDMACRO (QT4_WRAP_CPP)
+
+
+# QT4_WRAP_UI(outfiles inputfile ... )
+
+MACRO (QT4_WRAP_UI outfiles )
+ QT4_EXTRACT_OPTIONS(ui_files ui_options ${ARGN})
+
+ FOREACH (it ${ui_files})
+ GET_FILENAME_COMPONENT(outfile ${it} NAME_WE)
+ GET_FILENAME_COMPONENT(infile ${it} ABSOLUTE)
+ SET(outfile ${CMAKE_CURRENT_BINARY_DIR}/ui_${outfile}.h)
+ ADD_CUSTOM_COMMAND(OUTPUT ${outfile}
+ COMMAND ${QT_UIC_EXECUTABLE}
+ ARGS ${ui_options} -o ${outfile} ${infile}
+ MAIN_DEPENDENCY ${infile} VERBATIM)
+ SET(${outfiles} ${${outfiles}} ${outfile})
+ ENDFOREACH (it)
+
+ENDMACRO (QT4_WRAP_UI)
+
+
+# QT4_ADD_RESOURCES(outfiles inputfile ... )
+
+MACRO (QT4_ADD_RESOURCES outfiles )
+ QT4_EXTRACT_OPTIONS(rcc_files rcc_options ${ARGN})
+
+ FOREACH (it ${rcc_files})
+ GET_FILENAME_COMPONENT(outfilename ${it} NAME_WE)
+ GET_FILENAME_COMPONENT(infile ${it} ABSOLUTE)
+ GET_FILENAME_COMPONENT(rc_path ${infile} PATH)
+ SET(outfile ${CMAKE_CURRENT_BINARY_DIR}/qrc_${outfilename}.cxx)
+
+ SET(_RC_DEPENDS)
+ IF(EXISTS "${infile}")
+ # parse file for dependencies
+ # all files are absolute paths or relative to the location of the qrc file
+ FILE(READ "${infile}" _RC_FILE_CONTENTS)
+ STRING(REGEX MATCHALL "<file[^<]+" _RC_FILES "${_RC_FILE_CONTENTS}")
+ FOREACH(_RC_FILE ${_RC_FILES})
+ STRING(REGEX REPLACE "^<file[^>]*>" "" _RC_FILE "${_RC_FILE}")
+ IF(NOT IS_ABSOLUTE "${_RC_FILE}")
+ SET(_RC_FILE "${rc_path}/${_RC_FILE}")
+ ENDIF(NOT IS_ABSOLUTE "${_RC_FILE}")
+ SET(_RC_DEPENDS ${_RC_DEPENDS} "${_RC_FILE}")
+ ENDFOREACH(_RC_FILE)
+ # Since this cmake macro is doing the dependency scanning for these files,
+ # 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)
+ ELSE(EXISTS "${infile}")
+ # The .qrc file does not exist (yet). Let's add a dependency and hope
+ # that it will be generated later
+ SET(out_depends)
+ ENDIF(EXISTS "${infile}")
+
+ ADD_CUSTOM_COMMAND(OUTPUT ${outfile}
+ COMMAND ${QT_RCC_EXECUTABLE}
+ ARGS ${rcc_options} -name ${outfilename} -o ${outfile} ${infile}
+ MAIN_DEPENDENCY ${infile}
+ DEPENDS ${_RC_DEPENDS} "${out_depends}" VERBATIM)
+ SET(${outfiles} ${${outfiles}} ${outfile})
+ ENDFOREACH (it)
+
+ENDMACRO (QT4_ADD_RESOURCES)
+
+
+MACRO(QT4_ADD_DBUS_INTERFACE _sources _interface _basename)
+ GET_FILENAME_COMPONENT(_infile ${_interface} ABSOLUTE)
+ SET(_header "${CMAKE_CURRENT_BINARY_DIR}/${_basename}.h")
+ SET(_impl "${CMAKE_CURRENT_BINARY_DIR}/${_basename}.cpp")
+ SET(_moc "${CMAKE_CURRENT_BINARY_DIR}/${_basename}.moc")
+
+ GET_SOURCE_FILE_PROPERTY(_nonamespace ${_interface} NO_NAMESPACE)
+ IF(_nonamespace)
+ SET(_params -N -m)
+ ELSE(_nonamespace)
+ SET(_params -m)
+ ENDIF(_nonamespace)
+
+ GET_SOURCE_FILE_PROPERTY(_classname ${_interface} CLASSNAME)
+ IF(_classname)
+ SET(_params ${_params} -c ${_classname})
+ ENDIF(_classname)
+
+ GET_SOURCE_FILE_PROPERTY(_include ${_interface} INCLUDE)
+ IF(_include)
+ SET(_params ${_params} -i ${_include})
+ ENDIF(_include)
+
+ ADD_CUSTOM_COMMAND(OUTPUT "${_impl}" "${_header}"
+ COMMAND ${QT_DBUSXML2CPP_EXECUTABLE} ${_params} -p ${_basename} ${_infile}
+ DEPENDS ${_infile} VERBATIM)
+
+ SET_SOURCE_FILES_PROPERTIES("${_impl}" PROPERTIES SKIP_AUTOMOC TRUE)
+
+ QT4_GENERATE_MOC("${_header}" "${_moc}")
+
+ LIST(APPEND ${_sources} "${_impl}" "${_header}" "${_moc}")
+ MACRO_ADD_FILE_DEPENDENCIES("${_impl}" "${_moc}")
+
+ENDMACRO(QT4_ADD_DBUS_INTERFACE)
+
+
+MACRO(QT4_ADD_DBUS_INTERFACES _sources)
+ FOREACH (_current_FILE ${ARGN})
+ GET_FILENAME_COMPONENT(_infile ${_current_FILE} ABSOLUTE)
+ GET_FILENAME_COMPONENT(_basename ${_current_FILE} NAME)
+ # get the part before the ".xml" suffix
+ STRING(TOLOWER ${_basename} _basename)
+ STRING(REGEX REPLACE "(.*\\.)?([^\\.]+)\\.xml" "\\2" _basename ${_basename})
+ QT4_ADD_DBUS_INTERFACE(${_sources} ${_infile} ${_basename}interface)
+ ENDFOREACH (_current_FILE)
+ENDMACRO(QT4_ADD_DBUS_INTERFACES)
+
+
+MACRO(QT4_GENERATE_DBUS_INTERFACE _header) # _customName OPTIONS -some -options )
+ QT4_EXTRACT_OPTIONS(_customName _qt4_dbus_options ${ARGN})
+
+ GET_FILENAME_COMPONENT(_in_file ${_header} ABSOLUTE)
+ GET_FILENAME_COMPONENT(_basename ${_header} NAME_WE)
+
+ IF (_customName)
+ if (IS_ABSOLUTE ${_customName})
+ get_filename_component(_containingDir ${_customName} PATH)
+ if (NOT EXISTS ${_containingDir})
+ file(MAKE_DIRECTORY "${_containingDir}")
+ endif()
+ SET(_target ${_customName})
+ else()
+ SET(_target ${CMAKE_CURRENT_BINARY_DIR}/${_customName})
+ endif()
+ ELSE (_customName)
+ SET(_target ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.xml)
+ ENDIF (_customName)
+
+ ADD_CUSTOM_COMMAND(OUTPUT ${_target}
+ COMMAND ${QT_DBUSCPP2XML_EXECUTABLE} ${_qt4_dbus_options} ${_in_file} -o ${_target}
+ DEPENDS ${_in_file} VERBATIM
+ )
+ENDMACRO(QT4_GENERATE_DBUS_INTERFACE)
+
+
+MACRO(QT4_ADD_DBUS_ADAPTOR _sources _xml_file _include _parentClass) # _optionalBasename _optionalClassName)
+ GET_FILENAME_COMPONENT(_infile ${_xml_file} ABSOLUTE)
+
+ SET(_optionalBasename "${ARGV4}")
+ IF (_optionalBasename)
+ SET(_basename ${_optionalBasename} )
+ ELSE (_optionalBasename)
+ STRING(REGEX REPLACE "(.*[/\\.])?([^\\.]+)\\.xml" "\\2adaptor" _basename ${_infile})
+ STRING(TOLOWER ${_basename} _basename)
+ ENDIF (_optionalBasename)
+
+ SET(_optionalClassName "${ARGV5}")
+ 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}
+ DEPENDS ${_infile} VERBATIM
+ )
+ ELSE(_optionalClassName)
+ ADD_CUSTOM_COMMAND(OUTPUT "${_impl}" "${_header}"
+ COMMAND ${QT_DBUSXML2CPP_EXECUTABLE} -m -a ${_basename} -i ${_include} -l ${_parentClass} ${_infile}
+ DEPENDS ${_infile} VERBATIM
+ )
+ ENDIF(_optionalClassName)
+
+ QT4_GENERATE_MOC("${_header}" "${_moc}")
+ SET_SOURCE_FILES_PROPERTIES("${_impl}" PROPERTIES SKIP_AUTOMOC TRUE)
+ MACRO_ADD_FILE_DEPENDENCIES("${_impl}" "${_moc}")
+
+ LIST(APPEND ${_sources} "${_impl}" "${_header}" "${_moc}")
+ENDMACRO(QT4_ADD_DBUS_ADAPTOR)
+
+
+MACRO(QT4_AUTOMOC)
+ QT4_GET_MOC_FLAGS(_moc_INCS)
+
+ SET(_matching_FILES )
+ FOREACH (_current_FILE ${ARGN})
+
+ GET_FILENAME_COMPONENT(_abs_FILE ${_current_FILE} ABSOLUTE)
+ # if "SKIP_AUTOMOC" is set to true, we will not handle this file here.
+ # This is required to make uic work correctly:
+ # we need to add generated .cpp files to the sources (to compile them),
+ # but we cannot let automoc handle them, as the .cpp files don't exist yet when
+ # cmake is run for the very first time on them -> however the .cpp files might
+ # exist at a later run. at that time we need to skip them, so that we don't add two
+ # different rules for the same moc file
+ GET_SOURCE_FILE_PROPERTY(_skip ${_abs_FILE} SKIP_AUTOMOC)
+
+ IF ( NOT _skip AND EXISTS ${_abs_FILE} )
+
+ FILE(READ ${_abs_FILE} _contents)
+
+ GET_FILENAME_COMPONENT(_abs_PATH ${_abs_FILE} PATH)
+
+ STRING(REGEX MATCHALL "# *include +[^ ]+\\.moc[\">]" _match "${_contents}")
+ IF(_match)
+ FOREACH (_current_MOC_INC ${_match})
+ STRING(REGEX MATCH "[^ <\"]+\\.moc" _current_MOC "${_current_MOC_INC}")
+
+ GET_FILENAME_COMPONENT(_basename ${_current_MOC} NAME_WE)
+ IF(EXISTS ${_abs_PATH}/${_basename}.hpp)
+ SET(_header ${_abs_PATH}/${_basename}.hpp)
+ ELSE(EXISTS ${_abs_PATH}/${_basename}.hpp)
+ SET(_header ${_abs_PATH}/${_basename}.h)
+ ENDIF(EXISTS ${_abs_PATH}/${_basename}.hpp)
+ SET(_moc ${CMAKE_CURRENT_BINARY_DIR}/${_current_MOC})
+ QT4_CREATE_MOC_COMMAND(${_header} ${_moc} "${_moc_INCS}" "")
+ MACRO_ADD_FILE_DEPENDENCIES(${_abs_FILE} ${_moc})
+ ENDFOREACH (_current_MOC_INC)
+ ENDIF(_match)
+ ENDIF ( NOT _skip AND EXISTS ${_abs_FILE} )
+ ENDFOREACH (_current_FILE)
+ENDMACRO(QT4_AUTOMOC)
+
+
+MACRO(QT4_CREATE_TRANSLATION _qm_files)
+ QT4_EXTRACT_OPTIONS(_lupdate_files _lupdate_options ${ARGN})
+ SET(_my_sources)
+ SET(_my_dirs)
+ SET(_my_tsfiles)
+ SET(_ts_pro)
+ FOREACH (_file ${_lupdate_files})
+ GET_FILENAME_COMPONENT(_ext ${_file} EXT)
+ GET_FILENAME_COMPONENT(_abs_FILE ${_file} ABSOLUTE)
+ IF(_ext MATCHES "ts")
+ LIST(APPEND _my_tsfiles ${_abs_FILE})
+ ELSE(_ext MATCHES "ts")
+ IF(NOT _ext)
+ LIST(APPEND _my_dirs ${_abs_FILE})
+ ELSE(NOT _ext)
+ LIST(APPEND _my_sources ${_abs_FILE})
+ ENDIF(NOT _ext)
+ ENDIF(_ext MATCHES "ts")
+ ENDFOREACH(_file)
+ FOREACH(_ts_file ${_my_tsfiles})
+ IF(_my_sources)
+ # make a .pro file to call lupdate on, so we don't make our commands too
+ # long for some systems
+ GET_FILENAME_COMPONENT(_ts_name ${_ts_file} NAME_WE)
+ 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}\"")
+ ENDFOREACH(_pro_src ${_my_sources})
+ SET(_pro_includes)
+ GET_DIRECTORY_PROPERTY(_inc_DIRS INCLUDE_DIRECTORIES)
+ FOREACH(_pro_include ${_inc_DIRS})
+ GET_FILENAME_COMPONENT(_abs_include "${_pro_include}" ABSOLUTE)
+ SET(_pro_includes "${_pro_includes} \"${_abs_include}\"")
+ ENDFOREACH(_pro_include ${CMAKE_CXX_INCLUDE_PATH})
+ FILE(WRITE ${_ts_pro} "SOURCES = ${_pro_srcs}\nINCLUDEPATH = ${_pro_includes}\n")
+ ENDIF(_my_sources)
+ ADD_CUSTOM_COMMAND(OUTPUT ${_ts_file}
+ COMMAND ${QT_LUPDATE_EXECUTABLE}
+ ARGS ${_lupdate_options} ${_ts_pro} ${_my_dirs} -ts ${_ts_file}
+ DEPENDS ${_my_sources} ${_ts_pro} VERBATIM)
+ ENDFOREACH(_ts_file)
+ QT4_ADD_TRANSLATION(${_qm_files} ${_my_tsfiles})
+ENDMACRO(QT4_CREATE_TRANSLATION)
+
+
+MACRO(QT4_ADD_TRANSLATION _qm_files)
+ FOREACH (_current_FILE ${ARGN})
+ GET_FILENAME_COMPONENT(_abs_FILE ${_current_FILE} ABSOLUTE)
+ GET_FILENAME_COMPONENT(qm ${_abs_FILE} NAME_WE)
+ GET_SOURCE_FILE_PROPERTY(output_location ${_abs_FILE} OUTPUT_LOCATION)
+ IF(output_location)
+ FILE(MAKE_DIRECTORY "${output_location}")
+ SET(qm "${output_location}/${qm}.qm")
+ ELSE(output_location)
+ SET(qm "${CMAKE_CURRENT_BINARY_DIR}/${qm}.qm")
+ ENDIF(output_location)
+
+ ADD_CUSTOM_COMMAND(OUTPUT ${qm}
+ COMMAND ${QT_LRELEASE_EXECUTABLE}
+ ARGS ${_abs_FILE} -qm ${qm}
+ DEPENDS ${_abs_FILE} VERBATIM
+ )
+ SET(${_qm_files} ${${_qm_files}} ${qm})
+ ENDFOREACH (_current_FILE)
+ENDMACRO(QT4_ADD_TRANSLATION)
diff --git a/Modules/RepositoryInfo.txt.in b/Modules/RepositoryInfo.txt.in
new file mode 100644
index 000000000..df8e32272
--- /dev/null
+++ b/Modules/RepositoryInfo.txt.in
@@ -0,0 +1,3 @@
+repository='@repository@'
+module='@module@'
+tag='@tag@'
diff --git a/Modules/SelectLibraryConfigurations.cmake b/Modules/SelectLibraryConfigurations.cmake
new file mode 100644
index 000000000..2e8ade0df
--- /dev/null
+++ b/Modules/SelectLibraryConfigurations.cmake
@@ -0,0 +1,81 @@
+# 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, basename_LIBRARY_DEBUG,
+# and basename_LIBRARY_RELEASE will be set to the release value. If only
+# basename_LIBRARY_DEBUG is defined, then basename_LIBRARY,
+# basename_LIBRARY_DEBUG and basename_LIBRARY_RELEASE will take the debug value.
+#
+# 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 values.
+
+#=============================================================================
+# Copyright 2009 Will Dicharry <wdicharry@stellarscience.com>
+# 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.)
+
+# This macro was adapted from the FindQt4 CMake module and is maintained by Will
+# Dicharry <wdicharry@stellarscience.com>.
+
+# Utility macro to check if one variable exists while another doesn't, and set
+# one that doesn't exist to the one that exists.
+macro( _set_library_name basename GOOD BAD )
+ if( ${basename}_LIBRARY_${GOOD} AND NOT ${basename}_LIBRARY_${BAD} )
+ set( ${basename}_LIBRARY_${BAD} ${${basename}_LIBRARY_${GOOD}} )
+ set( ${basename}_LIBRARY ${${basename}_LIBRARY_${GOOD}} )
+ set( ${basename}_LIBRARIES ${${basename}_LIBRARY_${GOOD}} )
+ endif( ${basename}_LIBRARY_${GOOD} AND NOT ${basename}_LIBRARY_${BAD} )
+endmacro( _set_library_name )
+
+macro( select_library_configurations basename )
+ # if only the release version was found, set the debug to be the release
+ # version.
+ _set_library_name( ${basename} RELEASE DEBUG )
+ # if only the debug version was found, set the release value to be the
+ # debug value.
+ _set_library_name( ${basename} DEBUG RELEASE )
+ if (${basename}_LIBRARY_DEBUG AND ${basename}_LIBRARY_RELEASE AND
+ NOT ${basename}_LIBRARY_DEBUG STREQUAL ${basename}_LIBRARY_RELEASE)
+ # if the generator supports configuration types or CMAKE_BUILD_TYPE
+ # is set, then set optimized and debug options.
+ if( CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE )
+ set( ${basename}_LIBRARY
+ optimized ${${basename}_LIBRARY_RELEASE}
+ debug ${${basename}_LIBRARY_DEBUG} )
+ set( ${basename}_LIBRARIES
+ optimized ${${basename}_LIBRARY_RELEASE}
+ debug ${${basename}_LIBRARY_DEBUG} )
+ else( CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE )
+ # If there are no configuration types or build type, just use
+ # the release version
+ set( ${basename}_LIBRARY ${${basename}_LIBRARY_RELEASE} )
+ set( ${basename}_LIBRARIES ${${basename}_LIBRARY_RELEASE} )
+ endif( CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE )
+ endif()
+
+ set( ${basename}_LIBRARY ${${basename}_LIBRARY} CACHE FILEPATH
+ "The ${basename} library" )
+
+ if( ${basename}_LIBRARY )
+ set( ${basename}_FOUND TRUE )
+ endif( ${basename}_LIBRARY )
+
+ mark_as_advanced( ${basename}_LIBRARY
+ ${basename}_LIBRARY_RELEASE
+ ${basename}_LIBRARY_DEBUG
+ )
+endmacro( select_library_configurations )
diff --git a/Modules/SquishRunTestCase.bat b/Modules/SquishRunTestCase.bat
new file mode 100755
index 000000000..5c5d388b0
--- /dev/null
+++ b/Modules/SquishRunTestCase.bat
@@ -0,0 +1,11 @@
+echo 'Starting the squish server...'
+start %1
+
+echo 'Running the test case...'
+%2 --testcase %3 --wrapper %4 --aut %5
+set result=%ERRORLEVEL%
+
+echo 'Stopping the squish server...'
+%1 --stop
+
+exit \b %result%
diff --git a/Modules/SquishRunTestCase.sh b/Modules/SquishRunTestCase.sh
new file mode 100755
index 000000000..409b46a3e
--- /dev/null
+++ b/Modules/SquishRunTestCase.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+echo "Starting the squish server...$1 --daemon"
+$1 --daemon
+
+echo "Running the test case...$2 --testcase $3 --wrapper $4 --aut $5"
+$2 --testcase $3 --wrapper $4 --aut $5
+returnValue=$?
+
+echo "Stopping the squish server...$1 --stop"
+$1 --stop
+
+exit $returnValue
diff --git a/Modules/SquishTestScript.cmake b/Modules/SquishTestScript.cmake
new file mode 100644
index 000000000..9eac9707f
--- /dev/null
+++ b/Modules/SquishTestScript.cmake
@@ -0,0 +1,72 @@
+#
+# 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.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software 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.)
+
+cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
+
+# print out the variable that we are using
+message(STATUS "squish_aut='${squish_aut}'")
+
+message(STATUS "squish_server_executable='${squish_server_executable}'")
+message(STATUS "squish_client_executable='${squish_client_executable}'")
+message(STATUS "squish_libqtdir ='${squish_libqtdir}'")
+message(STATUS "squish_test_case='${squish_test_case}'")
+message(STATUS "squish_wrapper='${squish_wrapper}'")
+message(STATUS "squish_env_vars='${squish_env_vars}'")
+
+# parse enviornment variables
+foreach(i ${squish_env_vars})
+ message(STATUS "parsing env var key/value pair ${i}")
+ string(REGEX MATCH "([^=]*)=(.*)" squish_env_name ${i})
+ message(STATUS "key=${CMAKE_MATCH_1}")
+ message(STATUS "value=${CMAKE_MATCH_2}")
+ set ( ENV{${CMAKE_MATCH_1}} ${CMAKE_MATCH_2} )
+endforeach()
+
+if (QT4_INSTALLED)
+ # record qt lib directory
+ set ( ENV{${SQUISH_LIBQTDIR}} ${squish_libqtdir} )
+endif (QT4_INSTALLED)
+
+# run the test
+if (WIN32)
+ execute_process(
+ COMMAND ${CMAKE_ROOT}/Modules/SquishRunTestCase.bat ${squish_server_executable} ${squish_client_executable} ${squish_test_case} ${squish_wrapper} ${squish_aut}
+ RESULT_VARIABLE test_rv
+ )
+endif (WIN32)
+
+if (UNIX)
+ execute_process(
+ COMMAND ${CMAKE_ROOT}/Modules/SquishRunTestCase.sh ${squish_server_executable} ${squish_client_executable} ${squish_test_case} ${squish_wrapper} ${squish_aut}
+ RESULT_VARIABLE test_rv
+ )
+endif (UNIX)
+
+# check for an error with running the test
+if(NOT "${test_rv}" STREQUAL "0")
+ message(FATAL_ERROR "Error running Squish test")
+endif(NOT "${test_rv}" STREQUAL "0")
+
+
+
diff --git a/Modules/SystemInformation.cmake b/Modules/SystemInformation.cmake
new file mode 100644
index 000000000..d4f22331d
--- /dev/null
+++ b/Modules/SystemInformation.cmake
@@ -0,0 +1,103 @@
+
+#=============================================================================
+# Copyright 2007-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.)
+
+CMAKE_MINIMUM_REQUIRED(VERSION ${CMAKE_VERSION})
+PROJECT(DumpInformation)
+
+# first get the standard information for th platform
+INCLUDE_DIRECTORIES("This does not exists")
+GET_DIRECTORY_PROPERTY(incl INCLUDE_DIRECTORIES)
+SET_DIRECTORY_PROPERTIES(PROPERTIES INCLUDE_DIRECTORIES "${DumpInformation_BINARY_DIR};${DumpInformation_SOURCE_DIR}")
+
+CONFIGURE_FILE("${CMAKE_ROOT}/Modules/SystemInformation.in" "${RESULT_FILE}")
+
+
+FILE(APPEND "${RESULT_FILE}"
+ "\n=================================================================\n")
+FILE(APPEND "${RESULT_FILE}"
+ "=== VARIABLES\n")
+FILE(APPEND "${RESULT_FILE}"
+ "=================================================================\n")
+GET_CMAKE_PROPERTY(res VARIABLES)
+FOREACH(var ${res})
+ FILE(APPEND "${RESULT_FILE}" "${var} \"${${var}}\"\n")
+ENDFOREACH(var ${res})
+
+FILE(APPEND "${RESULT_FILE}"
+ "\n=================================================================\n")
+FILE(APPEND "${RESULT_FILE}"
+ "=== COMMANDS\n")
+FILE(APPEND "${RESULT_FILE}"
+ "=================================================================\n")
+GET_CMAKE_PROPERTY(res COMMANDS)
+FOREACH(var ${res})
+ FILE(APPEND "${RESULT_FILE}" "${var}\n")
+ENDFOREACH(var ${res})
+
+FILE(APPEND "${RESULT_FILE}"
+ "\n=================================================================\n")
+FILE(APPEND "${RESULT_FILE}"
+ "=== MACROS\n")
+FILE(APPEND "${RESULT_FILE}"
+ "=================================================================\n")
+FILE(WRITE ${CMAKE_CURRENT_BINARY_DIR}/AllMacros.txt "")
+GET_CMAKE_PROPERTY(res MACROS)
+FOREACH(var ${res})
+ FILE(APPEND "${RESULT_FILE}" "${var}\n")
+ENDFOREACH(var ${res})
+
+FILE(APPEND "${RESULT_FILE}"
+ "\n=================================================================\n")
+FILE(APPEND "${RESULT_FILE}"
+ "=== OTHER\n")
+FILE(APPEND "${RESULT_FILE}"
+ "=================================================================\n")
+GET_DIRECTORY_PROPERTY(res INCLUDE_DIRECTORIES)
+FOREACH(var ${res})
+ FILE(APPEND "${RESULT_FILE}" "INCLUDE_DIRECTORY: ${var}\n")
+ENDFOREACH(var)
+
+GET_DIRECTORY_PROPERTY(res LINK_DIRECTORIES)
+FOREACH(var ${res})
+ FILE(APPEND "${RESULT_FILE}" "LINK_DIRECTORIES: ${var}\n")
+ENDFOREACH(var)
+
+GET_DIRECTORY_PROPERTY(res INCLUDE_REGULAR_EXPRESSION)
+FILE(APPEND "${RESULT_FILE}" "INCLUDE_REGULAR_EXPRESSION: ${res}\n")
+
+# include other files if they are present, such as when run from within the
+# binary tree
+MACRO(DUMP_FILE THE_FILE)
+ IF (EXISTS "${THE_FILE}")
+ FILE(APPEND "${RESULT_FILE}"
+ "\n=================================================================\n")
+ FILE(APPEND "${RESULT_FILE}"
+ "=== ${THE_FILE}\n")
+ FILE(APPEND "${RESULT_FILE}"
+ "=================================================================\n")
+
+ FILE(READ "${THE_FILE}" FILE_CONTENTS LIMIT 50000)
+ FILE(APPEND "${RESULT_FILE}" "${FILE_CONTENTS}")
+ ENDIF (EXISTS "${THE_FILE}")
+ENDMACRO(DUMP_FILE)
+
+DUMP_FILE("../CMakeCache.txt")
+DUMP_FILE("../CMakeFiles/CMakeOutput.log")
+DUMP_FILE("../CMakeFiles/CMakeError.log")
+DUMP_FILE("../CMakeFiles/CMakeSystem.cmake")
+
+FOREACH (EXTRA_FILE ${EXTRA_DUMP_FILES})
+ DUMP_FILE("${EXTRA_FILE}")
+ENDFOREACH (EXTRA_FILE)
+
diff --git a/Modules/SystemInformation.in b/Modules/SystemInformation.in
new file mode 100644
index 000000000..f2aef5055
--- /dev/null
+++ b/Modules/SystemInformation.in
@@ -0,0 +1,88 @@
+Avoid ctest truncation of output: CTEST_FULL_OUTPUT
+========================================================
+=== MAIN VARIABLES
+========================================================
+CMAKE_STATIC_LIBRARY_PREFIX == "${CMAKE_STATIC_LIBRARY_PREFIX}"
+CMAKE_STATIC_LIBRARY_SUFFIX == "${CMAKE_STATIC_LIBRARY_SUFFIX}"
+CMAKE_SHARED_LIBRARY_PREFIX == "${CMAKE_SHARED_LIBRARY_PREFIX}"
+CMAKE_SHARED_LIBRARY_SUFFIX == "${CMAKE_SHARED_LIBRARY_SUFFIX}"
+CMAKE_SHARED_MODULE_PREFIX == "${CMAKE_SHARED_MODULE_PREFIX}"
+CMAKE_SHARED_MODULE_SUFFIX == "${CMAKE_SHARED_MODULE_SUFFIX}"
+
+
+CMAKE_DL_LIBS == "${CMAKE_DL_LIBS}"
+CMAKE_LIBRARY_PATH_FLAG == "${CMAKE_LIBRARY_PATH_FLAG}"
+CMAKE_LINK_LIBRARY_FLAG == "${CMAKE_LINK_LIBRARY_FLAG}"
+CMAKE_SKIP_RPATH == "${CMAKE_SKIP_RPATH}"
+CMAKE_SYSTEM_INFO_FILE == "${CMAKE_SYSTEM_INFO_FILE}"
+CMAKE_SYSTEM_NAME == "${CMAKE_SYSTEM_NAME}"
+CMAKE_SYSTEM == "${CMAKE_SYSTEM}"
+CMAKE_CXX_COMPILER == "${CMAKE_CXX_COMPILER}"
+CMAKE_C_COMPILER == "${CMAKE_C_COMPILER}"
+CMAKE_COMPILER_IS_GNUCC == "${CMAKE_COMPILER_IS_GNUCC}"
+CMAKE_COMPILER_IS_GNUCXX == "${CMAKE_COMPILER_IS_GNUCXX}"
+
+// C shared library flag
+CMAKE_SHARED_LIBRARY_C_FLAGS == "${CMAKE_SHARED_LIBRARY_C_FLAGS}"
+CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS == "${CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS}"
+CMAKE_SHARED_LIBRARY_LINK_FLAGS == "${CMAKE_SHARED_LIBRARY_LINK_FLAGS}"
+CMAKE_SHARED_LIBRARY_RUNTIME_FLAG == "${CMAKE_SHARED_LIBRARY_RUNTIME_FLAG}"
+CMAKE_SHARED_LIBRARY_RUNTIME_FLAG_SEP == "${CMAKE_SHARED_LIBRARY_RUNTIME_FLAG_SEP}"
+CMAKE_SHARED_LIBRARY_LINK_STATIC_C_FLAGS == "${CMAKE_SHARED_LIBRARY_LINK_STATIC_C_FLAGS}"
+CMAKE_SHARED_LIBRARY_LINK_DYNAMIC_C_FLAGS == "${CMAKE_SHARED_LIBRARY_LINK_DYNAMIC_C_FLAGS}"
+
+// C shared module flags
+CMAKE_SHARED_MODULE_C_FLAGS == "${CMAKE_SHARED_MODULE_C_FLAGS}"
+CMAKE_SHARED_MODULE_CREATE_C_FLAGS == "${CMAKE_SHARED_MODULE_CREATE_C_FLAGS}"
+CMAKE_SHARED_MODULE_LINK_STATIC_C_FLAGS == "${CMAKE_SHARED_MODULE_LINK_STATIC_C_FLAGS}"
+CMAKE_SHARED_MODULE_LINK_DYNAMIC_C_FLAGS == "${CMAKE_SHARED_MODULE_LINK_DYNAMIC_C_FLAGS}"
+
+// C exe flags
+CMAKE_EXE_LINK_STATIC_C_FLAGS == "${CMAKE_EXE_LINK_STATIC_C_FLAGS}"
+CMAKE_EXE_LINK_DYNAMIC_C_FLAGS == "${CMAKE_EXE_LINK_DYNAMIC_C_FLAGS}"
+
+// CXX shared library flags
+CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS == "${CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS}"
+CMAKE_SHARED_LIBRARY_CXX_FLAGS == "${CMAKE_SHARED_LIBRARY_CXX_FLAGS}"
+CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS == "${CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS}"
+CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG == "${CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG}"
+CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG_SEP == "${CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG_SEP}"
+CMAKE_SHARED_LIBRARY_LINK_STATIC_CXX_FLAGS == "${CMAKE_SHARED_LIBRARY_LINK_STATIC_CXX_FLAGS}"
+CMAKE_SHARED_LIBRARY_LINK_DYNAMIC_CXX_FLAGS == "${CMAKE_SHARED_LIBRARY_LINK_DYNAMIC_CXX_FLAGS}"
+
+// CXX shared module flags
+CMAKE_SHARED_MODULE_CREATE_CXX_FLAGS == "${CMAKE_SHARED_MODULE_CREATE_CXX_FLAGS}"
+CMAKE_SHARED_MODULE_CXX_FLAGS == "${CMAKE_SHARED_MODULE_CXX_FLAGS}"
+CMAKE_SHARED_MODULE_LINK_STATIC_CXX_FLAGS == "${CMAKE_SHARED_MODULE_LINK_STATIC_CXX_FLAGS}"
+CMAKE_SHARED_MODULE_LINK_DYNAMIC_CXX_FLAGS == "${CMAKE_SHARED_MODULE_LINK_DYNAMIC_CXX_FLAGS}"
+
+// CXX exe flags
+CMAKE_EXE_LINK_STATIC_CXX_FLAGS == "${CMAKE_EXE_LINK_STATIC_CXX_FLAGS}"
+CMAKE_EXE_LINK_DYNAMIC_CXX_FLAGS == "${CMAKE_EXE_LINK_DYNAMIC_CXX_FLAGS}"
+
+CMAKE_USER_MAKE_RULES_OVERRIDE == "${CMAKE_USER_MAKE_RULES_OVERRIDE}"
+CMAKE_VERBOSE_MAKEFILE == "${CMAKE_VERBOSE_MAKEFILE}"
+CMAKE_BUILD_TYPE == "${CMAKE_BUILD_TYPE}"
+CMAKE_CXX_FLAGS == "${CMAKE_CXX_FLAGS}"
+CMAKE_CXX_FLAGS_DEBUG == "${CMAKE_CXX_FLAGS_DEBUG}"
+CMAKE_CXX_FLAGS_MINSIZEREL == "${CMAKE_CXX_FLAGS_MINSIZEREL}"
+CMAKE_CXX_FLAGS_RELEASE == "${CMAKE_CXX_FLAGS_RELEASE}"
+CMAKE_CXX_FLAGS_RELWITHDEBINFO == "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}"
+
+CMAKE_C_FLAGS == "${CMAKE_C_FLAGS}"
+CMAKE_C_FLAGS_DEBUG == "${CMAKE_C_FLAGS_DEBUG}"
+CMAKE_C_FLAGS_MINSIZEREL == "${CMAKE_C_FLAGS_MINSIZEREL}"
+CMAKE_C_FLAGS_RELEASE == "${CMAKE_C_FLAGS_RELEASE}"
+CMAKE_C_FLAGS_RELWITHDEBINFO == "${CMAKE_C_FLAGS_RELWITHDEBINFO}"
+
+// build rules
+CMAKE_CXX_CREATE_SHARED_LIBRARY == "${CMAKE_CXX_CREATE_SHARED_LIBRARY}"
+CMAKE_CXX_CREATE_SHARED_MODULE == "${CMAKE_CXX_CREATE_SHARED_MODULE}"
+CMAKE_C_CREATE_SHARED_LIBRARY == "${CMAKE_C_CREATE_SHARED_LIBRARY}"
+CMAKE_C_CREATE_SHARED_MODULE == "${CMAKE_C_CREATE_SHARED_MODULE}"
+CMAKE_CXX_CREATE_STATIC_LIBRARY == "${CMAKE_CXX_CREATE_STATIC_LIBRARY}"
+CMAKE_C_CREATE_STATIC_LIBRARY == "${CMAKE_C_CREATE_STATIC_LIBRARY}"
+CMAKE_CXX_COMPILE_OBJECT == "${CMAKE_CXX_COMPILE_OBJECT}"
+CMAKE_C_COMPILE_OBJECT == "${CMAKE_C_COMPILE_OBJECT}"
+CMAKE_C_LINK_EXECUTABLE == "${CMAKE_C_LINK_EXECUTABLE}"
+CMAKE_CXX_LINK_EXECUTABLE == "${CMAKE_CXX_LINK_EXECUTABLE}"
diff --git a/Modules/TestBigEndian.cmake b/Modules/TestBigEndian.cmake
new file mode 100644
index 000000000..996060210
--- /dev/null
+++ b/Modules/TestBigEndian.cmake
@@ -0,0 +1,112 @@
+# - 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
+#
+
+#=============================================================================
+# 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.)
+
+MACRO(TEST_BIG_ENDIAN VARIABLE)
+ IF("HAVE_${VARIABLE}" MATCHES "^HAVE_${VARIABLE}$")
+ MESSAGE(STATUS "Check if the system is big endian")
+ MESSAGE(STATUS "Searching 16 bit integer")
+
+ INCLUDE(CheckTypeSize)
+
+ CHECK_TYPE_SIZE("unsigned short" CMAKE_SIZEOF_UNSIGNED_SHORT)
+ IF(CMAKE_SIZEOF_UNSIGNED_SHORT EQUAL 2)
+ MESSAGE(STATUS "Using unsigned short")
+ SET(CMAKE_16BIT_TYPE "unsigned short")
+ ELSE(CMAKE_SIZEOF_UNSIGNED_SHORT EQUAL 2)
+ CHECK_TYPE_SIZE("unsigned int" CMAKE_SIZEOF_UNSIGNED_INT)
+ IF(CMAKE_SIZEOF_UNSIGNED_INT)
+ MESSAGE(STATUS "Using unsigned int")
+ SET(CMAKE_16BIT_TYPE "unsigned int")
+
+ ELSE(CMAKE_SIZEOF_UNSIGNED_INT)
+
+ CHECK_TYPE_SIZE("unsigned long" CMAKE_SIZEOF_UNSIGNED_LONG)
+ IF(CMAKE_SIZEOF_UNSIGNED_LONG)
+ MESSAGE(STATUS "Using unsigned long")
+ SET(CMAKE_16BIT_TYPE "unsigned long")
+ ELSE(CMAKE_SIZEOF_UNSIGNED_LONG)
+ MESSAGE(FATAL_ERROR "no suitable type found")
+ ENDIF(CMAKE_SIZEOF_UNSIGNED_LONG)
+
+ ENDIF(CMAKE_SIZEOF_UNSIGNED_INT)
+
+ ENDIF(CMAKE_SIZEOF_UNSIGNED_SHORT EQUAL 2)
+
+
+ CONFIGURE_FILE("${CMAKE_ROOT}/Modules/TestEndianess.c.in"
+ "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/TestEndianess.c"
+ IMMEDIATE @ONLY)
+
+ FILE(READ "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/TestEndianess.c"
+ TEST_ENDIANESS_FILE_CONTENT)
+
+ TRY_COMPILE(HAVE_${VARIABLE}
+ "${CMAKE_BINARY_DIR}"
+ "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/TestEndianess.c"
+ OUTPUT_VARIABLE OUTPUT
+ COPY_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/TestEndianess.bin" )
+
+ IF(HAVE_${VARIABLE})
+
+ FILE(STRINGS "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/TestEndianess.bin"
+ CMAKE_TEST_ENDIANESS_STRINGS_LE LIMIT_COUNT 1 REGEX "THIS IS LITTLE ENDIAN")
+
+ FILE(STRINGS "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/TestEndianess.bin"
+ CMAKE_TEST_ENDIANESS_STRINGS_BE LIMIT_COUNT 1 REGEX "THIS IS BIG ENDIAN")
+
+ # on mac, if there are universal binaries built both will be true
+ # return the result depending on the machine on which cmake runs
+ IF(CMAKE_TEST_ENDIANESS_STRINGS_BE AND CMAKE_TEST_ENDIANESS_STRINGS_LE)
+ IF(CMAKE_SYSTEM_PROCESSOR MATCHES powerpc)
+ SET(CMAKE_TEST_ENDIANESS_STRINGS_BE TRUE)
+ SET(CMAKE_TEST_ENDIANESS_STRINGS_LE FALSE)
+ ELSE(CMAKE_SYSTEM_PROCESSOR MATCHES powerpc)
+ SET(CMAKE_TEST_ENDIANESS_STRINGS_BE FALSE)
+ SET(CMAKE_TEST_ENDIANESS_STRINGS_LE TRUE)
+ ENDIF(CMAKE_SYSTEM_PROCESSOR MATCHES powerpc)
+ MESSAGE(STATUS "TEST_BIG_ENDIAN found different results, consider setting CMAKE_OSX_ARCHITECTURES or CMAKE_TRY_COMPILE_OSX_ARCHITECTURES to one or no architecture !")
+ ENDIF(CMAKE_TEST_ENDIANESS_STRINGS_BE AND CMAKE_TEST_ENDIANESS_STRINGS_LE)
+
+ IF(CMAKE_TEST_ENDIANESS_STRINGS_LE)
+ SET(${VARIABLE} 0 CACHE INTERNAL "Result of TEST_BIG_ENDIAN" FORCE)
+ MESSAGE(STATUS "Check if the system is big endian - little endian")
+ ENDIF(CMAKE_TEST_ENDIANESS_STRINGS_LE)
+
+ IF(CMAKE_TEST_ENDIANESS_STRINGS_BE)
+ SET(${VARIABLE} 1 CACHE INTERNAL "Result of TEST_BIG_ENDIAN" FORCE)
+ MESSAGE(STATUS "Check if the system is big endian - big endian")
+ ENDIF(CMAKE_TEST_ENDIANESS_STRINGS_BE)
+
+ IF(NOT CMAKE_TEST_ENDIANESS_STRINGS_BE AND NOT CMAKE_TEST_ENDIANESS_STRINGS_LE)
+ MESSAGE(SEND_ERROR "TEST_BIG_ENDIAN found no result!")
+ ENDIF(NOT CMAKE_TEST_ENDIANESS_STRINGS_BE AND NOT CMAKE_TEST_ENDIANESS_STRINGS_LE)
+
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Determining if the system is big endian passed with the following output:\n${OUTPUT}\nTestEndianess.c:\n${TEST_ENDIANESS_FILE_CONTENT}\n\n")
+
+ ELSE(HAVE_${VARIABLE})
+ MESSAGE(STATUS "Check if the system is big endian - failed")
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Determining if the system is big endian failed with the following output:\n${OUTPUT}\nTestEndianess.c:\n${TEST_ENDIANESS_FILE_CONTENT}\n\n")
+ SET(${VARIABLE})
+ ENDIF(HAVE_${VARIABLE})
+ ENDIF("HAVE_${VARIABLE}" MATCHES "^HAVE_${VARIABLE}$")
+ENDMACRO(TEST_BIG_ENDIAN)
+
+
diff --git a/Modules/TestCXXAcceptsFlag.cmake b/Modules/TestCXXAcceptsFlag.cmake
new file mode 100644
index 000000000..52d0cf3e6
--- /dev/null
+++ b/Modules/TestCXXAcceptsFlag.cmake
@@ -0,0 +1,43 @@
+# - Test CXX compiler for a flag
+# Check if the CXX compiler accepts a flag
+#
+# Macro CHECK_CXX_ACCEPTS_FLAG(FLAGS VARIABLE) -
+# checks if the function exists
+# FLAGS - the flags to try
+# VARIABLE - variable to store the result
+#
+
+#=============================================================================
+# 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.)
+
+MACRO(CHECK_CXX_ACCEPTS_FLAG FLAGS VARIABLE)
+ IF(NOT DEFINED ${VARIABLE})
+ MESSAGE(STATUS "Checking to see if CXX compiler accepts flag ${FLAGS}")
+ TRY_COMPILE(${VARIABLE}
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_ROOT}/Modules/DummyCXXFile.cxx
+ CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${FLAGS}
+ OUTPUT_VARIABLE OUTPUT)
+ IF(${VARIABLE})
+ MESSAGE(STATUS "Checking to see if CXX compiler accepts flag ${FLAGS} - yes")
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "Determining if the CXX compiler accepts the flag ${FLAGS} passed with "
+ "the following output:\n${OUTPUT}\n\n")
+ ELSE(${VARIABLE})
+ MESSAGE(STATUS "Checking to see if CXX compiler accepts flag ${FLAGS} - no")
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Determining if the CXX compiler accepts the flag ${FLAGS} failed with "
+ "the following output:\n${OUTPUT}\n\n")
+ ENDIF(${VARIABLE})
+ ENDIF(NOT DEFINED ${VARIABLE})
+ENDMACRO(CHECK_CXX_ACCEPTS_FLAG)
diff --git a/Modules/TestEndianess.c.in b/Modules/TestEndianess.c.in
new file mode 100644
index 000000000..c924f7858
--- /dev/null
+++ b/Modules/TestEndianess.c.in
@@ -0,0 +1,23 @@
+/* A 16 bit integer is required. */
+typedef @CMAKE_16BIT_TYPE@ cmakeint16;
+
+/* On a little endian machine, these 16bit ints will give "THIS IS LITTLE ENDIAN."
+ On a big endian machine the characters will be exchanged pairwise. */
+const cmakeint16 info_little[] = {0x4854, 0x5349, 0x4920, 0x2053, 0x494c, 0x5454, 0x454c, 0x4520, 0x444e, 0x4149, 0x2e4e, 0x0000};
+
+/* on a big endian machine, these 16bit ints will give "THIS IS BIG ENDIAN."
+ On a little endian machine the characters will be exchanged pairwise. */
+const cmakeint16 info_big[] = {0x5448, 0x4953, 0x2049, 0x5320, 0x4249, 0x4720, 0x454e, 0x4449, 0x414e, 0x2e2e, 0x0000};
+
+#ifdef __CLASSIC_C__
+int main(argc, argv) int argc; char *argv[];
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ int require = 0;
+ require += info_little[argc];
+ require += info_big[argc];
+ (void)argv;
+ return require;
+}
diff --git a/Modules/TestForANSIForScope.cmake b/Modules/TestForANSIForScope.cmake
new file mode 100644
index 000000000..ae2acef7e
--- /dev/null
+++ b/Modules/TestForANSIForScope.cmake
@@ -0,0 +1,44 @@
+# - 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.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software 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_ANSI_FOR_SCOPE" MATCHES "^CMAKE_ANSI_FOR_SCOPE$")
+ MESSAGE(STATUS "Check for ANSI scope")
+ TRY_COMPILE(CMAKE_ANSI_FOR_SCOPE ${CMAKE_BINARY_DIR}
+ ${CMAKE_ROOT}/Modules/TestForAnsiForScope.cxx
+ OUTPUT_VARIABLE OUTPUT)
+ IF (CMAKE_ANSI_FOR_SCOPE)
+ MESSAGE(STATUS "Check for ANSI scope - found")
+ SET (CMAKE_NO_ANSI_FOR_SCOPE 0 CACHE INTERNAL
+ "Does the compiler support ansi for scope.")
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "Determining if the CXX compiler understands ansi for scopes passed with "
+ "the following output:\n${OUTPUT}\n\n")
+ ELSE (CMAKE_ANSI_FOR_SCOPE)
+ MESSAGE(STATUS "Check for ANSI scope - not found")
+ SET (CMAKE_NO_ANSI_FOR_SCOPE 1 CACHE INTERNAL
+ "Does the compiler support ansi for scope.")
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Determining if the CXX compiler understands ansi for scopes failed with "
+ "the following output:\n${OUTPUT}\n\n")
+ ENDIF (CMAKE_ANSI_FOR_SCOPE)
+ENDIF("CMAKE_ANSI_FOR_SCOPE" MATCHES "^CMAKE_ANSI_FOR_SCOPE$")
+
+
+
+
+
diff --git a/Modules/TestForANSIStreamHeaders.cmake b/Modules/TestForANSIStreamHeaders.cmake
new file mode 100644
index 000000000..19c1ab2f2
--- /dev/null
+++ b/Modules/TestForANSIStreamHeaders.cmake
@@ -0,0 +1,34 @@
+# - 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.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software 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(CheckIncludeFileCXX)
+
+IF(NOT CMAKE_NO_ANSI_STREAM_HEADERS)
+ CHECK_INCLUDE_FILE_CXX(iostream CMAKE_ANSI_STREAM_HEADERS)
+ IF (CMAKE_ANSI_STREAM_HEADERS)
+ SET (CMAKE_NO_ANSI_STREAM_HEADERS 0 CACHE INTERNAL
+ "Does the compiler support headers like iostream.")
+ ELSE (CMAKE_ANSI_STREAM_HEADERS)
+ SET (CMAKE_NO_ANSI_STREAM_HEADERS 1 CACHE INTERNAL
+ "Does the compiler support headers like iostream.")
+ ENDIF (CMAKE_ANSI_STREAM_HEADERS)
+
+ MARK_AS_ADVANCED(CMAKE_NO_ANSI_STREAM_HEADERS)
+ENDIF(NOT CMAKE_NO_ANSI_STREAM_HEADERS)
+
+
diff --git a/Modules/TestForANSIStreamHeaders.cxx b/Modules/TestForANSIStreamHeaders.cxx
new file mode 100644
index 000000000..cfb768608
--- /dev/null
+++ b/Modules/TestForANSIStreamHeaders.cxx
@@ -0,0 +1,6 @@
+#include <iostream>
+
+int main(int,char *[])
+{
+ return 0;
+}
diff --git a/Modules/TestForAnsiForScope.cxx b/Modules/TestForAnsiForScope.cxx
new file mode 100644
index 000000000..f2ec76077
--- /dev/null
+++ b/Modules/TestForAnsiForScope.cxx
@@ -0,0 +1,7 @@
+int main(int, char*[])
+{
+ int i;
+ for(int i=0; i < 1; ++i);
+ (void)i;
+ return 0;
+}
diff --git a/Modules/TestForSSTREAM.cmake b/Modules/TestForSSTREAM.cmake
new file mode 100644
index 000000000..8dd53e744
--- /dev/null
+++ b/Modules/TestForSSTREAM.cmake
@@ -0,0 +1,43 @@
+# - 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
+#
+
+#=============================================================================
+# Copyright 2006-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.)
+
+IF("CMAKE_HAS_ANSI_STRING_STREAM" MATCHES "^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
+ OUTPUT_VARIABLE OUTPUT)
+ IF (CMAKE_HAS_ANSI_STRING_STREAM)
+ MESSAGE(STATUS "Check for sstream - found")
+ SET (CMAKE_NO_ANSI_STRING_STREAM 0 CACHE INTERNAL
+ "Does the compiler support sstream")
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "Determining if the CXX compiler has sstream passed with "
+ "the following output:\n${OUTPUT}\n\n")
+ ELSE (CMAKE_HAS_ANSI_STRING_STREAM)
+ MESSAGE(STATUS "Check for sstream - not found")
+ SET (CMAKE_NO_ANSI_STRING_STREAM 1 CACHE INTERNAL
+ "Does the compiler support sstream")
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Determining if the CXX compiler has sstream failed with "
+ "the following output:\n${OUTPUT}\n\n")
+ ENDIF (CMAKE_HAS_ANSI_STRING_STREAM)
+ENDIF("CMAKE_HAS_ANSI_STRING_STREAM" MATCHES "^CMAKE_HAS_ANSI_STRING_STREAM$")
+
+
+
+
diff --git a/Modules/TestForSSTREAM.cxx b/Modules/TestForSSTREAM.cxx
new file mode 100644
index 000000000..af4a4bbef
--- /dev/null
+++ b/Modules/TestForSSTREAM.cxx
@@ -0,0 +1,11 @@
+#include <sstream>
+int main(int, char*[])
+{
+ std::ostringstream os;
+ os << "12345";
+ if(os.str().size() == 5)
+ {
+ return 0;
+ }
+ return -1;
+}
diff --git a/Modules/TestForSTDNamespace.cmake b/Modules/TestForSTDNamespace.cmake
new file mode 100644
index 000000000..932d6e994
--- /dev/null
+++ b/Modules/TestForSTDNamespace.cmake
@@ -0,0 +1,43 @@
+# - Test for std:: namespace support
+# check if the compiler supports std:: on stl classes
+# CMAKE_NO_STD_NAMESPACE - defined by the results
+#
+
+#=============================================================================
+# 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.)
+
+IF("CMAKE_STD_NAMESPACE" MATCHES "^CMAKE_STD_NAMESPACE$")
+ MESSAGE(STATUS "Check for STD namespace")
+ TRY_COMPILE(CMAKE_STD_NAMESPACE ${CMAKE_BINARY_DIR}
+ ${CMAKE_ROOT}/Modules/TestForSTDNamespace.cxx
+ OUTPUT_VARIABLE OUTPUT)
+ IF (CMAKE_STD_NAMESPACE)
+ MESSAGE(STATUS "Check for STD namespace - found")
+ SET (CMAKE_NO_STD_NAMESPACE 0 CACHE INTERNAL
+ "Does the compiler support std::.")
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "Determining if the CXX compiler has std namespace passed with "
+ "the following output:\n${OUTPUT}\n\n")
+ ELSE (CMAKE_STD_NAMESPACE)
+ MESSAGE(STATUS "Check for STD namespace - not found")
+ SET (CMAKE_NO_STD_NAMESPACE 1 CACHE INTERNAL
+ "Does the compiler support std::.")
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Determining if the CXX compiler has std namespace failed with "
+ "the following output:\n${OUTPUT}\n\n")
+ ENDIF (CMAKE_STD_NAMESPACE)
+ENDIF("CMAKE_STD_NAMESPACE" MATCHES "^CMAKE_STD_NAMESPACE$")
+
+
+
+
diff --git a/Modules/TestForSTDNamespace.cxx b/Modules/TestForSTDNamespace.cxx
new file mode 100644
index 000000000..fc3ac5911
--- /dev/null
+++ b/Modules/TestForSTDNamespace.cxx
@@ -0,0 +1,6 @@
+#include <list>
+int main(int, char*[])
+{
+ std::list<int>();
+ return 0;
+}
diff --git a/Modules/UseEcos.cmake b/Modules/UseEcos.cmake
new file mode 100644
index 000000000..60e1e46b4
--- /dev/null
+++ b/Modules/UseEcos.cmake
@@ -0,0 +1,236 @@
+# - 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
+#
+# 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
+
+#=============================================================================
+# Copyright 2006-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.)
+
+# first check that ecosconfig is available
+FIND_PROGRAM(ECOSCONFIG_EXECUTABLE NAMES ecosconfig)
+IF(NOT ECOSCONFIG_EXECUTABLE)
+ MESSAGE(SEND_ERROR "ecosconfig was not found. Either include it in the system path or set it manually using ccmake.")
+ELSE(NOT ECOSCONFIG_EXECUTABLE)
+ MESSAGE(STATUS "Found ecosconfig: ${ECOSCONFIG_EXECUTABLE}")
+ENDIF(NOT ECOSCONFIG_EXECUTABLE)
+
+# check that ECOS_REPOSITORY is set correctly
+IF (NOT EXISTS $ENV{ECOS_REPOSITORY}/ecos.db)
+ MESSAGE(SEND_ERROR "The environment variable ECOS_REPOSITORY is not set correctly. Set it to the directory which contains the file ecos.db")
+ELSE (NOT EXISTS $ENV{ECOS_REPOSITORY}/ecos.db)
+ MESSAGE(STATUS "ECOS_REPOSITORY is set to $ENV{ECOS_REPOSITORY}")
+ENDIF (NOT EXISTS $ENV{ECOS_REPOSITORY}/ecos.db)
+
+# check that tclsh (coming with TCL) is available, otherwise ecosconfig doesn't work
+FIND_PACKAGE(Tclsh)
+IF (NOT TCL_TCLSH)
+ MESSAGE(SEND_ERROR "The TCL tclsh was not found. Please install TCL, it is required for building eCos applications.")
+ELSE (NOT TCL_TCLSH)
+ MESSAGE(STATUS "tlcsh found: ${TCL_TCLSH}")
+ENDIF (NOT TCL_TCLSH)
+
+#add the globale include-diretories
+#usage: ECOS_ADD_INCLUDE_DIRECTORIES()
+MACRO(ECOS_ADD_INCLUDE_DIRECTORIES)
+#check for ProjectSources.txt one level higher
+ IF (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/../ProjectSources.txt)
+ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../)
+ ELSE (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/../ProjectSources.txt)
+ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/)
+ ENDIF (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/../ProjectSources.txt)
+
+#the ecos include directory
+ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}/ecos/install/include/)
+
+ENDMACRO(ECOS_ADD_INCLUDE_DIRECTORIES)
+
+
+#we want to compile for the xscale processor, in this case the following macro has to be called
+#usage: ECOS_USE_ARM_ELF_TOOLS()
+MACRO (ECOS_USE_ARM_ELF_TOOLS)
+ SET(CMAKE_CXX_COMPILER "arm-elf-c++")
+ SET(CMAKE_COMPILER_IS_GNUCXX 1)
+ SET(CMAKE_C_COMPILER "arm-elf-gcc")
+ SET(CMAKE_AR "arm-elf-ar")
+ SET(CMAKE_RANLIB "arm-elf-ranlib")
+#for linking
+ SET(ECOS_LD_MCPU "-mcpu=xscale")
+#for compiling
+ ADD_DEFINITIONS(-mcpu=xscale -mapcs-frame)
+#for the obj-tools
+ SET(ECOS_ARCH_PREFIX "arm-elf-")
+ENDMACRO (ECOS_USE_ARM_ELF_TOOLS)
+
+#usage: ECOS_USE_PPC_EABI_TOOLS()
+MACRO (ECOS_USE_PPC_EABI_TOOLS)
+ SET(CMAKE_CXX_COMPILER "powerpc-eabi-c++")
+ SET(CMAKE_COMPILER_IS_GNUCXX 1)
+ SET(CMAKE_C_COMPILER "powerpc-eabi-gcc")
+ SET(CMAKE_AR "powerpc-eabi-ar")
+ SET(CMAKE_RANLIB "powerpc-eabi-ranlib")
+#for linking
+ SET(ECOS_LD_MCPU "")
+#for compiling
+ ADD_DEFINITIONS()
+#for the obj-tools
+ SET(ECOS_ARCH_PREFIX "powerpc-eabi-")
+ENDMACRO (ECOS_USE_PPC_EABI_TOOLS)
+
+#usage: ECOS_USE_I386_ELF_TOOLS()
+MACRO (ECOS_USE_I386_ELF_TOOLS)
+ SET(CMAKE_CXX_COMPILER "i386-elf-c++")
+ SET(CMAKE_COMPILER_IS_GNUCXX 1)
+ SET(CMAKE_C_COMPILER "i386-elf-gcc")
+ SET(CMAKE_AR "i386-elf-ar")
+ SET(CMAKE_RANLIB "i386-elf-ranlib")
+#for linking
+ SET(ECOS_LD_MCPU "")
+#for compiling
+ ADD_DEFINITIONS()
+#for the obj-tools
+ SET(ECOS_ARCH_PREFIX "i386-elf-")
+ENDMACRO (ECOS_USE_I386_ELF_TOOLS)
+
+
+#since the actual sources are located one level upwards
+#a "../" has to be prepended in front of every source file
+#call the following macro to achieve this, the first parameter
+#is the name of the new list of source files with adjusted paths,
+#followed by all source files
+#usage: ECOS_ADJUST_DIRECTORY(adjusted_SRCS ${my_srcs})
+MACRO(ECOS_ADJUST_DIRECTORY _target_FILES )
+ FOREACH (_current_FILE ${ARGN})
+ GET_FILENAME_COMPONENT(_abs_FILE ${_current_FILE} ABSOLUTE)
+ IF (NOT ${_abs_FILE} STREQUAL ${_current_FILE})
+ GET_FILENAME_COMPONENT(_abs_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../${_current_FILE} ABSOLUTE)
+ ENDIF (NOT ${_abs_FILE} STREQUAL ${_current_FILE})
+ LIST(APPEND ${_target_FILES} ${_abs_FILE})
+ ENDFOREACH (_current_FILE)
+ENDMACRO(ECOS_ADJUST_DIRECTORY)
+
+# the default ecos config file name
+# maybe in the future also out-of-source builds may be possible
+SET(ECOS_CONFIG_FILE ecos.ecc)
+
+#creates the dependancy from all source files on the ecos target.ld,
+#adds the command for compiling ecos
+MACRO(ECOS_ADD_TARGET_LIB)
+# when building out-of-source, create the ecos/ subdir
+ IF(NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/ecos)
+ FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/ecos)
+ ENDIF(NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/ecos)
+
+#sources depend on target.ld
+ SET_SOURCE_FILES_PROPERTIES(
+ ${ARGN}
+ PROPERTIES
+ OBJECT_DEPENDS
+ ${CMAKE_CURRENT_BINARY_DIR}/ecos/install/lib/target.ld
+ )
+
+ ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/ecos/install/lib/target.ld
+ COMMAND sh -c \"make -C ${CMAKE_CURRENT_BINARY_DIR}/ecos || exit -1\; if [ -e ${CMAKE_CURRENT_BINARY_DIR}/ecos/install/lib/target.ld ] \; then touch ${CMAKE_CURRENT_BINARY_DIR}/ecos/install/lib/target.ld\; fi\"
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/ecos/makefile
+ )
+
+ ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/ecos/makefile
+ COMMAND sh -c \" cd ${CMAKE_CURRENT_BINARY_DIR}/ecos\; ${ECOSCONFIG_EXECUTABLE} --config=${CMAKE_CURRENT_SOURCE_DIR}/ecos/${ECOS_CONFIG_FILE} tree || exit -1\;\"
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/ecos/${ECOS_CONFIG_FILE}
+ )
+
+ ADD_CUSTOM_TARGET( ecos make -C ${CMAKE_CURRENT_BINARY_DIR}/ecos/ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/ecos/makefile )
+ENDMACRO(ECOS_ADD_TARGET_LIB)
+
+# get the directory of the current file, used later on in the file
+GET_FILENAME_COMPONENT( ECOS_CMAKE_MODULE_DIR ${CMAKE_CURRENT_LIST_FILE} PATH)
+
+#macro for creating an executable ecos application
+#the first parameter is the name of the executable,
+#the second is the list of all source files (where the path
+#has been adjusted beforehand by calling ECOS_ADJUST_DIRECTORY()
+#usage: ECOS_ADD_EXECUTABLE(my_app ${adjusted_SRCS})
+MACRO(ECOS_ADD_EXECUTABLE _exe_NAME )
+ #definitions, valid for all ecos projects
+ #the optimization and "-g" for debugging has to be enabled
+ #in the project-specific CMakeLists.txt
+ ADD_DEFINITIONS(-D__ECOS__=1 -D__ECOS=1)
+ SET(ECOS_DEFINITIONS -Wall -Wno-long-long -pipe -fno-builtin)
+
+#the executable depends on ecos target.ld
+ ECOS_ADD_TARGET_LIB(${ARGN})
+
+# when using nmake makefiles, the custom buildtype supresses the default cl.exe flags
+# and the rules for creating objects are adjusted for gcc
+ SET(CMAKE_BUILD_TYPE CUSTOM_ECOS_BUILD)
+ SET(CMAKE_C_COMPILE_OBJECT "<CMAKE_C_COMPILER> <FLAGS> -o <OBJECT> -c <SOURCE>")
+ SET(CMAKE_CXX_COMPILE_OBJECT "<CMAKE_CXX_COMPILER> <FLAGS> -o <OBJECT> -c <SOURCE>")
+# special link commands for ecos-executables
+ SET(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_CXX_COMPILER> <CMAKE_CXX_LINK_FLAGS> <OBJECTS> -o <TARGET> ${_ecos_EXTRA_LIBS} -nostdlib -nostartfiles -L${CMAKE_CURRENT_BINARY_DIR}/ecos/install/lib -Ttarget.ld ${ECOS_LD_MCPU}")
+ SET(CMAKE_C_LINK_EXECUTABLE "<CMAKE_C_COMPILER> <CMAKE_C_LINK_FLAGS> <OBJECTS> -o <TARGET> ${_ecos_EXTRA_LIBS} -nostdlib -nostartfiles -L${CMAKE_CURRENT_BINARY_DIR}/ecos/install/lib -Ttarget.ld ${ECOS_LD_MCPU}")
+# some strict compiler flags
+ SET (CMAKE_C_FLAGS "-Wstrict-prototypes")
+ SET (CMAKE_CXX_FLAGS "-Woverloaded-virtual -fno-rtti -Wctor-dtor-privacy -fno-strict-aliasing -fno-exceptions")
+
+ ADD_EXECUTABLE(${_exe_NAME} ${ARGN})
+ SET_TARGET_PROPERTIES(${_exe_NAME} PROPERTIES SUFFIX ".elf")
+
+#create a binary file
+ ADD_CUSTOM_COMMAND(
+ TARGET ${_exe_NAME}
+ POST_BUILD
+ COMMAND ${ECOS_ARCH_PREFIX}objcopy
+ ARGS -O binary ${CMAKE_CURRENT_BINARY_DIR}/${_exe_NAME}.elf ${CMAKE_CURRENT_BINARY_DIR}/${_exe_NAME}.bin
+ )
+
+#and an srec file
+ ADD_CUSTOM_COMMAND(
+ TARGET ${_exe_NAME}
+ POST_BUILD
+ COMMAND ${ECOS_ARCH_PREFIX}objcopy
+ ARGS -O srec ${CMAKE_CURRENT_BINARY_DIR}/${_exe_NAME}.elf ${CMAKE_CURRENT_BINARY_DIR}/${_exe_NAME}.srec
+ )
+
+#add the created files to the clean-files
+ SET_DIRECTORY_PROPERTIES(
+ PROPERTIES
+ ADDITIONAL_MAKE_CLEAN_FILES "${CMAKE_CURRENT_BINARY_DIR}/${_exe_NAME}.bin;${CMAKE_CURRENT_BINARY_DIR}/${_exe_NAME}.srec;${CMAKE_CURRENT_BINARY_DIR}/${_exe_NAME}.lst;"
+ )
+
+ ADD_CUSTOM_TARGET(ecosclean ${CMAKE_COMMAND} -DECOS_DIR=${CMAKE_CURRENT_BINARY_DIR}/ecos/ -P ${ECOS_CMAKE_MODULE_DIR}/ecos_clean.cmake )
+ ADD_CUSTOM_TARGET(normalclean ${CMAKE_MAKE_PROGRAM} clean WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
+ ADD_DEPENDENCIES (ecosclean normalclean)
+
+
+ ADD_CUSTOM_TARGET( listing
+ COMMAND echo -e \"\\n--- Symbols sorted by address ---\\n\" > ${CMAKE_CURRENT_BINARY_DIR}/${_exe_NAME}.lst
+ COMMAND ${ECOS_ARCH_PREFIX}nm -S -C -n ${CMAKE_CURRENT_BINARY_DIR}/${_exe_NAME}.elf >> ${CMAKE_CURRENT_BINARY_DIR}/${_exe_NAME}.lst
+ COMMAND echo -e \"\\n--- Symbols sorted by size ---\\n\" >> ${CMAKE_CURRENT_BINARY_DIR}/${_exe_NAME}.lst
+ COMMAND ${ECOS_ARCH_PREFIX}nm -S -C -r --size-sort ${CMAKE_CURRENT_BINARY_DIR}/${_exe_NAME}.elf >> ${CMAKE_CURRENT_BINARY_DIR}/${_exe_NAME}.lst
+ COMMAND echo -e \"\\n--- Full assembly listing ---\\n\" >> ${CMAKE_CURRENT_BINARY_DIR}/${_exe_NAME}.lst
+ COMMAND ${ECOS_ARCH_PREFIX}objdump -S -x -d -C ${CMAKE_CURRENT_BINARY_DIR}/${_exe_NAME}.elf >> ${CMAKE_CURRENT_BINARY_DIR}/${_exe_NAME}.lst )
+
+ENDMACRO(ECOS_ADD_EXECUTABLE)
+
diff --git a/Modules/UseJava.cmake b/Modules/UseJava.cmake
new file mode 100644
index 000000000..0b2d1b833
--- /dev/null
+++ b/Modules/UseJava.cmake
@@ -0,0 +1,881 @@
+# - 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 SRC1 SRC2 .. SRCN RCS1 RCS2 .. RCSN)
+#
+# This command creates a <TARGET_NAME>.jar. It compiles the given source
+# files (SRC) and adds the given resource files (RCS) to the jar file.
+# If only resource files are given then just a jar file is created.
+#
+# 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 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:
+#
+# set(CMAKE_JAVA_TARGET_OUTPUT_NAME shibboleet.jar)
+# add_jar(foobar foobar.java)
+#
+# To use a different output directory than CMAKE_CURRENT_BINARY_DIR
+# you can set it with:
+#
+# set(CMAKE_JAVA_TARGET_OUTPUT_DIR ${PROJECT_BINARY_DIR}/bin)
+#
+# To define an entry point in your jar you can set it with:
+#
+# set(CMAKE_JAVA_JAR_ENTRY_POINT com/examples/MyProject/Main)
+#
+# To add a VERSION to the target output name you can set it using
+# CMAKE_JAVA_TARGET_VERSION. 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_JAVA_TARGET_VERSION 1.2.0)
+# add_jar(shibboleet shibbotleet.java)
+#
+# If the target is a JNI library, utilize the following commands to
+# create a JNI symbolic link:
+#
+# set(CMAKE_JNI_TARGET TRUE)
+# set(CMAKE_JAVA_TARGET_VERSION 1.2.0)
+# add_jar(shibboleet shibbotleet.java)
+# 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)
+#
+# 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)
+#
+# 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)
+#
+# 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]
+# )
+#
+# 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
+# )
+#
+# 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]
+# )
+#
+# 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.
+#
+# The documentation will be by default installed to
+#
+# ${CMAKE_INSTALL_PREFIX}/share/javadoc/<VAR>
+#
+# if you don't set the INSTALLPATH.
+#
+
+#=============================================================================
+# Copyright 2010-2011 Andreas schneider <asn@redhat.com>
+# Copyright 2010 Ben Boeckel <ben.boeckel@kitware.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 (__java_copy_file src dest comment)
+ add_custom_command(
+ OUTPUT ${dest}
+ COMMAND cmake -E copy_if_different
+ ARGS ${src}
+ ${dest}
+ DEPENDS ${src}
+ COMMENT ${comment})
+endfunction (__java_copy_file src dest comment)
+
+# define helper scripts
+set(_JAVA_CLASS_FILELIST_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/UseJavaClassFilelist.cmake)
+set(_JAVA_SYMLINK_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/UseJavaSymlinks.cmake)
+
+function(add_jar _TARGET_NAME)
+ set(_JAVA_SOURCE_FILES ${ARGN})
+
+ if (NOT DEFINED CMAKE_JAVA_TARGET_OUTPUT_DIR)
+ set(CMAKE_JAVA_TARGET_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR})
+ endif(NOT DEFINED CMAKE_JAVA_TARGET_OUTPUT_DIR)
+
+ if (CMAKE_JAVA_JAR_ENTRY_POINT)
+ set(_ENTRY_POINT_OPTION e)
+ set(_ENTRY_POINT_VALUE ${CMAKE_JAVA_JAR_ENTRY_POINT})
+ endif (CMAKE_JAVA_JAR_ENTRY_POINT)
+
+ if (LIBRARY_OUTPUT_PATH)
+ set(CMAKE_JAVA_LIBRARY_OUTPUT_PATH ${LIBRARY_OUTPUT_PATH})
+ else (LIBRARY_OUTPUT_PATH)
+ set(CMAKE_JAVA_LIBRARY_OUTPUT_PATH ${CMAKE_JAVA_TARGET_OUTPUT_DIR})
+ endif (LIBRARY_OUTPUT_PATH)
+
+ set(CMAKE_JAVA_INCLUDE_PATH
+ ${CMAKE_JAVA_INCLUDE_PATH}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_JAVA_OBJECT_OUTPUT_PATH}
+ ${CMAKE_JAVA_LIBRARY_OUTPUT_PATH}
+ )
+
+ if (WIN32 AND NOT CYGWIN)
+ set(CMAKE_JAVA_INCLUDE_FLAG_SEP ";")
+ else (WIN32 AND NOT CYGWIN)
+ set(CMAKE_JAVA_INCLUDE_FLAG_SEP ":")
+ endif(WIN32 AND NOT CYGWIN)
+
+ foreach (JAVA_INCLUDE_DIR ${CMAKE_JAVA_INCLUDE_PATH})
+ set(CMAKE_JAVA_INCLUDE_PATH_FINAL "${CMAKE_JAVA_INCLUDE_PATH_FINAL}${CMAKE_JAVA_INCLUDE_FLAG_SEP}${JAVA_INCLUDE_DIR}")
+ endforeach(JAVA_INCLUDE_DIR)
+
+ set(CMAKE_JAVA_CLASS_OUTPUT_PATH "${CMAKE_JAVA_TARGET_OUTPUT_DIR}${CMAKE_FILES_DIRECTORY}/${_TARGET_NAME}.dir")
+
+ set(_JAVA_TARGET_OUTPUT_NAME "${_TARGET_NAME}.jar")
+ if (CMAKE_JAVA_TARGET_OUTPUT_NAME AND CMAKE_JAVA_TARGET_VERSION)
+ set(_JAVA_TARGET_OUTPUT_NAME "${CMAKE_JAVA_TARGET_OUTPUT_NAME}-${CMAKE_JAVA_TARGET_VERSION}.jar")
+ set(_JAVA_TARGET_OUTPUT_LINK "${CMAKE_JAVA_TARGET_OUTPUT_NAME}.jar")
+ elseif (CMAKE_JAVA_TARGET_VERSION)
+ set(_JAVA_TARGET_OUTPUT_NAME "${_TARGET_NAME}-${CMAKE_JAVA_TARGET_VERSION}.jar")
+ set(_JAVA_TARGET_OUTPUT_LINK "${_TARGET_NAME}.jar")
+ elseif (CMAKE_JAVA_TARGET_OUTPUT_NAME)
+ set(_JAVA_TARGET_OUTPUT_NAME "${CMAKE_JAVA_TARGET_OUTPUT_NAME}.jar")
+ endif (CMAKE_JAVA_TARGET_OUTPUT_NAME AND CMAKE_JAVA_TARGET_VERSION)
+ # reset
+ set(CMAKE_JAVA_TARGET_OUTPUT_NAME)
+
+ set(_JAVA_CLASS_FILES)
+ set(_JAVA_COMPILE_FILES)
+ set(_JAVA_DEPENDS)
+ set(_JAVA_RESOURCE_FILES)
+ 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)
+
+ file(RELATIVE_PATH _JAVA_REL_BINARY_PATH ${CMAKE_JAVA_TARGET_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)
+ string(LENGTH ${_JAVA_REL_SOURCE_PATH} _SRC_LEN)
+ if (${_BIN_LEN} LESS ${_SRC_LEN})
+ set(_JAVA_REL_PATH ${_JAVA_REL_BINARY_PATH})
+ else (${_BIN_LEN} LESS ${_SRC_LEN})
+ set(_JAVA_REL_PATH ${_JAVA_REL_SOURCE_PATH})
+ endif (${_BIN_LEN} LESS ${_SRC_LEN})
+ get_filename_component(_JAVA_REL_PATH ${_JAVA_REL_PATH} PATH)
+
+ if (_JAVA_EXT MATCHES ".java")
+ list(APPEND _JAVA_COMPILE_FILES ${_JAVA_SOURCE_FILE})
+ set(_JAVA_CLASS_FILE "${CMAKE_JAVA_CLASS_OUTPUT_PATH}/${_JAVA_REL_PATH}/${_JAVA_FILE}.class")
+ set(_JAVA_CLASS_FILES ${_JAVA_CLASS_FILES} ${_JAVA_CLASS_FILE})
+
+ elseif (_JAVA_EXT MATCHES ".jar"
+ OR _JAVA_EXT MATCHES ".war"
+ OR _JAVA_EXT MATCHES ".ear"
+ OR _JAVA_EXT MATCHES ".sar")
+ list(APPEND CMAKE_JAVA_INCLUDE_PATH ${_JAVA_SOURCE_FILE})
+
+ elseif (_JAVA_EXT STREQUAL "")
+ list(APPEND CMAKE_JAVA_INCLUDE_PATH ${JAVA_JAR_TARGET_${_JAVA_SOURCE_FILE}} ${JAVA_JAR_TARGET_${_JAVA_SOURCE_FILE}_CLASSPATH})
+ list(APPEND _JAVA_DEPENDS ${JAVA_JAR_TARGET_${_JAVA_SOURCE_FILE}})
+
+ else (_JAVA_EXT MATCHES ".java")
+ __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})
+ endif (_JAVA_EXT MATCHES ".java")
+ endforeach(_JAVA_SOURCE_FILE)
+
+ # create an empty java_class_filelist
+ if (NOT EXISTS ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_class_filelist)
+ file(WRITE ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_class_filelist "")
+ endif()
+
+ if (_JAVA_COMPILE_FILES)
+ # Compile the java files and create a list of class files
+ add_custom_command(
+ # NOTE: this command generates an artificial dependency file
+ OUTPUT ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_compiled_${_TARGET_NAME}
+ COMMAND ${Java_JAVAC_EXECUTABLE}
+ ${CMAKE_JAVA_COMPILE_FLAGS}
+ -classpath "${CMAKE_JAVA_INCLUDE_PATH_FINAL}"
+ -d ${CMAKE_JAVA_CLASS_OUTPUT_PATH}
+ ${_JAVA_COMPILE_FILES}
+ COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_compiled_${_TARGET_NAME}
+ DEPENDS ${_JAVA_COMPILE_FILES}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ COMMENT "Building Java objects for ${_TARGET_NAME}.jar"
+ )
+ add_custom_command(
+ OUTPUT ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_class_filelist
+ COMMAND ${CMAKE_COMMAND}
+ -DCMAKE_JAVA_CLASS_OUTPUT_PATH=${CMAKE_JAVA_CLASS_OUTPUT_PATH}
+ -DCMAKE_JAR_CLASSES_PREFIX="${CMAKE_JAR_CLASSES_PREFIX}"
+ -P ${_JAVA_CLASS_FILELIST_SCRIPT}
+ DEPENDS ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_compiled_${_TARGET_NAME}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ )
+ endif (_JAVA_COMPILE_FILES)
+
+ # create the jar file
+ set(_JAVA_JAR_OUTPUT_PATH
+ ${CMAKE_JAVA_TARGET_OUTPUT_DIR}/${_JAVA_TARGET_OUTPUT_NAME})
+ if (CMAKE_JNI_TARGET)
+ 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
+ COMMAND ${CMAKE_COMMAND}
+ -D_JAVA_TARGET_DIR=${CMAKE_JAVA_TARGET_OUTPUT_DIR}
+ -D_JAVA_TARGET_OUTPUT_NAME=${_JAVA_TARGET_OUTPUT_NAME}
+ -D_JAVA_TARGET_OUTPUT_LINK=${_JAVA_TARGET_OUTPUT_LINK}
+ -P ${_JAVA_SYMLINK_SCRIPT}
+ COMMAND ${CMAKE_COMMAND}
+ -D_JAVA_TARGET_DIR=${CMAKE_JAVA_TARGET_OUTPUT_DIR}
+ -D_JAVA_TARGET_OUTPUT_NAME=${_JAVA_JAR_OUTPUT_PATH}
+ -D_JAVA_TARGET_OUTPUT_LINK=${_JAVA_TARGET_OUTPUT_LINK}
+ -P ${_JAVA_SYMLINK_SCRIPT}
+ DEPENDS ${_JAVA_RESOURCE_FILES} ${_JAVA_DEPENDS} ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_class_filelist
+ WORKING_DIRECTORY ${CMAKE_JAVA_CLASS_OUTPUT_PATH}
+ COMMENT "Creating Java archive ${_JAVA_TARGET_OUTPUT_NAME}"
+ )
+ else ()
+ 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
+ COMMAND ${CMAKE_COMMAND}
+ -D_JAVA_TARGET_DIR=${CMAKE_JAVA_TARGET_OUTPUT_DIR}
+ -D_JAVA_TARGET_OUTPUT_NAME=${_JAVA_TARGET_OUTPUT_NAME}
+ -D_JAVA_TARGET_OUTPUT_LINK=${_JAVA_TARGET_OUTPUT_LINK}
+ -P ${_JAVA_SYMLINK_SCRIPT}
+ WORKING_DIRECTORY ${CMAKE_JAVA_CLASS_OUTPUT_PATH}
+ DEPENDS ${_JAVA_RESOURCE_FILES} ${_JAVA_DEPENDS} ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_class_filelist
+ COMMENT "Creating Java archive ${_JAVA_TARGET_OUTPUT_NAME}"
+ )
+ endif (CMAKE_JNI_TARGET)
+
+ # Add the target and make sure we have the latest resource files.
+ add_custom_target(${_TARGET_NAME} ALL DEPENDS ${_JAVA_JAR_OUTPUT_PATH})
+
+ set_property(
+ TARGET
+ ${_TARGET_NAME}
+ PROPERTY
+ INSTALL_FILES
+ ${_JAVA_JAR_OUTPUT_PATH}
+ )
+
+ if (_JAVA_TARGET_OUTPUT_LINK)
+ set_property(
+ TARGET
+ ${_TARGET_NAME}
+ PROPERTY
+ INSTALL_FILES
+ ${_JAVA_JAR_OUTPUT_PATH}
+ ${CMAKE_JAVA_TARGET_OUTPUT_DIR}/${_JAVA_TARGET_OUTPUT_LINK}
+ )
+
+ if (CMAKE_JNI_TARGET)
+ set_property(
+ TARGET
+ ${_TARGET_NAME}
+ PROPERTY
+ JNI_SYMLINK
+ ${CMAKE_JAVA_TARGET_OUTPUT_DIR}/${_JAVA_TARGET_OUTPUT_LINK}
+ )
+ endif (CMAKE_JNI_TARGET)
+ endif (_JAVA_TARGET_OUTPUT_LINK)
+
+ set_property(
+ TARGET
+ ${_TARGET_NAME}
+ PROPERTY
+ JAR_FILE
+ ${_JAVA_JAR_OUTPUT_PATH}
+ )
+
+ set_property(
+ TARGET
+ ${_TARGET_NAME}
+ PROPERTY
+ CLASSDIR
+ ${CMAKE_JAVA_CLASS_OUTPUT_PATH}
+ )
+
+endfunction(add_jar)
+
+function(INSTALL_JAR _TARGET_NAME _DESTINATION)
+ get_property(__FILES
+ TARGET
+ ${_TARGET_NAME}
+ PROPERTY
+ INSTALL_FILES
+ )
+
+ if (__FILES)
+ install(
+ FILES
+ ${__FILES}
+ DESTINATION
+ ${_DESTINATION}
+ )
+ else (__FILES)
+ message(SEND_ERROR "The target ${_TARGET_NAME} is not known in this scope.")
+ endif (__FILES)
+endfunction(INSTALL_JAR _TARGET_NAME _DESTINATION)
+
+function(INSTALL_JNI_SYMLINK _TARGET_NAME _DESTINATION)
+ get_property(__SYMLINK
+ TARGET
+ ${_TARGET_NAME}
+ PROPERTY
+ JNI_SYMLINK
+ )
+
+ if (__SYMLINK)
+ install(
+ FILES
+ ${__SYMLINK}
+ DESTINATION
+ ${_DESTINATION}
+ )
+ else (__SYMLINK)
+ message(SEND_ERROR "The target ${_TARGET_NAME} is not known in this scope.")
+ endif (__SYMLINK)
+endfunction(INSTALL_JNI_SYMLINK _TARGET_NAME _DESTINATION)
+
+function (find_jar VARIABLE)
+ set(_jar_names)
+ set(_jar_files)
+ set(_jar_versions)
+ set(_jar_paths
+ /usr/share/java/
+ /usr/local/share/java/
+ ${Java_JAR_PATHS})
+ set(_jar_doc "NOTSET")
+
+ set(_state "name")
+
+ foreach (arg ${ARGN})
+ if (${_state} STREQUAL "name")
+ if (${arg} STREQUAL "VERSIONS")
+ set(_state "versions")
+ elseif (${arg} STREQUAL "NAMES")
+ set(_state "names")
+ elseif (${arg} STREQUAL "PATHS")
+ set(_state "paths")
+ elseif (${arg} STREQUAL "DOC")
+ set(_state "doc")
+ else (${arg} STREQUAL "NAMES")
+ set(_jar_names ${arg})
+ if (_jar_doc STREQUAL "NOTSET")
+ set(_jar_doc "Finding ${arg} jar")
+ endif (_jar_doc STREQUAL "NOTSET")
+ endif (${arg} STREQUAL "VERSIONS")
+ elseif (${_state} STREQUAL "versions")
+ if (${arg} STREQUAL "NAMES")
+ set(_state "names")
+ elseif (${arg} STREQUAL "PATHS")
+ set(_state "paths")
+ elseif (${arg} STREQUAL "DOC")
+ set(_state "doc")
+ else (${arg} STREQUAL "NAMES")
+ set(_jar_versions ${_jar_versions} ${arg})
+ endif (${arg} STREQUAL "NAMES")
+ elseif (${_state} STREQUAL "names")
+ if (${arg} STREQUAL "VERSIONS")
+ set(_state "versions")
+ elseif (${arg} STREQUAL "PATHS")
+ set(_state "paths")
+ elseif (${arg} STREQUAL "DOC")
+ set(_state "doc")
+ else (${arg} STREQUAL "VERSIONS")
+ set(_jar_names ${_jar_names} ${arg})
+ if (_jar_doc STREQUAL "NOTSET")
+ set(_jar_doc "Finding ${arg} jar")
+ endif (_jar_doc STREQUAL "NOTSET")
+ endif (${arg} STREQUAL "VERSIONS")
+ elseif (${_state} STREQUAL "paths")
+ if (${arg} STREQUAL "VERSIONS")
+ set(_state "versions")
+ elseif (${arg} STREQUAL "NAMES")
+ set(_state "names")
+ elseif (${arg} STREQUAL "DOC")
+ set(_state "doc")
+ else (${arg} STREQUAL "VERSIONS")
+ set(_jar_paths ${_jar_paths} ${arg})
+ endif (${arg} STREQUAL "VERSIONS")
+ elseif (${_state} STREQUAL "doc")
+ if (${arg} STREQUAL "VERSIONS")
+ set(_state "versions")
+ elseif (${arg} STREQUAL "NAMES")
+ set(_state "names")
+ elseif (${arg} STREQUAL "PATHS")
+ set(_state "paths")
+ else (${arg} STREQUAL "VERSIONS")
+ set(_jar_doc ${arg})
+ endif (${arg} STREQUAL "VERSIONS")
+ endif (${_state} STREQUAL "name")
+ endforeach (arg ${ARGN})
+
+ if (NOT _jar_names)
+ message(FATAL_ERROR "find_jar: No name to search for given")
+ endif (NOT _jar_names)
+
+ foreach (jar_name ${_jar_names})
+ foreach (version ${_jar_versions})
+ set(_jar_files ${_jar_files} ${jar_name}-${version}.jar)
+ endforeach (version ${_jar_versions})
+ set(_jar_files ${_jar_files} ${jar_name}.jar)
+ endforeach (jar_name ${_jar_names})
+
+ find_file(${VARIABLE}
+ NAMES ${_jar_files}
+ PATHS ${_jar_paths}
+ DOC ${_jar_doc}
+ NO_DEFAULT_PATH)
+endfunction (find_jar VARIABLE)
+
+function(create_javadoc _target)
+ set(_javadoc_packages)
+ set(_javadoc_files)
+ set(_javadoc_sourcepath)
+ set(_javadoc_classpath)
+ set(_javadoc_installpath "${CMAKE_INSTALL_PREFIX}/share/javadoc")
+ set(_javadoc_doctitle)
+ set(_javadoc_windowtitle)
+ set(_javadoc_author FALSE)
+ set(_javadoc_version FALSE)
+ set(_javadoc_use FALSE)
+
+ set(_state "package")
+
+ foreach (arg ${ARGN})
+ if (${_state} STREQUAL "package")
+ if (${arg} STREQUAL "PACKAGES")
+ set(_state "packages")
+ elseif (${arg} STREQUAL "FILES")
+ set(_state "files")
+ elseif (${arg} STREQUAL "SOURCEPATH")
+ set(_state "sourcepath")
+ elseif (${arg} STREQUAL "CLASSPATH")
+ set(_state "classpath")
+ elseif (${arg} STREQUAL "INSTALLPATH")
+ set(_state "installpath")
+ elseif (${arg} STREQUAL "DOCTITLE")
+ set(_state "doctitle")
+ elseif (${arg} STREQUAL "WINDOWTITLE")
+ set(_state "windowtitle")
+ elseif (${arg} STREQUAL "AUTHOR")
+ set(_state "author")
+ elseif (${arg} STREQUAL "USE")
+ set(_state "use")
+ elseif (${arg} STREQUAL "VERSION")
+ set(_state "version")
+ else ()
+ set(_javadoc_packages ${arg})
+ set(_state "packages")
+ endif ()
+ elseif (${_state} STREQUAL "packages")
+ if (${arg} STREQUAL "FILES")
+ set(_state "files")
+ elseif (${arg} STREQUAL "SOURCEPATH")
+ set(_state "sourcepath")
+ elseif (${arg} STREQUAL "CLASSPATH")
+ set(_state "classpath")
+ elseif (${arg} STREQUAL "INSTALLPATH")
+ set(_state "installpath")
+ elseif (${arg} STREQUAL "DOCTITLE")
+ set(_state "doctitle")
+ elseif (${arg} STREQUAL "WINDOWTITLE")
+ set(_state "windowtitle")
+ elseif (${arg} STREQUAL "AUTHOR")
+ set(_state "author")
+ elseif (${arg} STREQUAL "USE")
+ set(_state "use")
+ elseif (${arg} STREQUAL "VERSION")
+ set(_state "version")
+ else ()
+ list(APPEND _javadoc_packages ${arg})
+ endif ()
+ elseif (${_state} STREQUAL "files")
+ if (${arg} STREQUAL "PACKAGES")
+ set(_state "packages")
+ elseif (${arg} STREQUAL "SOURCEPATH")
+ set(_state "sourcepath")
+ elseif (${arg} STREQUAL "CLASSPATH")
+ set(_state "classpath")
+ elseif (${arg} STREQUAL "INSTALLPATH")
+ set(_state "installpath")
+ elseif (${arg} STREQUAL "DOCTITLE")
+ set(_state "doctitle")
+ elseif (${arg} STREQUAL "WINDOWTITLE")
+ set(_state "windowtitle")
+ elseif (${arg} STREQUAL "AUTHOR")
+ set(_state "author")
+ elseif (${arg} STREQUAL "USE")
+ set(_state "use")
+ elseif (${arg} STREQUAL "VERSION")
+ set(_state "version")
+ else ()
+ list(APPEND _javadoc_files ${arg})
+ endif ()
+ elseif (${_state} STREQUAL "sourcepath")
+ if (${arg} STREQUAL "PACKAGES")
+ set(_state "packages")
+ elseif (${arg} STREQUAL "FILES")
+ set(_state "files")
+ elseif (${arg} STREQUAL "CLASSPATH")
+ set(_state "classpath")
+ elseif (${arg} STREQUAL "INSTALLPATH")
+ set(_state "installpath")
+ elseif (${arg} STREQUAL "DOCTITLE")
+ set(_state "doctitle")
+ elseif (${arg} STREQUAL "WINDOWTITLE")
+ set(_state "windowtitle")
+ elseif (${arg} STREQUAL "AUTHOR")
+ set(_state "author")
+ elseif (${arg} STREQUAL "USE")
+ set(_state "use")
+ elseif (${arg} STREQUAL "VERSION")
+ set(_state "version")
+ else ()
+ list(APPEND _javadoc_sourcepath ${arg})
+ endif ()
+ elseif (${_state} STREQUAL "classpath")
+ if (${arg} STREQUAL "PACKAGES")
+ set(_state "packages")
+ elseif (${arg} STREQUAL "FILES")
+ set(_state "files")
+ elseif (${arg} STREQUAL "SOURCEPATH")
+ set(_state "sourcepath")
+ elseif (${arg} STREQUAL "INSTALLPATH")
+ set(_state "installpath")
+ elseif (${arg} STREQUAL "DOCTITLE")
+ set(_state "doctitle")
+ elseif (${arg} STREQUAL "WINDOWTITLE")
+ set(_state "windowtitle")
+ elseif (${arg} STREQUAL "AUTHOR")
+ set(_state "author")
+ elseif (${arg} STREQUAL "USE")
+ set(_state "use")
+ elseif (${arg} STREQUAL "VERSION")
+ set(_state "version")
+ else ()
+ list(APPEND _javadoc_classpath ${arg})
+ endif ()
+ elseif (${_state} STREQUAL "installpath")
+ if (${arg} STREQUAL "PACKAGES")
+ set(_state "packages")
+ elseif (${arg} STREQUAL "FILES")
+ set(_state "files")
+ elseif (${arg} STREQUAL "SOURCEPATH")
+ set(_state "sourcepath")
+ elseif (${arg} STREQUAL "DOCTITLE")
+ set(_state "doctitle")
+ elseif (${arg} STREQUAL "WINDOWTITLE")
+ set(_state "windowtitle")
+ elseif (${arg} STREQUAL "AUTHOR")
+ set(_state "author")
+ elseif (${arg} STREQUAL "USE")
+ set(_state "use")
+ elseif (${arg} STREQUAL "VERSION")
+ set(_state "version")
+ else ()
+ set(_javadoc_installpath ${arg})
+ endif ()
+ elseif (${_state} STREQUAL "doctitle")
+ if (${arg} STREQUAL "PACKAGES")
+ set(_state "packages")
+ elseif (${arg} STREQUAL "FILES")
+ set(_state "files")
+ elseif (${arg} STREQUAL "SOURCEPATH")
+ set(_state "sourcepath")
+ elseif (${arg} STREQUAL "INSTALLPATH")
+ set(_state "installpath")
+ elseif (${arg} STREQUAL "CLASSPATH")
+ set(_state "classpath")
+ elseif (${arg} STREQUAL "WINDOWTITLE")
+ set(_state "windowtitle")
+ elseif (${arg} STREQUAL "AUTHOR")
+ set(_state "author")
+ elseif (${arg} STREQUAL "USE")
+ set(_state "use")
+ elseif (${arg} STREQUAL "VERSION")
+ set(_state "version")
+ else ()
+ set(_javadoc_doctitle ${arg})
+ endif ()
+ elseif (${_state} STREQUAL "windowtitle")
+ if (${arg} STREQUAL "PACKAGES")
+ set(_state "packages")
+ elseif (${arg} STREQUAL "FILES")
+ set(_state "files")
+ elseif (${arg} STREQUAL "SOURCEPATH")
+ set(_state "sourcepath")
+ elseif (${arg} STREQUAL "CLASSPATH")
+ set(_state "classpath")
+ elseif (${arg} STREQUAL "INSTALLPATH")
+ set(_state "installpath")
+ elseif (${arg} STREQUAL "DOCTITLE")
+ set(_state "doctitle")
+ elseif (${arg} STREQUAL "AUTHOR")
+ set(_state "author")
+ elseif (${arg} STREQUAL "USE")
+ set(_state "use")
+ elseif (${arg} STREQUAL "VERSION")
+ set(_state "version")
+ else ()
+ set(_javadoc_windowtitle ${arg})
+ endif ()
+ elseif (${_state} STREQUAL "author")
+ if (${arg} STREQUAL "PACKAGES")
+ set(_state "packages")
+ elseif (${arg} STREQUAL "FILES")
+ set(_state "files")
+ elseif (${arg} STREQUAL "SOURCEPATH")
+ set(_state "sourcepath")
+ elseif (${arg} STREQUAL "CLASSPATH")
+ set(_state "classpath")
+ elseif (${arg} STREQUAL "INSTALLPATH")
+ set(_state "installpath")
+ elseif (${arg} STREQUAL "DOCTITLE")
+ set(_state "doctitle")
+ elseif (${arg} STREQUAL "WINDOWTITLE")
+ set(_state "windowtitle")
+ elseif (${arg} STREQUAL "AUTHOR")
+ set(_state "author")
+ elseif (${arg} STREQUAL "USE")
+ set(_state "use")
+ elseif (${arg} STREQUAL "VERSION")
+ set(_state "version")
+ else ()
+ set(_javadoc_author ${arg})
+ endif ()
+ elseif (${_state} STREQUAL "use")
+ if (${arg} STREQUAL "PACKAGES")
+ set(_state "packages")
+ elseif (${arg} STREQUAL "FILES")
+ set(_state "files")
+ elseif (${arg} STREQUAL "SOURCEPATH")
+ set(_state "sourcepath")
+ elseif (${arg} STREQUAL "CLASSPATH")
+ set(_state "classpath")
+ elseif (${arg} STREQUAL "INSTALLPATH")
+ set(_state "installpath")
+ elseif (${arg} STREQUAL "DOCTITLE")
+ set(_state "doctitle")
+ elseif (${arg} STREQUAL "WINDOWTITLE")
+ set(_state "windowtitle")
+ elseif (${arg} STREQUAL "AUTHOR")
+ set(_state "author")
+ elseif (${arg} STREQUAL "USE")
+ set(_state "use")
+ elseif (${arg} STREQUAL "VERSION")
+ set(_state "version")
+ else ()
+ set(_javadoc_use ${arg})
+ endif ()
+ elseif (${_state} STREQUAL "version")
+ if (${arg} STREQUAL "PACKAGES")
+ set(_state "packages")
+ elseif (${arg} STREQUAL "FILES")
+ set(_state "files")
+ elseif (${arg} STREQUAL "SOURCEPATH")
+ set(_state "sourcepath")
+ elseif (${arg} STREQUAL "CLASSPATH")
+ set(_state "classpath")
+ elseif (${arg} STREQUAL "INSTALLPATH")
+ set(_state "installpath")
+ elseif (${arg} STREQUAL "DOCTITLE")
+ set(_state "doctitle")
+ elseif (${arg} STREQUAL "WINDOWTITLE")
+ set(_state "windowtitle")
+ elseif (${arg} STREQUAL "AUTHOR")
+ set(_state "author")
+ elseif (${arg} STREQUAL "USE")
+ set(_state "use")
+ elseif (${arg} STREQUAL "VERSION")
+ set(_state "version")
+ else ()
+ set(_javadoc_version ${arg})
+ endif ()
+ endif (${_state} STREQUAL "package")
+ endforeach (arg ${ARGN})
+
+ set(_javadoc_builddir ${CMAKE_CURRENT_BINARY_DIR}/javadoc/${_target})
+ set(_javadoc_options -d ${_javadoc_builddir})
+
+ if (_javadoc_sourcepath)
+ set(_start TRUE)
+ foreach(_path ${_javadoc_sourcepath})
+ if (_start)
+ set(_sourcepath ${_path})
+ set(_start FALSE)
+ else (_start)
+ set(_sourcepath ${_sourcepath}:${_path})
+ endif (_start)
+ endforeach(_path ${_javadoc_sourcepath})
+ set(_javadoc_options ${_javadoc_options} -sourcepath ${_sourcepath})
+ endif (_javadoc_sourcepath)
+
+ if (_javadoc_classpath)
+ set(_start TRUE)
+ foreach(_path ${_javadoc_classpath})
+ if (_start)
+ set(_classpath ${_path})
+ set(_start FALSE)
+ else (_start)
+ set(_classpath ${_classpath}:${_path})
+ endif (_start)
+ endforeach(_path ${_javadoc_classpath})
+ set(_javadoc_options ${_javadoc_options} -classpath "${_classpath}")
+ endif (_javadoc_classpath)
+
+ if (_javadoc_doctitle)
+ set(_javadoc_options ${_javadoc_options} -doctitle '${_javadoc_doctitle}')
+ endif (_javadoc_doctitle)
+
+ if (_javadoc_windowtitle)
+ set(_javadoc_options ${_javadoc_options} -windowtitle '${_javadoc_windowtitle}')
+ endif (_javadoc_windowtitle)
+
+ if (_javadoc_author)
+ set(_javadoc_options ${_javadoc_options} -author)
+ endif (_javadoc_author)
+
+ if (_javadoc_use)
+ set(_javadoc_options ${_javadoc_options} -use)
+ endif (_javadoc_use)
+
+ if (_javadoc_version)
+ set(_javadoc_options ${_javadoc_options} -version)
+ endif (_javadoc_version)
+
+ add_custom_target(${_target}_javadoc ALL
+ COMMAND ${Java_JAVADOC_EXECUTABLE} ${_javadoc_options}
+ ${_javadoc_files}
+ ${_javadoc_packages}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ )
+
+ install(
+ DIRECTORY ${_javadoc_builddir}
+ DESTINATION ${_javadoc_installpath}
+ )
+endfunction(create_javadoc)
diff --git a/Modules/UseJavaClassFilelist.cmake b/Modules/UseJavaClassFilelist.cmake
new file mode 100644
index 000000000..c842bf71a
--- /dev/null
+++ b/Modules/UseJavaClassFilelist.cmake
@@ -0,0 +1,52 @@
+#
+# 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>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software 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_JAVA_CLASS_OUTPUT_PATH)
+ if (EXISTS "${CMAKE_JAVA_CLASS_OUTPUT_PATH}")
+
+ set(_JAVA_GLOBBED_FILES)
+ if (CMAKE_JAR_CLASSES_PREFIX)
+ foreach(JAR_CLASS_PREFIX ${CMAKE_JAR_CLASSES_PREFIX})
+ message(STATUS "JAR_CLASS_PREFIX: ${JAR_CLASS_PREFIX}")
+
+ file(GLOB_RECURSE _JAVA_GLOBBED_TMP_FILES "${CMAKE_JAVA_CLASS_OUTPUT_PATH}/${JAR_CLASS_PREFIX}/*.class")
+ if (_JAVA_GLOBBED_TMP_FILES)
+ list(APPEND _JAVA_GLOBBED_FILES ${_JAVA_GLOBBED_TMP_FILES})
+ endif (_JAVA_GLOBBED_TMP_FILES)
+ endforeach(JAR_CLASS_PREFIX ${CMAKE_JAR_CLASSES_PREFIX})
+ else()
+ file(GLOB_RECURSE _JAVA_GLOBBED_FILES "${CMAKE_JAVA_CLASS_OUTPUT_PATH}/*.class")
+ endif (CMAKE_JAR_CLASSES_PREFIX)
+
+ set(_JAVA_CLASS_FILES)
+ # file(GLOB_RECURSE foo RELATIVE) is broken so we need this.
+ foreach(_JAVA_GLOBBED_FILE ${_JAVA_GLOBBED_FILES})
+ file(RELATIVE_PATH _JAVA_CLASS_FILE ${CMAKE_JAVA_CLASS_OUTPUT_PATH} ${_JAVA_GLOBBED_FILE})
+ set(_JAVA_CLASS_FILES ${_JAVA_CLASS_FILES}${_JAVA_CLASS_FILE}\n)
+ endforeach(_JAVA_GLOBBED_FILE ${_JAVA_GLOBBED_FILES})
+
+ # write to file
+ file(WRITE ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_class_filelist ${_JAVA_CLASS_FILES})
+
+ else (EXISTS "${CMAKE_JAVA_CLASS_OUTPUT_PATH}")
+ message(SEND_ERROR "FATAL: Java class output path doesn't exist")
+ endif (EXISTS "${CMAKE_JAVA_CLASS_OUTPUT_PATH}")
+else (CMAKE_JAVA_CLASS_OUTPUT_PATH)
+ message(SEND_ERROR "FATAL: Can't find CMAKE_JAVA_CLASS_OUTPUT_PATH")
+endif (CMAKE_JAVA_CLASS_OUTPUT_PATH)
diff --git a/Modules/UseJavaSymlinks.cmake b/Modules/UseJavaSymlinks.cmake
new file mode 100644
index 000000000..c66ee1ea1
--- /dev/null
+++ b/Modules/UseJavaSymlinks.cmake
@@ -0,0 +1,32 @@
+#
+# Helper script for UseJava.cmake
+#
+
+#=============================================================================
+# Copyright 2010-2011 Andreas schneider <asn@redhat.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.)
+
+if (UNIX AND _JAVA_TARGET_OUTPUT_LINK)
+ if (_JAVA_TARGET_OUTPUT_NAME)
+ find_program(LN_EXECUTABLE
+ NAMES
+ ln
+ )
+
+ execute_process(
+ COMMAND ${LN_EXECUTABLE} -sf "${_JAVA_TARGET_OUTPUT_NAME}" "${_JAVA_TARGET_OUTPUT_LINK}"
+ WORKING_DIRECTORY ${_JAVA_TARGET_DIR}
+ )
+ else (_JAVA_TARGET_OUTPUT_NAME)
+ message(SEND_ERROR "FATAL: Can't find _JAVA_TARGET_OUTPUT_NAME")
+ endif (_JAVA_TARGET_OUTPUT_NAME)
+endif (UNIX AND _JAVA_TARGET_OUTPUT_LINK)
diff --git a/Modules/UsePkgConfig.cmake b/Modules/UsePkgConfig.cmake
new file mode 100644
index 000000000..7f4318f05
--- /dev/null
+++ b/Modules/UsePkgConfig.cmake
@@ -0,0 +1,78 @@
+# - 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
+# the respective information
+#
+
+#=============================================================================
+# Copyright 2006-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(PKGCONFIG_EXECUTABLE NAMES pkg-config )
+
+MACRO(PKGCONFIG _package _include_DIR _link_DIR _link_FLAGS _cflags)
+ MESSAGE(STATUS
+ "WARNING: you are using the obsolete 'PKGCONFIG' macro, use FindPkgConfig")
+# reset the variables at the beginning
+ SET(${_include_DIR})
+ SET(${_link_DIR})
+ SET(${_link_FLAGS})
+ SET(${_cflags})
+
+ # if pkg-config has been found
+ IF(PKGCONFIG_EXECUTABLE)
+
+ EXEC_PROGRAM(${PKGCONFIG_EXECUTABLE} ARGS ${_package} --exists RETURN_VALUE _return_VALUE OUTPUT_VARIABLE _pkgconfigDevNull )
+
+ # and if the package of interest also exists for pkg-config, then get the information
+ IF(NOT _return_VALUE)
+
+ EXEC_PROGRAM(${PKGCONFIG_EXECUTABLE} ARGS ${_package} --variable=includedir
+ OUTPUT_VARIABLE ${_include_DIR} )
+ STRING(REGEX REPLACE "[\r\n]" " " ${_include_DIR} "${${_include_DIR}}")
+
+
+ EXEC_PROGRAM(${PKGCONFIG_EXECUTABLE} ARGS ${_package} --variable=libdir
+ OUTPUT_VARIABLE ${_link_DIR} )
+ STRING(REGEX REPLACE "[\r\n]" " " ${_link_DIR} "${${_link_DIR}}")
+
+ EXEC_PROGRAM(${PKGCONFIG_EXECUTABLE} ARGS ${_package} --libs
+ OUTPUT_VARIABLE ${_link_FLAGS} )
+ STRING(REGEX REPLACE "[\r\n]" " " ${_link_FLAGS} "${${_link_FLAGS}}")
+
+ EXEC_PROGRAM(${PKGCONFIG_EXECUTABLE} ARGS ${_package} --cflags
+ OUTPUT_VARIABLE ${_cflags} )
+ STRING(REGEX REPLACE "[\r\n]" " " ${_cflags} "${${_cflags}}")
+
+ ELSE( NOT _return_VALUE)
+
+ MESSAGE(STATUS "PKGCONFIG() indicates that ${_package} is not installed (install the package which contains ${_package}.pc if you want to support this feature)")
+
+ ENDIF(NOT _return_VALUE)
+
+ # if pkg-config has NOT been found, INFORM the user
+ ELSE(PKGCONFIG_EXECUTABLE)
+
+ MESSAGE(STATUS "WARNING: PKGCONFIG() indicates that the tool pkg-config has not been found on your system. You should install it.")
+
+ ENDIF(PKGCONFIG_EXECUTABLE)
+
+ENDMACRO(PKGCONFIG _include_DIR _link_DIR _link_FLAGS _cflags)
+
+MARK_AS_ADVANCED(PKGCONFIG_EXECUTABLE)
diff --git a/Modules/UseQt4.cmake b/Modules/UseQt4.cmake
new file mode 100644
index 000000000..027504fc5
--- /dev/null
+++ b/Modules/UseQt4.cmake
@@ -0,0 +1,108 @@
+# - 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.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software 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.)
+
+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()
+
+INCLUDE_DIRECTORIES(${QT_INCLUDE_DIR})
+
+SET(QT_LIBRARIES "")
+SET(QT_LIBRARIES_PLUGINS "")
+
+IF (QT_USE_QTMAIN)
+ IF (Q_WS_WIN)
+ SET(QT_LIBRARIES ${QT_LIBRARIES} ${QT_QTMAIN_LIBRARY})
+ ENDIF (Q_WS_WIN)
+ENDIF (QT_USE_QTMAIN)
+
+IF(QT_DONT_USE_QTGUI)
+ SET(QT_USE_QTGUI 0)
+ELSE(QT_DONT_USE_QTGUI)
+ SET(QT_USE_QTGUI 1)
+ENDIF(QT_DONT_USE_QTGUI)
+
+IF(QT_DONT_USE_QTCORE)
+ SET(QT_USE_QTCORE 0)
+ELSE(QT_DONT_USE_QTCORE)
+ SET(QT_USE_QTCORE 1)
+ENDIF(QT_DONT_USE_QTCORE)
+
+IF (QT_USE_QT3SUPPORT)
+ ADD_DEFINITIONS(-DQT3_SUPPORT)
+ENDIF (QT_USE_QT3SUPPORT)
+
+# 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_QTUITOOLS_MODULE_DEPENDS QTGUI QTXML QTCORE)
+SET(QT_QTHELP_MODULE_DEPENDS QTGUI QTSQL QTXML QTNETWORK QTCORE)
+IF(QT_QTDBUS_FOUND)
+ SET(QT_PHONON_MODULE_DEPENDS QTGUI QTDBUS QTCORE)
+ELSE(QT_QTDBUS_FOUND)
+ SET(QT_PHONON_MODULE_DEPENDS QTGUI QTCORE)
+ENDIF(QT_QTDBUS_FOUND)
+SET(QT_QTDBUS_MODULE_DEPENDS QTXML QTCORE)
+SET(QT_QTXMLPATTERNS_MODULE_DEPENDS QTNETWORK QTCORE)
+SET(QT_QAXCONTAINER_MODULE_DEPENDS QTGUI QTCORE)
+SET(QT_QAXSERVER_MODULE_DEPENDS QTGUI QTCORE)
+SET(QT_QTSCRIPTTOOLS_MODULE_DEPENDS QTGUI QTCORE)
+SET(QT_QTWEBKIT_MODULE_DEPENDS QTXMLPATTERNS QTGUI QTCORE)
+SET(QT_QTDECLARATIVE_MODULE_DEPENDS QTSCRIPT QTSVG QTSQL QTXMLPATTERNS QTGUI QTCORE)
+SET(QT_QTMULTIMEDIA_MODULE_DEPENDS QTGUI QTCORE)
+SET(QT_QTOPENGL_MODULE_DEPENDS QTGUI QTCORE)
+SET(QT_QTSCRIPT_MODULE_DEPENDS QTCORE)
+SET(QT_QTGUI_MODULE_DEPENDS QTCORE)
+SET(QT_QTTEST_MODULE_DEPENDS QTCORE)
+SET(QT_QTXML_MODULE_DEPENDS QTCORE)
+SET(QT_QTSQL_MODULE_DEPENDS QTCORE)
+SET(QT_QTNETWORK_MODULE_DEPENDS QTCORE)
+
+# Qt modules (in order of dependence)
+FOREACH(module QT3SUPPORT QTOPENGL QTASSISTANT QTDESIGNER QTMOTIF QTNSPLUGIN
+ QAXSERVER QAXCONTAINER QTDECLARATIVE QTSCRIPT QTSVG QTUITOOLS QTHELP
+ QTWEBKIT PHONON QTSCRIPTTOOLS QTMULTIMEDIA QTXMLPATTERNS QTGUI QTTEST
+ QTDBUS QTXML QTSQL QTNETWORK QTCORE)
+
+ IF (QT_USE_${module} OR QT_USE_${module}_DEPENDS)
+ IF (QT_${module}_FOUND)
+ IF(QT_USE_${module})
+ STRING(REPLACE "QT" "" qt_module_def "${module}")
+ ADD_DEFINITIONS(-DQT_${qt_module_def}_LIB)
+ INCLUDE_DIRECTORIES(${QT_${module}_INCLUDE_DIR})
+ ENDIF(QT_USE_${module})
+ SET(QT_LIBRARIES ${QT_LIBRARIES} ${QT_${module}_LIBRARY})
+ SET(QT_LIBRARIES_PLUGINS ${QT_LIBRARIES_PLUGINS} ${QT_${module}_PLUGINS})
+ IF(QT_IS_STATIC)
+ SET(QT_LIBRARIES ${QT_LIBRARIES} ${QT_${module}_LIB_DEPENDENCIES})
+ ENDIF(QT_IS_STATIC)
+ FOREACH(depend_module ${QT_${module}_MODULE_DEPENDS})
+ SET(QT_USE_${depend_module}_DEPENDS 1)
+ ENDFOREACH(depend_module ${QT_${module}_MODULE_DEPENDS})
+ ELSE (QT_${module}_FOUND)
+ MESSAGE("Qt ${module} library not found.")
+ ENDIF (QT_${module}_FOUND)
+ ENDIF (QT_USE_${module} OR QT_USE_${module}_DEPENDS)
+
+ENDFOREACH(module)
+
diff --git a/Modules/UseSWIG.cmake b/Modules/UseSWIG.cmake
new file mode 100644
index 000000000..ef7672440
--- /dev/null
+++ b/Modules/UseSWIG.cmake
@@ -0,0 +1,253 @@
+# - 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.
+# 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")
+
+
+#=============================================================================
+# Copyright 2004-2009 Kitware, Inc.
+# Copyright 2009 Mathieu Malaterre <mathieu.malaterre@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.)
+
+SET(SWIG_CXX_EXTENSION "cxx")
+SET(SWIG_EXTRA_LIBRARIES "")
+
+SET(SWIG_PYTHON_EXTRA_FILE_EXTENSION "py")
+
+#
+# For given swig module initialize variables associated with it
+#
+MACRO(SWIG_MODULE_INITIALIZE name language)
+ STRING(TOUPPER "${language}" swig_uppercase_language)
+ STRING(TOLOWER "${language}" swig_lowercase_language)
+ SET(SWIG_MODULE_${name}_LANGUAGE "${swig_uppercase_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")
+ 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).
+ SET(SWIG_MODULE_${name}_REAL_NAME "_${name}")
+ ELSEIF("${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "PERL")
+ SET(SWIG_MODULE_${name}_EXTRA_FLAGS "-shadow")
+ ENDIF()
+ENDMACRO(SWIG_MODULE_INITIALIZE)
+
+#
+# For a given language, input file, and output file, determine extra files that
+# will be generated. This is internal swig macro.
+#
+
+MACRO(SWIG_GET_EXTRA_OUTPUT_FILES language outfiles generatedpath infile)
+ SET(${outfiles} "")
+ 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)
+ ENDIF(SWIG_GET_EXTRA_OUTPUT_FILES_module_basename STREQUAL "NOTFOUND")
+ FOREACH(it ${SWIG_${language}_EXTRA_FILE_EXTENSION})
+ SET(${outfiles} ${${outfiles}}
+ "${generatedpath}/${SWIG_GET_EXTRA_OUTPUT_FILES_module_basename}.${it}")
+ ENDFOREACH(it)
+ENDMACRO(SWIG_GET_EXTRA_OUTPUT_FILES)
+
+#
+# Take swig (*.i) file and add proper custom commands for it
+#
+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)
+ GET_SOURCE_FILE_PROPERTY(swig_source_file_flags ${infile} SWIG_FLAGS)
+ IF("${swig_source_file_flags}" STREQUAL "NOTFOUND")
+ SET(swig_source_file_flags "")
+ ENDIF("${swig_source_file_flags}" STREQUAL "NOTFOUND")
+ 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(${swig_source_file_path} MATCHES "^${CMAKE_CURRENT_SOURCE_DIR}")
+ 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(${swig_source_file_path} MATCHES "^${CMAKE_CURRENT_BINARY_DIR}")
+ 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(swig_source_file_generated)
+ SET(swig_source_file_fullname "${CMAKE_CURRENT_SOURCE_DIR}/${infile}")
+ ENDIF(swig_source_file_generated)
+ ENDIF(${swig_source_file_path} MATCHES "^${CMAKE_CURRENT_BINARY_DIR}")
+ ENDIF(${swig_source_file_path} MATCHES "^${CMAKE_CURRENT_SOURCE_DIR}")
+
+ 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(swig_source_file_relative_path)
+ # If CMAKE_SWIG_OUTDIR was specified then pass it to -outdir
+ IF(CMAKE_SWIG_OUTDIR)
+ SET(swig_outdir ${CMAKE_SWIG_OUTDIR})
+ ELSE(CMAKE_SWIG_OUTDIR)
+ SET(swig_outdir ${CMAKE_CURRENT_BINARY_DIR})
+ ENDIF(CMAKE_SWIG_OUTDIR)
+ SWIG_GET_EXTRA_OUTPUT_FILES(${SWIG_MODULE_${name}_LANGUAGE}
+ swig_extra_generated_files
+ "${swig_outdir}"
+ "${infile}")
+ SET(swig_generated_file_fullname
+ "${swig_generated_file_fullname}/${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
+ "${swig_generated_file_fullname}${SWIG_MODULE_${name}_LANGUAGE}_wrap")
+
+ IF(swig_source_file_cplusplus)
+ SET(swig_generated_file_fullname
+ "${swig_generated_file_fullname}.${SWIG_CXX_EXTENSION}")
+ ELSE(swig_source_file_cplusplus)
+ SET(swig_generated_file_fullname
+ "${swig_generated_file_fullname}.c")
+ ENDIF(swig_source_file_cplusplus)
+
+ #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)
+ SET(swig_include_dirs)
+ FOREACH(it ${cmake_include_directories})
+ SET(swig_include_dirs ${swig_include_dirs} "-I${it}")
+ ENDFOREACH(it)
+
+ SET(swig_special_flags)
+ # default is c, so add c++ flag if it is c++
+ IF(swig_source_file_cplusplus)
+ SET(swig_special_flags ${swig_special_flags} "-c++")
+ ENDIF(swig_source_file_cplusplus)
+ SET(swig_extra_flags)
+ IF(SWIG_MODULE_${name}_EXTRA_FLAGS)
+ SET(swig_extra_flags ${swig_extra_flags} ${SWIG_MODULE_${name}_EXTRA_FLAGS})
+ ENDIF(SWIG_MODULE_${name}_EXTRA_FLAGS)
+ ADD_CUSTOM_COMMAND(
+ OUTPUT "${swig_generated_file_fullname}" ${swig_extra_generated_files}
+ # Let's create the ${swig_outdir} at execution time, in case dir contains $(OutDir)
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${swig_outdir}
+ COMMAND "${SWIG_EXECUTABLE}"
+ ARGS "-${SWIG_MODULE_${name}_SWIG_LANGUAGE_FLAG}"
+ ${swig_source_file_flags}
+ ${CMAKE_SWIG_FLAGS}
+ -outdir ${swig_outdir}
+ ${swig_special_flags}
+ ${swig_extra_flags}
+ ${swig_include_dirs}
+ -o "${swig_generated_file_fullname}"
+ "${swig_source_file_fullname}"
+ MAIN_DEPENDENCY "${swig_source_file_fullname}"
+ DEPENDS ${SWIG_MODULE_${name}_EXTRA_DEPS}
+ COMMENT "Swig source")
+ SET_SOURCE_FILES_PROPERTIES("${swig_generated_file_fullname}" ${swig_extra_generated_files}
+ PROPERTIES GENERATED 1)
+ SET(${outfiles} "${swig_generated_file_fullname}" ${swig_extra_generated_files})
+ENDMACRO(SWIG_ADD_SOURCE_TO_MODULE)
+
+#
+# Create Swig module
+#
+MACRO(SWIG_ADD_MODULE name language)
+ SWIG_MODULE_INITIALIZE(${name} ${language})
+ SET(swig_dot_i_sources)
+ SET(swig_other_sources)
+ FOREACH(it ${ARGN})
+ IF(${it} MATCHES ".*\\.i$")
+ SET(swig_dot_i_sources ${swig_dot_i_sources} "${it}")
+ ELSE(${it} MATCHES ".*\\.i$")
+ SET(swig_other_sources ${swig_other_sources} "${it}")
+ ENDIF(${it} MATCHES ".*\\.i$")
+ ENDFOREACH(it)
+
+ SET(swig_generated_sources)
+ FOREACH(it ${swig_dot_i_sources})
+ SWIG_ADD_SOURCE_TO_MODULE(${name} swig_generated_source ${it})
+ SET(swig_generated_sources ${swig_generated_sources} "${swig_generated_source}")
+ ENDFOREACH(it)
+ GET_DIRECTORY_PROPERTY(swig_extra_clean_files ADDITIONAL_MAKE_CLEAN_FILES)
+ SET_DIRECTORY_PROPERTIES(PROPERTIES
+ ADDITIONAL_MAKE_CLEAN_FILES "${swig_extra_clean_files};${swig_generated_sources}")
+ ADD_LIBRARY(${SWIG_MODULE_${name}_REAL_NAME}
+ MODULE
+ ${swig_generated_sources}
+ ${swig_other_sources})
+ STRING(TOLOWER "${language}" swig_lowercase_language)
+ IF ("${swig_lowercase_language}" STREQUAL "java")
+ IF (APPLE)
+ # In java you want:
+ # System.loadLibrary("LIBRARY");
+ # then JNI will look for a library whose name is platform dependent, namely
+ # MacOS : libLIBRARY.jnilib
+ # Windows: LIBRARY.dll
+ # Linux : libLIBRARY.so
+ SET_TARGET_PROPERTIES (${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES SUFFIX ".jnilib")
+ ENDIF (APPLE)
+ ENDIF ("${swig_lowercase_language}" STREQUAL "java")
+ IF ("${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"
+ # instead of ".dll" as of Python 2.5. Older python versions do support
+ # this suffix.
+ # http://docs.python.org/whatsnew/ports.html#SECTION0001510000000000000000
+ # <quote>
+ # Windows: .dll is no longer supported as a filename extension for extension modules.
+ # .pyd is now the only filename extension that will be searched for.
+ # </quote>
+ IF(WIN32 AND NOT CYGWIN)
+ SET_TARGET_PROPERTIES(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES SUFFIX ".pyd")
+ ENDIF(WIN32 AND NOT CYGWIN)
+ ENDIF ("${swig_lowercase_language}" STREQUAL "python")
+ENDMACRO(SWIG_ADD_MODULE)
+
+#
+# Like TARGET_LINK_LIBRARIES but for swig modules
+#
+MACRO(SWIG_LINK_LIBRARIES name)
+ IF(SWIG_MODULE_${name}_REAL_NAME)
+ TARGET_LINK_LIBRARIES(${SWIG_MODULE_${name}_REAL_NAME} ${ARGN})
+ ELSE(SWIG_MODULE_${name}_REAL_NAME)
+ MESSAGE(SEND_ERROR "Cannot find Swig library \"${name}\".")
+ ENDIF(SWIG_MODULE_${name}_REAL_NAME)
+ENDMACRO(SWIG_LINK_LIBRARIES name)
+
diff --git a/Modules/UseVTK40.cmake b/Modules/UseVTK40.cmake
new file mode 100644
index 000000000..c1157d6be
--- /dev/null
+++ b/Modules/UseVTK40.cmake
@@ -0,0 +1,29 @@
+#
+
+#=============================================================================
+# 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
new file mode 100644
index 000000000..4df59b9dd
--- /dev/null
+++ b/Modules/UseVTKBuildSettings40.cmake
@@ -0,0 +1,38 @@
+#
+
+#=============================================================================
+# 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
new file mode 100644
index 000000000..ca5e7aa3c
--- /dev/null
+++ b/Modules/UseVTKConfig40.cmake
@@ -0,0 +1,409 @@
+#
+
+#=============================================================================
+# 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(VTK_USE_RENDERING)
+IF(VTK_USE_HYBRID)
+ SET(VTK_KITS ${VTK_KITS} HYBRID)
+ENDIF(VTK_USE_HYBRID)
+IF(VTK_USE_PARALLEL)
+ SET(VTK_KITS ${VTK_KITS} PARALLEL)
+ENDIF(VTK_USE_PARALLEL)
+IF(VTK_USE_PATENTED)
+ SET(VTK_KITS ${VTK_KITS} PATENTED)
+ENDIF(VTK_USE_PATENTED)
+
+# Create the list of available languages.
+SET(VTK_LANGUAGES "")
+IF(VTK_WRAP_TCL)
+ SET(VTK_LANGUAGES ${VTK_LANGUAGES} TCL)
+ENDIF(VTK_WRAP_TCL)
+IF(VTK_WRAP_PYTHON)
+ SET(VTK_LANGUAGES ${VTK_LANGUAGES} PYTHON)
+ENDIF(VTK_WRAP_PYTHON)
+IF(VTK_WRAP_JAVA)
+ SET(VTK_LANGUAGES ${VTK_LANGUAGES} JAVA)
+ENDIF(VTK_WRAP_JAVA)
+
+# 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(VTK_USE_X)
+ENDIF(VTK_USE_RENDERING)
+
+IF(VTK_OPENGL_HAS_OSMESA)
+ SET(VTK_INCLUDE_DIRS_SYS ${VTK_INCLUDE_DIRS_SYS}
+ ${VTK40_OSMESA_INCLUDE_PATH})
+ENDIF(VTK_OPENGL_HAS_OSMESA)
+
+IF(VTK_USE_MPI)
+ SET(VTK_INCLUDE_DIRS_SYS ${VTK_INCLUDE_DIRS_SYS} ${VTK40_MPI_INCLUDE_PATH})
+ENDIF(VTK_USE_MPI)
+
+IF(VTK_WRAP_TCL)
+ SET(VTK_INCLUDE_DIRS_SYS ${VTK_INCLUDE_DIRS_SYS} ${VTK40_TCL_INCLUDE_PATH})
+ENDIF(VTK_WRAP_TCL)
+
+IF(VTK_WRAP_PYTHON)
+ SET(VTK_INCLUDE_DIRS_SYS ${VTK_INCLUDE_DIRS_SYS} ${VTK40_PYTHON_INCLUDE_PATH})
+ENDIF(VTK_WRAP_PYTHON)
+
+IF(VTK_WRAP_JAVA)
+ SET(VTK_INCLUDE_DIRS_SYS ${VTK_INCLUDE_DIRS_SYS}
+ ${VTK40_JAVA_INCLUDE_PATH} ${VTK40_JAVA_INCLUDE_PATH2})
+ENDIF(VTK_WRAP_JAVA)
+
+IF(VTK_HAVE_VG500)
+ SET(VTK_INCLUDE_DIRS_SYS ${VTK_INCLUDE_DIRS_SYS}
+ ${VTK40_VLI_INCLUDE_PATH_FOR_VG500})
+ENDIF(VTK_HAVE_VG500)
+
+IF(VTK_HAVE_VP1000)
+ SET(VTK_INCLUDE_DIRS_SYS ${VTK_INCLUDE_DIRS_SYS}
+ ${VTK40_VLI_INCLUDE_PATH_FOR_VP1000})
+ENDIF(VTK_HAVE_VP1000)
+
+# 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(VTK_USE_PARALLEL)
+ IF(VTK_USE_HYBRID)
+ SET(VTK_INCLUDE_DIRS ${VTK_INCLUDE_DIRS} ${VTK40_VTK_SOURCE_DIR}/Hybrid)
+ ENDIF(VTK_USE_HYBRID)
+ IF(VTK_USE_PATENTED)
+ SET(VTK_INCLUDE_DIRS ${VTK_INCLUDE_DIRS} ${VTK40_VTK_SOURCE_DIR}/Patented)
+ ENDIF(VTK_USE_PATENTED)
+ IF(VTK_USE_RENDERING)
+ SET(VTK_INCLUDE_DIRS ${VTK_INCLUDE_DIRS} ${VTK40_VTK_SOURCE_DIR}/Rendering)
+ ENDIF(VTK_USE_RENDERING)
+
+ # 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(VTK_WRAP_TCL)
+ IF(VTK_WRAP_PYTHON)
+ SET(VTK_WRAP_PYTHON_EXE ${VTK40_VTK_WRAP_PYTHON_EXE})
+ ENDIF(VTK_WRAP_PYTHON)
+ 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(VTK_WRAP_JAVA)
+
+ELSE(EXISTS ${VTK_DIR}/Common)
+ # 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(VTK_WRAP_TCL)
+ IF(VTK_WRAP_PYTHON)
+ SET(VTK_WRAP_PYTHON_EXE ${VTK40_CMAKE_INSTALL_PREFIX}/bin/vtkWrapPython)
+ ENDIF(VTK_WRAP_PYTHON)
+ 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(VTK_WRAP_JAVA)
+ENDIF(EXISTS ${VTK_DIR}/Common)
+
+# 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(WIN32)
+ELSE(CMAKE_COMPILER_IS_GNUCXX)
+ IF(CMAKE_ANSI_CFLAGS)
+ SET(VTK_REQUIRED_C_FLAGS "${VTK_REQUIRED_C_FLAGS} ${CMAKE_ANSI_CFLAGS}")
+ ENDIF(CMAKE_ANSI_CFLAGS)
+ IF(CMAKE_SYSTEM MATCHES "OSF1-V.*")
+ SET(VTK_REQUIRED_CXX_FLAGS
+ "${VTK_REQUIRED_CXX_FLAGS} -timplicit_local -no_implicit_include")
+ ENDIF(CMAKE_SYSTEM MATCHES "OSF1-V.*")
+ENDIF(CMAKE_COMPILER_IS_GNUCXX)
+
+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(CMAKE_X_CFLAGS)
+ENDIF(VTK_USE_X)
+
+# 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
new file mode 100644
index 000000000..01a15168e
--- /dev/null
+++ b/Modules/Use_wxWindows.cmake
@@ -0,0 +1,64 @@
+#
+# 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
+# INCLUDE( ${CMAKE_MODULE_PATH}/Use_wxWindows.cmake)
+##
+# if you are sure you need GL then
+# SET(WXWINDOWS_USE_GL 1)
+# *before* you include this file.
+
+#=============================================================================
+# Copyright 2003-2009 Kitware, Inc.
+# Copyright 2003 Jan Woetzel
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software 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.)
+
+# -----------------------------------------------------
+# 16.Feb.2004: changed INCLUDE to FIND_PACKAGE to read from users own non-system CMAKE_MODULE_PATH (Jan Woetzel JW)
+# 07/2006: rewrite as FindwxWidgets.cmake, kept for backward compatibility JW
+
+MESSAGE(STATUS "Use_wxWindows.cmake is DEPRECATED. \n"
+"Please use FIND_PACKAGE(wxWidgets) and INCLUDE(${wxWidgets_USE_FILE}) instead. (JW)")
+
+
+# ------------------------
+
+FIND_PACKAGE( wxWindows )
+
+IF(WXWINDOWS_FOUND)
+
+#MESSAGE("DBG Use_wxWindows.cmake: WXWINDOWS_INCLUDE_DIR=${WXWINDOWS_INCLUDE_DIR} WXWINDOWS_LINK_DIRECTORIES=${WXWINDOWS_LINK_DIRECTORIES} WXWINDOWS_LIBRARIES=${WXWINDOWS_LIBRARIES} CMAKE_WXWINDOWS_CXX_FLAGS=${CMAKE_WXWINDOWS_CXX_FLAGS} WXWINDOWS_DEFINITIONS=${WXWINDOWS_DEFINITIONS}")
+
+ IF(WXWINDOWS_INCLUDE_DIR)
+ INCLUDE_DIRECTORIES(${WXWINDOWS_INCLUDE_DIR})
+ ENDIF(WXWINDOWS_INCLUDE_DIR)
+ IF(WXWINDOWS_LINK_DIRECTORIES)
+ LINK_DIRECTORIES(${WXWINDOWS_LINK_DIRECTORIES})
+ ENDIF(WXWINDOWS_LINK_DIRECTORIES)
+ IF(WXWINDOWS_LIBRARIES)
+ LINK_LIBRARIES(${WXWINDOWS_LIBRARIES})
+ ENDIF(WXWINDOWS_LIBRARIES)
+ IF (CMAKE_WXWINDOWS_CXX_FLAGS)
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_WXWINDOWS_CXX_FLAGS}")
+ ENDIF(CMAKE_WXWINDOWS_CXX_FLAGS)
+ IF(WXWINDOWS_DEFINITIONS)
+ ADD_DEFINITIONS(${WXWINDOWS_DEFINITIONS})
+ ENDIF(WXWINDOWS_DEFINITIONS)
+ELSE(WXWINDOWS_FOUND)
+ MESSAGE(SEND_ERROR "wxWindows not found by Use_wxWindows.cmake")
+ENDIF(WXWINDOWS_FOUND)
+
diff --git a/Modules/UsewxWidgets.cmake b/Modules/UsewxWidgets.cmake
new file mode 100644
index 000000000..a0f2e8632
--- /dev/null
+++ b/Modules/UsewxWidgets.cmake
@@ -0,0 +1,89 @@
+# - 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})
+#
+# DEPRECATED
+# LINK_LIBRARIES is not called in favor of adding dependencies per target.
+#
+# AUTHOR
+# Jan Woetzel <jw -at- mip.informatik.uni-kiel.de>
+
+#=============================================================================
+# Copyright 2004-2009 Kitware, Inc.
+# Copyright 2006 Jan Woetzel
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software 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.)
+
+# debug message and logging.
+# comment these out for distribution
+IF (NOT LOGFILE )
+ # SET(LOGFILE "${PROJECT_BINARY_DIR}/CMakeOutput.log")
+ENDIF (NOT LOGFILE )
+MACRO(MSG _MSG)
+ # FILE(APPEND ${LOGFILE} "${CMAKE_CURRENT_LIST_FILE}(${CMAKE_CURRENT_LIST_LINE}): ${_MSG}\n")
+ # MESSAGE(STATUS "${CMAKE_CURRENT_LIST_FILE}(${CMAKE_CURRENT_LIST_LINE}): ${_MSG}")
+ENDMACRO(MSG)
+
+
+MSG("wxWidgets_FOUND=${wxWidgets_FOUND}")
+IF (wxWidgets_FOUND)
+ IF (wxWidgets_INCLUDE_DIRS)
+ IF(wxWidgets_INCLUDE_DIRS_NO_SYSTEM)
+ INCLUDE_DIRECTORIES(${wxWidgets_INCLUDE_DIRS})
+ ELSE(wxWidgets_INCLUDE_DIRS_NO_SYSTEM)
+ INCLUDE_DIRECTORIES(SYSTEM ${wxWidgets_INCLUDE_DIRS})
+ ENDIF(wxWidgets_INCLUDE_DIRS_NO_SYSTEM)
+ MSG("wxWidgets_INCLUDE_DIRS=${wxWidgets_INCLUDE_DIRS}")
+ ENDIF(wxWidgets_INCLUDE_DIRS)
+
+ IF (wxWidgets_LIBRARY_DIRS)
+ LINK_DIRECTORIES(${wxWidgets_LIBRARY_DIRS})
+ MSG("wxWidgets_LIBRARY_DIRS=${wxWidgets_LIBRARY_DIRS}")
+ ENDIF(wxWidgets_LIBRARY_DIRS)
+
+ IF (wxWidgets_DEFINITIONS)
+ SET_PROPERTY(DIRECTORY APPEND
+ PROPERTY COMPILE_DEFINITIONS ${wxWidgets_DEFINITIONS})
+ MSG("wxWidgets_DEFINITIONS=${wxWidgets_DEFINITIONS}")
+ ENDIF(wxWidgets_DEFINITIONS)
+
+ IF (wxWidgets_DEFINITIONS_DEBUG)
+ SET_PROPERTY(DIRECTORY APPEND
+ PROPERTY COMPILE_DEFINITIONS_DEBUG ${wxWidgets_DEFINITIONS_DEBUG})
+ MSG("wxWidgets_DEFINITIONS_DEBUG=${wxWidgets_DEFINITIONS_DEBUG}")
+ ENDIF(wxWidgets_DEFINITIONS_DEBUG)
+
+ IF (wxWidgets_CXX_FLAGS)
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${wxWidgets_CXX_FLAGS}")
+ MSG("wxWidgets_CXX_FLAGS=${wxWidgets_CXX_FLAGS}")
+ ENDIF(wxWidgets_CXX_FLAGS)
+
+ # DEPRECATED JW
+ # just for backward compatibility: add deps to all targets
+ # library projects better use advanced FIND_PACKAGE(wxWidgets) directly.
+ #IF(wxWidgets_LIBRARIES)
+ # LINK_LIBRARIES(${wxWidgets_LIBRARIES})
+ # # BUG: str too long: MSG("wxWidgets_LIBRARIES=${wxWidgets_LIBRARIES}")
+ # IF(LOGFILE)
+ # FILE(APPEND ${LOGFILE} "${CMAKE_CURRENT_LIST_FILE}(${CMAKE_CURRENT_LIST_LINE}): ${wxWidgets_LIBRARIES}\n")
+ # ENDIF(LOGFILE)
+ #ENDIF(wxWidgets_LIBRARIES)
+
+ELSE (wxWidgets_FOUND)
+ MESSAGE("wxWidgets requested but not found.")
+ENDIF(wxWidgets_FOUND)
diff --git a/Modules/VTKCompatibility.cmake b/Modules/VTKCompatibility.cmake
new file mode 100644
index 000000000..802969f2f
--- /dev/null
+++ b/Modules/VTKCompatibility.cmake
@@ -0,0 +1,52 @@
+
+#=============================================================================
+# 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.)
+
+IF(APPLE)
+ SET(CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_C_CREATE_SHARED_LIBRARY}")
+ SET(CMAKE_CXX_CREATE_SHARED_MODULE "${CMAKE_C_CREATE_SHARED_MODULE}")
+ STRING( REGEX REPLACE "CMAKE_C_COMPILER"
+ CMAKE_CXX_COMPILER CMAKE_CXX_CREATE_SHARED_MODULE
+ "${CMAKE_CXX_CREATE_SHARED_MODULE}")
+ STRING( REGEX REPLACE "CMAKE_C_COMPILER"
+ CMAKE_CXX_COMPILER CMAKE_CXX_CREATE_SHARED_LIBRARY
+ "${CMAKE_CXX_CREATE_SHARED_LIBRARY}")
+ENDIF(APPLE)
+
+SET(VTKFTGL_BINARY_DIR "${VTK_BINARY_DIR}/Utilities/ftgl"
+ CACHE INTERNAL "")
+SET(VTKFREETYPE_BINARY_DIR "${VTK_BINARY_DIR}/Utilities/freetype"
+ CACHE INTERNAL "")
+SET(VTKFTGL_SOURCE_DIR "${VTK_SOURCE_DIR}/Utilities/ftgl"
+ CACHE INTERNAL "")
+SET(VTKFREETYPE_SOURCE_DIR "${VTK_SOURCE_DIR}/Utilities/freetype"
+ CACHE INTERNAL "")
+
+SET(VTK_GLEXT_FILE "${VTK_SOURCE_DIR}/Utilities/ParseOGLExt/headers/glext.h"
+ CACHE FILEPATH
+ "Location of the OpenGL extensions header file (glext.h).")
+SET(VTK_GLXEXT_FILE
+ "${VTK_SOURCE_DIR}/Utilities/ParseOGLExt/headers/glxext.h" CACHE FILEPATH
+ "Location of the GLX extensions header file (glxext.h).")
+SET(VTK_WGLEXT_FILE "${VTK_SOURCE_DIR}/Utilities/ParseOGLExt/headers/wglext.h"
+ CACHE FILEPATH
+ "Location of the WGL extensions header file (wglext.h).")
+
+# work around an old bug in VTK
+SET(TIFF_RIGHT_VERSION 1)
+
+# for very old VTK (versions prior to 4.2)
+MACRO(SOURCE_FILES)
+ message (FATAL_ERROR "You are trying to build a very old version of VTK (prior to VTK 4.2). To do this you need to use CMake 2.0 as it was the last version of CMake to support VTK 4.0.")
+ENDMACRO(SOURCE_FILES)
+
diff --git a/Modules/WriteBasicConfigVersionFile.cmake b/Modules/WriteBasicConfigVersionFile.cmake
new file mode 100644
index 000000000..038cb5798
--- /dev/null
+++ b/Modules/WriteBasicConfigVersionFile.cmake
@@ -0,0 +1,44 @@
+# WRITE_BASIC_CONFIG_VERSION_FILE( filename VERSION major.minor.patch COMPATIBILITY (AnyNewerVersion|SameMajorVersion) )
+#
+# Deprecated, see WRITE_BASIC_PACKAGE_VERSION_FILE(), it is identical.
+
+#=============================================================================
+# Copyright 2008-2011 Alexander Neundorf, <neundorf@kde.org>
+# 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.)
+
+include(CMakeParseArguments)
+
+function(WRITE_BASIC_CONFIG_VERSION_FILE _filename)
+
+ set(options )
+ set(oneValueArgs VERSION COMPATIBILITY )
+ set(multiValueArgs )
+
+ cmake_parse_arguments(CVF "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+ if(CVF_UNPARSED_ARGUMENTS)
+ message(FATAL_ERROR "Unknown keywords given to WRITE_BASIC_CONFIG_VERSION_FILE(): \"${CVF_UNPARSED_ARGUMENTS}\"")
+ endif(CVF_UNPARSED_ARGUMENTS)
+
+ set(versionTemplateFile "${CMAKE_ROOT}/Modules/BasicConfigVersion-${CVF_COMPATIBILITY}.cmake.in")
+ if(NOT EXISTS "${versionTemplateFile}")
+ message(FATAL_ERROR "Bad COMPATIBILITY value used for WRITE_BASIC_CONFIG_VERSION_FILE(): \"${CVF_COMPATIBILITY}\"")
+ endif()
+
+ if("${CVF_VERSION}" STREQUAL "")
+ message(FATAL_ERROR "No VERSION specified for WRITE_BASIC_CONFIG_VERSION_FILE()")
+ endif()
+
+ configure_file("${versionTemplateFile}" "${_filename}" @ONLY)
+
+endfunction(WRITE_BASIC_CONFIG_VERSION_FILE)
diff --git a/Modules/ecos_clean.cmake b/Modules/ecos_clean.cmake
new file mode 100644
index 000000000..7a563ae23
--- /dev/null
+++ b/Modules/ecos_clean.cmake
@@ -0,0 +1,26 @@
+
+#=============================================================================
+# 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.)
+
+file(GLOB _files ${ECOS_DIR}/*)
+
+# remove all directories, which consist of lower-case letters only
+# this skips e.g. CVS/ and .subversion/
+foreach(_entry ${_files})
+ if(IS_DIRECTORY ${_entry})
+ get_filename_component(dir ${_entry} NAME)
+ if(${dir} MATCHES "^[a-z]+$")
+ file(REMOVE_RECURSE ${_entry})
+ endif(${dir} MATCHES "^[a-z]+$")
+ endif(IS_DIRECTORY ${_entry})
+endforeach(_entry)
diff --git a/Modules/exportheader.cmake.in b/Modules/exportheader.cmake.in
new file mode 100644
index 000000000..80a879d7e
--- /dev/null
+++ b/Modules/exportheader.cmake.in
@@ -0,0 +1,35 @@
+
+#ifndef @INCLUDE_GUARD_NAME@
+#define @INCLUDE_GUARD_NAME@
+
+#ifdef @STATIC_DEFINE@
+# define @EXPORT_MACRO_NAME@
+# define @NO_EXPORT_MACRO_NAME@
+#else
+# ifndef @EXPORT_MACRO_NAME@
+# ifdef @EXPORT_IMPORT_CONDITION@
+ /* We are building this library */
+# define @EXPORT_MACRO_NAME@ @DEFINE_EXPORT@
+# else
+ /* We are using this library */
+# define @EXPORT_MACRO_NAME@ @DEFINE_IMPORT@
+# endif
+# endif
+
+# ifndef @NO_EXPORT_MACRO_NAME@
+# define @NO_EXPORT_MACRO_NAME@ @DEFINE_NO_EXPORT@
+# endif
+#endif
+
+#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
+
+#cmakedefine01 DEFINE_NO_DEPRECATED
+#if DEFINE_NO_DEPRECATED
+# define @NO_DEPRECATED_MACRO_NAME@
+#endif
+
+#endif
diff --git a/Modules/kde3init_dummy.cpp.in b/Modules/kde3init_dummy.cpp.in
new file mode 100644
index 000000000..7135c73a1
--- /dev/null
+++ b/Modules/kde3init_dummy.cpp.in
@@ -0,0 +1,6 @@
+
+/* used by KDE3Macros.cmake */
+
+extern "C" int kdemain(int argc, char* argv[]);
+extern "C" int kdeinitmain(int argc, char* argv[]) { return kdemain(argc,argv); }
+int main(int argc, char* argv[]) { return kdemain(argc,argv); }
diff --git a/Modules/kde3uic.cmake b/Modules/kde3uic.cmake
new file mode 100644
index 000000000..6f904ac92
--- /dev/null
+++ b/Modules/kde3uic.cmake
@@ -0,0 +1,33 @@
+
+#=============================================================================
+# Copyright 2006-2009 Kitware, Inc.
+# Copyright 2006 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.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+# used internally by KDE3Macros.cmake
+# neundorf@kde.org
+
+
+EXECUTE_PROCESS(COMMAND ${KDE_UIC_EXECUTABLE}
+ -L ${KDE_UIC_PLUGIN_DIR} -nounload -tr tr2i18n
+ -impl ${KDE_UIC_H_FILE}
+ ${KDE_UIC_FILE}
+ OUTPUT_VARIABLE _uic_CONTENTS
+ ERROR_QUIET
+ )
+
+STRING(REGEX REPLACE "tr2i18n\\(\"\"\\)" "QString::null" _uic_CONTENTS "${_uic_CONTENTS}" )
+STRING(REGEX REPLACE "tr2i18n\\(\"\", \"\"\\)" "QString::null" _uic_CONTENTS "${_uic_CONTENTS}" )
+
+FILE(WRITE ${KDE_UIC_CPP_FILE} "#include <kdialog.h>\n#include <klocale.h>\n\n")
+FILE(APPEND ${KDE_UIC_CPP_FILE} "${_uic_CONTENTS}")
+
diff --git a/Modules/readme.txt b/Modules/readme.txt
new file mode 100644
index 000000000..7d61d8d27
--- /dev/null
+++ b/Modules/readme.txt
@@ -0,0 +1,151 @@
+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 relevent 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_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:
+
+# - 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.
+
+A package can be 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).
diff --git a/Readme.txt b/Readme.txt
new file mode 100644
index 000000000..11926bc53
--- /dev/null
+++ b/Readme.txt
@@ -0,0 +1,53 @@
+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/.cvsignore b/Source/.cvsignore
new file mode 100644
index 000000000..31e286c6d
--- /dev/null
+++ b/Source/.cvsignore
@@ -0,0 +1,5 @@
+ccommand___Win32_Debug
+Debug
+cmake___Win32_Debug
+ctest___Win32_Debug
+CMakeSetup.map
diff --git a/Source/.gitattributes b/Source/.gitattributes
new file mode 100644
index 000000000..cf4dabd86
--- /dev/null
+++ b/Source/.gitattributes
@@ -0,0 +1,2 @@
+# Preserve upstream indentation style.
+cm_sha2.* whitespace=indent-with-non-tab
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
new file mode 100644
index 000000000..e9c5a587e
--- /dev/null
+++ b/Source/CMakeLists.txt
@@ -0,0 +1,564 @@
+#=============================================================================
+# 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(CheckIncludeFile)
+# Check if we can build support for ELF parsing.
+CHECK_INCLUDE_FILE("elf.h" HAVE_ELF_H)
+IF(HAVE_ELF_H)
+ SET(CMAKE_USE_ELF_PARSER 1)
+ELSE(HAVE_ELF_H)
+ SET(CMAKE_USE_ELF_PARSER)
+ENDIF(HAVE_ELF_H)
+
+SET(EXECUTABLE_OUTPUT_PATH ${CMake_BIN_DIR})
+
+# configure the .h file
+CONFIGURE_FILE(
+ "${CMake_SOURCE_DIR}/Source/cmConfigure.cmake.h.in"
+ "${CMake_BINARY_DIR}/Source/cmConfigure.h"
+ )
+CONFIGURE_FILE(
+ "${CMake_SOURCE_DIR}/Source/cmVersionConfig.h.in"
+ "${CMake_BINARY_DIR}/Source/cmVersionConfig.h"
+ )
+CONFIGURE_FILE(
+ "${CMake_SOURCE_DIR}/Source/CPack/cmCPackConfigure.h.in"
+ "${CMake_BINARY_DIR}/Source/CPack/cmCPackConfigure.h"
+ )
+
+# add the include path to find the .h
+INCLUDE_DIRECTORIES(
+ "${CMake_BINARY_DIR}/Source"
+ "${CMake_SOURCE_DIR}/Source"
+ ${CMAKE_ZLIB_INCLUDES}
+ ${CMAKE_EXPAT_INCLUDES}
+ ${CMAKE_TAR_INCLUDES}
+ ${CMAKE_COMPRESS_INCLUDES}
+ )
+
+# let cmake know it is supposed to use it
+ADD_DEFINITIONS(-DCMAKE_BUILD_WITH_CMAKE)
+
+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)
+ FIND_PROGRAM(YACC_EXECUTABLE
+ NAMES yacc bison
+ PATHS /usr/bin
+ DOC "Yacc or Bison executable")
+ FIND_PROGRAM(FLEX_EXECUTABLE
+ NAMES flex
+ PATHS /usr/bin
+ DOC "Flex executable")
+ MARK_AS_ADVANCED(YACC_EXECUTABLE FLEX_EXECUTABLE)
+ IF(YACC_EXECUTABLE)
+ SET(BISON_FLAGS)
+ IF(YACC_EXECUTABLE MATCHES "bison")
+ SET(BISON_FLAGS "--yacc")
+ ENDIF(YACC_EXECUTABLE MATCHES "bison")
+ SET(yacc_files)
+ FOREACH(name ${parsersLexers})
+ SET(src "${CMAKE_CURRENT_SOURCE_DIR}/${name}Parser.y")
+ SET(dst "${CMAKE_CURRENT_BINARY_DIR}/${name}Parser.cxx")
+ SET(hdr "${CMAKE_CURRENT_BINARY_DIR}/${name}ParserTokens.h")
+ ADD_CUSTOM_COMMAND(
+ OUTPUT "${dst}"
+ DEPENDS "${src}"
+ COMMAND
+ ${YACC_EXECUTABLE}
+ --name-prefix=${name}_yy --defines=${hdr} -o${dst} ${src}
+ )
+ SET(yacc_files ${yacc_files} "${dst}")
+ ENDFOREACH(name)
+ ADD_CUSTOM_TARGET(RerunYacc DEPENDS ${yacc_files})
+ ENDIF(YACC_EXECUTABLE)
+ IF(FLEX_EXECUTABLE)
+ SET(lex_files)
+ FOREACH(name ${parsersLexers})
+ SET(src "${CMAKE_CURRENT_SOURCE_DIR}/${name}Lexer.in.l")
+ SET(dst "${CMAKE_CURRENT_BINARY_DIR}/${name}Lexer.cxx")
+ SET(hdr "${CMAKE_CURRENT_BINARY_DIR}/${name}Lexer.h")
+ ADD_CUSTOM_COMMAND(
+ OUTPUT "${dst}"
+ DEPENDS "${src}"
+ COMMAND
+ ${FLEX_EXECUTABLE}
+ --prefix=${name}_yy --header-file=${hdr} -o${dst} ${src}
+ )
+ SET(lex_files ${lex_files} "${dst}")
+ ENDFOREACH(name)
+ ADD_CUSTOM_TARGET(RerunLex DEPENDS ${lex_files})
+ ENDIF(FLEX_EXECUTABLE)
+
+ENDIF(CMAKE_REGENERATE_YACCLEX)
+
+# Check if we can build the ELF parser.
+IF(CMAKE_USE_ELF_PARSER)
+ SET(ELF_SRCS cmELF.h cmELF.cxx)
+ENDIF(CMAKE_USE_ELF_PARSER)
+
+#
+# Sources for CMakeLib
+#
+SET(SRCS
+ cmStandardIncludes.cxx
+ cmArchiveWrite.cxx
+ cmBootstrapCommands.cxx
+ cmCacheManager.cxx
+ cmCacheManager.h
+ cmCommands.cxx
+ cmCommands.h
+ cmCommandArgumentLexer.cxx
+ cmCommandArgumentParser.cxx
+ cmCommandArgumentParserHelper.cxx
+ cmComputeComponentGraph.cxx
+ cmComputeComponentGraph.h
+ cmComputeLinkDepends.cxx
+ cmComputeLinkDepends.h
+ cmComputeLinkInformation.cxx
+ cmComputeLinkInformation.h
+ cmComputeTargetDepends.h
+ cmComputeTargetDepends.cxx
+ cmCryptoHash.cxx
+ cmCryptoHash.h
+ cmCustomCommand.cxx
+ cmCustomCommand.h
+ cmCustomCommandGenerator.cxx
+ cmCustomCommandGenerator.h
+ cmDefinitions.cxx
+ cmDefinitions.h
+ cmDepends.cxx
+ cmDepends.h
+ cmDependsC.cxx
+ cmDependsC.h
+ cmDependsFortran.cxx
+ cmDependsFortran.h
+ cmDependsFortranLexer.cxx
+ cmDependsFortranParser.cxx
+ cmDependsFortranParser.h
+ cmDependsJava.cxx
+ cmDependsJava.h
+ cmDependsJavaLexer.cxx
+ cmDependsJavaParser.cxx
+ cmDependsJavaParserHelper.cxx
+ 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}
+ cmExprLexer.cxx
+ cmExprParser.cxx
+ cmExprParserHelper.cxx
+ cmExportBuildFileGenerator.h
+ cmExportBuildFileGenerator.cxx
+ cmExportFileGenerator.h
+ cmExportFileGenerator.cxx
+ cmExportInstallFileGenerator.h
+ cmExportInstallFileGenerator.cxx
+ cmExtraCodeBlocksGenerator.cxx
+ cmExtraCodeBlocksGenerator.h
+ cmExtraEclipseCDT4Generator.cxx
+ cmExtraEclipseCDT4Generator.h
+ cmFileTimeComparison.cxx
+ cmFileTimeComparison.h
+ cmGeneratedFileStream.cxx
+ cmGeneratorExpression.cxx
+ cmGeneratorExpression.h
+ cmGeneratorTarget.cxx
+ cmGeneratorTarget.h
+ cmGlobalGenerator.cxx
+ cmGlobalGenerator.h
+ cmGlobalUnixMakefileGenerator3.cxx
+ cmGlobalUnixMakefileGenerator3.h
+ cmGraphAdjacencyList.h
+ cmGraphVizWriter.cxx
+ cmGraphVizWriter.h
+ cmInstallGenerator.h
+ cmInstallGenerator.cxx
+ cmInstallExportGenerator.cxx
+ cmInstallFilesGenerator.h
+ cmInstallFilesGenerator.cxx
+ cmInstallScriptGenerator.h
+ cmInstallScriptGenerator.cxx
+ cmInstallTargetGenerator.h
+ cmInstallTargetGenerator.cxx
+ cmInstallDirectoryGenerator.h
+ cmInstallDirectoryGenerator.cxx
+ cmListFileCache.cxx
+ cmListFileCache.h
+ cmListFileLexer.c
+ cmLocalGenerator.cxx
+ cmLocalGenerator.h
+ cmLocalUnixMakefileGenerator3.cxx
+ cmMakeDepend.cxx
+ cmMakeDepend.h
+ cmMakefile.cxx
+ cmMakefile.h
+ cmMakefileTargetGenerator.cxx
+ cmMakefileExecutableTargetGenerator.cxx
+ cmMakefileLibraryTargetGenerator.cxx
+ cmMakefileUtilityTargetGenerator.cxx
+ cmOSXBundleGenerator.cxx
+ cmOSXBundleGenerator.h
+ cmNewLineStyle.h
+ cmNewLineStyle.cxx
+ cmOrderDirectories.cxx
+ cmOrderDirectories.h
+ cmPolicies.h
+ cmPolicies.cxx
+ cmProcessTools.cxx
+ cmProcessTools.h
+ cmProperty.cxx
+ cmProperty.h
+ cmPropertyDefinition.cxx
+ cmPropertyDefinition.h
+ cmPropertyDefinitionMap.cxx
+ cmPropertyDefinitionMap.h
+ cmPropertyMap.cxx
+ cmPropertyMap.h
+ cmQtAutomoc.cxx
+ cmQtAutomoc.h
+ cmScriptGenerator.h
+ cmScriptGenerator.cxx
+ cmSourceFile.cxx
+ cmSourceFile.h
+ cmSourceFileLocation.cxx
+ cmSourceFileLocation.h
+ cmSourceGroup.cxx
+ cmSourceGroup.h
+ cmSystemTools.cxx
+ cmSystemTools.h
+ cmTarget.cxx
+ cmTarget.h
+ cmTest.cxx
+ cmTest.h
+ cmTestGenerator.cxx
+ cmTestGenerator.h
+ cmVariableWatch.cxx
+ cmVariableWatch.h
+ cmVersion.cxx
+ cmVersion.h
+ cmXMLParser.cxx
+ cmXMLParser.h
+ cmXMLSafe.cxx
+ cmXMLSafe.h
+ cmake.cxx
+ cmake.h
+ cmakewizard.cxx
+ cmakewizard.h
+
+ cm_sha2.h
+ cm_sha2.c
+ cm_utf8.h
+ cm_utf8.c
+ )
+
+# Kdevelop only works on UNIX and not windows
+IF(UNIX)
+ SET(SRCS ${SRCS} cmGlobalKdevelopGenerator.cxx)
+ENDIF(UNIX)
+
+# Xcode only works on Apple
+IF(APPLE)
+ SET(SRCS ${SRCS}
+ cmXCodeObject.cxx
+ cmXCode21Object.cxx
+ cmGlobalXCodeGenerator.cxx
+ cmGlobalXCodeGenerator.h
+ cmLocalXCodeGenerator.cxx
+ cmLocalXCodeGenerator.h)
+ENDIF(APPLE)
+
+
+IF (WIN32)
+ SET(SRCS ${SRCS}
+ cmCallVisualStudioMacro.cxx
+ cmCallVisualStudioMacro.h
+ )
+
+ IF(NOT UNIX)
+ SET(SRCS ${SRCS}
+ cmGlobalBorlandMakefileGenerator.cxx
+ cmGlobalBorlandMakefileGenerator.h
+ cmGlobalMSYSMakefileGenerator.cxx
+ cmGlobalMinGWMakefileGenerator.cxx
+ cmGlobalNMakeMakefileGenerator.cxx
+ cmGlobalNMakeMakefileGenerator.h
+ cmGlobalJOMMakefileGenerator.cxx
+ cmGlobalJOMMakefileGenerator.h
+ cmGlobalVisualStudio6Generator.cxx
+ cmGlobalVisualStudio6Generator.h
+ cmGlobalVisualStudio71Generator.cxx
+ cmGlobalVisualStudio71Generator.h
+ cmGlobalVisualStudio7Generator.cxx
+ cmGlobalVisualStudio7Generator.h
+ cmGlobalVisualStudio8Generator.cxx
+ cmGlobalVisualStudio8Generator.h
+ cmGlobalVisualStudio9Generator.cxx
+ cmGlobalVisualStudio9Generator.h
+ cmGlobalVisualStudio8Win64Generator.cxx
+ cmGlobalVisualStudio8Win64Generator.h
+ cmGlobalVisualStudio9Win64Generator.cxx
+ cmGlobalVisualStudio9Win64Generator.h
+ cmGlobalVisualStudio9IA64Generator.cxx
+ cmGlobalVisualStudio9IA64Generator.h
+ cmVisualStudioGeneratorOptions.h
+ cmVisualStudioGeneratorOptions.cxx
+ cmVisualStudio10TargetGenerator.h
+ cmVisualStudio10TargetGenerator.cxx
+ cmLocalVisualStudio10Generator.cxx
+ cmLocalVisualStudio10Generator.h
+ cmGlobalVisualStudio10Generator.h
+ cmGlobalVisualStudio10Generator.cxx
+ cmGlobalVisualStudio10Win64Generator.h
+ cmGlobalVisualStudio10Win64Generator.cxx
+ cmGlobalVisualStudio10IA64Generator.h
+ cmGlobalVisualStudio10IA64Generator.cxx
+ cmGlobalVisualStudio11Generator.h
+ cmGlobalVisualStudio11Generator.cxx
+ cmGlobalVisualStudio11Win64Generator.h
+ cmGlobalVisualStudio11Win64Generator.cxx
+ cmGlobalVisualStudio11ARMGenerator.h
+ cmGlobalVisualStudio11ARMGenerator.cxx
+ cmGlobalVisualStudioGenerator.cxx
+ cmGlobalVisualStudioGenerator.h
+ cmGlobalWatcomWMakeGenerator.cxx
+ cmIDEFlagTable.h
+ cmIDEOptions.cxx
+ cmIDEOptions.h
+ cmLocalVisualStudio6Generator.cxx
+ cmLocalVisualStudio6Generator.h
+ cmLocalVisualStudio7Generator.cxx
+ cmLocalVisualStudio7Generator.h
+ cmLocalVisualStudioGenerator.cxx
+ cmLocalVisualStudioGenerator.h
+ cmWin32ProcessExecution.cxx
+ cmWin32ProcessExecution.h
+ )
+ ENDIF(NOT UNIX)
+ENDIF (WIN32)
+
+# Ninja support
+SET(SRCS ${SRCS}
+ cmGlobalNinjaGenerator.cxx
+ cmGlobalNinjaGenerator.h
+ cmNinjaTypes.h
+ cmLocalNinjaGenerator.cxx
+ cmLocalNinjaGenerator.h
+ cmNinjaTargetGenerator.cxx
+ cmNinjaTargetGenerator.h
+ cmNinjaNormalTargetGenerator.cxx
+ cmNinjaNormalTargetGenerator.h
+ cmNinjaUtilityTargetGenerator.cxx
+ cmNinjaUtilityTargetGenerator.h
+ )
+IF(WIN32 AND NOT CYGWIN AND NOT BORLAND)
+ SET_SOURCE_FILES_PROPERTIES(cmcldeps.cxx PROPERTIES COMPILE_DEFINITIONS _WIN32_WINNT=0x0501)
+ ADD_EXECUTABLE(cmcldeps cmcldeps.cxx)
+ TARGET_LINK_LIBRARIES(cmcldeps CMakeLib)
+ INSTALL_TARGETS(/bin cmcldeps)
+ENDIF()
+
+# 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} )
+
+# On Apple we need CoreFoundation
+IF(APPLE)
+ TARGET_LINK_LIBRARIES(CMakeLib "-framework CoreFoundation")
+ENDIF(APPLE)
+
+# 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)
+ENDIF(CMAKE_BUILD_ON_VISUAL_STUDIO OR MINGW)
+
+#
+# CTestLib
+#
+INCLUDE_DIRECTORIES(
+ "${CMake_SOURCE_DIR}/Source/CTest"
+ ${CMAKE_XMLRPC_INCLUDES}
+ ${CMAKE_CURL_INCLUDES}
+ )
+#
+# Sources for CTestLib
+#
+SET(CTEST_SRCS cmCTest.cxx
+ CTest/cmProcess.cxx
+ CTest/cmCTestBatchTestHandler.cxx
+ CTest/cmCTestBuildAndTestHandler.cxx
+ CTest/cmCTestBuildCommand.cxx
+ CTest/cmCTestBuildHandler.cxx
+ CTest/cmCTestConfigureCommand.cxx
+ CTest/cmCTestConfigureHandler.cxx
+ CTest/cmCTestCoverageCommand.cxx
+ CTest/cmCTestCoverageHandler.cxx
+ CTest/cmParseMumpsCoverage.cxx
+ CTest/cmParseCacheCoverage.cxx
+ CTest/cmParseGTMCoverage.cxx
+ CTest/cmParsePHPCoverage.cxx
+ CTest/cmCTestEmptyBinaryDirectoryCommand.cxx
+ CTest/cmCTestGenericHandler.cxx
+ CTest/cmCTestHandlerCommand.cxx
+ CTest/cmCTestLaunch.cxx
+ CTest/cmCTestMemCheckCommand.cxx
+ CTest/cmCTestMemCheckHandler.cxx
+ CTest/cmCTestMultiProcessHandler.cxx
+ CTest/cmCTestReadCustomFilesCommand.cxx
+ CTest/cmCTestRunScriptCommand.cxx
+ CTest/cmCTestRunTest.cxx
+ CTest/cmCTestScriptHandler.cxx
+ CTest/cmCTestSleepCommand.cxx
+ CTest/cmCTestStartCommand.cxx
+ CTest/cmCTestSubmitCommand.cxx
+ CTest/cmCTestSubmitHandler.cxx
+ CTest/cmCTestTestCommand.cxx
+ CTest/cmCTestTestHandler.cxx
+ CTest/cmCTestUpdateCommand.cxx
+ CTest/cmCTestUpdateHandler.cxx
+ CTest/cmCTestUploadCommand.cxx
+ CTest/cmCTestUploadHandler.cxx
+
+ CTest/cmCTestVC.cxx
+ CTest/cmCTestVC.h
+ CTest/cmCTestGlobalVC.cxx
+ CTest/cmCTestGlobalVC.h
+ CTest/cmCTestCVS.cxx
+ CTest/cmCTestCVS.h
+ CTest/cmCTestSVN.cxx
+ CTest/cmCTestSVN.h
+ CTest/cmCTestBZR.cxx
+ CTest/cmCTestBZR.h
+ CTest/cmCTestGIT.cxx
+ CTest/cmCTestGIT.h
+ CTest/cmCTestHG.cxx
+ CTest/cmCTestHG.h
+ )
+
+# Build CTestLib
+ADD_LIBRARY(CTestLib ${CTEST_SRCS})
+TARGET_LINK_LIBRARIES(CTestLib CMakeLib ${CMAKE_CURL_LIBRARIES} ${CMAKE_XMLRPC_LIBRARIES})
+
+#
+# Sources for CPack
+#
+SET(CPACK_SRCS
+ CPack/cmCPackArchiveGenerator.cxx
+ CPack/cmCPackComponentGroup.cxx
+ CPack/cmCPackGeneratorFactory.cxx
+ CPack/cmCPackGenerator.cxx
+ CPack/cmCPackLog.cxx
+ CPack/cmCPackNSISGenerator.cxx
+ CPack/cmCPackSTGZGenerator.cxx
+ CPack/cmCPackTGZGenerator.cxx
+ CPack/cmCPackTarBZip2Generator.cxx
+ CPack/cmCPackTarCompressGenerator.cxx
+ CPack/cmCPackZIPGenerator.cxx
+ CPack/cmCPackDocumentVariables.cxx
+ CPack/cmCPackDocumentMacros.cxx
+ )
+
+IF(CYGWIN)
+ SET(CPACK_SRCS ${CPACK_SRCS}
+ CPack/cmCPackCygwinBinaryGenerator.cxx
+ CPack/cmCPackCygwinSourceGenerator.cxx
+ )
+ENDIF(CYGWIN)
+
+IF(UNIX)
+ SET(CPACK_SRCS ${CPACK_SRCS}
+ CPack/cmCPackDebGenerator.cxx
+ CPack/cmCPackRPMGenerator.cxx
+ )
+ENDIF(UNIX)
+
+IF(APPLE)
+ SET(CPACK_SRCS ${CPACK_SRCS}
+ CPack/cmCPackBundleGenerator.cxx
+ CPack/cmCPackDragNDropGenerator.cxx
+ CPack/cmCPackOSXX11Generator.cxx
+ CPack/cmCPackPackageMakerGenerator.cxx
+ )
+ENDIF(APPLE)
+
+# Build CPackLib
+ADD_LIBRARY(CPackLib ${CPACK_SRCS})
+TARGET_LINK_LIBRARIES(CPackLib CMakeLib)
+
+IF(APPLE)
+ ADD_EXECUTABLE(cmakexbuild cmakexbuild.cxx)
+ TARGET_LINK_LIBRARIES(cmakexbuild CMakeLib)
+ ADD_EXECUTABLE(OSXScriptLauncher
+ CPack/OSXScriptLauncher.cxx)
+ TARGET_LINK_LIBRARIES(OSXScriptLauncher cmsys)
+ TARGET_LINK_LIBRARIES(OSXScriptLauncher "-framework CoreFoundation")
+ENDIF(APPLE)
+
+# Build CMake executable
+ADD_EXECUTABLE(cmake cmakemain.cxx)
+TARGET_LINK_LIBRARIES(cmake CMakeLib)
+
+# Build special executable for running programs on Windows 98
+IF(WIN32)
+ IF(NOT UNIX)
+ ADD_EXECUTABLE(cmw9xcom cmw9xcom.cxx)
+ TARGET_LINK_LIBRARIES(cmw9xcom CMakeLib)
+ INSTALL_TARGETS(/bin cmw9xcom)
+ ENDIF(NOT UNIX)
+ENDIF(WIN32)
+
+# Build CTest executable
+ADD_EXECUTABLE(ctest ctest.cxx)
+TARGET_LINK_LIBRARIES(ctest CTestLib)
+
+# Build CPack executable
+ADD_EXECUTABLE(cpack CPack/cpack.cxx)
+TARGET_LINK_LIBRARIES(cpack CPackLib)
+
+# Curses GUI
+IF(BUILD_CursesDialog)
+ INCLUDE(${CMake_SOURCE_DIR}/Source/CursesDialog/CMakeLists.txt)
+ENDIF(BUILD_CursesDialog)
+
+# Qt GUI
+OPTION(BUILD_QtDialog "Build Qt dialog for CMake" FALSE)
+IF(BUILD_QtDialog)
+ SUBDIRS(QtDialog)
+ENDIF(BUILD_QtDialog)
+
+INCLUDE (${CMake_BINARY_DIR}/Source/LocalUserOptions.cmake OPTIONAL)
+INCLUDE (${CMake_SOURCE_DIR}/Source/LocalUserOptions.cmake OPTIONAL)
+
+INSTALL_TARGETS(/bin cmake)
+INSTALL_TARGETS(/bin ctest)
+INSTALL_TARGETS(/bin cpack)
+IF(APPLE)
+ INSTALL_TARGETS(/bin cmakexbuild)
+ENDIF(APPLE)
+
+INSTALL_FILES(${CMAKE_DATA_DIR}/include cmCPluginAPI.h)
diff --git a/Source/CMakeVersion.bash b/Source/CMakeVersion.bash
new file mode 100755
index 000000000..126adba8e
--- /dev/null
+++ b/Source/CMakeVersion.bash
@@ -0,0 +1,7 @@
+#!/usr/bin/env bash
+# Update the version component if it looks like a date or -f is given.
+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/
+' "${BASH_SOURCE%/*}/CMakeVersion.cmake"
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
new file mode 100644
index 000000000..d124b660c
--- /dev/null
+++ b/Source/CMakeVersion.cmake
@@ -0,0 +1,6 @@
+# CMake version number components.
+SET(CMake_VERSION_MAJOR 2)
+SET(CMake_VERSION_MINOR 8)
+SET(CMake_VERSION_PATCH 9)
+SET(CMake_VERSION_TWEAK 0)
+#SET(CMake_VERSION_RC 3)
diff --git a/Source/CMakeVersionSource.cmake b/Source/CMakeVersionSource.cmake
new file mode 100644
index 000000000..05e265c03
--- /dev/null
+++ b/Source/CMakeVersionSource.cmake
@@ -0,0 +1,37 @@
+# Try to identify the current development source version.
+set(CMake_VERSION_SOURCE "")
+if(EXISTS ${CMake_SOURCE_DIR}/.git/HEAD)
+ find_program(GIT_EXECUTABLE NAMES git git.cmd)
+ mark_as_advanced(GIT_EXECUTABLE)
+ if(GIT_EXECUTABLE)
+ execute_process(
+ COMMAND ${GIT_EXECUTABLE} rev-parse --verify -q --short=4 HEAD
+ OUTPUT_VARIABLE head
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ WORKING_DIRECTORY ${CMake_SOURCE_DIR}
+ )
+ if(head)
+ set(CMake_VERSION_SOURCE "g${head}")
+ execute_process(
+ COMMAND ${GIT_EXECUTABLE} update-index -q --refresh
+ WORKING_DIRECTORY ${CMake_SOURCE_DIR}
+ )
+ execute_process(
+ COMMAND ${GIT_EXECUTABLE} diff-index --name-only HEAD --
+ OUTPUT_VARIABLE dirty
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ WORKING_DIRECTORY ${CMake_SOURCE_DIR}
+ )
+ if(dirty)
+ set(CMake_VERSION_SOURCE "${CMake_VERSION_SOURCE}-dirty")
+ endif()
+ endif()
+ endif()
+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}")
+ endif()
+ set(CMake_VERSION_SOURCE "cvs${branch}")
+endif()
diff --git a/Source/CPack/OSXLauncherScript.scpt b/Source/CPack/OSXLauncherScript.scpt
new file mode 100644
index 000000000..342cf8c01
--- /dev/null
+++ b/Source/CPack/OSXLauncherScript.scpt
Binary files differ
diff --git a/Source/CPack/OSXScriptLauncher.cxx b/Source/CPack/OSXScriptLauncher.cxx
new file mode 100644
index 000000000..e0fbe9b75
--- /dev/null
+++ b/Source/CPack/OSXScriptLauncher.cxx
@@ -0,0 +1,147 @@
+/*============================================================================
+ 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 <cmsys/SystemTools.hxx>
+#include <cmsys/Process.h>
+#include <cmsys/ios/fstream>
+#include <cmsys/ios/iostream>
+
+#include <CoreFoundation/CoreFoundation.h>
+
+// For the PATH_MAX constant
+#include <sys/syslimits.h>
+
+#define DebugError(x) \
+ ofs << x << cmsys_ios::endl; \
+ cmsys_ios::cout << x << cmsys_ios::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");
+
+ CFStringRef fileName;
+ CFBundleRef appBundle;
+ CFURLRef scriptFileURL;
+ UInt8 *path;
+
+ //get CF URL for script
+ if (! (appBundle = CFBundleGetMainBundle()))
+ {
+ DebugError("Cannot get main bundle");
+ return 1;
+ }
+ fileName = CFSTR("RuntimeScript");
+ if (! (scriptFileURL = CFBundleCopyResourceURL(appBundle, fileName, NULL,
+ NULL)))
+ {
+ DebugError("CFBundleCopyResourceURL failed");
+ return 1;
+ }
+
+ //create path string
+ if (! (path = new UInt8[PATH_MAX]))
+ {
+ return 1;
+ }
+
+ //get the file system path of the url as a cstring
+ //in an encoding suitable for posix apis
+ if ( CFURLGetFileSystemRepresentation(scriptFileURL, true, path,
+ PATH_MAX) == false)
+ {
+ DebugError("CFURLGetFileSystemRepresentation failed");
+ return 1;
+ }
+
+ //dispose of the CF variable
+ CFRelease(scriptFileURL);
+
+ cmsys_stl::string fullScriptPath = reinterpret_cast<char*>(path);
+ delete [] path;
+
+
+ if (! cmsys::SystemTools::FileExists(fullScriptPath.c_str()))
+ {
+ return 1;
+ }
+
+ cmsys_stl::string scriptDirectory = cmsys::SystemTools::GetFilenamePath(
+ fullScriptPath);
+ ofs << fullScriptPath.c_str() << cmsys_ios::endl;
+ cmsys_stl::vector<const char*> args;
+ args.push_back(fullScriptPath.c_str());
+ int cc;
+ for ( cc = 1; cc < argc; ++ cc )
+ {
+ args.push_back(argv[cc]);
+ }
+ args.push_back(0);
+
+ cmsysProcess* cp = cmsysProcess_New();
+ cmsysProcess_SetCommand(cp, &*args.begin());
+ cmsysProcess_SetWorkingDirectory(cp, scriptDirectory.c_str());
+ cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1);
+ cmsysProcess_SetTimeout(cp, 0);
+ cmsysProcess_Execute(cp);
+
+ std::vector<char> tempOutput;
+ char* data;
+ int length;
+ while(cmsysProcess_WaitForData(cp, &data, &length, 0))
+ {
+ // 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')
+ {
+ data[i] = ' ';
+ }
+ }
+ cmsys_ios::cout.write(data, length);
+ }
+
+ cmsysProcess_WaitForExit(cp, 0);
+
+ bool result = true;
+ if(cmsysProcess_GetState(cp) == cmsysProcess_State_Exited)
+ {
+ if ( cmsysProcess_GetExitValue(cp) != 0 )
+ {
+ result = false;
+ }
+ }
+ else if(cmsysProcess_GetState(cp) == cmsysProcess_State_Exception)
+ {
+ const char* exception_str = cmsysProcess_GetExceptionString(cp);
+ std::cerr << exception_str << std::endl;
+ result = false;
+ }
+ else if(cmsysProcess_GetState(cp) == cmsysProcess_State_Error)
+ {
+ const char* error_str = cmsysProcess_GetErrorString(cp);
+ std::cerr << error_str << std::endl;
+ result = false;
+ }
+ else if(cmsysProcess_GetState(cp) == cmsysProcess_State_Expired)
+ {
+ const char* error_str = "Process terminated due to timeout\n";
+ std::cerr << error_str << std::endl;
+ result = false;
+ }
+
+ cmsysProcess_Delete(cp);
+
+ return 0;
+}
diff --git a/Source/CPack/bills-comments.txt b/Source/CPack/bills-comments.txt
new file mode 100644
index 000000000..f73499d01
--- /dev/null
+++ b/Source/CPack/bills-comments.txt
@@ -0,0 +1,68 @@
+cpack.cxx
+
+cmCPackGenerators -- creates cmCPackGenericGenerator's via NewGenerator
+ - a cmCPackGenericGenerator factory
+
+
+cmCPackGenericGenerator::Initialize
+ this->InitializeInternal
+ CPACK_INCLUDE_TOPLEVEL_DIRECTORY = 0 turns off
+
+
+// binary package run
+cmCPackGenericGenerator::ProcessGenerator // DoPackage
+ cmCPackGenericGenerator::PrepareNames -- sets a bunch of CPACK_vars
+ cmCPackGenericGenerator::InstallProject
+ run preinstall (make preinstall/fast)
+ call ReadListFile(cmake_install.cmake)
+ glob recurse in install directory to get list of files
+ this->CompressFiles with the list of files
+
+
+// source package run
+cmCPackGenericGenerator::ProcessGenerator // DoPackage
+ cmCPackGenericGenerator::PrepareNames -- sets a bunch of CPACK_vars
+ cmCPackGenericGenerator::InstallProject -->
+ if set CPACK_INSTALLED_DIRECTORIES
+ glob the files in that directory
+ copy those files to the tmp install directory _CPack something
+ glob recurse in install directory to get list of files
+ this->CompressFiles with the list of files
+
+
+cmCPackGenericGenerator::InstallProject is used for both source and binary
+packages. It is controled based on values set in CPACK_ variables.
+
+
+InstallProject
+ 1. CPACK_INSTALL_COMMANDS - a list of commands used to install the package
+
+ 2. CPACK_INSTALLED_DIRECTORIES - copy this directory to CPACK_TEMPORARY_DIRECTORY
+
+ 3. CPACK_INSTALL_CMAKE_PROJECTS - a cmake install script
+ - run make preinstall
+ - run cmake_install.cmake
+ - set CMAKE_INSTALL_PREFIX to the temp directory
+ - CPACK_BUILD_CONFIG check this and set the BUILD_TYPE to it
+ - ReadListFile on the install script cmake_install.cmake
+ - run strip on the executables and libraries if CPACK_STRIP_FILES is TRUE
+
+Recommendations:
+
+rename cmCPackGenerators to cmCPackGeneratorFactory
+
+rename cmCPackGenericGenerator --> cmCPackGenerator
+
+rename cmCPackGenericGenerator::ProcessGenerator -> cmCPackGenerator::DoPackage
+
+
+break up cmCPackGenerator::InstallProject so it calls the following:
+
+// run user provided install commands
+ cmCPackGenerator::RunInstallCommands();
+// copy entire directories that need no processing like source trees
+ cmCPackGenerator::CopyPreInstalledDirectories();
+// run the cmake install scripts if provided
+ cmCPackGenerator::RunCMakeInstallScripts()
+
+-
diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx
new file mode 100644
index 000000000..6e7b8d7c8
--- /dev/null
+++ b/Source/CPack/cmCPackArchiveGenerator.cxx
@@ -0,0 +1,314 @@
+/*============================================================================
+ 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 "cmCPackArchiveGenerator.h"
+
+#include "cmake.h"
+#include "cmGlobalGenerator.h"
+#include "cmLocalGenerator.h"
+#include "cmSystemTools.h"
+#include "cmMakefile.h"
+#include "cmGeneratedFileStream.h"
+#include "cmCPackLog.h"
+#include <errno.h>
+
+#include <cmsys/SystemTools.hxx>
+#include <cmsys/Directory.hxx>
+#include <cm_libarchive.h>
+
+//----------------------------------------------------------------------
+cmCPackArchiveGenerator::cmCPackArchiveGenerator(cmArchiveWrite::Compress t,
+ cmArchiveWrite::Type at)
+{
+ this->Compress = t;
+ this->Archive = at;
+}
+
+//----------------------------------------------------------------------
+cmCPackArchiveGenerator::~cmCPackArchiveGenerator()
+{
+}
+
+//----------------------------------------------------------------------
+int cmCPackArchiveGenerator::InitializeInternal()
+{
+ this->SetOptionIfNotSet("CPACK_INCLUDE_TOPLEVEL_DIRECTORY", "1");
+ return this->Superclass::InitializeInternal();
+}
+//----------------------------------------------------------------------
+int cmCPackArchiveGenerator::addOneComponentToArchive(cmArchiveWrite& archive,
+ cmCPackComponent* component)
+{
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE, " - packaging component: "
+ << component->Name
+ << std::endl);
+ // Add the files of this component to the archive
+ std::string localToplevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY"));
+ localToplevel += "/"+ component->Name;
+ std::string dir = cmSystemTools::GetCurrentWorkingDirectory();
+ // Change to local toplevel
+ cmSystemTools::ChangeDirectory(localToplevel.c_str());
+ std::string filePrefix;
+ if (this->IsOn("CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY"))
+ {
+ filePrefix = this->GetOption("CPACK_PACKAGE_FILE_NAME");
+ filePrefix += "/";
+ }
+ std::vector<std::string>::const_iterator fileIt;
+ for (fileIt = component->Files.begin(); fileIt != component->Files.end();
+ ++fileIt )
+ {
+ std::string rp = filePrefix + *fileIt;
+ cmCPackLogger(cmCPackLog::LOG_DEBUG,"Adding file: "
+ << rp << std::endl);
+ archive.Add(rp);
+ if (!archive)
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "ERROR while packaging files: "
+ << archive.GetError()
+ << std::endl);
+ return 0;
+ }
+ }
+ // Go back to previous dir
+ cmSystemTools::ChangeDirectory(dir.c_str());
+ return 1;
+}
+
+/*
+ * The macro will open/create a file 'filename'
+ * an declare and open the associated
+ * cmArchiveWrite 'archive' object.
+ */
+#define DECLARE_AND_OPEN_ARCHIVE(filename,archive) \
+cmGeneratedFileStream gf; \
+gf.Open(filename.c_str(), false, true); \
+if (!GenerateHeader(&gf)) \
+ { \
+ cmCPackLogger(cmCPackLog::LOG_ERROR, \
+ "Problem to generate Header for archive < " \
+ << filename \
+ << ">." << std::endl); \
+ return 0; \
+ } \
+cmArchiveWrite archive(gf,this->Compress, this->Archive); \
+if (!archive) \
+ { \
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem to create archive < " \
+ << filename \
+ << ">. ERROR =" \
+ << archive.GetError() \
+ << std::endl); \
+ return 0; \
+ }
+
+//----------------------------------------------------------------------
+int cmCPackArchiveGenerator::PackageComponents(bool ignoreGroup)
+{
+ packageFileNames.clear();
+ // The default behavior is to have one package by component group
+ // unless CPACK_COMPONENTS_IGNORE_GROUP is specified.
+ if (!ignoreGroup)
+ {
+ std::map<std::string, cmCPackComponentGroup>::iterator compGIt;
+ for (compGIt=this->ComponentGroups.begin();
+ compGIt!=this->ComponentGroups.end(); ++compGIt)
+ {
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Packaging component group: "
+ << compGIt->first
+ << std::endl);
+ // Begin the archive for this group
+ std::string packageFileName= std::string(toplevel);
+ packageFileName += "/"+
+ GetComponentPackageFileName(this->GetOption("CPACK_PACKAGE_FILE_NAME"),
+ compGIt->first,
+ true)
+ + this->GetOutputExtension();
+ // open a block in order to automatically close archive
+ // at the end of the block
+ {
+ DECLARE_AND_OPEN_ARCHIVE(packageFileName,archive);
+ // now iterate over the component of this group
+ std::vector<cmCPackComponent*>::iterator compIt;
+ for (compIt=(compGIt->second).Components.begin();
+ compIt!=(compGIt->second).Components.end();
+ ++compIt)
+ {
+ // Add the files of this component to the archive
+ addOneComponentToArchive(archive,*compIt);
+ }
+ }
+ // add the generated package to package file names list
+ packageFileNames.push_back(packageFileName);
+ }
+ // Handle Orphan components (components not belonging to any groups)
+ std::map<std::string, cmCPackComponent>::iterator compIt;
+ for (compIt=this->Components.begin();
+ compIt!=this->Components.end(); ++compIt )
+ {
+ // Does the component belong to a group?
+ if (compIt->second.Group==NULL)
+ {
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE,
+ "Component <"
+ << compIt->second.Name
+ << "> does not belong to any group, package it separately."
+ << std::endl);
+ std::string localToplevel(
+ this->GetOption("CPACK_TEMPORARY_DIRECTORY")
+ );
+ std::string packageFileName = std::string(toplevel);
+
+ localToplevel += "/"+ compIt->first;
+ packageFileName += "/"+
+ GetComponentPackageFileName(this->GetOption("CPACK_PACKAGE_FILE_NAME"),
+ compIt->first,
+ false)
+ + this->GetOutputExtension();
+ {
+ DECLARE_AND_OPEN_ARCHIVE(packageFileName,archive);
+ // Add the files of this component to the archive
+ addOneComponentToArchive(archive,&(compIt->second));
+ }
+ // add the generated package to package file names list
+ packageFileNames.push_back(packageFileName);
+ }
+ }
+ }
+ // CPACK_COMPONENTS_IGNORE_GROUPS is set
+ // We build 1 package per component
+ else
+ {
+ std::map<std::string, cmCPackComponent>::iterator compIt;
+ for (compIt=this->Components.begin();
+ compIt!=this->Components.end(); ++compIt )
+ {
+ std::string localToplevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY"));
+ std::string packageFileName = std::string(toplevel);
+
+ localToplevel += "/"+ compIt->first;
+ packageFileName += "/"+
+ GetComponentPackageFileName(this->GetOption("CPACK_PACKAGE_FILE_NAME"),
+ compIt->first,
+ false)
+ + this->GetOutputExtension();
+ {
+ DECLARE_AND_OPEN_ARCHIVE(packageFileName,archive);
+ // Add the files of this component to the archive
+ addOneComponentToArchive(archive,&(compIt->second));
+ }
+ // add the generated package to package file names list
+ packageFileNames.push_back(packageFileName);
+ }
+ }
+ return 1;
+}
+
+//----------------------------------------------------------------------
+int cmCPackArchiveGenerator::PackageComponentsAllInOne()
+{
+ // reset the package file names
+ packageFileNames.clear();
+ packageFileNames.push_back(std::string(toplevel));
+ packageFileNames[0] += "/"
+ +std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME"))
+ + this->GetOutputExtension();
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE,
+ "Packaging all groups in one package..."
+ "(CPACK_COMPONENTS_ALL_GROUPS_IN_ONE_PACKAGE is set)"
+ << std::endl);
+ DECLARE_AND_OPEN_ARCHIVE(packageFileNames[0],archive);
+
+ // The ALL COMPONENTS in ONE package case
+ std::map<std::string, cmCPackComponent>::iterator compIt;
+ for (compIt=this->Components.begin();compIt!=this->Components.end();
+ ++compIt )
+ {
+ // Add the files of this component to the archive
+ addOneComponentToArchive(archive,&(compIt->second));
+ }
+
+ // archive goes out of scope so it will finalized and closed.
+ return 1;
+}
+
+//----------------------------------------------------------------------
+int cmCPackArchiveGenerator::PackageFiles()
+{
+ cmCPackLogger(cmCPackLog::LOG_DEBUG, "Toplevel: "
+ << toplevel << std::endl);
+
+ if (WantsComponentInstallation()) {
+ // CASE 1 : COMPONENT ALL-IN-ONE package
+ // If ALL COMPONENTS in ONE package has been requested
+ // then the package file is unique and should be open here.
+ if (componentPackageMethod == ONE_PACKAGE)
+ {
+ return PackageComponentsAllInOne();
+ }
+ // CASE 2 : COMPONENT CLASSICAL package(s) (i.e. not all-in-one)
+ // There will be 1 package for each component group
+ // however one may require to ignore component group and
+ // in this case you'll get 1 package for each component.
+ else
+ {
+ return PackageComponents(componentPackageMethod ==
+ ONE_PACKAGE_PER_COMPONENT);
+ }
+ }
+
+ // CASE 3 : NON COMPONENT package.
+ DECLARE_AND_OPEN_ARCHIVE(packageFileNames[0],archive);
+ std::vector<std::string>::const_iterator fileIt;
+ std::string dir = cmSystemTools::GetCurrentWorkingDirectory();
+ cmSystemTools::ChangeDirectory(toplevel.c_str());
+ 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);
+ if(!archive)
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem while adding file< "
+ << *fileIt
+ << "> to archive <"
+ << packageFileNames[0] << "> .ERROR ="
+ << archive.GetError()
+ << std::endl);
+ return 0;
+ }
+ }
+ cmSystemTools::ChangeDirectory(dir.c_str());
+ // The destructor of cmArchiveWrite will close and finish the write
+ return 1;
+}
+
+//----------------------------------------------------------------------
+int cmCPackArchiveGenerator::GenerateHeader(std::ostream*)
+{
+ return 1;
+}
+
+bool cmCPackArchiveGenerator::SupportsComponentInstallation() const {
+ // The Component installation support should only
+ // be activated if explicitly requested by the user
+ // (for backward compatibility reason)
+ if (IsOn("CPACK_ARCHIVE_COMPONENT_INSTALL"))
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
diff --git a/Source/CPack/cmCPackArchiveGenerator.h b/Source/CPack/cmCPackArchiveGenerator.h
new file mode 100644
index 000000000..b1bbb8363
--- /dev/null
+++ b/Source/CPack/cmCPackArchiveGenerator.h
@@ -0,0 +1,74 @@
+/*============================================================================
+ 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 cmCPackArchiveGenerator_h
+#define cmCPackArchiveGenerator_h
+
+#include "cmArchiveWrite.h"
+#include "cmCPackGenerator.h"
+
+
+/** \class cmCPackArchiveGenerator
+ * \brief A generator base for libarchive generation.
+ * The generator itself uses the libarchive wrapper
+ * \ref cmArchiveWrite.
+ *
+ */
+class cmCPackArchiveGenerator : public cmCPackGenerator
+ {
+public:
+ cmTypeMacro(cmCPackArchiveGenerator, cmCPackGenerator);
+
+ /**
+ * Construct generator
+ */
+ cmCPackArchiveGenerator(cmArchiveWrite::Compress, cmArchiveWrite::Type);
+ virtual ~cmCPackArchiveGenerator();
+ // Used to add a header to the archive
+ virtual int GenerateHeader(std::ostream* os);
+ // component support
+ virtual bool SupportsComponentInstallation() const;
+protected:
+ virtual int InitializeInternal();
+ /**
+ * Add the files belonging to the specified component
+ * to the provided (already opened) archive.
+ * @param[in,out] archive the archive object
+ * @param[in] component the component whose file will be added to archive
+ */
+ int addOneComponentToArchive(cmArchiveWrite& archive,
+ cmCPackComponent* component);
+
+ /**
+ * The main package file method.
+ * If component install was required this
+ * method will call either PackageComponents or
+ * PackageComponentsAllInOne.
+ */
+ int PackageFiles();
+ /**
+ * The method used to package files when component
+ * install is used. This will create one
+ * archive for each component group.
+ */
+ int PackageComponents(bool ignoreGroup);
+ /**
+ * Special case of component install where all
+ * components will be put in a single installer.
+ */
+ int PackageComponentsAllInOne();
+ virtual const char* GetOutputExtension() = 0;
+ cmArchiveWrite::Compress Compress;
+ cmArchiveWrite::Type Archive;
+ };
+
+#endif
diff --git a/Source/CPack/cmCPackBundleGenerator.cxx b/Source/CPack/cmCPackBundleGenerator.cxx
new file mode 100644
index 000000000..af78e7822
--- /dev/null
+++ b/Source/CPack/cmCPackBundleGenerator.cxx
@@ -0,0 +1,174 @@
+/*============================================================================
+ 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 "cmCPackBundleGenerator.h"
+#include "cmCPackLog.h"
+#include "cmSystemTools.h"
+
+#include <cmsys/RegularExpression.hxx>
+
+//----------------------------------------------------------------------
+cmCPackBundleGenerator::cmCPackBundleGenerator()
+{
+}
+
+//----------------------------------------------------------------------
+cmCPackBundleGenerator::~cmCPackBundleGenerator()
+{
+}
+
+//----------------------------------------------------------------------
+int cmCPackBundleGenerator::InitializeInternal()
+{
+ const char* name = this->GetOption("CPACK_BUNDLE_NAME");
+ if(0 == name)
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "CPACK_BUNDLE_NAME must be set to use the Bundle generator."
+ << std::endl);
+
+ return 0;
+ }
+
+ return this->Superclass::InitializeInternal();
+}
+
+//----------------------------------------------------------------------
+const char* cmCPackBundleGenerator::GetPackagingInstallPrefix()
+{
+ this->InstallPrefix = "/";
+ this->InstallPrefix += this->GetOption("CPACK_BUNDLE_NAME");
+ this->InstallPrefix += ".app/Contents/Resources";
+
+ return this->InstallPrefix.c_str();
+}
+
+//----------------------------------------------------------------------
+int cmCPackBundleGenerator::PackageFiles()
+{
+
+ // Get required arguments ...
+ const std::string cpack_bundle_name = this->GetOption("CPACK_BUNDLE_NAME")
+ ? this->GetOption("CPACK_BUNDLE_NAME") : "";
+ if(cpack_bundle_name.empty())
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "CPACK_BUNDLE_NAME must be set."
+ << std::endl);
+
+ return 0;
+ }
+
+ const std::string cpack_bundle_plist = this->GetOption("CPACK_BUNDLE_PLIST")
+ ? this->GetOption("CPACK_BUNDLE_PLIST") : "";
+ if(cpack_bundle_plist.empty())
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "CPACK_BUNDLE_PLIST must be set."
+ << std::endl);
+
+ return 0;
+ }
+
+ const std::string cpack_bundle_icon = this->GetOption("CPACK_BUNDLE_ICON")
+ ? this->GetOption("CPACK_BUNDLE_ICON") : "";
+ if(cpack_bundle_icon.empty())
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "CPACK_BUNDLE_ICON must be set."
+ << std::endl);
+
+ return 0;
+ }
+
+ // Get optional arguments ...
+ const std::string cpack_bundle_startup_command =
+ this->GetOption("CPACK_BUNDLE_STARTUP_COMMAND")
+ ? this->GetOption("CPACK_BUNDLE_STARTUP_COMMAND") : "";
+
+ // The staging directory contains everything that will end-up inside the
+ // final disk image ...
+ cmOStringStream staging;
+ staging << toplevel;
+
+ cmOStringStream contents;
+ contents << staging.str() << "/" << cpack_bundle_name
+ << ".app/" << "Contents";
+
+ cmOStringStream application;
+ application << contents.str() << "/" << "MacOS";
+
+ cmOStringStream resources;
+ resources << contents.str() << "/" << "Resources";
+
+ // Install a required, user-provided bundle metadata file ...
+ cmOStringStream plist_source;
+ plist_source << cpack_bundle_plist;
+
+ cmOStringStream plist_target;
+ plist_target << contents.str() << "/" << "Info.plist";
+
+ if(!this->CopyFile(plist_source, plist_target))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error copying plist. Check the value of CPACK_BUNDLE_PLIST."
+ << std::endl);
+
+ return 0;
+ }
+
+ // Install a user-provided bundle icon ...
+ cmOStringStream icon_source;
+ icon_source << cpack_bundle_icon;
+
+ cmOStringStream icon_target;
+ icon_target << resources.str() << "/" << cpack_bundle_name << ".icns";
+
+ if(!this->CopyFile(icon_source, icon_target))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error copying bundle icon. Check the value of CPACK_BUNDLE_ICON."
+ << std::endl);
+
+ return 0;
+ }
+
+ // Optionally a user-provided startup command (could be an
+ // executable or a script) ...
+ if(!cpack_bundle_startup_command.empty())
+ {
+ cmOStringStream command_source;
+ command_source << cpack_bundle_startup_command;
+
+ cmOStringStream command_target;
+ command_target << application.str() << "/" << cpack_bundle_name;
+
+ if(!this->CopyFile(command_source, command_target))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error copying startup command. "
+ " Check the value of CPACK_BUNDLE_STARTUP_COMMAND."
+ << std::endl);
+
+ return 0;
+ }
+
+ cmSystemTools::SetPermissions(command_target.str().c_str(), 0777);
+ }
+
+ return this->CreateDMG(toplevel, packageFileNames[0]);
+}
+
+bool cmCPackBundleGenerator::SupportsComponentInstallation() const
+{
+ return false;
+}
diff --git a/Source/CPack/cmCPackBundleGenerator.h b/Source/CPack/cmCPackBundleGenerator.h
new file mode 100644
index 000000000..ed0187dd4
--- /dev/null
+++ b/Source/CPack/cmCPackBundleGenerator.h
@@ -0,0 +1,40 @@
+/*============================================================================
+ 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 cmCPackBundleGenerator_h
+#define cmCPackBundleGenerator_h
+
+#include "cmCPackDragNDropGenerator.h"
+
+/** \class cmCPackBundleGenerator
+ * \brief A generator for OSX bundles
+ *
+ * Based on Gimp.app
+ */
+class cmCPackBundleGenerator : public cmCPackDragNDropGenerator
+{
+public:
+ cmCPackTypeMacro(cmCPackBundleGenerator, cmCPackDragNDropGenerator);
+
+ cmCPackBundleGenerator();
+ virtual ~cmCPackBundleGenerator();
+
+protected:
+ virtual int InitializeInternal();
+ virtual const char* GetPackagingInstallPrefix();
+ int PackageFiles();
+ bool SupportsComponentInstallation() const;
+
+ std::string InstallPrefix;
+};
+
+#endif
diff --git a/Source/CPack/cmCPackComponentGroup.cxx b/Source/CPack/cmCPackComponentGroup.cxx
new file mode 100644
index 000000000..1d21fb11c
--- /dev/null
+++ b/Source/CPack/cmCPackComponentGroup.cxx
@@ -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.
+============================================================================*/
+
+#include "cmCPackComponentGroup.h"
+#include "cmSystemTools.h"
+#include <vector>
+#include <string>
+
+//----------------------------------------------------------------------
+unsigned long cmCPackComponent::GetInstalledSize(const char* installDir) const
+{
+ if (this->TotalSize != 0)
+ {
+ return this->TotalSize;
+ }
+
+ std::vector<std::string>::const_iterator fileIt;
+ for (fileIt = this->Files.begin(); fileIt != this->Files.end(); ++fileIt)
+ {
+ std::string path = installDir;
+ path += '/';
+ path += *fileIt;
+ this->TotalSize += cmSystemTools::FileLength(path.c_str());
+ }
+
+ return this->TotalSize;
+}
+
+//----------------------------------------------------------------------
+unsigned long
+cmCPackComponent::GetInstalledSizeInKbytes(const char* 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
new file mode 100644
index 000000000..cebdd6d20
--- /dev/null
+++ b/Source/CPack/cmCPackComponentGroup.h
@@ -0,0 +1,138 @@
+/*============================================================================
+ 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 cmCPackComponentGroup_h
+#define cmCPackComponentGroup_h
+
+#include "cmStandardIncludes.h"
+
+class cmCPackComponentGroup;
+
+/** \class cmCPackInstallationType
+ * \brief A certain type of installation, which encompasses a
+ * set of components.
+ */
+class cmCPackInstallationType
+{
+public:
+ /// The name of the installation type (used to reference this
+ /// installation type).
+ std::string Name;
+
+ /// The name of the installation type as displayed to the user.
+ std::string DisplayName;
+
+ /// The index number of the installation type. This is an arbitrary
+ /// numbering from 1 to the number of installation types.
+ unsigned Index;
+};
+
+/** \class cmCPackComponent
+ * \brief A single component to be installed by CPack.
+ */
+class cmCPackComponent
+{
+public:
+ cmCPackComponent() : Group(0), TotalSize(0) { }
+
+ /// The name of the component (used to reference the component).
+ std::string Name;
+
+ /// The name of the component as displayed to the user.
+ std::string DisplayName;
+
+ /// The component group that contains this component (if any).
+ cmCPackComponentGroup *Group;
+
+ /// Whether this component group must always be installed.
+ bool IsRequired : 1;
+
+ /// Whether this component group is hidden. A hidden component group
+ /// is always installed. However, it may still be shown to the user.
+ bool IsHidden : 1;
+
+ /// Whether this component defaults to "disabled".
+ bool IsDisabledByDefault : 1;
+
+ /// Whether this component should be downloaded on-the-fly. If false,
+ /// the component will be a part of the installation package.
+ bool IsDownloaded : 1;
+
+ /// A description of this component.
+ std::string Description;
+
+ /// The installation types that this component is a part of.
+ std::vector<cmCPackInstallationType *> InstallationTypes;
+
+ /// If IsDownloaded is true, the name of the archive file that
+ /// contains the files that are part of this component.
+ std::string ArchiveFile;
+
+ /// The components that this component depends on.
+ std::vector<cmCPackComponent *> Dependencies;
+
+ /// The components that depend on this component.
+ std::vector<cmCPackComponent *> ReverseDependencies;
+
+ /// The list of installed files that are part of this component.
+ std::vector<std::string> Files;
+
+ /// The list of installed directories that are part of this component.
+ std::vector<std::string> Directories;
+
+ /// 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;
+
+ /// Identical to GetInstalledSize, but returns the result in
+ /// kilobytes.
+ unsigned long GetInstalledSizeInKbytes(const char* installDir) const;
+
+ private:
+ mutable unsigned long TotalSize;
+};
+
+/** \class cmCPackComponentGroup
+ * \brief A component group to be installed by CPack.
+ */
+class cmCPackComponentGroup
+{
+public:
+ cmCPackComponentGroup() : ParentGroup(0) { }
+
+ /// The name of the group (used to reference the group).
+ std::string Name;
+
+ /// The name of the component as displayed to the user.
+ std::string DisplayName;
+
+ /// The description of this component group.
+ std::string Description;
+
+ /// Whether the name of the component will be shown in bold.
+ bool IsBold : 1;
+
+ /// Whether the section should be expanded by default
+ bool IsExpandedByDefault : 1;
+
+ /// The components within this group.
+ std::vector<cmCPackComponent*> Components;
+
+ /// The parent group of this component group (if any).
+ cmCPackComponentGroup *ParentGroup;
+
+ /// The subgroups of this group.
+ std::vector<cmCPackComponentGroup*> Subgroups;
+};
+
+#endif
diff --git a/Source/CPack/cmCPackConfigure.h.in b/Source/CPack/cmCPackConfigure.h.in
new file mode 100644
index 000000000..3d7702e1a
--- /dev/null
+++ b/Source/CPack/cmCPackConfigure.h.in
@@ -0,0 +1,11 @@
+/*============================================================================
+ 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.
+============================================================================*/
diff --git a/Source/CPack/cmCPackCygwinBinaryGenerator.cxx b/Source/CPack/cmCPackCygwinBinaryGenerator.cxx
new file mode 100644
index 000000000..6c8fc54e0
--- /dev/null
+++ b/Source/CPack/cmCPackCygwinBinaryGenerator.cxx
@@ -0,0 +1,92 @@
+/*============================================================================
+ 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 "cmCPackCygwinBinaryGenerator.h"
+
+#include "cmake.h"
+#include "cmGlobalGenerator.h"
+#include "cmLocalGenerator.h"
+#include "cmSystemTools.h"
+#include "cmMakefile.h"
+#include "cmGeneratedFileStream.h"
+#include "cmCPackLog.h"
+
+#include <cmsys/SystemTools.hxx>
+
+//----------------------------------------------------------------------
+cmCPackCygwinBinaryGenerator::cmCPackCygwinBinaryGenerator()
+{
+}
+
+//----------------------------------------------------------------------
+cmCPackCygwinBinaryGenerator::~cmCPackCygwinBinaryGenerator()
+{
+}
+
+//----------------------------------------------------------------------
+int cmCPackCygwinBinaryGenerator::InitializeInternal()
+{
+ this->SetOptionIfNotSet("CPACK_PACKAGING_INSTALL_PREFIX", "/usr");
+ this->SetOptionIfNotSet("CPACK_INCLUDE_TOPLEVEL_DIRECTORY", "0");
+ return this->Superclass::InitializeInternal();
+}
+
+//----------------------------------------------------------------------
+int cmCPackCygwinBinaryGenerator::PackageFiles()
+{
+ std::string packageName = this->GetOption("CPACK_PACKAGE_NAME");
+ packageName += "-";
+ packageName += this->GetOption("CPACK_PACKAGE_VERSION");
+ packageName = cmsys::SystemTools::LowerCase(packageName);
+ std::string manifest = "/usr/share/doc/";
+ manifest += packageName;
+ manifest += "/MANIFEST";
+ std::string manifestFile
+ = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
+ // Create a MANIFEST file that contains all of the files in
+ // the tar file
+ std::string tempdir = manifestFile;
+ manifestFile += manifest;
+ // create an extra scope to force the stream
+ // to create the file before the super class is called
+ {
+ cmGeneratedFileStream ofs(manifestFile.c_str());
+ for(std::vector<std::string>::const_iterator i = files.begin();
+ i != files.end(); ++i)
+ {
+ // remove the temp dir and replace with /usr
+ ofs << (*i).substr(tempdir.size()) << "\n";
+ }
+ ofs << manifest << "\n";
+ }
+ // add the manifest file to the list of all files
+ files.push_back(manifestFile);
+
+ // create the bzip2 tar file
+ return this->Superclass::PackageFiles();
+}
+
+const char* cmCPackCygwinBinaryGenerator::GetOutputExtension()
+{
+ this->OutputExtension = "-";
+ const char* patchNumber =this->GetOption("CPACK_CYGWIN_PATCH_NUMBER");
+ if(!patchNumber)
+ {
+ patchNumber = "1";
+ cmCPackLogger(cmCPackLog::LOG_WARNING,
+ "CPACK_CYGWIN_PATCH_NUMBER not specified using 1"
+ << std::endl);
+ }
+ this->OutputExtension += patchNumber;
+ this->OutputExtension += ".tar.bz2";
+ return this->OutputExtension.c_str();
+}
diff --git a/Source/CPack/cmCPackCygwinBinaryGenerator.h b/Source/CPack/cmCPackCygwinBinaryGenerator.h
new file mode 100644
index 000000000..38f6df17d
--- /dev/null
+++ b/Source/CPack/cmCPackCygwinBinaryGenerator.h
@@ -0,0 +1,38 @@
+/*============================================================================
+ 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 cmCPackCygwinBinaryGenerator_h
+#define cmCPackCygwinBinaryGenerator_h
+
+#include "cmCPackTarBZip2Generator.h"
+
+/** \class cmCPackCygwinBinaryGenerator
+ * \brief A generator for TarBZip2 files
+ */
+class cmCPackCygwinBinaryGenerator : public cmCPackTarBZip2Generator
+{
+public:
+ cmCPackTypeMacro(cmCPackCygwinBinaryGenerator, cmCPackTarBZip2Generator);
+
+ /**
+ * Construct generator
+ */
+ cmCPackCygwinBinaryGenerator();
+ virtual ~cmCPackCygwinBinaryGenerator();
+protected:
+ virtual int InitializeInternal();
+ int PackageFiles();
+ virtual const char* GetOutputExtension();
+ std::string OutputExtension;
+};
+
+#endif
diff --git a/Source/CPack/cmCPackCygwinSourceGenerator.cxx b/Source/CPack/cmCPackCygwinSourceGenerator.cxx
new file mode 100644
index 000000000..597972992
--- /dev/null
+++ b/Source/CPack/cmCPackCygwinSourceGenerator.cxx
@@ -0,0 +1,182 @@
+/*============================================================================
+ 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 "cmCPackCygwinSourceGenerator.h"
+
+#include "cmake.h"
+#include "cmGlobalGenerator.h"
+#include "cmLocalGenerator.h"
+#include "cmSystemTools.h"
+#include "cmMakefile.h"
+#include "cmGeneratedFileStream.h"
+#include "cmCPackLog.h"
+
+#include <cmsys/SystemTools.hxx>
+
+// Includes needed for implementation of RenameFile. This is not in
+// system tools because it is not implemented robustly enough to move
+// files across directories.
+#ifdef _WIN32
+# include <windows.h>
+# include <sys/stat.h>
+#endif
+
+//----------------------------------------------------------------------
+cmCPackCygwinSourceGenerator::cmCPackCygwinSourceGenerator()
+{
+}
+
+//----------------------------------------------------------------------
+cmCPackCygwinSourceGenerator::~cmCPackCygwinSourceGenerator()
+{
+}
+
+//----------------------------------------------------------------------
+int cmCPackCygwinSourceGenerator::InitializeInternal()
+{
+ this->SetOptionIfNotSet("CPACK_INCLUDE_TOPLEVEL_DIRECTORY", "0");
+ return this->Superclass::InitializeInternal();
+}
+
+//----------------------------------------------------------------------
+int cmCPackCygwinSourceGenerator::PackageFiles()
+{
+ // Create a tar file of the sources
+ std::string packageDirFileName
+ = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
+ packageDirFileName += ".tar.bz2";
+ packageFileNames[0] = packageDirFileName;
+ std::string output;
+ // skip one parent up to the cmCPackTarBZip2Generator
+ // to create tar.bz2 file with the list of source
+ // files
+ this->Compress = cmArchiveWrite::CompressBZip2;
+ if ( !this->cmCPackTarBZip2Generator::PackageFiles() )
+ {
+ return 0;
+ }
+ // Now create a tar file that contains the above .tar.bz2 file
+ // and the CPACK_CYGWIN_PATCH_FILE and CPACK_TOPLEVEL_DIRECTORY
+ // files
+ std::string compressOutFile = packageDirFileName;
+ // at this point compressOutFile is the full path to
+ // _CPack_Package/.../package-2.5.0.tar.bz2
+ // we want to create a tar _CPack_Package/.../package-2.5.0-1-src.tar.bz2
+ // with these
+ // _CPack_Package/.../package-2.5.0-1.patch
+ // _CPack_Package/.../package-2.5.0-1.sh
+ // _CPack_Package/.../package-2.5.0.tar.bz2
+ // the -1 is CPACK_CYGWIN_PATCH_NUMBER
+
+ // first copy the patch file and the .sh file
+ // to the toplevel cpack temp dir
+
+ // copy the patch file into place
+ if(!this->GetOption("CPACK_CYGWIN_PATCH_FILE"))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "No patch file specified for cygwin sources.");
+ return 0;
+ }
+ if(!cmSystemTools::CopyFileAlways(
+ this->GetOption("CPACK_CYGWIN_PATCH_FILE"),
+ this->GetOption("CPACK_TOPLEVEL_DIRECTORY")))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "problem copying: ["
+ << this->GetOption("CPACK_CYGWIN_PATCH_FILE") << "]\nto\n["
+ << this->GetOption("CPACK_TOPLEVEL_DIRECTORY") << "]\n");
+ return 0;
+ }
+ if(!this->GetOption("CPACK_CYGWIN_BUILD_SCRIPT"))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "No build script specified for cygwin sources.");
+ return 0;
+ }
+ // copy the build script into place
+ if(!cmSystemTools::CopyFileAlways(
+ this->GetOption("CPACK_CYGWIN_BUILD_SCRIPT"),
+ this->GetOption("CPACK_TOPLEVEL_DIRECTORY")))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "problem copying: "
+ << this->GetOption("CPACK_CYGWIN_BUILD_SCRIPT") << "\nto\n"
+ << this->GetOption("CPACK_TOPLEVEL_DIRECTORY") << "]\n");
+ return 0;
+ }
+ std::string outerTarFile
+ = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
+ outerTarFile += "-";
+ const char* patch = this->GetOption("CPACK_CYGWIN_PATCH_NUMBER");
+ if(!patch)
+ {
+ cmCPackLogger(cmCPackLog::LOG_WARNING, "CPACK_CYGWIN_PATCH_NUMBER"
+ << " not specified, defaulting to 1\n");
+ patch = "1";
+ }
+ outerTarFile += patch;
+ outerTarFile += "-src.tar.bz2";
+ std::string tmpDir = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
+ std::string buildScript = tmpDir;
+ buildScript += "/";
+ buildScript += cmSystemTools::GetFilenameName(
+ this->GetOption("CPACK_CYGWIN_BUILD_SCRIPT"));
+ std::string patchFile = tmpDir;
+ patchFile += "/";
+ patchFile += cmSystemTools::GetFilenameName(
+ this->GetOption("CPACK_CYGWIN_PATCH_FILE"));
+
+ std::string file = cmSystemTools::GetFilenameName(compressOutFile);
+ std::string sourceTar = cmSystemTools::GetFilenamePath(compressOutFile);
+ sourceTar += "/";
+ sourceTar += file;
+ /* reset list of file to be packaged */
+ files.clear();
+ // a source release in cygwin should have the build script used
+ // to build the package, the patch file that is different from the
+ // regular upstream version of the sources, and a bziped tar file
+ // of the original sources
+ files.push_back(buildScript);
+ files.push_back(patchFile);
+ files.push_back(sourceTar);
+ /* update the name of the produced package */
+ packageFileNames[0] = outerTarFile;
+ /* update the toplevel dir */
+ toplevel = tmpDir;
+ if ( !this->cmCPackTarBZip2Generator::PackageFiles() )
+ {
+ return 0;
+ }
+ return 1;
+}
+
+const char* cmCPackCygwinSourceGenerator::GetPackagingInstallPrefix()
+{
+ this->InstallPrefix = "/";
+ this->InstallPrefix += this->GetOption("CPACK_PACKAGE_FILE_NAME");
+ return this->InstallPrefix.c_str();
+}
+
+const char* cmCPackCygwinSourceGenerator::GetOutputExtension()
+{
+ this->OutputExtension = "-";
+ const char* patch = this->GetOption("CPACK_CYGWIN_PATCH_NUMBER");
+ if(!patch)
+ {
+ cmCPackLogger(cmCPackLog::LOG_WARNING, "CPACK_CYGWIN_PATCH_NUMBER"
+ << " not specified, defaulting to 1\n");
+ patch = "1";
+ }
+ this->OutputExtension += patch;
+ this->OutputExtension += "-src.tar.bz2";
+ return this->OutputExtension.c_str();
+}
+
diff --git a/Source/CPack/cmCPackCygwinSourceGenerator.h b/Source/CPack/cmCPackCygwinSourceGenerator.h
new file mode 100644
index 000000000..9d98a9b95
--- /dev/null
+++ b/Source/CPack/cmCPackCygwinSourceGenerator.h
@@ -0,0 +1,40 @@
+/*============================================================================
+ 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 cmCPackCygwinSourceGenerator_h
+#define cmCPackCygwinSourceGenerator_h
+
+#include "cmCPackTarBZip2Generator.h"
+
+/** \class cmCPackCygwinSourceGenerator
+ * \brief A generator for cygwin source files
+ */
+class cmCPackCygwinSourceGenerator : public cmCPackTarBZip2Generator
+{
+public:
+ cmCPackTypeMacro(cmCPackCygwinSourceGenerator, cmCPackTarBZip2Generator);
+
+ /**
+ * Construct generator
+ */
+ cmCPackCygwinSourceGenerator();
+ virtual ~cmCPackCygwinSourceGenerator();
+protected:
+ const char* GetPackagingInstallPrefix();
+ virtual int InitializeInternal();
+ int PackageFiles();
+ virtual const char* GetOutputExtension();
+ std::string InstallPrefix;
+ std::string OutputExtension;
+};
+
+#endif
diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx
new file mode 100644
index 000000000..fa456deff
--- /dev/null
+++ b/Source/CPack/cmCPackDebGenerator.cxx
@@ -0,0 +1,833 @@
+/*============================================================================
+ 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 "cmCPackDebGenerator.h"
+
+#include "cmSystemTools.h"
+#include "cmMakefile.h"
+#include "cmGeneratedFileStream.h"
+#include "cmCPackLog.h"
+
+#include <cmsys/SystemTools.hxx>
+#include <cmsys/Glob.hxx>
+
+#include <limits.h> // USHRT_MAX
+
+// NOTE:
+// A debian package .deb is simply an 'ar' archive. The only subtle difference
+// is that debian uses the BSD ar style archive whereas most Linux distro have
+// a GNU ar.
+// See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=161593 for more info
+// Therefore we provide our own implementation of a BSD-ar:
+static int ar_append(const char*archive,const std::vector<std::string>& files);
+
+//----------------------------------------------------------------------
+cmCPackDebGenerator::cmCPackDebGenerator()
+{
+}
+
+//----------------------------------------------------------------------
+cmCPackDebGenerator::~cmCPackDebGenerator()
+{
+}
+
+//----------------------------------------------------------------------
+int cmCPackDebGenerator::InitializeInternal()
+{
+ this->SetOptionIfNotSet("CPACK_PACKAGING_INSTALL_PREFIX", "/usr");
+ if (cmSystemTools::IsOff(this->GetOption("CPACK_SET_DESTDIR")))
+ {
+ this->SetOption("CPACK_SET_DESTDIR", "I_ON");
+ }
+ return this->Superclass::InitializeInternal();
+}
+
+//----------------------------------------------------------------------
+int cmCPackDebGenerator::PackageOnePack(std::string initialTopLevel,
+ std::string packageName)
+ {
+ int retval = 1;
+ // Begin the archive for this pack
+ std::string localToplevel(initialTopLevel);
+ std::string packageFileName(
+ cmSystemTools::GetParentDirectory(toplevel.c_str())
+ );
+ std::string outputFileName(
+ std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME"))
+ +"-"+packageName + this->GetOutputExtension()
+ );
+
+ localToplevel += "/"+ packageName;
+ /* replace the TEMP DIRECTORY with the component one */
+ this->SetOption("CPACK_TEMPORARY_DIRECTORY",localToplevel.c_str());
+ packageFileName += "/"+ outputFileName;
+ /* replace proposed CPACK_OUTPUT_FILE_NAME */
+ this->SetOption("CPACK_OUTPUT_FILE_NAME",outputFileName.c_str());
+ /* replace the TEMPORARY package file name */
+ this->SetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME",
+ packageFileName.c_str());
+ // Tell CPackDeb.cmake the name of the component GROUP.
+ this->SetOption("CPACK_DEB_PACKAGE_COMPONENT",packageName.c_str());
+ if (!this->ReadListFile("CPackDeb.cmake"))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error while execution CPackDeb.cmake" << std::endl);
+ retval = 0;
+ return retval;
+ }
+
+ cmsys::Glob gl;
+ std::string findExpr(this->GetOption("WDIR"));
+ findExpr += "/*";
+ gl.RecurseOn();
+ if ( !gl.FindFiles(findExpr) )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Cannot find any files in the installed directory" << std::endl);
+ return 0;
+ }
+ packageFiles = gl.GetFiles();
+
+ int res = createDeb();
+ if (res != 1)
+ {
+ retval = 0;
+ }
+ // add the generated package to package file names list
+ packageFileNames.push_back(packageFileName);
+ return retval;
+}
+
+//----------------------------------------------------------------------
+int cmCPackDebGenerator::PackageComponents(bool ignoreGroup)
+{
+ int retval = 1;
+ /* Reset package file name list it will be populated during the
+ * component packaging run*/
+ packageFileNames.clear();
+ std::string initialTopLevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY"));
+
+ // The default behavior is to have one package by component group
+ // unless CPACK_COMPONENTS_IGNORE_GROUP is specified.
+ if (!ignoreGroup)
+ {
+ std::map<std::string, cmCPackComponentGroup>::iterator compGIt;
+ for (compGIt=this->ComponentGroups.begin();
+ compGIt!=this->ComponentGroups.end(); ++compGIt)
+ {
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Packaging component group: "
+ << compGIt->first
+ << std::endl);
+ // Begin the archive for this group
+ retval &= PackageOnePack(initialTopLevel,compGIt->first);
+ }
+ // Handle Orphan components (components not belonging to any groups)
+ std::map<std::string, cmCPackComponent>::iterator compIt;
+ for (compIt=this->Components.begin();
+ compIt!=this->Components.end(); ++compIt )
+ {
+ // Does the component belong to a group?
+ if (compIt->second.Group==NULL)
+ {
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE,
+ "Component <"
+ << compIt->second.Name
+ << "> does not belong to any group, package it separately."
+ << std::endl);
+ // Begin the archive for this orphan component
+ retval &= PackageOnePack(initialTopLevel,compIt->first);
+ }
+ }
+ }
+ // CPACK_COMPONENTS_IGNORE_GROUPS is set
+ // We build 1 package per component
+ else
+ {
+ std::map<std::string, cmCPackComponent>::iterator compIt;
+ for (compIt=this->Components.begin();
+ compIt!=this->Components.end(); ++compIt )
+ {
+ retval &= PackageOnePack(initialTopLevel,compIt->first);
+ }
+ }
+ return retval;
+}
+
+//----------------------------------------------------------------------
+int cmCPackDebGenerator::PackageComponentsAllInOne()
+{
+ int retval = 1;
+ std::string compInstDirName;
+ /* Reset package file name list it will be populated during the
+ * component packaging run*/
+ packageFileNames.clear();
+ std::string initialTopLevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY"));
+
+ compInstDirName = "ALL_COMPONENTS_IN_ONE";
+
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE,
+ "Packaging all groups in one package..."
+ "(CPACK_COMPONENTS_ALL_[GROUPS_]IN_ONE_PACKAGE is set)"
+ << std::endl);
+
+ // The ALL GROUPS in ONE package case
+ std::string localToplevel(initialTopLevel);
+ std::string packageFileName(
+ cmSystemTools::GetParentDirectory(toplevel.c_str())
+ );
+ std::string outputFileName(
+ std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME"))
+ + this->GetOutputExtension()
+ );
+ // all GROUP in one vs all COMPONENT in one
+ localToplevel += "/"+compInstDirName;
+
+ /* replace the TEMP DIRECTORY with the component one */
+ this->SetOption("CPACK_TEMPORARY_DIRECTORY",localToplevel.c_str());
+ packageFileName += "/"+ outputFileName;
+ /* replace proposed CPACK_OUTPUT_FILE_NAME */
+ this->SetOption("CPACK_OUTPUT_FILE_NAME",outputFileName.c_str());
+ /* replace the TEMPORARY package file name */
+ this->SetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME",
+ packageFileName.c_str());
+ // Tell CPackDeb.cmake the name of the component GROUP.
+ this->SetOption("CPACK_DEB_PACKAGE_COMPONENT",compInstDirName.c_str());
+ if (!this->ReadListFile("CPackDeb.cmake"))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error while execution CPackDeb.cmake" << std::endl);
+ retval = 0;
+ return retval;
+ }
+
+ cmsys::Glob gl;
+ std::string findExpr(this->GetOption("WDIR"));
+ findExpr += "/*";
+ gl.RecurseOn();
+ if ( !gl.FindFiles(findExpr) )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Cannot find any files in the installed directory" << std::endl);
+ return 0;
+ }
+ packageFiles = gl.GetFiles();
+
+ int res = createDeb();
+ if (res != 1)
+ {
+ retval = 0;
+ }
+ // add the generated package to package file names list
+ packageFileNames.push_back(packageFileName);
+ return retval;
+}
+
+//----------------------------------------------------------------------
+int cmCPackDebGenerator::PackageFiles()
+{
+ int retval = -1;
+
+ /* Are we in the component packaging case */
+ if (WantsComponentInstallation()) {
+ // CASE 1 : COMPONENT ALL-IN-ONE package
+ // If ALL GROUPS or ALL COMPONENTS in ONE package has been requested
+ // then the package file is unique and should be open here.
+ if (componentPackageMethod == ONE_PACKAGE)
+ {
+ return PackageComponentsAllInOne();
+ }
+ // CASE 2 : COMPONENT CLASSICAL package(s) (i.e. not all-in-one)
+ // There will be 1 package for each component group
+ // however one may require to ignore component group and
+ // in this case you'll get 1 package for each component.
+ else
+ {
+ return PackageComponents(componentPackageMethod ==
+ ONE_PACKAGE_PER_COMPONENT);
+ }
+ }
+ // CASE 3 : NON COMPONENT package.
+ else
+ {
+ if (!this->ReadListFile("CPackDeb.cmake"))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error while execution CPackDeb.cmake" << std::endl);
+ retval = 0;
+ }
+ else
+ {
+ packageFiles = files;
+ return createDeb();
+ }
+ }
+ return retval;
+}
+
+int cmCPackDebGenerator::createDeb()
+{
+ const char* cmakeExecutable = this->GetOption("CMAKE_COMMAND");
+
+ // debian-binary file
+ std::string dbfilename;
+ dbfilename += this->GetOption("WDIR");
+ dbfilename += "/debian-binary";
+ { // the scope is needed for cmGeneratedFileStream
+ cmGeneratedFileStream out(dbfilename.c_str());
+ out << "2.0";
+ out << std::endl; // required for valid debian package
+ }
+
+ // control file
+ std::string ctlfilename;
+ ctlfilename = this->GetOption("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") );
+ const char* debian_pkg_version =
+ this->GetOption("CPACK_DEBIAN_PACKAGE_VERSION");
+ const char* debian_pkg_section =
+ this->GetOption("CPACK_DEBIAN_PACKAGE_SECTION");
+ const char* debian_pkg_priority =
+ this->GetOption("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");
+
+ // optional entries
+ const char* debian_pkg_dep = this->GetOption("CPACK_DEBIAN_PACKAGE_DEPENDS");
+ const char* debian_pkg_rec =
+ this->GetOption("CPACK_DEBIAN_PACKAGE_RECOMMENDS");
+ const char* debian_pkg_sug =
+ this->GetOption("CPACK_DEBIAN_PACKAGE_SUGGESTS");
+ const char* debian_pkg_url =
+ this->GetOption("CPACK_DEBIAN_PACKAGE_HOMEPAGE");
+ const char* debian_pkg_predep =
+ this->GetOption("CPACK_DEBIAN_PACKAGE_PREDEPENDS");
+ const char* debian_pkg_enhances =
+ this->GetOption("CPACK_DEBIAN_PACKAGE_ENHANCES");
+ const char* debian_pkg_breaks =
+ this->GetOption("CPACK_DEBIAN_PACKAGE_BREAKS");
+ const char* debian_pkg_conflicts =
+ this->GetOption("CPACK_DEBIAN_PACKAGE_CONFLICTS");
+ const char* debian_pkg_provides =
+ this->GetOption("CPACK_DEBIAN_PACKAGE_PROVIDES");
+ const char* debian_pkg_replaces =
+ this->GetOption("CPACK_DEBIAN_PACKAGE_REPLACES");
+
+ { // the scope is needed for cmGeneratedFileStream
+ cmGeneratedFileStream out(ctlfilename.c_str());
+ out << "Package: " << debian_pkg_name << "\n";
+ out << "Version: " << debian_pkg_version << "\n";
+ out << "Section: " << debian_pkg_section << "\n";
+ out << "Priority: " << debian_pkg_priority << "\n";
+ out << "Architecture: " << debian_pkg_arch << "\n";
+ if(debian_pkg_dep && *debian_pkg_dep)
+ {
+ out << "Depends: " << debian_pkg_dep << "\n";
+ }
+ if(debian_pkg_rec && *debian_pkg_rec)
+ {
+ out << "Recommends: " << debian_pkg_rec << "\n";
+ }
+ if(debian_pkg_sug && *debian_pkg_sug)
+ {
+ out << "Suggests: " << debian_pkg_sug << "\n";
+ }
+ if(debian_pkg_url && *debian_pkg_url)
+ {
+ out << "Homepage: " << debian_pkg_url << "\n";
+ }
+ if (debian_pkg_predep && *debian_pkg_predep)
+ {
+ out << "Pre-Depends: " << debian_pkg_predep << "\n";
+ }
+ if (debian_pkg_enhances && *debian_pkg_enhances)
+ {
+ out << "Enhances: " << debian_pkg_enhances << "\n";
+ }
+ if (debian_pkg_breaks && *debian_pkg_breaks)
+ {
+ out << "Breaks: " << debian_pkg_breaks << "\n";
+ }
+ if (debian_pkg_conflicts && *debian_pkg_conflicts)
+ {
+ out << "Conflicts: " << debian_pkg_conflicts << "\n";
+ }
+ if (debian_pkg_provides && *debian_pkg_provides)
+ {
+ out << "Provides: " << debian_pkg_provides << "\n";
+ }
+ if (debian_pkg_replaces && *debian_pkg_replaces)
+ {
+ out << "Replaces: " << debian_pkg_replaces << "\n";
+ }
+ unsigned long totalSize = 0;
+ {
+ std::string dirName = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
+ dirName += '/';
+ for (std::vector<std::string>::const_iterator fileIt =
+ packageFiles.begin();
+ fileIt != packageFiles.end(); ++ fileIt )
+ {
+ totalSize += cmSystemTools::FileLength(fileIt->c_str());
+ }
+ }
+ out << "Installed-Size: " << (totalSize + 1023) / 1024 << "\n";
+ out << "Maintainer: " << maintainer << "\n";
+ out << "Description: " << desc << "\n";
+ out << std::endl;
+ }
+
+ std::string cmd;
+ if (NULL != this->GetOption("CPACK_DEBIAN_FAKEROOT_EXECUTABLE")) {
+ cmd += this->GetOption("CPACK_DEBIAN_FAKEROOT_EXECUTABLE");
+ }
+ 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::endl);
+ std::set<std::string> installDirs;
+ 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())
+ {
+ installDirs.insert(relativeDir);
+ cmd += " .";
+ cmd += relativeDir;
+ }
+ }
+
+ 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;
+ }
+
+ std::string md5filename;
+ md5filename = this->GetOption("WDIR");
+ md5filename += "/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 )
+ {
+ 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);
+ // debian md5sums entries are like this:
+ // 014f3604694729f3bf19263bac599765 usr/bin/ccmake
+ // thus strip the full path (with the trailing slash)
+ cmSystemTools::ReplaceString(output,
+ topLevelWithTrailingSlash.c_str(), "");
+ out << output;
+ }
+ // each line contains a eol.
+ // Do not end the md5sum file with yet another (invalid)
+ }
+
+ cmd = "";
+ if (NULL != this->GetOption("CPACK_DEBIAN_FAKEROOT_EXECUTABLE"))
+ {
+ cmd = this->GetOption("CPACK_DEBIAN_FAKEROOT_EXECUTABLE");
+ }
+ cmd += " \"";
+ cmd += cmakeExecutable;
+ cmd += "\" -E tar cfz control.tar.gz ./control ./md5sums";
+ 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)
+ {
+ 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()) )
+ {
+ // debian is picky and need relative to ./ path in the tar.gz
+ cmd += " ./";
+ cmd += filenamename;
+ }
+ }
+ }
+ 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
+ // 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 += "/";
+ 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);
+ if ( res!=0 )
+ {
+ std::string tmpFile = this->GetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME");
+ tmpFile += "/Deb.log";
+ cmGeneratedFileStream ofs(tmpFile.c_str());
+ ofs << "# Problem creating archive using: " << res << std::endl;
+ return 0;
+ }
+ return 1;
+}
+
+bool cmCPackDebGenerator::SupportsComponentInstallation() const
+ {
+ if (IsOn("CPACK_DEB_COMPONENT_INSTALL"))
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+std::string cmCPackDebGenerator::GetComponentInstallDirNameSuffix(
+ const std::string& componentName)
+ {
+ if (componentPackageMethod == ONE_PACKAGE_PER_COMPONENT) {
+ return componentName;
+ }
+
+ if (componentPackageMethod == ONE_PACKAGE) {
+ return std::string("ALL_COMPONENTS_IN_ONE");
+ }
+ // We have to find the name of the COMPONENT GROUP
+ // the current COMPONENT belongs to.
+ std::string groupVar = "CPACK_COMPONENT_" +
+ cmSystemTools::UpperCase(componentName) + "_GROUP";
+ if (NULL != GetOption(groupVar.c_str()))
+ {
+ return std::string(GetOption(groupVar.c_str()));
+ }
+ else
+ {
+ return componentName;
+ }
+ }
+
+
+// The following code is taken from OpenBSD ar:
+// http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ar/
+// It has been slightly modified:
+// -return error codes instead exit() in functions
+// -use the stdio file I/O functions instead the file descriptor based ones
+// -merged into one cxx file
+// -no additional options supported
+// The coding style hasn't been modified.
+
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Hugh Smith at The University of Guelph.
+ *
+ * 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 University 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 REGENTS 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 REGENTS 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 <sys/types.h>
+#include <sys/stat.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define ARMAG "!<arch>\n" /* ar "magic number" */
+#define SARMAG 8 /* strlen(ARMAG); */
+
+#define AR_EFMT1 "#1/" /* extended format #1 */
+#define ARFMAG "`\n"
+
+/* Header format strings. */
+#define HDR1 "%s%-13d%-12ld%-6u%-6u%-8o%-10lld%2s"
+#define HDR2 "%-16.16s%-12ld%-6u%-6u%-8o%-10lld%2s"
+
+struct ar_hdr {
+ char ar_name[16]; /* name */
+ char ar_date[12]; /* modification time */
+ char ar_uid[6]; /* user id */
+ char ar_gid[6]; /* group id */
+ char ar_mode[8]; /* octal file permissions */
+ char ar_size[10]; /* size in bytes */
+ char ar_fmag[2]; /* consistency check */
+};
+
+/* Set up file copy. */
+#define SETCF(from, fromname, to, toname, pad) { \
+ cf.rFile = from; \
+ cf.rname = fromname; \
+ cf.wFile = to; \
+ cf.wname = toname; \
+ cf.flags = pad; \
+}
+
+/* File copy structure. */
+typedef struct {
+ FILE* rFile; /* read file descriptor */
+ const char *rname; /* read name */
+ FILE* wFile; /* write file descriptor */
+ const char *wname; /* write name */
+#define NOPAD 0x00 /* don't pad */
+#define WPAD 0x02 /* pad on writes */
+ unsigned int flags; /* pad flags */
+} CF;
+
+/* misc.c */
+
+static const char * ar_rname(const char *path)
+{
+ const char *ind = strrchr(path, '/');
+ return (ind ) ? ind + 1 : path;
+}
+
+/* archive.c */
+
+typedef struct ar_hdr HDR;
+static char ar_hb[sizeof(HDR) + 1]; /* real header */
+
+static size_t ar_already_written;
+
+/* copy_ar --
+ * Copy size bytes from one file to another - taking care to handle the
+ * extra byte (for odd size files) when reading archives and writing an
+ * extra byte if necessary when adding files to archive. The length of
+ * the object is the long name plus the object itself; the variable
+ * already_written gets set if a long name was written.
+ *
+ * The padding is really unnecessary, and is almost certainly a remnant
+ * of early archive formats where the header included binary data which
+ * a PDP-11 required to start on an even byte boundary. (Or, perhaps,
+ * because 16-bit word addressed copies were faster?) Anyhow, it should
+ * have been ripped out long ago.
+ */
+static int copy_ar(CF *cfp, off_t size)
+{
+ static char pad = '\n';
+ off_t sz = size;
+ size_t nr, nw;
+ char buf[8*1024];
+
+ if (sz == 0)
+ return 0;
+
+ FILE* from = cfp->rFile;
+ FILE* to = cfp->wFile;
+ while (sz &&
+ (nr = fread(buf, 1, sz < static_cast<off_t>(sizeof(buf))
+ ? static_cast<size_t>(sz) : sizeof(buf), from ))
+ > 0) {
+ sz -= nr;
+ for (size_t off = 0; off < nr; nr -= off, off += nw)
+ if ((nw = fwrite(buf + off, 1, nr, to)) < nr)
+ return -1;
+ }
+ if (sz)
+ return -2;
+
+ if (cfp->flags & WPAD && (size + ar_already_written) & 1
+ && fwrite(&pad, 1, 1, to) != 1)
+ return -4;
+
+ return 0;
+}
+
+/* put_arobj -- Write an archive member to a file. */
+static int put_arobj(CF *cfp, struct stat *sb)
+{
+ int result = 0;
+ struct ar_hdr *hdr;
+
+ /* If passed an sb structure, reading a file from disk. Get stat(2)
+ * information, build a name and construct a header. (Files are named
+ * by their last component in the archive.) */
+ const char* name = ar_rname(cfp->rname);
+ (void)stat(cfp->rname, sb);
+
+ /* If not truncating names and the name is too long or contains
+ * a space, use extended format 1. */
+ size_t lname = strlen(name);
+ uid_t uid = sb->st_uid;
+ gid_t gid = sb->st_gid;
+ if (uid > USHRT_MAX) {
+ uid = USHRT_MAX;
+ }
+ if (gid > USHRT_MAX) {
+ gid = USHRT_MAX;
+ }
+ if (lname > sizeof(hdr->ar_name) || strchr(name, ' '))
+ (void)sprintf(ar_hb, HDR1, AR_EFMT1, (int)lname,
+ (long int)sb->st_mtime, uid, gid, sb->st_mode,
+ (long long)sb->st_size + lname, ARFMAG);
+ else {
+ lname = 0;
+ (void)sprintf(ar_hb, HDR2, name,
+ (long int)sb->st_mtime, uid, gid, sb->st_mode,
+ (long long)sb->st_size, ARFMAG);
+ }
+ off_t size = sb->st_size;
+
+ if (fwrite(ar_hb, 1, sizeof(HDR), cfp->wFile) != sizeof(HDR))
+ return -1;
+
+ if (lname) {
+ if (fwrite(name, 1, lname, cfp->wFile) != lname)
+ return -2;
+ ar_already_written = lname;
+ }
+ result = copy_ar(cfp, size);
+ ar_already_written = 0;
+ return result;
+}
+
+/* append.c */
+
+/* append --
+ * Append files to the archive - modifies original archive or creates
+ * a new archive if named archive does not exist.
+ */
+static int ar_append(const char* archive,const std::vector<std::string>& files)
+{
+ int eval = 0;
+ FILE* aFile = fopen(archive, "wb+");
+ if (aFile!=NULL) {
+ fwrite(ARMAG, SARMAG, 1, aFile);
+ if (fseek(aFile, 0, SEEK_END) != -1) {
+ CF cf;
+ struct stat sb;
+ /* Read from disk, write to an archive; pad on write. */
+ SETCF(NULL, 0, aFile, archive, WPAD);
+ 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");
+ if (file == NULL) {
+ eval = -1;
+ continue;
+ }
+ cf.rFile = file;
+ cf.rname = filename;
+ int result = put_arobj(&cf, &sb);
+ (void)fclose(file);
+ if (result!=0) {
+ eval = -2;
+ break;
+ }
+ }
+ }
+ else {
+ eval = -3;
+ }
+ fclose(aFile);
+ }
+ else {
+ eval = -4;
+ }
+ return eval;
+}
diff --git a/Source/CPack/cmCPackDebGenerator.h b/Source/CPack/cmCPackDebGenerator.h
new file mode 100644
index 000000000..d678cfacf
--- /dev/null
+++ b/Source/CPack/cmCPackDebGenerator.h
@@ -0,0 +1,77 @@
+/*============================================================================
+ 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 cmCPackDebGenerator_h
+#define cmCPackDebGenerator_h
+
+
+#include "cmCPackGenerator.h"
+
+/** \class cmCPackDebGenerator
+ * \brief A generator for Debian packages
+ *
+ */
+class cmCPackDebGenerator : public cmCPackGenerator
+{
+public:
+ cmCPackTypeMacro(cmCPackDebGenerator, cmCPackGenerator);
+
+ /**
+ * Construct generator
+ */
+ cmCPackDebGenerator();
+ virtual ~cmCPackDebGenerator();
+
+ static bool CanGenerate()
+ {
+#ifdef __APPLE__
+ // on MacOS enable CPackDeb iff dpkg is found
+ std::vector<std::string> locations;
+ locations.push_back("/sw/bin"); // Fink
+ locations.push_back("/opt/local/bin"); // MacPorts
+ return cmSystemTools::FindProgram("dpkg",locations) != "" ? true : false;
+#else
+ // legacy behavior on other systems
+ return true;
+#endif
+ }
+
+protected:
+ virtual int InitializeInternal();
+ /**
+ * This method factors out the work done in component packaging case.
+ */
+ int PackageOnePack(std::string initialToplevel, std::string packageName);
+ /**
+ * The method used to package files when component
+ * install is used. This will create one
+ * archive for each component group.
+ */
+ int PackageComponents(bool ignoreGroup);
+ /**
+ * Special case of component install where all
+ * components will be put in a single installer.
+ */
+ int PackageComponentsAllInOne();
+ virtual int PackageFiles();
+ virtual const char* GetOutputExtension() { return ".deb"; }
+ virtual bool SupportsComponentInstallation() const;
+ virtual std::string GetComponentInstallDirNameSuffix(
+ const std::string& componentName);
+
+private:
+ int createDeb();
+ std::vector<std::string> packageFiles;
+
+};
+
+#endif
diff --git a/Source/CPack/cmCPackDocumentMacros.cxx b/Source/CPack/cmCPackDocumentMacros.cxx
new file mode 100644
index 000000000..ddc75a4b4
--- /dev/null
+++ b/Source/CPack/cmCPackDocumentMacros.cxx
@@ -0,0 +1,16 @@
+#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
new file mode 100644
index 000000000..544f74f5f
--- /dev/null
+++ b/Source/CPack/cmCPackDocumentMacros.h
@@ -0,0 +1,21 @@
+/*============================================================================
+ 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
new file mode 100644
index 000000000..edbef45ef
--- /dev/null
+++ b/Source/CPack/cmCPackDocumentVariables.cxx
@@ -0,0 +1,111 @@
+#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 as 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 byt 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_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. "
+ "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
new file mode 100644
index 000000000..e7971be13
--- /dev/null
+++ b/Source/CPack/cmCPackDocumentVariables.h
@@ -0,0 +1,21 @@
+/*============================================================================
+ 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
new file mode 100644
index 000000000..6aee401ff
--- /dev/null
+++ b/Source/CPack/cmCPackDragNDropGenerator.cxx
@@ -0,0 +1,588 @@
+/*============================================================================
+ 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 "cmCPackDragNDropGenerator.h"
+#include "cmCPackLog.h"
+#include "cmSystemTools.h"
+#include "cmGeneratedFileStream.h"
+
+#include <cmsys/RegularExpression.hxx>
+
+static const char* SLAHeader =
+"data 'LPic' (5000) {\n"
+" $\"0002 0011 0003 0001 0000 0000 0002 0000\"\n"
+" $\"0008 0003 0000 0001 0004 0000 0004 0005\"\n"
+" $\"0000 000E 0006 0001 0005 0007 0000 0007\"\n"
+" $\"0008 0000 0047 0009 0000 0034 000A 0001\"\n"
+" $\"0035 000B 0001 0020 000C 0000 0011 000D\"\n"
+" $\"0000 005B 0004 0000 0033 000F 0001 000C\"\n"
+" $\"0010 0000 000B 000E 0000\"\n"
+"};\n"
+"\n";
+
+static const char* SLASTREnglish =
+"resource 'STR#' (5002, \"English\") {\n"
+" {\n"
+" \"English\",\n"
+" \"Agree\",\n"
+" \"Disagree\",\n"
+" \"Print\",\n"
+" \"Save...\",\n"
+" \"You agree to the License Agreement terms when you click \"\n"
+" \"the \\\"Agree\\\" button.\",\n"
+" \"Software License Agreement\",\n"
+" \"This text cannot be saved. This disk may be full or locked, "
+"or the \"\n"
+" \"file may be locked.\",\n"
+" \"Unable to print. Make sure you have selected a printer.\"\n"
+" }\n"
+"};\n"
+"\n";
+
+//----------------------------------------------------------------------
+cmCPackDragNDropGenerator::cmCPackDragNDropGenerator()
+{
+ // default to one package file for components
+ this->componentPackageMethod = ONE_PACKAGE;
+}
+
+//----------------------------------------------------------------------
+cmCPackDragNDropGenerator::~cmCPackDragNDropGenerator()
+{
+}
+
+//----------------------------------------------------------------------
+int cmCPackDragNDropGenerator::InitializeInternal()
+{
+ // Starting with Xcode 4.3, look in "/Applications/Xcode.app" first:
+ //
+ std::vector<std::string> paths;
+ paths.push_back("/Applications/Xcode.app/Contents/Developer/Tools");
+ paths.push_back("/Developer/Tools");
+
+ const std::string hdiutil_path = cmSystemTools::FindProgram("hdiutil",
+ std::vector<std::string>(), false);
+ if(hdiutil_path.empty())
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Cannot locate hdiutil command"
+ << std::endl);
+ return 0;
+ }
+ this->SetOptionIfNotSet("CPACK_COMMAND_HDIUTIL", hdiutil_path.c_str());
+
+ const std::string setfile_path = cmSystemTools::FindProgram("SetFile",
+ paths, false);
+ if(setfile_path.empty())
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Cannot locate SetFile command"
+ << std::endl);
+ return 0;
+ }
+ this->SetOptionIfNotSet("CPACK_COMMAND_SETFILE", setfile_path.c_str());
+
+ const std::string rez_path = cmSystemTools::FindProgram("Rez",
+ paths, false);
+ if(rez_path.empty())
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Cannot locate Rez command"
+ << std::endl);
+ return 0;
+ }
+ this->SetOptionIfNotSet("CPACK_COMMAND_REZ", rez_path.c_str());
+
+ return this->Superclass::InitializeInternal();
+}
+
+//----------------------------------------------------------------------
+const char* cmCPackDragNDropGenerator::GetOutputExtension()
+{
+ return ".dmg";
+}
+
+//----------------------------------------------------------------------
+int cmCPackDragNDropGenerator::PackageFiles()
+{
+ // gather which directories to make dmg files for
+ // multiple directories occur if packaging components or groups separately
+
+ // monolith
+ if(this->Components.empty())
+ {
+ return this->CreateDMG(toplevel, packageFileNames[0]);
+ }
+
+ // component install
+ std::vector<std::string> package_files;
+
+ std::map<std::string, cmCPackComponent>::iterator compIt;
+ for (compIt=this->Components.begin();
+ compIt!=this->Components.end(); ++compIt )
+ {
+ std::string name = GetComponentInstallDirNameSuffix(compIt->first);
+ package_files.push_back(name);
+ }
+ std::sort(package_files.begin(), package_files.end());
+ package_files.erase(std::unique(package_files.begin(),
+ package_files.end()),
+ package_files.end());
+
+
+ // loop to create dmg files
+ packageFileNames.clear();
+ for(size_t i=0; i<package_files.size(); i++)
+ {
+ std::string full_package_name = std::string(toplevel) + std::string("/");
+ if(package_files[i] == "ALL_IN_ONE")
+ {
+ full_package_name += this->GetOption("CPACK_PACKAGE_FILE_NAME");
+ }
+ else
+ {
+ full_package_name += package_files[i];
+ }
+ full_package_name += std::string(GetOutputExtension());
+ packageFileNames.push_back(full_package_name);
+
+ std::string src_dir = toplevel;
+ src_dir += "/";
+ src_dir += package_files[i];
+
+ if(0 == this->CreateDMG(src_dir, full_package_name))
+ {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+//----------------------------------------------------------------------
+bool cmCPackDragNDropGenerator::CopyFile(cmOStringStream& source,
+ cmOStringStream& target)
+{
+ if(!cmSystemTools::CopyFileIfDifferent(
+ source.str().c_str(),
+ target.str().c_str()))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error copying "
+ << source.str()
+ << " to "
+ << target.str()
+ << std::endl);
+
+ return false;
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------
+bool cmCPackDragNDropGenerator::RunCommand(cmOStringStream& command,
+ std::string* output)
+{
+ int exit_code = 1;
+
+ bool result = cmSystemTools::RunSingleCommand(
+ command.str().c_str(),
+ output,
+ &exit_code,
+ 0,
+ this->GeneratorVerbose,
+ 0);
+
+ if(!result || exit_code)
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error executing: "
+ << command.str()
+ << std::endl);
+
+ return false;
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------
+int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
+ const std::string& output_file)
+{
+ // Get optional arguments ...
+ const std::string cpack_package_icon = this->GetOption("CPACK_PACKAGE_ICON")
+ ? this->GetOption("CPACK_PACKAGE_ICON") : "";
+
+ const std::string cpack_dmg_volume_name =
+ this->GetOption("CPACK_DMG_VOLUME_NAME")
+ ? this->GetOption("CPACK_DMG_VOLUME_NAME")
+ : this->GetOption("CPACK_PACKAGE_FILE_NAME");
+
+ const std::string cpack_dmg_format =
+ this->GetOption("CPACK_DMG_FORMAT")
+ ? this->GetOption("CPACK_DMG_FORMAT") : "UDZO";
+
+ // Get optional arguments ...
+ std::string cpack_license_file =
+ this->GetOption("CPACK_RESOURCE_FILE_LICENSE") ?
+ this->GetOption("CPACK_RESOURCE_FILE_LICENSE") : "";
+
+ const std::string cpack_dmg_background_image =
+ this->GetOption("CPACK_DMG_BACKGROUND_IMAGE")
+ ? this->GetOption("CPACK_DMG_BACKGROUND_IMAGE") : "";
+
+ const std::string cpack_dmg_ds_store =
+ this->GetOption("CPACK_DMG_DS_STORE")
+ ? this->GetOption("CPACK_DMG_DS_STORE") : "";
+
+ // 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 = "";
+ }
+
+ // The staging directory contains everything that will end-up inside the
+ // final disk image ...
+ cmOStringStream staging;
+ staging << src_dir;
+
+ // Add a symlink to /Applications so users can drag-and-drop the bundle
+ // into it
+ cmOStringStream application_link;
+ application_link << staging.str() << "/Applications";
+ cmSystemTools::CreateSymlink("/Applications",
+ application_link.str().c_str());
+
+ // Optionally add a custom volume icon ...
+ if(!cpack_package_icon.empty())
+ {
+ cmOStringStream package_icon_source;
+ package_icon_source << cpack_package_icon;
+
+ cmOStringStream package_icon_destination;
+ package_icon_destination << staging.str() << "/.VolumeIcon.icns";
+
+ if(!this->CopyFile(package_icon_source, package_icon_destination))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error copying disk volume icon. "
+ "Check the value of CPACK_PACKAGE_ICON."
+ << std::endl);
+
+ return 0;
+ }
+ }
+
+ // Optionally add a custom .DS_Store file
+ // (e.g. for setting background/layout) ...
+ if(!cpack_dmg_ds_store.empty())
+ {
+ cmOStringStream package_settings_source;
+ package_settings_source << cpack_dmg_ds_store;
+
+ cmOStringStream package_settings_destination;
+ package_settings_destination << staging.str() << "/.DS_Store";
+
+ if(!this->CopyFile(package_settings_source, package_settings_destination))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error copying disk volume settings file. "
+ "Check the value of CPACK_DMG_DS_STORE."
+ << std::endl);
+
+ return 0;
+ }
+ }
+
+ // Optionally add a custom background image ...
+ if(!cpack_dmg_background_image.empty())
+ {
+ cmOStringStream package_background_source;
+ package_background_source << cpack_dmg_background_image;
+
+ cmOStringStream package_background_destination;
+ package_background_destination << staging.str() << "/background.png";
+
+ if(!this->CopyFile(package_background_source,
+ package_background_destination))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error copying disk volume background image. "
+ "Check the value of CPACK_DMG_BACKGROUND_IMAGE."
+ << std::endl);
+
+ 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 << "\"";
+
+ if(!this->RunCommand(temp_background_hiding_command))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error setting attributes on disk volume background image."
+ << std::endl);
+
+ return 0;
+ }
+ }
+
+ // Create a temporary read-write disk image ...
+ std::string temp_image = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
+ temp_image += "/temp.dmg";
+
+ cmOStringStream temp_image_command;
+ temp_image_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
+ temp_image_command << " create";
+ temp_image_command << " -ov";
+ temp_image_command << " -srcfolder \"" << staging.str() << "\"";
+ temp_image_command << " -volname \""
+ << cpack_dmg_volume_name << "\"";
+ temp_image_command << " -format UDRW";
+ temp_image_command << " \"" << temp_image << "\"";
+
+ if(!this->RunCommand(temp_image_command))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error generating temporary disk image."
+ << std::endl);
+
+ return 0;
+ }
+
+ // Optionally set the custom icon flag for the image ...
+ if(!cpack_package_icon.empty())
+ {
+ cmOStringStream temp_mount;
+
+ cmOStringStream attach_command;
+ attach_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
+ attach_command << " attach";
+ attach_command << " \"" << temp_image << "\"";
+
+ std::string attach_output;
+ if(!this->RunCommand(attach_command, &attach_output))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error attaching temporary disk image."
+ << std::endl);
+
+ return 0;
+ }
+
+ cmsys::RegularExpression mountpoint_regex(".*(/Volumes/[^\n]+)\n.*");
+ mountpoint_regex.find(attach_output.c_str());
+ 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))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error assigning custom icon to temporary disk image."
+ << std::endl);
+
+ return 0;
+ }
+
+ cmOStringStream detach_command;
+ detach_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
+ detach_command << " detach";
+ detach_command << " \"" << temp_mount.str() << "\"";
+
+ if(!this->RunCommand(detach_command))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error detaching temporary disk image."
+ << std::endl);
+
+ return 0;
+ }
+ }
+
+ if(!cpack_license_file.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::string line;
+ std::getline(ifs, line);
+ // escape quotes
+ std::string::size_type pos = line.find('\"');
+ while(pos != std::string::npos)
+ {
+ line.replace(pos, 1, "\\\"");
+ pos = line.find('\"', pos+2);
+ }
+ osf << " \"" << line << "\\n\"\n";
+ }
+ 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;
+ 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 << "\"";
+
+ std::string error;
+ if(!this->RunCommand(udco_image_command, &error))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error converting to UDCO dmg for adding SLA." << std::endl
+ << error
+ << std::endl);
+ return 0;
+ }
+
+ // unflatten dmg
+ cmOStringStream unflatten_command;
+ unflatten_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
+ unflatten_command << " unflatten ";
+ unflatten_command << "\"" << temp_udco << "\"";
+
+ if(!this->RunCommand(unflatten_command, &error))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error unflattening dmg for adding SLA." << std::endl
+ << error
+ << std::endl);
+ return 0;
+ }
+
+ // Rez the SLA
+ cmOStringStream embed_sla_command;
+ embed_sla_command << this->GetOption("CPACK_COMMAND_REZ");
+ embed_sla_command << " \"" << sla_r << "\"";
+ embed_sla_command << " -a -o ";
+ embed_sla_command << "\"" << temp_udco << "\"";
+
+ if(!this->RunCommand(embed_sla_command, &error))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error adding SLA." << std::endl
+ << error
+ << std::endl);
+ return 0;
+ }
+
+ // flatten dmg
+ cmOStringStream flatten_command;
+ flatten_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
+ flatten_command << " flatten ";
+ flatten_command << "\"" << temp_udco << "\"";
+
+ if(!this->RunCommand(flatten_command, &error))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error flattening dmg for adding SLA." << std::endl
+ << error
+ << std::endl);
+ return 0;
+ }
+
+ temp_image = temp_udco;
+ }
+
+
+ // Create the final compressed read-only disk image ...
+ cmOStringStream final_image_command;
+ final_image_command << this->GetOption("CPACK_COMMAND_HDIUTIL");
+ final_image_command << " convert \"" << temp_image << "\"";
+ final_image_command << " -format ";
+ final_image_command << cpack_dmg_format;
+ final_image_command << " -imagekey";
+ final_image_command << " zlib-level=9";
+ final_image_command << " -o \"" << output_file << "\"";
+
+ if(!this->RunCommand(final_image_command))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error compressing disk image."
+ << std::endl);
+
+ return 0;
+ }
+
+ return 1;
+}
+
+bool cmCPackDragNDropGenerator::SupportsComponentInstallation() const
+{
+ return true;
+}
+
+std::string
+cmCPackDragNDropGenerator::GetComponentInstallDirNameSuffix(
+ const std::string& componentName)
+{
+ // we want to group components together that go in the same dmg package
+ std::string package_file_name = this->GetOption("CPACK_PACKAGE_FILE_NAME");
+
+ // we have 3 mutually exclusive modes to work in
+ // 1. all components in one package
+ // 2. each group goes in its own package with left over
+ // components in their own package
+ // 3. ignore groups - if grouping is defined, it is ignored
+ // and each component goes in its own package
+
+ if(this->componentPackageMethod == ONE_PACKAGE)
+ {
+ return "ALL_IN_ONE";
+ }
+
+ if(this->componentPackageMethod == ONE_PACKAGE_PER_GROUP)
+ {
+ // We have to find the name of the COMPONENT GROUP
+ // the current COMPONENT belongs to.
+ std::string groupVar = "CPACK_COMPONENT_" +
+ cmSystemTools::UpperCase(componentName) + "_GROUP";
+ const char* _groupName = GetOption(groupVar.c_str());
+ if (_groupName)
+ {
+ std::string groupName = _groupName;
+
+ groupName = GetComponentPackageFileName(package_file_name,
+ groupName, true);
+ return groupName;
+ }
+ }
+
+ return GetComponentPackageFileName(package_file_name, componentName, false);
+}
diff --git a/Source/CPack/cmCPackDragNDropGenerator.h b/Source/CPack/cmCPackDragNDropGenerator.h
new file mode 100644
index 000000000..808c61886
--- /dev/null
+++ b/Source/CPack/cmCPackDragNDropGenerator.h
@@ -0,0 +1,47 @@
+/*============================================================================
+ 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 cmCPackDragNDropGenerator_h
+#define cmCPackDragNDropGenerator_h
+
+#include "cmCPackGenerator.h"
+
+/** \class cmCPackDragNDropGenerator
+ * \brief A generator for OSX drag-n-drop installs
+ */
+class cmCPackDragNDropGenerator : public cmCPackGenerator
+{
+public:
+ cmCPackTypeMacro(cmCPackDragNDropGenerator, cmCPackGenerator);
+
+ cmCPackDragNDropGenerator();
+ virtual ~cmCPackDragNDropGenerator();
+
+protected:
+ virtual int InitializeInternal();
+ virtual const char* GetOutputExtension();
+ int PackageFiles();
+ bool SupportsComponentInstallation() const;
+
+
+ bool CopyFile(cmOStringStream& source, cmOStringStream& target);
+ bool RunCommand(cmOStringStream& command, std::string* output = 0);
+
+ std::string
+ GetComponentInstallDirNameSuffix(const std::string& componentName);
+
+ int CreateDMG(const std::string& src_dir, const std::string& output_file);
+
+ std::string InstallPrefix;
+};
+
+#endif
diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx
new file mode 100644
index 000000000..0177653f5
--- /dev/null
+++ b/Source/CPack/cmCPackGenerator.cxx
@@ -0,0 +1,1685 @@
+/*============================================================================
+ 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 "cmCPackGenerator.h"
+
+#include "cmMakefile.h"
+#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 <memory> // auto_ptr
+#include <algorithm>
+
+#if defined(__HAIKU__)
+#include <StorageKit.h>
+#endif
+
+//----------------------------------------------------------------------
+cmCPackGenerator::cmCPackGenerator()
+{
+ this->GeneratorVerbose = cmSystemTools::OUTPUT_NONE;
+ this->MakefileMap = 0;
+ this->Logger = 0;
+ this->componentPackageMethod = ONE_PACKAGE_PER_GROUP;
+}
+
+//----------------------------------------------------------------------
+cmCPackGenerator::~cmCPackGenerator()
+{
+ this->MakefileMap = 0;
+}
+
+//----------------------------------------------------------------------
+void cmCPackGeneratorProgress(const char *msg, float prog, void* ptr)
+{
+ cmCPackGenerator* self = static_cast<cmCPackGenerator*>(ptr);
+ self->DisplayVerboseOutput(msg, prog);
+}
+
+//----------------------------------------------------------------------
+void cmCPackGenerator::DisplayVerboseOutput(const char* msg,
+ float progress)
+{
+ (void)progress;
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE, "" << msg << std::endl);
+}
+
+//----------------------------------------------------------------------
+int cmCPackGenerator::PrepareNames()
+{
+ cmCPackLogger(cmCPackLog::LOG_DEBUG,
+ "Create temp directory." << std::endl);
+
+ // checks CPACK_SET_DESTDIR support
+ if (IsOn("CPACK_SET_DESTDIR"))
+ {
+ if (SETDESTDIR_UNSUPPORTED==SupportsSetDestdir())
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "CPACK_SET_DESTDIR is set to ON but the '"
+ << Name << "' generator does NOT support it."
+ << std::endl);
+ return 0;
+ }
+ else if (SETDESTDIR_SHOULD_NOT_BE_USED==SupportsSetDestdir())
+ {
+ cmCPackLogger(cmCPackLog::LOG_WARNING,
+ "CPACK_SET_DESTDIR is set to ON but it is "
+ << "usually a bad idea to do that with '"
+ << Name << "' generator. Use at your own risk."
+ << std::endl);
+ }
+ }
+
+ std::string tempDirectory = this->GetOption("CPACK_PACKAGE_DIRECTORY");
+ tempDirectory += "/_CPack_Packages/";
+ const char* toplevelTag = this->GetOption("CPACK_TOPLEVEL_TAG");
+ if ( toplevelTag )
+ {
+ tempDirectory += toplevelTag;
+ tempDirectory += "/";
+ }
+ tempDirectory += this->GetOption("CPACK_GENERATOR");
+ std::string topDirectory = tempDirectory;
+ this->GetOption("CPACK_PACKAGE_FILE_NAME");
+ const char* pfname = this->GetOption("CPACK_PACKAGE_FILE_NAME");
+ if(!pfname)
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "CPACK_PACKAGE_FILE_NAME not specified" << std::endl);
+ return 0;
+ }
+ std::string outName = pfname;
+ tempDirectory += "/" + outName;
+ if(!this->GetOutputExtension())
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "No output extension specified" << std::endl);
+ return 0;
+ }
+ outName += this->GetOutputExtension();
+ const char* pdir = this->GetOption("CPACK_PACKAGE_DIRECTORY");
+ if(!pdir)
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "CPACK_PACKAGE_DIRECTORY not specified" << std::endl);
+ return 0;
+ }
+
+ std::string destFile = pdir;
+ this->SetOptionIfNotSet("CPACK_OUTPUT_FILE_PREFIX", destFile.c_str());
+ destFile += "/" + outName;
+ std::string outFile = topDirectory + "/" + outName;
+ this->SetOptionIfNotSet("CPACK_TOPLEVEL_DIRECTORY", topDirectory.c_str());
+ this->SetOptionIfNotSet("CPACK_TEMPORARY_DIRECTORY", tempDirectory.c_str());
+ this->SetOptionIfNotSet("CPACK_OUTPUT_FILE_NAME", outName.c_str());
+ this->SetOptionIfNotSet("CPACK_OUTPUT_FILE_PATH", destFile.c_str());
+ this->SetOptionIfNotSet("CPACK_TEMPORARY_PACKAGE_FILE_NAME",
+ outFile.c_str());
+ this->SetOptionIfNotSet("CPACK_INSTALL_DIRECTORY", this->GetInstallPath());
+ this->SetOptionIfNotSet("CPACK_NATIVE_INSTALL_DIRECTORY",
+ cmsys::SystemTools::ConvertToOutputPath(this->GetInstallPath()).c_str());
+ this->SetOptionIfNotSet("CPACK_TEMPORARY_INSTALL_DIRECTORY",
+ tempDirectory.c_str());
+
+ cmCPackLogger(cmCPackLog::LOG_DEBUG,
+ "Look for: CPACK_PACKAGE_DESCRIPTION_FILE" << std::endl);
+ const char* descFileName
+ = this->GetOption("CPACK_PACKAGE_DESCRIPTION_FILE");
+ if ( descFileName )
+ {
+ cmCPackLogger(cmCPackLog::LOG_DEBUG,
+ "Look for: " << descFileName << std::endl);
+ if ( !cmSystemTools::FileExists(descFileName) )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Cannot find description file name: ["
+ << descFileName << "]" << std::endl);
+ return 0;
+ }
+ std::ifstream ifs(descFileName);
+ if ( !ifs )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Cannot open description file name: " << descFileName << std::endl);
+ return 0;
+ }
+ cmOStringStream ostr;
+ std::string line;
+
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE,
+ "Read description file: " << descFileName << std::endl);
+ while ( ifs && cmSystemTools::GetLineFromStream(ifs, line) )
+ {
+ ostr << cmXMLSafe(line) << std::endl;
+ }
+ this->SetOptionIfNotSet("CPACK_PACKAGE_DESCRIPTION", ostr.str().c_str());
+ }
+ if ( !this->GetOption("CPACK_PACKAGE_DESCRIPTION") )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Project description not specified. Please specify "
+ "CPACK_PACKAGE_DESCRIPTION or CPACK_PACKAGE_DESCRIPTION_FILE."
+ << std::endl);
+ return 0;
+ }
+
+ this->SetOptionIfNotSet("CPACK_REMOVE_TOPLEVEL_DIRECTORY", "1");
+
+ return 1;
+}
+
+//----------------------------------------------------------------------
+int cmCPackGenerator::InstallProject()
+{
+ cmCPackLogger(cmCPackLog::LOG_OUTPUT, "Install projects" << std::endl);
+ this->CleanTemporaryDirectory();
+
+ std::string bareTempInstallDirectory
+ = this->GetOption("CPACK_TEMPORARY_INSTALL_DIRECTORY");
+ std::string tempInstallDirectoryStr = bareTempInstallDirectory;
+ bool setDestDir = cmSystemTools::IsOn(this->GetOption("CPACK_SET_DESTDIR"))
+ | cmSystemTools::IsInternallyOn(
+ this->GetOption("CPACK_SET_DESTDIR"));
+ if (!setDestDir)
+ {
+ tempInstallDirectoryStr += this->GetPackagingInstallPrefix();
+ }
+
+ const char* tempInstallDirectory = tempInstallDirectoryStr.c_str();
+ int res = 1;
+ if ( !cmsys::SystemTools::MakeDirectory(bareTempInstallDirectory.c_str()))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Problem creating temporary directory: "
+ << (tempInstallDirectory ? tempInstallDirectory : "(NULL}")
+ << std::endl);
+ return 0;
+ }
+
+ if ( setDestDir )
+ {
+ std::string destDir = "DESTDIR=";
+ destDir += tempInstallDirectory;
+ cmSystemTools::PutEnv(destDir.c_str());
+ }
+ else
+ {
+ // Make sure there is no destdir
+ cmSystemTools::PutEnv("DESTDIR=");
+ }
+
+ // If the CPackConfig file sets CPACK_INSTALL_COMMANDS then run them
+ // as listed
+ if ( !this->InstallProjectViaInstallCommands(
+ setDestDir, tempInstallDirectory) )
+ {
+ return 0;
+ }
+
+ // If the CPackConfig file sets CPACK_INSTALL_SCRIPT then run them
+ // as listed
+ if ( !this->InstallProjectViaInstallScript(
+ setDestDir, tempInstallDirectory) )
+ {
+ return 0;
+ }
+
+ // If the CPackConfig file sets CPACK_INSTALLED_DIRECTORIES
+ // then glob it and copy it to CPACK_TEMPORARY_DIRECTORY
+ // This is used in Source packaging
+ if ( !this->InstallProjectViaInstalledDirectories(
+ setDestDir, tempInstallDirectory) )
+ {
+ return 0;
+ }
+
+
+ // If the project is a CMAKE project then run pre-install
+ // and then read the cmake_install script to run it
+ if ( !this->InstallProjectViaInstallCMakeProjects(
+ setDestDir, bareTempInstallDirectory.c_str()) )
+ {
+ return 0;
+ }
+
+ if ( setDestDir )
+ {
+ cmSystemTools::PutEnv("DESTDIR=");
+ }
+
+ return res;
+}
+
+//----------------------------------------------------------------------
+int cmCPackGenerator::InstallProjectViaInstallCommands(
+ bool setDestDir, const char* tempInstallDirectory)
+{
+ (void) setDestDir;
+ const char* installCommands = this->GetOption("CPACK_INSTALL_COMMANDS");
+ if ( installCommands && *installCommands )
+ {
+ std::string tempInstallDirectoryEnv = "CMAKE_INSTALL_PREFIX=";
+ tempInstallDirectoryEnv += tempInstallDirectory;
+ cmSystemTools::PutEnv(tempInstallDirectoryEnv.c_str());
+ std::vector<std::string> installCommandsVector;
+ cmSystemTools::ExpandListArgument(installCommands,installCommandsVector);
+ std::vector<std::string>::iterator it;
+ for ( it = installCommandsVector.begin();
+ it != installCommandsVector.end();
+ ++it )
+ {
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << it->c_str()
+ << std::endl);
+ std::string output;
+ int retVal = 1;
+ bool resB = cmSystemTools::RunSingleCommand(it->c_str(), &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
+ << "# Output:" << std::endl
+ << output.c_str() << std::endl;
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Problem running install command: " << it->c_str() << std::endl
+ << "Please check " << tmpFile.c_str() << " for errors"
+ << std::endl);
+ return 0;
+ }
+ }
+ }
+ return 1;
+}
+
+//----------------------------------------------------------------------
+int cmCPackGenerator::InstallProjectViaInstalledDirectories(
+ bool setDestDir, const char* tempInstallDirectory)
+{
+ (void)setDestDir;
+ (void)tempInstallDirectory;
+ std::vector<cmsys::RegularExpression> ignoreFilesRegex;
+ const char* cpackIgnoreFiles = this->GetOption("CPACK_IGNORE_FILES");
+ if ( cpackIgnoreFiles )
+ {
+ std::vector<std::string> ignoreFilesRegexString;
+ cmSystemTools::ExpandListArgument(cpackIgnoreFiles,
+ ignoreFilesRegexString);
+ std::vector<std::string>::iterator it;
+ for ( it = ignoreFilesRegexString.begin();
+ it != ignoreFilesRegexString.end();
+ ++it )
+ {
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE,
+ "Create ignore files regex for: " << it->c_str() << std::endl);
+ ignoreFilesRegex.push_back(it->c_str());
+ }
+ }
+ const char* installDirectories
+ = this->GetOption("CPACK_INSTALLED_DIRECTORIES");
+ if ( installDirectories && *installDirectories )
+ {
+ std::vector<std::string> installDirectoriesVector;
+ cmSystemTools::ExpandListArgument(installDirectories,
+ installDirectoriesVector);
+ if ( installDirectoriesVector.size() % 2 != 0 )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "CPACK_INSTALLED_DIRECTORIES should contain pairs of <directory> and "
+ "<subdirectory>. The <subdirectory> can be '.' to be installed in "
+ "the toplevel directory of installation." << std::endl);
+ return 0;
+ }
+ std::vector<std::string>::iterator it;
+ const char* tempDir = tempInstallDirectory;
+ for ( it = installDirectoriesVector.begin();
+ it != installDirectoriesVector.end();
+ ++it )
+ {
+ 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();
+ it ++;
+ std::string subdir = it->c_str();
+ std::string findExpr = top;
+ findExpr += "/*";
+ cmCPackLogger(cmCPackLog::LOG_OUTPUT,
+ "- Install directory: " << top << std::endl);
+ gl.RecurseOn();
+ if ( !gl.FindFiles(findExpr) )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Cannot find any files in the installed directory" << std::endl);
+ return 0;
+ }
+ files = gl.GetFiles();
+ std::vector<std::string>::iterator gfit;
+ std::vector<cmsys::RegularExpression>::iterator regIt;
+ for ( gfit = files.begin(); gfit != files.end(); ++ gfit )
+ {
+ bool skip = false;
+ std::string &inFile = *gfit;
+ for ( regIt= ignoreFilesRegex.begin();
+ regIt!= ignoreFilesRegex.end();
+ ++ regIt)
+ {
+ if ( regIt->find(inFile.c_str()) )
+ {
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Ignore file: "
+ << inFile.c_str() << std::endl);
+ skip = true;
+ }
+ }
+ if ( skip )
+ {
+ continue;
+ }
+ std::string filePath = tempDir;
+ filePath += "/" + subdir + "/"
+ + cmSystemTools::RelativePath(top.c_str(), gfit->c_str());
+ cmCPackLogger(cmCPackLog::LOG_DEBUG, "Copy file: "
+ << inFile.c_str() << " -> " << filePath.c_str() << std::endl);
+ /* If the file is a symlink we will have to re-create it */
+ if ( cmSystemTools::FileIsSymlink(inFile.c_str()))
+ {
+ std::string targetFile;
+ std::string inFileRelative =
+ cmSystemTools::RelativePath(top.c_str(),inFile.c_str());
+ cmSystemTools::ReadSymlink(inFile.c_str(),targetFile);
+ symlinkedFiles.push_back(std::pair<std::string,
+ std::string>(targetFile,inFileRelative));
+ }
+ /* If it is not a symlink then do a plain copy */
+ else if (!(
+ cmSystemTools::CopyFileIfDifferent(inFile.c_str(),filePath.c_str())
+ &&
+ cmSystemTools::CopyFileTime(inFile.c_str(),filePath.c_str())
+ ) )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem copying file: "
+ << inFile.c_str() << " -> " << filePath.c_str() << std::endl);
+ return 0;
+ }
+ }
+ /* rebuild symlinks in the installed tree */
+ if (symlinkedFiles.size()>0)
+ {
+ std::list< std::pair<std::string,std::string> >::iterator symlinkedIt;
+ std::string curDir = cmSystemTools::GetCurrentWorkingDirectory();
+ std::string goToDir = tempDir;
+ goToDir += "/"+subdir;
+ cmCPackLogger(cmCPackLog::LOG_DEBUG,
+ "Change dir to: " << goToDir <<std::endl);
+ cmSystemTools::ChangeDirectory(goToDir.c_str());
+ for (symlinkedIt=symlinkedFiles.begin();
+ symlinkedIt != symlinkedFiles.end();
+ ++symlinkedIt)
+ {
+ 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()))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot create symlink: "
+ << symlinkedIt->second << "--> "
+ << symlinkedIt->first << std::endl);
+ return 0;
+ }
+ }
+ cmCPackLogger(cmCPackLog::LOG_DEBUG, "Going back to: "
+ << curDir <<std::endl);
+ cmSystemTools::ChangeDirectory(curDir.c_str());
+ }
+ }
+ }
+ return 1;
+}
+
+//----------------------------------------------------------------------
+int cmCPackGenerator::InstallProjectViaInstallScript(
+ bool setDestDir, const char* tempInstallDirectory)
+{
+ const char* cmakeScripts
+ = this->GetOption("CPACK_INSTALL_SCRIPT");
+ if ( cmakeScripts && *cmakeScripts )
+ {
+ cmCPackLogger(cmCPackLog::LOG_OUTPUT,
+ "- Install scripts: " << cmakeScripts << std::endl);
+ std::vector<std::string> cmakeScriptsVector;
+ cmSystemTools::ExpandListArgument(cmakeScripts,
+ cmakeScriptsVector);
+ std::vector<std::string>::iterator it;
+ for ( it = cmakeScriptsVector.begin();
+ it != cmakeScriptsVector.end();
+ ++it )
+ {
+ std::string installScript = it->c_str();
+
+ cmCPackLogger(cmCPackLog::LOG_OUTPUT,
+ "- Install script: " << installScript << std::endl);
+
+ if ( setDestDir )
+ {
+ // For DESTDIR based packaging, use the *project* CMAKE_INSTALL_PREFIX
+ // underneath the tempInstallDirectory. The value of the project's
+ // CMAKE_INSTALL_PREFIX is sent in here as the value of the
+ // CPACK_INSTALL_PREFIX variable.
+
+ std::string dir;
+ if (this->GetOption("CPACK_INSTALL_PREFIX"))
+ {
+ dir += this->GetOption("CPACK_INSTALL_PREFIX");
+ }
+ this->SetOption("CMAKE_INSTALL_PREFIX", dir.c_str());
+ cmCPackLogger(cmCPackLog::LOG_DEBUG,
+ "- Using DESTDIR + CPACK_INSTALL_PREFIX... (this->SetOption)"
+ << std::endl);
+ cmCPackLogger(cmCPackLog::LOG_DEBUG,
+ "- Setting CMAKE_INSTALL_PREFIX to '" << dir << "'" << std::endl);
+ }
+ else
+ {
+ this->SetOption("CMAKE_INSTALL_PREFIX", tempInstallDirectory);
+
+ cmCPackLogger(cmCPackLog::LOG_DEBUG,
+ "- Using non-DESTDIR install... (this->SetOption)" << std::endl);
+ cmCPackLogger(cmCPackLog::LOG_DEBUG,
+ "- Setting CMAKE_INSTALL_PREFIX to '" << tempInstallDirectory
+ << "'" << std::endl);
+ }
+
+ this->SetOptionIfNotSet("CMAKE_CURRENT_BINARY_DIR",
+ tempInstallDirectory);
+ this->SetOptionIfNotSet("CMAKE_CURRENT_SOURCE_DIR",
+ tempInstallDirectory);
+ int res = this->MakefileMap->ReadListFile(0, installScript.c_str());
+ if ( cmSystemTools::GetErrorOccuredFlag() || !res )
+ {
+ return 0;
+ }
+ }
+ }
+ return 1;
+}
+
+//----------------------------------------------------------------------
+int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
+ bool setDestDir, const char* baseTempInstallDirectory)
+{
+ const char* cmakeProjects
+ = this->GetOption("CPACK_INSTALL_CMAKE_PROJECTS");
+ const char* cmakeGenerator
+ = this->GetOption("CPACK_CMAKE_GENERATOR");
+ std::string absoluteDestFiles;
+ if ( cmakeProjects && *cmakeProjects )
+ {
+ if ( !cmakeGenerator )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "CPACK_INSTALL_CMAKE_PROJECTS is specified, but "
+ "CPACK_CMAKE_GENERATOR is not. CPACK_CMAKE_GENERATOR "
+ "is required to install the project."
+ << std::endl);
+ return 0;
+ }
+ std::vector<std::string> cmakeProjectsVector;
+ cmSystemTools::ExpandListArgument(cmakeProjects,
+ cmakeProjectsVector);
+ std::vector<std::string>::iterator it;
+ for ( it = cmakeProjectsVector.begin();
+ it != cmakeProjectsVector.end();
+ ++it )
+ {
+ if ( it+1 == cmakeProjectsVector.end() ||
+ it+2 == cmakeProjectsVector.end() ||
+ it+3 == cmakeProjectsVector.end() )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Not enough items on list: CPACK_INSTALL_CMAKE_PROJECTS. "
+ "CPACK_INSTALL_CMAKE_PROJECTS should hold quadruplet of install "
+ "directory, install project name, install component, and install "
+ "subdirectory."
+ << std::endl);
+ return 0;
+ }
+ std::string installDirectory = it->c_str();
+ ++it;
+ std::string installProjectName = it->c_str();
+ ++it;
+ std::string installComponent = it->c_str();
+ ++it;
+ std::string installSubDirectory = it->c_str();
+ std::string installFile = installDirectory + "/cmake_install.cmake";
+
+ std::vector<std::string> componentsVector;
+
+ bool componentInstall = false;
+ /*
+ * We do a component install iff
+ * - the CPack generator support component
+ * - the user did not request Monolithic install
+ * (this works at CPack time too)
+ */
+ if (this->SupportsComponentInstallation() &
+ !(this->IsSet("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());
+ if (installTypes && *installTypes)
+ {
+ std::vector<std::string> installTypesVector;
+ cmSystemTools::ExpandListArgument(installTypes, installTypesVector);
+ std::vector<std::string>::iterator installTypeIt;
+ for (installTypeIt = installTypesVector.begin();
+ installTypeIt != installTypesVector.end();
+ ++installTypeIt)
+ {
+ this->GetInstallationType(installProjectName.c_str(),
+ installTypeIt->c_str());
+ }
+ }
+
+ // 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());
+ if (components && *components)
+ {
+ cmSystemTools::ExpandListArgument(components, componentsVector);
+ std::vector<std::string>::iterator compIt;
+ for (compIt = componentsVector.begin();
+ compIt != componentsVector.end();
+ ++compIt)
+ {
+ GetComponent(installProjectName.c_str(), compIt->c_str());
+ }
+ componentInstall = true;
+ }
+ }
+ if (componentsVector.empty())
+ {
+ componentsVector.push_back(installComponent);
+ }
+
+ const char* buildConfig = this->GetOption("CPACK_BUILD_CONFIG");
+ cmGlobalGenerator* globalGenerator
+ = this->MakefileMap->GetCMakeInstance()->CreateGlobalGenerator(
+ cmakeGenerator);
+ // 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() )
+ {
+ globalGenerator->FindMakeProgram(this->MakefileMap);
+ const char* cmakeMakeProgram
+ = this->MakefileMap->GetDefinition("CMAKE_MAKE_PROGRAM");
+ std::string buildCommand
+ = globalGenerator->GenerateBuildCommand(cmakeMakeProgram,
+ installProjectName.c_str(), 0,
+ globalGenerator->GetPreinstallTargetName(),
+ buildConfig, false, false);
+ cmCPackLogger(cmCPackLog::LOG_DEBUG,
+ "- Install command: " << buildCommand << std::endl);
+ cmCPackLogger(cmCPackLog::LOG_OUTPUT,
+ "- Run preinstall target for: " << installProjectName << std::endl);
+ std::string output;
+ int retVal = 1;
+ bool resB =
+ cmSystemTools::RunSingleCommand(buildCommand.c_str(),
+ &output,
+ &retVal,
+ installDirectory.c_str(),
+ this->GeneratorVerbose, 0);
+ if ( !resB || retVal )
+ {
+ 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
+ << "# Output:" << std::endl
+ << output.c_str() << std::endl;
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Problem running install command: " << buildCommand.c_str()
+ << std::endl
+ << "Please check " << tmpFile.c_str() << " for errors"
+ << std::endl);
+ return 0;
+ }
+ }
+ delete globalGenerator;
+
+ cmCPackLogger(cmCPackLog::LOG_OUTPUT,
+ "- Install project: " << installProjectName << std::endl);
+
+ // Run the installation for each component
+ std::vector<std::string>::iterator componentIt;
+ for (componentIt = componentsVector.begin();
+ componentIt != componentsVector.end();
+ ++componentIt)
+ {
+ std::string tempInstallDirectory = baseTempInstallDirectory;
+ installComponent = *componentIt;
+ if (componentInstall)
+ {
+ cmCPackLogger(cmCPackLog::LOG_OUTPUT,
+ "- Install component: " << installComponent
+ << std::endl);
+ }
+
+ cmake cm;
+ cm.AddCMakePaths();
+ cm.SetProgressCallback(cmCPackGeneratorProgress, this);
+ cmGlobalGenerator gg;
+ gg.SetCMakeInstance(&cm);
+ std::auto_ptr<cmLocalGenerator> lg(gg.CreateLocalGenerator());
+ cmMakefile *mf = lg->GetMakefile();
+ std::string realInstallDirectory = tempInstallDirectory;
+ if ( !installSubDirectory.empty() && installSubDirectory != "/" )
+ {
+ realInstallDirectory += installSubDirectory;
+ }
+ if (componentInstall)
+ {
+ tempInstallDirectory += "/";
+ // Some CPack generators would rather chose
+ // the local installation directory suffix.
+ // Some (e.g. RPM) use
+ // one install directory for each component **GROUP**
+ // instead of the default
+ // one install directory for each component.
+ tempInstallDirectory +=
+ GetComponentInstallDirNameSuffix(installComponent);
+ if (this->IsOn("CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY"))
+ {
+ tempInstallDirectory += "/";
+ tempInstallDirectory += this->GetOption("CPACK_PACKAGE_FILE_NAME");
+ }
+ }
+
+ if (!setDestDir)
+ {
+ tempInstallDirectory += this->GetPackagingInstallPrefix();
+ }
+
+ if ( setDestDir )
+ {
+ // For DESTDIR based packaging, use the *project*
+ // CMAKE_INSTALL_PREFIX underneath the tempInstallDirectory. The
+ // value of the project's CMAKE_INSTALL_PREFIX is sent in here as
+ // the value of the CPACK_INSTALL_PREFIX variable.
+ //
+ // If DESTDIR has been 'internally set ON' this means that
+ // the underlying CPack specific generator did ask for that
+ // In this case we may override CPACK_INSTALL_PREFIX with
+ // CPACK_PACKAGING_INSTALL_PREFIX
+ // I know this is tricky and awkward but it's the price for
+ // CPACK_SET_DESTDIR backward compatibility.
+ if (cmSystemTools::IsInternallyOn(
+ this->GetOption("CPACK_SET_DESTDIR")))
+ {
+ this->SetOption("CPACK_INSTALL_PREFIX",
+ this->GetOption("CPACK_PACKAGING_INSTALL_PREFIX"));
+ }
+ std::string dir;
+ if (this->GetOption("CPACK_INSTALL_PREFIX"))
+ {
+ dir += this->GetOption("CPACK_INSTALL_PREFIX");
+ }
+ mf->AddDefinition("CMAKE_INSTALL_PREFIX", dir.c_str());
+
+ cmCPackLogger(
+ cmCPackLog::LOG_DEBUG,
+ "- Using DESTDIR + CPACK_INSTALL_PREFIX... (mf->AddDefinition)"
+ << std::endl);
+ cmCPackLogger(cmCPackLog::LOG_DEBUG,
+ "- Setting CMAKE_INSTALL_PREFIX to '" << dir << "'"
+ << std::endl);
+
+ // Make sure that DESTDIR + CPACK_INSTALL_PREFIX directory
+ // exists:
+ //
+ if (cmSystemTools::StringStartsWith(dir.c_str(), "/"))
+ {
+ dir = tempInstallDirectory + dir;
+ }
+ else
+ {
+ dir = tempInstallDirectory + "/" + dir;
+ }
+ /*
+ * We must re-set DESTDIR for each component
+ * We must not add the CPACK_INSTALL_PREFIX part because
+ * it will be added using the override of CMAKE_INSTALL_PREFIX
+ * The main reason for this awkward trick is that
+ * are using DESTDIR for 2 different reasons:
+ * - Because it was asked by the CPack Generator or the user
+ * using CPACK_SET_DESTDIR
+ * - Because it was already used for component install
+ * in order to put things in subdirs...
+ */
+ cmSystemTools::PutEnv(
+ (std::string("DESTDIR=")+tempInstallDirectory).c_str()
+ );
+ cmCPackLogger(cmCPackLog::LOG_DEBUG,
+ "- Creating directory: '" << dir << "'" << std::endl);
+
+ if ( !cmsys::SystemTools::MakeDirectory(dir.c_str()))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Problem creating temporary directory: "
+ << dir << std::endl);
+ return 0;
+ }
+ }
+ else
+ {
+ mf->AddDefinition("CMAKE_INSTALL_PREFIX",
+ tempInstallDirectory.c_str());
+
+ if ( !cmsys::SystemTools::MakeDirectory(
+ tempInstallDirectory.c_str()))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Problem creating temporary directory: "
+ << tempInstallDirectory << std::endl);
+ return 0;
+ }
+
+ cmCPackLogger(cmCPackLog::LOG_DEBUG,
+ "- Using non-DESTDIR install... (mf->AddDefinition)"
+ << std::endl);
+ cmCPackLogger(cmCPackLog::LOG_DEBUG,
+ "- Setting CMAKE_INSTALL_PREFIX to '"
+ << tempInstallDirectory
+ << "'" << std::endl);
+ }
+
+ if ( buildConfig && *buildConfig )
+ {
+ mf->AddDefinition("BUILD_TYPE", buildConfig);
+ }
+ std::string installComponentLowerCase
+ = cmSystemTools::LowerCase(installComponent);
+ if ( installComponentLowerCase != "all" )
+ {
+ mf->AddDefinition("CMAKE_INSTALL_COMPONENT",
+ installComponent.c_str());
+ }
+
+ // strip on TRUE, ON, 1, one or several file names, but not on
+ // FALSE, OFF, 0 and an empty string
+ if (!cmSystemTools::IsOff(this->GetOption("CPACK_STRIP_FILES")))
+ {
+ mf->AddDefinition("CMAKE_INSTALL_DO_STRIP", "1");
+ }
+ // Remember the list of files before installation
+ // of the current component (if we are in component install)
+ const char* InstallPrefix = tempInstallDirectory.c_str();
+ std::vector<std::string> filesBefore;
+ std::string findExpr(InstallPrefix);
+ if (componentInstall)
+ {
+ cmsys::Glob glB;
+ findExpr += "/*";
+ glB.RecurseOn();
+ glB.FindFiles(findExpr);
+ filesBefore = glB.GetFiles();
+ std::sort(filesBefore.begin(),filesBefore.end());
+ }
+
+ // If CPack was asked to warn on ABSOLUTE INSTALL DESTINATION
+ // then forward request to cmake_install.cmake script
+ if (this->GetOption("CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION"))
+ {
+ mf->AddDefinition("CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION",
+ "1");
+ }
+ // If current CPack generator does support
+ // ABSOLUTE INSTALL DESTINATION or CPack has been asked for
+ // then ask cmake_install.cmake script to error out
+ // as soon as it occurs (before installing file)
+ if (!SupportsAbsoluteDestination() ||
+ this->GetOption("CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION"))
+ {
+ mf->AddDefinition("CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION",
+ "1");
+ }
+ // do installation
+ int res = mf->ReadListFile(0, 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
+ if (mf->GetDefinition("CMAKE_ABSOLUTE_DESTINATION_FILES"))
+ {
+ mf->AddDefinition("CPACK_ABSOLUTE_DESTINATION_FILES",
+ mf->GetDefinition("CMAKE_ABSOLUTE_DESTINATION_FILES"));
+ }
+
+ // Now rebuild the list of files after installation
+ // of the current component (if we are in component install)
+ if (componentInstall)
+ {
+ cmsys::Glob glA;
+ glA.RecurseOn();
+ glA.FindFiles(findExpr);
+ std::vector<std::string> filesAfter = glA.GetFiles();
+ std::sort(filesAfter.begin(),filesAfter.end());
+ std::vector<std::string>::iterator diff;
+ std::vector<std::string> result(filesAfter.size());
+ diff = std::set_difference (
+ filesAfter.begin(),filesAfter.end(),
+ filesBefore.begin(),filesBefore.end(),
+ result.begin());
+
+ std::vector<std::string>::iterator fit;
+ std::string localFileName;
+ // Populate the File field of each component
+ for (fit=result.begin();fit!=diff;++fit)
+ {
+ localFileName =
+ cmSystemTools::RelativePath(InstallPrefix, fit->c_str());
+ localFileName =
+ localFileName.substr(localFileName.find('/')+1,
+ std::string::npos);
+ Components[installComponent].Files.push_back(localFileName);
+ cmCPackLogger(cmCPackLog::LOG_DEBUG, "Adding file <"
+ <<localFileName<<"> to component <"
+ <<installComponent<<">"<<std::endl);
+ }
+ }
+
+ if (NULL !=mf->GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES")) {
+ if (absoluteDestFiles.length()>0) {
+ absoluteDestFiles +=";";
+ }
+ absoluteDestFiles +=
+ mf->GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES");
+ cmCPackLogger(cmCPackLog::LOG_DEBUG,
+ "Got some ABSOLUTE DESTINATION FILES: "
+ << absoluteDestFiles << std::endl);
+ // define component specific var
+ if (componentInstall)
+ {
+ std::string absoluteDestFileComponent =
+ std::string("CPACK_ABSOLUTE_DESTINATION_FILES")
+ + "_" + GetComponentInstallDirNameSuffix(installComponent);
+ if (NULL != this->GetOption(absoluteDestFileComponent.c_str()))
+ {
+ std::string absoluteDestFilesListComponent =
+ this->GetOption(absoluteDestFileComponent.c_str());
+ absoluteDestFilesListComponent +=";";
+ absoluteDestFilesListComponent +=
+ mf->GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES");
+ this->SetOption(absoluteDestFileComponent.c_str(),
+ absoluteDestFilesListComponent.c_str());
+ }
+ else
+ {
+ this->SetOption(absoluteDestFileComponent.c_str(),
+ mf->GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES"));
+ }
+ }
+ }
+ if ( cmSystemTools::GetErrorOccuredFlag() || !res )
+ {
+ return 0;
+ }
+ }
+ }
+ }
+ this->SetOption("CPACK_ABSOLUTE_DESTINATION_FILES",
+ absoluteDestFiles.c_str());
+ return 1;
+}
+
+//----------------------------------------------------------------------
+bool cmCPackGenerator::ReadListFile(const char* moduleName)
+{
+ bool retval;
+ std::string fullPath = this->MakefileMap->GetModulesFile(moduleName);
+ retval = this->MakefileMap->ReadListFile(0, fullPath.c_str());
+ // include FATAL_ERROR and ERROR in the return status
+ retval = retval && (! cmSystemTools::GetErrorOccuredFlag());
+ return retval;
+}
+
+//----------------------------------------------------------------------
+void cmCPackGenerator::SetOptionIfNotSet(const char* op,
+ const char* value)
+{
+ const char* def = this->MakefileMap->GetDefinition(op);
+ if ( def && *def )
+ {
+ return;
+ }
+ this->SetOption(op, value);
+}
+
+//----------------------------------------------------------------------
+void cmCPackGenerator::SetOption(const char* op, const char* value)
+{
+ if ( !op )
+ {
+ return;
+ }
+ if ( !value )
+ {
+ this->MakefileMap->RemoveDefinition(op);
+ return;
+ }
+ cmCPackLogger(cmCPackLog::LOG_DEBUG, this->GetNameOfClass()
+ << "::SetOption(" << op << ", " << value << ")" << std::endl);
+ this->MakefileMap->AddDefinition(op, value);
+}
+
+//----------------------------------------------------------------------
+int cmCPackGenerator::DoPackage()
+{
+ cmCPackLogger(cmCPackLog::LOG_OUTPUT,
+ "Create package using " << this->Name.c_str() << std::endl);
+
+ // Prepare CPack internal name and check
+ // values for many CPACK_xxx vars
+ if ( !this->PrepareNames() )
+ {
+ return 0;
+ }
+
+ // Digest Component grouping specification
+ if ( !this->PrepareGroupingKind() )
+ {
+ return 0;
+ }
+
+ if ( cmSystemTools::IsOn(
+ this->GetOption("CPACK_REMOVE_TOPLEVEL_DIRECTORY")) )
+ {
+ const char* toplevelDirectory
+ = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
+ if ( cmSystemTools::FileExists(toplevelDirectory) )
+ {
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE,
+ "Remove toplevel directory: "
+ << toplevelDirectory << std::endl);
+ if ( !cmSystemTools::RepeatedRemoveDirectory(toplevelDirectory) )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Problem removing toplevel directory: "
+ << toplevelDirectory
+ << std::endl);
+ return 0;
+ }
+ }
+ }
+ cmCPackLogger(cmCPackLog::LOG_DEBUG,
+ "About to install project " << std::endl);
+
+ if ( !this->InstallProject() )
+ {
+ return 0;
+ }
+ cmCPackLogger(cmCPackLog::LOG_DEBUG,
+ "Done install project " << std::endl);
+
+
+ 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);
+ cmsys::Glob gl;
+ std::string findExpr = tempDirectory;
+ findExpr += "/*";
+ gl.RecurseOn();
+ gl.SetRecurseThroughSymlinks(false);
+ if ( !gl.FindFiles(findExpr) )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Cannot find any files in the packaging tree" << std::endl);
+ return 0;
+ }
+
+ cmCPackLogger(cmCPackLog::LOG_OUTPUT, "Create package" << std::endl);
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Package files to: "
+ << (tempPackageFileName ? tempPackageFileName : "(NULL)") << std::endl);
+ if ( cmSystemTools::FileExists(tempPackageFileName) )
+ {
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Remove old package file"
+ << std::endl);
+ cmSystemTools::RemoveFile(tempPackageFileName);
+ }
+ if ( cmSystemTools::IsOn(this->GetOption(
+ "CPACK_INCLUDE_TOPLEVEL_DIRECTORY")) )
+ {
+ tempDirectory = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
+ }
+
+ // The files to be installed
+ files = gl.GetFiles();
+
+ packageFileNames.clear();
+ /* Put at least one file name into the list of
+ * wanted packageFileNames. The specific generator
+ * may update this during PackageFiles.
+ * (either putting several names or updating the provided one)
+ */
+ packageFileNames.push_back(tempPackageFileName);
+ toplevel = tempDirectory;
+ if ( !this->PackageFiles() || cmSystemTools::GetErrorOccuredFlag())
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem compressing the directory"
+ << std::endl);
+ return 0;
+ }
+
+ /*
+ * Copy the generated packages to final destination
+ * - there may be several of them
+ * - the initially provided name may have changed
+ * (because the specific generator did 'normalize' it)
+ */
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Copying final package(s) ["
+ <<packageFileNames.size()
+ <<"]:"<<std::endl);
+ std::vector<std::string>::iterator it;
+ /* now copy package one by one */
+ for (it=packageFileNames.begin();it!=packageFileNames.end();++it)
+ {
+ std::string tmpPF(this->GetOption("CPACK_OUTPUT_FILE_PREFIX"));
+ tempPackageFileName = it->c_str();
+ tmpPF += "/"+cmSystemTools::GetFilenameName(*it);
+ packageFileName = tmpPF.c_str();
+ cmCPackLogger(cmCPackLog::LOG_DEBUG, "Copy final package(s): "
+ << (tempPackageFileName ? tempPackageFileName : "(NULL)" )
+ << " to "
+ << (packageFileName ? packageFileName : "(NULL)")
+ << std::endl);
+ if ( !cmSystemTools::CopyFileIfDifferent(tempPackageFileName,
+ packageFileName) )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem copying the package: "
+ << (tempPackageFileName ? tempPackageFileName : "(NULL)" )
+ << " to "
+ << (packageFileName ? packageFileName : "(NULL)")
+ << std::endl);
+ return 0;
+ }
+ cmCPackLogger(cmCPackLog::LOG_OUTPUT, "- package: "
+ << packageFileName
+ << " generated." << std::endl);
+ }
+
+ return 1;
+}
+
+//----------------------------------------------------------------------
+int cmCPackGenerator::Initialize(const char* 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
+ const char* config =
+ this->GetOption("CPACK_PROJECT_CONFIG_FILE");
+ if(config)
+ {
+ mf->ReadListFile(config);
+ }
+ int result = this->InitializeInternal();
+ if (cmSystemTools::GetErrorOccuredFlag())
+ {
+ return 0;
+ }
+
+ // If a generator subclass did not already set this option in its
+ // InitializeInternal implementation, and the project did not already set
+ // it, the default value should be:
+ this->SetOptionIfNotSet("CPACK_PACKAGING_INSTALL_PREFIX", "/");
+
+ return result;
+}
+
+//----------------------------------------------------------------------
+int cmCPackGenerator::InitializeInternal()
+{
+ return 1;
+}
+
+//----------------------------------------------------------------------
+bool cmCPackGenerator::IsSet(const char* name) const
+{
+ return this->MakefileMap->IsSet(name);
+}
+
+//----------------------------------------------------------------------
+bool cmCPackGenerator::IsOn(const char* name) const
+{
+ return cmSystemTools::IsOn(GetOption(name));
+}
+
+//----------------------------------------------------------------------
+const char* cmCPackGenerator::GetOption(const char* op) const
+{
+ const char* ret = this->MakefileMap->GetDefinition(op);
+ if(!ret)
+ {
+ cmCPackLogger(cmCPackLog::LOG_DEBUG,
+ "Warning, GetOption return NULL for: "
+ << op
+ << std::endl);
+ }
+ return ret;
+}
+
+//----------------------------------------------------------------------
+int cmCPackGenerator::SetCMakeRoot()
+{
+ // 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;
+}
+
+//----------------------------------------------------------------------
+int cmCPackGenerator::PackageFiles()
+{
+ return 0;
+}
+
+//----------------------------------------------------------------------
+const char* cmCPackGenerator::GetInstallPath()
+{
+ if ( !this->InstallPath.empty() )
+ {
+ return this->InstallPath.c_str();
+ }
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ const char* prgfiles = cmsys::SystemTools::GetEnv("ProgramFiles");
+ const char* sysDrive = cmsys::SystemTools::GetEnv("SystemDrive");
+ if ( prgfiles )
+ {
+ this->InstallPath = prgfiles;
+ }
+ else if ( sysDrive )
+ {
+ this->InstallPath = sysDrive;
+ this->InstallPath += "/Program Files";
+ }
+ else
+ {
+ this->InstallPath = "c:/Program Files";
+ }
+ this->InstallPath += "/";
+ this->InstallPath += this->GetOption("CPACK_PACKAGE_NAME");
+ this->InstallPath += "-";
+ this->InstallPath += this->GetOption("CPACK_PACKAGE_VERSION");
+#elif defined(__HAIKU__)
+ BPath dir;
+ if (find_directory(B_COMMON_DIRECTORY, &dir) == B_OK)
+ {
+ this->InstallPath = dir.Path();
+ }
+ else
+ {
+ this->InstallPath = "/boot/common";
+ }
+#else
+ this->InstallPath = "/usr/local/";
+#endif
+ return this->InstallPath.c_str();
+}
+
+//----------------------------------------------------------------------
+const char* cmCPackGenerator::GetPackagingInstallPrefix()
+{
+ cmCPackLogger(cmCPackLog::LOG_DEBUG, "GetPackagingInstallPrefix: '"
+ << this->GetOption("CPACK_PACKAGING_INSTALL_PREFIX") << "'" << std::endl);
+
+ return this->GetOption("CPACK_PACKAGING_INSTALL_PREFIX");
+}
+
+//----------------------------------------------------------------------
+std::string cmCPackGenerator::FindTemplate(const char* name)
+{
+ cmCPackLogger(cmCPackLog::LOG_DEBUG, "Look for template: "
+ << (name ? name : "(NULL)") << std::endl);
+ std::string ffile = this->MakefileMap->GetModulesFile(name);
+ cmCPackLogger(cmCPackLog::LOG_DEBUG, "Found template: "
+ << ffile.c_str() << std::endl);
+ return ffile;
+}
+
+//----------------------------------------------------------------------
+bool cmCPackGenerator::ConfigureString(const std::string& inString,
+ std::string& outString)
+{
+ this->MakefileMap->ConfigureString(inString,
+ outString, true, false);
+ return true;
+}
+
+//----------------------------------------------------------------------
+bool cmCPackGenerator::ConfigureFile(const char* inName,
+ const char* outName, bool copyOnly /* = false */)
+{
+ return this->MakefileMap->ConfigureFile(inName, outName,
+ copyOnly, true, false) == 1;
+}
+
+//----------------------------------------------------------------------
+int cmCPackGenerator::CleanTemporaryDirectory()
+{
+ std::string tempInstallDirectoryWithPostfix
+ = this->GetOption("CPACK_TEMPORARY_INSTALL_DIRECTORY");
+ const char* tempInstallDirectory = tempInstallDirectoryWithPostfix.c_str();
+ if(cmsys::SystemTools::FileExists(tempInstallDirectory))
+ {
+ cmCPackLogger(cmCPackLog::LOG_OUTPUT,
+ "- Clean temporary : "
+ << tempInstallDirectory << std::endl);
+ if(!cmSystemTools::RepeatedRemoveDirectory(tempInstallDirectory))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Problem removing temporary directory: " <<
+ tempInstallDirectory
+ << std::endl);
+ return 0;
+ }
+ }
+ return 1;
+}
+
+//----------------------------------------------------------------------
+int cmCPackGenerator::PrepareGroupingKind()
+{
+ // find a component package method specified by the user
+ ComponentPackageMethod method = UNKNOWN_COMPONENT_PACKAGE_METHOD;
+
+ if(this->GetOption("CPACK_COMPONENTS_ALL_IN_ONE_PACKAGE"))
+ {
+ method = ONE_PACKAGE;
+ }
+
+ if(this->GetOption("CPACK_COMPONENTS_IGNORE_GROUPS"))
+ {
+ method = ONE_PACKAGE_PER_COMPONENT;
+ }
+
+ if(this->GetOption("CPACK_COMPONENTS_ONE_PACKAGE_PER_GROUP"))
+ {
+ method = ONE_PACKAGE_PER_GROUP;
+ }
+
+ std::string groupingType;
+
+ // Second way to specify grouping
+ if (NULL != this->GetOption("CPACK_COMPONENTS_GROUPING")) {
+ groupingType = this->GetOption("CPACK_COMPONENTS_GROUPING");
+ }
+
+ if (groupingType.length()>0)
+ {
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE, "["
+ << this->Name << "]"
+ << " requested component grouping = "<< groupingType <<std::endl);
+ if (groupingType == "ALL_COMPONENTS_IN_ONE")
+ {
+ method = ONE_PACKAGE;
+ }
+ else if (groupingType == "IGNORE")
+ {
+ method = ONE_PACKAGE_PER_COMPONENT;
+ }
+ else if (groupingType == "ONE_PER_GROUP")
+ {
+ method = ONE_PACKAGE_PER_GROUP;
+ }
+ else
+ {
+ cmCPackLogger(cmCPackLog::LOG_WARNING, "["
+ << this->Name << "]"
+ << " requested component grouping type <"<< groupingType
+ << "> UNKNOWN not in (ALL_COMPONENTS_IN_ONE,IGNORE,ONE_PER_GROUP)"
+ << std::endl);
+ }
+ }
+
+ // Some components were defined but NO group
+ // fallback to default if not group based
+ if(method == ONE_PACKAGE_PER_GROUP &&
+ this->ComponentGroups.empty() && !this->Components.empty())
+ {
+ if(componentPackageMethod == ONE_PACKAGE)
+ {
+ method = ONE_PACKAGE;
+ }
+ else
+ {
+ method = ONE_PACKAGE_PER_COMPONENT;
+ }
+ cmCPackLogger(cmCPackLog::LOG_WARNING, "["
+ << this->Name << "]"
+ << " One package per component group requested, "
+ << "but NO component groups exist: Ignoring component group."
+ << std::endl);
+ }
+
+ // if user specified packaging method, override the default packaging method
+ if(method != UNKNOWN_COMPONENT_PACKAGE_METHOD)
+ {
+ componentPackageMethod = method;
+ }
+
+ const char* method_names[] =
+ {
+ "ALL_COMPONENTS_IN_ONE",
+ "IGNORE_GROUPS",
+ "ONE_PER_GROUP"
+ };
+
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE, "["
+ << this->Name << "]"
+ << " requested component grouping = "
+ << method_names[componentPackageMethod]
+ << std::endl);
+
+ return 1;
+}
+
+//----------------------------------------------------------------------
+std::string cmCPackGenerator::GetComponentInstallDirNameSuffix(
+ const std::string& componentName) {
+ return componentName;
+}
+//----------------------------------------------------------------------
+std::string cmCPackGenerator::GetComponentPackageFileName(
+ const std::string& initialPackageFileName,
+ const std::string& groupOrComponentName,
+ bool isGroupName) {
+
+ /*
+ * the default behavior is to use the
+ * component [group] name as a suffix
+ */
+ 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()))
+ {
+ /* the component Group case */
+ if (isGroupName)
+ {
+ std::string groupDispVar = "CPACK_COMPONENT_GROUP_"
+ + cmSystemTools::UpperCase(groupOrComponentName) + "_DISPLAY_NAME";
+ const char* groupDispName = GetOption(groupDispVar.c_str());
+ if (groupDispName)
+ {
+ suffix = "-"+std::string(groupDispName);
+ }
+ }
+ /* the [single] component case */
+ else
+ {
+ std::string dispVar = "CPACK_COMPONENT_"
+ + cmSystemTools::UpperCase(groupOrComponentName) + "_DISPLAY_NAME";
+ const char* dispName = GetOption(dispVar.c_str());
+ if(dispName)
+ {
+ suffix = "-"+std::string(dispName);
+ }
+ }
+ }
+ return initialPackageFileName + suffix;
+}
+
+//----------------------------------------------------------------------
+enum cmCPackGenerator::CPackSetDestdirSupport
+cmCPackGenerator::SupportsSetDestdir() const
+{
+ return cmCPackGenerator::SETDESTDIR_SUPPORTED;
+}
+
+//----------------------------------------------------------------------
+bool cmCPackGenerator::SupportsAbsoluteDestination() const
+{
+ return true;
+}
+
+//----------------------------------------------------------------------
+bool cmCPackGenerator::SupportsComponentInstallation() const
+{
+ return false;
+}
+
+//----------------------------------------------------------------------
+bool cmCPackGenerator::WantsComponentInstallation() const
+{
+ return (!IsOn("CPACK_MONOLITHIC_INSTALL") & SupportsComponentInstallation());
+}
+
+//----------------------------------------------------------------------
+cmCPackInstallationType*
+cmCPackGenerator::GetInstallationType(const char *projectName,
+ const char *name)
+{
+ (void) projectName;
+ bool hasInstallationType = this->InstallationTypes.count(name) != 0;
+ cmCPackInstallationType *installType = &this->InstallationTypes[name];
+ if (!hasInstallationType)
+ {
+ // Define the installation type
+ std::string macroPrefix = "CPACK_INSTALL_TYPE_"
+ + cmsys::SystemTools::UpperCase(name);
+ installType->Name = name;
+
+ const char* displayName
+ = this->GetOption((macroPrefix + "_DISPLAY_NAME").c_str());
+ if (displayName && *displayName)
+ {
+ installType->DisplayName = displayName;
+ }
+ else
+ {
+ installType->DisplayName = installType->Name;
+ }
+
+ installType->Index = static_cast<unsigned>(
+ this->InstallationTypes.size());
+ }
+ return installType;
+}
+
+//----------------------------------------------------------------------
+cmCPackComponent*
+cmCPackGenerator::GetComponent(const char *projectName, const char *name)
+{
+ bool hasComponent = this->Components.count(name) != 0;
+ cmCPackComponent *component = &this->Components[name];
+ if (!hasComponent)
+ {
+ // Define the component
+ std::string macroPrefix = "CPACK_COMPONENT_"
+ + cmsys::SystemTools::UpperCase(name);
+ component->Name = name;
+ const char* displayName
+ = this->GetOption((macroPrefix + "_DISPLAY_NAME").c_str());
+ if (displayName && *displayName)
+ {
+ component->DisplayName = displayName;
+ }
+ else
+ {
+ component->DisplayName = component->Name;
+ }
+ component->IsHidden
+ = this->IsSet((macroPrefix + "_HIDDEN").c_str());
+ component->IsRequired
+ = this->IsSet((macroPrefix + "_REQUIRED").c_str());
+ component->IsDisabledByDefault
+ = this->IsSet((macroPrefix + "_DISABLED").c_str());
+ component->IsDownloaded
+ = this->IsSet((macroPrefix + "_DOWNLOADED").c_str())
+ || cmSystemTools::IsOn(this->GetOption("CPACK_DOWNLOAD_ALL"));
+
+ const char* archiveFile = this->GetOption((macroPrefix +
+ "_ARCHIVE_FILE").c_str());
+ if (archiveFile && *archiveFile)
+ {
+ component->ArchiveFile = archiveFile;
+ }
+
+ const char* groupName = this->GetOption((macroPrefix + "_GROUP").c_str());
+ if (groupName && *groupName)
+ {
+ component->Group = GetComponentGroup(projectName, groupName);
+ component->Group->Components.push_back(component);
+ }
+ else
+ {
+ component->Group = 0;
+ }
+
+ const char* description
+ = this->GetOption((macroPrefix + "_DESCRIPTION").c_str());
+ if (description && *description)
+ {
+ component->Description = description;
+ }
+
+ // Determine the installation types.
+ const char *installTypes
+ = this->GetOption((macroPrefix + "_INSTALL_TYPES").c_str());
+ if (installTypes && *installTypes)
+ {
+ std::vector<std::string> installTypesVector;
+ cmSystemTools::ExpandListArgument(installTypes, installTypesVector);
+ std::vector<std::string>::iterator installTypesIt;
+ for (installTypesIt = installTypesVector.begin();
+ installTypesIt != installTypesVector.end();
+ ++installTypesIt)
+ {
+ component->InstallationTypes.push_back(
+ this->GetInstallationType(projectName, installTypesIt->c_str()));
+ }
+ }
+
+ // Determine the component dependencies.
+ const char *depends = this->GetOption((macroPrefix + "_DEPENDS").c_str());
+ if (depends && *depends)
+ {
+ std::vector<std::string> dependsVector;
+ cmSystemTools::ExpandListArgument(depends, dependsVector);
+ std::vector<std::string>::iterator dependIt;
+ for (dependIt = dependsVector.begin();
+ dependIt != dependsVector.end();
+ ++dependIt)
+ {
+ cmCPackComponent *child = GetComponent(projectName,
+ dependIt->c_str());
+ component->Dependencies.push_back(child);
+ child->ReverseDependencies.push_back(component);
+ }
+ }
+ }
+ return component;
+}
+
+//----------------------------------------------------------------------
+cmCPackComponentGroup*
+cmCPackGenerator::GetComponentGroup(const char *projectName, const char *name)
+{
+ (void) projectName;
+ std::string macroPrefix = "CPACK_COMPONENT_GROUP_"
+ + cmsys::SystemTools::UpperCase(name);
+ bool hasGroup = this->ComponentGroups.count(name) != 0;
+ cmCPackComponentGroup *group = &this->ComponentGroups[name];
+ if (!hasGroup)
+ {
+ // Define the group
+ group->Name = name;
+ const char* displayName
+ = this->GetOption((macroPrefix + "_DISPLAY_NAME").c_str());
+ if (displayName && *displayName)
+ {
+ group->DisplayName = displayName;
+ }
+ else
+ {
+ group->DisplayName = group->Name;
+ }
+
+ const char* description
+ = this->GetOption((macroPrefix + "_DESCRIPTION").c_str());
+ if (description && *description)
+ {
+ group->Description = description;
+ }
+ group->IsBold
+ = this->IsSet((macroPrefix + "_BOLD_TITLE").c_str());
+ group->IsExpandedByDefault
+ = this->IsSet((macroPrefix + "_EXPANDED").c_str());
+ const char* parentGroupName
+ = this->GetOption((macroPrefix + "_PARENT_GROUP").c_str());
+ if (parentGroupName && *parentGroupName)
+ {
+ group->ParentGroup = GetComponentGroup(projectName, parentGroupName);
+ group->ParentGroup->Subgroups.push_back(group);
+ }
+ else
+ {
+ group->ParentGroup = 0;
+ }
+ }
+ return group;
+}
diff --git a/Source/CPack/cmCPackGenerator.h b/Source/CPack/cmCPackGenerator.h
new file mode 100644
index 000000000..6748512d2
--- /dev/null
+++ b/Source/CPack/cmCPackGenerator.h
@@ -0,0 +1,329 @@
+/*============================================================================
+ 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 cmCPackGenerator_h
+#define cmCPackGenerator_h
+
+#include "cmObject.h"
+#include "cmSystemTools.h"
+#include <map>
+#include <vector>
+
+#include "cmCPackComponentGroup.h" // cmCPackComponent and friends
+ // 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 cmCPackLogger(logType, msg) \
+ do { \
+ cmOStringStream cmCPackLog_msg; \
+ cmCPackLog_msg << msg; \
+ this->Logger->Log(logType, __FILE__, __LINE__,\
+ cmCPackLog_msg.str().c_str());\
+ } while ( 0 )
+
+#ifdef cerr
+# undef cerr
+#endif
+#define cerr no_cerr_use_cmCPack_Log
+
+#ifdef cout
+# undef cout
+#endif
+#define cout no_cout_use_cmCPack_Log
+
+class cmMakefile;
+class cmCPackLog;
+
+/** \class cmCPackGenerator
+ * \brief A superclass of all CPack Generators
+ *
+ */
+class cmCPackGenerator : public cmObject
+{
+public:
+ cmTypeMacro(cmCPackGenerator, cmObject);
+ /**
+ * If verbose then more information is printed out
+ */
+ void SetVerbose(bool val)
+ { this->GeneratorVerbose = val ?
+ cmSystemTools::OUTPUT_MERGE : cmSystemTools::OUTPUT_NONE; }
+
+ /**
+ * Returns true if the generator may work on this system.
+ * Rational:
+ * Some CPack generator may run on some host and may not on others
+ * (with the same system) because some tools are missing. If the tool
+ * is missing then CPack won't activate (in the CPackGeneratorFactory)
+ * this particular generator.
+ */
+ static bool CanGenerate() { return true; }
+
+ /**
+ * Do the actual whole package processing.
+ * Subclass may redefine it but its usually enough
+ * to redefine @ref PackageFiles, because in fact
+ * this method do call:
+ * - PrepareName
+ * - clean-up temp dirs
+ * - InstallProject (with the appropriate method)
+ * - prepare list of files and/or components to be package
+ * - PackageFiles
+ * - Copy produced packages at the expected place
+ * @return 0 if error.
+ */
+ virtual int DoPackage();
+
+ /**
+ * Initialize generator
+ */
+ int Initialize(const char* name, cmMakefile* mf);
+
+ /**
+ * Construct generator
+ */
+ cmCPackGenerator();
+ 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();
+
+ //! Set the logger
+ void SetLogger(cmCPackLog* log) { this->Logger = log; }
+
+ //! Display verbose information via logger
+ void DisplayVerboseOutput(const char* msg, float progress);
+
+ bool ReadListFile(const char* moduleName);
+
+protected:
+ /**
+ * Prepare common used names by inspecting
+ * several CPACK_xxx var values.
+ */
+ int PrepareNames();
+
+ /**
+ * Install the project using appropriate method.
+ */
+ int InstallProject();
+
+ int CleanTemporaryDirectory();
+
+ virtual const char* GetOutputExtension() { return ".cpack"; }
+ virtual const char* GetOutputPostfix() { return 0; }
+
+ /**
+ * Prepare requested grouping kind from CPACK_xxx vars
+ * CPACK_COMPONENTS_ALL_IN_ONE_PACKAGE
+ * CPACK_COMPONENTS_IGNORE_GROUPS
+ * or
+ * CPACK_COMPONENTS_ONE_PACKAGE_PER_GROUP
+ * @return 1 on success 0 on failure.
+ */
+ virtual int PrepareGroupingKind();
+
+ /**
+ * Some CPack generators may prefer to have
+ * CPack install all components belonging to the same
+ * [component] group to be install in the same directory.
+ * The default behavior is to install each component in
+ * a separate directory.
+ * @param[in] componentName the name of the component to be installed
+ * @return the name suffix the generator wants for the specified component
+ * default is "componentName"
+ */
+ virtual std::string GetComponentInstallDirNameSuffix(
+ const std::string& componentName);
+
+ /**
+ * 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
+ */
+ virtual std::string GetComponentPackageFileName(
+ const std::string& initialPackageFileName,
+ const std::string& groupOrComponentName,
+ bool isGroupName);
+
+ /**
+ * 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 list of file @ref files has been populated
+ * @pre packageFileNames contains at least 1 entry
+ * @post packageFileNames may have been updated and contains
+ * the list of packages generated by the specific generator.
+ */
+ virtual int PackageFiles();
+ virtual const char* GetInstallPath();
+ virtual const char* GetPackagingInstallPrefix();
+
+ virtual std::string FindTemplate(const char* name);
+ virtual bool ConfigureFile(const char* inName, const char* outName,
+ bool copyOnly = false);
+ virtual bool ConfigureString(const std::string& input, std::string& output);
+ virtual int InitializeInternal();
+
+
+ //! Run install commands if specified
+ virtual int InstallProjectViaInstallCommands(
+ bool setDestDir, const char* tempInstallDirectory);
+ virtual int InstallProjectViaInstallScript(
+ bool setDestDir, const char* tempInstallDirectory);
+ virtual int InstallProjectViaInstalledDirectories(
+ bool setDestDir, const char* tempInstallDirectory);
+ virtual int InstallProjectViaInstallCMakeProjects(
+ bool setDestDir, const char* tempInstallDirectory);
+
+ /**
+ * The various level of support of
+ * CPACK_SET_DESTDIR used by the generator.
+ */
+ enum CPackSetDestdirSupport {
+ /* the generator works with or without it */
+ SETDESTDIR_SUPPORTED,
+ /* the generator works best if automatically handled */
+ SETDESTDIR_INTERNALLY_SUPPORTED,
+ /* no official support, use at your own risk */
+ SETDESTDIR_SHOULD_NOT_BE_USED,
+ /* officially NOT supported */
+ SETDESTDIR_UNSUPPORTED
+ };
+
+ /**
+ * Does the CPack generator support CPACK_SET_DESTDIR?
+ * The default legacy value is 'SETDESTDIR_SUPPORTED' generator
+ * have to override it in order change this.
+ * @return CPackSetDestdirSupport
+ */
+ virtual enum CPackSetDestdirSupport SupportsSetDestdir() const;
+
+ /**
+ * Does the CPack generator support absolute path
+ * in INSTALL DESTINATION?
+ * The default legacy value is 'true' generator
+ * have to override it in order change this.
+ * @return true if supported false otherwise
+ */
+ virtual bool SupportsAbsoluteDestination() const;
+
+ /**
+ * Does the CPack generator support component installation?.
+ * Some Generators requires the user to set
+ * CPACK_<GENNAME>_COMPONENT_INSTALL in order to make this
+ * method return true.
+ * @return true if supported, false otherwise
+ */
+ virtual bool SupportsComponentInstallation() const;
+ /**
+ * Does the currently running generator want a component installation.
+ * The generator may support component installation but he may
+ * be requiring monolithic install using CPACK_MONOLITHIC_INSTALL.
+ * @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);
+
+ cmSystemTools::OutputOption GeneratorVerbose;
+ std::string Name;
+
+ std::string InstallPath;
+
+ /**
+ * The list of package file names.
+ * At beginning of DoPackage the (generic) generator will populate
+ * the list of desired package file names then it will
+ * call the redefined method PackageFiles which is may
+ * either use this set of names (usually on entry there should be
+ * only a single name) or update the vector with the list
+ * of created package file names.
+ */
+ std::vector<std::string> packageFileNames;
+
+ /**
+ * The directory where all the files to be packaged reside.
+ * If the installer support components there will be one
+ * sub-directory for each component. In those directories
+ * one will find the file belonging to the specified component.
+ */
+ std::string toplevel;
+
+ /**
+ * The complete list of files to be packaged.
+ * This list will be populated by DoPackage before
+ * PackageFiles is called.
+ */
+ std::vector<std::string> files;
+
+ std::string CPackSelf;
+ std::string CMakeSelf;
+ std::string CMakeRoot;
+
+ std::map<std::string, cmCPackInstallationType> InstallationTypes;
+ /**
+ * The set of components.
+ * If component installation is supported then this map
+ * contains the component specified in CPACK_COMPONENTS_ALL
+ */
+ std::map<std::string, cmCPackComponent> Components;
+ std::map<std::string, cmCPackComponentGroup> ComponentGroups;
+
+ /**
+ * If components are enabled, this enum represents the different
+ * ways of mapping components to package files.
+ */
+ enum ComponentPackageMethod
+ {
+ /* one package for all components */
+ ONE_PACKAGE,
+ /* one package for each component */
+ ONE_PACKAGE_PER_COMPONENT,
+ /* one package for each group,
+ * with left over components in their own package */
+ ONE_PACKAGE_PER_GROUP,
+ UNKNOWN_COMPONENT_PACKAGE_METHOD
+ };
+
+ /**
+ * The component package method
+ * The default is ONE_PACKAGE_PER_GROUP,
+ * and generators may override the default
+ * before PrepareGroupingKind() is called.
+ */
+ ComponentPackageMethod componentPackageMethod;
+
+ cmCPackLog* Logger;
+private:
+ cmMakefile* MakefileMap;
+};
+
+#endif
diff --git a/Source/CPack/cmCPackGeneratorFactory.cxx b/Source/CPack/cmCPackGeneratorFactory.cxx
new file mode 100644
index 000000000..37ff46041
--- /dev/null
+++ b/Source/CPack/cmCPackGeneratorFactory.cxx
@@ -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.
+============================================================================*/
+
+#include "cmCPackGeneratorFactory.h"
+
+#include "cmCPackGenerator.h"
+#include "cmCPackTGZGenerator.h"
+#include "cmCPackTarBZip2Generator.h"
+#include "cmCPackTarCompressGenerator.h"
+#include "cmCPackZIPGenerator.h"
+#include "cmCPackSTGZGenerator.h"
+#include "cmCPackNSISGenerator.h"
+#ifdef __APPLE__
+# include "cmCPackDragNDropGenerator.h"
+# include "cmCPackBundleGenerator.h"
+# include "cmCPackPackageMakerGenerator.h"
+# include "cmCPackOSXX11Generator.h"
+#endif
+
+#ifdef __CYGWIN__
+# include "cmCPackCygwinBinaryGenerator.h"
+# include "cmCPackCygwinSourceGenerator.h"
+#endif
+
+#if !defined(_WIN32) \
+ && !defined(__QNXNTO__) && !defined(__BEOS__)
+# include "cmCPackDebGenerator.h"
+# include "cmCPackRPMGenerator.h"
+#endif
+
+
+#include "cmCPackLog.h"
+
+#if defined(__BORLANDC__)
+# pragma warn -8008 /* condition is always true */
+#endif
+
+//----------------------------------------------------------------------
+cmCPackGeneratorFactory::cmCPackGeneratorFactory()
+{
+ if (cmCPackTGZGenerator::CanGenerate())
+ {
+ this->RegisterGenerator("TGZ", "Tar GZip compression",
+ cmCPackTGZGenerator::CreateGenerator);
+ }
+ if (cmCPackSTGZGenerator::CanGenerate())
+ {
+ this->RegisterGenerator("STGZ", "Self extracting Tar GZip compression",
+ cmCPackSTGZGenerator::CreateGenerator);
+ }
+ if (cmCPackNSISGenerator::CanGenerate())
+ {
+ this->RegisterGenerator("NSIS", "Null Soft Installer",
+ cmCPackNSISGenerator::CreateGenerator);
+ }
+#ifdef __CYGWIN__
+ if (cmCPackCygwinBinaryGenerator::CanGenerate())
+ {
+ this->RegisterGenerator("CygwinBinary", "Cygwin Binary Installer",
+ cmCPackCygwinBinaryGenerator::CreateGenerator);
+ }
+ if (cmCPackCygwinSourceGenerator::CanGenerate())
+ {
+ this->RegisterGenerator("CygwinSource", "Cygwin Source Installer",
+ cmCPackCygwinSourceGenerator::CreateGenerator);
+ }
+#endif
+
+ if (cmCPackZIPGenerator::CanGenerate())
+ {
+ this->RegisterGenerator("ZIP", "ZIP file format",
+ cmCPackZIPGenerator::CreateGenerator);
+ }
+ if (cmCPackTarBZip2Generator::CanGenerate())
+ {
+ this->RegisterGenerator("TBZ2", "Tar BZip2 compression",
+ cmCPackTarBZip2Generator::CreateGenerator);
+ }
+ if (cmCPackTarCompressGenerator::CanGenerate())
+ {
+ this->RegisterGenerator("TZ", "Tar Compress compression",
+ cmCPackTarCompressGenerator::CreateGenerator);
+ }
+#ifdef __APPLE__
+ if (cmCPackDragNDropGenerator::CanGenerate())
+ {
+ this->RegisterGenerator("DragNDrop", "Mac OSX Drag And Drop",
+ cmCPackDragNDropGenerator::CreateGenerator);
+ }
+ if (cmCPackBundleGenerator::CanGenerate())
+ {
+ this->RegisterGenerator("Bundle", "Mac OSX bundle",
+ cmCPackBundleGenerator::CreateGenerator);
+ }
+ if (cmCPackPackageMakerGenerator::CanGenerate())
+ {
+ this->RegisterGenerator("PackageMaker", "Mac OSX Package Maker installer",
+ cmCPackPackageMakerGenerator::CreateGenerator);
+ }
+ if (cmCPackOSXX11Generator::CanGenerate())
+ {
+ this->RegisterGenerator("OSXX11", "Mac OSX X11 bundle",
+ cmCPackOSXX11Generator::CreateGenerator);
+ }
+#endif
+#if !defined(_WIN32) \
+ && !defined(__QNXNTO__) && !defined(__BEOS__)
+ if (cmCPackDebGenerator::CanGenerate())
+ {
+ this->RegisterGenerator("DEB", "Debian packages",
+ cmCPackDebGenerator::CreateGenerator);
+ }
+ if (cmCPackRPMGenerator::CanGenerate())
+ {
+ this->RegisterGenerator("RPM", "RPM packages",
+ cmCPackRPMGenerator::CreateGenerator);
+ }
+#endif
+}
+
+//----------------------------------------------------------------------
+cmCPackGeneratorFactory::~cmCPackGeneratorFactory()
+{
+ std::vector<cmCPackGenerator*>::iterator it;
+ for ( it = this->Generators.begin(); it != this->Generators.end(); ++ it )
+ {
+ delete *it;
+ }
+}
+
+//----------------------------------------------------------------------
+cmCPackGenerator* cmCPackGeneratorFactory::NewGenerator(const char* name)
+{
+ cmCPackGenerator* gen = this->NewGeneratorInternal(name);
+ if ( !gen )
+ {
+ return 0;
+ }
+ this->Generators.push_back(gen);
+ gen->SetLogger(this->Logger);
+ return gen;
+}
+
+//----------------------------------------------------------------------
+cmCPackGenerator* cmCPackGeneratorFactory::NewGeneratorInternal(
+ const char* name)
+{
+ if ( !name )
+ {
+ return 0;
+ }
+ cmCPackGeneratorFactory::t_GeneratorCreatorsMap::iterator it
+ = this->GeneratorCreators.find(name);
+ if ( it == this->GeneratorCreators.end() )
+ {
+ return 0;
+ }
+ return (it->second)();
+}
+
+//----------------------------------------------------------------------
+void cmCPackGeneratorFactory::RegisterGenerator(const char* name,
+ const char* generatorDescription,
+ CreateGeneratorCall* createGenerator)
+{
+ if ( !name || !createGenerator )
+ {
+ cmCPack_Log(this->Logger, cmCPackLog::LOG_ERROR,
+ "Cannot register generator" << std::endl);
+ return;
+ }
+ this->GeneratorCreators[name] = createGenerator;
+ this->GeneratorDescriptions[name] = generatorDescription;
+}
diff --git a/Source/CPack/cmCPackGeneratorFactory.h b/Source/CPack/cmCPackGeneratorFactory.h
new file mode 100644
index 000000000..dff2e49eb
--- /dev/null
+++ b/Source/CPack/cmCPackGeneratorFactory.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 cmCPackGeneratorFactory_h
+#define cmCPackGeneratorFactory_h
+
+#include "cmObject.h"
+
+class cmCPackLog;
+class cmCPackGenerator;
+
+/** \class cmCPackGeneratorFactory
+ * \brief A container for CPack generators
+ *
+ */
+class cmCPackGeneratorFactory : public cmObject
+{
+public:
+ cmTypeMacro(cmCPackGeneratorFactory, cmObject);
+
+ cmCPackGeneratorFactory();
+ ~cmCPackGeneratorFactory();
+
+ //! Get the generator
+ cmCPackGenerator* NewGenerator(const char* name);
+ void DeleteGenerator(cmCPackGenerator* gen);
+
+ typedef cmCPackGenerator* CreateGeneratorCall();
+
+ void RegisterGenerator(const char* name,
+ const char* generatorDescription,
+ CreateGeneratorCall* createGenerator);
+
+ void SetLogger(cmCPackLog* logger) { this->Logger = logger; }
+
+ typedef std::map<cmStdString, cmStdString> DescriptionsMap;
+ const DescriptionsMap& GetGeneratorsList() const
+ { return this->GeneratorDescriptions; }
+
+private:
+ cmCPackGenerator* NewGeneratorInternal(const char* name);
+ std::vector<cmCPackGenerator*> Generators;
+
+ typedef std::map<cmStdString, CreateGeneratorCall*> t_GeneratorCreatorsMap;
+ t_GeneratorCreatorsMap GeneratorCreators;
+ DescriptionsMap GeneratorDescriptions;
+ cmCPackLog* Logger;
+};
+
+#endif
diff --git a/Source/CPack/cmCPackLog.cxx b/Source/CPack/cmCPackLog.cxx
new file mode 100644
index 000000000..4e8bf0f4e
--- /dev/null
+++ b/Source/CPack/cmCPackLog.cxx
@@ -0,0 +1,225 @@
+/*============================================================================
+ 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 "cmCPackLog.h"
+
+#include "cmGeneratedFileStream.h"
+#include "cmSystemTools.h"
+
+//----------------------------------------------------------------------
+cmCPackLog::cmCPackLog()
+{
+ this->Verbose = false;
+ this->Debug = false;
+ this->Quiet = false;
+ this->NewLine = true;
+
+ this->LastTag = cmCPackLog::NOTAG;
+#undef cerr
+#undef cout
+ this->DefaultOutput = &std::cout;
+ this->DefaultError = &std::cerr;
+
+ this->LogOutput = 0;
+ this->LogOutputCleanup = false;
+}
+
+//----------------------------------------------------------------------
+cmCPackLog::~cmCPackLog()
+{
+ this->SetLogOutputStream(0);
+}
+
+//----------------------------------------------------------------------
+void cmCPackLog::SetLogOutputStream(std::ostream* os)
+{
+ if ( this->LogOutputCleanup && this->LogOutput )
+ {
+ delete this->LogOutput;
+ }
+ this->LogOutputCleanup = false;
+ this->LogOutput = os;
+}
+
+//----------------------------------------------------------------------
+bool cmCPackLog::SetLogOutputFile(const char* fname)
+{
+ cmGeneratedFileStream *cg = 0;
+ if ( fname )
+ {
+ cg = new cmGeneratedFileStream(fname);
+ }
+ if ( cg && !*cg )
+ {
+ delete cg;
+ cg = 0;
+ }
+ this->SetLogOutputStream(cg);
+ if ( !cg )
+ {
+ return false;
+ }
+ this->LogOutputCleanup = true;
+ return true;
+}
+
+//----------------------------------------------------------------------
+void cmCPackLog::Log(int tag, const char* file, int line,
+ const char* msg, size_t length)
+{
+ // By default no logging
+ bool display = false;
+
+ // Display file and line number if debug
+ bool useFileAndLine = this->Debug;
+
+ bool output = false;
+ bool debug = false;
+ bool warning = false;
+ bool error = false;
+ bool verbose = false;
+
+ // When writing in file, add list of tags whenever tag changes.
+ std::string tagString;
+ bool needTagString = false;
+ if ( this->LogOutput && this->LastTag != tag )
+ {
+ needTagString = true;
+ }
+
+ if ( tag & LOG_OUTPUT )
+ {
+ output = true;
+ display = true;
+ if ( needTagString )
+ {
+ if ( tagString.size() > 0 ) { tagString += ","; }
+ tagString = "VERBOSE";
+ }
+ }
+ if ( tag & LOG_WARNING )
+ {
+ warning = true;
+ display = true;
+ if ( needTagString )
+ {
+ if ( tagString.size() > 0 ) { tagString += ","; }
+ tagString = "WARNING";
+ }
+ }
+ if ( tag & LOG_ERROR )
+ {
+ error = true;
+ display = true;
+ if ( needTagString )
+ {
+ if ( tagString.size() > 0 ) { tagString += ","; }
+ tagString = "ERROR";
+ }
+ }
+ if ( tag & LOG_DEBUG && this->Debug )
+ {
+ debug = true;
+ display = true;
+ if ( needTagString )
+ {
+ if ( tagString.size() > 0 ) { tagString += ","; }
+ tagString = "DEBUG";
+ }
+ useFileAndLine = true;
+ }
+ if ( tag & LOG_VERBOSE && this->Verbose )
+ {
+ verbose = true;
+ display = true;
+ if ( needTagString )
+ {
+ if ( tagString.size() > 0 ) { tagString += ","; }
+ tagString = "VERBOSE";
+ }
+ }
+ if ( this->Quiet )
+ {
+ display = false;
+ }
+ if ( this->LogOutput )
+ {
+ if ( needTagString )
+ {
+ *this->LogOutput << "[" << file << ":" << line << " "
+ << tagString << "] ";
+ }
+ this->LogOutput->write(msg, length);
+ }
+ this->LastTag = tag;
+ if ( !display )
+ {
+ return;
+ }
+ if ( this->NewLine )
+ {
+ if ( error && !this->ErrorPrefix.empty() )
+ {
+ *this->DefaultError << this->ErrorPrefix.c_str();
+ }
+ else if ( warning && !this->WarningPrefix.empty() )
+ {
+ *this->DefaultError << this->WarningPrefix.c_str();
+ }
+ else if ( output && !this->OutputPrefix.empty() )
+ {
+ *this->DefaultOutput << this->OutputPrefix.c_str();
+ }
+ else if ( verbose && !this->VerbosePrefix.empty() )
+ {
+ *this->DefaultOutput << this->VerbosePrefix.c_str();
+ }
+ else if ( debug && !this->DebugPrefix.empty() )
+ {
+ *this->DefaultOutput << this->DebugPrefix.c_str();
+ }
+ else if ( !this->Prefix.empty() )
+ {
+ *this->DefaultOutput << this->Prefix.c_str();
+ }
+ if ( useFileAndLine )
+ {
+ if ( error || warning )
+ {
+ *this->DefaultError << file << ":" << line << " ";
+ }
+ else
+ {
+ *this->DefaultOutput << file << ":" << line << " ";
+ }
+ }
+ }
+ if ( error || warning )
+ {
+ this->DefaultError->write(msg, length);
+ this->DefaultError->flush();
+ }
+ else
+ {
+ this->DefaultOutput->write(msg, length);
+ this->DefaultOutput->flush();
+ }
+ if ( msg[length-1] == '\n' || length > 2 )
+ {
+ this->NewLine = true;
+ }
+
+ if ( error )
+ {
+ cmSystemTools::SetErrorOccured();
+ }
+}
diff --git a/Source/CPack/cmCPackLog.h b/Source/CPack/cmCPackLog.h
new file mode 100644
index 000000000..812f1de27
--- /dev/null
+++ b/Source/CPack/cmCPackLog.h
@@ -0,0 +1,155 @@
+/*============================================================================
+ 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 cmCPackLog_h
+#define cmCPackLog_h
+
+#include "cmObject.h"
+
+#define cmCPack_Log(ctSelf, logType, msg) \
+ do { \
+ cmOStringStream cmCPackLog_msg; \
+ cmCPackLog_msg << msg; \
+ (ctSelf)->Log(logType, __FILE__, __LINE__, cmCPackLog_msg.str().c_str());\
+ } while ( 0 )
+
+#ifdef cerr
+# undef cerr
+#endif
+#define cerr no_cerr_use_cmCPack_Log
+
+#ifdef cout
+# undef cout
+#endif
+#define cout no_cout_use_cmCPack_Log
+
+
+/** \class cmCPackLog
+ * \brief A container for CPack generators
+ *
+ */
+class cmCPackLog : public cmObject
+{
+public:
+ cmTypeMacro(cmCPackLog, cmObject);
+
+ cmCPackLog();
+ ~cmCPackLog();
+
+ enum __log_tags {
+ NOTAG = 0,
+ LOG_OUTPUT = 0x1,
+ LOG_VERBOSE = 0x2,
+ LOG_DEBUG = 0x4,
+ LOG_WARNING = 0x8,
+ LOG_ERROR = 0x10
+ };
+
+ //! Various signatures for logging.
+ void Log(const char* file, int line, const char* msg)
+ {
+ this->Log(LOG_OUTPUT, file, line, msg);
+ }
+ void Log(const char* file, int line, const char* msg, size_t length)
+ {
+ this->Log(LOG_OUTPUT, file, line, msg, length);
+ }
+ void Log(int tag, const char* file, int line, const char* msg)
+ {
+ this->Log(tag, file, line, msg, strlen(msg));
+ }
+ void Log(int tag, const char* file, int line, const char* msg,
+ size_t length);
+
+ //! Set Verbose
+ void VerboseOn() { this->SetVerbose(true); }
+ void VerboseOff() { this->SetVerbose(true); }
+ void SetVerbose(bool verb) { this->Verbose = verb; }
+ bool GetVerbose() { return this->Verbose; }
+
+ //! Set Debug
+ void DebugOn() { this->SetDebug(true); }
+ void DebugOff() { this->SetDebug(true); }
+ void SetDebug(bool verb) { this->Debug = verb; }
+ bool GetDebug() { return this->Debug; }
+
+ //! Set Quiet
+ void QuietOn() { this->SetQuiet(true); }
+ void QuietOff() { this->SetQuiet(true); }
+ void SetQuiet(bool verb) { this->Quiet = verb; }
+ bool GetQuiet() { return this->Quiet; }
+
+ //! Set the output stream
+ void SetOutputStream(std::ostream* os) { this->DefaultOutput = os; }
+
+ //! Set the error stream
+ void SetErrorStream(std::ostream* os) { this->DefaultError = os; }
+
+ //! Set the log output stream
+ void SetLogOutputStream(std::ostream* os);
+
+ //! Set the log output file. The cmCPackLog will try to create file. If it
+ // cannot, it will report an error.
+ bool SetLogOutputFile(const char* fname);
+
+ //! Set the various prefixes for the logging. SetPrefix sets the generic
+ // prefix that overwrittes missing ones.
+ void SetPrefix(std::string pfx) { this->Prefix = pfx; }
+ void SetOutputPrefix(std::string pfx) { this->OutputPrefix = pfx; }
+ void SetVerbosePrefix(std::string pfx) { this->VerbosePrefix = pfx; }
+ void SetDebugPrefix(std::string pfx) { this->DebugPrefix = pfx; }
+ void SetWarningPrefix(std::string pfx) { this->WarningPrefix = pfx; }
+ void SetErrorPrefix(std::string pfx) { this->ErrorPrefix = pfx; }
+
+private:
+ bool Verbose;
+ bool Debug;
+ bool Quiet;
+
+ bool NewLine;
+
+ int LastTag;
+
+ std::string Prefix;
+ std::string OutputPrefix;
+ std::string VerbosePrefix;
+ std::string DebugPrefix;
+ std::string WarningPrefix;
+ std::string ErrorPrefix;
+
+ std::ostream *DefaultOutput;
+ std::ostream *DefaultError;
+
+ std::string LogOutputFileName;
+ std::ostream *LogOutput;
+ // Do we need to cleanup log output stream
+ bool LogOutputCleanup;
+};
+
+class cmCPackLogWrite
+{
+public:
+ cmCPackLogWrite(const char* data, size_t length)
+ : Data(data), Length(length) {}
+
+ const char* Data;
+ size_t Length;
+};
+
+inline std::ostream& operator<< (std::ostream& os, const cmCPackLogWrite& c)
+{
+ os.write(c.Data, c.Length);
+ os.flush();
+ return os;
+}
+
+#endif
diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx
new file mode 100644
index 000000000..7b5251148
--- /dev/null
+++ b/Source/CPack/cmCPackNSISGenerator.cxx
@@ -0,0 +1,1004 @@
+/*============================================================================
+ 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 "cmCPackNSISGenerator.h"
+
+#include "cmGlobalGenerator.h"
+#include "cmLocalGenerator.h"
+#include "cmSystemTools.h"
+#include "cmMakefile.h"
+#include "cmGeneratedFileStream.h"
+#include "cmCPackLog.h"
+#include "cmCPackComponentGroup.h"
+
+#include <cmsys/SystemTools.hxx>
+#include <cmsys/Glob.hxx>
+#include <cmsys/Directory.hxx>
+#include <cmsys/RegularExpression.hxx>
+
+/* NSIS uses different command line syntax on Windows and others */
+#ifdef _WIN32
+# define NSIS_OPT "/"
+#else
+# define NSIS_OPT "-"
+#endif
+
+//----------------------------------------------------------------------
+cmCPackNSISGenerator::cmCPackNSISGenerator()
+{
+}
+
+//----------------------------------------------------------------------
+cmCPackNSISGenerator::~cmCPackNSISGenerator()
+{
+}
+
+//----------------------------------------------------------------------
+int cmCPackNSISGenerator::PackageFiles()
+{
+ // TODO: Fix nsis to force out file name
+
+ std::string nsisInFileName = this->FindTemplate("NSIS.template.in");
+ if ( nsisInFileName.size() == 0 )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "CPack error: Could not find NSIS installer template file."
+ << std::endl);
+ return false;
+ }
+ std::string nsisInInstallOptions
+ = this->FindTemplate("NSIS.InstallOptions.ini.in");
+ if ( nsisInInstallOptions.size() == 0 )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "CPack error: Could not find NSIS installer options file."
+ << std::endl);
+ return false;
+ }
+
+ std::string nsisFileName = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
+ std::string tmpFile = nsisFileName;
+ tmpFile += "/NSISOutput.log";
+ std::string nsisInstallOptions = nsisFileName + "/NSIS.InstallOptions.ini";
+ nsisFileName += "/project.nsi";
+ cmOStringStream str;
+ std::vector<std::string>::const_iterator it;
+ for ( it = files.begin(); it != files.end(); ++ it )
+ {
+ std::string fileN = cmSystemTools::RelativePath(toplevel.c_str(),
+ it->c_str());
+ if (!this->Components.empty())
+ {
+ // Strip off the component part of the path.
+ fileN = fileN.substr(fileN.find('/')+1, std::string::npos);
+ }
+ cmSystemTools::ReplaceString(fileN, "/", "\\");
+ str << " Delete \"$INSTDIR\\" << fileN.c_str() << "\"" << std::endl;
+ }
+ cmCPackLogger(cmCPackLog::LOG_DEBUG, "Uninstall Files: "
+ << str.str().c_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;
+ for ( sit = dirs.begin(); sit != dirs.end(); ++ sit )
+ {
+ std::string componentName;
+ std::string fileN = cmSystemTools::RelativePath(toplevel.c_str(),
+ sit->c_str());
+ if ( fileN.empty() )
+ {
+ continue;
+ }
+ if (!Components.empty())
+ {
+ // If this is a component installation, strip off the component
+ // part of the path.
+ std::string::size_type slash = fileN.find('/');
+ if (slash != std::string::npos)
+ {
+ // If this is a component installation, determine which component it
+ // is.
+ componentName = fileN.substr(0, slash);
+
+ // Strip off the component part of the path.
+ fileN = fileN.substr(slash+1, std::string::npos);
+ }
+ }
+ cmSystemTools::ReplaceString(fileN, "/", "\\");
+ dstr << " RMDir \"$INSTDIR\\" << fileN.c_str() << "\"" << std::endl;
+ if (!componentName.empty())
+ {
+ this->Components[componentName].Directories.push_back(fileN);
+ }
+ }
+ cmCPackLogger(cmCPackLog::LOG_DEBUG, "Uninstall Dirs: "
+ << dstr.str().c_str() << std::endl);
+ this->SetOptionIfNotSet("CPACK_NSIS_DELETE_DIRECTORIES",
+ dstr.str().c_str());
+
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Configure file: " << nsisInFileName
+ << " to " << nsisFileName << std::endl);
+ if(this->IsSet("CPACK_NSIS_MUI_ICON")
+ || this->IsSet("CPACK_NSIS_MUI_UNIICON"))
+ {
+ std::string installerIconCode;
+ if(this->IsSet("CPACK_NSIS_MUI_ICON"))
+ {
+ installerIconCode += "!define MUI_ICON \"";
+ installerIconCode += this->GetOption("CPACK_NSIS_MUI_ICON");
+ installerIconCode += "\"\n";
+ }
+ if(this->IsSet("CPACK_NSIS_MUI_UNIICON"))
+ {
+ installerIconCode += "!define MUI_UNICON \"";
+ installerIconCode += this->GetOption("CPACK_NSIS_MUI_UNIICON");
+ installerIconCode += "\"\n";
+ }
+ this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_MUI_ICON_CODE",
+ installerIconCode.c_str());
+ }
+ if(this->IsSet("CPACK_PACKAGE_ICON"))
+ {
+ std::string installerIconCode = "!define MUI_HEADERIMAGE_BITMAP \"";
+ installerIconCode += this->GetOption("CPACK_PACKAGE_ICON");
+ installerIconCode += "\"\n";
+ this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_ICON_CODE",
+ installerIconCode.c_str());
+ }
+
+ if(this->IsSet("CPACK_NSIS_MUI_FINISHPAGE_RUN"))
+ {
+ std::string installerRunCode = "!define MUI_FINISHPAGE_RUN \"$INSTDIR\\";
+ installerRunCode += this->GetOption("CPACK_NSIS_EXECUTABLES_DIRECTORY");
+ installerRunCode += "\\";
+ installerRunCode += this->GetOption("CPACK_NSIS_MUI_FINISHPAGE_RUN");
+ installerRunCode += "\"\n";
+ this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_MUI_FINISHPAGE_RUN_CODE",
+ installerRunCode.c_str());
+ }
+
+ // Setup all of the component sections
+ if (this->Components.empty())
+ {
+ this->SetOptionIfNotSet("CPACK_NSIS_INSTALLATION_TYPES", "");
+ this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_MUI_COMPONENTS_DESC", "");
+ this->SetOptionIfNotSet("CPACK_NSIS_PAGE_COMPONENTS", "");
+ this->SetOptionIfNotSet("CPACK_NSIS_FULL_INSTALL",
+ "File /r \"${INST_DIR}\\*.*\"");
+ this->SetOptionIfNotSet("CPACK_NSIS_COMPONENT_SECTIONS", "");
+ this->SetOptionIfNotSet("CPACK_NSIS_COMPONENT_SECTION_LIST", "");
+ this->SetOptionIfNotSet("CPACK_NSIS_SECTION_SELECTED_VARS", "");
+ }
+ else
+ {
+ std::string componentCode;
+ std::string sectionList;
+ std::string selectedVarsList;
+ std::string componentDescriptions;
+ std::string groupDescriptions;
+ std::string installTypesCode;
+ std::string defines;
+ cmOStringStream macrosOut;
+ bool anyDownloadedComponents = false;
+
+ // Create installation types. The order is significant, so we first fill
+ // in a vector based on the indices, and print them in that order.
+ std::vector<cmCPackInstallationType *>
+ installTypes(this->InstallationTypes.size());
+ std::map<std::string, cmCPackInstallationType>::iterator installTypeIt;
+ for (installTypeIt = this->InstallationTypes.begin();
+ installTypeIt != this->InstallationTypes.end();
+ ++installTypeIt)
+ {
+ installTypes[installTypeIt->second.Index-1] = &installTypeIt->second;
+ }
+ std::vector<cmCPackInstallationType *>::iterator installTypeIt2;
+ for (installTypeIt2 = installTypes.begin();
+ installTypeIt2 != installTypes.end();
+ ++installTypeIt2)
+ {
+ installTypesCode += "InstType \"";
+ installTypesCode += (*installTypeIt2)->DisplayName;
+ installTypesCode += "\"\n";
+ }
+
+ // Create installation groups first
+ std::map<std::string, cmCPackComponentGroup>::iterator groupIt;
+ for (groupIt = this->ComponentGroups.begin();
+ groupIt != this->ComponentGroups.end();
+ ++groupIt)
+ {
+ if (groupIt->second.ParentGroup == 0)
+ {
+ componentCode +=
+ this->CreateComponentGroupDescription(&groupIt->second, macrosOut);
+ }
+
+ // Add the group description, if any.
+ if (!groupIt->second.Description.empty())
+ {
+ groupDescriptions += " !insertmacro MUI_DESCRIPTION_TEXT ${"
+ + groupIt->first + "} \""
+ + this->TranslateNewlines(groupIt->second.Description) + "\"\n";
+ }
+ }
+
+ // Create the remaining components, which aren't associated with groups.
+ std::map<std::string, cmCPackComponent>::iterator compIt;
+ for (compIt = this->Components.begin();
+ compIt != this->Components.end();
+ ++compIt)
+ {
+ if (compIt->second.Files.empty())
+ {
+ // NSIS cannot cope with components that have no files.
+ continue;
+ }
+
+ anyDownloadedComponents =
+ anyDownloadedComponents || compIt->second.IsDownloaded;
+
+ if (!compIt->second.Group)
+ {
+ componentCode
+ += this->CreateComponentDescription(&compIt->second, macrosOut);
+ }
+
+ // Add this component to the various section lists.
+ sectionList += " !insertmacro \"${MacroName}\" \"";
+ sectionList += compIt->first;
+ sectionList += "\"\n";
+ selectedVarsList += "Var " + compIt->first + "_selected\n";
+ selectedVarsList += "Var " + compIt->first + "_was_installed\n";
+
+ // Add the component description, if any.
+ if (!compIt->second.Description.empty())
+ {
+ componentDescriptions += " !insertmacro MUI_DESCRIPTION_TEXT ${"
+ + compIt->first + "} \""
+ + this->TranslateNewlines(compIt->second.Description) + "\"\n";
+ }
+ }
+
+ componentCode += macrosOut.str();
+
+ if (componentDescriptions.empty() && groupDescriptions.empty())
+ {
+ // Turn off the "Description" box
+ this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_MUI_COMPONENTS_DESC",
+ "!define MUI_COMPONENTSPAGE_NODESC");
+ }
+ else
+ {
+ componentDescriptions =
+ "!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN\n"
+ + componentDescriptions
+ + groupDescriptions
+ + "!insertmacro MUI_FUNCTION_DESCRIPTION_END\n";
+ this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_MUI_COMPONENTS_DESC",
+ componentDescriptions.c_str());
+ }
+
+ if (anyDownloadedComponents)
+ {
+ defines += "!define CPACK_USES_DOWNLOAD\n";
+ if (cmSystemTools::IsOn(this->GetOption("CPACK_ADD_REMOVE")))
+ {
+ defines += "!define CPACK_NSIS_ADD_REMOVE\n";
+ }
+ }
+
+ this->SetOptionIfNotSet("CPACK_NSIS_INSTALLATION_TYPES",
+ installTypesCode.c_str());
+ this->SetOptionIfNotSet("CPACK_NSIS_PAGE_COMPONENTS",
+ "!insertmacro MUI_PAGE_COMPONENTS");
+ this->SetOptionIfNotSet("CPACK_NSIS_FULL_INSTALL", "");
+ this->SetOptionIfNotSet("CPACK_NSIS_COMPONENT_SECTIONS",
+ componentCode.c_str());
+ this->SetOptionIfNotSet("CPACK_NSIS_COMPONENT_SECTION_LIST",
+ sectionList.c_str());
+ this->SetOptionIfNotSet("CPACK_NSIS_SECTION_SELECTED_VARS",
+ selectedVarsList.c_str());
+ this->SetOption("CPACK_NSIS_DEFINES", defines.c_str());
+ }
+
+ this->ConfigureFile(nsisInInstallOptions.c_str(),
+ nsisInstallOptions.c_str());
+ this->ConfigureFile(nsisInFileName.c_str(), nsisFileName.c_str());
+ std::string nsisCmd = "\"";
+ nsisCmd += this->GetOption("CPACK_INSTALLER_PROGRAM");
+ nsisCmd += "\" \"" + nsisFileName + "\"";
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << nsisCmd.c_str()
+ << std::endl);
+ std::string output;
+ int retVal = 1;
+ bool res = cmSystemTools::RunSingleCommand(nsisCmd.c_str(), &output,
+ &retVal, 0, this->GeneratorVerbose, 0);
+ if ( !res || retVal )
+ {
+ cmGeneratedFileStream ofs(tmpFile.c_str());
+ ofs << "# Run command: " << nsisCmd.c_str() << std::endl
+ << "# Output:" << std::endl
+ << output.c_str() << std::endl;
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem running NSIS command: "
+ << nsisCmd.c_str() << std::endl
+ << "Please check " << tmpFile.c_str() << " for errors" << std::endl);
+ return 0;
+ }
+ return 1;
+}
+
+//----------------------------------------------------------------------
+int cmCPackNSISGenerator::InitializeInternal()
+{
+ if ( cmSystemTools::IsOn(this->GetOption(
+ "CPACK_INCLUDE_TOPLEVEL_DIRECTORY")) )
+ {
+ cmCPackLogger(cmCPackLog::LOG_WARNING,
+ "NSIS Generator cannot work with CPACK_INCLUDE_TOPLEVEL_DIRECTORY set. "
+ "This option will be reset to 0 (for this generator only)."
+ << std::endl);
+ this->SetOption("CPACK_INCLUDE_TOPLEVEL_DIRECTORY", 0);
+ }
+
+ cmCPackLogger(cmCPackLog::LOG_DEBUG, "cmCPackNSISGenerator::Initialize()"
+ << std::endl);
+ std::vector<std::string> path;
+ std::string nsisPath;
+ bool gotRegValue = true;
+
+#ifdef _WIN32
+ if ( !cmsys::SystemTools::ReadRegistryValue(
+ "HKEY_LOCAL_MACHINE\\SOFTWARE\\NSIS", nsisPath,
+ cmsys::SystemTools::KeyWOW64_32) )
+ {
+ if ( !cmsys::SystemTools::ReadRegistryValue(
+ "HKEY_LOCAL_MACHINE\\SOFTWARE\\NSIS", nsisPath) )
+ {
+ gotRegValue = false;
+ }
+ }
+
+ if (gotRegValue)
+ {
+ path.push_back(nsisPath);
+ }
+#endif
+
+ nsisPath = cmSystemTools::FindProgram("makensis", path, false);
+
+ if ( nsisPath.empty() )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Cannot find NSIS compiler makensis: likely it is not installed, "
+ "or not in your PATH"
+ << std::endl);
+
+ if (!gotRegValue)
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Could not read NSIS registry value. This is usually caused by "
+ "NSIS not being installed. Please install NSIS from "
+ "http://nsis.sourceforge.net"
+ << std::endl);
+ }
+
+ return 0;
+ }
+
+ std::string nsisCmd = "\"" + nsisPath + "\" " NSIS_OPT "VERSION";
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Test NSIS version: "
+ << nsisCmd.c_str() << std::endl);
+ std::string output;
+ int retVal = 1;
+ bool resS = cmSystemTools::RunSingleCommand(nsisCmd.c_str(),
+ &output, &retVal, 0, this->GeneratorVerbose, 0);
+
+ cmsys::RegularExpression versionRex("v([0-9]+.[0-9]+)");
+ if ( !resS || retVal || !versionRex.find(output))
+ {
+ std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
+ tmpFile += "/NSISOutput.log";
+ cmGeneratedFileStream ofs(tmpFile.c_str());
+ ofs << "# Run command: " << nsisCmd.c_str() << std::endl
+ << "# Output:" << std::endl
+ << output.c_str() << 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);
+ return 0;
+ }
+ double nsisVersion = atof(versionRex.match(1).c_str());
+ double minNSISVersion = 2.09;
+ cmCPackLogger(cmCPackLog::LOG_DEBUG, "NSIS Version: "
+ << nsisVersion << std::endl);
+ if ( nsisVersion < minNSISVersion )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "CPack requires NSIS Version 2.09 or greater. NSIS found on the system "
+ "was: "
+ << nsisVersion << std::endl);
+ return 0;
+ }
+ this->SetOptionIfNotSet("CPACK_INSTALLER_PROGRAM", nsisPath.c_str());
+ this->SetOptionIfNotSet("CPACK_NSIS_EXECUTABLES_DIRECTORY", "bin");
+ const char* cpackPackageExecutables
+ = this->GetOption("CPACK_PACKAGE_EXECUTABLES");
+ const char* cpackPackageDeskTopLinks
+ = this->GetOption("CPACK_CREATE_DESKTOP_LINKS");
+ const char* cpackNsisExecutablesDirectory
+ = this->GetOption("CPACK_NSIS_EXECUTABLES_DIRECTORY");
+ std::vector<std::string> cpackPackageDesktopLinksVector;
+ if(cpackPackageDeskTopLinks)
+ {
+ cmCPackLogger(cmCPackLog::LOG_DEBUG, "CPACK_CREATE_DESKTOP_LINKS: "
+ << cpackPackageDeskTopLinks << std::endl);
+
+ cmSystemTools::
+ ExpandListArgument(cpackPackageDeskTopLinks,
+ cpackPackageDesktopLinksVector);
+ for(std::vector<std::string>::iterator i =
+ cpackPackageDesktopLinksVector.begin(); i !=
+ cpackPackageDesktopLinksVector.end(); ++i)
+ {
+ cmCPackLogger(cmCPackLog::LOG_DEBUG, "CPACK_CREATE_DESKTOP_LINKS: "
+ << *i << std::endl);
+ }
+ }
+ else
+ {
+ cmCPackLogger(cmCPackLog::LOG_DEBUG, "CPACK_CREATE_DESKTOP_LINKS: "
+ << "not set" << std::endl);
+ }
+
+ cmOStringStream str;
+ cmOStringStream deleteStr;
+
+ if ( cpackPackageExecutables )
+ {
+ cmCPackLogger(cmCPackLog::LOG_DEBUG, "The cpackPackageExecutables: "
+ << cpackPackageExecutables << "." << std::endl);
+ std::vector<std::string> cpackPackageExecutablesVector;
+ cmSystemTools::ExpandListArgument(cpackPackageExecutables,
+ cpackPackageExecutablesVector);
+ if ( cpackPackageExecutablesVector.size() % 2 != 0 )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "CPACK_PACKAGE_EXECUTABLES should contain pairs of <executable> and "
+ "<icon name>." << std::endl);
+ return 0;
+ }
+ std::vector<std::string>::iterator it;
+ for ( it = cpackPackageExecutablesVector.begin();
+ it != cpackPackageExecutablesVector.end();
+ ++it )
+ {
+ std::string execName = *it;
+ ++ it;
+ std::string linkName = *it;
+ str << " CreateShortCut \"$SMPROGRAMS\\$STARTMENU_FOLDER\\"
+ << linkName << ".lnk\" \"$INSTDIR\\"
+ << cpackNsisExecutablesDirectory << "\\" << execName << ".exe\""
+ << std::endl;
+ deleteStr << " Delete \"$SMPROGRAMS\\$MUI_TEMP\\" << linkName
+ << ".lnk\"" << std::endl;
+ // see if CPACK_CREATE_DESKTOP_LINK_ExeName is on
+ // if so add a desktop link
+ if(cpackPackageDesktopLinksVector.size() &&
+ std::find(cpackPackageDesktopLinksVector.begin(),
+ cpackPackageDesktopLinksVector.end(),
+ execName)
+ != cpackPackageDesktopLinksVector.end())
+ {
+ str << " StrCmp \"$INSTALL_DESKTOP\" \"1\" 0 +2\n";
+ str << " CreateShortCut \"$DESKTOP\\"
+ << linkName << ".lnk\" \"$INSTDIR\\"
+ << cpackNsisExecutablesDirectory << "\\" << execName << ".exe\""
+ << std::endl;
+ deleteStr << " StrCmp \"$INSTALL_DESKTOP\" \"1\" 0 +2\n";
+ deleteStr << " Delete \"$DESKTOP\\" << linkName
+ << ".lnk\"" << std::endl;
+ }
+ }
+ }
+
+ this->CreateMenuLinks(str, deleteStr);
+ this->SetOptionIfNotSet("CPACK_NSIS_CREATE_ICONS", str.str().c_str());
+ this->SetOptionIfNotSet("CPACK_NSIS_DELETE_ICONS",
+ deleteStr.str().c_str());
+
+ this->SetOptionIfNotSet("CPACK_NSIS_COMPRESSOR", "lzma");
+
+ return this->Superclass::InitializeInternal();
+}
+
+//----------------------------------------------------------------------
+void cmCPackNSISGenerator::CreateMenuLinks( cmOStringStream& str,
+ cmOStringStream& deleteStr)
+{
+ const char* cpackMenuLinks
+ = this->GetOption("CPACK_NSIS_MENU_LINKS");
+ if(!cpackMenuLinks)
+ {
+ return;
+ }
+ cmCPackLogger(cmCPackLog::LOG_DEBUG, "The cpackMenuLinks: "
+ << cpackMenuLinks << "." << std::endl);
+ std::vector<std::string> cpackMenuLinksVector;
+ cmSystemTools::ExpandListArgument(cpackMenuLinks,
+ cpackMenuLinksVector);
+ if ( cpackMenuLinksVector.size() % 2 != 0 )
+ {
+ cmCPackLogger(
+ cmCPackLog::LOG_ERROR,
+ "CPACK_NSIS_MENU_LINKS should contain pairs of <shortcut target> and "
+ "<shortcut label>." << std::endl);
+ return;
+ }
+
+ cmsys::RegularExpression urlRegex;
+ urlRegex.compile("^(mailto:|(ftps?|https?|news)://).*$");
+
+ std::vector<std::string>::iterator it;
+ for ( it = cpackMenuLinksVector.begin();
+ it != cpackMenuLinksVector.end();
+ ++it )
+ {
+ std::string sourceName = *it;
+ const bool url = urlRegex.find(sourceName);
+
+ // Convert / to \ in filenames, but not in urls:
+ //
+ if(!url)
+ {
+ cmSystemTools::ReplaceString(sourceName, "/", "\\");
+ }
+
+ ++ it;
+ std::string linkName = *it;
+ if(!url)
+ {
+ str << " CreateShortCut \"$SMPROGRAMS\\$STARTMENU_FOLDER\\"
+ << linkName << ".lnk\" \"$INSTDIR\\" << sourceName << "\""
+ << std::endl;
+ deleteStr << " Delete \"$SMPROGRAMS\\$MUI_TEMP\\" << linkName
+ << ".lnk\"" << std::endl;
+ }
+ else
+ {
+ str << " WriteINIStr \"$SMPROGRAMS\\$STARTMENU_FOLDER\\"
+ << linkName << ".url\" \"InternetShortcut\" \"URL\" \""
+ << sourceName << "\""
+ << std::endl;
+ deleteStr << " Delete \"$SMPROGRAMS\\$MUI_TEMP\\" << linkName
+ << ".url\"" << std::endl;
+ }
+ // see if CPACK_CREATE_DESKTOP_LINK_ExeName is on
+ // if so add a desktop link
+ std::string desktop = "CPACK_CREATE_DESKTOP_LINK_";
+ desktop += linkName;
+ if(this->IsSet(desktop.c_str()))
+ {
+ str << " StrCmp \"$INSTALL_DESKTOP\" \"1\" 0 +2\n";
+ str << " CreateShortCut \"$DESKTOP\\"
+ << linkName << ".lnk\" \"$INSTDIR\\" << sourceName << "\""
+ << std::endl;
+ deleteStr << " StrCmp \"$INSTALL_DESKTOP\" \"1\" 0 +2\n";
+ deleteStr << " Delete \"$DESKTOP\\" << linkName
+ << ".lnk\"" << std::endl;
+ }
+ }
+}
+
+//----------------------------------------------------------------------
+bool cmCPackNSISGenerator::GetListOfSubdirectories(const char* topdir,
+ std::vector<std::string>& dirs)
+{
+ cmsys::Directory dir;
+ dir.Load(topdir);
+ 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)),".."))
+ {
+ cmsys_stl::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 (!this->GetListOfSubdirectories(fullPath.c_str(), dirs))
+ {
+ return false;
+ }
+ }
+ }
+ }
+ dirs.push_back(topdir);
+ return true;
+}
+
+//----------------------------------------------------------------------
+enum cmCPackGenerator::CPackSetDestdirSupport
+cmCPackNSISGenerator::SupportsSetDestdir() const
+{
+ return cmCPackGenerator::SETDESTDIR_SHOULD_NOT_BE_USED;
+}
+
+//----------------------------------------------------------------------
+bool cmCPackNSISGenerator::SupportsAbsoluteDestination() const
+{
+ return false;
+}
+
+//----------------------------------------------------------------------
+bool cmCPackNSISGenerator::SupportsComponentInstallation() const
+{
+ return true;
+}
+
+//----------------------------------------------------------------------
+std::string
+cmCPackNSISGenerator::
+CreateComponentDescription(cmCPackComponent *component,
+ cmOStringStream& macrosOut)
+{
+ // Basic description of the component
+ std::string componentCode = "Section ";
+ if (component->IsDisabledByDefault)
+ {
+ componentCode += "/o ";
+ }
+ componentCode += "\"";
+ if (component->IsHidden)
+ {
+ componentCode += "-";
+ }
+ componentCode += component->DisplayName + "\" " + component->Name + "\n";
+ if (component->IsRequired)
+ {
+ componentCode += " SectionIn RO\n";
+ }
+ else if (!component->InstallationTypes.empty())
+ {
+ cmOStringStream out;
+ std::vector<cmCPackInstallationType *>::iterator installTypeIter;
+ for (installTypeIter = component->InstallationTypes.begin();
+ installTypeIter != component->InstallationTypes.end();
+ ++installTypeIter)
+ {
+ out << " " << (*installTypeIter)->Index;
+ }
+ componentCode += " SectionIn" + out.str() + "\n";
+ }
+ componentCode += " SetOutPath \"$INSTDIR\"\n";
+
+ // Create the actual installation commands
+ if (component->IsDownloaded)
+ {
+ if (component->ArchiveFile.empty())
+ {
+ // Compute the name of the archive.
+ std::string packagesDir = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
+ packagesDir += ".dummy";
+ cmOStringStream out;
+ out << cmSystemTools::GetFilenameWithoutLastExtension(packagesDir)
+ << "-" << component->Name << ".zip";
+ component->ArchiveFile = out.str();
+ }
+
+ // Create the directory for the upload area
+ const char* userUploadDirectory =
+ this->GetOption("CPACK_UPLOAD_DIRECTORY");
+ std::string uploadDirectory;
+ if (userUploadDirectory && *userUploadDirectory)
+ {
+ uploadDirectory = userUploadDirectory;
+ }
+ else
+ {
+ uploadDirectory= this->GetOption("CPACK_PACKAGE_DIRECTORY");
+ uploadDirectory += "/CPackUploads";
+ }
+ if(!cmSystemTools::FileExists(uploadDirectory.c_str()))
+ {
+ if (!cmSystemTools::MakeDirectory(uploadDirectory.c_str()))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Unable to create NSIS upload directory " << uploadDirectory
+ << std::endl);
+ return "";
+ }
+ }
+
+ // Remove the old archive, if one exists
+ std::string archiveFile = uploadDirectory + '/' + component->ArchiveFile;
+ cmCPackLogger(cmCPackLog::LOG_OUTPUT,
+ "- Building downloaded component archive: "
+ << archiveFile << std::endl);
+ if (cmSystemTools::FileExists(archiveFile.c_str(), true))
+ {
+ if (!cmSystemTools::RemoveFile(archiveFile.c_str()))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Unable to remove archive file " << archiveFile
+ << std::endl);
+ return "";
+ }
+ }
+
+ // Find a ZIP program
+ if (!this->IsSet("ZIP_EXECUTABLE"))
+ {
+ this->ReadListFile("CPackZIP.cmake");
+
+ if (!this->IsSet("ZIP_EXECUTABLE"))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Unable to find ZIP program"
+ << std::endl);
+ return "";
+ }
+ }
+
+ // The directory where this component's files reside
+ std::string dirName = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
+ dirName += '/';
+ dirName += component->Name;
+ dirName += '/';
+
+ // Build the list of files to go into this archive, and determine the
+ // size of the installed component.
+ std::string zipListFileName = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
+ zipListFileName += "/winZip.filelist";
+ bool needQuotesInFile
+ = cmSystemTools::IsOn(this->GetOption("CPACK_ZIP_NEED_QUOTES"));
+ unsigned long totalSize = 0;
+ { // the scope is needed for cmGeneratedFileStream
+ cmGeneratedFileStream out(zipListFileName.c_str());
+ std::vector<std::string>::iterator fileIt;
+ for (fileIt = component->Files.begin();
+ fileIt != component->Files.end();
+ ++fileIt)
+ {
+ if ( needQuotesInFile )
+ {
+ out << "\"";
+ }
+ out << *fileIt;
+ if ( needQuotesInFile )
+ {
+ out << "\"";
+ }
+ out << std::endl;
+
+ totalSize += cmSystemTools::FileLength((dirName + *fileIt).c_str());
+ }
+ }
+
+ // Build the archive in the upload area
+ std::string cmd = this->GetOption("CPACK_ZIP_COMMAND");
+ cmsys::SystemTools::ReplaceString(cmd, "<ARCHIVE>", archiveFile.c_str());
+ cmsys::SystemTools::ReplaceString(cmd, "<FILELIST>",
+ 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);
+ 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
+ << "# Output:" << std::endl
+ << output.c_str() << std::endl;
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem running zip command: "
+ << cmd.c_str() << std::endl
+ << "Please check " << tmpFile.c_str() << " for errors" << std::endl);
+ return "";
+ }
+
+ // Create the NSIS code to download this file on-the-fly.
+ unsigned long totalSizeInKbytes = (totalSize + 512) / 1024;
+ if (totalSizeInKbytes == 0)
+ {
+ totalSizeInKbytes = 1;
+ }
+ cmOStringStream out;
+ out << " AddSize " << totalSizeInKbytes << "\n"
+ << " Push \"" << component->ArchiveFile << "\"\n"
+ << " Call DownloadFile\n"
+ << " ZipDLL::extractall \"$INSTDIR\\"
+ << component->ArchiveFile << "\" \"$INSTDIR\"\n"
+ << " Pop $2 ; error message\n"
+ " StrCmp $2 \"success\" +2 0\n"
+ " MessageBox MB_OK \"Failed to unzip $2\"\n"
+ " Delete $INSTDIR\\$0\n";
+ componentCode += out.str();
+ }
+ else
+ {
+ componentCode += " File /r \"${INST_DIR}\\" +
+ component->Name + "\\*.*\"\n";
+ }
+ componentCode += "SectionEnd\n";
+
+ // Macro used to remove the component
+ macrosOut << "!macro Remove_${" << component->Name << "}\n";
+ macrosOut << " IntCmp $" << component->Name << "_was_installed 0 noremove_"
+ << component->Name << "\n";
+ std::vector<std::string>::iterator pathIt;
+ std::string path;
+ for (pathIt = component->Files.begin();
+ pathIt != component->Files.end();
+ ++pathIt)
+ {
+ path = *pathIt;
+ cmSystemTools::ReplaceString(path, "/", "\\");
+ macrosOut << " Delete \"$INSTDIR\\"
+ << path.c_str()
+ << "\"\n";
+ }
+ for (pathIt = component->Directories.begin();
+ pathIt != component->Directories.end();
+ ++pathIt)
+ {
+ path = *pathIt;
+ cmSystemTools::ReplaceString(path, "/", "\\");
+ macrosOut << " RMDir \"$INSTDIR\\"
+ << path.c_str()
+ << "\"\n";
+ }
+ macrosOut << " noremove_" << component->Name << ":\n";
+ macrosOut << "!macroend\n";
+
+ // Macro used to select each of the components that this component
+ // depends on.
+ std::set<cmCPackComponent *> visited;
+ macrosOut << "!macro Select_" << component->Name << "_depends\n";
+ macrosOut << CreateSelectionDependenciesDescription(component, visited);
+ macrosOut << "!macroend\n";
+
+ // Macro used to deselect each of the components that depend on this
+ // component.
+ visited.clear();
+ macrosOut << "!macro Deselect_required_by_" << component->Name << "\n";
+ macrosOut << CreateDeselectionDependenciesDescription(component, visited);
+ macrosOut << "!macroend\n";
+ return componentCode;
+}
+
+//----------------------------------------------------------------------
+std::string cmCPackNSISGenerator::CreateSelectionDependenciesDescription
+ (cmCPackComponent *component,
+ std::set<cmCPackComponent *>& visited)
+{
+ // Don't visit a component twice
+ if (visited.count(component))
+ {
+ return std::string();
+ }
+ visited.insert(component);
+
+ cmOStringStream out;
+ std::vector<cmCPackComponent *>::iterator dependIt;
+ for (dependIt = component->Dependencies.begin();
+ dependIt != component->Dependencies.end();
+ ++dependIt)
+ {
+ // Write NSIS code to select this dependency
+ out << " SectionGetFlags ${" << (*dependIt)->Name << "} $0\n";
+ out << " IntOp $0 $0 | ${SF_SELECTED}\n";
+ out << " SectionSetFlags ${" << (*dependIt)->Name << "} $0\n";
+ out << " IntOp $" << (*dependIt)->Name
+ << "_selected 0 + ${SF_SELECTED}\n";
+ // Recurse
+ out << CreateSelectionDependenciesDescription(*dependIt, visited).c_str();
+ }
+
+ return out.str();
+}
+
+
+//----------------------------------------------------------------------
+std::string cmCPackNSISGenerator::CreateDeselectionDependenciesDescription
+ (cmCPackComponent *component,
+ std::set<cmCPackComponent *>& visited)
+{
+ // Don't visit a component twice
+ if (visited.count(component))
+ {
+ return std::string();
+ }
+ visited.insert(component);
+
+ cmOStringStream out;
+ std::vector<cmCPackComponent *>::iterator dependIt;
+ for (dependIt = component->ReverseDependencies.begin();
+ dependIt != component->ReverseDependencies.end();
+ ++dependIt)
+ {
+ // Write NSIS code to deselect this dependency
+ out << " SectionGetFlags ${" << (*dependIt)->Name << "} $0\n";
+ out << " IntOp $1 ${SF_SELECTED} ~\n";
+ out << " IntOp $0 $0 & $1\n";
+ out << " SectionSetFlags ${" << (*dependIt)->Name << "} $0\n";
+ out << " IntOp $" << (*dependIt)->Name << "_selected 0 + 0\n";
+
+ // Recurse
+ out <<
+ CreateDeselectionDependenciesDescription(*dependIt, visited).c_str();
+ }
+
+ return out.str();
+}
+
+//----------------------------------------------------------------------
+std::string
+cmCPackNSISGenerator::
+CreateComponentGroupDescription(cmCPackComponentGroup *group,
+ cmOStringStream& macrosOut)
+{
+ if (group->Components.empty() && group->Subgroups.empty())
+ {
+ // Silently skip empty groups. NSIS doesn't support them.
+ return std::string();
+ }
+
+ std::string code = "SectionGroup ";
+ if (group->IsExpandedByDefault)
+ {
+ code += "/e ";
+ }
+ if (group->IsBold)
+ {
+ code += "\"!" + group->DisplayName + "\" " + group->Name + "\n";
+ }
+ else
+ {
+ code += "\"" + group->DisplayName + "\" " + group->Name + "\n";
+ }
+
+ std::vector<cmCPackComponentGroup*>::iterator groupIt;
+ for (groupIt = group->Subgroups.begin(); groupIt != group->Subgroups.end();
+ ++groupIt)
+ {
+ code += this->CreateComponentGroupDescription(*groupIt, macrosOut);
+ }
+
+ std::vector<cmCPackComponent*>::iterator comp;
+ for (comp = group->Components.begin();
+ comp != group->Components.end();
+ ++comp)
+ {
+ if ((*comp)->Files.empty())
+ {
+ continue;
+ }
+
+ code += this->CreateComponentDescription(*comp, macrosOut);
+ }
+ code += "SectionGroupEnd\n";
+ return code;
+}
+
+std::string cmCPackNSISGenerator::TranslateNewlines(std::string str)
+{
+ cmSystemTools::ReplaceString(str, "\n", "$\\r$\\n");
+ return str;
+}
diff --git a/Source/CPack/cmCPackNSISGenerator.h b/Source/CPack/cmCPackNSISGenerator.h
new file mode 100644
index 000000000..82248546f
--- /dev/null
+++ b/Source/CPack/cmCPackNSISGenerator.h
@@ -0,0 +1,82 @@
+/*============================================================================
+ 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 cmCPackNSISGenerator_h
+#define cmCPackNSISGenerator_h
+
+
+#include "cmCPackGenerator.h"
+#include <set>
+
+/** \class cmCPackNSISGenerator
+ * \brief A generator for NSIS files
+ *
+ * http://people.freebsd.org/~kientzle/libarchive/
+ */
+class cmCPackNSISGenerator : public cmCPackGenerator
+{
+public:
+ cmCPackTypeMacro(cmCPackNSISGenerator, cmCPackGenerator);
+
+ /**
+ * Construct generator
+ */
+ cmCPackNSISGenerator();
+ virtual ~cmCPackNSISGenerator();
+
+protected:
+ virtual int InitializeInternal();
+ void CreateMenuLinks( cmOStringStream& str,
+ cmOStringStream& deleteStr);
+ int PackageFiles();
+ virtual const char* GetOutputExtension() { return ".exe"; }
+ virtual const char* GetOutputPostfix() { return "win32"; }
+
+ bool GetListOfSubdirectories(const char* dir,
+ std::vector<std::string>& dirs);
+
+ enum cmCPackGenerator::CPackSetDestdirSupport SupportsSetDestdir() const;
+ virtual bool SupportsAbsoluteDestination() const;
+ virtual bool SupportsComponentInstallation() const;
+
+ /// Produce a string that contains the NSIS code to describe a
+ /// particular component. Any added macros will be emitted via
+ /// macrosOut.
+ std::string
+ CreateComponentDescription(cmCPackComponent *component,
+ cmOStringStream& macrosOut);
+
+ /// Produce NSIS code that selects all of the components that this component
+ /// depends on, recursively.
+ std::string CreateSelectionDependenciesDescription
+ (cmCPackComponent *component,
+ std::set<cmCPackComponent *>& visited);
+
+ /// Produce NSIS code that de-selects all of the components that are
+ /// dependent on this component, recursively.
+ std::string CreateDeselectionDependenciesDescription
+ (cmCPackComponent *component,
+ std::set<cmCPackComponent *>& visited);
+
+ /// Produce a string that contains the NSIS code to describe a
+ /// particular component group, including its components. Any
+ /// added macros will be emitted via macrosOut.
+ std::string
+ CreateComponentGroupDescription(cmCPackComponentGroup *group,
+ cmOStringStream& macrosOut);
+
+ /// Translations any newlines found in the string into \\r\\n, so that the
+ /// resulting string can be used within NSIS.
+ static std::string TranslateNewlines(std::string str);
+};
+
+#endif
diff --git a/Source/CPack/cmCPackOSXX11Generator.cxx b/Source/CPack/cmCPackOSXX11Generator.cxx
new file mode 100644
index 000000000..363ccea0c
--- /dev/null
+++ b/Source/CPack/cmCPackOSXX11Generator.cxx
@@ -0,0 +1,311 @@
+/*============================================================================
+ 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 "cmCPackOSXX11Generator.h"
+
+#include "cmake.h"
+#include "cmGlobalGenerator.h"
+#include "cmLocalGenerator.h"
+#include "cmSystemTools.h"
+#include "cmMakefile.h"
+#include "cmGeneratedFileStream.h"
+#include "cmCPackLog.h"
+
+#include <cmsys/SystemTools.hxx>
+#include <cmsys/Glob.hxx>
+#include <sys/stat.h>
+
+//----------------------------------------------------------------------
+cmCPackOSXX11Generator::cmCPackOSXX11Generator()
+{
+}
+
+//----------------------------------------------------------------------
+cmCPackOSXX11Generator::~cmCPackOSXX11Generator()
+{
+}
+
+//----------------------------------------------------------------------
+int cmCPackOSXX11Generator::PackageFiles()
+{
+ // TODO: Use toplevel ?
+ // It is used! Is this an obsolete comment?
+
+ const char* cpackPackageExecutables
+ = this->GetOption("CPACK_PACKAGE_EXECUTABLES");
+ if ( cpackPackageExecutables )
+ {
+ cmCPackLogger(cmCPackLog::LOG_DEBUG, "The cpackPackageExecutables: "
+ << cpackPackageExecutables << "." << std::endl);
+ cmOStringStream str;
+ cmOStringStream deleteStr;
+ std::vector<std::string> cpackPackageExecutablesVector;
+ cmSystemTools::ExpandListArgument(cpackPackageExecutables,
+ cpackPackageExecutablesVector);
+ if ( cpackPackageExecutablesVector.size() % 2 != 0 )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "CPACK_PACKAGE_EXECUTABLES should contain pairs of <executable> and "
+ "<icon name>." << std::endl);
+ return 0;
+ }
+ std::vector<std::string>::iterator it;
+ for ( it = cpackPackageExecutablesVector.begin();
+ it != cpackPackageExecutablesVector.end();
+ ++it )
+ {
+ std::string cpackExecutableName = *it;
+ ++ it;
+ this->SetOptionIfNotSet("CPACK_EXECUTABLE_NAME",
+ cpackExecutableName.c_str());
+ }
+ }
+
+ // Disk image directories
+ std::string diskImageDirectory = toplevel;
+ std::string diskImageBackgroundImageDir
+ = diskImageDirectory + "/.background";
+
+
+ // App bundle directories
+ std::string packageDirFileName = toplevel;
+ packageDirFileName += "/";
+ packageDirFileName += this->GetOption("CPACK_PACKAGE_FILE_NAME");
+ packageDirFileName += ".app";
+ std::string contentsDirectory = packageDirFileName + "/Contents";
+ std::string resourcesDirectory = contentsDirectory + "/Resources";
+ std::string appDirectory = contentsDirectory + "/MacOS";
+ std::string scriptDirectory = resourcesDirectory + "/Scripts";
+ std::string resourceFileName = this->GetOption("CPACK_PACKAGE_FILE_NAME");
+ resourceFileName += ".rsrc";
+
+ const char* dir = resourcesDirectory.c_str();
+ const char* appdir = appDirectory.c_str();
+ const char* scrDir = scriptDirectory.c_str();
+ const char* contDir = contentsDirectory.c_str();
+ const char* rsrcFile = resourceFileName.c_str();
+ const char* iconFile = this->GetOption("CPACK_PACKAGE_ICON");
+ if ( iconFile )
+ {
+ std::string iconFileName = cmsys::SystemTools::GetFilenameName(
+ iconFile);
+ if ( !cmSystemTools::FileExists(iconFile) )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find icon file: "
+ << iconFile << ". Please check CPACK_PACKAGE_ICON setting."
+ << std::endl);
+ return 0;
+ }
+ std::string destFileName = resourcesDirectory + "/" + iconFileName;
+ this->ConfigureFile(iconFile, destFileName.c_str(), true);
+ this->SetOptionIfNotSet("CPACK_APPLE_GUI_ICON", iconFileName.c_str());
+ }
+
+ std::string applicationsLinkName = diskImageDirectory + "/Applications";
+ cmSystemTools::CreateSymlink("/Applications", applicationsLinkName.c_str());
+
+ if (
+ !this->CopyResourcePlistFile("VolumeIcon.icns",
+ diskImageDirectory.c_str(),
+ ".VolumeIcon.icns", true ) ||
+ !this->CopyResourcePlistFile("DS_Store", diskImageDirectory.c_str(),
+ ".DS_Store", true ) ||
+ !this->CopyResourcePlistFile("background.png",
+ diskImageBackgroundImageDir.c_str(), "background.png", true ) ||
+ !this->CopyResourcePlistFile("RuntimeScript", dir) ||
+ !this->CopyResourcePlistFile("OSXX11.Info.plist", contDir,
+ "Info.plist" ) ||
+ !this->CopyResourcePlistFile("OSXX11.main.scpt", scrDir,
+ "main.scpt", true ) ||
+ !this->CopyResourcePlistFile("OSXScriptLauncher.rsrc", dir,
+ rsrcFile, true) ||
+ !this->CopyResourcePlistFile("OSXScriptLauncher", appdir,
+ this->GetOption("CPACK_PACKAGE_FILE_NAME"), true)
+ )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem copying the resource files"
+ << std::endl);
+ return 0;
+ }
+
+ // Two of the files need to have execute permission, so ensure they do:
+ std::string runTimeScript = dir;
+ runTimeScript += "/";
+ runTimeScript += "RuntimeScript";
+
+ std::string appScriptName = appdir;
+ appScriptName += "/";
+ appScriptName += this->GetOption("CPACK_PACKAGE_FILE_NAME");
+
+ mode_t mode;
+ if (cmsys::SystemTools::GetPermissions(runTimeScript.c_str(), mode))
+ {
+ mode |= (S_IXUSR | S_IXGRP | S_IXOTH);
+ cmsys::SystemTools::SetPermissions(runTimeScript.c_str(), mode);
+ cmCPackLogger(cmCPackLog::LOG_OUTPUT, "Setting: " << runTimeScript
+ << " to permission: " << mode << std::endl);
+ }
+
+ if (cmsys::SystemTools::GetPermissions(appScriptName.c_str(), mode))
+ {
+ mode |= (S_IXUSR | S_IXGRP | S_IXOTH);
+ cmsys::SystemTools::SetPermissions(appScriptName.c_str(), mode);
+ cmCPackLogger(cmCPackLog::LOG_OUTPUT, "Setting: " << appScriptName
+ << " to permission: " << mode << std::endl);
+ }
+
+ std::string output;
+ std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
+ tmpFile += "/hdiutilOutput.log";
+ cmOStringStream dmgCmd;
+ dmgCmd << "\"" << this->GetOption("CPACK_INSTALLER_PROGRAM_DISK_IMAGE")
+ << "\" create -ov -format UDZO -srcfolder \""
+ << diskImageDirectory.c_str()
+ << "\" \"" << packageFileNames[0] << "\"";
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE,
+ "Compress disk image using command: "
+ << dmgCmd.str().c_str() << std::endl);
+ // since we get random dashboard failures with this one
+ // try running it more than once
+ int retVal = 1;
+ int numTries = 10;
+ bool res = false;
+ while(numTries > 0)
+ {
+ res = cmSystemTools::RunSingleCommand(dmgCmd.str().c_str(), &output,
+ &retVal, 0,
+ this->GeneratorVerbose, 0);
+ if ( res && !retVal )
+ {
+ numTries = -1;
+ break;
+ }
+ cmSystemTools::Delay(500);
+ numTries--;
+ }
+ if ( !res || retVal )
+ {
+ cmGeneratedFileStream ofs(tmpFile.c_str());
+ ofs << "# Run command: " << dmgCmd.str().c_str() << std::endl
+ << "# Output:" << std::endl
+ << output.c_str() << std::endl;
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem running hdiutil command: "
+ << dmgCmd.str().c_str() << std::endl
+ << "Please check " << tmpFile.c_str() << " for errors" << std::endl);
+ return 0;
+ }
+
+ return 1;
+}
+
+//----------------------------------------------------------------------
+int cmCPackOSXX11Generator::InitializeInternal()
+{
+ cmCPackLogger(cmCPackLog::LOG_DEBUG,
+ "cmCPackOSXX11Generator::Initialize()" << std::endl);
+ std::vector<std::string> path;
+ std::string pkgPath = cmSystemTools::FindProgram("hdiutil", path, false);
+ if ( pkgPath.empty() )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find hdiutil compiler"
+ << std::endl);
+ return 0;
+ }
+ this->SetOptionIfNotSet("CPACK_INSTALLER_PROGRAM_DISK_IMAGE",
+ pkgPath.c_str());
+
+ return this->Superclass::InitializeInternal();
+}
+
+//----------------------------------------------------------------------
+/*
+bool cmCPackOSXX11Generator::CopyCreateResourceFile(const char* name)
+{
+ std::string uname = cmSystemTools::UpperCase(name);
+ std::string cpackVar = "CPACK_RESOURCE_FILE_" + uname;
+ const char* inFileName = this->GetOption(cpackVar.c_str());
+ if ( !inFileName )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "CPack option: " << cpackVar.c_str()
+ << " not specified. It should point to "
+ << (name ? name : "(NULL)")
+ << ".rtf, " << name
+ << ".html, or " << name << ".txt file" << std::endl);
+ return false;
+ }
+ if ( !cmSystemTools::FileExists(inFileName) )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find "
+ << (name ? name : "(NULL)")
+ << " resource file: " << inFileName << std::endl);
+ return false;
+ }
+ std::string ext = cmSystemTools::GetFilenameLastExtension(inFileName);
+ if ( ext != ".rtfd" && ext != ".rtf" && ext != ".html" && ext != ".txt" )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Bad file extension specified: "
+ << ext << ". Currently only .rtfd, .rtf, .html, and .txt files allowed."
+ << std::endl);
+ return false;
+ }
+
+ std::string destFileName = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
+ destFileName += "/Resources/";
+ destFileName += name + ext;
+
+
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Configure file: "
+ << (inFileName ? inFileName : "(NULL)")
+ << " to " << destFileName.c_str() << std::endl);
+ this->ConfigureFile(inFileName, destFileName.c_str());
+ return true;
+}
+*/
+
+//----------------------------------------------------------------------
+bool cmCPackOSXX11Generator::CopyResourcePlistFile(const char* name,
+ const char* dir, const char* outputFileName /* = 0 */,
+ bool copyOnly /* = false */)
+{
+ std::string inFName = "CPack.";
+ inFName += name;
+ inFName += ".in";
+ std::string inFileName = this->FindTemplate(inFName.c_str());
+ if ( inFileName.empty() )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find input file: "
+ << inFName << std::endl);
+ return false;
+ }
+
+ if ( !outputFileName )
+ {
+ outputFileName = name;
+ }
+
+ std::string destFileName = dir;
+ destFileName += "/";
+ destFileName += outputFileName;
+
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Configure file: "
+ << inFileName.c_str() << " to " << destFileName.c_str() << std::endl);
+ this->ConfigureFile(inFileName.c_str(), destFileName.c_str(), copyOnly);
+ return true;
+}
+
+//----------------------------------------------------------------------
+const char* cmCPackOSXX11Generator::GetPackagingInstallPrefix()
+{
+ this->InstallPrefix = "/";
+ this->InstallPrefix += this->GetOption("CPACK_PACKAGE_FILE_NAME");
+ this->InstallPrefix += ".app/Contents/Resources";
+ return this->InstallPrefix.c_str();
+}
diff --git a/Source/CPack/cmCPackOSXX11Generator.h b/Source/CPack/cmCPackOSXX11Generator.h
new file mode 100644
index 000000000..b7bd24396
--- /dev/null
+++ b/Source/CPack/cmCPackOSXX11Generator.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 cmCPackOSXX11Generator_h
+#define cmCPackOSXX11Generator_h
+
+#include "cmCPackGenerator.h"
+
+/** \class cmCPackOSXX11Generator
+ * \brief A generator for OSX X11 modules
+ *
+ * Based on Gimp.app
+ */
+class cmCPackOSXX11Generator : public cmCPackGenerator
+{
+public:
+ cmCPackTypeMacro(cmCPackOSXX11Generator, cmCPackGenerator);
+
+ /**
+ * Construct generator
+ */
+ cmCPackOSXX11Generator();
+ virtual ~cmCPackOSXX11Generator();
+
+protected:
+ virtual int InitializeInternal();
+ int PackageFiles();
+ 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,
+ const char* outputFileName = 0, bool copyOnly = false);
+ std::string InstallPrefix;
+};
+
+#endif
diff --git a/Source/CPack/cmCPackPackageMakerGenerator.cxx b/Source/CPack/cmCPackPackageMakerGenerator.cxx
new file mode 100644
index 000000000..3a0e89bbd
--- /dev/null
+++ b/Source/CPack/cmCPackPackageMakerGenerator.cxx
@@ -0,0 +1,982 @@
+/*============================================================================
+ 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 "cmCPackPackageMakerGenerator.h"
+
+#include "cmake.h"
+#include "cmGlobalGenerator.h"
+#include "cmLocalGenerator.h"
+#include "cmSystemTools.h"
+#include "cmMakefile.h"
+#include "cmGeneratedFileStream.h"
+#include "cmCPackComponentGroup.h"
+#include "cmCPackLog.h"
+
+#include <cmsys/SystemTools.hxx>
+#include <cmsys/Glob.hxx>
+
+//----------------------------------------------------------------------
+cmCPackPackageMakerGenerator::cmCPackPackageMakerGenerator()
+{
+ this->PackageMakerVersion = 0.0;
+ this->PackageCompatibilityVersion = 10.4;
+}
+
+//----------------------------------------------------------------------
+cmCPackPackageMakerGenerator::~cmCPackPackageMakerGenerator()
+{
+}
+
+//----------------------------------------------------------------------
+bool cmCPackPackageMakerGenerator::SupportsComponentInstallation() const
+{
+ return this->PackageCompatibilityVersion >= 10.4;
+}
+
+//----------------------------------------------------------------------
+int cmCPackPackageMakerGenerator::CopyInstallScript(const char* resdir,
+ const char* script,
+ const char* name)
+{
+ std::string dst = resdir;
+ dst += "/";
+ dst += name;
+ cmSystemTools::CopyFileAlways(script, dst.c_str());
+ cmSystemTools::SetPermissions(dst.c_str(),0777);
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE,
+ "copy script : " << script << "\ninto " << dst.c_str() <<
+ std::endl);
+
+ return 1;
+}
+
+//----------------------------------------------------------------------
+int cmCPackPackageMakerGenerator::PackageFiles()
+{
+ // TODO: Use toplevel
+ // It is used! Is this an obsolete comment?
+
+ std::string resDir; // Where this package's resources will go.
+ std::string packageDirFileName
+ = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
+ if (this->Components.empty())
+ {
+ packageDirFileName += ".pkg";
+ resDir = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
+ resDir += "/Resources";
+ }
+ else
+ {
+ packageDirFileName += ".mpkg";
+ if ( !cmsys::SystemTools::MakeDirectory(packageDirFileName.c_str()))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "unable to create package directory "
+ << packageDirFileName << std::endl);
+ return 0;
+ }
+
+ resDir = packageDirFileName;
+ resDir += "/Contents";
+ if ( !cmsys::SystemTools::MakeDirectory(resDir.c_str()))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "unable to create package subdirectory " << resDir
+ << std::endl);
+ return 0;
+ }
+
+ resDir += "/Resources";
+ if ( !cmsys::SystemTools::MakeDirectory(resDir.c_str()))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "unable to create package subdirectory " << resDir
+ << std::endl);
+ return 0;
+ }
+
+ resDir += "/en.lproj";
+ }
+
+
+ // Create directory structure
+ std::string preflightDirName = resDir + "/PreFlight";
+ std::string postflightDirName = resDir + "/PostFlight";
+ const char* preflight = this->GetOption("CPACK_PREFLIGHT_SCRIPT");
+ const char* postflight = this->GetOption("CPACK_POSTFLIGHT_SCRIPT");
+ const char* postupgrade = this->GetOption("CPACK_POSTUPGRADE_SCRIPT");
+ // if preflight or postflight scripts not there create directories
+ // of the same name, I think this makes it work
+ if(!preflight)
+ {
+ if ( !cmsys::SystemTools::MakeDirectory(preflightDirName.c_str()))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Problem creating installer directory: "
+ << preflightDirName.c_str() << std::endl);
+ return 0;
+ }
+ }
+ if(!postflight)
+ {
+ if ( !cmsys::SystemTools::MakeDirectory(postflightDirName.c_str()))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Problem creating installer directory: "
+ << postflightDirName.c_str() << std::endl);
+ return 0;
+ }
+ }
+ // if preflight, postflight, or postupgrade are set
+ // then copy them into the resource directory and make
+ // them executable
+ if(preflight)
+ {
+ this->CopyInstallScript(resDir.c_str(),
+ preflight,
+ "preflight");
+ }
+ if(postflight)
+ {
+ this->CopyInstallScript(resDir.c_str(),
+ postflight,
+ "postflight");
+ }
+ if(postupgrade)
+ {
+ this->CopyInstallScript(resDir.c_str(),
+ postupgrade,
+ "postupgrade");
+ }
+
+ if (!this->Components.empty())
+ {
+ // Create the directory where component packages will be built.
+ std::string basePackageDir = packageDirFileName;
+ basePackageDir += "/Contents/Packages";
+ if (!cmsys::SystemTools::MakeDirectory(basePackageDir.c_str()))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Problem creating component packages directory: "
+ << basePackageDir.c_str() << std::endl);
+ return 0;
+ }
+
+ // Create the directory where downloaded component packages will
+ // be placed.
+ const char* userUploadDirectory =
+ this->GetOption("CPACK_UPLOAD_DIRECTORY");
+ std::string uploadDirectory;
+ if (userUploadDirectory && *userUploadDirectory)
+ {
+ uploadDirectory = userUploadDirectory;
+ }
+ else
+ {
+ uploadDirectory= this->GetOption("CPACK_PACKAGE_DIRECTORY");
+ uploadDirectory += "/CPackUploads";
+ }
+
+ // Create packages for each component
+ bool warnedAboutDownloadCompatibility = false;
+
+ std::map<std::string, cmCPackComponent>::iterator compIt;
+ for (compIt = this->Components.begin(); compIt != this->Components.end();
+ ++compIt)
+ {
+ std::string packageFile;
+ if (compIt->second.IsDownloaded)
+ {
+ if (this->PackageCompatibilityVersion >= 10.5 &&
+ this->PackageMakerVersion >= 3.0)
+ {
+ // Build this package within the upload directory.
+ packageFile = uploadDirectory;
+
+ if(!cmSystemTools::FileExists(uploadDirectory.c_str()))
+ {
+ if (!cmSystemTools::MakeDirectory(uploadDirectory.c_str()))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Unable to create package upload directory "
+ << uploadDirectory << std::endl);
+ return 0;
+ }
+ }
+ }
+ else if (!warnedAboutDownloadCompatibility)
+ {
+ if (this->PackageCompatibilityVersion < 10.5)
+ {
+ cmCPackLogger(
+ cmCPackLog::LOG_WARNING,
+ "CPack warning: please set CPACK_OSX_PACKAGE_VERSION to 10.5 "
+ "or greater enable downloaded packages. CPack will build a "
+ "non-downloaded package."
+ << std::endl);
+ }
+
+ if (this->PackageMakerVersion < 3)
+ {
+ cmCPackLogger(cmCPackLog::LOG_WARNING,
+ "CPack warning: unable to build downloaded "
+ "packages with PackageMaker versions prior "
+ "to 3.0. CPack will build a non-downloaded package."
+ << std::endl);
+ }
+
+ warnedAboutDownloadCompatibility = true;
+ }
+ }
+
+ if (packageFile.empty())
+ {
+ // Build this package within the overall distribution
+ // metapackage.
+ packageFile = basePackageDir;
+
+ // We're not downloading this component, even if the user
+ // requested it.
+ compIt->second.IsDownloaded = false;
+ }
+
+ packageFile += '/';
+ packageFile += GetPackageName(compIt->second);
+
+ std::string packageDir = toplevel;
+ packageDir += '/';
+ packageDir += compIt->first;
+ if (!this->GenerateComponentPackage(packageFile.c_str(),
+ packageDir.c_str(),
+ compIt->second))
+ {
+ return 0;
+ }
+ }
+ }
+ this->SetOption("CPACK_MODULE_VERSION_SUFFIX", "");
+
+ // Copy or create all of the resource files we need.
+ if ( !this->CopyCreateResourceFile("License", resDir.c_str())
+ || !this->CopyCreateResourceFile("ReadMe", resDir.c_str())
+ || !this->CopyCreateResourceFile("Welcome", resDir.c_str())
+ || !this->CopyResourcePlistFile("Info.plist")
+ || !this->CopyResourcePlistFile("Description.plist") )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem copying the resource files"
+ << std::endl);
+ return 0;
+ }
+
+ if (this->Components.empty())
+ {
+ // Use PackageMaker to build the package.
+ cmOStringStream pkgCmd;
+ pkgCmd << "\"" << this->GetOption("CPACK_INSTALLER_PROGRAM")
+ << "\" -build -p \"" << packageDirFileName << "\"";
+ if (this->Components.empty())
+ {
+ pkgCmd << " -f \"" << this->GetOption("CPACK_TEMPORARY_DIRECTORY");
+ }
+ else
+ {
+ pkgCmd << " -mi \"" << this->GetOption("CPACK_TEMPORARY_DIRECTORY")
+ << "/packages/";
+ }
+ pkgCmd << "\" -r \"" << this->GetOption("CPACK_TOPLEVEL_DIRECTORY")
+ << "/Resources\" -i \""
+ << this->GetOption("CPACK_TOPLEVEL_DIRECTORY")
+ << "/Info.plist\" -d \""
+ << this->GetOption("CPACK_TOPLEVEL_DIRECTORY")
+ << "/Description.plist\"";
+ if ( this->PackageMakerVersion > 2.0 )
+ {
+ pkgCmd << " -v";
+ }
+ if (!RunPackageMaker(pkgCmd.str().c_str(), packageDirFileName.c_str()))
+ return 0;
+ }
+ else
+ {
+ // We have built the package in place. Generate the
+ // distribution.dist file to describe it for the installer.
+ WriteDistributionFile(packageDirFileName.c_str());
+ }
+
+ std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
+ tmpFile += "/hdiutilOutput.log";
+ cmOStringStream dmgCmd;
+ dmgCmd << "\"" << this->GetOption("CPACK_INSTALLER_PROGRAM_DISK_IMAGE")
+ << "\" create -ov -format UDZO -srcfolder \"" << packageDirFileName
+ << "\" \"" << packageFileNames[0] << "\"";
+ std::string output;
+ int retVal = 1;
+ int numTries = 10;
+ bool res = false;
+ while(numTries > 0)
+ {
+ res = cmSystemTools::RunSingleCommand(dmgCmd.str().c_str(), &output,
+ &retVal, 0, this->GeneratorVerbose,
+ 0);
+ if ( res && !retVal )
+ {
+ numTries = -1;
+ break;
+ }
+ cmSystemTools::Delay(500);
+ numTries--;
+ }
+ if ( !res || retVal )
+ {
+ cmGeneratedFileStream ofs(tmpFile.c_str());
+ ofs << "# Run command: " << dmgCmd.str().c_str() << std::endl
+ << "# Output:" << std::endl
+ << output.c_str() << std::endl;
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem running hdiutil command: "
+ << dmgCmd.str().c_str() << std::endl
+ << "Please check " << tmpFile.c_str() << " for errors" << std::endl);
+ return 0;
+ }
+
+ return 1;
+}
+
+//----------------------------------------------------------------------
+int cmCPackPackageMakerGenerator::InitializeInternal()
+{
+ cmCPackLogger(cmCPackLog::LOG_DEBUG,
+ "cmCPackPackageMakerGenerator::Initialize()" << std::endl);
+ this->SetOptionIfNotSet("CPACK_PACKAGING_INSTALL_PREFIX", "/usr");
+
+ // Starting with Xcode 4.3, PackageMaker is a separate app, and you
+ // can put it anywhere you want. So... use a variable for its location.
+ // People who put it in unexpected places can use the variable to tell
+ // us where it is.
+ //
+ // Use the following locations, in "most recent installation" order,
+ // to search for the PackageMaker app. Assume people who copy it into
+ // the new Xcode 4.3 app in "/Applications" will copy it into the nested
+ // Applications folder inside the Xcode bundle itself. Or directly in
+ // the "/Applications" directory.
+ //
+ // If found, save result in the CPACK_INSTALLER_PROGRAM variable.
+
+ std::vector<std::string> paths;
+ paths.push_back(
+ "/Applications/Xcode.app/Contents/Applications"
+ "/PackageMaker.app/Contents/MacOS");
+ paths.push_back(
+ "/Applications/Utilities"
+ "/PackageMaker.app/Contents/MacOS");
+ paths.push_back(
+ "/Applications"
+ "/PackageMaker.app/Contents/MacOS");
+ paths.push_back(
+ "/Developer/Applications/Utilities"
+ "/PackageMaker.app/Contents/MacOS");
+ paths.push_back(
+ "/Developer/Applications"
+ "/PackageMaker.app/Contents/MacOS");
+
+ std::string pkgPath;
+ const char *inst_program = this->GetOption("CPACK_INSTALLER_PROGRAM");
+ if (inst_program && *inst_program)
+ {
+ pkgPath = inst_program;
+ }
+ else
+ {
+ pkgPath = cmSystemTools::FindProgram("PackageMaker", paths, false);
+ if ( pkgPath.empty() )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find PackageMaker compiler"
+ << std::endl);
+ return 0;
+ }
+ this->SetOptionIfNotSet("CPACK_INSTALLER_PROGRAM", pkgPath.c_str());
+ }
+
+ // Get path to the real PackageMaker, not a symlink:
+ pkgPath = cmSystemTools::GetRealPath(pkgPath.c_str());
+ // Up from there to find the version.plist file in the "Contents" dir:
+ std::string contents_dir;
+ contents_dir = cmSystemTools::GetFilenamePath(pkgPath);
+ contents_dir = cmSystemTools::GetFilenamePath(contents_dir);
+
+ std::string versionFile = contents_dir + "/version.plist";
+
+ if ( !cmSystemTools::FileExists(versionFile.c_str()) )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Cannot find PackageMaker compiler version file: "
+ << versionFile.c_str()
+ << std::endl);
+ return 0;
+ }
+
+ std::ifstream ifs(versionFile.c_str());
+ if ( !ifs )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Cannot open PackageMaker compiler version file" << std::endl);
+ return 0;
+ }
+
+ // Check the PackageMaker version
+ cmsys::RegularExpression rexKey("<key>CFBundleShortVersionString</key>");
+ cmsys::RegularExpression rexVersion("<string>([0-9]+.[0-9.]+)</string>");
+ std::string line;
+ bool foundKey = false;
+ while ( cmSystemTools::GetLineFromStream(ifs, line) )
+ {
+ if ( rexKey.find(line) )
+ {
+ foundKey = true;
+ break;
+ }
+ }
+ if ( !foundKey )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Cannot find CFBundleShortVersionString in the PackageMaker compiler "
+ "version file" << std::endl);
+ return 0;
+ }
+ if ( !cmSystemTools::GetLineFromStream(ifs, line) ||
+ !rexVersion.find(line) )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Problem reading the PackageMaker compiler version file: "
+ << versionFile.c_str() << std::endl);
+ return 0;
+ }
+ this->PackageMakerVersion = atof(rexVersion.match(1).c_str());
+ if ( this->PackageMakerVersion < 1.0 )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Require PackageMaker 1.0 or higher"
+ << std::endl);
+ return 0;
+ }
+ cmCPackLogger(cmCPackLog::LOG_DEBUG, "PackageMaker version is: "
+ << this->PackageMakerVersion << std::endl);
+
+ // Determine the package compatibility version. If it wasn't
+ // specified by the user, we define it based on which features the
+ // user requested.
+ const char *packageCompat = this->GetOption("CPACK_OSX_PACKAGE_VERSION");
+ if (packageCompat && *packageCompat)
+ {
+ this->PackageCompatibilityVersion = atof(packageCompat);
+ }
+ else if (this->GetOption("CPACK_DOWNLOAD_SITE"))
+ {
+ this->SetOption("CPACK_OSX_PACKAGE_VERSION", "10.5");
+ this->PackageCompatibilityVersion = 10.5;
+ }
+ else if (this->GetOption("CPACK_COMPONENTS_ALL"))
+ {
+ this->SetOption("CPACK_OSX_PACKAGE_VERSION", "10.4");
+ this->PackageCompatibilityVersion = 10.4;
+ }
+ else
+ {
+ this->SetOption("CPACK_OSX_PACKAGE_VERSION", "10.3");
+ this->PackageCompatibilityVersion = 10.3;
+ }
+
+ std::vector<std::string> no_paths;
+ pkgPath = cmSystemTools::FindProgram("hdiutil", no_paths, false);
+ if ( pkgPath.empty() )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find hdiutil compiler"
+ << std::endl);
+ return 0;
+ }
+ this->SetOptionIfNotSet("CPACK_INSTALLER_PROGRAM_DISK_IMAGE",
+ pkgPath.c_str());
+
+ return this->Superclass::InitializeInternal();
+}
+
+//----------------------------------------------------------------------
+bool cmCPackPackageMakerGenerator::CopyCreateResourceFile(const char* name,
+ const char* dirName)
+{
+ std::string uname = cmSystemTools::UpperCase(name);
+ std::string cpackVar = "CPACK_RESOURCE_FILE_" + uname;
+ const char* inFileName = this->GetOption(cpackVar.c_str());
+ if ( !inFileName )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "CPack option: " << cpackVar.c_str()
+ << " not specified. It should point to "
+ << (name ? name : "(NULL)")
+ << ".rtf, " << name
+ << ".html, or " << name << ".txt file" << std::endl);
+ return false;
+ }
+ if ( !cmSystemTools::FileExists(inFileName) )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find "
+ << (name ? name : "(NULL)")
+ << " resource file: " << inFileName << std::endl);
+ return false;
+ }
+ std::string ext = cmSystemTools::GetFilenameLastExtension(inFileName);
+ if ( ext != ".rtfd" && ext != ".rtf" && ext != ".html" && ext != ".txt" )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Bad file extension specified: "
+ << ext << ". Currently only .rtfd, .rtf, .html, and .txt files allowed."
+ << std::endl);
+ return false;
+ }
+
+ std::string destFileName = dirName;
+ destFileName += '/';
+ destFileName += name + ext;
+
+ // Set this so that distribution.dist gets the right name (without
+ // the path).
+ this->SetOption(("CPACK_RESOURCE_FILE_" + uname + "_NOPATH").c_str(),
+ (name + ext).c_str());
+
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Configure file: "
+ << (inFileName ? inFileName : "(NULL)")
+ << " to " << destFileName.c_str() << std::endl);
+ this->ConfigureFile(inFileName, destFileName.c_str());
+ return true;
+}
+
+bool cmCPackPackageMakerGenerator::CopyResourcePlistFile(const char* name,
+ const char* outName)
+{
+ if (!outName)
+ {
+ outName = name;
+ }
+
+ std::string inFName = "CPack.";
+ inFName += name;
+ inFName += ".in";
+ std::string inFileName = this->FindTemplate(inFName.c_str());
+ if ( inFileName.empty() )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find input file: "
+ << inFName << std::endl);
+ return false;
+ }
+
+ std::string destFileName = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
+ destFileName += "/";
+ destFileName += outName;
+
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Configure file: "
+ << inFileName.c_str() << " to " << destFileName.c_str() << std::endl);
+ this->ConfigureFile(inFileName.c_str(), destFileName.c_str());
+ return true;
+}
+
+//----------------------------------------------------------------------
+bool cmCPackPackageMakerGenerator::RunPackageMaker(const char *command,
+ const char *packageFile)
+{
+ std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
+ tmpFile += "/PackageMakerOutput.log";
+
+ 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);
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Done running package maker"
+ << std::endl);
+ if ( !res || retVal )
+ {
+ cmGeneratedFileStream ofs(tmpFile.c_str());
+ ofs << "# Run command: " << command << std::endl
+ << "# Output:" << std::endl
+ << output.c_str() << std::endl;
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Problem running PackageMaker command: " << command
+ << std::endl << "Please check " << tmpFile.c_str() << " for errors"
+ << std::endl);
+ return false;
+ }
+ // sometimes the command finishes but the directory is not yet
+ // created, so try 10 times to see if it shows up
+ int tries = 10;
+ while(tries > 0 &&
+ !cmSystemTools::FileExists(packageFile))
+ {
+ cmSystemTools::Delay(500);
+ tries--;
+ }
+ if(!cmSystemTools::FileExists(packageFile))
+ {
+ cmCPackLogger(
+ cmCPackLog::LOG_ERROR,
+ "Problem running PackageMaker command: " << command
+ << std::endl << "Package not created: " << packageFile
+ << std::endl);
+ return false;
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------
+std::string
+cmCPackPackageMakerGenerator::GetPackageName(const cmCPackComponent& component)
+{
+ if (component.ArchiveFile.empty())
+ {
+ std::string packagesDir = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
+ packagesDir += ".dummy";
+ cmOStringStream out;
+ out << cmSystemTools::GetFilenameWithoutLastExtension(packagesDir)
+ << "-" << component.Name << ".pkg";
+ return out.str();
+ }
+ else
+ {
+ return component.ArchiveFile + ".pkg";
+ }
+}
+
+//----------------------------------------------------------------------
+bool
+cmCPackPackageMakerGenerator::
+GenerateComponentPackage(const char *packageFile,
+ const char *packageDir,
+ const cmCPackComponent& component)
+{
+ cmCPackLogger(cmCPackLog::LOG_OUTPUT,
+ "- Building component package: " <<
+ packageFile << std::endl);
+
+ // The command that will be used to run PackageMaker
+ cmOStringStream pkgCmd;
+
+ if (this->PackageCompatibilityVersion < 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());
+ 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
+ << "<plist version=\"1.4\">" << std::endl
+ << "<dict>" << std::endl
+ << " <key>IFPkgDescriptionTitle</key>" << std::endl
+ << " <string>" << component.DisplayName << "</string>" << std::endl
+ << " <key>IFPkgDescriptionVersion</key>" << std::endl
+ << " <string>" << this->GetOption("CPACK_PACKAGE_VERSION")
+ << "</string>" << std::endl
+ << " <key>IFPkgDescriptionDescription</key>" << std::endl
+ << " <string>" + this->EscapeForXML(component.Description)
+ << "</string>" << std::endl
+ << "</dict>" << std::endl
+ << "</plist>" << std::endl;
+ out.close();
+
+ // Create the Info.plist file for this component
+ std::string moduleVersionSuffix = ".";
+ moduleVersionSuffix += component.Name;
+ this->SetOption("CPACK_MODULE_VERSION_SUFFIX",
+ moduleVersionSuffix.c_str());
+ std::string infoFileName = component.Name;
+ infoFileName += "-Info.plist";
+ if (!this->CopyResourcePlistFile("Info.plist", infoFileName.c_str()))
+ {
+ return false;
+ }
+
+ pkgCmd << "\"" << this->GetOption("CPACK_INSTALLER_PROGRAM")
+ << "\" -build -p \"" << packageFile << "\""
+ << " -f \"" << packageDir << "\""
+ << " -i \"" << this->GetOption("CPACK_TOPLEVEL_DIRECTORY")
+ << "/" << infoFileName << "\""
+ << " -d \"" << descriptionFile << "\"";
+ }
+ else
+ {
+ // Create a "flat" package on Mac OS X 10.5 and newer. Flat
+ // packages are stored in a single file, rather than a directory
+ // like normal packages, and can be downloaded by the installer
+ // on-the-fly in Mac OS X 10.5 or newer. Thus, we need to create
+ // flat packages when the packages will be downloaded on the fly.
+ std::string pkgId = "com.";
+ pkgId += this->GetOption("CPACK_PACKAGE_VENDOR");
+ pkgId += '.';
+ pkgId += this->GetOption("CPACK_PACKAGE_NAME");
+ pkgId += '.';
+ pkgId += component.Name;
+
+ pkgCmd << "\"" << this->GetOption("CPACK_INSTALLER_PROGRAM")
+ << "\" --root \"" << packageDir << "\""
+ << " --id " << pkgId
+ << " --target " << this->GetOption("CPACK_OSX_PACKAGE_VERSION")
+ << " --out \"" << packageFile << "\"";
+ }
+
+ // Run PackageMaker
+ return RunPackageMaker(pkgCmd.str().c_str(), packageFile);
+}
+
+//----------------------------------------------------------------------
+void
+cmCPackPackageMakerGenerator::
+WriteDistributionFile(const char* metapackageFile)
+{
+ std::string distributionTemplate
+ = this->FindTemplate("CPack.distribution.dist.in");
+ if ( distributionTemplate.empty() )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find input file: "
+ << distributionTemplate << std::endl);
+ return;
+ }
+
+ std::string distributionFile = metapackageFile;
+ distributionFile += "/Contents/distribution.dist";
+
+ // Create the choice outline, which provides a tree-based view of
+ // the components in their groups.
+ cmOStringStream choiceOut;
+ choiceOut << "<choices-outline>" << std::endl;
+
+ // Emit the outline for the groups
+ std::map<std::string, cmCPackComponentGroup>::iterator groupIt;
+ for (groupIt = this->ComponentGroups.begin();
+ groupIt != this->ComponentGroups.end();
+ ++groupIt)
+ {
+ if (groupIt->second.ParentGroup == 0)
+ {
+ CreateChoiceOutline(groupIt->second, choiceOut);
+ }
+ }
+
+ // Emit the outline for the non-grouped components
+ std::map<std::string, cmCPackComponent>::iterator compIt;
+ for (compIt = this->Components.begin(); compIt != this->Components.end();
+ ++compIt)
+ {
+ if (!compIt->second.Group)
+ {
+ choiceOut << "<line choice=\"" << compIt->first << "Choice\"></line>"
+ << std::endl;
+ }
+ }
+ choiceOut << "</choices-outline>" << std::endl;
+
+ // Create the actual choices
+ for (groupIt = this->ComponentGroups.begin();
+ groupIt != this->ComponentGroups.end();
+ ++groupIt)
+ {
+ CreateChoice(groupIt->second, choiceOut);
+ }
+ for (compIt = this->Components.begin(); compIt != this->Components.end();
+ ++compIt)
+ {
+ CreateChoice(compIt->second, choiceOut);
+ }
+ this->SetOption("CPACK_PACKAGEMAKER_CHOICES", choiceOut.str().c_str());
+
+ // Create the distribution.dist file in the metapackage to turn it
+ // into a distribution package.
+ this->ConfigureFile(distributionTemplate.c_str(),
+ distributionFile.c_str());
+}
+
+//----------------------------------------------------------------------
+void
+cmCPackPackageMakerGenerator::
+CreateChoiceOutline(const cmCPackComponentGroup& group, cmOStringStream& out)
+{
+ out << "<line choice=\"" << group.Name << "Choice\">" << std::endl;
+ std::vector<cmCPackComponentGroup*>::const_iterator groupIt;
+ for (groupIt = group.Subgroups.begin(); groupIt != group.Subgroups.end();
+ ++groupIt)
+ {
+ CreateChoiceOutline(**groupIt, out);
+ }
+
+ std::vector<cmCPackComponent*>::const_iterator compIt;
+ for (compIt = group.Components.begin(); compIt != group.Components.end();
+ ++compIt)
+ {
+ out << " <line choice=\"" << (*compIt)->Name << "Choice\"></line>"
+ << std::endl;
+ }
+ out << "</line>" << std::endl;
+}
+
+//----------------------------------------------------------------------
+void
+cmCPackPackageMakerGenerator::CreateChoice(const cmCPackComponentGroup& group,
+ cmOStringStream& out)
+{
+ out << "<choice id=\"" << group.Name << "Choice\" "
+ << "title=\"" << group.DisplayName << "\" "
+ << "start_selected=\"true\" "
+ << "start_enabled=\"true\" "
+ << "start_visible=\"true\" ";
+ if (!group.Description.empty())
+ {
+ out << "description=\"" << EscapeForXML(group.Description)
+ << "\"";
+ }
+ out << "></choice>" << std::endl;
+}
+
+//----------------------------------------------------------------------
+void
+cmCPackPackageMakerGenerator::CreateChoice(const cmCPackComponent& component,
+ cmOStringStream& out)
+{
+ std::string packageId = "com.";
+ packageId += this->GetOption("CPACK_PACKAGE_VENDOR");
+ packageId += '.';
+ packageId += this->GetOption("CPACK_PACKAGE_NAME");
+ packageId += '.';
+ packageId += component.Name;
+
+ out << "<choice id=\"" << component.Name << "Choice\" "
+ << "title=\"" << component.DisplayName << "\" "
+ << "start_selected=\""
+ << (component.IsDisabledByDefault &&
+ !component.IsRequired? "false" : "true")
+ << "\" "
+ << "start_enabled=\""
+ << (component.IsRequired? "false" : "true")
+ << "\" "
+ << "start_visible=\"" << (component.IsHidden? "false" : "true") << "\" ";
+ if (!component.Description.empty())
+ {
+ out << "description=\"" << EscapeForXML(component.Description)
+ << "\" ";
+ }
+ if (!component.Dependencies.empty() ||
+ !component.ReverseDependencies.empty())
+ {
+ // The "selected" expression is evaluated each time any choice is
+ // selected, for all choices *except* the one that the user
+ // selected. A component is marked selected if it has been
+ // selected (my.choice.selected in Javascript) and all of the
+ // components it depends on have been selected (transitively) or
+ // if any of the components that depend on it have been selected
+ // (transitively). Assume that we have components A, B, C, D, and
+ // E, where each component depends on the previous component (B
+ // depends on A, C depends on B, D depends on C, and E depends on
+ // D). The expression we build for the component C will be
+ // my.choice.selected && B && A || D || E
+ // This way, selecting C will automatically select everything it depends
+ // on (B and A), while selecting something that depends on C--either D
+ // or E--will automatically cause C to get selected.
+ out << "selected=\"my.choice.selected";
+ std::set<const cmCPackComponent *> visited;
+ AddDependencyAttributes(component, visited, out);
+ visited.clear();
+ AddReverseDependencyAttributes(component, visited, out);
+ out << "\"";
+ }
+ out << ">" << std::endl;
+ out << " <pkg-ref id=\"" << packageId << "\"></pkg-ref>" << std::endl;
+ out << "</choice>" << std::endl;
+
+ // Create a description of the package associated with this
+ // component.
+ std::string relativePackageLocation = "Contents/Packages/";
+ relativePackageLocation += this->GetPackageName(component);
+
+ // Determine the installed size of the package.
+ std::string dirName = this->GetOption("CPACK_TEMPORARY_DIRECTORY");
+ dirName += '/';
+ dirName += component.Name;
+ unsigned long installedSize
+ = component.GetInstalledSizeInKbytes(dirName.c_str());
+
+ out << "<pkg-ref id=\"" << packageId << "\" "
+ << "version=\"" << this->GetOption("CPACK_PACKAGE_VERSION") << "\" "
+ << "installKBytes=\"" << installedSize << "\" "
+ << "auth=\"Admin\" onConclusion=\"None\">";
+ if (component.IsDownloaded)
+ {
+ out << this->GetOption("CPACK_DOWNLOAD_SITE")
+ << this->GetPackageName(component);
+ }
+ else
+ {
+ out << "file:./" << relativePackageLocation;
+ }
+ out << "</pkg-ref>" << std::endl;
+}
+
+//----------------------------------------------------------------------
+void
+cmCPackPackageMakerGenerator::
+AddDependencyAttributes(const cmCPackComponent& component,
+ std::set<const cmCPackComponent *>& visited,
+ cmOStringStream& out)
+{
+ if (visited.find(&component) != visited.end())
+ {
+ return;
+ }
+ visited.insert(&component);
+
+ std::vector<cmCPackComponent *>::const_iterator dependIt;
+ for (dependIt = component.Dependencies.begin();
+ dependIt != component.Dependencies.end();
+ ++dependIt)
+ {
+ out << " &amp;&amp; choices['" <<
+ (*dependIt)->Name << "Choice'].selected";
+ AddDependencyAttributes(**dependIt, visited, out);
+ }
+}
+
+//----------------------------------------------------------------------
+void
+cmCPackPackageMakerGenerator::
+AddReverseDependencyAttributes(const cmCPackComponent& component,
+ std::set<const cmCPackComponent *>& visited,
+ cmOStringStream& out)
+{
+ if (visited.find(&component) != visited.end())
+ {
+ return;
+ }
+ visited.insert(&component);
+
+ std::vector<cmCPackComponent *>::const_iterator dependIt;
+ for (dependIt = component.ReverseDependencies.begin();
+ dependIt != component.ReverseDependencies.end();
+ ++dependIt)
+ {
+ out << " || choices['" << (*dependIt)->Name << "Choice'].selected";
+ AddReverseDependencyAttributes(**dependIt, visited, out);
+ }
+}
+
+//----------------------------------------------------------------------
+std::string cmCPackPackageMakerGenerator::EscapeForXML(std::string str)
+{
+ cmSystemTools::ReplaceString(str, "&", "&amp;");
+ cmSystemTools::ReplaceString(str, "<", "&lt;");
+ cmSystemTools::ReplaceString(str, ">", "&gt;");
+ cmSystemTools::ReplaceString(str, "\"", "&quot;");
+ return str;
+}
diff --git a/Source/CPack/cmCPackPackageMakerGenerator.h b/Source/CPack/cmCPackPackageMakerGenerator.h
new file mode 100644
index 000000000..2bab94791
--- /dev/null
+++ b/Source/CPack/cmCPackPackageMakerGenerator.h
@@ -0,0 +1,119 @@
+/*============================================================================
+ 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 cmCPackPackageMakerGenerator_h
+#define cmCPackPackageMakerGenerator_h
+
+
+#include "cmCPackGenerator.h"
+
+class cmCPackComponent;
+
+/** \class cmCPackPackageMakerGenerator
+ * \brief A generator for PackageMaker files
+ *
+ * http://developer.apple.com/documentation/Darwin
+ * /Reference/ManPages/man1/packagemaker.1.html
+ */
+class cmCPackPackageMakerGenerator : public cmCPackGenerator
+{
+public:
+ cmCPackTypeMacro(cmCPackPackageMakerGenerator, cmCPackGenerator);
+
+ /**
+ * Construct generator
+ */
+ cmCPackPackageMakerGenerator();
+ virtual ~cmCPackPackageMakerGenerator();
+
+ virtual bool SupportsComponentInstallation() const;
+
+protected:
+ int CopyInstallScript(const char* resdir,
+ const char* script,
+ const char* name);
+ virtual int InitializeInternal();
+ int PackageFiles();
+ virtual const char* GetOutputExtension() { return ".dmg"; }
+ virtual const char* GetOutputPostfix() { return "darwin"; }
+
+ // Copies or creates the resource file with the given name to the
+ // package or package staging directory dirName. The variable
+ // 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);
+
+ // Run PackageMaker with the given command line, which will (if
+ // successful) produce the given package file. Returns true if
+ // PackageMaker succeeds, false otherwise.
+ bool RunPackageMaker(const char *command, const char *packageFile);
+
+ // Retrieve the name of package file that will be generated for this
+ // component. The name is just the file name with extension, and
+ // does not include the subdirectory.
+ std::string GetPackageName(const cmCPackComponent& component);
+
+ // Generate a package in the file packageFile for the given
+ // component. All of the files within this component are stored in
+ // the directory packageDir. Returns true if successful, false
+ // otherwise.
+ bool GenerateComponentPackage(const char *packageFile,
+ const char *packageDir,
+ const cmCPackComponent& component);
+
+ // Writes a distribution.dist file, which turns a metapackage into a
+ // full-fledged distribution. This file is used to describe
+ // inter-component dependencies. metapackageFile is the name of the
+ // metapackage for the distribution. Only valid for a
+ // component-based install.
+ void WriteDistributionFile(const char* metapackageFile);
+
+ // Subroutine of WriteDistributionFile that writes out the
+ // dependency attributes for inter-component dependencies.
+ void AddDependencyAttributes(const cmCPackComponent& component,
+ std::set<const cmCPackComponent *>& visited,
+ cmOStringStream& 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);
+
+ // 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);
+
+ /// Create the "choice" XML element to describe a component group
+ /// for the installer GUI.
+ void CreateChoice(const cmCPackComponentGroup& group,
+ cmOStringStream& out);
+
+ /// Create the "choice" XML element to describe a component for the
+ /// installer GUI.
+ void CreateChoice(const cmCPackComponent& component,
+ cmOStringStream& out);
+
+ // Escape the given string to make it usable as an XML attribute
+ // value.
+ std::string EscapeForXML(std::string str);
+
+ double PackageMakerVersion;
+ double PackageCompatibilityVersion;
+};
+
+#endif
diff --git a/Source/CPack/cmCPackRPMGenerator.cxx b/Source/CPack/cmCPackRPMGenerator.cxx
new file mode 100644
index 000000000..413572ee7
--- /dev/null
+++ b/Source/CPack/cmCPackRPMGenerator.cxx
@@ -0,0 +1,275 @@
+/*============================================================================
+ 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 "cmCPackRPMGenerator.h"
+#include "cmCPackLog.h"
+#include "cmSystemTools.h"
+
+//----------------------------------------------------------------------
+cmCPackRPMGenerator::cmCPackRPMGenerator()
+{
+}
+
+//----------------------------------------------------------------------
+cmCPackRPMGenerator::~cmCPackRPMGenerator()
+{
+}
+
+//----------------------------------------------------------------------
+int cmCPackRPMGenerator::InitializeInternal()
+{
+ this->SetOptionIfNotSet("CPACK_PACKAGING_INSTALL_PREFIX", "/usr");
+ if (cmSystemTools::IsOff(this->GetOption("CPACK_SET_DESTDIR")))
+ {
+ this->SetOption("CPACK_SET_DESTDIR", "I_ON");
+ }
+ /* Replace space in CPACK_PACKAGE_NAME in order to avoid
+ * rpmbuild scream on unwanted space in filename issue
+ * Moreover RPM file do not usually embed space in filename
+ */
+ if (this->GetOption("CPACK_PACKAGE_NAME")) {
+ std::string packageName=this->GetOption("CPACK_PACKAGE_NAME");
+ cmSystemTools::ReplaceString(packageName," ","-");
+ this->SetOption("CPACK_PACKAGE_NAME",packageName.c_str());
+ }
+ /* same for CPACK_PACKAGE_FILE_NAME */
+ if (this->GetOption("CPACK_PACKAGE_FILE_NAME")) {
+ std::string packageName=this->GetOption("CPACK_PACKAGE_FILE_NAME");
+ cmSystemTools::ReplaceString(packageName," ","-");
+ this->SetOption("CPACK_PACKAGE_FILE_NAME",packageName.c_str());
+ }
+ return this->Superclass::InitializeInternal();
+}
+
+//----------------------------------------------------------------------
+int cmCPackRPMGenerator::PackageOnePack(std::string initialToplevel,
+ std::string packageName)
+{
+ int retval = 1;
+ // Begin the archive for this pack
+ std::string localToplevel(initialToplevel);
+ std::string packageFileName(
+ cmSystemTools::GetParentDirectory(toplevel.c_str())
+ );
+ std::string outputFileName(
+ GetComponentPackageFileName(this->GetOption("CPACK_PACKAGE_FILE_NAME"),
+ packageName,
+ true)
+ + this->GetOutputExtension()
+ );
+
+ localToplevel += "/"+ packageName;
+ /* replace the TEMP DIRECTORY with the component one */
+ this->SetOption("CPACK_TEMPORARY_DIRECTORY",localToplevel.c_str());
+ packageFileName += "/"+ outputFileName;
+ /* replace proposed CPACK_OUTPUT_FILE_NAME */
+ this->SetOption("CPACK_OUTPUT_FILE_NAME",outputFileName.c_str());
+ /* replace the TEMPORARY package file name */
+ this->SetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME",
+ packageFileName.c_str());
+ // Tell CPackRPM.cmake the name of the component NAME.
+ this->SetOption("CPACK_RPM_PACKAGE_COMPONENT",packageName.c_str());
+ if (!this->ReadListFile("CPackRPM.cmake"))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error while execution CPackRPM.cmake" << std::endl);
+ retval = 0;
+ }
+ // add the generated package to package file names list
+ packageFileNames.push_back(packageFileName);
+ return retval;
+}
+
+//----------------------------------------------------------------------
+int cmCPackRPMGenerator::PackageComponents(bool ignoreGroup)
+{
+ int retval = 1;
+ /* Reset package file name list it will be populated during the
+ * component packaging run*/
+ packageFileNames.clear();
+ std::string initialTopLevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY"));
+
+ // The default behavior is to have one package by component group
+ // unless CPACK_COMPONENTS_IGNORE_GROUP is specified.
+ if (!ignoreGroup)
+ {
+ std::map<std::string, cmCPackComponentGroup>::iterator compGIt;
+ for (compGIt=this->ComponentGroups.begin();
+ compGIt!=this->ComponentGroups.end(); ++compGIt)
+ {
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Packaging component group: "
+ << compGIt->first
+ << std::endl);
+ retval &= PackageOnePack(initialTopLevel,compGIt->first);
+ }
+ // Handle Orphan components (components not belonging to any groups)
+ std::map<std::string, cmCPackComponent>::iterator compIt;
+ for (compIt=this->Components.begin();
+ compIt!=this->Components.end(); ++compIt )
+ {
+ // Does the component belong to a group?
+ if (compIt->second.Group==NULL)
+ {
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE,
+ "Component <"
+ << compIt->second.Name
+ << "> does not belong to any group, package it separately."
+ << std::endl);
+ retval &= PackageOnePack(initialTopLevel,compIt->first);
+ }
+ }
+ }
+ // CPACK_COMPONENTS_IGNORE_GROUPS is set
+ // We build 1 package per component
+ else
+ {
+ std::map<std::string, cmCPackComponent>::iterator compIt;
+ for (compIt=this->Components.begin();
+ compIt!=this->Components.end(); ++compIt )
+ {
+ retval &= PackageOnePack(initialTopLevel,compIt->first);
+ }
+ }
+ return retval;
+}
+
+//----------------------------------------------------------------------
+int cmCPackRPMGenerator::PackageComponentsAllInOne()
+{
+ int retval = 1;
+ std::string compInstDirName;
+ /* Reset package file name list it will be populated during the
+ * component packaging run*/
+ packageFileNames.clear();
+ std::string initialTopLevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY"));
+
+ compInstDirName = "ALL_COMPONENTS_IN_ONE";
+
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE,
+ "Packaging all groups in one package..."
+ "(CPACK_COMPONENTS_ALL_[GROUPS_]IN_ONE_PACKAGE is set)"
+ << std::endl);
+
+ // The ALL GROUPS in ONE package case
+ std::string localToplevel(initialTopLevel);
+ std::string packageFileName(
+ cmSystemTools::GetParentDirectory(toplevel.c_str())
+ );
+ std::string outputFileName(
+ std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME"))
+ + this->GetOutputExtension()
+ );
+ // all GROUP in one vs all COMPONENT in one
+ localToplevel += "/"+compInstDirName;
+
+ /* replace the TEMP DIRECTORY with the component one */
+ this->SetOption("CPACK_TEMPORARY_DIRECTORY",localToplevel.c_str());
+ packageFileName += "/"+ outputFileName;
+ /* replace proposed CPACK_OUTPUT_FILE_NAME */
+ this->SetOption("CPACK_OUTPUT_FILE_NAME",outputFileName.c_str());
+ /* replace the TEMPORARY package file name */
+ this->SetOption("CPACK_TEMPORARY_PACKAGE_FILE_NAME",
+ packageFileName.c_str());
+ // Tell CPackRPM.cmake the name of the component GROUP.
+ this->SetOption("CPACK_RPM_PACKAGE_COMPONENT",compInstDirName.c_str());
+ if (!this->ReadListFile("CPackRPM.cmake"))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error while execution CPackRPM.cmake" << std::endl);
+ retval = 0;
+ }
+ // add the generated package to package file names list
+ packageFileNames.push_back(packageFileName);
+
+ return retval;
+}
+
+//----------------------------------------------------------------------
+int cmCPackRPMGenerator::PackageFiles()
+{
+ int retval = 1;
+
+ cmCPackLogger(cmCPackLog::LOG_DEBUG, "Toplevel: "
+ << toplevel << std::endl);
+
+ /* Are we in the component packaging case */
+ if (WantsComponentInstallation()) {
+ // CASE 1 : COMPONENT ALL-IN-ONE package
+ // If ALL COMPONENTS in ONE package has been requested
+ // then the package file is unique and should be open here.
+ if (componentPackageMethod == ONE_PACKAGE)
+ {
+ return PackageComponentsAllInOne();
+ }
+ // CASE 2 : COMPONENT CLASSICAL package(s) (i.e. not all-in-one)
+ // There will be 1 package for each component group
+ // however one may require to ignore component group and
+ // in this case you'll get 1 package for each component.
+ else
+ {
+ return PackageComponents(componentPackageMethod ==
+ ONE_PACKAGE_PER_COMPONENT);
+ }
+ }
+ // CASE 3 : NON COMPONENT package.
+ else
+ {
+ if (!this->ReadListFile("CPackRPM.cmake"))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error while execution CPackRPM.cmake" << std::endl);
+ retval = 0;
+ }
+ }
+
+ if (!this->IsSet("RPMBUILD_EXECUTABLE"))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find rpmbuild" << std::endl);
+ retval = 0;
+ }
+ return retval;
+}
+
+bool cmCPackRPMGenerator::SupportsComponentInstallation() const
+ {
+ if (IsOn("CPACK_RPM_COMPONENT_INSTALL"))
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+std::string cmCPackRPMGenerator::GetComponentInstallDirNameSuffix(
+ const std::string& componentName)
+ {
+ if (componentPackageMethod == ONE_PACKAGE_PER_COMPONENT) {
+ return componentName;
+ }
+
+ if (componentPackageMethod == ONE_PACKAGE) {
+ return std::string("ALL_COMPONENTS_IN_ONE");
+ }
+ // We have to find the name of the COMPONENT GROUP
+ // the current COMPONENT belongs to.
+ std::string groupVar = "CPACK_COMPONENT_" +
+ cmSystemTools::UpperCase(componentName) + "_GROUP";
+ if (NULL != GetOption(groupVar.c_str()))
+ {
+ return std::string(GetOption(groupVar.c_str()));
+ }
+ else
+ {
+ return componentName;
+ }
+ }
diff --git a/Source/CPack/cmCPackRPMGenerator.h b/Source/CPack/cmCPackRPMGenerator.h
new file mode 100644
index 000000000..a7722bc58
--- /dev/null
+++ b/Source/CPack/cmCPackRPMGenerator.h
@@ -0,0 +1,77 @@
+/*============================================================================
+ 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 cmCPackRPMGenerator_h
+#define cmCPackRPMGenerator_h
+
+
+#include "cmCPackGenerator.h"
+
+/** \class cmCPackRPMGenerator
+ * \brief A generator for RPM packages
+ * The idea of the CPack RPM generator is to use
+ * as minimal C++ code as possible.
+ * Ideally the C++ part of the CPack RPM generator
+ * will only 'execute' (aka ->ReadListFile) several
+ * CMake macros files.
+ */
+class cmCPackRPMGenerator : public cmCPackGenerator
+{
+public:
+ cmCPackTypeMacro(cmCPackRPMGenerator, cmCPackGenerator);
+
+ /**
+ * Construct generator
+ */
+ cmCPackRPMGenerator();
+ virtual ~cmCPackRPMGenerator();
+
+ static bool CanGenerate()
+ {
+#ifdef __APPLE__
+ // on MacOS enable CPackRPM iff rpmbuild is found
+ std::vector<std::string> locations;
+ locations.push_back("/sw/bin"); // Fink
+ locations.push_back("/opt/local/bin"); // MacPorts
+ return cmSystemTools::FindProgram("rpmbuild") != "" ? true : false;
+#else
+ // legacy behavior on other systems
+ return true;
+#endif
+ }
+
+protected:
+ virtual int InitializeInternal();
+ virtual int PackageFiles();
+ /**
+ * This method factors out the work done in component packaging case.
+ */
+ int PackageOnePack(std::string initialToplevel, std::string packageName);
+ /**
+ * The method used to package files when component
+ * install is used. This will create one
+ * archive for each component group.
+ */
+ int PackageComponents(bool ignoreGroup);
+ /**
+ * Special case of component install where all
+ * components will be put in a single installer.
+ */
+ int PackageComponentsAllInOne();
+ virtual const char* GetOutputExtension() { return ".rpm"; }
+ virtual bool SupportsComponentInstallation() const;
+ virtual std::string GetComponentInstallDirNameSuffix(
+ const std::string& componentName);
+
+};
+
+#endif
diff --git a/Source/CPack/cmCPackSTGZGenerator.cxx b/Source/CPack/cmCPackSTGZGenerator.cxx
new file mode 100644
index 000000000..966a231b7
--- /dev/null
+++ b/Source/CPack/cmCPackSTGZGenerator.cxx
@@ -0,0 +1,138 @@
+/*============================================================================
+ 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 "cmCPackSTGZGenerator.h"
+
+#include "cmake.h"
+#include "cmGlobalGenerator.h"
+#include "cmLocalGenerator.h"
+#include "cmSystemTools.h"
+#include "cmMakefile.h"
+#include "cmCPackLog.h"
+
+#include <cmsys/ios/sstream>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+//----------------------------------------------------------------------
+cmCPackSTGZGenerator::cmCPackSTGZGenerator()
+{
+}
+
+//----------------------------------------------------------------------
+cmCPackSTGZGenerator::~cmCPackSTGZGenerator()
+{
+}
+
+//----------------------------------------------------------------------
+int cmCPackSTGZGenerator::InitializeInternal()
+{
+ this->SetOptionIfNotSet("CPACK_INCLUDE_TOPLEVEL_DIRECTORY", "0");
+
+ std::string inFile = this->FindTemplate("CPack.STGZ_Header.sh.in");
+ if ( inFile.empty() )
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot find template file: "
+ << inFile.c_str() << std::endl);
+ return 0;
+ }
+ this->SetOptionIfNotSet("CPACK_STGZ_HEADER_FILE", inFile.c_str());
+ this->SetOptionIfNotSet("CPACK_AT_SIGN", "@");
+
+ return this->Superclass::InitializeInternal();
+}
+
+//----------------------------------------------------------------------
+int cmCPackSTGZGenerator::PackageFiles()
+{
+ bool retval = true;
+ if ( !this->Superclass::PackageFiles() )
+ {
+ return 0;
+ }
+
+ /* TGZ generator (our Superclass) may
+ * have generated several packages (component packaging)
+ * so we must iterate over generated packages.
+ */
+ for (std::vector<std::string>::iterator it=packageFileNames.begin();
+ it != packageFileNames.end(); ++it)
+ {
+ 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 |
+ S_IROTH | S_IWOTH | S_IXOTH
+#endif
+ );
+ }
+ return retval;
+}
+
+//----------------------------------------------------------------------
+int cmCPackSTGZGenerator::GenerateHeader(std::ostream* os)
+{
+ cmCPackLogger(cmCPackLog::LOG_DEBUG, "Writing header" << std::endl);
+ cmsys_ios::ostringstream str;
+ int counter = 0;
+
+ std::string inLicFile = this->GetOption("CPACK_RESOURCE_FILE_LICENSE");
+ std::string line;
+ std::ifstream ilfs(inLicFile.c_str());
+ std::string licenseText;
+ while ( cmSystemTools::GetLineFromStream(ilfs, line) )
+ {
+ licenseText += line + "\n";
+ }
+ this->SetOptionIfNotSet("CPACK_RESOURCE_FILE_LICENSE_CONTENT",
+ licenseText.c_str());
+
+ const char headerLengthTag[] = "###CPACK_HEADER_LENGTH###";
+
+ // Create the header
+ std::string inFile = this->GetOption("CPACK_STGZ_HEADER_FILE");
+ std::ifstream ifs(inFile.c_str());
+ std::string packageHeaderText;
+ while ( cmSystemTools::GetLineFromStream(ifs, line) )
+ {
+ packageHeaderText += line + "\n";
+ }
+
+ // Configure in the values
+ std::string res;
+ this->ConfigureString(packageHeaderText, res);
+
+ // Count the lines
+ const char* ptr = res.c_str();
+ while ( *ptr )
+ {
+ if ( *ptr == '\n' )
+ {
+ counter ++;
+ }
+ ++ptr;
+ }
+ counter ++;
+ cmCPackLogger(cmCPackLog::LOG_DEBUG,
+ "Number of lines: " << counter << std::endl);
+ char buffer[1024];
+ sprintf(buffer, "%d", counter);
+ cmSystemTools::ReplaceString(res, headerLengthTag, buffer);
+
+ // Write in file
+ *os << res.c_str();
+ return this->Superclass::GenerateHeader(os);
+}
diff --git a/Source/CPack/cmCPackSTGZGenerator.h b/Source/CPack/cmCPackSTGZGenerator.h
new file mode 100644
index 000000000..ccceec806
--- /dev/null
+++ b/Source/CPack/cmCPackSTGZGenerator.h
@@ -0,0 +1,41 @@
+/*============================================================================
+ 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 cmCPackSTGZGenerator_h
+#define cmCPackSTGZGenerator_h
+
+
+#include "cmCPackTGZGenerator.h"
+
+/** \class cmCPackSTGZGenerator
+ * \brief A generator for Self extractable TGZ files
+ *
+ */
+class cmCPackSTGZGenerator : public cmCPackTGZGenerator
+{
+public:
+ cmCPackTypeMacro(cmCPackSTGZGenerator, cmCPackTGZGenerator);
+
+ /**
+ * Construct generator
+ */
+ cmCPackSTGZGenerator();
+ virtual ~cmCPackSTGZGenerator();
+
+protected:
+ int PackageFiles();
+ virtual int InitializeInternal();
+ int GenerateHeader(std::ostream* os);
+ virtual const char* GetOutputExtension() { return ".sh"; }
+};
+
+#endif
diff --git a/Source/CPack/cmCPackTGZGenerator.cxx b/Source/CPack/cmCPackTGZGenerator.cxx
new file mode 100644
index 000000000..509c7f80a
--- /dev/null
+++ b/Source/CPack/cmCPackTGZGenerator.cxx
@@ -0,0 +1,26 @@
+/*============================================================================
+ 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 "cmCPackTGZGenerator.h"
+
+//----------------------------------------------------------------------
+cmCPackTGZGenerator::cmCPackTGZGenerator()
+ :cmCPackArchiveGenerator(cmArchiveWrite::CompressGZip,
+ cmArchiveWrite::TypeTAR)
+{
+}
+
+//----------------------------------------------------------------------
+cmCPackTGZGenerator::~cmCPackTGZGenerator()
+{
+}
+
diff --git a/Source/CPack/cmCPackTGZGenerator.h b/Source/CPack/cmCPackTGZGenerator.h
new file mode 100644
index 000000000..3a9fc6b41
--- /dev/null
+++ b/Source/CPack/cmCPackTGZGenerator.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 cmCPackTGZGenerator_h
+#define cmCPackTGZGenerator_h
+
+#include "cmCPackArchiveGenerator.h"
+
+/** \class cmCPackTGZGenerator
+ * \brief A generator for TGZ files
+ *
+ */
+class cmCPackTGZGenerator : public cmCPackArchiveGenerator
+{
+public:
+ cmCPackTypeMacro(cmCPackTGZGenerator, cmCPackArchiveGenerator);
+ /**
+ * Construct generator
+ */
+ cmCPackTGZGenerator();
+ virtual ~cmCPackTGZGenerator();
+protected:
+ virtual const char* GetOutputExtension() { return ".tar.gz"; }
+};
+
+#endif
diff --git a/Source/CPack/cmCPackTarBZip2Generator.cxx b/Source/CPack/cmCPackTarBZip2Generator.cxx
new file mode 100644
index 000000000..971d16667
--- /dev/null
+++ b/Source/CPack/cmCPackTarBZip2Generator.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 "cmCPackTarBZip2Generator.h"
+//----------------------------------------------------------------------
+cmCPackTarBZip2Generator::cmCPackTarBZip2Generator()
+ :cmCPackArchiveGenerator(cmArchiveWrite::CompressBZip2,
+ cmArchiveWrite::TypeTAR)
+{
+}
+
+//----------------------------------------------------------------------
+cmCPackTarBZip2Generator::~cmCPackTarBZip2Generator()
+{
+}
+
diff --git a/Source/CPack/cmCPackTarBZip2Generator.h b/Source/CPack/cmCPackTarBZip2Generator.h
new file mode 100644
index 000000000..74c244e5a
--- /dev/null
+++ b/Source/CPack/cmCPackTarBZip2Generator.h
@@ -0,0 +1,34 @@
+/*============================================================================
+ 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 cmCPackTarBZip2Generator_h
+#define cmCPackTarBZip2Generator_h
+
+#include "cmCPackArchiveGenerator.h"
+
+/** \class cmCPackTarBZip2Generator
+ * \brief A generator for TarBZip2 files
+ */
+class cmCPackTarBZip2Generator : public cmCPackArchiveGenerator
+{
+public:
+ cmCPackTypeMacro(cmCPackTarBZip2Generator, cmCPackArchiveGenerator);
+ /**
+ * Construct generator
+ */
+ cmCPackTarBZip2Generator();
+ virtual ~cmCPackTarBZip2Generator();
+protected:
+ virtual const char* GetOutputExtension() { return ".tar.bz2"; }
+};
+
+#endif
diff --git a/Source/CPack/cmCPackTarCompressGenerator.cxx b/Source/CPack/cmCPackTarCompressGenerator.cxx
new file mode 100644
index 000000000..7a8f697c0
--- /dev/null
+++ b/Source/CPack/cmCPackTarCompressGenerator.cxx
@@ -0,0 +1,26 @@
+/*============================================================================
+ 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 "cmCPackTarCompressGenerator.h"
+
+//----------------------------------------------------------------------
+cmCPackTarCompressGenerator::cmCPackTarCompressGenerator()
+ :cmCPackArchiveGenerator(cmArchiveWrite::CompressCompress,
+ cmArchiveWrite::TypeTAR)
+{
+}
+
+//----------------------------------------------------------------------
+cmCPackTarCompressGenerator::~cmCPackTarCompressGenerator()
+{
+}
+
diff --git a/Source/CPack/cmCPackTarCompressGenerator.h b/Source/CPack/cmCPackTarCompressGenerator.h
new file mode 100644
index 000000000..7ff9a0ade
--- /dev/null
+++ b/Source/CPack/cmCPackTarCompressGenerator.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 cmCPackTarCompressGenerator_h
+#define cmCPackTarCompressGenerator_h
+
+#include "cmCPackTGZGenerator.h"
+
+/** \class cmCPackTarCompressGenerator
+ * \brief A generator for TarCompress files
+ */
+class cmCPackTarCompressGenerator : public cmCPackArchiveGenerator
+{
+public:
+ cmCPackTypeMacro(cmCPackTarCompressGenerator, cmCPackArchiveGenerator);
+ /**
+ * Construct generator
+ */
+ cmCPackTarCompressGenerator();
+ virtual ~cmCPackTarCompressGenerator();
+
+protected:
+ virtual const char* GetOutputExtension() { return ".tar.Z"; }
+};
+
+#endif
diff --git a/Source/CPack/cmCPackZIPGenerator.cxx b/Source/CPack/cmCPackZIPGenerator.cxx
new file mode 100644
index 000000000..e6e4e77d0
--- /dev/null
+++ b/Source/CPack/cmCPackZIPGenerator.cxx
@@ -0,0 +1,26 @@
+/*============================================================================
+ 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 "cmCPackZIPGenerator.h"
+
+//----------------------------------------------------------------------
+cmCPackZIPGenerator::cmCPackZIPGenerator()
+ :cmCPackArchiveGenerator(cmArchiveWrite::CompressNone,
+ cmArchiveWrite::TypeZIP)
+{
+}
+
+//----------------------------------------------------------------------
+cmCPackZIPGenerator::~cmCPackZIPGenerator()
+{
+}
+
diff --git a/Source/CPack/cmCPackZIPGenerator.h b/Source/CPack/cmCPackZIPGenerator.h
new file mode 100644
index 000000000..70e1a5fa8
--- /dev/null
+++ b/Source/CPack/cmCPackZIPGenerator.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 cmCPackZIPGenerator_h
+#define cmCPackZIPGenerator_h
+
+#include "cmCPackArchiveGenerator.h"
+
+/** \class cmCPackZIPGenerator
+ * \brief A generator for ZIP files
+ */
+class cmCPackZIPGenerator : public cmCPackArchiveGenerator
+{
+public:
+ cmCPackTypeMacro(cmCPackZIPGenerator, cmCPackArchiveGenerator);
+
+ /**
+ * Construct generator
+ */
+ cmCPackZIPGenerator();
+ virtual ~cmCPackZIPGenerator();
+
+protected:
+ virtual const char* GetOutputExtension() { return ".zip"; }
+};
+
+#endif
diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx
new file mode 100644
index 000000000..b6035854e
--- /dev/null
+++ b/Source/CPack/cpack.cxx
@@ -0,0 +1,601 @@
+/*============================================================================
+ 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"
+
+// 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 <memory> // auto_ptr
+
+//----------------------------------------------------------------------------
+static const char * cmDocumentationName[][3] =
+{
+ {0,
+ " cpack - Packaging driver provided by CMake.", 0},
+ {0,0,0}
+};
+
+//----------------------------------------------------------------------------
+static const char * cmDocumentationUsage[][3] =
+{
+ {0,
+ " cpack -G <generator> [options]",
+ 0},
+ {0,0,0}
+};
+
+//----------------------------------------------------------------------------
+static const char * cmDocumentationDescription[][3] =
+{
+ {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}
+};
+
+//----------------------------------------------------------------------------
+int cpackUnknownArgument(const char*, void*)
+{
+ return 1;
+}
+
+//----------------------------------------------------------------------------
+struct cpackDefinitions
+{
+ typedef std::map<cmStdString, cmStdString> MapType;
+ MapType Map;
+ cmCPackLog *Log;
+};
+
+//----------------------------------------------------------------------------
+int cpackDefinitionArgument(const char* argument, const char* cValue,
+ void* call_data)
+{
+ (void)argument;
+ cpackDefinitions* def = static_cast<cpackDefinitions*>(call_data);
+ std::string value = cValue;
+ size_t pos = value.find_first_of("=");
+ if ( pos == std::string::npos )
+ {
+ cmCPack_Log(def->Log, cmCPackLog::LOG_ERROR,
+ "Please specify CPack definitions as: KEY=VALUE" << std::endl);
+ return 0;
+ }
+ std::string key = value.substr(0, pos);
+ 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);
+ return 1;
+}
+
+
+//----------------------------------------------------------------------------
+// this is CPack.
+int main (int argc, char *argv[])
+{
+ cmSystemTools::FindExecutableDirectory(argv[0]);
+ cmCPackLog log;
+ int nocwd = 0;
+
+ log.SetErrorPrefix("CPack Error: ");
+ log.SetWarningPrefix("CPack Warning: ");
+ log.SetOutputPrefix("CPack: ");
+ log.SetVerbosePrefix("CPack Verbose: ");
+
+ cmSystemTools::EnableMSVCDebugHook();
+
+ if ( cmSystemTools::GetCurrentWorkingDirectory().size() == 0 )
+ {
+ cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
+ "Current working directory cannot be established." << std::endl);
+ nocwd = 1;
+ }
+
+ std::string generator;
+ bool help = false;
+ bool helpVersion = false;
+ bool verbose = false;
+ bool debug = false;
+ std::string helpFull;
+ std::string helpMAN;
+ std::string helpHTML;
+
+ std::string cpackProjectName;
+ std::string cpackProjectDirectory;
+ std::string cpackBuildConfig;
+ std::string cpackProjectVersion;
+ std::string cpackProjectPatch;
+ std::string cpackProjectVendor;
+ std::string cpackConfigFile;
+
+ cpackDefinitions definitions;
+ definitions.Log = &log;
+
+ cpackConfigFile = "";
+
+ cmsys::CommandLineArguments arg;
+ arg.Initialize(argc, argv);
+ typedef cmsys::CommandLineArguments argT;
+ // Help arguments
+ arg.AddArgument("--help", argT::NO_ARGUMENT, &help, "CPack help");
+ arg.AddArgument("--help-full", argT::SPACE_ARGUMENT, &helpFull,
+ "CPack help");
+ arg.AddArgument("--help-html", argT::SPACE_ARGUMENT, &helpHTML,
+ "CPack help");
+ arg.AddArgument("--help-man", argT::SPACE_ARGUMENT, &helpMAN, "CPack help");
+ arg.AddArgument("--version", argT::NO_ARGUMENT, &helpVersion, "CPack help");
+
+ arg.AddArgument("-V", argT::NO_ARGUMENT, &verbose, "CPack verbose");
+ arg.AddArgument("--verbose", argT::NO_ARGUMENT, &verbose, "-V");
+ arg.AddArgument("--debug", argT::NO_ARGUMENT, &debug, "-V");
+ arg.AddArgument("--config", argT::SPACE_ARGUMENT, &cpackConfigFile,
+ "CPack configuration file");
+ arg.AddArgument("-C", argT::SPACE_ARGUMENT, &cpackBuildConfig,
+ "CPack build configuration");
+ arg.AddArgument("-G", argT::SPACE_ARGUMENT,
+ &generator, "CPack generator");
+ arg.AddArgument("-P", argT::SPACE_ARGUMENT,
+ &cpackProjectName, "CPack project name");
+ arg.AddArgument("-R", argT::SPACE_ARGUMENT,
+ &cpackProjectVersion, "CPack project version");
+ arg.AddArgument("-B", argT::SPACE_ARGUMENT,
+ &cpackProjectDirectory, "CPack project directory");
+ arg.AddArgument("--patch", argT::SPACE_ARGUMENT,
+ &cpackProjectPatch, "CPack project patch");
+ arg.AddArgument("--vendor", argT::SPACE_ARGUMENT,
+ &cpackProjectVendor, "CPack project vendor");
+ arg.AddCallback("-D", argT::SPACE_ARGUMENT,
+ cpackDefinitionArgument, &definitions, "CPack Definitions");
+ arg.SetUnknownArgumentCallback(cpackUnknownArgument);
+
+ // Parse command line
+ int parsed = arg.Parse();
+
+ // Setup logging
+ if ( verbose )
+ {
+ log.SetVerbose(verbose);
+ cmCPack_Log(&log, cmCPackLog::LOG_OUTPUT, "Enable Verbose" << std::endl);
+ }
+ if ( debug )
+ {
+ log.SetDebug(debug);
+ cmCPack_Log(&log, cmCPackLog::LOG_OUTPUT, "Enable Debug" << std::endl);
+ }
+
+ cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE,
+ "Read CPack config file: " << cpackConfigFile.c_str() << std::endl);
+
+ cmake cminst;
+ cminst.RemoveUnscriptableCommands();
+ cmGlobalGenerator cmgg;
+ cmgg.SetCMakeInstance(&cminst);
+ std::auto_ptr<cmLocalGenerator> cmlg(cmgg.CreateLocalGenerator());
+ cmMakefile* globalMF = cmlg->GetMakefile();
+
+ bool cpackConfigFileSpecified = true;
+ if ( cpackConfigFile.empty() )
+ {
+ cpackConfigFile = cmSystemTools::GetCurrentWorkingDirectory();
+ cpackConfigFile += "/CPackConfig.cmake";
+ cpackConfigFileSpecified = false;
+ }
+
+ cmCPackGeneratorFactory generators;
+ generators.SetLogger(&log);
+ cmCPackGenerator* cpackGenerator = 0;
+
+ cmDocumentation doc;
+ doc.addCPackStandardDocSections();
+ /* Were we invoked to display doc or to do some work ?
+ * Unlike cmake launching cpack with zero argument
+ * should launch cpack using "cpackConfigFile" if it exists
+ * in the current directory.
+ */
+ if((doc.CheckOptions(argc, argv,"-G") || nocwd) && !(argc==1))
+ {
+ help = true;
+ }
+ else
+ {
+ help = false;
+ }
+
+ // This part is used for cpack documentation lookup as well.
+ cminst.AddCMakePaths();
+
+ if ( parsed && !help )
+ {
+ // find out which system cpack is running on, so it can setup the search
+ // paths, so FIND_XXX() commands can be used in scripts
+ std::string systemFile =
+ globalMF->GetModulesFile("CMakeDetermineSystem.cmake");
+ if (!globalMF->ReadListFile(0, systemFile.c_str()))
+ {
+ cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
+ "Error reading CMakeDetermineSystem.cmake" << std::endl);
+ return 1;
+ }
+
+ systemFile =
+ globalMF->GetModulesFile("CMakeSystemSpecificInformation.cmake");
+ if (!globalMF->ReadListFile(0, systemFile.c_str()))
+ {
+ cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
+ "Error reading CMakeSystemSpecificInformation.cmake" << std::endl);
+ return 1;
+ }
+
+ if ( cmSystemTools::FileExists(cpackConfigFile.c_str()) )
+ {
+ cpackConfigFile =
+ cmSystemTools::CollapseFullPath(cpackConfigFile.c_str());
+ cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE,
+ "Read CPack configuration file: " << cpackConfigFile.c_str()
+ << std::endl);
+ if ( !globalMF->ReadListFile(0, cpackConfigFile.c_str()) )
+ {
+ cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
+ "Problem reading CPack config file: \""
+ << cpackConfigFile.c_str() << "\"" << std::endl);
+ return 1;
+ }
+ }
+ else if ( cpackConfigFileSpecified )
+ {
+ cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
+ "Cannot find CPack config file: \"" << cpackConfigFile.c_str()
+ << "\"" << std::endl);
+ return 1;
+ }
+
+ if ( !generator.empty() )
+ {
+ globalMF->AddDefinition("CPACK_GENERATOR", generator.c_str());
+ }
+ if ( !cpackProjectName.empty() )
+ {
+ globalMF->AddDefinition("CPACK_PACKAGE_NAME", cpackProjectName.c_str());
+ }
+ if ( !cpackProjectVersion.empty() )
+ {
+ globalMF->AddDefinition("CPACK_PACKAGE_VERSION",
+ cpackProjectVersion.c_str());
+ }
+ if ( !cpackProjectVendor.empty() )
+ {
+ globalMF->AddDefinition("CPACK_PACKAGE_VENDOR",
+ cpackProjectVendor.c_str());
+ }
+ // if this is not empty it has been set on the command line
+ // go for it. Command line override values set in config file.
+ if ( !cpackProjectDirectory.empty() )
+ {
+ globalMF->AddDefinition("CPACK_PACKAGE_DIRECTORY",
+ cpackProjectDirectory.c_str());
+ }
+ // The value has not been set on the command line
+ else
+ {
+ // get a default value (current working directory)
+ cpackProjectDirectory = cmsys::SystemTools::GetCurrentWorkingDirectory();
+ // use default value iff no value has been provided by the config file
+ if (!globalMF->IsSet("CPACK_PACKAGE_DIRECTORY"))
+ {
+ globalMF->AddDefinition("CPACK_PACKAGE_DIRECTORY",
+ 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());
+ }
+
+ const char* cpackModulesPath =
+ globalMF->GetDefinition("CPACK_MODULE_PATH");
+ if ( cpackModulesPath )
+ {
+ globalMF->AddDefinition("CMAKE_MODULE_PATH", cpackModulesPath);
+ }
+ const char* genList = globalMF->GetDefinition("CPACK_GENERATOR");
+ if ( !genList )
+ {
+ cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
+ "CPack generator not specified" << std::endl);
+ parsed = 0;
+ }
+ else
+ {
+ std::vector<std::string> generatorsVector;
+ cmSystemTools::ExpandListArgument(genList,
+ generatorsVector);
+ std::vector<std::string>::iterator it;
+ for ( it = generatorsVector.begin();
+ it != generatorsVector.end();
+ ++it )
+ {
+ const char* gen = it->c_str();
+ cmMakefile newMF(*globalMF);
+ cmMakefile* mf = &newMF;
+ cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE,
+ "Specified generator: " << gen << std::endl);
+ if ( parsed && !mf->GetDefinition("CPACK_PACKAGE_NAME") )
+ {
+ cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
+ "CPack project name not specified" << std::endl);
+ parsed = 0;
+ }
+ if (parsed &&
+ !(mf->GetDefinition("CPACK_PACKAGE_VERSION") ||
+ (mf->GetDefinition("CPACK_PACKAGE_VERSION_MAJOR") &&
+ mf->GetDefinition("CPACK_PACKAGE_VERSION_MINOR") &&
+ mf->GetDefinition("CPACK_PACKAGE_VERSION_PATCH"))))
+ {
+ cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
+ "CPack project version not specified" << std::endl
+ << "Specify CPACK_PACKAGE_VERSION, or "
+ "CPACK_PACKAGE_VERSION_MAJOR, "
+ "CPACK_PACKAGE_VERSION_MINOR, and CPACK_PACKAGE_VERSION_PATCH."
+ << std::endl);
+ parsed = 0;
+ }
+ if ( parsed )
+ {
+ cpackGenerator = generators.NewGenerator(gen);
+ if ( !cpackGenerator )
+ {
+ cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
+ "Cannot initialize CPack generator: "
+ << gen << std::endl);
+ parsed = 0;
+ }
+ if ( parsed && !cpackGenerator->Initialize(gen, mf) )
+ {
+ cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
+ "Cannot initialize the generator " << gen << std::endl);
+ parsed = 0;
+ }
+
+ if ( !mf->GetDefinition("CPACK_INSTALL_COMMANDS") &&
+ !mf->GetDefinition("CPACK_INSTALLED_DIRECTORIES") &&
+ !mf->GetDefinition("CPACK_INSTALL_CMAKE_PROJECTS") )
+ {
+ cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
+ "Please specify build tree of the project that uses CMake "
+ "using CPACK_INSTALL_CMAKE_PROJECTS, specify "
+ "CPACK_INSTALL_COMMANDS, or specify "
+ "CPACK_INSTALLED_DIRECTORIES."
+ << std::endl);
+ parsed = 0;
+ }
+ 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);
+ cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE, "For project: "
+ << projName << std::endl);
+
+ const char* projVersion =
+ mf->GetDefinition("CPACK_PACKAGE_VERSION");
+ if ( !projVersion )
+ {
+ const char* projVersionMajor
+ = mf->GetDefinition("CPACK_PACKAGE_VERSION_MAJOR");
+ const char* projVersionMinor
+ = mf->GetDefinition("CPACK_PACKAGE_VERSION_MINOR");
+ const char* projVersionPatch
+ = mf->GetDefinition("CPACK_PACKAGE_VERSION_PATCH");
+ cmOStringStream ostr;
+ ostr << projVersionMajor << "." << projVersionMinor << "."
+ << projVersionPatch;
+ mf->AddDefinition("CPACK_PACKAGE_VERSION",
+ ostr.str().c_str());
+ }
+
+ int res = cpackGenerator->DoPackage();
+ if ( !res )
+ {
+ cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
+ "Error when generating package: " << projName << std::endl);
+ return 1;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* In this case we are building the documentation object
+ * instance in order to create appropriate structure
+ * in order to satisfy the appropriate --help-xxx request
+ */
+ if ( help )
+ {
+ // Construct and print requested documentation.
+
+ 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();
+ generatorIt != generators.GetGeneratorsList().end();
+ ++ generatorIt )
+ {
+ 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
+ }
+
+ if (cmSystemTools::GetErrorOccuredFlag())
+ {
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/Source/CPack/cygwin.readme b/Source/CPack/cygwin.readme
new file mode 100644
index 000000000..88922d3e6
--- /dev/null
+++ b/Source/CPack/cygwin.readme
@@ -0,0 +1,69 @@
+http://cygwin.com/setup.html
+
+
+Need to produce two tar files:
+
+Source-
+
+- create subdirs
+- copy src
+- duplicate src
+- configure files into duplicate src
+ CPack.cygwin-readme.in
+ CPack.cygwin-install.sh.in
+ CPack.setup.hint.in
+- diff duplicate src and orig src
+- write diff into toplevel
+- create tar file call super class
+
+cmake-2.2.3-1
+
+
+1. a source release
+cmake-2.2.3-2-src.tar.bz2
+
+cmake-2.2.3-2.patch has cmake-2.2.3/CYGWIN-PATCHES/cmake.README cmake-2.2.3/CYGWIN-PATCHES/setup.hint
+cmake-2.2.3-2.sh -> script to create cygwin release
+cmake-2.2.3.tar.bz2 -> unmodified cmake sources for 2.2.3
+
+
+
+
+
+2 a binary release
+cmake-2.2.3-2.tar.bz2
+
+normal binary release with use as the root of the tree:
+
+Here is the bootstrap command used:
+
+ ${SOURCE_DIR}/bootstrap --prefix=/usr --datadir=/share/cmake-${VER} \
+ --docdir=/share/doc/cmake-${VER} --mandir=/share/man
+
+CMAKE_DOC_DIR /share/doc/${PKG}-${VER}
+CMAKE_MAN_DIR /share/man
+CMAKE_DATA_DIR /share/${PKG}-${VER}
+
+Here is the directory stucture:
+
+usr/bin/cmake.exe
+usr/share/doc/cmake-2.2.3/MANIFEST ***
+usr/share/doc/Cygwin/cmake-2.2.3-2.README ****
+usr/share/cmake-2.2.3/Modules
+
+
+
+usr/bin
+usr/share/cmake-2.2.3/include
+usr/share/cmake-2.2.3/Modules/Platform
+usr/share/cmake-2.2.3/Modules
+usr/share/cmake-2.2.3/Templates
+usr/share/cmake-2.2.3
+usr/share/doc/cmake-2.2.3
+usr/share/doc/Cygwin
+usr/share/doc
+usr/share/man/man1
+usr/share/man
+usr/share
+usr
+
diff --git a/Source/CTest/cmCTestBZR.cxx b/Source/CTest/cmCTestBZR.cxx
new file mode 100644
index 000000000..381c70ce5
--- /dev/null
+++ b/Source/CTest/cmCTestBZR.cxx
@@ -0,0 +1,523 @@
+/*============================================================================
+ 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 "cmCTestBZR.h"
+
+#include "cmCTest.h"
+#include "cmSystemTools.h"
+#include "cmXMLParser.h"
+#include "cmXMLSafe.h"
+
+#include <cmsys/RegularExpression.hxx>
+
+#include <cm_expat.h>
+
+//----------------------------------------------------------------------------
+extern "C"
+int cmBZRXMLParserUnknownEncodingHandler(void*,
+ const XML_Char *name,
+ XML_Encoding *info)
+{
+ static const int latin1[]=
+ {
+ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
+ 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
+ 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
+ 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
+ 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
+ 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
+ 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
+ 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
+ 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
+ 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
+ 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
+ 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
+ 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
+ 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
+ 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
+ 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
+ 0x20AC, 0x0081, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
+ 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x008D, 0x017D, 0x008F,
+ 0x0090, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+ 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x009D, 0x017E, 0x0178,
+ 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
+ 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+ 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
+ 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
+ 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
+ 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
+ 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
+ 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
+ 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
+ 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
+ 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF
+ };
+
+ // The BZR xml output plugin can use some encodings that are not
+ // recognized by expat. This will lead to an error, e.g. "Error
+ // parsing bzr log xml: unknown encoding", the following is a
+ // workaround for these unknown encodings.
+ if(name == std::string("ascii") || name == std::string("cp1252") ||
+ name == std::string("ANSI_X3.4-1968"))
+ {
+ for(unsigned int i=0;i<256;++i) info->map[i] = latin1[i];
+ return 1;
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+cmCTestBZR::cmCTestBZR(cmCTest* ct, std::ostream& log):
+ cmCTestGlobalVC(ct, log)
+{
+ this->PriorRev = this->Unknown;
+ // Even though it is specified in the documention, with bzr 1.13
+ // BZR_PROGRESS_BAR has no effect. In the future this bug might be fixed.
+ // Since it doesn't hurt, we specify this environment variable.
+ cmSystemTools::PutEnv("BZR_PROGRESS_BAR=none");
+}
+
+//----------------------------------------------------------------------------
+cmCTestBZR::~cmCTestBZR()
+{
+}
+
+//----------------------------------------------------------------------------
+class cmCTestBZR::InfoParser: public cmCTestVC::LineParser
+{
+public:
+ InfoParser(cmCTestBZR* bzr, const char* prefix):
+ BZR(bzr), CheckOutFound(false)
+ {
+ this->SetLog(&bzr->Log, prefix);
+ this->RegexCheckOut.compile("checkout of branch: *([^\t\r\n]+)$");
+ this->RegexParent.compile("parent branch: *([^\t\r\n]+)$");
+ }
+private:
+ cmCTestBZR* BZR;
+ bool CheckOutFound;
+ cmsys::RegularExpression RegexCheckOut;
+ cmsys::RegularExpression RegexParent;
+ virtual bool ProcessLine()
+ {
+ if(this->RegexCheckOut.find(this->Line))
+ {
+ this->BZR->URL = this->RegexCheckOut.match(1);
+ CheckOutFound = true;
+ }
+ else if(!CheckOutFound && this->RegexParent.find(this->Line))
+ {
+ this->BZR->URL = this->RegexParent.match(1);
+ }
+ return true;
+ }
+};
+
+//----------------------------------------------------------------------------
+class cmCTestBZR::RevnoParser: public cmCTestVC::LineParser
+{
+public:
+ RevnoParser(cmCTestBZR* bzr, const char* prefix, std::string& rev):
+ Rev(rev)
+ {
+ this->SetLog(&bzr->Log, prefix);
+ this->RegexRevno.compile("^([0-9]+)$");
+ }
+private:
+ std::string& Rev;
+ cmsys::RegularExpression RegexRevno;
+ virtual bool ProcessLine()
+ {
+ if(this->RegexRevno.find(this->Line))
+ {
+ this->Rev = this->RegexRevno.match(1);
+ }
+ return true;
+ }
+};
+
+//----------------------------------------------------------------------------
+std::string cmCTestBZR::LoadInfo()
+{
+ // Run "bzr info" to get the repository info from the work tree.
+ const char* bzr = this->CommandLineTool.c_str();
+ const char* bzr_info[] = {bzr, "info", 0};
+ InfoParser iout(this, "info-out> ");
+ OutputLogger ierr(this->Log, "info-err> ");
+ this->RunChild(bzr_info, &iout, &ierr);
+
+ // Run "bzr revno" to get the repository revision number from the work tree.
+ const char* bzr_revno[] = {bzr, "revno", 0};
+ std::string rev;
+ RevnoParser rout(this, "revno-out> ", rev);
+ OutputLogger rerr(this->Log, "revno-err> ");
+ this->RunChild(bzr_revno, &rout, &rerr);
+
+ return rev;
+}
+
+void cmCTestBZR::NoteOldRevision()
+{
+ this->OldRevision = this->LoadInfo();
+ this->Log << "Revision before update: " << this->OldRevision << "\n";
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " Old revision of repository is: "
+ << this->OldRevision << "\n");
+ this->PriorRev.Rev = this->OldRevision;
+}
+
+//----------------------------------------------------------------------------
+void cmCTestBZR::NoteNewRevision()
+{
+ this->NewRevision = this->LoadInfo();
+ this->Log << "Revision after update: " << this->NewRevision << "\n";
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " New revision of repository is: "
+ << this->NewRevision << "\n");
+ this->Log << "URL = " << this->URL << "\n";
+}
+
+//----------------------------------------------------------------------------
+class cmCTestBZR::LogParser: public cmCTestVC::OutputLogger,
+ private cmXMLParser
+{
+public:
+ LogParser(cmCTestBZR* bzr, const char* prefix):
+ OutputLogger(bzr->Log, prefix), BZR(bzr),
+ EmailRegex("(.*) <([A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+)>")
+ { this->InitializeParser(); }
+ ~LogParser() { this->CleanupParser(); }
+
+ virtual int InitializeParser()
+ {
+ int res = cmXMLParser::InitializeParser();
+ if (res)
+ {
+ XML_SetUnknownEncodingHandler(static_cast<XML_Parser>(this->Parser),
+ cmBZRXMLParserUnknownEncodingHandler, 0);
+ }
+ return res;
+ }
+private:
+ cmCTestBZR* BZR;
+
+ typedef cmCTestBZR::Revision Revision;
+ typedef cmCTestBZR::Change Change;
+ Revision Rev;
+ std::vector<Change> Changes;
+ Change CurChange;
+ std::vector<char> CData;
+
+ cmsys::RegularExpression EmailRegex;
+
+ virtual bool ProcessChunk(const char* data, int length)
+ {
+ this->OutputLogger::ProcessChunk(data, length);
+ this->ParseChunk(data, length);
+ return true;
+ }
+
+ virtual void StartElement(const char* name, const char**)
+ {
+ this->CData.clear();
+ if(strcmp(name, "log") == 0)
+ {
+ 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)
+ {
+ this->CurChange = Change();
+ this->CurChange.Action = 'M';
+ }
+ else if(strcmp(name, "added") == 0)
+ {
+ this->CurChange = Change();
+ this->CurChange = 'A';
+ }
+ else if(strcmp(name, "removed") == 0)
+ {
+ this->CurChange = Change();
+ this->CurChange = 'D';
+ }
+ else if(strcmp(name, "unknown") == 0
+ || strcmp(name, "conflicts") == 0)
+ {
+ // Should not happen here
+ this->CurChange = Change();
+ }
+ }
+
+ virtual void CharacterDataHandler(const char* data, int length)
+ {
+ this->CData.insert(this->CData.end(), data, data+length);
+ }
+
+ virtual void EndElement(const char* name)
+ {
+ if(strcmp(name, "log") == 0)
+ {
+ this->BZR->DoRevision(this->Rev, this->Changes);
+ }
+ else if((strcmp(name, "file") == 0 || strcmp(name, "directory") == 0)
+ && !this->CData.empty())
+ {
+ 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())
+ {
+ // 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())
+ {
+ this->Rev.Author.assign(&this->CData[0], this->CData.size());
+ if(this->EmailRegex.find(this->Rev.Author))
+ {
+ this->Rev.Author = this->EmailRegex.match(1);
+ this->Rev.EMail = this->EmailRegex.match(2);
+ }
+ }
+ else if(strcmp(name, "timestamp") == 0 && !this->CData.empty())
+ {
+ this->Rev.Date.assign(&this->CData[0], this->CData.size());
+ }
+ else if(strcmp(name, "message") == 0 && !this->CData.empty())
+ {
+ this->Rev.Log.assign(&this->CData[0], this->CData.size());
+ }
+ else if(strcmp(name, "revno") == 0 && !this->CData.empty())
+ {
+ this->Rev.Rev.assign(&this->CData[0], this->CData.size());
+ }
+ this->CData.clear();
+ }
+
+ virtual void ReportError(int, int, const char* msg)
+ {
+ this->BZR->Log << "Error parsing bzr log xml: " << msg << "\n";
+ }
+};
+
+//----------------------------------------------------------------------------
+class cmCTestBZR::UpdateParser: public cmCTestVC::LineParser
+{
+public:
+ UpdateParser(cmCTestBZR* bzr, const char* prefix): BZR(bzr)
+ {
+ this->SetLog(&bzr->Log, prefix);
+ this->RegexUpdate.compile("^([-+R?XCP ])([NDKM ])([* ]) +(.+)$");
+ }
+private:
+ cmCTestBZR* BZR;
+ cmsys::RegularExpression RegexUpdate;
+
+ virtual bool ProcessChunk(const char* first, int length)
+ {
+ bool last_is_new_line = (*first == '\r' || *first == '\n');
+
+ const char* const last = first + length;
+ for(const char* c = first; c != last; ++c)
+ {
+ if(*c == '\r' || *c == '\n')
+ {
+ if(!last_is_new_line)
+ {
+ // Log this line.
+ if(this->Log && this->Prefix)
+ {
+ *this->Log << this->Prefix << this->Line << "\n";
+ }
+
+ // Hand this line to the subclass implementation.
+ if(!this->ProcessLine())
+ {
+ this->Line = "";
+ return false;
+ }
+
+ this->Line = "";
+ last_is_new_line = true;
+ }
+ }
+ else
+ {
+ // Append this character to the line under construction.
+ this->Line.append(1, *c);
+ last_is_new_line = false;
+ }
+ }
+ return true;
+ }
+
+ bool ProcessLine()
+ {
+ if(this->RegexUpdate.find(this->Line))
+ {
+ this->DoPath(this->RegexUpdate.match(1)[0],
+ this->RegexUpdate.match(2)[0],
+ this->RegexUpdate.match(3)[0],
+ this->RegexUpdate.match(4));
+ }
+ return true;
+ }
+
+ void DoPath(char c0, char c1, char c2, std::string path)
+ {
+ if(path.empty()) return;
+ cmSystemTools::ConvertToUnixSlashes(path);
+
+ const std::string dir = cmSystemTools::GetFilenamePath(path);
+ const std::string name = cmSystemTools::GetFilenameName(path);
+
+ if ( c0=='C' )
+ {
+ this->BZR->Dirs[dir][name].Status = PathConflicting;
+ return;
+ }
+
+ if ( c1=='M' || c1=='K' || c1=='N' || c1=='D' || c2 =='*' )
+ {
+ this->BZR->Dirs[dir][name].Status = PathUpdated;
+ return;
+ }
+ }
+};
+
+//----------------------------------------------------------------------------
+bool cmCTestBZR::UpdateImpl()
+{
+ // Get user-specified update options.
+ std::string opts = this->CTest->GetCTestConfiguration("UpdateOptions");
+ if(opts.empty())
+ {
+ opts = this->CTest->GetCTestConfiguration("BZRUpdateOptions");
+ }
+ std::vector<cmStdString> args = cmSystemTools::ParseArguments(opts.c_str());
+
+ // TODO: if(this->CTest->GetTestModel() == cmCTest::NIGHTLY)
+
+ // Use "bzr pull" to update the working tree.
+ std::vector<char const*> bzr_update;
+ bzr_update.push_back(this->CommandLineTool.c_str());
+ bzr_update.push_back("pull");
+
+ for(std::vector<cmStdString>::const_iterator ai = args.begin();
+ ai != args.end(); ++ai)
+ {
+ bzr_update.push_back(ai->c_str());
+ }
+
+ bzr_update.push_back(this->URL.c_str());
+
+ bzr_update.push_back(0);
+
+ // For some reason bzr uses stderr to display the update status.
+ OutputLogger out(this->Log, "pull-out> ");
+ UpdateParser err(this, "pull-err> ");
+ return this->RunUpdateCommand(&bzr_update[0], &out, &err);
+}
+
+//----------------------------------------------------------------------------
+void cmCTestBZR::LoadRevisions()
+{
+ cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ " Gathering version information (one . per revision):\n"
+ " " << std::flush);
+
+ // We are interested in every revision included in the update.
+ this->Revisions.clear();
+ std::string revs;
+ if(atoi(this->OldRevision.c_str()) <= atoi(this->NewRevision.c_str()))
+ {
+ // DoRevision takes care of discarding the information about OldRevision
+ revs = this->OldRevision + ".." + this->NewRevision;
+ }
+ else
+ {
+ return;
+ }
+
+ // Run "bzr log" to get all global revisions of interest.
+ const char* bzr = this->CommandLineTool.c_str();
+ const char* bzr_log[] = {bzr, "log", "-v", "-r", revs.c_str(), "--xml",
+ this->URL.c_str(), 0};
+ {
+ LogParser out(this, "log-out> ");
+ OutputLogger err(this->Log, "log-err> ");
+ this->RunChild(bzr_log, &out, &err);
+ }
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, std::endl);
+}
+
+//----------------------------------------------------------------------------
+class cmCTestBZR::StatusParser: public cmCTestVC::LineParser
+{
+public:
+ StatusParser(cmCTestBZR* bzr, const char* prefix): BZR(bzr)
+ {
+ this->SetLog(&bzr->Log, prefix);
+ this->RegexStatus.compile("^([-+R?XCP ])([NDKM ])([* ]) +(.+)$");
+ }
+private:
+ cmCTestBZR* BZR;
+ cmsys::RegularExpression RegexStatus;
+ bool ProcessLine()
+ {
+ if(this->RegexStatus.find(this->Line))
+ {
+ this->DoPath(this->RegexStatus.match(1)[0],
+ this->RegexStatus.match(2)[0],
+ this->RegexStatus.match(3)[0],
+ this->RegexStatus.match(4));
+ }
+ return true;
+ }
+
+ void DoPath(char c0, char c1, char c2, std::string path)
+ {
+ if(path.empty()) return;
+ cmSystemTools::ConvertToUnixSlashes(path);
+
+ if ( c0=='C' )
+ {
+ this->BZR->DoModification(PathConflicting, path);
+ return;
+ }
+
+ if ( c0 == '+' || c0 == 'R' || c0 == 'P'
+ || c1=='M' || c1=='K' || c1=='N' || c1=='D'
+ || c2 =='*' )
+ {
+ this->BZR->DoModification(PathModified, path);
+ return;
+ }
+ }
+};
+
+//----------------------------------------------------------------------------
+void cmCTestBZR::LoadModifications()
+{
+ // Run "bzr status" which reports local modifications.
+ const char* bzr = this->CommandLineTool.c_str();
+ const char* bzr_status[] = {bzr, "status", "-SV", 0};
+ StatusParser out(this, "status-out> ");
+ OutputLogger err(this->Log, "status-err> ");
+ this->RunChild(bzr_status, &out, &err);
+}
diff --git a/Source/CTest/cmCTestBZR.h b/Source/CTest/cmCTestBZR.h
new file mode 100644
index 000000000..df688e1ee
--- /dev/null
+++ b/Source/CTest/cmCTestBZR.h
@@ -0,0 +1,55 @@
+/*============================================================================
+ 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 cmCTestBZR_h
+#define cmCTestBZR_h
+
+#include "cmCTestGlobalVC.h"
+
+/** \class cmCTestBZR
+ * \brief Interaction with bzr command-line tool
+ *
+ */
+class cmCTestBZR: public cmCTestGlobalVC
+{
+public:
+ /** Construct with a CTest instance and update log stream. */
+ cmCTestBZR(cmCTest* ctest, std::ostream& log);
+
+ virtual ~cmCTestBZR();
+
+private:
+ // Implement cmCTestVC internal API.
+ virtual void NoteOldRevision();
+ virtual void NoteNewRevision();
+ virtual bool UpdateImpl();
+
+ // URL of repository directory checked out in the working tree.
+ std::string URL;
+
+ std::string LoadInfo();
+ void LoadModifications();
+ void LoadRevisions();
+
+ // Parsing helper classes.
+ class InfoParser;
+ class RevnoParser;
+ class LogParser;
+ class UpdateParser;
+ class StatusParser;
+ friend class InfoParser;
+ friend class RevnoParser;
+ friend class LogParser;
+ friend class UpdateParser;
+ friend class StatusParser;
+};
+
+#endif
diff --git a/Source/CTest/cmCTestBatchTestHandler.cxx b/Source/CTest/cmCTestBatchTestHandler.cxx
new file mode 100644
index 000000000..00bb6fa70
--- /dev/null
+++ b/Source/CTest/cmCTestBatchTestHandler.cxx
@@ -0,0 +1,143 @@
+/*============================================================================
+ 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 "cmCTestBatchTestHandler.h"
+#include "cmProcess.h"
+#include "cmStandardIncludes.h"
+#include "cmCTest.h"
+#include "cmSystemTools.h"
+#include <stdlib.h>
+
+cmCTestBatchTestHandler::~cmCTestBatchTestHandler()
+{
+}
+
+//---------------------------------------------------------
+void cmCTestBatchTestHandler::RunTests()
+{
+ this->WriteBatchScript();
+ this->SubmitBatchScript();
+}
+
+//---------------------------------------------------------
+void cmCTestBatchTestHandler::WriteBatchScript()
+{
+ this->Script = this->CTest->GetBinaryDir()
+ + "/Testing/CTestBatch.txt";
+ std::fstream fout;
+ fout.open(this->Script.c_str(), std::ios::out);
+ fout << "#!/bin/sh\n";
+
+ for(TestMap::iterator i = this->Tests.begin(); i != this->Tests.end(); ++i)
+ {
+ this->WriteSrunArgs(i->first, fout);
+ this->WriteTestCommand(i->first, fout);
+ fout << "\n";
+ }
+ fout.flush();
+ fout.close();
+}
+
+//---------------------------------------------------------
+void cmCTestBatchTestHandler::WriteSrunArgs(int test, std::fstream& fout)
+{
+ cmCTestTestHandler::cmCTestTestProperties* properties =
+ this->Properties[test];
+
+ fout << "srun ";
+ //fout << "--jobid=" << test << " ";
+ fout << "-J=" << properties->Name << " ";
+
+ //Write dependency information
+ /*if(this->Tests[test].size() > 0)
+ {
+ fout << "-P=afterany";
+ for(TestSet::iterator i = this->Tests[test].begin();
+ i != this->Tests[test].end(); ++i)
+ {
+ fout << ":" << *i;
+ }
+ fout << " ";
+ }*/
+ if(properties->RunSerial)
+ {
+ fout << "--exclusive ";
+ }
+ if(properties->Processors > 1)
+ {
+ fout << "-n" << properties->Processors << " ";
+ }
+}
+
+//---------------------------------------------------------
+void cmCTestBatchTestHandler::WriteTestCommand(int test, std::fstream& fout)
+{
+ std::vector<std::string> args = this->Properties[test]->Args;
+ std::vector<std::string> processArgs;
+ std::string command;
+
+ command = this->TestHandler->FindTheExecutable(args[1].c_str());
+ command = cmSystemTools::ConvertToOutputPath(command.c_str());
+
+ //Prepends memcheck args to our command string if this is a memcheck
+ this->TestHandler->GenerateTestCommand(processArgs);
+ processArgs.push_back(command);
+
+ for(std::vector<std::string>::iterator arg = processArgs.begin();
+ arg != processArgs.end(); ++arg)
+ {
+ fout << *arg << " ";
+ }
+
+ std::vector<std::string>::iterator i = args.begin();
+ ++i; //the test name
+ ++i; //the executable (command)
+ if(args.size() > 2)
+ {
+ fout << "'";
+ }
+ while(i != args.end())
+ {
+ fout << "\"" << *i << "\""; //args to the test executable
+ ++i;
+
+ if(i == args.end() && args.size() > 2)
+ {
+ fout << "'";
+ }
+ fout << " ";
+ }
+ //TODO ZACH build TestResult.FullCommandLine
+ //this->TestResult.FullCommandLine = this->TestCommand;
+}
+
+//---------------------------------------------------------
+void cmCTestBatchTestHandler::SubmitBatchScript()
+{
+ cmProcess sbatch;
+ std::vector<std::string> args;
+ args.push_back(this->Script);
+ args.push_back("-o");
+ args.push_back(this->CTest->GetBinaryDir()
+ + "/Testing/CTestBatch.txt");
+
+ sbatch.SetCommand("sbatch");
+ sbatch.SetCommandArguments(args);
+ /*if(sbatch.StartProcess())
+ {
+ //success condition
+ }
+ else
+ {
+ //fail condition
+ }*/
+}
diff --git a/Source/CTest/cmCTestBatchTestHandler.h b/Source/CTest/cmCTestBatchTestHandler.h
new file mode 100644
index 000000000..fdfd1be29
--- /dev/null
+++ b/Source/CTest/cmCTestBatchTestHandler.h
@@ -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.
+============================================================================*/
+
+#ifndef cmCTestBatchTestHandler_h
+#define cmCTestBatchTestHandler_h
+
+#include <cmStandardIncludes.h>
+#include <cmCTestTestHandler.h>
+#include <cmCTestMultiProcessHandler.h>
+#include <cmCTestRunTest.h>
+
+/** \class cmCTestBatchTestHandler
+ * \brief run parallel ctest
+ *
+ * cmCTestBatchTestHandler
+ */
+class cmCTestBatchTestHandler : public cmCTestMultiProcessHandler
+{
+public:
+ ~cmCTestBatchTestHandler();
+ virtual void RunTests();
+protected:
+ void WriteBatchScript();
+ void WriteSrunArgs(int test, std::fstream& fout);
+ void WriteTestCommand(int test, std::fstream& fout);
+
+ void SubmitBatchScript();
+
+ std::string Script;
+};
+
+#endif
diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx
new file mode 100644
index 000000000..8a2d65a7b
--- /dev/null
+++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx
@@ -0,0 +1,526 @@
+/*============================================================================
+ 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 "cmCTestBuildAndTestHandler.h"
+
+#include "cmSystemTools.h"
+#include "cmCTest.h"
+#include "cmake.h"
+#include "cmGlobalGenerator.h"
+#include <cmsys/Process.h>
+#include "cmCTestTestHandler.h"
+
+//----------------------------------------------------------------------
+cmCTestBuildAndTestHandler::cmCTestBuildAndTestHandler()
+{
+ this->BuildTwoConfig = false;
+ this->BuildNoClean = false;
+ this->BuildNoCMake = false;
+ this->Timeout = 0;
+}
+
+//----------------------------------------------------------------------
+void cmCTestBuildAndTestHandler::Initialize()
+{
+ this->BuildTargets.erase(
+ this->BuildTargets.begin(), this->BuildTargets.end());
+ this->Superclass::Initialize();
+}
+
+//----------------------------------------------------------------------
+const char* cmCTestBuildAndTestHandler::GetOutput()
+{
+ return this->Output.c_str();
+}
+//----------------------------------------------------------------------
+int cmCTestBuildAndTestHandler::ProcessHandler()
+{
+ this->Output = "";
+ std::string output;
+ cmSystemTools::ResetErrorOccuredFlag();
+ int retv = this->RunCMakeAndTest(&this->Output);
+ cmSystemTools::ResetErrorOccuredFlag();
+ return retv;
+}
+
+//----------------------------------------------------------------------
+int cmCTestBuildAndTestHandler::RunCMake(std::string* outstring,
+ cmOStringStream &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(this->SourceDir);
+ if(this->BuildGenerator.size())
+ {
+ std::string generator = "-G";
+ generator += this->BuildGenerator;
+ args.push_back(generator);
+ }
+
+ const char* config = 0;
+ if ( this->CTest->GetConfigType().size() > 0 )
+ {
+ config = this->CTest->GetConfigType().c_str();
+ }
+#ifdef CMAKE_INTDIR
+ if(!config)
+ {
+ config = CMAKE_INTDIR;
+ }
+#endif
+
+ if ( config )
+ {
+ std::string btype
+ = "-DCMAKE_BUILD_TYPE:STRING=" + std::string(config);
+ args.push_back(btype);
+ }
+
+ for(k=0; k < this->BuildOptions.size(); ++k)
+ {
+ args.push_back(this->BuildOptions[k]);
+ }
+ if (cm->Run(args) != 0)
+ {
+ out << "Error: cmake execution failed\n";
+ out << cmakeOutString << "\n";
+ // return to the original directory
+ cmSystemTools::ChangeDirectory(cwd.c_str());
+ if(outstring)
+ {
+ *outstring = out.str();
+ }
+ else
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, out.str() << std::endl);
+ }
+ return 1;
+ }
+ // do another config?
+ if(this->BuildTwoConfig)
+ {
+ if (cm->Run(args) != 0)
+ {
+ out << "Error: cmake execution failed\n";
+ out << cmakeOutString << "\n";
+ // return to the original directory
+ cmSystemTools::ChangeDirectory(cwd.c_str());
+ if(outstring)
+ {
+ *outstring = out.str();
+ }
+ else
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, out.str() << std::endl);
+ }
+ return 1;
+ }
+ }
+ out << "======== CMake output ======\n";
+ out << cmakeOutString;
+ out << "======== End CMake output ======\n";
+ return 0;
+}
+
+//----------------------------------------------------------------------
+void CMakeMessageCallback(const char* m, const char*, bool&, void* s)
+{
+ std::string* out = (std::string*)s;
+ *out += m;
+ *out += "\n";
+}
+
+void CMakeProgressCallback(const char*msg, float , void * s)
+{
+ std::string* out = (std::string*)s;
+ *out += msg;
+ *out += "\n";
+}
+
+//----------------------------------------------------------------------
+void CMakeStdoutCallback(const char* m, int len, void* s)
+{
+ std::string* out = (std::string*)s;
+ out->append(m, len);
+}
+struct cmSetupOutputCaptureCleanup
+{
+ ~cmSetupOutputCaptureCleanup()
+ {
+ cmSystemTools::SetErrorCallback(0, 0);
+ cmSystemTools::SetStdoutCallback(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(outstring)
+ {
+ *outstring =
+ "--build-and-test requires that both the generator and makeprogram "
+ "be provided using the --build-generator and --build-makeprogram "
+ "command line options. ";
+ }
+ return 1;
+ }
+
+ if ( this->CTest->GetConfigType().size() == 0 &&
+ this->ConfigSample.size())
+ {
+ // use the config sample to set the ConfigType
+ std::string fullPath;
+ std::string resultingConfig;
+ std::vector<std::string> extraPaths;
+ std::vector<std::string> failed;
+ fullPath =
+ cmCTestTestHandler::FindExecutable(this->CTest,
+ this->ConfigSample.c_str(),
+ resultingConfig,
+ extraPaths,
+ failed);
+ if (fullPath.size() && resultingConfig.size())
+ {
+ this->CTest->SetConfigType(resultingConfig.c_str());
+ }
+ out << "Using config sample with results: "
+ << fullPath << " and " << resultingConfig << std::endl;
+ }
+
+ // we need to honor the timeout specified, the timeout include cmake, build
+ // and test time
+ double clock_start = cmSystemTools::GetTime();
+
+ // make sure the binary dir is there
+ std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
+ out << "Internal cmake changing into directory: "
+ << this->BinaryDir << std::endl;
+ if (!cmSystemTools::FileIsDirectory(this->BinaryDir.c_str()))
+ {
+ cmSystemTools::MakeDirectory(this->BinaryDir.c_str());
+ }
+ cmSystemTools::ChangeDirectory(this->BinaryDir.c_str());
+
+ // should we cmake?
+ cmake cm;
+ cm.SetProgressCallback(CMakeProgressCallback, &cmakeOutString);
+ cm.SetGlobalGenerator(cm.CreateGlobalGenerator(
+ this->BuildGenerator.c_str()));
+
+ if(!this->BuildNoCMake)
+ {
+ // do the cmake step, no timeout here since it is not a sub process
+ if (this->RunCMake(outstring,out,cmakeOutString,cwd,&cm))
+ {
+ return 1;
+ }
+ }
+
+ // do the build
+ std::vector<std::string>::iterator tarIt;
+ if ( this->BuildTargets.size() == 0 )
+ {
+ this->BuildTargets.push_back("");
+ }
+ for ( tarIt = this->BuildTargets.begin();
+ tarIt != this->BuildTargets.end(); ++ tarIt )
+ {
+ double remainingTime = 0;
+ if (this->Timeout > 0)
+ {
+ remainingTime = this->Timeout - cmSystemTools::GetTime() + clock_start;
+ if (remainingTime <= 0)
+ {
+ if(outstring)
+ {
+ *outstring = "--build-and-test timeout exceeded. ";
+ }
+ return 1;
+ }
+ }
+ std::string output;
+ const char* config = 0;
+ if ( this->CTest->GetConfigType().size() > 0 )
+ {
+ config = this->CTest->GetConfigType().c_str();
+ }
+#ifdef CMAKE_INTDIR
+ if(!config)
+ {
+ config = CMAKE_INTDIR;
+ }
+#endif
+ if(!config)
+ {
+ 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(),
+ config,
+ !this->BuildNoClean,
+ false, remainingTime);
+ out << output;
+ // if the build failed then return
+ if (retVal)
+ {
+ if(outstring)
+ {
+ *outstring = out.str();
+ }
+ return 1;
+ }
+ }
+ if(outstring)
+ {
+ *outstring = out.str();
+ }
+
+ // if no test was specified then we are done
+ if (!this->TestCommand.size())
+ {
+ return 0;
+ }
+
+ // now run the compiled test if we can find it
+ // store the final location in fullPath
+ std::string fullPath;
+ std::string resultingConfig;
+ std::vector<std::string> extraPaths;
+ // if this->ExecutableDirectory is set try that as well
+ if (this->ExecutableDirectory.size())
+ {
+ std::string tempPath = this->ExecutableDirectory;
+ tempPath += "/";
+ tempPath += this->TestCommand;
+ extraPaths.push_back(tempPath);
+ }
+ std::vector<std::string> failed;
+ fullPath =
+ cmCTestTestHandler::FindExecutable(this->CTest,
+ this->TestCommand.c_str(),
+ resultingConfig,
+ extraPaths,
+ failed);
+
+ if(!cmSystemTools::FileExists(fullPath.c_str()))
+ {
+ out << "Could not find path to executable, perhaps it was not built: "
+ << this->TestCommand << "\n";
+ out << "tried to find it in these places:\n";
+ out << fullPath.c_str() << "\n";
+ for(unsigned int i=0; i < failed.size(); ++i)
+ {
+ out << failed[i] << "\n";
+ }
+ if(outstring)
+ {
+ *outstring = out.str();
+ }
+ else
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, out.str());
+ }
+ // return to the original directory
+ cmSystemTools::ChangeDirectory(cwd.c_str());
+ return 1;
+ }
+
+ std::vector<const char*> testCommand;
+ testCommand.push_back(fullPath.c_str());
+ for(k=0; k < this->TestCommandArgs.size(); ++k)
+ {
+ testCommand.push_back(this->TestCommandArgs[k].c_str());
+ }
+ testCommand.push_back(0);
+ std::string outs;
+ int retval = 0;
+ // run the test from the this->BuildRunDir if set
+ if(this->BuildRunDir.size())
+ {
+ out << "Run test in directory: " << this->BuildRunDir << "\n";
+ cmSystemTools::ChangeDirectory(this->BuildRunDir.c_str());
+ }
+ out << "Running test command: \"" << fullPath << "\"";
+ for(k=0; k < this->TestCommandArgs.size(); ++k)
+ {
+ out << " \"" << this->TestCommandArgs[k] << "\"";
+ }
+ out << "\n";
+
+ // how much time is remaining
+ double remainingTime = 0;
+ if (this->Timeout > 0)
+ {
+ remainingTime = this->Timeout - cmSystemTools::GetTime() + clock_start;
+ if (remainingTime <= 0)
+ {
+ if(outstring)
+ {
+ *outstring = "--build-and-test timeout exceeded. ";
+ }
+ return 1;
+ }
+ }
+
+ int runTestRes = this->CTest->RunTest(testCommand, &outs, &retval, 0,
+ remainingTime, 0);
+
+ if(runTestRes != cmsysProcess_State_Exited || retval != 0)
+ {
+ out << "Test command failed: " << testCommand[0] << "\n";
+ retval = 1;
+ }
+
+ out << outs << "\n";
+ if(outstring)
+ {
+ *outstring = out.str();
+ }
+ else
+ {
+ cmCTestLog(this->CTest, OUTPUT, out.str() << std::endl);
+ }
+ return retval;
+}
+
+//----------------------------------------------------------------------
+int cmCTestBuildAndTestHandler::ProcessCommandLineArguments(
+ const std::string& currentArg, size_t& idx,
+ const std::vector<std::string>& allArgs)
+{
+ // --build-and-test options
+ if(currentArg.find("--build-and-test",0) == 0 && idx < allArgs.size() - 1)
+ {
+ if(idx+2 < allArgs.size())
+ {
+ idx++;
+ this->SourceDir = allArgs[idx];
+ idx++;
+ this->BinaryDir = allArgs[idx];
+ // dir must exist before CollapseFullPath is called
+ cmSystemTools::MakeDirectory(this->BinaryDir.c_str());
+ this->BinaryDir
+ = cmSystemTools::CollapseFullPath(this->BinaryDir.c_str());
+ this->SourceDir
+ = cmSystemTools::CollapseFullPath(this->SourceDir.c_str());
+ }
+ else
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "--build-and-test must have source and binary dir" << std::endl);
+ return 0;
+ }
+ }
+ if(currentArg.find("--build-target",0) == 0 && idx < allArgs.size() - 1)
+ {
+ idx++;
+ this->BuildTargets.push_back(allArgs[idx]);
+ }
+ if(currentArg.find("--build-nocmake",0) == 0)
+ {
+ this->BuildNoCMake = true;
+ }
+ if(currentArg.find("--build-run-dir",0) == 0 && idx < allArgs.size() - 1)
+ {
+ idx++;
+ this->BuildRunDir = allArgs[idx];
+ }
+ if(currentArg.find("--build-two-config",0) == 0)
+ {
+ this->BuildTwoConfig = true;
+ }
+ if(currentArg.find("--build-exe-dir",0) == 0 && idx < allArgs.size() - 1)
+ {
+ idx++;
+ this->ExecutableDirectory = allArgs[idx];
+ }
+ if(currentArg.find("--test-timeout",0) == 0 && idx < allArgs.size() - 1)
+ {
+ idx++;
+ this->Timeout = atof(allArgs[idx].c_str());
+ }
+ if(currentArg.find("--build-generator",0) == 0 && idx < allArgs.size() - 1)
+ {
+ idx++;
+ this->BuildGenerator = allArgs[idx];
+ }
+ if(currentArg.find("--build-project",0) == 0 && idx < allArgs.size() - 1)
+ {
+ idx++;
+ this->BuildProject = allArgs[idx];
+ }
+ if(currentArg.find("--build-makeprogram",0) == 0 &&
+ idx < allArgs.size() - 1)
+ {
+ idx++;
+ this->BuildMakeProgram = allArgs[idx];
+ }
+ if(currentArg.find("--build-config-sample",0) == 0 &&
+ idx < allArgs.size() - 1)
+ {
+ idx++;
+ this->ConfigSample = allArgs[idx];
+ }
+ if(currentArg.find("--build-noclean",0) == 0)
+ {
+ this->BuildNoClean = true;
+ }
+ if(currentArg.find("--build-options",0) == 0 && idx < allArgs.size() - 1)
+ {
+ ++idx;
+ bool done = false;
+ while(idx < allArgs.size() && !done)
+ {
+ 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)
+ {
+ ++idx;
+ this->TestCommand = allArgs[idx];
+ while(idx+1 < allArgs.size())
+ {
+ ++idx;
+ this->TestCommandArgs.push_back(allArgs[idx]);
+ }
+ }
+ return 1;
+}
+
diff --git a/Source/CTest/cmCTestBuildAndTestHandler.h b/Source/CTest/cmCTestBuildAndTestHandler.h
new file mode 100644
index 000000000..6e5f7a6ab
--- /dev/null
+++ b/Source/CTest/cmCTestBuildAndTestHandler.h
@@ -0,0 +1,78 @@
+/*============================================================================
+ 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 cmCTestBuildAndTestHandler_h
+#define cmCTestBuildAndTestHandler_h
+
+
+#include "cmCTestGenericHandler.h"
+#include "cmListFileCache.h"
+
+class cmake;
+
+/** \class cmCTestBuildAndTestHandler
+ * \brief A class that handles ctest -S invocations
+ *
+ */
+class cmCTestBuildAndTestHandler : public cmCTestGenericHandler
+{
+public:
+ cmTypeMacro(cmCTestBuildAndTestHandler, cmCTestGenericHandler);
+
+ /*
+ * The main entry point for this class
+ */
+ int ProcessHandler();
+
+ //! Set all the build and test arguments
+ virtual int ProcessCommandLineArguments(
+ const std::string& currentArg, size_t& idx,
+ const std::vector<std::string>& allArgs);
+
+ /*
+ * Get the output variable
+ */
+ const char* GetOutput();
+
+ cmCTestBuildAndTestHandler();
+
+ virtual void Initialize();
+
+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,
+ std::string &cmakeOutString,
+ std::string &cwd, cmake *cm);
+
+ cmStdString Output;
+
+ std::string BuildGenerator;
+ std::vector<std::string> BuildOptions;
+ bool BuildTwoConfig;
+ std::string BuildMakeProgram;
+ std::string ConfigSample;
+ std::string SourceDir;
+ std::string BinaryDir;
+ std::string BuildProject;
+ std::string TestCommand;
+ bool BuildNoClean;
+ std::string BuildRunDir;
+ std::string ExecutableDirectory;
+ std::vector<std::string> TestCommandArgs;
+ std::vector<std::string> BuildTargets;
+ bool BuildNoCMake;
+ double Timeout;
+};
+
+#endif
+
diff --git a/Source/CTest/cmCTestBuildCommand.cxx b/Source/CTest/cmCTestBuildCommand.cxx
new file mode 100644
index 000000000..b984e850f
--- /dev/null
+++ b/Source/CTest/cmCTestBuildCommand.cxx
@@ -0,0 +1,193 @@
+/*============================================================================
+ 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 "cmCTestBuildCommand.h"
+
+#include "cmCTest.h"
+#include "cmCTestGenericHandler.h"
+#include "cmCTestBuildHandler.h"
+#include "cmake.h"
+#include "cmGlobalGenerator.h"
+
+
+//----------------------------------------------------------------------------
+cmCTestBuildCommand::cmCTestBuildCommand()
+{
+ this->GlobalGenerator = 0;
+ this->Arguments[ctb_NUMBER_ERRORS] = "NUMBER_ERRORS";
+ this->Arguments[ctb_NUMBER_WARNINGS] = "NUMBER_WARNINGS";
+ this->Arguments[ctb_TARGET] = "TARGET";
+ this->Arguments[ctb_CONFIGURATION] = "CONFIGURATION";
+ this->Arguments[ctb_FLAGS] = "FLAGS";
+ this->Arguments[ctb_PROJECT_NAME] = "PROJECT_NAME";
+ this->Arguments[ctb_LAST] = 0;
+ this->Last = ctb_LAST;
+}
+
+//----------------------------------------------------------------------------
+cmCTestBuildCommand::~cmCTestBuildCommand()
+{
+ if ( this->GlobalGenerator )
+ {
+ delete this->GlobalGenerator;
+ this->GlobalGenerator = 0;
+ }
+}
+
+//----------------------------------------------------------------------------
+cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler()
+{
+ cmCTestGenericHandler* handler
+ = this->CTest->GetInitializedHandler("build");
+ if ( !handler )
+ {
+ this->SetError("internal CTest error. Cannot instantiate build handler");
+ return 0;
+ }
+ this->Handler = (cmCTestBuildHandler*)handler;
+
+ const char* ctestBuildCommand
+ = this->Makefile->GetDefinition("CTEST_BUILD_COMMAND");
+ if ( ctestBuildCommand && *ctestBuildCommand )
+ {
+ this->CTest->SetCTestConfiguration("MakeCommand", ctestBuildCommand);
+ }
+ else
+ {
+ const char* cmakeGeneratorName
+ = this->Makefile->GetDefinition("CTEST_CMAKE_GENERATOR");
+ const char* cmakeProjectName
+ = (this->Values[ctb_PROJECT_NAME] && *this->Values[ctb_PROJECT_NAME])
+ ? this->Values[ctb_PROJECT_NAME]
+ : this->Makefile->GetDefinition("CTEST_PROJECT_NAME");
+
+ // Build configuration is determined by: CONFIGURATION argument,
+ // or CTEST_BUILD_CONFIGURATION script variable, or
+ // CTEST_CONFIGURATION_TYPE script variable, or ctest -C command
+ // line argument... in that order.
+ //
+ const char* ctestBuildConfiguration
+ = this->Makefile->GetDefinition("CTEST_BUILD_CONFIGURATION");
+ const char* cmakeBuildConfiguration
+ = (this->Values[ctb_CONFIGURATION] && *this->Values[ctb_CONFIGURATION])
+ ? this->Values[ctb_CONFIGURATION]
+ : ((ctestBuildConfiguration && *ctestBuildConfiguration)
+ ? ctestBuildConfiguration
+ : this->CTest->GetConfigType().c_str());
+
+ const char* cmakeBuildAdditionalFlags
+ = (this->Values[ctb_FLAGS] && *this->Values[ctb_FLAGS])
+ ? this->Values[ctb_FLAGS]
+ : this->Makefile->GetDefinition("CTEST_BUILD_FLAGS");
+ const char* cmakeBuildTarget
+ = (this->Values[ctb_TARGET] && *this->Values[ctb_TARGET])
+ ? this->Values[ctb_TARGET]
+ : this->Makefile->GetDefinition("CTEST_BUILD_TARGET");
+
+ if ( cmakeGeneratorName && *cmakeGeneratorName &&
+ cmakeProjectName && *cmakeProjectName )
+ {
+ if ( !cmakeBuildConfiguration )
+ {
+ cmakeBuildConfiguration = "Release";
+ }
+ if ( this->GlobalGenerator )
+ {
+ if ( strcmp(this->GlobalGenerator->GetName(),
+ cmakeGeneratorName) != 0 )
+ {
+ delete this->GlobalGenerator;
+ this->GlobalGenerator = 0;
+ }
+ }
+ if ( !this->GlobalGenerator )
+ {
+ this->GlobalGenerator =
+ this->Makefile->GetCMakeInstance()->CreateGlobalGenerator(
+ cmakeGeneratorName);
+ }
+ this->GlobalGenerator->FindMakeProgram(this->Makefile);
+ const char* cmakeMakeProgram
+ = this->Makefile->GetDefinition("CMAKE_MAKE_PROGRAM");
+ if(strlen(cmakeBuildConfiguration) == 0)
+ {
+ const char* config = 0;
+#ifdef CMAKE_INTDIR
+ config = CMAKE_INTDIR;
+#endif
+ if(!config)
+ {
+ config = "Debug";
+ }
+ cmakeBuildConfiguration = config;
+ }
+
+ std::string buildCommand
+ = this->GlobalGenerator->
+ GenerateBuildCommand(cmakeMakeProgram,
+ cmakeProjectName,
+ cmakeBuildAdditionalFlags, cmakeBuildTarget,
+ cmakeBuildConfiguration, true, false);
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "SetMakeCommand:"
+ << buildCommand.c_str() << "\n");
+ this->CTest->SetCTestConfiguration("MakeCommand", buildCommand.c_str());
+ }
+ else
+ {
+ cmOStringStream 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."
+ "\n"
+ "CTEST_PROJECT_NAME is usually set in CTestConfig.cmake. Verify "
+ "that CTestConfig.cmake exists, or CTEST_PROJECT_NAME "
+ "is set in the script, or PROJECT_NAME is passed as an argument "
+ "to ctest_build."
+ "\n"
+ "Alternatively, set CTEST_BUILD_COMMAND to build the project "
+ "with a custom command line.";
+ this->SetError(ostr.str().c_str());
+ return 0;
+ }
+ }
+
+ if(const char* useLaunchers =
+ this->Makefile->GetDefinition("CTEST_USE_LAUNCHERS"))
+ {
+ this->CTest->SetCTestConfiguration("UseLaunchers", useLaunchers);
+ }
+
+ return handler;
+}
+
+
+bool cmCTestBuildCommand::InitialPass(std::vector<std::string> const& args,
+ cmExecutionStatus &status)
+{
+ bool ret = cmCTestHandlerCommand::InitialPass(args, status);
+ if ( this->Values[ctb_NUMBER_ERRORS] && *this->Values[ctb_NUMBER_ERRORS])
+ {
+ cmOStringStream str;
+ str << this->Handler->GetTotalErrors();
+ this->Makefile->AddDefinition(
+ this->Values[ctb_NUMBER_ERRORS], str.str().c_str());
+ }
+ if ( this->Values[ctb_NUMBER_WARNINGS]
+ && *this->Values[ctb_NUMBER_WARNINGS])
+ {
+ cmOStringStream str;
+ str << this->Handler->GetTotalWarnings();
+ this->Makefile->AddDefinition(
+ this->Values[ctb_NUMBER_WARNINGS], str.str().c_str());
+ }
+ return ret;
+}
diff --git a/Source/CTest/cmCTestBuildCommand.h b/Source/CTest/cmCTestBuildCommand.h
new file mode 100644
index 000000000..cabc39b32
--- /dev/null
+++ b/Source/CTest/cmCTestBuildCommand.h
@@ -0,0 +1,98 @@
+/*============================================================================
+ 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 cmCTestBuildCommand_h
+#define cmCTestBuildCommand_h
+
+#include "cmCTestHandlerCommand.h"
+
+class cmGlobalGenerator;
+class cmCTestBuildHandler;
+
+/** \class cmCTestBuild
+ * \brief Run a ctest script
+ *
+ * cmCTestBuildCommand defineds the command to build the project.
+ */
+class cmCTestBuildCommand : public cmCTestHandlerCommand
+{
+public:
+
+ cmCTestBuildCommand();
+ ~cmCTestBuildCommand();
+
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ cmCTestBuildCommand* ni = new cmCTestBuildCommand;
+ ni->CTest = this->CTest;
+ ni->CTestScriptHandler = this->CTestScriptHandler;
+ return ni;
+ }
+
+ /**
+ * The name of the command as specified in CMakeList.txt.
+ */
+ virtual const char* 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);
+
+ cmGlobalGenerator* GlobalGenerator;
+
+protected:
+ cmCTestBuildHandler* Handler;
+ enum {
+ ctb_BUILD = ct_LAST,
+ ctb_NUMBER_ERRORS,
+ ctb_NUMBER_WARNINGS,
+ ctb_TARGET,
+ ctb_CONFIGURATION,
+ ctb_FLAGS,
+ ctb_PROJECT_NAME,
+ ctb_LAST
+ };
+
+ cmCTestGenericHandler* InitializeHandler();
+};
+
+
+#endif
diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx
new file mode 100644
index 000000000..27bb06c13
--- /dev/null
+++ b/Source/CTest/cmCTestBuildHandler.cxx
@@ -0,0 +1,1310 @@
+/*============================================================================
+ 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 "cmCTestBuildHandler.h"
+
+#include "cmCTest.h"
+#include "cmake.h"
+#include "cmMakefile.h"
+#include "cmLocalGenerator.h"
+#include "cmGlobalGenerator.h"
+#include "cmGeneratedFileStream.h"
+#include "cmXMLSafe.h"
+#include "cmFileTimeComparison.h"
+
+//#include <cmsys/RegularExpression.hxx>
+#include <cmsys/Process.h>
+#include <cmsys/Directory.hxx>
+
+// used for sleep
+#ifdef _WIN32
+#include "windows.h"
+#endif
+
+#include <stdlib.h>
+#include <time.h>
+#include <math.h>
+#include <float.h>
+
+#if defined(__BORLANDC__)
+# pragma warn -8060 /* possibly incorrect assignment */
+#endif
+
+static const char* cmCTestErrorMatches[] = {
+ "^[Bb]us [Ee]rror",
+ "^[Ss]egmentation [Vv]iolation",
+ "^[Ss]egmentation [Ff]ault",
+ ":.*[Pp]ermission [Dd]enied",
+ "([^ :]+):([0-9]+): ([^ \\t])",
+ "([^:]+): error[ \\t]*[0-9]+[ \\t]*:",
+ "^Error ([0-9]+):",
+ "^Fatal",
+ "^Error: ",
+ "^Error ",
+ "[0-9] ERROR: ",
+ "^\"[^\"]+\", line [0-9]+: [^Ww]",
+ "^cc[^C]*CC: ERROR File = ([^,]+), Line = ([0-9]+)",
+ "^ld([^:])*:([ \\t])*ERROR([^:])*:",
+ "^ild:([ \\t])*\\(undefined symbol\\)",
+ "([^ :]+) : (error|fatal error|catastrophic error)",
+ "([^:]+): (Error:|error|undefined reference|multiply defined)",
+ "([^:]+)\\(([^\\)]+)\\) ?: (error|fatal error|catastrophic error)",
+ "^fatal error C[0-9]+:",
+ ": syntax error ",
+ "^collect2: ld returned 1 exit status",
+ "ld terminated with signal",
+ "Unsatisfied symbol",
+ "^Unresolved:",
+ "Undefined symbol",
+ "^Undefined[ \\t]+first referenced",
+ "^CMake Error.*:",
+ ":[ \\t]cannot find",
+ ":[ \\t]can't find",
+ ": \\*\\*\\* 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 \\`.*\\'",
+ "\", 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 ::",
+ "^could not be found and will not be loaded.",
+ "s:616 string too big",
+ "make: Fatal error: ",
+ "ld: 0711-993 Error occurred while writing to the output file:",
+ "ld: fatal: ",
+ "final link failed:",
+ "make: \\*\\*\\*.*Error",
+ "make\\[.*\\]: \\*\\*\\*.*Error",
+ "\\*\\*\\* Error code",
+ "nternal error:",
+ "Makefile:[0-9]+: \\*\\*\\* .* Stop\\.",
+ ": No such file or directory",
+ ": Invalid argument",
+ "^The project cannot be built\\.",
+ "^\\[ERROR\\]",
+ "^Command .* failed with exit code",
+ 0
+};
+
+static const char* cmCTestErrorExceptions[] = {
+ "instantiated from ",
+ "candidates are:",
+ ": warning",
+ ": \\(Warning\\)",
+ ": note",
+ "makefile:",
+ "Makefile:",
+ ":[ \\t]+Where:",
+ "([^ :]+):([0-9]+): Warning",
+ "------ Build started: .* ------",
+ 0
+};
+
+static const char* cmCTestWarningMatches[] = {
+ "([^ :]+):([0-9]+): warning:",
+ "([^ :]+):([0-9]+): note:",
+ "^cc[^C]*CC: WARNING File = ([^,]+), Line = ([0-9]+)",
+ "^ld([^:])*:([ \\t])*WARNING([^:])*:",
+ "([^:]+): warning ([0-9]+):",
+ "^\"[^\"]+\", line [0-9]+: [Ww](arning|arnung)",
+ "([^:]+): warning[ \\t]*[0-9]+[ \\t]*:",
+ "^(Warning|Warnung) ([0-9]+):",
+ "^(Warning|Warnung)[ :]",
+ "WARNING: ",
+ "([^ :]+) : warning",
+ "([^:]+): warning",
+ "\", line [0-9]+\\.[0-9]+: [0-9]+-[0-9]+ \\([WI]\\)",
+ "^cxx: Warning:",
+ ".*file: .* has no symbols",
+ "([^ :]+):([0-9]+): (Warning|Warnung)",
+ "\\([0-9]*\\): remark #[0-9]*",
+ "\".*\", line [0-9]+: remark\\([0-9]*\\):",
+ "cc-[0-9]* CC: REMARK File = .*, Line = [0-9]*",
+ "^CMake Warning.*:",
+ "^\\[WARNING\\]",
+ 0
+};
+
+static const char* cmCTestWarningExceptions[] = {
+ "/usr/.*/X11/Xlib\\.h:[0-9]+: war.*: ANSI C\\+\\+ forbids declaration",
+ "/usr/.*/X11/Xutil\\.h:[0-9]+: war.*: ANSI C\\+\\+ forbids declaration",
+ "/usr/.*/X11/XResource\\.h:[0-9]+: war.*: ANSI C\\+\\+ forbids declaration",
+ "WARNING 84 :",
+ "WARNING 47 :",
+ "makefile:",
+ "Makefile:",
+ "warning: Clock skew detected. Your build may be incomplete.",
+ "/usr/openwin/include/GL/[^:]+:",
+ "bind_at_load",
+ "XrmQGetResource",
+ "IceFlush",
+ "warning LNK4089: all references to [^ \\t]+ discarded by .OPT:REF",
+ "ld32: WARNING 85: definition of dataKey in",
+ "cc: warning 422: Unknown option \"\\+b",
+ "_with_warning_C",
+ 0
+};
+
+struct cmCTestBuildCompileErrorWarningRex
+{
+ const char* RegularExpressionString;
+ int FileIndex;
+ int LineIndex;
+};
+
+static cmCTestBuildCompileErrorWarningRex
+cmCTestWarningErrorFileLine[] = {
+ { "^Warning W[0-9]+ ([a-zA-Z.\\:/0-9_+ ~-]+) ([0-9]+):", 1, 2 },
+ { "^([a-zA-Z./0-9_+ ~-]+):([0-9]+):", 1, 2 },
+ { "^([a-zA-Z.\\:/0-9_+ ~-]+)\\(([0-9]+)\\)", 1, 2 },
+ { "^[0-9]+>([a-zA-Z.\\:/0-9_+ ~-]+)\\(([0-9]+)\\)", 1, 2 },
+ { "^([a-zA-Z./0-9_+ ~-]+)\\(([0-9]+)\\)", 1, 2 },
+ { "\"([a-zA-Z./0-9_+ ~-]+)\", line ([0-9]+)", 1, 2 },
+ { "File = ([a-zA-Z./0-9_+ ~-]+), Line = ([0-9]+)", 1, 2 },
+ { 0, 0, 0 }
+};
+
+//----------------------------------------------------------------------
+cmCTestBuildHandler::cmCTestBuildHandler()
+{
+ this->MaxPreContext = 10;
+ this->MaxPostContext = 10;
+
+ this->MaxErrors = 50;
+ this->MaxWarnings = 50;
+
+ this->LastErrorOrWarning = this->ErrorsAndWarnings.end();
+
+ this->UseCTestLaunch = false;
+}
+
+//----------------------------------------------------------------------
+void cmCTestBuildHandler::Initialize()
+{
+ this->Superclass::Initialize();
+ this->StartBuild = "";
+ this->EndBuild = "";
+ this->CustomErrorMatches.clear();
+ this->CustomErrorExceptions.clear();
+ this->CustomWarningMatches.clear();
+ this->CustomWarningExceptions.clear();
+ this->ReallyCustomWarningMatches.clear();
+ this->ReallyCustomWarningExceptions.clear();
+ this->ErrorWarningFileLineRegex.clear();
+
+ this->ErrorMatchRegex.clear();
+ this->ErrorExceptionRegex.clear();
+ this->WarningMatchRegex.clear();
+ this->WarningExceptionRegex.clear();
+ this->BuildProcessingQueue.clear();
+ this->BuildProcessingErrorQueue.clear();
+ this->BuildOutputLogSize = 0;
+ this->CurrentProcessingLine.clear();
+
+ this->SimplifySourceDir = "";
+ this->SimplifyBuildDir = "";
+ this->OutputLineCounter = 0;
+ this->ErrorsAndWarnings.clear();
+ this->LastErrorOrWarning = this->ErrorsAndWarnings.end();
+ this->PostContextCount = 0;
+ this->MaxPreContext = 10;
+ this->MaxPostContext = 10;
+ this->PreContext.clear();
+
+ this->TotalErrors = 0;
+ this->TotalWarnings = 0;
+ this->LastTickChar = 0;
+
+ this->ErrorQuotaReached = false;
+ this->WarningQuotaReached = false;
+
+ this->MaxErrors = 50;
+ this->MaxWarnings = 50;
+
+ this->UseCTestLaunch = false;
+}
+
+//----------------------------------------------------------------------
+void cmCTestBuildHandler::PopulateCustomVectors(cmMakefile *mf)
+{
+ this->CTest->PopulateCustomVector(mf, "CTEST_CUSTOM_ERROR_MATCH",
+ this->CustomErrorMatches);
+ this->CTest->PopulateCustomVector(mf, "CTEST_CUSTOM_ERROR_EXCEPTION",
+ this->CustomErrorExceptions);
+ this->CTest->PopulateCustomVector(mf, "CTEST_CUSTOM_WARNING_MATCH",
+ this->CustomWarningMatches);
+ this->CTest->PopulateCustomVector(mf, "CTEST_CUSTOM_WARNING_EXCEPTION",
+ this->CustomWarningExceptions);
+ this->CTest->PopulateCustomInteger(mf,
+ "CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS",
+ this->MaxErrors);
+ this->CTest->PopulateCustomInteger(mf,
+ "CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS",
+ this->MaxWarnings);
+
+ int n = -1;
+ this->CTest->PopulateCustomInteger(mf, "CTEST_CUSTOM_ERROR_PRE_CONTEXT", n);
+ if (n != -1)
+ {
+ this->MaxPreContext = static_cast<size_t>(n);
+ }
+
+ n = -1;
+ this->CTest->PopulateCustomInteger(mf, "CTEST_CUSTOM_ERROR_POST_CONTEXT", n);
+ if (n != -1)
+ {
+ this->MaxPostContext = static_cast<size_t>(n);
+ }
+
+ // Record the user-specified custom warning rules.
+ if(const char* customWarningMatchers =
+ mf->GetDefinition("CTEST_CUSTOM_WARNING_MATCH"))
+ {
+ cmSystemTools::ExpandListArgument(customWarningMatchers,
+ this->ReallyCustomWarningMatches);
+ }
+ if(const char* customWarningExceptions =
+ mf->GetDefinition("CTEST_CUSTOM_WARNING_EXCEPTION"))
+ {
+ cmSystemTools::ExpandListArgument(customWarningExceptions,
+ this->ReallyCustomWarningExceptions);
+ }
+}
+
+//----------------------------------------------------------------------
+std::string cmCTestBuildHandler::GetMakeCommand()
+{
+ std::string makeCommand
+ = this->CTest->GetCTestConfiguration("MakeCommand");
+ cmCTestLog(this->CTest,
+ HANDLER_VERBOSE_OUTPUT, "MakeCommand:" << makeCommand <<
+ "\n");
+
+ std::string configType = this->CTest->GetConfigType();
+ if (configType == "")
+ {
+ configType
+ = this->CTest->GetCTestConfiguration("DefaultCTestConfigurationType");
+ }
+ if (configType == "")
+ {
+ configType = "Release";
+ }
+
+ cmSystemTools::ReplaceString(makeCommand,
+ "${CTEST_CONFIGURATION_TYPE}", configType.c_str());
+
+ return makeCommand;
+}
+
+//----------------------------------------------------------------------
+//clearly it would be nice if this were broken up into a few smaller
+//functions and commented...
+int cmCTestBuildHandler::ProcessHandler()
+{
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, "Build project" << std::endl);
+
+ // do we have time for this
+ if (this->CTest->GetRemainingTimeAllowed() < 120)
+ {
+ return 0;
+ }
+
+ int entry;
+ for ( entry = 0;
+ cmCTestWarningErrorFileLine[entry].RegularExpressionString;
+ ++ entry )
+ {
+ cmCTestBuildHandler::cmCTestCompileErrorWarningRex r;
+ if ( r.RegularExpression.compile(
+ cmCTestWarningErrorFileLine[entry].RegularExpressionString) )
+ {
+ r.FileIndex = cmCTestWarningErrorFileLine[entry].FileIndex;
+ r.LineIndex = cmCTestWarningErrorFileLine[entry].LineIndex;
+ this->ErrorWarningFileLineRegex.push_back(r);
+ }
+ else
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Problem Compiling regular expression: "
+ << cmCTestWarningErrorFileLine[entry].RegularExpressionString
+ << std::endl);
+ }
+ }
+
+ // Determine build command and build directory
+ std::string makeCommand = this->GetMakeCommand();
+ if ( makeCommand.size() == 0 )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Cannot find MakeCommand key in the DartConfiguration.tcl"
+ << std::endl);
+ return -1;
+ }
+
+ const std::string &buildDirectory
+ = this->CTest->GetCTestConfiguration("BuildDirectory");
+ if ( buildDirectory.size() == 0 )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Cannot find BuildDirectory key in the DartConfiguration.tcl"
+ << std::endl);
+ return -1;
+ }
+
+ std::string const& useLaunchers =
+ this->CTest->GetCTestConfiguration("UseLaunchers");
+ this->UseCTestLaunch = cmSystemTools::IsOn(useLaunchers.c_str());
+
+ // Create a last build log
+ cmGeneratedFileStream ofs;
+ double elapsed_time_start = cmSystemTools::GetTime();
+ if ( !this->StartLogFile("Build", ofs) )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot create build log file"
+ << std::endl);
+ }
+
+ // Create lists of regular expression strings for errors, error exceptions,
+ // warnings and warning exceptions.
+ std::vector<cmStdString>::size_type cc;
+ for ( cc = 0; cmCTestErrorMatches[cc]; cc ++ )
+ {
+ this->CustomErrorMatches.push_back(cmCTestErrorMatches[cc]);
+ }
+ for ( cc = 0; cmCTestErrorExceptions[cc]; cc ++ )
+ {
+ this->CustomErrorExceptions.push_back(cmCTestErrorExceptions[cc]);
+ }
+ for ( cc = 0; cmCTestWarningMatches[cc]; cc ++ )
+ {
+ this->CustomWarningMatches.push_back(cmCTestWarningMatches[cc]);
+ }
+
+ for ( cc = 0; cmCTestWarningExceptions[cc]; cc ++ )
+ {
+ this->CustomWarningExceptions.push_back(cmCTestWarningExceptions[cc]);
+ }
+
+ // Pre-compile regular expressions objects for all regular expressions
+ std::vector<cmStdString>::iterator it;
+
+#define cmCTestBuildHandlerPopulateRegexVector(strings, regexes) \
+ regexes.clear(); \
+ cmCTestLog(this->CTest, DEBUG, this << "Add " #regexes \
+ << std::endl); \
+ for ( it = strings.begin(); it != strings.end(); ++it ) \
+ { \
+ cmCTestLog(this->CTest, DEBUG, "Add " #strings ": " \
+ << it->c_str() << std::endl); \
+ regexes.push_back(it->c_str()); \
+ }
+ cmCTestBuildHandlerPopulateRegexVector(
+ this->CustomErrorMatches, this->ErrorMatchRegex);
+ cmCTestBuildHandlerPopulateRegexVector(
+ this->CustomErrorExceptions, this->ErrorExceptionRegex);
+ cmCTestBuildHandlerPopulateRegexVector(
+ this->CustomWarningMatches, this->WarningMatchRegex);
+ cmCTestBuildHandlerPopulateRegexVector(
+ this->CustomWarningExceptions, this->WarningExceptionRegex);
+
+
+ // Determine source and binary tree substitutions to simplify the output.
+ this->SimplifySourceDir = "";
+ this->SimplifyBuildDir = "";
+ if ( this->CTest->GetCTestConfiguration("SourceDirectory").size() > 20 )
+ {
+ std::string srcdir
+ = this->CTest->GetCTestConfiguration("SourceDirectory") + "/";
+ std::string srcdirrep;
+ for ( cc = srcdir.size()-2; cc > 0; cc -- )
+ {
+ if ( srcdir[cc] == '/' )
+ {
+ srcdirrep = srcdir.c_str() + cc;
+ srcdirrep = "/..." + srcdirrep;
+ srcdir = srcdir.substr(0, cc+1);
+ break;
+ }
+ }
+ this->SimplifySourceDir = srcdir;
+ }
+ if ( this->CTest->GetCTestConfiguration("BuildDirectory").size() > 20 )
+ {
+ std::string bindir
+ = this->CTest->GetCTestConfiguration("BuildDirectory") + "/";
+ std::string bindirrep;
+ for ( cc = bindir.size()-2; cc > 0; cc -- )
+ {
+ if ( bindir[cc] == '/' )
+ {
+ bindirrep = bindir.c_str() + cc;
+ bindirrep = "/..." + bindirrep;
+ bindir = bindir.substr(0, cc+1);
+ break;
+ }
+ }
+ this->SimplifyBuildDir = bindir;
+ }
+
+
+ // Ok, let's do the build
+
+ // Remember start build time
+ this->StartBuild = this->CTest->CurrentTime();
+ this->StartBuildTime = cmSystemTools::GetTime();
+ int retVal = 0;
+ int res = cmsysProcess_State_Exited;
+ if ( !this->CTest->GetShowOnly() )
+ {
+ res = this->RunMakeCommand(makeCommand.c_str(), &retVal,
+ buildDirectory.c_str(), 0, ofs);
+ }
+ else
+ {
+ cmCTestLog(this->CTest, DEBUG, "Build with command: " << makeCommand
+ << std::endl);
+ }
+
+ // Remember end build time and calculate elapsed time
+ this->EndBuild = this->CTest->CurrentTime();
+ this->EndBuildTime = cmSystemTools::GetTime();
+ double elapsed_build_time = cmSystemTools::GetTime() - elapsed_time_start;
+
+ // Cleanups strings in the errors and warnings list.
+ t_ErrorsAndWarningsVector::iterator evit;
+ if ( !this->SimplifySourceDir.empty() )
+ {
+ for ( evit = this->ErrorsAndWarnings.begin();
+ evit != this->ErrorsAndWarnings.end();
+ ++ evit )
+ {
+ cmSystemTools::ReplaceString(
+ evit->Text, this->SimplifySourceDir.c_str(), "/.../");
+ cmSystemTools::ReplaceString(
+ evit->PreContext, this->SimplifySourceDir.c_str(), "/.../");
+ cmSystemTools::ReplaceString(
+ evit->PostContext, this->SimplifySourceDir.c_str(), "/.../");
+ }
+ }
+
+ if ( !this->SimplifyBuildDir.empty() )
+ {
+ for ( evit = this->ErrorsAndWarnings.begin();
+ evit != this->ErrorsAndWarnings.end();
+ ++ evit )
+ {
+ cmSystemTools::ReplaceString(
+ evit->Text, this->SimplifyBuildDir.c_str(), "/.../");
+ cmSystemTools::ReplaceString(
+ evit->PreContext, this->SimplifyBuildDir.c_str(), "/.../");
+ cmSystemTools::ReplaceString(
+ evit->PostContext, this->SimplifyBuildDir.c_str(), "/.../");
+ }
+ }
+
+ // Generate XML output
+ cmGeneratedFileStream xofs;
+ if(!this->StartResultingXML(cmCTest::PartBuild, "Build", xofs))
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot create build XML file"
+ << std::endl);
+ return -1;
+ }
+ this->GenerateXMLHeader(xofs);
+ if(this->UseCTestLaunch)
+ {
+ this->GenerateXMLLaunched(xofs);
+ }
+ else
+ {
+ this->GenerateXMLLogScraped(xofs);
+ }
+ this->GenerateXMLFooter(xofs, elapsed_build_time);
+
+ if (res != cmsysProcess_State_Exited || retVal || this->TotalErrors > 0)
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Error(s) when building project"
+ << std::endl);
+ }
+
+ // Display message about number of errors and warnings
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " " << this->TotalErrors
+ << (this->TotalErrors >= this->MaxErrors ? " or more" : "")
+ << " Compiler errors" << std::endl);
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " " << this->TotalWarnings
+ << (this->TotalWarnings >= this->MaxWarnings ? " or more" : "")
+ << " Compiler warnings" << std::endl);
+
+ return retVal;
+}
+
+//----------------------------------------------------------------------------
+void cmCTestBuildHandler::GenerateXMLHeader(std::ostream& os)
+{
+ 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;
+}
+
+//----------------------------------------------------------------------------
+class cmCTestBuildHandler::FragmentCompare
+{
+public:
+ FragmentCompare(cmFileTimeComparison* ftc): FTC(ftc) {}
+ FragmentCompare(): FTC(0) {}
+ bool operator()(std::string const& l, std::string const& r)
+ {
+ // Order files by modification time. Use lexicographic order
+ // among files with the same time.
+ int result;
+ if(this->FTC->FileTimeCompare(l.c_str(), r.c_str(), &result) &&
+ result != 0)
+ {
+ return result < 0;
+ }
+ else
+ {
+ return l < r;
+ }
+ }
+private:
+ cmFileTimeComparison* FTC;
+};
+
+//----------------------------------------------------------------------------
+void cmCTestBuildHandler::GenerateXMLLaunched(std::ostream& os)
+{
+ if(this->CTestLaunchDir.empty())
+ {
+ return;
+ }
+
+ // Sort XML fragments in chronological order.
+ cmFileTimeComparison ftc;
+ FragmentCompare fragmentCompare(&ftc);
+ typedef std::set<cmStdString, FragmentCompare> Fragments;
+ Fragments fragments(fragmentCompare);
+
+ // Identify fragments on disk.
+ cmsys::Directory launchDir;
+ launchDir.Load(this->CTestLaunchDir.c_str());
+ unsigned long n = launchDir.GetNumberOfFiles();
+ for(unsigned long i=0; i < n; ++i)
+ {
+ const char* fname = launchDir.GetFile(i);
+ if(this->IsLaunchedErrorFile(fname))
+ {
+ fragments.insert(this->CTestLaunchDir + "/" + fname);
+ ++this->TotalErrors;
+ }
+ else if(this->IsLaunchedWarningFile(fname))
+ {
+ fragments.insert(this->CTestLaunchDir + "/" + fname);
+ ++this->TotalWarnings;
+ }
+ }
+
+ // Copy the fragments into the final XML file.
+ for(Fragments::const_iterator fi = fragments.begin();
+ fi != fragments.end(); ++fi)
+ {
+ this->GenerateXMLLaunchedFragment(os, fi->c_str());
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmCTestBuildHandler::GenerateXMLLogScraped(std::ostream& os)
+{
+ std::vector<cmCTestBuildErrorWarning>& ew = this->ErrorsAndWarnings;
+ std::vector<cmCTestBuildErrorWarning>::iterator it;
+
+ // only report the first 50 warnings and first 50 errors
+ int numErrorsAllowed = this->MaxErrors;
+ int numWarningsAllowed = this->MaxWarnings;
+ 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 += "/";
+ for ( it = ew.begin();
+ it != ew.end() && (numErrorsAllowed || numWarningsAllowed); it++ )
+ {
+ cmCTestBuildErrorWarning *cm = &(*it);
+ if ((cm->Error && numErrorsAllowed) ||
+ (!cm->Error && numWarningsAllowed))
+ {
+ if (cm->Error)
+ {
+ numErrorsAllowed--;
+ }
+ else
+ {
+ 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;
+ std::vector<cmCTestCompileErrorWarningRex>::iterator rit;
+ for ( rit = this->ErrorWarningFileLineRegex.begin();
+ rit != this->ErrorWarningFileLineRegex.end(); ++ rit )
+ {
+ cmsys::RegularExpression* re = &rit->RegularExpression;
+ if ( re->find(cm->Text.c_str() ) )
+ {
+ cm->SourceFile = re->match(rit->FileIndex);
+ // At this point we need to make this->SourceFile relative to
+ // the source root of the project, so cvs links will work
+ cmSystemTools::ConvertToUnixSlashes(cm->SourceFile);
+ if(cm->SourceFile.find("/.../") != cm->SourceFile.npos)
+ {
+ cmSystemTools::ReplaceString(cm->SourceFile, "/.../", "");
+ std::string::size_type p = cm->SourceFile.find("/");
+ if(p != cm->SourceFile.npos)
+ {
+ cm->SourceFile = cm->SourceFile.substr(
+ p+1, cm->SourceFile.size()-p);
+ }
+ }
+ else
+ {
+ // make sure it is a full path with the correct case
+ cm->SourceFile = cmSystemTools::CollapseFullPath(
+ cm->SourceFile.c_str());
+ cmSystemTools::ReplaceString(
+ cm->SourceFile, srcdir.c_str(), "");
+ }
+ cm->LineNumber = atoi(re->match(rit->LineIndex).c_str());
+ break;
+ }
+ }
+ if ( !cm->SourceFile.empty() && cm->LineNumber >= 0 )
+ {
+ if ( cm->SourceFile.size() > 0 )
+ {
+ os << "\t\t<SourceFile>" << cm->SourceFile << "</SourceFile>"
+ << std::endl;
+ }
+ if ( cm->SourceFileTail.size() > 0 )
+ {
+ os << "\t\t<SourceFileTail>" << cm->SourceFileTail
+ << "</SourceFileTail>" << std::endl;
+ }
+ if ( cm->LineNumber >= 0 )
+ {
+ os << "\t\t<SourceLineNumber>" << cm->LineNumber
+ << "</SourceLineNumber>" << std::endl;
+ }
+ }
+ os << "\t\t<PreContext>" << cmXMLSafe(cm->PreContext).Quotes(false)
+ << "</PreContext>\n"
+ << "\t\t<PostContext>" << cmXMLSafe(cm->PostContext).Quotes(false);
+ // 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";
+ }
+ os << "</PostContext>\n"
+ << "\t\t<RepeatCount>0</RepeatCount>\n"
+ << "</" << (cm->Error ? "Error" : "Warning") << ">\n\n"
+ << std::endl;
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmCTestBuildHandler::GenerateXMLFooter(std::ostream& os,
+ 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";
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestBuildHandler::IsLaunchedErrorFile(const char* fname)
+{
+ // error-{hash}.xml
+ return (strncmp(fname, "error-", 6) == 0 &&
+ strcmp(fname+strlen(fname)-4, ".xml") == 0);
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestBuildHandler::IsLaunchedWarningFile(const char* fname)
+{
+ // warning-{hash}.xml
+ return (strncmp(fname, "warning-", 8) == 0 &&
+ strcmp(fname+strlen(fname)-4, ".xml") == 0);
+}
+
+//######################################################################
+//######################################################################
+//######################################################################
+//######################################################################
+
+//----------------------------------------------------------------------------
+class cmCTestBuildHandler::LaunchHelper
+{
+public:
+ LaunchHelper(cmCTestBuildHandler* handler);
+ ~LaunchHelper();
+private:
+ cmCTestBuildHandler* Handler;
+ cmCTest* CTest;
+
+ void WriteLauncherConfig();
+ void WriteScrapeMatchers(const char* purpose,
+ std::vector<std::string> const& matchers);
+};
+
+//----------------------------------------------------------------------------
+cmCTestBuildHandler::LaunchHelper::LaunchHelper(cmCTestBuildHandler* handler):
+ Handler(handler), CTest(handler->CTest)
+{
+ std::string tag = this->CTest->GetCurrentTag();
+ if(tag.empty())
+ {
+ // This is not for a dashboard submission, so there is no XML.
+ // Skip enabling the launchers.
+ this->Handler->UseCTestLaunch = false;
+ }
+ else
+ {
+ // Compute a directory in which to store launcher fragments.
+ std::string& launchDir = this->Handler->CTestLaunchDir;
+ launchDir = this->CTest->GetBinaryDir();
+ launchDir += "/Testing/";
+ launchDir += tag;
+ launchDir += "/Build";
+
+ // Clean out any existing launcher fragments.
+ cmSystemTools::RemoveADirectory(launchDir.c_str());
+
+ if(this->Handler->UseCTestLaunch)
+ {
+ // Enable launcher fragments.
+ cmSystemTools::MakeDirectory(launchDir.c_str());
+ this->WriteLauncherConfig();
+ std::string launchEnv = "CTEST_LAUNCH_LOGS=";
+ launchEnv += launchDir;
+ cmSystemTools::PutEnv(launchEnv.c_str());
+ }
+ }
+
+ // If not using launchers, make sure they passthru.
+ if(!this->Handler->UseCTestLaunch)
+ {
+ cmSystemTools::UnsetEnv("CTEST_LAUNCH_LOGS");
+ }
+}
+
+//----------------------------------------------------------------------------
+cmCTestBuildHandler::LaunchHelper::~LaunchHelper()
+{
+ if(this->Handler->UseCTestLaunch)
+ {
+ cmSystemTools::UnsetEnv("CTEST_LAUNCH_LOGS");
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmCTestBuildHandler::LaunchHelper::WriteLauncherConfig()
+{
+ this->WriteScrapeMatchers("Warning",
+ this->Handler->ReallyCustomWarningMatches);
+ this->WriteScrapeMatchers("WarningSuppress",
+ this->Handler->ReallyCustomWarningExceptions);
+
+ // Give some testing configuration information to the launcher.
+ std::string fname = this->Handler->CTestLaunchDir;
+ fname += "/CTestLaunchConfig.cmake";
+ cmGeneratedFileStream fout(fname.c_str());
+ std::string srcdir = this->CTest->GetCTestConfiguration("SourceDirectory");
+ fout << "set(CTEST_SOURCE_DIRECTORY \"" << srcdir << "\")\n";
+}
+
+//----------------------------------------------------------------------------
+void
+cmCTestBuildHandler::LaunchHelper
+::WriteScrapeMatchers(const char* purpose,
+ std::vector<std::string> const& matchers)
+{
+ if(matchers.empty())
+ {
+ return;
+ }
+ std::string fname = this->Handler->CTestLaunchDir;
+ fname += "/Custom";
+ fname += purpose;
+ fname += ".txt";
+ cmGeneratedFileStream fout(fname.c_str());
+ for(std::vector<std::string>::const_iterator mi = matchers.begin();
+ mi != matchers.end(); ++mi)
+ {
+ fout << *mi << "\n";
+ }
+}
+
+//----------------------------------------------------------------------
+int cmCTestBuildHandler::RunMakeCommand(const char* command,
+ int* retVal, const char* dir, int timeout, std::ofstream& ofs)
+{
+ // First generate the command and arguments
+ std::vector<cmStdString> args = cmSystemTools::ParseArguments(command);
+
+ if(args.size() < 1)
+ {
+ return false;
+ }
+
+ std::vector<const char*> argv;
+ for(std::vector<cmStdString>::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:");
+ std::vector<const char*>::iterator ait;
+ for ( ait = argv.begin(); ait != argv.end() && *ait; ++ ait )
+ {
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " \"" << *ait << "\"");
+ }
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, std::endl);
+
+ // Optionally use make rule launchers to record errors and warnings.
+ LaunchHelper launchHelper(this);
+ static_cast<void>(launchHelper);
+
+ // Now create process object
+ cmsysProcess* cp = cmsysProcess_New();
+ cmsysProcess_SetCommand(cp, &*argv.begin());
+ cmsysProcess_SetWorkingDirectory(cp, dir);
+ cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1);
+ cmsysProcess_SetTimeout(cp, timeout);
+ cmsysProcess_Execute(cp);
+
+ // Initialize tick's
+ std::string::size_type tick = 0;
+ const std::string::size_type tick_len = 1024;
+
+ char* data;
+ int length;
+ cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ " Each symbol represents " << tick_len << " bytes of output."
+ << std::endl
+ << (this->UseCTestLaunch? "" :
+ " '!' represents an error and '*' a warning.\n")
+ << " " << std::flush);
+
+ // Initialize building structures
+ this->BuildProcessingQueue.clear();
+ this->OutputLineCounter = 0;
+ this->ErrorsAndWarnings.clear();
+ this->TotalErrors = 0;
+ this->TotalWarnings = 0;
+ this->BuildOutputLogSize = 0;
+ this->LastTickChar = '.';
+ this->WarningQuotaReached = false;
+ this->ErrorQuotaReached = false;
+
+ // For every chunk of data
+ int res;
+ while((res = cmsysProcess_WaitForData(cp, &data, &length, 0)))
+ {
+ // Replace '\0' with '\n', since '\0' does not really make sense. This is
+ // for Visual Studio output
+ for(int cc =0; cc < length; ++cc)
+ {
+ if(data[cc] == 0)
+ {
+ data[cc] = '\n';
+ }
+ }
+
+ // Process the chunk of data
+ if ( res == cmsysProcess_Pipe_STDERR )
+ {
+ this->ProcessBuffer(data, length, tick, tick_len, ofs,
+ &this->BuildProcessingErrorQueue);
+ }
+ else
+ {
+ this->ProcessBuffer(data, length, tick, tick_len, ofs,
+ &this->BuildProcessingQueue);
+ }
+ }
+
+ 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);
+
+ // Properly handle output of the build command
+ cmsysProcess_WaitForExit(cp, 0);
+ int result = cmsysProcess_GetState(cp);
+
+ if(result == cmsysProcess_State_Exited)
+ {
+ if (retVal)
+ {
+ *retVal = cmsysProcess_GetExitValue(cp);
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Command exited with the value: " << *retVal << std::endl);
+ // if a non zero return value
+ if (*retVal)
+ {
+ // If there was an error running command, report that on the
+ // dashboard.
+ cmCTestBuildErrorWarning errorwarning;
+ errorwarning.LogLine = 1;
+ errorwarning.Text
+ = "*** WARNING non-zero return value in ctest from: ";
+ errorwarning.Text += argv[0];
+ errorwarning.PreContext = "";
+ errorwarning.PostContext = "";
+ errorwarning.Error = false;
+ this->ErrorsAndWarnings.push_back(errorwarning);
+ this->TotalWarnings ++;
+ }
+ }
+ }
+ else if(result == cmsysProcess_State_Exception)
+ {
+ if (retVal)
+ {
+ *retVal = cmsysProcess_GetExitException(cp);
+ cmCTestLog(this->CTest, WARNING, "There was an exception: " << *retVal
+ << std::endl);
+ }
+ }
+ else if(result == cmsysProcess_State_Expired)
+ {
+ cmCTestLog(this->CTest, WARNING, "There was a timeout" << std::endl);
+ }
+ else if(result == cmsysProcess_State_Error)
+ {
+ // If there was an error running command, report that on the dashboard.
+ cmCTestBuildErrorWarning errorwarning;
+ errorwarning.LogLine = 1;
+ errorwarning.Text = "*** ERROR executing: ";
+ errorwarning.Text += cmsysProcess_GetErrorString(cp);
+ errorwarning.PreContext = "";
+ errorwarning.PostContext = "";
+ errorwarning.Error = true;
+ this->ErrorsAndWarnings.push_back(errorwarning);
+ this->TotalErrors ++;
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "There was an error: "
+ << cmsysProcess_GetErrorString(cp) << std::endl);
+ }
+
+ cmsysProcess_Delete(cp);
+ return result;
+}
+
+//######################################################################
+//######################################################################
+//######################################################################
+//######################################################################
+
+//----------------------------------------------------------------------
+void cmCTestBuildHandler::ProcessBuffer(const char* data, int length,
+ size_t& tick, size_t tick_len, std::ofstream& ofs,
+ t_BuildProcessingQueueType* queue)
+{
+ const std::string::size_type tick_line_len = 50;
+ const char* ptr;
+ for ( ptr = data; ptr < data+length; ptr ++ )
+ {
+ queue->push_back(*ptr);
+ }
+ this->BuildOutputLogSize += length;
+
+ // until there are any lines left in the buffer
+ while ( 1 )
+ {
+ // Find the end of line
+ t_BuildProcessingQueueType::iterator it;
+ for ( it = queue->begin();
+ it != queue->end();
+ ++ it )
+ {
+ if ( *it == '\n' )
+ {
+ break;
+ }
+ }
+
+ // Once certain number of errors or warnings reached, ignore future errors
+ // or warnings.
+ if ( this->TotalWarnings >= this->MaxWarnings )
+ {
+ this->WarningQuotaReached = true;
+ }
+ if ( this->TotalErrors >= this->MaxErrors )
+ {
+ this->ErrorQuotaReached = true;
+ }
+
+ // If the end of line was found
+ if ( it != queue->end() )
+ {
+ // 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.push_back(0);
+ const char* line = &*this->CurrentProcessingLine.begin();
+
+ // Process the line
+ int lineType = this->ProcessSingleLine(line);
+
+ // Erase the line from the queue
+ queue->erase(queue->begin(), it+1);
+
+ // Depending on the line type, produce error or warning, or nothing
+ cmCTestBuildErrorWarning errorwarning;
+ bool found = false;
+ switch ( lineType )
+ {
+ case b_WARNING_LINE:
+ this->LastTickChar = '*';
+ errorwarning.Error = false;
+ found = true;
+ this->TotalWarnings ++;
+ break;
+ case b_ERROR_LINE:
+ this->LastTickChar = '!';
+ errorwarning.Error = true;
+ found = true;
+ this->TotalErrors ++;
+ break;
+ }
+ if ( found )
+ {
+ // This is an error or warning, so generate report
+ errorwarning.LogLine = static_cast<int>(this->OutputLineCounter+1);
+ errorwarning.Text = line;
+ errorwarning.PreContext = "";
+ errorwarning.PostContext = "";
+
+ // Copy pre-context to report
+ std::deque<cmStdString>::iterator pcit;
+ for ( pcit = this->PreContext.begin();
+ pcit != this->PreContext.end();
+ ++pcit )
+ {
+ errorwarning.PreContext += *pcit + "\n";
+ }
+ this->PreContext.clear();
+
+ // Store report
+ this->ErrorsAndWarnings.push_back(errorwarning);
+ this->LastErrorOrWarning = this->ErrorsAndWarnings.end()-1;
+ this->PostContextCount = 0;
+ }
+ else
+ {
+ // This is not an error or warning.
+ // So, figure out if this is a post-context line
+ if ( this->ErrorsAndWarnings.size() &&
+ this->LastErrorOrWarning != this->ErrorsAndWarnings.end() &&
+ this->PostContextCount < this->MaxPostContext )
+ {
+ this->PostContextCount ++;
+ this->LastErrorOrWarning->PostContext += line;
+ if ( this->PostContextCount < this->MaxPostContext )
+ {
+ this->LastErrorOrWarning->PostContext += "\n";
+ }
+ }
+ else
+ {
+ // Otherwise store pre-context for the next error
+ this->PreContext.push_back(line);
+ if ( this->PreContext.size() > this->MaxPreContext )
+ {
+ this->PreContext.erase(this->PreContext.begin(),
+ this->PreContext.end()-this->MaxPreContext);
+ }
+ }
+ }
+ this->OutputLineCounter ++;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ // Now that the buffer is processed, display missing ticks
+ int tickDisplayed = false;
+ while ( this->BuildOutputLogSize > (tick * tick_len) )
+ {
+ tick ++;
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, this->LastTickChar);
+ tickDisplayed = true;
+ if ( tick % tick_line_len == 0 && tick > 0 )
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " Size: "
+ << ((this->BuildOutputLogSize + 512) / 1024) << "K" << std::endl
+ << " ");
+ }
+ }
+ if ( tickDisplayed )
+ {
+ this->LastTickChar = '.';
+ }
+
+ // And if this is verbose output, display the content of the chunk
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ cmCTestLogWrite(data, length));
+
+ // Always store the chunk to the file
+ ofs << cmCTestLogWrite(data, length);
+}
+
+//----------------------------------------------------------------------
+int cmCTestBuildHandler::ProcessSingleLine(const char* data)
+{
+ if(this->UseCTestLaunch)
+ {
+ // No log scraping when using launchers.
+ return b_REGULAR_LINE;
+ }
+
+ cmCTestLog(this->CTest, DEBUG, "Line: [" << data << "]" << std::endl);
+
+ std::vector<cmsys::RegularExpression>::iterator it;
+
+ int warningLine = 0;
+ int errorLine = 0;
+
+ // Check for regular expressions
+
+ if ( !this->ErrorQuotaReached )
+ {
+ // Errors
+ int wrxCnt = 0;
+ for ( it = this->ErrorMatchRegex.begin();
+ it != this->ErrorMatchRegex.end();
+ ++ it )
+ {
+ if ( it->find(data) )
+ {
+ errorLine = 1;
+ cmCTestLog(this->CTest, DEBUG, " Error Line: " << data
+ << " (matches: " << this->CustomErrorMatches[wrxCnt] << ")"
+ << std::endl);
+ break;
+ }
+ wrxCnt ++;
+ }
+ // Error exceptions
+ wrxCnt = 0;
+ for ( it = this->ErrorExceptionRegex.begin();
+ it != this->ErrorExceptionRegex.end();
+ ++ it )
+ {
+ if ( it->find(data) )
+ {
+ errorLine = 0;
+ cmCTestLog(this->CTest, DEBUG, " Not an error Line: " << data
+ << " (matches: " << this->CustomErrorExceptions[wrxCnt] << ")"
+ << std::endl);
+ break;
+ }
+ wrxCnt ++;
+ }
+ }
+ if ( !this->WarningQuotaReached )
+ {
+ // Warnings
+ int wrxCnt = 0;
+ for ( it = this->WarningMatchRegex.begin();
+ it != this->WarningMatchRegex.end();
+ ++ it )
+ {
+ if ( it->find(data) )
+ {
+ warningLine = 1;
+ cmCTestLog(this->CTest, DEBUG,
+ " Warning Line: " << data
+ << " (matches: " << this->CustomWarningMatches[wrxCnt] << ")"
+ << std::endl);
+ break;
+ }
+ wrxCnt ++;
+ }
+
+ wrxCnt = 0;
+ // Warning exceptions
+ for ( it = this->WarningExceptionRegex.begin();
+ it != this->WarningExceptionRegex.end();
+ ++ it )
+ {
+ if ( it->find(data) )
+ {
+ warningLine = 0;
+ cmCTestLog(this->CTest, DEBUG, " Not a warning Line: " << data
+ << " (matches: " << this->CustomWarningExceptions[wrxCnt] << ")"
+ << std::endl);
+ break;
+ }
+ wrxCnt ++;
+ }
+ }
+ if ( errorLine )
+ {
+ return b_ERROR_LINE;
+ }
+ if ( warningLine )
+ {
+ return b_WARNING_LINE;
+ }
+ return b_REGULAR_LINE;
+}
+
diff --git a/Source/CTest/cmCTestBuildHandler.h b/Source/CTest/cmCTestBuildHandler.h
new file mode 100644
index 000000000..439efd604
--- /dev/null
+++ b/Source/CTest/cmCTestBuildHandler.h
@@ -0,0 +1,152 @@
+/*============================================================================
+ 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 cmCTestBuildHandler_h
+#define cmCTestBuildHandler_h
+
+
+#include "cmCTestGenericHandler.h"
+#include "cmListFileCache.h"
+
+#include <cmsys/RegularExpression.hxx>
+
+class cmMakefile;
+
+/** \class cmCTestBuildHandler
+ * \brief A class that handles ctest -S invocations
+ *
+ */
+class cmCTestBuildHandler : public cmCTestGenericHandler
+{
+public:
+ cmTypeMacro(cmCTestBuildHandler, cmCTestGenericHandler);
+
+ /*
+ * The main entry point for this class
+ */
+ int ProcessHandler();
+
+ cmCTestBuildHandler();
+
+ void PopulateCustomVectors(cmMakefile *mf);
+
+ /**
+ * Initialize handler
+ */
+ virtual void Initialize();
+
+ int GetTotalErrors() { return this->TotalErrors;}
+ int GetTotalWarnings() { return this->TotalWarnings;}
+
+private:
+ std::string GetMakeCommand();
+
+ //! Run command specialized for make and configure. Returns process status
+ // and retVal is return value or exception.
+ int RunMakeCommand(const char* command,
+ int* retVal, const char* dir, int timeout,
+ std::ofstream& ofs);
+
+ enum {
+ b_REGULAR_LINE,
+ b_WARNING_LINE,
+ b_ERROR_LINE
+ };
+
+ class cmCTestCompileErrorWarningRex
+ {
+ public:
+ cmCTestCompileErrorWarningRex() {}
+ int FileIndex;
+ int LineIndex;
+ cmsys::RegularExpression RegularExpression;
+ };
+
+ struct cmCTestBuildErrorWarning
+ {
+ bool Error;
+ int LogLine;
+ std::string Text;
+ std::string SourceFile;
+ std::string SourceFileTail;
+ int LineNumber;
+ std::string PreContext;
+ std::string PostContext;
+ };
+
+ // 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);
+ bool IsLaunchedErrorFile(const char* fname);
+ bool IsLaunchedWarningFile(const char* fname);
+
+ std::string StartBuild;
+ std::string EndBuild;
+ double StartBuildTime;
+ double EndBuildTime;
+
+ std::vector<cmStdString> CustomErrorMatches;
+ std::vector<cmStdString> CustomErrorExceptions;
+ std::vector<cmStdString> CustomWarningMatches;
+ std::vector<cmStdString> CustomWarningExceptions;
+ std::vector<std::string> ReallyCustomWarningMatches;
+ std::vector<std::string> ReallyCustomWarningExceptions;
+ std::vector<cmCTestCompileErrorWarningRex> ErrorWarningFileLineRegex;
+
+ std::vector<cmsys::RegularExpression> ErrorMatchRegex;
+ std::vector<cmsys::RegularExpression> ErrorExceptionRegex;
+ std::vector<cmsys::RegularExpression> WarningMatchRegex;
+ std::vector<cmsys::RegularExpression> WarningExceptionRegex;
+
+ 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);
+ int ProcessSingleLine(const char* data);
+
+ t_BuildProcessingQueueType BuildProcessingQueue;
+ t_BuildProcessingQueueType BuildProcessingErrorQueue;
+ size_t BuildOutputLogSize;
+ std::vector<char> CurrentProcessingLine;
+
+ cmStdString SimplifySourceDir;
+ cmStdString SimplifyBuildDir;
+ size_t OutputLineCounter;
+ typedef std::vector<cmCTestBuildErrorWarning> t_ErrorsAndWarningsVector;
+ t_ErrorsAndWarningsVector ErrorsAndWarnings;
+ t_ErrorsAndWarningsVector::iterator LastErrorOrWarning;
+ size_t PostContextCount;
+ size_t MaxPreContext;
+ size_t MaxPostContext;
+ std::deque<cmStdString> PreContext;
+
+ int TotalErrors;
+ int TotalWarnings;
+ char LastTickChar;
+
+ bool ErrorQuotaReached;
+ bool WarningQuotaReached;
+
+ int MaxErrors;
+ int MaxWarnings;
+
+ bool UseCTestLaunch;
+ std::string CTestLaunchDir;
+ class LaunchHelper;
+ friend class LaunchHelper;
+ class FragmentCompare;
+};
+
+#endif
diff --git a/Source/CTest/cmCTestCVS.cxx b/Source/CTest/cmCTestCVS.cxx
new file mode 100644
index 000000000..726950704
--- /dev/null
+++ b/Source/CTest/cmCTestCVS.cxx
@@ -0,0 +1,319 @@
+/*============================================================================
+ 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 "cmCTestCVS.h"
+
+#include "cmCTest.h"
+#include "cmSystemTools.h"
+#include "cmXMLSafe.h"
+
+#include <cmsys/RegularExpression.hxx>
+
+//----------------------------------------------------------------------------
+cmCTestCVS::cmCTestCVS(cmCTest* ct, std::ostream& log): cmCTestVC(ct, log)
+{
+}
+
+//----------------------------------------------------------------------------
+cmCTestCVS::~cmCTestCVS()
+{
+}
+
+//----------------------------------------------------------------------------
+class cmCTestCVS::UpdateParser: public cmCTestVC::LineParser
+{
+public:
+ UpdateParser(cmCTestCVS* cvs, const char* prefix): CVS(cvs)
+ {
+ this->SetLog(&cvs->Log, prefix);
+ // See "man cvs", section "update output".
+ this->RegexFileUpdated.compile("^([UP]) *(.*)");
+ this->RegexFileModified.compile("^([MRA]) *(.*)");
+ this->RegexFileConflicting.compile("^([C]) *(.*)");
+ this->RegexFileRemoved1.compile(
+ "cvs[^ ]* update: `?([^']*)'? is no longer in the repository");
+ this->RegexFileRemoved2.compile(
+ "cvs[^ ]* update: "
+ "warning: `?([^']*)'? is not \\(any longer\\) pertinent");
+ }
+private:
+ cmCTestCVS* CVS;
+ cmsys::RegularExpression RegexFileUpdated;
+ cmsys::RegularExpression RegexFileModified;
+ cmsys::RegularExpression RegexFileConflicting;
+ cmsys::RegularExpression RegexFileRemoved1;
+ cmsys::RegularExpression RegexFileRemoved2;
+
+ virtual bool ProcessLine()
+ {
+ if(this->RegexFileUpdated.find(this->Line))
+ {
+ this->DoFile(PathUpdated, this->RegexFileUpdated.match(2));
+ }
+ else if(this->RegexFileModified.find(this->Line))
+ {
+ this->DoFile(PathModified, this->RegexFileModified.match(2));
+ }
+ else if(this->RegexFileConflicting.find(this->Line))
+ {
+ this->DoFile(PathConflicting, this->RegexFileConflicting.match(2));
+ }
+ else if(this->RegexFileRemoved1.find(this->Line))
+ {
+ this->DoFile(PathUpdated, this->RegexFileRemoved1.match(1));
+ }
+ else if(this->RegexFileRemoved2.find(this->Line))
+ {
+ this->DoFile(PathUpdated, this->RegexFileRemoved2.match(1));
+ }
+ return true;
+ }
+
+ void DoFile(PathStatus status, std::string const& file)
+ {
+ std::string dir = cmSystemTools::GetFilenamePath(file);
+ std::string name = cmSystemTools::GetFilenameName(file);
+ this->CVS->Dirs[dir][name] = status;
+ }
+};
+
+//----------------------------------------------------------------------------
+bool cmCTestCVS::UpdateImpl()
+{
+ // Get user-specified update options.
+ std::string opts = this->CTest->GetCTestConfiguration("UpdateOptions");
+ if(opts.empty())
+ {
+ opts = this->CTest->GetCTestConfiguration("CVSUpdateOptions");
+ if(opts.empty())
+ {
+ opts = "-dP";
+ }
+ }
+ std::vector<cmStdString> args = cmSystemTools::ParseArguments(opts.c_str());
+
+ // Specify the start time for nightly testing.
+ if(this->CTest->GetTestModel() == cmCTest::NIGHTLY)
+ {
+ args.push_back("-D" + this->GetNightlyTime() + " UTC");
+ }
+
+ // Run "cvs update" to update the work tree.
+ std::vector<char const*> cvs_update;
+ 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();
+ ai != args.end(); ++ai)
+ {
+ cvs_update.push_back(ai->c_str());
+ }
+ cvs_update.push_back(0);
+
+ UpdateParser out(this, "up-out> ");
+ UpdateParser err(this, "up-err> ");
+ return this->RunUpdateCommand(&cvs_update[0], &out, &err);
+}
+
+//----------------------------------------------------------------------------
+class cmCTestCVS::LogParser: public cmCTestVC::LineParser
+{
+public:
+ typedef cmCTestCVS::Revision Revision;
+ LogParser(cmCTestCVS* cvs, const char* prefix, std::vector<Revision>& revs):
+ CVS(cvs), Revisions(revs), Section(SectionHeader)
+ {
+ this->SetLog(&cvs->Log, prefix),
+ this->RegexRevision.compile("^revision +([^ ]*) *$");
+ this->RegexBranches.compile("^branches: .*$");
+ this->RegexPerson.compile("^date: +([^;]+); +author: +([^;]+);");
+ }
+private:
+ cmCTestCVS* CVS;
+ std::vector<Revision>& Revisions;
+ cmsys::RegularExpression RegexRevision;
+ cmsys::RegularExpression RegexBranches;
+ cmsys::RegularExpression RegexPerson;
+ enum SectionType { SectionHeader, SectionRevisions, SectionEnd };
+ SectionType Section;
+ Revision Rev;
+
+ virtual bool ProcessLine()
+ {
+ if(this->Line == ("======================================="
+ "======================================"))
+ {
+ // This line ends the revision list.
+ if(this->Section == SectionRevisions)
+ {
+ this->FinishRevision();
+ }
+ this->Section = SectionEnd;
+ }
+ else if(this->Line == "----------------------------")
+ {
+ // This line divides revisions from the header and each other.
+ if(this->Section == SectionHeader)
+ {
+ this->Section = SectionRevisions;
+ }
+ else if(this->Section == SectionRevisions)
+ {
+ this->FinishRevision();
+ }
+ }
+ else if(this->Section == SectionRevisions)
+ {
+ if(!this->Rev.Log.empty())
+ {
+ // Continue the existing log.
+ this->Rev.Log += this->Line;
+ this->Rev.Log += "\n";
+ }
+ else if(this->Rev.Rev.empty() && this->RegexRevision.find(this->Line))
+ {
+ this->Rev.Rev = this->RegexRevision.match(1);
+ }
+ else if(this->Rev.Date.empty() && this->RegexPerson.find(this->Line))
+ {
+ this->Rev.Date = this->RegexPerson.match(1);
+ this->Rev.Author = this->RegexPerson.match(2);
+ }
+ else if(!this->RegexBranches.find(this->Line))
+ {
+ // Start the log.
+ this->Rev.Log += this->Line;
+ this->Rev.Log += "\n";
+ }
+ }
+ return this->Section != SectionEnd;
+ }
+
+ void FinishRevision()
+ {
+ if(!this->Rev.Rev.empty())
+ {
+ // Record this revision.
+ this->CVS->Log << "Found revision " << this->Rev.Rev << "\n"
+ << " author = " << this->Rev.Author << "\n"
+ << " date = " << this->Rev.Date << "\n";
+ this->Revisions.push_back(this->Rev);
+
+ // We only need two revisions.
+ if(this->Revisions.size() >= 2)
+ {
+ this->Section = SectionEnd;
+ }
+ }
+ this->Rev = Revision();
+ }
+};
+
+//----------------------------------------------------------------------------
+std::string cmCTestCVS::ComputeBranchFlag(std::string const& dir)
+{
+ // Compute the tag file location for this directory.
+ std::string tagFile = this->SourceDirectory;
+ if(!dir.empty())
+ {
+ tagFile += "/";
+ tagFile += dir;
+ }
+ tagFile += "/CVS/Tag";
+
+ // Lookup the branch in the tag file, if any.
+ std::string tagLine;
+ std::ifstream tagStream(tagFile.c_str());
+ if(tagStream && cmSystemTools::GetLineFromStream(tagStream, tagLine) &&
+ tagLine.size() > 1 && tagLine[0] == 'T')
+ {
+ // Use the branch specified in the tag file.
+ std::string flag = "-r";
+ flag += tagLine.substr(1);
+ return flag;
+ }
+ else
+ {
+ // Use the default branch.
+ return "-b";
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmCTestCVS::LoadRevisions(std::string const& file,
+ const char* branchFlag,
+ std::vector<Revision>& revisions)
+{
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, "." << std::flush);
+
+ // Run "cvs log" to get revisions of this file on this branch.
+ const char* cvs = this->CommandLineTool.c_str();
+ const char* cvs_log[] =
+ {cvs, "log", "-N", branchFlag, file.c_str(), 0};
+
+ LogParser out(this, "log-out> ", revisions);
+ OutputLogger err(this->Log, "log-err> ");
+ this->RunChild(cvs_log, &out, &err);
+}
+
+//----------------------------------------------------------------------------
+void cmCTestCVS::WriteXMLDirectory(std::ostream& xml,
+ std::string const& path,
+ Directory const& dir)
+{
+ const char* slash = path.empty()? "":"/";
+ xml << "\t<Directory>\n"
+ << "\t\t<Name>" << cmXMLSafe(path) << "</Name>\n";
+
+ // Lookup the branch checked out in the working tree.
+ std::string branchFlag = this->ComputeBranchFlag(path);
+
+ // Load revisions and write an entry for each file in this directory.
+ std::vector<Revision> revisions;
+ for(Directory::const_iterator fi = dir.begin(); fi != dir.end(); ++fi)
+ {
+ std::string full = path + slash + fi->first;
+
+ // Load two real or unknown revisions.
+ revisions.clear();
+ if(fi->second != PathUpdated)
+ {
+ // For local modifications the current rev is unknown and the
+ // prior rev is the latest from cvs.
+ revisions.push_back(this->Unknown);
+ }
+ this->LoadRevisions(full, branchFlag.c_str(), revisions);
+ revisions.resize(2, this->Unknown);
+
+ // Write the entry for this file with these revisions.
+ File f(fi->second, &revisions[0], &revisions[1]);
+ this->WriteXMLEntry(xml, path, fi->first, full, f);
+ }
+ xml << "\t</Directory>\n";
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestCVS::WriteXMLUpdates(std::ostream& xml)
+{
+ cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ " Gathering version information (one . per updated file):\n"
+ " " << std::flush);
+
+ for(std::map<cmStdString, Directory>::const_iterator
+ di = this->Dirs.begin(); di != this->Dirs.end(); ++di)
+ {
+ this->WriteXMLDirectory(xml, di->first, di->second);
+ }
+
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, std::endl);
+
+ return true;
+}
diff --git a/Source/CTest/cmCTestCVS.h b/Source/CTest/cmCTestCVS.h
new file mode 100644
index 000000000..b7fe567d8
--- /dev/null
+++ b/Source/CTest/cmCTestCVS.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 cmCTestCVS_h
+#define cmCTestCVS_h
+
+#include "cmCTestVC.h"
+
+/** \class cmCTestCVS
+ * \brief Interaction with cvs command-line tool
+ *
+ */
+class cmCTestCVS: public cmCTestVC
+{
+public:
+ /** Construct with a CTest instance and update log stream. */
+ cmCTestCVS(cmCTest* ctest, std::ostream& log);
+
+ virtual ~cmCTestCVS();
+
+private:
+ // Implement cmCTestVC internal API.
+ virtual bool UpdateImpl();
+ virtual bool WriteXMLUpdates(std::ostream& xml);
+
+ // Update status for files in each directory.
+ class Directory: public std::map<cmStdString, PathStatus> {};
+ std::map<cmStdString, 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,
+ Directory const& dir);
+
+ // Parsing helper classes.
+ class UpdateParser;
+ class LogParser;
+ friend class UpdateParser;
+ friend class LogParser;
+};
+
+#endif
diff --git a/Source/CTest/cmCTestCommand.h b/Source/CTest/cmCTestCommand.h
new file mode 100644
index 000000000..e2ebba8fd
--- /dev/null
+++ b/Source/CTest/cmCTestCommand.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 cmCTestCommand_h
+#define cmCTestCommand_h
+
+#include "cmCommand.h"
+
+class cmCTest;
+class cmCTestScriptHandler;
+
+/** \class cmCTestCommand
+ * \brief A superclass for all commands added to the CTestScriptHandler
+ *
+ * cmCTestCommand is the superclass for all commands that will be added to
+ * the ctest script handlers parser.
+ *
+ */
+class cmCTestCommand : public cmCommand
+{
+public:
+
+ cmCTestCommand() {this->CTest = 0; this->CTestScriptHandler = 0;}
+
+ cmCTest *CTest;
+ cmCTestScriptHandler *CTestScriptHandler;
+
+ cmTypeMacro(cmCTestCommand, cmCommand);
+};
+
+
+#endif
diff --git a/Source/CTest/cmCTestConfigureCommand.cxx b/Source/CTest/cmCTestConfigureCommand.cxx
new file mode 100644
index 000000000..7a99ddfa0
--- /dev/null
+++ b/Source/CTest/cmCTestConfigureCommand.cxx
@@ -0,0 +1,172 @@
+/*============================================================================
+ 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 "cmCTestConfigureCommand.h"
+
+#include "cmGlobalGenerator.h"
+#include "cmCTest.h"
+#include "cmCTestGenericHandler.h"
+
+cmCTestConfigureCommand::cmCTestConfigureCommand()
+{
+ this->Arguments[ctc_OPTIONS] = "OPTIONS";
+ this->Arguments[ctc_LAST] = 0;
+ this->Last = ctc_LAST;
+}
+
+cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler()
+{
+ std::vector<std::string> options;
+
+ if (this->Values[ctc_OPTIONS])
+ {
+ cmSystemTools::ExpandListArgument(this->Values[ctc_OPTIONS], options);
+ }
+
+ if ( this->Values[ct_BUILD] )
+ {
+ this->CTest->SetCTestConfiguration("BuildDirectory",
+ cmSystemTools::CollapseFullPath(
+ this->Values[ct_BUILD]).c_str());
+ }
+ else
+ {
+ this->CTest->SetCTestConfiguration("BuildDirectory",
+ cmSystemTools::CollapseFullPath(
+ this->Makefile->GetSafeDefinition("CTEST_BINARY_DIRECTORY")).c_str());
+ }
+
+ if ( this->Values[ct_SOURCE] )
+ {
+ this->CTest->SetCTestConfiguration("SourceDirectory",
+ cmSystemTools::CollapseFullPath(
+ this->Values[ct_SOURCE]).c_str());
+ }
+ else
+ {
+ this->CTest->SetCTestConfiguration("SourceDirectory",
+ cmSystemTools::CollapseFullPath(
+ this->Makefile->GetSafeDefinition("CTEST_SOURCE_DIRECTORY")).c_str());
+ }
+
+ if ( this->CTest->GetCTestConfiguration("BuildDirectory").empty() )
+ {
+ this->SetError("Build directory not specified. Either use BUILD "
+ "argument to CTEST_CONFIGURE command or set CTEST_BINARY_DIRECTORY "
+ "variable");
+ return 0;
+ }
+
+ const char* ctestConfigureCommand
+ = this->Makefile->GetDefinition("CTEST_CONFIGURE_COMMAND");
+
+ if ( ctestConfigureCommand && *ctestConfigureCommand )
+ {
+ this->CTest->SetCTestConfiguration("ConfigureCommand",
+ ctestConfigureCommand);
+ }
+ else
+ {
+ const char* cmakeGeneratorName
+ = this->Makefile->GetDefinition("CTEST_CMAKE_GENERATOR");
+ if ( cmakeGeneratorName && *cmakeGeneratorName )
+ {
+ const std::string& source_dir
+ = this->CTest->GetCTestConfiguration("SourceDirectory");
+ if ( source_dir.empty() )
+ {
+ this->SetError("Source directory not specified. Either use SOURCE "
+ "argument to CTEST_CONFIGURE command or set CTEST_SOURCE_DIRECTORY "
+ "variable");
+ return 0;
+ }
+
+ const std::string cmakelists_file = source_dir + "/CMakeLists.txt";
+ if ( !cmSystemTools::FileExists(cmakelists_file.c_str()) )
+ {
+ cmOStringStream e;
+ e << "CMakeLists.txt file does not exist ["
+ << cmakelists_file << "]";
+ this->SetError(e.str().c_str());
+ return 0;
+ }
+
+ bool multiConfig = false;
+ bool cmakeBuildTypeInOptions = false;
+
+ cmGlobalGenerator *gg =
+ this->Makefile->GetCMakeInstance()->CreateGlobalGenerator(
+ cmakeGeneratorName);
+ if(gg)
+ {
+ multiConfig = gg->IsMultiConfig();
+ delete gg;
+ }
+
+ std::string cmakeConfigureCommand = "\"";
+ cmakeConfigureCommand += this->CTest->GetCMakeExecutable();
+ cmakeConfigureCommand += "\"";
+
+ std::vector<std::string>::const_iterator it;
+ std::string option;
+ for (it= options.begin(); it!=options.end(); ++it)
+ {
+ option = *it;
+
+ cmakeConfigureCommand += " \"";
+ cmakeConfigureCommand += option;
+ cmakeConfigureCommand += "\"";
+
+ if ((0 != strstr(option.c_str(), "CMAKE_BUILD_TYPE=")) ||
+ (0 != strstr(option.c_str(), "CMAKE_BUILD_TYPE:STRING=")))
+ {
+ cmakeBuildTypeInOptions = true;
+ }
+ }
+
+ if (!multiConfig && !cmakeBuildTypeInOptions &&
+ !this->CTest->GetConfigType().empty())
+ {
+ cmakeConfigureCommand += " \"-DCMAKE_BUILD_TYPE:STRING=";
+ cmakeConfigureCommand += this->CTest->GetConfigType();
+ cmakeConfigureCommand += "\"";
+ }
+
+ cmakeConfigureCommand += " \"-G";
+ cmakeConfigureCommand += cmakeGeneratorName;
+ cmakeConfigureCommand += "\"";
+
+ cmakeConfigureCommand += " \"";
+ cmakeConfigureCommand += source_dir;
+ cmakeConfigureCommand += "\"";
+
+ this->CTest->SetCTestConfiguration("ConfigureCommand",
+ cmakeConfigureCommand.c_str());
+ }
+ else
+ {
+ this->SetError("Configure command is not specified. If this is a "
+ "\"built with CMake\" project, set CTEST_CMAKE_GENERATOR. If not, "
+ "set CTEST_CONFIGURE_COMMAND.");
+ return 0;
+ }
+ }
+
+ cmCTestGenericHandler* handler
+ = this->CTest->GetInitializedHandler("configure");
+ if ( !handler )
+ {
+ this->SetError(
+ "internal CTest error. Cannot instantiate configure handler");
+ return 0;
+ }
+ return handler;
+}
diff --git a/Source/CTest/cmCTestConfigureCommand.h b/Source/CTest/cmCTestConfigureCommand.h
new file mode 100644
index 000000000..b343fc1e9
--- /dev/null
+++ b/Source/CTest/cmCTestConfigureCommand.h
@@ -0,0 +1,84 @@
+/*============================================================================
+ 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 cmCTestConfigureCommand_h
+#define cmCTestConfigureCommand_h
+
+#include "cmCTestHandlerCommand.h"
+
+/** \class cmCTestConfigure
+ * \brief Run a ctest script
+ *
+ * cmCTestConfigureCommand defineds the command to configures the project.
+ */
+class cmCTestConfigureCommand : public cmCTestHandlerCommand
+{
+public:
+ cmCTestConfigureCommand();
+
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ cmCTestConfigureCommand* ni = new cmCTestConfigureCommand;
+ ni->CTest = this->CTest;
+ ni->CTestScriptHandler = this->CTestScriptHandler;
+ return ni;
+ }
+
+ /**
+ * 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;
+ }
+
+ cmTypeMacro(cmCTestConfigureCommand, cmCTestHandlerCommand);
+
+protected:
+ cmCTestGenericHandler* InitializeHandler();
+
+ enum {
+ ctc_FIRST = ct_LAST,
+ ctc_OPTIONS,
+ ctc_LAST
+ };
+};
+
+
+#endif
diff --git a/Source/CTest/cmCTestConfigureHandler.cxx b/Source/CTest/cmCTestConfigureHandler.cxx
new file mode 100644
index 000000000..33297564e
--- /dev/null
+++ b/Source/CTest/cmCTestConfigureHandler.cxx
@@ -0,0 +1,132 @@
+/*============================================================================
+ 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 "cmCTestConfigureHandler.h"
+
+#include "cmCTest.h"
+#include "cmGeneratedFileStream.h"
+#include "cmake.h"
+#include "cmXMLSafe.h"
+#include <cmsys/Process.h>
+
+
+//----------------------------------------------------------------------
+cmCTestConfigureHandler::cmCTestConfigureHandler()
+{
+}
+
+//----------------------------------------------------------------------
+void cmCTestConfigureHandler::Initialize()
+{
+ this->Superclass::Initialize();
+}
+
+//----------------------------------------------------------------------
+//clearly it would be nice if this were broken up into a few smaller
+//functions and commented...
+int cmCTestConfigureHandler::ProcessHandler()
+{
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, "Configure project" << std::endl);
+ std::string cCommand
+ = this->CTest->GetCTestConfiguration("ConfigureCommand");
+ if ( cCommand.size() == 0 )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Cannot find ConfigureCommand key in the DartConfiguration.tcl"
+ << std::endl);
+ return -1;
+ }
+
+ std::string buildDirectory
+ = this->CTest->GetCTestConfiguration("BuildDirectory");
+ if ( buildDirectory.size() == 0 )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Cannot find BuildDirectory key in the DartConfiguration.tcl"
+ << std::endl);
+ return -1;
+ }
+
+ double elapsed_time_start = cmSystemTools::GetTime();
+ std::string output;
+ int retVal = 0;
+ int res = 0;
+ if ( !this->CTest->GetShowOnly() )
+ {
+ cmGeneratedFileStream os;
+ if(!this->StartResultingXML(cmCTest::PartConfigure, "Configure", os))
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot open configure file"
+ << std::endl);
+ return 1;
+ }
+ std::string start_time = this->CTest->CurrentTime();
+ unsigned int start_time_time = static_cast<unsigned int>(
+ cmSystemTools::GetTime());
+
+ 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,
+ &retVal, buildDirectory.c_str(),
+ 0, ofs);
+
+ if ( ofs )
+ {
+ ofs.close();
+ }
+
+ 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);
+ }
+ }
+ else
+ {
+ cmCTestLog(this->CTest, DEBUG, "Configure with command: " << cCommand
+ << std::endl);
+ }
+ if (! res || retVal )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Error(s) when configuring the project" << std::endl);
+ return -1;
+ }
+ return 0;
+}
diff --git a/Source/CTest/cmCTestConfigureHandler.h b/Source/CTest/cmCTestConfigureHandler.h
new file mode 100644
index 000000000..d880bd7df
--- /dev/null
+++ b/Source/CTest/cmCTestConfigureHandler.h
@@ -0,0 +1,39 @@
+/*============================================================================
+ 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 cmCTestConfigureHandler_h
+#define cmCTestConfigureHandler_h
+
+
+#include "cmCTestGenericHandler.h"
+#include "cmListFileCache.h"
+
+/** \class cmCTestConfigureHandler
+ * \brief A class that handles ctest -S invocations
+ *
+ */
+class cmCTestConfigureHandler : public cmCTestGenericHandler
+{
+public:
+ cmTypeMacro(cmCTestConfigureHandler, cmCTestGenericHandler);
+
+ /*
+ * The main entry point for this class
+ */
+ int ProcessHandler();
+
+ cmCTestConfigureHandler();
+
+ void Initialize();
+};
+
+#endif
diff --git a/Source/CTest/cmCTestCoverageCommand.cxx b/Source/CTest/cmCTestCoverageCommand.cxx
new file mode 100644
index 000000000..72ff720d3
--- /dev/null
+++ b/Source/CTest/cmCTestCoverageCommand.cxx
@@ -0,0 +1,73 @@
+/*============================================================================
+ 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 "cmCTestCoverageCommand.h"
+
+#include "cmCTest.h"
+#include "cmCTestCoverageHandler.h"
+
+//----------------------------------------------------------------------------
+cmCTestCoverageCommand::cmCTestCoverageCommand()
+{
+ this->LabelsMentioned = false;
+}
+
+//----------------------------------------------------------------------------
+cmCTestGenericHandler* cmCTestCoverageCommand::InitializeHandler()
+{
+ this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
+ "CoverageCommand", "CTEST_COVERAGE_COMMAND");
+
+ cmCTestCoverageHandler* handler = static_cast<cmCTestCoverageHandler*>(
+ this->CTest->GetInitializedHandler("coverage"));
+ if ( !handler )
+ {
+ this->SetError("internal CTest error. Cannot instantiate test handler");
+ return 0;
+ }
+
+ // If a LABELS option was given, select only files with the labels.
+ if(this->LabelsMentioned)
+ {
+ handler->SetLabelFilter(this->Labels);
+ }
+
+ return handler;
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestCoverageCommand::CheckArgumentKeyword(std::string const& arg)
+{
+ // Look for arguments specific to this command.
+ if(arg == "LABELS")
+ {
+ this->ArgumentDoing = ArgumentDoingLabels;
+ this->LabelsMentioned = true;
+ return true;
+ }
+
+ // Look for other arguments.
+ return this->Superclass::CheckArgumentKeyword(arg);
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestCoverageCommand::CheckArgumentValue(std::string const& arg)
+{
+ // Handle states specific to this command.
+ if(this->ArgumentDoing == ArgumentDoingLabels)
+ {
+ this->Labels.insert(arg);
+ return true;
+ }
+
+ // Look for other arguments.
+ return this->Superclass::CheckArgumentValue(arg);
+}
diff --git a/Source/CTest/cmCTestCoverageCommand.h b/Source/CTest/cmCTestCoverageCommand.h
new file mode 100644
index 000000000..2fe762c45
--- /dev/null
+++ b/Source/CTest/cmCTestCoverageCommand.h
@@ -0,0 +1,90 @@
+/*============================================================================
+ 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 cmCTestCoverageCommand_h
+#define cmCTestCoverageCommand_h
+
+#include "cmCTestHandlerCommand.h"
+
+/** \class cmCTestCoverage
+ * \brief Run a ctest script
+ *
+ * cmCTestCoverageCommand defineds the command to test the project.
+ */
+class cmCTestCoverageCommand : public cmCTestHandlerCommand
+{
+public:
+
+ cmCTestCoverageCommand();
+
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ cmCTestCoverageCommand* ni = new cmCTestCoverageCommand;
+ ni->CTest = this->CTest;
+ ni->CTestScriptHandler = this->CTestScriptHandler;
+ return ni;
+ }
+
+ /**
+ * 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;
+ }
+
+ cmTypeMacro(cmCTestCoverageCommand, cmCTestHandlerCommand);
+
+protected:
+ cmCTestGenericHandler* InitializeHandler();
+
+ virtual bool CheckArgumentKeyword(std::string const& arg);
+ virtual bool CheckArgumentValue(std::string const& arg);
+
+ enum
+ {
+ ArgumentDoingLabels = Superclass::ArgumentDoingLast1,
+ ArgumentDoingLast2
+ };
+
+ bool LabelsMentioned;
+ std::set<cmStdString> Labels;
+};
+
+
+#endif
+
diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx
new file mode 100644
index 000000000..81d366937
--- /dev/null
+++ b/Source/CTest/cmCTestCoverageHandler.cxx
@@ -0,0 +1,2144 @@
+/*============================================================================
+ 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 "cmCTestCoverageHandler.h"
+#include "cmParsePHPCoverage.h"
+#include "cmParseGTMCoverage.h"
+#include "cmParseCacheCoverage.h"
+#include "cmCTest.h"
+#include "cmake.h"
+#include "cmMakefile.h"
+#include "cmSystemTools.h"
+#include "cmGeneratedFileStream.h"
+#include "cmXMLSafe.h"
+
+#include <cmsys/Process.h>
+#include <cmsys/RegularExpression.hxx>
+#include <cmsys/Glob.hxx>
+#include <cmsys/stl/iterator>
+#include <cmsys/stl/algorithm>
+
+#include <stdlib.h>
+#include <math.h>
+#include <float.h>
+
+#define SAFEDIV(x,y) (((y)!=0)?((x)/(y)):(0))
+
+class cmCTestRunProcess
+{
+public:
+ cmCTestRunProcess()
+ {
+ this->Process = cmsysProcess_New();
+ this->PipeState = -1;
+ this->TimeOut = -1;
+ }
+ ~cmCTestRunProcess()
+ {
+ if(!(this->PipeState == -1)
+ && !(this->PipeState == cmsysProcess_Pipe_None )
+ && !(this->PipeState == cmsysProcess_Pipe_Timeout))
+ {
+ this->WaitForExit();
+ }
+ cmsysProcess_Delete(this->Process);
+ }
+ void SetCommand(const char* command)
+ {
+ this->CommandLineStrings.clear();
+ this->CommandLineStrings.push_back(command);;
+ }
+ void AddArgument(const char* arg)
+ {
+ if(arg)
+ {
+ this->CommandLineStrings.push_back(arg);
+ }
+ }
+ void SetWorkingDirectory(const char* dir)
+ {
+ this->WorkingDirectory = dir;
+ }
+ void SetTimeout(double t)
+ {
+ this->TimeOut = t;
+ }
+ bool StartProcess()
+ {
+ std::vector<const char*> args;
+ for(std::vector<std::string>::iterator i =
+ this->CommandLineStrings.begin();
+ i != this->CommandLineStrings.end(); ++i)
+ {
+ args.push_back(i->c_str());
+ }
+ args.push_back(0); // null terminate
+ cmsysProcess_SetCommand(this->Process, &*args.begin());
+ if(this->WorkingDirectory.size())
+ {
+ cmsysProcess_SetWorkingDirectory(this->Process,
+ this->WorkingDirectory.c_str());
+ }
+
+ cmsysProcess_SetOption(this->Process,
+ cmsysProcess_Option_HideWindow, 1);
+ if(this->TimeOut != -1)
+ {
+ cmsysProcess_SetTimeout(this->Process, this->TimeOut);
+ }
+ cmsysProcess_Execute(this->Process);
+ this->PipeState = cmsysProcess_GetState(this->Process);
+ // if the process is running or exited return true
+ if(this->PipeState == cmsysProcess_State_Executing
+ || this->PipeState == cmsysProcess_State_Exited)
+ {
+ return true;
+ }
+ return false;
+ }
+ void SetStdoutFile(const char* fname)
+ {
+ cmsysProcess_SetPipeFile(this->Process, cmsysProcess_Pipe_STDOUT, fname);
+ }
+ void SetStderrFile(const char* fname)
+ {
+ cmsysProcess_SetPipeFile(this->Process, cmsysProcess_Pipe_STDERR, fname);
+ }
+ int WaitForExit(double* timeout =0)
+ {
+ this->PipeState = cmsysProcess_WaitForExit(this->Process,
+ timeout);
+ return this->PipeState;
+ }
+ int GetProcessState() { return this->PipeState;}
+private:
+ int PipeState;
+ cmsysProcess* Process;
+ std::vector<std::string> CommandLineStrings;
+ std::string WorkingDirectory;
+ double TimeOut;
+};
+
+
+//----------------------------------------------------------------------
+
+//----------------------------------------------------------------------
+cmCTestCoverageHandler::cmCTestCoverageHandler()
+{
+}
+
+//----------------------------------------------------------------------
+void cmCTestCoverageHandler::Initialize()
+{
+ this->Superclass::Initialize();
+ this->CustomCoverageExclude.clear();
+ this->SourceLabels.clear();
+ this->LabelIdMap.clear();
+ this->Labels.clear();
+ this->LabelFilter.clear();
+}
+
+//----------------------------------------------------------------------------
+void cmCTestCoverageHandler::CleanCoverageLogFiles(std::ostream& log)
+{
+ std::string logGlob = this->CTest->GetCTestConfiguration("BuildDirectory");
+ logGlob += "/Testing/";
+ logGlob += this->CTest->GetCurrentTag();
+ logGlob += "/CoverageLog*";
+ cmsys::Glob gl;
+ gl.FindFiles(logGlob.c_str());
+ 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());
+ }
+}
+
+//----------------------------------------------------------------------
+bool cmCTestCoverageHandler::StartCoverageLogFile(
+ cmGeneratedFileStream& covLogFile, int logFileCount)
+{
+ char covLogFilename[1024];
+ sprintf(covLogFilename, "CoverageLog-%d", logFileCount);
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Open file: "
+ << covLogFilename << std::endl);
+ if(!this->StartResultingXML(cmCTest::PartCoverage,
+ covLogFilename, covLogFile))
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot open log file: "
+ << 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;
+}
+
+//----------------------------------------------------------------------
+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);
+ ostr.Close();
+}
+
+//----------------------------------------------------------------------
+bool cmCTestCoverageHandler::ShouldIDoCoverage(const char* file,
+ const char* srcDir,
+ const char* binDir)
+{
+ if(this->IsFilteredOut(file))
+ {
+ return false;
+ }
+
+ std::vector<cmsys::RegularExpression>::iterator sit;
+ for ( sit = this->CustomCoverageExcludeRegex.begin();
+ sit != this->CustomCoverageExcludeRegex.end(); ++ sit )
+ {
+ if ( sit->find(file) )
+ {
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " File " << file
+ << " is excluded in CTestCustom.ctest" << std::endl;);
+ return false;
+ }
+ }
+
+ 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());
+ // Always check parent directory of the file.
+ std::string fileDir = cmSystemTools::GetFilenamePath(fFile.c_str());
+ std::string checkDir;
+
+ // We also need to check the binary/source directory pair.
+ if ( sourceSubDir && buildSubDir )
+ {
+ if ( fSrcDir.size() > fBinDir.size() )
+ {
+ checkDir = fSrcDir;
+ }
+ else
+ {
+ checkDir = fBinDir;
+ }
+ }
+ else if ( sourceSubDir )
+ {
+ checkDir = fSrcDir;
+ }
+ else if ( buildSubDir )
+ {
+ checkDir = fBinDir;
+ }
+ std::string ndc
+ = cmSystemTools::FileExistsInParentDirectories(".NoDartCoverage",
+ fFile.c_str(), checkDir.c_str());
+ if ( ndc.size() )
+ {
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Found: " << ndc.c_str()
+ << " so skip coverage of " << file << std::endl);
+ return false;
+ }
+
+ // By now checkDir should be set to parent directory of the 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() )
+ {
+ relPath = cmSystemTools::RelativePath(checkDir.c_str(),
+ fFile.c_str());
+ }
+ else
+ {
+ relPath = fFile;
+ }
+ if ( checkDir == fSrcDir )
+ {
+ checkDir = fBinDir;
+ }
+ else
+ {
+ checkDir = fSrcDir;
+ }
+ fFile = checkDir + "/" + relPath;
+ fFile = cmSystemTools::GetFilenamePath(fFile.c_str());
+
+ if ( fileDir == fFile )
+ {
+ // This is in-source build, so we trust the previous check.
+ return true;
+ }
+
+ ndc = cmSystemTools::FileExistsInParentDirectories(".NoDartCoverage",
+ fFile.c_str(), checkDir.c_str());
+ if ( ndc.size() )
+ {
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Found: " << ndc.c_str()
+ << " so skip coverage of: " << file << std::endl);
+ return false;
+ }
+ // Ok, nothing in source tree, nothing in binary tree
+ return true;
+}
+
+//----------------------------------------------------------------------
+//clearly it would be nice if this were broken up into a few smaller
+//functions and commented...
+int cmCTestCoverageHandler::ProcessHandler()
+{
+ this->CTest->ClearSubmitFiles(cmCTest::PartCoverage);
+ int error = 0;
+ // do we have time for this
+ if (this->CTest->GetRemainingTimeAllowed() < 120)
+ {
+ return error;
+ }
+
+ std::string coverage_start_time = this->CTest->CurrentTime();
+ unsigned int coverage_start_time_time = static_cast<unsigned int>(
+ cmSystemTools::GetTime());
+ std::string sourceDir
+ = this->CTest->GetCTestConfiguration("SourceDirectory");
+ std::string binaryDir
+ = this->CTest->GetCTestConfiguration("BuildDirectory");
+
+ this->LoadLabels();
+
+ cmGeneratedFileStream ofs;
+ double elapsed_time_start = cmSystemTools::GetTime();
+ if ( !this->StartLogFile("Coverage", ofs) )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Cannot create LastCoverage.log file" << std::endl);
+ }
+
+ ofs << "Performing coverage: " << elapsed_time_start << std::endl;
+ this->CleanCoverageLogFiles(ofs);
+
+ cmSystemTools::ConvertToUnixSlashes(sourceDir);
+ cmSystemTools::ConvertToUnixSlashes(binaryDir);
+
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, "Performing coverage" << std::endl);
+
+ cmCTestCoverageHandlerContainer cont;
+ cont.Error = error;
+ cont.SourceDir = sourceDir;
+ cont.BinaryDir = binaryDir;
+ cont.OFS = &ofs;
+
+ // setup the regex exclude stuff
+ this->CustomCoverageExcludeRegex.clear();
+ std::vector<cmStdString>::iterator rexIt;
+ for ( rexIt = this->CustomCoverageExclude.begin();
+ rexIt != this->CustomCoverageExclude.end();
+ ++ rexIt )
+ {
+ this->CustomCoverageExcludeRegex.push_back(
+ cmsys::RegularExpression(rexIt->c_str()));
+ }
+
+ if(this->HandleBullseyeCoverage(&cont))
+ {
+ return cont.Error;
+ }
+ int file_count = 0;
+ file_count += this->HandleGCovCoverage(&cont);
+ error = cont.Error;
+ if ( file_count < 0 )
+ {
+ return error;
+ }
+ file_count += this->HandleTracePyCoverage(&cont);
+ error = cont.Error;
+ if ( file_count < 0 )
+ {
+ return error;
+ }
+ file_count += this->HandlePHPCoverage(&cont);
+ error = cont.Error;
+ if ( file_count < 0 )
+ {
+ return error;
+ }
+ file_count += this->HandleMumpsCoverage(&cont);
+ error = cont.Error;
+ if ( file_count < 0 )
+ {
+ return error;
+ }
+
+ std::set<std::string> uncovered = this->FindUncoveredFiles(&cont);
+
+ if ( file_count == 0 )
+ {
+ cmCTestLog(this->CTest, WARNING,
+ " Cannot find any coverage files. Ignoring Coverage request."
+ << std::endl);
+ return error;
+ }
+ cmGeneratedFileStream covSumFile;
+ cmGeneratedFileStream covLogFile;
+
+ if(!this->StartResultingXML(cmCTest::PartCoverage, "Coverage", covSumFile))
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Cannot open coverage summary file." << std::endl);
+ return -1;
+ }
+
+ this->CTest->StartXML(covSumFile, 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;
+ int logFileCount = 0;
+ if ( !this->StartCoverageLogFile(covLogFile, logFileCount) )
+ {
+ return -1;
+ }
+ 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, " ");
+
+ std::vector<std::string> errorsWhileAccumulating;
+
+ file_count = 0;
+ for ( fileIterator = cont.TotalCoverage.begin();
+ fileIterator != cont.TotalCoverage.end();
+ ++fileIterator )
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, "." << std::flush);
+ file_count ++;
+ if ( file_count % 50 == 0 )
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " processed: " << file_count
+ << " out of "
+ << cont.TotalCoverage.size() << std::endl);
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " ");
+ }
+
+ const std::string fullFileName = fileIterator->first;
+ bool shouldIDoCoverage
+ = this->ShouldIDoCoverage(fullFileName.c_str(),
+ sourceDir.c_str(), binaryDir.c_str());
+ if ( !shouldIDoCoverage )
+ {
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ ".NoDartCoverage found, so skip coverage check for: "
+ << fullFileName.c_str()
+ << std::endl);
+ continue;
+ }
+
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Process file: " << fullFileName << std::endl);
+
+ if ( !cmSystemTools::FileExists(fullFileName.c_str()) )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot find file: "
+ << fullFileName.c_str() << std::endl);
+ continue;
+ }
+
+ if ( ++cnt % 100 == 0 )
+ {
+ this->EndCoverageLogFile(covLogFile, logFileCount);
+ logFileCount ++;
+ if ( !this->StartCoverageLogFile(covLogFile, logFileCount) )
+ {
+ return -1;
+ }
+ }
+
+ const std::string fileName
+ = cmSystemTools::GetFilenameName(fullFileName.c_str());
+ 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;
+
+ std::ifstream ifs(fullFileName.c_str());
+ if ( !ifs)
+ {
+ cmOStringStream ostr;
+ ostr << "Cannot open source file: " << fullFileName.c_str();
+ errorsWhileAccumulating.push_back(ostr.str());
+ error ++;
+ continue;
+ }
+
+ int tested = 0;
+ int untested = 0;
+
+ cmCTestCoverageHandlerContainer::SingleFileCoverageVector::size_type cc;
+ std::string line;
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Actually performing coverage for: " << fullFileName << std::endl);
+ 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()
+ << " 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;
+ if ( fcov[cc] == 0 )
+ {
+ untested ++;
+ }
+ else if ( fcov[cc] > 0 )
+ {
+ tested ++;
+ }
+ }
+ if ( cmSystemTools::GetLineFromStream(ifs, line) )
+ {
+ cmOStringStream ostr;
+ ostr << "Looks like there are more lines in the file: " << line;
+ errorsWhileAccumulating.push_back(ostr.str());
+ }
+ float cper = 0;
+ float cmet = 0;
+ if ( tested + untested > 0 )
+ {
+ cper = (100 * SAFEDIV(static_cast<float>(tested),
+ static_cast<float>(tested + untested)));
+ cmet = ( SAFEDIV(static_cast<float>(tested + 10),
+ static_cast<float>(tested + untested + 10)));
+ }
+ 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;
+ }
+
+ //Handle all the files in the extra coverage globs that have no cov data
+ for(std::set<std::string>::iterator i = uncovered.begin();
+ i != uncovered.end(); ++i)
+ {
+ 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;
+
+ std::ifstream ifs(fullPath.c_str());
+ if (!ifs)
+ {
+ cmOStringStream ostr;
+ ostr << "Cannot open source file: " << fullPath.c_str();
+ 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);
+ while (cmSystemTools::GetLineFromStream(ifs, line))
+ {
+ covLogFile << "\t\t<Line Number=\"" << untested << "\" Count=\"0\">"
+ << cmXMLSafe(line) << "</Line>" << std::endl;
+ untested ++;
+ }
+ covLogFile << "\t\t</Report>\n\t</File>" << std::endl;
+
+ 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;
+ }
+
+ this->EndCoverageLogFile(covLogFile, logFileCount);
+
+ if ( errorsWhileAccumulating.size() > 0 )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, std::endl);
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Error(s) while accumulating results:" << std::endl);
+ std::vector<std::string>::iterator erIt;
+ for ( erIt = errorsWhileAccumulating.begin();
+ erIt != errorsWhileAccumulating.end();
+ ++ erIt )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ " " << erIt->c_str() << std::endl);
+ }
+ }
+
+ long total_lines = total_tested + total_untested;
+ float percent_coverage = 100 * SAFEDIV(static_cast<float>(total_tested),
+ static_cast<float>(total_lines));
+ if ( total_lines == 0 )
+ {
+ percent_coverage = 0;
+ }
+
+ 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);
+
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, "" << std::endl
+ << "\tCovered LOC: "
+ << total_tested << std::endl
+ << "\tNot covered LOC: " << total_untested << std::endl
+ << "\tTotal LOC: " << total_lines << std::endl
+ << "\tPercentage Coverage: "
+ << std::setiosflags(std::ios::fixed)
+ << std::setprecision(2)
+ << (percent_coverage) << "%" << std::endl);
+
+ ofs << "\tCovered LOC: " << total_tested << std::endl
+ << "\tNot covered LOC: " << total_untested << std::endl
+ << "\tTotal LOC: " << total_lines << std::endl
+ << "\tPercentage Coverage: "
+ << std::setiosflags(std::ios::fixed)
+ << std::setprecision(2)
+ << (percent_coverage) << "%" << std::endl;
+
+
+ if ( error )
+ {
+ return -1;
+ }
+ return 0;
+}
+
+//----------------------------------------------------------------------
+void cmCTestCoverageHandler::PopulateCustomVectors(cmMakefile *mf)
+{
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " Add coverage exclude regular expressions." << std::endl);
+ 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;
+ for ( it = this->CustomCoverageExclude.begin();
+ it != this->CustomCoverageExclude.end();
+ ++ it )
+ {
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Add coverage exclude: "
+ << it->c_str() << std::endl);
+ }
+ for ( it = this->ExtraCoverageGlobs.begin();
+ it != this->ExtraCoverageGlobs.end(); ++it)
+ {
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Add coverage glob: "
+ << it->c_str() << std::endl);
+ }
+}
+
+//----------------------------------------------------------------------
+// Fix for issue #4971 where the case of the drive letter component of
+// the filenames might be different when analyzing gcov output.
+//
+// Compare file names: fnc(fn1) == fnc(fn2) // fnc == file name compare
+//
+#ifdef _WIN32
+#define fnc(s) cmSystemTools::LowerCase(s)
+#else
+#define fnc(s) s
+#endif
+
+//----------------------------------------------------------------------
+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());
+
+ if (
+ file.size() > dir.size() &&
+ (fnc(file.substr(0, dir.size())) == fnc(dir)) &&
+ file[dir.size()] == '/'
+ )
+ {
+ return true;
+ }
+
+ return false;
+}
+
+//----------------------------------------------------------------------
+int cmCTestCoverageHandler::HandlePHPCoverage(
+ cmCTestCoverageHandlerContainer* cont)
+{
+ cmParsePHPCoverage cov(*cont, this->CTest);
+ std::string coverageDir = this->CTest->GetBinaryDir() + "/xdebugCoverage";
+ if(cmSystemTools::FileIsDirectory(coverageDir.c_str()))
+ {
+ cov.ReadPHPCoverageDirectory(coverageDir.c_str());
+ }
+ return static_cast<int>(cont->TotalCoverage.size());
+}
+//----------------------------------------------------------------------
+int cmCTestCoverageHandler::HandleMumpsCoverage(
+ cmCTestCoverageHandlerContainer* cont)
+{
+ // try gtm coverage
+ cmParseGTMCoverage cov(*cont, this->CTest);
+ std::string coverageFile = this->CTest->GetBinaryDir() +
+ "/gtm_coverage.mcov";
+ if(cmSystemTools::FileExists(coverageFile.c_str()))
+ {
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Parsing Cache Coverage: " << coverageFile
+ << std::endl);
+ 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);
+ }
+ cmParseCacheCoverage ccov(*cont, this->CTest);
+ coverageFile = this->CTest->GetBinaryDir() +
+ "/cache_coverage.cmcov";
+ if(cmSystemTools::FileExists(coverageFile.c_str()))
+ {
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Parsing Cache Coverage: " << coverageFile
+ << std::endl);
+ ccov.ReadCoverageFile(coverageFile.c_str());
+ }
+ else
+ {
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " Cannot find Cache coverage file: " << coverageFile
+ << std::endl);
+ }
+ return static_cast<int>(cont->TotalCoverage.size());
+}
+
+struct cmCTestCoverageHandlerLocale
+{
+ cmCTestCoverageHandlerLocale()
+ {
+ if(const char* l = cmSystemTools::GetEnv("LC_ALL"))
+ {
+ lc_all = l;
+ }
+ if(lc_all != "C")
+ {
+ cmSystemTools::PutEnv("LC_ALL=C");
+ }
+ }
+ ~cmCTestCoverageHandlerLocale()
+ {
+ if(!lc_all.empty())
+ {
+ cmSystemTools::PutEnv(("LC_ALL=" + lc_all).c_str());
+ }
+ else
+ {
+ cmSystemTools::UnsetEnv("LC_ALL");
+ }
+ }
+ std::string lc_all;
+};
+
+//----------------------------------------------------------------------
+int cmCTestCoverageHandler::HandleGCovCoverage(
+ cmCTestCoverageHandlerContainer* cont)
+{
+ std::string gcovCommand
+ = this->CTest->GetCTestConfiguration("CoverageCommand");
+ std::string gcovExtraFlags
+ = this->CTest->GetCTestConfiguration("CoverageExtraFlags");
+
+ // Style 1
+ std::string st1gcovOutputRex1
+ = "[0-9]+\\.[0-9]+% of [0-9]+ (source |)lines executed in file (.*)$";
+ std::string st1gcovOutputRex2 = "^Creating (.*\\.gcov)\\.";
+ cmsys::RegularExpression st1re1(st1gcovOutputRex1.c_str());
+ cmsys::RegularExpression st1re2(st1gcovOutputRex2.c_str());
+
+
+ // Style 2
+ std::string st2gcovOutputRex1 = "^File *[`'](.*)'$";
+ std::string st2gcovOutputRex2
+ = "Lines executed: *[0-9]+\\.[0-9]+% of [0-9]+$";
+ std::string st2gcovOutputRex3 = "^(.*)reating [`'](.*\\.gcov)'";
+ std::string st2gcovOutputRex4 = "^(.*):unexpected EOF *$";
+ std::string st2gcovOutputRex5 = "^(.*):cannot open source file*$";
+ std::string st2gcovOutputRex6
+ = "^(.*):source file is newer than graph file `(.*)'$";
+ cmsys::RegularExpression st2re1(st2gcovOutputRex1.c_str());
+ cmsys::RegularExpression st2re2(st2gcovOutputRex2.c_str());
+ cmsys::RegularExpression st2re3(st2gcovOutputRex3.c_str());
+ cmsys::RegularExpression st2re4(st2gcovOutputRex4.c_str());
+ cmsys::RegularExpression st2re5(st2gcovOutputRex5.c_str());
+ cmsys::RegularExpression st2re6(st2gcovOutputRex6.c_str());
+
+ std::vector<std::string> files;
+ this->FindGCovFiles(files);
+ std::vector<std::string>::iterator it;
+
+ if ( files.size() == 0 )
+ {
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " Cannot find any GCov coverage files."
+ << std::endl);
+ // No coverage files is a valid thing, so the exit code is 0
+ return 0;
+ }
+
+ std::string testingDir = this->CTest->GetBinaryDir() + "/Testing";
+ std::string tempDir = testingDir + "/CoverageInfo";
+ std::string currentDirectory = cmSystemTools::GetCurrentWorkingDirectory();
+ cmSystemTools::MakeDirectory(tempDir.c_str());
+ cmSystemTools::ChangeDirectory(tempDir.c_str());
+
+ 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, " ");
+ int file_count = 0;
+
+ // make sure output from gcov is in English!
+ cmCTestCoverageHandlerLocale locale_C;
+ static_cast<void>(locale_C);
+
+ // files is a list of *.da and *.gcda files with coverage data in them.
+ // These are binary files that you give as input to gcov so that it will
+ // give us text output we can analyze to summarize coverage.
+ //
+ for ( it = files.begin(); it != files.end(); ++ it )
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, "." << std::flush);
+
+ // Call gcov to get coverage data for this *.gcda file:
+ //
+ std::string fileDir = cmSystemTools::GetFilenamePath(it->c_str());
+ std::string command = "\"" + gcovCommand + "\" " +
+ gcovExtraFlags + " " +
+ "-o \"" + fileDir + "\" " +
+ "\"" + *it + "\"";
+
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, command.c_str()
+ << std::endl);
+
+ 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;
+ 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;
+ if ( ! res )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Problem running coverage on file: " << it->c_str() << 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->c_str() << std::endl);
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Command produced error: " << cont->Error << std::endl);
+ }
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "--------------------------------------------------------------"
+ << std::endl
+ << output << std::endl
+ << "--------------------------------------------------------------"
+ << std::endl);
+
+ std::vector<cmStdString> lines;
+ std::vector<cmStdString>::iterator line;
+
+ cmSystemTools::Split(output.c_str(), lines);
+
+ for ( line = lines.begin(); line != lines.end(); ++line)
+ {
+ std::string sourceFile;
+ std::string gcovFile;
+
+ cmCTestLog(this->CTest, DEBUG, "Line: [" << line->c_str() << "]"
+ << std::endl);
+
+ if ( line->size() == 0 )
+ {
+ // Ignore empty line; probably style 2
+ }
+ else if ( st1re1.find(line->c_str()) )
+ {
+ if ( gcovStyle == 0 )
+ {
+ gcovStyle = 1;
+ }
+ if ( gcovStyle != 1 )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Unknown gcov output style e1"
+ << std::endl);
+ cont->Error ++;
+ break;
+ }
+
+ actualSourceFile = "";
+ sourceFile = st1re1.match(2);
+ }
+ else if ( st1re2.find(line->c_str() ) )
+ {
+ if ( gcovStyle == 0 )
+ {
+ gcovStyle = 1;
+ }
+ if ( gcovStyle != 1 )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Unknown gcov output style e2"
+ << std::endl);
+ cont->Error ++;
+ break;
+ }
+
+ gcovFile = st1re2.match(1);
+ }
+ else if ( st2re1.find(line->c_str() ) )
+ {
+ if ( gcovStyle == 0 )
+ {
+ gcovStyle = 2;
+ }
+ if ( gcovStyle != 2 )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Unknown gcov output style e3"
+ << std::endl);
+ cont->Error ++;
+ break;
+ }
+
+ actualSourceFile = "";
+ sourceFile = st2re1.match(1);
+ }
+ else if ( st2re2.find(line->c_str() ) )
+ {
+ if ( gcovStyle == 0 )
+ {
+ gcovStyle = 2;
+ }
+ if ( gcovStyle != 2 )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Unknown gcov output style e4"
+ << std::endl);
+ cont->Error ++;
+ break;
+ }
+ }
+ else if ( st2re3.find(line->c_str() ) )
+ {
+ if ( gcovStyle == 0 )
+ {
+ gcovStyle = 2;
+ }
+ if ( gcovStyle != 2 )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Unknown gcov output style e5"
+ << std::endl);
+ cont->Error ++;
+ break;
+ }
+
+ gcovFile = st2re3.match(2);
+ }
+ else if ( st2re4.find(line->c_str() ) )
+ {
+ if ( gcovStyle == 0 )
+ {
+ gcovStyle = 2;
+ }
+ if ( gcovStyle != 2 )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Unknown gcov output style e6"
+ << std::endl);
+ cont->Error ++;
+ break;
+ }
+
+ cmCTestLog(this->CTest, WARNING, "Warning: " << st2re4.match(1)
+ << " had unexpected EOF" << std::endl);
+ }
+ else if ( st2re5.find(line->c_str() ) )
+ {
+ if ( gcovStyle == 0 )
+ {
+ gcovStyle = 2;
+ }
+ if ( gcovStyle != 2 )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Unknown gcov output style e7"
+ << std::endl);
+ cont->Error ++;
+ break;
+ }
+
+ cmCTestLog(this->CTest, WARNING, "Warning: Cannot open file: "
+ << st2re5.match(1) << std::endl);
+ }
+ else if ( st2re6.find(line->c_str() ) )
+ {
+ if ( gcovStyle == 0 )
+ {
+ gcovStyle = 2;
+ }
+ if ( gcovStyle != 2 )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Unknown gcov output style e8"
+ << std::endl);
+ cont->Error ++;
+ break;
+ }
+
+ cmCTestLog(this->CTest, WARNING, "Warning: File: " << st2re6.match(1)
+ << " is newer than " << st2re6.match(2) << std::endl);
+ }
+ else
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Unknown gcov output line: [" << line->c_str() << "]" << std::endl);
+ cont->Error ++;
+ //abort();
+ }
+
+
+ // If the last line of gcov output gave us a valid value for gcovFile,
+ // and we have an actualSourceFile, then insert a (or add to existing)
+ // SingleFileCoverageVector for actualSourceFile:
+ //
+ if ( !gcovFile.empty() && !actualSourceFile.empty() )
+ {
+ cmCTestCoverageHandlerContainer::SingleFileCoverageVector& vec
+ = cont->TotalCoverage[actualSourceFile];
+
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " in gcovFile: "
+ << gcovFile << std::endl);
+
+ std::ifstream ifile(gcovFile.c_str());
+ if ( ! ifile )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot open file: "
+ << gcovFile << std::endl);
+ }
+ else
+ {
+ long cnt = -1;
+ std::string nl;
+ while ( cmSystemTools::GetLineFromStream(ifile, nl) )
+ {
+ cnt ++;
+
+ //TODO: Handle gcov 3.0 non-coverage lines
+
+ // Skip empty lines
+ if ( !nl.size() )
+ {
+ continue;
+ }
+
+ // Skip unused lines
+ if ( nl.size() < 12 )
+ {
+ continue;
+ }
+
+ // Read the coverage count from the beginning of the gcov output
+ // line
+ std::string prefix = nl.substr(0, 12);
+ int cov = atoi(prefix.c_str());
+
+ // Read the line number starting at the 10th character of the gcov
+ // output line
+ std::string lineNumber = nl.substr(10, 5);
+
+ 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 = "";
+ }
+
+
+ if ( !sourceFile.empty() && actualSourceFile.empty() )
+ {
+ gcovFile = "";
+
+ // Is it in the source dir or the binary dir?
+ //
+ 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()
+ << std::endl;
+ actualSourceFile
+ = cmSystemTools::CollapseFullPath(sourceFile.c_str());
+ }
+ 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()
+ << std::endl;
+ actualSourceFile
+ = cmSystemTools::CollapseFullPath(sourceFile.c_str());
+ }
+
+ 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,
+ "Cannot find file: ["
+ << sourceFile.c_str() << "]" << std::endl);
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " in source dir: ["
+ << cont->SourceDir.c_str() << "]"
+ << std::endl);
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " or binary dir: ["
+ << cont->BinaryDir.size() << "]"
+ << std::endl);
+ *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;
+
+ missingFiles.insert(sourceFile);
+ }
+ }
+ }
+ }
+
+ file_count++;
+
+ if ( file_count % 50 == 0 )
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " processed: " << file_count
+ << " out of " << files.size() << std::endl);
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " ");
+ }
+ }
+
+ cmSystemTools::ChangeDirectory(currentDirectory.c_str());
+ return file_count;
+}
+
+//----------------------------------------------------------------------------
+void cmCTestCoverageHandler::FindGCovFiles(std::vector<std::string>& files)
+{
+ cmsys::Glob gl;
+ gl.RecurseOn();
+ gl.RecurseThroughSymlinksOff();
+
+ for(LabelMapType::const_iterator lmi = this->TargetDirs.begin();
+ lmi != this->TargetDirs.end(); ++lmi)
+ {
+ // Skip targets containing no interesting labels.
+ if(!this->IntersectsFilter(lmi->second))
+ {
+ continue;
+ }
+
+ // 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);
+ std::string daGlob = lmi->first;
+ daGlob += "/*.da";
+ gl.FindFiles(daGlob);
+ files.insert(files.end(), gl.GetFiles().begin(), gl.GetFiles().end());
+ daGlob = lmi->first;
+ daGlob += "/*.gcda";
+ gl.FindFiles(daGlob);
+ files.insert(files.end(), gl.GetFiles().begin(), gl.GetFiles().end());
+ }
+}
+
+//----------------------------------------------------------------------
+int cmCTestCoverageHandler::HandleTracePyCoverage(
+ cmCTestCoverageHandlerContainer* cont)
+{
+ cmsys::Glob gl;
+ gl.RecurseOn();
+ gl.RecurseThroughSymlinksOff();
+ std::string daGlob = cont->BinaryDir + "/*.cover";
+ gl.FindFiles(daGlob);
+ std::vector<std::string> files = gl.GetFiles();
+
+ if ( files.size() == 0 )
+ {
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " Cannot find any Python Trace.py coverage files."
+ << std::endl);
+ // No coverage files is a valid thing, so the exit code is 0
+ return 0;
+ }
+
+ std::string testingDir = this->CTest->GetBinaryDir() + "/Testing";
+ std::string tempDir = testingDir + "/CoverageInfo";
+ std::string currentDirectory = cmSystemTools::GetCurrentWorkingDirectory();
+ cmSystemTools::MakeDirectory(tempDir.c_str());
+ cmSystemTools::ChangeDirectory(tempDir.c_str());
+
+ cmSystemTools::ChangeDirectory(currentDirectory.c_str());
+
+ std::vector<std::string>::iterator fileIt;
+ int file_count = 0;
+ for ( fileIt = files.begin(); fileIt != files.end(); ++ fileIt )
+ {
+ std::string fileName = this->FindFile(cont, *fileIt);
+ if ( fileName.empty() )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Cannot find source Python file corresponding to: "
+ << fileIt->c_str() << 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);
+ 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());
+ if ( ! ifile )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot open file: "
+ << fileIt->c_str() << std::endl);
+ }
+ else
+ {
+ long cnt = -1;
+ std::string nl;
+ while ( cmSystemTools::GetLineFromStream(ifile, nl) )
+ {
+ cnt ++;
+
+ // Skip empty lines
+ if ( !nl.size() )
+ {
+ continue;
+ }
+
+ // Skip unused lines
+ if ( nl.size() < 12 )
+ {
+ continue;
+ }
+
+ // Read the coverage count from the beginning of the Trace.py output
+ // line
+ std::string prefix = nl.substr(0, 6);
+ if ( prefix[5] != ' ' && prefix[5] != ':' )
+ {
+ // This is a hack. We should really do something more elaborate
+ prefix = nl.substr(0, 7);
+ if ( prefix[6] != ' ' && prefix[6] != ':' )
+ {
+ prefix = nl.substr(0, 8);
+ if ( prefix[7] != ' ' && prefix[7] != ':' )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Currently the limit is maximum coverage of 999999"
+ << std::endl);
+ }
+ }
+ }
+ int cov = atoi(prefix.c_str());
+ if ( prefix[prefix.size()-1] != ':' )
+ {
+ // This line does not have ':' so no coverage here. That said,
+ // Trace.py does not handle not covered lines versus comments etc.
+ // So, this will be set to 0.
+ cov = 0;
+ }
+ cmCTestLog(this->CTest, DEBUG, "Prefix: " << prefix.c_str()
+ << " cov: " << cov
+ << std::endl);
+ // Read the line number starting at the 10th character of the gcov
+ // output line
+ long lineIdx = cnt;
+ 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 )
+ {
+ (*vec)[lineIdx] = 0;
+ }
+ }
+ (*vec)[lineIdx] += cov;
+ }
+ }
+ }
+ ++ file_count;
+ }
+ cmSystemTools::ChangeDirectory(currentDirectory.c_str());
+ return file_count;
+}
+
+//----------------------------------------------------------------------
+std::string cmCTestCoverageHandler::FindFile(
+ cmCTestCoverageHandlerContainer* cont,
+ std::string fileName)
+{
+ std::string fileNameNoE
+ = cmSystemTools::GetFilenameWithoutLastExtension(fileName);
+ // First check in source and binary directory
+ std::string fullName = cont->SourceDir + "/" + fileNameNoE + ".py";
+ if ( cmSystemTools::FileExists(fullName.c_str()) )
+ {
+ return fullName;
+ }
+ fullName = cont->BinaryDir + "/" + fileNameNoE + ".py";
+ if ( cmSystemTools::FileExists(fullName.c_str()) )
+ {
+ return fullName;
+ }
+ return "";
+}
+
+// This is a header put on each marked up source file
+namespace
+{
+ const char* bullseyeHelp[] =
+ {" Coverage produced by bullseye covbr tool: ",
+ " www.bullseye.com/help/ref_covbr.html",
+ " * An arrow --> indicates incomplete coverage.",
+ " * An X indicates a function that was invoked, a switch label that ",
+ " was exercised, a try-block that finished, or an exception handler ",
+ " that was invoked.",
+ " * A T or F indicates a boolean decision that evaluated true or false,",
+ " respectively.",
+ " * A t or f indicates a boolean condition within a decision if the ",
+ " condition evaluated true or false, respectively.",
+ " * A k indicates a constant decision or condition.",
+ " * The slash / means this probe is excluded from summary results. ",
+ 0};
+}
+
+//----------------------------------------------------------------------
+int cmCTestCoverageHandler::RunBullseyeCoverageBranch(
+ cmCTestCoverageHandlerContainer* cont,
+ std::set<cmStdString>& coveredFileNames,
+ std::vector<std::string>& files,
+ std::vector<std::string>& filesFullPath)
+{
+ if(files.size() != filesFullPath.size())
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Files and full path files not the same size?:\n");
+ return 0;
+ }
+ // create the output stream for the CoverageLog-N.xml file
+ cmGeneratedFileStream covLogFile;
+ int logFileCount = 0;
+ if ( !this->StartCoverageLogFile(covLogFile, logFileCount) )
+ {
+ return -1;
+ }
+ // 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);
+
+ 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);
+ // open the output file
+ std::ifstream fin(outputFile.c_str());
+ if(!fin)
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Cannot open coverage file: " <<
+ outputFile.c_str() << std::endl);
+ return 0;
+ }
+ std::map<cmStdString, cmStdString> fileMap;
+ std::vector<std::string>::iterator fp = filesFullPath.begin();
+ for(std::vector<std::string>::iterator f = files.begin();
+ f != files.end(); ++f, ++fp)
+ {
+ fileMap[*f] = *fp;
+ }
+
+ int count =0; // keep count of the number of files
+ // Now parse each line from the bullseye cov log file
+ std::string lineIn;
+ bool valid = false; // are we in a valid output file
+ int line = 0; // line of the current file
+ cmStdString file;
+ while(cmSystemTools::GetLineFromStream(fin, lineIn))
+ {
+ bool startFile = false;
+ if(lineIn.size() > 1 && lineIn[lineIn.size()-1] == ':')
+ {
+ file = lineIn.substr(0, lineIn.size()-1);
+ if(coveredFileNames.find(file) != coveredFileNames.end())
+ {
+ startFile = true;
+ }
+ }
+ if(startFile)
+ {
+ // 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;
+ }
+ // 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);
+ this->EndCoverageLogFile(covLogFile, logFileCount);
+ logFileCount ++;
+ if ( !this->StartCoverageLogFile(covLogFile, logFileCount) )
+ {
+ return -1;
+ }
+ count++; // move on one
+ }
+ std::map<cmStdString, cmStdString>::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);
+ // 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;
+ // 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;
+ line++;
+ }
+ valid = true; // we are in a valid file section
+ }
+ else
+ {
+ // this is not a file that we want coverage for
+ valid = false;
+ }
+ }
+ // 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;
+ 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;
+ }
+ this->EndCoverageLogFile(covLogFile, logFileCount);
+ return 1;
+}
+
+//----------------------------------------------------------------------
+int cmCTestCoverageHandler::RunBullseyeCommand(
+ cmCTestCoverageHandlerContainer* cont,
+ const char* cmd,
+ const char* arg,
+ std::string& outputFile)
+{
+ std::string program = cmSystemTools::FindProgram(cmd);
+ if(program.size() == 0)
+ {
+ 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");
+ }
+ else
+ {
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Run : " << program.c_str() << "\n");
+ }
+ // create a process object and start it
+ cmCTestRunProcess runCoverageSrc;
+ runCoverageSrc.SetCommand(program.c_str());
+ runCoverageSrc.AddArgument(arg);
+ std::string stdoutFile = cont->BinaryDir + "/Testing/Temporary/";
+ stdoutFile += this->GetCTestInstance()->GetCurrentTag();
+ stdoutFile += "-";
+ stdoutFile += cmd;
+ std::string stderrFile = stdoutFile;
+ stdoutFile += ".stdout";
+ stderrFile += ".stderr";
+ runCoverageSrc.SetStdoutFile(stdoutFile.c_str());
+ runCoverageSrc.SetStderrFile(stderrFile.c_str());
+ if(!runCoverageSrc.StartProcess())
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Could not run : "
+ << program.c_str() << " " << arg << "\n"
+ << "kwsys process state : "
+ << runCoverageSrc.GetProcessState());
+ return 0;
+ }
+ // since we set the output file names wait for it to end
+ runCoverageSrc.WaitForExit();
+ outputFile = stdoutFile;
+ return 1;
+}
+
+//----------------------------------------------------------------------
+int cmCTestCoverageHandler::RunBullseyeSourceSummary(
+ cmCTestCoverageHandlerContainer* cont)
+{
+ // Run the covsrc command and create a temp outputfile
+ std::string outputFile;
+ if(!this->RunBullseyeCommand(cont, "covsrc", "-c", outputFile))
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "error running covsrc:\n");
+ return 0;
+ }
+
+ std::ostream& tmpLog = *cont->OFS;
+ // copen the Coverage.xml file in the Testing directory
+ cmGeneratedFileStream 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);
+ 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;
+ std::string stdline;
+ std::string errline;
+ // expected output:
+ // first line is:
+ // "Source","Function Coverage","out of","%","C/D Coverage","out of","%"
+ // after that data follows in that format
+ std::string sourceFile;
+ int functionsCalled = 0;
+ int totalFunctions = 0;
+ int percentFunction = 0;
+ int branchCovered = 0;
+ int totalBranches = 0;
+ int percentBranch = 0;
+ double total_tested = 0;
+ double total_untested = 0;
+ double total_functions = 0;
+ double percent_coverage =0;
+ double number_files = 0;
+ std::vector<std::string> coveredFiles;
+ std::vector<std::string> coveredFilesFullPath;
+ // Read and parse the summary output file
+ std::ifstream fin(outputFile.c_str());
+ if(!fin)
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Cannot open coverage summary file: " <<
+ outputFile.c_str() << std::endl);
+ return 0;
+ }
+ std::set<cmStdString> coveredFileNames;
+ while(cmSystemTools::GetLineFromStream(fin, stdline))
+ {
+ // if we have a line of output from stdout
+ if(stdline.size())
+ {
+ // parse the comma separated output
+ this->ParseBullsEyeCovsrcLine(stdline,
+ sourceFile,
+ functionsCalled,
+ totalFunctions,
+ percentFunction,
+ branchCovered,
+ totalBranches,
+ percentBranch);
+ // The first line is the header
+ if(sourceFile == "Source" || sourceFile == "Total")
+ {
+ continue;
+ }
+ std::string file = sourceFile;
+ coveredFileNames.insert(file);
+ if(!cmSystemTools::FileIsFullPath(sourceFile.c_str()))
+ {
+ // file will be relative to the binary dir
+ file = cont->BinaryDir;
+ file += "/";
+ file += sourceFile;
+ }
+ file = cmSystemTools::CollapseFullPath(file.c_str());
+ 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);
+ continue;
+ }
+
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Doing coverage for: "
+ << file.c_str()
+ << std::endl);
+
+ coveredFiles.push_back(sourceFile);
+ coveredFilesFullPath.push_back(file);
+
+ number_files++;
+ total_functions += totalFunctions;
+ total_tested += functionsCalled;
+ total_untested += (totalFunctions - functionsCalled);
+
+ std::string fileName = cmSystemTools::GetFilenameName(file.c_str());
+ std::string shortFileName =
+ this->CTest->GetShortPathToFile(file.c_str());
+
+ float cper = static_cast<float>(percentBranch + percentFunction);
+ if(totalBranches > 0)
+ {
+ cper /= 2.0f;
+ }
+ percent_coverage += cper;
+ float cmet = static_cast<float>(percentFunction + percentBranch);
+ if(totalBranches > 0)
+ {
+ cmet /= 2.0f;
+ }
+ cmet /= 100.0f;
+ tmpLog << stdline.c_str() << "\n";
+ tmpLog << fileName << "\n";
+ tmpLog << "functionsCalled: " << functionsCalled/100 << "\n";
+ tmpLog << "totalFunctions: " << totalFunctions/100 << "\n";
+ tmpLog << "percentFunction: " << percentFunction << "\n";
+ tmpLog << "branchCovered: " << branchCovered << "\n";
+ tmpLog << "totalBranches: " << totalBranches << "\n";
+ 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;
+ }
+ }
+ 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);
+
+ // Now create the coverage information for each file
+ return this->RunBullseyeCoverageBranch(cont,
+ coveredFileNames,
+ coveredFiles,
+ coveredFilesFullPath);
+}
+
+//----------------------------------------------------------------------
+int cmCTestCoverageHandler::HandleBullseyeCoverage(
+ cmCTestCoverageHandlerContainer* cont)
+{
+ 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");
+ return 0;
+ }
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " run covsrc with COVFILE=["
+ << covfile
+ << "]" << std::endl);
+ 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);
+ return 1;
+}
+
+bool cmCTestCoverageHandler::GetNextInt(std::string const& inputLine,
+ std::string::size_type& pos,
+ int& value)
+{
+ std::string::size_type start = pos;
+ pos = inputLine.find(',', start);
+ value = atoi(inputLine.substr(start, pos).c_str());
+ if(pos == inputLine.npos)
+ {
+ return true;
+ }
+ pos++;
+ return true;
+}
+
+bool cmCTestCoverageHandler::ParseBullsEyeCovsrcLine(
+ std::string const& inputLine,
+ std::string& sourceFile,
+ int& functionsCalled,
+ int& totalFunctions,
+ int& percentFunction,
+ int& branchCovered,
+ int& totalBranches,
+ int& percentBranch)
+{
+ // find the first comma
+ std::string::size_type pos = inputLine.find(',');
+ if(pos == inputLine.npos)
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Error parsing string : "
+ << inputLine.c_str() << "\n");
+ return false;
+ }
+ // the source file has "" around it so extract out the file name
+ sourceFile = inputLine.substr(1,pos-2);
+ pos++;
+ if(!this->GetNextInt(inputLine, pos, functionsCalled))
+ {
+ return false;
+ }
+ if(!this->GetNextInt(inputLine, pos, totalFunctions))
+ {
+ return false;
+ }
+ if(!this->GetNextInt(inputLine, pos, percentFunction))
+ {
+ return false;
+ }
+ if(!this->GetNextInt(inputLine, pos, branchCovered))
+ {
+ return false;
+ }
+ if(!this->GetNextInt(inputLine, pos, totalBranches))
+ {
+ return false;
+ }
+ if(!this->GetNextInt(inputLine, pos, percentBranch))
+ {
+ return false;
+ }
+ // should be at the end now
+ if(pos != inputLine.npos)
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Error parsing input : "
+ << inputLine.c_str() << " last pos not npos = " << pos <<
+ "\n");
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------
+int cmCTestCoverageHandler::GetLabelId(std::string const& label)
+{
+ LabelIdMapType::iterator i = this->LabelIdMap.find(label);
+ if(i == this->LabelIdMap.end())
+ {
+ int n = int(this->Labels.size());
+ this->Labels.push_back(label);
+ LabelIdMapType::value_type entry(label, n);
+ i = this->LabelIdMap.insert(entry).first;
+ }
+ return i->second;
+}
+
+//----------------------------------------------------------------------
+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());
+ std::string line;
+ while(cmSystemTools::GetLineFromStream(finList, line))
+ {
+ this->LoadLabels(line.c_str());
+ }
+}
+
+//----------------------------------------------------------------------
+void cmCTestCoverageHandler::LoadLabels(const char* dir)
+{
+ LabelSet& dirLabels = this->TargetDirs[dir];
+ std::string fname = dir;
+ fname += "/Labels.txt";
+ std::ifstream fin(fname.c_str());
+ if(!fin)
+ {
+ return;
+ }
+
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " loading labels from [" << fname << "]\n");
+ bool inTarget = true;
+ std::string source;
+ std::string line;
+ std::vector<int> targetLabels;
+ while(cmSystemTools::GetLineFromStream(fin, line))
+ {
+ if(line.empty() || line[0] == '#')
+ {
+ // Ignore blank and comment lines.
+ continue;
+ }
+ else if(line[0] == ' ')
+ {
+ // Label lines appear indented by one space.
+ std::string label = line.substr(1);
+ int id = this->GetLabelId(label);
+ dirLabels.insert(id);
+ if(inTarget)
+ {
+ targetLabels.push_back(id);
+ }
+ else
+ {
+ this->SourceLabels[source].insert(id);
+ }
+ }
+ else
+ {
+ // Non-indented lines specify a source file name. The first one
+ // is the end of the target-wide labels.
+ inTarget = false;
+
+ source = this->CTest->GetShortPathToFile(line.c_str());
+
+ // 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);
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------
+void cmCTestCoverageHandler::WriteXMLLabels(std::ofstream& os,
+ 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";
+ for(LabelSet::const_iterator lsi = li->second.begin();
+ lsi != li->second.end(); ++lsi)
+ {
+ os << "\t\t\t<Label>" << cmXMLSafe(this->Labels[*lsi]) << "</Label>\n";
+ }
+ os << "\t\t</Labels>\n";
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmCTestCoverageHandler::SetLabelFilter(std::set<cmStdString> const& labels)
+{
+ this->LabelFilter.clear();
+ for(std::set<cmStdString>::const_iterator li = labels.begin();
+ li != labels.end(); ++li)
+ {
+ this->LabelFilter.insert(this->GetLabelId(*li));
+ }
+}
+
+//----------------------------------------------------------------------
+bool cmCTestCoverageHandler::IntersectsFilter(LabelSet const& labels)
+{
+ // If there is no label filter then nothing is filtered out.
+ if(this->LabelFilter.empty())
+ {
+ return true;
+ }
+
+ std::vector<int> ids;
+ cmsys_stl::set_intersection
+ (labels.begin(), labels.end(),
+ this->LabelFilter.begin(), this->LabelFilter.end(),
+ cmsys_stl::back_inserter(ids));
+ return !ids.empty();
+}
+
+//----------------------------------------------------------------------
+bool cmCTestCoverageHandler::IsFilteredOut(std::string const& source)
+{
+ // If there is no label filter then nothing is filtered out.
+ if(this->LabelFilter.empty())
+ {
+ return false;
+ }
+
+ // The source is filtered out if it does not have any labels in
+ // common with the filter set.
+ std::string shortSrc = this->CTest->GetShortPathToFile(source.c_str());
+ LabelMapType::const_iterator li = this->SourceLabels.find(shortSrc);
+ if(li != this->SourceLabels.end())
+ {
+ return !this->IntersectsFilter(li->second);
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------
+std::set<std::string> cmCTestCoverageHandler::FindUncoveredFiles(
+ cmCTestCoverageHandlerContainer* cont)
+{
+ std::set<std::string> extraMatches;
+
+ for(std::vector<cmStdString>::iterator i = this->ExtraCoverageGlobs.begin();
+ i != this->ExtraCoverageGlobs.end(); ++i)
+ {
+ cmsys::Glob gl;
+ gl.RecurseOn();
+ gl.RecurseThroughSymlinksOff();
+ std::string glob = cont->SourceDir + "/" + *i;
+ gl.FindFiles(glob);
+ std::vector<std::string> files = gl.GetFiles();
+ for(std::vector<std::string>::iterator f = files.begin();
+ f != files.end(); ++f)
+ {
+ if(this->ShouldIDoCoverage(f->c_str(),
+ cont->SourceDir.c_str(), cont->BinaryDir.c_str()))
+ {
+ extraMatches.insert(this->CTest->GetShortPathToFile(
+ f->c_str()));
+ }
+ }
+ }
+
+ if(extraMatches.size())
+ {
+ for(cmCTestCoverageHandlerContainer::TotalCoverageMap::iterator i =
+ cont->TotalCoverage.begin(); i != cont->TotalCoverage.end(); ++i)
+ {
+ std::string shortPath = this->CTest->GetShortPathToFile(
+ i->first.c_str());
+ extraMatches.erase(shortPath);
+ }
+ }
+ return extraMatches;
+}
diff --git a/Source/CTest/cmCTestCoverageHandler.h b/Source/CTest/cmCTestCoverageHandler.h
new file mode 100644
index 000000000..92b0b2285
--- /dev/null
+++ b/Source/CTest/cmCTestCoverageHandler.h
@@ -0,0 +1,139 @@
+/*============================================================================
+ 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 cmCTestCoverageHandler_h
+#define cmCTestCoverageHandler_h
+
+
+#include "cmCTestGenericHandler.h"
+#include "cmListFileCache.h"
+
+#include <cmsys/RegularExpression.hxx>
+
+class cmGeneratedFileStream;
+class cmCTestCoverageHandlerContainer
+{
+public:
+ int Error;
+ std::string SourceDir;
+ std::string BinaryDir;
+ typedef std::vector<int> SingleFileCoverageVector;
+ typedef std::map<std::string, SingleFileCoverageVector> TotalCoverageMap;
+ TotalCoverageMap TotalCoverage;
+ std::ostream* OFS;
+};
+/** \class cmCTestCoverageHandler
+ * \brief A class that handles coverage computaiton for ctest
+ *
+ */
+class cmCTestCoverageHandler : public cmCTestGenericHandler
+{
+public:
+ cmTypeMacro(cmCTestCoverageHandler, cmCTestGenericHandler);
+
+ /*
+ * The main entry point for this class
+ */
+ int ProcessHandler();
+
+ cmCTestCoverageHandler();
+
+ virtual void Initialize();
+
+ /**
+ * This method is called when reading CTest custom file
+ */
+ void PopulateCustomVectors(cmMakefile *mf);
+
+ /** Report coverage only for sources with these labels. */
+ void SetLabelFilter(std::set<cmStdString> const& labels);
+
+private:
+ bool ShouldIDoCoverage(const char* file, const char* srcDir,
+ const char* binDir);
+ void CleanCoverageLogFiles(std::ostream& log);
+ bool StartCoverageLogFile(cmGeneratedFileStream& ostr, int logFileCount);
+ void EndCoverageLogFile(cmGeneratedFileStream& ostr, int logFileCount);
+
+ //! Handle coverage using GCC's GCov
+ int HandleGCovCoverage(cmCTestCoverageHandlerContainer* cont);
+ void FindGCovFiles(std::vector<std::string>& files);
+
+ //! Handle coverage using xdebug php coverage
+ int HandlePHPCoverage(cmCTestCoverageHandlerContainer* cont);
+ //! Handle coverage for mumps
+ int HandleMumpsCoverage(cmCTestCoverageHandlerContainer* cont);
+
+ //! Handle coverage using Bullseye
+ int HandleBullseyeCoverage(cmCTestCoverageHandlerContainer* cont);
+ int RunBullseyeSourceSummary(cmCTestCoverageHandlerContainer* cont);
+ int RunBullseyeCoverageBranch(cmCTestCoverageHandlerContainer* cont,
+ std::set<cmStdString>& coveredFileNames,
+ std::vector<std::string>& files,
+ std::vector<std::string>& filesFullPath);
+
+ int RunBullseyeCommand(
+ cmCTestCoverageHandlerContainer* cont,
+ const char* cmd,
+ const char* arg,
+ std::string& outputFile);
+ bool ParseBullsEyeCovsrcLine(
+ std::string const& inputLine,
+ std::string& sourceFile,
+ int& functionsCalled,
+ int& totalFunctions,
+ int& percentFunction,
+ int& branchCovered,
+ int& totalBranches,
+ int& percentBranch);
+ bool GetNextInt(std::string const& inputLine,
+ std::string::size_type& pos,
+ int& value);
+ //! Handle Python coverage using Python's Trace.py
+ int HandleTracePyCoverage(cmCTestCoverageHandlerContainer* cont);
+
+ // Find the source file based on the source and build tree. This is used for
+ // Trace.py mode, since that one does not tell us where the source file is.
+ std::string FindFile(cmCTestCoverageHandlerContainer* cont,
+ std::string fileName);
+
+ std::set<std::string> FindUncoveredFiles(
+ cmCTestCoverageHandlerContainer* cont);
+ std::vector<cmStdString> CustomCoverageExclude;
+ std::vector<cmsys::RegularExpression> CustomCoverageExcludeRegex;
+ std::vector<cmStdString> ExtraCoverageGlobs;
+
+
+ // Map from source file to label ids.
+ class LabelSet: public std::set<int> {};
+ typedef std::map<cmStdString, LabelSet> LabelMapType;
+ LabelMapType SourceLabels;
+ LabelMapType TargetDirs;
+
+ // Map from label name to label id.
+ typedef std::map<cmStdString, int> LabelIdMapType;
+ LabelIdMapType LabelIdMap;
+ std::vector<std::string> Labels;
+ int GetLabelId(std::string const& label);
+
+ // Label reading and writing methods.
+ void LoadLabels();
+ void LoadLabels(const char* dir);
+ void WriteXMLLabels(std::ofstream& os, std::string const& source);
+
+ // Label-based filtering.
+ std::set<int> LabelFilter;
+ bool IntersectsFilter(LabelSet const& labels);
+ bool IsFilteredOut(std::string const& source);
+};
+
+#endif
diff --git a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.cxx b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.cxx
new file mode 100644
index 000000000..56312c0fb
--- /dev/null
+++ b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.cxx
@@ -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.
+============================================================================*/
+#include "cmCTestEmptyBinaryDirectoryCommand.h"
+
+#include "cmCTestScriptHandler.h"
+
+bool cmCTestEmptyBinaryDirectoryCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() != 1 )
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ 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());
+ return false;
+ }
+
+ return true;
+}
+
+
diff --git a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h
new file mode 100644
index 000000000..a763fe9e9
--- /dev/null
+++ b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h
@@ -0,0 +1,78 @@
+/*============================================================================
+ 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 cmCTestEmptyBinaryDirectoryCommand_h
+#define cmCTestEmptyBinaryDirectoryCommand_h
+
+#include "cmCTestCommand.h"
+
+/** \class cmCTestEmptyBinaryDirectory
+ * \brief Run a ctest script
+ *
+ * cmLibrarysCommand defines a list of executable (i.e., test)
+ * programs to create.
+ */
+class cmCTestEmptyBinaryDirectoryCommand : public cmCTestCommand
+{
+public:
+
+ cmCTestEmptyBinaryDirectoryCommand() {}
+
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ cmCTestEmptyBinaryDirectoryCommand* ni
+ = new cmCTestEmptyBinaryDirectoryCommand;
+ ni->CTest = this->CTest;
+ ni->CTestScriptHandler = this->CTestScriptHandler;
+ return ni;
+ }
+
+ /**
+ * 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 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.";
+ }
+
+ cmTypeMacro(cmCTestEmptyBinaryDirectoryCommand, cmCTestCommand);
+
+};
+
+
+#endif
diff --git a/Source/CTest/cmCTestGIT.cxx b/Source/CTest/cmCTestGIT.cxx
new file mode 100644
index 000000000..2c1a0afd9
--- /dev/null
+++ b/Source/CTest/cmCTestGIT.cxx
@@ -0,0 +1,652 @@
+/*============================================================================
+ 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 "cmCTestGIT.h"
+
+#include "cmCTest.h"
+#include "cmSystemTools.h"
+#include "cmXMLSafe.h"
+
+#include <cmsys/RegularExpression.hxx>
+#include <cmsys/ios/sstream>
+#include <cmsys/Process.h>
+
+#include <sys/types.h>
+#include <time.h>
+#include <ctype.h>
+
+//----------------------------------------------------------------------------
+static unsigned int cmCTestGITVersion(unsigned int epic, unsigned int major,
+ unsigned int minor, unsigned int fix)
+{
+ // 1.6.5.0 maps to 10605000
+ return fix + minor*1000 + major*100000 + epic*10000000;
+}
+
+//----------------------------------------------------------------------------
+cmCTestGIT::cmCTestGIT(cmCTest* ct, std::ostream& log):
+ cmCTestGlobalVC(ct, log)
+{
+ this->PriorRev = this->Unknown;
+ this->CurrentGitVersion = 0;
+}
+
+//----------------------------------------------------------------------------
+cmCTestGIT::~cmCTestGIT()
+{
+}
+
+//----------------------------------------------------------------------------
+class cmCTestGIT::OneLineParser: public cmCTestVC::LineParser
+{
+public:
+ OneLineParser(cmCTestGIT* git, const char* prefix,
+ std::string& l): Line1(l)
+ {
+ this->SetLog(&git->Log, prefix);
+ }
+private:
+ std::string& Line1;
+ virtual bool ProcessLine()
+ {
+ // Only the first line is of interest.
+ this->Line1 = this->Line;
+ return false;
+ }
+};
+
+//----------------------------------------------------------------------------
+std::string cmCTestGIT::GetWorkingRevision()
+{
+ // Run plumbing "git rev-list" to get work tree revision.
+ const char* git = this->CommandLineTool.c_str();
+ const char* git_rev_list[] = {git, "rev-list", "-n", "1", "HEAD", 0};
+ std::string rev;
+ OneLineParser out(this, "rl-out> ", rev);
+ OutputLogger err(this->Log, "rl-err> ");
+ this->RunChild(git_rev_list, &out, &err);
+ return rev;
+}
+
+//----------------------------------------------------------------------------
+void cmCTestGIT::NoteOldRevision()
+{
+ this->OldRevision = this->GetWorkingRevision();
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " Old revision of repository is: "
+ << this->OldRevision << "\n");
+ this->PriorRev.Rev = this->OldRevision;
+}
+
+//----------------------------------------------------------------------------
+void cmCTestGIT::NoteNewRevision()
+{
+ this->NewRevision = this->GetWorkingRevision();
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " New revision of repository is: "
+ << this->NewRevision << "\n");
+}
+
+//----------------------------------------------------------------------------
+std::string cmCTestGIT::FindGitDir()
+{
+ std::string git_dir;
+
+ // Run "git rev-parse --git-dir" to locate the real .git directory.
+ const char* git = this->CommandLineTool.c_str();
+ char const* git_rev_parse[] = {git, "rev-parse", "--git-dir", 0};
+ std::string git_dir_line;
+ OneLineParser rev_parse_out(this, "rev-parse-out> ", git_dir_line);
+ OutputLogger rev_parse_err(this->Log, "rev-parse-err> ");
+ if(this->RunChild(git_rev_parse, &rev_parse_out, &rev_parse_err))
+ {
+ git_dir = git_dir_line;
+ }
+ if(git_dir.empty())
+ {
+ git_dir = ".git";
+ }
+
+ // Git reports a relative path only when the .git directory is in
+ // the current directory.
+ if(git_dir[0] == '.')
+ {
+ git_dir = this->SourceDirectory + "/" + git_dir;
+ }
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ else if(git_dir[0] == '/')
+ {
+ // Cygwin Git reports a full path that Cygwin understands, but we
+ // are a Windows application. Run "cygpath" to get Windows path.
+ std::string cygpath_exe = cmSystemTools::GetFilenamePath(git);
+ cygpath_exe += "/cygpath.exe";
+ if(cmSystemTools::FileExists(cygpath_exe.c_str()))
+ {
+ char const* cygpath[] = {cygpath_exe.c_str(), "-w", git_dir.c_str(), 0};
+ OneLineParser cygpath_out(this, "cygpath-out> ", git_dir_line);
+ OutputLogger cygpath_err(this->Log, "cygpath-err> ");
+ if(this->RunChild(cygpath, &cygpath_out, &cygpath_err))
+ {
+ git_dir = git_dir_line;
+ }
+ }
+ }
+#endif
+ return git_dir;
+}
+
+//----------------------------------------------------------------------------
+std::string cmCTestGIT::FindTopDir()
+{
+ std::string top_dir = this->SourceDirectory;
+
+ // Run "git rev-parse --show-cdup" to locate the top of the tree.
+ const char* git = this->CommandLineTool.c_str();
+ char const* git_rev_parse[] = {git, "rev-parse", "--show-cdup", 0};
+ std::string cdup;
+ OneLineParser rev_parse_out(this, "rev-parse-out> ", cdup);
+ OutputLogger rev_parse_err(this->Log, "rev-parse-err> ");
+ if(this->RunChild(git_rev_parse, &rev_parse_out, &rev_parse_err) &&
+ !cdup.empty())
+ {
+ top_dir += "/";
+ top_dir += cdup;
+ top_dir = cmSystemTools::CollapseFullPath(top_dir.c_str());
+ }
+ return top_dir;
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestGIT::UpdateByFetchAndReset()
+{
+ const char* git = this->CommandLineTool.c_str();
+
+ // Use "git fetch" to get remote commits.
+ std::vector<char const*> git_fetch;
+ git_fetch.push_back(git);
+ git_fetch.push_back("fetch");
+
+ // Add user-specified update options.
+ std::string opts = this->CTest->GetCTestConfiguration("UpdateOptions");
+ if(opts.empty())
+ {
+ opts = this->CTest->GetCTestConfiguration("GITUpdateOptions");
+ }
+ std::vector<cmStdString> args = cmSystemTools::ParseArguments(opts.c_str());
+ for(std::vector<cmStdString>::const_iterator ai = args.begin();
+ ai != args.end(); ++ai)
+ {
+ git_fetch.push_back(ai->c_str());
+ }
+
+ // Sentinel argument.
+ git_fetch.push_back(0);
+
+ // Fetch upstream refs.
+ OutputLogger fetch_out(this->Log, "fetch-out> ");
+ OutputLogger fetch_err(this->Log, "fetch-err> ");
+ if(!this->RunUpdateCommand(&git_fetch[0], &fetch_out, &fetch_err))
+ {
+ return false;
+ }
+
+ // Identify the merge head that would be used by "git pull".
+ std::string sha1;
+ {
+ std::string fetch_head = this->FindGitDir() + "/FETCH_HEAD";
+ std::ifstream fin(fetch_head.c_str(), std::ios::in | std::ios::binary);
+ if(!fin)
+ {
+ this->Log << "Unable to open " << fetch_head << "\n";
+ return false;
+ }
+ std::string line;
+ while(sha1.empty() && cmSystemTools::GetLineFromStream(fin, line))
+ {
+ this->Log << "FETCH_HEAD> " << line << "\n";
+ if(line.find("\tnot-for-merge\t") == line.npos)
+ {
+ std::string::size_type pos = line.find('\t');
+ if(pos != line.npos)
+ {
+ sha1 = line.substr(0, pos);
+ }
+ }
+ }
+ if(sha1.empty())
+ {
+ this->Log << "FETCH_HEAD has no upstream branch candidate!\n";
+ return false;
+ }
+ }
+
+ // Reset the local branch to point at that tracked from upstream.
+ char const* git_reset[] = {git, "reset", "--hard", sha1.c_str(), 0};
+ OutputLogger reset_out(this->Log, "reset-out> ");
+ OutputLogger reset_err(this->Log, "reset-err> ");
+ return this->RunChild(&git_reset[0], &reset_out, &reset_err);
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestGIT::UpdateByCustom(std::string const& custom)
+{
+ std::vector<std::string> git_custom_command;
+ cmSystemTools::ExpandListArgument(custom, git_custom_command, true);
+ std::vector<char const*> git_custom;
+ for(std::vector<std::string>::const_iterator
+ i = git_custom_command.begin(); i != git_custom_command.end(); ++i)
+ {
+ git_custom.push_back(i->c_str());
+ }
+ git_custom.push_back(0);
+
+ OutputLogger custom_out(this->Log, "custom-out> ");
+ OutputLogger custom_err(this->Log, "custom-err> ");
+ return this->RunUpdateCommand(&git_custom[0], &custom_out, &custom_err);
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestGIT::UpdateInternal()
+{
+ std::string custom = this->CTest->GetCTestConfiguration("GITUpdateCustom");
+ if(!custom.empty())
+ {
+ return this->UpdateByCustom(custom);
+ }
+ return this->UpdateByFetchAndReset();
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestGIT::UpdateImpl()
+{
+ if(!this->UpdateInternal())
+ {
+ return false;
+ }
+
+ std::string top_dir = this->FindTopDir();
+ const char* git = this->CommandLineTool.c_str();
+ const char* recursive = "--recursive";
+
+ // Git < 1.6.5.0 did not support --recursive
+ if(this->GetGitVersion() < cmCTestGITVersion(1,6,5,0))
+ {
+ recursive = 0;
+ // No need to require >= 1.6.5.0 if there are no submodules.
+ if(cmSystemTools::FileExists((top_dir + "/.gitmodules").c_str()))
+ {
+ this->Log << "Git < 1.6.5.0 cannot update submodules recursively\n";
+ }
+ }
+
+ char const* git_submodule[] = {git, "submodule", "update", recursive, 0};
+ OutputLogger submodule_out(this->Log, "submodule-out> ");
+ OutputLogger submodule_err(this->Log, "submodule-err> ");
+ return this->RunChild(git_submodule, &submodule_out, &submodule_err,
+ top_dir.c_str());
+}
+
+//----------------------------------------------------------------------------
+unsigned int cmCTestGIT::GetGitVersion()
+{
+ if(!this->CurrentGitVersion)
+ {
+ const char* git = this->CommandLineTool.c_str();
+ char const* git_version[] = {git, "--version", 0};
+ std::string version;
+ OneLineParser version_out(this, "version-out> ", version);
+ OutputLogger version_err(this->Log, "version-err> ");
+ unsigned int v[4] = {0,0,0,0};
+ if(this->RunChild(git_version, &version_out, &version_err) &&
+ sscanf(version.c_str(), "git version %u.%u.%u.%u",
+ &v[0], &v[1], &v[2], &v[3]) >= 3)
+ {
+ this->CurrentGitVersion = cmCTestGITVersion(v[0], v[1], v[2], v[3]);
+ }
+ }
+ return this->CurrentGitVersion;
+}
+
+//----------------------------------------------------------------------------
+/* Diff format:
+
+ :src-mode dst-mode src-sha1 dst-sha1 status\0
+ src-path\0
+ [dst-path\0]
+
+ The format is repeated for every file changed. The [dst-path\0]
+ line appears only for lines with status 'C' or 'R'. See 'git help
+ diff-tree' for details.
+*/
+class cmCTestGIT::DiffParser: public cmCTestVC::LineParser
+{
+public:
+ DiffParser(cmCTestGIT* git, const char* prefix):
+ LineParser('\0', false), GIT(git), DiffField(DiffFieldNone)
+ {
+ this->SetLog(&git->Log, prefix);
+ }
+
+ typedef cmCTestGIT::Change Change;
+ std::vector<Change> Changes;
+protected:
+ cmCTestGIT* GIT;
+ enum DiffFieldType { DiffFieldNone, DiffFieldChange,
+ DiffFieldSrc, DiffFieldDst };
+ DiffFieldType DiffField;
+ Change CurChange;
+
+ void DiffReset()
+ {
+ this->DiffField = DiffFieldNone;
+ this->Changes.clear();
+ }
+
+ virtual bool ProcessLine()
+ {
+ if(this->Line[0] == ':')
+ {
+ this->DiffField = DiffFieldChange;
+ this->CurChange = Change();
+ }
+ if(this->DiffField == DiffFieldChange)
+ {
+ // :src-mode dst-mode src-sha1 dst-sha1 status
+ if(this->Line[0] != ':')
+ {
+ this->DiffField = DiffFieldNone;
+ return true;
+ }
+ const char* src_mode_first = this->Line.c_str()+1;
+ const char* src_mode_last = this->ConsumeField(src_mode_first);
+ const char* dst_mode_first = this->ConsumeSpace(src_mode_last);
+ const char* dst_mode_last = this->ConsumeField(dst_mode_first);
+ const char* src_sha1_first = this->ConsumeSpace(dst_mode_last);
+ const char* src_sha1_last = this->ConsumeField(src_sha1_first);
+ const char* dst_sha1_first = this->ConsumeSpace(src_sha1_last);
+ const char* dst_sha1_last = this->ConsumeField(dst_sha1_first);
+ const char* status_first = this->ConsumeSpace(dst_sha1_last);
+ const char* status_last = this->ConsumeField(status_first);
+ if(status_first != status_last)
+ {
+ this->CurChange.Action = *status_first;
+ this->DiffField = DiffFieldSrc;
+ }
+ else
+ {
+ this->DiffField = DiffFieldNone;
+ }
+ }
+ else if(this->DiffField == DiffFieldSrc)
+ {
+ // src-path
+ if(this->CurChange.Action == 'C')
+ {
+ // Convert copy to addition of destination.
+ this->CurChange.Action = 'A';
+ this->DiffField = DiffFieldDst;
+ }
+ else if(this->CurChange.Action == 'R')
+ {
+ // Convert rename to deletion of source and addition of destination.
+ this->CurChange.Action = 'D';
+ this->CurChange.Path = this->Line;
+ this->Changes.push_back(this->CurChange);
+
+ this->CurChange = Change('A');
+ this->DiffField = DiffFieldDst;
+ }
+ else
+ {
+ this->CurChange.Path = this->Line;
+ this->Changes.push_back(this->CurChange);
+ this->DiffField = this->DiffFieldNone;
+ }
+ }
+ else if(this->DiffField == DiffFieldDst)
+ {
+ // dst-path
+ this->CurChange.Path = this->Line;
+ this->Changes.push_back(this->CurChange);
+ this->DiffField = this->DiffFieldNone;
+ }
+ return true;
+ }
+
+ const char* ConsumeSpace(const char* c)
+ {
+ while(*c && isspace(*c)) { ++c; }
+ return c;
+ }
+ const char* ConsumeField(const char* c)
+ {
+ while(*c && !isspace(*c)) { ++c; }
+ return c;
+ }
+};
+
+//----------------------------------------------------------------------------
+/* Commit format:
+
+ commit ...\n
+ tree ...\n
+ parent ...\n
+ author ...\n
+ committer ...\n
+ \n
+ Log message indented by (4) spaces\n
+ (even blank lines have the spaces)\n
+ [[
+ \n
+ [Diff format]
+ OR
+ \0
+ ]]
+
+ The header may have more fields. See 'git help diff-tree'.
+*/
+class cmCTestGIT::CommitParser: public cmCTestGIT::DiffParser
+{
+public:
+ CommitParser(cmCTestGIT* git, const char* prefix):
+ DiffParser(git, prefix), Section(SectionHeader)
+ {
+ this->Separator = SectionSep[this->Section];
+ }
+
+private:
+ typedef cmCTestGIT::Revision Revision;
+ enum SectionType { SectionHeader, SectionBody, SectionDiff, SectionCount };
+ static char const SectionSep[SectionCount];
+ SectionType Section;
+ Revision Rev;
+
+ struct Person
+ {
+ std::string Name;
+ std::string EMail;
+ unsigned long Time;
+ long TimeZone;
+ Person(): Name(), EMail(), Time(0), TimeZone(0) {}
+ };
+
+ void ParsePerson(const char* str, Person& person)
+ {
+ // Person Name <person@domain.com> 1234567890 +0000
+ const char* c = str;
+ while(*c && isspace(*c)) { ++c; }
+
+ const char* name_first = c;
+ while(*c && *c != '<') { ++c; }
+ const char* name_last = c;
+ while(name_last != name_first && isspace(*(name_last-1))) { --name_last; }
+ person.Name.assign(name_first, name_last-name_first);
+
+ const char* email_first = *c? ++c : c;
+ while(*c && *c != '>') { ++c; }
+ const char* email_last = *c? c++ : c;
+ person.EMail.assign(email_first, email_last-email_first);
+
+ person.Time = strtoul(c, (char**)&c, 10);
+ person.TimeZone = strtol(c, (char**)&c, 10);
+ }
+
+ virtual bool ProcessLine()
+ {
+ if(this->Line.empty())
+ {
+ if(this->Section == SectionBody && this->LineEnd == '\0')
+ {
+ // Skip SectionDiff
+ this->NextSection();
+ }
+ this->NextSection();
+ }
+ else
+ {
+ switch(this->Section)
+ {
+ case SectionHeader: this->DoHeaderLine(); break;
+ case SectionBody: this->DoBodyLine(); break;
+ case SectionDiff: this->DiffParser::ProcessLine(); break;
+ case SectionCount: break; // never happens
+ }
+ }
+ return true;
+ }
+
+ void NextSection()
+ {
+ this->Section = SectionType((this->Section+1) % SectionCount);
+ this->Separator = SectionSep[this->Section];
+ if(this->Section == SectionHeader)
+ {
+ this->GIT->DoRevision(this->Rev, this->Changes);
+ this->Rev = Revision();
+ this->DiffReset();
+ }
+ }
+
+ void DoHeaderLine()
+ {
+ // Look for header fields that we need.
+ if(strncmp(this->Line.c_str(), "commit ", 7) == 0)
+ {
+ this->Rev.Rev = this->Line.c_str()+7;
+ }
+ else if(strncmp(this->Line.c_str(), "author ", 7) == 0)
+ {
+ Person author;
+ this->ParsePerson(this->Line.c_str()+7, author);
+ this->Rev.Author = author.Name;
+ this->Rev.EMail = author.EMail;
+ this->Rev.Date = this->FormatDateTime(author);
+ }
+ else if(strncmp(this->Line.c_str(), "committer ", 10) == 0)
+ {
+ Person committer;
+ this->ParsePerson(this->Line.c_str()+10, committer);
+ this->Rev.Committer = committer.Name;
+ this->Rev.CommitterEMail = committer.EMail;
+ this->Rev.CommitDate = this->FormatDateTime(committer);
+ }
+ }
+
+ void DoBodyLine()
+ {
+ // Commit log lines are indented by 4 spaces.
+ if(this->Line.size() >= 4)
+ {
+ this->Rev.Log += this->Line.substr(4);
+ }
+ this->Rev.Log += "\n";
+ }
+
+ std::string FormatDateTime(Person const& person)
+ {
+ // Convert the time to a human-readable format that is also easy
+ // to machine-parse: "CCYY-MM-DD hh:mm:ss".
+ time_t seconds = static_cast<time_t>(person.Time);
+ struct tm* t = gmtime(&seconds);
+ char dt[1024];
+ sprintf(dt, "%04d-%02d-%02d %02d:%02d:%02d",
+ t->tm_year+1900, t->tm_mon+1, t->tm_mday,
+ t->tm_hour, t->tm_min, t->tm_sec);
+ std::string out = dt;
+
+ // Add the time-zone field "+zone" or "-zone".
+ char tz[32];
+ if(person.TimeZone >= 0)
+ {
+ sprintf(tz, " +%04ld", person.TimeZone);
+ }
+ else
+ {
+ sprintf(tz, " -%04ld", -person.TimeZone);
+ }
+ out += tz;
+ return out;
+ }
+};
+
+char const cmCTestGIT::CommitParser::SectionSep[SectionCount] =
+{'\n', '\n', '\0'};
+
+//----------------------------------------------------------------------------
+void cmCTestGIT::LoadRevisions()
+{
+ // Use 'git rev-list ... | git diff-tree ...' to get revisions.
+ std::string range = this->OldRevision + ".." + this->NewRevision;
+ const char* git = this->CommandLineTool.c_str();
+ const char* git_rev_list[] =
+ {git, "rev-list", "--reverse", range.c_str(), "--", 0};
+ const char* git_diff_tree[] =
+ {git, "diff-tree", "--stdin", "--always", "-z", "-r", "--pretty=raw",
+ "--encoding=utf-8", 0};
+ this->Log << this->ComputeCommandLine(git_rev_list) << " | "
+ << this->ComputeCommandLine(git_diff_tree) << "\n";
+
+ cmsysProcess* cp = cmsysProcess_New();
+ cmsysProcess_AddCommand(cp, git_rev_list);
+ cmsysProcess_AddCommand(cp, git_diff_tree);
+ cmsysProcess_SetWorkingDirectory(cp, this->SourceDirectory.c_str());
+
+ CommitParser out(this, "dt-out> ");
+ OutputLogger err(this->Log, "dt-err> ");
+ this->RunProcess(cp, &out, &err);
+
+ // Send one extra zero-byte to terminate the last record.
+ out.Process("", 1);
+
+ cmsysProcess_Delete(cp);
+}
+
+//----------------------------------------------------------------------------
+void cmCTestGIT::LoadModifications()
+{
+ const char* git = this->CommandLineTool.c_str();
+
+ // Use 'git update-index' to refresh the index w.r.t. the work tree.
+ const char* git_update_index[] = {git, "update-index", "--refresh", 0};
+ OutputLogger ui_out(this->Log, "ui-out> ");
+ OutputLogger ui_err(this->Log, "ui-err> ");
+ this->RunChild(git_update_index, &ui_out, &ui_err);
+
+ // Use 'git diff-index' to get modified files.
+ const char* git_diff_index[] = {git, "diff-index", "-z", "HEAD", 0};
+ DiffParser out(this, "di-out> ");
+ OutputLogger err(this->Log, "di-err> ");
+ this->RunChild(git_diff_index, &out, &err);
+
+ for(std::vector<Change>::const_iterator ci = out.Changes.begin();
+ ci != out.Changes.end(); ++ci)
+ {
+ this->DoModification(PathModified, ci->Path);
+ }
+}
diff --git a/Source/CTest/cmCTestGIT.h b/Source/CTest/cmCTestGIT.h
new file mode 100644
index 000000000..f4fae8f9d
--- /dev/null
+++ b/Source/CTest/cmCTestGIT.h
@@ -0,0 +1,57 @@
+/*============================================================================
+ 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 cmCTestGIT_h
+#define cmCTestGIT_h
+
+#include "cmCTestGlobalVC.h"
+
+/** \class cmCTestGIT
+ * \brief Interaction with git command-line tool
+ *
+ */
+class cmCTestGIT: public cmCTestGlobalVC
+{
+public:
+ /** Construct with a CTest instance and update log stream. */
+ cmCTestGIT(cmCTest* ctest, std::ostream& log);
+
+ virtual ~cmCTestGIT();
+
+private:
+ unsigned int CurrentGitVersion;
+ unsigned int GetGitVersion();
+ std::string GetWorkingRevision();
+ virtual void NoteOldRevision();
+ virtual void NoteNewRevision();
+ virtual bool UpdateImpl();
+
+ std::string FindGitDir();
+ std::string FindTopDir();
+
+ bool UpdateByFetchAndReset();
+ bool UpdateByCustom(std::string const& custom);
+ bool UpdateInternal();
+
+ void LoadRevisions();
+ void LoadModifications();
+
+public: // needed by older Sun compilers
+ // Parsing helper classes.
+ class OneLineParser;
+ class DiffParser;
+ class CommitParser;
+ friend class OneLineParser;
+ friend class DiffParser;
+ friend class CommitParser;
+};
+
+#endif
diff --git a/Source/CTest/cmCTestGenericHandler.cxx b/Source/CTest/cmCTestGenericHandler.cxx
new file mode 100644
index 000000000..fd75e45e8
--- /dev/null
+++ b/Source/CTest/cmCTestGenericHandler.cxx
@@ -0,0 +1,171 @@
+/*============================================================================
+ 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 "cmCTestGenericHandler.h"
+#include "cmSystemTools.h"
+
+#include "cmCTest.h"
+
+//----------------------------------------------------------------------
+cmCTestGenericHandler::cmCTestGenericHandler()
+{
+ this->HandlerVerbose = cmSystemTools::OUTPUT_NONE;
+ this->CTest = 0;
+ this->SubmitIndex = 0;
+ this->AppendXML = false;
+}
+
+//----------------------------------------------------------------------
+cmCTestGenericHandler::~cmCTestGenericHandler()
+{
+}
+
+//----------------------------------------------------------------------
+void cmCTestGenericHandler::SetOption(const char* op, const char* value)
+{
+ if ( !op )
+ {
+ return;
+ }
+ if ( !value )
+ {
+ cmCTestGenericHandler::t_StringToString::iterator remit
+ = this->Options.find(op);
+ if ( remit != this->Options.end() )
+ {
+ this->Options.erase(remit);
+ }
+ return;
+ }
+
+ this->Options[op] = value;
+}
+
+//----------------------------------------------------------------------
+void cmCTestGenericHandler::SetPersistentOption(const char* op,
+ const char* value)
+{
+ this->SetOption(op, value);
+ if ( !op )
+ {
+ return;
+ }
+ if ( !value )
+ {
+ cmCTestGenericHandler::t_StringToString::iterator remit
+ = this->PersistentOptions.find(op);
+ if ( remit != this->PersistentOptions.end() )
+ {
+ this->PersistentOptions.erase(remit);
+ }
+ return;
+ }
+
+ this->PersistentOptions[op] = value;
+}
+
+//----------------------------------------------------------------------
+void cmCTestGenericHandler::Initialize()
+{
+ this->AppendXML = false;
+ 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();
+ }
+}
+
+//----------------------------------------------------------------------
+const char* cmCTestGenericHandler::GetOption(const char* op)
+{
+ cmCTestGenericHandler::t_StringToString::iterator remit
+ = this->Options.find(op);
+ if ( remit == this->Options.end() )
+ {
+ return 0;
+ }
+ return remit->second.c_str();
+}
+
+//----------------------------------------------------------------------
+bool cmCTestGenericHandler::StartResultingXML(cmCTest::Part part,
+ const char* name,
+ cmGeneratedFileStream& xofs)
+{
+ if ( !name )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Cannot create resulting XML file without providing the name"
+ << std::endl;);
+ return false;
+ }
+ cmOStringStream ostr;
+ ostr << name;
+ if ( this->SubmitIndex > 0 )
+ {
+ ostr << "_" << this->SubmitIndex;
+ }
+ ostr << ".xml";
+ if(this->CTest->GetCurrentTag().empty())
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Current Tag empty, this may mean NightlyStartTime / "
+ "CTEST_NIGHTLY_START_TIME was not set correctly. Or "
+ "maybe you forgot to call ctest_start() before calling "
+ "ctest_configure()." << std::endl);
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+ if( !this->CTest->OpenOutputFile(this->CTest->GetCurrentTag(),
+ ostr.str().c_str(), xofs, true) )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Cannot create resulting XML file: " << ostr.str().c_str()
+ << std::endl);
+ return false;
+ }
+ this->CTest->AddSubmitFile(part, ostr.str().c_str());
+ return true;
+}
+
+//----------------------------------------------------------------------
+bool cmCTestGenericHandler::StartLogFile(const char* name,
+ cmGeneratedFileStream& xofs)
+{
+ if ( !name )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Cannot create log file without providing the name" << std::endl;);
+ return false;
+ }
+ cmOStringStream ostr;
+ ostr << "Last" << name;
+ if ( this->SubmitIndex > 0 )
+ {
+ ostr << "_" << this->SubmitIndex;
+ }
+ if ( !this->CTest->GetCurrentTag().empty() )
+ {
+ ostr << "_" << this->CTest->GetCurrentTag();
+ }
+ ostr << ".log";
+ if( !this->CTest->OpenOutputFile("Temporary", ostr.str().c_str(), xofs) )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot create log file: "
+ << ostr.str().c_str() << std::endl);
+ return false;
+ }
+ return true;
+}
diff --git a/Source/CTest/cmCTestGenericHandler.h b/Source/CTest/cmCTestGenericHandler.h
new file mode 100644
index 000000000..18189ec2b
--- /dev/null
+++ b/Source/CTest/cmCTestGenericHandler.h
@@ -0,0 +1,107 @@
+/*============================================================================
+ 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 cmCTestGenericHandler_h
+#define cmCTestGenericHandler_h
+
+
+#include "cmObject.h"
+#include "cmCTest.h"
+#include "cmSystemTools.h" //OutputOption
+
+class cmMakefile;
+class cmCTestCommand;
+class cmGeneratedFileStream;
+
+/** \class cmCTestGenericHandler
+ * \brief A superclass of all CTest Handlers
+ *
+ */
+class cmCTestGenericHandler : public cmObject
+{
+public:
+ /**
+ * If verbose then more informaiton is printed out
+ */
+ void SetVerbose(bool val)
+ { this->HandlerVerbose = val ?
+ cmSystemTools::OUTPUT_MERGE : cmSystemTools::OUTPUT_NONE; }
+
+ /**
+ * Populate internals from CTest custom scripts
+ */
+ virtual void PopulateCustomVectors(cmMakefile *) {}
+
+ /**
+ * Do the actual processing. Subclass has to override it.
+ * Return < 0 if error.
+ */
+ virtual int ProcessHandler() = 0;
+
+ /**
+ * Process command line arguments that are applicable for the handler
+ */
+ virtual int ProcessCommandLineArguments(
+ const std::string& /*currentArg*/, size_t& /*idx*/,
+ const std::vector<std::string>& /*allArgs*/) { return 1; }
+
+ /**
+ * Initialize handler
+ */
+ virtual void Initialize();
+
+ /**
+ * Set the CTest instance
+ */
+ void SetCTestInstance(cmCTest* ctest) { this->CTest = ctest; }
+ cmCTest* GetCTestInstance() { return this->CTest; }
+
+ /**
+ * Construct handler
+ */
+ cmCTestGenericHandler();
+ virtual ~cmCTestGenericHandler();
+
+ typedef std::map<cmStdString,cmStdString> 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 SetCommand(cmCTestCommand* command)
+ {
+ this->Command = command;
+ }
+
+ void SetSubmitIndex(int idx) { this->SubmitIndex = idx; }
+ int GetSubmitIndex() { return this->SubmitIndex; }
+
+ void SetAppendXML(bool b) { this->AppendXML = b; }
+
+protected:
+ bool StartResultingXML(cmCTest::Part part,
+ const char* name, cmGeneratedFileStream& xofs);
+ bool StartLogFile(const char* name, cmGeneratedFileStream& xofs);
+
+ bool AppendXML;
+ cmSystemTools::OutputOption HandlerVerbose;
+ cmCTest *CTest;
+ t_StringToString Options;
+ t_StringToString PersistentOptions;
+
+ cmCTestCommand* Command;
+ int SubmitIndex;
+};
+
+#endif
+
diff --git a/Source/CTest/cmCTestGlobalVC.cxx b/Source/CTest/cmCTestGlobalVC.cxx
new file mode 100644
index 000000000..8c51102e5
--- /dev/null
+++ b/Source/CTest/cmCTestGlobalVC.cxx
@@ -0,0 +1,142 @@
+/*============================================================================
+ 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 "cmCTestGlobalVC.h"
+
+#include "cmCTest.h"
+#include "cmSystemTools.h"
+#include "cmXMLSafe.h"
+
+#include <cmsys/RegularExpression.hxx>
+
+//----------------------------------------------------------------------------
+cmCTestGlobalVC::cmCTestGlobalVC(cmCTest* ct, std::ostream& log):
+ cmCTestVC(ct, log)
+{
+ this->PriorRev = this->Unknown;
+}
+
+//----------------------------------------------------------------------------
+cmCTestGlobalVC::~cmCTestGlobalVC()
+{
+}
+
+//----------------------------------------------------------------------------
+const char* cmCTestGlobalVC::LocalPath(std::string const& path)
+{
+ return path.c_str();
+}
+
+//----------------------------------------------------------------------------
+void cmCTestGlobalVC::DoRevision(Revision const& revision,
+ std::vector<Change> const& changes)
+{
+ // Ignore changes in the old revision.
+ if(revision.Rev == this->OldRevision)
+ {
+ this->PriorRev = revision;
+ return;
+ }
+
+ // Indicate we found a revision.
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, "." << std::flush);
+
+ // Store the revision.
+ this->Revisions.push_back(revision);
+
+ // Report this revision.
+ Revision const& rev = this->Revisions.back();
+ this->Log << "Found revision " << rev.Rev << "\n"
+ << " author = " << rev.Author << "\n"
+ << " date = " << rev.Date << "\n";
+
+ // Update information about revisions of the changed files.
+ for(std::vector<Change>::const_iterator ci = changes.begin();
+ ci != changes.end(); ++ci)
+ {
+ if(const char* local = this->LocalPath(ci->Path))
+ {
+ std::string dir = cmSystemTools::GetFilenamePath(local);
+ std::string name = cmSystemTools::GetFilenameName(local);
+ File& file = this->Dirs[dir][name];
+ file.PriorRev = file.Rev? file.Rev : &this->PriorRev;
+ file.Rev = &rev;
+ this->Log << " " << ci->Action << " " << local << " " << "\n";
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmCTestGlobalVC::DoModification(PathStatus status,
+ std::string const& path)
+{
+ std::string dir = cmSystemTools::GetFilenamePath(path);
+ std::string name = cmSystemTools::GetFilenameName(path);
+ File& file = this->Dirs[dir][name];
+ file.Status = status;
+ // For local modifications the current rev is unknown and the
+ // prior rev is the latest from svn.
+ if(!file.Rev && !file.PriorRev)
+ {
+ file.PriorRev = &this->PriorRev;
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmCTestGlobalVC::WriteXMLDirectory(std::ostream& xml,
+ std::string const& path,
+ Directory const& dir)
+{
+ const char* slash = path.empty()? "":"/";
+ xml << "\t<Directory>\n"
+ << "\t\t<Name>" << cmXMLSafe(path) << "</Name>\n";
+ 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";
+}
+
+//----------------------------------------------------------------------------
+void cmCTestGlobalVC::WriteXMLGlobal(std::ostream& xml)
+{
+ if(!this->NewRevision.empty())
+ {
+ xml << "\t<Revision>" << this->NewRevision << "</Revision>\n";
+ }
+ if(!this->OldRevision.empty() && this->OldRevision != this->NewRevision)
+ {
+ xml << "\t<PriorRevision>" << this->OldRevision << "</PriorRevision>\n";
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestGlobalVC::WriteXMLUpdates(std::ostream& xml)
+{
+ cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ " Gathering version information (one . per revision):\n"
+ " " << std::flush);
+ this->LoadRevisions();
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, std::endl);
+
+ this->LoadModifications();
+
+ this->WriteXMLGlobal(xml);
+
+ for(std::map<cmStdString, Directory>::const_iterator
+ di = this->Dirs.begin(); di != this->Dirs.end(); ++di)
+ {
+ this->WriteXMLDirectory(xml, di->first, di->second);
+ }
+
+ return true;
+}
diff --git a/Source/CTest/cmCTestGlobalVC.h b/Source/CTest/cmCTestGlobalVC.h
new file mode 100644
index 000000000..a648a5982
--- /dev/null
+++ b/Source/CTest/cmCTestGlobalVC.h
@@ -0,0 +1,68 @@
+/*============================================================================
+ 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 cmCTestGlobalVC_h
+#define cmCTestGlobalVC_h
+
+#include "cmCTestVC.h"
+
+/** \class cmCTestGlobalVC
+ * \brief Base class for handling globally-versioned trees
+ *
+ */
+class cmCTestGlobalVC: public cmCTestVC
+{
+public:
+ /** Construct with a CTest instance and update log stream. */
+ cmCTestGlobalVC(cmCTest* ctest, std::ostream& log);
+
+ virtual ~cmCTestGlobalVC();
+
+protected:
+ // Implement cmCTestVC internal API.
+ virtual bool WriteXMLUpdates(std::ostream& xml);
+
+ /** Represent a vcs-reported action for one path in a revision. */
+ struct Change
+ {
+ char Action;
+ std::string Path;
+ Change(char a = '?'): Action(a) {}
+ };
+
+ // Update status for files in each directory.
+ class Directory: public std::map<cmStdString, File> {};
+ std::map<cmStdString, Directory> Dirs;
+
+ // Old and new repository revisions.
+ std::string OldRevision;
+ std::string NewRevision;
+
+ // Information known about old revision.
+ Revision PriorRev;
+
+ // Information about revisions from a svn log.
+ std::list<Revision> Revisions;
+
+ virtual const char* LocalPath(std::string const& path);
+
+ virtual void DoRevision(Revision const& revision,
+ std::vector<Change> const& changes);
+ virtual void DoModification(PathStatus status, std::string const& path);
+ virtual void LoadModifications() = 0;
+ virtual void LoadRevisions() = 0;
+
+ virtual void WriteXMLGlobal(std::ostream& xml);
+ void WriteXMLDirectory(std::ostream& xml, std::string const& path,
+ Directory const& dir);
+};
+
+#endif
diff --git a/Source/CTest/cmCTestHG.cxx b/Source/CTest/cmCTestHG.cxx
new file mode 100644
index 000000000..86a7617f1
--- /dev/null
+++ b/Source/CTest/cmCTestHG.cxx
@@ -0,0 +1,338 @@
+/*============================================================================
+ 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 "cmCTestHG.h"
+
+#include "cmCTest.h"
+#include "cmSystemTools.h"
+#include "cmXMLParser.h"
+
+#include <cmsys/RegularExpression.hxx>
+
+//----------------------------------------------------------------------------
+cmCTestHG::cmCTestHG(cmCTest* ct, std::ostream& log):
+ cmCTestGlobalVC(ct, log)
+{
+ this->PriorRev = this->Unknown;
+}
+
+//----------------------------------------------------------------------------
+cmCTestHG::~cmCTestHG()
+{
+}
+
+//----------------------------------------------------------------------------
+class cmCTestHG::IdentifyParser: public cmCTestVC::LineParser
+{
+public:
+ IdentifyParser(cmCTestHG* hg, const char* prefix,
+ std::string& rev): Rev(rev)
+ {
+ this->SetLog(&hg->Log, prefix);
+ this->RegexIdentify.compile("^([0-9a-f]+)");
+ }
+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 cmCTestHG::StatusParser: public cmCTestVC::LineParser
+{
+public:
+ StatusParser(cmCTestHG* hg, const char* prefix): HG(hg)
+ {
+ this->SetLog(&hg->Log, prefix);
+ this->RegexStatus.compile("([MARC!?I]) (.*)");
+ }
+
+private:
+ cmCTestHG* HG;
+ cmsys::RegularExpression RegexStatus;
+
+ bool ProcessLine()
+ {
+ if(this->RegexStatus.find(this->Line))
+ {
+ this->DoPath(this->RegexStatus.match(1)[0],
+ this->RegexStatus.match(2));
+ }
+ return true;
+ }
+
+ void DoPath(char status, std::string const& path)
+ {
+ if(path.empty()) return;
+
+ // See "hg help status". Note that there is no 'conflict' status.
+ switch(status)
+ {
+ case 'M': case 'A': case '!': case 'R':
+ this->HG->DoModification(PathModified, path);
+ break;
+ case 'I': case '?': case 'C': case ' ': default:
+ break;
+ }
+ }
+};
+
+//----------------------------------------------------------------------------
+std::string cmCTestHG::GetWorkingRevision()
+{
+ // Run plumbing "hg identify" to get work tree revision.
+ const char* hg = this->CommandLineTool.c_str();
+ const char* hg_identify[] = {hg, "identify","-i", 0};
+ std::string rev;
+ IdentifyParser out(this, "rev-out> ", rev);
+ OutputLogger err(this->Log, "rev-err> ");
+ this->RunChild(hg_identify, &out, &err);
+ return rev;
+}
+
+//----------------------------------------------------------------------------
+void cmCTestHG::NoteOldRevision()
+{
+ this->OldRevision = this->GetWorkingRevision();
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " Old revision of repository is: "
+ << this->OldRevision << "\n");
+ this->PriorRev.Rev = this->OldRevision;
+}
+
+//----------------------------------------------------------------------------
+void cmCTestHG::NoteNewRevision()
+{
+ this->NewRevision = this->GetWorkingRevision();
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " New revision of repository is: "
+ << this->NewRevision << "\n");
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestHG::UpdateImpl()
+{
+ // Use "hg pull" followed by "hg update" to update the working tree.
+ {
+ const char* hg = this->CommandLineTool.c_str();
+ const char* hg_pull[] = {hg, "pull","-v", 0};
+ OutputLogger out(this->Log, "pull-out> ");
+ OutputLogger err(this->Log, "pull-err> ");
+ this->RunChild(&hg_pull[0], &out, &err);
+ }
+
+ // TODO: if(this->CTest->GetTestModel() == cmCTest::NIGHTLY)
+
+ std::vector<char const*> hg_update;
+ hg_update.push_back(this->CommandLineTool.c_str());
+ hg_update.push_back("update");
+ hg_update.push_back("-v");
+
+ // Add user-specified update options.
+ std::string opts = this->CTest->GetCTestConfiguration("UpdateOptions");
+ if(opts.empty())
+ {
+ opts = this->CTest->GetCTestConfiguration("HGUpdateOptions");
+ }
+ std::vector<cmStdString> args = cmSystemTools::ParseArguments(opts.c_str());
+ for(std::vector<cmStdString>::const_iterator ai = args.begin();
+ ai != args.end(); ++ai)
+ {
+ hg_update.push_back(ai->c_str());
+ }
+
+ // Sentinel argument.
+ hg_update.push_back(0);
+
+ OutputLogger out(this->Log, "update-out> ");
+ OutputLogger err(this->Log, "update-err> ");
+ return this->RunUpdateCommand(&hg_update[0], &out, &err);
+}
+
+//----------------------------------------------------------------------------
+class cmCTestHG::LogParser: public cmCTestVC::OutputLogger,
+ private cmXMLParser
+{
+public:
+ LogParser(cmCTestHG* hg, const char* prefix):
+ OutputLogger(hg->Log, prefix), HG(hg) { this->InitializeParser(); }
+ ~LogParser() { this->CleanupParser(); }
+private:
+ cmCTestHG* HG;
+
+ typedef cmCTestHG::Revision Revision;
+ typedef cmCTestHG::Change Change;
+ Revision Rev;
+ std::vector<Change> Changes;
+ Change CurChange;
+ std::vector<char> CData;
+
+ virtual bool ProcessChunk(const char* data, int length)
+ {
+ this->OutputLogger::ProcessChunk(data, length);
+ this->ParseChunk(data, length);
+ return true;
+ }
+
+ virtual void StartElement(const char* name, const char** atts)
+ {
+ this->CData.clear();
+ if(strcmp(name, "logentry") == 0)
+ {
+ this->Rev = Revision();
+ if(const char* rev = this->FindAttribute(atts, "revision"))
+ {
+ this->Rev.Rev = rev;
+ }
+ this->Changes.clear();
+ }
+ }
+
+ virtual void CharacterDataHandler(const char* data, int length)
+ {
+ this->CData.insert(this->CData.end(), data, data+length);
+ }
+
+ virtual void EndElement(const char* name)
+ {
+ if(strcmp(name, "logentry") == 0)
+ {
+ this->HG->DoRevision(this->Rev, this->Changes);
+ }
+ else if(strcmp(name, "author") == 0 && !this->CData.empty())
+ {
+ this->Rev.Author.assign(&this->CData[0], this->CData.size());
+ }
+ else if ( strcmp(name, "email") == 0 && !this->CData.empty())
+ {
+ this->Rev.EMail.assign(&this->CData[0], this->CData.size());
+ }
+ else if(strcmp(name, "date") == 0 && !this->CData.empty())
+ {
+ this->Rev.Date.assign(&this->CData[0], this->CData.size());
+ }
+ else if(strcmp(name, "msg") == 0 && !this->CData.empty())
+ {
+ this->Rev.Log.assign(&this->CData[0], this->CData.size());
+ }
+ else if(strcmp(name, "files") == 0 && !this->CData.empty())
+ {
+ std::vector<std::string> paths = this->SplitCData();
+ for(unsigned int i = 0; i < paths.size(); ++i)
+ {
+ // Updated by default, will be modified using file_adds and
+ // file_dels.
+ this->CurChange = Change('U');
+ this->CurChange.Path = paths[i];
+ this->Changes.push_back(this->CurChange);
+ }
+ }
+ else if(strcmp(name, "file_adds") == 0 && !this->CData.empty())
+ {
+ std::string added_paths(this->CData.begin(), this->CData.end());
+ for(unsigned int i = 0; i < this->Changes.size(); ++i)
+ {
+ if(added_paths.find(this->Changes[i].Path) != std::string::npos)
+ {
+ this->Changes[i].Action = 'A';
+ }
+ }
+ }
+ else if(strcmp(name, "file_dels") == 0 && !this->CData.empty())
+ {
+ std::string added_paths(this->CData.begin(), this->CData.end());
+ for(unsigned int i = 0; i < this->Changes.size(); ++i)
+ {
+ if(added_paths.find(this->Changes[i].Path) != std::string::npos)
+ {
+ this->Changes[i].Action = 'D';
+ }
+ }
+ }
+ this->CData.clear();
+ }
+
+ std::vector<std::string> SplitCData()
+ {
+ std::vector<std::string> output;
+ std::string currPath;
+ for(unsigned int i=0; i < this->CData.size(); ++i)
+ {
+ if(this->CData[i] != ' ')
+ {
+ currPath += this->CData[i];
+ }
+ else
+ {
+ output.push_back(currPath);
+ currPath = "";
+ }
+ }
+ output.push_back(currPath);
+ return output;
+ }
+
+ virtual void ReportError(int, int, const char* msg)
+ {
+ this->HG->Log << "Error parsing hg log xml: " << msg << "\n";
+ }
+};
+
+//----------------------------------------------------------------------------
+void cmCTestHG::LoadRevisions()
+{
+ // Use 'hg log' to get revisions in a xml format.
+ //
+ // TODO: This should use plumbing or python code to be more precise.
+ // The "list of strings" templates like {files} will not work when
+ // the project has spaces in the path. Also, they may not have
+ // proper XML escapes.
+ std::string range = this->OldRevision + ":" + this->NewRevision;
+ const char* hg = this->CommandLineTool.c_str();
+ const char* hgXMLTemplate =
+ "<logentry\n"
+ " revision=\"{node|short}\">\n"
+ " <author>{author|person}</author>\n"
+ " <email>{author|email}</email>\n"
+ " <date>{date|isodate}</date>\n"
+ " <msg>{desc}</msg>\n"
+ " <files>{files}</files>\n"
+ " <file_adds>{file_adds}</file_adds>\n"
+ " <file_dels>{file_dels}</file_dels>\n"
+ "</logentry>\n";
+ const char* hg_log[] = {hg, "log","--removed", "-r", range.c_str(),
+ "--template", hgXMLTemplate, 0};
+
+ LogParser out(this, "log-out> ");
+ out.Process("<?xml version=\"1.0\"?>\n"
+ "<log>\n");
+ OutputLogger err(this->Log, "log-err> ");
+ this->RunChild(hg_log, &out, &err);
+ out.Process("</log>\n");
+}
+
+//----------------------------------------------------------------------------
+void cmCTestHG::LoadModifications()
+{
+ // Use 'hg status' to get modified files.
+ const char* hg = this->CommandLineTool.c_str();
+ const char* hg_status[] = {hg, "status", 0};
+ StatusParser out(this, "status-out> ");
+ OutputLogger err(this->Log, "status-err> ");
+ this->RunChild(hg_status, &out, &err);
+}
diff --git a/Source/CTest/cmCTestHG.h b/Source/CTest/cmCTestHG.h
new file mode 100644
index 000000000..1eaf9337e
--- /dev/null
+++ b/Source/CTest/cmCTestHG.h
@@ -0,0 +1,47 @@
+/*============================================================================
+ 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 cmCTestHG_h
+#define cmCTestHG_h
+
+#include "cmCTestGlobalVC.h"
+
+/** \class cmCTestHG
+ * \brief Interaction with Mercurial command-line tool
+ *
+ */
+class cmCTestHG: public cmCTestGlobalVC
+{
+public:
+ /** Construct with a CTest instance and update log stream. */
+ cmCTestHG(cmCTest* ctest, std::ostream& log);
+
+ virtual ~cmCTestHG();
+
+private:
+ std::string GetWorkingRevision();
+ virtual void NoteOldRevision();
+ virtual void NoteNewRevision();
+ virtual bool UpdateImpl();
+
+ void LoadRevisions();
+ void LoadModifications();
+
+ // Parsing helper classes.
+ class IdentifyParser;
+ class StatusParser;
+ class LogParser;
+ friend class IdentifyParser;
+ friend class StatusParser;
+ friend class LogParser;
+};
+
+#endif
diff --git a/Source/CTest/cmCTestHandlerCommand.cxx b/Source/CTest/cmCTestHandlerCommand.cxx
new file mode 100644
index 000000000..1957e04e3
--- /dev/null
+++ b/Source/CTest/cmCTestHandlerCommand.cxx
@@ -0,0 +1,197 @@
+/*============================================================================
+ 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 "cmCTestHandlerCommand.h"
+
+#include "cmCTest.h"
+#include "cmCTestGenericHandler.h"
+
+cmCTestHandlerCommand::cmCTestHandlerCommand()
+{
+ const size_t INIT_SIZE = 100;
+ size_t cc;
+ this->Arguments.reserve(INIT_SIZE);
+ for ( cc = 0; cc < INIT_SIZE; ++ cc )
+ {
+ this->Arguments.push_back(0);
+ }
+ this->Arguments[ct_RETURN_VALUE] = "RETURN_VALUE";
+ this->Arguments[ct_SOURCE] = "SOURCE";
+ this->Arguments[ct_BUILD] = "BUILD";
+ this->Arguments[ct_SUBMIT_INDEX] = "SUBMIT_INDEX";
+ this->Last = ct_LAST;
+ this->AppendXML = false;
+}
+
+bool cmCTestHandlerCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ // Allocate space for argument values.
+ this->Values.clear();
+ this->Values.resize(this->Last, 0);
+
+ // Process input arguments.
+ this->ArgumentDoing = ArgumentDoingNone;
+ for(unsigned int i=0; i < args.size(); ++i)
+ {
+ // Check this argument.
+ if(!this->CheckArgumentKeyword(args[i]) &&
+ !this->CheckArgumentValue(args[i]))
+ {
+ cmOStringStream e;
+ e << "called with unknown argument \"" << args[i] << "\".";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+
+ // Quit if an argument is invalid.
+ if(this->ArgumentDoing == ArgumentDoingError)
+ {
+ return false;
+ }
+ }
+
+ // Set the config type of this ctest to the current value of the
+ // CTEST_CONFIGURATION_TYPE script variable if it is defined.
+ // The current script value trumps the -C argument on the command
+ // line.
+ const char* ctestConfigType =
+ this->Makefile->GetDefinition("CTEST_CONFIGURATION_TYPE");
+ if (ctestConfigType)
+ {
+ this->CTest->SetConfigType(ctestConfigType);
+ }
+
+ cmCTestLog(this->CTest, DEBUG, "Initialize handler" << std::endl;);
+ cmCTestGenericHandler* handler = this->InitializeHandler();
+ if ( !handler )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Cannot instantiate test handler " << this->GetName()
+ << std::endl);
+ return false;
+ }
+
+ handler->SetAppendXML(this->AppendXML);
+
+ handler->PopulateCustomVectors(this->Makefile);
+ if ( this->Values[ct_BUILD] )
+ {
+ this->CTest->SetCTestConfiguration("BuildDirectory",
+ cmSystemTools::CollapseFullPath(
+ this->Values[ct_BUILD]).c_str());
+ }
+ else
+ {
+ const char* bdir =
+ this->Makefile->GetSafeDefinition("CTEST_BINARY_DIRECTORY");
+ if(bdir)
+ {
+ this->
+ CTest->SetCTestConfiguration("BuildDirectory",
+ cmSystemTools::CollapseFullPath(bdir).c_str());
+ }
+ else
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "CTEST_BINARY_DIRECTORY not set" << std::endl;);
+ }
+ }
+ if ( this->Values[ct_SOURCE] )
+ {
+ cmCTestLog(this->CTest, DEBUG,
+ "Set source directory to: " << this->Values[ct_SOURCE] << std::endl);
+ this->CTest->SetCTestConfiguration("SourceDirectory",
+ cmSystemTools::CollapseFullPath(
+ this->Values[ct_SOURCE]).c_str());
+ }
+ else
+ {
+ this->CTest->SetCTestConfiguration("SourceDirectory",
+ cmSystemTools::CollapseFullPath(
+ this->Makefile->GetSafeDefinition("CTEST_SOURCE_DIRECTORY")).c_str());
+ }
+ if ( this->Values[ct_SUBMIT_INDEX] )
+ {
+ if ( this->CTest->GetDartVersion() <= 1 )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Dart before version 2.0 does not support collecting submissions."
+ << std::endl
+ << "Please upgrade the server to Dart 2 or higher, or do not use "
+ "SUBMIT_INDEX." << std::endl);
+ }
+ else
+ {
+ handler->SetSubmitIndex(atoi(this->Values[ct_SUBMIT_INDEX]));
+ }
+ }
+ std::string current_dir = cmSystemTools::GetCurrentWorkingDirectory();
+ cmSystemTools::ChangeDirectory(
+ this->CTest->GetCTestConfiguration("BuildDirectory").c_str());
+ int res = handler->ProcessHandler();
+ if ( this->Values[ct_RETURN_VALUE] && *this->Values[ct_RETURN_VALUE])
+ {
+ cmOStringStream str;
+ str << res;
+ this->Makefile->AddDefinition(
+ this->Values[ct_RETURN_VALUE], str.str().c_str());
+ }
+ cmSystemTools::ChangeDirectory(current_dir.c_str());
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestHandlerCommand::CheckArgumentKeyword(std::string const& arg)
+{
+ // Look for non-value arguments common to all commands.
+ if(arg == "APPEND")
+ {
+ this->ArgumentDoing = ArgumentDoingNone;
+ this->AppendXML = true;
+ return true;
+ }
+
+ // Check for a keyword in our argument/value table.
+ for(unsigned int k=0; k < this->Arguments.size(); ++k)
+ {
+ if(this->Arguments[k] && arg == this->Arguments[k])
+ {
+ this->ArgumentDoing = ArgumentDoingKeyword;
+ this->ArgumentIndex = k;
+ return true;
+ }
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestHandlerCommand::CheckArgumentValue(std::string const& arg)
+{
+ if(this->ArgumentDoing == ArgumentDoingKeyword)
+ {
+ this->ArgumentDoing = ArgumentDoingNone;
+ unsigned int k = this->ArgumentIndex;
+ if(this->Values[k])
+ {
+ cmOStringStream e;
+ e << "Called with more than one value for " << this->Arguments[k];
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ this->ArgumentDoing = ArgumentDoingError;
+ return true;
+ }
+ this->Values[k] = arg.c_str();
+ cmCTestLog(this->CTest, DEBUG, "Set " << this->Arguments[k]
+ << " to " << arg << "\n");
+ return true;
+ }
+ return false;
+}
diff --git a/Source/CTest/cmCTestHandlerCommand.h b/Source/CTest/cmCTestHandlerCommand.h
new file mode 100644
index 000000000..8ef2b8028
--- /dev/null
+++ b/Source/CTest/cmCTestHandlerCommand.h
@@ -0,0 +1,77 @@
+/*============================================================================
+ 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 cmCTestHandlerCommand_h
+#define cmCTestHandlerCommand_h
+
+#include "cmCTestCommand.h"
+
+class cmCTestGenericHandler;
+
+/** \class cmCTestHandler
+ * \brief Run a ctest script
+ *
+ * cmCTestHandlerCommand defineds the command to test the project.
+ */
+class cmCTestHandlerCommand : public cmCTestCommand
+{
+public:
+ cmCTestHandlerCommand();
+
+ /**
+ * 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);
+
+ cmTypeMacro(cmCTestHandlerCommand, cmCTestCommand);
+
+ enum
+ {
+ ct_NONE,
+ ct_RETURN_VALUE,
+ ct_BUILD,
+ ct_SOURCE,
+ ct_SUBMIT_INDEX,
+ ct_LAST
+ };
+
+protected:
+ virtual cmCTestGenericHandler* InitializeHandler() = 0;
+
+ // Command argument handling.
+ virtual bool CheckArgumentKeyword(std::string const& arg);
+ virtual bool CheckArgumentValue(std::string const& arg);
+ enum
+ {
+ ArgumentDoingNone,
+ ArgumentDoingError,
+ ArgumentDoingKeyword,
+ ArgumentDoingLast1
+ };
+ int ArgumentDoing;
+ unsigned int ArgumentIndex;
+
+ bool AppendXML;
+
+ std::string ReturnVariable;
+ std::vector<const char*> Arguments;
+ std::vector<const char*> Values;
+ size_t Last;
+};
+
+#define CTEST_COMMAND_APPEND_OPTION_DOCS \
+ "The APPEND option marks results for append to those previously " \
+ "submitted to a dashboard server since the last ctest_start. " \
+ "Append semantics are defined by the dashboard server in use."
+
+#endif
diff --git a/Source/CTest/cmCTestLaunch.cxx b/Source/CTest/cmCTestLaunch.cxx
new file mode 100644
index 000000000..9831d0200
--- /dev/null
+++ b/Source/CTest/cmCTestLaunch.cxx
@@ -0,0 +1,719 @@
+/*============================================================================
+ 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 "cmCTestLaunch.h"
+
+#include "cmGeneratedFileStream.h"
+#include "cmSystemTools.h"
+#include "cmXMLSafe.h"
+#include "cmake.h"
+
+#include <cmsys/MD5.h>
+#include <cmsys/Process.h>
+#include <cmsys/RegularExpression.hxx>
+
+//----------------------------------------------------------------------------
+cmCTestLaunch::cmCTestLaunch(int argc, const char* const* argv)
+{
+ this->Passthru = true;
+ this->Process = 0;
+ this->ExitCode = 1;
+ this->CWD = cmSystemTools::GetCurrentWorkingDirectory();
+
+ if(!this->ParseArguments(argc, argv))
+ {
+ return;
+ }
+
+ this->ComputeFileNames();
+
+ this->ScrapeRulesLoaded = false;
+ this->HaveOut = false;
+ this->HaveErr = false;
+ this->Process = cmsysProcess_New();
+}
+
+//----------------------------------------------------------------------------
+cmCTestLaunch::~cmCTestLaunch()
+{
+ cmsysProcess_Delete(this->Process);
+ if(!this->Passthru)
+ {
+ cmSystemTools::RemoveFile(this->LogOut.c_str());
+ cmSystemTools::RemoveFile(this->LogErr.c_str());
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestLaunch::ParseArguments(int argc, const char* const* argv)
+{
+ // Launcher options occur first and are separated from the real
+ // command line by a '--' option.
+ enum Doing { DoingNone,
+ DoingOutput,
+ DoingSource,
+ DoingLanguage,
+ DoingTargetName,
+ DoingTargetType,
+ DoingBuildDir,
+ DoingCount };
+ Doing doing = DoingNone;
+ int arg0 = 0;
+ for(int i=1; !arg0 && i < argc; ++i)
+ {
+ const char* arg = argv[i];
+ if(strcmp(arg, "--") == 0)
+ {
+ arg0 = i+1;
+ }
+ else if(strcmp(arg, "--output") == 0)
+ {
+ doing = DoingOutput;
+ }
+ else if(strcmp(arg, "--source") == 0)
+ {
+ doing = DoingSource;
+ }
+ else if(strcmp(arg, "--language") == 0)
+ {
+ doing = DoingLanguage;
+ }
+ else if(strcmp(arg, "--target-name") == 0)
+ {
+ doing = DoingTargetName;
+ }
+ else if(strcmp(arg, "--target-type") == 0)
+ {
+ doing = DoingTargetType;
+ }
+ else if(strcmp(arg, "--build-dir") == 0)
+ {
+ doing = DoingBuildDir;
+ }
+ else if(doing == DoingOutput)
+ {
+ this->OptionOutput = arg;
+ doing = DoingNone;
+ }
+ else if(doing == DoingSource)
+ {
+ this->OptionSource = arg;
+ doing = DoingNone;
+ }
+ else if(doing == DoingLanguage)
+ {
+ this->OptionLanguage = arg;
+ if(this->OptionLanguage == "CXX")
+ {
+ this->OptionLanguage = "C++";
+ }
+ doing = DoingNone;
+ }
+ else if(doing == DoingTargetName)
+ {
+ this->OptionTargetName = arg;
+ doing = DoingNone;
+ }
+ else if(doing == DoingTargetType)
+ {
+ this->OptionTargetType = arg;
+ doing = DoingNone;
+ }
+ else if(doing == DoingBuildDir)
+ {
+ this->OptionBuildDir = arg;
+ doing = DoingNone;
+ }
+ }
+
+ // Extract the real command line.
+ if(arg0)
+ {
+ this->RealArgC = argc - arg0;
+ this->RealArgV = argv + arg0;
+ for(int i=0; i < this->RealArgC; ++i)
+ {
+ this->HandleRealArg(this->RealArgV[i]);
+ }
+ return true;
+ }
+ else
+ {
+ this->RealArgC = 0;
+ this->RealArgV = 0;
+ std::cerr << "No launch/command separator ('--') found!\n";
+ return false;
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmCTestLaunch::HandleRealArg(const char* arg)
+{
+#ifdef _WIN32
+ // Expand response file arguments.
+ if(arg[0] == '@' && cmSystemTools::FileExists(arg+1))
+ {
+ std::ifstream fin(arg+1);
+ std::string line;
+ while(cmSystemTools::GetLineFromStream(fin, line))
+ {
+ cmSystemTools::ParseWindowsCommandLine(line.c_str(), this->RealArgs);
+ }
+ return;
+ }
+#endif
+ this->RealArgs.push_back(arg);
+}
+
+//----------------------------------------------------------------------------
+void cmCTestLaunch::ComputeFileNames()
+{
+ // We just passthru the behavior of the real command unless the
+ // CTEST_LAUNCH_LOGS environment variable is set.
+ const char* d = getenv("CTEST_LAUNCH_LOGS");
+ if(!(d && *d))
+ {
+ return;
+ }
+ this->Passthru = false;
+
+ // The environment variable specifies the directory into which we
+ // generate build logs.
+ this->LogDir = d;
+ cmSystemTools::ConvertToUnixSlashes(this->LogDir);
+ this->LogDir += "/";
+
+ // We hash the input command working dir and command line to obtain
+ // a repeatable and (probably) unique name for log files.
+ char hash[32];
+ cmsysMD5* md5 = cmsysMD5_New();
+ cmsysMD5_Initialize(md5);
+ cmsysMD5_Append(md5, (unsigned char const*)(this->CWD.c_str()), -1);
+ for(std::vector<std::string>::const_iterator ai = this->RealArgs.begin();
+ ai != this->RealArgs.end(); ++ai)
+ {
+ cmsysMD5_Append(md5, (unsigned char const*)ai->c_str(), -1);
+ }
+ cmsysMD5_FinalizeHex(md5, hash);
+ cmsysMD5_Delete(md5);
+ this->LogHash.assign(hash, 32);
+
+ // We store stdout and stderr in temporary log files.
+ this->LogOut = this->LogDir;
+ this->LogOut += "launch-";
+ this->LogOut += this->LogHash;
+ this->LogOut += "-out.txt";
+ this->LogErr = this->LogDir;
+ this->LogErr += "launch-";
+ this->LogErr += this->LogHash;
+ this->LogErr += "-err.txt";
+}
+
+//----------------------------------------------------------------------------
+void cmCTestLaunch::RunChild()
+{
+ // Ignore noopt make rules
+ if(this->RealArgs.empty() || this->RealArgs[0] == ":")
+ {
+ this->ExitCode = 0;
+ return;
+ }
+
+ // Prepare to run the real command.
+ cmsysProcess* cp = this->Process;
+ cmsysProcess_SetCommand(cp, this->RealArgV);
+
+ std::ofstream fout;
+ std::ofstream ferr;
+ if(this->Passthru)
+ {
+ // In passthru mode we just share the output pipes.
+ cmsysProcess_SetPipeShared(cp, cmsysProcess_Pipe_STDOUT, 1);
+ cmsysProcess_SetPipeShared(cp, cmsysProcess_Pipe_STDERR, 1);
+ }
+ else
+ {
+ // In full mode we record the child output pipes to log files.
+ fout.open(this->LogOut.c_str(),
+ std::ios::out | std::ios::binary);
+ ferr.open(this->LogErr.c_str(),
+ std::ios::out | std::ios::binary);
+ }
+
+ // Run the real command.
+ cmsysProcess_Execute(cp);
+
+ // Record child stdout and stderr if necessary.
+ if(!this->Passthru)
+ {
+ char* data = 0;
+ int length = 0;
+ while(int p = cmsysProcess_WaitForData(cp, &data, &length, 0))
+ {
+ if(p == cmsysProcess_Pipe_STDOUT)
+ {
+ fout.write(data, length);
+ std::cout.write(data, length);
+ this->HaveOut = true;
+ }
+ else if(p == cmsysProcess_Pipe_STDERR)
+ {
+ ferr.write(data, length);
+ std::cerr.write(data, length);
+ this->HaveErr = true;
+ }
+ }
+ }
+
+ // Wait for the real command to finish.
+ cmsysProcess_WaitForExit(cp, 0);
+ this->ExitCode = cmsysProcess_GetExitValue(cp);
+}
+
+//----------------------------------------------------------------------------
+int cmCTestLaunch::Run()
+{
+ if(!this->Process)
+ {
+ std::cerr << "Could not allocate cmsysProcess instance!\n";
+ return -1;
+ }
+
+ this->RunChild();
+
+ if(this->CheckResults())
+ {
+ return this->ExitCode;
+ }
+
+ this->LoadConfig();
+ this->WriteXML();
+
+ return this->ExitCode;
+}
+
+//----------------------------------------------------------------------------
+void cmCTestLaunch::LoadLabels()
+{
+ if(this->OptionBuildDir.empty() || this->OptionTargetName.empty())
+ {
+ return;
+ }
+
+ // Labels are listed in per-target files.
+ std::string fname = this->OptionBuildDir;
+ fname += cmake::GetCMakeFilesDirectory();
+ fname += "/";
+ fname += this->OptionTargetName;
+ fname += ".dir/Labels.txt";
+
+ // We are interested in per-target labels for this source file.
+ std::string source = this->OptionSource;
+ cmSystemTools::ConvertToUnixSlashes(source);
+
+ // Load the labels file.
+ std::ifstream fin(fname.c_str(), std::ios::in | std::ios::binary);
+ if(!fin) { return; }
+ bool inTarget = true;
+ bool inSource = false;
+ std::string line;
+ while(cmSystemTools::GetLineFromStream(fin, line))
+ {
+ if(line.empty() || line[0] == '#')
+ {
+ // Ignore blank and comment lines.
+ continue;
+ }
+ else if(line[0] == ' ')
+ {
+ // Label lines appear indented by one space.
+ if(inTarget || inSource)
+ {
+ this->Labels.insert(line.c_str()+1);
+ }
+ }
+ else if(!this->OptionSource.empty() && !inSource)
+ {
+ // Non-indented lines specify a source file name. The first one
+ // is the end of the target-wide labels. Use labels following a
+ // matching source.
+ inTarget = false;
+ inSource = this->SourceMatches(line, source);
+ }
+ else
+ {
+ return;
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestLaunch::SourceMatches(std::string const& lhs,
+ std::string const& rhs)
+{
+ // TODO: Case sensitivity, UseRelativePaths, etc. Note that both
+ // paths in the comparison get generated by CMake. This is done for
+ // every source in the target, so it should be efficient (cannot use
+ // cmSystemTools::IsSameFile).
+ return lhs == rhs;
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestLaunch::IsError() const
+{
+ return this->ExitCode != 0;
+}
+
+//----------------------------------------------------------------------------
+void cmCTestLaunch::WriteXML()
+{
+ // Name the xml file.
+ std::string logXML = this->LogDir;
+ logXML += this->IsError()? "error-" : "warning-";
+ logXML += this->LogHash;
+ logXML += ".xml";
+
+ // 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";
+}
+
+//----------------------------------------------------------------------------
+void cmCTestLaunch::WriteXMLAction(std::ostream& fxml)
+{
+ fxml << "\t\t<!-- Meta-information about the build action -->\n";
+ fxml << "\t\t<Action>\n";
+
+ // TargetName
+ if(!this->OptionTargetName.empty())
+ {
+ fxml << "\t\t\t<TargetName>"
+ << cmXMLSafe(this->OptionTargetName)
+ << "</TargetName>\n";
+ }
+
+ // Language
+ if(!this->OptionLanguage.empty())
+ {
+ fxml << "\t\t\t<Language>"
+ << cmXMLSafe(this->OptionLanguage)
+ << "</Language>\n";
+ }
+
+ // SourceFile
+ if(!this->OptionSource.empty())
+ {
+ std::string source = this->OptionSource;
+ cmSystemTools::ConvertToUnixSlashes(source);
+
+ // 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()))
+ {
+ source = cmSystemTools::RelativePath(this->SourceDir.c_str(),
+ source.c_str());
+ }
+
+ fxml << "\t\t\t<SourceFile>"
+ << cmXMLSafe(source)
+ << "</SourceFile>\n";
+ }
+
+ // OutputFile
+ if(!this->OptionOutput.empty())
+ {
+ fxml << "\t\t\t<OutputFile>"
+ << cmXMLSafe(this->OptionOutput)
+ << "</OutputFile>\n";
+ }
+
+ // OutputType
+ const char* outputType = 0;
+ if(!this->OptionTargetType.empty())
+ {
+ if(this->OptionTargetType == "EXECUTABLE")
+ {
+ outputType = "executable";
+ }
+ else if(this->OptionTargetType == "SHARED_LIBRARY")
+ {
+ outputType = "shared library";
+ }
+ else if(this->OptionTargetType == "MODULE_LIBRARY")
+ {
+ outputType = "module library";
+ }
+ else if(this->OptionTargetType == "STATIC_LIBRARY")
+ {
+ outputType = "static library";
+ }
+ }
+ else if(!this->OptionSource.empty())
+ {
+ outputType = "object file";
+ }
+ if(outputType)
+ {
+ fxml << "\t\t\t<OutputType>"
+ << cmXMLSafe(outputType)
+ << "</OutputType>\n";
+ }
+
+ fxml << "\t\t</Action>\n";
+}
+
+//----------------------------------------------------------------------------
+void cmCTestLaunch::WriteXMLCommand(std::ostream& fxml)
+{
+ fxml << "\n";
+ fxml << "\t\t<!-- Details of command -->\n";
+ fxml << "\t\t<Command>\n";
+ if(!this->CWD.empty())
+ {
+ fxml << "\t\t\t<WorkingDirectory>"
+ << cmXMLSafe(this->CWD)
+ << "</WorkingDirectory>\n";
+ }
+ 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";
+ }
+ fxml << "\t\t</Command>\n";
+}
+
+//----------------------------------------------------------------------------
+void cmCTestLaunch::WriteXMLResult(std::ostream& fxml)
+{
+ fxml << "\n";
+ fxml << "\t\t<!-- Result of command -->\n";
+ fxml << "\t\t<Result>\n";
+
+ // StdOut
+ fxml << "\t\t\t<StdOut>";
+ this->DumpFileToXML(fxml, this->LogOut);
+ fxml << "</StdOut>\n";
+
+ // StdErr
+ fxml << "\t\t\t<StdErr>";
+ this->DumpFileToXML(fxml, this->LogErr);
+ fxml << "</StdErr>\n";
+
+ // ExitCondition
+ fxml << "\t\t\t<ExitCondition>";
+ cmsysProcess* cp = this->Process;
+ switch (cmsysProcess_GetState(cp))
+ {
+ case cmsysProcess_State_Starting:
+ fxml << "No process has been executed"; break;
+ case cmsysProcess_State_Executing:
+ fxml << "The process is still executing"; break;
+ case cmsysProcess_State_Disowned:
+ fxml << "Disowned"; break;
+ case cmsysProcess_State_Killed:
+ fxml << "Killed by parent"; break;
+
+ case cmsysProcess_State_Expired:
+ fxml << "Killed when timeout expired"; break;
+ case cmsysProcess_State_Exited:
+ fxml << this->ExitCode; break;
+ case cmsysProcess_State_Exception:
+ fxml << "Terminated abnormally: "
+ << cmXMLSafe(cmsysProcess_GetExceptionString(cp)); break;
+ case cmsysProcess_State_Error:
+ fxml << "Error administrating child process: "
+ << cmXMLSafe(cmsysProcess_GetErrorString(cp)); break;
+ };
+ fxml << "</ExitCondition>\n";
+
+ fxml << "\t\t</Result>\n";
+}
+
+//----------------------------------------------------------------------------
+void cmCTestLaunch::WriteXMLLabels(std::ostream& fxml)
+{
+ 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();
+ li != this->Labels.end(); ++li)
+ {
+ fxml << "\t\t\t<Label>" << cmXMLSafe(*li) << "</Label>\n";
+ }
+ fxml << "\t\t</Labels>\n";
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmCTestLaunch::DumpFileToXML(std::ostream& fxml,
+ std::string const& fname)
+{
+ std::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);
+ sep = "\n";
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestLaunch::CheckResults()
+{
+ // Skip XML in passthru mode.
+ if(this->Passthru)
+ {
+ return true;
+ }
+
+ // We always report failure for error conditions.
+ if(this->IsError())
+ {
+ return false;
+ }
+
+ // Scrape the output logs to look for warnings.
+ if((this->HaveErr && this->ScrapeLog(this->LogErr)) ||
+ (this->HaveOut && this->ScrapeLog(this->LogOut)))
+ {
+ return false;
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+void cmCTestLaunch::LoadScrapeRules()
+{
+ if(this->ScrapeRulesLoaded)
+ {
+ return;
+ }
+ this->ScrapeRulesLoaded = true;
+
+ // Common compiler warning formats. These are much simpler than the
+ // full log-scraping expressions because we do not need to extract
+ // file and line information.
+ this->RegexWarning.push_back("(^|[ :])[Ww][Aa][Rr][Nn][Ii][Nn][Gg]");
+ this->RegexWarning.push_back("(^|[ :])[Rr][Ee][Mm][Aa][Rr][Kk]");
+ this->RegexWarning.push_back("(^|[ :])[Nn][Oo][Tt][Ee]");
+
+ // Load custom match rules given to us by CTest.
+ this->LoadScrapeRules("Warning", this->RegexWarning);
+ this->LoadScrapeRules("WarningSuppress", this->RegexWarningSuppress);
+}
+
+//----------------------------------------------------------------------------
+void
+cmCTestLaunch
+::LoadScrapeRules(const char* purpose,
+ std::vector<cmsys::RegularExpression>& regexps)
+{
+ std::string fname = this->LogDir;
+ fname += "Custom";
+ fname += purpose;
+ fname += ".txt";
+ std::ifstream fin(fname.c_str(), std::ios::in | std::ios::binary);
+ std::string line;
+ cmsys::RegularExpression rex;
+ while(cmSystemTools::GetLineFromStream(fin, line))
+ {
+ if(rex.compile(line.c_str()))
+ {
+ regexps.push_back(rex);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestLaunch::ScrapeLog(std::string const& fname)
+{
+ this->LoadScrapeRules();
+
+ // Look for log file lines matching warning expressions but not
+ // suppression expressions.
+ std::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))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestLaunch::Match(std::string const& line,
+ std::vector<cmsys::RegularExpression>& regexps)
+{
+ for(std::vector<cmsys::RegularExpression>::iterator ri = regexps.begin();
+ ri != regexps.end(); ++ri)
+ {
+ if(ri->find(line.c_str()))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+int cmCTestLaunch::Main(int argc, const char* const argv[])
+{
+ if(argc == 2)
+ {
+ std::cerr << "ctest --launch: this mode is for internal CTest use only"
+ << std::endl;
+ return 1;
+ }
+ cmCTestLaunch self(argc, argv);
+ return self.Run();
+}
+
+//----------------------------------------------------------------------------
+#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();
+ std::string fname = this->LogDir;
+ fname += "CTestLaunchConfig.cmake";
+ if(cmSystemTools::FileExists(fname.c_str()) &&
+ mf->ReadListFile(0, 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
new file mode 100644
index 000000000..7457e8357
--- /dev/null
+++ b/Source/CTest/cmCTestLaunch.h
@@ -0,0 +1,104 @@
+/*============================================================================
+ 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 cmCTestLaunch_h
+#define cmCTestLaunch_h
+
+#include "cmStandardIncludes.h"
+#include <cmsys/RegularExpression.hxx>
+
+/** \class cmCTestLaunch
+ * \brief Launcher for make rules to report results for ctest
+ *
+ * This implements the 'ctest --launch' tool.
+ */
+class cmCTestLaunch
+{
+public:
+ /** Entry point from ctest executable main(). */
+ static int Main(int argc, const char* const argv[]);
+private:
+ // Initialize the launcher from its command line.
+ cmCTestLaunch(int argc, const char* const* argv);
+ ~cmCTestLaunch();
+
+ // Run the real command.
+ int Run();
+ void RunChild();
+
+ // Methods to check the result of the real command.
+ bool IsError() const;
+ bool CheckResults();
+
+ // Launcher options specified before the real command.
+ std::string OptionOutput;
+ std::string OptionSource;
+ std::string OptionLanguage;
+ std::string OptionTargetName;
+ std::string OptionTargetType;
+ std::string OptionBuildDir;
+ bool ParseArguments(int argc, const char* const* argv);
+
+ // The real command line appearing after launcher arguments.
+ int RealArgC;
+ const char* const* RealArgV;
+ std::string CWD;
+
+ // The real command line after response file expansion.
+ std::vector<std::string> RealArgs;
+ void HandleRealArg(const char* arg);
+
+ // A hash of the real command line is unique and unlikely to collide.
+ std::string LogHash;
+ void ComputeFileNames();
+
+ bool Passthru;
+ struct cmsysProcess_s* Process;
+ int ExitCode;
+
+ // Temporary log files for stdout and stderr of real command.
+ std::string LogDir;
+ std::string LogOut;
+ std::string LogErr;
+ bool HaveOut;
+ bool HaveErr;
+
+ // Labels associated with the build rule.
+ std::set<cmStdString> Labels;
+ void LoadLabels();
+ bool SourceMatches(std::string const& lhs,
+ std::string const& rhs);
+
+ // Regular expressions to match warnings and their exceptions.
+ bool ScrapeRulesLoaded;
+ std::vector<cmsys::RegularExpression> RegexWarning;
+ std::vector<cmsys::RegularExpression> RegexWarningSuppress;
+ void LoadScrapeRules();
+ void LoadScrapeRules(const char* purpose,
+ std::vector<cmsys::RegularExpression>& regexps);
+ bool ScrapeLog(std::string const& fname);
+ bool Match(std::string const& line,
+ std::vector<cmsys::RegularExpression>& regexps);
+
+ // 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);
+
+ // Configuration
+ void LoadConfig();
+ std::string SourceDir;
+};
+
+#endif
diff --git a/Source/CTest/cmCTestMemCheckCommand.cxx b/Source/CTest/cmCTestMemCheckCommand.cxx
new file mode 100644
index 000000000..535c9934f
--- /dev/null
+++ b/Source/CTest/cmCTestMemCheckCommand.cxx
@@ -0,0 +1,32 @@
+/*============================================================================
+ 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 "cmCTestMemCheckCommand.h"
+
+#include "cmCTest.h"
+#include "cmCTestGenericHandler.h"
+
+
+cmCTestGenericHandler* cmCTestMemCheckCommand::InitializeActualHandler()
+{
+ cmCTestGenericHandler* handler
+ = this->CTest->GetInitializedHandler("memcheck");
+
+ this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
+ "MemoryCheckCommand", "CTEST_MEMORYCHECK_COMMAND");
+ this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
+ "MemoryCheckCommandOptions", "CTEST_MEMORYCHECK_COMMAND_OPTIONS");
+ this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
+ "MemoryCheckSuppressionFile", "CTEST_MEMORYCHECK_SUPPRESSIONS_FILE");
+
+ return handler;
+}
+
diff --git a/Source/CTest/cmCTestMemCheckCommand.h b/Source/CTest/cmCTestMemCheckCommand.h
new file mode 100644
index 000000000..399fe8b22
--- /dev/null
+++ b/Source/CTest/cmCTestMemCheckCommand.h
@@ -0,0 +1,88 @@
+/*============================================================================
+ 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 cmCTestMemCheckCommand_h
+#define cmCTestMemCheckCommand_h
+
+#include "cmCTestTestCommand.h"
+
+class cmCTestGenericHandler;
+
+/** \class cmCTestMemCheck
+ * \brief Run a ctest script
+ *
+ * cmCTestMemCheckCommand defineds the command to test the project.
+ */
+class cmCTestMemCheckCommand : public cmCTestTestCommand
+{
+public:
+
+ cmCTestMemCheckCommand() {}
+
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ cmCTestMemCheckCommand* ni = new cmCTestMemCheckCommand;
+ ni->CTest = this->CTest;
+ ni->CTestScriptHandler = this->CTestScriptHandler;
+ return ni;
+ }
+
+ /**
+ * 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;
+ }
+
+ cmTypeMacro(cmCTestMemCheckCommand, cmCTestTestCommand);
+
+protected:
+ cmCTestGenericHandler* InitializeActualHandler();
+};
+
+
+#endif
+
diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx
new file mode 100644
index 000000000..3e4ecddaa
--- /dev/null
+++ b/Source/CTest/cmCTestMemCheckHandler.cxx
@@ -0,0 +1,955 @@
+/*============================================================================
+ 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 "cmCTestMemCheckHandler.h"
+#include "cmXMLParser.h"
+#include "cmCTest.h"
+#include "cmake.h"
+#include "cmGeneratedFileStream.h"
+#include <cmsys/Process.h>
+#include <cmsys/RegularExpression.hxx>
+#include <cmsys/Base64.h>
+#include "cmMakefile.h"
+#include "cmXMLSafe.h"
+
+#include <stdlib.h>
+#include <math.h>
+#include <float.h>
+
+struct CatToErrorType
+{
+ const char* ErrorCategory;
+ int ErrorCode;
+};
+
+
+static CatToErrorType cmCTestMemCheckBoundsChecker[] = {
+ // Error tags
+ {"Write Overrun", cmCTestMemCheckHandler::ABW},
+ {"Read Overrun", cmCTestMemCheckHandler::ABR},
+ {"Memory Overrun", cmCTestMemCheckHandler::ABW},
+ {"Allocation Conflict", cmCTestMemCheckHandler::FMM},
+ {"Bad Pointer Use", cmCTestMemCheckHandler::FMW},
+ {"Dangling Pointer", cmCTestMemCheckHandler::FMR},
+ {0,0}
+};
+
+// parse the xml file storing the installed version of Xcode on
+// the machine
+class cmBoundsCheckerParser : public cmXMLParser
+{
+public:
+ cmBoundsCheckerParser(cmCTest* c) { this->CTest = c;}
+ void StartElement(const char* name, const char** atts)
+ {
+ if(strcmp(name, "MemoryLeak") == 0)
+ {
+ this->Errors.push_back(cmCTestMemCheckHandler::MLK);
+ }
+ if(strcmp(name, "ResourceLeak") == 0)
+ {
+ this->Errors.push_back(cmCTestMemCheckHandler::MLK);
+ }
+ if(strcmp(name, "Error") == 0)
+ {
+ this->ParseError(atts);
+ }
+ if(strcmp(name, "Dangling Pointer") == 0)
+ {
+ this->ParseError(atts);
+ }
+ // Create the log
+ cmOStringStream ostr;
+ ostr << name << ":\n";
+ int i = 0;
+ for(; atts[i] != 0; i+=2)
+ {
+ ostr << " " << cmXMLSafe(atts[i])
+ << " - " << cmXMLSafe(atts[i+1]) << "\n";
+ }
+ ostr << "\n";
+ this->Log += ostr.str();
+ }
+ void EndElement(const char* )
+ {
+ }
+
+ const char* GetAttribute(const char* name, const char** atts)
+ {
+ int i = 0;
+ for(; atts[i] != 0; ++i)
+ {
+ if(strcmp(name, atts[i]) == 0)
+ {
+ return atts[i+1];
+ }
+ }
+ return 0;
+ }
+ void ParseError(const char** atts)
+ {
+ CatToErrorType* ptr = cmCTestMemCheckBoundsChecker;
+ const char* cat = this->GetAttribute("ErrorCategory", atts);
+ if(!cat)
+ {
+ this->Errors.push_back(cmCTestMemCheckHandler::ABW); // do not know
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "No Category found in Bounds checker XML\n" );
+ return;
+ }
+ while(ptr->ErrorCategory && cat)
+ {
+ if(strcmp(ptr->ErrorCategory, cat) == 0)
+ {
+ this->Errors.push_back(ptr->ErrorCode);
+ return; // found it we are done
+ }
+ ptr++;
+ }
+ if(ptr->ErrorCategory)
+ {
+ this->Errors.push_back(cmCTestMemCheckHandler::ABW); // do not know
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Found unknown Bounds Checker error "
+ << ptr->ErrorCategory << std::endl);
+ }
+ }
+ cmCTest* CTest;
+ std::vector<int> Errors;
+ std::string Log;
+};
+
+#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
+};
+
+
+//----------------------------------------------------------------------
+cmCTestMemCheckHandler::cmCTestMemCheckHandler()
+{
+ this->MemCheck = true;
+ this->CustomMaximumPassedTestOutputSize = 0;
+ this->CustomMaximumFailedTestOutputSize = 0;
+}
+
+//----------------------------------------------------------------------
+void cmCTestMemCheckHandler::Initialize()
+{
+ this->Superclass::Initialize();
+ this->CustomMaximumPassedTestOutputSize = 0;
+ this->CustomMaximumFailedTestOutputSize = 0;
+ this->MemoryTester = "";
+ this->MemoryTesterOptions.clear();
+ this->MemoryTesterStyle = UNKNOWN;
+ this->MemoryTesterOutputFile = "";
+ int cc;
+ for ( cc = 0; cc < NO_MEMORY_FAULT; cc ++ )
+ {
+ this->MemoryTesterGlobalResults[cc] = 0;
+ }
+
+}
+
+//----------------------------------------------------------------------
+int cmCTestMemCheckHandler::PreProcessHandler()
+{
+ if ( !this->InitializeMemoryChecking() )
+ {
+ return 0;
+ }
+
+ if ( !this->ExecuteCommands(this->CustomPreMemCheck) )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Problem executing pre-memcheck command(s)." << std::endl);
+ return 0;
+ }
+ return 1;
+}
+
+//----------------------------------------------------------------------
+int cmCTestMemCheckHandler::PostProcessHandler()
+{
+ if ( !this->ExecuteCommands(this->CustomPostMemCheck) )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Problem executing post-memcheck command(s)." << std::endl);
+ return 0;
+ }
+ return 1;
+}
+
+//----------------------------------------------------------------------
+void cmCTestMemCheckHandler::GenerateTestCommand(
+ std::vector<std::string>& args)
+{
+ std::vector<cmStdString>::size_type pp;
+ std::string memcheckcommand = "";
+ memcheckcommand = this->MemoryTester;
+ for ( pp = 0; pp < this->MemoryTesterOptions.size(); pp ++ )
+ {
+ args.push_back(this->MemoryTesterOptions[pp]);
+ memcheckcommand += " \"";
+ memcheckcommand += this->MemoryTesterOptions[pp];
+ memcheckcommand += "\"";
+ }
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Memory check command: "
+ << memcheckcommand << std::endl);
+}
+
+//----------------------------------------------------------------------
+void cmCTestMemCheckHandler::PopulateCustomVectors(cmMakefile *mf)
+{
+ this->cmCTestTestHandler::PopulateCustomVectors(mf);
+ this->CTest->PopulateCustomVector(mf, "CTEST_CUSTOM_PRE_MEMCHECK",
+ this->CustomPreMemCheck);
+ this->CTest->PopulateCustomVector(mf, "CTEST_CUSTOM_POST_MEMCHECK",
+ this->CustomPostMemCheck);
+
+ this->CTest->PopulateCustomVector(mf,
+ "CTEST_CUSTOM_MEMCHECK_IGNORE",
+ this->CustomTestsIgnore);
+}
+
+//----------------------------------------------------------------------
+void cmCTestMemCheckHandler::GenerateDartOutput(std::ostream& os)
+{
+ if ( !this->CTest->GetProduceXML() )
+ {
+ return;
+ }
+
+ this->CTest->StartXML(os, this->AppendXML);
+ os << "<DynamicAnalysis Checker=\"";
+ switch ( this->MemoryTesterStyle )
+ {
+ case cmCTestMemCheckHandler::VALGRIND:
+ os << "Valgrind";
+ break;
+ case cmCTestMemCheckHandler::PURIFY:
+ os << "Purify";
+ break;
+ case cmCTestMemCheckHandler::BOUNDS_CHECKER:
+ os << "BoundsChecker";
+ break;
+ default:
+ os << "Unknown";
+ }
+ os << "\">" << std::endl;
+
+ os << "\t<StartDateTime>" << this->StartTest << "</StartDateTime>\n"
+ << "\t<StartTestTime>" << this->StartTestTime << "</StartTestTime>\n"
+ << "\t<TestList>\n";
+ 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;
+ }
+ os << "\t</TestList>\n";
+ cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ "-- Processing memory checking output: ");
+ size_t total = this->TestResults.size();
+ size_t step = total / 10;
+ size_t current = 0;
+ for ( cc = 0; cc < this->TestResults.size(); cc ++ )
+ {
+ cmCTestTestResult *result = &this->TestResults[cc];
+ std::string memcheckstr;
+ int memcheckresults[cmCTestMemCheckHandler::NO_MEMORY_FAULT];
+ int kk;
+ bool res = this->ProcessMemCheckOutput(result->Output, memcheckstr,
+ memcheckresults);
+ if ( res && result->Status == cmCTestMemCheckHandler::COMPLETED )
+ {
+ continue;
+ }
+ 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 ++ )
+ {
+ if ( memcheckresults[kk] )
+ {
+ os << "\t\t\t<Defect type=\"" << cmCTestMemCheckResultLongStrings[kk]
+ << "\">"
+ << memcheckresults[kk]
+ << "</Defect>" << std::endl;
+ }
+ this->MemoryTesterGlobalResults[kk] += memcheckresults[kk];
+ }
+
+ std::string logTag;
+ if(this->CTest->ShouldCompressMemCheckOutput())
+ {
+ this->CTest->CompressString(memcheckstr);
+ logTag = "\t<Log compression=\"gzip\" encoding=\"base64\">\n";
+ }
+ else
+ {
+ logTag = "\t<Log>\n";
+ }
+
+ os
+ << "\t\t</Results>\n"
+ << logTag << cmXMLSafe(memcheckstr) << std::endl
+ << "\t</Log>\n";
+ this->WriteTestResultFooter(os, result);
+ if ( current < cc )
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, "#" << std::flush);
+ 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 ++ )
+ {
+ if ( this->MemoryTesterGlobalResults[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;
+ }
+ }
+ 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);
+
+
+}
+
+//----------------------------------------------------------------------
+bool cmCTestMemCheckHandler::InitializeMemoryChecking()
+{
+ // Setup the command
+ if ( cmSystemTools::FileExists(this->CTest->GetCTestConfiguration(
+ "MemoryCheckCommand").c_str()) )
+ {
+ this->MemoryTester
+ = cmSystemTools::ConvertToOutputPath(this->CTest->GetCTestConfiguration(
+ "MemoryCheckCommand").c_str());
+ }
+ else if ( cmSystemTools::FileExists(this->CTest->GetCTestConfiguration(
+ "PurifyCommand").c_str()) )
+ {
+ this->MemoryTester
+ = cmSystemTools::ConvertToOutputPath(this->CTest->GetCTestConfiguration(
+ "PurifyCommand").c_str());
+ }
+ else if ( cmSystemTools::FileExists(this->CTest->GetCTestConfiguration(
+ "ValgrindCommand").c_str()) )
+ {
+ this->MemoryTester
+ = cmSystemTools::ConvertToOutputPath(this->CTest->GetCTestConfiguration(
+ "ValgrindCommand").c_str());
+ }
+ else if ( cmSystemTools::FileExists(this->CTest->GetCTestConfiguration(
+ "BoundsCheckerCommand").c_str()) )
+ {
+ this->MemoryTester
+ = cmSystemTools::ConvertToOutputPath(this->CTest->GetCTestConfiguration(
+ "BoundsCheckerCommand").c_str());
+ }
+ else
+ {
+ cmCTestLog(this->CTest, WARNING,
+ "Memory checker (MemoryCheckCommand) "
+ "not set, or cannot find the specified program."
+ << std::endl);
+ return false;
+ }
+
+ if ( this->MemoryTester[0] == '\"' &&
+ this->MemoryTester[this->MemoryTester.size()-1] == '\"' )
+ {
+ this->MemoryTester
+ = this->MemoryTester.substr(1, this->MemoryTester.size()-2);
+ }
+
+ // Setup the options
+ std::string memoryTesterOptions;
+ if ( this->CTest->GetCTestConfiguration(
+ "MemoryCheckCommandOptions").size() )
+ {
+ memoryTesterOptions = this->CTest->GetCTestConfiguration(
+ "MemoryCheckCommandOptions");
+ }
+ else if ( this->CTest->GetCTestConfiguration(
+ "ValgrindCommandOptions").size() )
+ {
+ memoryTesterOptions = this->CTest->GetCTestConfiguration(
+ "ValgrindCommandOptions");
+ }
+ this->MemoryTesterOptions
+ = cmSystemTools::ParseArguments(memoryTesterOptions.c_str());
+
+ this->MemoryTesterOutputFile
+ = this->CTest->GetBinaryDir() + "/Testing/Temporary/MemoryChecker.log";
+
+ if ( this->MemoryTester.find("valgrind") != std::string::npos )
+ {
+ this->MemoryTesterStyle = cmCTestMemCheckHandler::VALGRIND;
+ if ( this->MemoryTesterOptions.empty() )
+ {
+ this->MemoryTesterOptions.push_back("-q");
+ this->MemoryTesterOptions.push_back("--tool=memcheck");
+ this->MemoryTesterOptions.push_back("--leak-check=yes");
+ this->MemoryTesterOptions.push_back("--show-reachable=yes");
+ this->MemoryTesterOptions.push_back("--workaround-gcc296-bugs=yes");
+ this->MemoryTesterOptions.push_back("--num-callers=50");
+ }
+ if ( this->CTest->GetCTestConfiguration(
+ "MemoryCheckSuppressionFile").size() )
+ {
+ if ( !cmSystemTools::FileExists(this->CTest->GetCTestConfiguration(
+ "MemoryCheckSuppressionFile").c_str()) )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Cannot find memory checker suppression file: "
+ << this->CTest->GetCTestConfiguration(
+ "MemoryCheckSuppressionFile").c_str() << std::endl);
+ return false;
+ }
+ std::string suppressions = "--suppressions="
+ + this->CTest->GetCTestConfiguration("MemoryCheckSuppressionFile");
+ this->MemoryTesterOptions.push_back(suppressions);
+ }
+ }
+ else if ( this->MemoryTester.find("purify") != std::string::npos )
+ {
+ this->MemoryTesterStyle = cmCTestMemCheckHandler::PURIFY;
+ std::string outputFile;
+#ifdef _WIN32
+ if( this->CTest->GetCTestConfiguration(
+ "MemoryCheckSuppressionFile").size() )
+ {
+ if( !cmSystemTools::FileExists(this->CTest->GetCTestConfiguration(
+ "MemoryCheckSuppressionFile").c_str()) )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Cannot find memory checker suppression file: "
+ << this->CTest->GetCTestConfiguration(
+ "MemoryCheckSuppressionFile").c_str() << std::endl);
+ return false;
+ }
+ std::string filterFiles = "/FilterFiles="
+ + this->CTest->GetCTestConfiguration("MemoryCheckSuppressionFile");
+ this->MemoryTesterOptions.push_back(filterFiles);
+ }
+ outputFile = "/SAVETEXTDATA=";
+#else
+ outputFile = "-log-file=";
+#endif
+ outputFile += this->MemoryTesterOutputFile;
+ this->MemoryTesterOptions.push_back(outputFile);
+ }
+ else if ( this->MemoryTester.find("BC") != std::string::npos )
+ {
+ this->BoundsCheckerXMLFile = this->MemoryTesterOutputFile;
+ std::string dpbdFile = this->CTest->GetBinaryDir()
+ + "/Testing/Temporary/MemoryChecker.DPbd";
+ this->BoundsCheckerDPBDFile = dpbdFile;
+ this->MemoryTesterStyle = cmCTestMemCheckHandler::BOUNDS_CHECKER;
+ this->MemoryTesterOptions.push_back("/B");
+ this->MemoryTesterOptions.push_back(dpbdFile);
+ this->MemoryTesterOptions.push_back("/X");
+ this->MemoryTesterOptions.push_back(this->MemoryTesterOutputFile);
+ this->MemoryTesterOptions.push_back("/M");
+ }
+ else
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Do not understand memory checker: " << this->MemoryTester.c_str()
+ << std::endl);
+ return false;
+ }
+
+ std::vector<cmStdString>::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)
+{
+ 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);
+ }
+ else if ( this->MemoryTesterStyle == cmCTestMemCheckHandler::PURIFY )
+ {
+ return this->ProcessMemCheckPurifyOutput(str, log, results);
+ }
+ else if ( this->MemoryTesterStyle ==
+ cmCTestMemCheckHandler::BOUNDS_CHECKER )
+ {
+ return this->ProcessMemCheckBoundsCheckerOutput(str, log, results);
+ }
+ else
+ {
+ log.append("\nMemory checking style used was: ");
+ log.append("None that I know");
+ log = str;
+ }
+
+
+ return true;
+}
+
+//----------------------------------------------------------------------
+bool cmCTestMemCheckHandler::ProcessMemCheckPurifyOutput(
+ const std::string& str, std::string& log,
+ int* results)
+{
+ std::vector<cmStdString> lines;
+ cmSystemTools::Split(str.c_str(), lines);
+ cmOStringStream 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();
+ i != lines.end(); ++i)
+ {
+ int failure = cmCTestMemCheckHandler::NO_MEMORY_FAULT;
+ if ( pfW.find(*i) )
+ {
+ int cc;
+ for ( cc = 0; cc < cmCTestMemCheckHandler::NO_MEMORY_FAULT; cc ++ )
+ {
+ if ( pfW.match(1) == cmCTestMemCheckResultStrings[cc] )
+ {
+ failure = cc;
+ break;
+ }
+ }
+ if ( cc == cmCTestMemCheckHandler::NO_MEMORY_FAULT )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Unknown Purify memory fault: "
+ << pfW.match(1) << std::endl);
+ ostr << "*** Unknown Purify memory fault: " << pfW.match(1)
+ << std::endl;
+ }
+ }
+ if ( failure != NO_MEMORY_FAULT )
+ {
+ ostr << "<b>" << cmCTestMemCheckResultStrings[failure] << "</b> ";
+ results[failure] ++;
+ defects ++;
+ }
+ ostr << cmXMLSafe(*i) << std::endl;
+ }
+
+ log = ostr.str();
+ if ( defects )
+ {
+ return false;
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------
+bool cmCTestMemCheckHandler::ProcessMemCheckValgrindOutput(
+ const std::string& str, std::string& log,
+ int* results)
+{
+ std::vector<cmStdString> lines;
+ cmSystemTools::Split(str.c_str(), lines);
+ bool unlimitedOutput = false;
+ if(str.find("CTEST_FULL_OUTPUT") != str.npos ||
+ this->CustomMaximumFailedTestOutputSize == 0)
+ {
+ unlimitedOutput = true;
+ }
+
+ std::string::size_type cc;
+
+ cmOStringStream ostr;
+ log = "";
+
+ int defects = 0;
+
+ cmsys::RegularExpression valgrindLine("^==[0-9][0-9]*==");
+
+ cmsys::RegularExpression vgFIM(
+ "== .*Invalid free\\(\\) / delete / delete\\[\\]");
+ cmsys::RegularExpression vgFMM(
+ "== .*Mismatched free\\(\\) / delete / delete \\[\\]");
+ cmsys::RegularExpression vgMLK1(
+ "== .*[0-9,]+ bytes in [0-9,]+ blocks are definitely lost"
+ " in loss record [0-9,]+ of [0-9,]+");
+ cmsys::RegularExpression vgMLK2(
+ "== .*[0-9,]+ \\([0-9,]+ direct, [0-9,]+ indirect\\)"
+ " bytes in [0-9,]+ blocks are definitely lost"
+ " in loss record [0-9,]+ of [0-9,]+");
+ cmsys::RegularExpression vgPAR(
+ "== .*Syscall param .* (contains|points to) unaddressable byte\\(s\\)");
+ cmsys::RegularExpression vgMPK1(
+ "== .*[0-9,]+ bytes in [0-9,]+ blocks are possibly lost in"
+ " loss record [0-9,]+ of [0-9,]+");
+ cmsys::RegularExpression vgMPK2(
+ "== .*[0-9,]+ bytes in [0-9,]+ blocks are still reachable"
+ " in loss record [0-9,]+ of [0-9,]+");
+ cmsys::RegularExpression vgUMC(
+ "== .*Conditional jump or move depends on uninitialised value\\(s\\)");
+ cmsys::RegularExpression vgUMR1(
+ "== .*Use of uninitialised value of size [0-9,]+");
+ cmsys::RegularExpression vgUMR2("== .*Invalid read of size [0-9,]+");
+ cmsys::RegularExpression vgUMR3("== .*Jump to the invalid address ");
+ cmsys::RegularExpression vgUMR4("== .*Syscall param .* contains "
+ "uninitialised or unaddressable byte\\(s\\)");
+ cmsys::RegularExpression vgUMR5("== .*Syscall param .* uninitialised");
+ cmsys::RegularExpression vgIPW("== .*Invalid write of size [0-9,]+");
+ cmsys::RegularExpression vgABR("== .*pthread_mutex_unlock: mutex is "
+ "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);
+ 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);
+
+ if ( valgrindLine.find(lines[cc]) )
+ {
+ cmCTestLog(this->CTest, DEBUG, "valgrind line "
+ << lines[cc] << std::endl);
+ int failure = cmCTestMemCheckHandler::NO_MEMORY_FAULT;
+ if ( vgFIM.find(lines[cc]) )
+ {
+ failure = cmCTestMemCheckHandler::FIM;
+ }
+ else if ( vgFMM.find(lines[cc]) )
+ {
+ failure = cmCTestMemCheckHandler::FMM;
+ }
+ else if ( vgMLK1.find(lines[cc]) )
+ {
+ failure = cmCTestMemCheckHandler::MLK;
+ }
+ else if ( vgMLK2.find(lines[cc]) )
+ {
+ failure = cmCTestMemCheckHandler::MLK;
+ }
+ else if ( vgPAR.find(lines[cc]) )
+ {
+ failure = cmCTestMemCheckHandler::PAR;
+ }
+ else if ( vgMPK1.find(lines[cc]) )
+ {
+ failure = cmCTestMemCheckHandler::MPK;
+ }
+ else if ( vgMPK2.find(lines[cc]) )
+ {
+ failure = cmCTestMemCheckHandler::MPK;
+ }
+ else if ( vgUMC.find(lines[cc]) )
+ {
+ failure = cmCTestMemCheckHandler::UMC;
+ }
+ else if ( vgUMR1.find(lines[cc]) )
+ {
+ failure = cmCTestMemCheckHandler::UMR;
+ }
+ else if ( vgUMR2.find(lines[cc]) )
+ {
+ failure = cmCTestMemCheckHandler::UMR;
+ }
+ else if ( vgUMR3.find(lines[cc]) )
+ {
+ failure = cmCTestMemCheckHandler::UMR;
+ }
+ else if ( vgUMR4.find(lines[cc]) )
+ {
+ failure = cmCTestMemCheckHandler::UMR;
+ }
+ else if ( vgUMR5.find(lines[cc]) )
+ {
+ failure = cmCTestMemCheckHandler::UMR;
+ }
+ else if ( vgIPW.find(lines[cc]) )
+ {
+ failure = cmCTestMemCheckHandler::IPW;
+ }
+ else if ( vgABR.find(lines[cc]) )
+ {
+ failure = cmCTestMemCheckHandler::ABR;
+ }
+
+ if ( failure != cmCTestMemCheckHandler::NO_MEMORY_FAULT )
+ {
+ ostr << "<b>" << cmCTestMemCheckResultStrings[failure] << "</b> ";
+ results[failure] ++;
+ defects ++;
+ }
+ totalOutputSize += lines[cc].size();
+ ostr << cmXMLSafe(lines[cc]) << std::endl;
+ }
+ else
+ {
+ nonValGrindOutput.push_back(cc);
+ }
+ }
+ // Now put all all the non valgrind output into the test output
+ if(!outputFull)
+ {
+ for(std::vector<std::string::size_type>::iterator i =
+ nonValGrindOutput.begin(); i != nonValGrindOutput.end(); ++i)
+ {
+ 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";
+ }
+ }
+ }
+ cmCTestLog(this->CTest, DEBUG, "End test (elapsed: "
+ << (cmSystemTools::GetTime() - sttime) << std::endl);
+ log = ostr.str();
+ if ( defects )
+ {
+ return false;
+ }
+ return true;
+}
+
+
+
+//----------------------------------------------------------------------
+bool cmCTestMemCheckHandler::ProcessMemCheckBoundsCheckerOutput(
+ const std::string& str, std::string& log,
+ int* results)
+{
+ log = "";
+ double sttime = cmSystemTools::GetTime();
+ std::vector<cmStdString> lines;
+ cmSystemTools::Split(str.c_str(), lines);
+ cmCTestLog(this->CTest, DEBUG, "Start test: " << lines.size() << std::endl);
+ std::vector<cmStdString>::size_type cc;
+ for ( cc = 0; cc < lines.size(); cc ++ )
+ {
+ if(lines[cc] == BOUNDS_CHECKER_MARKER)
+ {
+ break;
+ }
+ }
+ cmBoundsCheckerParser parser(this->CTest);
+ parser.InitializeParser();
+ if(cc < lines.size())
+ {
+ for(cc++; cc < lines.size(); ++cc)
+ {
+ std::string& theLine = lines[cc];
+ // check for command line arguments that are not escaped
+ // correctly by BC
+ if(theLine.find("TargetArgs=") != theLine.npos)
+ {
+ // skip this because BC gets it wrong and we can't parse it
+ }
+ else if(!parser.ParseChunk(theLine.c_str(), theLine.size()))
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Error in ParseChunk: " << theLine.c_str()
+ << std::endl);
+ }
+ }
+ }
+ int defects = 0;
+ for(cc =0; cc < parser.Errors.size(); ++cc)
+ {
+ results[parser.Errors[cc]]++;
+ defects++;
+ }
+ cmCTestLog(this->CTest, DEBUG, "End test (elapsed: "
+ << (cmSystemTools::GetTime() - sttime) << std::endl);
+ if(defects)
+ {
+ // only put the output of Bounds Checker if there were
+ // errors or leaks detected
+ log = parser.Log;
+ return false;
+ }
+ return true;
+}
+
+// This method puts the bounds checker output file into the output
+// for the test
+void
+cmCTestMemCheckHandler::PostProcessBoundsCheckerTest(cmCTestTestResult& res)
+{
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "PostProcessBoundsCheckerTest for : "
+ << res.Name.c_str() << std::endl);
+ if ( !cmSystemTools::FileExists(this->MemoryTesterOutputFile.c_str()) )
+ {
+ std::string log = "Cannot find memory tester output file: "
+ + this->MemoryTesterOutputFile;
+ cmCTestLog(this->CTest, ERROR_MESSAGE, log.c_str() << std::endl);
+ return;
+ }
+ // put a scope around this to close ifs so the file can be removed
+ {
+ std::ifstream ifs(this->MemoryTesterOutputFile.c_str());
+ if ( !ifs )
+ {
+ std::string log = "Cannot read memory tester output file: "
+ + this->MemoryTesterOutputFile;
+ cmCTestLog(this->CTest, ERROR_MESSAGE, log.c_str() << std::endl);
+ return;
+ }
+ res.Output += BOUNDS_CHECKER_MARKER;
+ res.Output += "\n";
+ std::string line;
+ while ( cmSystemTools::GetLineFromStream(ifs, line) )
+ {
+ res.Output += line;
+ res.Output += "\n";
+ }
+ }
+ 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);
+}
+
+void
+cmCTestMemCheckHandler::PostProcessPurifyTest(cmCTestTestResult& res)
+{
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "PostProcessPurifyTest for : "
+ << res.Name.c_str() << std::endl);
+ if ( !cmSystemTools::FileExists(this->MemoryTesterOutputFile.c_str()) )
+ {
+ std::string log = "Cannot find memory tester output file: "
+ + this->MemoryTesterOutputFile;
+ cmCTestLog(this->CTest, ERROR_MESSAGE, log.c_str() << std::endl);
+ return;
+ }
+ std::ifstream ifs(this->MemoryTesterOutputFile.c_str());
+ if ( !ifs )
+ {
+ std::string log = "Cannot read memory tester output file: "
+ + this->MemoryTesterOutputFile;
+ cmCTestLog(this->CTest, ERROR_MESSAGE, log.c_str() << std::endl);
+ return;
+ }
+ std::string line;
+ while ( cmSystemTools::GetLineFromStream(ifs, line) )
+ {
+ res.Output += line;
+ res.Output += "\n";
+ }
+}
diff --git a/Source/CTest/cmCTestMemCheckHandler.h b/Source/CTest/cmCTestMemCheckHandler.h
new file mode 100644
index 000000000..427d4717d
--- /dev/null
+++ b/Source/CTest/cmCTestMemCheckHandler.h
@@ -0,0 +1,125 @@
+/*============================================================================
+ 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 cmCTestMemCheckHandler_h
+#define cmCTestMemCheckHandler_h
+
+
+#include "cmCTestTestHandler.h"
+#include "cmListFileCache.h"
+
+class cmMakefile;
+
+/** \class cmCTestMemCheckHandler
+ * \brief A class that handles ctest -S invocations
+ *
+ */
+class cmCTestMemCheckHandler : public cmCTestTestHandler
+{
+ friend class cmCTestRunTest;
+public:
+ cmTypeMacro(cmCTestMemCheckHandler, cmCTestTestHandler);
+
+ void PopulateCustomVectors(cmMakefile *mf);
+
+ cmCTestMemCheckHandler();
+
+ void Initialize();
+protected:
+ virtual int PreProcessHandler();
+ virtual int PostProcessHandler();
+ virtual void GenerateTestCommand(std::vector<std::string>& args);
+
+private:
+
+ enum { // Memory checkers
+ UNKNOWN = 0,
+ VALGRIND,
+ PURIFY,
+ BOUNDS_CHECKER
+ };
+public:
+ enum { // Memory faults
+ ABR = 0,
+ ABW,
+ ABWL,
+ COR,
+ EXU,
+ FFM,
+ FIM,
+ FMM,
+ FMR,
+ FMW,
+ FUM,
+ IPR,
+ IPW,
+ MAF,
+ MLK,
+ MPK,
+ NPR,
+ ODS,
+ PAR,
+ PLK,
+ UMC,
+ UMR,
+ NO_MEMORY_FAULT
+ };
+private:
+ enum { // Program statuses
+ NOT_RUN = 0,
+ TIMEOUT,
+ SEGFAULT,
+ ILLEGAL,
+ INTERRUPT,
+ NUMERICAL,
+ OTHER_FAULT,
+ FAILED,
+ BAD_COMMAND,
+ COMPLETED
+ };
+ std::string BoundsCheckerDPBDFile;
+ std::string BoundsCheckerXMLFile;
+ std::string MemoryTester;
+ std::vector<cmStdString> MemoryTesterOptions;
+ int MemoryTesterStyle;
+ std::string MemoryTesterOutputFile;
+ int MemoryTesterGlobalResults[NO_MEMORY_FAULT];
+
+ ///! Initialize memory checking subsystem.
+ bool InitializeMemoryChecking();
+
+ /**
+ * Generate the Dart compatible output
+ */
+ void GenerateDartOutput(std::ostream& os);
+
+ std::vector<cmStdString> CustomPreMemCheck;
+ std::vector<cmStdString> 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);
+ bool ProcessMemCheckValgrindOutput(const std::string& str,
+ std::string& log, int* results);
+ bool ProcessMemCheckPurifyOutput(const std::string& str,
+ std::string& log, int* results);
+ bool ProcessMemCheckBoundsCheckerOutput(const std::string& str,
+ std::string& log, int* results);
+
+ void PostProcessPurifyTest(cmCTestTestResult& res);
+ void PostProcessBoundsCheckerTest(cmCTestTestResult& res);
+};
+
+#endif
+
diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx
new file mode 100644
index 000000000..2cae80215
--- /dev/null
+++ b/Source/CTest/cmCTestMultiProcessHandler.cxx
@@ -0,0 +1,691 @@
+/*============================================================================
+ 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 "cmCTestMultiProcessHandler.h"
+#include "cmProcess.h"
+#include "cmStandardIncludes.h"
+#include "cmCTest.h"
+#include "cmSystemTools.h"
+#include <stdlib.h>
+#include <stack>
+#include <float.h>
+
+class TestComparator
+{
+public:
+ TestComparator(cmCTestMultiProcessHandler* handler) : Handler(handler) {}
+ ~TestComparator() {}
+
+ // Sorts tests in descending order of cost
+ bool operator() (int index1, int index2) const
+ {
+ return Handler->Properties[index1]->Cost >
+ Handler->Properties[index2]->Cost;
+ }
+
+private:
+ cmCTestMultiProcessHandler* Handler;
+};
+
+cmCTestMultiProcessHandler::cmCTestMultiProcessHandler()
+{
+ this->ParallelLevel = 1;
+ this->Completed = 0;
+ this->RunningCount = 0;
+ this->StopTimePassed = false;
+}
+
+cmCTestMultiProcessHandler::~cmCTestMultiProcessHandler()
+{
+}
+
+ // Set the tests
+void
+cmCTestMultiProcessHandler::SetTests(TestMap& tests,
+ PropertiesMap& properties)
+{
+ this->Tests = tests;
+ this->Properties = properties;
+ this->Total = this->Tests.size();
+ // set test run map to false for all
+ for(TestMap::iterator i = this->Tests.begin();
+ i != this->Tests.end(); ++i)
+ {
+ this->TestRunningMap[i->first] = false;
+ this->TestFinishMap[i->first] = false;
+ }
+ if(!this->CTest->GetShowOnly())
+ {
+ this->ReadCostData();
+ this->CreateTestCostList();
+ }
+}
+
+ // Set the max number of tests that can be run at the same time.
+void cmCTestMultiProcessHandler::SetParallelLevel(size_t level)
+{
+ this->ParallelLevel = level < 1 ? 1 : level;
+}
+
+//---------------------------------------------------------
+void cmCTestMultiProcessHandler::RunTests()
+{
+ this->CheckResume();
+ if(!this->CheckCycles())
+ {
+ return;
+ }
+ this->TestHandler->SetMaxIndex(this->FindMaxIndex());
+ this->StartNextTests();
+ while(this->Tests.size() != 0)
+ {
+ if(this->StopTimePassed)
+ {
+ return;
+ }
+ this->CheckOutput();
+ this->StartNextTests();
+ }
+ // let all running tests finish
+ while(this->CheckOutput())
+ {
+ }
+ this->MarkFinished();
+ this->UpdateCostData();
+}
+
+//---------------------------------------------------------
+void cmCTestMultiProcessHandler::StartTestProcess(int test)
+{
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "test " << test << "\n");
+ 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);
+ testRun->SetIndex(test);
+ testRun->SetTestProperties(this->Properties[test]);
+
+ std::string current_dir = cmSystemTools::GetCurrentWorkingDirectory();
+ cmSystemTools::ChangeDirectory(this->Properties[test]->Directory.c_str());
+
+ // Lock the resources we'll be using
+ this->LockResources(test);
+
+ if(testRun->StartTest(this->Total))
+ {
+ this->RunningTests.insert(testRun);
+ }
+ else if(testRun->IsStopTimePassed())
+ {
+ this->StopTimePassed = true;
+ delete testRun;
+ return;
+ }
+ else
+ {
+ this->UnlockResources(test);
+ this->Completed++;
+ this->TestFinishMap[test] = true;
+ this->TestRunningMap[test] = false;
+ this->RunningCount -= GetProcessorsUsed(test);
+ testRun->EndTest(this->Completed, this->Total, false);
+ this->Failed->push_back(this->Properties[test]->Name);
+ delete testRun;
+ }
+ cmSystemTools::ChangeDirectory(current_dir.c_str());
+}
+
+//---------------------------------------------------------
+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(*i);
+ }
+}
+
+//---------------------------------------------------------
+void cmCTestMultiProcessHandler::UnlockResources(int index)
+{
+ for(std::set<std::string>::iterator i =
+ this->Properties[index]->LockedResources.begin();
+ i != this->Properties[index]->LockedResources.end(); ++i)
+ {
+ this->LockedResources.erase(*i);
+ }
+}
+
+//---------------------------------------------------------
+void cmCTestMultiProcessHandler::EraseTest(int test)
+{
+ this->Tests.erase(test);
+ this->SortedTests.erase(
+ std::find(this->SortedTests.begin(), this->SortedTests.end(), test));
+}
+
+//---------------------------------------------------------
+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
+ //setting, we default to using all of the process slots.
+ if(this->Properties[test]->RunSerial
+ || processors > this->ParallelLevel)
+ {
+ processors = this->ParallelLevel;
+ }
+ return processors;
+}
+
+//---------------------------------------------------------
+bool cmCTestMultiProcessHandler::StartTest(int test)
+{
+ //Check for locked resources
+ for(std::set<std::string>::iterator i =
+ this->Properties[test]->LockedResources.begin();
+ i != this->Properties[test]->LockedResources.end(); ++i)
+ {
+ if(this->LockedResources.find(*i) != this->LockedResources.end())
+ {
+ return false;
+ }
+ }
+
+ // 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)
+ {
+ this->StartTestProcess(test);
+ return true;
+ }
+ // This test was not able to start because it is waiting
+ // on depends to run
+ return false;
+}
+
+//---------------------------------------------------------
+void cmCTestMultiProcessHandler::StartNextTests()
+{
+ size_t numToStart = this->ParallelLevel - this->RunningCount;
+ if(numToStart == 0)
+ {
+ return;
+ }
+
+ 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])
+ {
+ continue;
+ }
+ size_t processors = GetProcessorsUsed(*test);
+ if(processors > numToStart)
+ {
+ return;
+ }
+ if(this->StartTest(*test))
+ {
+ if(this->StopTimePassed)
+ {
+ return;
+ }
+ numToStart -= processors;
+ }
+ if(numToStart == 0)
+ {
+ return;
+ }
+ }
+}
+
+//---------------------------------------------------------
+bool cmCTestMultiProcessHandler::CheckOutput()
+{
+ // no more output we are done
+ if(this->RunningTests.size() == 0)
+ {
+ return false;
+ }
+ std::vector<cmCTestRunTest*> finished;
+ std::string out, err;
+ for(std::set<cmCTestRunTest*>::const_iterator i = this->RunningTests.begin();
+ i != this->RunningTests.end(); ++i)
+ {
+ cmCTestRunTest* p = *i;
+ if(!p->CheckOutput())
+ {
+ finished.push_back(p);
+ }
+ }
+ for( std::vector<cmCTestRunTest*>::iterator i = finished.begin();
+ i != finished.end(); ++i)
+ {
+ this->Completed++;
+ cmCTestRunTest* p = *i;
+ int test = p->GetIndex();
+
+ if(p->EndTest(this->Completed, this->Total, true))
+ {
+ this->Passed->push_back(p->GetTestProperties()->Name);
+ }
+ else
+ {
+ this->Failed->push_back(p->GetTestProperties()->Name);
+ }
+ for(TestMap::iterator j = this->Tests.begin();
+ j != this->Tests.end(); ++j)
+ {
+ j->second.erase(test);
+ }
+ this->TestFinishMap[test] = true;
+ this->TestRunningMap[test] = false;
+ this->RunningTests.erase(p);
+ this->WriteCheckpoint(test);
+ this->UnlockResources(test);
+ this->RunningCount -= GetProcessorsUsed(test);
+ delete p;
+ }
+ return true;
+}
+
+//---------------------------------------------------------
+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);
+
+ PropertiesMap temp = this->Properties;
+
+ if(cmSystemTools::FileExists(fname.c_str()))
+ {
+ std::ifstream fin;
+ fin.open(fname.c_str());
+
+ std::string line;
+ while(std::getline(fin, line))
+ {
+ if(line == "---") break;
+ std::vector<cmsys::String> parts =
+ cmSystemTools::SplitString(line.c_str(), ' ');
+ //Format: <name> <previous_runs> <avg_cost>
+ if(parts.size() < 3) break;
+
+ std::string name = parts[0];
+ int prev = atoi(parts[1].c_str());
+ float cost = static_cast<float>(atof(parts[2].c_str()));
+
+ int index = this->SearchByName(name);
+ if(index == -1)
+ {
+ // This test is not in memory. We just rewrite the entry
+ fout << name << " " << prev << " " << cost << "\n";
+ }
+ else
+ {
+ // Update with our new average cost
+ fout << name << " " << this->Properties[index]->PreviousRuns << " "
+ << this->Properties[index]->Cost << "\n";
+ temp.erase(index);
+ }
+ }
+ fin.close();
+ cmSystemTools::RemoveFile(fname.c_str());
+ }
+
+ // Add all tests not previously listed in the file
+ for(PropertiesMap::iterator i = temp.begin(); i != temp.end(); ++i)
+ {
+ fout << i->second->Name << " " << i->second->PreviousRuns << " "
+ << i->second->Cost << "\n";
+ }
+
+ // Write list of failed tests
+ fout << "---\n";
+ for(std::vector<cmStdString>::iterator i = this->Failed->begin();
+ i != this->Failed->end(); ++i)
+ {
+ fout << i->c_str() << "\n";
+ }
+ fout.close();
+ cmSystemTools::RenameFile(tmpout.c_str(), fname.c_str());
+}
+
+//---------------------------------------------------------
+void cmCTestMultiProcessHandler::ReadCostData()
+{
+ std::string fname = this->CTest->GetCostDataFile();
+
+ if(cmSystemTools::FileExists(fname.c_str(), true))
+ {
+ std::ifstream fin;
+ fin.open(fname.c_str());
+ std::string line;
+ while(std::getline(fin, line))
+ {
+ if(line == "---") break;
+
+ std::vector<cmsys::String> parts =
+ cmSystemTools::SplitString(line.c_str(), ' ');
+
+ // Probably an older version of the file, will be fixed next run
+ if(parts.size() < 3)
+ {
+ fin.close();
+ return;
+ }
+
+ std::string name = parts[0];
+ int prev = atoi(parts[1].c_str());
+ float cost = static_cast<float>(atof(parts[2].c_str()));
+
+ int index = this->SearchByName(name);
+ if(index == -1) continue;
+
+ this->Properties[index]->PreviousRuns = prev;
+ // When not running in parallel mode, don't use cost data
+ if(this->ParallelLevel > 1 &&
+ this->Properties[index] &&
+ this->Properties[index]->Cost == 0)
+ {
+ this->Properties[index]->Cost = cost;
+ }
+ }
+ // Next part of the file is the failed tests
+ while(std::getline(fin, line))
+ {
+ if(line != "")
+ {
+ this->LastTestsFailed.push_back(line);
+ }
+ }
+ fin.close();
+ }
+}
+
+//---------------------------------------------------------
+int cmCTestMultiProcessHandler::SearchByName(std::string name)
+{
+ int index = -1;
+
+ for(PropertiesMap::iterator i = this->Properties.begin();
+ i != this->Properties.end(); ++i)
+ {
+ if(i->second->Name == name)
+ {
+ index = i->first;
+ }
+ }
+ return index;
+}
+
+//---------------------------------------------------------
+void cmCTestMultiProcessHandler::CreateTestCostList()
+{
+ for(TestMap::iterator i = this->Tests.begin();
+ i != this->Tests.end(); ++i)
+ {
+ SortedTests.push_back(i->first);
+
+ //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(),
+ this->Properties[i->first]->Name) != this->LastTestsFailed.end())
+ {
+ this->Properties[i->first]->Cost = FLT_MAX;
+ }
+ }
+
+ TestComparator comp(this);
+ std::stable_sort(SortedTests.begin(), SortedTests.end(), comp);
+}
+
+//---------------------------------------------------------
+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);
+ fout << index << "\n";
+ fout.close();
+}
+
+//---------------------------------------------------------
+void cmCTestMultiProcessHandler::MarkFinished()
+{
+ std::string fname = this->CTest->GetBinaryDir()
+ + "/Testing/Temporary/CTestCheckpoint.txt";
+ cmSystemTools::RemoveFile(fname.c_str());
+}
+
+//---------------------------------------------------------
+//For ShowOnly mode
+void cmCTestMultiProcessHandler::PrintTestList()
+{
+ this->TestHandler->SetMaxIndex(this->FindMaxIndex());
+ int count = 0;
+
+ for (PropertiesMap::iterator it = this->Properties.begin();
+ it != this->Properties.end(); ++it)
+ {
+ count++;
+ cmCTestTestHandler::cmCTestTestProperties& p = *it->second;
+
+ //push working dir
+ std::string current_dir = cmSystemTools::GetCurrentWorkingDirectory();
+ cmSystemTools::ChangeDirectory(p.Directory.c_str());
+
+ 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
+ {
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Labels:");
+ }
+ for(std::vector<std::string>::iterator label = p.Labels.begin();
+ label != p.Labels.end(); ++label)
+ {
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " " << *label);
+ }
+ if(p.Labels.size()) //print the labels
+ {
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, std::endl);
+ }
+
+ if (this->TestHandler->MemCheck)
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " Memory Check");
+ }
+ else
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " Test");
+ }
+ cmOStringStream indexStr;
+ indexStr << " #" << p.Index << ":";
+ cmCTestLog(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);
+ //pop working dir
+ cmSystemTools::ChangeDirectory(current_dir.c_str());
+ }
+
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, std::endl << "Total Tests: "
+ << this->Total << std::endl);
+}
+
+void cmCTestMultiProcessHandler::PrintLabels()
+{
+ std::set<std::string> allLabels;
+ for (PropertiesMap::iterator it = this->Properties.begin();
+ it != this->Properties.end(); ++it)
+ {
+ cmCTestTestHandler::cmCTestTestProperties& p = *it->second;
+ allLabels.insert(p.Labels.begin(), p.Labels.end());
+ }
+
+ if(allLabels.size())
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, "All Labels:" << std::endl);
+ }
+ else
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, "No Labels Exist" << std::endl);
+ }
+ for(std::set<std::string>::iterator label = allLabels.begin();
+ label != allLabels.end(); ++label)
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " " << *label << std::endl);
+ }
+}
+
+//---------------------------------------------------------
+void cmCTestMultiProcessHandler::CheckResume()
+{
+ std::string fname = this->CTest->GetBinaryDir()
+ + "/Testing/Temporary/CTestCheckpoint.txt";
+ if(this->CTest->GetFailover())
+ {
+ if(cmSystemTools::FileExists(fname.c_str(), true))
+ {
+ *this->TestHandler->LogFile << "Resuming previously interrupted test set"
+ << std::endl
+ << "----------------------------------------------------------"
+ << std::endl;
+
+ std::ifstream fin;
+ fin.open(fname.c_str());
+ std::string line;
+ while(std::getline(fin, line))
+ {
+ int index = atoi(line.c_str());
+ this->RemoveTest(index);
+ }
+ fin.close();
+ }
+ }
+ else if(cmSystemTools::FileExists(fname.c_str(), true))
+ {
+ cmSystemTools::RemoveFile(fname.c_str());
+ }
+}
+
+//---------------------------------------------------------
+void cmCTestMultiProcessHandler::RemoveTest(int index)
+{
+ this->EraseTest(index);
+ this->Properties.erase(index);
+ this->TestRunningMap[index] = false;
+ this->TestFinishMap[index] = true;
+ this->Completed++;
+}
+
+//---------------------------------------------------------
+int cmCTestMultiProcessHandler::FindMaxIndex()
+{
+ int max = 0;
+ cmCTestMultiProcessHandler::TestMap::iterator i = this->Tests.begin();
+ for(; i != this->Tests.end(); ++i)
+ {
+ if(i->first > max)
+ {
+ max = i->first;
+ }
+ }
+ return max;
+}
+
+//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);
+ for(TestMap::iterator it = this->Tests.begin();
+ it != this->Tests.end(); ++it)
+ {
+ //DFS from each element to itself
+ int root = it->first;
+ std::set<int> visited;
+ std::stack<int> s;
+ s.push(root);
+ while(!s.empty())
+ {
+ int test = s.top();
+ s.pop();
+ if(visited.insert(test).second)
+ {
+ for(TestSet::iterator d = this->Tests[test].begin();
+ d != this->Tests[test].end(); ++d)
+ {
+ if(*d == root)
+ {
+ //cycle exists
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Error: a cycle exists in the test dependency graph "
+ "for the test \"" << this->Properties[root]->Name <<
+ "\".\nPlease fix the cycle and run ctest again.\n");
+ return false;
+ }
+ else
+ {
+ s.push(*d);
+ }
+ }
+ }
+ }
+ }
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Checking test dependency graph end" << std::endl);
+ return true;
+}
diff --git a/Source/CTest/cmCTestMultiProcessHandler.h b/Source/CTest/cmCTestMultiProcessHandler.h
new file mode 100644
index 000000000..1483440c6
--- /dev/null
+++ b/Source/CTest/cmCTestMultiProcessHandler.h
@@ -0,0 +1,116 @@
+/*============================================================================
+ 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 cmCTestMultiProcessHandler_h
+#define cmCTestMultiProcessHandler_h
+
+#include <cmStandardIncludes.h>
+#include <cmCTestTestHandler.h>
+#include <cmCTestRunTest.h>
+
+/** \class cmCTestMultiProcessHandler
+ * \brief run parallel ctest
+ *
+ * cmCTestMultiProcessHandler
+ */
+class cmCTestMultiProcessHandler
+{
+ friend class TestComparator;
+public:
+ struct TestSet : public std::set<int> {};
+ struct TestMap : public std::map<int, TestSet> {};
+ struct TestList : public std::vector<int> {};
+ struct PropertiesMap : public
+ std::map<int, cmCTestTestHandler::cmCTestTestProperties*> {};
+
+ cmCTestMultiProcessHandler();
+ virtual ~cmCTestMultiProcessHandler();
+ // Set the tests
+ void SetTests(TestMap& tests, PropertiesMap& properties);
+ // Set the max number of tests that can be run at the same time.
+ void SetParallelLevel(size_t);
+ virtual void RunTests();
+ void PrintTestList();
+ void PrintLabels();
+
+ void SetPassFailVectors(std::vector<cmStdString>* passed,
+ std::vector<cmStdString>* failed)
+ {
+ this->Passed = passed;
+ this->Failed = failed;
+ }
+ void SetTestResults(std::vector<cmCTestTestHandler::cmCTestTestResult>* r)
+ { this->TestResults = r; }
+
+ void SetCTest(cmCTest* ctest) { this->CTest = ctest;}
+
+ void SetTestHandler(cmCTestTestHandler * handler)
+ { this->TestHandler = handler; }
+
+ cmCTestTestHandler * GetTestHandler()
+ { return this->TestHandler; }
+protected:
+ // Start the next test or tests as many as are allowed by
+ // ParallelLevel
+ void StartNextTests();
+ void StartTestProcess(int test);
+ bool StartTest(int test);
+ // Mark the checkpoint for the given test
+ void WriteCheckpoint(int index);
+
+ void UpdateCostData();
+ void ReadCostData();
+ // Return index of a test based on its name
+ int SearchByName(std::string name);
+
+ void CreateTestCostList();
+ // Removes the checkpoint file
+ void MarkFinished();
+ void EraseTest(int index);
+ // Return true if there are still tests running
+ // check all running processes for output and exit case
+ bool CheckOutput();
+ void RemoveTest(int index);
+ //Check if we need to resume an interrupted test set
+ void CheckResume();
+ //Check if there are any circular dependencies
+ bool CheckCycles();
+ int FindMaxIndex();
+ inline size_t GetProcessorsUsed(int index);
+
+ void LockResources(int index);
+ void UnlockResources(int index);
+ // map from test number to set of depend tests
+ TestMap Tests;
+ TestList SortedTests;
+ //Total number of tests we'll be running
+ size_t Total;
+ //Number of tests that are complete
+ size_t Completed;
+ size_t RunningCount;
+ bool StopTimePassed;
+ //list of test properties (indices concurrent to the test map)
+ 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::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
+ std::set<cmCTestRunTest*> RunningTests; // current running tests
+ cmCTestTestHandler * TestHandler;
+ cmCTest* CTest;
+};
+
+#endif
diff --git a/Source/CTest/cmCTestReadCustomFilesCommand.cxx b/Source/CTest/cmCTestReadCustomFilesCommand.cxx
new file mode 100644
index 000000000..5db01f98d
--- /dev/null
+++ b/Source/CTest/cmCTestReadCustomFilesCommand.cxx
@@ -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.
+============================================================================*/
+#include "cmCTestReadCustomFilesCommand.h"
+
+#include "cmCTest.h"
+
+bool cmCTestReadCustomFilesCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if (args.size() < 1)
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ std::vector<std::string>::const_iterator dit;
+ for ( dit = args.begin(); dit != args.end(); ++ dit )
+ {
+ this->CTest->ReadCustomConfigurationFileTree(dit->c_str(),
+ this->Makefile);
+ }
+
+ return true;
+}
+
+
diff --git a/Source/CTest/cmCTestReadCustomFilesCommand.h b/Source/CTest/cmCTestReadCustomFilesCommand.h
new file mode 100644
index 000000000..f382b0f2d
--- /dev/null
+++ b/Source/CTest/cmCTestReadCustomFilesCommand.h
@@ -0,0 +1,75 @@
+/*============================================================================
+ 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 cmCTestReadCustomFilesCommand_h
+#define cmCTestReadCustomFilesCommand_h
+
+#include "cmCTestCommand.h"
+
+/** \class cmCTestReadCustomFiles
+ * \brief Run a ctest script
+ *
+ * cmLibrarysCommand defines a list of executable (i.e., test)
+ * programs to create.
+ */
+class cmCTestReadCustomFilesCommand : public cmCTestCommand
+{
+public:
+
+ cmCTestReadCustomFilesCommand() {}
+
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ cmCTestReadCustomFilesCommand* ni = new cmCTestReadCustomFilesCommand;
+ ni->CTest = this->CTest;
+ return ni;
+ }
+
+ /**
+ * 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 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.";
+ }
+
+ cmTypeMacro(cmCTestReadCustomFilesCommand, cmCTestCommand);
+
+};
+
+
+#endif
diff --git a/Source/CTest/cmCTestRunScriptCommand.cxx b/Source/CTest/cmCTestRunScriptCommand.cxx
new file mode 100644
index 000000000..fe429bd9d
--- /dev/null
+++ b/Source/CTest/cmCTestRunScriptCommand.cxx
@@ -0,0 +1,65 @@
+/*============================================================================
+ 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 "cmCTestRunScriptCommand.h"
+
+#include "cmCTestScriptHandler.h"
+
+bool cmCTestRunScriptCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 1 )
+ {
+ this->CTestScriptHandler->RunCurrentScript();
+ return true;
+ }
+
+ bool np = false;
+ unsigned int i = 0;
+ if (args[i] == "NEW_PROCESS")
+ {
+ np = true;
+ i++;
+ }
+ int start = i;
+ // run each script
+ std::string returnVariable;
+ for (i = start; i < args.size(); ++i)
+ {
+ if(args[i] == "RETURN_VALUE")
+ {
+ ++i;
+ if(i < args.size())
+ {
+ returnVariable = args[i];
+ }
+ }
+ }
+ for (i = start; i < args.size(); ++i)
+ {
+ if(args[i] == "RETURN_VALUE")
+ {
+ ++i;
+ }
+ else
+ {
+ int ret;
+ cmCTestScriptHandler::RunScript(this->CTest, args[i].c_str(), !np,
+ &ret);
+ cmOStringStream str;
+ str << ret;
+ this->Makefile->AddDefinition(returnVariable.c_str(), str.str().c_str());
+ }
+ }
+ return true;
+}
+
+
diff --git a/Source/CTest/cmCTestRunScriptCommand.h b/Source/CTest/cmCTestRunScriptCommand.h
new file mode 100644
index 000000000..6df69afa6
--- /dev/null
+++ b/Source/CTest/cmCTestRunScriptCommand.h
@@ -0,0 +1,80 @@
+/*============================================================================
+ 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 cmCTestRunScriptCommand_h
+#define cmCTestRunScriptCommand_h
+
+#include "cmCTestCommand.h"
+
+/** \class cmCTestRunScript
+ * \brief Run a ctest script
+ *
+ * cmLibrarysCommand defines a list of executable (i.e., test)
+ * programs to create.
+ */
+class cmCTestRunScriptCommand : public cmCTestCommand
+{
+public:
+
+ cmCTestRunScriptCommand() {}
+
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ cmCTestRunScriptCommand* ni = new cmCTestRunScriptCommand;
+ ni->CTest = this->CTest;
+ ni->CTestScriptHandler = this->CTestScriptHandler;
+ return ni;
+ }
+
+ /**
+ * 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 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.";
+ }
+
+ cmTypeMacro(cmCTestRunScriptCommand, cmCTestCommand);
+};
+
+
+#endif
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx
new file mode 100644
index 000000000..c3de5dcf6
--- /dev/null
+++ b/Source/CTest/cmCTestRunTest.cxx
@@ -0,0 +1,735 @@
+/*============================================================================
+ 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 "cmCTestRunTest.h"
+#include "cmCTestMemCheckHandler.h"
+#include "cmCTest.h"
+#include "cmSystemTools.h"
+#include "cm_curl.h"
+
+#include <cm_zlib.h>
+#include <cmsys/Base64.h>
+
+cmCTestRunTest::cmCTestRunTest(cmCTestTestHandler* handler)
+{
+ this->CTest = handler->CTest;
+ this->TestHandler = handler;
+ this->TestProcess = 0;
+ this->TestResult.ExecutionTime =0;
+ this->TestResult.ReturnValue = 0;
+ this->TestResult.Status = cmCTestTestHandler::NOT_RUN;
+ this->TestResult.TestCount = 0;
+ this->TestResult.Properties = 0;
+ this->ProcessOutput = "";
+ this->CompressedOutput = "";
+ this->CompressionRatio = 2;
+ this->StopTimePassed = false;
+}
+
+cmCTestRunTest::~cmCTestRunTest()
+{
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestRunTest::CheckOutput()
+{
+ // Read lines for up to 0.1 seconds of total time.
+ double timeout = 0.1;
+ double timeEnd = cmSystemTools::GetTime() + timeout;
+ std::string line;
+ while((timeout = timeEnd - cmSystemTools::GetTime(), timeout > 0))
+ {
+ int p = this->TestProcess->GetNextOutputLine(line, timeout);
+ if(p == cmsysProcess_Pipe_None)
+ {
+ // Process has terminated and all output read.
+ return false;
+ }
+ else if(p == cmsysProcess_Pipe_STDOUT ||
+ p == cmsysProcess_Pipe_STDERR)
+ {
+ // Store this line of output.
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ this->GetIndex() << ": " << line << std::endl);
+ this->ProcessOutput += line;
+ this->ProcessOutput += "\n";
+ }
+ else // if(p == cmsysProcess_Pipe_Timeout)
+ {
+ break;
+ }
+ }
+ return true;
+}
+
+//---------------------------------------------------------
+// Streamed compression of test output. The compressed data
+// is appended to this->CompressedOutput
+void cmCTestRunTest::CompressOutput()
+{
+ int ret;
+ z_stream strm;
+
+ unsigned char* in =
+ reinterpret_cast<unsigned char*>(
+ const_cast<char*>(this->ProcessOutput.c_str()));
+ //zlib makes the guarantee that this is the maximum output size
+ int outSize = static_cast<int>(
+ static_cast<double>(this->ProcessOutput.size()) * 1.001 + 13.0);
+ unsigned char* out = new unsigned char[outSize];
+
+ strm.zalloc = Z_NULL;
+ strm.zfree = Z_NULL;
+ strm.opaque = Z_NULL;
+ ret = deflateInit(&strm, -1); //default compression level
+ if (ret != Z_OK)
+ {
+ delete[] out;
+ return;
+ }
+
+ strm.avail_in = static_cast<uInt>(this->ProcessOutput.size());
+ strm.next_in = in;
+ strm.avail_out = outSize;
+ strm.next_out = out;
+ ret = deflate(&strm, Z_FINISH);
+
+ if(ret == Z_STREAM_ERROR || ret != Z_STREAM_END)
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Error during output "
+ "compression. Sending uncompressed output." << std::endl);
+ delete[] out;
+ return;
+ }
+
+ (void)deflateEnd(&strm);
+
+ unsigned char *encoded_buffer
+ = new unsigned char[static_cast<int>(outSize * 1.5)];
+
+ unsigned long rlen
+ = cmsysBase64_Encode(out, strm.total_out, encoded_buffer, 1);
+
+ for(unsigned long i = 0; i < rlen; i++)
+ {
+ this->CompressedOutput += encoded_buffer[i];
+ }
+
+ if(strm.total_in)
+ {
+ this->CompressionRatio = static_cast<double>(strm.total_out) /
+ static_cast<double>(strm.total_in);
+ }
+
+ delete [] encoded_buffer;
+ delete [] out;
+}
+
+//---------------------------------------------------------
+bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started)
+{
+ if ((!this->TestHandler->MemCheck &&
+ this->CTest->ShouldCompressTestOutput()) ||
+ (this->TestHandler->MemCheck &&
+ this->CTest->ShouldCompressMemCheckOutput()))
+ {
+ this->CompressOutput();
+ }
+
+ this->WriteLogOutputTop(completed, total);
+ std::string reason;
+ bool passed = true;
+ int res = started ? this->TestProcess->GetProcessStatus()
+ : cmsysProcess_State_Error;
+ int retVal = this->TestProcess->GetExitValue();
+ std::vector<std::pair<cmsys::RegularExpression,
+ std::string> >::iterator passIt;
+ bool forceFail = false;
+ bool outputTestErrorsToConsole = false;
+ if ( this->TestProperties->RequiredRegularExpressions.size() > 0 )
+ {
+ bool found = false;
+ for ( passIt = this->TestProperties->RequiredRegularExpressions.begin();
+ passIt != this->TestProperties->RequiredRegularExpressions.end();
+ ++ passIt )
+ {
+ if ( passIt->first.find(this->ProcessOutput.c_str()) )
+ {
+ found = true;
+ reason = "Required regular expression found.";
+ }
+ }
+ if ( !found )
+ {
+ reason = "Required regular expression not found.";
+ forceFail = true;
+ }
+ reason += "Regex=[";
+ for ( passIt = this->TestProperties->RequiredRegularExpressions.begin();
+ passIt != this->TestProperties->RequiredRegularExpressions.end();
+ ++ passIt )
+ {
+ reason += passIt->second;
+ reason += "\n";
+ }
+ reason += "]";
+ }
+ if ( this->TestProperties->ErrorRegularExpressions.size() > 0 )
+ {
+ for ( passIt = this->TestProperties->ErrorRegularExpressions.begin();
+ passIt != this->TestProperties->ErrorRegularExpressions.end();
+ ++ passIt )
+ {
+ if ( passIt->first.find(this->ProcessOutput.c_str()) )
+ {
+ reason = "Error regular expression found in output.";
+ reason += " Regex=[";
+ reason += passIt->second;
+ reason += "]";
+ forceFail = true;
+ }
+ }
+ }
+ if (res == cmsysProcess_State_Exited)
+ {
+ bool success =
+ !forceFail && (retVal == 0 ||
+ this->TestProperties->RequiredRegularExpressions.size());
+ if((success && !this->TestProperties->WillFail)
+ || (!success && this->TestProperties->WillFail))
+ {
+ this->TestResult.Status = cmCTestTestHandler::COMPLETED;
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " Passed " );
+ }
+ else
+ {
+ this->TestResult.Status = cmCTestTestHandler::FAILED;
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, "***Failed " << reason );
+ outputTestErrorsToConsole = this->CTest->OutputTestOutputOnTestFailure;
+ }
+ }
+ else if ( res == cmsysProcess_State_Expired )
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, "***Timeout ");
+ this->TestResult.Status = cmCTestTestHandler::TIMEOUT;
+ outputTestErrorsToConsole = this->CTest->OutputTestOutputOnTestFailure;
+ }
+ else if ( res == cmsysProcess_State_Exception )
+ {
+ outputTestErrorsToConsole = this->CTest->OutputTestOutputOnTestFailure;
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, "***Exception: ");
+ switch(this->TestProcess->GetExitException())
+ {
+ case cmsysProcess_Exception_Fault:
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, "SegFault");
+ this->TestResult.Status = cmCTestTestHandler::SEGFAULT;
+ break;
+ case cmsysProcess_Exception_Illegal:
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, "Illegal");
+ this->TestResult.Status = cmCTestTestHandler::ILLEGAL;
+ break;
+ case cmsysProcess_Exception_Interrupt:
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, "Interrupt");
+ this->TestResult.Status = cmCTestTestHandler::INTERRUPT;
+ break;
+ case cmsysProcess_Exception_Numerical:
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, "Numerical");
+ this->TestResult.Status = cmCTestTestHandler::NUMERICAL;
+ break;
+ default:
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, "Other");
+ this->TestResult.Status = cmCTestTestHandler::OTHER_FAULT;
+ }
+ }
+ else //cmsysProcess_State_Error
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, "***Not Run ");
+ }
+
+ passed = this->TestResult.Status == cmCTestTestHandler::COMPLETED;
+ char buf[1024];
+ sprintf(buf, "%6.2f sec", this->TestProcess->GetTotalTime());
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, buf << "\n" );
+
+ if ( outputTestErrorsToConsole )
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, this->ProcessOutput << std::endl );
+ }
+
+ if ( this->TestHandler->LogFile )
+ {
+ *this->TestHandler->LogFile << "Test time = " << buf << std::endl;
+ }
+
+ // Set the working directory to the tests directory
+ std::string oldpath = cmSystemTools::GetCurrentWorkingDirectory();
+ cmSystemTools::ChangeDirectory(this->TestProperties->Directory.c_str());
+
+ this->DartProcessing();
+
+ // restore working directory
+ cmSystemTools::ChangeDirectory(oldpath.c_str());
+
+
+ // if this is doing MemCheck then all the output needs to be put into
+ // Output since that is what is parsed by cmCTestMemCheckHandler
+ if(!this->TestHandler->MemCheck && started)
+ {
+ this->TestHandler->CleanTestOutput(this->ProcessOutput,
+ static_cast<size_t>
+ (this->TestResult.Status == cmCTestTestHandler::COMPLETED ?
+ this->TestHandler->CustomMaximumPassedTestOutputSize :
+ this->TestHandler->CustomMaximumFailedTestOutputSize));
+ }
+ this->TestResult.Reason = reason;
+ if (this->TestHandler->LogFile)
+ {
+ bool pass = true;
+ const char* reasonType = "Test Pass Reason";
+ if(this->TestResult.Status != cmCTestTestHandler::COMPLETED &&
+ this->TestResult.Status != cmCTestTestHandler::NOT_RUN)
+ {
+ reasonType = "Test Fail Reason";
+ pass = false;
+ }
+ double ttime = this->TestProcess->GetTotalTime();
+ int hours = static_cast<int>(ttime / (60 * 60));
+ int minutes = static_cast<int>(ttime / 60) % 60;
+ int seconds = static_cast<int>(ttime) % 60;
+ char buffer[100];
+ sprintf(buffer, "%02d:%02d:%02d", hours, minutes, seconds);
+ *this->TestHandler->LogFile
+ << "----------------------------------------------------------"
+ << std::endl;
+ if(this->TestResult.Reason.size())
+ {
+ *this->TestHandler->LogFile << reasonType << ":\n"
+ << this->TestResult.Reason << "\n";
+ }
+ else
+ {
+ if(pass)
+ {
+ *this->TestHandler->LogFile << "Test Passed.\n";
+ }
+ else
+ {
+ *this->TestHandler->LogFile << "Test Failed.\n";
+ }
+ }
+ *this->TestHandler->LogFile << "\"" << this->TestProperties->Name.c_str()
+ << "\" end time: " << this->CTest->CurrentTime() << std::endl
+ << "\"" << this->TestProperties->Name.c_str() << "\" time elapsed: "
+ << buffer << std::endl
+ << "----------------------------------------------------------"
+ << std::endl << std::endl;
+ }
+ // if the test actually started and ran
+ // record the results in TestResult
+ if(started)
+ {
+ bool compress = !this->TestHandler->MemCheck &&
+ this->CompressionRatio < 1 &&
+ this->CTest->ShouldCompressTestOutput();
+ this->TestResult.Output = compress ? this->CompressedOutput
+ : this->ProcessOutput;
+ this->TestResult.CompressOutput = compress;
+ this->TestResult.ReturnValue = this->TestProcess->GetExitValue();
+ this->TestResult.CompletionStatus = "Completed";
+ this->TestResult.ExecutionTime = this->TestProcess->GetTotalTime();
+ this->MemCheckPostProcess();
+ this->ComputeWeightedCost();
+ }
+ // Always push the current TestResult onto the
+ // TestHandler vector
+ this->TestHandler->TestResults.push_back(this->TestResult);
+ delete this->TestProcess;
+ return passed;
+}
+
+//----------------------------------------------------------------------
+void cmCTestRunTest::ComputeWeightedCost()
+{
+ double prev = static_cast<double>(this->TestProperties->PreviousRuns);
+ double avgcost = static_cast<double>(this->TestProperties->Cost);
+ double current = this->TestResult.ExecutionTime;
+
+ if(this->TestResult.Status == cmCTestTestHandler::COMPLETED)
+ {
+ this->TestProperties->Cost =
+ static_cast<float>(((prev * avgcost) + current) / (prev + 1.0));
+ this->TestProperties->PreviousRuns++;
+ }
+}
+
+//----------------------------------------------------------------------
+void cmCTestRunTest::MemCheckPostProcess()
+{
+ if(!this->TestHandler->MemCheck)
+ {
+ 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);
+ cmCTestMemCheckHandler * handler = static_cast<cmCTestMemCheckHandler*>
+ (this->TestHandler);
+ if(handler->MemoryTesterStyle == cmCTestMemCheckHandler::BOUNDS_CHECKER)
+ {
+ handler->PostProcessBoundsCheckerTest(this->TestResult);
+ }
+ else if(handler->MemoryTesterStyle == cmCTestMemCheckHandler::PURIFY)
+ {
+ handler->PostProcessPurifyTest(this->TestResult);
+ }
+}
+
+//----------------------------------------------------------------------
+// Starts the execution of a test. Returns once it has started
+bool cmCTestRunTest::StartTest(size_t total)
+{
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, std::setw(2*getNumWidth(total) + 8)
+ << "Start "
+ << std::setw(getNumWidth(this->TestHandler->GetMaxIndex()))
+ << this->TestProperties->Index << ": "
+ << this->TestProperties->Name << std::endl);
+ this->ComputeArguments();
+ std::vector<std::string>& args = this->TestProperties->Args;
+ this->TestResult.Properties = this->TestProperties;
+ this->TestResult.ExecutionTime = 0;
+ this->TestResult.CompressOutput = false;
+ this->TestResult.ReturnValue = -1;
+ this->TestResult.CompletionStatus = "Failed to start";
+ this->TestResult.Status = cmCTestTestHandler::BAD_COMMAND;
+ this->TestResult.TestCount = this->TestProperties->Index;
+ this->TestResult.Name = this->TestProperties->Name;
+ this->TestResult.Path = this->TestProperties->Directory.c_str();
+
+ if(args.size() >= 2 && args[1] == "NOT_AVAILABLE")
+ {
+ this->TestProcess = new cmProcess;
+ std::string msg;
+ if(this->CTest->GetConfigType().empty())
+ {
+ msg = "Test not available without configuration.";
+ msg += " (Missing \"-C <config>\"?)";
+ }
+ else
+ {
+ msg = "Test not available in configuration \"";
+ msg += this->CTest->GetConfigType();
+ msg += "\".";
+ }
+ *this->TestHandler->LogFile << msg << std::endl;
+ cmCTestLog(this->CTest, ERROR_MESSAGE, msg << std::endl);
+ this->TestResult.Output = msg;
+ this->TestResult.FullCommandLine = "";
+ this->TestResult.CompletionStatus = "Not Run";
+ this->TestResult.Status = cmCTestTestHandler::NOT_RUN;
+ return false;
+ }
+
+ // Check if all required files exist
+ for(std::vector<std::string>::iterator i =
+ this->TestProperties->RequiredFiles.begin();
+ i != this->TestProperties->RequiredFiles.end(); ++i)
+ {
+ std::string file = *i;
+
+ if(!cmSystemTools::FileExists(file.c_str()))
+ {
+ //Required file was not found
+ this->TestProcess = new cmProcess;
+ *this->TestHandler->LogFile << "Unable to find required file: "
+ << file.c_str() << std::endl;
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Unable to find required file: "
+ << file.c_str() << std::endl);
+ this->TestResult.Output = "Unable to find required file: " + file;
+ this->TestResult.FullCommandLine = "";
+ this->TestResult.CompletionStatus = "Not Run";
+ this->TestResult.Status = cmCTestTestHandler::NOT_RUN;
+ return false;
+ }
+ }
+ // log and return if we did not find the executable
+ if (this->ActualCommand == "")
+ {
+ // if the command was not found create a TestResult object
+ // that has that information
+ this->TestProcess = new cmProcess;
+ *this->TestHandler->LogFile << "Unable to find executable: "
+ << args[1].c_str() << std::endl;
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Unable to find executable: "
+ << args[1].c_str() << std::endl);
+ this->TestResult.Output = "Unable to find executable: " + args[1];
+ this->TestResult.FullCommandLine = "";
+ this->TestResult.CompletionStatus = "Not Run";
+ this->TestResult.Status = cmCTestTestHandler::NOT_RUN;
+ return false;
+ }
+ this->StartTime = this->CTest->CurrentTime();
+
+ double timeout = this->ResolveTimeout();
+
+ if(this->StopTimePassed)
+ {
+ return false;
+ }
+ return this->ForkProcess(timeout, this->TestProperties->ExplicitTimeout,
+ &this->TestProperties->Environment);
+}
+
+//----------------------------------------------------------------------
+void cmCTestRunTest::ComputeArguments()
+{
+ std::vector<std::string>::const_iterator j =
+ this->TestProperties->Args.begin();
+ ++j; // skip test name
+
+ // find the test executable
+ if(this->TestHandler->MemCheck)
+ {
+ cmCTestMemCheckHandler * handler = static_cast<cmCTestMemCheckHandler*>
+ (this->TestHandler);
+ this->ActualCommand = handler->MemoryTester.c_str();
+ this->TestProperties->Args[1] = this->TestHandler->FindTheExecutable(
+ this->TestProperties->Args[1].c_str());
+ }
+ else
+ {
+ this->ActualCommand =
+ this->TestHandler->FindTheExecutable(
+ this->TestProperties->Args[1].c_str());
+ ++j; //skip the executable (it will be actualCommand)
+ }
+ std::string testCommand
+ = cmSystemTools::ConvertToOutputPath(this->ActualCommand.c_str());
+
+ //Prepends memcheck args to our command string
+ this->TestHandler->GenerateTestCommand(this->Arguments);
+ for(std::vector<std::string>::iterator i = this->Arguments.begin();
+ i != this->Arguments.end(); ++i)
+ {
+ testCommand += " \"";
+ testCommand += *i;
+ testCommand += "\"";
+ }
+
+ for(;j != this->TestProperties->Args.end(); ++j)
+ {
+ testCommand += " \"";
+ testCommand += *j;
+ testCommand += "\"";
+ this->Arguments.push_back(*j);
+ }
+ this->TestResult.FullCommandLine = testCommand;
+
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, std::endl
+ << this->Index << ": "
+ << (this->TestHandler->MemCheck?"MemCheck":"Test")
+ << " command: " << testCommand
+ << std::endl);
+}
+
+//----------------------------------------------------------------------
+void cmCTestRunTest::DartProcessing()
+{
+ if (!this->ProcessOutput.empty() &&
+ this->ProcessOutput.find("<DartMeasurement") != this->ProcessOutput.npos)
+ {
+ if (this->TestHandler->DartStuff.find(this->ProcessOutput.c_str()))
+ {
+ std::string dartString = this->TestHandler->DartStuff.match(1);
+ // keep searching and replacing until none are left
+ while (this->TestHandler->DartStuff1.find(this->ProcessOutput.c_str()))
+ {
+ // replace the exact match for the string
+ cmSystemTools::ReplaceString(this->ProcessOutput,
+ this->TestHandler->DartStuff1.match(1).c_str(), "");
+ }
+ this->TestResult.RegressionImages
+ = this->TestHandler->GenerateRegressionImages(dartString);
+ }
+ }
+}
+
+//----------------------------------------------------------------------
+double cmCTestRunTest::ResolveTimeout()
+{
+ double timeout = this->TestProperties->Timeout;
+
+ if(this->CTest->GetStopTime() == "")
+ {
+ return timeout;
+ }
+ struct tm* lctime;
+ time_t current_time = time(0);
+ lctime = gmtime(&current_time);
+ int gm_hour = lctime->tm_hour;
+ time_t gm_time = mktime(lctime);
+ lctime = localtime(&current_time);
+ int local_hour = lctime->tm_hour;
+
+ int tzone_offset = local_hour - gm_hour;
+ if(gm_time > current_time && gm_hour < local_hour)
+ {
+ // this means gm_time is on the next day
+ tzone_offset -= 24;
+ }
+ else if(gm_time < current_time && gm_hour > local_hour)
+ {
+ // this means gm_time is on the previous day
+ tzone_offset += 24;
+ }
+
+ tzone_offset *= 100;
+ char buf[1024];
+ // add todays year day and month to the time in str because
+ // curl_getdate no longer assumes the day is today
+ sprintf(buf, "%d%02d%02d %s %+05i",
+ lctime->tm_year + 1900,
+ lctime->tm_mon + 1,
+ lctime->tm_mday,
+ this->CTest->GetStopTime().c_str(),
+ tzone_offset);
+
+ time_t stop_time = curl_getdate(buf, &current_time);
+ if(stop_time == -1)
+ {
+ return timeout;
+ }
+
+ //the stop time refers to the next day
+ if(this->CTest->NextDayStopTime)
+ {
+ stop_time += 24*60*60;
+ }
+ int stop_timeout = static_cast<int>(stop_time - current_time) % (24*60*60);
+ this->CTest->LastStopTimeout = stop_timeout;
+
+ if(stop_timeout <= 0 || stop_timeout > this->CTest->LastStopTimeout)
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "The stop time has been passed. "
+ "Stopping all tests." << std::endl);
+ this->StopTimePassed = true;
+ return 0;
+ }
+ return timeout == 0 ? stop_timeout :
+ (timeout < stop_timeout ? timeout : stop_timeout);
+}
+
+//----------------------------------------------------------------------
+bool cmCTestRunTest::ForkProcess(double testTimeOut, bool explicitTimeout,
+ std::vector<std::string>* environment)
+{
+ this->TestProcess = new cmProcess;
+ this->TestProcess->SetId(this->Index);
+ this->TestProcess->SetWorkingDirectory(
+ this->TestProperties->Directory.c_str());
+ this->TestProcess->SetCommand(this->ActualCommand.c_str());
+ this->TestProcess->SetCommandArguments(this->Arguments);
+
+ // determine how much time we have
+ double timeout = this->CTest->GetRemainingTimeAllowed() - 120;
+ if (this->CTest->GetTimeOut() > 0 && this->CTest->GetTimeOut() < timeout)
+ {
+ timeout = this->CTest->GetTimeOut();
+ }
+ if (testTimeOut > 0
+ && testTimeOut < this->CTest->GetRemainingTimeAllowed())
+ {
+ timeout = testTimeOut;
+ }
+ // always have at least 1 second if we got to here
+ if (timeout <= 0)
+ {
+ timeout = 1;
+ }
+ // handle timeout explicitly set to 0
+ if (testTimeOut == 0 && explicitTimeout)
+ {
+ timeout = 0;
+ }
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, this->Index << ": "
+ << "Test timeout computed to be: " << timeout << "\n");
+
+ this->TestProcess->SetTimeout(timeout);
+
+#ifdef CMAKE_BUILD_WITH_CMAKE
+ cmSystemTools::SaveRestoreEnvironment sre;
+#endif
+
+ if (environment && environment->size()>0)
+ {
+ cmSystemTools::AppendEnv(*environment);
+ }
+
+ return this->TestProcess->StartProcess();
+}
+
+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->TestHandler->MemCheck )
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, "MemCheck");
+ }
+ else
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, "Test");
+ }
+
+ cmOStringStream indexStr;
+ indexStr << " #" << this->Index << ":";
+ cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ std::setw(3 + getNumWidth(this->TestHandler->GetMaxIndex()))
+ << indexStr.str().c_str());
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " ");
+ const int maxTestNameWidth = this->CTest->GetMaxTestNameWidth();
+ std::string outname = this->TestProperties->Name + " ";
+ outname.resize(maxTestNameWidth + 4, '.');
+
+ *this->TestHandler->LogFile << this->TestProperties->Index << "/"
+ << this->TestHandler->TotalNumberOfTests << " Testing: "
+ << this->TestProperties->Name << std::endl;
+ *this->TestHandler->LogFile << this->TestProperties->Index << "/"
+ << this->TestHandler->TotalNumberOfTests
+ << " Test: " << this->TestProperties->Name.c_str() << 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() << "\"";
+ }
+ *this->TestHandler->LogFile << std::endl
+ << "Directory: " << this->TestProperties->Directory << std::endl
+ << "\"" << this->TestProperties->Name.c_str() << "\" start time: "
+ << this->StartTime << std::endl;
+
+ *this->TestHandler->LogFile
+ << "Output:" << std::endl
+ << "----------------------------------------------------------"
+ << std::endl;
+ *this->TestHandler->LogFile
+ << this->ProcessOutput.c_str() << "<end of output>" << std::endl;
+
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, outname.c_str());
+ cmCTestLog(this->CTest, DEBUG, "Testing "
+ << this->TestProperties->Name.c_str() << " ... ");
+}
diff --git a/Source/CTest/cmCTestRunTest.h b/Source/CTest/cmCTestRunTest.h
new file mode 100644
index 000000000..89456d505
--- /dev/null
+++ b/Source/CTest/cmCTestRunTest.h
@@ -0,0 +1,112 @@
+/*============================================================================
+ 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 cmCTestRunTest_h
+#define cmCTestRunTest_h
+
+#include <cmStandardIncludes.h>
+#include <cmCTestTestHandler.h>
+#include <cmProcess.h>
+
+/** \class cmRunTest
+ * \brief represents a single test to be run
+ *
+ * cmRunTest contains the information related to running a single test
+ */
+class cmCTestRunTest
+{
+public:
+ cmCTestRunTest(cmCTestTestHandler* handler);
+ ~cmCTestRunTest();
+
+ void SetTestProperties(cmCTestTestHandler::cmCTestTestProperties * prop)
+ { this->TestProperties = prop; }
+
+ cmCTestTestHandler::cmCTestTestProperties * GetTestProperties()
+ { return this->TestProperties; }
+
+ void SetIndex(int i) { this->Index = i; }
+
+ int GetIndex() { return this->Index; }
+
+ std::string GetProcessOutput() { return this->ProcessOutput; }
+
+ bool IsStopTimePassed() { return this->StopTimePassed; }
+
+ cmCTestTestHandler::cmCTestTestResult GetTestResults()
+ { return this->TestResult; }
+
+ // Read and store output. Returns true if it must be called again.
+ bool CheckOutput();
+
+ // Compresses the output, writing to CompressedOutput
+ void CompressOutput();
+
+ //launch the test process, return whether it started correctly
+ bool StartTest(size_t total);
+ //capture and report the test results
+ bool EndTest(size_t completed, size_t total, bool started);
+ //Called by ctest -N to log the command string
+ void ComputeArguments();
+
+ void ComputeWeightedCost();
+private:
+ void DartProcessing();
+ void ExeNotFound(std::string exe);
+ // Figures out a final timeout which is min(STOP_TIME, NOW+TIMEOUT)
+ double ResolveTimeout();
+ bool ForkProcess(double testTimeOut, bool explicitTimeout,
+ std::vector<std::string>* environment);
+ void WriteLogOutputTop(size_t completed, size_t total);
+ //Run post processing of the process output for MemCheck
+ void MemCheckPostProcess();
+
+ cmCTestTestHandler::cmCTestTestProperties * TestProperties;
+ //Pointer back to the "parent"; the handler that invoked this test run
+ cmCTestTestHandler * TestHandler;
+ cmCTest * CTest;
+ cmProcess * TestProcess;
+ //If the executable to run is ctest, don't create a new process;
+ //just instantiate a new cmTest. (Can be disabled for a single test
+ //if this option is set to false.)
+ //bool OptimizeForCTest;
+
+ bool UsePrefixCommand;
+ std::string PrefixCommand;
+
+ std::string ProcessOutput;
+ std::string CompressedOutput;
+ double CompressionRatio;
+ //The test results
+ cmCTestTestHandler::cmCTestTestResult TestResult;
+ int Index;
+ std::string StartTime;
+ std::string ActualCommand;
+ std::vector<std::string> Arguments;
+ bool StopTimePassed;
+};
+
+inline int getNumWidth(size_t n)
+{
+ int numWidth = 1;
+ if(n >= 10)
+ {
+ numWidth = 2;
+ }
+ if(n >= 100)
+ {
+ numWidth = 3;
+ }
+ return numWidth;
+}
+
+#endif
+
diff --git a/Source/CTest/cmCTestSVN.cxx b/Source/CTest/cmCTestSVN.cxx
new file mode 100644
index 000000000..fab9a8cba
--- /dev/null
+++ b/Source/CTest/cmCTestSVN.cxx
@@ -0,0 +1,450 @@
+/*============================================================================
+ 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 "cmCTestSVN.h"
+
+#include "cmCTest.h"
+#include "cmSystemTools.h"
+#include "cmXMLParser.h"
+#include "cmXMLSafe.h"
+
+#include <cmsys/RegularExpression.hxx>
+
+//----------------------------------------------------------------------------
+cmCTestSVN::cmCTestSVN(cmCTest* ct, std::ostream& log):
+ cmCTestGlobalVC(ct, log)
+{
+ this->PriorRev = this->Unknown;
+}
+
+//----------------------------------------------------------------------------
+cmCTestSVN::~cmCTestSVN()
+{
+}
+
+//----------------------------------------------------------------------------
+void cmCTestSVN::CleanupImpl()
+{
+ const char* svn = this->CommandLineTool.c_str();
+ const char* svn_cleanup[] = {svn, "cleanup", 0};
+ OutputLogger out(this->Log, "cleanup-out> ");
+ OutputLogger err(this->Log, "cleanup-err> ");
+ this->RunChild(svn_cleanup, &out, &err);
+}
+
+//----------------------------------------------------------------------------
+class cmCTestSVN::InfoParser: public cmCTestVC::LineParser
+{
+public:
+ InfoParser(cmCTestSVN* svn, const char* prefix, std::string& rev):
+ SVN(svn), Rev(rev)
+ {
+ this->SetLog(&svn->Log, prefix);
+ this->RegexRev.compile("^Revision: ([0-9]+)");
+ this->RegexURL.compile("^URL: +([^ ]+) *$");
+ this->RegexRoot.compile("^Repository Root: +([^ ]+) *$");
+ }
+private:
+ cmCTestSVN* SVN;
+ std::string& Rev;
+ cmsys::RegularExpression RegexRev;
+ cmsys::RegularExpression RegexURL;
+ cmsys::RegularExpression RegexRoot;
+ virtual bool ProcessLine()
+ {
+ if(this->RegexRev.find(this->Line))
+ {
+ this->Rev = this->RegexRev.match(1);
+ }
+ else if(this->RegexURL.find(this->Line))
+ {
+ this->SVN->URL = this->RegexURL.match(1);
+ }
+ else if(this->RegexRoot.find(this->Line))
+ {
+ this->SVN->Root = this->RegexRoot.match(1);
+ }
+ return true;
+ }
+};
+
+//----------------------------------------------------------------------------
+static bool cmCTestSVNPathStarts(std::string const& p1, std::string const& p2)
+{
+ // Does path p1 start with path p2?
+ if(p1.size() == p2.size())
+ {
+ return p1 == p2;
+ }
+ else if(p1.size() > p2.size() && p1[p2.size()] == '/')
+ {
+ return strncmp(p1.c_str(), p2.c_str(), p2.size()) == 0;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string cmCTestSVN::LoadInfo()
+{
+ // Run "svn info" to get the repository info from the work tree.
+ const char* svn = this->CommandLineTool.c_str();
+ const char* svn_info[] = {svn, "info", 0};
+ std::string rev;
+ InfoParser out(this, "info-out> ", rev);
+ OutputLogger err(this->Log, "info-err> ");
+ this->RunChild(svn_info, &out, &err);
+ return rev;
+}
+
+//----------------------------------------------------------------------------
+void cmCTestSVN::NoteOldRevision()
+{
+ this->OldRevision = this->LoadInfo();
+ this->Log << "Revision before update: " << this->OldRevision << "\n";
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " Old revision of repository is: "
+ << this->OldRevision << "\n");
+ this->PriorRev.Rev = this->OldRevision;
+}
+
+//----------------------------------------------------------------------------
+void cmCTestSVN::NoteNewRevision()
+{
+ this->NewRevision = this->LoadInfo();
+ this->Log << "Revision after update: " << this->NewRevision << "\n";
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " New revision of repository is: "
+ << this->NewRevision << "\n");
+
+ // this->Root = ""; // uncomment to test GuessBase
+ this->Log << "URL = " << this->URL << "\n";
+ this->Log << "Root = " << this->Root << "\n";
+
+ // Compute the base path the working tree has checked out under
+ // the repository root.
+ if(!this->Root.empty() && cmCTestSVNPathStarts(this->URL, this->Root))
+ {
+ this->Base = cmCTest::DecodeURL(this->URL.substr(this->Root.size()));
+ this->Base += "/";
+ }
+ this->Log << "Base = " << this->Base << "\n";
+}
+
+//----------------------------------------------------------------------------
+void cmCTestSVN::GuessBase(std::vector<Change> const& changes)
+{
+ // Subversion did not give us a good repository root so we need to
+ // guess the base path from the URL and the paths in a revision with
+ // changes under it.
+
+ // Consider each possible URL suffix from longest to shortest.
+ for(std::string::size_type slash = this->URL.find('/');
+ this->Base.empty() && slash != std::string::npos;
+ slash = this->URL.find('/', slash+1))
+ {
+ // If the URL suffix is a prefix of at least one path then it is the base.
+ std::string base = cmCTest::DecodeURL(this->URL.substr(slash));
+ for(std::vector<Change>::const_iterator ci = changes.begin();
+ this->Base.empty() && ci != changes.end(); ++ci)
+ {
+ if(cmCTestSVNPathStarts(ci->Path, base))
+ {
+ this->Base = base;
+ }
+ }
+ }
+
+ // We always append a slash so that we know paths beginning in the
+ // base lie under its path. If no base was found then the working
+ // tree must be a checkout of the entire repo and this will match
+ // the leading slash in all paths.
+ this->Base += "/";
+
+ this->Log << "Guessed Base = " << this->Base << "\n";
+}
+
+//----------------------------------------------------------------------------
+const char* cmCTestSVN::LocalPath(std::string const& path)
+{
+ if(path.size() > this->Base.size() &&
+ strncmp(path.c_str(), this->Base.c_str(), this->Base.size()) == 0)
+ {
+ // This path lies under the base, so return a relative path.
+ return path.c_str() + this->Base.size();
+ }
+ else
+ {
+ // This path does not lie under the base, so ignore it.
+ return 0;
+ }
+}
+
+//----------------------------------------------------------------------------
+class cmCTestSVN::UpdateParser: public cmCTestVC::LineParser
+{
+public:
+ UpdateParser(cmCTestSVN* svn, const char* prefix): SVN(svn)
+ {
+ this->SetLog(&svn->Log, prefix);
+ this->RegexUpdate.compile("^([ADUCGE ])([ADUCGE ])[B ] +(.+)$");
+ }
+private:
+ cmCTestSVN* SVN;
+ cmsys::RegularExpression RegexUpdate;
+
+ bool ProcessLine()
+ {
+ if(this->RegexUpdate.find(this->Line))
+ {
+ this->DoPath(this->RegexUpdate.match(1)[0],
+ this->RegexUpdate.match(2)[0],
+ this->RegexUpdate.match(3));
+ }
+ return true;
+ }
+
+ void DoPath(char path_status, char prop_status, std::string const& path)
+ {
+ char status = (path_status != ' ')? path_status : prop_status;
+ std::string dir = cmSystemTools::GetFilenamePath(path);
+ std::string name = cmSystemTools::GetFilenameName(path);
+ // See "svn help update".
+ switch(status)
+ {
+ case 'G':
+ this->SVN->Dirs[dir][name].Status = PathModified;
+ break;
+ case 'C':
+ this->SVN->Dirs[dir][name].Status = PathConflicting;
+ break;
+ case 'A': case 'D': case 'U':
+ this->SVN->Dirs[dir][name].Status = PathUpdated;
+ break;
+ case 'E': // TODO?
+ case '?': case ' ': default:
+ break;
+ }
+ }
+};
+
+//----------------------------------------------------------------------------
+bool cmCTestSVN::UpdateImpl()
+{
+ // Get user-specified update options.
+ std::string opts = this->CTest->GetCTestConfiguration("UpdateOptions");
+ if(opts.empty())
+ {
+ opts = this->CTest->GetCTestConfiguration("SVNUpdateOptions");
+ }
+ std::vector<cmStdString> args = cmSystemTools::ParseArguments(opts.c_str());
+
+ // Specify the start time for nightly testing.
+ if(this->CTest->GetTestModel() == cmCTest::NIGHTLY)
+ {
+ args.push_back("-r{" + this->GetNightlyTime() + " +0000}");
+ }
+
+ std::vector<char const*> svn_update;
+ svn_update.push_back(this->CommandLineTool.c_str());
+ svn_update.push_back("update");
+ svn_update.push_back("--non-interactive");
+ for(std::vector<cmStdString>::const_iterator ai = args.begin();
+ ai != args.end(); ++ai)
+ {
+ svn_update.push_back(ai->c_str());
+ }
+ svn_update.push_back(0);
+
+ UpdateParser out(this, "up-out> ");
+ OutputLogger err(this->Log, "up-err> ");
+ return this->RunUpdateCommand(&svn_update[0], &out, &err);
+}
+
+//----------------------------------------------------------------------------
+class cmCTestSVN::LogParser: public cmCTestVC::OutputLogger,
+ private cmXMLParser
+{
+public:
+ LogParser(cmCTestSVN* svn, const char* prefix):
+ OutputLogger(svn->Log, prefix), SVN(svn) { this->InitializeParser(); }
+ ~LogParser() { this->CleanupParser(); }
+private:
+ cmCTestSVN* SVN;
+
+ typedef cmCTestSVN::Revision Revision;
+ typedef cmCTestSVN::Change Change;
+ Revision Rev;
+ std::vector<Change> Changes;
+ Change CurChange;
+ std::vector<char> CData;
+
+ virtual bool ProcessChunk(const char* data, int length)
+ {
+ this->OutputLogger::ProcessChunk(data, length);
+ this->ParseChunk(data, length);
+ return true;
+ }
+
+ virtual void StartElement(const char* name, const char** atts)
+ {
+ this->CData.clear();
+ if(strcmp(name, "logentry") == 0)
+ {
+ this->Rev = Revision();
+ if(const char* rev = this->FindAttribute(atts, "revision"))
+ {
+ this->Rev.Rev = rev;
+ }
+ this->Changes.clear();
+ }
+ else if(strcmp(name, "path") == 0)
+ {
+ this->CurChange = Change();
+ if(const char* action = this->FindAttribute(atts, "action"))
+ {
+ this->CurChange.Action = action[0];
+ }
+ }
+ }
+
+ virtual void CharacterDataHandler(const char* data, int length)
+ {
+ this->CData.insert(this->CData.end(), data, data+length);
+ }
+
+ virtual void EndElement(const char* name)
+ {
+ if(strcmp(name, "logentry") == 0)
+ {
+ this->SVN->DoRevision(this->Rev, this->Changes);
+ }
+ else if(strcmp(name, "path") == 0 && !this->CData.empty())
+ {
+ this->CurChange.Path.assign(&this->CData[0], this->CData.size());
+ this->Changes.push_back(this->CurChange);
+ }
+ else if(strcmp(name, "author") == 0 && !this->CData.empty())
+ {
+ this->Rev.Author.assign(&this->CData[0], this->CData.size());
+ }
+ else if(strcmp(name, "date") == 0 && !this->CData.empty())
+ {
+ this->Rev.Date.assign(&this->CData[0], this->CData.size());
+ }
+ else if(strcmp(name, "msg") == 0 && !this->CData.empty())
+ {
+ this->Rev.Log.assign(&this->CData[0], this->CData.size());
+ }
+ this->CData.clear();
+ }
+
+ virtual void ReportError(int, int, const char* msg)
+ {
+ this->SVN->Log << "Error parsing svn log xml: " << msg << "\n";
+ }
+};
+
+//----------------------------------------------------------------------------
+void cmCTestSVN::LoadRevisions()
+{
+ // We are interested in every revision included in the update.
+ std::string revs;
+ if(atoi(this->OldRevision.c_str()) < atoi(this->NewRevision.c_str()))
+ {
+ revs = "-r" + this->OldRevision + ":" + this->NewRevision;
+ }
+ else
+ {
+ revs = "-r" + this->NewRevision;
+ }
+
+ // Run "svn log" to get all global revisions of interest.
+ const char* svn = this->CommandLineTool.c_str();
+ const char* svn_log[] = {svn, "log", "--xml", "-v", revs.c_str(), 0};
+ {
+ LogParser out(this, "log-out> ");
+ OutputLogger err(this->Log, "log-err> ");
+ this->RunChild(svn_log, &out, &err);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmCTestSVN::DoRevision(Revision const& revision,
+ std::vector<Change> const& changes)
+{
+ // Guess the base checkout path from the changes if necessary.
+ if(this->Base.empty() && !changes.empty())
+ {
+ this->GuessBase(changes);
+ }
+ this->cmCTestGlobalVC::DoRevision(revision, changes);
+}
+
+//----------------------------------------------------------------------------
+class cmCTestSVN::StatusParser: public cmCTestVC::LineParser
+{
+public:
+ StatusParser(cmCTestSVN* svn, const char* prefix): SVN(svn)
+ {
+ this->SetLog(&svn->Log, prefix);
+ this->RegexStatus.compile("^([ACDIMRX?!~ ])([CM ])[ L]... +(.+)$");
+ }
+private:
+ cmCTestSVN* SVN;
+ cmsys::RegularExpression RegexStatus;
+ bool ProcessLine()
+ {
+ if(this->RegexStatus.find(this->Line))
+ {
+ this->DoPath(this->RegexStatus.match(1)[0],
+ this->RegexStatus.match(2)[0],
+ this->RegexStatus.match(3));
+ }
+ return true;
+ }
+
+ void DoPath(char path_status, char prop_status, std::string const& path)
+ {
+ char status = (path_status != ' ')? path_status : prop_status;
+ // See "svn help status".
+ switch(status)
+ {
+ case 'M': case '!': case 'A': case 'D': case 'R':
+ this->SVN->DoModification(PathModified, path);
+ break;
+ case 'C': case '~':
+ this->SVN->DoModification(PathConflicting, path);
+ break;
+ case 'X': case 'I': case '?': case ' ': default:
+ break;
+ }
+ }
+};
+
+//----------------------------------------------------------------------------
+void cmCTestSVN::LoadModifications()
+{
+ // Run "svn status" which reports local modifications.
+ const char* svn = this->CommandLineTool.c_str();
+ const char* svn_status[] = {svn, "status", "--non-interactive", 0};
+ StatusParser out(this, "status-out> ");
+ OutputLogger err(this->Log, "status-err> ");
+ this->RunChild(svn_status, &out, &err);
+}
+
+//----------------------------------------------------------------------------
+void cmCTestSVN::WriteXMLGlobal(std::ostream& xml)
+{
+ this->cmCTestGlobalVC::WriteXMLGlobal(xml);
+
+ xml << "\t<SVNPath>" << this->Base << "</SVNPath>\n";
+}
diff --git a/Source/CTest/cmCTestSVN.h b/Source/CTest/cmCTestSVN.h
new file mode 100644
index 000000000..f72c58fb0
--- /dev/null
+++ b/Source/CTest/cmCTestSVN.h
@@ -0,0 +1,68 @@
+/*============================================================================
+ 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 cmCTestSVN_h
+#define cmCTestSVN_h
+
+#include "cmCTestGlobalVC.h"
+
+/** \class cmCTestSVN
+ * \brief Interaction with subversion command-line tool
+ *
+ */
+class cmCTestSVN: public cmCTestGlobalVC
+{
+public:
+ /** Construct with a CTest instance and update log stream. */
+ cmCTestSVN(cmCTest* ctest, std::ostream& log);
+
+ virtual ~cmCTestSVN();
+
+private:
+ // Implement cmCTestVC internal API.
+ virtual void CleanupImpl();
+ virtual void NoteOldRevision();
+ virtual void NoteNewRevision();
+ virtual bool UpdateImpl();
+
+ // URL of repository directory checked out in the working tree.
+ std::string URL;
+
+ // URL of repository root directory.
+ std::string Root;
+
+ // Directory under repository root checked out in working tree.
+ std::string Base;
+
+ std::string LoadInfo();
+ void LoadModifications();
+ void LoadRevisions();
+
+ void GuessBase(std::vector<Change> const& changes);
+ const char* LocalPath(std::string const& path);
+
+ void DoRevision(Revision const& revision,
+ std::vector<Change> const& changes);
+
+ void WriteXMLGlobal(std::ostream& xml);
+
+ // Parsing helper classes.
+ class InfoParser;
+ class LogParser;
+ class StatusParser;
+ class UpdateParser;
+ friend class InfoParser;
+ friend class LogParser;
+ friend class StatusParser;
+ friend class UpdateParser;
+};
+
+#endif
diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx
new file mode 100644
index 000000000..8643cb3f7
--- /dev/null
+++ b/Source/CTest/cmCTestScriptHandler.cxx
@@ -0,0 +1,1095 @@
+/*============================================================================
+ 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 "cmCTestScriptHandler.h"
+
+#include "cmCTest.h"
+#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>
+
+// used for sleep
+#ifdef _WIN32
+#include "windows.h"
+#endif
+
+#include <stdlib.h>
+#include <time.h>
+#include <math.h>
+#include <float.h>
+
+// needed for sleep
+#if !defined(_WIN32)
+# include <unistd.h>
+#endif
+
+#include "cmCTestBuildCommand.h"
+#include "cmCTestConfigureCommand.h"
+#include "cmCTestCoverageCommand.h"
+#include "cmCTestEmptyBinaryDirectoryCommand.h"
+#include "cmCTestMemCheckCommand.h"
+#include "cmCTestReadCustomFilesCommand.h"
+#include "cmCTestRunScriptCommand.h"
+#include "cmCTestSleepCommand.h"
+#include "cmCTestStartCommand.h"
+#include "cmCTestSubmitCommand.h"
+#include "cmCTestTestCommand.h"
+#include "cmCTestUpdateCommand.h"
+#include "cmCTestUploadCommand.h"
+
+#define CTEST_INITIAL_CMAKE_OUTPUT_FILE_NAME "CTestInitialCMakeOutput.log"
+
+// used to keep elapsed time up to date
+class cmCTestScriptFunctionBlocker : public cmFunctionBlocker
+{
+public:
+ cmCTestScriptFunctionBlocker() {}
+ virtual ~cmCTestScriptFunctionBlocker() {}
+ virtual bool IsFunctionBlocked(const cmListFileFunction& lff,
+ cmMakefile &mf,
+ cmExecutionStatus &);
+ //virtual bool ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf);
+ //virtual void ScopeEnded(cmMakefile &mf);
+
+ cmCTestScriptHandler* CTestScriptHandler;
+};
+
+// simply update the time and don't block anything
+bool cmCTestScriptFunctionBlocker::
+IsFunctionBlocked(const cmListFileFunction& , cmMakefile &,
+ cmExecutionStatus &)
+{
+ this->CTestScriptHandler->UpdateElapsedTime();
+ return false;
+}
+
+//----------------------------------------------------------------------
+cmCTestScriptHandler::cmCTestScriptHandler()
+{
+ this->Backup = false;
+ this->EmptyBinDir = false;
+ this->EmptyBinDirOnce = false;
+ this->Makefile = 0;
+ this->LocalGenerator = 0;
+ this->CMake = 0;
+ this->GlobalGenerator = 0;
+
+ this->ScriptStartTime = 0;
+
+ // the *60 is becuase the settings are in minutes but GetTime is seconds
+ this->MinimumInterval = 30*60;
+ this->ContinuousDuration = -1;
+}
+
+//----------------------------------------------------------------------
+void cmCTestScriptHandler::Initialize()
+{
+ this->Superclass::Initialize();
+ this->Backup = false;
+ this->EmptyBinDir = false;
+ this->EmptyBinDirOnce = false;
+
+ this->SourceDir = "";
+ this->BinaryDir = "";
+ this->BackupSourceDir = "";
+ this->BackupBinaryDir = "";
+ this->CTestRoot = "";
+ this->CVSCheckOut = "";
+ this->CTestCmd = "";
+ this->UpdateCmd = "";
+ this->CTestEnv = "";
+ this->InitialCache = "";
+ this->CMakeCmd = "";
+ this->CMOutFile = "";
+ this->ExtraUpdates.clear();
+
+ this->MinimumInterval = 20*60;
+ this->ContinuousDuration = -1;
+
+ // what time in seconds did this script start running
+ this->ScriptStartTime = 0;
+
+ 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;
+ }
+}
+
+//----------------------------------------------------------------------
+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;
+ }
+}
+
+
+//----------------------------------------------------------------------
+// just adds an argument to the vector
+void cmCTestScriptHandler::AddConfigurationScript(const char *script,
+ bool pscope)
+{
+ this->ConfigurationScripts.push_back(script);
+ this->ScriptProcessScope.push_back(pscope);
+}
+
+
+//----------------------------------------------------------------------
+// the generic entry point for handling scripts, this routine will run all
+// the scripts provides a -S arguments
+int cmCTestScriptHandler::ProcessHandler()
+{
+ int res = 0;
+ 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()),
+ this->ScriptProcessScope[i]);
+ }
+ if ( res )
+ {
+ return -1;
+ }
+ return 0;
+}
+
+void cmCTestScriptHandler::UpdateElapsedTime()
+{
+ if (this->LocalGenerator)
+ {
+ // 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);
+ }
+}
+
+//----------------------------------------------------------------------
+void cmCTestScriptHandler::AddCTestCommand(cmCTestCommand* command)
+{
+ cmCTestCommand* newCom = command;
+ newCom->CTest = this->CTest;
+ newCom->CTestScriptHandler = this;
+ this->CMake->AddCommand(newCom);
+}
+
+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("-SR");
+ argv.push_back(total_script_arg.c_str());
+
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Executable for CTest is: " <<
+ this->CTest->GetCTestExecutable() << "\n");
+
+ // now pass through all the other arguments
+ std::vector<cmStdString> &initArgs =
+ this->CTest->GetInitialCommandLineArguments();
+ //*** need to make sure this does not have the current script ***
+ for(size_t i=1; i < initArgs.size(); ++i)
+ {
+ argv.push_back(initArgs[i].c_str());
+ }
+ argv.push_back(0);
+
+ // Now create process object
+ cmsysProcess* cp = cmsysProcess_New();
+ cmsysProcess_SetCommand(cp, &*argv.begin());
+ //cmsysProcess_SetWorkingDirectory(cp, dir);
+ cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1);
+ //cmsysProcess_SetTimeout(cp, timeout);
+ cmsysProcess_Execute(cp);
+
+ std::vector<char> out;
+ std::vector<char> err;
+ std::string line;
+ int pipe = cmSystemTools::WaitForLine(cp, line, 100.0, out, err);
+ while(pipe != cmsysProcess_Pipe_None)
+ {
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Output: "
+ << line << "\n");
+ if(pipe == cmsysProcess_Pipe_STDERR)
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, line << "\n");
+ }
+ else if(pipe == cmsysProcess_Pipe_STDOUT)
+ {
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, line << "\n");
+ }
+ pipe = cmSystemTools::WaitForLine(cp, line, 100, out, err);
+ }
+
+ // Properly handle output of the build command
+ cmsysProcess_WaitForExit(cp, 0);
+ int result = cmsysProcess_GetState(cp);
+ int retVal = 0;
+ bool failed = false;
+ if(result == cmsysProcess_State_Exited)
+ {
+ retVal = cmsysProcess_GetExitValue(cp);
+ }
+ else if(result == cmsysProcess_State_Exception)
+ {
+ retVal = cmsysProcess_GetExitException(cp);
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "\tThere was an exception: "
+ << cmsysProcess_GetExceptionString(cp) << " " <<
+ retVal << std::endl);
+ failed = true;
+ }
+ else if(result == cmsysProcess_State_Expired)
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "\tThere was a timeout"
+ << std::endl);
+ failed = true;
+ }
+ else if(result == cmsysProcess_State_Error)
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "\tError executing ctest: "
+ << cmsysProcess_GetErrorString(cp) << std::endl);
+ failed = true;
+ }
+ cmsysProcess_Delete(cp);
+ if(failed)
+ {
+ cmOStringStream message;
+ message << "Error running command: [";
+ message << result << "] ";
+ for(std::vector<const char*>::iterator i = argv.begin();
+ i != argv.end(); ++i)
+ {
+ if(*i)
+ {
+ message << *i << " ";
+ }
+ }
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ message.str() << argv[0] << std::endl);
+ return -1;
+ }
+ return retVal;
+}
+
+void cmCTestScriptHandler::CreateCMake()
+{
+ // create a cmake instance to read the configuration script
+ if (this->CMake)
+ {
+ delete this->CMake;
+ delete this->GlobalGenerator;
+ delete this->LocalGenerator;
+ }
+ this->CMake = new cmake;
+ this->CMake->AddCMakePaths();
+ this->GlobalGenerator = new cmGlobalGenerator;
+ this->GlobalGenerator->SetCMakeInstance(this->CMake);
+
+ this->LocalGenerator = this->GlobalGenerator->CreateLocalGenerator();
+ this->Makefile = this->LocalGenerator->GetMakefile();
+
+ // Set CMAKE_CURRENT_SOURCE_DIR and CMAKE_CURRENT_BINARY_DIR.
+ // Also, some commands need Makefile->GetCurrentDirectory().
+ std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
+ this->Makefile->SetStartDirectory(cwd.c_str());
+ this->Makefile->SetStartOutputDirectory(cwd.c_str());
+
+ // remove all cmake commands which are not scriptable, since they can't be
+ // used in ctest scripts
+ this->CMake->RemoveUnscriptableCommands();
+
+ // add any ctest specific commands, probably should have common superclass
+ // for ctest commands to clean this up. If a couple more commands are
+ // created with the same format lets do that - ken
+ this->AddCTestCommand(new cmCTestBuildCommand);
+ this->AddCTestCommand(new cmCTestConfigureCommand);
+ this->AddCTestCommand(new cmCTestCoverageCommand);
+ this->AddCTestCommand(new cmCTestEmptyBinaryDirectoryCommand);
+ this->AddCTestCommand(new cmCTestMemCheckCommand);
+ this->AddCTestCommand(new cmCTestReadCustomFilesCommand);
+ this->AddCTestCommand(new cmCTestRunScriptCommand);
+ this->AddCTestCommand(new cmCTestSleepCommand);
+ this->AddCTestCommand(new cmCTestStartCommand);
+ this->AddCTestCommand(new cmCTestSubmitCommand);
+ this->AddCTestCommand(new cmCTestTestCommand);
+ this->AddCTestCommand(new cmCTestUpdateCommand);
+ 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
+int cmCTestScriptHandler::ReadInScript(const std::string& total_script_arg)
+{
+ // Reset the error flag so that the script is read in no matter what
+ cmSystemTools::ResetErrorOccuredFlag();
+
+ // if the argument has a , in it then it needs to be broken into the fist
+ // argument (which is the script) and the second argument which will be
+ // passed into the scripts as S_ARG
+ std::string script = total_script_arg;
+ std::string script_arg;
+ if (total_script_arg.find(",") != std::string::npos)
+ {
+ script = total_script_arg.substr(0,total_script_arg.find(","));
+ script_arg = total_script_arg.substr(total_script_arg.find(",")+1);
+ }
+ // make sure the file exists
+ if (!cmSystemTools::FileExists(script.c_str()))
+ {
+ cmSystemTools::Error("Cannot find file: ", script.c_str());
+ return 1;
+ }
+
+ // read in the list file to fill the cache
+ // create a cmake instance to read the configuration script
+ this->CreateCMake();
+
+ // set a variable with the path to the current script
+ this->Makefile->AddDefinition("CTEST_SCRIPT_DIRECTORY",
+ cmSystemTools::GetFilenamePath(script).c_str());
+ this->Makefile->AddDefinition("CTEST_SCRIPT_NAME",
+ cmSystemTools::GetFilenameName(script).c_str());
+ this->Makefile->AddDefinition("CTEST_EXECUTABLE_NAME",
+ this->CTest->GetCTestExecutable());
+ this->Makefile->AddDefinition("CMAKE_EXECUTABLE_NAME",
+ this->CTest->GetCMakeExecutable());
+ this->Makefile->AddDefinition("CTEST_RUN_CURRENT_SCRIPT", true);
+ this->UpdateElapsedTime();
+
+ // add the script arg if defined
+ if (script_arg.size())
+ {
+ this->Makefile->AddDefinition("CTEST_SCRIPT_ARG", script_arg.c_str());
+ }
+
+ // always add a function blocker to update the elapsed time
+ cmCTestScriptFunctionBlocker *f = new cmCTestScriptFunctionBlocker();
+ f->CTestScriptHandler = this;
+ this->Makefile->AddFunctionBlocker(f);
+
+
+ /* Execute CTestScriptMode.cmake, which loads CMakeDetermineSystem and
+ CMakeSystemSpecificInformation, so
+ that variables like CMAKE_SYSTEM and also the search paths for libraries,
+ header and executables are set correctly and can be used. Makes new-style
+ ctest scripting easier. */
+ std::string systemFile =
+ this->Makefile->GetModulesFile("CTestScriptMode.cmake");
+ if (!this->Makefile->ReadListFile(0, systemFile.c_str()) ||
+ cmSystemTools::GetErrorOccuredFlag())
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Error in read:"
+ << systemFile.c_str() << "\n");
+ return 2;
+ }
+
+ // Add definitions of variables passed in on the command line:
+ const std::map<std::string, std::string> &defs =
+ this->CTest->GetDefinitions();
+ 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());
+ }
+
+ // finally read in the script
+ if (!this->Makefile->ReadListFile(0, 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
+ cmSystemTools::ResetErrorOccuredFlag();
+ return 2;
+ }
+
+ return 0;
+}
+
+
+//----------------------------------------------------------------------
+// extract variabels from the script to set ivars
+int cmCTestScriptHandler::ExtractVariables()
+{
+ // Temporary variables
+ const char* minInterval;
+ const char* contDuration;
+
+ this->SourceDir
+ = this->Makefile->GetSafeDefinition("CTEST_SOURCE_DIRECTORY");
+ this->BinaryDir
+ = 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());
+
+ this->CTestCmd
+ = this->Makefile->GetSafeDefinition("CTEST_COMMAND");
+ this->CVSCheckOut
+ = this->Makefile->GetSafeDefinition("CTEST_CVS_CHECKOUT");
+ this->CTestRoot
+ = this->Makefile->GetSafeDefinition("CTEST_DASHBOARD_ROOT");
+ this->UpdateCmd
+ = this->Makefile->GetSafeDefinition("CTEST_UPDATE_COMMAND");
+ if ( this->UpdateCmd.empty() )
+ {
+ this->UpdateCmd
+ = this->Makefile->GetSafeDefinition("CTEST_CVS_COMMAND");
+ }
+ this->CTestEnv
+ = this->Makefile->GetSafeDefinition("CTEST_ENVIRONMENT");
+ this->InitialCache
+ = this->Makefile->GetSafeDefinition("CTEST_INITIAL_CACHE");
+ this->CMakeCmd
+ = this->Makefile->GetSafeDefinition("CTEST_CMAKE_COMMAND");
+ this->CMOutFile
+ = this->Makefile->GetSafeDefinition("CTEST_CMAKE_OUTPUT_FILE_NAME");
+
+ this->Backup
+ = this->Makefile->IsOn("CTEST_BACKUP_AND_RESTORE");
+ this->EmptyBinDir
+ = this->Makefile->IsOn("CTEST_START_WITH_EMPTY_BINARY_DIRECTORY");
+ this->EmptyBinDirOnce
+ = this->Makefile->IsOn("CTEST_START_WITH_EMPTY_BINARY_DIRECTORY_ONCE");
+
+ minInterval
+ = this->Makefile->GetDefinition("CTEST_CONTINUOUS_MINIMUM_INTERVAL");
+ contDuration
+ = this->Makefile->GetDefinition("CTEST_CONTINUOUS_DURATION");
+
+ char updateVar[40];
+ int i;
+ for (i = 1; i < 10; ++i)
+ {
+ sprintf(updateVar,"CTEST_EXTRA_UPDATES_%i",i);
+ const char *updateVal = this->Makefile->GetDefinition(updateVar);
+ if ( updateVal )
+ {
+ if ( this->UpdateCmd.empty() )
+ {
+ cmSystemTools::Error(updateVar,
+ " specified without specifying CTEST_CVS_COMMAND.");
+ return 12;
+ }
+ this->ExtraUpdates.push_back(updateVal);
+ }
+ }
+
+ // in order to backup and restore we also must have the cvs root
+ if (this->Backup && this->CVSCheckOut.empty())
+ {
+ cmSystemTools::Error(
+ "Backup was requested without specifying CTEST_CVS_CHECKOUT.");
+ return 3;
+ }
+
+ // make sure the required info is here
+ if (this->SourceDir.empty() ||
+ this->BinaryDir.empty() ||
+ this->CTestCmd.empty())
+ {
+ std::string msg = "CTEST_SOURCE_DIRECTORY = ";
+ msg += (!this->SourceDir.empty()) ? this->SourceDir.c_str() : "(Null)";
+ msg += "\nCTEST_BINARY_DIRECTORY = ";
+ msg += (!this->BinaryDir.empty()) ? this->BinaryDir.c_str() : "(Null)";
+ msg += "\nCTEST_COMMAND = ";
+ msg += (!this->CTestCmd.empty()) ? this->CTestCmd.c_str() : "(Null)";
+ cmSystemTools::Error(
+ "Some required settings in the configuration file were missing:\n",
+ msg.c_str());
+ return 4;
+ }
+
+ // if the dashboard root isn't specified then we can compute it from the
+ // this->SourceDir
+ if (this->CTestRoot.empty() )
+ {
+ this->CTestRoot = cmSystemTools::GetFilenamePath(this->SourceDir).c_str();
+ }
+
+ // the script may override the minimum continuous interval
+ if (minInterval)
+ {
+ this->MinimumInterval = 60 * atof(minInterval);
+ }
+ if (contDuration)
+ {
+ this->ContinuousDuration = 60.0 * atof(contDuration);
+ }
+
+
+ this->UpdateElapsedTime();
+
+ return 0;
+}
+
+//----------------------------------------------------------------------
+void cmCTestScriptHandler::SleepInSeconds(unsigned int secondsToWait)
+{
+#if defined(_WIN32)
+ Sleep(1000*secondsToWait);
+#else
+ sleep(secondsToWait);
+#endif
+}
+
+//----------------------------------------------------------------------
+// run a specific script
+int cmCTestScriptHandler::RunConfigurationScript
+(const std::string& total_script_arg, bool pscope)
+{
+#ifdef CMAKE_BUILD_WITH_CMAKE
+ cmSystemTools::SaveRestoreEnvironment sre;
+#endif
+
+ int result;
+
+ this->ScriptStartTime =
+ cmSystemTools::GetTime();
+
+ // read in the script
+ if (pscope)
+ {
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Reading Script: " << total_script_arg << std::endl);
+ result = this->ReadInScript(total_script_arg);
+ }
+ else
+ {
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Executing Script: " << total_script_arg << std::endl);
+ result = this->ExecuteScript(total_script_arg);
+ }
+ if (result)
+ {
+ return result;
+ }
+
+ // only run the curent script if we should
+ if (this->Makefile && this->Makefile->IsOn("CTEST_RUN_CURRENT_SCRIPT"))
+ {
+ return this->RunCurrentScript();
+ }
+ return result;
+}
+
+//----------------------------------------------------------------------
+int cmCTestScriptHandler::RunCurrentScript()
+{
+ int result;
+
+ // do not run twice
+ this->Makefile->AddDefinition("CTEST_RUN_CURRENT_SCRIPT", false);
+
+ // no popup widows
+ cmSystemTools::SetRunCommandHideConsole(true);
+
+ // extract the vars from the cache and store in ivars
+ result = this->ExtractVariables();
+ if (result)
+ {
+ return result;
+ }
+
+ // set any environment variables
+ if (!this->CTestEnv.empty())
+ {
+ std::vector<std::string> envArgs;
+ cmSystemTools::ExpandListArgument(this->CTestEnv.c_str(),envArgs);
+ cmSystemTools::AppendEnv(envArgs);
+ }
+
+ // now that we have done most of the error checking finally run the
+ // dashboard, we may be asked to repeatedly run this dashboard, such as
+ // for a continuous, do we ned to run it more than once?
+ if ( this->ContinuousDuration >= 0 )
+ {
+ this->UpdateElapsedTime();
+ double ending_time = cmSystemTools::GetTime() + this->ContinuousDuration;
+ if (this->EmptyBinDirOnce)
+ {
+ this->EmptyBinDir = true;
+ }
+ do
+ {
+ double interval = cmSystemTools::GetTime();
+ result = this->RunConfigurationDashboard();
+ interval = cmSystemTools::GetTime() - interval;
+ if (interval < this->MinimumInterval)
+ {
+ this->SleepInSeconds(
+ static_cast<unsigned int>(this->MinimumInterval - interval));
+ }
+ if (this->EmptyBinDirOnce)
+ {
+ this->EmptyBinDir = false;
+ }
+ }
+ while (cmSystemTools::GetTime() < ending_time);
+ }
+ // otherwise just run it once
+ else
+ {
+ result = this->RunConfigurationDashboard();
+ }
+
+ return result;
+}
+
+//----------------------------------------------------------------------
+int cmCTestScriptHandler::CheckOutSourceDir()
+{
+ std::string command;
+ std::string output;
+ int retVal;
+ bool res;
+
+ if (!cmSystemTools::FileExists(this->SourceDir.c_str()) &&
+ !this->CVSCheckOut.empty())
+ {
+ // we must now checkout the src dir
+ output = "";
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Run cvs: " << this->CVSCheckOut << std::endl);
+ res = cmSystemTools::RunSingleCommand(this->CVSCheckOut.c_str(), &output,
+ &retVal, this->CTestRoot.c_str(), this->HandlerVerbose,
+ 0 /*this->TimeOut*/);
+ if (!res || retVal != 0)
+ {
+ cmSystemTools::Error("Unable to perform cvs checkout:\n",
+ output.c_str());
+ return 6;
+ }
+ }
+ return 0;
+}
+
+//----------------------------------------------------------------------
+int cmCTestScriptHandler::BackupDirectories()
+{
+ int retVal;
+
+ // compute the backup names
+ this->BackupSourceDir = this->SourceDir;
+ this->BackupSourceDir += "_CMakeBackup";
+ this->BackupBinaryDir = this->BinaryDir;
+ this->BackupBinaryDir += "_CMakeBackup";
+
+ // backup the binary and src directories if requested
+ if (this->Backup)
+ {
+ // if for some reason those directories exist then first delete them
+ if (cmSystemTools::FileExists(this->BackupSourceDir.c_str()))
+ {
+ cmSystemTools::RemoveADirectory(this->BackupSourceDir.c_str());
+ }
+ if (cmSystemTools::FileExists(this->BackupBinaryDir.c_str()))
+ {
+ cmSystemTools::RemoveADirectory(this->BackupBinaryDir.c_str());
+ }
+
+ // first rename the src and binary directories
+ rename(this->SourceDir.c_str(), this->BackupSourceDir.c_str());
+ rename(this->BinaryDir.c_str(), this->BackupBinaryDir.c_str());
+
+ // we must now checkout the src dir
+ retVal = this->CheckOutSourceDir();
+ if (retVal)
+ {
+ this->RestoreBackupDirectories();
+ return retVal;
+ }
+ }
+
+ return 0;
+}
+
+
+//----------------------------------------------------------------------
+int cmCTestScriptHandler::PerformExtraUpdates()
+{
+ std::string command;
+ std::string output;
+ int retVal;
+ bool res;
+
+ // do an initial cvs update as required
+ command = this->UpdateCmd;
+ std::vector<cmStdString>::iterator it;
+ for (it = this->ExtraUpdates.begin();
+ it != this->ExtraUpdates.end();
+ ++ it )
+ {
+ std::vector<std::string> cvsArgs;
+ cmSystemTools::ExpandListArgument(it->c_str(),cvsArgs);
+ if (cvsArgs.size() == 2)
+ {
+ std::string fullCommand = command;
+ fullCommand += " update ";
+ fullCommand += cvsArgs[1];
+ output = "";
+ retVal = 0;
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Run Update: "
+ << fullCommand.c_str() << std::endl);
+ res = cmSystemTools::RunSingleCommand(fullCommand.c_str(), &output,
+ &retVal, cvsArgs[0].c_str(),
+ this->HandlerVerbose, 0 /*this->TimeOut*/);
+ if (!res || retVal != 0)
+ {
+ cmSystemTools::Error("Unable to perform extra updates:\n",
+ it->c_str(), "\nWith output:\n",
+ output.c_str());
+ return 0;
+ }
+ }
+ }
+ return 0;
+}
+
+
+//----------------------------------------------------------------------
+// run a single dashboard entry
+int cmCTestScriptHandler::RunConfigurationDashboard()
+{
+ // local variables
+ std::string command;
+ std::string output;
+ int retVal;
+ bool res;
+
+ // make sure the src directory is there, if it isn't then we might be able
+ // to check it out from cvs
+ retVal = this->CheckOutSourceDir();
+ if (retVal)
+ {
+ return retVal;
+ }
+
+ // backup the dirs if requested
+ retVal = this->BackupDirectories();
+ if (retVal)
+ {
+ return retVal;
+ }
+
+ // clear the binary directory?
+ if (this->EmptyBinDir)
+ {
+ if ( !cmCTestScriptHandler::EmptyBinaryDirectory(
+ this->BinaryDir.c_str()) )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Problem removing the binary directory" << std::endl);
+ }
+ }
+
+ // make sure the binary directory exists if it isn't the srcdir
+ if (!cmSystemTools::FileExists(this->BinaryDir.c_str()) &&
+ this->SourceDir != this->BinaryDir)
+ {
+ if (!cmSystemTools::MakeDirectory(this->BinaryDir.c_str()))
+ {
+ cmSystemTools::Error("Unable to create the binary directory:\n",
+ this->BinaryDir.c_str());
+ this->RestoreBackupDirectories();
+ return 7;
+ }
+ }
+
+ // if the binary directory and the source directory are the same,
+ // and we are starting with an empty binary directory, then that means
+ // we must check out the source tree
+ if (this->EmptyBinDir && this->SourceDir == this->BinaryDir)
+ {
+ // make sure we have the required info
+ if (this->CVSCheckOut.empty())
+ {
+ cmSystemTools::Error("You have specified the source and binary "
+ "directories to be the same (an in source build). You have also "
+ "specified that the binary directory is to be erased. This means "
+ "that the source will have to be checked out from CVS. But you have "
+ "not specified CTEST_CVS_CHECKOUT");
+ return 8;
+ }
+
+ // we must now checkout the src dir
+ retVal = this->CheckOutSourceDir();
+ if (retVal)
+ {
+ this->RestoreBackupDirectories();
+ return retVal;
+ }
+ }
+
+ // backup the dirs if requested
+ retVal = this->PerformExtraUpdates();
+ if (retVal)
+ {
+ return retVal;
+ }
+
+ // put the initial cache into the bin dir
+ if (!this->InitialCache.empty())
+ {
+ if (!this->WriteInitialCache(this->BinaryDir.c_str(),
+ this->InitialCache.c_str()))
+ {
+ this->RestoreBackupDirectories();
+ return 9;
+ }
+ }
+
+ // do an initial cmake to setup the DartConfig file
+ int cmakeFailed = 0;
+ std::string cmakeFailedOuput;
+ if (!this->CMakeCmd.empty())
+ {
+ command = this->CMakeCmd;
+ command += " \"";
+ command += this->SourceDir;
+ output = "";
+ command += "\"";
+ retVal = 0;
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Run cmake command: "
+ << command.c_str() << std::endl);
+ res = cmSystemTools::RunSingleCommand(command.c_str(), &output,
+ &retVal, this->BinaryDir.c_str(),
+ this->HandlerVerbose, 0 /*this->TimeOut*/);
+
+ if ( !this->CMOutFile.empty() )
+ {
+ std::string cmakeOutputFile = this->CMOutFile;
+ if ( !cmSystemTools::FileIsFullPath(cmakeOutputFile.c_str()) )
+ {
+ cmakeOutputFile = this->BinaryDir + "/" + cmakeOutputFile;
+ }
+
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Write CMake output to file: " << cmakeOutputFile.c_str()
+ << std::endl);
+ cmGeneratedFileStream fout(cmakeOutputFile.c_str());
+ if ( fout )
+ {
+ fout << output.c_str();
+ }
+ else
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Cannot open CMake output file: "
+ << cmakeOutputFile.c_str() << " for writing" << std::endl);
+ }
+ }
+ if (!res || retVal != 0)
+ {
+ // even if this fails continue to the next step
+ cmakeFailed = 1;
+ cmakeFailedOuput = output;
+ }
+ }
+
+ // run ctest, it may be more than one command in here
+ std::vector<std::string> ctestCommands;
+ cmSystemTools::ExpandListArgument(this->CTestCmd,ctestCommands);
+ // for each variable/argument do a putenv
+ for (unsigned i = 0; i < ctestCommands.size(); ++i)
+ {
+ command = ctestCommands[i];
+ output = "";
+ retVal = 0;
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Run ctest command: "
+ << command.c_str() << std::endl);
+ res = cmSystemTools::RunSingleCommand(command.c_str(), &output,
+ &retVal, this->BinaryDir.c_str(), this->HandlerVerbose,
+ 0 /*this->TimeOut*/);
+
+ // did something critical fail in ctest
+ if (!res || cmakeFailed ||
+ retVal & cmCTest::BUILD_ERRORS)
+ {
+ this->RestoreBackupDirectories();
+ if (cmakeFailed)
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Unable to run cmake:" << std::endl
+ << cmakeFailedOuput.c_str() << 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);
+ if (!res)
+ {
+ return 11;
+ }
+ return retVal * 100;
+ }
+ }
+
+ // 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());
+ }
+
+ return 0;
+}
+
+//-------------------------------------------------------------------------
+bool cmCTestScriptHandler::WriteInitialCache(const char* directory,
+ const char* text)
+{
+ std::string cacheFile = directory;
+ cacheFile += "/CMakeCache.txt";
+ cmGeneratedFileStream fout(cacheFile.c_str());
+ if(!fout)
+ {
+ return false;
+ }
+
+ if (text!=0)
+ {
+ fout.write(text, strlen(text));
+ }
+
+ // 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();
+ fout.close();
+ return true;
+}
+
+//-------------------------------------------------------------------------
+void cmCTestScriptHandler::RestoreBackupDirectories()
+{
+ // if we backed up the dirs and the build failed, then restore
+ // the backed up dirs
+ if (this->Backup)
+ {
+ // if for some reason those directories exist then first delete them
+ if (cmSystemTools::FileExists(this->SourceDir.c_str()))
+ {
+ cmSystemTools::RemoveADirectory(this->SourceDir.c_str());
+ }
+ if (cmSystemTools::FileExists(this->BinaryDir.c_str()))
+ {
+ cmSystemTools::RemoveADirectory(this->BinaryDir.c_str());
+ }
+ // rename the src and binary directories
+ rename(this->BackupSourceDir.c_str(), this->SourceDir.c_str());
+ rename(this->BackupBinaryDir.c_str(), this->BinaryDir.c_str());
+ }
+}
+
+bool cmCTestScriptHandler::RunScript(cmCTest* ctest, const char *sname,
+ bool InProcess, int* returnValue)
+{
+ cmCTestScriptHandler* sh = new cmCTestScriptHandler();
+ sh->SetCTestInstance(ctest);
+ sh->AddConfigurationScript(sname,InProcess);
+ int res = sh->ProcessHandler();
+ if(returnValue)
+ {
+ *returnValue = res;
+ }
+ delete sh;
+ return true;
+}
+
+bool cmCTestScriptHandler::EmptyBinaryDirectory(const char *sname)
+{
+ // try to avoid deleting root
+ if (!sname || strlen(sname) < 2)
+ {
+ return false;
+ }
+
+ // 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))
+ {
+ return false;
+ }
+ return true;
+}
+
+//-------------------------------------------------------------------------
+double cmCTestScriptHandler::GetRemainingTimeAllowed()
+{
+ if (!this->Makefile)
+ {
+ return 1.0e7;
+ }
+
+ const char *timelimitS
+ = this->Makefile->GetDefinition("CTEST_TIME_LIMIT");
+
+ if (!timelimitS)
+ {
+ return 1.0e7;
+ }
+
+ double timelimit = atof(timelimitS);
+
+ return timelimit - cmSystemTools::GetTime() + this->ScriptStartTime;
+}
diff --git a/Source/CTest/cmCTestScriptHandler.h b/Source/CTest/cmCTestScriptHandler.h
new file mode 100644
index 000000000..a7cf6ba65
--- /dev/null
+++ b/Source/CTest/cmCTestScriptHandler.h
@@ -0,0 +1,172 @@
+/*============================================================================
+ 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 cmCTestScriptHandler_h
+#define cmCTestScriptHandler_h
+
+
+#include "cmCTestGenericHandler.h"
+#include "cmListFileCache.h"
+
+class cmMakefile;
+class cmLocalGenerator;
+class cmGlobalGenerator;
+class cmake;
+class cmCTestCommand;
+
+/** \class cmCTestScriptHandler
+ * \brief A class that handles ctest -S invocations
+ *
+ * CTest script is controlled using several variables that script has to
+ * specify and some optional ones. Required ones are:
+ * CTEST_SOURCE_DIRECTORY - Source directory of the project
+ * CTEST_BINARY_DIRECTORY - Binary directory of the project
+ * CTEST_COMMAND - Testing commands
+ *
+ * Optional variables are:
+ * CTEST_BACKUP_AND_RESTORE
+ * CTEST_CMAKE_COMMAND
+ * CTEST_CMAKE_OUTPUT_FILE_NAME
+ * CTEST_CONTINUOUS_DURATION
+ * CTEST_CONTINUOUS_MINIMUM_INTERVAL
+ * CTEST_CVS_CHECKOUT
+ * CTEST_CVS_COMMAND
+ * CTEST_UPDATE_COMMAND
+ * CTEST_DASHBOARD_ROOT
+ * CTEST_ENVIRONMENT
+ * CTEST_INITIAL_CACHE
+ * CTEST_START_WITH_EMPTY_BINARY_DIRECTORY
+ * CTEST_START_WITH_EMPTY_BINARY_DIRECTORY_ONCE
+ *
+ * In addition the following variables can be used. The number can be 1-10.
+ * CTEST_EXTRA_UPDATES_1
+ * CTEST_EXTRA_UPDATES_2
+ * ...
+ * CTEST_EXTRA_UPDATES_10
+ *
+ * CTest script can use the following arguments CTest provides:
+ * CTEST_SCRIPT_ARG
+ * CTEST_SCRIPT_DIRECTORY
+ * CTEST_SCRIPT_NAME
+ *
+ */
+class cmCTestScriptHandler : public cmCTestGenericHandler
+{
+public:
+ cmTypeMacro(cmCTestScriptHandler, cmCTestGenericHandler);
+
+ /**
+ * Add a script to run, and if is should run in the current process
+ */
+ void AddConfigurationScript(const char *, bool pscope);
+
+ /**
+ * Run a dashboard using a specified confiuration script
+ */
+ int ProcessHandler();
+
+ /*
+ * Run a script
+ */
+ static bool RunScript(cmCTest* ctest, const char *script, bool InProcess,
+ int* returnValue);
+ int RunCurrentScript();
+
+ /*
+ * Empty Binary Directory
+ */
+ static bool EmptyBinaryDirectory(const char *dir);
+
+ /*
+ * Write an initial CMakeCache.txt from the given contents.
+ */
+ static bool WriteInitialCache(const char* directory, const char* text);
+
+ /*
+ * Some elapsed time handling functions
+ */
+ static void SleepInSeconds(unsigned int secondsToWait);
+ void UpdateElapsedTime();
+
+ /**
+ * Return the time remaianing that the script is allowed to run in
+ * seconds if the user has set the variable CTEST_TIME_LIMIT. If that has
+ * not been set it returns 1e7 seconds
+ */
+ double GetRemainingTimeAllowed();
+
+ cmCTestScriptHandler();
+ ~cmCTestScriptHandler();
+
+ void Initialize();
+
+ void CreateCMake();
+ void GetCommandDocumentation(std::vector<cmDocumentationEntry>& v) const;
+ cmake* GetCMake() { return this->CMake;}
+private:
+ // reads in a script
+ int ReadInScript(const std::string& total_script_arg);
+ int ExecuteScript(const std::string& total_script_arg);
+
+ // extract vars from the script to set ivars
+ int ExtractVariables();
+
+ // perform a CVS checkout of the source dir
+ int CheckOutSourceDir();
+
+ // perform any extra cvs updates that were requested
+ int PerformExtraUpdates();
+
+ // backup and restore dirs
+ int BackupDirectories();
+ void RestoreBackupDirectories();
+
+ int RunConfigurationScript(const std::string& script, bool pscope);
+ int RunConfigurationDashboard();
+
+ // Add ctest command
+ void AddCTestCommand(cmCTestCommand* command);
+
+ std::vector<cmStdString> 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;
+
+ double MinimumInterval;
+ double ContinuousDuration;
+
+ // what time in seconds did this script start running
+ double ScriptStartTime;
+
+ cmMakefile *Makefile;
+ cmLocalGenerator *LocalGenerator;
+ cmGlobalGenerator *GlobalGenerator;
+ cmake *CMake;
+};
+
+#endif
diff --git a/Source/CTest/cmCTestSleepCommand.cxx b/Source/CTest/cmCTestSleepCommand.cxx
new file mode 100644
index 000000000..5b0697219
--- /dev/null
+++ b/Source/CTest/cmCTestSleepCommand.cxx
@@ -0,0 +1,55 @@
+/*============================================================================
+ 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 "cmCTestSleepCommand.h"
+
+#include "cmCTestScriptHandler.h"
+#include <stdlib.h> // required for atoi
+
+bool cmCTestSleepCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if (args.size() < 1)
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ // sleep for specified seconds
+ unsigned int time1 = atoi(args[0].c_str());
+ if(args.size() == 1 )
+ {
+ cmCTestScriptHandler::SleepInSeconds(time1);
+ // update the elapsed time since it could have slept for a while
+ this->CTestScriptHandler->UpdateElapsedTime();
+ return true;
+ }
+
+ // sleep up to a duration
+ if(args.size() == 3 )
+ {
+ unsigned int duration = atoi(args[1].c_str());
+ unsigned int time2 = atoi(args[2].c_str());
+ if (time1 + duration > time2)
+ {
+ duration = (time1 + duration - time2);
+ cmCTestScriptHandler::SleepInSeconds(duration);
+ // update the elapsed time since it could have slept for a while
+ this->CTestScriptHandler->UpdateElapsedTime();
+ }
+ return true;
+ }
+
+ this->SetError("called with incorrect number of arguments");
+ return false;
+}
+
+
diff --git a/Source/CTest/cmCTestSleepCommand.h b/Source/CTest/cmCTestSleepCommand.h
new file mode 100644
index 000000000..80fd6afb7
--- /dev/null
+++ b/Source/CTest/cmCTestSleepCommand.h
@@ -0,0 +1,77 @@
+/*============================================================================
+ 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 cmCTestSleepCommand_h
+#define cmCTestSleepCommand_h
+
+#include "cmCTestCommand.h"
+
+/** \class cmCTestSleep
+ * \brief Run a ctest script
+ *
+ * cmLibrarysCommand defines a list of executable (i.e., test)
+ * programs to create.
+ */
+class cmCTestSleepCommand : public cmCTestCommand
+{
+public:
+
+ cmCTestSleepCommand() {}
+
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ cmCTestSleepCommand* ni = new cmCTestSleepCommand;
+ ni->CTest = this->CTest;
+ ni->CTestScriptHandler = this->CTestScriptHandler;
+ return ni;
+ }
+
+ /**
+ * 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 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.";
+ }
+
+ cmTypeMacro(cmCTestSleepCommand, cmCTestCommand);
+
+};
+
+
+#endif
diff --git a/Source/CTest/cmCTestStartCommand.cxx b/Source/CTest/cmCTestStartCommand.cxx
new file mode 100644
index 000000000..228a17300
--- /dev/null
+++ b/Source/CTest/cmCTestStartCommand.cxx
@@ -0,0 +1,170 @@
+/*============================================================================
+ 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 "cmCTestStartCommand.h"
+
+#include "cmCTest.h"
+#include "cmLocalGenerator.h"
+#include "cmGlobalGenerator.h"
+#include "cmCTestVC.h"
+#include "cmGeneratedFileStream.h"
+
+cmCTestStartCommand::cmCTestStartCommand()
+{
+ this->CreateNewTag = true;
+}
+
+bool cmCTestStartCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if (args.size() < 1)
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ size_t cnt = 0;
+ const char* smodel = args[cnt].c_str();
+ const char* src_dir = 0;
+ const char* bld_dir = 0;
+
+ cnt++;
+
+ this->CTest->SetSpecificTrack(0);
+ if ( cnt < args.size() -1 )
+ {
+ if ( args[cnt] == "TRACK" )
+ {
+ cnt ++;
+ this->CTest->SetSpecificTrack(args[cnt].c_str());
+ cnt ++;
+ }
+ }
+
+ if (cnt < args.size())
+ {
+ if (args[cnt] == "APPEND")
+ {
+ cnt ++;
+ this->CreateNewTag = false;
+ }
+ }
+
+ if ( cnt < args.size() )
+ {
+ src_dir = args[cnt].c_str();
+ cnt ++;
+ if ( cnt < args.size() )
+ {
+ bld_dir = args[cnt].c_str();
+ }
+ }
+ if ( !src_dir )
+ {
+ src_dir = this->Makefile->GetDefinition("CTEST_SOURCE_DIRECTORY");
+ }
+ if ( !bld_dir)
+ {
+ bld_dir = this->Makefile->GetDefinition("CTEST_BINARY_DIRECTORY");
+ }
+ if ( !src_dir )
+ {
+ this->SetError("source directory not specified. Specify source directory "
+ "as an argument or set CTEST_SOURCE_DIRECTORY");
+ return false;
+ }
+ if ( !bld_dir)
+ {
+ this->SetError("binary directory not specified. Specify binary directory "
+ "as an argument or set CTEST_BINARY_DIRECTORY");
+ return false;
+ }
+
+ cmSystemTools::AddKeepPath(src_dir);
+ cmSystemTools::AddKeepPath(bld_dir);
+
+ this->CTest->EmptyCTestConfiguration();
+
+ 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());
+
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, "Run dashboard with model "
+ << smodel << std::endl
+ << " Source directory: " << src_dir << std::endl
+ << " Build directory: " << bld_dir << std::endl);
+ const char* track = this->CTest->GetSpecificTrack();
+ if ( track )
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ " Track: " << track << std::endl);
+ }
+
+ // Log startup actions.
+ std::string startLogFile = binaryDir + "/Testing/Temporary/LastStart.log";
+ cmGeneratedFileStream ofs(startLogFile.c_str());
+ if(!ofs)
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Cannot create log file: LastStart.log" << std::endl);
+ return false;
+ }
+
+ // Make sure the source directory exists.
+ if(!this->InitialCheckout(ofs, sourceDir))
+ {
+ return false;
+ }
+ if(!cmSystemTools::FileIsDirectory(sourceDir.c_str()))
+ {
+ cmOStringStream 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());
+ return false;
+ }
+
+ this->Makefile->AddDefinition("CTEST_RUN_CURRENT_SCRIPT", "OFF");
+ this->CTest->SetSuppressUpdatingCTestConfiguration(true);
+ int model = this->CTest->GetTestModelFromString(smodel);
+ this->CTest->SetTestModel(model);
+ this->CTest->SetProduceXML(true);
+
+ return this->CTest->InitializeFromCommand(this);
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestStartCommand::InitialCheckout(
+ std::ostream& ofs, std::string const& sourceDir)
+{
+ // Use the user-provided command to create the source tree.
+ const char* initialCheckoutCommand
+ = this->Makefile->GetDefinition("CTEST_CHECKOUT_COMMAND");
+ if(!initialCheckoutCommand)
+ {
+ initialCheckoutCommand =
+ this->Makefile->GetDefinition("CTEST_CVS_CHECKOUT");
+ }
+ if(initialCheckoutCommand)
+ {
+ // Use a generic VC object to run and log the command.
+ cmCTestVC vc(this->CTest, ofs);
+ vc.SetSourceDirectory(sourceDir.c_str());
+ if(!vc.InitialCheckout(initialCheckoutCommand))
+ {
+ return false;
+ }
+ }
+ return true;
+}
diff --git a/Source/CTest/cmCTestStartCommand.h b/Source/CTest/cmCTestStartCommand.h
new file mode 100644
index 000000000..6be47703e
--- /dev/null
+++ b/Source/CTest/cmCTestStartCommand.h
@@ -0,0 +1,92 @@
+/*============================================================================
+ 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 cmCTestStartCommand_h
+#define cmCTestStartCommand_h
+
+#include "cmCTestCommand.h"
+
+/** \class cmCTestStart
+ * \brief Run a ctest script
+ *
+ * cmCTestStartCommand defineds the command to start the nightly testing.
+ */
+class cmCTestStartCommand : public cmCTestCommand
+{
+public:
+
+ cmCTestStartCommand();
+
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ cmCTestStartCommand* ni = new cmCTestStartCommand;
+ ni->CTest = this->CTest;
+ ni->CTestScriptHandler = this->CTestScriptHandler;
+ ni->CreateNewTag = this->CreateNewTag;
+ return ni;
+ }
+
+ /**
+ * 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);
+
+ /**
+ * Will this invocation of ctest_start create a new TAG file?
+ */
+ bool ShouldCreateNewTag()
+ {
+ return this->CreateNewTag;
+ }
+
+ /**
+ * The name of the command as specified in CMakeList.txt.
+ */
+ virtual const char* GetName() const { return "ctest_start";}
+
+ /**
+ * Succinct documentation.
+ */
+ virtual const char* GetTerseDocumentation() const
+ {
+ return "Starts the testing for a given model";
+ }
+
+ /**
+ * More documentation.
+ */
+ 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.";
+ }
+
+ cmTypeMacro(cmCTestStartCommand, cmCTestCommand);
+
+private:
+ bool InitialCheckout(std::ostream& ofs, std::string const& sourceDir);
+ bool CreateNewTag;
+};
+
+
+#endif
diff --git a/Source/CTest/cmCTestSubmitCommand.cxx b/Source/CTest/cmCTestSubmitCommand.cxx
new file mode 100644
index 000000000..24974e3bc
--- /dev/null
+++ b/Source/CTest/cmCTestSubmitCommand.cxx
@@ -0,0 +1,255 @@
+/*============================================================================
+ 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 "cmCTestSubmitCommand.h"
+
+#include "cmCTest.h"
+#include "cmCTestGenericHandler.h"
+#include "cmCTestSubmitHandler.h"
+
+cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler()
+{
+ const char* ctestDropMethod
+ = this->Makefile->GetDefinition("CTEST_DROP_METHOD");
+ const char* ctestDropSite
+ = this->Makefile->GetDefinition("CTEST_DROP_SITE");
+ const char* ctestDropLocation
+ = this->Makefile->GetDefinition("CTEST_DROP_LOCATION");
+ const char* ctestTriggerSite
+ = this->Makefile->GetDefinition("CTEST_TRIGGER_SITE");
+ bool ctestDropSiteCDash
+ = this->Makefile->IsOn("CTEST_DROP_SITE_CDASH");
+
+ if ( !ctestDropMethod )
+ {
+ ctestDropMethod = "http";
+ }
+
+ if ( !ctestDropSite )
+ {
+ // error: CDash requires CTEST_DROP_SITE definition
+ // in CTestConfig.cmake
+ }
+ if ( !ctestDropLocation )
+ {
+ // 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("IsCDash",
+ ctestDropSiteCDash ? "TRUE" : "FALSE");
+
+ // Only propagate TriggerSite for non-CDash projects:
+ //
+ if ( !ctestDropSiteCDash )
+ {
+ this->CTest->SetCTestConfiguration("TriggerSite", ctestTriggerSite);
+ }
+
+ this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
+ "CurlOptions", "CTEST_CURL_OPTIONS");
+ this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
+ "DropSiteUser", "CTEST_DROP_SITE_USER");
+ this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
+ "DropSitePassword", "CTEST_DROP_SITE_PASSWORD");
+ this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
+ "ScpCommand", "CTEST_SCP_COMMAND");
+
+ const char* notesFilesVariable
+ = this->Makefile->GetDefinition("CTEST_NOTES_FILES");
+ if (notesFilesVariable)
+ {
+ std::vector<std::string> notesFiles;
+ std::vector<cmStdString> newNotesFiles;
+ cmSystemTools::ExpandListArgument(notesFilesVariable,notesFiles);
+ std::vector<std::string>::iterator it;
+ for ( it = notesFiles.begin();
+ it != notesFiles.end();
+ ++ it )
+ {
+ newNotesFiles.push_back(*it);
+ }
+ this->CTest->GenerateNotesFile(newNotesFiles);
+ }
+
+ const char* extraFilesVariable
+ = this->Makefile->GetDefinition("CTEST_EXTRA_SUBMIT_FILES");
+ if (extraFilesVariable)
+ {
+ std::vector<std::string> extraFiles;
+ std::vector<cmStdString> newExtraFiles;
+ cmSystemTools::ExpandListArgument(extraFilesVariable,extraFiles);
+ std::vector<std::string>::iterator it;
+ for ( it = extraFiles.begin();
+ it != extraFiles.end();
+ ++ it )
+ {
+ newExtraFiles.push_back(*it);
+ }
+ if ( !this->CTest->SubmitExtraFiles(newExtraFiles))
+ {
+ this->SetError("problem submitting extra files.");
+ return 0;
+ }
+ }
+
+ cmCTestGenericHandler* handler
+ = this->CTest->GetInitializedHandler("submit");
+ if ( !handler )
+ {
+ this->SetError("internal CTest error. Cannot instantiate submit handler");
+ return 0;
+ }
+
+ // If no FILES or PARTS given, *all* PARTS are submitted by default.
+ //
+ // If FILES are given, but not PARTS, only the FILES are submitted
+ // and *no* PARTS are submitted.
+ // (This is why we select the empty "noParts" set in the
+ // FilesMentioned block below...)
+ //
+ // If PARTS are given, only the selected PARTS are submitted.
+ //
+ // If both PARTS and FILES are given, only the selected PARTS *and*
+ // all the given FILES are submitted.
+
+ // If given explicit FILES to submit, pass them to the handler.
+ //
+ if(this->FilesMentioned)
+ {
+ // Intentionally select *no* PARTS. (Pass an empty set.) If PARTS
+ // were also explicitly mentioned, they will be selected below...
+ // But FILES with no PARTS mentioned should just submit the FILES
+ // without any of the default parts.
+ //
+ std::set<cmCTest::Part> noParts;
+ static_cast<cmCTestSubmitHandler*>(handler)->SelectParts(noParts);
+
+ static_cast<cmCTestSubmitHandler*>(handler)->SelectFiles(this->Files);
+ }
+
+ // If a PARTS option was given, select only the named parts for submission.
+ //
+ if(this->PartsMentioned)
+ {
+ static_cast<cmCTestSubmitHandler*>(handler)->SelectParts(this->Parts);
+ }
+
+ static_cast<cmCTestSubmitHandler*>(handler)->SetOption("RetryDelay",
+ this->RetryDelay.c_str());
+ static_cast<cmCTestSubmitHandler*>(handler)->SetOption("RetryCount",
+ this->RetryCount.c_str());
+ static_cast<cmCTestSubmitHandler*>(handler)->SetOption("InternalTest",
+ this->InternalTest ? "ON" : "OFF");
+
+ return handler;
+}
+
+
+//----------------------------------------------------------------------------
+bool cmCTestSubmitCommand::CheckArgumentKeyword(std::string const& arg)
+{
+ // Look for arguments specific to this command.
+ if(arg == "PARTS")
+ {
+ this->ArgumentDoing = ArgumentDoingParts;
+ this->PartsMentioned = true;
+ return true;
+ }
+
+ if(arg == "FILES")
+ {
+ this->ArgumentDoing = ArgumentDoingFiles;
+ this->FilesMentioned = 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.
+ return this->Superclass::CheckArgumentKeyword(arg);
+}
+
+
+//----------------------------------------------------------------------------
+bool cmCTestSubmitCommand::CheckArgumentValue(std::string const& arg)
+{
+ // Handle states specific to this command.
+ if(this->ArgumentDoing == ArgumentDoingParts)
+ {
+ cmCTest::Part p = this->CTest->GetPartFromName(arg.c_str());
+ if(p != cmCTest::PartCount)
+ {
+ this->Parts.insert(p);
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "Part name \"" << arg << "\" is invalid.";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ this->ArgumentDoing = ArgumentDoingError;
+ }
+ return true;
+ }
+
+ if(this->ArgumentDoing == ArgumentDoingFiles)
+ {
+ cmStdString filename(arg);
+ if(cmSystemTools::FileExists(filename.c_str()))
+ {
+ this->Files.insert(filename);
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "File \"" << filename << "\" does not exist. Cannot submit "
+ << "a non-existent file.";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ this->ArgumentDoing = ArgumentDoingError;
+ }
+ return true;
+ }
+
+ if(this->ArgumentDoing == ArgumentDoingRetryCount)
+ {
+ this->RetryCount = arg;
+ return true;
+ }
+
+ if(this->ArgumentDoing == ArgumentDoingRetryDelay)
+ {
+ this->RetryDelay = arg;
+ return true;
+ }
+
+ // Look for other arguments.
+ return this->Superclass::CheckArgumentValue(arg);
+}
diff --git a/Source/CTest/cmCTestSubmitCommand.h b/Source/CTest/cmCTestSubmitCommand.h
new file mode 100644
index 000000000..53ee8754e
--- /dev/null
+++ b/Source/CTest/cmCTestSubmitCommand.h
@@ -0,0 +1,118 @@
+/*============================================================================
+ 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 cmCTestSubmitCommand_h
+#define cmCTestSubmitCommand_h
+
+#include "cmCTestHandlerCommand.h"
+#include "cmCTest.h"
+
+/** \class cmCTestSubmit
+ * \brief Run a ctest script
+ *
+ * cmCTestSubmitCommand defineds the command to submit the test results for
+ * the project.
+ */
+class cmCTestSubmitCommand : public cmCTestHandlerCommand
+{
+public:
+
+ cmCTestSubmitCommand()
+ {
+ this->PartsMentioned = false;
+ this->FilesMentioned = false;
+ this->InternalTest = false;
+ this->RetryCount = "";
+ this->RetryDelay = "";
+ }
+
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ cmCTestSubmitCommand* ni = new cmCTestSubmitCommand;
+ ni->CTest = this->CTest;
+ ni->CTestScriptHandler = this->CTestScriptHandler;
+ return ni;
+ }
+
+ /**
+ * The name of the command as specified in CMakeList.txt.
+ */
+ virtual const char* GetName() const { return "ctest_submit";}
+
+ /**
+ * Succinct documentation.
+ */
+ virtual const char* GetTerseDocumentation() const
+ {
+ return "Submit results to a dashboard server.";
+ }
+
+ /**
+ * More documentation.
+ */
+ 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";
+ }
+
+ cmTypeMacro(cmCTestSubmitCommand, cmCTestHandlerCommand);
+
+protected:
+ cmCTestGenericHandler* InitializeHandler();
+
+ virtual bool CheckArgumentKeyword(std::string const& arg);
+ virtual bool CheckArgumentValue(std::string const& arg);
+
+ enum
+ {
+ ArgumentDoingParts = Superclass::ArgumentDoingLast1,
+ ArgumentDoingFiles,
+ ArgumentDoingRetryDelay,
+ ArgumentDoingRetryCount,
+ ArgumentDoingLast2
+ };
+
+ bool PartsMentioned;
+ std::set<cmCTest::Part> Parts;
+ bool FilesMentioned;
+ bool InternalTest;
+ cmCTest::SetOfStrings Files;
+ std::string RetryCount;
+ std::string RetryDelay;
+};
+
+
+#endif
diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx
new file mode 100644
index 000000000..142bb4613
--- /dev/null
+++ b/Source/CTest/cmCTestSubmitHandler.cxx
@@ -0,0 +1,1508 @@
+/*============================================================================
+ 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 "cmCTestSubmitHandler.h"
+
+#include "cmSystemTools.h"
+#include "cmVersion.h"
+#include "cmGeneratedFileStream.h"
+#include "cmCTest.h"
+#include "cmXMLParser.h"
+
+#include <cmsys/Process.h>
+#include <cmsys/Base64.h>
+
+// For XML-RPC submission
+#include "cm_xmlrpc.h"
+
+// For curl submission
+#include "cm_curl.h"
+
+#include <sys/stat.h>
+
+#define SUBMIT_TIMEOUT_IN_SECONDS_DEFAULT 120
+
+typedef std::vector<char> cmCTestSubmitHandlerVectorOfChar;
+
+//----------------------------------------------------------------------------
+class cmCTestSubmitHandler::ResponseParser: public cmXMLParser
+{
+public:
+ ResponseParser() { this->Status = STATUS_OK; }
+ ~ResponseParser() {}
+
+public:
+
+ enum StatusType
+ {
+ STATUS_OK,
+ STATUS_WARNING,
+ STATUS_ERROR
+ };
+
+ StatusType Status;
+ std::string CDashVersion;
+ std::string Filename;
+ std::string MD5;
+ std::string Message;
+
+private:
+
+ std::vector<char> CurrentValue;
+
+ std::string GetCurrentValue()
+ {
+ std::string val;
+ if(this->CurrentValue.size())
+ {
+ val.assign(&this->CurrentValue[0], this->CurrentValue.size());
+ }
+ return val;
+ }
+
+ virtual void StartElement(const char* name, const char** atts)
+ {
+ this->CurrentValue.clear();
+ if(strcmp(name, "cdash") == 0)
+ {
+ this->CDashVersion = this->FindAttribute(atts, "version");
+ }
+ }
+
+ virtual void CharacterDataHandler(const char* data, int length)
+ {
+ this->CurrentValue.insert(this->CurrentValue.end(), data, data+length);
+ }
+
+ virtual void EndElement(const char* name)
+ {
+ if(strcmp(name, "status") == 0)
+ {
+ std::string status = cmSystemTools::UpperCase(this->GetCurrentValue());
+ if(status == "OK" || status == "SUCCESS")
+ {
+ this->Status = STATUS_OK;
+ }
+ else if(status == "WARNING")
+ {
+ this->Status = STATUS_WARNING;
+ }
+ else
+ {
+ this->Status = STATUS_ERROR;
+ }
+ }
+ else if(strcmp(name, "filename") == 0)
+ {
+ this->Filename = this->GetCurrentValue();
+ }
+ else if(strcmp(name, "md5") == 0)
+ {
+ this->MD5 = this->GetCurrentValue();
+ }
+ else if(strcmp(name, "message") == 0)
+ {
+ this->Message = this->GetCurrentValue();
+ }
+ }
+};
+
+
+static size_t
+cmCTestSubmitHandlerWriteMemoryCallback(void *ptr, size_t size, size_t nmemb,
+ void *data)
+{
+ register int realsize = (int)(size * nmemb);
+
+ cmCTestSubmitHandlerVectorOfChar *vec
+ = static_cast<cmCTestSubmitHandlerVectorOfChar*>(data);
+ const char* chPtr = static_cast<char*>(ptr);
+ vec->insert(vec->end(), chPtr, chPtr + realsize);
+
+ return realsize;
+}
+
+static size_t
+cmCTestSubmitHandlerCurlDebugCallback(CURL *, curl_infotype, char *chPtr,
+ size_t size, void *data)
+{
+ cmCTestSubmitHandlerVectorOfChar *vec
+ = static_cast<cmCTestSubmitHandlerVectorOfChar*>(data);
+ vec->insert(vec->end(), chPtr, chPtr + size);
+
+ return size;
+}
+
+//----------------------------------------------------------------------------
+cmCTestSubmitHandler::cmCTestSubmitHandler() : HTTPProxy(), FTPProxy()
+{
+ this->Initialize();
+}
+
+//----------------------------------------------------------------------------
+void cmCTestSubmitHandler::Initialize()
+{
+ // We submit all available parts by default.
+ for(cmCTest::Part p = cmCTest::PartStart;
+ p != cmCTest::PartCount; p = cmCTest::Part(p+1))
+ {
+ this->SubmitPart[p] = true;
+ }
+ this->CDash = false;
+ this->HasWarnings = false;
+ this->HasErrors = false;
+ this->Superclass::Initialize();
+ this->HTTPProxy = "";
+ this->HTTPProxyType = 0;
+ this->HTTPProxyAuth = "";
+ this->FTPProxy = "";
+ this->FTPProxyType = 0;
+ this->LogFile = 0;
+ this->Files.clear();
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestSubmitHandler::SubmitUsingFTP(const cmStdString& localprefix,
+ const std::set<cmStdString>& files,
+ const cmStdString& remoteprefix,
+ const cmStdString& url)
+{
+ CURL *curl;
+ CURLcode res;
+ FILE* ftpfile;
+ char error_buffer[1024];
+
+ /* In windows, this will init the winsock stuff */
+ ::curl_global_init(CURL_GLOBAL_ALL);
+
+ cmCTest::SetOfStrings::const_iterator file;
+ for ( file = files.begin(); file != files.end(); ++file )
+ {
+ /* get a curl handle */
+ curl = curl_easy_init();
+ if(curl)
+ {
+ // Using proxy
+ if ( this->FTPProxyType > 0 )
+ {
+ curl_easy_setopt(curl, CURLOPT_PROXY, this->FTPProxy.c_str());
+ switch (this->FTPProxyType)
+ {
+ case 2:
+ curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4);
+ break;
+ case 3:
+ curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
+ break;
+ default:
+ curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
+ }
+ }
+
+ // enable uploading
+ ::curl_easy_setopt(curl, CURLOPT_UPLOAD, 1);
+
+ // if there is little to no activity for too long stop submitting
+ ::curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, 1);
+ ::curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME,
+ SUBMIT_TIMEOUT_IN_SECONDS_DEFAULT);
+
+ ::curl_easy_setopt(curl, CURLOPT_UPLOAD, 1);
+
+ cmStdString local_file = *file;
+ if ( !cmSystemTools::FileExists(local_file.c_str()) )
+ {
+ local_file = localprefix + "/" + *file;
+ }
+ cmStdString upload_as
+ = url + "/" + remoteprefix + cmSystemTools::GetFilenameName(*file);
+
+ struct stat st;
+ if ( ::stat(local_file.c_str(), &st) )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, " Cannot find file: "
+ << local_file.c_str() << std::endl);
+ ::curl_easy_cleanup(curl);
+ ::curl_global_cleanup();
+ return false;
+ }
+
+ 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);
+
+ ::curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
+
+ // specify target
+ ::curl_easy_setopt(curl,CURLOPT_URL, upload_as.c_str());
+
+ // now specify which file to upload
+ ::curl_easy_setopt(curl, CURLOPT_INFILE, ftpfile);
+
+ // and give the size of the upload (optional)
+ ::curl_easy_setopt(curl, CURLOPT_INFILESIZE,
+ static_cast<long>(st.st_size));
+
+ // and give curl the buffer for errors
+ ::curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, &error_buffer);
+
+ // specify handler for output
+ ::curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
+ cmCTestSubmitHandlerWriteMemoryCallback);
+ ::curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION,
+ cmCTestSubmitHandlerCurlDebugCallback);
+
+ /* we pass our 'chunk' struct to the callback function */
+ cmCTestSubmitHandlerVectorOfChar chunk;
+ cmCTestSubmitHandlerVectorOfChar chunkDebug;
+ ::curl_easy_setopt(curl, CURLOPT_FILE, (void *)&chunk);
+ ::curl_easy_setopt(curl, CURLOPT_DEBUGDATA, (void *)&chunkDebug);
+
+ // Now run off and do what you've been told!
+ res = ::curl_easy_perform(curl);
+
+ if ( chunk.size() > 0 )
+ {
+ cmCTestLog(this->CTest, DEBUG, "CURL output: ["
+ << cmCTestLogWrite(&*chunk.begin(), chunk.size()) << "]"
+ << std::endl);
+ }
+ if ( chunkDebug.size() > 0 )
+ {
+ cmCTestLog(this->CTest, DEBUG, "CURL debug output: ["
+ << cmCTestLogWrite(&*chunkDebug.begin(), chunkDebug.size()) << "]"
+ << std::endl);
+ }
+
+ fclose(ftpfile);
+ if ( res )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ " Error when uploading file: "
+ << local_file.c_str() << std::endl);
+ cmCTestLog(this->CTest, ERROR_MESSAGE, " Error message was: "
+ << error_buffer << std::endl);
+ *this->LogFile << " Error when uploading file: "
+ << local_file.c_str()
+ << std::endl
+ << " Error message was: "
+ << error_buffer << std::endl
+ << " Curl output was: ";
+ // avoid dereference of empty vector
+ if(chunk.size())
+ {
+ *this->LogFile << cmCTestLogWrite(&*chunk.begin(), chunk.size());
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "CURL output: ["
+ << cmCTestLogWrite(&*chunk.begin(), chunk.size()) << "]"
+ << std::endl);
+ }
+ *this->LogFile << std::endl;
+ ::curl_easy_cleanup(curl);
+ ::curl_global_cleanup();
+ return false;
+ }
+ // always cleanup
+ ::curl_easy_cleanup(curl);
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " Uploaded: " + local_file
+ << std::endl);
+ }
+ }
+ ::curl_global_cleanup();
+ return true;
+}
+
+//----------------------------------------------------------------------------
+// Uploading files is simpler
+bool cmCTestSubmitHandler::SubmitUsingHTTP(const cmStdString& localprefix,
+ const std::set<cmStdString>& files,
+ const cmStdString& remoteprefix,
+ const cmStdString& url)
+{
+ CURL *curl;
+ CURLcode res;
+ FILE* ftpfile;
+ char error_buffer[1024];
+
+ /* 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::vector<std::string> args;
+ cmSystemTools::ExpandListArgument(curlopt.c_str(), args);
+ bool verifyPeerOff = false;
+ bool verifyHostOff = false;
+ for( std::vector<std::string>::iterator i = args.begin();
+ i != args.end(); ++i)
+ {
+ if(*i == "CURLOPT_SSL_VERIFYPEER_OFF")
+ {
+ verifyPeerOff = true;
+ }
+ if(*i == "CURLOPT_SSL_VERIFYHOST_OFF")
+ {
+ verifyHostOff = true;
+ }
+ }
+ cmStdString::size_type kk;
+ cmCTest::SetOfStrings::const_iterator file;
+ for ( file = files.begin(); file != files.end(); ++file )
+ {
+ /* get a curl handle */
+ curl = curl_easy_init();
+ if(curl)
+ {
+ if(verifyPeerOff)
+ {
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " Set CURLOPT_SSL_VERIFYPEER to off\n");
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
+ }
+ if(verifyHostOff)
+ {
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ " Set CURLOPT_SSL_VERIFYHOST to off\n");
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
+ }
+
+ // Using proxy
+ if ( this->HTTPProxyType > 0 )
+ {
+ curl_easy_setopt(curl, CURLOPT_PROXY, this->HTTPProxy.c_str());
+ switch (this->HTTPProxyType)
+ {
+ case 2:
+ curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4);
+ break;
+ case 3:
+ curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
+ break;
+ default:
+ curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
+ if (this->HTTPProxyAuth.size() > 0)
+ {
+ curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD,
+ this->HTTPProxyAuth.c_str());
+ }
+ }
+ }
+ if(this->CTest->ShouldUseHTTP10())
+ {
+ curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ }
+ // enable HTTP ERROR parsing
+ curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);
+ /* enable uploading */
+ curl_easy_setopt(curl, CURLOPT_UPLOAD, 1);
+
+ // if there is little to no activity for too long stop submitting
+ ::curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, 1);
+ ::curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME,
+ SUBMIT_TIMEOUT_IN_SECONDS_DEFAULT);
+
+ /* HTTP PUT please */
+ ::curl_easy_setopt(curl, CURLOPT_PUT, 1);
+ ::curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
+
+ cmStdString local_file = *file;
+ if ( !cmSystemTools::FileExists(local_file.c_str()) )
+ {
+ local_file = localprefix + "/" + *file;
+ }
+ cmStdString remote_file
+ = remoteprefix + cmSystemTools::GetFilenameName(*file);
+
+ *this->LogFile << "\tUpload file: " << local_file.c_str() << " to "
+ << remote_file.c_str() << std::endl;
+
+ cmStdString ofile = "";
+ for ( kk = 0; kk < remote_file.size(); kk ++ )
+ {
+ char c = remote_file[kk];
+ char hexCh[4] = { 0, 0, 0, 0 };
+ hexCh[0] = c;
+ switch ( c )
+ {
+ case '+':
+ case '?':
+ case '/':
+ case '\\':
+ case '&':
+ case ' ':
+ case '=':
+ case '%':
+ sprintf(hexCh, "%%%02X", (int)c);
+ ofile.append(hexCh);
+ break;
+ default:
+ ofile.append(hexCh);
+ }
+ }
+ cmStdString upload_as
+ = url + ((url.find("?",0) == cmStdString::npos) ? "?" : "&")
+ + "FileName=" + ofile;
+
+ upload_as += "&MD5=";
+
+ if(cmSystemTools::IsOn(this->GetOption("InternalTest")))
+ {
+ upload_as += "bad_md5sum";
+ }
+ else
+ {
+ char md5[33];
+ cmSystemTools::ComputeFileMD5(local_file.c_str(), md5);
+ md5[32] = 0;
+ upload_as += md5;
+ }
+
+ struct stat st;
+ if ( ::stat(local_file.c_str(), &st) )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, " Cannot find file: "
+ << local_file.c_str() << std::endl);
+ ::curl_easy_cleanup(curl);
+ ::curl_global_cleanup();
+ return false;
+ }
+
+ 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);
+
+ // specify target
+ ::curl_easy_setopt(curl,CURLOPT_URL, upload_as.c_str());
+
+ // now specify which file to upload
+ ::curl_easy_setopt(curl, CURLOPT_INFILE, ftpfile);
+
+ // and give the size of the upload (optional)
+ ::curl_easy_setopt(curl, CURLOPT_INFILESIZE,
+ static_cast<long>(st.st_size));
+
+ // and give curl the buffer for errors
+ ::curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, &error_buffer);
+
+ // specify handler for output
+ ::curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
+ cmCTestSubmitHandlerWriteMemoryCallback);
+ ::curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION,
+ cmCTestSubmitHandlerCurlDebugCallback);
+
+ /* we pass our 'chunk' struct to the callback function */
+ cmCTestSubmitHandlerVectorOfChar chunk;
+ cmCTestSubmitHandlerVectorOfChar chunkDebug;
+ ::curl_easy_setopt(curl, CURLOPT_FILE, (void *)&chunk);
+ ::curl_easy_setopt(curl, CURLOPT_DEBUGDATA, (void *)&chunkDebug);
+
+ // Now run off and do what you've been told!
+ res = ::curl_easy_perform(curl);
+
+ if(cmSystemTools::IsOn(this->GetOption("InternalTest")) &&
+ cmSystemTools::VersionCompare(cmSystemTools::OP_LESS,
+ this->CTest->GetCDashVersion().c_str(), "1.7"))
+ {
+ // mock failure output for internal test case
+ std::string mock_output = "<cdash version=\"1.7.0\">\n"
+ " <status>ERROR</status>\n"
+ " <message>Checksum failed for file.</message>\n"
+ "</cdash>\n";
+ chunk.clear();
+ chunk.assign(mock_output.begin(), mock_output.end());
+ }
+
+ if ( chunk.size() > 0 )
+ {
+ cmCTestLog(this->CTest, DEBUG, "CURL output: ["
+ << cmCTestLogWrite(&*chunk.begin(), chunk.size()) << "]"
+ << std::endl);
+ this->ParseResponse(chunk);
+ }
+ if ( chunkDebug.size() > 0 )
+ {
+ cmCTestLog(this->CTest, DEBUG, "CURL debug output: ["
+ << cmCTestLogWrite(&*chunkDebug.begin(), chunkDebug.size()) << "]"
+ << std::endl);
+ }
+
+ // If curl failed for any reason, or checksum fails, wait and retry
+ //
+ if(res != CURLE_OK || this->HasErrors)
+ {
+ std::string retryDelay = this->GetOption("RetryDelay") == NULL ?
+ "" : this->GetOption("RetryDelay");
+ std::string retryCount = this->GetOption("RetryCount") == NULL ?
+ "" : this->GetOption("RetryCount");
+
+ int delay = retryDelay == "" ? atoi(this->CTest->GetCTestConfiguration(
+ "CTestSubmitRetryDelay").c_str()) : atoi(retryDelay.c_str());
+ int count = retryCount == "" ? atoi(this->CTest->GetCTestConfiguration(
+ "CTestSubmitRetryCount").c_str()) : atoi(retryCount.c_str());
+
+ for(int i = 0; i < count; i++)
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ " Submit failed, waiting " << delay << " seconds...\n");
+
+ double stop = cmSystemTools::GetTime() + delay;
+ while(cmSystemTools::GetTime() < stop)
+ {
+ cmSystemTools::Delay(100);
+ }
+
+ cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ " Retry submission: Attempt " << (i + 1) << " of "
+ << count << std::endl);
+
+ ::fclose(ftpfile);
+ ftpfile = ::fopen(local_file.c_str(), "rb");
+ ::curl_easy_setopt(curl, CURLOPT_INFILE, ftpfile);
+
+ chunk.clear();
+ chunkDebug.clear();
+ this->HasErrors = false;
+
+ res = ::curl_easy_perform(curl);
+
+ if ( chunk.size() > 0 )
+ {
+ cmCTestLog(this->CTest, DEBUG, "CURL output: ["
+ << cmCTestLogWrite(&*chunk.begin(), chunk.size()) << "]"
+ << std::endl);
+ this->ParseResponse(chunk);
+ }
+
+ if(res == CURLE_OK && !this->HasErrors)
+ {
+ break;
+ }
+ }
+ }
+
+ fclose(ftpfile);
+ if ( res )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ " Error when uploading file: "
+ << local_file.c_str() << std::endl);
+ cmCTestLog(this->CTest, ERROR_MESSAGE, " Error message was: "
+ << error_buffer << std::endl);
+ *this->LogFile << " Error when uploading file: "
+ << local_file.c_str()
+ << std::endl
+ << " Error message was: " << error_buffer
+ << std::endl;
+ // avoid deref of begin for zero size array
+ if(chunk.size())
+ {
+ *this->LogFile << " Curl output was: "
+ << cmCTestLogWrite(&*chunk.begin(), chunk.size())
+ << std::endl;
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "CURL output: ["
+ << cmCTestLogWrite(&*chunk.begin(), chunk.size()) << "]"
+ << std::endl);
+ }
+ ::curl_easy_cleanup(curl);
+ ::curl_global_cleanup();
+ return false;
+ }
+ // always cleanup
+ ::curl_easy_cleanup(curl);
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " Uploaded: " + local_file
+ << std::endl);
+ }
+ }
+ ::curl_global_cleanup();
+ return true;
+}
+
+//----------------------------------------------------------------------------
+void cmCTestSubmitHandler
+::ParseResponse(cmCTestSubmitHandlerVectorOfChar chunk)
+{
+ std::string output = "";
+ output.append(chunk.begin(), chunk.end());
+
+ if(output.find("<cdash") != output.npos)
+ {
+ ResponseParser parser;
+ parser.Parse(output.c_str());
+
+ if(parser.Status != ResponseParser::STATUS_OK)
+ {
+ this->HasErrors = true;
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " Submission failed: " <<
+ parser.Message << std::endl);
+ return;
+ }
+ }
+ output = cmSystemTools::UpperCase(output);
+ if(output.find("WARNING") != std::string::npos)
+ {
+ this->HasWarnings = true;
+ }
+ if(output.find("ERROR") != std::string::npos)
+ {
+ this->HasErrors = true;
+ }
+
+ if(this->HasWarnings || this->HasErrors)
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " Server Response:\n" <<
+ cmCTestLogWrite(&*chunk.begin(), chunk.size()) << "\n");
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestSubmitHandler::TriggerUsingHTTP(
+ const std::set<cmStdString>& files,
+ const cmStdString& remoteprefix,
+ const cmStdString& url)
+{
+ CURL *curl;
+ char error_buffer[1024];
+ /* In windows, this will init the winsock stuff */
+ ::curl_global_init(CURL_GLOBAL_ALL);
+
+ cmCTest::SetOfStrings::const_iterator file;
+ for ( file = files.begin(); file != files.end(); ++file )
+ {
+ /* get a curl handle */
+ curl = curl_easy_init();
+ if(curl)
+ {
+ // Using proxy
+ if ( this->HTTPProxyType > 0 )
+ {
+ curl_easy_setopt(curl, CURLOPT_PROXY, this->HTTPProxy.c_str());
+ switch (this->HTTPProxyType)
+ {
+ case 2:
+ curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4);
+ break;
+ case 3:
+ curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
+ break;
+ default:
+ curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
+ if (this->HTTPProxyAuth.size() > 0)
+ {
+ curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD,
+ this->HTTPProxyAuth.c_str());
+ }
+ }
+ }
+
+ ::curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
+
+ // and give curl the buffer for errors
+ ::curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, &error_buffer);
+
+ // specify handler for output
+ ::curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
+ cmCTestSubmitHandlerWriteMemoryCallback);
+ ::curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION,
+ cmCTestSubmitHandlerCurlDebugCallback);
+
+ /* we pass our 'chunk' struct to the callback function */
+ cmCTestSubmitHandlerVectorOfChar chunk;
+ cmCTestSubmitHandlerVectorOfChar chunkDebug;
+ ::curl_easy_setopt(curl, CURLOPT_FILE, (void *)&chunk);
+ ::curl_easy_setopt(curl, CURLOPT_DEBUGDATA, (void *)&chunkDebug);
+
+ cmStdString rfile
+ = remoteprefix + cmSystemTools::GetFilenameName(*file);
+ cmStdString ofile = "";
+ cmStdString::iterator kk;
+ for ( kk = rfile.begin(); kk < rfile.end(); ++ kk)
+ {
+ char c = *kk;
+ char hexCh[4] = { 0, 0, 0, 0 };
+ hexCh[0] = c;
+ switch ( c )
+ {
+ case '+':
+ case '?':
+ case '/':
+ case '\\':
+ case '&':
+ case ' ':
+ case '=':
+ case '%':
+ sprintf(hexCh, "%%%02X", (int)c);
+ ofile.append(hexCh);
+ break;
+ default:
+ ofile.append(hexCh);
+ }
+ }
+ cmStdString turl
+ = url + ((url.find("?",0) == cmStdString::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);
+ 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);
+ 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())
+ {
+ *this->LogFile
+ << " Curl output was: "
+ << cmCTestLogWrite(&*chunk.begin(), chunk.size()) << std::endl;
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "CURL output: ["
+ << cmCTestLogWrite(&*chunk.begin(), chunk.size()) << "]"
+ << std::endl);
+ }
+ ::curl_easy_cleanup(curl);
+ ::curl_global_cleanup();
+ return false;
+ }
+
+ if ( chunk.size() > 0 )
+ {
+ cmCTestLog(this->CTest, DEBUG, "CURL output: ["
+ << cmCTestLogWrite(&*chunk.begin(), chunk.size()) << "]"
+ << std::endl);
+ }
+ if ( chunkDebug.size() > 0 )
+ {
+ cmCTestLog(this->CTest, DEBUG, "CURL debug output: ["
+ << cmCTestLogWrite(&*chunkDebug.begin(), chunkDebug.size())
+ << "]" << std::endl);
+ }
+
+ // always cleanup
+ ::curl_easy_cleanup(curl);
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, std::endl);
+ }
+ }
+ ::curl_global_cleanup();
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " Dart server triggered..."
+ << std::endl);
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestSubmitHandler::SubmitUsingSCP(
+ const cmStdString& scp_command,
+ const cmStdString& localprefix,
+ const std::set<cmStdString>& files,
+ const cmStdString& remoteprefix,
+ const cmStdString& url)
+{
+ if ( !scp_command.size() || !localprefix.size() ||
+ !files.size() || !remoteprefix.size() || !url.size() )
+ {
+ 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
+ argv.push_back(scp_command.c_str()); // Dummy string for remote url
+ argv.push_back(0);
+
+ cmsysProcess* cp = cmsysProcess_New();
+ cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1);
+ //cmsysProcess_SetTimeout(cp, timeout);
+
+ int problems = 0;
+
+ cmCTest::SetOfStrings::const_iterator file;
+ for ( file = files.begin(); file != files.end(); ++file )
+ {
+ int retVal;
+
+ std::string lfname = localprefix;
+ cmSystemTools::ConvertToUnixSlashes(lfname);
+ lfname += "/" + *file;
+ lfname = cmSystemTools::ConvertToOutputPath(lfname.c_str());
+ 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);
+ *this->LogFile << "Execute \"" << argv[0] << "\" \"" << argv[1] << "\" \""
+ << argv[2] << "\"" << std::endl;
+
+ cmsysProcess_SetCommand(cp, &*argv.begin());
+ cmsysProcess_Execute(cp);
+ char* data;
+ int length;
+
+ while(cmsysProcess_WaitForData(cp, &data, &length, 0))
+ {
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ cmCTestLogWrite(data, length));
+ }
+
+ cmsysProcess_WaitForExit(cp, 0);
+
+ int result = cmsysProcess_GetState(cp);
+
+ if(result == cmsysProcess_State_Exited)
+ {
+ retVal = cmsysProcess_GetExitValue(cp);
+ if ( retVal != 0 )
+ {
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "\tSCP returned: "
+ << retVal << std::endl);
+ *this->LogFile << "\tSCP returned: " << retVal << std::endl;
+ problems ++;
+ }
+ }
+ else if(result == cmsysProcess_State_Exception)
+ {
+ retVal = cmsysProcess_GetExitException(cp);
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "\tThere was an exception: "
+ << retVal << std::endl);
+ *this->LogFile << "\tThere was an exception: " << retVal << std::endl;
+ problems ++;
+ }
+ else if(result == cmsysProcess_State_Expired)
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "\tThere was a timeout"
+ << std::endl);
+ *this->LogFile << "\tThere was a timeout" << std::endl;
+ problems ++;
+ }
+ else if(result == cmsysProcess_State_Error)
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "\tError executing SCP: "
+ << cmsysProcess_GetErrorString(cp) << std::endl);
+ *this->LogFile << "\tError executing SCP: "
+ << cmsysProcess_GetErrorString(cp) << std::endl;
+ problems ++;
+ }
+ }
+ cmsysProcess_Delete(cp);
+ if ( problems )
+ {
+ return false;
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestSubmitHandler::SubmitUsingCP(
+ const cmStdString& localprefix,
+ const std::set<cmStdString>& files,
+ const cmStdString& remoteprefix,
+ const cmStdString& destination)
+{
+ if ( !localprefix.size() ||
+ !files.size() || !remoteprefix.size() || !destination.size() )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Missing arguments for submit via cp:\n"
+ << "\tlocalprefix: " << localprefix << "\n"
+ << "\tNumber of files: " << files.size() << "\n"
+ << "\tremoteprefix: " << remoteprefix << "\n"
+ << "\tdestination: " << destination << std::endl);
+ return 0;
+ }
+ cmCTest::SetOfStrings::const_iterator file;
+ bool problems = false;
+ for ( file = files.begin(); file != files.end(); ++file )
+ {
+ std::string lfname = localprefix;
+ 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);
+ }
+ std::string tagDoneFile = destination + "/" + remoteprefix + "DONE";
+ cmSystemTools::Touch(tagDoneFile.c_str(), true);
+ if ( problems )
+ {
+ return false;
+ }
+ return true;
+}
+
+
+//----------------------------------------------------------------------------
+#if defined(CTEST_USE_XMLRPC)
+bool cmCTestSubmitHandler::SubmitUsingXMLRPC(const cmStdString& localprefix,
+ const std::set<cmStdString>& files,
+ const cmStdString& remoteprefix,
+ const cmStdString& 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/";
+
+ /* Start up our XML-RPC client library. */
+ xmlrpc_client_init(XMLRPC_CLIENT_NO_FLAGS, ctestString, ctestVersion);
+
+ /* Initialize our error-handling environment. */
+ 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);
+ cmCTest::SetOfStrings::const_iterator file;
+ for ( file = files.begin(); file != files.end(); ++file )
+ {
+ xmlrpc_value *result;
+
+ cmStdString 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);
+ struct stat st;
+ if ( ::stat(local_file.c_str(), &st) )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, " Cannot find file: "
+ << local_file.c_str() << std::endl);
+ return false;
+ }
+
+ // off_t can be bigger than size_t. fread takes size_t.
+ // make sure the file is not too big.
+ if(static_cast<off_t>(static_cast<size_t>(st.st_size)) !=
+ static_cast<off_t>(st.st_size))
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, " File too big: "
+ << local_file.c_str() << std::endl);
+ return false;
+ }
+ size_t fileSize = static_cast<size_t>(st.st_size);
+ FILE* fp = fopen(local_file.c_str(), "rb");
+ if ( !fp )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, " Cannot open file: "
+ << local_file.c_str() << std::endl);
+ return false;
+ }
+
+ unsigned char *fileBuffer = new unsigned char[fileSize];
+ if ( fread(fileBuffer, 1, fileSize, fp) != fileSize )
+ {
+ delete [] fileBuffer;
+ fclose(fp);
+ cmCTestLog(this->CTest, ERROR_MESSAGE, " Cannot read file: "
+ << local_file.c_str() << std::endl);
+ return false;
+ }
+ fclose(fp);
+
+ char remoteCommand[] = "Submit.put";
+ char* pRealURL = const_cast<char*>(realURL.c_str());
+ result = xmlrpc_client_call(&env, pRealURL, remoteCommand,
+ "(6)", fileBuffer, (xmlrpc_int32)fileSize );
+
+ delete [] fileBuffer;
+
+ if ( env.fault_occurred )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, " Submission problem: "
+ << env.fault_string << " (" << env.fault_code << ")" << std::endl);
+ xmlrpc_env_clean(&env);
+ xmlrpc_client_cleanup();
+ return false;
+ }
+
+ /* Dispose of our result value. */
+ xmlrpc_DECREF(result);
+ }
+
+ /* Clean up our error-handling environment. */
+ xmlrpc_env_clean(&env);
+
+ /* Shutdown our XML-RPC client library. */
+ xmlrpc_client_cleanup();
+ return true;
+}
+#else
+bool cmCTestSubmitHandler::SubmitUsingXMLRPC(cmStdString const&,
+ std::set<cmStdString> const&,
+ cmStdString const&,
+ cmStdString const&)
+{
+ return false;
+}
+#endif
+
+//----------------------------------------------------------------------------
+int cmCTestSubmitHandler::ProcessHandler()
+{
+ std::string iscdash = this->CTest->GetCTestConfiguration("IsCDash");
+ // cdash does not need to trigger so just return true
+ if(iscdash.size())
+ {
+ this->CDash = true;
+ }
+
+ const std::string &buildDirectory
+ = this->CTest->GetCTestConfiguration("BuildDirectory");
+ if ( buildDirectory.size() == 0 )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Cannot find BuildDirectory key in the DartConfiguration.tcl"
+ << std::endl);
+ return -1;
+ }
+
+ if ( getenv("HTTP_PROXY") )
+ {
+ this->HTTPProxyType = 1;
+ this->HTTPProxy = getenv("HTTP_PROXY");
+ if ( getenv("HTTP_PROXY_PORT") )
+ {
+ this->HTTPProxy += ":";
+ this->HTTPProxy += getenv("HTTP_PROXY_PORT");
+ }
+ if ( getenv("HTTP_PROXY_TYPE") )
+ {
+ cmStdString type = getenv("HTTP_PROXY_TYPE");
+ // HTTP/SOCKS4/SOCKS5
+ if ( type == "HTTP" )
+ {
+ this->HTTPProxyType = 1;
+ }
+ else if ( type == "SOCKS4" )
+ {
+ this->HTTPProxyType = 2;
+ }
+ else if ( type == "SOCKS5" )
+ {
+ this->HTTPProxyType = 3;
+ }
+ }
+ if ( getenv("HTTP_PROXY_USER") )
+ {
+ this->HTTPProxyAuth = getenv("HTTP_PROXY_USER");
+ }
+ if ( getenv("HTTP_PROXY_PASSWD") )
+ {
+ this->HTTPProxyAuth += ":";
+ this->HTTPProxyAuth += getenv("HTTP_PROXY_PASSWD");
+ }
+ }
+
+ if ( getenv("FTP_PROXY") )
+ {
+ this->FTPProxyType = 1;
+ this->FTPProxy = getenv("FTP_PROXY");
+ if ( getenv("FTP_PROXY_PORT") )
+ {
+ this->FTPProxy += ":";
+ this->FTPProxy += getenv("FTP_PROXY_PORT");
+ }
+ if ( getenv("FTP_PROXY_TYPE") )
+ {
+ cmStdString type = getenv("FTP_PROXY_TYPE");
+ // HTTP/SOCKS4/SOCKS5
+ if ( type == "HTTP" )
+ {
+ this->FTPProxyType = 1;
+ }
+ else if ( type == "SOCKS4" )
+ {
+ this->FTPProxyType = 2;
+ }
+ else if ( type == "SOCKS5" )
+ {
+ this->FTPProxyType = 3;
+ }
+ }
+ }
+
+ if ( this->HTTPProxy.size() > 0 )
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " Use HTTP Proxy: "
+ << this->HTTPProxy << std::endl);
+ }
+ if ( this->FTPProxy.size() > 0 )
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " Use FTP Proxy: "
+ << this->FTPProxy << std::endl);
+ }
+ cmGeneratedFileStream ofs;
+ this->StartLogFile("Submit", ofs);
+
+ cmCTest::SetOfStrings files;
+ std::string prefix = this->GetSubmitResultsPrefix();
+
+ if (!this->Files.empty())
+ {
+ // Submit the explicitly selected files:
+ //
+ cmCTest::SetOfStrings::const_iterator it;
+ for (it = this->Files.begin(); it != this->Files.end(); ++it)
+ {
+ files.insert(*it);
+ }
+ }
+
+ // Add to the list of files to submit from any selected, existing parts:
+ //
+
+ // TODO:
+ // Check if test is enabled
+
+ this->CTest->AddIfExists(cmCTest::PartUpdate, "Update.xml");
+ this->CTest->AddIfExists(cmCTest::PartConfigure, "Configure.xml");
+ this->CTest->AddIfExists(cmCTest::PartBuild, "Build.xml");
+ this->CTest->AddIfExists(cmCTest::PartTest, "Test.xml");
+ if(this->CTest->AddIfExists(cmCTest::PartCoverage, "Coverage.xml"))
+ {
+ cmCTest::VectorOfStrings 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);
+ 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);
+ this->CTest->AddSubmitFile(cmCTest::PartCoverage, gfiles[cc].c_str());
+ }
+ }
+ else
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Problem globbing" << std::endl);
+ }
+ }
+ this->CTest->AddIfExists(cmCTest::PartMemCheck, "DynamicAnalysis.xml");
+ this->CTest->AddIfExists(cmCTest::PartMemCheck, "Purify.xml");
+ this->CTest->AddIfExists(cmCTest::PartNotes, "Notes.xml");
+ this->CTest->AddIfExists(cmCTest::PartUpload, "Upload.xml");
+
+ // Query parts for files to submit.
+ for(cmCTest::Part p = cmCTest::PartStart;
+ p != cmCTest::PartCount; p = cmCTest::Part(p+1))
+ {
+ // Skip parts we are not submitting.
+ if(!this->SubmitPart[p])
+ {
+ continue;
+ }
+
+ // 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);
+ }
+ }
+
+ if ( ofs )
+ {
+ ofs << "Upload files:" << std::endl;
+ int cnt = 0;
+ cmCTest::SetOfStrings::iterator it;
+ for ( it = files.begin(); it != files.end(); ++ it )
+ {
+ ofs << cnt << "\t" << it->c_str() << std::endl;
+ cnt ++;
+ }
+ }
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, "Submit files (using "
+ << this->CTest->GetCTestConfiguration("DropMethod") << ")"
+ << std::endl);
+ const char* specificTrack = this->CTest->GetSpecificTrack();
+ if ( specificTrack )
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " Send to track: "
+ << specificTrack << std::endl);
+ }
+ this->SetLogFile(&ofs);
+
+ cmStdString 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://");
+ std::string url = "ftp://";
+ url += cmCTest::MakeURLSafe(
+ this->CTest->GetCTestConfiguration("DropSiteUser")) + ":" +
+ cmCTest::MakeURLSafe(this->CTest->GetCTestConfiguration(
+ "DropSitePassword")) + "@" +
+ this->CTest->GetCTestConfiguration("DropSite") +
+ cmCTest::MakeURLSafe(
+ this->CTest->GetCTestConfiguration("DropLocation"));
+ if ( this->CTest->GetCTestConfiguration("DropSiteUser").size() > 0 )
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ this->CTest->GetCTestConfiguration(
+ "DropSiteUser").c_str());
+ if ( this->CTest->GetCTestConfiguration("DropSitePassword").size() > 0 )
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, ":******");
+ }
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, "@");
+ }
+ cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ this->CTest->GetCTestConfiguration("DropSite")
+ << this->CTest->GetCTestConfiguration("DropLocation") << std::endl);
+ if ( !this->SubmitUsingFTP(buildDirectory + "/Testing/"
+ + this->CTest->GetCurrentTag(),
+ files, prefix, url) )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ " Problems when submitting via FTP"
+ << std::endl);
+ ofs << " Problems when submitting via FTP" << std::endl;
+ return -1;
+ }
+ if(!this->CDash)
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " Using HTTP trigger method"
+ << std::endl
+ << " Trigger site: "
+ << this->CTest->GetCTestConfiguration("TriggerSite")
+ << std::endl);
+ if ( !this->
+ TriggerUsingHTTP(files, prefix,
+ this->CTest->GetCTestConfiguration("TriggerSite")))
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ " Problems when triggering via HTTP" << std::endl);
+ ofs << " Problems when triggering via HTTP" << std::endl;
+ return -1;
+ }
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " Submission successful"
+ << std::endl);
+ ofs << " Submission successful" << std::endl;
+ return 0;
+ }
+ }
+ else if ( dropMethod == "http" || dropMethod == "https" )
+ {
+ 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 )
+ {
+ url += this->CTest->GetCTestConfiguration("DropSiteUser");
+ cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ this->CTest->GetCTestConfiguration("DropSiteUser").c_str());
+ if ( this->CTest->GetCTestConfiguration("DropSitePassword").size() > 0 )
+ {
+ url += ":" + this->CTest->GetCTestConfiguration("DropSitePassword");
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, ":******");
+ }
+ url += "@";
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, "@");
+ }
+ url += this->CTest->GetCTestConfiguration("DropSite") +
+ this->CTest->GetCTestConfiguration("DropLocation");
+ cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ this->CTest->GetCTestConfiguration("DropSite")
+ << this->CTest->GetCTestConfiguration("DropLocation") << std::endl);
+ if ( !this->SubmitUsingHTTP(buildDirectory + "/Testing/" +
+ this->CTest->GetCurrentTag(), files, prefix, url) )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ " Problems when submitting via HTTP" << std::endl);
+ ofs << " Problems when submitting via HTTP" << std::endl;
+ return -1;
+ }
+ if(!this->CDash)
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " Using HTTP trigger method"
+ << std::endl
+ << " Trigger site: "
+ << this->CTest->GetCTestConfiguration("TriggerSite")
+ << std::endl);
+ if ( !this->
+ TriggerUsingHTTP(files, prefix,
+ this->CTest->GetCTestConfiguration("TriggerSite")))
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ " Problems when triggering via HTTP" << std::endl);
+ ofs << " Problems when triggering via HTTP" << std::endl;
+ return -1;
+ }
+ }
+ if(this->HasErrors)
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " Errors occurred during "
+ "submission." << std::endl);
+ ofs << " Errors occurred during submission. " << std::endl;
+ }
+ else
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " Submission successful" <<
+ (this->HasWarnings ? ", with warnings." : "") << std::endl);
+ ofs << " Submission successful" <<
+ (this->HasWarnings ? ", with warnings." : "") << std::endl;
+ }
+
+ return 0;
+ }
+ else if ( dropMethod == "xmlrpc" )
+ {
+#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);
+ std::string url = this->CTest->GetCTestConfiguration("DropSite");
+ prefix = this->CTest->GetCTestConfiguration("DropLocation");
+ if ( !this->SubmitUsingXMLRPC(buildDirectory + "/Testing/" +
+ this->CTest->GetCurrentTag(), files, prefix, url) )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ " Problems when submitting via XML-RPC" << std::endl);
+ ofs << " Problems when submitting via XML-RPC" << std::endl;
+ return -1;
+ }
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " Submission successful"
+ << std::endl);
+ ofs << " Submission successful" << std::endl;
+ return 0;
+#else
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ " Submission method \"xmlrpc\" not compiled into CTest!"
+ << std::endl);
+ return -1;
+#endif
+ }
+ else if ( dropMethod == "scp" )
+ {
+ std::string url;
+ std::string oldWorkingDirectory;
+ if ( this->CTest->GetCTestConfiguration("DropSiteUser").size() > 0 )
+ {
+ url += this->CTest->GetCTestConfiguration("DropSiteUser") + "@";
+ }
+ url += this->CTest->GetCTestConfiguration("DropSite") + ":" +
+ this->CTest->GetCTestConfiguration("DropLocation");
+
+ // 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());
+
+ if ( !this->SubmitUsingSCP(
+ this->CTest->GetCTestConfiguration("ScpCommand"),
+ "Testing/"+this->CTest->GetCurrentTag(), files, prefix, url) )
+ {
+ cmSystemTools::ChangeDirectory(oldWorkingDirectory.c_str());
+ 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);
+ ofs << " Submission successful" << std::endl;
+ return 0;
+ }
+ else if ( dropMethod == "cp" )
+ {
+ std::string location
+ = this->CTest->GetCTestConfiguration("DropLocation");
+
+
+ // 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
+ std::string
+ oldWorkingDirectory = cmSystemTools::GetCurrentWorkingDirectory();
+ cmSystemTools::ChangeDirectory(buildDirectory.c_str());
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Change directory: "
+ << buildDirectory.c_str() << std::endl);
+
+ if ( !this->SubmitUsingCP(
+ "Testing/"+this->CTest->GetCurrentTag(),
+ files,
+ prefix,
+ location) )
+ {
+ cmSystemTools::ChangeDirectory(oldWorkingDirectory.c_str());
+ 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);
+ ofs << " Submission successful" << std::endl;
+ return 0;
+ }
+
+ cmCTestLog(this->CTest, ERROR_MESSAGE, " Unknown submission method: \""
+ << dropMethod << "\"" << std::endl);
+ return -1;
+}
+
+//----------------------------------------------------------------------------
+std::string cmCTestSubmitHandler::GetSubmitResultsPrefix()
+{
+ std::string name = this->CTest->GetCTestConfiguration("Site") +
+ "___" + this->CTest->GetCTestConfiguration("BuildName") +
+ "___" + this->CTest->GetCurrentTag() + "-" +
+ this->CTest->GetTestModelString() + "___XML___";
+ return name;
+}
+
+//----------------------------------------------------------------------------
+void cmCTestSubmitHandler::SelectParts(std::set<cmCTest::Part> const& parts)
+{
+ // Check whether each part is selected.
+ for(cmCTest::Part p = cmCTest::PartStart;
+ p != cmCTest::PartCount; p = cmCTest::Part(p+1))
+ {
+ this->SubmitPart[p] =
+ (std::set<cmCTest::Part>::const_iterator(parts.find(p)) != parts.end());
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmCTestSubmitHandler::SelectFiles(cmCTest::SetOfStrings const& files)
+{
+ cmCTest::SetOfStrings::const_iterator it;
+ for (it = files.begin(); it != files.end(); ++it)
+ {
+ this->Files.insert(*it);
+ }
+}
diff --git a/Source/CTest/cmCTestSubmitHandler.h b/Source/CTest/cmCTestSubmitHandler.h
new file mode 100644
index 000000000..14eac80b5
--- /dev/null
+++ b/Source/CTest/cmCTestSubmitHandler.h
@@ -0,0 +1,98 @@
+/*============================================================================
+ 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 cmCTestSubmitHandler_h
+#define cmCTestSubmitHandler_h
+
+#include "cmCTestGenericHandler.h"
+
+/** \class cmCTestSubmitHandler
+ * \brief Helper class for CTest
+ *
+ * Submit testing results
+ *
+ */
+class cmCTestSubmitHandler : public cmCTestGenericHandler
+{
+public:
+ cmTypeMacro(cmCTestSubmitHandler, cmCTestGenericHandler);
+
+ cmCTestSubmitHandler();
+ ~cmCTestSubmitHandler() { this->LogFile = 0; }
+
+ /*
+ * The main entry point for this class
+ */
+ int ProcessHandler();
+
+ void Initialize();
+
+ /** Specify a set of parts (by name) to submit. */
+ void SelectParts(std::set<cmCTest::Part> const& parts);
+
+ /** Specify a set of files to submit. */
+ void SelectFiles(cmCTest::SetOfStrings const& files);
+
+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);
+
+ typedef std::vector<char> cmCTestSubmitHandlerVectorOfChar;
+
+ void ParseResponse(cmCTestSubmitHandlerVectorOfChar chunk);
+
+ std::string GetSubmitResultsPrefix();
+
+ class ResponseParser;
+ cmStdString HTTPProxy;
+ int HTTPProxyType;
+ cmStdString HTTPProxyAuth;
+ cmStdString FTPProxy;
+ int FTPProxyType;
+ std::ostream* LogFile;
+ bool SubmitPart[cmCTest::PartCount];
+ bool CDash;
+ bool HasWarnings;
+ bool HasErrors;
+ cmCTest::SetOfStrings Files;
+};
+
+#endif
diff --git a/Source/CTest/cmCTestTestCommand.cxx b/Source/CTest/cmCTestTestCommand.cxx
new file mode 100644
index 000000000..5aee035c7
--- /dev/null
+++ b/Source/CTest/cmCTestTestCommand.cxx
@@ -0,0 +1,112 @@
+/*============================================================================
+ 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 "cmCTestTestCommand.h"
+
+#include "cmCTest.h"
+#include "cmCTestGenericHandler.h"
+
+cmCTestTestCommand::cmCTestTestCommand()
+{
+ this->Arguments[ctt_START] = "START";
+ this->Arguments[ctt_END] = "END";
+ this->Arguments[ctt_STRIDE] = "STRIDE";
+ this->Arguments[ctt_EXCLUDE] = "EXCLUDE";
+ this->Arguments[ctt_INCLUDE] = "INCLUDE";
+ this->Arguments[ctt_EXCLUDE_LABEL] = "EXCLUDE_LABEL";
+ this->Arguments[ctt_INCLUDE_LABEL] = "INCLUDE_LABEL";
+ this->Arguments[ctt_PARALLEL_LEVEL] = "PARALLEL_LEVEL";
+ this->Arguments[ctt_SCHEDULE_RANDOM] = "SCHEDULE_RANDOM";
+ this->Arguments[ctt_STOP_TIME] = "STOP_TIME";
+ this->Arguments[ctt_LAST] = 0;
+ this->Last = ctt_LAST;
+}
+
+cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler()
+{
+ const char* ctestTimeout =
+ this->Makefile->GetDefinition("CTEST_TEST_TIMEOUT");
+
+ double timeout = this->CTest->GetTimeOut();
+ if ( ctestTimeout )
+ {
+ timeout = atof(ctestTimeout);
+ }
+ else
+ {
+ if ( timeout <= 0 )
+ {
+ // By default use timeout of 10 minutes
+ timeout = 600;
+ }
+ }
+ this->CTest->SetTimeOut(timeout);
+ cmCTestGenericHandler* handler = this->InitializeActualHandler();
+ if ( this->Values[ctt_START] || this->Values[ctt_END] ||
+ this->Values[ctt_STRIDE] )
+ {
+ cmOStringStream testsToRunString;
+ if ( this->Values[ctt_START] )
+ {
+ testsToRunString << this->Values[ctt_START];
+ }
+ testsToRunString << ",";
+ if ( this->Values[ctt_END] )
+ {
+ testsToRunString << this->Values[ctt_END];
+ }
+ testsToRunString << ",";
+ if ( this->Values[ctt_STRIDE] )
+ {
+ testsToRunString << this->Values[ctt_STRIDE];
+ }
+ handler->SetOption("TestsToRunInformation",
+ testsToRunString.str().c_str());
+ }
+ if(this->Values[ctt_EXCLUDE])
+ {
+ handler->SetOption("ExcludeRegularExpression", this->Values[ctt_EXCLUDE]);
+ }
+ if(this->Values[ctt_INCLUDE])
+ {
+ handler->SetOption("IncludeRegularExpression", this->Values[ctt_INCLUDE]);
+ }
+ if(this->Values[ctt_EXCLUDE_LABEL])
+ {
+ handler->SetOption("ExcludeLabelRegularExpression",
+ this->Values[ctt_EXCLUDE_LABEL]);
+ }
+ if(this->Values[ctt_INCLUDE_LABEL])
+ {
+ handler->SetOption("LabelRegularExpression",
+ this->Values[ctt_INCLUDE_LABEL]);
+ }
+ if(this->Values[ctt_PARALLEL_LEVEL])
+ {
+ handler->SetOption("ParallelLevel",
+ this->Values[ctt_PARALLEL_LEVEL]);
+ }
+ if(this->Values[ctt_SCHEDULE_RANDOM])
+ {
+ handler->SetOption("ScheduleRandom",
+ this->Values[ctt_SCHEDULE_RANDOM]);
+ }
+ if(this->Values[ctt_STOP_TIME])
+ {
+ this->CTest->SetStopTime(this->Values[ctt_STOP_TIME]);
+ }
+ return handler;
+}
+
+cmCTestGenericHandler* cmCTestTestCommand::InitializeActualHandler()
+{
+ return this->CTest->GetInitializedHandler("test");
+}
diff --git a/Source/CTest/cmCTestTestCommand.h b/Source/CTest/cmCTestTestCommand.h
new file mode 100644
index 000000000..d184ff2a0
--- /dev/null
+++ b/Source/CTest/cmCTestTestCommand.h
@@ -0,0 +1,107 @@
+/*============================================================================
+ 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 cmCTestTestCommand_h
+#define cmCTestTestCommand_h
+
+#include "cmCTestHandlerCommand.h"
+
+/** \class cmCTestTest
+ * \brief Run a ctest script
+ *
+ * cmCTestTestCommand defineds the command to test the project.
+ */
+class cmCTestTestCommand : public cmCTestHandlerCommand
+{
+public:
+
+ cmCTestTestCommand();
+
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ cmCTestTestCommand* ni = new cmCTestTestCommand;
+ ni->CTest = this->CTest;
+ ni->CTestScriptHandler = this->CTestScriptHandler;
+ return ni;
+ }
+
+ /**
+ * 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;
+ }
+
+ cmTypeMacro(cmCTestTestCommand, cmCTestHandlerCommand);
+
+protected:
+ virtual cmCTestGenericHandler* InitializeActualHandler();
+ cmCTestGenericHandler* InitializeHandler();
+
+ enum {
+ ctt_BUILD = ct_LAST,
+ ctt_RETURN_VALUE,
+ ctt_START,
+ ctt_END,
+ ctt_STRIDE,
+ ctt_EXCLUDE,
+ ctt_INCLUDE,
+ ctt_EXCLUDE_LABEL,
+ ctt_INCLUDE_LABEL,
+ ctt_PARALLEL_LEVEL,
+ ctt_SCHEDULE_RANDOM,
+ ctt_STOP_TIME,
+ ctt_LAST
+ };
+};
+
+
+#endif
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
new file mode 100644
index 000000000..ead449edd
--- /dev/null
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -0,0 +1,2267 @@
+/*============================================================================
+ 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 "cmCTestTestHandler.h"
+#include "cmCTestMultiProcessHandler.h"
+#include "cmCTestBatchTestHandler.h"
+#include "cmCTest.h"
+#include "cmCTestRunTest.h"
+#include "cmake.h"
+#include "cmGeneratedFileStream.h"
+#include <cmsys/Process.h>
+#include <cmsys/RegularExpression.hxx>
+#include <cmsys/Base64.h>
+#include "cmMakefile.h"
+#include "cmGlobalGenerator.h"
+#include "cmLocalGenerator.h"
+#include "cmCommand.h"
+#include "cmSystemTools.h"
+#include "cmXMLSafe.h"
+#include "cm_utf8.h"
+
+#include <stdlib.h>
+#include <math.h>
+#include <float.h>
+
+#include <memory> // auto_ptr
+#include <set>
+
+//----------------------------------------------------------------------
+class cmCTestSubdirCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ cmCTestSubdirCommand* c = new cmCTestSubdirCommand;
+ c->TestHandler = this->TestHandler;
+ return c;
+ }
+
+ /**
+ * This is called when the command is first encountered in
+ * the CMakeLists.txt file.
+ */
+ virtual bool InitialPass(std::vector<std::string> const& args,
+ cmExecutionStatus &);
+
+ /**
+ * 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 ""; }
+
+ cmTypeMacro(cmCTestSubdirCommand, cmCommand);
+
+ cmCTestTestHandler* TestHandler;
+};
+
+//----------------------------------------------------------------------
+bool cmCTestSubdirCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 1 )
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+ std::vector<std::string>::const_iterator it;
+ std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
+ for ( it = args.begin(); it != args.end(); ++ it )
+ {
+ cmSystemTools::ChangeDirectory(cwd.c_str());
+ std::string fname;
+
+ if(cmSystemTools::FileIsFullPath(it->c_str()))
+ {
+ fname = *it;
+ }
+ else
+ {
+ fname = cwd;
+ fname += "/";
+ fname += *it;
+ }
+
+ if ( !cmSystemTools::FileIsDirectory(fname.c_str()) )
+ {
+ // No subdirectory? So what...
+ continue;
+ }
+ cmSystemTools::ChangeDirectory(fname.c_str());
+ const char* testFilename;
+ if( cmSystemTools::FileExists("CTestTestfile.cmake") )
+ {
+ // does the CTestTestfile.cmake exist ?
+ testFilename = "CTestTestfile.cmake";
+ }
+ else if( cmSystemTools::FileExists("DartTestfile.txt") )
+ {
+ // does the DartTestfile.txt exist ?
+ testFilename = "DartTestfile.txt";
+ }
+ else
+ {
+ // No CTestTestfile? Who cares...
+ cmSystemTools::ChangeDirectory(cwd.c_str());
+ continue;
+ }
+ fname += "/";
+ fname += testFilename;
+ bool readit =
+ this->Makefile->ReadListFile(this->Makefile->GetCurrentListFile(),
+ fname.c_str());
+ cmSystemTools::ChangeDirectory(cwd.c_str());
+ if(!readit)
+ {
+ std::string m = "Could not find include file: ";
+ m += fname;
+ this->SetError(m.c_str());
+ return false;
+ }
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------
+class cmCTestAddSubdirectoryCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ cmCTestAddSubdirectoryCommand* c = new cmCTestAddSubdirectoryCommand;
+ c->TestHandler = this->TestHandler;
+ return c;
+ }
+
+ /**
+ * This is called when the command is first encountered in
+ * the CMakeLists.txt file.
+ */
+ virtual bool InitialPass(std::vector<std::string> const& args,
+ cmExecutionStatus &);
+
+ /**
+ * 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 ""; }
+
+ cmTypeMacro(cmCTestAddSubdirectoryCommand, cmCommand);
+
+ cmCTestTestHandler* TestHandler;
+};
+
+//----------------------------------------------------------------------
+bool cmCTestAddSubdirectoryCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 1 )
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
+ cmSystemTools::ChangeDirectory(cwd.c_str());
+ std::string fname = cwd;
+ fname += "/";
+ fname += args[1];
+
+ if ( !cmSystemTools::FileExists(fname.c_str()) )
+ {
+ // No subdirectory? So what...
+ return true;
+ }
+ cmSystemTools::ChangeDirectory(fname.c_str());
+ const char* testFilename;
+ if( cmSystemTools::FileExists("CTestTestfile.cmake") )
+ {
+ // does the CTestTestfile.cmake exist ?
+ testFilename = "CTestTestfile.cmake";
+ }
+ else if( cmSystemTools::FileExists("DartTestfile.txt") )
+ {
+ // does the DartTestfile.txt exist ?
+ testFilename = "DartTestfile.txt";
+ }
+ else
+ {
+ // No CTestTestfile? Who cares...
+ cmSystemTools::ChangeDirectory(cwd.c_str());
+ return true;
+ }
+ fname += "/";
+ fname += testFilename;
+ bool readit =
+ this->Makefile->ReadListFile(this->Makefile->GetCurrentListFile(),
+ fname.c_str());
+ cmSystemTools::ChangeDirectory(cwd.c_str());
+ if(!readit)
+ {
+ std::string m = "Could not find include file: ";
+ m += fname;
+ this->SetError(m.c_str());
+ return false;
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------
+class cmCTestAddTestCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ cmCTestAddTestCommand* c = new cmCTestAddTestCommand;
+ c->TestHandler = this->TestHandler;
+ return c;
+ }
+
+ /**
+ * This is called when the command is first encountered in
+ * the CMakeLists.txt file.
+ */
+ virtual bool InitialPass(std::vector<std::string> const&,
+ cmExecutionStatus &);
+
+ /**
+ * 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 ""; }
+
+ cmTypeMacro(cmCTestAddTestCommand, cmCommand);
+
+ cmCTestTestHandler* TestHandler;
+};
+
+//----------------------------------------------------------------------
+bool cmCTestAddTestCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if ( args.size() < 2 )
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+ return this->TestHandler->AddTest(args);
+}
+
+//----------------------------------------------------------------------
+class cmCTestSetTestsPropertiesCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ cmCTestSetTestsPropertiesCommand* c
+ = new cmCTestSetTestsPropertiesCommand;
+ c->TestHandler = this->TestHandler;
+ return c;
+ }
+
+ /**
+ * This is called when the command is first encountered in
+ * the CMakeLists.txt file.
+ */
+ virtual bool InitialPass(std::vector<std::string> const&,
+ cmExecutionStatus &);
+
+ /**
+ * 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 ""; }
+
+ cmTypeMacro(cmCTestSetTestsPropertiesCommand, cmCommand);
+
+ cmCTestTestHandler* TestHandler;
+};
+
+//----------------------------------------------------------------------
+bool cmCTestSetTestsPropertiesCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ return this->TestHandler->SetTestsProperties(args);
+}
+
+//----------------------------------------------------------------------
+// get the next number in a string with numbers separated by ,
+// pos is the start of the search and pos2 is the end of the search
+// pos becomes pos2 after a call to GetNextNumber.
+// -1 is returned at the end of the list.
+inline int GetNextNumber(std::string const& in,
+ int& val,
+ std::string::size_type& pos,
+ std::string::size_type& pos2)
+{
+ pos2 = in.find(',', pos);
+ if(pos2 != in.npos)
+ {
+ if(pos2-pos == 0)
+ {
+ val = -1;
+ }
+ else
+ {
+ val = atoi(in.substr(pos, pos2-pos).c_str());
+ }
+ pos = pos2+1;
+ return 1;
+ }
+ else
+ {
+ if(in.size()-pos == 0)
+ {
+ val = -1;
+ }
+ else
+ {
+ val = atoi(in.substr(pos, in.size()-pos).c_str());
+ }
+ return 0;
+ }
+}
+
+//----------------------------------------------------------------------
+// get the next number in a string with numbers separated by ,
+// pos is the start of the search and pos2 is the end of the search
+// pos becomes pos2 after a call to GetNextNumber.
+// -1 is returned at the end of the list.
+inline int GetNextRealNumber(std::string const& in,
+ double& val,
+ std::string::size_type& pos,
+ std::string::size_type& pos2)
+{
+ pos2 = in.find(',', pos);
+ if(pos2 != in.npos)
+ {
+ if(pos2-pos == 0)
+ {
+ val = -1;
+ }
+ else
+ {
+ val = atof(in.substr(pos, pos2-pos).c_str());
+ }
+ pos = pos2+1;
+ return 1;
+ }
+ else
+ {
+ if(in.size()-pos == 0)
+ {
+ val = -1;
+ }
+ else
+ {
+ val = atof(in.substr(pos, in.size()-pos).c_str());
+ }
+ return 0;
+ }
+}
+
+
+//----------------------------------------------------------------------
+cmCTestTestHandler::cmCTestTestHandler()
+{
+ this->UseUnion = false;
+
+ this->UseIncludeLabelRegExpFlag = false;
+ this->UseExcludeLabelRegExpFlag = false;
+ this->UseIncludeRegExpFlag = false;
+ this->UseExcludeRegExpFlag = false;
+ this->UseExcludeRegExpFirst = false;
+
+ this->CustomMaximumPassedTestOutputSize = 1 * 1024;
+ this->CustomMaximumFailedTestOutputSize = 300 * 1024;
+
+ this->MemCheck = false;
+
+ this->LogFile = 0;
+
+ // regex to detect <DartMeasurement>...</DartMeasurement>
+ this->DartStuff.compile(
+ "(<DartMeasurement.*/DartMeasurement[a-zA-Z]*>)");
+ // regex to detect each individual <DartMeasurement>...</DartMeasurement>
+ this->DartStuff1.compile(
+ "(<DartMeasurement[^<]*</DartMeasurement[a-zA-Z]*>)");
+}
+
+//----------------------------------------------------------------------
+void cmCTestTestHandler::Initialize()
+{
+ this->Superclass::Initialize();
+
+ this->ElapsedTestingTime = -1;
+
+ this->TestResults.clear();
+
+ this->CustomTestsIgnore.clear();
+ this->StartTest = "";
+ this->EndTest = "";
+
+ this->CustomPreTest.clear();
+ this->CustomPostTest.clear();
+ this->CustomMaximumPassedTestOutputSize = 1 * 1024;
+ this->CustomMaximumFailedTestOutputSize = 300 * 1024;
+
+ this->TestsToRun.clear();
+
+ this->UseIncludeLabelRegExpFlag = false;
+ this->UseExcludeLabelRegExpFlag = false;
+ this->UseIncludeRegExpFlag = false;
+ this->UseExcludeRegExpFlag = false;
+ this->UseExcludeRegExpFirst = false;
+ this->IncludeLabelRegularExpression = "";
+ this->ExcludeLabelRegularExpression = "";
+ this->IncludeRegExp = "";
+ this->ExcludeRegExp = "";
+
+ TestsToRunString = "";
+ this->UseUnion = false;
+ this->TestList.clear();
+}
+
+//----------------------------------------------------------------------
+void cmCTestTestHandler::PopulateCustomVectors(cmMakefile *mf)
+{
+ this->CTest->PopulateCustomVector(mf, "CTEST_CUSTOM_PRE_TEST",
+ this->CustomPreTest);
+ this->CTest->PopulateCustomVector(mf, "CTEST_CUSTOM_POST_TEST",
+ this->CustomPostTest);
+ this->CTest->PopulateCustomVector(mf,
+ "CTEST_CUSTOM_TESTS_IGNORE",
+ this->CustomTestsIgnore);
+ this->CTest->PopulateCustomInteger(mf,
+ "CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE",
+ this->CustomMaximumPassedTestOutputSize);
+ this->CTest->PopulateCustomInteger(mf,
+ "CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE",
+ this->CustomMaximumFailedTestOutputSize);
+}
+
+//----------------------------------------------------------------------
+int cmCTestTestHandler::PreProcessHandler()
+{
+ if ( !this->ExecuteCommands(this->CustomPreTest) )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Problem executing pre-test command(s)." << std::endl);
+ return 0;
+ }
+ return 1;
+}
+
+//----------------------------------------------------------------------
+int cmCTestTestHandler::PostProcessHandler()
+{
+ if ( !this->ExecuteCommands(this->CustomPostTest) )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Problem executing post-test command(s)." << std::endl);
+ return 0;
+ }
+ return 1;
+}
+
+//----------------------------------------------------------------------
+//clearly it would be nice if this were broken up into a few smaller
+//functions and commented...
+int cmCTestTestHandler::ProcessHandler()
+{
+ // Update internal data structure from generic one
+ this->SetTestsToRunInformation(this->GetOption("TestsToRunInformation"));
+ this->SetUseUnion(cmSystemTools::IsOn(this->GetOption("UseUnion")));
+ if(cmSystemTools::IsOn(this->GetOption("ScheduleRandom")))
+ {
+ this->CTest->SetScheduleType("Random");
+ }
+ if(this->GetOption("ParallelLevel"))
+ {
+ this->CTest->SetParallelLevel(atoi(this->GetOption("ParallelLevel")));
+ }
+
+ const char* val;
+ val = this->GetOption("LabelRegularExpression");
+ if ( val )
+ {
+ this->UseIncludeLabelRegExpFlag = true;
+ this->IncludeLabelRegExp = val;
+ }
+ val = this->GetOption("ExcludeLabelRegularExpression");
+ if ( val )
+ {
+ this->UseExcludeLabelRegExpFlag = true;
+ this->ExcludeLabelRegularExpression = val;
+ }
+ val = this->GetOption("IncludeRegularExpression");
+ if ( val )
+ {
+ this->UseIncludeRegExp();
+ this->SetIncludeRegExp(val);
+ }
+ val = this->GetOption("ExcludeRegularExpression");
+ if ( val )
+ {
+ this->UseExcludeRegExp();
+ this->SetExcludeRegExp(val);
+ }
+
+ this->TestResults.clear();
+
+ cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ (this->MemCheck ? "Memory check" : "Test")
+ << " project " << cmSystemTools::GetCurrentWorkingDirectory()
+ << std::endl);
+ if ( ! this->PreProcessHandler() )
+ {
+ return -1;
+ }
+
+ cmGeneratedFileStream mLogFile;
+ this->StartLogFile((this->MemCheck ? "DynamicAnalysis" : "Test"), mLogFile);
+ this->LogFile = &mLogFile;
+
+ std::vector<cmStdString> passed;
+ std::vector<cmStdString> failed;
+ int total;
+
+ //start the real time clock
+ double clock_start, clock_finish;
+ clock_start = cmSystemTools::GetTime();
+
+ this->ProcessDirectory(passed, failed);
+
+ clock_finish = cmSystemTools::GetTime();
+
+ total = int(passed.size()) + int(failed.size());
+
+ if (total == 0)
+ {
+ if ( !this->CTest->GetShowOnly() && !this->CTest->ShouldPrintLabels() )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "No tests were found!!!"
+ << std::endl);
+ }
+ }
+ else
+ {
+ if (this->HandlerVerbose && passed.size() &&
+ (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();
+ j != passed.end(); ++j)
+ {
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "\t" << *j
+ << std::endl);
+ }
+ }
+
+ float percent = float(passed.size()) * 100.0f / float(total);
+ if ( failed.size() > 0 && percent > 99)
+ {
+ percent = 99;
+ }
+
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, std::endl
+ << static_cast<int>(percent + .5) << "% tests passed, "
+ << failed.size() << " tests failed out of "
+ << total << std::endl);
+ if(this->CTest->GetLabelSummary())
+ {
+ this->PrintLabelSummary();
+ }
+ char realBuf[1024];
+ sprintf(realBuf, "%6.2f sec", (double)(clock_finish - clock_start));
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, "\nTotal Test time (real) = "
+ << realBuf << "\n" );
+
+ if (failed.size())
+ {
+ cmGeneratedFileStream ofs;
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, std::endl
+ << "The following tests FAILED:" << std::endl);
+ this->StartLogFile("TestsFailed", ofs);
+
+ typedef std::set<cmCTestTestHandler::cmCTestTestResult,
+ cmCTestTestResultLess> SetOfTests;
+ SetOfTests resultsSet(this->TestResults.begin(),
+ this->TestResults.end());
+
+ for(SetOfTests::iterator ftit = resultsSet.begin();
+ ftit != resultsSet.end(); ++ftit)
+ {
+ if ( ftit->Status != cmCTestTestHandler::COMPLETED )
+ {
+ ofs << ftit->TestCount << ":" << ftit->Name << std::endl;
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, "\t" << std::setw(3)
+ << ftit->TestCount << " - "
+ << ftit->Name.c_str() << " ("
+ << this->GetTestStatus(ftit->Status) << ")"
+ << std::endl);
+ }
+ }
+ }
+ }
+
+ if ( this->CTest->GetProduceXML() )
+ {
+ cmGeneratedFileStream xmlfile;
+ if( !this->StartResultingXML(
+ (this->MemCheck ? cmCTest::PartMemCheck : cmCTest::PartTest),
+ (this->MemCheck ? "DynamicAnalysis" : "Test"), xmlfile) )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot create "
+ << (this->MemCheck ? "memory check" : "testing")
+ << " XML file" << std::endl);
+ this->LogFile = 0;
+ return 1;
+ }
+ this->GenerateDartOutput(xmlfile);
+ }
+
+ if ( ! this->PostProcessHandler() )
+ {
+ this->LogFile = 0;
+ return -1;
+ }
+
+ if ( !failed.empty() )
+ {
+ this->LogFile = 0;
+ return -1;
+ }
+ this->LogFile = 0;
+ return 0;
+}
+
+//----------------------------------------------------------------------
+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;
+ // initialize maps
+ std::string::size_type maxlen = 0;
+ for(; it != this->TestList.end(); ++it)
+ {
+ cmCTestTestProperties& p = *it;
+ if(p.Labels.size() != 0)
+ {
+ for(std::vector<std::string>::iterator l = p.Labels.begin();
+ l != p.Labels.end(); ++l)
+ {
+ if((*l).size() > maxlen)
+ {
+ maxlen = (*l).size();
+ }
+ labels.insert(*l);
+ labelTimes[*l] = 0;
+ }
+ }
+ }
+ ri = this->TestResults.begin();
+ // fill maps
+ for(; ri != this->TestResults.end(); ++ri)
+ {
+ cmCTestTestResult &result = *ri;
+ cmCTestTestProperties& p = *result.Properties;
+ if(p.Labels.size() != 0)
+ {
+ for(std::vector<std::string>::iterator l = p.Labels.begin();
+ l != p.Labels.end(); ++l)
+ {
+ labelTimes[*l] += result.ExecutionTime;
+ }
+ }
+ }
+ // now print times
+ if(labels.size())
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, "\nLabel Time Summary:");
+ }
+ for(std::set<cmStdString>::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 );
+ if ( this->LogFile )
+ {
+ *this->LogFile << "\n" << *i << " = "
+ << buf << "\n";
+ }
+ }
+ if(labels.size())
+ {
+ if(this->LogFile)
+ {
+ *this->LogFile << "\n";
+ }
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, "\n");
+ }
+
+}
+
+//----------------------------------------------------------------------
+void cmCTestTestHandler::CheckLabelFilterInclude(cmCTestTestProperties& it)
+{
+ // if not using Labels to filter then return
+ if (!this->UseIncludeLabelRegExpFlag )
+ {
+ return;
+ }
+ // 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 )
+ {
+ it.IsInBasedOnREOptions = false;
+ return;
+ }
+ // check to see if the label regular expression matches
+ bool found = false; // assume it does not match
+ // loop over all labels and look for match
+ for(std::vector<std::string>::iterator l = it.Labels.begin();
+ l != it.Labels.end(); ++l)
+ {
+ if(this->IncludeLabelRegularExpression.find(*l))
+ {
+ found = true;
+ }
+ }
+ // if no match was found, exclude the test
+ if(!found)
+ {
+ it.IsInBasedOnREOptions = false;
+ }
+}
+
+
+//----------------------------------------------------------------------
+void cmCTestTestHandler::CheckLabelFilterExclude(cmCTestTestProperties& it)
+{
+ // if not using Labels to filter then return
+ if (!this->UseExcludeLabelRegExpFlag )
+ {
+ return;
+ }
+ // 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 )
+ {
+ return;
+ }
+ // check to see if the label regular expression matches
+ bool found = false; // assume it does not match
+ // loop over all labels and look for match
+ for(std::vector<std::string>::iterator l = it.Labels.begin();
+ l != it.Labels.end(); ++l)
+ {
+ if(this->ExcludeLabelRegularExpression.find(*l))
+ {
+ found = true;
+ }
+ }
+ // if match was found, exclude the test
+ if(found)
+ {
+ it.IsInBasedOnREOptions = false;
+ }
+}
+
+//----------------------------------------------------------------------
+void cmCTestTestHandler::CheckLabelFilter(cmCTestTestProperties& it)
+{
+ this->CheckLabelFilterInclude(it);
+ this->CheckLabelFilterExclude(it);
+}
+
+//----------------------------------------------------------------------
+void cmCTestTestHandler::ComputeTestList()
+{
+ this->TestList.clear(); // clear list of test
+ this->GetListOfTests();
+ cmCTestTestHandler::ListOfTests::size_type tmsize = this->TestList.size();
+ // how many tests are in based on RegExp?
+ int inREcnt = 0;
+ cmCTestTestHandler::ListOfTests::iterator it;
+ for ( it = this->TestList.begin(); it != this->TestList.end(); it ++ )
+ {
+ this->CheckLabelFilter(*it);
+ if (it->IsInBasedOnREOptions)
+ {
+ inREcnt ++;
+ }
+ }
+ // expand the test list based on the union flag
+ if (this->UseUnion)
+ {
+ this->ExpandTestsToRunInformation((int)tmsize);
+ }
+ else
+ {
+ this->ExpandTestsToRunInformation(inREcnt);
+ }
+ // Now create a final list of tests to run
+ int cnt = 0;
+ inREcnt = 0;
+ std::string last_directory = "";
+ ListOfTests finalList;
+ for ( it = this->TestList.begin(); it != this->TestList.end(); it ++ )
+ {
+ cnt ++;
+ if (it->IsInBasedOnREOptions)
+ {
+ inREcnt++;
+ }
+
+ if (this->UseUnion)
+ {
+ // if it is not in the list and not in the regexp then skip
+ if ((this->TestsToRun.size() &&
+ std::find(this->TestsToRun.begin(), this->TestsToRun.end(), cnt)
+ == this->TestsToRun.end()) && !it->IsInBasedOnREOptions)
+ {
+ continue;
+ }
+ }
+ else
+ {
+ // is this test in the list of tests to run? If not then skip it
+ if ((this->TestsToRun.size() &&
+ std::find(this->TestsToRun.begin(),
+ this->TestsToRun.end(), inREcnt)
+ == this->TestsToRun.end()) || !it->IsInBasedOnREOptions)
+ {
+ continue;
+ }
+ }
+ it->Index = cnt; // save the index into the test list for this test
+ finalList.push_back(*it);
+ }
+ // Save the total number of tests before exclusions
+ this->TotalNumberOfTests = this->TestList.size();
+ // Set the TestList to the final list of all test
+ this->TestList = finalList;
+ std::string::size_type max = this->CTest->GetMaxTestNameWidth();
+ for (it = this->TestList.begin();
+ it != this->TestList.end(); it ++ )
+ {
+ cmCTestTestProperties& p = *it;
+ if(max < p.Name.size())
+ {
+ max = p.Name.size();
+ }
+ }
+ if(static_cast<std::string::size_type>(this->CTest->GetMaxTestNameWidth())
+ != max)
+ {
+ this->CTest->SetMaxTestNameWidth(static_cast<int>(max));
+ }
+}
+
+bool cmCTestTestHandler::GetValue(const char* tag,
+ int& value,
+ std::ifstream& fin)
+{
+ std::string line;
+ bool ret = true;
+ cmSystemTools::GetLineFromStream(fin, line);
+ if(line == tag)
+ {
+ fin >> value;
+ ret = cmSystemTools::GetLineFromStream(fin, line); // read blank line
+ }
+ else
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "parse error: missing tag: "
+ << tag << " found [" << line << "]" << std::endl);
+ ret = false;
+ }
+ return ret;
+}
+
+bool cmCTestTestHandler::GetValue(const char* tag,
+ double& value,
+ std::ifstream& fin)
+{
+ std::string line;
+ cmSystemTools::GetLineFromStream(fin, line);
+ bool ret = true;
+ if(line == tag)
+ {
+ fin >> value;
+ ret = cmSystemTools::GetLineFromStream(fin, line); // read blank line
+ }
+ else
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "parse error: missing tag: "
+ << tag << " found [" << line << "]" << std::endl);
+ ret = false;
+ }
+ return ret;
+}
+
+bool cmCTestTestHandler::GetValue(const char* tag,
+ bool& value,
+ std::ifstream& fin)
+{
+ std::string line;
+ cmSystemTools::GetLineFromStream(fin, line);
+ bool ret = true;
+ if(line == tag)
+ {
+#ifdef __HAIKU__
+ int tmp = 0;
+ fin >> tmp;
+ value = false;
+ if(tmp)
+ {
+ value = true;
+ }
+#else
+ fin >> value;
+#endif
+ ret = cmSystemTools::GetLineFromStream(fin, line); // read blank line
+ }
+ else
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "parse error: missing tag: "
+ << tag << " found [" << line << "]" << std::endl);
+ ret = false;
+ }
+ return ret;
+}
+
+bool cmCTestTestHandler::GetValue(const char* tag,
+ size_t& value,
+ std::ifstream& fin)
+{
+ std::string line;
+ cmSystemTools::GetLineFromStream(fin, line);
+ bool ret = true;
+ if(line == tag)
+ {
+ fin >> value;
+ ret = cmSystemTools::GetLineFromStream(fin, line); // read blank line
+ }
+ else
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "parse error: missing tag: "
+ << tag << " found [" << line.c_str() << "]" << std::endl);
+ ret = false;
+ }
+ return ret;
+}
+
+bool cmCTestTestHandler::GetValue(const char* tag,
+ std::string& value,
+ std::ifstream& fin)
+{
+ std::string line;
+ cmSystemTools::GetLineFromStream(fin, line);
+ bool ret = true;
+ if(line == tag)
+ {
+ ret = cmSystemTools::GetLineFromStream(fin, value);
+ }
+ else
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "parse error: missing tag: "
+ << tag << " found [" << line << "]" << std::endl);
+ ret = false;
+ }
+ return ret;
+}
+
+//---------------------------------------------------------------------
+void cmCTestTestHandler::ProcessDirectory(std::vector<cmStdString> &passed,
+ std::vector<cmStdString> &failed)
+{
+ this->ComputeTestList();
+ this->StartTest = this->CTest->CurrentTime();
+ this->StartTestTime = static_cast<unsigned int>(cmSystemTools::GetTime());
+ double elapsed_time_start = cmSystemTools::GetTime();
+
+ cmCTestMultiProcessHandler* parallel = this->CTest->GetBatchJobs() ?
+ new cmCTestBatchTestHandler : new cmCTestMultiProcessHandler;
+ parallel->SetCTest(this->CTest);
+ parallel->SetParallelLevel(this->CTest->GetParallelLevel());
+ parallel->SetTestHandler(this);
+
+ *this->LogFile << "Start testing: "
+ << this->CTest->CurrentTime() << std::endl
+ << "----------------------------------------------------------"
+ << std::endl;
+
+ cmCTestMultiProcessHandler::TestMap tests;
+ cmCTestMultiProcessHandler::PropertiesMap properties;
+
+ bool randomSchedule = this->CTest->GetScheduleType() == "Random";
+ if(randomSchedule)
+ {
+ srand((unsigned)time(0));
+ }
+
+ for (ListOfTests::iterator it = this->TestList.begin();
+ it != this->TestList.end(); ++it)
+ {
+ cmCTestTestProperties& p = *it;
+ cmCTestMultiProcessHandler::TestSet depends;
+
+ if(randomSchedule)
+ {
+ p.Cost = static_cast<float>(rand());
+ }
+
+ if(p.Timeout == 0 && this->CTest->GetGlobalTimeout() != 0)
+ {
+ p.Timeout = this->CTest->GetGlobalTimeout();
+ }
+
+ if(p.Depends.size())
+ {
+ for(std::vector<std::string>::iterator i = p.Depends.begin();
+ i != p.Depends.end(); ++i)
+ {
+ for(ListOfTests::iterator it2 = this->TestList.begin();
+ it2 != this->TestList.end(); ++it2)
+ {
+ if(it2->Name == *i)
+ {
+ depends.insert(it2->Index);
+ break; // break out of test loop as name can only match 1
+ }
+ }
+ }
+ }
+ tests[it->Index] = depends;
+ properties[it->Index] = &*it;
+ }
+ parallel->SetTests(tests, properties);
+ parallel->SetPassFailVectors(&passed, &failed);
+ this->TestResults.clear();
+ parallel->SetTestResults(&this->TestResults);
+
+ if(this->CTest->ShouldPrintLabels())
+ {
+ parallel->PrintLabels();
+ }
+ else if(this->CTest->GetShowOnly())
+ {
+ parallel->PrintTestList();
+ }
+ else
+ {
+ parallel->RunTests();
+ }
+ delete parallel;
+ this->EndTest = this->CTest->CurrentTime();
+ this->EndTestTime = static_cast<unsigned int>(cmSystemTools::GetTime());
+ this->ElapsedTestingTime = cmSystemTools::GetTime() - elapsed_time_start;
+ *this->LogFile << "End testing: "
+ << this->CTest->CurrentTime() << std::endl;
+}
+
+//----------------------------------------------------------------------
+void cmCTestTestHandler::GenerateTestCommand(std::vector<std::string>&)
+{
+}
+
+//----------------------------------------------------------------------
+void cmCTestTestHandler::GenerateDartOutput(std::ostream& os)
+{
+ 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";
+ 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;
+ }
+ os << "\t</TestList>\n";
+ for ( cc = 0; cc < this->TestResults.size(); cc ++ )
+ {
+ cmCTestTestResult *result = &this->TestResults[cc];
+ this->WriteTestResultHeader(os, result);
+ os << "\t\t<Results>" << std::endl;
+ 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;
+ }
+ os << result->RegressionImages;
+ os << "\t\t\t<NamedMeasurement type=\"numeric/double\" "
+ << "name=\"Execution Time\"><Value>"
+ << result->ExecutionTime
+ << "</Value></NamedMeasurement>\n";
+ if(result->Reason.size())
+ {
+ const char* reasonType = "Pass Reason";
+ if(result->Status != cmCTestTestHandler::COMPLETED &&
+ result->Status != cmCTestTestHandler::NOT_RUN)
+ {
+ reasonType = "Fail Reason";
+ }
+ os << "\t\t\t<NamedMeasurement type=\"text/string\" "
+ << "name=\"" << reasonType << "\"><Value>"
+ << cmXMLSafe(result->Reason)
+ << "</Value></NamedMeasurement>\n";
+ }
+ 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;
+ 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);
+}
+
+//----------------------------------------------------------------------------
+void cmCTestTestHandler::WriteTestResultHeader(std::ostream& os,
+ cmCTestTestResult* result)
+{
+ os << "\t<Test Status=\"";
+ if ( result->Status == cmCTestTestHandler::COMPLETED )
+ {
+ os << "passed";
+ }
+ else if ( result->Status == cmCTestTestHandler::NOT_RUN )
+ {
+ os << "notrun";
+ }
+ else
+ {
+ os << "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";
+}
+
+//----------------------------------------------------------------------------
+void cmCTestTestHandler::WriteTestResultFooter(std::ostream& os,
+ cmCTestTestResult* result)
+{
+ if(!result->Properties->Labels.empty())
+ {
+ os << "\t\t<Labels>\n";
+ 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";
+ }
+ os << "\t\t</Labels>\n";
+ }
+
+ os
+ << "\t</Test>" << std::endl;
+}
+
+//----------------------------------------------------------------------
+void cmCTestTestHandler::AttachFiles(std::ostream& os,
+ cmCTestTestResult* result)
+{
+ if(result->Status != cmCTestTestHandler::COMPLETED
+ && result->Properties->AttachOnFail.size())
+ {
+ result->Properties->AttachedFiles.insert(
+ result->Properties->AttachedFiles.end(),
+ result->Properties->AttachOnFail.begin(),
+ result->Properties->AttachOnFail.end());
+ }
+ for(std::vector<std::string>::const_iterator file =
+ result->Properties->AttachedFiles.begin();
+ file != result->Properties->AttachedFiles.end(); ++file)
+ {
+ 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";
+ }
+}
+
+//----------------------------------------------------------------------
+int cmCTestTestHandler::ExecuteCommands(std::vector<cmStdString>& vec)
+{
+ std::vector<cmStdString>::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,
+ cmSystemTools::OUTPUT_MERGE
+ /*this->Verbose*/) || retVal != 0 )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Problem running command: "
+ << *it << std::endl);
+ return 0;
+ }
+ }
+ return 1;
+}
+
+
+//----------------------------------------------------------------------
+// Find the appropriate executable to run for a test
+std::string cmCTestTestHandler::FindTheExecutable(const char *exe)
+{
+ std::string resConfig;
+ std::vector<std::string> extraPaths;
+ std::vector<std::string> failedPaths;
+ if(strcmp(exe, "NOT_AVAILABLE") == 0)
+ {
+ return exe;
+ }
+ return cmCTestTestHandler::FindExecutable(this->CTest,
+ exe, resConfig,
+ extraPaths,
+ failedPaths);
+}
+
+// add additional configurations to the search path
+void cmCTestTestHandler
+::AddConfigurations(cmCTest *ctest,
+ std::vector<std::string> &attempted,
+ std::vector<std::string> &attemptedConfigs,
+ std::string filepath,
+ std::string &filename)
+{
+ std::string tempPath;
+
+ if (filepath.size() &&
+ filepath[filepath.size()-1] != '/')
+ {
+ filepath += "/";
+ }
+ tempPath = filepath + filename;
+ attempted.push_back(tempPath);
+ attemptedConfigs.push_back("");
+
+ if(ctest->GetConfigType().size())
+ {
+ tempPath = filepath;
+ tempPath += ctest->GetConfigType();
+ tempPath += "/";
+ tempPath += filename;
+ attempted.push_back(tempPath);
+ attemptedConfigs.push_back(ctest->GetConfigType());
+ // If the file is an OSX bundle then the configtyp
+ // will be at the start of the path
+ tempPath = ctest->GetConfigType();
+ tempPath += "/";
+ tempPath += filepath;
+ tempPath += filename;
+ attempted.push_back(tempPath);
+ attemptedConfigs.push_back(ctest->GetConfigType());
+ }
+ else
+ {
+ // no config specified to try some options
+ tempPath = filepath;
+ tempPath += "Release/";
+ tempPath += filename;
+ attempted.push_back(tempPath);
+ attemptedConfigs.push_back("Release");
+ tempPath = filepath;
+ tempPath += "Debug/";
+ tempPath += filename;
+ attempted.push_back(tempPath);
+ attemptedConfigs.push_back("Debug");
+ tempPath = filepath;
+ tempPath += "MinSizeRel/";
+ tempPath += filename;
+ attempted.push_back(tempPath);
+ attemptedConfigs.push_back("MinSizeRel");
+ tempPath = filepath;
+ tempPath += "RelWithDebInfo/";
+ tempPath += filename;
+ attempted.push_back(tempPath);
+ attemptedConfigs.push_back("RelWithDebInfo");
+ tempPath = filepath;
+ tempPath += "Deployment/";
+ tempPath += filename;
+ attempted.push_back(tempPath);
+ attemptedConfigs.push_back("Deployment");
+ tempPath = filepath;
+ tempPath += "Development/";
+ tempPath += filename;
+ attempted.push_back(tempPath);
+ attemptedConfigs.push_back("Deployment");
+ }
+}
+
+
+//----------------------------------------------------------------------
+// Find the appropriate executable to run for a test
+std::string cmCTestTestHandler
+::FindExecutable(cmCTest *ctest,
+ const char *testCommand,
+ std::string &resultingConfig,
+ std::vector<std::string> &extraPaths,
+ std::vector<std::string> &failed)
+{
+ // now run the compiled test if we can find it
+ std::vector<std::string> attempted;
+ std::vector<std::string> attemptedConfigs;
+ std::string tempPath;
+ std::string filepath =
+ cmSystemTools::GetFilenamePath(testCommand);
+ std::string filename =
+ cmSystemTools::GetFilenameName(testCommand);
+
+ cmCTestTestHandler::AddConfigurations(ctest, attempted,
+ attemptedConfigs,
+ filepath,filename);
+
+ // even if a fullpath was specified also try it relative to the current
+ // directory
+ if (filepath.size() && filepath[0] == '/')
+ {
+ std::string localfilepath = filepath.substr(1,filepath.size()-1);
+ cmCTestTestHandler::AddConfigurations(ctest, attempted,
+ attemptedConfigs,
+ localfilepath,filename);
+ }
+
+
+ // if extraPaths are provided and we were not passed a full path, try them,
+ // try any extra paths
+ if (filepath.size() == 0)
+ {
+ for (unsigned int i = 0; i < extraPaths.size(); ++i)
+ {
+ std::string filepathExtra =
+ cmSystemTools::GetFilenamePath(extraPaths[i]);
+ std::string filenameExtra =
+ cmSystemTools::GetFilenameName(extraPaths[i]);
+ cmCTestTestHandler::AddConfigurations(ctest,attempted,
+ attemptedConfigs,
+ filepathExtra,
+ filenameExtra);
+ }
+ }
+
+ // store the final location in fullPath
+ std::string fullPath;
+
+ // now look in the paths we specified above
+ for(unsigned int ai=0;
+ ai < attempted.size() && fullPath.size() == 0; ++ai)
+ {
+ // first check without exe extension
+ if(cmSystemTools::FileExists(attempted[ai].c_str())
+ && !cmSystemTools::FileIsDirectory(attempted[ai].c_str()))
+ {
+ fullPath = cmSystemTools::CollapseFullPath(attempted[ai].c_str());
+ resultingConfig = attemptedConfigs[ai];
+ }
+ // then try with the exe extension
+ else
+ {
+ failed.push_back(attempted[ai].c_str());
+ tempPath = attempted[ai];
+ tempPath += cmSystemTools::GetExecutableExtension();
+ if(cmSystemTools::FileExists(tempPath.c_str())
+ && !cmSystemTools::FileIsDirectory(tempPath.c_str()))
+ {
+ fullPath = cmSystemTools::CollapseFullPath(tempPath.c_str());
+ resultingConfig = attemptedConfigs[ai];
+ }
+ else
+ {
+ failed.push_back(tempPath.c_str());
+ }
+ }
+ }
+
+ // if everything else failed, check the users path, but only if a full path
+ // wasn't specified
+ if (fullPath.size() == 0 && filepath.size() == 0)
+ {
+ std::string path = cmSystemTools::FindProgram(filename.c_str());
+ if (path != "")
+ {
+ resultingConfig = "";
+ return path;
+ }
+ }
+ if(fullPath.size() == 0)
+ {
+ cmCTestLog(ctest, HANDLER_OUTPUT,
+ "Could not find executable " << testCommand << "\n"
+ << "Looked in the following places:\n");
+ for(std::vector<std::string>::iterator i = failed.begin();
+ i != failed.end(); ++i)
+ {
+ cmCTestLog(ctest, HANDLER_OUTPUT,
+ i->c_str() << "\n");
+ }
+ }
+
+ return fullPath;
+}
+
+
+//----------------------------------------------------------------------
+void cmCTestTestHandler::GetListOfTests()
+{
+ if ( !this->IncludeLabelRegExp.empty() )
+ {
+ this->IncludeLabelRegularExpression.
+ compile(this->IncludeLabelRegExp.c_str());
+ }
+ if ( !this->IncludeLabelRegExp.empty() )
+ {
+ this->ExcludeLabelRegularExpression.
+ compile(this->ExcludeLabelRegExp.c_str());
+ }
+ if ( !this->IncludeRegExp.empty() )
+ {
+ this->IncludeTestsRegularExpression.compile(this->IncludeRegExp.c_str());
+ }
+ if ( !this->ExcludeRegExp.empty() )
+ {
+ this->ExcludeTestsRegularExpression.compile(this->ExcludeRegExp.c_str());
+ }
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Constructing a list of tests" << std::endl);
+ cmake cm;
+ cmGlobalGenerator gg;
+ gg.SetCMakeInstance(&cm);
+ std::auto_ptr<cmLocalGenerator> lg(gg.CreateLocalGenerator());
+ cmMakefile *mf = lg->GetMakefile();
+ 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);
+
+ // Add handler for SUBDIRS
+ cmCTestSubdirCommand* newCom2 =
+ new cmCTestSubdirCommand;
+ newCom2->TestHandler = this;
+ cm.AddCommand(newCom2);
+
+ // Add handler for ADD_SUBDIRECTORY
+ cmCTestAddSubdirectoryCommand* newCom3 =
+ new cmCTestAddSubdirectoryCommand;
+ newCom3->TestHandler = this;
+ cm.AddCommand(newCom3);
+
+ // Add handler for SET_SOURCE_FILES_PROPERTIES
+ cmCTestSetTestsPropertiesCommand* newCom4
+ = new cmCTestSetTestsPropertiesCommand;
+ newCom4->TestHandler = this;
+ cm.AddCommand(newCom4);
+
+ const char* testFilename;
+ if( cmSystemTools::FileExists("CTestTestfile.cmake") )
+ {
+ // does the CTestTestfile.cmake exist ?
+ testFilename = "CTestTestfile.cmake";
+ }
+ else if( cmSystemTools::FileExists("DartTestfile.txt") )
+ {
+ // does the DartTestfile.txt exist ?
+ testFilename = "DartTestfile.txt";
+ }
+ else
+ {
+ return;
+ }
+
+ if ( !mf->ReadListFile(0, testFilename) )
+ {
+ return;
+ }
+ if ( cmSystemTools::GetErrorOccuredFlag() )
+ {
+ return;
+ }
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "Done constructing a list of tests" << std::endl);
+}
+
+//----------------------------------------------------------------------
+void cmCTestTestHandler::UseIncludeRegExp()
+{
+ this->UseIncludeRegExpFlag = true;
+}
+
+//----------------------------------------------------------------------
+void cmCTestTestHandler::UseExcludeRegExp()
+{
+ this->UseExcludeRegExpFlag = true;
+ this->UseExcludeRegExpFirst = this->UseIncludeRegExpFlag ? false : true;
+}
+
+//----------------------------------------------------------------------
+const char* cmCTestTestHandler::GetTestStatus(int status)
+{
+ static const char statuses[][100] = {
+ "Not Run",
+ "Timeout",
+ "SEGFAULT",
+ "ILLEGAL",
+ "INTERRUPT",
+ "NUMERICAL",
+ "OTHER_FAULT",
+ "Failed",
+ "BAD_COMMAND",
+ "Completed"
+ };
+
+ if ( status < cmCTestTestHandler::NOT_RUN ||
+ status > cmCTestTestHandler::COMPLETED )
+ {
+ return "No Status";
+ }
+ return statuses[status];
+}
+
+//----------------------------------------------------------------------
+void cmCTestTestHandler::ExpandTestsToRunInformation(size_t numTests)
+{
+ if (this->TestsToRunString.empty())
+ {
+ return;
+ }
+
+ int start;
+ int end = -1;
+ double stride = -1;
+ std::string::size_type pos = 0;
+ std::string::size_type pos2;
+ // read start
+ if(GetNextNumber(this->TestsToRunString, start, pos, pos2))
+ {
+ // read end
+ if(GetNextNumber(this->TestsToRunString, end, pos, pos2))
+ {
+ // read stride
+ if(GetNextRealNumber(this->TestsToRunString, stride, pos, pos2))
+ {
+ int val =0;
+ // now read specific numbers
+ while(GetNextNumber(this->TestsToRunString, val, pos, pos2))
+ {
+ this->TestsToRun.push_back(val);
+ }
+ this->TestsToRun.push_back(val);
+ }
+ }
+ }
+
+ // if start is not specified then we assume we start at 1
+ if(start == -1)
+ {
+ start = 1;
+ }
+
+ // if end isnot specified then we assume we end with the last test
+ if(end == -1)
+ {
+ end = static_cast<int>(numTests);
+ }
+
+ // if the stride wasn't specified then it defaults to 1
+ if(stride == -1)
+ {
+ stride = 1;
+ }
+
+ // if we have a range then add it
+ if(end != -1 && start != -1 && stride > 0)
+ {
+ int i = 0;
+ while (i*stride + start <= end)
+ {
+ this->TestsToRun.push_back(static_cast<int>(i*stride+start));
+ ++i;
+ }
+ }
+
+ // sort the array
+ std::sort(this->TestsToRun.begin(), this->TestsToRun.end(),
+ std::less<int>());
+ // remove duplicates
+ std::vector<int>::iterator new_end =
+ std::unique(this->TestsToRun.begin(), this->TestsToRun.end());
+ this->TestsToRun.erase(new_end, this->TestsToRun.end());
+}
+
+//----------------------------------------------------------------------
+// Just for convenience
+#define SPACE_REGEX "[ \t\r\n]"
+//----------------------------------------------------------------------
+std::string cmCTestTestHandler::GenerateRegressionImages(
+ const std::string& xml)
+{
+ cmsys::RegularExpression twoattributes(
+ "<DartMeasurement"
+ SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
+ SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
+ SPACE_REGEX "*>([^<]*)</DartMeasurement>");
+ cmsys::RegularExpression threeattributes(
+ "<DartMeasurement"
+ SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
+ SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
+ SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
+ SPACE_REGEX "*>([^<]*)</DartMeasurement>");
+ cmsys::RegularExpression fourattributes(
+ "<DartMeasurement"
+ SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
+ SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
+ SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
+ SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
+ SPACE_REGEX "*>([^<]*)</DartMeasurement>");
+ cmsys::RegularExpression cdatastart(
+ "<DartMeasurement"
+ SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
+ SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
+ SPACE_REGEX "*>"
+ SPACE_REGEX "*<!\\[CDATA\\[");
+ cmsys::RegularExpression cdataend(
+ "]]>"
+ SPACE_REGEX "*</DartMeasurement>");
+ cmsys::RegularExpression measurementfile(
+ "<DartMeasurementFile"
+ SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
+ SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
+ SPACE_REGEX "*>([^<]*)</DartMeasurementFile>");
+
+ cmOStringStream ostr;
+ bool done = false;
+ std::string cxml = xml;
+ 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;
+ 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;
+ 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;
+ 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;
+ cxml.erase(cdatastart.start(),
+ cdataend.end() - cdatastart.start());
+ }
+ else if ( measurementfile.find(cxml) )
+ {
+ const std::string& filename =
+ cmCTest::CleanString(measurementfile.match(5));
+ if ( cmSystemTools::FileExists(filename.c_str()) )
+ {
+ long len = cmSystemTools::FileLength(filename.c_str());
+ if ( len == 0 )
+ {
+ std::string k1 = measurementfile.match(1);
+ std::string v1 = measurementfile.match(2);
+ std::string k2 = measurementfile.match(3);
+ std::string v2 = measurementfile.match(4);
+ if ( cmSystemTools::LowerCase(k1) == "type" )
+ {
+ v1 = "text/string";
+ }
+ if ( cmSystemTools::LowerCase(k2) == "type" )
+ {
+ v2 = "text/string";
+ }
+
+ ostr
+ << "\t\t\t<NamedMeasurement"
+ << " " << k1 << "=\"" << v1 << "\""
+ << " " << k2 << "=\"" << v2 << "\""
+ << " encoding=\"none\""
+ << "><Value>Image " << filename.c_str()
+ << " is empty</Value></NamedMeasurement>";
+ }
+ else
+ {
+ std::ifstream ifs(filename.c_str(), std::ios::in
+#ifdef _WIN32
+ | std::ios::binary
+#endif
+ );
+ unsigned char *file_buffer = new unsigned char [ len + 1 ];
+ ifs.read(reinterpret_cast<char*>(file_buffer), len);
+ unsigned char *encoded_buffer
+ = new unsigned char [ static_cast<int>(
+ static_cast<double>(len) * 1.5 + 5.0) ];
+
+ unsigned long 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 ++ )
+ {
+ ostr << encoded_buffer[cc];
+ if ( cc % 60 == 0 && cc )
+ {
+ ostr << std::endl;
+ }
+ }
+ ostr
+ << "</Value>" << std::endl << "\t\t\t</NamedMeasurement>"
+ << std::endl;
+ delete [] file_buffer;
+ delete [] encoded_buffer;
+ }
+ }
+ else
+ {
+ int idx = 4;
+ if ( measurementfile.match(1) == "name" )
+ {
+ 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);
+ }
+ cxml.erase(measurementfile.start(),
+ measurementfile.end() - measurementfile.start());
+ }
+ else
+ {
+ done = true;
+ }
+ }
+ return ostr.str();
+}
+
+//----------------------------------------------------------------------
+void cmCTestTestHandler::SetIncludeRegExp(const char *arg)
+{
+ this->IncludeRegExp = arg;
+}
+
+//----------------------------------------------------------------------
+void cmCTestTestHandler::SetExcludeRegExp(const char *arg)
+{
+ this->ExcludeRegExp = arg;
+}
+
+//----------------------------------------------------------------------
+void cmCTestTestHandler::SetTestsToRunInformation(const char* in)
+{
+ if ( !in )
+ {
+ return;
+ }
+ this->TestsToRunString = in;
+ // if the argument is a file, then read it and use the contents as the
+ // string
+ if(cmSystemTools::FileExists(in))
+ {
+ std::ifstream fin(in);
+ unsigned long filelen = cmSystemTools::FileLength(in);
+ char* buff = new char[filelen+1];
+ fin.getline(buff, filelen);
+ buff[fin.gcount()] = 0;
+ this->TestsToRunString = buff;
+ delete [] buff;
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestTestHandler::CleanTestOutput(std::string& output, size_t length)
+{
+ if(!length || length >= output.size() ||
+ output.find("CTEST_FULL_OUTPUT") != output.npos)
+ {
+ return true;
+ }
+
+ // Truncate at given length but do not break in the middle of a multi-byte
+ // UTF-8 encoding.
+ char const* const begin = output.c_str();
+ char const* const end = begin + output.size();
+ char const* const truncate = begin + length;
+ char const* current = begin;
+ while(current < truncate)
+ {
+ unsigned int ch;
+ if(const char* next = cm_utf8_decode_character(current, end, &ch))
+ {
+ if(next > truncate)
+ {
+ break;
+ }
+ current = next;
+ }
+ else // Bad byte will be handled by cmXMLSafe.
+ {
+ ++current;
+ }
+ }
+ output = output.substr(0, current - begin);
+
+ // Append truncation message.
+ cmOStringStream msg;
+ msg << "...\n"
+ "The rest of the test output was removed since it exceeds the threshold "
+ "of " << length << " bytes.\n";
+ output += msg.str();
+ return true;
+}
+
+//----------------------------------------------------------------------
+bool cmCTestTestHandler::SetTestsProperties(
+ const std::vector<std::string>& args)
+{
+ std::vector<std::string>::const_iterator it;
+ std::vector<cmStdString> tests;
+ bool found = false;
+ for ( it = args.begin(); it != args.end(); ++ it )
+ {
+ if ( *it == "PROPERTIES" )
+ {
+ found = true;
+ break;
+ }
+ tests.push_back(*it);
+ }
+ if ( !found )
+ {
+ return false;
+ }
+ ++ it; // skip PROPERTIES
+ for ( ; it != args.end(); ++ it )
+ {
+ std::string key = *it;
+ ++ it;
+ if ( it == args.end() )
+ {
+ break;
+ }
+ std::string val = *it;
+ std::vector<cmStdString>::const_iterator tit;
+ for ( tit = tests.begin(); tit != tests.end(); ++ tit )
+ {
+ cmCTestTestHandler::ListOfTests::iterator rtit;
+ for ( rtit = this->TestList.begin();
+ rtit != this->TestList.end();
+ ++ rtit )
+ {
+ if ( *tit == rtit->Name )
+ {
+ if ( key == "WILL_FAIL" )
+ {
+ rtit->WillFail = cmSystemTools::IsOn(val.c_str());
+ }
+ 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);
+ }
+ }
+ 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);
+ }
+ }
+ if ( key == "RESOURCE_LOCK" )
+ {
+ 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->LockedResources.insert(*f);
+ }
+ }
+ if ( key == "TIMEOUT" )
+ {
+ rtit->Timeout = atof(val.c_str());
+ rtit->ExplicitTimeout = true;
+ }
+ if ( key == "COST" )
+ {
+ rtit->Cost = static_cast<float>(atof(val.c_str()));
+ }
+ 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);
+ }
+ }
+ if ( key == "RUN_SERIAL" )
+ {
+ rtit->RunSerial = cmSystemTools::IsOn(val.c_str());
+ }
+ if ( key == "FAIL_REGULAR_EXPRESSION" )
+ {
+ 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->ErrorRegularExpressions.push_back(
+ std::pair<cmsys::RegularExpression, std::string>(
+ cmsys::RegularExpression(crit->c_str()),
+ std::string(crit->c_str())));
+ }
+ }
+ if ( key == "PROCESSORS" )
+ {
+ rtit->Processors = atoi(val.c_str());
+ if(rtit->Processors < 1)
+ {
+ rtit->Processors = 1;
+ }
+ }
+ if ( key == "DEPENDS" )
+ {
+ 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->Depends.push_back(*crit);
+ }
+ }
+ 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);
+ }
+ }
+ 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);
+ }
+ }
+ if ( key == "MEASUREMENT" )
+ {
+ size_t pos = val.find_first_of("=");
+ if ( pos != val.npos )
+ {
+ std::string mKey = val.substr(0, pos);
+ const char* mVal = val.c_str() + pos + 1;
+ rtit->Measurements[mKey] = mVal;
+ }
+ else
+ {
+ rtit->Measurements[val] = "1";
+ }
+ }
+ if ( key == "PASS_REGULAR_EXPRESSION" )
+ {
+ 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->RequiredRegularExpressions.push_back(
+ std::pair<cmsys::RegularExpression, std::string>(
+ cmsys::RegularExpression(crit->c_str()),
+ std::string(crit->c_str())));
+ }
+ }
+ if ( key == "WORKING_DIRECTORY" )
+ {
+ rtit->Directory = val;
+ }
+ }
+ }
+ }
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------
+bool cmCTestTestHandler::AddTest(const std::vector<std::string>& args)
+{
+ const std::string& testname = args[0];
+ cmCTestLog(this->CTest, DEBUG, "Add test: " << args[0] << std::endl);
+
+ if (this->UseExcludeRegExpFlag &&
+ this->UseExcludeRegExpFirst &&
+ this->ExcludeTestsRegularExpression.find(testname.c_str()))
+ {
+ return true;
+ }
+ if ( this->MemCheck )
+ {
+ std::vector<cmStdString>::iterator it;
+ bool found = false;
+ for ( it = this->CustomTestsIgnore.begin();
+ it != this->CustomTestsIgnore.end(); ++ it )
+ {
+ if ( *it == testname )
+ {
+ found = true;
+ break;
+ }
+ }
+ if ( found )
+ {
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Ignore memcheck: "
+ << *it << std::endl);
+ return true;
+ }
+ }
+ else
+ {
+ std::vector<cmStdString>::iterator it;
+ bool found = false;
+ for ( it = this->CustomTestsIgnore.begin();
+ it != this->CustomTestsIgnore.end(); ++ it )
+ {
+ if ( *it == testname )
+ {
+ found = true;
+ break;
+ }
+ }
+ if ( found )
+ {
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Ignore test: "
+ << *it << std::endl);
+ return true;
+ }
+ }
+
+ cmCTestTestProperties test;
+ test.Name = testname;
+ test.Args = args;
+ test.Directory = cmSystemTools::GetCurrentWorkingDirectory();
+ cmCTestLog(this->CTest, DEBUG, "Set test directory: "
+ << test.Directory << std::endl);
+
+ test.IsInBasedOnREOptions = true;
+ test.WillFail = false;
+ test.RunSerial = false;
+ test.Timeout = 0;
+ test.ExplicitTimeout = false;
+ test.Cost = 0;
+ test.Processors = 1;
+ test.PreviousRuns = 0;
+ if (this->UseIncludeRegExpFlag &&
+ !this->IncludeTestsRegularExpression.find(testname.c_str()))
+ {
+ test.IsInBasedOnREOptions = false;
+ }
+ else if (this->UseExcludeRegExpFlag &&
+ !this->UseExcludeRegExpFirst &&
+ this->ExcludeTestsRegularExpression.find(testname.c_str()))
+ {
+ test.IsInBasedOnREOptions = false;
+ }
+ this->TestList.push_back(test);
+ return true;
+}
+
diff --git a/Source/CTest/cmCTestTestHandler.h b/Source/CTest/cmCTestTestHandler.h
new file mode 100644
index 000000000..8e59e5915
--- /dev/null
+++ b/Source/CTest/cmCTestTestHandler.h
@@ -0,0 +1,273 @@
+/*============================================================================
+ 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 cmCTestTestHandler_h
+#define cmCTestTestHandler_h
+
+
+#include "cmCTestGenericHandler.h"
+#include <cmsys/RegularExpression.hxx>
+
+class cmMakefile;
+
+/** \class cmCTestTestHandler
+ * \brief A class that handles ctest -S invocations
+ *
+ */
+class cmCTestTestHandler : public cmCTestGenericHandler
+{
+ friend class cmCTestRunTest;
+ friend class cmCTestMultiProcessHandler;
+ friend class cmCTestBatchTestHandler;
+public:
+ cmTypeMacro(cmCTestTestHandler, cmCTestGenericHandler);
+
+ /**
+ * The main entry point for this class
+ */
+ int ProcessHandler();
+
+ /**
+ * When both -R and -I are used should te resulting test list be the
+ * intersection or the union of the lists. By default it is the
+ * intersection.
+ */
+ void SetUseUnion(bool val) { this->UseUnion = val; }
+
+ /**
+ * This method is called when reading CTest custom file
+ */
+ void PopulateCustomVectors(cmMakefile *mf);
+
+ ///! Control the use of the regular expresisons, call these methods to turn
+ ///them on
+ void UseIncludeRegExp();
+ void UseExcludeRegExp();
+ void SetIncludeRegExp(const char *);
+ void SetExcludeRegExp(const char *);
+
+ void SetMaxIndex(int n) {this->MaxIndex = n;}
+ int GetMaxIndex() {return this->MaxIndex;}
+
+ ///! pass the -I argument down
+ void SetTestsToRunInformation(const char*);
+
+ cmCTestTestHandler();
+
+ /*
+ * Add the test to the list of tests to be executed
+ */
+ bool AddTest(const std::vector<std::string>& args);
+
+ /*
+ * Set tests properties
+ */
+ bool SetTestsProperties(const std::vector<std::string>& args);
+
+ void Initialize();
+
+ // NOTE: This struct is Saved/Restored
+ // in cmCTestTestHandler, if you add to this class
+ // then you must add the new members to that code or
+ // ctest -j N will break for that feature
+ struct cmCTestTestProperties
+ {
+ cmStdString Name;
+ cmStdString Directory;
+ std::vector<std::string> Args;
+ std::vector<std::string> RequiredFiles;
+ std::vector<std::string> Depends;
+ std::vector<std::string> AttachedFiles;
+ std::vector<std::string> AttachOnFail;
+ std::vector<std::pair<cmsys::RegularExpression,
+ std::string> > ErrorRegularExpressions;
+ std::vector<std::pair<cmsys::RegularExpression,
+ std::string> > RequiredRegularExpressions;
+ std::map<cmStdString, cmStdString> Measurements;
+ bool IsInBasedOnREOptions;
+ bool WillFail;
+ float Cost;
+ int PreviousRuns;
+ bool RunSerial;
+ double Timeout;
+ bool ExplicitTimeout;
+ int Index;
+ //Requested number of process slots
+ int Processors;
+ std::vector<std::string> Environment;
+ std::vector<std::string> Labels;
+ std::set<std::string> LockedResources;
+ };
+
+ struct cmCTestTestResult
+ {
+ std::string Name;
+ std::string Path;
+ std::string Reason;
+ std::string FullCommandLine;
+ double ExecutionTime;
+ int ReturnValue;
+ int Status;
+ bool CompressOutput;
+ std::string CompletionStatus;
+ std::string Output;
+ std::string RegressionImages;
+ int TestCount;
+ cmCTestTestProperties* Properties;
+ };
+
+ struct cmCTestTestResultLess
+ {
+ bool operator() (const cmCTestTestResult &lhs,
+ const cmCTestTestResult &rhs) const
+ {
+ return lhs.TestCount < rhs.TestCount;
+ }
+ };
+
+ // add configurations to a search path for an executable
+ static void AddConfigurations(cmCTest *ctest,
+ std::vector<std::string> &attempted,
+ std::vector<std::string> &attemptedConfigs,
+ std::string filepath,
+ std::string &filename);
+
+ // full signature static method to find an executable
+ static std::string FindExecutable(cmCTest *ctest,
+ const char *testCommand,
+ std::string &resultingConfig,
+ std::vector<std::string> &extraPaths,
+ std::vector<std::string> &failed);
+
+ typedef std::vector<cmCTestTestProperties> ListOfTests;
+protected:
+ // compute a final test list
+ virtual int PreProcessHandler();
+ virtual int PostProcessHandler();
+ virtual void GenerateTestCommand(std::vector<std::string>& args);
+ int ExecuteCommands(std::vector<cmStdString>& vec);
+
+ void WriteTestResultHeader(std::ostream& os, cmCTestTestResult* result);
+ void WriteTestResultFooter(std::ostream& os, cmCTestTestResult* result);
+ // Write attached test files into the xml
+ void AttachFiles(std::ostream& os, cmCTestTestResult* result);
+
+ //! Clean test output to specified length
+ bool CleanTestOutput(std::string& output, size_t length);
+
+ double ElapsedTestingTime;
+
+ typedef std::vector<cmCTestTestResult> TestResultsVector;
+ TestResultsVector TestResults;
+
+ std::vector<cmStdString> CustomTestsIgnore;
+ std::string StartTest;
+ std::string EndTest;
+ unsigned int StartTestTime;
+ unsigned int EndTestTime;
+ bool MemCheck;
+ int CustomMaximumPassedTestOutputSize;
+ int CustomMaximumFailedTestOutputSize;
+ int MaxIndex;
+public:
+ enum { // Program statuses
+ NOT_RUN = 0,
+ TIMEOUT,
+ SEGFAULT,
+ ILLEGAL,
+ INTERRUPT,
+ NUMERICAL,
+ OTHER_FAULT,
+ FAILED,
+ BAD_COMMAND,
+ COMPLETED
+ };
+
+private:
+ /**
+ * Generate the Dart compatible output
+ */
+ virtual void GenerateDartOutput(std::ostream& os);
+
+ void PrintLabelSummary();
+ /**
+ * Run the tests for a directory and any subdirectories
+ */
+ void ProcessDirectory(std::vector<cmStdString> &passed,
+ std::vector<cmStdString> &failed);
+
+ /**
+ * Get the list of tests in directory and subdirectories.
+ */
+ void GetListOfTests();
+ // compute the lists of tests that will actually run
+ // based on union regex and -I stuff
+ void ComputeTestList();
+
+ bool GetValue(const char* tag,
+ std::string& value,
+ std::ifstream& fin);
+ bool GetValue(const char* tag,
+ int& value,
+ std::ifstream& fin);
+ bool GetValue(const char* tag,
+ size_t& value,
+ std::ifstream& fin);
+ bool GetValue(const char* tag,
+ bool& value,
+ std::ifstream& fin);
+ bool GetValue(const char* tag,
+ double& value,
+ std::ifstream& fin);
+ /**
+ * Find the executable for a test
+ */
+ std::string FindTheExecutable(const char *exe);
+
+ const char* GetTestStatus(int status);
+ void ExpandTestsToRunInformation(size_t numPossibleTests);
+
+ std::vector<cmStdString> CustomPreTest;
+ std::vector<cmStdString> CustomPostTest;
+
+ std::vector<int> TestsToRun;
+
+ bool UseIncludeLabelRegExpFlag;
+ bool UseExcludeLabelRegExpFlag;
+ bool UseIncludeRegExpFlag;
+ bool UseExcludeRegExpFlag;
+ bool UseExcludeRegExpFirst;
+ std::string IncludeLabelRegExp;
+ std::string ExcludeLabelRegExp;
+ std::string IncludeRegExp;
+ std::string ExcludeRegExp;
+ cmsys::RegularExpression IncludeLabelRegularExpression;
+ cmsys::RegularExpression ExcludeLabelRegularExpression;
+ cmsys::RegularExpression IncludeTestsRegularExpression;
+ cmsys::RegularExpression ExcludeTestsRegularExpression;
+
+ std::string GenerateRegressionImages(const std::string& xml);
+ cmsys::RegularExpression DartStuff1;
+ void CheckLabelFilter(cmCTestTestProperties& it);
+ void CheckLabelFilterExclude(cmCTestTestProperties& it);
+ void CheckLabelFilterInclude(cmCTestTestProperties& it);
+
+ std::string TestsToRunString;
+ bool UseUnion;
+ ListOfTests TestList;
+ size_t TotalNumberOfTests;
+ cmsys::RegularExpression DartStuff;
+
+ std::ostream* LogFile;
+};
+
+#endif
diff --git a/Source/CTest/cmCTestUpdateCommand.cxx b/Source/CTest/cmCTestUpdateCommand.cxx
new file mode 100644
index 000000000..841434911
--- /dev/null
+++ b/Source/CTest/cmCTestUpdateCommand.cxx
@@ -0,0 +1,78 @@
+/*============================================================================
+ 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 "cmCTestUpdateCommand.h"
+
+#include "cmCTest.h"
+#include "cmCTestGenericHandler.h"
+
+cmCTestGenericHandler* cmCTestUpdateCommand::InitializeHandler()
+{
+ if ( this->Values[ct_SOURCE] )
+ {
+ this->CTest->SetCTestConfiguration("SourceDirectory",
+ cmSystemTools::CollapseFullPath(
+ this->Values[ct_SOURCE]).c_str());
+ }
+ else
+ {
+ this->CTest->SetCTestConfiguration("SourceDirectory",
+ cmSystemTools::CollapseFullPath(
+ this->Makefile->GetDefinition("CTEST_SOURCE_DIRECTORY")).c_str());
+ }
+ std::string source_dir
+ = this->CTest->GetCTestConfiguration("SourceDirectory");
+
+ this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
+ "UpdateCommand", "CTEST_UPDATE_COMMAND");
+ this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
+ "UpdateOptions", "CTEST_UPDATE_OPTIONS");
+ this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
+ "CVSCommand", "CTEST_CVS_COMMAND");
+ this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
+ "CVSUpdateOptions", "CTEST_CVS_UPDATE_OPTIONS");
+ this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
+ "SVNCommand", "CTEST_SVN_COMMAND");
+ this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
+ "SVNUpdateOptions", "CTEST_SVN_UPDATE_OPTIONS");
+ this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
+ "BZRCommand", "CTEST_BZR_COMMAND");
+ this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
+ "BZRUpdateOptions", "CTEST_BZR_UPDATE_OPTIONS");
+ this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
+ "GITCommand", "CTEST_GIT_COMMAND");
+ this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
+ "GITUpdateOptions", "CTEST_GIT_UPDATE_OPTIONS");
+ this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
+ "GITUpdateCustom", "CTEST_GIT_UPDATE_CUSTOM");
+ this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
+ "HGCommand", "CTEST_HG_COMMAND");
+ this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile,
+ "HGUpdateOptions", "CTEST_HG_UPDATE_OPTIONS");
+
+ cmCTestGenericHandler* handler
+ = this->CTest->GetInitializedHandler("update");
+ if ( !handler )
+ {
+ this->SetError("internal CTest error. Cannot instantiate update handler");
+ return 0;
+ }
+ handler->SetCommand(this);
+ if ( source_dir.empty() )
+ {
+ this->SetError("source directory not specified. Please use SOURCE tag");
+ return 0;
+ }
+ handler->SetOption("SourceDirectory", source_dir.c_str());
+ return handler;
+}
+
+
diff --git a/Source/CTest/cmCTestUpdateCommand.h b/Source/CTest/cmCTestUpdateCommand.h
new file mode 100644
index 000000000..c578fff6f
--- /dev/null
+++ b/Source/CTest/cmCTestUpdateCommand.h
@@ -0,0 +1,73 @@
+/*============================================================================
+ 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 cmCTestUpdateCommand_h
+#define cmCTestUpdateCommand_h
+
+#include "cmCTestHandlerCommand.h"
+
+/** \class cmCTestUpdate
+ * \brief Run a ctest script
+ *
+ * cmCTestUpdateCommand defineds the command to updates the repository.
+ */
+class cmCTestUpdateCommand : public cmCTestHandlerCommand
+{
+public:
+
+ cmCTestUpdateCommand() {}
+
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ cmCTestUpdateCommand* ni = new cmCTestUpdateCommand;
+ ni->CTest = this->CTest;
+ ni->CTestScriptHandler = this->CTestScriptHandler;
+ return ni;
+ }
+
+ /**
+ * 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."
+ ;
+ }
+
+ cmTypeMacro(cmCTestUpdateCommand, cmCTestHandlerCommand);
+
+protected:
+ cmCTestGenericHandler* InitializeHandler();
+};
+
+
+#endif
diff --git a/Source/CTest/cmCTestUpdateHandler.cxx b/Source/CTest/cmCTestUpdateHandler.cxx
new file mode 100644
index 000000000..9eae3f3ac
--- /dev/null
+++ b/Source/CTest/cmCTestUpdateHandler.cxx
@@ -0,0 +1,404 @@
+/*============================================================================
+ 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 "cmCTestUpdateHandler.h"
+
+#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 "cmCTestVC.h"
+#include "cmCTestCVS.h"
+#include "cmCTestSVN.h"
+#include "cmCTestBZR.h"
+#include "cmCTestGIT.h"
+#include "cmCTestHG.h"
+
+#include <cmsys/auto_ptr.hxx>
+
+//#include <cmsys/RegularExpression.hxx>
+#include <cmsys/Process.h>
+
+// used for sleep
+#ifdef _WIN32
+#include "windows.h"
+#endif
+
+#include <stdlib.h>
+#include <math.h>
+#include <float.h>
+
+//----------------------------------------------------------------------
+static const char* cmCTestUpdateHandlerUpdateStrings[] =
+{
+ "Unknown",
+ "CVS",
+ "SVN",
+ "BZR",
+ "GIT",
+ "HG"
+};
+
+static const char* cmCTestUpdateHandlerUpdateToString(int type)
+{
+ if ( type < cmCTestUpdateHandler::e_UNKNOWN ||
+ type >= cmCTestUpdateHandler::e_LAST )
+ {
+ return cmCTestUpdateHandlerUpdateStrings[cmCTestUpdateHandler::e_UNKNOWN];
+ }
+ 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()
+{
+}
+
+//----------------------------------------------------------------------
+void cmCTestUpdateHandler::Initialize()
+{
+ this->Superclass::Initialize();
+ this->UpdateCommand = "";
+ this->UpdateType = e_CVS;
+}
+
+//----------------------------------------------------------------------
+int cmCTestUpdateHandler::DetermineType(const char* cmd, const char* type)
+{
+ cmCTestLog(this->CTest, DEBUG, "Determine update type from command: " << cmd
+ << " and type: " << type << std::endl);
+ if ( type && *type )
+ {
+ cmCTestLog(this->CTest, DEBUG, "Type specified: " << type << std::endl);
+ std::string stype = cmSystemTools::LowerCase(type);
+ if ( stype.find("cvs") != std::string::npos )
+ {
+ return cmCTestUpdateHandler::e_CVS;
+ }
+ if ( stype.find("svn") != std::string::npos )
+ {
+ return cmCTestUpdateHandler::e_SVN;
+ }
+ if ( stype.find("bzr") != std::string::npos )
+ {
+ return cmCTestUpdateHandler::e_BZR;
+ }
+ if ( stype.find("git") != std::string::npos )
+ {
+ return cmCTestUpdateHandler::e_GIT;
+ }
+ if ( stype.find("hg") != std::string::npos )
+ {
+ return cmCTestUpdateHandler::e_HG;
+ }
+ }
+ else
+ {
+ cmCTestLog(this->CTest, DEBUG, "Type not specified, check command: "
+ << cmd << std::endl);
+ std::string stype = cmSystemTools::LowerCase(cmd);
+ if ( stype.find("cvs") != std::string::npos )
+ {
+ return cmCTestUpdateHandler::e_CVS;
+ }
+ if ( stype.find("svn") != std::string::npos )
+ {
+ return cmCTestUpdateHandler::e_SVN;
+ }
+ if ( stype.find("bzr") != std::string::npos )
+ {
+ return cmCTestUpdateHandler::e_BZR;
+ }
+ if ( stype.find("git") != std::string::npos )
+ {
+ return cmCTestUpdateHandler::e_GIT;
+ }
+ if ( stype.find("hg") != std::string::npos )
+ {
+ return cmCTestUpdateHandler::e_HG;
+ }
+ }
+ return cmCTestUpdateHandler::e_UNKNOWN;
+}
+
+//----------------------------------------------------------------------
+//clearly it would be nice if this were broken up into a few smaller
+//functions and commented...
+int cmCTestUpdateHandler::ProcessHandler()
+{
+ // Make sure VCS tool messages are in English so we can parse them.
+ cmCTestUpdateHandlerLocale fixLocale;
+ static_cast<void>(fixLocale);
+
+ // Get source dir
+ const char* sourceDirectory = this->GetOption("SourceDirectory");
+ if ( !sourceDirectory )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Cannot find SourceDirectory key in the DartConfiguration.tcl"
+ << std::endl);
+ return -1;
+ }
+
+ cmGeneratedFileStream ofs;
+ if ( !this->CTest->GetShowOnly() )
+ {
+ this->StartLogFile("Update", ofs);
+ }
+
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " Updating the repository: "
+ << sourceDirectory << std::endl);
+
+ if(!this->SelectVCS())
+ {
+ return -1;
+ }
+
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " Use "
+ << cmCTestUpdateHandlerUpdateToString(this->UpdateType)
+ << " repository type"
+ << std::endl;);
+
+ // Create an object to interact with the VCS tool.
+ cmsys::auto_ptr<cmCTestVC> vc;
+ switch (this->UpdateType)
+ {
+ case e_CVS: vc.reset(new cmCTestCVS(this->CTest, ofs)); break;
+ case e_SVN: vc.reset(new cmCTestSVN(this->CTest, ofs)); break;
+ 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;
+ default: vc.reset(new cmCTestVC(this->CTest, ofs)); break;
+ }
+ vc->SetCommandLineTool(this->UpdateCommand);
+ vc->SetSourceDirectory(sourceDirectory);
+
+ // Cleanup the working tree.
+ vc->Cleanup();
+
+ //
+ // Now update repository and remember what files were updated
+ //
+ cmGeneratedFileStream os;
+ if(!this->StartResultingXML(cmCTest::PartUpdate, "Update", os))
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot open log file"
+ << std::endl);
+ return -1;
+ }
+ std::string start_time = this->CTest->CurrentTime();
+ unsigned int start_time_time =
+ static_cast<unsigned int>(cmSystemTools::GetTime());
+ 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);
+
+ int localModifications = 0;
+ int numUpdated = vc->GetPathCount(cmCTestVC::PathUpdated);
+ if(numUpdated)
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ " Found " << numUpdated << " updated files\n");
+ }
+ if(int numModified = vc->GetPathCount(cmCTestVC::PathModified))
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ " Found " << numModified << " locally modified files\n");
+ localModifications += numModified;
+ }
+ if(int numConflicting = vc->GetPathCount(cmCTestVC::PathConflicting))
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ " Found " << numConflicting << " conflicting files\n");
+ localModifications += numConflicting;
+ }
+
+ cmCTestLog(this->CTest, DEBUG, "End" << std::endl);
+ 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>";
+ if(localModifications)
+ {
+ os << "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: "
+ << vc->GetUpdateCommandLine() << "\n");
+ }
+ os << "</UpdateReturnStatus>" << std::endl;
+ os << "</Update>" << std::endl;
+ return numUpdated;
+}
+
+//----------------------------------------------------------------------
+int cmCTestUpdateHandler::DetectVCS(const char* dir)
+{
+ std::string sourceDirectory = dir;
+ cmCTestLog(this->CTest, DEBUG, "Check directory: "
+ << sourceDirectory.c_str() << std::endl);
+ sourceDirectory += "/.svn";
+ if ( cmSystemTools::FileExists(sourceDirectory.c_str()) )
+ {
+ return cmCTestUpdateHandler::e_SVN;
+ }
+ sourceDirectory = dir;
+ sourceDirectory += "/CVS";
+ if ( cmSystemTools::FileExists(sourceDirectory.c_str()) )
+ {
+ return cmCTestUpdateHandler::e_CVS;
+ }
+ sourceDirectory = dir;
+ sourceDirectory += "/.bzr";
+ if ( cmSystemTools::FileExists(sourceDirectory.c_str()) )
+ {
+ return cmCTestUpdateHandler::e_BZR;
+ }
+ sourceDirectory = dir;
+ sourceDirectory += "/.git";
+ if ( cmSystemTools::FileExists(sourceDirectory.c_str()) )
+ {
+ return cmCTestUpdateHandler::e_GIT;
+ }
+ sourceDirectory = dir;
+ sourceDirectory += "/.hg";
+ if ( cmSystemTools::FileExists(sourceDirectory.c_str()) )
+ {
+ return cmCTestUpdateHandler::e_HG;
+ }
+ return cmCTestUpdateHandler::e_UNKNOWN;
+}
+
+//----------------------------------------------------------------------
+bool cmCTestUpdateHandler::SelectVCS()
+{
+ // Get update command
+ this->UpdateCommand = this->CTest->GetCTestConfiguration("UpdateCommand");
+
+ // Detect the VCS managing the source tree.
+ this->UpdateType = this->DetectVCS(this->GetOption("SourceDirectory"));
+ if (this->UpdateType == e_UNKNOWN)
+ {
+ // The source tree does not have a recognized VCS. Check the
+ // configuration value or command name.
+ this->UpdateType = this->DetermineType(this->UpdateCommand.c_str(),
+ this->CTest->GetCTestConfiguration("UpdateType").c_str());
+ }
+
+ // If no update command was specified, lookup one for this VCS tool.
+ if (this->UpdateCommand.empty())
+ {
+ const char* key = 0;
+ switch (this->UpdateType)
+ {
+ case e_CVS: key = "CVSCommand"; break;
+ case e_SVN: key = "SVNCommand"; break;
+ case e_BZR: key = "BZRCommand"; break;
+ case e_GIT: key = "GITCommand"; break;
+ case e_HG: key = "HGCommand"; break;
+ default: break;
+ }
+ if (key)
+ {
+ this->UpdateCommand = this->CTest->GetCTestConfiguration(key);
+ }
+ if (this->UpdateCommand.empty())
+ {
+ cmOStringStream e;
+ e << "Cannot find UpdateCommand ";
+ if (key)
+ {
+ e << "or " << key;
+ }
+ e << " configuration key.";
+ cmCTestLog(this->CTest, ERROR_MESSAGE, e.str() << std::endl);
+ return false;
+ }
+ }
+
+ return true;
+}
diff --git a/Source/CTest/cmCTestUpdateHandler.h b/Source/CTest/cmCTestUpdateHandler.h
new file mode 100644
index 000000000..55ec974dc
--- /dev/null
+++ b/Source/CTest/cmCTestUpdateHandler.h
@@ -0,0 +1,76 @@
+/*============================================================================
+ 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 cmCTestUpdateHandler_h
+#define cmCTestUpdateHandler_h
+
+
+#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
+ *
+ */
+class cmCTestUpdateHandler : public cmCTestGenericHandler
+{
+public:
+ cmTypeMacro(cmCTestUpdateHandler, cmCTestGenericHandler);
+
+ /*
+ * The main entry point for this class
+ */
+ int ProcessHandler();
+
+ cmCTestUpdateHandler();
+
+ enum {
+ e_UNKNOWN = 0,
+ e_CVS,
+ e_SVN,
+ e_BZR,
+ e_GIT,
+ e_HG,
+ e_LAST
+ };
+
+ /**
+ * Initialize handler
+ */
+ virtual void Initialize();
+
+private:
+ // Some structures needed for update
+ struct StringPair :
+ public std::pair<std::string, std::string>{};
+ struct UpdateFiles : public std::vector<StringPair>{};
+
+ // Determine the type of version control
+ int DetermineType(const char* cmd, const char* type);
+
+ // The VCS command to update the working tree.
+ std::string UpdateCommand;
+ int UpdateType;
+
+ int DetectVCS(const char* dir);
+ 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
new file mode 100644
index 000000000..731c1c7a3
--- /dev/null
+++ b/Source/CTest/cmCTestUploadCommand.cxx
@@ -0,0 +1,69 @@
+/*============================================================================
+ 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 "cmCTestUploadCommand.h"
+
+#include "cmCTest.h"
+#include "cmCTestGenericHandler.h"
+#include "cmCTestUploadHandler.h"
+
+cmCTestGenericHandler* cmCTestUploadCommand::InitializeHandler()
+{
+ cmCTestGenericHandler* handler
+ = this->CTest->GetInitializedHandler("upload");
+ if ( !handler )
+ {
+ this->SetError("internal CTest error. Cannot instantiate upload handler");
+ return 0;
+ }
+ static_cast<cmCTestUploadHandler*>(handler)->SetFiles(this->Files);
+
+ return handler;
+}
+
+
+//----------------------------------------------------------------------------
+bool cmCTestUploadCommand::CheckArgumentKeyword(std::string const& arg)
+{
+ if(arg == "FILES")
+ {
+ this->ArgumentDoing = ArgumentDoingFiles;
+ return true;
+ }
+ return false;
+}
+
+
+//----------------------------------------------------------------------------
+bool cmCTestUploadCommand::CheckArgumentValue(std::string const& arg)
+{
+ if(this->ArgumentDoing == ArgumentDoingFiles)
+ {
+ cmStdString filename(arg);
+ if(cmSystemTools::FileExists(filename.c_str()))
+ {
+ this->Files.insert(filename);
+ return true;
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "File \"" << filename << "\" does not exist. Cannot submit "
+ << "a non-existent file.";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ this->ArgumentDoing = ArgumentDoingError;
+ return false;
+ }
+ }
+
+ // Look for other arguments.
+ return this->Superclass::CheckArgumentValue(arg);
+}
diff --git a/Source/CTest/cmCTestUploadCommand.h b/Source/CTest/cmCTestUploadCommand.h
new file mode 100644
index 000000000..62f379f6d
--- /dev/null
+++ b/Source/CTest/cmCTestUploadCommand.h
@@ -0,0 +1,85 @@
+/*============================================================================
+ 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 cmCTestUploadCommand_h
+#define cmCTestUploadCommand_h
+
+#include "cmCTestHandlerCommand.h"
+#include "cmCTest.h"
+
+/** \class cmCTestUpload
+ * \brief Run a ctest script
+ *
+ * cmCTestUploadCommand defines the command to upload result files for
+ * the project.
+ */
+class cmCTestUploadCommand : public cmCTestHandlerCommand
+{
+public:
+
+ cmCTestUploadCommand()
+ {
+ }
+
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ cmCTestUploadCommand* ni = new cmCTestUploadCommand;
+ ni->CTest = this->CTest;
+ ni->CTestScriptHandler = this->CTestScriptHandler;
+ return ni;
+ }
+
+ /**
+ * 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";
+ }
+
+ cmTypeMacro(cmCTestUploadCommand, cmCTestHandlerCommand);
+
+protected:
+ cmCTestGenericHandler* InitializeHandler();
+
+ virtual bool CheckArgumentKeyword(std::string const& arg);
+ virtual bool CheckArgumentValue(std::string const& arg);
+
+ enum
+ {
+ ArgumentDoingFiles = Superclass::ArgumentDoingLast1,
+ ArgumentDoingLast2
+ };
+
+ cmCTest::SetOfStrings Files;
+};
+
+
+#endif
diff --git a/Source/CTest/cmCTestUploadHandler.cxx b/Source/CTest/cmCTestUploadHandler.cxx
new file mode 100644
index 000000000..caf2e5370
--- /dev/null
+++ b/Source/CTest/cmCTestUploadHandler.cxx
@@ -0,0 +1,77 @@
+/*============================================================================
+ 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 "cmCTestUploadHandler.h"
+
+#include "cmGeneratedFileStream.h"
+#include "cmVersion.h"
+#include "cmXMLSafe.h"
+
+//----------------------------------------------------------------------------
+cmCTestUploadHandler::cmCTestUploadHandler()
+{
+ this->Initialize();
+}
+
+//----------------------------------------------------------------------------
+void cmCTestUploadHandler::Initialize()
+{
+ this->Superclass::Initialize();
+ this->Files.clear();
+}
+
+void cmCTestUploadHandler::SetFiles(const cmCTest::SetOfStrings& files)
+{
+ this->Files = files;
+}
+
+//----------------------------------------------------------------------------
+int cmCTestUploadHandler::ProcessHandler()
+{
+ cmGeneratedFileStream ofs;
+ if ( !this->CTest->OpenOutputFile(this->CTest->GetCurrentTag(),
+ "Upload.xml", ofs))
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Cannot open Upload.xml file" << std::endl);
+ return -1;
+ }
+
+ cmCTest::SetOfStrings::const_iterator it;
+ ofs << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ << "<?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";
+
+ 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";
+ }
+ ofs << "</Upload>\n"
+ << "</Site>\n";
+ return 0;
+}
diff --git a/Source/CTest/cmCTestUploadHandler.h b/Source/CTest/cmCTestUploadHandler.h
new file mode 100644
index 000000000..23ed35a25
--- /dev/null
+++ b/Source/CTest/cmCTestUploadHandler.h
@@ -0,0 +1,45 @@
+/*============================================================================
+ 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 cmCTestUploadHandler_h
+#define cmCTestUploadHandler_h
+
+#include "cmCTestGenericHandler.h"
+
+/** \class cmCTestUploadHandler
+ * \brief Helper class for CTest
+ *
+ * Submit arbitrary files
+ *
+ */
+class cmCTestUploadHandler : public cmCTestGenericHandler
+{
+public:
+ cmTypeMacro(cmCTestUploadHandler, cmCTestGenericHandler);
+
+ cmCTestUploadHandler();
+ ~cmCTestUploadHandler() {}
+
+ /*
+ * The main entry point for this class
+ */
+ int ProcessHandler();
+
+ void Initialize();
+
+ /** Specify a set of files to submit. */
+ void SetFiles(cmCTest::SetOfStrings const& files);
+
+private:
+ cmCTest::SetOfStrings Files;
+};
+
+#endif
diff --git a/Source/CTest/cmCTestVC.cxx b/Source/CTest/cmCTestVC.cxx
new file mode 100644
index 000000000..fbee2272e
--- /dev/null
+++ b/Source/CTest/cmCTestVC.cxx
@@ -0,0 +1,241 @@
+/*============================================================================
+ 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 "cmCTestVC.h"
+
+#include "cmCTest.h"
+#include "cmSystemTools.h"
+#include "cmXMLSafe.h"
+
+#include <cmsys/Process.h>
+
+//----------------------------------------------------------------------------
+cmCTestVC::cmCTestVC(cmCTest* ct, std::ostream& log): CTest(ct), Log(log)
+{
+ this->PathCount[PathUpdated] = 0;
+ this->PathCount[PathModified] = 0;
+ this->PathCount[PathConflicting] = 0;
+ this->Unknown.Date = "Unknown";
+ this->Unknown.Author = "Unknown";
+ this->Unknown.Rev = "Unknown";
+}
+
+//----------------------------------------------------------------------------
+cmCTestVC::~cmCTestVC()
+{
+}
+
+//----------------------------------------------------------------------------
+void cmCTestVC::SetCommandLineTool(std::string const& tool)
+{
+ this->CommandLineTool = tool;
+}
+
+//----------------------------------------------------------------------------
+void cmCTestVC::SetSourceDirectory(std::string const& dir)
+{
+ this->SourceDirectory = dir;
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestVC::InitialCheckout(const char* command)
+{
+ cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ " First perform the initial checkout: " << command << "\n");
+
+ // Make the parent directory in which to perform the checkout.
+ std::string parent = cmSystemTools::GetFilenamePath(this->SourceDirectory);
+ cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ " Perform checkout in directory: " << parent << "\n");
+ if(!cmSystemTools::MakeDirectory(parent.c_str()))
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Cannot create directory: " << parent << std::endl);
+ return false;
+ }
+
+ // Construct the initial checkout command line.
+ std::vector<cmStdString> args = cmSystemTools::ParseArguments(command);
+ std::vector<char const*> vc_co;
+ for(std::vector<cmStdString>::const_iterator ai = args.begin();
+ ai != args.end(); ++ai)
+ {
+ vc_co.push_back(ai->c_str());
+ }
+ vc_co.push_back(0);
+
+ // Run the initial checkout command and log its output.
+ this->Log << "--- Begin Initial Checkout ---\n";
+ OutputLogger out(this->Log, "co-out> ");
+ OutputLogger err(this->Log, "co-err> ");
+ bool result = this->RunChild(&vc_co[0], &out, &err, parent.c_str());
+ this->Log << "--- End Initial Checkout ---\n";
+ if(!result)
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Initial checkout failed!" << std::endl);
+ }
+ return result;
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestVC::RunChild(char const* const* cmd, OutputParser* out,
+ OutputParser* err, const char* workDir)
+{
+ this->Log << this->ComputeCommandLine(cmd) << "\n";
+
+ cmsysProcess* cp = cmsysProcess_New();
+ cmsysProcess_SetCommand(cp, cmd);
+ workDir = workDir? workDir : this->SourceDirectory.c_str();
+ cmsysProcess_SetWorkingDirectory(cp, workDir);
+ this->RunProcess(cp, out, err);
+ int result = cmsysProcess_GetExitValue(cp);
+ cmsysProcess_Delete(cp);
+ return result == 0;
+}
+
+//----------------------------------------------------------------------------
+std::string cmCTestVC::ComputeCommandLine(char const* const* cmd)
+{
+ cmOStringStream line;
+ const char* sep = "";
+ for(const char* const* arg = cmd; *arg; ++arg)
+ {
+ line << sep << "\"" << *arg << "\"";
+ sep = " ";
+ }
+ return line.str();
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestVC::RunUpdateCommand(char const* const* cmd,
+ OutputParser* out, OutputParser* err)
+{
+ // Report the command line.
+ this->UpdateCommandLine = this->ComputeCommandLine(cmd);
+ if(this->CTest->GetShowOnly())
+ {
+ this->Log << this->UpdateCommandLine << "\n";
+ return true;
+ }
+
+ // Run the command.
+ return this->RunChild(cmd, out, err);
+}
+
+//----------------------------------------------------------------------------
+std::string cmCTestVC::GetNightlyTime()
+{
+ // Get the nightly start time corresponding to the current dau.
+ struct tm* t = this->CTest->GetNightlyTime(
+ this->CTest->GetCTestConfiguration("NightlyStartTime"),
+ this->CTest->GetTomorrowTag());
+ char current_time[1024];
+ sprintf(current_time, "%04d-%02d-%02d %02d:%02d:%02d",
+ t->tm_year + 1900,
+ t->tm_mon + 1,
+ t->tm_mday,
+ t->tm_hour,
+ t->tm_min,
+ t->tm_sec);
+ return std::string(current_time);
+}
+
+//----------------------------------------------------------------------------
+void cmCTestVC::Cleanup()
+{
+ this->Log << "--- Begin Cleanup ---\n";
+ this->CleanupImpl();
+ this->Log << "--- End Cleanup ---\n";
+}
+
+//----------------------------------------------------------------------------
+void cmCTestVC::CleanupImpl()
+{
+ // We do no cleanup by default.
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestVC::Update()
+{
+ this->NoteOldRevision();
+ this->Log << "--- Begin Update ---\n";
+ bool result = this->UpdateImpl();
+ this->Log << "--- End Update ---\n";
+ this->NoteNewRevision();
+ return result;
+}
+
+//----------------------------------------------------------------------------
+void cmCTestVC::NoteOldRevision()
+{
+ // We do nothing by default.
+}
+
+//----------------------------------------------------------------------------
+void cmCTestVC::NoteNewRevision()
+{
+ // We do nothing by default.
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestVC::UpdateImpl()
+{
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "* Unknown VCS tool, not updating!" << std::endl);
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestVC::WriteXML(std::ostream& xml)
+{
+ this->Log << "--- Begin Revisions ---\n";
+ bool result = this->WriteXMLUpdates(xml);
+ this->Log << "--- End Revisions ---\n";
+ return result;
+}
+
+//----------------------------------------------------------------------------
+bool cmCTestVC::WriteXMLUpdates(std::ostream&)
+{
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "* CTest cannot extract updates for this VCS tool.\n");
+ return true;
+}
+
+//----------------------------------------------------------------------------
+void cmCTestVC::WriteXMLEntry(std::ostream& xml,
+ std::string const& path,
+ std::string const& name,
+ std::string const& full,
+ File const& f)
+{
+ 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";
+ ++this->PathCount[f.Status];
+}
diff --git a/Source/CTest/cmCTestVC.h b/Source/CTest/cmCTestVC.h
new file mode 100644
index 000000000..44e1dacbb
--- /dev/null
+++ b/Source/CTest/cmCTestVC.h
@@ -0,0 +1,133 @@
+/*============================================================================
+ 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 cmCTestVC_h
+#define cmCTestVC_h
+
+#include "cmProcessTools.h"
+
+class cmCTest;
+
+/** \class cmCTestVC
+ * \brief Base class for version control system handlers
+ *
+ */
+class cmCTestVC: public cmProcessTools
+{
+public:
+ /** Construct with a CTest instance and update log stream. */
+ cmCTestVC(cmCTest* ctest, std::ostream& log);
+
+ virtual ~cmCTestVC();
+
+ /** Command line tool to invoke. */
+ void SetCommandLineTool(std::string const& tool);
+
+ /** Top-level source directory. */
+ void SetSourceDirectory(std::string const& dir);
+
+ /** Get the date/time specification for the current nightly start time. */
+ std::string GetNightlyTime();
+
+ /** Prepare the work tree. */
+ bool InitialCheckout(const char* command);
+
+ /** Perform cleanup operations on the work tree. */
+ void Cleanup();
+
+ /** Update the working tree to the new revision. */
+ bool Update();
+
+ /** Get the command line used by the Update method. */
+ std::string const& GetUpdateCommandLine() const
+ { return this->UpdateCommandLine; }
+
+ /** Write Update.xml entries for the updates found. */
+ bool WriteXML(std::ostream& xml);
+
+ /** Enumerate non-trivial working tree states during update. */
+ enum PathStatus { PathUpdated, PathModified, PathConflicting };
+
+ /** Get the number of working tree paths in each state after update. */
+ int GetPathCount(PathStatus s) const { return this->PathCount[s]; }
+
+protected:
+ // Internal API to be implemented by subclasses.
+ virtual void CleanupImpl();
+ virtual void NoteOldRevision();
+ virtual bool UpdateImpl();
+ virtual void NoteNewRevision();
+ virtual bool WriteXMLUpdates(std::ostream& xml);
+
+ /** Basic information about one revision of a tree or file. */
+ struct Revision
+ {
+ std::string Rev;
+ std::string Date;
+ std::string Author;
+ std::string EMail;
+ std::string Committer;
+ std::string CommitterEMail;
+ std::string CommitDate;
+ std::string Log;
+ };
+
+ struct File;
+ friend struct File;
+
+ /** Represent change to one file. */
+ struct File
+ {
+ PathStatus Status;
+ Revision const* Rev;
+ Revision const* PriorRev;
+ File(): Status(PathUpdated), Rev(0), PriorRev(0) {}
+ File(PathStatus status, Revision const* rev, Revision const* priorRev):
+ Status(status), Rev(rev), PriorRev(priorRev) {}
+ };
+
+ /** Convert a list of arguments to a human-readable command line. */
+ static std::string ComputeCommandLine(char const* const* cmd);
+
+ /** Run a command line and send output to given parsers. */
+ bool RunChild(char const* const* cmd, OutputParser* out,
+ OutputParser* err, const char* workDir = 0);
+
+ /** Run VC update command line and send output to given parsers. */
+ bool RunUpdateCommand(char const* const* cmd,
+ OutputParser* out, OutputParser* err = 0);
+
+ /** Write xml element for one file. */
+ void WriteXMLEntry(std::ostream& xml, std::string const& path,
+ std::string const& name, std::string const& full,
+ File const& f);
+
+ // Instance of cmCTest running the script.
+ cmCTest* CTest;
+
+ // A stream to which we write log information.
+ std::ostream& Log;
+
+ // Basic information about the working tree.
+ std::string CommandLineTool;
+ std::string SourceDirectory;
+
+ // Record update command info.
+ std::string UpdateCommandLine;
+
+ // Placeholder for unknown revisions.
+ Revision Unknown;
+
+ // Count paths reported with each PathStatus value.
+ int PathCount[3];
+};
+
+#endif
diff --git a/Source/CTest/cmParseCacheCoverage.cxx b/Source/CTest/cmParseCacheCoverage.cxx
new file mode 100644
index 000000000..137f344df
--- /dev/null
+++ b/Source/CTest/cmParseCacheCoverage.cxx
@@ -0,0 +1,220 @@
+#include "cmStandardIncludes.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "cmSystemTools.h"
+#include "cmParseCacheCoverage.h"
+#include <cmsys/Directory.hxx>
+#include <cmsys/Glob.hxx>
+
+
+cmParseCacheCoverage::cmParseCacheCoverage(
+ cmCTestCoverageHandlerContainer& cont,
+ cmCTest* ctest)
+ :cmParseMumpsCoverage(cont, ctest)
+{
+}
+
+
+bool cmParseCacheCoverage::LoadCoverageData(const char* d)
+{
+ // load all the .mcov files in the specified directory
+ cmsys::Directory dir;
+ if(!dir.Load(d))
+ {
+ return false;
+ }
+ size_t numf;
+ unsigned int i;
+ numf = dir.GetNumberOfFiles();
+ for (i = 0; i < numf; i++)
+ {
+ std::string file = dir.GetFile(i);
+ if(file != "." && file != ".."
+ && !cmSystemTools::FileIsDirectory(file.c_str()))
+ {
+ std::string path = d;
+ path += "/";
+ path += file;
+ if(cmSystemTools::GetFilenameLastExtension(path) == ".cmcov")
+ {
+ if(!this->ReadCMCovFile(path.c_str()))
+ {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+}
+
+// not currently used, but leave it in case we want it in the future
+void cmParseCacheCoverage::RemoveUnCoveredFiles()
+{
+ // loop over the coverage data computed and remove all files
+ // that only have -1 or 0 for the lines.
+ cmCTestCoverageHandlerContainer::TotalCoverageMap::iterator ci =
+ this->Coverage.TotalCoverage.begin();
+ while(ci != this->Coverage.TotalCoverage.end())
+ {
+ cmCTestCoverageHandlerContainer::SingleFileCoverageVector& v =
+ ci->second;
+ bool nothing = true;
+ for(cmCTestCoverageHandlerContainer::SingleFileCoverageVector::iterator i=
+ v.begin(); i != v.end(); ++i)
+ {
+ if(*i > 0)
+ {
+ nothing = false;
+ break;
+ }
+ }
+ if(nothing)
+ {
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ "No coverage found in: " << ci->first
+ << std::endl);
+ this->Coverage.TotalCoverage.erase(ci++);
+ }
+ else
+ {
+ ++ci;
+ }
+ }
+}
+
+bool cmParseCacheCoverage::SplitString(std::vector<std::string>& args,
+ std::string const& line)
+{
+ std::string::size_type pos1 = 0;
+ std::string::size_type pos2 = line.find(',', 0);
+ if(pos2 == std::string::npos)
+ {
+ return false;
+ }
+ std::string arg;
+ while(pos2 != std::string::npos)
+ {
+ arg = line.substr(pos1, pos2-pos1);
+ args.push_back(arg);
+ pos1 = pos2+1;
+ pos2 = line.find(',',pos1);
+ }
+ arg = line.substr(pos1);
+ args.push_back(arg);
+ return true;
+}
+
+bool cmParseCacheCoverage::ReadCMCovFile(const char* file)
+{
+ std::ifstream in(file);
+ if(!in)
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Can not open : "
+ << file << "\n");
+ return false;
+ }
+ std::string line;
+ std::vector<std::string> separateLine;
+ if(!cmSystemTools::GetLineFromStream(in, line))
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Empty file : "
+ << file << " referenced in this line of cmcov data:\n"
+ "[" << line << "]\n");
+ return false;
+ }
+ separateLine.clear();
+ this->SplitString(separateLine, line);
+ if(separateLine.size() !=4 || separateLine[0] != "Routine"
+ || separateLine[1] != "Line" || separateLine[2] != "RtnLine"
+ || separateLine[3] != "Code")
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Bad first line of cmcov file : "
+ << file << " line:\n"
+ "[" << line << "]\n");
+ }
+ std::string routine;
+ std::string filepath;
+ while(cmSystemTools::GetLineFromStream(in, line))
+ {
+ // clear out line argument vector
+ separateLine.clear();
+ // parse the comma separated line
+ this->SplitString(separateLine, line);
+ // might have more because code could have a quoted , in it
+ // but we only care about the first 3 args anyway
+ if(separateLine.size() < 4)
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Bad line of cmcov file expected at least 4 found: "
+ << separateLine.size() << " "
+ << file << " line:\n"
+ "[" << line << "]\n");
+ for(std::string::size_type i = 0; i < separateLine.size(); ++i)
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,""
+ << separateLine[1] << " ");
+ }
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "\n");
+ return false;
+ }
+ // if we do not have a routine yet, then it should be
+ // the first argument in the vector
+ if(routine.size() == 0)
+ {
+ routine = separateLine[0];
+ // Find the full path to the file
+ if(!this->FindMumpsFile(routine, filepath))
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Could not find mumps file for routine: "
+ << routine << "\n");
+ filepath = "";
+ continue; // move to next line
+ }
+ }
+ // if we have a routine name, check for end of routine
+ else
+ {
+ // Totals in arg 0 marks the end of a routine
+ if(separateLine[0].substr(0, 6) == "Totals")
+ {
+ routine = ""; // at the end of this routine
+ filepath = "";
+ continue; // move to next line
+ }
+ }
+ // if the file path was not found for the routine
+ // 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)
+ {
+ continue;
+ }
+ // now we are ready to set the coverage from the line of data
+ cmCTestCoverageHandlerContainer::SingleFileCoverageVector&
+ coverageVector = this->Coverage.TotalCoverage[filepath];
+ std::string::size_type linenumber = atoi(separateLine[1].c_str()) -1;
+ int count = atoi(separateLine[2].c_str());
+ if(linenumber > coverageVector.size())
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Parse error line is greater than number of lines in file: "
+ << linenumber << " " << filepath << "\n");
+ continue; // skip setting count to avoid crash
+ }
+ // now add to count for linenumber
+ // for some reason the cache coverage adds extra lines to the
+ // end of the file in some cases. Since they do not exist, we will
+ // mark them as non executable
+ while(linenumber >= coverageVector.size())
+ {
+ coverageVector.push_back(-1);
+ }
+ coverageVector[linenumber] += count;
+ }
+ return true;
+}
diff --git a/Source/CTest/cmParseCacheCoverage.h b/Source/CTest/cmParseCacheCoverage.h
new file mode 100644
index 000000000..114eb92d3
--- /dev/null
+++ b/Source/CTest/cmParseCacheCoverage.h
@@ -0,0 +1,42 @@
+/*============================================================================
+ 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 cmParseCacheCoverage_h
+#define cmParseCacheCoverage_h
+
+#include "cmParseMumpsCoverage.h"
+
+/** \class cmParseCacheCoverage
+ * \brief Parse Cache coverage information
+ *
+ * This class is used to parse Cache coverage information for
+ * mumps.
+ */
+class cmParseCacheCoverage : public cmParseMumpsCoverage
+{
+public:
+ cmParseCacheCoverage(cmCTestCoverageHandlerContainer& cont,
+ cmCTest* ctest);
+protected:
+ // implement virtual from parent
+ bool LoadCoverageData(const char* dir);
+ // remove files with no coverage
+ void RemoveUnCoveredFiles();
+ // Read a single mcov file
+ bool ReadCMCovFile(const char* f);
+ // split a string based on ,
+ bool SplitString(std::vector<std::string>& args,
+ std::string const& line);
+};
+
+
+#endif
diff --git a/Source/CTest/cmParseGTMCoverage.cxx b/Source/CTest/cmParseGTMCoverage.cxx
new file mode 100644
index 000000000..5dfcfe50a
--- /dev/null
+++ b/Source/CTest/cmParseGTMCoverage.cxx
@@ -0,0 +1,272 @@
+#include "cmStandardIncludes.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "cmSystemTools.h"
+#include "cmParseGTMCoverage.h"
+#include <cmsys/Directory.hxx>
+#include <cmsys/Glob.hxx>
+
+
+cmParseGTMCoverage::cmParseGTMCoverage(cmCTestCoverageHandlerContainer& cont,
+ cmCTest* ctest)
+ :cmParseMumpsCoverage(cont, ctest)
+{
+}
+
+
+bool cmParseGTMCoverage::LoadCoverageData(const char* d)
+{
+ // load all the .mcov files in the specified directory
+ cmsys::Directory dir;
+ if(!dir.Load(d))
+ {
+ return false;
+ }
+ size_t numf;
+ unsigned int i;
+ numf = dir.GetNumberOfFiles();
+ for (i = 0; i < numf; i++)
+ {
+ std::string file = dir.GetFile(i);
+ if(file != "." && file != ".."
+ && !cmSystemTools::FileIsDirectory(file.c_str()))
+ {
+ std::string path = d;
+ path += "/";
+ path += file;
+ if(cmSystemTools::GetFilenameLastExtension(path) == ".mcov")
+ {
+ if(!this->ReadMCovFile(path.c_str()))
+ {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+}
+
+bool cmParseGTMCoverage::ReadMCovFile(const char* file)
+{
+ std::ifstream in(file);
+ if(!in)
+ {
+ return false;
+ }
+ std::string line;
+ std::string lastfunction;
+ std::string lastroutine;
+ std::string lastpath;
+ int lastoffset = 0;
+ while( cmSystemTools::GetLineFromStream(in, line))
+ {
+ // only look at lines that have coverage data
+ if(line.find("^ZZCOVERAGE") == line.npos)
+ {
+ continue;
+ }
+ std::string filepath;
+ std::string function;
+ std::string routine;
+ int linenumber = 0;
+ int count = 0;
+ this->ParseMCOVLine(line, routine, function, linenumber, count);
+ // skip this one
+ if(routine == "RSEL")
+ {
+ continue;
+ }
+ // no need to search the file if we just did it
+ if(function == lastfunction && lastroutine == routine)
+ {
+ if(lastpath.size())
+ {
+ this->Coverage.TotalCoverage[lastpath][lastoffset + linenumber]
+ += count;
+ }
+ else
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Can not find mumps file : "
+ << lastroutine <<
+ " referenced in this line of mcov data:\n"
+ "[" << line << "]\n");
+ }
+ continue;
+ }
+ // Find the full path to the file
+ bool found = this->FindMumpsFile(routine, filepath);
+ if(found)
+ {
+ int lineoffset;
+ if(this->FindFunctionInMumpsFile(filepath,
+ function,
+ lineoffset))
+ {
+ cmCTestCoverageHandlerContainer::SingleFileCoverageVector&
+ coverageVector = this->Coverage.TotalCoverage[filepath];
+ coverageVector[lineoffset + linenumber] += count;
+ }
+ lastoffset = lineoffset;
+ }
+ else
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Can not find mumps file : "
+ << routine << " referenced in this line of mcov data:\n"
+ "[" << line << "]\n");
+ }
+ lastfunction = function;
+ lastroutine = routine;
+ lastpath = filepath;
+ }
+ return true;
+}
+
+bool cmParseGTMCoverage::FindFunctionInMumpsFile(std::string const& filepath,
+ std::string const& function,
+ int& lineoffset)
+{
+ std::ifstream in(filepath.c_str());
+ if(!in)
+ {
+ return false;
+ }
+ std::string line;
+ int linenum = 0;
+ while( cmSystemTools::GetLineFromStream(in, line))
+ {
+ std::string::size_type pos = line.find(function.c_str());
+ if(pos == 0)
+ {
+ char nextchar = line[function.size()];
+ if(nextchar == ' ' || nextchar == '(')
+ {
+ lineoffset = linenum;
+ return true;
+ }
+ }
+ if(pos == 1)
+ {
+ char prevchar = line[0];
+ char nextchar = line[function.size()+1];
+ if(prevchar == '%' && (nextchar == ' ' || nextchar == '('))
+ {
+ lineoffset = linenum;
+ return true;
+ }
+ }
+ linenum++; // move to next line count
+ }
+ lineoffset = 0;
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Could not find entry point : "
+ << function << " in " << filepath << "\n");
+ return false;
+}
+
+bool cmParseGTMCoverage::ParseMCOVLine(std::string const& line,
+ std::string& routine,
+ std::string& function,
+ int& linenumber,
+ int& count)
+{
+ // this method parses lines from the .mcov file
+ // each line has ^COVERAGE(...) in it, and there
+ // are several varients of coverage lines:
+ //
+ // ^COVERAGE("DIC11","PR1",0)="2:0:0:0"
+ // ( file , entry, line ) = "number_executed:timing_info"
+ // ^COVERAGE("%RSEL","SRC")="1:0:0:0"
+ // ( 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::string::size_type pos = line.find('(', 0);
+ // if no ( is found, then return line has no coverage
+ if(pos == std::string::npos)
+ {
+ return false;
+ }
+ std::string arg;
+ bool done = false;
+ // separate out all of the comma separated arguments found
+ // in the COVERAGE(...) line
+ while(line[pos] && !done)
+ {
+ // save the char we are looking at
+ char cur = line[pos];
+ // , or ) means end of argument
+ if(cur == ',' || cur == ')')
+ {
+ // save the argument into the argument vector
+ args.push_back(arg);
+ // start on a new argument
+ arg = "";
+ // if we are at the end of the ), then finish while loop
+ if(cur == ')')
+ {
+ done = true;
+ }
+ }
+ else
+ {
+ // all chars except ", (, and % get stored in the arg string
+ if(cur != '\"' && cur != '(' && cur != '%')
+ {
+ arg.append(1, line[pos]);
+ }
+ }
+ // move to next char
+ pos++;
+ }
+ // now parse the right hand side of the =
+ pos = line.find('=');
+ // no = found, this is an error
+ if(pos == line.npos)
+ {
+ return false;
+ }
+ pos++; // move past =
+
+ // if the next positing is not a ", then this is a
+ // COVERAGE(..)=count line and turn the rest of the string
+ // past the = into an integer and set it to count
+ if(line[pos] != '\"')
+ {
+ count = atoi(line.substr(pos).c_str());
+ }
+ else
+ {
+ // this means line[pos] is a ", and we have a
+ // COVERAGE(...)="1:0:0:0" type of line
+ pos++; // move past "
+ // find the first : past the "
+ std::string::size_type pos2 = line.find(':', pos);
+ // turn the string between the " and the first : into an integer
+ // and set it to count
+ count = atoi(line.substr(pos, pos2-pos).c_str());
+ }
+ // less then two arguments is an error
+ if(args.size() < 2)
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Error parsing mcov line: [" << line << "]\n");
+ return false;
+ }
+ routine = args[0]; // the routine is the first argument
+ function = args[1]; // the function in the routine is the second
+ // in the two argument only format
+ // ^COVERAGE("%RSEL","SRC"), the line offset is 0
+ if(args.size() == 2)
+ {
+ linenumber = 0;
+ }
+ else
+ {
+ // this is the format for this line
+ // ^COVERAGE("%RSEL","SRC",count)
+ linenumber = atoi(args[2].c_str());
+ }
+ return true;
+}
diff --git a/Source/CTest/cmParseGTMCoverage.h b/Source/CTest/cmParseGTMCoverage.h
new file mode 100644
index 000000000..c6d7ef919
--- /dev/null
+++ b/Source/CTest/cmParseGTMCoverage.h
@@ -0,0 +1,49 @@
+/*============================================================================
+ 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 cmParseGTMCoverage_h
+#define cmParseGTMCoverage_h
+
+#include "cmParseMumpsCoverage.h"
+
+/** \class cmParseGTMCoverage
+ * \brief Parse GTM coverage information
+ *
+ * This class is used to parse GTM coverage information for
+ * mumps.
+ */
+class cmParseGTMCoverage : public cmParseMumpsCoverage
+{
+public:
+ cmParseGTMCoverage(cmCTestCoverageHandlerContainer& cont,
+ cmCTest* ctest);
+protected:
+ // implement virtual from parent
+ bool LoadCoverageData(const char* dir);
+ // Read a single mcov file
+ bool ReadMCovFile(const char* f);
+ // find out what line in a mumps file (filepath) the given entry point
+ // or function is. lineoffset is set by this method.
+ bool FindFunctionInMumpsFile(std::string const& filepath,
+ std::string const& function,
+ int& lineoffset);
+ // parse a line from a .mcov file, and fill in the
+ // routine, function, linenumber and coverage count
+ bool ParseMCOVLine(std::string const& line,
+ std::string& routine,
+ std::string& function,
+ int& linenumber,
+ int& count);
+};
+
+
+#endif
diff --git a/Source/CTest/cmParseMumpsCoverage.cxx b/Source/CTest/cmParseMumpsCoverage.cxx
new file mode 100644
index 000000000..37e8bd082
--- /dev/null
+++ b/Source/CTest/cmParseMumpsCoverage.cxx
@@ -0,0 +1,165 @@
+#include "cmStandardIncludes.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "cmSystemTools.h"
+#include "cmParseGTMCoverage.h"
+#include <cmsys/Directory.hxx>
+#include <cmsys/Glob.hxx>
+
+
+cmParseMumpsCoverage::cmParseMumpsCoverage(
+ cmCTestCoverageHandlerContainer& cont,
+ cmCTest* ctest)
+ :Coverage(cont), CTest(ctest)
+{
+}
+
+cmParseMumpsCoverage::~cmParseMumpsCoverage()
+{
+}
+
+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);
+ if(!in)
+ {
+ return false;
+ }
+ std::string line;
+ while(cmSystemTools::GetLineFromStream(in, line))
+ {
+ std::string::size_type pos = line.find(':', 0);
+ std::string packages;
+ if(pos != std::string::npos)
+ {
+ std::string type = line.substr(0, pos);
+ std::string path = line.substr(pos+1);
+ if(type == "packages")
+ {
+ this->LoadPackages(path.c_str());
+ }
+ else if(type == "coverage_dir")
+ {
+ this->LoadCoverageData(path.c_str());
+ }
+ else
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Parse Error in Mumps coverage file :\n"
+ << file <<
+ "\ntype: [" << type << "]\npath:[" << path << "]\n"
+ "input line: [" << line << "]\n");
+ }
+ }
+ }
+ return true;
+}
+
+void cmParseMumpsCoverage::InitializeMumpsFile(std::string& file)
+{
+ // initialize the coverage information for a given mumps file
+ std::ifstream in(file.c_str());
+ if(!in)
+ {
+ return;
+ }
+ std::string line;
+ cmCTestCoverageHandlerContainer::SingleFileCoverageVector&
+ coverageVector = this->Coverage.TotalCoverage[file];
+ if(!cmSystemTools::GetLineFromStream(in, line))
+ {
+ return;
+ }
+ // first line of a .m file can never be run
+ coverageVector.push_back(-1);
+ while( cmSystemTools::GetLineFromStream(in, line) )
+ {
+ // putting in a 0 for a line means it is executable code
+ // putting in a -1 for a line means it is not executable code
+ int val = -1; // assume line is not executable
+ bool found = false;
+ std::string::size_type i = 0;
+ // (1) Search for the first whitespace or semicolon character on a line.
+ //This will skip over labels if the line starts with one, or will simply
+ //be the first character on the line for non-label lines.
+ for(; i < line.size(); ++i)
+ {
+ if(line[i] == ' ' || line[i] == '\t' || line[i] == ';')
+ {
+ found = true;
+ break;
+ }
+ }
+ if(found)
+ {
+ // (2) If the first character found above is whitespace 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'))
+ {
+ i++;
+ }
+ }
+ // (3) If the character found is not a semicolon then the line counts for
+ // coverage.
+ if(i < line.size() && line[i] != ';')
+ {
+ val = 0;
+ }
+ }
+ coverageVector.push_back(val);
+ }
+}
+
+bool cmParseMumpsCoverage::LoadPackages(const char* d)
+{
+ cmsys::Glob glob;
+ glob.RecurseOn();
+ std::string pat = d;
+ pat += "/*.m";
+ glob.FindFiles(pat.c_str());
+ std::vector<std::string>& files = glob.GetFiles();
+ std::vector<std::string>::iterator fileIt;
+ for ( fileIt = files.begin(); fileIt != files.end();
+ ++ fileIt )
+ {
+ std::string name = cmSystemTools::GetFilenameName(*fileIt);
+ this->RoutineToDirectory[name.substr(0, name.size()-2)] = *fileIt;
+ // initialze each file, this is left out until CDash is fixed
+ // to handle large numbers of files
+ this->InitializeMumpsFile(*fileIt);
+ }
+ return true;
+}
+
+bool cmParseMumpsCoverage::FindMumpsFile(std::string const& routine,
+ std::string& filepath)
+{
+ std::map<cmStdString, cmStdString>::iterator i =
+ this->RoutineToDirectory.find(routine);
+ if(i != this->RoutineToDirectory.end())
+ {
+ filepath = i->second;
+ return true;
+ }
+ else
+ {
+ // try some alternate names
+ const char* tryname[] = {"GUX", "GTM", "ONT", 0};
+ for(int k=0; tryname[k] != 0; k++)
+ {
+ std::string routine2 = routine + tryname[k];
+ i = this->RoutineToDirectory.find(routine2);
+ if(i != this->RoutineToDirectory.end())
+ {
+ filepath = i->second;
+ return true;
+ }
+ }
+ }
+ return false;
+}
diff --git a/Source/CTest/cmParseMumpsCoverage.h b/Source/CTest/cmParseMumpsCoverage.h
new file mode 100644
index 000000000..c1effa79b
--- /dev/null
+++ b/Source/CTest/cmParseMumpsCoverage.h
@@ -0,0 +1,52 @@
+/*============================================================================
+ 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 cmParseMumpsCoverage_h
+#define cmParseMumpsCoverage_h
+
+#include "cmStandardIncludes.h"
+#include "cmCTestCoverageHandler.h"
+
+/** \class cmParseMumpsCoverage
+ * \brief Parse Mumps coverage information
+ *
+ * This class is used as the base class for Mumps coverage
+ * parsing.
+ */
+class cmParseMumpsCoverage
+{
+public:
+ cmParseMumpsCoverage(cmCTestCoverageHandlerContainer& cont,
+ cmCTest* ctest);
+ virtual ~cmParseMumpsCoverage();
+ // This is the toplevel coverage file locating the coverage files
+ // and the mumps source code package tree.
+ bool ReadCoverageFile(const char* file);
+protected:
+ // sub classes will use this to
+ // load all coverage files found in the given directory
+ virtual bool LoadCoverageData(const char* d) = 0;
+ // search the package directory for mumps files and fill
+ // in the RoutineToDirectory map
+ bool LoadPackages(const char* dir);
+ // initialize the coverage information for a single mumps file
+ void InitializeMumpsFile(std::string& file);
+ // Find mumps file for routine
+ bool FindMumpsFile(std::string const& routine,
+ std::string& filepath);
+protected:
+ std::map<cmStdString, cmStdString> RoutineToDirectory;
+ cmCTestCoverageHandlerContainer& Coverage;
+ cmCTest* CTest;
+};
+
+#endif
diff --git a/Source/CTest/cmParsePHPCoverage.cxx b/Source/CTest/cmParsePHPCoverage.cxx
new file mode 100644
index 000000000..593b2d1a8
--- /dev/null
+++ b/Source/CTest/cmParsePHPCoverage.cxx
@@ -0,0 +1,253 @@
+#include "cmStandardIncludes.h"
+#include "cmSystemTools.h"
+#include "cmParsePHPCoverage.h"
+#include <cmsys/Directory.hxx>
+
+/*
+ To setup coverage for php.
+
+ - edit php.ini to add auto prepend and append php files from phpunit
+ auto_prepend_file =
+ auto_append_file =
+ - run the tests
+ - run this program on all the files in c:/tmp
+
+*/
+
+cmParsePHPCoverage::cmParsePHPCoverage(cmCTestCoverageHandlerContainer& cont,
+ cmCTest* ctest)
+ :Coverage(cont), CTest(ctest)
+{
+}
+
+bool cmParsePHPCoverage::ReadUntil(std::ifstream& in, char until)
+{
+ char c = 0;
+ while(in.get(c) && c != until)
+ {
+ }
+ if(c != until)
+ {
+ return false;
+ }
+ return true;
+}
+bool cmParsePHPCoverage::ReadCoverageArray(std::ifstream& in,
+ cmStdString const& fileName)
+{
+ cmCTestCoverageHandlerContainer::SingleFileCoverageVector& coverageVector
+ = this->Coverage.TotalCoverage[fileName];
+
+ char c;
+ char buf[4];
+ in.read(buf, 3);
+ buf[3] = 0;
+ if(strcmp(buf, ";a:") != 0)
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "failed to read start of coverage array, found : "
+ << buf << "\n");
+ return false;
+ }
+ int size = 0;
+ if(!this->ReadInt(in, size))
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "failed to read size ");
+ return false;
+ }
+ if(!in.get(c) && c == '{')
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "failed to read open {\n");
+ return false;
+ }
+ for(int i =0; i < size; i++)
+ {
+ this->ReadUntil(in, ':');
+ int line = 0;
+ this->ReadInt(in, line);
+ // ok xdebug may have a bug here
+ // it seems to be 1 based but often times
+ // seems to have a 0'th line.
+ line--;
+ if(line < 0)
+ {
+ line = 0;
+ }
+ this->ReadUntil(in, ':');
+ int value = 0;
+ this->ReadInt(in, value);
+ // make sure the vector is the right size and is
+ // initialized with -1 for each line
+ while(coverageVector.size() <= static_cast<size_t>(line) )
+ {
+ coverageVector.push_back(-1);
+ }
+ // if value is less than 0, set it to zero
+ // TODO figure out the difference between
+ // -1 and -2 in xdebug coverage?? For now
+ // assume less than 0 is just not covered
+ // CDash expects -1 for non executable code (like comments)
+ // and 0 for uncovered code, and a positive value
+ // for number of times a line was executed
+ if(value < 0)
+ {
+ value = 0;
+ }
+ // if unset then set it to value
+ if(coverageVector[line] == -1)
+ {
+ coverageVector[line] = value;
+ }
+ // otherwise increment by value
+ else
+ {
+ coverageVector[line] += value;
+ }
+ }
+ return true;
+}
+
+bool cmParsePHPCoverage::ReadInt(std::ifstream& in, int& v)
+{
+ std::string s;
+ char c = 0;
+ while(in.get(c) && c != ':' && c != ';')
+ {
+ s += c;
+ }
+ v = atoi(s.c_str());
+ return true;
+}
+
+bool cmParsePHPCoverage::ReadArraySize(std::ifstream& in, int& size)
+{
+ char c = 0;
+ in.get(c);
+ if(c != 'a')
+ {
+ return false;
+ }
+ if(in.get(c) && c == ':')
+ {
+ if(this->ReadInt(in, size))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool cmParsePHPCoverage::ReadFileInformation(std::ifstream& in)
+{
+ char buf[4];
+ in.read(buf, 2);
+ buf[2] = 0;
+ if(strcmp(buf, "s:") != 0)
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "failed to read start of file info found: [" << buf << "]\n");
+ return false;
+ }
+ char c;
+ int size = 0;
+ if(this->ReadInt(in, size))
+ {
+ size++; // add one for null termination
+ char* s = new char[size+1];
+ // read open quote
+ if(in.get(c) && c != '"')
+ {
+ delete[] s;
+ return false;
+ }
+ // read the string data
+ in.read(s, size-1);
+ s[size-1] = 0;
+ cmStdString fileName = s;
+ delete [] s;
+ // read close quote
+ if(in.get(c) && c != '"')
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "failed to read close quote\n"
+ << "read [" << c << "]\n");
+ return false;
+ }
+ if(!this->ReadCoverageArray(in, fileName) )
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "failed to read coverage array for file: "
+ << fileName << "\n");
+ return false;
+ }
+ return true;
+ }
+ return false;
+}
+
+
+bool cmParsePHPCoverage::ReadPHPData(const char* file)
+{
+ std::ifstream in(file);
+ if(!in)
+ {
+ return false;
+ }
+ int size = 0;
+ this->ReadArraySize(in, size);
+ char c = 0;
+ in.get(c);
+ if(c != '{')
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "failed to read open array\n");
+ return false;
+ }
+ for(int i =0; i < size; i++)
+ {
+ if(!this->ReadFileInformation(in))
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Failed to read file #" << i << "\n");
+ return false;
+ }
+ in.get(c);
+ if(c != '}')
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "failed to read close array\n");
+ return false;
+ }
+ }
+ return true;
+}
+
+bool cmParsePHPCoverage::ReadPHPCoverageDirectory(const char* d)
+{
+ cmsys::Directory dir;
+ if(!dir.Load(d))
+ {
+ return false;
+ }
+ size_t numf;
+ unsigned int i;
+ numf = dir.GetNumberOfFiles();
+ for (i = 0; i < numf; i++)
+ {
+ std::string file = dir.GetFile(i);
+ if(file != "." && file != ".."
+ && !cmSystemTools::FileIsDirectory(file.c_str()))
+ {
+ std::string path = d;
+ path += "/";
+ path += file;
+ if(!this->ReadPHPData(path.c_str()))
+ {
+ return false;
+ }
+ }
+ }
+ return true;
+}
diff --git a/Source/CTest/cmParsePHPCoverage.h b/Source/CTest/cmParsePHPCoverage.h
new file mode 100644
index 000000000..d50a83c58
--- /dev/null
+++ b/Source/CTest/cmParsePHPCoverage.h
@@ -0,0 +1,45 @@
+/*============================================================================
+ 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 cmParsePHPCoverage_h
+#define cmParsePHPCoverage_h
+
+#include "cmStandardIncludes.h"
+#include "cmCTestCoverageHandler.h"
+
+/** \class cmParsePHPCoverage
+ * \brief Parse xdebug PHP coverage information
+ *
+ * This class is used to parse php coverage information produced
+ * by xdebug. The data is stored as a php dump of the array
+ * return by xdebug coverage. It is an array of arrays.
+ */
+class cmParsePHPCoverage
+{
+public:
+ cmParsePHPCoverage(cmCTestCoverageHandlerContainer& cont,
+ cmCTest* ctest);
+ bool ReadPHPCoverageDirectory(const char* dir);
+ 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);
+ cmCTestCoverageHandlerContainer& Coverage;
+ cmCTest* CTest;
+};
+
+
+#endif
diff --git a/Source/CTest/cmProcess.cxx b/Source/CTest/cmProcess.cxx
new file mode 100644
index 000000000..0ee631fe9
--- /dev/null
+++ b/Source/CTest/cmProcess.cxx
@@ -0,0 +1,272 @@
+/*============================================================================
+ 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 <cmProcess.h>
+#include <cmSystemTools.h>
+
+cmProcess::cmProcess()
+{
+ this->Process = 0;
+ this->Timeout = 0;
+ this->TotalTime = 0;
+ this->ExitValue = 0;
+ this->Id = 0;
+ this->StartTime = 0;
+}
+
+cmProcess::~cmProcess()
+{
+ cmsysProcess_Delete(this->Process);
+}
+void cmProcess::SetCommand(const char* command)
+{
+ this->Command = command;
+}
+
+void cmProcess::SetCommandArguments(std::vector<std::string> const& args)
+{
+ this->Arguments = args;
+}
+
+bool cmProcess::StartProcess()
+{
+ if(this->Command.size() == 0)
+ {
+ return false;
+ }
+ this->StartTime = cmSystemTools::GetTime();
+ this->ProcessArgs.clear();
+ // put the command as arg0
+ this->ProcessArgs.push_back(this->Command.c_str());
+ // now put the command arguments in
+ for(std::vector<std::string>::iterator i = this->Arguments.begin();
+ i != this->Arguments.end(); ++i)
+ {
+ this->ProcessArgs.push_back(i->c_str());
+ }
+ this->ProcessArgs.push_back(0); // null terminate the list
+ this->Process = cmsysProcess_New();
+ cmsysProcess_SetCommand(this->Process, &*this->ProcessArgs.begin());
+ if(this->WorkingDirectory.size())
+ {
+ cmsysProcess_SetWorkingDirectory(this->Process,
+ this->WorkingDirectory.c_str());
+ }
+ cmsysProcess_SetTimeout(this->Process, this->Timeout);
+ cmsysProcess_Execute(this->Process);
+ return (cmsysProcess_GetState(this->Process)
+ == cmsysProcess_State_Executing);
+}
+
+//----------------------------------------------------------------------------
+bool cmProcess::Buffer::GetLine(std::string& line)
+{
+ // Scan for the next newline.
+ for(size_type sz = this->size(); this->Last != sz; ++this->Last)
+ {
+ if((*this)[this->Last] == '\n' || (*this)[this->Last] == '\0')
+ {
+ // Extract the range first..last as a line.
+ const char* text = &*this->begin() + this->First;
+ size_type length = this->Last - this->First;
+ while(length && text[length-1] == '\r')
+ {
+ length --;
+ }
+ line.assign(text, length);
+
+ // Start a new range for the next line.
+ ++this->Last;
+ this->First = Last;
+
+ // Return the line extracted.
+ return true;
+ }
+ }
+
+ // Available data have been exhausted without a newline.
+ if(this->First != 0)
+ {
+ // Move the partial line to the beginning of the buffer.
+ this->erase(this->begin(), this->begin() + this->First);
+ this->First = 0;
+ this->Last = this->size();
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmProcess::Buffer::GetLast(std::string& line)
+{
+ // Return the partial last line, if any.
+ if(!this->empty())
+ {
+ line.assign(&*this->begin(), this->size());
+ this->First = this->Last = 0;
+ this->clear();
+ return true;
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+int cmProcess::GetNextOutputLine(std::string& line, double timeout)
+{
+ for(;;)
+ {
+ // Look for lines already buffered.
+ if(this->StdOut.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;
+ int length;
+ int p = cmsysProcess_WaitForData(this->Process, &data, &length, &timeout);
+ if(p == cmsysProcess_Pipe_Timeout)
+ {
+ return cmsysProcess_Pipe_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);
+ }
+ else // p == cmsysProcess_Pipe_None
+ {
+ // The process will provide no more data.
+ break;
+ }
+ }
+
+ // Look for partial last lines.
+ if(this->StdOut.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))
+ {
+ return cmsysProcess_Pipe_Timeout;
+ }
+
+ // Record exit information.
+ this->ExitValue = cmsysProcess_GetExitValue(this->Process);
+ this->TotalTime = cmSystemTools::GetTime() - this->StartTime;
+ // std::cerr << "Time to run: " << this->TotalTime << "\n";
+ return cmsysProcess_Pipe_None;
+}
+
+// return the process status
+int cmProcess::GetProcessStatus()
+{
+ if(!this->Process)
+ {
+ return cmsysProcess_State_Exited;
+ }
+ return cmsysProcess_GetState(this->Process);
+}
+
+int cmProcess::ReportStatus()
+{
+ int result = 1;
+ switch(cmsysProcess_GetState(this->Process))
+ {
+ case cmsysProcess_State_Starting:
+ {
+ std::cerr << "cmProcess: Never started "
+ << this->Command << " process.\n";
+ } break;
+ case cmsysProcess_State_Error:
+ {
+ std::cerr << "cmProcess: Error executing " << this->Command
+ << " process: "
+ << cmsysProcess_GetErrorString(this->Process)
+ << "\n";
+ } break;
+ case cmsysProcess_State_Exception:
+ {
+ std::cerr << "cmProcess: " << this->Command
+ << " process exited with an exception: ";
+ switch(cmsysProcess_GetExitException(this->Process))
+ {
+ case cmsysProcess_Exception_None:
+ {
+ std::cerr << "None";
+ } break;
+ case cmsysProcess_Exception_Fault:
+ {
+ std::cerr << "Segmentation fault";
+ } break;
+ case cmsysProcess_Exception_Illegal:
+ {
+ std::cerr << "Illegal instruction";
+ } break;
+ case cmsysProcess_Exception_Interrupt:
+ {
+ std::cerr << "Interrupted by user";
+ } break;
+ case cmsysProcess_Exception_Numerical:
+ {
+ std::cerr << "Numerical exception";
+ } break;
+ case cmsysProcess_Exception_Other:
+ {
+ std::cerr << "Unknown";
+ } break;
+ }
+ std::cerr << "\n";
+ } break;
+ case cmsysProcess_State_Executing:
+ {
+ std::cerr << "cmProcess: Never terminated " <<
+ this->Command << " process.\n";
+ } break;
+ case cmsysProcess_State_Exited:
+ {
+ result = cmsysProcess_GetExitValue(this->Process);
+ std::cerr << "cmProcess: " << this->Command
+ << " process exited with code "
+ << result << "\n";
+ } break;
+ case cmsysProcess_State_Expired:
+ {
+ std::cerr << "cmProcess: killed " << this->Command
+ << " process due to timeout.\n";
+ } break;
+ case cmsysProcess_State_Killed:
+ {
+ std::cerr << "cmProcess: killed " << this->Command << " process.\n";
+ } break;
+ }
+ return result;
+
+}
+
+
+int cmProcess::GetExitException()
+{
+ return cmsysProcess_GetExitException(this->Process);
+}
diff --git a/Source/CTest/cmProcess.h b/Source/CTest/cmProcess.h
new file mode 100644
index 000000000..ff99ca23d
--- /dev/null
+++ b/Source/CTest/cmProcess.h
@@ -0,0 +1,82 @@
+/*============================================================================
+ 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 cmProcess_h
+#define cmProcess_h
+
+
+#include "cmStandardIncludes.h"
+#include <cmsys/Process.h>
+
+
+/** \class cmProcess
+ * \brief run a process with c++
+ *
+ * cmProcess wraps the kwsys process stuff in a c++ class.
+ */
+class cmProcess
+{
+public:
+ cmProcess();
+ ~cmProcess();
+ const char* GetCommand() { return this->Command.c_str();}
+ void SetCommand(const char* command);
+ void SetCommandArguments(std::vector<std::string> const& arg);
+ void SetWorkingDirectory(const char* dir) { this->WorkingDirectory = dir;}
+ void SetTimeout(double t) { this->Timeout = t;}
+ // Return true if the process starts
+ bool StartProcess();
+
+ // return the process status
+ int GetProcessStatus();
+ // Report the status of the program
+ int ReportStatus();
+ int GetId() { return this->Id; }
+ void SetId(int id) { this->Id = id;}
+ int GetExitValue() { return this->ExitValue;}
+ double GetTotalTime() { return this->TotalTime;}
+ int GetExitException();
+ /**
+ * 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_Timeout = Timeout expired while waiting
+ */
+ int GetNextOutputLine(std::string& line, double timeout);
+private:
+ double Timeout;
+ double StartTime;
+ double TotalTime;
+ cmsysProcess* Process;
+ class Buffer: public std::vector<char>
+ {
+ // Half-open index range of partial line already scanned.
+ size_type First;
+ size_type Last;
+ public:
+ Buffer(): First(0), Last(0) {}
+ bool GetLine(std::string& line);
+ bool GetLast(std::string& line);
+ };
+ Buffer StdErr;
+ Buffer StdOut;
+ std::string Command;
+ std::string WorkingDirectory;
+ std::vector<std::string> Arguments;
+ std::vector<const char*> ProcessArgs;
+ std::string Output;
+ int Id;
+ int ExitValue;
+};
+
+#endif
diff --git a/Source/CursesDialog/.NoDartCoverage b/Source/CursesDialog/.NoDartCoverage
new file mode 100644
index 000000000..3c9972938
--- /dev/null
+++ b/Source/CursesDialog/.NoDartCoverage
@@ -0,0 +1 @@
+# do not do coverage in this directory
diff --git a/Source/CursesDialog/CMakeLists.txt b/Source/CursesDialog/CMakeLists.txt
new file mode 100644
index 000000000..3349ebe96
--- /dev/null
+++ b/Source/CursesDialog/CMakeLists.txt
@@ -0,0 +1,37 @@
+#=============================================================================
+# 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.
+#=============================================================================
+
+SET( CURSES_SRCS
+ CursesDialog/cmCursesBoolWidget
+ CursesDialog/cmCursesCacheEntryComposite
+ CursesDialog/cmCursesDummyWidget
+ CursesDialog/cmCursesFilePathWidget
+ CursesDialog/cmCursesForm
+ CursesDialog/cmCursesLabelWidget
+ CursesDialog/cmCursesLongMessageForm
+ CursesDialog/cmCursesMainForm
+ CursesDialog/cmCursesPathWidget
+ CursesDialog/cmCursesStringWidget
+ CursesDialog/cmCursesWidget
+ CursesDialog/ccmake
+ )
+
+INCLUDE_DIRECTORIES(${CMake_SOURCE_DIR}/Source/CursesDialog/form
+ ${CMake_BINARY_DIR}/Source/CursesDialog/form)
+INCLUDE_DIRECTORIES(${CURSES_INCLUDE_PATH})
+
+
+ADD_EXECUTABLE(ccmake ${CURSES_SRCS} )
+TARGET_LINK_LIBRARIES(ccmake CMakeLib)
+TARGET_LINK_LIBRARIES(ccmake cmForm)
+
+INSTALL_TARGETS(/bin ccmake)
diff --git a/Source/CursesDialog/ccmake.cxx b/Source/CursesDialog/ccmake.cxx
new file mode 100644
index 000000000..623d7d3a5
--- /dev/null
+++ b/Source/CursesDialog/ccmake.cxx
@@ -0,0 +1,217 @@
+/*============================================================================
+ 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 "../cmCacheManager.h"
+#include "../cmSystemTools.h"
+#include "../cmake.h"
+#include "../cmDocumentation.h"
+
+#include <signal.h>
+#include <sys/ioctl.h>
+
+#include "cmCursesMainForm.h"
+#include "cmCursesStandardIncludes.h"
+
+#include <form.h>
+
+//----------------------------------------------------------------------------
+static const char * cmDocumentationName[][3] =
+{
+ {0,
+ " ccmake - Curses Interface for CMake.", 0},
+ {0,0,0}
+};
+
+//----------------------------------------------------------------------------
+static const char * cmDocumentationUsage[][3] =
+{
+ {0,
+ " ccmake <path-to-source>\n"
+ " ccmake <path-to-existing-build>", 0},
+ {0,0,0}
+};
+
+//----------------------------------------------------------------------------
+static const char * cmDocumentationDescription[][3] =
+{
+ {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}
+};
+
+//----------------------------------------------------------------------------
+static const char * cmDocumentationOptions[][3] =
+{
+ CMAKE_STANDARD_OPTIONS_TABLE,
+ {0,0,0}
+};
+
+//----------------------------------------------------------------------------
+static const char * cmDocumentationSeeAlso[][3] =
+{
+ {0, "cmake", 0},
+ {0, "ctest", 0},
+ {0, 0, 0}
+};
+
+cmCursesForm* cmCursesForm::CurrentForm=0;
+
+extern "C"
+{
+
+void onsig(int)
+{
+ if (cmCursesForm::CurrentForm)
+ {
+ endwin();
+ initscr(); /* Initialization */
+ noecho(); /* Echo off */
+ cbreak(); /* nl- or cr not needed */
+ keypad(stdscr,TRUE); /* Use key symbols as
+ KEY_DOWN*/
+ refresh();
+ int x,y;
+ getmaxyx(stdscr, y, x);
+ cmCursesForm::CurrentForm->Render(1,1,x,y);
+ cmCursesForm::CurrentForm->UpdateStatusBar();
+ }
+ signal(SIGWINCH, onsig);
+}
+
+}
+
+void CMakeErrorHandler(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)
+{
+ cmSystemTools::FindExecutableDirectory(argv[0]);
+ cmDocumentation doc;
+ doc.addCMakeStandardDocSections();
+ if(doc.CheckOptions(argc, argv))
+ {
+ cmake hcm;
+ std::vector<cmDocumentationEntry> commands;
+ std::vector<cmDocumentationEntry> compatCommands;
+ 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);
+ 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;
+ }
+
+ bool debug = false;
+ unsigned int i;
+ int j;
+ std::vector<std::string> args;
+ for(j =0; j < argc; ++j)
+ {
+ if(strcmp(argv[j], "-debug") == 0)
+ {
+ debug = true;
+ }
+ else
+ {
+ args.push_back(argv[j]);
+ }
+ }
+
+ std::string cacheDir = cmSystemTools::GetCurrentWorkingDirectory();
+ for(i=1; i < args.size(); ++i)
+ {
+ std::string arg = args[i];
+ if(arg.find("-B",0) == 0)
+ {
+ cacheDir = arg.substr(2);
+ }
+ }
+
+ cmSystemTools::DisableRunCommandOutput();
+
+ if (debug)
+ {
+ cmCursesForm::DebugStart();
+ }
+
+ initscr(); /* Initialization */
+ noecho(); /* Echo off */
+ cbreak(); /* nl- or cr not needed */
+ keypad(stdscr,TRUE); /* Use key symbols as
+ KEY_DOWN*/
+
+ signal(SIGWINCH, onsig);
+
+ int x,y;
+ getmaxyx(stdscr, y, x);
+ if ( x < cmCursesMainForm::MIN_WIDTH ||
+ y < cmCursesMainForm::MIN_HEIGHT )
+ {
+ endwin();
+ std::cerr << "Window is too small. A size of at least "
+ << cmCursesMainForm::MIN_WIDTH << " x "
+ << cmCursesMainForm::MIN_HEIGHT
+ << " is required to run ccmake." << std::endl;
+ return 1;
+ }
+
+
+ cmCursesMainForm* myform;
+
+ myform = new cmCursesMainForm(args, x);
+ if(myform->LoadCache(cacheDir.c_str()))
+ {
+ curses_clear();
+ touchwin(stdscr);
+ endwin();
+ delete myform;
+ std::cerr << "Error running cmake::LoadCache(). Aborting.\n";
+ return 1;
+ }
+
+ cmSystemTools::SetErrorCallback(CMakeErrorHandler, myform);
+
+ cmCursesForm::CurrentForm = myform;
+
+ myform->InitializeUI();
+ if ( myform->Configure(1) == 0 )
+ {
+ myform->Render(1, 1, x, y);
+ myform->HandleInput();
+ }
+
+ // Need to clean-up better
+ curses_clear();
+ touchwin(stdscr);
+ endwin();
+ delete cmCursesForm::CurrentForm;
+ cmCursesForm::CurrentForm = 0;
+
+ std::cout << std::endl << std::endl;
+
+ return 0;
+
+}
diff --git a/Source/CursesDialog/cmCursesBoolWidget.cxx b/Source/CursesDialog/cmCursesBoolWidget.cxx
new file mode 100644
index 000000000..9c4c5a577
--- /dev/null
+++ b/Source/CursesDialog/cmCursesBoolWidget.cxx
@@ -0,0 +1,74 @@
+/*============================================================================
+ 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 "cmCursesBoolWidget.h"
+#include "cmCursesMainForm.h"
+
+cmCursesBoolWidget::cmCursesBoolWidget(int width, int height,
+ int left, int top) :
+ cmCursesWidget(width, height, left, top)
+{
+ this->Type = cmCacheManager::BOOL;
+ set_field_fore(this->Field, A_NORMAL);
+ set_field_back(this->Field, A_STANDOUT);
+ field_opts_off(this->Field, O_STATIC);
+ this->SetValueAsBool(false);
+}
+
+bool cmCursesBoolWidget::HandleInput(int& key, cmCursesMainForm*, WINDOW* w)
+{
+
+ // 10 == enter
+ if (key == 10 || key == KEY_ENTER)
+ {
+ if (this->GetValueAsBool())
+ {
+ this->SetValueAsBool(false);
+ }
+ else
+ {
+ this->SetValueAsBool(true);
+ }
+
+ touchwin(w);
+ wrefresh(w);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+
+}
+
+void cmCursesBoolWidget::SetValueAsBool(bool value)
+{
+ if (value)
+ {
+ this->SetValue("ON");
+ }
+ else
+ {
+ this->SetValue("OFF");
+ }
+}
+
+bool cmCursesBoolWidget::GetValueAsBool()
+{
+ if (this->Value == "ON")
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
diff --git a/Source/CursesDialog/cmCursesBoolWidget.h b/Source/CursesDialog/cmCursesBoolWidget.h
new file mode 100644
index 000000000..0d1d6a6cf
--- /dev/null
+++ b/Source/CursesDialog/cmCursesBoolWidget.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 __cmCursesBoolWidget_h
+#define __cmCursesBoolWidget_h
+
+#include "cmCursesWidget.h"
+class cmCursesMainForm;
+
+class cmCursesBoolWidget : public cmCursesWidget
+{
+public:
+ cmCursesBoolWidget(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);
+
+ // Description:
+ // Set/Get the value (on/off).
+ void SetValueAsBool(bool value);
+ bool GetValueAsBool();
+
+protected:
+ cmCursesBoolWidget(const cmCursesBoolWidget& from);
+ void operator=(const cmCursesBoolWidget&);
+
+};
+
+#endif // __cmCursesBoolWidget_h
diff --git a/Source/CursesDialog/cmCursesCacheEntryComposite.cxx b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx
new file mode 100644
index 000000000..828384d71
--- /dev/null
+++ b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx
@@ -0,0 +1,103 @@
+/*============================================================================
+ 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 "cmCursesCacheEntryComposite.h"
+#include "cmCursesStringWidget.h"
+#include "cmCursesLabelWidget.h"
+#include "cmCursesBoolWidget.h"
+#include "cmCursesPathWidget.h"
+#include "cmCursesFilePathWidget.h"
+#include "cmCursesDummyWidget.h"
+#include "../cmSystemTools.h"
+
+cmCursesCacheEntryComposite::cmCursesCacheEntryComposite(const char* key,
+ int labelwidth,
+ int entrywidth) :
+ Key(key), LabelWidth(labelwidth), EntryWidth(entrywidth)
+{
+ this->Label = new cmCursesLabelWidget(this->LabelWidth, 1, 1, 1, key);
+ this->IsNewLabel = new cmCursesLabelWidget(1, 1, 1, 1, " ");
+ this->Entry = 0;
+ this->Entry = new cmCursesStringWidget(this->EntryWidth, 1, 1, 1);
+}
+
+cmCursesCacheEntryComposite::cmCursesCacheEntryComposite(
+ const char* key, const cmCacheManager::CacheIterator& it, bool isNew,
+ int labelwidth, int entrywidth)
+ : Key(key), LabelWidth(labelwidth), EntryWidth(entrywidth)
+{
+ this->Label = new cmCursesLabelWidget(this->LabelWidth, 1, 1, 1, key);
+ if (isNew)
+ {
+ this->IsNewLabel = new cmCursesLabelWidget(1, 1, 1, 1, "*");
+ }
+ else
+ {
+ this->IsNewLabel = new cmCursesLabelWidget(1, 1, 1, 1, " ");
+ }
+
+ this->Entry = 0;
+ switch ( it.GetType() )
+ {
+ case cmCacheManager::BOOL:
+ this->Entry = new cmCursesBoolWidget(this->EntryWidth, 1, 1, 1);
+ if (cmSystemTools::IsOn(it.GetValue()))
+ {
+ static_cast<cmCursesBoolWidget*>(this->Entry)->SetValueAsBool(true);
+ }
+ else
+ {
+ static_cast<cmCursesBoolWidget*>(this->Entry)->SetValueAsBool(false);
+ }
+ break;
+ case cmCacheManager::PATH:
+ this->Entry = new cmCursesPathWidget(this->EntryWidth, 1, 1, 1);
+ static_cast<cmCursesPathWidget*>(this->Entry)->SetString(
+ it.GetValue());
+ break;
+ case cmCacheManager::FILEPATH:
+ this->Entry = new cmCursesFilePathWidget(this->EntryWidth, 1, 1, 1);
+ static_cast<cmCursesFilePathWidget*>(this->Entry)->SetString(
+ it.GetValue());
+ break;
+ case cmCacheManager::STRING:
+ this->Entry = new cmCursesStringWidget(this->EntryWidth, 1, 1, 1);
+ static_cast<cmCursesStringWidget*>(this->Entry)->SetString(
+ it.GetValue());
+ break;
+ case cmCacheManager::UNINITIALIZED:
+ cmSystemTools::Error("Found an undefined variable: ", it.GetName());
+ break;
+ default:
+ // TODO : put warning message here
+ break;
+ }
+
+}
+
+cmCursesCacheEntryComposite::~cmCursesCacheEntryComposite()
+{
+ delete this->Label;
+ delete this->IsNewLabel;
+ delete this->Entry;
+}
+
+const char* cmCursesCacheEntryComposite::GetValue()
+{
+ if (this->Label)
+ {
+ return this->Label->GetValue();
+ }
+ else
+ {
+ return 0;
+ }
+}
diff --git a/Source/CursesDialog/cmCursesCacheEntryComposite.h b/Source/CursesDialog/cmCursesCacheEntryComposite.h
new file mode 100644
index 000000000..a40ea28e1
--- /dev/null
+++ b/Source/CursesDialog/cmCursesCacheEntryComposite.h
@@ -0,0 +1,42 @@
+/*============================================================================
+ 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 __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,
+ bool isNew, int labelwidth, int entrywidth);
+ ~cmCursesCacheEntryComposite();
+ const char* GetValue();
+
+ friend class cmCursesMainForm;
+
+protected:
+ cmCursesCacheEntryComposite(const cmCursesCacheEntryComposite& from);
+ void operator=(const cmCursesCacheEntryComposite&);
+
+ cmCursesLabelWidget* Label;
+ cmCursesLabelWidget* IsNewLabel;
+ cmCursesWidget* Entry;
+ std::string Key;
+ int LabelWidth;
+ int EntryWidth;
+};
+
+#endif // __cmCursesCacheEntryComposite_h
diff --git a/Source/CursesDialog/cmCursesDummyWidget.cxx b/Source/CursesDialog/cmCursesDummyWidget.cxx
new file mode 100644
index 000000000..1d8a45d79
--- /dev/null
+++ b/Source/CursesDialog/cmCursesDummyWidget.cxx
@@ -0,0 +1,26 @@
+/*============================================================================
+ 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 "cmCursesDummyWidget.h"
+
+cmCursesDummyWidget::cmCursesDummyWidget(int width, int height,
+ int left, int top) :
+ cmCursesWidget(width, height, left, top)
+{
+ this->Type = cmCacheManager::INTERNAL;
+}
+
+
+bool cmCursesDummyWidget::HandleInput(int&, cmCursesMainForm*, WINDOW* )
+{
+ return false;
+}
+
diff --git a/Source/CursesDialog/cmCursesDummyWidget.h b/Source/CursesDialog/cmCursesDummyWidget.h
new file mode 100644
index 000000000..cc4cc748d
--- /dev/null
+++ b/Source/CursesDialog/cmCursesDummyWidget.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 __cmCursesDummyWidget_h
+#define __cmCursesDummyWidget_h
+
+#include "cmCursesWidget.h"
+
+class cmCursesMainForm;
+
+class cmCursesDummyWidget : public cmCursesWidget
+{
+public:
+ cmCursesDummyWidget(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);
+
+protected:
+ cmCursesDummyWidget(const cmCursesDummyWidget& from);
+ void operator=(const cmCursesDummyWidget&);
+
+};
+
+#endif // __cmCursesDummyWidget_h
diff --git a/Source/CursesDialog/cmCursesFilePathWidget.cxx b/Source/CursesDialog/cmCursesFilePathWidget.cxx
new file mode 100644
index 000000000..13bbcc936
--- /dev/null
+++ b/Source/CursesDialog/cmCursesFilePathWidget.cxx
@@ -0,0 +1,20 @@
+/*============================================================================
+ 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 "cmCursesFilePathWidget.h"
+
+cmCursesFilePathWidget::cmCursesFilePathWidget(int width, int height,
+ int left, int top) :
+ cmCursesPathWidget(width, height, left, top)
+{
+ this->Type = cmCacheManager::FILEPATH;
+}
+
diff --git a/Source/CursesDialog/cmCursesFilePathWidget.h b/Source/CursesDialog/cmCursesFilePathWidget.h
new file mode 100644
index 000000000..9d2972ee7
--- /dev/null
+++ b/Source/CursesDialog/cmCursesFilePathWidget.h
@@ -0,0 +1,28 @@
+/*============================================================================
+ 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 __cmCursesFilePathWidget_h
+#define __cmCursesFilePathWidget_h
+
+#include "cmCursesPathWidget.h"
+
+class cmCursesFilePathWidget : public cmCursesPathWidget
+{
+public:
+ cmCursesFilePathWidget(int width, int height, int left, int top);
+
+protected:
+ cmCursesFilePathWidget(const cmCursesFilePathWidget& from);
+ void operator=(const cmCursesFilePathWidget&);
+
+};
+
+#endif // __cmCursesFilePathWidget_h
diff --git a/Source/CursesDialog/cmCursesForm.cxx b/Source/CursesDialog/cmCursesForm.cxx
new file mode 100644
index 000000000..72ae5eef7
--- /dev/null
+++ b/Source/CursesDialog/cmCursesForm.cxx
@@ -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.
+============================================================================*/
+#include "cmCursesForm.h"
+
+std::ofstream cmCursesForm::DebugFile;
+bool cmCursesForm::Debug = false;
+
+cmCursesForm::cmCursesForm()
+{
+ this->Form = 0;
+}
+
+cmCursesForm::~cmCursesForm()
+{
+ if (this->Form)
+ {
+ unpost_form(this->Form);
+ free_form(this->Form);
+ this->Form = 0;
+ }
+}
+
+void cmCursesForm::DebugStart()
+{
+ cmCursesForm::Debug = true;
+ cmCursesForm::DebugFile.open("ccmakelog.txt");
+}
+
+void cmCursesForm::DebugEnd()
+{
+ if (!cmCursesForm::Debug)
+ {
+ return;
+ }
+
+ cmCursesForm::Debug = false;
+ cmCursesForm::DebugFile.close();
+}
+
+void cmCursesForm::LogMessage(const char* msg)
+{
+ if (!cmCursesForm::Debug)
+ {
+ return;
+ }
+
+ cmCursesForm::DebugFile << msg << std::endl;
+}
diff --git a/Source/CursesDialog/cmCursesForm.h b/Source/CursesDialog/cmCursesForm.h
new file mode 100644
index 000000000..7556d74b5
--- /dev/null
+++ b/Source/CursesDialog/cmCursesForm.h
@@ -0,0 +1,75 @@
+/*============================================================================
+ 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 __cmCursesForm_h
+#define __cmCursesForm_h
+
+#include "../cmStandardIncludes.h"
+#include "cmCursesStandardIncludes.h"
+
+class cmCursesForm
+{
+public:
+ cmCursesForm();
+ virtual ~cmCursesForm();
+
+ // Description:
+ // Handle user input.
+ virtual void HandleInput() = 0;
+
+ // Description:
+ // Display form.
+ virtual void Render(int left, int top, int width, int height) = 0;
+
+ // Description:
+ // This method should normally called only by the form.
+ // The only exception is during a resize.
+ virtual void UpdateStatusBar() = 0;
+
+ // Description:
+ // During a CMake run, an error handle should add errors
+ // to be displayed afterwards.
+ virtual void AddError(const char*, const char*) {}
+
+ // Description:
+ // Turn debugging on. This will create ccmakelog.txt.
+ static void DebugStart();
+
+ // Description:
+ // Turn debugging off. This will close ccmakelog.txt.
+ static void DebugEnd();
+
+ // Description:
+ // Write a debugging message.
+ static void LogMessage(const char* msg);
+
+ // Description:
+ // Return the FORM. Should be only used by low-level methods.
+ FORM* GetForm()
+ {
+ return this->Form;
+ }
+
+ static cmCursesForm* CurrentForm;
+
+
+protected:
+
+ static std::ofstream DebugFile;
+ static bool Debug;
+
+ cmCursesForm(const cmCursesForm& form);
+ void operator=(const cmCursesForm&);
+
+ FORM* Form;
+};
+
+#endif // __cmCursesForm_h
diff --git a/Source/CursesDialog/cmCursesLabelWidget.cxx b/Source/CursesDialog/cmCursesLabelWidget.cxx
new file mode 100644
index 000000000..2ad4813c6
--- /dev/null
+++ b/Source/CursesDialog/cmCursesLabelWidget.cxx
@@ -0,0 +1,33 @@
+/*============================================================================
+ 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 "cmCursesLabelWidget.h"
+
+cmCursesLabelWidget::cmCursesLabelWidget(int width, int height,
+ int left, int top,
+ const std::string& name) :
+ cmCursesWidget(width, height, left, top)
+{
+ 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());
+}
+
+cmCursesLabelWidget::~cmCursesLabelWidget()
+{
+}
+
+bool cmCursesLabelWidget::HandleInput(int&, cmCursesMainForm*, WINDOW* )
+{
+ // Static text. No input is handled here.
+ return false;
+}
diff --git a/Source/CursesDialog/cmCursesLabelWidget.h b/Source/CursesDialog/cmCursesLabelWidget.h
new file mode 100644
index 000000000..bbcc58618
--- /dev/null
+++ b/Source/CursesDialog/cmCursesLabelWidget.h
@@ -0,0 +1,38 @@
+/*============================================================================
+ 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 __cmCursesLabelWidget_h
+#define __cmCursesLabelWidget_h
+
+#include "cmCursesWidget.h"
+#include "cmCursesStandardIncludes.h"
+
+class cmCursesMainForm;
+
+class cmCursesLabelWidget : public cmCursesWidget
+{
+public:
+ cmCursesLabelWidget(int width, int height, int left, int top,
+ const std::string& name);
+ virtual ~cmCursesLabelWidget();
+
+ // 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);
+
+protected:
+ cmCursesLabelWidget(const cmCursesLabelWidget& from);
+ void operator=(const cmCursesLabelWidget&);
+};
+
+#endif // __cmCursesLabelWidget_h
diff --git a/Source/CursesDialog/cmCursesLongMessageForm.cxx b/Source/CursesDialog/cmCursesLongMessageForm.cxx
new file mode 100644
index 000000000..0e2cd229f
--- /dev/null
+++ b/Source/CursesDialog/cmCursesLongMessageForm.cxx
@@ -0,0 +1,207 @@
+/*============================================================================
+ 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 "../cmCacheManager.h"
+#include "../cmSystemTools.h"
+#include "../cmake.h"
+#include "../cmVersion.h"
+#include "cmCursesLongMessageForm.h"
+#include "cmCursesMainForm.h"
+
+inline int ctrl(int z)
+{
+ return (z&037);
+}
+
+cmCursesLongMessageForm::cmCursesLongMessageForm(std::vector<std::string>
+ const& messages, const char*
+ title)
+{
+ // Append all messages into on big string
+ std::vector<std::string>::const_iterator it;
+ for(it=messages.begin(); it != messages.end(); it++)
+ {
+ this->Messages += (*it);
+ // Add one blank line after each message
+ this->Messages += "\n\n";
+ }
+ this->Title = title;
+ this->Fields[0] = 0;
+ this->Fields[1] = 0;
+}
+
+cmCursesLongMessageForm::~cmCursesLongMessageForm()
+{
+ if (this->Fields[0])
+ {
+ free_field(this->Fields[0]);
+ }
+}
+
+
+void cmCursesLongMessageForm::UpdateStatusBar()
+{
+ int x,y;
+ getmaxyx(stdscr, y, x);
+
+ char bar[cmCursesMainForm::MAX_WIDTH];
+ size_t size = strlen(this->Title.c_str());
+ if ( size >= cmCursesMainForm::MAX_WIDTH )
+ {
+ size = cmCursesMainForm::MAX_WIDTH-1;
+ }
+ strncpy(bar, this->Title.c_str(), size);
+ for(size_t i=size-1; i<cmCursesMainForm::MAX_WIDTH; i++) bar[i] = ' ';
+
+ int width;
+ if (x < cmCursesMainForm::MAX_WIDTH )
+ {
+ width = x;
+ }
+ else
+ {
+ width = cmCursesMainForm::MAX_WIDTH-1;
+ }
+
+ bar[width] = '\0';
+
+ char version[cmCursesMainForm::MAX_WIDTH];
+ char vertmp[128];
+ sprintf(vertmp,"CMake Version %s", cmVersion::GetCMakeVersion());
+ size_t sideSpace = (width-strlen(vertmp));
+ for(size_t i=0; i<sideSpace; i++) { version[i] = ' '; }
+ sprintf(version+sideSpace, "%s", vertmp);
+ version[width] = '\0';
+
+ curses_move(y-4,0);
+ attron(A_STANDOUT);
+ printw(bar);
+ attroff(A_STANDOUT);
+ curses_move(y-3,0);
+ printw(version);
+ pos_form_cursor(this->Form);
+}
+
+void cmCursesLongMessageForm::PrintKeys()
+{
+ int x,y;
+ getmaxyx(stdscr, y, x);
+ if ( x < cmCursesMainForm::MIN_WIDTH ||
+ y < cmCursesMainForm::MIN_HEIGHT )
+ {
+ return;
+ }
+ char firstLine[512];
+ sprintf(firstLine, "Press [e] to exit help");
+
+ curses_move(y-2,0);
+ printw(firstLine);
+ pos_form_cursor(this->Form);
+
+}
+
+void cmCursesLongMessageForm::Render(int, int, int, int)
+{
+ int x,y;
+ getmaxyx(stdscr, y, x);
+
+ if (this->Form)
+ {
+ unpost_form(this->Form);
+ free_form(this->Form);
+ this->Form = 0;
+ }
+
+ const char* msg = this->Messages.c_str();
+
+ curses_clear();
+
+ if (this->Fields[0])
+ {
+ free_field(this->Fields[0]);
+ this->Fields[0] = 0;
+ }
+
+ this->Fields[0] = new_field(y-6, x-2, 1, 1, 0, 0);
+
+ field_opts_off(this->Fields[0], O_STATIC);
+
+ this->Form = new_form(this->Fields);
+ post_form(this->Form);
+
+ int i=0;
+ form_driver(this->Form, REQ_BEG_FIELD);
+ while(msg[i] != '\0' && i < 60000)
+ {
+ if (msg[i] == '\n' && msg[i+1] != '\0')
+ {
+ form_driver(this->Form, REQ_NEW_LINE);
+ }
+ else
+ {
+ form_driver(this->Form, msg[i]);
+ }
+ i++;
+ }
+ form_driver(this->Form, REQ_BEG_FIELD);
+
+ this->UpdateStatusBar();
+ this->PrintKeys();
+ touchwin(stdscr);
+ refresh();
+
+}
+
+void cmCursesLongMessageForm::HandleInput()
+{
+ if (!this->Form)
+ {
+ return;
+ }
+
+ char debugMessage[128];
+
+ for(;;)
+ {
+ int key = getch();
+
+ sprintf(debugMessage, "Message widget handling input, key: %d", key);
+ cmCursesForm::LogMessage(debugMessage);
+
+ // quit
+ if ( key == 'o' || key == 'e' )
+ {
+ break;
+ }
+ else if ( key == KEY_DOWN || key == ctrl('n') )
+ {
+ form_driver(this->Form, REQ_SCR_FLINE);
+ }
+ else if ( key == KEY_UP || key == ctrl('p') )
+ {
+ form_driver(this->Form, REQ_SCR_BLINE);
+ }
+ else if ( key == KEY_NPAGE || key == ctrl('d') )
+ {
+ form_driver(this->Form, REQ_SCR_FPAGE);
+ }
+ else if ( key == KEY_PPAGE || key == ctrl('u') )
+ {
+ form_driver(this->Form, REQ_SCR_BPAGE);
+ }
+
+ this->UpdateStatusBar();
+ this->PrintKeys();
+ touchwin(stdscr);
+ wrefresh(stdscr);
+ }
+
+}
diff --git a/Source/CursesDialog/cmCursesLongMessageForm.h b/Source/CursesDialog/cmCursesLongMessageForm.h
new file mode 100644
index 000000000..341f9c6c6
--- /dev/null
+++ b/Source/CursesDialog/cmCursesLongMessageForm.h
@@ -0,0 +1,58 @@
+/*============================================================================
+ 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 __cmCursesLongMessageForm_h
+#define __cmCursesLongMessageForm_h
+
+#include "../cmStandardIncludes.h"
+#include "cmCursesForm.h"
+#include "cmCursesStandardIncludes.h"
+
+class cmCursesCacheEntryComposite;
+
+class cmCursesLongMessageForm : public cmCursesForm
+{
+public:
+ cmCursesLongMessageForm(std::vector<std::string> const& messages,
+ const char* title);
+ virtual ~cmCursesLongMessageForm();
+
+ // Description:
+ // Handle user input.
+ virtual void HandleInput();
+
+ // Description:
+ // Display form. Use a window of size width x height, starting
+ // at top, left.
+ virtual void Render(int left, int top, int width, int height);
+
+ // Description:
+ // This method should normally called only by the form.
+ // The only exception is during a resize.
+ void PrintKeys();
+
+ // Description:
+ // This method should normally called only by the form.
+ // The only exception is during a resize.
+ virtual void UpdateStatusBar();
+
+protected:
+ cmCursesLongMessageForm(const cmCursesLongMessageForm& from);
+ void operator=(const cmCursesLongMessageForm&);
+
+ std::string Messages;
+ std::string Title;
+
+ FIELD* Fields[2];
+
+};
+
+#endif // __cmCursesLongMessageForm_h
diff --git a/Source/CursesDialog/cmCursesMainForm.cxx b/Source/CursesDialog/cmCursesMainForm.cxx
new file mode 100644
index 000000000..4fee0bbd3
--- /dev/null
+++ b/Source/CursesDialog/cmCursesMainForm.cxx
@@ -0,0 +1,1303 @@
+/*============================================================================
+ 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 "../cmCacheManager.h"
+#include "../cmSystemTools.h"
+#include "../cmVersion.h"
+#include "../cmake.h"
+#include "cmCursesMainForm.h"
+#include "cmCursesStringWidget.h"
+#include "cmCursesLabelWidget.h"
+#include "cmCursesBoolWidget.h"
+#include "cmCursesPathWidget.h"
+#include "cmCursesFilePathWidget.h"
+#include "cmCursesDummyWidget.h"
+#include "cmCursesCacheEntryComposite.h"
+#include "cmCursesLongMessageForm.h"
+
+
+inline int ctrl(int z)
+{
+ return (z&037);
+}
+
+cmCursesMainForm::cmCursesMainForm(std::vector<std::string> const& args,
+ int initWidth) :
+ Args(args), InitialWidth(initWidth)
+{
+ this->NumberOfPages = 0;
+ this->Fields = 0;
+ this->Entries = 0;
+ this->AdvancedMode = false;
+ this->NumberOfVisibleEntries = 0;
+ this->OkToGenerate = false;
+ this->HelpMessage.push_back("Welcome to ccmake, curses based user interface for CMake.");
+ this->HelpMessage.push_back("");
+ this->HelpMessage.push_back(s_ConstHelpMessage);
+ this->CMakeInstance = new cmake;
+ this->CMakeInstance->SetCMakeEditCommand("ccmake");
+
+ // create the arguments for the cmake object
+ std::string whereCMake = cmSystemTools::GetProgramPath(this->Args[0].c_str());
+ whereCMake += "/cmake";
+ this->Args[0] = whereCMake;
+ this->CMakeInstance->SetArgs(this->Args);
+ this->CMakeInstance->SetCMakeCommand(whereCMake.c_str());
+ this->SearchString = "";
+ this->OldSearchString = "";
+ this->SearchMode = false;
+}
+
+cmCursesMainForm::~cmCursesMainForm()
+{
+ if (this->Form)
+ {
+ unpost_form(this->Form);
+ free_form(this->Form);
+ this->Form = 0;
+ }
+ delete[] this->Fields;
+
+ // Clean-up composites
+ if (this->Entries)
+ {
+ std::vector<cmCursesCacheEntryComposite*>::iterator it;
+ for (it = this->Entries->begin(); it != this->Entries->end(); ++it)
+ {
+ delete *it;
+ }
+ }
+ delete this->Entries;
+ if (this->CMakeInstance)
+ {
+ delete this->CMakeInstance;
+ this->CMakeInstance = 0;
+ }
+}
+
+// See if a cache entry is in the list of entries in the ui.
+bool cmCursesMainForm::LookForCacheEntry(const char* key)
+{
+ if (!key || !this->Entries)
+ {
+ return false;
+ }
+
+ std::vector<cmCursesCacheEntryComposite*>::iterator it;
+ for (it = this->Entries->begin(); it != this->Entries->end(); ++it)
+ {
+ if (!strcmp(key, (*it)->Key.c_str()))
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+// Create new cmCursesCacheEntryComposite entries from the cache
+void cmCursesMainForm::InitializeUI()
+{
+ // Create a vector of cmCursesCacheEntryComposite's
+ // which contain labels, entries and new entry markers
+ std::vector<cmCursesCacheEntryComposite*>* newEntries =
+ new std::vector<cmCursesCacheEntryComposite*>;
+ newEntries->reserve(this->CMakeInstance->GetCacheManager()->GetSize());
+
+ // Count non-internal and non-static entries
+ int count=0;
+ for(cmCacheManager::CacheIterator i =
+ this->CMakeInstance->GetCacheManager()->NewIterator();
+ !i.IsAtEnd(); i.Next())
+ {
+ if ( i.GetType() != cmCacheManager::INTERNAL &&
+ i.GetType() != cmCacheManager::STATIC &&
+ i.GetType() != cmCacheManager::UNINITIALIZED)
+ {
+ ++count;
+ }
+ }
+
+ int entrywidth = this->InitialWidth - 35;
+
+ cmCursesCacheEntryComposite* comp;
+ if ( count == 0 )
+ {
+ // If cache is empty, display a label saying so and a
+ // dummy entry widget (does not respond to input)
+ comp = new cmCursesCacheEntryComposite("EMPTY CACHE", 30, 30);
+ comp->Entry = new cmCursesDummyWidget(1, 1, 1, 1);
+ newEntries->push_back(comp);
+ }
+ else
+ {
+ // Create the composites.
+
+ // First add entries which are new
+ for(cmCacheManager::CacheIterator i =
+ this->CMakeInstance->GetCacheManager()->NewIterator();
+ !i.IsAtEnd(); i.Next())
+ {
+ const char* key = i.GetName();
+ if ( i.GetType() == cmCacheManager::INTERNAL ||
+ i.GetType() == cmCacheManager::STATIC ||
+ i.GetType() == cmCacheManager::UNINITIALIZED )
+ {
+ continue;
+ }
+
+ if (!this->LookForCacheEntry(key))
+ {
+ newEntries->push_back(new cmCursesCacheEntryComposite(key, i,
+ true, 30,
+ entrywidth));
+ this->OkToGenerate = false;
+ }
+ }
+
+ // then add entries which are old
+ for(cmCacheManager::CacheIterator i =
+ this->CMakeInstance->GetCacheManager()->NewIterator();
+ !i.IsAtEnd(); i.Next())
+ {
+ const char* key = i.GetName();
+ if ( i.GetType() == cmCacheManager::INTERNAL ||
+ i.GetType() == cmCacheManager::STATIC ||
+ i.GetType() == cmCacheManager::UNINITIALIZED )
+ {
+ continue;
+ }
+
+ if (this->LookForCacheEntry(key))
+ {
+ newEntries->push_back(new cmCursesCacheEntryComposite(key, i,
+ false, 30,
+ entrywidth));
+ }
+ }
+ }
+
+ // 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;
+ }
+ }
+ delete this->Entries;
+ this->Entries = newEntries;
+
+ // Compute fields from composites
+ this->RePost();
+}
+
+
+void cmCursesMainForm::RePost()
+{
+ // Create the fields to be passed to the form.
+ if (this->Form)
+ {
+ unpost_form(this->Form);
+ free_form(this->Form);
+ this->Form = 0;
+ }
+ delete[] this->Fields;
+ if (this->AdvancedMode)
+ {
+ this->NumberOfVisibleEntries = this->Entries->size();
+ }
+ else
+ {
+ // If normal mode, count only non-advanced entries
+ this->NumberOfVisibleEntries = 0;
+ 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")))
+ {
+ continue;
+ }
+ this->NumberOfVisibleEntries++;
+ }
+ }
+ // there is always one even if it is the dummy one
+ if(this->NumberOfVisibleEntries == 0)
+ {
+ this->NumberOfVisibleEntries = 1;
+ }
+ // Assign the fields: 3 for each entry: label, new entry marker
+ // ('*' or ' ') and entry widget
+ this->Fields = new FIELD*[3*this->NumberOfVisibleEntries+1];
+ size_t cc;
+ for ( cc = 0; cc < 3 * this->NumberOfVisibleEntries+1; cc ++ )
+ {
+ this->Fields[cc] = 0;
+ }
+
+ // Assign fields
+ int j=0;
+ 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")))
+ {
+ continue;
+ }
+ this->Fields[3*j] = (*it)->Label->Field;
+ this->Fields[3*j+1] = (*it)->IsNewLabel->Field;
+ this->Fields[3*j+2] = (*it)->Entry->Field;
+ j++;
+ }
+ // if no cache entries there should still be one dummy field
+ if(j == 0)
+ {
+ it = this->Entries->begin();
+ this->Fields[0] = (*it)->Label->Field;
+ this->Fields[1] = (*it)->IsNewLabel->Field;
+ this->Fields[2] = (*it)->Entry->Field;
+ this->NumberOfVisibleEntries = 1;
+ }
+ // Has to be null terminated.
+ this->Fields[3*this->NumberOfVisibleEntries] = 0;
+}
+
+void cmCursesMainForm::Render(int left, int top, int width, int height)
+{
+
+ if (this->Form)
+ {
+ FIELD* currentField = current_field(this->Form);
+ 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 )
+ {
+ cmCursesStringWidget* sw = static_cast<cmCursesStringWidget*>(cw);
+ sw->SetInEdit(false);
+ }
+ // Delete the previous form
+ unpost_form(this->Form);
+ free_form(this->Form);
+ this->Form = 0;
+ }
+
+ // Wrong window size
+ if ( width < cmCursesMainForm::MIN_WIDTH ||
+ width < this->InitialWidth ||
+ height < cmCursesMainForm::MIN_HEIGHT )
+ {
+ return;
+ }
+
+ // Leave room for toolbar
+ height -= 7;
+
+ if (this->AdvancedMode)
+ {
+ this->NumberOfVisibleEntries = this->Entries->size();
+ }
+ else
+ {
+ // If normal, display only non-advanced entries
+ this->NumberOfVisibleEntries = 0;
+ 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")))
+ {
+ continue;
+ }
+ this->NumberOfVisibleEntries++;
+ }
+ }
+
+ // Re-adjust the fields according to their place
+ this->NumberOfPages = 1;
+ if (height > 0)
+ {
+ bool isNewPage;
+ int i=0;
+ 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")))
+ {
+ continue;
+ }
+ int row = (i % height) + 1;
+ int page = (i / height) + 1;
+ isNewPage = ( page > 1 ) && ( row == 1 );
+
+ if (isNewPage)
+ {
+ this->NumberOfPages++;
+ }
+ (*it)->Label->Move(left, top+row-1, isNewPage);
+ (*it)->IsNewLabel->Move(left+32, top+row-1, false);
+ (*it)->Entry->Move(left+33, top+row-1, false);
+ (*it)->Entry->SetPage(this->NumberOfPages);
+ i++;
+ }
+ }
+
+ // Post the form
+ this->Form = new_form(this->Fields);
+ post_form(this->Form);
+ // Update toolbar
+ this->UpdateStatusBar();
+ this->PrintKeys();
+
+ touchwin(stdscr);
+ refresh();
+}
+
+void cmCursesMainForm::PrintKeys(int process /* = 0 */)
+{
+ int x,y;
+ getmaxyx(stdscr, y, x);
+ if ( x < cmCursesMainForm::MIN_WIDTH ||
+ x < this->InitialWidth ||
+ y < cmCursesMainForm::MIN_HEIGHT )
+ {
+ return;
+ }
+
+ // Give the current widget (if it exists), a chance to print keys
+ cmCursesWidget* cw = 0;
+ if (this->Form)
+ {
+ FIELD* currentField = current_field(this->Form);
+ cw = reinterpret_cast<cmCursesWidget*>(field_userptr(currentField));
+ }
+
+ if (cw)
+ {
+ cw->PrintKeys();
+ }
+
+// {
+// }
+// else
+// {
+ char firstLine[512]="";
+ char secondLine[512]="";
+ char thirdLine[512]="";
+ if (process)
+ {
+ const char* clearLine =
+ " ";
+ strcpy(firstLine, clearLine);
+ strcpy(secondLine, clearLine);
+ strcpy(thirdLine, clearLine);
+ }
+ else
+ {
+ if (this->OkToGenerate)
+ {
+ sprintf(firstLine,
+ "Press [c] to configure Press [g] to generate and exit");
+ }
+ else
+ {
+ sprintf(firstLine, "Press [c] to configure ");
+ }
+ {
+ const char* toggleKeyInstruction =
+ "Press [t] to toggle advanced mode (Currently %s)";
+ sprintf(thirdLine,
+ toggleKeyInstruction,
+ this->AdvancedMode ? "On" : "Off");
+ }
+ sprintf(secondLine,
+ "Press [h] for help "
+ "Press [q] to quit without generating");
+ }
+
+ curses_move(y-4,0);
+ char fmt[512] = "Press [enter] to edit option";
+ if ( process )
+ {
+ strcpy(fmt, " ");
+ }
+ printw(fmt);
+ curses_move(y-3,0);
+ printw(firstLine);
+ curses_move(y-2,0);
+ printw(secondLine);
+ curses_move(y-1,0);
+ printw(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);
+ }
+// }
+
+ pos_form_cursor(this->Form);
+
+}
+
+// Print the key of the current entry and the CMake version
+// on the status bar. Designed for a width of 80 chars.
+void cmCursesMainForm::UpdateStatusBar(const char* message)
+{
+ int x,y;
+ getmaxyx(stdscr, y, x);
+ // If window size is too small, display error and return
+ if ( x < cmCursesMainForm::MIN_WIDTH ||
+ x < this->InitialWidth ||
+ y < cmCursesMainForm::MIN_HEIGHT )
+ {
+ curses_clear();
+ curses_move(0,0);
+ char fmt[] = "Window is too small. A size of at least %dx%d is required.";
+ printw(fmt,
+ (cmCursesMainForm::MIN_WIDTH < this->InitialWidth ?
+ this->InitialWidth : cmCursesMainForm::MIN_WIDTH),
+ cmCursesMainForm::MIN_HEIGHT);
+ touchwin(stdscr);
+ wrefresh(stdscr);
+ return;
+ }
+
+ // Get the key of the current entry
+ FIELD* cur = current_field(this->Form);
+ int findex = field_index(cur);
+ cmCursesWidget* lbl = 0;
+ if ( findex >= 0 )
+ {
+ lbl = reinterpret_cast<cmCursesWidget*>(field_userptr(this->Fields[findex-2]));
+ }
+ char help[128] = "";
+ const char* curField = "";
+ if ( lbl )
+ {
+ curField = lbl->GetValue();
+
+ // 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* hs = it.GetProperty("HELPSTRING");
+ if ( hs )
+ {
+ strncpy(help, hs, 127);
+ help[127] = '\0';
+ }
+ else
+ {
+ help[0] = 0;
+ }
+ }
+ else
+ {
+ sprintf(help," ");
+ }
+ }
+
+ // Join the key, help string and pad with spaces
+ // (or truncate) as necessary
+ char bar[cmCursesMainForm::MAX_WIDTH];
+ size_t i, curFieldLen = strlen(curField);
+ size_t helpLen = strlen(help);
+
+ size_t width;
+ if (x < cmCursesMainForm::MAX_WIDTH )
+ {
+ width = x;
+ }
+ else
+ {
+ width = cmCursesMainForm::MAX_WIDTH;
+ }
+
+ if ( message )
+ {
+ curField = message;
+ curFieldLen = strlen(message);
+ if ( curFieldLen < width )
+ {
+ strcpy(bar, curField);
+ for(i=curFieldLen; i < width; ++i)
+ {
+ bar[i] = ' ';
+ }
+ }
+ else
+ {
+ strncpy(bar, curField, width);
+ }
+ }
+ else
+ {
+ if (curFieldLen >= width)
+ {
+ strncpy(bar, curField, width);
+ }
+ else
+ {
+ strcpy(bar, curField);
+ bar[curFieldLen] = ':';
+ bar[curFieldLen+1] = ' ';
+ if (curFieldLen + helpLen + 2 >= width)
+ {
+ strncpy(bar+curFieldLen+2, help, width
+ - curFieldLen - 2);
+ }
+ else
+ {
+ strcpy(bar+curFieldLen+2, help);
+ for(i=curFieldLen+helpLen+2; i < width; ++i)
+ {
+ bar[i] = ' ';
+ }
+ }
+ }
+ }
+
+
+ bar[width] = '\0';
+
+
+ // Display CMake version info on the next line
+ // We want to display this on the right
+ char version[cmCursesMainForm::MAX_WIDTH];
+ char vertmp[128];
+ sprintf(vertmp,"CMake Version %s", cmVersion::GetCMakeVersion());
+ size_t sideSpace = (width-strlen(vertmp));
+ for(i=0; i<sideSpace; i++) { version[i] = ' '; }
+ sprintf(version+sideSpace, "%s", vertmp);
+ version[width] = '\0';
+
+ // Now print both lines
+ curses_move(y-5,0);
+ attron(A_STANDOUT);
+ char format[] = "%s";
+ printw(format, bar);
+ attroff(A_STANDOUT);
+ curses_move(y-4,0);
+ printw(version);
+ pos_form_cursor(this->Form);
+}
+
+void cmCursesMainForm::UpdateProgress(const char *msg, float prog, void* vp)
+{
+ cmCursesMainForm* cm = static_cast<cmCursesMainForm*>(vp);
+ if ( !cm )
+ {
+ return;
+ }
+ char tmp[1024];
+ const char *cmsg = tmp;
+ if ( prog >= 0 )
+ {
+ sprintf(tmp, "%s %i%%",msg,(int)(100*prog));
+ }
+ else
+ {
+ cmsg = msg;
+ }
+ cm->UpdateStatusBar(cmsg);
+ cm->PrintKeys(1);
+ curses_move(1,1);
+ touchwin(stdscr);
+ refresh();
+}
+
+int cmCursesMainForm::Configure(int noconfigure)
+{
+ int xi,yi;
+ getmaxyx(stdscr, yi, xi);
+
+ curses_move(1,1);
+ this->UpdateStatusBar("Configuring, please wait...");
+ this->PrintKeys(1);
+ touchwin(stdscr);
+ refresh();
+ this->CMakeInstance->SetProgressCallback(cmCursesMainForm::UpdateProgress, this);
+
+ // always save the current gui values to disk
+ this->FillCacheManagerFromUI();
+ this->CMakeInstance->GetCacheManager()->SaveCache(
+ this->CMakeInstance->GetHomeOutputDirectory());
+ this->LoadCache(0);
+
+ // Get rid of previous errors
+ this->Errors = std::vector<std::string>();
+
+ // run the generate process
+ this->OkToGenerate = true;
+ int retVal;
+ if ( noconfigure )
+ {
+ retVal = this->CMakeInstance->DoPreConfigureChecks();
+ this->OkToGenerate = false;
+ if ( retVal > 0 )
+ {
+ retVal = 0;
+ }
+ }
+ else
+ {
+ retVal = this->CMakeInstance->Configure();
+ }
+ this->CMakeInstance->SetProgressCallback(0, 0);
+
+ keypad(stdscr,TRUE); /* Use key symbols as
+ KEY_DOWN*/
+
+ if( retVal != 0 || !this->Errors.empty())
+ {
+ // see if there was an error
+ if(cmSystemTools::GetErrorOccuredFlag())
+ {
+ this->OkToGenerate = false;
+ }
+ int xx,yy;
+ getmaxyx(stdscr, yy, xx);
+ cmCursesLongMessageForm* msgs = new cmCursesLongMessageForm(
+ this->Errors,
+ cmSystemTools::GetErrorOccuredFlag()
+ ? "Errors occurred during the last pass." :
+ "CMake produced the following output.");
+ // reset error condition
+ cmSystemTools::ResetErrorOccuredFlag();
+ CurrentForm = msgs;
+ msgs->Render(1,1,xx,yy);
+ msgs->HandleInput();
+ // If they typed the wrong source directory, we report
+ // an error and exit
+ if ( retVal == -2 )
+ {
+ return retVal;
+ }
+ CurrentForm = this;
+ this->Render(1,1,xx,yy);
+ }
+
+ this->InitializeUI();
+ this->Render(1, 1, xi, yi);
+
+ return 0;
+}
+
+int cmCursesMainForm::Generate()
+{
+ int xi,yi;
+ getmaxyx(stdscr, yi, xi);
+
+ curses_move(1,1);
+ this->UpdateStatusBar("Generating, please wait...");
+ this->PrintKeys(1);
+ touchwin(stdscr);
+ refresh();
+ this->CMakeInstance->SetProgressCallback(cmCursesMainForm::UpdateProgress, this);
+
+ // Get rid of previous errors
+ this->Errors = std::vector<std::string>();
+
+ // run the generate process
+ int retVal = this->CMakeInstance->Generate();
+
+ this->CMakeInstance->SetProgressCallback(0, 0);
+ keypad(stdscr,TRUE); /* Use key symbols as
+ KEY_DOWN*/
+
+ if( retVal != 0 || !this->Errors.empty())
+ {
+ // see if there was an error
+ if(cmSystemTools::GetErrorOccuredFlag())
+ {
+ this->OkToGenerate = false;
+ }
+ // reset error condition
+ cmSystemTools::ResetErrorOccuredFlag();
+ int xx,yy;
+ getmaxyx(stdscr, yy, xx);
+ const char* title = "Messages during last pass.";
+ if(cmSystemTools::GetErrorOccuredFlag())
+ {
+ title = "Errors occurred during the last pass.";
+ }
+ cmCursesLongMessageForm* msgs = new cmCursesLongMessageForm(this->Errors,
+ title);
+ CurrentForm = msgs;
+ msgs->Render(1,1,xx,yy);
+ msgs->HandleInput();
+ // If they typed the wrong source directory, we report
+ // an error and exit
+ if ( retVal == -2 )
+ {
+ return retVal;
+ }
+ CurrentForm = this;
+ this->Render(1,1,xx,yy);
+ }
+
+ this->InitializeUI();
+ this->Render(1, 1, xi, yi);
+
+ return 0;
+}
+
+void cmCursesMainForm::AddError(const char* message, const char*)
+{
+ this->Errors.push_back(message);
+}
+
+void cmCursesMainForm::RemoveEntry(const char* value)
+{
+ if (!value)
+ {
+ return;
+ }
+
+ std::vector<cmCursesCacheEntryComposite*>::iterator it;
+ for (it = this->Entries->begin(); it != this->Entries->end(); ++it)
+ {
+ const char* val = (*it)->GetValue();
+ if ( val && !strcmp(value, val) )
+ {
+ this->CMakeInstance->UnwatchUnusedCli(value);
+ this->Entries->erase(it);
+ break;
+ }
+ }
+}
+
+// copy from the list box to the cache manager
+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 oldValue = it.GetValue();
+ 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);
+
+ if(!(fixedOldValue == fixedNewValue))
+ {
+ // The user has changed the value. Mark it as modified.
+ it.SetProperty("MODIFIED", true);
+ it.SetValue(fixedNewValue.c_str());
+ }
+ }
+ }
+}
+
+void cmCursesMainForm::FixValue(cmCacheManager::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)
+ {
+ cmSystemTools::ConvertToUnixSlashes(out);
+ }
+ if(type == cmCacheManager::BOOL)
+ {
+ if(cmSystemTools::IsOff(out.c_str()))
+ {
+ out = "OFF";
+ }
+ else
+ {
+ out = "ON";
+ }
+ }
+}
+
+#include <unistd.h>
+
+void cmCursesMainForm::HandleInput()
+{
+ int x=0,y=0;
+
+ if (!this->Form)
+ {
+ return;
+ }
+
+ FIELD* currentField;
+ cmCursesWidget* currentWidget;
+
+ char debugMessage[128];
+
+ for(;;)
+ {
+ this->UpdateStatusBar();
+ this->PrintKeys();
+ if ( this->SearchMode )
+ {
+ std::string searchstr = "Search: " + this->SearchString;
+ this->UpdateStatusBar( searchstr.c_str() );
+ this->PrintKeys(1);
+ curses_move(y-5,static_cast<unsigned int>(searchstr.size()));
+ //curses_move(1,1);
+ touchwin(stdscr);
+ refresh();
+ }
+ int key = getch();
+
+ getmaxyx(stdscr, y, x);
+ // If window too small, handle 'q' only
+ if ( x < cmCursesMainForm::MIN_WIDTH ||
+ y < cmCursesMainForm::MIN_HEIGHT )
+ {
+ // quit
+ if ( key == 'q' )
+ {
+ break;
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ currentField = current_field(this->Form);
+ currentWidget = reinterpret_cast<cmCursesWidget*>(field_userptr(
+ currentField));
+
+ bool widgetHandled=false;
+
+ if ( this->SearchMode )
+ {
+ if ( key == 10 || key == KEY_ENTER )
+ {
+ this->SearchMode = false;
+ if ( this->SearchString.size() > 0 )
+ {
+ this->JumpToCacheEntry(this->SearchString.c_str());
+ this->OldSearchString = this->SearchString;
+ }
+ this->SearchString = "";
+ }
+ /*
+ else if ( key == KEY_ESCAPE )
+ {
+ this->SearchMode = false;
+ }
+ */
+ else if ((key >= 'a' && key <= 'z') ||
+ (key >= 'A' && key <= 'Z') ||
+ (key >= '0' && key <= '9') ||
+ (key == '_' ))
+ {
+ if ( this->SearchString.size() < static_cast<std::string::size_type>(x-10) )
+ {
+ this->SearchString += static_cast<char>(key);
+ }
+ }
+ else if ( key == ctrl('h') || key == KEY_BACKSPACE || key == KEY_DC )
+ {
+ if ( this->SearchString.size() > 0 )
+ {
+ this->SearchString.resize(this->SearchString.size()-1);
+ }
+ }
+ }
+ else if (currentWidget && !this->SearchMode)
+ {
+ // Ask the current widget if it wants to handle input
+ widgetHandled = currentWidget->HandleInput(key, this, stdscr);
+ if (widgetHandled)
+ {
+ this->OkToGenerate = false;
+ this->UpdateStatusBar();
+ this->PrintKeys();
+ }
+ }
+ if ((!currentWidget || !widgetHandled) && !this->SearchMode)
+ {
+ // If the current widget does not want to handle input,
+ // we handle it.
+ sprintf(debugMessage, "Main form handling input, key: %d", key);
+ cmCursesForm::LogMessage(debugMessage);
+ // quit
+ if ( key == 'q' )
+ {
+ break;
+ }
+ // if not end of page, next field otherwise next page
+ // each entry consists of fields: label, isnew, value
+ // therefore, the label field for the prev. entry is index-5
+ // and the label field for the next entry is index+1
+ // (index always corresponds to the value field)
+ else if ( key == KEY_DOWN || key == ctrl('n') )
+ {
+ FIELD* cur = current_field(this->Form);
+ size_t findex = field_index(cur);
+ if ( findex == 3*this->NumberOfVisibleEntries-1 )
+ {
+ continue;
+ }
+ if (new_page(this->Fields[findex+1]))
+ {
+ form_driver(this->Form, REQ_NEXT_PAGE);
+ }
+ else
+ {
+ form_driver(this->Form, REQ_NEXT_FIELD);
+ }
+ }
+ // if not beginning of page, previous field, otherwise previous page
+ // each entry consists of fields: label, isnew, value
+ // therefore, the label field for the prev. entry is index-5
+ // and the label field for the next entry is index+1
+ // (index always corresponds to the value field)
+ else if ( key == KEY_UP || key == ctrl('p') )
+ {
+ FIELD* cur = current_field(this->Form);
+ int findex = field_index(cur);
+ if ( findex == 2 )
+ {
+ continue;
+ }
+ if ( new_page(this->Fields[findex-2]) )
+ {
+ form_driver(this->Form, REQ_PREV_PAGE);
+ set_current_field(this->Form, this->Fields[findex-3]);
+ }
+ else
+ {
+ form_driver(this->Form, REQ_PREV_FIELD);
+ }
+ }
+ // pg down
+ else if ( key == KEY_NPAGE || key == ctrl('d') )
+ {
+ form_driver(this->Form, REQ_NEXT_PAGE);
+ }
+ // pg up
+ else if ( key == KEY_PPAGE || key == ctrl('u') )
+ {
+ form_driver(this->Form, REQ_PREV_PAGE);
+ }
+ // configure
+ else if ( key == 'c' )
+ {
+ this->Configure();
+ }
+ // display help
+ else if ( key == 'h' )
+ {
+ getmaxyx(stdscr, y, x);
+
+ FIELD* cur = current_field(this->Form);
+ int findex = field_index(cur);
+ 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())
+ {
+ helpString = it.GetProperty("HELPSTRING");
+ }
+ if (helpString)
+ {
+ char* message = new char[strlen(curField)+strlen(helpString)
+ +strlen("Current option is: \n Help string for this option is: \n")+10];
+ sprintf(message,"Current option is: %s\nHelp string for this option is: %s\n", curField, helpString);
+ this->HelpMessage[1] = message;
+ delete[] message;
+ }
+ else
+ {
+ this->HelpMessage[1] = "";
+ }
+
+ cmCursesLongMessageForm* msgs = new cmCursesLongMessageForm(this->HelpMessage,
+ "Help.");
+ CurrentForm = msgs;
+ msgs->Render(1,1,x,y);
+ msgs->HandleInput();
+ CurrentForm = this;
+ this->Render(1,1,x,y);
+ set_current_field(this->Form, cur);
+ }
+ // display last errors
+ else if ( key == 'l' )
+ {
+ getmaxyx(stdscr, y, x);
+ cmCursesLongMessageForm* msgs = new cmCursesLongMessageForm(this->Errors,
+ "Errors occurred during the last pass.");
+ CurrentForm = msgs;
+ msgs->Render(1,1,x,y);
+ msgs->HandleInput();
+ CurrentForm = this;
+ this->Render(1,1,x,y);
+ }
+ else if ( key == '/' )
+ {
+ this->SearchMode = true;
+ this->UpdateStatusBar("Search");
+ this->PrintKeys(1);
+ touchwin(stdscr);
+ refresh();
+ }
+ else if ( key == 'n' )
+ {
+ if ( this->OldSearchString.size() > 0 )
+ {
+ this->JumpToCacheEntry(this->OldSearchString.c_str());
+ }
+ }
+ // switch advanced on/off
+ else if ( key == 't' )
+ {
+ if (this->AdvancedMode)
+ {
+ this->AdvancedMode = false;
+ }
+ else
+ {
+ this->AdvancedMode = true;
+ }
+ getmaxyx(stdscr, y, x);
+ this->RePost();
+ this->Render(1, 1, x, y);
+ }
+ // generate and exit
+ else if ( key == 'g' )
+ {
+ if ( this->OkToGenerate )
+ {
+ this->Generate();
+ break;
+ }
+ }
+ // delete cache entry
+ else if ( key == 'd' && this->NumberOfVisibleEntries )
+ {
+ this->OkToGenerate = false;
+ FIELD* cur = current_field(this->Form);
+ size_t findex = field_index(cur);
+
+ // make the next or prev. current field after deletion
+ // each entry consists of fields: label, isnew, value
+ // therefore, the label field for the prev. entry is findex-5
+ // and the label field for the next entry is findex+1
+ // (findex always corresponds to the value field)
+ FIELD* nextCur;
+ if ( findex == 2 )
+ {
+ nextCur=0;
+ }
+ else if ( findex == 3*this->NumberOfVisibleEntries-1 )
+ {
+ nextCur = this->Fields[findex-5];
+ }
+ else
+ {
+ nextCur = this->Fields[findex+1];
+ }
+
+ // Get the label widget
+ // each entry consists of fields: label, isnew, value
+ // therefore, the label field for the is findex-2
+ // (findex always corresponds to the value field)
+ cmCursesWidget* lbl
+ = reinterpret_cast<cmCursesWidget*>(
+ field_userptr(this->Fields[findex-2]));
+ if ( lbl )
+ {
+ this->CMakeInstance->GetCacheManager()->RemoveCacheEntry(lbl->GetValue());
+
+ std::string nextVal;
+ if (nextCur)
+ {
+ nextVal = (reinterpret_cast<cmCursesWidget*>(field_userptr(nextCur))->GetValue());
+ }
+
+ getmaxyx(stdscr, y, x);
+ this->RemoveEntry(lbl->GetValue());
+ this->RePost();
+ this->Render(1, 1, x, y);
+
+ if (nextCur)
+ {
+ // make the next or prev. current field after deletion
+ nextCur = 0;
+ std::vector<cmCursesCacheEntryComposite*>::iterator it;
+ for (it = this->Entries->begin(); it != this->Entries->end(); ++it)
+ {
+ if (nextVal == (*it)->Key)
+ {
+ nextCur = (*it)->Entry->Field;
+ }
+ }
+
+ if (nextCur)
+ {
+ set_current_field(this->Form, nextCur);
+ }
+ }
+ }
+ }
+ }
+
+ touchwin(stdscr);
+ wrefresh(stdscr);
+ }
+}
+
+int cmCursesMainForm::LoadCache(const char *)
+
+{
+ int r = this->CMakeInstance->LoadCache();
+ if(r < 0)
+ {
+ return r;
+ }
+ this->CMakeInstance->SetCacheArgs(this->Args);
+ this->CMakeInstance->PreLoadCMakeFiles();
+ return r;
+}
+
+void cmCursesMainForm::JumpToCacheEntry(const char* astr)
+{
+ std::string str;
+ if ( astr )
+ {
+ str = cmSystemTools::LowerCase(astr);
+ }
+
+ if(str.empty())
+ {
+ return;
+ }
+ FIELD* cur = current_field(this->Form);
+ int start_index = field_index(cur);
+ int findex = start_index;
+ for(;;)
+ {
+ if ( str.size() > 0 )
+ {
+ cmCursesWidget* lbl = 0;
+ if ( findex >= 0 )
+ {
+ lbl = reinterpret_cast<cmCursesWidget*>(field_userptr(this->Fields[findex-2]));
+ }
+ if ( lbl )
+ {
+ const char* curField = lbl->GetValue();
+ if ( curField )
+ {
+ std::string cfld = cmSystemTools::LowerCase(curField);
+ if ( cfld.find(str) != cfld.npos && findex != start_index )
+ {
+ break;
+ }
+ }
+ }
+ }
+ if ( size_t(findex) >= 3* this->NumberOfVisibleEntries-1 )
+ {
+ set_current_field(this->Form, this->Fields[2]);
+ }
+ else if (new_page(this->Fields[findex+1]))
+ {
+ form_driver(this->Form, REQ_NEXT_PAGE);
+ }
+ else
+ {
+ form_driver(this->Form, REQ_NEXT_FIELD);
+ }
+ /*
+ char buffer[1024];
+ sprintf(buffer, "Line: %d != %d / %d\n", findex, idx, this->NumberOfVisibleEntries);
+ touchwin(stdscr);
+ refresh();
+ this->UpdateStatusBar( buffer );
+ usleep(100000);
+ */
+ cur = current_field(this->Form);
+ findex = field_index(cur);
+ if ( findex == start_index )
+ {
+ break;
+ }
+ }
+}
+
+
+const char* cmCursesMainForm::s_ConstHelpMessage =
+"CMake is used to configure and generate build files for software projects. "
+"The basic steps for configuring a project with ccmake are as follows:\n\n"
+"1. Run ccmake in the directory where you want the object and executable files to be placed (build directory). If the source directory is not the same as this build directory, you have to specify it as an argument on the command line.\n\n"
+"2. When ccmake is run, it will read the configuration files and display the current build options. "
+"If you have run CMake before and have updated the configuration files since then, any new entries will be displayed on top and will be marked with a *. "
+"On the other hand, the first time you run ccmake, all build options will be new and will be marked as such. "
+"At this point, you can modify any options (see keys below) you want to change. "
+"When you are satisfied with your changes, press 'c' to have CMake process the configuration files. "
+"Please note that changing some options may cause new ones to appear. These will be shown on top and will be marked with *. "
+"Repeat this procedure until you are satisfied with all the options and there are no new entries. "
+"At this point, a new command will appear: G)enerate and Exit. You can now hit 'g' to have CMake generate all the build files (i.e. makefiles or project files) and exit. "
+"At any point during the process, you can exit ccmake with 'q'. However, this will not generate/change any build files.\n\n"
+"ccmake KEYS:\n\n"
+"Navigation: "
+"You can use the arrow keys and page up, down to navigate the options. Alternatively, you can use the following keys: \n"
+" C-n : next option\n"
+" C-p : previous options\n"
+" C-d : down one page\n"
+" C-u : up one page\n\n"
+"Editing options: "
+"To change an option press enter or return. If the current options is a boolean, this will toggle it's value. "
+"Otherwise, ccmake will enter edit mode. In this mode you can edit an option using arrow keys and backspace. Alternatively, you can use the following keys:\n"
+" C-b : back one character\n"
+" C-f : forward one character\n"
+" C-a : go to the beginning of the field\n"
+" C-e : go to the end of the field\n"
+" C-d : delete previous character\n"
+" C-k : kill the rest of the field\n"
+" Esc : Restore field (discard last changes)\n"
+" Enter : Leave edit mode\n"
+"You can also delete an option by pressing 'd'\n\n"
+"Commands:\n"
+" q : quit ccmake without generating build files\n"
+" h : help, shows this screen\n"
+" c : process the configuration files with the current options\n"
+" g : generate build files and exit, only available when there are no "
+"new options and no errors have been detected during last configuration.\n"
+" l : shows last errors\n"
+" t : toggles advanced mode. In normal mode, only the most important options are shown. In advanced mode, all options are shown. We recommend using normal mode unless you are an expert.\n"
+" / : search for a variable name.\n";
diff --git a/Source/CursesDialog/cmCursesMainForm.h b/Source/CursesDialog/cmCursesMainForm.h
new file mode 100644
index 000000000..3e191b497
--- /dev/null
+++ b/Source/CursesDialog/cmCursesMainForm.h
@@ -0,0 +1,164 @@
+/*============================================================================
+ 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 __cmCursesMainForm_h
+#define __cmCursesMainForm_h
+
+#include "../cmStandardIncludes.h"
+#include "cmCursesForm.h"
+#include "cmCursesStandardIncludes.h"
+
+class cmCursesCacheEntryComposite;
+class cmCursesWidget;
+class cmake;
+
+/** \class cmCursesMainForm
+ * \brief The main page of ccmake
+ *
+ * cmCursesMainForm is the main page of ccmake.
+ */
+class cmCursesMainForm : public cmCursesForm
+{
+public:
+ cmCursesMainForm(std::vector<std::string> const& args, int initwidth);
+ virtual ~cmCursesMainForm();
+
+ /**
+ * Set the widgets which represent the cache entries.
+ */
+ void InitializeUI();
+
+ /**
+ * Handle user input.
+ */
+ virtual void HandleInput();
+
+ /**
+ * Display form. Use a window of size width x height, starting
+ * at top, left.
+ */
+ virtual void Render(int left, int top, int width, int height);
+
+ /**
+ * Returns true if an entry with the given key is in the
+ * list of current composites.
+ */
+ bool LookForCacheEntry(const char* key);
+
+ enum {
+ MIN_WIDTH = 65,
+ MIN_HEIGHT = 6,
+ IDEAL_WIDTH = 80,
+ MAX_WIDTH = 512
+ };
+
+ /**
+ * This method should normally be called only by the form. The only
+ * exception is during a resize. The optional argument specifies the
+ * string to be displayed in the status bar.
+ */
+ virtual void UpdateStatusBar() { this->UpdateStatusBar(0); }
+ virtual void UpdateStatusBar(const char* message);
+
+ /**
+ * Display current commands and their keys on the toolbar. This
+ * method should normally called only by the form. The only
+ * exception is during a resize. If the optional argument process is
+ * specified and is either 1 (configure) or 2 (generate), then keys
+ * will be displayed accordingly.
+ */
+ void PrintKeys(int process = 0);
+
+ /**
+ * During a CMake run, an error handle should add errors
+ * to be displayed afterwards.
+ */
+ virtual void AddError(const char* message, const char* title);
+
+ /**
+ * Used to do a configure. If argument is specified, it does only the check
+ * and not configure.
+ */
+ int Configure(int noconfigure=0);
+
+ /**
+ * Used to generate
+ */
+ int Generate();
+
+ /**
+ * Used by main program
+ */
+ int LoadCache(const char *dir);
+
+ /**
+ * Progress callback
+ */
+ static void UpdateProgressOld(const char *msg, float prog, void*);
+ static void UpdateProgress(const char *msg, float prog, void*);
+
+protected:
+ cmCursesMainForm(const cmCursesMainForm& from);
+ void operator=(const cmCursesMainForm&);
+
+ // Copy the cache values from the user interface to the actual
+ // cache.
+ void FillCacheManagerFromUI();
+ // Fix formatting of values to a consistent form.
+ void FixValue(cmCacheManager::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
+ // afterwards.
+ void RePost();
+ // Remove an entry from the interface and the cache.
+ void RemoveEntry(const char* value);
+
+ // Jump to the cache entry whose name matches the string.
+ void JumpToCacheEntry(const char* str);
+
+ // Copies of cache entries stored in the user interface
+ std::vector<cmCursesCacheEntryComposite*>* Entries;
+ // Errors produced during last run of cmake
+ std::vector<std::string> Errors;
+ // Command line argumens to be passed to cmake each time
+ // it is run
+ std::vector<std::string> Args;
+ // Message displayed when user presses 'h'
+ // It is: Welcome + info about current entry + common help
+ std::vector<std::string> HelpMessage;
+
+ // Common help
+ static const char* s_ConstHelpMessage;
+
+ // Fields displayed. Includes labels, new entry markers, entries
+ FIELD** Fields;
+ // Where is source of current project
+ std::string WhereSource;
+ // Where is cmake executable
+ std::string WhereCMake;
+ // Number of entries shown (depends on mode -normal or advanced-)
+ size_t NumberOfVisibleEntries;
+ bool AdvancedMode;
+ // Did the iteration converge (no new entries) ?
+ bool OkToGenerate;
+ // Number of pages displayed
+ int NumberOfPages;
+
+ int InitialWidth;
+ cmake *CMakeInstance;
+
+ std::string SearchString;
+ std::string OldSearchString;
+ bool SearchMode;
+};
+
+#endif // __cmCursesMainForm_h
diff --git a/Source/CursesDialog/cmCursesPathWidget.cxx b/Source/CursesDialog/cmCursesPathWidget.cxx
new file mode 100644
index 000000000..b113c2e6a
--- /dev/null
+++ b/Source/CursesDialog/cmCursesPathWidget.cxx
@@ -0,0 +1,94 @@
+/*============================================================================
+ 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 "cmCursesPathWidget.h"
+
+#include "cmCursesMainForm.h"
+#include "cmSystemTools.h"
+
+cmCursesPathWidget::cmCursesPathWidget(int width, int height,
+ int left, int top) :
+ cmCursesStringWidget(width, height, left, top)
+{
+ this->Type = cmCacheManager::PATH;
+ this->Cycle = false;
+ this->CurrentIndex = 0;
+}
+
+void cmCursesPathWidget::OnType(int& key, cmCursesMainForm* fm, WINDOW* w)
+{
+ this->Cycle = false;
+ this->CurrentIndex = 0;
+ this->LastGlob = "";
+ this->cmCursesStringWidget::OnType(key, fm, w);
+}
+
+void cmCursesPathWidget::OnTab(cmCursesMainForm* fm, WINDOW* w)
+{
+ if ( !this->GetString() )
+ {
+ return;
+ }
+ FORM* form = fm->GetForm();
+ form_driver(form, REQ_NEXT_FIELD);
+ form_driver(form, REQ_PREV_FIELD);
+ std::string cstr = this->GetString();
+ cstr = cstr.substr(0, cstr.find_last_not_of(" \t\n\r")+1);
+ if ( this->LastString != cstr )
+ {
+ this->Cycle = false;
+ this->CurrentIndex = 0;
+ this->LastGlob = "";
+ }
+ std::string glob;
+ if ( this->Cycle )
+ {
+ glob = this->LastGlob;
+ }
+ else
+ {
+ glob = cstr + "*";
+ }
+ std::vector<cmStdString> dirs;
+
+ cmSystemTools::SimpleGlob(glob.c_str(), dirs, (this->Type == cmCacheManager::PATH?-1:0));
+ if ( this->CurrentIndex < dirs.size() )
+ {
+ cstr = dirs[this->CurrentIndex];
+ }
+ if ( cstr[cstr.size()-1] == '*' )
+ {
+ cstr = cstr.substr(0, cstr.size()-1);
+ }
+
+ if ( cmSystemTools::FileIsDirectory(cstr.c_str()) )
+ {
+ cstr += "/";
+ }
+
+ this->SetString(cstr.c_str());
+ touchwin(w);
+ wrefresh(w);
+ form_driver(form, REQ_END_FIELD);
+ this->LastGlob = glob;
+ this->LastString = cstr;
+ this->Cycle = true;
+ this->CurrentIndex ++;
+ if ( this->CurrentIndex >= dirs.size() )
+ {
+ this->CurrentIndex = 0;
+ }
+}
+
+void cmCursesPathWidget::OnReturn(cmCursesMainForm* fm, WINDOW* w)
+{
+ this->cmCursesStringWidget::OnReturn(fm, w);
+}
diff --git a/Source/CursesDialog/cmCursesPathWidget.h b/Source/CursesDialog/cmCursesPathWidget.h
new file mode 100644
index 000000000..45c22a392
--- /dev/null
+++ b/Source/CursesDialog/cmCursesPathWidget.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 __cmCursesPathWidget_h
+#define __cmCursesPathWidget_h
+
+#include "cmCursesStringWidget.h"
+
+class cmCursesPathWidget : public cmCursesStringWidget
+{
+public:
+ cmCursesPathWidget(int width, int height, int left, int top);
+
+ /**
+ * This method is called when different keys are pressed. The
+ * subclass can have a special implementation handler for this.
+ */
+ virtual void OnTab(cmCursesMainForm* fm, WINDOW* w);
+ virtual void OnReturn(cmCursesMainForm* fm, WINDOW* w);
+ virtual void OnType(int& key, cmCursesMainForm* fm, WINDOW* w);
+
+protected:
+ cmCursesPathWidget(const cmCursesPathWidget& from);
+ void operator=(const cmCursesPathWidget&);
+
+ std::string LastString;
+ std::string LastGlob;
+ bool Cycle;
+ std::string::size_type CurrentIndex;
+};
+
+#endif // __cmCursesPathWidget_h
diff --git a/Source/CursesDialog/cmCursesStandardIncludes.h b/Source/CursesDialog/cmCursesStandardIncludes.h
new file mode 100644
index 000000000..b157a289b
--- /dev/null
+++ b/Source/CursesDialog/cmCursesStandardIncludes.h
@@ -0,0 +1,83 @@
+/*============================================================================
+ 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 cmCursesStandardIncludes_h
+#define cmCursesStandardIncludes_h
+#if defined(__sun__) && defined(__GNUC__)
+ #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
+
+
+// on some machines move erase and clear conflict with stl
+// so remove them from the namespace
+inline void curses_move(unsigned int x, unsigned int y)
+{
+ move(x,y);
+}
+
+inline void curses_clear()
+{
+ erase();
+ clearok(stdscr, TRUE);
+}
+
+#undef move
+#undef erase
+#undef clear
+
+
+#endif // cmCursesStandardIncludes_h
diff --git a/Source/CursesDialog/cmCursesStringWidget.cxx b/Source/CursesDialog/cmCursesStringWidget.cxx
new file mode 100644
index 000000000..d363f0090
--- /dev/null
+++ b/Source/CursesDialog/cmCursesStringWidget.cxx
@@ -0,0 +1,249 @@
+/*============================================================================
+ 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 "cmCursesStringWidget.h"
+#include "cmCursesMainForm.h"
+
+inline int ctrl(int z)
+{
+ return (z&037);
+}
+
+cmCursesStringWidget::cmCursesStringWidget(int width, int height,
+ int left, int top) :
+ cmCursesWidget(width, height, left, top)
+{
+ this->InEdit = false;
+ this->Type = cmCacheManager::STRING;
+ set_field_fore(this->Field, A_NORMAL);
+ set_field_back(this->Field, A_STANDOUT);
+ field_opts_off(this->Field, O_STATIC);
+}
+
+void cmCursesStringWidget::OnTab(cmCursesMainForm*, WINDOW*)
+{
+ //FORM* form = fm->GetForm();
+}
+
+void cmCursesStringWidget::OnReturn(cmCursesMainForm* fm, WINDOW*)
+{
+ FORM* form = fm->GetForm();
+ if (this->InEdit)
+ {
+ cmCursesForm::LogMessage("String widget leaving edit.");
+ this->InEdit = false;
+ fm->PrintKeys();
+ delete[] this->OriginalString;
+ // trick to force forms to update the field buffer
+ form_driver(form, REQ_NEXT_FIELD);
+ form_driver(form, REQ_PREV_FIELD);
+ this->Done = true;
+ }
+ else
+ {
+ cmCursesForm::LogMessage("String widget entering edit.");
+ this->InEdit = true;
+ fm->PrintKeys();
+ char* buf = field_buffer(this->Field, 0);
+ this->OriginalString = new char[strlen(buf)+1];
+ strcpy(this->OriginalString, buf);
+ }
+}
+
+void cmCursesStringWidget::OnType(int& key, cmCursesMainForm* fm, WINDOW*)
+{
+ form_driver(fm->GetForm(), key);
+}
+
+bool cmCursesStringWidget::HandleInput(int& key, cmCursesMainForm* fm,
+ WINDOW* w)
+{
+ int x,y;
+
+ FORM* form = fm->GetForm();
+ // 10 == enter
+ if (!this->InEdit && ( key != 10 && key != KEY_ENTER ) )
+ {
+ return false;
+ }
+
+ this->OriginalString=0;
+ this->Done = false;
+
+ char debugMessage[128];
+
+ // <Enter> is used to change edit mode (like <Esc> in vi).
+ while(!this->Done)
+ {
+ sprintf(debugMessage, "String widget handling input, key: %d", key);
+ cmCursesForm::LogMessage(debugMessage);
+
+ fm->PrintKeys();
+
+ getmaxyx(stdscr, y, x);
+ // If window too small, handle 'q' only
+ if ( x < cmCursesMainForm::MIN_WIDTH ||
+ y < cmCursesMainForm::MIN_HEIGHT )
+ {
+ // quit
+ if ( key == 'q' )
+ {
+ return false;
+ }
+ else
+ {
+ key=getch();
+ continue;
+ }
+ }
+
+ // If resize occured during edit, move out of edit mode
+ if (!this->InEdit && ( key != 10 && key != KEY_ENTER ) )
+ {
+ return false;
+ }
+ // 10 == enter
+ if (key == 10 || key == KEY_ENTER)
+ {
+ this->OnReturn(fm, w);
+ }
+ else if ( key == KEY_DOWN || key == ctrl('n') ||
+ key == KEY_UP || key == ctrl('p') ||
+ key == KEY_NPAGE || key == ctrl('d') ||
+ key == KEY_PPAGE || key == ctrl('u'))
+ {
+ this->InEdit = false;
+ delete[] this->OriginalString;
+ // trick to force forms to update the field buffer
+ form_driver(form, REQ_NEXT_FIELD);
+ form_driver(form, REQ_PREV_FIELD);
+ return false;
+ }
+ // esc
+ else if (key == 27)
+ {
+ if (this->InEdit)
+ {
+ this->InEdit = false;
+ fm->PrintKeys();
+ this->SetString(this->OriginalString);
+ delete[] this->OriginalString;
+ touchwin(w);
+ wrefresh(w);
+ return true;
+ }
+ }
+ else if ( key == 9 )
+ {
+ this->OnTab(fm, w);
+ }
+ else if ( key == KEY_LEFT || key == ctrl('b') )
+ {
+ form_driver(form, REQ_PREV_CHAR);
+ }
+ else if ( key == KEY_RIGHT || key == ctrl('f') )
+ {
+ form_driver(form, REQ_NEXT_CHAR);
+ }
+ else if ( key == ctrl('k') )
+ {
+ form_driver(form, REQ_CLR_EOL);
+ }
+ else if ( key == ctrl('a') || key == KEY_HOME )
+ {
+ form_driver(form, REQ_BEG_FIELD);
+ }
+ else if ( key == ctrl('e') || key == KEY_END )
+ {
+ form_driver(form, REQ_END_FIELD);
+ }
+ else if ( key == 127 ||
+ key == KEY_BACKSPACE )
+ {
+ if ( form->curcol > 0 )
+ {
+ form_driver(form, REQ_DEL_PREV);
+ }
+ }
+ else if ( key == ctrl('d') ||key == KEY_DC )
+ {
+ if ( form->curcol > 0 )
+ {
+ form_driver(form, REQ_DEL_CHAR);
+ }
+ }
+ else
+ {
+ this->OnType(key, fm, w);
+ }
+ if ( !this->Done )
+ {
+ touchwin(w);
+ wrefresh(w);
+
+ key=getch();
+ }
+ }
+ return true;
+}
+
+void cmCursesStringWidget::SetString(const char* value)
+{
+ this->SetValue(value);
+}
+
+const char* cmCursesStringWidget::GetString()
+{
+ return this->GetValue();
+}
+
+const char* cmCursesStringWidget::GetValue()
+{
+ return field_buffer(this->Field, 0);
+}
+
+bool cmCursesStringWidget::PrintKeys()
+{
+ int x,y;
+ getmaxyx(stdscr, y, x);
+ if ( x < cmCursesMainForm::MIN_WIDTH ||
+ y < cmCursesMainForm::MIN_HEIGHT )
+ {
+ return false;
+ }
+ if (this->InEdit)
+ {
+ char firstLine[512];
+ // Clean the toolbar
+ for(int i=0; i<512; i++)
+ {
+ firstLine[i] = ' ';
+ }
+ firstLine[511] = '\0';
+ curses_move(y-4,0);
+ printw(firstLine);
+ curses_move(y-3,0);
+ printw(firstLine);
+ curses_move(y-2,0);
+ printw(firstLine);
+ curses_move(y-1,0);
+ printw(firstLine);
+
+ sprintf(firstLine, "Editing option, press [enter] to leave edit.");
+ curses_move(y-3,0);
+ printw(firstLine);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
diff --git a/Source/CursesDialog/cmCursesStringWidget.h b/Source/CursesDialog/cmCursesStringWidget.h
new file mode 100644
index 000000000..cd54f249b
--- /dev/null
+++ b/Source/CursesDialog/cmCursesStringWidget.h
@@ -0,0 +1,76 @@
+/*============================================================================
+ 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 __cmCursesStringWidget_h
+#define __cmCursesStringWidget_h
+
+#include "cmCursesWidget.h"
+
+class cmCursesMainForm;
+
+/** \class cmCursesStringWidget
+ * \brief A simple entry widget.
+ *
+ * cmCursesStringWdiget is a simple text entry widget.
+ */
+
+class cmCursesStringWidget : public cmCursesWidget
+{
+public:
+ cmCursesStringWidget(int width, int height, int left, int top);
+
+ /**
+ * 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);
+
+ /**
+ * Set/Get the string.
+ */
+ void SetString(const char* value);
+ const char* GetString();
+ virtual const char* GetValue();
+
+ /**
+ * Set/Get InEdit flag. Can be used to tell the widget to leave
+ * edit mode (in case of a resize for example).
+ */
+ void SetInEdit(bool inedit) { this->InEdit = inedit; }
+ bool GetInEdit() { return this->InEdit; }
+
+ /**
+ * This method is called when different keys are pressed. The
+ * subclass can have a special implementation handler for this.
+ */
+ virtual void OnTab(cmCursesMainForm* fm, WINDOW* w);
+ virtual void OnReturn(cmCursesMainForm* fm, WINDOW* w);
+ virtual void OnType(int& key, cmCursesMainForm* fm, WINDOW* w);
+
+ /**
+ * If there are any, print the widget specific commands
+ * in the toolbar and return true. Otherwise, return false
+ * and the parent widget will print.
+ */
+ virtual bool PrintKeys();
+
+protected:
+ cmCursesStringWidget(const cmCursesStringWidget& from);
+ void operator=(const cmCursesStringWidget&);
+
+ // true if the widget is in edit mode
+ bool InEdit;
+ char* OriginalString;
+ bool Done;
+};
+
+#endif // __cmCursesStringWidget_h
diff --git a/Source/CursesDialog/cmCursesWidget.cxx b/Source/CursesDialog/cmCursesWidget.cxx
new file mode 100644
index 000000000..5dffcaa5c
--- /dev/null
+++ b/Source/CursesDialog/cmCursesWidget.cxx
@@ -0,0 +1,58 @@
+/*============================================================================
+ 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 "cmCursesWidget.h"
+
+cmCursesWidget::cmCursesWidget(int width, int height, int left, int top)
+{
+ this->Field = new_field(height, width, top, left, 0, 0);
+ set_field_userptr(this->Field, reinterpret_cast<char*>(this));
+ field_opts_off(this->Field, O_AUTOSKIP);
+ this->Page = 0;
+}
+
+cmCursesWidget::~cmCursesWidget()
+{
+ if (this->Field)
+ {
+ free_field(this->Field);
+ this->Field = 0;
+ }
+}
+
+void cmCursesWidget::Move(int x, int y, bool isNewPage)
+{
+ if (!this->Field)
+ {
+ return;
+ }
+
+ move_field(this->Field, y, x);
+ if (isNewPage)
+ {
+ set_new_page(this->Field, TRUE);
+ }
+ else
+ {
+ set_new_page(this->Field, FALSE);
+ }
+}
+
+void cmCursesWidget::SetValue(const char* value)
+{
+ this->Value = value;
+ set_field_buffer(this->Field, 0, value);
+}
+
+const char* cmCursesWidget::GetValue()
+{
+ return this->Value.c_str();
+}
diff --git a/Source/CursesDialog/cmCursesWidget.h b/Source/CursesDialog/cmCursesWidget.h
new file mode 100644
index 000000000..ee36af613
--- /dev/null
+++ b/Source/CursesDialog/cmCursesWidget.h
@@ -0,0 +1,87 @@
+/*============================================================================
+ 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 __cmCursesWidget_h
+#define __cmCursesWidget_h
+
+#include "../cmCacheManager.h"
+#include "cmCursesStandardIncludes.h"
+
+class cmCursesMainForm;
+
+class cmCursesWidget
+{
+public:
+ cmCursesWidget(int width, int height, int left, int top);
+ virtual ~cmCursesWidget();
+
+ /**
+ * 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) = 0;
+
+ /**
+ * Change the position of the widget. Set isNewPage to true
+ * if this widget marks the beginning of a new page.
+ */
+ virtual void Move(int x, int y, bool isNewPage);
+
+ /**
+ * Set/Get the value (setting the value also changes the contents
+ * of the field buffer).
+ */
+ virtual void SetValue(const char* value);
+ virtual const char* GetValue();
+
+ /**
+ * Get the type of the widget (STRING, PATH etc...)
+ */
+ cmCacheManager::CacheEntryType GetType()
+ { return this->Type; }
+
+ /**
+ * If there are any, print the widget specific commands
+ * in the toolbar and return true. Otherwise, return false
+ * and the parent widget will print.
+ */
+ virtual bool PrintKeys()
+ {
+ return false;
+ }
+
+ /**
+ * Set/Get the page this widget is in.
+ */
+ void SetPage(int page)
+ {
+ this->Page = page;
+ }
+ int GetPage()
+ {
+ return this->Page;
+ }
+
+ friend class cmCursesMainForm;
+
+protected:
+ cmCursesWidget(const cmCursesWidget& from);
+ void operator=(const cmCursesWidget&);
+
+ cmCacheManager::CacheEntryType Type;
+ std::string Value;
+ FIELD* Field;
+ // The page in the main form this widget is in
+ int Page;
+};
+
+#endif // __cmCursesWidget_h
diff --git a/Source/CursesDialog/form/.NoDartCoverage b/Source/CursesDialog/form/.NoDartCoverage
new file mode 100644
index 000000000..3c9972938
--- /dev/null
+++ b/Source/CursesDialog/form/.NoDartCoverage
@@ -0,0 +1 @@
+# do not do coverage in this directory
diff --git a/Source/CursesDialog/form/CMakeLists.txt b/Source/CursesDialog/form/CMakeLists.txt
new file mode 100644
index 000000000..2435f3935
--- /dev/null
+++ b/Source/CursesDialog/form/CMakeLists.txt
@@ -0,0 +1,66 @@
+#=============================================================================
+# 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.
+#=============================================================================
+PROJECT(CMAKE_FORM)
+
+INCLUDE_REGULAR_EXPRESSION("^.*$")
+INCLUDE_DIRECTORIES(${CURSES_INCLUDE_PATH} "${CMAKE_CURRENT_BINARY_DIR}")
+
+CONFIGURE_FILE(cmFormConfigure.h.in "${CMAKE_CURRENT_BINARY_DIR}/cmFormConfigure.h")
+
+SET( FORM_SRCS
+ 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
+ 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
+ )
+
+INCLUDE_DIRECTORIES(${CMAKE_FORM_SOURCE_DIR})
+ADD_LIBRARY(cmForm ${FORM_SRCS} )
+TARGET_LINK_LIBRARIES(cmForm ${CURSES_LIBRARY})
+IF(CURSES_EXTRA_LIBRARY)
+ TARGET_LINK_LIBRARIES(cmForm ${CURSES_EXTRA_LIBRARY})
+ENDIF(CURSES_EXTRA_LIBRARY)
diff --git a/Source/CursesDialog/form/READ.ME b/Source/CursesDialog/form/READ.ME
new file mode 100644
index 000000000..dd91693f6
--- /dev/null
+++ b/Source/CursesDialog/form/READ.ME
@@ -0,0 +1,15 @@
+This is a clone of the form library that is available with typical
+System V curses implementations (ETI).
+
+It is modelled after the documentation that comes for this library with
+a 386 based SVR4 implementation (ESIX).
+
+The development environment was and is an ELF based Linux system.
+
+For things that still need doing, see the TO-DO file in the top-level
+directory.
+
+Juergen Pfeifer
+
+eMail: juergen.pfeifer@gmx.net
+
diff --git a/Source/CursesDialog/form/cmFormConfigure.h.in b/Source/CursesDialog/form/cmFormConfigure.h.in
new file mode 100644
index 000000000..a43169d03
--- /dev/null
+++ b/Source/CursesDialog/form/cmFormConfigure.h.in
@@ -0,0 +1,21 @@
+/*============================================================================
+ 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 CMFORMCONFIGURE_H
+#define CMFORMCONFIGURE_H
+
+#cmakedefine CURSES_HAVE_CURSES_H
+#cmakedefine CURSES_HAVE_NCURSES_H
+#cmakedefine CURSES_HAVE_NCURSES_NCURSES_H
+#cmakedefine CURSES_HAVE_NCURSES_CURSES_H
+
+#endif
diff --git a/Source/CursesDialog/form/eti.h b/Source/CursesDialog/form/eti.h
new file mode 100644
index 000000000..cc1c8308a
--- /dev/null
+++ b/Source/CursesDialog/form/eti.h
@@ -0,0 +1,52 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 ABOVE 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. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <juergen.pfeifer@gmx.net> 1995,1997 *
+ ****************************************************************************/
+
+#ifndef _ETI_ERRNO_H_
+#define _ETI_ERRNO_H_
+
+#define E_OK (0)
+#define E_SYSTEM_ERROR (-1)
+#define E_BAD_ARGUMENT (-2)
+#define E_POSTED (-3)
+#define E_CONNECTED (-4)
+#define E_BAD_STATE (-5)
+#define E_NO_ROOM (-6)
+#define E_NOT_POSTED (-7)
+#define E_UNKNOWN_COMMAND (-8)
+#define E_NO_MATCH (-9)
+#define E_NOT_SELECTABLE (-10)
+#define E_NOT_CONNECTED (-11)
+#define E_REQUEST_DENIED (-12)
+#define E_INVALID_FIELD (-13)
+#define E_CURRENT (-14)
+
+#endif
diff --git a/Source/CursesDialog/form/fld_arg.c b/Source/CursesDialog/form/fld_arg.c
new file mode 100644
index 000000000..91ad79f1a
--- /dev/null
+++ b/Source/CursesDialog/form/fld_arg.c
@@ -0,0 +1,91 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 ABOVE 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. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <juergen.pfeifer@gmx.net> 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id$")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_fieldtype_arg(
+| FIELDTYPE *typ,
+| void * (* const make_arg)(va_list *),
+| void * (* const copy_arg)(const void *),
+| void (* const free_arg)(void *) )
+|
+| Description : Connects to the type additional arguments necessary
+| for a set_field_type call. The various function pointer
+| arguments are:
+| make_arg : allocates a structure for the field
+| specific parameters.
+| copy_arg : duplicate the structure created by
+| make_arg
+| free_arg : Release the memory allocated by make_arg
+| or copy_arg
+|
+| At least make_arg must be non-NULL.
+| You may pass NULL for copy_arg and free_arg if your
+| make_arg function doesn't allocate memory and your
+| arg fits into the storage for a (void*).
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid argument
++--------------------------------------------------------------------------*/
+int set_fieldtype_arg(FIELDTYPE * typ,
+ void * (* const make_arg)(va_list *),
+ void * (* const copy_arg)(const void *),
+ void (* const free_arg)(void *))
+{
+ if ( !typ || !make_arg )
+ RETURN(E_BAD_ARGUMENT);
+
+ typ->status |= _HAS_ARGS;
+ typ->makearg = make_arg;
+ typ->copyarg = copy_arg;
+ typ->freearg = free_arg;
+ RETURN(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : void *field_arg(const FIELD *field)
+|
+| Description : Retrieve pointer to the fields argument structure.
+|
+| Return Values : Pointer to structure or NULL if none is defined.
++--------------------------------------------------------------------------*/
+void *field_arg(const FIELD * field)
+{
+ return Normalize_Field(field)->arg;
+}
+
+/* fld_arg.c ends here */
diff --git a/Source/CursesDialog/form/fld_attr.c b/Source/CursesDialog/form/fld_attr.c
new file mode 100644
index 000000000..86195882b
--- /dev/null
+++ b/Source/CursesDialog/form/fld_attr.c
@@ -0,0 +1,116 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 ABOVE 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. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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
+MODULE_ID("$Id$")
+
+/*----------------------------------------------------------------------------
+ Field-Attribute manipulation routines
+ --------------------------------------------------------------------------*/
+/* "Template" macro to generate a function to set a fields attribute */
+#define GEN_FIELD_ATTR_SET_FCT( name ) \
+int set_field_ ## name (FIELD * field, chtype attr)\
+{\
+ int res = E_BAD_ARGUMENT;\
+ if ( attr==A_NORMAL || ((attr & A_ATTRIBUTES)==attr) )\
+ {\
+ Normalize_Field( field );\
+ if ((field -> name) != attr)\
+ {\
+ field -> name = attr;\
+ res = _nc_Synchronize_Attributes( field );\
+ }\
+ else\
+ res = E_OK;\
+ }\
+ RETURN(res);\
+}
+
+/* "Template" macro to generate a function to get a fields attribute */
+#define GEN_FIELD_ATTR_GET_FCT( name ) \
+chtype field_ ## name (const FIELD * field)\
+{\
+ return ( A_ATTRIBUTES & (Normalize_Field( field ) -> name) );\
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_field_fore(FIELD *field, chtype attr)
+|
+| Description : Sets the foreground of the field used to display the
+| field contents.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid attributes
+| E_SYSTEM_ERROR - system error
++--------------------------------------------------------------------------*/
+GEN_FIELD_ATTR_SET_FCT( fore )
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : chtype field_fore(const FIELD *)
+|
+| Description : Retrieve fields foreground attribute
+|
+| Return Values : The foreground attribute
++--------------------------------------------------------------------------*/
+GEN_FIELD_ATTR_GET_FCT( fore )
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_field_back(FIELD *field, chtype attr)
+|
+| Description : Sets the background of the field used to display the
+| fields extend.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid attributes
+| E_SYSTEM_ERROR - system error
++--------------------------------------------------------------------------*/
+GEN_FIELD_ATTR_SET_FCT( back )
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : chtype field_back(const
+|
+| Description : Retrieve fields background attribute
+|
+| Return Values : The background attribute
++--------------------------------------------------------------------------*/
+GEN_FIELD_ATTR_GET_FCT( back )
+
+/* fld_attr.c ends here */
diff --git a/Source/CursesDialog/form/fld_current.c b/Source/CursesDialog/form/fld_current.c
new file mode 100644
index 000000000..d4b1254f7
--- /dev/null
+++ b/Source/CursesDialog/form/fld_current.c
@@ -0,0 +1,124 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 ABOVE 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. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <juergen.pfeifer@gmx.net> 1995,1997 *
+ ****************************************************************************/
+#include "form.priv.h"
+
+MODULE_ID("$Id$")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_current_field(FORM * form,FIELD * field)
+|
+| Description : Set the current field of the form to the specified one.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid form or field pointer
+| E_REQUEST_DENIED - field not selectable
+| E_BAD_STATE - called from a hook routine
+| E_INVALID_FIELD - current field can't be left
+| E_SYSTEM_ERROR - system error
++--------------------------------------------------------------------------*/
+int set_current_field(FORM * form, FIELD * field)
+{
+ int err = E_OK;
+
+ if ( !form || !field )
+ RETURN(E_BAD_ARGUMENT);
+
+ if ( (form != field->form) || Field_Is_Not_Selectable(field) )
+ RETURN(E_REQUEST_DENIED);
+
+ if (!(form->status & _POSTED))
+ {
+ form->current = field;
+ form->curpage = field->page;
+ }
+ else
+ {
+ if (form->status & _IN_DRIVER)
+ err = E_BAD_STATE;
+ else
+ {
+ if (form->current != field)
+ {
+ if (!_nc_Internal_Validation(form))
+ err = E_INVALID_FIELD;
+ else
+ {
+ Call_Hook(form,fieldterm);
+ if (field->page != form->curpage)
+ {
+ Call_Hook(form,formterm);
+ err = _nc_Set_Form_Page(form,field->page,field);
+ Call_Hook(form,forminit);
+ }
+ else
+ {
+ err = _nc_Set_Current_Field(form,field);
+ }
+ Call_Hook(form,fieldinit);
+ _nc_Refresh_Current_Field(form);
+ }
+ }
+ }
+ }
+ RETURN(err);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : FIELD *current_field(const FORM * form)
+|
+| Description : Return the current field.
+|
+| Return Values : Pointer to the current field.
++--------------------------------------------------------------------------*/
+FIELD *current_field(const FORM * form)
+{
+ return Normalize_Form(form)->current;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int field_index(const FIELD * field)
+|
+| Description : Return the index of the field in the field-array of
+| the form.
+|
+| Return Values : >= 0 : field index
+| -1 : fieldpointer invalid or field not connected
++--------------------------------------------------------------------------*/
+int field_index(const FIELD * field)
+{
+ return ( (field && field->form) ? field->index : -1 );
+}
+
+/* fld_current.c ends here */
diff --git a/Source/CursesDialog/form/fld_def.c b/Source/CursesDialog/form/fld_def.c
new file mode 100644
index 000000000..4a49a2558
--- /dev/null
+++ b/Source/CursesDialog/form/fld_def.c
@@ -0,0 +1,346 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 ABOVE 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. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <juergen.pfeifer@gmx.net> 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id$")
+
+/* this can't be readonly */
+static FIELD default_field = {
+ 0, /* status */
+ 0, /* rows */
+ 0, /* cols */
+ 0, /* frow */
+ 0, /* fcol */
+ 0, /* drows */
+ 0, /* dcols */
+ 0, /* maxgrow*/
+ 0, /* nrow */
+ 0, /* nbuf */
+ NO_JUSTIFICATION, /* just */
+ 0, /* page */
+ 0, /* index */
+ (int)' ', /* pad */
+ A_NORMAL, /* fore */
+ A_NORMAL, /* back */
+ ALL_FIELD_OPTS, /* opts */
+ (FIELD *)0, /* snext */
+ (FIELD *)0, /* sprev */
+ (FIELD *)0, /* link */
+ (FORM *)0, /* form */
+ (FIELDTYPE *)0, /* type */
+ (char *)0, /* arg */
+ (char *)0, /* buf */
+ (char *)0 /* usrptr */
+};
+
+FIELD *_nc_Default_Field = &default_field;
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : TypeArgument *_nc_Make_Argument(
+| const FIELDTYPE *typ,
+| va_list *ap,
+| int *err )
+|
+| Description : Create an argument structure for the specified type.
+| Use the type-dependant argument list to construct
+| it.
+|
+| Return Values : Pointer to argument structure. Maybe NULL.
+| In case of an error in *err an errorcounter is increased.
++--------------------------------------------------------------------------*/
+TypeArgument*
+_nc_Make_Argument(const FIELDTYPE *typ, va_list *ap, int *err)
+{
+ TypeArgument *res = (TypeArgument *)0;
+ TypeArgument *p;
+
+ if (typ && (typ->status & _HAS_ARGS))
+ {
+ assert(err && ap);
+ if (typ->status & _LINKED_TYPE)
+ {
+ p = (TypeArgument *)malloc(sizeof(TypeArgument));
+ if (p)
+ {
+ p->left = _nc_Make_Argument(typ->left ,ap,err);
+ p->right = _nc_Make_Argument(typ->right,ap,err);
+ return p;
+ }
+ else
+ *err += 1;
+ } else
+ {
+ assert(typ->makearg != 0);
+ if ( !(res=(TypeArgument *)typ->makearg(ap)) )
+ *err += 1;
+ }
+ }
+ return res;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : TypeArgument *_nc_Copy_Argument(const FIELDTYPE *typ,
+| const TypeArgument *argp,
+| int *err )
+|
+| Description : Create a copy of an argument structure for the specified
+| type.
+|
+| Return Values : Pointer to argument structure. Maybe NULL.
+| In case of an error in *err an errorcounter is increased.
++--------------------------------------------------------------------------*/
+TypeArgument*
+_nc_Copy_Argument(const FIELDTYPE *typ,
+ const TypeArgument *argp, int *err)
+{
+ TypeArgument *res = (TypeArgument *)0;
+ TypeArgument *p;
+
+ if ( typ && (typ->status & _HAS_ARGS) )
+ {
+ assert(err && argp);
+ if (typ->status & _LINKED_TYPE)
+ {
+ p = (TypeArgument *)malloc(sizeof(TypeArgument));
+ if (p)
+ {
+ p->left = _nc_Copy_Argument(typ,argp->left ,err);
+ p->right = _nc_Copy_Argument(typ,argp->right,err);
+ return p;
+ }
+ *err += 1;
+ }
+ else
+ {
+ if (typ->copyarg)
+ {
+ if (!(res = (TypeArgument *)(typ->copyarg((const void *)argp))))
+ *err += 1;
+ }
+ else
+ res = (TypeArgument *)argp;
+ }
+ }
+ return res;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : void _nc_Free_Argument(const FIELDTYPE *typ,
+| TypeArgument * argp )
+|
+| Description : Release memory associated with the argument structure
+| for the given fieldtype.
+|
+| Return Values : -
++--------------------------------------------------------------------------*/
+void
+_nc_Free_Argument(const FIELDTYPE * typ, TypeArgument * argp)
+{
+ if (!typ || !(typ->status & _HAS_ARGS))
+ return;
+
+ if (typ->status & _LINKED_TYPE)
+ {
+ assert(argp != 0);
+ _nc_Free_Argument(typ->left ,argp->left );
+ _nc_Free_Argument(typ->right,argp->right);
+ free(argp);
+ }
+ else
+ {
+ if (typ->freearg)
+ typ->freearg((void *)argp);
+ }
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : bool _nc_Copy_Type( FIELD *dst, FIELD const *src )
+|
+| Description : Copy argument structure of field src to field dst
+|
+| Return Values : TRUE - copy worked
+| FALSE - error occured
++--------------------------------------------------------------------------*/
+bool
+_nc_Copy_Type(FIELD *dst, FIELD const *src)
+{
+ int err = 0;
+
+ assert(dst && src);
+
+ dst->type = src->type;
+ dst->arg = (void *)_nc_Copy_Argument(src->type,(TypeArgument *)(src->arg),&err);
+
+ if (err)
+ {
+ _nc_Free_Argument(dst->type,(TypeArgument *)(dst->arg));
+ dst->type = (FIELDTYPE *)0;
+ dst->arg = (void *)0;
+ return FALSE;
+ }
+ else
+ {
+ if (dst->type)
+ dst->type->ref++;
+ return TRUE;
+ }
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : void _nc_Free_Type( FIELD *field )
+|
+| Description : Release Argument structure for this field
+|
+| Return Values : -
++--------------------------------------------------------------------------*/
+void
+_nc_Free_Type(FIELD *field)
+{
+ assert(field != 0);
+ if (field->type)
+ field->type->ref--;
+ _nc_Free_Argument(field->type,(TypeArgument *)(field->arg));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : FIELD *new_field( int rows, int cols,
+| int frow, int fcol,
+| int nrow, int nbuf )
+|
+| Description : Create a new field with this many 'rows' and 'cols',
+| starting at 'frow/fcol' in the subwindow of the form.
+| Allocate 'nrow' off-screen rows and 'nbuf' additional
+| buffers. If an error occurs, errno is set to
+|
+| E_BAD_ARGUMENT - invalid argument
+| E_SYSTEM_ERROR - system error
+|
+| Return Values : Pointer to the new field or NULL if failure.
++--------------------------------------------------------------------------*/
+FIELD *new_field(int rows, int cols, int frow, int fcol, int nrow, int nbuf)
+{
+ FIELD *New_Field = (FIELD *)0;
+ int err = E_BAD_ARGUMENT;
+
+ if (rows>0 &&
+ cols>0 &&
+ frow>=0 &&
+ fcol>=0 &&
+ nrow>=0 &&
+ nbuf>=0 &&
+ ((err = E_SYSTEM_ERROR) != 0) && /* trick: this resets the default error */
+ (New_Field=(FIELD *)malloc(sizeof(FIELD))) )
+ {
+ *New_Field = default_field;
+ New_Field->rows = rows;
+ New_Field->cols = cols;
+ New_Field->drows = rows + nrow;
+ New_Field->dcols = cols;
+ New_Field->frow = frow;
+ New_Field->fcol = fcol;
+ New_Field->nrow = nrow;
+ New_Field->nbuf = nbuf;
+ New_Field->link = New_Field;
+
+ if (_nc_Copy_Type(New_Field,&default_field))
+ {
+ size_t len;
+
+ len = Total_Buffer_Size(New_Field);
+ if ((New_Field->buf = (char *)malloc(len)))
+ {
+ /* Prefill buffers with blanks and insert terminating zeroes
+ between buffers */
+ int i;
+
+ memset(New_Field->buf,' ',len);
+ for(i=0;i<=New_Field->nbuf;i++)
+ {
+ New_Field->buf[(New_Field->drows*New_Field->cols+1)*(i+1)-1]
+ = '\0';
+ }
+ return New_Field;
+ }
+ }
+ }
+
+ if (New_Field)
+ free_field(New_Field);
+
+ SET_ERROR( err );
+ return (FIELD *)0;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int free_field( FIELD *field )
+|
+| Description : Frees the storage allocated for the field.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid field pointer
+| E_CONNECTED - field is connected
++--------------------------------------------------------------------------*/
+int free_field(FIELD * field)
+{
+ if (!field)
+ RETURN(E_BAD_ARGUMENT);
+
+ if (field->form)
+ RETURN(E_CONNECTED);
+
+ if (field == field->link)
+ {
+ if (field->buf)
+ free(field->buf);
+ }
+ else
+ {
+ FIELD *f;
+
+ for(f=field;f->link != field;f = f->link)
+ {}
+ f->link = field->link;
+ }
+ _nc_Free_Type(field);
+ free(field);
+ RETURN(E_OK);
+}
+
+/* fld_def.c ends here */
diff --git a/Source/CursesDialog/form/fld_dup.c b/Source/CursesDialog/form/fld_dup.c
new file mode 100644
index 000000000..1c5301d55
--- /dev/null
+++ b/Source/CursesDialog/form/fld_dup.c
@@ -0,0 +1,97 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 ABOVE 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. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <juergen.pfeifer@gmx.net> 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id$")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : FIELD *dup_field(FIELD *field, int frow, int fcol)
+|
+| Description : Duplicates the field at the specified position. All
+| field attributes and the buffers are copied.
+| If an error occurs, errno is set to
+|
+| E_BAD_ARGUMENT - invalid argument
+| E_SYSTEM_ERROR - system error
+|
+| Return Values : Pointer to the new field or NULL if failure
++--------------------------------------------------------------------------*/
+FIELD *dup_field(FIELD * field, int frow, int fcol)
+{
+ FIELD *New_Field = (FIELD *)0;
+ int err = E_BAD_ARGUMENT;
+
+ if (field && (frow>=0) && (fcol>=0) &&
+ ((err=E_SYSTEM_ERROR) != 0) && /* trick : this resets the default error */
+ (New_Field=(FIELD *)malloc(sizeof(FIELD))) )
+ {
+ *New_Field = *_nc_Default_Field;
+ New_Field->frow = frow;
+ New_Field->fcol = fcol;
+ New_Field->link = New_Field;
+ New_Field->rows = field->rows;
+ New_Field->cols = field->cols;
+ New_Field->nrow = field->nrow;
+ New_Field->drows = field->drows;
+ New_Field->dcols = field->dcols;
+ New_Field->maxgrow = field->maxgrow;
+ New_Field->nbuf = field->nbuf;
+ New_Field->just = field->just;
+ New_Field->fore = field->fore;
+ New_Field->back = field->back;
+ New_Field->pad = field->pad;
+ New_Field->opts = field->opts;
+ New_Field->usrptr = field->usrptr;
+
+ if (_nc_Copy_Type(New_Field,field))
+ {
+ size_t len;
+
+ len = Total_Buffer_Size(New_Field);
+ if ( (New_Field->buf=(char *)malloc(len)) )
+ {
+ memcpy(New_Field->buf,field->buf,len);
+ return New_Field;
+ }
+ }
+ }
+
+ if (New_Field)
+ free_field(New_Field);
+
+ SET_ERROR(err);
+ return (FIELD *)0;
+}
+
+/* fld_dup.c ends here */
diff --git a/Source/CursesDialog/form/fld_ftchoice.c b/Source/CursesDialog/form/fld_ftchoice.c
new file mode 100644
index 000000000..bb37073fb
--- /dev/null
+++ b/Source/CursesDialog/form/fld_ftchoice.c
@@ -0,0 +1,62 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 ABOVE 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. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <juergen.pfeifer@gmx.net> 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id$")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_fieldtype_choice(
+| FIELDTYPE *typ,
+| bool (* const next_choice)(FIELD *,const void *),
+| bool (* const prev_choice)(FIELD *,const void *))
+|
+| Description : Define implementation of enumeration requests.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid arguments
++--------------------------------------------------------------------------*/
+int set_fieldtype_choice(FIELDTYPE * typ,
+ bool (* const next_choice) (FIELD *,const void *),
+ bool (* const prev_choice) (FIELD *,const void *))
+{
+ if ( !typ || !next_choice || !prev_choice )
+ RETURN(E_BAD_ARGUMENT);
+
+ typ->status |= _HAS_CHOICE;
+ typ->next = next_choice;
+ typ->prev = prev_choice;
+ RETURN(E_OK);
+}
+
+/* fld_ftchoice.c ends here */
diff --git a/Source/CursesDialog/form/fld_ftlink.c b/Source/CursesDialog/form/fld_ftlink.c
new file mode 100644
index 000000000..1cb80d118
--- /dev/null
+++ b/Source/CursesDialog/form/fld_ftlink.c
@@ -0,0 +1,83 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 ABOVE 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. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <juergen.pfeifer@gmx.net> 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id$")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : FIELDTYPE *link_fieldtype(
+| FIELDTYPE *type1,
+| FIELDTYPE *type2)
+|
+| Description : Create a new fieldtype built from the two given types.
+| They are connected by an logical 'OR'.
+| If an error occurs, errno is set to
+| E_BAD_ARGUMENT - invalid arguments
+| E_SYSTEM_ERROR - system error (no memory)
+|
+| Return Values : Fieldtype pointer or NULL if error occured.
++--------------------------------------------------------------------------*/
+FIELDTYPE *link_fieldtype(FIELDTYPE * type1, FIELDTYPE * type2)
+{
+ FIELDTYPE *nftyp = (FIELDTYPE *)0;
+
+ if ( type1 && type2 )
+ {
+ nftyp = (FIELDTYPE *)malloc(sizeof(FIELDTYPE));
+ if (nftyp)
+ {
+ *nftyp = *_nc_Default_FieldType;
+ nftyp->status |= _LINKED_TYPE;
+ if ((type1->status & _HAS_ARGS) || (type2->status & _HAS_ARGS) )
+ nftyp->status |= _HAS_ARGS;
+ if ((type1->status & _HAS_CHOICE) || (type2->status & _HAS_CHOICE) )
+ nftyp->status |= _HAS_CHOICE;
+ nftyp->left = type1;
+ nftyp->right = type2;
+ type1->ref++;
+ type2->ref++;
+ }
+ else
+ {
+ SET_ERROR( E_SYSTEM_ERROR );
+ }
+ }
+ else
+ {
+ SET_ERROR( E_BAD_ARGUMENT );
+ }
+ return nftyp;
+}
+
+/* fld_ftlink.c ends here */
diff --git a/Source/CursesDialog/form/fld_info.c b/Source/CursesDialog/form/fld_info.c
new file mode 100644
index 000000000..1ba92c833
--- /dev/null
+++ b/Source/CursesDialog/form/fld_info.c
@@ -0,0 +1,91 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 ABOVE 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. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <juergen.pfeifer@gmx.net> 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id$")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int field_info(const FIELD *field,
+| int *rows, int *cols,
+| int *frow, int *fcol,
+| int *nrow, int *nbuf)
+|
+| Description : Retrieve infos about the fields creation parameters.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid field pointer
++--------------------------------------------------------------------------*/
+int field_info(const FIELD *field,
+ int *rows, int *cols,
+ int *frow, int *fcol,
+ int *nrow, int *nbuf)
+{
+ if (!field)
+ RETURN(E_BAD_ARGUMENT);
+
+ if (rows) *rows = field->rows;
+ if (cols) *cols = field->cols;
+ if (frow) *frow = field->frow;
+ if (fcol) *fcol = field->fcol;
+ if (nrow) *nrow = field->nrow;
+ if (nbuf) *nbuf = field->nbuf;
+ RETURN(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int dynamic_field_info(const FIELD *field,
+| int *drows, int *dcols,
+| int *maxgrow)
+|
+| Description : Retrieve information about a dynamic fields current
+| dynamic parameters.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid argument
++--------------------------------------------------------------------------*/
+int dynamic_field_info(const FIELD *field,
+ int *drows, int *dcols, int *maxgrow)
+{
+ if (!field)
+ RETURN(E_BAD_ARGUMENT);
+
+ if (drows) *drows = field->drows;
+ if (dcols) *dcols = field->dcols;
+ if (maxgrow) *maxgrow = field->maxgrow;
+
+ RETURN(E_OK);
+}
+
+/* fld_info.c ends here */
diff --git a/Source/CursesDialog/form/fld_just.c b/Source/CursesDialog/form/fld_just.c
new file mode 100644
index 000000000..701565450
--- /dev/null
+++ b/Source/CursesDialog/form/fld_just.c
@@ -0,0 +1,81 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 ABOVE 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. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <juergen.pfeifer@gmx.net> 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id$")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_field_just(FIELD *field, int just)
+|
+| Description : Set the fields type of justification.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - one of the arguments was incorrect
+| E_SYSTEM_ERROR - system error
++--------------------------------------------------------------------------*/
+int set_field_just(FIELD * field, int just)
+{
+ int res = E_BAD_ARGUMENT;
+
+ if ((just==NO_JUSTIFICATION) ||
+ (just==JUSTIFY_LEFT) ||
+ (just==JUSTIFY_CENTER) ||
+ (just==JUSTIFY_RIGHT) )
+ {
+ Normalize_Field( field );
+ if (field->just != just)
+ {
+ field->just = just;
+ res = _nc_Synchronize_Attributes( field );
+ }
+ else
+ res = E_OK;
+ }
+ RETURN(res);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int field_just( const FIELD *field )
+|
+| Description : Retrieve the fields type of justification
+|
+| Return Values : The justification type.
++--------------------------------------------------------------------------*/
+int field_just(const FIELD * field)
+{
+ return Normalize_Field( field )->just;
+}
+
+/* fld_just.c ends here */
diff --git a/Source/CursesDialog/form/fld_link.c b/Source/CursesDialog/form/fld_link.c
new file mode 100644
index 000000000..164f51bc4
--- /dev/null
+++ b/Source/CursesDialog/form/fld_link.c
@@ -0,0 +1,90 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 ABOVE 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. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <juergen.pfeifer@gmx.net> 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id$")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : FIELD *link_field(FIELD *field, int frow, int fcol)
+|
+| Description : Duplicates the field at the specified position. The
+| new field shares its buffers with the original one,
+| the attributes are independent.
+| If an error occurs, errno is set to
+|
+| E_BAD_ARGUMENT - invalid argument
+| E_SYSTEM_ERROR - system error
+|
+| Return Values : Pointer to the new field or NULL if failure
++--------------------------------------------------------------------------*/
+FIELD *link_field(FIELD * field, int frow, int fcol)
+{
+ FIELD *New_Field = (FIELD *)0;
+ int err = E_BAD_ARGUMENT;
+
+ if (field && (frow>=0) && (fcol>=0) &&
+ ((err=E_SYSTEM_ERROR) != 0) && /* trick: this resets the default error */
+ (New_Field = (FIELD *)malloc(sizeof(FIELD))) )
+ {
+ *New_Field = *_nc_Default_Field;
+ New_Field->frow = frow;
+ New_Field->fcol = fcol;
+ New_Field->link = field->link;
+ field->link = New_Field;
+ New_Field->buf = field->buf;
+ New_Field->rows = field->rows;
+ New_Field->cols = field->cols;
+ New_Field->nrow = field->nrow;
+ New_Field->nbuf = field->nbuf;
+ New_Field->drows = field->drows;
+ New_Field->dcols = field->dcols;
+ New_Field->maxgrow= field->maxgrow;
+ New_Field->just = field->just;
+ New_Field->fore = field->fore;
+ New_Field->back = field->back;
+ New_Field->pad = field->pad;
+ New_Field->opts = field->opts;
+ New_Field->usrptr = field->usrptr;
+ if (_nc_Copy_Type(New_Field,field))
+ return New_Field;
+ }
+
+ if (New_Field)
+ free_field(New_Field);
+
+ SET_ERROR( err );
+ return (FIELD *)0;
+}
+
+/* fld_link.c ends here */
diff --git a/Source/CursesDialog/form/fld_max.c b/Source/CursesDialog/form/fld_max.c
new file mode 100644
index 000000000..cca8dc558
--- /dev/null
+++ b/Source/CursesDialog/form/fld_max.c
@@ -0,0 +1,74 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 ABOVE 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. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <juergen.pfeifer@gmx.net> 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id$")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_max_field(FIELD *field, int maxgrow)
+|
+| Description : Set the maximum growth for a dynamic field. If maxgrow=0
+| the field may grow to any possible size.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid argument
++--------------------------------------------------------------------------*/
+int set_max_field(FIELD *field, int maxgrow)
+{
+ if (!field || (maxgrow<0))
+ RETURN(E_BAD_ARGUMENT);
+ else
+ {
+ bool single_line_field = Single_Line_Field(field);
+
+ if (maxgrow>0)
+ {
+ if (( single_line_field && (maxgrow < field->dcols)) ||
+ (!single_line_field && (maxgrow < field->drows)))
+ RETURN(E_BAD_ARGUMENT);
+ }
+ field->maxgrow = maxgrow;
+ field->status &= ~_MAY_GROW;
+ if (!(field->opts & O_STATIC))
+ {
+ if ((maxgrow==0) ||
+ ( single_line_field && (field->dcols < maxgrow)) ||
+ (!single_line_field && (field->drows < maxgrow)))
+ field->status |= _MAY_GROW;
+ }
+ }
+ RETURN(E_OK);
+}
+
+/* fld_max.c ends here */
diff --git a/Source/CursesDialog/form/fld_move.c b/Source/CursesDialog/form/fld_move.c
new file mode 100644
index 000000000..22934779c
--- /dev/null
+++ b/Source/CursesDialog/form/fld_move.c
@@ -0,0 +1,62 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 ABOVE 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. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <juergen.pfeifer@gmx.net> 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id$")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int move_field(FIELD *field,int frow, int fcol)
+|
+| Description : Moves the disconnected field to the new location in
+| the forms subwindow.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid argument passed
+| E_CONNECTED - field is connected
++--------------------------------------------------------------------------*/
+int move_field(FIELD *field, int frow, int fcol)
+{
+ if ( !field || (frow<0) || (fcol<0) )
+ RETURN(E_BAD_ARGUMENT);
+
+ if (field->form)
+ RETURN(E_CONNECTED);
+
+ field->frow = frow;
+ field->fcol = fcol;
+ RETURN(E_OK);
+}
+
+/* fld_move.c ends here */
+
diff --git a/Source/CursesDialog/form/fld_newftyp.c b/Source/CursesDialog/form/fld_newftyp.c
new file mode 100644
index 000000000..b45ebd879
--- /dev/null
+++ b/Source/CursesDialog/form/fld_newftyp.c
@@ -0,0 +1,125 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 ABOVE 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. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <juergen.pfeifer@gmx.net> 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id$")
+
+static FIELDTYPE const default_fieldtype = {
+ 0, /* status */
+ 0L, /* reference count */
+ (FIELDTYPE *)0, /* pointer to left operand */
+ (FIELDTYPE *)0, /* pointer to right operand */
+ NULL, /* makearg function */
+ NULL, /* copyarg function */
+ NULL, /* freearg function */
+ NULL, /* field validation function */
+ NULL, /* Character check function */
+ NULL, /* enumerate next function */
+ NULL /* enumerate previous function */
+};
+
+const FIELDTYPE* _nc_Default_FieldType = &default_fieldtype;
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : FIELDTYPE *new_fieldtype(
+| bool (* const field_check)(FIELD *,const void *),
+| bool (* const char_check) (int, const void *) )
+|
+| Description : Create a new fieldtype. The application programmer must
+| write a field_check and a char_check function and give
+| them as input to this call.
+| If an error occurs, errno is set to
+| E_BAD_ARGUMENT - invalid arguments
+| E_SYSTEM_ERROR - system error (no memory)
+|
+| Return Values : Fieldtype pointer or NULL if error occured
++--------------------------------------------------------------------------*/
+FIELDTYPE *new_fieldtype(
+ bool (* const field_check)(FIELD *,const void *),
+ bool (* const char_check) (int,const void *) )
+{
+ FIELDTYPE *nftyp = (FIELDTYPE *)0;
+
+ if ( (field_check) || (char_check) )
+ {
+ nftyp = (FIELDTYPE *)malloc(sizeof(FIELDTYPE));
+ if (nftyp)
+ {
+ *nftyp = default_fieldtype;
+ nftyp->fcheck = field_check;
+ nftyp->ccheck = char_check;
+ }
+ else
+ {
+ SET_ERROR( E_SYSTEM_ERROR );
+ }
+ }
+ else
+ {
+ SET_ERROR( E_BAD_ARGUMENT );
+ }
+ return nftyp;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int free_fieldtype(FIELDTYPE *typ)
+|
+| Description : Release the memory associated with this fieldtype.
+|
+| Return Values : E_OK - success
+| E_CONNECTED - there are fields referencing the type
+| E_BAD_ARGUMENT - invalid fieldtype pointer
++--------------------------------------------------------------------------*/
+int free_fieldtype(FIELDTYPE *typ)
+{
+ if (!typ)
+ RETURN(E_BAD_ARGUMENT);
+
+ if (typ->ref!=0)
+ RETURN(E_CONNECTED);
+
+ if (typ->status & _RESIDENT)
+ RETURN(E_CONNECTED);
+
+ if (typ->status & _LINKED_TYPE)
+ {
+ if (typ->left ) typ->left->ref--;
+ if (typ->right) typ->right->ref--;
+ }
+ free(typ);
+ RETURN(E_OK);
+}
+
+/* fld_newftyp.c ends here */
diff --git a/Source/CursesDialog/form/fld_opts.c b/Source/CursesDialog/form/fld_opts.c
new file mode 100644
index 000000000..234634bc6
--- /dev/null
+++ b/Source/CursesDialog/form/fld_opts.c
@@ -0,0 +1,124 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 ABOVE 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. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <juergen.pfeifer@gmx.net> 1995,1997 *
+ ****************************************************************************/
+#include "form.priv.h"
+
+MODULE_ID("$Id$")
+
+/*----------------------------------------------------------------------------
+ Field-Options manipulation routines
+ --------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_field_opts(FIELD *field, Field_Options opts)
+|
+| Description : Turns on the named options for this field and turns
+| off all the remaining options.
+|
+| Return Values : E_OK - success
+| E_CURRENT - the field is the current field
+| E_BAD_ARGUMENT - invalid options
+| E_SYSTEM_ERROR - system error
++--------------------------------------------------------------------------*/
+int set_field_opts(FIELD * field, Field_Options opts)
+{
+ int res = E_BAD_ARGUMENT;
+ opts &= ALL_FIELD_OPTS;
+ if (!(opts & ~ALL_FIELD_OPTS))
+ res = _nc_Synchronize_Options( Normalize_Field(field), opts );
+ RETURN(res);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : Field_Options field_opts(const FIELD *field)
+|
+| Description : Retrieve the fields options.
+|
+| Return Values : The options.
++--------------------------------------------------------------------------*/
+Field_Options field_opts(const FIELD * field)
+{
+ return ALL_FIELD_OPTS & Normalize_Field( field )->opts;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int field_opts_on(FIELD *field, Field_Options opts)
+|
+| Description : Turns on the named options for this field and all the
+| remaining options are unchanged.
+|
+| Return Values : E_OK - success
+| E_CURRENT - the field is the current field
+| E_BAD_ARGUMENT - invalid options
+| E_SYSTEM_ERROR - system error
++--------------------------------------------------------------------------*/
+int field_opts_on(FIELD * field, Field_Options opts)
+{
+ int res = E_BAD_ARGUMENT;
+
+ opts &= ALL_FIELD_OPTS;
+ if (!(opts & ~ALL_FIELD_OPTS))
+ {
+ Normalize_Field( field );
+ res = _nc_Synchronize_Options( field, field->opts | opts );
+ }
+ RETURN(res);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int field_opts_off(FIELD *field, Field_Options opts)
+|
+| Description : Turns off the named options for this field and all the
+| remaining options are unchanged.
+|
+| Return Values : E_OK - success
+| E_CURRENT - the field is the current field
+| E_BAD_ARGUMENT - invalid options
+| E_SYSTEM_ERROR - system error
++--------------------------------------------------------------------------*/
+int field_opts_off(FIELD * field, Field_Options opts)
+{
+ int res = E_BAD_ARGUMENT;
+
+ opts &= ALL_FIELD_OPTS;
+ if (!(opts & ~ALL_FIELD_OPTS))
+ {
+ Normalize_Field( field );
+ res = _nc_Synchronize_Options( field, field->opts & ~opts );
+ }
+ RETURN(res);
+}
+
+/* fld_opts.c ends here */
diff --git a/Source/CursesDialog/form/fld_pad.c b/Source/CursesDialog/form/fld_pad.c
new file mode 100644
index 000000000..45983409d
--- /dev/null
+++ b/Source/CursesDialog/form/fld_pad.c
@@ -0,0 +1,78 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 ABOVE 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. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <juergen.pfeifer@gmx.net> 1995,1997 *
+ ****************************************************************************/
+#include "form.priv.h"
+
+MODULE_ID("$Id$")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_field_pad(FIELD *field, int ch)
+|
+| Description : Set the pad character used to fill the field. This must
+| be a printable character.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid field pointer or pad character
+| E_SYSTEM_ERROR - system error
++--------------------------------------------------------------------------*/
+int set_field_pad(FIELD * field, int ch)
+{
+ int res = E_BAD_ARGUMENT;
+
+ Normalize_Field( field );
+ if (isprint((unsigned char)ch))
+ {
+ if (field->pad != ch)
+ {
+ field->pad = ch;
+ res = _nc_Synchronize_Attributes( field );
+ }
+ else
+ res = E_OK;
+ }
+ RETURN(res);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int field_pad(const FIELD *field)
+|
+| Description : Retrieve the fields pad character.
+|
+| Return Values : The pad character.
++--------------------------------------------------------------------------*/
+int field_pad(const FIELD * field)
+{
+ return Normalize_Field( field )->pad;
+}
+
+/* fld_pad.c ends here */
diff --git a/Source/CursesDialog/form/fld_page.c b/Source/CursesDialog/form/fld_page.c
new file mode 100644
index 000000000..408e71201
--- /dev/null
+++ b/Source/CursesDialog/form/fld_page.c
@@ -0,0 +1,76 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 ABOVE 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. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <juergen.pfeifer@gmx.net> 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id$")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_new_page(FIELD *field, bool new_page_flag)
+|
+| Description : Marks the field as the beginning of a new page of
+| the form.
+|
+| Return Values : E_OK - success
+| E_CONNECTED - field is connected
++--------------------------------------------------------------------------*/
+int set_new_page(FIELD * field, bool new_page_flag)
+{
+ Normalize_Field(field);
+ if (field->form)
+ RETURN(E_CONNECTED);
+
+ if (new_page_flag)
+ field->status |= _NEWPAGE;
+ else
+ field->status &= ~_NEWPAGE;
+
+ RETURN(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : bool new_page(const FIELD *field)
+|
+| Description : Retrieve the info whether or not the field starts a
+| new page on the form.
+|
+| Return Values : TRUE - field starts a new page
+| FALSE - field doesn't start a new page
++--------------------------------------------------------------------------*/
+bool new_page(const FIELD * field)
+{
+ return (Normalize_Field(field)->status & _NEWPAGE) ? TRUE : FALSE;
+}
+
+/* fld_page.c ends here */
diff --git a/Source/CursesDialog/form/fld_stat.c b/Source/CursesDialog/form/fld_stat.c
new file mode 100644
index 000000000..ee6831bbe
--- /dev/null
+++ b/Source/CursesDialog/form/fld_stat.c
@@ -0,0 +1,73 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 ABOVE 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. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <juergen.pfeifer@gmx.net> 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id$")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_field_status(FIELD *field, bool status)
+|
+| Description : Set or clear the 'changed' indication flag for that
+| fields primary buffer.
+|
+| Return Values : E_OK - success
++--------------------------------------------------------------------------*/
+int set_field_status(FIELD * field, bool status)
+{
+ Normalize_Field( field );
+
+ if (status)
+ field->status |= _CHANGED;
+ else
+ field->status &= ~_CHANGED;
+
+ return(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : bool field_status(const FIELD *field)
+|
+| Description : Retrieve the value of the 'changed' indication flag
+| for that fields primary buffer.
+|
+| Return Values : TRUE - buffer has been changed
+| FALSE - buffer has not been changed
++--------------------------------------------------------------------------*/
+bool field_status(const FIELD * field)
+{
+ return ((Normalize_Field(field)->status & _CHANGED) ? TRUE : FALSE);
+}
+
+/* fld_stat.c ends here */
diff --git a/Source/CursesDialog/form/fld_type.c b/Source/CursesDialog/form/fld_type.c
new file mode 100644
index 000000000..6c9def2c9
--- /dev/null
+++ b/Source/CursesDialog/form/fld_type.c
@@ -0,0 +1,51 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 ABOVE 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. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <juergen.pfeifer@gmx.net> 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id$")
+
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : FIELDTYPE *field_type(const FIELD *field)
+|
+| Description : Retrieve the associated fieldtype for this field.
+|
+| Return Values : Pointer to fieldtype of NULL if none is defined.
++--------------------------------------------------------------------------*/
+FIELDTYPE *field_type(const FIELD * field)
+{
+ return Normalize_Field(field)->type;
+}
+
+/* fld_type.c ends here */
diff --git a/Source/CursesDialog/form/fld_user.c b/Source/CursesDialog/form/fld_user.c
new file mode 100644
index 000000000..3287b5b17
--- /dev/null
+++ b/Source/CursesDialog/form/fld_user.c
@@ -0,0 +1,67 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 ABOVE 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. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <juergen.pfeifer@gmx.net> 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id$")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_field_userptr(FIELD *field, void *usrptr)
+|
+| Description : Set the pointer that is reserved in any field to store
+| application relevant information
+|
+| Return Values : E_OK - on success
++--------------------------------------------------------------------------*/
+int set_field_userptr(FIELD * field, void *usrptr)
+{
+ Normalize_Field( field )->usrptr = usrptr;
+ RETURN(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : void *field_userptr(const FIELD *field)
+|
+| Description : Return the pointer that is reserved in any field to
+| store application relevant information.
+|
+| Return Values : Value of pointer. If no such pointer has been set,
+| NULL is returned
++--------------------------------------------------------------------------*/
+void *field_userptr(const FIELD *field)
+{
+ return Normalize_Field( field )->usrptr;
+}
+
+/* fld_user.c ends here */
diff --git a/Source/CursesDialog/form/form.h b/Source/CursesDialog/form/form.h
new file mode 100644
index 000000000..94f05af8a
--- /dev/null
+++ b/Source/CursesDialog/form/form.h
@@ -0,0 +1,401 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 ABOVE 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. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <juergen.pfeifer@gmx.net> 1995,1997 *
+ ****************************************************************************/
+
+#ifndef FORM_H
+#define FORM_H
+
+#if defined(__sun__) && defined(__GNUC__)
+ #define _MSE_INT_H
+#endif
+
+#include <cmFormConfigure.h>
+
+/* 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 <eti.h>
+#include <stdarg.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+typedef int Form_Options;
+typedef int Field_Options;
+
+ /**********
+ * _PAGE *
+ **********/
+
+typedef struct {
+ short pmin; /* index of first field on page */
+ short pmax; /* index of last field on page */
+ short smin; /* index of top leftmost field on page */
+ short smax; /* index of bottom rightmost field on page */
+} _PAGE;
+
+ /**********
+ * FIELD *
+ **********/
+
+typedef struct fieldnode {
+ unsigned short status; /* flags */
+ short rows; /* size in rows */
+ short cols; /* size in cols */
+ short frow; /* first row */
+ short fcol; /* first col */
+ int drows; /* dynamic rows */
+ int dcols; /* dynamic cols */
+ int maxgrow; /* maximum field growth */
+ int nrow; /* offscreen rows */
+ short nbuf; /* additional buffers */
+ short just; /* justification */
+ short page; /* page on form */
+ short index; /* into form -> field */
+ int pad; /* pad character */
+ chtype fore; /* foreground attribute */
+ chtype back; /* background attribute */
+ Field_Options opts; /* options */
+ struct fieldnode * snext; /* sorted order pointer */
+ struct fieldnode * sprev; /* sorted order pointer */
+ struct fieldnode * link; /* linked field chain */
+ struct formnode * form; /* containing form */
+ struct typenode * type; /* field type */
+ void * arg; /* argument for type */
+ char * buf; /* field buffers */
+ void * usrptr; /* user pointer */
+} FIELD;
+
+ /**************
+ * FIELDTYPE *
+ **************/
+
+typedef struct typenode {
+ unsigned short status; /* flags */
+ long ref; /* reference count */
+ struct typenode * left; /* ptr to operand for | */
+ struct typenode * right; /* ptr to operand for | */
+
+ void* (*makearg)(va_list *); /* make fieldtype arg */
+ void* (*copyarg)(const void *); /* copy fieldtype arg */
+ void (*freearg)(void *); /* free fieldtype arg */
+
+ bool (*fcheck)(FIELD *,const void *); /* field validation */
+ bool (*ccheck)(int,const void *); /* character validation */
+
+ bool (*next)(FIELD *,const void *); /* enumerate next value */
+ bool (*prev)(FIELD *,const void *); /* enumerate prev value */
+
+} FIELDTYPE;
+
+ /*********
+ * FORM *
+ *********/
+
+typedef struct formnode {
+ unsigned short status; /* flags */
+ short rows; /* size in rows */
+ short cols; /* size in cols */
+ int currow; /* current row in field window*/
+ int curcol; /* current col in field window*/
+ int toprow; /* in scrollable field window */
+ int begincol; /* in horiz. scrollable field */
+ short maxfield; /* number of fields */
+ short maxpage; /* number of pages */
+ short curpage; /* index into page */
+ Form_Options opts; /* options */
+ WINDOW * win; /* window */
+ WINDOW * sub; /* subwindow */
+ WINDOW * w; /* window for current field */
+ FIELD ** field; /* field [maxfield] */
+ FIELD * current; /* current field */
+ _PAGE * page; /* page [maxpage] */
+ void * usrptr; /* user pointer */
+
+ void (*forminit)(struct formnode *);
+ void (*formterm)(struct formnode *);
+ void (*fieldinit)(struct formnode *);
+ void (*fieldterm)(struct formnode *);
+
+} FORM;
+
+typedef void (*Form_Hook)(FORM *);
+
+ /***************************
+ * miscellaneous #defines *
+ ***************************/
+
+/* field justification */
+#define NO_JUSTIFICATION (0)
+#define JUSTIFY_LEFT (1)
+#define JUSTIFY_CENTER (2)
+#define JUSTIFY_RIGHT (3)
+
+/* field options */
+#define O_VISIBLE (0x0001)
+#define O_ACTIVE (0x0002)
+#define O_PUBLIC (0x0004)
+#define O_EDIT (0x0008)
+#define O_WRAP (0x0010)
+#define O_BLANK (0x0020)
+#define O_AUTOSKIP (0x0040)
+#define O_NULLOK (0x0080)
+#define O_PASSOK (0x0100)
+#define O_STATIC (0x0200)
+
+/* form options */
+#define O_NL_OVERLOAD (0x0001)
+#define O_BS_OVERLOAD (0x0002)
+
+/* form driver commands */
+#define REQ_NEXT_PAGE (KEY_MAX + 1) /* move to next page */
+#define REQ_PREV_PAGE (KEY_MAX + 2) /* move to previous page */
+#define REQ_FIRST_PAGE (KEY_MAX + 3) /* move to first page */
+#define REQ_LAST_PAGE (KEY_MAX + 4) /* move to last page */
+
+#define REQ_NEXT_FIELD (KEY_MAX + 5) /* move to next field */
+#define REQ_PREV_FIELD (KEY_MAX + 6) /* move to previous field */
+#define REQ_FIRST_FIELD (KEY_MAX + 7) /* move to first field */
+#define REQ_LAST_FIELD (KEY_MAX + 8) /* move to last field */
+#define REQ_SNEXT_FIELD (KEY_MAX + 9) /* move to sorted next field */
+#define REQ_SPREV_FIELD (KEY_MAX + 10) /* move to sorted prev field */
+#define REQ_SFIRST_FIELD (KEY_MAX + 11) /* move to sorted first field */
+#define REQ_SLAST_FIELD (KEY_MAX + 12) /* move to sorted last field */
+#define REQ_LEFT_FIELD (KEY_MAX + 13) /* move to left to field */
+#define REQ_RIGHT_FIELD (KEY_MAX + 14) /* move to right to field */
+#define REQ_UP_FIELD (KEY_MAX + 15) /* move to up to field */
+#define REQ_DOWN_FIELD (KEY_MAX + 16) /* move to down to field */
+
+#define REQ_NEXT_CHAR (KEY_MAX + 17) /* move to next char in field */
+#define REQ_PREV_CHAR (KEY_MAX + 18) /* move to prev char in field */
+#define REQ_NEXT_LINE (KEY_MAX + 19) /* move to next line in field */
+#define REQ_PREV_LINE (KEY_MAX + 20) /* move to prev line in field */
+#define REQ_NEXT_WORD (KEY_MAX + 21) /* move to next word in field */
+#define REQ_PREV_WORD (KEY_MAX + 22) /* move to prev word in field */
+#define REQ_BEG_FIELD (KEY_MAX + 23) /* move to first char in field */
+#define REQ_END_FIELD (KEY_MAX + 24) /* move after last char in fld */
+#define REQ_BEG_LINE (KEY_MAX + 25) /* move to beginning of line */
+#define REQ_END_LINE (KEY_MAX + 26) /* move after last char in line */
+#define REQ_LEFT_CHAR (KEY_MAX + 27) /* move left in field */
+#define REQ_RIGHT_CHAR (KEY_MAX + 28) /* move right in field */
+#define REQ_UP_CHAR (KEY_MAX + 29) /* move up in field */
+#define REQ_DOWN_CHAR (KEY_MAX + 30) /* move down in field */
+
+#define REQ_NEW_LINE (KEY_MAX + 31) /* insert/overlay new line */
+#define REQ_INS_CHAR (KEY_MAX + 32) /* insert blank char at cursor */
+#define REQ_INS_LINE (KEY_MAX + 33) /* insert blank line at cursor */
+#define REQ_DEL_CHAR (KEY_MAX + 34) /* delete char at cursor */
+#define REQ_DEL_PREV (KEY_MAX + 35) /* delete char before cursor */
+#define REQ_DEL_LINE (KEY_MAX + 36) /* delete line at cursor */
+#define REQ_DEL_WORD (KEY_MAX + 37) /* delete line at cursor */
+#define REQ_CLR_EOL (KEY_MAX + 38) /* clear to end of line */
+#define REQ_CLR_EOF (KEY_MAX + 39) /* clear to end of field */
+#define REQ_CLR_FIELD (KEY_MAX + 40) /* clear entire field */
+#define REQ_OVL_MODE (KEY_MAX + 41) /* begin overlay mode */
+#define REQ_INS_MODE (KEY_MAX + 42) /* begin insert mode */
+#define REQ_SCR_FLINE (KEY_MAX + 43) /* scroll field forward a line */
+#define REQ_SCR_BLINE (KEY_MAX + 44) /* scroll field backward a line */
+#define REQ_SCR_FPAGE (KEY_MAX + 45) /* scroll field forward a page */
+#define REQ_SCR_BPAGE (KEY_MAX + 46) /* scroll field backward a page */
+#define REQ_SCR_FHPAGE (KEY_MAX + 47) /* scroll field forward half page */
+#define REQ_SCR_BHPAGE (KEY_MAX + 48) /* scroll field backward half page */
+#define REQ_SCR_FCHAR (KEY_MAX + 49) /* horizontal scroll char */
+#define REQ_SCR_BCHAR (KEY_MAX + 50) /* horizontal scroll char */
+#define REQ_SCR_HFLINE (KEY_MAX + 51) /* horizontal scroll line */
+#define REQ_SCR_HBLINE (KEY_MAX + 52) /* horizontal scroll line */
+#define REQ_SCR_HFHALF (KEY_MAX + 53) /* horizontal scroll half line */
+#define REQ_SCR_HBHALF (KEY_MAX + 54) /* horizontal scroll half line */
+
+#define REQ_VALIDATION (KEY_MAX + 55) /* validate field */
+#define REQ_NEXT_CHOICE (KEY_MAX + 56) /* display next field choice */
+#define REQ_PREV_CHOICE (KEY_MAX + 57) /* display prev field choice */
+
+#define MIN_FORM_COMMAND (KEY_MAX + 1) /* used by form_driver */
+#define MAX_FORM_COMMAND (KEY_MAX + 57) /* used by form_driver */
+
+#if defined(MAX_COMMAND)
+# if (MAX_FORM_COMMAND > MAX_COMMAND)
+# error Something is wrong -- MAX_FORM_COMMAND is greater than MAX_COMMAND
+# elif (MAX_COMMAND != (KEY_MAX + 128))
+# error Something is wrong -- MAX_COMMAND is already inconsistently defined.
+# endif
+#else
+# define MAX_COMMAND (KEY_MAX + 128)
+#endif
+
+ /*************************
+ * standard field types *
+ *************************/
+extern FIELDTYPE *TYPE_ALPHA,
+ *TYPE_ALNUM,
+ *TYPE_ENUM,
+ *TYPE_INTEGER,
+ *TYPE_NUMERIC,
+ *TYPE_REGEXP;
+
+ /************************************
+ * built-in additional field types *
+ * They are not defined in SVr4 *
+ ************************************/
+extern FIELDTYPE *TYPE_IPV4; /* Internet IP Version 4 address */
+
+ /***********************
+ * Default objects *
+ ***********************/
+extern FORM *_nc_Default_Form;
+extern FIELD *_nc_Default_Field;
+
+
+ /***********************
+ * FIELDTYPE routines *
+ ***********************/
+extern FIELDTYPE
+ *new_fieldtype(
+ bool (* const field_check)(FIELD *,const void *),
+ bool (* const char_check)(int,const void *)),
+ *link_fieldtype(FIELDTYPE *,FIELDTYPE *);
+
+extern int free_fieldtype(FIELDTYPE *),
+ set_fieldtype_choice (FIELDTYPE *,
+ bool (* const next_choice)(FIELD *,const void *),
+ bool (* const prev_choice)(FIELD *,const void *));
+
+ /*******************
+ * FIELD routines *
+ *******************/
+extern FIELD *new_field(int,int,int,int,int,int),
+ *dup_field(FIELD *,int,int),
+ *link_field(FIELD *,int,int);
+
+extern int free_field(FIELD *),
+ field_info(const FIELD *,int *,int *,int *,int *,int *,int *),
+ dynamic_field_info(const FIELD *,int *,int *,int *),
+ set_max_field( FIELD *,int),
+ move_field(FIELD *,int,int),
+ set_field_type(FIELD *,FIELDTYPE *,...),
+ set_new_page(FIELD *,bool),
+ set_field_just(FIELD *,int),
+ field_just(const FIELD *),
+ set_field_fore(FIELD *,chtype),
+ set_field_back(FIELD *,chtype),
+ set_field_pad(FIELD *,int),
+ field_pad(const FIELD *),
+ set_field_buffer(FIELD *,int,const char *),
+ set_field_status(FIELD *,bool),
+ set_field_userptr(FIELD *, void *),
+ set_field_opts(FIELD *,Field_Options),
+ field_opts_on(FIELD *,Field_Options),
+ field_opts_off(FIELD *,Field_Options);
+
+extern chtype field_fore(const FIELD *),
+ field_back(const FIELD *);
+
+extern bool new_page(const FIELD *),
+ field_status(const FIELD *);
+
+extern void *field_arg(const FIELD *);
+
+extern void *field_userptr(const FIELD *);
+
+extern FIELDTYPE
+ *field_type(const FIELD *);
+
+extern char* field_buffer(const FIELD *,int);
+
+extern Field_Options
+ field_opts(const FIELD *);
+
+ /******************
+ * FORM routines *
+ ******************/
+extern FORM *new_form(FIELD **);
+
+extern FIELD **form_fields(const FORM *),
+ *current_field(const FORM *);
+
+extern WINDOW *form_win(const FORM *),
+ *form_sub(const FORM *);
+
+extern Form_Hook
+ form_init(const FORM *),
+ form_term(const FORM *),
+ field_init(const FORM *),
+ field_term(const FORM *);
+
+extern int free_form(FORM *),
+ set_form_fields(FORM *,FIELD **),
+ field_count(const FORM *),
+ set_form_win(FORM *,WINDOW *),
+ set_form_sub(FORM *,WINDOW *),
+ set_current_field(FORM *,FIELD *),
+ field_index(const FIELD *),
+ set_form_page(FORM *,int),
+ form_page(const FORM *),
+ scale_form(const FORM *,int *,int *),
+ set_form_init(FORM *,Form_Hook),
+ set_form_term(FORM *,Form_Hook),
+ set_field_init(FORM *,Form_Hook),
+ set_field_term(FORM *,Form_Hook),
+ post_form(FORM *),
+ unpost_form(FORM *),
+ pos_form_cursor(FORM *),
+ form_driver(FORM *,int),
+ set_form_userptr(FORM *,void *),
+ set_form_opts(FORM *,Form_Options),
+ form_opts_on(FORM *,Form_Options),
+ form_opts_off(FORM *,Form_Options),
+ form_request_by_name(const char *);
+
+extern const char
+ *form_request_name(int);
+
+extern void *form_userptr(const FORM *);
+
+extern Form_Options
+ form_opts(const FORM *);
+
+extern bool data_ahead(const FORM *),
+ data_behind(const FORM *);
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* FORM_H */
diff --git a/Source/CursesDialog/form/form.priv.h b/Source/CursesDialog/form/form.priv.h
new file mode 100644
index 000000000..3691f2fd0
--- /dev/null
+++ b/Source/CursesDialog/form/form.priv.h
@@ -0,0 +1,134 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 ABOVE 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. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <juergen.pfeifer@gmx.net> 1995,1997 *
+ ****************************************************************************/
+
+#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 */
+#define _FCHECK_REQUIRED (0x20) /* Current field needs validation */
+
+/* field status values */
+#define _CHANGED (0x01) /* Field has been changed */
+#define _NEWTOP (0x02) /* Vertical scrolling occured */
+#define _NEWPAGE (0x04) /* field begins new page of form */
+#define _MAY_GROW (0x08) /* dynamic field may still grow */
+
+/* fieldtype status values */
+#define _LINKED_TYPE (0x01) /* Type is a linked type */
+#define _HAS_ARGS (0x02) /* Type has arguments */
+#define _HAS_CHOICE (0x04) /* Type has choice methods */
+#define _RESIDENT (0x08) /* Type is builtin */
+
+/* This are the field options required to be a selectable field in field
+ navigation requests */
+#define O_SELECTABLE (O_ACTIVE | O_VISIBLE)
+
+/* If form is NULL replace form argument by default-form */
+#define Normalize_Form(form) ((form)=(form)?(form):_nc_Default_Form)
+
+/* If field is NULL replace field argument by default-field */
+#define Normalize_Field(field) ((field)=(field)?(field):_nc_Default_Field)
+
+/* Retrieve forms window */
+#define Get_Form_Window(form) \
+ ((form)->sub?(form)->sub:((form)->win?(form)->win:stdscr))
+
+/* Calculate the size for a single buffer for this field */
+#define Buffer_Length(field) ((field)->drows * (field)->dcols)
+
+/* Calculate the total size of all buffers for this field */
+#define Total_Buffer_Size(field) \
+ ( (Buffer_Length(field) + 1) * (1+(field)->nbuf) )
+
+/* Logic to determine whether or not a field is single lined */
+#define Single_Line_Field(field) \
+ (((field)->rows + (field)->nrow) == 1)
+
+/* Logic to determine whether or not a field is selectable */
+#define Field_Is_Selectable(f) (((f)->opts & O_SELECTABLE)==O_SELECTABLE)
+#define Field_Is_Not_Selectable(f) (((f)->opts & O_SELECTABLE)!=O_SELECTABLE)
+
+typedef struct typearg {
+ struct typearg *left;
+ struct typearg *right;
+} TypeArgument;
+
+/* This is a dummy request code (normally invalid) to be used internally
+ with the form_driver() routine to position to the first active field
+ on the form
+*/
+#define FIRST_ACTIVE_MAGIC (-291056)
+
+#define ALL_FORM_OPTS ( \
+ O_NL_OVERLOAD |\
+ O_BS_OVERLOAD )
+
+#define ALL_FIELD_OPTS ( \
+ O_VISIBLE |\
+ O_ACTIVE |\
+ O_PUBLIC |\
+ O_EDIT |\
+ O_WRAP |\
+ O_BLANK |\
+ O_AUTOSKIP|\
+ O_NULLOK |\
+ O_PASSOK |\
+ O_STATIC )
+
+
+#define C_BLANK ' '
+#define is_blank(c) ((c)==C_BLANK)
+
+extern const FIELDTYPE* _nc_Default_FieldType;
+
+extern TypeArgument* _nc_Make_Argument(const FIELDTYPE*,va_list*,int*);
+extern TypeArgument *_nc_Copy_Argument(const FIELDTYPE*,const TypeArgument*, int*);
+extern void _nc_Free_Argument(const FIELDTYPE*,TypeArgument*);
+extern bool _nc_Copy_Type(FIELD*, FIELD const *);
+extern void _nc_Free_Type(FIELD *);
+
+extern int _nc_Synchronize_Attributes(FIELD*);
+extern int _nc_Synchronize_Options(FIELD*,Field_Options);
+extern int _nc_Set_Form_Page(FORM*,int,FIELD*);
+extern int _nc_Refresh_Current_Field(FORM*);
+extern FIELD* _nc_First_Active_Field(FORM*);
+extern bool _nc_Internal_Validation(FORM*);
+extern int _nc_Set_Current_Field(FORM*,FIELD*);
+extern int _nc_Position_Form_Cursor(FORM*);
diff --git a/Source/CursesDialog/form/frm_cursor.c b/Source/CursesDialog/form/frm_cursor.c
new file mode 100644
index 000000000..6c311fe60
--- /dev/null
+++ b/Source/CursesDialog/form/frm_cursor.c
@@ -0,0 +1,66 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 ABOVE 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. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <juergen.pfeifer@gmx.net> 1995,1997 *
+ ****************************************************************************/
+#include "form.priv.h"
+
+MODULE_ID("$Id$")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int pos_form_cursor(FORM * form)
+|
+| Description : Moves the form window cursor to the location required
+| by the form driver to resume form processing. This may
+| be needed after the application calls a curses library
+| I/O routine that modifies the cursor position.
+|
+| Return Values : E_OK - Success
+| E_SYSTEM_ERROR - System error.
+| E_BAD_ARGUMENT - Invalid form pointer
+| E_NOT_POSTED - Form is not posted
++--------------------------------------------------------------------------*/
+int pos_form_cursor(FORM * form)
+{
+ int res;
+
+ if (!form)
+ res = E_BAD_ARGUMENT;
+ else
+ {
+ if (!(form->status & _POSTED))
+ res = E_NOT_POSTED;
+ else
+ res = _nc_Position_Form_Cursor(form);
+ }
+ RETURN(res);
+}
+
+/* frm_cursor.c ends here */
diff --git a/Source/CursesDialog/form/frm_data.c b/Source/CursesDialog/form/frm_data.c
new file mode 100644
index 000000000..fb62ab82a
--- /dev/null
+++ b/Source/CursesDialog/form/frm_data.c
@@ -0,0 +1,183 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 ABOVE 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. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <juergen.pfeifer@gmx.net> 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id$")
+
+extern int winnstr(WINDOW *, char *, int);
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : bool data_behind(const FORM *form)
+|
+| Description : Check for off-screen data behind. This is nearly trivial
+| becose the begin of a field is fixed.
+|
+| Return Values : TRUE - there are off-screen data behind
+| FALSE - there are no off-screen data behind
++--------------------------------------------------------------------------*/
+bool data_behind(const FORM *form)
+{
+ bool result = FALSE;
+
+ if (form && (form->status & _POSTED) && form->current)
+ {
+ FIELD *field;
+
+ field = form->current;
+ if (!Single_Line_Field(field))
+ {
+ result = (form->toprow==0) ? FALSE : TRUE;
+ }
+ else
+ {
+ result = (form->begincol==0) ? FALSE : TRUE;
+ }
+ }
+ return(result);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static char * After_Last_Non_Pad_Position(
+| char *buffer,
+| int len,
+| int pad)
+|
+| Description : Find the last position in the buffer that doesn't
+| contain a padding character.
+|
+| Return Values : The pointer to this position
++--------------------------------------------------------------------------*/
+INLINE
+static char * After_Last_Non_Pad_Position(char *buffer, int len, int pad)
+{
+ char *end = buffer + len;
+
+ assert(buffer && len>=0);
+ while ( (buffer < end) && (*(end-1)==pad) )
+ end--;
+
+ return end;
+}
+
+#define SMALL_BUFFER_SIZE (80)
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : bool data_ahead(const FORM *form)
+|
+| Description : Check for off-screen data ahead. This is more difficult
+| because a dynamic field has a variable end.
+|
+| Return Values : TRUE - there are off-screen data ahead
+| FALSE - there are no off-screen data ahead
++--------------------------------------------------------------------------*/
+bool data_ahead(const FORM *form)
+{
+ bool result = FALSE;
+
+ if (form && (form->status & _POSTED) && form->current)
+ {
+ static char buffer[SMALL_BUFFER_SIZE + 1];
+ FIELD *field;
+ bool large_buffer;
+ bool cursor_moved = FALSE;
+ char *bp;
+ char *found_content;
+ int pos;
+
+ field = form->current;
+ assert(form->w != 0);
+
+ large_buffer = (field->cols > SMALL_BUFFER_SIZE);
+ if (large_buffer)
+ bp = (char *)malloc((size_t)(field->cols) + 1);
+ else
+ bp = buffer;
+
+ assert(bp != 0);
+
+ if (Single_Line_Field(field))
+ {
+ int check_len;
+
+ pos = form->begincol + field->cols;
+ while (pos < field->dcols)
+ {
+ check_len = field->dcols - pos;
+ if ( check_len >= field->cols )
+ check_len = field->cols;
+ cursor_moved = TRUE;
+ wmove(form->w,0,pos);
+ winnstr(form->w,bp,check_len);
+ found_content =
+ After_Last_Non_Pad_Position(bp,check_len,field->pad);
+ if (found_content==bp)
+ pos += field->cols;
+ else
+ {
+ result = TRUE;
+ break;
+ }
+ }
+ }
+ else
+ {
+ pos = form->toprow + field->rows;
+ while (pos < field->drows)
+ {
+ cursor_moved = TRUE;
+ wmove(form->w,pos,0);
+ pos++;
+ winnstr(form->w,bp,field->cols);
+ found_content =
+ After_Last_Non_Pad_Position(bp,field->cols,field->pad);
+ if (found_content!=bp)
+ {
+ result = TRUE;
+ break;
+ }
+ }
+ }
+
+ if (large_buffer)
+ free(bp);
+
+ if (cursor_moved)
+ wmove(form->w,form->currow,form->curcol);
+ }
+ return(result);
+}
+
+/* frm_data.c ends here */
diff --git a/Source/CursesDialog/form/frm_def.c b/Source/CursesDialog/form/frm_def.c
new file mode 100644
index 000000000..0b28f5f0e
--- /dev/null
+++ b/Source/CursesDialog/form/frm_def.c
@@ -0,0 +1,376 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 ABOVE 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. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <juergen.pfeifer@gmx.net> 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id$")
+
+/* this can't be readonly */
+static FORM default_form = {
+ 0, /* status */
+ 0, /* rows */
+ 0, /* cols */
+ 0, /* currow */
+ 0, /* curcol */
+ 0, /* toprow */
+ 0, /* begincol */
+ -1, /* maxfield */
+ -1, /* maxpage */
+ -1, /* curpage */
+ ALL_FORM_OPTS, /* opts */
+ (WINDOW *)0, /* win */
+ (WINDOW *)0, /* sub */
+ (WINDOW *)0, /* w */
+ (FIELD **)0, /* field */
+ (FIELD *)0, /* current */
+ (_PAGE *)0, /* page */
+ (char *)0, /* usrptr */
+ NULL, /* forminit */
+ NULL, /* formterm */
+ NULL, /* fieldinit */
+ NULL /* fieldterm */
+};
+
+FORM *_nc_Default_Form = &default_form;
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static FIELD *Insert_Field_By_Position(
+| FIELD *new_field,
+| FIELD *head )
+|
+| Description : Insert new_field into sorted fieldlist with head "head"
+| and return new head of sorted fieldlist. Sorting
+| criteria is (row,column). This is a circular list.
+|
+| Return Values : New head of sorted fieldlist
++--------------------------------------------------------------------------*/
+static FIELD *Insert_Field_By_Position(FIELD *newfield, FIELD *head)
+{
+ FIELD *current, *newhead;
+
+ assert(newfield != 0);
+
+ if (!head)
+ { /* empty list is trivial */
+ newhead = newfield->snext = newfield->sprev = newfield;
+ }
+ else
+ {
+ newhead = current = head;
+ while((current->frow < newfield->frow) ||
+ ((current->frow==newfield->frow) &&
+ (current->fcol < newfield->fcol)) )
+ {
+ current = current->snext;
+ if (current==head)
+ { /* We cycled through. Reset head to indicate that */
+ head = (FIELD *)0;
+ break;
+ }
+ }
+ /* we leave the loop with current pointing to the field after newfield*/
+ newfield->snext = current;
+ newfield->sprev = current->sprev;
+ newfield->snext->sprev = newfield;
+ newfield->sprev->snext = newfield;
+ if (current==head)
+ newhead = newfield;
+ }
+ return(newhead);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void Disconnect_Fields(FORM *form)
+|
+| Description : Break association between form and array of fields.
+|
+| Return Values : -
++--------------------------------------------------------------------------*/
+static void Disconnect_Fields( FORM * form )
+{
+ if (form->field)
+ {
+ FIELD **fields;
+
+ for(fields=form->field;*fields;fields++)
+ {
+ if (form == (*fields)->form)
+ (*fields)->form = (FORM *)0;
+ }
+
+ form->rows = form->cols = 0;
+ form->maxfield = form->maxpage = -1;
+ form->field = (FIELD **)0;
+ if (form->page)
+ free(form->page);
+ form->page = (_PAGE *)0;
+ }
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int Connect_Fields(FORM *form, FIELD **fields)
+|
+| Description : Set association between form and array of fields.
+|
+| Return Values : E_OK - no error
+| E_CONNECTED - a field is already connected
+| E_BAD_ARGUMENT - Invalid form pointer or field array
+| E_SYSTEM_ERROR - not enough memory
++--------------------------------------------------------------------------*/
+static int Connect_Fields(FORM * form, FIELD ** fields)
+{
+ int field_cnt, j;
+ int page_nr;
+ int maximum_row_in_field, maximum_col_in_field;
+ _PAGE *pg;
+
+ assert(form != 0);
+
+ form->field = fields;
+ form->maxfield = 0;
+ form->maxpage = 0;
+
+ if (!fields)
+ RETURN(E_OK);
+
+ page_nr = 0;
+ /* store formpointer in fields and count pages */
+ for(field_cnt=0;fields[field_cnt];field_cnt++)
+ {
+ if (fields[field_cnt]->form)
+ RETURN(E_CONNECTED);
+ if ( field_cnt==0 ||
+ (fields[field_cnt]->status & _NEWPAGE))
+ page_nr++;
+ fields[field_cnt]->form = form;
+ }
+ if (field_cnt==0)
+ RETURN(E_BAD_ARGUMENT);
+
+ /* allocate page structures */
+ if ( (pg = (_PAGE *)malloc(page_nr * sizeof(_PAGE))) != (_PAGE *)0 )
+ {
+ form->page = pg;
+ }
+ else
+ RETURN(E_SYSTEM_ERROR);
+
+ /* Cycle through fields and calculate page boundaries as well as
+ size of the form */
+ for(j=0;j<field_cnt;j++)
+ {
+ if (j==0)
+ pg->pmin = j;
+ else
+ {
+ if (fields[j]->status & _NEWPAGE)
+ {
+ pg->pmax = j-1;
+ pg++;
+ pg->pmin = j;
+ }
+ }
+
+ maximum_row_in_field = fields[j]->frow + fields[j]->rows;
+ maximum_col_in_field = fields[j]->fcol + fields[j]->cols;
+
+ if (form->rows < maximum_row_in_field)
+ form->rows = maximum_row_in_field;
+ if (form->cols < maximum_col_in_field)
+ form->cols = maximum_col_in_field;
+ }
+
+ pg->pmax = field_cnt-1;
+ form->maxfield = field_cnt;
+ form->maxpage = page_nr;
+
+ /* Sort fields on form pages */
+ for(page_nr = 0;page_nr < form->maxpage; page_nr++)
+ {
+ FIELD *fld = (FIELD *)0;
+ for(j = form->page[page_nr].pmin;j <= form->page[page_nr].pmax;j++)
+ {
+ fields[j]->index = j;
+ fields[j]->page = page_nr;
+ fld = Insert_Field_By_Position(fields[j],fld);
+ }
+ form->page[page_nr].smin = fld->index;
+ form->page[page_nr].smax = fld->sprev->index;
+ }
+ RETURN(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int Associate_Fields(FORM *form, FIELD **fields)
+|
+| Description : Set association between form and array of fields.
+| If there are fields, position to first active field.
+|
+| Return Values : E_OK - success
+| any other - error occured
++--------------------------------------------------------------------------*/
+INLINE static int Associate_Fields(FORM *form, FIELD **fields)
+{
+ int res = Connect_Fields(form,fields);
+ if (res == E_OK)
+ {
+ if (form->maxpage>0)
+ {
+ form->curpage = 0;
+ form_driver(form,FIRST_ACTIVE_MAGIC);
+ }
+ else
+ {
+ form->curpage = -1;
+ form->current = (FIELD *)0;
+ }
+ }
+ return(res);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : FORM *new_form( FIELD **fields )
+|
+| Description : Create new form with given array of fields.
+|
+| Return Values : Pointer to form. NULL if error occured.
++--------------------------------------------------------------------------*/
+FORM *new_form(FIELD ** fields)
+{
+ int err = E_SYSTEM_ERROR;
+
+ FORM *form = (FORM *)malloc(sizeof(FORM));
+
+ if (form)
+ {
+ *form = *_nc_Default_Form;
+ if ((err=Associate_Fields(form,fields))!=E_OK)
+ {
+ free_form(form);
+ form = (FORM *)0;
+ }
+ }
+
+ if (!form)
+ SET_ERROR(err);
+
+ return(form);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int free_form( FORM *form )
+|
+| Description : Release internal memory associated with form.
+|
+| Return Values : E_OK - no error
+| E_BAD_ARGUMENT - invalid form pointer
+| E_POSTED - form is posted
++--------------------------------------------------------------------------*/
+int free_form(FORM * form)
+{
+ if ( !form )
+ RETURN(E_BAD_ARGUMENT);
+
+ if ( form->status & _POSTED)
+ RETURN(E_POSTED);
+
+ Disconnect_Fields( form );
+ if (form->page)
+ free(form->page);
+ free(form);
+
+ RETURN(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_form_fields( FORM *form, FIELD **fields )
+|
+| Description : Set a new association of an array of fields to a form
+|
+| Return Values : E_OK - no error
+| E_BAD_ARGUMENT - invalid form pointer
+| E_POSTED - form is posted
++--------------------------------------------------------------------------*/
+int set_form_fields(FORM * form, FIELD ** fields)
+{
+ FIELD **old;
+ int res;
+
+ if ( !form )
+ RETURN(E_BAD_ARGUMENT);
+
+ if ( form->status & _POSTED )
+ RETURN(E_POSTED);
+
+ old = form->field;
+ Disconnect_Fields( form );
+
+ if( (res = Associate_Fields( form, fields )) != E_OK )
+ Connect_Fields( form, old );
+
+ RETURN(res);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : FIELD **form_fields( const FORM *form )
+|
+| Description : Retrieve array of fields
+|
+| Return Values : Pointer to field array
++--------------------------------------------------------------------------*/
+FIELD **form_fields(const FORM * form)
+{
+ return (Normalize_Form( form )->field);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int field_count( const FORM *form )
+|
+| Description : Retrieve number of fields
+|
+| Return Values : Number of fields, -1 if none are defined
++--------------------------------------------------------------------------*/
+int field_count(const FORM * form)
+{
+ return (Normalize_Form( form )->maxfield);
+}
+
+/* frm_def.c ends here */
diff --git a/Source/CursesDialog/form/frm_driver.c b/Source/CursesDialog/form/frm_driver.c
new file mode 100644
index 000000000..f234722f3
--- /dev/null
+++ b/Source/CursesDialog/form/frm_driver.c
@@ -0,0 +1,3898 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 ABOVE 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. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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
+#undef columns
+
+MODULE_ID("$Id$")
+
+/* These declarations are missing from curses.h on some platforms. */
+extern int winnstr(WINDOW *, char *, int);
+#if defined(__DECCXX_VER) || (defined(__GNUC__) && defined(__osf__))
+extern int waddnstr(WINDOW *,const char *const,int);
+extern void wbkgdset(WINDOW *,chtype);
+#ifndef untouchwin
+extern int untouchwin(WINDOW *);
+#endif
+extern void wcursyncup(WINDOW *);
+extern int copywin(const WINDOW*,WINDOW*,int,int,int,int,int,int,int);
+extern bool is_linetouched(WINDOW *,int);
+extern void wsyncup(WINDOW *);
+extern WINDOW *derwin(WINDOW *,int,int,int,int);
+extern int winsnstr(WINDOW *, const char *,int);
+extern int winsdelln(WINDOW *,int);
+#endif
+
+/*----------------------------------------------------------------------------
+ This is the core module of the form library. It contains the majority
+ of the driver routines as well as the form_driver function.
+
+ Essentially this module is nearly the whole library. This is because
+ all the functions in this module depends on some others in the module,
+ so it makes no sense to split them into separate files because they
+ will always be linked together. The only acceptable concern is turnaround
+ time for this module, but now we have all Pentiums or Riscs, so what!
+
+ The driver routines are grouped into nine generic categories:
+
+ a) Page Navigation ( all functions prefixed by PN_ )
+ The current page of the form is left and some new page is
+ entered.
+ b) Inter-Field Navigation ( all functions prefixed by FN_ )
+ The current field of the form is left and some new field is
+ entered.
+ c) Intra-Field Navigation ( all functions prefixed by IFN_ )
+ The current position in the current field is changed.
+ d) Vertical Scrolling ( all functions prefixed by VSC_ )
+ Esseantially this is a specialization of Intra-Field navigation.
+ It has to check for a multi-line field.
+ e) Horizontal Scrolling ( all functions prefixed by HSC_ )
+ Esseantially this is a specialization of Intra-Field navigation.
+ It has to check for a single-line field.
+ f) Field Editing ( all functions prefixed by FE_ )
+ The content of the current field is changed
+ g) Edit Mode requests ( all functions prefixed by EM_ )
+ Switching between insert and overlay mode
+ h) Field-Validation requests ( all functions prefixed by FV_ )
+ Perform verifications of the field.
+ i) Choice requests ( all functions prefixed by CR_ )
+ Requests to enumerate possible field values
+ --------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ Some remarks on the placements of assert() macros :
+ I use them only on "strategic" places, i.e. top level entries where
+ I want to make sure that things are set correctly. Throughout subordinate
+ routines I omit them mostly.
+ --------------------------------------------------------------------------*/
+
+/*
+Some options that may effect compatibility in behavior to SVr4 forms,
+but they are here to allow a more intuitive and user friendly behaviour of
+our form implementation. This doesn't affect the API, so we feel it is
+uncritical.
+
+The initial implementation tries to stay very close with the behaviour
+of the original SVr4 implementation, although in some areas it is quite
+clear that this isn't the most appropriate way. As far as possible this
+sources will allow you to build a forms lib that behaves quite similar
+to SVr4, but now and in the future we will give you better options.
+Perhaps at some time we will make this configurable at runtime.
+*/
+
+/* Implement a more user-friendly previous/next word behaviour */
+#define FRIENDLY_PREV_NEXT_WORD (1)
+/* Fix the wrong behaviour for forms with all fields inactive */
+#define FIX_FORM_INACTIVE_BUG (1)
+/* Allow dynamic field growth also when navigating past the end */
+#define GROW_IF_NAVIGATE (1)
+
+/*----------------------------------------------------------------------------
+ Forward references to some internally used static functions
+ --------------------------------------------------------------------------*/
+static int Inter_Field_Navigation ( int (* const fct) (FORM *), FORM * form );
+static int FN_Next_Field (FORM * form);
+static int FN_Previous_Field (FORM * form);
+static int FE_New_Line(FORM *);
+static int FE_Delete_Previous(FORM *);
+
+/*----------------------------------------------------------------------------
+ Macro Definitions.
+
+ Some Remarks on that: I use the convention to use UPPERCASE for constants
+ defined by Macros. If I provide a macro as a kind of inline routine to
+ provide some logic, I use my Upper_Lower case style.
+ --------------------------------------------------------------------------*/
+
+/* Calculate the position of a single row in a field buffer */
+#define Position_Of_Row_In_Buffer(field,row) ((row)*(field)->dcols)
+
+/* Calculate start address for the fields buffer# N */
+#define Address_Of_Nth_Buffer(field,N) \
+ ((field)->buf + (N)*(1+Buffer_Length(field)))
+
+/* Calculate the start address of the row in the fields specified buffer# N */
+#define Address_Of_Row_In_Nth_Buffer(field,N,row) \
+ (Address_Of_Nth_Buffer(field,N) + Position_Of_Row_In_Buffer(field,row))
+
+/* Calculate the start address of the row in the fields primary buffer */
+#define Address_Of_Row_In_Buffer(field,row) \
+ Address_Of_Row_In_Nth_Buffer(field,0,row)
+
+/* Calculate the start address of the row in the forms current field
+ buffer# N */
+#define Address_Of_Current_Row_In_Nth_Buffer(form,N) \
+ Address_Of_Row_In_Nth_Buffer((form)->current,N,(form)->currow)
+
+/* Calculate the start address of the row in the forms current field
+ primary buffer */
+#define Address_Of_Current_Row_In_Buffer(form) \
+ Address_Of_Current_Row_In_Nth_Buffer(form,0)
+
+/* Calculate the address of the cursor in the forms current field
+ primary buffer */
+#define Address_Of_Current_Position_In_Nth_Buffer(form,N) \
+ (Address_Of_Current_Row_In_Nth_Buffer(form,N) + (form)->curcol)
+
+/* Calculate the address of the cursor in the forms current field
+ buffer# N */
+#define Address_Of_Current_Position_In_Buffer(form) \
+ Address_Of_Current_Position_In_Nth_Buffer(form,0)
+
+/* Logic to decide wether or not a field is actually a field with
+ vertical or horizontal scrolling */
+#define Is_Scroll_Field(field) \
+ (((field)->drows > (field)->rows) || \
+ ((field)->dcols > (field)->cols))
+
+/* Logic to decide whether or not a field needs to have an individual window
+ instead of a derived window because it contains invisible parts.
+ This is true for non-public fields and for scrollable fields. */
+#define Has_Invisible_Parts(field) \
+ (!((field)->opts & O_PUBLIC) || \
+ Is_Scroll_Field(field))
+
+/* Logic to decide whether or not a field needs justification */
+#define Justification_Allowed(field) \
+ (((field)->just != NO_JUSTIFICATION) && \
+ (Single_Line_Field(field)) && \
+ (((field)->dcols == (field)->cols) && \
+ ((field)->opts & O_STATIC)) )
+
+/* Logic to determine whether or not a dynamic field may still grow */
+#define Growable(field) ((field)->status & _MAY_GROW)
+
+/* Macro to set the attributes for a fields window */
+#define Set_Field_Window_Attributes(field,win) \
+( wbkgdset((win),(chtype)((field)->pad | (field)->back)), \
+ wattrset((win),(field)->fore) )
+
+/* Logic to decide whether or not a field really appears on the form */
+#define Field_Really_Appears(field) \
+ ((field->form) &&\
+ (field->form->status & _POSTED) &&\
+ (field->opts & O_VISIBLE) &&\
+ (field->page == field->form->curpage))
+
+/* Logic to determine whether or not we are on the first position in the
+ current field */
+#define First_Position_In_Current_Field(form) \
+ (((form)->currow==0) && ((form)->curcol==0))
+
+
+#define Minimum(a,b) (((a)<=(b)) ? (a) : (b))
+#define Maximum(a,b) (((a)>=(b)) ? (a) : (b))
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static char *Get_Start_Of_Data(char * buf, int blen)
+|
+| Description : Return pointer to first non-blank position in buffer.
+| If buffer is empty return pointer to buffer itself.
+|
+| Return Values : Pointer to first non-blank position in buffer
++--------------------------------------------------------------------------*/
+INLINE static char *Get_Start_Of_Data(char * buf, int blen)
+{
+ char *p = buf;
+ char *end = &buf[blen];
+
+ assert(buf && blen>=0);
+ while( (p < end) && is_blank(*p) )
+ p++;
+ return( (p==end) ? buf : p );
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static char *After_End_Of_Data(char * buf, int blen)
+|
+| Description : Return pointer after last non-blank position in buffer.
+| If buffer is empty, return pointer to buffer itself.
+|
+| Return Values : Pointer to position after last non-blank position in
+| buffer.
++--------------------------------------------------------------------------*/
+INLINE static char *After_End_Of_Data(char * buf,int blen)
+{
+ char *p = &buf[blen];
+
+ assert(buf && blen>=0);
+ while( (p>buf) && is_blank(p[-1]) )
+ p--;
+ return( p );
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static char *Get_First_Whitespace_Character(
+| char * buf, int blen)
+|
+| Description : Position to the first whitespace character.
+|
+| Return Values : Pointer to first whitespace character in buffer.
++--------------------------------------------------------------------------*/
+INLINE static char *Get_First_Whitespace_Character(char * buf, int blen)
+{
+ char *p = buf;
+ char *end = &p[blen];
+
+ assert(buf && blen>=0);
+ while( (p < end) && !is_blank(*p))
+ p++;
+ return( (p==end) ? buf : p );
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static char *After_Last_Whitespace_Character(
+| char * buf, int blen)
+|
+| Description : Get the position after the last whitespace character.
+|
+| Return Values : Pointer to position after last whitespace character in
+| buffer.
++--------------------------------------------------------------------------*/
+INLINE static char *After_Last_Whitespace_Character(char * buf, int blen)
+{
+ char *p = &buf[blen];
+
+ assert(buf && blen>=0);
+ while( (p>buf) && !is_blank(p[-1]) )
+ p--;
+ return( p );
+}
+
+/* Set this to 1 to use the div_t version. This is a good idea if your
+ compiler has an intrinsic div() support. Unfortunately GNU-C has it
+ not yet.
+ N.B.: This only works if form->curcol follows immediately form->currow
+ and both are of type int.
+*/
+#define USE_DIV_T (0)
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void Adjust_Cursor_Position(
+| FORM * form, const char * pos)
+|
+| Description : Set current row and column of the form to values
+| corresponding to the buffer position.
+|
+| Return Values : -
++--------------------------------------------------------------------------*/
+INLINE static void Adjust_Cursor_Position(FORM * form, const char * pos)
+{
+ FIELD *field;
+ int idx;
+
+ field = form->current;
+ assert( pos >= field->buf && field->dcols > 0);
+ idx = (int)( pos - field->buf );
+#if USE_DIV_T
+ *((div_t *)&(form->currow)) = div(idx,field->dcols);
+#else
+ form->currow = idx / field->dcols;
+ form->curcol = idx - field->cols * form->currow;
+#endif
+ if ( field->drows < form->currow )
+ form->currow = 0;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void Buffer_To_Window(
+| const FIELD * field,
+| WINDOW * win)
+|
+| Description : Copy the buffer to the window. If its a multiline
+| field, the buffer is split to the lines of the
+| window without any editing.
+|
+| Return Values : -
++--------------------------------------------------------------------------*/
+static void Buffer_To_Window(const FIELD * field, WINDOW * win)
+{
+ int width, height;
+ int len;
+ int row;
+ char *pBuffer;
+
+ 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;
+ row++, pBuffer += width )
+ {
+ if ((len = (int)( After_End_Of_Data( pBuffer, width ) - pBuffer )) > 0)
+ {
+ wmove( win, row, 0 );
+ waddnstr( win, pBuffer, len );
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void Window_To_Buffer(
+| WINDOW * win,
+| FIELD * field)
+|
+| Description : Copy the content of the window into the buffer.
+| The multiple lines of a window are simply
+| concatenated into the buffer. Pad characters in
+| the window will be replaced by blanks in the buffer.
+|
+| Return Values : -
++--------------------------------------------------------------------------*/
+static void Window_To_Buffer(WINDOW * win, FIELD * field)
+{
+ int pad;
+ int len = 0;
+ char *p;
+ int row, height;
+
+ 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
+
+ for(row=0; (row < height) && (row < field->drows); row++ )
+ {
+ wmove( win, row, 0 );
+ len += winnstr( win, p+len, field->dcols );
+ }
+ p[len] = '\0';
+
+ /* replace visual padding character by blanks in buffer */
+ if (pad != C_BLANK)
+ {
+ int i;
+ for(i=0; i<len; i++, p++)
+ {
+ if (*p==pad)
+ *p = C_BLANK;
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void Synchronize_Buffer(FORM * form)
+|
+| Description : If there was a change, copy the content of the
+| window into the buffer, so the buffer is synchronized
+| with the windows content. We have to indicate that the
+| buffer needs validation due to the change.
+|
+| Return Values : -
++--------------------------------------------------------------------------*/
+INLINE static void Synchronize_Buffer(FORM * form)
+{
+ if (form->status & _WINDOW_MODIFIED)
+ {
+ form->status &= ~_WINDOW_MODIFIED;
+ form->status |= _FCHECK_REQUIRED;
+ Window_To_Buffer(form->w,form->current);
+ wmove(form->w,form->currow,form->curcol);
+ }
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Field_Grown( FIELD *field, int amount)
+|
+| Description : This function is called for growable dynamic fields
+| only. It has to increase the buffers and to allocate
+| a new window for this field.
+| This function has the side effect to set a new
+| field-buffer pointer, the dcols and drows values
+| as well as a new current Window for the field.
+|
+| Return Values : TRUE - field successfully increased
+| FALSE - there was some error
++--------------------------------------------------------------------------*/
+static bool Field_Grown(FIELD * field, int amount)
+{
+ bool result = FALSE;
+
+ if (field && Growable(field))
+ {
+ bool single_line_field = Single_Line_Field(field);
+ int old_buflen = Buffer_Length(field);
+ int new_buflen;
+ int old_dcols = field->dcols;
+ int old_drows = field->drows;
+ char *oldbuf = field->buf;
+ char *newbuf;
+
+ int growth;
+ FORM *form = field->form;
+ bool need_visual_update = ((form != (FORM *)0) &&
+ (form->status & _POSTED) &&
+ (form->current==field));
+
+ if (need_visual_update)
+ Synchronize_Buffer(form);
+
+ if (single_line_field)
+ {
+ growth = field->cols * amount;
+ if (field->maxgrow)
+ growth = Minimum(field->maxgrow - field->dcols,growth);
+ field->dcols += growth;
+ if (field->dcols == field->maxgrow)
+ field->status &= ~_MAY_GROW;
+ }
+ else
+ {
+ growth = (field->rows + field->nrow) * amount;
+ if (field->maxgrow)
+ growth = Minimum(field->maxgrow - field->drows,growth);
+ field->drows += growth;
+ if (field->drows == field->maxgrow)
+ field->status &= ~_MAY_GROW;
+ }
+ /* drows, dcols changed, so we get really the new buffer length */
+ new_buflen = Buffer_Length(field);
+ newbuf=(char *)malloc((size_t)Total_Buffer_Size(field));
+ if (!newbuf)
+ { /* restore to previous state */
+ field->dcols = old_dcols;
+ field->drows = old_drows;
+ if (( single_line_field && (field->dcols!=field->maxgrow)) ||
+ (!single_line_field && (field->drows!=field->maxgrow)))
+ field->status |= _MAY_GROW;
+ return FALSE;
+ }
+ else
+ { /* Copy all the buffers. This is the reason why we can't
+ just use realloc().
+ */
+ int i;
+ char *old_bp;
+ char *new_bp;
+
+ field->buf = newbuf;
+ for(i=0;i<=field->nbuf;i++)
+ {
+ new_bp = Address_Of_Nth_Buffer(field,i);
+ old_bp = oldbuf + i*(1+old_buflen);
+ memcpy(new_bp,old_bp,(size_t)old_buflen);
+ if (new_buflen > old_buflen)
+ memset(new_bp + old_buflen,C_BLANK,
+ (size_t)(new_buflen - old_buflen));
+ *(new_bp + new_buflen) = '\0';
+ }
+
+ if (need_visual_update)
+ {
+ WINDOW *new_window = newpad(field->drows,field->dcols);
+ if (!new_window)
+ { /* restore old state */
+ field->dcols = old_dcols;
+ field->drows = old_drows;
+ field->buf = oldbuf;
+ if (( single_line_field &&
+ (field->dcols!=field->maxgrow)) ||
+ (!single_line_field &&
+ (field->drows!=field->maxgrow)))
+ field->status |= _MAY_GROW;
+ free( newbuf );
+ return FALSE;
+ }
+ assert(form!=(FORM *)0);
+ delwin(form->w);
+ form->w = new_window;
+ Set_Field_Window_Attributes(field,form->w);
+ werase(form->w);
+ Buffer_To_Window(field,form->w);
+ untouchwin(form->w);
+ wmove(form->w,form->currow,form->curcol);
+ }
+
+ free(oldbuf);
+ /* reflect changes in linked fields */
+ if (field != field->link)
+ {
+ FIELD *linked_field;
+ for(linked_field = field->link;
+ linked_field!= field;
+ linked_field = linked_field->link)
+ {
+ linked_field->buf = field->buf;
+ linked_field->drows = field->drows;
+ linked_field->dcols = field->dcols;
+ }
+ }
+ result = TRUE;
+ }
+ }
+ return(result);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int _nc_Position_Form_Cursor(FORM * form)
+|
+| Description : Position the cursor in the window for the current
+| field to be in sync. with the currow and curcol
+| values.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid form pointer
+| E_SYSTEM_ERROR - form has no current field or
+| field-window
++--------------------------------------------------------------------------*/
+int
+_nc_Position_Form_Cursor(FORM * form)
+{
+ FIELD *field;
+ WINDOW *formwin;
+
+ if (!form)
+ return(E_BAD_ARGUMENT);
+
+ if (!form->w || !form->current)
+ return(E_SYSTEM_ERROR);
+
+ field = form->current;
+ formwin = Get_Form_Window(form);
+
+ wmove( form->w, form->currow, form->curcol );
+ if ( Has_Invisible_Parts(field) )
+ {
+ /* in this case fieldwin isn't derived from formwin, so we have
+ to move the cursor in formwin by hand... */
+ wmove(formwin,
+ field->frow + form->currow - form->toprow,
+ field->fcol + form->curcol - form->begincol);
+ wcursyncup(formwin);
+ }
+ else
+ wcursyncup(form->w);
+ return(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int _nc_Refresh_Current_Field(FORM * form)
+|
+| Description : Propagate the changes in the fields window to the
+| window of the form.
+|
+| Return Values : E_OK - on success
+| E_BAD_ARGUMENT - invalid form pointer
+| E_SYSTEM_ERROR - general error
++--------------------------------------------------------------------------*/
+int
+_nc_Refresh_Current_Field(FORM * form)
+{
+ WINDOW *formwin;
+ FIELD *field;
+
+ if (!form)
+ RETURN(E_BAD_ARGUMENT);
+
+ if (!form->w || !form->current)
+ RETURN(E_SYSTEM_ERROR);
+
+ field = form->current;
+ formwin = Get_Form_Window(form);
+
+ if (field->opts & O_PUBLIC)
+ {
+ if (Is_Scroll_Field(field))
+ {
+ /* Again, in this case the fieldwin isn't derived from formwin,
+ so we have to perform a copy operation. */
+ if (Single_Line_Field(field))
+ { /* horizontal scrolling */
+ if (form->curcol < form->begincol)
+ form->begincol = form->curcol;
+ else
+ {
+ if (form->curcol >= (form->begincol + field->cols))
+ form->begincol = form->curcol - field->cols + 1;
+ }
+ copywin(form->w,
+ formwin,
+ 0,
+ form->begincol,
+ field->frow,
+ field->fcol,
+ field->frow,
+ field->cols + field->fcol - 1,
+ 0);
+ }
+ else
+ { /* A multiline, i.e. vertical scrolling field */
+ int row_after_bottom,first_modified_row,first_unmodified_row;
+
+ if (field->drows > field->rows)
+ {
+ row_after_bottom = form->toprow + field->rows;
+ if (form->currow < form->toprow)
+ {
+ form->toprow = form->currow;
+ field->status |= _NEWTOP;
+ }
+ if (form->currow >= row_after_bottom)
+ {
+ form->toprow = form->currow - field->rows + 1;
+ field->status |= _NEWTOP;
+ }
+ if (field->status & _NEWTOP)
+ { /* means we have to copy whole range */
+ first_modified_row = form->toprow;
+ first_unmodified_row = first_modified_row + field->rows;
+ field->status &= ~_NEWTOP;
+ }
+ else
+ { /* we try to optimize : finding the range of touched
+ lines */
+ first_modified_row = form->toprow;
+ while(first_modified_row < row_after_bottom)
+ {
+ if (is_linetouched(form->w,first_modified_row))
+ break;
+ first_modified_row++;
+ }
+ first_unmodified_row = first_modified_row;
+ while(first_unmodified_row < row_after_bottom)
+ {
+ if (!is_linetouched(form->w,first_unmodified_row))
+ break;
+ first_unmodified_row++;
+ }
+ }
+ }
+ else
+ {
+ first_modified_row = form->toprow;
+ first_unmodified_row = first_modified_row + field->rows;
+ }
+ if (first_unmodified_row != first_modified_row)
+ copywin(form->w,
+ formwin,
+ first_modified_row,
+ 0,
+ field->frow + first_modified_row - form->toprow,
+ field->fcol,
+ field->frow + first_unmodified_row - form->toprow - 1,
+ field->cols + field->fcol - 1,
+ 0);
+ }
+ wsyncup(formwin);
+ }
+ else
+ { /* if the field-window is simply a derived window, i.e. contains
+ no invisible parts, the whole thing is trivial
+ */
+ wsyncup(form->w);
+ }
+ }
+ untouchwin(form->w);
+ return _nc_Position_Form_Cursor(form);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void Perform_Justification(
+| FIELD * field,
+| WINDOW * win)
+|
+| Description : Output field with requested justification
+|
+| Return Values : -
++--------------------------------------------------------------------------*/
+static void Perform_Justification(FIELD * field, WINDOW * win)
+{
+ char *bp;
+ int len;
+ int col = 0;
+
+ bp = Get_Start_Of_Data(field->buf,Buffer_Length(field));
+ len = (int)(After_End_Of_Data(field->buf,Buffer_Length(field)) - bp);
+
+ if (len>0)
+ {
+ assert(win && (field->drows == 1) && (field->dcols == field->cols));
+
+ switch(field->just)
+ {
+ case JUSTIFY_LEFT:
+ break;
+ case JUSTIFY_CENTER:
+ col = (field->cols - len)/2;
+ break;
+ case JUSTIFY_RIGHT:
+ col = field->cols - len;
+ break;
+ default:
+ break;
+ }
+
+ wmove(win,0,col);
+ waddnstr(win,bp,len);
+ }
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void Undo_Justification(
+| FIELD * field,
+| WINDOW * win)
+|
+| Description : Display field without any justification, i.e.
+| left justified
+|
+| Return Values : -
++--------------------------------------------------------------------------*/
+static void Undo_Justification(FIELD * field, WINDOW * win)
+{
+ char *bp;
+ int len;
+
+ bp = Get_Start_Of_Data(field->buf,Buffer_Length(field));
+ len = (int)(After_End_Of_Data(field->buf,Buffer_Length(field))-bp);
+
+ if (len>0)
+ {
+ assert(win != 0);
+ wmove(win,0,0);
+ waddnstr(win,bp,len);
+ }
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Check_Char(
+| FIELDTYPE * typ,
+| int ch,
+| TypeArgument *argp)
+|
+| Description : Perform a single character check for character ch
+| according to the fieldtype instance.
+|
+| Return Values : TRUE - Character is valid
+| FALSE - Character is invalid
++--------------------------------------------------------------------------*/
+static bool Check_Char(FIELDTYPE * typ, int ch, TypeArgument *argp)
+{
+ if (typ)
+ {
+ if (typ->status & _LINKED_TYPE)
+ {
+ assert(argp != 0);
+ return(
+ Check_Char(typ->left ,ch,argp->left ) ||
+ Check_Char(typ->right,ch,argp->right) );
+ }
+ else
+ {
+ if (typ->ccheck)
+ return typ->ccheck(ch,(void *)argp);
+ }
+ }
+ return (isprint((unsigned char)ch) ? TRUE : FALSE);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int Display_Or_Erase_Field(
+| FIELD * field,
+| bool bEraseFlag)
+|
+| Description : Create a subwindow for the field and display the
+| buffer contents (apply justification if required)
+| or simply erase the field.
+|
+| Return Values : E_OK - on success
+| E_SYSTEM_ERROR - some error (typical no memory)
++--------------------------------------------------------------------------*/
+static int Display_Or_Erase_Field(FIELD * field, bool bEraseFlag)
+{
+ WINDOW *win;
+ WINDOW *fwin;
+
+ if (!field)
+ return E_SYSTEM_ERROR;
+
+ fwin = Get_Form_Window(field->form);
+ win = derwin(fwin,
+ field->rows,field->cols,field->frow,field->fcol);
+
+ if (!win)
+ return E_SYSTEM_ERROR;
+ else
+ {
+ if (field->opts & O_VISIBLE)
+ Set_Field_Window_Attributes(field,win);
+ else
+ {
+#if defined(__LSB_VERSION__)
+ /* getattrs() would be handy, but it is not part of LSB 4.0 */
+ attr_t fwinAttrs;
+ short fwinPair;
+ wattr_get(fwin, &fwinAttrs, &fwinPair, 0);
+ wattr_set(win, fwinAttrs, fwinPair, 0);
+#else
+ wattrset(win,getattrs(fwin));
+#endif
+ }
+ werase(win);
+ }
+
+ if (!bEraseFlag)
+ {
+ if (field->opts & O_PUBLIC)
+ {
+ if (Justification_Allowed(field))
+ Perform_Justification(field,win);
+ else
+ Buffer_To_Window(field,win);
+ }
+ field->status &= ~_NEWTOP;
+ }
+ wsyncup(win);
+ delwin(win);
+ return E_OK;
+}
+
+/* Macros to preset the bEraseFlag */
+#define Display_Field(field) Display_Or_Erase_Field(field,FALSE)
+#define Erase_Field(field) Display_Or_Erase_Field(field,TRUE)
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int Synchronize_Field(FIELD * field)
+|
+| Description : Synchronize the windows content with the value in
+| the buffer.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid field pointer
+| E_SYSTEM_ERROR - some severe basic error
++--------------------------------------------------------------------------*/
+static int Synchronize_Field(FIELD * field)
+{
+ FORM *form;
+ int res = E_OK;
+
+ if (!field)
+ return(E_BAD_ARGUMENT);
+
+ if (((form=field->form) != (FORM *)0)
+ && Field_Really_Appears(field))
+ {
+ if (field == form->current)
+ {
+ form->currow = form->curcol = form->toprow = form->begincol = 0;
+ werase(form->w);
+
+ if ( (field->opts & O_PUBLIC) && Justification_Allowed(field) )
+ Undo_Justification( field, form->w );
+ else
+ Buffer_To_Window( field, form->w );
+
+ field->status |= _NEWTOP;
+ res = _nc_Refresh_Current_Field( form );
+ }
+ else
+ res = Display_Field( field );
+ }
+ field->status |= _CHANGED;
+ return(res);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int Synchronize_Linked_Fields(FIELD * field)
+|
+| Description : Propagate the Synchronize_Field function to all linked
+| fields. The first error that occurs in the sequence
+| of updates is the returnvalue.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid field pointer
+| E_SYSTEM_ERROR - some severe basic error
++--------------------------------------------------------------------------*/
+static int Synchronize_Linked_Fields(FIELD * field)
+{
+ FIELD *linked_field;
+ int res = E_OK;
+ int syncres;
+
+ if (!field)
+ return(E_BAD_ARGUMENT);
+
+ if (!field->link)
+ return(E_SYSTEM_ERROR);
+
+ for(linked_field = field->link;
+ linked_field!= field;
+ linked_field = linked_field->link )
+ {
+ if (((syncres=Synchronize_Field(linked_field)) != E_OK) &&
+ (res==E_OK))
+ res = syncres;
+ }
+ return(res);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int _nc_Synchronize_Attributes(FIELD * field)
+|
+| Description : If a fields visual attributes have changed, this
+| routine is called to propagate those changes to the
+| screen.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid field pointer
+| E_SYSTEM_ERROR - some severe basic error
++--------------------------------------------------------------------------*/
+int _nc_Synchronize_Attributes(FIELD * field)
+{
+ FORM *form;
+ int res = E_OK;
+ WINDOW *formwin;
+
+ if (!field)
+ return(E_BAD_ARGUMENT);
+
+ if (((form=field->form) != (FORM *)0)
+ && Field_Really_Appears(field))
+ {
+ if (form->current==field)
+ {
+ Synchronize_Buffer(form);
+ Set_Field_Window_Attributes(field,form->w);
+ werase(form->w);
+ if (field->opts & O_PUBLIC)
+ {
+ if (Justification_Allowed(field))
+ Undo_Justification(field,form->w);
+ else
+ Buffer_To_Window(field,form->w);
+ }
+ else
+ {
+ formwin = Get_Form_Window(form);
+ copywin(form->w,formwin,
+ 0,0,
+ field->frow,field->fcol,
+ field->rows-1,field->cols-1,0);
+ wsyncup(formwin);
+ Buffer_To_Window(field,form->w);
+ field->status |= _NEWTOP; /* fake refresh to paint all */
+ _nc_Refresh_Current_Field(form);
+ }
+ }
+ else
+ {
+ res = Display_Field(field);
+ }
+ }
+ return(res);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int _nc_Synchronize_Options(FIELD * field,
+| Field_Options newopts)
+|
+| Description : If a fields options have changed, this routine is
+| called to propagate these changes to the screen and
+| to really change the behaviour of the field.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid field pointer
+| E_SYSTEM_ERROR - some severe basic error
++--------------------------------------------------------------------------*/
+int
+_nc_Synchronize_Options(FIELD *field, Field_Options newopts)
+{
+ Field_Options oldopts;
+ Field_Options changed_opts;
+ FORM *form;
+ int res = E_OK;
+
+ if (!field)
+ return(E_BAD_ARGUMENT);
+
+ oldopts = field->opts;
+ changed_opts = oldopts ^ newopts;
+ field->opts = newopts;
+ form = field->form;
+
+ if (form)
+ {
+ if (form->current == field)
+ {
+ field->opts = oldopts;
+ return(E_CURRENT);
+ }
+
+ if (form->status & _POSTED)
+ {
+ if (form->curpage == field->page)
+ {
+ if (changed_opts & O_VISIBLE)
+ {
+ if (newopts & O_VISIBLE)
+ res = Display_Field(field);
+ else
+ res = Erase_Field(field);
+ }
+ else
+ {
+ if ((changed_opts & O_PUBLIC) &&
+ (newopts & O_VISIBLE))
+ res = Display_Field(field);
+ }
+ }
+ }
+ }
+
+ if (changed_opts & O_STATIC)
+ {
+ bool single_line_field = Single_Line_Field(field);
+ int res2 = E_OK;
+
+ if (newopts & O_STATIC)
+ { /* the field becomes now static */
+ field->status &= ~_MAY_GROW;
+ /* if actually we have no hidden columns, justification may
+ occur again */
+ if (single_line_field &&
+ (field->cols == field->dcols) &&
+ (field->just != NO_JUSTIFICATION) &&
+ Field_Really_Appears(field))
+ {
+ res2 = Display_Field(field);
+ }
+ }
+ else
+ { /* field is no longer static */
+ if ((field->maxgrow==0) ||
+ ( single_line_field && (field->dcols < field->maxgrow)) ||
+ (!single_line_field && (field->drows < field->maxgrow)))
+ {
+ field->status |= _MAY_GROW;
+ /* a field with justification now changes its behaviour,
+ so we must redisplay it */
+ if (single_line_field &&
+ (field->just != NO_JUSTIFICATION) &&
+ Field_Really_Appears(field))
+ {
+ res2 = Display_Field(field);
+ }
+ }
+ }
+ if (res2 != E_OK)
+ res = res2;
+ }
+
+ return(res);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int _nc_Set_Current_Field(FORM * form,
+| FIELD * newfield)
+|
+| Description : Make the newfield the new current field.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid form or field pointer
+| E_SYSTEM_ERROR - some severe basic error
++--------------------------------------------------------------------------*/
+int
+_nc_Set_Current_Field(FORM *form, FIELD *newfield)
+{
+ FIELD *field;
+ WINDOW *new_window;
+
+ if (!form || !newfield || !form->current || (newfield->form!=form))
+ return(E_BAD_ARGUMENT);
+
+ if ( (form->status & _IN_DRIVER) )
+ return(E_BAD_STATE);
+
+ if (!(form->field))
+ return(E_NOT_CONNECTED);
+
+ field = form->current;
+
+ if ((field!=newfield) ||
+ !(form->status & _POSTED))
+ {
+ if ((form->w) &&
+ (field->opts & O_VISIBLE) &&
+ (field->form->curpage == field->page))
+ {
+ _nc_Refresh_Current_Field(form);
+ if (field->opts & O_PUBLIC)
+ {
+ if (field->drows > field->rows)
+ {
+ if (form->toprow==0)
+ field->status &= ~_NEWTOP;
+ else
+ field->status |= _NEWTOP;
+ }
+ else
+ {
+ if (Justification_Allowed(field))
+ {
+ Window_To_Buffer(form->w,field);
+ werase(form->w);
+ Perform_Justification(field,form->w);
+ wsyncup(form->w);
+ }
+ }
+ }
+ delwin(form->w);
+ }
+
+ field = newfield;
+
+ if (Has_Invisible_Parts(field))
+ new_window = newpad(field->drows,field->dcols);
+ else
+ new_window = derwin(Get_Form_Window(form),
+ field->rows,field->cols,field->frow,field->fcol);
+
+ if (!new_window)
+ return(E_SYSTEM_ERROR);
+
+ form->current = field;
+ form->w = new_window;
+ form->status &= ~_WINDOW_MODIFIED;
+ Set_Field_Window_Attributes(field,form->w);
+
+ if (Has_Invisible_Parts(field))
+ {
+ werase(form->w);
+ Buffer_To_Window(field,form->w);
+ }
+ else
+ {
+ if (Justification_Allowed(field))
+ {
+ werase(form->w);
+ Undo_Justification(field,form->w);
+ wsyncup(form->w);
+ }
+ }
+
+ untouchwin(form->w);
+ }
+
+ form->currow = form->curcol = form->toprow = form->begincol = 0;
+ return(E_OK);
+}
+
+/*----------------------------------------------------------------------------
+ Intra-Field Navigation routines
+ --------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int IFN_Next_Character(FORM * form)
+|
+| Description : Move to the next character in the field. In a multiline
+| field this wraps at the end of the line.
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - at the rightmost position
++--------------------------------------------------------------------------*/
+static int IFN_Next_Character(FORM * form)
+{
+ FIELD *field = form->current;
+
+ if ((++(form->curcol))==field->dcols)
+ {
+ if ((++(form->currow))==field->drows)
+ {
+#if GROW_IF_NAVIGATE
+ if (!Single_Line_Field(field) && Field_Grown(field,1)) {
+ form->curcol = 0;
+ return(E_OK);
+ }
+#endif
+ form->currow--;
+#if GROW_IF_NAVIGATE
+ if (Single_Line_Field(field) && Field_Grown(field,1))
+ return(E_OK);
+#endif
+ form->curcol--;
+ return(E_REQUEST_DENIED);
+ }
+ form->curcol = 0;
+ }
+ return(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int IFN_Previous_Character(FORM * form)
+|
+| Description : Move to the previous character in the field. In a
+| multiline field this wraps and the beginning of the
+| line.
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - at the leftmost position
++--------------------------------------------------------------------------*/
+static int IFN_Previous_Character(FORM * form)
+{
+ if ((--(form->curcol))<0)
+ {
+ if ((--(form->currow))<0)
+ {
+ form->currow++;
+ form->curcol++;
+ return(E_REQUEST_DENIED);
+ }
+ form->curcol = form->current->dcols - 1;
+ }
+ return(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int IFN_Next_Line(FORM * form)
+|
+| Description : Move to the beginning of the next line in the field
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - at the last line
++--------------------------------------------------------------------------*/
+static int IFN_Next_Line(FORM * form)
+{
+ FIELD *field = form->current;
+
+ if ((++(form->currow))==field->drows)
+ {
+#if GROW_IF_NAVIGATE
+ if (!Single_Line_Field(field) && Field_Grown(field,1))
+ return(E_OK);
+#endif
+ form->currow--;
+ return(E_REQUEST_DENIED);
+ }
+ form->curcol = 0;
+ return(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int IFN_Previous_Line(FORM * form)
+|
+| Description : Move to the beginning of the previous line in the field
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - at the first line
++--------------------------------------------------------------------------*/
+static int IFN_Previous_Line(FORM * form)
+{
+ if ( (--(form->currow)) < 0 )
+ {
+ form->currow++;
+ return(E_REQUEST_DENIED);
+ }
+ form->curcol = 0;
+ return(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int IFN_Next_Word(FORM * form)
+|
+| Description : Move to the beginning of the next word in the field.
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - there is no next word
++--------------------------------------------------------------------------*/
+static int IFN_Next_Word(FORM * form)
+{
+ FIELD *field = form->current;
+ char *bp = Address_Of_Current_Position_In_Buffer(form);
+ char *s;
+ char *t;
+
+ /* We really need access to the data, so we have to synchronize */
+ Synchronize_Buffer(form);
+
+ /* Go to the first whitespace after the current position (including
+ current position). This is then the startpoint to look for the
+ next non-blank data */
+ s = Get_First_Whitespace_Character(bp,Buffer_Length(field) -
+ (int)(bp - field->buf));
+
+ /* Find the start of the next word */
+ t = Get_Start_Of_Data(s,Buffer_Length(field) -
+ (int)(s - field->buf));
+#if !FRIENDLY_PREV_NEXT_WORD
+ if (s==t)
+ return(E_REQUEST_DENIED);
+ else
+#endif
+ {
+ Adjust_Cursor_Position(form,t);
+ return(E_OK);
+ }
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int IFN_Previous_Word(FORM * form)
+|
+| Description : Move to the beginning of the previous word in the field.
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - there is no previous word
++--------------------------------------------------------------------------*/
+static int IFN_Previous_Word(FORM * form)
+{
+ FIELD *field = form->current;
+ char *bp = Address_Of_Current_Position_In_Buffer(form);
+ char *s;
+ char *t;
+ bool again = FALSE;
+
+ /* We really need access to the data, so we have to synchronize */
+ Synchronize_Buffer(form);
+
+ s = After_End_Of_Data(field->buf,(int)(bp-field->buf));
+ /* s points now right after the last non-blank in the buffer before bp.
+ If bp was in a word, s equals bp. In this case we must find the last
+ whitespace in the buffer before bp and repeat the game to really find
+ the previous word! */
+ if (s==bp)
+ again = TRUE;
+
+ /* And next call now goes backward to look for the last whitespace
+ before that, pointing right after this, so it points to the begin
+ of the previous word.
+ */
+ t = After_Last_Whitespace_Character(field->buf,(int)(s - field->buf));
+#if !FRIENDLY_PREV_NEXT_WORD
+ if (s==t)
+ return(E_REQUEST_DENIED);
+#endif
+ if (again)
+ { /* and do it again, replacing bp by t */
+ s = After_End_Of_Data(field->buf,(int)(t - field->buf));
+ t = After_Last_Whitespace_Character(field->buf,(int)(s - field->buf));
+#if !FRIENDLY_PREV_NEXT_WORD
+ if (s==t)
+ return(E_REQUEST_DENIED);
+#endif
+ }
+ Adjust_Cursor_Position(form,t);
+ return(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int IFN_Beginning_Of_Field(FORM * form)
+|
+| Description : Place the cursor at the first non-pad character in
+| the field.
+|
+| Return Values : E_OK - success
++--------------------------------------------------------------------------*/
+static int IFN_Beginning_Of_Field(FORM * form)
+{
+ FIELD *field = form->current;
+
+ Synchronize_Buffer(form);
+ Adjust_Cursor_Position(form,
+ Get_Start_Of_Data(field->buf,Buffer_Length(field)));
+ return(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int IFN_End_Of_Field(FORM * form)
+|
+| Description : Place the cursor after the last non-pad character in
+| the field. If the field occupies the last position in
+| the buffer, the cursos is positioned on the last
+| character.
+|
+| Return Values : E_OK - success
++--------------------------------------------------------------------------*/
+static int IFN_End_Of_Field(FORM * form)
+{
+ FIELD *field = form->current;
+ char *pos;
+
+ Synchronize_Buffer(form);
+ pos = After_End_Of_Data(field->buf,Buffer_Length(field));
+ if (pos==(field->buf + Buffer_Length(field)))
+ pos--;
+ Adjust_Cursor_Position(form,pos);
+ return(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int IFN_Beginning_Of_Line(FORM * form)
+|
+| Description : Place the cursor on the first non-pad character in
+| the current line of the field.
+|
+| Return Values : E_OK - success
++--------------------------------------------------------------------------*/
+static int IFN_Beginning_Of_Line(FORM * form)
+{
+ FIELD *field = form->current;
+
+ Synchronize_Buffer(form);
+ Adjust_Cursor_Position(form,
+ Get_Start_Of_Data(Address_Of_Current_Row_In_Buffer(form),
+ field->dcols));
+ return(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int IFN_End_Of_Line(FORM * form)
+|
+| Description : Place the cursor after the last non-pad character in the
+| current line of the field. If the field occupies the
+| last column in the line, the cursor is positioned on the
+| last character of the line.
+|
+| Return Values : E_OK - success
++--------------------------------------------------------------------------*/
+static int IFN_End_Of_Line(FORM * form)
+{
+ FIELD *field = form->current;
+ char *pos;
+ char *bp;
+
+ Synchronize_Buffer(form);
+ bp = Address_Of_Current_Row_In_Buffer(form);
+ pos = After_End_Of_Data(bp,field->dcols);
+ if (pos == (bp + field->dcols))
+ pos--;
+ Adjust_Cursor_Position(form,pos);
+ return(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int IFN_Left_Character(FORM * form)
+|
+| Description : Move one character to the left in the current line.
+| This doesn't cycle.
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - already in first column
++--------------------------------------------------------------------------*/
+static int IFN_Left_Character(FORM * form)
+{
+ if ( (--(form->curcol)) < 0 )
+ {
+ form->curcol++;
+ return(E_REQUEST_DENIED);
+ }
+ return(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int IFN_Right_Character(FORM * form)
+|
+| Description : Move one character to the right in the current line.
+| This doesn't cycle.
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - already in last column
++--------------------------------------------------------------------------*/
+static int IFN_Right_Character(FORM * form)
+{
+ if ( (++(form->curcol)) == form->current->dcols )
+ {
+#if GROW_IF_NAVIGATE
+ FIELD *field = form->current;
+ if (Single_Line_Field(field) && Field_Grown(field,1))
+ return(E_OK);
+#endif
+ --(form->curcol);
+ return(E_REQUEST_DENIED);
+ }
+ return(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int IFN_Up_Character(FORM * form)
+|
+| Description : Move one line up. This doesn't cycle through the lines
+| of the field.
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - already in last column
++--------------------------------------------------------------------------*/
+static int IFN_Up_Character(FORM * form)
+{
+ if ( (--(form->currow)) < 0 )
+ {
+ form->currow++;
+ return(E_REQUEST_DENIED);
+ }
+ return(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int IFN_Down_Character(FORM * form)
+|
+| Description : Move one line down. This doesn't cycle through the
+| lines of the field.
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - already in last column
++--------------------------------------------------------------------------*/
+static int IFN_Down_Character(FORM * form)
+{
+ FIELD *field = form->current;
+
+ if ( (++(form->currow)) == field->drows )
+ {
+#if GROW_IF_NAVIGATE
+ if (!Single_Line_Field(field) && Field_Grown(field,1))
+ return(E_OK);
+#endif
+ --(form->currow);
+ return(E_REQUEST_DENIED);
+ }
+ return(E_OK);
+}
+/*----------------------------------------------------------------------------
+ END of Intra-Field Navigation routines
+ --------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ Vertical scrolling helper routines
+ --------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int VSC_Generic(FORM *form, int lines)
+|
+| Description : Scroll multi-line field forward (lines>0) or
+| backward (lines<0) this many lines.
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - can't scroll
++--------------------------------------------------------------------------*/
+static int VSC_Generic(FORM *form, int lines)
+{
+ FIELD *field = form->current;
+ int res = E_REQUEST_DENIED;
+ int rows_to_go = (lines > 0 ? lines : -lines);
+
+ if (lines > 0)
+ {
+ if ( (rows_to_go + form->toprow) > (field->drows - field->rows) )
+ rows_to_go = (field->drows - field->rows - form->toprow);
+
+ if (rows_to_go > 0)
+ {
+ form->currow += rows_to_go;
+ form->toprow += rows_to_go;
+ res = E_OK;
+ }
+ }
+ else
+ {
+ if (rows_to_go > form->toprow)
+ rows_to_go = form->toprow;
+
+ if (rows_to_go > 0)
+ {
+ form->currow -= rows_to_go;
+ form->toprow -= rows_to_go;
+ res = E_OK;
+ }
+ }
+ return(res);
+}
+/*----------------------------------------------------------------------------
+ End of Vertical scrolling helper routines
+ --------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ Vertical scrolling routines
+ --------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int Vertical_Scrolling(
+| int (* const fct) (FORM *),
+| FORM * form)
+|
+| Description : Performs the generic vertical scrolling routines.
+| This has to check for a multi-line field and to set
+| the _NEWTOP flag if scrolling really occured.
+|
+| Return Values : Propagated error code from low-level driver calls
++--------------------------------------------------------------------------*/
+static int Vertical_Scrolling(int (* const fct) (FORM *), FORM * form)
+{
+ int res = E_REQUEST_DENIED;
+
+ if (!Single_Line_Field(form->current))
+ {
+ res = fct(form);
+ if (res == E_OK)
+ form->current->status |= _NEWTOP;
+ }
+ return(res);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int VSC_Scroll_Line_Forward(FORM * form)
+|
+| Description : Scroll multi-line field forward a line
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - no data ahead
++--------------------------------------------------------------------------*/
+static int VSC_Scroll_Line_Forward(FORM * form)
+{
+ return VSC_Generic(form,1);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int VSC_Scroll_Line_Backward(FORM * form)
+|
+| Description : Scroll multi-line field backward a line
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - no data behind
++--------------------------------------------------------------------------*/
+static int VSC_Scroll_Line_Backward(FORM * form)
+{
+ return VSC_Generic(form,-1);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int VSC_Scroll_Page_Forward(FORM * form)
+|
+| Description : Scroll a multi-line field forward a page
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - no data ahead
++--------------------------------------------------------------------------*/
+static int VSC_Scroll_Page_Forward(FORM * form)
+{
+ return VSC_Generic(form,form->current->rows);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int VSC_Scroll_Half_Page_Forward(FORM * form)
+|
+| Description : Scroll a multi-line field forward half a page
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - no data ahead
++--------------------------------------------------------------------------*/
+static int VSC_Scroll_Half_Page_Forward(FORM * form)
+{
+ return VSC_Generic(form,(form->current->rows + 1)/2);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int VSC_Scroll_Page_Backward(FORM * form)
+|
+| Description : Scroll a multi-line field backward a page
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - no data behind
++--------------------------------------------------------------------------*/
+static int VSC_Scroll_Page_Backward(FORM * form)
+{
+ return VSC_Generic(form, -(form->current->rows));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int VSC_Scroll_Half_Page_Backward(FORM * form)
+|
+| Description : Scroll a multi-line field backward half a page
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - no data behind
++--------------------------------------------------------------------------*/
+static int VSC_Scroll_Half_Page_Backward(FORM * form)
+{
+ return VSC_Generic(form, -((form->current->rows + 1)/2));
+}
+/*----------------------------------------------------------------------------
+ End of Vertical scrolling routines
+ --------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ Horizontal scrolling helper routines
+ --------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int HSC_Generic(FORM *form, int columns)
+|
+| Description : Scroll single-line field forward (columns>0) or
+| backward (columns<0) this many columns.
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - can't scroll
++--------------------------------------------------------------------------*/
+static int HSC_Generic(FORM *form, int columns)
+{
+ FIELD *field = form->current;
+ int res = E_REQUEST_DENIED;
+ int cols_to_go = (columns > 0 ? columns : -columns);
+
+ if (columns > 0)
+ {
+ if ((cols_to_go + form->begincol) > (field->dcols - field->cols))
+ cols_to_go = field->dcols - field->cols - form->begincol;
+
+ if (cols_to_go > 0)
+ {
+ form->curcol += cols_to_go;
+ form->begincol += cols_to_go;
+ res = E_OK;
+ }
+ }
+ else
+ {
+ if ( cols_to_go > form->begincol )
+ cols_to_go = form->begincol;
+
+ if (cols_to_go > 0)
+ {
+ form->curcol -= cols_to_go;
+ form->begincol -= cols_to_go;
+ res = E_OK;
+ }
+ }
+ return(res);
+}
+/*----------------------------------------------------------------------------
+ End of Horizontal scrolling helper routines
+ --------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ Horizontal scrolling routines
+ --------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int Horizontal_Scrolling(
+| int (* const fct) (FORM *),
+| FORM * form)
+|
+| Description : Performs the generic horizontal scrolling routines.
+| This has to check for a single-line field.
+|
+| Return Values : Propagated error code from low-level driver calls
++--------------------------------------------------------------------------*/
+static int Horizontal_Scrolling(int (* const fct) (FORM *), FORM * form)
+{
+ if (Single_Line_Field(form->current))
+ return fct(form);
+ else
+ return(E_REQUEST_DENIED);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int HSC_Scroll_Char_Forward(FORM * form)
+|
+| Description : Scroll single-line field forward a character
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - no data ahead
++--------------------------------------------------------------------------*/
+static int HSC_Scroll_Char_Forward(FORM *form)
+{
+ return HSC_Generic(form,1);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int HSC_Scroll_Char_Backward(FORM * form)
+|
+| Description : Scroll single-line field backward a character
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - no data behind
++--------------------------------------------------------------------------*/
+static int HSC_Scroll_Char_Backward(FORM *form)
+{
+ return HSC_Generic(form,-1);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int HSC_Horizontal_Line_Forward(FORM* form)
+|
+| Description : Scroll single-line field forward a line
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - no data ahead
++--------------------------------------------------------------------------*/
+static int HSC_Horizontal_Line_Forward(FORM * form)
+{
+ return HSC_Generic(form,form->current->cols);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int HSC_Horizontal_Half_Line_Forward(FORM* form)
+|
+| Description : Scroll single-line field forward half a line
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - no data ahead
++--------------------------------------------------------------------------*/
+static int HSC_Horizontal_Half_Line_Forward(FORM * form)
+{
+ return HSC_Generic(form,(form->current->cols + 1)/2);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int HSC_Horizontal_Line_Backward(FORM* form)
+|
+| Description : Scroll single-line field backward a line
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - no data behind
++--------------------------------------------------------------------------*/
+static int HSC_Horizontal_Line_Backward(FORM * form)
+{
+ return HSC_Generic(form,-(form->current->cols));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int HSC_Horizontal_Half_Line_Backward(FORM* form)
+|
+| Description : Scroll single-line field backward half a line
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - no data behind
++--------------------------------------------------------------------------*/
+static int HSC_Horizontal_Half_Line_Backward(FORM * form)
+{
+ return HSC_Generic(form,-((form->current->cols + 1)/2));
+}
+
+/*----------------------------------------------------------------------------
+ End of Horizontal scrolling routines
+ --------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ Helper routines for Field Editing
+ --------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Is_There_Room_For_A_Line(FORM * form)
+|
+| Description : Check whether or not there is enough room in the
+| buffer to enter a whole line.
+|
+| Return Values : TRUE - there is enough space
+| FALSE - there is not enough space
++--------------------------------------------------------------------------*/
+INLINE static bool Is_There_Room_For_A_Line(FORM * form)
+{
+ FIELD *field = form->current;
+ char *begin_of_last_line, *s;
+
+ Synchronize_Buffer(form);
+ begin_of_last_line = Address_Of_Row_In_Buffer(field,(field->drows-1));
+ s = After_End_Of_Data(begin_of_last_line,field->dcols);
+ return ((s==begin_of_last_line) ? TRUE : FALSE);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Is_There_Room_For_A_Char_In_Line(FORM * form)
+|
+| Description : Checks whether or not there is room for a new character
+| in the current line.
+|
+| Return Values : TRUE - there is room
+| FALSE - there is not enough room (line full)
++--------------------------------------------------------------------------*/
+INLINE static bool Is_There_Room_For_A_Char_In_Line(FORM * form)
+{
+ int last_char_in_line;
+
+ wmove(form->w,form->currow,form->current->dcols-1);
+ last_char_in_line = (int)(winch(form->w) & A_CHARTEXT);
+ wmove(form->w,form->currow,form->curcol);
+ return (((last_char_in_line == form->current->pad) ||
+ is_blank(last_char_in_line)) ? TRUE : FALSE);
+}
+
+#define There_Is_No_Room_For_A_Char_In_Line(f) \
+ !Is_There_Room_For_A_Char_In_Line(f)
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int Insert_String(
+| FORM * form,
+| int row,
+| char *txt,
+| int len )
+|
+| Description : Insert the 'len' characters beginning at pointer 'txt'
+| into the 'row' of the 'form'. The insertion occurs
+| on the beginning of the row, all other characters are
+| moved to the right. After the text a pad character will
+| be inserted to separate the text from the rest. If
+| necessary the insertion moves characters on the next
+| line to make place for the requested insertion string.
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED -
+| E_SYSTEM_ERROR - system error
++--------------------------------------------------------------------------*/
+static int Insert_String(FORM *form, int row, char *txt, int len)
+{
+ FIELD *field = form->current;
+ char *bp = Address_Of_Row_In_Buffer(field,row);
+ int datalen = (int)(After_End_Of_Data(bp,field->dcols) - bp);
+ int freelen = field->dcols - datalen;
+ int requiredlen = len+1;
+ char *split;
+ int result = E_REQUEST_DENIED;
+ char *Space;
+
+ Space = (char*)malloc(2*sizeof(char));
+ strcpy(Space, " ");
+
+ if (freelen >= requiredlen)
+ {
+ wmove(form->w,row,0);
+ winsnstr(form->w,txt,len);
+ wmove(form->w,row,len);
+ winsnstr(form->w,Space,1);
+ free(Space);
+ return E_OK;
+ }
+ else
+ { /* we have to move characters on the next line. If we are on the
+ last line this may work, if the field is growable */
+ if ((row == (field->drows - 1)) && Growable(field))
+ {
+ if (!Field_Grown(field,1))
+ {
+ free(Space);
+ return(E_SYSTEM_ERROR);
+ }
+ /* !!!Side-Effect : might be changed due to growth!!! */
+ bp = Address_Of_Row_In_Buffer(field,row);
+ }
+
+ if (row < (field->drows - 1))
+ {
+ split = After_Last_Whitespace_Character(bp,
+ (int)(Get_Start_Of_Data(bp + field->dcols - requiredlen ,
+ requiredlen) - bp));
+ /* split points now to the first character of the portion of the
+ line that must be moved to the next line */
+ datalen = (int)(split-bp); /* + freelen has to stay on this line */
+ freelen = field->dcols - (datalen + freelen); /* for the next line */
+
+ if ((result=Insert_String(form,row+1,split,freelen))==E_OK)
+ {
+ wmove(form->w,row,datalen);
+ wclrtoeol(form->w);
+ wmove(form->w,row,0);
+ winsnstr(form->w,txt,len);
+ wmove(form->w,row,len);
+ winsnstr(form->w,Space,1);
+ free(Space);
+ return E_OK;
+ }
+ }
+ free(Space);
+ return(result);
+ }
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int Wrapping_Not_Necessary_Or_Wrapping_Ok(
+| FORM * form)
+|
+| Description : If a character has been entered into a field, it may
+| be that wrapping has to occur. This routine checks
+| whether or not wrapping is required and if so, performs
+| the wrapping.
+|
+| Return Values : E_OK - no wrapping required or wrapping
+| was successfull
+| E_REQUEST_DENIED -
+| E_SYSTEM_ERROR - some system error
++--------------------------------------------------------------------------*/
+static int Wrapping_Not_Necessary_Or_Wrapping_Ok(FORM * form)
+{
+ FIELD *field = form->current;
+ int result = E_REQUEST_DENIED;
+ bool Last_Row = ((field->drows - 1) == form->currow);
+
+ if ( (field->opts & O_WRAP) && /* wrapping wanted */
+ (!Single_Line_Field(field)) && /* must be multi-line */
+ (There_Is_No_Room_For_A_Char_In_Line(form)) && /* line is full */
+ (!Last_Row || Growable(field)) ) /* there are more lines*/
+ {
+ char *bp;
+ char *split;
+ int chars_to_be_wrapped;
+ int chars_to_remain_on_line;
+ if (Last_Row)
+ { /* the above logic already ensures, that in this case the field
+ is growable */
+ if (!Field_Grown(field,1))
+ return E_SYSTEM_ERROR;
+ }
+ bp = Address_Of_Current_Row_In_Buffer(form);
+ Window_To_Buffer(form->w,field);
+ split = After_Last_Whitespace_Character(bp,field->dcols);
+ /* split points to the first character of the sequence to be brought
+ on the next line */
+ chars_to_remain_on_line = (int)(split - bp);
+ chars_to_be_wrapped = field->dcols - chars_to_remain_on_line;
+ if (chars_to_remain_on_line > 0)
+ {
+ if ((result=Insert_String(form,form->currow+1,split,
+ chars_to_be_wrapped)) == E_OK)
+ {
+ wmove(form->w,form->currow,chars_to_remain_on_line);
+ wclrtoeol(form->w);
+ if (form->curcol >= chars_to_remain_on_line)
+ {
+ form->currow++;
+ form->curcol -= chars_to_remain_on_line;
+ }
+ return E_OK;
+ }
+ }
+ else
+ return E_OK;
+ if (result!=E_OK)
+ {
+ wmove(form->w,form->currow,form->curcol);
+ wdelch(form->w);
+ Window_To_Buffer(form->w,field);
+ result = E_REQUEST_DENIED;
+ }
+ }
+ else
+ result = E_OK; /* wrapping was not necessary */
+ return(result);
+}
+
+/*----------------------------------------------------------------------------
+ Field Editing routines
+ --------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int Field_Editing(
+| int (* const fct) (FORM *),
+| FORM * form)
+|
+| Description : Generic routine for field editing requests. The driver
+| routines are only called for editable fields, the
+| _WINDOW_MODIFIED flag is set if editing occured.
+| This is somewhat special due to the overload semantics
+| of the NEW_LINE and DEL_PREV requests.
+|
+| Return Values : Error code from low level drivers.
++--------------------------------------------------------------------------*/
+static int Field_Editing(int (* const fct) (FORM *), FORM * form)
+{
+ int res = E_REQUEST_DENIED;
+
+ /* We have to deal here with the specific case of the overloaded
+ behaviour of New_Line and Delete_Previous requests.
+ They may end up in navigational requests if we are on the first
+ character in a field. But navigation is also allowed on non-
+ editable fields.
+ */
+ if ((fct==FE_Delete_Previous) &&
+ (form->opts & O_BS_OVERLOAD) &&
+ First_Position_In_Current_Field(form) )
+ {
+ res = Inter_Field_Navigation(FN_Previous_Field,form);
+ }
+ else
+ {
+ if (fct==FE_New_Line)
+ {
+ if ((form->opts & O_NL_OVERLOAD) &&
+ First_Position_In_Current_Field(form))
+ {
+ res = Inter_Field_Navigation(FN_Next_Field,form);
+ }
+ else
+ /* FE_New_Line deals itself with the _WINDOW_MODIFIED flag */
+ res = fct(form);
+ }
+ else
+ {
+ /* From now on, everything must be editable */
+ if (form->current->opts & O_EDIT)
+ {
+ res = fct(form);
+ if (res==E_OK)
+ form->status |= _WINDOW_MODIFIED;
+ }
+ }
+ }
+ return res;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FE_New_Line(FORM * form)
+|
+| Description : Perform a new line request. This is rather complex
+| compared to other routines in this code due to the
+| rather difficult to understand description in the
+| manuals.
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - new line not allowed
+| E_SYSTEM_ERROR - system error
++--------------------------------------------------------------------------*/
+static int FE_New_Line(FORM * form)
+{
+ FIELD *field = form->current;
+ char *bp, *t;
+ bool Last_Row = ((field->drows - 1)==form->currow);
+
+ if (form->status & _OVLMODE)
+ {
+ if (Last_Row &&
+ (!(Growable(field) && !Single_Line_Field(field))))
+ {
+ if (!(form->opts & O_NL_OVERLOAD))
+ return(E_REQUEST_DENIED);
+ wclrtoeol(form->w);
+ /* we have to set this here, although it is also
+ handled in the generic routine. The reason is,
+ that FN_Next_Field may fail, but the form is
+ definitively changed */
+ form->status |= _WINDOW_MODIFIED;
+ return Inter_Field_Navigation(FN_Next_Field,form);
+ }
+ else
+ {
+ if (Last_Row && !Field_Grown(field,1))
+ { /* N.B.: due to the logic in the 'if', LastRow==TRUE
+ means here that the field is growable and not
+ a single-line field */
+ return(E_SYSTEM_ERROR);
+ }
+ wclrtoeol(form->w);
+ form->currow++;
+ form->curcol = 0;
+ form->status |= _WINDOW_MODIFIED;
+ return(E_OK);
+ }
+ }
+ else
+ { /* Insert Mode */
+ if (Last_Row &&
+ !(Growable(field) && !Single_Line_Field(field)))
+ {
+ if (!(form->opts & O_NL_OVERLOAD))
+ return(E_REQUEST_DENIED);
+ return Inter_Field_Navigation(FN_Next_Field,form);
+ }
+ else
+ {
+ bool May_Do_It = !Last_Row && Is_There_Room_For_A_Line(form);
+
+ if (!(May_Do_It || Growable(field)))
+ return(E_REQUEST_DENIED);
+ if (!May_Do_It && !Field_Grown(field,1))
+ return(E_SYSTEM_ERROR);
+
+ bp= Address_Of_Current_Position_In_Buffer(form);
+ t = After_End_Of_Data(bp,field->dcols - form->curcol);
+ wclrtoeol(form->w);
+ form->currow++;
+ form->curcol=0;
+ wmove(form->w,form->currow,form->curcol);
+ winsertln(form->w);
+ waddnstr(form->w,bp,(int)(t-bp));
+ form->status |= _WINDOW_MODIFIED;
+ return E_OK;
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FE_Insert_Character(FORM * form)
+|
+| Description : Insert blank character at the cursor position
+|
+| Return Values : E_OK
+| E_REQUEST_DENIED
++--------------------------------------------------------------------------*/
+static int FE_Insert_Character(FORM * form)
+{
+ FIELD *field = form->current;
+ int result = E_REQUEST_DENIED;
+
+ if (Check_Char(field->type,(int)C_BLANK,(TypeArgument *)(field->arg)))
+ {
+ bool There_Is_Room = Is_There_Room_For_A_Char_In_Line(form);
+
+ if (There_Is_Room ||
+ ((Single_Line_Field(field) && Growable(field))))
+ {
+ if (!There_Is_Room && !Field_Grown(field,1))
+ result = E_SYSTEM_ERROR;
+ else
+ {
+ winsch(form->w,(chtype)C_BLANK);
+ result = Wrapping_Not_Necessary_Or_Wrapping_Ok(form);
+ }
+ }
+ }
+ return result;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FE_Insert_Line(FORM * form)
+|
+| Description : Insert a blank line at the cursor position
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - line can not be inserted
++--------------------------------------------------------------------------*/
+static int FE_Insert_Line(FORM * form)
+{
+ FIELD *field = form->current;
+ int result = E_REQUEST_DENIED;
+
+ if (Check_Char(field->type,(int)C_BLANK,(TypeArgument *)(field->arg)))
+ {
+ bool Maybe_Done = (form->currow!=(field->drows-1)) &&
+ Is_There_Room_For_A_Line(form);
+
+ if (!Single_Line_Field(field) &&
+ (Maybe_Done || Growable(field)))
+ {
+ if (!Maybe_Done && !Field_Grown(field,1))
+ result = E_SYSTEM_ERROR;
+ else
+ {
+ form->curcol = 0;
+ winsertln(form->w);
+ result = E_OK;
+ }
+ }
+ }
+ return result;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FE_Delete_Character(FORM * form)
+|
+| Description : Delete character at the cursor position
+|
+| Return Values : E_OK - success
++--------------------------------------------------------------------------*/
+static int FE_Delete_Character(FORM * form)
+{
+ wdelch(form->w);
+ return E_OK;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FE_Delete_Previous(FORM * form)
+|
+| Description : Delete character before cursor. Again this is a rather
+| difficult piece compared to others due to the overloading
+| semantics of backspace.
+| N.B.: The case of overloaded BS on first field position
+| is already handled in the generic routine.
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - Character can't be deleted
++--------------------------------------------------------------------------*/
+static int FE_Delete_Previous(FORM * form)
+{
+ FIELD *field = form->current;
+
+ if (First_Position_In_Current_Field(form))
+ return E_REQUEST_DENIED;
+
+ if ( (--(form->curcol))<0 )
+ {
+ char *this_line, *prev_line, *prev_end, *this_end;
+
+ form->curcol++;
+ if (form->status & _OVLMODE)
+ return E_REQUEST_DENIED;
+
+ prev_line = Address_Of_Row_In_Buffer(field,(form->currow-1));
+ this_line = Address_Of_Row_In_Buffer(field,(form->currow));
+ Synchronize_Buffer(form);
+ prev_end = After_End_Of_Data(prev_line,field->dcols);
+ this_end = After_End_Of_Data(this_line,field->dcols);
+ if ((int)(this_end-this_line) >
+ (field->cols-(int)(prev_end-prev_line)))
+ return E_REQUEST_DENIED;
+ wdeleteln(form->w);
+ Adjust_Cursor_Position(form,prev_end);
+ wmove(form->w,form->currow,form->curcol);
+ waddnstr(form->w,this_line,(int)(this_end-this_line));
+ }
+ else
+ {
+ wmove(form->w,form->currow,form->curcol);
+ wdelch(form->w);
+ }
+ return E_OK;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FE_Delete_Line(FORM * form)
+|
+| Description : Delete line at cursor position.
+|
+| Return Values : E_OK - success
++--------------------------------------------------------------------------*/
+static int FE_Delete_Line(FORM * form)
+{
+ form->curcol = 0;
+ wdeleteln(form->w);
+ return E_OK;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FE_Delete_Word(FORM * form)
+|
+| Description : Delete word at cursor position
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - failure
++--------------------------------------------------------------------------*/
+static int FE_Delete_Word(FORM * form)
+{
+ FIELD *field = form->current;
+ char *bp = Address_Of_Current_Row_In_Buffer(form);
+ char *ep = bp + field->dcols;
+ char *cp = bp + form->curcol;
+ char *s;
+
+ Synchronize_Buffer(form);
+ if (is_blank(*cp))
+ return E_REQUEST_DENIED; /* not in word */
+
+ /* move cursor to begin of word and erase to end of screen-line */
+ Adjust_Cursor_Position(form,
+ After_Last_Whitespace_Character(bp,form->curcol));
+ wmove(form->w,form->currow,form->curcol);
+ wclrtoeol(form->w);
+
+ /* skip over word in buffer */
+ s = Get_First_Whitespace_Character(cp,(int)(ep-cp));
+ /* to begin of next word */
+ s = Get_Start_Of_Data(s,(int)(ep - s));
+ if ( (s!=cp) && !is_blank(*s))
+ {
+ /* copy remaining line to window */
+ waddnstr(form->w,s,(int)(s - After_End_Of_Data(s,(int)(ep - s))));
+ }
+ return E_OK;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FE_Clear_To_End_Of_Line(FORM * form)
+|
+| Description : Clear to end of current line.
+|
+| Return Values : E_OK - success
++--------------------------------------------------------------------------*/
+static int FE_Clear_To_End_Of_Line(FORM * form)
+{
+ wclrtoeol(form->w);
+ return E_OK;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FE_Clear_To_End_Of_Form(FORM * form)
+|
+| Description : Clear to end of form.
+|
+| Return Values : E_OK - success
++--------------------------------------------------------------------------*/
+static int FE_Clear_To_End_Of_Form(FORM * form)
+{
+ wclrtobot(form->w);
+ return E_OK;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FE_Clear_Field(FORM * form)
+|
+| Description : Clear entire field.
+|
+| Return Values : E_OK - success
++--------------------------------------------------------------------------*/
+static int FE_Clear_Field(FORM * form)
+{
+ form->currow = form->curcol = 0;
+ werase(form->w);
+ return E_OK;
+}
+/*----------------------------------------------------------------------------
+ END of Field Editing routines
+ --------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ Edit Mode routines
+ --------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int EM_Overlay_Mode(FORM * form)
+|
+| Description : Switch to overlay mode.
+|
+| Return Values : E_OK - success
++--------------------------------------------------------------------------*/
+static int EM_Overlay_Mode(FORM * form)
+{
+ form->status |= _OVLMODE;
+ return E_OK;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int EM_Insert_Mode(FORM * form)
+|
+| Description : Switch to insert mode
+|
+| Return Values : E_OK - success
++--------------------------------------------------------------------------*/
+static int EM_Insert_Mode(FORM * form)
+{
+ form->status &= ~_OVLMODE;
+ return E_OK;
+}
+
+/*----------------------------------------------------------------------------
+ END of Edit Mode routines
+ --------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ Helper routines for Choice Requests
+ --------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Next_Choice(
+| FIELDTYPE * typ,
+| FIELD * field,
+| TypeArgument *argp)
+|
+| Description : Get the next field choice. For linked types this is
+| done recursively.
+|
+| Return Values : TRUE - next choice successfully retrieved
+| FALSE - couldn't retrieve next choice
++--------------------------------------------------------------------------*/
+static bool Next_Choice(FIELDTYPE * typ, FIELD *field, TypeArgument *argp)
+{
+ if (!typ || !(typ->status & _HAS_CHOICE))
+ return FALSE;
+
+ if (typ->status & _LINKED_TYPE)
+ {
+ assert(argp != 0);
+ return(
+ Next_Choice(typ->left ,field,argp->left) ||
+ Next_Choice(typ->right,field,argp->right) );
+ }
+ else
+ {
+ assert(typ->next != 0);
+ return typ->next(field,(void *)argp);
+ }
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Previous_Choice(
+| FIELDTYPE * typ,
+| FIELD * field,
+| TypeArgument *argp)
+|
+| Description : Get the previous field choice. For linked types this
+| is done recursively.
+|
+| Return Values : TRUE - previous choice successfully retrieved
+| FALSE - couldn't retrieve previous choice
++--------------------------------------------------------------------------*/
+static bool Previous_Choice(FIELDTYPE *typ, FIELD *field, TypeArgument *argp)
+{
+ if (!typ || !(typ->status & _HAS_CHOICE))
+ return FALSE;
+
+ if (typ->status & _LINKED_TYPE)
+ {
+ assert(argp != 0);
+ return(
+ Previous_Choice(typ->left ,field,argp->left) ||
+ Previous_Choice(typ->right,field,argp->right));
+ }
+ else
+ {
+ assert(typ->prev != 0);
+ return typ->prev(field,(void *)argp);
+ }
+}
+/*----------------------------------------------------------------------------
+ End of Helper routines for Choice Requests
+ --------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ Routines for Choice Requests
+ --------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int CR_Next_Choice(FORM * form)
+|
+| Description : Get the next field choice.
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - next choice couldn't be retrieved
++--------------------------------------------------------------------------*/
+static int CR_Next_Choice(FORM * form)
+{
+ FIELD *field = form->current;
+ Synchronize_Buffer(form);
+ return ((Next_Choice(field->type,field,(TypeArgument *)(field->arg))) ?
+ E_OK : E_REQUEST_DENIED);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int CR_Previous_Choice(FORM * form)
+|
+| Description : Get the previous field choice.
+|
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - prev. choice couldn't be retrieved
++--------------------------------------------------------------------------*/
+static int CR_Previous_Choice(FORM * form)
+{
+ FIELD *field = form->current;
+ Synchronize_Buffer(form);
+ return ((Previous_Choice(field->type,field,(TypeArgument *)(field->arg))) ?
+ E_OK : E_REQUEST_DENIED);
+}
+/*----------------------------------------------------------------------------
+ End of Routines for Choice Requests
+ --------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ Helper routines for Field Validations.
+ --------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Check_Field(
+| FIELDTYPE * typ,
+| FIELD * field,
+| TypeArgument * argp)
+|
+| Description : Check the field according to its fieldtype and its
+| actual arguments. For linked fieldtypes this is done
+| recursively.
+|
+| Return Values : TRUE - field is valid
+| FALSE - field is invalid.
++--------------------------------------------------------------------------*/
+static bool Check_Field(FIELDTYPE *typ, FIELD *field, TypeArgument *argp)
+{
+ if (typ)
+ {
+ if (field->opts & O_NULLOK)
+ {
+ char *bp = field->buf;
+ assert(bp != 0);
+ while(is_blank(*bp))
+ { bp++; }
+ if (*bp == '\0')
+ return TRUE;
+ }
+
+ if (typ->status & _LINKED_TYPE)
+ {
+ assert(argp != 0);
+ return(
+ Check_Field(typ->left ,field,argp->left ) ||
+ Check_Field(typ->right,field,argp->right) );
+ }
+ else
+ {
+ if (typ->fcheck)
+ return typ->fcheck(field,(void *)argp);
+ }
+ }
+ return TRUE;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : bool _nc_Internal_Validation(FORM * form )
+|
+| Description : Validate the current field of the form.
+|
+| Return Values : TRUE - field is valid
+| FALSE - field is invalid
++--------------------------------------------------------------------------*/
+bool
+_nc_Internal_Validation(FORM *form)
+{
+ FIELD *field;
+
+ field = form->current;
+
+ Synchronize_Buffer(form);
+ if ((form->status & _FCHECK_REQUIRED) ||
+ (!(field->opts & O_PASSOK)))
+ {
+ if (!Check_Field(field->type,field,(TypeArgument *)(field->arg)))
+ return FALSE;
+ form->status &= ~_FCHECK_REQUIRED;
+ field->status |= _CHANGED;
+ Synchronize_Linked_Fields(field);
+ }
+ return TRUE;
+}
+/*----------------------------------------------------------------------------
+ End of Helper routines for Field Validations.
+ --------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ Routines for Field Validation.
+ --------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FV_Validation(FORM * form)
+|
+| Description : Validate the current field of the form.
+|
+| Return Values : E_OK - field valid
+| E_INVALID_FIELD - field not valid
++--------------------------------------------------------------------------*/
+static int FV_Validation(FORM * form)
+{
+ if (_nc_Internal_Validation(form))
+ return E_OK;
+ else
+ return E_INVALID_FIELD;
+}
+/*----------------------------------------------------------------------------
+ End of routines for Field Validation.
+ --------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ Helper routines for Inter-Field Navigation
+ --------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static FIELD *Next_Field_On_Page(FIELD * field)
+|
+| Description : Get the next field after the given field on the current
+| page. The order of fields is the one defined by the
+| fields array. Only visible and active fields are
+| counted.
+|
+| Return Values : Pointer to the next field.
++--------------------------------------------------------------------------*/
+INLINE static FIELD *Next_Field_On_Page(FIELD * field)
+{
+ FORM *form = field->form;
+ FIELD **field_on_page = &form->field[field->index];
+ FIELD **first_on_page = &form->field[form->page[form->curpage].pmin];
+ FIELD **last_on_page = &form->field[form->page[form->curpage].pmax];
+
+ do
+ {
+ field_on_page =
+ (field_on_page==last_on_page) ? first_on_page : field_on_page + 1;
+ if (Field_Is_Selectable(*field_on_page))
+ break;
+ } while(field!=(*field_on_page));
+ return(*field_on_page);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : FIELD* _nc_First_Active_Field(FORM * form)
+|
+| Description : Get the first active field on the current page,
+| if there are such. If there are none, get the first
+| visible field on the page. If there are also none,
+| we return the first field on page and hope the best.
+|
+| Return Values : Pointer to calculated field.
++--------------------------------------------------------------------------*/
+FIELD*
+_nc_First_Active_Field(FORM * form)
+{
+ FIELD **last_on_page = &form->field[form->page[form->curpage].pmax];
+ FIELD *proposed = Next_Field_On_Page(*last_on_page);
+
+ if (proposed == *last_on_page)
+ { /* there might be the special situation, where there is no
+ active and visible field on the current page. We then select
+ the first visible field on this readonly page
+ */
+ if (Field_Is_Not_Selectable(proposed))
+ {
+ FIELD **field = &form->field[proposed->index];
+ FIELD **first = &form->field[form->page[form->curpage].pmin];
+
+ do
+ {
+ field = (field==last_on_page) ? first : field + 1;
+ if (((*field)->opts & O_VISIBLE))
+ break;
+ } while(proposed!=(*field));
+
+ proposed = *field;
+
+ if ((proposed == *last_on_page) && !(proposed->opts&O_VISIBLE))
+ { /* This means, there is also no visible field on the page.
+ So we propose the first one and hope the very best...
+ Some very clever user has designed a readonly and invisible
+ page on this form.
+ */
+ proposed = *first;
+ }
+ }
+ }
+ return(proposed);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static FIELD *Previous_Field_On_Page(FIELD * field)
+|
+| Description : Get the previous field before the given field on the
+| current page. The order of fields is the one defined by
+| the fields array. Only visible and active fields are
+| counted.
+|
+| Return Values : Pointer to the previous field.
++--------------------------------------------------------------------------*/
+INLINE static FIELD *Previous_Field_On_Page(FIELD * field)
+{
+ FORM *form = field->form;
+ FIELD **field_on_page = &form->field[field->index];
+ FIELD **first_on_page = &form->field[form->page[form->curpage].pmin];
+ FIELD **last_on_page = &form->field[form->page[form->curpage].pmax];
+
+ do
+ {
+ field_on_page =
+ (field_on_page==first_on_page) ? last_on_page : field_on_page - 1;
+ if (Field_Is_Selectable(*field_on_page))
+ break;
+ } while(field!=(*field_on_page));
+
+ return (*field_on_page);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static FIELD *Sorted_Next_Field(FIELD * field)
+|
+| Description : Get the next field after the given field on the current
+| page. The order of fields is the one defined by the
+| (row,column) geometry, rows are major.
+|
+| Return Values : Pointer to the next field.
++--------------------------------------------------------------------------*/
+INLINE static FIELD *Sorted_Next_Field(FIELD * field)
+{
+ FIELD *field_on_page = field;
+
+ do
+ {
+ field_on_page = field_on_page->snext;
+ if (Field_Is_Selectable(field_on_page))
+ break;
+ } while(field_on_page!=field);
+
+ return (field_on_page);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static FIELD *Sorted_Previous_Field(FIELD * field)
+|
+| Description : Get the previous field before the given field on the
+| current page. The order of fields is the one defined
+| by the (row,column) geometry, rows are major.
+|
+| Return Values : Pointer to the previous field.
++--------------------------------------------------------------------------*/
+INLINE static FIELD *Sorted_Previous_Field(FIELD * field)
+{
+ FIELD *field_on_page = field;
+
+ do
+ {
+ field_on_page = field_on_page->sprev;
+ if (Field_Is_Selectable(field_on_page))
+ break;
+ } while(field_on_page!=field);
+
+ return (field_on_page);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static FIELD *Left_Neighbour_Field(FIELD * field)
+|
+| Description : Get the left neighbour of the field on the same line
+| and the same page. Cycles through the line.
+|
+| Return Values : Pointer to left neighbour field.
++--------------------------------------------------------------------------*/
+INLINE static FIELD *Left_Neighbour_Field(FIELD * field)
+{
+ FIELD *field_on_page = field;
+
+ /* For a field that has really a left neighbour, the while clause
+ immediately fails and the loop is left, positioned at the right
+ neighbour. Otherwise we cycle backwards through the sorted fieldlist
+ until we enter the same line (from the right end).
+ */
+ do
+ {
+ field_on_page = Sorted_Previous_Field(field_on_page);
+ } while(field_on_page->frow != field->frow);
+
+ return (field_on_page);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static FIELD *Right_Neighbour_Field(FIELD * field)
+|
+| Description : Get the right neighbour of the field on the same line
+| and the same page.
+|
+| Return Values : Pointer to right neighbour field.
++--------------------------------------------------------------------------*/
+INLINE static FIELD *Right_Neighbour_Field(FIELD * field)
+{
+ FIELD *field_on_page = field;
+
+ /* See the comments on Left_Neighbour_Field to understand how it works */
+ do
+ {
+ field_on_page = Sorted_Next_Field(field_on_page);
+ } while(field_on_page->frow != field->frow);
+
+ return (field_on_page);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static FIELD *Upper_Neighbour_Field(FIELD * field)
+|
+| Description : Because of the row-major nature of sorting the fields,
+| its more difficult to define whats the upper neighbour
+| field really means. We define that it must be on a
+| 'previous' line (cyclic order!) and is the rightmost
+| field laying on the left side of the given field. If
+| this set is empty, we take the first field on the line.
+|
+| Return Values : Pointer to the upper neighbour field.
++--------------------------------------------------------------------------*/
+static FIELD *Upper_Neighbour_Field(FIELD * field)
+{
+ FIELD *field_on_page = field;
+ int frow = field->frow;
+ int fcol = field->fcol;
+
+ /* Walk back to the 'previous' line. The second term in the while clause
+ just guarantees that we stop if we cycled through the line because
+ there might be no 'previous' line if the page has just one line.
+ */
+ do
+ {
+ field_on_page = Sorted_Previous_Field(field_on_page);
+ } while(field_on_page->frow==frow && field_on_page->fcol!=fcol);
+
+ if (field_on_page->frow!=frow)
+ { /* We really found a 'previous' line. We are positioned at the
+ rightmost field on this line */
+ frow = field_on_page->frow;
+
+ /* We walk to the left as long as we are really right of the
+ field. */
+ while(field_on_page->frow==frow && field_on_page->fcol>fcol)
+ field_on_page = Sorted_Previous_Field(field_on_page);
+
+ /* If we wrapped, just go to the right which is the first field on
+ the row */
+ if (field_on_page->frow!=frow)
+ field_on_page = Sorted_Next_Field(field_on_page);
+ }
+
+ return (field_on_page);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static FIELD *Down_Neighbour_Field(FIELD * field)
+|
+| Description : Because of the row-major nature of sorting the fields,
+| its more difficult to define whats the down neighbour
+| field really means. We define that it must be on a
+| 'next' line (cyclic order!) and is the leftmost
+| field laying on the right side of the given field. If
+| this set is empty, we take the last field on the line.
+|
+| Return Values : Pointer to the upper neighbour field.
++--------------------------------------------------------------------------*/
+static FIELD *Down_Neighbour_Field(FIELD * field)
+{
+ FIELD *field_on_page = field;
+ int frow = field->frow;
+ int fcol = field->fcol;
+
+ /* Walk forward to the 'next' line. The second term in the while clause
+ just guarantees that we stop if we cycled through the line because
+ there might be no 'next' line if the page has just one line.
+ */
+ do
+ {
+ field_on_page = Sorted_Next_Field(field_on_page);
+ } while(field_on_page->frow==frow && field_on_page->fcol!=fcol);
+
+ if (field_on_page->frow!=frow)
+ { /* We really found a 'next' line. We are positioned at the rightmost
+ field on this line */
+ frow = field_on_page->frow;
+
+ /* We walk to the right as long as we are really left of the
+ field. */
+ while(field_on_page->frow==frow && field_on_page->fcol<fcol)
+ field_on_page = Sorted_Next_Field(field_on_page);
+
+ /* If we wrapped, just go to the left which is the last field on
+ the row */
+ if (field_on_page->frow!=frow)
+ field_on_page = Sorted_Previous_Field(field_on_page);
+ }
+
+ return(field_on_page);
+}
+
+/*----------------------------------------------------------------------------
+ Inter-Field Navigation routines
+ --------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int Inter_Field_Navigation(
+| int (* const fct) (FORM *),
+| FORM * form)
+|
+| Description : Generic behaviour for changing the current field, the
+| field is left and a new field is entered. So the field
+| must be validated and the field init/term hooks must
+| be called.
+|
+| Return Values : E_OK - success
+| E_INVALID_FIELD - field is invalid
+| some other - error from subordinate call
++--------------------------------------------------------------------------*/
+static int Inter_Field_Navigation(int (* const fct) (FORM *),FORM *form)
+{
+ int res;
+
+ if (!_nc_Internal_Validation(form))
+ res = E_INVALID_FIELD;
+ else
+ {
+ Call_Hook(form,fieldterm);
+ res = fct(form);
+ Call_Hook(form,fieldinit);
+ }
+ return res;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FN_Next_Field(FORM * form)
+|
+| Description : Move to the next field on the current page of the form
+|
+| Return Values : E_OK - success
+| != E_OK - error from subordinate call
++--------------------------------------------------------------------------*/
+static int FN_Next_Field(FORM * form)
+{
+ return _nc_Set_Current_Field(form,
+ Next_Field_On_Page(form->current));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FN_Previous_Field(FORM * form)
+|
+| Description : Move to the previous field on the current page of the
+| form
+|
+| Return Values : E_OK - success
+| != E_OK - error from subordinate call
++--------------------------------------------------------------------------*/
+static int FN_Previous_Field(FORM * form)
+{
+ return _nc_Set_Current_Field(form,
+ Previous_Field_On_Page(form->current));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FN_First_Field(FORM * form)
+|
+| Description : Move to the first field on the current page of the form
+|
+| Return Values : E_OK - success
+| != E_OK - error from subordinate call
++--------------------------------------------------------------------------*/
+static int FN_First_Field(FORM * form)
+{
+ return _nc_Set_Current_Field(form,
+ Next_Field_On_Page(form->field[form->page[form->curpage].pmax]));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FN_Last_Field(FORM * form)
+|
+| Description : Move to the last field on the current page of the form
+|
+| Return Values : E_OK - success
+| != E_OK - error from subordinate call
++--------------------------------------------------------------------------*/
+static int FN_Last_Field(FORM * form)
+{
+ return
+ _nc_Set_Current_Field(form,
+ Previous_Field_On_Page(form->field[form->page[form->curpage].pmin]));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FN_Sorted_Next_Field(FORM * form)
+|
+| Description : Move to the sorted next field on the current page
+| of the form.
+|
+| Return Values : E_OK - success
+| != E_OK - error from subordinate call
++--------------------------------------------------------------------------*/
+static int FN_Sorted_Next_Field(FORM * form)
+{
+ return _nc_Set_Current_Field(form,
+ Sorted_Next_Field(form->current));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FN_Sorted_Previous_Field(FORM * form)
+|
+| Description : Move to the sorted previous field on the current page
+| of the form.
+|
+| Return Values : E_OK - success
+| != E_OK - error from subordinate call
++--------------------------------------------------------------------------*/
+static int FN_Sorted_Previous_Field(FORM * form)
+{
+ return _nc_Set_Current_Field(form,
+ Sorted_Previous_Field(form->current));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FN_Sorted_First_Field(FORM * form)
+|
+| Description : Move to the sorted first field on the current page
+| of the form.
+|
+| Return Values : E_OK - success
+| != E_OK - error from subordinate call
++--------------------------------------------------------------------------*/
+static int FN_Sorted_First_Field(FORM * form)
+{
+ return _nc_Set_Current_Field(form,
+ Sorted_Next_Field(form->field[form->page[form->curpage].smax]));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FN_Sorted_Last_Field(FORM * form)
+|
+| Description : Move to the sorted last field on the current page
+| of the form.
+|
+| Return Values : E_OK - success
+| != E_OK - error from subordinate call
++--------------------------------------------------------------------------*/
+static int FN_Sorted_Last_Field(FORM * form)
+{
+ return _nc_Set_Current_Field(form,
+ Sorted_Previous_Field(form->field[form->page[form->curpage].smin]));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FN_Left_Field(FORM * form)
+|
+| Description : Get the field on the left of the current field on the
+| same line and the same page. Cycles through the line.
+|
+| Return Values : E_OK - success
+| != E_OK - error from subordinate call
++--------------------------------------------------------------------------*/
+static int FN_Left_Field(FORM * form)
+{
+ return _nc_Set_Current_Field(form,
+ Left_Neighbour_Field(form->current));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FN_Right_Field(FORM * form)
+|
+| Description : Get the field on the right of the current field on the
+| same line and the same page. Cycles through the line.
+|
+| Return Values : E_OK - success
+| != E_OK - error from subordinate call
++--------------------------------------------------------------------------*/
+static int FN_Right_Field(FORM * form)
+{
+ return _nc_Set_Current_Field(form,
+ Right_Neighbour_Field(form->current));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FN_Up_Field(FORM * form)
+|
+| Description : Get the upper neighbour of the current field. This
+| cycles through the page. See the comments of the
+| Upper_Neighbour_Field function to understand how
+| 'upper' is defined.
+|
+| Return Values : E_OK - success
+| != E_OK - error from subordinate call
++--------------------------------------------------------------------------*/
+static int FN_Up_Field(FORM * form)
+{
+ return _nc_Set_Current_Field(form,
+ Upper_Neighbour_Field(form->current));
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int FN_Down_Field(FORM * form)
+|
+| Description : Get the down neighbour of the current field. This
+| cycles through the page. See the comments of the
+| Down_Neighbour_Field function to understand how
+| 'down' is defined.
+|
+| Return Values : E_OK - success
+| != E_OK - error from subordinate call
++--------------------------------------------------------------------------*/
+static int FN_Down_Field(FORM * form)
+{
+ return _nc_Set_Current_Field(form,
+ Down_Neighbour_Field(form->current));
+}
+/*----------------------------------------------------------------------------
+ END of Field Navigation routines
+ --------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ Helper routines for Page Navigation
+ --------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int _nc_Set_Form_Page(FORM * form,
+| int page,
+| FIELD * field)
+|
+| Description : Make the given page nr. the current page and make
+| the given field the current field on the page. If
+| for the field NULL is given, make the first field on
+| the page the current field. The routine acts only
+| if the requested page is not the current page.
+|
+| Return Values : E_OK - success
+| != E_OK - error from subordinate call
++--------------------------------------------------------------------------*/
+int
+_nc_Set_Form_Page(FORM * form, int page, FIELD * field)
+{
+ int res = E_OK;
+
+ if ((form->curpage!=page))
+ {
+ FIELD *last_field, *field_on_page;
+
+ werase(Get_Form_Window(form));
+ form->curpage = page;
+ last_field = field_on_page = form->field[form->page[page].smin];
+ do
+ {
+ if (field_on_page->opts & O_VISIBLE)
+ if ((res=Display_Field(field_on_page))!=E_OK)
+ return(res);
+ field_on_page = field_on_page->snext;
+ } while(field_on_page != last_field);
+
+ if (field)
+ res = _nc_Set_Current_Field(form,field);
+ else
+ /* N.B.: we don't encapsulate this by Inter_Field_Navigation(),
+ because this is already executed in a page navigation
+ context that contains field navigation
+ */
+ res = FN_First_Field(form);
+ }
+ return(res);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int Next_Page_Number(const FORM * form)
+|
+| Description : Calculate the page number following the current page
+| number. This cycles if the highest page number is
+| reached.
+|
+| Return Values : The next page number
++--------------------------------------------------------------------------*/
+INLINE static int Next_Page_Number(const FORM * form)
+{
+ return (form->curpage + 1) % form->maxpage;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int Previous_Page_Number(const FORM * form)
+|
+| Description : Calculate the page number before the current page
+| number. This cycles if the first page number is
+| reached.
+|
+| Return Values : The previous page number
++--------------------------------------------------------------------------*/
+INLINE static int Previous_Page_Number(const FORM * form)
+{
+ return (form->curpage!=0 ? form->curpage - 1 : form->maxpage - 1);
+}
+
+/*----------------------------------------------------------------------------
+ Page Navigation routines
+ --------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int Page_Navigation(
+| int (* const fct) (FORM *),
+| FORM * form)
+|
+| Description : Generic behaviour for changing a page. This means
+| that the field is left and a new field is entered.
+| So the field must be validated and the field init/term
+| hooks must be called. Because also the page is changed,
+| the forms init/term hooks must be called also.
+|
+| Return Values : E_OK - success
+| E_INVALID_FIELD - field is invalid
+| some other - error from subordinate call
++--------------------------------------------------------------------------*/
+static int Page_Navigation(int (* const fct) (FORM *), FORM * form)
+{
+ int res;
+
+ if (!_nc_Internal_Validation(form))
+ res = E_INVALID_FIELD;
+ else
+ {
+ Call_Hook(form,fieldterm);
+ Call_Hook(form,formterm);
+ res = fct(form);
+ Call_Hook(form,forminit);
+ Call_Hook(form,fieldinit);
+ }
+ return res;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int PN_Next_Page(FORM * form)
+|
+| Description : Move to the next page of the form
+|
+| Return Values : E_OK - success
+| != E_OK - error from subordinate call
++--------------------------------------------------------------------------*/
+static int PN_Next_Page(FORM * form)
+{
+ return _nc_Set_Form_Page(form,Next_Page_Number(form),(FIELD *)0);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int PN_Previous_Page(FORM * form)
+|
+| Description : Move to the previous page of the form
+|
+| Return Values : E_OK - success
+| != E_OK - error from subordinate call
++--------------------------------------------------------------------------*/
+static int PN_Previous_Page(FORM * form)
+{
+ return _nc_Set_Form_Page(form,Previous_Page_Number(form),(FIELD *)0);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int PN_First_Page(FORM * form)
+|
+| Description : Move to the first page of the form
+|
+| Return Values : E_OK - success
+| != E_OK - error from subordinate call
++--------------------------------------------------------------------------*/
+static int PN_First_Page(FORM * form)
+{
+ return _nc_Set_Form_Page(form,0,(FIELD *)0);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int PN_Last_Page(FORM * form)
+|
+| Description : Move to the last page of the form
+|
+| Return Values : E_OK - success
+| != E_OK - error from subordinate call
++--------------------------------------------------------------------------*/
+static int PN_Last_Page(FORM * form)
+{
+ return _nc_Set_Form_Page(form,form->maxpage-1,(FIELD *)0);
+}
+/*----------------------------------------------------------------------------
+ END of Field Navigation routines
+ --------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ Helper routines for the core form driver.
+ --------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int Data_Entry(FORM * form,int c)
+|
+| Description : Enter character c into at the current position of the
+| current field of the form.
+|
+| Return Values : E_OK -
+| E_REQUEST_DENIED -
+| E_SYSTEM_ERROR -
++--------------------------------------------------------------------------*/
+static int Data_Entry(FORM * form, int c)
+{
+ FIELD *field = form->current;
+ int result = E_REQUEST_DENIED;
+
+ if ( (field->opts & O_EDIT)
+#if FIX_FORM_INACTIVE_BUG
+ && (field->opts & O_ACTIVE)
+#endif
+ )
+ {
+ if ( (field->opts & O_BLANK) &&
+ First_Position_In_Current_Field(form) &&
+ !(form->status & _FCHECK_REQUIRED) &&
+ !(form->status & _WINDOW_MODIFIED) )
+ werase(form->w);
+
+ if (form->status & _OVLMODE)
+ {
+ waddch(form->w,(chtype)c);
+ }
+ else /* no _OVLMODE */
+ {
+ bool There_Is_Room = Is_There_Room_For_A_Char_In_Line(form);
+
+ if (!(There_Is_Room ||
+ ((Single_Line_Field(field) && Growable(field)))))
+ return E_REQUEST_DENIED;
+
+ if (!There_Is_Room && !Field_Grown(field,1))
+ return E_SYSTEM_ERROR;
+
+ winsch(form->w,(chtype)c);
+ }
+
+ if ((result=Wrapping_Not_Necessary_Or_Wrapping_Ok(form))==E_OK)
+ {
+ bool End_Of_Field= (((field->drows-1)==form->currow) &&
+ ((field->dcols-1)==form->curcol));
+ form->status |= _WINDOW_MODIFIED;
+ if (End_Of_Field && !Growable(field) && (field->opts & O_AUTOSKIP))
+ result = Inter_Field_Navigation(FN_Next_Field,form);
+ else
+ {
+ if (End_Of_Field && Growable(field) && !Field_Grown(field,1))
+ result = E_SYSTEM_ERROR;
+ else
+ {
+ IFN_Next_Character(form);
+ result = E_OK;
+ }
+ }
+ }
+ }
+ return result;
+}
+
+/* Structure to describe the binding of a request code to a function.
+ The member keycode codes the request value as well as the generic
+ routine to use for the request. The code for the generic routine
+ is coded in the upper 16 Bits while the request code is coded in
+ the lower 16 bits.
+
+ In terms of C++ you might think of a request as a class with a
+ virtual method "perform". The different types of request are
+ derived from this base class and overload (or not) the base class
+ implementation of perform.
+*/
+typedef struct {
+ int keycode; /* must be at least 32 bit: hi:mode, lo: key */
+ int (*cmd)(FORM *); /* low level driver routine for this key */
+} Binding_Info;
+
+/* You may see this is the class-id of the request type class */
+#define ID_PN (0x00000000) /* Page navigation */
+#define ID_FN (0x00010000) /* Inter-Field navigation */
+#define ID_IFN (0x00020000) /* Intra-Field navigation */
+#define ID_VSC (0x00030000) /* Vertical Scrolling */
+#define ID_HSC (0x00040000) /* Horizontal Scrolling */
+#define ID_FE (0x00050000) /* Field Editing */
+#define ID_EM (0x00060000) /* Edit Mode */
+#define ID_FV (0x00070000) /* Field Validation */
+#define ID_CH (0x00080000) /* Choice */
+#define ID_Mask (0xffff0000)
+#define Key_Mask (0x0000ffff)
+#define ID_Shft (16)
+
+/* This array holds all the Binding Infos */
+static const Binding_Info bindings[MAX_FORM_COMMAND - MIN_FORM_COMMAND + 1] =
+{
+ { REQ_NEXT_PAGE |ID_PN ,PN_Next_Page},
+ { REQ_PREV_PAGE |ID_PN ,PN_Previous_Page},
+ { REQ_FIRST_PAGE |ID_PN ,PN_First_Page},
+ { REQ_LAST_PAGE |ID_PN ,PN_Last_Page},
+
+ { REQ_NEXT_FIELD |ID_FN ,FN_Next_Field},
+ { REQ_PREV_FIELD |ID_FN ,FN_Previous_Field},
+ { REQ_FIRST_FIELD |ID_FN ,FN_First_Field},
+ { REQ_LAST_FIELD |ID_FN ,FN_Last_Field},
+ { REQ_SNEXT_FIELD |ID_FN ,FN_Sorted_Next_Field},
+ { REQ_SPREV_FIELD |ID_FN ,FN_Sorted_Previous_Field},
+ { REQ_SFIRST_FIELD |ID_FN ,FN_Sorted_First_Field},
+ { REQ_SLAST_FIELD |ID_FN ,FN_Sorted_Last_Field},
+ { REQ_LEFT_FIELD |ID_FN ,FN_Left_Field},
+ { REQ_RIGHT_FIELD |ID_FN ,FN_Right_Field},
+ { REQ_UP_FIELD |ID_FN ,FN_Up_Field},
+ { REQ_DOWN_FIELD |ID_FN ,FN_Down_Field},
+
+ { REQ_NEXT_CHAR |ID_IFN ,IFN_Next_Character},
+ { REQ_PREV_CHAR |ID_IFN ,IFN_Previous_Character},
+ { REQ_NEXT_LINE |ID_IFN ,IFN_Next_Line},
+ { REQ_PREV_LINE |ID_IFN ,IFN_Previous_Line},
+ { REQ_NEXT_WORD |ID_IFN ,IFN_Next_Word},
+ { REQ_PREV_WORD |ID_IFN ,IFN_Previous_Word},
+ { REQ_BEG_FIELD |ID_IFN ,IFN_Beginning_Of_Field},
+ { REQ_END_FIELD |ID_IFN ,IFN_End_Of_Field},
+ { REQ_BEG_LINE |ID_IFN ,IFN_Beginning_Of_Line},
+ { REQ_END_LINE |ID_IFN ,IFN_End_Of_Line},
+ { REQ_LEFT_CHAR |ID_IFN ,IFN_Left_Character},
+ { REQ_RIGHT_CHAR |ID_IFN ,IFN_Right_Character},
+ { REQ_UP_CHAR |ID_IFN ,IFN_Up_Character},
+ { REQ_DOWN_CHAR |ID_IFN ,IFN_Down_Character},
+
+ { REQ_NEW_LINE |ID_FE ,FE_New_Line},
+ { REQ_INS_CHAR |ID_FE ,FE_Insert_Character},
+ { REQ_INS_LINE |ID_FE ,FE_Insert_Line},
+ { REQ_DEL_CHAR |ID_FE ,FE_Delete_Character},
+ { REQ_DEL_PREV |ID_FE ,FE_Delete_Previous},
+ { REQ_DEL_LINE |ID_FE ,FE_Delete_Line},
+ { REQ_DEL_WORD |ID_FE ,FE_Delete_Word},
+ { REQ_CLR_EOL |ID_FE ,FE_Clear_To_End_Of_Line},
+ { REQ_CLR_EOF |ID_FE ,FE_Clear_To_End_Of_Form},
+ { REQ_CLR_FIELD |ID_FE ,FE_Clear_Field},
+
+ { REQ_OVL_MODE |ID_EM ,EM_Overlay_Mode},
+ { REQ_INS_MODE |ID_EM ,EM_Insert_Mode},
+
+ { REQ_SCR_FLINE |ID_VSC ,VSC_Scroll_Line_Forward},
+ { REQ_SCR_BLINE |ID_VSC ,VSC_Scroll_Line_Backward},
+ { REQ_SCR_FPAGE |ID_VSC ,VSC_Scroll_Page_Forward},
+ { REQ_SCR_BPAGE |ID_VSC ,VSC_Scroll_Page_Backward},
+ { REQ_SCR_FHPAGE |ID_VSC ,VSC_Scroll_Half_Page_Forward},
+ { REQ_SCR_BHPAGE |ID_VSC ,VSC_Scroll_Half_Page_Backward},
+
+ { REQ_SCR_FCHAR |ID_HSC ,HSC_Scroll_Char_Forward},
+ { REQ_SCR_BCHAR |ID_HSC ,HSC_Scroll_Char_Backward},
+ { REQ_SCR_HFLINE |ID_HSC ,HSC_Horizontal_Line_Forward},
+ { REQ_SCR_HBLINE |ID_HSC ,HSC_Horizontal_Line_Backward},
+ { REQ_SCR_HFHALF |ID_HSC ,HSC_Horizontal_Half_Line_Forward},
+ { REQ_SCR_HBHALF |ID_HSC ,HSC_Horizontal_Half_Line_Backward},
+
+ { REQ_VALIDATION |ID_FV ,FV_Validation},
+
+ { REQ_NEXT_CHOICE |ID_CH ,CR_Next_Choice},
+ { REQ_PREV_CHOICE |ID_CH ,CR_Previous_Choice}
+};
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int form_driver(FORM * form,int c)
+|
+| Description : This is the workhorse of the forms system. It checks
+| to determine whether the character c is a request or
+| data. If it is a request, the form driver executes
+| the request and returns the result. If it is data
+| (printable character), it enters the data into the
+| current position in the current field. If it is not
+| recognized, the form driver assumes it is an application
+| defined command and returns E_UNKNOWN_COMMAND.
+| Application defined command should be defined relative
+| to MAX_FORM_COMMAND, the maximum value of a request.
+|
+| Return Values : E_OK - success
+| E_SYSTEM_ERROR - system error
+| E_BAD_ARGUMENT - an argument is incorrect
+| E_NOT_POSTED - form is not posted
+| E_INVALID_FIELD - field contents are invalid
+| E_BAD_STATE - called from inside a hook routine
+| E_REQUEST_DENIED - request failed
+| E_UNKNOWN_COMMAND - command not known
++--------------------------------------------------------------------------*/
+int form_driver(FORM * form, int c)
+{
+ const Binding_Info* BI = (Binding_Info *)0;
+ int res = E_UNKNOWN_COMMAND;
+
+ if (!form)
+ RETURN(E_BAD_ARGUMENT);
+
+ if (!(form->field))
+ RETURN(E_NOT_CONNECTED);
+
+ assert(form->page != 0);
+
+ if (c==FIRST_ACTIVE_MAGIC)
+ {
+ form->current = _nc_First_Active_Field(form);
+ return E_OK;
+ }
+
+ assert(form->current &&
+ form->current->buf &&
+ (form->current->form == form)
+ );
+
+ if ( form->status & _IN_DRIVER )
+ RETURN(E_BAD_STATE);
+
+ if ( !( form->status & _POSTED ) )
+ RETURN(E_NOT_POSTED);
+
+ if ((c>=MIN_FORM_COMMAND && c<=MAX_FORM_COMMAND) &&
+ ((bindings[c-MIN_FORM_COMMAND].keycode & Key_Mask) == c))
+ BI = &(bindings[c-MIN_FORM_COMMAND]);
+
+ if (BI)
+ {
+ typedef int (*Generic_Method)(int (* const)(FORM *),FORM *);
+ static const Generic_Method Generic_Methods[] =
+ {
+ Page_Navigation, /* overloaded to call field&form hooks */
+ Inter_Field_Navigation, /* overloaded to call field hooks */
+ NULL, /* Intra-Field is generic */
+ Vertical_Scrolling, /* Overloaded to check multi-line */
+ Horizontal_Scrolling, /* Overloaded to check single-line */
+ Field_Editing, /* Overloaded to mark modification */
+ NULL, /* Edit Mode is generic */
+ NULL, /* Field Validation is generic */
+ NULL /* Choice Request is generic */
+ };
+ size_t nMethods = (sizeof(Generic_Methods)/sizeof(Generic_Methods[0]));
+ size_t method = ((BI->keycode & ID_Mask) >> ID_Shft) & 0xffff;
+
+ if ( (method >= nMethods) || !(BI->cmd) )
+ res = E_SYSTEM_ERROR;
+ else
+ {
+ Generic_Method fct = Generic_Methods[method];
+ if (fct)
+ res = fct(BI->cmd,form);
+ else
+ res = (BI->cmd)(form);
+ }
+ }
+ else
+ {
+ if (!(c & (~(int)MAX_REGULAR_CHARACTER)) &&
+ isprint((unsigned char)c) &&
+ Check_Char(form->current->type,c,
+ (TypeArgument *)(form->current->arg)))
+ res = Data_Entry(form,c);
+ }
+ _nc_Refresh_Current_Field(form);
+ RETURN(res);
+}
+
+/*----------------------------------------------------------------------------
+ Field-Buffer manipulation routines.
+ The effects of setting a buffer is tightly coupled to the core of the form
+ driver logic. This is especially true in the case of growable fields.
+ So I don't separate this into an own module.
+ --------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_field_buffer(FIELD *field,
+| int buffer, char *value)
+|
+| Description : Set the given buffer of the field to the given value.
+| Buffer 0 stores the displayed content of the field.
+| For dynamic fields this may grow the fieldbuffers if
+| the length of the value exceeds the current buffer
+| length. For buffer 0 only printable values are allowed.
+| For static fields, the value needs not to be zero ter-
+| minated. It is copied up to the length of the buffer.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid argument
+| E_SYSTEM_ERROR - system error
++--------------------------------------------------------------------------*/
+int set_field_buffer(FIELD * field, int buffer, const char * value)
+{
+ char *s, *p;
+ int res = E_OK;
+ unsigned int len;
+
+ if ( !field || !value || ((buffer < 0)||(buffer > field->nbuf)) )
+ RETURN(E_BAD_ARGUMENT);
+
+ len = Buffer_Length(field);
+
+ if (buffer==0)
+ {
+ const char *v;
+ unsigned int i = 0;
+
+ for(v=value; *v && (i<len); v++,i++)
+ {
+ if (!isprint((unsigned char)*v))
+ RETURN(E_BAD_ARGUMENT);
+ }
+ }
+
+ if (Growable(field))
+ {
+ /* for a growable field we must assume zero terminated strings, because
+ somehow we have to detect the length of what should be copied.
+ */
+ unsigned int vlen = strlen(value);
+ if (vlen > len)
+ {
+ if (!Field_Grown(field,
+ (int)(1 + (vlen-len)/((field->rows+field->nrow)*field->cols))))
+ RETURN(E_SYSTEM_ERROR);
+
+ /* in this case we also have to check, wether or not the remaining
+ characters in value are also printable for buffer 0. */
+ if (buffer==0)
+ {
+ unsigned int i;
+
+ for(i=len; i<vlen; i++)
+ if (!isprint((int)(value[i])))
+ RETURN(E_BAD_ARGUMENT);
+ }
+ len = vlen;
+ }
+ }
+
+ p = Address_Of_Nth_Buffer(field,buffer);
+
+#if HAVE_MEMCCPY
+ s = memccpy(p,value,0,len);
+#else
+ for(s=(char *)value; *s && (s < (value+len)); s++)
+ p[s-value] = *s;
+ if (s < (value+len))
+ {
+ int off = s-value;
+ p[off] = *s++;
+ s = p + (s-value);
+ }
+ else
+ s=(char *)0;
+#endif
+
+ if (s)
+ { /* this means, value was null terminated and not greater than the
+ buffer. We have to pad with blanks. Please note that due to memccpy
+ logic s points after the terminating null. */
+ s--; /* now we point to the terminator. */
+ assert(len >= (unsigned int)(s-p));
+ if (len > (unsigned int)(s-p))
+ memset(s,C_BLANK,len-(unsigned int)(s-p));
+ }
+
+ if (buffer==0)
+ {
+ int syncres;
+ if (((syncres=Synchronize_Field( field ))!=E_OK) &&
+ (res==E_OK))
+ res = syncres;
+ if (((syncres=Synchronize_Linked_Fields(field ))!=E_OK) &&
+ (res==E_OK))
+ res = syncres;
+ }
+ RETURN(res);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : char *field_buffer(const FIELD *field,int buffer)
+|
+| Description : Return the address of the buffer for the field.
+|
+| Return Values : Pointer to buffer or NULL if arguments were invalid.
++--------------------------------------------------------------------------*/
+char *field_buffer(const FIELD * field, int buffer)
+{
+ if (field && (buffer >= 0) && (buffer <= field->nbuf))
+ return Address_Of_Nth_Buffer(field,buffer);
+ else
+ return (char *)0;
+}
+
+/* frm_driver.c ends here */
diff --git a/Source/CursesDialog/form/frm_hook.c b/Source/CursesDialog/form/frm_hook.c
new file mode 100644
index 000000000..eb654c4f3
--- /dev/null
+++ b/Source/CursesDialog/form/frm_hook.c
@@ -0,0 +1,140 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 ABOVE 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. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <juergen.pfeifer@gmx.net> 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id$")
+
+/* "Template" macro to generate function to set application specific hook */
+#define GEN_HOOK_SET_FUNCTION( typ, name ) \
+int set_ ## typ ## _ ## name (FORM *form, Form_Hook func)\
+{\
+ (Normalize_Form( form ) -> typ ## name) = func ;\
+ RETURN(E_OK);\
+}
+
+/* "Template" macro to generate function to get application specific hook */
+#define GEN_HOOK_GET_FUNCTION( typ, name ) \
+Form_Hook typ ## _ ## name ( const FORM *form )\
+{\
+ return ( Normalize_Form( form ) -> typ ## name );\
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_field_init(FORM *form, Form_Hook f)
+|
+| Description : Assigns an application defined initialization function
+| to be called when the form is posted and just after
+| the current field changes.
+|
+| Return Values : E_OK - success
++--------------------------------------------------------------------------*/
+GEN_HOOK_SET_FUNCTION(field,init)
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : Form_Hook field_init(const FORM *form)
+|
+| Description : Retrieve field initialization routine address.
+|
+| Return Values : The address or NULL if no hook defined.
++--------------------------------------------------------------------------*/
+GEN_HOOK_GET_FUNCTION(field,init)
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_field_term(FORM *form, Form_Hook f)
+|
+| Description : Assigns an application defined finalization function
+| to be called when the form is unposted and just before
+| the current field changes.
+|
+| Return Values : E_OK - success
++--------------------------------------------------------------------------*/
+GEN_HOOK_SET_FUNCTION(field,term)
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : Form_Hook field_term(const FORM *form)
+|
+| Description : Retrieve field finalization routine address.
+|
+| Return Values : The address or NULL if no hook defined.
++--------------------------------------------------------------------------*/
+GEN_HOOK_GET_FUNCTION(field,term)
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_form_init(FORM *form, Form_Hook f)
+|
+| Description : Assigns an application defined initialization function
+| to be called when the form is posted and just after
+| a page change.
+|
+| Return Values : E_OK - success
++--------------------------------------------------------------------------*/
+GEN_HOOK_SET_FUNCTION(form,init)
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : Form_Hook form_init(const FORM *form)
+|
+| Description : Retrieve form initialization routine address.
+|
+| Return Values : The address or NULL if no hook defined.
++--------------------------------------------------------------------------*/
+GEN_HOOK_GET_FUNCTION(form,init)
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_form_term(FORM *form, Form_Hook f)
+|
+| Description : Assigns an application defined finalization function
+| to be called when the form is unposted and just before
+| a page change.
+|
+| Return Values : E_OK - success
++--------------------------------------------------------------------------*/
+GEN_HOOK_SET_FUNCTION(form,term)
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : Form_Hook form_term(const FORM *form)
+|
+| Description : Retrieve form finalization routine address.
+|
+| Return Values : The address or NULL if no hook defined.
++--------------------------------------------------------------------------*/
+GEN_HOOK_GET_FUNCTION(form,term)
+
+/* frm_hook.c ends here */
diff --git a/Source/CursesDialog/form/frm_opts.c b/Source/CursesDialog/form/frm_opts.c
new file mode 100644
index 000000000..7bbeaa135
--- /dev/null
+++ b/Source/CursesDialog/form/frm_opts.c
@@ -0,0 +1,116 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 ABOVE 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. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <juergen.pfeifer@gmx.net> 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id$")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_form_opts(FORM *form, Form_Options opts)
+|
+| Description : Turns on the named options and turns off all the
+| remaining options for that form.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid options
++--------------------------------------------------------------------------*/
+int set_form_opts(FORM * form, Form_Options opts)
+{
+ opts &= ALL_FORM_OPTS;
+ if (opts & ~ALL_FORM_OPTS)
+ RETURN(E_BAD_ARGUMENT);
+ else
+ {
+ Normalize_Form( form )->opts = opts;
+ RETURN(E_OK);
+ }
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : Form_Options form_opts(const FORM *)
+|
+| Description : Retrieves the current form options.
+|
+| Return Values : The option flags.
++--------------------------------------------------------------------------*/
+Form_Options form_opts(const FORM * form)
+{
+ return (Normalize_Form(form)->opts & ALL_FORM_OPTS);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int form_opts_on(FORM *form, Form_Options opts)
+|
+| Description : Turns on the named options; no other options are
+| changed.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid options
++--------------------------------------------------------------------------*/
+int form_opts_on(FORM * form, Form_Options opts)
+{
+ opts &= ALL_FORM_OPTS;
+ if (opts & ~ALL_FORM_OPTS)
+ RETURN(E_BAD_ARGUMENT);
+ else
+ {
+ Normalize_Form( form )->opts |= opts;
+ RETURN(E_OK);
+ }
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int form_opts_off(FORM *form, Form_Options opts)
+|
+| Description : Turns off the named options; no other options are
+| changed.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid options
++--------------------------------------------------------------------------*/
+int form_opts_off(FORM * form, Form_Options opts)
+{
+ opts &= ALL_FORM_OPTS;
+ if (opts & ~ALL_FORM_OPTS)
+ RETURN(E_BAD_ARGUMENT);
+ else
+ {
+ Normalize_Form(form)->opts &= ~opts;
+ RETURN(E_OK);
+ }
+}
+
+/* frm_opts.c ends here */
diff --git a/Source/CursesDialog/form/frm_page.c b/Source/CursesDialog/form/frm_page.c
new file mode 100644
index 000000000..842cbce7b
--- /dev/null
+++ b/Source/CursesDialog/form/frm_page.c
@@ -0,0 +1,100 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 ABOVE 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. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <juergen.pfeifer@gmx.net> 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id$")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_form_page(FORM * form,int page)
+|
+| Description : Set the page number of the form.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid form pointer or page number
+| E_BAD_STATE - called from a hook routine
+| E_INVALID_FIELD - current field can't be left
+| E_SYSTEM_ERROR - system error
++--------------------------------------------------------------------------*/
+int set_form_page(FORM * form, int page)
+{
+ int err = E_OK;
+
+ if ( !form || (page<0) || (page>=form->maxpage) )
+ RETURN(E_BAD_ARGUMENT);
+
+ if (!(form->status & _POSTED))
+ {
+ form->curpage = page;
+ form->current = _nc_First_Active_Field(form);
+ }
+ else
+ {
+ if (form->status & _IN_DRIVER)
+ err = E_BAD_STATE;
+ else
+ {
+ if (form->curpage != page)
+ {
+ if (!_nc_Internal_Validation(form))
+ err = E_INVALID_FIELD;
+ else
+ {
+ Call_Hook(form,fieldterm);
+ Call_Hook(form,formterm);
+ err = _nc_Set_Form_Page(form,page,(FIELD *)0);
+ Call_Hook(form,forminit);
+ Call_Hook(form,fieldinit);
+ _nc_Refresh_Current_Field(form);
+ }
+ }
+ }
+ }
+ RETURN(err);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int form_page(const FORM * form)
+|
+| Description : Return the current page of the form.
+|
+| Return Values : >= 0 : current page number
+| -1 : invalid form pointer
++--------------------------------------------------------------------------*/
+int form_page(const FORM * form)
+{
+ return Normalize_Form(form)->curpage;
+}
+
+/* frm_page.c ends here */
diff --git a/Source/CursesDialog/form/frm_post.c b/Source/CursesDialog/form/frm_post.c
new file mode 100644
index 000000000..3c63de70e
--- /dev/null
+++ b/Source/CursesDialog/form/frm_post.c
@@ -0,0 +1,124 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 ABOVE 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. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <juergen.pfeifer@gmx.net> 1995,1997 *
+ ****************************************************************************/
+#include "form.priv.h"
+
+MODULE_ID("$Id$")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int post_form(FORM * form)
+|
+| Description : Writes the form into its associated subwindow.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid form pointer
+| E_POSTED - form already posted
+| E_NOT_CONNECTED - no fields connected to form
+| E_NO_ROOM - form doesn't fit into subwindow
+| E_SYSTEM_ERROR - system error
++--------------------------------------------------------------------------*/
+int post_form(FORM * form)
+{
+ WINDOW *formwin;
+ int err;
+ int page;
+ int height, width;
+
+ if (!form)
+ RETURN(E_BAD_ARGUMENT);
+
+ if (form->status & _POSTED)
+ RETURN(E_POSTED);
+
+ if (!(form->field))
+ 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);
+
+ /* reset form->curpage to an invald value. This forces Set_Form_Page
+ to do the page initialization which is required by post_form.
+ */
+ page = form->curpage;
+ form->curpage = -1;
+ if ((err = _nc_Set_Form_Page(form,page,form->current))!=E_OK)
+ RETURN(err);
+
+ form->status |= _POSTED;
+
+ Call_Hook(form,forminit);
+ Call_Hook(form,fieldinit);
+
+ _nc_Refresh_Current_Field(form);
+ RETURN(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int unpost_form(FORM * form)
+|
+| Description : Erase form from its associated subwindow.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid form pointer
+| E_NOT_POSTED - form isn't posted
+| E_BAD_STATE - called from a hook routine
++--------------------------------------------------------------------------*/
+int unpost_form(FORM * form)
+{
+ if (!form)
+ RETURN(E_BAD_ARGUMENT);
+
+ if (!(form->status & _POSTED))
+ RETURN(E_NOT_POSTED);
+
+ if (form->status & _IN_DRIVER)
+ RETURN(E_BAD_STATE);
+
+ Call_Hook(form,fieldterm);
+ Call_Hook(form,formterm);
+
+ werase(Get_Form_Window(form));
+ delwin(form->w);
+ form->w = (WINDOW *)0;
+ form->status &= ~_POSTED;
+ RETURN(E_OK);
+}
+
+/* frm_post.c ends here */
diff --git a/Source/CursesDialog/form/frm_req_name.c b/Source/CursesDialog/form/frm_req_name.c
new file mode 100644
index 000000000..b108dabe4
--- /dev/null
+++ b/Source/CursesDialog/form/frm_req_name.c
@@ -0,0 +1,169 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 ABOVE 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. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <juergen.pfeifer@gmx.net> 1995,1997 *
+ ****************************************************************************/
+
+/***************************************************************************
+* Module form_request_name *
+* 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$")
+
+static const char *request_names[ MAX_FORM_COMMAND - MIN_FORM_COMMAND + 1 ] = {
+ "NEXT_PAGE" ,
+ "PREV_PAGE" ,
+ "FIRST_PAGE" ,
+ "LAST_PAGE" ,
+
+ "NEXT_FIELD" ,
+ "PREV_FIELD" ,
+ "FIRST_FIELD" ,
+ "LAST_FIELD" ,
+ "SNEXT_FIELD" ,
+ "SPREV_FIELD" ,
+ "SFIRST_FIELD" ,
+ "SLAST_FIELD" ,
+ "LEFT_FIELD" ,
+ "RIGHT_FIELD" ,
+ "UP_FIELD" ,
+ "DOWN_FIELD" ,
+
+ "NEXT_CHAR" ,
+ "PREV_CHAR" ,
+ "NEXT_LINE" ,
+ "PREV_LINE" ,
+ "NEXT_WORD" ,
+ "PREV_WORD" ,
+ "BEG_FIELD" ,
+ "END_FIELD" ,
+ "BEG_LINE" ,
+ "END_LINE" ,
+ "LEFT_CHAR" ,
+ "RIGHT_CHAR" ,
+ "UP_CHAR" ,
+ "DOWN_CHAR" ,
+
+ "NEW_LINE" ,
+ "INS_CHAR" ,
+ "INS_LINE" ,
+ "DEL_CHAR" ,
+ "DEL_PREV" ,
+ "DEL_LINE" ,
+ "DEL_WORD" ,
+ "CLR_EOL" ,
+ "CLR_EOF" ,
+ "CLR_FIELD" ,
+ "OVL_MODE" ,
+ "INS_MODE" ,
+ "SCR_FLINE" ,
+ "SCR_BLINE" ,
+ "SCR_FPAGE" ,
+ "SCR_BPAGE" ,
+ "SCR_FHPAGE" ,
+ "SCR_BHPAGE" ,
+ "SCR_FCHAR" ,
+ "SCR_BCHAR" ,
+ "SCR_HFLINE" ,
+ "SCR_HBLINE" ,
+ "SCR_HFHALF" ,
+ "SCR_HBHALF" ,
+
+ "VALIDATION" ,
+ "NEXT_CHOICE" ,
+ "PREV_CHOICE"
+};
+#define A_SIZE (sizeof(request_names)/sizeof(request_names[0]))
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : const char * form_request_name (int request);
+|
+| Description : Get the external name of a form request.
+|
+| Return Values : Pointer to name - on success
+| NULL - on invalid request code
++--------------------------------------------------------------------------*/
+const char *form_request_name( int request )
+{
+ if ( (request < MIN_FORM_COMMAND) || (request > MAX_FORM_COMMAND) )
+ {
+ SET_ERROR (E_BAD_ARGUMENT);
+ return (const char *)0;
+ }
+ else
+ return request_names[ request - MIN_FORM_COMMAND ];
+}
+
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int form_request_by_name (const char *str);
+|
+| Description : Search for a request with this name.
+|
+| Return Values : Request Id - on success
+| E_NO_MATCH - request not found
++--------------------------------------------------------------------------*/
+int form_request_by_name( const char *str )
+{
+ /* because the table is so small, it doesn't really hurt
+ to run sequentially through it.
+ */
+ unsigned int i = 0;
+ char buf[16];
+
+ if (str)
+ {
+ strncpy(buf,str,sizeof(buf));
+ while( (i<sizeof(buf)) && (buf[i] != '\0') )
+ {
+ buf[i] = toupper((int)(buf[i]));
+ i++;
+ }
+
+ for (i=0; i < A_SIZE; i++)
+ {
+ if (strncmp(request_names[i],buf,sizeof(buf))==0)
+ return MIN_FORM_COMMAND + i;
+ }
+ }
+ RETURN(E_NO_MATCH);
+}
+
+/* frm_req_name.c ends here */
diff --git a/Source/CursesDialog/form/frm_scale.c b/Source/CursesDialog/form/frm_scale.c
new file mode 100644
index 000000000..028e9e2e8
--- /dev/null
+++ b/Source/CursesDialog/form/frm_scale.c
@@ -0,0 +1,63 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 ABOVE 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. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <juergen.pfeifer@gmx.net> 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id$")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int scale_form( const FORM *form, int *rows, int *cols )
+|
+| Description : Retrieve size of form
+|
+| Return Values : E_OK - no error
+| E_BAD_ARGUMENT - invalid form pointer
+| E_NOT_CONNECTED - no fields connected to form
++--------------------------------------------------------------------------*/
+int scale_form(const FORM * form, int * rows, int * cols)
+{
+ if ( !form )
+ RETURN(E_BAD_ARGUMENT);
+
+ if ( !(form->field) )
+ RETURN(E_NOT_CONNECTED);
+
+ if (rows)
+ *rows = form->rows;
+ if (cols)
+ *cols = form->cols;
+
+ RETURN(E_OK);
+}
+
+/* frm_scale.c ends here */
diff --git a/Source/CursesDialog/form/frm_sub.c b/Source/CursesDialog/form/frm_sub.c
new file mode 100644
index 000000000..62dc613b0
--- /dev/null
+++ b/Source/CursesDialog/form/frm_sub.c
@@ -0,0 +1,69 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 ABOVE 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. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <juergen.pfeifer@gmx.net> 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id$")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_form_sub(FORM *form, WINDOW *win)
+|
+| Description : Set the subwindow of the form to win.
+|
+| Return Values : E_OK - success
+| E_POSTED - form is posted
++--------------------------------------------------------------------------*/
+int set_form_sub(FORM * form, WINDOW * win)
+{
+ if (form && (form->status & _POSTED))
+ RETURN(E_POSTED);
+
+ Normalize_Form( form )->sub = win;
+ RETURN(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : WINDOW *form_sub(const FORM *)
+|
+| Description : Retrieve the window of the form.
+|
+| Return Values : The pointer to the Subwindow.
++--------------------------------------------------------------------------*/
+WINDOW *form_sub(const FORM * form)
+{
+ const FORM* f = Normalize_Form( form );
+ return Get_Form_Window(f);
+}
+
+/* frm_sub.c ends here */
diff --git a/Source/CursesDialog/form/frm_user.c b/Source/CursesDialog/form/frm_user.c
new file mode 100644
index 000000000..f38bbbb8d
--- /dev/null
+++ b/Source/CursesDialog/form/frm_user.c
@@ -0,0 +1,67 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 ABOVE 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. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <juergen.pfeifer@gmx.net> 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id$")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_form_userptr(FORM *form, void *usrptr)
+|
+| Description : Set the pointer that is reserved in any form to store
+| application relevant information
+|
+| Return Values : E_OK - on success
++--------------------------------------------------------------------------*/
+int set_form_userptr(FORM * form, void *usrptr)
+{
+ Normalize_Form(form)->usrptr = usrptr;
+ RETURN(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : void *form_userptr(const FORM *form)
+|
+| Description : Return the pointer that is reserved in any form to
+| store application relevant information.
+|
+| Return Values : Value of pointer. If no such pointer has been set,
+| NULL is returned
++--------------------------------------------------------------------------*/
+void *form_userptr(const FORM * form)
+{
+ return Normalize_Form(form)->usrptr;
+}
+
+/* frm_user.c ends here */
diff --git a/Source/CursesDialog/form/frm_win.c b/Source/CursesDialog/form/frm_win.c
new file mode 100644
index 000000000..82d716f7f
--- /dev/null
+++ b/Source/CursesDialog/form/frm_win.c
@@ -0,0 +1,70 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 ABOVE 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. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <juergen.pfeifer@gmx.net> 1995,1997 *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id$")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int set_form_win(FORM *form,WINDOW *win)
+|
+| Description : Set the window of the form to win.
+|
+| Return Values : E_OK - success
+| E_POSTED - form is posted
++--------------------------------------------------------------------------*/
+int set_form_win(FORM * form, WINDOW * win)
+{
+ if (form && (form->status & _POSTED))
+ RETURN(E_POSTED);
+
+ Normalize_Form( form )->win = win;
+ RETURN(E_OK);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : WINDOW *form_win(const FORM *)
+|
+| Description : Retrieve the window of the form.
+|
+| Return Values : The pointer to the Window or stdscr if there is none.
++--------------------------------------------------------------------------*/
+WINDOW *form_win(const FORM * form)
+{
+ const FORM* f = Normalize_Form( form );
+ return (f->win ? f->win : stdscr);
+}
+
+/* frm_win.c ends here */
+
diff --git a/Source/CursesDialog/form/fty_alnum.c b/Source/CursesDialog/form/fty_alnum.c
new file mode 100644
index 000000000..6f3cfd4fc
--- /dev/null
+++ b/Source/CursesDialog/form/fty_alnum.c
@@ -0,0 +1,138 @@
+
+/*
+ * THIS CODE IS SPECIFICALLY EXEMPTED FROM THE NCURSES PACKAGE COPYRIGHT.
+ * You may freely copy it for use as a template for your own field types.
+ * If you develop a field type that might be of general use, please send
+ * it back to the ncurses maintainers for inclusion in the next version.
+ */
+/***************************************************************************
+* *
+* Author : Juergen Pfeifer, juergen.pfeifer@gmx.net *
+* *
+***************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id$")
+
+typedef struct {
+ int width;
+} alnumARG;
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void *Make_AlphaNumeric_Type(va_list *ap)
+|
+| Description : Allocate structure for alphanumeric type argument.
+|
+| Return Values : Pointer to argument structure or NULL on error
++--------------------------------------------------------------------------*/
+static void *Make_AlphaNumeric_Type(va_list * ap)
+{
+ alnumARG *argp = (alnumARG *)malloc(sizeof(alnumARG));
+
+ if (argp)
+ argp->width = va_arg(*ap,int);
+
+ return ((void *)argp);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void *Copy_AlphaNumericType(const void *argp)
+|
+| Description : Copy structure for alphanumeric type argument.
+|
+| Return Values : Pointer to argument structure or NULL on error.
++--------------------------------------------------------------------------*/
+static void *Copy_AlphaNumeric_Type(const void *argp)
+{
+ const alnumARG *ap = (const alnumARG *)argp;
+ alnumARG *result = (alnumARG *)malloc(sizeof(alnumARG));
+
+ if (result)
+ *result = *ap;
+
+ return ((void *)result);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void Free_AlphaNumeric_Type(void *argp)
+|
+| Description : Free structure for alphanumeric type argument.
+|
+| Return Values : -
++--------------------------------------------------------------------------*/
+static void Free_AlphaNumeric_Type(void * argp)
+{
+ if (argp)
+ free(argp);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Check_AlphaNumeric_Field(
+| FIELD *field,
+| const void *argp)
+|
+| Description : Validate buffer content to be a valid alphanumeric value
+|
+| Return Values : TRUE - field is valid
+| FALSE - field is invalid
++--------------------------------------------------------------------------*/
+static bool Check_AlphaNumeric_Field(FIELD * field, const void * argp)
+{
+ int width = ((const alnumARG *)argp)->width;
+ unsigned char *bp = (unsigned char *)field_buffer(field,0);
+ int l = -1;
+ unsigned char *s;
+
+ while(*bp && *bp==' ')
+ bp++;
+ if (*bp)
+ {
+ s = bp;
+ while(*bp && isalnum(*bp))
+ bp++;
+ l = (int)(bp-s);
+ while(*bp && *bp==' ')
+ bp++;
+ }
+ return ((*bp || (l < width)) ? FALSE : TRUE);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Check_AlphaNumeric_Character(
+| int c,
+| const void *argp )
+|
+| Description : Check a character for the alphanumeric type.
+|
+| Return Values : TRUE - character is valid
+| FALSE - character is invalid
++--------------------------------------------------------------------------*/
+static bool Check_AlphaNumeric_Character(int c, const void * argp)
+{
+ argp=0; /* Silence unused parameter warning. */
+ return (isalnum(c) ? TRUE : FALSE);
+}
+
+static FIELDTYPE typeALNUM = {
+ _HAS_ARGS | _RESIDENT,
+ 1, /* this is mutable, so we can't be const */
+ (FIELDTYPE *)0,
+ (FIELDTYPE *)0,
+ Make_AlphaNumeric_Type,
+ Copy_AlphaNumeric_Type,
+ Free_AlphaNumeric_Type,
+ Check_AlphaNumeric_Field,
+ Check_AlphaNumeric_Character,
+ NULL,
+ NULL
+};
+
+FIELDTYPE* TYPE_ALNUM = &typeALNUM;
+
+/* fty_alnum.c ends here */
diff --git a/Source/CursesDialog/form/fty_alpha.c b/Source/CursesDialog/form/fty_alpha.c
new file mode 100644
index 000000000..e4e9ceb1c
--- /dev/null
+++ b/Source/CursesDialog/form/fty_alpha.c
@@ -0,0 +1,139 @@
+
+/*
+ * THIS CODE IS SPECIFICALLY EXEMPTED FROM THE NCURSES PACKAGE COPYRIGHT.
+ * You may freely copy it for use as a template for your own field types.
+ * If you develop a field type that might be of general use, please send
+ * it back to the ncurses maintainers for inclusion in the next version.
+ */
+/***************************************************************************
+* *
+* Author : Juergen Pfeifer, juergen.pfeifer@gmx.net *
+* *
+***************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id$")
+
+typedef struct {
+ int width;
+} alphaARG;
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void *Make_Alpha_Type(va_list *ap)
+|
+| Description : Allocate structure for alpha type argument.
+|
+| Return Values : Pointer to argument structure or NULL on error
++--------------------------------------------------------------------------*/
+static void *Make_Alpha_Type(va_list * ap)
+{
+ alphaARG *argp = (alphaARG *)malloc(sizeof(alphaARG));
+ if (argp)
+ {
+ argp->width = va_arg(*ap,int);
+ }
+ return ((void *)argp);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void *Copy_Alpha_Type(const void * argp)
+|
+| Description : Copy structure for alpha type argument.
+|
+| Return Values : Pointer to argument structure or NULL on error.
++--------------------------------------------------------------------------*/
+static void *Copy_Alpha_Type(const void * argp)
+{
+ const alphaARG *ap = (const alphaARG *)argp;
+ alphaARG *result = (alphaARG *)malloc(sizeof(alphaARG));
+
+ if (result)
+ {
+ *result = *ap;
+ }
+ return ((void *)result);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void Free_Alpha_Type( void * argp )
+|
+| Description : Free structure for alpha type argument.
+|
+| Return Values : -
++--------------------------------------------------------------------------*/
+static void Free_Alpha_Type(void * argp)
+{
+ if (argp)
+ free(argp);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Check_Alpha_Field(
+| FIELD * field,
+| const void * argp)
+|
+| Description : Validate buffer content to be a valid alpha value
+|
+| Return Values : TRUE - field is valid
+| FALSE - field is invalid
++--------------------------------------------------------------------------*/
+static bool Check_Alpha_Field(FIELD * field, const void * argp)
+{
+ int width = ((const alphaARG *)argp)->width;
+ unsigned char *bp = (unsigned char *)field_buffer(field,0);
+ int l = -1;
+ unsigned char *s;
+
+ while(*bp && *bp==' ')
+ bp++;
+ if (*bp)
+ {
+ s = bp;
+ while(*bp && isalpha(*bp))
+ bp++;
+ l = (int)(bp-s);
+ while(*bp && *bp==' ')
+ bp++;
+ }
+ return ((*bp || (l < width)) ? FALSE : TRUE);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Check_Alpha_Character(
+| int c,
+| const void * argp)
+|
+| Description : Check a character for the alpha type.
+|
+| Return Values : TRUE - character is valid
+| FALSE - character is invalid
++--------------------------------------------------------------------------*/
+static bool Check_Alpha_Character(int c, const void * argp)
+{
+ argp=0; /* Silence unused parameter warning. */
+ return (isalpha(c) ? TRUE : FALSE);
+}
+
+static FIELDTYPE typeALPHA = {
+ _HAS_ARGS | _RESIDENT,
+ 1, /* this is mutable, so we can't be const */
+ (FIELDTYPE *)0,
+ (FIELDTYPE *)0,
+ Make_Alpha_Type,
+ Copy_Alpha_Type,
+ Free_Alpha_Type,
+ Check_Alpha_Field,
+ Check_Alpha_Character,
+ NULL,
+ NULL
+};
+
+FIELDTYPE* TYPE_ALPHA = &typeALPHA;
+
+/* fty_alpha.c ends here */
diff --git a/Source/CursesDialog/form/fty_enum.c b/Source/CursesDialog/form/fty_enum.c
new file mode 100644
index 000000000..8fc4cd7b6
--- /dev/null
+++ b/Source/CursesDialog/form/fty_enum.c
@@ -0,0 +1,295 @@
+
+/*
+ * THIS CODE IS SPECIFICALLY EXEMPTED FROM THE NCURSES PACKAGE COPYRIGHT.
+ * You may freely copy it for use as a template for your own field types.
+ * If you develop a field type that might be of general use, please send
+ * it back to the ncurses maintainers for inclusion in the next version.
+ */
+/***************************************************************************
+* *
+* Author : Juergen Pfeifer, juergen.pfeifer@gmx.net *
+* *
+***************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id$")
+
+typedef struct {
+ char **kwds;
+ int count;
+ bool checkcase;
+ bool checkunique;
+} enumARG;
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void *Make_Enum_Type( va_list * ap )
+|
+| Description : Allocate structure for enumeration type argument.
+|
+| Return Values : Pointer to argument structure or NULL on error
++--------------------------------------------------------------------------*/
+static void *Make_Enum_Type(va_list * ap)
+{
+ enumARG *argp = (enumARG *)malloc(sizeof(enumARG));
+
+ if (argp)
+ {
+ int cnt = 0;
+ char **kp = (char **)0;
+ int ccase, cunique;
+
+ argp->kwds = va_arg(*ap,char **);
+ ccase = va_arg(*ap,int);
+ cunique = va_arg(*ap,int);
+ argp->checkcase = ccase ? TRUE : FALSE;
+ argp->checkunique = cunique ? TRUE : FALSE;
+
+ kp = argp->kwds;
+ while( kp && (*kp++) ) cnt++;
+ argp->count = cnt;
+ }
+ return (void *)argp;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void *Copy_Enum_Type( const void * argp )
+|
+| Description : Copy structure for enumeration type argument.
+|
+| Return Values : Pointer to argument structure or NULL on error.
++--------------------------------------------------------------------------*/
+static void *Copy_Enum_Type(const void * argp)
+{
+ enumARG *result = (enumARG *)0;
+
+ if (argp)
+ {
+ const enumARG *ap = (const enumARG *)argp;
+
+ result = (enumARG *)malloc(sizeof(enumARG));
+ if (result)
+ *result = *ap;
+ }
+ return (void *)result;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void Free_Enum_Type( void * argp )
+|
+| Description : Free structure for enumeration type argument.
+|
+| Return Values : -
++--------------------------------------------------------------------------*/
+static void Free_Enum_Type(void * argp)
+{
+ if (argp)
+ free(argp);
+}
+
+#define SKIP_SPACE(x) while(((*(x))!='\0') && (is_blank(*(x)))) (x)++
+#define NOMATCH 0
+#define PARTIAL 1
+#define EXACT 2
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static int Compare(const unsigned char * s,
+| const unsigned char * buf,
+| bool ccase )
+|
+| Description : Check wether or not the text in 'buf' matches the
+| text in 's', at least partial.
+|
+| Return Values : NOMATCH - buffer doesn't match
+| PARTIAL - buffer matches partially
+| EXACT - buffer matches exactly
++--------------------------------------------------------------------------*/
+static int Compare(const unsigned char *s, const unsigned char *buf,
+ bool ccase)
+{
+ SKIP_SPACE(buf); /* Skip leading spaces in both texts */
+ SKIP_SPACE(s);
+
+ if (*buf=='\0')
+ {
+ return (((*s)!='\0') ? NOMATCH : EXACT);
+ }
+ else
+ {
+ if (ccase)
+ {
+ while(*s++ == *buf)
+ {
+ if (*buf++=='\0') return EXACT;
+ }
+ }
+ else
+ {
+ while(toupper(*s++)==toupper(*buf))
+ {
+ if (*buf++=='\0') return EXACT;
+ }
+ }
+ }
+ /* At this location buf points to the first character where it no longer
+ matches with s. So if only blanks are following, we have a partial
+ match otherwise there is no match */
+ SKIP_SPACE(buf);
+ if (*buf)
+ return NOMATCH;
+
+ /* If it happens that the reference buffer is at its end, the partial
+ match is actually an exact match. */
+ return ((s[-1]!='\0') ? PARTIAL : EXACT);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Check_Enum_Field(
+| FIELD * field,
+| const void * argp)
+|
+| Description : Validate buffer content to be a valid enumeration value
+|
+| Return Values : TRUE - field is valid
+| FALSE - field is invalid
++--------------------------------------------------------------------------*/
+static bool Check_Enum_Field(FIELD * field, const void * argp)
+{
+ char **kwds = ((const enumARG *)argp)->kwds;
+ bool ccase = ((const enumARG *)argp)->checkcase;
+ bool unique = ((const enumARG *)argp)->checkunique;
+ unsigned char *bp = (unsigned char *)field_buffer(field,0);
+ char *s, *t, *p;
+ int res;
+
+ while( kwds && (s=(*kwds++)) )
+ {
+ if ((res=Compare((unsigned char *)s,bp,ccase))!=NOMATCH)
+ {
+ p=t=s; /* t is at least a partial match */
+ if ((unique && res!=EXACT))
+ {
+ while( kwds && (p = *kwds++) )
+ {
+ if ((res=Compare((unsigned char *)p,bp,ccase))!=NOMATCH)
+ {
+ if (res==EXACT)
+ {
+ t = p;
+ break;
+ }
+ else
+ t = (char *)0;
+ }
+ }
+ }
+ if (t)
+ {
+ set_field_buffer(field,0,t);
+ return TRUE;
+ }
+ if (!p)
+ break;
+ }
+ }
+ return FALSE;
+}
+
+static const char *dummy[] = { (char *)0 };
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Next_Enum(FIELD * field,
+| const void * argp)
+|
+| Description : Check for the next enumeration value
+|
+| Return Values : TRUE - next value found and loaded
+| FALSE - no next value loaded
++--------------------------------------------------------------------------*/
+static bool Next_Enum(FIELD * field, const void * argp)
+{
+ const enumARG *args = (const enumARG *)argp;
+ char **kwds = args->kwds;
+ bool ccase = args->checkcase;
+ int cnt = args->count;
+ unsigned char *bp = (unsigned char *)field_buffer(field,0);
+
+ if (kwds) {
+ while(cnt--)
+ {
+ if (Compare((unsigned char *)(*kwds++),bp,ccase)==EXACT)
+ break;
+ }
+ if (cnt<=0)
+ kwds = args->kwds;
+ if ((cnt>=0) || (Compare((const unsigned char *)dummy,bp,ccase)==EXACT))
+ {
+ set_field_buffer(field,0,*kwds);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Previous_Enum(
+| FIELD * field,
+| const void * argp)
+|
+| Description : Check for the previous enumeration value
+|
+| Return Values : TRUE - previous value found and loaded
+| FALSE - no previous value loaded
++--------------------------------------------------------------------------*/
+static bool Previous_Enum(FIELD * field, const void * argp)
+{
+ const enumARG *args = (const enumARG *)argp;
+ int cnt = args->count;
+ char **kwds = &args->kwds[cnt-1];
+ bool ccase = args->checkcase;
+ unsigned char *bp = (unsigned char *)field_buffer(field,0);
+
+ if (kwds) {
+ while(cnt--)
+ {
+ if (Compare((unsigned char *)(*kwds--),bp,ccase)==EXACT)
+ break;
+ }
+
+ if (cnt<=0)
+ kwds = &args->kwds[args->count-1];
+
+ if ((cnt>=0) || (Compare((const unsigned char *)dummy,bp,ccase)==EXACT))
+ {
+ set_field_buffer(field,0,*kwds);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+
+static FIELDTYPE typeENUM = {
+ _HAS_ARGS | _HAS_CHOICE | _RESIDENT,
+ 1, /* this is mutable, so we can't be const */
+ (FIELDTYPE *)0,
+ (FIELDTYPE *)0,
+ Make_Enum_Type,
+ Copy_Enum_Type,
+ Free_Enum_Type,
+ Check_Enum_Field,
+ NULL,
+ Next_Enum,
+ Previous_Enum
+};
+
+FIELDTYPE* TYPE_ENUM = &typeENUM;
+
+/* fty_enum.c ends here */
diff --git a/Source/CursesDialog/form/fty_int.c b/Source/CursesDialog/form/fty_int.c
new file mode 100644
index 000000000..7107fcc3f
--- /dev/null
+++ b/Source/CursesDialog/form/fty_int.c
@@ -0,0 +1,161 @@
+
+/*
+ * THIS CODE IS SPECIFICALLY EXEMPTED FROM THE NCURSES PACKAGE COPYRIGHT.
+ * You may freely copy it for use as a template for your own field types.
+ * If you develop a field type that might be of general use, please send
+ * it back to the ncurses maintainers for inclusion in the next version.
+ */
+/***************************************************************************
+* *
+* Author : Juergen Pfeifer, juergen.pfeifer@gmx.net *
+* *
+***************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id$")
+
+typedef struct {
+ int precision;
+ long low;
+ long high;
+} integerARG;
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void *Make_Integer_Type( va_list * ap )
+|
+| Description : Allocate structure for integer type argument.
+|
+| Return Values : Pointer to argument structure or NULL on error
++--------------------------------------------------------------------------*/
+static void *Make_Integer_Type(va_list * ap)
+{
+ integerARG *argp = (integerARG *)malloc(sizeof(integerARG));
+
+ if (argp)
+ {
+ argp->precision = va_arg(*ap,int);
+ argp->low = va_arg(*ap,long);
+ argp->high = va_arg(*ap,long);
+ }
+ return (void *)argp;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void *Copy_Integer_Type(const void * argp)
+|
+| Description : Copy structure for integer type argument.
+|
+| Return Values : Pointer to argument structure or NULL on error.
++--------------------------------------------------------------------------*/
+static void *Copy_Integer_Type(const void * argp)
+{
+ const integerARG *ap = (const integerARG *)argp;
+ integerARG *result = (integerARG *)0;
+
+ if (argp)
+ {
+ result = (integerARG *)malloc(sizeof(integerARG));
+ if (result)
+ *result = *ap;
+ }
+ return (void *)result;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void Free_Integer_Type(void * argp)
+|
+| Description : Free structure for integer type argument.
+|
+| Return Values : -
++--------------------------------------------------------------------------*/
+static void Free_Integer_Type(void * argp)
+{
+ if (argp)
+ free(argp);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Check_Integer_Field(
+| FIELD * field,
+| const void * argp)
+|
+| Description : Validate buffer content to be a valid integer value
+|
+| Return Values : TRUE - field is valid
+| FALSE - field is invalid
++--------------------------------------------------------------------------*/
+static bool Check_Integer_Field(FIELD * field, const void * argp)
+{
+ const integerARG *argi = (const integerARG *)argp;
+ long low = argi->low;
+ long high = argi->high;
+ int prec = argi->precision;
+ unsigned char *bp = (unsigned char *)field_buffer(field,0);
+ char *s = (char *)bp;
+ long val;
+ char buf[100];
+
+ while( *bp && *bp==' ') bp++;
+ if (*bp)
+ {
+ if (*bp=='-') bp++;
+ while (*bp)
+ {
+ if (!isdigit(*bp)) break;
+ bp++;
+ }
+ while(*bp && *bp==' ') bp++;
+ if (*bp=='\0')
+ {
+ val = atol(s);
+ if (low<high)
+ {
+ if (val<low || val>high) return FALSE;
+ }
+ sprintf(buf,"%.*ld",(prec>0?prec:0),val);
+ set_field_buffer(field,0,buf);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Check_Integer_Character(
+| int c,
+| const void * argp)
+|
+| Description : Check a character for the integer type.
+|
+| Return Values : TRUE - character is valid
+| FALSE - character is invalid
++--------------------------------------------------------------------------*/
+static bool Check_Integer_Character(int c, const void * argp)
+{
+ argp=0; /* Silence unused parameter warning. */
+ return ((isdigit(c) || (c=='-')) ? TRUE : FALSE);
+}
+
+static FIELDTYPE typeINTEGER = {
+ _HAS_ARGS | _RESIDENT,
+ 1, /* this is mutable, so we can't be const */
+ (FIELDTYPE *)0,
+ (FIELDTYPE *)0,
+ Make_Integer_Type,
+ Copy_Integer_Type,
+ Free_Integer_Type,
+ Check_Integer_Field,
+ Check_Integer_Character,
+ NULL,
+ NULL
+};
+
+FIELDTYPE* TYPE_INTEGER = &typeINTEGER;
+
+/* fty_int.c ends here */
diff --git a/Source/CursesDialog/form/fty_ipv4.c b/Source/CursesDialog/form/fty_ipv4.c
new file mode 100644
index 000000000..4ac8a50ec
--- /dev/null
+++ b/Source/CursesDialog/form/fty_ipv4.c
@@ -0,0 +1,84 @@
+
+/*
+ * THIS CODE IS SPECIFICALLY EXEMPTED FROM THE NCURSES PACKAGE COPYRIGHT.
+ * You may freely copy it for use as a template for your own field types.
+ * If you develop a field type that might be of general use, please send
+ * it back to the ncurses maintainers for inclusion in the next version.
+ */
+/***************************************************************************
+* *
+* Author : Per Foreby, perf@efd.lth.se *
+* *
+***************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id$")
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Check_IPV4_Field(
+| FIELD * field,
+| const void * argp)
+|
+| Description : Validate buffer content to be a valid IP number (Ver. 4)
+|
+| Return Values : TRUE - field is valid
+| FALSE - field is invalid
++--------------------------------------------------------------------------*/
+static bool Check_IPV4_Field(FIELD * field, const void * argp)
+{
+ char *bp = field_buffer(field,0);
+ int num = 0, len;
+ unsigned int d1, d2, d3, d4;
+
+ argp=0; /* Silence unused parameter warning. */
+
+ if(isdigit((int)(*bp))) /* Must start with digit */
+ {
+ num = sscanf(bp, "%u.%u.%u.%u%n", &d1, &d2, &d3, &d4, &len);
+ if (num == 4)
+ {
+ bp += len; /* Make bp point to what sscanf() left */
+ while (*bp && isspace((int)(*bp)))
+ bp++; /* Allow trailing whitespace */
+ }
+ }
+ return ((num != 4 || *bp || d1 > 255 || d2 > 255
+ || d3 > 255 || d4 > 255) ? FALSE : TRUE);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Check_IPV4_Character(
+| int c,
+| const void *argp )
+|
+| Description : Check a character for unsigned type or period.
+|
+| Return Values : TRUE - character is valid
+| FALSE - character is invalid
++--------------------------------------------------------------------------*/
+static bool Check_IPV4_Character(int c, const void * argp)
+{
+ argp=0; /* Silence unused parameter warning. */
+ return ((isdigit(c) || (c=='.')) ? TRUE : FALSE);
+}
+
+static FIELDTYPE typeIPV4 = {
+ _RESIDENT,
+ 1, /* this is mutable, so we can't be const */
+ (FIELDTYPE *)0,
+ (FIELDTYPE *)0,
+ NULL,
+ NULL,
+ NULL,
+ Check_IPV4_Field,
+ Check_IPV4_Character,
+ NULL,
+ NULL
+};
+
+FIELDTYPE* TYPE_IPV4 = &typeIPV4;
+
+/* fty_ipv4.c ends here */
diff --git a/Source/CursesDialog/form/fty_num.c b/Source/CursesDialog/form/fty_num.c
new file mode 100644
index 000000000..78095995f
--- /dev/null
+++ b/Source/CursesDialog/form/fty_num.c
@@ -0,0 +1,192 @@
+
+/*
+ * THIS CODE IS SPECIFICALLY EXEMPTED FROM THE NCURSES PACKAGE COPYRIGHT.
+ * You may freely copy it for use as a template for your own field types.
+ * If you develop a field type that might be of general use, please send
+ * it back to the ncurses maintainers for inclusion in the next version.
+ */
+/***************************************************************************
+* *
+* Author : Juergen Pfeifer, juergen.pfeifer@gmx.net *
+* *
+***************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id$")
+
+#if HAVE_LOCALE_H
+#include <locale.h>
+#endif
+
+typedef struct {
+ int precision;
+ double low;
+ double high;
+ struct lconv* L;
+} numericARG;
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void *Make_Numeric_Type(va_list * ap)
+|
+| Description : Allocate structure for numeric type argument.
+|
+| Return Values : Pointer to argument structure or NULL on error
++--------------------------------------------------------------------------*/
+static void *Make_Numeric_Type(va_list * ap)
+{
+ numericARG *argn = (numericARG *)malloc(sizeof(numericARG));
+
+ if (argn)
+ {
+ argn->precision = va_arg(*ap,int);
+ argn->low = va_arg(*ap,double);
+ argn->high = va_arg(*ap,double);
+#if HAVE_LOCALE_H
+ argn->L = localeconv();
+#else
+ argn->L = NULL;
+#endif
+ }
+ return (void *)argn;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void *Copy_Numeric_Type(const void * argp)
+|
+| Description : Copy structure for numeric type argument.
+|
+| Return Values : Pointer to argument structure or NULL on error.
++--------------------------------------------------------------------------*/
+static void *Copy_Numeric_Type(const void * argp)
+{
+ const numericARG *ap = (const numericARG *)argp;
+ numericARG *result = (numericARG *)0;
+
+ if (argp)
+ {
+ result = (numericARG *)malloc(sizeof(numericARG));
+ if (result)
+ *result = *ap;
+ }
+ return (void *)result;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void Free_Numeric_Type(void * argp)
+|
+| Description : Free structure for numeric type argument.
+|
+| Return Values : -
++--------------------------------------------------------------------------*/
+static void Free_Numeric_Type(void * argp)
+{
+ if (argp)
+ free(argp);
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Check_Numeric_Field(FIELD * field,
+| const void * argp)
+|
+| Description : Validate buffer content to be a valid numeric value
+|
+| Return Values : TRUE - field is valid
+| FALSE - field is invalid
++--------------------------------------------------------------------------*/
+static bool Check_Numeric_Field(FIELD * field, const void * argp)
+{
+ const numericARG *argn = (const numericARG *)argp;
+ double low = argn->low;
+ double high = argn->high;
+ int prec = argn->precision;
+ unsigned char *bp = (unsigned char *)field_buffer(field,0);
+ char *s = (char *)bp;
+ double val = 0.0;
+ char buf[64];
+
+ while(*bp && *bp==' ') bp++;
+ if (*bp)
+ {
+ if (*bp=='-' || *bp=='+')
+ bp++;
+ while(*bp)
+ {
+ if (!isdigit(*bp)) break;
+ bp++;
+ }
+ if (*bp==(
+#if HAVE_LOCALE_H
+ (L && L->decimal_point) ? *(L->decimal_point) :
+#endif
+ '.'))
+ {
+ bp++;
+ while(*bp)
+ {
+ if (!isdigit(*bp)) break;
+ bp++;
+ }
+ }
+ while(*bp && *bp==' ') bp++;
+ if (*bp=='\0')
+ {
+ val = atof(s);
+ if (low<high)
+ {
+ if (val<low || val>high) return FALSE;
+ }
+ sprintf(buf,"%.*f",(prec>0?prec:0),val);
+ set_field_buffer(field,0,buf);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Check_Numeric_Character(
+| int c,
+| const void * argp)
+|
+| Description : Check a character for the numeric type.
+|
+| Return Values : TRUE - character is valid
+| FALSE - character is invalid
++--------------------------------------------------------------------------*/
+static bool Check_Numeric_Character(int c, const void * argp)
+{
+ argp=0; /* Silence unused parameter warning. */
+ return (isdigit(c) ||
+ c == '+' ||
+ c == '-' ||
+ c == (
+#if HAVE_LOCALE_H
+ (L && L->decimal_point) ? *(L->decimal_point) :
+#endif
+ '.')
+ ) ? TRUE : FALSE;
+}
+
+static FIELDTYPE typeNUMERIC = {
+ _HAS_ARGS | _RESIDENT,
+ 1, /* this is mutable, so we can't be const */
+ (FIELDTYPE *)0,
+ (FIELDTYPE *)0,
+ Make_Numeric_Type,
+ Copy_Numeric_Type,
+ Free_Numeric_Type,
+ Check_Numeric_Field,
+ Check_Numeric_Character,
+ NULL,
+ NULL
+};
+
+FIELDTYPE* TYPE_NUMERIC = &typeNUMERIC;
+
+/* fty_num.c ends here */
diff --git a/Source/CursesDialog/form/fty_regex.c b/Source/CursesDialog/form/fty_regex.c
new file mode 100644
index 000000000..0af1cef17
--- /dev/null
+++ b/Source/CursesDialog/form/fty_regex.c
@@ -0,0 +1,264 @@
+
+/*
+ * THIS CODE IS SPECIFICALLY EXEMPTED FROM THE NCURSES PACKAGE COPYRIGHT.
+ * You may freely copy it for use as a template for your own field types.
+ * If you develop a field type that might be of general use, please send
+ * it back to the ncurses maintainers for inclusion in the next version.
+ */
+/***************************************************************************
+* *
+* Author : Juergen Pfeifer, juergen.pfeifer@gmx.net *
+* *
+***************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id$")
+
+#if HAVE_REGEX_H_FUNCS /* We prefer POSIX regex */
+#include <regex.h>
+
+typedef struct
+{
+ regex_t *pRegExp;
+ unsigned long *refCount;
+} RegExp_Arg;
+
+#elif HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS
+#undef RETURN
+static int reg_errno;
+
+static char *RegEx_Init(char *instring)
+{
+ reg_errno = 0;
+ return instring;
+}
+
+static char *RegEx_Error(int code)
+{
+ reg_errno = code;
+ return 0;
+}
+
+#define INIT register char *sp = RegEx_Init(instring);
+#define GETC() (*sp++)
+#define PEEKC() (*sp)
+#define UNGETC(c) (--sp)
+#define RETURN(c) return(c)
+#define ERROR(c) return RegEx_Error(c)
+
+#if HAVE_REGEXP_H_FUNCS
+#include <regexp.h>
+#else
+#include <regexpr.h>
+#endif
+
+typedef struct
+{
+ char *compiled_expression;
+ unsigned long *refCount;
+} RegExp_Arg;
+
+/* Maximum Length we allow for a compiled regular expression */
+#define MAX_RX_LEN (2048)
+#define RX_INCREMENT (256)
+
+#endif
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void *Make_RegularExpression_Type(va_list * ap)
+|
+| Description : Allocate structure for regex type argument.
+|
+| Return Values : Pointer to argument structure or NULL on error
++--------------------------------------------------------------------------*/
+static void *Make_RegularExpression_Type(va_list * ap)
+{
+#if HAVE_REGEX_H_FUNCS
+ char *rx = va_arg(*ap,char *);
+ RegExp_Arg *preg;
+
+ preg = (RegExp_Arg*)malloc(sizeof(RegExp_Arg));
+ if (preg)
+ {
+ if (((preg->pRegExp = (regex_t*)malloc(sizeof(regex_t))) != (regex_t*)0)
+ && !regcomp(preg->pRegExp,rx,
+ (REG_EXTENDED | REG_NOSUB | REG_NEWLINE) ))
+ {
+ preg->refCount = (unsigned long *)malloc(sizeof(unsigned long));
+ *(preg->refCount) = 1;
+ }
+ else
+ {
+ if (preg->pRegExp)
+ free(preg->pRegExp);
+ free(preg);
+ preg = (RegExp_Arg*)0;
+ }
+ }
+ return((void *)preg);
+#elif HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS
+ char *rx = va_arg(*ap,char *);
+ RegExp_Arg *pArg;
+
+ pArg = (RegExp_Arg *)malloc(sizeof(RegExp_Arg));
+
+ if (pArg)
+ {
+ int blen = RX_INCREMENT;
+ pArg->compiled_expression = NULL;
+ pArg->refCount = (unsigned long *)malloc(sizeof(unsigned long));
+ *(pArg->refCount) = 1;
+
+ do {
+ char *buf = (char *)malloc(blen);
+ if (buf)
+ {
+#if HAVE_REGEXP_H_FUNCS
+ char *last_pos = compile (rx, buf, &buf[blen], '\0');
+#else /* HAVE_REGEXPR_H_FUNCS */
+ char *last_pos = compile (rx, buf, &buf[blen]);
+#endif
+ if (reg_errno)
+ {
+ free(buf);
+ if (reg_errno==50)
+ blen += RX_INCREMENT;
+ else
+ {
+ free(pArg);
+ pArg = NULL;
+ break;
+ }
+ }
+ else
+ {
+ pArg->compiled_expression = buf;
+ break;
+ }
+ }
+ } while( blen <= MAX_RX_LEN );
+ }
+ if (pArg && !pArg->compiled_expression)
+ {
+ free(pArg);
+ pArg = NULL;
+ }
+ return (void *)pArg;
+#else
+ ap=0; /* Silence unused parameter warning. */
+ return 0;
+#endif
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void *Copy_RegularExpression_Type(
+| const void * argp)
+|
+| Description : Copy structure for regex type argument.
+|
+| Return Values : Pointer to argument structure or NULL on error.
++--------------------------------------------------------------------------*/
+static void *Copy_RegularExpression_Type(const void * argp)
+{
+#if (HAVE_REGEX_H_FUNCS | HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS)
+ const RegExp_Arg *ap = (const RegExp_Arg *)argp;
+ const RegExp_Arg *result = (const RegExp_Arg *)0;
+
+ if (ap)
+ {
+ *(ap->refCount) += 1;
+ result = ap;
+ }
+ return (void *)result;
+#else
+ argp=0; /* Silence unused parameter warning. */
+ return 0;
+#endif
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static void Free_RegularExpression_Type(void * argp)
+|
+| Description : Free structure for regex type argument.
+|
+| Return Values : -
++--------------------------------------------------------------------------*/
+static void Free_RegularExpression_Type(void * argp)
+{
+#if HAVE_REGEX_H_FUNCS | HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS
+ RegExp_Arg *ap = (RegExp_Arg *)argp;
+ if (ap)
+ {
+ if (--(*(ap->refCount)) == 0)
+ {
+#if HAVE_REGEX_H_FUNCS
+ if (ap->pRegExp)
+ {
+ free(ap->refCount);
+ regfree(ap->pRegExp);
+ }
+#elif HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS
+ if (ap->compiled_expression)
+ {
+ free(ap->refCount);
+ free(ap->compiled_expression);
+ }
+#endif
+ free(ap);
+ }
+ }
+#else
+ argp=0; /* Silence unused parameter warning. */
+#endif
+}
+
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : static bool Check_RegularExpression_Field(
+| FIELD * field,
+| const void * argp)
+|
+| Description : Validate buffer content to be a valid regular expression
+|
+| Return Values : TRUE - field is valid
+| FALSE - field is invalid
++--------------------------------------------------------------------------*/
+static bool Check_RegularExpression_Field(FIELD * field, const void * argp)
+{
+ bool match = FALSE;
+#if HAVE_REGEX_H_FUNCS
+ const RegExp_Arg *ap = (const RegExp_Arg*)argp;
+ if (ap && ap->pRegExp)
+ match = (regexec(ap->pRegExp,field_buffer(field,0),0,NULL,0) ? FALSE:TRUE);
+#elif HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS
+ RegExp_Arg *ap = (RegExp_Arg *)argp;
+ if (ap && ap->compiled_expression)
+ match = (step(field_buffer(field,0),ap->compiled_expression) ? TRUE:FALSE);
+#else
+ argp=0; /* Silence unused parameter warning. */
+ field=0; /* Silence unused parameter warning. */
+#endif
+ return match;
+}
+
+static FIELDTYPE typeREGEXP = {
+ _HAS_ARGS | _RESIDENT,
+ 1, /* this is mutable, so we can't be const */
+ (FIELDTYPE *)0,
+ (FIELDTYPE *)0,
+ Make_RegularExpression_Type,
+ Copy_RegularExpression_Type,
+ Free_RegularExpression_Type,
+ Check_RegularExpression_Field,
+ NULL,
+ NULL,
+ NULL
+};
+
+FIELDTYPE* TYPE_REGEXP = &typeREGEXP;
+
+/* fty_regex.c ends here */
diff --git a/Source/CursesDialog/form/llib-lform b/Source/CursesDialog/form/llib-lform
new file mode 100644
index 000000000..ac2ba436d
--- /dev/null
+++ b/Source/CursesDialog/form/llib-lform
@@ -0,0 +1,694 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 ABOVE 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. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Thomas E. Dickey <dickey@clark.net> 1996,1997 *
+ ****************************************************************************/
+/* LINTLIBRARY */
+
+/* ./fld_arg.c */
+
+#include "form.priv.h"
+
+#undef set_fieldtype_arg
+int set_fieldtype_arg(
+ FIELDTYPE *typ,
+ void *(*const make_arg)(
+ va_list *p1),
+ void *(*const copy_arg)(
+ const void *p1),
+ void (*const free_arg)(
+ void *p1))
+ { return(*(int *)0); }
+
+#undef field_arg
+void *field_arg(
+ const FIELD *field)
+ { return(*(void **)0); }
+
+/* ./fld_attr.c */
+
+#undef set_field_fore
+int set_field_fore(
+ FIELD *field,
+ chtype attr)
+ { return(*(int *)0); }
+
+#undef field_fore
+chtype field_fore(
+ const FIELD *field)
+ { return(*(chtype *)0); }
+
+#undef set_field_back
+int set_field_back(
+ FIELD *field,
+ chtype attr)
+ { return(*(int *)0); }
+
+#undef field_back
+chtype field_back(
+ const FIELD *field)
+ { return(*(chtype *)0); }
+
+/* ./fld_current.c */
+
+#undef set_current_field
+int set_current_field(
+ FORM *form,
+ FIELD *field)
+ { return(*(int *)0); }
+
+#undef current_field
+FIELD *current_field(
+ const FORM *form)
+ { return(*(FIELD **)0); }
+
+#undef field_index
+int field_index(
+ const FIELD *field)
+ { return(*(int *)0); }
+
+/* ./fld_def.c */
+
+#undef _nc_Default_Field
+FIELD *_nc_Default_Field;
+
+#undef _nc_Make_Argument
+TypeArgument *_nc_Make_Argument(
+ const FIELDTYPE *typ,
+ va_list *ap,
+ int *err)
+ { return(*(TypeArgument **)0); }
+
+#undef _nc_Copy_Argument
+TypeArgument *_nc_Copy_Argument(
+ const FIELDTYPE *typ,
+ const TypeArgument *argp,
+ int *err)
+ { return(*(TypeArgument **)0); }
+
+#undef _nc_Free_Argument
+void _nc_Free_Argument(
+ const FIELDTYPE *typ,
+ TypeArgument *argp)
+ { /* void */ }
+
+#undef _nc_Copy_Type
+bool _nc_Copy_Type(
+ FIELD *dst,
+ FIELD const *src)
+ { return(*(bool *)0); }
+
+#undef _nc_Free_Type
+void _nc_Free_Type(
+ FIELD *field)
+ { /* void */ }
+
+#undef new_field
+FIELD *new_field(
+ int rows,
+ int cols,
+ int frow,
+ int fcol,
+ int nrow,
+ int nbuf)
+ { return(*(FIELD **)0); }
+
+#undef free_field
+int free_field(
+ FIELD *field)
+ { return(*(int *)0); }
+
+/* ./fld_dup.c */
+
+#undef dup_field
+FIELD *dup_field(
+ FIELD *field,
+ int frow,
+ int fcol)
+ { return(*(FIELD **)0); }
+
+/* ./fld_ftchoice.c */
+
+#undef set_fieldtype_choice
+int set_fieldtype_choice(
+ FIELDTYPE *typ,
+ bool (*const next_choice)(
+ FIELD *p1,
+ const void *p2),
+ bool (*const prev_choice)(
+ FIELD *p1,
+ const void *p2))
+ { return(*(int *)0); }
+
+/* ./fld_ftlink.c */
+
+#undef link_fieldtype
+FIELDTYPE *link_fieldtype(
+ FIELDTYPE *type1,
+ FIELDTYPE *type2)
+ { return(*(FIELDTYPE **)0); }
+
+/* ./fld_info.c */
+
+#undef field_info
+int field_info(
+ const FIELD *field,
+ int *rows,
+ int *cols,
+ int *frow,
+ int *fcol,
+ int *nrow,
+ int *nbuf)
+ { return(*(int *)0); }
+
+#undef dynamic_field_info
+int dynamic_field_info(
+ const FIELD *field,
+ int *drows,
+ int *dcols,
+ int *maxgrow)
+ { return(*(int *)0); }
+
+/* ./fld_just.c */
+
+#undef set_field_just
+int set_field_just(
+ FIELD *field,
+ int just)
+ { return(*(int *)0); }
+
+#undef field_just
+int field_just(
+ const FIELD *field)
+ { return(*(int *)0); }
+
+/* ./fld_link.c */
+
+#undef link_field
+FIELD *link_field(
+ FIELD *field,
+ int frow,
+ int fcol)
+ { return(*(FIELD **)0); }
+
+/* ./fld_max.c */
+
+#undef set_max_field
+int set_max_field(
+ FIELD *field,
+ int maxgrow)
+ { return(*(int *)0); }
+
+/* ./fld_move.c */
+
+#undef move_field
+int move_field(
+ FIELD *field,
+ int frow,
+ int fcol)
+ { return(*(int *)0); }
+
+/* ./fld_newftyp.c */
+
+#undef _nc_Default_FieldType
+const FIELDTYPE *_nc_Default_FieldType = {0};
+
+#undef new_fieldtype
+FIELDTYPE *new_fieldtype(
+ bool (*const field_check)(
+ FIELD *p1,
+ const void *p2),
+ bool (*const char_check)(
+ int p1,
+ const void *p2))
+ { return(*(FIELDTYPE **)0); }
+
+#undef free_fieldtype
+int free_fieldtype(
+ FIELDTYPE *typ)
+ { return(*(int *)0); }
+
+/* ./fld_opts.c */
+
+#undef set_field_opts
+int set_field_opts(
+ FIELD *field,
+ Field_Options opts)
+ { return(*(int *)0); }
+
+#undef field_opts
+Field_Options field_opts(
+ const FIELD *field)
+ { return(*(Field_Options *)0); }
+
+#undef field_opts_on
+int field_opts_on(
+ FIELD *field,
+ Field_Options opts)
+ { return(*(int *)0); }
+
+#undef field_opts_off
+int field_opts_off(
+ FIELD *field,
+ Field_Options opts)
+ { return(*(int *)0); }
+
+/* ./fld_pad.c */
+
+#undef set_field_pad
+int set_field_pad(
+ FIELD *field,
+ int ch)
+ { return(*(int *)0); }
+
+#undef field_pad
+int field_pad(
+ const FIELD *field)
+ { return(*(int *)0); }
+
+/* ./fld_page.c */
+
+#undef set_new_page
+int set_new_page(
+ FIELD *field,
+ bool new_page_flag)
+ { return(*(int *)0); }
+
+#undef new_page
+bool new_page(
+ const FIELD *field)
+ { return(*(bool *)0); }
+
+/* ./fld_stat.c */
+
+#undef set_field_status
+int set_field_status(
+ FIELD *field,
+ bool status)
+ { return(*(int *)0); }
+
+#undef field_status
+bool field_status(
+ const FIELD *field)
+ { return(*(bool *)0); }
+
+/* ./fld_type.c */
+
+#undef set_field_type
+int set_field_type(
+ FIELD *field,
+ FIELDTYPE *type,
+ ...)
+ { return(*(int *)0); }
+
+#undef field_type
+FIELDTYPE *field_type(
+ const FIELD *field)
+ { return(*(FIELDTYPE **)0); }
+
+/* ./fld_user.c */
+
+#undef set_field_userptr
+int set_field_userptr(
+ FIELD *field,
+ void *usrptr)
+ { return(*(int *)0); }
+
+#undef field_userptr
+void *field_userptr(
+ const FIELD *field)
+ { return(*(void **)0); }
+
+/* ./frm_cursor.c */
+
+#undef pos_form_cursor
+int pos_form_cursor(
+ FORM *form)
+ { return(*(int *)0); }
+
+/* ./frm_data.c */
+
+#undef data_behind
+bool data_behind(
+ const FORM *form)
+ { return(*(bool *)0); }
+
+#undef data_ahead
+bool data_ahead(
+ const FORM *form)
+ { return(*(bool *)0); }
+
+/* ./frm_def.c */
+
+#undef _nc_Default_Form
+FORM *_nc_Default_Form;
+
+#undef new_form
+FORM *new_form(
+ FIELD **fields)
+ { return(*(FORM **)0); }
+
+#undef free_form
+int free_form(
+ FORM *form)
+ { return(*(int *)0); }
+
+#undef set_form_fields
+int set_form_fields(
+ FORM *form,
+ FIELD **fields)
+ { return(*(int *)0); }
+
+#undef form_fields
+FIELD **form_fields(
+ const FORM *form)
+ { return(*(FIELD ***)0); }
+
+#undef field_count
+int field_count(
+ const FORM *form)
+ { return(*(int *)0); }
+
+/* ./frm_driver.c */
+
+#undef _nc_Position_Form_Cursor
+int _nc_Position_Form_Cursor(
+ FORM *form)
+ { return(*(int *)0); }
+
+#undef _nc_Refresh_Current_Field
+int _nc_Refresh_Current_Field(
+ FORM *form)
+ { return(*(int *)0); }
+
+#undef _nc_Synchronize_Attributes
+int _nc_Synchronize_Attributes(
+ FIELD *field)
+ { return(*(int *)0); }
+
+#undef _nc_Synchronize_Options
+int _nc_Synchronize_Options(
+ FIELD *field,
+ Field_Options newopts)
+ { return(*(int *)0); }
+
+#undef _nc_Set_Current_Field
+int _nc_Set_Current_Field(
+ FORM *form,
+ FIELD *newfield)
+ { return(*(int *)0); }
+
+#undef _nc_Internal_Validation
+bool _nc_Internal_Validation(
+ FORM *form)
+ { return(*(bool *)0); }
+
+#undef _nc_First_Active_Field
+FIELD *_nc_First_Active_Field(
+ FORM *form)
+ { return(*(FIELD **)0); }
+
+#undef _nc_Set_Form_Page
+int _nc_Set_Form_Page(
+ FORM *form,
+ int page,
+ FIELD *field)
+ { return(*(int *)0); }
+
+typedef struct {
+ int keycode;
+ int (*cmd)(FORM *);
+} Binding_Info;
+
+#undef form_driver
+int form_driver(
+ FORM *form,
+ int c)
+ { return(*(int *)0); }
+
+#undef set_field_buffer
+int set_field_buffer(
+ FIELD *field,
+ int buffer,
+ const char *value)
+ { return(*(int *)0); }
+
+#undef field_buffer
+char *field_buffer(
+ const FIELD *field,
+ int buffer)
+ { return(*(char **)0); }
+
+/* ./frm_hook.c */
+
+#undef set_field_init
+int set_field_init(
+ FORM *form,
+ Form_Hook func)
+ { return(*(int *)0); }
+
+#undef field_init
+Form_Hook field_init(
+ const FORM *form)
+ { return(*(Form_Hook *)0); }
+
+#undef set_field_term
+int set_field_term(
+ FORM *form,
+ Form_Hook func)
+ { return(*(int *)0); }
+
+#undef field_term
+Form_Hook field_term(
+ const FORM *form)
+ { return(*(Form_Hook *)0); }
+
+#undef set_form_init
+int set_form_init(
+ FORM *form,
+ Form_Hook func)
+ { return(*(int *)0); }
+
+#undef form_init
+Form_Hook form_init(
+ const FORM *form)
+ { return(*(Form_Hook *)0); }
+
+#undef set_form_term
+int set_form_term(
+ FORM *form,
+ Form_Hook func)
+ { return(*(int *)0); }
+
+#undef form_term
+Form_Hook form_term(
+ const FORM *form)
+ { return(*(Form_Hook *)0); }
+
+/* ./frm_opts.c */
+
+#undef set_form_opts
+int set_form_opts(
+ FORM *form,
+ Form_Options opts)
+ { return(*(int *)0); }
+
+#undef form_opts
+Form_Options form_opts(
+ const FORM *form)
+ { return(*(Form_Options *)0); }
+
+#undef form_opts_on
+int form_opts_on(
+ FORM *form,
+ Form_Options opts)
+ { return(*(int *)0); }
+
+#undef form_opts_off
+int form_opts_off(
+ FORM *form,
+ Form_Options opts)
+ { return(*(int *)0); }
+
+/* ./frm_page.c */
+
+#undef set_form_page
+int set_form_page(
+ FORM *form,
+ int page)
+ { return(*(int *)0); }
+
+#undef form_page
+int form_page(
+ const FORM *form)
+ { return(*(int *)0); }
+
+/* ./frm_post.c */
+
+#undef post_form
+int post_form(
+ FORM *form)
+ { return(*(int *)0); }
+
+#undef unpost_form
+int unpost_form(
+ FORM *form)
+ { return(*(int *)0); }
+
+/* ./frm_req_name.c */
+
+#undef form_request_name
+const char *form_request_name(
+ int request)
+ { return(*(const char **)0); }
+
+#undef form_request_by_name
+int form_request_by_name(
+ const char *str)
+ { return(*(int *)0); }
+
+/* ./frm_scale.c */
+
+#undef scale_form
+int scale_form(
+ const FORM *form,
+ int *rows,
+ int *cols)
+ { return(*(int *)0); }
+
+/* ./frm_sub.c */
+
+#undef set_form_sub
+int set_form_sub(
+ FORM *form,
+ WINDOW *win)
+ { return(*(int *)0); }
+
+#undef form_sub
+WINDOW *form_sub(
+ const FORM *form)
+ { return(*(WINDOW **)0); }
+
+/* ./frm_user.c */
+
+#undef set_form_userptr
+int set_form_userptr(
+ FORM *form,
+ void *usrptr)
+ { return(*(int *)0); }
+
+#undef form_userptr
+void *form_userptr(
+ const FORM *form)
+ { return(*(void **)0); }
+
+/* ./frm_win.c */
+
+#undef set_form_win
+int set_form_win(
+ FORM *form,
+ WINDOW *win)
+ { return(*(int *)0); }
+
+#undef form_win
+WINDOW *form_win(
+ const FORM *form)
+ { return(*(WINDOW **)0); }
+
+/* ./fty_alnum.c */
+
+typedef struct {
+ int width;
+} alnumARG;
+
+#undef TYPE_ALNUM
+FIELDTYPE *TYPE_ALNUM;
+
+/* ./fty_alpha.c */
+
+typedef struct {
+ int width;
+} alphaARG;
+
+#undef TYPE_ALPHA
+FIELDTYPE *TYPE_ALPHA;
+
+/* ./fty_enum.c */
+
+typedef struct {
+ char **kwds;
+ int count;
+ bool checkcase;
+ bool checkunique;
+} enumARG;
+
+#undef TYPE_ENUM
+FIELDTYPE *TYPE_ENUM;
+
+/* ./fty_int.c */
+
+typedef struct {
+ int precision;
+ long low;
+ long high;
+} integerARG;
+
+#undef TYPE_INTEGER
+FIELDTYPE *TYPE_INTEGER;
+
+/* ./fty_ipv4.c */
+#undef TYPE_IPV4
+FIELDTYPE *TYPE_IPV4;
+
+/* ./fty_num.c */
+
+#include <locale.h>
+
+typedef struct {
+ int precision;
+ double low;
+ double high;
+ struct lconv* L;
+} numericARG;
+
+#undef TYPE_NUMERIC
+FIELDTYPE *TYPE_NUMERIC;
+
+/* ./fty_regex.c */
+
+#include <regex.h>
+
+typedef struct
+{
+ regex_t *pRegExp;
+ unsigned long *refCount;
+} RegExp_Arg;
+
+#undef TYPE_REGEXP
+FIELDTYPE *TYPE_REGEXP;
diff --git a/Source/CursesDialog/form/mf_common.h b/Source/CursesDialog/form/mf_common.h
new file mode 100644
index 000000000..6b1e8feee
--- /dev/null
+++ b/Source/CursesDialog/form/mf_common.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+ * Copyright (c) 1998,2000 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 ABOVE 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. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Juergen Pfeifer <juergen.pfeifer@gmx.net> 1995,1997 *
+ ****************************************************************************/
+
+/* Common internal header for menu and form library */
+
+#if HAVE_CONFIG_H
+# include <ncurses_cfg.h>
+#endif
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+
+#if DECL_ERRNO
+extern int errno;
+#endif
+
+/* in case of debug version we ignore the suppression of assertions */
+#ifdef TRACE
+# ifdef NDEBUG
+# undef NDEBUG
+# endif
+#endif
+
+#include <nc_alloc.h>
+
+#if USE_RCS_IDS
+#define MODULE_ID(id) static const char Ident[] = id;
+#else
+#define MODULE_ID(id) /*nothing*/
+#endif
+
+
+/* Maximum regular 8-bit character code */
+#define MAX_REGULAR_CHARACTER (0xff)
+
+#define SET_ERROR(code) (errno=(code))
+#define GET_ERROR() (errno)
+#define RETURN(code) return( SET_ERROR(code) )
+
+/* The few common values in the status fields for menus and forms */
+#define _POSTED (0x01) /* menu or form is posted */
+#define _IN_DRIVER (0x02) /* menu or form is processing hook routine */
+
+/* Call object hook */
+#define Call_Hook( object, handler ) \
+ if ( (object) && ((object)->handler) )\
+ {\
+ (object)->status |= _IN_DRIVER;\
+ (object)->handler(object);\
+ (object)->status &= ~_IN_DRIVER;\
+ }
+
+#define INLINE
+
+#ifndef TRACE
+# if CC_HAS_INLINE_FUNCS
+# undef INLINE
+# define INLINE inline
+# endif
+#endif
diff --git a/Source/CursesDialog/form/nc_alloc.h b/Source/CursesDialog/form/nc_alloc.h
new file mode 100644
index 000000000..f49ea93e8
--- /dev/null
+++ b/Source/CursesDialog/form/nc_alloc.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+ * Copyright (c) 1998 Free Software Foundation, Inc. *
+ * *
+ * 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, distribute with modifications, 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 ABOVE 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. *
+ * *
+ * Except as contained in this notice, the name(s) of the above copyright *
+ * holders shall not be used in advertising or otherwise to promote the *
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Author: Thomas E. Dickey <dickey@clark.net> 1996,1997 *
+ ****************************************************************************/
+/* $Id$ */
+
+#ifndef NC_ALLOC_included
+#define NC_ALLOC_included 1
+
+#if HAVE_LIBDMALLOC
+#include <dmalloc.h> /* Gray Watson's library */
+#else
+#undef HAVE_LIBDMALLOC
+#define HAVE_LIBDMALLOC 0
+#endif
+
+#if HAVE_LIBDBMALLOC
+#include <dbmalloc.h> /* Conor Cahill's library */
+#else
+#undef HAVE_LIBDBMALLOC
+#define HAVE_LIBDBMALLOC 0
+#endif
+
+#ifndef NO_LEAKS
+#define NO_LEAKS 0
+#endif
+
+#if HAVE_LIBDBMALLOC || HAVE_LIBDMALLOC || NO_LEAKS
+#define HAVE_NC_FREEALL 1
+struct termtype;
+extern void _nc_free_and_exit(int) GCC_NORETURN;
+extern void _nc_free_tparm(void);
+extern void _nc_leaks_dump_entry(void);
+#define ExitProgram(code) _nc_free_and_exit(code)
+#endif
+
+#ifndef HAVE_NC_FREEALL
+#define HAVE_NC_FREEALL 0
+#endif
+
+#ifndef ExitProgram
+#define ExitProgram(code) return code
+#endif
+
+/* doalloc.c */
+extern void *_nc_doalloc(void *, size_t);
+#if !HAVE_STRDUP
+/* #define strdup _nc_strdup */
+extern char *_nc_strdup(const char *);
+#endif
+
+#define typeMalloc(type,elts) (type *)malloc((elts)*sizeof(type))
+#define typeCalloc(type,elts) (type *)calloc((elts),sizeof(type))
+#define typeRealloc(type,elts,ptr) (type *)_nc_doalloc(ptr, (elts)*sizeof(type))
+
+#endif /* NC_ALLOC_included */
diff --git a/Source/QtDialog/AddCacheEntry.cxx b/Source/QtDialog/AddCacheEntry.cxx
new file mode 100644
index 000000000..e7fedc5c5
--- /dev/null
+++ b/Source/QtDialog/AddCacheEntry.cxx
@@ -0,0 +1,83 @@
+/*============================================================================
+ 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 "AddCacheEntry.h"
+#include <QMetaProperty>
+#include <QCompleter>
+
+static const int NumTypes = 4;
+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)
+{
+ this->setupUi(this);
+ for(int i=0; i<NumTypes; i++)
+ {
+ this->Type->addItem(TypeStrings[i]);
+ }
+ QWidget* cb = new QCheckBox();
+ QWidget* path = new QCMakePathEditor();
+ QWidget* filepath = new QCMakeFilePathEditor();
+ QWidget* string = new QLineEdit();
+ this->StackedWidget->addWidget(cb);
+ this->StackedWidget->addWidget(path);
+ this->StackedWidget->addWidget(filepath);
+ this->StackedWidget->addWidget(string);
+ this->setTabOrder(this->Name, this->Type);
+ this->setTabOrder(this->Type, cb);
+ this->setTabOrder(cb, path);
+ this->setTabOrder(path, filepath);
+ this->setTabOrder(filepath, string);
+ this->setTabOrder(string, this->Description);
+ this->Name->setCompleter(new QCompleter(completions, this));
+}
+
+QString AddCacheEntry::name() const
+{
+ return this->Name->text();
+}
+
+QVariant AddCacheEntry::value() const
+{
+ QWidget* w = this->StackedWidget->currentWidget();
+ if(qobject_cast<QLineEdit*>(w))
+ {
+ return static_cast<QLineEdit*>(w)->text();
+ }
+ else if(qobject_cast<QCheckBox*>(w))
+ {
+ return static_cast<QCheckBox*>(w)->isChecked();
+ }
+ return QVariant();
+}
+
+QString AddCacheEntry::description() const
+{
+ return this->Description->text();
+}
+
+QCMakeProperty::PropertyType AddCacheEntry::type() const
+{
+ int idx = this->Type->currentIndex();
+ if(idx >= 0 && idx < NumTypes)
+ {
+ return Types[idx];
+ }
+ return QCMakeProperty::BOOL;
+}
+
+
diff --git a/Source/QtDialog/AddCacheEntry.h b/Source/QtDialog/AddCacheEntry.h
new file mode 100644
index 000000000..e219d4ee7
--- /dev/null
+++ b/Source/QtDialog/AddCacheEntry.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 AddCacheEntry_h
+#define AddCacheEntry_h
+
+#include <QWidget>
+#include <QCheckBox>
+#include <QStringList>
+
+#include "QCMake.h"
+#include "ui_AddCacheEntry.h"
+
+class AddCacheEntry : public QWidget, public Ui::AddCacheEntry
+{
+ Q_OBJECT
+public:
+ AddCacheEntry(QWidget* p, const QStringList& completions);
+
+ QString name() const;
+ QVariant value() const;
+ QString description() const;
+ QCMakeProperty::PropertyType type() const;
+};
+
+#endif
+
diff --git a/Source/QtDialog/AddCacheEntry.ui b/Source/QtDialog/AddCacheEntry.ui
new file mode 100644
index 000000000..a81587473
--- /dev/null
+++ b/Source/QtDialog/AddCacheEntry.ui
@@ -0,0 +1,97 @@
+<ui version="4.0" >
+ <class>AddCacheEntry</class>
+ <widget class="QWidget" name="AddCacheEntry" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>380</width>
+ <height>158</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Name:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QLineEdit" name="Name" />
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_2" >
+ <property name="text" >
+ <string>Type:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QComboBox" name="Type" >
+ </widget>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="label_5" >
+ <property name="text" >
+ <string>Value:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" >
+ <widget class="QStackedWidget" name="StackedWidget" >
+ <property name="currentIndex" >
+ <number>0</number>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" >
+ <widget class="QLabel" name="label_3" >
+ <property name="text" >
+ <string>Description:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1" >
+ <widget class="QLineEdit" name="Description" />
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>QCMakePathEditor</class>
+ <extends>QLineEdit</extends>
+ <header>QCMakeWidgets.h</header>
+ </customwidget>
+ <customwidget>
+ <class>QCMakeFilePathEditor</class>
+ <extends>QLineEdit</extends>
+ <header>QCMakeWidgets.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>Type</sender>
+ <signal>currentIndexChanged(int)</signal>
+ <receiver>StackedWidget</receiver>
+ <slot>setCurrentIndex(int)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>229</x>
+ <y>34</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>287</x>
+ <y>65</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/Source/QtDialog/CMake.desktop b/Source/QtDialog/CMake.desktop
new file mode 100644
index 000000000..645eb76e9
--- /dev/null
+++ b/Source/QtDialog/CMake.desktop
@@ -0,0 +1,12 @@
+[Desktop Entry]
+Version=1.0
+Name=CMake
+Comment=Cross-platform buildsystem
+Exec=cmake-gui %f
+Icon=CMakeSetup32.png
+Terminal=false
+X-MultipleArgs=false
+Type=Application
+Categories=Development;
+StartupNotify=true
+MimeType=application/x-cmakecache;
diff --git a/Source/QtDialog/CMakeLists.txt b/Source/QtDialog/CMakeLists.txt
new file mode 100644
index 000000000..07ec10674
--- /dev/null
+++ b/Source/QtDialog/CMakeLists.txt
@@ -0,0 +1,123 @@
+#=============================================================================
+# 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.
+#=============================================================================
+PROJECT(QtDialog)
+SET(QT_MIN_VERSION "4.4.0")
+FIND_PACKAGE(Qt4 REQUIRED)
+
+IF(NOT QT4_FOUND)
+ MESSAGE(SEND_ERROR "Failed to find Qt 4.4 or greater.")
+ELSE(NOT QT4_FOUND)
+
+ INCLUDE(${QT_USE_FILE})
+ SET(CMAKE_PACKAGE_QTGUI TRUE)
+ SET(SRCS
+ AddCacheEntry.cxx
+ AddCacheEntry.h
+ CMakeSetup.cxx
+ CMakeSetupDialog.cxx
+ CMakeSetupDialog.h
+ FirstConfigure.cxx
+ FirstConfigure.h
+ QCMake.cxx
+ QCMake.h
+ QCMakeCacheView.cxx
+ QCMakeCacheView.h
+ QCMakeWidgets.cxx
+ QCMakeWidgets.h
+ QMacInstallDialog.cxx
+ QMacInstallDialog.h
+ )
+ QT4_WRAP_UI(UI_SRCS
+ CMakeSetupDialog.ui
+ Compilers.ui
+ CrossCompiler.ui
+ AddCacheEntry.ui
+ MacInstallDialog.ui
+ )
+ QT4_WRAP_CPP(MOC_SRCS
+ AddCacheEntry.h
+ Compilers.h
+ CMakeSetupDialog.h
+ FirstConfigure.h
+ QCMake.h
+ QCMakeCacheView.h
+ QCMakeWidgets.h
+ QMacInstallDialog.h
+ )
+ QT4_ADD_RESOURCES(RC_SRCS CMakeSetup.qrc)
+
+ SET(SRCS ${SRCS} ${UI_SRCS} ${MOC_SRCS} ${RC_SRCS})
+ IF(Q_WS_WIN)
+ SET(SRCS ${SRCS} CMakeSetup.rc)
+ ENDIF(Q_WS_WIN)
+ IF(Q_WS_MAC)
+ SET(SRCS ${SRCS} CMakeSetup.icns)
+ SET(MACOSX_BUNDLE_ICON_FILE CMakeSetup.icns)
+ SET_SOURCE_FILES_PROPERTIES(CMakeSetup.icns PROPERTIES
+ MACOSX_PACKAGE_LOCATION Resources)
+ ENDIF(Q_WS_MAC)
+
+ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+
+ ADD_EXECUTABLE(cmake-gui WIN32 MACOSX_BUNDLE ${SRCS})
+ TARGET_LINK_LIBRARIES(cmake-gui CMakeLib ${QT_QTMAIN_LIBRARY} ${QT_LIBRARIES})
+ IF(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.4)
+ IF(APPLE)
+ SET_TARGET_PROPERTIES(cmake-gui PROPERTIES
+ OUTPUT_NAME ${CMAKE_BUNDLE_NAME})
+ ENDIF(APPLE)
+ SET(CMAKE_INSTALL_DESTINATION_ARGS
+ BUNDLE DESTINATION "${CMAKE_BUNDLE_LOCATION}")
+ ENDIF(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.4)
+
+ INSTALL(TARGETS cmake-gui RUNTIME DESTINATION bin ${CMAKE_INSTALL_DESTINATION_ARGS})
+
+ 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 )
+ ENDIF(UNIX)
+
+ 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)")
+ ENDIF(APPLE)
+
+ if(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}")
+ endif(APPLE)
+ 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}\")
+ ")
+ endif(APPLE OR WIN32)
+
+ CONFIGURE_FILE("${QtDialog_SOURCE_DIR}/QtDialogCPack.cmake.in"
+ "${QtDialog_BINARY_DIR}/QtDialogCPack.cmake" @ONLY)
+ENDIF(NOT QT4_FOUND)
+
diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx
new file mode 100644
index 000000000..c942bc4ad
--- /dev/null
+++ b/Source/QtDialog/CMakeSetup.cxx
@@ -0,0 +1,205 @@
+/*============================================================================
+ 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 "QCMake.h" // include to disable MS warnings
+#include <QApplication>
+#include <QDir>
+#include <QTranslator>
+#include <QLocale>
+#include "QMacInstallDialog.h"
+#include "CMakeSetupDialog.h"
+#include "cmDocumentation.h"
+#include "cmake.h"
+#include "cmVersion.h"
+#include <cmsys/CommandLineArguments.hxx>
+#include <cmsys/SystemTools.hxx>
+
+//----------------------------------------------------------------------------
+static const char * cmDocumentationName[][3] =
+{
+ {0,
+ " cmake-gui - CMake GUI.", 0},
+ {0,0,0}
+};
+
+//----------------------------------------------------------------------------
+static const char * cmDocumentationUsage[][3] =
+{
+ {0,
+ " cmake-gui [options]\n"
+ " cmake-gui [options] <path-to-source>\n"
+ " cmake-gui [options] <path-to-existing-build>", 0},
+ {0,0,0}
+};
+
+//----------------------------------------------------------------------------
+static const char * cmDocumentationDescription[][3] =
+{
+ {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}
+};
+
+//----------------------------------------------------------------------------
+static const char * cmDocumentationOptions[][3] =
+{
+ {0,0,0}
+};
+
+int main(int argc, char** argv)
+{
+ cmSystemTools::FindExecutableDirectory(argv[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))
+ {
+ // Construct and print requested documentation.
+ cmake hcm;
+ 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);
+ }
+
+ QApplication app(argc, argv);
+
+ // 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())
+ {
+ 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)
+ cmExecDir.cd("../../../");
+#endif
+
+ // pick up translation files if they exists in the data directory
+ QDir translationsDir = cmExecDir;
+ translationsDir.cd(QString::fromLocal8Bit(".." CMAKE_DATA_DIR));
+ translationsDir.cd("i18n");
+ QTranslator translator;
+ QString transfile = QString("cmake_%1").arg(QLocale::system().name());
+ translator.load(transfile, translationsDir.path());
+ app.installTranslator(&translator);
+
+ // app setup
+ app.setApplicationName("CMakeSetup");
+ app.setOrganizationName("Kitware");
+ QIcon appIcon;
+ appIcon.addFile(":/Icons/CMakeSetup32.png");
+ appIcon.addFile(":/Icons/CMakeSetup128.png");
+ app.setWindowIcon(appIcon);
+
+ CMakeSetupDialog dialog;
+ dialog.show();
+
+ cmsys::CommandLineArguments arg;
+ arg.Initialize(argc, argv);
+ std::string binaryDirectory;
+ std::string sourceDirectory;
+ typedef cmsys::CommandLineArguments argT;
+ arg.AddArgument("-B", argT::CONCAT_ARGUMENT,
+ &binaryDirectory, "Binary Directory");
+ arg.AddArgument("-H", argT::CONCAT_ARGUMENT,
+ &sourceDirectory, "Source Directory");
+ // do not complain about unknown options
+ arg.StoreUnusedArguments(true);
+ arg.Parse();
+ if(!sourceDirectory.empty() && !binaryDirectory.empty())
+ {
+ dialog.setSourceDirectory(QString::fromLocal8Bit(sourceDirectory.c_str()));
+ dialog.setBinaryDirectory(QString::fromLocal8Bit(binaryDirectory.c_str()));
+ }
+ else
+ {
+ QStringList args = app.arguments();
+ if(args.count() == 2)
+ {
+ cmsys_stl::string filePath = cmSystemTools::CollapseFullPath(args[1].toLocal8Bit().data());
+
+ // check if argument is a directory containing CMakeCache.txt
+ cmsys_stl::string buildFilePath =
+ cmSystemTools::CollapseFullPath("CMakeCache.txt", filePath.c_str());
+
+ // check if argument is a CMakeCache.txt file
+ if(cmSystemTools::GetFilenameName(filePath) == "CMakeCache.txt" &&
+ cmSystemTools::FileExists(filePath.c_str()))
+ {
+ buildFilePath = filePath;
+ }
+
+ // check if argument is a directory containing CMakeLists.txt
+ cmsys_stl::string srcFilePath =
+ cmSystemTools::CollapseFullPath("CMakeLists.txt", filePath.c_str());
+
+ if(cmSystemTools::FileExists(buildFilePath.c_str()))
+ {
+ dialog.setBinaryDirectory(
+ QString::fromLocal8Bit(
+ cmSystemTools::GetFilenamePath(buildFilePath).c_str()
+ )
+ );
+ }
+ else if(cmSystemTools::FileExists(srcFilePath.c_str()))
+ {
+ dialog.setSourceDirectory(QString::fromLocal8Bit(filePath.c_str()));
+ dialog.setBinaryDirectory(
+ QString::fromLocal8Bit(cmSystemTools::CollapseFullPath(".").c_str())
+ );
+ }
+ }
+ }
+
+ return app.exec();
+}
+
diff --git a/Source/QtDialog/CMakeSetup.icns b/Source/QtDialog/CMakeSetup.icns
new file mode 100644
index 000000000..4a50c0416
--- /dev/null
+++ b/Source/QtDialog/CMakeSetup.icns
Binary files differ
diff --git a/Source/QtDialog/CMakeSetup.ico b/Source/QtDialog/CMakeSetup.ico
new file mode 100644
index 000000000..e13bb156f
--- /dev/null
+++ b/Source/QtDialog/CMakeSetup.ico
Binary files differ
diff --git a/Source/QtDialog/CMakeSetup.qrc b/Source/QtDialog/CMakeSetup.qrc
new file mode 100644
index 000000000..eaac19223
--- /dev/null
+++ b/Source/QtDialog/CMakeSetup.qrc
@@ -0,0 +1,8 @@
+<RCC>
+ <qresource prefix="/Icons" >
+ <file>CMakeSetup128.png</file>
+ <file>CMakeSetup32.png</file>
+ <file>Delete16.png</file>
+ <file>Plus16.png</file>
+ </qresource>
+</RCC>
diff --git a/Source/QtDialog/CMakeSetup.rc b/Source/QtDialog/CMakeSetup.rc
new file mode 100644
index 000000000..fcc887ddb
--- /dev/null
+++ b/Source/QtDialog/CMakeSetup.rc
@@ -0,0 +1 @@
+IDI_ICON1 ICON DISCARDABLE "CMakeSetup.ico"
diff --git a/Source/QtDialog/CMakeSetup128.png b/Source/QtDialog/CMakeSetup128.png
new file mode 100644
index 000000000..12f1d9a9a
--- /dev/null
+++ b/Source/QtDialog/CMakeSetup128.png
Binary files differ
diff --git a/Source/QtDialog/CMakeSetup32.png b/Source/QtDialog/CMakeSetup32.png
new file mode 100644
index 000000000..7bbcee413
--- /dev/null
+++ b/Source/QtDialog/CMakeSetup32.png
Binary files differ
diff --git a/Source/QtDialog/CMakeSetupDialog.cxx b/Source/QtDialog/CMakeSetupDialog.cxx
new file mode 100644
index 000000000..c0dde1c2c
--- /dev/null
+++ b/Source/QtDialog/CMakeSetupDialog.cxx
@@ -0,0 +1,1152 @@
+/*============================================================================
+ 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 "CMakeSetupDialog.h"
+#include <QFileDialog>
+#include <QProgressBar>
+#include <QMessageBox>
+#include <QStatusBar>
+#include <QToolButton>
+#include <QDialogButtonBox>
+#include <QCloseEvent>
+#include <QCoreApplication>
+#include <QSettings>
+#include <QMenu>
+#include <QMenuBar>
+#include <QDragEnterEvent>
+#include <QMimeData>
+#include <QUrl>
+#include <QShortcut>
+#include <QKeySequence>
+#include <QMacInstallDialog.h>
+
+#include "QCMake.h"
+#include "QCMakeCacheView.h"
+#include "AddCacheEntry.h"
+#include "FirstConfigure.h"
+#include "cmVersion.h"
+
+QCMakeThread::QCMakeThread(QObject* p)
+ : QThread(p), CMakeInstance(NULL)
+{
+}
+
+QCMake* QCMakeThread::cmakeInstance() const
+{
+ return this->CMakeInstance;
+}
+
+void QCMakeThread::run()
+{
+ this->CMakeInstance = new QCMake;
+ // emit that this cmake thread is ready for use
+ emit this->cmakeInitialized();
+ this->exec();
+ delete this->CMakeInstance;
+ this->CMakeInstance = NULL;
+}
+
+CMakeSetupDialog::CMakeSetupDialog()
+ : ExitAfterGenerate(true), CacheModified(false), ConfigureNeeded(true), CurrentState(Interrupting)
+{
+ QString title = QString(tr("CMake %1"));
+ title = title.arg(cmVersion::GetCMakeVersion());
+ this->setWindowTitle(title);
+
+ // 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);
+
+ this->AddVariableCompletions = settings.value("AddVariableCompletionEntries",
+ QStringList("CMAKE_INSTALL_PREFIX")).toStringList();
+
+ QWidget* cont = new QWidget(this);
+ this->setupUi(cont);
+ this->Splitter->setStretchFactor(0, 3);
+ this->Splitter->setStretchFactor(1, 1);
+ this->setCentralWidget(cont);
+ this->ProgressBar->reset();
+ this->RemoveEntry->setEnabled(false);
+ this->AddEntry->setEnabled(false);
+
+ QByteArray p = settings.value("SplitterSizes").toByteArray();
+ this->Splitter->restoreState(p);
+
+ bool groupView = settings.value("GroupView", false).toBool();
+ this->setGroupedView(groupView);
+ this->groupedCheck->setCheckState(groupView ? Qt::Checked : Qt::Unchecked);
+
+ bool advancedView = settings.value("AdvancedView", false).toBool();
+ this->setAdvancedView(advancedView);
+ this->advancedCheck->setCheckState(advancedView?Qt::Checked : Qt::Unchecked);
+
+ QMenu* FileMenu = this->menuBar()->addMenu(tr("&File"));
+ this->ReloadCacheAction = FileMenu->addAction(tr("&Reload Cache"));
+ QObject::connect(this->ReloadCacheAction, SIGNAL(triggered(bool)),
+ this, SLOT(doReloadCache()));
+ this->DeleteCacheAction = FileMenu->addAction(tr("&Delete Cache"));
+ QObject::connect(this->DeleteCacheAction, SIGNAL(triggered(bool)),
+ this, SLOT(doDeleteCache()));
+ this->ExitAction = FileMenu->addAction(tr("E&xit"));
+ this->ExitAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q));
+ QObject::connect(this->ExitAction, SIGNAL(triggered(bool)),
+ this, SLOT(close()));
+
+ QMenu* ToolsMenu = this->menuBar()->addMenu(tr("&Tools"));
+ this->ConfigureAction = ToolsMenu->addAction(tr("&Configure"));
+ // prevent merging with Preferences menu item on Mac OS X
+ this->ConfigureAction->setMenuRole(QAction::NoRole);
+ QObject::connect(this->ConfigureAction, SIGNAL(triggered(bool)),
+ this, SLOT(doConfigure()));
+ this->GenerateAction = ToolsMenu->addAction(tr("&Generate"));
+ QObject::connect(this->GenerateAction, SIGNAL(triggered(bool)),
+ this, SLOT(doGenerate()));
+ QAction* showChangesAction = ToolsMenu->addAction(tr("&Show My Changes"));
+ QObject::connect(showChangesAction, SIGNAL(triggered(bool)),
+ this, SLOT(showUserChanges()));
+#if defined(Q_WS_MAC)
+ this->InstallForCommandLineAction
+ = ToolsMenu->addAction(tr("&Install For Command Line Use"));
+ QObject::connect(this->InstallForCommandLineAction, SIGNAL(triggered(bool)),
+ this, SLOT(doInstallForCommandLine()));
+#endif
+ QMenu* OptionsMenu = this->menuBar()->addMenu(tr("&Options"));
+ this->SuppressDevWarningsAction =
+ OptionsMenu->addAction(tr("&Suppress dev Warnings (-Wno-dev)"));
+ this->SuppressDevWarningsAction->setCheckable(true);
+ this->WarnUninitializedAction =
+ OptionsMenu->addAction(tr("&Warn Uninitialized (--warn-uninitialized)"));
+ this->WarnUninitializedAction->setCheckable(true);
+ this->WarnUnusedAction =
+ OptionsMenu->addAction(tr("&Warn Unused (--warn-unused-vars)"));
+ this->WarnUnusedAction->setCheckable(true);
+
+ QAction* debugAction = OptionsMenu->addAction(tr("&Debug Output"));
+ debugAction->setCheckable(true);
+ QObject::connect(debugAction, SIGNAL(toggled(bool)),
+ this, SLOT(setDebugOutput(bool)));
+
+ OptionsMenu->addSeparator();
+ QAction* expandAction = OptionsMenu->addAction(tr("&Expand Grouped Entries"));
+ QObject::connect(expandAction, SIGNAL(triggered(bool)),
+ this->CacheValues, SLOT(expandAll()));
+ QAction* collapseAction = OptionsMenu->addAction(tr("&Collapse Grouped Entries"));
+ QObject::connect(collapseAction, SIGNAL(triggered(bool)),
+ this->CacheValues, SLOT(collapseAll()));
+
+ QMenu* HelpMenu = this->menuBar()->addMenu(tr("&Help"));
+ QAction* a = HelpMenu->addAction(tr("About"));
+ QObject::connect(a, SIGNAL(triggered(bool)),
+ this, SLOT(doAbout()));
+ a = HelpMenu->addAction(tr("Help"));
+ QObject::connect(a, SIGNAL(triggered(bool)),
+ this, SLOT(doHelp()));
+
+ QShortcut* filterShortcut = new QShortcut(QKeySequence::Find, this);
+ QObject::connect(filterShortcut, SIGNAL(activated()),
+ this, SLOT(startSearch()));
+
+ this->setAcceptDrops(true);
+
+ // get the saved binary directories
+ QStringList buildPaths = this->loadBuildPaths();
+ this->BinaryDirectory->addItems(buildPaths);
+
+ this->BinaryDirectory->setCompleter(new QCMakeFileCompleter(this, true));
+ this->SourceDirectory->setCompleter(new QCMakeFileCompleter(this, true));
+
+ // fixed pitch font in output window
+ QFont outputFont("Courier");
+ this->Output->setFont(outputFont);
+ this->ErrorFormat.setForeground(QBrush(Qt::red));
+
+ // start the cmake worker thread
+ this->CMakeThread = new QCMakeThread(this);
+ QObject::connect(this->CMakeThread, SIGNAL(cmakeInitialized()),
+ this, SLOT(initialize()), Qt::QueuedConnection);
+ this->CMakeThread->start();
+
+ this->enterState(ReadyConfigure);
+
+ ProgressOffset = 0.0;
+ ProgressFactor = 1.0;
+}
+
+void CMakeSetupDialog::initialize()
+{
+ // now the cmake worker thread is running, lets make our connections to it
+ QObject::connect(this->CMakeThread->cmakeInstance(),
+ SIGNAL(propertiesChanged(const QCMakePropertyList&)),
+ this->CacheValues->cacheModel(),
+ SLOT(setProperties(const QCMakePropertyList&)));
+
+ QObject::connect(this->ConfigureButton, SIGNAL(clicked(bool)),
+ this, SLOT(doConfigure()));
+
+ QObject::connect(this->CMakeThread->cmakeInstance(), SIGNAL(configureDone(int)),
+ this, SLOT(exitLoop(int)));
+ QObject::connect(this->CMakeThread->cmakeInstance(), SIGNAL(generateDone(int)),
+ this, SLOT(exitLoop(int)));
+
+ QObject::connect(this->GenerateButton, SIGNAL(clicked(bool)),
+ this, SLOT(doGenerate()));
+
+ QObject::connect(this->BrowseSourceDirectoryButton, SIGNAL(clicked(bool)),
+ this, SLOT(doSourceBrowse()));
+ QObject::connect(this->BrowseBinaryDirectoryButton, SIGNAL(clicked(bool)),
+ this, SLOT(doBinaryBrowse()));
+
+ QObject::connect(this->BinaryDirectory, SIGNAL(editTextChanged(QString)),
+ this, SLOT(onBinaryDirectoryChanged(QString)));
+ QObject::connect(this->SourceDirectory, SIGNAL(textChanged(QString)),
+ this, SLOT(onSourceDirectoryChanged(QString)));
+
+ QObject::connect(this->CMakeThread->cmakeInstance(),
+ SIGNAL(sourceDirChanged(QString)),
+ this, SLOT(updateSourceDirectory(QString)));
+ QObject::connect(this->CMakeThread->cmakeInstance(),
+ SIGNAL(binaryDirChanged(QString)),
+ this, SLOT(updateBinaryDirectory(QString)));
+
+ QObject::connect(this->CMakeThread->cmakeInstance(),
+ SIGNAL(progressChanged(QString, float)),
+ this, SLOT(showProgress(QString,float)));
+
+ QObject::connect(this->CMakeThread->cmakeInstance(),
+ SIGNAL(errorMessage(QString)),
+ this, SLOT(error(QString)));
+
+ QObject::connect(this->CMakeThread->cmakeInstance(),
+ SIGNAL(outputMessage(QString)),
+ this, SLOT(message(QString)));
+
+ QObject::connect(this->groupedCheck, SIGNAL(toggled(bool)),
+ this, SLOT(setGroupedView(bool)));
+ QObject::connect(this->advancedCheck, SIGNAL(toggled(bool)),
+ this, SLOT(setAdvancedView(bool)));
+ QObject::connect(this->Search, SIGNAL(textChanged(QString)),
+ this, SLOT(setSearchFilter(QString)));
+
+ QObject::connect(this->CMakeThread->cmakeInstance(),
+ SIGNAL(generatorChanged(QString)),
+ this, SLOT(updateGeneratorLabel(QString)));
+ this->updateGeneratorLabel(QString());
+
+ QObject::connect(this->CacheValues->cacheModel(),
+ SIGNAL(dataChanged(QModelIndex,QModelIndex)),
+ this, SLOT(setCacheModified()));
+
+ QObject::connect(this->CacheValues->selectionModel(),
+ SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
+ this, SLOT(selectionChanged()));
+ QObject::connect(this->RemoveEntry, SIGNAL(clicked(bool)),
+ this, SLOT(removeSelectedCacheEntries()));
+ 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)));
+ QObject::connect(this->WarnUnusedAction, SIGNAL(triggered(bool)),
+ this->CMakeThread->cmakeInstance(),
+ SLOT(setWarnUnusedMode(bool)));
+
+ if(!this->SourceDirectory->text().isEmpty() ||
+ !this->BinaryDirectory->lineEdit()->text().isEmpty())
+ {
+ this->onSourceDirectoryChanged(this->SourceDirectory->text());
+ this->onBinaryDirectoryChanged(this->BinaryDirectory->lineEdit()->text());
+ }
+ else
+ {
+ this->onBinaryDirectoryChanged(this->BinaryDirectory->lineEdit()->text());
+ }
+}
+
+CMakeSetupDialog::~CMakeSetupDialog()
+{
+ QSettings settings;
+ settings.beginGroup("Settings/StartPath");
+ settings.setValue("Height", this->height());
+ settings.setValue("Width", this->width());
+ settings.setValue("SplitterSizes", this->Splitter->saveState());
+
+ // wait for thread to stop
+ this->CMakeThread->quit();
+ this->CMakeThread->wait();
+}
+
+bool CMakeSetupDialog::prepareConfigure()
+{
+ // make sure build directory exists
+ QString bindir = this->CMakeThread->cmakeInstance()->binaryDirectory();
+ QDir dir(bindir);
+ if(!dir.exists())
+ {
+ QString msg = tr("Build directory does not exist, "
+ "should I create it?\n\n"
+ "Directory: ");
+ msg += bindir;
+ QString title = tr("Create Directory");
+ QMessageBox::StandardButton btn;
+ btn = QMessageBox::information(this, title, msg,
+ QMessageBox::Yes | QMessageBox::No);
+ if(btn == QMessageBox::No)
+ {
+ return false;
+ }
+ if(!dir.mkpath("."))
+ {
+ QMessageBox::information(this, tr("Create Directory Failed"),
+ QString(tr("Failed to create directory %1")).arg(dir.path()),
+ QMessageBox::Ok);
+
+ return false;
+ }
+ }
+
+ // if no generator, prompt for it and other setup stuff
+ if(this->CMakeThread->cmakeInstance()->generator().isEmpty())
+ {
+ if(!this->setupFirstConfigure())
+ {
+ return false;
+ }
+ }
+
+ // remember path
+ this->addBinaryPath(dir.absolutePath());
+
+ return true;
+}
+
+void CMakeSetupDialog::exitLoop(int err)
+{
+ this->LocalLoop.exit(err);
+}
+
+void CMakeSetupDialog::doConfigure()
+{
+ if(this->CurrentState == Configuring)
+ {
+ // stop configure
+ doInterrupt();
+ return;
+ }
+
+ if(!prepareConfigure())
+ {
+ return;
+ }
+
+ this->enterState(Configuring);
+
+ bool ret = doConfigureInternal();
+
+ if(ret)
+ {
+ this->ConfigureNeeded = false;
+ }
+
+ if(ret && !this->CacheValues->cacheModel()->newPropertyCount())
+ {
+ this->enterState(ReadyGenerate);
+ }
+ else
+ {
+ this->enterState(ReadyConfigure);
+ this->CacheValues->scrollToTop();
+ }
+ this->ProgressBar->reset();
+}
+
+bool CMakeSetupDialog::doConfigureInternal()
+{
+ this->Output->clear();
+ this->CacheValues->selectionModel()->clear();
+
+ QMetaObject::invokeMethod(this->CMakeThread->cmakeInstance(),
+ "setProperties", Qt::QueuedConnection,
+ Q_ARG(QCMakePropertyList,
+ this->CacheValues->cacheModel()->properties()));
+ QMetaObject::invokeMethod(this->CMakeThread->cmakeInstance(),
+ "configure", Qt::QueuedConnection);
+
+ int err = this->LocalLoop.exec();
+
+ if(err != 0)
+ {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Error in configuration process, project files may be invalid"),
+ QMessageBox::Ok);
+ }
+
+ return 0 == err;
+}
+
+void CMakeSetupDialog::doInstallForCommandLine()
+{
+ QMacInstallDialog setupdialog(0);
+ setupdialog.exec();
+}
+
+bool CMakeSetupDialog::doGenerateInternal()
+{
+ QMetaObject::invokeMethod(this->CMakeThread->cmakeInstance(),
+ "generate", Qt::QueuedConnection);
+
+ int err = this->LocalLoop.exec();
+
+ if(err != 0)
+ {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Error in generation process, project files may be invalid"),
+ QMessageBox::Ok);
+ }
+
+ return 0 == err;
+}
+
+void CMakeSetupDialog::doGenerate()
+{
+ if(this->CurrentState == Generating)
+ {
+ // stop generate
+ doInterrupt();
+ return;
+ }
+
+ // see if we need to configure
+ // we'll need to configure if:
+ // the configure step hasn't been done yet
+ // generate was the last step done
+ if(this->ConfigureNeeded)
+ {
+ if(!prepareConfigure())
+ {
+ return;
+ }
+ }
+
+ this->enterState(Generating);
+
+ bool config_passed = true;
+ if(this->ConfigureNeeded)
+ {
+ this->CacheValues->cacheModel()->setShowNewProperties(false);
+ this->ProgressFactor = 0.5;
+ config_passed = doConfigureInternal();
+ this->ProgressOffset = 0.5;
+ }
+
+ if(config_passed)
+ {
+ doGenerateInternal();
+ }
+
+ this->ProgressOffset = 0.0;
+ this->ProgressFactor = 1.0;
+ this->CacheValues->cacheModel()->setShowNewProperties(true);
+
+ this->enterState(ReadyConfigure);
+ this->ProgressBar->reset();
+
+ this->ConfigureNeeded = true;
+}
+
+void CMakeSetupDialog::closeEvent(QCloseEvent* e)
+{
+ // prompt for close if there are unsaved changes, and we're not busy
+ if(this->CacheModified)
+ {
+ QString msg = tr("You have changed options but not rebuilt, "
+ "are you sure you want to exit?");
+ QString title = tr("Confirm Exit");
+ QMessageBox::StandardButton btn;
+ btn = QMessageBox::critical(this, title, msg,
+ QMessageBox::Yes | QMessageBox::No);
+ if(btn == QMessageBox::No)
+ {
+ e->ignore();
+ }
+ }
+
+ // don't close if we're busy, unless the user really wants to
+ if(this->CurrentState == Configuring)
+ {
+ QString msg = tr("You are in the middle of a Configure.\n"
+ "If you Exit now the configure information will be lost.\n"
+ "Are you sure you want to Exit?");
+ QString title = tr("Confirm Exit");
+ QMessageBox::StandardButton btn;
+ btn = QMessageBox::critical(this, title, msg,
+ QMessageBox::Yes | QMessageBox::No);
+ if(btn == QMessageBox::No)
+ {
+ e->ignore();
+ }
+ else
+ {
+ this->doInterrupt();
+ }
+ }
+
+ // let the generate finish
+ if(this->CurrentState == Generating)
+ {
+ e->ignore();
+ }
+}
+
+void CMakeSetupDialog::doHelp()
+{
+ QString msg = tr("CMake is used to configure and generate build files for "
+ "software projects. The basic steps for configuring a project are as "
+ "follows:\r\n\r\n1. Select the source directory for the project. This should "
+ "contain the CMakeLists.txt files for the project.\r\n\r\n2. Select the build "
+ "directory for the project. This is the directory where the project will be "
+ "built. It can be the same or a different directory than the source "
+ "directory. For easy clean up, a separate build directory is recommended. "
+ "CMake will create the directory if it does not exist.\r\n\r\n3. Once the "
+ "source and binary directories are selected, it is time to press the "
+ "Configure button. This will cause CMake to read all of the input files and "
+ "discover all the variables used by the project. The first time a variable "
+ "is displayed it will be in Red. Users should inspect red variables making "
+ "sure the values are correct. For some projects the Configure process can "
+ "be iterative, so continue to press the Configure button until there are no "
+ "longer red entries.\r\n\r\n4. Once there are no longer red entries, you "
+ "should click the Generate button. This will write the build files to the build "
+ "directory.");
+
+ QDialog dialog;
+ QFontMetrics met(this->font());
+ int msgWidth = met.width(msg);
+ dialog.setMinimumSize(msgWidth/15,20);
+ dialog.setWindowTitle(tr("Help"));
+ QVBoxLayout* l = new QVBoxLayout(&dialog);
+ QLabel* lab = new QLabel(&dialog);
+ lab->setText(msg);
+ lab->setWordWrap(true);
+ QDialogButtonBox* btns = new QDialogButtonBox(QDialogButtonBox::Ok,
+ Qt::Horizontal, &dialog);
+ QObject::connect(btns, SIGNAL(accepted()), &dialog, SLOT(accept()));
+ l->addWidget(lab);
+ l->addWidget(btns);
+ dialog.exec();
+}
+
+void CMakeSetupDialog::doInterrupt()
+{
+ this->enterState(Interrupting);
+ this->CMakeThread->cmakeInstance()->interrupt();
+}
+
+void CMakeSetupDialog::doSourceBrowse()
+{
+ QString dir = QFileDialog::getExistingDirectory(this,
+ tr("Enter Path to Source"), this->SourceDirectory->text());
+ if(!dir.isEmpty())
+ {
+ this->setSourceDirectory(dir);
+ }
+}
+
+void CMakeSetupDialog::updateSourceDirectory(const QString& dir)
+{
+ if(this->SourceDirectory->text() != dir)
+ {
+ this->SourceDirectory->blockSignals(true);
+ this->SourceDirectory->setText(dir);
+ this->SourceDirectory->blockSignals(false);
+ }
+}
+
+void CMakeSetupDialog::updateBinaryDirectory(const QString& dir)
+{
+ if(this->BinaryDirectory->currentText() != dir)
+ {
+ this->BinaryDirectory->blockSignals(true);
+ this->BinaryDirectory->setEditText(dir);
+ this->BinaryDirectory->blockSignals(false);
+ }
+}
+
+void CMakeSetupDialog::doBinaryBrowse()
+{
+ QString dir = QFileDialog::getExistingDirectory(this,
+ tr("Enter Path to Build"), this->BinaryDirectory->currentText());
+ if(!dir.isEmpty() && dir != this->BinaryDirectory->currentText())
+ {
+ this->setBinaryDirectory(dir);
+ }
+}
+
+void CMakeSetupDialog::setBinaryDirectory(const QString& dir)
+{
+ this->BinaryDirectory->setEditText(dir);
+}
+
+void CMakeSetupDialog::onSourceDirectoryChanged(const QString& dir)
+{
+ this->Output->clear();
+ QMetaObject::invokeMethod(this->CMakeThread->cmakeInstance(),
+ "setSourceDirectory", Qt::QueuedConnection, Q_ARG(QString, dir));
+}
+
+void CMakeSetupDialog::onBinaryDirectoryChanged(const QString& dir)
+{
+ QString title = QString(tr("CMake %1 - %2"));
+ title = title.arg(cmVersion::GetCMakeVersion());
+ title = title.arg(dir);
+ this->setWindowTitle(title);
+
+ this->CacheModified = false;
+ this->CacheValues->cacheModel()->clear();
+ qobject_cast<QCMakeCacheModelDelegate*>(this->CacheValues->itemDelegate())->clearChanges();
+ this->Output->clear();
+ QMetaObject::invokeMethod(this->CMakeThread->cmakeInstance(),
+ "setBinaryDirectory", Qt::QueuedConnection, Q_ARG(QString, dir));
+}
+
+void CMakeSetupDialog::setSourceDirectory(const QString& dir)
+{
+ this->SourceDirectory->setText(dir);
+}
+
+void CMakeSetupDialog::showProgress(const QString& /*msg*/, float percent)
+{
+ percent = (percent * ProgressFactor) + ProgressOffset;
+ this->ProgressBar->setValue(qRound(percent * 100));
+}
+
+void CMakeSetupDialog::error(const QString& msg)
+{
+ this->Output->setCurrentCharFormat(this->ErrorFormat);
+ this->Output->append(msg);
+}
+
+void CMakeSetupDialog::message(const QString& msg)
+{
+ this->Output->setCurrentCharFormat(this->MessageFormat);
+ this->Output->append(msg);
+}
+
+void CMakeSetupDialog::setEnabledState(bool enabled)
+{
+ // disable parts of the GUI during configure/generate
+ this->CacheValues->cacheModel()->setEditEnabled(enabled);
+ this->SourceDirectory->setEnabled(enabled);
+ this->BrowseSourceDirectoryButton->setEnabled(enabled);
+ this->BinaryDirectory->setEnabled(enabled);
+ this->BrowseBinaryDirectoryButton->setEnabled(enabled);
+ this->ReloadCacheAction->setEnabled(enabled);
+ this->DeleteCacheAction->setEnabled(enabled);
+ this->ExitAction->setEnabled(enabled);
+ this->ConfigureAction->setEnabled(enabled);
+ this->AddEntry->setEnabled(enabled);
+ this->RemoveEntry->setEnabled(false); // let selection re-enable it
+}
+
+bool CMakeSetupDialog::setupFirstConfigure()
+{
+ FirstConfigure dialog;
+
+ // initialize dialog and restore saved settings
+
+ // add generators
+ dialog.setGenerators(this->CMakeThread->cmakeInstance()->availableGenerators());
+
+ // restore from settings
+ dialog.loadFromSettings();
+
+ if(dialog.exec() == QDialog::Accepted)
+ {
+ dialog.saveToSettings();
+ this->CMakeThread->cmakeInstance()->setGenerator(dialog.getGenerator());
+
+ QCMakeCacheModel* m = this->CacheValues->cacheModel();
+
+ if(dialog.compilerSetup())
+ {
+ QString fortranCompiler = dialog.getFortranCompiler();
+ if(!fortranCompiler.isEmpty())
+ {
+ m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_Fortran_COMPILER",
+ "Fortran compiler.", fortranCompiler, false);
+ }
+ QString cxxCompiler = dialog.getCXXCompiler();
+ if(!cxxCompiler.isEmpty())
+ {
+ m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_CXX_COMPILER",
+ "CXX compiler.", cxxCompiler, false);
+ }
+
+ QString cCompiler = dialog.getCCompiler();
+ if(!cCompiler.isEmpty())
+ {
+ m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_C_COMPILER",
+ "C compiler.", cCompiler, false);
+ }
+ }
+ else if(dialog.crossCompilerSetup())
+ {
+ QString fortranCompiler = dialog.getFortranCompiler();
+ if(!fortranCompiler.isEmpty())
+ {
+ m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_Fortran_COMPILER",
+ "Fortran compiler.", fortranCompiler, false);
+ }
+
+ QString mode = dialog.getCrossIncludeMode();
+ m->insertProperty(QCMakeProperty::STRING, "CMAKE_FIND_ROOT_PATH_MODE_INCLUDE",
+ tr("CMake Find Include Mode"), mode, false);
+ mode = dialog.getCrossLibraryMode();
+ m->insertProperty(QCMakeProperty::STRING, "CMAKE_FIND_ROOT_PATH_MODE_LIBRARY",
+ tr("CMake Find Library Mode"), mode, false);
+ mode = dialog.getCrossProgramMode();
+ m->insertProperty(QCMakeProperty::STRING, "CMAKE_FIND_ROOT_PATH_MODE_PROGRAM",
+ tr("CMake Find Program Mode"), mode, false);
+
+ QString rootPath = dialog.getCrossRoot();
+ m->insertProperty(QCMakeProperty::PATH, "CMAKE_FIND_ROOT_PATH",
+ tr("CMake Find Root Path"), rootPath, false);
+
+ QString systemName = dialog.getSystemName();
+ m->insertProperty(QCMakeProperty::STRING, "CMAKE_SYSTEM_NAME",
+ tr("CMake System Name"), systemName, false);
+ QString cxxCompiler = dialog.getCXXCompiler();
+ m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_CXX_COMPILER",
+ tr("CXX compiler."), cxxCompiler, false);
+ QString cCompiler = dialog.getCCompiler();
+ m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_C_COMPILER",
+ tr("C compiler."), cCompiler, false);
+ }
+ else if(dialog.crossCompilerToolChainFile())
+ {
+ QString toolchainFile = dialog.getCrossCompilerToolChainFile();
+ m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_TOOLCHAIN_FILE",
+ tr("Cross Compile ToolChain File"), toolchainFile, false);
+ }
+ return true;
+ }
+
+ return false;
+}
+
+void CMakeSetupDialog::updateGeneratorLabel(const QString& gen)
+{
+ QString str = tr("Current Generator: ");
+ if(gen.isEmpty())
+ {
+ str += tr("None");
+ }
+ else
+ {
+ str += gen;
+ }
+ this->Generator->setText(str);
+}
+
+void CMakeSetupDialog::doReloadCache()
+{
+ QMetaObject::invokeMethod(this->CMakeThread->cmakeInstance(),
+ "reloadCache", Qt::QueuedConnection);
+}
+
+void CMakeSetupDialog::doDeleteCache()
+{
+ QString title = tr("Delete Cache");
+ QString msg = tr("Are you sure you want to delete the cache?");
+ QMessageBox::StandardButton btn;
+ btn = QMessageBox::information(this, title, msg,
+ QMessageBox::Yes | QMessageBox::No);
+ if(btn == QMessageBox::No)
+ {
+ return;
+ }
+ QMetaObject::invokeMethod(this->CMakeThread->cmakeInstance(),
+ "deleteCache", Qt::QueuedConnection);
+}
+
+void CMakeSetupDialog::doAbout()
+{
+ QString msg = tr("CMake %1\n"
+ "Using Qt %2\n"
+ "www.cmake.org");
+
+ msg = msg.arg(cmVersion::GetCMakeVersion());
+ msg = msg.arg(qVersion());
+
+ QDialog dialog;
+ dialog.setWindowTitle(tr("About"));
+ QVBoxLayout* l = new QVBoxLayout(&dialog);
+ QLabel* lab = new QLabel(&dialog);
+ l->addWidget(lab);
+ lab->setText(msg);
+ lab->setWordWrap(true);
+ QDialogButtonBox* btns = new QDialogButtonBox(QDialogButtonBox::Ok,
+ Qt::Horizontal, &dialog);
+ QObject::connect(btns, SIGNAL(accepted()), &dialog, SLOT(accept()));
+ l->addWidget(btns);
+ dialog.exec();
+}
+
+void CMakeSetupDialog::setExitAfterGenerate(bool b)
+{
+ this->ExitAfterGenerate = b;
+}
+
+void CMakeSetupDialog::addBinaryPath(const QString& path)
+{
+ QString cleanpath = QDir::cleanPath(path);
+
+ // update UI
+ this->BinaryDirectory->blockSignals(true);
+ int idx = this->BinaryDirectory->findText(cleanpath);
+ if(idx != -1)
+ {
+ this->BinaryDirectory->removeItem(idx);
+ }
+ this->BinaryDirectory->insertItem(0, cleanpath);
+ this->BinaryDirectory->setCurrentIndex(0);
+ this->BinaryDirectory->blockSignals(false);
+
+ // save to registry
+ QStringList buildPaths = this->loadBuildPaths();
+ buildPaths.removeAll(cleanpath);
+ buildPaths.prepend(cleanpath);
+ this->saveBuildPaths(buildPaths);
+}
+
+void CMakeSetupDialog::dragEnterEvent(QDragEnterEvent* e)
+{
+ if(!(this->CurrentState == ReadyConfigure ||
+ this->CurrentState == ReadyGenerate))
+ {
+ e->ignore();
+ return;
+ }
+
+ const QMimeData* dat = e->mimeData();
+ QList<QUrl> urls = dat->urls();
+ QString file = urls.count() ? urls[0].toLocalFile() : QString();
+ if(!file.isEmpty() &&
+ (file.endsWith("CMakeCache.txt", Qt::CaseInsensitive) ||
+ file.endsWith("CMakeLists.txt", Qt::CaseInsensitive) ) )
+ {
+ e->accept();
+ }
+ else
+ {
+ e->ignore();
+ }
+}
+
+void CMakeSetupDialog::dropEvent(QDropEvent* e)
+{
+ if(!(this->CurrentState == ReadyConfigure ||
+ this->CurrentState == ReadyGenerate))
+ {
+ return;
+ }
+
+ const QMimeData* dat = e->mimeData();
+ QList<QUrl> urls = dat->urls();
+ QString file = urls.count() ? urls[0].toLocalFile() : QString();
+ if(file.endsWith("CMakeCache.txt", Qt::CaseInsensitive))
+ {
+ QFileInfo info(file);
+ if(this->CMakeThread->cmakeInstance()->binaryDirectory() != info.absolutePath())
+ {
+ this->setBinaryDirectory(info.absolutePath());
+ }
+ }
+ else if(file.endsWith("CMakeLists.txt", Qt::CaseInsensitive))
+ {
+ QFileInfo info(file);
+ if(this->CMakeThread->cmakeInstance()->binaryDirectory() != info.absolutePath())
+ {
+ this->setSourceDirectory(info.absolutePath());
+ this->setBinaryDirectory(info.absolutePath());
+ }
+ }
+}
+
+QStringList CMakeSetupDialog::loadBuildPaths()
+{
+ QSettings settings;
+ settings.beginGroup("Settings/StartPath");
+
+ QStringList buildPaths;
+ for(int i=0; i<10; i++)
+ {
+ QString p = settings.value(QString("WhereBuild%1").arg(i)).toString();
+ if(!p.isEmpty())
+ {
+ buildPaths.append(p);
+ }
+ }
+ return buildPaths;
+}
+
+void CMakeSetupDialog::saveBuildPaths(const QStringList& paths)
+{
+ QSettings settings;
+ settings.beginGroup("Settings/StartPath");
+
+ int num = paths.count();
+ if(num > 10)
+ {
+ num = 10;
+ }
+
+ for(int i=0; i<num; i++)
+ {
+ settings.setValue(QString("WhereBuild%1").arg(i), paths[i]);
+ }
+}
+
+void CMakeSetupDialog::setCacheModified()
+{
+ this->CacheModified = true;
+ this->enterState(ReadyConfigure);
+}
+
+void CMakeSetupDialog::removeSelectedCacheEntries()
+{
+ QModelIndexList idxs = this->CacheValues->selectionModel()->selectedRows();
+ QList<QPersistentModelIndex> pidxs;
+ foreach(QModelIndex i, idxs)
+ {
+ pidxs.append(i);
+ }
+ foreach(QPersistentModelIndex pi, pidxs)
+ {
+ this->CacheValues->model()->removeRow(pi.row(), pi.parent());
+ }
+}
+
+void CMakeSetupDialog::selectionChanged()
+{
+ QModelIndexList idxs = this->CacheValues->selectionModel()->selectedRows();
+ if(idxs.count() &&
+ (this->CurrentState == ReadyConfigure ||
+ this->CurrentState == ReadyGenerate) )
+ {
+ this->RemoveEntry->setEnabled(true);
+ }
+ else
+ {
+ this->RemoveEntry->setEnabled(false);
+ }
+}
+
+void CMakeSetupDialog::enterState(CMakeSetupDialog::State s)
+{
+ if(s == this->CurrentState)
+ {
+ return;
+ }
+
+ this->CurrentState = s;
+
+ if(s == Interrupting)
+ {
+ this->ConfigureButton->setEnabled(false);
+ this->GenerateButton->setEnabled(false);
+ }
+ else if(s == Configuring)
+ {
+ this->setEnabledState(false);
+ this->GenerateButton->setEnabled(false);
+ this->GenerateAction->setEnabled(false);
+ this->ConfigureButton->setText(tr("&Stop"));
+ }
+ else if(s == Generating)
+ {
+ this->CacheModified = false;
+ this->setEnabledState(false);
+ this->ConfigureButton->setEnabled(false);
+ this->GenerateAction->setEnabled(false);
+ this->GenerateButton->setText(tr("&Stop"));
+ }
+ else if(s == ReadyConfigure)
+ {
+ this->setEnabledState(true);
+ this->GenerateButton->setEnabled(true);
+ this->GenerateAction->setEnabled(true);
+ this->ConfigureButton->setEnabled(true);
+ this->ConfigureButton->setText(tr("&Configure"));
+ this->GenerateButton->setText(tr("&Generate"));
+ }
+ else if(s == ReadyGenerate)
+ {
+ this->setEnabledState(true);
+ this->GenerateButton->setEnabled(true);
+ this->GenerateAction->setEnabled(true);
+ this->ConfigureButton->setEnabled(true);
+ this->ConfigureButton->setText(tr("&Configure"));
+ this->GenerateButton->setText(tr("&Generate"));
+ }
+}
+
+void CMakeSetupDialog::addCacheEntry()
+{
+ QDialog dialog(this);
+ dialog.resize(400, 200);
+ dialog.setWindowTitle(tr("Add Cache Entry"));
+ QVBoxLayout* l = new QVBoxLayout(&dialog);
+ AddCacheEntry* w = new AddCacheEntry(&dialog, this->AddVariableCompletions);
+ QDialogButtonBox* btns = new QDialogButtonBox(
+ QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
+ Qt::Horizontal, &dialog);
+ QObject::connect(btns, SIGNAL(accepted()), &dialog, SLOT(accept()));
+ QObject::connect(btns, SIGNAL(rejected()), &dialog, SLOT(reject()));
+ l->addWidget(w);
+ l->addStretch();
+ l->addWidget(btns);
+ if(QDialog::Accepted == dialog.exec())
+ {
+ QCMakeCacheModel* m = this->CacheValues->cacheModel();
+ 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()))
+ {
+ this->AddVariableCompletions << w->name();
+ // limit to at most 100 completion items
+ if (this->AddVariableCompletions.size() > 100)
+ {
+ this->AddVariableCompletions.removeFirst();
+ }
+ // make sure CMAKE_INSTALL_PREFIX is always there
+ if (!this->AddVariableCompletions.contains("CMAKE_INSTALL_PREFIX"))
+ {
+ this->AddVariableCompletions << QString("CMAKE_INSTALL_PREFIX");
+ }
+ QSettings settings;
+ settings.beginGroup("Settings/StartPath");
+ settings.setValue("AddVariableCompletionEntries",
+ this->AddVariableCompletions);
+ }
+ }
+}
+
+void CMakeSetupDialog::startSearch()
+{
+ this->Search->setFocus(Qt::OtherFocusReason);
+ this->Search->selectAll();
+}
+
+void CMakeSetupDialog::setDebugOutput(bool flag)
+{
+ QMetaObject::invokeMethod(this->CMakeThread->cmakeInstance(),
+ "setDebugOutput", Qt::QueuedConnection, Q_ARG(bool, flag));
+}
+
+void CMakeSetupDialog::setGroupedView(bool v)
+{
+ this->CacheValues->cacheModel()->setViewType(v ? QCMakeCacheModel::GroupView : QCMakeCacheModel::FlatView);
+ this->CacheValues->setRootIsDecorated(v);
+
+ QSettings settings;
+ settings.beginGroup("Settings/StartPath");
+ settings.setValue("GroupView", v);
+
+}
+
+void CMakeSetupDialog::setAdvancedView(bool v)
+{
+ this->CacheValues->setShowAdvanced(v);
+ QSettings settings;
+ settings.beginGroup("Settings/StartPath");
+ settings.setValue("AdvancedView", v);
+}
+
+void CMakeSetupDialog::showUserChanges()
+{
+ QSet<QCMakeProperty> changes =
+ qobject_cast<QCMakeCacheModelDelegate*>(this->CacheValues->itemDelegate())->changes();
+
+ QDialog dialog(this);
+ dialog.setWindowTitle(tr("My Changes"));
+ dialog.resize(600, 400);
+ QVBoxLayout* l = new QVBoxLayout(&dialog);
+ QTextEdit* textedit = new QTextEdit(&dialog);
+ textedit->setReadOnly(true);
+ l->addWidget(textedit);
+ QDialogButtonBox* btns = new QDialogButtonBox(QDialogButtonBox::Close,
+ Qt::Horizontal, &dialog);
+ QObject::connect(btns, SIGNAL(rejected()), &dialog, SLOT(accept()));
+ l->addWidget(btns);
+
+ QString command;
+ QString cache;
+
+ foreach(QCMakeProperty prop, changes)
+ {
+ QString type;
+ switch(prop.Type)
+ {
+ case QCMakeProperty::BOOL:
+ type = "BOOL";
+ break;
+ case QCMakeProperty::PATH:
+ type = "PATH";
+ break;
+ case QCMakeProperty::FILEPATH:
+ type = "FILEPATH";
+ break;
+ case QCMakeProperty::STRING:
+ type = "STRING";
+ break;
+ }
+ QString value;
+ if(prop.Type == QCMakeProperty::BOOL)
+ {
+ value = prop.Value.toBool() ? "1" : "0";
+ }
+ else
+ {
+ value = prop.Value.toString();
+ }
+
+ QString line("%1:%2=");
+ line = line.arg(prop.Key);
+ line = line.arg(type);
+
+ command += QString("-D%1\"%2\" ").arg(line).arg(value);
+ cache += QString("%1%2\n").arg(line).arg(value);
+ }
+
+ textedit->append(tr("Commandline options:"));
+ textedit->append(command);
+ textedit->append("\n");
+ textedit->append(tr("Cache file:"));
+ textedit->append(cache);
+
+ dialog.exec();
+}
+
+void CMakeSetupDialog::setSearchFilter(const QString& str)
+{
+ this->CacheValues->selectionModel()->clear();
+ this->CacheValues->setSearchFilter(str);
+}
+
+
diff --git a/Source/QtDialog/CMakeSetupDialog.h b/Source/QtDialog/CMakeSetupDialog.h
new file mode 100644
index 000000000..259967580
--- /dev/null
+++ b/Source/QtDialog/CMakeSetupDialog.h
@@ -0,0 +1,132 @@
+/*============================================================================
+ 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 CMakeSetupDialog_h
+#define CMakeSetupDialog_h
+
+#include "QCMake.h"
+#include <QMainWindow>
+#include <QThread>
+#include <QEventLoop>
+#include "ui_CMakeSetupDialog.h"
+
+class QCMakeThread;
+class CMakeCacheModel;
+class QProgressBar;
+class QToolButton;
+
+/// Qt user interface for CMake
+class CMakeSetupDialog : public QMainWindow, public Ui::CMakeSetupDialog
+{
+ Q_OBJECT
+public:
+ CMakeSetupDialog();
+ ~CMakeSetupDialog();
+
+public slots:
+ void setBinaryDirectory(const QString& dir);
+ void setSourceDirectory(const QString& dir);
+
+protected slots:
+ void initialize();
+ void doConfigure();
+ void doGenerate();
+ void doInstallForCommandLine();
+ void doHelp();
+ void doAbout();
+ void doInterrupt();
+ void error(const QString& message);
+ void message(const QString& message);
+
+ void doSourceBrowse();
+ void doBinaryBrowse();
+ void doReloadCache();
+ void doDeleteCache();
+ void updateSourceDirectory(const QString& dir);
+ void updateBinaryDirectory(const QString& dir);
+ void showProgress(const QString& msg, float percent);
+ void setEnabledState(bool);
+ bool setupFirstConfigure();
+ void updateGeneratorLabel(const QString& gen);
+ void setExitAfterGenerate(bool);
+ void addBinaryPath(const QString&);
+ QStringList loadBuildPaths();
+ void saveBuildPaths(const QStringList&);
+ void onBinaryDirectoryChanged(const QString& dir);
+ void onSourceDirectoryChanged(const QString& dir);
+ void setCacheModified();
+ void removeSelectedCacheEntries();
+ void selectionChanged();
+ void addCacheEntry();
+ void startSearch();
+ void setDebugOutput(bool);
+ void setAdvancedView(bool);
+ void setGroupedView(bool);
+ void showUserChanges();
+ void setSearchFilter(const QString& str);
+ bool prepareConfigure();
+ bool doConfigureInternal();
+ bool doGenerateInternal();
+ void exitLoop(int);
+
+protected:
+
+ enum State { Interrupting, ReadyConfigure, ReadyGenerate, Configuring, Generating };
+ void enterState(State s);
+
+ void closeEvent(QCloseEvent*);
+ void dragEnterEvent(QDragEnterEvent*);
+ void dropEvent(QDropEvent*);
+
+ QCMakeThread* CMakeThread;
+ bool ExitAfterGenerate;
+ bool CacheModified;
+ bool ConfigureNeeded;
+ QAction* ReloadCacheAction;
+ QAction* DeleteCacheAction;
+ QAction* ExitAction;
+ QAction* ConfigureAction;
+ QAction* GenerateAction;
+ QAction* SuppressDevWarningsAction;
+ QAction* WarnUninitializedAction;
+ QAction* WarnUnusedAction;
+ QAction* InstallForCommandLineAction;
+ State CurrentState;
+
+ QTextCharFormat ErrorFormat;
+ QTextCharFormat MessageFormat;
+
+ QStringList AddVariableCompletions;
+
+ QEventLoop LocalLoop;
+
+ float ProgressOffset;
+ float ProgressFactor;
+};
+
+// QCMake instance on a thread
+class QCMakeThread : public QThread
+{
+ Q_OBJECT
+public:
+ QCMakeThread(QObject* p);
+ QCMake* cmakeInstance() const;
+
+signals:
+ void cmakeInitialized();
+
+protected:
+ virtual void run();
+ QCMake* CMakeInstance;
+};
+
+#endif // CMakeSetupDialog_h
diff --git a/Source/QtDialog/CMakeSetupDialog.ui b/Source/QtDialog/CMakeSetupDialog.ui
new file mode 100644
index 000000000..dc8ee3fbd
--- /dev/null
+++ b/Source/QtDialog/CMakeSetupDialog.ui
@@ -0,0 +1,310 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>CMakeSetupDialog</class>
+ <widget class="QWidget" name="CMakeSetupDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>707</width>
+ <height>582</height>
+ </rect>
+ </property>
+ <layout class="QGridLayout">
+ <property name="margin">
+ <number>9</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <item row="0" column="0">
+ <layout class="QGridLayout">
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Where is the source code:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="SourceDirectory"/>
+ </item>
+ <item row="0" column="2">
+ <widget class="QPushButton" name="BrowseSourceDirectoryButton">
+ <property name="text">
+ <string>Browse &amp;Source...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Where to build the binaries:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QComboBox" name="BinaryDirectory">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Ignored" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="editable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QPushButton" name="BrowseBinaryDirectoryButton">
+ <property name="text">
+ <string>Browse &amp;Build...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="0">
+ <widget class="QSplitter" name="Splitter">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <widget class="QFrame" name="frame">
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QVBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label_4">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Search:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="Search">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Minimum</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>23</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="groupedCheck">
+ <property name="text">
+ <string>Grouped</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="advancedCheck">
+ <property name="text">
+ <string>Advanced</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="AddEntry">
+ <property name="toolTip">
+ <string>Add New Entry</string>
+ </property>
+ <property name="text">
+ <string>&amp;Add Entry</string>
+ </property>
+ <property name="icon">
+ <iconset resource="CMakeSetup.qrc">
+ <normaloff>:/Icons/Plus16.png</normaloff>:/Icons/Plus16.png</iconset>
+ </property>
+ <property name="toolButtonStyle">
+ <enum>Qt::ToolButtonTextBesideIcon</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="RemoveEntry">
+ <property name="toolTip">
+ <string>Remove Selected Entries</string>
+ </property>
+ <property name="text">
+ <string>&amp;Remove Entry</string>
+ </property>
+ <property name="icon">
+ <iconset resource="CMakeSetup.qrc">
+ <normaloff>:/Icons/Delete16.png</normaloff>:/Icons/Delete16.png</iconset>
+ </property>
+ <property name="toolButtonStyle">
+ <enum>Qt::ToolButtonTextBesideIcon</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QCMakeCacheView" name="CacheValues">
+ <property name="alternatingRowColors">
+ <bool>true</bool>
+ </property>
+ <property name="selectionMode">
+ <enum>QAbstractItemView::ExtendedSelection</enum>
+ </property>
+ <property name="selectionBehavior">
+ <enum>QAbstractItemView::SelectRows</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Press Configure to update and display new values in red, then press Generate to generate selected build files.</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="ConfigureButton">
+ <property name="text">
+ <string>&amp;Configure</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="GenerateButton">
+ <property name="text">
+ <string>&amp;Generate</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="Generator">
+ <property name="text">
+ <string>Current Generator:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>121</width>
+ <height>27</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QProgressBar" name="ProgressBar">
+ <property name="minimum">
+ <number>0</number>
+ </property>
+ <property name="maximum">
+ <number>100</number>
+ </property>
+ <property name="value">
+ <number>0</number>
+ </property>
+ <property name="textVisible">
+ <bool>false</bool>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="textDirection">
+ <enum>QProgressBar::BottomToTop</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QTextEdit" name="Output">
+ <property name="lineWrapMode">
+ <enum>QTextEdit::NoWrap</enum>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>QCMakeCacheView</class>
+ <extends>QTreeView</extends>
+ <header>QCMakeCacheView.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources>
+ <include location="CMakeSetup.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/Source/QtDialog/Compilers.h b/Source/QtDialog/Compilers.h
new file mode 100644
index 000000000..e9c90a504
--- /dev/null
+++ b/Source/QtDialog/Compilers.h
@@ -0,0 +1,21 @@
+
+
+#ifndef COMPILERS_HPP
+#define COMPILERS_HPP
+
+#include <QWidget>
+#include <ui_Compilers.h>
+
+class Compilers : public QWidget, public Ui::Compilers
+{
+ Q_OBJECT
+public:
+ Compilers(QWidget* p=NULL) :
+ QWidget(p)
+ {
+ this->setupUi(this);
+ }
+};
+
+#endif
+
diff --git a/Source/QtDialog/Compilers.ui b/Source/QtDialog/Compilers.ui
new file mode 100644
index 000000000..41f70acdb
--- /dev/null
+++ b/Source/QtDialog/Compilers.ui
@@ -0,0 +1,87 @@
+<ui version="4.0" >
+ <class>Compilers</class>
+ <widget class="QWidget" name="Compilers" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>506</width>
+ <height>115</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item row="0" column="0" >
+ <widget class="QGroupBox" name="groupBox_4" >
+ <property name="title" >
+ <string>Compilers</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="leftMargin" >
+ <number>4</number>
+ </property>
+ <property name="topMargin" >
+ <number>4</number>
+ </property>
+ <property name="rightMargin" >
+ <number>4</number>
+ </property>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label_16" >
+ <property name="text" >
+ <string>C</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QCMakeFilePathEditor" name="CCompiler" />
+ </item>
+ <item row="0" column="2" >
+ <widget class="QLabel" name="label_17" >
+ <property name="text" >
+ <string>C++</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3" >
+ <widget class="QCMakeFilePathEditor" name="CXXCompiler" />
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_18" >
+ <property name="text" >
+ <string>Fortran</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QCMakeFilePathEditor" name="FortranCompiler" />
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>QCMakeFilePathEditor</class>
+ <extends>QLineEdit</extends>
+ <header>QCMakeWidgets.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Source/QtDialog/CrossCompiler.ui b/Source/QtDialog/CrossCompiler.ui
new file mode 100644
index 000000000..1fb1ebf49
--- /dev/null
+++ b/Source/QtDialog/CrossCompiler.ui
@@ -0,0 +1,213 @@
+<ui version="4.0" >
+ <class>CrossCompiler</class>
+ <widget class="QWidget" name="CrossCompiler" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>433</width>
+ <height>319</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>CrossCompiler</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <widget class="QGroupBox" name="groupBox" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title" >
+ <string>Target System</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label_6" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Operating System</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QLineEdit" name="systemName" />
+ </item>
+ <item row="0" column="2" colspan="2" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_10" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Version</string>
+ </property>
+ <property name="wordWrap" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QLineEdit" name="systemVersion" />
+ </item>
+ <item row="1" column="2" >
+ <widget class="QLabel" name="label_11" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Processor</string>
+ </property>
+ <property name="wordWrap" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3" >
+ <widget class="QLineEdit" name="systemProcessor" />
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QGroupBox" name="groupBox_2" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title" >
+ <string>Find Program/Library/Include</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label_9" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Target Root</string>
+ </property>
+ <property name="wordWrap" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QCMakePathEditor" name="crossFindRoot" />
+ </item>
+ <item row="0" column="2" >
+ <widget class="QLabel" name="label_12" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Program Mode</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3" >
+ <widget class="QComboBox" name="crossProgramMode" />
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_13" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Library Mode</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QComboBox" name="crossLibraryMode" />
+ </item>
+ <item row="1" column="2" >
+ <widget class="QLabel" name="label_14" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Include Mode</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3" >
+ <widget class="QComboBox" name="crossIncludeMode" />
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="Compilers" native="1" name="CrossCompilers" >
+ <property name="focusPolicy" >
+ <enum>Qt::TabFocus</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>QCMakePathEditor</class>
+ <extends>QLineEdit</extends>
+ <header>QCMakeWidgets.h</header>
+ </customwidget>
+ <customwidget>
+ <class>Compilers</class>
+ <extends>QWidget</extends>
+ <header>Compilers.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <tabstops>
+ <tabstop>systemVersion</tabstop>
+ <tabstop>systemProcessor</tabstop>
+ <tabstop>CrossCompilers</tabstop>
+ <tabstop>crossFindRoot</tabstop>
+ <tabstop>crossProgramMode</tabstop>
+ <tabstop>crossLibraryMode</tabstop>
+ <tabstop>crossIncludeMode</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Source/QtDialog/Delete16.png b/Source/QtDialog/Delete16.png
new file mode 100644
index 000000000..16989fee1
--- /dev/null
+++ b/Source/QtDialog/Delete16.png
Binary files differ
diff --git a/Source/QtDialog/FirstConfigure.cxx b/Source/QtDialog/FirstConfigure.cxx
new file mode 100644
index 000000000..2a79877da
--- /dev/null
+++ b/Source/QtDialog/FirstConfigure.cxx
@@ -0,0 +1,509 @@
+
+#include "FirstConfigure.h"
+#include "Compilers.h"
+
+#include <QSettings>
+#include <QRadioButton>
+#include <QComboBox>
+#include <QVBoxLayout>
+
+
+StartCompilerSetup::StartCompilerSetup(QWidget* p)
+ : QWizardPage(p)
+{
+ QVBoxLayout* l = new QVBoxLayout(this);
+ l->addWidget(new QLabel(tr("Specify the generator for this project")));
+ this->GeneratorOptions = new QComboBox(this);
+ l->addWidget(this->GeneratorOptions);
+ l->addSpacing(6);
+
+ this->CompilerSetupOptions[0] = new QRadioButton(tr("Use default native compilers"), this);
+ this->CompilerSetupOptions[1] = new QRadioButton(tr("Specify native compilers"), this);
+ this->CompilerSetupOptions[2] = new QRadioButton(tr("Specify toolchain file for cross-compiling"), this);
+ this->CompilerSetupOptions[3] = new QRadioButton(tr("Specify options for cross-compiling"), this);
+ l->addWidget(this->CompilerSetupOptions[0]);
+ l->addWidget(this->CompilerSetupOptions[1]);
+ l->addWidget(this->CompilerSetupOptions[2]);
+ l->addWidget(this->CompilerSetupOptions[3]);
+
+ this->CompilerSetupOptions[0]->setChecked(true);
+
+ QObject::connect(this->CompilerSetupOptions[0], SIGNAL(toggled(bool)),
+ this, SLOT(onSelectionChanged(bool)));
+ QObject::connect(this->CompilerSetupOptions[1], SIGNAL(toggled(bool)),
+ this, SLOT(onSelectionChanged(bool)));
+ QObject::connect(this->CompilerSetupOptions[2], SIGNAL(toggled(bool)),
+ this, SLOT(onSelectionChanged(bool)));
+ QObject::connect(this->CompilerSetupOptions[3], SIGNAL(toggled(bool)),
+ this, SLOT(onSelectionChanged(bool)));
+}
+
+StartCompilerSetup::~StartCompilerSetup()
+{
+}
+
+void StartCompilerSetup::setGenerators(const QStringList& gens)
+{
+ this->GeneratorOptions->clear();
+ this->GeneratorOptions->addItems(gens);
+};
+
+void StartCompilerSetup::setCurrentGenerator(const QString& gen)
+{
+ int idx = this->GeneratorOptions->findText(gen);
+ if(idx != -1)
+ {
+ this->GeneratorOptions->setCurrentIndex(idx);
+ }
+}
+
+QString StartCompilerSetup::getGenerator() const
+{
+ return this->GeneratorOptions->currentText();
+};
+
+bool StartCompilerSetup::defaultSetup() const
+{
+ return this->CompilerSetupOptions[0]->isChecked();
+}
+
+bool StartCompilerSetup::compilerSetup() const
+{
+ return this->CompilerSetupOptions[1]->isChecked();
+}
+
+bool StartCompilerSetup::crossCompilerToolChainFile() const
+{
+ return this->CompilerSetupOptions[2]->isChecked();
+}
+
+bool StartCompilerSetup::crossCompilerSetup() const
+{
+ return this->CompilerSetupOptions[3]->isChecked();
+}
+
+void StartCompilerSetup::onSelectionChanged(bool on)
+{
+ if(on)
+ selectionChanged();
+}
+
+int StartCompilerSetup::nextId() const
+{
+ if(compilerSetup())
+ return NativeSetup;
+ if(crossCompilerSetup())
+ return CrossSetup;
+ if(crossCompilerToolChainFile())
+ return ToolchainSetup;
+ return -1;
+}
+
+NativeCompilerSetup::NativeCompilerSetup(QWidget* p)
+ : QWizardPage(p)
+{
+ QVBoxLayout* l = new QVBoxLayout(this);
+ QWidget* c = new QWidget(this);
+ l->addWidget(c);
+ this->setupUi(c);
+}
+
+NativeCompilerSetup::~NativeCompilerSetup()
+{
+}
+
+QString NativeCompilerSetup::getCCompiler() const
+{
+ return this->CCompiler->text();
+}
+
+void NativeCompilerSetup::setCCompiler(const QString& s)
+{
+ this->CCompiler->setText(s);
+}
+
+QString NativeCompilerSetup::getCXXCompiler() const
+{
+ return this->CXXCompiler->text();
+}
+
+void NativeCompilerSetup::setCXXCompiler(const QString& s)
+{
+ this->CXXCompiler->setText(s);
+}
+
+QString NativeCompilerSetup::getFortranCompiler() const
+{
+ return this->FortranCompiler->text();
+}
+
+void NativeCompilerSetup::setFortranCompiler(const QString& s)
+{
+ this->FortranCompiler->setText(s);
+}
+
+
+CrossCompilerSetup::CrossCompilerSetup(QWidget* p)
+ : QWizardPage(p)
+{
+ this->setupUi(this);
+ QWidget::setTabOrder(systemName, systemVersion);
+ QWidget::setTabOrder(systemVersion, systemProcessor);
+ QWidget::setTabOrder(systemProcessor, CrossCompilers->CCompiler);
+ QWidget::setTabOrder(CrossCompilers->CCompiler, CrossCompilers->CXXCompiler);
+ QWidget::setTabOrder(CrossCompilers->CXXCompiler, CrossCompilers->FortranCompiler);
+ QWidget::setTabOrder(CrossCompilers->FortranCompiler, crossFindRoot);
+ QWidget::setTabOrder(crossFindRoot, crossProgramMode);
+ QWidget::setTabOrder(crossProgramMode, crossLibraryMode);
+ QWidget::setTabOrder(crossLibraryMode, crossIncludeMode);
+
+ // fill in combo boxes
+ QStringList modes;
+ modes << tr("Search in Target Root, then native system");
+ modes << tr("Search only in Target Root");
+ modes << tr("Search only in native system");
+ crossProgramMode->addItems(modes);
+ crossLibraryMode->addItems(modes);
+ crossIncludeMode->addItems(modes);
+ crossProgramMode->setCurrentIndex(2);
+ crossLibraryMode->setCurrentIndex(1);
+ crossIncludeMode->setCurrentIndex(1);
+
+ this->registerField("systemName*", this->systemName);
+}
+
+CrossCompilerSetup::~CrossCompilerSetup()
+{
+}
+
+QString CrossCompilerSetup::getCCompiler() const
+{
+ return this->CrossCompilers->CCompiler->text();
+}
+
+void CrossCompilerSetup::setCCompiler(const QString& s)
+{
+ this->CrossCompilers->CCompiler->setText(s);
+}
+
+QString CrossCompilerSetup::getCXXCompiler() const
+{
+ return this->CrossCompilers->CXXCompiler->text();
+}
+
+void CrossCompilerSetup::setCXXCompiler(const QString& s)
+{
+ this->CrossCompilers->CXXCompiler->setText(s);
+}
+
+QString CrossCompilerSetup::getFortranCompiler() const
+{
+ return this->CrossCompilers->FortranCompiler->text();
+}
+
+void CrossCompilerSetup::setFortranCompiler(const QString& s)
+{
+ this->CrossCompilers->FortranCompiler->setText(s);
+}
+
+QString CrossCompilerSetup::getSystem() const
+{
+ return this->systemName->text();
+}
+
+void CrossCompilerSetup::setSystem(const QString& t)
+{
+ this->systemName->setText(t);
+}
+
+
+QString CrossCompilerSetup::getVersion() const
+{
+ return this->systemVersion->text();
+}
+
+void CrossCompilerSetup::setVersion(const QString& t)
+{
+ this->systemVersion->setText(t);
+}
+
+
+QString CrossCompilerSetup::getProcessor() const
+{
+ return this->systemProcessor->text();
+}
+
+void CrossCompilerSetup::setProcessor(const QString& t)
+{
+ this->systemProcessor->setText(t);
+}
+
+QString CrossCompilerSetup::getFindRoot() const
+{
+ return this->crossFindRoot->text();
+}
+
+void CrossCompilerSetup::setFindRoot(const QString& t)
+{
+ return this->crossFindRoot->setText(t);
+}
+
+int CrossCompilerSetup::getProgramMode() const
+{
+ return this->crossProgramMode->currentIndex();
+}
+
+int CrossCompilerSetup::getLibraryMode() const
+{
+ return this->crossLibraryMode->currentIndex();
+}
+
+int CrossCompilerSetup::getIncludeMode() const
+{
+ return this->crossIncludeMode->currentIndex();
+}
+
+void CrossCompilerSetup::setProgramMode(int m)
+{
+ this->crossProgramMode->setCurrentIndex(m);
+}
+
+void CrossCompilerSetup::setLibraryMode(int m)
+{
+ this->crossLibraryMode->setCurrentIndex(m);
+}
+
+void CrossCompilerSetup::setIncludeMode(int m)
+{
+ this->crossIncludeMode->setCurrentIndex(m);
+}
+
+ToolchainCompilerSetup::ToolchainCompilerSetup(QWidget* p)
+ : QWizardPage(p)
+{
+ QVBoxLayout* l = new QVBoxLayout(this);
+ l->addWidget(new QLabel(tr("Specify the Toolchain file")));
+ this->ToolchainFile = new QCMakeFilePathEditor(this);
+ l->addWidget(this->ToolchainFile);
+}
+
+ToolchainCompilerSetup::~ToolchainCompilerSetup()
+{
+}
+
+QString ToolchainCompilerSetup::toolchainFile() const
+{
+ return this->ToolchainFile->text();
+}
+
+void ToolchainCompilerSetup::setToolchainFile(const QString& t)
+{
+ this->ToolchainFile->setText(t);
+}
+
+
+
+FirstConfigure::FirstConfigure()
+{
+ //this->setOption(QWizard::HaveFinishButtonOnEarlyPages, true);
+ this->mStartCompilerSetupPage = new StartCompilerSetup(this);
+ this->setPage(Start, this->mStartCompilerSetupPage);
+ QObject::connect(this->mStartCompilerSetupPage, SIGNAL(selectionChanged()),
+ this, SLOT(restart()));
+
+ this->mNativeCompilerSetupPage = new NativeCompilerSetup(this);
+ this->setPage(NativeSetup, this->mNativeCompilerSetupPage);
+
+ this->mCrossCompilerSetupPage = new CrossCompilerSetup(this);
+ this->setPage(CrossSetup, this->mCrossCompilerSetupPage);
+
+ this->mToolchainCompilerSetupPage = new ToolchainCompilerSetup(this);
+ this->setPage(ToolchainSetup, this->mToolchainCompilerSetupPage);
+}
+
+FirstConfigure::~FirstConfigure()
+{
+}
+
+void FirstConfigure::setGenerators(const QStringList& gens)
+{
+ this->mStartCompilerSetupPage->setGenerators(gens);
+}
+
+QString FirstConfigure::getGenerator() const
+{
+ return this->mStartCompilerSetupPage->getGenerator();
+}
+
+void FirstConfigure::loadFromSettings()
+{
+ QSettings settings;
+ // restore generator
+ settings.beginGroup("Settings/StartPath");
+ QString lastGen = settings.value("LastGenerator").toString();
+ this->mStartCompilerSetupPage->setCurrentGenerator(lastGen);
+ settings.endGroup();
+
+ // restore compiler setup
+ settings.beginGroup("Settings/Compiler");
+ this->mNativeCompilerSetupPage->setCCompiler(settings.value("CCompiler").toString());
+ this->mNativeCompilerSetupPage->setCXXCompiler(settings.value("CXXCompiler").toString());
+ this->mNativeCompilerSetupPage->setFortranCompiler(settings.value("FortranCompiler").toString());
+ settings.endGroup();
+
+ // restore cross compiler setup
+ settings.beginGroup("Settings/CrossCompiler");
+ this->mCrossCompilerSetupPage->setCCompiler(settings.value("CCompiler").toString());
+ this->mCrossCompilerSetupPage->setCXXCompiler(settings.value("CXXCompiler").toString());
+ this->mCrossCompilerSetupPage->setFortranCompiler(settings.value("FortranCompiler").toString());
+ this->mToolchainCompilerSetupPage->setToolchainFile(settings.value("ToolChainFile").toString());
+ this->mCrossCompilerSetupPage->setSystem(settings.value("SystemName").toString());
+ this->mCrossCompilerSetupPage->setVersion(settings.value("SystemVersion").toString());
+ this->mCrossCompilerSetupPage->setProcessor(settings.value("SystemProcessor").toString());
+ this->mCrossCompilerSetupPage->setFindRoot(settings.value("FindRoot").toString());
+ this->mCrossCompilerSetupPage->setProgramMode(settings.value("ProgramMode", 0).toInt());
+ this->mCrossCompilerSetupPage->setLibraryMode(settings.value("LibraryMode", 0).toInt());
+ this->mCrossCompilerSetupPage->setIncludeMode(settings.value("IncludeMode", 0).toInt());
+ settings.endGroup();
+}
+
+void FirstConfigure::saveToSettings()
+{
+ QSettings settings;
+
+ // save generator
+ settings.beginGroup("Settings/StartPath");
+ QString lastGen = this->mStartCompilerSetupPage->getGenerator();
+ settings.setValue("LastGenerator", lastGen);
+ settings.endGroup();
+
+ // save compiler setup
+ settings.beginGroup("Settings/Compiler");
+ settings.setValue("CCompiler", this->mNativeCompilerSetupPage->getCCompiler());
+ settings.setValue("CXXCompiler", this->mNativeCompilerSetupPage->getCXXCompiler());
+ settings.setValue("FortranCompiler", this->mNativeCompilerSetupPage->getFortranCompiler());
+ settings.endGroup();
+
+ // save cross compiler setup
+ settings.beginGroup("Settings/CrossCompiler");
+ settings.setValue("CCompiler", this->mCrossCompilerSetupPage->getCCompiler());
+ settings.setValue("CXXCompiler", this->mCrossCompilerSetupPage->getCXXCompiler());
+ settings.setValue("FortranCompiler", this->mCrossCompilerSetupPage->getFortranCompiler());
+ settings.setValue("ToolChainFile", this->getCrossCompilerToolChainFile());
+ settings.setValue("SystemName", this->mCrossCompilerSetupPage->getSystem());
+ settings.setValue("SystemVersion", this->mCrossCompilerSetupPage->getVersion());
+ settings.setValue("SystemProcessor", this->mCrossCompilerSetupPage->getProcessor());
+ settings.setValue("FindRoot", this->mCrossCompilerSetupPage->getFindRoot());
+ settings.setValue("ProgramMode", this->mCrossCompilerSetupPage->getProgramMode());
+ settings.setValue("LibraryMode", this->mCrossCompilerSetupPage->getLibraryMode());
+ settings.setValue("IncludeMode", this->mCrossCompilerSetupPage->getIncludeMode());
+ settings.endGroup();
+}
+
+bool FirstConfigure::defaultSetup() const
+{
+ return this->mStartCompilerSetupPage->defaultSetup();
+}
+
+bool FirstConfigure::compilerSetup() const
+{
+ return this->mStartCompilerSetupPage->compilerSetup();
+}
+
+bool FirstConfigure::crossCompilerSetup() const
+{
+ return this->mStartCompilerSetupPage->crossCompilerSetup();
+}
+
+bool FirstConfigure::crossCompilerToolChainFile() const
+{
+ return this->mStartCompilerSetupPage->crossCompilerToolChainFile();
+}
+
+QString FirstConfigure::getCrossCompilerToolChainFile() const
+{
+ return this->mToolchainCompilerSetupPage->toolchainFile();
+}
+
+QString FirstConfigure::getSystemName() const
+{
+ return this->mCrossCompilerSetupPage->getSystem();
+}
+
+QString FirstConfigure::getCCompiler() const
+{
+ if(this->compilerSetup())
+ {
+ return this->mNativeCompilerSetupPage->getCCompiler();
+ }
+ else if(this->crossCompilerSetup())
+ {
+ return this->mCrossCompilerSetupPage->getCCompiler();
+ }
+ return QString();
+}
+
+QString FirstConfigure::getCXXCompiler() const
+{
+ if(this->compilerSetup())
+ {
+ return this->mNativeCompilerSetupPage->getCXXCompiler();
+ }
+ else if(this->crossCompilerSetup())
+ {
+ return this->mCrossCompilerSetupPage->getCXXCompiler();
+ }
+ return QString();
+}
+
+QString FirstConfigure::getFortranCompiler() const
+{
+ if(this->compilerSetup())
+ {
+ return this->mNativeCompilerSetupPage->getFortranCompiler();
+ }
+ else if(this->crossCompilerSetup())
+ {
+ return this->mCrossCompilerSetupPage->getFortranCompiler();
+ }
+ return QString();
+}
+
+
+QString FirstConfigure::getSystemVersion() const
+{
+ return this->mCrossCompilerSetupPage->getVersion();
+}
+
+QString FirstConfigure::getSystemProcessor() const
+{
+ return this->mCrossCompilerSetupPage->getProcessor();
+}
+
+QString FirstConfigure::getCrossRoot() const
+{
+ return this->mCrossCompilerSetupPage->getFindRoot();
+}
+
+const QString CrossModes[] =
+{
+ "BOTH",
+ "ONLY",
+ "NEVER"
+};
+
+QString FirstConfigure::getCrossProgramMode() const
+{
+ return CrossModes[this->mCrossCompilerSetupPage->getProgramMode()];
+}
+
+QString FirstConfigure::getCrossLibraryMode() const
+{
+ return CrossModes[this->mCrossCompilerSetupPage->getLibraryMode()];
+}
+
+QString FirstConfigure::getCrossIncludeMode() const
+{
+ return CrossModes[this->mCrossCompilerSetupPage->getIncludeMode()];
+}
+
diff --git a/Source/QtDialog/FirstConfigure.h b/Source/QtDialog/FirstConfigure.h
new file mode 100644
index 000000000..f4e368bfc
--- /dev/null
+++ b/Source/QtDialog/FirstConfigure.h
@@ -0,0 +1,177 @@
+
+#ifndef FirstConfigure_h
+#define FirstConfigure_h
+
+#include <QWizard>
+#include <QWizardPage>
+#include "ui_Compilers.h"
+#include "ui_CrossCompiler.h"
+
+class QRadioButton;
+class QComboBox;
+
+//! the wizard pages we'll use for the first configure of a build
+enum FirstConfigurePages
+{
+ Start,
+ NativeSetup,
+ ToolchainSetup,
+ CrossSetup,
+ Done
+};
+
+//! the first page that gives basic options for what compilers setup to choose from
+class StartCompilerSetup : public QWizardPage
+{
+ Q_OBJECT
+ public:
+ StartCompilerSetup(QWidget* p);
+ ~StartCompilerSetup();
+ void setGenerators(const QStringList& gens);
+ void setCurrentGenerator(const QString& gen);
+ QString getGenerator() const;
+
+ bool defaultSetup() const;
+ bool compilerSetup() const;
+ bool crossCompilerSetup() const;
+ bool crossCompilerToolChainFile() const;
+
+ int nextId() const;
+
+ signals:
+ void selectionChanged();
+
+ protected slots:
+ void onSelectionChanged(bool);
+
+ protected:
+ QComboBox* GeneratorOptions;
+ QRadioButton* CompilerSetupOptions[4];
+};
+
+//! the page that gives basic options for native compilers
+class NativeCompilerSetup : public QWizardPage, protected Ui::Compilers
+{
+ Q_OBJECT
+ public:
+ NativeCompilerSetup(QWidget* p);
+ ~NativeCompilerSetup();
+
+ QString getCCompiler() const;
+ void setCCompiler(const QString&);
+
+ QString getCXXCompiler() const;
+ void setCXXCompiler(const QString&);
+
+ QString getFortranCompiler() const;
+ void setFortranCompiler(const QString&);
+
+ int nextId() const { return -1; }
+};
+
+//! the page that gives options for cross compilers
+class CrossCompilerSetup : public QWizardPage, protected Ui::CrossCompiler
+{
+ Q_OBJECT
+ public:
+ CrossCompilerSetup(QWidget* p);
+ ~CrossCompilerSetup();
+
+ QString getSystem() const;
+ void setSystem(const QString&);
+
+ QString getVersion() const;
+ void setVersion(const QString&);
+
+ QString getProcessor() const;
+ void setProcessor(const QString&);
+
+ QString getCCompiler() const;
+ void setCCompiler(const QString&);
+
+ QString getCXXCompiler() const;
+ void setCXXCompiler(const QString&);
+
+ QString getFortranCompiler() const;
+ void setFortranCompiler(const QString&);
+
+ QString getFindRoot() const;
+ void setFindRoot(const QString&);
+
+ enum CrossMode
+ {
+ BOTH,
+ ONLY,
+ NEVER
+ };
+
+ int getProgramMode() const;
+ void setProgramMode(int);
+ int getLibraryMode() const;
+ void setLibraryMode(int);
+ int getIncludeMode() const;
+ void setIncludeMode(int);
+
+ int nextId() const { return -1; }
+};
+
+//! the page that gives options for a toolchain file
+class ToolchainCompilerSetup : public QWizardPage
+{
+ Q_OBJECT
+ public:
+ ToolchainCompilerSetup(QWidget* p);
+ ~ToolchainCompilerSetup();
+
+ QString toolchainFile() const;
+ void setToolchainFile(const QString&);
+
+ int nextId() const { return -1; }
+
+ protected:
+ QCMakeFilePathEditor* ToolchainFile;
+};
+
+//! the wizard with the pages
+class FirstConfigure : public QWizard
+{
+ Q_OBJECT
+public:
+ FirstConfigure();
+ ~FirstConfigure();
+
+ void setGenerators(const QStringList& gens);
+ QString getGenerator() const;
+
+ bool defaultSetup() const;
+ bool compilerSetup() const;
+ bool crossCompilerSetup() const;
+ bool crossCompilerToolChainFile() const;
+
+ QString getCCompiler() const;
+ QString getCXXCompiler() const;
+ QString getFortranCompiler() const;
+
+ QString getSystemName() const;
+ QString getSystemVersion() const;
+ QString getSystemProcessor() const;
+ QString getCrossRoot() const;
+ QString getCrossProgramMode() const;
+ QString getCrossLibraryMode() const;
+ QString getCrossIncludeMode() const;
+
+ QString getCrossCompilerToolChainFile() const;
+
+ void loadFromSettings();
+ void saveToSettings();
+
+protected:
+ StartCompilerSetup* mStartCompilerSetupPage;
+ NativeCompilerSetup* mNativeCompilerSetupPage;
+ CrossCompilerSetup* mCrossCompilerSetupPage;
+ ToolchainCompilerSetup* mToolchainCompilerSetupPage;
+
+};
+
+#endif // FirstConfigure_h
+
diff --git a/Source/QtDialog/MacInstallDialog.ui b/Source/QtDialog/MacInstallDialog.ui
new file mode 100644
index 000000000..c7e31dbbe
--- /dev/null
+++ b/Source/QtDialog/MacInstallDialog.ui
@@ -0,0 +1,103 @@
+<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/Plus16.png b/Source/QtDialog/Plus16.png
new file mode 100644
index 000000000..552f6f004
--- /dev/null
+++ b/Source/QtDialog/Plus16.png
Binary files differ
diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx
new file mode 100644
index 000000000..8554ff894
--- /dev/null
+++ b/Source/QtDialog/QCMake.cxx
@@ -0,0 +1,448 @@
+/*============================================================================
+ 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 "QCMake.h"
+
+#include <QDir>
+#include <QCoreApplication>
+
+#include "cmake.h"
+#include "cmCacheManager.h"
+#include "cmSystemTools.h"
+#include "cmExternalMakefileProjectGenerator.h"
+
+#ifdef Q_OS_WIN
+#include "qt_windows.h" // For SetErrorMode
+#endif
+
+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());
+
+ 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->SetProgressCallback(QCMake::progressCallback, this);
+
+ cmSystemTools::SetInterruptCallback(QCMake::interruptCallback, this);
+
+ std::vector<std::string> generators;
+ this->CMakeInstance->GetRegisteredGenerators(generators);
+ std::vector<std::string>::iterator iter;
+ for(iter = generators.begin(); iter != generators.end(); ++iter)
+ {
+ // 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")
+ {
+ continue;
+ }
+ this->AvailableGenerators.append(QString::fromLocal8Bit(iter->c_str()));
+ }
+}
+
+QCMake::~QCMake()
+{
+ delete this->CMakeInstance;
+ //cmDynamicLoader::FlushCache();
+}
+
+void QCMake::loadCache(const QString& dir)
+{
+ this->setBinaryDirectory(dir);
+}
+
+void QCMake::setSourceDirectory(const QString& _dir)
+{
+ QString dir =
+ QString::fromLocal8Bit(cmSystemTools::GetActualCaseForPath(_dir.toLocal8Bit().data()).c_str());
+ if(this->SourceDirectory != dir)
+ {
+ this->SourceDirectory = QDir::fromNativeSeparators(dir);
+ emit this->sourceDirChanged(this->SourceDirectory);
+ }
+}
+
+void QCMake::setBinaryDirectory(const QString& _dir)
+{
+ QString dir =
+ QString::fromLocal8Bit(cmSystemTools::GetActualCaseForPath(_dir.toLocal8Bit().data()).c_str());
+ if(this->BinaryDirectory != dir)
+ {
+ this->BinaryDirectory = QDir::fromNativeSeparators(dir);
+ emit this->binaryDirChanged(this->BinaryDirectory);
+ cmCacheManager *cachem = this->CMakeInstance->GetCacheManager();
+ this->setGenerator(QString());
+ if(!this->CMakeInstance->GetCacheManager()->LoadCache(
+ this->BinaryDirectory.toLocal8Bit().data()))
+ {
+ QDir testDir(this->BinaryDirectory);
+ if(testDir.exists("CMakeCache.txt"))
+ {
+ cmSystemTools::Error("There is a CMakeCache.txt file for the current binary "
+ "tree but cmake does not have permission to read it. "
+ "Please check the permissions of the directory you are trying to run CMake on.");
+ }
+ }
+
+ QCMakePropertyList props = this->properties();
+ emit this->propertiesChanged(props);
+ cmCacheManager::CacheIterator itm = cachem->NewIterator();
+ if ( itm.Find("CMAKE_HOME_DIRECTORY"))
+ {
+ setSourceDirectory(QString::fromLocal8Bit(itm.GetValue()));
+ }
+ if ( itm.Find("CMAKE_GENERATOR"))
+ {
+ const char* extraGen = cachem->GetCacheValue("CMAKE_EXTRA_GENERATOR");
+ std::string curGen = cmExternalMakefileProjectGenerator::
+ CreateFullGeneratorName(itm.GetValue(), extraGen);
+ this->setGenerator(QString::fromLocal8Bit(curGen.c_str()));
+ }
+ }
+}
+
+
+void QCMake::setGenerator(const QString& gen)
+{
+ if(this->Generator != gen)
+ {
+ this->Generator = gen;
+ emit this->generatorChanged(this->Generator);
+ }
+}
+
+void QCMake::configure()
+{
+#ifdef Q_OS_WIN
+ UINT lastErrorMode = SetErrorMode(0);
+#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->LoadCache();
+ this->CMakeInstance->SetSuppressDevWarnings(this->SuppressDevWarnings);
+ this->CMakeInstance->SetWarnUninitialized(this->WarnUninitializedMode);
+ this->CMakeInstance->SetWarnUnused(this->WarnUnusedMode);
+ this->CMakeInstance->PreLoadCMakeFiles();
+
+ InterruptFlag = 0;
+ cmSystemTools::ResetErrorOccuredFlag();
+
+ int err = this->CMakeInstance->Configure();
+
+#ifdef Q_OS_WIN
+ SetErrorMode(lastErrorMode);
+#endif
+
+ emit this->propertiesChanged(this->properties());
+ emit this->configureDone(err);
+}
+
+void QCMake::generate()
+{
+#ifdef Q_OS_WIN
+ UINT lastErrorMode = SetErrorMode(0);
+#endif
+
+ InterruptFlag = 0;
+ cmSystemTools::ResetErrorOccuredFlag();
+
+ int err = this->CMakeInstance->Generate();
+
+#ifdef Q_OS_WIN
+ SetErrorMode(lastErrorMode);
+#endif
+
+ emit this->generateDone(err);
+}
+
+void QCMake::setProperties(const QCMakePropertyList& newProps)
+{
+ QCMakePropertyList props = newProps;
+
+ QStringList toremove;
+
+ // set the value of properties
+ cmCacheManager *cachem = this->CMakeInstance->GetCacheManager();
+ for(cmCacheManager::CacheIterator i = cachem->NewIterator();
+ !i.IsAtEnd(); i.Next())
+ {
+
+ if(i.GetType() == cmCacheManager::INTERNAL ||
+ i.GetType() == cmCacheManager::STATIC)
+ {
+ continue;
+ }
+
+ QCMakeProperty prop;
+ prop.Key = QString::fromLocal8Bit(i.GetName());
+ int idx = props.indexOf(prop);
+ if(idx == -1)
+ {
+ toremove.append(QString::fromLocal8Bit(i.GetName()));
+ }
+ else
+ {
+ prop = props[idx];
+ if(prop.Value.type() == QVariant::Bool)
+ {
+ i.SetValue(prop.Value.toBool() ? "ON" : "OFF");
+ }
+ else
+ {
+ i.SetValue(prop.Value.toString().toLocal8Bit().data());
+ }
+ props.removeAt(idx);
+ }
+
+ }
+
+ // remove some properites
+ foreach(QString s, toremove)
+ {
+ this->CMakeInstance->UnwatchUnusedCli(s.toLocal8Bit().data());
+
+ cachem->RemoveCacheEntry(s.toLocal8Bit().data());
+ }
+
+ // add some new properites
+ foreach(QCMakeProperty s, props)
+ {
+ this->CMakeInstance->WatchUnusedCli(s.Key.toLocal8Bit().data());
+
+ if(s.Type == QCMakeProperty::BOOL)
+ {
+ this->CMakeInstance->AddCacheEntry(s.Key.toLocal8Bit().data(),
+ s.Value.toBool() ? "ON" : "OFF",
+ s.Help.toLocal8Bit().data(),
+ cmCacheManager::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);
+ }
+ else if(s.Type == QCMakeProperty::PATH)
+ {
+ this->CMakeInstance->AddCacheEntry(s.Key.toLocal8Bit().data(),
+ s.Value.toString().toLocal8Bit().data(),
+ s.Help.toLocal8Bit().data(),
+ cmCacheManager::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);
+ }
+ }
+
+ cachem->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())
+ {
+
+ if(i.GetType() == cmCacheManager::INTERNAL ||
+ i.GetType() == cmCacheManager::STATIC ||
+ i.GetType() == cmCacheManager::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");
+
+ if(i.GetType() == cmCacheManager::BOOL)
+ {
+ prop.Type = QCMakeProperty::BOOL;
+ prop.Value = cmSystemTools::IsOn(i.GetValue());
+ }
+ else if(i.GetType() == cmCacheManager::PATH)
+ {
+ prop.Type = QCMakeProperty::PATH;
+ }
+ else if(i.GetType() == cmCacheManager::FILEPATH)
+ {
+ prop.Type = QCMakeProperty::FILEPATH;
+ }
+ else if(i.GetType() == cmCacheManager::STRING)
+ {
+ prop.Type = QCMakeProperty::STRING;
+ if (i.PropertyExists("STRINGS"))
+ {
+ prop.Strings = QString::fromLocal8Bit(i.GetProperty("STRINGS")).split(";");
+ }
+ }
+
+ ret.append(prop);
+ }
+
+ return ret;
+}
+
+void QCMake::interrupt()
+{
+ this->InterruptFlag.ref();
+}
+
+bool QCMake::interruptCallback(void* cd)
+{
+ QCMake* self = reinterpret_cast<QCMake*>(cd);
+ return self->InterruptFlag;
+}
+
+void QCMake::progressCallback(const char* msg, float percent, void* cd)
+{
+ QCMake* self = reinterpret_cast<QCMake*>(cd);
+ if(percent >= 0)
+ {
+ emit self->progressChanged(QString::fromLocal8Bit(msg), percent);
+ }
+ else
+ {
+ emit self->outputMessage(QString::fromLocal8Bit(msg));
+ }
+ QCoreApplication::processEvents();
+}
+
+void QCMake::errorCallback(const char* msg, const char* /*title*/,
+ bool& /*stop*/, void* cd)
+{
+ QCMake* self = reinterpret_cast<QCMake*>(cd);
+ emit self->errorMessage(QString::fromLocal8Bit(msg));
+ QCoreApplication::processEvents();
+}
+
+QString QCMake::binaryDirectory() const
+{
+ return this->BinaryDirectory;
+}
+
+QString QCMake::sourceDirectory() const
+{
+ return this->SourceDirectory;
+}
+
+QString QCMake::generator() const
+{
+ return this->Generator;
+}
+
+QStringList QCMake::availableGenerators() const
+{
+ return this->AvailableGenerators;
+}
+
+void QCMake::deleteCache()
+{
+ // delete cache
+ this->CMakeInstance->GetCacheManager()->DeleteCache(this->BinaryDirectory.toLocal8Bit().data());
+ // reload to make our cache empty
+ this->CMakeInstance->GetCacheManager()->LoadCache(this->BinaryDirectory.toLocal8Bit().data());
+ // emit no generator and no properties
+ this->setGenerator(QString());
+ QCMakePropertyList props = this->properties();
+ emit this->propertiesChanged(props);
+}
+
+void QCMake::reloadCache()
+{
+ // emit that the cache was cleaned out
+ QCMakePropertyList props;
+ emit this->propertiesChanged(props);
+ // reload
+ this->CMakeInstance->GetCacheManager()->LoadCache(this->BinaryDirectory.toLocal8Bit().data());
+ // emit new cache properties
+ props = this->properties();
+ emit this->propertiesChanged(props);
+}
+
+void QCMake::setDebugOutput(bool flag)
+{
+ if(flag != this->CMakeInstance->GetDebugOutput())
+ {
+ this->CMakeInstance->SetDebugOutputOn(flag);
+ emit this->debugOutputChanged(flag);
+ }
+}
+
+bool QCMake::getDebugOutput() const
+{
+ return this->CMakeInstance->GetDebugOutput();
+}
+
+
+void QCMake::setSuppressDevWarnings(bool value)
+{
+ this->SuppressDevWarnings = value;
+}
+
+void QCMake::setWarnUninitializedMode(bool value)
+{
+ this->WarnUninitializedMode = value;
+}
+
+void QCMake::setWarnUnusedMode(bool value)
+{
+ this->WarnUnusedMode = value;
+}
diff --git a/Source/QtDialog/QCMake.h b/Source/QtDialog/QCMake.h
new file mode 100644
index 000000000..0d68586f2
--- /dev/null
+++ b/Source/QtDialog/QCMake.h
@@ -0,0 +1,154 @@
+/*============================================================================
+ 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 __QCMake_h
+#define __QCMake_h
+#ifdef _MSC_VER
+#pragma warning ( disable : 4127 )
+#pragma warning ( disable : 4512 )
+#endif
+
+#include <QObject>
+#include <QString>
+#include <QVariant>
+#include <QList>
+#include <QStringList>
+#include <QMetaType>
+#include <QAtomicInt>
+
+class cmake;
+
+/// struct to represent cmake properties in Qt
+/// Value is of type String or Bool
+struct QCMakeProperty
+{
+ enum PropertyType { BOOL, PATH, FILEPATH, STRING };
+ QString Key;
+ QVariant Value;
+ QStringList Strings;
+ QString Help;
+ PropertyType Type;
+ bool Advanced;
+ bool operator==(const QCMakeProperty& other) const
+ {
+ return this->Key == other.Key;
+ }
+ bool operator<(const QCMakeProperty& other) const
+ {
+ return this->Key < other.Key;
+ }
+};
+
+// list of properties
+typedef QList<QCMakeProperty> QCMakePropertyList;
+
+// allow QVariant to be a property or list of properties
+Q_DECLARE_METATYPE(QCMakeProperty)
+Q_DECLARE_METATYPE(QCMakePropertyList)
+
+/// Qt API for CMake library.
+/// Wrapper like class allows for easier integration with
+/// Qt features such as, signal/slot connections, multi-threading, etc..
+class QCMake : public QObject
+{
+ Q_OBJECT
+public:
+ QCMake(QObject* p=0);
+ ~QCMake();
+public slots:
+ /// load the cache file in a directory
+ void loadCache(const QString& dir);
+ /// set the source directory containing the source
+ void setSourceDirectory(const QString& dir);
+ /// set the binary directory to build in
+ void setBinaryDirectory(const QString& dir);
+ /// set the desired generator to use
+ void setGenerator(const QString& generator);
+ /// do the configure step
+ void configure();
+ /// generate the files
+ void generate();
+ /// set the property values
+ void setProperties(const QCMakePropertyList&);
+ /// interrupt the configure or generate process (if connecting, make a direct connection)
+ void interrupt();
+ /// delete the cache in binary directory
+ void deleteCache();
+ /// reload the cache in binary directory
+ void reloadCache();
+ /// set whether to do debug output
+ void setDebugOutput(bool);
+ /// set whether to do suppress dev warnings
+ void setSuppressDevWarnings(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
+ void setWarnUnusedMode(bool value);
+
+public:
+ /// get the list of cache properties
+ QCMakePropertyList properties() const;
+ /// get the current binary directory
+ QString binaryDirectory() const;
+ /// get the current source directory
+ QString sourceDirectory() const;
+ /// get the current generator
+ QString generator() const;
+ /// get the available generators
+ QStringList availableGenerators() const;
+ /// get whether to do debug output
+ bool getDebugOutput() const;
+
+signals:
+ /// signal when properties change (during read from disk or configure process)
+ void propertiesChanged(const QCMakePropertyList& vars);
+ /// signal when the generator changes
+ void generatorChanged(const QString& gen);
+ /// signal when the source directory changes (binary directory already
+ /// containing a CMakeCache.txt file)
+ void sourceDirChanged(const QString& dir);
+ /// signal when the binary directory changes
+ void binaryDirChanged(const QString& dir);
+ /// signal for progress events
+ void progressChanged(const QString& msg, float percent);
+ /// signal when configure is done
+ void configureDone(int error);
+ /// signal when generate is done
+ void generateDone(int error);
+ /// signal when there is an output message
+ void outputMessage(const QString& msg);
+ /// signal when there is an error message
+ void errorMessage(const QString& msg);
+ /// signal when debug output changes
+ void debugOutputChanged(bool);
+
+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;
+ bool WarnUninitializedMode;
+ bool WarnUnusedMode;
+ bool WarnUnusedAllMode;
+ QString SourceDirectory;
+ QString BinaryDirectory;
+ QString Generator;
+ QStringList AvailableGenerators;
+ QString CMakeExecutable;
+ QAtomicInt InterruptFlag;
+};
+
+#endif // __QCMake_h
+
diff --git a/Source/QtDialog/QCMakeCacheView.cxx b/Source/QtDialog/QCMakeCacheView.cxx
new file mode 100644
index 000000000..72e9b2464
--- /dev/null
+++ b/Source/QtDialog/QCMakeCacheView.cxx
@@ -0,0 +1,735 @@
+/*============================================================================
+ 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 "QCMakeCacheView.h"
+
+#include <QHBoxLayout>
+#include <QHeaderView>
+#include <QEvent>
+#include <QStyle>
+#include <QKeyEvent>
+#include <QSortFilterProxyModel>
+#include <QMetaProperty>
+#include <QApplication>
+
+#include "QCMakeWidgets.h"
+
+// filter for searches
+class QCMakeSearchFilter : public QSortFilterProxyModel
+{
+public:
+ QCMakeSearchFilter(QObject* o) : QSortFilterProxyModel(o) {}
+protected:
+ bool filterAcceptsRow(int row, const QModelIndex& p) const
+ {
+ QStringList strs;
+ const QAbstractItemModel* m = this->sourceModel();
+ QModelIndex idx = m->index(row, 0, p);
+
+ // if there are no children, get strings for column 0 and 1
+ if(!m->hasChildren(idx))
+ {
+ strs.append(m->data(idx).toString());
+ idx = m->index(row, 1, p);
+ strs.append(m->data(idx).toString());
+ }
+ else
+ {
+ // get strings for children entries to compare with
+ // instead of comparing with the parent
+ int num = m->rowCount(idx);
+ for(int i=0; i<num; i++)
+ {
+ QModelIndex tmpidx = m->index(i, 0, idx);
+ strs.append(m->data(tmpidx).toString());
+ tmpidx = m->index(i, 1, idx);
+ strs.append(m->data(tmpidx).toString());
+ }
+ }
+
+ // check all strings for a match
+ foreach(QString str, strs)
+ {
+ if(str.contains(this->filterRegExp()))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+};
+
+// filter for searches
+class QCMakeAdvancedFilter : public QSortFilterProxyModel
+{
+public:
+ QCMakeAdvancedFilter(QObject* o)
+ : QSortFilterProxyModel(o), ShowAdvanced(false) {}
+
+ void setShowAdvanced(bool f)
+ {
+ this->ShowAdvanced = f;
+ this->invalidate();
+ }
+ bool showAdvanced() const { return this->ShowAdvanced; }
+
+protected:
+
+ bool ShowAdvanced;
+
+ bool filterAcceptsRow(int row, const QModelIndex& p) const
+ {
+ const QAbstractItemModel* m = this->sourceModel();
+ QModelIndex idx = m->index(row, 0, p);
+
+ // if there are no children
+ if(!m->hasChildren(idx))
+ {
+ bool adv = m->data(idx, QCMakeCacheModel::AdvancedRole).toBool();
+ if(!adv || (adv && this->ShowAdvanced))
+ {
+ return true;
+ }
+ return false;
+ }
+
+ // check children
+ int num = m->rowCount(idx);
+ for(int i=0; i<num; i++)
+ {
+ bool accept = this->filterAcceptsRow(i, idx);
+ if(accept)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+};
+
+QCMakeCacheView::QCMakeCacheView(QWidget* p)
+ : QTreeView(p)
+{
+ // hook up our model and search/filter proxies
+ this->CacheModel = new QCMakeCacheModel(this);
+ this->AdvancedFilter = new QCMakeAdvancedFilter(this);
+ this->AdvancedFilter->setSourceModel(this->CacheModel);
+ this->AdvancedFilter->setDynamicSortFilter(true);
+ this->SearchFilter = new QCMakeSearchFilter(this);
+ this->SearchFilter->setSourceModel(this->AdvancedFilter);
+ this->SearchFilter->setFilterCaseSensitivity(Qt::CaseInsensitive);
+ this->SearchFilter->setDynamicSortFilter(true);
+ this->setModel(this->SearchFilter);
+
+ // our delegate for creating our editors
+ QCMakeCacheModelDelegate* delegate = new QCMakeCacheModelDelegate(this);
+ this->setItemDelegate(delegate);
+
+ this->setUniformRowHeights(true);
+
+ this->setEditTriggers(QAbstractItemView::AllEditTriggers);
+
+ // tab, backtab doesn't step through items
+ this->setTabKeyNavigation(false);
+
+ this->setRootIsDecorated(false);
+}
+
+bool QCMakeCacheView::event(QEvent* e)
+{
+ if(e->type() == QEvent::Show)
+ {
+ this->header()->setDefaultSectionSize(this->viewport()->width()/2);
+ }
+ return QTreeView::event(e);
+}
+
+QCMakeCacheModel* QCMakeCacheView::cacheModel() const
+{
+ return this->CacheModel;
+}
+
+QModelIndex QCMakeCacheView::moveCursor(CursorAction act,
+ Qt::KeyboardModifiers mod)
+{
+ // want home/end to go to begin/end of rows, not columns
+ if(act == MoveHome)
+ {
+ return this->model()->index(0, 1);
+ }
+ else if(act == MoveEnd)
+ {
+ return this->model()->index(this->model()->rowCount()-1, 1);
+ }
+ return QTreeView::moveCursor(act, mod);
+}
+
+void QCMakeCacheView::setShowAdvanced(bool s)
+{
+#if QT_VERSION >= 040300
+ // new 4.3 api that needs to be called. what about an older Qt?
+ this->SearchFilter->invalidate();
+#endif
+
+ this->AdvancedFilter->setShowAdvanced(s);
+}
+
+bool QCMakeCacheView::showAdvanced() const
+{
+ return this->AdvancedFilter->showAdvanced();
+}
+
+void QCMakeCacheView::setSearchFilter(const QString& s)
+{
+ this->SearchFilter->setFilterFixedString(s);
+}
+
+QCMakeCacheModel::QCMakeCacheModel(QObject* p)
+ : QStandardItemModel(p),
+ EditEnabled(true),
+ NewPropertyCount(0),
+ View(FlatView)
+{
+ this->ShowNewProperties = true;
+ QStringList labels;
+ labels << tr("Name") << tr("Value");
+ this->setHorizontalHeaderLabels(labels);
+}
+
+QCMakeCacheModel::~QCMakeCacheModel()
+{
+}
+
+static uint qHash(const QCMakeProperty& p)
+{
+ return qHash(p.Key);
+}
+
+void QCMakeCacheModel::setShowNewProperties(bool f)
+{
+ this->ShowNewProperties = f;
+}
+
+void QCMakeCacheModel::clear()
+{
+ this->QStandardItemModel::clear();
+ this->NewPropertyCount = 0;
+
+ QStringList labels;
+ labels << tr("Name") << tr("Value");
+ this->setHorizontalHeaderLabels(labels);
+}
+
+void QCMakeCacheModel::setProperties(const QCMakePropertyList& props)
+{
+ QSet<QCMakeProperty> newProps, newProps2;
+
+ if(this->ShowNewProperties)
+ {
+ newProps = props.toSet();
+ newProps2 = newProps;
+ QSet<QCMakeProperty> oldProps = this->properties().toSet();
+ oldProps.intersect(newProps);
+ newProps.subtract(oldProps);
+ newProps2.subtract(newProps);
+ }
+ else
+ {
+ newProps2 = props.toSet();
+ }
+
+ bool b = this->blockSignals(true);
+
+ this->clear();
+ this->NewPropertyCount = newProps.size();
+
+ if(View == FlatView)
+ {
+ QCMakePropertyList newP = newProps.toList();
+ QCMakePropertyList newP2 = newProps2.toList();
+ qSort(newP);
+ qSort(newP2);
+ int row_count = 0;
+ foreach(QCMakeProperty p, newP)
+ {
+ this->insertRow(row_count);
+ this->setPropertyData(this->index(row_count, 0), p, true);
+ row_count++;
+ }
+ foreach(QCMakeProperty p, newP2)
+ {
+ this->insertRow(row_count);
+ this->setPropertyData(this->index(row_count, 0), p, false);
+ row_count++;
+ }
+ }
+ else if(this->View == GroupView)
+ {
+ QMap<QString, QCMakePropertyList> newPropsTree;
+ this->breakProperties(newProps, newPropsTree);
+ QMap<QString, QCMakePropertyList> newPropsTree2;
+ this->breakProperties(newProps2, newPropsTree2);
+
+ QStandardItem* root = this->invisibleRootItem();
+
+ foreach(QString key, newPropsTree.keys())
+ {
+ QCMakePropertyList props2 = newPropsTree[key];
+
+ QList<QStandardItem*> parentItems;
+ parentItems.append(
+ new QStandardItem(key.isEmpty() ? tr("Ungrouped Entries") : key)
+ );
+ parentItems.append(new QStandardItem());
+ parentItems[0]->setData(QBrush(QColor(255,100,100)), Qt::BackgroundColorRole);
+ parentItems[1]->setData(QBrush(QColor(255,100,100)), Qt::BackgroundColorRole);
+ parentItems[0]->setData(1, GroupRole);
+ parentItems[1]->setData(1, GroupRole);
+ root->appendRow(parentItems);
+
+ int num = props2.size();
+ for(int i=0; i<num; i++)
+ {
+ QCMakeProperty prop = props2[i];
+ QList<QStandardItem*> items;
+ items.append(new QStandardItem());
+ items.append(new QStandardItem());
+ parentItems[0]->appendRow(items);
+ this->setPropertyData(this->indexFromItem(items[0]), prop, true);
+ }
+ }
+
+ foreach(QString key, newPropsTree2.keys())
+ {
+ QCMakePropertyList props2 = newPropsTree2[key];
+
+ QStandardItem* parentItem =
+ new QStandardItem(key.isEmpty() ? tr("Ungrouped Entries") : key);
+ root->appendRow(parentItem);
+ parentItem->setData(1, GroupRole);
+
+ int num = props2.size();
+ for(int i=0; i<num; i++)
+ {
+ QCMakeProperty prop = props2[i];
+ QList<QStandardItem*> items;
+ items.append(new QStandardItem());
+ items.append(new QStandardItem());
+ parentItem->appendRow(items);
+ this->setPropertyData(this->indexFromItem(items[0]), prop, false);
+ }
+ }
+ }
+
+ this->blockSignals(b);
+ this->reset();
+}
+
+QCMakeCacheModel::ViewType QCMakeCacheModel::viewType() const
+{
+ return this->View;
+}
+
+void QCMakeCacheModel::setViewType(QCMakeCacheModel::ViewType t)
+{
+ this->View = t;
+
+ QCMakePropertyList props = this->properties();
+ QCMakePropertyList oldProps;
+ int numNew = this->NewPropertyCount;
+ int numTotal = props.count();
+ for(int i=numNew; i<numTotal; i++)
+ {
+ oldProps.append(props[i]);
+ }
+
+ bool b = this->blockSignals(true);
+ this->clear();
+ this->setProperties(oldProps);
+ this->setProperties(props);
+ this->blockSignals(b);
+ this->reset();
+}
+
+void QCMakeCacheModel::setPropertyData(const QModelIndex& idx1,
+ const QCMakeProperty& prop, bool isNew)
+{
+ QModelIndex idx2 = idx1.sibling(idx1.row(), 1);
+
+ this->setData(idx1, prop.Key, Qt::DisplayRole);
+ this->setData(idx1, prop.Help, QCMakeCacheModel::HelpRole);
+ this->setData(idx1, prop.Type, QCMakeCacheModel::TypeRole);
+ this->setData(idx1, prop.Advanced, QCMakeCacheModel::AdvancedRole);
+
+ if(prop.Type == QCMakeProperty::BOOL)
+ {
+ int check = prop.Value.toBool() ? Qt::Checked : Qt::Unchecked;
+ this->setData(idx2, check, Qt::CheckStateRole);
+ }
+ else
+ {
+ this->setData(idx2, prop.Value, Qt::DisplayRole);
+ }
+ this->setData(idx2, prop.Help, QCMakeCacheModel::HelpRole);
+
+ if (!prop.Strings.isEmpty())
+ {
+ this->setData(idx1, prop.Strings, QCMakeCacheModel::StringsRole);
+ }
+
+ if(isNew)
+ {
+ this->setData(idx1, QBrush(QColor(255,100,100)), Qt::BackgroundColorRole);
+ this->setData(idx2, QBrush(QColor(255,100,100)), Qt::BackgroundColorRole);
+ }
+}
+
+void QCMakeCacheModel::getPropertyData(const QModelIndex& idx1,
+ QCMakeProperty& prop) const
+{
+ QModelIndex idx2 = idx1.sibling(idx1.row(), 1);
+
+ prop.Key = this->data(idx1, Qt::DisplayRole).toString();
+ prop.Help = this->data(idx1, HelpRole).toString();
+ prop.Type = static_cast<QCMakeProperty::PropertyType>(this->data(idx1, TypeRole).toInt());
+ prop.Advanced = this->data(idx1, AdvancedRole).toBool();
+ prop.Strings = this->data(idx1, QCMakeCacheModel::StringsRole).toStringList();
+ if(prop.Type == QCMakeProperty::BOOL)
+ {
+ int check = this->data(idx2, Qt::CheckStateRole).toInt();
+ prop.Value = check == Qt::Checked;
+ }
+ else
+ {
+ prop.Value = this->data(idx2, Qt::DisplayRole).toString();
+ }
+}
+
+QString QCMakeCacheModel::prefix(const QString& s)
+{
+ QString prefix = s.section('_', 0, 0);
+ if(prefix == s)
+ {
+ prefix = QString();
+ }
+ return prefix;
+}
+
+void QCMakeCacheModel::breakProperties(const QSet<QCMakeProperty>& props,
+ QMap<QString, QCMakePropertyList>& result)
+{
+ QMap<QString, QCMakePropertyList> tmp;
+ // return a map of properties grouped by prefixes, and sorted
+ foreach(QCMakeProperty p, props)
+ {
+ QString prefix = QCMakeCacheModel::prefix(p.Key);
+ tmp[prefix].append(p);
+ }
+ // sort it and re-org any properties with only one sub item
+ QCMakePropertyList reorgProps;
+ QMap<QString, QCMakePropertyList>::iterator iter;
+ for(iter = tmp.begin(); iter != tmp.end();)
+ {
+ if(iter->count() == 1)
+ {
+ reorgProps.append((*iter)[0]);
+ iter = tmp.erase(iter);
+ }
+ else
+ {
+ qSort(*iter);
+ ++iter;
+ }
+ }
+ if(reorgProps.count())
+ {
+ tmp[QString()] += reorgProps;
+ }
+ result = tmp;
+}
+
+QCMakePropertyList QCMakeCacheModel::properties() const
+{
+ QCMakePropertyList props;
+
+ if(!this->rowCount())
+ {
+ return props;
+ }
+
+ QList<QModelIndex> idxs;
+ idxs.append(this->index(0,0));
+
+ // walk the entire model for property entries
+ // this works regardless of a flat view or a tree view
+ while(!idxs.isEmpty())
+ {
+ QModelIndex idx = idxs.last();
+ if(this->hasChildren(idx) && this->rowCount(idx))
+ {
+ idxs.append(this->index(0,0, idx));
+ }
+ else
+ {
+ if(!data(idx, GroupRole).toInt())
+ {
+ // get data
+ QCMakeProperty prop;
+ this->getPropertyData(idx, prop);
+ props.append(prop);
+ }
+
+ // go to the next in the tree
+ while(!idxs.isEmpty() && !idxs.last().sibling(idxs.last().row()+1, 0).isValid())
+ {
+ idxs.removeLast();
+ }
+ if(!idxs.isEmpty())
+ {
+ idxs.last() = idxs.last().sibling(idxs.last().row()+1, 0);
+ }
+ }
+ }
+
+ return props;
+}
+
+bool QCMakeCacheModel::insertProperty(QCMakeProperty::PropertyType t,
+ const QString& name, const QString& description,
+ const QVariant& value, bool advanced)
+{
+ QCMakeProperty prop;
+ prop.Key = name;
+ prop.Value = value;
+ prop.Help = description;
+ prop.Type = t;
+ prop.Advanced = advanced;
+
+ //insert at beginning
+ this->insertRow(0);
+ this->setPropertyData(this->index(0,0), prop, true);
+ this->NewPropertyCount++;
+ return true;
+}
+
+void QCMakeCacheModel::setEditEnabled(bool e)
+{
+ this->EditEnabled = e;
+}
+
+bool QCMakeCacheModel::editEnabled() const
+{
+ return this->EditEnabled;
+}
+
+int QCMakeCacheModel::newPropertyCount() const
+{
+ return this->NewPropertyCount;
+}
+
+Qt::ItemFlags QCMakeCacheModel::flags (const QModelIndex& idx) const
+{
+ Qt::ItemFlags f = QStandardItemModel::flags(idx);
+ if(!this->EditEnabled)
+ {
+ f &= ~Qt::ItemIsEditable;
+ return f;
+ }
+ if(QCMakeProperty::BOOL == this->data(idx, TypeRole).toInt())
+ {
+ f |= Qt::ItemIsUserCheckable;
+ }
+ return f;
+}
+
+QModelIndex QCMakeCacheModel::buddy(const QModelIndex& idx) const
+{
+ if(!this->hasChildren(idx) &&
+ this->data(idx, TypeRole).toInt() != QCMakeProperty::BOOL)
+ {
+ return this->index(idx.row(), 1, idx.parent());
+ }
+ return idx;
+}
+
+QCMakeCacheModelDelegate::QCMakeCacheModelDelegate(QObject* p)
+ : QItemDelegate(p), FileDialogFlag(false)
+{
+}
+
+void QCMakeCacheModelDelegate::setFileDialogFlag(bool f)
+{
+ this->FileDialogFlag = f;
+}
+
+QWidget* QCMakeCacheModelDelegate::createEditor(QWidget* p,
+ const QStyleOptionViewItem&, const QModelIndex& idx) const
+{
+ QModelIndex var = idx.sibling(idx.row(), 0);
+ int type = var.data(QCMakeCacheModel::TypeRole).toInt();
+ if(type == QCMakeProperty::BOOL)
+ {
+ return NULL;
+ }
+ else if(type == QCMakeProperty::PATH)
+ {
+ QCMakePathEditor* editor =
+ new QCMakePathEditor(p,
+ var.data(Qt::DisplayRole).toString());
+ QObject::connect(editor, SIGNAL(fileDialogExists(bool)), this,
+ SLOT(setFileDialogFlag(bool)));
+ return editor;
+ }
+ else if(type == QCMakeProperty::FILEPATH)
+ {
+ QCMakeFilePathEditor* editor =
+ new QCMakeFilePathEditor(p,
+ var.data(Qt::DisplayRole).toString());
+ QObject::connect(editor, SIGNAL(fileDialogExists(bool)), this,
+ SLOT(setFileDialogFlag(bool)));
+ return editor;
+ }
+ else if(type == QCMakeProperty::STRING &&
+ var.data(QCMakeCacheModel::StringsRole).isValid())
+ {
+ QCMakeComboBox* editor =
+ new QCMakeComboBox(p, var.data(QCMakeCacheModel::StringsRole).toStringList());
+ editor->setFrame(false);
+ return editor;
+ }
+
+ QLineEdit* editor = new QLineEdit(p);
+ editor->setFrame(false);
+ return editor;
+}
+
+bool QCMakeCacheModelDelegate::editorEvent(QEvent* e, QAbstractItemModel* model,
+ const QStyleOptionViewItem& option, const QModelIndex& index)
+{
+ Qt::ItemFlags flags = model->flags(index);
+ if (!(flags & Qt::ItemIsUserCheckable) || !(option.state & QStyle::State_Enabled)
+ || !(flags & Qt::ItemIsEnabled))
+ {
+ return false;
+ }
+
+ QVariant value = index.data(Qt::CheckStateRole);
+ if (!value.isValid())
+ {
+ return false;
+ }
+
+ if ((e->type() == QEvent::MouseButtonRelease)
+ || (e->type() == QEvent::MouseButtonDblClick))
+ {
+ // eat the double click events inside the check rect
+ if (e->type() == QEvent::MouseButtonDblClick)
+ {
+ return true;
+ }
+ }
+ else if (e->type() == QEvent::KeyPress)
+ {
+ if(static_cast<QKeyEvent*>(e)->key() != Qt::Key_Space &&
+ static_cast<QKeyEvent*>(e)->key() != Qt::Key_Select)
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+
+ Qt::CheckState state = (static_cast<Qt::CheckState>(value.toInt()) == Qt::Checked
+ ? Qt::Unchecked : Qt::Checked);
+ bool success = model->setData(index, state, Qt::CheckStateRole);
+ if(success)
+ {
+ this->recordChange(model, index);
+ }
+ return success;
+}
+
+// Issue 205903 fixed in Qt 4.5.0.
+// Can remove this function and FileDialogFlag when minimum Qt version is 4.5
+bool QCMakeCacheModelDelegate::eventFilter(QObject* object, QEvent* evt)
+{
+ // workaround for what looks like a bug in Qt on Mac OS X
+ // where it doesn't create a QWidget wrapper for the native file dialog
+ // so the Qt library ends up assuming the focus was lost to something else
+
+ if(evt->type() == QEvent::FocusOut && this->FileDialogFlag)
+ {
+ return false;
+ }
+ return QItemDelegate::eventFilter(object, evt);
+}
+
+void QCMakeCacheModelDelegate::setModelData(QWidget* editor,
+ QAbstractItemModel* model, const QModelIndex& index ) const
+{
+ QItemDelegate::setModelData(editor, model, index);
+ const_cast<QCMakeCacheModelDelegate*>(this)->recordChange(model, index);
+}
+
+QSize QCMakeCacheModelDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
+{
+ QSize sz = QItemDelegate::sizeHint(option, index);
+ QStyle *style = QApplication::style();
+
+ // increase to checkbox size
+ QStyleOptionButton opt;
+ opt.QStyleOption::operator=(option);
+ sz = sz.expandedTo(style->subElementRect(QStyle::SE_ViewItemCheckIndicator, &opt, NULL).size());
+
+ return sz;
+}
+
+QSet<QCMakeProperty> QCMakeCacheModelDelegate::changes() const
+{
+ return mChanges;
+}
+
+void QCMakeCacheModelDelegate::clearChanges()
+{
+ mChanges.clear();
+}
+
+void QCMakeCacheModelDelegate::recordChange(QAbstractItemModel* model, const QModelIndex& index)
+{
+ QModelIndex idx = index;
+ QAbstractItemModel* mymodel = model;
+ while(qobject_cast<QAbstractProxyModel*>(mymodel))
+ {
+ idx = static_cast<QAbstractProxyModel*>(mymodel)->mapToSource(idx);
+ mymodel = static_cast<QAbstractProxyModel*>(mymodel)->sourceModel();
+ }
+ QCMakeCacheModel* cache_model = qobject_cast<QCMakeCacheModel*>(mymodel);
+ if(cache_model && idx.isValid())
+ {
+ QCMakeProperty prop;
+ idx = idx.sibling(idx.row(), 0);
+ cache_model->getPropertyData(idx, prop);
+
+ // clean out an old one
+ QSet<QCMakeProperty>::iterator iter = mChanges.find(prop);
+ if(iter != mChanges.end())
+ {
+ mChanges.erase(iter);
+ }
+ // now add the new item
+ mChanges.insert(prop);
+ }
+}
+
diff --git a/Source/QtDialog/QCMakeCacheView.h b/Source/QtDialog/QCMakeCacheView.h
new file mode 100644
index 000000000..0a628b90a
--- /dev/null
+++ b/Source/QtDialog/QCMakeCacheView.h
@@ -0,0 +1,172 @@
+/*============================================================================
+ 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 QCMakeCacheView_h
+#define QCMakeCacheView_h
+
+#include "QCMake.h"
+#include <QTreeView>
+#include <QSet>
+#include <QStandardItemModel>
+#include <QItemDelegate>
+
+class QSortFilterProxyModel;
+class QCMakeCacheModel;
+class QCMakeAdvancedFilter;
+
+/// Qt view class for cache properties
+class QCMakeCacheView : public QTreeView
+{
+ Q_OBJECT
+public:
+ QCMakeCacheView(QWidget* p);
+
+ // retrieve the QCMakeCacheModel storing all the pointers
+ // this isn't necessarily the model one would get from model()
+ QCMakeCacheModel* cacheModel() const;
+
+ // get whether to show advanced entries
+ bool showAdvanced() const;
+
+ QSize sizeHint() const { return QSize(200,200); }
+
+public slots:
+ // set whether to show advanced entries
+ void setShowAdvanced(bool);
+ // set the search filter string. any property key or value not matching will
+ // be filtered out
+ void setSearchFilter(const QString&);
+
+protected:
+ QModelIndex moveCursor(CursorAction, Qt::KeyboardModifiers);
+ bool event(QEvent* e);
+ QCMakeCacheModel* CacheModel;
+ QCMakeAdvancedFilter* AdvancedFilter;
+ QSortFilterProxyModel* SearchFilter;
+};
+
+/// Qt model class for cache properties
+class QCMakeCacheModel : public QStandardItemModel
+{
+ Q_OBJECT
+public:
+ QCMakeCacheModel(QObject* parent);
+ ~QCMakeCacheModel();
+
+ // roles used to retrieve extra data such has help strings, types of
+ // properties, and the advanced flag
+ enum { HelpRole = Qt::ToolTipRole,
+ TypeRole = Qt::UserRole,
+ AdvancedRole,
+ StringsRole,
+ GroupRole
+ };
+
+ enum ViewType { FlatView, GroupView };
+
+public slots:
+ // set a list of properties. This list will be sorted and grouped according
+ // to prefix. Any property that existed already and which is found in this
+ // list of properties to set will become an old property. All others will
+ // become new properties and be marked red.
+ void setProperties(const QCMakePropertyList& props);
+
+ // set whether to show new properties in red
+ void setShowNewProperties(bool);
+
+ // clear everything from the model
+ void clear();
+
+ // set flag whether the model can currently be edited.
+ void setEditEnabled(bool);
+
+ // insert a new property at a row specifying all the information about the
+ // property
+ bool insertProperty(QCMakeProperty::PropertyType t,
+ const QString& name, const QString& description,
+ const QVariant& value, bool advanced);
+
+ // set the view type
+ void setViewType(ViewType t);
+ ViewType viewType() const;
+
+public:
+ // get the properties
+ QCMakePropertyList properties() const;
+
+ // editing enabled
+ bool editEnabled() const;
+
+ // returns how many new properties there are
+ int newPropertyCount() const;
+
+ // return flags (overloaded to modify flag based on EditEnabled flag)
+ Qt::ItemFlags flags (const QModelIndex& index) const;
+ QModelIndex buddy(const QModelIndex& idx) const;
+
+ // get the data in the model for this property
+ void getPropertyData(const QModelIndex& idx1,
+ QCMakeProperty& prop) const;
+
+protected:
+ bool EditEnabled;
+ int NewPropertyCount;
+ bool ShowNewProperties;
+ ViewType View;
+
+ // set the data in the model for this property
+ void setPropertyData(const QModelIndex& idx1,
+ const QCMakeProperty& p, bool isNew);
+
+ // breaks up he property list into groups
+ // where each group has the same prefix up to the first underscore
+ static void breakProperties(const QSet<QCMakeProperty>& props,
+ QMap<QString, QCMakePropertyList>& result);
+
+ // gets the prefix of a string up to the first _
+ static QString prefix(const QString& s);
+
+};
+
+/// Qt delegate class for interaction (or other customization)
+/// with cache properties
+class QCMakeCacheModelDelegate : public QItemDelegate
+{
+ Q_OBJECT
+public:
+ QCMakeCacheModelDelegate(QObject* p);
+ /// create our own editors for cache properties
+ QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option,
+ const QModelIndex& index ) const;
+ bool editorEvent (QEvent* event, QAbstractItemModel* model,
+ const QStyleOptionViewItem& option, const QModelIndex& index);
+ bool eventFilter(QObject* object, QEvent* event);
+ void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index ) const;
+ QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;
+
+ QSet<QCMakeProperty> changes() const;
+ void clearChanges();
+
+protected slots:
+ void setFileDialogFlag(bool);
+protected:
+ bool FileDialogFlag;
+ // record a change to an item in the model.
+ // this simply saves the item in the set of changes
+ void recordChange(QAbstractItemModel* model, const QModelIndex& index);
+
+ // properties changed by user via this delegate
+ QSet<QCMakeProperty> mChanges;
+};
+
+#endif
+
diff --git a/Source/QtDialog/QCMakeWidgets.cxx b/Source/QtDialog/QCMakeWidgets.cxx
new file mode 100644
index 000000000..144e1f32e
--- /dev/null
+++ b/Source/QtDialog/QCMakeWidgets.cxx
@@ -0,0 +1,134 @@
+/*============================================================================
+ 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 "QCMakeWidgets.h"
+
+#include <QDirModel>
+#include <QFileInfo>
+#include <QFileDialog>
+#include <QToolButton>
+#include <QResizeEvent>
+
+QCMakeFileEditor::QCMakeFileEditor(QWidget* p, const QString& var)
+ : QLineEdit(p), Variable(var)
+{
+ this->ToolButton = new QToolButton(this);
+ this->ToolButton->setText("...");
+ this->ToolButton->setCursor(QCursor(Qt::ArrowCursor));
+ QObject::connect(this->ToolButton, SIGNAL(clicked(bool)),
+ this, SLOT(chooseFile()));
+}
+
+QCMakeFilePathEditor::QCMakeFilePathEditor(QWidget* p, const QString& var)
+ : QCMakeFileEditor(p, var)
+{
+ this->setCompleter(new QCMakeFileCompleter(this, false));
+}
+
+QCMakePathEditor::QCMakePathEditor(QWidget* p, const QString& var)
+ : QCMakeFileEditor(p, var)
+{
+ this->setCompleter(new QCMakeFileCompleter(this, true));
+}
+
+void QCMakeFileEditor::resizeEvent(QResizeEvent* e)
+{
+ // make the tool button fit on the right side
+ int h = e->size().height();
+ // move the line edit to make room for the tool button
+ this->setContentsMargins(0, 0, h, 0);
+ // put the tool button in its place
+ this->ToolButton->resize(h, h);
+ this->ToolButton->move(this->width() - h, 0);
+}
+
+void QCMakeFilePathEditor::chooseFile()
+{
+ // choose a file and set it
+ QString path;
+ QFileInfo info(this->text());
+ QString title;
+ if(this->Variable.isEmpty())
+ {
+ title = tr("Select File");
+ }
+ else
+ {
+ title = tr("Select File for %1");
+ title = title.arg(this->Variable);
+ }
+ this->fileDialogExists(true);
+ path = QFileDialog::getOpenFileName(this, title, info.absolutePath());
+ this->fileDialogExists(false);
+
+ if(!path.isEmpty())
+ {
+ this->setText(QDir::fromNativeSeparators(path));
+ }
+}
+
+void QCMakePathEditor::chooseFile()
+{
+ // choose a file and set it
+ QString path;
+ QString title;
+ if(this->Variable.isEmpty())
+ {
+ title = tr("Select Path");
+ }
+ else
+ {
+ title = tr("Select Path for %1");
+ title = title.arg(this->Variable);
+ }
+ this->fileDialogExists(true);
+ path = QFileDialog::getExistingDirectory(this, title, this->text());
+ this->fileDialogExists(false);
+ if(!path.isEmpty())
+ {
+ this->setText(QDir::fromNativeSeparators(path));
+ }
+}
+
+// use same QDirModel for all completers
+static QDirModel* fileDirModel()
+{
+ static QDirModel* m = NULL;
+ if(!m)
+ {
+ m = new QDirModel();
+ }
+ return m;
+}
+static QDirModel* pathDirModel()
+{
+ static QDirModel* m = NULL;
+ if(!m)
+ {
+ m = new QDirModel();
+ m->setFilter(QDir::AllDirs | QDir::Drives | QDir::NoDotAndDotDot);
+ }
+ return m;
+}
+
+QCMakeFileCompleter::QCMakeFileCompleter(QObject* o, bool dirs)
+ : QCompleter(o)
+{
+ QDirModel* m = dirs ? pathDirModel() : fileDirModel();
+ this->setModel(m);
+}
+
+QString QCMakeFileCompleter::pathFromIndex(const QModelIndex& idx) const
+{
+ return QDir::fromNativeSeparators(QCompleter::pathFromIndex(idx));
+}
+
diff --git a/Source/QtDialog/QCMakeWidgets.h b/Source/QtDialog/QCMakeWidgets.h
new file mode 100644
index 000000000..8f58df2bb
--- /dev/null
+++ b/Source/QtDialog/QCMakeWidgets.h
@@ -0,0 +1,87 @@
+/*============================================================================
+ 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 QCMakeWidgets_h
+#define QCMakeWidgets_h
+
+#include <QLineEdit>
+#include <QComboBox>
+#include <QCompleter>
+class QToolButton;
+
+// common widgets for Qt based CMake
+
+/// Editor widget for editing paths or file paths
+class QCMakeFileEditor : public QLineEdit
+{
+ Q_OBJECT
+public:
+ QCMakeFileEditor(QWidget* p, const QString& var);
+protected slots:
+ virtual void chooseFile() = 0;
+signals:
+ void fileDialogExists(bool);
+protected:
+ void resizeEvent(QResizeEvent* e);
+ QToolButton* ToolButton;
+ QString Variable;
+};
+
+/// editor widget for editing files
+class QCMakePathEditor : public QCMakeFileEditor
+{
+ Q_OBJECT
+public:
+ QCMakePathEditor(QWidget* p = NULL, const QString& var = QString());
+ void chooseFile();
+};
+
+/// editor widget for editing paths
+class QCMakeFilePathEditor : public QCMakeFileEditor
+{
+ Q_OBJECT
+public:
+ QCMakeFilePathEditor(QWidget* p = NULL, const QString& var = QString());
+ void chooseFile();
+};
+
+/// completer class that returns native cmake paths
+class QCMakeFileCompleter : public QCompleter
+{
+ Q_OBJECT
+public:
+ QCMakeFileCompleter(QObject* o, bool dirs);
+ virtual QString pathFromIndex(const QModelIndex& idx) const;
+};
+
+// editor for strings
+class QCMakeComboBox : public QComboBox
+{
+ Q_OBJECT
+ Q_PROPERTY(QString value READ currentText WRITE setValue USER true);
+public:
+ QCMakeComboBox(QWidget* p, QStringList strings) : QComboBox(p)
+ {
+ this->addItems(strings);
+ }
+ void setValue(const QString& v)
+ {
+ int i = this->findText(v);
+ if(i != -1)
+ {
+ this->setCurrentIndex(i);
+ }
+ }
+};
+
+#endif
+
diff --git a/Source/QtDialog/QMacInstallDialog.cxx b/Source/QtDialog/QMacInstallDialog.cxx
new file mode 100644
index 000000000..6eb053b21
--- /dev/null
+++ b/Source/QtDialog/QMacInstallDialog.cxx
@@ -0,0 +1,121 @@
+#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
new file mode 100644
index 000000000..efe67dfaf
--- /dev/null
+++ b/Source/QtDialog/QMacInstallDialog.h
@@ -0,0 +1,20 @@
+#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
new file mode 100644
index 000000000..701991b7a
--- /dev/null
+++ b/Source/QtDialog/QtDialogCPack.cmake.in
@@ -0,0 +1,18 @@
+SET(IS_APPLE @APPLE@)
+SET(CMAKE_PACKAGE_QTGUI @CMAKE_PACKAGE_QTGUI@)
+
+IF(CMAKE_PACKAGE_QTGUI)
+ SET(CPACK_PACKAGE_EXECUTABLES "cmake-gui" "CMake (cmake-gui)" ${CPACK_PACKAGE_EXECUTABLES})
+ SET(CPACK_CREATE_DESKTOP_LINKS "cmake-gui" ${CPACK_CREATE_DESKTOP_LINKS})
+ IF(IS_APPLE)
+ # for apple install we set the install prefix to
+ # / 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(IS_APPLE)
+ENDIF(CMAKE_PACKAGE_QTGUI)
+
+
diff --git a/Source/QtDialog/cmakecache.xml b/Source/QtDialog/cmakecache.xml
new file mode 100644
index 000000000..a13b5b19c
--- /dev/null
+++ b/Source/QtDialog/cmakecache.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
+ <mime-type type="application/x-cmakecache">
+ <comment>CMake cache file</comment>
+ <glob pattern="CMakeCache.txt"/>
+ <sub-class-of type="text/plain"/>
+ </mime-type>
+</mime-info>
diff --git a/Source/QtDialog/postflight.sh.in b/Source/QtDialog/postflight.sh.in
new file mode 100755
index 000000000..33be35206
--- /dev/null
+++ b/Source/QtDialog/postflight.sh.in
@@ -0,0 +1,3 @@
+#!/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
new file mode 100755
index 000000000..06bd98656
--- /dev/null
+++ b/Source/QtDialog/postupgrade.sh.in
@@ -0,0 +1,2 @@
+#!/bin/bash
+exit 0
diff --git a/Source/cmAddCustomCommandCommand.cxx b/Source/cmAddCustomCommandCommand.cxx
new file mode 100644
index 000000000..56348494d
--- /dev/null
+++ b/Source/cmAddCustomCommandCommand.cxx
@@ -0,0 +1,387 @@
+/*============================================================================
+ 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 "cmAddCustomCommandCommand.h"
+
+#include "cmTarget.h"
+
+#include "cmSourceFile.h"
+
+// cmAddCustomCommandCommand
+bool cmAddCustomCommandCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ /* Let's complain at the end of this function about the lack of a particular
+ arg. For the moment, let's say that COMMAND, and either TARGET or SOURCE
+ are required.
+ */
+ if (args.size() < 4)
+ {
+ this->SetError("called with wrong number of arguments.");
+ return false;
+ }
+
+ std::string source, target, main_dependency, working;
+ std::string comment_buffer;
+ const char* comment = 0;
+ std::vector<std::string> depends, outputs, output;
+ bool verbatim = false;
+ bool append = false;
+ std::string implicit_depends_lang;
+ cmCustomCommand::ImplicitDependsList implicit_depends;
+
+ // Accumulate one command line at a time.
+ cmCustomCommandLine currentLine;
+
+ // Save all command lines.
+ cmCustomCommandLines commandLines;
+
+ cmTarget::CustomCommandType cctype = cmTarget::POST_BUILD;
+
+ enum tdoing {
+ doing_source,
+ doing_command,
+ doing_target,
+ doing_depends,
+ doing_implicit_depends_lang,
+ doing_implicit_depends_file,
+ doing_main_dependency,
+ doing_output,
+ doing_outputs,
+ doing_comment,
+ doing_working_directory,
+ doing_nothing
+ };
+
+ tdoing doing = doing_nothing;
+
+ for (unsigned int j = 0; j < args.size(); ++j)
+ {
+ std::string const& copy = args[j];
+
+ if(copy == "SOURCE")
+ {
+ doing = doing_source;
+ }
+ else if(copy == "COMMAND")
+ {
+ doing = doing_command;
+
+ // Save the current command before starting the next command.
+ if(!currentLine.empty())
+ {
+ commandLines.push_back(currentLine);
+ currentLine.clear();
+ }
+ }
+ else if(copy == "PRE_BUILD")
+ {
+ cctype = cmTarget::PRE_BUILD;
+ }
+ else if(copy == "PRE_LINK")
+ {
+ cctype = cmTarget::PRE_LINK;
+ }
+ else if(copy == "POST_BUILD")
+ {
+ cctype = cmTarget::POST_BUILD;
+ }
+ else if(copy == "VERBATIM")
+ {
+ verbatim = true;
+ }
+ else if(copy == "APPEND")
+ {
+ append = true;
+ }
+ else if(copy == "TARGET")
+ {
+ doing = doing_target;
+ }
+ else if(copy == "ARGS")
+ {
+ // Ignore this old keyword.
+ }
+ else if (copy == "DEPENDS")
+ {
+ doing = doing_depends;
+ }
+ else if (copy == "OUTPUTS")
+ {
+ doing = doing_outputs;
+ }
+ else if (copy == "OUTPUT")
+ {
+ doing = doing_output;
+ }
+ else if (copy == "WORKING_DIRECTORY")
+ {
+ doing = doing_working_directory;
+ }
+ else if (copy == "MAIN_DEPENDENCY")
+ {
+ doing = doing_main_dependency;
+ }
+ else if (copy == "IMPLICIT_DEPENDS")
+ {
+ doing = doing_implicit_depends_lang;
+ }
+ else if (copy == "COMMENT")
+ {
+ doing = doing_comment;
+ }
+ else
+ {
+ std::string filename;
+ switch (doing)
+ {
+ case doing_output:
+ case doing_outputs:
+ if (!cmSystemTools::FileIsFullPath(copy.c_str()))
+ {
+ // This is an output to be generated, so it should be
+ // under the build tree. CMake 2.4 placed this under the
+ // source tree. However the only case that this change
+ // will break is when someone writes
+ //
+ // add_custom_command(OUTPUT out.txt ...)
+ //
+ // 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 += "/";
+ }
+ filename += copy;
+ cmSystemTools::ConvertToUnixSlashes(filename);
+ break;
+ case doing_source:
+ // We do not want to convert the argument to SOURCE because
+ // that option is only available for backward compatibility.
+ // Old-style use of this command may use the SOURCE==TARGET
+ // trick which we must preserve. If we convert the source
+ // to a full path then it will no longer equal the target.
+ default:
+ break;
+ }
+
+ switch (doing)
+ {
+ case doing_working_directory:
+ working = copy;
+ break;
+ case doing_source:
+ source = copy;
+ break;
+ case doing_output:
+ output.push_back(filename);
+ break;
+ case doing_main_dependency:
+ main_dependency = copy;
+ break;
+ case doing_implicit_depends_lang:
+ implicit_depends_lang = copy;
+ doing = doing_implicit_depends_file;
+ break;
+ case doing_implicit_depends_file:
+ {
+ // An implicit dependency starting point is also an
+ // explicit dependency.
+ std::string dep = copy;
+ cmSystemTools::ConvertToUnixSlashes(dep);
+ depends.push_back(dep);
+
+ // Add the implicit dependency language and file.
+ cmCustomCommand::ImplicitDependsPair
+ entry(implicit_depends_lang, dep);
+ implicit_depends.push_back(entry);
+
+ // Switch back to looking for a language.
+ doing = doing_implicit_depends_lang;
+ }
+ break;
+ case doing_command:
+ currentLine.push_back(copy);
+ break;
+ case doing_target:
+ target = copy;
+ break;
+ case doing_depends:
+ {
+ std::string dep = copy;
+ cmSystemTools::ConvertToUnixSlashes(dep);
+ depends.push_back(dep);
+ }
+ break;
+ case doing_outputs:
+ outputs.push_back(filename);
+ break;
+ case doing_comment:
+ comment_buffer = copy;
+ comment = comment_buffer.c_str();
+ break;
+ default:
+ this->SetError("Wrong syntax. Unknown type of argument.");
+ return false;
+ }
+ }
+ }
+
+ // Store the last command line finished.
+ if(!currentLine.empty())
+ {
+ commandLines.push_back(currentLine);
+ currentLine.clear();
+ }
+
+ // At this point we could complain about the lack of arguments. For
+ // the moment, let's say that COMMAND, TARGET are always required.
+ if(output.empty() && target.empty())
+ {
+ this->SetError("Wrong syntax. A TARGET or OUTPUT must be specified.");
+ return false;
+ }
+
+ if(source.empty() && !target.empty() && !output.empty())
+ {
+ this->SetError(
+ "Wrong syntax. A TARGET and OUTPUT can not both be specified.");
+ return false;
+ }
+ if(append && output.empty())
+ {
+ this->SetError("given APPEND option with no OUTPUT.");
+ return false;
+ }
+
+ // Make sure the output names and locations are safe.
+ if(!this->CheckOutputs(output) || !this->CheckOutputs(outputs))
+ {
+ return false;
+ }
+
+ // Check for an append request.
+ if(append)
+ {
+ // Lookup an existing command.
+ if(cmSourceFile* sf =
+ this->Makefile->GetSourceFileWithOutput(output[0].c_str()))
+ {
+ if(cmCustomCommand* cc = sf->GetCustomCommand())
+ {
+ cc->AppendCommands(commandLines);
+ cc->AppendDepends(depends);
+ cc->AppendImplicitDepends(implicit_depends);
+ return true;
+ }
+ }
+
+ // No command for this output exists.
+ cmOStringStream e;
+ e << "given APPEND option with output \"" << output[0].c_str()
+ << "\" which is not already a custom command output.";
+ this->SetError(e.str().c_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);
+ }
+
+ // Choose which mode of the command to use.
+ bool escapeOldStyle = !verbatim;
+ if(source.empty() && output.empty())
+ {
+ // Source is empty, use the target.
+ std::vector<std::string> no_depends;
+ this->Makefile->AddCustomCommandToTarget(target.c_str(), no_depends,
+ commandLines, cctype,
+ comment, working.c_str(),
+ escapeOldStyle);
+ }
+ else if(target.empty())
+ {
+ // Target is empty, use the output.
+ this->Makefile->AddCustomCommandToOutput(output, depends,
+ main_dependency.c_str(),
+ commandLines, comment,
+ working.c_str(), false,
+ escapeOldStyle);
+
+ // 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()))
+ {
+ if(cmCustomCommand* cc = sf->GetCustomCommand())
+ {
+ okay = true;
+ cc->SetImplicitDepends(implicit_depends);
+ }
+ }
+ if(!okay)
+ {
+ cmOStringStream 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());
+ return false;
+ }
+ }
+ }
+ else
+ {
+ // Use the old-style mode for backward compatibility.
+ this->Makefile->AddCustomCommandOldStyle(target.c_str(), outputs, depends,
+ source.c_str(), commandLines,
+ comment);
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool
+cmAddCustomCommandCommand
+::CheckOutputs(const std::vector<std::string>& outputs)
+{
+ for(std::vector<std::string>::const_iterator o = outputs.begin();
+ o != outputs.end(); ++o)
+ {
+ // Make sure the file will not be generated into the source
+ // directory during an out of source build.
+ if(!this->Makefile->CanIWriteThisFile(o->c_str()))
+ {
+ std::string e = "attempted to have a file \"" + *o +
+ "\" in a source directory as an output of custom command.";
+ this->SetError(e.c_str());
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+
+ // Make sure the output file name has no invalid characters.
+ std::string::size_type pos = o->find_first_of("#<>");
+ if(pos != o->npos)
+ {
+ cmOStringStream msg;
+ msg << "called with OUTPUT containing a \"" << (*o)[pos]
+ << "\". This character is not allowed.";
+ this->SetError(msg.str().c_str());
+ return false;
+ }
+ }
+ return true;
+}
diff --git a/Source/cmAddCustomCommandCommand.h b/Source/cmAddCustomCommandCommand.h
new file mode 100644
index 000000000..1f770ed39
--- /dev/null
+++ b/Source/cmAddCustomCommandCommand.h
@@ -0,0 +1,187 @@
+/*============================================================================
+ 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 cmAddCustomCommandCommand_h
+#define cmAddCustomCommandCommand_h
+
+#include "cmCommand.h"
+#include "cmDocumentGeneratorExpressions.h"
+
+/** \class cmAddCustomCommandCommand
+ * \brief
+ *
+ * cmAddCustomCommandCommand defines a new command (rule) that can
+ * be executed within the build process
+ *
+ */
+
+class cmAddCustomCommandCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmAddCustomCommandCommand;
+ }
+
+ /**
+ * 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 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"
+ " [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. "
+ "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"
+ ;
+ }
+
+ cmTypeMacro(cmAddCustomCommandCommand, cmCommand);
+protected:
+ bool CheckOutputs(const std::vector<std::string>& outputs);
+};
+
+
+#endif
diff --git a/Source/cmAddCustomTargetCommand.cxx b/Source/cmAddCustomTargetCommand.cxx
new file mode 100644
index 000000000..4eba88636
--- /dev/null
+++ b/Source/cmAddCustomTargetCommand.cxx
@@ -0,0 +1,192 @@
+/*============================================================================
+ 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 "cmAddCustomTargetCommand.h"
+
+// cmAddCustomTargetCommand
+bool cmAddCustomTargetCommand
+::InitialPass(std::vector<std::string> const& args,
+ cmExecutionStatus&)
+{
+ if(args.size() < 1 )
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ // Check the target name.
+ if(args[0].find_first_of("/\\") != args[0].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;
+ }
+ }
+
+ // Accumulate one command line at a time.
+ cmCustomCommandLine currentLine;
+
+ // Save all command lines.
+ cmCustomCommandLines commandLines;
+
+ // Accumulate dependencies.
+ std::vector<std::string> depends;
+ std::string working_directory;
+ bool verbatim = false;
+ std::string comment_buffer;
+ const char* comment = 0;
+ std::vector<std::string> sources;
+
+ // Keep track of parser state.
+ enum tdoing {
+ doing_command,
+ doing_depends,
+ doing_working_directory,
+ doing_comment,
+ doing_source,
+ doing_verbatim
+ };
+ tdoing doing = doing_command;
+
+ // Look for the ALL option.
+ bool excludeFromAll = true;
+ unsigned int start = 1;
+ if(args.size() > 1)
+ {
+ if(args[1] == "ALL")
+ {
+ excludeFromAll = false;
+ start = 2;
+ }
+ }
+
+ // Parse the rest of the arguments.
+ for(unsigned int j = start; j < args.size(); ++j)
+ {
+ std::string const& copy = args[j];
+
+ if(copy == "DEPENDS")
+ {
+ doing = doing_depends;
+ }
+ else if(copy == "WORKING_DIRECTORY")
+ {
+ doing = doing_working_directory;
+ }
+ else if(copy == "VERBATIM")
+ {
+ doing = doing_verbatim;
+ verbatim = true;
+ }
+ else if (copy == "COMMENT")
+ {
+ doing = doing_comment;
+ }
+ else if(copy == "COMMAND")
+ {
+ doing = doing_command;
+
+ // Save the current command before starting the next command.
+ if(!currentLine.empty())
+ {
+ commandLines.push_back(currentLine);
+ currentLine.clear();
+ }
+ }
+ else if(copy == "SOURCES")
+ {
+ doing = doing_source;
+ }
+ else
+ {
+ switch (doing)
+ {
+ case doing_working_directory:
+ working_directory = copy;
+ break;
+ case doing_command:
+ currentLine.push_back(copy);
+ break;
+ case doing_depends:
+ {
+ std::string dep = copy;
+ cmSystemTools::ConvertToUnixSlashes(dep);
+ depends.push_back(dep);
+ }
+ break;
+ case doing_comment:
+ comment_buffer = copy;
+ comment = comment_buffer.c_str();
+ break;
+ case doing_source:
+ sources.push_back(copy);
+ break;
+ default:
+ this->SetError("Wrong syntax. Unknown type of argument.");
+ return false;
+ }
+ }
+ }
+
+ std::string::size_type pos = args[0].find_first_of("#<>");
+ if(pos != args[0].npos)
+ {
+ cmOStringStream msg;
+ msg << "called with target name containing a \"" << args[0][pos]
+ << "\". This character is not allowed.";
+ this->SetError(msg.str().c_str());
+ return false;
+ }
+
+ // Store the last command line finished.
+ if(!currentLine.empty())
+ {
+ commandLines.push_back(currentLine);
+ currentLine.clear();
+ }
+
+ // Enforce name uniqueness.
+ {
+ std::string msg;
+ if(!this->Makefile->EnforceUniqueName(args[0], msg, true))
+ {
+ this->SetError(msg.c_str());
+ return false;
+ }
+ }
+
+ // Convert working directory to a full path.
+ if(!working_directory.empty())
+ {
+ const char* build_dir = this->Makefile->GetCurrentOutputDirectory();
+ working_directory =
+ cmSystemTools::CollapseFullPath(working_directory.c_str(), build_dir);
+ }
+
+ // 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);
+
+ // Add additional user-specified source files to the target.
+ target->AddSources(sources);
+
+ return true;
+}
diff --git a/Source/cmAddCustomTargetCommand.h b/Source/cmAddCustomTargetCommand.h
new file mode 100644
index 000000000..50bffefde
--- /dev/null
+++ b/Source/cmAddCustomTargetCommand.h
@@ -0,0 +1,108 @@
+/*============================================================================
+ 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 cmAddCustomTargetCommand_h
+#define cmAddCustomTargetCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmAddCustomTargetCommand
+ * \brief Command that adds a target to the build system.
+ *
+ * cmAddCustomTargetCommand adds an extra target to the build system.
+ * This is useful when you would like to add special
+ * targets like "install,", "clean," and so on.
+ */
+class cmAddCustomTargetCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmAddCustomTargetCommand;
+ }
+
+ /**
+ * 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 const char* 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);
+};
+
+#endif
diff --git a/Source/cmAddDefinitionsCommand.cxx b/Source/cmAddDefinitionsCommand.cxx
new file mode 100644
index 000000000..b813e3eb0
--- /dev/null
+++ b/Source/cmAddDefinitionsCommand.cxx
@@ -0,0 +1,31 @@
+/*============================================================================
+ 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 "cmAddDefinitionsCommand.h"
+
+// cmAddDefinitionsCommand
+bool cmAddDefinitionsCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ // it is OK to have no arguments
+ if(args.size() < 1 )
+ {
+ return true;
+ }
+
+ for(std::vector<std::string>::const_iterator i = args.begin();
+ i != args.end(); ++i)
+ {
+ this->Makefile->AddDefineFlag(i->c_str());
+ }
+ return true;
+}
+
diff --git a/Source/cmAddDefinitionsCommand.h b/Source/cmAddDefinitionsCommand.h
new file mode 100644
index 000000000..7bb37674d
--- /dev/null
+++ b/Source/cmAddDefinitionsCommand.h
@@ -0,0 +1,82 @@
+/*============================================================================
+ 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 cmAddDefinitionsCommand_h
+#define cmAddDefinitionsCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmAddDefinitionsCommand
+ * \brief Specify a list of compiler defines
+ *
+ * cmAddDefinitionsCommand specifies a list of compiler defines. These defines
+ * will be added to the compile command.
+ */
+class cmAddDefinitionsCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmAddDefinitionsCommand;
+ }
+
+ /**
+ * 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 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-trival 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."
+ ;
+ }
+
+ cmTypeMacro(cmAddDefinitionsCommand, cmCommand);
+private:
+ bool ParseDefinition(std::string const& def);
+};
+
+
+
+#endif
diff --git a/Source/cmAddDependenciesCommand.cxx b/Source/cmAddDependenciesCommand.cxx
new file mode 100644
index 000000000..a77140d61
--- /dev/null
+++ b/Source/cmAddDependenciesCommand.cxx
@@ -0,0 +1,46 @@
+/*============================================================================
+ 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 "cmAddDependenciesCommand.h"
+#include "cmLocalGenerator.h"
+#include "cmGlobalGenerator.h"
+
+// cmDependenciesCommand
+bool cmAddDependenciesCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 2 )
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ std::string target_name = args[0];
+ if(cmTarget* target = this->Makefile->FindTargetToUse(target_name.c_str()))
+ {
+ std::vector<std::string>::const_iterator s = args.begin();
+ ++s; // skip over target_name
+ for (; s != args.end(); ++s)
+ {
+ target->AddUtility(s->c_str());
+ }
+ }
+ else
+ {
+ std::string error = "Adding dependency to non-existent target: ";
+ error += target_name;
+ this->SetError(error.c_str());
+ return false;
+ }
+
+ return true;
+}
+
diff --git a/Source/cmAddDependenciesCommand.h b/Source/cmAddDependenciesCommand.h
new file mode 100644
index 000000000..14a7741fa
--- /dev/null
+++ b/Source/cmAddDependenciesCommand.h
@@ -0,0 +1,78 @@
+/*============================================================================
+ 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 cmDependenciessCommand_h
+#define cmDependenciessCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmAddDependenciesCommand
+ * \brief Add a dependency to a target
+ *
+ * cmAddDependenciesCommand adds a dependency to a target
+ */
+class cmAddDependenciesCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmAddDependenciesCommand;
+ }
+
+ /**
+ * 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 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.";
+ }
+
+ cmTypeMacro(cmAddDependenciesCommand, cmCommand);
+};
+
+
+#endif
diff --git a/Source/cmAddExecutableCommand.cxx b/Source/cmAddExecutableCommand.cxx
new file mode 100644
index 000000000..6dd8e5c64
--- /dev/null
+++ b/Source/cmAddExecutableCommand.cxx
@@ -0,0 +1,136 @@
+/*============================================================================
+ 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 "cmAddExecutableCommand.h"
+
+// cmExecutableCommand
+bool cmAddExecutableCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 2 )
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+ std::vector<std::string>::const_iterator s = args.begin();
+
+ std::string exename = *s;
+
+ ++s;
+ bool use_win32 = false;
+ bool use_macbundle = false;
+ bool excludeFromAll = false;
+ bool importTarget = false;
+ bool importGlobal = false;
+ while ( s != args.end() )
+ {
+ if (*s == "WIN32")
+ {
+ ++s;
+ use_win32 = true;
+ }
+ else if ( *s == "MACOSX_BUNDLE" )
+ {
+ ++s;
+ use_macbundle = true;
+ }
+ else if(*s == "EXCLUDE_FROM_ALL")
+ {
+ ++s;
+ excludeFromAll = true;
+ }
+ else if(*s == "IMPORTED")
+ {
+ ++s;
+ importTarget = true;
+ }
+ else if(importTarget && *s == "GLOBAL")
+ {
+ ++s;
+ importGlobal = true;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ // Special modifiers are not allowed with IMPORTED signature.
+ if(importTarget
+ && (use_win32 || use_macbundle || excludeFromAll))
+ {
+ if(use_win32)
+ {
+ this->SetError("may not be given WIN32 for an IMPORTED target.");
+ }
+ else if(use_macbundle)
+ {
+ this->SetError(
+ "may not be given MACOSX_BUNDLE for an IMPORTED target.");
+ }
+ else // if(excludeFromAll)
+ {
+ this->SetError(
+ "may not be given EXCLUDE_FROM_ALL for an IMPORTED target.");
+ }
+ return false;
+ }
+
+ // Handle imported target creation.
+ if(importTarget)
+ {
+ // Make sure the target does not already exist.
+ if(this->Makefile->FindTargetToUse(exename.c_str()))
+ {
+ cmOStringStream e;
+ e << "cannot create imported target \"" << exename
+ << "\" because another target with the same name already exists.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+
+ // Create the imported target.
+ this->Makefile->AddImportedTarget(exename.c_str(), cmTarget::EXECUTABLE,
+ importGlobal);
+ return true;
+ }
+
+ // Enforce name uniqueness.
+ {
+ std::string msg;
+ if(!this->Makefile->EnforceUniqueName(exename, msg))
+ {
+ this->SetError(msg.c_str());
+ return false;
+ }
+ }
+
+ if (s == args.end())
+ {
+ this->SetError
+ ("called with incorrect number of arguments, no sources provided");
+ return false;
+ }
+
+ std::vector<std::string> srclists(s, args.end());
+ cmTarget* tgt = this->Makefile->AddExecutable(exename.c_str(), srclists,
+ excludeFromAll);
+ if ( use_win32 )
+ {
+ tgt->SetProperty("WIN32_EXECUTABLE", "ON");
+ }
+ if ( use_macbundle)
+ {
+ tgt->SetProperty("MACOSX_BUNDLE", "ON");
+ }
+
+ return true;
+}
diff --git a/Source/cmAddExecutableCommand.h b/Source/cmAddExecutableCommand.h
new file mode 100644
index 000000000..1e9f9b3be
--- /dev/null
+++ b/Source/cmAddExecutableCommand.h
@@ -0,0 +1,117 @@
+/*============================================================================
+ 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 cmExecutablesCommand_h
+#define cmExecutablesCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmExecutablesCommand
+ * \brief Defines a list of executables to build.
+ *
+ * cmExecutablesCommand defines a list of executable (i.e., test)
+ * programs to create.
+ */
+class cmAddExecutableCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmAddExecutableCommand;
+ }
+
+ /**
+ * 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 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."
+ ;
+ }
+
+ cmTypeMacro(cmAddExecutableCommand, cmCommand);
+};
+
+
+#endif
diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx
new file mode 100644
index 000000000..fd39eec02
--- /dev/null
+++ b/Source/cmAddLibraryCommand.cxx
@@ -0,0 +1,193 @@
+/*============================================================================
+ 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 "cmAddLibraryCommand.h"
+
+#include "cmake.h"
+
+// cmLibraryCommand
+bool cmAddLibraryCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 1 )
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+ // Library type defaults to value of BUILD_SHARED_LIBS, if it exists,
+ // otherwise it defaults to static library.
+ cmTarget::TargetType type = cmTarget::SHARED_LIBRARY;
+ if (cmSystemTools::IsOff(this->Makefile->GetDefinition("BUILD_SHARED_LIBS")))
+ {
+ type = cmTarget::STATIC_LIBRARY;
+ }
+ bool excludeFromAll = false;
+ bool importTarget = false;
+ bool importGlobal = false;
+
+ std::vector<std::string>::const_iterator s = args.begin();
+
+ std::string libName = *s;
+
+ ++s;
+
+ // If the second argument is "SHARED" or "STATIC", then it controls
+ // the type of library. Otherwise, it is treated as a source or
+ // source list name. There may be two keyword arguments, check for them
+ bool haveSpecifiedType = false;
+ while ( s != args.end() )
+ {
+ std::string libType = *s;
+ if(libType == "STATIC")
+ {
+ ++s;
+ type = cmTarget::STATIC_LIBRARY;
+ haveSpecifiedType = true;
+ }
+ else if(libType == "SHARED")
+ {
+ ++s;
+ type = cmTarget::SHARED_LIBRARY;
+ haveSpecifiedType = true;
+ }
+ else if(libType == "MODULE")
+ {
+ ++s;
+ type = cmTarget::MODULE_LIBRARY;
+ haveSpecifiedType = true;
+ }
+ else if(libType == "OBJECT")
+ {
+ ++s;
+ type = cmTarget::OBJECT_LIBRARY;
+ haveSpecifiedType = true;
+ }
+ else if(libType == "UNKNOWN")
+ {
+ ++s;
+ type = cmTarget::UNKNOWN_LIBRARY;
+ haveSpecifiedType = true;
+ }
+ else if(*s == "EXCLUDE_FROM_ALL")
+ {
+ ++s;
+ excludeFromAll = true;
+ }
+ else if(*s == "IMPORTED")
+ {
+ ++s;
+ importTarget = true;
+ }
+ else if(importTarget && *s == "GLOBAL")
+ {
+ ++s;
+ importGlobal = true;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ /* ideally we should check whether for the linker language of the target
+ 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(
+ "TARGET_SUPPORTS_SHARED_LIBS") == false))
+ {
+ cmOStringStream w;
+ w <<
+ "ADD_LIBRARY called with " <<
+ (type==cmTarget::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;
+ }
+
+ // Handle imported target creation.
+ if(importTarget)
+ {
+ // The IMPORTED signature requires a type to be specified explicitly.
+ if (!haveSpecifiedType)
+ {
+ this->SetError("called with IMPORTED argument but no library type.");
+ return false;
+ }
+ if(type == cmTarget::OBJECT_LIBRARY)
+ {
+ this->Makefile->IssueMessage(
+ cmake::FATAL_ERROR,
+ "The OBJECT library type may not be used for IMPORTED libraries."
+ );
+ return true;
+ }
+
+ // Make sure the target does not already exist.
+ if(this->Makefile->FindTargetToUse(libName.c_str()))
+ {
+ cmOStringStream e;
+ e << "cannot create imported target \"" << libName
+ << "\" because another target with the same name already exists.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+
+ // Create the imported target.
+ this->Makefile->AddImportedTarget(libName.c_str(), type, importGlobal);
+ return true;
+ }
+
+ // A non-imported target may not have UNKNOWN type.
+ if(type == cmTarget::UNKNOWN_LIBRARY)
+ {
+ this->Makefile->IssueMessage(
+ cmake::FATAL_ERROR,
+ "The UNKNOWN library type may be used only for IMPORTED libraries."
+ );
+ return true;
+ }
+
+ // Enforce name uniqueness.
+ {
+ std::string msg;
+ if(!this->Makefile->EnforceUniqueName(libName, msg))
+ {
+ this->SetError(msg.c_str());
+ return false;
+ }
+ }
+
+ if (s == args.end())
+ {
+ std::string msg = "You have called ADD_LIBRARY for library ";
+ msg += args[0];
+ msg += " without any source files. This typically indicates a problem ";
+ msg += "with your CMakeLists.txt file";
+ cmSystemTools::Message(msg.c_str() ,"Warning");
+ }
+
+ std::vector<std::string> srclists;
+ while (s != args.end())
+ {
+ srclists.push_back(*s);
+ ++s;
+ }
+
+ this->Makefile->AddLibrary(libName.c_str(), type, srclists, excludeFromAll);
+
+ return true;
+}
+
+
diff --git a/Source/cmAddLibraryCommand.h b/Source/cmAddLibraryCommand.h
new file mode 100644
index 000000000..b1ae20289
--- /dev/null
+++ b/Source/cmAddLibraryCommand.h
@@ -0,0 +1,142 @@
+/*============================================================================
+ 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 cmLibrarysCommand_h
+#define cmLibrarysCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmLibrarysCommand
+ * \brief Defines a list of executables to build.
+ *
+ * cmLibrarysCommand defines a list of executable (i.e., test)
+ * programs to create.
+ */
+class cmAddLibraryCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmAddLibraryCommand;
+ }
+
+ /**
+ * 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 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."
+ "\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."
+ ;
+ }
+
+ cmTypeMacro(cmAddLibraryCommand, cmCommand);
+};
+
+
+#endif
diff --git a/Source/cmAddSubDirectoryCommand.cxx b/Source/cmAddSubDirectoryCommand.cxx
new file mode 100644
index 000000000..5fca527ca
--- /dev/null
+++ b/Source/cmAddSubDirectoryCommand.cxx
@@ -0,0 +1,123 @@
+/*============================================================================
+ 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 "cmAddSubDirectoryCommand.h"
+
+// cmAddSubDirectoryCommand
+bool cmAddSubDirectoryCommand::InitialPass
+(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 1 )
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ // store the binpath
+ std::string srcArg = args[0];
+ std::string binArg;
+
+ bool excludeFromAll = false;
+
+ // process the rest of the arguments looking for optional args
+ std::vector<std::string>::const_iterator i = args.begin();
+ ++i;
+ for(;i != args.end(); ++i)
+ {
+ if(*i == "EXCLUDE_FROM_ALL")
+ {
+ excludeFromAll = true;
+ continue;
+ }
+ else if (!binArg.size())
+ {
+ binArg = *i;
+ }
+ else
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+ }
+
+ // Compute the full path to the specified source directory.
+ // Interpret a relative path with respect to the current source directory.
+ std::string srcPath;
+ if(cmSystemTools::FileIsFullPath(srcArg.c_str()))
+ {
+ srcPath = srcArg;
+ }
+ else
+ {
+ srcPath = this->Makefile->GetCurrentDirectory();
+ srcPath += "/";
+ srcPath += srcArg;
+ }
+ if(!cmSystemTools::FileIsDirectory(srcPath.c_str()))
+ {
+ std::string error = "given source \"";
+ error += srcArg;
+ error += "\" which is not an existing directory.";
+ this->SetError(error.c_str());
+ return false;
+ }
+ srcPath = cmSystemTools::CollapseFullPath(srcPath.c_str());
+
+ // Compute the full path to the binary directory.
+ std::string binPath;
+ if(binArg.empty())
+ {
+ // No binary directory was specified. If the source directory is
+ // not a subdirectory of the current directory then it is an
+ // error.
+ if(!cmSystemTools::FindLastString(srcPath.c_str(),
+ this->Makefile->GetCurrentDirectory()))
+ {
+ cmOStringStream e;
+ e << "not given a binary directory but the given source directory "
+ << "\"" << srcPath << "\" is not a subdirectory of \""
+ << this->Makefile->GetCurrentDirectory() << "\". "
+ << "When specifying an out-of-tree source a binary directory "
+ << "must be explicitly specified.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+
+ // Remove the CurrentDirectory from the srcPath and replace it
+ // with the CurrentOutputDirectory.
+ binPath = srcPath;
+ cmSystemTools::ReplaceString(binPath,
+ this->Makefile->GetCurrentDirectory(),
+ this->Makefile->GetCurrentOutputDirectory());
+ }
+ else
+ {
+ // Use the binary directory specified.
+ // Interpret a relative path with respect to the current binary directory.
+ if(cmSystemTools::FileIsFullPath(binArg.c_str()))
+ {
+ binPath = binArg;
+ }
+ else
+ {
+ binPath = this->Makefile->GetCurrentOutputDirectory();
+ binPath += "/";
+ binPath += binArg;
+ }
+ }
+ binPath = cmSystemTools::CollapseFullPath(binPath.c_str());
+
+ // Add the subdirectory using the computed full paths.
+ this->Makefile->AddSubDirectory(srcPath.c_str(), binPath.c_str(),
+ excludeFromAll, false, true);
+
+ return true;
+}
diff --git a/Source/cmAddSubDirectoryCommand.h b/Source/cmAddSubDirectoryCommand.h
new file mode 100644
index 000000000..3d6f51ea5
--- /dev/null
+++ b/Source/cmAddSubDirectoryCommand.h
@@ -0,0 +1,99 @@
+/*============================================================================
+ 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 cmAddSubDirectoryCommand_h
+#define cmAddSubDirectoryCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmAddSubDirectoryCommand
+ * \brief Specify a subdirectory to build
+ *
+ * cmAddSubDirectoryCommand specifies a subdirectory to process
+ * by CMake. CMake will descend
+ * into the specified source directory and process any CMakeLists.txt found.
+ */
+class cmAddSubDirectoryCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmAddSubDirectoryCommand;
+ }
+
+ /**
+ * 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 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."
+ ;
+ }
+
+ cmTypeMacro(cmAddSubDirectoryCommand, cmCommand);
+};
+
+
+
+#endif
diff --git a/Source/cmAddTestCommand.cxx b/Source/cmAddTestCommand.cxx
new file mode 100644
index 000000000..a9165f5b1
--- /dev/null
+++ b/Source/cmAddTestCommand.cxx
@@ -0,0 +1,180 @@
+/*============================================================================
+ 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 "cmAddTestCommand.h"
+
+#include "cmTestGenerator.h"
+
+#include "cmTest.h"
+
+
+// cmExecutableCommand
+bool cmAddTestCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(!args.empty() && args[0] == "NAME")
+ {
+ return this->HandleNameMode(args);
+ }
+
+ // First argument is the name of the test Second argument is the name of
+ // the executable to run (a target or external program) Remaining arguments
+ // are the arguments to pass to the executable
+ if(args.size() < 2 )
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ // 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);
+ }
+
+ // 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());
+ 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;
+ e << " given test name \"" << args[0]
+ << "\" which already exists in this directory.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+ else
+ {
+ test = this->Makefile->CreateTest(args[0].c_str());
+ test->SetOldStyle(true);
+ this->Makefile->AddTestGenerator(new cmTestGenerator(test));
+ }
+ test->SetCommand(command);
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmAddTestCommand::HandleNameMode(std::vector<std::string> const& args)
+{
+ std::string name;
+ std::vector<std::string> configurations;
+ std::string working_directory;
+ std::vector<std::string> command;
+
+ // Read the arguments.
+ enum Doing {
+ DoingName,
+ DoingCommand,
+ DoingConfigs,
+ DoingWorkingDirectory,
+ DoingNone
+ };
+ Doing doing = DoingName;
+ for(unsigned int i=1; i < args.size(); ++i)
+ {
+ if(args[i] == "COMMAND")
+ {
+ if(!command.empty())
+ {
+ this->SetError(" may be given at most one COMMAND.");
+ return false;
+ }
+ doing = DoingCommand;
+ }
+ else if(args[i] == "CONFIGURATIONS")
+ {
+ if(!configurations.empty())
+ {
+ this->SetError(" may be given at most one set of CONFIGURATIONS.");
+ return false;
+ }
+ doing = DoingConfigs;
+ }
+ else if(args[i] == "WORKING_DIRECTORY")
+ {
+ if(!working_directory.empty())
+ {
+ this->SetError(" may be given at most one WORKING_DIRECTORY.");
+ return false;
+ }
+ doing = DoingWorkingDirectory;
+ }
+ else if(doing == DoingName)
+ {
+ name = args[i];
+ doing = DoingNone;
+ }
+ else if(doing == DoingCommand)
+ {
+ command.push_back(args[i]);
+ }
+ else if(doing == DoingConfigs)
+ {
+ configurations.push_back(args[i]);
+ }
+ else if(doing == DoingWorkingDirectory)
+ {
+ working_directory = args[i];
+ doing = DoingNone;
+ }
+ else
+ {
+ cmOStringStream e;
+ e << " given unknown argument:\n " << args[i] << "\n";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+
+ // Require a test name.
+ if(name.empty())
+ {
+ this->SetError(" must be given non-empty NAME.");
+ return false;
+ }
+
+ // Require a command.
+ if(command.empty())
+ {
+ this->SetError(" must be given non-empty COMMAND.");
+ return false;
+ }
+
+ // Require a unique test name within the directory.
+ if(this->Makefile->GetTest(name.c_str()))
+ {
+ cmOStringStream e;
+ e << " given test NAME \"" << name
+ << "\" which already exists in this directory.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+
+ // Add the test.
+ cmTest* test = this->Makefile->CreateTest(name.c_str());
+ test->SetOldStyle(false);
+ test->SetCommand(command);
+ if(!working_directory.empty())
+ {
+ test->SetProperty("WORKING_DIRECTORY", working_directory.c_str());
+ }
+ this->Makefile->AddTestGenerator(new cmTestGenerator(test, configurations));
+
+ return true;
+}
diff --git a/Source/cmAddTestCommand.h b/Source/cmAddTestCommand.h
new file mode 100644
index 000000000..59f10f622
--- /dev/null
+++ b/Source/cmAddTestCommand.h
@@ -0,0 +1,101 @@
+/*============================================================================
+ 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 cmAddTestCommand_h
+#define cmAddTestCommand_h
+
+#include "cmCommand.h"
+#include "cmDocumentGeneratorExpressions.h"
+
+/** \class cmAddTestCommand
+ * \brief Add a test to the lists of tests to run.
+ *
+ * cmAddTestCommand adds a test to the list of tests to run .
+ */
+class cmAddTestCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmAddTestCommand;
+ }
+
+ /**
+ * 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 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"
+ "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_COMMAND_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\"."
+ ;
+ }
+
+ cmTypeMacro(cmAddTestCommand, cmCommand);
+private:
+ bool HandleNameMode(std::vector<std::string> const& args);
+};
+
+
+#endif
diff --git a/Source/cmArchiveWrite.cxx b/Source/cmArchiveWrite.cxx
new file mode 100644
index 000000000..b410e440e
--- /dev/null
+++ b/Source/cmArchiveWrite.cxx
@@ -0,0 +1,308 @@
+/*============================================================================
+ 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 "cmArchiveWrite.h"
+
+#include "cmSystemTools.h"
+#include <cmsys/ios/iostream>
+#include <cmsys/Directory.hxx>
+#include <cm_libarchive.h>
+
+//----------------------------------------------------------------------------
+class cmArchiveWrite::Entry
+{
+ struct archive_entry* Object;
+public:
+ Entry(): Object(archive_entry_new()) {}
+ ~Entry() { archive_entry_free(this->Object); }
+ operator struct archive_entry*() { return this->Object; }
+};
+
+//----------------------------------------------------------------------------
+struct cmArchiveWrite::Callback
+{
+ // archive_write_callback
+ static __LA_SSIZE_T Write(struct archive*, void *cd,
+ const void *b, size_t n)
+ {
+ cmArchiveWrite* self = static_cast<cmArchiveWrite*>(cd);
+ if(self->Stream.write(static_cast<const char*>(b),
+ static_cast<cmsys_ios::streamsize>(n)))
+ {
+ return static_cast<__LA_SSIZE_T>(n);
+ }
+ else
+ {
+ return static_cast<__LA_SSIZE_T>(-1);
+ }
+ }
+};
+
+//----------------------------------------------------------------------------
+cmArchiveWrite::cmArchiveWrite(std::ostream& os, Compress c, Type t):
+ Stream(os),
+ Archive(archive_write_new()),
+ Disk(archive_read_disk_new()),
+ Verbose(false)
+{
+ switch (c)
+ {
+ case CompressNone:
+ if(archive_write_set_compression_none(this->Archive) != ARCHIVE_OK)
+ {
+ this->Error = "archive_write_set_compression_none: ";
+ this->Error += archive_error_string(this->Archive);
+ return;
+ }
+ break;
+ case CompressCompress:
+ if(archive_write_set_compression_compress(this->Archive) != ARCHIVE_OK)
+ {
+ this->Error = "archive_write_set_compression_compress: ";
+ this->Error += archive_error_string(this->Archive);
+ return;
+ }
+ break;
+ case CompressGZip:
+ if(archive_write_set_compression_gzip(this->Archive) != ARCHIVE_OK)
+ {
+ this->Error = "archive_write_set_compression_gzip: ";
+ this->Error += archive_error_string(this->Archive);
+ return;
+ }
+ break;
+ case CompressBZip2:
+ if(archive_write_set_compression_bzip2(this->Archive) != ARCHIVE_OK)
+ {
+ this->Error = "archive_write_set_compression_bzip2: ";
+ this->Error += archive_error_string(this->Archive);
+ return;
+ }
+ break;
+ case CompressLZMA:
+ if(archive_write_set_compression_lzma(this->Archive) != ARCHIVE_OK)
+ {
+ this->Error = "archive_write_set_compression_lzma: ";
+ this->Error += archive_error_string(this->Archive);
+ return;
+ }
+ break;
+ case CompressXZ:
+ if(archive_write_set_compression_xz(this->Archive) != ARCHIVE_OK)
+ {
+ this->Error = "archive_write_set_compression_xz: ";
+ this->Error += archive_error_string(this->Archive);
+ return;
+ }
+ break;
+ };
+#if !defined(_WIN32) || defined(__CYGWIN__)
+ 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;;
+ }
+#endif
+ switch (t)
+ {
+ 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;
+ }
+
+ // 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);
+ return;
+ }
+
+ if(archive_write_open(
+ this->Archive, this, 0,
+ reinterpret_cast<archive_write_callback*>(&Callback::Write),
+ 0) != ARCHIVE_OK)
+ {
+ this->Error = "archive_write_open: ";
+ this->Error += archive_error_string(this->Archive);
+ return;
+ }
+}
+
+//----------------------------------------------------------------------------
+cmArchiveWrite::~cmArchiveWrite()
+{
+ archive_read_finish(this->Disk);
+ archive_write_finish(this->Archive);
+}
+
+//----------------------------------------------------------------------------
+bool cmArchiveWrite::Add(std::string path, size_t skip, const char* prefix)
+{
+ if(this->Okay())
+ {
+ if(!path.empty() && path[path.size()-1] == '/')
+ {
+ path.erase(path.size()-1);
+ }
+ this->AddPath(path.c_str(), skip, prefix);
+ }
+ return this->Okay();
+}
+
+//----------------------------------------------------------------------------
+bool cmArchiveWrite::AddPath(const char* path,
+ size_t skip, const char* prefix)
+{
+ if(!this->AddFile(path, skip, prefix))
+ {
+ return false;
+ }
+ if(!cmSystemTools::FileIsDirectory(path) ||
+ cmSystemTools::FileIsSymlink(path))
+ {
+ return true;
+ }
+ cmsys::Directory d;
+ if(d.Load(path))
+ {
+ std::string next = path;
+ next += "/";
+ std::string::size_type end = next.size();
+ unsigned long n = d.GetNumberOfFiles();
+ for(unsigned long i = 0; i < n; ++i)
+ {
+ const char* file = d.GetFile(i);
+ if(strcmp(file, ".") != 0 && strcmp(file, "..") != 0)
+ {
+ next.erase(end);
+ next += file;
+ if(!this->AddPath(next.c_str(), skip, prefix))
+ {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmArchiveWrite::AddFile(const char* file,
+ size_t skip, const char* prefix)
+{
+ // Skip the file if we have no name for it. This may happen on a
+ // top-level directory, which does not need to be included anyway.
+ if(skip >= strlen(file))
+ {
+ return true;
+ }
+ const char* out = file + skip;
+
+ // Meta-data.
+ std::string dest = prefix? prefix : "";
+ dest += out;
+ if(this->Verbose)
+ {
+ std::cout << dest << "\n";
+ }
+ Entry e;
+ archive_entry_copy_sourcepath(e, file);
+ archive_entry_set_pathname(e, dest.c_str());
+ 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);
+ return false;
+ }
+ // 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(archive_write_header(this->Archive, e) != ARCHIVE_OK)
+ {
+ this->Error = "archive_write_header: ";
+ this->Error += archive_error_string(this->Archive);
+ return false;
+ }
+
+ // do not copy content of symlink
+ if (!archive_entry_symlink(e))
+ {
+ // Content.
+ if(size_t size = static_cast<size_t>(archive_entry_size(e)))
+ {
+ return this->AddData(file, size);
+ }
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmArchiveWrite::AddData(const char* file, size_t size)
+{
+ std::ifstream fin(file, std::ios::in | cmsys_ios_binary);
+ if(!fin)
+ {
+ this->Error = "Error opening \"";
+ this->Error += file;
+ this->Error += "\": ";
+ this->Error += cmSystemTools::GetLastSystemError();
+ return false;
+ }
+
+ char buffer[16384];
+ size_t nleft = size;
+ while(nleft > 0)
+ {
+ typedef cmsys_ios::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);
+ // Some stream libraries (older HPUX) return failure at end of
+ // file on the last read even if some data were read. Check
+ // gcount instead of trusting the stream error status.
+ if(static_cast<size_t>(fin.gcount()) != nnext)
+ {
+ break;
+ }
+ if(archive_write_data(this->Archive, buffer, nnext) != nnext_s)
+ {
+ this->Error = "archive_write_data: ";
+ this->Error += archive_error_string(this->Archive);
+ return false;
+ }
+ nleft -= nnext;
+ }
+ if(nleft > 0)
+ {
+ this->Error = "Error reading \"";
+ this->Error += file;
+ this->Error += "\": ";
+ this->Error += cmSystemTools::GetLastSystemError();
+ return false;
+ }
+ return true;
+}
diff --git a/Source/cmArchiveWrite.h b/Source/cmArchiveWrite.h
new file mode 100644
index 000000000..3e3b2f0ca
--- /dev/null
+++ b/Source/cmArchiveWrite.h
@@ -0,0 +1,94 @@
+/*============================================================================
+ 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 cmArchiveWrite_h
+#define cmArchiveWrite_h
+
+#include "cmStandardIncludes.h"
+
+#if !defined(CMAKE_BUILD_WITH_CMAKE)
+# error "cmArchiveWrite not allowed during bootstrap build!"
+#endif
+
+/** \class cmArchiveWrite
+ * \brief Wrapper around libarchive for writing.
+ *
+ */
+class cmArchiveWrite
+{
+ typedef void (cmArchiveWrite::* safe_bool)();
+ void safe_bool_true() {}
+public:
+ /** Compression type. */
+ enum Compress
+ {
+ CompressNone,
+ CompressCompress,
+ CompressGZip,
+ CompressBZip2,
+ CompressLZMA,
+ 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();
+
+ /**
+ * Add a path (file or directory) to the archive. Directories are
+ * added recursively. The "path" must be readable on disk, either
+ * full path or relative to current working directory. The "skip"
+ * value indicates how many leading bytes from the input path to
+ * 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);
+
+ /** Returns true if there has been no error. */
+ operator safe_bool() const
+ { return this->Okay()? &cmArchiveWrite::safe_bool_true : 0; }
+
+ /** Returns true if there has been an error. */
+ bool operator!() const { return !this->Okay(); }
+
+ /** Return the error string; empty if none. */
+ std::string GetError() const { return this->Error; }
+
+ // TODO: More general callback instead of hard-coding calls to
+ // std::cout.
+ void SetVerbose(bool v) { this->Verbose = v; }
+
+private:
+ bool Okay() const { return this->Error.empty(); }
+ bool AddPath(const char* path, size_t skip, const char* prefix);
+ bool AddFile(const char* file, size_t skip, const char* prefix);
+ bool AddData(const char* file, size_t size);
+
+ struct Callback;
+ friend struct Callback;
+
+ class Entry;
+
+ std::ostream& Stream;
+ struct archive* Archive;
+ struct archive* Disk;
+ bool Verbose;
+ std::string Error;
+};
+
+#endif
diff --git a/Source/cmAuxSourceDirectoryCommand.cxx b/Source/cmAuxSourceDirectoryCommand.cxx
new file mode 100644
index 000000000..f88be3d58
--- /dev/null
+++ b/Source/cmAuxSourceDirectoryCommand.cxx
@@ -0,0 +1,89 @@
+/*============================================================================
+ 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 "cmAuxSourceDirectoryCommand.h"
+#include "cmSourceFile.h"
+
+#include <cmsys/Directory.hxx>
+
+// cmAuxSourceDirectoryCommand
+bool cmAuxSourceDirectoryCommand::InitialPass
+(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 2 || args.size() > 2)
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ 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 += "/";
+ tdir += templateDirectory;
+ }
+ else
+ {
+ tdir = templateDirectory;
+ }
+
+ // was the list already populated
+ const char *def = this->Makefile->GetDefinition(args[1].c_str());
+ if (def)
+ {
+ sourceListValue = def;
+ }
+
+ // Load all the files in the directory
+ cmsys::Directory dir;
+ if(dir.Load(tdir.c_str()))
+ {
+ size_t numfiles = dir.GetNumberOfFiles();
+ for(size_t i =0; i < numfiles; ++i)
+ {
+ std::string file = dir.GetFile(static_cast<unsigned long>(i));
+ // Split the filename into base and extension
+ std::string::size_type dotpos = file.rfind(".");
+ if( dotpos != std::string::npos )
+ {
+ 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::string fullname = templateDirectory;
+ fullname += "/";
+ fullname += file;
+ // add the file as a class file so
+ // depends can be done
+ cmSourceFile* sf =
+ this->Makefile->GetOrCreateSource(fullname.c_str());
+ sf->SetProperty("ABSTRACT","0");
+ if(!sourceListValue.empty())
+ {
+ sourceListValue += ";";
+ }
+ sourceListValue += fullname;
+ }
+ }
+ }
+ }
+ this->Makefile->AddDefinition(args[1].c_str(), sourceListValue.c_str());
+ return true;
+}
+
diff --git a/Source/cmAuxSourceDirectoryCommand.h b/Source/cmAuxSourceDirectoryCommand.h
new file mode 100644
index 000000000..f059e4473
--- /dev/null
+++ b/Source/cmAuxSourceDirectoryCommand.h
@@ -0,0 +1,86 @@
+/*============================================================================
+ 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 cmAuxSourceDirectoryCommand_h
+#define cmAuxSourceDirectoryCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmAuxSourceDirectoryCommand
+ * \brief Specify auxiliary source code directories.
+ *
+ * cmAuxSourceDirectoryCommand specifies source code directories
+ * that must be built as part of this build process. This directories
+ * are not recursively processed like the SUBDIR command (cmSubdirCommand).
+ * A side effect of this command is to create a subdirectory in the build
+ * directory structure.
+ */
+class cmAuxSourceDirectoryCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmAuxSourceDirectoryCommand;
+ }
+
+ /**
+ * 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 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.";
+ }
+
+ cmTypeMacro(cmAuxSourceDirectoryCommand, cmCommand);
+};
+
+
+
+#endif
diff --git a/Source/cmBootstrapCommands.cxx b/Source/cmBootstrapCommands.cxx
new file mode 100644
index 000000000..9097a7482
--- /dev/null
+++ b/Source/cmBootstrapCommands.cxx
@@ -0,0 +1,171 @@
+/*============================================================================
+ 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.
+============================================================================*/
+// This file is used to compile all the commands
+// that CMake knows about at compile time.
+// This is sort of a boot strapping approach since you would
+// like to have CMake to build CMake.
+#include "cmCommands.h"
+#include "cmAddCustomCommandCommand.cxx"
+#include "cmAddCustomTargetCommand.cxx"
+#include "cmAddDefinitionsCommand.cxx"
+#include "cmAddDependenciesCommand.cxx"
+#include "cmAddExecutableCommand.cxx"
+#include "cmAddLibraryCommand.cxx"
+#include "cmAddSubDirectoryCommand.cxx"
+#include "cmAddTestCommand.cxx"
+#include "cmBreakCommand.cxx"
+#include "cmBuildCommand.cxx"
+#include "cmCMakeMinimumRequired.cxx"
+#include "cmCMakePolicyCommand.cxx"
+#include "cmCommandArgumentsHelper.cxx"
+#include "cmConfigureFileCommand.cxx"
+#include "cmCoreTryCompile.cxx"
+#include "cmCreateTestSourceList.cxx"
+#include "cmDefinePropertyCommand.cxx"
+#include "cmElseCommand.cxx"
+#include "cmEnableLanguageCommand.cxx"
+#include "cmEnableTestingCommand.cxx"
+#include "cmEndForEachCommand.cxx"
+#include "cmEndFunctionCommand.cxx"
+#include "cmEndIfCommand.cxx"
+#include "cmEndMacroCommand.cxx"
+#include "cmEndWhileCommand.cxx"
+#include "cmExecProgramCommand.cxx"
+#include "cmExecuteProcessCommand.cxx"
+#include "cmExternalMakefileProjectGenerator.cxx"
+#include "cmFindBase.cxx"
+#include "cmFindCommon.cxx"
+#include "cmFileCommand.cxx"
+#include "cmFindFileCommand.cxx"
+#include "cmFindLibraryCommand.cxx"
+#include "cmFindPackageCommand.cxx"
+#include "cmFindPathCommand.cxx"
+#include "cmFindProgramCommand.cxx"
+#include "cmForEachCommand.cxx"
+#include "cmFunctionCommand.cxx"
+#include "cmGetCMakePropertyCommand.cxx"
+#include "cmGetDirectoryPropertyCommand.cxx"
+#include "cmGetFilenameComponentCommand.cxx"
+#include "cmGetPropertyCommand.cxx"
+#include "cmGetSourceFilePropertyCommand.cxx"
+#include "cmGetTargetPropertyCommand.cxx"
+#include "cmHexFileConverter.cxx"
+#include "cmIfCommand.cxx"
+#include "cmIncludeCommand.cxx"
+#include "cmIncludeDirectoryCommand.cxx"
+#include "cmIncludeRegularExpressionCommand.cxx"
+#include "cmInstallFilesCommand.cxx"
+#include "cmInstallCommandArguments.cxx"
+#include "cmInstallCommand.cxx"
+#include "cmInstallTargetsCommand.cxx"
+#include "cmLinkDirectoriesCommand.cxx"
+#include "cmListCommand.cxx"
+#include "cmMacroCommand.cxx"
+#include "cmMakeDirectoryCommand.cxx"
+#include "cmMarkAsAdvancedCommand.cxx"
+#include "cmMathCommand.cxx"
+#include "cmMessageCommand.cxx"
+#include "cmOptionCommand.cxx"
+#include "cmProjectCommand.cxx"
+#include "cmReturnCommand.cxx"
+#include "cmSeparateArgumentsCommand.cxx"
+#include "cmSetCommand.cxx"
+#include "cmSetDirectoryPropertiesCommand.cxx"
+#include "cmSetPropertyCommand.cxx"
+#include "cmSetSourceFilesPropertiesCommand.cxx"
+#include "cmSetTargetPropertiesCommand.cxx"
+#include "cmSetTestsPropertiesCommand.cxx"
+#include "cmGetTestPropertyCommand.cxx"
+#include "cmSiteNameCommand.cxx"
+#include "cmStringCommand.cxx"
+#include "cmSubdirCommand.cxx"
+#include "cmTargetLinkLibrariesCommand.cxx"
+#include "cmTryCompileCommand.cxx"
+#include "cmTryRunCommand.cxx"
+#include "cmUnsetCommand.cxx"
+#include "cmWhileCommand.cxx"
+
+void GetBootstrapCommands(std::list<cmCommand*>& commands)
+{
+ commands.push_back(new cmAddCustomCommandCommand);
+ commands.push_back(new cmAddCustomTargetCommand);
+ commands.push_back(new cmAddDefinitionsCommand);
+ commands.push_back(new cmAddDependenciesCommand);
+ commands.push_back(new cmAddExecutableCommand);
+ commands.push_back(new cmAddLibraryCommand);
+ commands.push_back(new cmAddSubDirectoryCommand);
+ commands.push_back(new cmAddTestCommand);
+ commands.push_back(new cmBreakCommand);
+ commands.push_back(new cmBuildCommand);
+ commands.push_back(new cmCMakeMinimumRequired);
+ commands.push_back(new cmCMakePolicyCommand);
+ commands.push_back(new cmConfigureFileCommand);
+ commands.push_back(new cmCreateTestSourceList);
+ commands.push_back(new cmDefinePropertyCommand);
+ commands.push_back(new cmElseCommand);
+ commands.push_back(new cmEnableLanguageCommand);
+ commands.push_back(new cmEnableTestingCommand);
+ commands.push_back(new cmEndForEachCommand);
+ commands.push_back(new cmEndFunctionCommand);
+ commands.push_back(new cmEndIfCommand);
+ commands.push_back(new cmEndMacroCommand);
+ commands.push_back(new cmEndWhileCommand);
+ commands.push_back(new cmExecProgramCommand);
+ commands.push_back(new cmExecuteProcessCommand);
+ commands.push_back(new cmFileCommand);
+ commands.push_back(new cmFindFileCommand);
+ commands.push_back(new cmFindLibraryCommand);
+ commands.push_back(new cmFindPackageCommand);
+ commands.push_back(new cmFindPathCommand);
+ commands.push_back(new cmFindProgramCommand);
+ commands.push_back(new cmForEachCommand);
+ commands.push_back(new cmFunctionCommand);
+ commands.push_back(new cmGetCMakePropertyCommand);
+ commands.push_back(new cmGetDirectoryPropertyCommand);
+ commands.push_back(new cmGetFilenameComponentCommand);
+ commands.push_back(new cmGetPropertyCommand);
+ commands.push_back(new cmGetSourceFilePropertyCommand);
+ commands.push_back(new cmGetTargetPropertyCommand);
+ commands.push_back(new cmIfCommand);
+ commands.push_back(new cmIncludeCommand);
+ commands.push_back(new cmIncludeDirectoryCommand);
+ commands.push_back(new cmIncludeRegularExpressionCommand);
+ commands.push_back(new cmInstallCommand);
+ commands.push_back(new cmInstallFilesCommand);
+ commands.push_back(new cmInstallTargetsCommand);
+ commands.push_back(new cmLinkDirectoriesCommand);
+ commands.push_back(new cmListCommand);
+ commands.push_back(new cmMacroCommand);
+ commands.push_back(new cmMakeDirectoryCommand);
+ commands.push_back(new cmMarkAsAdvancedCommand);
+ commands.push_back(new cmMathCommand);
+ commands.push_back(new cmMessageCommand);
+ commands.push_back(new cmOptionCommand);
+ commands.push_back(new cmProjectCommand);
+ commands.push_back(new cmReturnCommand);
+ commands.push_back(new cmSeparateArgumentsCommand);
+ commands.push_back(new cmSetCommand);
+ commands.push_back(new cmSetDirectoryPropertiesCommand);
+ commands.push_back(new cmSetPropertyCommand);
+ commands.push_back(new cmSetSourceFilesPropertiesCommand);
+ commands.push_back(new cmSetTargetPropertiesCommand);
+ commands.push_back(new cmGetTestPropertyCommand);
+ commands.push_back(new cmSetTestsPropertiesCommand);
+ commands.push_back(new cmSiteNameCommand);
+ commands.push_back(new cmStringCommand);
+ commands.push_back(new cmSubdirCommand);
+ commands.push_back(new cmTargetLinkLibrariesCommand);
+ commands.push_back(new cmTryCompileCommand);
+ commands.push_back(new cmTryRunCommand);
+ commands.push_back(new cmUnsetCommand);
+ commands.push_back(new cmWhileCommand);
+}
diff --git a/Source/cmBreakCommand.cxx b/Source/cmBreakCommand.cxx
new file mode 100644
index 000000000..b70e40088
--- /dev/null
+++ b/Source/cmBreakCommand.cxx
@@ -0,0 +1,21 @@
+/*============================================================================
+ 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 "cmBreakCommand.h"
+
+// cmBreakCommand
+bool cmBreakCommand::InitialPass(std::vector<std::string> const&,
+ cmExecutionStatus &status)
+{
+ status.SetBreakInvoked(true);
+ return true;
+}
+
diff --git a/Source/cmBreakCommand.h b/Source/cmBreakCommand.h
new file mode 100644
index 000000000..67ef37e9a
--- /dev/null
+++ b/Source/cmBreakCommand.h
@@ -0,0 +1,73 @@
+/*============================================================================
+ 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 cmBreakCommand_h
+#define cmBreakCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmBreakCommand
+ * \brief Break from an enclosing foreach or while loop
+ *
+ * cmBreakCommand returns from an enclosing foreach or while loop
+ */
+class cmBreakCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmBreakCommand;
+ }
+
+ /**
+ * 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 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";
+ }
+
+ cmTypeMacro(cmBreakCommand, cmCommand);
+};
+
+
+
+#endif
diff --git a/Source/cmBuildCommand.cxx b/Source/cmBuildCommand.cxx
new file mode 100644
index 000000000..3722ab635
--- /dev/null
+++ b/Source/cmBuildCommand.cxx
@@ -0,0 +1,161 @@
+/*============================================================================
+ 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 "cmBuildCommand.h"
+
+#include "cmLocalGenerator.h"
+#include "cmGlobalGenerator.h"
+
+//----------------------------------------------------------------------
+bool cmBuildCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ // Support the legacy signature of the command:
+ //
+ if(2 == args.size())
+ {
+ return this->TwoArgsSignature(args);
+ }
+
+ return this->MainSignature(args);
+}
+
+//----------------------------------------------------------------------
+bool cmBuildCommand
+::MainSignature(std::vector<std::string> const& args)
+{
+ if(args.size() < 1)
+ {
+ this->SetError("requires at least one argument naming a CMake variable");
+ return false;
+ }
+
+ // The cmake variable in which to store the result.
+ const char* variable = args[0].c_str();
+
+ // Parse remaining arguments.
+ const char* configuration = 0;
+ const char* project_name = 0;
+ const char* target = 0;
+ enum Doing { DoingNone, DoingConfiguration, DoingProjectName, DoingTarget };
+ Doing doing = DoingNone;
+ for(unsigned int i=1; i < args.size(); ++i)
+ {
+ if(args[i] == "CONFIGURATION")
+ {
+ doing = DoingConfiguration;
+ }
+ else if(args[i] == "PROJECT_NAME")
+ {
+ doing = DoingProjectName;
+ }
+ else if(args[i] == "TARGET")
+ {
+ doing = DoingTarget;
+ }
+ else if(doing == DoingConfiguration)
+ {
+ doing = DoingNone;
+ configuration = args[i].c_str();
+ }
+ else if(doing == DoingProjectName)
+ {
+ doing = DoingNone;
+ project_name = args[i].c_str();
+ }
+ else if(doing == DoingTarget)
+ {
+ doing = DoingNone;
+ target = args[i].c_str();
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "unknown argument \"" << args[i] << "\"";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+
+ const char* makeprogram
+ = this->Makefile->GetDefinition("CMAKE_MAKE_PROGRAM");
+
+ // If null/empty CONFIGURATION argument, GenerateBuildCommand 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:
+ //
+ if(!configuration || !*configuration)
+ {
+ configuration = getenv("CMAKE_CONFIG_TYPE");
+ }
+ if(!configuration || !*configuration)
+ {
+ configuration = "Release";
+ }
+
+ // If null/empty PROJECT_NAME argument, use the Makefile's project name:
+ //
+ if(!project_name || !*project_name)
+ {
+ project_name = this->Makefile->GetProjectName();
+ }
+
+ // 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, target, configuration, true, false);
+
+ this->Makefile->AddDefinition(variable, makecommand.c_str());
+
+ return true;
+}
+
+//----------------------------------------------------------------------
+bool cmBuildCommand
+::TwoArgsSignature(std::vector<std::string> const& args)
+{
+ if(args.size() < 2 )
+ {
+ this->SetError("called with less than two arguments");
+ return false;
+ }
+
+ 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 )
+ {
+ configType = cfg;
+ }
+
+ std::string makecommand = this->Makefile->GetLocalGenerator()
+ ->GetGlobalGenerator()->GenerateBuildCommand
+ (makeprogram.c_str(), this->Makefile->GetProjectName(), 0,
+ 0, configType.c_str(), true, false);
+
+ if(cacheValue)
+ {
+ return true;
+ }
+ this->Makefile->AddCacheDefinition(define,
+ makecommand.c_str(),
+ "Command used to build entire project "
+ "from the command line.",
+ cmCacheManager::STRING);
+ return true;
+}
diff --git a/Source/cmBuildCommand.h b/Source/cmBuildCommand.h
new file mode 100644
index 000000000..a333c5d95
--- /dev/null
+++ b/Source/cmBuildCommand.h
@@ -0,0 +1,97 @@
+/*============================================================================
+ 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 cmBuildCommand_h
+#define cmBuildCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmBuildCommand
+ * \brief build_command command
+ *
+ * cmBuildCommand implements the build_command CMake command
+ */
+class cmBuildCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmBuildCommand;
+ }
+
+ /**
+ * 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 primary command signature with optional, KEYWORD-based args.
+ */
+ virtual bool MainSignature(std::vector<std::string> const& args);
+
+ /**
+ * Legacy "exactly 2 args required" signature.
+ */
+ virtual bool TwoArgsSignature(std::vector<std::string> const& args);
+
+ /**
+ * 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."
+ ;
+ }
+
+ cmTypeMacro(cmBuildCommand, cmCommand);
+};
+
+#endif
diff --git a/Source/cmBuildNameCommand.cxx b/Source/cmBuildNameCommand.cxx
new file mode 100644
index 000000000..fa698303c
--- /dev/null
+++ b/Source/cmBuildNameCommand.cxx
@@ -0,0 +1,77 @@
+/*============================================================================
+ 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 "cmBuildNameCommand.h"
+
+#include <cmsys/RegularExpression.hxx>
+
+// cmBuildNameCommand
+bool cmBuildNameCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 1 )
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+ const char* cacheValue = this->Makefile->GetDefinition(args[0].c_str());
+ if(cacheValue)
+ {
+ // do we need to correct the value?
+ cmsys::RegularExpression reg("[()/]");
+ if (reg.find(cacheValue))
+ {
+ std::string cv = cacheValue;
+ cmSystemTools::ReplaceString(cv,"/", "_");
+ cmSystemTools::ReplaceString(cv,"(", "_");
+ cmSystemTools::ReplaceString(cv,")", "_");
+ this->Makefile->AddCacheDefinition(args[0].c_str(),
+ cv.c_str(),
+ "Name of build.",
+ cmCacheManager::STRING);
+ }
+ return true;
+ }
+
+
+ std::string buildname = "WinNT";
+ if(this->Makefile->GetDefinition("UNIX"))
+ {
+ buildname = "";
+ cmSystemTools::RunSingleCommand("uname -a", &buildname);
+ if(buildname.length())
+ {
+ std::string RegExp = "([^ ]*) [^ ]* ([^ ]*) ";
+ cmsys::RegularExpression reg( RegExp.c_str() );
+ if(reg.find(buildname.c_str()))
+ {
+ buildname = reg.match(1) + "-" + reg.match(2);
+ }
+ }
+ }
+ std::string compiler = "${CMAKE_CXX_COMPILER}";
+ this->Makefile->ExpandVariablesInString ( compiler );
+ buildname += "-";
+ buildname += cmSystemTools::GetFilenameName(compiler);
+ cmSystemTools::ReplaceString(buildname,
+ "/", "_");
+ cmSystemTools::ReplaceString(buildname,
+ "(", "_");
+ cmSystemTools::ReplaceString(buildname,
+ ")", "_");
+
+ this->Makefile->AddCacheDefinition(args[0].c_str(),
+ buildname.c_str(),
+ "Name of build.",
+ cmCacheManager::STRING);
+ return true;
+}
+
diff --git a/Source/cmBuildNameCommand.h b/Source/cmBuildNameCommand.h
new file mode 100644
index 000000000..26505a260
--- /dev/null
+++ b/Source/cmBuildNameCommand.h
@@ -0,0 +1,82 @@
+/*============================================================================
+ 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 cmBuildNameCommand_h
+#define cmBuildNameCommand_h
+
+#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.
+ */
+ 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 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);
+};
+
+
+
+#endif
diff --git a/Source/cmCMakeMinimumRequired.cxx b/Source/cmCMakeMinimumRequired.cxx
new file mode 100644
index 000000000..126934ceb
--- /dev/null
+++ b/Source/cmCMakeMinimumRequired.cxx
@@ -0,0 +1,139 @@
+/*============================================================================
+ 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 "cmCMakeMinimumRequired.h"
+
+#include "cmVersion.h"
+
+// cmCMakeMinimumRequired
+bool cmCMakeMinimumRequired
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ // Process arguments.
+ std::string version_string;
+ bool doing_version = false;
+ for(unsigned int i=0; i < args.size(); ++i)
+ {
+ if(args[i] == "VERSION")
+ {
+ doing_version = true;
+ }
+ else if(args[i] == "FATAL_ERROR")
+ {
+ if(doing_version)
+ {
+ this->SetError("called with no value for VERSION.");
+ return false;
+ }
+ doing_version = false;
+ }
+ else if(doing_version)
+ {
+ doing_version = false;
+ version_string = args[i];
+ }
+ else
+ {
+ this->UnknownArguments.push_back(args[i]);
+ }
+ }
+ if(doing_version)
+ {
+ this->SetError("called with no value for VERSION.");
+ return false;
+ }
+
+ // Make sure there was a version to check.
+ if(version_string.empty())
+ {
+ return this->EnforceUnknownArguments();
+ }
+
+ // Save the required version string.
+ this->Makefile->AddDefinition("CMAKE_MINIMUM_REQUIRED_VERSION",
+ version_string.c_str());
+
+
+ // 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();
+
+ // 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;
+ 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());
+ return false;
+ }
+
+ // Compare the version numbers.
+ if((current_major < required_major) ||
+ (current_major == required_major &&
+ current_minor < required_minor) ||
+ (current_major == required_major &&
+ current_minor == required_minor &&
+ current_patch < required_patch) ||
+ (current_major == required_major &&
+ current_minor == required_minor &&
+ current_patch == required_patch &&
+ current_tweak < required_tweak))
+ {
+ // The current version is too low.
+ cmOStringStream e;
+ e << "CMake " << version_string.c_str()
+ << " or higher is required. You are running version "
+ << cmVersion::GetCMakeVersion();
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ cmSystemTools::SetFatalErrorOccured();
+ return true;
+ }
+
+ // The version is not from the future, so enforce unknown arguments.
+ if(!this->EnforceUnknownArguments())
+ {
+ return false;
+ }
+
+ if (required_major < 2 || (required_major == 2 && required_minor < 4))
+ {
+ this->Makefile->SetPolicyVersion("2.4");
+ }
+ else
+ {
+ this->Makefile->SetPolicyVersion(version_string.c_str());
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmCMakeMinimumRequired::EnforceUnknownArguments()
+{
+ if(!this->UnknownArguments.empty())
+ {
+ cmOStringStream e;
+ e << "called with unknown argument \""
+ << this->UnknownArguments[0] << "\".";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ return true;
+}
diff --git a/Source/cmCMakeMinimumRequired.h b/Source/cmCMakeMinimumRequired.h
new file mode 100644
index 000000000..d23ce79cf
--- /dev/null
+++ b/Source/cmCMakeMinimumRequired.h
@@ -0,0 +1,90 @@
+/*============================================================================
+ 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 cmCMakeMinimumRequired_h
+#define cmCMakeMinimumRequired_h
+
+#include "cmCommand.h"
+
+/** \class cmCMakeMinimumRequired
+ * \brief cmake_minimum_required command
+ *
+ * cmCMakeMinimumRequired implements the cmake_minimum_required CMake command
+ */
+class cmCMakeMinimumRequired : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmCMakeMinimumRequired;
+ }
+
+ /**
+ * 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 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.";
+ }
+
+ cmTypeMacro(cmCMakeMinimumRequired, cmCommand);
+
+private:
+ std::vector<std::string> UnknownArguments;
+ bool EnforceUnknownArguments();
+};
+
+
+
+#endif
diff --git a/Source/cmCMakePolicyCommand.cxx b/Source/cmCMakePolicyCommand.cxx
new file mode 100644
index 000000000..f4be55930
--- /dev/null
+++ b/Source/cmCMakePolicyCommand.cxx
@@ -0,0 +1,172 @@
+/*============================================================================
+ 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 "cmCMakePolicyCommand.h"
+
+#include "cmVersion.h"
+
+// cmCMakePolicyCommand
+bool cmCMakePolicyCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 1)
+ {
+ this->SetError("requires at least one argument.");
+ return false;
+ }
+
+ if(args[0] == "SET")
+ {
+ return this->HandleSetMode(args);
+ }
+ else if(args[0] == "GET")
+ {
+ return this->HandleGetMode(args);
+ }
+ else if(args[0] == "PUSH")
+ {
+ if(args.size() > 1)
+ {
+ this->SetError("PUSH may not be given additional arguments.");
+ return false;
+ }
+ this->Makefile->PushPolicy();
+ return true;
+ }
+ else if(args[0] == "POP")
+ {
+ if(args.size() > 1)
+ {
+ this->SetError("POP may not be given additional arguments.");
+ return false;
+ }
+ this->Makefile->PopPolicy();
+ return true;
+ }
+ else if(args[0] == "VERSION")
+ {
+ return this->HandleVersionMode(args);
+ }
+
+ cmOStringStream e;
+ e << "given unknown first argument \"" << args[0] << "\"";
+ this->SetError(e.str().c_str());
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmCMakePolicyCommand::HandleSetMode(std::vector<std::string> const& args)
+{
+ if(args.size() != 3)
+ {
+ this->SetError("SET must be given exactly 2 additional arguments.");
+ return false;
+ }
+
+ cmPolicies::PolicyStatus status;
+ if(args[2] == "OLD")
+ {
+ status = cmPolicies::OLD;
+ }
+ else if(args[2] == "NEW")
+ {
+ status = cmPolicies::NEW;
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "SET given unrecognized policy status \"" << args[2] << "\"";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+
+ if(!this->Makefile->SetPolicy(args[1].c_str(), status))
+ {
+ this->SetError("SET failed to set policy.");
+ return false;
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmCMakePolicyCommand::HandleGetMode(std::vector<std::string> const& args)
+{
+ if(args.size() != 3)
+ {
+ this->SetError("GET must be given exactly 2 additional arguments.");
+ return false;
+ }
+
+ // Get arguments.
+ std::string const& id = args[1];
+ std::string const& var = args[2];
+
+ // Lookup the policy number.
+ cmPolicies::PolicyID pid;
+ if(!this->Makefile->GetPolicies()->GetPolicyID(id.c_str(), pid))
+ {
+ cmOStringStream e;
+ e << "GET given policy \"" << id << "\" which is not known to this "
+ << "version of CMake.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+
+ // Lookup the policy setting.
+ cmPolicies::PolicyStatus status = this->Makefile->GetPolicyStatus(pid);
+ switch (status)
+ {
+ case cmPolicies::OLD:
+ // Report that the policy is set to OLD.
+ this->Makefile->AddDefinition(var.c_str(), "OLD");
+ break;
+ case cmPolicies::WARN:
+ // Report that the policy is not set.
+ this->Makefile->AddDefinition(var.c_str(), "");
+ break;
+ case cmPolicies::NEW:
+ // Report that the policy is set to NEW.
+ this->Makefile->AddDefinition(var.c_str(), "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)
+ << "\n"
+ << "The call to cmake_policy(GET " << id << " ...) at which this "
+ << "error appears requests the policy, and this version of CMake "
+ << "requires that the policy be set to NEW before it is checked.";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ }
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool
+cmCMakePolicyCommand::HandleVersionMode(std::vector<std::string> const& args)
+{
+ if(args.size() <= 1)
+ {
+ this->SetError("VERSION not given an argument");
+ return false;
+ }
+ else if(args.size() >= 3)
+ {
+ this->SetError("VERSION given too many arguments");
+ return false;
+ }
+ this->Makefile->SetPolicyVersion(args[1].c_str());
+ return true;
+}
diff --git a/Source/cmCMakePolicyCommand.h b/Source/cmCMakePolicyCommand.h
new file mode 100644
index 000000000..4f1ed36ad
--- /dev/null
+++ b/Source/cmCMakePolicyCommand.h
@@ -0,0 +1,142 @@
+/*============================================================================
+ 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 cmCMakePolicyCommand_h
+#define cmCMakePolicyCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmCMakePolicyCommand
+ * \brief Set how CMake should handle policies
+ *
+ * cmCMakePolicyCommand sets how CMake should deal with backwards
+ * compatibility policies.
+ */
+class cmCMakePolicyCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmCMakePolicyCommand;
+ }
+
+ /**
+ * 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 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."
+ ;
+ }
+
+ cmTypeMacro(cmCMakePolicyCommand, cmCommand);
+private:
+ bool HandleSetMode(std::vector<std::string> const& args);
+ bool HandleGetMode(std::vector<std::string> const& args);
+ bool HandleVersionMode(std::vector<std::string> const& args);
+};
+
+
+
+#endif
diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx
new file mode 100644
index 000000000..e23791355
--- /dev/null
+++ b/Source/cmCPluginAPI.cxx
@@ -0,0 +1,934 @@
+/*============================================================================
+ 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.
+============================================================================*/
+/*
+ this file contains the implementation of the C API to CMake. Generally
+ these routines just manipulate arguments and then call the associated
+ methods on the CMake classes. */
+
+#include "cmMakefile.h"
+#include "cmCPluginAPI.h"
+#include "cmVersion.h"
+
+#include "cmSourceFile.h"
+
+#include <stdlib.h>
+
+#ifdef __QNX__
+# include <malloc.h> /* for malloc/free on QNX */
+#endif
+
+extern "C"
+{
+
+void CCONV *cmGetClientData(void *info)
+{
+ return ((cmLoadedCommandInfo *)info)->ClientData;
+}
+
+void CCONV cmSetClientData(void *info, void *cd)
+{
+ ((cmLoadedCommandInfo *)info)->ClientData = cd;
+}
+
+void CCONV cmSetError(void *info, const char *err)
+{
+ if (((cmLoadedCommandInfo *)info)->Error)
+ {
+ free(((cmLoadedCommandInfo *)info)->Error);
+ }
+ ((cmLoadedCommandInfo *)info)->Error = strdup(err);
+}
+
+unsigned int CCONV cmGetCacheMajorVersion(void *arg)
+{
+ cmMakefile *mf = static_cast<cmMakefile *>(arg);
+ return mf->GetCacheMajorVersion();
+}
+unsigned int CCONV cmGetCacheMinorVersion(void *arg)
+{
+ cmMakefile *mf = static_cast<cmMakefile *>(arg);
+ return mf->GetCacheMinorVersion();
+}
+
+unsigned int CCONV cmGetMajorVersion(void *)
+{
+ return cmVersion::GetMajorVersion();
+}
+
+unsigned int CCONV cmGetMinorVersion(void *)
+{
+ return cmVersion::GetMinorVersion();
+}
+
+void CCONV cmAddDefinition(void *arg, const char* name, const char* value)
+{
+ cmMakefile *mf = static_cast<cmMakefile *>(arg);
+ mf->AddDefinition(name,value);
+}
+
+/* Add a definition to this makefile and the global cmake cache. */
+void CCONV cmAddCacheDefinition(void *arg, const char* name,
+ const char* value, const char* doc, int type)
+{
+ cmMakefile *mf = static_cast<cmMakefile *>(arg);
+
+ switch (type)
+ {
+ case CM_CACHE_BOOL:
+ mf->AddCacheDefinition(name,value,doc,
+ cmCacheManager::BOOL);
+ break;
+ case CM_CACHE_PATH:
+ mf->AddCacheDefinition(name,value,doc,
+ cmCacheManager::PATH);
+ break;
+ case CM_CACHE_FILEPATH:
+ mf->AddCacheDefinition(name,value,doc,
+ cmCacheManager::FILEPATH);
+ break;
+ case CM_CACHE_STRING:
+ mf->AddCacheDefinition(name,value,doc,
+ cmCacheManager::STRING);
+ break;
+ case CM_CACHE_INTERNAL:
+ mf->AddCacheDefinition(name,value,doc,
+ cmCacheManager::INTERNAL);
+ break;
+ case CM_CACHE_STATIC:
+ mf->AddCacheDefinition(name,value,doc,
+ cmCacheManager::STATIC);
+ break;
+ }
+}
+
+const char* CCONV cmGetProjectName(void *arg)
+{
+ cmMakefile *mf = static_cast<cmMakefile *>(arg);
+ return mf->GetProjectName();
+}
+
+const char* CCONV cmGetHomeDirectory(void *arg)
+{
+ cmMakefile *mf = static_cast<cmMakefile *>(arg);
+ return mf->GetHomeDirectory();
+}
+const char* CCONV cmGetHomeOutputDirectory(void *arg)
+{
+ cmMakefile *mf = static_cast<cmMakefile *>(arg);
+ return mf->GetHomeOutputDirectory();
+}
+const char* CCONV cmGetStartDirectory(void *arg)
+{
+ cmMakefile *mf = static_cast<cmMakefile *>(arg);
+ return mf->GetStartDirectory();
+}
+const char* CCONV cmGetStartOutputDirectory(void *arg)
+{
+ cmMakefile *mf = static_cast<cmMakefile *>(arg);
+ return mf->GetStartOutputDirectory();
+}
+const char* CCONV cmGetCurrentDirectory(void *arg)
+{
+ cmMakefile *mf = static_cast<cmMakefile *>(arg);
+ return mf->GetCurrentDirectory();
+}
+const char* CCONV cmGetCurrentOutputDirectory(void *arg)
+{
+ cmMakefile *mf = static_cast<cmMakefile *>(arg);
+ return mf->GetCurrentOutputDirectory();
+}
+const char* CCONV cmGetDefinition(void *arg,const char*def)
+{
+ cmMakefile *mf = static_cast<cmMakefile *>(arg);
+ return mf->GetDefinition(def);
+}
+
+int CCONV cmIsOn(void *arg, const char* name)
+{
+ cmMakefile *mf = static_cast<cmMakefile *>(arg);
+ return static_cast<int>(mf->IsOn(name));
+}
+
+/** Check if a command exists. */
+int CCONV cmCommandExists(void *arg, const char* name)
+{
+ cmMakefile *mf = static_cast<cmMakefile *>(arg);
+ return static_cast<int>(mf->CommandExists(name));
+}
+
+void CCONV cmAddDefineFlag(void *arg, const char* definition)
+{
+ cmMakefile *mf = static_cast<cmMakefile *>(arg);
+ mf->AddDefineFlag(definition);
+}
+
+void CCONV cmAddLinkDirectoryForTarget(void *arg, const char *tgt,
+ const char* d)
+{
+ cmMakefile *mf = static_cast<cmMakefile *>(arg);
+ mf->AddLinkDirectoryForTarget(tgt,d);
+}
+
+
+void CCONV cmAddExecutable(void *arg, const char *exename,
+ int numSrcs, const char **srcs, int win32)
+{
+ cmMakefile *mf = static_cast<cmMakefile *>(arg);
+ std::vector<std::string> srcs2;
+ int i;
+ for (i = 0; i < numSrcs; ++i)
+ {
+ srcs2.push_back(srcs[i]);
+ }
+ cmTarget* tg = mf->AddExecutable(exename, srcs2);
+ if ( win32 )
+ {
+ tg->SetProperty("WIN32_EXECUTABLE", "ON");
+ }
+}
+
+void CCONV cmAddUtilityCommand(void *arg, const char* utilityName,
+ const char* command,
+ const char* arguments,
+ int all,
+ int numDepends,
+ const char **depends,
+ int,
+ const char **)
+{
+ // Get the makefile instance. Perform an extra variable expansion
+ // now because the API caller expects it.
+ cmMakefile* mf = static_cast<cmMakefile*>(arg);
+
+ // Construct the command line for the command.
+ cmCustomCommandLine commandLine;
+ std::string expand = command;
+ commandLine.push_back(mf->ExpandVariablesInString(expand));
+ if(arguments && arguments[0])
+ {
+ // TODO: Parse arguments!
+ expand = arguments;
+ commandLine.push_back(mf->ExpandVariablesInString(expand));
+ }
+ cmCustomCommandLines commandLines;
+ commandLines.push_back(commandLine);
+
+ // Accumulate the list of dependencies.
+ std::vector<std::string> depends2;
+ for(int i = 0; i < numDepends; ++i)
+ {
+ expand = depends[i];
+ depends2.push_back(mf->ExpandVariablesInString(expand));
+ }
+
+ // Pass the call to the makefile instance.
+ mf->AddUtilityCommand(utilityName, (all ? false : true),
+ 0, depends2, commandLines);
+}
+void CCONV cmAddCustomCommand(void *arg, const char* source,
+ const char* command,
+ int numArgs, const char **args,
+ int numDepends, const char **depends,
+ int numOutputs, const char **outputs,
+ const char *target)
+{
+ // Get the makefile instance. Perform an extra variable expansion
+ // now because the API caller expects it.
+ cmMakefile* mf = static_cast<cmMakefile*>(arg);
+
+ // Construct the command line for the command.
+ cmCustomCommandLine commandLine;
+ std::string expand = command;
+ commandLine.push_back(mf->ExpandVariablesInString(expand));
+ for(int i=0; i < numArgs; ++i)
+ {
+ expand = args[i];
+ commandLine.push_back(mf->ExpandVariablesInString(expand));
+ }
+ cmCustomCommandLines commandLines;
+ commandLines.push_back(commandLine);
+
+ // Accumulate the list of dependencies.
+ std::vector<std::string> depends2;
+ for(int i = 0; i < numDepends; ++i)
+ {
+ expand = depends[i];
+ depends2.push_back(mf->ExpandVariablesInString(expand));
+ }
+
+ // Accumulate the list of outputs.
+ std::vector<std::string> outputs2;
+ for(int i = 0; i < numOutputs; ++i)
+ {
+ expand = outputs[i];
+ outputs2.push_back(mf->ExpandVariablesInString(expand));
+ }
+
+ // Pass the call to the makefile instance.
+ const char* no_comment = 0;
+ mf->AddCustomCommandOldStyle(target, outputs2, depends2, source,
+ commandLines, no_comment);
+}
+
+void CCONV cmAddCustomCommandToOutput(void *arg, const char* output,
+ const char* command,
+ int numArgs, const char **args,
+ const char* main_dependency,
+ int numDepends, const char **depends)
+{
+ // Get the makefile instance. Perform an extra variable expansion
+ // now because the API caller expects it.
+ cmMakefile* mf = static_cast<cmMakefile*>(arg);
+
+ // Construct the command line for the command.
+ cmCustomCommandLine commandLine;
+ std::string expand = command;
+ commandLine.push_back(mf->ExpandVariablesInString(expand));
+ for(int i=0; i < numArgs; ++i)
+ {
+ expand = args[i];
+ commandLine.push_back(mf->ExpandVariablesInString(expand));
+ }
+ cmCustomCommandLines commandLines;
+ commandLines.push_back(commandLine);
+
+ // Accumulate the list of dependencies.
+ std::vector<std::string> depends2;
+ for(int i = 0; i < numDepends; ++i)
+ {
+ expand = depends[i];
+ depends2.push_back(mf->ExpandVariablesInString(expand));
+ }
+
+ // Pass the call to the makefile instance.
+ const char* no_comment = 0;
+ const char* no_working_dir = 0;
+ mf->AddCustomCommandToOutput(output, depends2, main_dependency,
+ commandLines, no_comment, no_working_dir);
+}
+
+void CCONV cmAddCustomCommandToTarget(void *arg, const char* target,
+ const char* command,
+ int numArgs, const char **args,
+ int commandType)
+{
+ // Get the makefile instance.
+ cmMakefile* mf = static_cast<cmMakefile*>(arg);
+
+ // Construct the command line for the command. Perform an extra
+ // variable expansion now because the API caller expects it.
+ cmCustomCommandLine commandLine;
+ std::string expand = command;
+ commandLine.push_back(mf->ExpandVariablesInString(expand));
+ for(int i=0; i < numArgs; ++i)
+ {
+ expand = args[i];
+ commandLine.push_back(mf->ExpandVariablesInString(expand));
+ }
+ cmCustomCommandLines commandLines;
+ commandLines.push_back(commandLine);
+
+ // Select the command type.
+ cmTarget::CustomCommandType cctype = cmTarget::POST_BUILD;
+ switch (commandType)
+ {
+ case CM_PRE_BUILD:
+ cctype = cmTarget::PRE_BUILD;
+ break;
+ case CM_PRE_LINK:
+ cctype = cmTarget::PRE_LINK;
+ break;
+ case CM_POST_BUILD:
+ cctype = cmTarget::POST_BUILD;
+ break;
+ }
+
+ // Pass the call to the makefile instance.
+ std::vector<std::string> no_depends;
+ const char* no_comment = 0;
+ const char* no_working_dir = 0;
+ mf->AddCustomCommandToTarget(target, no_depends, commandLines,
+ cctype, no_comment, no_working_dir);
+}
+
+void CCONV cmAddLinkLibraryForTarget(void *arg, const char *tgt,
+ const char*value, int libtype)
+{
+ cmMakefile *mf = static_cast<cmMakefile *>(arg);
+
+ switch (libtype)
+ {
+ case CM_LIBRARY_GENERAL:
+ mf->AddLinkLibraryForTarget(tgt,value, cmTarget::GENERAL);
+ break;
+ case CM_LIBRARY_DEBUG:
+ mf->AddLinkLibraryForTarget(tgt,value, cmTarget::DEBUG);
+ break;
+ case CM_LIBRARY_OPTIMIZED:
+ mf->AddLinkLibraryForTarget(tgt,value, cmTarget::OPTIMIZED);
+ break;
+ }
+}
+
+void CCONV cmAddLibrary(void *arg, const char *libname, int shared,
+ int numSrcs, const char **srcs)
+{
+ cmMakefile *mf = static_cast<cmMakefile *>(arg);
+ std::vector<std::string> srcs2;
+ int i;
+ for (i = 0; i < numSrcs; ++i)
+ {
+ srcs2.push_back(srcs[i]);
+ }
+ mf->AddLibrary(libname,
+ (shared? cmTarget::SHARED_LIBRARY : cmTarget::STATIC_LIBRARY),
+ srcs2);
+}
+
+char CCONV *cmExpandVariablesInString(void *arg, const char *source,
+ int escapeQuotes, int atOnly)
+{
+ cmMakefile *mf = static_cast<cmMakefile *>(arg);
+ std::string barf = source;
+ std::string result =
+ mf->ExpandVariablesInString(barf,
+ (escapeQuotes ? true : false),
+ (atOnly ? true : false));
+ char *res = static_cast<char *>(malloc(result.size() + 1));
+ if (result.size())
+ {
+ strcpy(res,result.c_str());
+ }
+ res[result.size()] = '\0';
+ return res;
+}
+
+
+int CCONV cmExecuteCommand(void *arg, const char *name,
+ int numArgs, const char **args)
+{
+ cmMakefile *mf = static_cast<cmMakefile *>(arg);
+ cmListFileFunction lff;
+ lff.Name = name;
+ for(int i = 0; i < numArgs; ++i)
+ {
+ // Assume all arguments are quoted.
+ lff.Arguments.push_back(cmListFileArgument(args[i], true,
+ "[CMake-Plugin]", 0));
+ }
+ cmExecutionStatus status;
+ return mf->ExecuteCommand(lff,status);
+}
+
+void CCONV cmExpandSourceListArguments(void *arg,
+ int numArgs,
+ const char **args,
+ int *resArgc,
+ char ***resArgv,
+ unsigned int startArgumentIndex)
+{
+ cmMakefile *mf = static_cast<cmMakefile *>(arg);
+ std::vector<std::string> result;
+ std::vector<std::string> args2;
+ int i;
+ for (i = 0; i < numArgs; ++i)
+ {
+ args2.push_back(args[i]);
+ }
+ mf->ExpandSourceListArguments(args2, result, startArgumentIndex);
+ int resargc = static_cast<int>(result.size());
+ char **resargv = 0;
+ if (resargc)
+ {
+ resargv = (char **)malloc(resargc*sizeof(char *));
+ }
+ for (i = 0; i < resargc; ++i)
+ {
+ resargv[i] = strdup(result[i].c_str());
+ }
+ *resArgc = resargc;
+ *resArgv = resargv;
+}
+
+void CCONV cmFreeArguments(int argc, char **argv)
+{
+ int i;
+ for (i = 0; i < argc; ++i)
+ {
+ free(argv[i]);
+ }
+ if (argv)
+ {
+ free(argv);
+ }
+}
+
+int CCONV cmGetTotalArgumentSize(int argc, char **argv)
+{
+ int i;
+ int result = 0;
+ for (i = 0; i < argc; ++i)
+ {
+ if (argv[i])
+ {
+ result = result + static_cast<int>(strlen(argv[i]));
+ }
+ }
+ return result;
+}
+
+// Source file proxy object to support the old cmSourceFile/cmMakefile
+// API for source files.
+struct cmCPluginAPISourceFile
+{
+ cmCPluginAPISourceFile(): RealSourceFile(0) {}
+ cmSourceFile* RealSourceFile;
+ std::string SourceName;
+ std::string SourceExtension;
+ std::string FullPath;
+ std::vector<std::string> Depends;
+ cmPropertyMap Properties;
+};
+
+// Keep a map from real cmSourceFile instances stored in a makefile to
+// the CPluginAPI proxy source file.
+class cmCPluginAPISourceFileMap:
+ public std::map<cmSourceFile*, cmCPluginAPISourceFile*>
+{
+public:
+ typedef std::map<cmSourceFile*, cmCPluginAPISourceFile*> derived;
+ typedef derived::iterator iterator;
+ typedef derived::value_type value_type;
+ ~cmCPluginAPISourceFileMap()
+ {
+ for(iterator i=this->begin(); i != this->end(); ++i)
+ {
+ delete i->second;
+ }
+ }
+};
+cmCPluginAPISourceFileMap cmCPluginAPISourceFiles;
+
+void * CCONV cmCreateSourceFile(void)
+{
+ return (void*)new cmCPluginAPISourceFile;
+}
+
+void * CCONV cmCreateNewSourceFile(void *arg)
+{
+ cmMakefile *mf = static_cast<cmMakefile *>(arg);
+ cmCPluginAPISourceFile *sf = new cmCPluginAPISourceFile;
+ sf->Properties.SetCMakeInstance(mf->GetCMakeInstance());
+ return (void*)sf;
+}
+
+void CCONV cmDestroySourceFile(void *arg)
+{
+ cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
+ // Only delete if it was created by cmCreateSourceFile or
+ // cmCreateNewSourceFile and is therefore not in the map.
+ if(!sf->RealSourceFile)
+ {
+ delete sf;
+ }
+}
+
+void CCONV *cmGetSource(void *arg, const char *name)
+{
+ cmMakefile *mf = static_cast<cmMakefile *>(arg);
+ if(cmSourceFile* rsf = mf->GetSource(name))
+ {
+ // Lookup the proxy source file object for this source.
+ cmCPluginAPISourceFileMap::iterator i = cmCPluginAPISourceFiles.find(rsf);
+ if(i == cmCPluginAPISourceFiles.end())
+ {
+ // Create a proxy source file object for this source.
+ cmCPluginAPISourceFile* sf = new cmCPluginAPISourceFile;
+ sf->RealSourceFile = rsf;
+ sf->FullPath = rsf->GetFullPath();
+ sf->SourceName =
+ cmSystemTools::GetFilenameWithoutLastExtension(sf->FullPath.c_str());
+ sf->SourceExtension =
+ cmSystemTools::GetFilenameLastExtension(sf->FullPath.c_str());
+
+ // Store the proxy in the map so it can be re-used and deleted later.
+ cmCPluginAPISourceFileMap::value_type entry(rsf, sf);
+ i = cmCPluginAPISourceFiles.insert(entry).first;
+ }
+ return (void *)i->second;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+void * CCONV cmAddSource(void *arg, void *arg2)
+{
+ cmMakefile *mf = static_cast<cmMakefile *>(arg);
+ cmCPluginAPISourceFile* osf = static_cast<cmCPluginAPISourceFile*>(arg2);
+ if(osf->FullPath.empty())
+ {
+ return 0;
+ }
+
+ // Create the real cmSourceFile instance and copy over saved information.
+ cmSourceFile* rsf = mf->GetOrCreateSource(osf->FullPath.c_str());
+ rsf->GetProperties() = osf->Properties;
+ for(std::vector<std::string>::iterator i = osf->Depends.begin();
+ i != osf->Depends.end(); ++i)
+ {
+ rsf->AddDepend(i->c_str());
+ }
+
+ // Create the proxy for the real source file.
+ cmCPluginAPISourceFile* sf = new cmCPluginAPISourceFile;
+ sf->RealSourceFile = rsf;
+ sf->FullPath = osf->FullPath;
+ sf->SourceName = osf->SourceName;
+ sf->SourceExtension = osf->SourceExtension;
+
+ // Store the proxy in the map so it can be re-used and deleted later.
+ cmCPluginAPISourceFiles[rsf] = sf;
+ return (void *)sf;
+}
+
+const char * CCONV cmSourceFileGetSourceName(void *arg)
+{
+ cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
+ return sf->SourceName.c_str();
+}
+
+const char * CCONV cmSourceFileGetFullPath(void *arg)
+{
+ cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
+ return sf->FullPath.c_str();
+}
+
+const char * CCONV cmSourceFileGetProperty(void *arg,const char *prop)
+{
+ cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
+ if(cmSourceFile* rsf = sf->RealSourceFile)
+ {
+ return rsf->GetProperty(prop);
+ }
+ else
+ {
+ if(!strcmp(prop,"LOCATION"))
+ {
+ 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);
+ }
+}
+
+int CCONV cmSourceFileGetPropertyAsBool(void *arg,const char *prop)
+{
+ cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
+ if(cmSourceFile* rsf = sf->RealSourceFile)
+ {
+ return rsf->GetPropertyAsBool(prop) ? 1:0;
+ }
+ else
+ {
+ return cmSystemTools::IsOn(cmSourceFileGetProperty(arg, prop))? 1:0;
+ }
+}
+
+void CCONV cmSourceFileSetProperty(void *arg,const char *prop,
+ const char *value)
+{
+ cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
+ if(cmSourceFile* rsf = sf->RealSourceFile)
+ {
+ rsf->SetProperty(prop, value);
+ }
+ else if(prop)
+ {
+ if(!value) { value = "NOTFOUND"; }
+ sf->Properties.SetProperty(prop, value, cmProperty::SOURCE_FILE);
+ }
+}
+
+void CCONV cmSourceFileAddDepend(void *arg, const char *depend)
+{
+ cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
+ if(cmSourceFile* rsf = sf->RealSourceFile)
+ {
+ rsf->AddDepend(depend);
+ }
+ else
+ {
+ sf->Depends.push_back(depend);
+ }
+}
+
+void CCONV cmSourceFileSetName(void *arg, const char* name, const char* dir,
+ int numSourceExtensions,
+ const char **sourceExtensions,
+ int numHeaderExtensions,
+ const char **headerExtensions)
+{
+ cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
+ if(sf->RealSourceFile)
+ {
+ // SetName is allowed only on temporary source files created by
+ // the command for building and passing to AddSource.
+ return;
+ }
+ std::vector<std::string> sourceExts;
+ std::vector<std::string> headerExts;
+ int i;
+ for (i = 0; i < numSourceExtensions; ++i)
+ {
+ sourceExts.push_back(sourceExtensions[i]);
+ }
+ for (i = 0; i < numHeaderExtensions; ++i)
+ {
+ headerExts.push_back(headerExtensions[i]);
+ }
+
+ // Save the original name given.
+ sf->SourceName = name;
+
+ // Convert the name to a full path in case the given name is a
+ // relative path.
+ std::string pathname = cmSystemTools::CollapseFullPath(name, dir);
+
+ // First try and see whether the listed file can be found
+ // as is without extensions added on.
+ std::string hname = pathname;
+ if(cmSystemTools::FileExists(hname.c_str()))
+ {
+ sf->SourceName = cmSystemTools::GetFilenamePath(name);
+ if ( sf->SourceName.size() > 0 )
+ {
+ sf->SourceName += "/";
+ }
+ sf->SourceName += cmSystemTools::GetFilenameWithoutLastExtension(name);
+ std::string::size_type pos = hname.rfind('.');
+ if(pos != std::string::npos)
+ {
+ sf->SourceExtension = hname.substr(pos+1, hname.size()-pos);
+ if ( cmSystemTools::FileIsFullPath(name) )
+ {
+ std::string::size_type pos2 = hname.rfind('/');
+ if(pos2 != std::string::npos)
+ {
+ sf->SourceName = hname.substr(pos2+1, pos - pos2-1);
+ }
+ }
+ }
+
+ sf->FullPath = hname;
+ return;
+ }
+
+ // Next, try the various source extensions
+ for( std::vector<std::string>::const_iterator ext = sourceExts.begin();
+ ext != sourceExts.end(); ++ext )
+ {
+ hname = pathname;
+ hname += ".";
+ hname += *ext;
+ if(cmSystemTools::FileExists(hname.c_str()))
+ {
+ sf->SourceExtension = *ext;
+ sf->FullPath = hname;
+ return;
+ }
+ }
+
+ // Finally, try the various header extensions
+ for( std::vector<std::string>::const_iterator ext = headerExts.begin();
+ ext != headerExts.end(); ++ext )
+ {
+ hname = pathname;
+ hname += ".";
+ hname += *ext;
+ if(cmSystemTools::FileExists(hname.c_str()))
+ {
+ sf->SourceExtension = *ext;
+ sf->FullPath = hname;
+ return;
+ }
+ }
+
+ cmOStringStream e;
+ e << "Cannot find source file \"" << pathname << "\"";
+ e << "\n\nTried extensions";
+ for( std::vector<std::string>::const_iterator ext = sourceExts.begin();
+ ext != sourceExts.end(); ++ext )
+ {
+ e << " ." << *ext;
+ }
+ for( std::vector<std::string>::const_iterator ext = headerExts.begin();
+ ext != headerExts.end(); ++ext )
+ {
+ e << " ." << *ext;
+ }
+ cmSystemTools::Error(e.str().c_str());
+ return;
+}
+
+void CCONV cmSourceFileSetName2(void *arg, const char* name, const char* dir,
+ const char *ext, int headerFileOnly)
+{
+ cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
+ if(sf->RealSourceFile)
+ {
+ // SetName is allowed only on temporary source files created by
+ // the command for building and passing to AddSource.
+ return;
+ }
+
+ // Implement the old SetName method code here.
+ if(headerFileOnly)
+ {
+ sf->Properties.SetProperty("HEADER_FILE_ONLY", "1",
+ cmProperty::SOURCE_FILE);
+ }
+ sf->SourceName = name;
+ std::string fname = sf->SourceName;
+ if(ext && strlen(ext))
+ {
+ fname += ".";
+ fname += ext;
+ }
+ sf->FullPath = cmSystemTools::CollapseFullPath(fname.c_str(), dir);
+ cmSystemTools::ConvertToUnixSlashes(sf->FullPath);
+ sf->SourceExtension = ext;
+}
+
+char * CCONV cmGetFilenameWithoutExtension(const char *name)
+{
+ std::string sres = cmSystemTools::GetFilenameWithoutExtension(name);
+ char *result = (char *)malloc(sres.size()+1);
+ strcpy(result,sres.c_str());
+ return result;
+}
+
+char * CCONV cmGetFilenamePath(const char *name)
+{
+ std::string sres = cmSystemTools::GetFilenamePath(name);
+ char *result = (char *)malloc(sres.size()+1);
+ strcpy(result,sres.c_str());
+ return result;
+}
+
+char * CCONV cmCapitalized(const char *name)
+{
+ std::string sres = cmSystemTools::Capitalized(name);
+ char *result = (char *)malloc(sres.size()+1);
+ strcpy(result,sres.c_str());
+ return result;
+}
+
+void CCONV cmCopyFileIfDifferent(const char *name1, const char *name2)
+{
+ cmSystemTools::CopyFileIfDifferent(name1,name2);
+}
+
+void CCONV cmRemoveFile(const char *name)
+{
+ cmSystemTools::RemoveFile(name);
+}
+
+void CCONV cmDisplayStatus(void *arg, const char* message)
+{
+ cmMakefile *mf = static_cast<cmMakefile *>(arg);
+ mf->DisplayStatus(message, -1);
+}
+
+void CCONV cmFree(void *data)
+{
+ free(data);
+}
+
+void CCONV DefineSourceFileProperty (void *arg, const char *name,
+ const char *briefDocs,
+ const char *longDocs,
+ int chained)
+{
+ cmMakefile *mf = static_cast<cmMakefile *>(arg);
+ mf->GetCMakeInstance()->DefineProperty(name,cmProperty::SOURCE_FILE,
+ briefDocs, longDocs,
+ chained != 0);
+}
+
+} // close the extern "C" scope
+
+cmCAPI cmStaticCAPI =
+{
+ cmGetClientData,
+ cmGetTotalArgumentSize,
+ cmFreeArguments,
+ cmSetClientData,
+ cmSetError,
+ cmAddCacheDefinition,
+ cmAddCustomCommand,
+ cmAddDefineFlag,
+ cmAddDefinition,
+ cmAddExecutable,
+ cmAddLibrary,
+ cmAddLinkDirectoryForTarget,
+ cmAddLinkLibraryForTarget,
+ cmAddUtilityCommand,
+ cmCommandExists,
+ cmExecuteCommand,
+ cmExpandSourceListArguments,
+ cmExpandVariablesInString,
+ cmGetCacheMajorVersion,
+ cmGetCacheMinorVersion,
+ cmGetCurrentDirectory,
+ cmGetCurrentOutputDirectory,
+ cmGetDefinition,
+ cmGetHomeDirectory,
+ cmGetHomeOutputDirectory,
+ cmGetMajorVersion,
+ cmGetMinorVersion,
+ cmGetProjectName,
+ cmGetStartDirectory,
+ cmGetStartOutputDirectory,
+ cmIsOn,
+
+ cmAddSource,
+ cmCreateSourceFile,
+ cmDestroySourceFile,
+ cmGetSource,
+ cmSourceFileAddDepend,
+ cmSourceFileGetProperty,
+ cmSourceFileGetPropertyAsBool,
+ cmSourceFileGetSourceName,
+ cmSourceFileGetFullPath,
+ cmSourceFileSetName,
+ cmSourceFileSetName2,
+ cmSourceFileSetProperty,
+
+ cmCapitalized,
+ cmCopyFileIfDifferent,
+ cmGetFilenameWithoutExtension,
+ cmGetFilenamePath,
+ cmRemoveFile,
+ cmFree,
+
+ cmAddCustomCommandToOutput,
+ cmAddCustomCommandToTarget,
+ cmDisplayStatus,
+ cmCreateNewSourceFile,
+ DefineSourceFileProperty,
+};
+
diff --git a/Source/cmCPluginAPI.h b/Source/cmCPluginAPI.h
new file mode 100644
index 000000000..fd5a4f819
--- /dev/null
+++ b/Source/cmCPluginAPI.h
@@ -0,0 +1,243 @@
+/*============================================================================
+ 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.
+============================================================================*/
+/* This header file defines the API that loadable commands can use. In many
+ of these commands C++ instances of cmMakefile of cmSourceFile are passed
+ in as arguments or returned. In these cases they are passed as a void *
+ argument. In the function prototypes mf is used to represent a makefile
+ and sf is used to represent a source file. The functions are grouped
+ loosely into four groups 1) Utility 2) cmMakefile 3) cmSourceFile 4)
+ cmSystemTools. Within each grouping functions are listed alphabetically */
+/*=========================================================================*/
+#ifndef cmCPluginAPI_h
+#define cmCPluginAPI_h
+
+#define CMAKE_VERSION_MAJOR 2
+#define CMAKE_VERSION_MINOR 5
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __WATCOMC__
+#define CCONV __cdecl
+#else
+#define CCONV
+#endif
+/*=========================================================================
+this is the structure of function entry points that a plugin may call. This
+structure must be kept in sync with the static decaled at the bottom of
+cmCPLuginAPI.cxx
+=========================================================================*/
+typedef struct
+{
+ /*=========================================================================
+ Here we define the set of functions that a plugin may call. The first goup
+ of functions are utility functions that are specific to the plugin API
+ =========================================================================*/
+ /* set/Get the ClientData in the cmLoadedCommandInfo structure, this is how
+ information is passed from the InitialPass to FInalPass for commands
+ that need a FinalPass and need information from the InitialPass */
+ void *(CCONV *GetClientData) (void *info);
+ /* return the summed size in characters of all the arguments */
+ int (CCONV *GetTotalArgumentSize) (int argc, char **argv);
+ /* free all the memory associated with an argc, argv pair */
+ void (CCONV *FreeArguments) (int argc, char **argv);
+ /* set/Get the ClientData in the cmLoadedCommandInfo structure, this is how
+ information is passed from the InitialPass to FInalPass for commands
+ that need a FinalPass and need information from the InitialPass */
+ void (CCONV *SetClientData) (void *info, void *cd);
+ /* when an error occurs, call this function to set the error string */
+ void (CCONV *SetError) (void *info, const char *err);
+
+ /*=========================================================================
+ The following functions all directly map to methods in the cmMakefile
+ class. See cmMakefile.h for descriptions of what each method does. All of
+ these methods take the void * makefile pointer as their first argument.
+ =========================================================================*/
+ void (CCONV *AddCacheDefinition) (void *mf, const char* name,
+ const char* value,
+ const char* doc, int cachetype);
+ void (CCONV *AddCustomCommand) (void *mf, const char* source,
+ const char* command,
+ int numArgs, const char **args,
+ int numDepends, const char **depends,
+ int numOutputs, const char **outputs,
+ const char *target);
+ void (CCONV *AddDefineFlag) (void *mf, const char* definition);
+ void (CCONV *AddDefinition) (void *mf, const char* name,
+ const char* value);
+ void (CCONV *AddExecutable) (void *mf, const char *exename,
+ int numSrcs, const char **srcs, int win32);
+ void (CCONV *AddLibrary) (void *mf, const char *libname,
+ int shared, int numSrcs, const char **srcs);
+ void (CCONV *AddLinkDirectoryForTarget) (void *mf, const char *tgt,
+ const char* d);
+ void (CCONV *AddLinkLibraryForTarget) (void *mf, const char *tgt,
+ const char *libname, int libtype);
+ void (CCONV *AddUtilityCommand) (void *mf, const char* utilityName,
+ const char *command, const char *arguments,
+ int all, int numDepends, const char **depends,
+ int numOutputs, const char **outputs);
+ int (CCONV *CommandExists) (void *mf, const char* name);
+ int (CCONV *ExecuteCommand) (void *mf, const char *name,
+ int numArgs, const char **args);
+ void (CCONV *ExpandSourceListArguments) (void *mf,int argc,
+ const char **argv,
+ int *resArgc, char ***resArgv,
+ unsigned int startArgumentIndex);
+ char *(CCONV *ExpandVariablesInString) (void *mf, const char *source,
+ int escapeQuotes, int atOnly);
+ unsigned int (CCONV *GetCacheMajorVersion) (void *mf);
+ unsigned int (CCONV *GetCacheMinorVersion) (void *mf);
+ const char* (CCONV *GetCurrentDirectory) (void *mf);
+ const char* (CCONV *GetCurrentOutputDirectory) (void *mf);
+ const char* (CCONV *GetDefinition) (void *mf, const char *def);
+ const char* (CCONV *GetHomeDirectory) (void *mf);
+ const char* (CCONV *GetHomeOutputDirectory) (void *mf);
+ unsigned int (CCONV *GetMajorVersion) (void *mf);
+ unsigned int (CCONV *GetMinorVersion) (void *mf);
+ const char* (CCONV *GetProjectName) (void *mf);
+ const char* (CCONV *GetStartDirectory) (void *mf);
+ const char* (CCONV *GetStartOutputDirectory) (void *mf);
+ int (CCONV *IsOn) (void *mf, const char* name);
+
+
+ /*=========================================================================
+ The following functions are designed to operate or manipulate
+ cmSourceFiles. Please see cmSourceFile.h for additional information on many
+ of these methods. Some of these methods are in cmMakefile.h.
+ =========================================================================*/
+ void *(CCONV *AddSource) (void *mf, void *sf);
+ void *(CCONV *CreateSourceFile) ();
+ void (CCONV *DestroySourceFile) (void *sf);
+ void *(CCONV *GetSource) (void *mf, const char* sourceName);
+ void (CCONV *SourceFileAddDepend) (void *sf, const char *depend);
+ const char *(CCONV *SourceFileGetProperty) (void *sf, const char *prop);
+ int (CCONV *SourceFileGetPropertyAsBool) (void *sf, const char *prop);
+ const char *(CCONV *SourceFileGetSourceName) (void *sf);
+ const char *(CCONV *SourceFileGetFullPath) (void *sf);
+ void (CCONV *SourceFileSetName) (void *sf, const char* name,
+ const char* dir,
+ int numSourceExtensions,
+ const char **sourceExtensions,
+ int numHeaderExtensions,
+ const char **headerExtensions);
+ void (CCONV *SourceFileSetName2) (void *sf, const char* name,
+ const char* dir,
+ const char *ext, int headerFileOnly);
+ void (CCONV *SourceFileSetProperty) (void *sf, const char *prop,
+ const char *value);
+
+
+ /*=========================================================================
+ The following methods are from cmSystemTools.h see that file for specific
+ documentation on each method.
+ =========================================================================*/
+ char *(CCONV *Capitalized)(const char *);
+ void (CCONV *CopyFileIfDifferent)(const char *f1, const char *f2);
+ char *(CCONV *GetFilenameWithoutExtension)(const char *);
+ char *(CCONV *GetFilenamePath)(const char *);
+ void (CCONV *RemoveFile)(const char *f1);
+ void (CCONV *Free)(void *);
+
+ /*=========================================================================
+ The following are new functions added after 1.6
+ =========================================================================*/
+ void (CCONV *AddCustomCommandToOutput) (void *mf, const char* output,
+ const char* command,
+ int numArgs, const char **args,
+ const char* main_dependency,
+ int numDepends, const char **depends);
+ void (CCONV *AddCustomCommandToTarget) (void *mf, const char* target,
+ const char* command,
+ int numArgs, const char **args,
+ int commandType);
+
+ /* display status information */
+ void (CCONV *DisplaySatus) (void *info, const char *message);
+
+ /* new functions added after 2.4 */
+ void *(CCONV *CreateNewSourceFile) (void *mf);
+ void (CCONV *DefineSourceFileProperty) (void *mf, const char *name,
+ const char *briefDocs,
+ const char *longDocs,
+ int chained);
+
+ /* this is the end of the C function stub API structure */
+} cmCAPI;
+
+
+/*=========================================================================
+CM_PLUGIN_EXPORT should be used by plugins
+=========================================================================*/
+#ifdef _WIN32
+#define CM_PLUGIN_EXPORT __declspec( dllexport )
+#else
+#define CM_PLUGIN_EXPORT
+#endif
+
+/*=========================================================================
+define the different types of cache entries, see cmCacheManager.h for more
+information
+=========================================================================*/
+#define CM_CACHE_BOOL 0
+#define CM_CACHE_PATH 1
+#define CM_CACHE_FILEPATH 2
+#define CM_CACHE_STRING 3
+#define CM_CACHE_INTERNAL 4
+#define CM_CACHE_STATIC 5
+
+/*=========================================================================
+define the different types of compiles a library may be
+=========================================================================*/
+#define CM_LIBRARY_GENERAL 0
+#define CM_LIBRARY_DEBUG 1
+#define CM_LIBRARY_OPTIMIZED 2
+
+/*=========================================================================
+define the different types of custom commands for a target
+=========================================================================*/
+#define CM_PRE_BUILD 0
+#define CM_PRE_LINK 1
+#define CM_POST_BUILD 2
+
+/*=========================================================================
+Finally we define the key data structures and function prototypes
+=========================================================================*/
+ typedef const char* (CCONV *CM_DOC_FUNCTION)();
+ typedef int (CCONV *CM_INITIAL_PASS_FUNCTION)(void *info, void *mf,
+ int argc, char *[]);
+ typedef void (CCONV *CM_FINAL_PASS_FUNCTION)(void *info, void *mf);
+ typedef void (CCONV *CM_DESTRUCTOR_FUNCTION)(void *info);
+
+ typedef struct {
+ unsigned long reserved1; /* Reserved for future use. DO NOT USE. */
+ unsigned long reserved2; /* Reserved for future use. DO NOT USE. */
+ cmCAPI *CAPI;
+ int m_Inherited; /* this ivar is no longer used in CMake 2.2 or later */
+ CM_INITIAL_PASS_FUNCTION InitialPass;
+ CM_FINAL_PASS_FUNCTION FinalPass;
+ CM_DESTRUCTOR_FUNCTION Destructor;
+ CM_DOC_FUNCTION GetTerseDocumentation;
+ CM_DOC_FUNCTION GetFullDocumentation;
+ const char *Name;
+ char *Error;
+ void *ClientData;
+ } cmLoadedCommandInfo;
+
+ typedef void (CCONV *CM_INIT_FUNCTION)(cmLoadedCommandInfo *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
new file mode 100644
index 000000000..b5687e39a
--- /dev/null
+++ b/Source/cmCTest.cxx
@@ -0,0 +1,3225 @@
+/*============================================================================
+ 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 "cm_curl.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 "cmDynamicLoader.h"
+#include "cmGeneratedFileStream.h"
+#include "cmXMLSafe.h"
+#include "cmVersionMacros.h"
+#include "cmCTestCommand.h"
+#include "cmCTestStartCommand.h"
+
+#include "cmCTestBuildHandler.h"
+#include "cmCTestBuildAndTestHandler.h"
+#include "cmCTestConfigureHandler.h"
+#include "cmCTestCoverageHandler.h"
+#include "cmCTestMemCheckHandler.h"
+#include "cmCTestScriptHandler.h"
+#include "cmCTestSubmitHandler.h"
+#include "cmCTestTestHandler.h"
+#include "cmCTestUpdateHandler.h"
+#include "cmCTestUploadHandler.h"
+
+#include "cmVersion.h"
+
+#include <cmsys/RegularExpression.hxx>
+#include <cmsys/Process.h>
+#include <cmsys/Glob.hxx>
+
+#include <stdlib.h>
+#include <math.h>
+#include <float.h>
+#include <ctype.h>
+
+#include <cmsys/auto_ptr.hxx>
+
+#include <cm_zlib.h>
+#include <cmsys/Base64.h>
+
+#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
+
+//----------------------------------------------------------------------
+struct tm* cmCTest::GetNightlyTime(std::string str,
+ bool tomorrowtag)
+{
+ struct tm* lctime;
+ time_t tctime = time(0);
+ lctime = gmtime(&tctime);
+ char buf[1024];
+ // add todays year day and month to the time in str because
+ // curl_getdate no longer assumes the day is today
+ sprintf(buf, "%d%02d%02d %s",
+ lctime->tm_year+1900,
+ lctime->tm_mon +1,
+ lctime->tm_mday,
+ str.c_str());
+ cmCTestLog(this, OUTPUT, "Determine Nightly Start Time" << std::endl
+ << " Specified time: " << str.c_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
+ //is the time at which the nightly dashboard was opened or
+ //will be opened on the date of the current client machine.
+ //As such, this time may be in the past or in the future.
+ time_t ntime = curl_getdate(buf, &tctime);
+ cmCTestLog(this, DEBUG, " Get curl time: " << ntime << std::endl);
+ tctime = time(0);
+ cmCTestLog(this, DEBUG, " Get the current time: " << tctime << std::endl);
+
+ const int dayLength = 24 * 60 * 60;
+ cmCTestLog(this, DEBUG, "Seconds: " << tctime << std::endl);
+ while ( ntime > tctime )
+ {
+ // If nightlySeconds is in the past, this is the current
+ // open dashboard, then return nightlySeconds. If
+ // nightlySeconds is in the future, this is the next
+ // dashboard to be opened, so subtract 24 hours to get the
+ // time of the current open dashboard
+ ntime -= dayLength;
+ cmCTestLog(this, DEBUG, "Pick yesterday" << std::endl);
+ cmCTestLog(this, DEBUG, " Future time, subtract day: " << ntime
+ << std::endl);
+ }
+ while ( tctime > (ntime + dayLength) )
+ {
+ ntime += dayLength;
+ cmCTestLog(this, DEBUG, " Past time, add day: " << ntime << std::endl);
+ }
+ cmCTestLog(this, DEBUG, "nightlySeconds: " << ntime << std::endl);
+ cmCTestLog(this, DEBUG, " Current time: " << tctime
+ << " Nightly time: " << ntime << std::endl);
+ if ( tomorrowtag )
+ {
+ cmCTestLog(this, OUTPUT, " Use future tag, Add a day" << std::endl);
+ ntime += dayLength;
+ }
+ lctime = gmtime(&ntime);
+ return lctime;
+}
+
+//----------------------------------------------------------------------
+std::string cmCTest::CleanString(const std::string& str)
+{
+ std::string::size_type spos = str.find_first_not_of(" \n\t\r\f\v");
+ std::string::size_type epos = str.find_last_not_of(" \n\t\r\f\v");
+ if ( spos == str.npos )
+ {
+ return std::string();
+ }
+ if ( epos != str.npos )
+ {
+ epos = epos - spos + 1;
+ }
+ return str.substr(spos, epos);
+}
+
+//----------------------------------------------------------------------
+std::string cmCTest::CurrentTime()
+{
+ time_t currenttime = time(0);
+ struct tm* t = localtime(&currenttime);
+ //return ::CleanString(ctime(&currenttime));
+ char current_time[1024];
+ if ( this->ShortDateFormat )
+ {
+ strftime(current_time, 1000, "%b %d %H:%M %Z", t);
+ }
+ else
+ {
+ 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();
+}
+
+//----------------------------------------------------------------------
+std::string cmCTest::GetCostDataFile()
+{
+ std::string fname = this->GetCTestConfiguration("CostDataFile");
+ if(fname == "")
+ {
+ fname= this->GetBinaryDir() + "/Testing/Temporary/CTestCostData.txt";
+ }
+ return fname;
+}
+
+#ifdef CMAKE_BUILD_WITH_CMAKE
+//----------------------------------------------------------------------------
+static size_t
+HTTPResponseCallback(void *ptr, size_t size, size_t nmemb, void *data)
+{
+ register int realsize = (int)(size * nmemb);
+
+ std::string *response
+ = static_cast<std::string*>(data);
+ const char* chPtr = static_cast<char*>(ptr);
+ *response += chPtr;
+
+ return realsize;
+}
+
+//----------------------------------------------------------------------------
+int cmCTest::HTTPRequest(std::string url, HTTPMethod method,
+ std::string& response,
+ std::string fields,
+ std::string putFile, int timeout)
+{
+ CURL* curl;
+ FILE* file;
+ ::curl_global_init(CURL_GLOBAL_ALL);
+ curl = ::curl_easy_init();
+
+ //set request options based on method
+ switch(method)
+ {
+ case cmCTest::HTTP_POST:
+ ::curl_easy_setopt(curl, CURLOPT_POST, 1);
+ ::curl_easy_setopt(curl, CURLOPT_POSTFIELDS, fields.c_str());
+ break;
+ case cmCTest::HTTP_PUT:
+ if(!cmSystemTools::FileExists(putFile.c_str()))
+ {
+ response = "Error: File ";
+ response += putFile + " does not exist.\n";
+ return -1;
+ }
+ ::curl_easy_setopt(curl, CURLOPT_PUT, 1);
+ file = ::fopen(putFile.c_str(), "rb");
+ ::curl_easy_setopt(curl, CURLOPT_INFILE, file);
+ //fall through to append GET fields
+ case cmCTest::HTTP_GET:
+ if(fields.size())
+ {
+ url += "?" + fields;
+ }
+ break;
+ default:
+ break;
+ }
+
+ ::curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
+ ::curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout);
+ ::curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
+
+ //set response options
+ ::curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, HTTPResponseCallback);
+ ::curl_easy_setopt(curl, CURLOPT_FILE, (void *)&response);
+ ::curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);
+
+ CURLcode res = ::curl_easy_perform(curl);
+
+ ::curl_easy_cleanup(curl);
+ ::curl_global_cleanup();
+
+ return static_cast<int>(res);
+}
+#endif
+
+//----------------------------------------------------------------------
+std::string cmCTest::MakeURLSafe(const std::string& str)
+{
+ cmOStringStream ost;
+ char buffer[10];
+ for ( std::string::size_type pos = 0; pos < str.size(); pos ++ )
+ {
+ unsigned char ch = str[pos];
+ if ( ( ch > 126 || ch < 32 ||
+ ch == '&' ||
+ ch == '%' ||
+ ch == '+' ||
+ ch == '=' ||
+ ch == '@'
+ ) && ch != 9 )
+ {
+ sprintf(buffer, "%02x;", (unsigned int)ch);
+ ost << buffer;
+ }
+ else
+ {
+ ost << ch;
+ }
+ }
+ return ost.str();
+}
+
+//----------------------------------------------------------------------------
+std::string cmCTest::DecodeURL(const std::string& in)
+{
+ std::string out;
+ for(const char* c = in.c_str(); *c; ++c)
+ {
+ if(*c == '%' && isxdigit(*(c+1)) && isxdigit(*(c+2)))
+ {
+ char buf[3] = {*(c+1), *(c+2), 0};
+ out.append(1, char(strtoul(buf, 0, 16)));
+ c += 2;
+ }
+ else
+ {
+ out.append(1, *c);
+ }
+ }
+ return out;
+}
+
+//----------------------------------------------------------------------
+cmCTest::cmCTest()
+{
+ this->LabelSummary = true;
+ this->ParallelLevel = 1;
+ this->SubmitIndex = 0;
+ this->Failover = false;
+ this->BatchJobs = false;
+ this->ForceNewCTestProcess = false;
+ this->TomorrowTag = false;
+ this->Verbose = false;
+
+ this->Debug = false;
+ this->ShowLineNumbers = false;
+ this->Quiet = false;
+ this->ExtraVerbose = false;
+ this->ProduceXML = false;
+ this->ShowOnly = false;
+ this->RunConfigurationScript = false;
+ this->UseHTTP10 = false;
+ this->PrintLabels = false;
+ this->CompressTestOutput = true;
+ this->CompressMemCheckOutput = true;
+ this->TestModel = cmCTest::EXPERIMENTAL;
+ this->MaxTestNameWidth = 30;
+ this->InteractiveDebugMode = true;
+ this->TimeOut = 0;
+ this->GlobalTimeout = 0;
+ this->LastStopTimeout = 24 * 60 * 60;
+ this->CompressXMLFiles = false;
+ this->CTestConfigFile = "";
+ this->ScheduleType = "";
+ this->StopTime = "";
+ this->NextDayStopTime = false;
+ this->OutputLogFile = 0;
+ this->OutputLogFileLastTag = -1;
+ this->SuppressUpdatingCTestConfiguration = false;
+ this->DartVersion = 1;
+ this->OutputTestOutputOnTestFailure = false;
+ this->ComputedCompressTestOutput = false;
+ this->ComputedCompressMemCheckOutput = false;
+ if(cmSystemTools::GetEnv("CTEST_OUTPUT_ON_FAILURE"))
+ {
+ this->OutputTestOutputOnTestFailure = true;
+ }
+ this->InitStreams();
+
+ this->Parts[PartStart].SetName("Start");
+ this->Parts[PartUpdate].SetName("Update");
+ this->Parts[PartConfigure].SetName("Configure");
+ this->Parts[PartBuild].SetName("Build");
+ this->Parts[PartTest].SetName("Test");
+ this->Parts[PartCoverage].SetName("Coverage");
+ this->Parts[PartMemCheck].SetName("MemCheck");
+ this->Parts[PartSubmit].SetName("Submit");
+ this->Parts[PartNotes].SetName("Notes");
+ this->Parts[PartExtraFiles].SetName("ExtraFiles");
+ this->Parts[PartUpload].SetName("Upload");
+
+ // Fill the part name-to-id map.
+ for(Part p = PartStart; p != PartCount; p = Part(p+1))
+ {
+ this->PartMap[cmSystemTools::LowerCase(this->Parts[p].GetName())] = p;
+ }
+
+ this->ShortDateFormat = true;
+
+ this->TestingHandlers["build"] = new cmCTestBuildHandler;
+ this->TestingHandlers["buildtest"] = new cmCTestBuildAndTestHandler;
+ this->TestingHandlers["coverage"] = new cmCTestCoverageHandler;
+ this->TestingHandlers["script"] = new cmCTestScriptHandler;
+ this->TestingHandlers["test"] = new cmCTestTestHandler;
+ this->TestingHandlers["update"] = new cmCTestUpdateHandler;
+ this->TestingHandlers["configure"] = new cmCTestConfigureHandler;
+ this->TestingHandlers["memcheck"] = new cmCTestMemCheckHandler;
+ this->TestingHandlers["submit"] = new cmCTestSubmitHandler;
+ this->TestingHandlers["upload"] = new cmCTestUploadHandler;
+
+ cmCTest::t_TestingHandlers::iterator it;
+ for ( it = this->TestingHandlers.begin();
+ it != this->TestingHandlers.end(); ++ it )
+ {
+ it->second->SetCTestInstance(this);
+ }
+
+ // Make sure we can capture the build tool output.
+ cmSystemTools::EnableVSConsoleOutput();
+}
+
+//----------------------------------------------------------------------
+cmCTest::~cmCTest()
+{
+ cmCTest::t_TestingHandlers::iterator it;
+ for ( it = this->TestingHandlers.begin();
+ it != this->TestingHandlers.end(); ++ it )
+ {
+ delete it->second;
+ it->second = 0;
+ }
+ this->SetOutputLogFileName(0);
+}
+
+void cmCTest::SetParallelLevel(int level)
+{
+ this->ParallelLevel = level < 1 ? 1 : level;
+}
+
+//----------------------------------------------------------------------------
+bool cmCTest::ShouldCompressTestOutput()
+{
+ if(!this->ComputedCompressTestOutput)
+ {
+ std::string cdashVersion = this->GetCDashVersion();
+ //version >= 1.6?
+ bool cdashSupportsGzip = cmSystemTools::VersionCompare(
+ cmSystemTools::OP_GREATER, cdashVersion.c_str(), "1.6") ||
+ cmSystemTools::VersionCompare(cmSystemTools::OP_EQUAL,
+ cdashVersion.c_str(), "1.6");
+ this->CompressTestOutput &= cdashSupportsGzip;
+ this->ComputedCompressTestOutput = true;
+ }
+ return this->CompressTestOutput;
+}
+
+//----------------------------------------------------------------------------
+bool cmCTest::ShouldCompressMemCheckOutput()
+{
+ if(!this->ComputedCompressMemCheckOutput)
+ {
+ std::string cdashVersion = this->GetCDashVersion();
+
+ bool compressionSupported = cmSystemTools::VersionCompare(
+ cmSystemTools::OP_GREATER, cdashVersion.c_str(), "1.9.0");
+ this->CompressMemCheckOutput &= compressionSupported;
+ this->ComputedCompressMemCheckOutput = true;
+ }
+ return this->CompressMemCheckOutput;
+}
+
+//----------------------------------------------------------------------------
+std::string cmCTest::GetCDashVersion()
+{
+#ifdef CMAKE_BUILD_WITH_CMAKE
+ //First query the server. If that fails, fall back to the local setting
+ std::string response;
+ std::string url = "http://";
+ url += this->GetCTestConfiguration("DropSite");
+
+ std::string cdashUri = this->GetCTestConfiguration("DropLocation");
+ cdashUri = cdashUri.substr(0, cdashUri.find("/submit.php"));
+
+ int res = 1;
+ if ( ! cdashUri.empty() )
+ {
+ url += cdashUri + "/api/getversion.php";
+ res = cmCTest::HTTPRequest(url, cmCTest::HTTP_GET, response, "", "", 3);
+ }
+
+ return res ? this->GetCTestConfiguration("CDashVersion") : response;
+#else
+ return this->GetCTestConfiguration("CDashVersion");
+#endif
+}
+
+//----------------------------------------------------------------------------
+cmCTest::Part cmCTest::GetPartFromName(const char* name)
+{
+ // Look up by lower-case to make names case-insensitive.
+ std::string lower_name = cmSystemTools::LowerCase(name);
+ PartMapType::const_iterator i = this->PartMap.find(lower_name);
+ if(i != this->PartMap.end())
+ {
+ return i->second;
+ }
+
+ // The string does not name a valid part.
+ return PartCount;
+}
+
+//----------------------------------------------------------------------
+int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command)
+{
+ cmCTestLog(this, DEBUG, "Here: " << __LINE__ << std::endl);
+ if(!this->InteractiveDebugMode)
+ {
+ this->BlockTestErrorDiagnostics();
+ }
+ else
+ {
+ cmSystemTools::PutEnv("CTEST_INTERACTIVE_DEBUG_MODE=1");
+ }
+
+ this->BinaryDir = binary_dir;
+ cmSystemTools::ConvertToUnixSlashes(this->BinaryDir);
+
+ this->UpdateCTestConfiguration();
+
+ cmCTestLog(this, DEBUG, "Here: " << __LINE__ << std::endl);
+ 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);
+ 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);
+ 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);
+ return 0;
+ }
+
+ if ( this->ProduceXML )
+ {
+ // Verify "Testing" directory exists:
+ //
+ std::string testingDir = this->BinaryDir + "/Testing";
+ if ( cmSystemTools::FileExists(testingDir.c_str()) )
+ {
+ if ( !cmSystemTools::FileIsDirectory(testingDir.c_str()) )
+ {
+ cmCTestLog(this, ERROR_MESSAGE, "File " << testingDir
+ << " is in the place of the testing directory" << std::endl);
+ return 0;
+ }
+ }
+ else
+ {
+ if ( !cmSystemTools::MakeDirectory(testingDir.c_str()) )
+ {
+ cmCTestLog(this, ERROR_MESSAGE, "Cannot create directory "
+ << testingDir << std::endl);
+ return 0;
+ }
+ }
+
+ // Create new "TAG" file or read existing one:
+ //
+ bool createNewTag = true;
+ if (command)
+ {
+ createNewTag = command->ShouldCreateNewTag();
+ }
+
+ std::string tagfile = testingDir + "/TAG";
+ std::ifstream tfin(tagfile.c_str());
+ std::string tag;
+
+ if (createNewTag)
+ {
+ time_t tctime = time(0);
+ if ( this->TomorrowTag )
+ {
+ tctime += ( 24 * 60 * 60 );
+ }
+ struct tm *lctime = gmtime(&tctime);
+ if ( tfin && cmSystemTools::GetLineFromStream(tfin, tag) )
+ {
+ int year = 0;
+ int mon = 0;
+ int day = 0;
+ int hour = 0;
+ int min = 0;
+ sscanf(tag.c_str(), "%04d%02d%02d-%02d%02d",
+ &year, &mon, &day, &hour, &min);
+ if ( year != lctime->tm_year + 1900 ||
+ mon != lctime->tm_mon+1 ||
+ day != lctime->tm_mday )
+ {
+ tag = "";
+ }
+ std::string tagmode;
+ if ( cmSystemTools::GetLineFromStream(tfin, tagmode) )
+ {
+ if (tagmode.size() > 4 && !this->Parts[PartStart])
+ {
+ this->TestModel = cmCTest::GetTestModelFromString(tagmode.c_str());
+ }
+ }
+ tfin.close();
+ }
+ if (tag.size() == 0 || (0 != command) || this->Parts[PartStart])
+ {
+ cmCTestLog(this, DEBUG, "TestModel: " << this->GetTestModelString()
+ << std::endl);
+ cmCTestLog(this, DEBUG, "TestModel: " << this->TestModel << std::endl);
+ if ( this->TestModel == cmCTest::NIGHTLY )
+ {
+ lctime = this->GetNightlyTime(
+ this->GetCTestConfiguration("NightlyStartTime"),
+ this->TomorrowTag);
+ }
+ char datestring[100];
+ sprintf(datestring, "%04d%02d%02d-%02d%02d",
+ lctime->tm_year + 1900,
+ lctime->tm_mon+1,
+ lctime->tm_mday,
+ lctime->tm_hour,
+ lctime->tm_min);
+ tag = datestring;
+ std::ofstream ofs(tagfile.c_str());
+ if ( ofs )
+ {
+ ofs << tag << std::endl;
+ ofs << this->GetTestModelString() << std::endl;
+ }
+ ofs.close();
+ if ( 0 == command )
+ {
+ cmCTestLog(this, OUTPUT, "Create new tag: " << tag << " - "
+ << this->GetTestModelString() << std::endl);
+ }
+ }
+ }
+ else
+ {
+ if ( tfin )
+ {
+ cmSystemTools::GetLineFromStream(tfin, tag);
+ tfin.close();
+ }
+
+ if ( tag.empty() )
+ {
+ cmCTestLog(this, ERROR_MESSAGE,
+ "Cannot read existing TAG file in " << testingDir
+ << std::endl);
+ return 0;
+ }
+
+ cmCTestLog(this, OUTPUT, " Use existing tag: " << tag << " - "
+ << this->GetTestModelString() << std::endl);
+ }
+
+ this->CurrentTag = tag;
+ }
+
+ return 1;
+}
+
+//----------------------------------------------------------------------
+bool cmCTest::InitializeFromCommand(cmCTestStartCommand* command)
+{
+ std::string src_dir
+ = this->GetCTestConfiguration("SourceDirectory").c_str();
+ std::string bld_dir = this->GetCTestConfiguration("BuildDirectory").c_str();
+ this->DartVersion = 1;
+ for(Part p = PartStart; p != PartCount; p = Part(p+1))
+ {
+ this->Parts[p].SubmitFiles.clear();
+ }
+
+ cmMakefile* mf = command->GetMakefile();
+ std::string fname;
+
+ std::string src_dir_fname = src_dir;
+ src_dir_fname += "/CTestConfig.cmake";
+ cmSystemTools::ConvertToUnixSlashes(src_dir_fname);
+
+ std::string bld_dir_fname = bld_dir;
+ bld_dir_fname += "/CTestConfig.cmake";
+ cmSystemTools::ConvertToUnixSlashes(bld_dir_fname);
+
+ if ( cmSystemTools::FileExists(bld_dir_fname.c_str()) )
+ {
+ fname = bld_dir_fname;
+ }
+ else if ( cmSystemTools::FileExists(src_dir_fname.c_str()) )
+ {
+ fname = src_dir_fname;
+ }
+
+ if ( !fname.empty() )
+ {
+ cmCTestLog(this, OUTPUT, " Reading ctest configuration file: "
+ << fname.c_str() << std::endl);
+ bool readit = mf->ReadListFile(mf->GetCurrentListFile(),
+ fname.c_str() );
+ if(!readit)
+ {
+ std::string m = "Could not find include file: ";
+ m += fname;
+ command->SetError(m.c_str());
+ return false;
+ }
+ }
+ else
+ {
+ cmCTestLog(this, WARNING,
+ "Cannot locate CTest configuration: in BuildDirectory: "
+ << bld_dir_fname.c_str() << std::endl);
+ cmCTestLog(this, WARNING,
+ "Cannot locate CTest configuration: in SourceDirectory: "
+ << src_dir_fname.c_str() << std::endl);
+ }
+
+ this->SetCTestConfigurationFromCMakeVariable(mf, "NightlyStartTime",
+ "CTEST_NIGHTLY_START_TIME");
+ this->SetCTestConfigurationFromCMakeVariable(mf, "Site", "CTEST_SITE");
+ this->SetCTestConfigurationFromCMakeVariable(mf, "BuildName",
+ "CTEST_BUILD_NAME");
+ const char* dartVersion = mf->GetDefinition("CTEST_DART_SERVER_VERSION");
+ if ( dartVersion )
+ {
+ this->DartVersion = atoi(dartVersion);
+ if ( this->DartVersion < 0 )
+ {
+ cmCTestLog(this, ERROR_MESSAGE, "Invalid Dart server version: "
+ << dartVersion << ". Please specify the version number."
+ << std::endl);
+ return false;
+ }
+ }
+
+ if ( !this->Initialize(bld_dir.c_str(), command) )
+ {
+ return false;
+ }
+ cmCTestLog(this, OUTPUT, " Use " << this->GetTestModelString()
+ << " tag: " << this->GetCurrentTag() << std::endl);
+ return true;
+}
+
+
+//----------------------------------------------------------------------
+bool cmCTest::UpdateCTestConfiguration()
+{
+ if ( this->SuppressUpdatingCTestConfiguration )
+ {
+ return true;
+ }
+ std::string fileName = this->CTestConfigFile;
+ if ( fileName.empty() )
+ {
+ fileName = this->BinaryDir + "/CTestConfiguration.ini";
+ if ( !cmSystemTools::FileExists(fileName.c_str()) )
+ {
+ fileName = this->BinaryDir + "/DartConfiguration.tcl";
+ }
+ }
+ cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, "UpdateCTestConfiguration from :"
+ << fileName.c_str() << "\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()
+ << std::endl);
+ return false;
+ }
+ }
+ else
+ {
+ cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, "Parse Config file:"
+ << fileName.c_str() << "\n");
+ // parse the dart test file
+ std::ifstream fin(fileName.c_str());
+
+ if(!fin)
+ {
+ return false;
+ }
+
+ char buffer[1024];
+ while ( fin )
+ {
+ buffer[0] = 0;
+ fin.getline(buffer, 1023);
+ buffer[1023] = 0;
+ std::string line = cmCTest::CleanString(buffer);
+ if(line.size() == 0)
+ {
+ continue;
+ }
+ while ( fin && (line[line.size()-1] == '\\') )
+ {
+ line = line.substr(0, line.size()-1);
+ buffer[0] = 0;
+ fin.getline(buffer, 1023);
+ buffer[1023] = 0;
+ line += cmCTest::CleanString(buffer);
+ }
+ if ( line[0] == '#' )
+ {
+ continue;
+ }
+ std::string::size_type cpos = line.find_first_of(":");
+ if ( cpos == line.npos )
+ {
+ continue;
+ }
+ std::string key = line.substr(0, cpos);
+ std::string value
+ = cmCTest::CleanString(line.substr(cpos+1, line.npos));
+ this->CTestConfiguration[key] = value;
+ }
+ fin.close();
+ }
+ if ( !this->GetCTestConfiguration("BuildDirectory").empty() )
+ {
+ this->BinaryDir = this->GetCTestConfiguration("BuildDirectory");
+ cmSystemTools::ChangeDirectory(this->BinaryDir.c_str());
+ }
+ this->TimeOut = atoi(this->GetCTestConfiguration("TimeOut").c_str());
+ if ( this->ProduceXML )
+ {
+ this->CompressXMLFiles = cmSystemTools::IsOn(
+ this->GetCTestConfiguration("CompressSubmission").c_str());
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------
+void cmCTest::BlockTestErrorDiagnostics()
+{
+ cmSystemTools::PutEnv("DART_TEST_FROM_DART=1");
+ cmSystemTools::PutEnv("DASHBOARD_TEST_FROM_CTEST=" CMake_VERSION);
+#if defined(_WIN32)
+ SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
+#elif defined(__BEOS__) || defined(__HAIKU__)
+ disable_debugger(1);
+#endif
+}
+
+//----------------------------------------------------------------------
+void cmCTest::SetTestModel(int mode)
+{
+ this->InteractiveDebugMode = false;
+ this->TestModel = mode;
+}
+
+//----------------------------------------------------------------------
+bool cmCTest::SetTest(const char* ttype, bool report)
+{
+ if ( cmSystemTools::LowerCase(ttype) == "all" )
+ {
+ for(Part p = PartStart; p != PartCount; p = Part(p+1))
+ {
+ this->Parts[p].Enable();
+ }
+ return true;
+ }
+ Part p = this->GetPartFromName(ttype);
+ if(p != PartCount)
+ {
+ this->Parts[p].Enable();
+ return true;
+ }
+ else
+ {
+ if ( report )
+ {
+ cmCTestLog(this, ERROR_MESSAGE, "Don't know about test \"" << ttype
+ << "\" yet..." << std::endl);
+ }
+ return false;
+ }
+}
+
+//----------------------------------------------------------------------
+void cmCTest::Finalize()
+{
+}
+
+//----------------------------------------------------------------------
+bool cmCTest::OpenOutputFile(const std::string& path,
+ const std::string& name, cmGeneratedFileStream& stream,
+ bool compress)
+{
+ std::string testingDir = this->BinaryDir + "/Testing";
+ if ( path.size() > 0 )
+ {
+ testingDir += "/" + path;
+ }
+ if ( cmSystemTools::FileExists(testingDir.c_str()) )
+ {
+ if ( !cmSystemTools::FileIsDirectory(testingDir.c_str()) )
+ {
+ cmCTestLog(this, ERROR_MESSAGE, "File " << testingDir
+ << " is in the place of the testing directory"
+ << std::endl);
+ return false;
+ }
+ }
+ else
+ {
+ if ( !cmSystemTools::MakeDirectory(testingDir.c_str()) )
+ {
+ cmCTestLog(this, ERROR_MESSAGE, "Cannot create directory " << testingDir
+ << std::endl);
+ return false;
+ }
+ }
+ std::string filename = testingDir + "/" + name;
+ stream.Open(filename.c_str());
+ if( !stream )
+ {
+ cmCTestLog(this, ERROR_MESSAGE, "Problem opening file: " << filename
+ << std::endl);
+ return false;
+ }
+ if ( compress )
+ {
+ if ( this->CompressXMLFiles )
+ {
+ stream.SetCompression(true);
+ }
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------
+bool cmCTest::AddIfExists(Part part, const char* file)
+{
+ if ( this->CTestFileExists(file) )
+ {
+ this->AddSubmitFile(part, file);
+ }
+ else
+ {
+ std::string name = file;
+ name += ".gz";
+ if ( this->CTestFileExists(name.c_str()) )
+ {
+ this->AddSubmitFile(part, file);
+ }
+ else
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------
+bool cmCTest::CTestFileExists(const std::string& filename)
+{
+ std::string testingDir = this->BinaryDir + "/Testing/" +
+ this->CurrentTag + "/" + filename;
+ return cmSystemTools::FileExists(testingDir.c_str());
+}
+
+//----------------------------------------------------------------------
+cmCTestGenericHandler* cmCTest::GetInitializedHandler(const char* handler)
+{
+ cmCTest::t_TestingHandlers::iterator it =
+ this->TestingHandlers.find(handler);
+ if ( it == this->TestingHandlers.end() )
+ {
+ return 0;
+ }
+ it->second->Initialize();
+ return it->second;
+}
+
+//----------------------------------------------------------------------
+cmCTestGenericHandler* cmCTest::GetHandler(const char* handler)
+{
+ cmCTest::t_TestingHandlers::iterator it =
+ this->TestingHandlers.find(handler);
+ if ( it == this->TestingHandlers.end() )
+ {
+ return 0;
+ }
+ return it->second;
+}
+
+//----------------------------------------------------------------------
+int cmCTest::ExecuteHandler(const char* shandler)
+{
+ cmCTestGenericHandler* handler = this->GetHandler(shandler);
+ if ( !handler )
+ {
+ return -1;
+ }
+ handler->Initialize();
+ return handler->ProcessHandler();
+}
+
+//----------------------------------------------------------------------
+int cmCTest::ProcessTests()
+{
+ int res = 0;
+ bool notest = true;
+ int update_count = 0;
+
+ for(Part p = PartStart; notest && p != PartCount; p = Part(p+1))
+ {
+ notest = !this->Parts[p];
+ }
+ if (this->Parts[PartUpdate] &&
+ (this->GetRemainingTimeAllowed() - 120 > 0))
+ {
+ cmCTestGenericHandler* uphandler = this->GetHandler("update");
+ uphandler->SetPersistentOption("SourceDirectory",
+ this->GetCTestConfiguration("SourceDirectory").c_str());
+ update_count = uphandler->ProcessHandler();
+ if ( update_count < 0 )
+ {
+ res |= cmCTest::UPDATE_ERRORS;
+ }
+ }
+ if ( this->TestModel == cmCTest::CONTINUOUS && !update_count )
+ {
+ return 0;
+ }
+ if (this->Parts[PartConfigure] &&
+ (this->GetRemainingTimeAllowed() - 120 > 0))
+ {
+ if (this->GetHandler("configure")->ProcessHandler() < 0)
+ {
+ res |= cmCTest::CONFIGURE_ERRORS;
+ }
+ }
+ if (this->Parts[PartBuild] &&
+ (this->GetRemainingTimeAllowed() - 120 > 0))
+ {
+ this->UpdateCTestConfiguration();
+ if (this->GetHandler("build")->ProcessHandler() < 0)
+ {
+ res |= cmCTest::BUILD_ERRORS;
+ }
+ }
+ if ((this->Parts[PartTest] || notest) &&
+ (this->GetRemainingTimeAllowed() - 120 > 0))
+ {
+ this->UpdateCTestConfiguration();
+ if (this->GetHandler("test")->ProcessHandler() < 0)
+ {
+ res |= cmCTest::TEST_ERRORS;
+ }
+ }
+ if (this->Parts[PartCoverage] &&
+ (this->GetRemainingTimeAllowed() - 120 > 0))
+ {
+ this->UpdateCTestConfiguration();
+ if (this->GetHandler("coverage")->ProcessHandler() < 0)
+ {
+ res |= cmCTest::COVERAGE_ERRORS;
+ }
+ }
+ if (this->Parts[PartMemCheck] &&
+ (this->GetRemainingTimeAllowed() - 120 > 0))
+ {
+ this->UpdateCTestConfiguration();
+ if (this->GetHandler("memcheck")->ProcessHandler() < 0)
+ {
+ res |= cmCTest::MEMORY_ERRORS;
+ }
+ }
+ if ( !notest )
+ {
+ std::string notes_dir = this->BinaryDir + "/Testing/Notes";
+ if ( cmSystemTools::FileIsDirectory(notes_dir.c_str()) )
+ {
+ cmsys::Directory d;
+ d.Load(notes_dir.c_str());
+ 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()) )
+ {
+ if ( this->NotesFiles.size() > 0 )
+ {
+ this->NotesFiles += ";";
+ }
+ this->NotesFiles += fullname;
+ this->Parts[PartNotes].Enable();
+ }
+ }
+ }
+ }
+ if (this->Parts[PartNotes])
+ {
+ this->UpdateCTestConfiguration();
+ if ( this->NotesFiles.size() )
+ {
+ this->GenerateNotesFile(this->NotesFiles.c_str());
+ }
+ }
+ if (this->Parts[PartSubmit])
+ {
+ this->UpdateCTestConfiguration();
+ if (this->GetHandler("submit")->ProcessHandler() < 0)
+ {
+ res |= cmCTest::SUBMIT_ERRORS;
+ }
+ }
+ if ( res != 0 )
+ {
+ cmCTestLog(this, ERROR_MESSAGE, "Errors while running CTest"
+ << std::endl);
+ }
+ return res;
+}
+
+//----------------------------------------------------------------------
+std::string cmCTest::GetTestModelString()
+{
+ if ( !this->SpecificTrack.empty() )
+ {
+ return this->SpecificTrack;
+ }
+ switch ( this->TestModel )
+ {
+ case cmCTest::NIGHTLY:
+ return "Nightly";
+ case cmCTest::CONTINUOUS:
+ return "Continuous";
+ }
+ return "Experimental";
+}
+
+//----------------------------------------------------------------------
+int cmCTest::GetTestModelFromString(const char* str)
+{
+ if ( !str )
+ {
+ return cmCTest::EXPERIMENTAL;
+ }
+ std::string rstr = cmSystemTools::LowerCase(str);
+ if ( strncmp(rstr.c_str(), "cont", 4) == 0 )
+ {
+ return cmCTest::CONTINUOUS;
+ }
+ if ( strncmp(rstr.c_str(), "nigh", 4) == 0 )
+ {
+ return cmCTest::NIGHTLY;
+ }
+ return cmCTest::EXPERIMENTAL;
+}
+
+//######################################################################
+//######################################################################
+//######################################################################
+//######################################################################
+
+//----------------------------------------------------------------------
+int cmCTest::RunMakeCommand(const char* command, std::string* output,
+ int* retVal, const char* dir, int timeout, std::ofstream& ofs)
+{
+ // First generate the command and arguments
+ std::vector<cmStdString> args = cmSystemTools::ParseArguments(command);
+
+ if(args.size() < 1)
+ {
+ return false;
+ }
+
+ std::vector<const char*> argv;
+ for(std::vector<cmStdString>::const_iterator a = args.begin();
+ a != args.end(); ++a)
+ {
+ argv.push_back(a->c_str());
+ }
+ argv.push_back(0);
+
+ if ( output )
+ {
+ *output = "";
+ }
+
+ cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, "Run command:");
+ std::vector<const char*>::iterator ait;
+ for ( ait = argv.begin(); ait != argv.end() && *ait; ++ ait )
+ {
+ cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, " \"" << *ait << "\"");
+ }
+ cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, std::endl);
+
+ // Now create process object
+ cmsysProcess* cp = cmsysProcess_New();
+ cmsysProcess_SetCommand(cp, &*argv.begin());
+ cmsysProcess_SetWorkingDirectory(cp, dir);
+ cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1);
+ cmsysProcess_SetTimeout(cp, timeout);
+ cmsysProcess_Execute(cp);
+
+ // Initialize tick's
+ std::string::size_type tick = 0;
+ std::string::size_type tick_len = 1024;
+ std::string::size_type tick_line_len = 50;
+
+ char* data;
+ int length;
+ cmCTestLog(this, HANDLER_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)
+ {
+ if(data[cc] == 0)
+ {
+ data[cc] = '\n';
+ }
+ }
+
+ output->append(data, length);
+ while ( output->size() > (tick * tick_len) )
+ {
+ 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_VERBOSE_OUTPUT, cmCTestLogWrite(data, length));
+ if ( ofs )
+ {
+ ofs << cmCTestLogWrite(data, length);
+ }
+ }
+ cmCTestLog(this, OUTPUT, " Size of output: "
+ << int(double(output->size()) / 1024.0) << "K" << std::endl);
+
+ cmsysProcess_WaitForExit(cp, 0);
+
+ int result = cmsysProcess_GetState(cp);
+
+ if(result == cmsysProcess_State_Exited)
+ {
+ *retVal = cmsysProcess_GetExitValue(cp);
+ cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, "Command exited with the value: "
+ << *retVal << std::endl);
+ }
+ else if(result == cmsysProcess_State_Exception)
+ {
+ *retVal = cmsysProcess_GetExitException(cp);
+ cmCTestLog(this, WARNING, "There was an exception: " << *retVal
+ << std::endl);
+ }
+ else if(result == cmsysProcess_State_Expired)
+ {
+ cmCTestLog(this, WARNING, "There was a timeout" << std::endl);
+ }
+ else if(result == cmsysProcess_State_Error)
+ {
+ *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);
+ }
+
+ cmsysProcess_Delete(cp);
+
+ return result;
+}
+
+//######################################################################
+//######################################################################
+//######################################################################
+//######################################################################
+
+//----------------------------------------------------------------------
+int cmCTest::RunTest(std::vector<const char*> argv,
+ std::string* output, int *retVal,
+ std::ostream* log, double testTimeOut,
+ std::vector<std::string>* environment)
+{
+ bool modifyEnv = (environment && environment->size()>0);
+
+ // determine how much time we have
+ double timeout = this->GetRemainingTimeAllowed() - 120;
+ if (this->TimeOut > 0 && this->TimeOut < timeout)
+ {
+ timeout = this->TimeOut;
+ }
+ if (testTimeOut > 0
+ && testTimeOut < this->GetRemainingTimeAllowed())
+ {
+ timeout = testTimeOut;
+ }
+
+ // always have at least 1 second if we got to here
+ if (timeout <= 0)
+ {
+ timeout = 1;
+ }
+ cmCTestLog(this, HANDLER_VERBOSE_OUTPUT,
+ "Test timeout computed to be: " << timeout << "\n");
+ if(cmSystemTools::SameFile(argv[0], this->CTestSelf.c_str()) &&
+ !this->ForceNewCTestProcess)
+ {
+ cmCTest inst;
+ inst.ConfigType = this->ConfigType;
+ inst.TimeOut = timeout;
+
+ // Capture output of the child ctest.
+ cmOStringStream oss;
+ inst.SetStreams(&oss, &oss);
+
+ std::vector<std::string> args;
+ for(unsigned int i =0; i < argv.size(); ++i)
+ {
+ if(argv[i])
+ {
+ // make sure we pass the timeout in for any build and test
+ // invocations. Since --build-generator is required this is a
+ // good place to check for it, and to add the arguments in
+ if (strcmp(argv[i],"--build-generator") == 0 && timeout > 0)
+ {
+ args.push_back("--test-timeout");
+ cmOStringStream msg;
+ msg << timeout;
+ args.push_back(msg.str());
+ }
+ args.push_back(argv[i]);
+ }
+ }
+ if ( log )
+ {
+ *log << "* Run internal CTest" << std::endl;
+ }
+ std::string oldpath = cmSystemTools::GetCurrentWorkingDirectory();
+
+ cmsys::auto_ptr<cmSystemTools::SaveRestoreEnvironment> saveEnv;
+ if (modifyEnv)
+ {
+ saveEnv.reset(new cmSystemTools::SaveRestoreEnvironment);
+ cmSystemTools::AppendEnv(*environment);
+ }
+
+ *retVal = inst.Run(args, output);
+ *output += oss.str();
+ if ( log )
+ {
+ *log << output->c_str();
+ }
+ 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;
+ }
+ std::vector<char> tempOutput;
+ if ( output )
+ {
+ *output = "";
+ }
+
+ cmsys::auto_ptr<cmSystemTools::SaveRestoreEnvironment> saveEnv;
+ if (modifyEnv)
+ {
+ saveEnv.reset(new cmSystemTools::SaveRestoreEnvironment);
+ cmSystemTools::AppendEnv(*environment);
+ }
+
+ cmsysProcess* cp = cmsysProcess_New();
+ cmsysProcess_SetCommand(cp, &*argv.begin());
+ cmCTestLog(this, DEBUG, "Command is: " << argv[0] << std::endl);
+ if(cmSystemTools::GetRunCommandHideConsole())
+ {
+ cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1);
+ }
+
+ cmsysProcess_SetTimeout(cp, timeout);
+ cmsysProcess_Execute(cp);
+
+ char* data;
+ int length;
+ while(cmsysProcess_WaitForData(cp, &data, &length, 0))
+ {
+ if ( output )
+ {
+ tempOutput.insert(tempOutput.end(), data, data+length);
+ }
+ cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, cmCTestLogWrite(data, length));
+ if ( log )
+ {
+ log->write(data, length);
+ }
+ }
+
+ cmsysProcess_WaitForExit(cp, 0);
+ if(output && tempOutput.begin() != tempOutput.end())
+ {
+ output->append(&*tempOutput.begin(), tempOutput.size());
+ }
+ cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, "-- Process completed"
+ << std::endl);
+
+ int result = cmsysProcess_GetState(cp);
+
+ if(result == cmsysProcess_State_Exited)
+ {
+ *retVal = cmsysProcess_GetExitValue(cp);
+ if(*retVal != 0 && this->OutputTestOutputOnTestFailure)
+ {
+ OutputTestErrors(tempOutput);
+ }
+ }
+ else if(result == cmsysProcess_State_Exception)
+ {
+ if(this->OutputTestOutputOnTestFailure)
+ {
+ OutputTestErrors(tempOutput);
+ }
+ *retVal = cmsysProcess_GetExitException(cp);
+ std::string outerr = "\n*** Exception executing: ";
+ outerr += cmsysProcess_GetExceptionString(cp);
+ *output += outerr;
+ cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, outerr.c_str() << std::endl
+ << std::flush);
+ }
+ else if(result == cmsysProcess_State_Error)
+ {
+ std::string outerr = "\n*** ERROR executing: ";
+ outerr += cmsysProcess_GetErrorString(cp);
+ *output += outerr;
+ cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, outerr.c_str() << std::endl
+ << std::flush);
+ }
+ cmsysProcess_Delete(cp);
+
+ return result;
+}
+
+//----------------------------------------------------------------------
+std::string cmCTest::SafeBuildIdField(const std::string& value)
+{
+ std::string safevalue(value);
+
+ if (safevalue != "")
+ {
+ // Disallow non-filename and non-space whitespace characters.
+ // If they occur, replace them with ""
+ //
+ const char *disallowed = "\\/:*?\"<>|\n\r\t\f\v";
+
+ if (safevalue.find_first_of(disallowed) != value.npos)
+ {
+ std::string::size_type i = 0;
+ std::string::size_type n = strlen(disallowed);
+ char replace[2];
+ replace[1] = 0;
+
+ for (i= 0; i<n; ++i)
+ {
+ replace[0] = disallowed[i];
+ cmSystemTools::ReplaceString(safevalue, replace, "");
+ }
+ }
+
+ safevalue = cmXMLSafe(safevalue).str();
+ }
+
+ if (safevalue == "")
+ {
+ safevalue = "(empty)";
+ }
+
+ return safevalue;
+}
+
+//----------------------------------------------------------------------
+void cmCTest::StartXML(std::ostream& ostr, bool append)
+{
+ if(this->CurrentTag.empty())
+ {
+ cmCTestLog(this, ERROR_MESSAGE,
+ "Current Tag empty, this may mean"
+ " NightlStartTime was not set correctly." << std::endl);
+ cmSystemTools::SetFatalErrorOccured();
+ }
+
+ // find out about the system
+ cmsys::SystemInformation info;
+ info.RunCPUCheck();
+ info.RunOSCheck();
+ info.RunMemoryCheck();
+
+ std::string buildname = cmCTest::SafeBuildIdField(
+ this->GetCTestConfiguration("BuildName"));
+ std::string stamp = cmCTest::SafeBuildIdField(
+ this->CurrentTag + "-" + this->GetTestModelString());
+ 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)
+{
+ cmCTestScriptHandler* ch =
+ static_cast<cmCTestScriptHandler*>(this->GetHandler("script"));
+ cmake* cm = ch->GetCMake();
+ // if no CMake then this is the old style script and props like
+ // this will not work anyway.
+ if(!cm)
+ {
+ return;
+ }
+ // This code should go when cdash is changed to use labels only
+ const char* subproject = cm->GetProperty("SubProject", cmProperty::GLOBAL);
+ if(subproject)
+ {
+ ostr << "<Subproject name=\"" << subproject << "\">\n";
+ const char* labels =
+ ch->GetCMake()->GetProperty("SubProjectLabels", cmProperty::GLOBAL);
+ if(labels)
+ {
+ ostr << " <Labels>\n";
+ 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";
+ }
+ ostr << " </Labels>\n";
+ }
+ ostr << "</Subproject>\n";
+ }
+
+ // This code should stay when cdash only does label based sub-projects
+ const char* label = cm->GetProperty("Label", cmProperty::GLOBAL);
+ if(label)
+ {
+ ostr << "<Labels>\n";
+ ostr << " <Label>" << label << "</Label>\n";
+ ostr << "</Labels>\n";
+ }
+}
+
+
+//----------------------------------------------------------------------
+void cmCTest::EndXML(std::ostream& ostr)
+{
+ ostr << "</Site>" << std::endl;
+}
+
+//----------------------------------------------------------------------
+int cmCTest::GenerateCTestNotesOutput(std::ostream& os,
+ const cmCTest::VectorOfStrings& files)
+{
+ cmCTest::VectorOfStrings::const_iterator it;
+ os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ << "<?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;
+
+ for ( it = files.begin(); it != files.end(); it ++ )
+ {
+ cmCTestLog(this, OUTPUT, "\tAdd file: " << it->c_str() << 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());
+ if ( ifs )
+ {
+ std::string line;
+ while ( cmSystemTools::GetLineFromStream(ifs, line) )
+ {
+ os << cmXMLSafe(line) << std::endl;
+ }
+ ifs.close();
+ }
+ else
+ {
+ os << "Problem reading file: " << it->c_str() << std::endl;
+ cmCTestLog(this, ERROR_MESSAGE, "Problem reading file: " << it->c_str()
+ << " while creating notes" << std::endl);
+ }
+ os << "</Text>\n"
+ << "</Note>" << std::endl;
+ }
+ os << "</Notes>\n"
+ << "</Site>" << std::endl;
+ return 1;
+}
+
+//----------------------------------------------------------------------
+int cmCTest::GenerateNotesFile(const std::vector<cmStdString> &files)
+{
+ cmGeneratedFileStream ofs;
+ if ( !this->OpenOutputFile(this->CurrentTag, "Notes.xml", ofs) )
+ {
+ cmCTestLog(this, ERROR_MESSAGE, "Cannot open notes file" << std::endl);
+ return 1;
+ }
+
+ this->GenerateCTestNotesOutput(ofs, files);
+ return 0;
+}
+
+//----------------------------------------------------------------------
+int cmCTest::GenerateNotesFile(const char* cfiles)
+{
+ if ( !cfiles )
+ {
+ return 1;
+ }
+
+ std::vector<cmStdString> files;
+
+ cmCTestLog(this, OUTPUT, "Create notes file" << std::endl);
+
+ files = cmSystemTools::SplitString(cfiles, ';');
+ if ( files.size() == 0 )
+ {
+ return 1;
+ }
+
+ return this->GenerateNotesFile(files);
+}
+
+//----------------------------------------------------------------------
+std::string cmCTest::Base64GzipEncodeFile(std::string file)
+{
+ std::string tarFile = file + "_temp.tar.gz";
+ std::vector<cmStdString> files;
+ files.push_back(file);
+
+ if(!cmSystemTools::CreateTar(tarFile.c_str(), files, true, false, 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());
+ 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
+#ifdef _WIN32
+ | std::ios::binary
+#endif
+ );
+ unsigned char *file_buffer = new unsigned char [ len + 1 ];
+ ifs.read(reinterpret_cast<char*>(file_buffer), len);
+ ifs.close();
+
+ unsigned char *encoded_buffer
+ = new unsigned char [ static_cast<int>(
+ static_cast<double>(len) * 1.5 + 5.0) ];
+
+ unsigned long rlen
+ = cmsysBase64_Encode(file_buffer, len, encoded_buffer, 1);
+
+ std::string base64 = "";
+ for(unsigned long i = 0; i < rlen; i++)
+ {
+ base64 += encoded_buffer[i];
+ }
+ delete [] file_buffer;
+ delete [] encoded_buffer;
+
+ return base64;
+}
+
+
+//----------------------------------------------------------------------
+bool cmCTest::SubmitExtraFiles(const std::vector<cmStdString> &files)
+{
+ std::vector<cmStdString>::const_iterator it;
+ for ( it = files.begin();
+ it != files.end();
+ ++ it )
+ {
+ if ( !cmSystemTools::FileExists(it->c_str()) )
+ {
+ cmCTestLog(this, ERROR_MESSAGE, "Cannot find extra file: "
+ << it->c_str() << " to submit."
+ << std::endl;);
+ return false;
+ }
+ this->AddSubmitFile(PartExtraFiles, it->c_str());
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------
+bool cmCTest::SubmitExtraFiles(const char* cfiles)
+{
+ if ( !cfiles )
+ {
+ return 1;
+ }
+
+ std::vector<cmStdString> files;
+
+ cmCTestLog(this, OUTPUT, "Submit extra files" << std::endl);
+
+ files = cmSystemTools::SplitString(cfiles, ';');
+ if ( files.size() == 0 )
+ {
+ return 1;
+ }
+
+ return this->SubmitExtraFiles(files);
+}
+
+
+//-------------------------------------------------------
+// for a -D argument convert the next argument into
+// the proper list of dashboard steps via SetTest
+bool cmCTest::AddTestsForDashboardType(std::string &targ)
+{
+ if ( targ == "Experimental" )
+ {
+ this->SetTestModel(cmCTest::EXPERIMENTAL);
+ this->SetTest("Start");
+ this->SetTest("Configure");
+ this->SetTest("Build");
+ this->SetTest("Test");
+ this->SetTest("Coverage");
+ this->SetTest("Submit");
+ }
+ else if ( targ == "ExperimentalStart" )
+ {
+ this->SetTestModel(cmCTest::EXPERIMENTAL);
+ this->SetTest("Start");
+ }
+ else if ( targ == "ExperimentalUpdate" )
+ {
+ this->SetTestModel(cmCTest::EXPERIMENTAL);
+ this->SetTest("Update");
+ }
+ else if ( targ == "ExperimentalConfigure" )
+ {
+ this->SetTestModel(cmCTest::EXPERIMENTAL);
+ this->SetTest("Configure");
+ }
+ else if ( targ == "ExperimentalBuild" )
+ {
+ this->SetTestModel(cmCTest::EXPERIMENTAL);
+ this->SetTest("Build");
+ }
+ else if ( targ == "ExperimentalTest" )
+ {
+ this->SetTestModel(cmCTest::EXPERIMENTAL);
+ this->SetTest("Test");
+ }
+ else if ( targ == "ExperimentalMemCheck"
+ || targ == "ExperimentalPurify" )
+ {
+ this->SetTestModel(cmCTest::EXPERIMENTAL);
+ this->SetTest("MemCheck");
+ }
+ else if ( targ == "ExperimentalCoverage" )
+ {
+ this->SetTestModel(cmCTest::EXPERIMENTAL);
+ this->SetTest("Coverage");
+ }
+ else if ( targ == "ExperimentalSubmit" )
+ {
+ this->SetTestModel(cmCTest::EXPERIMENTAL);
+ this->SetTest("Submit");
+ }
+ else if ( targ == "Continuous" )
+ {
+ this->SetTestModel(cmCTest::CONTINUOUS);
+ this->SetTest("Start");
+ this->SetTest("Update");
+ this->SetTest("Configure");
+ this->SetTest("Build");
+ this->SetTest("Test");
+ this->SetTest("Coverage");
+ this->SetTest("Submit");
+ }
+ else if ( targ == "ContinuousStart" )
+ {
+ this->SetTestModel(cmCTest::CONTINUOUS);
+ this->SetTest("Start");
+ }
+ else if ( targ == "ContinuousUpdate" )
+ {
+ this->SetTestModel(cmCTest::CONTINUOUS);
+ this->SetTest("Update");
+ }
+ else if ( targ == "ContinuousConfigure" )
+ {
+ this->SetTestModel(cmCTest::CONTINUOUS);
+ this->SetTest("Configure");
+ }
+ else if ( targ == "ContinuousBuild" )
+ {
+ this->SetTestModel(cmCTest::CONTINUOUS);
+ this->SetTest("Build");
+ }
+ else if ( targ == "ContinuousTest" )
+ {
+ this->SetTestModel(cmCTest::CONTINUOUS);
+ this->SetTest("Test");
+ }
+ else if ( targ == "ContinuousMemCheck"
+ || targ == "ContinuousPurify" )
+ {
+ this->SetTestModel(cmCTest::CONTINUOUS);
+ this->SetTest("MemCheck");
+ }
+ else if ( targ == "ContinuousCoverage" )
+ {
+ this->SetTestModel(cmCTest::CONTINUOUS);
+ this->SetTest("Coverage");
+ }
+ else if ( targ == "ContinuousSubmit" )
+ {
+ this->SetTestModel(cmCTest::CONTINUOUS);
+ this->SetTest("Submit");
+ }
+ else if ( targ == "Nightly" )
+ {
+ this->SetTestModel(cmCTest::NIGHTLY);
+ this->SetTest("Start");
+ this->SetTest("Update");
+ this->SetTest("Configure");
+ this->SetTest("Build");
+ this->SetTest("Test");
+ this->SetTest("Coverage");
+ this->SetTest("Submit");
+ }
+ else if ( targ == "NightlyStart" )
+ {
+ this->SetTestModel(cmCTest::NIGHTLY);
+ this->SetTest("Start");
+ }
+ else if ( targ == "NightlyUpdate" )
+ {
+ this->SetTestModel(cmCTest::NIGHTLY);
+ this->SetTest("Update");
+ }
+ else if ( targ == "NightlyConfigure" )
+ {
+ this->SetTestModel(cmCTest::NIGHTLY);
+ this->SetTest("Configure");
+ }
+ else if ( targ == "NightlyBuild" )
+ {
+ this->SetTestModel(cmCTest::NIGHTLY);
+ this->SetTest("Build");
+ }
+ else if ( targ == "NightlyTest" )
+ {
+ this->SetTestModel(cmCTest::NIGHTLY);
+ this->SetTest("Test");
+ }
+ else if ( targ == "NightlyMemCheck"
+ || targ == "NightlyPurify" )
+ {
+ this->SetTestModel(cmCTest::NIGHTLY);
+ this->SetTest("MemCheck");
+ }
+ else if ( targ == "NightlyCoverage" )
+ {
+ this->SetTestModel(cmCTest::NIGHTLY);
+ this->SetTest("Coverage");
+ }
+ else if ( targ == "NightlySubmit" )
+ {
+ this->SetTestModel(cmCTest::NIGHTLY);
+ this->SetTest("Submit");
+ }
+ else if ( targ == "MemoryCheck" )
+ {
+ this->SetTestModel(cmCTest::EXPERIMENTAL);
+ this->SetTest("Start");
+ this->SetTest("Configure");
+ this->SetTest("Build");
+ this->SetTest("MemCheck");
+ this->SetTest("Coverage");
+ this->SetTest("Submit");
+ }
+ else if ( targ == "NightlyMemoryCheck" )
+ {
+ this->SetTestModel(cmCTest::NIGHTLY);
+ this->SetTest("Start");
+ this->SetTest("Update");
+ this->SetTest("Configure");
+ this->SetTest("Build");
+ this->SetTest("MemCheck");
+ this->SetTest("Coverage");
+ this->SetTest("Submit");
+ }
+ else
+ {
+ return false;
+ }
+ return true;
+}
+
+
+//----------------------------------------------------------------------
+void cmCTest::ErrorMessageUnknownDashDValue(std::string &val)
+{
+ cmCTestLog(this, ERROR_MESSAGE,
+ "CTest -D called with incorrect option: " << val << std::endl);
+
+ cmCTestLog(this, ERROR_MESSAGE,
+ "Available options are:" << std::endl
+ << " ctest -D Continuous" << std::endl
+ << " ctest -D Continuous(Start|Update|Configure|Build)" << std::endl
+ << " ctest -D Continuous(Test|Coverage|MemCheck|Submit)" << std::endl
+ << " ctest -D Experimental" << std::endl
+ << " ctest -D Experimental(Start|Update|Configure|Build)" << std::endl
+ << " ctest -D Experimental(Test|Coverage|MemCheck|Submit)" << std::endl
+ << " ctest -D Nightly" << std::endl
+ << " ctest -D Nightly(Start|Update|Configure|Build)" << std::endl
+ << " ctest -D Nightly(Test|Coverage|MemCheck|Submit)" << std::endl
+ << " ctest -D NightlyMemoryCheck" << std::endl);
+}
+
+
+//----------------------------------------------------------------------
+bool cmCTest::CheckArgument(const std::string& arg, const char* varg1,
+ const char* varg2)
+{
+ return (varg1 && arg == varg1) || (varg2 && arg == varg2);
+}
+
+
+//----------------------------------------------------------------------
+// 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)
+{
+ std::string arg = args[i];
+
+ if(this->CheckArgument(arg, "-F"))
+ {
+ this->Failover = true;
+ }
+ if(this->CheckArgument(arg, "-j", "--parallel") && i < args.size() - 1)
+ {
+ i++;
+ int plevel = atoi(args[i].c_str());
+ this->SetParallelLevel(plevel);
+ }
+ else if(arg.find("-j") == 0)
+ {
+ int plevel = atoi(arg.substr(2).c_str());
+ this->SetParallelLevel(plevel);
+ }
+
+ if(this->CheckArgument(arg, "--no-compress-output"))
+ {
+ this->CompressTestOutput = false;
+ this->CompressMemCheckOutput = false;
+ }
+
+ if(this->CheckArgument(arg, "--print-labels"))
+ {
+ this->PrintLabels = true;
+ }
+
+ if(this->CheckArgument(arg, "--http1.0"))
+ {
+ this->UseHTTP10 = true;
+ }
+
+ if(this->CheckArgument(arg, "--timeout") && i < args.size() - 1)
+ {
+ i++;
+ double timeout = (double)atof(args[i].c_str());
+ this->GlobalTimeout = timeout;
+ }
+
+ if(this->CheckArgument(arg, "--stop-time") && i < args.size() - 1)
+ {
+ i++;
+ this->SetStopTime(args[i]);
+ }
+
+ if(this->CheckArgument(arg, "-C", "--build-config") &&
+ i < args.size() - 1)
+ {
+ i++;
+ this->SetConfigType(args[i].c_str());
+ }
+
+ if(this->CheckArgument(arg, "--debug"))
+ {
+ this->Debug = true;
+ this->ShowLineNumbers = true;
+ }
+ if(this->CheckArgument(arg, "--track") && i < args.size() - 1)
+ {
+ i++;
+ this->SpecificTrack = args[i];
+ }
+ if(this->CheckArgument(arg, "--show-line-numbers"))
+ {
+ this->ShowLineNumbers = true;
+ }
+ if(this->CheckArgument(arg, "--no-label-summary"))
+ {
+ this->LabelSummary = false;
+ }
+ if(this->CheckArgument(arg, "-Q", "--quiet"))
+ {
+ this->Quiet = true;
+ }
+ if(this->CheckArgument(arg, "-V", "--verbose"))
+ {
+ this->Verbose = true;
+ }
+ if(this->CheckArgument(arg, "-B"))
+ {
+ this->BatchJobs = true;
+ }
+ if(this->CheckArgument(arg, "-VV", "--extra-verbose"))
+ {
+ this->ExtraVerbose = true;
+ this->Verbose = true;
+ }
+ if(this->CheckArgument(arg, "--output-on-failure"))
+ {
+ this->OutputTestOutputOnTestFailure = true;
+ }
+
+ if(this->CheckArgument(arg, "-N", "--show-only"))
+ {
+ this->ShowOnly = true;
+ }
+
+ if(this->CheckArgument(arg, "-O", "--output-log") && i < args.size() - 1 )
+ {
+ i++;
+ this->SetOutputLogFileName(args[i].c_str());
+ }
+
+ if(this->CheckArgument(arg, "--tomorrow-tag"))
+ {
+ this->TomorrowTag = true;
+ }
+ if(this->CheckArgument(arg, "--force-new-ctest-process"))
+ {
+ this->ForceNewCTestProcess = true;
+ }
+ if(this->CheckArgument(arg, "-W", "--max-width") && i < args.size() - 1)
+ {
+ i++;
+ this->MaxTestNameWidth = atoi(args[i].c_str());
+ }
+ if(this->CheckArgument(arg, "--interactive-debug-mode") &&
+ i < args.size() - 1 )
+ {
+ i++;
+ this->InteractiveDebugMode = cmSystemTools::IsOn(args[i].c_str());
+ }
+ if(this->CheckArgument(arg, "--submit-index") && i < args.size() - 1 )
+ {
+ i++;
+ this->SubmitIndex = atoi(args[i].c_str());
+ if ( this->SubmitIndex < 0 )
+ {
+ this->SubmitIndex = 0;
+ }
+ }
+
+ if(this->CheckArgument(arg, "--overwrite") && i < args.size() - 1)
+ {
+ i++;
+ this->AddCTestConfigurationOverwrite(args[i].c_str());
+ }
+ if(this->CheckArgument(arg, "-A", "--add-notes") && i < args.size() - 1)
+ {
+ this->ProduceXML = true;
+ this->SetTest("Notes");
+ i++;
+ this->SetNotesFiles(args[i].c_str());
+ }
+
+ // options that control what tests are run
+ if(this->CheckArgument(arg, "-I", "--tests-information") &&
+ i < args.size() - 1)
+ {
+ i++;
+ this->GetHandler("test")->SetPersistentOption("TestsToRunInformation",
+ args[i].c_str());
+ this->GetHandler("memcheck")->
+ SetPersistentOption("TestsToRunInformation",args[i].c_str());
+ }
+ if(this->CheckArgument(arg, "-U", "--union"))
+ {
+ this->GetHandler("test")->SetPersistentOption("UseUnion", "true");
+ this->GetHandler("memcheck")->SetPersistentOption("UseUnion", "true");
+ }
+ if(this->CheckArgument(arg, "-R", "--tests-regex") && i < args.size() - 1)
+ {
+ i++;
+ this->GetHandler("test")->
+ SetPersistentOption("IncludeRegularExpression", args[i].c_str());
+ this->GetHandler("memcheck")->
+ SetPersistentOption("IncludeRegularExpression", args[i].c_str());
+ }
+ if(this->CheckArgument(arg, "-L", "--label-regex") && i < args.size() - 1)
+ {
+ i++;
+ this->GetHandler("test")->
+ SetPersistentOption("LabelRegularExpression", args[i].c_str());
+ this->GetHandler("memcheck")->
+ SetPersistentOption("LabelRegularExpression", args[i].c_str());
+ }
+ if(this->CheckArgument(arg, "-LE", "--label-exclude") && i < args.size() - 1)
+ {
+ i++;
+ this->GetHandler("test")->
+ SetPersistentOption("ExcludeLabelRegularExpression", args[i].c_str());
+ this->GetHandler("memcheck")->
+ SetPersistentOption("ExcludeLabelRegularExpression", args[i].c_str());
+ }
+
+ if(this->CheckArgument(arg, "-E", "--exclude-regex") &&
+ i < args.size() - 1)
+ {
+ i++;
+ this->GetHandler("test")->
+ SetPersistentOption("ExcludeRegularExpression", args[i].c_str());
+ this->GetHandler("memcheck")->
+ SetPersistentOption("ExcludeRegularExpression", args[i].c_str());
+ }
+}
+
+//----------------------------------------------------------------------
+// handle the -S -SR and -SP arguments
+void cmCTest::HandleScriptArguments(size_t &i,
+ std::vector<std::string> &args,
+ bool &SRArgumentSpecified)
+{
+ std::string arg = args[i];
+ if(this->CheckArgument(arg, "-SP", "--script-new-process") &&
+ i < args.size() - 1 )
+ {
+ this->RunConfigurationScript = true;
+ i++;
+ cmCTestScriptHandler* ch
+ = static_cast<cmCTestScriptHandler*>(this->GetHandler("script"));
+ // -SR is an internal argument, -SP should be ignored when it is passed
+ if (!SRArgumentSpecified)
+ {
+ ch->AddConfigurationScript(args[i].c_str(),false);
+ }
+ }
+
+ if(this->CheckArgument(arg, "-SR", "--script-run") &&
+ i < args.size() - 1 )
+ {
+ SRArgumentSpecified = true;
+ this->RunConfigurationScript = true;
+ i++;
+ cmCTestScriptHandler* ch
+ = static_cast<cmCTestScriptHandler*>(this->GetHandler("script"));
+ ch->AddConfigurationScript(args[i].c_str(),true);
+ }
+
+ if(this->CheckArgument(arg, "-S", "--script") && i < args.size() - 1 )
+ {
+ this->RunConfigurationScript = true;
+ i++;
+ cmCTestScriptHandler* ch
+ = static_cast<cmCTestScriptHandler*>(this->GetHandler("script"));
+ // -SR is an internal argument, -S should be ignored when it is passed
+ if (!SRArgumentSpecified)
+ {
+ ch->AddConfigurationScript(args[i].c_str(),true);
+ }
+ }
+}
+
+//----------------------------------------------------------------------
+bool cmCTest::AddVariableDefinition(const std::string &arg)
+{
+ std::string name;
+ std::string value;
+ cmCacheManager::CacheEntryType type = cmCacheManager::UNINITIALIZED;
+
+ if (cmCacheManager::ParseEntry(arg.c_str(), name, value, type))
+ {
+ this->Definitions[name] = value;
+ return true;
+ }
+
+ return false;
+}
+
+//----------------------------------------------------------------------
+// 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]);
+ }
+
+ // process the command line arguments
+ for(size_t i=1; i < args.size(); ++i)
+ {
+ // handle the simple commandline arguments
+ this->HandleCommandLineArguments(i,args);
+
+ // handle the script arguments -S -SR -SP
+ this->HandleScriptArguments(i,args,SRArgumentSpecified);
+
+ // handle a request for a dashboard
+ std::string arg = args[i];
+ if(this->CheckArgument(arg, "-D", "--dashboard") && i < args.size() - 1 )
+ {
+ this->ProduceXML = true;
+ i++;
+ std::string targ = args[i];
+ // AddTestsForDashboard parses the dashboard type and converts it
+ // into the separate stages
+ if (!this->AddTestsForDashboardType(targ))
+ {
+ if (!this->AddVariableDefinition(targ))
+ {
+ this->ErrorMessageUnknownDashDValue(targ);
+ executeTests = false;
+ }
+ }
+ }
+
+ // If it's not exactly -D, but it starts with -D, then try to parse out
+ // a variable definition from it, same as CMake does. Unsuccessful
+ // attempts are simply ignored since previous ctest versions ignore
+ // this too. (As well as many other unknown command line args.)
+ //
+ if(arg != "-D" && cmSystemTools::StringStartsWith(arg.c_str(), "-D"))
+ {
+ std::string input = arg.substr(2);
+ this->AddVariableDefinition(input);
+ }
+
+ if(this->CheckArgument(arg, "-T", "--test-action") &&
+ (i < args.size() -1) )
+ {
+ this->ProduceXML = true;
+ i++;
+ if ( !this->SetTest(args[i].c_str(), false) )
+ {
+ executeTests = false;
+ cmCTestLog(this, ERROR_MESSAGE,
+ "CTest -T called with incorrect option: "
+ << args[i].c_str() << std::endl);
+ cmCTestLog(this, ERROR_MESSAGE, "Available options are:" << std::endl
+ << " " << ctestExec << " -T all" << std::endl
+ << " " << ctestExec << " -T start" << std::endl
+ << " " << ctestExec << " -T update" << std::endl
+ << " " << ctestExec << " -T configure" << std::endl
+ << " " << ctestExec << " -T build" << std::endl
+ << " " << ctestExec << " -T test" << std::endl
+ << " " << ctestExec << " -T coverage" << std::endl
+ << " " << ctestExec << " -T memcheck" << std::endl
+ << " " << ctestExec << " -T notes" << std::endl
+ << " " << ctestExec << " -T submit" << std::endl);
+ }
+ }
+
+ // what type of test model
+ if(this->CheckArgument(arg, "-M", "--test-model") &&
+ (i < args.size() -1) )
+ {
+ i++;
+ std::string const& str = args[i];
+ if ( cmSystemTools::LowerCase(str) == "nightly" )
+ {
+ this->SetTestModel(cmCTest::NIGHTLY);
+ }
+ else if ( cmSystemTools::LowerCase(str) == "continuous" )
+ {
+ this->SetTestModel(cmCTest::CONTINUOUS);
+ }
+ else if ( cmSystemTools::LowerCase(str) == "experimental" )
+ {
+ this->SetTestModel(cmCTest::EXPERIMENTAL);
+ }
+ else
+ {
+ executeTests = false;
+ cmCTestLog(this, ERROR_MESSAGE,
+ "CTest -M called with incorrect option: " << str.c_str()
+ << std::endl);
+ cmCTestLog(this, ERROR_MESSAGE, "Available options are:" << std::endl
+ << " " << ctestExec << " -M Continuous" << std::endl
+ << " " << ctestExec << " -M Experimental" << std::endl
+ << " " << ctestExec << " -M Nightly" << std::endl);
+ }
+ }
+
+ if(this->CheckArgument(arg, "--extra-submit") && i < args.size() - 1)
+ {
+ this->ProduceXML = true;
+ this->SetTest("Submit");
+ i++;
+ if ( !this->SubmitExtraFiles(args[i].c_str()) )
+ {
+ return 0;
+ }
+ }
+
+ // --build-and-test options
+ if(this->CheckArgument(arg, "--build-and-test") && i < args.size() - 1)
+ {
+ cmakeAndTest = true;
+ }
+
+ if(this->CheckArgument(arg, "--schedule-random"))
+ {
+ this->ScheduleType = "Random";
+ }
+
+ // pass the argument to all the handlers as well, but i may no longer be
+ // set to what it was originally so I'm not sure this is working as
+ // intended
+ cmCTest::t_TestingHandlers::iterator it;
+ for ( it = this->TestingHandlers.begin();
+ it != this->TestingHandlers.end();
+ ++ it )
+ {
+ if ( !it->second->ProcessCommandLineArguments(arg, i, args) )
+ {
+ cmCTestLog(this, ERROR_MESSAGE,
+ "Problem parsing command line arguments within a handler");
+ return 0;
+ }
+ }
+ } // the close of the for argument loop
+
+
+ // now what sould cmake do? if --build-and-test was specified then
+ // we run the build and test handler and return
+ if(cmakeAndTest)
+ {
+ this->Verbose = true;
+ cmCTestBuildAndTestHandler* handler =
+ static_cast<cmCTestBuildAndTestHandler*>(this->GetHandler("buildtest"));
+ int retv = handler->ProcessHandler();
+ *output = handler->GetOutput();
+#ifdef CMAKE_BUILD_WITH_CMAKE
+ cmDynamicLoader::FlushCache();
+#endif
+ if(retv != 0)
+ {
+ cmCTestLog(this, DEBUG, "build and test failing returing: " << retv
+ << std::endl);
+ }
+ return retv;
+ }
+
+ if(executeTests)
+ {
+ int res;
+ // call process directory
+ if (this->RunConfigurationScript)
+ {
+ if ( this->ExtraVerbose )
+ {
+ cmCTestLog(this, OUTPUT, "* Extra verbosity turned on" << std::endl);
+ }
+ cmCTest::t_TestingHandlers::iterator it;
+ for ( it = this->TestingHandlers.begin();
+ it != this->TestingHandlers.end();
+ ++ it )
+ {
+ it->second->SetVerbose(this->ExtraVerbose);
+ it->second->SetSubmitIndex(this->SubmitIndex);
+ }
+ this->GetHandler("script")->SetVerbose(this->Verbose);
+ res = this->GetHandler("script")->ProcessHandler();
+ if(res != 0)
+ {
+ cmCTestLog(this, DEBUG, "running script failing returning: " << res
+ << std::endl);
+ }
+
+ }
+ else
+ {
+ // What is this? -V seems to be the same as -VV,
+ // and Verbose is always on in this case
+ this->ExtraVerbose = this->Verbose;
+ this->Verbose = true;
+ cmCTest::t_TestingHandlers::iterator it;
+ for ( it = this->TestingHandlers.begin();
+ it != this->TestingHandlers.end();
+ ++ it )
+ {
+ it->second->SetVerbose(this->Verbose);
+ it->second->SetSubmitIndex(this->SubmitIndex);
+ }
+ std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
+ if(!this->Initialize(cwd.c_str(), 0))
+ {
+ res = 12;
+ cmCTestLog(this, ERROR_MESSAGE, "Problem initializing the dashboard."
+ << std::endl);
+ }
+ else
+ {
+ res = this->ProcessTests();
+ }
+ this->Finalize();
+ }
+ if(res != 0)
+ {
+ cmCTestLog(this, DEBUG, "Running a test(s) failed returning : " << res
+ << std::endl);
+ }
+ return res;
+ }
+
+ return 1;
+}
+
+//----------------------------------------------------------------------
+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 )
+ {
+ return;
+ }
+ this->NotesFiles = notes;
+}
+
+//----------------------------------------------------------------------
+void cmCTest::SetStopTime(std::string time)
+{
+ this->StopTime = time;
+ this->DetermineNextDayStop();
+}
+
+//----------------------------------------------------------------------
+int cmCTest::ReadCustomConfigurationFileTree(const char* dir, cmMakefile* mf)
+{
+ bool found = false;
+ VectorOfStrings dirs;
+ VectorOfStrings ndirs;
+ cmCTestLog(this, DEBUG, "* Read custom CTest configuration directory: "
+ << dir << std::endl);
+
+ std::string fname = dir;
+ fname += "/CTestCustom.cmake";
+ cmCTestLog(this, DEBUG, "* Check for file: "
+ << fname.c_str() << std::endl);
+ if ( cmSystemTools::FileExists(fname.c_str()) )
+ {
+ cmCTestLog(this, DEBUG, "* Read custom CTest configuration file: "
+ << fname.c_str() << std::endl);
+ bool erroroc = cmSystemTools::GetErrorOccuredFlag();
+ cmSystemTools::ResetErrorOccuredFlag();
+
+ if ( !mf->ReadListFile(0, fname.c_str()) ||
+ cmSystemTools::GetErrorOccuredFlag() )
+ {
+ cmCTestLog(this, ERROR_MESSAGE,
+ "Problem reading custom configuration: "
+ << fname.c_str() << std::endl);
+ }
+ found = true;
+ if ( erroroc )
+ {
+ cmSystemTools::SetErrorOccured();
+ }
+ }
+
+ std::string rexpr = dir;
+ rexpr += "/CTestCustom.ctest";
+ cmCTestLog(this, DEBUG, "* Check for file: "
+ << rexpr.c_str() << std::endl);
+ if ( !found && cmSystemTools::FileExists(rexpr.c_str()) )
+ {
+ cmsys::Glob gl;
+ gl.RecurseOn();
+ gl.FindFiles(rexpr);
+ std::vector<std::string>& files = gl.GetFiles();
+ std::vector<std::string>::iterator fileIt;
+ for ( fileIt = files.begin(); fileIt != files.end();
+ ++ fileIt )
+ {
+ cmCTestLog(this, DEBUG, "* Read custom CTest configuration file: "
+ << fileIt->c_str() << std::endl);
+ if ( !mf->ReadListFile(0, fileIt->c_str()) ||
+ cmSystemTools::GetErrorOccuredFlag() )
+ {
+ cmCTestLog(this, ERROR_MESSAGE,
+ "Problem reading custom configuration: "
+ << fileIt->c_str() << std::endl);
+ }
+ }
+ found = true;
+ }
+
+ if ( found )
+ {
+ cmCTest::t_TestingHandlers::iterator it;
+ for ( it = this->TestingHandlers.begin();
+ it != this->TestingHandlers.end(); ++ it )
+ {
+ cmCTestLog(this, DEBUG,
+ "* Read custom CTest configuration vectors for handler: "
+ << it->first.c_str() << " (" << it->second << ")" << std::endl);
+ it->second->PopulateCustomVectors(mf);
+ }
+ }
+
+ return 1;
+}
+
+//----------------------------------------------------------------------
+void cmCTest::PopulateCustomVector(cmMakefile* mf, const char* def,
+ VectorOfStrings& 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();
+
+ for ( it = slist.begin(); it != slist.end(); ++it )
+ {
+ cmCTestLog(this, DEBUG, " -- " << it->c_str() << std::endl);
+ vec.push_back(it->c_str());
+ }
+}
+
+//----------------------------------------------------------------------
+void cmCTest::PopulateCustomInteger(cmMakefile* mf, const char* def, int& val)
+{
+ if ( !def)
+ {
+ return;
+ }
+ const char* dval = mf->GetDefinition(def);
+ if ( !dval )
+ {
+ return;
+ }
+ val = atoi(dval);
+}
+
+//----------------------------------------------------------------------
+std::string cmCTest::GetShortPathToFile(const char* cfname)
+{
+ const std::string& sourceDir
+ = cmSystemTools::CollapseFullPath(
+ this->GetCTestConfiguration("SourceDirectory").c_str());
+ const std::string& buildDir
+ = cmSystemTools::CollapseFullPath(
+ this->GetCTestConfiguration("BuildDirectory").c_str());
+ std::string fname = cmSystemTools::CollapseFullPath(cfname);
+
+ // Find relative paths to both directories
+ std::string srcRelpath
+ = cmSystemTools::RelativePath(sourceDir.c_str(), fname.c_str());
+ std::string bldRelpath
+ = cmSystemTools::RelativePath(buildDir.c_str(), fname.c_str());
+
+ // If any contains "." it is not parent directory
+ bool inSrc = srcRelpath.find("..") == srcRelpath.npos;
+ bool inBld = bldRelpath.find("..") == bldRelpath.npos;
+ // TODO: Handle files with .. in their name
+
+ std::string* res = 0;
+
+ if ( inSrc && inBld )
+ {
+ // If both have relative path with no dots, pick the shorter one
+ if ( srcRelpath.size() < bldRelpath.size() )
+ {
+ res = &srcRelpath;
+ }
+ else
+ {
+ res = &bldRelpath;
+ }
+ }
+ else if ( inSrc )
+ {
+ res = &srcRelpath;
+ }
+ else if ( inBld )
+ {
+ res = &bldRelpath;
+ }
+
+ std::string path;
+
+ if ( !res )
+ {
+ path = fname;
+ }
+ else
+ {
+ cmSystemTools::ConvertToUnixSlashes(*res);
+
+ path = "./" + *res;
+ if ( path[path.size()-1] == '/' )
+ {
+ path = path.substr(0, path.size()-1);
+ }
+ }
+
+ cmsys::SystemTools::ReplaceString(path, ":", "_");
+ cmsys::SystemTools::ReplaceString(path, " ", "_");
+ return path;
+}
+
+//----------------------------------------------------------------------
+std::string cmCTest::GetCTestConfiguration(const char *name)
+{
+ if ( this->CTestConfigurationOverwrites.find(name) !=
+ this->CTestConfigurationOverwrites.end() )
+ {
+ return this->CTestConfigurationOverwrites[name];
+ }
+ return this->CTestConfiguration[name];
+}
+
+//----------------------------------------------------------------------
+void cmCTest::EmptyCTestConfiguration()
+{
+ this->CTestConfiguration.clear();
+}
+
+//----------------------------------------------------------------------
+void cmCTest::DetermineNextDayStop()
+{
+ struct tm* lctime;
+ time_t current_time = time(0);
+ lctime = gmtime(&current_time);
+ int gm_hour = lctime->tm_hour;
+ time_t gm_time = mktime(lctime);
+ lctime = localtime(&current_time);
+ int local_hour = lctime->tm_hour;
+
+ int tzone_offset = local_hour - gm_hour;
+ if(gm_time > current_time && gm_hour < local_hour)
+ {
+ // this means gm_time is on the next day
+ tzone_offset -= 24;
+ }
+ else if(gm_time < current_time && gm_hour > local_hour)
+ {
+ // this means gm_time is on the previous day
+ tzone_offset += 24;
+ }
+
+ tzone_offset *= 100;
+ char buf[1024];
+ sprintf(buf, "%d%02d%02d %s %+05i",
+ lctime->tm_year + 1900,
+ lctime->tm_mon + 1,
+ lctime->tm_mday,
+ this->StopTime.c_str(),
+ tzone_offset);
+
+ time_t stop_time = curl_getdate(buf, &current_time);
+
+ if(stop_time < current_time)
+ {
+ this->NextDayStopTime = true;
+ }
+}
+
+//----------------------------------------------------------------------
+void cmCTest::SetCTestConfiguration(const char *name, const char* value)
+{
+ cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, "SetCTestConfiguration:"
+ << name << ":" << (value ? value : "(null)") << "\n");
+
+ if ( !name )
+ {
+ return;
+ }
+ if ( !value )
+ {
+ this->CTestConfiguration.erase(name);
+ return;
+ }
+ this->CTestConfiguration[name] = value;
+}
+
+
+//----------------------------------------------------------------------
+std::string cmCTest::GetCurrentTag()
+{
+ return this->CurrentTag;
+}
+
+//----------------------------------------------------------------------
+std::string cmCTest::GetBinaryDir()
+{
+ return this->BinaryDir;
+}
+
+//----------------------------------------------------------------------
+std::string const& cmCTest::GetConfigType()
+{
+ return this->ConfigType;
+}
+
+//----------------------------------------------------------------------
+bool cmCTest::GetShowOnly()
+{
+ return this->ShowOnly;
+}
+
+//----------------------------------------------------------------------
+int cmCTest::GetMaxTestNameWidth() const
+{
+ return this->MaxTestNameWidth;
+}
+
+//----------------------------------------------------------------------
+void cmCTest::SetProduceXML(bool v)
+{
+ this->ProduceXML = v;
+}
+
+//----------------------------------------------------------------------
+bool cmCTest::GetProduceXML()
+{
+ return this->ProduceXML;
+}
+
+//----------------------------------------------------------------------
+const char* cmCTest::GetSpecificTrack()
+{
+ if ( this->SpecificTrack.empty() )
+ {
+ return 0;
+ }
+ return this->SpecificTrack.c_str();
+}
+
+//----------------------------------------------------------------------
+void cmCTest::SetSpecificTrack(const char* track)
+{
+ if ( !track )
+ {
+ this->SpecificTrack = "";
+ return;
+ }
+ this->SpecificTrack = track;
+}
+
+//----------------------------------------------------------------------
+void cmCTest::AddSubmitFile(Part part, const char* name)
+{
+ this->Parts[part].SubmitFiles.push_back(name);
+}
+
+//----------------------------------------------------------------------
+void cmCTest::AddCTestConfigurationOverwrite(const char* encstr)
+{
+ std::string overStr = encstr;
+ size_t epos = overStr.find("=");
+ if ( epos == overStr.npos )
+ {
+ cmCTestLog(this, ERROR_MESSAGE,
+ "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);
+ return;
+ }
+ std::string key = overStr.substr(0, epos);
+ std::string value = overStr.substr(epos+1, overStr.npos);
+ this->CTestConfigurationOverwrites[key] = value;
+}
+
+//----------------------------------------------------------------------
+void cmCTest::SetConfigType(const char* ct)
+{
+ this->ConfigType = ct?ct:"";
+ cmSystemTools::ReplaceString(this->ConfigType, ".\\", "");
+ std::string confTypeEnv
+ = "CMAKE_CONFIG_TYPE=" + this->ConfigType;
+ cmSystemTools::PutEnv(confTypeEnv.c_str());
+}
+
+//----------------------------------------------------------------------
+bool cmCTest::SetCTestConfigurationFromCMakeVariable(cmMakefile* mf,
+ const char* dconfig, const char* cmake_var)
+{
+ const char* ctvar;
+ ctvar = mf->GetDefinition(cmake_var);
+ if ( !ctvar )
+ {
+ return false;
+ }
+ cmCTestLog(this, HANDLER_VERBOSE_OUTPUT,
+ "SetCTestConfigurationFromCMakeVariable:"
+ << dconfig << ":" << cmake_var << std::endl);
+ this->SetCTestConfiguration(dconfig, ctvar);
+ return true;
+}
+
+bool cmCTest::RunCommand(
+ const char* command,
+ std::string* stdOut,
+ std::string* stdErr,
+ int *retVal,
+ const char* dir,
+ double timeout)
+{
+ std::vector<cmStdString> args = cmSystemTools::ParseArguments(command);
+
+ if(args.size() < 1)
+ {
+ return false;
+ }
+
+ std::vector<const char*> argv;
+ for(std::vector<cmStdString>::const_iterator a = args.begin();
+ a != args.end(); ++a)
+ {
+ argv.push_back(a->c_str());
+ }
+ argv.push_back(0);
+
+ *stdOut = "";
+ *stdErr = "";
+
+ cmsysProcess* cp = cmsysProcess_New();
+ cmsysProcess_SetCommand(cp, &*argv.begin());
+ cmsysProcess_SetWorkingDirectory(cp, dir);
+ if(cmSystemTools::GetRunCommandHideConsole())
+ {
+ cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1);
+ }
+ cmsysProcess_SetTimeout(cp, timeout);
+ cmsysProcess_Execute(cp);
+
+ std::vector<char> tempOutput;
+ std::vector<char> tempError;
+ char* data;
+ int length;
+ int res;
+ bool done = false;
+ while(!done)
+ {
+ res = cmsysProcess_WaitForData(cp, &data, &length, 0);
+ switch ( res )
+ {
+ case cmsysProcess_Pipe_STDOUT:
+ tempOutput.insert(tempOutput.end(), data, data+length);
+ break;
+ case cmsysProcess_Pipe_STDERR:
+ tempError.insert(tempError.end(), data, data+length);
+ break;
+ default:
+ done = true;
+ }
+ if ( (res == cmsysProcess_Pipe_STDOUT ||
+ res == cmsysProcess_Pipe_STDERR) && this->ExtraVerbose )
+ {
+ cmSystemTools::Stdout(data, length);
+ }
+ }
+
+ cmsysProcess_WaitForExit(cp, 0);
+ if ( tempOutput.size() > 0 )
+ {
+ stdOut->append(&*tempOutput.begin(), tempOutput.size());
+ }
+ if ( tempError.size() > 0 )
+ {
+ stdErr->append(&*tempError.begin(), tempError.size());
+ }
+
+ bool result = true;
+ if(cmsysProcess_GetState(cp) == cmsysProcess_State_Exited)
+ {
+ if ( retVal )
+ {
+ *retVal = cmsysProcess_GetExitValue(cp);
+ }
+ else
+ {
+ if ( cmsysProcess_GetExitValue(cp) != 0 )
+ {
+ result = false;
+ }
+ }
+ }
+ else if(cmsysProcess_GetState(cp) == cmsysProcess_State_Exception)
+ {
+ const char* exception_str = cmsysProcess_GetExceptionString(cp);
+ cmCTestLog(this, ERROR_MESSAGE, exception_str << std::endl);
+ stdErr->append(exception_str, strlen(exception_str));
+ result = false;
+ }
+ else if(cmsysProcess_GetState(cp) == cmsysProcess_State_Error)
+ {
+ const char* error_str = cmsysProcess_GetErrorString(cp);
+ cmCTestLog(this, ERROR_MESSAGE, error_str << std::endl);
+ stdErr->append(error_str, strlen(error_str));
+ result = false;
+ }
+ else if(cmsysProcess_GetState(cp) == cmsysProcess_State_Expired)
+ {
+ const char* error_str = "Process terminated due to timeout\n";
+ cmCTestLog(this, ERROR_MESSAGE, error_str << std::endl);
+ stdErr->append(error_str, strlen(error_str));
+ result = false;
+ }
+
+ cmsysProcess_Delete(cp);
+ return result;
+}
+
+//----------------------------------------------------------------------
+void cmCTest::SetOutputLogFileName(const char* name)
+{
+ if ( this->OutputLogFile)
+ {
+ delete this->OutputLogFile;
+ this->OutputLogFile= 0;
+ }
+ if ( name )
+ {
+ this->OutputLogFile = new cmGeneratedFileStream(name);
+ }
+}
+
+//----------------------------------------------------------------------
+static const char* cmCTestStringLogType[] =
+{
+ "DEBUG",
+ "OUTPUT",
+ "HANDLER_OUTPUT",
+ "HANDLER_VERBOSE_OUTPUT",
+ "WARNING",
+ "ERROR_MESSAGE",
+ 0
+};
+
+//----------------------------------------------------------------------
+#ifdef cerr
+# undef cerr
+#endif
+#ifdef cout
+# undef cout
+#endif
+
+#define cmCTestLogOutputFileLine(stream) \
+ if ( this->ShowLineNumbers ) \
+ { \
+ (stream) << std::endl << file << ":" << line << " "; \
+ }
+
+void cmCTest::InitStreams()
+{
+ // By default we write output to the process output streams.
+ this->StreamOut = &std::cout;
+ this->StreamErr = &std::cerr;
+}
+
+void cmCTest::Log(int logType, const char* file, int line, const char* msg)
+{
+ if ( !msg || !*msg )
+ {
+ return;
+ }
+ if ( this->OutputLogFile )
+ {
+ bool display = true;
+ if ( logType == cmCTest::DEBUG && !this->Debug ) { display = false; }
+ if ( logType == cmCTest::HANDLER_VERBOSE_OUTPUT && !this->Debug &&
+ !this->ExtraVerbose ) { display = false; }
+ if ( display )
+ {
+ cmCTestLogOutputFileLine(*this->OutputLogFile);
+ if ( logType != this->OutputLogFileLastTag )
+ {
+ *this->OutputLogFile << "[";
+ if ( logType >= OTHER || logType < 0 )
+ {
+ *this->OutputLogFile << "OTHER";
+ }
+ else
+ {
+ *this->OutputLogFile << cmCTestStringLogType[logType];
+ }
+ *this->OutputLogFile << "] " << std::endl << std::flush;
+ }
+ *this->OutputLogFile << msg << std::flush;
+ if ( logType != this->OutputLogFileLastTag )
+ {
+ *this->OutputLogFile << std::endl << std::flush;
+ this->OutputLogFileLastTag = logType;
+ }
+ }
+ }
+ if ( !this->Quiet )
+ {
+ std::ostream& out = *this->StreamOut;
+ std::ostream& err = *this->StreamErr;
+ switch ( logType )
+ {
+ case DEBUG:
+ if ( this->Debug )
+ {
+ cmCTestLogOutputFileLine(out);
+ out << msg;
+ out.flush();
+ }
+ break;
+ case OUTPUT: case HANDLER_OUTPUT:
+ if ( this->Debug || this->Verbose )
+ {
+ cmCTestLogOutputFileLine(out);
+ out << msg;
+ out.flush();
+ }
+ break;
+ case HANDLER_VERBOSE_OUTPUT:
+ if ( this->Debug || this->ExtraVerbose )
+ {
+ cmCTestLogOutputFileLine(out);
+ out << msg;
+ out.flush();
+ }
+ break;
+ case WARNING:
+ cmCTestLogOutputFileLine(err);
+ err << msg;
+ err.flush();
+ break;
+ case ERROR_MESSAGE:
+ cmCTestLogOutputFileLine(err);
+ err << msg;
+ err.flush();
+ cmSystemTools::SetErrorOccured();
+ break;
+ default:
+ cmCTestLogOutputFileLine(out);
+ out << msg;
+ out.flush();
+ }
+ }
+}
+
+//-------------------------------------------------------------------------
+double cmCTest::GetRemainingTimeAllowed()
+{
+ if (!this->GetHandler("script"))
+ {
+ return 1.0e7;
+ }
+
+ cmCTestScriptHandler* ch
+ = static_cast<cmCTestScriptHandler*>(this->GetHandler("script"));
+
+ return ch->GetRemainingTimeAllowed();
+}
+
+//----------------------------------------------------------------------
+void cmCTest::OutputTestErrors(std::vector<char> const &process_output)
+{
+ std::string test_outputs("\n*** Test Failed:\n");
+ if(process_output.size())
+ {
+ test_outputs.append(&*process_output.begin(), process_output.size());
+ }
+ cmCTestLog(this, HANDLER_OUTPUT, test_outputs << std::endl << std::flush);
+}
+
+//----------------------------------------------------------------------
+bool cmCTest::CompressString(std::string& str)
+{
+ int ret;
+ z_stream strm;
+
+ unsigned char* in = reinterpret_cast<unsigned char*>(
+ const_cast<char*>(str.c_str()));
+ //zlib makes the guarantee that this is the maximum output size
+ int outSize = static_cast<int>(
+ static_cast<double>(str.size()) * 1.001 + 13.0);
+ unsigned char* out = new unsigned char[outSize];
+
+ strm.zalloc = Z_NULL;
+ strm.zfree = Z_NULL;
+ strm.opaque = Z_NULL;
+ ret = deflateInit(&strm, -1); //default compression level
+ if (ret != Z_OK)
+ {
+ delete[] out;
+ return false;
+ }
+
+ strm.avail_in = static_cast<uInt>(str.size());
+ strm.next_in = in;
+ strm.avail_out = outSize;
+ strm.next_out = out;
+ ret = deflate(&strm, Z_FINISH);
+
+ if(ret == Z_STREAM_ERROR || ret != Z_STREAM_END)
+ {
+ cmCTestLog(this, ERROR_MESSAGE, "Error during gzip compression."
+ << std::endl);
+ delete[] out;
+ return false;
+ }
+
+ (void)deflateEnd(&strm);
+
+ // Now base64 encode the resulting binary string
+ unsigned char* base64EncodedBuffer
+ = new unsigned char[static_cast<int>(outSize * 1.5)];
+
+ unsigned long rlen
+ = cmsysBase64_Encode(out, strm.total_out, base64EncodedBuffer, 1);
+
+ str = "";
+ str.append(reinterpret_cast<char*>(base64EncodedBuffer), rlen);
+
+ delete [] base64EncodedBuffer;
+ delete [] out;
+
+ return true;
+}
diff --git a/Source/cmCTest.h b/Source/cmCTest.h
new file mode 100644
index 000000000..beffe9e7a
--- /dev/null
+++ b/Source/cmCTest.h
@@ -0,0 +1,598 @@
+/*============================================================================
+ 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 cmCTest_h
+#define cmCTest_h
+
+#include "cmStandardIncludes.h"
+#include "cmListFileCache.h"
+#include <time.h>
+
+class cmake;
+class cmMakefile;
+class cmCTestGenericHandler;
+class cmGeneratedFileStream;
+class cmCTestCommand;
+class cmCTestScriptHandler;
+class cmCTestStartCommand;
+
+#define cmCTestLog(ctSelf, logType, msg) \
+ do { \
+ cmOStringStream cmCTestLog_msg; \
+ cmCTestLog_msg << msg; \
+ (ctSelf)->Log(cmCTest::logType, __FILE__, __LINE__,\
+ cmCTestLog_msg.str().c_str());\
+ } while ( 0 )
+
+#ifdef cerr
+# undef cerr
+#endif
+#define cerr no_cerr_use_cmCTestLog
+
+#ifdef cout
+# undef cout
+#endif
+#define cout no_cout_use_cmCTestLog
+
+class cmCTest
+{
+ friend class cmCTestRunTest;
+ friend class cmCTestMultiProcessHandler;
+public:
+ /** Enumerate parts of the testing and submission process. */
+ enum Part
+ {
+ PartStart,
+ PartUpdate,
+ PartConfigure,
+ PartBuild,
+ PartTest,
+ PartCoverage,
+ PartMemCheck,
+ PartSubmit,
+ PartNotes,
+ PartExtraFiles,
+ PartUpload,
+ PartCount // Update names in constructor when adding a part
+ };
+
+ /** Representation of one part. */
+ struct PartInfo
+ {
+ PartInfo(): Enabled(false) {}
+
+ void SetName(const char* name) { this->Name = name; }
+ const char* GetName() const { return this->Name.c_str(); }
+
+ void Enable() { this->Enabled = true; }
+ operator bool() const { return this->Enabled; }
+
+ std::vector<std::string> SubmitFiles;
+ private:
+ bool Enabled;
+ std::string Name;
+ };
+#ifdef CMAKE_BUILD_WITH_CMAKE
+ enum HTTPMethod {
+ HTTP_GET,
+ HTTP_POST,
+ HTTP_PUT
+ };
+
+ /**
+ * Perform an HTTP request.
+ */
+ static int HTTPRequest(std::string url, HTTPMethod method,
+ std::string& response,
+ std::string fields = "",
+ std::string putFile = "", int timeout = 0);
+#endif
+
+ /** Get a testing part id from its string name. Returns PartCount
+ if the string does not name a valid part. */
+ Part GetPartFromName(const char* name);
+
+ typedef std::vector<cmStdString> VectorOfStrings;
+ typedef std::set<cmStdString> SetOfStrings;
+
+ ///! Process Command line arguments
+ int Run(std::vector<std::string> &, std::string* output = 0);
+
+ /**
+ * Initialize and finalize testing
+ */
+ bool InitializeFromCommand(cmCTestStartCommand* command);
+ void Finalize();
+
+ /**
+ * Process the tests. This is the main routine. The execution of the
+ * tests should look like this:
+ *
+ * ctest foo;
+ * foo.Initialize();
+ * // Set some things on foo
+ * foo.ProcessTests();
+ * foo.Finalize();
+ */
+ int ProcessTests();
+
+ /*
+ * A utility function that returns the nightly time
+ */
+ struct tm* GetNightlyTime(std::string str,
+ bool tomorrowtag);
+
+ /*
+ * Is the tomorrow tag set?
+ */
+ bool GetTomorrowTag() { return this->TomorrowTag; };
+
+ /**
+ * Try to run tests of the project
+ */
+ int TestDirectory(bool memcheck);
+
+ ///! what is the configuraiton type, e.g. Debug, Release etc.
+ std::string const& GetConfigType();
+ double GetTimeOut() { return this->TimeOut; }
+ void SetTimeOut(double t) { this->TimeOut = t; }
+
+ double GetGlobalTimeout() { return this->GlobalTimeout; }
+
+ // how many test to run at the same time
+ int GetParallelLevel() { return this->ParallelLevel; }
+ void SetParallelLevel(int);
+
+ /**
+ * Check if CTest file exists
+ */
+ bool CTestFileExists(const std::string& filename);
+ bool AddIfExists(Part part, const char* file);
+
+ /**
+ * Set the cmake test
+ */
+ bool SetTest(const char*, bool report = true);
+
+ /**
+ * Set the cmake test mode (experimental, nightly, continuous).
+ */
+ void SetTestModel(int mode);
+ 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);
+ void EmptyCTestConfiguration();
+
+ /**
+ * constructor and destructor
+ */
+ cmCTest();
+ ~cmCTest();
+
+ //! 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,
+ int& val);
+
+ ///! Get the current time as string
+ std::string CurrentTime();
+
+ //! tar/gzip and then base 64 encode a file
+ std::string Base64GzipEncodeFile(std::string file);
+ //! base64 encode a file
+ std::string Base64EncodeFile(std::string file);
+
+ /**
+ * Return the time remaining that the script is allowed to run in
+ * seconds if the user has set the variable CTEST_TIME_LIMIT. If that has
+ * not been set it returns 1e7 seconds
+ */
+ double GetRemainingTimeAllowed();
+
+ ///! Open file in the output directory and set the stream
+ bool OpenOutputFile(const std::string& path,
+ const std::string& name,
+ cmGeneratedFileStream& stream,
+ bool compress = false);
+
+ ///! Should we only show what we would do?
+ bool GetShowOnly();
+
+ bool ShouldUseHTTP10() { return this->UseHTTP10; }
+
+ bool ShouldPrintLabels() { return this->PrintLabels; }
+
+ bool ShouldCompressTestOutput();
+ bool ShouldCompressMemCheckOutput();
+ bool CompressString(std::string& str);
+
+ std::string GetCDashVersion();
+
+ std::string GetStopTime() { return this->StopTime; }
+ void SetStopTime(std::string time);
+
+ //Used for parallel ctest job scheduling
+ std::string GetScheduleType() { return this->ScheduleType; }
+ void SetScheduleType(std::string type) { this->ScheduleType = type; }
+
+ ///! The max output width
+ int GetMaxTestNameWidth() const;
+ void SetMaxTestNameWidth(int w) { this->MaxTestNameWidth = w;}
+
+ /**
+ * Run a single executable command and put the stdout and stderr
+ * in output.
+ *
+ * If verbose is false, no user-viewable output from the program
+ * being run will be generated.
+ *
+ * If timeout is specified, the command will be terminated after
+ * timeout expires. Timeout is specified in seconds.
+ *
+ * Argument retVal should be a pointer to the location where the
+ * exit code will be stored. If the retVal is not specified and
+ * the program exits with a code other than 0, then the this
+ * function will return false.
+ *
+ * If the command has spaces in the path the caller MUST call
+ * cmSystemTools::ConvertToRunCommandPath on the command before passing
+ * it into this function or it will not work. The command must be correctly
+ * escaped for this to with spaces.
+ */
+ bool RunCommand(const char* command,
+ std::string* stdOut, std::string* stdErr,
+ int* retVal = 0, const char* dir = 0, double timeout = 0.0);
+
+ //! Clean/make safe for xml the given value such that it may be used as
+ // one of the key fields by CDash when computing the buildid.
+ static std::string SafeBuildIdField(const std::string& value);
+
+ //! Start CTest XML output file
+ void StartXML(std::ostream& ostr, bool append);
+
+ //! End CTest XML output file
+ void EndXML(std::ostream& ostr);
+
+ //! 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* retVal, const char* dir, int timeout,
+ std::ofstream& ofs);
+
+ /*
+ * return the current tag
+ */
+ std::string GetCurrentTag();
+
+ //! Get the path to the build tree
+ std::string GetBinaryDir();
+
+ //! Get the short path to the file. This means if the file is in binary or
+ //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,
+ CONTINUOUS
+ };
+
+ // provide some more detailed info on the return code for ctest
+ enum {
+ UPDATE_ERRORS = 0x01,
+ CONFIGURE_ERRORS = 0x02,
+ BUILD_ERRORS = 0x04,
+ TEST_ERRORS = 0x08,
+ MEMORY_ERRORS = 0x10,
+ COVERAGE_ERRORS = 0x20,
+ SUBMIT_ERRORS = 0x40
+ };
+
+ ///! Are we producing XML
+ bool GetProduceXML();
+ void SetProduceXML(bool v);
+
+ //! Run command specialized for tests. Returns process status and retVal is
+ // return value or exception. If environment is non-null, it is used to set
+ // environment variables prior to running the test. After running the test,
+ // environment variables are restored to their previous values.
+ int RunTest(std::vector<const char*> args, std::string* output, int *retVal,
+ std::ostream* logfile, double testTimeOut,
+ std::vector<std::string>* environment);
+
+ /**
+ * Execute handler and return its result. If the handler fails, it returns
+ * negative value.
+ */
+ int ExecuteHandler(const char* handler);
+
+ /*
+ * Get the handler object
+ */
+ cmCTestGenericHandler* GetHandler(const char* handler);
+ cmCTestGenericHandler* GetInitializedHandler(const char* handler);
+
+ /*
+ * Set the CTest variable from CMake variable
+ */
+ bool SetCTestConfigurationFromCMakeVariable(cmMakefile* mf,
+ const char* dconfig, const char* cmake_var);
+
+ //! Make string safe to be send as an URL
+ static std::string MakeURLSafe(const std::string&);
+
+ /** Decode a URL to the original string. */
+ static std::string DecodeURL(const std::string&);
+
+ //! Should ctect configuration be updated. When using new style ctest
+ // script, this should be true.
+ void SetSuppressUpdatingCTestConfiguration(bool val)
+ {
+ this->SuppressUpdatingCTestConfiguration = val;
+ }
+
+ //! Add overwrite to ctest configuration.
+ // The format is key=value
+ void AddCTestConfigurationOverwrite(const char* encstr);
+
+ //! Create XML file that contains all the notes specified
+ int GenerateNotesFile(const std::vector<cmStdString> &files);
+
+ //! Submit extra files to the server
+ bool SubmitExtraFiles(const char* files);
+ bool SubmitExtraFiles(const std::vector<cmStdString> &files);
+
+ //! Set the output log file name
+ void SetOutputLogFileName(const char* name);
+
+ //! Set the visual studio or Xcode config type
+ void SetConfigType(const char* ct);
+
+ //! Various log types
+ enum {
+ DEBUG = 0,
+ OUTPUT,
+ HANDLER_OUTPUT,
+ HANDLER_VERBOSE_OUTPUT,
+ WARNING,
+ ERROR_MESSAGE,
+ OTHER
+ };
+
+ //! Add log to the output
+ void Log(int logType, const char* file, int line, const char* msg);
+
+ //! Get the version of dart server
+ int GetDartVersion() { return this->DartVersion; }
+
+ //! Add file to be submitted
+ void AddSubmitFile(Part part, const char* name);
+ std::vector<std::string> const& GetSubmitFiles(Part part)
+ { return this->Parts[part].SubmitFiles; }
+ void ClearSubmitFiles(Part part) { this->Parts[part].SubmitFiles.clear(); }
+
+ //! 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; };
+
+ //! Set the track to submit to
+ void SetSpecificTrack(const char* track);
+ const char* GetSpecificTrack();
+
+ void SetFailover(bool failover) { this->Failover = failover; }
+ bool GetFailover() { return this->Failover; }
+
+ void SetBatchJobs(bool batch = true) { this->BatchJobs = batch; }
+ bool GetBatchJobs() { return this->BatchJobs; }
+
+ bool GetVerbose() { return this->Verbose;}
+ bool GetExtraVerbose() { return this->ExtraVerbose;}
+
+ /** Direct process output to given streams. */
+ void SetStreams(std::ostream* out, std::ostream* err)
+ { this->StreamOut = out; this->StreamErr = err; }
+ void AddSiteProperties(std::ostream& );
+ bool GetLabelSummary() { return this->LabelSummary;}
+
+ std::string GetCostDataFile();
+
+ const std::map<std::string, std::string> &GetDefinitions()
+ {
+ return this->Definitions;
+ }
+
+private:
+ std::string ConfigType;
+ std::string ScheduleType;
+ std::string StopTime;
+ bool NextDayStopTime;
+ bool Verbose;
+ bool ExtraVerbose;
+ bool ProduceXML;
+ bool LabelSummary;
+ bool UseHTTP10;
+ bool PrintLabels;
+ bool Failover;
+ bool BatchJobs;
+
+ bool ForceNewCTestProcess;
+
+ bool RunConfigurationScript;
+
+ //flag for lazy getter (optimization)
+ bool ComputedCompressTestOutput;
+ bool ComputedCompressMemCheckOutput;
+
+ int GenerateNotesFile(const char* files);
+
+ void DetermineNextDayStop();
+
+ // these are helper classes
+ typedef std::map<cmStdString,cmCTestGenericHandler*> t_TestingHandlers;
+ t_TestingHandlers TestingHandlers;
+
+ bool ShowOnly;
+
+ //! Map of configuration properties
+ typedef std::map<cmStdString, cmStdString> CTestConfigurationMap;
+
+ std::string CTestConfigFile;
+ // TODO: The ctest configuration should be a hierarchy of
+ // configuration option sources: command-line, script, ini file.
+ // Then the ini file can get re-loaded whenever it changes without
+ // affecting any higher-precedence settings.
+ CTestConfigurationMap CTestConfiguration;
+ CTestConfigurationMap CTestConfigurationOverwrites;
+ PartInfo Parts[PartCount];
+ typedef std::map<cmStdString, Part> PartMapType;
+ PartMapType PartMap;
+
+ std::string CurrentTag;
+ bool TomorrowTag;
+
+ int TestModel;
+ std::string SpecificTrack;
+
+ double TimeOut;
+
+ double GlobalTimeout;
+
+ int LastStopTimeout;
+
+ int MaxTestNameWidth;
+
+ int ParallelLevel;
+
+ int CompatibilityMode;
+
+ // information for the --build-and-test options
+ std::string CMakeSelf;
+ std::string CTestSelf;
+ std::string BinaryDir;
+
+ std::string NotesFiles;
+
+
+ bool InteractiveDebugMode;
+
+ bool ShortDateFormat;
+
+ bool CompressXMLFiles;
+ bool CompressTestOutput;
+ bool CompressMemCheckOutput;
+
+ void InitStreams();
+ std::ostream* StreamOut;
+ std::ostream* StreamErr;
+
+ void BlockTestErrorDiagnostics();
+
+ /**
+ * Initialize a dashboard run in the given build tree. The "command"
+ * argument is non-NULL when running from a command-driven (ctest_start)
+ * dashboard script, and NULL when running from the CTest command
+ * line. Note that a declarative dashboard script does not actually
+ * call this method because it sets CTEST_COMMAND to drive a build
+ * through the ctest command line.
+ */
+ int Initialize(const char* binary_dir, cmCTestStartCommand* command);
+
+ //! parse the option after -D and convert it into the appropriate steps
+ bool AddTestsForDashboardType(std::string &targ);
+
+ //! read as "emit an error message for an unknown -D value"
+ void ErrorMessageUnknownDashDValue(std::string &val);
+
+ //! add a variable definition from a command line -D value
+ bool AddVariableDefinition(const std::string &arg);
+
+ //! parse and process most common command line arguments
+ void HandleCommandLineArguments(size_t &i,
+ std::vector<std::string> &args);
+
+ //! hande the -S -SP and -SR arguments
+ void HandleScriptArguments(size_t &i,
+ std::vector<std::string> &args,
+ bool &SRArgumentSpecified);
+
+ //! Reread the configuration file
+ bool UpdateCTestConfiguration();
+
+ //! Create note from files.
+ int GenerateCTestNotesOutput(std::ostream& os,
+ 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);
+
+ //! Output errors from a test
+ void OutputTestErrors(std::vector<char> const &process_output);
+
+ bool SuppressUpdatingCTestConfiguration;
+
+ bool Debug;
+ bool ShowLineNumbers;
+ bool Quiet;
+
+ int DartVersion;
+
+ std::vector<cmStdString> InitialCommandLineArguments;
+
+ int SubmitIndex;
+
+ cmGeneratedFileStream* OutputLogFile;
+ int OutputLogFileLastTag;
+
+ bool OutputTestOutputOnTestFailure;
+
+ std::map<std::string, std::string> Definitions;
+};
+
+class cmCTestLogWrite
+{
+public:
+ cmCTestLogWrite(const char* data, size_t length)
+ : Data(data), Length(length) {}
+
+ const char* Data;
+ size_t Length;
+};
+
+inline std::ostream& operator<< (std::ostream& os, const cmCTestLogWrite& c)
+{
+ if (!c.Length)
+ {
+ return os;
+ }
+ os.write(c.Data, c.Length);
+ os.flush();
+ return os;
+}
+
+#endif
diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx
new file mode 100644
index 000000000..47a0e8553
--- /dev/null
+++ b/Source/cmCacheManager.cxx
@@ -0,0 +1,1003 @@
+/*============================================================================
+ 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 "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/RegularExpression.hxx>
+
+const char* cmCacheManagerTypes[] =
+{ "BOOL",
+ "PATH",
+ "FILEPATH",
+ "STRING",
+ "INTERNAL",
+ "STATIC",
+ "UNINITIALIZED",
+ 0
+};
+
+cmCacheManager::cmCacheManager(cmake* cm)
+{
+ 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)
+{
+ std::string glob = path;
+ glob += cmake::GetCMakeFilesDirectory();
+ glob += "/*.cmake";
+ 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());
+ }
+}
+
+bool cmCacheManager::LoadCache(const char* path,
+ bool internal,
+ std::set<cmStdString>& excludes,
+ std::set<cmStdString>& includes)
+{
+ std::string cacheFile = path;
+ cacheFile += "/CMakeCache.txt";
+ // clear the old cache, if we are reading in internal values
+ if ( internal )
+ {
+ this->Cache.clear();
+ }
+ if(!cmSystemTools::FileExists(cacheFile.c_str()))
+ {
+ this->CleanCMakeFiles(path);
+ return false;
+ }
+
+ std::ifstream fin(cacheFile.c_str());
+ if(!fin)
+ {
+ return false;
+ }
+ const char *realbuffer;
+ std::string buffer;
+ std::string entryKey;
+ while(fin)
+ {
+ // Format is key:type=value
+ std::string helpString;
+ CacheEntry e;
+ e.Properties.SetCMakeInstance(this->CMakeInstance);
+ cmSystemTools::GetLineFromStream(fin, buffer);
+ realbuffer = buffer.c_str();
+ while(*realbuffer != '0' &&
+ (*realbuffer == ' ' ||
+ *realbuffer == '\t' ||
+ *realbuffer == '\r' ||
+ *realbuffer == '\n'))
+ {
+ realbuffer++;
+ }
+ // skip blank lines and comment lines
+ if(realbuffer[0] == '#' || realbuffer[0] == 0)
+ {
+ continue;
+ }
+ while(realbuffer[0] == '/' && realbuffer[1] == '/')
+ {
+ if ((realbuffer[2] == '\\') && (realbuffer[3]=='n'))
+ {
+ helpString += "\n";
+ helpString += &realbuffer[4];
+ }
+ else
+ {
+ helpString += &realbuffer[2];
+ }
+ cmSystemTools::GetLineFromStream(fin, buffer);
+ realbuffer = buffer.c_str();
+ if(!fin)
+ {
+ continue;
+ }
+ }
+ e.SetProperty("HELPSTRING", helpString.c_str());
+ if(cmCacheManager::ParseEntry(realbuffer, entryKey, e.Value, e.Type))
+ {
+ if ( excludes.find(entryKey) == excludes.end() )
+ {
+ // Load internal values if internal is set.
+ // 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) ||
+ (includes.find(entryKey) != includes.end()) )
+ {
+ // If we are loading the cache from another project,
+ // make all loaded entries internal so that it is
+ // not visible in the gui
+ if (!internal)
+ {
+ e.Type = INTERNAL;
+ helpString = "DO NOT EDIT, ";
+ helpString += entryKey;
+ helpString += " loaded from external file. "
+ "To change this value edit this file: ";
+ helpString += path;
+ helpString += "/CMakeCache.txt" ;
+ e.SetProperty("HELPSTRING", helpString.c_str());
+ }
+ if(!this->ReadPropertyEntry(entryKey, e))
+ {
+ e.Initialized = true;
+ this->Cache[entryKey] = e;
+ }
+ }
+ }
+ }
+ else
+ {
+ cmSystemTools::Error("Parse error in cache file ", cacheFile.c_str(),
+ ". Offending entry: ", realbuffer);
+ }
+ }
+ this->CacheMajorVersion = 0;
+ this->CacheMinorVersion = 0;
+ if(const char* cmajor = this->GetCacheValue("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(sscanf(cminor, "%u", &v) == 1)
+ {
+ this->CacheMinorVersion = v;
+ }
+ }
+ }
+ else
+ {
+ // CMake version not found in the list file.
+ // 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);
+ this->AddCacheEntry("CMAKE_CACHE_MAJOR_VERSION", "0",
+ "Major version of cmake used to create the "
+ "current loaded cache", cmCacheManager::INTERNAL);
+
+ }
+ // check to make sure the cache directory has not
+ // been moved
+ if ( internal && this->GetCacheValue("CMAKE_CACHEFILE_DIR") )
+ {
+ std::string currentcwd = path;
+ std::string oldcwd = this->GetCacheValue("CMAKE_CACHEFILE_DIR");
+ cmSystemTools::ConvertToUnixSlashes(currentcwd);
+ currentcwd += "/CMakeCache.txt";
+ oldcwd += "/CMakeCache.txt";
+ if(!cmSystemTools::SameFile(oldcwd.c_str(), currentcwd.c_str()))
+ {
+ 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(" 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");
+ cmSystemTools::Error(message.c_str());
+ }
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+const char* cmCacheManager::PersistentProperties[] =
+{
+ "ADVANCED",
+ "MODIFIED",
+ "STRINGS",
+ 0
+};
+
+//----------------------------------------------------------------------------
+bool cmCacheManager::ReadPropertyEntry(std::string const& entryKey,
+ CacheEntry& e)
+{
+ // All property entries are internal.
+ if(e.Type != cmCacheManager::INTERNAL)
+ {
+ return false;
+ }
+
+ const char* end = entryKey.c_str() + entryKey.size();
+ for(const char** p = this->PersistentProperties; *p; ++p)
+ {
+ std::string::size_type plen = strlen(*p) + 1;
+ if(entryKey.size() > plen && *(end-plen) == '-' &&
+ strcmp(end-plen+1, *p) == 0)
+ {
+ std::string key = entryKey.substr(0, entryKey.size() - plen);
+ cmCacheManager::CacheIterator it = this->GetCacheIterator(key.c_str());
+ if(it.IsAtEnd())
+ {
+ // Create an entry and store the property.
+ CacheEntry& ne = this->Cache[key];
+ ne.Properties.SetCMakeInstance(this->CMakeInstance);
+ ne.Type = cmCacheManager::UNINITIALIZED;
+ ne.SetProperty(*p, e.Value.c_str());
+ }
+ else
+ {
+ // Store this property on its entry.
+ it.SetProperty(*p, e.Value.c_str());
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+void cmCacheManager::WritePropertyEntries(std::ostream& os,
+ CacheIterator const& i)
+{
+ for(const char** p = this->PersistentProperties; *p; ++p)
+ {
+ if(const char* value = i.GetProperty(*p))
+ {
+ std::string helpstring = *p;
+ helpstring += " property for variable: ";
+ helpstring += i.GetName();
+ cmCacheManager::OutputHelpString(os, helpstring);
+
+ std::string key = i.GetName();
+ key += "-";
+ key += *p;
+ this->OutputKey(os, key);
+ os << ":INTERNAL=";
+ this->OutputValue(os, value);
+ os << "\n";
+ }
+ }
+}
+
+bool cmCacheManager::SaveCache(cmMakefile* mf)
+{
+ return this->SaveCache(mf->GetHomeOutputDirectory());
+}
+
+
+bool cmCacheManager::SaveCache(const char* path)
+{
+ std::string cacheFile = path;
+ cacheFile += "/CMakeCache.txt";
+ cmGeneratedFileStream fout(cacheFile.c_str());
+ fout.SetCopyIfDifferent(true);
+ if(!fout)
+ {
+ cmSystemTools::Error("Unable to open cache file for save. ",
+ cacheFile.c_str());
+ cmSystemTools::ReportLastSystemError("");
+ return false;
+ }
+ // before writing the cache, update the version numbers
+ // to the
+ char temp[1024];
+ 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);
+ 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);
+ 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);
+
+ // Let us store the current working directory so that if somebody
+ // Copies it, he will not be surprised
+ std::string currentcwd = path;
+ if ( currentcwd[0] >= 'A' && currentcwd[0] <= 'Z' &&
+ currentcwd[1] == ':' )
+ {
+ // Cast added to avoid compiler warning. Cast is ok because
+ // value is guaranteed to fit in char by the above if...
+ currentcwd[0] = static_cast<char>(currentcwd[0] - 'A' + 'a');
+ }
+ cmSystemTools::ConvertToUnixSlashes(currentcwd);
+ this->AddCacheEntry("CMAKE_CACHEFILE_DIR", currentcwd.c_str(),
+ "This is the directory where this CMakeCache.txt"
+ " was created", cmCacheManager::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;
+ }
+
+ fout << "# You can edit this file to change values found and used by cmake."
+ << std::endl
+ << "# If you do not want to change any of the values, simply exit the "
+ "editor." << std::endl
+ << "# If you do want to change a value, simply edit, save, and exit "
+ "the editor." << std::endl
+ << "# The syntax for the file is as follows:\n"
+ << "# KEY:TYPE=VALUE\n"
+ << "# KEY is the name of a variable in the cache.\n"
+ << "# TYPE is a hint to GUI's for the type of VALUE, DO NOT EDIT "
+ "TYPE!." << std::endl
+ << "# VALUE is the current value for the KEY.\n\n";
+
+ fout << "########################\n";
+ fout << "# EXTERNAL cache entries\n";
+ fout << "########################\n";
+ fout << "\n";
+
+ for( std::map<cmStdString, CacheEntry>::const_iterator i =
+ this->Cache.begin(); i != this->Cache.end(); ++i)
+ {
+ const CacheEntry& ce = (*i).second;
+ CacheEntryType t = ce.Type;
+ if(!ce.Initialized)
+ {
+ /*
+ // This should be added in, but is not for now.
+ cmSystemTools::Error("Cache entry \"", (*i).first.c_str(),
+ "\" is uninitialized");
+ */
+ }
+ else if(t != INTERNAL)
+ {
+ // Format is key:type=value
+ if(const char* help = ce.GetProperty("HELPSTRING"))
+ {
+ cmCacheManager::OutputHelpString(fout, help);
+ }
+ else
+ {
+ cmCacheManager::OutputHelpString(fout, "Missing description");
+ }
+ this->OutputKey(fout, i->first);
+ fout << ":" << cmCacheManagerTypes[t] << "=";
+ this->OutputValue(fout, ce.Value);
+ fout << "\n\n";
+ }
+ }
+
+ fout << "\n";
+ fout << "########################\n";
+ fout << "# INTERNAL cache entries\n";
+ fout << "########################\n";
+ fout << "\n";
+
+ for( cmCacheManager::CacheIterator i = this->NewIterator();
+ !i.IsAtEnd(); i.Next())
+ {
+ if ( !i.Initialized() )
+ {
+ continue;
+ }
+
+ CacheEntryType t = i.GetType();
+ this->WritePropertyEntries(fout, i);
+ if(t == cmCacheManager::INTERNAL)
+ {
+ // Format is key:type=value
+ if(const char* help = i.GetProperty("HELPSTRING"))
+ {
+ this->OutputHelpString(fout, help);
+ }
+ this->OutputKey(fout, i.GetName());
+ fout << ":" << cmCacheManagerTypes[t] << "=";
+ this->OutputValue(fout, i.GetValue());
+ fout << "\n";
+ }
+ }
+ fout << "\n";
+ fout.Close();
+ std::string checkCacheFile = path;
+ checkCacheFile += cmake::GetCMakeFilesDirectory();
+ cmSystemTools::MakeDirectory(checkCacheFile.c_str());
+ checkCacheFile += "/cmake.check_cache";
+ std::ofstream checkCache(checkCacheFile.c_str());
+ if(!checkCache)
+ {
+ cmSystemTools::Error("Unable to open check cache file for write. ",
+ checkCacheFile.c_str());
+ return false;
+ }
+ checkCache << "# This file is generated by cmake for dependency checking "
+ "of the CMakeCache.txt file\n";
+ return true;
+}
+
+bool cmCacheManager::DeleteCache(const char* path)
+{
+ std::string cacheFile = path;
+ cmSystemTools::ConvertToUnixSlashes(cacheFile);
+ std::string cmakeFiles = cacheFile;
+ cacheFile += "/CMakeCache.txt";
+ cmSystemTools::RemoveFile(cacheFile.c_str());
+ // now remove the files in the CMakeFiles directory
+ // this cleans up language cache files
+ cmsys::Directory dir;
+ cmakeFiles += cmake::GetCMakeFilesDirectory();
+ dir.Load(cmakeFiles.c_str());
+ for (unsigned long fileNum = 0;
+ fileNum < dir.GetNumberOfFiles();
+ ++fileNum)
+ {
+ if(!cmSystemTools::
+ FileIsDirectory(dir.GetFile(fileNum)))
+ {
+ std::string fullPath = cmakeFiles;
+ fullPath += "/";
+ fullPath += dir.GetFile(fileNum);
+ cmSystemTools::RemoveFile(fullPath.c_str());
+ }
+ }
+ return true;
+}
+
+void cmCacheManager::OutputKey(std::ostream& fout, std::string const& key)
+{
+ // support : in key name by double quoting
+ const char* q = (key.find(':') != key.npos ||
+ key.find("//") == 0)? "\"" : "";
+ fout << q << key << q;
+}
+
+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() &&
+ (value[value.size() - 1] == ' ' ||
+ value[value.size() - 1] == '\t'))
+ {
+ fout << '\'' << value << '\'';
+ }
+ else
+ {
+ fout << value;
+ }
+}
+
+void cmCacheManager::OutputHelpString(std::ostream& fout,
+ const std::string& helpString)
+{
+ std::string::size_type end = helpString.size();
+ if(end == 0)
+ {
+ return;
+ }
+ std::string oneLine;
+ std::string::size_type pos = 0;
+ for (std::string::size_type i=0; i<=end; i++)
+ {
+ if ((i==end)
+ || (helpString[i]=='\n')
+ || ((i-pos >= 60) && (helpString[i]==' ')))
+ {
+ fout << "//";
+ if (helpString[pos] == '\n')
+ {
+ pos++;
+ fout << "\\n";
+ }
+ oneLine = helpString.substr(pos, i - pos);
+ fout << oneLine.c_str() << "\n";
+ pos = i;
+ }
+ }
+}
+
+void cmCacheManager::RemoveCacheEntry(const char* key)
+{
+ CacheEntryMap::iterator i = this->Cache.find(key);
+ if(i != this->Cache.end())
+ {
+ this->Cache.erase(i);
+ }
+}
+
+
+cmCacheManager::CacheEntry *cmCacheManager::GetCacheEntry(const char* key)
+{
+ CacheEntryMap::iterator i = this->Cache.find(key);
+ if(i != this->Cache.end())
+ {
+ return &i->second;
+ }
+ return 0;
+}
+
+cmCacheManager::CacheIterator cmCacheManager::GetCacheIterator(
+ const char *key)
+{
+ return CacheIterator(*this, key);
+}
+
+const char* cmCacheManager::GetCacheValue(const char* key) const
+{
+ CacheEntryMap::const_iterator i = this->Cache.find(key);
+ if(i != this->Cache.end() &&
+ i->second.Initialized)
+ {
+ return i->second.Value.c_str();
+ }
+ return 0;
+}
+
+
+void cmCacheManager::PrintCache(std::ostream& out) const
+{
+ out << "=================================================" << std::endl;
+ out << "CMakeCache Contents:" << std::endl;
+ for(std::map<cmStdString, CacheEntry>::const_iterator i =
+ this->Cache.begin(); i != this->Cache.end(); ++i)
+ {
+ if((*i).second.Type != INTERNAL)
+ {
+ out << (*i).first.c_str() << " = " << (*i).second.Value.c_str()
+ << std::endl;
+ }
+ }
+ out << "\n\n";
+ out << "To change values in the CMakeCache, "
+ << std::endl << "edit CMakeCache.txt in your output directory.\n";
+ out << "=================================================" << std::endl;
+}
+
+
+void cmCacheManager::AddCacheEntry(const char* key,
+ const char* value,
+ const char* helpString,
+ CacheEntryType type)
+{
+ CacheEntry& e = this->Cache[key];
+ e.Properties.SetCMakeInstance(this->CMakeInstance);
+ if ( value )
+ {
+ e.Value = value;
+ e.Initialized = true;
+ }
+ else
+ {
+ e.Value = "";
+ }
+ e.Type = type;
+ // make sure we only use unix style paths
+ if(type == FILEPATH || type == PATH)
+ {
+ if(e.Value.find(';') != e.Value.npos)
+ {
+ std::vector<std::string> paths;
+ cmSystemTools::ExpandListArgument(e.Value, paths);
+ const char* sep = "";
+ e.Value = "";
+ for(std::vector<std::string>::iterator i = paths.begin();
+ i != paths.end(); ++i)
+ {
+ cmSystemTools::ConvertToUnixSlashes(*i);
+ e.Value += sep;
+ e.Value += *i;
+ sep = ";";
+ }
+ }
+ else
+ {
+ cmSystemTools::ConvertToUnixSlashes(e.Value);
+ }
+ }
+ e.SetProperty("HELPSTRING", helpString? helpString :
+ "(This variable does not exist and should not be used)");
+ this->Cache[key] = e;
+}
+
+bool cmCacheManager::CacheIterator::IsAtEnd() const
+{
+ return this->Position == this->Container.Cache.end();
+}
+
+void cmCacheManager::CacheIterator::Begin()
+{
+ this->Position = this->Container.Cache.begin();
+}
+
+bool cmCacheManager::CacheIterator::Find(const char* key)
+{
+ this->Position = this->Container.Cache.find(key);
+ return !this->IsAtEnd();
+}
+
+void cmCacheManager::CacheIterator::Next()
+{
+ if (!this->IsAtEnd())
+ {
+ ++this->Position;
+ }
+}
+
+void cmCacheManager::CacheIterator::SetValue(const char* value)
+{
+ if (this->IsAtEnd())
+ {
+ return;
+ }
+ CacheEntry* entry = &this->GetEntry();
+ if ( value )
+ {
+ entry->Value = value;
+ entry->Initialized = true;
+ }
+ else
+ {
+ entry->Value = "";
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmCacheManager::CacheIterator::GetValueAsBool() const
+{
+ return cmSystemTools::IsOn(this->GetEntry().Value.c_str());
+}
+
+//----------------------------------------------------------------------------
+const char*
+cmCacheManager::CacheEntry::GetProperty(const char* prop) const
+{
+ if(strcmp(prop, "TYPE") == 0)
+ {
+ return cmCacheManagerTypes[this->Type];
+ }
+ else if(strcmp(prop, "VALUE") == 0)
+ {
+ return this->Value.c_str();
+ }
+ bool c = false;
+ return
+ this->Properties.GetPropertyValue(prop, cmProperty::CACHE, c);
+}
+
+//----------------------------------------------------------------------------
+void cmCacheManager::CacheEntry::SetProperty(const char* prop,
+ const char* value)
+{
+ if(strcmp(prop, "TYPE") == 0)
+ {
+ this->Type = cmCacheManager::StringToType(value? value : "STRING");
+ }
+ else if(strcmp(prop, "VALUE") == 0)
+ {
+ this->Value = value? value : "";
+ }
+ else
+ {
+ this->Properties.SetProperty(prop, value, cmProperty::CACHE);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmCacheManager::CacheEntry::AppendProperty(const char* prop,
+ const char* value,
+ bool asString)
+{
+ if(strcmp(prop, "TYPE") == 0)
+ {
+ this->Type = cmCacheManager::StringToType(value? value : "STRING");
+ }
+ else if(strcmp(prop, "VALUE") == 0)
+ {
+ if(value)
+ {
+ if(!this->Value.empty() && *value && !asString)
+ {
+ this->Value += ";";
+ }
+ this->Value += value;
+ }
+ }
+ else
+ {
+ this->Properties.AppendProperty(prop, value, cmProperty::CACHE, asString);
+ }
+}
+
+//----------------------------------------------------------------------------
+const char* cmCacheManager::CacheIterator::GetProperty(const char* prop) const
+{
+ if(!this->IsAtEnd())
+ {
+ return this->GetEntry().GetProperty(prop);
+ }
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+void cmCacheManager::CacheIterator::SetProperty(const char* p, const char* v)
+{
+ if(!this->IsAtEnd())
+ {
+ this->GetEntry().SetProperty(p, v);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmCacheManager::CacheIterator::AppendProperty(const char* p,
+ const char* v,
+ bool asString)
+{
+ if(!this->IsAtEnd())
+ {
+ this->GetEntry().AppendProperty(p, v, asString);
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmCacheManager::CacheIterator::GetPropertyAsBool(const char* prop) const
+{
+ if(const char* value = this->GetProperty(prop))
+ {
+ return cmSystemTools::IsOn(value);
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+void cmCacheManager::CacheIterator::SetProperty(const char* p, bool v)
+{
+ this->SetProperty(p, v ? "ON" : "OFF");
+}
+
+//----------------------------------------------------------------------------
+bool cmCacheManager::CacheIterator::PropertyExists(const char* 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
new file mode 100644
index 000000000..9c94d214c
--- /dev/null
+++ b/Source/cmCacheManager.h
@@ -0,0 +1,189 @@
+/*============================================================================
+ 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 cmCacheManager_h
+#define cmCacheManager_h
+
+#include "cmStandardIncludes.h"
+#include "cmPropertyMap.h"
+class cmMakefile;
+class cmMarkAsAdvancedCommand;
+class cmake;
+
+/** \class cmCacheManager
+ * \brief Control class for cmake's cache
+ *
+ * Load and Save CMake cache files.
+ *
+ */
+class cmCacheManager
+{
+public:
+ cmCacheManager(cmake* cm);
+ class CacheIterator;
+ friend class cmCacheManager::CacheIterator;
+ enum CacheEntryType{ BOOL=0, PATH, FILEPATH, STRING, INTERNAL,STATIC,
+ UNINITIALIZED };
+
+private:
+ struct CacheEntry
+ {
+ std::string Value;
+ 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,
+ bool asString=false);
+ bool Initialized;
+ CacheEntry() : Value(""), Type(UNINITIALIZED), Initialized(false)
+ {}
+ };
+
+public:
+ class CacheIterator
+ {
+ public:
+ void Begin();
+ bool Find(const char*);
+ 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,
+ bool asString=false);
+ void SetProperty(const char* 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; }
+ bool Initialized() { return this->GetEntry().Initialized; }
+ cmCacheManager &Container;
+ std::map<cmStdString, CacheEntry>::iterator Position;
+ CacheIterator(cmCacheManager &cm) : Container(cm) {
+ this->Begin();
+ }
+ CacheIterator(cmCacheManager &cm, const char* key) : Container(cm)
+ {
+ if ( key )
+ {
+ this->Find(key);
+ }
+ }
+ private:
+ CacheEntry const& GetEntry() const { return this->Position->second; }
+ CacheEntry& GetEntry() { return this->Position->second; }
+ };
+
+ ///! return an iterator to iterate through the cache map
+ cmCacheManager::CacheIterator NewIterator()
+ {
+ 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*) ;
+ ///! Save cache for given makefile. Saves to ouput path/CMakeCache.txt
+ bool SaveCache(const char* path) ;
+
+ ///! Delete the cache given
+ bool DeleteCache(const char* path);
+
+ ///! Print the cache to a stream
+ void PrintCache(std::ostream&) const;
+
+ ///! Get the iterator for an entry with a given key.
+ cmCacheManager::CacheIterator GetCacheIterator(const char *key=0);
+
+ ///! Remove an entry from the cache
+ void RemoveCacheEntry(const char* 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;
+
+ /** 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);
+
+ /** Define and document CACHE entry properties. */
+ static void DefineProperties(cmake *cm);
+
+protected:
+ ///! Add an entry into the cache
+ void AddCacheEntry(const char* key, const char* value,
+ const char* helpString, CacheEntryType type);
+
+ ///! Get a cache entry object for a key
+ CacheEntry *GetCacheEntry(const char *key);
+ ///! Clean out the CMakeFiles directory if no CMakeCache.txt
+ void CleanCMakeFiles(const char* path);
+
+ // Cache version info
+ unsigned int CacheMajorVersion;
+ unsigned int CacheMinorVersion;
+private:
+ cmake* CMakeInstance;
+ typedef std::map<cmStdString, CacheEntry> CacheEntryMap;
+ static void OutputHelpString(std::ostream& fout,
+ const std::string& helpString);
+ static void OutputKey(std::ostream& fout, std::string const& key);
+ static void OutputValue(std::ostream& fout, std::string const& value);
+
+ static const char* PersistentProperties[];
+ bool ReadPropertyEntry(std::string const& key, CacheEntry& e);
+ void WritePropertyEntries(std::ostream& os, CacheIterator const& i);
+
+ CacheEntryMap Cache;
+ // Only cmake and cmMakefile 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 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
new file mode 100644
index 000000000..0c154770d
--- /dev/null
+++ b/Source/cmCallVisualStudioMacro.cxx
@@ -0,0 +1,540 @@
+/*============================================================================
+ 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 "cmCallVisualStudioMacro.h"
+#include "cmSystemTools.h"
+
+
+#if defined(_MSC_VER)
+#define HAVE_COMDEF_H
+#endif
+
+
+// Just for this file:
+//
+static bool LogErrorsAsMessages;
+
+
+#if defined(HAVE_COMDEF_H)
+
+
+#include <comdef.h>
+
+
+//----------------------------------------------------------------------------
+// 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")
+# else
+# pragma comment(lib, "comsuppw.lib")
+# endif
+#else
+# ifdef _DEBUG
+# pragma comment(lib, "comsuppd.lib")
+# else
+# pragma comment(lib, "comsupp.lib")
+# endif
+#endif
+#else
+// VS6 only had comsupp.lib:
+# pragma comment(lib, "comsupp.lib")
+#endif
+
+
+//----------------------------------------------------------------------------
+///! Use ReportHRESULT to make a cmSystemTools::Message after calling
+///! a COM method that may have failed.
+#define ReportHRESULT(hr, context) \
+ if (FAILED(hr)) \
+ { \
+ 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()); \
+ } \
+ }
+
+
+//----------------------------------------------------------------------------
+///! Using the given instance of Visual Studio, call the named macro
+HRESULT InstanceCallMacro(
+ IDispatch* vsIDE,
+ const std::string& macro,
+ const std::string& args)
+{
+ HRESULT hr = E_POINTER;
+
+ _bstr_t macroName(macro.c_str());
+ _bstr_t macroArgs(args.c_str());
+
+ if (0 != vsIDE)
+ {
+ DISPID dispid = (DISPID) -1;
+ OLECHAR *name = L"ExecuteCommand";
+
+ hr = vsIDE->GetIDsOfNames(IID_NULL, &name, 1,
+ LOCALE_USER_DEFAULT, &dispid);
+ ReportHRESULT(hr, "GetIDsOfNames(ExecuteCommand)");
+
+ if (SUCCEEDED(hr))
+ {
+ VARIANTARG vargs[2];
+ DISPPARAMS params;
+ VARIANT result;
+ EXCEPINFO excep;
+ UINT arg = (UINT) -1;
+
+ // No VariantInit or VariantClear calls are necessary for
+ // these two vargs. They are both local _bstr_t variables
+ // that remain in scope for the duration of the Invoke call.
+ //
+ V_VT(&vargs[1]) = VT_BSTR;
+ V_BSTR(&vargs[1]) = macroName;
+ V_VT(&vargs[0]) = VT_BSTR;
+ V_BSTR(&vargs[0]) = macroArgs;
+
+ params.rgvarg = &vargs[0];
+ params.rgdispidNamedArgs = 0;
+ params.cArgs = sizeof(vargs)/sizeof(vargs[0]);
+ params.cNamedArgs = 0;
+
+ VariantInit(&result);
+
+ memset(&excep, 0, sizeof(excep));
+
+ hr = vsIDE->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT,
+ DISPATCH_METHOD, &params, &result, &excep, &arg);
+
+ std::ostringstream oss;
+ oss << std::endl;
+ oss << "Invoke(ExecuteCommand)" << std::endl;
+ oss << " Macro: " << macro.c_str() << std::endl;
+ oss << " Args: " << args.c_str() << std::endl;
+
+ if (DISP_E_EXCEPTION == hr)
+ {
+ oss << "DISP_E_EXCEPTION EXCEPINFO:" << excep.wCode << std::endl;
+ oss << " wCode: " << excep.wCode << std::endl;
+ oss << " wReserved: " << excep.wReserved << std::endl;
+ if (excep.bstrSource)
+ {
+ oss << " bstrSource: " <<
+ (const char*)(_bstr_t)excep.bstrSource << std::endl;
+ }
+ if (excep.bstrDescription)
+ {
+ oss << " bstrDescription: " <<
+ (const char*)(_bstr_t)excep.bstrDescription << std::endl;
+ }
+ if (excep.bstrHelpFile)
+ {
+ oss << " bstrHelpFile: " <<
+ (const char*)(_bstr_t)excep.bstrHelpFile << std::endl;
+ }
+ oss << " dwHelpContext: " << excep.dwHelpContext << std::endl;
+ oss << " pvReserved: " << excep.pvReserved << std::endl;
+ oss << " pfnDeferredFillIn: " << excep.pfnDeferredFillIn << std::endl;
+ oss << " scode: " << excep.scode << std::endl;
+ }
+
+ std::string exstr(oss.str());
+ ReportHRESULT(hr, exstr.c_str());
+
+ VariantClear(&result);
+ }
+ }
+
+ return hr;
+}
+
+
+//----------------------------------------------------------------------------
+///! Get the Solution object from the IDE object
+HRESULT GetSolutionObject(
+ IDispatch* vsIDE,
+ IDispatchPtr& vsSolution)
+{
+ HRESULT hr = E_POINTER;
+
+ if (0 != vsIDE)
+ {
+ DISPID dispid = (DISPID) -1;
+ OLECHAR *name = L"Solution";
+
+ hr = vsIDE->GetIDsOfNames(IID_NULL, &name, 1,
+ LOCALE_USER_DEFAULT, &dispid);
+ ReportHRESULT(hr, "GetIDsOfNames(Solution)");
+
+ if (SUCCEEDED(hr))
+ {
+ DISPPARAMS params;
+ VARIANT result;
+ EXCEPINFO excep;
+ UINT arg = (UINT) -1;
+
+ params.rgvarg = 0;
+ params.rgdispidNamedArgs = 0;
+ params.cArgs = 0;
+ params.cNamedArgs = 0;
+
+ VariantInit(&result);
+
+ memset(&excep, 0, sizeof(excep));
+
+ hr = vsIDE->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT,
+ DISPATCH_PROPERTYGET, &params, &result, &excep, &arg);
+ ReportHRESULT(hr, "Invoke(Solution)");
+
+ if (SUCCEEDED(hr))
+ {
+ vsSolution = V_DISPATCH(&result);
+ }
+
+ VariantClear(&result);
+ }
+ }
+
+ return hr;
+}
+
+
+//----------------------------------------------------------------------------
+///! Get the FullName property from the Solution object
+HRESULT GetSolutionFullName(
+ IDispatch* vsSolution,
+ std::string& fullName)
+{
+ HRESULT hr = E_POINTER;
+
+ if (0 != vsSolution)
+ {
+ DISPID dispid = (DISPID) -1;
+ OLECHAR *name = L"FullName";
+
+ hr = vsSolution->GetIDsOfNames(IID_NULL, &name, 1,
+ LOCALE_USER_DEFAULT, &dispid);
+ ReportHRESULT(hr, "GetIDsOfNames(FullName)");
+
+ if (SUCCEEDED(hr))
+ {
+ DISPPARAMS params;
+ VARIANT result;
+ EXCEPINFO excep;
+ UINT arg = (UINT) -1;
+
+ params.rgvarg = 0;
+ params.rgdispidNamedArgs = 0;
+ params.cArgs = 0;
+ params.cNamedArgs = 0;
+
+ VariantInit(&result);
+
+ memset(&excep, 0, sizeof(excep));
+
+ hr = vsSolution->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT,
+ DISPATCH_PROPERTYGET, &params, &result, &excep, &arg);
+ ReportHRESULT(hr, "Invoke(FullName)");
+
+ if (SUCCEEDED(hr))
+ {
+ fullName = (std::string) (_bstr_t) V_BSTR(&result);
+ }
+
+ VariantClear(&result);
+ }
+ }
+
+ return hr;
+}
+
+
+//----------------------------------------------------------------------------
+///! Get the FullName property from the Solution object, given the IDE object
+HRESULT GetIDESolutionFullName(
+ IDispatch* vsIDE,
+ std::string& fullName)
+{
+ IDispatchPtr vsSolution;
+ HRESULT hr = GetSolutionObject(vsIDE, vsSolution);
+ ReportHRESULT(hr, "GetSolutionObject");
+
+ if (SUCCEEDED(hr))
+ {
+ GetSolutionFullName(vsSolution, fullName);
+ ReportHRESULT(hr, "GetSolutionFullName");
+ }
+
+ return hr;
+}
+
+
+//----------------------------------------------------------------------------
+///! Get all running objects from the Windows running object table.
+///! Save them in a map by their display names.
+HRESULT GetRunningInstances(std::map<std::string, IUnknownPtr>& mrot)
+{
+ // mrot == Map of the Running Object Table
+
+ IRunningObjectTablePtr runningObjectTable;
+ IEnumMonikerPtr monikerEnumerator;
+ IMonikerPtr moniker;
+ ULONG numFetched = 0;
+
+ HRESULT hr = GetRunningObjectTable(0, &runningObjectTable);
+ ReportHRESULT(hr, "GetRunningObjectTable");
+
+ if(SUCCEEDED(hr))
+ {
+ hr = runningObjectTable->EnumRunning(&monikerEnumerator);
+ ReportHRESULT(hr, "EnumRunning");
+ }
+
+ if(SUCCEEDED(hr))
+ {
+ hr = monikerEnumerator->Reset();
+ ReportHRESULT(hr, "Reset");
+ }
+
+ if(SUCCEEDED(hr))
+ {
+ while (S_OK == monikerEnumerator->Next(1, &moniker, &numFetched))
+ {
+ std::string runningObjectName;
+ IUnknownPtr runningObjectVal;
+ IBindCtxPtr ctx;
+
+ hr = CreateBindCtx(0, &ctx);
+ ReportHRESULT(hr, "CreateBindCtx");
+
+ if(SUCCEEDED(hr))
+ {
+ LPOLESTR displayName = 0;
+ hr = moniker->GetDisplayName(ctx, 0, &displayName);
+ ReportHRESULT(hr, "GetDisplayName");
+ if (displayName)
+ {
+ runningObjectName = (std::string) (_bstr_t) displayName;
+ CoTaskMemFree(displayName);
+ }
+
+ hr = runningObjectTable->GetObject(moniker, &runningObjectVal);
+ ReportHRESULT(hr, "GetObject");
+ if(SUCCEEDED(hr))
+ {
+ mrot.insert(std::make_pair(runningObjectName, runningObjectVal));
+ }
+ }
+
+ numFetched = 0;
+ moniker = 0;
+ }
+ }
+
+ return hr;
+}
+
+
+//----------------------------------------------------------------------------
+///! Do the two file names refer to the same Visual Studio solution? Or are
+///! we perhaps looking for any and all solutions?
+bool FilesSameSolution(
+ const std::string& slnFile,
+ const std::string& slnName)
+{
+ if (slnFile == "ALL" || slnName == "ALL")
+ {
+ return true;
+ }
+
+ // Otherwise, make lowercase local copies, convert to Unix slashes, and
+ // see if the resulting strings are the same:
+ std::string s1 = cmSystemTools::LowerCase(slnFile);
+ std::string s2 = cmSystemTools::LowerCase(slnName);
+ cmSystemTools::ConvertToUnixSlashes(s1);
+ cmSystemTools::ConvertToUnixSlashes(s2);
+
+ return s1 == s2;
+}
+
+
+//----------------------------------------------------------------------------
+///! Find instances of Visual Studio with the given solution file
+///! open. Pass "ALL" for slnFile to gather all running instances
+///! of Visual Studio.
+HRESULT FindVisualStudioInstances(
+ const std::string& slnFile,
+ std::vector<IDispatchPtr>& instances)
+{
+ std::map<std::string, IUnknownPtr> mrot;
+
+ HRESULT hr = GetRunningInstances(mrot);
+ ReportHRESULT(hr, "GetRunningInstances");
+
+ if(SUCCEEDED(hr))
+ {
+ std::map<std::string, IUnknownPtr>::iterator it;
+ for(it = mrot.begin(); it != mrot.end(); ++it)
+ {
+ if (cmSystemTools::StringStartsWith(it->first.c_str(),
+ "!VisualStudio.DTE."))
+ {
+ IDispatchPtr disp(it->second);
+ if (disp != (IDispatch*) 0)
+ {
+ std::string slnName;
+ hr = GetIDESolutionFullName(disp, slnName);
+ ReportHRESULT(hr, "GetIDESolutionFullName");
+
+ if (FilesSameSolution(slnFile, slnName))
+ {
+ instances.push_back(disp);
+
+ //std::cout << "Found Visual Studio instance." << std::endl;
+ //std::cout << " ROT entry name: " << it->first << std::endl;
+ //std::cout << " ROT entry object: "
+ // << (IUnknown*) it->second << std::endl;
+ //std::cout << " slnFile: " << slnFile << std::endl;
+ //std::cout << " slnName: " << slnName << std::endl;
+ }
+ }
+ }
+ }
+ }
+
+ return hr;
+}
+
+
+#endif //defined(HAVE_COMDEF_H)
+
+
+//----------------------------------------------------------------------------
+int cmCallVisualStudioMacro::GetNumberOfRunningVisualStudioInstances(
+ const std::string& slnFile)
+{
+ int count = 0;
+
+ LogErrorsAsMessages = false;
+
+#if defined(HAVE_COMDEF_H)
+ HRESULT hr = CoInitialize(0);
+ ReportHRESULT(hr, "CoInitialize");
+
+ if(SUCCEEDED(hr))
+ {
+ std::vector<IDispatchPtr> instances;
+ hr = FindVisualStudioInstances(slnFile, instances);
+ ReportHRESULT(hr, "FindVisualStudioInstances");
+
+ if(SUCCEEDED(hr))
+ {
+ count = static_cast<int>(instances.size());
+ }
+
+ // Force release all COM pointers before CoUninitialize:
+ instances.clear();
+
+ CoUninitialize();
+ }
+#else
+ (void)slnFile;
+#endif
+
+ return count;
+}
+
+
+//----------------------------------------------------------------------------
+///! Get all running objects from the Windows running object table.
+///! Save them in a map by their display names.
+int cmCallVisualStudioMacro::CallMacro(
+ const std::string& slnFile,
+ const std::string& macro,
+ const std::string& args,
+ const bool logErrorsAsMessages)
+{
+ int err = 1; // no comdef.h
+
+ LogErrorsAsMessages = logErrorsAsMessages;
+
+#if defined(HAVE_COMDEF_H)
+ err = 2; // error initializing
+
+ HRESULT hr = CoInitialize(0);
+ ReportHRESULT(hr, "CoInitialize");
+
+ if(SUCCEEDED(hr))
+ {
+ std::vector<IDispatchPtr> instances;
+ hr = FindVisualStudioInstances(slnFile, instances);
+ ReportHRESULT(hr, "FindVisualStudioInstances");
+
+ if(SUCCEEDED(hr))
+ {
+ err = 0; // no error
+
+ std::vector<IDispatchPtr>::iterator it;
+ for(it = instances.begin(); it != instances.end(); ++it)
+ {
+ hr = InstanceCallMacro(*it, macro, args);
+ ReportHRESULT(hr, "InstanceCallMacro");
+
+ if (FAILED(hr))
+ {
+ err = 3; // error attempting to call the macro
+ }
+ }
+
+ if(0 == instances.size())
+ {
+ // no instances to call
+
+ //cmSystemTools::Message(
+ // "cmCallVisualStudioMacro::CallMacro no instances found to call",
+ // "Warning");
+ }
+ }
+
+ // Force release all COM pointers before CoUninitialize:
+ instances.clear();
+
+ CoUninitialize();
+ }
+#else
+ (void)slnFile;
+ (void)macro;
+ (void)args;
+ if (LogErrorsAsMessages)
+ {
+ cmSystemTools::Message("cmCallVisualStudioMacro::CallMacro is not "
+ "supported on this platform");
+ }
+#endif
+
+ if (err && LogErrorsAsMessages)
+ {
+ std::ostringstream oss;
+ oss << "cmCallVisualStudioMacro::CallMacro failed, err = " << err;
+ cmSystemTools::Message(oss.str().c_str());
+ }
+
+ return 0;
+}
diff --git a/Source/cmCallVisualStudioMacro.h b/Source/cmCallVisualStudioMacro.h
new file mode 100644
index 000000000..09bddfa25
--- /dev/null
+++ b/Source/cmCallVisualStudioMacro.h
@@ -0,0 +1,45 @@
+/*============================================================================
+ 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 cmCallVisualStudioMacro_h
+#define cmCallVisualStudioMacro_h
+
+#include "cmStandardIncludes.h"
+
+/** \class cmCallVisualStudioMacro
+ * \brief Control class for communicating with CMake's Visual Studio macros
+ *
+ * Find running instances of Visual Studio by full path solution name.
+ * Call a Visual Studio IDE macro in any of those instances.
+ */
+class cmCallVisualStudioMacro
+{
+public:
+ ///! Call the named macro in instances of Visual Studio with the
+ ///! given solution file open. Pass "ALL" for slnFile to call the
+ ///! macro in each Visual Studio instance.
+ static int CallMacro(const std::string& slnFile,
+ const std::string& macro,
+ const std::string& args,
+ const bool logErrorsAsMessages);
+
+ ///! Count the number of running instances of Visual Studio with the
+ ///! given solution file open. Pass "ALL" for slnFile to count all
+ ///! running Visual Studio instances.
+ static int GetNumberOfRunningVisualStudioInstances(
+ const std::string& slnFile);
+
+protected:
+
+private:
+};
+
+#endif
diff --git a/Source/cmCommand.h b/Source/cmCommand.h
new file mode 100644
index 000000000..4faaee3ac
--- /dev/null
+++ b/Source/cmCommand.h
@@ -0,0 +1,195 @@
+/*============================================================================
+ 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 cmCommand_h
+#define cmCommand_h
+
+#include "cmObject.h"
+#include "cmListFileCache.h"
+#include "cmMakefile.h"
+#include "cmCommandArgumentsHelper.h"
+
+/** \class cmCommand
+ * \brief Superclass for all commands in CMake.
+ *
+ * cmCommand is the base class for all commands in CMake. A command
+ * manifests as an entry in CMakeLists.txt and produces one or
+ * more makefile rules. Commands are associated with a particular
+ * makefile. This base class cmCommand defines the API for commands
+ * to support such features as enable/disable, inheritance,
+ * documentation, and construction.
+ */
+class cmCommand : public cmObject
+{
+public:
+ cmTypeMacro(cmCommand, cmObject);
+
+ /**
+ * Construct the command. By default it is enabled with no makefile.
+ */
+ cmCommand()
+ {this->Makefile = 0; this->Enabled = true;}
+
+ /**
+ * Need virtual destructor to destroy real command type.
+ */
+ virtual ~cmCommand() {}
+
+ /**
+ * Specify the makefile.
+ */
+ void SetMakefile(cmMakefile*m)
+ {this->Makefile = m; }
+ cmMakefile* GetMakefile() { return this->Makefile; }
+
+ /**
+ * This is called by the cmMakefile when the command is first
+ * encountered in the CMakeLists.txt file. It expands the command's
+ * arguments and then invokes the InitialPass.
+ */
+ virtual bool InvokeInitialPass(const std::vector<cmListFileArgument>& args,
+ cmExecutionStatus &status)
+ {
+ std::vector<std::string> expandedArguments;
+ if(!this->Makefile->ExpandArguments(args, expandedArguments))
+ {
+ // There was an error expanding arguments. It was already
+ // reported, so we can skip this command without error.
+ return true;
+ }
+ return this->InitialPass(expandedArguments,status);
+ }
+
+ /**
+ * This is called when the command is first encountered in
+ * the CMakeLists.txt file.
+ */
+ virtual bool InitialPass(std::vector<std::string> const& args,
+ cmExecutionStatus &) = 0;
+
+ /**
+ * This is called at the end after all the information
+ * specified by the command is accumulated. Most commands do
+ * not implement this method. At this point, reading and
+ * writing to the cache can be done.
+ */
+ virtual void FinalPass() {};
+
+ /**
+ * Does this command have a final pass? Query after InitialPass.
+ */
+ virtual bool HasFinalPass() const { return false; }
+
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone() = 0;
+
+ /**
+ * This determines if the command is invoked when in script mode.
+ */
+ virtual bool IsScriptable() const
+ {
+ return false;
+ }
+
+ /**
+ * 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
+ * which cannot provide appropriate documentation.
+ */
+ virtual bool ShouldAppearInDocumentation() const
+ {
+ return true;
+ }
+
+ /**
+ * 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;
+
+ /**
+ * Enable the command.
+ */
+ void EnabledOn()
+ {this->Enabled = true;}
+
+ /**
+ * Disable the command.
+ */
+ void EnabledOff()
+ {this->Enabled = false;}
+
+ /**
+ * Query whether the command is enabled.
+ */
+ bool GetEnabled() const
+ {return this->Enabled;}
+
+ /**
+ * Disable or enable the command.
+ */
+ void SetEnabled(bool enabled)
+ {this->Enabled = enabled;}
+
+ /**
+ * Return the last error string.
+ */
+ const char* GetError()
+ {
+ if(this->Error.length() == 0)
+ {
+ this->Error = this->GetName();
+ this->Error += " unknown error.";
+ }
+ return this->Error.c_str();
+ }
+
+ /**
+ * Set the error message
+ */
+ void SetError(const char* e)
+ {
+ this->Error = this->GetName();
+ this->Error += " ";
+ this->Error += e;
+ }
+
+protected:
+ cmMakefile* Makefile;
+ cmCommandArgumentsHelper Helper;
+
+private:
+ bool Enabled;
+ std::string Error;
+};
+
+#endif
diff --git a/Source/cmCommandArgumentLexer.cxx b/Source/cmCommandArgumentLexer.cxx
new file mode 100644
index 000000000..1d7140bb2
--- /dev/null
+++ b/Source/cmCommandArgumentLexer.cxx
@@ -0,0 +1,2077 @@
+/*============================================================================
+ 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"
+
+#line 2 "cmCommandArgumentLexer.cxx"
+
+#line 4 "cmCommandArgumentLexer.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 cmCommandArgument_yyrestart(yyin ,yyscanner )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#define YY_BUF_SIZE 16384
+#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 cmCommandArgument_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 cmCommandArgument_yyrestart (FILE *input_file ,yyscan_t yyscanner );
+void cmCommandArgument_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+YY_BUFFER_STATE cmCommandArgument_yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
+void cmCommandArgument_yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void cmCommandArgument_yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void cmCommandArgument_yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+void cmCommandArgument_yypop_buffer_state (yyscan_t yyscanner );
+
+static void cmCommandArgument_yyensure_buffer_stack (yyscan_t yyscanner );
+static void cmCommandArgument_yy_load_buffer_state (yyscan_t yyscanner );
+static void cmCommandArgument_yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );
+
+#define YY_FLUSH_BUFFER cmCommandArgument_yy_flush_buffer(YY_CURRENT_BUFFER ,yyscanner)
+
+YY_BUFFER_STATE cmCommandArgument_yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
+YY_BUFFER_STATE cmCommandArgument_yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
+YY_BUFFER_STATE cmCommandArgument_yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
+
+void *cmCommandArgument_yyalloc (yy_size_t ,yyscan_t yyscanner );
+void *cmCommandArgument_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
+void cmCommandArgument_yyfree (void * ,yyscan_t yyscanner );
+
+#define yy_new_buffer cmCommandArgument_yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){ \
+ cmCommandArgument_yyensure_buffer_stack (yyscanner); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ cmCommandArgument_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 ){\
+ cmCommandArgument_yyensure_buffer_stack (yyscanner); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ cmCommandArgument_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 cmCommandArgument_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 14
+#define YY_END_OF_BUFFER 15
+/* 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[30] =
+ { 0,
+ 0, 0, 0, 0, 0, 0, 15, 9, 10, 7,
+ 6, 14, 11, 5, 12, 13, 9, 0, 0, 4,
+ 7, 0, 8, 2, 0, 3, 0, 1, 0
+ } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 3, 1, 1, 1, 1,
+ 1, 1, 4, 1, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 1, 1, 1,
+ 1, 1, 1, 5, 4, 4, 4, 4, 6, 4,
+ 4, 4, 4, 4, 4, 4, 4, 7, 4, 4,
+ 4, 4, 4, 4, 4, 8, 4, 4, 4, 4,
+ 1, 9, 1, 1, 4, 1, 4, 4, 4, 4,
+
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 10, 1, 11, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 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[12] =
+ { 0,
+ 1, 2, 3, 4, 3, 4, 4, 4, 3, 5,
+ 3
+ } ;
+
+static yyconst flex_int16_t yy_base[35] =
+ { 0,
+ 0, 0, 31, 30, 29, 28, 36, 0, 6, 16,
+ 0, 41, 41, 41, 0, 41, 0, 22, 22, 41,
+ 18, 18, 41, 41, 7, 41, 4, 41, 41, 20,
+ 21, 26, 9, 30
+ } ;
+
+static yyconst flex_int16_t yy_def[35] =
+ { 0,
+ 29, 1, 1, 1, 1, 1, 29, 30, 31, 32,
+ 33, 29, 29, 29, 34, 29, 30, 31, 18, 29,
+ 32, 33, 29, 29, 18, 29, 18, 29, 0, 29,
+ 29, 29, 29, 29
+ } ;
+
+static yyconst flex_int16_t yy_nxt[53] =
+ { 0,
+ 8, 8, 9, 10, 11, 10, 10, 10, 12, 13,
+ 14, 19, 22, 28, 27, 20, 17, 17, 17, 17,
+ 17, 17, 26, 17, 18, 18, 21, 21, 25, 21,
+ 23, 24, 23, 23, 23, 29, 16, 16, 15, 15,
+ 7, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29
+ } ;
+
+static yyconst flex_int16_t yy_chk[53] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 9, 33, 27, 25, 9, 10, 10, 21, 21,
+ 30, 30, 22, 30, 31, 31, 32, 32, 19, 32,
+ 34, 18, 34, 34, 34, 7, 6, 5, 4, 3,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29
+ } ;
+
+/* 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 "cmCommandArgumentLexer.in.l"
+#line 2 "cmCommandArgumentLexer.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.
+============================================================================*/
+/*
+
+This file must be translated to C and modified to build everywhere.
+
+Run flex like this:
+
+ flex --prefix=cmCommandArgument_yy --header-file=cmCommandArgumentLexer.h -ocmCommandArgumentLexer.cxx cmCommandArgumentLexer.in.l
+
+Modify cmCommandArgumentLexer.cxx:
+ - add #include "cmStandardIncludes.h" to top of file
+ - put header block at top of file
+ - remove TABs
+ - remove "yyscanner" argument from these methods:
+ yy_fatal_error, cmCommandArgument_yyalloc, cmCommandArgument_yyrealloc, cmCommandArgument_yyfree
+ - remove all YY_BREAK lines occurring right after return statements
+ - change while ( 1 ) to for(;;)
+ - add "return 0;" to end of cmCommandArgument_yylex
+
+Modify cmCommandArgumentLexer.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"
+
+#include "cmCommandArgumentParserHelper.h"
+
+/* Replace the lexer input function. */
+#undef YY_INPUT
+#define YY_INPUT(buf, result, max_size) \
+ { result = yyextra->LexInput(buf, max_size); }
+
+/* Include the set of tokens from the parser. */
+#include "cmCommandArgumentParserTokens.h"
+
+/*--------------------------------------------------------------------------*/
+
+
+#line 508 "cmCommandArgumentLexer.cxx"
+
+#define INITIAL 0
+#define ESCAPES 1
+#define NOESCAPES 2
+
+#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 cmCommandArgument_yylex_init (yyscan_t* scanner);
+
+int cmCommandArgument_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 cmCommandArgument_yylex_destroy (yyscan_t yyscanner );
+
+int cmCommandArgument_yyget_debug (yyscan_t yyscanner );
+
+void cmCommandArgument_yyset_debug (int debug_flag ,yyscan_t yyscanner );
+
+YY_EXTRA_TYPE cmCommandArgument_yyget_extra (yyscan_t yyscanner );
+
+void cmCommandArgument_yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
+
+FILE *cmCommandArgument_yyget_in (yyscan_t yyscanner );
+
+void cmCommandArgument_yyset_in (FILE * in_str ,yyscan_t yyscanner );
+
+FILE *cmCommandArgument_yyget_out (yyscan_t yyscanner );
+
+void cmCommandArgument_yyset_out (FILE * out_str ,yyscan_t yyscanner );
+
+int cmCommandArgument_yyget_leng (yyscan_t yyscanner );
+
+char *cmCommandArgument_yyget_text (yyscan_t yyscanner );
+
+int cmCommandArgument_yyget_lineno (yyscan_t yyscanner );
+
+void cmCommandArgument_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 cmCommandArgument_yywrap (yyscan_t yyscanner );
+#else
+extern int cmCommandArgument_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
+
+#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
+#define YY_READ_BUF_SIZE 8192
+#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 fwrite( yytext, yyleng, 1, yyout )
+#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 cmCommandArgument_yylex (yyscan_t yyscanner);
+
+#define YY_DECL int cmCommandArgument_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 \
+ YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp, *yy_bp;
+ register int yy_act;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+#line 64 "cmCommandArgumentLexer.in.l"
+
+
+#line 732 "cmCommandArgumentLexer.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 ) {
+ cmCommandArgument_yyensure_buffer_stack (yyscanner);
+ YY_CURRENT_BUFFER_LVALUE =
+ cmCommandArgument_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+ }
+
+ cmCommandArgument_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_match:
+ do
+ {
+ register 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 >= 30 )
+ 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] != 41 );
+
+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 66 "cmCommandArgumentLexer.in.l"
+{
+ //std::cerr << __LINE__ << " here: [" << yytext << "]" << std::endl;
+ yyextra->AllocateParserType(yylvalp, yytext+1, strlen(yytext)-2);
+ return cal_ENVCURLY;
+}
+case 2:
+YY_RULE_SETUP
+#line 72 "cmCommandArgumentLexer.in.l"
+{
+ //std::cerr << __LINE__ << " here: [" << yytext << "]" << std::endl;
+ yyextra->AllocateParserType(yylvalp, yytext+1, strlen(yytext)-2);
+ return cal_NCURLY;
+}
+case 3:
+YY_RULE_SETUP
+#line 78 "cmCommandArgumentLexer.in.l"
+{
+ //std::cerr << __LINE__ << " here: [" << yytext << "]" << std::endl;
+ yyextra->AllocateParserType(yylvalp, yytext+1, strlen(yytext)-2);
+ return cal_ATNAME;
+}
+case 4:
+YY_RULE_SETUP
+#line 84 "cmCommandArgumentLexer.in.l"
+{
+ //std::cerr << __LINE__ << " here: [" << yytext << "]" << std::endl;
+ //yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext));
+ yylvalp->str = yyextra->DCURLYVariable;
+ return cal_DCURLY;
+}
+case 5:
+YY_RULE_SETUP
+#line 91 "cmCommandArgumentLexer.in.l"
+{
+ //std::cerr << __LINE__ << " here: [" << yytext << "]" << std::endl;
+ //yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext));
+ yylvalp->str = yyextra->RCURLYVariable;
+ return cal_RCURLY;
+}
+case 6:
+YY_RULE_SETUP
+#line 98 "cmCommandArgumentLexer.in.l"
+{
+ //std::cerr << __LINE__ << " here: [" << yytext << "]" << std::endl;
+ //yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext));
+ yylvalp->str = yyextra->ATVariable;
+ return cal_AT;
+}
+case 7:
+YY_RULE_SETUP
+#line 105 "cmCommandArgumentLexer.in.l"
+{
+ //std::cerr << __LINE__ << " here: [" << yytext << "]" << std::endl;
+ yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext));
+ return cal_NAME;
+}
+case 8:
+YY_RULE_SETUP
+#line 111 "cmCommandArgumentLexer.in.l"
+{
+ if ( !yyextra->HandleEscapeSymbol(yylvalp, *(yytext+1)) )
+ {
+ return cal_ERROR;
+ }
+ return cal_SYMBOL;
+}
+case 9:
+/* rule 9 can match eol */
+YY_RULE_SETUP
+#line 119 "cmCommandArgumentLexer.in.l"
+{
+ //std::cerr << __LINE__ << " here: [" << yytext << "]" << std::endl;
+ yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext));
+ return cal_SYMBOL;
+}
+case 10:
+YY_RULE_SETUP
+#line 125 "cmCommandArgumentLexer.in.l"
+{
+ //yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext));
+ yylvalp->str = yyextra->DOLLARVariable;
+ return cal_DOLLAR;
+}
+case 11:
+YY_RULE_SETUP
+#line 131 "cmCommandArgumentLexer.in.l"
+{
+ //yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext));
+ yylvalp->str = yyextra->LCURLYVariable;
+ return cal_LCURLY;
+}
+case 12:
+YY_RULE_SETUP
+#line 137 "cmCommandArgumentLexer.in.l"
+{
+ //yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext));
+ yylvalp->str = yyextra->BSLASHVariable;
+ return cal_BSLASH;
+}
+case 13:
+YY_RULE_SETUP
+#line 143 "cmCommandArgumentLexer.in.l"
+{
+ //yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext));
+ yylvalp->str = yyextra->BSLASHVariable;
+ return cal_SYMBOL;
+}
+case 14:
+YY_RULE_SETUP
+#line 149 "cmCommandArgumentLexer.in.l"
+ECHO;
+ YY_BREAK
+#line 943 "cmCommandArgumentLexer.cxx"
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(ESCAPES):
+case YY_STATE_EOF(NOESCAPES):
+ yyterminate();
+
+ 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
+ * cmCommandArgument_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 ( cmCommandArgument_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 */
+return 0; /* this should not happend but it should silence a warning */
+} /* end of cmCommandArgument_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;
+ register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ register char *source = yyg->yytext_ptr;
+ register 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. */
+ cmCommandArgument_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;
+ cmCommandArgument_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 *) cmCommandArgument_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)
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ yy_current_state = yyg->yy_start;
+
+ for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp )
+ {
+ register 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 >= 30 )
+ 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)
+{
+ register int yy_is_jam;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */
+ register char *yy_cp = yyg->yy_c_buf_p;
+
+ register 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 >= 30 )
+ 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 == 29);
+
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+#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. */
+ cmCommandArgument_yyrestart(yyin ,yyscanner);
+
+ /*FALLTHROUGH*/
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( cmCommandArgument_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;
+
+ 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 cmCommandArgument_yyrestart (FILE * input_file , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if ( ! YY_CURRENT_BUFFER ){
+ cmCommandArgument_yyensure_buffer_stack (yyscanner);
+ YY_CURRENT_BUFFER_LVALUE =
+ cmCommandArgument_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+ }
+
+ cmCommandArgument_yy_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner);
+ cmCommandArgument_yy_load_buffer_state(yyscanner );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ * @param yyscanner The scanner object.
+ */
+ void cmCommandArgument_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
+ * cmCommandArgument_yypop_buffer_state();
+ * cmCommandArgument_yypush_buffer_state(new_buffer);
+ */
+ cmCommandArgument_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;
+ cmCommandArgument_yy_load_buffer_state(yyscanner );
+
+ /* We don't actually know whether we did this switch during
+ * EOF (cmCommandArgument_yywrap()) processing, but the only time this flag
+ * is looked at is after cmCommandArgument_yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ yyg->yy_did_buffer_switch_on_eof = 1;
+}
+
+static void cmCommandArgument_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 cmCommandArgument_yy_create_buffer (FILE * file, int size , yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) cmCommandArgument_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in cmCommandArgument_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 *) cmCommandArgument_yyalloc(b->yy_buf_size + 2 ,yyscanner );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in cmCommandArgument_yy_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ cmCommandArgument_yy_init_buffer(b,file ,yyscanner);
+
+ return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with cmCommandArgument_yy_create_buffer()
+ * @param yyscanner The scanner object.
+ */
+ void cmCommandArgument_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 )
+ cmCommandArgument_yyfree((void *) b->yy_ch_buf ,yyscanner );
+
+ cmCommandArgument_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 cmCommandArgument_yyrestart() or at EOF.
+ */
+ static void cmCommandArgument_yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner)
+
+{
+ int oerrno = errno;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ cmCommandArgument_yy_flush_buffer(b ,yyscanner);
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then cmCommandArgument_yy_init_buffer was _probably_
+ * called from cmCommandArgument_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 cmCommandArgument_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 )
+ cmCommandArgument_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 cmCommandArgument_yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if (new_buffer == NULL)
+ return;
+
+ cmCommandArgument_yyensure_buffer_stack(yyscanner);
+
+ /* This block is copied from cmCommandArgument_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 cmCommandArgument_yy_switch_to_buffer. */
+ cmCommandArgument_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 cmCommandArgument_yypop_buffer_state (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ cmCommandArgument_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) {
+ cmCommandArgument_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 cmCommandArgument_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**)cmCommandArgument_yyalloc
+ (num_to_alloc * sizeof(struct yy_buffer_state*)
+ , yyscanner);
+ if ( ! yyg->yy_buffer_stack )
+ YY_FATAL_ERROR( "out of dynamic memory in cmCommandArgument_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**)cmCommandArgument_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 cmCommandArgument_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 cmCommandArgument_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) cmCommandArgument_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in cmCommandArgument_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;
+
+ cmCommandArgument_yy_switch_to_buffer(b ,yyscanner );
+
+ return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to cmCommandArgument_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
+ * cmCommandArgument_yy_scan_bytes() instead.
+ */
+YY_BUFFER_STATE cmCommandArgument_yy_scan_string (yyconst char * yystr , yyscan_t yyscanner)
+{
+
+ return cmCommandArgument_yy_scan_bytes(yystr,strlen(yystr) ,yyscanner);
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to cmCommandArgument_yylex() will
+ * scan from a @e copy of @a yybytes.
+ * @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 cmCommandArgument_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 *) cmCommandArgument_yyalloc(n ,yyscanner );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in cmCommandArgument_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 = cmCommandArgument_yy_scan_buffer(buf,n ,yyscanner);
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in cmCommandArgument_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 cmCommandArgument_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 cmCommandArgument_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 cmCommandArgument_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 *cmCommandArgument_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 *cmCommandArgument_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 cmCommandArgument_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 *cmCommandArgument_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 cmCommandArgument_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 cmCommandArgument_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( "cmCommandArgument_yyset_lineno called with no buffer" , yyscanner);
+
+ yylineno = line_number;
+}
+
+/** Set the current column.
+ * @param column_no
+ * @param yyscanner The scanner object.
+ */
+void cmCommandArgument_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( "cmCommandArgument_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 cmCommandArgument_yy_switch_to_buffer
+ */
+void cmCommandArgument_yyset_in (FILE * in_str , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyin = in_str ;
+}
+
+void cmCommandArgument_yyset_out (FILE * out_str , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyout = out_str ;
+}
+
+int cmCommandArgument_yyget_debug (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yy_flex_debug;
+}
+
+void cmCommandArgument_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 */
+
+/* cmCommandArgument_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 cmCommandArgument_yylex_init(yyscan_t* ptr_yy_globals)
+
+{
+ if (ptr_yy_globals == NULL){
+ errno = EINVAL;
+ return 1;
+ }
+
+ *ptr_yy_globals = (yyscan_t) cmCommandArgument_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 );
+}
+
+/* cmCommandArgument_yylex_init_extra has the same functionality as cmCommandArgument_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 cmCommandArgument_yyalloc in
+ * the yyextra field.
+ */
+
+int cmCommandArgument_yylex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals )
+
+{
+ struct yyguts_t dummy_yyguts;
+
+ cmCommandArgument_yyset_extra (yy_user_defined, &dummy_yyguts);
+
+ if (ptr_yy_globals == NULL){
+ errno = EINVAL;
+ return 1;
+ }
+
+ *ptr_yy_globals = (yyscan_t) cmCommandArgument_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));
+
+ cmCommandArgument_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 cmCommandArgument_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
+ * cmCommandArgument_yylex_init()
+ */
+ return 0;
+}
+
+/* cmCommandArgument_yylex_destroy is for both reentrant and non-reentrant scanners. */
+int cmCommandArgument_yylex_destroy (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* Pop the buffer stack, destroying each element. */
+ while(YY_CURRENT_BUFFER){
+ cmCommandArgument_yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ cmCommandArgument_yypop_buffer_state(yyscanner);
+ }
+
+ /* Destroy the stack itself. */
+ cmCommandArgument_yyfree(yyg->yy_buffer_stack ,yyscanner);
+ yyg->yy_buffer_stack = NULL;
+
+ /* Destroy the start condition stack. */
+ cmCommandArgument_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
+ * cmCommandArgument_yylex() is called, initialization will occur. */
+ yy_init_globals( yyscanner);
+
+ /* Destroy the main struct (reentrant only). */
+ cmCommandArgument_yyfree ( yyscanner , yyscanner );
+ yyscanner = NULL;
+ return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner)
+{
+ register 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)
+{
+ register int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+}
+#endif
+
+void *cmCommandArgument_yyalloc (yy_size_t size , yyscan_t)
+{
+ return (void *) malloc( size );
+}
+
+void *cmCommandArgument_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 cmCommandArgument_yyfree (void * ptr , yyscan_t)
+{
+ free( (char *) ptr ); /* see cmCommandArgument_yyrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#line 149 "cmCommandArgumentLexer.in.l"
+
+
+
+/*--------------------------------------------------------------------------*/
+void cmCommandArgument_SetupEscapes(yyscan_t yyscanner, bool noEscapes)
+{
+ /* Hack into the internal flex-generated scanner to set the state. */
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if(noEscapes)
+ {
+ BEGIN(NOESCAPES);
+ }
+ else
+ {
+ BEGIN(ESCAPES);
+ }
+}
+
diff --git a/Source/cmCommandArgumentLexer.h b/Source/cmCommandArgumentLexer.h
new file mode 100644
index 000000000..828122b9f
--- /dev/null
+++ b/Source/cmCommandArgumentLexer.h
@@ -0,0 +1,333 @@
+/*============================================================================
+ 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 cmCommandArgument_yyHEADER_H
+#define cmCommandArgument_yyHEADER_H 1
+#define cmCommandArgument_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
+#define YY_BUF_SIZE 16384
+#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 cmCommandArgument_yyrestart (FILE *input_file ,yyscan_t yyscanner );
+void cmCommandArgument_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+YY_BUFFER_STATE cmCommandArgument_yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
+void cmCommandArgument_yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void cmCommandArgument_yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void cmCommandArgument_yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+void cmCommandArgument_yypop_buffer_state (yyscan_t yyscanner );
+
+YY_BUFFER_STATE cmCommandArgument_yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
+YY_BUFFER_STATE cmCommandArgument_yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
+YY_BUFFER_STATE cmCommandArgument_yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
+
+void *cmCommandArgument_yyalloc (yy_size_t ,yyscan_t yyscanner );
+void *cmCommandArgument_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
+void cmCommandArgument_yyfree (void * ,yyscan_t yyscanner );
+
+/* Begin user sect3 */
+
+#define cmCommandArgument_yywrap(n) 1
+#define YY_SKIP_YYWRAP
+
+#define yytext_ptr yytext_r
+
+#ifdef YY_HEADER_EXPORT_START_CONDITIONS
+#define INITIAL 0
+#define ESCAPES 1
+#define NOESCAPES 2
+
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+int cmCommandArgument_yylex_init (yyscan_t* scanner);
+
+int cmCommandArgument_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 cmCommandArgument_yylex_destroy (yyscan_t yyscanner );
+
+int cmCommandArgument_yyget_debug (yyscan_t yyscanner );
+
+void cmCommandArgument_yyset_debug (int debug_flag ,yyscan_t yyscanner );
+
+YY_EXTRA_TYPE cmCommandArgument_yyget_extra (yyscan_t yyscanner );
+
+void cmCommandArgument_yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
+
+FILE *cmCommandArgument_yyget_in (yyscan_t yyscanner );
+
+void cmCommandArgument_yyset_in (FILE * in_str ,yyscan_t yyscanner );
+
+FILE *cmCommandArgument_yyget_out (yyscan_t yyscanner );
+
+void cmCommandArgument_yyset_out (FILE * out_str ,yyscan_t yyscanner );
+
+int cmCommandArgument_yyget_leng (yyscan_t yyscanner );
+
+char *cmCommandArgument_yyget_text (yyscan_t yyscanner );
+
+int cmCommandArgument_yyget_lineno (yyscan_t yyscanner );
+
+void cmCommandArgument_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 cmCommandArgument_yywrap (yyscan_t yyscanner );
+#else
+extern int cmCommandArgument_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
+#define YY_READ_BUF_SIZE 8192
+#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 cmCommandArgument_yylex (yyscan_t yyscanner);
+
+#define YY_DECL int cmCommandArgument_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 cmCommandArgument_yyIN_HEADER
+#endif /* cmCommandArgument_yyHEADER_H */
diff --git a/Source/cmCommandArgumentLexer.in.l b/Source/cmCommandArgumentLexer.in.l
new file mode 100644
index 000000000..d10e50d97
--- /dev/null
+++ b/Source/cmCommandArgumentLexer.in.l
@@ -0,0 +1,161 @@
+%{
+/*============================================================================
+ 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.
+============================================================================*/
+/*
+
+This file must be translated to C and modified to build everywhere.
+
+Run flex like this:
+
+ flex --prefix=cmCommandArgument_yy --header-file=cmCommandArgumentLexer.h -ocmCommandArgumentLexer.cxx cmCommandArgumentLexer.in.l
+
+Modify cmCommandArgumentLexer.cxx:
+ - add #include "cmStandardIncludes.h" to top of file
+ - put header block at top of file
+ - remove TABs
+ - remove "yyscanner" argument from these methods:
+ yy_fatal_error, cmCommandArgument_yyalloc, cmCommandArgument_yyrealloc, cmCommandArgument_yyfree
+ - remove all YY_BREAK lines occurring right after return statements
+ - change while ( 1 ) to for(;;)
+ - add "return 0;" to end of cmCommandArgument_yylex
+
+Modify cmCommandArgumentLexer.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"
+
+#include "cmCommandArgumentParserHelper.h"
+
+/* Replace the lexer input function. */
+#undef YY_INPUT
+#define YY_INPUT(buf, result, max_size) \
+ { result = yyextra->LexInput(buf, max_size); }
+
+/* Include the set of tokens from the parser. */
+#include "cmCommandArgumentParserTokens.h"
+
+/*--------------------------------------------------------------------------*/
+%}
+
+%option reentrant
+%option noyywrap
+%option nounput
+%pointer
+%s ESCAPES
+%s NOESCAPES
+
+%%
+
+\$ENV\{ {
+ //std::cerr << __LINE__ << " here: [" << yytext << "]" << std::endl;
+ yyextra->AllocateParserType(yylvalp, yytext+1, strlen(yytext)-2);
+ return cal_ENVCURLY;
+}
+
+\$[A-Za-z0-9/_.+-]+\{ {
+ //std::cerr << __LINE__ << " here: [" << yytext << "]" << std::endl;
+ yyextra->AllocateParserType(yylvalp, yytext+1, strlen(yytext)-2);
+ return cal_NCURLY;
+}
+
+@[A-Za-z0-9/_.+-]+@ {
+ //std::cerr << __LINE__ << " here: [" << yytext << "]" << std::endl;
+ yyextra->AllocateParserType(yylvalp, yytext+1, strlen(yytext)-2);
+ return cal_ATNAME;
+}
+
+"${" {
+ //std::cerr << __LINE__ << " here: [" << yytext << "]" << std::endl;
+ //yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext));
+ yylvalp->str = yyextra->DCURLYVariable;
+ return cal_DCURLY;
+}
+
+"}" {
+ //std::cerr << __LINE__ << " here: [" << yytext << "]" << std::endl;
+ //yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext));
+ yylvalp->str = yyextra->RCURLYVariable;
+ return cal_RCURLY;
+}
+
+"@" {
+ //std::cerr << __LINE__ << " here: [" << yytext << "]" << std::endl;
+ //yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext));
+ yylvalp->str = yyextra->ATVariable;
+ return cal_AT;
+}
+
+[A-Za-z0-9/_.+-]+ {
+ //std::cerr << __LINE__ << " here: [" << yytext << "]" << std::endl;
+ yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext));
+ return cal_NAME;
+}
+
+<ESCAPES>\\. {
+ if ( !yyextra->HandleEscapeSymbol(yylvalp, *(yytext+1)) )
+ {
+ return cal_ERROR;
+ }
+ return cal_SYMBOL;
+}
+
+[^\${}\\@]+ {
+ //std::cerr << __LINE__ << " here: [" << yytext << "]" << std::endl;
+ yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext));
+ return cal_SYMBOL;
+}
+
+"$" {
+ //yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext));
+ yylvalp->str = yyextra->DOLLARVariable;
+ return cal_DOLLAR;
+}
+
+"{" {
+ //yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext));
+ yylvalp->str = yyextra->LCURLYVariable;
+ return cal_LCURLY;
+}
+
+<ESCAPES>"\\" {
+ //yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext));
+ yylvalp->str = yyextra->BSLASHVariable;
+ return cal_BSLASH;
+}
+
+<NOESCAPES>"\\" {
+ //yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext));
+ yylvalp->str = yyextra->BSLASHVariable;
+ return cal_SYMBOL;
+}
+
+%%
+
+/*--------------------------------------------------------------------------*/
+void cmCommandArgument_SetupEscapes(yyscan_t yyscanner, bool noEscapes)
+{
+ /* Hack into the internal flex-generated scanner to set the state. */
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if(noEscapes)
+ {
+ BEGIN(NOESCAPES);
+ }
+ else
+ {
+ BEGIN(ESCAPES);
+ }
+}
diff --git a/Source/cmCommandArgumentParser.cxx b/Source/cmCommandArgumentParser.cxx
new file mode 100644
index 000000000..696a6a8c3
--- /dev/null
+++ b/Source/cmCommandArgumentParser.cxx
@@ -0,0 +1,1835 @@
+/*============================================================================
+ 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.
+============================================================================*/
+/* A Bison parser, made by GNU Bison 2.3. */
+
+/* Skeleton implementation for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ 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 2, 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, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+/* 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.3"
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers. */
+#define YYPURE 1
+
+/* Using locations. */
+#define YYLSP_NEEDED 0
+
+/* Substitute the variable and function names. */
+#define yyparse cmCommandArgument_yyparse
+#define yylex cmCommandArgument_yylex
+#define yyerror cmCommandArgument_yyerror
+#define yylval cmCommandArgument_yylval
+#define yychar cmCommandArgument_yychar
+#define yydebug cmCommandArgument_yydebug
+#define yynerrs cmCommandArgument_yynerrs
+
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ cal_ENVCURLY = 258,
+ cal_NCURLY = 259,
+ cal_DCURLY = 260,
+ cal_DOLLAR = 261,
+ cal_LCURLY = 262,
+ cal_RCURLY = 263,
+ cal_NAME = 264,
+ cal_BSLASH = 265,
+ cal_SYMBOL = 266,
+ cal_AT = 267,
+ cal_ERROR = 268,
+ cal_ATNAME = 269
+ };
+#endif
+/* Tokens. */
+#define cal_ENVCURLY 258
+#define cal_NCURLY 259
+#define cal_DCURLY 260
+#define cal_DOLLAR 261
+#define cal_LCURLY 262
+#define cal_RCURLY 263
+#define cal_NAME 264
+#define cal_BSLASH 265
+#define cal_SYMBOL 266
+#define cal_AT 267
+#define cal_ERROR 268
+#define cal_ATNAME 269
+
+
+
+
+/* Copy the first part of user declarations. */
+#line 1 "cmCommandArgumentParser.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.
+============================================================================*/
+/*
+
+This file must be translated to C and modified to build everywhere.
+
+Run bison like this:
+
+ bison --yacc --name-prefix=cmCommandArgument_yy --defines=cmCommandArgumentParserTokens.h -ocmCommandArgumentParser.cxx cmCommandArgumentParser.y
+
+Modify cmCommandArgumentParser.cxx:
+ - remove TABs
+ - put header block at top of file
+
+*/
+
+#include "cmStandardIncludes.h"
+
+/* Configure the parser to use a lexer object. */
+#define YYPARSE_PARAM yyscanner
+#define YYLEX_PARAM yyscanner
+#define YYERROR_VERBOSE 1
+#define cmCommandArgument_yyerror(x) \
+ cmCommandArgumentError(yyscanner, x)
+#define yyGetParser (cmCommandArgument_yyget_extra(yyscanner))
+
+/* Make sure malloc and free are available on QNX. */
+#ifdef __QNX__
+# include <malloc.h>
+#endif
+
+/* Make sure the parser uses standard memory allocation. The default
+ generated parser malloc/free declarations do not work on all
+ platforms. */
+#include <stdlib.h>
+#define YYMALLOC malloc
+#define YYFREE free
+
+/*-------------------------------------------------------------------------*/
+#include "cmCommandArgumentParserHelper.h" /* Interface to parser object. */
+#include "cmCommandArgumentLexer.h" /* Interface to lexer object. */
+#include "cmCommandArgumentParserTokens.h" /* Need YYSTYPE for YY_DECL. */
+
+/* Forward declare the lexer entry point. */
+YY_DECL;
+
+/* Internal utility functions. */
+static void cmCommandArgumentError(yyscan_t yyscanner, const char* message);
+
+#define YYDEBUG 1
+/* Configure the parser to support large input. */
+#define YYMAXDEPTH 100000
+#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
+ case. */
+# pragma warning (disable: 4244) /* loss of precision */
+# pragma warning (disable: 4702) /* unreachable code */
+#endif
+
+
+/* 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
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef int YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+/* Copy the second part of user declarations. */
+
+
+/* Line 216 of yacc.c. */
+#line 227 "cmCommandArgumentParser.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 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 i)
+#else
+static int
+YYID (i)
+ int i;
+#endif
+{
+ return i;
+}
+#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 _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
+# 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 _STDLIB_H \
+ && ! ((defined YYMALLOC || defined malloc) \
+ && (defined YYFREE || defined free)))
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
+# endif
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# if ! defined malloc && ! defined _STDLIB_H && (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 _STDLIB_H && (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;
+ YYSTYPE yyvs;
+ };
+
+/* 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)
+
+/* 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
+
+/* 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) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack, Stack, yysize); \
+ Stack = &yyptr->Stack; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (YYID (0))
+
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 25
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 40
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 15
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 10
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 24
+/* YYNRULES -- Number of states. */
+#define YYNSTATES 33
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
+#define YYUNDEFTOK 2
+#define YYMAXUTOK 269
+
+#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
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+ YYRHS. */
+static const yytype_uint8 yyprhs[] =
+{
+ 0, 0, 3, 5, 7, 10, 11, 14, 16, 18,
+ 20, 22, 24, 26, 28, 30, 34, 38, 42, 44,
+ 46, 49, 50, 53, 55
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const yytype_int8 yyrhs[] =
+{
+ 16, 0, -1, 17, -1, 18, -1, 18, 10, -1,
+ -1, 19, 18, -1, 20, -1, 21, -1, 9, -1,
+ 12, -1, 6, -1, 7, -1, 8, -1, 11, -1,
+ 3, 22, 8, -1, 4, 23, 8, -1, 5, 23,
+ 8, -1, 14, -1, 23, -1, 11, 22, -1, -1,
+ 24, 23, -1, 9, -1, 21, -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+static const yytype_uint8 yyrline[] =
+{
+ 0, 116, 116, 123, 128, 134, 138, 144, 149, 155,
+ 160, 165, 170, 175, 180, 186, 192, 198, 204, 210,
+ 215, 221, 225, 231, 236
+};
+#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", "cal_ENVCURLY", "cal_NCURLY",
+ "cal_DCURLY", "\"$\"", "\"{\"", "\"}\"", "cal_NAME", "\"\\\\\"",
+ "cal_SYMBOL", "\"@\"", "cal_ERROR", "cal_ATNAME", "$accept", "Start",
+ "GoalWithOptionalBackSlash", "Goal", "String", "OuterText", "Variable",
+ "EnvVarName", "MultipleIds", "ID", 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
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const yytype_uint8 yyr1[] =
+{
+ 0, 15, 16, 17, 17, 18, 18, 19, 19, 20,
+ 20, 20, 20, 20, 20, 21, 21, 21, 21, 22,
+ 22, 23, 23, 24, 24
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
+static const yytype_uint8 yyr2[] =
+{
+ 0, 2, 1, 1, 2, 0, 2, 1, 1, 1,
+ 1, 1, 1, 1, 1, 3, 3, 3, 1, 1,
+ 2, 0, 2, 1, 1
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero
+ means the default is an error. */
+static const yytype_uint8 yydefact[] =
+{
+ 5, 21, 21, 21, 11, 12, 13, 9, 14, 10,
+ 18, 0, 2, 3, 5, 7, 8, 23, 21, 24,
+ 0, 19, 21, 0, 0, 1, 4, 6, 20, 15,
+ 22, 16, 17
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const yytype_int8 yydefgoto[] =
+{
+ -1, 11, 12, 13, 14, 15, 19, 20, 21, 22
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+#define YYPACT_NINF -3
+static const yytype_int8 yypact[] =
+{
+ 0, 14, 26, 26, -3, -3, -3, -3, -3, -3,
+ -3, 10, -3, 3, 0, -3, -3, -3, 14, -3,
+ 7, -3, 26, 13, 16, -3, -3, -3, -3, -3,
+ -3, -3, -3
+};
+
+/* YYPGOTO[NTERM-NUM]. */
+static const yytype_int8 yypgoto[] =
+{
+ -3, -3, -3, 8, -3, -3, 2, 9, -2, -3
+};
+
+/* 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 zero, do what YYDEFACT says.
+ If YYTABLE_NINF, syntax error. */
+#define YYTABLE_NINF -1
+static const yytype_uint8 yytable[] =
+{
+ 23, 24, 16, 1, 2, 3, 4, 5, 6, 7,
+ 25, 8, 9, 26, 10, 29, 16, 1, 2, 3,
+ 30, 31, 27, 17, 32, 18, 0, 28, 10, 1,
+ 2, 3, 0, 0, 0, 17, 0, 0, 0, 0,
+ 10
+};
+
+static const yytype_int8 yycheck[] =
+{
+ 2, 3, 0, 3, 4, 5, 6, 7, 8, 9,
+ 0, 11, 12, 10, 14, 8, 14, 3, 4, 5,
+ 22, 8, 14, 9, 8, 11, -1, 18, 14, 3,
+ 4, 5, -1, -1, -1, 9, -1, -1, -1, -1,
+ 14
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
+static const yytype_uint8 yystos[] =
+{
+ 0, 3, 4, 5, 6, 7, 8, 9, 11, 12,
+ 14, 16, 17, 18, 19, 20, 21, 9, 11, 21,
+ 22, 23, 24, 23, 23, 0, 10, 18, 22, 8,
+ 23, 8, 8
+};
+
+#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. */
+
+#define YYFAIL goto yyerrlab
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY && yylen == 1) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ yytoken = YYTRANSLATE (yychar); \
+ 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
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+ This macro was not mandated originally: define only if we know
+ we won't break user code: when these are the locations we know. */
+
+#ifndef YY_LOCATION_PRINT
+# if YYLTYPE_IS_TRIVIAL
+# define YY_LOCATION_PRINT(File, Loc) \
+ fprintf (File, "%d.%d-%d.%d", \
+ (Loc).first_line, (Loc).first_column, \
+ (Loc).last_line, (Loc).last_column)
+# else
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#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 *bottom, yytype_int16 *top)
+#else
+static void
+yy_stack_print (bottom, top)
+ yytype_int16 *bottom;
+ yytype_int16 *top;
+#endif
+{
+ YYFPRINTF (stderr, "Stack now");
+ for (; bottom <= top; ++bottom)
+ YYFPRINTF (stderr, " %d", *bottom);
+ 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++)
+ {
+ fprintf (stderr, " $%d = ", yyi + 1);
+ yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
+ &(yyvsp[(yyi + 1) - (yynrhs)])
+ );
+ fprintf (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 YYRESULT an error message about the unexpected token
+ YYCHAR while in state YYSTATE. Return the number of bytes copied,
+ including the terminating null byte. If YYRESULT is null, do not
+ copy anything; just return the number of bytes that would be
+ copied. As a special case, return 0 if an ordinary "syntax error"
+ message will do. Return YYSIZE_MAXIMUM if overflow occurs during
+ size calculation. */
+static YYSIZE_T
+yysyntax_error (char *yyresult, int yystate, int yychar)
+{
+ int yyn = yypact[yystate];
+
+ if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
+ return 0;
+ else
+ {
+ int yytype = YYTRANSLATE (yychar);
+ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+ YYSIZE_T yysize = yysize0;
+ YYSIZE_T yysize1;
+ int yysize_overflow = 0;
+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+ int yyx;
+
+# if 0
+ /* This is so xgettext sees the translatable formats that are
+ constructed on the fly. */
+ YY_("syntax error, unexpected %s");
+ YY_("syntax error, unexpected %s, expecting %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+# endif
+ char *yyfmt;
+ char const *yyf;
+ static char const yyunexpected[] = "syntax error, unexpected %s";
+ static char const yyexpecting[] = ", expecting %s";
+ static char const yyor[] = " or %s";
+ char yyformat[sizeof yyunexpected
+ + sizeof yyexpecting - 1
+ + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+ * (sizeof yyor - 1))];
+ char const *yyprefix = yyexpecting;
+
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. */
+ 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 yycount = 1;
+
+ yyarg[0] = yytname[yytype];
+ yyfmt = yystpcpy (yyformat, yyunexpected);
+
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+ {
+ yycount = 1;
+ yysize = yysize0;
+ yyformat[sizeof yyunexpected - 1] = '\0';
+ break;
+ }
+ yyarg[yycount++] = yytname[yyx];
+ yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
+ yyfmt = yystpcpy (yyfmt, yyprefix);
+ yyprefix = yyor;
+ }
+
+ yyf = YY_(yyformat);
+ yysize1 = yysize + yystrlen (yyf);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
+
+ if (yysize_overflow)
+ return YYSIZE_MAXIMUM;
+
+ if (yyresult)
+ {
+ /* 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 = yyresult;
+ int yyi = 0;
+ while ((*yyp = *yyf) != '\0')
+ {
+ if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+ {
+ yyp += yytnamerr (yyp, yyarg[yyi++]);
+ yyf += 2;
+ }
+ else
+ {
+ yyp++;
+ yyf++;
+ }
+ }
+ }
+ return yysize;
+ }
+}
+#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 look-ahead symbol. */
+int yychar;
+
+/* The semantic value of the look-ahead symbol. */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far. */
+int yynerrs;
+
+ int yystate;
+ int yyn;
+ int yyresult;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+ /* Look-ahead token as an internal (translated) token number. */
+ int yytoken = 0;
+#if YYERROR_VERBOSE
+ /* Buffer for error messages, and its allocated size. */
+ char yymsgbuf[128];
+ char *yymsg = yymsgbuf;
+ YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+ /* Three stacks and their tools:
+ `yyss': related to states,
+ `yyvs': related to semantic values,
+ `yyls': related to locations.
+
+ Refer to the stacks thru separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ yytype_int16 yyssa[YYINITDEPTH];
+ yytype_int16 *yyss = yyssa;
+ yytype_int16 *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs = yyvsa;
+ YYSTYPE *yyvsp;
+
+
+
+#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
+
+ YYSIZE_T yystacksize = YYINITDEPTH;
+
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+
+
+ /* The number of symbols on the RHS of the reduced rule.
+ Keep to zero when no symbol should be popped. */
+ int yylen = 0;
+
+ 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);
+ YYSTACK_RELOCATE (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));
+
+ goto yybackup;
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+
+ /* Do appropriate processing given the current state. Read a
+ look-ahead token if we need one and don't already have one. */
+
+ /* First try to decide what to do without reference to look-ahead token. */
+ yyn = yypact[yystate];
+ if (yyn == YYPACT_NINF)
+ goto yydefault;
+
+ /* Not known => get a look-ahead token if don't already have one. */
+
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead 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 (yyn == 0 || yyn == YYTABLE_NINF)
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ /* Shift the look-ahead token. */
+ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+ /* Discard the shifted token unless it is eof. */
+ if (yychar != YYEOF)
+ 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 2:
+#line 117 "cmCommandArgumentParser.y"
+ {
+ (yyval.str) = 0;
+ yyGetParser->SetResult((yyvsp[(1) - (1)].str));
+}
+ break;
+
+ case 3:
+#line 124 "cmCommandArgumentParser.y"
+ {
+ (yyval.str) = (yyvsp[(1) - (1)].str);
+}
+ break;
+
+ case 4:
+#line 129 "cmCommandArgumentParser.y"
+ {
+ (yyval.str) = yyGetParser->CombineUnions((yyvsp[(1) - (2)].str), (yyvsp[(2) - (2)].str));
+}
+ break;
+
+ case 5:
+#line 134 "cmCommandArgumentParser.y"
+ {
+ (yyval.str) = 0;
+}
+ break;
+
+ case 6:
+#line 139 "cmCommandArgumentParser.y"
+ {
+ (yyval.str) = yyGetParser->CombineUnions((yyvsp[(1) - (2)].str), (yyvsp[(2) - (2)].str));
+}
+ break;
+
+ case 7:
+#line 145 "cmCommandArgumentParser.y"
+ {
+ (yyval.str) = (yyvsp[(1) - (1)].str);
+}
+ break;
+
+ case 8:
+#line 150 "cmCommandArgumentParser.y"
+ {
+ (yyval.str) = (yyvsp[(1) - (1)].str);
+}
+ break;
+
+ case 9:
+#line 156 "cmCommandArgumentParser.y"
+ {
+ (yyval.str) = (yyvsp[(1) - (1)].str);
+}
+ break;
+
+ case 10:
+#line 161 "cmCommandArgumentParser.y"
+ {
+ (yyval.str) = (yyvsp[(1) - (1)].str);
+}
+ break;
+
+ case 11:
+#line 166 "cmCommandArgumentParser.y"
+ {
+ (yyval.str) = (yyvsp[(1) - (1)].str);
+}
+ break;
+
+ case 12:
+#line 171 "cmCommandArgumentParser.y"
+ {
+ (yyval.str) = (yyvsp[(1) - (1)].str);
+}
+ break;
+
+ case 13:
+#line 176 "cmCommandArgumentParser.y"
+ {
+ (yyval.str) = (yyvsp[(1) - (1)].str);
+}
+ break;
+
+ case 14:
+#line 181 "cmCommandArgumentParser.y"
+ {
+ (yyval.str) = (yyvsp[(1) - (1)].str);
+}
+ break;
+
+ case 15:
+#line 187 "cmCommandArgumentParser.y"
+ {
+ (yyval.str) = yyGetParser->ExpandSpecialVariable((yyvsp[(1) - (3)].str),(yyvsp[(2) - (3)].str));
+ //std::cerr << __LINE__ << " here: [" << $<str>1 << "] [" << $<str>2 << "] [" << $<str>3 << "]" << std::endl;
+}
+ break;
+
+ case 16:
+#line 193 "cmCommandArgumentParser.y"
+ {
+ (yyval.str) = yyGetParser->ExpandSpecialVariable((yyvsp[(1) - (3)].str),(yyvsp[(2) - (3)].str));
+ //std::cerr << __LINE__ << " here: [" << $<str>1 << "] [" << $<str>2 << "] [" << $<str>3 << "]" << std::endl;
+}
+ break;
+
+ case 17:
+#line 199 "cmCommandArgumentParser.y"
+ {
+ (yyval.str) = yyGetParser->ExpandVariable((yyvsp[(2) - (3)].str));
+ //std::cerr << __LINE__ << " here: [" << $<str>1 << "] [" << $<str>2 << "] [" << $<str>3 << "]" << std::endl;
+}
+ break;
+
+ case 18:
+#line 205 "cmCommandArgumentParser.y"
+ {
+ (yyval.str) = yyGetParser->ExpandVariableForAt((yyvsp[(1) - (1)].str));
+}
+ break;
+
+ case 19:
+#line 211 "cmCommandArgumentParser.y"
+ {
+ (yyval.str) = (yyvsp[(1) - (1)].str);
+}
+ break;
+
+ case 20:
+#line 216 "cmCommandArgumentParser.y"
+ {
+ (yyval.str) = (yyvsp[(1) - (2)].str);
+}
+ break;
+
+ case 21:
+#line 221 "cmCommandArgumentParser.y"
+ {
+ (yyval.str) = 0;
+}
+ break;
+
+ case 22:
+#line 226 "cmCommandArgumentParser.y"
+ {
+ (yyval.str) = yyGetParser->CombineUnions((yyvsp[(1) - (2)].str), (yyvsp[(2) - (2)].str));
+}
+ break;
+
+ case 23:
+#line 232 "cmCommandArgumentParser.y"
+ {
+ (yyval.str) = (yyvsp[(1) - (1)].str);
+}
+ break;
+
+ case 24:
+#line 237 "cmCommandArgumentParser.y"
+ {
+ (yyval.str) = (yyvsp[(1) - (1)].str);
+}
+ break;
+
+
+/* Line 1267 of yacc.c. */
+#line 1606 "cmCommandArgumentParser.cxx"
+ default: break;
+ }
+ 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:
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+#if ! YYERROR_VERBOSE
+ yyerror (YY_("syntax error"));
+#else
+ {
+ YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
+ if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
+ {
+ YYSIZE_T yyalloc = 2 * yysize;
+ if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
+ yyalloc = YYSTACK_ALLOC_MAXIMUM;
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+ yymsg = (char *) YYSTACK_ALLOC (yyalloc);
+ if (yymsg)
+ yymsg_alloc = yyalloc;
+ else
+ {
+ yymsg = yymsgbuf;
+ yymsg_alloc = sizeof yymsgbuf;
+ }
+ }
+
+ if (0 < yysize && yysize <= yymsg_alloc)
+ {
+ (void) yysyntax_error (yymsg, yystate, yychar);
+ yyerror (yymsg);
+ }
+ else
+ {
+ yyerror (YY_("syntax error"));
+ if (yysize != 0)
+ goto yyexhaustedlab;
+ }
+ }
+#endif
+ }
+
+
+
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse look-ahead 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;
+ }
+ }
+
+ /* Else will try to reuse look-ahead 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:
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (yyn != YYPACT_NINF)
+ {
+ 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);
+ }
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ *++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;
+
+#ifndef yyoverflow
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here. |
+`-------------------------------------------------*/
+yyexhaustedlab:
+ yyerror (YY_("memory exhausted"));
+ yyresult = 2;
+ /* Fall through. */
+#endif
+
+yyreturn:
+ if (yychar != YYEOF && yychar != YYEMPTY)
+ 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 242 "cmCommandArgumentParser.y"
+
+/* End of grammar */
+
+/*--------------------------------------------------------------------------*/
+void cmCommandArgumentError(yyscan_t yyscanner, const char* message)
+{
+ yyGetParser->Error(message);
+}
+
+
diff --git a/Source/cmCommandArgumentParser.y b/Source/cmCommandArgumentParser.y
new file mode 100644
index 000000000..3e700c80b
--- /dev/null
+++ b/Source/cmCommandArgumentParser.y
@@ -0,0 +1,245 @@
+%{
+/*============================================================================
+ 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.
+============================================================================*/
+/*
+
+This file must be translated to C and modified to build everywhere.
+
+Run bison like this:
+
+ bison --yacc --name-prefix=cmCommandArgument_yy --defines=cmCommandArgumentParserTokens.h -ocmCommandArgumentParser.cxx cmCommandArgumentParser.y
+
+Modify cmCommandArgumentParser.cxx:
+ - remove TABs
+ - put header block at top of file
+
+*/
+
+#include "cmStandardIncludes.h"
+
+/* Configure the parser to use a lexer object. */
+#define YYPARSE_PARAM yyscanner
+#define YYLEX_PARAM yyscanner
+#define YYERROR_VERBOSE 1
+#define cmCommandArgument_yyerror(x) \
+ cmCommandArgumentError(yyscanner, x)
+#define yyGetParser (cmCommandArgument_yyget_extra(yyscanner))
+
+/* Make sure malloc and free are available on QNX. */
+#ifdef __QNX__
+# include <malloc.h>
+#endif
+
+/* Make sure the parser uses standard memory allocation. The default
+ generated parser malloc/free declarations do not work on all
+ platforms. */
+#include <stdlib.h>
+#define YYMALLOC malloc
+#define YYFREE free
+
+/*-------------------------------------------------------------------------*/
+#include "cmCommandArgumentParserHelper.h" /* Interface to parser object. */
+#include "cmCommandArgumentLexer.h" /* Interface to lexer object. */
+#include "cmCommandArgumentParserTokens.h" /* Need YYSTYPE for YY_DECL. */
+
+/* Forward declare the lexer entry point. */
+YY_DECL;
+
+/* Internal utility functions. */
+static void cmCommandArgumentError(yyscan_t yyscanner, const char* message);
+
+#define YYDEBUG 1
+/* Configure the parser to support large input. */
+#define YYMAXDEPTH 100000
+#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
+ case. */
+# pragma warning (disable: 4244) /* loss of precision */
+# pragma warning (disable: 4702) /* unreachable code */
+#endif
+%}
+
+/* Generate a reentrant parser object. */
+%pure_parser
+
+/*
+%union {
+ char* string;
+}
+*/
+
+/*-------------------------------------------------------------------------*/
+/* Tokens */
+%token cal_ENVCURLY
+%token cal_NCURLY
+%token cal_DCURLY
+%token cal_DOLLAR "$"
+%token cal_LCURLY "{"
+%token cal_RCURLY "}"
+%token cal_NAME
+%token cal_BSLASH "\\"
+%token cal_SYMBOL
+%token cal_AT "@"
+%token cal_ERROR
+%token cal_ATNAME
+
+/*-------------------------------------------------------------------------*/
+/* grammar */
+%%
+
+
+Start:
+GoalWithOptionalBackSlash
+{
+ $<str>$ = 0;
+ yyGetParser->SetResult($<str>1);
+}
+
+GoalWithOptionalBackSlash:
+Goal
+{
+ $<str>$ = $<str>1;
+}
+|
+Goal cal_BSLASH
+{
+ $<str>$ = yyGetParser->CombineUnions($<str>1, $<str>2);
+}
+
+Goal:
+{
+ $<str>$ = 0;
+}
+|
+String Goal
+{
+ $<str>$ = yyGetParser->CombineUnions($<str>1, $<str>2);
+}
+
+String:
+OuterText
+{
+ $<str>$ = $<str>1;
+}
+|
+Variable
+{
+ $<str>$ = $<str>1;
+}
+
+OuterText:
+cal_NAME
+{
+ $<str>$ = $<str>1;
+}
+|
+cal_AT
+{
+ $<str>$ = $<str>1;
+}
+|
+cal_DOLLAR
+{
+ $<str>$ = $<str>1;
+}
+|
+cal_LCURLY
+{
+ $<str>$ = $<str>1;
+}
+|
+cal_RCURLY
+{
+ $<str>$ = $<str>1;
+}
+|
+cal_SYMBOL
+{
+ $<str>$ = $<str>1;
+}
+
+Variable:
+cal_ENVCURLY EnvVarName cal_RCURLY
+{
+ $<str>$ = yyGetParser->ExpandSpecialVariable($<str>1,$<str>2);
+ //std::cerr << __LINE__ << " here: [" << $<str>1 << "] [" << $<str>2 << "] [" << $<str>3 << "]" << std::endl;
+}
+|
+cal_NCURLY MultipleIds cal_RCURLY
+{
+ $<str>$ = yyGetParser->ExpandSpecialVariable($<str>1,$<str>2);
+ //std::cerr << __LINE__ << " here: [" << $<str>1 << "] [" << $<str>2 << "] [" << $<str>3 << "]" << std::endl;
+}
+|
+cal_DCURLY MultipleIds cal_RCURLY
+{
+ $<str>$ = yyGetParser->ExpandVariable($<str>2);
+ //std::cerr << __LINE__ << " here: [" << $<str>1 << "] [" << $<str>2 << "] [" << $<str>3 << "]" << std::endl;
+}
+|
+cal_ATNAME
+{
+ $<str>$ = yyGetParser->ExpandVariableForAt($<str>1);
+}
+
+EnvVarName:
+MultipleIds
+{
+ $<str>$ = $<str>1;
+}
+|
+cal_SYMBOL EnvVarName
+{
+ $<str>$ = $<str>1;
+}
+
+MultipleIds:
+{
+ $<str>$ = 0;
+}
+|
+ID MultipleIds
+{
+ $<str>$ = yyGetParser->CombineUnions($<str>1, $<str>2);
+}
+
+ID:
+cal_NAME
+{
+ $<str>$ = $<str>1;
+}
+|
+Variable
+{
+ $<str>$ = $<str>1;
+}
+
+
+%%
+/* End of grammar */
+
+/*--------------------------------------------------------------------------*/
+void cmCommandArgumentError(yyscan_t yyscanner, const char* message)
+{
+ yyGetParser->Error(message);
+}
+
diff --git a/Source/cmCommandArgumentParserHelper.cxx b/Source/cmCommandArgumentParserHelper.cxx
new file mode 100644
index 000000000..a781767e3
--- /dev/null
+++ b/Source/cmCommandArgumentParserHelper.cxx
@@ -0,0 +1,367 @@
+/*============================================================================
+ 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 "cmCommandArgumentParserHelper.h"
+
+#include "cmSystemTools.h"
+#include "cmCommandArgumentLexer.h"
+
+#include "cmMakefile.h"
+
+int cmCommandArgument_yyparse( yyscan_t yyscanner );
+//
+cmCommandArgumentParserHelper::cmCommandArgumentParserHelper()
+{
+ this->WarnUninitialized = false;
+ this->CheckSystemVars = false;
+ this->FileLine = -1;
+ this->FileName = 0;
+ this->RemoveEmpty = true;
+ this->EmptyVariable[0] = 0;
+ strcpy(this->DCURLYVariable, "${");
+ strcpy(this->RCURLYVariable, "}");
+ strcpy(this->ATVariable, "@");
+ strcpy(this->DOLLARVariable, "$");
+ strcpy(this->LCURLYVariable, "{");
+ strcpy(this->BSLASHVariable, "\\");
+
+ this->NoEscapeMode = false;
+ this->ReplaceAtSyntax = false;
+}
+
+
+cmCommandArgumentParserHelper::~cmCommandArgumentParserHelper()
+{
+ this->CleanupParser();
+}
+
+void cmCommandArgumentParserHelper::SetLineFile(long line, const char* file)
+{
+ this->FileLine = line;
+ this->FileName = file;
+}
+
+char* cmCommandArgumentParserHelper::AddString(const char* str)
+{
+ if ( !str || !*str )
+ {
+ return this->EmptyVariable;
+ }
+ char* stVal = new char[strlen(str)+1];
+ strcpy(stVal, str);
+ this->Variables.push_back(stVal);
+ return stVal;
+}
+
+char* cmCommandArgumentParserHelper::ExpandSpecialVariable(const char* key,
+ const char* var)
+{
+ if ( !key )
+ {
+ return this->ExpandVariable(var);
+ }
+ if(!var)
+ {
+ return this->EmptyVariable;
+ }
+ if ( strcmp(key, "ENV") == 0 )
+ {
+ char *ptr = getenv(var);
+ if (ptr)
+ {
+ if (this->EscapeQuotes)
+ {
+ return this->AddString(cmSystemTools::EscapeQuotes(ptr).c_str());
+ }
+ else
+ {
+ return ptr;
+ }
+ }
+ return this->EmptyVariable;
+ }
+ if ( strcmp(key, "CACHE") == 0 )
+ {
+ if(const char* c = this->Makefile->GetCacheManager()->GetCacheValue(var))
+ {
+ if(this->EscapeQuotes)
+ {
+ return this->AddString(cmSystemTools::EscapeQuotes(c).c_str());
+ }
+ else
+ {
+ return this->AddString(c);
+ }
+ }
+ return this->EmptyVariable;
+ }
+ cmOStringStream e;
+ e << "Syntax $" << key << "{} is not supported. "
+ << "Only ${}, $ENV{}, and $CACHE{} are allowed.";
+ this->SetError(e.str());
+ return 0;
+}
+
+char* cmCommandArgumentParserHelper::ExpandVariable(const char* var)
+{
+ if(!var)
+ {
+ return 0;
+ }
+ if(this->FileLine >= 0 && strcmp(var, "CMAKE_CURRENT_LIST_LINE") == 0)
+ {
+ cmOStringStream ostr;
+ ostr << this->FileLine;
+ return this->AddString(ostr.str().c_str());
+ }
+ const char* value = this->Makefile->GetDefinition(var);
+ if(!value && !this->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->WarnUninitialized && !this->Makefile->VariableInitialized(var))
+ {
+ if (this->CheckSystemVars ||
+ cmSystemTools::IsSubDirectory(this->FileName,
+ this->Makefile->GetHomeDirectory()) ||
+ cmSystemTools::IsSubDirectory(this->FileName,
+ this->Makefile->GetHomeOutputDirectory()))
+ {
+ cmOStringStream msg;
+ cmListFileBacktrace bt;
+ cmListFileContext lfc;
+ lfc.FilePath = this->FileName;
+ lfc.Line = this->FileLine;
+ bt.push_back(lfc);
+ msg << "uninitialized variable \'" << var << "\'";
+ this->Makefile->GetCMakeInstance()->IssueMessage(cmake::AUTHOR_WARNING,
+ msg.str().c_str(), bt);
+ }
+ }
+ return 0;
+ }
+ if (this->EscapeQuotes && value)
+ {
+ return this->AddString(cmSystemTools::EscapeQuotes(value).c_str());
+ }
+ return this->AddString(value);
+}
+
+char* cmCommandArgumentParserHelper::ExpandVariableForAt(const char* var)
+{
+ if(this->ReplaceAtSyntax)
+ {
+ // try to expand the variable
+ char* ret = this->ExpandVariable(var);
+ // if the return was 0 and we want to replace empty strings
+ // then return an empty string
+ if(!ret && this->RemoveEmpty)
+ {
+ return this->AddString(ret);
+ }
+ // if the ret was not 0, then return it
+ if(ret)
+ {
+ return ret;
+ }
+ }
+ // at this point we want to put it back because of one of these cases:
+ // - this->ReplaceAtSyntax is false
+ // - this->ReplaceAtSyntax is true, but this->RemoveEmpty is false,
+ // and the variable was not defined
+ std::string ref = "@";
+ ref += var;
+ ref += "@";
+ return this->AddString(ref.c_str());
+}
+
+char* cmCommandArgumentParserHelper::CombineUnions(char* in1, char* in2)
+{
+ if ( !in1 )
+ {
+ return in2;
+ }
+ else if ( !in2 )
+ {
+ return in1;
+ }
+ size_t len = strlen(in1) + strlen(in2) + 1;
+ char* out = new char [ len ];
+ strcpy(out, in1);
+ strcat(out, in2);
+ this->Variables.push_back(out);
+ return out;
+}
+
+void cmCommandArgumentParserHelper::AllocateParserType
+(cmCommandArgumentParserHelper::ParserType* pt,const char* str, int len)
+{
+ pt->str = 0;
+ if ( len == 0 )
+ {
+ len = static_cast<int>(strlen(str));
+ }
+ if ( len == 0 )
+ {
+ return;
+ }
+ pt->str = new char[ len + 1 ];
+ strncpy(pt->str, str, len);
+ pt->str[len] = 0;
+ this->Variables.push_back(pt->str);
+}
+
+bool cmCommandArgumentParserHelper::HandleEscapeSymbol
+(cmCommandArgumentParserHelper::ParserType* pt, char symbol)
+{
+ switch ( symbol )
+ {
+ case '\\':
+ case '"':
+ case ' ':
+ case '#':
+ case '(':
+ case ')':
+ case '$':
+ case '@':
+ case '^':
+ this->AllocateParserType(pt, &symbol, 1);
+ break;
+ case ';':
+ this->AllocateParserType(pt, "\\;", 2);
+ break;
+ case 't':
+ this->AllocateParserType(pt, "\t", 1);
+ break;
+ case 'n':
+ this->AllocateParserType(pt, "\n", 1);
+ break;
+ case 'r':
+ this->AllocateParserType(pt, "\r", 1);
+ break;
+ case '0':
+ this->AllocateParserType(pt, "\0", 1);
+ break;
+ default:
+ {
+ cmOStringStream e;
+ e << "Invalid escape sequence \\" << symbol;
+ this->SetError(e.str());
+ }
+ return false;
+ }
+ return true;
+}
+
+void cmCommandArgument_SetupEscapes(yyscan_t yyscanner, bool noEscapes);
+
+int cmCommandArgumentParserHelper::ParseString(const char* str, int verb)
+{
+ if ( !str)
+ {
+ return 0;
+ }
+ this->Verbose = verb;
+ this->InputBuffer = str;
+ this->InputBufferPos = 0;
+ this->CurrentLine = 0;
+
+ this->Result = "";
+
+ yyscan_t yyscanner;
+ cmCommandArgument_yylex_init(&yyscanner);
+ cmCommandArgument_yyset_extra(this, yyscanner);
+ cmCommandArgument_SetupEscapes(yyscanner, this->NoEscapeMode);
+ int res = cmCommandArgument_yyparse(yyscanner);
+ cmCommandArgument_yylex_destroy(yyscanner);
+ if ( res != 0 )
+ {
+ return 0;
+ }
+
+ this->CleanupParser();
+
+ if ( Verbose )
+ {
+ std::cerr << "Expanding [" << str << "] produced: ["
+ << this->Result.c_str() << "]" << std::endl;
+ }
+ return 1;
+}
+
+void cmCommandArgumentParserHelper::CleanupParser()
+{
+ std::vector<char*>::iterator sit;
+ for ( sit = this->Variables.begin();
+ sit != this->Variables.end();
+ ++ sit )
+ {
+ delete [] *sit;
+ }
+ this->Variables.erase(this->Variables.begin(), this->Variables.end());
+}
+
+int cmCommandArgumentParserHelper::LexInput(char* buf, int maxlen)
+{
+ if ( maxlen < 1 )
+ {
+ return 0;
+ }
+ if ( this->InputBufferPos < this->InputBuffer.size() )
+ {
+ buf[0] = this->InputBuffer[ this->InputBufferPos++ ];
+ if ( buf[0] == '\n' )
+ {
+ this->CurrentLine ++;
+ }
+ return(1);
+ }
+ else
+ {
+ buf[0] = '\n';
+ return( 0 );
+ }
+}
+
+void cmCommandArgumentParserHelper::Error(const char* str)
+{
+ unsigned long pos = static_cast<unsigned long>(this->InputBufferPos);
+ cmOStringStream ostr;
+ ostr << str << " (" << pos << ")";
+ this->SetError(ostr.str());
+}
+
+void cmCommandArgumentParserHelper::SetMakefile(const cmMakefile* mf)
+{
+ this->Makefile = mf;
+ this->WarnUninitialized = mf->GetCMakeInstance()->GetWarnUninitialized();
+ this->CheckSystemVars = mf->GetCMakeInstance()->GetCheckSystemVars();
+}
+
+void cmCommandArgumentParserHelper::SetResult(const char* value)
+{
+ if ( !value )
+ {
+ this->Result = "";
+ return;
+ }
+ this->Result = value;
+}
+
+void cmCommandArgumentParserHelper::SetError(std::string const& msg)
+{
+ // Keep only the first error.
+ if(this->ErrorString.empty())
+ {
+ this->ErrorString = msg;
+ }
+}
diff --git a/Source/cmCommandArgumentParserHelper.h b/Source/cmCommandArgumentParserHelper.h
new file mode 100644
index 000000000..cdb832b5f
--- /dev/null
+++ b/Source/cmCommandArgumentParserHelper.h
@@ -0,0 +1,110 @@
+/*============================================================================
+ 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 cmCommandArgumentParserHelper_h
+#define cmCommandArgumentParserHelper_h
+
+#include "cmStandardIncludes.h"
+
+#define YYSTYPE cmCommandArgumentParserHelper::ParserType
+#define YYSTYPE_IS_DECLARED
+#define YY_EXTRA_TYPE cmCommandArgumentParserHelper*
+#define YY_DECL int cmCommandArgument_yylex(YYSTYPE* yylvalp,\
+ yyscan_t yyscanner)
+
+/** \class cmCommandArgumentParserHelper
+ * \brief Helper class for parsing java source files
+ *
+ * Finds dependencies for java file and list of outputs
+ */
+
+class cmMakefile;
+
+class cmCommandArgumentParserHelper
+{
+public:
+ typedef struct {
+ char* str;
+ } ParserType;
+
+ cmCommandArgumentParserHelper();
+ ~cmCommandArgumentParserHelper();
+
+ int ParseString(const char* str, int verb);
+
+ // For the lexer:
+ void AllocateParserType(cmCommandArgumentParserHelper::ParserType* pt,
+ const char* str, int len = 0);
+ bool HandleEscapeSymbol(cmCommandArgumentParserHelper::ParserType* pt,
+ char symbol);
+
+ int LexInput(char* buf, int maxlen);
+ void Error(const char* str);
+
+ // For yacc
+ char* CombineUnions(char* in1, char* in2);
+
+ char* ExpandSpecialVariable(const char* key, const char* var);
+ char* ExpandVariable(const char* var);
+ char* ExpandVariableForAt(const char* var);
+ void SetResult(const char* value);
+
+ void SetMakefile(const cmMakefile* mf);
+
+ std::string& GetResult() { return this->Result; }
+
+ void SetLineFile(long line, const char* file);
+ void SetEscapeQuotes(bool b) { this->EscapeQuotes = b; }
+ void SetNoEscapeMode(bool b) { this->NoEscapeMode = b; }
+ void SetReplaceAtSyntax(bool b) { this->ReplaceAtSyntax = b; }
+ void SetRemoveEmpty(bool b) { this->RemoveEmpty = b; }
+
+ const char* GetError() { return this->ErrorString.c_str(); }
+ char EmptyVariable[1];
+ char DCURLYVariable[3];
+ char RCURLYVariable[3];
+ char ATVariable[3];
+ char DOLLARVariable[3];
+ char LCURLYVariable[3];
+ char BSLASHVariable[3];
+
+private:
+ cmStdString::size_type InputBufferPos;
+ cmStdString 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);
+
+ void CleanupParser();
+ void SetError(std::string const& msg);
+
+ std::vector<char*> Variables;
+ const cmMakefile* Makefile;
+ std::string Result;
+ const char* FileName;
+ bool WarnUninitialized;
+ bool CheckSystemVars;
+ long FileLine;
+ bool EscapeQuotes;
+ std::string ErrorString;
+ bool NoEscapeMode;
+ bool ReplaceAtSyntax;
+ bool RemoveEmpty;
+};
+
+#endif
+
+
diff --git a/Source/cmCommandArgumentParserTokens.h b/Source/cmCommandArgumentParserTokens.h
new file mode 100644
index 000000000..7fb58e2d9
--- /dev/null
+++ b/Source/cmCommandArgumentParserTokens.h
@@ -0,0 +1,92 @@
+/*============================================================================
+ 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.
+============================================================================*/
+/* A Bison parser, made by GNU Bison 2.3. */
+
+/* Skeleton interface for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ 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 2, 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, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+/* 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 {
+ cal_ENVCURLY = 258,
+ cal_NCURLY = 259,
+ cal_DCURLY = 260,
+ cal_DOLLAR = 261,
+ cal_LCURLY = 262,
+ cal_RCURLY = 263,
+ cal_NAME = 264,
+ cal_BSLASH = 265,
+ cal_SYMBOL = 266,
+ cal_AT = 267,
+ cal_ERROR = 268,
+ cal_ATNAME = 269
+ };
+#endif
+/* Tokens. */
+#define cal_ENVCURLY 258
+#define cal_NCURLY 259
+#define cal_DCURLY 260
+#define cal_DOLLAR 261
+#define cal_LCURLY 262
+#define cal_RCURLY 263
+#define cal_NAME 264
+#define cal_BSLASH 265
+#define cal_SYMBOL 266
+#define cal_AT 267
+#define cal_ERROR 268
+#define cal_ATNAME 269
+
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef int YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+
+
diff --git a/Source/cmCommandArgumentsHelper.cxx b/Source/cmCommandArgumentsHelper.cxx
new file mode 100644
index 000000000..d92013788
--- /dev/null
+++ b/Source/cmCommandArgumentsHelper.cxx
@@ -0,0 +1,307 @@
+/*============================================================================
+ 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 "cmCommandArgumentsHelper.h"
+
+cmCommandArgument::cmCommandArgument(cmCommandArgumentsHelper* args,
+ const char* key,
+ cmCommandArgumentGroup* group)
+:Key(key)
+,Group(group)
+,WasActive(false)
+,ArgumentsBeforeEmpty(true)
+,CurrentIndex(0)
+{
+ if (args!=0)
+ {
+ args->AddArgument(this);
+ }
+
+ if (this->Group!=0)
+ {
+ this->Group->ContainedArguments.push_back(this);
+ }
+}
+
+void cmCommandArgument::Reset()
+{
+ this->WasActive =false;
+ this->CurrentIndex = 0;
+ this->DoReset();
+}
+
+void cmCommandArgument::Follows(const cmCommandArgument* arg)
+{
+ this->ArgumentsBeforeEmpty = false;
+ this->ArgumentsBefore.insert(arg);
+}
+
+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);
+ }
+ }
+}
+
+bool cmCommandArgument::MayFollow(const cmCommandArgument* current) const
+{
+ if (this->ArgumentsBeforeEmpty)
+ {
+ return true;
+ }
+
+ std::set<const cmCommandArgument*>::const_iterator argIt
+ = this->ArgumentsBefore.find(current);
+ if (argIt != this->ArgumentsBefore.end())
+ {
+ return true;
+ }
+
+ return false;
+}
+
+bool cmCommandArgument::KeyMatches(const std::string& key) const
+{
+ if ((this->Key==0) || (this->Key[0]=='\0'))
+ {
+ return true;
+ }
+ return (key==this->Key);
+}
+
+void cmCommandArgument::ApplyOwnGroup()
+{
+ if (this->Group!=0)
+ {
+ for (std::vector<cmCommandArgument*>::const_iterator
+ it = this->Group->ContainedArguments.begin();
+ it != this->Group->ContainedArguments.end();
+ ++it)
+ {
+ if(*it != this)
+ {
+ this->ArgumentsBefore.insert(*it);
+ }
+ }
+ }
+}
+
+void cmCommandArgument::Activate()
+{
+ this->WasActive = true;
+ this->CurrentIndex = 0;
+}
+
+bool cmCommandArgument::Consume(const std::string& arg)
+{
+ bool res=this->DoConsume(arg, this->CurrentIndex);
+ this->CurrentIndex++;
+ return res;
+}
+
+
+cmCAStringVector::cmCAStringVector(cmCommandArgumentsHelper* args,
+ const char* key,
+ cmCommandArgumentGroup* group)
+:cmCommandArgument(args, key, group)
+,Ignore(0)
+{
+ if ((key==0) || (*key==0))
+ {
+ this->DataStart = 0;
+ }
+ else
+ {
+ this->DataStart = 1;
+ }
+}
+
+bool cmCAStringVector::DoConsume(const std::string& arg,unsigned int index)
+{
+ if (index >= this->DataStart)
+ {
+ if ((this->Ignore==0) || (arg != this->Ignore))
+ {
+ this->Vector.push_back(arg);
+ }
+ }
+
+ return false;
+}
+
+void cmCAStringVector::DoReset()
+{
+ this->Vector.clear();
+}
+
+cmCAString::cmCAString(cmCommandArgumentsHelper* args,
+ const char* key,
+ cmCommandArgumentGroup* group)
+:cmCommandArgument(args, key, group)
+{
+ if ((key==0) || (*key==0))
+ {
+ this->DataStart = 0;
+ }
+ else
+ {
+ this->DataStart = 1;
+ }
+}
+
+bool cmCAString::DoConsume(const std::string& arg, unsigned int index)
+{
+ if (index == this->DataStart)
+ {
+ this->String = arg;
+ }
+
+ return index >= this->DataStart;
+}
+
+void cmCAString::DoReset()
+{
+ this->String = "";
+}
+
+cmCAEnabler::cmCAEnabler(cmCommandArgumentsHelper* args,
+ const char* key,
+ cmCommandArgumentGroup* group)
+:cmCommandArgument(args, key, group)
+,Enabled(false)
+{}
+
+bool cmCAEnabler::DoConsume(const std::string&, unsigned int index)
+{
+ if (index==0)
+ {
+ this->Enabled = true;
+ }
+ return true;
+}
+
+void cmCAEnabler::DoReset()
+{
+ this->Enabled = false;
+}
+
+cmCADisabler::cmCADisabler(cmCommandArgumentsHelper* args,
+ const char* key,
+ cmCommandArgumentGroup* group)
+:cmCommandArgument(args, key, group)
+,Enabled(true)
+{}
+
+bool cmCADisabler::DoConsume(const std::string&, unsigned int index)
+{
+ if (index==0)
+ {
+ this->Enabled = false;
+ }
+ return true;
+}
+
+void cmCADisabler::DoReset()
+{
+ this->Enabled = true;
+}
+
+void cmCommandArgumentGroup::Follows(const cmCommandArgument* arg)
+{
+ for(std::vector<cmCommandArgument*>::iterator
+ it = this->ContainedArguments.begin();
+ it != this->ContainedArguments.end();
+ ++it)
+ {
+ (*it)->Follows(arg);
+ }
+}
+
+void cmCommandArgumentGroup::FollowsGroup(const cmCommandArgumentGroup* group)
+{
+ for(std::vector<cmCommandArgument*>::iterator
+ it = this->ContainedArguments.begin();
+ it != this->ContainedArguments.end();
+ ++it)
+ {
+ (*it)->FollowsGroup(group);
+ }
+}
+
+void cmCommandArgumentsHelper::Parse(const std::vector<std::string>* args,
+ std::vector<std::string>* unconsumedArgs)
+{
+ if(args==0)
+ {
+ return;
+ }
+
+ for(std::vector<cmCommandArgument*>::iterator
+ argIt = this->Arguments.begin();
+ argIt != this->Arguments.end();
+ ++argIt)
+ {
+ (*argIt)->ApplyOwnGroup();
+ (*argIt)->Reset();
+ }
+
+ cmCommandArgument* activeArgument = 0;
+ const cmCommandArgument* previousArgument = 0;
+ for(std::vector<std::string>::const_iterator it = args->begin();
+ it != args->end();
+ ++it)
+ {
+ for(std::vector<cmCommandArgument*>::iterator
+ argIt = this->Arguments.begin();
+ argIt != this->Arguments.end();
+ ++argIt)
+ {
+ if ((*argIt)->KeyMatches(*it) && ((*argIt)->MayFollow(previousArgument)))
+ {
+ activeArgument = *argIt;
+ activeArgument->Activate();
+ break;
+ }
+ }
+
+ if (activeArgument)
+ {
+ bool argDone = activeArgument->Consume(*it);
+ previousArgument = activeArgument;
+ if (argDone)
+ {
+ activeArgument = 0;
+ }
+ }
+ else
+ {
+ if (unconsumedArgs!=0)
+ {
+ unconsumedArgs->push_back(*it);
+ }
+ }
+ }
+}
+
+void cmCommandArgumentsHelper::AddArgument(cmCommandArgument* arg)
+{
+ this->Arguments.push_back(arg);
+}
+
diff --git a/Source/cmCommandArgumentsHelper.h b/Source/cmCommandArgumentsHelper.h
new file mode 100644
index 000000000..3b0b058fd
--- /dev/null
+++ b/Source/cmCommandArgumentsHelper.h
@@ -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.
+============================================================================*/
+#ifndef cmCommandArgumentsHelper_h
+#define cmCommandArgumentsHelper_h
+
+#include "cmStandardIncludes.h"
+
+class cmCommandArgumentsHelper;
+class cmCommandArgumentGroup;
+
+/* cmCommandArgumentsHelper, cmCommandArgumentGroup and cmCommandArgument (i.e.
+its derived classes cmCAXXX can be used to simplify the processing of
+arguments to cmake commands. Maybe they can also be used to generate
+documentation.
+
+For every argument supported by a command one cmCommandArgument is created
+and added to cmCommandArgumentsHelper. cmCommand has a cmCommandArgumentsHelper
+as member variable so this should be used.
+
+The order of the arguments is defined using the Follows(arg) method. It says
+that this argument follows immediateley the given argument. It can be used
+with multiple arguments if the argument can follow after different arguments.
+
+Arguments can be arranged in groups using cmCommandArgumentGroup. Every
+member of a group can follow any other member of the group. These groups
+can also be used to define the order.
+
+Once all arguments and groups are set up, cmCommandArgumentsHelper::Parse()
+is called and afterwards the values of the arguments can be evaluated.
+
+For an example see cmExportCommand.cxx.
+*/
+class cmCommandArgument
+{
+ public:
+ cmCommandArgument(cmCommandArgumentsHelper* args,
+ const char* key,
+ cmCommandArgumentGroup* group=0);
+ virtual ~cmCommandArgument() {}
+
+ /// this argument may follow after arg. 0 means it comes first.
+ void Follows(const cmCommandArgument* arg);
+
+ /// this argument may follow after any of the arguments in the given group
+ void FollowsGroup(const cmCommandArgumentGroup* group);
+
+ /// Returns true if the argument was found in the argument list
+ bool WasFound() const {return this->WasActive;}
+
+ // The following methods are only called from
+ // cmCommandArgumentsHelper::Parse(), but making this a friend would
+ // give it access to everything
+
+ /// Make the current argument the currently active argument
+ void Activate();
+ /// Consume the current string
+ bool Consume(const std::string& arg);
+
+ /// Return true if this argument may follow after the given argument.
+ bool MayFollow(const cmCommandArgument* current) const;
+
+ /** Returns true if the given key matches the key for this argument.
+ If this argument has an empty key everything matches. */
+ bool KeyMatches(const std::string& key) const;
+
+ /// Make this argument follow all members of the own group
+ void ApplyOwnGroup();
+
+ /// Reset argument, so it's back to its initial state
+ void Reset();
+ private:
+ const char* Key;
+ std::set<const cmCommandArgument*> ArgumentsBefore;
+ cmCommandArgumentGroup* Group;
+ bool WasActive;
+ bool ArgumentsBeforeEmpty;
+ unsigned int CurrentIndex;
+
+ virtual bool DoConsume(const std::string& arg, unsigned int index) = 0;
+ virtual void DoReset() = 0;
+};
+
+/** cmCAStringVector is to be used for arguments which can consist of more
+than one string, e.g. the FILES argument in INSTALL(FILES f1 f2 f3 ...). */
+class cmCAStringVector : public cmCommandArgument
+{
+ public:
+ cmCAStringVector(cmCommandArgumentsHelper* args,
+ const char* key,
+ cmCommandArgumentGroup* group=0);
+
+ /// Return the vector of strings
+ const std::vector<std::string>& GetVector() const {return this->Vector;}
+
+ /** Is there a keyword which should be skipped in
+ the arguments (e.g. ARGS for ADD_CUSTOM_COMMAND) ? */
+ void SetIgnore(const char* ignore) {this->Ignore=ignore;}
+ private:
+ std::vector<std::string> Vector;
+ unsigned int DataStart;
+ const char* Ignore;
+ cmCAStringVector();
+ virtual bool DoConsume(const std::string& arg, unsigned int index);
+ virtual void DoReset();
+};
+
+/** cmCAString is to be used for arguments which consist of one value,
+e.g. the executable name in ADD_EXECUTABLE(). */
+class cmCAString : public cmCommandArgument
+{
+ public:
+ cmCAString(cmCommandArgumentsHelper* args,
+ const char* key,
+ cmCommandArgumentGroup* group=0);
+
+ /// Return the string
+ const std::string& GetString() const {return this->String;}
+ const char* GetCString() const {return this->String.c_str();}
+ private:
+ std::string String;
+ unsigned int DataStart;
+ virtual bool DoConsume(const std::string& arg, unsigned int index);
+ virtual void DoReset();
+ cmCAString();
+};
+
+/** cmCAEnabler is to be used for options which are off by default and can be
+enabled using a special argument, e.g. EXCLUDE_FROM_ALL in ADD_EXECUTABLE(). */
+class cmCAEnabler : public cmCommandArgument
+{
+ public:
+ cmCAEnabler(cmCommandArgumentsHelper* args,
+ const char* key,
+ cmCommandArgumentGroup* group=0);
+
+ /// Has it been enabled ?
+ bool IsEnabled() const {return this->Enabled;}
+ private:
+ bool Enabled;
+ virtual bool DoConsume(const std::string& arg, unsigned int index);
+ virtual void DoReset();
+ cmCAEnabler();
+};
+
+/** cmCADisable is to be used for options which are on by default and can be
+disabled using a special argument.*/
+class cmCADisabler : public cmCommandArgument
+{
+ public:
+ cmCADisabler(cmCommandArgumentsHelper* args,
+ const char* key,
+ cmCommandArgumentGroup* group=0);
+
+ /// Is it still enabled ?
+ bool IsEnabled() const {return this->Enabled;}
+ private:
+ bool Enabled;
+ virtual bool DoConsume(const std::string& arg, unsigned int index);
+ virtual void DoReset();
+ cmCADisabler();
+};
+
+
+/** Group of arguments, needed for ordering. E.g. WIN32, EXCLUDE_FROM_ALL and
+MACSOX_BUNDLE from ADD_EXECUTABLE() are a group.
+*/
+class cmCommandArgumentGroup
+{
+ friend class cmCommandArgument;
+ public:
+ cmCommandArgumentGroup() {}
+
+ /// All members of this group may follow the given argument
+ void Follows(const cmCommandArgument* arg);
+
+ /// All members of this group may follow all members of the given group
+ void FollowsGroup(const cmCommandArgumentGroup* group);
+ private:
+ std::vector<cmCommandArgument*> ContainedArguments;
+};
+
+class cmCommandArgumentsHelper
+{
+ public:
+ /// Parse the argument list
+ void Parse(const std::vector<std::string>* args,
+ std::vector<std::string>* unconsumedArgs);
+ /// Add an argument.
+ void AddArgument(cmCommandArgument* arg);
+ private:
+ std::vector<cmCommandArgument*> Arguments;
+};
+
+
+#endif
diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
new file mode 100644
index 000000000..49ed96795
--- /dev/null
+++ b/Source/cmCommands.cxx
@@ -0,0 +1,75 @@
+/*============================================================================
+ 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 "cmAuxSourceDirectoryCommand.cxx"
+#include "cmBuildNameCommand.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 "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 cmAuxSourceDirectoryCommand);
+ commands.push_back(new cmBuildNameCommand);
+ 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 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.h b/Source/cmCommands.h
new file mode 100644
index 000000000..096fc2006
--- /dev/null
+++ b/Source/cmCommands.h
@@ -0,0 +1,28 @@
+/*============================================================================
+ 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 cmCommands_h
+#define cmCommands_h
+#include "cmStandardIncludes.h"
+
+class cmCommand;
+/**
+ * Global function to return all compiled in commands.
+ * To add a new command edit cmCommands.cxx or cmBootstrapCommands.cxx
+ * and add your command.
+ * It is up to the caller to delete the commands created by this
+ * call.
+ */
+void GetBootstrapCommands(std::list<cmCommand*>& commands);
+void GetPredefinedCommands(std::list<cmCommand*>& commands);
+
+
+#endif
diff --git a/Source/cmComputeComponentGraph.cxx b/Source/cmComputeComponentGraph.cxx
new file mode 100644
index 000000000..5bec6a1ec
--- /dev/null
+++ b/Source/cmComputeComponentGraph.cxx
@@ -0,0 +1,159 @@
+/*============================================================================
+ 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 "cmComputeComponentGraph.h"
+
+#include <algorithm>
+
+#include <assert.h>
+
+//----------------------------------------------------------------------------
+cmComputeComponentGraph::cmComputeComponentGraph(Graph const& input):
+ InputGraph(input)
+{
+ // Identify components.
+ this->Tarjan();
+
+ // Compute the component graph.
+ this->ComponentGraph.resize(0);
+ this->ComponentGraph.resize(this->Components.size());
+ this->TransferEdges();
+}
+
+//----------------------------------------------------------------------------
+cmComputeComponentGraph::~cmComputeComponentGraph()
+{
+}
+
+//----------------------------------------------------------------------------
+void cmComputeComponentGraph::Tarjan()
+{
+ int n = static_cast<int>(this->InputGraph.size());
+ TarjanEntry entry = {0,0};
+ this->TarjanEntries.resize(0);
+ this->TarjanEntries.resize(n, entry);
+ this->TarjanComponents.resize(0);
+ this->TarjanComponents.resize(n, -1);
+ this->TarjanWalkId = 0;
+ this->TarjanVisited.resize(0);
+ this->TarjanVisited.resize(n, 0);
+ for(int i = 0; i < n; ++i)
+ {
+ // Start a new DFS from this node if it has never been visited.
+ if(!this->TarjanVisited[i])
+ {
+ assert(this->TarjanStack.empty());
+ ++this->TarjanWalkId;
+ this->TarjanIndex = 0;
+ this->TarjanVisit(i);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmComputeComponentGraph::TarjanVisit(int i)
+{
+ // We are now visiting this node.
+ this->TarjanVisited[i] = this->TarjanWalkId;
+
+ // Initialize the entry.
+ this->TarjanEntries[i].Root = i;
+ this->TarjanComponents[i] = -1;
+ this->TarjanEntries[i].VisitIndex = ++this->TarjanIndex;
+ this->TarjanStack.push(i);
+
+ // Follow outgoing edges.
+ EdgeList const& nl = this->InputGraph[i];
+ for(EdgeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni)
+ {
+ int j = *ni;
+
+ // Ignore edges to nodes that have been reached by a previous DFS
+ // walk. Since we did not reach the current node from that walk
+ // it must not belong to the same component and it has already
+ // been assigned to a component.
+ if(this->TarjanVisited[j] > 0 &&
+ this->TarjanVisited[j] < this->TarjanWalkId)
+ {
+ continue;
+ }
+
+ // Visit the destination if it has not yet been visited.
+ if(!this->TarjanVisited[j])
+ {
+ this->TarjanVisit(j);
+ }
+
+ // If the destination has not yet been assigned to a component,
+ // check if it has a better root for the current object.
+ if(this->TarjanComponents[j] < 0)
+ {
+ if(this->TarjanEntries[this->TarjanEntries[j].Root].VisitIndex <
+ this->TarjanEntries[this->TarjanEntries[i].Root].VisitIndex)
+ {
+ this->TarjanEntries[i].Root = this->TarjanEntries[j].Root;
+ }
+ }
+ }
+
+ // Check if we have found a component.
+ if(this->TarjanEntries[i].Root == i)
+ {
+ // Yes. Create it.
+ int c = static_cast<int>(this->Components.size());
+ this->Components.push_back(NodeList());
+ NodeList& component = this->Components[c];
+
+ // Populate the component list.
+ int j;
+ do
+ {
+ // Get the next member of the component.
+ j = this->TarjanStack.top();
+ this->TarjanStack.pop();
+
+ // Assign the member to the component.
+ this->TarjanComponents[j] = c;
+ this->TarjanEntries[j].Root = i;
+
+ // Store the node in its component.
+ component.push_back(j);
+ } while(j != i);
+
+ // Sort the component members for clarity.
+ std::sort(component.begin(), component.end());
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmComputeComponentGraph::TransferEdges()
+{
+ // Map inter-component edges in the original graph to edges in the
+ // component graph.
+ int n = static_cast<int>(this->InputGraph.size());
+ for(int i=0; i < n; ++i)
+ {
+ int i_component = this->TarjanComponents[i];
+ EdgeList const& nl = this->InputGraph[i];
+ for(EdgeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni)
+ {
+ int j = *ni;
+ int j_component = this->TarjanComponents[j];
+ if(i_component != j_component)
+ {
+ // We do not attempt to combine duplicate edges, but instead
+ // store the inter-component edges with suitable multiplicity.
+ this->ComponentGraph[i_component].push_back(
+ cmGraphEdge(j_component, ni->IsStrong()));
+ }
+ }
+ }
+}
diff --git a/Source/cmComputeComponentGraph.h b/Source/cmComputeComponentGraph.h
new file mode 100644
index 000000000..a2ce946c1
--- /dev/null
+++ b/Source/cmComputeComponentGraph.h
@@ -0,0 +1,83 @@
+/*============================================================================
+ 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 cmComputeComponentGraph_h
+#define cmComputeComponentGraph_h
+
+#include "cmStandardIncludes.h"
+
+#include "cmGraphAdjacencyList.h"
+
+#include <stack>
+
+/** \class cmComputeComponentGraph
+ * \brief Analyze a graph to determine strongly connected components.
+ *
+ * Convert a directed graph into a directed acyclic graph whose nodes
+ * correspond to strongly connected components of the original graph.
+ *
+ * We use Tarjan's algorithm to enumerate the components efficiently.
+ * An advantage of this approach is that the components are identified
+ * in a topologically sorted order.
+ */
+class cmComputeComponentGraph
+{
+public:
+ // Represent the graph with an adjacency list.
+ typedef cmGraphNodeList NodeList;
+ typedef cmGraphEdgeList EdgeList;
+ typedef cmGraphAdjacencyList Graph;
+
+ cmComputeComponentGraph(Graph const& input);
+ ~cmComputeComponentGraph();
+
+ /** Get the adjacency list of the component graph. */
+ Graph const& GetComponentGraph() const
+ { return this->ComponentGraph; }
+ EdgeList const& GetComponentGraphEdges(int c) const
+ { return this->ComponentGraph[c]; }
+
+ /** Get map from component index to original node indices. */
+ std::vector<NodeList> const& GetComponents() const
+ { return this->Components; }
+ NodeList const& GetComponent(int c) const
+ { return this->Components[c]; }
+
+ /** Get map from original node index to component index. */
+ std::vector<int> const& GetComponentMap() const
+ { return this->TarjanComponents; }
+
+private:
+ void TransferEdges();
+
+ Graph const& InputGraph;
+ Graph ComponentGraph;
+
+ // Tarjan's algorithm.
+ struct TarjanEntry
+ {
+ int Root;
+ int VisitIndex;
+ };
+ int TarjanWalkId;
+ std::vector<int> TarjanVisited;
+ std::vector<int> TarjanComponents;
+ std::vector<TarjanEntry> TarjanEntries;
+ std::stack<int> TarjanStack;
+ 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
new file mode 100644
index 000000000..055aab032
--- /dev/null
+++ b/Source/cmComputeLinkDepends.cxx
@@ -0,0 +1,998 @@
+/*============================================================================
+ 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 "cmComputeLinkDepends.h"
+
+#include "cmComputeComponentGraph.h"
+#include "cmGlobalGenerator.h"
+#include "cmLocalGenerator.h"
+#include "cmMakefile.h"
+#include "cmTarget.h"
+#include "cmake.h"
+
+#include <cmsys/stl/algorithm>
+
+#include <assert.h>
+
+/*
+
+This file computes an ordered list of link items to use when linking a
+single target in one configuration. Each link item is identified by
+the string naming it. A graph of dependencies is created in which
+each node corresponds to one item and directed edges lead from nodes to
+those which must *follow* them on the link line. For example, the
+graph
+
+ A -> B -> C
+
+will lead to the link line order
+
+ A B C
+
+The set of items placed in the graph is formed with a breadth-first
+search of the link dependencies starting from the main target.
+
+There are two types of items: those with known direct dependencies and
+those without known dependencies. We will call the two types "known
+items" and "unknown items", respectively. Known items are those whose
+names correspond to targets (built or imported) and those for which an
+old-style <item>_LIB_DEPENDS variable is defined. All other items are
+unknown and we must infer dependencies for them. For items that look
+like flags (beginning with '-') we trivially infer no dependencies,
+and do not include them in the dependencies of other items.
+
+Known items have dependency lists ordered based on how the user
+specified them. We can use this order to infer potential dependencies
+of unknown items. For example, if link items A and B are unknown and
+items X and Y are known, then we might have the following dependency
+lists:
+
+ X: Y A B
+ Y: A B
+
+The explicitly known dependencies form graph edges
+
+ X -> Y , X -> A , X -> B , Y -> A , Y -> B
+
+We can also infer the edge
+
+ A -> B
+
+because *every* time A appears B is seen on its right. We do not know
+whether A really needs symbols from B to link, but it *might* so we
+must preserve their order. This is the case also for the following
+explicit lists:
+
+ X: A B Y
+ Y: A B
+
+Here, A is followed by the set {B,Y} in one list, and {B} in the other
+list. The intersection of these sets is {B}, so we can infer that A
+depends on at most B. Meanwhile B is followed by the set {Y} in one
+list and {} in the other. The intersection is {} so we can infer that
+B has no dependencies.
+
+Let's make a more complex example by adding unknown item C and
+considering these dependency lists:
+
+ X: A B Y C
+ Y: A C B
+
+The explicit edges are
+
+ X -> Y , X -> A , X -> B , X -> C , Y -> A , Y -> B , Y -> C
+
+For the unknown items, we infer dependencies by looking at the
+"follow" sets:
+
+ A: intersect( {B,Y,C} , {C,B} ) = {B,C} ; infer edges A -> B , A -> C
+ B: intersect( {Y,C} , {} ) = {} ; infer no edges
+ C: intersect( {} , {B} ) = {} ; infer no edges
+
+Note that targets are never inferred as dependees because outside
+libraries should not depend on them.
+
+------------------------------------------------------------------------------
+
+The initial exploration of dependencies using a BFS associates an
+integer index with each link item. When the graph is built outgoing
+edges are sorted by this index.
+
+After the initial exploration of the link interface tree, any
+transitive (dependent) shared libraries that were encountered and not
+included in the interface are processed in their own BFS. This BFS
+follows only the dependent library lists and not the link interfaces.
+They are added to the link items with a mark indicating that the are
+transitive dependencies. Then cmComputeLinkInformation deals with
+them on a per-platform basis.
+
+The complete graph formed from all known and inferred dependencies may
+not be acyclic, so an acyclic version must be created.
+The original graph is converted to a directed acyclic graph in which
+each node corresponds to a strongly connected component of the
+original graph. For example, the dependency graph
+
+ X -> A -> B -> C -> A -> Y
+
+contains strongly connected components {X}, {A,B,C}, and {Y}. The
+implied directed acyclic graph (DAG) is
+
+ {X} -> {A,B,C} -> {Y}
+
+We then compute a topological order for the DAG nodes to serve as a
+reference for satisfying dependencies efficiently. We perform the DFS
+in reverse order and assign topological order indices counting down so
+that the result is as close to the original BFS order as possible
+without violating dependencies.
+
+------------------------------------------------------------------------------
+
+The final link entry order is constructed as follows. We first walk
+through and emit the *original* link line as specified by the user.
+As each item is emitted, a set of pending nodes in the component DAG
+is maintained. When a pending component has been completely seen, it
+is removed from the pending set and its dependencies (following edges
+of the DAG) are added. A trivial component (those with one item) is
+complete as soon as its item is seen. A non-trivial component (one
+with more than one item; assumed to be static libraries) is complete
+when *all* its entries have been seen *twice* (all entries seen once,
+then all entries seen again, not just each entry twice). A pending
+component tracks which items have been seen and a count of how many
+times the component needs to be seen (once for trivial components,
+twice for non-trivial). If at any time another component finishes and
+re-adds an already pending component, the pending component is reset
+so that it needs to be seen in its entirety again. This ensures that
+all dependencies of a component are satisfied no matter where it
+appears.
+
+After the original link line has been completed, we append to it the
+remaining pending components and their dependencies. This is done by
+repeatedly emitting the first item from the first pending component
+and following the same update rules as when traversing the original
+link line. Since the pending components are kept in topological order
+they are emitted with minimal repeats (we do not want to emit a
+component just to have it added again when another component is
+completed later). This process continues until no pending components
+remain. We know it will terminate because the component graph is
+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.
+
+*/
+
+//----------------------------------------------------------------------------
+cmComputeLinkDepends
+::cmComputeLinkDepends(cmTarget* target, const char* config)
+{
+ // Store context information.
+ this->Target = target;
+ this->Makefile = this->Target->GetMakefile();
+ this->LocalGenerator = this->Makefile->GetLocalGenerator();
+ this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator();
+ this->CMakeInstance = this->GlobalGenerator->GetCMakeInstance();
+
+ // The configuration being linked.
+ this->Config = (config && *config)? config : 0;
+ this->LinkType = this->Target->ComputeLinkType(this->Config);
+
+ // Enable debug mode if requested.
+ this->DebugMode = this->Makefile->IsOn("CMAKE_LINK_DEPENDS_DEBUG_MODE");
+
+ // Assume no compatibility until set.
+ this->OldLinkDirMode = false;
+
+ // No computation has been done.
+ this->CCG = 0;
+}
+
+//----------------------------------------------------------------------------
+cmComputeLinkDepends::~cmComputeLinkDepends()
+{
+ for(std::vector<DependSetList*>::iterator
+ i = this->InferredDependSets.begin();
+ i != this->InferredDependSets.end(); ++i)
+ {
+ delete *i;
+ }
+ delete this->CCG;
+}
+
+//----------------------------------------------------------------------------
+void cmComputeLinkDepends::SetOldLinkDirMode(bool b)
+{
+ this->OldLinkDirMode = b;
+}
+
+//----------------------------------------------------------------------------
+std::vector<cmComputeLinkDepends::LinkEntry> const&
+cmComputeLinkDepends::Compute()
+{
+ // Follow the link dependencies of the target to be linked.
+ this->AddDirectLinkEntries();
+
+ // Complete the breadth-first search of dependencies.
+ while(!this->BFSQueue.empty())
+ {
+ // Get the next entry.
+ BFSEntry qe = this->BFSQueue.front();
+ this->BFSQueue.pop();
+
+ // Follow the entry's dependencies.
+ this->FollowLinkEntry(qe);
+ }
+
+ // Complete the search of shared library dependencies.
+ while(!this->SharedDepQueue.empty())
+ {
+ // Handle the next entry.
+ this->HandleSharedDependency(this->SharedDepQueue.front());
+ this->SharedDepQueue.pop();
+ }
+
+ // Infer dependencies of targets for which they were not known.
+ this->InferDependencies();
+
+ // Cleanup the constraint graph.
+ this->CleanConstraintGraph();
+
+ // Display the constraint graph.
+ if(this->DebugMode)
+ {
+ fprintf(stderr,
+ "---------------------------------------"
+ "---------------------------------------\n");
+ fprintf(stderr, "Link dependency analysis for target %s, config %s\n",
+ this->Target->GetName(), this->Config?this->Config:"noconfig");
+ this->DisplayConstraintGraph();
+ }
+
+ // Compute the final ordering.
+ 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]);
+ }
+
+ // Display the final set.
+ if(this->DebugMode)
+ {
+ this->DisplayFinalEntries();
+ }
+
+ return this->FinalLinkEntries;
+}
+
+//----------------------------------------------------------------------------
+std::map<cmStdString, int>::iterator
+cmComputeLinkDepends::AllocateLinkEntry(std::string const& item)
+{
+ std::map<cmStdString, int>::value_type
+ index_entry(item, static_cast<int>(this->EntryList.size()));
+ std::map<cmStdString, int>::iterator
+ lei = this->LinkEntryIndex.insert(index_entry).first;
+ this->EntryList.push_back(LinkEntry());
+ this->InferredDependSets.push_back(0);
+ this->EntryConstraintGraph.push_back(EdgeList());
+ return lei;
+}
+
+//----------------------------------------------------------------------------
+int cmComputeLinkDepends::AddLinkEntry(int depender_index,
+ std::string const& item)
+{
+ // Check if the item entry has already been added.
+ std::map<cmStdString, int>::iterator lei = this->LinkEntryIndex.find(item);
+ if(lei != this->LinkEntryIndex.end())
+ {
+ // Yes. We do not need to follow the item's dependencies again.
+ return lei->second;
+ }
+
+ // Allocate a spot for the item entry.
+ lei = this->AllocateLinkEntry(item);
+
+ // Initialize the item entry.
+ int index = lei->second;
+ LinkEntry& entry = this->EntryList[index];
+ entry.Item = item;
+ entry.Target = this->FindTargetToLink(depender_index, entry.Item.c_str());
+ entry.IsFlag = (!entry.Target && item[0] == '-' && item[1] != 'l' &&
+ item.substr(0, 10) != "-framework");
+
+ // If the item has dependencies queue it to follow them.
+ if(entry.Target)
+ {
+ // Target dependencies are always known. Follow them.
+ BFSEntry qe = {index, 0};
+ this->BFSQueue.push(qe);
+ }
+ else
+ {
+ // 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()))
+ {
+ // The item dependencies are known. Follow them.
+ BFSEntry qe = {index, val};
+ this->BFSQueue.push(qe);
+ }
+ else if(!entry.IsFlag)
+ {
+ // The item dependencies are not known. We need to infer them.
+ this->InferredDependSets[index] = new DependSetList;
+ }
+ }
+
+ return index;
+}
+
+//----------------------------------------------------------------------------
+void cmComputeLinkDepends::FollowLinkEntry(BFSEntry const& qe)
+{
+ // Get this entry representation.
+ int depender_index = qe.Index;
+ LinkEntry const& entry = this->EntryList[depender_index];
+
+ // Follow the item's dependencies.
+ if(entry.Target)
+ {
+ // Follow the target dependencies.
+ if(cmTarget::LinkInterface const* iface =
+ entry.Target->GetLinkInterface(this->Config))
+ {
+ // This target provides its own link interface information.
+ this->AddLinkEntries(depender_index, iface->Libraries);
+
+ // Handle dependent shared libraries.
+ this->FollowSharedDeps(depender_index, iface);
+
+ // Support for CMP0003.
+ for(std::vector<std::string>::const_iterator
+ oi = iface->WrongConfigLibraries.begin();
+ oi != iface->WrongConfigLibraries.end(); ++oi)
+ {
+ this->CheckWrongConfigItem(depender_index, *oi);
+ }
+ }
+ }
+ else
+ {
+ // Follow the old-style dependency list.
+ this->AddVarLinkEntries(depender_index, qe.LibDepends);
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmComputeLinkDepends
+::FollowSharedDeps(int depender_index, cmTarget::LinkInterface const* iface,
+ bool follow_interface)
+{
+ // Follow dependencies if we have not followed them already.
+ if(this->SharedDepFollowed.insert(depender_index).second)
+ {
+ if(follow_interface)
+ {
+ this->QueueSharedDependencies(depender_index, iface->Libraries);
+ }
+ this->QueueSharedDependencies(depender_index, iface->SharedDeps);
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmComputeLinkDepends
+::QueueSharedDependencies(int depender_index,
+ std::vector<std::string> const& deps)
+{
+ for(std::vector<std::string>::const_iterator li = deps.begin();
+ li != deps.end(); ++li)
+ {
+ SharedDepEntry qe;
+ qe.Item = *li;
+ qe.DependerIndex = depender_index;
+ this->SharedDepQueue.push(qe);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry const& dep)
+{
+ // Check if the target already has an entry.
+ std::map<cmStdString, int>::iterator lei =
+ this->LinkEntryIndex.find(dep.Item);
+ if(lei == this->LinkEntryIndex.end())
+ {
+ // Allocate a spot for the item entry.
+ lei = this->AllocateLinkEntry(dep.Item);
+
+ // Initialize the item entry.
+ LinkEntry& entry = this->EntryList[lei->second];
+ entry.Item = dep.Item;
+ entry.Target = this->FindTargetToLink(dep.DependerIndex,
+ dep.Item.c_str());
+
+ // This item was added specifically because it is a dependent
+ // shared library. It may get special treatment
+ // in cmComputeLinkInformation.
+ entry.IsSharedDep = true;
+ }
+
+ // Get the link entry for this target.
+ int index = lei->second;
+ LinkEntry& entry = this->EntryList[index];
+
+ // This shared library dependency must follow the item that listed
+ // it.
+ this->EntryConstraintGraph[dep.DependerIndex].push_back(index);
+
+ // Target items may have their own dependencies.
+ if(entry.Target)
+ {
+ if(cmTarget::LinkInterface const* iface =
+ entry.Target->GetLinkInterface(this->Config))
+ {
+ // Follow public and private dependencies transitively.
+ this->FollowSharedDeps(index, iface, true);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmComputeLinkDepends::AddVarLinkEntries(int depender_index,
+ const char* value)
+{
+ // This is called to add the dependencies named by
+ // <item>_LIB_DEPENDS. The variable contains a semicolon-separated
+ // list. The list contains link-type;item pairs and just items.
+ std::vector<std::string> deplist;
+ cmSystemTools::ExpandListArgument(value, deplist);
+
+ // Look for entries meant for this configuration.
+ std::vector<std::string> actual_libs;
+ cmTarget::LinkLibraryType llt = cmTarget::GENERAL;
+ bool haveLLT = false;
+ for(std::vector<std::string>::const_iterator di = deplist.begin();
+ di != deplist.end(); ++di)
+ {
+ if(*di == "debug")
+ {
+ llt = cmTarget::DEBUG;
+ haveLLT = true;
+ }
+ else if(*di == "optimized")
+ {
+ llt = cmTarget::OPTIMIZED;
+ haveLLT = true;
+ }
+ else if(*di == "general")
+ {
+ llt = cmTarget::GENERAL;
+ haveLLT = true;
+ }
+ else if(!di->empty())
+ {
+ // If no explicit link type was given prior to this entry then
+ // check if the entry has its own link type variable. This is
+ // needed for compatibility with dependency files generated by
+ // the export_library_dependencies command from CMake 2.4 and
+ // lower.
+ if(!haveLLT)
+ {
+ std::string var = *di;
+ var += "_LINK_TYPE";
+ if(const char* val = this->Makefile->GetDefinition(var.c_str()))
+ {
+ if(strcmp(val, "debug") == 0)
+ {
+ llt = cmTarget::DEBUG;
+ }
+ else if(strcmp(val, "optimized") == 0)
+ {
+ llt = cmTarget::OPTIMIZED;
+ }
+ }
+ }
+
+ // If the library is meant for this link type then use it.
+ if(llt == cmTarget::GENERAL || llt == this->LinkType)
+ {
+ actual_libs.push_back(*di);
+ }
+ else if(this->OldLinkDirMode)
+ {
+ this->CheckWrongConfigItem(depender_index, *di);
+ }
+
+ // Reset the link type until another explicit type is given.
+ llt = cmTarget::GENERAL;
+ haveLLT = false;
+ }
+ }
+
+ // Add the entries from this list.
+ this->AddLinkEntries(depender_index, actual_libs);
+}
+
+//----------------------------------------------------------------------------
+void cmComputeLinkDepends::AddDirectLinkEntries()
+{
+ // Add direct link dependencies in this configuration.
+ cmTarget::LinkImplementation const* impl =
+ this->Target->GetLinkImplementation(this->Config);
+ this->AddLinkEntries(-1, impl->Libraries);
+ for(std::vector<std::string>::const_iterator
+ wi = impl->WrongConfigLibraries.begin();
+ wi != impl->WrongConfigLibraries.end(); ++wi)
+ {
+ this->CheckWrongConfigItem(-1, *wi);
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmComputeLinkDepends::AddLinkEntries(int depender_index,
+ std::vector<std::string> 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();
+ li != libs.end(); ++li)
+ {
+ // Skip entries that will resolve to the target getting linked or
+ // are empty.
+ std::string item = this->Target->CheckCMP0004(*li);
+ if(item == this->Target->GetName() || item.empty())
+ {
+ continue;
+ }
+
+ // Add a link entry for this item.
+ int dependee_index = this->AddLinkEntry(depender_index, item);
+
+ // The dependee must come after the depender.
+ if(depender_index >= 0)
+ {
+ this->EntryConstraintGraph[depender_index].push_back(dependee_index);
+ }
+ else
+ {
+ // This is a direct dependency of the target being linked.
+ this->OriginalEntries.push_back(dependee_index);
+ }
+
+ // Update the inferred dependencies for earlier items.
+ for(std::map<int, DependSet>::iterator dsi = dependSets.begin();
+ dsi != dependSets.end(); ++dsi)
+ {
+ // Add this item to the inferred dependencies of other items.
+ // Target items are never inferred dependees because unknown
+ // items are outside libraries that should not be depending on
+ // targets.
+ if(!this->EntryList[dependee_index].Target &&
+ !this->EntryList[dependee_index].IsFlag &&
+ dependee_index != dsi->first)
+ {
+ dsi->second.insert(dependee_index);
+ }
+ }
+
+ // If this item needs to have dependencies inferred, do so.
+ if(this->InferredDependSets[dependee_index])
+ {
+ // Make sure an entry exists to hold the set for the item.
+ dependSets[dependee_index];
+ }
+ }
+
+ // Store the inferred dependency sets discovered for this list.
+ for(std::map<int, DependSet>::iterator dsi = dependSets.begin();
+ dsi != dependSets.end(); ++dsi)
+ {
+ this->InferredDependSets[dsi->first]->push_back(dsi->second);
+ }
+}
+
+//----------------------------------------------------------------------------
+cmTarget* cmComputeLinkDepends::FindTargetToLink(int depender_index,
+ const char* name)
+{
+ // Look for a target in the scope of the depender.
+ cmMakefile* mf = this->Makefile;
+ if(depender_index >= 0)
+ {
+ if(cmTarget* depender = this->EntryList[depender_index].Target)
+ {
+ mf = depender->GetMakefile();
+ }
+ }
+ 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;
+}
+
+//----------------------------------------------------------------------------
+void cmComputeLinkDepends::InferDependencies()
+{
+ // The inferred dependency sets for each item list the possible
+ // dependencies. The intersection of the sets for one item form its
+ // inferred dependencies.
+ for(unsigned int depender_index=0;
+ depender_index < this->InferredDependSets.size(); ++depender_index)
+ {
+ // Skip items for which dependencies do not need to be inferred or
+ // for which the inferred dependency sets are empty.
+ DependSetList* sets = this->InferredDependSets[depender_index];
+ if(!sets || sets->empty())
+ {
+ continue;
+ }
+
+ // Intersect the sets for this item.
+ DependSetList::const_iterator i = sets->begin();
+ DependSet common = *i;
+ for(++i; i != sets->end(); ++i)
+ {
+ DependSet intersection;
+ cmsys_stl::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);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmComputeLinkDepends::CleanConstraintGraph()
+{
+ for(Graph::iterator i = this->EntryConstraintGraph.begin();
+ i != this->EntryConstraintGraph.end(); ++i)
+ {
+ // 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());
+
+ // Make the edge list unique.
+ EdgeList::iterator last = cmsys_stl::unique(i->begin(), i->end());
+ i->erase(last, i->end());
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmComputeLinkDepends::DisplayConstraintGraph()
+{
+ // Display the graph nodes and their edges.
+ cmOStringStream 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";
+ }
+ }
+ fprintf(stderr, "%s\n", e.str().c_str());
+}
+
+//----------------------------------------------------------------------------
+void cmComputeLinkDepends::OrderLinkEntires()
+{
+ // Compute the DAG of strongly connected components. The algorithm
+ // used by cmComputeComponentGraph should identify the components in
+ // the same order in which the items were originally discovered in
+ // the BFS. This should preserve the original order when no
+ // constraints disallow it.
+ this->CCG = new cmComputeComponentGraph(this->EntryConstraintGraph);
+
+ // The component graph is guaranteed to be acyclic. Start a DFS
+ // from every entry to compute a topological order for the
+ // components.
+ Graph const& cgraph = this->CCG->GetComponentGraph();
+ int n = static_cast<int>(cgraph.size());
+ this->ComponentVisited.resize(cgraph.size(), 0);
+ this->ComponentOrder.resize(cgraph.size(), n);
+ this->ComponentOrderId = n;
+ // Run in reverse order so the topological order will preserve the
+ // original order where there are no constraints.
+ for(int c = n-1; c >= 0; --c)
+ {
+ this->VisitComponent(c);
+ }
+
+ // Display the component graph.
+ if(this->DebugMode)
+ {
+ this->DisplayComponents();
+ }
+
+ // Start with the original link line.
+ for(std::vector<int>::const_iterator i = this->OriginalEntries.begin();
+ i != this->OriginalEntries.end(); ++i)
+ {
+ this->VisitEntry(*i);
+ }
+
+ // Now explore anything left pending. Since the component graph is
+ // guaranteed to be acyclic we know this will terminate.
+ while(!this->PendingComponents.empty())
+ {
+ // Visit one entry from the first pending component. The visit
+ // logic will update the pending components accordingly. Since
+ // the pending components are kept in topological order this will
+ // not repeat one.
+ int e = *this->PendingComponents.begin()->second.Entries.begin();
+ this->VisitEntry(e);
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmComputeLinkDepends::DisplayComponents()
+{
+ fprintf(stderr, "The strongly connected components are:\n");
+ std::vector<NodeList> const& components = this->CCG->GetComponents();
+ for(unsigned int c=0; c < components.size(); ++c)
+ {
+ fprintf(stderr, "Component (%u):\n", c);
+ NodeList const& nl = components[c];
+ for(NodeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni)
+ {
+ int i = *ni;
+ fprintf(stderr, " item %d [%s]\n", i,
+ this->EntryList[i].Item.c_str());
+ }
+ EdgeList const& ol = this->CCG->GetComponentGraphEdges(c);
+ for(EdgeList::const_iterator oi = ol.begin(); oi != ol.end(); ++oi)
+ {
+ int i = *oi;
+ fprintf(stderr, " followed by Component (%d)\n", i);
+ }
+ fprintf(stderr, " topo order index %d\n",
+ this->ComponentOrder[c]);
+ }
+ fprintf(stderr, "\n");
+}
+
+//----------------------------------------------------------------------------
+void cmComputeLinkDepends::VisitComponent(unsigned int c)
+{
+ // Check if the node has already been visited.
+ if(this->ComponentVisited[c])
+ {
+ return;
+ }
+
+ // We are now visiting this component so mark it.
+ this->ComponentVisited[c] = 1;
+
+ // Visit the neighbors of the component first.
+ // Run in reverse order so the topological order will preserve the
+ // original order where there are no constraints.
+ EdgeList const& nl = this->CCG->GetComponentGraphEdges(c);
+ for(EdgeList::const_reverse_iterator ni = nl.rbegin();
+ ni != nl.rend(); ++ni)
+ {
+ this->VisitComponent(*ni);
+ }
+
+ // Assign an ordering id to this component.
+ this->ComponentOrder[c] = --this->ComponentOrderId;
+}
+
+//----------------------------------------------------------------------------
+void cmComputeLinkDepends::VisitEntry(int index)
+{
+ // Include this entry on the link line.
+ this->FinalLinkOrder.push_back(index);
+
+ // This entry has now been seen. Update its component.
+ bool completed = false;
+ int component = this->CCG->GetComponentMap()[index];
+ std::map<int, PendingComponent>::iterator mi =
+ this->PendingComponents.find(this->ComponentOrder[component]);
+ if(mi != this->PendingComponents.end())
+ {
+ // The entry is in an already pending component.
+ PendingComponent& pc = mi->second;
+
+ // Remove the entry from those pending in its component.
+ pc.Entries.erase(index);
+ if(pc.Entries.empty())
+ {
+ // The complete component has been seen since it was last needed.
+ --pc.Count;
+
+ if(pc.Count == 0)
+ {
+ // The component has been completed.
+ this->PendingComponents.erase(mi);
+ completed = true;
+ }
+ else
+ {
+ // The whole component needs to be seen again.
+ NodeList const& nl = this->CCG->GetComponent(component);
+ assert(nl.size() > 1);
+ pc.Entries.insert(nl.begin(), nl.end());
+ }
+ }
+ }
+ else
+ {
+ // The entry is not in an already pending component.
+ NodeList const& nl = this->CCG->GetComponent(component);
+ if(nl.size() > 1)
+ {
+ // This is a non-trivial component. It is now pending.
+ PendingComponent& pc = this->MakePendingComponent(component);
+
+ // The starting entry has already been seen.
+ pc.Entries.erase(index);
+ }
+ else
+ {
+ // This is a trivial component, so it is already complete.
+ completed = true;
+ }
+ }
+
+ // If the entry completed a component, the component's dependencies
+ // are now pending.
+ if(completed)
+ {
+ EdgeList const& ol = this->CCG->GetComponentGraphEdges(component);
+ for(EdgeList::const_iterator oi = ol.begin(); oi != ol.end(); ++oi)
+ {
+ // This entire component is now pending no matter whether it has
+ // been partially seen already.
+ this->MakePendingComponent(*oi);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+cmComputeLinkDepends::PendingComponent&
+cmComputeLinkDepends::MakePendingComponent(unsigned int component)
+{
+ // Create an entry (in topological order) for the component.
+ PendingComponent& pc =
+ this->PendingComponents[this->ComponentOrder[component]];
+ pc.Id = component;
+ NodeList const& nl = this->CCG->GetComponent(component);
+
+ if(nl.size() == 1)
+ {
+ // Trivial components need be seen only once.
+ pc.Count = 1;
+ }
+ else
+ {
+ // This is a non-trivial strongly connected component of the
+ // original graph. It consists of two or more libraries
+ // (archives) that mutually require objects from one another. In
+ // the worst case we may have to repeat the list of libraries as
+ // many times as there are object files in the biggest archive.
+ // For now we just list them twice.
+ //
+ // The list of items in the component has been sorted by the order
+ // of discovery in the original BFS of dependencies. This has the
+ // advantage that the item directly linked by a target requiring
+ // this component will come first which minimizes the number of
+ // repeats needed.
+ pc.Count = this->ComputeComponentCount(nl);
+ }
+
+ // Store the entries to be seen.
+ pc.Entries.insert(nl.begin(), nl.end());
+
+ return pc;
+}
+
+//----------------------------------------------------------------------------
+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(cmTarget::LinkInterface const* iface =
+ target->GetLinkInterface(this->Config))
+ {
+ if(iface->Multiplicity > count)
+ {
+ count = iface->Multiplicity;
+ }
+ }
+ }
+ }
+ return count;
+}
+
+//----------------------------------------------------------------------------
+void cmComputeLinkDepends::DisplayFinalEntries()
+{
+ fprintf(stderr, "target [%s] links to:\n", this->Target->GetName());
+ 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());
+ }
+ else
+ {
+ fprintf(stderr, " item [%s]\n", lei->Item.c_str());
+ }
+ }
+ fprintf(stderr, "\n");
+}
+
+//----------------------------------------------------------------------------
+void cmComputeLinkDepends::CheckWrongConfigItem(int depender_index,
+ std::string const& item)
+{
+ if(!this->OldLinkDirMode)
+ {
+ return;
+ }
+
+ // 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(!tgt->IsImported())
+ {
+ this->OldWrongConfigItems.insert(tgt);
+ }
+ }
+}
diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h
new file mode 100644
index 000000000..80a04541f
--- /dev/null
+++ b/Source/cmComputeLinkDepends.h
@@ -0,0 +1,168 @@
+/*============================================================================
+ 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 cmComputeLinkDepends_h
+#define cmComputeLinkDepends_h
+
+#include "cmStandardIncludes.h"
+#include "cmTarget.h"
+
+#include "cmGraphAdjacencyList.h"
+
+#include <queue>
+
+class cmComputeComponentGraph;
+class cmGlobalGenerator;
+class cmLocalGenerator;
+class cmMakefile;
+class cmTarget;
+class cmake;
+
+/** \class cmComputeLinkDepends
+ * \brief Compute link dependencies for targets.
+ */
+class cmComputeLinkDepends
+{
+public:
+ cmComputeLinkDepends(cmTarget* target, const char* config);
+ ~cmComputeLinkDepends();
+
+ // Basic information about each link item.
+ struct LinkEntry
+ {
+ std::string Item;
+ cmTarget* Target;
+ bool IsSharedDep;
+ bool IsFlag;
+ LinkEntry(): Item(), Target(0), IsSharedDep(false), IsFlag(false) {}
+ LinkEntry(LinkEntry const& r):
+ Item(r.Item), Target(r.Target), IsSharedDep(r.IsSharedDep),
+ IsFlag(r.IsFlag) {}
+ };
+
+ typedef std::vector<LinkEntry> EntryVector;
+ EntryVector const& Compute();
+
+ void SetOldLinkDirMode(bool b);
+ std::set<cmTarget*> const& GetOldWrongConfigItems() const
+ { return this->OldWrongConfigItems; }
+
+private:
+
+ // Context information.
+ cmTarget* Target;
+ cmMakefile* Makefile;
+ cmLocalGenerator* LocalGenerator;
+ cmGlobalGenerator* GlobalGenerator;
+ cmake* CMakeInstance;
+ bool DebugMode;
+
+ // Configuration information.
+ const char* Config;
+ cmTarget::LinkLibraryType LinkType;
+
+ // Output information.
+ EntryVector FinalLinkEntries;
+
+ typedef cmTarget::LinkLibraryVectorType LinkLibraryVectorType;
+
+ std::map<cmStdString, int>::iterator
+ AllocateLinkEntry(std::string const& item);
+ int AddLinkEntry(int depender_index, std::string 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);
+
+ // One entry for each unique item.
+ std::vector<LinkEntry> EntryList;
+ std::map<cmStdString, int> LinkEntryIndex;
+
+ // BFS of initial dependencies.
+ struct BFSEntry
+ {
+ int Index;
+ const char* LibDepends;
+ };
+ std::queue<BFSEntry> BFSQueue;
+ void FollowLinkEntry(BFSEntry const&);
+
+ // Shared libraries that are included only because they are
+ // dependencies of other shared libraries, not because they are part
+ // of the interface.
+ struct SharedDepEntry
+ {
+ std::string Item;
+ int DependerIndex;
+ };
+ std::queue<SharedDepEntry> SharedDepQueue;
+ std::set<int> SharedDepFollowed;
+ void FollowSharedDeps(int depender_index,
+ cmTarget::LinkInterface const* iface,
+ bool follow_interface = false);
+ void QueueSharedDependencies(int depender_index,
+ std::vector<std::string> const& deps);
+ void HandleSharedDependency(SharedDepEntry const& dep);
+
+ // Dependency inferral for each link item.
+ struct DependSet: public std::set<int> {};
+ struct DependSetList: public std::vector<DependSet> {};
+ std::vector<DependSetList*> InferredDependSets;
+ void InferDependencies();
+
+ // Ordering constraint graph adjacency list.
+ typedef cmGraphNodeList NodeList;
+ typedef cmGraphEdgeList EdgeList;
+ typedef cmGraphAdjacencyList Graph;
+ Graph EntryConstraintGraph;
+ void CleanConstraintGraph();
+ void DisplayConstraintGraph();
+
+ // Ordering algorithm.
+ 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
+ // component topological index.
+ int Id;
+
+ // The number of times the component needs to be seen. This is
+ // always 1 for trivial components and is initially 2 for
+ // non-trivial components.
+ int Count;
+
+ // The entries yet to be seen to complete the component.
+ std::set<int> Entries;
+ };
+ std::map<int, PendingComponent> PendingComponents;
+ cmComputeComponentGraph* CCG;
+ std::vector<int> FinalLinkOrder;
+ void DisplayComponents();
+ void VisitComponent(unsigned int c);
+ void VisitEntry(int index);
+ PendingComponent& MakePendingComponent(unsigned int component);
+ int ComputeComponentCount(NodeList const& nl);
+ void DisplayFinalEntries();
+
+ // Record of the original link line.
+ std::vector<int> OriginalEntries;
+
+ // Compatibility help.
+ 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
new file mode 100644
index 000000000..df78bf886
--- /dev/null
+++ b/Source/cmComputeLinkInformation.cxx
@@ -0,0 +1,1869 @@
+/*============================================================================
+ 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 "cmComputeLinkInformation.h"
+
+#include "cmComputeLinkDepends.h"
+#include "cmOrderDirectories.h"
+
+#include "cmGlobalGenerator.h"
+#include "cmLocalGenerator.h"
+#include "cmMakefile.h"
+#include "cmTarget.h"
+#include "cmake.h"
+
+#include <ctype.h>
+
+//#define CM_COMPUTE_LINK_INFO_DEBUG
+
+/*
+Notes about linking on various platforms:
+
+------------------------------------------------------------------------------
+
+Linux, FreeBSD, Mac OS X, IRIX, Sun, Windows:
+
+Linking to libraries using the full path works fine.
+
+------------------------------------------------------------------------------
+
+On AIX, more work is needed.
+
+ The "-bnoipath" option is needed. From "man ld":
+
+ Note: If you specify a shared object, or an archive file
+ containing a shared object, with an absolute or relative path
+ name, instead of with the -lName flag, the path name is
+ included in the import file ID string in the loader section of
+ the output file. You can override this behavior with the
+ -bnoipath option.
+
+ noipath
+
+ For shared objects listed on the command-line, rather than
+ specified with the -l flag, use a null path component when
+ listing the shared object in the loader section of the
+ output file. A null path component is always used for
+ shared objects specified with the -l flag. This option
+ does not affect the specification of a path component by
+ using a line beginning with #! in an import file. The
+ default is the ipath option.
+
+ This prevents the full path specified on the compile line from being
+ compiled directly into the binary.
+
+ By default the linker places -L paths in the embedded runtime path.
+ In order to implement CMake's RPATH interface correctly, we need the
+ -blibpath:Path option. From "man ld":
+
+ libpath:Path
+
+ Uses Path as the library path when writing the loader section
+ of the output file. Path is neither checked for validity nor
+ used when searching for libraries specified by the -l flag.
+ Path overrides any library paths generated when the -L flag is
+ used.
+
+ If you do not specify any -L flags, or if you specify the
+ nolibpath option, the default library path information is
+ written in the loader section of the output file. The default
+ library path information is the value of the LIBPATH
+ environment variable if it is defined, and /usr/lib:/lib,
+ otherwise.
+
+ We can pass -Wl,-blibpath:/usr/lib:/lib always to avoid the -L stuff
+ and not break when the user sets LIBPATH. Then if we want to add an
+ rpath we insert it into the option before /usr/lib.
+
+------------------------------------------------------------------------------
+
+On HP-UX, more work is needed. There are differences between
+versions.
+
+ld: 92453-07 linker linker ld B.10.33 990520
+
+ Linking with a full path works okay for static and shared libraries.
+ The linker seems to always put the full path to where the library
+ was found in the binary whether using a full path or -lfoo syntax.
+ Transitive link dependencies work just fine due to the full paths.
+
+ It has the "-l:libfoo.sl" option. The +nodefaultrpath is accepted
+ but not documented and does not seem to do anything. There is no
+ +forceload option.
+
+ld: 92453-07 linker ld HP Itanium(R) B.12.41 IPF/IPF
+
+ Linking with a full path works okay for static libraries.
+
+ Linking with a full path works okay for shared libraries. However
+ dependent (transitive) libraries of those linked directly must be
+ either found with an rpath stored in the direct dependencies or
+ found in -L paths as if they were specified with "-l:libfoo.sl"
+ (really "-l:<soname>"). The search matches that of the dynamic
+ loader but only with -L paths. In other words, if we have an
+ executable that links to shared library bar which links to shared
+ library foo, the link line for the exe must contain
+
+ /dir/with/bar/libbar.sl -L/dir/with/foo
+
+ It does not matter whether the exe wants to link to foo directly or
+ whether /dir/with/foo/libfoo.sl is listed. The -L path must still
+ be present. It should match the runtime path computed for the
+ executable taking all directly and transitively linked libraries
+ into account.
+
+ The "+nodefaultrpath" option should be used to avoid getting -L
+ paths in the rpath unless we add our own rpath with +b. This means
+ that skip-build-rpath should use this option.
+
+ See documentation in "man ld", "man dld.so", and
+ http://docs.hp.com/en/B2355-90968/creatingandusinglibraries.htm
+
+ +[no]defaultrpath
+ +defaultrpath is the default. Include any paths that are
+ specified with -L in the embedded path, unless you specify the
+ +b option. If you use +b, only the path list specified by +b is
+ in the embedded path.
+
+ The +nodefaultrpath option removes all library paths that were
+ specified with the -L option from the embedded path. The linker
+ searches the library paths specified by the -L option at link
+ time. At run time, the only library paths searched are those
+ specified by the environment variables LD_LIBRARY_PATH and
+ SHLIB_PATH, library paths specified by the +b linker option, and
+ finally the default library paths.
+
+ +rpathfirst
+ This option will cause the paths specified in RPATH (embedded
+ path) to be used before the paths specified in LD_LIBRARY_PATH
+ or SHLIB_PATH, in searching for shared libraries. This changes
+ the default search order of LD_LIBRARY_PATH, SHLIB_PATH, and
+ RPATH (embedded path).
+
+------------------------------------------------------------------------------
+Notes about dependent (transitive) shared libraries:
+
+On non-Windows systems shared libraries may have transitive
+dependencies. In order to support LINK_INTERFACE_LIBRARIES we must
+support linking to a shared library without listing all the libraries
+to which it links. Some linkers want to be able to find the
+transitive dependencies (dependent libraries) of shared libraries
+listed on the command line.
+
+ - On Windows, DLLs are not directly linked, and the import libraries
+ have no transitive dependencies.
+
+ - On Mac OS X 10.5 and above transitive dependencies are not needed.
+
+ - On Mac OS X 10.4 and below we need to actually list the dependencies.
+ Otherwise when using -isysroot for universal binaries it cannot
+ find the dependent libraries. Listing them on the command line
+ tells the linker where to find them, but unfortunately also links
+ the library.
+
+ - On HP-UX, the linker wants to find the transitive dependencies of
+ shared libraries in the -L paths even if the dependent libraries
+ are given on the link line.
+
+ - On AIX the transitive dependencies are not needed.
+
+ - On SGI, the linker wants to find the transitive dependencies of
+ shared libraries in the -L paths if they are not given on the link
+ line. Transitive linking can be disabled using the options
+
+ -no_transitive_link -Wl,-no_transitive_link
+
+ which disable it. Both options must be given when invoking the
+ linker through the compiler.
+
+ - On Sun, the linker wants to find the transitive dependencies of
+ shared libraries in the -L paths if they are not given on the link
+ line.
+
+ - On Linux, FreeBSD, and QNX:
+
+ The linker wants to find the transitive dependencies of shared
+ libraries in the "-rpath-link" paths option if they have not been
+ given on the link line. The option is like rpath but just for
+ link time:
+
+ -Wl,-rpath-link,"/path1:/path2"
+
+For -rpath-link, we need a separate runtime path ordering pass
+including just the dependent libraries that are not linked.
+
+For -L paths on non-HP, we can do the same thing as with rpath-link
+but put the results in -L paths. The paths should be listed at the
+end to avoid conflicting with user search paths (?).
+
+For -L paths on HP, we should do a runtime path ordering pass with
+all libraries, both linked and non-linked. Even dependent
+libraries that are also linked need to be listed in -L paths.
+
+In our implementation we add all dependent libraries to the runtime
+path computation. Then the auto-generated RPATH will find everything.
+
+------------------------------------------------------------------------------
+Notes about shared libraries with not builtin soname:
+
+Some UNIX shared libraries may be created with no builtin soname. On
+some platforms such libraries cannot be linked using the path to their
+location because the linker will copy the path into the field used to
+find the library at runtime.
+
+ Apple: ../libfoo.dylib ==> libfoo.dylib # ok, uses install_name
+ SGI: ../libfoo.so ==> libfoo.so # ok
+ AIX: ../libfoo.so ==> libfoo.so # ok
+ Linux: ../libfoo.so ==> ../libfoo.so # bad
+ HP-UX: ../libfoo.so ==> ../libfoo.so # bad
+ Sun: ../libfoo.so ==> ../libfoo.so # bad
+ FreeBSD: ../libfoo.so ==> ../libfoo.so # bad
+
+In order to link these libraries we need to use the old-style split
+into -L.. and -lfoo options. This should be fairly safe because most
+problems with -lfoo options were related to selecting shared libraries
+instead of static but in this case we want the shared lib. Link
+directory ordering needs to be done to make sure these shared
+libraries are found first. There should be very few restrictions
+because this need be done only for shared libraries without soname-s.
+
+*/
+
+//----------------------------------------------------------------------------
+cmComputeLinkInformation
+::cmComputeLinkInformation(cmTarget* target, const char* config)
+{
+ // Store context information.
+ this->Target = target;
+ this->Makefile = this->Target->GetMakefile();
+ this->LocalGenerator = this->Makefile->GetLocalGenerator();
+ this->GlobalGenerator = this->LocalGenerator->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");
+
+ // The configuration being linked.
+ this->Config = config;
+
+ // Allocate internals.
+ this->OrderLinkerSearchPath =
+ new cmOrderDirectories(this->GlobalGenerator, target,
+ "linker search path");
+ this->OrderRuntimeSearchPath =
+ new cmOrderDirectories(this->GlobalGenerator, target,
+ "runtime search path");
+ this->OrderDependentRPath = 0;
+
+ // Get the language used for linking this target.
+ this->LinkLanguage = this->Target->GetLinkerLanguage(config);
+ if(!this->LinkLanguage)
+ {
+ // The Compute method will do nothing, so skip the rest of the
+ // initialization.
+ return;
+ }
+
+ // Check whether we should use an import library for linking a target.
+ this->UseImportLibrary =
+ this->Makefile->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")?true:false;
+
+ // On platforms without import libraries there may be a special flag
+ // to use when creating a plugin (module) that obtains symbols from
+ // the program that will load it.
+ this->LoaderFlag = 0;
+ if(!this->UseImportLibrary &&
+ this->Target->GetType() == cmTarget::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());
+ }
+
+ // Get options needed to link libraries.
+ this->LibLinkFlag =
+ this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_FLAG");
+ this->LibLinkFileFlag =
+ this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_FILE_FLAG");
+ this->LibLinkSuffix =
+ this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_SUFFIX");
+
+ // Get options needed to specify RPATHs.
+ this->RuntimeUseChrpath = false;
+ if(this->Target->GetType() != cmTarget::STATIC_LIBRARY)
+ {
+ const char* tType =
+ ((this->Target->GetType() == cmTarget::EXECUTABLE)?
+ "EXECUTABLE" : "SHARED_LIBRARY");
+ std::string rtVar = "CMAKE_";
+ rtVar += tType;
+ rtVar += "_RUNTIME_";
+ 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->RuntimeAlways =
+ (this->Makefile->
+ GetSafeDefinition("CMAKE_PLATFORM_REQUIRED_RUNTIME_PATH"));
+ this->RuntimeUseChrpath = this->Target->IsChrpathUsed(config);
+
+ // Get options needed to help find dependent libraries.
+ std::string rlVar = "CMAKE_";
+ rlVar += tType;
+ rlVar += "_RPATH_LINK_";
+ rlVar += this->LinkLanguage;
+ rlVar += "_FLAG";
+ this->RPathLinkFlag = this->Makefile->GetSafeDefinition(rlVar.c_str());
+ }
+
+ // Check if we need to include the runtime search path at link time.
+ {
+ std::string var = "CMAKE_SHARED_LIBRARY_LINK_";
+ var += this->LinkLanguage;
+ var += "_WITH_RUNTIME_PATH";
+ this->LinkWithRuntimePath = this->Makefile->IsOn(var.c_str());
+ }
+
+ // Check the platform policy for missing soname case.
+ this->NoSONameUsesPath =
+ this->Makefile->IsOn("CMAKE_PLATFORM_USES_PATH_WHEN_NO_SONAME");
+
+ // Get link type information.
+ this->ComputeLinkTypeInfo();
+
+ // Setup the link item parser.
+ this->ComputeItemParserInfo();
+
+ // Setup framework support.
+ this->ComputeFrameworkInfo();
+
+ // Choose a mode for dealing with shared library dependencies.
+ this->SharedDependencyMode = SharedDepModeNone;
+ if(this->Makefile->IsOn("CMAKE_LINK_DEPENDENT_LIBRARY_FILES"))
+ {
+ this->SharedDependencyMode = SharedDepModeLink;
+ }
+ else if(this->Makefile->IsOn("CMAKE_LINK_DEPENDENT_LIBRARY_DIRS"))
+ {
+ this->SharedDependencyMode = SharedDepModeLibDir;
+ }
+ else if(!this->RPathLinkFlag.empty())
+ {
+ this->SharedDependencyMode = SharedDepModeDir;
+ this->OrderDependentRPath =
+ new cmOrderDirectories(this->GlobalGenerator, target,
+ "dependent library path");
+ }
+
+ // Add the search path entries requested by the user to path ordering.
+ this->OrderLinkerSearchPath
+ ->AddUserDirectories(this->Target->GetLinkDirectories());
+ this->OrderRuntimeSearchPath
+ ->AddUserDirectories(this->Target->GetLinkDirectories());
+
+ // Set up the implicit link directories.
+ this->LoadImplicitLinkInfo();
+ this->OrderLinkerSearchPath
+ ->SetImplicitDirectories(this->ImplicitLinkDirs);
+ this->OrderRuntimeSearchPath
+ ->SetImplicitDirectories(this->ImplicitLinkDirs);
+ if(this->OrderDependentRPath)
+ {
+ this->OrderDependentRPath
+ ->SetImplicitDirectories(this->ImplicitLinkDirs);
+ this->OrderDependentRPath
+ ->AddLanguageDirectories(this->RuntimeLinkDirs);
+ }
+
+ // Decide whether to enable compatible library search path mode.
+ // There exists code that effectively does
+ //
+ // /path/to/libA.so -lB
+ //
+ // where -lB is meant to link to /path/to/libB.so. This is broken
+ // because it specified -lB without specifying a link directory (-L)
+ // in which to search for B. This worked in CMake 2.4 and below
+ // because -L/path/to would be added by the -L/-l split for A. In
+ // order to support such projects we need to add the directories
+ // containing libraries linked with a full path to the -L path.
+ this->OldLinkDirMode =
+ this->Target->GetPolicyStatusCMP0003() != cmPolicies::NEW;
+ if(this->OldLinkDirMode)
+ {
+ // 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);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+cmComputeLinkInformation::~cmComputeLinkInformation()
+{
+ delete this->OrderLinkerSearchPath;
+ delete this->OrderRuntimeSearchPath;
+ delete this->OrderDependentRPath;
+}
+
+//----------------------------------------------------------------------------
+cmComputeLinkInformation::ItemVector const&
+cmComputeLinkInformation::GetItems()
+{
+ return this->Items;
+}
+
+//----------------------------------------------------------------------------
+std::vector<std::string> const& cmComputeLinkInformation::GetDirectories()
+{
+ return this->OrderLinkerSearchPath->GetOrderedDirectories();
+}
+
+//----------------------------------------------------------------------------
+std::string cmComputeLinkInformation::GetRPathLinkString()
+{
+ // If there is no separate linker runtime search flag (-rpath-link)
+ // there is no reason to compute a string.
+ if(!this->OrderDependentRPath)
+ {
+ return "";
+ }
+
+ // 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;
+}
+
+//----------------------------------------------------------------------------
+std::vector<std::string> const& cmComputeLinkInformation::GetDepends()
+{
+ return this->Depends;
+}
+
+//----------------------------------------------------------------------------
+std::vector<std::string> const& cmComputeLinkInformation::GetFrameworkPaths()
+{
+ return this->FrameworkPaths;
+}
+
+//----------------------------------------------------------------------------
+std::set<cmTarget*> const&
+cmComputeLinkInformation::GetSharedLibrariesLinked()
+{
+ return this->SharedLibrariesLinked;
+}
+
+//----------------------------------------------------------------------------
+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))
+ {
+ return false;
+ }
+
+ // We require a link language for the target.
+ if(!this->LinkLanguage)
+ {
+ cmSystemTools::
+ Error("CMake can not determine linker language for target:",
+ this->Target->GetName());
+ return false;
+ }
+
+ // Compute the ordered link line items.
+ cmComputeLinkDepends cld(this->Target, this->Config);
+ cld.SetOldLinkDirMode(this->OldLinkDirMode);
+ cmComputeLinkDepends::EntryVector const& linkEntries = cld.Compute();
+
+ // Add the link line items.
+ for(cmComputeLinkDepends::EntryVector::const_iterator
+ lei = linkEntries.begin();
+ lei != linkEntries.end(); ++lei)
+ {
+ if(lei->IsSharedDep)
+ {
+ this->AddSharedDepItem(lei->Item, lei->Target);
+ }
+ else
+ {
+ this->AddItem(lei->Item, lei->Target);
+ }
+ }
+
+ // Restore the target link type so the correct system runtime
+ // libraries are found.
+ const char* lss = this->Target->GetProperty("LINK_SEARCH_END_STATIC");
+ if(cmSystemTools::IsOn(lss))
+ {
+ this->SetCurrentLinkType(LinkStatic);
+ }
+ else
+ {
+ this->SetCurrentLinkType(this->StartLinkType);
+ }
+
+ // Finish listing compatibility paths.
+ if(this->OldLinkDirMode)
+ {
+ // 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)
+ {
+ cmTarget* tgt = *i;
+ bool implib =
+ (this->UseImportLibrary &&
+ (tgt->GetType() == cmTarget::SHARED_LIBRARY));
+ std::string lib = tgt->GetFullPath(this->Config , implib, true);
+ this->OldLinkDirItems.push_back(lib);
+ }
+ }
+
+ // Finish setting up linker search directories.
+ if(!this->FinishLinkerSearchDirectories())
+ {
+ return false;
+ }
+
+ // Add implicit language runtime libraries and directories.
+ this->AddImplicitLinkInfo();
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+void cmComputeLinkInformation::AddImplicitLinkInfo()
+{
+ // The link closure lists all languages whose implicit info is needed.
+ cmTarget::LinkClosure const* lc=this->Target->GetLinkClosure(this->Config);
+ for(std::vector<std::string>::const_iterator li = lc->Languages.begin();
+ li != lc->Languages.end(); ++li)
+ {
+ // Skip those of the linker language. They are implicit.
+ if(*li != this->LinkLanguage)
+ {
+ this->AddImplicitLinkInfo(*li);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmComputeLinkInformation::AddImplicitLinkInfo(std::string const& lang)
+{
+ // Add libraries for this language that are not implied by the
+ // linker language.
+ std::string libVar = "CMAKE_";
+ libVar += lang;
+ libVar += "_IMPLICIT_LINK_LIBRARIES";
+ if(const char* libs = this->Makefile->GetDefinition(libVar.c_str()))
+ {
+ std::vector<std::string> libsVec;
+ cmSystemTools::ExpandListArgument(libs, libsVec);
+ for(std::vector<std::string>::const_iterator i = libsVec.begin();
+ i != libsVec.end(); ++i)
+ {
+ if(this->ImplicitLinkLibs.find(*i) == this->ImplicitLinkLibs.end())
+ {
+ this->AddItem(i->c_str(), 0);
+ }
+ }
+ }
+
+ // Add linker search paths for this language that are not
+ // implied by the linker language.
+ std::string dirVar = "CMAKE_";
+ dirVar += lang;
+ dirVar += "_IMPLICIT_LINK_DIRECTORIES";
+ if(const char* dirs = this->Makefile->GetDefinition(dirVar.c_str()))
+ {
+ std::vector<std::string> dirsVec;
+ cmSystemTools::ExpandListArgument(dirs, dirsVec);
+ this->OrderLinkerSearchPath->AddLanguageDirectories(dirsVec);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmComputeLinkInformation::AddItem(std::string const& item, cmTarget* tgt)
+{
+ // Compute the proper name to use to link this library.
+ const char* config = this->Config;
+ bool impexe = (tgt && tgt->IsExecutableWithExports());
+ if(impexe && !this->UseImportLibrary && !this->LoaderFlag)
+ {
+ // Skip linking to executables on platforms with no import
+ // libraries or loader flags.
+ return;
+ }
+
+ if(tgt && tgt->IsLinkable())
+ {
+ // This is a CMake target. Ask the target for its real name.
+ if(impexe && this->LoaderFlag)
+ {
+ // This link item is an executable that may provide symbols
+ // used by this target. A special flag is needed on this
+ // 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
+ {
+ // Decide whether to use an import library.
+ bool implib =
+ (this->UseImportLibrary &&
+ (impexe || tgt->GetType() == cmTarget::SHARED_LIBRARY));
+
+ // Pass the full path to the target file.
+ std::string lib = tgt->GetFullPath(config, implib, true);
+ this->Depends.push_back(lib);
+
+ this->AddTargetItem(lib, tgt);
+ this->AddLibraryRuntimeInfo(lib, tgt);
+ }
+ }
+ else
+ {
+ // This is not a CMake target. Use the name given.
+ if(cmSystemTools::FileIsFullPath(item.c_str()))
+ {
+ if(cmSystemTools::FileIsDirectory(item.c_str()))
+ {
+ // This is a directory.
+ this->AddDirectoryItem(item);
+ }
+ else
+ {
+ // Use the full path given to the library file.
+ this->Depends.push_back(item);
+ this->AddFullItem(item);
+ this->AddLibraryRuntimeInfo(item);
+ }
+ }
+ else
+ {
+ // This is a library or option specified by the user.
+ this->AddUserItem(item, true);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmComputeLinkInformation::AddSharedDepItem(std::string const& item,
+ cmTarget* tgt)
+{
+ // If dropping shared library dependencies, ignore them.
+ if(this->SharedDependencyMode == SharedDepModeNone)
+ {
+ return;
+ }
+
+ // The user may have incorrectly named an item. Skip items that are
+ // not full paths to shared libraries.
+ if(tgt)
+ {
+ // The target will provide a full path. Make sure it is a shared
+ // library.
+ if(tgt->GetType() != cmTarget::SHARED_LIBRARY)
+ {
+ return;
+ }
+ }
+ else
+ {
+ // Skip items that are not full paths. We will not be able to
+ // reliably specify them.
+ if(!cmSystemTools::FileIsFullPath(item.c_str()))
+ {
+ return;
+ }
+
+ // Get the name of the library from the file name.
+ std::string file = cmSystemTools::GetFilenameName(item);
+ if(!this->ExtractSharedLibraryName.find(file.c_str()))
+ {
+ // This is not the name of a shared library.
+ return;
+ }
+ }
+
+ // If in linking mode, just link to the shared library.
+ if(this->SharedDependencyMode == SharedDepModeLink)
+ {
+ this->AddItem(item, tgt);
+ return;
+ }
+
+ // Get a full path to the dependent shared library.
+ // Add it to the runtime path computation so that the target being
+ // linked will be able to find it.
+ std::string lib;
+ if(tgt)
+ {
+ lib = tgt->GetFullPath(this->Config, this->UseImportLibrary);
+ this->AddLibraryRuntimeInfo(lib, tgt);
+ }
+ else
+ {
+ lib = item;
+ this->AddLibraryRuntimeInfo(lib);
+ }
+
+ // Check if we need to include the dependent shared library in other
+ // path ordering.
+ cmOrderDirectories* order = 0;
+ if(this->SharedDependencyMode == SharedDepModeLibDir &&
+ !this->LinkWithRuntimePath /* AddLibraryRuntimeInfo adds it */)
+ {
+ // Add the item to the linker search path.
+ order = this->OrderLinkerSearchPath;
+ }
+ else if(this->SharedDependencyMode == SharedDepModeDir)
+ {
+ // Add the item to the separate dependent library search path.
+ order = this->OrderDependentRPath;
+ }
+ if(order)
+ {
+ if(tgt)
+ {
+ std::string soName = tgt->GetSOName(this->Config);
+ const char* soname = soName.empty()? 0 : soName.c_str();
+ order->AddRuntimeLibrary(lib, soname);
+ }
+ else
+ {
+ order->AddRuntimeLibrary(lib);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmComputeLinkInformation::ComputeLinkTypeInfo()
+{
+ // Check whether archives may actually be shared libraries.
+ this->ArchivesMayBeShared =
+ this->CMakeInstance->GetPropertyAsBool(
+ "TARGET_ARCHIVES_MAY_BE_SHARED_LIBS");
+
+ // First assume we cannot do link type stuff.
+ this->LinkTypeEnabled = false;
+
+ // Lookup link type selection flags.
+ const char* static_link_type_flag = 0;
+ const char* shared_link_type_flag = 0;
+ 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;
+ default: break;
+ }
+ if(target_type_str)
+ {
+ std::string static_link_type_flag_var = "CMAKE_";
+ static_link_type_flag_var += target_type_str;
+ static_link_type_flag_var += "_LINK_STATIC_";
+ 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());
+
+ std::string shared_link_type_flag_var = "CMAKE_";
+ shared_link_type_flag_var += target_type_str;
+ shared_link_type_flag_var += "_LINK_DYNAMIC_";
+ 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());
+ }
+
+ // We can support link type switching only if all needed flags are
+ // known.
+ if(static_link_type_flag && *static_link_type_flag &&
+ shared_link_type_flag && *shared_link_type_flag)
+ {
+ this->LinkTypeEnabled = true;
+ this->StaticLinkTypeFlag = static_link_type_flag;
+ this->SharedLinkTypeFlag = shared_link_type_flag;
+ }
+
+ // Lookup the starting link type from the target (linked statically?).
+ const char* lss = this->Target->GetProperty("LINK_SEARCH_START_STATIC");
+ this->StartLinkType = cmSystemTools::IsOn(lss)? LinkStatic : LinkShared;
+ this->CurrentLinkType = this->StartLinkType;
+}
+
+//----------------------------------------------------------------------------
+void cmComputeLinkInformation::ComputeItemParserInfo()
+{
+ // Get possible library name prefixes.
+ cmMakefile* mf = this->Makefile;
+ this->AddLinkPrefix(mf->GetDefinition("CMAKE_STATIC_LIBRARY_PREFIX"));
+ this->AddLinkPrefix(mf->GetDefinition("CMAKE_SHARED_LIBRARY_PREFIX"));
+
+ // Import library names should be matched and treated as shared
+ // libraries for the purposes of linking.
+ this->AddLinkExtension(mf->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX"),
+ LinkShared);
+ this->AddLinkExtension(mf->GetDefinition("CMAKE_STATIC_LIBRARY_SUFFIX"),
+ LinkStatic);
+ this->AddLinkExtension(mf->GetDefinition("CMAKE_SHARED_LIBRARY_SUFFIX"),
+ LinkShared);
+ this->AddLinkExtension(mf->GetDefinition("CMAKE_LINK_LIBRARY_SUFFIX"),
+ LinkUnknown);
+ if(const char* linkSuffixes =
+ mf->GetDefinition("CMAKE_EXTRA_LINK_EXTENSIONS"))
+ {
+ std::vector<std::string> linkSuffixVec;
+ cmSystemTools::ExpandListArgument(linkSuffixes, linkSuffixVec);
+ for(std::vector<std::string>::iterator i = linkSuffixVec.begin();
+ i != linkSuffixVec.end(); ++i)
+ {
+ this->AddLinkExtension(i->c_str(), LinkUnknown);
+ }
+ }
+ if(const char* sharedSuffixes =
+ mf->GetDefinition("CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES"))
+ {
+ std::vector<std::string> sharedSuffixVec;
+ cmSystemTools::ExpandListArgument(sharedSuffixes, sharedSuffixVec);
+ for(std::vector<std::string>::iterator i = sharedSuffixVec.begin();
+ i != sharedSuffixVec.end(); ++i)
+ {
+ this->AddLinkExtension(i->c_str(), LinkShared);
+ }
+ }
+
+ // Compute a regex to match link extensions.
+ std::string libext = this->CreateExtensionRegex(this->LinkExtensions);
+
+ // Create regex to remove any library extension.
+ std::string reg("(.*)");
+ reg += libext;
+ this->OrderLinkerSearchPath->SetLinkExtensionInfo(this->LinkExtensions,
+ reg);
+
+ // Create a regex to match a library name. Match index 1 will be
+ // the prefix if it exists and empty otherwise. Match index 2 will
+ // be the library name. Match index 3 will be the library
+ // extension.
+ reg = "^(";
+ for(std::set<cmStdString>::iterator p = this->LinkPrefixes.begin();
+ p != this->LinkPrefixes.end(); ++p)
+ {
+ reg += *p;
+ reg += "|";
+ }
+ reg += ")";
+ reg += "([^/:]*)";
+
+ // Create a regex to match any library name.
+ std::string reg_any = reg;
+ reg_any += libext;
+#ifdef CM_COMPUTE_LINK_INFO_DEBUG
+ fprintf(stderr, "any regex [%s]\n", reg_any.c_str());
+#endif
+ this->ExtractAnyLibraryName.compile(reg_any.c_str());
+
+ // Create a regex to match static library names.
+ if(!this->StaticLinkExtensions.empty())
+ {
+ std::string reg_static = reg;
+ reg_static += this->CreateExtensionRegex(this->StaticLinkExtensions);
+#ifdef CM_COMPUTE_LINK_INFO_DEBUG
+ fprintf(stderr, "static regex [%s]\n", reg_static.c_str());
+#endif
+ this->ExtractStaticLibraryName.compile(reg_static.c_str());
+ }
+
+ // Create a regex to match shared library names.
+ if(!this->SharedLinkExtensions.empty())
+ {
+ std::string reg_shared = reg;
+ this->SharedRegexString =
+ this->CreateExtensionRegex(this->SharedLinkExtensions);
+ reg_shared += this->SharedRegexString;
+#ifdef CM_COMPUTE_LINK_INFO_DEBUG
+ fprintf(stderr, "shared regex [%s]\n", reg_shared.c_str());
+#endif
+ this->ExtractSharedLibraryName.compile(reg_shared.c_str());
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmComputeLinkInformation::AddLinkPrefix(const char* p)
+{
+ if(p && *p)
+ {
+ this->LinkPrefixes.insert(p);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmComputeLinkInformation::AddLinkExtension(const char* e, LinkType type)
+{
+ if(e && *e)
+ {
+ if(type == LinkStatic)
+ {
+ this->StaticLinkExtensions.push_back(e);
+ }
+ if(type == LinkShared)
+ {
+ this->SharedLinkExtensions.push_back(e);
+ }
+ this->LinkExtensions.push_back(e);
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmComputeLinkInformation
+::CreateExtensionRegex(std::vector<std::string> const& exts)
+{
+ // Build a list of extension choices.
+ std::string libext = "(";
+ const char* sep = "";
+ for(std::vector<std::string>::const_iterator i = exts.begin();
+ i != exts.end(); ++i)
+ {
+ // Separate this choice from the previous one.
+ libext += sep;
+ sep = "|";
+
+ // Store this extension choice with the "." escaped.
+ libext += "\\";
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ libext += this->NoCaseExpression(i->c_str());
+#else
+ libext += *i;
+#endif
+ }
+
+ // Finish the list.
+ libext += ")";
+
+ // Add an optional OpenBSD version component.
+ if(this->OpenBSD)
+ {
+ libext += "(\\.[0-9]+\\.[0-9]+)?";
+ }
+
+ libext += "$";
+ return libext;
+}
+
+//----------------------------------------------------------------------------
+std::string cmComputeLinkInformation::NoCaseExpression(const char* str)
+{
+ std::string ret;
+ const char* s = str;
+ while(*s)
+ {
+ if(*s == '.')
+ {
+ ret += *s;
+ }
+ else
+ {
+ ret += "[";
+ ret += static_cast<char>(tolower(*s));
+ ret += static_cast<char>(toupper(*s));
+ ret += "]";
+ }
+ s++;
+ }
+ return ret;
+}
+
+//-------------------------------------------------------------------
+void cmComputeLinkInformation::SetCurrentLinkType(LinkType lt)
+{
+ // If we are changing the current link type add the flag to tell the
+ // linker about it.
+ if(this->CurrentLinkType != lt)
+ {
+ this->CurrentLinkType = lt;
+
+ if(this->LinkTypeEnabled)
+ {
+ switch(this->CurrentLinkType)
+ {
+ case LinkStatic:
+ this->Items.push_back(Item(this->StaticLinkTypeFlag, false));
+ break;
+ case LinkShared:
+ this->Items.push_back(Item(this->SharedLinkTypeFlag, false));
+ break;
+ default:
+ break;
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmComputeLinkInformation::AddTargetItem(std::string const& item,
+ cmTarget* 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
+ // shared. This is because dynamic-mode linking can handle both
+ // 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)
+ {
+ this->SetCurrentLinkType(LinkShared);
+ }
+
+ // Keep track of shared library targets linked.
+ if(target->GetType() == cmTarget::SHARED_LIBRARY)
+ {
+ this->SharedLibrariesLinked.insert(target);
+ }
+
+ // Handle case of an imported shared library with no soname.
+ if(this->NoSONameUsesPath &&
+ target->IsImportedSharedLibWithoutSOName(this->Config))
+ {
+ this->AddSharedLibNoSOName(item);
+ return;
+ }
+
+ // If this platform wants a flag before the full path, add it.
+ if(!this->LibLinkFileFlag.empty())
+ {
+ this->Items.push_back(Item(this->LibLinkFileFlag, false));
+ }
+
+ // For compatibility with CMake 2.4 include the item's directory in
+ // the linker search path.
+ if(this->OldLinkDirMode && !target->IsFrameworkOnApple() &&
+ this->OldLinkDirMask.find(cmSystemTools::GetFilenamePath(item)) ==
+ this->OldLinkDirMask.end())
+ {
+ this->OldLinkDirItems.push_back(item);
+ }
+
+ // Now add the full path to the library.
+ this->Items.push_back(Item(item, true, target));
+}
+
+//----------------------------------------------------------------------------
+void cmComputeLinkInformation::AddFullItem(std::string const& item)
+{
+ // Check for the implicit link directory special case.
+ if(this->CheckImplicitDirItem(item))
+ {
+ return;
+ }
+
+ // Check for case of shared library with no builtin soname.
+ if(this->NoSONameUsesPath && this->CheckSharedLibNoSOName(item))
+ {
+ return;
+ }
+
+ // Full path libraries should specify a valid library file name.
+ // See documentation of CMP0008.
+ if(this->Target->GetPolicyStatusCMP0008() != cmPolicies::NEW &&
+ (strstr(this->GlobalGenerator->GetName(), "Visual Studio") ||
+ strstr(this->GlobalGenerator->GetName(), "Xcode")))
+ {
+ std::string file = cmSystemTools::GetFilenameName(item);
+ if(!this->ExtractAnyLibraryName.find(file.c_str()))
+ {
+ this->HandleBadFullItem(item, file);
+ return;
+ }
+ }
+
+ // This is called to handle a link item that is a full path.
+ // If the target is not a static library make sure the link type is
+ // shared. This is because dynamic-mode linking can handle both
+ // 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(this->LinkTypeEnabled)
+ {
+ std::string name = cmSystemTools::GetFilenameName(item);
+ if(this->ExtractSharedLibraryName.find(name))
+ {
+ this->SetCurrentLinkType(LinkShared);
+ }
+ else if(!this->ExtractStaticLibraryName.find(item))
+ {
+ // We cannot determine the type. Assume it is the target's
+ // default type.
+ this->SetCurrentLinkType(this->StartLinkType);
+ }
+ }
+
+ // For compatibility with CMake 2.4 include the item's directory in
+ // the linker search path.
+ if(this->OldLinkDirMode &&
+ this->OldLinkDirMask.find(cmSystemTools::GetFilenamePath(item)) ==
+ this->OldLinkDirMask.end())
+ {
+ this->OldLinkDirItems.push_back(item);
+ }
+
+ // If this platform wants a flag before the full path, add it.
+ if(!this->LibLinkFileFlag.empty())
+ {
+ this->Items.push_back(Item(this->LibLinkFileFlag, false));
+ }
+
+ // Now add the full path to the library.
+ this->Items.push_back(Item(item, true));
+}
+
+//----------------------------------------------------------------------------
+bool cmComputeLinkInformation::CheckImplicitDirItem(std::string const& item)
+{
+ // We only switch to a pathless item if the link type may be
+ // enforced. Fortunately only platforms that support link types
+ // seem to have magic per-architecture implicit link directories.
+ if(!this->LinkTypeEnabled)
+ {
+ return false;
+ }
+
+ // Check if this item is in an implicit link directory.
+ std::string dir = cmSystemTools::GetFilenamePath(item);
+ if(this->ImplicitLinkDirs.find(dir) == this->ImplicitLinkDirs.end())
+ {
+ // Only libraries in implicit link directories are converted to
+ // pathless items.
+ return false;
+ }
+
+ // Only apply the policy below if the library file is one that can
+ // be found by the linker.
+ std::string file = cmSystemTools::GetFilenameName(item);
+ if(!this->ExtractAnyLibraryName.find(file))
+ {
+ 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
+ // directory then just report the file name without the directory
+ // portion. This will allow the system linker to locate the proper
+ // library for the architecture at link time.
+ this->AddUserItem(file, false);
+
+ // Make sure the link directory ordering will find the library.
+ this->OrderLinkerSearchPath->AddLinkLibrary(item);
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+void cmComputeLinkInformation::AddUserItem(std::string const& item,
+ bool pathNotKnown)
+{
+ // This is called to handle a link item that does not match a CMake
+ // target and is not a full path. We check here if it looks like a
+ // library file name to automatically request the proper link type
+ // from the linker. For example:
+ //
+ // foo ==> -lfoo
+ // libfoo.a ==> -Wl,-Bstatic -lfoo
+
+ // Pass flags through untouched.
+ if(item[0] == '-' || item[0] == '$' || item[0] == '`')
+ {
+ // if this is a -l option then we might need to warn about
+ // CMP0003 so put it in OldUserFlagItems, if it is not a -l
+ // or -Wl,-l (-framework -pthread), then allow it without a
+ // CMP0003 as -L will not affect those other linker flags
+ if(item.find("-l") == 0 || item.find("-Wl,-l") == 0)
+ {
+ // This is a linker option provided by the user.
+ this->OldUserFlagItems.push_back(item);
+ }
+
+ // Restore the target link type since this item does not specify
+ // one.
+ this->SetCurrentLinkType(this->StartLinkType);
+
+ // Use the item verbatim.
+ this->Items.push_back(Item(item, false));
+ return;
+ }
+
+ // Parse out the prefix, base, and suffix components of the
+ // library name. If the name matches that of a shared or static
+ // library then set the link type accordingly.
+ //
+ // Search for shared library names first because some platforms
+ // have shared libraries with names that match the static library
+ // pattern. For example cygwin and msys use the convention
+ // libfoo.dll.a for import libraries and libfoo.a for static
+ // libraries. On AIX a library with the name libfoo.a can be
+ // shared!
+ std::string lib;
+ if(this->ExtractSharedLibraryName.find(item))
+ {
+ // This matches a shared library file name.
+#ifdef CM_COMPUTE_LINK_INFO_DEBUG
+ fprintf(stderr, "shared regex matched [%s] [%s] [%s]\n",
+ this->ExtractSharedLibraryName.match(1).c_str(),
+ this->ExtractSharedLibraryName.match(2).c_str(),
+ this->ExtractSharedLibraryName.match(3).c_str());
+#endif
+ // Set the link type to shared.
+ this->SetCurrentLinkType(LinkShared);
+
+ // Use just the library name so the linker will search.
+ lib = this->ExtractSharedLibraryName.match(2);
+ }
+ else if(this->ExtractStaticLibraryName.find(item))
+ {
+ // This matches a static library file name.
+#ifdef CM_COMPUTE_LINK_INFO_DEBUG
+ fprintf(stderr, "static regex matched [%s] [%s] [%s]\n",
+ this->ExtractStaticLibraryName.match(1).c_str(),
+ this->ExtractStaticLibraryName.match(2).c_str(),
+ this->ExtractStaticLibraryName.match(3).c_str());
+#endif
+ // Set the link type to static.
+ this->SetCurrentLinkType(LinkStatic);
+
+ // Use just the library name so the linker will search.
+ lib = this->ExtractStaticLibraryName.match(2);
+ }
+ else if(this->ExtractAnyLibraryName.find(item))
+ {
+ // This matches a library file name.
+#ifdef CM_COMPUTE_LINK_INFO_DEBUG
+ fprintf(stderr, "any regex matched [%s] [%s] [%s]\n",
+ this->ExtractAnyLibraryName.match(1).c_str(),
+ this->ExtractAnyLibraryName.match(2).c_str(),
+ this->ExtractAnyLibraryName.match(3).c_str());
+#endif
+ // Restore the target link type since this item does not specify
+ // one.
+ this->SetCurrentLinkType(this->StartLinkType);
+
+ // Use just the library name so the linker will search.
+ lib = this->ExtractAnyLibraryName.match(2);
+ }
+ else
+ {
+ // This is a name specified by the user.
+ if(pathNotKnown)
+ {
+ this->OldUserFlagItems.push_back(item);
+ }
+
+ // We must ask the linker to search for a library with this name.
+ // Restore the target link type since this item does not specify
+ // one.
+ this->SetCurrentLinkType(this->StartLinkType);
+ lib = item;
+ }
+
+ // Create an option to ask the linker to search for the library.
+ std::string out = this->LibLinkFlag;
+ out += lib;
+ out += this->LibLinkSuffix;
+ this->Items.push_back(Item(out, false));
+
+ // Here we could try to find the library the linker will find and
+ // add a runtime information entry for it. It would probably not be
+ // reliable and we want to encourage use of full paths for library
+ // specification.
+}
+
+//----------------------------------------------------------------------------
+void cmComputeLinkInformation::AddFrameworkItem(std::string const& item)
+{
+ // Try to separate the framework name and path.
+ if(!this->SplitFramework.find(item.c_str()))
+ {
+ cmOStringStream e;
+ e << "Could not parse framework path \"" << item << "\" "
+ << "linked by target " << this->Target->GetName() << ".";
+ cmSystemTools::Error(e.str().c_str());
+ return;
+ }
+
+ // Add the directory portion to the framework search path.
+ this->AddFrameworkPath(this->SplitFramework.match(1));
+
+ // Add the item using the -framework option.
+ this->Items.push_back(Item("-framework", false));
+ std::string fw = this->SplitFramework.match(2);
+ fw = this->LocalGenerator->EscapeForShell(fw.c_str());
+ this->Items.push_back(Item(fw, false));
+}
+
+//----------------------------------------------------------------------------
+void cmComputeLinkInformation::AddDirectoryItem(std::string const& item)
+{
+ if(this->Makefile->IsOn("APPLE")
+ && cmSystemTools::IsPathToFramework(item.c_str()))
+ {
+ this->AddFrameworkItem(item);
+ }
+ else
+ {
+ this->DropDirectoryItem(item);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmComputeLinkInformation::DropDirectoryItem(std::string const& item)
+{
+ // A full path to a directory was found as a link item. Warn the
+ // user.
+ cmOStringStream e;
+ e << "WARNING: Target \"" << this->Target->GetName()
+ << "\" requests linking to directory \"" << item << "\". "
+ << "Targets may link only to libraries. "
+ << "CMake is dropping the item.";
+ cmSystemTools::Message(e.str().c_str());
+}
+
+//----------------------------------------------------------------------------
+void cmComputeLinkInformation::ComputeFrameworkInfo()
+{
+ // Avoid adding system framework paths. See "man ld" on OS X.
+ this->FrameworkPathsEmmitted.insert("/Library/Frameworks");
+ this->FrameworkPathsEmmitted.insert("/Network/Library/Frameworks");
+ this->FrameworkPathsEmmitted.insert("/System/Library/Frameworks");
+
+ // Regular expression to extract a framework path and name.
+ this->SplitFramework.compile("(.*)/(.*)\\.framework$");
+}
+
+//----------------------------------------------------------------------------
+void cmComputeLinkInformation::AddFrameworkPath(std::string const& p)
+{
+ if(this->FrameworkPathsEmmitted.insert(p).second)
+ {
+ this->FrameworkPaths.push_back(p);
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmComputeLinkInformation::CheckSharedLibNoSOName(std::string const& item)
+{
+ // This platform will use the path to a library as its soname if the
+ // library is given via path and was not built with an soname. If
+ // this is a shared library that might be the case.
+ std::string file = cmSystemTools::GetFilenameName(item);
+ if(this->ExtractSharedLibraryName.find(file))
+ {
+ // If we can guess the soname fairly reliably then assume the
+ // library has one. Otherwise assume the library has no builtin
+ // soname.
+ std::string soname;
+ if(!cmSystemTools::GuessLibrarySOName(item, soname))
+ {
+ this->AddSharedLibNoSOName(item);
+ return true;
+ }
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+void cmComputeLinkInformation::AddSharedLibNoSOName(std::string const& item)
+{
+ // We have a full path to a shared library with no soname. We need
+ // to ask the linker to locate the item because otherwise the path
+ // we give to it will be embedded in the target linked. Then at
+ // runtime the dynamic linker will search for the library using the
+ // path instead of just the name.
+ std::string file = cmSystemTools::GetFilenameName(item);
+ this->AddUserItem(file, false);
+
+ // Make sure the link directory ordering will find the library.
+ this->OrderLinkerSearchPath->AddLinkLibrary(item);
+}
+
+//----------------------------------------------------------------------------
+void cmComputeLinkInformation::HandleBadFullItem(std::string const& item,
+ std::string const& file)
+{
+ // Do not depend on things that do not exist.
+ std::vector<std::string>::iterator i =
+ std::find(this->Depends.begin(), this->Depends.end(), item);
+ if(i != this->Depends.end())
+ {
+ this->Depends.erase(i);
+ }
+
+ // Tell the linker to search for the item and provide the proper
+ // path for it. Do not contribute to any CMP0003 warning (do not
+ // put in OldLinkDirItems or OldUserFlagItems).
+ this->AddUserItem(file, false);
+ this->OrderLinkerSearchPath->AddLinkLibrary(item);
+
+ // Produce any needed message.
+ switch(this->Target->GetPolicyStatusCMP0008())
+ {
+ case cmPolicies::WARN:
+ {
+ // Print the warning at most once for this item.
+ std::string wid = "CMP0008-WARNING-GIVEN-";
+ wid += item;
+ if(!this->CMakeInstance->GetPropertyAsBool(wid.c_str()))
+ {
+ this->CMakeInstance->SetProperty(wid.c_str(), "1");
+ cmOStringStream w;
+ w << (this->Makefile->GetPolicies()
+ ->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());
+ }
+ }
+ case cmPolicies::OLD:
+ // OLD behavior does not warn.
+ break;
+ case cmPolicies::NEW:
+ // NEW behavior will not get here.
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ {
+ cmOStringStream e;
+ e << (this->Makefile->GetPolicies()->
+ 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.";
+ this->CMakeInstance->IssueMessage(cmake::FATAL_ERROR, e.str(),
+ this->Target->GetBacktrace());
+ }
+ break;
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmComputeLinkInformation::FinishLinkerSearchDirectories()
+{
+ // Support broken projects if necessary.
+ if(this->OldLinkDirItems.empty() || this->OldUserFlagItems.empty() ||
+ !this->OldLinkDirMode)
+ {
+ return true;
+ }
+
+ // Enforce policy constraints.
+ switch(this->Target->GetPolicyStatusCMP0003())
+ {
+ case cmPolicies::WARN:
+ if(!this->CMakeInstance->GetPropertyAsBool("CMP0003-WARNING-GIVEN"))
+ {
+ this->CMakeInstance->SetProperty("CMP0003-WARNING-GIVEN", "1");
+ cmOStringStream w;
+ this->PrintLinkPolicyDiagnosis(w);
+ this->CMakeInstance->IssueMessage(cmake::AUTHOR_WARNING, w.str(),
+ this->Target->GetBacktrace());
+ }
+ case cmPolicies::OLD:
+ // OLD behavior is to add the paths containing libraries with
+ // known full paths as link directories.
+ break;
+ case cmPolicies::NEW:
+ // Should never happen due to assignment of OldLinkDirMode
+ return true;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ {
+ cmOStringStream e;
+ e << (this->Makefile->GetPolicies()->
+ GetRequiredPolicyError(cmPolicies::CMP0003)) << "\n";
+ this->PrintLinkPolicyDiagnosis(e);
+ this->CMakeInstance->IssueMessage(cmake::FATAL_ERROR, e.str(),
+ this->Target->GetBacktrace());
+ return false;
+ }
+ }
+
+ // Add the link directories for full path items.
+ for(std::vector<std::string>::const_iterator
+ i = this->OldLinkDirItems.begin();
+ i != this->OldLinkDirItems.end(); ++i)
+ {
+ this->OrderLinkerSearchPath->AddLinkLibrary(*i);
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+void cmComputeLinkInformation::PrintLinkPolicyDiagnosis(std::ostream& os)
+{
+ // Tell the user what to do.
+ os << "Policy CMP0003 should be set before this line. "
+ << "Add code such as\n"
+ << " if(COMMAND cmake_policy)\n"
+ << " cmake_policy(SET CMP0003 NEW)\n"
+ << " endif(COMMAND cmake_policy)\n"
+ << "as early as possible but after the most recent call to "
+ << "cmake_minimum_required or cmake_policy(VERSION). ";
+
+ // List the items that might need the old-style paths.
+ os << "This warning appears because target \""
+ << this->Target->GetName() << "\" "
+ << "links to some libraries for which the linker must search:\n";
+ {
+ // Format the list of unknown items to be as short as possible while
+ // still fitting in the allowed width (a true solution would be the
+ // bin packing problem if we were allowed to change the order).
+ std::string::size_type max_size = 76;
+ std::string line;
+ const char* sep = " ";
+ for(std::vector<std::string>::const_iterator
+ i = this->OldUserFlagItems.begin();
+ i != this->OldUserFlagItems.end(); ++i)
+ {
+ // If the addition of another item will exceed the limit then
+ // output the current line and reset it. Note that the separator
+ // is either " " or ", " which is always 2 characters.
+ if(!line.empty() && (line.size() + i->size() + 2) > max_size)
+ {
+ os << line << "\n";
+ sep = " ";
+ line = "";
+ }
+ line += sep;
+ line += *i;
+ // Convert to the other separator.
+ sep = ", ";
+ }
+ if(!line.empty())
+ {
+ os << line << "\n";
+ }
+ }
+
+ // List the paths old behavior is adding.
+ os << "and other libraries with known full path:\n";
+ std::set<cmStdString> emitted;
+ for(std::vector<std::string>::const_iterator
+ i = this->OldLinkDirItems.begin();
+ i != this->OldLinkDirItems.end(); ++i)
+ {
+ if(emitted.insert(cmSystemTools::GetFilenamePath(*i)).second)
+ {
+ os << " " << *i << "\n";
+ }
+ }
+
+ // Explain.
+ os << "CMake is adding directories in the second list to the linker "
+ << "search path in case they are needed to find libraries from the "
+ << "first list (for backwards compatibility with CMake 2.4). "
+ << "Set policy CMP0003 to OLD or NEW to enable or disable this "
+ << "behavior explicitly. "
+ << "Run \"cmake --help-policy CMP0003\" for more information.";
+}
+
+//----------------------------------------------------------------------------
+void cmComputeLinkInformation::LoadImplicitLinkInfo()
+{
+ std::vector<std::string> implicitDirVec;
+
+ // Get platform-wide implicit directories.
+ if(const char* implicitLinks =
+ (this->Makefile->GetDefinition
+ ("CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES")))
+ {
+ cmSystemTools::ExpandListArgument(implicitLinks, implicitDirVec);
+ }
+
+ // Append library architecture to all implicit platform directories
+ // and add them to the set
+ if(const char* libraryArch =
+ this->Makefile->GetDefinition("CMAKE_LIBRARY_ARCHITECTURE"))
+ {
+ for (std::vector<std::string>::const_iterator i = implicitDirVec.begin();
+ i != implicitDirVec.end(); ++i)
+ {
+ this->ImplicitLinkDirs.insert(*i + "/" + libraryArch);
+ }
+ }
+
+ // Get language-specific implicit directories.
+ std::string implicitDirVar = "CMAKE_";
+ implicitDirVar += this->LinkLanguage;
+ implicitDirVar += "_IMPLICIT_LINK_DIRECTORIES";
+ if(const char* implicitDirs =
+ this->Makefile->GetDefinition(implicitDirVar.c_str()))
+ {
+ 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);
+ }
+
+ // Get language-specific implicit libraries.
+ std::vector<std::string> implicitLibVec;
+ std::string implicitLibVar = "CMAKE_";
+ implicitLibVar += this->LinkLanguage;
+ implicitLibVar += "_IMPLICIT_LINK_LIBRARIES";
+ if(const char* implicitLibs =
+ this->Makefile->GetDefinition(implicitLibVar.c_str()))
+ {
+ cmSystemTools::ExpandListArgument(implicitLibs, implicitLibVec);
+ }
+
+ // Store implicit link libraries.
+ for(std::vector<std::string>::const_iterator i = implicitLibVec.begin();
+ i != implicitLibVec.end(); ++i)
+ {
+ // Items starting in '-' but not '-l' are flags, not libraries,
+ // and should not be filtered by this implicit list.
+ std::string const& item = *i;
+ if(item[0] != '-' || item[1] == 'l')
+ {
+ this->ImplicitLinkLibs.insert(item);
+ }
+ }
+
+ // Get platform specific rpath link directories
+ if(const char *rpathDirs =
+ (this->Makefile->GetDefinition
+ ("CMAKE_PLATFORM_RUNTIME_PATH")))
+ {
+ cmSystemTools::ExpandListArgument(rpathDirs, this->RuntimeLinkDirs);
+ }
+}
+
+//----------------------------------------------------------------------------
+std::vector<std::string> const&
+cmComputeLinkInformation::GetRuntimeSearchPath()
+{
+ return this->OrderRuntimeSearchPath->GetOrderedDirectories();
+}
+
+//----------------------------------------------------------------------------
+void
+cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath,
+ cmTarget* target)
+{
+ // Libraries with unknown type must be handled using just the file
+ // on disk.
+ if(target->GetType() == cmTarget::UNKNOWN_LIBRARY)
+ {
+ this->AddLibraryRuntimeInfo(fullPath);
+ return;
+ }
+
+ // Skip targets that are not shared libraries (modules cannot be linked).
+ if(target->GetType() != cmTarget::SHARED_LIBRARY)
+ {
+ return;
+ }
+
+ // Try to get the soname of the library. Only files with this name
+ // could possibly conflict.
+ std::string soName = target->GetSOName(this->Config);
+ const char* soname = soName.empty()? 0 : soName.c_str();
+
+ // Include this library in the runtime path ordering.
+ this->OrderRuntimeSearchPath->AddRuntimeLibrary(fullPath, soname);
+ if(this->LinkWithRuntimePath)
+ {
+ this->OrderLinkerSearchPath->AddRuntimeLibrary(fullPath, soname);
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath)
+{
+ // Get the name of the library from the file name.
+ std::string file = cmSystemTools::GetFilenameName(fullPath);
+ if(!this->ExtractSharedLibraryName.find(file.c_str()))
+ {
+ // On some platforms (AIX) a shared library may look static.
+ if(this->ArchivesMayBeShared)
+ {
+ if(!this->ExtractStaticLibraryName.find(file.c_str()))
+ {
+ // This is not the name of a shared library or archive.
+ return;
+ }
+ }
+ else
+ {
+ // This is not the name of a shared library.
+ return;
+ }
+ }
+
+ // Include this library in the runtime path ordering.
+ this->OrderRuntimeSearchPath->AddRuntimeLibrary(fullPath);
+ if(this->LinkWithRuntimePath)
+ {
+ this->OrderLinkerSearchPath->AddRuntimeLibrary(fullPath);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
+ bool for_install)
+{
+ // Select whether to generate runtime search directories.
+ bool outputRuntime =
+ !this->Makefile->IsOn("CMAKE_SKIP_RPATH") && !this->RuntimeFlag.empty();
+
+ // Select whether to generate an rpath for the install tree or the
+ // build tree.
+ bool linking_for_install =
+ (for_install ||
+ this->Target->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"));
+ bool use_install_rpath =
+ (outputRuntime && this->Target->HaveInstallTreeRPATH() &&
+ linking_for_install);
+ bool use_build_rpath =
+ (outputRuntime && this->Target->HaveBuildTreeRPATH() &&
+ !linking_for_install);
+ bool use_link_rpath =
+ outputRuntime && linking_for_install &&
+ !this->Makefile->IsOn("CMAKE_SKIP_INSTALL_RPATH") &&
+ this->Target->GetPropertyAsBool("INSTALL_RPATH_USE_LINK_PATH");
+
+ // Construct the RPATH.
+ if(use_install_rpath)
+ {
+ const char* install_rpath = this->Target->GetProperty("INSTALL_RPATH");
+ cmSystemTools::ExpandListArgument(install_rpath, runtimeDirs);
+ }
+ if(use_build_rpath || use_link_rpath)
+ {
+ std::vector<std::string> const& rdirs = this->GetRuntimeSearchPath();
+ for(std::vector<std::string>::const_iterator ri = rdirs.begin();
+ ri != rdirs.end(); ++ri)
+ {
+ // Put this directory in the rpath if using build-tree rpath
+ // support or if using the link path as an rpath.
+ if(use_build_rpath)
+ {
+ runtimeDirs.push_back(*ri);
+ }
+ 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))
+ {
+ runtimeDirs.push_back(*ri);
+ }
+ }
+ }
+ }
+
+ // Add runtime paths required by the platform to always be
+ // present. This is done even when skipping rpath support.
+ cmSystemTools::ExpandListArgument(this->RuntimeAlways.c_str(), runtimeDirs);
+}
+
+//----------------------------------------------------------------------------
+std::string cmComputeLinkInformation::GetRPathString(bool for_install)
+{
+ // Get the directories to use.
+ std::vector<std::string> runtimeDirs;
+ 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;
+ }
+
+ // If the rpath will be replaced at install time, prepare space.
+ if(!for_install && this->RuntimeUseChrpath)
+ {
+ if(!rpath.empty())
+ {
+ // Add one trailing separator so the linker does not re-use the
+ // rpath .dynstr entry for a symbol name that happens to match
+ // the end of the rpath string.
+ rpath += this->GetRuntimeSep();
+ }
+
+ // Make sure it is long enough to hold the replacement value.
+ std::string::size_type minLength = this->GetChrpathString().length();
+ while(rpath.length() < minLength)
+ {
+ rpath += this->GetRuntimeSep();
+ }
+ }
+
+ return rpath;
+}
+
+//----------------------------------------------------------------------------
+std::string cmComputeLinkInformation::GetChrpathString()
+{
+ if(!this->RuntimeUseChrpath)
+ {
+ return "";
+ }
+
+ return this->GetRPathString(true);
+}
diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h
new file mode 100644
index 000000000..f60f8d325
--- /dev/null
+++ b/Source/cmComputeLinkInformation.h
@@ -0,0 +1,185 @@
+/*============================================================================
+ 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 cmComputeLinkInformation_h
+#define cmComputeLinkInformation_h
+
+#include "cmStandardIncludes.h"
+
+#include <cmsys/RegularExpression.hxx>
+
+class cmake;
+class cmGlobalGenerator;
+class cmLocalGenerator;
+class cmMakefile;
+class cmTarget;
+class cmOrderDirectories;
+
+/** \class cmComputeLinkInformation
+ * \brief Compute link information for a target in one configuration.
+ */
+class cmComputeLinkInformation
+{
+public:
+ cmComputeLinkInformation(cmTarget* target, const char* config);
+ ~cmComputeLinkInformation();
+ bool Compute();
+
+ struct Item
+ {
+ 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):
+ Value(v), IsPath(p), Target(target) {}
+ std::string Value;
+ bool IsPath;
+ cmTarget* 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::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::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);
+
+ // Output information.
+ ItemVector Items;
+ std::vector<std::string> Directories;
+ std::vector<std::string> Depends;
+ std::vector<std::string> FrameworkPaths;
+ std::vector<std::string> RuntimeSearchPath;
+ std::set<cmTarget*> SharedLibrariesLinked;
+
+ // Context information.
+ cmTarget* Target;
+ cmMakefile* Makefile;
+ cmLocalGenerator* LocalGenerator;
+ cmGlobalGenerator* GlobalGenerator;
+ cmake* CMakeInstance;
+
+ // Configuration information.
+ const char* Config;
+ const char* LinkLanguage;
+
+ // Modes for dealing with dependent shared libraries.
+ enum SharedDepMode
+ {
+ SharedDepModeNone, // Drop
+ SharedDepModeDir, // List dir in -rpath-link flag
+ SharedDepModeLibDir, // List dir in linker search path
+ SharedDepModeLink // List file on link line
+ };
+
+ // System info.
+ bool UseImportLibrary;
+ const char* LoaderFlag;
+ std::string LibLinkFlag;
+ std::string LibLinkFileFlag;
+ std::string LibLinkSuffix;
+ std::string RuntimeFlag;
+ std::string RuntimeSep;
+ std::string RuntimeAlways;
+ bool RuntimeUseChrpath;
+ bool NoSONameUsesPath;
+ bool LinkWithRuntimePath;
+ std::string RPathLinkFlag;
+ SharedDepMode SharedDependencyMode;
+
+ // 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;
+ 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);
+ std::string NoCaseExpression(const char* str);
+
+ // Handling of link items.
+ void AddTargetItem(std::string const& item, cmTarget* target);
+ void AddFullItem(std::string const& item);
+ bool CheckImplicitDirItem(std::string const& item);
+ void AddUserItem(std::string const& item, bool pathNotKnown);
+ void AddDirectoryItem(std::string const& item);
+ void AddFrameworkItem(std::string const& item);
+ void DropDirectoryItem(std::string const& item);
+ bool CheckSharedLibNoSOName(std::string const& item);
+ void AddSharedLibNoSOName(std::string const& item);
+ void HandleBadFullItem(std::string const& item, std::string const& file);
+
+ // Framework info.
+ void ComputeFrameworkInfo();
+ void AddFrameworkPath(std::string const& p);
+ std::set<cmStdString> FrameworkPathsEmmitted;
+ cmsys::RegularExpression SplitFramework;
+
+ // Linker search path computation.
+ cmOrderDirectories* OrderLinkerSearchPath;
+ bool FinishLinkerSearchDirectories();
+ void PrintLinkPolicyDiagnosis(std::ostream&);
+
+ // Implicit link libraries and directories for linker language.
+ void LoadImplicitLinkInfo();
+ void AddImplicitLinkInfo();
+ void AddImplicitLinkInfo(std::string const& lang);
+ std::set<cmStdString> ImplicitLinkDirs;
+ std::set<cmStdString> ImplicitLinkLibs;
+
+ // Additional paths configured by the runtime linker
+ std::vector<std::string> RuntimeLinkDirs;
+
+ // Linker search path compatibility mode.
+ std::set<cmStdString> OldLinkDirMask;
+ std::vector<std::string> OldLinkDirItems;
+ std::vector<std::string> OldUserFlagItems;
+ bool OldLinkDirMode;
+
+ // Runtime path computation.
+ cmOrderDirectories* OrderRuntimeSearchPath;
+ void AddLibraryRuntimeInfo(std::string const& fullPath, cmTarget* target);
+ void AddLibraryRuntimeInfo(std::string const& fullPath);
+
+ // Dependent library path computation.
+ cmOrderDirectories* OrderDependentRPath;
+};
+
+#endif
diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx
new file mode 100644
index 000000000..ab77c6bc9
--- /dev/null
+++ b/Source/cmComputeTargetDepends.cxx
@@ -0,0 +1,537 @@
+/*============================================================================
+ 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 "cmComputeTargetDepends.h"
+
+#include "cmComputeComponentGraph.h"
+#include "cmGlobalGenerator.h"
+#include "cmLocalGenerator.h"
+#include "cmMakefile.h"
+#include "cmSystemTools.h"
+#include "cmTarget.h"
+#include "cmake.h"
+
+#include <algorithm>
+
+#include <assert.h>
+
+/*
+
+This class is meant to analyze inter-target dependencies globally
+during the generation step. The goal is to produce a set of direct
+dependencies for each target such that no cycles are left and the
+build order is safe.
+
+For most target types cyclic dependencies are not allowed. However
+STATIC libraries may depend on each other in a cyclic fashion. In
+general the directed dependency graph forms a directed-acyclic-graph
+of strongly connected components. All strongly connected components
+should consist of only STATIC_LIBRARY targets.
+
+In order to safely break dependency cycles we must preserve all other
+dependencies passing through the corresponding strongly connected component.
+The approach taken by this class is as follows:
+
+ - Collect all targets and form the original dependency graph
+ - Run Tarjan's algorithm to extract the strongly connected components
+ (error if any member of a non-trivial component is not STATIC)
+ - The original dependencies imply a DAG on the components.
+ Use the implied DAG to construct a final safe set of dependencies.
+
+The final dependency set is constructed as follows:
+
+ - For each connected component targets are placed in an arbitrary
+ order. Each target depends on the target following it in the order.
+ The first target is designated the head and the last target the tail.
+ (most components will be just 1 target anyway)
+
+ - Original dependencies between targets in different components are
+ converted to connect the depender's component tail to the
+ dependee's component head.
+
+In most cases this will reproduce the original dependencies. However
+when there are cycles of static libraries they will be broken in a
+safe manner.
+
+For example, consider targets A0, A1, A2, B0, B1, B2, and C with these
+dependencies:
+
+ A0 -> A1 -> A2 -> A0 , B0 -> B1 -> B2 -> B0 -> A0 , C -> B0
+
+Components may be identified as
+
+ Component 0: A0, A1, A2
+ Component 1: B0, B1, B2
+ Component 2: C
+
+Intra-component dependencies are:
+
+ 0: A0 -> A1 -> A2 , head=A0, tail=A2
+ 1: B0 -> B1 -> B2 , head=B0, tail=B2
+ 2: head=C, tail=C
+
+The inter-component dependencies are converted as:
+
+ B0 -> A0 is component 1->0 and becomes B2 -> A0
+ C -> B0 is component 2->1 and becomes C -> B0
+
+This leads to the final target dependencies:
+
+ C -> B0 -> B1 -> B2 -> A0 -> A1 -> A2
+
+These produce a safe build order since C depends directly or
+transitively on all the static libraries it links.
+
+*/
+
+//----------------------------------------------------------------------------
+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");
+}
+
+//----------------------------------------------------------------------------
+cmComputeTargetDepends::~cmComputeTargetDepends()
+{
+}
+
+//----------------------------------------------------------------------------
+bool cmComputeTargetDepends::Compute()
+{
+ // Build the original graph.
+ this->CollectTargets();
+ this->CollectDepends();
+ if(this->DebugMode)
+ {
+ this->DisplayGraph(this->InitialGraph, "initial");
+ }
+
+ // Identify components.
+ cmComputeComponentGraph ccg(this->InitialGraph);
+ if(this->DebugMode)
+ {
+ this->DisplayComponents(ccg);
+ }
+ if(!this->CheckComponents(ccg))
+ {
+ return false;
+ }
+
+ // Compute the final dependency graph.
+ if(!this->ComputeFinalDepends(ccg))
+ {
+ return false;
+ }
+ if(this->DebugMode)
+ {
+ this->DisplayGraph(this->FinalGraph, "final");
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+void
+cmComputeTargetDepends::GetTargetDirectDepends(cmTarget* 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);
+ assert(tii != this->TargetIndex.end());
+ int i = tii->second;
+
+ // Get its final dependencies.
+ EdgeList const& nl = this->FinalGraph[i];
+ for(EdgeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni)
+ {
+ cmTarget* dep = this->Targets[*ni];
+ cmTargetDependSet::iterator di = deps.insert(dep).first;
+ di->SetType(ni->IsStrong());
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmComputeTargetDepends::CollectTargets()
+{
+ // Collect all targets from all generators.
+ std::vector<cmLocalGenerator*> const& lgens =
+ 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)
+ {
+ cmTarget* target = &ti->second;
+ int index = static_cast<int>(this->Targets.size());
+ this->TargetIndex[target] = index;
+ this->Targets.push_back(target);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmComputeTargetDepends::CollectDepends()
+{
+ // Allocate the dependency graph adjacency lists.
+ this->InitialGraph.resize(this->Targets.size());
+
+ // Compute each dependency list.
+ for(unsigned int i=0; i < this->Targets.size(); ++i)
+ {
+ this->CollectTargetDepends(i);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
+{
+ // Get the depender.
+ cmTarget* depender = this->Targets[depender_index];
+
+ // Loop over all targets linked directly.
+ {
+ cmTarget::LinkLibraryVectorType const& tlibs =
+ depender->GetOriginalLinkLibraries();
+ std::set<cmStdString> emitted;
+ // A target should not depend on itself.
+ emitted.insert(depender->GetName());
+ for(cmTarget::LinkLibraryVectorType::const_iterator lib = tlibs.begin();
+ lib != tlibs.end(); ++lib)
+ {
+ // Don't emit the same library twice for this target.
+ if(emitted.insert(lib->first).second)
+ {
+ this->AddTargetDepend(depender_index, lib->first.c_str(), true);
+ }
+ }
+ }
+
+ // Loop over all utility dependencies.
+ {
+ std::set<cmStdString> const& tutils = depender->GetUtilities();
+ std::set<cmStdString> emitted;
+ // A target should not depend on itself.
+ emitted.insert(depender->GetName());
+ for(std::set<cmStdString>::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);
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmComputeTargetDepends::AddTargetDepend(int depender_index,
+ const char* dependee_name,
+ bool linking)
+{
+ // Get the depender.
+ cmTarget* depender = this->Targets[depender_index];
+
+ // Check the target's makefile first.
+ cmTarget* dependee =
+ depender->GetMakefile()->FindTargetToUse(dependee_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(linking && dependee &&
+ dependee->GetType() == cmTarget::EXECUTABLE &&
+ !dependee->IsExecutableWithExports())
+ {
+ dependee = 0;
+ }
+
+ if(dependee)
+ {
+ this->AddTargetDepend(depender_index, dependee, linking);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmComputeTargetDepends::AddTargetDepend(int depender_index,
+ cmTarget* dependee,
+ bool linking)
+{
+ if(dependee->IsImported())
+ {
+ // Skip imported targets but follow their utility dependencies.
+ std::set<cmStdString> const& utils = dependee->GetUtilities();
+ for(std::set<cmStdString>::const_iterator i = utils.begin();
+ i != utils.end(); ++i)
+ {
+ if(cmTarget* transitive_dependee =
+ dependee->GetMakefile()->FindTargetToUse(i->c_str()))
+ {
+ this->AddTargetDepend(depender_index, transitive_dependee, false);
+ }
+ }
+ }
+ else
+ {
+ // Lookup the index for this target. All targets should be known by
+ // this point.
+ std::map<cmTarget*, int>::const_iterator tii =
+ this->TargetIndex.find(dependee);
+ assert(tii != this->TargetIndex.end());
+ int dependee_index = tii->second;
+
+ // Add this entry to the dependency graph.
+ this->InitialGraph[depender_index].push_back(
+ cmGraphEdge(dependee_index, !linking));
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmComputeTargetDepends::DisplayGraph(Graph const& graph, const char* name)
+{
+ fprintf(stderr, "The %s target dependency graph is:\n", name);
+ 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];
+ fprintf(stderr, "target %d is [%s]\n",
+ depender_index, depender->GetName());
+ for(EdgeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni)
+ {
+ int dependee_index = *ni;
+ cmTarget* dependee = this->Targets[dependee_index];
+ fprintf(stderr, " depends on target %d [%s] (%s)\n", dependee_index,
+ dependee->GetName(), ni->IsStrong()? "strong" : "weak");
+ }
+ }
+ fprintf(stderr, "\n");
+}
+
+//----------------------------------------------------------------------------
+void
+cmComputeTargetDepends
+::DisplayComponents(cmComputeComponentGraph const& ccg)
+{
+ fprintf(stderr, "The strongly connected components are:\n");
+ std::vector<NodeList> const& components = ccg.GetComponents();
+ int n = static_cast<int>(components.size());
+ for(int c = 0; c < n; ++c)
+ {
+ NodeList const& nl = components[c];
+ fprintf(stderr, "Component (%d):\n", c);
+ for(NodeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni)
+ {
+ int i = *ni;
+ fprintf(stderr, " contains target %d [%s]\n",
+ i, this->Targets[i]->GetName());
+ }
+ }
+ fprintf(stderr, "\n");
+}
+
+//----------------------------------------------------------------------------
+bool
+cmComputeTargetDepends
+::CheckComponents(cmComputeComponentGraph const& ccg)
+{
+ // All non-trivial components should consist only of static
+ // libraries.
+ std::vector<NodeList> const& components = ccg.GetComponents();
+ int nc = static_cast<int>(components.size());
+ for(int c=0; c < nc; ++c)
+ {
+ // Get the current component.
+ NodeList const& nl = components[c];
+
+ // Skip trivial components.
+ if(nl.size() < 2)
+ {
+ continue;
+ }
+
+ // Immediately complain if no cycles are allowed at all.
+ if(this->NoCycles)
+ {
+ this->ComplainAboutBadComponent(ccg, c);
+ return false;
+ }
+
+ // 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)
+ {
+ this->ComplainAboutBadComponent(ccg, c);
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+void
+cmComputeTargetDepends
+::ComplainAboutBadComponent(cmComputeComponentGraph const& ccg, int c,
+ bool strong)
+{
+ // Construct the error message.
+ cmOStringStream e;
+ e << "The inter-target dependency graph contains the following "
+ << "strongly connected component (cycle):\n";
+ std::vector<NodeList> const& components = ccg.GetComponents();
+ std::vector<int> const& cmap = ccg.GetComponentMap();
+ NodeList const& cl = components[c];
+ for(NodeList::const_iterator ci = cl.begin(); ci != cl.end(); ++ci)
+ {
+ // Get the depender.
+ int i = *ci;
+ cmTarget* depender = this->Targets[i];
+
+ // Describe the depender.
+ e << " \"" << depender->GetName() << "\" of type "
+ << cmTarget::GetTargetTypeName(depender->GetType()) << "\n";
+
+ // List its dependencies that are inside the component.
+ EdgeList const& nl = this->InitialGraph[i];
+ for(EdgeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni)
+ {
+ int j = *ni;
+ if(cmap[j] == c)
+ {
+ cmTarget* dependee = this->Targets[j];
+ e << " depends on \"" << dependee->GetName() << "\""
+ << " (" << (ni->IsStrong()? "strong" : "weak") << ")\n";
+ }
+ }
+ }
+ if(strong)
+ {
+ // Custom command executable dependencies cannot occur within a
+ // component of static libraries. The cycle must appear in calls
+ // to add_dependencies.
+ e << "The component contains at least one cycle consisting of strong "
+ << "dependencies (created by add_dependencies) that cannot be broken.";
+ }
+ else if(this->NoCycles)
+ {
+ e << "The GLOBAL_DEPENDS_NO_CYCLES global property is enabled, so "
+ << "cyclic dependencies are not allowed even among static libraries.";
+ }
+ else
+ {
+ e << "At least one of these targets is not a STATIC_LIBRARY. "
+ << "Cyclic dependencies are allowed only among static libraries.";
+ }
+ cmSystemTools::Error(e.str().c_str());
+}
+
+//----------------------------------------------------------------------------
+bool
+cmComputeTargetDepends
+::IntraComponent(std::vector<int> const& cmap, int c, int i, int* head,
+ std::set<int>& emitted, std::set<int>& visited)
+{
+ if(!visited.insert(i).second)
+ {
+ // Cycle in utility depends!
+ return false;
+ }
+ if(emitted.insert(i).second)
+ {
+ // Honor strong intra-component edges in the final order.
+ EdgeList const& el = this->InitialGraph[i];
+ for(EdgeList::const_iterator ei = el.begin(); ei != el.end(); ++ei)
+ {
+ int j = *ei;
+ if(cmap[j] == c && ei->IsStrong())
+ {
+ this->FinalGraph[i].push_back(cmGraphEdge(j, true));
+ if(!this->IntraComponent(cmap, c, j, head, emitted, visited))
+ {
+ return false;
+ }
+ }
+ }
+
+ // Prepend to a linear linked-list of intra-component edges.
+ if(*head >= 0)
+ {
+ this->FinalGraph[i].push_back(cmGraphEdge(*head, false));
+ }
+ else
+ {
+ this->ComponentTail[c] = i;
+ }
+ *head = i;
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool
+cmComputeTargetDepends
+::ComputeFinalDepends(cmComputeComponentGraph const& ccg)
+{
+ // Get the component graph information.
+ std::vector<NodeList> const& components = ccg.GetComponents();
+ Graph const& cgraph = ccg.GetComponentGraph();
+
+ // Allocate the final graph.
+ this->FinalGraph.resize(0);
+ this->FinalGraph.resize(this->InitialGraph.size());
+
+ // Choose intra-component edges to linearize dependencies.
+ std::vector<int> const& cmap = ccg.GetComponentMap();
+ this->ComponentHead.resize(components.size());
+ this->ComponentTail.resize(components.size());
+ int nc = static_cast<int>(components.size());
+ for(int c=0; c < nc; ++c)
+ {
+ int head = -1;
+ std::set<int> emitted;
+ NodeList const& nl = components[c];
+ for(NodeList::const_reverse_iterator ni = nl.rbegin();
+ ni != nl.rend(); ++ni)
+ {
+ std::set<int> visited;
+ if(!this->IntraComponent(cmap, c, *ni, &head, emitted, visited))
+ {
+ // Cycle in add_dependencies within component!
+ this->ComplainAboutBadComponent(ccg, c, true);
+ return false;
+ }
+ }
+ this->ComponentHead[c] = head;
+ }
+
+ // Convert inter-component edges to connect component tails to heads.
+ int n = static_cast<int>(cgraph.size());
+ for(int depender_component=0; depender_component < n; ++depender_component)
+ {
+ int depender_component_tail = this->ComponentTail[depender_component];
+ EdgeList const& nl = cgraph[depender_component];
+ for(EdgeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni)
+ {
+ int dependee_component = *ni;
+ int dependee_component_head = this->ComponentHead[dependee_component];
+ this->FinalGraph[depender_component_tail]
+ .push_back(cmGraphEdge(dependee_component_head, ni->IsStrong()));
+ }
+ }
+ return true;
+}
diff --git a/Source/cmComputeTargetDepends.h b/Source/cmComputeTargetDepends.h
new file mode 100644
index 000000000..67bce72d9
--- /dev/null
+++ b/Source/cmComputeTargetDepends.h
@@ -0,0 +1,82 @@
+/*============================================================================
+ 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 cmComputeTargetDepends_h
+#define cmComputeTargetDepends_h
+
+#include "cmStandardIncludes.h"
+
+#include "cmGraphAdjacencyList.h"
+
+#include <stack>
+
+class cmComputeComponentGraph;
+class cmGlobalGenerator;
+class cmTarget;
+class cmTargetDependSet;
+
+/** \class cmComputeTargetDepends
+ * \brief Compute global interdependencies among targets.
+ *
+ * Static libraries may form cycles in the target dependency graph.
+ * This class evaluates target dependencies globally and adjusts them
+ * to remove cycles while preserving a safe build order.
+ */
+class cmComputeTargetDepends
+{
+public:
+ cmComputeTargetDepends(cmGlobalGenerator* gg);
+ ~cmComputeTargetDepends();
+
+ bool Compute();
+
+ std::vector<cmTarget*> const& GetTargets() const { return this->Targets; }
+ void GetTargetDirectDepends(cmTarget* t, cmTargetDependSet& deps);
+private:
+ void CollectTargets();
+ void CollectDepends();
+ void CollectTargetDepends(int depender_index);
+ void AddTargetDepend(int depender_index, const char* dependee_name,
+ bool linking);
+ void AddTargetDepend(int depender_index, cmTarget* dependee, bool linking);
+ bool ComputeFinalDepends(cmComputeComponentGraph const& ccg);
+
+ cmGlobalGenerator* GlobalGenerator;
+ bool DebugMode;
+ bool NoCycles;
+
+ // Collect all targets.
+ std::vector<cmTarget*> Targets;
+ std::map<cmTarget*, int> TargetIndex;
+
+ // Represent the target dependency graph. The entry at each
+ // top-level index corresponds to a depender whose dependencies are
+ // listed.
+ typedef cmGraphNodeList NodeList;
+ typedef cmGraphEdgeList EdgeList;
+ typedef cmGraphAdjacencyList Graph;
+ Graph InitialGraph;
+ Graph FinalGraph;
+ void DisplayGraph(Graph const& graph, const char* name);
+
+ // Deal with connected components.
+ void DisplayComponents(cmComputeComponentGraph const& ccg);
+ bool CheckComponents(cmComputeComponentGraph const& ccg);
+ void ComplainAboutBadComponent(cmComputeComponentGraph const& ccg, int c,
+ bool strong = false);
+
+ std::vector<int> ComponentHead;
+ std::vector<int> ComponentTail;
+ bool IntraComponent(std::vector<int> const& cmap, int c, int i, int* head,
+ std::set<int>& emitted, std::set<int>& visited);
+};
+
+#endif
diff --git a/Source/cmConfigure.cmake.h.in b/Source/cmConfigure.cmake.h.in
new file mode 100644
index 000000000..114afd7b7
--- /dev/null
+++ b/Source/cmConfigure.cmake.h.in
@@ -0,0 +1,22 @@
+/*============================================================================
+ 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.
+============================================================================*/
+#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}"
+#define CMAKE_DATA_DIR "@CMAKE_DATA_DIR@"
diff --git a/Source/cmConfigureFileCommand.cxx b/Source/cmConfigureFileCommand.cxx
new file mode 100644
index 000000000..ea98326e2
--- /dev/null
+++ b/Source/cmConfigureFileCommand.cxx
@@ -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.
+============================================================================*/
+#include "cmConfigureFileCommand.h"
+
+#include <cmsys/RegularExpression.hxx>
+
+// cmConfigureFileCommand
+bool cmConfigureFileCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 2 )
+ {
+ this->SetError("called with incorrect number of arguments, expected 2");
+ return false;
+ }
+
+ const char* inFile = args[0].c_str();
+ if(!cmSystemTools::FileIsFullPath(inFile))
+ {
+ this->InputFile = this->Makefile->GetCurrentDirectory();
+ this->InputFile += "/";
+ }
+ this->InputFile += inFile;
+
+ // If the input location is a directory, error out.
+ if(cmSystemTools::FileIsDirectory(this->InputFile.c_str()))
+ {
+ cmOStringStream e;
+ e << "input location\n"
+ << " " << this->InputFile << "\n"
+ << "is a directory but a file was expected.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+
+ const char* outFile = args[1].c_str();
+ if(!cmSystemTools::FileIsFullPath(outFile))
+ {
+ this->OutputFile = this->Makefile->GetCurrentOutputDirectory();
+ 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()))
+ {
+ this->OutputFile += "/";
+ this->OutputFile += cmSystemTools::GetFilenameName(inFile);
+ }
+
+ if ( !this->Makefile->CanIWriteThisFile(this->OutputFile.c_str()) )
+ {
+ std::string e = "attempted to configure a file: " + this->OutputFile
+ + " into a source directory.";
+ this->SetError(e.c_str());
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+ std::string errorMessage;
+ if (!this->NewLineStyle.ReadFromArguments(args, errorMessage))
+ {
+ this->SetError(errorMessage.c_str());
+ 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);
+
+ this->AtOnly = false;
+ for(unsigned int i=2;i < args.size();++i)
+ {
+ if(args[i] == "COPYONLY")
+ {
+ this->CopyOnly = true;
+ if (this->NewLineStyle.IsValid())
+ {
+ this->SetError("COPYONLY could not be used in combination "
+ "with NEWLINE_STYLE");
+ return false;
+ }
+ }
+ else if(args[i] == "ESCAPE_QUOTES")
+ {
+ this->EscapeQuotes = true;
+ }
+ else if(args[i] == "@ONLY")
+ {
+ this->AtOnly = true;
+ }
+ else if(args[i] == "IMMEDIATE")
+ {
+ this->Immediate = true;
+ }
+ }
+
+ // If we were told to copy the file immediately, then do it on the
+ // first pass (now).
+ if(this->Immediate)
+ {
+ if ( !this->ConfigureFile() )
+ {
+ this->SetError("Problem configuring file");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void cmConfigureFileCommand::FinalPass()
+{
+ if(!this->Immediate)
+ {
+ this->ConfigureFile();
+ }
+}
+
+int cmConfigureFileCommand::ConfigureFile()
+{
+ return this->Makefile->ConfigureFile(
+ this->InputFile.c_str(),
+ this->OutputFile.c_str(),
+ this->CopyOnly,
+ this->AtOnly,
+ this->EscapeQuotes,
+ this->NewLineStyle);
+}
+
+
diff --git a/Source/cmConfigureFileCommand.h b/Source/cmConfigureFileCommand.h
new file mode 100644
index 000000000..de497a952
--- /dev/null
+++ b/Source/cmConfigureFileCommand.h
@@ -0,0 +1,109 @@
+/*============================================================================
+ 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 cmConfigureFileCommand_h
+#define cmConfigureFileCommand_h
+
+#include "cmCommand.h"
+
+class cmConfigureFileCommand : public cmCommand
+{
+public:
+ cmTypeMacro(cmConfigureFileCommand, cmCommand);
+
+ virtual cmCommand* Clone()
+ {
+ return new cmConfigureFileCommand;
+ }
+
+ /**
+ * This is called when the command is first encountered in
+ * the input file.
+ */
+ 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 "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"
+ "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 replaces and ${VAR} will be ignored. "
+ "This is useful for configuring scripts that use ${VAR}. "
+ "Any occurrences of #cmakedefine VAR will be replaced with "
+ "either #define VAR or /* #undef VAR */ depending on "
+ "the setting of VAR in CMake. Any occurrences of #cmakedefine01 VAR "
+ "will be replaced with either #define VAR 1 or #define VAR 0 "
+ "depending on whether VAR evaluates to TRUE or FALSE in CMake.\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();
+
+ cmNewLineStyle NewLineStyle;
+
+ std::string InputFile;
+ std::string OutputFile;
+ bool CopyOnly;
+ bool EscapeQuotes;
+ bool Immediate;
+ bool AtOnly;
+};
+
+
+
+#endif
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
new file mode 100644
index 000000000..1ae70350b
--- /dev/null
+++ b/Source/cmCoreTryCompile.cxx
@@ -0,0 +1,483 @@
+/*============================================================================
+ 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.
+============================================================================*/
+#include "cmCoreTryCompile.h"
+#include "cmake.h"
+#include "cmCacheManager.h"
+#include "cmGlobalGenerator.h"
+#include <cmsys/Directory.hxx>
+
+int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
+{
+ this->BinaryDirectory = argv[1].c_str();
+ this->OutputFile = "";
+ // which signature were we called with ?
+ this->SrcFileSignature = false;
+ unsigned int i;
+
+ const char* sourceDirectory = argv[2].c_str();
+ const char* projectName = 0;
+ const char* targetName = 0;
+ char targetNameBuf[64];
+ int extraArgs = 0;
+
+ // look for CMAKE_FLAGS and store them
+ std::vector<std::string> cmakeFlags;
+ for (i = 3; i < argv.size(); ++i)
+ {
+ if (argv[i] == "CMAKE_FLAGS")
+ {
+ // 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
+ for (; i < argv.size() && argv[i] != "COMPILE_DEFINITIONS" &&
+ argv[i] != "OUTPUT_VARIABLE";
+ ++i)
+ {
+ extraArgs++;
+ cmakeFlags.push_back(argv[i]);
+ }
+ break;
+ }
+ }
+
+ // look for OUTPUT_VARIABLE and store them
+ std::string outputVariable;
+ for (i = 3; i < argv.size(); ++i)
+ {
+ if (argv[i] == "OUTPUT_VARIABLE")
+ {
+ if ( argv.size() <= (i+1) )
+ {
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR,
+ "OUTPUT_VARIABLE specified but there is no variable");
+ return -1;
+ }
+ extraArgs += 2;
+ outputVariable = argv[i+1];
+ break;
+ }
+ }
+
+ // look for COMPILE_DEFINITIONS and store them
+ std::vector<std::string> compileFlags;
+ for (i = 3; i < argv.size(); ++i)
+ {
+ if (argv[i] == "COMPILE_DEFINITIONS")
+ {
+ extraArgs++;
+ for (i = i + 1; i < argv.size() && argv[i] != "CMAKE_FLAGS" &&
+ argv[i] != "OUTPUT_VARIABLE";
+ ++i)
+ {
+ extraArgs++;
+ compileFlags.push_back(argv[i]);
+ }
+ break;
+ }
+ }
+
+ // look for COPY_FILE
+ std::string copyFile;
+ for (i = 3; i < argv.size(); ++i)
+ {
+ if (argv[i] == "COPY_FILE")
+ {
+ if ( argv.size() <= (i+1) )
+ {
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR,
+ "COPY_FILE specified but there is no variable");
+ return -1;
+ }
+ extraArgs += 2;
+ copyFile = argv[i+1];
+ break;
+ }
+ }
+
+ // do we have a srcfile signature
+ if (argv.size() - extraArgs == 3)
+ {
+ this->SrcFileSignature = true;
+ }
+
+ // compute the binary dir when TRY_COMPILE is called with a src file
+ // signature
+ if (this->SrcFileSignature)
+ {
+ this->BinaryDirectory += cmake::GetCMakeFilesDirectory();
+ this->BinaryDirectory += "/CMakeTmp";
+ }
+ else
+ {
+ // only valid for srcfile signatures
+ if (compileFlags.size())
+ {
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR,
+ "COMPILE_FLAGS specified on a srcdir type TRY_COMPILE");
+ return -1;
+ }
+ if (copyFile.size())
+ {
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR,
+ "COPY_FILE specified on a srcdir type TRY_COMPILE");
+ return -1;
+ }
+ }
+ // make sure the binary directory exists
+ cmSystemTools::MakeDirectory(this->BinaryDirectory.c_str());
+
+ // do not allow recursive try Compiles
+ if (this->BinaryDirectory == this->Makefile->GetHomeOutputDirectory())
+ {
+ cmOStringStream e;
+ e << "Attempt at a recursive or nested TRY_COMPILE in directory\n"
+ << " " << this->BinaryDirectory << "\n";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return -1;
+ }
+
+ std::string outFileName = this->BinaryDirectory + "/CMakeLists.txt";
+ // which signature are we using? If we are using var srcfile bindir
+ if (this->SrcFileSignature)
+ {
+ // remove any CMakeCache.txt files so we will have a clean test
+ std::string ccFile = this->BinaryDirectory + "/CMakeCache.txt";
+ cmSystemTools::RemoveFile(ccFile.c_str());
+
+ // we need to create a directory and CMakeLists file etc...
+ // first create the directories
+ sourceDirectory = this->BinaryDirectory.c_str();
+
+ // now create a CMakeLists.txt file in that directory
+ FILE *fout = fopen(outFileName.c_str(),"w");
+ if (!fout)
+ {
+ cmOStringStream e;
+ e << "Failed to open\n"
+ << " " << outFileName.c_str() << "\n"
+ << cmSystemTools::GetLastSystemError();
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return -1;
+ }
+
+ std::string source = argv[2];
+ std::string ext = cmSystemTools::GetFilenameLastExtension(source);
+ const char* lang =(this->Makefile->GetCMakeInstance()->GetGlobalGenerator()
+ ->GetLanguageFromExtension(ext.c_str()));
+ const char* def = this->Makefile->GetDefinition("CMAKE_MODULE_PATH");
+ fprintf(fout, "cmake_minimum_required(VERSION %u.%u.%u.%u)\n",
+ cmVersion::GetMajorVersion(), cmVersion::GetMinorVersion(),
+ cmVersion::GetPatchVersion(), cmVersion::GetTweakVersion());
+ if(def)
+ {
+ fprintf(fout, "SET(CMAKE_MODULE_PATH %s)\n", def);
+ }
+
+ const char* rulesOverrideBase = "CMAKE_USER_MAKE_RULES_OVERRIDE";
+ std::string rulesOverrideLang =
+ rulesOverrideBase + (lang ? std::string("_") + lang : std::string(""));
+ if(const char* rulesOverridePath =
+ this->Makefile->GetDefinition(rulesOverrideLang.c_str()))
+ {
+ fprintf(fout, "SET(%s \"%s\")\n",
+ rulesOverrideLang.c_str(), rulesOverridePath);
+ }
+ else if(const char* rulesOverridePath2 =
+ this->Makefile->GetDefinition(rulesOverrideBase))
+ {
+ fprintf(fout, "SET(%s \"%s\")\n",
+ rulesOverrideBase, rulesOverridePath2);
+ }
+
+ if(lang)
+ {
+ fprintf(fout, "PROJECT(CMAKE_TRY_COMPILE %s)\n", lang);
+ }
+ else
+ {
+ fclose(fout);
+ cmOStringStream err;
+ err << "Unknown extension \"" << ext << "\" for file\n"
+ << " " << source << "\n"
+ << "try_compile() works only for enabled languages. "
+ << "Currently these are:\n ";
+ std::vector<std::string> langs;
+ this->Makefile->GetCMakeInstance()->GetGlobalGenerator()->
+ GetEnabledLanguages(langs);
+ for(std::vector<std::string>::iterator l = langs.begin();
+ l != langs.end(); ++l)
+ {
+ err << " " << *l;
+ }
+ err << "\nSee project() command to enable other languages.";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, err.str());
+ return -1;
+ }
+ std::string langFlags = "CMAKE_";
+ langFlags += lang;
+ langFlags += "_FLAGS";
+ fprintf(fout, "SET(CMAKE_VERBOSE_MAKEFILE 1)\n");
+ fprintf(fout, "SET(CMAKE_%s_FLAGS \"", lang);
+ const char* flags = this->Makefile->GetDefinition(langFlags.c_str());
+ if(flags)
+ {
+ fprintf(fout, " %s ", flags);
+ }
+ fprintf(fout, " ${COMPILE_DEFINITIONS}\")\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 (compileFlags.size())
+ {
+ fprintf(fout, "ADD_DEFINITIONS( ");
+ for (i = 0; i < compileFlags.size(); ++i)
+ {
+ fprintf(fout,"%s ",compileFlags[i].c_str());
+ }
+ fprintf(fout, ")\n");
+ }
+
+ /* 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
+ have the tests run for each specific architecture. Since
+ cmLocalGenerator doesn't allow building for "the other"
+ architecture only via CMAKE_OSX_ARCHITECTURES.
+ */
+ if(this->Makefile->GetDefinition("CMAKE_TRY_COMPILE_OSX_ARCHITECTURES")!=0)
+ {
+ std::string flag="-DCMAKE_OSX_ARCHITECTURES=";
+ flag += this->Makefile->GetSafeDefinition(
+ "CMAKE_TRY_COMPILE_OSX_ARCHITECTURES");
+ cmakeFlags.push_back(flag);
+ }
+ else if (this->Makefile->GetDefinition("CMAKE_OSX_ARCHITECTURES")!=0)
+ {
+ std::string flag="-DCMAKE_OSX_ARCHITECTURES=";
+ flag += this->Makefile->GetSafeDefinition("CMAKE_OSX_ARCHITECTURES");
+ cmakeFlags.push_back(flag);
+ }
+ /* on APPLE also pass CMAKE_OSX_SYSROOT to the try_compile */
+ if(this->Makefile->GetDefinition("CMAKE_OSX_SYSROOT")!=0)
+ {
+ std::string flag="-DCMAKE_OSX_SYSROOT=";
+ flag += this->Makefile->GetSafeDefinition("CMAKE_OSX_SYSROOT");
+ cmakeFlags.push_back(flag);
+ }
+ /* on APPLE also pass CMAKE_OSX_DEPLOYMENT_TARGET to the try_compile */
+ if(this->Makefile->GetDefinition("CMAKE_OSX_DEPLOYMENT_TARGET")!=0)
+ {
+ std::string flag="-DCMAKE_OSX_DEPLOYMENT_TARGET=";
+ flag += this->Makefile->GetSafeDefinition("CMAKE_OSX_DEPLOYMENT_TARGET");
+ cmakeFlags.push_back(flag);
+ }
+ if(this->Makefile->GetDefinition("CMAKE_POSITION_INDEPENDENT_CODE")!=0)
+ {
+ fprintf(fout, "SET(CMAKE_POSITION_INDEPENDENT_CODE \"ON\")\n");
+ }
+
+ /* 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());
+ targetName = targetNameBuf;
+
+ /* Put the executable at a known location (for COPY_FILE). */
+ fprintf(fout, "SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY \"%s\")\n",
+ this->BinaryDirectory.c_str());
+ /* Create the actual executable. */
+ fprintf(fout, "ADD_EXECUTABLE(%s \"%s\")\n", targetName, source.c_str());
+ fprintf(fout, "TARGET_LINK_LIBRARIES(%s ${LINK_LIBRARIES})\n",targetName);
+ fclose(fout);
+ projectName = "CMAKE_TRY_COMPILE";
+ // if the source is not in CMakeTmp
+ if(source.find("CMakeTmp") == source.npos)
+ {
+ this->Makefile->AddCMakeDependFile(source.c_str());
+ }
+
+ }
+ // else the srcdir bindir project target signature
+ else
+ {
+ projectName = argv[3].c_str();
+
+ if (argv.size() - extraArgs == 5)
+ {
+ targetName = argv[4].c_str();
+ }
+ }
+
+ bool erroroc = cmSystemTools::GetErrorOccuredFlag();
+ cmSystemTools::ResetErrorOccuredFlag();
+ std::string output;
+ // actually do the try compile now that everything is setup
+ int res = this->Makefile->TryCompile(sourceDirectory,
+ this->BinaryDirectory.c_str(),
+ projectName,
+ targetName,
+ this->SrcFileSignature,
+ &cmakeFlags,
+ &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(),
+ (res == 0 ? "TRUE" : "FALSE"),
+ "Result of TRY_COMPILE",
+ cmCacheManager::INTERNAL);
+
+ if ( outputVariable.size() > 0 )
+ {
+ this->Makefile->AddDefinition(outputVariable.c_str(), output.c_str());
+ }
+
+ if (this->SrcFileSignature)
+ {
+ this->FindOutputFile(targetName);
+
+ if ((res==0) && (copyFile.size()))
+ {
+ if(this->OutputFile.empty() ||
+ !cmSystemTools::CopyFileAlways(this->OutputFile.c_str(),
+ copyFile.c_str()))
+ {
+ cmOStringStream emsg;
+ emsg << "Cannot copy output executable\n"
+ << " '" << this->OutputFile.c_str() << "'\n"
+ << "to destination specified by COPY_FILE:\n"
+ << " '" << copyFile.c_str() << "'\n";
+ if(!this->FindErrorMessage.empty())
+ {
+ emsg << this->FindErrorMessage.c_str();
+ }
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, emsg.str());
+ return -1;
+ }
+ }
+ }
+ return res;
+}
+
+void cmCoreTryCompile::CleanupFiles(const char* binDir)
+{
+ if ( !binDir )
+ {
+ return;
+ }
+
+ std::string bdir = binDir;
+ if(bdir.find("CMakeTmp") == std::string::npos)
+ {
+ cmSystemTools::Error(
+ "TRY_COMPILE attempt to remove -rf directory that does not contain "
+ "CMakeTmp:", binDir);
+ return;
+ }
+
+ cmsys::Directory dir;
+ dir.Load(binDir);
+ size_t fileNum;
+ std::set<cmStdString> deletedFiles;
+ for (fileNum = 0; fileNum < dir.GetNumberOfFiles(); ++fileNum)
+ {
+ if (strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)),".") &&
+ strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)),".."))
+ {
+
+ if(deletedFiles.find( dir.GetFile(static_cast<unsigned long>(fileNum)))
+ == deletedFiles.end())
+ {
+ deletedFiles.insert(dir.GetFile(static_cast<unsigned long>(fileNum)));
+ std::string fullPath = binDir;
+ fullPath += "/";
+ fullPath += dir.GetFile(static_cast<unsigned long>(fileNum));
+ if(cmSystemTools::FileIsDirectory(fullPath.c_str()))
+ {
+ this->CleanupFiles(fullPath.c_str());
+ cmSystemTools::RemoveADirectory(fullPath.c_str());
+ }
+ else
+ {
+ // Sometimes anti-virus software hangs on to new files so we
+ // cannot delete them immediately. Try a few times.
+ int tries = 5;
+ while(!cmSystemTools::RemoveFile(fullPath.c_str()) &&
+ --tries && cmSystemTools::FileExists(fullPath.c_str()))
+ {
+ cmSystemTools::Delay(500);
+ }
+ if(tries == 0)
+ {
+ std::string m = "Remove failed on file: " + fullPath;
+ cmSystemTools::ReportLastSystemError(m.c_str());
+ }
+ }
+ }
+ }
+ }
+}
+
+void cmCoreTryCompile::FindOutputFile(const char* targetName)
+{
+ this->FindErrorMessage = "";
+ this->OutputFile = "";
+ std::string tmpOutputFile = "/";
+ tmpOutputFile += targetName;
+ tmpOutputFile +=this->Makefile->GetSafeDefinition("CMAKE_EXECUTABLE_SUFFIX");
+
+ // a list of directories where to search for the compilation result
+ // at first directly in the binary dir
+ std::vector<std::string> searchDirs;
+ searchDirs.push_back("");
+
+ const char* config = this->Makefile->GetDefinition(
+ "CMAKE_TRY_COMPILE_CONFIGURATION");
+ // if a config was specified try that first
+ if (config && config[0])
+ {
+ std::string tmp = "/";
+ tmp += config;
+ searchDirs.push_back(tmp);
+ }
+ searchDirs.push_back("/Debug");
+ searchDirs.push_back("/Development");
+
+ for(std::vector<std::string>::const_iterator it = searchDirs.begin();
+ it != searchDirs.end();
+ ++it)
+ {
+ std::string command = this->BinaryDirectory;
+ command += *it;
+ command += tmpOutputFile;
+ if(cmSystemTools::FileExists(command.c_str()))
+ {
+ tmpOutputFile = cmSystemTools::CollapseFullPath(command.c_str());
+ this->OutputFile = tmpOutputFile;
+ return;
+ }
+ }
+
+ cmOStringStream 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";
+ }
+ this->FindErrorMessage = emsg.str();
+ return;
+}
diff --git a/Source/cmCoreTryCompile.h b/Source/cmCoreTryCompile.h
new file mode 100644
index 000000000..5c67f1355
--- /dev/null
+++ b/Source/cmCoreTryCompile.h
@@ -0,0 +1,60 @@
+/*============================================================================
+ 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 cmCoreTryCompile_h
+#define cmCoreTryCompile_h
+
+#include "cmCommand.h"
+
+/** \class cmCoreTryCompile
+ * \brief Base class for cmTryCompileCommand and cmTryRunCommand
+ *
+ * cmCoreTryCompile implements the functionality to build a program.
+ * It is the base class for cmTryCompileCommand and cmTryRunCommand.
+ */
+class cmCoreTryCompile : public cmCommand
+{
+public:
+
+ protected:
+ /**
+ * This is the core code for try compile. It is here so that other
+ * commands, such as TryRun can access the same logic without
+ * duplication.
+ */
+ int TryCompileCode(std::vector<std::string> const& argv);
+
+ /**
+ * This deletes all the files created by TryCompileCode.
+ * This way we do not have to rely on the timing and
+ * dependencies of makefiles.
+ */
+ void CleanupFiles(const char* binDir);
+
+ /**
+ * This tries to find the (executable) file created by
+ TryCompileCode. The result is stored in OutputFile. If nothing is found,
+ the error message is stored in FindErrorMessage.
+ */
+ void FindOutputFile(const char* targetName);
+
+
+ cmTypeMacro(cmCoreTryCompile, cmCommand);
+
+ std::string BinaryDirectory;
+ std::string OutputFile;
+ std::string FindErrorMessage;
+ bool SrcFileSignature;
+
+};
+
+
+#endif
diff --git a/Source/cmCreateTestSourceList.cxx b/Source/cmCreateTestSourceList.cxx
new file mode 100644
index 000000000..de20cb7ef
--- /dev/null
+++ b/Source/cmCreateTestSourceList.cxx
@@ -0,0 +1,189 @@
+/*============================================================================
+ 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 "cmCreateTestSourceList.h"
+#include "cmSourceFile.h"
+
+// cmCreateTestSourceList
+bool cmCreateTestSourceList
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if (args.size() < 3)
+ {
+ this->SetError("called with wrong number of arguments.");
+ return false;
+ }
+
+
+ std::vector<std::string>::const_iterator i = args.begin();
+ std::string extraInclude;
+ std::string function;
+ std::vector<std::string> tests;
+ // extract extra include and function ot
+ for(; i != args.end(); i++)
+ {
+ if(*i == "EXTRA_INCLUDE")
+ {
+ ++i;
+ if(i == args.end())
+ {
+ this->SetError("incorrect arguments to EXTRA_INCLUDE");
+ return false;
+ }
+ extraInclude = "#include \"";
+ extraInclude += *i;
+ extraInclude += "\"\n";
+ }
+ else if(*i == "FUNCTION")
+ {
+ ++i;
+ if(i == args.end())
+ {
+ this->SetError("incorrect arguments to FUNCTION");
+ return false;
+ }
+ function = *i;
+ function += "(&ac, &av);\n";
+ }
+ else
+ {
+ tests.push_back(*i);
+ }
+ }
+ i = tests.begin();
+
+ // Name of the source list
+
+ const char* sourceList = i->c_str();
+ ++i;
+
+ // Name of the test driver
+ // make sure they specified an extension
+ if (cmSystemTools::GetFilenameExtension(*i).size() < 2)
+ {
+ this->SetError(
+ "You must specify a file extension for the test driver file.");
+ return false;
+ }
+ std::string driver = this->Makefile->GetCurrentOutputDirectory();
+ driver += "/";
+ driver += *i;
+ ++i;
+
+ std::string configFile =
+ this->Makefile->GetRequiredDefinition("CMAKE_ROOT");
+
+ configFile += "/Templates/TestDriver.cxx.in";
+ // Create the test driver file
+
+ std::vector<std::string>::const_iterator testsBegin = i;
+ std::vector<std::string> tests_func_name;
+
+ // The rest of the arguments consist of a list of test source files.
+ // Sadly, they can be in directories. Let's find a unique function
+ // name for the corresponding test, and push it to the tests_func_name
+ // list.
+ // For the moment:
+ // - replace spaces ' ', ':' and '/' with underscores '_'
+ std::string forwardDeclareCode;
+ for(i = testsBegin; i != tests.end(); ++i)
+ {
+ if(*i == "EXTRA_INCLUDE")
+ {
+ break;
+ }
+ std::string func_name;
+ if (cmSystemTools::GetFilenamePath(*i).size() > 0)
+ {
+ func_name = cmSystemTools::GetFilenamePath(*i) + "/" +
+ cmSystemTools::GetFilenameWithoutLastExtension(*i);
+ }
+ else
+ {
+ func_name = cmSystemTools::GetFilenameWithoutLastExtension(*i);
+ }
+ cmSystemTools::ConvertToUnixSlashes(func_name);
+ cmSystemTools::ReplaceString(func_name, " ", "_");
+ cmSystemTools::ReplaceString(func_name, "/", "_");
+ cmSystemTools::ReplaceString(func_name, ":", "_");
+ tests_func_name.push_back(func_name);
+ forwardDeclareCode += "int ";
+ forwardDeclareCode += func_name;
+ forwardDeclareCode += "(int, char*[]);\n";
+ }
+
+ std::string functionMapCode;
+ int numTests = 0;
+ std::vector<std::string>::iterator j;
+ for(i = testsBegin, j = tests_func_name.begin(); i != tests.end(); ++i, ++j)
+ {
+ std::string func_name;
+ if (cmSystemTools::GetFilenamePath(*i).size() > 0)
+ {
+ func_name = cmSystemTools::GetFilenamePath(*i) + "/" +
+ cmSystemTools::GetFilenameWithoutLastExtension(*i);
+ }
+ else
+ {
+ func_name = cmSystemTools::GetFilenameWithoutLastExtension(*i);
+ }
+ functionMapCode += " {\n"
+ " \"";
+ functionMapCode += func_name;
+ functionMapCode += "\",\n"
+ " ";
+ functionMapCode += *j;
+ functionMapCode += "\n"
+ " },\n";
+ numTests++;
+ }
+ if(extraInclude.size())
+ {
+ this->Makefile->AddDefinition("CMAKE_TESTDRIVER_EXTRA_INCLUDES",
+ extraInclude.c_str());
+ }
+ if(function.size())
+ {
+ this->Makefile->AddDefinition("CMAKE_TESTDRIVER_ARGVC_FUNCTION",
+ function.c_str());
+ }
+ this->Makefile->AddDefinition("CMAKE_FORWARD_DECLARE_TESTS",
+ forwardDeclareCode.c_str());
+ this->Makefile->AddDefinition("CMAKE_FUNCTION_TABLE_ENTIRES",
+ functionMapCode.c_str());
+ bool res = true;
+ if ( !this->Makefile->ConfigureFile(configFile.c_str(), driver.c_str(),
+ false, true, false) )
+ {
+ res = false;
+ }
+
+ // Construct the source list.
+ std::string sourceListValue;
+ {
+ cmSourceFile* sf = this->Makefile->GetOrCreateSource(driver.c_str());
+ sf->SetProperty("ABSTRACT","0");
+ sourceListValue = args[1];
+ }
+ for(i = testsBegin; i != tests.end(); ++i)
+ {
+ cmSourceFile* sf = this->Makefile->GetOrCreateSource(i->c_str());
+ sf->SetProperty("ABSTRACT","0");
+ sourceListValue += ";";
+ sourceListValue += *i;
+ }
+
+ this->Makefile->AddDefinition(sourceList, sourceListValue.c_str());
+ return res;
+}
+
+
+
diff --git a/Source/cmCreateTestSourceList.h b/Source/cmCreateTestSourceList.h
new file mode 100644
index 000000000..806e5a909
--- /dev/null
+++ b/Source/cmCreateTestSourceList.h
@@ -0,0 +1,90 @@
+/*============================================================================
+ 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 cmCreateTestSourceList_h
+#define cmCreateTestSourceList_h
+
+#include "cmCommand.h"
+
+/** \class cmCreateTestSourceList
+ * \brief
+ *
+ */
+
+class cmCreateTestSourceList : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmCreateTestSourceList;
+ }
+
+ /**
+ * 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 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.";
+ }
+
+ cmTypeMacro(cmCreateTestSourceList, cmCommand);
+};
+
+
+
+#endif
diff --git a/Source/cmCryptoHash.cxx b/Source/cmCryptoHash.cxx
new file mode 100644
index 000000000..a1505bd65
--- /dev/null
+++ b/Source/cmCryptoHash.cxx
@@ -0,0 +1,130 @@
+/*============================================================================
+ 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 "cmCryptoHash.h"
+
+#include <cmsys/MD5.h>
+#include "cm_sha2.h"
+
+//----------------------------------------------------------------------------
+cmsys::auto_ptr<cmCryptoHash> cmCryptoHash::New(const char* algo)
+{
+ if(strcmp(algo,"MD5") == 0)
+ { return cmsys::auto_ptr<cmCryptoHash>(new cmCryptoHashMD5); }
+ else if(strcmp(algo,"SHA1") == 0)
+ { return cmsys::auto_ptr<cmCryptoHash>(new cmCryptoHashSHA1); }
+ else if(strcmp(algo,"SHA224") == 0)
+ { return cmsys::auto_ptr<cmCryptoHash>(new cmCryptoHashSHA224); }
+ else if(strcmp(algo,"SHA256") == 0)
+ { return cmsys::auto_ptr<cmCryptoHash>(new cmCryptoHashSHA256); }
+ else if(strcmp(algo,"SHA384") == 0)
+ { return cmsys::auto_ptr<cmCryptoHash>(new cmCryptoHashSHA384); }
+ else if(strcmp(algo,"SHA512") == 0)
+ { return cmsys::auto_ptr<cmCryptoHash>(new cmCryptoHashSHA512); }
+ else
+ { return cmsys::auto_ptr<cmCryptoHash>(0); }
+}
+
+//----------------------------------------------------------------------------
+std::string cmCryptoHash::HashString(const char* input)
+{
+ this->Initialize();
+ this->Append(reinterpret_cast<unsigned char const*>(input),
+ static_cast<int>(strlen(input)));
+ return this->Finalize();
+}
+
+//----------------------------------------------------------------------------
+std::string cmCryptoHash::HashFile(const char* file)
+{
+ std::ifstream fin(file, std::ios::in | cmsys_ios_binary);
+ if(!fin)
+ {
+ return "";
+ }
+
+ this->Initialize();
+
+ // Should be efficient enough on most system:
+ const int bufferSize = 4096;
+ char buffer[bufferSize];
+ unsigned char const* buffer_uc =
+ reinterpret_cast<unsigned char const*>(buffer);
+ // 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(int gcount = static_cast<int>(fin.gcount()))
+ {
+ this->Append(buffer_uc, gcount);
+ }
+ }
+ if(fin.eof())
+ {
+ return this->Finalize();
+ }
+ return "";
+}
+
+//----------------------------------------------------------------------------
+cmCryptoHashMD5::cmCryptoHashMD5(): MD5(cmsysMD5_New())
+{
+}
+
+//----------------------------------------------------------------------------
+cmCryptoHashMD5::~cmCryptoHashMD5()
+{
+ cmsysMD5_Delete(this->MD5);
+}
+
+//----------------------------------------------------------------------------
+void cmCryptoHashMD5::Initialize()
+{
+ cmsysMD5_Initialize(this->MD5);
+}
+
+//----------------------------------------------------------------------------
+void cmCryptoHashMD5::Append(unsigned char const* buf, int sz)
+{
+ cmsysMD5_Append(this->MD5, buf, sz);
+}
+
+//----------------------------------------------------------------------------
+std::string cmCryptoHashMD5::Finalize()
+{
+ char md5out[32];
+ cmsysMD5_FinalizeHex(this->MD5, md5out);
+ return std::string(md5out, 32);
+}
+
+
+#define cmCryptoHash_SHA_CLASS_IMPL(SHA) \
+cmCryptoHash##SHA::cmCryptoHash##SHA(): SHA(new SHA_CTX) {} \
+cmCryptoHash##SHA::~cmCryptoHash##SHA() { delete this->SHA; } \
+void cmCryptoHash##SHA::Initialize() { SHA##_Init(this->SHA); } \
+void cmCryptoHash##SHA::Append(unsigned char const* buf, int sz) \
+{ SHA##_Update(this->SHA, buf, sz); } \
+std::string cmCryptoHash##SHA::Finalize() \
+{ \
+ char out[SHA##_DIGEST_STRING_LENGTH]; \
+ SHA##_End(this->SHA, out); \
+ return std::string(out, SHA##_DIGEST_STRING_LENGTH-1); \
+}
+
+cmCryptoHash_SHA_CLASS_IMPL(SHA1)
+cmCryptoHash_SHA_CLASS_IMPL(SHA224)
+cmCryptoHash_SHA_CLASS_IMPL(SHA256)
+cmCryptoHash_SHA_CLASS_IMPL(SHA384)
+cmCryptoHash_SHA_CLASS_IMPL(SHA512)
diff --git a/Source/cmCryptoHash.h b/Source/cmCryptoHash.h
new file mode 100644
index 000000000..1bea9abcb
--- /dev/null
+++ b/Source/cmCryptoHash.h
@@ -0,0 +1,65 @@
+/*============================================================================
+ 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 cmCryptoHash_h
+#define cmCryptoHash_h
+
+#include "cmStandardIncludes.h"
+
+#include <cmsys/auto_ptr.hxx>
+
+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);
+protected:
+ virtual void Initialize()=0;
+ virtual void Append(unsigned char const*, int)=0;
+ virtual std::string Finalize()=0;
+};
+
+class cmCryptoHashMD5: public cmCryptoHash
+{
+ struct cmsysMD5_s* MD5;
+public:
+ cmCryptoHashMD5();
+ ~cmCryptoHashMD5();
+protected:
+ virtual void Initialize();
+ virtual void Append(unsigned char const* buf, int sz);
+ virtual std::string Finalize();
+};
+
+#define cmCryptoHash_SHA_CLASS_DECL(SHA) \
+ class cmCryptoHash##SHA: public cmCryptoHash \
+ { \
+ union _SHA_CTX* SHA; \
+ public: \
+ cmCryptoHash##SHA(); \
+ ~cmCryptoHash##SHA(); \
+ protected: \
+ virtual void Initialize(); \
+ virtual void Append(unsigned char const* buf, int sz); \
+ virtual std::string Finalize(); \
+ }
+
+cmCryptoHash_SHA_CLASS_DECL(SHA1);
+cmCryptoHash_SHA_CLASS_DECL(SHA224);
+cmCryptoHash_SHA_CLASS_DECL(SHA256);
+cmCryptoHash_SHA_CLASS_DECL(SHA384);
+cmCryptoHash_SHA_CLASS_DECL(SHA512);
+
+#undef cmCryptoHash_SHA_CLASS_DECL
+
+#endif
diff --git a/Source/cmCustomCommand.cxx b/Source/cmCustomCommand.cxx
new file mode 100644
index 000000000..bd860ee6a
--- /dev/null
+++ b/Source/cmCustomCommand.cxx
@@ -0,0 +1,172 @@
+/*============================================================================
+ 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 "cmCustomCommand.h"
+
+#include "cmMakefile.h"
+
+//----------------------------------------------------------------------------
+cmCustomCommand::cmCustomCommand()
+{
+ this->HaveComment = false;
+ this->EscapeOldStyle = true;
+ this->EscapeAllowMakeVars = 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(cmMakefile* mf,
+ const std::vector<std::string>& outputs,
+ const std::vector<std::string>& depends,
+ const cmCustomCommandLines& commandLines,
+ const char* comment,
+ const char* workingDirectory):
+ Outputs(outputs),
+ Depends(depends),
+ CommandLines(commandLines),
+ HaveComment(comment?true:false),
+ Comment(comment?comment:""),
+ WorkingDirectory(workingDirectory?workingDirectory:""),
+ EscapeAllowMakeVars(false),
+ EscapeOldStyle(true),
+ Backtrace(new cmListFileBacktrace)
+{
+ this->EscapeOldStyle = true;
+ this->EscapeAllowMakeVars = false;
+ if(mf)
+ {
+ mf->GetBacktrace(*this->Backtrace);
+ }
+}
+
+//----------------------------------------------------------------------------
+cmCustomCommand::~cmCustomCommand()
+{
+ delete this->Backtrace;
+}
+
+//----------------------------------------------------------------------------
+const std::vector<std::string>& cmCustomCommand::GetOutputs() const
+{
+ return this->Outputs;
+}
+
+//----------------------------------------------------------------------------
+const char* cmCustomCommand::GetWorkingDirectory() const
+{
+ if(this->WorkingDirectory.size() == 0)
+ {
+ return 0;
+ }
+ return this->WorkingDirectory.c_str();
+}
+
+//----------------------------------------------------------------------------
+const std::vector<std::string>& cmCustomCommand::GetDepends() const
+{
+ return this->Depends;
+}
+
+//----------------------------------------------------------------------------
+const cmCustomCommandLines& cmCustomCommand::GetCommandLines() const
+{
+ return this->CommandLines;
+}
+
+//----------------------------------------------------------------------------
+const char* cmCustomCommand::GetComment() const
+{
+ const char* no_comment = 0;
+ return this->HaveComment? this->Comment.c_str() : no_comment;
+}
+
+//----------------------------------------------------------------------------
+void cmCustomCommand::AppendCommands(const cmCustomCommandLines& commandLines)
+{
+ for(cmCustomCommandLines::const_iterator i=commandLines.begin();
+ i != commandLines.end(); ++i)
+ {
+ this->CommandLines.push_back(*i);
+ }
+}
+
+//----------------------------------------------------------------------------
+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);
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmCustomCommand::GetEscapeOldStyle() const
+{
+ return this->EscapeOldStyle;
+}
+
+//----------------------------------------------------------------------------
+void cmCustomCommand::SetEscapeOldStyle(bool b)
+{
+ this->EscapeOldStyle = b;
+}
+
+//----------------------------------------------------------------------------
+bool cmCustomCommand::GetEscapeAllowMakeVars() const
+{
+ return this->EscapeAllowMakeVars;
+}
+
+//----------------------------------------------------------------------------
+void cmCustomCommand::SetEscapeAllowMakeVars(bool b)
+{
+ this->EscapeAllowMakeVars = b;
+}
+
+//----------------------------------------------------------------------------
+cmListFileBacktrace const& cmCustomCommand::GetBacktrace() const
+{
+ return *this->Backtrace;
+}
+
+//----------------------------------------------------------------------------
+cmCustomCommand::ImplicitDependsList const&
+cmCustomCommand::GetImplicitDepends() const
+{
+ return this->ImplicitDepends;
+}
+
+//----------------------------------------------------------------------------
+void cmCustomCommand::SetImplicitDepends(ImplicitDependsList const& l)
+{
+ this->ImplicitDepends = l;
+}
+
+//----------------------------------------------------------------------------
+void cmCustomCommand::AppendImplicitDepends(ImplicitDependsList const& l)
+{
+ this->ImplicitDepends.insert(this->ImplicitDepends.end(),
+ l.begin(), l.end());
+}
diff --git a/Source/cmCustomCommand.h b/Source/cmCustomCommand.h
new file mode 100644
index 000000000..dd92e34d7
--- /dev/null
+++ b/Source/cmCustomCommand.h
@@ -0,0 +1,93 @@
+/*============================================================================
+ 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 cmCustomCommand_h
+#define cmCustomCommand_h
+
+#include "cmStandardIncludes.h"
+class cmMakefile;
+class cmListFileBacktrace;
+
+/** \class cmCustomCommand
+ * \brief A class to encapsulate a custom command
+ *
+ * cmCustomCommand encapsulates the properties of a custom command
+ */
+class cmCustomCommand
+{
+public:
+ /** Default and copy constructors for STL containers. */
+ cmCustomCommand();
+ cmCustomCommand(const cmCustomCommand& r);
+
+ /** Main constructor specifies all information for the command. */
+ cmCustomCommand(cmMakefile* mf,
+ const std::vector<std::string>& outputs,
+ 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 vector that holds the list of dependencies. */
+ const std::vector<std::string>& GetDepends() const;
+
+ /** Get the list of command lines. */
+ const cmCustomCommandLines& GetCommandLines() const;
+
+ /** Get the comment string for the command. */
+ const char* GetComment() const;
+
+ /** Append to the list of command lines. */
+ void AppendCommands(const cmCustomCommandLines& commandLines);
+
+ /** Append to the list of dependencies. */
+ void AppendDepends(const std::vector<std::string>& depends);
+
+ /** Set/Get whether old-style escaping should be used. */
+ bool GetEscapeOldStyle() const;
+ void SetEscapeOldStyle(bool b);
+
+ /** Set/Get whether the build tool can replace variables in
+ arguments to the command. */
+ bool GetEscapeAllowMakeVars() const;
+ void SetEscapeAllowMakeVars(bool b);
+
+ /** Backtrace of the command that created this custom command. */
+ cmListFileBacktrace const& GetBacktrace() const;
+
+ typedef std::pair<cmStdString, cmStdString> ImplicitDependsPair;
+ class ImplicitDependsList: public std::vector<ImplicitDependsPair> {};
+ void SetImplicitDepends(ImplicitDependsList const&);
+ void AppendImplicitDepends(ImplicitDependsList const&);
+ ImplicitDependsList const& GetImplicitDepends() const;
+
+private:
+ std::vector<std::string> Outputs;
+ std::vector<std::string> Depends;
+ cmCustomCommandLines CommandLines;
+ bool HaveComment;
+ std::string Comment;
+ std::string WorkingDirectory;
+ bool EscapeAllowMakeVars;
+ bool EscapeOldStyle;
+ cmListFileBacktrace* Backtrace;
+ ImplicitDependsList ImplicitDepends;
+};
+
+#endif
diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx
new file mode 100644
index 000000000..a65012905
--- /dev/null
+++ b/Source/cmCustomCommandGenerator.cxx
@@ -0,0 +1,72 @@
+/*============================================================================
+ 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 "cmCustomCommandGenerator.h"
+
+#include "cmMakefile.h"
+#include "cmCustomCommand.h"
+#include "cmLocalGenerator.h"
+#include "cmGeneratorExpression.h"
+
+//----------------------------------------------------------------------------
+cmCustomCommandGenerator::cmCustomCommandGenerator(
+ cmCustomCommand const& cc, const char* config, cmMakefile* mf):
+ CC(cc), Config(config), Makefile(mf), LG(mf->GetLocalGenerator()),
+ OldStyle(cc.GetEscapeOldStyle()), MakeVars(cc.GetEscapeAllowMakeVars()),
+ GE(new cmGeneratorExpression(mf, config, cc.GetBacktrace()))
+{
+}
+
+//----------------------------------------------------------------------------
+cmCustomCommandGenerator::~cmCustomCommandGenerator()
+{
+ delete this->GE;
+}
+
+//----------------------------------------------------------------------------
+unsigned int cmCustomCommandGenerator::GetNumberOfCommands() const
+{
+ return static_cast<unsigned int>(this->CC.GetCommandLines().size());
+}
+
+//----------------------------------------------------------------------------
+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")))
+ {
+ return target->GetLocation(this->Config);
+ }
+ return this->GE->Process(argv0);
+}
+
+//----------------------------------------------------------------------------
+void
+cmCustomCommandGenerator
+::AppendArguments(unsigned int c, std::string& cmd) const
+{
+ cmCustomCommandLine const& commandLine = this->CC.GetCommandLines()[c];
+ for(unsigned int j=1;j < commandLine.size(); ++j)
+ {
+ std::string arg = this->GE->Process(commandLine[j]);
+ cmd += " ";
+ if(this->OldStyle)
+ {
+ cmd += this->LG->EscapeForShellOldStyle(arg.c_str());
+ }
+ else
+ {
+ cmd += this->LG->EscapeForShell(arg.c_str(), this->MakeVars);
+ }
+ }
+}
diff --git a/Source/cmCustomCommandGenerator.h b/Source/cmCustomCommandGenerator.h
new file mode 100644
index 000000000..4e89f2731
--- /dev/null
+++ b/Source/cmCustomCommandGenerator.h
@@ -0,0 +1,40 @@
+/*============================================================================
+ 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 cmCustomCommandGenerator_h
+#define cmCustomCommandGenerator_h
+
+#include "cmStandardIncludes.h"
+
+class cmCustomCommand;
+class cmMakefile;
+class cmLocalGenerator;
+class cmGeneratorExpression;
+
+class cmCustomCommandGenerator
+{
+ cmCustomCommand const& CC;
+ const char* Config;
+ cmMakefile* Makefile;
+ cmLocalGenerator* LG;
+ bool OldStyle;
+ bool MakeVars;
+ cmGeneratorExpression* GE;
+public:
+ cmCustomCommandGenerator(cmCustomCommand const& cc, const char* config,
+ cmMakefile* mf);
+ ~cmCustomCommandGenerator();
+ unsigned int GetNumberOfCommands() const;
+ std::string GetCommand(unsigned int c) const;
+ void AppendArguments(unsigned int c, std::string& cmd) const;
+};
+
+#endif
diff --git a/Source/cmDefinePropertyCommand.cxx b/Source/cmDefinePropertyCommand.cxx
new file mode 100644
index 000000000..5816829e0
--- /dev/null
+++ b/Source/cmDefinePropertyCommand.cxx
@@ -0,0 +1,137 @@
+/*============================================================================
+ 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 "cmDefinePropertyCommand.h"
+#include "cmake.h"
+
+// cmDefinePropertiesCommand
+bool cmDefinePropertyCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 1)
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ // Get the scope in which to define the property.
+ cmProperty::ScopeType scope;
+ if(args[0] == "GLOBAL")
+ {
+ scope = cmProperty::GLOBAL;
+ }
+ else if(args[0] == "DIRECTORY")
+ {
+ scope = cmProperty::DIRECTORY;
+ }
+ else if(args[0] == "TARGET")
+ {
+ scope = cmProperty::TARGET;
+ }
+ else if(args[0] == "SOURCE")
+ {
+ scope = cmProperty::SOURCE_FILE;
+ }
+ else if(args[0] == "TEST")
+ {
+ scope = cmProperty::TEST;
+ }
+ else if(args[0] == "VARIABLE")
+ {
+ scope = cmProperty::VARIABLE;
+ }
+ else if (args[0] == "CACHED_VARIABLE")
+ {
+ scope = cmProperty::CACHED_VARIABLE;
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "given invalid scope " << args[0] << ". "
+ << "Valid scopes are "
+ << "GLOBAL, DIRECTORY, TARGET, SOURCE, "
+ << "TEST, VARIABLE, CACHED_VARIABLE.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+
+ // Parse remaining arguments.
+ bool inherited = false;
+ enum Doing { DoingNone, DoingProperty, DoingBrief, DoingFull };
+ Doing doing = DoingNone;
+ for(unsigned int i=1; i < args.size(); ++i)
+ {
+ if(args[i] == "PROPERTY")
+ {
+ doing = DoingProperty;
+ }
+ else if(args[i] == "BRIEF_DOCS")
+ {
+ doing = DoingBrief;
+ }
+ else if(args[i] == "FULL_DOCS")
+ {
+ doing = DoingFull;
+ }
+ else if(args[i] == "INHERITED")
+ {
+ doing = DoingNone;
+ inherited = true;
+ }
+ else if(doing == DoingProperty)
+ {
+ doing = DoingNone;
+ this->PropertyName = args[i];
+ }
+ else if(doing == DoingBrief)
+ {
+ this->BriefDocs += args[i];
+ }
+ else if(doing == DoingFull)
+ {
+ this->FullDocs += args[i];
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "given invalid argument \"" << args[i] << "\".";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+
+ // Make sure a property name was found.
+ if(this->PropertyName.empty())
+ {
+ this->SetError("not given a PROPERTY <name> argument.");
+ return false;
+ }
+
+ // Make sure documentation was given.
+ if(this->BriefDocs.empty())
+ {
+ this->SetError("not given a BRIEF_DOCS <brief-doc> argument.");
+ return false;
+ }
+ if(this->FullDocs.empty())
+ {
+ this->SetError("not given a FULL_DOCS <full-doc> argument.");
+ return false;
+ }
+
+ // Actually define the property.
+ this->Makefile->GetCMakeInstance()->DefineProperty
+ (this->PropertyName.c_str(), scope,
+ this->BriefDocs.c_str(), this->FullDocs.c_str(), inherited);
+
+ return true;
+}
+
diff --git a/Source/cmDefinePropertyCommand.h b/Source/cmDefinePropertyCommand.h
new file mode 100644
index 000000000..55ef52137
--- /dev/null
+++ b/Source/cmDefinePropertyCommand.h
@@ -0,0 +1,93 @@
+/*============================================================================
+ 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 cmDefinesPropertyCommand_h
+#define cmDefinesPropertyCommand_h
+
+#include "cmCommand.h"
+
+class cmDefinePropertyCommand : public cmCommand
+{
+public:
+ virtual cmCommand* Clone()
+ {
+ return new cmDefinePropertyCommand;
+ }
+
+ /**
+ * This is called when the command is first encountered in
+ * the input file.
+ */
+ 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 "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.";
+ }
+
+ cmTypeMacro(cmDefinePropertyCommand, cmCommand);
+private:
+ std::string PropertyName;
+ std::string BriefDocs;
+ std::string FullDocs;
+};
+
+
+
+#endif
diff --git a/Source/cmDefinitions.cxx b/Source/cmDefinitions.cxx
new file mode 100644
index 000000000..9d2870058
--- /dev/null
+++ b/Source/cmDefinitions.cxx
@@ -0,0 +1,178 @@
+/*============================================================================
+ 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 "cmDefinitions.h"
+
+//----------------------------------------------------------------------------
+cmDefinitions::Def cmDefinitions::NoDef;
+
+//----------------------------------------------------------------------------
+cmDefinitions::cmDefinitions(cmDefinitions* parent): Up(parent)
+{
+}
+
+//----------------------------------------------------------------------------
+void cmDefinitions::Reset(cmDefinitions* parent)
+{
+ this->Up = parent;
+ this->Map.clear();
+}
+
+//----------------------------------------------------------------------------
+cmDefinitions::Def const&
+cmDefinitions::GetInternal(const char* key)
+{
+ MapType::const_iterator i = this->Map.find(key);
+ if(i != this->Map.end())
+ {
+ return i->second;
+ }
+ else if(cmDefinitions* up = this->Up)
+ {
+ // 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 this->NoDef;
+}
+
+//----------------------------------------------------------------------------
+cmDefinitions::Def const&
+cmDefinitions::SetInternal(const char* key, Def const& def)
+{
+ if(this->Up || def.Exists)
+ {
+ // 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;
+ }
+}
+
+//----------------------------------------------------------------------------
+const char* cmDefinitions::Get(const char* key)
+{
+ Def const& def = this->GetInternal(key);
+ return def.Exists? def.c_str() : 0;
+}
+
+//----------------------------------------------------------------------------
+const char* cmDefinitions::Set(const char* key, const char* value)
+{
+ Def const& def = this->SetInternal(key, Def(value));
+ return def.Exists? def.c_str() : 0;
+}
+
+//----------------------------------------------------------------------------
+std::set<cmStdString> cmDefinitions::LocalKeys() const
+{
+ std::set<cmStdString> keys;
+ // Consider local definitions.
+ for(MapType::const_iterator mi = this->Map.begin();
+ mi != this->Map.end(); ++mi)
+ {
+ if (mi->second.Exists)
+ {
+ keys.insert(mi->first);
+ }
+ }
+ return keys;
+}
+
+//----------------------------------------------------------------------------
+cmDefinitions cmDefinitions::Closure() const
+{
+ return cmDefinitions(ClosureTag(), this);
+}
+
+//----------------------------------------------------------------------------
+cmDefinitions::cmDefinitions(ClosureTag const&, cmDefinitions const* root):
+ Up(0)
+{
+ std::set<cmStdString> undefined;
+ this->ClosureImpl(undefined, root);
+}
+
+//----------------------------------------------------------------------------
+void cmDefinitions::ClosureImpl(std::set<cmStdString>& undefined,
+ cmDefinitions const* defs)
+{
+ // Consider local definitions.
+ for(MapType::const_iterator mi = defs->Map.begin();
+ mi != defs->Map.end(); ++mi)
+ {
+ // 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())
+ {
+ if(mi->second.Exists)
+ {
+ this->Map.insert(*mi);
+ }
+ else
+ {
+ undefined.insert(mi->first);
+ }
+ }
+ }
+
+ // Traverse parents.
+ if(cmDefinitions const* up = defs->Up)
+ {
+ this->ClosureImpl(undefined, up);
+ }
+}
+
+//----------------------------------------------------------------------------
+std::set<cmStdString> cmDefinitions::ClosureKeys() const
+{
+ std::set<cmStdString> defined;
+ std::set<cmStdString> undefined;
+ this->ClosureKeys(defined, undefined);
+ return 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)
+ {
+ // Use this key if it is not already set or unset.
+ if(defined.find(mi->first) == defined.end() &&
+ undefined.find(mi->first) == undefined.end())
+ {
+ std::set<cmStdString>& m = mi->second.Exists? defined : undefined;
+ m.insert(mi->first);
+ }
+ }
+
+ // Traverse parents.
+ if(cmDefinitions const* up = this->Up)
+ {
+ up->ClosureKeys(defined, undefined);
+ }
+}
diff --git a/Source/cmDefinitions.h b/Source/cmDefinitions.h
new file mode 100644
index 000000000..4834d8443
--- /dev/null
+++ b/Source/cmDefinitions.h
@@ -0,0 +1,86 @@
+/*============================================================================
+ 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 cmDefinitions_h
+#define cmDefinitions_h
+
+#include "cmStandardIncludes.h"
+
+/** \class cmDefinitions
+ * \brief Store a scope of variable definitions for CMake language.
+ *
+ * This stores the state of variable definitions (set or unset) for
+ * one scope. Sets are always local. Gets search parent scopes
+ * transitively and save results locally.
+ */
+class cmDefinitions
+{
+public:
+ /** Construct with the given parent scope. */
+ cmDefinitions(cmDefinitions* parent = 0);
+
+ /** Reset object as if newly constructed. */
+ void Reset(cmDefinitions* parent = 0);
+
+ /** Returns the parent scope, if any. */
+ cmDefinitions* GetParent() const { return this->Up; }
+
+ /** 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);
+
+ /** Set (or unset if null) a value associated with a key. */
+ const char* Set(const char* key, const char* value);
+
+ /** Get the set of all local keys. */
+ std::set<cmStdString> LocalKeys() const;
+
+ /** Compute the closure of all defined keys with values.
+ This flattens the scope. The result has no parent. */
+ cmDefinitions Closure() const;
+
+ /** Compute the set of all defined keys. */
+ std::set<cmStdString> ClosureKeys() const;
+
+private:
+ // String with existence boolean.
+ struct Def: public cmStdString
+ {
+ Def(): cmStdString(), Exists(false) {}
+ Def(const char* v): cmStdString(v?v:""), Exists(v?true:false) {}
+ Def(Def const& d): cmStdString(d), Exists(d.Exists) {}
+ bool Exists;
+ };
+ static Def NoDef;
+
+ // Parent scope, if any.
+ cmDefinitions* Up;
+
+ // Local definitions, set or unset.
+ typedef std::map<cmStdString, Def> MapType;
+ 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;
+};
+
+#endif
diff --git a/Source/cmDepends.cxx b/Source/cmDepends.cxx
new file mode 100644
index 000000000..9296d4cca
--- /dev/null
+++ b/Source/cmDepends.cxx
@@ -0,0 +1,286 @@
+/*============================================================================
+ 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 "cmDepends.h"
+
+#include "cmLocalGenerator.h"
+#include "cmMakefile.h"
+#include "cmGeneratedFileStream.h"
+#include "cmSystemTools.h"
+#include "cmFileTimeComparison.h"
+#include <string.h>
+
+//----------------------------------------------------------------------------
+cmDepends::cmDepends(cmLocalGenerator* lg, const char* targetDir):
+ CompileDirectory(),
+ LocalGenerator(lg),
+ Verbose(false),
+ FileComparison(0),
+ TargetDirectory(targetDir),
+ MaxPath(16384),
+ Dependee(new char[MaxPath]),
+ Depender(new char[MaxPath])
+{
+}
+
+//----------------------------------------------------------------------------
+cmDepends::~cmDepends()
+{
+ delete [] this->Dependee;
+ delete [] this->Depender;
+}
+
+//----------------------------------------------------------------------------
+bool cmDepends::Write(std::ostream &makeDepends,
+ std::ostream &internalDepends)
+{
+ // Lookup the set of sources to scan.
+ std::string srcLang = "CMAKE_DEPENDS_CHECK_";
+ srcLang += this->Language;
+ cmMakefile* mf = this->LocalGenerator->GetMakefile();
+ const char* srcStr = mf->GetSafeDefinition(srcLang.c_str());
+ std::vector<std::string> pairs;
+ cmSystemTools::ExpandListArgument(srcStr, pairs);
+
+ for(std::vector<std::string>::iterator si = pairs.begin();
+ si != pairs.end();)
+ {
+ // 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);
+
+ // Write the dependencies for this pair.
+ if(!this->WriteDependencies(src.c_str(), obj.c_str(),
+ makeDepends, internalDepends))
+ {
+ return false;
+ }
+ }
+
+ return this->Finalize(makeDepends, internalDepends);
+}
+
+//----------------------------------------------------------------------------
+bool cmDepends::Finalize(std::ostream&,
+ std::ostream&)
+{
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmDepends::Check(const char *makeFile, const char *internalFile,
+ std::map<std::string, DependencyVector>& validDeps)
+{
+ // Dependency checks must be done in proper working directory.
+ std::string oldcwd = ".";
+ if(this->CompileDirectory != ".")
+ {
+ // 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());
+ }
+
+ // Check whether dependencies must be regenerated.
+ bool okay = true;
+ std::ifstream fin(internalFile);
+ if(!(fin && this->CheckDependencies(fin, validDeps)))
+ {
+ // Clear all dependencies so they will be regenerated.
+ this->Clear(makeFile);
+ cmSystemTools::RemoveFile(internalFile);
+ okay = false;
+ }
+
+ // Restore working directory.
+ if(oldcwd != ".")
+ {
+ cmSystemTools::ChangeDirectory(oldcwd.c_str());
+ }
+
+ return okay;
+}
+
+//----------------------------------------------------------------------------
+void cmDepends::Clear(const char *file)
+{
+ // Print verbose output.
+ if(this->Verbose)
+ {
+ cmOStringStream msg;
+ msg << "Clearing dependencies in \"" << file << "\"." << std::endl;
+ cmSystemTools::Stdout(msg.str().c_str());
+ }
+
+ // Write an empty dependency file.
+ cmGeneratedFileStream depFileStream(file);
+ depFileStream
+ << "# Empty dependencies file\n"
+ << "# This may be replaced when dependencies are built." << std::endl;
+}
+
+//----------------------------------------------------------------------------
+bool cmDepends::WriteDependencies(const char*, const char*,
+ std::ostream&, std::ostream&)
+{
+ // This should be implemented by the subclass.
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmDepends::CheckDependencies(std::istream& internalDepends,
+ std::map<std::string, DependencyVector>& validDeps)
+{
+ // Parse dependencies from the stream. If any dependee is missing
+ // or newer than the depender then dependencies should be
+ // regenerated.
+ bool okay = true;
+ bool dependerExists = false;
+ DependencyVector* currentDependencies = 0;
+
+ while(internalDepends.getline(this->Dependee, this->MaxPath))
+ {
+ if ( this->Dependee[0] == 0 || this->Dependee[0] == '#' ||
+ this->Dependee[0] == '\r' )
+ {
+ continue;
+ }
+ size_t len = internalDepends.gcount()-1;
+ if ( this->Dependee[len-1] == '\r' )
+ {
+ len --;
+ this->Dependee[len] = 0;
+ }
+ if ( this->Dependee[0] != ' ' )
+ {
+ memcpy(this->Depender, this->Dependee, len+1);
+ // Calling FileExists() for the depender here saves in many cases 50%
+ // of the calls to FileExists() further down in the loop. E.g. for
+ // kdelibs/khtml this reduces the number of calls from 184k down to 92k,
+ // or the time for cmake -E cmake_depends from 0.3 s down to 0.21 s.
+ dependerExists = cmSystemTools::FileExists(this->Depender);
+ DependencyVector tmp;
+ validDeps[this->Depender] = tmp;
+ currentDependencies = &validDeps[this->Depender];
+ continue;
+ }
+ /*
+ // Parse the dependency line.
+ if(!this->ParseDependency(line.c_str()))
+ {
+ continue;
+ }
+ */
+
+ // Dependencies must be regenerated if the dependee does not exist
+ // or if the depender exists and is older than the dependee.
+ bool regenerate = false;
+ const char* dependee = this->Dependee+1;
+ const char* depender = this->Depender;
+ if (currentDependencies != 0)
+ {
+ currentDependencies->push_back(dependee);
+ }
+
+ if(!cmSystemTools::FileExists(dependee))
+ {
+ // The dependee does not exist.
+ regenerate = true;
+
+ // Print verbose output.
+ if(this->Verbose)
+ {
+ cmOStringStream msg;
+ msg << "Dependee \"" << dependee
+ << "\" does not exist for depender \""
+ << depender << "\"." << std::endl;
+ cmSystemTools::Stdout(msg.str().c_str());
+ }
+ }
+ else if(dependerExists)
+ {
+ // The dependee and depender both exist. Compare file times.
+ int result = 0;
+ if((!this->FileComparison->FileTimeCompare(depender, dependee,
+ &result) || result < 0))
+ {
+ // The depender is older than the dependee.
+ regenerate = true;
+
+ // Print verbose output.
+ if(this->Verbose)
+ {
+ cmOStringStream msg;
+ msg << "Dependee \"" << dependee
+ << "\" is newer than depender \""
+ << depender << "\"." << std::endl;
+ cmSystemTools::Stdout(msg.str().c_str());
+ }
+ }
+ }
+ if(regenerate)
+ {
+ // Dependencies must be regenerated.
+ okay = false;
+
+ // Remove the information of this depender from the map, it needs
+ // to be rescanned
+ if (currentDependencies != 0)
+ {
+ validDeps.erase(this->Depender);
+ currentDependencies = 0;
+ }
+
+ // Remove the depender to be sure it is rebuilt.
+ if (dependerExists)
+ {
+ cmSystemTools::RemoveFile(depender);
+ dependerExists = false;
+ }
+ }
+ }
+
+ return okay;
+}
+
+//----------------------------------------------------------------------------
+void cmDepends::SetIncludePathFromLanguage(const char* lang)
+{
+ // Look for the new per "TARGET_" variant first:
+ const char * includePath = 0;
+ std::string includePathVar = "CMAKE_";
+ includePathVar += lang;
+ includePathVar += "_TARGET_INCLUDE_PATH";
+ cmMakefile* mf = this->LocalGenerator->GetMakefile();
+ includePath = mf->GetDefinition(includePathVar.c_str());
+ if(includePath)
+ {
+ cmSystemTools::ExpandListArgument(includePath, this->IncludePath);
+ }
+ else
+ {
+ // Fallback to the old directory level variable if no per-target var:
+ includePathVar = "CMAKE_";
+ includePathVar += lang;
+ includePathVar += "_INCLUDE_PATH";
+ includePath = mf->GetDefinition(includePathVar.c_str());
+ if(includePath)
+ {
+ cmSystemTools::ExpandListArgument(includePath, this->IncludePath);
+ }
+ }
+}
diff --git a/Source/cmDepends.h b/Source/cmDepends.h
new file mode 100644
index 000000000..087da6400
--- /dev/null
+++ b/Source/cmDepends.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 cmDepends_h
+#define cmDepends_h
+
+#include "cmStandardIncludes.h"
+
+class cmFileTimeComparison;
+class cmLocalGenerator;
+
+/** \class cmDepends
+ * \brief Dependency scanner superclass.
+ *
+ * This class is responsible for maintaining a .depends.make file in
+ * the build tree corresponding to an object file. Subclasses help it
+ * maintain dependencies for particular languages.
+ */
+class cmDepends
+{
+public:
+ /** Instances need to know the build directory name and the relative
+ path from the build directory to the target file. */
+ cmDepends(cmLocalGenerator* lg=0, const char* targetDir="");
+
+ /** at what level will the compile be done from */
+ 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
+ has been setup to do relative path conversions for the current
+ directory. */
+ void SetLocalGenerator(cmLocalGenerator* lg) { this->LocalGenerator = lg; }
+
+ /** Set the specific language to be scanned. */
+ void SetLanguage(const char* lang) { this->Language = lang; }
+
+ /** Set the target build directory. */
+ void SetTargetDirectory(const char* dir) { this->TargetDirectory = dir; }
+
+ /** should this be verbose in its output */
+ void SetVerbose(bool verb) { this->Verbose = verb; }
+
+ /** Virtual destructor to cleanup subclasses properly. */
+ virtual ~cmDepends();
+
+ /** Write dependencies for the target file. */
+ bool Write(std::ostream &makeDepends, std::ostream &internalDepends);
+
+ class DependencyVector: public std::vector<std::string> {};
+
+ /** Check dependencies for the target file. Returns true if
+ dependencies are okay and false if they must be generated. If
+ they must be generated Clear has already been called to wipe out
+ the old dependencies.
+ Dependencies which are still valid will be stored in validDeps. */
+ bool Check(const char *makeFile, const char* internalFile,
+ std::map<std::string, DependencyVector>& validDeps);
+
+ /** Clear dependencies for the target file so they will be regenerated. */
+ void Clear(const char *file);
+
+ /** Set the file comparison object */
+ void SetFileComparison(cmFileTimeComparison* fc) {
+ this->FileComparison = fc; }
+
+protected:
+
+ // Write dependencies for the target file to the given stream.
+ // Return true for success and false for failure.
+ virtual bool WriteDependencies(const char *src, const char* obj,
+ std::ostream& makeDepends, std::ostream& internalDepends);
+
+ // Check dependencies for the target file in the given stream.
+ // Return false if dependencies must be regenerated and true
+ // otherwise.
+ virtual bool CheckDependencies(std::istream& internalDepends,
+ std::map<std::string, DependencyVector>& validDeps);
+
+ // Finalize the dependency information for the target.
+ virtual bool Finalize(std::ostream& makeDepends,
+ std::ostream& internalDepends);
+
+ // The directory in which the build rule for the target file is executed.
+ std::string CompileDirectory;
+
+ // The local generator.
+ cmLocalGenerator* LocalGenerator;
+
+ // Flag for verbose output.
+ bool Verbose;
+ cmFileTimeComparison* FileComparison;
+
+ std::string Language;
+
+ // The full path to the target's build directory.
+ std::string TargetDirectory;
+
+ size_t MaxPath;
+ char* Dependee;
+ char* Depender;
+
+ // The include file search path.
+ std::vector<std::string> IncludePath;
+
+ void SetIncludePathFromLanguage(const char* lang);
+
+private:
+ cmDepends(cmDepends const&); // Purposely not implemented.
+ void operator=(cmDepends const&); // Purposely not implemented.
+};
+
+#endif
diff --git a/Source/cmDependsC.cxx b/Source/cmDependsC.cxx
new file mode 100644
index 000000000..44841a900
--- /dev/null
+++ b/Source/cmDependsC.cxx
@@ -0,0 +1,581 @@
+/*============================================================================
+ 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 "cmDependsC.h"
+
+#include "cmFileTimeComparison.h"
+#include "cmLocalGenerator.h"
+#include "cmMakefile.h"
+#include "cmSystemTools.h"
+
+#include <ctype.h> // isspace
+
+
+#define INCLUDE_REGEX_LINE \
+ "^[ \t]*#[ \t]*(include|import)[ \t]*[<\"]([^\">]+)([\">])"
+
+#define INCLUDE_REGEX_LINE_MARKER "#IncludeRegexLine: "
+#define INCLUDE_REGEX_SCAN_MARKER "#IncludeRegexScan: "
+#define INCLUDE_REGEX_COMPLAIN_MARKER "#IncludeRegexComplain: "
+#define INCLUDE_REGEX_TRANSFORM_MARKER "#IncludeRegexTransform: "
+
+//----------------------------------------------------------------------------
+cmDependsC::cmDependsC()
+: ValidDeps(0)
+{
+}
+
+//----------------------------------------------------------------------------
+cmDependsC::cmDependsC(cmLocalGenerator* lg,
+ const char* targetDir,
+ const char* lang,
+ const std::map<std::string, DependencyVector>* validDeps)
+: cmDepends(lg, targetDir)
+, ValidDeps(validDeps)
+{
+ cmMakefile* mf = lg->GetMakefile();
+
+ // Configure the include file search path.
+ this->SetIncludePathFromLanguage(lang);
+
+ // Configure regular expressions.
+ std::string scanRegex = "^.*$";
+ std::string complainRegex = "^$";
+ {
+ std::string scanRegexVar = "CMAKE_";
+ scanRegexVar += lang;
+ scanRegexVar += "_INCLUDE_REGEX_SCAN";
+ if(const char* sr = mf->GetDefinition(scanRegexVar.c_str()))
+ {
+ scanRegex = sr;
+ }
+ std::string complainRegexVar = "CMAKE_";
+ complainRegexVar += lang;
+ complainRegexVar += "_INCLUDE_REGEX_COMPLAIN";
+ if(const char* cr = mf->GetDefinition(complainRegexVar.c_str()))
+ {
+ complainRegex = cr;
+ }
+ }
+
+ this->IncludeRegexLine.compile(INCLUDE_REGEX_LINE);
+ this->IncludeRegexScan.compile(scanRegex.c_str());
+ this->IncludeRegexComplain.compile(complainRegex.c_str());
+ this->IncludeRegexLineString = INCLUDE_REGEX_LINE_MARKER INCLUDE_REGEX_LINE;
+ this->IncludeRegexScanString = INCLUDE_REGEX_SCAN_MARKER;
+ this->IncludeRegexScanString += scanRegex;
+ this->IncludeRegexComplainString = INCLUDE_REGEX_COMPLAIN_MARKER;
+ this->IncludeRegexComplainString += complainRegex;
+
+ this->SetupTransforms();
+
+ this->CacheFileName = this->TargetDirectory;
+ this->CacheFileName += "/";
+ this->CacheFileName += lang;
+ this->CacheFileName += ".includecache";
+
+ this->ReadCacheFile();
+}
+
+//----------------------------------------------------------------------------
+cmDependsC::~cmDependsC()
+{
+ this->WriteCacheFile();
+
+ for (std::map<cmStdString, cmIncludeLines*>::iterator it=
+ this->FileCache.begin(); it!=this->FileCache.end(); ++it)
+ {
+ delete it->second;
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmDependsC::WriteDependencies(const char *src, const char *obj,
+ std::ostream& makeDepends, std::ostream& internalDepends)
+{
+ // Make sure this is a scanning instance.
+ if(!src || src[0] == '\0')
+ {
+ cmSystemTools::Error("Cannot scan dependencies without a source file.");
+ return false;
+ }
+ if(!obj || obj[0] == '\0')
+ {
+ cmSystemTools::Error("Cannot scan dependencies without an object file.");
+ return false;
+ }
+
+ if (this->ValidDeps != 0)
+ {
+ std::map<std::string, DependencyVector>::const_iterator tmpIt =
+ this->ValidDeps->find(obj);
+ if (tmpIt!= this->ValidDeps->end())
+ {
+ // Write the dependencies to the output stream. Makefile rules
+ // 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(DependencyVector::const_iterator i=tmpIt->second.begin();
+ i != tmpIt->second.end(); ++i)
+ {
+ makeDepends << obj << ": " <<
+ this->LocalGenerator->Convert(i->c_str(),
+ cmLocalGenerator::HOME_OUTPUT,
+ cmLocalGenerator::MAKEFILE)
+ << std::endl;
+ internalDepends << " " << i->c_str() << std::endl;
+ }
+ makeDepends << std::endl;
+ return true;
+ }
+ }
+
+ // Walk the dependency graph starting with the source file.
+ bool first = true;
+ UnscannedEntry root;
+ root.FileName = src;
+ this->Unscanned.push(root);
+ this->Encountered.clear();
+ this->Encountered.insert(src);
+ std::set<cmStdString> dependencies;
+ std::set<cmStdString> scanned;
+
+ // Use reserve to allocate enough memory for tempPathStr
+ // so that during the loops no memory is allocated or freed
+ std::string tempPathStr;
+ tempPathStr.reserve(4*1024);
+
+ while(!this->Unscanned.empty())
+ {
+ // Get the next file to scan.
+ UnscannedEntry current = this->Unscanned.front();
+ this->Unscanned.pop();
+
+ // If not a full path, find the file in the include path.
+ std::string fullName;
+ if(first || cmSystemTools::FileIsFullPath(current.FileName.c_str()))
+ {
+ if(cmSystemTools::FileExists(current.FileName.c_str(), true))
+ {
+ fullName = current.FileName;
+ }
+ }
+ else if(!current.QuotedLocation.empty() &&
+ cmSystemTools::FileExists(current.QuotedLocation.c_str(), true))
+ {
+ // The include statement producing this entry was a double-quote
+ // include and the included file is present in the directory of
+ // the source containing the include statement.
+ fullName = current.QuotedLocation;
+ }
+ else
+ {
+ std::map<cmStdString, cmStdString>::iterator
+ headerLocationIt=this->HeaderLocationCache.find(current.FileName);
+ if (headerLocationIt!=this->HeaderLocationCache.end())
+ {
+ fullName=headerLocationIt->second;
+ }
+ else for(std::vector<std::string>::const_iterator i =
+ this->IncludePath.begin(); i != this->IncludePath.end(); ++i)
+ {
+ // Construct the name of the file as if it were in the current
+ // include directory. Avoid using a leading "./".
+
+ tempPathStr = "";
+ if((*i) == ".")
+ {
+ tempPathStr += current.FileName;
+ }
+ else
+ {
+ tempPathStr += *i;
+ tempPathStr+="/";
+ tempPathStr+=current.FileName;
+ }
+
+ // Look for the file in this location.
+ if(cmSystemTools::FileExists(tempPathStr.c_str(), true))
+ {
+ fullName = tempPathStr;
+ HeaderLocationCache[current.FileName]=fullName;
+ break;
+ }
+ }
+ }
+
+ // Complain if the file cannot be found and matches the complain
+ // regex.
+ if(fullName.empty() &&
+ this->IncludeRegexComplain.find(current.FileName.c_str()))
+ {
+ cmSystemTools::Error("Cannot find file \"",
+ current.FileName.c_str(), "\".");
+ return false;
+ }
+
+ // Scan the file if it was found and has not been scanned already.
+ if(!fullName.empty() && (scanned.find(fullName) == scanned.end()))
+ {
+ // Record scanned files.
+ scanned.insert(fullName);
+
+ // Check whether this file is already in the cache
+ std::map<cmStdString, cmIncludeLines*>::iterator fileIt=
+ this->FileCache.find(fullName);
+ if (fileIt!=this->FileCache.end())
+ {
+ fileIt->second->Used=true;
+ dependencies.insert(fullName);
+ for (std::vector<UnscannedEntry>::const_iterator incIt=
+ fileIt->second->UnscannedEntries.begin();
+ incIt!=fileIt->second->UnscannedEntries.end(); ++incIt)
+ {
+ if (this->Encountered.find(incIt->FileName) ==
+ this->Encountered.end())
+ {
+ this->Encountered.insert(incIt->FileName);
+ this->Unscanned.push(*incIt);
+ }
+ }
+ }
+ else
+ {
+
+ // Try to scan the file. Just leave it out if we cannot find
+ // it.
+ std::ifstream fin(fullName.c_str());
+ if(fin)
+ {
+ // 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);
+ }
+ }
+ }
+
+ first = false;
+ }
+
+ // Write the dependencies to the output stream. Makefile rules
+ // 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>::iterator i=dependencies.begin();
+ i != dependencies.end(); ++i)
+ {
+ makeDepends << obj << ": " <<
+ this->LocalGenerator->Convert(i->c_str(),
+ cmLocalGenerator::HOME_OUTPUT,
+ cmLocalGenerator::MAKEFILE)
+ << std::endl;
+ internalDepends << " " << i->c_str() << std::endl;
+ }
+ makeDepends << std::endl;
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+void cmDependsC::ReadCacheFile()
+{
+ if(this->CacheFileName.size() == 0)
+ {
+ return;
+ }
+ std::ifstream fin(this->CacheFileName.c_str());
+ if(!fin)
+ {
+ return;
+ }
+
+ std::string line;
+ cmIncludeLines* cacheEntry=0;
+ bool haveFileName=false;
+
+ while(cmSystemTools::GetLineFromStream(fin, line))
+ {
+ if (line.empty())
+ {
+ cacheEntry=0;
+ haveFileName=false;
+ continue;
+ }
+ //the first line after an empty line is the name of the parsed file
+ if (haveFileName==false)
+ {
+ haveFileName=true;
+ int newer=0;
+ cmFileTimeComparison comp;
+ bool res=comp.FileTimeCompare(this->CacheFileName.c_str(),
+ line.c_str(), &newer);
+
+ if ((res==true) && (newer==1)) //cache is newer than the parsed file
+ {
+ cacheEntry=new cmIncludeLines;
+ this->FileCache[line]=cacheEntry;
+ }
+ // file doesn't exist, check that the regular expressions
+ // haven't changed
+ else if (res==false)
+ {
+ if (line.find(INCLUDE_REGEX_LINE_MARKER) == 0)
+ {
+ if (line != this->IncludeRegexLineString)
+ {
+ return;
+ }
+ }
+ else if (line.find(INCLUDE_REGEX_SCAN_MARKER) == 0)
+ {
+ if (line != this->IncludeRegexScanString)
+ {
+ return;
+ }
+ }
+ else if (line.find(INCLUDE_REGEX_COMPLAIN_MARKER) == 0)
+ {
+ if (line != this->IncludeRegexComplainString)
+ {
+ return;
+ }
+ }
+ else if (line.find(INCLUDE_REGEX_TRANSFORM_MARKER) == 0)
+ {
+ if (line != this->IncludeRegexTransformString)
+ {
+ return;
+ }
+ }
+ }
+ }
+ else if (cacheEntry!=0)
+ {
+ UnscannedEntry entry;
+ entry.FileName = line;
+ if (cmSystemTools::GetLineFromStream(fin, line))
+ {
+ if (line!="-")
+ {
+ entry.QuotedLocation=line;
+ }
+ cacheEntry->UnscannedEntries.push_back(entry);
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmDependsC::WriteCacheFile() const
+{
+ if(this->CacheFileName.size() == 0)
+ {
+ return;
+ }
+ std::ofstream cacheOut(this->CacheFileName.c_str());
+ if(!cacheOut)
+ {
+ return;
+ }
+
+ cacheOut << this->IncludeRegexLineString << "\n\n";
+ cacheOut << this->IncludeRegexScanString << "\n\n";
+ cacheOut << this->IncludeRegexComplainString << "\n\n";
+ cacheOut << this->IncludeRegexTransformString << "\n\n";
+
+ for (std::map<cmStdString, cmIncludeLines*>::const_iterator fileIt=
+ this->FileCache.begin();
+ fileIt!=this->FileCache.end(); ++fileIt)
+ {
+ if (fileIt->second->Used)
+ {
+ cacheOut<<fileIt->first.c_str()<<std::endl;
+
+ for (std::vector<UnscannedEntry>::const_iterator
+ incIt=fileIt->second->UnscannedEntries.begin();
+ incIt!=fileIt->second->UnscannedEntries.end(); ++incIt)
+ {
+ cacheOut<<incIt->FileName.c_str()<<std::endl;
+ if (incIt->QuotedLocation.empty())
+ {
+ cacheOut<<"-"<<std::endl;
+ }
+ else
+ {
+ cacheOut<<incIt->QuotedLocation.c_str()<<std::endl;
+ }
+ }
+ cacheOut<<std::endl;
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmDependsC::Scan(std::istream& is, const char* directory,
+ const cmStdString& fullName)
+{
+ cmIncludeLines* newCacheEntry=new cmIncludeLines;
+ newCacheEntry->Used=true;
+ this->FileCache[fullName]=newCacheEntry;
+
+ // Read one line at a time.
+ std::string line;
+ while(cmSystemTools::GetLineFromStream(is, line))
+ {
+ // Transform the line content first.
+ if(!this->TransformRules.empty())
+ {
+ this->TransformLine(line);
+ }
+
+ // Match include directives.
+ if(this->IncludeRegexLine.find(line.c_str()))
+ {
+ // Get the file being included.
+ UnscannedEntry entry;
+ entry.FileName = this->IncludeRegexLine.match(2);
+ cmSystemTools::ConvertToUnixSlashes(entry.FileName);
+ if(this->IncludeRegexLine.match(3) == "\"" &&
+ !cmSystemTools::FileIsFullPath(entry.FileName.c_str()))
+ {
+ // This was a double-quoted include with a relative path. We
+ // must check for the file in the directory containing the
+ // file we are scanning.
+ entry.QuotedLocation = directory;
+ entry.QuotedLocation += "/";
+ entry.QuotedLocation += entry.FileName;
+ }
+
+ // Queue the file if it has not yet been encountered and it
+ // matches the regular expression for recursive scanning. Note
+ // that this check does not account for the possibility of two
+ // headers with the same name in different directories when one
+ // is included by double-quotes and the other by angle brackets.
+ // It also does not work properly if two header files with the same
+ // name exist in different directories, and both are included from a
+ // file their own directory by simply using "filename.h" (#12619)
+ // This kind of problem will be fixed when a more
+ // preprocessor-like implementation of this scanner is created.
+ if (this->IncludeRegexScan.find(entry.FileName.c_str()))
+ {
+ newCacheEntry->UnscannedEntries.push_back(entry);
+ if(this->Encountered.find(entry.FileName) == this->Encountered.end())
+ {
+ this->Encountered.insert(entry.FileName);
+ this->Unscanned.push(entry);
+ }
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmDependsC::SetupTransforms()
+{
+ // Get the transformation rules.
+ std::vector<std::string> transformRules;
+ cmMakefile* mf = this->LocalGenerator->GetMakefile();
+ if(const char* xform =
+ mf->GetDefinition("CMAKE_INCLUDE_TRANSFORMS"))
+ {
+ cmSystemTools::ExpandListArgument(xform, transformRules, true);
+ }
+ for(std::vector<std::string>::const_iterator tri = transformRules.begin();
+ tri != transformRules.end(); ++tri)
+ {
+ this->ParseTransform(*tri);
+ }
+
+ this->IncludeRegexTransformString = INCLUDE_REGEX_TRANSFORM_MARKER;
+ if(!this->TransformRules.empty())
+ {
+ // Construct the regular expression to match lines to be
+ // transformed.
+ std::string xform = "^([ \t]*#[ \t]*(include|import)[ \t]*)(";
+ const char* sep = "";
+ for(TransformRulesType::const_iterator tri = this->TransformRules.begin();
+ tri != this->TransformRules.end(); ++tri)
+ {
+ xform += sep;
+ xform += tri->first;
+ sep = "|";
+ }
+ xform += ")[ \t]*\\(([^),]*)\\)";
+ this->IncludeRegexTransform.compile(xform.c_str());
+
+ // Build a string that encodes all transformation rules and will
+ // change when rules are changed.
+ this->IncludeRegexTransformString += xform;
+ for(TransformRulesType::const_iterator tri = this->TransformRules.begin();
+ tri != this->TransformRules.end(); ++tri)
+ {
+ this->IncludeRegexTransformString += " ";
+ this->IncludeRegexTransformString += tri->first;
+ this->IncludeRegexTransformString += "(%)=";
+ this->IncludeRegexTransformString += tri->second;
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmDependsC::ParseTransform(std::string const& xform)
+{
+ // A transform rule is of the form SOME_MACRO(%)=value-with-%
+ // We can simply separate with "(%)=".
+ std::string::size_type pos = xform.find("(%)=");
+ if(pos == xform.npos || pos == 0)
+ {
+ return;
+ }
+ std::string name = xform.substr(0, pos);
+ std::string value = xform.substr(pos+4, xform.npos);
+ this->TransformRules[name] = value;
+}
+
+//----------------------------------------------------------------------------
+void cmDependsC::TransformLine(std::string& line)
+{
+ // Check for a transform rule match. Return if none.
+ if(!this->IncludeRegexTransform.find(line.c_str()))
+ {
+ return;
+ }
+ TransformRulesType::const_iterator tri =
+ this->TransformRules.find(this->IncludeRegexTransform.match(3));
+ if(tri == this->TransformRules.end())
+ {
+ return;
+ }
+
+ // Construct the transformed line.
+ std::string newline = this->IncludeRegexTransform.match(1);
+ std::string arg = this->IncludeRegexTransform.match(4);
+ for(const char* c = tri->second.c_str(); *c; ++c)
+ {
+ if(*c == '%')
+ {
+ newline += arg;
+ }
+ else
+ {
+ newline += *c;
+ }
+ }
+
+ // Return the transformed line.
+ line = newline;
+}
diff --git a/Source/cmDependsC.h b/Source/cmDependsC.h
new file mode 100644
index 000000000..bd9a4b7b4
--- /dev/null
+++ b/Source/cmDependsC.h
@@ -0,0 +1,99 @@
+/*============================================================================
+ 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 cmDependsC_h
+#define cmDependsC_h
+
+#include "cmDepends.h"
+#include <cmsys/RegularExpression.hxx>
+#include <queue>
+
+/** \class cmDependsC
+ * \brief Dependency scanner for C and C++ object files.
+ */
+class cmDependsC: public cmDepends
+{
+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,
+ const std::map<std::string, DependencyVector>* validDeps);
+
+ /** Virtual destructor to cleanup subclasses properly. */
+ virtual ~cmDependsC();
+
+protected:
+ typedef std::vector<char> t_CharBuffer;
+
+ // Implement writing/checking methods required by superclass.
+ virtual bool WriteDependencies(const char *src,
+ const char *file,
+ std::ostream& makeDepends,
+ std::ostream& internalDepends);
+
+ // Method to scan a single file.
+ void Scan(std::istream& is, const char* directory,
+ const cmStdString& fullName);
+
+ // Regular expression to identify C preprocessor include directives.
+ cmsys::RegularExpression IncludeRegexLine;
+
+ // Regular expressions to choose which include files to scan
+ // recursively and which to complain about not finding.
+ cmsys::RegularExpression IncludeRegexScan;
+ cmsys::RegularExpression IncludeRegexComplain;
+ std::string IncludeRegexLineString;
+ std::string IncludeRegexScanString;
+ std::string IncludeRegexComplainString;
+
+ // Regex to transform #include lines.
+ std::string IncludeRegexTransformString;
+ cmsys::RegularExpression IncludeRegexTransform;
+ typedef std::map<cmStdString, cmStdString> TransformRulesType;
+ TransformRulesType TransformRules;
+ void SetupTransforms();
+ void ParseTransform(std::string const& xform);
+ void TransformLine(std::string& line);
+
+public:
+ // Data structures for dependency graph walk.
+ struct UnscannedEntry
+ {
+ cmStdString FileName;
+ cmStdString QuotedLocation;
+ };
+
+ struct cmIncludeLines
+ {
+ cmIncludeLines(): Used(false) {}
+ std::vector<UnscannedEntry> UnscannedEntries;
+ bool Used;
+ };
+protected:
+ const std::map<std::string, DependencyVector>* ValidDeps;
+ std::set<cmStdString> Encountered;
+ std::queue<UnscannedEntry> Unscanned;
+ t_CharBuffer Buffer;
+
+ std::map<cmStdString, cmIncludeLines *> FileCache;
+ std::map<cmStdString, cmStdString> HeaderLocationCache;
+
+ cmStdString CacheFileName;
+
+ void WriteCacheFile() const;
+ void ReadCacheFile();
+private:
+ cmDependsC(cmDependsC const&); // Purposely not implemented.
+ void operator=(cmDependsC const&); // Purposely not implemented.
+};
+
+#endif
diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx
new file mode 100644
index 000000000..c1b60905d
--- /dev/null
+++ b/Source/cmDependsFortran.cxx
@@ -0,0 +1,1258 @@
+/*============================================================================
+ 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 "cmDependsFortran.h"
+
+#include "cmSystemTools.h"
+#include "cmLocalGenerator.h"
+#include "cmMakefile.h"
+#include "cmGeneratedFileStream.h"
+
+#include "cmDependsFortranParser.h" /* Interface to parser object. */
+
+#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;
+
+ // Map modules required by this target to locations.
+ typedef std::map<cmStdString, cmStdString> TargetRequiresMap;
+ TargetRequiresMap TargetRequires;
+
+ // Information about each object file.
+ typedef std::map<cmStdString, cmDependsFortranSourceInfo> ObjectInfoMap;
+ ObjectInfoMap ObjectInfo;
+
+ cmDependsFortranSourceInfo& CreateObjectInfo(const char* obj,
+ const char* src)
+ {
+ std::map<cmStdString, cmDependsFortranSourceInfo>::iterator i =
+ this->ObjectInfo.find(obj);
+ if(i == this->ObjectInfo.end())
+ {
+ std::map<cmStdString, cmDependsFortranSourceInfo>::value_type
+ entry(obj, cmDependsFortranSourceInfo());
+ i = this->ObjectInfo.insert(entry).first;
+ i->second.Source = src;
+ }
+ return i->second;
+ }
+};
+
+//----------------------------------------------------------------------------
+cmDependsFortran::cmDependsFortran():
+ PPDefinitions(0), Internal(0)
+{
+}
+
+//----------------------------------------------------------------------------
+cmDependsFortran
+::cmDependsFortran(cmLocalGenerator* lg):
+ cmDepends(lg),
+ Internal(new cmDependsFortranInternals)
+{
+ // Configure the include file search path.
+ this->SetIncludePathFromLanguage("Fortran");
+
+ // Get the list of definitions.
+ std::vector<std::string> definitions;
+ cmMakefile* mf = this->LocalGenerator->GetMakefile();
+ if(const char* c_defines =
+ mf->GetDefinition("CMAKE_TARGET_DEFINITIONS"))
+ {
+ cmSystemTools::ExpandListArgument(c_defines, definitions);
+ }
+
+ // translate i.e. FOO=BAR to FOO and add it to the list of defined
+ // preprocessor symbols
+ for(std::vector<std::string>::const_iterator
+ it = definitions.begin(); it != definitions.end(); ++it)
+ {
+ std::string def = *it;
+ std::string::size_type assignment = def.find("=");
+ if(assignment != std::string::npos)
+ {
+ def = it->substr(0, assignment);
+ }
+ this->PPDefinitions.push_back(def);
+ }
+}
+
+//----------------------------------------------------------------------------
+cmDependsFortran::~cmDependsFortran()
+{
+ delete this->Internal;
+}
+
+//----------------------------------------------------------------------------
+bool cmDependsFortran::WriteDependencies(const char *src, const char *obj,
+ std::ostream&, std::ostream&)
+{
+ // Make sure this is a scanning instance.
+ if(!src || src[0] == '\0')
+ {
+ cmSystemTools::Error("Cannot scan dependencies without an source file.");
+ return false;
+ }
+ if(!obj || obj[0] == '\0')
+ {
+ cmSystemTools::Error("Cannot scan dependencies without an object file.");
+ return false;
+ }
+
+ // Get the information object for this source.
+ cmDependsFortranSourceInfo& info =
+ this->Internal->CreateObjectInfo(obj, src);
+
+ // 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);
+
+ // Push on the starting file.
+ cmDependsFortranParser_FilePush(&parser, src);
+
+ // Parse the translation unit.
+ if(cmDependsFortran_yyparse(parser.Scanner) != 0)
+ {
+ // Failed to parse the file. Report failure to write dependencies.
+ return false;
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmDependsFortran::Finalize(std::ostream& makeDepends,
+ std::ostream& internalDepends)
+{
+ // Prepare the module search process.
+ this->LocateModules();
+
+ // Get the directory in which stamp files will be stored.
+ 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
+ {
+ mod_dir =
+ this->LocalGenerator->GetMakefile()->GetCurrentOutputDirectory();
+ }
+
+ // Actually write dependencies to the streams.
+ typedef cmDependsFortranInternals::ObjectInfoMap ObjectInfoMap;
+ ObjectInfoMap const& objInfo = this->Internal->ObjectInfo;
+ for(ObjectInfoMap::const_iterator i = objInfo.begin();
+ i != objInfo.end(); ++i)
+ {
+ if(!this->WriteDependenciesReal(i->first.c_str(), i->second,
+ mod_dir, stamp_dir,
+ makeDepends, internalDepends))
+ {
+ return false;
+ }
+ }
+
+ // Store the list of modules provided by this target.
+ std::string fiName = this->TargetDirectory;
+ fiName += "/fortran.internal";
+ 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();
+ i != provides.end(); ++i)
+ {
+ fiStream << " " << *i << "\n";
+ }
+
+ // Create a script to clean the modules.
+ if(!provides.empty())
+ {
+ std::string fcName = this->TargetDirectory;
+ fcName += "/cmake_clean_Fortran.cmake";
+ 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();
+ i != provides.end(); ++i)
+ {
+ std::string mod_upper = mod_dir;
+ mod_upper += "/";
+ mod_upper += cmSystemTools::UpperCase(*i);
+ mod_upper += ".mod";
+ std::string mod_lower = mod_dir;
+ mod_lower += "/";
+ mod_lower += *i;
+ mod_lower += ".mod";
+ std::string stamp = stamp_dir;
+ stamp += "/";
+ stamp += *i;
+ stamp += ".mod.stamp";
+ fcStream << "\n";
+ fcStream << " \"" <<
+ this->LocalGenerator->Convert(mod_lower.c_str(),
+ cmLocalGenerator::START_OUTPUT)
+ << "\"\n";
+ fcStream << " \"" <<
+ this->LocalGenerator->Convert(mod_upper.c_str(),
+ cmLocalGenerator::START_OUTPUT)
+ << "\"\n";
+ fcStream << " \"" <<
+ this->LocalGenerator->Convert(stamp.c_str(),
+ cmLocalGenerator::START_OUTPUT)
+ << "\"\n";
+ }
+ fcStream << " )\n";
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+void cmDependsFortran::LocateModules()
+{
+ // Collect the set of modules provided and required by all sources.
+ typedef cmDependsFortranInternals::ObjectInfoMap ObjectInfoMap;
+ ObjectInfoMap const& objInfo = this->Internal->ObjectInfo;
+ 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);
+ }
+
+ for(std::set<cmStdString>::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] = "";
+ }
+ }
+
+ // Short-circuit for simple targets.
+ if(this->Internal->TargetRequires.empty())
+ {
+ return;
+ }
+
+ // Match modules provided by this target to those it requires.
+ this->MatchLocalModules();
+
+ // Load information about other targets.
+ cmMakefile* mf = this->LocalGenerator->GetMakefile();
+ std::vector<std::string> infoFiles;
+ if(const char* infoFilesValue =
+ mf->GetDefinition("CMAKE_TARGET_LINKED_INFO_FILES"))
+ {
+ cmSystemTools::ExpandListArgument(infoFilesValue, infoFiles);
+ }
+ for(std::vector<std::string>::const_iterator i = infoFiles.begin();
+ i != infoFiles.end(); ++i)
+ {
+ std::string targetDir = cmSystemTools::GetFilenamePath(*i);
+ std::string fname = targetDir + "/fortran.internal";
+ std::ifstream fin(fname.c_str());
+ if(fin)
+ {
+ this->MatchRemoteModules(fin, targetDir.c_str());
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+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();
+ i != provides.end(); ++i)
+ {
+ this->ConsiderModule(i->c_str(), stampDir);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmDependsFortran::MatchRemoteModules(std::istream& fin,
+ const char* stampDir)
+{
+ std::string line;
+ bool doing_provides = false;
+ while(cmSystemTools::GetLineFromStream(fin, line))
+ {
+ // Ignore comments and empty lines.
+ if(line.empty() || line[0] == '#' || line[0] == '\r')
+ {
+ continue;
+ }
+
+ if(line[0] == ' ')
+ {
+ if(doing_provides)
+ {
+ this->ConsiderModule(line.c_str()+1, stampDir);
+ }
+ }
+ else if(line == "provides")
+ {
+ doing_provides = true;
+ }
+ else
+ {
+ doing_provides = false;
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmDependsFortran::ConsiderModule(const char* name,
+ const char* stampDir)
+{
+ // Locate each required module.
+ typedef cmDependsFortranInternals::TargetRequiresMap TargetRequiresMap;
+ TargetRequiresMap::iterator required =
+ this->Internal->TargetRequires.find(name);
+ if(required != this->Internal->TargetRequires.end() &&
+ required->second.empty())
+ {
+ // The module is provided by a CMake target. It will have a stamp file.
+ std::string stampFile = stampDir;
+ stampFile += "/";
+ stampFile += name;
+ stampFile += ".mod.stamp";
+ required->second = stampFile;
+ }
+}
+
+//----------------------------------------------------------------------------
+bool
+cmDependsFortran
+::WriteDependenciesReal(const char *obj,
+ cmDependsFortranSourceInfo const& info,
+ const char* mod_dir, const char* stamp_dir,
+ std::ostream& makeDepends,
+ std::ostream& internalDepends)
+{
+ typedef cmDependsFortranInternals::TargetRequiresMap TargetRequiresMap;
+
+ // Get the source file for this object.
+ const char* src = info.Source.c_str();
+
+ // Write the include dependencies to the output stream.
+ internalDepends << obj << std::endl;
+ internalDepends << " " << src << std::endl;
+ for(std::set<cmStdString>::const_iterator i = info.Includes.begin();
+ i != info.Includes.end(); ++i)
+ {
+ makeDepends << obj << ": " <<
+ this->LocalGenerator->Convert(i->c_str(),
+ cmLocalGenerator::HOME_OUTPUT,
+ cmLocalGenerator::MAKEFILE)
+ << std::endl;
+ internalDepends << " " << i->c_str() << std::endl;
+ }
+ makeDepends << std::endl;
+
+ // Write module requirements to the output stream.
+ for(std::set<cmStdString>::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)) !=
+ info.Provides.end())
+ {
+ continue;
+ }
+
+ // If the module is provided in this target special handling is
+ // needed.
+ if(this->Internal->TargetProvides.find(*i) !=
+ this->Internal->TargetProvides.end())
+ {
+ // The module is provided by a different source in the same
+ // target. Add the proxy dependency to make sure the other
+ // source builds first.
+ std::string proxy = stamp_dir;
+ proxy += "/";
+ proxy += *i;
+ proxy += ".mod.proxy";
+ proxy = this->LocalGenerator->Convert(proxy.c_str(),
+ cmLocalGenerator::HOME_OUTPUT,
+ cmLocalGenerator::MAKEFILE);
+
+ // since we require some things add them to our list of requirements
+ makeDepends << obj << ".requires: " << proxy << std::endl;
+ }
+
+ // The object file should depend on timestamped files for the
+ // modules it uses.
+ TargetRequiresMap::const_iterator required =
+ this->Internal->TargetRequires.find(*i);
+ if(required == this->Internal->TargetRequires.end()) { abort(); }
+ if(!required->second.empty())
+ {
+ // This module is known. Depend on its timestamp file.
+ std::string stampFile =
+ this->LocalGenerator->Convert(required->second.c_str(),
+ cmLocalGenerator::HOME_OUTPUT,
+ cmLocalGenerator::MAKEFILE);
+ makeDepends << obj << ": " << stampFile << "\n";
+ }
+ else
+ {
+ // This module is not known to CMake. Try to locate it where
+ // the compiler will and depend on that.
+ std::string module;
+ if(this->FindModule(*i, module))
+ {
+ module =
+ this->LocalGenerator->Convert(module.c_str(),
+ cmLocalGenerator::HOME_OUTPUT,
+ cmLocalGenerator::MAKEFILE);
+ makeDepends << obj << ": " << module << "\n";
+ }
+ }
+ }
+
+ // Write provided modules to the output stream.
+ for(std::set<cmStdString>::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(),
+ cmLocalGenerator::HOME_OUTPUT,
+ cmLocalGenerator::MAKEFILE);
+ makeDepends << proxy << ": " << obj << ".provides" << std::endl;
+ }
+
+ // If any modules are provided then they must be converted to stamp files.
+ if(!info.Provides.empty())
+ {
+ // 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();
+ i != info.Provides.end(); ++i)
+ {
+ // Include this module in the set provided by this target.
+ this->Internal->TargetProvides.insert(*i);
+
+ // Always use lower case for the mod stamp file name. The
+ // cmake_copy_f90_mod will call back to this class, which will
+ // try various cases for the real mod file name.
+ std::string m = cmSystemTools::LowerCase(*i);
+ std::string modFile = mod_dir;
+ modFile += "/";
+ modFile += *i;
+ modFile =
+ this->LocalGenerator->Convert(modFile.c_str(),
+ cmLocalGenerator::HOME_OUTPUT,
+ cmLocalGenerator::SHELL);
+ std::string stampFile = stamp_dir;
+ stampFile += "/";
+ stampFile += m;
+ stampFile += ".mod.stamp";
+ stampFile =
+ this->LocalGenerator->Convert(stampFile.c_str(),
+ cmLocalGenerator::HOME_OUTPUT,
+ cmLocalGenerator::SHELL);
+ makeDepends << "\t$(CMAKE_COMMAND) -E cmake_copy_f90_mod "
+ << modFile << " " << stampFile;
+ cmMakefile* mf = this->LocalGenerator->GetMakefile();
+ const char* cid = mf->GetDefinition("CMAKE_Fortran_COMPILER_ID");
+ if(cid && *cid)
+ {
+ makeDepends << " " << cid;
+ }
+ makeDepends << "\n";
+ }
+ // 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
+ << ".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(),
+ cmLocalGenerator::HOME_OUTPUT,
+ cmLocalGenerator::MAKEFILE);
+ makeDepends << driver << ": " << obj << ".provides.build\n";
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmDependsFortran::FindModule(std::string const& name,
+ std::string& module)
+{
+ // Construct possible names for the module file.
+ std::string mod_upper = cmSystemTools::UpperCase(name);
+ std::string mod_lower = name;
+ mod_upper += ".mod";
+ mod_lower += ".mod";
+
+ // Search the include path for the module.
+ std::string fullName;
+ for(std::vector<std::string>::const_iterator i =
+ this->IncludePath.begin(); i != this->IncludePath.end(); ++i)
+ {
+ // Try the lower-case name.
+ fullName = *i;
+ fullName += "/";
+ fullName += mod_lower;
+ if(cmSystemTools::FileExists(fullName.c_str(), true))
+ {
+ module = fullName;
+ return true;
+ }
+
+ // Try the upper-case name.
+ fullName = *i;
+ fullName += "/";
+ fullName += mod_upper;
+ if(cmSystemTools::FileExists(fullName.c_str(), true))
+ {
+ module = fullName;
+ return true;
+ }
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmDependsFortran::CopyModule(const std::vector<std::string>& args)
+{
+ // Implements
+ //
+ // $(CMAKE_COMMAND) -E cmake_copy_f90_mod input.mod output.mod.stamp
+ // [compiler-id]
+ //
+ // Note that the case of the .mod file depends on the compiler. In
+ // the future this copy could also account for the fact that some
+ // compilers include a timestamp in the .mod file so it changes even
+ // when the interface described in the module does not.
+
+ std::string mod = args[2];
+ std::string stamp = args[3];
+ std::string compilerId;
+ if(args.size() >= 5)
+ {
+ compilerId = args[4];
+ }
+ std::string mod_dir = cmSystemTools::GetFilenamePath(mod);
+ if(!mod_dir.empty()) { mod_dir += "/"; }
+ std::string mod_upper = mod_dir;
+ mod_upper += cmSystemTools::UpperCase(cmSystemTools::GetFilenameName(mod));
+ std::string mod_lower = mod_dir;
+ mod_lower += cmSystemTools::LowerCase(cmSystemTools::GetFilenameName(mod));
+ mod += ".mod";
+ mod_upper += ".mod";
+ mod_lower += ".mod";
+ if(cmSystemTools::FileExists(mod_upper.c_str(), true))
+ {
+ if(cmDependsFortran::ModulesDiffer(mod_upper.c_str(), stamp.c_str(),
+ compilerId.c_str()))
+ {
+ if(!cmSystemTools::CopyFileAlways(mod_upper.c_str(), stamp.c_str()))
+ {
+ std::cerr << "Error copying Fortran module from \""
+ << mod_upper.c_str() << "\" to \"" << stamp.c_str()
+ << "\".\n";
+ return false;
+ }
+ }
+ return true;
+ }
+ else if(cmSystemTools::FileExists(mod_lower.c_str(), true))
+ {
+ if(cmDependsFortran::ModulesDiffer(mod_lower.c_str(), stamp.c_str(),
+ compilerId.c_str()))
+ {
+ if(!cmSystemTools::CopyFileAlways(mod_lower.c_str(), stamp.c_str()))
+ {
+ std::cerr << "Error copying Fortran module from \""
+ << mod_lower.c_str() << "\" to \"" << stamp.c_str()
+ << "\".\n";
+ return false;
+ }
+ }
+ return true;
+ }
+
+ std::cerr << "Error copying Fortran module \"" << args[2].c_str()
+ << "\". Tried \"" << mod_upper.c_str()
+ << "\" and \"" << mod_lower.c_str() << "\".\n";
+ return false;
+}
+
+//----------------------------------------------------------------------------
+// Helper function to look for a short sequence in a stream. If this
+// 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,
+ const char* seq, int len)
+{
+ assert(len > 0);
+
+ int cur = 0;
+ while(cur < len)
+ {
+ // Get the next character.
+ int token = ifs.get();
+ if(!ifs)
+ {
+ return false;
+ }
+
+ // Check the character.
+ if(token == static_cast<int>(seq[cur]))
+ {
+ ++cur;
+ }
+ else
+ {
+ // Assume the sequence has no repeating subsequence.
+ cur = 0;
+ }
+ }
+
+ // The entire sequence was matched.
+ return true;
+}
+
+//----------------------------------------------------------------------------
+// Helper function to compare the remaining content in two streams.
+static bool cmDependsFortranStreamsDiffer(std::ifstream& ifs1,
+ std::ifstream& ifs2)
+{
+ // Compare the remaining content.
+ for(;;)
+ {
+ int ifs1_c = ifs1.get();
+ int ifs2_c = ifs2.get();
+ if(!ifs1 && !ifs2)
+ {
+ // We have reached the end of both streams simultaneously.
+ // The streams are identical.
+ return false;
+ }
+
+ if(!ifs1 || !ifs2 || ifs1_c != ifs2_c)
+ {
+ // We have reached the end of one stream before the other or
+ // found differing content. The streams are different.
+ break;
+ }
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmDependsFortran::ModulesDiffer(const char* modFile,
+ const char* stampFile,
+ const char* compilerId)
+{
+ /*
+ gnu:
+ 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
+ If you edit this, you'll get what you deserve.
+ ...
+ </bar.mod>
+ As you can see the first line contains the date.
+
+ intel:
+ A mod file is a binary file.
+ However, looking into both generated bar.mod files with a hex editor
+ shows that they differ only before a sequence linefeed-zero (0x0A 0x00)
+ which is located some bytes in front of the absoulte path to the source
+ file.
+
+ sun:
+ A mod file is a binary file. Compiling twice produces identical modules.
+
+ others:
+ TODO ...
+ */
+
+
+ /* Compilers which do _not_ produce different mod content when the same
+ * source is compiled twice
+ * -SunPro
+ */
+ if(strcmp(compilerId, "SunPro") == 0)
+ {
+ return cmSystemTools::FilesDiffer(modFile, stampFile);
+ }
+
+#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);
+#else
+ std::ifstream finModFile(modFile, std::ios::in);
+ std::ifstream finStampFile(stampFile, std::ios::in);
+#endif
+ if(!finModFile || !finStampFile)
+ {
+ // At least one of the files does not exist. The modules differ.
+ return true;
+ }
+
+ /* Compilers which _do_ produce different mod content when the same
+ * source is compiled twice
+ * -GNU
+ * -Intel
+ *
+ * Eat the stream content until all recompile only related changes
+ * are left behind.
+ */
+ if (strcmp(compilerId, "GNU") == 0 )
+ {
+ const char seq[1] = {'\n'};
+ const int seqlen = 1;
+
+ if(!cmDependsFortranStreamContainsSequence(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(!cmDependsFortranStreamContainsSequence(finStampFile, seq, seqlen))
+ {
+ // The stamp must differ if the sequence is not contained.
+ return true;
+ }
+ }
+ else if(strcmp(compilerId, "Intel") == 0)
+ {
+ const char seq[2] = {'\n', '\0'};
+ const int seqlen = 2;
+
+ if(!cmDependsFortranStreamContainsSequence(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(!cmDependsFortranStreamContainsSequence(finStampFile, seq, seqlen))
+ {
+ // The stamp must differ if the sequence is not contained.
+ return true;
+ }
+ }
+
+ // 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))
+ {
+ return false;
+ }
+
+ // 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
new file mode 100644
index 000000000..cdfde6ea9
--- /dev/null
+++ b/Source/cmDependsFortran.h
@@ -0,0 +1,92 @@
+/*============================================================================
+ 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_h
+#define cmDependsFortran_h
+
+#include "cmDepends.h"
+
+class cmDependsFortranInternals;
+class cmDependsFortranSourceInfo;
+
+/** \class cmDependsFortran
+ * \brief Dependency scanner for Fortran object files.
+ */
+class cmDependsFortran: public cmDepends
+{
+public:
+ /** Checking instances need to know the build directory name and the
+ relative path from the build directory to the target file. */
+ cmDependsFortran();
+
+ /** Scanning need to know the build directory name, the relative
+ path from the build directory to the target file, the source
+ file from which to start scanning, the include file search
+ path, and the target directory. */
+ cmDependsFortran(cmLocalGenerator* lg);
+
+ /** Virtual destructor to cleanup subclasses properly. */
+ virtual ~cmDependsFortran();
+
+ /** Callback from build system after a .mod file has been generated
+ by a Fortran90 compiler to copy the .mod file to the
+ corresponding stamp file. */
+ static bool CopyModule(const std::vector<std::string>& args);
+
+ /** Determine if a mod file and the corresponding mod.stamp file
+ are representing different module information. */
+ 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,
+ std::ostream& internalDepends);
+
+ // Find all the modules required by the target.
+ void LocateModules();
+ void MatchLocalModules();
+ void MatchRemoteModules(std::istream& fin, const char* stampDir);
+ void ConsiderModule(const char* name, const char* stampDir);
+ bool FindModule(std::string const& name, std::string& module);
+
+ // Implement writing/checking methods required by superclass.
+ virtual bool WriteDependencies(
+ const char *src, const char *file,
+ std::ostream& makeDepends, std::ostream& internalDepends);
+
+ // Actually write the depenencies to the streams.
+ bool WriteDependenciesReal(const char *obj,
+ cmDependsFortranSourceInfo const& info,
+ const char* 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;
+
+ // Internal implementation details.
+ cmDependsFortranInternals* Internal;
+
+private:
+ cmDependsFortran(cmDependsFortran const&); // Purposely not implemented.
+ void operator=(cmDependsFortran const&); // Purposely not implemented.
+};
+
+#endif
diff --git a/Source/cmDependsFortranLexer.cxx b/Source/cmDependsFortranLexer.cxx
new file mode 100644
index 000000000..b0d9a742d
--- /dev/null
+++ b/Source/cmDependsFortranLexer.cxx
@@ -0,0 +1,2414 @@
+/*============================================================================
+ 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
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp, *yy_bp;
+ register 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
+ {
+ register 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;
+ register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ register char *source = yyg->yytext_ptr;
+ register 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)
+{
+ register yy_state_type yy_current_state;
+ register 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 )
+ {
+ register 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)
+{
+ register int yy_is_jam;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */
+ register char *yy_cp = yyg->yy_c_buf_p;
+
+ register 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, register char * yy_bp , yyscan_t yyscanner)
+{
+ register 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. */
+ register int number_to_move = yyg->yy_n_chars + 2;
+ register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+ register 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)
+{
+ register 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)
+{
+ register 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
new file mode 100644
index 000000000..8e24cfd80
--- /dev/null
+++ b/Source/cmDependsFortranLexer.h
@@ -0,0 +1,348 @@
+/*============================================================================
+ 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
new file mode 100644
index 000000000..40e80b719
--- /dev/null
+++ b/Source/cmDependsFortranLexer.in.l
@@ -0,0 +1,189 @@
+%{
+/*============================================================================
+ 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"
+
+/*--------------------------------------------------------------------------*/
+%}
+
+
+%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
new file mode 100644
index 000000000..7b49a9c5c
--- /dev/null
+++ b/Source/cmDependsFortranParser.cxx
@@ -0,0 +1,2094 @@
+/* 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
new file mode 100644
index 000000000..399c3c8d9
--- /dev/null
+++ b/Source/cmDependsFortranParser.h
@@ -0,0 +1,96 @@
+/*============================================================================
+ 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
new file mode 100644
index 000000000..5681d698c
--- /dev/null
+++ b/Source/cmDependsFortranParser.y
@@ -0,0 +1,287 @@
+%{
+/*============================================================================
+ 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
+%}
+
+/* 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
new file mode 100644
index 000000000..941eda09c
--- /dev/null
+++ b/Source/cmDependsFortranParserTokens.h
@@ -0,0 +1,122 @@
+/* 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/cmDependsJava.cxx b/Source/cmDependsJava.cxx
new file mode 100644
index 000000000..1d849145c
--- /dev/null
+++ b/Source/cmDependsJava.cxx
@@ -0,0 +1,45 @@
+/*============================================================================
+ 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 "cmDependsJava.h"
+
+#include "cmDependsJavaParserHelper.h"
+#include "cmSystemTools.h"
+
+//----------------------------------------------------------------------------
+cmDependsJava::cmDependsJava()
+{
+}
+
+//----------------------------------------------------------------------------
+cmDependsJava::~cmDependsJava()
+{
+}
+
+//----------------------------------------------------------------------------
+bool cmDependsJava::WriteDependencies(const char *src, const char *,
+ std::ostream&, std::ostream&)
+{
+ // Make sure this is a scanning instance.
+ if(!src || src[0] == '\0')
+ {
+ cmSystemTools::Error("Cannot scan dependencies without an source file.");
+ return false;
+ }
+
+ return true;
+}
+
+bool cmDependsJava::CheckDependencies(std::istream&,
+ std::map<std::string, DependencyVector >&)
+{
+ return true;
+}
diff --git a/Source/cmDependsJava.h b/Source/cmDependsJava.h
new file mode 100644
index 000000000..fe6fef50d
--- /dev/null
+++ b/Source/cmDependsJava.h
@@ -0,0 +1,42 @@
+/*============================================================================
+ 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 cmDependsJava_h
+#define cmDependsJava_h
+
+#include "cmDepends.h"
+
+/** \class cmDependsJava
+ * \brief Dependency scanner for Java class files.
+ */
+class cmDependsJava: public cmDepends
+{
+public:
+ /** Checking instances need to know the build directory name and the
+ relative path from the build directory to the target file. */
+ cmDependsJava();
+
+ /** Virtual destructor to cleanup subclasses properly. */
+ virtual ~cmDependsJava();
+
+protected:
+ // Implement writing/checking methods required by superclass.
+ virtual bool WriteDependencies(const char *src, const char *file,
+ std::ostream& makeDepends, std::ostream& internalDepends);
+ virtual bool CheckDependencies(std::istream& internalDepends,
+ std::map<std::string, DependencyVector >& validDeps);
+
+private:
+ cmDependsJava(cmDependsJava const&); // Purposely not implemented.
+ void operator=(cmDependsJava const&); // Purposely not implemented.
+};
+
+#endif
diff --git a/Source/cmDependsJavaLexer.cxx b/Source/cmDependsJavaLexer.cxx
new file mode 100644
index 000000000..63cfebcd7
--- /dev/null
+++ b/Source/cmDependsJavaLexer.cxx
@@ -0,0 +1,2542 @@
+#include "cmStandardIncludes.h"
+#line 2 "cmDependsJavaLexer.cxx"
+
+#line 4 "cmDependsJavaLexer.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 31
+#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>
+
+#if defined(__BEOS__) || defined (__HAIKU__)
+#include <unistd.h> /* prevents a conflict with a #define later on... */
+#endif
+
+/* 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
+#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;
+#endif /* ! C99 */
+
+/* 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 /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_CONST
+
+#endif /* __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
+
+int cmDependsJava_yylex_init (yyscan_t* scanner);
+
+/* 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 cmDependsJava_yyrestart(yyin ,yyscanner )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#define YY_BUF_SIZE 16384
+#endif
+
+#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 )
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef unsigned int 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 cmDependsJava_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 cmDependsJava_yyrestart (FILE *input_file ,yyscan_t yyscanner );
+void cmDependsJava_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+YY_BUFFER_STATE cmDependsJava_yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
+void cmDependsJava_yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void cmDependsJava_yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void cmDependsJava_yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+void cmDependsJava_yypop_buffer_state (yyscan_t yyscanner );
+
+static void cmDependsJava_yyensure_buffer_stack (yyscan_t yyscanner );
+static void cmDependsJava_yy_load_buffer_state (yyscan_t yyscanner );
+static void cmDependsJava_yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );
+
+#define YY_FLUSH_BUFFER cmDependsJava_yy_flush_buffer(YY_CURRENT_BUFFER ,yyscanner)
+
+YY_BUFFER_STATE cmDependsJava_yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
+YY_BUFFER_STATE cmDependsJava_yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
+YY_BUFFER_STATE cmDependsJava_yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
+
+void *cmDependsJava_yyalloc (yy_size_t ,yyscan_t yyscanner );
+void *cmDependsJava_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
+void cmDependsJava_yyfree (void * ,yyscan_t yyscanner );
+
+#define yy_new_buffer cmDependsJava_yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){ \
+ cmDependsJava_yyensure_buffer_stack (yyscanner); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ cmDependsJava_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 ){\
+ cmDependsJava_yyensure_buffer_stack (yyscanner); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ cmDependsJava_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 cmDependsJava_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 111
+#define YY_END_OF_BUFFER 112
+/* 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[327] =
+ { 0,
+ 0, 0, 0, 0, 0, 0, 112, 110, 109, 109,
+ 77, 4, 73, 94, 60, 110, 93, 92, 105, 99,
+ 68, 89, 74, 71, 56, 56, 67, 103, 86, 75,
+ 79, 102, 107, 64, 63, 65, 107, 107, 107, 107,
+ 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
+ 107, 70, 96, 69, 104, 3, 3, 6, 111, 5,
+ 78, 95, 61, 62, 0, 0, 106, 101, 100, 91,
+ 90, 57, 1, 0, 72, 57, 56, 57, 0, 56,
+ 0, 88, 87, 76, 80, 81, 107, 66, 107, 107,
+ 107, 107, 107, 107, 107, 107, 107, 107, 18, 107,
+
+ 107, 107, 107, 107, 107, 26, 107, 107, 107, 107,
+ 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
+ 107, 107, 107, 107, 107, 97, 98, 2, 55, 55,
+ 0, 0, 0, 108, 57, 0, 57, 58, 85, 82,
+ 83, 107, 107, 107, 107, 107, 107, 107, 107, 107,
+ 107, 107, 107, 107, 107, 107, 107, 107, 25, 107,
+ 107, 30, 107, 107, 34, 107, 107, 107, 107, 107,
+ 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
+ 107, 50, 107, 107, 107, 0, 0, 58, 84, 107,
+ 107, 107, 107, 11, 12, 107, 14, 107, 107, 107,
+
+ 107, 20, 107, 107, 107, 107, 107, 107, 107, 107,
+ 32, 107, 59, 107, 107, 107, 107, 107, 107, 107,
+ 107, 107, 107, 107, 46, 107, 107, 54, 51, 107,
+ 107, 107, 107, 107, 10, 13, 15, 107, 107, 107,
+ 107, 22, 24, 107, 107, 107, 107, 107, 107, 107,
+ 107, 107, 107, 40, 107, 107, 43, 107, 107, 47,
+ 107, 107, 53, 107, 8, 107, 107, 107, 19, 107,
+ 107, 107, 28, 107, 107, 33, 107, 107, 107, 38,
+ 39, 41, 107, 44, 107, 48, 107, 107, 107, 9,
+ 107, 17, 21, 23, 107, 107, 107, 35, 36, 107,
+
+ 107, 107, 107, 107, 7, 16, 107, 107, 107, 107,
+ 42, 107, 107, 52, 107, 107, 31, 37, 107, 49,
+ 27, 29, 107, 107, 45, 0
+ } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 1, 2, 2, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 4, 5, 1, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 19,
+ 19, 19, 19, 19, 19, 20, 20, 21, 22, 23,
+ 24, 25, 26, 1, 27, 27, 27, 28, 29, 28,
+ 30, 30, 30, 30, 30, 31, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 32, 30, 30,
+ 33, 34, 35, 36, 30, 1, 37, 38, 39, 40,
+
+ 41, 42, 43, 44, 45, 30, 46, 47, 48, 49,
+ 50, 51, 30, 52, 53, 54, 55, 56, 57, 58,
+ 59, 60, 61, 62, 63, 64, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 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[65] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 1,
+ 1, 1, 1, 1, 1, 1, 1, 3, 3, 3,
+ 1, 1, 1, 1, 1, 1, 3, 3, 3, 4,
+ 4, 4, 1, 1, 1, 1, 3, 3, 3, 3,
+ 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 1, 1, 1, 1
+ } ;
+
+static yyconst flex_int16_t yy_base[334] =
+ { 0,
+ 0, 0, 401, 400, 62, 63, 411, 414, 414, 414,
+ 386, 414, 414, 385, 61, 374, 414, 414, 383, 57,
+ 414, 56, 54, 65, 74, 43, 414, 414, 55, 382,
+ 59, 414, 0, 414, 414, 381, 38, 36, 60, 46,
+ 51, 75, 69, 354, 82, 76, 362, 85, 56, 352,
+ 357, 414, 100, 414, 414, 414, 383, 414, 414, 414,
+ 414, 414, 414, 414, 390, 127, 414, 414, 414, 414,
+ 414, 129, 414, 395, 414, 132, 95, 414, 165, 414,
+ 0, 373, 414, 414, 414, 109, 0, 414, 343, 342,
+ 344, 352, 338, 101, 354, 353, 340, 346, 332, 333,
+
+ 331, 337, 334, 332, 329, 0, 329, 110, 330, 324,
+ 320, 329, 336, 93, 336, 319, 322, 89, 320, 325,
+ 320, 114, 131, 120, 323, 414, 414, 414, 414, 358,
+ 170, 357, 362, 414, 173, 157, 176, 150, 414, 414,
+ 340, 309, 321, 314, 323, 318, 317, 318, 304, 302,
+ 300, 316, 314, 310, 309, 296, 311, 310, 0, 153,
+ 292, 304, 301, 298, 0, 295, 295, 284, 285, 291,
+ 282, 284, 281, 289, 292, 278, 292, 277, 279, 279,
+ 286, 0, 286, 288, 277, 189, 314, 414, 414, 270,
+ 269, 279, 273, 0, 0, 274, 0, 264, 271, 260,
+
+ 267, 0, 264, 271, 264, 256, 268, 256, 270, 254,
+ 0, 249, 0, 267, 266, 261, 256, 248, 245, 253,
+ 258, 244, 256, 250, 0, 236, 239, 0, 0, 237,
+ 249, 252, 234, 250, 0, 0, 0, 237, 238, 243,
+ 243, 235, 0, 233, 226, 230, 236, 236, 233, 221,
+ 235, 234, 223, 0, 232, 216, 0, 225, 216, 214,
+ 221, 220, 0, 225, 0, 214, 207, 207, 0, 207,
+ 200, 217, 0, 218, 219, 0, 214, 213, 199, 0,
+ 0, 0, 210, 0, 201, 0, 209, 202, 194, 0,
+ 206, 0, 0, 0, 197, 204, 205, 0, 0, 202,
+
+ 191, 192, 191, 198, 0, 0, 163, 162, 170, 170,
+ 0, 164, 152, 0, 152, 157, 0, 0, 127, 0,
+ 0, 0, 115, 95, 0, 414, 218, 222, 226, 228,
+ 232, 96, 235
+ } ;
+
+static yyconst flex_int16_t yy_def[334] =
+ { 0,
+ 326, 1, 327, 327, 328, 328, 326, 326, 326, 326,
+ 326, 326, 326, 326, 326, 329, 326, 326, 326, 326,
+ 326, 326, 326, 326, 326, 25, 326, 326, 326, 326,
+ 326, 326, 330, 326, 326, 326, 330, 330, 330, 330,
+ 330, 330, 330, 330, 330, 330, 330, 330, 330, 330,
+ 330, 326, 326, 326, 326, 326, 326, 326, 326, 326,
+ 326, 326, 326, 326, 326, 329, 326, 326, 326, 326,
+ 326, 326, 326, 331, 326, 326, 25, 326, 326, 326,
+ 332, 326, 326, 326, 326, 326, 330, 326, 330, 330,
+ 330, 330, 330, 330, 330, 330, 330, 330, 330, 330,
+
+ 330, 330, 330, 330, 330, 330, 330, 330, 330, 330,
+ 330, 330, 330, 330, 330, 330, 330, 330, 330, 330,
+ 330, 330, 330, 330, 330, 326, 326, 326, 326, 326,
+ 326, 333, 331, 326, 326, 326, 326, 332, 326, 326,
+ 326, 330, 330, 330, 330, 330, 330, 330, 330, 330,
+ 330, 330, 330, 330, 330, 330, 330, 330, 330, 330,
+ 330, 330, 330, 330, 330, 330, 330, 330, 330, 330,
+ 330, 330, 330, 330, 330, 330, 330, 330, 330, 330,
+ 330, 330, 330, 330, 330, 326, 333, 326, 326, 330,
+ 330, 330, 330, 330, 330, 330, 330, 330, 330, 330,
+
+ 330, 330, 330, 330, 330, 330, 330, 330, 330, 330,
+ 330, 330, 330, 330, 330, 330, 330, 330, 330, 330,
+ 330, 330, 330, 330, 330, 330, 330, 330, 330, 330,
+ 330, 330, 330, 330, 330, 330, 330, 330, 330, 330,
+ 330, 330, 330, 330, 330, 330, 330, 330, 330, 330,
+ 330, 330, 330, 330, 330, 330, 330, 330, 330, 330,
+ 330, 330, 330, 330, 330, 330, 330, 330, 330, 330,
+ 330, 330, 330, 330, 330, 330, 330, 330, 330, 330,
+ 330, 330, 330, 330, 330, 330, 330, 330, 330, 330,
+ 330, 330, 330, 330, 330, 330, 330, 330, 330, 330,
+
+ 330, 330, 330, 330, 330, 330, 330, 330, 330, 330,
+ 330, 330, 330, 330, 330, 330, 330, 330, 330, 330,
+ 330, 330, 330, 330, 330, 0, 326, 326, 326, 326,
+ 326, 326, 326
+ } ;
+
+static yyconst flex_int16_t yy_nxt[479] =
+ { 0,
+ 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 26,
+ 27, 28, 29, 30, 31, 32, 33, 33, 33, 33,
+ 33, 33, 34, 8, 35, 36, 37, 38, 39, 40,
+ 41, 42, 33, 33, 43, 33, 44, 33, 45, 33,
+ 46, 47, 48, 49, 33, 50, 51, 33, 33, 33,
+ 52, 53, 54, 55, 59, 59, 60, 60, 63, 68,
+ 70, 72, 72, 72, 326, 89, 73, 82, 83, 71,
+ 69, 74, 85, 86, 64, 91, 98, 92, 75, 76,
+ 90, 77, 77, 77, 93, 99, 94, 100, 138, 122,
+
+ 326, 78, 79, 95, 80, 81, 96, 123, 101, 97,
+ 106, 102, 113, 78, 79, 78, 107, 108, 110, 103,
+ 80, 104, 111, 126, 105, 173, 326, 114, 117, 326,
+ 115, 81, 140, 141, 325, 130, 112, 168, 118, 119,
+ 174, 120, 169, 121, 131, 131, 72, 72, 72, 135,
+ 135, 135, 326, 147, 148, 324, 78, 79, 178, 78,
+ 79, 127, 161, 162, 183, 179, 184, 180, 78, 79,
+ 78, 78, 79, 78, 137, 137, 137, 136, 129, 136,
+ 188, 132, 137, 137, 137, 181, 323, 186, 186, 182,
+ 135, 135, 135, 137, 137, 137, 188, 129, 322, 207,
+
+ 78, 79, 208, 78, 321, 320, 186, 186, 319, 318,
+ 317, 316, 78, 79, 78, 78, 315, 78, 56, 56,
+ 56, 56, 58, 58, 58, 58, 65, 65, 65, 65,
+ 87, 87, 133, 133, 133, 133, 187, 187, 314, 313,
+ 312, 311, 310, 309, 308, 307, 306, 305, 304, 303,
+ 302, 301, 300, 299, 298, 297, 296, 295, 294, 293,
+ 292, 291, 290, 289, 288, 287, 286, 285, 284, 283,
+ 282, 281, 280, 279, 278, 277, 276, 275, 274, 273,
+ 272, 271, 270, 269, 268, 267, 266, 265, 264, 263,
+ 262, 261, 260, 259, 258, 257, 256, 255, 254, 253,
+
+ 252, 251, 250, 249, 248, 247, 246, 245, 244, 243,
+ 242, 228, 241, 240, 239, 238, 237, 236, 235, 234,
+ 233, 232, 129, 231, 230, 229, 228, 227, 226, 225,
+ 224, 223, 222, 221, 220, 219, 218, 217, 216, 215,
+ 214, 213, 212, 211, 210, 209, 206, 205, 204, 203,
+ 202, 201, 200, 199, 198, 197, 196, 195, 194, 193,
+ 192, 191, 190, 189, 134, 129, 129, 185, 177, 176,
+ 175, 172, 171, 170, 167, 166, 165, 164, 163, 160,
+ 159, 158, 157, 156, 155, 154, 153, 152, 151, 150,
+ 149, 146, 145, 144, 143, 142, 139, 134, 129, 128,
+
+ 125, 124, 116, 109, 88, 84, 67, 66, 62, 61,
+ 326, 57, 57, 7, 326, 326, 326, 326, 326, 326,
+ 326, 326, 326, 326, 326, 326, 326, 326, 326, 326,
+ 326, 326, 326, 326, 326, 326, 326, 326, 326, 326,
+ 326, 326, 326, 326, 326, 326, 326, 326, 326, 326,
+ 326, 326, 326, 326, 326, 326, 326, 326, 326, 326,
+ 326, 326, 326, 326, 326, 326, 326, 326, 326, 326,
+ 326, 326, 326, 326, 326, 326, 326, 326
+ } ;
+
+static yyconst flex_int16_t yy_chk[479] =
+ { 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, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 5, 6, 5, 6, 15, 20,
+ 22, 23, 23, 23, 26, 37, 24, 29, 29, 22,
+ 20, 24, 31, 31, 15, 38, 40, 38, 24, 25,
+ 37, 25, 25, 25, 38, 40, 39, 41, 332, 49,
+
+ 26, 25, 25, 39, 25, 25, 39, 49, 41, 39,
+ 43, 42, 46, 25, 25, 25, 43, 43, 45, 42,
+ 25, 42, 45, 53, 42, 118, 77, 46, 48, 66,
+ 46, 25, 86, 86, 324, 66, 45, 114, 48, 48,
+ 118, 48, 114, 48, 66, 66, 72, 72, 72, 76,
+ 76, 76, 77, 94, 94, 323, 72, 72, 122, 76,
+ 76, 53, 108, 108, 124, 122, 124, 123, 72, 72,
+ 72, 76, 76, 76, 136, 136, 136, 79, 131, 79,
+ 138, 66, 79, 79, 79, 123, 319, 131, 131, 123,
+ 135, 135, 135, 137, 137, 137, 138, 186, 316, 160,
+
+ 135, 135, 160, 137, 315, 313, 186, 186, 312, 310,
+ 309, 308, 135, 135, 135, 137, 307, 137, 327, 327,
+ 327, 327, 328, 328, 328, 328, 329, 329, 329, 329,
+ 330, 330, 331, 331, 331, 331, 333, 333, 304, 303,
+ 302, 301, 300, 297, 296, 295, 291, 289, 288, 287,
+ 285, 283, 279, 278, 277, 275, 274, 272, 271, 270,
+ 268, 267, 266, 264, 262, 261, 260, 259, 258, 256,
+ 255, 253, 252, 251, 250, 249, 248, 247, 246, 245,
+ 244, 242, 241, 240, 239, 238, 234, 233, 232, 231,
+ 230, 227, 226, 224, 223, 222, 221, 220, 219, 218,
+
+ 217, 216, 215, 214, 212, 210, 209, 208, 207, 206,
+ 205, 204, 203, 201, 200, 199, 198, 196, 193, 192,
+ 191, 190, 187, 185, 184, 183, 181, 180, 179, 178,
+ 177, 176, 175, 174, 173, 172, 171, 170, 169, 168,
+ 167, 166, 164, 163, 162, 161, 158, 157, 156, 155,
+ 154, 153, 152, 151, 150, 149, 148, 147, 146, 145,
+ 144, 143, 142, 141, 133, 132, 130, 125, 121, 120,
+ 119, 117, 116, 115, 113, 112, 111, 110, 109, 107,
+ 105, 104, 103, 102, 101, 100, 99, 98, 97, 96,
+ 95, 93, 92, 91, 90, 89, 82, 74, 65, 57,
+
+ 51, 50, 47, 44, 36, 30, 19, 16, 14, 11,
+ 7, 4, 3, 326, 326, 326, 326, 326, 326, 326,
+ 326, 326, 326, 326, 326, 326, 326, 326, 326, 326,
+ 326, 326, 326, 326, 326, 326, 326, 326, 326, 326,
+ 326, 326, 326, 326, 326, 326, 326, 326, 326, 326,
+ 326, 326, 326, 326, 326, 326, 326, 326, 326, 326,
+ 326, 326, 326, 326, 326, 326, 326, 326, 326, 326,
+ 326, 326, 326, 326, 326, 326, 326, 326
+ } ;
+
+/* 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 "cmDependsJavaLexer.in.l"
+#line 2 "cmDependsJavaLexer.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.
+============================================================================*/
+/*
+
+This file must be translated to C and modified to build everywhere.
+
+Run flex like this:
+
+ flex --prefix=cmDependsJava_yy --header-file=cmDependsJavaLexer.h -ocmDependsJavaLexer.cxx cmDependsJavaLexer.in.l
+
+Modify cmDependsJavaLexer.c:
+ - remove TABs
+ - remove "yyscanner" argument from these methods:
+ yy_fatal_error, cmDependsJava_yyalloc, cmDependsJava_yyrealloc, cmDependsJava_yyfree
+ - remove all YY_BREAK lines occurring right after return statements
+ - change while ( 1 ) to for(;;)
+
+Modify cmDependsJavaLexer.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"
+
+#include "cmDependsJavaParserHelper.h"
+
+/* Replace the lexer input function. */
+#undef YY_INPUT
+#define YY_INPUT(buf, result, max_size) \
+ { result = yyextra->LexInput(buf, max_size); }
+
+/* Include the set of tokens from the parser. */
+#include "cmDependsJavaParserTokens.h"
+
+#define KEYWORD yylvalp->str = 0
+#define SYMBOL yylvalp->str = 0
+#define PRIMITIVE yylvalp->str = 0
+
+/*--------------------------------------------------------------------------*/
+
+
+#line 721 "cmDependsJavaLexer.cxx"
+
+#define INITIAL 0
+#define comment 1
+#define string 2
+
+#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 */
+
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int cmDependsJava_yylex_destroy (yyscan_t yyscanner );
+
+int cmDependsJava_yyget_debug (yyscan_t yyscanner );
+
+void cmDependsJava_yyset_debug (int debug_flag ,yyscan_t yyscanner );
+
+YY_EXTRA_TYPE cmDependsJava_yyget_extra (yyscan_t yyscanner );
+
+void cmDependsJava_yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
+
+FILE *cmDependsJava_yyget_in (yyscan_t yyscanner );
+
+void cmDependsJava_yyset_in (FILE * in_str ,yyscan_t yyscanner );
+
+FILE *cmDependsJava_yyget_out (yyscan_t yyscanner );
+
+void cmDependsJava_yyset_out (FILE * out_str ,yyscan_t yyscanner );
+
+int cmDependsJava_yyget_leng (yyscan_t yyscanner );
+
+char *cmDependsJava_yyget_text (yyscan_t yyscanner );
+
+int cmDependsJava_yyget_lineno (yyscan_t yyscanner );
+
+void cmDependsJava_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 cmDependsJava_yywrap (yyscan_t yyscanner );
+#else
+extern int cmDependsJava_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
+
+#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
+#define YY_READ_BUF_SIZE 8192
+#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 (void) fwrite( yytext, yyleng, 1, yyout )
+#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 cmDependsJava_yylex (yyscan_t yyscanner);
+
+#define YY_DECL int cmDependsJava_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 \
+ YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp, *yy_bp;
+ register int yy_act;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+#line 88 "cmDependsJavaLexer.in.l"
+
+#line 940 "cmDependsJavaLexer.cxx"
+
+ if ( yyg->yy_init )
+ {
+ yyg->yy_init = 0;
+
+#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 ) {
+ cmDependsJava_yyensure_buffer_stack (yyscanner);
+ YY_CURRENT_BUFFER_LVALUE =
+ cmDependsJava_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+ }
+
+ cmDependsJava_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_match:
+ do
+ {
+ register 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 >= 327 )
+ 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] != 414 );
+
+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 89 "cmDependsJavaLexer.in.l"
+{ BEGIN(comment); }
+ YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 90 "cmDependsJavaLexer.in.l"
+{ BEGIN(INITIAL); }
+ YY_BREAK
+case 3:
+/* rule 3 can match eol */
+YY_RULE_SETUP
+#line 91 "cmDependsJavaLexer.in.l"
+{}
+ YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 93 "cmDependsJavaLexer.in.l"
+{ BEGIN(string); }
+ YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 94 "cmDependsJavaLexer.in.l"
+{ BEGIN(INITIAL); return jp_STRINGLITERAL; }
+case 6:
+YY_RULE_SETUP
+#line 95 "cmDependsJavaLexer.in.l"
+{}
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 97 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_ABSTRACT; }
+case 8:
+YY_RULE_SETUP
+#line 98 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_ASSERT; }
+case 9:
+YY_RULE_SETUP
+#line 99 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_BOOLEAN_TYPE; }
+case 10:
+YY_RULE_SETUP
+#line 100 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_BREAK; }
+case 11:
+YY_RULE_SETUP
+#line 101 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_BYTE_TYPE; }
+case 12:
+YY_RULE_SETUP
+#line 102 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_CASE; }
+case 13:
+YY_RULE_SETUP
+#line 103 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_CATCH; }
+case 14:
+YY_RULE_SETUP
+#line 104 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_CHAR_TYPE; }
+case 15:
+YY_RULE_SETUP
+#line 105 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_CLASS; }
+case 16:
+YY_RULE_SETUP
+#line 106 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_CONTINUE; }
+case 17:
+YY_RULE_SETUP
+#line 107 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_DEFAULT; }
+case 18:
+YY_RULE_SETUP
+#line 108 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_DO; }
+case 19:
+YY_RULE_SETUP
+#line 109 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_DOUBLE_TYPE; }
+case 20:
+YY_RULE_SETUP
+#line 110 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_ELSE; }
+case 21:
+YY_RULE_SETUP
+#line 111 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_EXTENDS; }
+case 22:
+YY_RULE_SETUP
+#line 112 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_FINAL; }
+case 23:
+YY_RULE_SETUP
+#line 113 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_FINALLY; }
+case 24:
+YY_RULE_SETUP
+#line 114 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_FLOAT_TYPE; }
+case 25:
+YY_RULE_SETUP
+#line 115 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_FOR; }
+case 26:
+YY_RULE_SETUP
+#line 116 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_IF; }
+case 27:
+YY_RULE_SETUP
+#line 117 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_IMPLEMENTS; }
+case 28:
+YY_RULE_SETUP
+#line 118 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_IMPORT; }
+case 29:
+YY_RULE_SETUP
+#line 119 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_INSTANCEOF; }
+case 30:
+YY_RULE_SETUP
+#line 120 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_INT_TYPE; }
+case 31:
+YY_RULE_SETUP
+#line 121 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_INTERFACE; }
+case 32:
+YY_RULE_SETUP
+#line 122 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_LONG_TYPE; }
+case 33:
+YY_RULE_SETUP
+#line 123 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_NATIVE; }
+case 34:
+YY_RULE_SETUP
+#line 124 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_NEW; }
+case 35:
+YY_RULE_SETUP
+#line 125 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_PACKAGE; }
+case 36:
+YY_RULE_SETUP
+#line 126 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_PRIVATE; }
+case 37:
+YY_RULE_SETUP
+#line 127 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_PROTECTED; }
+case 38:
+YY_RULE_SETUP
+#line 128 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_PUBLIC; }
+case 39:
+YY_RULE_SETUP
+#line 129 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_RETURN; }
+case 40:
+YY_RULE_SETUP
+#line 130 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_SHORT_TYPE; }
+case 41:
+YY_RULE_SETUP
+#line 131 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_STATIC; }
+case 42:
+YY_RULE_SETUP
+#line 132 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_STRICTFP; }
+case 43:
+YY_RULE_SETUP
+#line 133 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_SUPER; }
+case 44:
+YY_RULE_SETUP
+#line 134 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_SWITCH; }
+case 45:
+YY_RULE_SETUP
+#line 135 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_SYNCHRONIZED; }
+case 46:
+YY_RULE_SETUP
+#line 136 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_THIS; }
+case 47:
+YY_RULE_SETUP
+#line 137 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_THROW; }
+case 48:
+YY_RULE_SETUP
+#line 138 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_THROWS; }
+case 49:
+YY_RULE_SETUP
+#line 139 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_TRANSIENT; }
+case 50:
+YY_RULE_SETUP
+#line 140 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_TRY; }
+case 51:
+YY_RULE_SETUP
+#line 141 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_VOID; }
+case 52:
+YY_RULE_SETUP
+#line 142 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_VOLATILE; }
+case 53:
+YY_RULE_SETUP
+#line 143 "cmDependsJavaLexer.in.l"
+{ KEYWORD; return jp_WHILE; }
+case 54:
+YY_RULE_SETUP
+#line 145 "cmDependsJavaLexer.in.l"
+{ PRIMITIVE; return jp_BOOLEANLITERAL; }
+case 55:
+/* rule 55 can match eol */
+YY_RULE_SETUP
+#line 146 "cmDependsJavaLexer.in.l"
+{ PRIMITIVE; return jp_CHARACTERLITERAL; }
+case 56:
+YY_RULE_SETUP
+#line 147 "cmDependsJavaLexer.in.l"
+{ PRIMITIVE; return jp_DECIMALINTEGERLITERAL; }
+case 57:
+YY_RULE_SETUP
+#line 148 "cmDependsJavaLexer.in.l"
+{ PRIMITIVE; return jp_FLOATINGPOINTLITERAL; }
+case 58:
+YY_RULE_SETUP
+#line 149 "cmDependsJavaLexer.in.l"
+{ PRIMITIVE; return jp_HEXINTEGERLITERAL; }
+case 59:
+YY_RULE_SETUP
+#line 150 "cmDependsJavaLexer.in.l"
+{ PRIMITIVE; return jp_NULLLITERAL; }
+case 60:
+YY_RULE_SETUP
+#line 152 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_AND; }
+case 61:
+YY_RULE_SETUP
+#line 153 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_ANDAND; }
+case 62:
+YY_RULE_SETUP
+#line 154 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_ANDEQUALS; }
+case 63:
+YY_RULE_SETUP
+#line 155 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_BRACKETEND; }
+case 64:
+YY_RULE_SETUP
+#line 156 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_BRACKETSTART; }
+case 65:
+YY_RULE_SETUP
+#line 157 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_CARROT; }
+case 66:
+YY_RULE_SETUP
+#line 158 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_CARROTEQUALS; }
+case 67:
+YY_RULE_SETUP
+#line 159 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_COLON; }
+case 68:
+YY_RULE_SETUP
+#line 160 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_COMMA; }
+case 69:
+YY_RULE_SETUP
+#line 161 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_CURLYEND; }
+case 70:
+YY_RULE_SETUP
+#line 162 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_CURLYSTART; }
+case 71:
+YY_RULE_SETUP
+#line 163 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_DIVIDE; }
+case 72:
+YY_RULE_SETUP
+#line 164 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_DIVIDEEQUALS; }
+case 73:
+YY_RULE_SETUP
+#line 165 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_DOLLAR; }
+case 74:
+YY_RULE_SETUP
+#line 166 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_DOT; }
+case 75:
+YY_RULE_SETUP
+#line 167 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_EQUALS; }
+case 76:
+YY_RULE_SETUP
+#line 168 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_EQUALSEQUALS; }
+case 77:
+YY_RULE_SETUP
+#line 169 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_EXCLAMATION; }
+case 78:
+YY_RULE_SETUP
+#line 170 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_EXCLAMATIONEQUALS; }
+case 79:
+YY_RULE_SETUP
+#line 171 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_GREATER; }
+case 80:
+YY_RULE_SETUP
+#line 172 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_GTEQUALS; }
+case 81:
+YY_RULE_SETUP
+#line 173 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_GTGT; }
+case 82:
+YY_RULE_SETUP
+#line 174 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_GTGTEQUALS; }
+case 83:
+YY_RULE_SETUP
+#line 175 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_GTGTGT; }
+case 84:
+YY_RULE_SETUP
+#line 176 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_GTGTGTEQUALS; }
+case 85:
+YY_RULE_SETUP
+#line 177 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_LESLESEQUALS; }
+case 86:
+YY_RULE_SETUP
+#line 178 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_LESSTHAN; }
+case 87:
+YY_RULE_SETUP
+#line 179 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_LTEQUALS; }
+case 88:
+YY_RULE_SETUP
+#line 180 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_LTLT; }
+case 89:
+YY_RULE_SETUP
+#line 181 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_MINUS; }
+case 90:
+YY_RULE_SETUP
+#line 182 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_MINUSEQUALS; }
+case 91:
+YY_RULE_SETUP
+#line 183 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_MINUSMINUS; }
+case 92:
+YY_RULE_SETUP
+#line 184 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_PAREEND; }
+case 93:
+YY_RULE_SETUP
+#line 185 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_PARESTART; }
+case 94:
+YY_RULE_SETUP
+#line 186 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_PERCENT; }
+case 95:
+YY_RULE_SETUP
+#line 187 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_PERCENTEQUALS; }
+case 96:
+YY_RULE_SETUP
+#line 188 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_PIPE; }
+case 97:
+YY_RULE_SETUP
+#line 189 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_PIPEEQUALS; }
+case 98:
+YY_RULE_SETUP
+#line 190 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_PIPEPIPE; }
+case 99:
+YY_RULE_SETUP
+#line 191 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_PLUS; }
+case 100:
+YY_RULE_SETUP
+#line 192 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_PLUSEQUALS; }
+case 101:
+YY_RULE_SETUP
+#line 193 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_PLUSPLUS; }
+case 102:
+YY_RULE_SETUP
+#line 194 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_QUESTION; }
+case 103:
+YY_RULE_SETUP
+#line 195 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_SEMICOL; }
+case 104:
+YY_RULE_SETUP
+#line 196 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_TILDE; }
+case 105:
+YY_RULE_SETUP
+#line 197 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_TIMES; }
+case 106:
+YY_RULE_SETUP
+#line 198 "cmDependsJavaLexer.in.l"
+{ SYMBOL; return jp_TIMESEQUALS; }
+case 107:
+YY_RULE_SETUP
+#line 200 "cmDependsJavaLexer.in.l"
+{
+ yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext));
+ return jp_NAME;
+}
+case 108:
+/* rule 108 can match eol */
+YY_RULE_SETUP
+#line 205 "cmDependsJavaLexer.in.l"
+{ }
+ YY_BREAK
+case 109:
+/* rule 109 can match eol */
+YY_RULE_SETUP
+#line 206 "cmDependsJavaLexer.in.l"
+{ }
+ YY_BREAK
+case 110:
+YY_RULE_SETUP
+#line 207 "cmDependsJavaLexer.in.l"
+{
+ std::cerr << "Unknown character: " << yytext[0]
+ << " (" << (int)yytext[0] << ")" << std::endl;
+ yyextra->Error("Unknown character");
+ return jp_ERROR;
+}
+case 111:
+YY_RULE_SETUP
+#line 214 "cmDependsJavaLexer.in.l"
+ECHO;
+ YY_BREAK
+#line 1590 "cmDependsJavaLexer.cxx"
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(comment):
+case YY_STATE_EOF(string):
+ yyterminate();
+
+ 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
+ * cmDependsJava_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 ( cmDependsJava_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 */
+return 0; /* this should not happen but it silences a warning*/
+} /* end of cmDependsJava_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;
+ register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ register char *source = yyg->yytext_ptr;
+ register 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
+ {
+ size_t nuto_read =
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+ while ( nuto_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. */
+ cmDependsJava_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];
+
+ nuto_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+ number_to_move - 1;
+
+ }
+
+ if ( nuto_read > YY_READ_BUF_SIZE )
+ nuto_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, nuto_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;
+ cmDependsJava_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;
+
+ 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)
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ yy_current_state = yyg->yy_start;
+
+ for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp )
+ {
+ register 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 >= 327 )
+ 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)
+{
+ register int yy_is_jam;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ register char *yy_cp = yyg->yy_c_buf_p;
+
+ register 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 >= 327 )
+ 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 == 326);
+
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+#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. */
+ cmDependsJava_yyrestart(yyin ,yyscanner);
+
+ /*FALLTHROUGH*/
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( cmDependsJava_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;
+
+ 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 cmDependsJava_yyrestart (FILE * input_file , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if ( ! YY_CURRENT_BUFFER ){
+ cmDependsJava_yyensure_buffer_stack (yyscanner);
+ YY_CURRENT_BUFFER_LVALUE =
+ cmDependsJava_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+ }
+
+ cmDependsJava_yy_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner);
+ cmDependsJava_yy_load_buffer_state(yyscanner );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ * @param yyscanner The scanner object.
+ */
+ void cmDependsJava_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
+ * cmDependsJava_yypop_buffer_state();
+ * cmDependsJava_yypush_buffer_state(new_buffer);
+ */
+ cmDependsJava_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;
+ cmDependsJava_yy_load_buffer_state(yyscanner );
+
+ /* We don't actually know whether we did this switch during
+ * EOF (cmDependsJava_yywrap()) processing, but the only time this flag
+ * is looked at is after cmDependsJava_yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ yyg->yy_did_buffer_switch_on_eof = 1;
+}
+
+static void cmDependsJava_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 cmDependsJava_yy_create_buffer (FILE * file, int size , yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) cmDependsJava_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in cmDependsJava_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 *) cmDependsJava_yyalloc(b->yy_buf_size + 2 ,yyscanner );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in cmDependsJava_yy_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ cmDependsJava_yy_init_buffer(b,file ,yyscanner);
+
+ return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with cmDependsJava_yy_create_buffer()
+ * @param yyscanner The scanner object.
+ */
+ void cmDependsJava_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 )
+ cmDependsJava_yyfree((void *) b->yy_ch_buf ,yyscanner );
+
+ cmDependsJava_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 cmDependsJava_yyrestart() or at EOF.
+ */
+ static void cmDependsJava_yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner)
+
+{
+ int oerrno = errno;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ cmDependsJava_yy_flush_buffer(b ,yyscanner);
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then cmDependsJava_yy_init_buffer was _probably_
+ * called from cmDependsJava_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 cmDependsJava_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 )
+ cmDependsJava_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 cmDependsJava_yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if (new_buffer == NULL)
+ return;
+
+ cmDependsJava_yyensure_buffer_stack(yyscanner);
+
+ /* This block is copied from cmDependsJava_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 cmDependsJava_yy_switch_to_buffer. */
+ cmDependsJava_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 cmDependsJava_yypop_buffer_state (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ cmDependsJava_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) {
+ cmDependsJava_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 cmDependsJava_yyensure_buffer_stack (yyscan_t yyscanner)
+{
+ int nuto_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.
+ */
+ nuto_alloc = 1;
+ yyg->yy_buffer_stack = (struct yy_buffer_state**)cmDependsJava_yyalloc
+ (nuto_alloc * sizeof(struct yy_buffer_state*)
+ , yyscanner);
+
+ memset(yyg->yy_buffer_stack, 0, nuto_alloc * sizeof(struct yy_buffer_state*));
+
+ yyg->yy_buffer_stack_max = nuto_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 */;
+
+ nuto_alloc = yyg->yy_buffer_stack_max + grow_size;
+ yyg->yy_buffer_stack = (struct yy_buffer_state**)cmDependsJava_yyrealloc
+ (yyg->yy_buffer_stack,
+ nuto_alloc * sizeof(struct yy_buffer_state*)
+ , yyscanner);
+
+ /* 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 = nuto_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 cmDependsJava_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) cmDependsJava_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in cmDependsJava_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;
+
+ cmDependsJava_yy_switch_to_buffer(b ,yyscanner );
+
+ return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to cmDependsJava_yylex() will
+ * scan from a @e copy of @a yy_str.
+ * @param yy_str 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
+ * cmDependsJava_yy_scan_bytes() instead.
+ */
+YY_BUFFER_STATE cmDependsJava_yy_scan_string (yyconst char * yy_str , yyscan_t yyscanner)
+{
+
+ return cmDependsJava_yy_scan_bytes(yy_str,strlen(yy_str) ,yyscanner);
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to cmDependsJava_yylex() will
+ * scan from a @e copy of @a bytes.
+ * @param bytes the byte buffer to scan
+ * @param 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 cmDependsJava_yy_scan_bytes (yyconst char * bytes, int 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 = len + 2;
+ buf = (char *) cmDependsJava_yyalloc(n ,yyscanner );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in cmDependsJava_yy_scan_bytes()" );
+
+ for ( i = 0; i < len; ++i )
+ buf[i] = bytes[i];
+
+ buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = cmDependsJava_yy_scan_buffer(buf,n ,yyscanner);
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in cmDependsJava_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 cmDependsJava_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 cmDependsJava_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 cmDependsJava_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 *cmDependsJava_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 *cmDependsJava_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 cmDependsJava_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 *cmDependsJava_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 cmDependsJava_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 cmDependsJava_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( "cmDependsJava_yyset_lineno called with no buffer" , yyscanner);
+
+ yylineno = line_number;
+}
+
+/** Set the current column.
+ * @param column_no
+ * @param yyscanner The scanner object.
+ */
+void cmDependsJava_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( "cmDependsJava_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 cmDependsJava_yy_switch_to_buffer
+ */
+void cmDependsJava_yyset_in (FILE * in_str , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyin = in_str ;
+}
+
+void cmDependsJava_yyset_out (FILE * out_str , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyout = out_str ;
+}
+
+int cmDependsJava_yyget_debug (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yy_flex_debug;
+}
+
+void cmDependsJava_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 */
+
+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 once per scanner lifetime. */
+
+ 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 = 1;
+ yyg->yy_start = 0;
+ yyg->yy_start_stack_ptr = 0;
+ yyg->yy_start_stack_depth = 0;
+ yyg->yy_start_stack = (int *) 0;
+
+/* 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
+ * cmDependsJava_yylex_init()
+ */
+ return 0;
+}
+
+/* User-visible API */
+
+/* cmDependsJava_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 cmDependsJava_yylex_init(yyscan_t* ptr_yy_globals)
+
+{
+ if (ptr_yy_globals == NULL){
+ errno = EINVAL;
+ return 1;
+ }
+
+ *ptr_yy_globals = (yyscan_t) cmDependsJava_yyalloc ( sizeof( struct yyguts_t ), NULL );
+
+ if (*ptr_yy_globals == NULL){
+ errno = ENOMEM;
+ return 1;
+ }
+
+ memset(*ptr_yy_globals,0,sizeof(struct yyguts_t));
+
+ return yy_init_globals ( *ptr_yy_globals );
+}
+
+/* cmDependsJava_yylex_destroy is for both reentrant and non-reentrant scanners. */
+int cmDependsJava_yylex_destroy (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* Pop the buffer stack, destroying each element. */
+ while(YY_CURRENT_BUFFER){
+ cmDependsJava_yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ cmDependsJava_yypop_buffer_state(yyscanner);
+ }
+
+ /* Destroy the stack itself. */
+ cmDependsJava_yyfree(yyg->yy_buffer_stack ,yyscanner);
+ yyg->yy_buffer_stack = NULL;
+
+ /* Destroy the start condition stack. */
+ cmDependsJava_yyfree(yyg->yy_start_stack ,yyscanner );
+ yyg->yy_start_stack = NULL;
+
+ /* Destroy the main struct (reentrant only). */
+ cmDependsJava_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)
+{
+ register int i;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ 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)
+{
+ register int n;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+}
+#endif
+
+void *cmDependsJava_yyalloc (yy_size_t size , yyscan_t)
+{
+ return (void *) malloc( size );
+}
+
+void *cmDependsJava_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 cmDependsJava_yyfree (void * ptr , yyscan_t)
+{
+ free( (char *) ptr ); /* see cmDependsJava_yyrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#undef YY_NEW_FILE
+#undef YY_FLUSH_BUFFER
+#undef yy_set_bol
+#undef yy_new_buffer
+#undef yy_set_interactive
+#undef yytext_ptr
+#undef YY_DO_BEFORE_ACTION
+
+#ifdef YY_DECL_IS_OURS
+#undef YY_DECL_IS_OURS
+#undef YY_DECL
+#endif
+#line 214 "cmDependsJavaLexer.in.l"
+
+
+
diff --git a/Source/cmDependsJavaLexer.h b/Source/cmDependsJavaLexer.h
new file mode 100644
index 000000000..09c19bfff
--- /dev/null
+++ b/Source/cmDependsJavaLexer.h
@@ -0,0 +1,334 @@
+/*============================================================================
+ 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 cmDependsJava_yyHEADER_H
+#define cmDependsJava_yyHEADER_H 1
+#define cmDependsJava_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 31
+#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>
+
+#if defined(__BEOS__) || defined(__HAIKU__)
+#include <unistd.h> /* prevents a conflict with a #define later on... */
+#endif
+
+/* 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
+#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;
+#endif /* ! C99 */
+
+/* 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 /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_CONST
+
+#endif /* __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
+
+int cmDependsJava_yylex_init (yyscan_t* scanner);
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef unsigned int 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 cmDependsJava_yyrestart (FILE *input_file ,yyscan_t yyscanner );
+void cmDependsJava_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,
+ yyscan_t yyscanner );
+YY_BUFFER_STATE cmDependsJava_yy_create_buffer (FILE *file,int size ,
+ yyscan_t yyscanner );
+void cmDependsJava_yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void cmDependsJava_yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void cmDependsJava_yypush_buffer_state (YY_BUFFER_STATE new_buffer ,
+ yyscan_t yyscanner );
+void cmDependsJava_yypop_buffer_state (yyscan_t yyscanner );
+
+YY_BUFFER_STATE cmDependsJava_yy_scan_buffer (char *base,yy_size_t size ,
+ yyscan_t yyscanner );
+YY_BUFFER_STATE cmDependsJava_yy_scan_string (yyconst char *yy_str ,
+ yyscan_t yyscanner );
+YY_BUFFER_STATE cmDependsJava_yy_scan_bytes (yyconst char *bytes,int len ,
+ yyscan_t yyscanner );
+
+void *cmDependsJava_yyalloc (yy_size_t ,yyscan_t yyscanner );
+void *cmDependsJava_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
+void cmDependsJava_yyfree (void * ,yyscan_t yyscanner );
+
+/* Begin user sect3 */
+
+#define cmDependsJava_yywrap(n) 1
+#define YY_SKIP_YYWRAP
+
+#define yytext_ptr yytext_r
+
+#ifdef YY_HEADER_EXPORT_START_CONDITIONS
+#define INITIAL 0
+#define comment 1
+#define string 2
+
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int cmDependsJava_yylex_destroy (yyscan_t yyscanner );
+
+int cmDependsJava_yyget_debug (yyscan_t yyscanner );
+
+void cmDependsJava_yyset_debug (int debug_flag ,yyscan_t yyscanner );
+
+YY_EXTRA_TYPE cmDependsJava_yyget_extra (yyscan_t yyscanner );
+
+void cmDependsJava_yyset_extra (YY_EXTRA_TYPE user_defined ,
+ yyscan_t yyscanner );
+
+FILE *cmDependsJava_yyget_in (yyscan_t yyscanner );
+
+void cmDependsJava_yyset_in (FILE * in_str ,yyscan_t yyscanner );
+
+FILE *cmDependsJava_yyget_out (yyscan_t yyscanner );
+
+void cmDependsJava_yyset_out (FILE * out_str ,yyscan_t yyscanner );
+
+int cmDependsJava_yyget_leng (yyscan_t yyscanner );
+
+char *cmDependsJava_yyget_text (yyscan_t yyscanner );
+
+int cmDependsJava_yyget_lineno (yyscan_t yyscanner );
+
+void cmDependsJava_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 cmDependsJava_yywrap (yyscan_t yyscanner );
+#else
+extern int cmDependsJava_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
+#define YY_READ_BUF_SIZE 8192
+#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 cmDependsJava_yylex (yyscan_t yyscanner);
+
+#define YY_DECL int cmDependsJava_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 yytext_ptr
+#undef YY_DO_BEFORE_ACTION
+
+#ifdef YY_DECL_IS_OURS
+#undef YY_DECL_IS_OURS
+#undef YY_DECL
+#endif
+
+#undef cmDependsJava_yyIN_HEADER
+#endif /* cmDependsJava_yyHEADER_H */
diff --git a/Source/cmDependsJavaLexer.in.l b/Source/cmDependsJavaLexer.in.l
new file mode 100644
index 000000000..aae7ec658
--- /dev/null
+++ b/Source/cmDependsJavaLexer.in.l
@@ -0,0 +1,188 @@
+%{
+/*============================================================================
+ 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.
+============================================================================*/
+/*
+
+This file must be translated to C and modified to build everywhere.
+
+Run flex like this:
+
+ flex --prefix=cmDependsJava_yy --header-file=cmDependsJavaLexer.h -ocmDependsJavaLexer.cxx cmDependsJavaLexer.in.l
+
+Modify cmDependsJavaLexer.c:
+ - remove TABs
+ - remove "yyscanner" argument from these methods:
+ yy_fatal_error, cmDependsJava_yyalloc, cmDependsJava_yyrealloc, cmDependsJava_yyfree
+ - remove all YY_BREAK lines occurring right after return statements
+ - change while ( 1 ) to for(;;)
+
+Modify cmDependsJavaLexer.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"
+
+#include "cmDependsJavaParserHelper.h"
+
+/* Replace the lexer input function. */
+#undef YY_INPUT
+#define YY_INPUT(buf, result, max_size) \
+ { result = yyextra->LexInput(buf, max_size); }
+
+/* Include the set of tokens from the parser. */
+#include "cmDependsJavaParserTokens.h"
+
+#define KEYWORD yylvalp->str = 0
+#define SYMBOL yylvalp->str = 0
+#define PRIMITIVE yylvalp->str = 0
+
+/*--------------------------------------------------------------------------*/
+%}
+
+%option reentrant
+%option noyywrap
+%pointer
+
+%x comment
+%x string
+
+%%
+"/*" { BEGIN(comment); }
+<comment>"*/" { BEGIN(INITIAL); }
+<comment>.|\n {}
+
+\" { BEGIN(string); }
+<string>\" { BEGIN(INITIAL); return jp_STRINGLITERAL; }
+<string>. {}
+
+abstract { KEYWORD; return jp_ABSTRACT; }
+assert { KEYWORD; return jp_ASSERT; }
+boolean { KEYWORD; return jp_BOOLEAN_TYPE; }
+break { KEYWORD; return jp_BREAK; }
+byte { KEYWORD; return jp_BYTE_TYPE; }
+case { KEYWORD; return jp_CASE; }
+catch { KEYWORD; return jp_CATCH; }
+char { KEYWORD; return jp_CHAR_TYPE; }
+class { KEYWORD; return jp_CLASS; }
+continue { KEYWORD; return jp_CONTINUE; }
+default { KEYWORD; return jp_DEFAULT; }
+do { KEYWORD; return jp_DO; }
+double { KEYWORD; return jp_DOUBLE_TYPE; }
+else { KEYWORD; return jp_ELSE; }
+extends { KEYWORD; return jp_EXTENDS; }
+final { KEYWORD; return jp_FINAL; }
+finally { KEYWORD; return jp_FINALLY; }
+float { KEYWORD; return jp_FLOAT_TYPE; }
+for { KEYWORD; return jp_FOR; }
+if { KEYWORD; return jp_IF; }
+implements { KEYWORD; return jp_IMPLEMENTS; }
+import { KEYWORD; return jp_IMPORT; }
+instanceof { KEYWORD; return jp_INSTANCEOF; }
+int { KEYWORD; return jp_INT_TYPE; }
+interface { KEYWORD; return jp_INTERFACE; }
+long { KEYWORD; return jp_LONG_TYPE; }
+native { KEYWORD; return jp_NATIVE; }
+new { KEYWORD; return jp_NEW; }
+package { KEYWORD; return jp_PACKAGE; }
+private { KEYWORD; return jp_PRIVATE; }
+protected { KEYWORD; return jp_PROTECTED; }
+public { KEYWORD; return jp_PUBLIC; }
+return { KEYWORD; return jp_RETURN; }
+short { KEYWORD; return jp_SHORT_TYPE; }
+static { KEYWORD; return jp_STATIC; }
+strictfp { KEYWORD; return jp_STRICTFP; }
+super { KEYWORD; return jp_SUPER; }
+switch { KEYWORD; return jp_SWITCH; }
+synchronized { KEYWORD; return jp_SYNCHRONIZED; }
+this { KEYWORD; return jp_THIS; }
+throw { KEYWORD; return jp_THROW; }
+throws { KEYWORD; return jp_THROWS; }
+transient { KEYWORD; return jp_TRANSIENT; }
+try { KEYWORD; return jp_TRY; }
+void { KEYWORD; return jp_VOID; }
+volatile { KEYWORD; return jp_VOLATILE; }
+while { KEYWORD; return jp_WHILE; }
+
+(true|false) { PRIMITIVE; return jp_BOOLEANLITERAL; }
+\'([^\\]|\\.|\\u[0-9a-fA-F]*|\\[0-7]*)\' { PRIMITIVE; return jp_CHARACTERLITERAL; }
+(0|[0-9]+)[lL]? { PRIMITIVE; return jp_DECIMALINTEGERLITERAL; }
+([0-9]+\.[0-9]*|\.[0-9]+|[0-9]+)([eE][+\-]?[0-9]+)?[fFdD]? { PRIMITIVE; return jp_FLOATINGPOINTLITERAL; }
+0[xX][0-9a-fA-F]+[lL]? { PRIMITIVE; return jp_HEXINTEGERLITERAL; }
+null { PRIMITIVE; return jp_NULLLITERAL; }
+
+"&" { SYMBOL; return jp_AND; }
+"&&" { SYMBOL; return jp_ANDAND; }
+"&=" { SYMBOL; return jp_ANDEQUALS; }
+"\]" { SYMBOL; return jp_BRACKETEND; }
+"\[" { SYMBOL; return jp_BRACKETSTART; }
+"\^" { SYMBOL; return jp_CARROT; }
+"\^=" { SYMBOL; return jp_CARROTEQUALS; }
+":" { SYMBOL; return jp_COLON; }
+"," { SYMBOL; return jp_COMMA; }
+"}" { SYMBOL; return jp_CURLYEND; }
+"{" { SYMBOL; return jp_CURLYSTART; }
+"/" { SYMBOL; return jp_DIVIDE; }
+"/=" { SYMBOL; return jp_DIVIDEEQUALS; }
+"\$" { SYMBOL; return jp_DOLLAR; }
+"\." { SYMBOL; return jp_DOT; }
+"=" { SYMBOL; return jp_EQUALS; }
+"==" { SYMBOL; return jp_EQUALSEQUALS; }
+"\!" { SYMBOL; return jp_EXCLAMATION; }
+"\!=" { SYMBOL; return jp_EXCLAMATIONEQUALS; }
+">" { SYMBOL; return jp_GREATER; }
+">=" { SYMBOL; return jp_GTEQUALS; }
+">>" { SYMBOL; return jp_GTGT; }
+">>=" { SYMBOL; return jp_GTGTEQUALS; }
+">>>" { SYMBOL; return jp_GTGTGT; }
+">>>=" { SYMBOL; return jp_GTGTGTEQUALS; }
+"<<=" { SYMBOL; return jp_LESLESEQUALS; }
+"<" { SYMBOL; return jp_LESSTHAN; }
+"<=" { SYMBOL; return jp_LTEQUALS; }
+"<<" { SYMBOL; return jp_LTLT; }
+"-" { SYMBOL; return jp_MINUS; }
+"-=" { SYMBOL; return jp_MINUSEQUALS; }
+"--" { SYMBOL; return jp_MINUSMINUS; }
+"\)" { SYMBOL; return jp_PAREEND; }
+"\(" { SYMBOL; return jp_PARESTART; }
+"%" { SYMBOL; return jp_PERCENT; }
+"%=" { SYMBOL; return jp_PERCENTEQUALS; }
+"\|" { SYMBOL; return jp_PIPE; }
+"\|=" { SYMBOL; return jp_PIPEEQUALS; }
+"\|\|" { SYMBOL; return jp_PIPEPIPE; }
+"\+" { SYMBOL; return jp_PLUS; }
+"\+=" { SYMBOL; return jp_PLUSEQUALS; }
+"\+\+" { SYMBOL; return jp_PLUSPLUS; }
+"\?" { SYMBOL; return jp_QUESTION; }
+";" { SYMBOL; return jp_SEMICOL; }
+"\~" { SYMBOL; return jp_TILDE; }
+"\*" { SYMBOL; return jp_TIMES; }
+"\*=" { SYMBOL; return jp_TIMESEQUALS; }
+
+[a-z_A-Z][a-z_0-9A-Z]* {
+ yyextra->AllocateParserType(yylvalp, yytext, strlen(yytext));
+ return jp_NAME;
+}
+
+\/\/.*\n { }
+[ \f\t\n\r] { }
+. {
+ std::cerr << "Unknown character: " << yytext[0]
+ << " (" << (int)yytext[0] << ")" << std::endl;
+ yyextra->Error("Unknown character");
+ return jp_ERROR;
+}
+
+%%
diff --git a/Source/cmDependsJavaParser.cxx b/Source/cmDependsJavaParser.cxx
new file mode 100644
index 000000000..7f7c385da
--- /dev/null
+++ b/Source/cmDependsJavaParser.cxx
@@ -0,0 +1,6021 @@
+/* A Bison parser, made by GNU Bison 1.875d. */
+
+/* Skeleton parser for Yacc-like parsing with Bison, Copyright (C) 1984,
+ 1989, 1990, 2000, 2001, 2002, 2003, 2004 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 2, 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* As a special exception, when this file is copied by Bison into a
+ Bison output file, you may use that output file without restriction.
+ This special exception was added by the Free Software Foundation
+ in version 1.24 of Bison. */
+
+/* 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. */
+
+/* turn off some warning as this is generated code */
+#if defined(_MSC_VER)
+# pragma warning ( disable : 4702 ) /* unreachable code */
+#endif
+
+/* Identify Bison output. */
+#define YYBISON 1
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers. */
+#define YYPURE 1
+
+/* Using locations. */
+#define YYLSP_NEEDED 0
+
+/* If NAME_PREFIX is specified substitute the variables and functions
+ names. */
+#define yyparse cmDependsJava_yyparse
+#define yylex cmDependsJava_yylex
+#define yyerror cmDependsJava_yyerror
+#define yylval cmDependsJava_yylval
+#define yychar cmDependsJava_yychar
+#define yydebug cmDependsJava_yydebug
+#define yynerrs cmDependsJava_yynerrs
+
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ jp_ABSTRACT = 258,
+ jp_ASSERT = 259,
+ jp_BOOLEAN_TYPE = 260,
+ jp_BREAK = 261,
+ jp_BYTE_TYPE = 262,
+ jp_CASE = 263,
+ jp_CATCH = 264,
+ jp_CHAR_TYPE = 265,
+ jp_CLASS = 266,
+ jp_CONTINUE = 267,
+ jp_DEFAULT = 268,
+ jp_DO = 269,
+ jp_DOUBLE_TYPE = 270,
+ jp_ELSE = 271,
+ jp_EXTENDS = 272,
+ jp_FINAL = 273,
+ jp_FINALLY = 274,
+ jp_FLOAT_TYPE = 275,
+ jp_FOR = 276,
+ jp_IF = 277,
+ jp_IMPLEMENTS = 278,
+ jp_IMPORT = 279,
+ jp_INSTANCEOF = 280,
+ jp_INT_TYPE = 281,
+ jp_INTERFACE = 282,
+ jp_LONG_TYPE = 283,
+ jp_NATIVE = 284,
+ jp_NEW = 285,
+ jp_PACKAGE = 286,
+ jp_PRIVATE = 287,
+ jp_PROTECTED = 288,
+ jp_PUBLIC = 289,
+ jp_RETURN = 290,
+ jp_SHORT_TYPE = 291,
+ jp_STATIC = 292,
+ jp_STRICTFP = 293,
+ jp_SUPER = 294,
+ jp_SWITCH = 295,
+ jp_SYNCHRONIZED = 296,
+ jp_THIS = 297,
+ jp_THROW = 298,
+ jp_THROWS = 299,
+ jp_TRANSIENT = 300,
+ jp_TRY = 301,
+ jp_VOID = 302,
+ jp_VOLATILE = 303,
+ jp_WHILE = 304,
+ jp_BOOLEANLITERAL = 305,
+ jp_CHARACTERLITERAL = 306,
+ jp_DECIMALINTEGERLITERAL = 307,
+ jp_FLOATINGPOINTLITERAL = 308,
+ jp_HEXINTEGERLITERAL = 309,
+ jp_NULLLITERAL = 310,
+ jp_STRINGLITERAL = 311,
+ jp_NAME = 312,
+ jp_AND = 313,
+ jp_ANDAND = 314,
+ jp_ANDEQUALS = 315,
+ jp_BRACKETEND = 316,
+ jp_BRACKETSTART = 317,
+ jp_CARROT = 318,
+ jp_CARROTEQUALS = 319,
+ jp_COLON = 320,
+ jp_COMMA = 321,
+ jp_CURLYEND = 322,
+ jp_CURLYSTART = 323,
+ jp_DIVIDE = 324,
+ jp_DIVIDEEQUALS = 325,
+ jp_DOLLAR = 326,
+ jp_DOT = 327,
+ jp_EQUALS = 328,
+ jp_EQUALSEQUALS = 329,
+ jp_EXCLAMATION = 330,
+ jp_EXCLAMATIONEQUALS = 331,
+ jp_GREATER = 332,
+ jp_GTEQUALS = 333,
+ jp_GTGT = 334,
+ jp_GTGTEQUALS = 335,
+ jp_GTGTGT = 336,
+ jp_GTGTGTEQUALS = 337,
+ jp_LESLESEQUALS = 338,
+ jp_LESSTHAN = 339,
+ jp_LTEQUALS = 340,
+ jp_LTLT = 341,
+ jp_MINUS = 342,
+ jp_MINUSEQUALS = 343,
+ jp_MINUSMINUS = 344,
+ jp_PAREEND = 345,
+ jp_PARESTART = 346,
+ jp_PERCENT = 347,
+ jp_PERCENTEQUALS = 348,
+ jp_PIPE = 349,
+ jp_PIPEEQUALS = 350,
+ jp_PIPEPIPE = 351,
+ jp_PLUS = 352,
+ jp_PLUSEQUALS = 353,
+ jp_PLUSPLUS = 354,
+ jp_QUESTION = 355,
+ jp_SEMICOL = 356,
+ jp_TILDE = 357,
+ jp_TIMES = 358,
+ jp_TIMESEQUALS = 359,
+ jp_ERROR = 360
+ };
+#endif
+#define jp_ABSTRACT 258
+#define jp_ASSERT 259
+#define jp_BOOLEAN_TYPE 260
+#define jp_BREAK 261
+#define jp_BYTE_TYPE 262
+#define jp_CASE 263
+#define jp_CATCH 264
+#define jp_CHAR_TYPE 265
+#define jp_CLASS 266
+#define jp_CONTINUE 267
+#define jp_DEFAULT 268
+#define jp_DO 269
+#define jp_DOUBLE_TYPE 270
+#define jp_ELSE 271
+#define jp_EXTENDS 272
+#define jp_FINAL 273
+#define jp_FINALLY 274
+#define jp_FLOAT_TYPE 275
+#define jp_FOR 276
+#define jp_IF 277
+#define jp_IMPLEMENTS 278
+#define jp_IMPORT 279
+#define jp_INSTANCEOF 280
+#define jp_INT_TYPE 281
+#define jp_INTERFACE 282
+#define jp_LONG_TYPE 283
+#define jp_NATIVE 284
+#define jp_NEW 285
+#define jp_PACKAGE 286
+#define jp_PRIVATE 287
+#define jp_PROTECTED 288
+#define jp_PUBLIC 289
+#define jp_RETURN 290
+#define jp_SHORT_TYPE 291
+#define jp_STATIC 292
+#define jp_STRICTFP 293
+#define jp_SUPER 294
+#define jp_SWITCH 295
+#define jp_SYNCHRONIZED 296
+#define jp_THIS 297
+#define jp_THROW 298
+#define jp_THROWS 299
+#define jp_TRANSIENT 300
+#define jp_TRY 301
+#define jp_VOID 302
+#define jp_VOLATILE 303
+#define jp_WHILE 304
+#define jp_BOOLEANLITERAL 305
+#define jp_CHARACTERLITERAL 306
+#define jp_DECIMALINTEGERLITERAL 307
+#define jp_FLOATINGPOINTLITERAL 308
+#define jp_HEXINTEGERLITERAL 309
+#define jp_NULLLITERAL 310
+#define jp_STRINGLITERAL 311
+#define jp_NAME 312
+#define jp_AND 313
+#define jp_ANDAND 314
+#define jp_ANDEQUALS 315
+#define jp_BRACKETEND 316
+#define jp_BRACKETSTART 317
+#define jp_CARROT 318
+#define jp_CARROTEQUALS 319
+#define jp_COLON 320
+#define jp_COMMA 321
+#define jp_CURLYEND 322
+#define jp_CURLYSTART 323
+#define jp_DIVIDE 324
+#define jp_DIVIDEEQUALS 325
+#define jp_DOLLAR 326
+#define jp_DOT 327
+#define jp_EQUALS 328
+#define jp_EQUALSEQUALS 329
+#define jp_EXCLAMATION 330
+#define jp_EXCLAMATIONEQUALS 331
+#define jp_GREATER 332
+#define jp_GTEQUALS 333
+#define jp_GTGT 334
+#define jp_GTGTEQUALS 335
+#define jp_GTGTGT 336
+#define jp_GTGTGTEQUALS 337
+#define jp_LESLESEQUALS 338
+#define jp_LESSTHAN 339
+#define jp_LTEQUALS 340
+#define jp_LTLT 341
+#define jp_MINUS 342
+#define jp_MINUSEQUALS 343
+#define jp_MINUSMINUS 344
+#define jp_PAREEND 345
+#define jp_PARESTART 346
+#define jp_PERCENT 347
+#define jp_PERCENTEQUALS 348
+#define jp_PIPE 349
+#define jp_PIPEEQUALS 350
+#define jp_PIPEPIPE 351
+#define jp_PLUS 352
+#define jp_PLUSEQUALS 353
+#define jp_PLUSPLUS 354
+#define jp_QUESTION 355
+#define jp_SEMICOL 356
+#define jp_TILDE 357
+#define jp_TIMES 358
+#define jp_TIMESEQUALS 359
+#define jp_ERROR 360
+
+
+
+
+/* Copy the first part of user declarations. */
+#line 1 "cmDependsJavaParser.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.
+============================================================================*/
+/*
+
+This file must be translated to C and modified to build everywhere.
+
+Run bison like this:
+
+ bison --yacc --name-prefix=cmDependsJava_yy
+ --defines=cmDependsJavaParserTokens.h -ocmDependsJavaParser.cxx
+ cmDependsJavaParser.y
+
+Modify cmDependsJavaParser.c:
+ - remove TABs
+
+*/
+
+/* Configure the parser to use a lexer object. */
+#define YYPARSE_PARAM yyscanner
+#define YYLEX_PARAM yyscanner
+#define YYERROR_VERBOSE 1
+#define cmDependsJava_yyerror(x) \
+ cmDependsJavaError(yyscanner, x)
+#define yyGetParser (cmDependsJava_yyget_extra(yyscanner))
+
+/*-------------------------------------------------------------------------*/
+#include "cmDependsJavaParserHelper.h" /* Interface to parser object. */
+#include "cmDependsJavaLexer.h" /* Interface to lexer object. */
+#include "cmDependsJavaParserTokens.h" /* Need YYSTYPE for YY_DECL. */
+
+/* Forward declare the lexer entry point. */
+YY_DECL;
+
+/* Internal utility functions. */
+static void cmDependsJavaError(yyscan_t yyscanner, const char* message);
+
+#define YYDEBUG 1
+#define YYMAXDEPTH 1000000
+
+
+#define jpCheckEmpty(cnt) yyGetParser->CheckEmpty(__LINE__, cnt, yyvsp);
+#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. */
+#endif
+
+
+/* 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
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+typedef int YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+/* Copy the second part of user declarations. */
+
+
+/* Line 214 of yacc.c. */
+#line 372 "cmDependsJavaParser.cxx"
+
+#if ! defined (yyoverflow) || YYERROR_VERBOSE
+
+# ifndef YYFREE
+# define YYFREE free
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# endif
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# ifdef YYSTACK_USE_ALLOCA
+# if YYSTACK_USE_ALLOCA
+# define YYSTACK_ALLOC alloca
+# endif
+# else
+# if defined (alloca) || defined (_ALLOCA_H)
+# define YYSTACK_ALLOC alloca
+# else
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's `empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+# else
+# if defined (__STDC__) || defined (__cplusplus)
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# endif
+# define YYSTACK_ALLOC YYMALLOC
+# define YYSTACK_FREE YYFREE
+# 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
+{
+ short int yyss;
+ YYSTYPE yyvs;
+ };
+
+/* 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 (short int) + sizeof (YYSTYPE)) \
+ + YYSTACK_GAP_MAXIMUM)
+
+/* 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 \
+ { \
+ register YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (To)[yyi] = (From)[yyi]; \
+ } \
+ while (0)
+# endif
+# endif
+
+/* 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) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack, Stack, yysize); \
+ Stack = &yyptr->Stack; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (0)
+
+#endif
+
+#if defined (__STDC__) || defined (__cplusplus)
+ typedef signed char yysigned_char;
+#else
+ typedef short int yysigned_char;
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 23
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 2215
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 106
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 158
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 351
+/* YYNRULES -- Number of states. */
+#define YYNSTATES 575
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
+#define YYUNDEFTOK 2
+#define YYMAXUTOK 360
+
+#define YYTRANSLATE(YYX) \
+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
+static const unsigned char 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, 33, 34,
+ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
+ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
+ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
+ 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
+ 105
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+ YYRHS. */
+static const unsigned short int yyprhs[] =
+{
+ 0, 0, 3, 5, 7, 9, 11, 13, 15, 17,
+ 19, 21, 23, 25, 27, 29, 31, 33, 35, 37,
+ 39, 41, 43, 45, 47, 49, 51, 54, 57, 59,
+ 61, 63, 65, 68, 72, 76, 80, 84, 86, 88,
+ 92, 93, 95, 96, 99, 100, 103, 107, 109, 111,
+ 115, 121, 123, 125, 127, 129, 132, 134, 136, 138,
+ 140, 142, 144, 146, 148, 150, 152, 154, 158, 161,
+ 165, 169, 174, 175, 177, 180, 183, 185, 189, 193,
+ 194, 197, 199, 201, 203, 205, 207, 209, 214, 216,
+ 220, 222, 226, 228, 232, 234, 236, 239, 242, 246,
+ 251, 256, 257, 259, 264, 268, 269, 271, 273, 277,
+ 281, 284, 286, 290, 292, 295, 300, 306, 311, 316,
+ 317, 320, 326, 332, 336, 340, 341, 343, 346, 350,
+ 354, 355, 358, 360, 362, 364, 367, 369, 372, 374,
+ 377, 379, 382, 386, 387, 389, 392, 394, 398, 402,
+ 403, 405, 407, 410, 412, 414, 416, 419, 423, 426,
+ 428, 430, 432, 434, 436, 438, 440, 442, 444, 446,
+ 448, 450, 452, 454, 456, 458, 460, 462, 464, 466,
+ 468, 470, 472, 474, 478, 482, 485, 487, 489, 491,
+ 493, 495, 497, 499, 505, 513, 521, 527, 532, 533,
+ 535, 536, 539, 542, 544, 547, 551, 554, 560, 566,
+ 574, 584, 585, 587, 588, 590, 600, 601, 603, 605,
+ 607, 609, 611, 615, 619, 625, 629, 630, 632, 636,
+ 640, 644, 650, 654, 659, 660, 662, 664, 667, 673,
+ 676, 678, 680, 682, 684, 688, 690, 692, 694, 696,
+ 703, 704, 706, 707, 709, 711, 715, 720, 725, 730,
+ 735, 736, 738, 740, 743, 747, 750, 754, 758, 762,
+ 766, 770, 775, 782, 789, 796, 801, 806, 808, 810,
+ 814, 816, 818, 821, 824, 826, 828, 831, 834, 836,
+ 839, 842, 844, 847, 850, 852, 858, 863, 869, 871,
+ 875, 879, 883, 885, 889, 893, 895, 899, 903, 907,
+ 909, 913, 917, 921, 925, 929, 931, 935, 939, 941,
+ 945, 947, 951, 953, 957, 959, 963, 965, 969, 971,
+ 977, 979, 981, 985, 987, 989, 991, 993, 995, 997,
+ 999, 1001, 1003, 1005, 1007, 1009, 1011, 1013, 1015, 1017,
+ 1019, 1021
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const short int yyrhs[] =
+{
+ 107, 0, -1, 122, -1, 109, -1, 53, -1, 50,
+ -1, 51, -1, 56, -1, 55, -1, 52, -1, 54,
+ -1, 111, -1, 112, -1, 7, -1, 36, -1, 26,
+ -1, 28, -1, 10, -1, 20, -1, 15, -1, 5,
+ -1, 113, -1, 116, -1, 117, -1, 113, -1, 113,
+ -1, 111, 234, -1, 117, 234, -1, 118, -1, 120,
+ -1, 119, -1, 57, -1, 71, 57, -1, 117, 72,
+ 119, -1, 117, 72, 11, -1, 117, 72, 42, -1,
+ 121, 72, 11, -1, 111, -1, 47, -1, 123, 124,
+ 125, -1, -1, 126, -1, -1, 124, 127, -1, -1,
+ 125, 130, -1, 31, 117, 101, -1, 128, -1, 129,
+ -1, 24, 117, 101, -1, 24, 117, 72, 103, 101,
+ -1, 134, -1, 165, -1, 101, -1, 132, -1, 131,
+ 132, -1, 34, -1, 33, -1, 32, -1, 37, -1,
+ 3, -1, 18, -1, 29, -1, 41, -1, 45, -1,
+ 48, -1, 38, -1, 135, 11, 119, -1, 133, 139,
+ -1, 133, 137, 139, -1, 133, 136, 139, -1, 133,
+ 136, 137, 139, -1, -1, 131, -1, 17, 114, -1,
+ 23, 138, -1, 115, -1, 138, 66, 115, -1, 68,
+ 140, 67, -1, -1, 140, 141, -1, 142, -1, 158,
+ -1, 159, -1, 130, -1, 143, -1, 148, -1, 135,
+ 110, 144, 101, -1, 145, -1, 144, 66, 145, -1,
+ 146, -1, 146, 73, 147, -1, 119, -1, 146, 62,
+ 61, -1, 261, -1, 174, -1, 149, 101, -1, 149,
+ 157, -1, 149, 157, 101, -1, 135, 110, 151, 150,
+ -1, 135, 47, 151, 150, -1, -1, 155, -1, 119,
+ 91, 152, 90, -1, 151, 62, 61, -1, -1, 153,
+ -1, 154, -1, 153, 66, 154, -1, 135, 110, 146,
+ -1, 44, 156, -1, 114, -1, 156, 66, 114, -1,
+ 177, -1, 37, 177, -1, 135, 160, 150, 161, -1,
+ 135, 160, 150, 161, 101, -1, 118, 91, 152, 90,
+ -1, 68, 162, 178, 67, -1, -1, 162, 163, -1,
+ 42, 91, 228, 90, 101, -1, 39, 91, 228, 90,
+ 101, -1, 135, 27, 119, -1, 164, 166, 168, -1,
+ -1, 167, -1, 17, 115, -1, 167, 66, 115, -1,
+ 68, 169, 67, -1, -1, 169, 170, -1, 171, -1,
+ 172, -1, 134, -1, 134, 101, -1, 165, -1, 165,
+ 101, -1, 143, -1, 149, 173, -1, 101, -1, 173,
+ 101, -1, 68, 175, 67, -1, -1, 176, -1, 176,
+ 66, -1, 147, -1, 176, 66, 147, -1, 68, 178,
+ 67, -1, -1, 179, -1, 180, -1, 179, 180, -1,
+ 181, -1, 183, -1, 134, -1, 182, 101, -1, 131,
+ 110, 144, -1, 110, 144, -1, 185, -1, 187, -1,
+ 191, -1, 192, -1, 201, -1, 204, -1, 185, -1,
+ 188, -1, 193, -1, 202, -1, 207, -1, 177, -1,
+ 186, -1, 189, -1, 194, -1, 203, -1, 213, -1,
+ 215, -1, 216, -1, 218, -1, 217, -1, 219, -1,
+ 212, -1, 101, -1, 119, 65, 183, -1, 119, 65,
+ 184, -1, 190, 101, -1, 258, -1, 242, -1, 243,
+ -1, 239, -1, 240, -1, 236, -1, 226, -1, 22,
+ 91, 261, 90, 183, -1, 22, 91, 261, 90, 184,
+ 16, 183, -1, 22, 91, 261, 90, 184, 16, 184,
+ -1, 40, 91, 261, 90, 195, -1, 68, 197, 196,
+ 67, -1, -1, 199, -1, -1, 197, 198, -1, 199,
+ 179, -1, 200, -1, 199, 200, -1, 8, 262, 65,
+ -1, 13, 65, -1, 49, 91, 261, 90, 183, -1,
+ 49, 91, 261, 90, 184, -1, 14, 183, 49, 91,
+ 261, 90, 101, -1, 21, 91, 206, 101, 208, 101,
+ 205, 90, 183, -1, -1, 210, -1, -1, 209, -1,
+ 21, 91, 206, 101, 208, 101, 205, 90, 184, -1,
+ -1, 261, -1, 211, -1, 182, -1, 211, -1, 190,
+ -1, 211, 66, 190, -1, 4, 261, 101, -1, 4,
+ 261, 65, 261, 101, -1, 6, 214, 101, -1, -1,
+ 119, -1, 12, 214, 101, -1, 35, 208, 101, -1,
+ 43, 261, 101, -1, 41, 91, 261, 90, 177, -1,
+ 46, 177, 221, -1, 46, 177, 220, 223, -1, -1,
+ 221, -1, 222, -1, 221, 222, -1, 9, 91, 154,
+ 90, 177, -1, 19, 177, -1, 225, -1, 230, -1,
+ 108, -1, 42, -1, 91, 261, 90, -1, 226, -1,
+ 235, -1, 236, -1, 237, -1, 263, 114, 91, 228,
+ 90, 227, -1, -1, 139, -1, -1, 229, -1, 261,
+ -1, 229, 66, 261, -1, 263, 111, 232, 231, -1,
+ 263, 113, 232, 231, -1, 263, 111, 234, 174, -1,
+ 263, 113, 234, 174, -1, -1, 234, -1, 233, -1,
+ 232, 233, -1, 62, 261, 61, -1, 62, 61, -1,
+ 234, 62, 61, -1, 224, 72, 119, -1, 39, 72,
+ 119, -1, 42, 72, 119, -1, 224, 72, 42, -1,
+ 117, 91, 228, 90, -1, 224, 72, 119, 91, 228,
+ 90, -1, 39, 72, 119, 91, 228, 90, -1, 42,
+ 72, 119, 91, 228, 90, -1, 117, 62, 261, 61,
+ -1, 225, 62, 261, 61, -1, 224, -1, 117, -1,
+ 116, 72, 11, -1, 239, -1, 240, -1, 238, 99,
+ -1, 238, 89, -1, 242, -1, 243, -1, 97, 241,
+ -1, 87, 241, -1, 244, -1, 99, 241, -1, 89,
+ 241, -1, 238, -1, 102, 241, -1, 75, 241, -1,
+ 245, -1, 91, 111, 231, 90, 241, -1, 91, 261,
+ 90, 244, -1, 91, 117, 234, 90, 244, -1, 241,
+ -1, 246, 103, 241, -1, 246, 69, 241, -1, 246,
+ 92, 241, -1, 246, -1, 247, 97, 246, -1, 247,
+ 87, 246, -1, 247, -1, 248, 86, 247, -1, 248,
+ 79, 247, -1, 248, 81, 247, -1, 248, -1, 249,
+ 84, 248, -1, 249, 77, 248, -1, 249, 85, 248,
+ -1, 249, 78, 248, -1, 249, 25, 112, -1, 249,
+ -1, 250, 74, 249, -1, 250, 76, 249, -1, 250,
+ -1, 251, 58, 250, -1, 251, -1, 252, 63, 251,
+ -1, 252, -1, 253, 94, 252, -1, 253, -1, 254,
+ 59, 253, -1, 254, -1, 255, 96, 254, -1, 255,
+ -1, 255, 100, 261, 65, 256, -1, 256, -1, 258,
+ -1, 259, 260, 257, -1, 117, -1, 235, -1, 237,
+ -1, 73, -1, 104, -1, 70, -1, 93, -1, 98,
+ -1, 88, -1, 83, -1, 80, -1, 82, -1, 60,
+ -1, 64, -1, 95, -1, 257, -1, 261, -1, 30,
+ -1, 117, 72, 30, -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+static const unsigned short int yyrline[] =
+{
+ 0, 191, 191, 200, 208, 216, 224, 232, 240, 249,
+ 257, 266, 274, 283, 288, 293, 298, 303, 308, 313,
+ 318, 324, 332, 341, 351, 360, 369, 377, 387, 393,
+ 400, 407, 413, 420, 429, 439, 449, 458, 466, 475,
+ 484, 490, 499, 505, 514, 520, 529, 541, 549, 558,
+ 570, 583, 591, 599, 608, 616, 625, 625, 625, 626,
+ 627, 627, 627, 627, 627, 627, 628, 631, 641, 650,
+ 659, 668, 678, 684, 693, 702, 711, 719, 728, 737,
+ 743, 752, 760, 768, 776, 785, 793, 802, 808, 816,
+ 825, 833, 842, 851, 860, 868, 877, 885, 893, 902,
+ 911, 921, 928, 938, 948, 955, 962, 965, 971, 981,
+ 991, 1001, 1007, 1017, 1027, 1037, 1046, 1056, 1067, 1077,
+ 1084, 1094, 1103, 1113, 1122, 1132, 1138, 1148, 1157, 1167,
+ 1177, 1184, 1193, 1202, 1211, 1220, 1228, 1237, 1246, 1256,
+ 1266, 1275, 1285, 1295, 1302, 1311, 1321, 1330, 1340, 1349,
+ 1356, 1366, 1375, 1385, 1394, 1403, 1413, 1423, 1432, 1442,
+ 1451, 1460, 1469, 1478, 1487, 1497, 1506, 1515, 1524, 1533,
+ 1543, 1552, 1561, 1570, 1579, 1588, 1597, 1606, 1615, 1624,
+ 1633, 1642, 1652, 1662, 1673, 1683, 1693, 1702, 1711, 1720,
+ 1729, 1738, 1747, 1757, 1767, 1777, 1787, 1794, 1801, 1808,
+ 1818, 1825, 1835, 1845, 1854, 1864, 1873, 1883, 1890, 1897,
+ 1904, 1912, 1919, 1929, 1936, 1946, 1956, 1963, 1973, 1982,
+ 1992, 2002, 2011, 2021, 2030, 2040, 2051, 2058, 2065, 2076,
+ 2086, 2096, 2106, 2115, 2125, 2132, 2142, 2151, 2161, 2168,
+ 2178, 2187, 2197, 2206, 2212, 2221, 2230, 2239, 2248, 2258,
+ 2268, 2275, 2285, 2292, 2302, 2311, 2321, 2330, 2339, 2348,
+ 2358, 2365, 2375, 2384, 2394, 2404, 2410, 2417, 2427, 2437,
+ 2447, 2458, 2468, 2479, 2489, 2500, 2510, 2520, 2529, 2538,
+ 2547, 2556, 2566, 2576, 2586, 2595, 2604, 2613, 2622, 2632,
+ 2642, 2652, 2661, 2670, 2679, 2689, 2698, 2707, 2714, 2723,
+ 2732, 2741, 2751, 2760, 2769, 2779, 2788, 2797, 2806, 2816,
+ 2825, 2834, 2843, 2852, 2861, 2871, 2880, 2889, 2899, 2908,
+ 2918, 2927, 2937, 2946, 2956, 2965, 2975, 2984, 2994, 3003,
+ 3013, 3022, 3032, 3042, 3052, 3061, 3071, 3080, 3089, 3098,
+ 3107, 3116, 3125, 3134, 3143, 3152, 3161, 3170, 3180, 3190,
+ 3200, 3209
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE
+/* YYTNME[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", "jp_ABSTRACT", "jp_ASSERT",
+ "jp_BOOLEAN_TYPE", "jp_BREAK", "jp_BYTE_TYPE", "jp_CASE", "jp_CATCH",
+ "jp_CHAR_TYPE", "jp_CLASS", "jp_CONTINUE", "jp_DEFAULT", "jp_DO",
+ "jp_DOUBLE_TYPE", "jp_ELSE", "jp_EXTENDS", "jp_FINAL", "jp_FINALLY",
+ "jp_FLOAT_TYPE", "jp_FOR", "jp_IF", "jp_IMPLEMENTS", "jp_IMPORT",
+ "jp_INSTANCEOF", "jp_INT_TYPE", "jp_INTERFACE", "jp_LONG_TYPE",
+ "jp_NATIVE", "jp_NEW", "jp_PACKAGE", "jp_PRIVATE", "jp_PROTECTED",
+ "jp_PUBLIC", "jp_RETURN", "jp_SHORT_TYPE", "jp_STATIC", "jp_STRICTFP",
+ "jp_SUPER", "jp_SWITCH", "jp_SYNCHRONIZED", "jp_THIS", "jp_THROW",
+ "jp_THROWS", "jp_TRANSIENT", "jp_TRY", "jp_VOID", "jp_VOLATILE",
+ "jp_WHILE", "jp_BOOLEANLITERAL", "jp_CHARACTERLITERAL",
+ "jp_DECIMALINTEGERLITERAL", "jp_FLOATINGPOINTLITERAL",
+ "jp_HEXINTEGERLITERAL", "jp_NULLLITERAL", "jp_STRINGLITERAL", "jp_NAME",
+ "jp_AND", "jp_ANDAND", "jp_ANDEQUALS", "jp_BRACKETEND",
+ "jp_BRACKETSTART", "jp_CARROT", "jp_CARROTEQUALS", "jp_COLON",
+ "jp_COMMA", "jp_CURLYEND", "jp_CURLYSTART", "jp_DIVIDE",
+ "jp_DIVIDEEQUALS", "jp_DOLLAR", "jp_DOT", "jp_EQUALS", "jp_EQUALSEQUALS",
+ "jp_EXCLAMATION", "jp_EXCLAMATIONEQUALS", "jp_GREATER", "jp_GTEQUALS",
+ "jp_GTGT", "jp_GTGTEQUALS", "jp_GTGTGT", "jp_GTGTGTEQUALS",
+ "jp_LESLESEQUALS", "jp_LESSTHAN", "jp_LTEQUALS", "jp_LTLT", "jp_MINUS",
+ "jp_MINUSEQUALS", "jp_MINUSMINUS", "jp_PAREEND", "jp_PARESTART",
+ "jp_PERCENT", "jp_PERCENTEQUALS", "jp_PIPE", "jp_PIPEEQUALS",
+ "jp_PIPEPIPE", "jp_PLUS", "jp_PLUSEQUALS", "jp_PLUSPLUS", "jp_QUESTION",
+ "jp_SEMICOL", "jp_TILDE", "jp_TIMES", "jp_TIMESEQUALS", "jp_ERROR",
+ "$accept", "Goal", "Literal", "IntegerLiteral", "Type", "PrimitiveType",
+ "ReferenceType", "ClassOrInterfaceType", "ClassType", "InterfaceType",
+ "ArrayType", "Name", "SimpleName", "Identifier", "QualifiedName",
+ "SimpleType", "CompilationUnit", "PackageDeclarationopt",
+ "ImportDeclarations", "TypeDeclarations", "PackageDeclaration",
+ "ImportDeclaration", "SingleTypeImportDeclaration",
+ "TypeImportOnDemandDeclaration", "TypeDeclaration", "Modifiers",
+ "Modifier", "ClassHeader", "ClassDeclaration", "Modifiersopt", "Super",
+ "Interfaces", "InterfaceTypeList", "ClassBody", "ClassBodyDeclarations",
+ "ClassBodyDeclaration", "ClassMemberDeclaration", "FieldDeclaration",
+ "VariableDeclarators", "VariableDeclarator", "VariableDeclaratorId",
+ "VariableInitializer", "MethodDeclaration", "MethodHeader", "Throwsopt",
+ "MethodDeclarator", "FormalParameterListopt", "FormalParameterList",
+ "FormalParameter", "Throws", "ClassTypeList", "MethodBody",
+ "StaticInitializer", "ConstructorDeclaration", "ConstructorDeclarator",
+ "ConstructorBody", "ExplicitConstructorInvocationopt",
+ "ExplicitConstructorInvocation", "InterfaceHeader",
+ "InterfaceDeclaration", "ExtendsInterfacesopt", "ExtendsInterfaces",
+ "InterfaceBody", "InterfaceMemberDeclarations",
+ "InterfaceMemberDeclaration", "ConstantDeclaration",
+ "AbstractMethodDeclaration", "Semicols", "ArrayInitializer",
+ "VariableInitializersOptional", "VariableInitializers", "Block",
+ "BlockStatementsopt", "BlockStatements", "BlockStatement",
+ "LocalVariableDeclarationStatement", "LocalVariableDeclaration",
+ "Statement", "StatementNoShortIf",
+ "StatementWithoutTrailingSubstatement", "EmptyStatement",
+ "LabeledStatement", "LabeledStatementNoShortIf", "ExpressionStatement",
+ "StatementExpression", "IfThenStatement", "IfThenElseStatement",
+ "IfThenElseStatementNoShortIf", "SwitchStatement", "SwitchBlock",
+ "SwitchLabelsopt", "SwitchBlockStatementGroups",
+ "SwitchBlockStatementGroup", "SwitchLabels", "SwitchLabel",
+ "WhileStatement", "WhileStatementNoShortIf", "DoStatement",
+ "ForStatement", "ForUpdateopt", "ForInitopt", "ForStatementNoShortIf",
+ "Expressionopt", "ForInit", "ForUpdate", "StatementExpressionList",
+ "AssertStatement", "BreakStatement", "Identifieropt",
+ "ContinueStatement", "ReturnStatement", "ThrowStatement",
+ "SynchronizedStatement", "TryStatement", "Catchesopt", "Catches",
+ "CatchClause", "Finally", "Primary", "PrimaryNoNewArray",
+ "ClassInstanceCreationExpression", "ClassBodyOpt", "ArgumentListopt",
+ "ArgumentList", "ArrayCreationExpression", "Dimsopt", "DimExprs",
+ "DimExpr", "Dims", "FieldAccess", "MethodInvocation", "ArrayAccess",
+ "PostfixExpression", "PostIncrementExpression",
+ "PostDecrementExpression", "UnaryExpression", "PreIncrementExpression",
+ "PreDecrementExpression", "UnaryExpressionNotPlusMinus",
+ "CastExpression", "MultiplicativeExpression", "AdditiveExpression",
+ "ShiftExpression", "RelationalExpression", "EqualityExpression",
+ "AndExpression", "ExclusiveOrExpression", "InclusiveOrExpression",
+ "ConditionalAndExpression", "ConditionalOrExpression",
+ "ConditionalExpression", "AssignmentExpression", "Assignment",
+ "LeftHandSide", "AssignmentOperator", "Expression", "ConstantExpression",
+ "New", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+ token YYLEX-NUM. */
+static const unsigned short int 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, 288, 289, 290, 291, 292, 293, 294,
+ 295, 296, 297, 298, 299, 300, 301, 302, 303, 304,
+ 305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
+ 315, 316, 317, 318, 319, 320, 321, 322, 323, 324,
+ 325, 326, 327, 328, 329, 330, 331, 332, 333, 334,
+ 335, 336, 337, 338, 339, 340, 341, 342, 343, 344,
+ 345, 346, 347, 348, 349, 350, 351, 352, 353, 354,
+ 355, 356, 357, 358, 359, 360
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const unsigned short int yyr1[] =
+{
+ 0, 106, 107, 108, 108, 108, 108, 108, 108, 109,
+ 109, 110, 110, 111, 111, 111, 111, 111, 111, 111,
+ 111, 112, 112, 113, 114, 115, 116, 116, 117, 117,
+ 118, 119, 119, 120, 120, 120, 120, 121, 121, 122,
+ 123, 123, 124, 124, 125, 125, 126, 127, 127, 128,
+ 129, 130, 130, 130, 131, 131, 132, 132, 132, 132,
+ 132, 132, 132, 132, 132, 132, 132, 133, 134, 134,
+ 134, 134, 135, 135, 136, 137, 138, 138, 139, 140,
+ 140, 141, 141, 141, 141, 142, 142, 143, 144, 144,
+ 145, 145, 146, 146, 147, 147, 148, 148, 148, 149,
+ 149, 150, 150, 151, 151, 152, 152, 153, 153, 154,
+ 155, 156, 156, 157, 158, 159, 159, 160, 161, 162,
+ 162, 163, 163, 164, 165, 166, 166, 167, 167, 168,
+ 169, 169, 170, 170, 170, 170, 170, 170, 171, 172,
+ 173, 173, 174, 175, 175, 175, 176, 176, 177, 178,
+ 178, 179, 179, 180, 180, 180, 181, 182, 182, 183,
+ 183, 183, 183, 183, 183, 184, 184, 184, 184, 184,
+ 185, 185, 185, 185, 185, 185, 185, 185, 185, 185,
+ 185, 185, 186, 187, 188, 189, 190, 190, 190, 190,
+ 190, 190, 190, 191, 192, 193, 194, 195, 196, 196,
+ 197, 197, 198, 199, 199, 200, 200, 201, 202, 203,
+ 204, 205, 205, 206, 206, 207, 208, 208, 209, 209,
+ 210, 211, 211, 212, 212, 213, 214, 214, 215, 216,
+ 217, 218, 219, 219, 220, 220, 221, 221, 222, 223,
+ 224, 224, 225, 225, 225, 225, 225, 225, 225, 226,
+ 227, 227, 228, 228, 229, 229, 230, 230, 230, 230,
+ 231, 231, 232, 232, 233, 234, 234, 235, 235, 235,
+ 235, 236, 236, 236, 236, 237, 237, 238, 238, 238,
+ 238, 238, 239, 240, 241, 241, 241, 241, 241, 242,
+ 243, 244, 244, 244, 244, 245, 245, 245, 246, 246,
+ 246, 246, 247, 247, 247, 248, 248, 248, 248, 249,
+ 249, 249, 249, 249, 249, 250, 250, 250, 251, 251,
+ 252, 252, 253, 253, 254, 254, 255, 255, 256, 256,
+ 257, 257, 258, 259, 259, 259, 260, 260, 260, 260,
+ 260, 260, 260, 260, 260, 260, 260, 260, 261, 262,
+ 263, 263
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
+static const unsigned char yyr2[] =
+{
+ 0, 2, 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, 2, 1, 1,
+ 1, 1, 2, 3, 3, 3, 3, 1, 1, 3,
+ 0, 1, 0, 2, 0, 2, 3, 1, 1, 3,
+ 5, 1, 1, 1, 1, 2, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 3, 2, 3,
+ 3, 4, 0, 1, 2, 2, 1, 3, 3, 0,
+ 2, 1, 1, 1, 1, 1, 1, 4, 1, 3,
+ 1, 3, 1, 3, 1, 1, 2, 2, 3, 4,
+ 4, 0, 1, 4, 3, 0, 1, 1, 3, 3,
+ 2, 1, 3, 1, 2, 4, 5, 4, 4, 0,
+ 2, 5, 5, 3, 3, 0, 1, 2, 3, 3,
+ 0, 2, 1, 1, 1, 2, 1, 2, 1, 2,
+ 1, 2, 3, 0, 1, 2, 1, 3, 3, 0,
+ 1, 1, 2, 1, 1, 1, 2, 3, 2, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 3, 3, 2, 1, 1, 1, 1,
+ 1, 1, 1, 5, 7, 7, 5, 4, 0, 1,
+ 0, 2, 2, 1, 2, 3, 2, 5, 5, 7,
+ 9, 0, 1, 0, 1, 9, 0, 1, 1, 1,
+ 1, 1, 3, 3, 5, 3, 0, 1, 3, 3,
+ 3, 5, 3, 4, 0, 1, 1, 2, 5, 2,
+ 1, 1, 1, 1, 3, 1, 1, 1, 1, 6,
+ 0, 1, 0, 1, 1, 3, 4, 4, 4, 4,
+ 0, 1, 1, 2, 3, 2, 3, 3, 3, 3,
+ 3, 4, 6, 6, 6, 4, 4, 1, 1, 3,
+ 1, 1, 2, 2, 1, 1, 2, 2, 1, 2,
+ 2, 1, 2, 2, 1, 5, 4, 5, 1, 3,
+ 3, 3, 1, 3, 3, 1, 3, 3, 3, 1,
+ 3, 3, 3, 3, 3, 1, 3, 3, 1, 3,
+ 1, 3, 1, 3, 1, 3, 1, 3, 1, 5,
+ 1, 1, 3, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 3
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero
+ means the default is an error. */
+static const unsigned short int yydefact[] =
+{
+ 40, 0, 0, 2, 42, 41, 20, 13, 17, 19,
+ 18, 15, 16, 14, 38, 31, 0, 37, 0, 28,
+ 30, 29, 0, 1, 44, 32, 0, 46, 0, 0,
+ 72, 43, 47, 48, 34, 35, 33, 36, 0, 60,
+ 61, 62, 58, 57, 56, 59, 66, 63, 64, 65,
+ 53, 45, 73, 54, 0, 51, 0, 125, 52, 0,
+ 49, 55, 0, 0, 79, 0, 0, 68, 0, 0,
+ 0, 0, 126, 0, 24, 74, 23, 25, 76, 75,
+ 72, 0, 70, 69, 67, 123, 127, 130, 124, 0,
+ 50, 0, 59, 78, 84, 0, 80, 81, 85, 86,
+ 0, 82, 83, 71, 72, 128, 77, 72, 114, 38,
+ 0, 11, 12, 21, 22, 23, 28, 101, 96, 97,
+ 113, 129, 134, 0, 138, 0, 136, 131, 132, 133,
+ 0, 226, 226, 0, 0, 0, 350, 216, 0, 0,
+ 63, 243, 0, 0, 0, 5, 6, 9, 4, 10,
+ 8, 7, 0, 0, 0, 182, 242, 3, 0, 22,
+ 333, 30, 73, 155, 0, 170, 0, 72, 151, 153,
+ 0, 154, 159, 171, 160, 172, 0, 161, 162, 173,
+ 163, 174, 164, 181, 175, 176, 177, 179, 178, 180,
+ 277, 240, 245, 241, 246, 247, 248, 0, 189, 190,
+ 187, 188, 186, 0, 0, 0, 101, 92, 0, 88,
+ 90, 101, 0, 26, 27, 72, 0, 0, 102, 98,
+ 135, 140, 139, 137, 0, 0, 0, 0, 0, 37,
+ 0, 278, 245, 247, 291, 280, 281, 298, 284, 285,
+ 288, 294, 302, 305, 309, 315, 318, 320, 322, 324,
+ 326, 328, 330, 348, 331, 0, 227, 0, 0, 0,
+ 0, 213, 0, 0, 217, 0, 0, 0, 0, 0,
+ 234, 0, 278, 246, 248, 290, 0, 289, 92, 158,
+ 0, 0, 0, 252, 0, 0, 148, 152, 156, 185,
+ 0, 0, 283, 282, 345, 346, 338, 336, 343, 344,
+ 342, 341, 339, 347, 340, 337, 0, 37, 24, 0,
+ 72, 0, 100, 0, 87, 0, 0, 99, 265, 0,
+ 0, 0, 106, 107, 111, 110, 119, 115, 141, 293,
+ 287, 37, 278, 0, 286, 292, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 223, 225,
+ 228, 0, 0, 219, 221, 0, 214, 218, 0, 229,
+ 268, 0, 0, 269, 230, 0, 0, 232, 236, 0,
+ 244, 279, 0, 351, 0, 253, 254, 183, 157, 270,
+ 267, 0, 332, 0, 260, 262, 0, 260, 0, 252,
+ 0, 104, 89, 93, 143, 91, 95, 94, 266, 0,
+ 117, 72, 0, 72, 116, 0, 26, 27, 244, 300,
+ 301, 299, 304, 303, 307, 308, 306, 314, 311, 313,
+ 310, 312, 316, 317, 319, 321, 323, 325, 327, 0,
+ 0, 0, 216, 0, 0, 252, 0, 0, 252, 72,
+ 0, 233, 237, 0, 275, 271, 0, 252, 276, 0,
+ 256, 263, 261, 258, 257, 259, 0, 103, 146, 0,
+ 144, 109, 108, 112, 0, 243, 120, 0, 0, 0,
+ 296, 0, 224, 0, 0, 222, 0, 0, 0, 30,
+ 193, 0, 159, 166, 167, 168, 169, 0, 200, 196,
+ 231, 0, 0, 239, 207, 255, 0, 264, 250, 142,
+ 145, 252, 252, 118, 295, 297, 329, 0, 211, 213,
+ 0, 0, 0, 0, 273, 198, 274, 0, 272, 251,
+ 249, 147, 0, 0, 209, 0, 212, 220, 0, 0,
+ 0, 184, 194, 0, 0, 0, 201, 72, 203, 238,
+ 0, 0, 0, 216, 0, 0, 349, 0, 206, 197,
+ 202, 204, 122, 121, 210, 0, 0, 208, 205, 211,
+ 0, 0, 195, 0, 215
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const short int yydefgoto[] =
+{
+ -1, 2, 156, 157, 158, 229, 112, 113, 75, 78,
+ 230, 231, 19, 20, 21, 22, 3, 4, 24, 30,
+ 5, 31, 32, 33, 51, 52, 53, 54, 163, 164,
+ 65, 66, 79, 67, 80, 96, 97, 98, 208, 209,
+ 210, 405, 99, 100, 217, 206, 321, 322, 323, 218,
+ 325, 119, 101, 102, 117, 327, 413, 476, 57, 58,
+ 71, 72, 88, 104, 127, 128, 129, 222, 406, 469,
+ 470, 165, 166, 167, 168, 169, 170, 171, 491, 172,
+ 173, 174, 493, 175, 176, 177, 178, 494, 179, 499,
+ 545, 525, 546, 547, 548, 180, 495, 181, 182, 535,
+ 365, 496, 263, 366, 536, 367, 183, 184, 257, 185,
+ 186, 187, 188, 189, 376, 377, 378, 451, 190, 191,
+ 232, 530, 384, 385, 193, 415, 394, 395, 214, 194,
+ 233, 196, 234, 235, 236, 237, 238, 239, 240, 241,
+ 242, 243, 244, 245, 246, 247, 248, 249, 250, 251,
+ 252, 253, 254, 203, 306, 386, 557, 204
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+#define YYPACT_NINF -503
+static const short int yypact[] =
+{
+ 159, 1039, 236, -503, -503, -503, -503, -503, -503, -503,
+ -503, -503, -503, -503, -503, -503, 186, -503, 56, -503,
+ -503, -503, 178, -503, 35, -503, 21, -503, 248, 1039,
+ 273, -503, -503, -503, -503, -503, -503, -503, 78, -503,
+ -503, -503, -503, -503, -503, -503, -503, -503, -503, -503,
+ -503, -503, 2088, -503, 32, -503, 16, 245, -503, 28,
+ -503, -503, 1039, 1039, -503, 80, 206, -503, 129, 129,
+ 1039, 221, 228, 194, -503, -503, 225, -503, -503, 234,
+ 164, 206, -503, -503, -503, -503, -503, -503, -503, 1039,
+ -503, 1039, 233, -503, -503, 739, -503, -503, -503, -503,
+ -49, -503, -503, -503, 1116, -503, -503, 1276, -503, 129,
+ 129, 40, -503, -503, -503, 122, 212, 265, -503, 215,
+ -503, -503, 219, 739, -503, 222, 224, -503, -503, -503,
+ 1820, 129, 129, 1627, 237, 238, -503, 1820, 241, 239,
+ 242, 283, 1820, 233, 266, -503, -503, -503, -503, -503,
+ -503, -503, 1820, 1820, 1820, -503, -503, -503, 129, 284,
+ 476, 293, 2067, -503, 349, -503, 296, 1366, -503, -503,
+ 264, -503, -503, -503, -503, -503, 268, -503, -503, -503,
+ -503, -503, -503, -503, -503, -503, -503, -503, -503, -503,
+ 294, 305, 72, -503, 2070, 88, 2084, 121, 130, 148,
+ -503, -503, -503, 2111, 1039, 281, 133, 281, -25, -503,
+ 126, 133, 314, 315, 315, 921, 1039, 308, -503, -503,
+ -503, -503, 277, -503, 1820, 1820, 1820, 1820, 1820, 317,
+ 284, 545, -503, -503, 121, -503, -503, -503, -503, -503,
+ -503, -503, 73, 124, 163, 59, 196, 323, 319, 290,
+ 324, 18, -503, -503, -503, -30, -503, 285, 286, 242,
+ 342, 1941, 1820, 291, -503, 129, 1820, 1820, 129, 292,
+ 385, 1820, 96, -503, -503, -503, 310, -503, -503, 329,
+ 387, 1085, 3, 1820, 1627, 129, -503, -503, -503, -503,
+ 175, 1820, -503, -503, -503, -503, -503, -503, -503, -503,
+ -503, -503, -503, -503, -503, -503, 1820, 339, 339, 311,
+ 921, 343, -503, 129, -503, 344, 1766, -503, -503, 346,
+ 1039, 313, 347, -503, -503, 353, -503, 307, -503, -503,
+ -503, 6, 545, 326, -503, -503, 1820, 1820, 1820, 1820,
+ 1820, 1820, 1820, 1820, 1039, 1820, 1820, 1820, 1820, 1820,
+ 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, -503, -503,
+ -503, 330, 2067, -503, -503, 327, -503, 354, 334, -503,
+ 345, 335, 340, 348, -503, 351, 416, 232, -503, 356,
+ -503, -503, 376, -503, 357, 377, -503, -503, 329, -503,
+ 358, 390, -503, 1085, 339, -503, 154, 339, 154, 1820,
+ 362, -503, -503, -503, 1766, -503, -503, -503, -503, 129,
+ -503, 2088, 1039, 1456, -503, 363, 70, 93, 1874, -503,
+ -503, -503, 73, 73, 124, 124, 124, -503, 163, 163,
+ 163, 163, 59, 59, 196, 323, 319, 290, 324, 383,
+ 360, 1820, 1820, 1995, 1699, 1820, 386, 233, 1820, 2088,
+ 233, -503, -503, 1627, -503, -503, 1820, 1820, -503, 394,
+ -503, -503, 315, -503, -503, -503, 369, -503, -503, 396,
+ 404, 410, -503, -503, 26, 113, -503, 407, 1820, 1874,
+ -503, 1820, -503, 391, 374, -503, 393, 395, 397, 411,
+ -503, 466, 471, -503, -503, -503, -503, 399, -503, -503,
+ -503, 400, 401, -503, -503, -503, 402, -503, 206, -503,
+ 1766, 1820, 1820, -503, -503, -503, -503, 403, 1995, 1941,
+ 1820, 1820, 1699, 1627, -503, 34, -503, 233, -503, -503,
+ -503, -503, 405, 412, -503, 413, -503, 354, 406, 418,
+ 421, -503, -503, 1820, 429, 430, -503, 1186, -503, -503,
+ 419, 422, 1627, 1820, 1699, 1699, -503, 447, -503, -503,
+ 1555, -503, -503, -503, -503, 423, 497, -503, -503, 1995,
+ 1699, 432, -503, 1699, -503
+};
+
+/* YYPGOTO[NTERM-NUM]. */
+static const short int yypgoto[] =
+{
+ -503, -503, -503, -503, -85, 2, 181, -41, -198, -45,
+ -87, -1, 431, 14, -503, -503, -503, -503, -503, -503,
+ -503, -503, -503, -503, 448, -81, -47, -503, 7, -23,
+ -503, 462, -503, -64, -503, -503, -503, 425, -146, 217,
+ 123, -391, -503, 427, -101, 424, 230, -503, -360, -503,
+ -503, -503, -503, -503, -503, -503, -503, -503, -503, 439,
+ -503, -503, -503, -503, -503, -503, -503, -503, -110, -503,
+ -503, -77, 138, -12, -163, -503, -250, -13, -421, -414,
+ -503, -503, -503, -503, -252, -503, -503, -503, -503, -503,
+ -503, -503, -503, -503, 5, -503, -503, -503, -503, -16,
+ 36, -503, -418, -503, -503, -502, -503, -503, 440, -503,
+ -503, -503, -503, -503, -503, -503, 179, -503, -503, -503,
+ -54, -503, -341, -503, -503, -149, 255, -136, 102, 652,
+ 101, 688, 145, 157, 201, -98, 289, 338, -384, -503,
+ -59, -58, -92, -57, 213, 226, 218, 223, 227, -503,
+ 95, 274, 350, -503, -503, 660, -503, -503
+};
+
+/* 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 zero, do what YYDEFACT says.
+ If YYTABLE_NINF, syntax error. */
+#define YYTABLE_NINF -336
+static const short int yytable[] =
+{
+ 18, 82, 83, 17, 287, 61, 309, 56, 114, 364,
+ 110, 363, 279, 468, 34, 108, 537, 103, 324, 107,
+ 159, 74, 77, 120, 484, 86, 162, 68, 38, 77,
+ 492, 17, 34, 383, 480, 357, 114, 55, 110, 34,
+ 36, 313, 543, 69, 105, 35, 106, 544, 77, 62,
+ 77, 472, 118, 192, 275, 63, 277, 95, 466, 29,
+ 15, 76, 76, 35, 17, 17, 270, 537, 212, 76,
+ 35, 358, 17, 36, 16, 114, 314, 285, 15, 192,
+ 159, 123, 84, 85, 344, 15, 162, 55, 76, 502,
+ 76, 17, 16, 17, 115, 515, -260, 111, 265, 16,
+ 64, 541, 212, 63, 497, 312, 160, 501, 492, 111,
+ 317, 122, -37, 192, 355, 61, 506, 511, 356, 531,
+ 260, 161, 115, 205, 207, 111, 329, 330, 26, 334,
+ 335, 73, 319, 566, 567, 565, 345, 346, -192, 388,
+ 492, 492, 336, 347, 348, 256, 256, 161, 64, 572,
+ 59, 272, 574, 272, -191, 319, 492, 27, 281, 492,
+ -261, 115, -192, 308, 111, 337, 160, 39, 282, 111,
+ 532, 533, 278, -192, 159, 74, 338, 216, -191, 60,
+ 362, 161, 40, 479, 212, 268, 15, 283, 315, -191,
+ 1, 485, 320, 41, 26, 311, 42, 43, 44, 316,
+ 16, 92, 46, 76, 512, 47, 307, 192, 195, 48,
+ 292, 339, 49, 213, 473, 76, 319, 389, 17, -280,
+ 293, 340, 404, 272, 272, 332, 272, 272, 331, -280,
+ 192, 93, 15, 114, 195, 409, 23, -281, 419, 420,
+ 421, 375, 341, 25, 342, 460, 16, -281, 464, 343,
+ 28, -235, 197, 428, 429, 430, 431, 114, 461, 37,
+ 160, 461, 70, 111, 198, 50, 364, 364, 195, 363,
+ 349, 387, 350, -39, 64, 114, 39, 285, 197, 370,
+ 422, 423, 373, 424, 425, 426, 463, 320, 465, 87,
+ 198, 40, 432, 433, 89, 90, 36, 26, 161, 278,
+ 91, 107, 41, 215, 390, 42, 43, 44, 199, 216,
+ 45, 46, 197, 265, 47, 61, 219, 364, 48, 115,
+ 220, 49, 111, 221, 198, 223, 159, 278, 261, 262,
+ 266, 213, 162, 267, 199, 272, 272, 272, 272, 272,
+ 272, 272, 272, 115, 272, 272, 272, 272, 272, 272,
+ 272, 272, 272, 272, 272, 268, 280, 271, 284, 192,
+ 68, 115, 195, 286, 111, 288, 290, 291, 199, 289,
+ 500, 74, 310, 503, 50, 318, 326, 319, 328, 212,
+ 514, 351, 352, 354, 353, 195, 359, 360, 320, 192,
+ 192, 361, 369, 374, 375, 313, 200, 287, 381, 192,
+ 380, 393, 399, 410, 401, 403, 197, 408, 414, 396,
+ 398, 76, 160, 411, 17, 111, 418, 272, 198, 412,
+ 443, 441, 200, 278, 444, 446, 320, 161, 442, 197,
+ 447, 490, 159, 416, 417, 450, 445, 454, 362, 448,
+ 504, 198, 449, 456, 529, 201, 453, 455, 481, 457,
+ 549, 458, 467, 478, 498, 507, 200, 202, 489, 508,
+ 159, 482, 199, 509, 192, 192, 162, 161, 192, 192,
+ 510, 201, 315, 159, 513, 518, 522, 272, 272, 162,
+ 272, 517, 523, 202, 519, 199, 520, -165, 521, 524,
+ 526, 527, 528, 192, 558, 550, 462, 559, 192, 462,
+ 192, 192, 551, 552, 534, 201, 192, 553, 554, 387,
+ 542, 555, 568, 570, 195, 192, 192, 202, 160, 192,
+ 562, 111, 573, 563, 569, 427, 116, 81, 94, 124,
+ 402, 125, 471, -23, 211, 560, 489, 161, 281, 564,
+ 400, 490, 504, 126, 195, 195, 160, -23, 282, 111,
+ 200, 477, 561, 571, 195, 538, 452, 542, 197, 160,
+ 564, 161, 111, 397, 434, -278, 161, 283, 489, 489,
+ 198, 436, 258, 200, 161, -278, 516, 437, 435, 0,
+ 392, 0, 438, 0, 489, 0, 0, 489, 197, 197,
+ 0, 0, 0, 0, 0, 0, 0, 0, 197, 201,
+ 198, 198, 0, 0, 0, -333, 0, 281, 0, -333,
+ 198, 202, 0, 0, 199, -333, 0, 282, -333, 195,
+ 195, 0, 201, 195, 195, -333, 0, -333, -333, 0,
+ 0, 0, 0, -333, 202, 0, 283, 0, -333, 0,
+ -333, 0, 0, -333, 199, 199, 0, 0, 195, -333,
+ 0, 0, 0, 195, 199, 195, 195, 0, 0, 0,
+ 0, 195, 0, 197, 197, 0, 0, 197, 197, 0,
+ 195, 195, 0, 0, 195, 198, 198, 0, 0, 198,
+ 198, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 197, 0, 0, 0, 0, 197, 0, 197,
+ 197, 0, 200, 0, 198, 197, 0, 0, 0, 198,
+ 0, 198, 198, 0, 197, 197, 0, 198, 197, 199,
+ 199, 0, 0, 199, 199, 0, 198, 198, 0, 0,
+ 198, 0, 200, 200, 0, 0, 0, 0, 0, 0,
+ 0, 0, 200, 0, 6, 0, 7, 0, 199, 8,
+ 68, 201, 0, 199, 9, 199, 199, 0, 0, 10,
+ 0, 199, 0, 202, 0, 11, 69, 12, 0, 0,
+ 199, 199, 0, 0, 199, 13, 0, 0, 0, 0,
+ 0, 201, 201, 0, 0, 0, 109, 0, 0, 0,
+ 255, 201, 0, 202, 202, 0, 15, 264, 0, 0,
+ 0, 0, 269, 202, 273, 0, 273, 200, 200, 0,
+ 16, 200, 200, 276, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 200, 0, 0, 0,
+ 274, 200, 274, 200, 200, 0, 0, 0, 0, 200,
+ 0, 0, 0, 0, 0, 0, 201, 201, 200, 200,
+ 201, 201, 200, 0, 0, 0, 0, 0, 202, 202,
+ 0, 0, 202, 202, 0, 0, 273, 273, 0, 273,
+ 273, 0, 0, 0, 0, 201, 333, 0, 0, 0,
+ 201, 0, 201, 201, 0, 0, 0, 202, 201, 0,
+ 0, 0, 202, 0, 202, 202, 0, 201, 201, 0,
+ 202, 201, 274, 274, 0, 274, 274, 0, 0, 202,
+ 202, 0, 368, 202, 39, 0, 371, 372, 0, 0,
+ 0, 379, 0, 0, 0, 0, 0, 0, 0, 40,
+ 0, 382, 0, 0, 0, 0, 0, 0, 0, 0,
+ 41, 391, 0, 42, 43, 44, 0, 0, 45, 46,
+ 0, 0, 47, 0, 0, 0, 48, 0, 0, 49,
+ 0, 0, 0, 0, 0, 0, 407, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 273, 273,
+ 273, 273, 273, 273, 273, 273, 0, 273, 273, 273,
+ 273, 273, 273, 273, 273, 273, 273, 273, 0, 0,
+ 0, -105, 0, 0, 0, 0, 439, 440, 0, 0,
+ 0, 0, 0, 0, 274, 274, 274, 274, 274, 274,
+ 274, 274, 0, 274, 274, 274, 274, 274, 274, 274,
+ 274, 274, 274, 274, 6, 0, 7, 0, 0, 8,
+ 0, 0, 0, 459, 9, 0, 0, 0, 0, 10,
+ 0, 0, 0, 0, 407, 11, 0, 12, 0, 0,
+ 273, 0, 0, 0, 0, 13, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 14, 0, 0, 0,
+ 6, 0, 7, 0, 0, 8, 15, 0, 0, 0,
+ 9, 483, 264, 0, 0, 10, 274, 0, 0, 0,
+ 16, 11, 0, 12, 0, 136, 505, 0, 0, 39,
+ 0, 13, 0, 0, 138, 0, 0, 141, 0, 0,
+ 273, 273, 14, 273, 40, 145, 146, 147, 148, 149,
+ 150, 151, 15, 0, 0, 41, 318, 0, 42, 43,
+ 44, 0, 0, 45, 46, 0, 16, 47, 0, 0,
+ 224, 48, 0, 0, 49, 0, 274, 274, 0, 274,
+ 407, 0, 225, 0, 152, 0, 226, 0, 0, 0,
+ 539, 540, 227, 121, 154, 0, 0, 228, 0, 39,
+ 130, 6, 131, 7, 543, 0, 8, 0, 132, 544,
+ 133, 9, 0, 556, 40, 0, 10, 134, 135, 0,
+ 0, 0, 11, 264, 12, 41, 136, 0, 42, 43,
+ 44, 137, 13, 45, 46, 138, 139, 140, 141, 142,
+ 0, 48, 143, 14, 49, 144, 145, 146, 147, 148,
+ 149, 150, 151, 15, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, -199, 107, 0, 0, 16, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 152, 0, 153, 0, 39,
+ 130, 6, 131, 7, 0, 154, 8, 155, 132, 0,
+ 133, 9, 0, 0, 40, 0, 10, 134, 135, 0,
+ 0, 0, 11, 0, 12, 41, 136, 0, 42, 43,
+ 44, 137, 13, 45, 46, 138, 139, 140, 141, 142,
+ 0, 48, 143, 14, 49, 144, 145, 146, 147, 148,
+ 149, 150, 151, 15, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, -149, 107, 0, 0, 16, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 152, 0, 153, 0, 39,
+ 130, 6, 131, 7, 0, 154, 8, 155, 132, 0,
+ 133, 9, 0, 0, 40, 0, 10, 134, 135, 0,
+ 0, 0, 11, 0, 12, 41, 136, 0, 42, 43,
+ 44, 137, 13, 45, 46, 138, 139, 140, 141, 142,
+ 0, 48, 143, 14, 49, 144, 145, 146, 147, 148,
+ 149, 150, 151, 15, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, -150, 107, 0, 0, 16, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 152, 0, 153, 0, 39,
+ 130, 6, 131, 7, 0, 154, 8, 155, 132, 0,
+ 133, 9, 0, 0, 40, 0, 10, 134, 135, 0,
+ 0, 0, 11, 0, 12, 41, 136, 0, 42, 43,
+ 44, 137, 13, 45, 46, 474, 139, 140, 475, 142,
+ 0, 48, 143, 14, 49, 144, 145, 146, 147, 148,
+ 149, 150, 151, 15, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, -149, 107, 0, 0, 16, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 152, 0, 153, 0, 0,
+ 0, 0, 0, 0, 0, 154, 0, 155, 39, 130,
+ 6, 131, 7, 0, 0, 8, -72, 132, 0, 133,
+ 9, 0, 0, 40, 0, 10, 134, 135, 0, 0,
+ 0, 11, 0, 12, 41, 136, 0, 42, 43, 44,
+ 137, 13, 45, 46, 138, 139, 140, 141, 142, 0,
+ 48, 143, 14, 49, 144, 145, 146, 147, 148, 149,
+ 150, 151, 15, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 107, 0, 0, 16, 0, 0, 0,
+ 0, 130, 6, 131, 7, 0, 0, 8, 0, 132,
+ 0, 133, 9, 0, 152, 0, 153, 10, 134, 135,
+ 0, 0, 0, 11, 154, 12, 155, 136, 0, 0,
+ 0, 0, 137, 13, 0, 0, 138, 139, 259, 141,
+ 142, 0, 0, 143, 14, 0, 144, 145, 146, 147,
+ 148, 149, 150, 151, 15, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 107, 0, 0, 16, 0,
+ 0, 0, 0, 130, 6, 131, 7, 0, 0, 8,
+ 0, 132, 0, 133, 9, 0, 152, 0, 153, 10,
+ 486, 487, 0, 0, 0, 11, 154, 12, 155, 136,
+ 0, 0, 0, 0, 137, 13, 0, 0, 138, 139,
+ 259, 141, 142, 0, 0, 143, 14, 0, 488, 145,
+ 146, 147, 148, 149, 150, 151, 15, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 107, 0, 0,
+ 16, 6, 0, 7, 0, 0, 8, 0, 0, 0,
+ 0, 9, 0, 0, 0, 0, 10, 0, 152, 0,
+ 153, 0, 11, 0, 12, 0, 136, 0, 154, 0,
+ 155, 0, 13, 0, 0, 138, 0, 0, 141, 0,
+ 0, 0, 0, 14, 0, 0, 145, 146, 147, 148,
+ 149, 150, 151, 15, 0, 6, 0, 7, 0, 0,
+ 8, 0, 0, 0, 404, 9, 0, 16, 0, 0,
+ 10, 224, 0, 0, 0, 0, 11, 0, 12, 0,
+ 136, 0, 0, 225, 0, 152, 13, 226, 0, 138,
+ 0, 0, 141, 227, 0, 154, 0, 14, 228, 0,
+ 145, 146, 147, 148, 149, 150, 151, 15, 0, 6,
+ 0, 7, 0, 0, 8, 0, 0, 0, 0, 9,
+ 0, 16, 0, 0, 10, 224, 0, 0, 0, 0,
+ 11, 0, 12, 0, 136, 0, 0, 225, 0, 152,
+ 13, 226, 0, 138, 0, 0, 141, 227, 0, 154,
+ 0, 14, 228, 0, 145, 146, 147, 148, 149, 150,
+ 151, 15, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 39, 16, 6, 0, 7, 224,
+ 0, 8, 0, 0, 0, 0, 9, 0, 0, 40,
+ 0, 10, 0, 0, 0, 226, 0, 11, 0, 12,
+ 41, 136, 0, 42, 43, 44, 228, 13, 45, 46,
+ 138, 0, 47, 141, 0, 0, 48, 0, 14, 49,
+ 0, 145, 146, 147, 148, 149, 150, 151, 15, 0,
+ 6, 0, 7, 0, 0, 8, 0, 0, 0, 0,
+ 9, 0, 16, 0, 0, 10, 0, 0, 0, 0,
+ 0, 11, 0, 12, 0, 136, 0, 0, 0, 0,
+ 152, 13, 153, 0, 138, 0, 0, 141, 0, 0,
+ 154, 0, 14, 0, 0, 145, 146, 147, 148, 149,
+ 150, 151, 15, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 16, 0, 0, 0,
+ 39, 0, 6, 0, 7, 0, 0, 8, 0, 0,
+ 0, 0, 9, 0, 152, 40, 153, 10, 0, 0,
+ 0, 39, 0, 11, 154, 12, 41, 0, 0, 42,
+ 43, 44, 0, 13, 45, 46, 40, 0, 47, 0,
+ 0, 0, 48, 0, 14, 49, 0, 41, 0, 0,
+ 42, 43, 44, 0, 15, 45, 46, 0, 0, 47,
+ -334, 0, 0, 48, -334, 0, 49, 0, 16, 0,
+ -334, 0, 0, -334, -335, 0, 0, 0, -335, 0,
+ -334, 0, -334, -334, -335, 0, 0, -335, -334, 0,
+ 0, 0, 0, -334, -335, -334, -335, -335, -334, 0,
+ 0, 294, -335, 0, -334, 295, 0, -335, 0, -335,
+ 0, 296, -335, 0, 297, 0, 0, 0, -335, 0,
+ 0, 298, 0, 299, 300, 0, 0, 0, 0, 301,
+ 0, 0, 0, 0, 302, 0, 303, 0, 0, 304,
+ 0, 0, 0, 0, 0, 305
+};
+
+static const short int yycheck[] =
+{
+ 1, 65, 66, 1, 167, 52, 204, 30, 95, 261,
+ 95, 261, 158, 404, 11, 92, 518, 81, 216, 68,
+ 107, 62, 63, 100, 442, 70, 107, 11, 29, 70,
+ 444, 29, 11, 30, 418, 65, 123, 30, 123, 11,
+ 26, 66, 8, 27, 89, 42, 91, 13, 89, 17,
+ 91, 411, 101, 107, 152, 23, 154, 80, 399, 24,
+ 57, 62, 63, 42, 62, 63, 143, 569, 62, 70,
+ 42, 101, 70, 59, 71, 162, 101, 162, 57, 133,
+ 167, 104, 68, 69, 25, 57, 167, 80, 89, 449,
+ 91, 89, 71, 91, 95, 479, 90, 95, 72, 71,
+ 68, 522, 62, 23, 445, 206, 107, 448, 522, 107,
+ 211, 104, 72, 167, 96, 162, 457, 91, 100, 510,
+ 133, 107, 123, 109, 110, 123, 224, 225, 72, 227,
+ 228, 103, 62, 554, 555, 553, 77, 78, 66, 285,
+ 554, 555, 69, 84, 85, 131, 132, 133, 68, 570,
+ 72, 152, 573, 154, 66, 62, 570, 101, 62, 573,
+ 90, 162, 90, 204, 162, 92, 167, 3, 72, 167,
+ 511, 512, 158, 101, 261, 216, 103, 44, 90, 101,
+ 261, 167, 18, 90, 62, 72, 57, 91, 62, 101,
+ 31, 443, 215, 29, 72, 62, 32, 33, 34, 73,
+ 71, 37, 38, 204, 91, 41, 204, 261, 107, 45,
+ 89, 87, 48, 111, 412, 216, 62, 42, 216, 89,
+ 99, 97, 68, 224, 225, 226, 227, 228, 226, 99,
+ 284, 67, 57, 320, 133, 320, 0, 89, 336, 337,
+ 338, 9, 79, 57, 81, 394, 71, 99, 397, 86,
+ 72, 19, 107, 345, 346, 347, 348, 344, 394, 11,
+ 261, 397, 17, 261, 107, 101, 518, 519, 167, 519,
+ 74, 284, 76, 0, 68, 362, 3, 362, 133, 265,
+ 339, 340, 268, 341, 342, 343, 396, 310, 398, 68,
+ 133, 18, 349, 350, 66, 101, 282, 72, 284, 285,
+ 66, 68, 29, 91, 290, 32, 33, 34, 107, 44,
+ 37, 38, 167, 72, 41, 362, 101, 569, 45, 320,
+ 101, 48, 320, 101, 167, 101, 413, 313, 91, 91,
+ 91, 229, 413, 91, 133, 336, 337, 338, 339, 340,
+ 341, 342, 343, 344, 345, 346, 347, 348, 349, 350,
+ 351, 352, 353, 354, 355, 72, 72, 91, 65, 413,
+ 11, 362, 261, 67, 362, 101, 72, 62, 167, 101,
+ 447, 412, 91, 450, 101, 61, 68, 62, 101, 62,
+ 478, 58, 63, 59, 94, 284, 101, 101, 411, 443,
+ 444, 49, 101, 101, 9, 66, 107, 560, 11, 453,
+ 90, 62, 91, 90, 61, 61, 261, 61, 101, 307,
+ 308, 412, 413, 66, 412, 413, 90, 418, 261, 66,
+ 66, 91, 133, 409, 90, 90, 449, 413, 101, 284,
+ 90, 444, 519, 331, 332, 19, 91, 61, 519, 91,
+ 453, 284, 91, 66, 508, 107, 90, 90, 65, 91,
+ 527, 61, 90, 90, 68, 61, 167, 107, 444, 90,
+ 547, 101, 261, 67, 518, 519, 547, 453, 522, 523,
+ 66, 133, 62, 560, 67, 101, 65, 478, 479, 560,
+ 481, 90, 16, 133, 91, 284, 91, 16, 91, 90,
+ 90, 90, 90, 547, 65, 90, 394, 67, 552, 397,
+ 554, 555, 90, 90, 101, 167, 560, 101, 90, 522,
+ 523, 90, 65, 16, 413, 569, 570, 167, 519, 573,
+ 101, 519, 90, 101, 101, 344, 95, 65, 80, 104,
+ 313, 104, 409, 57, 110, 547, 522, 523, 62, 552,
+ 310, 554, 555, 104, 443, 444, 547, 71, 72, 547,
+ 261, 413, 547, 569, 453, 519, 377, 570, 413, 560,
+ 573, 547, 560, 308, 351, 89, 552, 91, 554, 555,
+ 413, 353, 132, 284, 560, 99, 481, 354, 352, -1,
+ 306, -1, 355, -1, 570, -1, -1, 573, 443, 444,
+ -1, -1, -1, -1, -1, -1, -1, -1, 453, 261,
+ 443, 444, -1, -1, -1, 60, -1, 62, -1, 64,
+ 453, 261, -1, -1, 413, 70, -1, 72, 73, 518,
+ 519, -1, 284, 522, 523, 80, -1, 82, 83, -1,
+ -1, -1, -1, 88, 284, -1, 91, -1, 93, -1,
+ 95, -1, -1, 98, 443, 444, -1, -1, 547, 104,
+ -1, -1, -1, 552, 453, 554, 555, -1, -1, -1,
+ -1, 560, -1, 518, 519, -1, -1, 522, 523, -1,
+ 569, 570, -1, -1, 573, 518, 519, -1, -1, 522,
+ 523, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 547, -1, -1, -1, -1, 552, -1, 554,
+ 555, -1, 413, -1, 547, 560, -1, -1, -1, 552,
+ -1, 554, 555, -1, 569, 570, -1, 560, 573, 518,
+ 519, -1, -1, 522, 523, -1, 569, 570, -1, -1,
+ 573, -1, 443, 444, -1, -1, -1, -1, -1, -1,
+ -1, -1, 453, -1, 5, -1, 7, -1, 547, 10,
+ 11, 413, -1, 552, 15, 554, 555, -1, -1, 20,
+ -1, 560, -1, 413, -1, 26, 27, 28, -1, -1,
+ 569, 570, -1, -1, 573, 36, -1, -1, -1, -1,
+ -1, 443, 444, -1, -1, -1, 47, -1, -1, -1,
+ 130, 453, -1, 443, 444, -1, 57, 137, -1, -1,
+ -1, -1, 142, 453, 152, -1, 154, 518, 519, -1,
+ 71, 522, 523, 153, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 547, -1, -1, -1,
+ 152, 552, 154, 554, 555, -1, -1, -1, -1, 560,
+ -1, -1, -1, -1, -1, -1, 518, 519, 569, 570,
+ 522, 523, 573, -1, -1, -1, -1, -1, 518, 519,
+ -1, -1, 522, 523, -1, -1, 224, 225, -1, 227,
+ 228, -1, -1, -1, -1, 547, 226, -1, -1, -1,
+ 552, -1, 554, 555, -1, -1, -1, 547, 560, -1,
+ -1, -1, 552, -1, 554, 555, -1, 569, 570, -1,
+ 560, 573, 224, 225, -1, 227, 228, -1, -1, 569,
+ 570, -1, 262, 573, 3, -1, 266, 267, -1, -1,
+ -1, 271, -1, -1, -1, -1, -1, -1, -1, 18,
+ -1, 281, -1, -1, -1, -1, -1, -1, -1, -1,
+ 29, 291, -1, 32, 33, 34, -1, -1, 37, 38,
+ -1, -1, 41, -1, -1, -1, 45, -1, -1, 48,
+ -1, -1, -1, -1, -1, -1, 316, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 336, 337,
+ 338, 339, 340, 341, 342, 343, -1, 345, 346, 347,
+ 348, 349, 350, 351, 352, 353, 354, 355, -1, -1,
+ -1, 90, -1, -1, -1, -1, 356, 357, -1, -1,
+ -1, -1, -1, -1, 336, 337, 338, 339, 340, 341,
+ 342, 343, -1, 345, 346, 347, 348, 349, 350, 351,
+ 352, 353, 354, 355, 5, -1, 7, -1, -1, 10,
+ -1, -1, -1, 393, 15, -1, -1, -1, -1, 20,
+ -1, -1, -1, -1, 404, 26, -1, 28, -1, -1,
+ 418, -1, -1, -1, -1, 36, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 47, -1, -1, -1,
+ 5, -1, 7, -1, -1, 10, 57, -1, -1, -1,
+ 15, 441, 442, -1, -1, 20, 418, -1, -1, -1,
+ 71, 26, -1, 28, -1, 30, 456, -1, -1, 3,
+ -1, 36, -1, -1, 39, -1, -1, 42, -1, -1,
+ 478, 479, 47, 481, 18, 50, 51, 52, 53, 54,
+ 55, 56, 57, -1, -1, 29, 61, -1, 32, 33,
+ 34, -1, -1, 37, 38, -1, 71, 41, -1, -1,
+ 75, 45, -1, -1, 48, -1, 478, 479, -1, 481,
+ 510, -1, 87, -1, 89, -1, 91, -1, -1, -1,
+ 520, 521, 97, 67, 99, -1, -1, 102, -1, 3,
+ 4, 5, 6, 7, 8, -1, 10, -1, 12, 13,
+ 14, 15, -1, 543, 18, -1, 20, 21, 22, -1,
+ -1, -1, 26, 553, 28, 29, 30, -1, 32, 33,
+ 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
+ -1, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ 54, 55, 56, 57, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 67, 68, -1, -1, 71, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 89, -1, 91, -1, 3,
+ 4, 5, 6, 7, -1, 99, 10, 101, 12, -1,
+ 14, 15, -1, -1, 18, -1, 20, 21, 22, -1,
+ -1, -1, 26, -1, 28, 29, 30, -1, 32, 33,
+ 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
+ -1, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ 54, 55, 56, 57, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 67, 68, -1, -1, 71, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 89, -1, 91, -1, 3,
+ 4, 5, 6, 7, -1, 99, 10, 101, 12, -1,
+ 14, 15, -1, -1, 18, -1, 20, 21, 22, -1,
+ -1, -1, 26, -1, 28, 29, 30, -1, 32, 33,
+ 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
+ -1, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ 54, 55, 56, 57, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 67, 68, -1, -1, 71, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 89, -1, 91, -1, 3,
+ 4, 5, 6, 7, -1, 99, 10, 101, 12, -1,
+ 14, 15, -1, -1, 18, -1, 20, 21, 22, -1,
+ -1, -1, 26, -1, 28, 29, 30, -1, 32, 33,
+ 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
+ -1, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ 54, 55, 56, 57, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 67, 68, -1, -1, 71, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 89, -1, 91, -1, -1,
+ -1, -1, -1, -1, -1, 99, -1, 101, 3, 4,
+ 5, 6, 7, -1, -1, 10, 11, 12, -1, 14,
+ 15, -1, -1, 18, -1, 20, 21, 22, -1, -1,
+ -1, 26, -1, 28, 29, 30, -1, 32, 33, 34,
+ 35, 36, 37, 38, 39, 40, 41, 42, 43, -1,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, 57, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 68, -1, -1, 71, -1, -1, -1,
+ -1, 4, 5, 6, 7, -1, -1, 10, -1, 12,
+ -1, 14, 15, -1, 89, -1, 91, 20, 21, 22,
+ -1, -1, -1, 26, 99, 28, 101, 30, -1, -1,
+ -1, -1, 35, 36, -1, -1, 39, 40, 41, 42,
+ 43, -1, -1, 46, 47, -1, 49, 50, 51, 52,
+ 53, 54, 55, 56, 57, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 68, -1, -1, 71, -1,
+ -1, -1, -1, 4, 5, 6, 7, -1, -1, 10,
+ -1, 12, -1, 14, 15, -1, 89, -1, 91, 20,
+ 21, 22, -1, -1, -1, 26, 99, 28, 101, 30,
+ -1, -1, -1, -1, 35, 36, -1, -1, 39, 40,
+ 41, 42, 43, -1, -1, 46, 47, -1, 49, 50,
+ 51, 52, 53, 54, 55, 56, 57, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 68, -1, -1,
+ 71, 5, -1, 7, -1, -1, 10, -1, -1, -1,
+ -1, 15, -1, -1, -1, -1, 20, -1, 89, -1,
+ 91, -1, 26, -1, 28, -1, 30, -1, 99, -1,
+ 101, -1, 36, -1, -1, 39, -1, -1, 42, -1,
+ -1, -1, -1, 47, -1, -1, 50, 51, 52, 53,
+ 54, 55, 56, 57, -1, 5, -1, 7, -1, -1,
+ 10, -1, -1, -1, 68, 15, -1, 71, -1, -1,
+ 20, 75, -1, -1, -1, -1, 26, -1, 28, -1,
+ 30, -1, -1, 87, -1, 89, 36, 91, -1, 39,
+ -1, -1, 42, 97, -1, 99, -1, 47, 102, -1,
+ 50, 51, 52, 53, 54, 55, 56, 57, -1, 5,
+ -1, 7, -1, -1, 10, -1, -1, -1, -1, 15,
+ -1, 71, -1, -1, 20, 75, -1, -1, -1, -1,
+ 26, -1, 28, -1, 30, -1, -1, 87, -1, 89,
+ 36, 91, -1, 39, -1, -1, 42, 97, -1, 99,
+ -1, 47, 102, -1, 50, 51, 52, 53, 54, 55,
+ 56, 57, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 3, 71, 5, -1, 7, 75,
+ -1, 10, -1, -1, -1, -1, 15, -1, -1, 18,
+ -1, 20, -1, -1, -1, 91, -1, 26, -1, 28,
+ 29, 30, -1, 32, 33, 34, 102, 36, 37, 38,
+ 39, -1, 41, 42, -1, -1, 45, -1, 47, 48,
+ -1, 50, 51, 52, 53, 54, 55, 56, 57, -1,
+ 5, -1, 7, -1, -1, 10, -1, -1, -1, -1,
+ 15, -1, 71, -1, -1, 20, -1, -1, -1, -1,
+ -1, 26, -1, 28, -1, 30, -1, -1, -1, -1,
+ 89, 36, 91, -1, 39, -1, -1, 42, -1, -1,
+ 99, -1, 47, -1, -1, 50, 51, 52, 53, 54,
+ 55, 56, 57, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 71, -1, -1, -1,
+ 3, -1, 5, -1, 7, -1, -1, 10, -1, -1,
+ -1, -1, 15, -1, 89, 18, 91, 20, -1, -1,
+ -1, 3, -1, 26, 99, 28, 29, -1, -1, 32,
+ 33, 34, -1, 36, 37, 38, 18, -1, 41, -1,
+ -1, -1, 45, -1, 47, 48, -1, 29, -1, -1,
+ 32, 33, 34, -1, 57, 37, 38, -1, -1, 41,
+ 60, -1, -1, 45, 64, -1, 48, -1, 71, -1,
+ 70, -1, -1, 73, 60, -1, -1, -1, 64, -1,
+ 80, -1, 82, 83, 70, -1, -1, 73, 88, -1,
+ -1, -1, -1, 93, 80, 95, 82, 83, 98, -1,
+ -1, 60, 88, -1, 104, 64, -1, 93, -1, 95,
+ -1, 70, 98, -1, 73, -1, -1, -1, 104, -1,
+ -1, 80, -1, 82, 83, -1, -1, -1, -1, 88,
+ -1, -1, -1, -1, 93, -1, 95, -1, -1, 98,
+ -1, -1, -1, -1, -1, 104
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
+static const unsigned short int yystos[] =
+{
+ 0, 31, 107, 122, 123, 126, 5, 7, 10, 15,
+ 20, 26, 28, 36, 47, 57, 71, 111, 117, 118,
+ 119, 120, 121, 0, 124, 57, 72, 101, 72, 24,
+ 125, 127, 128, 129, 11, 42, 119, 11, 117, 3,
+ 18, 29, 32, 33, 34, 37, 38, 41, 45, 48,
+ 101, 130, 131, 132, 133, 134, 135, 164, 165, 72,
+ 101, 132, 17, 23, 68, 136, 137, 139, 11, 27,
+ 17, 166, 167, 103, 113, 114, 117, 113, 115, 138,
+ 140, 137, 139, 139, 119, 119, 115, 68, 168, 66,
+ 101, 66, 37, 67, 130, 135, 141, 142, 143, 148,
+ 149, 158, 159, 139, 169, 115, 115, 68, 177, 47,
+ 110, 111, 112, 113, 116, 117, 118, 160, 101, 157,
+ 177, 67, 134, 135, 143, 149, 165, 170, 171, 172,
+ 4, 6, 12, 14, 21, 22, 30, 35, 39, 40,
+ 41, 42, 43, 46, 49, 50, 51, 52, 53, 54,
+ 55, 56, 89, 91, 99, 101, 108, 109, 110, 116,
+ 117, 119, 131, 134, 135, 177, 178, 179, 180, 181,
+ 182, 183, 185, 186, 187, 189, 190, 191, 192, 194,
+ 201, 203, 204, 212, 213, 215, 216, 217, 218, 219,
+ 224, 225, 226, 230, 235, 236, 237, 238, 239, 240,
+ 242, 243, 258, 259, 263, 119, 151, 119, 144, 145,
+ 146, 151, 62, 234, 234, 91, 44, 150, 155, 101,
+ 101, 101, 173, 101, 75, 87, 91, 97, 102, 111,
+ 116, 117, 226, 236, 238, 239, 240, 241, 242, 243,
+ 244, 245, 246, 247, 248, 249, 250, 251, 252, 253,
+ 254, 255, 256, 257, 258, 261, 119, 214, 214, 41,
+ 183, 91, 91, 208, 261, 72, 91, 91, 72, 261,
+ 177, 91, 117, 235, 237, 241, 261, 241, 119, 144,
+ 72, 62, 72, 91, 65, 110, 67, 180, 101, 101,
+ 72, 62, 89, 99, 60, 64, 70, 73, 80, 82,
+ 83, 88, 93, 95, 98, 104, 260, 111, 113, 114,
+ 91, 62, 150, 66, 101, 62, 73, 150, 61, 62,
+ 135, 152, 153, 154, 114, 156, 68, 161, 101, 241,
+ 241, 111, 117, 261, 241, 241, 69, 92, 103, 87,
+ 97, 79, 81, 86, 25, 77, 78, 84, 85, 74,
+ 76, 58, 63, 94, 59, 96, 100, 65, 101, 101,
+ 101, 49, 131, 182, 190, 206, 209, 211, 261, 101,
+ 119, 261, 261, 119, 101, 9, 220, 221, 222, 261,
+ 90, 11, 261, 30, 228, 229, 261, 183, 144, 42,
+ 119, 261, 257, 62, 232, 233, 234, 232, 234, 91,
+ 152, 61, 145, 61, 68, 147, 174, 261, 61, 110,
+ 90, 66, 66, 162, 101, 231, 234, 234, 90, 241,
+ 241, 241, 246, 246, 247, 247, 247, 112, 248, 248,
+ 248, 248, 249, 249, 250, 251, 252, 253, 254, 261,
+ 261, 91, 101, 66, 90, 91, 90, 90, 91, 91,
+ 19, 223, 222, 90, 61, 90, 66, 91, 61, 261,
+ 231, 233, 234, 174, 231, 174, 228, 90, 147, 175,
+ 176, 146, 154, 114, 39, 42, 163, 178, 90, 90,
+ 244, 65, 101, 261, 208, 190, 21, 22, 49, 119,
+ 183, 184, 185, 188, 193, 202, 207, 228, 68, 195,
+ 177, 228, 154, 177, 183, 261, 228, 61, 90, 67,
+ 66, 91, 91, 67, 241, 244, 256, 90, 101, 91,
+ 91, 91, 65, 16, 90, 197, 90, 90, 90, 139,
+ 227, 147, 228, 228, 101, 205, 210, 211, 206, 261,
+ 261, 184, 183, 8, 13, 196, 198, 199, 200, 177,
+ 90, 90, 90, 101, 90, 90, 261, 262, 65, 67,
+ 179, 200, 101, 101, 183, 208, 184, 184, 65, 101,
+ 16, 205, 184, 90, 184
+};
+
+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
+# define YYSIZE_T __SIZE_TYPE__
+#endif
+#if ! defined (YYSIZE_T) && defined (size_t)
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T)
+# if defined (__STDC__) || defined (__cplusplus)
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# endif
+#endif
+#if ! defined (YYSIZE_T)
+# define YYSIZE_T unsigned int
+#endif
+
+#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. */
+
+#define YYFAIL goto yyerrlab
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY && yylen == 1) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ yytoken = YYTRANSLATE (yychar); \
+ YYPOPSTACK; \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror ("syntax error: cannot back up");\
+ YYERROR; \
+ } \
+while (0)
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+/* YYLLOC_DEFAULT -- Compute the default location (before the actions
+ are run). */
+
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ ((Current).first_line = (Rhs)[1].first_line, \
+ (Current).first_column = (Rhs)[1].first_column, \
+ (Current).last_line = (Rhs)[N].last_line, \
+ (Current).last_column = (Rhs)[N].last_column)
+#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 (0)
+
+# define YYDSYMPRINT(Args) \
+do { \
+ if (yydebug) \
+ yysymprint Args; \
+} while (0)
+
+# define YYDSYMPRINTF(Title, Token, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yysymprint (stderr, \
+ Token, Value); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (0)
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included). |
+`------------------------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_stack_print (short int *bottom, short int *top)
+#else
+static void
+yy_stack_print (bottom, top)
+ short int *bottom;
+ short int *top;
+#endif
+{
+ YYFPRINTF (stderr, "Stack now");
+ for (/* Nothing. */; bottom <= top; ++bottom)
+ YYFPRINTF (stderr, " %d", *bottom);
+ 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. |
+`------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_reduce_print (int yyrule)
+#else
+static void
+yy_reduce_print (yyrule)
+ int yyrule;
+#endif
+{
+ int yyi;
+ unsigned int yylno = yyrline[yyrule];
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
+ yyrule - 1, yylno);
+ /* Print the symbols being reduced, and their result. */
+ for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
+ YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]);
+ YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]);
+}
+
+# define YY_REDUCE_PRINT(Rule) \
+do { \
+ if (yydebug) \
+ yy_reduce_print (Rule); \
+} 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 YYDSYMPRINT(Args)
+# define YYDSYMPRINTF(Title, Token, 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
+ SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#if defined (YYMAXDEPTH) && YYMAXDEPTH == 0
+# undef YYMAXDEPTH
+#endif
+
+#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
+# if defined (__STDC__) || defined (__cplusplus)
+yystrlen (const char *yystr)
+# else
+yystrlen (yystr)
+ const char *yystr;
+# endif
+{
+ register const char *yys = yystr;
+
+ while (*yys++ != '\0')
+ continue;
+
+ return yys - yystr - 1;
+}
+# 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 *
+# if defined (__STDC__) || defined (__cplusplus)
+yystpcpy (char *yydest, const char *yysrc)
+# else
+yystpcpy (yydest, yysrc)
+ char *yydest;
+ const char *yysrc;
+# endif
+{
+ register char *yyd = yydest;
+ register const char *yys = yysrc;
+
+ while ((*yyd++ = *yys++) != '\0')
+ continue;
+
+ return yyd - 1;
+}
+# endif
+# endif
+
+#endif /* !YYERROR_VERBOSE */
+
+
+
+#if YYDEBUG
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yysymprint (yyoutput, yytype, yyvaluep)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE *yyvaluep;
+#endif
+{
+ /* Pacify ``unused variable'' warnings. */
+ (void) yyvaluep;
+
+ if (yytype < YYNTOKENS)
+ {
+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+# ifdef YYPRINT
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# endif
+ }
+ else
+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+ switch (yytype)
+ {
+ default:
+ break;
+ }
+ YYFPRINTF (yyoutput, ")");
+}
+
+#endif /* ! YYDEBUG */
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yydestruct (int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yydestruct (yytype, yyvaluep)
+ int yytype;
+ YYSTYPE *yyvaluep;
+#endif
+{
+ /* Pacify ``unused variable'' warnings. */
+ (void) yyvaluep;
+
+ 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 (__cplusplus)
+int yyparse (void *YYPARSE_PARAM)
+# else
+int yyparse (YYPARSE_PARAM)
+ void *YYPARSE_PARAM;
+# endif
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
+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;
+
+ register int yystate;
+ register int yyn;
+ int yyresult;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+ /* Lookahead token as an internal (translated) token number. */
+ int yytoken = 0;
+
+ /* Three stacks and their tools:
+ `yyss': related to states,
+ `yyvs': related to semantic values,
+ `yyls': related to locations.
+
+ Refer to the stacks thru separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ short int yyssa[YYINITDEPTH];
+ short int *yyss = yyssa;
+ register short int *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs = yyvsa;
+ register YYSTYPE *yyvsp;
+
+
+
+#define YYPOPSTACK (yyvsp--, yyssp--)
+
+ YYSIZE_T yystacksize = YYINITDEPTH;
+
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+
+
+ /* When reducing, the number of symbols on the RHS of the reduced
+ rule. */
+ int yylen;
+
+ 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;
+ short int *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 ("parser stack overflow",
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+
+ &yystacksize);
+
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+ goto yyoverflowlab;
+# else
+ /* Extend the stack our own way. */
+ if (YYMAXDEPTH <= yystacksize)
+ goto yyoverflowlab;
+ yystacksize *= 2;
+ if (YYMAXDEPTH < yystacksize)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ short int *yyss1 = yyss;
+ union yyalloc *yyptr =
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ if (! yyptr)
+ goto yyoverflowlab;
+ YYSTACK_RELOCATE (yyss);
+ YYSTACK_RELOCATE (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));
+
+ 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. */
+/* yyresume: */
+
+ /* First try to decide what to do without reference to lookahead token. */
+
+ yyn = yypact[yystate];
+ if (yyn == YYPACT_NINF)
+ 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);
+ YYDSYMPRINTF ("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 (yyn == 0 || yyn == YYTABLE_NINF)
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ /* Shift the lookahead token. */
+ YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken]));
+
+ /* Discard the token being shifted unless it is eof. */
+ if (yychar != YYEOF)
+ yychar = YYEMPTY;
+
+ *++yyvsp = yylval;
+
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ yystate = yyn;
+ 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 2:
+#line 192 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 3:
+#line 201 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 4:
+#line 209 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 5:
+#line 217 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 6:
+#line 225 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 7:
+#line 233 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 8:
+#line 241 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 9:
+#line 250 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 10:
+#line 258 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 11:
+#line 267 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 12:
+#line 275 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 13:
+#line 284 "cmDependsJavaParser.y"
+ {
+ jpElementStart(0);
+}
+ break;
+
+ case 14:
+#line 289 "cmDependsJavaParser.y"
+ {
+ jpElementStart(0);
+}
+ break;
+
+ case 15:
+#line 294 "cmDependsJavaParser.y"
+ {
+ jpElementStart(0);
+}
+ break;
+
+ case 16:
+#line 299 "cmDependsJavaParser.y"
+ {
+ jpElementStart(0);
+}
+ break;
+
+ case 17:
+#line 304 "cmDependsJavaParser.y"
+ {
+ jpElementStart(0);
+}
+ break;
+
+ case 18:
+#line 309 "cmDependsJavaParser.y"
+ {
+ jpElementStart(0);
+}
+ break;
+
+ case 19:
+#line 314 "cmDependsJavaParser.y"
+ {
+ jpElementStart(0);
+}
+ break;
+
+ case 20:
+#line 319 "cmDependsJavaParser.y"
+ {
+ jpElementStart(0);
+}
+ break;
+
+ case 21:
+#line 325 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 22:
+#line 333 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 23:
+#line 342 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpStoreClass(yyvsp[0].str);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 24:
+#line 352 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 25:
+#line 361 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 26:
+#line 370 "cmDependsJavaParser.y"
+ {
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 27:
+#line 378 "cmDependsJavaParser.y"
+ {
+ jpElementStart(2);
+ jpStoreClass(yyvsp[-1].str);
+ jpCheckEmpty(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 28:
+#line 388 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ yyval.str = yyvsp[0].str;
+}
+ break;
+
+ case 29:
+#line 394 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ yyval.str = yyvsp[0].str;
+}
+ break;
+
+ case 30:
+#line 401 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ yyval.str = yyvsp[0].str;
+}
+ break;
+
+ case 31:
+#line 408 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ yyval.str = yyvsp[0].str;
+}
+ break;
+
+ case 32:
+#line 414 "cmDependsJavaParser.y"
+ {
+ jpElementStart(2);
+ yyval.str = yyvsp[0].str;
+}
+ break;
+
+ case 33:
+#line 421 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ yyGetParser->AddClassFound(yyvsp[-2].str);
+ yyGetParser->UpdateCombine(yyvsp[-2].str, yyvsp[0].str);
+ yyGetParser->DeallocateParserType(&(yyvsp[-2].str));
+ yyval.str = const_cast<char*>(yyGetParser->GetCurrentCombine());
+}
+ break;
+
+ case 34:
+#line 430 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpStoreClass(yyvsp[-2].str);
+ jpCheckEmpty(3);
+ yyGetParser->SetCurrentCombine("");
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 35:
+#line 440 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpStoreClass(yyvsp[-2].str);
+ yyGetParser->SetCurrentCombine("");
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 36:
+#line 450 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 37:
+#line 459 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 38:
+#line 467 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 39:
+#line 476 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 40:
+#line 484 "cmDependsJavaParser.y"
+ {
+ jpElementStart(0);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 41:
+#line 491 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 42:
+#line 499 "cmDependsJavaParser.y"
+ {
+ jpElementStart(0);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 43:
+#line 506 "cmDependsJavaParser.y"
+ {
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 44:
+#line 514 "cmDependsJavaParser.y"
+ {
+ jpElementStart(0);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 45:
+#line 521 "cmDependsJavaParser.y"
+ {
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 46:
+#line 530 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ yyGetParser->SetCurrentPackage(yyvsp[-1].str);
+ yyGetParser->DeallocateParserType(&(yyvsp[-1].str));
+ yyGetParser->SetCurrentCombine("");
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 47:
+#line 542 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 48:
+#line 550 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 49:
+#line 559 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ yyGetParser->AddPackagesImport(yyvsp[-1].str);
+ yyGetParser->DeallocateParserType(&(yyvsp[-1].str));
+ yyGetParser->SetCurrentCombine("");
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 50:
+#line 571 "cmDependsJavaParser.y"
+ {
+ jpElementStart(5);
+ std::string str = yyvsp[-3].str;
+ str += ".*";
+ yyGetParser->AddPackagesImport(str.c_str());
+ yyGetParser->DeallocateParserType(&(yyvsp[-3].str));
+ yyGetParser->SetCurrentCombine("");
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 51:
+#line 584 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 52:
+#line 592 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 53:
+#line 600 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 54:
+#line 609 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 55:
+#line 617 "cmDependsJavaParser.y"
+ {
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 67:
+#line 632 "cmDependsJavaParser.y"
+ {
+ yyGetParser->StartClass(yyvsp[0].str);
+ jpElementStart(3);
+ yyGetParser->DeallocateParserType(&(yyvsp[0].str));
+ jpCheckEmpty(3);
+}
+ break;
+
+ case 68:
+#line 642 "cmDependsJavaParser.y"
+ {
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+ yyGetParser->EndClass();
+}
+ break;
+
+ case 69:
+#line 651 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+ yyGetParser->EndClass();
+}
+ break;
+
+ case 70:
+#line 660 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+ yyGetParser->EndClass();
+}
+ break;
+
+ case 71:
+#line 669 "cmDependsJavaParser.y"
+ {
+ jpElementStart(4);
+ jpCheckEmpty(4);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+ yyGetParser->EndClass();
+}
+ break;
+
+ case 72:
+#line 678 "cmDependsJavaParser.y"
+ {
+ jpElementStart(0);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 73:
+#line 685 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 74:
+#line 694 "cmDependsJavaParser.y"
+ {
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 75:
+#line 703 "cmDependsJavaParser.y"
+ {
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 76:
+#line 712 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 77:
+#line 720 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 78:
+#line 729 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 79:
+#line 737 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 80:
+#line 744 "cmDependsJavaParser.y"
+ {
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 81:
+#line 753 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 82:
+#line 761 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 83:
+#line 769 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 84:
+#line 777 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 85:
+#line 786 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 86:
+#line 794 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 87:
+#line 803 "cmDependsJavaParser.y"
+ {
+ jpElementStart(4);
+}
+ break;
+
+ case 88:
+#line 809 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 89:
+#line 817 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 90:
+#line 826 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 91:
+#line 834 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 92:
+#line 843 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ yyGetParser->DeallocateParserType(&(yyvsp[0].str));
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 93:
+#line 852 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 94:
+#line 861 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 95:
+#line 869 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 96:
+#line 878 "cmDependsJavaParser.y"
+ {
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 97:
+#line 886 "cmDependsJavaParser.y"
+ {
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 98:
+#line 894 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 99:
+#line 903 "cmDependsJavaParser.y"
+ {
+ jpElementStart(4);
+ jpCheckEmpty(4);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 100:
+#line 912 "cmDependsJavaParser.y"
+ {
+ jpElementStart(4);
+ jpCheckEmpty(4);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 101:
+#line 921 "cmDependsJavaParser.y"
+ {
+ jpElementStart(0);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 102:
+#line 929 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 103:
+#line 939 "cmDependsJavaParser.y"
+ {
+ jpElementStart(4);
+ yyGetParser->DeallocateParserType(&(yyvsp[-3].str));
+ jpCheckEmpty(4);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 104:
+#line 949 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+
+}
+ break;
+
+ case 105:
+#line 955 "cmDependsJavaParser.y"
+ {
+ jpElementStart(0);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 107:
+#line 966 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+
+}
+ break;
+
+ case 108:
+#line 972 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 109:
+#line 982 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 110:
+#line 992 "cmDependsJavaParser.y"
+ {
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 111:
+#line 1002 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+
+}
+ break;
+
+ case 112:
+#line 1008 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 113:
+#line 1018 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 114:
+#line 1028 "cmDependsJavaParser.y"
+ {
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 115:
+#line 1038 "cmDependsJavaParser.y"
+ {
+ jpElementStart(4);
+ jpCheckEmpty(4);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 116:
+#line 1047 "cmDependsJavaParser.y"
+ {
+ jpElementStart(5);
+ jpCheckEmpty(5);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 117:
+#line 1057 "cmDependsJavaParser.y"
+ {
+ jpElementStart(4);
+ yyGetParser->DeallocateParserType(&(yyvsp[-3].str));
+ jpCheckEmpty(4);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 118:
+#line 1068 "cmDependsJavaParser.y"
+ {
+ jpElementStart(4);
+ jpCheckEmpty(4);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 119:
+#line 1077 "cmDependsJavaParser.y"
+ {
+ jpElementStart(0);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 120:
+#line 1085 "cmDependsJavaParser.y"
+ {
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 121:
+#line 1095 "cmDependsJavaParser.y"
+ {
+ jpElementStart(5);
+ jpCheckEmpty(5);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 122:
+#line 1104 "cmDependsJavaParser.y"
+ {
+ jpElementStart(5);
+ jpCheckEmpty(5);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 123:
+#line 1114 "cmDependsJavaParser.y"
+ {
+ yyGetParser->StartClass(yyvsp[0].str);
+ jpElementStart(3);
+ yyGetParser->DeallocateParserType(&(yyvsp[0].str));
+ jpCheckEmpty(3);
+}
+ break;
+
+ case 124:
+#line 1123 "cmDependsJavaParser.y"
+ {
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+ yyGetParser->EndClass();
+}
+ break;
+
+ case 125:
+#line 1132 "cmDependsJavaParser.y"
+ {
+ jpElementStart(0);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+ break;
+
+ case 126:
+#line 1139 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 127:
+#line 1149 "cmDependsJavaParser.y"
+ {
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 128:
+#line 1158 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 129:
+#line 1168 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 130:
+#line 1177 "cmDependsJavaParser.y"
+ {
+ jpElementStart(0);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 131:
+#line 1185 "cmDependsJavaParser.y"
+ {
+ jpElementStart(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 132:
+#line 1194 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 133:
+#line 1203 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 134:
+#line 1212 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 135:
+#line 1221 "cmDependsJavaParser.y"
+ {
+ jpElementStart(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 136:
+#line 1229 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 137:
+#line 1238 "cmDependsJavaParser.y"
+ {
+ jpElementStart(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 138:
+#line 1247 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 139:
+#line 1257 "cmDependsJavaParser.y"
+ {
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 140:
+#line 1267 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 141:
+#line 1276 "cmDependsJavaParser.y"
+ {
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 142:
+#line 1286 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 143:
+#line 1295 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 144:
+#line 1303 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 145:
+#line 1312 "cmDependsJavaParser.y"
+ {
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 146:
+#line 1322 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 147:
+#line 1331 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 148:
+#line 1341 "cmDependsJavaParser.y"
+ {
+ jpElementStart(4);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 149:
+#line 1349 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 150:
+#line 1357 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 151:
+#line 1367 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 152:
+#line 1376 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 153:
+#line 1386 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 154:
+#line 1395 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 155:
+#line 1404 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 156:
+#line 1414 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 157:
+#line 1424 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 158:
+#line 1433 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 159:
+#line 1443 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 160:
+#line 1452 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 161:
+#line 1461 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 162:
+#line 1470 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 163:
+#line 1479 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 164:
+#line 1488 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 165:
+#line 1498 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 166:
+#line 1507 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 167:
+#line 1516 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 168:
+#line 1525 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 169:
+#line 1534 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 170:
+#line 1544 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 171:
+#line 1553 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 172:
+#line 1562 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 173:
+#line 1571 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 174:
+#line 1580 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 175:
+#line 1589 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 176:
+#line 1598 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 177:
+#line 1607 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 178:
+#line 1616 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 179:
+#line 1625 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 180:
+#line 1634 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 181:
+#line 1643 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 182:
+#line 1653 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 183:
+#line 1663 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ yyGetParser->DeallocateParserType(&(yyvsp[-2].str));
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 184:
+#line 1674 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 185:
+#line 1684 "cmDependsJavaParser.y"
+ {
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 186:
+#line 1694 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 187:
+#line 1703 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 188:
+#line 1712 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 189:
+#line 1721 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 190:
+#line 1730 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 191:
+#line 1739 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 192:
+#line 1748 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 193:
+#line 1758 "cmDependsJavaParser.y"
+ {
+ jpElementStart(5);
+ jpCheckEmpty(5);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 194:
+#line 1768 "cmDependsJavaParser.y"
+ {
+ jpElementStart(7);
+ jpCheckEmpty(7);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 195:
+#line 1778 "cmDependsJavaParser.y"
+ {
+ jpElementStart(7);
+ jpCheckEmpty(7);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 196:
+#line 1788 "cmDependsJavaParser.y"
+ {
+ jpElementStart(5);
+
+}
+ break;
+
+ case 197:
+#line 1795 "cmDependsJavaParser.y"
+ {
+ jpElementStart(4);
+
+}
+ break;
+
+ case 198:
+#line 1801 "cmDependsJavaParser.y"
+ {
+ jpElementStart(0);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 199:
+#line 1809 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 200:
+#line 1818 "cmDependsJavaParser.y"
+ {
+ jpElementStart(0);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 201:
+#line 1826 "cmDependsJavaParser.y"
+ {
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 202:
+#line 1836 "cmDependsJavaParser.y"
+ {
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 203:
+#line 1846 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 204:
+#line 1855 "cmDependsJavaParser.y"
+ {
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 205:
+#line 1865 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 206:
+#line 1874 "cmDependsJavaParser.y"
+ {
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 207:
+#line 1884 "cmDependsJavaParser.y"
+ {
+ jpElementStart(5);
+
+}
+ break;
+
+ case 208:
+#line 1891 "cmDependsJavaParser.y"
+ {
+ jpElementStart(5);
+
+}
+ break;
+
+ case 209:
+#line 1898 "cmDependsJavaParser.y"
+ {
+ jpElementStart(7);
+
+}
+ break;
+
+ case 210:
+#line 1906 "cmDependsJavaParser.y"
+ {
+ jpElementStart(9);
+
+}
+ break;
+
+ case 211:
+#line 1912 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 212:
+#line 1920 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 213:
+#line 1929 "cmDependsJavaParser.y"
+ {
+ jpElementStart(0);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 214:
+#line 1937 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 215:
+#line 1948 "cmDependsJavaParser.y"
+ {
+ jpElementStart(9);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 216:
+#line 1956 "cmDependsJavaParser.y"
+ {
+ jpElementStart(0);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 217:
+#line 1964 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 218:
+#line 1974 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 219:
+#line 1983 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 220:
+#line 1993 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 221:
+#line 2003 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 222:
+#line 2012 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 223:
+#line 2022 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 224:
+#line 2031 "cmDependsJavaParser.y"
+ {
+ jpElementStart(5);
+ jpCheckEmpty(5);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 225:
+#line 2041 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ yyGetParser->DeallocateParserType(&(yyvsp[-1].str));
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 226:
+#line 2051 "cmDependsJavaParser.y"
+ {
+ jpElementStart(0);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 227:
+#line 2059 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+
+}
+ break;
+
+ case 228:
+#line 2066 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ yyGetParser->DeallocateParserType(&(yyvsp[-1].str));
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 229:
+#line 2077 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 230:
+#line 2087 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 231:
+#line 2097 "cmDependsJavaParser.y"
+ {
+ jpElementStart(5);
+ jpCheckEmpty(5);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 232:
+#line 2107 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 233:
+#line 2116 "cmDependsJavaParser.y"
+ {
+ jpElementStart(4);
+ jpCheckEmpty(4);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 234:
+#line 2125 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 235:
+#line 2133 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 236:
+#line 2143 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 237:
+#line 2152 "cmDependsJavaParser.y"
+ {
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 238:
+#line 2162 "cmDependsJavaParser.y"
+ {
+ jpElementStart(5);
+
+}
+ break;
+
+ case 239:
+#line 2169 "cmDependsJavaParser.y"
+ {
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 240:
+#line 2179 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 241:
+#line 2188 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 242:
+#line 2198 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 243:
+#line 2207 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+
+}
+ break;
+
+ case 244:
+#line 2213 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 245:
+#line 2222 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 246:
+#line 2231 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 247:
+#line 2240 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 248:
+#line 2249 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 249:
+#line 2259 "cmDependsJavaParser.y"
+ {
+ jpElementStart(6);
+ jpCheckEmpty(6);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 250:
+#line 2268 "cmDependsJavaParser.y"
+ {
+ jpElementStart(0);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 251:
+#line 2276 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 252:
+#line 2285 "cmDependsJavaParser.y"
+ {
+ jpElementStart(0);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 253:
+#line 2293 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 254:
+#line 2303 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 255:
+#line 2312 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 256:
+#line 2322 "cmDependsJavaParser.y"
+ {
+ jpElementStart(4);
+ jpCheckEmpty(4);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 257:
+#line 2331 "cmDependsJavaParser.y"
+ {
+ jpElementStart(4);
+ jpCheckEmpty(4);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 258:
+#line 2340 "cmDependsJavaParser.y"
+ {
+ jpElementStart(4);
+ jpCheckEmpty(4);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 259:
+#line 2349 "cmDependsJavaParser.y"
+ {
+ jpElementStart(4);
+ jpCheckEmpty(4);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 260:
+#line 2358 "cmDependsJavaParser.y"
+ {
+ jpElementStart(0);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 261:
+#line 2366 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 262:
+#line 2376 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 263:
+#line 2385 "cmDependsJavaParser.y"
+ {
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 264:
+#line 2395 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 265:
+#line 2405 "cmDependsJavaParser.y"
+ {
+ jpElementStart(2);
+
+}
+ break;
+
+ case 266:
+#line 2411 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+
+}
+ break;
+
+ case 267:
+#line 2418 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ yyGetParser->DeallocateParserType(&(yyvsp[0].str));
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 268:
+#line 2428 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ yyGetParser->DeallocateParserType(&(yyvsp[0].str));
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 269:
+#line 2438 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ yyGetParser->DeallocateParserType(&(yyvsp[0].str));
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 270:
+#line 2448 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ yyGetParser->DeallocateParserType(&(yyvsp[0].str));
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 271:
+#line 2459 "cmDependsJavaParser.y"
+ {
+ jpElementStart(4);
+ yyGetParser->DeallocateParserType(&(yyvsp[-3].str));
+ jpCheckEmpty(4);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 272:
+#line 2469 "cmDependsJavaParser.y"
+ {
+ jpElementStart(6);
+ yyGetParser->DeallocateParserType(&(yyvsp[-5].str));
+ yyGetParser->DeallocateParserType(&(yyvsp[-3].str));
+ jpCheckEmpty(6);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 273:
+#line 2480 "cmDependsJavaParser.y"
+ {
+ jpElementStart(6);
+ yyGetParser->DeallocateParserType(&(yyvsp[-3].str));
+ jpCheckEmpty(6);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 274:
+#line 2490 "cmDependsJavaParser.y"
+ {
+ jpElementStart(6);
+ yyGetParser->DeallocateParserType(&(yyvsp[-3].str));
+ jpCheckEmpty(6);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 275:
+#line 2501 "cmDependsJavaParser.y"
+ {
+ jpElementStart(4);
+ yyGetParser->DeallocateParserType(&(yyvsp[-3].str));
+ jpCheckEmpty(4);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 276:
+#line 2511 "cmDependsJavaParser.y"
+ {
+ jpElementStart(4);
+ jpCheckEmpty(4);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 277:
+#line 2521 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 278:
+#line 2530 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ yyGetParser->DeallocateParserType(&(yyvsp[0].str));
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 279:
+#line 2539 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 280:
+#line 2548 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 281:
+#line 2557 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 282:
+#line 2567 "cmDependsJavaParser.y"
+ {
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 283:
+#line 2577 "cmDependsJavaParser.y"
+ {
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 284:
+#line 2587 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 285:
+#line 2596 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 286:
+#line 2605 "cmDependsJavaParser.y"
+ {
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 287:
+#line 2614 "cmDependsJavaParser.y"
+ {
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 288:
+#line 2623 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 289:
+#line 2633 "cmDependsJavaParser.y"
+ {
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 290:
+#line 2643 "cmDependsJavaParser.y"
+ {
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 291:
+#line 2653 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 292:
+#line 2662 "cmDependsJavaParser.y"
+ {
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 293:
+#line 2671 "cmDependsJavaParser.y"
+ {
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 294:
+#line 2680 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 295:
+#line 2690 "cmDependsJavaParser.y"
+ {
+ jpElementStart(5);
+ jpCheckEmpty(5);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 296:
+#line 2699 "cmDependsJavaParser.y"
+ {
+ jpElementStart(4);
+ jpCheckEmpty(4);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 297:
+#line 2708 "cmDependsJavaParser.y"
+ {
+ jpElementStart(5);
+
+}
+ break;
+
+ case 298:
+#line 2715 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 299:
+#line 2724 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 300:
+#line 2733 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 301:
+#line 2742 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 302:
+#line 2752 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 303:
+#line 2761 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 304:
+#line 2770 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 305:
+#line 2780 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 306:
+#line 2789 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 307:
+#line 2798 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 308:
+#line 2807 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 309:
+#line 2817 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 310:
+#line 2826 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 311:
+#line 2835 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 312:
+#line 2844 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 313:
+#line 2853 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 314:
+#line 2862 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 315:
+#line 2872 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 316:
+#line 2881 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 317:
+#line 2890 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 318:
+#line 2900 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 319:
+#line 2909 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 320:
+#line 2919 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 321:
+#line 2928 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 322:
+#line 2938 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 323:
+#line 2947 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 324:
+#line 2957 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 325:
+#line 2966 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 326:
+#line 2976 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 327:
+#line 2985 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 328:
+#line 2995 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 329:
+#line 3004 "cmDependsJavaParser.y"
+ {
+ jpElementStart(5);
+ jpCheckEmpty(5);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 330:
+#line 3014 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 331:
+#line 3023 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 332:
+#line 3033 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 333:
+#line 3043 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ yyGetParser->DeallocateParserType(&(yyvsp[0].str));
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 334:
+#line 3053 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 335:
+#line 3062 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 336:
+#line 3072 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 337:
+#line 3081 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 338:
+#line 3090 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 339:
+#line 3099 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 340:
+#line 3108 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 341:
+#line 3117 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 342:
+#line 3126 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 343:
+#line 3135 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 344:
+#line 3144 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 345:
+#line 3153 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 346:
+#line 3162 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 347:
+#line 3171 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 348:
+#line 3181 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 349:
+#line 3191 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 350:
+#line 3201 "cmDependsJavaParser.y"
+ {
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+ case 351:
+#line 3210 "cmDependsJavaParser.y"
+ {
+ jpElementStart(3);
+ jpStoreClass(yyvsp[-2].str);
+ jpCheckEmpty(3);
+ yyval.str = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+ break;
+
+
+ }
+
+/* Line 1010 of yacc.c. */
+#line 5780 "cmDependsJavaParser.cxx"
+
+ yyvsp -= yylen;
+ yyssp -= yylen;
+
+
+ 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:
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+#if YYERROR_VERBOSE
+ yyn = yypact[yystate];
+
+ if (YYPACT_NINF < yyn && yyn < YYLAST)
+ {
+ YYSIZE_T yysize = 0;
+ int yytype = YYTRANSLATE (yychar);
+ const char* yyprefix;
+ char *yymsg;
+ int yyx;
+
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yycount = 0;
+
+ yyprefix = ", expecting ";
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]);
+ yycount += 1;
+ if (yycount == 5)
+ {
+ yysize = 0;
+ break;
+ }
+ }
+ yysize += (sizeof ("syntax error, unexpected ")
+ + yystrlen (yytname[yytype]));
+ yymsg = (char *) YYSTACK_ALLOC (yysize);
+ if (yymsg != 0)
+ {
+ char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
+ yyp = yystpcpy (yyp, yytname[yytype]);
+
+ if (yycount < 5)
+ {
+ yyprefix = ", expecting ";
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ yyp = yystpcpy (yyp, yyprefix);
+ yyp = yystpcpy (yyp, yytname[yyx]);
+ yyprefix = " or ";
+ }
+ }
+ yyerror (yymsg);
+ YYSTACK_FREE (yymsg);
+ }
+ else
+ yyerror ("syntax error; also virtual memory exhausted");
+ }
+ else
+#endif /* YYERROR_VERBOSE */
+ yyerror ("syntax error");
+ }
+
+
+
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse lookahead token after an
+ error, discard it. */
+
+ if (yychar <= YYEOF)
+ {
+ /* If at end of input, pop the error token,
+ then the rest of the stack, then return failure. */
+ if (yychar == YYEOF)
+ for (;;)
+ {
+ YYPOPSTACK;
+ if (yyssp == yyss)
+ YYABORT;
+ YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
+ yydestruct (yystos[*yyssp], yyvsp);
+ }
+ }
+ else
+ {
+ YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc);
+ yydestruct (yytoken, &yylval);
+ yychar = YYEMPTY;
+
+ }
+ }
+
+ /* Else will try to reuse lookahead token after shifting the error
+ token. */
+ goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR. |
+`---------------------------------------------------*/
+yyerrorlab:
+
+#if defined(__GNUC__) || defined(__HP_aCC)
+ /* Pacify GCC when the user code never invokes YYERROR and the label
+ yyerrorlab therefore never appears in user code. */
+ if (0)
+ goto yyerrorlab;
+#endif
+
+ yyvsp -= yylen;
+ yyssp -= yylen;
+ yystate = *yyssp;
+ goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR. |
+`-------------------------------------------------------------*/
+yyerrlab1:
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (yyn != YYPACT_NINF)
+ {
+ 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;
+
+ YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
+ yydestruct (yystos[yystate], yyvsp);
+ YYPOPSTACK;
+ yystate = *yyssp;
+ YY_STACK_PRINT (yyss, yyssp);
+ }
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ YYDPRINTF ((stderr, "Shifting error token, "));
+
+ *++yyvsp = yylval;
+
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturn;
+
+#ifndef yyoverflow
+/*----------------------------------------------.
+| yyoverflowlab -- parser overflow comes here. |
+`----------------------------------------------*/
+yyoverflowlab:
+ yyerror ("parser stack overflow");
+ yyresult = 2;
+ /* Fall through. */
+#endif
+
+yyreturn:
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE (yyss);
+#endif
+ return yyresult;
+}
+
+
+#line 3219 "cmDependsJavaParser.y"
+
+/* End of grammar */
+
+/*--------------------------------------------------------------------------*/
+void cmDependsJavaError(yyscan_t yyscanner, const char* message)
+{
+ yyGetParser->Error(message);
+}
+
+
diff --git a/Source/cmDependsJavaParser.y b/Source/cmDependsJavaParser.y
new file mode 100644
index 000000000..53210b8ca
--- /dev/null
+++ b/Source/cmDependsJavaParser.y
@@ -0,0 +1,3226 @@
+%{
+/*============================================================================
+ 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.
+============================================================================*/
+/*
+
+This file must be translated to C and modified to build everywhere.
+
+Run bison like this:
+
+ bison --yacc --name-prefix=cmDependsJava_yy --defines=cmDependsJavaParserTokens.h -ocmDependsJavaParser.cxx cmDependsJavaParser.y
+
+Modify cmDependsJavaParser.cxx:
+ - remove TABs
+ - add __HP_aCC to the #if test for yyerrorlab warning suppression
+
+*/
+
+/* Configure the parser to use a lexer object. */
+#define YYPARSE_PARAM yyscanner
+#define YYLEX_PARAM yyscanner
+#define YYERROR_VERBOSE 1
+#define cmDependsJava_yyerror(x) \
+ cmDependsJavaError(yyscanner, x)
+#define yyGetParser (cmDependsJava_yyget_extra(yyscanner))
+
+/*-------------------------------------------------------------------------*/
+#include "cmDependsJavaParserHelper.h" /* Interface to parser object. */
+#include "cmDependsJavaLexer.h" /* Interface to lexer object. */
+#include "cmDependsJavaParserTokens.h" /* Need YYSTYPE for YY_DECL. */
+
+/* Forward declare the lexer entry point. */
+YY_DECL;
+
+/* Internal utility functions. */
+static void cmDependsJavaError(yyscan_t yyscanner, const char* message);
+
+#define YYDEBUG 1
+#define YYMAXDEPTH 1000000
+
+
+#define jpCheckEmpty(cnt) yyGetParser->CheckEmpty(__LINE__, cnt, yyvsp);
+#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. */
+#endif
+%}
+
+/* Generate a reentrant parser object. */
+%pure_parser
+
+/*
+%union {
+ char* string;
+}
+*/
+
+/*-------------------------------------------------------------------------*/
+/* Tokens */
+%token jp_ABSTRACT
+%token jp_ASSERT
+%token jp_BOOLEAN_TYPE
+%token jp_BREAK
+%token jp_BYTE_TYPE
+%token jp_CASE
+%token jp_CATCH
+%token jp_CHAR_TYPE
+%token jp_CLASS
+%token jp_CONTINUE
+%token jp_DEFAULT
+%token jp_DO
+%token jp_DOUBLE_TYPE
+%token jp_ELSE
+%token jp_EXTENDS
+%token jp_FINAL
+%token jp_FINALLY
+%token jp_FLOAT_TYPE
+%token jp_FOR
+%token jp_IF
+%token jp_IMPLEMENTS
+%token jp_IMPORT
+%token jp_INSTANCEOF
+%token jp_INT_TYPE
+%token jp_INTERFACE
+%token jp_LONG_TYPE
+%token jp_NATIVE
+%token jp_NEW
+%token jp_PACKAGE
+%token jp_PRIVATE
+%token jp_PROTECTED
+%token jp_PUBLIC
+%token jp_RETURN
+%token jp_SHORT_TYPE
+%token jp_STATIC
+%token jp_STRICTFP
+%token jp_SUPER
+%token jp_SWITCH
+%token jp_SYNCHRONIZED
+%token jp_THIS
+%token jp_THROW
+%token jp_THROWS
+%token jp_TRANSIENT
+%token jp_TRY
+%token jp_VOID
+%token jp_VOLATILE
+%token jp_WHILE
+
+%token jp_BOOLEANLITERAL
+%token jp_CHARACTERLITERAL
+%token jp_DECIMALINTEGERLITERAL
+%token jp_FLOATINGPOINTLITERAL
+%token jp_HEXINTEGERLITERAL
+%token jp_NULLLITERAL
+%token jp_STRINGLITERAL
+
+%token jp_NAME
+
+%token jp_AND
+%token jp_ANDAND
+%token jp_ANDEQUALS
+%token jp_BRACKETEND
+%token jp_BRACKETSTART
+%token jp_CARROT
+%token jp_CARROTEQUALS
+%token jp_COLON
+%token jp_COMMA
+%token jp_CURLYEND
+%token jp_CURLYSTART
+%token jp_DIVIDE
+%token jp_DIVIDEEQUALS
+%token jp_DOLLAR
+%token jp_DOT
+%token jp_EQUALS
+%token jp_EQUALSEQUALS
+%token jp_EXCLAMATION
+%token jp_EXCLAMATIONEQUALS
+%token jp_GREATER
+%token jp_GTEQUALS
+%token jp_GTGT
+%token jp_GTGTEQUALS
+%token jp_GTGTGT
+%token jp_GTGTGTEQUALS
+%token jp_LESLESEQUALS
+%token jp_LESSTHAN
+%token jp_LTEQUALS
+%token jp_LTLT
+%token jp_MINUS
+%token jp_MINUSEQUALS
+%token jp_MINUSMINUS
+%token jp_PAREEND
+%token jp_PARESTART
+%token jp_PERCENT
+%token jp_PERCENTEQUALS
+%token jp_PIPE
+%token jp_PIPEEQUALS
+%token jp_PIPEPIPE
+%token jp_PLUS
+%token jp_PLUSEQUALS
+%token jp_PLUSPLUS
+%token jp_QUESTION
+%token jp_SEMICOL
+%token jp_TILDE
+%token jp_TIMES
+%token jp_TIMESEQUALS
+
+%token jp_ERROR
+
+/*-------------------------------------------------------------------------*/
+/* grammar */
+%%
+
+Goal:
+CompilationUnit
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+
+Literal:
+IntegerLiteral
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+|
+jp_FLOATINGPOINTLITERAL
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+|
+jp_BOOLEANLITERAL
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+|
+jp_CHARACTERLITERAL
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+|
+jp_STRINGLITERAL
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+|
+jp_NULLLITERAL
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+
+IntegerLiteral:
+jp_DECIMALINTEGERLITERAL
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+|
+jp_HEXINTEGERLITERAL
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+
+Type:
+PrimitiveType
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+|
+ReferenceType
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+
+PrimitiveType:
+jp_BYTE_TYPE
+{
+ jpElementStart(0);
+}
+|
+jp_SHORT_TYPE
+{
+ jpElementStart(0);
+}
+|
+jp_INT_TYPE
+{
+ jpElementStart(0);
+}
+|
+jp_LONG_TYPE
+{
+ jpElementStart(0);
+}
+|
+jp_CHAR_TYPE
+{
+ jpElementStart(0);
+}
+|
+jp_FLOAT_TYPE
+{
+ jpElementStart(0);
+}
+|
+jp_DOUBLE_TYPE
+{
+ jpElementStart(0);
+}
+|
+jp_BOOLEAN_TYPE
+{
+ jpElementStart(0);
+}
+
+ReferenceType:
+ClassOrInterfaceType
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+|
+ArrayType
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+
+ClassOrInterfaceType:
+Name
+{
+ jpElementStart(1);
+ jpStoreClass($<str>1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+
+ClassType:
+ClassOrInterfaceType
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+
+InterfaceType:
+ClassOrInterfaceType
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+
+ArrayType:
+PrimitiveType Dims
+{
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+|
+Name Dims
+{
+ jpElementStart(2);
+ jpStoreClass($<str>1);
+ jpCheckEmpty(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+
+Name:
+SimpleName
+{
+ jpElementStart(1);
+ $<str>$ = $<str>1;
+}
+|
+QualifiedName
+{
+ jpElementStart(1);
+ $<str>$ = $<str>1;
+}
+
+SimpleName:
+Identifier
+{
+ jpElementStart(1);
+ $<str>$ = $<str>1;
+}
+
+Identifier:
+jp_NAME
+{
+ jpElementStart(1);
+ $<str>$ = $<str>1;
+}
+|
+jp_DOLLAR jp_NAME
+{
+ jpElementStart(2);
+ $<str>$ = $<str>2;
+}
+
+QualifiedName:
+Name jp_DOT Identifier
+{
+ jpElementStart(3);
+ yyGetParser->AddClassFound($<str>1);
+ yyGetParser->UpdateCombine($<str>1, $<str>3);
+ yyGetParser->DeallocateParserType(&($<str>1));
+ $<str>$ = const_cast<char*>(yyGetParser->GetCurrentCombine());
+}
+|
+Name jp_DOT jp_CLASS
+{
+ jpElementStart(3);
+ jpStoreClass($<str>1);
+ jpCheckEmpty(3);
+ yyGetParser->SetCurrentCombine("");
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+|
+Name jp_DOT jp_THIS
+{
+ jpElementStart(3);
+ jpStoreClass($<str>1);
+ yyGetParser->SetCurrentCombine("");
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+|
+SimpleType jp_DOT jp_CLASS
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+
+SimpleType:
+PrimitiveType
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+|
+jp_VOID
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+
+CompilationUnit:
+PackageDeclarationopt ImportDeclarations TypeDeclarations
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+
+PackageDeclarationopt:
+{
+ jpElementStart(0);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+|
+PackageDeclaration
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+
+ImportDeclarations:
+{
+ jpElementStart(0);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+|
+ImportDeclarations ImportDeclaration
+{
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+
+TypeDeclarations:
+{
+ jpElementStart(0);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+|
+TypeDeclarations TypeDeclaration
+{
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+
+PackageDeclaration:
+jp_PACKAGE Name jp_SEMICOL
+{
+ jpElementStart(3);
+ yyGetParser->SetCurrentPackage($<str>2);
+ yyGetParser->DeallocateParserType(&($<str>2));
+ yyGetParser->SetCurrentCombine("");
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+
+ImportDeclaration:
+SingleTypeImportDeclaration
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+|
+TypeImportOnDemandDeclaration
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+
+SingleTypeImportDeclaration:
+jp_IMPORT Name jp_SEMICOL
+{
+ jpElementStart(3);
+ yyGetParser->AddPackagesImport($<str>2);
+ yyGetParser->DeallocateParserType(&($<str>2));
+ yyGetParser->SetCurrentCombine("");
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+
+TypeImportOnDemandDeclaration:
+jp_IMPORT Name jp_DOT jp_TIMES jp_SEMICOL
+{
+ jpElementStart(5);
+ std::string str = $<str>2;
+ str += ".*";
+ yyGetParser->AddPackagesImport(str.c_str());
+ yyGetParser->DeallocateParserType(&($<str>2));
+ yyGetParser->SetCurrentCombine("");
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+
+TypeDeclaration:
+ClassDeclaration
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+|
+InterfaceDeclaration
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+|
+jp_SEMICOL
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+
+Modifiers:
+Modifier
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+|
+Modifiers Modifier
+{
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+
+Modifier:
+jp_PUBLIC | jp_PROTECTED | jp_PRIVATE |
+jp_STATIC |
+jp_ABSTRACT | jp_FINAL | jp_NATIVE | jp_SYNCHRONIZED | jp_TRANSIENT | jp_VOLATILE |
+jp_STRICTFP
+
+ClassHeader:
+Modifiersopt jp_CLASS Identifier
+{
+ yyGetParser->StartClass($<str>3);
+ jpElementStart(3);
+ yyGetParser->DeallocateParserType(&($<str>3));
+ jpCheckEmpty(3);
+}
+
+
+ClassDeclaration:
+ClassHeader ClassBody
+{
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+ yyGetParser->EndClass();
+}
+|
+ClassHeader Interfaces ClassBody
+{
+ jpElementStart(3);
+ jpCheckEmpty(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+ yyGetParser->EndClass();
+}
+|
+ClassHeader Super ClassBody
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+ yyGetParser->EndClass();
+}
+|
+ClassHeader Super Interfaces ClassBody
+{
+ jpElementStart(4);
+ jpCheckEmpty(4);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+ yyGetParser->EndClass();
+}
+
+Modifiersopt:
+{
+ jpElementStart(0);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+|
+Modifiers
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+
+Super:
+jp_EXTENDS ClassType
+{
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+
+Interfaces:
+jp_IMPLEMENTS InterfaceTypeList
+{
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+
+InterfaceTypeList:
+InterfaceType
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+|
+InterfaceTypeList jp_COMMA InterfaceType
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+
+ClassBody:
+jp_CURLYSTART ClassBodyDeclarations jp_CURLYEND
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+
+ClassBodyDeclarations:
+{
+ jpElementStart(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+|
+ClassBodyDeclarations ClassBodyDeclaration
+{
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+
+ClassBodyDeclaration:
+ClassMemberDeclaration
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+|
+StaticInitializer
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+|
+ConstructorDeclaration
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+|
+TypeDeclaration
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+
+ClassMemberDeclaration:
+FieldDeclaration
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+|
+MethodDeclaration
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+
+FieldDeclaration:
+Modifiersopt Type VariableDeclarators jp_SEMICOL
+{
+ jpElementStart(4);
+}
+
+VariableDeclarators:
+VariableDeclarator
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+|
+VariableDeclarators jp_COMMA VariableDeclarator
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+
+VariableDeclarator:
+VariableDeclaratorId
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+|
+VariableDeclaratorId jp_EQUALS VariableInitializer
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+
+VariableDeclaratorId:
+Identifier
+{
+ jpElementStart(1);
+ yyGetParser->DeallocateParserType(&($<str>1));
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+|
+VariableDeclaratorId jp_BRACKETSTART jp_BRACKETEND
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+
+VariableInitializer:
+Expression
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+|
+ArrayInitializer
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+
+MethodDeclaration:
+MethodHeader jp_SEMICOL
+{
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+|
+MethodHeader MethodBody
+{
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+|
+MethodHeader MethodBody jp_SEMICOL
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+
+MethodHeader:
+Modifiersopt Type MethodDeclarator Throwsopt
+{
+ jpElementStart(4);
+ jpCheckEmpty(4);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+Modifiersopt jp_VOID MethodDeclarator Throwsopt
+{
+ jpElementStart(4);
+ jpCheckEmpty(4);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+Throwsopt:
+{
+ jpElementStart(0);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+Throws
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+MethodDeclarator:
+Identifier jp_PARESTART FormalParameterListopt jp_PAREEND
+{
+ jpElementStart(4);
+ yyGetParser->DeallocateParserType(&($<str>1));
+ jpCheckEmpty(4);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+MethodDeclarator jp_BRACKETSTART jp_BRACKETEND
+{
+ jpElementStart(3);
+
+}
+
+FormalParameterListopt:
+{
+ jpElementStart(0);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+FormalParameterList
+
+FormalParameterList:
+FormalParameter
+{
+ jpElementStart(1);
+
+}
+|
+FormalParameterList jp_COMMA FormalParameter
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+FormalParameter:
+Modifiersopt Type VariableDeclaratorId
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+Throws:
+jp_THROWS ClassTypeList
+{
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+ClassTypeList:
+ClassType
+{
+ jpElementStart(1);
+
+}
+|
+ClassTypeList jp_COMMA ClassType
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+MethodBody:
+Block
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+StaticInitializer:
+jp_STATIC Block
+{
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+ConstructorDeclaration:
+Modifiersopt ConstructorDeclarator Throwsopt ConstructorBody
+{
+ jpElementStart(4);
+ jpCheckEmpty(4);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+Modifiersopt ConstructorDeclarator Throwsopt ConstructorBody jp_SEMICOL
+{
+ jpElementStart(5);
+ jpCheckEmpty(5);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+ConstructorDeclarator:
+SimpleName jp_PARESTART FormalParameterListopt jp_PAREEND
+{
+ jpElementStart(4);
+ yyGetParser->DeallocateParserType(&($<str>1));
+ jpCheckEmpty(4);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+ConstructorBody:
+jp_CURLYSTART ExplicitConstructorInvocationopt BlockStatementsopt jp_CURLYEND
+{
+ jpElementStart(4);
+ jpCheckEmpty(4);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+ExplicitConstructorInvocationopt:
+{
+ jpElementStart(0);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+ExplicitConstructorInvocationopt ExplicitConstructorInvocation
+{
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+ExplicitConstructorInvocation:
+jp_THIS jp_PARESTART ArgumentListopt jp_PAREEND jp_SEMICOL
+{
+ jpElementStart(5);
+ jpCheckEmpty(5);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+jp_SUPER jp_PARESTART ArgumentListopt jp_PAREEND jp_SEMICOL
+{
+ jpElementStart(5);
+ jpCheckEmpty(5);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+InterfaceHeader:
+Modifiersopt jp_INTERFACE Identifier
+{
+ yyGetParser->StartClass($<str>3);
+ jpElementStart(3);
+ yyGetParser->DeallocateParserType(&($<str>3));
+ jpCheckEmpty(3);
+}
+
+InterfaceDeclaration:
+InterfaceHeader ExtendsInterfacesopt InterfaceBody
+{
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+ yyGetParser->EndClass();
+}
+
+ExtendsInterfacesopt:
+{
+ jpElementStart(0);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+}
+|
+ExtendsInterfaces
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+ExtendsInterfaces:
+jp_EXTENDS InterfaceType
+{
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+ExtendsInterfaces jp_COMMA InterfaceType
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+InterfaceBody:
+jp_CURLYSTART InterfaceMemberDeclarations jp_CURLYEND
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+InterfaceMemberDeclarations:
+{
+ jpElementStart(0);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+InterfaceMemberDeclarations InterfaceMemberDeclaration
+{
+ jpElementStart(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+InterfaceMemberDeclaration:
+ConstantDeclaration
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+AbstractMethodDeclaration
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+ClassDeclaration
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+ClassDeclaration jp_SEMICOL
+{
+ jpElementStart(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+InterfaceDeclaration
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+InterfaceDeclaration jp_SEMICOL
+{
+ jpElementStart(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+ConstantDeclaration:
+FieldDeclaration
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+AbstractMethodDeclaration:
+MethodHeader Semicols
+{
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+Semicols:
+jp_SEMICOL
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+Semicols jp_SEMICOL
+{
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+ArrayInitializer:
+jp_CURLYSTART VariableInitializersOptional jp_CURLYEND
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+VariableInitializersOptional:
+{
+ jpElementStart(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+VariableInitializers
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+VariableInitializers jp_COMMA
+{
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+VariableInitializers:
+VariableInitializer
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+VariableInitializers jp_COMMA VariableInitializer
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+Block:
+jp_CURLYSTART BlockStatementsopt jp_CURLYEND
+{
+ jpElementStart(4);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+BlockStatementsopt:
+{
+ jpElementStart(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+BlockStatements
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+BlockStatements:
+BlockStatement
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+BlockStatements BlockStatement
+{
+ jpElementStart(1);
+ jpCheckEmpty(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+BlockStatement:
+LocalVariableDeclarationStatement
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+Statement
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+ClassDeclaration
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+LocalVariableDeclarationStatement:
+LocalVariableDeclaration jp_SEMICOL
+{
+ jpElementStart(1);
+ jpCheckEmpty(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+LocalVariableDeclaration:
+Modifiers Type VariableDeclarators
+{
+ jpElementStart(1);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+Type VariableDeclarators
+{
+ jpElementStart(1);
+ jpCheckEmpty(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+Statement:
+StatementWithoutTrailingSubstatement
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+LabeledStatement
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+IfThenStatement
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+IfThenElseStatement
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+WhileStatement
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+ForStatement
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+StatementNoShortIf:
+StatementWithoutTrailingSubstatement
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+LabeledStatementNoShortIf
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+IfThenElseStatementNoShortIf
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+WhileStatementNoShortIf
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+ForStatementNoShortIf
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+StatementWithoutTrailingSubstatement:
+Block
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+EmptyStatement
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+ExpressionStatement
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+SwitchStatement
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+DoStatement
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+BreakStatement
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+ContinueStatement
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+ReturnStatement
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+SynchronizedStatement
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+ThrowStatement
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+TryStatement
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+AssertStatement
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+EmptyStatement:
+jp_SEMICOL
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+LabeledStatement:
+Identifier jp_COLON Statement
+{
+ jpElementStart(3);
+ yyGetParser->DeallocateParserType(&($<str>1));
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+LabeledStatementNoShortIf:
+Identifier jp_COLON StatementNoShortIf
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+ExpressionStatement:
+StatementExpression jp_SEMICOL
+{
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+StatementExpression:
+Assignment
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+PreIncrementExpression
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+PreDecrementExpression
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+PostIncrementExpression
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+PostDecrementExpression
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+MethodInvocation
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+ClassInstanceCreationExpression
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+IfThenStatement:
+jp_IF jp_PARESTART Expression jp_PAREEND Statement
+{
+ jpElementStart(5);
+ jpCheckEmpty(5);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+IfThenElseStatement:
+jp_IF jp_PARESTART Expression jp_PAREEND StatementNoShortIf jp_ELSE Statement
+{
+ jpElementStart(7);
+ jpCheckEmpty(7);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+IfThenElseStatementNoShortIf:
+jp_IF jp_PARESTART Expression jp_PAREEND StatementNoShortIf jp_ELSE StatementNoShortIf
+{
+ jpElementStart(7);
+ jpCheckEmpty(7);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+SwitchStatement:
+jp_SWITCH jp_PARESTART Expression jp_PAREEND SwitchBlock
+{
+ jpElementStart(5);
+
+}
+
+SwitchBlock:
+jp_CURLYSTART SwitchBlockStatementGroups SwitchLabelsopt jp_CURLYEND
+{
+ jpElementStart(4);
+
+}
+
+SwitchLabelsopt:
+{
+ jpElementStart(0);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+SwitchLabels
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+SwitchBlockStatementGroups:
+{
+ jpElementStart(0);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+SwitchBlockStatementGroups SwitchBlockStatementGroup
+{
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+SwitchBlockStatementGroup:
+SwitchLabels BlockStatements
+{
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+SwitchLabels:
+SwitchLabel
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+SwitchLabels SwitchLabel
+{
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+SwitchLabel:
+jp_CASE ConstantExpression jp_COLON
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+jp_DEFAULT jp_COLON
+{
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+WhileStatement:
+jp_WHILE jp_PARESTART Expression jp_PAREEND Statement
+{
+ jpElementStart(5);
+
+}
+
+WhileStatementNoShortIf:
+jp_WHILE jp_PARESTART Expression jp_PAREEND StatementNoShortIf
+{
+ jpElementStart(5);
+
+}
+
+DoStatement:
+jp_DO Statement jp_WHILE jp_PARESTART Expression jp_PAREEND jp_SEMICOL
+{
+ jpElementStart(7);
+
+}
+
+ForStatement:
+jp_FOR jp_PARESTART ForInitopt jp_SEMICOL Expressionopt jp_SEMICOL ForUpdateopt jp_PAREEND
+Statement
+{
+ jpElementStart(9);
+
+}
+
+ForUpdateopt:
+{
+ jpElementStart(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+ForUpdate
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+ForInitopt:
+{
+ jpElementStart(0);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+ForInit
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+ForStatementNoShortIf:
+jp_FOR jp_PARESTART ForInitopt jp_SEMICOL Expressionopt jp_SEMICOL ForUpdateopt jp_PAREEND
+StatementNoShortIf
+{
+ jpElementStart(9);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+Expressionopt:
+{
+ jpElementStart(0);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+Expression
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+ForInit:
+StatementExpressionList
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+LocalVariableDeclaration
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+ForUpdate:
+StatementExpressionList
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+StatementExpressionList:
+StatementExpression
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+StatementExpressionList jp_COMMA StatementExpression
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+AssertStatement:
+jp_ASSERT Expression jp_SEMICOL
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+jp_ASSERT Expression jp_COLON Expression jp_SEMICOL
+{
+ jpElementStart(5);
+ jpCheckEmpty(5);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+BreakStatement:
+jp_BREAK Identifieropt jp_SEMICOL
+{
+ jpElementStart(3);
+ yyGetParser->DeallocateParserType(&($<str>2));
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+Identifieropt:
+{
+ jpElementStart(0);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+Identifier
+{
+ jpElementStart(1);
+
+}
+
+ContinueStatement:
+jp_CONTINUE Identifieropt jp_SEMICOL
+{
+ jpElementStart(3);
+ yyGetParser->DeallocateParserType(&($<str>2));
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+ReturnStatement:
+jp_RETURN Expressionopt jp_SEMICOL
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+ThrowStatement:
+jp_THROW Expression jp_SEMICOL
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+SynchronizedStatement:
+jp_SYNCHRONIZED jp_PARESTART Expression jp_PAREEND Block
+{
+ jpElementStart(5);
+ jpCheckEmpty(5);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+TryStatement:
+jp_TRY Block Catches
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+jp_TRY Block Catchesopt Finally
+{
+ jpElementStart(4);
+ jpCheckEmpty(4);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+Catchesopt:
+{
+ jpElementStart(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+Catches
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+Catches:
+CatchClause
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+Catches CatchClause
+{
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+CatchClause:
+jp_CATCH jp_PARESTART FormalParameter jp_PAREEND Block
+{
+ jpElementStart(5);
+
+}
+
+Finally:
+jp_FINALLY Block
+{
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+Primary:
+PrimaryNoNewArray
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+ArrayCreationExpression
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+PrimaryNoNewArray:
+Literal
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+jp_THIS
+{
+ jpElementStart(1);
+
+}
+|
+jp_PARESTART Expression jp_PAREEND
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+ClassInstanceCreationExpression
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+FieldAccess
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+MethodInvocation
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+ArrayAccess
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+ClassInstanceCreationExpression:
+New ClassType jp_PARESTART ArgumentListopt jp_PAREEND ClassBodyOpt
+{
+ jpElementStart(6);
+ jpCheckEmpty(6);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+ClassBodyOpt:
+{
+ jpElementStart(0);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+ClassBody
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+ArgumentListopt:
+{
+ jpElementStart(0);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+ArgumentList
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+ArgumentList:
+Expression
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+ArgumentList jp_COMMA Expression
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+ArrayCreationExpression:
+New PrimitiveType DimExprs Dimsopt
+{
+ jpElementStart(4);
+ jpCheckEmpty(4);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+New ClassOrInterfaceType DimExprs Dimsopt
+{
+ jpElementStart(4);
+ jpCheckEmpty(4);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+New PrimitiveType Dims ArrayInitializer
+{
+ jpElementStart(4);
+ jpCheckEmpty(4);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+New ClassOrInterfaceType Dims ArrayInitializer
+{
+ jpElementStart(4);
+ jpCheckEmpty(4);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+Dimsopt:
+{
+ jpElementStart(0);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+Dims
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+DimExprs:
+DimExpr
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+DimExprs DimExpr
+{
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+DimExpr:
+jp_BRACKETSTART Expression jp_BRACKETEND
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+Dims:
+jp_BRACKETSTART jp_BRACKETEND
+{
+ jpElementStart(2);
+
+}
+|
+Dims jp_BRACKETSTART jp_BRACKETEND
+{
+ jpElementStart(3);
+
+}
+
+FieldAccess:
+Primary jp_DOT Identifier
+{
+ jpElementStart(3);
+ yyGetParser->DeallocateParserType(&($<str>3));
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+jp_SUPER jp_DOT Identifier
+{
+ jpElementStart(3);
+ yyGetParser->DeallocateParserType(&($<str>3));
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+jp_THIS jp_DOT Identifier
+{
+ jpElementStart(3);
+ yyGetParser->DeallocateParserType(&($<str>3));
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+Primary jp_DOT jp_THIS
+{
+ jpElementStart(3);
+ yyGetParser->DeallocateParserType(&($<str>3));
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+MethodInvocation:
+Name jp_PARESTART ArgumentListopt jp_PAREEND
+{
+ jpElementStart(4);
+ yyGetParser->DeallocateParserType(&($<str>1));
+ jpCheckEmpty(4);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+Primary jp_DOT Identifier jp_PARESTART ArgumentListopt jp_PAREEND
+{
+ jpElementStart(6);
+ yyGetParser->DeallocateParserType(&($<str>1));
+ yyGetParser->DeallocateParserType(&($<str>3));
+ jpCheckEmpty(6);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+jp_SUPER jp_DOT Identifier jp_PARESTART ArgumentListopt jp_PAREEND
+{
+ jpElementStart(6);
+ yyGetParser->DeallocateParserType(&($<str>3));
+ jpCheckEmpty(6);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+jp_THIS jp_DOT Identifier jp_PARESTART ArgumentListopt jp_PAREEND
+{
+ jpElementStart(6);
+ yyGetParser->DeallocateParserType(&($<str>3));
+ jpCheckEmpty(6);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+ArrayAccess:
+Name jp_BRACKETSTART Expression jp_BRACKETEND
+{
+ jpElementStart(4);
+ yyGetParser->DeallocateParserType(&($<str>1));
+ jpCheckEmpty(4);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+PrimaryNoNewArray jp_BRACKETSTART Expression jp_BRACKETEND
+{
+ jpElementStart(4);
+ jpCheckEmpty(4);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+PostfixExpression:
+Primary
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+Name
+{
+ jpElementStart(1);
+ yyGetParser->DeallocateParserType(&($<str>1));
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+ArrayType jp_DOT jp_CLASS
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+PostIncrementExpression
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+PostDecrementExpression
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+PostIncrementExpression:
+PostfixExpression jp_PLUSPLUS
+{
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+PostDecrementExpression:
+PostfixExpression jp_MINUSMINUS
+{
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+UnaryExpression:
+PreIncrementExpression
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+PreDecrementExpression
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+jp_PLUS UnaryExpression
+{
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+jp_MINUS UnaryExpression
+{
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+UnaryExpressionNotPlusMinus
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+PreIncrementExpression:
+jp_PLUSPLUS UnaryExpression
+{
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+PreDecrementExpression:
+jp_MINUSMINUS UnaryExpression
+{
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+UnaryExpressionNotPlusMinus:
+PostfixExpression
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+jp_TILDE UnaryExpression
+{
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+jp_EXCLAMATION UnaryExpression
+{
+ jpElementStart(2);
+ jpCheckEmpty(2);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+CastExpression
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+CastExpression:
+jp_PARESTART PrimitiveType Dimsopt jp_PAREEND UnaryExpression
+{
+ jpElementStart(5);
+ jpCheckEmpty(5);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+jp_PARESTART Expression jp_PAREEND UnaryExpressionNotPlusMinus
+{
+ jpElementStart(4);
+ jpCheckEmpty(4);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+jp_PARESTART Name Dims jp_PAREEND UnaryExpressionNotPlusMinus
+{
+ jpElementStart(5);
+
+}
+
+MultiplicativeExpression:
+UnaryExpression
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+MultiplicativeExpression jp_TIMES UnaryExpression
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+MultiplicativeExpression jp_DIVIDE UnaryExpression
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+MultiplicativeExpression jp_PERCENT UnaryExpression
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+AdditiveExpression:
+MultiplicativeExpression
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+AdditiveExpression jp_PLUS MultiplicativeExpression
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+AdditiveExpression jp_MINUS MultiplicativeExpression
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+ShiftExpression:
+AdditiveExpression
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+ShiftExpression jp_LTLT AdditiveExpression
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+ShiftExpression jp_GTGT AdditiveExpression
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+ShiftExpression jp_GTGTGT AdditiveExpression
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+RelationalExpression:
+ShiftExpression
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+RelationalExpression jp_LESSTHAN ShiftExpression
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+RelationalExpression jp_GREATER ShiftExpression
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+RelationalExpression jp_LTEQUALS ShiftExpression
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+RelationalExpression jp_GTEQUALS ShiftExpression
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+RelationalExpression jp_INSTANCEOF ReferenceType
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+EqualityExpression:
+RelationalExpression
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+EqualityExpression jp_EQUALSEQUALS RelationalExpression
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+EqualityExpression jp_EXCLAMATIONEQUALS RelationalExpression
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+AndExpression:
+EqualityExpression
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+AndExpression jp_AND EqualityExpression
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+ExclusiveOrExpression:
+AndExpression
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+ExclusiveOrExpression jp_CARROT AndExpression
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+InclusiveOrExpression:
+ExclusiveOrExpression
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+InclusiveOrExpression jp_PIPE ExclusiveOrExpression
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+ConditionalAndExpression:
+InclusiveOrExpression
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+ConditionalAndExpression jp_ANDAND InclusiveOrExpression
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+ConditionalOrExpression:
+ConditionalAndExpression
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+ConditionalOrExpression jp_PIPEPIPE ConditionalAndExpression
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+ConditionalExpression:
+ConditionalOrExpression
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+ConditionalOrExpression jp_QUESTION Expression jp_COLON ConditionalExpression
+{
+ jpElementStart(5);
+ jpCheckEmpty(5);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+AssignmentExpression:
+ConditionalExpression
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+Assignment
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+Assignment:
+LeftHandSide AssignmentOperator AssignmentExpression
+{
+ jpElementStart(3);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+LeftHandSide:
+Name
+{
+ jpElementStart(1);
+ yyGetParser->DeallocateParserType(&($<str>1));
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+FieldAccess
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+ArrayAccess
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+AssignmentOperator:
+jp_EQUALS
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+jp_TIMESEQUALS
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+jp_DIVIDEEQUALS
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+jp_PERCENTEQUALS
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+jp_PLUSEQUALS
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+jp_MINUSEQUALS
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+jp_LESLESEQUALS
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+jp_GTGTEQUALS
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+jp_GTGTGTEQUALS
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+jp_ANDEQUALS
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+jp_CARROTEQUALS
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+jp_PIPEEQUALS
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+Expression:
+AssignmentExpression
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+ConstantExpression:
+Expression
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+New:
+jp_NEW
+{
+ jpElementStart(1);
+ jpCheckEmpty(1);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+|
+Name jp_DOT jp_NEW
+{
+ jpElementStart(3);
+ jpStoreClass($<str>1);
+ jpCheckEmpty(3);
+ $<str>$ = 0;
+ yyGetParser->SetCurrentCombine("");
+
+}
+
+%%
+/* End of grammar */
+
+/*--------------------------------------------------------------------------*/
+void cmDependsJavaError(yyscan_t yyscanner, const char* message)
+{
+ yyGetParser->Error(message);
+}
+
diff --git a/Source/cmDependsJavaParserHelper.cxx b/Source/cmDependsJavaParserHelper.cxx
new file mode 100644
index 000000000..7b595cc1f
--- /dev/null
+++ b/Source/cmDependsJavaParserHelper.cxx
@@ -0,0 +1,429 @@
+/*============================================================================
+ 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 "cmDependsJavaParserHelper.h"
+
+#include "cmSystemTools.h"
+#include "cmDependsJavaLexer.h"
+
+int cmDependsJava_yyparse( yyscan_t yyscanner );
+
+cmDependsJavaParserHelper::cmDependsJavaParserHelper()
+{
+ this->CurrentDepth = 0;
+
+ this->UnionsAvailable = 0;
+ this->LastClassId = 0;
+
+ CurrentClass tl;
+ tl.Name = "*";
+ this->ClassStack.push_back(tl);
+}
+
+
+cmDependsJavaParserHelper::~cmDependsJavaParserHelper()
+{
+ this->CleanupParser();
+}
+
+void cmDependsJavaParserHelper::CurrentClass
+::AddFileNamesForPrinting(std::vector<cmStdString> *files,
+ const char* prefix, const char* sep)
+{
+ cmStdString rname = "";
+ if ( prefix )
+ {
+ rname += prefix;
+ rname += sep;
+ }
+ rname += this->Name;
+ files->push_back(rname);
+ std::vector<CurrentClass>::iterator it;
+ for ( it = this->NestedClasses->begin();
+ it != this->NestedClasses->end();
+ ++ it )
+ {
+ it->AddFileNamesForPrinting(files, rname.c_str(), sep);
+ }
+}
+
+void cmDependsJavaParserHelper::DeallocateParserType(char** pt)
+{
+ if (!pt)
+ {
+ return;
+ }
+ if (!*pt)
+ {
+ return;
+ }
+ *pt = 0;
+ this->UnionsAvailable --;
+}
+
+void cmDependsJavaParserHelper::AddClassFound(const char* sclass)
+{
+ if( ! sclass )
+ {
+ return;
+ }
+ std::vector<cmStdString>::iterator it;
+ for ( it = this->ClassesFound.begin();
+ it != this->ClassesFound.end();
+ it ++ )
+ {
+ if ( *it == sclass )
+ {
+ return;
+ }
+ }
+ this->ClassesFound.push_back(sclass);
+}
+
+void cmDependsJavaParserHelper::AddPackagesImport(const char* sclass)
+{
+ std::vector<cmStdString>::iterator it;
+ for ( it = this->PackagesImport.begin();
+ it != this->PackagesImport.end();
+ it ++ )
+ {
+ if ( *it == sclass )
+ {
+ return;
+ }
+ }
+ this->PackagesImport.push_back(sclass);
+}
+
+void cmDependsJavaParserHelper::SafePrintMissing(const char* str,
+ int line, int cnt)
+{
+ if ( str )
+ {
+ std::cout << line << " String " << cnt << " exists: ";
+ unsigned int cc;
+ for ( cc = 0; cc < strlen(str); cc ++ )
+ {
+ unsigned char ch = str[cc];
+ if ( ch >= 32 && ch <= 126 )
+ {
+ std::cout << (char)ch;
+ }
+ else
+ {
+ std::cout << "<" << (int)ch << ">";
+ break;
+ }
+ }
+ std::cout << "- " << strlen(str) << std::endl;
+ }
+}
+void cmDependsJavaParserHelper::Print(const char* place, const char* str)
+{
+ if ( this->Verbose )
+ {
+ std::cout << "[" << place << "=" << str << "]" << std::endl;
+ }
+}
+
+void cmDependsJavaParserHelper::CombineUnions(char** out,
+ const char* in1, char** in2,
+ const char* sep)
+{
+ size_t len = 1;
+ if ( in1 )
+ {
+ len += strlen(in1);
+ }
+ if ( *in2 )
+ {
+ len += strlen(*in2);
+ }
+ if ( sep )
+ {
+ len += strlen(sep);
+ }
+ *out = new char [ len ];
+ *out[0] = 0;
+ if ( in1 )
+ {
+ strcat(*out, in1);
+ }
+ if ( sep )
+ {
+ strcat(*out, sep);
+ }
+ if ( *in2 )
+ {
+ strcat(*out, *in2);
+ }
+ if ( *in2 )
+ {
+ this->DeallocateParserType(in2);
+ }
+ this->UnionsAvailable ++;
+}
+
+void cmDependsJavaParserHelper
+::CheckEmpty(int line, int cnt, cmDependsJavaParserHelper::ParserType* pt)
+{
+ int cc;
+ int kk = -cnt + 1;
+ for ( cc = 1; cc <= cnt; cc ++)
+ {
+ cmDependsJavaParserHelper::ParserType* cpt = pt + kk;
+ this->SafePrintMissing(cpt->str, line, cc);
+ kk ++;
+ }
+}
+
+void cmDependsJavaParserHelper
+::PrepareElement(cmDependsJavaParserHelper::ParserType* me)
+{
+ // Inititalize self
+ me->str = 0;
+}
+
+void cmDependsJavaParserHelper
+::AllocateParserType(cmDependsJavaParserHelper::ParserType* pt,
+ const char* str, int len)
+{
+ pt->str = 0;
+ if ( len == 0 )
+ {
+ len = (int)strlen(str);
+ }
+ if ( len == 0 )
+ {
+ return;
+ }
+ this->UnionsAvailable ++;
+ pt->str = new char[ len + 1 ];
+ strncpy(pt->str, str, len);
+ pt->str[len] = 0;
+ this->Allocates.push_back(pt->str);
+}
+
+void cmDependsJavaParserHelper::StartClass(const char* cls)
+{
+ CurrentClass cl;
+ cl.Name = cls;
+ this->ClassStack.push_back(cl);
+
+ this->CurrentDepth ++;
+}
+
+void cmDependsJavaParserHelper::EndClass()
+{
+ CurrentClass* parent = 0;
+ CurrentClass* current = 0;
+ if ( this->ClassStack.size() > 0 )
+ {
+ current = &(*(this->ClassStack.end() - 1));
+ if ( this->ClassStack.size() > 1 )
+ {
+ parent = &(*(this->ClassStack.end() - 2));
+ }
+ }
+ if ( current == 0 )
+ {
+ std::cerr << "Error when parsing. Current class is null" << std::endl;
+ abort();
+ }
+ if ( parent == 0 )
+ {
+ std::cerr << "Error when parsing. Parent class is null" << std::endl;
+ abort();
+ }
+ this->CurrentDepth --;
+ parent->NestedClasses->push_back(*current);
+ this->ClassStack.erase(this->ClassStack.end()-1, this->ClassStack.end());
+}
+
+void cmDependsJavaParserHelper::PrintClasses()
+{
+ if ( this->ClassStack.size() == 0 )
+ {
+ std::cerr << "Error when parsing. No classes on class stack" << std::endl;
+ abort();
+ }
+ std::vector<cmStdString> files = this->GetFilesProduced();
+ std::vector<cmStdString>::iterator sit;
+ for ( sit = files.begin();
+ sit != files.end();
+ ++ sit )
+ {
+ std::cout << " " << sit->c_str() << ".class" << std::endl;
+ }
+}
+
+std::vector<cmStdString> cmDependsJavaParserHelper::GetFilesProduced()
+{
+ std::vector<cmStdString> files;
+ CurrentClass* toplevel = &(*(this->ClassStack.begin()));
+ std::vector<CurrentClass>::iterator it;
+ for ( it = toplevel->NestedClasses->begin();
+ it != toplevel->NestedClasses->end();
+ ++ it )
+ {
+ it->AddFileNamesForPrinting(&files, 0, "$");
+ }
+ return files;
+}
+
+int cmDependsJavaParserHelper::ParseString(const char* str, int verb)
+{
+ if ( !str)
+ {
+ return 0;
+ }
+ this->Verbose = verb;
+ this->InputBuffer = str;
+ this->InputBufferPos = 0;
+ this->CurrentLine = 0;
+
+
+ yyscan_t yyscanner;
+ cmDependsJava_yylex_init(&yyscanner);
+ cmDependsJava_yyset_extra(this, yyscanner);
+ int res = cmDependsJava_yyparse(yyscanner);
+ cmDependsJava_yylex_destroy(yyscanner);
+ if ( res != 0 )
+ {
+ std::cout << "JP_Parse returned: " << res << std::endl;
+ return 0;
+ }
+
+ if ( verb )
+ {
+ if ( this->CurrentPackage.size() > 0 )
+ {
+ std::cout << "Current package is: " <<
+ this->CurrentPackage.c_str() << std::endl;
+ }
+ std::cout << "Imports packages:";
+ if ( this->PackagesImport.size() > 0 )
+ {
+ std::vector<cmStdString>::iterator it;
+ for ( it = this->PackagesImport.begin();
+ it != this->PackagesImport.end();
+ ++ it )
+ {
+ std::cout << " " << it->c_str();
+ }
+ }
+ std::cout << std::endl;
+ std::cout << "Depends on:";
+ if ( this->ClassesFound.size() > 0 )
+ {
+ std::vector<cmStdString>::iterator it;
+ for ( it = this->ClassesFound.begin();
+ it != this->ClassesFound.end();
+ ++ it )
+ {
+ std::cout << " " << it->c_str();
+ }
+ }
+ std::cout << std::endl;
+ std::cout << "Generated files:" << std::endl;
+ this->PrintClasses();
+ if ( this->UnionsAvailable != 0 )
+ {
+ std::cout << "There are still " <<
+ this->UnionsAvailable << " unions available" << std::endl;
+ }
+ }
+ this->CleanupParser();
+ return 1;
+}
+
+void cmDependsJavaParserHelper::CleanupParser()
+{
+ std::vector<char*>::iterator it;
+ for ( it = this->Allocates.begin();
+ it != this->Allocates.end();
+ ++ it )
+ {
+ delete [] *it;
+ }
+ this->Allocates.erase(this->Allocates.begin(),
+ this->Allocates.end());
+}
+
+int cmDependsJavaParserHelper::LexInput(char* buf, int maxlen)
+{
+ if ( maxlen < 1 )
+ {
+ return 0;
+ }
+ if ( this->InputBufferPos < this->InputBuffer.size() )
+ {
+ buf[0] = this->InputBuffer[ this->InputBufferPos++ ];
+ if ( buf[0] == '\n' )
+ {
+ this->CurrentLine ++;
+ }
+ return(1);
+ }
+ else
+ {
+ buf[0] = '\n';
+ return( 0 );
+ }
+}
+void cmDependsJavaParserHelper::Error(const char* str)
+{
+ unsigned long pos = static_cast<unsigned long>(this->InputBufferPos);
+ fprintf(stderr, "JPError: %s (%lu / Line: %d)\n",
+ str, pos, this->CurrentLine);
+ int cc;
+ std::cerr << "String: [";
+ for ( cc = 0;
+ cc < 30 && *(this->InputBuffer.c_str() + this->InputBufferPos + cc);
+ cc ++ )
+ {
+ std::cerr << *(this->InputBuffer.c_str() + this->InputBufferPos + cc);
+ }
+ std::cerr << "]" << std::endl;
+}
+
+void cmDependsJavaParserHelper::UpdateCombine(const char* str1,
+ const char* str2)
+{
+ if ( this->CurrentCombine == "" && str1 != 0)
+ {
+ this->CurrentCombine = str1;
+ }
+ this->CurrentCombine += ".";
+ this->CurrentCombine += str2;
+}
+
+int cmDependsJavaParserHelper::ParseFile(const char* file)
+{
+ if ( !cmSystemTools::FileExists(file))
+ {
+ return 0;
+ }
+ std::ifstream ifs(file);
+ if ( !ifs )
+ {
+ return 0;
+ }
+
+ cmStdString fullfile = "";
+ cmStdString line;
+ while ( cmSystemTools::GetLineFromStream(ifs, line) )
+ {
+ fullfile += line + "\n";
+ }
+ return this->ParseString(fullfile.c_str(), 0);
+}
+
diff --git a/Source/cmDependsJavaParserHelper.h b/Source/cmDependsJavaParserHelper.h
new file mode 100644
index 000000000..baecab378
--- /dev/null
+++ b/Source/cmDependsJavaParserHelper.h
@@ -0,0 +1,128 @@
+/*============================================================================
+ 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 cmDependsJavaParserHelper_h
+#define cmDependsJavaParserHelper_h
+
+#include "cmStandardIncludes.h"
+
+#define YYSTYPE cmDependsJavaParserHelper::ParserType
+#define YYSTYPE_IS_DECLARED
+#define YY_EXTRA_TYPE cmDependsJavaParserHelper*
+#define YY_DECL int cmDependsJava_yylex(YYSTYPE* yylvalp, yyscan_t yyscanner)
+
+/** \class cmDependsJavaParserHelper
+ * \brief Helper class for parsing java source files
+ *
+ * Finds dependencies for java file and list of outputs
+ */
+
+class cmDependsJavaParserHelper
+{
+public:
+ typedef struct {
+ char* str;
+ } ParserType;
+
+ cmDependsJavaParserHelper();
+ ~cmDependsJavaParserHelper();
+
+ int ParseString(const char* str, int verb);
+ int ParseFile(const char* file);
+
+ // For the lexer:
+ void AllocateParserType(cmDependsJavaParserHelper::ParserType* pt,
+ const char* str, int len = 0);
+
+ int LexInput(char* buf, int maxlen);
+ void Error(const char* str);
+
+ // For yacc
+ void AddClassFound(const char* sclass);
+ void PrepareElement(ParserType* opt);
+ void DeallocateParserType(char** pt);
+ void CheckEmpty(int line, int cnt, ParserType* pt);
+ void StartClass(const char* cls);
+ void EndClass();
+ void AddPackagesImport(const char* sclass);
+ void SetCurrentPackage(const char* pkg) { this->CurrentPackage = pkg; }
+ const char* GetCurrentPackage() { return this->CurrentPackage.c_str(); }
+ void SetCurrentCombine(const char* cmb) { this->CurrentCombine = cmb; }
+ 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<cmStdString> GetFilesProduced();
+
+private:
+ class CurrentClass
+ {
+ public:
+ cmStdString Name;
+ std::vector<CurrentClass>* NestedClasses;
+ CurrentClass()
+ {
+ this->NestedClasses = new std::vector<CurrentClass>;
+ }
+ ~CurrentClass()
+ {
+ delete this->NestedClasses;
+ }
+ CurrentClass& operator=(CurrentClass const& c)
+ {
+ this->NestedClasses->clear();
+ this->Name = c.Name;
+ std::copy(
+ c.NestedClasses->begin(),
+ c.NestedClasses->end(),
+ std::back_inserter(
+ *this->NestedClasses)
+ );
+ return *this;
+ }
+ CurrentClass(CurrentClass const& c)
+ {
+ (*this) = c;
+ }
+ void AddFileNamesForPrinting(std::vector<cmStdString> *files,
+ const char* prefix, const char* sep);
+ };
+ cmStdString CurrentPackage;
+ cmStdString::size_type InputBufferPos;
+ cmStdString InputBuffer;
+ std::vector<char> OutputBuffer;
+ std::vector<cmStdString> ClassesFound;
+ std::vector<cmStdString> PackagesImport;
+ cmStdString CurrentCombine;
+
+ std::vector<CurrentClass> ClassStack;
+
+ int CurrentLine;
+ int UnionsAvailable;
+ int LastClassId;
+ int CurrentDepth;
+ int Verbose;
+
+ std::vector<char*> Allocates;
+
+ void PrintClasses();
+
+ void Print(const char* place, const char* str);
+ void CombineUnions(char** out, const char* in1, char** in2,
+ const char* sep);
+ void SafePrintMissing(const char* str, int line, int cnt);
+
+ void CleanupParser();
+};
+
+#endif
+
diff --git a/Source/cmDependsJavaParserTokens.h b/Source/cmDependsJavaParserTokens.h
new file mode 100644
index 000000000..c7a414f07
--- /dev/null
+++ b/Source/cmDependsJavaParserTokens.h
@@ -0,0 +1,254 @@
+/* A Bison parser, made by GNU Bison 1.875d. */
+
+/* Skeleton parser for Yacc-like parsing with Bison, Copyright (C) 1984,
+ 1989, 1990, 2000, 2001, 2002, 2003, 2004 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 2, 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* As a special exception, when this file is copied by Bison into a
+ Bison output file, you may use that output file without restriction.
+ This special exception was added by the Free Software Foundation
+ in version 1.24 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 {
+ jp_ABSTRACT = 258,
+ jp_ASSERT = 259,
+ jp_BOOLEAN_TYPE = 260,
+ jp_BREAK = 261,
+ jp_BYTE_TYPE = 262,
+ jp_CASE = 263,
+ jp_CATCH = 264,
+ jp_CHAR_TYPE = 265,
+ jp_CLASS = 266,
+ jp_CONTINUE = 267,
+ jp_DEFAULT = 268,
+ jp_DO = 269,
+ jp_DOUBLE_TYPE = 270,
+ jp_ELSE = 271,
+ jp_EXTENDS = 272,
+ jp_FINAL = 273,
+ jp_FINALLY = 274,
+ jp_FLOAT_TYPE = 275,
+ jp_FOR = 276,
+ jp_IF = 277,
+ jp_IMPLEMENTS = 278,
+ jp_IMPORT = 279,
+ jp_INSTANCEOF = 280,
+ jp_INT_TYPE = 281,
+ jp_INTERFACE = 282,
+ jp_LONG_TYPE = 283,
+ jp_NATIVE = 284,
+ jp_NEW = 285,
+ jp_PACKAGE = 286,
+ jp_PRIVATE = 287,
+ jp_PROTECTED = 288,
+ jp_PUBLIC = 289,
+ jp_RETURN = 290,
+ jp_SHORT_TYPE = 291,
+ jp_STATIC = 292,
+ jp_STRICTFP = 293,
+ jp_SUPER = 294,
+ jp_SWITCH = 295,
+ jp_SYNCHRONIZED = 296,
+ jp_THIS = 297,
+ jp_THROW = 298,
+ jp_THROWS = 299,
+ jp_TRANSIENT = 300,
+ jp_TRY = 301,
+ jp_VOID = 302,
+ jp_VOLATILE = 303,
+ jp_WHILE = 304,
+ jp_BOOLEANLITERAL = 305,
+ jp_CHARACTERLITERAL = 306,
+ jp_DECIMALINTEGERLITERAL = 307,
+ jp_FLOATINGPOINTLITERAL = 308,
+ jp_HEXINTEGERLITERAL = 309,
+ jp_NULLLITERAL = 310,
+ jp_STRINGLITERAL = 311,
+ jp_NAME = 312,
+ jp_AND = 313,
+ jp_ANDAND = 314,
+ jp_ANDEQUALS = 315,
+ jp_BRACKETEND = 316,
+ jp_BRACKETSTART = 317,
+ jp_CARROT = 318,
+ jp_CARROTEQUALS = 319,
+ jp_COLON = 320,
+ jp_COMMA = 321,
+ jp_CURLYEND = 322,
+ jp_CURLYSTART = 323,
+ jp_DIVIDE = 324,
+ jp_DIVIDEEQUALS = 325,
+ jp_DOLLAR = 326,
+ jp_DOT = 327,
+ jp_EQUALS = 328,
+ jp_EQUALSEQUALS = 329,
+ jp_EXCLAMATION = 330,
+ jp_EXCLAMATIONEQUALS = 331,
+ jp_GREATER = 332,
+ jp_GTEQUALS = 333,
+ jp_GTGT = 334,
+ jp_GTGTEQUALS = 335,
+ jp_GTGTGT = 336,
+ jp_GTGTGTEQUALS = 337,
+ jp_LESLESEQUALS = 338,
+ jp_LESSTHAN = 339,
+ jp_LTEQUALS = 340,
+ jp_LTLT = 341,
+ jp_MINUS = 342,
+ jp_MINUSEQUALS = 343,
+ jp_MINUSMINUS = 344,
+ jp_PAREEND = 345,
+ jp_PARESTART = 346,
+ jp_PERCENT = 347,
+ jp_PERCENTEQUALS = 348,
+ jp_PIPE = 349,
+ jp_PIPEEQUALS = 350,
+ jp_PIPEPIPE = 351,
+ jp_PLUS = 352,
+ jp_PLUSEQUALS = 353,
+ jp_PLUSPLUS = 354,
+ jp_QUESTION = 355,
+ jp_SEMICOL = 356,
+ jp_TILDE = 357,
+ jp_TIMES = 358,
+ jp_TIMESEQUALS = 359,
+ jp_ERROR = 360
+ };
+#endif
+#define jp_ABSTRACT 258
+#define jp_ASSERT 259
+#define jp_BOOLEAN_TYPE 260
+#define jp_BREAK 261
+#define jp_BYTE_TYPE 262
+#define jp_CASE 263
+#define jp_CATCH 264
+#define jp_CHAR_TYPE 265
+#define jp_CLASS 266
+#define jp_CONTINUE 267
+#define jp_DEFAULT 268
+#define jp_DO 269
+#define jp_DOUBLE_TYPE 270
+#define jp_ELSE 271
+#define jp_EXTENDS 272
+#define jp_FINAL 273
+#define jp_FINALLY 274
+#define jp_FLOAT_TYPE 275
+#define jp_FOR 276
+#define jp_IF 277
+#define jp_IMPLEMENTS 278
+#define jp_IMPORT 279
+#define jp_INSTANCEOF 280
+#define jp_INT_TYPE 281
+#define jp_INTERFACE 282
+#define jp_LONG_TYPE 283
+#define jp_NATIVE 284
+#define jp_NEW 285
+#define jp_PACKAGE 286
+#define jp_PRIVATE 287
+#define jp_PROTECTED 288
+#define jp_PUBLIC 289
+#define jp_RETURN 290
+#define jp_SHORT_TYPE 291
+#define jp_STATIC 292
+#define jp_STRICTFP 293
+#define jp_SUPER 294
+#define jp_SWITCH 295
+#define jp_SYNCHRONIZED 296
+#define jp_THIS 297
+#define jp_THROW 298
+#define jp_THROWS 299
+#define jp_TRANSIENT 300
+#define jp_TRY 301
+#define jp_VOID 302
+#define jp_VOLATILE 303
+#define jp_WHILE 304
+#define jp_BOOLEANLITERAL 305
+#define jp_CHARACTERLITERAL 306
+#define jp_DECIMALINTEGERLITERAL 307
+#define jp_FLOATINGPOINTLITERAL 308
+#define jp_HEXINTEGERLITERAL 309
+#define jp_NULLLITERAL 310
+#define jp_STRINGLITERAL 311
+#define jp_NAME 312
+#define jp_AND 313
+#define jp_ANDAND 314
+#define jp_ANDEQUALS 315
+#define jp_BRACKETEND 316
+#define jp_BRACKETSTART 317
+#define jp_CARROT 318
+#define jp_CARROTEQUALS 319
+#define jp_COLON 320
+#define jp_COMMA 321
+#define jp_CURLYEND 322
+#define jp_CURLYSTART 323
+#define jp_DIVIDE 324
+#define jp_DIVIDEEQUALS 325
+#define jp_DOLLAR 326
+#define jp_DOT 327
+#define jp_EQUALS 328
+#define jp_EQUALSEQUALS 329
+#define jp_EXCLAMATION 330
+#define jp_EXCLAMATIONEQUALS 331
+#define jp_GREATER 332
+#define jp_GTEQUALS 333
+#define jp_GTGT 334
+#define jp_GTGTEQUALS 335
+#define jp_GTGTGT 336
+#define jp_GTGTGTEQUALS 337
+#define jp_LESLESEQUALS 338
+#define jp_LESSTHAN 339
+#define jp_LTEQUALS 340
+#define jp_LTLT 341
+#define jp_MINUS 342
+#define jp_MINUSEQUALS 343
+#define jp_MINUSMINUS 344
+#define jp_PAREEND 345
+#define jp_PARESTART 346
+#define jp_PERCENT 347
+#define jp_PERCENTEQUALS 348
+#define jp_PIPE 349
+#define jp_PIPEEQUALS 350
+#define jp_PIPEPIPE 351
+#define jp_PLUS 352
+#define jp_PLUSEQUALS 353
+#define jp_PLUSPLUS 354
+#define jp_QUESTION 355
+#define jp_SEMICOL 356
+#define jp_TILDE 357
+#define jp_TIMES 358
+#define jp_TIMESEQUALS 359
+#define jp_ERROR 360
+
+
+
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+typedef int YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+
+
diff --git a/Source/cmDocumentCompileDefinitions.h b/Source/cmDocumentCompileDefinitions.h
new file mode 100644
index 000000000..ef3b3e715
--- /dev/null
+++ b/Source/cmDocumentCompileDefinitions.h
@@ -0,0 +1,34 @@
+/*============================================================================
+ 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 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
new file mode 100644
index 000000000..535901397
--- /dev/null
+++ b/Source/cmDocumentGeneratorExpressions.h
@@ -0,0 +1,30 @@
+/*============================================================================
+ 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_COMMAND_GENERATOR_EXPRESSIONS \
+ "Generator expressions are evaluted during build system generation " \
+ "to produce information specific to each build configuration. " \
+ "Valid expressions are:\n" \
+ " $<CONFIGURATION> = configuration name\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"
+
+#endif
diff --git a/Source/cmDocumentLocationUndefined.h b/Source/cmDocumentLocationUndefined.h
new file mode 100644
index 000000000..d1be77abf
--- /dev/null
+++ b/Source/cmDocumentLocationUndefined.h
@@ -0,0 +1,24 @@
+/*============================================================================
+ 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>)?\" " \
+ "or \"(IMPLIB_)?(PREFIX|SUFFIX)\". " \
+ "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
new file mode 100644
index 000000000..77aaffcba
--- /dev/null
+++ b/Source/cmDocumentVariables.cxx
@@ -0,0 +1,1753 @@
+#include "cmDocumentVariables.h"
+#include "cmake.h"
+
+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 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 is 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 is 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 is 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_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, .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 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_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 parent listfile of the one currently being processed.",
+ "As CMake processes the listfiles in your project this "
+ "variable will always be set to the listfile that included "
+ "or somehow invoked the one currently being "
+ "processed. 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_USING_VC_FREE_TOOLS", cmProperty::VARIABLE,
+ "True if free visual studio tools being used.",
+ "This is set to true if the compiler is Visual "
+ "Studio free tools.",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 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, .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 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, .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");
+
+
+ // 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.",
+ "This specifies what build types 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.",
+ false,
+ "Variables That Change Behavior");
+
+ cm->DefineProperty
+ ("CMAKE_BUILD_TYPE", cmProperty::VARIABLE,
+ "Specifies the build type for make based generators.",
+ "This specifies what build type will be built in this tree. "
+ " Possible values are empty, Debug, Release, RelWithDebInfo"
+ " and MinSizeRel. This variable is only supported for "
+ "make based generators. If this variable is supported, "
+ "then CMake will also provide initial values for the "
+ "variables with the name "
+ " CMAKE_C_FLAGS_[DEBUG|RELEASE|RELWITHDEBINFO|MINSIZEREL]."
+ " For example, if CMAKE_BUILD_TYPE is Debug, then "
+ "CMAKE_C_FLAGS_DEBUG will be added to the CMAKE_C_FLAGS.",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 pre-pended onto all install "
+ "directories. This variable defaults to /usr/local"
+ " on UNIX and c:/Program Files on Windows.",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_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. 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 the 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 static 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 program or script 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 ones set 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 ones set this variable to ON while running the"
+ " script, it may get fatal error messages from the script.",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 OSX 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 OSX.",
+ "Set to true on Mac OSX.",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");
+
+ cm->DefineProperty
+ ("MSVC80", cmProperty::VARIABLE,
+ "True when using Microsoft Visual C 8.0",
+ "Set to true when the compiler is version 8.0 of Microsoft Visual C.",
+ 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"
+ "",
+ 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 OSXoperating systems.",
+ "Set to true when the host system is Apple OSX.",
+ 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");
+
+ // 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_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 OSX 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_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 used to create executables.",
+ "Flags used by the linker when creating an executable.",false,
+ "Variables that Control the Build");
+
+ cm->DefineProperty
+ ("CMAKE_EXE_LINKER_FLAGS_[CMAKE_BUILD_TYPE]", cmProperty::VARIABLE,
+ "Flag 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_LIBRARY_PATH_FLAG", cmProperty::VARIABLE,
+ "The flag used to add a library search path to a compiler.",
+ "The flag 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 used to specify a .def file for dll creation.",
+ "The flag 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 used to link a library into an executable.",
+ "The flag 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 used to link a library specified by a path to its file.",
+ "The flag 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 the 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_FLAGS", 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");
+
+// 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,
+ "An internal variable subject to change.",
+ "This is used in determining the compiler and is subject to change.",
+ 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,
+ "An internal variable subject to change.",
+ "Compiler version in major[.minor[.patch[.tweak]]] format. "
+ "This variable is reserved for internal use by CMake and is not "
+ "guaranteed to be set.",
+ 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.",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 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.", 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 and executable.",
+ "Rule variable to link and 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 languages 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",
+ 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_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
new file mode 100644
index 000000000..1d59b2450
--- /dev/null
+++ b/Source/cmDocumentVariables.h
@@ -0,0 +1,21 @@
+/*============================================================================
+ 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
new file mode 100644
index 000000000..1b042ae6f
--- /dev/null
+++ b/Source/cmDocumentation.cxx
@@ -0,0 +1,1978 @@
+/*============================================================================
+ 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 "cmDocumentation.h"
+
+#include "cmSystemTools.h"
+#include "cmVersion.h"
+#include <cmsys/Directory.hxx>
+#include <cmsys/Glob.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 "
+ "existance 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 "
+ "existance 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}
+};
+
+//----------------------------------------------------------------------------
+static const char *cmDocumentationGeneratorsHeader[][3] =
+{
+ {0,
+ "The following generators are available on this platform:", 0},
+ {0,0,0}
+};
+
+//----------------------------------------------------------------------------
+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,
+ "Summary of helpful links:\n"
+ " Home: http://www.cmake.org\n"
+ " Docs: http://www.cmake.org/HTML/Documentation.html\n"
+ " Mail: http://www.cmake.org/HTML/MailingLists.html\n"
+ " FAQ: http://www.cmake.org/Wiki/CMake_FAQ\n"
+ , 0},
+ {0,0,0}
+};
+
+//----------------------------------------------------------------------------
+static const char *cmDocumentationCopyright[][3] =
+{
+ {0,
+ "Copyright 2000-2009 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}
+};
+
+//----------------------------------------------------------------------------
+#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;
+}
+
+//----------------------------------------------------------------------------
+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;
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::PrintVersion(std::ostream& os)
+{
+ os << this->GetNameString() << " version "
+ << cmVersion::GetCMakeVersion() << "\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()
+{
+ 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;
+ 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);
+ case cmDocumentation::Version:
+ return true;
+ 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)
+{
+ bool result = true;
+
+ // Loop over requested documentation types.
+ for(std::vector<RequestedHelpItem>::const_iterator
+ i = this->RequestedHelpItems.begin();
+ 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;
+ std::ostream* s = &os;
+ std::string docname("");
+ if(i->Filename.length() > 0)
+ {
+ fout = new std::ofstream(i->Filename.c_str(), std::ios::out);
+ if(fout)
+ {
+ s = fout;
+ }
+ else
+ {
+ result = false;
+ }
+ if(i->Filename != "-")
+ {
+ docname = cmSystemTools::GetFilenameWithoutLastExtension(i->Filename);
+ }
+ }
+
+ // Print this documentation type to the stream.
+ if(!this->PrintDocumentation(i->HelpType, *s, docname.c_str()) || !*s)
+ {
+ result = false;
+ }
+
+ // Close the file if we wrote one.
+ if(fout)
+ {
+ delete fout;
+ }
+ }
+ return result;
+}
+
+#define GET_OPT_ARGUMENT(target) \
+ if((i+1 < argc) && !this->IsOption(argv[i+1])) \
+ { \
+ target = argv[i+1]; \
+ i = i+1; \
+ };
+
+
+cmDocumentation::Form cmDocumentation::GetFormFromFilename(
+ const std::string& filename,
+ int* manSection)
+{
+ std::string ext = cmSystemTools::GetFilenameLastExtension(filename);
+ ext = cmSystemTools::UpperCase(ext);
+ if ((ext == ".HTM") || (ext == ".HTML"))
+ {
+ return cmDocumentation::HTMLForm;
+ }
+
+ if (ext == ".DOCBOOK")
+ {
+ return cmDocumentation::DocbookForm;
+ }
+
+ // ".1" to ".9" should be manpages
+ if ((ext.length()==2) && (ext[1] >='1') && (ext[1]<='9'))
+ {
+ if (manSection)
+ {
+ *manSection = ext[1] - '0';
+ }
+ return cmDocumentation::ManForm;
+ }
+
+ return cmDocumentation::TextForm;
+}
+
+//----------------------------------------------------------------------------
+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;
+}
+
+//----------------------------------------------------------------------------
+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");
+
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::addCTestStandardDocSections()
+{
+ // This is currently done for backward compatibility reason
+ // We may suppress some of these.
+ addCMakeStandardDocSections();
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::addCPackStandardDocSections()
+{
+ cmDocumentationSection *sec;
+
+ 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;
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::CheckOptions(int argc, const char* const* argv,
+ const char* exitOpt)
+{
+ // Providing zero arguments gives usage information.
+ if(argc == 1)
+ {
+ RequestedHelpItem help;
+ help.HelpType = cmDocumentation::Usage;
+ help.HelpForm = cmDocumentation::UsageForm;
+ this->RequestedHelpItems.push_back(help);
+ return true;
+ }
+
+ // Search for supported help options.
+
+ bool result = false;
+ for(int i=1; i < argc; ++i)
+ {
+ if(exitOpt && strcmp(argv[i], exitOpt) == 0)
+ {
+ return result;
+ }
+ RequestedHelpItem help;
+ // Check if this is a supported help option.
+ if((strcmp(argv[i], "-help") == 0) ||
+ (strcmp(argv[i], "--help") == 0) ||
+ (strcmp(argv[i], "/?") == 0) ||
+ (strcmp(argv[i], "-usage") == 0) ||
+ (strcmp(argv[i], "-h") == 0) ||
+ (strcmp(argv[i], "-H") == 0))
+ {
+ help.HelpType = cmDocumentation::Usage;
+ help.HelpForm = cmDocumentation::UsageForm;
+ GET_OPT_ARGUMENT(help.Argument);
+ help.Argument = cmSystemTools::LowerCase(help.Argument);
+ // special case for single command
+ if (!help.Argument.empty())
+ {
+ help.HelpType = cmDocumentation::Single;
+ }
+ }
+ else if(strcmp(argv[i], "--help-properties") == 0)
+ {
+ help.HelpType = cmDocumentation::Properties;
+ GET_OPT_ARGUMENT(help.Filename);
+ help.HelpForm = this->GetFormFromFilename(help.Filename,
+ &help.ManSection);
+ }
+ else if(strcmp(argv[i], "--help-policies") == 0)
+ {
+ help.HelpType = cmDocumentation::Policies;
+ GET_OPT_ARGUMENT(help.Filename);
+ help.HelpForm = this->GetFormFromFilename(help.Filename,
+ &help.ManSection);
+ }
+ else if(strcmp(argv[i], "--help-variables") == 0)
+ {
+ help.HelpType = cmDocumentation::Variables;
+ GET_OPT_ARGUMENT(help.Filename);
+ help.HelpForm = this->GetFormFromFilename(help.Filename,
+ &help.ManSection);
+ }
+ else if(strcmp(argv[i], "--help-modules") == 0)
+ {
+ help.HelpType = cmDocumentation::Modules;
+ GET_OPT_ARGUMENT(help.Filename);
+ help.HelpForm = this->GetFormFromFilename(help.Filename,
+ &help.ManSection);
+ }
+ 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);
+ }
+ else if(strcmp(argv[i], "--help-commands") == 0)
+ {
+ help.HelpType = cmDocumentation::Commands;
+ GET_OPT_ARGUMENT(help.Filename);
+ help.HelpForm = this->GetFormFromFilename(help.Filename,
+ &help.ManSection);
+ }
+ 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);
+ }
+ 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);
+ }
+ else if(strcmp(argv[i], "--help-html") == 0)
+ {
+ help.HelpType = cmDocumentation::Full;
+ GET_OPT_ARGUMENT(help.Filename);
+ help.HelpForm = cmDocumentation::HTMLForm;
+ }
+ else if(strcmp(argv[i], "--help-man") == 0)
+ {
+ help.HelpType = cmDocumentation::Full;
+ GET_OPT_ARGUMENT(help.Filename);
+ help.HelpForm = cmDocumentation::ManForm;
+ help.ManSection = 1;
+ }
+ else if(strcmp(argv[i], "--help-command") == 0)
+ {
+ help.HelpType = cmDocumentation::Single;
+ GET_OPT_ARGUMENT(help.Argument);
+ GET_OPT_ARGUMENT(help.Filename);
+ help.Argument = cmSystemTools::LowerCase(help.Argument);
+ help.HelpForm = this->GetFormFromFilename(help.Filename,
+ &help.ManSection);
+ }
+ else if(strcmp(argv[i], "--help-module") == 0)
+ {
+ help.HelpType = cmDocumentation::SingleModule;
+ GET_OPT_ARGUMENT(help.Argument);
+ GET_OPT_ARGUMENT(help.Filename);
+ help.HelpForm = this->GetFormFromFilename(help.Filename,
+ &help.ManSection);
+ }
+ else if(strcmp(argv[i], "--help-property") == 0)
+ {
+ help.HelpType = cmDocumentation::SingleProperty;
+ GET_OPT_ARGUMENT(help.Argument);
+ GET_OPT_ARGUMENT(help.Filename);
+ help.HelpForm = this->GetFormFromFilename(help.Filename,
+ &help.ManSection);
+ }
+ else if(strcmp(argv[i], "--help-policy") == 0)
+ {
+ help.HelpType = cmDocumentation::SinglePolicy;
+ GET_OPT_ARGUMENT(help.Argument);
+ GET_OPT_ARGUMENT(help.Filename);
+ help.HelpForm = this->GetFormFromFilename(help.Filename,
+ &help.ManSection);
+ }
+ else if(strcmp(argv[i], "--help-variable") == 0)
+ {
+ help.HelpType = cmDocumentation::SingleVariable;
+ GET_OPT_ARGUMENT(help.Argument);
+ GET_OPT_ARGUMENT(help.Filename);
+ help.HelpForm = this->GetFormFromFilename(help.Filename,
+ &help.ManSection);
+ }
+ else if(strcmp(argv[i], "--help-command-list") == 0)
+ {
+ help.HelpType = cmDocumentation::List;
+ GET_OPT_ARGUMENT(help.Filename);
+ help.HelpForm = cmDocumentation::TextForm;
+ }
+ else if(strcmp(argv[i], "--help-module-list") == 0)
+ {
+ help.HelpType = cmDocumentation::ModuleList;
+ GET_OPT_ARGUMENT(help.Filename);
+ help.HelpForm = cmDocumentation::TextForm;
+ }
+ else if(strcmp(argv[i], "--help-property-list") == 0)
+ {
+ help.HelpType = cmDocumentation::PropertyList;
+ GET_OPT_ARGUMENT(help.Filename);
+ help.HelpForm = cmDocumentation::TextForm;
+ }
+ else if(strcmp(argv[i], "--help-variable-list") == 0)
+ {
+ help.HelpType = cmDocumentation::VariableList;
+ 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;
+ }
+ else if((strcmp(argv[i], "--version") == 0) ||
+ (strcmp(argv[i], "-version") == 0) ||
+ (strcmp(argv[i], "/V") == 0))
+ {
+ help.HelpType = cmDocumentation::Version;
+ GET_OPT_ARGUMENT(help.Filename);
+ help.HelpForm = cmDocumentation::UsageForm;
+ }
+ if(help.HelpType != None)
+ {
+ // This is a help option. See if there is a file name given.
+ result = true;
+ this->RequestedHelpItems.push_back(help);
+ }
+ }
+ return result;
+}
+
+//----------------------------------------------------------------------------
+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)
+{
+ this->NameString = name?name:"";
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::SetDocName(const char *docname)
+{
+ this->DocName = docname?docname:"";
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::SetSection(const char *name,
+ cmDocumentationSection *section)
+{
+ if (this->AllSections.find(name) != this->AllSections.end())
+ {
+ delete this->AllSections[name];
+ }
+ this->AllSections[name] = section;
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::SetSection(const char *name,
+ std::vector<cmDocumentationEntry> &docs)
+{
+ cmDocumentationSection *sec =
+ new cmDocumentationSection(name,
+ cmSystemTools::UpperCase(name).c_str());
+ sec->Append(docs);
+ this->SetSection(name,sec);
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::SetSection(const char *name,
+ const char *docs[][3])
+{
+ cmDocumentationSection *sec =
+ new cmDocumentationSection(name,
+ cmSystemTools::UpperCase(name).c_str());
+ sec->Append(docs);
+ this->SetSection(name,sec);
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation
+::SetSections(std::map<std::string,cmDocumentationSection *> &sections)
+{
+ for (std::map<std::string,cmDocumentationSection *>::const_iterator
+ it = sections.begin(); it != sections.end(); ++it)
+ {
+ this->SetSection(it->first.c_str(),it->second);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::PrependSection(const char *name,
+ const char *docs[][3])
+{
+ cmDocumentationSection *sec = 0;
+ if (this->AllSections.find(name) == this->AllSections.end())
+ {
+ sec = new cmDocumentationSection
+ (name, cmSystemTools::UpperCase(name).c_str());
+ this->SetSection(name,sec);
+ }
+ else
+ {
+ sec = this->AllSections[name];
+ }
+ sec->Prepend(docs);
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::PrependSection(const char *name,
+ std::vector<cmDocumentationEntry> &docs)
+{
+ cmDocumentationSection *sec = 0;
+ if (this->AllSections.find(name) == this->AllSections.end())
+ {
+ sec = new cmDocumentationSection
+ (name, cmSystemTools::UpperCase(name).c_str());
+ this->SetSection(name,sec);
+ }
+ else
+ {
+ sec = this->AllSections[name];
+ }
+ sec->Prepend(docs);
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::AppendSection(const char *name,
+ const char *docs[][3])
+{
+ cmDocumentationSection *sec = 0;
+ if (this->AllSections.find(name) == this->AllSections.end())
+ {
+ sec = new cmDocumentationSection
+ (name, cmSystemTools::UpperCase(name).c_str());
+ this->SetSection(name,sec);
+ }
+ else
+ {
+ sec = this->AllSections[name];
+ }
+ sec->Append(docs);
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::AppendSection(const char *name,
+ std::vector<cmDocumentationEntry> &docs)
+{
+ cmDocumentationSection *sec = 0;
+ if (this->AllSections.find(name) == this->AllSections.end())
+ {
+ sec = new cmDocumentationSection
+ (name, cmSystemTools::UpperCase(name).c_str());
+ this->SetSection(name,sec);
+ }
+ else
+ {
+ sec = this->AllSections[name];
+ }
+ sec->Append(docs);
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::AppendSection(const char *name,
+ cmDocumentationEntry &docs)
+{
+
+ std::vector<cmDocumentationEntry> docsVec;
+ docsVec.push_back(docs);
+ this->AppendSection(name,docsVec);
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::PrependSection(const char *name,
+ cmDocumentationEntry &docs)
+{
+
+ std::vector<cmDocumentationEntry> docsVec;
+ docsVec.push_back(docs);
+ this->PrependSection(name,docsVec);
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentation::SetSeeAlsoList(const char *data[][3])
+{
+ cmDocumentationSection *sec =
+ new cmDocumentationSection("See Also", "SEE ALSO");
+ this->AllSections["See Also"] = sec;
+ this->SeeAlsoString = ".B ";
+ int i = 0;
+ while(data[i][1])
+ {
+ this->SeeAlsoString += data[i][1];
+ this->SeeAlsoString += data[i+1][1]? "(1), ":"(1)";
+ ++i;
+ }
+ sec->Append(0,this->SeeAlsoString.c_str(),0);
+ sec->Append(cmDocumentationStandardSeeAlso);
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::PrintDocumentationGeneric(std::ostream& os,
+ const char *section)
+{
+ 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)
+ {
+ if(this->CurrentArgument == ei->Name)
+ {
+ this->PrintDocumentationCommand(os, *ei);
+ return true;
+ }
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::PrintDocumentationSingle(std::ostream& os)
+{
+ if (this->PrintDocumentationGeneric(os,"Commands"))
+ {
+ return true;
+ }
+ if (this->PrintDocumentationGeneric(os,"Compatibility Commands"))
+ {
+ return true;
+ }
+
+ // 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;
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::PrintDocumentationSingleModule(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;
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::PrintDocumentationSingleProperty(std::ostream& os)
+{
+ bool done = false;
+ for (std::vector<std::string>::iterator i =
+ this->PropertySections.begin();
+ !done && i != this->PropertySections.end(); ++i)
+ {
+ done = this->PrintDocumentationGeneric(os,i->c_str());
+ }
+
+ if (done)
+ {
+ 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";
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::PrintDocumentationSinglePolicy(std::ostream& os)
+{
+ if (this->PrintDocumentationGeneric(os,"Policies"))
+ {
+ return true;
+ }
+
+ // Argument was not a command. Complain.
+ os << "Argument \"" << this->CurrentArgument.c_str()
+ << "\" to --help-policy is not a CMake policy.\n";
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::PrintDocumentationSingleVariable(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());
+ }
+
+ if (done)
+ {
+ 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";
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::PrintDocumentationList(std::ostream& os,
+ const char *section)
+{
+ if(this->AllSections.find(section) == this->AllSections.end())
+ {
+ os << "Internal error: " << section << " list is empty." << std::endl;
+ return false;
+ }
+
+ const std::vector<cmDocumentationEntry> &entries =
+ this->AllSections[section]->GetEntries();
+ for(std::vector<cmDocumentationEntry>::const_iterator ei =
+ entries.begin();
+ ei != entries.end(); ++ei)
+ {
+ if(ei->Name.size())
+ {
+ os << ei->Name << std::endl;
+ }
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::PrintDocumentationUsage(std::ostream& os)
+{
+ this->ClearSections();
+ this->AddSectionToPrint("Usage");
+ this->AddSectionToPrint("Options");
+ if(this->ShowGenerators)
+ {
+ this->AddSectionToPrint("Generators");
+ }
+ this->Print(os);
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::PrintDocumentationFull(std::ostream& os)
+{
+ this->CreateFullDocumentation();
+ this->CurrentFormatter->PrintHeader(GetNameString(), GetNameString(), os);
+ this->Print(os);
+ this->CurrentFormatter->PrintFooter(os);
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::PrintDocumentationModules(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;
+}
+
+//----------------------------------------------------------------------------
+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;
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::PrintDocumentationPolicies(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);
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::PrintDocumentationProperties(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)
+ {
+ this->AddSectionToPrint(i->c_str());
+ }
+ 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)
+{
+ this->ClearSections();
+ this->AddDocumentIntroToPrint(GET_DOCUMENT_INTRO(Variables));
+ for (std::vector<std::string>::iterator i =
+ this->VariableSections.begin();
+ i != this->VariableSections.end(); ++i)
+ {
+ this->AddSectionToPrint(i->c_str());
+ }
+ 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::PrintDocumentationCurrentCommands(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);
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::PrintDocumentationCompatCommands(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);
+ 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()
+{
+ 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)
+ {
+ this->AddSectionToPrint(i->c_str());
+ emitted.insert(i->c_str());
+ }
+
+ 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)
+ {
+ if (emitted.find(i->first) == emitted.end())
+ {
+ this->AddSectionToPrint(i->first.c_str());
+ }
+ }
+
+ this->AddSectionToPrint("Copyright");
+
+ if(this->CurrentFormatter->GetForm() == ManForm)
+ {
+ this->AddSectionToPrint("See Also");
+ this->AddSectionToPrint("Author");
+ }
+ else
+ {
+ this->AddSectionToPrint("Standard See Also");
+ }
+}
+
+//----------------------------------------------------------------------------
+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)
+ {
+ return this->NameString.c_str();
+ }
+ else
+ {
+ return "CMake";
+ }
+}
+
+//----------------------------------------------------------------------------
+const char* cmDocumentation::GetDocName(bool fallbackToNameString) const
+{
+ if (this->DocName.length() > 0)
+ {
+ return this->DocName.c_str();
+ }
+ else if (fallbackToNameString)
+ {
+ return this->GetNameString();
+ }
+ else
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+#define CASE_DEFAULT_DOCNAME(doctype) \
+ case cmDocumentation::doctype : \
+ return GET_DOCUMENT_INTRO(doctype)[0];
+const char* cmDocumentation::GetDefaultDocName(Type ht) const
+{
+ switch (ht)
+ {
+ 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;
+ }
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::IsOption(const char* arg) const
+{
+ return ((arg[0] == '-') || (strcmp(arg, "/V") == 0) ||
+ (strcmp(arg, "/?") == 0));
+}
diff --git a/Source/cmDocumentation.h b/Source/cmDocumentation.h
new file mode 100644
index 000000000..e180f60f5
--- /dev/null
+++ b/Source/cmDocumentation.h
@@ -0,0 +1,271 @@
+/*============================================================================
+ 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 _cmDocumentation_h
+#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"
+
+namespace cmsys
+{
+ class Directory;
+}
+
+/** Class to generate documentation. */
+class cmDocumentation: public cmDocumentationEnums
+{
+public:
+ cmDocumentation();
+
+ ~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
+ * called. exitOpt can be used for things like cmake -E, so that
+ * all arguments after the -E are ignored and not searched for
+ * help arguments.
+ */
+ bool CheckOptions(int argc, const char* const* argv,
+ const char* exitOpt =0);
+
+ /**
+ * Print help requested on the command line. Call after
+ * CheckOptions returns true. Returns true on success, and false
+ * otherwise. Failure can occur when output files specified on the
+ * command line cannot be written.
+ */
+ bool PrintRequestedDocumentation(std::ostream& os);
+
+ /** Print help of the given type. */
+ bool PrintDocumentation(Type ht, std::ostream& os, const char* docname=0);
+
+ void SetShowGenerators(bool showGen) { this->ShowGenerators = showGen; }
+
+ /** Set the program name for standard document generation. */
+ void SetName(const char* name);
+
+ /** Set a section of the documentation. Typical sections include Name,
+ Usage, Description, Options, SeeAlso */
+ 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]);
+ 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]);
+ 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]);
+ 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();
+
+ /** Add the CMake standard documentation section(s) */
+ void addCMakeStandardDocSections();
+
+ /** Add the CTest standard documentation section(s) */
+ void addCTestStandardDocSections();
+
+ /** 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]);
+
+ 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);
+
+
+ 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;
+ 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;
+
+ std::vector<std::string> PropertySections;
+ std::vector<std::string> VariableSections;
+};
+
+#endif
diff --git a/Source/cmDocumentationFormatter.cxx b/Source/cmDocumentationFormatter.cxx
new file mode 100644
index 000000000..6762d6677
--- /dev/null
+++ b/Source/cmDocumentationFormatter.cxx
@@ -0,0 +1,156 @@
+/*============================================================================
+ 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 "cmDocumentationFormatter.h"
+
+cmDocumentationFormatter::cmDocumentationFormatter()
+{
+}
+
+cmDocumentationFormatter::~cmDocumentationFormatter()
+{
+}
+
+void cmDocumentationFormatter::PrintFormatted(std::ostream& os,
+ const char* text)
+{
+ if(!text)
+ {
+ return;
+ }
+ const char* ptr = text;
+ while(*ptr)
+ {
+ // Any ptrs starting in a space are treated as preformatted text.
+ std::string preformatted;
+ while(*ptr == ' ')
+ {
+ for(char ch = *ptr; ch && ch != '\n'; ++ptr, ch = *ptr)
+ {
+ preformatted.append(1, ch);
+ }
+ if(*ptr)
+ {
+ ++ptr;
+ preformatted.append(1, '\n');
+ }
+ }
+ if(preformatted.length())
+ {
+ this->PrintPreformatted(os, preformatted.c_str());
+ }
+
+ // Other ptrs are treated as paragraphs.
+ std::string paragraph;
+ for(char ch = *ptr; ch && ch != '\n'; ++ptr, ch = *ptr)
+ {
+ paragraph.append(1, ch);
+ }
+ if(*ptr)
+ {
+ ++ptr;
+ paragraph.append(1, '\n');
+ }
+ if(paragraph.length())
+ {
+ this->PrintParagraph(os, paragraph.c_str());
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmDocumentationFormatter::ComputeSectionLinkPrefix(std::string const& name)
+{
+ // 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)
+ {
+ if(name.find("Global") != name.npos)
+ {
+ return "prop_global";
+ }
+ else if(name.find("Direct") != name.npos)
+ {
+ return "prop_dir";
+ }
+ else if(name.find("Target") != name.npos)
+ {
+ return "prop_tgt";
+ }
+ else if(name.find("Test") != name.npos)
+ {
+ return "prop_test";
+ }
+ else if(name.find("Source") != name.npos)
+ {
+ return "prop_sf";
+ }
+ 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";
+ }
+ else
+ {
+ std::cerr
+ << "WARNING: ComputeSectionLinkPrefix failed for \"" << name << "\""
+ << std::endl;
+ return "other";
+ }
+}
diff --git a/Source/cmDocumentationFormatter.h b/Source/cmDocumentationFormatter.h
new file mode 100644
index 000000000..665b9b61a
--- /dev/null
+++ b/Source/cmDocumentationFormatter.h
@@ -0,0 +1,67 @@
+/*============================================================================
+ 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 _cmDocumentationFormatter_h
+#define _cmDocumentationFormatter_h
+
+#include "cmStandardIncludes.h"
+
+/** This is just a helper class to make it build with MSVC 6.0.
+Actually the enums and internal classes could directly go into
+cmDocumentation, but then MSVC6 complains in RequestedHelpItem that
+cmDocumentation is an undefined type and so it doesn't know the enums.
+Moving the enums to a class which is then already completely parsed helps
+against this. */
+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 };
+};
+
+class cmDocumentationSection;
+
+/** Base class for printing the documentation in the various supported
+ formats. */
+class cmDocumentationFormatter
+{
+public:
+ cmDocumentationFormatter();
+ 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);
+};
+
+#endif
diff --git a/Source/cmDocumentationFormatterDocbook.cxx b/Source/cmDocumentationFormatterDocbook.cxx
new file mode 100644
index 000000000..30873306d
--- /dev/null
+++ b/Source/cmDocumentationFormatterDocbook.cxx
@@ -0,0 +1,255 @@
+/*============================================================================
+ 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"
+//----------------------------------------------------------------------------
+
+// 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)
+{
+ if(name)
+ {
+ std::string id = "section_";
+ id += name;
+ if (this->EmittedLinkIds.find(id) == this->EmittedLinkIds.end())
+ {
+ this->EmittedLinkIds.insert(id);
+ os << "<sect1 id=\"section_" << name << "\">\n"
+ "<title>\n" << name << "</title>\n";
+ }
+ else
+ {
+ static unsigned int i=0;
+ i++;
+ os << "<sect1 id=\"section_" << name << i << "\">\n"
+ "<title>\n" << name << "</title>\n";
+ }
+ }
+
+ std::string prefix = this->ComputeSectionLinkPrefix(name);
+
+ const std::vector<cmDocumentationEntry> &entries =
+ section.GetEntries();
+
+ if (!entries.empty())
+ {
+ os << "<itemizedlist>\n";
+ for(std::vector<cmDocumentationEntry>::const_iterator op
+ = entries.begin(); op != entries.end(); ++ op )
+ {
+ if(op->Name.size())
+ {
+ os << " <listitem><link linkend=\"" << prefix << "_";
+ cmDocumentationPrintDocbookEscapes(os, op->Name.c_str());
+ os << "\"><emphasis><literal>";
+ cmDocumentationPrintDocbookEscapes(os, op->Name.c_str());
+ os << "</literal></emphasis></link></listitem>\n";
+ }
+ }
+ os << "</itemizedlist>\n" ;
+ }
+
+ for(std::vector<cmDocumentationEntry>::const_iterator op = entries.begin();
+ op != entries.end();)
+ {
+ if(op->Name.size())
+ {
+ for(;op != entries.end() && op->Name.size(); ++op)
+ {
+ if(op->Name.size())
+ {
+ os << " <para id=\"" << prefix << "_";
+ cmDocumentationPrintDocbookEscapes(os, op->Name.c_str());
+
+ // 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
+ std::string id = prefix;
+ id += "_";
+ id += op->Name;
+ if (this->EmittedLinkIds.find(id) == this->EmittedLinkIds.end())
+ {
+ this->EmittedLinkIds.insert(id);
+ }
+ else
+ {
+ static unsigned int i=0;
+ i++;
+ os << i;
+ }
+ // continue as normal...
+
+ os << "\"><sect2><title>";
+ cmDocumentationPrintDocbookEscapes(os, op->Name.c_str());
+ os << "</title></sect2> ";
+ }
+ cmDocumentationPrintDocbookEscapes(os, op->Brief.c_str());
+ if(op->Name.size())
+ {
+ os << "</para>\n";
+ }
+
+ if(op->Full.size())
+ {
+ // a line break seems to be simply a line break with docbook
+ os << "\n ";
+ this->PrintFormatted(os, op->Full.c_str());
+ }
+ os << "\n";
+ }
+ }
+ else
+ {
+ this->PrintFormatted(os, op->Brief.c_str());
+ os << "\n";
+ ++op;
+ }
+ }
+ if(name)
+ {
+ os << "</sect1>\n";
+ }
+}
+
+void cmDocumentationFormatterDocbook::PrintPreformatted(std::ostream& os,
+ const char* text)
+{
+ os << "<literallayout>";
+ cmDocumentationPrintDocbookEscapes(os, text);
+ os << "</literallayout>\n ";
+}
+
+void cmDocumentationFormatterDocbook::PrintParagraph(std::ostream& os,
+ const char* text)
+{
+ os << "<para>";
+ cmDocumentationPrintDocbookEscapes(os, text);
+ os << "</para>";
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentationFormatterDocbook::PrintHeader(const char* docname,
+ const char* appname,
+ std::ostream& os)
+{
+ // 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.2//EN\" "
+ "\"http://www.oasis-open.org/docbook/xml/4.2/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";
+}
+
diff --git a/Source/cmDocumentationFormatterDocbook.h b/Source/cmDocumentationFormatterDocbook.h
new file mode 100644
index 000000000..213948dcc
--- /dev/null
+++ b/Source/cmDocumentationFormatterDocbook.h
@@ -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.
+============================================================================*/
+#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:
+ std::set<std::string> EmittedLinkIds;
+};
+
+#endif
diff --git a/Source/cmDocumentationFormatterHTML.cxx b/Source/cmDocumentationFormatterHTML.cxx
new file mode 100644
index 000000000..cd0077ed9
--- /dev/null
+++ b/Source/cmDocumentationFormatterHTML.cxx
@@ -0,0 +1,288 @@
+/*============================================================================
+ 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
new file mode 100644
index 000000000..427e04bc5
--- /dev/null
+++ b/Source/cmDocumentationFormatterHTML.h
@@ -0,0 +1,42 @@
+/*============================================================================
+ 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
new file mode 100644
index 000000000..4123c85cb
--- /dev/null
+++ b/Source/cmDocumentationFormatterMan.cxx
@@ -0,0 +1,102 @@
+/*============================================================================
+ 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
new file mode 100644
index 000000000..b3d069c36
--- /dev/null
+++ b/Source/cmDocumentationFormatterMan.h
@@ -0,0 +1,43 @@
+/*============================================================================
+ 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
new file mode 100644
index 000000000..0b04b73d2
--- /dev/null
+++ b/Source/cmDocumentationFormatterText.cxx
@@ -0,0 +1,180 @@
+/*============================================================================
+ 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
new file mode 100644
index 000000000..d9c2af297
--- /dev/null
+++ b/Source/cmDocumentationFormatterText.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 _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
new file mode 100644
index 000000000..8a415cb4d
--- /dev/null
+++ b/Source/cmDocumentationFormatterUsage.cxx
@@ -0,0 +1,63 @@
+/*============================================================================
+ 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
new file mode 100644
index 000000000..3ed3442cb
--- /dev/null
+++ b/Source/cmDocumentationFormatterUsage.h
@@ -0,0 +1,31 @@
+/*============================================================================
+ 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
new file mode 100644
index 000000000..a2dfe70d0
--- /dev/null
+++ b/Source/cmDocumentationSection.cxx
@@ -0,0 +1,81 @@
+/*============================================================================
+ 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 "cmDocumentationSection.h"
+
+
+//----------------------------------------------------------------------------
+void cmDocumentationSection::Append(const char *data[][3])
+{
+ int i = 0;
+ while(data[i][1])
+ {
+ this->Entries.push_back(cmDocumentationEntry(data[i][0],
+ data[i][1],
+ data[i][2]));
+ data += 1;
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentationSection::Prepend(const char *data[][3])
+{
+ 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 += 1;
+ }
+ this->Entries.insert(this->Entries.begin(),tmp.begin(),tmp.end());
+}
+
+//----------------------------------------------------------------------------
+void cmDocumentationSection::Append(const char *n, const char *b,
+ const char *f)
+{
+ this->Entries.push_back(cmDocumentationEntry(n,b,f));
+}
+
+#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
new file mode 100644
index 000000000..0fab38f81
--- /dev/null
+++ b/Source/cmDocumentationSection.h
@@ -0,0 +1,68 @@
+/*============================================================================
+ 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 _cmDocumentationSection_h
+#define _cmDocumentationSection_h
+
+#include "cmStandardIncludes.h"
+#include "cmDocumentationFormatter.h"
+
+// Low-level interface for custom documents:
+/** Internal class representing a section of the documentation.
+ * Cares e.g. for the different section titles in the different
+ * output formats.
+ */
+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) {}
+
+ /** Has any content been added to this section or is it empty ? */
+ bool IsEmpty() const { return this->Entries.empty(); }
+
+ /** 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 a pointer to the first entry of this section. */
+ const std::vector<cmDocumentationEntry> &GetEntries() const
+ { return this->Entries; }
+
+ /** Append an entry to this section. */
+ void Append(const cmDocumentationEntry& entry)
+ { this->Entries.push_back(entry); }
+ void Append(const std::vector<cmDocumentationEntry> &entries)
+ { 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);
+
+ /** prepend some documentation to this section */
+ void Prepend(const char *[][3]);
+ void Prepend(const std::vector<cmDocumentationEntry> &entries)
+ { this->Entries.insert(this->Entries.begin(),
+ entries.begin(),entries.end()); }
+
+
+private:
+ std::string Name;
+ std::string ManName;
+ std::vector<cmDocumentationEntry> Entries;
+};
+
+#endif
diff --git a/Source/cmDynamicLoader.cxx b/Source/cmDynamicLoader.cxx
new file mode 100644
index 000000000..6a0ab7b1b
--- /dev/null
+++ b/Source/cmDynamicLoader.cxx
@@ -0,0 +1,112 @@
+/*============================================================================
+ 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 "cmDynamicLoader.h"
+
+class cmDynamicLoaderCache
+{
+public:
+ ~cmDynamicLoaderCache();
+ void CacheFile(const char* path,
+ const cmsys::DynamicLoader::LibraryHandle&);
+ bool GetCacheFile(const char* path, cmsys::DynamicLoader::LibraryHandle&);
+ bool FlushCache(const char* path);
+ void FlushCache();
+ static cmDynamicLoaderCache* GetInstance();
+
+private:
+ std::map<cmStdString, cmsys::DynamicLoader::LibraryHandle> CacheMap;
+ static cmDynamicLoaderCache* Instance;
+};
+
+cmDynamicLoaderCache* cmDynamicLoaderCache::Instance = 0;
+
+cmDynamicLoaderCache::~cmDynamicLoaderCache()
+{
+}
+
+void cmDynamicLoaderCache::CacheFile(const char* path,
+ const cmsys::DynamicLoader::LibraryHandle& p)
+{
+ cmsys::DynamicLoader::LibraryHandle h;
+ if ( this->GetCacheFile(path, h) )
+ {
+ this->FlushCache(path);
+ }
+ this->CacheMap[path] = p;
+}
+
+bool cmDynamicLoaderCache::GetCacheFile(const char* path,
+ cmsys::DynamicLoader::LibraryHandle& p)
+{
+ std::map<cmStdString, cmsys::DynamicLoader::LibraryHandle>::iterator it
+ = this->CacheMap.find(path);
+ if ( it != this->CacheMap.end() )
+ {
+ p = it->second;
+ return true;
+ }
+ return false;
+}
+
+bool cmDynamicLoaderCache::FlushCache(const char* path)
+{
+ std::map<cmStdString, cmsys::DynamicLoader::LibraryHandle>::iterator it
+ = this->CacheMap.find(path);
+ bool ret = false;
+ if ( it != this->CacheMap.end() )
+ {
+ cmsys::DynamicLoader::CloseLibrary(it->second);
+ this->CacheMap.erase(it);
+ ret = true;
+ }
+ return ret;
+}
+
+void cmDynamicLoaderCache::FlushCache()
+{
+ for ( std::map<cmStdString,
+ cmsys::DynamicLoader::LibraryHandle>::iterator it
+ = this->CacheMap.begin();
+ it != this->CacheMap.end(); it++ )
+ {
+ cmsys::DynamicLoader::CloseLibrary(it->second);
+ }
+ delete cmDynamicLoaderCache::Instance;
+ cmDynamicLoaderCache::Instance = 0;
+}
+
+cmDynamicLoaderCache* cmDynamicLoaderCache::GetInstance()
+{
+ if ( !cmDynamicLoaderCache::Instance )
+ {
+ cmDynamicLoaderCache::Instance = new cmDynamicLoaderCache;
+ }
+ return cmDynamicLoaderCache::Instance;
+}
+
+cmsys::DynamicLoader::LibraryHandle cmDynamicLoader::OpenLibrary(
+ const char* libname )
+{
+ cmsys::DynamicLoader::LibraryHandle lh;
+ if ( cmDynamicLoaderCache::GetInstance()->GetCacheFile(libname, lh) )
+ {
+ return lh;
+ }
+ lh = cmsys::DynamicLoader::OpenLibrary(libname);
+ cmDynamicLoaderCache::GetInstance()->CacheFile(libname, lh);
+ return lh;
+}
+
+void cmDynamicLoader::FlushCache()
+{
+ cmDynamicLoaderCache::GetInstance()->FlushCache();
+}
diff --git a/Source/cmDynamicLoader.h b/Source/cmDynamicLoader.h
new file mode 100644
index 000000000..acf8011f2
--- /dev/null
+++ b/Source/cmDynamicLoader.h
@@ -0,0 +1,47 @@
+/*============================================================================
+ 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.
+============================================================================*/
+// .NAME cmDynamicLoader - class interface to system dynamic libraries
+// .SECTION Description
+// cmDynamicLoader provides a portable interface to loading dynamic
+// libraries into a process.
+
+
+#ifndef __cmDynamicLoader_h
+#define __cmDynamicLoader_h
+
+#include "cmStandardIncludes.h"
+
+#include <cmsys/DynamicLoader.hxx>
+
+class cmDynamicLoader
+{
+public:
+ // Description:
+ // Load a dynamic library into the current process.
+ // The returned cmsys::DynamicLoader::LibraryHandle can be used to access
+ // the symbols in the library.
+ static cmsys::DynamicLoader::LibraryHandle OpenLibrary(const char*);
+
+ // Description:
+ // Flush the cache of dynamic loader.
+ static void FlushCache();
+
+protected:
+ cmDynamicLoader() {};
+ ~cmDynamicLoader() {};
+
+private:
+ cmDynamicLoader(const cmDynamicLoader&); // Not implemented.
+ void operator=(const cmDynamicLoader&); // Not implemented.
+};
+
+#endif
diff --git a/Source/cmELF.cxx b/Source/cmELF.cxx
new file mode 100644
index 000000000..1158fc0c0
--- /dev/null
+++ b/Source/cmELF.cxx
@@ -0,0 +1,920 @@
+/*============================================================================
+ 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_ELF_PARSER first
+#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 the ELF format information system header.
+#include <elf.h>
+#if defined(__sun)
+# include <sys/link.h> // For dynamic section information
+#endif
+
+//----------------------------------------------------------------------------
+// Low-level byte swapping implementation.
+template <size_t s> struct cmELFByteSwapSize {};
+void cmELFByteSwap(char*, cmELFByteSwapSize<1> const&)
+{
+}
+void cmELFByteSwap(char* data, cmELFByteSwapSize<2> const&)
+{
+ char one_byte;
+ one_byte = data[0]; data[0] = data[1]; data[1] = one_byte;
+}
+void cmELFByteSwap(char* data, cmELFByteSwapSize<4> const&)
+{
+ char one_byte;
+ one_byte = data[0]; data[0] = data[3]; data[3] = one_byte;
+ one_byte = data[1]; data[1] = data[2]; data[2] = one_byte;
+}
+void cmELFByteSwap(char* data, cmELFByteSwapSize<8> const&)
+{
+ char one_byte;
+ one_byte = data[0]; data[0] = data[7]; data[7] = one_byte;
+ one_byte = data[1]; data[1] = data[6]; data[6] = one_byte;
+ one_byte = data[2]; data[2] = data[5]; data[5] = one_byte;
+ one_byte = data[3]; data[3] = data[4]; data[4] = one_byte;
+}
+
+// Low-level byte swapping interface.
+template <typename T>
+void cmELFByteSwap(T& x)
+{
+ cmELFByteSwap(reinterpret_cast<char*>(&x), cmELFByteSwapSize<sizeof(T)>());
+}
+
+//----------------------------------------------------------------------------
+class cmELFInternal
+{
+public:
+ typedef cmELF::StringEntry StringEntry;
+ enum ByteOrderType { ByteOrderMSB, ByteOrderLSB };
+
+ // Construct and take ownership of the file stream object.
+ cmELFInternal(cmELF* external,
+ cmsys::auto_ptr<std::ifstream>& fin,
+ ByteOrderType order):
+ External(external),
+ Stream(*fin.release()),
+ ByteOrder(order),
+ ELFType(cmELF::FileTypeInvalid)
+ {
+ // 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
+ this->NeedSwap = (this->ByteOrder == ByteOrderMSB);
+#elif cmsys_CPU_ENDIAN_ID == cmsys_CPU_ENDIAN_ID_BIG
+ this->NeedSwap = (this->ByteOrder == ByteOrderLSB);
+#else
+ this->NeedSwap = false; // Final decision is at runtime anyway.
+#endif
+
+ // We have not yet loaded the section info.
+ this->DynamicSectionIndex = -1;
+ }
+
+ // Destruct and delete the file stream object.
+ virtual ~cmELFInternal()
+ {
+ delete &this->Stream;
+ }
+
+ // Forward to the per-class implementation.
+ 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 void PrintInfo(std::ostream& os) const = 0;
+
+ bool ReadBytes(unsigned long pos, unsigned long size, char* buf)
+ {
+ this->Stream.seekg(pos);
+ this->Stream.read(buf, size);
+ return this->Stream?true:false;
+ }
+
+ // Lookup the SONAME in the DYNAMIC section.
+ StringEntry const* GetSOName()
+ {
+ return this->GetDynamicSectionString(DT_SONAME);
+ }
+
+ // Lookup the RPATH in the DYNAMIC section.
+ StringEntry const* GetRPath()
+ {
+ return this->GetDynamicSectionString(DT_RPATH);
+ }
+
+ // Lookup the RUNPATH in the DYNAMIC section.
+ StringEntry const* GetRunPath()
+ {
+#if defined(DT_RUNPATH)
+ return this->GetDynamicSectionString(DT_RUNPATH);
+#else
+ return 0;
+#endif
+ }
+
+ // Return the recorded ELF type.
+ cmELF::FileType GetFileType() const { return this->ELFType; }
+protected:
+ // Data common to all ELF class implementations.
+
+ // The external cmELF object.
+ cmELF* External;
+
+ // The stream from which to read.
+ std::istream& Stream;
+
+ // The byte order of the ELF file.
+ ByteOrderType ByteOrder;
+
+ // The ELF file type.
+ cmELF::FileType ELFType;
+
+ // Whether we need to byte-swap structures read from the stream.
+ bool NeedSwap;
+
+ // The section header index of the DYNAMIC section (-1 if none).
+ int DynamicSectionIndex;
+
+ // Helper methods for subclasses.
+ void SetErrorMessage(const char* msg)
+ {
+ this->External->ErrorMessage = msg;
+ this->ELFType = cmELF::FileTypeInvalid;
+ }
+
+ // Store string table entry states.
+ std::map<int, StringEntry> DynamicSectionStrings;
+};
+
+//----------------------------------------------------------------------------
+// Configure the implementation template for 32-bit ELF files.
+struct cmELFTypes32
+{
+ typedef Elf32_Ehdr ELF_Ehdr;
+ typedef Elf32_Shdr ELF_Shdr;
+ typedef Elf32_Dyn ELF_Dyn;
+ typedef Elf32_Half ELF_Half;
+ static const char* GetName() { return "32-bit"; }
+};
+
+// Configure the implementation template for 32-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;
+ static const char* GetName() { return "64-bit"; }
+};
+
+//----------------------------------------------------------------------------
+// Parser implementation template.
+template <class Types>
+class cmELFInternalImpl: public cmELFInternal
+{
+public:
+ // Copy the ELF file format types from our configuration parameter.
+ typedef typename Types::ELF_Ehdr ELF_Ehdr;
+ typedef typename Types::ELF_Shdr ELF_Shdr;
+ typedef typename Types::ELF_Dyn ELF_Dyn;
+ typedef typename Types::ELF_Half ELF_Half;
+
+ // Construct with a stream and byte swap indicator.
+ cmELFInternalImpl(cmELF* external,
+ cmsys::auto_ptr<std::ifstream>& fin,
+ ByteOrderType order);
+
+ // Return the number of sections as specified by the ELF header.
+ virtual unsigned int GetNumberOfSections() const
+ {
+ return static_cast<unsigned int>(this->ELFHeader.e_shnum);
+ }
+
+ // Get the file position and size of a dynamic section entry.
+ virtual unsigned int GetDynamicEntryCount();
+ virtual unsigned long GetDynamicEntryPosition(int j);
+
+ // Lookup a string from the dynamic section with the given tag.
+ virtual StringEntry const* GetDynamicSectionString(int tag);
+
+ // Print information about the ELF file.
+ virtual void PrintInfo(std::ostream& os) const
+ {
+ os << "ELF " << Types::GetName();
+ if(this->ByteOrder == ByteOrderMSB)
+ {
+ os << " MSB";
+ }
+ else if(this->ByteOrder == ByteOrderLSB)
+ {
+ os << " LSB";
+ }
+ switch(this->ELFType)
+ {
+ case cmELF::FileTypeInvalid:
+ os << " invalid file";
+ break;
+ case cmELF::FileTypeRelocatableObject:
+ os << " relocatable object";
+ break;
+ case cmELF::FileTypeExecutable:
+ os << " executable";
+ break;
+ case cmELF::FileTypeSharedLibrary:
+ os << " shared library";
+ break;
+ case cmELF::FileTypeCore:
+ os << " core file";
+ break;
+ case cmELF::FileTypeSpecificOS:
+ os << " os-specific type";
+ break;
+ case cmELF::FileTypeSpecificProc:
+ os << " processor-specific type";
+ break;
+ }
+ os << "\n";
+ }
+
+private:
+ void ByteSwap(ELF_Ehdr& elf_header)
+ {
+ cmELFByteSwap(elf_header.e_type);
+ cmELFByteSwap(elf_header.e_machine);
+ cmELFByteSwap(elf_header.e_version);
+ cmELFByteSwap(elf_header.e_entry);
+ cmELFByteSwap(elf_header.e_phoff);
+ cmELFByteSwap(elf_header.e_shoff);
+ cmELFByteSwap(elf_header.e_flags);
+ cmELFByteSwap(elf_header.e_ehsize);
+ cmELFByteSwap(elf_header.e_phentsize);
+ cmELFByteSwap(elf_header.e_phnum);
+ cmELFByteSwap(elf_header.e_shentsize);
+ cmELFByteSwap(elf_header.e_shnum);
+ cmELFByteSwap(elf_header.e_shstrndx);
+ }
+
+ void ByteSwap(ELF_Shdr& sec_header)
+ {
+ cmELFByteSwap(sec_header.sh_name);
+ cmELFByteSwap(sec_header.sh_type);
+ cmELFByteSwap(sec_header.sh_flags);
+ cmELFByteSwap(sec_header.sh_addr);
+ cmELFByteSwap(sec_header.sh_offset);
+ cmELFByteSwap(sec_header.sh_size);
+ cmELFByteSwap(sec_header.sh_link);
+ cmELFByteSwap(sec_header.sh_info);
+ cmELFByteSwap(sec_header.sh_addralign);
+ cmELFByteSwap(sec_header.sh_entsize);
+ }
+
+ void ByteSwap(ELF_Dyn& dyn)
+ {
+ cmELFByteSwap(dyn.d_tag);
+ switch (dyn.d_tag)
+ {
+ case DT_NULL: /* dyn.d_un ignored */ break;
+ case DT_NEEDED: cmELFByteSwap(dyn.d_un.d_val); break;
+ case DT_PLTRELSZ: cmELFByteSwap(dyn.d_un.d_val); break;
+ case DT_PLTGOT: cmELFByteSwap(dyn.d_un.d_ptr); break;
+ case DT_HASH: cmELFByteSwap(dyn.d_un.d_ptr); break;
+ case DT_STRTAB: cmELFByteSwap(dyn.d_un.d_ptr); break;
+ case DT_SYMTAB: cmELFByteSwap(dyn.d_un.d_ptr); break;
+ case DT_RELA: cmELFByteSwap(dyn.d_un.d_ptr); break;
+ case DT_RELASZ: cmELFByteSwap(dyn.d_un.d_val); break;
+ case DT_RELAENT: cmELFByteSwap(dyn.d_un.d_val); break;
+ case DT_STRSZ: cmELFByteSwap(dyn.d_un.d_val); break;
+ case DT_SYMENT: cmELFByteSwap(dyn.d_un.d_val); break;
+ case DT_INIT: cmELFByteSwap(dyn.d_un.d_ptr); break;
+ case DT_FINI: cmELFByteSwap(dyn.d_un.d_ptr); break;
+ case DT_SONAME: cmELFByteSwap(dyn.d_un.d_val); break;
+ case DT_RPATH: cmELFByteSwap(dyn.d_un.d_val); break;
+ case DT_SYMBOLIC: /* dyn.d_un ignored */ break;
+ case DT_REL: cmELFByteSwap(dyn.d_un.d_ptr); break;
+ case DT_RELSZ: cmELFByteSwap(dyn.d_un.d_val); break;
+ case DT_RELENT: cmELFByteSwap(dyn.d_un.d_val); break;
+ case DT_PLTREL: cmELFByteSwap(dyn.d_un.d_val); break;
+ case DT_DEBUG: cmELFByteSwap(dyn.d_un.d_ptr); break;
+ case DT_TEXTREL: /* dyn.d_un ignored */ break;
+ case DT_JMPREL: cmELFByteSwap(dyn.d_un.d_ptr); break;
+#ifdef T_BIND_NOW
+ case T_BIND_NOW: /* dyn.d_un ignored */ break;
+#endif
+#ifdef DT_INIT_ARRAY
+ case DT_INIT_ARRAY: cmELFByteSwap(dyn.d_un.d_ptr); break;
+#endif
+#ifdef DT_FINI_ARRAY
+ case DT_FINI_ARRAY: cmELFByteSwap(dyn.d_un.d_ptr); break;
+#endif
+#ifdef DT_INIT_ARRAYSZ
+ case DT_INIT_ARRAYSZ: cmELFByteSwap(dyn.d_un.d_val); break;
+#endif
+#ifdef DT_FINI_ARRAYSZ
+ case DT_FINI_ARRAYSZ: cmELFByteSwap(dyn.d_un.d_val); break;
+#endif
+#ifdef DT_RUNPATH
+ case DT_RUNPATH: cmELFByteSwap(dyn.d_un.d_val); break;
+#endif
+#ifdef DT_FLAGS
+ case DT_FLAGS: cmELFByteSwap(dyn.d_un.d_val); break;
+#endif
+#ifdef DT_PREINIT_ARRAY
+ case DT_PREINIT_ARRAY: cmELFByteSwap(dyn.d_un.d_ptr); break;
+#endif
+#ifdef DT_PREINIT_ARRAYSZ
+ case DT_PREINIT_ARRAYSZ: cmELFByteSwap(dyn.d_un.d_val); break;
+#endif
+ }
+ }
+
+ bool FileTypeValid(ELF_Half et)
+ {
+ unsigned int eti = static_cast<unsigned int>(et);
+ if(eti == ET_NONE || eti == ET_REL || eti == ET_EXEC ||
+ eti == ET_DYN || eti == ET_CORE)
+ {
+ return true;
+ }
+#if defined(ET_LOOS) && defined(ET_HIOS)
+ if(eti >= ET_LOOS && eti <= ET_HIOS)
+ {
+ return true;
+ }
+#endif
+#if defined(ET_LOPROC) && defined(ET_HIPROC)
+ if(eti >= ET_LOPROC && eti <= ET_HIPROC)
+ {
+ return true;
+ }
+#endif
+ return false;
+ }
+
+ bool Read(ELF_Ehdr& x)
+ {
+ // Read the header from the file.
+ if(!this->Stream.read(reinterpret_cast<char*>(&x), sizeof(x)))
+ {
+ return false;
+ }
+
+ // The byte order of ELF header fields may not match that of the
+ // processor-specific data. The header fields are ordered to
+ // match the target execution environment, so we may need to
+ // memorize the order of all platforms based on the e_machine
+ // value. As a heuristic, if the type is invalid but its
+ // swapped value is okay then flip our swap mode.
+ ELF_Half et = x.e_type;
+ if(this->NeedSwap)
+ {
+ cmELFByteSwap(et);
+ }
+ if(!this->FileTypeValid(et))
+ {
+ cmELFByteSwap(et);
+ if(this->FileTypeValid(et))
+ {
+ // The previous byte order guess was wrong. Flip it.
+ this->NeedSwap = !this->NeedSwap;
+ }
+ }
+
+ // Fix the byte order of the header.
+ if(this->NeedSwap)
+ {
+ ByteSwap(x);
+ }
+ return true;
+ }
+ bool Read(ELF_Shdr& x)
+ {
+ if(this->Stream.read(reinterpret_cast<char*>(&x), sizeof(x)) &&
+ this->NeedSwap)
+ {
+ ByteSwap(x);
+ }
+ return this->Stream? true:false;
+ }
+ bool Read(ELF_Dyn& x)
+ {
+ if(this->Stream.read(reinterpret_cast<char*>(&x), sizeof(x)) &&
+ this->NeedSwap)
+ {
+ ByteSwap(x);
+ }
+ return this->Stream? true:false;
+ }
+
+ bool LoadSectionHeader(ELF_Half i)
+ {
+ // Read the section header from the file.
+ this->Stream.seekg(this->ELFHeader.e_shoff +
+ this->ELFHeader.e_shentsize * i);
+ if(!this->Read(this->SectionHeaders[i]))
+ {
+ return false;
+ }
+
+ // Identify some important sections.
+ if(this->SectionHeaders[i].sh_type == SHT_DYNAMIC)
+ {
+ this->DynamicSectionIndex = i;
+ }
+ return true;
+ }
+
+ bool LoadDynamicSection();
+
+ // Store the main ELF header.
+ ELF_Ehdr ELFHeader;
+
+ // Store all the section headers.
+ std::vector<ELF_Shdr> SectionHeaders;
+
+ // Store all entries of the DYNAMIC section.
+ std::vector<ELF_Dyn> DynamicSectionEntries;
+};
+
+//----------------------------------------------------------------------------
+template <class Types>
+cmELFInternalImpl<Types>
+::cmELFInternalImpl(cmELF* external,
+ cmsys::auto_ptr<std::ifstream>& fin,
+ ByteOrderType order):
+ cmELFInternal(external, fin, order)
+{
+ // Read the main header.
+ if(!this->Read(this->ELFHeader))
+ {
+ this->SetErrorMessage("Failed to read main ELF header.");
+ return;
+ }
+
+ // Determine the ELF file type.
+ switch(this->ELFHeader.e_type)
+ {
+ case ET_NONE:
+ this->SetErrorMessage("ELF file type is NONE.");
+ return;
+ case ET_REL:
+ this->ELFType = cmELF::FileTypeRelocatableObject;
+ break;
+ case ET_EXEC:
+ this->ELFType = cmELF::FileTypeExecutable;
+ break;
+ case ET_DYN:
+ this->ELFType = cmELF::FileTypeSharedLibrary;
+ break;
+ case ET_CORE:
+ this->ELFType = cmELF::FileTypeCore;
+ break;
+ default:
+ {
+ unsigned int eti = static_cast<unsigned int>(this->ELFHeader.e_type);
+#if defined(ET_LOOS) && defined(ET_HIOS)
+ if(eti >= ET_LOOS && eti <= ET_HIOS)
+ {
+ this->ELFType = cmELF::FileTypeSpecificOS;
+ break;
+ }
+#endif
+#if defined(ET_LOPROC) && defined(ET_HIPROC)
+ if(eti >= ET_LOPROC && eti <= ET_HIPROC)
+ {
+ this->ELFType = cmELF::FileTypeSpecificProc;
+ break;
+ }
+#endif
+ cmOStringStream e;
+ e << "Unknown ELF file type " << eti;
+ this->SetErrorMessage(e.str().c_str());
+ return;
+ }
+ }
+
+ // Load the section headers.
+ this->SectionHeaders.resize(this->ELFHeader.e_shnum);
+ for(ELF_Half i=0; i < this->ELFHeader.e_shnum; ++i)
+ {
+ if(!this->LoadSectionHeader(i))
+ {
+ this->SetErrorMessage("Failed to load section headers.");
+ return;
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+template <class Types>
+bool cmELFInternalImpl<Types>::LoadDynamicSection()
+{
+ // If there is no dynamic section we are done.
+ if(this->DynamicSectionIndex < 0)
+ {
+ return false;
+ }
+
+ // If the section was already loaded we are done.
+ if(!this->DynamicSectionEntries.empty())
+ {
+ return true;
+ }
+
+ // Allocate the dynamic section entries.
+ ELF_Shdr const& sec = this->SectionHeaders[this->DynamicSectionIndex];
+ int n = static_cast<int>(sec.sh_size / sec.sh_entsize);
+ this->DynamicSectionEntries.resize(n);
+
+ // Read each entry.
+ for(int j=0; j < n; ++j)
+ {
+ // Seek to the beginning of the section entry.
+ this->Stream.seekg(sec.sh_offset + sec.sh_entsize*j);
+ ELF_Dyn& dyn = this->DynamicSectionEntries[j];
+
+ // Try reading the entry.
+ if(!this->Read(dyn))
+ {
+ this->SetErrorMessage("Error reading entry from DYNAMIC section.");
+ this->DynamicSectionIndex = -1;
+ return false;
+ }
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+template <class Types>
+unsigned int cmELFInternalImpl<Types>::GetDynamicEntryCount()
+{
+ if(!this->LoadDynamicSection())
+ {
+ return 0;
+ }
+ for(unsigned int i = 0; i < this->DynamicSectionEntries.size(); ++i)
+ {
+ if(this->DynamicSectionEntries[i].d_tag == DT_NULL)
+ {
+ return i;
+ }
+ }
+ return static_cast<unsigned int>(this->DynamicSectionEntries.size());
+}
+
+//----------------------------------------------------------------------------
+template <class Types>
+unsigned long cmELFInternalImpl<Types>::GetDynamicEntryPosition(int j)
+{
+ if(!this->LoadDynamicSection())
+ {
+ return 0;
+ }
+ if(j < 0 || j >= static_cast<int>(this->DynamicSectionEntries.size()))
+ {
+ return 0;
+ }
+ ELF_Shdr const& sec = this->SectionHeaders[this->DynamicSectionIndex];
+ return static_cast<unsigned long>(sec.sh_offset + sec.sh_entsize*j);
+}
+
+//----------------------------------------------------------------------------
+template <class Types>
+cmELF::StringEntry const*
+cmELFInternalImpl<Types>::GetDynamicSectionString(int tag)
+{
+ // Short-circuit if already checked.
+ std::map<int, StringEntry>::iterator dssi =
+ this->DynamicSectionStrings.find(tag);
+ if(dssi != this->DynamicSectionStrings.end())
+ {
+ if(dssi->second.Position > 0)
+ {
+ return &dssi->second;
+ }
+ return 0;
+ }
+
+ // Create an entry for this tag. Assume it is missing until found.
+ StringEntry& se = this->DynamicSectionStrings[tag];
+ se.Position = 0;
+ se.Size = 0;
+ se.IndexInSection = -1;
+
+ // Try reading the dynamic section.
+ if(!this->LoadDynamicSection())
+ {
+ return 0;
+ }
+
+ // Get the string table referenced by the DYNAMIC section.
+ ELF_Shdr const& sec = this->SectionHeaders[this->DynamicSectionIndex];
+ if(sec.sh_link >= this->SectionHeaders.size())
+ {
+ this->SetErrorMessage("Section DYNAMIC has invalid string table index.");
+ return 0;
+ }
+ ELF_Shdr const& strtab = this->SectionHeaders[sec.sh_link];
+
+ // Look for the requested entry.
+ for(typename std::vector<ELF_Dyn>::iterator
+ di = this->DynamicSectionEntries.begin();
+ di != this->DynamicSectionEntries.end(); ++di)
+ {
+ ELF_Dyn& dyn = *di;
+ if(dyn.d_tag == tag)
+ {
+ // We found the tag requested.
+ // Make sure the position given is within the string section.
+ if(dyn.d_un.d_val >= strtab.sh_size)
+ {
+ this->SetErrorMessage("Section DYNAMIC references string beyond "
+ "the end of its string section.");
+ return 0;
+ }
+
+ // Seek to the position reported by the entry.
+ unsigned long first = static_cast<unsigned long>(dyn.d_un.d_val);
+ unsigned long last = first;
+ unsigned long end = static_cast<unsigned long>(strtab.sh_size);
+ this->Stream.seekg(strtab.sh_offset + first);
+
+ // Read the string. It may be followed by more than one NULL
+ // terminator. Count the total size of the region allocated to
+ // the string. This assumes that the next string in the table
+ // is non-empty, but the "chrpath" tool makes the same
+ // assumption.
+ bool terminated = false;
+ char c;
+ while(last != end && this->Stream.get(c) && !(terminated && c))
+ {
+ ++last;
+ if(c)
+ {
+ se.Value += c;
+ }
+ else
+ {
+ terminated = true;
+ }
+ }
+
+ // Make sure the whole value was read.
+ if(!this->Stream)
+ {
+ this->SetErrorMessage("Dynamic section specifies unreadable RPATH.");
+ se.Value = "";
+ return 0;
+ }
+
+ // The value has been read successfully. Report it.
+ se.Position = static_cast<unsigned long>(strtab.sh_offset + first);
+ se.Size = last - first;
+ se.IndexInSection =
+ static_cast<int>(di - this->DynamicSectionEntries.begin());
+ return &se;
+ }
+ }
+ return 0;
+}
+
+//============================================================================
+// External class implementation.
+
+//----------------------------------------------------------------------------
+cmELF::cmELF(const char* fname): Internal(0)
+{
+ // Try to open the file.
+ cmsys::auto_ptr<std::ifstream> fin(new std::ifstream(fname));
+
+ // Quit now if the file could not be opened.
+ if(!fin.get() || !*fin)
+ {
+ this->ErrorMessage = "Error opening input file.";
+ return;
+ }
+
+ // Read the ELF identification block.
+ char ident[EI_NIDENT];
+ if(!fin->read(ident, EI_NIDENT))
+ {
+ this->ErrorMessage = "Error reading ELF identification.";
+ return;
+ }
+ if(!fin->seekg(0))
+ {
+ this->ErrorMessage = "Error seeking to beginning of file.";
+ return;
+ }
+
+ // Verify the ELF identification.
+ if(!(ident[EI_MAG0] == ELFMAG0 &&
+ ident[EI_MAG1] == ELFMAG1 &&
+ ident[EI_MAG2] == ELFMAG2 &&
+ ident[EI_MAG3] == ELFMAG3))
+ {
+ this->ErrorMessage = "File does not have a valid ELF identification.";
+ return;
+ }
+
+ // Check the byte order in which the rest of the file is encoded.
+ cmELFInternal::ByteOrderType order;
+ if(ident[EI_DATA] == ELFDATA2LSB)
+ {
+ // File is LSB.
+ order = cmELFInternal::ByteOrderLSB;
+ }
+ else if(ident[EI_DATA] == ELFDATA2MSB)
+ {
+ // File is MSB.
+ order = cmELFInternal::ByteOrderMSB;
+ }
+ else
+ {
+ this->ErrorMessage = "ELF file is not LSB or MSB encoded.";
+ return;
+ }
+
+ // Check the class of the file and construct the corresponding
+ // parser implementation.
+ if(ident[EI_CLASS] == ELFCLASS32)
+ {
+ // 32-bit ELF
+ this->Internal = new cmELFInternalImpl<cmELFTypes32>(this, fin, order);
+ }
+ else if(ident[EI_CLASS] == ELFCLASS64)
+ {
+ // 64-bit ELF
+ this->Internal = new cmELFInternalImpl<cmELFTypes64>(this, fin, order);
+ }
+ else
+ {
+ this->ErrorMessage = "ELF file class is not 32-bit or 64-bit.";
+ return;
+ }
+}
+
+//----------------------------------------------------------------------------
+cmELF::~cmELF()
+{
+ delete this->Internal;
+}
+
+//----------------------------------------------------------------------------
+bool cmELF::Valid() const
+{
+ return this->Internal && this->Internal->GetFileType() != FileTypeInvalid;
+}
+
+//----------------------------------------------------------------------------
+cmELF::FileType cmELF::GetFileType() const
+{
+ if(this->Valid())
+ {
+ return this->Internal->GetFileType();
+ }
+ else
+ {
+ return FileTypeInvalid;
+ }
+}
+
+//----------------------------------------------------------------------------
+unsigned int cmELF::GetNumberOfSections() const
+{
+ if(this->Valid())
+ {
+ return this->Internal->GetNumberOfSections();
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+//----------------------------------------------------------------------------
+unsigned int cmELF::GetDynamicEntryCount() const
+{
+ if(this->Valid())
+ {
+ return this->Internal->GetDynamicEntryCount();
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+//----------------------------------------------------------------------------
+unsigned long cmELF::GetDynamicEntryPosition(int index) const
+{
+ if(this->Valid())
+ {
+ return this->Internal->GetDynamicEntryPosition(index);
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmELF::ReadBytes(unsigned long pos, unsigned long size, char* buf) const
+{
+ if(this->Valid())
+ {
+ return this->Internal->ReadBytes(pos, size, buf);
+ }
+ else
+ {
+ return false;
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmELF::GetSOName(std::string& soname)
+{
+ if(StringEntry const* se = this->GetSOName())
+ {
+ soname = se->Value;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+//----------------------------------------------------------------------------
+cmELF::StringEntry const* cmELF::GetSOName()
+{
+ if(this->Valid() &&
+ this->Internal->GetFileType() == cmELF::FileTypeSharedLibrary)
+ {
+ return this->Internal->GetSOName();
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+//----------------------------------------------------------------------------
+cmELF::StringEntry const* cmELF::GetRPath()
+{
+ if(this->Valid() &&
+ (this->Internal->GetFileType() == cmELF::FileTypeExecutable ||
+ this->Internal->GetFileType() == cmELF::FileTypeSharedLibrary))
+ {
+ return this->Internal->GetRPath();
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+//----------------------------------------------------------------------------
+cmELF::StringEntry const* cmELF::GetRunPath()
+{
+ if(this->Valid() &&
+ (this->Internal->GetFileType() == cmELF::FileTypeExecutable ||
+ this->Internal->GetFileType() == cmELF::FileTypeSharedLibrary))
+ {
+ return this->Internal->GetRunPath();
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmELF::PrintInfo(std::ostream& os) const
+{
+ if(this->Valid())
+ {
+ this->Internal->PrintInfo(os);
+ }
+ else
+ {
+ os << "Not a valid ELF file.\n";
+ }
+}
diff --git a/Source/cmELF.h b/Source/cmELF.h
new file mode 100644
index 000000000..ab9be4245
--- /dev/null
+++ b/Source/cmELF.h
@@ -0,0 +1,108 @@
+/*============================================================================
+ 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 cmELF_h
+#define cmELF_h
+
+#if !defined(CMAKE_USE_ELF_PARSER)
+# error "This file may be included only if CMAKE_USE_ELF_PARSER is enabled."
+#endif
+
+class cmELFInternal;
+
+/** \class cmELF
+ * \brief Executable and Link Format (ELF) parser.
+ */
+class cmELF
+{
+public:
+ /** Construct with the name of the ELF input file to parse. */
+ cmELF(const char* fname);
+
+ /** Destruct. */
+ ~cmELF();
+
+ /** Get the error message if any. */
+ std::string const& GetErrorMessage() const
+ {
+ return this->ErrorMessage;
+ }
+
+ /** Boolean conversion. True if the ELF file is valid. */
+ operator bool() const { return this->Valid(); }
+
+ /** Enumeration of ELF file types. */
+ enum FileType
+ {
+ FileTypeInvalid,
+ FileTypeRelocatableObject,
+ FileTypeExecutable,
+ FileTypeSharedLibrary,
+ FileTypeCore,
+ FileTypeSpecificOS,
+ FileTypeSpecificProc
+ };
+
+ /** Represent string table entries. */
+ struct StringEntry
+ {
+ // The string value itself.
+ std::string Value;
+
+ // The position in the file at which the string appears.
+ unsigned long Position;
+
+ // The size of the string table entry. This includes the space
+ // allocated for one or more null terminators.
+ unsigned long Size;
+
+ // The index of the section entry referencing the string.
+ int IndexInSection;
+ };
+
+ /** Get the type of the file opened. */
+ FileType GetFileType() const;
+
+ /** Get the number of ELF sections present. */
+ unsigned int GetNumberOfSections() const;
+
+ /** Get the number of DYNAMIC section entries before the first
+ DT_NULL. Returns zero on error. */
+ unsigned int GetDynamicEntryCount() const;
+
+ /** Get the position of a DYNAMIC section header entry. Returns
+ zero on error. */
+ unsigned long GetDynamicEntryPosition(int index) const;
+
+ /** Read bytes from the file. */
+ bool ReadBytes(unsigned long pos, unsigned long size, char* buf) const;
+
+ /** Get the SONAME field if any. */
+ bool GetSOName(std::string& soname);
+ StringEntry const* GetSOName();
+
+ /** Get the RPATH field if any. */
+ StringEntry const* GetRPath();
+
+ /** Get the RUNPATH field if any. */
+ StringEntry const* GetRunPath();
+
+ /** Print human-readable information about the ELF file. */
+ void PrintInfo(std::ostream& os) const;
+
+private:
+ friend class cmELFInternal;
+ bool Valid() const;
+ cmELFInternal* Internal;
+ std::string ErrorMessage;
+};
+
+#endif
diff --git a/Source/cmElseCommand.cxx b/Source/cmElseCommand.cxx
new file mode 100644
index 000000000..163d006ad
--- /dev/null
+++ b/Source/cmElseCommand.cxx
@@ -0,0 +1,21 @@
+/*============================================================================
+ 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 "cmElseCommand.h"
+
+bool cmElseCommand::InitialPass(std::vector<std::string> const&,
+ cmExecutionStatus &)
+{
+ this->SetError("An ELSE command was found outside of a proper "
+ "IF ENDIF structure. Or its arguments did not match "
+ "the opening IF command.");
+ return false;
+}
diff --git a/Source/cmElseCommand.h b/Source/cmElseCommand.h
new file mode 100644
index 000000000..5e8b79058
--- /dev/null
+++ b/Source/cmElseCommand.h
@@ -0,0 +1,72 @@
+/*============================================================================
+ 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 cmElseCommand_h
+#define cmElseCommand_h
+
+#include "cmIfCommand.h"
+
+/** \class cmElseCommand
+ * \brief ends an if block
+ *
+ * cmElseCommand ends an if block
+ */
+class cmElseCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmElseCommand;
+ }
+
+ /**
+ * 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 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.";
+ }
+
+ cmTypeMacro(cmElseCommand, cmCommand);
+};
+
+
+#endif
diff --git a/Source/cmElseIfCommand.cxx b/Source/cmElseIfCommand.cxx
new file mode 100644
index 000000000..cd9742bbd
--- /dev/null
+++ b/Source/cmElseIfCommand.cxx
@@ -0,0 +1,20 @@
+/*============================================================================
+ 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 "cmElseIfCommand.h"
+
+bool cmElseIfCommand::InitialPass(std::vector<std::string> const&,
+ cmExecutionStatus &)
+{
+ this->SetError("An ELSEIF command was found outside of a proper "
+ "IF ENDIF structure.");
+ return false;
+}
diff --git a/Source/cmElseIfCommand.h b/Source/cmElseIfCommand.h
new file mode 100644
index 000000000..20cd81aaa
--- /dev/null
+++ b/Source/cmElseIfCommand.h
@@ -0,0 +1,72 @@
+/*============================================================================
+ 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 cmElseIfCommand_h
+#define cmElseIfCommand_h
+
+#include "cmIfCommand.h"
+
+/** \class cmElseIfCommand
+ * \brief ends an if block
+ *
+ * cmElseIfCommand ends an if block
+ */
+class cmElseIfCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmElseIfCommand;
+ }
+
+ /**
+ * 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 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.";
+ }
+
+ cmTypeMacro(cmElseIfCommand, cmCommand);
+};
+
+
+#endif
diff --git a/Source/cmEnableLanguageCommand.cxx b/Source/cmEnableLanguageCommand.cxx
new file mode 100644
index 000000000..f8f36ebbb
--- /dev/null
+++ b/Source/cmEnableLanguageCommand.cxx
@@ -0,0 +1,43 @@
+/*============================================================================
+ 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 "cmEnableLanguageCommand.h"
+
+// cmEnableLanguageCommand
+bool cmEnableLanguageCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ bool optional = false;
+ std::vector<std::string> languages;
+ if(args.size() < 1 )
+ {
+ this->SetError
+ ("called with incorrect number of arguments");
+ return false;
+ }
+ for (std::vector<std::string>::const_iterator it = args.begin();
+ it != args.end();
+ ++it)
+ {
+ if ((*it) == "OPTIONAL")
+ {
+ optional = true;
+ }
+ else
+ {
+ languages.push_back(*it);
+ }
+ }
+
+ this->Makefile->EnableLanguage(languages, optional);
+ return true;
+}
+
diff --git a/Source/cmEnableLanguageCommand.h b/Source/cmEnableLanguageCommand.h
new file mode 100644
index 000000000..5958e4481
--- /dev/null
+++ b/Source/cmEnableLanguageCommand.h
@@ -0,0 +1,76 @@
+/*============================================================================
+ 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 cmEnableLanguageCommand_h
+#define cmEnableLanguageCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmEnableLanguageCommand
+ * \brief Specify the name for this build project.
+ *
+ * cmEnableLanguageCommand is used to specify a name for this build project.
+ * It is defined once per set of CMakeList.txt files (including
+ * all subdirectories). Currently it just sets the name of the workspace
+ * file for Microsoft Visual C++
+ */
+class cmEnableLanguageCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmEnableLanguageCommand;
+ }
+
+ /**
+ * 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 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(languageName [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. "
+ "If OPTIONAL is used, use the CMAKE_<languageName>_COMPILER_WORKS "
+ "variable to check whether the language has been enabled successfully.";
+ }
+
+ cmTypeMacro(cmEnableLanguageCommand, cmCommand);
+};
+
+
+
+#endif
diff --git a/Source/cmEnableTestingCommand.cxx b/Source/cmEnableTestingCommand.cxx
new file mode 100644
index 000000000..5abb873bd
--- /dev/null
+++ b/Source/cmEnableTestingCommand.cxx
@@ -0,0 +1,22 @@
+/*============================================================================
+ 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 "cmEnableTestingCommand.h"
+#include "cmLocalGenerator.h"
+
+// we do this in the final pass so that we now the subdirs have all
+// been defined
+bool cmEnableTestingCommand::InitialPass(std::vector<std::string> const&,
+ cmExecutionStatus &)
+{
+ this->Makefile->AddDefinition("CMAKE_TESTING_ENABLED","1");
+ return true;
+}
diff --git a/Source/cmEnableTestingCommand.h b/Source/cmEnableTestingCommand.h
new file mode 100644
index 000000000..b607818ce
--- /dev/null
+++ b/Source/cmEnableTestingCommand.h
@@ -0,0 +1,79 @@
+/*============================================================================
+ 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 cmEnableTestingCommand_h
+#define cmEnableTestingCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmEnableTestingCommand
+ * \brief Enable testing for this directory and below.
+ *
+ * Produce the output testfile. This produces a file in the build directory
+ * called CMakeTestfile with a syntax similar to CMakeLists.txt. It contains
+ * the SUBDIRS() and ADD_TEST() commands from the source CMakeLists.txt
+ * file with CMake variables expanded. Only the subdirs and tests
+ * within the valid control structures are replicated in Testfile
+ * (i.e. SUBDIRS() and ADD_TEST() commands within IF() commands that are
+ * not entered by CMake are not replicated in Testfile).
+ * Note that CTest expects to find this file in the build directory root;
+ * therefore, this command should be in the source directory root too.
+ */
+class cmEnableTestingCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmEnableTestingCommand;
+ }
+
+ /**
+ * This is called when the command is first encountered in
+ * the CMakeLists.txt file.
+ */
+ virtual bool InitialPass(std::vector<std::string> const&,
+ cmExecutionStatus &);
+
+ /**
+ * 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.";
+ }
+
+ cmTypeMacro(cmEnableTestingCommand, cmCommand);
+
+};
+
+
+#endif
diff --git a/Source/cmEndForEachCommand.cxx b/Source/cmEndForEachCommand.cxx
new file mode 100644
index 000000000..2eca4e292
--- /dev/null
+++ b/Source/cmEndForEachCommand.cxx
@@ -0,0 +1,23 @@
+/*============================================================================
+ 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 "cmEndForEachCommand.h"
+
+bool cmEndForEachCommand
+::InvokeInitialPass(std::vector<cmListFileArgument> const&,
+ cmExecutionStatus &)
+{
+ this->SetError("An ENDFOREACH command was found outside of a proper "
+ "FOREACH ENDFOREACH structure. Or its arguments did "
+ "not match the opening FOREACH command.");
+ return false;
+}
+
diff --git a/Source/cmEndForEachCommand.h b/Source/cmEndForEachCommand.h
new file mode 100644
index 000000000..37b2d2a32
--- /dev/null
+++ b/Source/cmEndForEachCommand.h
@@ -0,0 +1,79 @@
+/*============================================================================
+ 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 cmEndForEachCommand_h
+#define cmEndForEachCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmEndForEachCommand
+ * \brief ends an if block
+ *
+ * cmEndForEachCommand ends an if block
+ */
+class cmEndForEachCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmEndForEachCommand;
+ }
+
+ /**
+ * Override cmCommand::InvokeInitialPass to get arguments before
+ * expansion.
+ */
+ virtual bool InvokeInitialPass(std::vector<cmListFileArgument> const&,
+ cmExecutionStatus &);
+
+ /**
+ * This is called when the command is first encountered in
+ * the CMakeLists.txt file.
+ */
+ virtual bool InitialPass(std::vector<std::string> const&,
+ cmExecutionStatus &) {return false;}
+
+ /**
+ * 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 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.";
+ }
+
+ cmTypeMacro(cmEndForEachCommand, cmCommand);
+};
+
+
+#endif
diff --git a/Source/cmEndFunctionCommand.cxx b/Source/cmEndFunctionCommand.cxx
new file mode 100644
index 000000000..04b242d70
--- /dev/null
+++ b/Source/cmEndFunctionCommand.cxx
@@ -0,0 +1,23 @@
+/*============================================================================
+ 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 "cmEndFunctionCommand.h"
+
+bool cmEndFunctionCommand
+::InvokeInitialPass(std::vector<cmListFileArgument> const&,
+ cmExecutionStatus &)
+{
+ this->SetError("An ENDFUNCTION command was found outside of a proper "
+ "FUNCTION ENDFUNCTION structure. Or its arguments did not "
+ "match the opening FUNCTION command.");
+ return false;
+}
+
diff --git a/Source/cmEndFunctionCommand.h b/Source/cmEndFunctionCommand.h
new file mode 100644
index 000000000..54ac068f3
--- /dev/null
+++ b/Source/cmEndFunctionCommand.h
@@ -0,0 +1,79 @@
+/*============================================================================
+ 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 cmEndFunctionCommand_h
+#define cmEndFunctionCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmEndFunctionCommand
+ * \brief ends an if block
+ *
+ * cmEndFunctionCommand ends an if block
+ */
+class cmEndFunctionCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmEndFunctionCommand;
+ }
+
+ /**
+ * Override cmCommand::InvokeInitialPass to get arguments before
+ * expansion.
+ */
+ virtual bool InvokeInitialPass(std::vector<cmListFileArgument> const&,
+ cmExecutionStatus &);
+
+ /**
+ * This is called when the command is first encountered in
+ * the CMakeLists.txt file.
+ */
+ virtual bool InitialPass(std::vector<std::string> const&,
+ cmExecutionStatus &) {return false;}
+
+ /**
+ * 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 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.";
+ }
+
+ cmTypeMacro(cmEndFunctionCommand, cmCommand);
+};
+
+
+#endif
diff --git a/Source/cmEndIfCommand.cxx b/Source/cmEndIfCommand.cxx
new file mode 100644
index 000000000..e98d4d415
--- /dev/null
+++ b/Source/cmEndIfCommand.cxx
@@ -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.
+============================================================================*/
+#include "cmEndIfCommand.h"
+#include <stdlib.h> // required for atof
+bool cmEndIfCommand::InitialPass(std::vector<std::string> const&,
+ cmExecutionStatus &)
+{
+ const char* versionValue
+ = this->Makefile->GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION");
+ if (!versionValue || (atof(versionValue) <= 1.4))
+ {
+ return true;
+ }
+
+ this->SetError("An ENDIF command was found outside of a proper "
+ "IF ENDIF structure. Or its arguments did not match "
+ "the opening IF command.");
+ return false;
+}
+
diff --git a/Source/cmEndIfCommand.h b/Source/cmEndIfCommand.h
new file mode 100644
index 000000000..81d1b5ff4
--- /dev/null
+++ b/Source/cmEndIfCommand.h
@@ -0,0 +1,72 @@
+/*============================================================================
+ 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 cmEndIfCommand_h
+#define cmEndIfCommand_h
+
+#include "cmIfCommand.h"
+
+/** \class cmEndIfCommand
+ * \brief ends an if block
+ *
+ * cmEndIfCommand ends an if block
+ */
+class cmEndIfCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmEndIfCommand;
+ }
+
+ /**
+ * 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 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.";
+ }
+
+ cmTypeMacro(cmEndIfCommand, cmCommand);
+};
+
+
+#endif
diff --git a/Source/cmEndMacroCommand.cxx b/Source/cmEndMacroCommand.cxx
new file mode 100644
index 000000000..86d907ba4
--- /dev/null
+++ b/Source/cmEndMacroCommand.cxx
@@ -0,0 +1,23 @@
+/*============================================================================
+ 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 "cmEndMacroCommand.h"
+
+bool cmEndMacroCommand
+::InvokeInitialPass(std::vector<cmListFileArgument> const&,
+ cmExecutionStatus &)
+{
+ this->SetError("An ENDMACRO command was found outside of a proper "
+ "MACRO ENDMACRO structure. Or its arguments did not "
+ "match the opening MACRO command.");
+ return false;
+}
+
diff --git a/Source/cmEndMacroCommand.h b/Source/cmEndMacroCommand.h
new file mode 100644
index 000000000..25e86b70f
--- /dev/null
+++ b/Source/cmEndMacroCommand.h
@@ -0,0 +1,79 @@
+/*============================================================================
+ 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 cmEndMacroCommand_h
+#define cmEndMacroCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmEndMacroCommand
+ * \brief ends an if block
+ *
+ * cmEndMacroCommand ends an if block
+ */
+class cmEndMacroCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmEndMacroCommand;
+ }
+
+ /**
+ * Override cmCommand::InvokeInitialPass to get arguments before
+ * expansion.
+ */
+ virtual bool InvokeInitialPass(std::vector<cmListFileArgument> const&,
+ cmExecutionStatus &);
+
+ /**
+ * This is called when the command is first encountered in
+ * the CMakeLists.txt file.
+ */
+ virtual bool InitialPass(std::vector<std::string> const&,
+ cmExecutionStatus &) {return false;}
+
+ /**
+ * 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 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.";
+ }
+
+ cmTypeMacro(cmEndMacroCommand, cmCommand);
+};
+
+
+#endif
diff --git a/Source/cmEndWhileCommand.cxx b/Source/cmEndWhileCommand.cxx
new file mode 100644
index 000000000..abb9e5e0b
--- /dev/null
+++ b/Source/cmEndWhileCommand.cxx
@@ -0,0 +1,32 @@
+/*============================================================================
+ 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 "cmEndWhileCommand.h"
+
+bool cmEndWhileCommand
+::InvokeInitialPass(std::vector<cmListFileArgument> const& args,
+ cmExecutionStatus &)
+{
+ if (args.empty())
+ {
+ this->SetError("An ENDWHILE command was found outside of a proper "
+ "WHILE ENDWHILE structure.");
+ }
+ else
+ {
+ this->SetError("An ENDWHILE command was found outside of a proper "
+ "WHILE ENDWHILE structure. Or its arguments did not "
+ "match the opening WHILE command.");
+ }
+
+ return false;
+}
+
diff --git a/Source/cmEndWhileCommand.h b/Source/cmEndWhileCommand.h
new file mode 100644
index 000000000..635ad5a7f
--- /dev/null
+++ b/Source/cmEndWhileCommand.h
@@ -0,0 +1,79 @@
+/*============================================================================
+ 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 cmEndWhileCommand_h
+#define cmEndWhileCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmEndWhileCommand
+ * \brief ends a while loop
+ *
+ * cmEndWhileCommand ends a while loop
+ */
+class cmEndWhileCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmEndWhileCommand;
+ }
+
+ /**
+ * Override cmCommand::InvokeInitialPass to get arguments before
+ * expansion.
+ */
+ virtual bool InvokeInitialPass(std::vector<cmListFileArgument> const& args,
+ cmExecutionStatus &status);
+
+ /**
+ * This is called when the command is first encountered in
+ * the CMakeLists.txt file.
+ */
+ virtual bool InitialPass(std::vector<std::string> const&,
+ cmExecutionStatus &) {return false;}
+
+ /**
+ * 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 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.";
+ }
+
+ cmTypeMacro(cmEndWhileCommand, cmCommand);
+};
+
+
+#endif
diff --git a/Source/cmExecProgramCommand.cxx b/Source/cmExecProgramCommand.cxx
new file mode 100644
index 000000000..61b27eaf0
--- /dev/null
+++ b/Source/cmExecProgramCommand.cxx
@@ -0,0 +1,145 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmExecProgramCommand.h"
+#include "cmSystemTools.h"
+
+// cmExecProgramCommand
+bool cmExecProgramCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 1 )
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+ std::string arguments;
+ bool doingargs = false;
+ int count = 0;
+ std::string output_variable;
+ bool haveoutput_variable = false;
+ std::string return_variable;
+ bool havereturn_variable = false;
+ for(size_t i=0; i < args.size(); ++i)
+ {
+ if(args[i] == "OUTPUT_VARIABLE")
+ {
+ count++;
+ doingargs = false;
+ havereturn_variable = false;
+ haveoutput_variable = true;
+ }
+ else if ( haveoutput_variable )
+ {
+ if ( output_variable.size() > 0 )
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+ output_variable = args[i];
+ haveoutput_variable = false;
+ count ++;
+ }
+ else if(args[i] == "RETURN_VALUE")
+ {
+ count++;
+ doingargs = false;
+ haveoutput_variable = false;
+ havereturn_variable = true;
+ }
+ else if ( havereturn_variable )
+ {
+ if ( return_variable.size() > 0 )
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+ return_variable = args[i];
+ havereturn_variable = false;
+ count ++;
+ }
+ else if(args[i] == "ARGS")
+ {
+ count++;
+ havereturn_variable = false;
+ haveoutput_variable = false;
+ doingargs = true;
+ }
+ else if(doingargs)
+ {
+ arguments += args[i];
+ arguments += " ";
+ count++;
+ }
+ }
+
+ std::string command;
+ if(arguments.size())
+ {
+ command = cmSystemTools::ConvertToRunCommandPath(args[0].c_str());
+ command += " ";
+ command += arguments;
+ }
+ else
+ {
+ command = args[0];
+ }
+ bool verbose = true;
+ if(output_variable.size() > 0)
+ {
+ verbose = false;
+ }
+ int retVal = 0;
+ std::string output;
+ bool result = true;
+ if(args.size() - count == 2)
+ {
+ cmSystemTools::MakeDirectory(args[1].c_str());
+ result = cmSystemTools::RunCommand(command.c_str(), output, retVal,
+ args[1].c_str(), verbose);
+ }
+ else
+ {
+ result = cmSystemTools::RunCommand(command.c_str(), output,
+ retVal, 0, verbose);
+ }
+ if(!result)
+ {
+ retVal = -1;
+ }
+
+ if ( output_variable.size() > 0 )
+ {
+ std::string::size_type first = output.find_first_not_of(" \n\t\r");
+ std::string::size_type last = output.find_last_not_of(" \n\t\r");
+ if(first == std::string::npos)
+ {
+ first = 0;
+ }
+ if(last == std::string::npos)
+ {
+ last = output.size()-1;
+ }
+
+ std::string coutput = std::string(output, first, last-first+1);
+ this->Makefile->AddDefinition(output_variable.c_str(), coutput.c_str());
+ }
+
+ if ( return_variable.size() > 0 )
+ {
+ char buffer[100];
+ sprintf(buffer, "%d", retVal);
+ this->Makefile->AddDefinition(return_variable.c_str(), buffer);
+ }
+
+ return true;
+}
+
diff --git a/Source/cmExecProgramCommand.h b/Source/cmExecProgramCommand.h
new file mode 100644
index 000000000..723386099
--- /dev/null
+++ b/Source/cmExecProgramCommand.h
@@ -0,0 +1,95 @@
+/*============================================================================
+ 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 cmExecProgramCommand_h
+#define cmExecProgramCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmExecProgramCommand
+ * \brief Command that adds a target to the build system.
+ *
+ * cmExecProgramCommand adds an extra target to the build system.
+ * This is useful when you would like to add special
+ * targets like "install,", "clean," and so on.
+ */
+class cmExecProgramCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmExecProgramCommand;
+ }
+
+ /**
+ * 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 const char* GetName() const
+ {return "exec_program";}
+
+ /**
+ * 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 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);
+};
+
+#endif
diff --git a/Source/cmExecuteProcessCommand.cxx b/Source/cmExecuteProcessCommand.cxx
new file mode 100644
index 000000000..a0d9c9caf
--- /dev/null
+++ b/Source/cmExecuteProcessCommand.cxx
@@ -0,0 +1,422 @@
+/*============================================================================
+ 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 "cmExecuteProcessCommand.h"
+#include "cmSystemTools.h"
+
+#include <cmsys/Process.h>
+
+#include <ctype.h> /* isspace */
+
+static bool cmExecuteProcessCommandIsWhitespace(char c)
+{
+ return (isspace((int)c) || c == '\n' || c == '\r');
+}
+
+void cmExecuteProcessCommandFixText(std::vector<char>& output,
+ bool strip_trailing_whitespace);
+void cmExecuteProcessCommandAppend(std::vector<char>& output,
+ const char* data, int length);
+
+// cmExecuteProcessCommand
+bool cmExecuteProcessCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 1 )
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+ std::vector< std::vector<const char*> > cmds;
+ std::string arguments;
+ bool doing_command = false;
+ size_t command_index = 0;
+ bool output_quiet = false;
+ bool error_quiet = false;
+ bool output_strip_trailing_whitespace = false;
+ bool error_strip_trailing_whitespace = false;
+ std::string timeout_string;
+ std::string input_file;
+ std::string output_file;
+ std::string error_file;
+ std::string output_variable;
+ std::string error_variable;
+ std::string result_variable;
+ std::string working_directory;
+ for(size_t i=0; i < args.size(); ++i)
+ {
+ if(args[i] == "COMMAND")
+ {
+ doing_command = true;
+ command_index = cmds.size();
+ cmds.push_back(std::vector<const char*>());
+ }
+ else if(args[i] == "OUTPUT_VARIABLE")
+ {
+ doing_command = false;
+ if(++i < args.size())
+ {
+ output_variable = args[i];
+ }
+ else
+ {
+ this->SetError(" called with no value for OUTPUT_VARIABLE.");
+ return false;
+ }
+ }
+ else if(args[i] == "ERROR_VARIABLE")
+ {
+ doing_command = false;
+ if(++i < args.size())
+ {
+ error_variable = args[i];
+ }
+ else
+ {
+ this->SetError(" called with no value for ERROR_VARIABLE.");
+ return false;
+ }
+ }
+ else if(args[i] == "RESULT_VARIABLE")
+ {
+ doing_command = false;
+ if(++i < args.size())
+ {
+ result_variable = args[i];
+ }
+ else
+ {
+ this->SetError(" called with no value for RESULT_VARIABLE.");
+ return false;
+ }
+ }
+ else if(args[i] == "WORKING_DIRECTORY")
+ {
+ doing_command = false;
+ if(++i < args.size())
+ {
+ working_directory = args[i];
+ }
+ else
+ {
+ this->SetError(" called with no value for WORKING_DIRECTORY.");
+ return false;
+ }
+ }
+ else if(args[i] == "INPUT_FILE")
+ {
+ doing_command = false;
+ if(++i < args.size())
+ {
+ input_file = args[i];
+ }
+ else
+ {
+ this->SetError(" called with no value for INPUT_FILE.");
+ return false;
+ }
+ }
+ else if(args[i] == "OUTPUT_FILE")
+ {
+ doing_command = false;
+ if(++i < args.size())
+ {
+ output_file = args[i];
+ }
+ else
+ {
+ this->SetError(" called with no value for OUTPUT_FILE.");
+ return false;
+ }
+ }
+ else if(args[i] == "ERROR_FILE")
+ {
+ doing_command = false;
+ if(++i < args.size())
+ {
+ error_file = args[i];
+ }
+ else
+ {
+ this->SetError(" called with no value for ERROR_FILE.");
+ return false;
+ }
+ }
+ else if(args[i] == "TIMEOUT")
+ {
+ doing_command = false;
+ if(++i < args.size())
+ {
+ timeout_string = args[i];
+ }
+ else
+ {
+ this->SetError(" called with no value for TIMEOUT.");
+ return false;
+ }
+ }
+ else if(args[i] == "OUTPUT_QUIET")
+ {
+ doing_command = false;
+ output_quiet = true;
+ }
+ else if(args[i] == "ERROR_QUIET")
+ {
+ doing_command = false;
+ error_quiet = true;
+ }
+ else if(args[i] == "OUTPUT_STRIP_TRAILING_WHITESPACE")
+ {
+ doing_command = false;
+ output_strip_trailing_whitespace = true;
+ }
+ else if(args[i] == "ERROR_STRIP_TRAILING_WHITESPACE")
+ {
+ doing_command = false;
+ error_strip_trailing_whitespace = true;
+ }
+ else if(doing_command)
+ {
+ cmds[command_index].push_back(args[i].c_str());
+ }
+ else
+ {
+ cmOStringStream e;
+ e << " given unknown argument \"" << args[i] << "\".";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+
+ if ( !this->Makefile->CanIWriteThisFile(output_file.c_str()) )
+ {
+ std::string e = "attempted to output into a file: " + output_file
+ + " into a source directory.";
+ this->SetError(e.c_str());
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+
+ // Check for commands given.
+ if(cmds.empty())
+ {
+ this->SetError(" called with no COMMAND argument.");
+ return false;
+ }
+ for(unsigned int i=0; i < cmds.size(); ++i)
+ {
+ if(cmds[i].empty())
+ {
+ this->SetError(" given COMMAND argument with no value.");
+ return false;
+ }
+ else
+ {
+ // Add the null terminating pointer to the command argument list.
+ cmds[i].push_back(0);
+ }
+ }
+
+ // Parse the timeout string.
+ double timeout = -1;
+ if(!timeout_string.empty())
+ {
+ if(sscanf(timeout_string.c_str(), "%lg", &timeout) != 1)
+ {
+ this->SetError(" called with TIMEOUT value that could not be parsed.");
+ return false;
+ }
+ }
+
+ // Create a process instance.
+ cmsysProcess* cp = cmsysProcess_New();
+
+ // Set the command sequence.
+ for(unsigned int i=0; i < cmds.size(); ++i)
+ {
+ cmsysProcess_AddCommand(cp, &*cmds[i].begin());
+ }
+
+ // Set the process working directory.
+ if(!working_directory.empty())
+ {
+ cmsysProcess_SetWorkingDirectory(cp, working_directory.c_str());
+ }
+
+ // Always hide the process window.
+ 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);
+ }
+ if(!input_file.empty())
+ {
+ cmsysProcess_SetPipeFile(cp, cmsysProcess_Pipe_STDIN, input_file.c_str());
+ }
+ if(!output_file.empty())
+ {
+ cmsysProcess_SetPipeFile(cp, cmsysProcess_Pipe_STDOUT,
+ output_file.c_str());
+ }
+ if(!error_file.empty())
+ {
+ cmsysProcess_SetPipeFile(cp, cmsysProcess_Pipe_STDERR,
+ error_file.c_str());
+ }
+
+ // Set the timeout if any.
+ if(timeout >= 0)
+ {
+ cmsysProcess_SetTimeout(cp, timeout);
+ }
+
+ // Start the process.
+ cmsysProcess_Execute(cp);
+
+ // Read the process output.
+ std::vector<char> tempOutput;
+ std::vector<char> tempError;
+ int length;
+ char* data;
+ int p;
+ 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(output_variable.empty())
+ {
+ cmSystemTools::Stdout(data, length);
+ }
+ else
+ {
+ cmExecuteProcessCommandAppend(tempOutput, data, length);
+ }
+ }
+ else if(p == cmsysProcess_Pipe_STDERR && !error_quiet)
+ {
+ if(!error_variable.empty())
+ {
+ cmExecuteProcessCommandAppend(tempError, data, length);
+ }
+ }
+ }
+
+ // All output has been read. Wait for the process to exit.
+ cmsysProcess_WaitForExit(cp, 0);
+
+ // Fix the text in the output strings.
+ cmExecuteProcessCommandFixText(tempOutput,
+ output_strip_trailing_whitespace);
+ cmExecuteProcessCommandFixText(tempError,
+ error_strip_trailing_whitespace);
+
+ // Store the output obtained.
+ if(!output_variable.empty() && tempOutput.size())
+ {
+ this->Makefile->AddDefinition(output_variable.c_str(),
+ &*tempOutput.begin());
+ }
+ if(!merge_output && !error_variable.empty() && tempError.size())
+ {
+ this->Makefile->AddDefinition(error_variable.c_str(),
+ &*tempError.begin());
+ }
+
+ // Store the result of running the process.
+ if(!result_variable.empty())
+ {
+ switch(cmsysProcess_GetState(cp))
+ {
+ case cmsysProcess_State_Exited:
+ {
+ int v = cmsysProcess_GetExitValue(cp);
+ char buf[100];
+ sprintf(buf, "%d", v);
+ this->Makefile->AddDefinition(result_variable.c_str(), buf);
+ }
+ break;
+ case cmsysProcess_State_Exception:
+ this->Makefile->AddDefinition(result_variable.c_str(),
+ cmsysProcess_GetExceptionString(cp));
+ break;
+ case cmsysProcess_State_Error:
+ this->Makefile->AddDefinition(result_variable.c_str(),
+ cmsysProcess_GetErrorString(cp));
+ break;
+ case cmsysProcess_State_Expired:
+ this->Makefile->AddDefinition(result_variable.c_str(),
+ "Process terminated due to timeout");
+ break;
+ }
+ }
+
+ // Delete the process instance.
+ cmsysProcess_Delete(cp);
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+void cmExecuteProcessCommandFixText(std::vector<char>& output,
+ bool strip_trailing_whitespace)
+{
+ // Remove \0 characters and the \r part of \r\n pairs.
+ unsigned int in_index = 0;
+ unsigned int out_index = 0;
+ while(in_index < output.size())
+ {
+ char c = output[in_index++];
+ if((c != '\r' || !(in_index < output.size() && output[in_index] == '\n'))
+ && c != '\0')
+ {
+ output[out_index++] = c;
+ }
+ }
+
+ // Remove trailing whitespace if requested.
+ if(strip_trailing_whitespace)
+ {
+ while(out_index > 0 &&
+ cmExecuteProcessCommandIsWhitespace(output[out_index-1]))
+ {
+ --out_index;
+ }
+ }
+
+ // Shrink the vector to the size needed.
+ output.resize(out_index);
+
+ // Put a terminator on the text string.
+ output.push_back('\0');
+}
+
+//----------------------------------------------------------------------------
+void cmExecuteProcessCommandAppend(std::vector<char>& output,
+ const char* data, int length)
+{
+#if defined(__APPLE__)
+ // HACK on Apple to work around bug with inserting at the
+ // end of an empty vector. This resulted in random failures
+ // that were hard to reproduce.
+ if(output.empty() && length > 0)
+ {
+ output.push_back(data[0]);
+ ++data;
+ --length;
+ }
+#endif
+ output.insert(output.end(), data, data+length);
+}
diff --git a/Source/cmExecuteProcessCommand.h b/Source/cmExecuteProcessCommand.h
new file mode 100644
index 000000000..0e20a4b19
--- /dev/null
+++ b/Source/cmExecuteProcessCommand.h
@@ -0,0 +1,113 @@
+/*============================================================================
+ 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 cmExecuteProcessCommand_h
+#define cmExecuteProcessCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmExecuteProcessCommand
+ * \brief Command that adds a target to the build system.
+ *
+ * cmExecuteProcessCommand is a CMake language interface to the KWSys
+ * Process Execution implementation.
+ */
+class cmExecuteProcessCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmExecuteProcessCommand;
+ }
+
+ /**
+ * 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 const char* GetName() const
+ {return "execute_process";}
+
+ /**
+ * 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 "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);
+};
+
+#endif
diff --git a/Source/cmExecutionStatus.h b/Source/cmExecutionStatus.h
new file mode 100644
index 000000000..9fbecacfe
--- /dev/null
+++ b/Source/cmExecutionStatus.h
@@ -0,0 +1,55 @@
+/*============================================================================
+ 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 cmExecutionStatus_h
+#define cmExecutionStatus_h
+
+#include "cmObject.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
+{
+public:
+ cmTypeMacro(cmExecutionStatus, cmObject);
+
+ cmExecutionStatus() { this->Clear();};
+
+ virtual void SetReturnInvoked(bool val)
+ { this->ReturnInvoked = val; }
+ virtual bool GetReturnInvoked()
+ { return this->ReturnInvoked; }
+
+ virtual void SetBreakInvoked(bool val)
+ { this->BreakInvoked = val; }
+ virtual bool GetBreakInvoked()
+ { return this->BreakInvoked; }
+
+ virtual void Clear()
+ {
+ this->ReturnInvoked = false;
+ this->BreakInvoked = false;
+ this->NestedError = false;
+ }
+ virtual void SetNestedError(bool val) { this->NestedError = val; }
+ virtual bool GetNestedError() { return this->NestedError; }
+
+
+protected:
+ bool ReturnInvoked;
+ bool BreakInvoked;
+ bool NestedError;
+};
+
+#endif
diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx
new file mode 100644
index 000000000..32595ee4b
--- /dev/null
+++ b/Source/cmExportBuildFileGenerator.cxx
@@ -0,0 +1,152 @@
+/*============================================================================
+ 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 "cmExportBuildFileGenerator.h"
+
+#include "cmExportCommand.h"
+
+//----------------------------------------------------------------------------
+cmExportBuildFileGenerator::cmExportBuildFileGenerator()
+{
+ this->ExportCommand = 0;
+}
+
+//----------------------------------------------------------------------------
+bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
+{
+ // Create all the imported targets.
+ for(std::vector<cmTarget*>::const_iterator
+ tei = this->Exports->begin();
+ tei != this->Exports->end(); ++tei)
+ {
+ cmTarget* te = *tei;
+ if(this->ExportedTargets.insert(te).second)
+ {
+ this->GenerateImportTargetCode(os, te);
+ }
+ else
+ {
+ if(this->ExportCommand && this->ExportCommand->ErrorMessage.empty())
+ {
+ cmOStringStream e;
+ e << "given target \"" << te->GetName() << "\" more than once.";
+ this->ExportCommand->ErrorMessage = e.str();
+ }
+ return false;
+ }
+ }
+
+ // Generate import file content for each configuration.
+ for(std::vector<std::string>::const_iterator
+ ci = this->Configurations.begin();
+ ci != this->Configurations.end(); ++ci)
+ {
+ this->GenerateImportConfig(os, ci->c_str());
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+void
+cmExportBuildFileGenerator
+::GenerateImportTargetsConfig(std::ostream& os,
+ const char* config, std::string const& suffix)
+{
+ for(std::vector<cmTarget*>::const_iterator
+ tei = this->Exports->begin();
+ tei != this->Exports->end(); ++tei)
+ {
+ // Collect import properties for this target.
+ cmTarget* target = *tei;
+ ImportPropertyMap properties;
+ this->SetImportLocationProperty(config, suffix, target, properties);
+ if(!properties.empty())
+ {
+ // Get the rest of the target details.
+ this->SetImportDetailProperties(config, suffix,
+ target, properties);
+
+ // TOOD: PUBLIC_HEADER_LOCATION
+ // This should wait until the build feature propagation stuff
+ // is done. Then this can be a propagated include directory.
+ // this->GenerateImportProperty(config, te->HeaderGenerator,
+ // properties);
+
+ // Generate code in the export file.
+ this->GenerateImportPropertyCode(os, config, target, properties);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmExportBuildFileGenerator
+::SetImportLocationProperty(const char* config, std::string const& suffix,
+ cmTarget* target, ImportPropertyMap& properties)
+{
+ // Get the makefile in which to lookup target information.
+ cmMakefile* mf = target->GetMakefile();
+
+ // Add the main target file.
+ {
+ std::string prop = "IMPORTED_LOCATION";
+ prop += suffix;
+ std::string value;
+ if(target->IsFrameworkOnApple() || target->IsAppBundleOnApple())
+ {
+ value = target->GetFullPath(config, false);
+ }
+ else
+ {
+ value = target->GetFullPath(config, false, true);
+ }
+ 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 ||
+ target->IsExecutableWithExports()) &&
+ mf->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX"))
+ {
+ std::string prop = "IMPORTED_IMPLIB";
+ prop += suffix;
+ std::string value = target->GetFullPath(config, true);
+ target->GetImplibGNUtoMS(value, value,
+ "${CMAKE_IMPORT_LIBRARY_SUFFIX}");
+ properties[prop] = value;
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmExportBuildFileGenerator
+::ComplainAboutMissingTarget(cmTarget* depender,
+ cmTarget* dependee)
+{
+ if(!this->ExportCommand || !this->ExportCommand->ErrorMessage.empty())
+ {
+ 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, "
+ << "consider using the APPEND option with multiple separate calls.";
+ this->ExportCommand->ErrorMessage = e.str();
+}
diff --git a/Source/cmExportBuildFileGenerator.h b/Source/cmExportBuildFileGenerator.h
new file mode 100644
index 000000000..0f37626cc
--- /dev/null
+++ b/Source/cmExportBuildFileGenerator.h
@@ -0,0 +1,61 @@
+/*============================================================================
+ 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 cmExportBuildFileGenerator_h
+#define cmExportBuildFileGenerator_h
+
+#include "cmExportFileGenerator.h"
+
+class cmExportCommand;
+
+/** \class cmExportBuildFileGenerator
+ * \brief Generate a file exporting targets from a build tree.
+ *
+ * cmExportBuildFileGenerator generates a file exporting targets from
+ * a build tree. A single file exports information for all
+ * configurations built.
+ *
+ * This is used to implement the EXPORT() command.
+ */
+class cmExportBuildFileGenerator: public cmExportFileGenerator
+{
+public:
+ cmExportBuildFileGenerator();
+
+ /** Set the list of targets to export. */
+ void SetExports(std::vector<cmTarget*> const* exports)
+ { this->Exports = exports; }
+
+ /** 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; }
+protected:
+ // Implement virtual methods from the superclass.
+ virtual bool GenerateMainFile(std::ostream& os);
+ virtual void GenerateImportTargetsConfig(std::ostream& os,
+ const char* config,
+ std::string const& suffix);
+ virtual void ComplainAboutMissingTarget(cmTarget* depender,
+ cmTarget* dependee);
+
+ /** Fill in properties indicating built file locations. */
+ void SetImportLocationProperty(const char* config,
+ std::string const& suffix,
+ cmTarget* target,
+ ImportPropertyMap& properties);
+
+ std::vector<cmTarget*> const* Exports;
+ cmExportCommand* ExportCommand;
+};
+
+#endif
diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx
new file mode 100644
index 000000000..1cc17545a
--- /dev/null
+++ b/Source/cmExportCommand.cxx
@@ -0,0 +1,347 @@
+/*============================================================================
+ 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 "cmExportCommand.h"
+#include "cmGlobalGenerator.h"
+#include "cmLocalGenerator.h"
+#include "cmGeneratedFileStream.h"
+#include "cmake.h"
+
+#include <cmsys/RegularExpression.hxx>
+
+#include "cmExportBuildFileGenerator.h"
+
+#if defined(__HAIKU__)
+#include <StorageKit.h>
+#endif
+
+cmExportCommand::cmExportCommand()
+:cmCommand()
+,ArgumentGroup()
+,Targets(&Helper, "TARGETS")
+,Append(&Helper, "APPEND", &ArgumentGroup)
+,Namespace(&Helper, "NAMESPACE", &ArgumentGroup)
+,Filename(&Helper, "FILE", &ArgumentGroup)
+{
+ // at first TARGETS
+ this->Targets.Follows(0);
+ // and after that the other options in any order
+ this->ArgumentGroup.Follows(&this->Targets);
+}
+
+
+// cmExportCommand
+bool cmExportCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 2 )
+ {
+ this->SetError("called with too few arguments");
+ return false;
+ }
+
+ if(args[0] == "PACKAGE")
+ {
+ return this->HandlePackage(args);
+ }
+
+ std::vector<std::string> unknownArgs;
+ this->Helper.Parse(&args, &unknownArgs);
+
+ if (!unknownArgs.empty())
+ {
+ this->SetError("Unknown arguments.");
+ return false;
+ }
+
+ if (this->Targets.WasFound() == false)
+ {
+ this->SetError("TARGETS option missing.");
+ return false;
+ }
+
+ if(!this->Filename.WasFound())
+ {
+ this->SetError("FILE <filename> option missing.");
+ return false;
+ }
+
+ // Make sure the file has a .cmake extension.
+ if(cmSystemTools::GetFilenameLastExtension(this->Filename.GetCString())
+ != ".cmake")
+ {
+ 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;
+ }
+
+ // 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;
+ e << "FILE option given filename \"" << fname
+ << "\" which is in the source tree.\n";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+ else
+ {
+ // Interpret relative paths with respect to the current build dir.
+ fname = this->Makefile->GetCurrentOutputDirectory();
+ fname += "/";
+ fname += this->Filename.GetString();
+ }
+
+ // 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)
+ {
+ if(cmTarget* target =
+ this->Makefile->GetLocalGenerator()->
+ GetGlobalGenerator()->FindTarget(0, currentTarget->c_str()))
+ {
+ 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)
+ {
+ cmOStringStream e;
+ e << "given OBJECT library \"" << *currentTarget
+ << "\" which may not be exported.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "given target \"" << *currentTarget
+ << "\" which is not an executable or library.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "given target \"" << *currentTarget
+ << "\" which is not built by this project.";
+ this->SetError(e.str().c_str());
+ 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);
+
+ // Compute the set of configurations exported.
+ std::vector<std::string> configurationTypes;
+ this->Makefile->GetConfigurations(configurationTypes);
+ if(!configurationTypes.empty())
+ {
+ for(std::vector<std::string>::const_iterator
+ ci = configurationTypes.begin();
+ ci != configurationTypes.end(); ++ci)
+ {
+ ebfg.AddConfiguration(ci->c_str());
+ }
+ }
+ else
+ {
+ ebfg.AddConfiguration("");
+ }
+
+ // Generate the import file.
+ if(!ebfg.GenerateImportFile() && this->ErrorMessage.empty())
+ {
+ this->SetError("could not write export file.");
+ return false;
+ }
+
+ // Report generated error message if any.
+ if(!this->ErrorMessage.empty())
+ {
+ this->SetError(this->ErrorMessage.c_str());
+ return false;
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmExportCommand::HandlePackage(std::vector<std::string> const& args)
+{
+ // Parse PACKAGE mode arguments.
+ enum Doing { DoingNone, DoingPackage };
+ Doing doing = DoingPackage;
+ std::string package;
+ for(unsigned int i=1; i < args.size(); ++i)
+ {
+ if(doing == DoingPackage)
+ {
+ package = args[i];
+ doing = DoingNone;
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "PACKAGE given unknown argumsnt: " << args[i];
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+
+ // Verify the package name.
+ if(package.empty())
+ {
+ this->SetError("PACKAGE must be given a package name.");
+ return false;
+ }
+ const char* packageExpr = "^[A-Za-z0-9_.-]+$";
+ cmsys::RegularExpression packageRegex(packageExpr);
+ if(!packageRegex.find(package.c_str()))
+ {
+ cmOStringStream e;
+ e << "PACKAGE given invalid package name \"" << package << "\". "
+ << "Package names must match \"" << packageExpr << "\".";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+
+ // 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();
+ std::string hash = cmSystemTools::ComputeStringMD5(outDir);
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ this->StorePackageRegistryWin(package, outDir, hash.c_str());
+#else
+ this->StorePackageRegistryDir(package, outDir, hash.c_str());
+#endif
+
+ return true;
+}
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+# include <windows.h>
+# undef GetCurrentDirectory
+//----------------------------------------------------------------------------
+void cmExportCommand::ReportRegistryError(std::string const& msg,
+ std::string const& key,
+ long err)
+{
+ cmOStringStream e;
+ e << msg << "\n"
+ << " HKEY_CURRENT_USER\\" << key << "\n";
+ char winmsg[1024];
+ if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS, 0, err,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ winmsg, 1024, 0) > 0)
+ {
+ e << "Windows reported:\n"
+ << " " << winmsg;
+ }
+ this->Makefile->IssueMessage(cmake::WARNING, e.str());
+}
+
+//----------------------------------------------------------------------------
+void cmExportCommand::StorePackageRegistryWin(std::string const& package,
+ const char* content,
+ const char* hash)
+{
+ 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,
+ KEY_SET_VALUE, 0, &hKey, 0);
+ if(err != ERROR_SUCCESS)
+ {
+ this->ReportRegistryError(
+ "Cannot create/open registry key", key, err);
+ return;
+ }
+ err = RegSetValueEx(hKey, hash, 0, REG_SZ, (BYTE const*)content,
+ static_cast<DWORD>(strlen(content)+1));
+ RegCloseKey(hKey);
+ if(err != ERROR_SUCCESS)
+ {
+ cmOStringStream msg;
+ msg << "Cannot set registry value \"" << hash << "\" under key";
+ this->ReportRegistryError(msg.str(), key, err);
+ return;
+ }
+}
+#else
+//----------------------------------------------------------------------------
+void cmExportCommand::StorePackageRegistryDir(std::string const& package,
+ const char* content,
+ const char* hash)
+{
+#if defined(__HAIKU__)
+ BPath dir;
+ if (find_directory(B_USER_SETTINGS_DIRECTORY, &dir) != B_OK)
+ {
+ return;
+ }
+ dir.Append("cmake/packages");
+ dir.Append(package.c_str());
+ std::string fname = dir.Path();
+#else
+ const char* home = cmSystemTools::GetEnv("HOME");
+ if(!home)
+ {
+ return;
+ }
+ std::string fname = home;
+ cmSystemTools::ConvertToUnixSlashes(fname);
+ fname += "/.cmake/packages/";
+ fname += package;
+#endif
+ cmSystemTools::MakeDirectory(fname.c_str());
+ fname += "/";
+ fname += hash;
+ if(!cmSystemTools::FileExists(fname.c_str()))
+ {
+ cmGeneratedFileStream entry(fname.c_str(), true);
+ if(entry)
+ {
+ entry << content << "\n";
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "Cannot create package registry file:\n"
+ << " " << fname << "\n"
+ << cmSystemTools::GetLastSystemError() << "\n";
+ this->Makefile->IssueMessage(cmake::WARNING, e.str());
+ }
+ }
+}
+#endif
diff --git a/Source/cmExportCommand.h b/Source/cmExportCommand.h
new file mode 100644
index 000000000..ae67b4762
--- /dev/null
+++ b/Source/cmExportCommand.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 cmExportCommand_h
+#define cmExportCommand_h
+
+#include "cmCommand.h"
+#include "cmDocumentLocationUndefined.h"
+
+class cmExportBuildFileGenerator;
+
+/** \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 cmExportCommand : public cmCommand
+{
+public:
+ cmExportCommand();
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmExportCommand;
+ }
+
+ /**
+ * 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 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>)\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. "
+ "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."
+ ;
+ }
+
+ cmTypeMacro(cmExportCommand, cmCommand);
+
+private:
+ cmCommandArgumentGroup ArgumentGroup;
+ cmCAStringVector Targets;
+ cmCAEnabler Append;
+ cmCAString Namespace;
+ cmCAString Filename;
+
+ friend class cmExportBuildFileGenerator;
+ std::string ErrorMessage;
+
+ bool HandlePackage(std::vector<std::string> const& args);
+ void StorePackageRegistryWin(std::string const& package,
+ const char* content, const char* hash);
+ void StorePackageRegistryDir(std::string const& package,
+ const char* content, const char* hash);
+ void ReportRegistryError(std::string const& msg, std::string const& key,
+ long err);
+};
+
+
+#endif
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
new file mode 100644
index 000000000..eb19df5e2
--- /dev/null
+++ b/Source/cmExportFileGenerator.cxx
@@ -0,0 +1,443 @@
+/*============================================================================
+ 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 "cmExportFileGenerator.h"
+
+#include "cmGeneratedFileStream.h"
+#include "cmMakefile.h"
+#include "cmSystemTools.h"
+#include "cmTarget.h"
+#include "cmVersion.h"
+
+#include <cmsys/auto_ptr.hxx>
+
+//----------------------------------------------------------------------------
+cmExportFileGenerator::cmExportFileGenerator()
+{
+ this->AppendMode = false;
+}
+
+//----------------------------------------------------------------------------
+void cmExportFileGenerator::AddConfiguration(const char* config)
+{
+ this->Configurations.push_back(config);
+}
+
+//----------------------------------------------------------------------------
+void cmExportFileGenerator::SetExportFile(const char* mainFile)
+{
+ this->MainImportFile = mainFile;
+ this->FileDir =
+ cmSystemTools::GetFilenamePath(this->MainImportFile);
+ this->FileBase =
+ cmSystemTools::GetFilenameWithoutLastExtension(this->MainImportFile);
+ this->FileExt =
+ cmSystemTools::GetFilenameLastExtension(this->MainImportFile);
+}
+
+//----------------------------------------------------------------------------
+bool cmExportFileGenerator::GenerateImportFile()
+{
+ // Open the output file to generate it.
+ cmsys::auto_ptr<std::ofstream> foutPtr;
+ if(this->AppendMode)
+ {
+ // Open for append.
+ cmsys::auto_ptr<std::ofstream>
+ ap(new std::ofstream(this->MainImportFile.c_str(), std::ios::app));
+ foutPtr = ap;
+ }
+ else
+ {
+ // Generate atomically and with copy-if-different.
+ cmsys::auto_ptr<cmGeneratedFileStream>
+ ap(new cmGeneratedFileStream(this->MainImportFile.c_str(), true));
+ ap->SetCopyIfDifferent(true);
+ foutPtr = ap;
+ }
+ if(!foutPtr.get() || !*foutPtr)
+ {
+ std::string se = cmSystemTools::GetLastSystemError();
+ cmOStringStream e;
+ e << "cannot write to file \"" << this->MainImportFile
+ << "\": " << se;
+ cmSystemTools::Error(e.str().c_str());
+ return false;
+ }
+ std::ostream& os = *foutPtr;
+
+ // Protect that file against use with older CMake versions.
+ os << "# Generated by CMake " << cmVersion::GetCMakeVersion() << "\n\n";
+ os << "IF(\"${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}\" LESS 2.5)\n"
+ << " MESSAGE(FATAL_ERROR \"CMake >= 2.6.0 required\")\n"
+ << "ENDIF(\"${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}\" LESS 2.5)\n";
+
+ // Isolate the file policy level.
+ // We use 2.6 here instead of the current version because newer
+ // versions of CMake should be able to export files imported by 2.6
+ // until the import format changes.
+ os << "CMAKE_POLICY(PUSH)\n"
+ << "CMAKE_POLICY(VERSION 2.6)\n";
+
+ // Start with the import file header.
+ this->GenerateImportHeaderCode(os);
+
+ // Create all the imported targets.
+ bool result = this->GenerateMainFile(os);
+
+ // End with the import file footer.
+ this->GenerateImportFooterCode(os);
+ os << "CMAKE_POLICY(POP)\n";
+
+ return result;
+}
+
+//----------------------------------------------------------------------------
+void cmExportFileGenerator::GenerateImportConfig(std::ostream& os,
+ const char* config)
+{
+ // Construct the property configuration suffix.
+ std::string suffix = "_";
+ if(config && *config)
+ {
+ suffix += cmSystemTools::UpperCase(config);
+ }
+ else
+ {
+ suffix += "NOCONFIG";
+ }
+
+ // Generate the per-config target information.
+ this->GenerateImportTargetsConfig(os, config, suffix);
+}
+
+//----------------------------------------------------------------------------
+void
+cmExportFileGenerator
+::SetImportDetailProperties(const char* config, std::string const& suffix,
+ cmTarget* target, ImportPropertyMap& properties)
+{
+ // Get the makefile in which to lookup target information.
+ cmMakefile* mf = target->GetMakefile();
+
+ // Add the soname for unix shared libraries.
+ if(target->GetType() == cmTarget::SHARED_LIBRARY ||
+ target->GetType() == cmTarget::MODULE_LIBRARY)
+ {
+ // Check whether this is a DLL platform.
+ bool dll_platform =
+ (mf->IsOn("WIN32") || mf->IsOn("CYGWIN") || mf->IsOn("MINGW"));
+ if(!dll_platform)
+ {
+ std::string prop;
+ std::string value;
+ if(target->HasSOName(config))
+ {
+ prop = "IMPORTED_SONAME";
+ value = target->GetSOName(config);
+ }
+ else
+ {
+ prop = "IMPORTED_NO_SONAME";
+ value = "TRUE";
+ }
+ prop += suffix;
+ properties[prop] = value;
+ }
+ }
+
+ // Add the transitive link dependencies for this configuration.
+ if(cmTarget::LinkInterface const* iface = target->GetLinkInterface(config))
+ {
+ this->SetImportLinkProperty(suffix, target,
+ "IMPORTED_LINK_INTERFACE_LANGUAGES",
+ iface->Languages, properties);
+ this->SetImportLinkProperty(suffix, target,
+ "IMPORTED_LINK_INTERFACE_LIBRARIES",
+ iface->Libraries, properties);
+ this->SetImportLinkProperty(suffix, target,
+ "IMPORTED_LINK_DEPENDENT_LIBRARIES",
+ iface->SharedDeps, properties);
+ if(iface->Multiplicity > 0)
+ {
+ std::string prop = "IMPORTED_LINK_INTERFACE_MULTIPLICITY";
+ prop += suffix;
+ cmOStringStream m;
+ m << iface->Multiplicity;
+ properties[prop] = m.str();
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmExportFileGenerator
+::SetImportLinkProperty(std::string const& suffix,
+ cmTarget* target,
+ const char* propName,
+ std::vector<std::string> const& libs,
+ ImportPropertyMap& properties)
+{
+ // Skip the property if there are no libraries.
+ if(libs.empty())
+ {
+ return;
+ }
+
+ // Get the makefile in which to lookup target information.
+ cmMakefile* mf = target->GetMakefile();
+
+ // Construct the property value.
+ std::string link_libs;
+ const char* sep = "";
+ for(std::vector<std::string>::const_iterator li = libs.begin();
+ li != libs.end(); ++li)
+ {
+ // Separate this from the previous entry.
+ link_libs += sep;
+ sep = ";";
+
+ // Append this entry.
+ if(cmTarget* tgt = mf->FindTargetToUse(li->c_str()))
+ {
+ // This is a target.
+ if(tgt->IsImported())
+ {
+ // The target is imported (and therefore is not in the
+ // export). Append the raw name.
+ link_libs += *li;
+ }
+ else if(this->ExportedTargets.find(tgt) != this->ExportedTargets.end())
+ {
+ // The target is in the export. Append it with the export
+ // namespace.
+ link_libs += this->Namespace;
+ link_libs += *li;
+ }
+ else
+ {
+ // 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(target, tgt);
+ }
+ // Assume the target will be exported by another command.
+ // Append it with the export namespace.
+ link_libs += this->Namespace;
+ link_libs += *li;
+ }
+ }
+ else
+ {
+ // Append the raw name.
+ link_libs += *li;
+ }
+ }
+
+ // Store the property.
+ std::string prop = propName;
+ prop += suffix;
+ properties[prop] = link_libs;
+}
+
+//----------------------------------------------------------------------------
+void cmExportFileGenerator::GenerateImportHeaderCode(std::ostream& os,
+ const char* config)
+{
+ os << "#----------------------------------------------------------------\n"
+ << "# Generated CMake target import file";
+ if(config)
+ {
+ os << " for configuration \"" << config << "\".\n";
+ }
+ else
+ {
+ os << ".\n";
+ }
+ os << "#----------------------------------------------------------------\n"
+ << "\n";
+ this->GenerateImportVersionCode(os);
+}
+
+//----------------------------------------------------------------------------
+void cmExportFileGenerator::GenerateImportFooterCode(std::ostream& os)
+{
+ os << "# Commands beyond this point should not need to know the version.\n"
+ << "SET(CMAKE_IMPORT_FILE_VERSION)\n";
+}
+
+//----------------------------------------------------------------------------
+void cmExportFileGenerator::GenerateImportVersionCode(std::ostream& os)
+{
+ // Store an import file format version. This will let us change the
+ // format later while still allowing old import files to work.
+ os << "# Commands may need to know the format version.\n"
+ << "SET(CMAKE_IMPORT_FILE_VERSION 1)\n"
+ << "\n";
+}
+
+//----------------------------------------------------------------------------
+void
+cmExportFileGenerator
+::GenerateImportTargetCode(std::ostream& os, cmTarget* target)
+{
+ // Construct the imported target name.
+ std::string targetName = this->Namespace;
+ targetName += target->GetName();
+
+ // Create the imported target.
+ os << "# Create imported target " << targetName << "\n";
+ switch(target->GetType())
+ {
+ case cmTarget::EXECUTABLE:
+ os << "ADD_EXECUTABLE(" << targetName << " IMPORTED)\n";
+ break;
+ case cmTarget::STATIC_LIBRARY:
+ os << "ADD_LIBRARY(" << targetName << " STATIC IMPORTED)\n";
+ break;
+ case cmTarget::SHARED_LIBRARY:
+ os << "ADD_LIBRARY(" << targetName << " SHARED IMPORTED)\n";
+ break;
+ case cmTarget::MODULE_LIBRARY:
+ os << "ADD_LIBRARY(" << targetName << " MODULE IMPORTED)\n";
+ break;
+ default: // should never happen
+ break;
+ }
+
+ // Mark the imported executable if it has exports.
+ if(target->IsExecutableWithExports())
+ {
+ os << "SET_PROPERTY(TARGET " << targetName
+ << " PROPERTY ENABLE_EXPORTS 1)\n";
+ }
+
+ // Mark the imported library if it is a framework.
+ if(target->IsFrameworkOnApple())
+ {
+ os << "SET_PROPERTY(TARGET " << targetName
+ << " PROPERTY FRAMEWORK 1)\n";
+ }
+
+ // Mark the imported executable if it is an application bundle.
+ if(target->IsAppBundleOnApple())
+ {
+ os << "SET_PROPERTY(TARGET " << targetName
+ << " PROPERTY MACOSX_BUNDLE 1)\n";
+ }
+
+ if (target->IsCFBundleOnApple())
+ {
+ os << "SET_PROPERTY(TARGET " << targetName
+ << " PROPERTY BUNDLE 1)\n";
+ }
+ os << "\n";
+}
+
+//----------------------------------------------------------------------------
+void
+cmExportFileGenerator
+::GenerateImportPropertyCode(std::ostream& os, const char* config,
+ cmTarget* target,
+ ImportPropertyMap const& properties)
+{
+ // Construct the imported target name.
+ std::string targetName = this->Namespace;
+ targetName += target->GetName();
+
+ // Set the import properties.
+ os << "# Import target \"" << targetName << "\" for configuration \""
+ << config << "\"\n";
+ os << "SET_PROPERTY(TARGET " << targetName
+ << " APPEND PROPERTY IMPORTED_CONFIGURATIONS ";
+ if(config && *config)
+ {
+ os << cmSystemTools::UpperCase(config);
+ }
+ else
+ {
+ os << "NOCONFIG";
+ }
+ os << ")\n";
+ os << "SET_TARGET_PROPERTIES(" << targetName << " PROPERTIES\n";
+ for(ImportPropertyMap::const_iterator pi = properties.begin();
+ pi != properties.end(); ++pi)
+ {
+ os << " " << pi->first << " \"" << pi->second << "\"\n";
+ }
+ os << " )\n"
+ << "\n";
+}
+
+
+//----------------------------------------------------------------------------
+void
+cmExportFileGenerator::GenerateImportedFileCheckLoop(std::ostream& os)
+{
+ // Add code which verifies at cmake time that the file which is being
+ // imported actually exists on disk. This should in theory always be theory
+ // case, but still when packages are split into normal and development
+ // packages this might get broken (e.g. the Config.cmake could be part of
+ // the non-development package, something similar happened to me without
+ // on SUSE with a mysql pkg-config file, which claimed everything is fine,
+ // but the development package was not installed.).
+ os << "# Loop over all imported files and verify that they actually exist\n"
+ "FOREACH(target ${_IMPORT_CHECK_TARGETS} )\n"
+ " FOREACH(file ${_IMPORT_CHECK_FILES_FOR_${target}} )\n"
+ " IF(NOT EXISTS \"${file}\" )\n"
+ " MESSAGE(FATAL_ERROR \"The imported target \\\"${target}\\\""
+ " references the file\n"
+ " \\\"${file}\\\"\n"
+ "but this file does not exist. Possible reasons include:\n"
+ "* The file 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 contained\n"
+ " \\\"${CMAKE_CURRENT_LIST_FILE}\\\"\n"
+ "but not all the files it references.\n"
+ "\")\n"
+ " ENDIF()\n"
+ " ENDFOREACH()\n"
+ " UNSET(_IMPORT_CHECK_FILES_FOR_${target})\n"
+ "ENDFOREACH()\n"
+ "UNSET(_IMPORT_CHECK_TARGETS)\n"
+ "\n";
+}
+
+
+//----------------------------------------------------------------------------
+void
+cmExportFileGenerator
+::GenerateImportedFileChecksCode(std::ostream& os, cmTarget* target,
+ ImportPropertyMap const& properties,
+ const std::set<std::string>& importedLocations)
+{
+ // Construct the imported target name.
+ std::string targetName = this->Namespace;
+ targetName += target->GetName();
+
+ os << "LIST(APPEND _IMPORT_CHECK_TARGETS " << targetName << " )\n"
+ "LIST(APPEND _IMPORT_CHECK_FILES_FOR_" << targetName << " ";
+
+ for(std::set<std::string>::const_iterator li = importedLocations.begin();
+ li != importedLocations.end();
+ ++li)
+ {
+ ImportPropertyMap::const_iterator pi = properties.find(*li);
+ if (pi != properties.end())
+ {
+ os << "\"" << pi->second << "\" ";
+ }
+ }
+
+ os << ")\n\n";
+}
diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h
new file mode 100644
index 000000000..f271e5570
--- /dev/null
+++ b/Source/cmExportFileGenerator.h
@@ -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.
+============================================================================*/
+#ifndef cmExportFileGenerator_h
+#define cmExportFileGenerator_h
+
+#include "cmCommand.h"
+
+/** \class cmExportFileGenerator
+ * \brief Generate a file exporting targets from a build or install tree.
+ *
+ * cmExportFileGenerator is the superclass for
+ * cmExportBuildFileGenerator and cmExportInstallFileGenerator. It
+ * contains common code generation routines for the two kinds of
+ * export implementations.
+ */
+class cmExportFileGenerator
+{
+public:
+ cmExportFileGenerator();
+ virtual ~cmExportFileGenerator() {}
+
+ /** Set the full path to the export file to generate. */
+ void SetExportFile(const char* mainFile);
+
+ /** Set the namespace in which to place exported target names. */
+ void SetNamespace(const char* ns) { this->Namespace = ns; }
+
+ /** Add a configuration to be exported. */
+ void AddConfiguration(const char* config);
+
+ /** Actually generate the export file. Returns whether there was an
+ error. */
+ bool GenerateImportFile();
+protected:
+
+ typedef std::map<cmStdString, cmStdString> ImportPropertyMap;
+
+ // Generate per-configuration target information to the given output
+ // stream.
+ void GenerateImportConfig(std::ostream& os, const char* config);
+
+ // Methods to implement export file code generation.
+ void GenerateImportHeaderCode(std::ostream& os, const char* config = 0);
+ 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,
+ ImportPropertyMap const& properties);
+ void GenerateImportedFileChecksCode(std::ostream& os, cmTarget* target,
+ ImportPropertyMap const& properties,
+ const std::set<std::string>& importedLocations);
+ void GenerateImportedFileCheckLoop(std::ostream& os);
+
+
+ // Collect properties with detailed information about targets beyond
+ // their location on disk.
+ void SetImportDetailProperties(const char* config,
+ std::string const& suffix, cmTarget* target,
+ ImportPropertyMap& properties);
+ void SetImportLinkProperty(std::string const& suffix,
+ cmTarget* target, const char* propName,
+ std::vector<std::string> const& libs,
+ ImportPropertyMap& properties);
+
+ /** Each subclass knows how to generate its kind of export file. */
+ virtual bool GenerateMainFile(std::ostream& os) = 0;
+
+ /** Each subclass knows where the target files are located. */
+ virtual void GenerateImportTargetsConfig(std::ostream& os,
+ const char* config,
+ std::string const& suffix) = 0;
+
+ /** Each subclass knows how to complain about a target that is
+ missing from an export set. */
+ virtual void ComplainAboutMissingTarget(cmTarget* depender,
+ cmTarget* dependee) = 0;
+
+ // The namespace in which the exports are placed in the generated file.
+ std::string Namespace;
+
+ // The set of configurations to export.
+ std::vector<std::string> Configurations;
+
+ // The file to generate.
+ std::string MainImportFile;
+ std::string FileDir;
+ std::string FileBase;
+ std::string FileExt;
+ bool AppendMode;
+
+ // The set of targets included in the export.
+ std::set<cmTarget*> ExportedTargets;
+};
+
+#endif
diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx
new file mode 100644
index 000000000..da14dd787
--- /dev/null
+++ b/Source/cmExportInstallFileGenerator.cxx
@@ -0,0 +1,333 @@
+/*============================================================================
+ 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 "cmExportInstallFileGenerator.h"
+
+#include "cmGeneratedFileStream.h"
+#include "cmInstallExportGenerator.h"
+#include "cmInstallTargetGenerator.h"
+
+//----------------------------------------------------------------------------
+cmExportInstallFileGenerator
+::cmExportInstallFileGenerator(cmInstallExportGenerator* iegen):
+ InstallExportGenerator(iegen)
+{
+}
+
+//----------------------------------------------------------------------------
+std::string cmExportInstallFileGenerator::GetConfigImportFileGlob()
+{
+ std::string glob = this->FileBase;
+ glob += "-*";
+ glob += this->FileExt;
+ return glob;
+}
+
+//----------------------------------------------------------------------------
+bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
+{
+ // Create all the imported targets.
+ for(std::vector<cmTargetExport*>::const_iterator
+ tei = this->ExportSet->begin();
+ tei != this->ExportSet->end(); ++tei)
+ {
+ cmTargetExport* te = *tei;
+ if(this->ExportedTargets.insert(te->Target).second)
+ {
+ this->GenerateImportTargetCode(os, te->Target);
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "INSTALL(EXPORT \"" << this->Name << "\" ...) "
+ << "includes target \"" << te->Target->GetName()
+ << "\" more than once in the export set.";
+ cmSystemTools::Error(e.str().c_str());
+ return false;
+ }
+ }
+
+ // Now load per-configuration properties for them.
+ os << "# Load information for each installed configuration.\n"
+ << "GET_FILENAME_COMPONENT(_DIR \"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n"
+ << "FILE(GLOB CONFIG_FILES \"${_DIR}/"
+ << this->GetConfigImportFileGlob() << "\")\n"
+ << "FOREACH(f ${CONFIG_FILES})\n"
+ << " INCLUDE(${f})\n"
+ << "ENDFOREACH(f)\n"
+ << "\n";
+
+ // 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)
+ {
+ if(!this->GenerateImportFileConfig(ci->c_str()))
+ {
+ result = false;
+ }
+ }
+ return result;
+}
+
+//----------------------------------------------------------------------------
+bool
+cmExportInstallFileGenerator::GenerateImportFileConfig(const char* config)
+{
+ // Skip configurations not enabled for this export.
+ if(!this->InstallExportGenerator->InstallsForConfig(config))
+ {
+ return true;
+ }
+
+ // Construct the name of the file to generate.
+ std::string fileName = this->FileDir;
+ fileName += "/";
+ fileName += this->FileBase;
+ fileName += "-";
+ if(config && *config)
+ {
+ fileName += cmSystemTools::LowerCase(config);
+ }
+ else
+ {
+ fileName += "noconfig";
+ }
+ fileName += this->FileExt;
+
+ // Open the output file to generate it.
+ cmGeneratedFileStream exportFileStream(fileName.c_str(), true);
+ if(!exportFileStream)
+ {
+ std::string se = cmSystemTools::GetLastSystemError();
+ cmOStringStream e;
+ e << "cannot write to file \"" << fileName.c_str()
+ << "\": " << se;
+ cmSystemTools::Error(e.str().c_str());
+ return false;
+ }
+ std::ostream& os = exportFileStream;
+
+ // Start with the import file header.
+ this->GenerateImportHeaderCode(os, config);
+
+ // Generate the per-config target information.
+ this->GenerateImportConfig(os, config);
+
+ // End with the import file footer.
+ this->GenerateImportFooterCode(os);
+
+ // Record this per-config import file.
+ this->ConfigImportFiles[config] = fileName;
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+void
+cmExportInstallFileGenerator
+::GenerateImportTargetsConfig(std::ostream& os,
+ const char* config, std::string const& suffix)
+{
+ // Add code to compute the installation prefix relative to the
+ // import file location.
+ const char* installDest = this->InstallExportGenerator->GetDestination();
+ if(!cmSystemTools::FileIsFullPath(installDest))
+ {
+ std::string dest = installDest;
+ os << "# Compute the installation prefix relative to this file.\n"
+ << "GET_FILENAME_COMPONENT(_IMPORT_PREFIX "
+ << "\"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n";
+ while(!dest.empty())
+ {
+ os <<
+ "GET_FILENAME_COMPONENT(_IMPORT_PREFIX \"${_IMPORT_PREFIX}\" PATH)\n";
+ dest = cmSystemTools::GetFilenamePath(dest);
+ }
+ os << "\n";
+
+ // Import location properties may reference this variable.
+ this->ImportPrefix = "${_IMPORT_PREFIX}/";
+ }
+
+ // Add each target in the set to the export.
+ for(std::vector<cmTargetExport*>::const_iterator
+ tei = this->ExportSet->begin();
+ tei != this->ExportSet->end(); ++tei)
+ {
+ // Collect import properties for this target.
+ cmTargetExport* te = *tei;
+ ImportPropertyMap properties;
+ std::set<std::string> importedLocations;
+ this->SetImportLocationProperty(config, suffix, te->ArchiveGenerator,
+ properties, importedLocations);
+ this->SetImportLocationProperty(config, suffix, te->LibraryGenerator,
+ properties, importedLocations);
+ this->SetImportLocationProperty(config, suffix,
+ te->RuntimeGenerator, properties,
+ importedLocations);
+ this->SetImportLocationProperty(config, suffix, te->FrameworkGenerator,
+ properties, importedLocations);
+ this->SetImportLocationProperty(config, suffix, te->BundleGenerator,
+ properties, importedLocations);
+
+ // If any file location was set for the target add it to the
+ // import file.
+ if(!properties.empty())
+ {
+ // Get the rest of the target details.
+ this->SetImportDetailProperties(config, suffix,
+ te->Target, properties);
+
+ // TOOD: PUBLIC_HEADER_LOCATION
+ // This should wait until the build feature propagation stuff
+ // is done. Then this can be a propagated include directory.
+ // this->GenerateImportProperty(config, te->HeaderGenerator,
+ // properties);
+
+ // Generate code in the export file.
+ this->GenerateImportPropertyCode(os, config, te->Target, properties);
+ this->GenerateImportedFileChecksCode(os, te->Target, properties,
+ importedLocations);
+ }
+ }
+
+ this->GenerateImportedFileCheckLoop(os);
+
+ // Cleanup the import prefix variable.
+ if(!this->ImportPrefix.empty())
+ {
+ os << "# Cleanup temporary variables.\n"
+ << "SET(_IMPORT_PREFIX)\n"
+ << "\n";
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmExportInstallFileGenerator
+::SetImportLocationProperty(const char* config, std::string const& suffix,
+ cmInstallTargetGenerator* itgen,
+ ImportPropertyMap& properties,
+ std::set<std::string>& importedLocations
+ )
+{
+ // Skip rules that do not match this configuration.
+ if(!(itgen && itgen->InstallsForConfig(config)))
+ {
+ return;
+ }
+
+ // Get the target to be installed.
+ cmTarget* target = itgen->GetTarget();
+
+ // Construct the installed location of the target.
+ std::string dest = itgen->GetDestination();
+ 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 += dest;
+ value += "/";
+
+ if(itgen->IsImportLibrary())
+ {
+ // Construct the property name.
+ std::string prop = "IMPORTED_IMPLIB";
+ prop += suffix;
+
+ // Append the installed file name.
+ value += itgen->GetInstallFilename(target, config,
+ cmInstallTargetGenerator::NameImplib);
+
+ // Store the property.
+ properties[prop] = value;
+ importedLocations.insert(prop);
+ }
+ else
+ {
+ // Construct the property name.
+ std::string prop = "IMPORTED_LOCATION";
+ prop += suffix;
+
+ // Append the installed file name.
+ if(target->IsFrameworkOnApple())
+ {
+ value += itgen->GetInstallFilename(target, config);
+ value += ".framework/";
+ value += itgen->GetInstallFilename(target, config);
+ }
+ else if(target->IsCFBundleOnApple())
+ {
+ const char *ext = target->GetProperty("BUNDLE_EXTENSION");
+ if (!ext)
+ {
+ ext = "bundle";
+ }
+
+ value += itgen->GetInstallFilename(target, config);
+ value += ".";
+ value += ext;
+ value += "/";
+ value += itgen->GetInstallFilename(target, config);
+ }
+ else if(target->IsAppBundleOnApple())
+ {
+ value += itgen->GetInstallFilename(target, config);
+ value += ".app/Contents/MacOS/";
+ value += itgen->GetInstallFilename(target, config);
+ }
+ else
+ {
+ value += itgen->GetInstallFilename(target, config,
+ cmInstallTargetGenerator::NameReal);
+ }
+
+ // Store the property.
+ properties[prop] = value;
+ importedLocations.insert(prop);
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmExportInstallFileGenerator
+::ComplainAboutImportPrefix(cmInstallTargetGenerator* itgen)
+{
+ const char* installDest = this->InstallExportGenerator->GetDestination();
+ cmOStringStream e;
+ e << "INSTALL(EXPORT \"" << this->Name << "\") 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)
+{
+ cmOStringStream e;
+ e << "INSTALL(EXPORT \"" << this->Name << "\" ...) "
+ << "includes target \"" << depender->GetName()
+ << "\" which requires target \"" << dependee->GetName()
+ << "\" that is not in the export set.";
+ cmSystemTools::Error(e.str().c_str());
+}
diff --git a/Source/cmExportInstallFileGenerator.h b/Source/cmExportInstallFileGenerator.h
new file mode 100644
index 000000000..fb678e891
--- /dev/null
+++ b/Source/cmExportInstallFileGenerator.h
@@ -0,0 +1,124 @@
+/*============================================================================
+ 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 cmExportInstallFileGenerator_h
+#define cmExportInstallFileGenerator_h
+
+#include "cmExportFileGenerator.h"
+
+class cmInstallExportGenerator;
+class cmInstallFilesGenerator;
+class cmInstallTargetGenerator;
+class cmTargetExport;
+
+/** \class cmExportInstallFileGenerator
+ * \brief Generate a file exporting targets from an install tree.
+ *
+ * cmExportInstallFileGenerator generates files exporting targets from
+ * install an installation tree. The files are placed in a temporary
+ * location for installation by cmInstallExportGenerator. One main
+ * file is generated that creates the imported targets and loads
+ * per-configuration files. Target locations and settings for each
+ * configuration are written to these per-configuration files. After
+ * installation the main file loads the configurations that have been
+ * installed.
+ *
+ * This is used to implement the INSTALL(EXPORT) command.
+ */
+class cmExportInstallFileGenerator: public cmExportFileGenerator
+{
+public:
+ /** Construct with the export installer that will install the
+ files. */
+ cmExportInstallFileGenerator(cmInstallExportGenerator* iegen);
+
+ /** Set the name of the export associated with the files. This is
+ the name given to the install(EXPORT) command mode. */
+ void SetName(const char* name) { this->Name = name; }
+
+ /** Set the set of targets to be exported. These are the targets
+ associated with the export name. */
+ void SetExportSet(std::vector<cmTargetExport*> const* eSet)
+ { this->ExportSet = eSet; }
+
+ /** 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()
+ { return this->ConfigImportFiles; }
+
+ /** Compute the globbing expression used to load per-config import
+ files from the main file. */
+ std::string GetConfigImportFileGlob();
+protected:
+
+ // Implement virtual methods from the superclass.
+ virtual bool GenerateMainFile(std::ostream& os);
+ virtual void GenerateImportTargetsConfig(std::ostream& os,
+ const char* config,
+ std::string const& suffix);
+ virtual void ComplainAboutMissingTarget(cmTarget* depender,
+ cmTarget* dependee);
+
+ /** Generate a per-configuration file for the targets. */
+ bool GenerateImportFileConfig(const char* config);
+
+ /** Fill in properties indicating installed file locations. */
+ void SetImportLocationProperty(const char* config,
+ std::string const& suffix,
+ cmInstallTargetGenerator* itgen,
+ ImportPropertyMap& properties,
+ std::set<std::string>& importedLocations
+ );
+
+ void ComplainAboutImportPrefix(cmInstallTargetGenerator* itgen);
+
+ cmInstallExportGenerator* InstallExportGenerator;
+ std::string Name;
+ std::vector<cmTargetExport*> const* ExportSet;
+
+ std::string ImportPrefix;
+
+ // The import file generated for each configuration.
+ std::map<cmStdString, cmStdString> ConfigImportFiles;
+};
+
+/*
+ cmTargetExport is used in cmGlobalGenerator to collect the install
+ generators for targets associated with an export.
+*/
+class cmTargetExport
+{
+public:
+ cmTargetExport(cmTarget* tgt,
+ cmInstallTargetGenerator* archive,
+ cmInstallTargetGenerator* runtime,
+ cmInstallTargetGenerator* library,
+ cmInstallTargetGenerator* framework,
+ cmInstallTargetGenerator* bundle,
+ cmInstallFilesGenerator* headers
+ ) : Target(tgt), ArchiveGenerator(archive),
+ RuntimeGenerator(runtime), LibraryGenerator(library),
+ FrameworkGenerator(framework), BundleGenerator(bundle),
+ HeaderGenerator(headers) {}
+
+ cmTarget* Target;
+ cmInstallTargetGenerator* ArchiveGenerator;
+ cmInstallTargetGenerator* RuntimeGenerator;
+ cmInstallTargetGenerator* LibraryGenerator;
+ cmInstallTargetGenerator* FrameworkGenerator;
+ cmInstallTargetGenerator* BundleGenerator;
+ cmInstallFilesGenerator* HeaderGenerator;
+private:
+ cmTargetExport();
+};
+
+#endif
diff --git a/Source/cmExportLibraryDependencies.cxx b/Source/cmExportLibraryDependencies.cxx
new file mode 100644
index 000000000..8fdb069da
--- /dev/null
+++ b/Source/cmExportLibraryDependencies.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 "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
new file mode 100644
index 000000000..2a2ff215e
--- /dev/null
+++ b/Source/cmExportLibraryDependencies.h
@@ -0,0 +1,100 @@
+/*============================================================================
+ 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/cmExprLexer.cxx b/Source/cmExprLexer.cxx
new file mode 100644
index 000000000..53dfca7c0
--- /dev/null
+++ b/Source/cmExprLexer.cxx
@@ -0,0 +1,1928 @@
+#include "cmStandardIncludes.h"
+#line 2 "/home/andy/vtk/CMake-bin/Source/cmExprLexer.cxx"
+
+#line 4 "/home/andy/vtk/CMake-bin/Source/cmExprLexer.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 31
+#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
+#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;
+#endif /* ! C99 */
+
+/* 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 /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_CONST
+
+#endif /* __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
+
+int cmExpr_yylex_init (yyscan_t* scanner);
+
+/* 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 cmExpr_yyrestart(yyin ,yyscanner )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#define YY_BUF_SIZE 16384
+#endif
+
+#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 )
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef unsigned int 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 cmExpr_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 cmExpr_yyrestart (FILE *input_file ,yyscan_t yyscanner );
+void cmExpr_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+YY_BUFFER_STATE cmExpr_yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
+void cmExpr_yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void cmExpr_yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void cmExpr_yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+void cmExpr_yypop_buffer_state (yyscan_t yyscanner );
+
+static void cmExpr_yyensure_buffer_stack (yyscan_t yyscanner );
+static void cmExpr_yy_load_buffer_state (yyscan_t yyscanner );
+static void cmExpr_yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );
+
+#define YY_FLUSH_BUFFER cmExpr_yy_flush_buffer(YY_CURRENT_BUFFER ,yyscanner)
+
+YY_BUFFER_STATE cmExpr_yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
+YY_BUFFER_STATE cmExpr_yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
+YY_BUFFER_STATE cmExpr_yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
+
+void *cmExpr_yyalloc (yy_size_t ,yyscan_t yyscanner );
+void *cmExpr_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
+void cmExpr_yyfree (void * ,yyscan_t yyscanner );
+
+#define yy_new_buffer cmExpr_yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){ \
+ cmExpr_yyensure_buffer_stack (yyscanner); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ cmExpr_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 ){\
+ cmExpr_yyensure_buffer_stack (yyscanner); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ cmExpr_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 cmExpr_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 15
+#define YY_END_OF_BUFFER 16
+/* 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[23] =
+ { 0,
+ 0, 0, 16, 15, 6, 8, 13, 14, 4, 2,
+ 3, 5, 1, 15, 15, 9, 7, 10, 1, 11,
+ 12, 0
+ } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+ { 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, 2, 3, 1, 4,
+ 5, 6, 7, 1, 8, 1, 9, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 1, 1, 11,
+ 1, 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, 13, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 14, 1, 15, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 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[16] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static yyconst flex_int16_t yy_base[23] =
+ { 0,
+ 0, 0, 20, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 9, 7, 5, 21, 21, 21, 6, 21,
+ 21, 21
+ } ;
+
+static yyconst flex_int16_t yy_def[23] =
+ { 0,
+ 22, 1, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 0
+ } ;
+
+static yyconst flex_int16_t yy_nxt[37] =
+ { 0,
+ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
+ 14, 15, 16, 17, 18, 19, 21, 20, 19, 22,
+ 3, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22
+ } ;
+
+static yyconst flex_int16_t yy_chk[37] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 19, 15, 14, 13, 3,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22
+ } ;
+
+/* 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 "/home/andy/vtk/CMake/Source/cmExprLexer.in.l"
+#line 2 "/home/andy/vtk/CMake/Source/cmExprLexer.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.
+============================================================================*/
+/*
+
+This file must be translated to C and modified to build everywhere.
+
+Run flex like this:
+
+ flex --prefix=cmExpr_yy --header-file=cmExprLexer.h -ocmExprLexer.cxx cmExprLexer.in.l
+
+Modify cmExprLexer.cxx:
+ - remove TABs
+ - remove "yyscanner" argument from these methods:
+ yy_fatal_error, cmExpr_yyalloc, cmExpr_yyrealloc, cmExpr_yyfree
+ - remove all YY_BREAK lines occurring right after return statements
+ - change while ( 1 ) to for(;;)
+
+Modify cmExprLexer.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"
+
+#include "cmExprParserHelper.h"
+
+/* Replace the lexer input function. */
+#undef YY_INPUT
+#define YY_INPUT(buf, result, max_size) \
+ { result = yyextra->LexInput(buf, max_size); }
+
+/* Include the set of tokens from the parser. */
+#include "cmExprParserTokens.h"
+
+/*--------------------------------------------------------------------------*/
+#line 518 "/home/andy/vtk/CMake-bin/Source/cmExprLexer.cxx"
+
+#define INITIAL 0
+
+#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 */
+
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int cmExpr_yylex_destroy (yyscan_t yyscanner );
+
+int cmExpr_yyget_debug (yyscan_t yyscanner );
+
+void cmExpr_yyset_debug (int debug_flag ,yyscan_t yyscanner );
+
+YY_EXTRA_TYPE cmExpr_yyget_extra (yyscan_t yyscanner );
+
+void cmExpr_yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
+
+FILE *cmExpr_yyget_in (yyscan_t yyscanner );
+
+void cmExpr_yyset_in (FILE * in_str ,yyscan_t yyscanner );
+
+FILE *cmExpr_yyget_out (yyscan_t yyscanner );
+
+void cmExpr_yyset_out (FILE * out_str ,yyscan_t yyscanner );
+
+int cmExpr_yyget_leng (yyscan_t yyscanner );
+
+char *cmExpr_yyget_text (yyscan_t yyscanner );
+
+int cmExpr_yyget_lineno (yyscan_t yyscanner );
+
+void cmExpr_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 cmExpr_yywrap (yyscan_t yyscanner );
+#else
+extern int cmExpr_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
+
+#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
+#define YY_READ_BUF_SIZE 8192
+#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 (void) fwrite( yytext, yyleng, 1, yyout )
+#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 cmExpr_yylex (yyscan_t yyscanner);
+
+#define YY_DECL int cmExpr_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 \
+ YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp, *yy_bp;
+ register int yy_act;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+#line 86 "/home/andy/vtk/CMake/Source/cmExprLexer.in.l"
+
+
+#line 736 "/home/andy/vtk/CMake-bin/Source/cmExprLexer.cxx"
+
+ if ( yyg->yy_init )
+ {
+ yyg->yy_init = 0;
+
+#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 ) {
+ cmExpr_yyensure_buffer_stack (yyscanner);
+ YY_CURRENT_BUFFER_LVALUE =
+ cmExpr_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+ }
+
+ cmExpr_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_match:
+ do
+ {
+ register 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 >= 23 )
+ 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] != 21 );
+
+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 88 "/home/andy/vtk/CMake/Source/cmExprLexer.in.l"
+{ yylvalp->Number = atoi(yytext); return exp_NUMBER; }
+case 2:
+YY_RULE_SETUP
+#line 90 "/home/andy/vtk/CMake/Source/cmExprLexer.in.l"
+{ return exp_PLUS; }
+case 3:
+YY_RULE_SETUP
+#line 91 "/home/andy/vtk/CMake/Source/cmExprLexer.in.l"
+{ return exp_MINUS; }
+case 4:
+YY_RULE_SETUP
+#line 92 "/home/andy/vtk/CMake/Source/cmExprLexer.in.l"
+{ return exp_TIMES; }
+case 5:
+YY_RULE_SETUP
+#line 93 "/home/andy/vtk/CMake/Source/cmExprLexer.in.l"
+{ return exp_DIVIDE; }
+case 6:
+YY_RULE_SETUP
+#line 94 "/home/andy/vtk/CMake/Source/cmExprLexer.in.l"
+{ return exp_MOD; }
+case 7:
+YY_RULE_SETUP
+#line 95 "/home/andy/vtk/CMake/Source/cmExprLexer.in.l"
+{ return exp_OR; }
+case 8:
+YY_RULE_SETUP
+#line 96 "/home/andy/vtk/CMake/Source/cmExprLexer.in.l"
+{ return exp_AND; }
+case 9:
+YY_RULE_SETUP
+#line 97 "/home/andy/vtk/CMake/Source/cmExprLexer.in.l"
+{ return exp_XOR; }
+case 10:
+YY_RULE_SETUP
+#line 98 "/home/andy/vtk/CMake/Source/cmExprLexer.in.l"
+{ return exp_NOT; }
+case 11:
+YY_RULE_SETUP
+#line 99 "/home/andy/vtk/CMake/Source/cmExprLexer.in.l"
+{ return exp_SHIFTLEFT; }
+case 12:
+YY_RULE_SETUP
+#line 100 "/home/andy/vtk/CMake/Source/cmExprLexer.in.l"
+{ return exp_SHIFTRIGHT; }
+case 13:
+YY_RULE_SETUP
+#line 101 "/home/andy/vtk/CMake/Source/cmExprLexer.in.l"
+{ return exp_OPENPARENT; }
+case 14:
+YY_RULE_SETUP
+#line 102 "/home/andy/vtk/CMake/Source/cmExprLexer.in.l"
+{ return exp_CLOSEPARENT; }
+case 15:
+YY_RULE_SETUP
+#line 104 "/home/andy/vtk/CMake/Source/cmExprLexer.in.l"
+ECHO;
+ YY_BREAK
+#line 894 "/home/andy/vtk/CMake-bin/Source/cmExprLexer.cxx"
+case YY_STATE_EOF(INITIAL):
+ yyterminate();
+
+ 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
+ * cmExpr_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 ( cmExpr_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 */
+return 0; /* this should not happen but it silences a warning*/
+} /* end of cmExpr_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;
+ register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ register char *source = yyg->yytext_ptr;
+ register 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
+ {
+ size_t nuto_read =
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+ while ( nuto_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. */
+ cmExpr_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];
+
+ nuto_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+ number_to_move - 1;
+
+ }
+
+ if ( nuto_read > YY_READ_BUF_SIZE )
+ nuto_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, nuto_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;
+ cmExpr_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;
+
+ 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)
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ yy_current_state = yyg->yy_start;
+
+ for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp )
+ {
+ register 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 >= 23 )
+ 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)
+{
+ register int yy_is_jam;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ register char *yy_cp = yyg->yy_c_buf_p;
+
+ register 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 >= 23 )
+ 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 == 22);
+
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+#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. */
+ cmExpr_yyrestart(yyin ,yyscanner);
+
+ /*FALLTHROUGH*/
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( cmExpr_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;
+
+ 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 cmExpr_yyrestart (FILE * input_file , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if ( ! YY_CURRENT_BUFFER ){
+ cmExpr_yyensure_buffer_stack (yyscanner);
+ YY_CURRENT_BUFFER_LVALUE =
+ cmExpr_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+ }
+
+ cmExpr_yy_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner);
+ cmExpr_yy_load_buffer_state(yyscanner );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ * @param yyscanner The scanner object.
+ */
+ void cmExpr_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
+ * cmExpr_yypop_buffer_state();
+ * cmExpr_yypush_buffer_state(new_buffer);
+ */
+ cmExpr_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;
+ cmExpr_yy_load_buffer_state(yyscanner );
+
+ /* We don't actually know whether we did this switch during
+ * EOF (cmExpr_yywrap()) processing, but the only time this flag
+ * is looked at is after cmExpr_yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ yyg->yy_did_buffer_switch_on_eof = 1;
+}
+
+static void cmExpr_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 cmExpr_yy_create_buffer (FILE * file, int size , yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) cmExpr_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in cmExpr_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 *) cmExpr_yyalloc(b->yy_buf_size + 2 ,yyscanner );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in cmExpr_yy_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ cmExpr_yy_init_buffer(b,file ,yyscanner);
+
+ return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with cmExpr_yy_create_buffer()
+ * @param yyscanner The scanner object.
+ */
+ void cmExpr_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 )
+ cmExpr_yyfree((void *) b->yy_ch_buf ,yyscanner );
+
+ cmExpr_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 cmExpr_yyrestart() or at EOF.
+ */
+ static void cmExpr_yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner)
+
+{
+ int oerrno = errno;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ cmExpr_yy_flush_buffer(b ,yyscanner);
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then cmExpr_yy_init_buffer was _probably_
+ * called from cmExpr_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 cmExpr_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 )
+ cmExpr_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 cmExpr_yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if (new_buffer == NULL)
+ return;
+
+ cmExpr_yyensure_buffer_stack(yyscanner);
+
+ /* This block is copied from cmExpr_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 cmExpr_yy_switch_to_buffer. */
+ cmExpr_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 cmExpr_yypop_buffer_state (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ cmExpr_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) {
+ cmExpr_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 cmExpr_yyensure_buffer_stack (yyscan_t yyscanner)
+{
+ int nuto_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.
+ */
+ nuto_alloc = 1;
+ yyg->yy_buffer_stack = (struct yy_buffer_state**)cmExpr_yyalloc
+ (nuto_alloc * sizeof(struct yy_buffer_state*)
+ , yyscanner);
+
+ memset(yyg->yy_buffer_stack, 0, nuto_alloc * sizeof(struct yy_buffer_state*));
+
+ yyg->yy_buffer_stack_max = nuto_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 */;
+
+ nuto_alloc = yyg->yy_buffer_stack_max + grow_size;
+ yyg->yy_buffer_stack = (struct yy_buffer_state**)cmExpr_yyrealloc
+ (yyg->yy_buffer_stack,
+ nuto_alloc * sizeof(struct yy_buffer_state*)
+ , yyscanner);
+
+ /* 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 = nuto_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 cmExpr_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) cmExpr_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in cmExpr_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;
+
+ cmExpr_yy_switch_to_buffer(b ,yyscanner );
+
+ return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to cmExpr_yylex() will
+ * scan from a @e copy of @a yy_str.
+ * @param yy_str 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
+ * cmExpr_yy_scan_bytes() instead.
+ */
+YY_BUFFER_STATE cmExpr_yy_scan_string (yyconst char * yy_str , yyscan_t yyscanner)
+{
+
+ return cmExpr_yy_scan_bytes(yy_str,strlen(yy_str) ,yyscanner);
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to cmExpr_yylex() will
+ * scan from a @e copy of @a bytes.
+ * @param bytes the byte buffer to scan
+ * @param 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 cmExpr_yy_scan_bytes (yyconst char * bytes, int 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 = len + 2;
+ buf = (char *) cmExpr_yyalloc(n ,yyscanner );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in cmExpr_yy_scan_bytes()" );
+
+ for ( i = 0; i < len; ++i )
+ buf[i] = bytes[i];
+
+ buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = cmExpr_yy_scan_buffer(buf,n ,yyscanner);
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in cmExpr_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 cmExpr_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 cmExpr_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 cmExpr_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 *cmExpr_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 *cmExpr_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 cmExpr_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 *cmExpr_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 cmExpr_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 cmExpr_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( "cmExpr_yyset_lineno called with no buffer" , yyscanner);
+
+ yylineno = line_number;
+}
+
+/** Set the current column.
+ * @param column_no
+ * @param yyscanner The scanner object.
+ */
+void cmExpr_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( "cmExpr_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 cmExpr_yy_switch_to_buffer
+ */
+void cmExpr_yyset_in (FILE * in_str , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyin = in_str ;
+}
+
+void cmExpr_yyset_out (FILE * out_str , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyout = out_str ;
+}
+
+int cmExpr_yyget_debug (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yy_flex_debug;
+}
+
+void cmExpr_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 */
+
+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 once per scanner lifetime. */
+
+ 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 = 1;
+ yyg->yy_start = 0;
+ yyg->yy_start_stack_ptr = 0;
+ yyg->yy_start_stack_depth = 0;
+ yyg->yy_start_stack = (int *) 0;
+
+/* 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
+ * cmExpr_yylex_init()
+ */
+ return 0;
+}
+
+/* User-visible API */
+
+/* cmExpr_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 cmExpr_yylex_init(yyscan_t* ptr_yy_globals)
+
+{
+ if (ptr_yy_globals == NULL){
+ errno = EINVAL;
+ return 1;
+ }
+
+ *ptr_yy_globals = (yyscan_t) cmExpr_yyalloc ( sizeof( struct yyguts_t ), NULL );
+
+ if (*ptr_yy_globals == NULL){
+ errno = ENOMEM;
+ return 1;
+ }
+
+ memset(*ptr_yy_globals,0,sizeof(struct yyguts_t));
+
+ return yy_init_globals ( *ptr_yy_globals );
+}
+
+/* cmExpr_yylex_destroy is for both reentrant and non-reentrant scanners. */
+int cmExpr_yylex_destroy (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* Pop the buffer stack, destroying each element. */
+ while(YY_CURRENT_BUFFER){
+ cmExpr_yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ cmExpr_yypop_buffer_state(yyscanner);
+ }
+
+ /* Destroy the stack itself. */
+ cmExpr_yyfree(yyg->yy_buffer_stack ,yyscanner);
+ yyg->yy_buffer_stack = NULL;
+
+ /* Destroy the start condition stack. */
+ cmExpr_yyfree(yyg->yy_start_stack ,yyscanner );
+ yyg->yy_start_stack = NULL;
+
+ /* Destroy the main struct (reentrant only). */
+ cmExpr_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)
+{
+ register int i;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ 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)
+{
+ register int n;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+}
+#endif
+
+void *cmExpr_yyalloc (yy_size_t size , yyscan_t)
+{
+ return (void *) malloc( size );
+}
+
+void *cmExpr_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 cmExpr_yyfree (void * ptr , yyscan_t)
+{
+ free( (char *) ptr ); /* see cmExpr_yyrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#undef YY_NEW_FILE
+#undef YY_FLUSH_BUFFER
+#undef yy_set_bol
+#undef yy_new_buffer
+#undef yy_set_interactive
+#undef yytext_ptr
+#undef YY_DO_BEFORE_ACTION
+
+#ifdef YY_DECL_IS_OURS
+#undef YY_DECL_IS_OURS
+#undef YY_DECL
+#endif
+#line 104 "/home/andy/vtk/CMake/Source/cmExprLexer.in.l"
+
+
+
diff --git a/Source/cmExprLexer.h b/Source/cmExprLexer.h
new file mode 100644
index 000000000..4c10496ab
--- /dev/null
+++ b/Source/cmExprLexer.h
@@ -0,0 +1,334 @@
+/*============================================================================
+ 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 cmExpr_yyHEADER_H
+#define cmExpr_yyHEADER_H 1
+#define cmExpr_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 31
+#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
+#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;
+#endif /* ! C99 */
+
+/* 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 /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_CONST
+
+#endif /* __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
+
+int cmExpr_yylex_init (yyscan_t* scanner);
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef unsigned int 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 cmExpr_yyrestart (FILE *input_file ,yyscan_t yyscanner );
+void cmExpr_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,
+ yyscan_t yyscanner );
+YY_BUFFER_STATE cmExpr_yy_create_buffer (FILE *file,int size ,
+ yyscan_t yyscanner );
+void cmExpr_yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void cmExpr_yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void cmExpr_yypush_buffer_state (YY_BUFFER_STATE new_buffer ,
+ yyscan_t yyscanner );
+void cmExpr_yypop_buffer_state (yyscan_t yyscanner );
+
+YY_BUFFER_STATE cmExpr_yy_scan_buffer (char *base,yy_size_t size ,
+ yyscan_t yyscanner );
+YY_BUFFER_STATE cmExpr_yy_scan_string (yyconst char *yy_str ,
+ yyscan_t yyscanner );
+YY_BUFFER_STATE cmExpr_yy_scan_bytes (yyconst char *bytes,int len ,
+ yyscan_t yyscanner );
+
+void *cmExpr_yyalloc (yy_size_t ,yyscan_t yyscanner );
+void *cmExpr_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
+void cmExpr_yyfree (void * ,yyscan_t yyscanner );
+
+/* Begin user sect3 */
+
+#define cmExpr_yywrap(n) 1
+#define YY_SKIP_YYWRAP
+
+#define yytext_ptr yytext_r
+
+#ifdef YY_HEADER_EXPORT_START_CONDITIONS
+#define INITIAL 0
+
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int cmExpr_yylex_destroy (yyscan_t yyscanner );
+
+int cmExpr_yyget_debug (yyscan_t yyscanner );
+
+void cmExpr_yyset_debug (int debug_flag ,yyscan_t yyscanner );
+
+YY_EXTRA_TYPE cmExpr_yyget_extra (yyscan_t yyscanner );
+
+void cmExpr_yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
+
+FILE *cmExpr_yyget_in (yyscan_t yyscanner );
+
+void cmExpr_yyset_in (FILE * in_str ,yyscan_t yyscanner );
+
+FILE *cmExpr_yyget_out (yyscan_t yyscanner );
+
+void cmExpr_yyset_out (FILE * out_str ,yyscan_t yyscanner );
+
+int cmExpr_yyget_leng (yyscan_t yyscanner );
+
+char *cmExpr_yyget_text (yyscan_t yyscanner );
+
+int cmExpr_yyget_lineno (yyscan_t yyscanner );
+
+void cmExpr_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 cmExpr_yywrap (yyscan_t yyscanner );
+#else
+extern int cmExpr_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
+#define YY_READ_BUF_SIZE 8192
+#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 cmExpr_yylex (yyscan_t yyscanner);
+
+#define YY_DECL int cmExpr_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 yytext_ptr
+#undef YY_DO_BEFORE_ACTION
+
+#ifdef YY_DECL_IS_OURS
+#undef YY_DECL_IS_OURS
+#undef YY_DECL
+#endif
+
+
+
+
+#undef cmExpr_yyIN_HEADER
+#endif /* cmExpr_yyHEADER_H */
diff --git a/Source/cmExprLexer.in.l b/Source/cmExprLexer.in.l
new file mode 100644
index 000000000..db9018f99
--- /dev/null
+++ b/Source/cmExprLexer.in.l
@@ -0,0 +1,73 @@
+%{
+/*============================================================================
+ 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.
+============================================================================*/
+/*
+
+This file must be translated to C and modified to build everywhere.
+
+Run flex like this:
+
+ flex --prefix=cmExpr_yy --header-file=cmExprLexer.h -ocmExprLexer.cxx cmExprLexer.in.l
+
+Modify cmExprLexer.cxx:
+ - remove TABs
+ - remove "yyscanner" argument from these methods:
+ yy_fatal_error, cmExpr_yyalloc, cmExpr_yyrealloc, cmExpr_yyfree
+ - remove all YY_BREAK lines occurring right after return statements
+ - change while ( 1 ) to for(;;)
+
+Modify cmExprLexer.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"
+
+#include "cmExprParserHelper.h"
+
+/* Replace the lexer input function. */
+#undef YY_INPUT
+#define YY_INPUT(buf, result, max_size) \
+ { result = yyextra->LexInput(buf, max_size); }
+
+/* Include the set of tokens from the parser. */
+#include "cmExprParserTokens.h"
+
+/*--------------------------------------------------------------------------*/
+%}
+
+%option reentrant
+%option noyywrap
+%pointer
+
+%%
+
+[0-9][0-9]* { yylvalp->Number = atoi(yytext); return exp_NUMBER; }
+
+"+" { return exp_PLUS; }
+"-" { return exp_MINUS; }
+"*" { return exp_TIMES; }
+"/" { return exp_DIVIDE; }
+"%" { return exp_MOD; }
+"\|" { return exp_OR; }
+"&" { return exp_AND; }
+"^" { return exp_XOR; }
+"~" { return exp_NOT; }
+"<<" { return exp_SHIFTLEFT; }
+">>" { return exp_SHIFTRIGHT; }
+"(" { return exp_OPENPARENT; }
+")" { return exp_CLOSEPARENT; }
+
+%%
diff --git a/Source/cmExprParser.cxx b/Source/cmExprParser.cxx
new file mode 100644
index 000000000..5c164a081
--- /dev/null
+++ b/Source/cmExprParser.cxx
@@ -0,0 +1,1433 @@
+/* A Bison parser, made by GNU Bison 1.875d. */
+
+/* Skeleton parser for Yacc-like parsing with Bison, Copyright (C) 1984,
+ 1989, 1990, 2000, 2001, 2002, 2003, 2004 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 2, 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* As a special exception, when this file is copied by Bison into a
+ Bison output file, you may use that output file without restriction.
+ This special exception was added by the Free Software Foundation
+ in version 1.24 of Bison. */
+
+/* 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. */
+
+/* turn off some warning as this is generated code */
+#if defined(_MSC_VER)
+# pragma warning ( disable : 4702 ) /* unreachable code */
+#endif
+
+/* Identify Bison output. */
+#define YYBISON 1
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers. */
+#define YYPURE 1
+
+/* Using locations. */
+#define YYLSP_NEEDED 0
+
+/* If NAME_PREFIX is specified substitute the variables and functions
+ names. */
+#define yyparse cmExpr_yyparse
+#define yylex cmExpr_yylex
+#define yyerror cmExpr_yyerror
+#define yylval cmExpr_yylval
+#define yychar cmExpr_yychar
+#define yydebug cmExpr_yydebug
+#define yynerrs cmExpr_yynerrs
+
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ exp_PLUS = 258,
+ exp_MINUS = 259,
+ exp_TIMES = 260,
+ exp_DIVIDE = 261,
+ exp_MOD = 262,
+ exp_SHIFTLEFT = 263,
+ exp_SHIFTRIGHT = 264,
+ exp_OPENPARENT = 265,
+ exp_CLOSEPARENT = 266,
+ exp_OR = 267,
+ exp_AND = 268,
+ exp_XOR = 269,
+ exp_NOT = 270,
+ exp_NUMBER = 271
+ };
+#endif
+#define exp_PLUS 258
+#define exp_MINUS 259
+#define exp_TIMES 260
+#define exp_DIVIDE 261
+#define exp_MOD 262
+#define exp_SHIFTLEFT 263
+#define exp_SHIFTRIGHT 264
+#define exp_OPENPARENT 265
+#define exp_CLOSEPARENT 266
+#define exp_OR 267
+#define exp_AND 268
+#define exp_XOR 269
+#define exp_NOT 270
+#define exp_NUMBER 271
+
+
+
+
+/* Copy the first part of user declarations. */
+
+
+/*============================================================================
+ 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.
+============================================================================*/
+/*
+
+This file must be translated to C and modified to build everywhere.
+
+Run bison like this:
+
+ bison --yacc --name-prefix=cmExpr_yy --defines=cmExprParserTokens.h
+ -ocmExprParser.cxx cmExprParser.y
+
+Modify cmExprParser.cxx:
+ - remove TABs
+ - add __HP_aCC to the #if test for yyerrorlab warning suppression
+
+*/
+
+/* Configure the parser to use a lexer object. */
+#define YYPARSE_PARAM yyscanner
+#define YYLEX_PARAM yyscanner
+#define YYERROR_VERBOSE 1
+#define cmExpr_yyerror(x) \
+ cmExprError(yyscanner, x)
+#define yyGetParser (cmExpr_yyget_extra(yyscanner))
+
+/*-------------------------------------------------------------------------*/
+#include "cmExprParserHelper.h" /* Interface to parser object. */
+#include "cmExprLexer.h" /* Interface to lexer object. */
+#include "cmExprParserTokens.h" /* Need YYSTYPE for YY_DECL. */
+
+#include <math.h>
+
+/* Forward declare the lexer entry point. */
+YY_DECL;
+
+/* Internal utility functions. */
+static void cmExprError(yyscan_t yyscanner, const char* message);
+
+#define YYDEBUG 1
+//#define YYMAXDEPTH 100000
+//#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 case. */
+#endif
+
+
+/* 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
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+typedef int YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+/* Copy the second part of user declarations. */
+
+
+/* Line 214 of yacc.c. */
+
+
+#if ! defined (yyoverflow) || YYERROR_VERBOSE
+
+# ifndef YYFREE
+# define YYFREE free
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# endif
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# ifdef YYSTACK_USE_ALLOCA
+# if YYSTACK_USE_ALLOCA
+# define YYSTACK_ALLOC alloca
+# endif
+# else
+# if defined (alloca) || defined (_ALLOCA_H)
+# define YYSTACK_ALLOC alloca
+# else
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's `empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+# else
+# if defined (__STDC__) || defined (__cplusplus)
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# endif
+# define YYSTACK_ALLOC YYMALLOC
+# define YYSTACK_FREE YYFREE
+# 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
+{
+ short int yyss;
+ YYSTYPE yyvs;
+ };
+
+/* 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 (short int) + sizeof (YYSTYPE)) \
+ + YYSTACK_GAP_MAXIMUM)
+
+/* 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 \
+ { \
+ register YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (To)[yyi] = (From)[yyi]; \
+ } \
+ while (0)
+# endif
+# endif
+
+/* 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) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack, Stack, yysize); \
+ Stack = &yyptr->Stack; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (0)
+
+#endif
+
+#if defined (__STDC__) || defined (__cplusplus)
+ typedef signed char yysigned_char;
+#else
+ typedef short int yysigned_char;
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 12
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 25
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 17
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 9
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 20
+/* YYNRULES -- Number of states. */
+#define YYNSTATES 34
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
+#define YYUNDEFTOK 2
+#define YYMAXUTOK 271
+
+#define YYTRANSLATE(YYX) \
+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
+static const unsigned char 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
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+ YYRHS. */
+static const unsigned char yyprhs[] =
+{
+ 0, 0, 3, 5, 7, 11, 13, 17, 19, 23,
+ 25, 29, 33, 35, 39, 43, 45, 49, 53, 57,
+ 59
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const yysigned_char yyrhs[] =
+{
+ 18, 0, -1, 19, -1, 20, -1, 19, 12, 20,
+ -1, 21, -1, 20, 14, 21, -1, 22, -1, 21,
+ 13, 22, -1, 23, -1, 22, 8, 23, -1, 22,
+ 9, 23, -1, 24, -1, 23, 3, 24, -1, 23,
+ 4, 24, -1, 25, -1, 24, 5, 25, -1, 24,
+ 6, 25, -1, 24, 7, 25, -1, 16, -1, 10,
+ 19, 11, -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+static const unsigned char yyrline[] =
+{
+ 0, 94, 94, 100, 103, 107, 110, 114, 117, 121,
+ 124, 127, 132, 135, 138, 142, 145, 148, 151, 155,
+ 158
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE
+/* YYTNME[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", "exp_PLUS", "exp_MINUS", "exp_TIMES",
+ "exp_DIVIDE", "exp_MOD", "exp_SHIFTLEFT", "exp_SHIFTRIGHT",
+ "exp_OPENPARENT", "exp_CLOSEPARENT", "exp_OR", "exp_AND", "exp_XOR",
+ "exp_NOT", "exp_NUMBER", "$accept", "Start", "exp", "bitwiseor",
+ "bitwisexor", "bitwiseand", "shift", "term", "factor", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+ token YYLEX-NUM. */
+static const unsigned short int yytoknum[] =
+{
+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
+ 265, 266, 267, 268, 269, 270, 271
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const unsigned char yyr1[] =
+{
+ 0, 17, 18, 19, 19, 20, 20, 21, 21, 22,
+ 22, 22, 23, 23, 23, 24, 24, 24, 24, 25,
+ 25
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
+static const unsigned char yyr2[] =
+{
+ 0, 2, 1, 1, 3, 1, 3, 1, 3, 1,
+ 3, 3, 1, 3, 3, 1, 3, 3, 3, 1,
+ 3
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero
+ means the default is an error. */
+static const unsigned char yydefact[] =
+{
+ 0, 0, 19, 0, 2, 3, 5, 7, 9, 12,
+ 15, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 20, 4, 6, 8, 10, 11, 13,
+ 14, 16, 17, 18
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const yysigned_char yydefgoto[] =
+{
+ -1, 3, 4, 5, 6, 7, 8, 9, 10
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+#define YYPACT_NINF -14
+static const yysigned_char yypact[] =
+{
+ -10, -10, -14, 18, 7, 6, 8, 2, 1, -4,
+ -14, 3, -14, -10, -10, -10, -10, -10, -10, -10,
+ -10, -10, -10, -14, 6, 8, 2, 1, 1, -4,
+ -4, -14, -14, -14
+};
+
+/* YYPGOTO[NTERM-NUM]. */
+static const yysigned_char yypgoto[] =
+{
+ -14, -14, 21, 10, 11, 9, 0, -6, -13
+};
+
+/* 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 zero, do what YYDEFACT says.
+ If YYTABLE_NINF, syntax error. */
+#define YYTABLE_NINF -1
+static const unsigned char yytable[] =
+{
+ 1, 20, 21, 22, 18, 19, 2, 31, 32, 33,
+ 16, 17, 29, 30, 23, 13, 27, 28, 12, 13,
+ 14, 15, 11, 24, 26, 25
+};
+
+static const unsigned char yycheck[] =
+{
+ 10, 5, 6, 7, 3, 4, 16, 20, 21, 22,
+ 8, 9, 18, 19, 11, 12, 16, 17, 0, 12,
+ 14, 13, 1, 13, 15, 14
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
+static const unsigned char yystos[] =
+{
+ 0, 10, 16, 18, 19, 20, 21, 22, 23, 24,
+ 25, 19, 0, 12, 14, 13, 8, 9, 3, 4,
+ 5, 6, 7, 11, 20, 21, 22, 23, 23, 24,
+ 24, 25, 25, 25
+};
+
+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
+# define YYSIZE_T __SIZE_TYPE__
+#endif
+#if ! defined (YYSIZE_T) && defined (size_t)
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T)
+# if defined (__STDC__) || defined (__cplusplus)
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# endif
+#endif
+#if ! defined (YYSIZE_T)
+# define YYSIZE_T unsigned int
+#endif
+
+#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. */
+
+#define YYFAIL goto yyerrlab
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY && yylen == 1) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ yytoken = YYTRANSLATE (yychar); \
+ YYPOPSTACK; \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror ("syntax error: cannot back up");\
+ YYERROR; \
+ } \
+while (0)
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+/* YYLLOC_DEFAULT -- Compute the default location (before the actions
+ are run). */
+
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ ((Current).first_line = (Rhs)[1].first_line, \
+ (Current).first_column = (Rhs)[1].first_column, \
+ (Current).last_line = (Rhs)[N].last_line, \
+ (Current).last_column = (Rhs)[N].last_column)
+#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 (0)
+
+# define YYDSYMPRINT(Args) \
+do { \
+ if (yydebug) \
+ yysymprint Args; \
+} while (0)
+
+# define YYDSYMPRINTF(Title, Token, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yysymprint (stderr, \
+ Token, Value); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (0)
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included). |
+`------------------------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_stack_print (short int *bottom, short int *top)
+#else
+static void
+yy_stack_print (bottom, top)
+ short int *bottom;
+ short int *top;
+#endif
+{
+ YYFPRINTF (stderr, "Stack now");
+ for (/* Nothing. */; bottom <= top; ++bottom)
+ YYFPRINTF (stderr, " %d", *bottom);
+ 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. |
+`------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_reduce_print (int yyrule)
+#else
+static void
+yy_reduce_print (yyrule)
+ int yyrule;
+#endif
+{
+ int yyi;
+ unsigned int yylno = yyrline[yyrule];
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
+ yyrule - 1, yylno);
+ /* Print the symbols being reduced, and their result. */
+ for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
+ YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]);
+ YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]);
+}
+
+# define YY_REDUCE_PRINT(Rule) \
+do { \
+ if (yydebug) \
+ yy_reduce_print (Rule); \
+} 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 YYDSYMPRINT(Args)
+# define YYDSYMPRINTF(Title, Token, 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
+ SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#if defined (YYMAXDEPTH) && YYMAXDEPTH == 0
+# undef YYMAXDEPTH
+#endif
+
+#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
+# if defined (__STDC__) || defined (__cplusplus)
+yystrlen (const char *yystr)
+# else
+yystrlen (yystr)
+ const char *yystr;
+# endif
+{
+ register const char *yys = yystr;
+
+ while (*yys++ != '\0')
+ continue;
+
+ return yys - yystr - 1;
+}
+# 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 *
+# if defined (__STDC__) || defined (__cplusplus)
+yystpcpy (char *yydest, const char *yysrc)
+# else
+yystpcpy (yydest, yysrc)
+ char *yydest;
+ const char *yysrc;
+# endif
+{
+ register char *yyd = yydest;
+ register const char *yys = yysrc;
+
+ while ((*yyd++ = *yys++) != '\0')
+ continue;
+
+ return yyd - 1;
+}
+# endif
+# endif
+
+#endif /* !YYERROR_VERBOSE */
+
+
+
+#if YYDEBUG
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yysymprint (yyoutput, yytype, yyvaluep)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE *yyvaluep;
+#endif
+{
+ /* Pacify ``unused variable'' warnings. */
+ (void) yyvaluep;
+
+ if (yytype < YYNTOKENS)
+ {
+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+# ifdef YYPRINT
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# endif
+ }
+ else
+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+ switch (yytype)
+ {
+ default:
+ break;
+ }
+ YYFPRINTF (yyoutput, ")");
+}
+
+#endif /* ! YYDEBUG */
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yydestruct (int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yydestruct (yytype, yyvaluep)
+ int yytype;
+ YYSTYPE *yyvaluep;
+#endif
+{
+ /* Pacify ``unused variable'' warnings. */
+ (void) yyvaluep;
+
+ 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 (__cplusplus)
+int yyparse (void *YYPARSE_PARAM)
+# else
+int yyparse (YYPARSE_PARAM)
+ void *YYPARSE_PARAM;
+# endif
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
+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;
+
+ register int yystate;
+ register int yyn;
+ int yyresult;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+ /* Lookahead token as an internal (translated) token number. */
+ int yytoken = 0;
+
+ /* Three stacks and their tools:
+ `yyss': related to states,
+ `yyvs': related to semantic values,
+ `yyls': related to locations.
+
+ Refer to the stacks thru separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ short int yyssa[YYINITDEPTH];
+ short int *yyss = yyssa;
+ register short int *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs = yyvsa;
+ register YYSTYPE *yyvsp;
+
+
+
+#define YYPOPSTACK (yyvsp--, yyssp--)
+
+ YYSIZE_T yystacksize = YYINITDEPTH;
+
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+
+
+ /* When reducing, the number of symbols on the RHS of the reduced
+ rule. */
+ int yylen;
+
+ 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;
+ short int *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 ("parser stack overflow",
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+
+ &yystacksize);
+
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+ goto yyoverflowlab;
+# else
+ /* Extend the stack our own way. */
+ if (YYMAXDEPTH <= yystacksize)
+ goto yyoverflowlab;
+ yystacksize *= 2;
+ if (YYMAXDEPTH < yystacksize)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ short int *yyss1 = yyss;
+ union yyalloc *yyptr =
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ if (! yyptr)
+ goto yyoverflowlab;
+ YYSTACK_RELOCATE (yyss);
+ YYSTACK_RELOCATE (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));
+
+ 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. */
+/* yyresume: */
+
+ /* First try to decide what to do without reference to lookahead token. */
+
+ yyn = yypact[yystate];
+ if (yyn == YYPACT_NINF)
+ 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);
+ YYDSYMPRINTF ("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 (yyn == 0 || yyn == YYTABLE_NINF)
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ /* Shift the lookahead token. */
+ YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken]));
+
+ /* Discard the token being shifted unless it is eof. */
+ if (yychar != YYEOF)
+ yychar = YYEMPTY;
+
+ *++yyvsp = yylval;
+
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ yystate = yyn;
+ 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 2:
+
+ {
+ yyGetParser->SetResult(yyvsp[0].Number);
+}
+ break;
+
+ case 3:
+
+ {yyval.Number = yyvsp[0].Number;}
+ break;
+
+ case 4:
+
+ {yyval.Number = yyvsp[-2].Number | yyvsp[0].Number;}
+ break;
+
+ case 5:
+
+ {yyval.Number = yyvsp[0].Number;}
+ break;
+
+ case 6:
+
+ {yyval.Number = yyvsp[-2].Number ^ yyvsp[0].Number;}
+ break;
+
+ case 7:
+
+ {yyval.Number = yyvsp[0].Number;}
+ break;
+
+ case 8:
+
+ {yyval.Number = yyvsp[-2].Number & yyvsp[0].Number;}
+ break;
+
+ case 9:
+
+ {yyval.Number = yyvsp[0].Number;}
+ break;
+
+ case 10:
+
+ {yyval.Number = yyvsp[-2].Number << yyvsp[0].Number;}
+ break;
+
+ case 11:
+
+ {yyval.Number = yyvsp[-2].Number >> yyvsp[0].Number;}
+ break;
+
+ case 12:
+
+ {yyval.Number = yyvsp[0].Number;}
+ break;
+
+ case 13:
+
+ {yyval.Number = yyvsp[-2].Number + yyvsp[0].Number;}
+ break;
+
+ case 14:
+
+ {yyval.Number = yyvsp[-2].Number - yyvsp[0].Number;}
+ break;
+
+ case 15:
+
+ {yyval.Number = yyvsp[0].Number;}
+ break;
+
+ case 16:
+
+ {yyval.Number = yyvsp[-2].Number * yyvsp[0].Number;}
+ break;
+
+ case 17:
+
+ {yyval.Number = yyvsp[-2].Number / yyvsp[0].Number;}
+ break;
+
+ case 18:
+
+ {yyval.Number = yyvsp[-2].Number % yyvsp[0].Number;}
+ break;
+
+ case 19:
+
+ {yyval.Number = yyvsp[0].Number;}
+ break;
+
+ case 20:
+
+ {yyval.Number = yyvsp[-1].Number;}
+ break;
+
+
+ }
+
+/* Line 1010 of yacc.c. */
+
+
+ yyvsp -= yylen;
+ yyssp -= yylen;
+
+
+ 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:
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+#if YYERROR_VERBOSE
+ yyn = yypact[yystate];
+
+ if (YYPACT_NINF < yyn && yyn < YYLAST)
+ {
+ YYSIZE_T yysize = 0;
+ int yytype = YYTRANSLATE (yychar);
+ const char* yyprefix;
+ char *yymsg;
+ int yyx;
+
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yycount = 0;
+
+ yyprefix = ", expecting ";
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]);
+ yycount += 1;
+ if (yycount == 5)
+ {
+ yysize = 0;
+ break;
+ }
+ }
+ yysize += (sizeof ("syntax error, unexpected ")
+ + yystrlen (yytname[yytype]));
+ yymsg = (char *) YYSTACK_ALLOC (yysize);
+ if (yymsg != 0)
+ {
+ char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
+ yyp = yystpcpy (yyp, yytname[yytype]);
+
+ if (yycount < 5)
+ {
+ yyprefix = ", expecting ";
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ yyp = yystpcpy (yyp, yyprefix);
+ yyp = yystpcpy (yyp, yytname[yyx]);
+ yyprefix = " or ";
+ }
+ }
+ yyerror (yymsg);
+ YYSTACK_FREE (yymsg);
+ }
+ else
+ yyerror ("syntax error; also virtual memory exhausted");
+ }
+ else
+#endif /* YYERROR_VERBOSE */
+ yyerror ("syntax error");
+ }
+
+
+
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse lookahead token after an
+ error, discard it. */
+
+ if (yychar <= YYEOF)
+ {
+ /* If at end of input, pop the error token,
+ then the rest of the stack, then return failure. */
+ if (yychar == YYEOF)
+ for (;;)
+ {
+ YYPOPSTACK;
+ if (yyssp == yyss)
+ YYABORT;
+ YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
+ yydestruct (yystos[*yyssp], yyvsp);
+ }
+ }
+ else
+ {
+ YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc);
+ yydestruct (yytoken, &yylval);
+ yychar = YYEMPTY;
+
+ }
+ }
+
+ /* Else will try to reuse lookahead token after shifting the error
+ token. */
+ goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR. |
+`---------------------------------------------------*/
+yyerrorlab:
+
+#if defined( __GNUC__ ) || defined(__HP_aCC)
+ /* Pacify GCC when the user code never invokes YYERROR and the label
+ yyerrorlab therefore never appears in user code. */
+ if (0)
+ goto yyerrorlab;
+#endif
+
+ yyvsp -= yylen;
+ yyssp -= yylen;
+ yystate = *yyssp;
+ goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR. |
+`-------------------------------------------------------------*/
+yyerrlab1:
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (yyn != YYPACT_NINF)
+ {
+ 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;
+
+ YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
+ yydestruct (yystos[yystate], yyvsp);
+ YYPOPSTACK;
+ yystate = *yyssp;
+ YY_STACK_PRINT (yyss, yyssp);
+ }
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ YYDPRINTF ((stderr, "Shifting error token, "));
+
+ *++yyvsp = yylval;
+
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturn;
+
+#ifndef yyoverflow
+/*----------------------------------------------.
+| yyoverflowlab -- parser overflow comes here. |
+`----------------------------------------------*/
+yyoverflowlab:
+ yyerror ("parser stack overflow");
+ yyresult = 2;
+ /* Fall through. */
+#endif
+
+yyreturn:
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE (yyss);
+#endif
+ return yyresult;
+}
+
+
+
+
+/* End of grammar */
+
+/*--------------------------------------------------------------------------*/
+void cmExprError(yyscan_t yyscanner, const char* message)
+{
+ yyGetParser->Error(message);
+}
+
+
diff --git a/Source/cmExprParser.y b/Source/cmExprParser.y
new file mode 100644
index 000000000..317b0ba98
--- /dev/null
+++ b/Source/cmExprParser.y
@@ -0,0 +1,169 @@
+%{
+/*============================================================================
+ 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.
+============================================================================*/
+/*
+
+This file must be translated to C and modified to build everywhere.
+
+Run bison like this:
+
+ bison --yacc --name-prefix=cmExpr_yy --defines=cmExprParserTokens.h -ocmExprParser.cxx cmExprParser.y
+
+Modify cmExprParser.cxx:
+ - remove TABs
+ - add __HP_aCC to the #if test for yyerrorlab warning suppression
+
+*/
+
+/* Configure the parser to use a lexer object. */
+#define YYPARSE_PARAM yyscanner
+#define YYLEX_PARAM yyscanner
+#define YYERROR_VERBOSE 1
+#define cmExpr_yyerror(x) \
+ cmExprError(yyscanner, x)
+#define yyGetParser (cmExpr_yyget_extra(yyscanner))
+
+/*-------------------------------------------------------------------------*/
+#include "cmExprParserHelper.h" /* Interface to parser object. */
+#include "cmExprLexer.h" /* Interface to lexer object. */
+#include "cmExprParserTokens.h" /* Need YYSTYPE for YY_DECL. */
+
+#include <math.h>
+
+/* Forward declare the lexer entry point. */
+YY_DECL;
+
+/* Internal utility functions. */
+static void cmExprError(yyscan_t yyscanner, const char* message);
+
+#define YYDEBUG 1
+//#define YYMAXDEPTH 100000
+//#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 case. */
+#endif
+%}
+
+/* Generate a reentrant parser object. */
+%pure_parser
+
+/*-------------------------------------------------------------------------*/
+/* Tokens */
+%token exp_PLUS
+%token exp_MINUS
+%token exp_TIMES
+%token exp_DIVIDE
+%token exp_MOD
+%token exp_SHIFTLEFT
+%token exp_SHIFTRIGHT
+%token exp_OPENPARENT
+%token exp_CLOSEPARENT
+%token exp_OR;
+%token exp_AND;
+%token exp_XOR;
+%token exp_NOT;
+%token exp_NUMBER;
+
+/*-------------------------------------------------------------------------*/
+/* grammar */
+%%
+
+
+Start:
+exp
+{
+ yyGetParser->SetResult($<Number>1);
+}
+
+exp:
+bitwiseor
+{$<Number>$ = $<Number>1;}
+|
+exp exp_OR bitwiseor
+{$<Number>$ = $<Number>1 | $<Number>3;}
+
+bitwiseor:
+bitwisexor
+{$<Number>$ = $<Number>1;}
+|
+bitwiseor exp_XOR bitwisexor
+{$<Number>$ = $<Number>1 ^ $<Number>3;}
+
+bitwisexor:
+bitwiseand
+{$<Number>$ = $<Number>1;}
+|
+bitwisexor exp_AND bitwiseand
+{$<Number>$ = $<Number>1 & $<Number>3;}
+
+bitwiseand:
+shift
+{$<Number>$ = $<Number>1;}
+|
+bitwiseand exp_SHIFTLEFT shift
+{$<Number>$ = $<Number>1 << $<Number>3;}
+|
+bitwiseand exp_SHIFTRIGHT shift
+{$<Number>$ = $<Number>1 >> $<Number>3;}
+
+
+shift:
+term
+{$<Number>$ = $<Number>1;}
+|
+shift exp_PLUS term
+{$<Number>$ = $<Number>1 + $<Number>3;}
+|
+shift exp_MINUS term
+{$<Number>$ = $<Number>1 - $<Number>3;}
+
+term:
+factor
+{$<Number>$ = $<Number>1;}
+|
+term exp_TIMES factor
+{$<Number>$ = $<Number>1 * $<Number>3;}
+|
+term exp_DIVIDE factor
+{$<Number>$ = $<Number>1 / $<Number>3;}
+|
+term exp_MOD factor
+{$<Number>$ = $<Number>1 % $<Number>3;}
+
+factor:
+exp_NUMBER
+{$<Number>$ = $<Number>1;}
+|
+exp_OPENPARENT exp exp_CLOSEPARENT
+{$<Number>$ = $<Number>2;}
+;
+
+
+%%
+/* End of grammar */
+
+/*--------------------------------------------------------------------------*/
+void cmExprError(yyscan_t yyscanner, const char* message)
+{
+ yyGetParser->Error(message);
+}
+
diff --git a/Source/cmExprParserHelper.cxx b/Source/cmExprParserHelper.cxx
new file mode 100644
index 000000000..7728d740b
--- /dev/null
+++ b/Source/cmExprParserHelper.cxx
@@ -0,0 +1,112 @@
+/*============================================================================
+ 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 "cmExprParserHelper.h"
+
+#include "cmSystemTools.h"
+#include "cmExprLexer.h"
+
+#include "cmMakefile.h"
+
+int cmExpr_yyparse( yyscan_t yyscanner );
+//
+cmExprParserHelper::cmExprParserHelper()
+{
+ this->FileLine = -1;
+ this->FileName = 0;
+}
+
+
+cmExprParserHelper::~cmExprParserHelper()
+{
+ this->CleanupParser();
+}
+
+int cmExprParserHelper::ParseString(const char* str, int verb)
+{
+ if ( !str)
+ {
+ return 0;
+ }
+ //printf("Do some parsing: %s\n", str);
+
+ this->Verbose = verb;
+ this->InputBuffer = str;
+ this->InputBufferPos = 0;
+ this->CurrentLine = 0;
+
+ this->Result = 0;
+
+ yyscan_t yyscanner;
+ cmExpr_yylex_init(&yyscanner);
+ cmExpr_yyset_extra(this, yyscanner);
+ int res = cmExpr_yyparse(yyscanner);
+ cmExpr_yylex_destroy(yyscanner);
+ if ( res != 0 )
+ {
+ //str << "CAL_Parser returned: " << res << std::endl;
+ //std::cerr << "When parsing: [" << str << "]" << std::endl;
+ return 0;
+ }
+
+ this->CleanupParser();
+
+ if ( Verbose )
+ {
+ std::cerr << "Expanding [" << str << "] produced: ["
+ << this->Result << "]" << std::endl;
+ }
+ return 1;
+}
+
+void cmExprParserHelper::CleanupParser()
+{
+}
+
+int cmExprParserHelper::LexInput(char* buf, int maxlen)
+{
+ //std::cout << "JPLexInput ";
+ //std::cout.write(buf, maxlen);
+ //std::cout << std::endl;
+ if ( maxlen < 1 )
+ {
+ return 0;
+ }
+ if ( this->InputBufferPos < this->InputBuffer.size() )
+ {
+ buf[0] = this->InputBuffer[ this->InputBufferPos++ ];
+ if ( buf[0] == '\n' )
+ {
+ this->CurrentLine ++;
+ }
+ return(1);
+ }
+ else
+ {
+ buf[0] = '\n';
+ return( 0 );
+ }
+}
+
+void cmExprParserHelper::Error(const char* str)
+{
+ unsigned long pos = static_cast<unsigned long>(this->InputBufferPos);
+ cmOStringStream ostr;
+ ostr << str << " (" << pos << ")";
+ this->ErrorString = ostr.str();
+}
+
+void cmExprParserHelper::SetResult(int value)
+{
+ this->Result = value;
+}
+
+
diff --git a/Source/cmExprParserHelper.h b/Source/cmExprParserHelper.h
new file mode 100644
index 000000000..690426d8d
--- /dev/null
+++ b/Source/cmExprParserHelper.h
@@ -0,0 +1,71 @@
+/*============================================================================
+ 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 cmExprParserHelper_h
+#define cmExprParserHelper_h
+
+#include "cmStandardIncludes.h"
+
+#define YYSTYPE cmExprParserHelper::ParserType
+#define YYSTYPE_IS_DECLARED
+#define YY_EXTRA_TYPE cmExprParserHelper*
+#define YY_DECL int cmExpr_yylex(YYSTYPE* yylvalp, yyscan_t yyscanner)
+
+/** \class cmExprParserHelper
+ * \brief Helper class for parsing java source files
+ *
+ * Finds dependencies for java file and list of outputs
+ */
+
+class cmMakefile;
+
+class cmExprParserHelper
+{
+public:
+ typedef struct {
+ int Number;
+ } ParserType;
+
+ cmExprParserHelper();
+ ~cmExprParserHelper();
+
+ int ParseString(const char* str, int verb);
+
+ int LexInput(char* buf, int maxlen);
+ void Error(const char* str);
+
+ void SetResult(int value);
+
+ int GetResult() { return this->Result; }
+
+ const char* GetError() { return this->ErrorString.c_str(); }
+
+private:
+ cmStdString::size_type InputBufferPos;
+ cmStdString InputBuffer;
+ std::vector<char> OutputBuffer;
+ int CurrentLine;
+ int Verbose;
+
+ void Print(const char* place, const char* str);
+
+ void CleanupParser();
+
+ int Result;
+ const char* FileName;
+ long FileLine;
+ std::string ErrorString;
+};
+
+#endif
+
+
+
diff --git a/Source/cmExprParserTokens.h b/Source/cmExprParserTokens.h
new file mode 100644
index 000000000..0309c09a1
--- /dev/null
+++ b/Source/cmExprParserTokens.h
@@ -0,0 +1,76 @@
+/* A Bison parser, made by GNU Bison 1.875d. */
+
+/* Skeleton parser for Yacc-like parsing with Bison, Copyright (C) 1984,
+ 1989, 1990, 2000, 2001, 2002, 2003, 2004 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 2, 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* As a special exception, when this file is copied by Bison into a
+ Bison output file, you may use that output file without restriction.
+ This special exception was added by the Free Software Foundation
+ in version 1.24 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 {
+ exp_PLUS = 258,
+ exp_MINUS = 259,
+ exp_TIMES = 260,
+ exp_DIVIDE = 261,
+ exp_MOD = 262,
+ exp_SHIFTLEFT = 263,
+ exp_SHIFTRIGHT = 264,
+ exp_OPENPARENT = 265,
+ exp_CLOSEPARENT = 266,
+ exp_OR = 267,
+ exp_AND = 268,
+ exp_XOR = 269,
+ exp_NOT = 270,
+ exp_NUMBER = 271
+ };
+#endif
+#define exp_PLUS 258
+#define exp_MINUS 259
+#define exp_TIMES 260
+#define exp_DIVIDE 261
+#define exp_MOD 262
+#define exp_SHIFTLEFT 263
+#define exp_SHIFTRIGHT 264
+#define exp_OPENPARENT 265
+#define exp_CLOSEPARENT 266
+#define exp_OR 267
+#define exp_AND 268
+#define exp_XOR 269
+#define exp_NOT 270
+#define exp_NUMBER 271
+
+
+
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+typedef int YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+
+
diff --git a/Source/cmExternalMakefileProjectGenerator.cxx b/Source/cmExternalMakefileProjectGenerator.cxx
new file mode 100644
index 000000000..6ed84bd95
--- /dev/null
+++ b/Source/cmExternalMakefileProjectGenerator.cxx
@@ -0,0 +1,64 @@
+/*============================================================================
+ 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 <assert.h>
+
+#include "cmExternalMakefileProjectGenerator.h"
+
+std::string cmExternalMakefileProjectGenerator::CreateFullGeneratorName(
+ const char* globalGenerator,
+ const char* extraGenerator)
+{
+ std::string fullName;
+ if (globalGenerator)
+ {
+ if (extraGenerator && *extraGenerator)
+ {
+ fullName = extraGenerator;
+ fullName += " - ";
+ }
+ fullName += globalGenerator;
+ }
+ return fullName;
+}
+
+const char* cmExternalMakefileProjectGenerator::GetGlobalGeneratorName(
+ const char* fullName)
+{
+ // at least one global generator must be supported
+ assert(!this->SupportedGlobalGenerators.empty());
+
+ if (fullName==0)
+ {
+ return 0;
+ }
+
+ 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();
+ }
+
+ // otherwise search for the matching global generator
+ for (std::vector<std::string>::const_iterator
+ it = this->SupportedGlobalGenerators.begin();
+ it != this->SupportedGlobalGenerators.end();
+ ++it)
+ {
+ if (this->CreateFullGeneratorName(it->c_str(), this->GetName())
+ == currentName)
+ {
+ return it->c_str();
+ }
+ }
+ return 0;
+}
diff --git a/Source/cmExternalMakefileProjectGenerator.h b/Source/cmExternalMakefileProjectGenerator.h
new file mode 100644
index 000000000..46f1d310b
--- /dev/null
+++ b/Source/cmExternalMakefileProjectGenerator.h
@@ -0,0 +1,70 @@
+/*============================================================================
+ 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 cmExternalMakefileProjectGenerator_h
+#define cmExternalMakefileProjectGenerator_h
+
+#include "cmStandardIncludes.h"
+
+#include "cmDocumentation.h"
+
+class cmGlobalGenerator;
+
+/** \class cmExternalMakefileProjectGenerator
+ * \brief Base class for generators for "External Makefile based IDE projects".
+ *
+ * cmExternalMakefileProjectGenerator is a base class for generators
+ * for "external makefile based projects", i.e. IDE projects which work
+ * an already existing makefiles.
+ * See cmGlobalKdevelopGenerator as an example.
+ * After the makefiles have been generated by one of the Makefile
+ * generators, the Generate() method is called and this generator
+ * can iterate over the local generators and/or projects to produce the
+ * project files for the IDE.
+ */
+class cmExternalMakefileProjectGenerator
+{
+public:
+
+ virtual ~cmExternalMakefileProjectGenerator() {}
+
+ ///! Get the name for this generator.
+ virtual const char* GetName() const = 0;
+ /** Get the documentation entry for this generator. */
+ virtual void GetDocumentation(cmDocumentationEntry& entry,
+ const char* fullName) const = 0;
+
+ ///! set the global generator which will generate the makefiles
+ virtual void SetGlobalGenerator(cmGlobalGenerator* generator)
+ {this->GlobalGenerator = generator;}
+
+ ///! Return the list of global generators supported by this extra generator
+ const std::vector<std::string>& GetSupportedGlobalGenerators() const
+ {return this->SupportedGlobalGenerators;}
+
+ ///! Get the name of the global generator for the given full name
+ const char* GetGlobalGeneratorName(const char* 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);
+
+ ///! Generate the project files, the Makefiles have already been generated
+ virtual void Generate() = 0;
+protected:
+ ///! Contains the names of the global generators support by this generator.
+ std::vector<std::string> SupportedGlobalGenerators;
+ ///! the global generator which creates the makefiles
+ const cmGlobalGenerator* GlobalGenerator;
+};
+
+#endif
diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx
new file mode 100644
index 000000000..ad4ab76ee
--- /dev/null
+++ b/Source/cmExtraCodeBlocksGenerator.cxx
@@ -0,0 +1,819 @@
+/*============================================================================
+ 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 "cmExtraCodeBlocksGenerator.h"
+#include "cmGlobalUnixMakefileGenerator3.h"
+#include "cmLocalUnixMakefileGenerator3.h"
+#include "cmMakefile.h"
+#include "cmake.h"
+#include "cmSourceFile.h"
+#include "cmGeneratedFileStream.h"
+#include "cmTarget.h"
+#include "cmSystemTools.h"
+#include "cmXMLSafe.h"
+
+#include <cmsys/SystemTools.hxx>
+
+/* Some useful URLs:
+Homepage:
+http://www.codeblocks.org
+
+File format docs:
+http://wiki.codeblocks.org/index.php?title=File_formats_description
+http://wiki.codeblocks.org/index.php?title=Workspace_file
+http://wiki.codeblocks.org/index.php?title=Project_file
+
+Discussion:
+http://forums.codeblocks.org/index.php/topic,6789.0.html
+*/
+
+//----------------------------------------------------------------------------
+void cmExtraCodeBlocksGenerator
+::GetDocumentation(cmDocumentationEntry& entry, const char*) 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()
+: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 cmExtraCodeBlocksGenerator::Generate()
+{
+ // for each sub project in the project create a codeblocks project
+ for (std::map<cmStdString, std::vector<cmLocalGenerator*> >::const_iterator
+ it = this->GlobalGenerator->GetProjectMap().begin();
+ it!= this->GlobalGenerator->GetProjectMap().end();
+ ++it)
+ {
+ // create a project file
+ this->CreateProjectFile(it->second);
+ }
+}
+
+
+/* create the project file */
+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 filename=outputDir+"/";
+ filename+=projectName+".cbp";
+ std::string sessionFilename=outputDir+"/";
+ sessionFilename+=projectName+".layout";
+
+ this->CreateNewProjectFile(lgs, filename);
+}
+
+
+/* Tree is used to create a "Virtual Folder" in CodeBlocks, in which all
+ CMake files this project depends on will be put. This means additionally
+ to the "Sources" and "Headers" virtual folders of CodeBlocks, there will
+ now also be a "CMake Files" virtual folder.
+ Patch by Daniel Teske <daniel.teske AT nokia.com> (which use C::B project
+ files in QtCreator).*/
+struct Tree
+{
+ std::string path; //only one component of the path
+ std::vector<Tree> folders;
+ std::vector<std::string> files;
+ void InsertPath(const std::vector<std::string>& splitted,
+ std::vector<std::string>::size_type start,
+ const std::string& fileName);
+ void BuildVirtualFolder(std::string& virtualFolders) const;
+ void BuildVirtualFolderImpl(std::string& virtualFolders,
+ const std::string& prefix) const;
+ void BuildUnit(std::string& unitString, const std::string& fsPath) const;
+ void BuildUnitImpl(std::string& unitString,
+ const std::string& virtualFolderPath,
+ const std::string& fsPath) const;
+};
+
+
+void Tree::InsertPath(const std::vector<std::string>& splitted,
+ std::vector<std::string>::size_type start,
+ const std::string& fileName)
+{
+ if (start == splitted.size())
+ {
+ files.push_back(fileName);
+ return;
+ }
+ for (std::vector<Tree>::iterator
+ it = folders.begin();
+ it != folders.end();
+ ++it)
+ {
+ if ((*it).path == splitted[start])
+ {
+ if (start + 1 < splitted.size())
+ {
+ it->InsertPath(splitted, start + 1, fileName);
+ return;
+ }
+ else
+ {
+ // last part of splitted
+ it->files.push_back(fileName);
+ return;
+ }
+ }
+ }
+ // Not found in folders, thus insert
+ Tree newFolder;
+ newFolder.path = splitted[start];
+ if (start + 1 < splitted.size())
+ {
+ newFolder.InsertPath(splitted, start + 1, fileName);
+ folders.push_back(newFolder);
+ return;
+ }
+ else
+ {
+ // last part of splitted
+ newFolder.files.push_back(fileName);
+ folders.push_back(newFolder);
+ return;
+ }
+}
+
+
+void Tree::BuildVirtualFolder(std::string& virtualFolders) const
+{
+ virtualFolders += "<Option virtualFolders=\"CMake Files\\;";
+ for (std::vector<Tree>::const_iterator it = folders.begin();
+ it != folders.end();
+ ++it)
+ {
+ it->BuildVirtualFolderImpl(virtualFolders, "");
+ }
+ virtualFolders += "\" />";
+}
+
+
+void Tree::BuildVirtualFolderImpl(std::string& virtualFolders,
+ const std::string& prefix) const
+{
+ virtualFolders += "CMake Files\\" + prefix + path + "\\;";
+ for (std::vector<Tree>::const_iterator it = folders.begin();
+ it != folders.end();
+ ++it)
+ {
+ it->BuildVirtualFolderImpl(virtualFolders, prefix + path + "\\");
+ }
+}
+
+
+void Tree::BuildUnit(std::string& unitString, const std::string& fsPath) const
+{
+ for (std::vector<std::string>::const_iterator it = files.begin();
+ it != files.end();
+ ++it)
+ {
+ unitString += " <Unit filename=\"" + fsPath + *it + "\">\n";
+ unitString += " <Option virtualFolder=\"CMake Files\\\" />\n";
+ unitString += " </Unit>\n";
+ }
+ for (std::vector<Tree>::const_iterator it = folders.begin();
+ it != folders.end();
+ ++it)
+ {
+ it->BuildUnitImpl(unitString, "", fsPath);
+ }
+}
+
+
+void Tree::BuildUnitImpl(std::string& unitString,
+ const std::string& virtualFolderPath,
+ const std::string& fsPath) const
+{
+ for (std::vector<std::string>::const_iterator it = files.begin();
+ it != files.end();
+ ++it)
+ {
+ unitString += " <Unit filename=\"" +fsPath+path+ "/" + *it + "\">\n";
+ unitString += " <Option virtualFolder=\"CMake Files\\"
+ + virtualFolderPath + path + "\\\" />\n";
+ unitString += " </Unit>\n";
+ }
+ for (std::vector<Tree>::const_iterator it = folders.begin();
+ it != folders.end();
+ ++it)
+ {
+ it->BuildUnitImpl(unitString,
+ virtualFolderPath + path + "\\", fsPath + path + "/");
+ }
+}
+
+
+void cmExtraCodeBlocksGenerator
+ ::CreateNewProjectFile(const std::vector<cmLocalGenerator*>& lgs,
+ const std::string& filename)
+{
+ const cmMakefile* mf=lgs[0]->GetMakefile();
+ cmGeneratedFileStream fout(filename.c_str());
+ if(!fout)
+ {
+ return;
+ }
+
+ Tree tree;
+
+ // build tree of virtual folders
+ for (std::map<cmStdString, std::vector<cmLocalGenerator*> >::const_iterator
+ it = this->GlobalGenerator->GetProjectMap().begin();
+ it != this->GlobalGenerator->GetProjectMap().end();
+ ++it)
+ {
+ // Collect all files
+ std::vector<std::string> listFiles;
+ for (std::vector<cmLocalGenerator *>::const_iterator
+ jt = it->second.begin();
+ jt != it->second.end();
+ ++jt)
+ {
+ const std::vector<std::string> & files =
+ (*jt)->GetMakefile()->GetListFiles();
+ listFiles.insert(listFiles.end(), files.begin(), files.end());
+ }
+
+ // Convert
+ const char* cmakeRoot = mf->GetDefinition("CMAKE_ROOT");
+ for (std::vector<std::string>::const_iterator jt = listFiles.begin();
+ jt != listFiles.end();
+ ++jt)
+ {
+ // don't put cmake's own files into the project (#12110):
+ if (jt->find(cmakeRoot) == 0)
+ {
+ continue;
+ }
+
+ const std::string &relative = cmSystemTools::RelativePath(
+ it->second[0]->GetMakefile()->GetHomeDirectory(),
+ jt->c_str());
+ std::vector<std::string> splitted;
+ cmSystemTools::SplitPath(relative.c_str(), splitted, false);
+ // Split filename from path
+ std::string fileName = *(splitted.end()-1);
+ splitted.erase(splitted.end() - 1, splitted.end());
+
+ // We don't want paths with CMakeFiles in them
+ // or do we?
+ // In speedcrunch those where purely internal
+ if (splitted.size() >= 1
+ && relative.find("CMakeFiles") == std::string::npos)
+ {
+ tree.InsertPath(splitted, 1, fileName);
+ }
+ }
+ }
+
+ // Now build a virtual tree string
+ std::string virtualFolders;
+ tree.BuildVirtualFolder(virtualFolders);
+ // And one for <Unit>
+ std::string unitFiles;
+ tree.BuildUnit(unitFiles, std::string(mf->GetHomeDirectory()) + "/");
+
+ // figure out the compiler
+ std::string compiler = this->GetCBCompilerId(mf);
+ std::string make = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM");
+
+ fout<<"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>\n"
+ "<CodeBlocks_project_file>\n"
+ " <FileVersion major=\"1\" minor=\"6\" />\n"
+ " <Project>\n"
+ " <Option title=\"" << mf->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());
+
+ // 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();
+ ti != targets.end(); ti++)
+ {
+ switch(ti->second.GetType())
+ {
+ case cmTarget::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)
+ {
+ this->AppendTarget(fout, ti->first.c_str(), 0,
+ make.c_str(), makefile, compiler.c_str());
+ }
+ }
+ break;
+ case cmTarget::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")))
+ {
+ break;
+ }
+
+ this->AppendTarget(fout, ti->first.c_str(), 0,
+ make.c_str(), makefile, compiler.c_str());
+ break;
+ case cmTarget::EXECUTABLE:
+ case cmTarget::STATIC_LIBRARY:
+ case cmTarget::SHARED_LIBRARY:
+ case cmTarget::MODULE_LIBRARY:
+ case cmTarget::OBJECT_LIBRARY:
+ {
+ this->AppendTarget(fout, ti->first.c_str(), &ti->second,
+ make.c_str(), makefile, compiler.c_str());
+ std::string fastTarget = ti->first;
+ fastTarget += "/fast";
+ this->AppendTarget(fout, fastTarget.c_str(), &ti->second,
+ make.c_str(), makefile, compiler.c_str());
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ 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;
+ 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++)
+ {
+ switch(ti->second.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
+ {
+ const std::vector<cmSourceFile*>&sources=ti->second.GetSourceFiles();
+ for (std::vector<cmSourceFile*>::const_iterator si=sources.begin();
+ si!=sources.end(); si++)
+ {
+ // don't add source files which have the GENERATED property set:
+ if ((*si)->GetPropertyAsBool("GENERATED"))
+ {
+ continue;
+ }
+
+ // check whether it is a C/C++ implementation file
+ bool isCFile = false;
+ if ((*si)->GetLanguage() && (*(*si)->GetLanguage() == 'C'))
+ {
+ for(std::vector<std::string>::const_iterator
+ ext = mf->GetSourceExtensions().begin();
+ ext != mf->GetSourceExtensions().end();
+ ++ext)
+ {
+ if ((*si)->GetExtension() == *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 = mf->GetHeaderExtensions().begin();
+ ext != mf->GetHeaderExtensions().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;
+ }
+ }
+ }
+
+ // 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();
+ ++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";
+ }
+
+ // Add CMakeLists.txt
+ fout<<unitFiles;
+
+ fout<<" </Project>\n"
+ "</CodeBlocks_project_file>\n";
+}
+
+
+// Write a dummy file for OBJECT libraries, so C::B can reference some file
+std::string cmExtraCodeBlocksGenerator::CreateDummyTargetFile(
+ cmMakefile* mf, cmTarget* 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();
+ filename += "/";
+ filename += mf->GetLocalGenerator()->GetTargetDirectory(*target);
+ filename += "/";
+ filename += target->GetName();
+ filename += ".objlib";
+ cmGeneratedFileStream fout(filename.c_str());
+ if(fout)
+ {
+ fout << "# This is a dummy file for the OBJECT library "
+ << target->GetName()
+ << " for the CMake CodeBlocks project generator.\n"
+ << "# Don't edit, this file will be overwritten.\n";
+ }
+ return filename;
+}
+
+
+// Generate the xml code for one target.
+void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout,
+ const char* targetName,
+ cmTarget* target,
+ const char* make,
+ const cmMakefile* makefile,
+ const char* compiler)
+{
+ std::string makefileName = makefile->GetStartOutputDirectory();
+ 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)
+ {
+ // Determine the directory where the executable target is created, and
+ // set the working directory to this dir.
+ const char* runtimeOutputDir = makefile->GetDefinition(
+ "CMAKE_RUNTIME_OUTPUT_DIRECTORY");
+ if (runtimeOutputDir != 0)
+ {
+ workingDir = runtimeOutputDir;
+ }
+ else
+ {
+ const char* executableOutputDir = makefile->GetDefinition(
+ "EXECUTABLE_OUTPUT_PATH");
+ if (executableOutputDir != 0)
+ {
+ workingDir = executableOutputDir;
+ }
+ }
+ }
+
+ const char* buildType = makefile->GetDefinition("CMAKE_BUILD_TYPE");
+ std::string location;
+ if ( target->GetType()==cmTarget::OBJECT_LIBRARY)
+ {
+ location = this->CreateDummyTargetFile(const_cast<cmMakefile*>(makefile),
+ target);
+ }
+ else
+ {
+ location = target->GetLocation(buildType);
+ }
+
+ fout<<" <Option output=\"" << location
+ << "\" prefix_auto=\"0\" extension_auto=\"0\" />\n"
+ " <Option working_dir=\"" << workingDir << "\" />\n"
+ " <Option object_output=\"./\" />\n"
+ " <Option type=\"" << cbTargetType << "\" />\n"
+ " <Option compiler=\"" << compiler << "\" />\n"
+ " <Compiler>\n";
+
+ // the compilerdefines for this target
+ const char* cdefs = target->GetMakefile()->GetProperty(
+ "COMPILE_DEFINITIONS");
+ if(cdefs)
+ {
+ // Expand the list.
+ std::vector<std::string> defs;
+ cmSystemTools::ExpandListArgument(cdefs, defs);
+ for(std::vector<std::string>::const_iterator di = defs.begin();
+ di != defs.end(); ++di)
+ {
+ cmXMLSafe safedef(di->c_str());
+ fout <<" <Add option=\"-D" << safedef.str() << "\" />\n";
+ }
+ }
+
+ // the include directories for this target
+ std::set<std::string> uniqIncludeDirs;
+
+ std::vector<std::string> includes;
+ target->GetMakefile()->GetLocalGenerator()->
+ GetIncludeDirectories(includes, target);
+ for(std::vector<std::string>::const_iterator dirIt=includes.begin();
+ dirIt != includes.end();
+ ++dirIt)
+ {
+ uniqIncludeDirs.insert(*dirIt);
+ }
+
+ 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);
+ }
+ }
+
+ systemIncludeDirs = makefile->GetSafeDefinition(
+ "CMAKE_EXTRA_GENERATOR_CXX_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);
+ }
+ }
+
+ for(std::set<std::string>::const_iterator dirIt=uniqIncludeDirs.begin();
+ dirIt != uniqIncludeDirs.end();
+ ++dirIt)
+ {
+ fout <<" <Add directory=\"" << dirIt->c_str() << "\" />\n";
+ }
+
+ fout<<" </Compiler>\n";
+ }
+ else // e.g. all and the GLOBAL and UTILITY targets
+ {
+ fout<<" <Option working_dir=\""
+ << makefile->GetStartOutputDirectory() << "\" />\n"
+ <<" <Option type=\"" << 4 << "\" />\n";
+ }
+
+ fout<<" <MakeCommands>\n"
+ " <Build command=\""
+ << this->BuildMakeCommand(make, makefileName.c_str(), targetName)
+ << "\" />\n"
+ " <CompileFile command=\""
+ << this->BuildMakeCommand(make, makefileName.c_str(),"&quot;$file&quot;")
+ << "\" />\n"
+ " <Clean command=\""
+ << this->BuildMakeCommand(make, makefileName.c_str(), "clean")
+ << "\" />\n"
+ " <DistClean command=\""
+ << this->BuildMakeCommand(make, makefileName.c_str(), "clean")
+ << "\" />\n"
+ " </MakeCommands>\n"
+ " </Target>\n";
+
+}
+
+
+// Translate the cmake compiler id into the CodeBlocks compiler id
+std::string cmExtraCodeBlocksGenerator::GetCBCompilerId(const cmMakefile* mf)
+{
+ // 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 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 compiler = "gcc"; // default to gcc
+ if (compilerId == "MSVC")
+ {
+ compiler = "msvc8";
+ }
+ else if (compilerId == "Borland")
+ {
+ compiler = "bcc";
+ }
+ else if (compilerId == "SDCC")
+ {
+ compiler = "sdcc";
+ }
+ else if (compilerId == "Intel")
+ {
+ compiler = "icc";
+ }
+ else if (compilerId == "Watcom")
+ {
+ compiler = "ow";
+ }
+ else if (compilerId == "GNU")
+ {
+ compiler = "gcc";
+ }
+ return compiler;
+}
+
+
+// Translate the cmake target type into the CodeBlocks target type id
+int cmExtraCodeBlocksGenerator::GetCBTargetType(cmTarget* target)
+{
+ if ( target->GetType()==cmTarget::EXECUTABLE)
+ {
+ if ((target->GetPropertyAsBool("WIN32_EXECUTABLE"))
+ || (target->GetPropertyAsBool("MACOSX_BUNDLE")))
+ {
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
+ }
+ else if (( target->GetType()==cmTarget::STATIC_LIBRARY)
+ || (target->GetType()==cmTarget::OBJECT_LIBRARY))
+ {
+ return 2;
+ }
+ else if ((target->GetType()==cmTarget::SHARED_LIBRARY)
+ || (target->GetType()==cmTarget::MODULE_LIBRARY))
+ {
+ return 3;
+ }
+ return 4;
+}
+
+// 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)
+{
+ std::string command = make;
+ if (strcmp(this->GlobalGenerator->GetName(), "NMake Makefiles")==0)
+ {
+ std::string makefileName = cmSystemTools::ConvertToOutputPath(makefile);
+ command += " /NOLOGO /f &quot;";
+ command += makefileName;
+ command += "&quot; ";
+ command += " VERBOSE=1 ";
+ command += target;
+ }
+ else if (strcmp(this->GlobalGenerator->GetName(), "MinGW Makefiles")==0)
+ {
+ // no escaping of spaces in this case, see
+ // http://public.kitware.com/Bug/view.php?id=10014
+ std::string makefileName = makefile;
+ command += " -f &quot;";
+ command += makefileName;
+ command += "&quot; ";
+ command += " VERBOSE=1 ";
+ command += target;
+ }
+ else
+ {
+ std::string makefileName = cmSystemTools::ConvertToOutputPath(makefile);
+ command += " -f &quot;";
+ command += makefileName;
+ command += "&quot; ";
+ command += " VERBOSE=1 ";
+ command += target;
+ }
+ return command;
+}
diff --git a/Source/cmExtraCodeBlocksGenerator.h b/Source/cmExtraCodeBlocksGenerator.h
new file mode 100644
index 000000000..e0a64ca01
--- /dev/null
+++ b/Source/cmExtraCodeBlocksGenerator.h
@@ -0,0 +1,62 @@
+/*============================================================================
+ 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.
+============================================================================*/
+#ifndef cmExtraCodeBlocksGenerator_h
+#define cmExtraCodeBlocksGenerator_h
+
+#include "cmExternalMakefileProjectGenerator.h"
+
+class cmLocalGenerator;
+class cmMakefile;
+class cmTarget;
+class cmGeneratedFileStream;
+
+/** \class cmExtraCodeBlocksGenerator
+ * \brief Write CodeBlocks project files for Makefile based projects
+ */
+class cmExtraCodeBlocksGenerator : public cmExternalMakefileProjectGenerator
+{
+public:
+ cmExtraCodeBlocksGenerator();
+
+ virtual const char* GetName() const
+ { return cmExtraCodeBlocksGenerator::GetActualName();}
+ static const char* 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;
+
+ virtual void Generate();
+private:
+
+ 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 GetCBCompilerId(const cmMakefile* mf);
+ int GetCBTargetType(cmTarget* target);
+ std::string BuildMakeCommand(const std::string& make, const char* makefile,
+ const char* target);
+ void AppendTarget(cmGeneratedFileStream& fout,
+ const char* targetName,
+ cmTarget* target,
+ const char* make,
+ const cmMakefile* makefile,
+ const char* compiler);
+
+};
+
+#endif
diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx
new file mode 100644
index 000000000..78a87047a
--- /dev/null
+++ b/Source/cmExtraEclipseCDT4Generator.cxx
@@ -0,0 +1,1367 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2004-2009 Kitware, Inc.
+ Copyright 2004 Alexander Neundorf (neundorf@kde.org)
+ Copyright 2007 Miguel A. Figueroa-Villanueva
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software 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 "cmExtraEclipseCDT4Generator.h"
+#include "cmGlobalUnixMakefileGenerator3.h"
+#include "cmLocalUnixMakefileGenerator3.h"
+#include "cmMakefile.h"
+#include "cmGeneratedFileStream.h"
+#include "cmTarget.h"
+#include "cmSourceFile.h"
+
+#include "cmSystemTools.h"
+#include <stdlib.h>
+#include <assert.h>
+
+//----------------------------------------------------------------------------
+cmExtraEclipseCDT4Generator
+::cmExtraEclipseCDT4Generator() : cmExternalMakefileProjectGenerator()
+{
+// TODO: Verify if __CYGWIN__ should be checked.
+//#if defined(_WIN32) && !defined(__CYGWIN__)
+#if defined(_WIN32)
+ this->SupportedGlobalGenerators.push_back("NMake Makefiles");
+ this->SupportedGlobalGenerators.push_back("MinGW Makefiles");
+// this->SupportedGlobalGenerators.push_back("MSYS Makefiles");
+#endif
+ this->SupportedGlobalGenerators.push_back("Ninja");
+ this->SupportedGlobalGenerators.push_back("Unix Makefiles");
+
+ this->SupportsVirtualFolders = true;
+}
+
+//----------------------------------------------------------------------------
+void cmExtraEclipseCDT4Generator
+::GetDocumentation(cmDocumentationEntry& entry, const char*) 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::Generate()
+{
+ const cmMakefile* mf
+ = this->GlobalGenerator->GetLocalGenerators()[0]->GetMakefile();
+
+ std::string eclipseVersion = mf->GetSafeDefinition("CMAKE_ECLIPSE_VERSION");
+ cmsys::RegularExpression regex(".*([0-9]+\\.[0-9]+).*");
+ if (regex.find(eclipseVersion.c_str()))
+ {
+ unsigned int majorVersion = 0;
+ unsigned int minorVersion = 0;
+ int res=sscanf(regex.match(1).c_str(), "%u.%u", &majorVersion,
+ &minorVersion);
+ if (res == 2)
+ {
+ int version = majorVersion * 1000 + minorVersion;
+ if (version < 3006) // 3.6 is Helios
+ {
+ this->SupportsVirtualFolders = false;
+ }
+ }
+ }
+
+ // TODO: Decide if these are local or member variables
+ this->HomeDirectory = mf->GetHomeDirectory();
+ this->HomeOutputDirectory = mf->GetHomeOutputDirectory();
+
+ this->IsOutOfSourceBuild = (this->HomeDirectory!=this->HomeOutputDirectory);
+
+ this->GenerateSourceProject = (this->IsOutOfSourceBuild &&
+ mf->IsOn("CMAKE_ECLIPSE_GENERATE_SOURCE_PROJECT"));
+
+ if ((this->GenerateSourceProject == false)
+ && (mf->IsOn("ECLIPSE_CDT4_GENERATE_SOURCE_PROJECT")))
+ {
+ mf->IssueMessage(cmake::WARNING,
+ "ECLIPSE_CDT4_GENERATE_SOURCE_PROJECT is set to TRUE, "
+ "but this variable is not supported anymore since CMake 2.8.7.\n"
+ "Enable CMAKE_ECLIPSE_GENERATE_SOURCE_PROJECT instead.");
+ }
+
+ if (cmSystemTools::IsSubDirectory(this->HomeOutputDirectory.c_str(),
+ this->HomeDirectory.c_str()))
+ {
+ mf->IssueMessage(cmake::WARNING, "The build directory is a subdirectory "
+ "of the source directory.\n"
+ "This is not supported well by Eclipse. It is strongly "
+ "recommended to use a build directory which is a "
+ "sibling of the source directory.");
+ }
+
+ // NOTE: This is not good, since it pollutes the source tree. However,
+ // Eclipse doesn't allow CVS/SVN to work when the .project is not in
+ // the cvs/svn root directory. Hence, this is provided as an option.
+ if (this->GenerateSourceProject)
+ {
+ // create .project file in the source tree
+ this->CreateSourceProjectFile();
+ }
+
+ // create a .project file
+ this->CreateProjectFile();
+
+ // create a .cproject file
+ this->CreateCProjectFile();
+}
+
+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",
+ this->GetPathBasename(this->HomeDirectory));
+
+ const std::string filename = this->HomeDirectory + "/.project";
+ cmGeneratedFileStream fout(filename.c_str());
+ if (!fout)
+ {
+ return;
+ }
+
+ fout <<
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<projectDescription>\n"
+ "\t<name>" << this->EscapeForXML(name) << "</name>\n"
+ "\t<comment></comment>\n"
+ "\t<projects>\n"
+ "\t</projects>\n"
+ "\t<buildSpec>\n"
+ "\t</buildSpec>\n"
+ "\t<natures>\n"
+ "\t</natures>\n"
+ "\t<linkedResources>\n";
+
+ if (this->SupportsVirtualFolders)
+ {
+ this->CreateLinksToSubprojects(fout, this->HomeDirectory);
+ this->SrcLinkedResources.clear();
+ }
+
+ fout <<
+ "\t</linkedResources>\n"
+ "</projectDescription>\n"
+ ;
+}
+
+
+//----------------------------------------------------------------------------
+void cmExtraEclipseCDT4Generator::AddEnvVar(cmGeneratedFileStream& fout,
+ const char* envVar, cmMakefile* mf)
+{
+ // get the variables from the environment and from the cache and then
+ // figure out which one to use:
+
+ const char* envVarValue = getenv(envVar);
+
+ std::string cacheEntryName = "CMAKE_ECLIPSE_ENVVAR_";
+ cacheEntryName += envVar;
+ const char* cacheValue = mf->GetCacheManager()->GetCacheValue(
+ cacheEntryName.c_str());
+
+ // now we have both, decide which one to use
+ std::string valueToUse;
+ if (envVarValue==0 && cacheValue==0)
+ {
+ // nothing known, do nothing
+ valueToUse = "";
+ }
+ else if (envVarValue!=0 && cacheValue==0)
+ {
+ // 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,
+ true);
+ mf->GetCacheManager()->SaveCache(mf->GetHomeOutputDirectory());
+ }
+ else if (envVarValue==0 && cacheValue!=0)
+ {
+ // It is already in the cache, but not in the env, so use it from the cache
+ valueToUse = cacheValue;
+ }
+ else
+ {
+ // It is both in the cache and in the env.
+ // Use the version from the env. except if the value from the env is
+ // completely contained in the value from the cache (for the case that we
+ // now have a PATH without MSVC dirs in the env. but had the full PATH with
+ // all MSVC dirs during the cmake run which stored the var in the cache:
+ valueToUse = cacheValue;
+ if (valueToUse.find(envVarValue) == std::string::npos)
+ {
+ valueToUse = envVarValue;
+ mf->AddCacheDefinition(cacheEntryName.c_str(), valueToUse.c_str(),
+ cacheEntryName.c_str(), cmCacheManager::STRING,
+ true);
+ mf->GetCacheManager()->SaveCache(mf->GetHomeOutputDirectory());
+ }
+ }
+
+ if (!valueToUse.empty())
+ {
+ fout << envVar << "=" << valueToUse << "|";
+ }
+}
+
+
+//----------------------------------------------------------------------------
+void cmExtraEclipseCDT4Generator::CreateProjectFile()
+{
+ cmMakefile* mf
+ = this->GlobalGenerator->GetLocalGenerators()[0]->GetMakefile();
+
+ const std::string filename = this->HomeOutputDirectory + "/.project";
+
+ cmGeneratedFileStream fout(filename.c_str());
+ if (!fout)
+ {
+ return;
+ }
+
+ std::string compilerId = mf->GetSafeDefinition("CMAKE_C_COMPILER_ID");
+ if (compilerId.empty()) // no C compiler, try the C++ compiler:
+ {
+ compilerId = mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID");
+ }
+
+ fout <<
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<projectDescription>\n"
+ "\t<name>" <<
+ this->GenerateProjectName(mf->GetProjectName(),
+ mf->GetSafeDefinition("CMAKE_BUILD_TYPE"),
+ this->GetPathBasename(this->HomeOutputDirectory))
+ << "</name>\n"
+ "\t<comment></comment>\n"
+ "\t<projects>\n"
+ "\t</projects>\n"
+ "\t<buildSpec>\n"
+ "\t\t<buildCommand>\n"
+ "\t\t\t<name>org.eclipse.cdt.make.core.makeBuilder</name>\n"
+ "\t\t\t<triggers>clean,full,incremental,</triggers>\n"
+ "\t\t\t<arguments>\n"
+ ;
+
+ // use clean target
+ fout <<
+ "\t\t\t\t<dictionary>\n"
+ "\t\t\t\t\t<key>org.eclipse.cdt.make.core.cleanBuildTarget</key>\n"
+ "\t\t\t\t\t<value>clean</value>\n"
+ "\t\t\t\t</dictionary>\n"
+ "\t\t\t\t<dictionary>\n"
+ "\t\t\t\t\t<key>org.eclipse.cdt.make.core.enableCleanBuild</key>\n"
+ "\t\t\t\t\t<value>true</value>\n"
+ "\t\t\t\t</dictionary>\n"
+ "\t\t\t\t<dictionary>\n"
+ "\t\t\t\t\t<key>org.eclipse.cdt.make.core.append_environment</key>\n"
+ "\t\t\t\t\t<value>true</value>\n"
+ "\t\t\t\t</dictionary>\n"
+ "\t\t\t\t<dictionary>\n"
+ "\t\t\t\t\t<key>org.eclipse.cdt.make.core.stopOnError</key>\n"
+ "\t\t\t\t\t<value>true</value>\n"
+ "\t\t\t\t</dictionary>\n"
+ ;
+
+ // set the make command
+ std::string make = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM");
+ const std::string makeArgs = mf->GetSafeDefinition(
+ "CMAKE_ECLIPSE_MAKE_ARGUMENTS");
+
+ fout <<
+ "\t\t\t\t<dictionary>\n"
+ "\t\t\t\t\t<key>org.eclipse.cdt.make.core.enabledIncrementalBuild</key>\n"
+ "\t\t\t\t\t<value>true</value>\n"
+ "\t\t\t\t</dictionary>\n"
+ "\t\t\t\t<dictionary>\n"
+ "\t\t\t\t\t<key>org.eclipse.cdt.make.core.build.command</key>\n"
+ "\t\t\t\t\t<value>" << this->GetEclipsePath(make) << "</value>\n"
+ "\t\t\t\t</dictionary>\n"
+ "\t\t\t\t<dictionary>\n"
+ "\t\t\t\t\t<key>org.eclipse.cdt.make.core.contents</key>\n"
+ "\t\t\t\t\t<value>org.eclipse.cdt.make.core.activeConfigSettings</value>\n"
+ "\t\t\t\t</dictionary>\n"
+ "\t\t\t\t<dictionary>\n"
+ "\t\t\t\t\t<key>org.eclipse.cdt.make.core.build.target.inc</key>\n"
+ "\t\t\t\t\t<value>all</value>\n"
+ "\t\t\t\t</dictionary>\n"
+ "\t\t\t\t<dictionary>\n"
+ "\t\t\t\t\t<key>org.eclipse.cdt.make.core.build.arguments</key>\n"
+ "\t\t\t\t\t<value>" << makeArgs << "</value>\n"
+ "\t\t\t\t</dictionary>\n"
+ "\t\t\t\t<dictionary>\n"
+ "\t\t\t\t\t<key>org.eclipse.cdt.make.core.buildLocation</key>\n"
+ "\t\t\t\t\t<value>"
+ << this->GetEclipsePath(this->HomeOutputDirectory) << "</value>\n"
+ "\t\t\t\t</dictionary>\n"
+ "\t\t\t\t<dictionary>\n"
+ "\t\t\t\t\t<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>\n"
+ "\t\t\t\t\t<value>false</value>\n"
+ "\t\t\t\t</dictionary>\n"
+ ;
+
+ // set project specific environment
+ fout <<
+ "\t\t\t\t<dictionary>\n"
+ "\t\t\t\t\t<key>org.eclipse.cdt.make.core.environment</key>\n"
+ "\t\t\t\t\t<value>VERBOSE=1|CMAKE_NO_VERBOSE=1|" //verbose Makefile output
+ ;
+ // set vsvars32.bat environment available at CMake time,
+ // 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);
+ }
+ 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);
+ }
+ fout <<
+ "</value>\n"
+ "\t\t\t\t</dictionary>\n"
+ ;
+
+ fout <<
+ "\t\t\t\t<dictionary>\n"
+ "\t\t\t\t\t<key>org.eclipse.cdt.make.core.enableFullBuild</key>\n"
+ "\t\t\t\t\t<value>true</value>\n"
+ "\t\t\t\t</dictionary>\n"
+ "\t\t\t\t<dictionary>\n"
+ "\t\t\t\t\t<key>org.eclipse.cdt.make.core.build.target.auto</key>\n"
+ "\t\t\t\t\t<value>all</value>\n"
+ "\t\t\t\t</dictionary>\n"
+ "\t\t\t\t<dictionary>\n"
+ "\t\t\t\t\t<key>org.eclipse.cdt.make.core.enableAutoBuild</key>\n"
+ "\t\t\t\t\t<value>false</value>\n"
+ "\t\t\t\t</dictionary>\n"
+ "\t\t\t\t<dictionary>\n"
+ "\t\t\t\t\t<key>org.eclipse.cdt.make.core.build.target.clean</key>\n"
+ "\t\t\t\t\t<value>clean</value>\n"
+ "\t\t\t\t</dictionary>\n"
+ "\t\t\t\t<dictionary>\n"
+ "\t\t\t\t\t<key>org.eclipse.cdt.make.core.fullBuildTarget</key>\n"
+ "\t\t\t\t\t<value>all</value>\n"
+ "\t\t\t\t</dictionary>\n"
+ "\t\t\t\t<dictionary>\n"
+ "\t\t\t\t\t<key>org.eclipse.cdt.make.core.buildArguments</key>\n"
+ "\t\t\t\t\t<value></value>\n"
+ "\t\t\t\t</dictionary>\n"
+ "\t\t\t\t<dictionary>\n"
+ "\t\t\t\t\t<key>org.eclipse.cdt.make.core.build.location</key>\n"
+ "\t\t\t\t\t<value>"
+ << this->GetEclipsePath(this->HomeOutputDirectory) << "</value>\n"
+ "\t\t\t\t</dictionary>\n"
+ "\t\t\t\t<dictionary>\n"
+ "\t\t\t\t\t<key>org.eclipse.cdt.make.core.autoBuildTarget</key>\n"
+ "\t\t\t\t\t<value>all</value>\n"
+ "\t\t\t\t</dictionary>\n"
+ ;
+
+ // set error parsers
+ fout <<
+ "\t\t\t\t<dictionary>\n"
+ "\t\t\t\t\t<key>org.eclipse.cdt.core.errorOutputParser</key>\n"
+ "\t\t\t\t\t<value>"
+ ;
+ if (compilerId == "MSVC")
+ {
+ fout << "org.eclipse.cdt.core.VCErrorParser;";
+ }
+ else if (compilerId == "Intel")
+ {
+ fout << "org.eclipse.cdt.core.ICCErrorParser;";
+ }
+ fout <<
+ "org.eclipse.cdt.core.MakeErrorParser;"
+ "org.eclipse.cdt.core.GCCErrorParser;"
+ "org.eclipse.cdt.core.GASErrorParser;"
+ "org.eclipse.cdt.core.GLDErrorParser;"
+ "</value>\n"
+ "\t\t\t\t</dictionary>\n"
+ ;
+
+ fout <<
+ "\t\t\t</arguments>\n"
+ "\t\t</buildCommand>\n"
+ "\t\t<buildCommand>\n"
+ "\t\t\t<name>org.eclipse.cdt.make.core.ScannerConfigBuilder</name>\n"
+ "\t\t\t<arguments>\n"
+ "\t\t\t</arguments>\n"
+ "\t\t</buildCommand>\n"
+ "\t</buildSpec>\n"
+ ;
+
+ // 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"
+ ;
+
+ fout << "\t<linkedResources>\n";
+ // create linked resources
+ if (this->IsOutOfSourceBuild)
+ {
+ // create a linked resource to CMAKE_SOURCE_DIR
+ // (this is not done anymore for each project because of
+ // http://public.kitware.com/Bug/view.php?id=9978 and because I found it
+ // actually quite confusing in bigger projects with many directories and
+ // projects, Alex
+
+ std::string sourceLinkedResourceName = "[Source directory]";
+ std::string linkSourceDirectory = this->GetEclipsePath(
+ mf->GetStartDirectory());
+ // .project dir can't be subdir of a linked resource dir
+ if (!cmSystemTools::IsSubDirectory(this->HomeOutputDirectory.c_str(),
+ linkSourceDirectory.c_str()))
+ {
+ this->AppendLinkedResource(fout, sourceLinkedResourceName,
+ this->GetEclipsePath(linkSourceDirectory),
+ LinkToFolder);
+ this->SrcLinkedResources.push_back(sourceLinkedResourceName);
+ }
+
+ }
+
+ if (this->SupportsVirtualFolders)
+ {
+ this->CreateLinksToSubprojects(fout, this->HomeOutputDirectory);
+
+ this->CreateLinksForTargets(fout);
+ }
+
+ // I'm not sure this makes too much sense. There can be different
+ // output directories in different subdirs, so we would need more of them.
+
+ // for EXECUTABLE_OUTPUT_PATH when not in binary dir
+ this->AppendOutLinkedResource(fout,
+ mf->GetSafeDefinition("CMAKE_RUNTIME_OUTPUT_DIRECTORY"),
+ mf->GetSafeDefinition("EXECUTABLE_OUTPUT_PATH"));
+ // for LIBRARY_OUTPUT_PATH when not in binary dir
+ this->AppendOutLinkedResource(fout,
+ mf->GetSafeDefinition("CMAKE_LIBRARY_OUTPUT_DIRECTORY"),
+ mf->GetSafeDefinition("LIBRARY_OUTPUT_PATH"));
+
+ fout << "\t</linkedResources>\n";
+
+ fout << "</projectDescription>\n";
+}
+
+
+//----------------------------------------------------------------------------
+void cmExtraEclipseCDT4Generator::CreateLinksForTargets(
+ cmGeneratedFileStream& fout)
+{
+ std::string linkName = "[Targets]";
+ this->AppendLinkedResource(fout, linkName, "virtual:/virtual",VirtualFolder);
+
+ for (std::vector<cmLocalGenerator*>::const_iterator
+ lgIt = this->GlobalGenerator->GetLocalGenerators().begin();
+ lgIt != this->GlobalGenerator->GetLocalGenerators().end();
+ ++lgIt)
+ {
+ cmMakefile* makefile = (*lgIt)->GetMakefile();
+ const cmTargets& targets = makefile->GetTargets();
+
+ for(cmTargets::const_iterator ti=targets.begin(); ti!=targets.end();++ti)
+ {
+ std::string linkName2 = linkName;
+ linkName2 += "/";
+ switch(ti->second.GetType())
+ {
+ case cmTarget::EXECUTABLE:
+ case cmTarget::STATIC_LIBRARY:
+ case cmTarget::SHARED_LIBRARY:
+ case cmTarget::MODULE_LIBRARY:
+ case cmTarget::OBJECT_LIBRARY:
+ {
+ const char* prefix = (ti->second.GetType()==cmTarget::EXECUTABLE ?
+ "[exe] " : "[lib] ");
+ linkName2 += prefix;
+ linkName2 += ti->first;
+ this->AppendLinkedResource(fout, linkName2, "virtual:/virtual",
+ VirtualFolder);
+ 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();
+ 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 =
+ makefile->FindSourceGroup(source.c_str(), sourceGroups);
+ sourceGroup.AssignSource(*sfIt);
+ }
+
+ for(std::vector<cmSourceGroup>::iterator sgIt = sourceGroups.begin();
+ sgIt != sourceGroups.end();
+ ++sgIt)
+ {
+ std::string linkName3 = linkName2;
+ linkName3 += "/";
+ linkName3 += sgIt->GetFullName();
+ this->AppendLinkedResource(fout, linkName3, "virtual:/virtual",
+ VirtualFolder);
+
+ std::vector<const cmSourceFile*> sFiles = sgIt->GetSourceFiles();
+ for(std::vector<const cmSourceFile*>::const_iterator fileIt =
+ sFiles.begin();
+ fileIt != sFiles.end();
+ ++fileIt)
+ {
+ std::string linkName4 = linkName3;
+ linkName4 += "/";
+ linkName4 +=
+ cmSystemTools::GetFilenameName((*fileIt)->GetFullPath());
+ this->AppendLinkedResource(fout, linkName4,
+ (*fileIt)->GetFullPath(), LinkToFile);
+ }
+ }
+ }
+ break;
+ // ignore all others:
+ default:
+ break;
+ }
+ }
+ }
+}
+
+
+//----------------------------------------------------------------------------
+void cmExtraEclipseCDT4Generator::CreateLinksToSubprojects(
+ cmGeneratedFileStream& fout, const std::string& baseDir)
+{
+ // for each sub project create a linked resource to the source dir
+ // - only if it is an out-of-source build
+ this->AppendLinkedResource(fout, "[Subprojects]",
+ "virtual:/virtual", VirtualFolder);
+
+ for (std::map<cmStdString, 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());
+ // 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()))
+ {
+ std::string linkName = "[Subprojects]/";
+ linkName += it->first;
+ this->AppendLinkedResource(fout, linkName,
+ this->GetEclipsePath(linkSourceDirectory),
+ LinkToFolder
+ );
+ this->SrcLinkedResources.push_back(it->first);
+ }
+ }
+}
+
+
+//----------------------------------------------------------------------------
+void cmExtraEclipseCDT4Generator::AppendIncludeDirectories(
+ cmGeneratedFileStream& fout,
+ const std::vector<std::string>& includeDirs,
+ std::set<std::string>& emittedDirs)
+{
+ for(std::vector<std::string>::const_iterator inc = includeDirs.begin();
+ inc != includeDirs.end();
+ ++inc)
+ {
+ if (!inc->empty())
+ {
+ std::string dir = cmSystemTools::CollapseFullPath(inc->c_str());
+ if(emittedDirs.find(dir) == emittedDirs.end())
+ {
+ emittedDirs.insert(dir);
+ fout << "<pathentry include=\""
+ << cmExtraEclipseCDT4Generator::EscapeForXML(
+ cmExtraEclipseCDT4Generator::GetEclipsePath(dir))
+ << "\" kind=\"inc\" path=\"\" system=\"true\"/>\n";
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
+{
+ std::set<std::string> emmited;
+
+ const cmMakefile* mf
+ = this->GlobalGenerator->GetLocalGenerators()[0]->GetMakefile();
+
+ const std::string filename = this->HomeOutputDirectory + "/.cproject";
+
+ cmGeneratedFileStream fout(filename.c_str());
+ if (!fout)
+ {
+ return;
+ }
+
+ // add header
+ fout <<
+ "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
+ "<?fileVersion 4.0.0?>\n\n"
+ "<cproject>\n"
+ "<storageModule moduleId=\"org.eclipse.cdt.core.settings\">\n"
+ ;
+
+ fout << "<cconfiguration id=\"org.eclipse.cdt.core.default.config.1\">\n";
+
+ // Configuration settings...
+ fout <<
+ "<storageModule"
+ " buildSystemId=\"org.eclipse.cdt.core.defaultConfigDataProvider\""
+ " id=\"org.eclipse.cdt.core.default.config.1\""
+ " moduleId=\"org.eclipse.cdt.core.settings\" name=\"Configuration\">\n"
+ "<externalSettings/>\n"
+ "<extensions>\n"
+ ;
+ // TODO: refactor this out...
+ std::string executableFormat = mf->GetSafeDefinition(
+ "CMAKE_EXECUTABLE_FORMAT");
+ if (executableFormat == "ELF")
+ {
+ fout << "<extension id=\"org.eclipse.cdt.core.ELF\""
+ " point=\"org.eclipse.cdt.core.BinaryParser\"/>\n"
+ ;
+ fout << "<extension id=\"org.eclipse.cdt.core.GNU_ELF\""
+ " point=\"org.eclipse.cdt.core.BinaryParser\">\n"
+ "<attribute key=\"addr2line\" value=\"addr2line\"/>\n"
+ "<attribute key=\"c++filt\" value=\"c++filt\"/>\n"
+ "</extension>\n"
+ ;
+ }
+ else
+ {
+ std::string systemName = mf->GetSafeDefinition("CMAKE_SYSTEM_NAME");
+ if (systemName == "CYGWIN")
+ {
+ fout << "<extension id=\"org.eclipse.cdt.core.Cygwin_PE\""
+ " point=\"org.eclipse.cdt.core.BinaryParser\">\n"
+ "<attribute key=\"addr2line\" value=\"addr2line\"/>\n"
+ "<attribute key=\"c++filt\" value=\"c++filt\"/>\n"
+ "<attribute key=\"cygpath\" value=\"cygpath\"/>\n"
+ "<attribute key=\"nm\" value=\"nm\"/>\n"
+ "</extension>\n"
+ ;
+ }
+ else if (systemName == "Windows")
+ {
+ fout << "<extension id=\"org.eclipse.cdt.core.PE\""
+ " point=\"org.eclipse.cdt.core.BinaryParser\"/>\n"
+ ;
+ }
+ else if (systemName == "Darwin")
+ {
+ fout << "<extension id=\"org.eclipse.cdt.core.MachO\""
+ " point=\"org.eclipse.cdt.core.BinaryParser\">\n"
+ "<attribute key=\"c++filt\" value=\"c++filt\"/>\n"
+ "</extension>\n"
+ ;
+ }
+ else
+ {
+ // *** Should never get here ***
+ fout << "<error_toolchain_type/>\n";
+ }
+ }
+
+ fout << "</extensions>\n"
+ "</storageModule>\n"
+ ;
+
+ // ???
+ fout <<
+ "<storageModule moduleId=\"org.eclipse.cdt.core.language.mapping\">\n"
+ "<project-mappings/>\n"
+ "</storageModule>\n"
+ ;
+
+ // ???
+ fout<<"<storageModule moduleId=\"org.eclipse.cdt.core.externalSettings\"/>\n"
+ ;
+
+ // set the path entries (includes, libs, source dirs, etc.)
+ fout << "<storageModule moduleId=\"org.eclipse.cdt.core.pathentry\">\n"
+ ;
+ // for each sub project with a linked resource to the source dir:
+ // - make it type 'src'
+ // - and exclude it from type 'out'
+ std::string excludeFromOut;
+/* I don't know what the pathentry kind="src" are good for, e.g. autocompletion
+ * works also without them. Done wrong, the indexer complains, see #12417
+ * and #12213.
+ * The CDT documentation is very terse on that:
+ * "CDT_SOURCE: Entry kind constant describing a path entry identifying a
+ * folder containing source code to be compiled."
+ * Also on the cdt-dev list didn't bring any information:
+ * http://web.archiveorange.com/archive/v/B4NlJDNIpYoOS1SbxFNy
+ * So I'm disabling them for now, hoping that somebody will report if something
+ * is not workging anymore.
+ * Alex */
+#ifdef DO_CREATE_SRC_PATH_ENTRIES
+ for (std::vector<std::string>::const_iterator
+ it = this->SrcLinkedResources.begin();
+ it != this->SrcLinkedResources.end();
+ ++it)
+ {
+ fout << "<pathentry kind=\"src\" path=\"" << this->EscapeForXML(*it)
+ << "\"/>\n";
+
+ // 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()))
+ {
+ excludeFromOut += this->EscapeForXML(*it) + "/|";
+ }
+ }
+#endif
+ excludeFromOut += "**/CMakeFiles/";
+ fout << "<pathentry excluding=\"" << excludeFromOut
+ << "\" kind=\"out\" path=\"\"/>\n";
+ // add output entry for EXECUTABLE_OUTPUT_PATH and LIBRARY_OUTPUT_PATH
+ // - if it is a subdir of homeOutputDirectory, there is no need to add it
+ // - if it is not then create a linked resource and add the linked name
+ // but check it doesn't conflict with other linked resources names
+ for (std::vector<std::string>::const_iterator
+ it = this->OutLinkedResources.begin();
+ it != this->OutLinkedResources.end();
+ ++it)
+ {
+ fout << "<pathentry kind=\"out\" path=\"" << this->EscapeForXML(*it)
+ << "\"/>\n";
+ }
+
+ // add pre-processor definitions to allow eclipse to gray out sections
+ emmited.clear();
+ for (std::vector<cmLocalGenerator*>::const_iterator
+ it = this->GlobalGenerator->GetLocalGenerators().begin();
+ it != this->GlobalGenerator->GetLocalGenerators().end();
+ ++it)
+ {
+
+ if(const char* cdefs = (*it)->GetMakefile()->GetProperty(
+ "COMPILE_DEFINITIONS"))
+ {
+ // Expand the list.
+ std::vector<std::string> defs;
+ cmSystemTools::ExpandListArgument(cdefs, defs);
+
+ for(std::vector<std::string>::const_iterator di = defs.begin();
+ di != defs.end(); ++di)
+ {
+ std::string::size_type equals = di->find('=', 0);
+ std::string::size_type enddef = di->length();
+
+ std::string def;
+ std::string val;
+ if (equals != std::string::npos && equals < enddef)
+ {
+ // we have -DFOO=BAR
+ def = di->substr(0, equals);
+ val = di->substr(equals + 1, enddef - equals + 1);
+ }
+ else
+ {
+ // we have -DFOO
+ def = *di;
+ }
+
+ // insert the definition if not already added.
+ if(emmited.find(def) == emmited.end())
+ {
+ emmited.insert(def);
+ fout << "<pathentry kind=\"mac\" name=\"" << def
+ << "\" path=\"\" value=\"" << this->EscapeForXML(val)
+ << "\"/>\n";
+ }
+ }
+ }
+ }
+ // add system defined c macros
+ const char* cDefs=mf->GetDefinition(
+ "CMAKE_EXTRA_GENERATOR_C_SYSTEM_DEFINED_MACROS");
+ if(cDefs)
+ {
+ // Expand the list.
+ std::vector<std::string> defs;
+ cmSystemTools::ExpandListArgument(cDefs, defs, true);
+
+ // the list must contain only definition-value pairs:
+ if ((defs.size() % 2) == 0)
+ {
+ std::vector<std::string>::const_iterator di = defs.begin();
+ while (di != defs.end())
+ {
+ std::string def = *di;
+ ++di;
+ std::string val;
+ if (di != defs.end())
+ {
+ val = *di;
+ ++di;
+ }
+
+ // insert the definition if not already added.
+ if(emmited.find(def) == emmited.end())
+ {
+ emmited.insert(def);
+ fout << "<pathentry kind=\"mac\" name=\"" << def
+ << "\" path=\"\" value=\"" << this->EscapeForXML(val)
+ << "\"/>\n";
+ }
+ }
+ }
+ }
+ // add system defined c++ macros
+ const char* cxxDefs = mf->GetDefinition(
+ "CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_DEFINED_MACROS");
+ if(cxxDefs)
+ {
+ // Expand the list.
+ std::vector<std::string> defs;
+ cmSystemTools::ExpandListArgument(cxxDefs, defs, true);
+
+ // the list must contain only definition-value pairs:
+ if ((defs.size() % 2) == 0)
+ {
+ std::vector<std::string>::const_iterator di = defs.begin();
+ while (di != defs.end())
+ {
+ std::string def = *di;
+ ++di;
+ std::string val;
+ if (di != defs.end())
+ {
+ val = *di;
+ ++di;
+ }
+
+ // insert the definition if not already added.
+ if(emmited.find(def) == emmited.end())
+ {
+ emmited.insert(def);
+ fout << "<pathentry kind=\"mac\" name=\"" << def
+ << "\" path=\"\" value=\"" << this->EscapeForXML(val)
+ << "\"/>\n";
+ }
+ }
+ }
+ }
+
+ // include dirs
+ emmited.clear();
+ for (std::vector<cmLocalGenerator*>::const_iterator
+ it = this->GlobalGenerator->GetLocalGenerators().begin();
+ it != this->GlobalGenerator->GetLocalGenerators().end();
+ ++it)
+ {
+ cmTargets & targets = (*it)->GetMakefile()->GetTargets();
+ for (cmTargets::iterator l = targets.begin(); l != targets.end(); ++l)
+ {
+ std::vector<std::string> includeDirs;
+ (*it)->GetIncludeDirectories(includeDirs, &l->second);
+ this->AppendIncludeDirectories(fout, includeDirs, emmited);
+ }
+ }
+ // now also the system include directories, in case we found them in
+ // CMakeSystemSpecificInformation.cmake. This makes Eclipse find the
+ // standard headers.
+ std::string compiler = mf->GetSafeDefinition("CMAKE_C_COMPILER");
+ if (!compiler.empty())
+ {
+ std::string systemIncludeDirs = mf->GetSafeDefinition(
+ "CMAKE_EXTRA_GENERATOR_C_SYSTEM_INCLUDE_DIRS");
+ std::vector<std::string> dirs;
+ cmSystemTools::ExpandListArgument(systemIncludeDirs.c_str(), dirs);
+ this->AppendIncludeDirectories(fout, dirs, emmited);
+ }
+ compiler = mf->GetSafeDefinition("CMAKE_CXX_COMPILER");
+ if (!compiler.empty())
+ {
+ std::string systemIncludeDirs = mf->GetSafeDefinition(
+ "CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_INCLUDE_DIRS");
+ std::vector<std::string> dirs;
+ cmSystemTools::ExpandListArgument(systemIncludeDirs.c_str(), dirs);
+ this->AppendIncludeDirectories(fout, dirs, emmited);
+ }
+
+ fout << "</storageModule>\n";
+
+ // add build targets
+ fout <<
+ "<storageModule moduleId=\"org.eclipse.cdt.make.core.buildtargets\">\n"
+ "<buildTargets>\n"
+ ;
+ emmited.clear();
+ 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);
+
+ std::string allTarget;
+ std::string cleanTarget;
+ if (generator->GetAllTargetName())
+ {
+ allTarget = generator->GetAllTargetName();
+ }
+ if (generator->GetCleanTargetName())
+ {
+ cleanTarget = generator->GetCleanTargetName();
+ }
+
+ // 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 cmTargets& targets = (*it)->GetMakefile()->GetTargets();
+ cmMakefile* makefile=(*it)->GetMakefile();
+ std::string subdir = (*it)->Convert(makefile->GetCurrentOutputDirectory(),
+ cmLocalGenerator::HOME_OUTPUT);
+ if (subdir == ".")
+ {
+ subdir = "";
+ }
+
+ for(cmTargets::const_iterator ti=targets.begin(); ti!=targets.end(); ++ti)
+ {
+ switch(ti->second.GetType())
+ {
+ case cmTarget::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, ": ");
+ }
+ }
+ break;
+ case cmTarget::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")))
+ {
+ break;
+ }
+
+ this->AppendTarget(fout, ti->first, make, makeArgs, subdir, ": ");
+ break;
+ case cmTarget::EXECUTABLE:
+ case cmTarget::STATIC_LIBRARY:
+ case cmTarget::SHARED_LIBRARY:
+ case cmTarget::MODULE_LIBRARY:
+ case cmTarget::OBJECT_LIBRARY:
+ {
+ const char* prefix = (ti->second.GetType()==cmTarget::EXECUTABLE ?
+ "[exe] " : "[lib] ");
+ this->AppendTarget(fout, ti->first, make, makeArgs, subdir, prefix);
+ std::string fastTarget = ti->first;
+ fastTarget += "/fast";
+ this->AppendTarget(fout, fastTarget, make, makeArgs, subdir, prefix);
+
+ // Add Build and Clean targets in the virtual folder of targets:
+ if (this->SupportsVirtualFolders)
+ {
+ std::string virtDir = "[Targets]/";
+ virtDir += prefix;
+ virtDir += ti->first;
+ std::string buildArgs = "-C \"";
+ buildArgs += makefile->GetHomeOutputDirectory();
+ buildArgs += "\" ";
+ buildArgs += makeArgs;
+ this->AppendTarget(fout, "Build", make, buildArgs, virtDir, "",
+ ti->first.c_str());
+
+ std::string cleanArgs = "-E chdir \"";
+ cleanArgs += makefile->GetCurrentOutputDirectory();
+ cleanArgs += "\" \"";
+ cleanArgs += cmake;
+ cleanArgs += "\" -P \"";
+ cleanArgs += (*it)->GetTargetDirectory(ti->second);
+ cleanArgs += "/cmake_clean.cmake\"";
+ this->AppendTarget(fout, "Clean", cmake, cleanArgs, virtDir, "", "");
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ // insert the all and clean targets in every subdir
+ if (!allTarget.empty())
+ {
+ this->AppendTarget(fout, allTarget, make, makeArgs, subdir, ": ");
+ }
+ if (!cleanTarget.empty())
+ {
+ this->AppendTarget(fout, cleanTarget, make, makeArgs, subdir, ": ");
+ }
+
+ //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)
+ {
+ const char* prefix = "[obj] ";
+ if ((*fit)[fit->length()-1] == 's')
+ {
+ prefix = "[to asm] ";
+ }
+ else if ((*fit)[fit->length()-1] == 'i')
+ {
+ prefix = "[pre] ";
+ }
+ this->AppendTarget(fout, *fit, make, makeArgs, subdir, prefix);
+ }
+ }
+
+ fout << "</buildTargets>\n"
+ "</storageModule>\n"
+ ;
+
+ this->AppendStorageScanners(fout, *mf);
+
+ 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())
+ << "\"/>\n"
+ "</storageModule>\n"
+ "</cproject>\n"
+ ;
+}
+
+//----------------------------------------------------------------------------
+std::string
+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))
+ {
+ return path;
+ }
+ else
+ {
+ out.erase(out.find_last_of('\n'));
+ return out;
+ }
+#else
+ return path;
+#endif
+}
+
+std::string
+cmExtraEclipseCDT4Generator::GetPathBasename(const std::string& path)
+{
+ std::string outputBasename = path;
+ while (outputBasename.size() > 0 &&
+ (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;
+}
+
+std::string
+cmExtraEclipseCDT4Generator::GenerateProjectName(const std::string& name,
+ const std::string& type,
+ const std::string& path)
+{
+ return cmExtraEclipseCDT4Generator::EscapeForXML(name)
+ +(type.empty() ? "" : "-") + type + "@" + path;
+}
+
+std::string cmExtraEclipseCDT4Generator::EscapeForXML(const std::string& value)
+{
+ std::string str = value;
+ cmSystemTools::ReplaceString(str, "&", "&amp;");
+ cmSystemTools::ReplaceString(str, "<", "&lt;");
+ cmSystemTools::ReplaceString(str, ">", "&gt;");
+ cmSystemTools::ReplaceString(str, "\"", "&quot;");
+ // NOTE: This one is not necessary, since as of Eclipse CDT4 it will
+ // automatically change this to the original value (').
+ //cmSystemTools::ReplaceString(str, "'", "&apos;");
+ return str;
+}
+
+//----------------------------------------------------------------------------
+// Helper functions
+//----------------------------------------------------------------------------
+void cmExtraEclipseCDT4Generator
+::AppendStorageScanners(cmGeneratedFileStream& fout,
+ const cmMakefile& makefile)
+{
+ // we need the "make" and the C (or C++) compiler which are used, Alex
+ std::string make = makefile.GetRequiredDefinition("CMAKE_MAKE_PROGRAM");
+ std::string compiler = makefile.GetSafeDefinition("CMAKE_C_COMPILER");
+ std::string arg1 = makefile.GetSafeDefinition("CMAKE_C_COMPILER_ARG1");
+ if (compiler.empty())
+ {
+ compiler = makefile.GetSafeDefinition("CMAKE_CXX_COMPILER");
+ arg1 = makefile.GetSafeDefinition("CMAKE_CXX_COMPILER_ARG1");
+ }
+ if (compiler.empty()) //Hmm, what to do now ?
+ {
+ compiler = "gcc";
+ }
+
+ // the following right now hardcodes gcc behaviour :-/
+ std::string compilerArgs =
+ "-E -P -v -dD ${plugin_state_location}/${specs_file}";
+ if (!arg1.empty())
+ {
+ arg1 += " ";
+ compilerArgs = arg1 + compilerArgs;
+ }
+
+ fout <<
+ "<storageModule moduleId=\"scannerConfiguration\">\n"
+ "<autodiscovery enabled=\"true\" problemReportingEnabled=\"true\""
+ " selectedProfileId="
+ "\"org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile\"/>\n"
+ ;
+ cmExtraEclipseCDT4Generator::AppendScannerProfile(fout,
+ "org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile",
+ true, "", true, "specsFile",
+ compilerArgs,
+ compiler, true, true);
+ cmExtraEclipseCDT4Generator::AppendScannerProfile(fout,
+ "org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile",
+ true, "", true, "makefileGenerator",
+ "-f ${project_name}_scd.mk",
+ make, true, true);
+
+ fout << "</storageModule>\n";
+}
+
+// The prefix is prepended before the actual name of the target. The purpose
+// of that is to sort the targets in the view of Eclipse, so that at first
+// the global/utility/all/clean targets appear ": ", then the executable
+// targets "[exe] ", then the libraries "[lib]", then the rules for the
+// object files "[obj]", then for preprocessing only "[pre] " and
+// finally the assembly files "[to asm] ". Note the "to" in "to asm",
+// without it, "asm" would be the first targets in the list, with the "to"
+// they are the last targets, which makes more sense.
+void cmExtraEclipseCDT4Generator::AppendTarget(cmGeneratedFileStream& fout,
+ const std::string& target,
+ const std::string& make,
+ const std::string& makeArgs,
+ const std::string& path,
+ const char* prefix,
+ const char* makeTarget
+ )
+{
+ std::string targetXml = cmExtraEclipseCDT4Generator::EscapeForXML(target);
+ std::string makeTargetXml = targetXml;
+ if (makeTarget != NULL)
+ {
+ makeTargetXml = cmExtraEclipseCDT4Generator::EscapeForXML(makeTarget);
+ }
+ cmExtraEclipseCDT4Generator::EscapeForXML(target);
+ std::string pathXml = cmExtraEclipseCDT4Generator::EscapeForXML(path);
+ fout <<
+ "<target name=\"" << prefix << targetXml << "\""
+ " path=\"" << pathXml.c_str() << "\""
+ " targetID=\"org.eclipse.cdt.make.MakeTargetBuilder\">\n"
+ "<buildCommand>"
+ << cmExtraEclipseCDT4Generator::GetEclipsePath(make)
+ << "</buildCommand>\n"
+ "<buildArguments>" << makeArgs << "</buildArguments>\n"
+ "<buildTarget>" << makeTargetXml << "</buildTarget>\n"
+ "<stopOnError>true</stopOnError>\n"
+ "<useDefaultCommand>false</useDefaultCommand>\n"
+ "</target>\n"
+ ;
+}
+
+void cmExtraEclipseCDT4Generator
+::AppendScannerProfile(cmGeneratedFileStream& fout,
+ const std::string& profileID,
+ bool openActionEnabled,
+ const std::string& openActionFilePath,
+ bool pParserEnabled,
+ const std::string& scannerInfoProviderID,
+ const std::string& runActionArguments,
+ const std::string& runActionCommand,
+ bool runActionUseDefault,
+ bool sipParserEnabled)
+{
+ fout <<
+ "<profile id=\"" << profileID << "\">\n"
+ "<buildOutputProvider>\n"
+ "<openAction enabled=\"" << (openActionEnabled ? "true" : "false")
+ << "\" filePath=\"" << openActionFilePath << "\"/>\n"
+ "<parser enabled=\"" << (pParserEnabled ? "true" : "false") << "\"/>\n"
+ "</buildOutputProvider>\n"
+ "<scannerInfoProvider id=\"" << scannerInfoProviderID << "\">\n"
+ "<runAction arguments=\"" << runActionArguments << "\""
+ " command=\"" << runActionCommand
+ << "\" useDefault=\"" << (runActionUseDefault ? "true":"false") << "\"/>\n"
+ "<parser enabled=\"" << (sipParserEnabled ? "true" : "false") << "\"/>\n"
+ "</scannerInfoProvider>\n"
+ "</profile>\n"
+ ;
+}
+
+void cmExtraEclipseCDT4Generator
+::AppendLinkedResource (cmGeneratedFileStream& fout,
+ const std::string& name,
+ const std::string& path,
+ LinkType linkType)
+{
+ const char* locationTag = "location";
+ const char* typeTag = "2";
+ if (linkType == VirtualFolder) // ... and not a linked folder
+ {
+ locationTag = "locationURI";
+ }
+ if (linkType == LinkToFile)
+ {
+ typeTag = "1";
+ }
+
+ fout <<
+ "\t\t<link>\n"
+ "\t\t\t<name>"
+ << cmExtraEclipseCDT4Generator::EscapeForXML(name)
+ << "</name>\n"
+ "\t\t\t<type>" << typeTag << "</type>\n"
+ "\t\t\t<" << locationTag << ">"
+ << cmExtraEclipseCDT4Generator::EscapeForXML(path)
+ << "</" << locationTag << ">\n"
+ "\t\t</link>\n"
+ ;
+}
+
+bool cmExtraEclipseCDT4Generator
+::AppendOutLinkedResource(cmGeneratedFileStream& fout,
+ const std::string& defname,
+ const std::string& altdefname)
+{
+ if (defname.empty() && altdefname.empty())
+ {
+ return false;
+ }
+
+ std::string outputPath = (defname.empty() ? altdefname : defname);
+
+ if (!cmSystemTools::FileIsFullPath(outputPath.c_str()))
+ {
+ outputPath = this->HomeOutputDirectory + "/" + outputPath;
+ }
+ if (cmSystemTools::IsSubDirectory(outputPath.c_str(),
+ this->HomeOutputDirectory.c_str()))
+ {
+ return false;
+ }
+
+ std::string name = this->GetPathBasename(outputPath);
+
+ // make sure linked resource name is unique
+ while (this->GlobalGenerator->GetProjectMap().find(name)
+ != this->GlobalGenerator->GetProjectMap().end())
+ {
+ name += "_";
+ }
+
+ if (std::find(this->OutLinkedResources.begin(),
+ this->OutLinkedResources.end(),
+ name)
+ != this->OutLinkedResources.end())
+ {
+ return false;
+ }
+ else
+ {
+ this->AppendLinkedResource(fout, name,
+ this->GetEclipsePath(outputPath), LinkToFolder);
+ this->OutLinkedResources.push_back(name);
+ return true;
+ }
+}
+
diff --git a/Source/cmExtraEclipseCDT4Generator.h b/Source/cmExtraEclipseCDT4Generator.h
new file mode 100644
index 000000000..ebd8c081e
--- /dev/null
+++ b/Source/cmExtraEclipseCDT4Generator.h
@@ -0,0 +1,121 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2004-2009 Kitware, Inc.
+ Copyright 2004 Alexander Neundorf (neundorf@kde.org)
+ Copyright 2007 Miguel A. Figueroa-Villanueva
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software 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 cmExtraEclipseCDT4Generator_h
+#define cmExtraEclipseCDT4Generator_h
+
+#include "cmExternalMakefileProjectGenerator.h"
+
+class cmMakefile;
+class cmGeneratedFileStream;
+
+/** \class cmExtraEclipseCDT4Generator
+ * \brief Write Eclipse project files for Makefile based projects
+ */
+class cmExtraEclipseCDT4Generator : public cmExternalMakefileProjectGenerator
+{
+public:
+ enum LinkType {VirtualFolder, LinkToFolder, LinkToFile };
+
+ cmExtraEclipseCDT4Generator();
+
+ static cmExternalMakefileProjectGenerator* New() {
+ return new cmExtraEclipseCDT4Generator;
+ }
+
+ virtual const char* GetName() const {
+ return cmExtraEclipseCDT4Generator::GetActualName();
+ }
+
+ static const char* GetActualName() { return "Eclipse CDT4"; }
+
+ virtual void GetDocumentation(cmDocumentationEntry& entry,
+ const char* fullName) const;
+
+ virtual void Generate();
+
+private:
+ // create .project file in the source tree
+ void CreateSourceProjectFile();
+
+ // create .project file
+ void CreateProjectFile();
+
+ // create .cproject file
+ void CreateCProjectFile() const;
+
+ // If built with cygwin cmake, convert posix to windows path.
+ static std::string GetEclipsePath(const std::string& path);
+
+ // Extract basename.
+ static std::string GetPathBasename(const std::string& path);
+
+ // Generate the project name as: <name>-<type>@<path>
+ static std::string GenerateProjectName(const std::string& name,
+ const std::string& type,
+ const std::string& path);
+
+ static std::string EscapeForXML(const std::string& value);
+
+ // Helper functions
+ static void AppendStorageScanners(cmGeneratedFileStream& fout,
+ const cmMakefile& makefile);
+ static void AppendTarget (cmGeneratedFileStream& fout,
+ const std::string& target,
+ const std::string& make,
+ const std::string& makeArguments,
+ const std::string& path,
+ const char* prefix = "",
+ const char* makeTarget = NULL);
+ static void AppendScannerProfile (cmGeneratedFileStream& fout,
+ const std::string& profileID,
+ bool openActionEnabled,
+ const std::string& openActionFilePath,
+ bool pParserEnabled,
+ const std::string& scannerInfoProviderID,
+ const std::string& runActionArguments,
+ const std::string& runActionCommand,
+ bool runActionUseDefault,
+ bool sipParserEnabled);
+
+ static void AppendLinkedResource (cmGeneratedFileStream& fout,
+ const std::string& name,
+ const std::string& path,
+ LinkType linkType);
+
+ bool AppendOutLinkedResource(cmGeneratedFileStream& fout,
+ const std::string& defname,
+ const std::string& altdefname);
+
+ static void AppendIncludeDirectories(cmGeneratedFileStream& fout,
+ const std::vector<std::string>& includeDirs,
+ std::set<std::string>& emittedDirs);
+
+ static void AddEnvVar(cmGeneratedFileStream& fout, const char* envVar,
+ cmMakefile* mf);
+
+ void CreateLinksToSubprojects(cmGeneratedFileStream& fout,
+ const std::string& baseDir);
+ void CreateLinksForTargets(cmGeneratedFileStream& fout);
+
+ std::vector<std::string> SrcLinkedResources;
+ std::vector<std::string> OutLinkedResources;
+ std::string HomeDirectory;
+ std::string HomeOutputDirectory;
+ bool IsOutOfSourceBuild;
+ bool GenerateSourceProject;
+ bool SupportsVirtualFolders;
+
+};
+
+#endif
diff --git a/Source/cmFLTKWrapUICommand.cxx b/Source/cmFLTKWrapUICommand.cxx
new file mode 100644
index 000000000..93533e57c
--- /dev/null
+++ b/Source/cmFLTKWrapUICommand.cxx
@@ -0,0 +1,173 @@
+/*============================================================================
+ 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 "cmFLTKWrapUICommand.h"
+
+#include "cmSourceFile.h"
+
+// cmFLTKWrapUICommand
+bool cmFLTKWrapUICommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 2 )
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ // what is the current source dir
+ std::string cdir = this->Makefile->GetCurrentDirectory();
+ 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();
+
+ // Some of the generated files are *.h so the directory "GUI"
+ // where they are created have to be added to the include path
+ this->Makefile->AddIncludeDirectory( outputDirectory.c_str() );
+
+ for(std::vector<std::string>::iterator i = (newArgs.begin() + 1);
+ i != newArgs.end(); i++)
+ {
+ cmSourceFile *curr = this->Makefile->GetSource(i->c_str());
+ // if we should use the source GUI
+ // to generate .cxx and .h files
+ if (!curr || !curr->GetPropertyAsBool("WRAP_EXCLUDE"))
+ {
+ std::string outName = outputDirectory;
+ outName += "/";
+ outName += cmSystemTools::GetFilenameWithoutExtension(*i);
+ std::string hname = outName;
+ hname += ".h";
+ std::string origname = cdir + "/" + *i;
+ // add starting depends
+ std::vector<std::string> depends;
+ depends.push_back(origname);
+ depends.push_back(fluid_exe);
+ std::string cxxres = outName;
+ cxxres += ".cxx";
+
+ cmCustomCommandLine commandLine;
+ commandLine.push_back(fluid_exe);
+ commandLine.push_back("-c"); // instructs Fluid to run in command line
+ commandLine.push_back("-h"); // optionally rename .h files
+ commandLine.push_back(hname);
+ commandLine.push_back("-o"); // optionally rename .cxx files
+ commandLine.push_back(cxxres);
+ commandLine.push_back(origname);// name of the GUI fluid file
+ cmCustomCommandLines commandLines;
+ commandLines.push_back(commandLine);
+
+ // Add command for generating the .h and .cxx files
+ const char* no_main_dependency = 0;
+ const char* no_comment = 0;
+ const char* no_working_dir = 0;
+ this->Makefile->AddCustomCommandToOutput(cxxres.c_str(),
+ depends, no_main_dependency,
+ commandLines, no_comment,
+ no_working_dir);
+ this->Makefile->AddCustomCommandToOutput(hname.c_str(),
+ depends, no_main_dependency,
+ commandLines, no_comment,
+ no_working_dir);
+
+ cmSourceFile *sf = this->Makefile->GetSource(cxxres.c_str());
+ sf->AddDepend(hname.c_str());
+ sf->AddDepend(origname.c_str());
+ this->GeneratedSourcesClasses.push_back(sf);
+ }
+ }
+
+ // create the variable with the list of sources in it
+ size_t lastHeadersClass = this->GeneratedSourcesClasses.size();
+ std::string sourceListValue;
+ for(size_t classNum = 0; classNum < lastHeadersClass; classNum++)
+ {
+ if (classNum)
+ {
+ sourceListValue += ";";
+ }
+ sourceListValue += this->GeneratedSourcesClasses[classNum]->GetFullPath();
+ }
+ std::string varName = this->Target;
+ varName += "_FLTK_UI_SRCS";
+ this->Makefile->AddDefinition(varName.c_str(), sourceListValue.c_str());
+
+ return true;
+}
+
+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());
+ 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 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
new file mode 100644
index 000000000..cb0f9d534
--- /dev/null
+++ b/Source/cmFLTKWrapUICommand.h
@@ -0,0 +1,94 @@
+/*============================================================================
+ 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 cmFLTKWrapUICommand_h
+#define cmFLTKWrapUICommand_h
+
+#include "cmCommand.h"
+
+/** \class cmFLTKWrapUICommand
+ * \brief Create .h and .cxx files rules for FLTK user interfaces files
+ *
+ * cmFLTKWrapUICommand is used to create wrappers for FLTK classes into
+ * normal C++
+ */
+class cmFLTKWrapUICommand : public cmCommand
+{
+public:
+ cmTypeMacro(cmFLTKWrapUICommand, cmCommand);
+
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmFLTKWrapUICommand;
+ }
+
+ /**
+ * 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. Most commands do
+ * not implement this method. At this point, reading and
+ * writing to the cache can be done.
+ */
+ 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 "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.";
+ }
+
+private:
+ /**
+ * List of produced files.
+ */
+ std::vector<cmSourceFile *> GeneratedSourcesClasses;
+
+ /**
+ * List of Fluid files that provide the source
+ * generating .cxx and .h files
+ */
+ std::string Target;
+};
+
+
+
+#endif
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
new file mode 100644
index 000000000..5da5a0181
--- /dev/null
+++ b/Source/cmFileCommand.cxx
@@ -0,0 +1,3180 @@
+/*============================================================================
+ 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 "cmFileCommand.h"
+#include "cmake.h"
+#include "cmHexFileConverter.h"
+#include "cmInstallType.h"
+#include "cmFileTimeComparison.h"
+#include "cmCryptoHash.h"
+
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+#include "cm_curl.h"
+#endif
+
+#undef GetCurrentDirectory
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <cmsys/auto_ptr.hxx>
+#include <cmsys/Directory.hxx>
+#include <cmsys/Glob.hxx>
+#include <cmsys/RegularExpression.hxx>
+
+// Table of permissions flags.
+#if defined(_WIN32) && !defined(__CYGWIN__)
+static mode_t mode_owner_read = S_IREAD;
+static mode_t mode_owner_write = S_IWRITE;
+static mode_t mode_owner_execute = S_IEXEC;
+static mode_t mode_group_read = 0;
+static mode_t mode_group_write = 0;
+static mode_t mode_group_execute = 0;
+static mode_t mode_world_read = 0;
+static mode_t mode_world_write = 0;
+static mode_t mode_world_execute = 0;
+static mode_t mode_setuid = 0;
+static mode_t mode_setgid = 0;
+#else
+static mode_t mode_owner_read = S_IRUSR;
+static mode_t mode_owner_write = S_IWUSR;
+static mode_t mode_owner_execute = S_IXUSR;
+static mode_t mode_group_read = S_IRGRP;
+static mode_t mode_group_write = S_IWGRP;
+static mode_t mode_group_execute = S_IXGRP;
+static mode_t mode_world_read = S_IROTH;
+static mode_t mode_world_write = S_IWOTH;
+static mode_t mode_world_execute = S_IXOTH;
+static mode_t mode_setuid = S_ISUID;
+static mode_t mode_setgid = S_ISGID;
+#endif
+
+// cmLibraryCommand
+bool cmFileCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 2 )
+ {
+ this->SetError("must be called with at least two arguments.");
+ return false;
+ }
+ std::string subCommand = args[0];
+ if ( subCommand == "WRITE" )
+ {
+ return this->HandleWriteCommand(args, false);
+ }
+ else if ( subCommand == "APPEND" )
+ {
+ return this->HandleWriteCommand(args, true);
+ }
+ else if ( subCommand == "DOWNLOAD" )
+ {
+ return this->HandleDownloadCommand(args);
+ }
+ else if ( subCommand == "UPLOAD" )
+ {
+ return this->HandleUploadCommand(args);
+ }
+ else if ( subCommand == "READ" )
+ {
+ return this->HandleReadCommand(args);
+ }
+ else if ( subCommand == "MD5" ||
+ subCommand == "SHA1" ||
+ subCommand == "SHA224" ||
+ subCommand == "SHA256" ||
+ subCommand == "SHA384" ||
+ subCommand == "SHA512" )
+ {
+ return this->HandleHashCommand(args);
+ }
+ else if ( subCommand == "STRINGS" )
+ {
+ return this->HandleStringsCommand(args);
+ }
+ else if ( subCommand == "GLOB" )
+ {
+ return this->HandleGlobCommand(args, false);
+ }
+ else if ( subCommand == "GLOB_RECURSE" )
+ {
+ return this->HandleGlobCommand(args, true);
+ }
+ else if ( subCommand == "MAKE_DIRECTORY" )
+ {
+ return this->HandleMakeDirectoryCommand(args);
+ }
+ else if ( subCommand == "RENAME" )
+ {
+ return this->HandleRename(args);
+ }
+ else if ( subCommand == "REMOVE" )
+ {
+ return this->HandleRemove(args, false);
+ }
+ else if ( subCommand == "REMOVE_RECURSE" )
+ {
+ return this->HandleRemove(args, true);
+ }
+ else if ( subCommand == "COPY" )
+ {
+ return this->HandleCopyCommand(args);
+ }
+ else if ( subCommand == "INSTALL" )
+ {
+ return this->HandleInstallCommand(args);
+ }
+ else if ( subCommand == "DIFFERENT" )
+ {
+ return this->HandleDifferentCommand(args);
+ }
+ else if ( subCommand == "RPATH_CHANGE" || subCommand == "CHRPATH" )
+ {
+ return this->HandleRPathChangeCommand(args);
+ }
+ else if ( subCommand == "RPATH_CHECK" )
+ {
+ return this->HandleRPathCheckCommand(args);
+ }
+ else if ( subCommand == "RPATH_REMOVE" )
+ {
+ return this->HandleRPathRemoveCommand(args);
+ }
+ else if ( subCommand == "RELATIVE_PATH" )
+ {
+ return this->HandleRelativePathCommand(args);
+ }
+ else if ( subCommand == "TO_CMAKE_PATH" )
+ {
+ return this->HandleCMakePathCommand(args, false);
+ }
+ else if ( subCommand == "TO_NATIVE_PATH" )
+ {
+ return this->HandleCMakePathCommand(args, true);
+ }
+
+ std::string e = "does not recognize sub-command "+subCommand;
+ this->SetError(e.c_str());
+ return false;
+}
+
+//----------------------------------------------------------------------------
+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
+
+ std::string fileName = *i;
+ if ( !cmsys::SystemTools::FileIsFullPath(i->c_str()) )
+ {
+ fileName = this->Makefile->GetCurrentDirectory();
+ 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());
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+ std::string dir = cmSystemTools::GetFilenamePath(fileName);
+ cmSystemTools::MakeDirectory(dir.c_str());
+
+ mode_t mode = 0;
+
+ // Set permissions to writable
+ if ( cmSystemTools::GetPermissions(fileName.c_str(), mode) )
+ {
+ 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
+ );
+ }
+ // 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);
+ 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());
+ return false;
+ }
+ file << message;
+ file.close();
+ if(mode)
+ {
+ cmSystemTools::SetPermissions(fileName.c_str(), mode);
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmFileCommand::HandleReadCommand(std::vector<std::string> const& args)
+{
+ if ( args.size() < 3 )
+ {
+ this->SetError("READ must be called with at least two additional "
+ "arguments");
+ return false;
+ }
+
+ cmCommandArgumentsHelper argHelper;
+ cmCommandArgumentGroup group;
+
+ cmCAString readArg (&argHelper, "READ");
+ cmCAString fileNameArg (&argHelper, 0);
+ cmCAString resultArg (&argHelper, 0);
+
+ cmCAString offsetArg (&argHelper, "OFFSET", &group);
+ cmCAString limitArg (&argHelper, "LIMIT", &group);
+ cmCAEnabler hexOutputArg (&argHelper, "HEX", &group);
+ readArg.Follows(0);
+ fileNameArg.Follows(&readArg);
+ resultArg.Follows(&fileNameArg);
+ group.Follows(&resultArg);
+ argHelper.Parse(&args, 0);
+
+ std::string fileName = fileNameArg.GetString();
+ if ( !cmsys::SystemTools::FileIsFullPath(fileName.c_str()) )
+ {
+ fileName = this->Makefile->GetCurrentDirectory();
+ fileName += "/" + fileNameArg.GetString();
+ }
+
+ std::string variable = resultArg.GetString();
+
+ // Open the specified file.
+#if defined(_WIN32) || defined(__CYGWIN__)
+ std::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);
+#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());
+ return false;
+ }
+
+ // is there a limit?
+ long sizeLimit = -1;
+ if (limitArg.GetString().size() > 0)
+ {
+ sizeLimit = atoi(limitArg.GetCString());
+ }
+
+ // is there an offset?
+ long offset = 0;
+ if (offsetArg.GetString().size() > 0)
+ {
+ offset = atoi(offsetArg.GetCString());
+ }
+
+ file.seekg(offset, std::ios::beg); // explicit ios::beg for IBM VisualAge 6
+
+ std::string output;
+
+ if (hexOutputArg.IsEnabled())
+ {
+ // Convert part of the file into hex code
+ char c;
+ while((sizeLimit != 0) && (file.get(c)))
+ {
+ char hex[4];
+ sprintf(hex, "%.2x", c&0xff);
+ output += hex;
+ if (sizeLimit > 0)
+ {
+ sizeLimit--;
+ }
+ }
+ }
+ else
+ {
+ std::string line;
+ bool has_newline = false;
+ while (sizeLimit != 0 &&
+ cmSystemTools::GetLineFromStream(file, line, &has_newline,
+ sizeLimit) )
+ {
+ if (sizeLimit > 0)
+ {
+ sizeLimit = sizeLimit - static_cast<long>(line.size());
+ if (has_newline)
+ {
+ sizeLimit--;
+ }
+ if (sizeLimit < 0)
+ {
+ sizeLimit = 0;
+ }
+ }
+ output += line;
+ if ( has_newline )
+ {
+ output += "\n";
+ }
+ }
+ }
+ this->Makefile->AddDefinition(variable.c_str(), output.c_str());
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmFileCommand::HandleHashCommand(std::vector<std::string> const& args)
+{
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ if(args.size() != 3)
+ {
+ cmOStringStream e;
+ e << args[0] << " requires a file name and output variable";
+ this->SetError(e.str().c_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());
+ if(!out.empty())
+ {
+ this->Makefile->AddDefinition(args[2].c_str(), out.c_str());
+ return true;
+ }
+ cmOStringStream e;
+ e << args[0] << " failed to read file \"" << args[1] << "\": "
+ << cmSystemTools::GetLastSystemError();
+ this->SetError(e.str().c_str());
+ }
+ return false;
+#else
+ cmOStringStream e;
+ e << args[0] << " not available during bootstrap";
+ this->SetError(e.str().c_str());
+ return false;
+#endif
+}
+
+//----------------------------------------------------------------------------
+bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
+{
+ if(args.size() < 3)
+ {
+ this->SetError("STRINGS requires a file name and output variable");
+ return false;
+ }
+
+ // Get the file to read.
+ std::string fileName = args[1];
+ if(!cmsys::SystemTools::FileIsFullPath(fileName.c_str()))
+ {
+ fileName = this->Makefile->GetCurrentDirectory();
+ fileName += "/" + args[1];
+ }
+
+ // Get the variable in which to store the results.
+ std::string outVar = args[2];
+
+ // Parse the options.
+ enum { arg_none,
+ arg_limit_input,
+ arg_limit_output,
+ arg_limit_count,
+ arg_length_minimum,
+ arg_length_maximum,
+ arg__maximum,
+ arg_regex };
+ unsigned int minlen = 0;
+ unsigned int maxlen = 0;
+ int limit_input = -1;
+ int limit_output = -1;
+ unsigned int limit_count = 0;
+ cmsys::RegularExpression regex;
+ bool have_regex = false;
+ bool newline_consume = false;
+ bool hex_conversion_enabled = true;
+ int arg_mode = arg_none;
+ for(unsigned int i=3; i < args.size(); ++i)
+ {
+ if(args[i] == "LIMIT_INPUT")
+ {
+ arg_mode = arg_limit_input;
+ }
+ else if(args[i] == "LIMIT_OUTPUT")
+ {
+ arg_mode = arg_limit_output;
+ }
+ else if(args[i] == "LIMIT_COUNT")
+ {
+ arg_mode = arg_limit_count;
+ }
+ else if(args[i] == "LENGTH_MINIMUM")
+ {
+ arg_mode = arg_length_minimum;
+ }
+ else if(args[i] == "LENGTH_MAXIMUM")
+ {
+ arg_mode = arg_length_maximum;
+ }
+ else if(args[i] == "REGEX")
+ {
+ arg_mode = arg_regex;
+ }
+ else if(args[i] == "NEWLINE_CONSUME")
+ {
+ newline_consume = true;
+ arg_mode = arg_none;
+ }
+ else if(args[i] == "NO_HEX_CONVERSION")
+ {
+ hex_conversion_enabled = false;
+ arg_mode = arg_none;
+ }
+ else if(arg_mode == arg_limit_input)
+ {
+ if(sscanf(args[i].c_str(), "%d", &limit_input) != 1 ||
+ limit_input < 0)
+ {
+ cmOStringStream e;
+ e << "STRINGS option LIMIT_INPUT value \""
+ << args[i] << "\" is not an unsigned integer.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ arg_mode = arg_none;
+ }
+ else if(arg_mode == arg_limit_output)
+ {
+ if(sscanf(args[i].c_str(), "%d", &limit_output) != 1 ||
+ limit_output < 0)
+ {
+ cmOStringStream e;
+ e << "STRINGS option LIMIT_OUTPUT value \""
+ << args[i] << "\" is not an unsigned integer.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ arg_mode = arg_none;
+ }
+ else if(arg_mode == arg_limit_count)
+ {
+ int count;
+ if(sscanf(args[i].c_str(), "%d", &count) != 1 || count < 0)
+ {
+ cmOStringStream e;
+ e << "STRINGS option LIMIT_COUNT value \""
+ << args[i] << "\" is not an unsigned integer.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ limit_count = count;
+ arg_mode = arg_none;
+ }
+ else if(arg_mode == arg_length_minimum)
+ {
+ int len;
+ if(sscanf(args[i].c_str(), "%d", &len) != 1 || len < 0)
+ {
+ cmOStringStream e;
+ e << "STRINGS option LENGTH_MINIMUM value \""
+ << args[i] << "\" is not an unsigned integer.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ minlen = len;
+ arg_mode = arg_none;
+ }
+ else if(arg_mode == arg_length_maximum)
+ {
+ int len;
+ if(sscanf(args[i].c_str(), "%d", &len) != 1 || len < 0)
+ {
+ cmOStringStream e;
+ e << "STRINGS option LENGTH_MAXIMUM value \""
+ << args[i] << "\" is not an unsigned integer.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ maxlen = len;
+ arg_mode = arg_none;
+ }
+ else if(arg_mode == arg_regex)
+ {
+ if(!regex.compile(args[i].c_str()))
+ {
+ cmOStringStream e;
+ e << "STRINGS option REGEX value \""
+ << args[i] << "\" could not be compiled.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ have_regex = true;
+ arg_mode = arg_none;
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "STRINGS given unknown argument \""
+ << args[i] << "\"";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+
+ if (hex_conversion_enabled)
+ {
+ // TODO: should work without temp file, but just on a memory buffer
+ std::string binaryFileName = this->Makefile->GetCurrentOutputDirectory();
+ binaryFileName += cmake::GetCMakeFilesDirectory();
+ binaryFileName += "/FileCommandStringsBinaryFile";
+ if(cmHexFileConverter::TryConvert(fileName.c_str(),binaryFileName.c_str()))
+ {
+ fileName = binaryFileName;
+ }
+ }
+
+ // Open the specified file.
+#if defined(_WIN32) || defined(__CYGWIN__)
+ std::ifstream fin(fileName.c_str(), std::ios::in | std::ios::binary);
+#else
+ std::ifstream fin(fileName.c_str(), std::ios::in);
+#endif
+ if(!fin)
+ {
+ cmOStringStream e;
+ e << "STRINGS file \"" << fileName << "\" cannot be read.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+
+ // 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))
+ {
+ if(c == '\n' && !newline_consume)
+ {
+ // The current line has been terminated. Check if the current
+ // string matches the requirements. The length may now be as
+ // low as zero since blank lines are allowed.
+ if(s.length() >= minlen &&
+ (!have_regex || regex.find(s.c_str())))
+ {
+ output_size += static_cast<int>(s.size()) + 1;
+ if(limit_output >= 0 && output_size >= limit_output)
+ {
+ s = "";
+ break;
+ }
+ strings.push_back(s);
+ }
+
+ // 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
+ {
+ // 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())))
+ {
+ output_size += static_cast<int>(s.size()) + 1;
+ if(limit_output >= 0 && output_size >= limit_output)
+ {
+ s = "";
+ break;
+ }
+ strings.push_back(s);
+ }
+
+ // Reset the string to empty.
+ s = "";
+ }
+
+ // Terminate a string if the maximum length is reached.
+ if(maxlen > 0 && s.size() == maxlen)
+ {
+ if(s.length() >= minlen &&
+ (!have_regex || regex.find(s.c_str())))
+ {
+ output_size += static_cast<int>(s.size()) + 1;
+ if(limit_output >= 0 && output_size >= limit_output)
+ {
+ s = "";
+ break;
+ }
+ strings.push_back(s);
+ }
+ s = "";
+ }
+ }
+
+ // If there is a non-empty current string we have hit the end of the
+ // input file or the input size limit. Check if the current string
+ // matches the requirements.
+ if((!limit_count || strings.size() < limit_count) &&
+ !s.empty() && s.length() >= minlen &&
+ (!have_regex || regex.find(s.c_str())))
+ {
+ output_size += static_cast<int>(s.size()) + 1;
+ if(limit_output < 0 || output_size < limit_output)
+ {
+ strings.push_back(s);
+ }
+ }
+
+ // Encode the result in a CMake list.
+ const char* sep = "";
+ std::string output;
+ for(std::vector<std::string>::const_iterator si = strings.begin();
+ si != strings.end(); ++si)
+ {
+ // Separate the strings in the output to make it a list.
+ output += sep;
+ sep = ";";
+
+ // Store the string in the output, but escape semicolons to
+ // make sure it is a list.
+ std::string const& sr = *si;
+ for(unsigned int i=0; i < sr.size(); ++i)
+ {
+ if(sr[i] == ';')
+ {
+ output += '\\';
+ }
+ output += sr[i];
+ }
+ }
+
+ // Save the output in a makefile variable.
+ this->Makefile->AddDefinition(outVar.c_str(), output.c_str());
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args,
+ bool recurse)
+{
+ if ( args.size() < 2 )
+ {
+ this->SetError("GLOB requires at least a variable name");
+ return false;
+ }
+
+ std::vector<std::string>::const_iterator i = args.begin();
+
+ i++; // Get rid of subcommand
+
+ std::string variable = *i;
+ i++;
+ cmsys::Glob g;
+ g.SetRecurse(recurse);
+
+ bool explicitFollowSymlinks = false;
+ cmPolicies::PolicyStatus status =
+ this->Makefile->GetPolicyStatus(cmPolicies::CMP0009);
+ if(recurse)
+ {
+ switch(status)
+ {
+ case cmPolicies::NEW:
+ g.RecurseThroughSymlinksOff();
+ break;
+ case cmPolicies::OLD:
+ case cmPolicies::WARN:
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ g.RecurseThroughSymlinksOn();
+ break;
+ }
+ }
+
+ std::string output = "";
+ bool first = true;
+ for ( ; i != args.end(); ++i )
+ {
+ if ( recurse && (*i == "FOLLOW_SYMLINKS") )
+ {
+ explicitFollowSymlinks = true;
+ g.RecurseThroughSymlinksOn();
+ ++i;
+ if ( i == args.end() )
+ {
+ this->SetError(
+ "GLOB_RECURSE requires a glob expression after FOLLOW_SYMLINKS");
+ return false;
+ }
+ }
+
+ if ( *i == "RELATIVE" )
+ {
+ ++i; // skip RELATIVE
+ if ( i == args.end() )
+ {
+ this->SetError("GLOB requires a directory after the RELATIVE tag");
+ return false;
+ }
+ g.SetRelative(i->c_str());
+ ++i;
+ if(i == args.end())
+ {
+ this->SetError("GLOB requires a glob expression after the directory");
+ return false;
+ }
+ }
+
+ if ( !cmsys::SystemTools::FileIsFullPath(i->c_str()) )
+ {
+ std::string expr = this->Makefile->GetCurrentDirectory();
+ // Handle script mode
+ if ( expr.size() > 0 )
+ {
+ expr += "/" + *i;
+ g.FindFiles(expr);
+ }
+ else
+ {
+ g.FindFiles(*i);
+ }
+ }
+ else
+ {
+ g.FindFiles(*i);
+ }
+
+ std::vector<std::string>::size_type cc;
+ std::vector<std::string>& files = g.GetFiles();
+ for ( cc = 0; cc < files.size(); cc ++ )
+ {
+ if ( !first )
+ {
+ output += ";";
+ }
+ output += files[cc];
+ first = false;
+ }
+ }
+
+ if(recurse && !explicitFollowSymlinks)
+ {
+ switch (status)
+ {
+ case cmPolicies::NEW:
+ // Correct behavior, yay!
+ break;
+ case cmPolicies::OLD:
+ // Probably not really the expected behavior, but the author explicitly
+ // asked for the old behavior... no warning.
+ case cmPolicies::WARN:
+ // Possibly unexpected old behavior *and* we actually traversed
+ // symlinks without being explicitly asked to: warn the author.
+ if(g.GetFollowedSymlinkCount() != 0)
+ {
+ this->Makefile->IssueMessage(cmake::AUTHOR_WARNING,
+ this->Makefile->GetPolicies()->
+ 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());
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmFileCommand::HandleMakeDirectoryCommand(
+ std::vector<std::string> const& args)
+{
+ if(args.size() < 2 )
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ std::vector<std::string>::const_iterator i = args.begin();
+
+ i++; // Get rid of subcommand
+
+ std::string expr;
+ for ( ; i != args.end(); ++i )
+ {
+ const std::string* cdir = &(*i);
+ if ( !cmsys::SystemTools::FileIsFullPath(i->c_str()) )
+ {
+ expr = this->Makefile->GetCurrentDirectory();
+ expr += "/" + *i;
+ cdir = &expr;
+ }
+ if ( !this->Makefile->CanIWriteThisFile(cdir->c_str()) )
+ {
+ std::string e = "attempted to create a directory: " + *cdir
+ + " into a source directory.";
+ this->SetError(e.c_str());
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+ if ( !cmSystemTools::MakeDirectory(cdir->c_str()) )
+ {
+ std::string error = "problem creating directory: " + *cdir;
+ this->SetError(error.c_str());
+ return false;
+ }
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool
+cmFileCommand::HandleDifferentCommand(std::vector<std::string> const& args)
+{
+ /*
+ FILE(DIFFERENT <variable> FILES <lhs> <rhs>)
+ */
+
+ // Evaluate arguments.
+ const char* file_lhs = 0;
+ const char* file_rhs = 0;
+ const char* var = 0;
+ enum Doing { DoingNone, DoingVar, DoingFileLHS, DoingFileRHS };
+ Doing doing = DoingVar;
+ for(unsigned int i=1; i < args.size(); ++i)
+ {
+ if(args[i] == "FILES")
+ {
+ doing = DoingFileLHS;
+ }
+ else if(doing == DoingVar)
+ {
+ var = args[i].c_str();
+ doing = DoingNone;
+ }
+ else if(doing == DoingFileLHS)
+ {
+ file_lhs = args[i].c_str();
+ doing = DoingFileRHS;
+ }
+ else if(doing == DoingFileRHS)
+ {
+ file_rhs = args[i].c_str();
+ doing = DoingNone;
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "DIFFERENT given unknown argument " << args[i];
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+ if(!var)
+ {
+ this->SetError("DIFFERENT not given result variable name.");
+ return false;
+ }
+ if(!file_lhs || !file_rhs)
+ {
+ this->SetError("DIFFERENT not given FILES option with two file names.");
+ return false;
+ }
+
+ // Compare the files.
+ const char* result =
+ cmSystemTools::FilesDiffer(file_lhs, file_rhs)? "1" : "0";
+ this->Makefile->AddDefinition(var, result);
+ return true;
+}
+
+//----------------------------------------------------------------------------
+// File installation helper class.
+struct cmFileCopier
+{
+ cmFileCopier(cmFileCommand* command, const char* name = "COPY"):
+ FileCommand(command),
+ Makefile(command->GetMakefile()),
+ Name(name),
+ Always(false),
+ MatchlessFiles(true),
+ FilePermissions(0),
+ DirPermissions(0),
+ CurrentMatchRule(0),
+ UseGivenPermissionsFile(false),
+ UseGivenPermissionsDir(false),
+ UseSourcePermissions(true),
+ Doing(DoingNone)
+ {
+ }
+ virtual ~cmFileCopier() {}
+
+ bool Run(std::vector<std::string> const& args);
+protected:
+
+ cmFileCommand* FileCommand;
+ cmMakefile* Makefile;
+ const char* Name;
+ bool Always;
+ cmFileTimeComparison FileTimes;
+
+ // Whether to install a file not matching any expression.
+ bool MatchlessFiles;
+
+ // Permissions for files and directories installed by this object.
+ mode_t FilePermissions;
+ mode_t DirPermissions;
+
+ // Properties set by pattern and regex match rules.
+ struct MatchProperties
+ {
+ bool Exclude;
+ mode_t Permissions;
+ MatchProperties(): Exclude(false), Permissions(0) {}
+ };
+ struct MatchRule;
+ friend struct MatchRule;
+ struct MatchRule
+ {
+ cmsys::RegularExpression Regex;
+ MatchProperties Properties;
+ std::string RegexString;
+ MatchRule(std::string const& regex):
+ Regex(regex.c_str()), RegexString(regex) {}
+ };
+ std::vector<MatchRule> MatchRules;
+
+ // Get the properties from rules matching this input file.
+ MatchProperties CollectMatchProperties(const char* file)
+ {
+ // Match rules are case-insensitive on some platforms.
+#if defined(_WIN32) || defined(__APPLE__) || defined(__CYGWIN__)
+ std::string lower = cmSystemTools::LowerCase(file);
+ const char* file_to_match = lower.c_str();
+#else
+ const char* file_to_match = file;
+#endif
+
+ // Collect properties from all matching rules.
+ bool matched = false;
+ MatchProperties result;
+ for(std::vector<MatchRule>::iterator mr = this->MatchRules.begin();
+ mr != this->MatchRules.end(); ++mr)
+ {
+ if(mr->Regex.find(file_to_match))
+ {
+ matched = true;
+ result.Exclude |= mr->Properties.Exclude;
+ result.Permissions |= mr->Properties.Permissions;
+ }
+ }
+ if(!matched && !this->MatchlessFiles)
+ {
+ result.Exclude = !cmSystemTools::FileIsDirectory(file);
+ }
+ return result;
+ }
+
+ bool SetPermissions(const char* toFile, mode_t permissions)
+ {
+ if(permissions && !cmSystemTools::SetPermissions(toFile, permissions))
+ {
+ cmOStringStream e;
+ e << this->Name << " cannot set permissions on \"" << toFile << "\"";
+ this->FileCommand->SetError(e.str().c_str());
+ return false;
+ }
+ return true;
+ }
+
+ // Translate an argument to a permissions bit.
+ bool CheckPermissions(std::string const& arg, mode_t& permissions)
+ {
+ if(arg == "OWNER_READ") { permissions |= mode_owner_read; }
+ else if(arg == "OWNER_WRITE") { permissions |= mode_owner_write; }
+ else if(arg == "OWNER_EXECUTE") { permissions |= mode_owner_execute; }
+ else if(arg == "GROUP_READ") { permissions |= mode_group_read; }
+ else if(arg == "GROUP_WRITE") { permissions |= mode_group_write; }
+ else if(arg == "GROUP_EXECUTE") { permissions |= mode_group_execute; }
+ else if(arg == "WORLD_READ") { permissions |= mode_world_read; }
+ else if(arg == "WORLD_WRITE") { permissions |= mode_world_write; }
+ else if(arg == "WORLD_EXECUTE") { permissions |= mode_world_execute; }
+ else if(arg == "SETUID") { permissions |= mode_setuid; }
+ else if(arg == "SETGID") { permissions |= mode_setgid; }
+ else
+ {
+ cmOStringStream e;
+ e << this->Name << " given invalid permission \"" << arg << "\".";
+ this->FileCommand->SetError(e.str().c_str());
+ return false;
+ }
+ return true;
+ }
+
+ bool InstallSymlink(const char* fromFile, const char* toFile);
+ bool InstallFile(const char* fromFile, const char* toFile,
+ MatchProperties const& match_properties);
+ bool InstallDirectory(const char* source, const char* destination,
+ MatchProperties const& match_properties);
+ virtual bool Install(const char* fromFile, const char* toFile);
+ virtual std::string const& ToName(std::string const& fromName)
+ { return fromName; }
+
+ enum Type
+ {
+ TypeFile,
+ TypeDir,
+ TypeLink
+ };
+ virtual void ReportCopy(const char*, Type, bool) {}
+ virtual bool ReportMissing(const char* fromFile)
+ {
+ // The input file does not exist and installation is not optional.
+ cmOStringStream e;
+ e << this->Name << " cannot find \"" << fromFile << "\".";
+ this->FileCommand->SetError(e.str().c_str());
+ return false;
+ }
+
+ MatchRule* CurrentMatchRule;
+ bool UseGivenPermissionsFile;
+ bool UseGivenPermissionsDir;
+ bool UseSourcePermissions;
+ std::string Destination;
+ std::vector<std::string> Files;
+ int Doing;
+
+ virtual bool Parse(std::vector<std::string> const& args);
+ enum
+ {
+ DoingNone,
+ DoingError,
+ DoingDestination,
+ DoingFiles,
+ DoingPattern,
+ DoingRegex,
+ DoingPermissionsFile,
+ DoingPermissionsDir,
+ DoingPermissionsMatch,
+ DoingLast1
+ };
+ virtual bool CheckKeyword(std::string const& arg);
+ virtual bool CheckValue(std::string const& arg);
+
+ void NotBeforeMatch(std::string const& arg)
+ {
+ cmOStringStream e;
+ e << "option " << arg << " may not appear before PATTERN or REGEX.";
+ this->FileCommand->SetError(e.str().c_str());
+ this->Doing = DoingError;
+ }
+ void NotAfterMatch(std::string const& arg)
+ {
+ cmOStringStream e;
+ e << "option " << arg << " may not appear after PATTERN or REGEX.";
+ this->FileCommand->SetError(e.str().c_str());
+ this->Doing = DoingError;
+ }
+ virtual void DefaultFilePermissions()
+ {
+ // Use read/write permissions.
+ this->FilePermissions = 0;
+ this->FilePermissions |= mode_owner_read;
+ this->FilePermissions |= mode_owner_write;
+ this->FilePermissions |= mode_group_read;
+ this->FilePermissions |= mode_world_read;
+ }
+ virtual void DefaultDirectoryPermissions()
+ {
+ // Use read/write/executable permissions.
+ this->DirPermissions = 0;
+ this->DirPermissions |= mode_owner_read;
+ this->DirPermissions |= mode_owner_write;
+ this->DirPermissions |= mode_owner_execute;
+ this->DirPermissions |= mode_group_read;
+ this->DirPermissions |= mode_group_execute;
+ this->DirPermissions |= mode_world_read;
+ this->DirPermissions |= mode_world_execute;
+ }
+};
+
+//----------------------------------------------------------------------------
+bool cmFileCopier::Parse(std::vector<std::string> const& args)
+{
+ this->Doing = DoingFiles;
+ for(unsigned int i=1; i < args.size(); ++i)
+ {
+ // Check this argument.
+ if(!this->CheckKeyword(args[i]) &&
+ !this->CheckValue(args[i]))
+ {
+ cmOStringStream e;
+ e << "called with unknown argument \"" << args[i] << "\".";
+ this->FileCommand->SetError(e.str().c_str());
+ return false;
+ }
+
+ // Quit if an argument is invalid.
+ if(this->Doing == DoingError)
+ {
+ return false;
+ }
+ }
+
+ // Require a destination.
+ if(this->Destination.empty())
+ {
+ cmOStringStream e;
+ e << this->Name << " given no DESTINATION";
+ this->FileCommand->SetError(e.str().c_str());
+ return false;
+ }
+
+ // If file permissions were not specified set default permissions.
+ if(!this->UseGivenPermissionsFile && !this->UseSourcePermissions)
+ {
+ this->DefaultFilePermissions();
+ }
+
+ // If directory permissions were not specified set default permissions.
+ if(!this->UseGivenPermissionsDir && !this->UseSourcePermissions)
+ {
+ this->DefaultDirectoryPermissions();
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmFileCopier::CheckKeyword(std::string const& arg)
+{
+ if(arg == "DESTINATION")
+ {
+ if(this->CurrentMatchRule)
+ {
+ this->NotAfterMatch(arg);
+ }
+ else
+ {
+ this->Doing = DoingDestination;
+ }
+ }
+ else if(arg == "PATTERN")
+ {
+ this->Doing = DoingPattern;
+ }
+ else if(arg == "REGEX")
+ {
+ this->Doing = DoingRegex;
+ }
+ else if(arg == "EXCLUDE")
+ {
+ // Add this property to the current match rule.
+ if(this->CurrentMatchRule)
+ {
+ this->CurrentMatchRule->Properties.Exclude = true;
+ this->Doing = DoingNone;
+ }
+ else
+ {
+ this->NotBeforeMatch(arg);
+ }
+ }
+ else if(arg == "PERMISSIONS")
+ {
+ if(this->CurrentMatchRule)
+ {
+ this->Doing = DoingPermissionsMatch;
+ }
+ else
+ {
+ this->NotBeforeMatch(arg);
+ }
+ }
+ else if(arg == "FILE_PERMISSIONS")
+ {
+ if(this->CurrentMatchRule)
+ {
+ this->NotAfterMatch(arg);
+ }
+ else
+ {
+ this->Doing = DoingPermissionsFile;
+ this->UseGivenPermissionsFile = true;
+ }
+ }
+ else if(arg == "DIRECTORY_PERMISSIONS")
+ {
+ if(this->CurrentMatchRule)
+ {
+ this->NotAfterMatch(arg);
+ }
+ else
+ {
+ this->Doing = DoingPermissionsDir;
+ this->UseGivenPermissionsDir = true;
+ }
+ }
+ else if(arg == "USE_SOURCE_PERMISSIONS")
+ {
+ if(this->CurrentMatchRule)
+ {
+ this->NotAfterMatch(arg);
+ }
+ else
+ {
+ this->Doing = DoingNone;
+ this->UseSourcePermissions = true;
+ }
+ }
+ else if(arg == "NO_SOURCE_PERMISSIONS")
+ {
+ if(this->CurrentMatchRule)
+ {
+ this->NotAfterMatch(arg);
+ }
+ else
+ {
+ this->Doing = DoingNone;
+ this->UseSourcePermissions = false;
+ }
+ }
+ else if(arg == "FILES_MATCHING")
+ {
+ if(this->CurrentMatchRule)
+ {
+ this->NotAfterMatch(arg);
+ }
+ else
+ {
+ this->Doing = DoingNone;
+ this->MatchlessFiles = false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmFileCopier::CheckValue(std::string const& arg)
+{
+ switch(this->Doing)
+ {
+ case DoingFiles:
+ if(arg.empty() || cmSystemTools::FileIsFullPath(arg.c_str()))
+ {
+ this->Files.push_back(arg);
+ }
+ else
+ {
+ std::string file = this->Makefile->GetCurrentDirectory();
+ file += "/" + arg;
+ this->Files.push_back(file);
+ }
+ break;
+ case DoingDestination:
+ if(arg.empty() || cmSystemTools::FileIsFullPath(arg.c_str()))
+ {
+ this->Destination = arg;
+ }
+ else
+ {
+ this->Destination = this->Makefile->GetCurrentOutputDirectory();
+ this->Destination += "/" + arg;
+ }
+ this->Doing = DoingNone;
+ break;
+ case DoingPattern:
+ {
+ // Convert the pattern to a regular expression. Require a
+ // leading slash and trailing end-of-string in the matched
+ // string to make sure the pattern matches only whole file
+ // names.
+ std::string regex = "/";
+ regex += cmsys::Glob::PatternToRegex(arg, false);
+ regex += "$";
+ this->MatchRules.push_back(MatchRule(regex));
+ this->CurrentMatchRule = &*(this->MatchRules.end()-1);
+ if(this->CurrentMatchRule->Regex.is_valid())
+ {
+ this->Doing = DoingNone;
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "could not compile PATTERN \"" << arg << "\".";
+ this->FileCommand->SetError(e.str().c_str());
+ this->Doing = DoingError;
+ }
+ }
+ break;
+ case DoingRegex:
+ this->MatchRules.push_back(MatchRule(arg));
+ this->CurrentMatchRule = &*(this->MatchRules.end()-1);
+ if(this->CurrentMatchRule->Regex.is_valid())
+ {
+ this->Doing = DoingNone;
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "could not compile REGEX \"" << arg << "\".";
+ this->FileCommand->SetError(e.str().c_str());
+ this->Doing = DoingError;
+ }
+ break;
+ case DoingPermissionsFile:
+ if(!this->CheckPermissions(arg, this->FilePermissions))
+ {
+ this->Doing = DoingError;
+ }
+ break;
+ case DoingPermissionsDir:
+ if(!this->CheckPermissions(arg, this->DirPermissions))
+ {
+ this->Doing = DoingError;
+ }
+ break;
+ case DoingPermissionsMatch:
+ if(!this->CheckPermissions(
+ arg, this->CurrentMatchRule->Properties.Permissions))
+ {
+ this->Doing = DoingError;
+ }
+ break;
+ default:
+ return false;
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmFileCopier::Run(std::vector<std::string> const& args)
+{
+ if(!this->Parse(args))
+ {
+ return false;
+ }
+
+ std::vector<std::string> const& files = this->Files;
+ for(std::vector<std::string>::size_type i = 0; i < files.size(); ++i)
+ {
+ // Split the input file into its directory and name components.
+ std::vector<std::string> fromPathComponents;
+ cmSystemTools::SplitPath(files[i].c_str(), fromPathComponents);
+ std::string fromName = *(fromPathComponents.end()-1);
+ std::string fromDir = cmSystemTools::JoinPath(fromPathComponents.begin(),
+ fromPathComponents.end()-1);
+
+ // Compute the full path to the destination file.
+ std::string toFile = this->Destination;
+ std::string const& toName = this->ToName(fromName);
+ if(!toName.empty())
+ {
+ toFile += "/";
+ toFile += toName;
+ }
+
+ // Construct the full path to the source file. The file name may
+ // have been changed above.
+ std::string fromFile = fromDir;
+ if(!fromName.empty())
+ {
+ fromFile += "/";
+ fromFile += fromName;
+ }
+
+ if(!this->Install(fromFile.c_str(), toFile.c_str()))
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmFileCopier::Install(const char* fromFile, const char* toFile)
+{
+ if(!*fromFile)
+ {
+ cmOStringStream e;
+ e << "INSTALL encountered an empty string input file name.";
+ this->FileCommand->SetError(e.str().c_str());
+ return false;
+ }
+
+ // Collect any properties matching this file name.
+ MatchProperties match_properties = this->CollectMatchProperties(fromFile);
+
+ // Skip the file if it is excluded.
+ if(match_properties.Exclude)
+ {
+ return true;
+ }
+
+ if(cmSystemTools::SameFile(fromFile, toFile))
+ {
+ return true;
+ }
+ else if(cmSystemTools::FileIsSymlink(fromFile))
+ {
+ return this->InstallSymlink(fromFile, toFile);
+ }
+ else if(cmSystemTools::FileIsDirectory(fromFile))
+ {
+ return this->InstallDirectory(fromFile, toFile, match_properties);
+ }
+ else if(cmSystemTools::FileExists(fromFile))
+ {
+ return this->InstallFile(fromFile, toFile, match_properties);
+ }
+ return this->ReportMissing(fromFile);
+}
+
+//----------------------------------------------------------------------------
+bool cmFileCopier::InstallSymlink(const char* fromFile, const char* toFile)
+{
+ // Read the original symlink.
+ std::string symlinkTarget;
+ if(!cmSystemTools::ReadSymlink(fromFile, symlinkTarget))
+ {
+ cmOStringStream e;
+ e << this->Name << " cannot read symlink \"" << fromFile
+ << "\" to duplicate at \"" << toFile << "\".";
+ this->FileCommand->SetError(e.str().c_str());
+ return false;
+ }
+
+ // Compare the symlink value to that at the destination if not
+ // always installing.
+ bool copy = true;
+ if(!this->Always)
+ {
+ std::string oldSymlinkTarget;
+ if(cmSystemTools::ReadSymlink(toFile, oldSymlinkTarget))
+ {
+ if(symlinkTarget == oldSymlinkTarget)
+ {
+ copy = false;
+ }
+ }
+ }
+
+ // Inform the user about this file installation.
+ this->ReportCopy(toFile, TypeLink, copy);
+
+ if(copy)
+ {
+ // Remove the destination file so we can always create the symlink.
+ cmSystemTools::RemoveFile(toFile);
+
+ // Create the symlink.
+ if(!cmSystemTools::CreateSymlink(symlinkTarget.c_str(), toFile))
+ {
+ cmOStringStream e;
+ e << this->Name << " cannot duplicate symlink \"" << fromFile
+ << "\" at \"" << toFile << "\".";
+ this->FileCommand->SetError(e.str().c_str());
+ return false;
+ }
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmFileCopier::InstallFile(const char* fromFile, const char* toFile,
+ MatchProperties const& match_properties)
+{
+ // Determine whether we will copy the file.
+ bool copy = true;
+ if(!this->Always)
+ {
+ // If both files exist with the same time do not copy.
+ if(!this->FileTimes.FileTimesDiffer(fromFile, toFile))
+ {
+ copy = false;
+ }
+ }
+
+ // Inform the user about this file installation.
+ this->ReportCopy(toFile, TypeFile, copy);
+
+ // Copy the file.
+ if(copy && !cmSystemTools::CopyAFile(fromFile, toFile, true))
+ {
+ cmOStringStream e;
+ e << this->Name << " cannot copy file \"" << fromFile
+ << "\" to \"" << toFile << "\".";
+ this->FileCommand->SetError(e.str().c_str());
+ return false;
+ }
+
+ // Set the file modification time of the destination file.
+ if(copy && !this->Always)
+ {
+ // Add write permission so we can set the file time.
+ // Permissions are set unconditionally below anyway.
+ mode_t perm = 0;
+ if(cmSystemTools::GetPermissions(toFile, perm))
+ {
+ cmSystemTools::SetPermissions(toFile, perm | mode_owner_write);
+ }
+ if (!cmSystemTools::CopyFileTime(fromFile, toFile))
+ {
+ cmOStringStream e;
+ e << this->Name << " cannot set modification time on \""
+ << toFile << "\"";
+ this->FileCommand->SetError(e.str().c_str());
+ return false;
+ }
+ }
+
+ // Set permissions of the destination file.
+ mode_t permissions = (match_properties.Permissions?
+ match_properties.Permissions : this->FilePermissions);
+ if(!permissions)
+ {
+ // No permissions were explicitly provided but the user requested
+ // that the source file permissions be used.
+ cmSystemTools::GetPermissions(fromFile, permissions);
+ }
+ return this->SetPermissions(toFile, permissions);
+}
+
+//----------------------------------------------------------------------------
+bool cmFileCopier::InstallDirectory(const char* source,
+ const char* destination,
+ MatchProperties const& match_properties)
+{
+ // Inform the user about this directory installation.
+ this->ReportCopy(destination, TypeDir, true);
+
+ // Make sure the destination directory exists.
+ if(!cmSystemTools::MakeDirectory(destination))
+ {
+ cmOStringStream e;
+ e << this->Name << " cannot make directory \"" << destination << "\": "
+ << cmSystemTools::GetLastSystemError();
+ this->FileCommand->SetError(e.str().c_str());
+ return false;
+ }
+
+ // Compute the requested permissions for the destination directory.
+ mode_t permissions = (match_properties.Permissions?
+ match_properties.Permissions : this->DirPermissions);
+ if(!permissions)
+ {
+ // No permissions were explicitly provided but the user requested
+ // that the source directory permissions be used.
+ cmSystemTools::GetPermissions(source, permissions);
+ }
+
+ // Compute the set of permissions required on this directory to
+ // recursively install files and subdirectories safely.
+ mode_t required_permissions =
+ mode_owner_read | mode_owner_write | mode_owner_execute;
+
+ // If the required permissions are specified it is safe to set the
+ // final permissions now. Otherwise we must add the required
+ // permissions temporarily during file installation.
+ mode_t permissions_before = 0;
+ mode_t permissions_after = 0;
+ if((permissions & required_permissions) == required_permissions)
+ {
+ permissions_before = permissions;
+ }
+ else
+ {
+ permissions_before = permissions | required_permissions;
+ permissions_after = permissions;
+ }
+
+ // Set the required permissions of the destination directory.
+ if(!this->SetPermissions(destination, permissions_before))
+ {
+ return false;
+ }
+
+ // Load the directory contents to traverse it recursively.
+ cmsys::Directory dir;
+ if(source && *source)
+ {
+ dir.Load(source);
+ }
+ unsigned long numFiles = static_cast<unsigned long>(dir.GetNumberOfFiles());
+ for(unsigned long fileNum = 0; fileNum < numFiles; ++fileNum)
+ {
+ if(!(strcmp(dir.GetFile(fileNum), ".") == 0 ||
+ strcmp(dir.GetFile(fileNum), "..") == 0))
+ {
+ cmsys_stl::string fromPath = source;
+ fromPath += "/";
+ fromPath += dir.GetFile(fileNum);
+ std::string toPath = destination;
+ toPath += "/";
+ toPath += dir.GetFile(fileNum);
+ if(!this->Install(fromPath.c_str(), toPath.c_str()))
+ {
+ return false;
+ }
+ }
+ }
+
+ // Set the requested permissions of the destination directory.
+ return this->SetPermissions(destination, permissions_after);
+}
+
+//----------------------------------------------------------------------------
+bool cmFileCommand::HandleCopyCommand(std::vector<std::string> const& args)
+{
+ cmFileCopier copier(this);
+ return copier.Run(args);
+}
+
+//----------------------------------------------------------------------------
+struct cmFileInstaller: public cmFileCopier
+{
+ cmFileInstaller(cmFileCommand* command):
+ cmFileCopier(command, "INSTALL"),
+ InstallType(cmInstallType_FILES),
+ Optional(false),
+ DestDirLength(0)
+ {
+ // Installation does not use source permissions by default.
+ this->UseSourcePermissions = false;
+ // Check whether to copy files always or only if they have changed.
+ this->Always =
+ cmSystemTools::IsOn(cmSystemTools::GetEnv("CMAKE_INSTALL_ALWAYS"));
+ // Get the current manifest.
+ this->Manifest =
+ this->Makefile->GetSafeDefinition("CMAKE_INSTALL_MANIFEST_FILES");
+ }
+ ~cmFileInstaller()
+ {
+ // Save the updated install manifest.
+ this->Makefile->AddDefinition("CMAKE_INSTALL_MANIFEST_FILES",
+ this->Manifest.c_str());
+ }
+
+protected:
+ cmInstallType InstallType;
+ bool Optional;
+ int DestDirLength;
+ std::string Rename;
+
+ std::string Manifest;
+ void ManifestAppend(std::string const& file)
+ {
+ this->Manifest += ";";
+ this->Manifest += file.substr(this->DestDirLength);
+ }
+
+ virtual std::string const& ToName(std::string const& fromName)
+ { return this->Rename.empty()? fromName : this->Rename; }
+
+ 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(type != TypeDir)
+ {
+ // Add the file to the manifest.
+ this->ManifestAppend(toFile);
+ }
+ }
+ virtual bool ReportMissing(const char* fromFile)
+ {
+ return (this->Optional ||
+ this->cmFileCopier::ReportMissing(fromFile));
+ }
+ virtual bool Install(const char* fromFile, const char* toFile)
+ {
+ // Support installing from empty source to make a directory.
+ if(this->InstallType == cmInstallType_DIRECTORY && !*fromFile)
+ {
+ return this->InstallDirectory(fromFile, toFile, MatchProperties());
+ }
+ return this->cmFileCopier::Install(fromFile, toFile);
+ }
+
+ virtual bool Parse(std::vector<std::string> const& args);
+ enum
+ {
+ DoingType = DoingLast1,
+ DoingRename,
+ DoingLast2
+ };
+ virtual bool CheckKeyword(std::string const& arg);
+ virtual bool CheckValue(std::string const& arg);
+ virtual void DefaultFilePermissions()
+ {
+ this->cmFileCopier::DefaultFilePermissions();
+ // Add execute permissions based on the target type.
+ switch(this->InstallType)
+ {
+ case cmInstallType_SHARED_LIBRARY:
+ case cmInstallType_MODULE_LIBRARY:
+ if(this->Makefile->IsOn("CMAKE_INSTALL_SO_NO_EXE"))
+ {
+ break;
+ }
+ case cmInstallType_EXECUTABLE:
+ case cmInstallType_PROGRAMS:
+ this->FilePermissions |= mode_owner_execute;
+ this->FilePermissions |= mode_group_execute;
+ this->FilePermissions |= mode_world_execute;
+ break;
+ default: break;
+ }
+ }
+ bool GetTargetTypeFromString(const std::string& stype);
+ bool HandleInstallDestination();
+};
+
+//----------------------------------------------------------------------------
+bool cmFileInstaller::Parse(std::vector<std::string> const& args)
+{
+ if(!this->cmFileCopier::Parse(args))
+ {
+ return false;
+ }
+
+ if(!this->Rename.empty())
+ {
+ if(this->InstallType != cmInstallType_FILES &&
+ this->InstallType != cmInstallType_PROGRAMS)
+ {
+ this->FileCommand->SetError("INSTALL option RENAME may be used "
+ "only with FILES or PROGRAMS.");
+ return false;
+ }
+ if(this->Files.size() > 1)
+ {
+ this->FileCommand->SetError("INSTALL option RENAME may be used "
+ "only with one file.");
+ return false;
+ }
+ }
+
+ if(!this->HandleInstallDestination())
+ {
+ return false;
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmFileInstaller::CheckKeyword(std::string const& arg)
+{
+ if(arg == "TYPE")
+ {
+ if(this->CurrentMatchRule)
+ {
+ this->NotAfterMatch(arg);
+ }
+ else
+ {
+ this->Doing = DoingType;
+ }
+ }
+ else if(arg == "FILES")
+ {
+ if(this->CurrentMatchRule)
+ {
+ this->NotAfterMatch(arg);
+ }
+ else
+ {
+ this->Doing = DoingFiles;
+ }
+ }
+ else if(arg == "RENAME")
+ {
+ if(this->CurrentMatchRule)
+ {
+ this->NotAfterMatch(arg);
+ }
+ else
+ {
+ this->Doing = DoingRename;
+ }
+ }
+ else if(arg == "OPTIONAL")
+ {
+ if(this->CurrentMatchRule)
+ {
+ this->NotAfterMatch(arg);
+ }
+ else
+ {
+ this->Doing = DoingNone;
+ this->Optional = true;
+ }
+ }
+ else if(arg == "PERMISSIONS")
+ {
+ if(this->CurrentMatchRule)
+ {
+ this->Doing = DoingPermissionsMatch;
+ }
+ else
+ {
+ // file(INSTALL) aliases PERMISSIONS to FILE_PERMISSIONS
+ this->Doing = DoingPermissionsFile;
+ this->UseGivenPermissionsFile = true;
+ }
+ }
+ else if(arg == "DIR_PERMISSIONS")
+ {
+ if(this->CurrentMatchRule)
+ {
+ this->NotAfterMatch(arg);
+ }
+ else
+ {
+ // file(INSTALL) aliases DIR_PERMISSIONS to DIRECTORY_PERMISSIONS
+ this->Doing = DoingPermissionsDir;
+ this->UseGivenPermissionsDir = true;
+ }
+ }
+ else if(arg == "COMPONENTS" || arg == "CONFIGURATIONS" ||
+ arg == "PROPERTIES")
+ {
+ cmOStringStream 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->Doing = DoingError;
+ }
+ else
+ {
+ return this->cmFileCopier::CheckKeyword(arg);
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmFileInstaller::CheckValue(std::string const& arg)
+{
+ switch(this->Doing)
+ {
+ case DoingType:
+ if(!this->GetTargetTypeFromString(arg))
+ {
+ this->Doing = DoingError;
+ }
+ break;
+ case DoingRename:
+ this->Rename = arg;
+ break;
+ default:
+ return this->cmFileCopier::CheckValue(arg);
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmFileInstaller
+::GetTargetTypeFromString(const std::string& stype)
+{
+ if ( stype == "EXECUTABLE" )
+ {
+ this->InstallType = cmInstallType_EXECUTABLE;
+ }
+ else if ( stype == "FILE" )
+ {
+ this->InstallType = cmInstallType_FILES;
+ }
+ else if ( stype == "PROGRAM" )
+ {
+ this->InstallType = cmInstallType_PROGRAMS;
+ }
+ else if ( stype == "STATIC_LIBRARY" )
+ {
+ this->InstallType = cmInstallType_STATIC_LIBRARY;
+ }
+ else if ( stype == "SHARED_LIBRARY" )
+ {
+ this->InstallType = cmInstallType_SHARED_LIBRARY;
+ }
+ else if ( stype == "MODULE" )
+ {
+ this->InstallType = cmInstallType_MODULE_LIBRARY;
+ }
+ else if ( stype == "DIRECTORY" )
+ {
+ this->InstallType = cmInstallType_DIRECTORY;
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "Option TYPE given uknown value \"" << stype << "\".";
+ this->FileCommand->SetError(e.str().c_str());
+ return false;
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmFileInstaller::HandleInstallDestination()
+{
+ std::string& destination = this->Destination;
+
+ // allow for / to be a valid destination
+ if ( destination.size() < 2 && destination != "/" )
+ {
+ this->FileCommand->SetError("called with inapropriate arguments. "
+ "No DESTINATION provided or .");
+ return false;
+ }
+
+ const char* destdir = cmSystemTools::GetEnv("DESTDIR");
+ if ( destdir && *destdir )
+ {
+ std::string sdestdir = destdir;
+ cmSystemTools::ConvertToUnixSlashes(sdestdir);
+ char ch1 = destination[0];
+ char ch2 = destination[1];
+ char ch3 = 0;
+ if ( destination.size() > 2 )
+ {
+ ch3 = destination[2];
+ }
+ int skip = 0;
+ if ( ch1 != '/' )
+ {
+ int relative = 0;
+ if (((ch1 >= 'a' && ch1 <= 'z') || (ch1 >= 'A' && ch1 <= 'Z')) &&
+ ch2 == ':' )
+ {
+ // Assume windows
+ // let's do some destdir magic:
+ skip = 2;
+ if ( ch3 != '/' )
+ {
+ relative = 1;
+ }
+ }
+ else
+ {
+ relative = 1;
+ }
+ if ( relative )
+ {
+ // This is relative path on unix or windows. Since we are doing
+ // destdir, this case does not make sense.
+ this->FileCommand->SetError(
+ "called with relative DESTINATION. This "
+ "does not make sense when using DESTDIR. Specify "
+ "absolute path or remove DESTDIR environment variable.");
+ return false;
+ }
+ }
+ else
+ {
+ if ( ch2 == '/' )
+ {
+ // looks like a network path.
+ std::string message = "called with network path DESTINATION. This "
+ "does not make sense when using DESTDIR. Specify local "
+ "absolute path or remove DESTDIR environment variable."
+ "\nDESTINATION=\n";
+ message += destination;
+ this->FileCommand->SetError(message.c_str());
+ return false;
+ }
+ }
+ destination = sdestdir + (destination.c_str() + skip);
+ this->DestDirLength = int(sdestdir.size());
+ }
+
+ if ( !cmSystemTools::FileExists(destination.c_str()) )
+ {
+ 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;
+ }
+ }
+ if ( !cmSystemTools::FileIsDirectory(destination.c_str()) )
+ {
+ std::string errstring = "INSTALL destination: " + destination +
+ " is not a directory.";
+ this->FileCommand->SetError(errstring.c_str());
+ return false;
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool
+cmFileCommand::HandleRPathChangeCommand(std::vector<std::string> const& args)
+{
+ // Evaluate arguments.
+ const char* file = 0;
+ const char* oldRPath = 0;
+ const char* newRPath = 0;
+ enum Doing { DoingNone, DoingFile, DoingOld, DoingNew };
+ Doing doing = DoingNone;
+ for(unsigned int i=1; i < args.size(); ++i)
+ {
+ if(args[i] == "OLD_RPATH")
+ {
+ doing = DoingOld;
+ }
+ else if(args[i] == "NEW_RPATH")
+ {
+ doing = DoingNew;
+ }
+ else if(args[i] == "FILE")
+ {
+ doing = DoingFile;
+ }
+ else if(doing == DoingFile)
+ {
+ file = args[i].c_str();
+ doing = DoingNone;
+ }
+ else if(doing == DoingOld)
+ {
+ oldRPath = args[i].c_str();
+ doing = DoingNone;
+ }
+ else if(doing == DoingNew)
+ {
+ newRPath = args[i].c_str();
+ doing = DoingNone;
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "RPATH_CHANGE given unknown argument " << args[i];
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+ if(!file)
+ {
+ this->SetError("RPATH_CHANGE not given FILE option.");
+ return false;
+ }
+ if(!oldRPath)
+ {
+ this->SetError("RPATH_CHANGE not given OLD_RPATH option.");
+ return false;
+ }
+ if(!newRPath)
+ {
+ this->SetError("RPATH_CHANGE not given NEW_RPATH option.");
+ return false;
+ }
+ if(!cmSystemTools::FileExists(file, true))
+ {
+ cmOStringStream e;
+ e << "RPATH_CHANGE given FILE \"" << file << "\" that does not exist.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ bool success = true;
+ cmSystemToolsFileTime* ft = cmSystemTools::FileTimeNew();
+ bool have_ft = cmSystemTools::FileTimeGet(file, ft);
+ std::string emsg;
+ bool changed;
+ if(!cmSystemTools::ChangeRPath(file, oldRPath, newRPath, &emsg, &changed))
+ {
+ cmOStringStream 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());
+ success = false;
+ }
+ if(success)
+ {
+ if(changed)
+ {
+ std::string message = "Set runtime path of \"";
+ message += file;
+ message += "\" to \"";
+ message += newRPath;
+ message += "\"";
+ this->Makefile->DisplayStatus(message.c_str(), -1);
+ }
+ if(have_ft)
+ {
+ cmSystemTools::FileTimeSet(file, ft);
+ }
+ }
+ cmSystemTools::FileTimeDelete(ft);
+ return success;
+}
+
+//----------------------------------------------------------------------------
+bool
+cmFileCommand::HandleRPathRemoveCommand(std::vector<std::string> const& args)
+{
+ // Evaluate arguments.
+ const char* file = 0;
+ enum Doing { DoingNone, DoingFile };
+ Doing doing = DoingNone;
+ for(unsigned int i=1; i < args.size(); ++i)
+ {
+ if(args[i] == "FILE")
+ {
+ doing = DoingFile;
+ }
+ else if(doing == DoingFile)
+ {
+ file = args[i].c_str();
+ doing = DoingNone;
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "RPATH_REMOVE given unknown argument " << args[i];
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+ if(!file)
+ {
+ this->SetError("RPATH_REMOVE not given FILE option.");
+ return false;
+ }
+ if(!cmSystemTools::FileExists(file, true))
+ {
+ cmOStringStream e;
+ e << "RPATH_REMOVE given FILE \"" << file << "\" that does not exist.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ bool success = true;
+ cmSystemToolsFileTime* ft = cmSystemTools::FileTimeNew();
+ bool have_ft = cmSystemTools::FileTimeGet(file, ft);
+ std::string emsg;
+ bool removed;
+ if(!cmSystemTools::RemoveRPath(file, &emsg, &removed))
+ {
+ cmOStringStream e;
+ e << "RPATH_REMOVE could not remove RPATH from file:\n"
+ << " " << file << "\n"
+ << emsg;
+ this->SetError(e.str().c_str());
+ success = false;
+ }
+ if(success)
+ {
+ if(removed)
+ {
+ std::string message = "Removed runtime path from \"";
+ message += file;
+ message += "\"";
+ this->Makefile->DisplayStatus(message.c_str(), -1);
+ }
+ if(have_ft)
+ {
+ cmSystemTools::FileTimeSet(file, ft);
+ }
+ }
+ cmSystemTools::FileTimeDelete(ft);
+ return success;
+}
+
+//----------------------------------------------------------------------------
+bool
+cmFileCommand::HandleRPathCheckCommand(std::vector<std::string> const& args)
+{
+ // Evaluate arguments.
+ const char* file = 0;
+ const char* rpath = 0;
+ enum Doing { DoingNone, DoingFile, DoingRPath };
+ Doing doing = DoingNone;
+ for(unsigned int i=1; i < args.size(); ++i)
+ {
+ if(args[i] == "RPATH")
+ {
+ doing = DoingRPath;
+ }
+ else if(args[i] == "FILE")
+ {
+ doing = DoingFile;
+ }
+ else if(doing == DoingFile)
+ {
+ file = args[i].c_str();
+ doing = DoingNone;
+ }
+ else if(doing == DoingRPath)
+ {
+ rpath = args[i].c_str();
+ doing = DoingNone;
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "RPATH_CHECK given unknown argument " << args[i];
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+ if(!file)
+ {
+ this->SetError("RPATH_CHECK not given FILE option.");
+ return false;
+ }
+ if(!rpath)
+ {
+ this->SetError("RPATH_CHECK not given RPATH option.");
+ return false;
+ }
+
+ // If the file exists but does not have the desired RPath then
+ // delete it. This is used during installation to re-install a file
+ // if its RPath will change.
+ if(cmSystemTools::FileExists(file, true) &&
+ !cmSystemTools::CheckRPath(file, rpath))
+ {
+ cmSystemTools::RemoveFile(file);
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmFileCommand::HandleInstallCommand(std::vector<std::string> const& args)
+{
+ cmFileInstaller installer(this);
+ return installer.Run(args);
+}
+
+//----------------------------------------------------------------------------
+bool cmFileCommand::HandleRelativePathCommand(
+ std::vector<std::string> const& args)
+{
+ if(args.size() != 4 )
+ {
+ this->SetError("RELATIVE_PATH called with incorrect number of arguments");
+ return false;
+ }
+
+ const std::string& outVar = args[1];
+ const std::string& directoryName = args[2];
+ const std::string& fileName = args[3];
+
+ if(!cmSystemTools::FileIsFullPath(directoryName.c_str()))
+ {
+ std::string errstring =
+ "RELATIVE_PATH must be passed a full path to the directory: "
+ + directoryName;
+ this->SetError(errstring.c_str());
+ return false;
+ }
+ if(!cmSystemTools::FileIsFullPath(fileName.c_str()))
+ {
+ std::string errstring =
+ "RELATIVE_PATH must be passed a full path to the file: "
+ + fileName;
+ this->SetError(errstring.c_str());
+ return false;
+ }
+
+ std::string res = cmSystemTools::RelativePath(directoryName.c_str(),
+ fileName.c_str());
+ this->Makefile->AddDefinition(outVar.c_str(),
+ res.c_str());
+ return true;
+}
+
+
+//----------------------------------------------------------------------------
+bool cmFileCommand::HandleRename(std::vector<std::string> const& args)
+{
+ if(args.size() != 3)
+ {
+ this->SetError("RENAME given incorrect number of arguments.");
+ return false;
+ }
+
+ // Compute full path for old and new names.
+ std::string oldname = args[1];
+ if(!cmsys::SystemTools::FileIsFullPath(oldname.c_str()))
+ {
+ oldname = this->Makefile->GetCurrentDirectory();
+ oldname += "/" + args[1];
+ }
+ std::string newname = args[2];
+ if(!cmsys::SystemTools::FileIsFullPath(newname.c_str()))
+ {
+ newname = this->Makefile->GetCurrentDirectory();
+ newname += "/" + args[2];
+ }
+
+ if(!cmSystemTools::RenameFile(oldname.c_str(), newname.c_str()))
+ {
+ std::string err = cmSystemTools::GetLastSystemError();
+ cmOStringStream e;
+ e << "RENAME failed to rename\n"
+ << " " << oldname << "\n"
+ << "to\n"
+ << " " << newname << "\n"
+ << "because: " << err << "\n";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ return true;
+}
+
+
+//----------------------------------------------------------------------------
+bool cmFileCommand::HandleRemove(std::vector<std::string> const& args,
+ bool recurse)
+{
+
+ std::string message;
+ std::vector<std::string>::const_iterator i = args.begin();
+
+ i++; // Get rid of subcommand
+ for(;i != args.end(); ++i)
+ {
+ std::string fileName = *i;
+ if(!cmsys::SystemTools::FileIsFullPath(fileName.c_str()))
+ {
+ fileName = this->Makefile->GetCurrentDirectory();
+ fileName += "/" + *i;
+ }
+
+ if(cmSystemTools::FileIsDirectory(fileName.c_str()) && recurse)
+ {
+ cmSystemTools::RemoveADirectory(fileName.c_str());
+ }
+ else
+ {
+ cmSystemTools::RemoveFile(fileName.c_str());
+ }
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmFileCommand::HandleCMakePathCommand(std::vector<std::string>
+ const& args,
+ bool nativePath)
+{
+ std::vector<std::string>::const_iterator i = args.begin();
+ if(args.size() != 3)
+ {
+ this->SetError("FILE([TO_CMAKE_PATH|TO_NATIVE_PATH] path result) must be "
+ "called with exactly three arguments.");
+ return false;
+ }
+ i++; // Get rid of subcommand
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ char pathSep = ';';
+#else
+ char pathSep = ':';
+#endif
+ std::vector<cmsys::String> path = cmSystemTools::SplitString(i->c_str(),
+ pathSep);
+ i++;
+ const char* var = i->c_str();
+ std::string value;
+ for(std::vector<cmsys::String>::iterator j = path.begin();
+ j != path.end(); ++j)
+ {
+ if(j != path.begin())
+ {
+ value += ";";
+ }
+ if(!nativePath)
+ {
+ cmSystemTools::ConvertToUnixSlashes(*j);
+ }
+ else
+ {
+ *j = cmSystemTools::ConvertToOutputPath(j->c_str());
+ // remove double quotes in the path
+ cmsys::String& s = *j;
+
+ if(s.size() > 1 && s[0] == '\"' && s[s.size()-1] == '\"')
+ {
+ s = s.substr(1,s.size()-2);
+ }
+ }
+ value += *j;
+ }
+ this->Makefile->AddDefinition(var, value.c_str());
+ return true;
+}
+
+
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+
+// Stuff for curl download/upload
+typedef std::vector<char> cmFileCommandVectorOfChar;
+
+namespace {
+
+ size_t
+ cmWriteToFileCallback(void *ptr, size_t size, size_t nmemb,
+ void *data)
+ {
+ register int realsize = (int)(size * nmemb);
+ std::ofstream* fout = static_cast<std::ofstream*>(data);
+ const char* chPtr = static_cast<char*>(ptr);
+ fout->write(chPtr, realsize);
+ return realsize;
+ }
+
+
+ size_t
+ cmWriteToMemoryCallback(void *ptr, size_t size, size_t nmemb,
+ void *data)
+ {
+ register int realsize = (int)(size * nmemb);
+ cmFileCommandVectorOfChar *vec
+ = static_cast<cmFileCommandVectorOfChar*>(data);
+ const char* chPtr = static_cast<char*>(ptr);
+ vec->insert(vec->end(), chPtr, chPtr + realsize);
+ return realsize;
+ }
+
+
+ static size_t
+ cmFileCommandCurlDebugCallback(CURL *, curl_infotype, char *chPtr,
+ size_t size, void *data)
+ {
+ cmFileCommandVectorOfChar *vec
+ = static_cast<cmFileCommandVectorOfChar*>(data);
+ vec->insert(vec->end(), chPtr, chPtr + size);
+ return size;
+ }
+
+
+ class cURLProgressHelper
+ {
+ public:
+ cURLProgressHelper(cmFileCommand *fc, const char *text)
+ {
+ this->CurrentPercentage = -1;
+ this->FileCommand = fc;
+ this->Text = text;
+ }
+
+ bool UpdatePercentage(double value, double total, std::string &status)
+ {
+ int OldPercentage = this->CurrentPercentage;
+
+ if (total > 0.0)
+ {
+ this->CurrentPercentage = static_cast<int>(value/total*100.0 + 0.5);
+ }
+
+ bool updated = (OldPercentage != this->CurrentPercentage);
+
+ if (updated)
+ {
+ cmOStringStream oss;
+ oss << "[" << this->Text << " " << this->CurrentPercentage
+ << "% complete]";
+ status = oss.str();
+ }
+
+ return updated;
+ }
+
+ cmFileCommand *GetFileCommand()
+ {
+ return this->FileCommand;
+ }
+
+ private:
+ int CurrentPercentage;
+ cmFileCommand *FileCommand;
+ std::string Text;
+ };
+
+
+ static int
+ cmFileDownloadProgressCallback(void *clientp,
+ double dltotal, double dlnow,
+ double ultotal, double ulnow)
+ {
+ cURLProgressHelper *helper =
+ reinterpret_cast<cURLProgressHelper *>(clientp);
+
+ static_cast<void>(ultotal);
+ static_cast<void>(ulnow);
+
+ std::string status;
+ if (helper->UpdatePercentage(dlnow, dltotal, status))
+ {
+ cmFileCommand *fc = helper->GetFileCommand();
+ cmMakefile *mf = fc->GetMakefile();
+ mf->DisplayStatus(status.c_str(), -1);
+ }
+
+ return 0;
+ }
+
+
+ static int
+ cmFileUploadProgressCallback(void *clientp,
+ double dltotal, double dlnow,
+ double ultotal, double ulnow)
+ {
+ cURLProgressHelper *helper =
+ reinterpret_cast<cURLProgressHelper *>(clientp);
+
+ static_cast<void>(dltotal);
+ static_cast<void>(dlnow);
+
+ std::string status;
+ if (helper->UpdatePercentage(ulnow, ultotal, status))
+ {
+ cmFileCommand *fc = helper->GetFileCommand();
+ cmMakefile *mf = fc->GetMakefile();
+ mf->DisplayStatus(status.c_str(), -1);
+ }
+
+ return 0;
+ }
+}
+
+
+namespace {
+
+ class cURLEasyGuard
+ {
+ public:
+ cURLEasyGuard(CURL * easy)
+ : Easy(easy)
+ {}
+
+ ~cURLEasyGuard(void)
+ {
+ if (this->Easy)
+ {
+ ::curl_easy_cleanup(this->Easy);
+ }
+ }
+
+ inline void release(void)
+ {
+ this->Easy = 0;
+ return;
+ }
+
+ private:
+ ::CURL * Easy;
+ };
+
+}
+#endif
+
+
+#define check_curl_result(result, errstr) \
+ if (result != CURLE_OK) \
+ { \
+ std::string e(errstr); \
+ e += ::curl_easy_strerror(result); \
+ this->SetError(e.c_str()); \
+ return false; \
+ }
+
+
+bool
+cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
+{
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ std::vector<std::string>::const_iterator i = args.begin();
+ if(args.size() < 3)
+ {
+ this->SetError("DOWNLOAD must be called with at least three arguments.");
+ return false;
+ }
+ ++i; // Get rid of subcommand
+ std::string url = *i;
+ ++i;
+ std::string file = *i;
+ ++i;
+
+ long timeout = 0;
+ long inactivity_timeout = 0;
+ std::string verboseLog;
+ std::string statusVar;
+ std::string expectedMD5sum;
+ bool showProgress = false;
+
+ while(i != args.end())
+ {
+ if(*i == "TIMEOUT")
+ {
+ ++i;
+ if(i != args.end())
+ {
+ timeout = atol(i->c_str());
+ }
+ else
+ {
+ this->SetError("DOWNLOAD missing time for TIMEOUT.");
+ return false;
+ }
+ }
+ else if(*i == "INACTIVITY_TIMEOUT")
+ {
+ ++i;
+ if(i != args.end())
+ {
+ inactivity_timeout = atol(i->c_str());
+ }
+ else
+ {
+ this->SetError("DOWNLOAD missing time for INACTIVITY_TIMEOUT.");
+ return false;
+ }
+ }
+ else if(*i == "LOG")
+ {
+ ++i;
+ if( i == args.end())
+ {
+ this->SetError("DOWNLOAD missing VAR for LOG.");
+ return false;
+ }
+ verboseLog = *i;
+ }
+ else if(*i == "STATUS")
+ {
+ ++i;
+ if( i == args.end())
+ {
+ this->SetError("DOWNLOAD missing VAR for STATUS.");
+ return false;
+ }
+ statusVar = *i;
+ }
+ else if(*i == "EXPECTED_MD5")
+ {
+ ++i;
+ if( i == args.end())
+ {
+ this->SetError("DOWNLOAD missing sum value for EXPECTED_MD5.");
+ return false;
+ }
+ expectedMD5sum = cmSystemTools::LowerCase(*i);
+ }
+ else if(*i == "SHOW_PROGRESS")
+ {
+ showProgress = true;
+ }
+ ++i;
+ }
+
+ // If file exists already, and caller specified an expected md5 sum,
+ // and the existing file already has the expected md5 sum, then simply
+ // return.
+ //
+ if(cmSystemTools::FileExists(file.c_str()) &&
+ !expectedMD5sum.empty())
+ {
+ char computedMD5[32];
+
+ if (!cmSystemTools::ComputeFileMD5(file.c_str(), computedMD5))
+ {
+ this->SetError("DOWNLOAD cannot compute MD5 sum on pre-existing file");
+ return false;
+ }
+
+ std::string actualMD5sum = cmSystemTools::LowerCase(
+ std::string(computedMD5, 32));
+
+ if (expectedMD5sum == actualMD5sum)
+ {
+ if(statusVar.size())
+ {
+ cmOStringStream result;
+ result << (int)0 << ";\""
+ "returning early: file already exists with expected MD5 sum\"";
+ this->Makefile->AddDefinition(statusVar.c_str(),
+ result.str().c_str());
+ }
+
+ return true;
+ }
+ }
+
+ // 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());
+ 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());
+ return false;
+ }
+
+ std::ofstream fout(file.c_str(), std::ios::binary);
+ if(!fout)
+ {
+ this->SetError("DOWNLOAD cannot open file for write.");
+ return false;
+ }
+
+ ::CURL *curl;
+ ::curl_global_init(CURL_GLOBAL_DEFAULT);
+ curl = ::curl_easy_init();
+ if(!curl)
+ {
+ this->SetError("DOWNLOAD error initializing curl.");
+ return false;
+ }
+
+ cURLEasyGuard g_curl(curl);
+
+ ::CURLcode res = ::curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
+ check_curl_result(res, "DOWNLOAD cannot set url: ");
+
+ // enable HTTP ERROR parsing
+ res = ::curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);
+ check_curl_result(res, "DOWNLOAD cannot set http failure option: ");
+
+ res = ::curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
+ cmWriteToFileCallback);
+ check_curl_result(res, "DOWNLOAD cannot set write function: ");
+
+ res = ::curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION,
+ cmFileCommandCurlDebugCallback);
+ check_curl_result(res, "DOWNLOAD cannot set debug function: ");
+
+ cmFileCommandVectorOfChar chunkDebug;
+
+ res = ::curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&fout);
+ check_curl_result(res, "DOWNLOAD cannot set write data: ");
+
+ res = ::curl_easy_setopt(curl, CURLOPT_DEBUGDATA, (void *)&chunkDebug);
+ check_curl_result(res, "DOWNLOAD cannot set debug data: ");
+
+ res = ::curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
+ check_curl_result(res, "DOWNLOAD cannot set follow-redirect option: ");
+
+ if(verboseLog.size())
+ {
+ res = ::curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
+ check_curl_result(res, "DOWNLOAD cannot set verbose: ");
+ }
+
+ if(timeout > 0)
+ {
+ res = ::curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout );
+ check_curl_result(res, "DOWNLOAD cannot set timeout: ");
+ }
+
+ if(inactivity_timeout > 0)
+ {
+ // Give up if there is no progress for a long time.
+ ::curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, 1);
+ ::curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, inactivity_timeout);
+ }
+
+ // Need the progress helper's scope to last through the duration of
+ // the curl_easy_perform call... so this object is declared at function
+ // scope intentionally, rather than inside the "if(showProgress)"
+ // block...
+ //
+ cURLProgressHelper helper(this, "download");
+
+ if(showProgress)
+ {
+ res = ::curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
+ check_curl_result(res, "DOWNLOAD cannot set noprogress value: ");
+
+ res = ::curl_easy_setopt(curl,
+ CURLOPT_PROGRESSFUNCTION, cmFileDownloadProgressCallback);
+ check_curl_result(res, "DOWNLOAD cannot set progress function: ");
+
+ res = ::curl_easy_setopt(curl,
+ CURLOPT_PROGRESSDATA, reinterpret_cast<void*>(&helper));
+ check_curl_result(res, "DOWNLOAD cannot set progress data: ");
+ }
+
+ res = ::curl_easy_perform(curl);
+
+ /* always cleanup */
+ g_curl.release();
+ ::curl_easy_cleanup(curl);
+
+ if(statusVar.size())
+ {
+ cmOStringStream result;
+ result << (int)res << ";\"" << ::curl_easy_strerror(res) << "\"";
+ this->Makefile->AddDefinition(statusVar.c_str(),
+ result.str().c_str());
+ }
+
+ ::curl_global_cleanup();
+
+ // Explicitly flush/close so we can measure the md5 accurately.
+ //
+ fout.flush();
+ fout.close();
+
+ // Verify MD5 sum if requested:
+ //
+ if (!expectedMD5sum.empty())
+ {
+ char computedMD5[32];
+
+ if (!cmSystemTools::ComputeFileMD5(file.c_str(), computedMD5))
+ {
+ this->SetError("DOWNLOAD cannot compute MD5 sum on downloaded file");
+ return false;
+ }
+
+ std::string actualMD5sum = cmSystemTools::LowerCase(
+ std::string(computedMD5, 32));
+
+ if (expectedMD5sum != actualMD5sum)
+ {
+ cmOStringStream oss;
+ oss << "DOWNLOAD MD5 mismatch" << std::endl
+ << " for file: [" << file << "]" << std::endl
+ << " expected MD5 sum: [" << expectedMD5sum << "]" << std::endl
+ << " actual MD5 sum: [" << actualMD5sum << "]" << std::endl
+ ;
+ this->SetError(oss.str().c_str());
+ return false;
+ }
+ }
+
+ if(chunkDebug.size())
+ {
+ 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());
+ }
+
+ return true;
+#else
+ this->SetError("DOWNLOAD not supported by bootstrap cmake.");
+ return false;
+#endif
+}
+
+
+bool
+cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
+{
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ if(args.size() < 3)
+ {
+ this->SetError("UPLOAD must be called with at least three arguments.");
+ return false;
+ }
+ std::vector<std::string>::const_iterator i = args.begin();
+ ++i;
+ std::string filename = *i;
+ ++i;
+ std::string url = *i;
+ ++i;
+
+ long timeout = 0;
+ long inactivity_timeout = 0;
+ std::string logVar;
+ std::string statusVar;
+ bool showProgress = false;
+
+ while(i != args.end())
+ {
+ if(*i == "TIMEOUT")
+ {
+ ++i;
+ if(i != args.end())
+ {
+ timeout = atol(i->c_str());
+ }
+ else
+ {
+ this->SetError("UPLOAD missing time for TIMEOUT.");
+ return false;
+ }
+ }
+ else if(*i == "INACTIVITY_TIMEOUT")
+ {
+ ++i;
+ if(i != args.end())
+ {
+ inactivity_timeout = atol(i->c_str());
+ }
+ else
+ {
+ this->SetError("UPLOAD missing time for INACTIVITY_TIMEOUT.");
+ return false;
+ }
+ }
+ else if(*i == "LOG")
+ {
+ ++i;
+ if( i == args.end())
+ {
+ this->SetError("UPLOAD missing VAR for LOG.");
+ return false;
+ }
+ logVar = *i;
+ }
+ else if(*i == "STATUS")
+ {
+ ++i;
+ if( i == args.end())
+ {
+ this->SetError("UPLOAD missing VAR for STATUS.");
+ return false;
+ }
+ statusVar = *i;
+ }
+ else if(*i == "SHOW_PROGRESS")
+ {
+ showProgress = true;
+ }
+
+ ++i;
+ }
+
+ // Open file for reading:
+ //
+ FILE *fin = fopen(filename.c_str(), "rb");
+ if(!fin)
+ {
+ std::string errStr = "UPLOAD cannot open file '";
+ errStr += filename + "' for reading.";
+ this->SetError(errStr.c_str());
+ 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;
+ }
+
+ ::CURL *curl;
+ ::curl_global_init(CURL_GLOBAL_DEFAULT);
+ curl = ::curl_easy_init();
+ if(!curl)
+ {
+ this->SetError("UPLOAD error initializing curl.");
+ fclose(fin);
+ return false;
+ }
+
+ cURLEasyGuard g_curl(curl);
+
+ // enable HTTP ERROR parsing
+ ::CURLcode res = ::curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);
+
+ // enable uploading
+ res = ::curl_easy_setopt(curl, CURLOPT_UPLOAD, 1);
+ check_curl_result(res, "UPLOAD cannot set upload flag: ");
+
+ res = ::curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
+ check_curl_result(res, "UPLOAD cannot set url: ");
+
+ res = ::curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
+ cmWriteToMemoryCallback);
+ check_curl_result(res, "UPLOAD cannot set write function: ");
+
+ res = ::curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION,
+ cmFileCommandCurlDebugCallback);
+ check_curl_result(res, "UPLOAD cannot set debug function: ");
+
+ cmFileCommandVectorOfChar chunkResponse;
+ cmFileCommandVectorOfChar chunkDebug;
+
+ res = ::curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunkResponse);
+ check_curl_result(res, "UPLOAD cannot set write data: ");
+
+ res = ::curl_easy_setopt(curl, CURLOPT_DEBUGDATA, (void *)&chunkDebug);
+ check_curl_result(res, "UPLOAD cannot set debug data: ");
+
+ res = ::curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
+ check_curl_result(res, "UPLOAD cannot set follow-redirect option: ");
+
+ if(logVar.size())
+ {
+ res = ::curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
+ check_curl_result(res, "UPLOAD cannot set verbose: ");
+ }
+
+ if(timeout > 0)
+ {
+ res = ::curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout );
+ check_curl_result(res, "UPLOAD cannot set timeout: ");
+ }
+
+ if(inactivity_timeout > 0)
+ {
+ // Give up if there is no progress for a long time.
+ ::curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, 1);
+ ::curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, inactivity_timeout);
+ }
+
+ // Need the progress helper's scope to last through the duration of
+ // the curl_easy_perform call... so this object is declared at function
+ // scope intentionally, rather than inside the "if(showProgress)"
+ // block...
+ //
+ cURLProgressHelper helper(this, "upload");
+
+ if(showProgress)
+ {
+ res = ::curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
+ check_curl_result(res, "UPLOAD cannot set noprogress value: ");
+
+ res = ::curl_easy_setopt(curl,
+ CURLOPT_PROGRESSFUNCTION, cmFileUploadProgressCallback);
+ check_curl_result(res, "UPLOAD cannot set progress function: ");
+
+ res = ::curl_easy_setopt(curl,
+ CURLOPT_PROGRESSDATA, reinterpret_cast<void*>(&helper));
+ check_curl_result(res, "UPLOAD cannot set progress data: ");
+ }
+
+ // now specify which file to upload
+ res = ::curl_easy_setopt(curl, CURLOPT_INFILE, fin);
+ check_curl_result(res, "UPLOAD cannot set input file: ");
+
+ // and give the size of the upload (optional)
+ res = ::curl_easy_setopt(curl,
+ CURLOPT_INFILESIZE, static_cast<long>(st.st_size));
+ check_curl_result(res, "UPLOAD cannot set input file size: ");
+
+ res = ::curl_easy_perform(curl);
+
+ /* always cleanup */
+ g_curl.release();
+ ::curl_easy_cleanup(curl);
+
+ if(statusVar.size())
+ {
+ cmOStringStream result;
+ result << (int)res << ";\"" << ::curl_easy_strerror(res) << "\"";
+ this->Makefile->AddDefinition(statusVar.c_str(),
+ result.str().c_str());
+ }
+
+ ::curl_global_cleanup();
+
+ fclose(fin);
+ fin = NULL;
+
+ if(logVar.size())
+ {
+ std::string log;
+
+ if(chunkResponse.size())
+ {
+ chunkResponse.push_back(0);
+ log += "Response:\n";
+ log += &*chunkResponse.begin();
+ log += "\n";
+ }
+
+ if(chunkDebug.size())
+ {
+ chunkDebug.push_back(0);
+ log += "Debug:\n";
+ log += &*chunkDebug.begin();
+ log += "\n";
+ }
+
+ this->Makefile->AddDefinition(logVar.c_str(), log.c_str());
+ }
+
+ return true;
+#else
+ this->SetError("UPLOAD not supported by bootstrap cmake.");
+ return false;
+#endif
+}
diff --git a/Source/cmFileCommand.h b/Source/cmFileCommand.h
new file mode 100644
index 000000000..ced26c49b
--- /dev/null
+++ b/Source/cmFileCommand.h
@@ -0,0 +1,254 @@
+/*============================================================================
+ 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 cmFileCommand_h
+#define cmFileCommand_h
+
+#include "cmCommand.h"
+
+struct cmFileInstaller;
+
+/** \class cmFileCommand
+ * \brief Command for manipulation of files
+ *
+ */
+class cmFileCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmFileCommand;
+ }
+
+ /**
+ * 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 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_MD5 sum])\n"
+ " file(UPLOAD filename url [INACTIVITY_TIMEOUT timeout]\n"
+ " [TIMEOUT timeout] [STATUS status] [LOG log] [SHOW_PROGRESS])\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.\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_MD5 sum is specified, the operation will verify that the "
+ "downloaded file's actual md5 sum matches the expected value. If it "
+ "does not match, the operation fails with an error. "
+ "If SHOW_PROGRESS is specified, progress information will be printed "
+ "as status messages until the operation is complete."
+ "\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"
+ "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)."
+ // 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)
+ ;
+ }
+
+ cmTypeMacro(cmFileCommand, cmCommand);
+
+protected:
+ bool HandleRename(std::vector<std::string> const& args);
+ bool HandleRemove(std::vector<std::string> const& args, bool recurse);
+ bool HandleWriteCommand(std::vector<std::string> const& args, bool append);
+ bool HandleReadCommand(std::vector<std::string> const& args);
+ bool HandleHashCommand(std::vector<std::string> const& args);
+ bool HandleStringsCommand(std::vector<std::string> const& args);
+ bool HandleGlobCommand(std::vector<std::string> const& args, bool recurse);
+ bool HandleMakeDirectoryCommand(std::vector<std::string> const& args);
+
+ bool HandleRelativePathCommand(std::vector<std::string> const& args);
+ bool HandleCMakePathCommand(std::vector<std::string> const& args,
+ bool nativePath);
+ bool HandleRPathChangeCommand(std::vector<std::string> const& args);
+ bool HandleRPathCheckCommand(std::vector<std::string> const& args);
+ bool HandleRPathRemoveCommand(std::vector<std::string> const& args);
+ bool HandleDifferentCommand(std::vector<std::string> const& args);
+
+ bool HandleCopyCommand(std::vector<std::string> const& args);
+ bool HandleInstallCommand(std::vector<std::string> const& args);
+ bool HandleDownloadCommand(std::vector<std::string> const& args);
+ bool HandleUploadCommand(std::vector<std::string> const& args);
+};
+
+
+#endif
diff --git a/Source/cmFileTimeComparison.cxx b/Source/cmFileTimeComparison.cxx
new file mode 100644
index 000000000..b1050d311
--- /dev/null
+++ b/Source/cmFileTimeComparison.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 "cmFileTimeComparison.h"
+
+// Use a hash table to avoid duplicate file time checks from disk.
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+# include <cmsys/hash_map.hxx>
+#endif
+
+// Use a platform-specific API to get file times efficiently.
+#if !defined(_WIN32) || defined(__CYGWIN__)
+# define cmFileTimeComparison_Type struct stat
+# include <ctype.h>
+# include <sys/stat.h>
+#else
+# define cmFileTimeComparison_Type FILETIME
+# include <windows.h>
+#endif
+
+//----------------------------------------------------------------------------
+class cmFileTimeComparisonInternal
+{
+public:
+ // Internal comparison method.
+ inline bool FileTimeCompare(const char* f1, const char* f2, int* result);
+
+ bool FileTimesDiffer(const char* f1, const char* f2);
+
+private:
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ // Use a hash table to efficiently map from file name to modification time.
+ class HashString
+ {
+ public:
+ size_t operator()(const cmStdString& s) const
+ {
+ return h(s.c_str());
+ }
+ cmsys::hash<const char*> h;
+ };
+ typedef cmsys::hash_map<cmStdString,
+ cmFileTimeComparison_Type, HashString> FileStatsMap;
+ FileStatsMap Files;
+#endif
+
+ // Internal methods to lookup and compare modification times.
+ inline bool Stat(const char* fname, cmFileTimeComparison_Type* st);
+ inline int Compare(cmFileTimeComparison_Type* st1,
+ cmFileTimeComparison_Type* st2);
+ inline bool TimesDiffer(cmFileTimeComparison_Type* st1,
+ cmFileTimeComparison_Type* st2);
+};
+
+//----------------------------------------------------------------------------
+bool cmFileTimeComparisonInternal::Stat(const char* fname,
+ cmFileTimeComparison_Type* st)
+{
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ // Use the stored time if available.
+ cmFileTimeComparisonInternal::FileStatsMap::iterator fit =
+ this->Files.find(fname);
+ if ( fit != this->Files.end() )
+ {
+ *st = fit->second;
+ return true;
+ }
+#endif
+
+#if !defined(_WIN32) || defined(__CYGWIN__)
+ // POSIX version. Use the stat function.
+ int res = ::stat(fname, st);
+ if ( res != 0 )
+ {
+ return false;
+ }
+#else
+ // Windows version. Get the modification time from extended file
+ // attributes.
+ WIN32_FILE_ATTRIBUTE_DATA fdata;
+ if(!GetFileAttributesEx(fname, GetFileExInfoStandard, &fdata))
+ {
+ return false;
+ }
+
+ // Copy the file time to the output location.
+ *st = fdata.ftLastWriteTime;
+#endif
+
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ // Store the time for future use.
+ this->Files[fname] = *st;
+#endif
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+cmFileTimeComparison::cmFileTimeComparison()
+{
+ this->Internals = new cmFileTimeComparisonInternal;
+}
+
+//----------------------------------------------------------------------------
+cmFileTimeComparison::~cmFileTimeComparison()
+{
+ delete this->Internals;
+}
+
+//----------------------------------------------------------------------------
+bool cmFileTimeComparison::FileTimeCompare(const char* f1,
+ const char* f2, int* result)
+{
+ return this->Internals->FileTimeCompare(f1, f2, result);
+}
+
+//----------------------------------------------------------------------------
+bool cmFileTimeComparison::FileTimesDiffer(const char* f1, const char* f2)
+{
+ return this->Internals->FileTimesDiffer(f1, f2);
+}
+
+//----------------------------------------------------------------------------
+int cmFileTimeComparisonInternal::Compare(cmFileTimeComparison_Type* s1,
+ cmFileTimeComparison_Type* s2)
+{
+#if !defined(_WIN32) || defined(__CYGWIN__)
+# if cmsys_STAT_HAS_ST_MTIM
+ // Compare using nanosecond resolution.
+ if(s1->st_mtim.tv_sec < s2->st_mtim.tv_sec)
+ {
+ return -1;
+ }
+ else if(s1->st_mtim.tv_sec > s2->st_mtim.tv_sec)
+ {
+ return 1;
+ }
+ else if(s1->st_mtim.tv_nsec < s2->st_mtim.tv_nsec)
+ {
+ return -1;
+ }
+ else if(s1->st_mtim.tv_nsec > s2->st_mtim.tv_nsec)
+ {
+ return 1;
+ }
+# else
+ // Compare using 1 second resolution.
+ if(s1->st_mtime < s2->st_mtime)
+ {
+ return -1;
+ }
+ else if(s1->st_mtime > s2->st_mtime)
+ {
+ return 1;
+ }
+# endif
+ // Files have the same time.
+ return 0;
+#else
+ // Compare using system-provided function.
+ return (int)CompareFileTime(s1, s2);
+#endif
+}
+
+//----------------------------------------------------------------------------
+bool cmFileTimeComparisonInternal::TimesDiffer(cmFileTimeComparison_Type* s1,
+ cmFileTimeComparison_Type* s2)
+{
+#if !defined(_WIN32) || defined(__CYGWIN__)
+# if cmsys_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;
+ long long t2 = s2->st_mtim.tv_sec * bil + s2->st_mtim.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)
+ {
+ return (s2->st_mtime - s1->st_mtime) >= 1;
+ }
+ else if(s1->st_mtime > s2->st_mtime)
+ {
+ return (s1->st_mtime - s2->st_mtime) >= 1;
+ }
+ else
+ {
+ return false;
+ }
+# endif
+#else
+ // Times are integers in units of 100ns.
+ LARGE_INTEGER t1;
+ LARGE_INTEGER t2;
+ t1.LowPart = s1->dwLowDateTime;
+ t1.HighPart = s1->dwHighDateTime;
+ t2.LowPart = s2->dwLowDateTime;
+ t2.HighPart = s2->dwHighDateTime;
+ if(t1.QuadPart < t2.QuadPart)
+ {
+ return (t2.QuadPart - t1.QuadPart) >= static_cast<LONGLONG>(10000000);
+ }
+ else if(t2.QuadPart < t1.QuadPart)
+ {
+ return (t1.QuadPart - t2.QuadPart) >= static_cast<LONGLONG>(10000000);
+ }
+ else
+ {
+ return false;
+ }
+#endif
+}
+
+//----------------------------------------------------------------------------
+bool cmFileTimeComparisonInternal::FileTimeCompare(const char* f1,
+ const char* f2,
+ int* result)
+{
+ // Get the modification time for each file.
+ cmFileTimeComparison_Type s1;
+ cmFileTimeComparison_Type s2;
+ if(this->Stat(f1, &s1) &&
+ this->Stat(f2, &s2))
+ {
+ // Compare the two modification times.
+ *result = this->Compare(&s1, &s2);
+ return true;
+ }
+ else
+ {
+ // No comparison available. Default to the same time.
+ *result = 0;
+ return false;
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmFileTimeComparisonInternal::FileTimesDiffer(const char* f1,
+ const char* f2)
+{
+ // Get the modification time for each file.
+ cmFileTimeComparison_Type s1;
+ cmFileTimeComparison_Type s2;
+ if(this->Stat(f1, &s1) &&
+ this->Stat(f2, &s2))
+ {
+ // Compare the two modification times.
+ return this->TimesDiffer(&s1, &s2);
+ }
+ else
+ {
+ // No comparison available. Default to different times.
+ return true;
+ }
+}
diff --git a/Source/cmFileTimeComparison.h b/Source/cmFileTimeComparison.h
new file mode 100644
index 000000000..f5de2f619
--- /dev/null
+++ b/Source/cmFileTimeComparison.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 cmFileTimeComparison_h
+#define cmFileTimeComparison_h
+
+#include "cmStandardIncludes.h"
+
+class cmFileTimeComparisonInternal;
+
+/** \class cmFileTimeComparison
+ * \brief Helper class for performing globbing searches.
+ *
+ * Finds all files that match a given globbing expression.
+ */
+class cmFileTimeComparison
+{
+public:
+ cmFileTimeComparison();
+ ~cmFileTimeComparison();
+
+ /**
+ * 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.
+ */
+ bool FileTimeCompare(const char* f1, const char* f2, int* result);
+
+ /**
+ * Compare file modification times. Return true unless both files
+ * exist and have modification times less than 1 second apart.
+ */
+ bool FileTimesDiffer(const char* f1, const char* f2);
+
+protected:
+
+ cmFileTimeComparisonInternal* Internals;
+};
+
+
+#endif
+
diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx
new file mode 100644
index 000000000..fb8bcf78d
--- /dev/null
+++ b/Source/cmFindBase.cxx
@@ -0,0 +1,598 @@
+/*============================================================================
+ 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 "cmFindBase.h"
+
+cmFindBase::cmFindBase()
+{
+ this->AlreadyInCache = false;
+ this->AlreadyInCacheWithoutMetaInfo = false;
+}
+
+//----------------------------------------------------------------------------
+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 )
+ {
+ this->SetError("called with incorrect number of arguments");
+ 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();
+ std::vector<std::string> args;
+ bool foundDoc = false;
+ for(unsigned int j = 0; j < size; ++j)
+ {
+ if(foundDoc || argsIn[j] != "DOC" )
+ {
+ if(argsIn[j] == "ENV")
+ {
+ if(j+1 < size)
+ {
+ j++;
+ cmSystemTools::GetPath(args, argsIn[j].c_str());
+ }
+ }
+ else
+ {
+ args.push_back(argsIn[j]);
+ }
+ }
+ else
+ {
+ if(j+1 < size)
+ {
+ foundDoc = true;
+ this->VariableDocumentation = argsIn[j+1];
+ j++;
+ if(j >= size)
+ {
+ break;
+ }
+ }
+ }
+ }
+ if(args.size() < 2 )
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+ this->VariableName = args[0];
+ if(this->CheckForVariableInCache())
+ {
+ this->AlreadyInCache = true;
+ return true;
+ }
+ this->AlreadyInCache = false;
+
+ // Find the current root path mode.
+ this->SelectDefaultRootPathMode();
+
+ // Find the current bundle/framework search policy.
+ this->SelectDefaultMacMode();
+
+ bool newStyle = false;
+ enum Doing { DoingNone, DoingNames, DoingPaths, DoingPathSuffixes,
+ DoingHints };
+ Doing doing = DoingNames; // assume it starts with a name
+ for (unsigned int j = 1; j < args.size(); ++j)
+ {
+ if(args[j] == "NAMES")
+ {
+ doing = DoingNames;
+ newStyle = true;
+ }
+ else if (args[j] == "PATHS")
+ {
+ doing = DoingPaths;
+ newStyle = true;
+ }
+ else if (args[j] == "HINTS")
+ {
+ doing = DoingHints;
+ newStyle = true;
+ }
+ else if (args[j] == "PATH_SUFFIXES")
+ {
+ doing = DoingPathSuffixes;
+ compatibility = false;
+ newStyle = true;
+ }
+ else if (args[j] == "NO_SYSTEM_PATH")
+ {
+ doing = DoingNone;
+ this->NoDefaultPath = true;
+ }
+ 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.
+ }
+ else if(doing == DoingNames)
+ {
+ this->Names.push_back(args[j]);
+ }
+ else if(doing == DoingPaths)
+ {
+ this->AddUserPath(args[j], this->UserPaths);
+ }
+ else if(doing == DoingHints)
+ {
+ this->AddUserPath(args[j], this->UserHints);
+ }
+ else if(doing == DoingPathSuffixes)
+ {
+ this->AddPathSuffix(args[j]);
+ }
+ }
+
+ // 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)
+ {
+ this->VariableDocumentation = "Where can ";
+ if(this->Names.size() == 0)
+ {
+ this->VariableDocumentation += "the (unknown) library be found";
+ }
+ else if(this->Names.size() == 1)
+ {
+ this->VariableDocumentation += "the "
+ + this->Names[0] + " library be found";
+ }
+ 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 += " or "
+ + this->Names[this->Names.size() - 1] + " libraries be found";
+ }
+ }
+
+ // look for old style
+ // FIND_*(VAR name path1 path2 ...)
+ if(!newStyle)
+ {
+ // All the short-hand arguments have been recorded as names.
+ 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->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;
+}
+
+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")
+ {
+ 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] != '/')
+ {
+ dir += "/";
+ }
+ if(subdir == "lib")
+ {
+ const char* arch =
+ this->Makefile->GetDefinition("CMAKE_LIBRARY_ARCHITECTURE");
+ if(arch && *arch)
+ {
+ this->AddPathInternal(dir+"lib/"+arch, pathType);
+ }
+ }
+ std::string add = dir + subdir;
+ if(add != "/")
+ {
+ this->AddPathInternal(add, pathType);
+ }
+ if (subdir == "bin")
+ {
+ this->AddPathInternal(dir+"sbin", pathType);
+ }
+ if(!subdir.empty() && *it != "/")
+ {
+ this->AddPathInternal(*it, pathType);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmFindBase::AddCMakePrefixPath(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);
+ this->AddPrefixPaths(tmp, CMakePath);
+ }
+}
+
+//----------------------------------------------------------------------------
+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);
+}
+
+//----------------------------------------------------------------------------
+void cmFindBase::AddCMakeEnvironmentPath()
+{
+ if(!this->NoCMakeEnvironmentPath && !this->NoDefaultPath)
+ {
+ // 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");
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmFindBase::AddCMakeVariablePath()
+{
+ if(!this->NoCMakePath && !this->NoDefaultPath)
+ {
+ // 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");
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmFindBase::AddSystemEnvironmentPath()
+{
+ if(!this->NoSystemEnvironmentPath && !this->NoDefaultPath)
+ {
+ // Add LIB or INCLUDE
+ if(!this->EnvironmentPath.empty())
+ {
+ this->AddEnvPath(this->EnvironmentPath.c_str());
+ }
+ // Add PATH
+ this->AddEnvPath(0);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmFindBase::AddCMakeSystemVariablePath()
+{
+ 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());
+
+ if(this->CMakePathName == "PROGRAM")
+ {
+ this->AddCMakePath("CMAKE_SYSTEM_APPBUNDLE_PATH");
+ }
+ else
+ {
+ this->AddCMakePath("CMAKE_SYSTEM_FRAMEWORK_PATH");
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmFindBase::AddUserHintsPath()
+{
+ this->AddPathsInternal(this->UserHints, CMakePath);
+}
+
+//----------------------------------------------------------------------------
+void cmFindBase::AddUserGuessPath()
+{
+ this->AddPathsInternal(this->UserPaths, CMakePath);
+}
+
+//----------------------------------------------------------------------------
+void cmFindBase::AddPathSuffixes()
+{
+ 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)
+ {
+ 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);
+ }
+}
+
+void cmFindBase::PrintFindStuff()
+{
+ std::cerr << "SearchFrameworkLast: " << this->SearchFrameworkLast << "\n";
+ std::cerr << "SearchFrameworkOnly: " << this->SearchFrameworkOnly << "\n";
+ std::cerr << "SearchFrameworkFirst: " << this->SearchFrameworkFirst << "\n";
+ std::cerr << "SearchAppBundleLast: " << this->SearchAppBundleLast << "\n";
+ std::cerr << "SearchAppBundleOnly: " << this->SearchAppBundleOnly << "\n";
+ std::cerr << "SearchAppBundleFirst: " << this->SearchAppBundleFirst << "\n";
+ std::cerr << "VariableName " << this->VariableName << "\n";
+ std::cerr << "VariableDocumentation "
+ << this->VariableDocumentation << "\n";
+ std::cerr << "NoDefaultPath " << this->NoDefaultPath << "\n";
+ std::cerr << "NoCMakeEnvironmentPath "
+ << this->NoCMakeEnvironmentPath << "\n";
+ std::cerr << "NoCMakePath " << this->NoCMakePath << "\n";
+ std::cerr << "NoSystemEnvironmentPath "
+ << this->NoSystemEnvironmentPath << "\n";
+ 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 << "\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 << "SearchPaths\n";
+ for(unsigned int i =0; i < this->SearchPaths.size(); ++i)
+ {
+ std::cerr << "[" << this->SearchPaths[i] << "]\n";
+ }
+}
+
+bool cmFindBase::CheckForVariableInCache()
+{
+ if(const char* cacheValue =
+ this->Makefile->GetDefinition(this->VariableName.c_str()))
+ {
+ cmCacheManager::CacheIterator it =
+ this->Makefile->GetCacheManager()->
+ GetCacheIterator(this->VariableName.c_str());
+ bool found = !cmSystemTools::IsNOTFOUND(cacheValue);
+ bool cached = !it.IsAtEnd();
+ if(found)
+ {
+ // If the user specifies the entry on the command line without a
+ // type we should add the type and docstring but keep the
+ // original value. Tell the subclass implementations to do
+ // this.
+ if(cached && it.GetType() == cmCacheManager::UNINITIALIZED)
+ {
+ this->AlreadyInCacheWithoutMetaInfo = true;
+ }
+ return true;
+ }
+ else if(cached)
+ {
+ const char* hs = it.GetProperty("HELPSTRING");
+ this->VariableDocumentation = hs?hs:"(none)";
+ }
+ }
+ return false;
+}
diff --git a/Source/cmFindBase.h b/Source/cmFindBase.h
new file mode 100644
index 000000000..37ab2ecd2
--- /dev/null
+++ b/Source/cmFindBase.h
@@ -0,0 +1,76 @@
+/*============================================================================
+ 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 cmFindBase_h
+#define cmFindBase_h
+
+#include "cmFindCommon.h"
+
+/** \class cmFindBase
+ * \brief Base class for most FIND_XXX commands.
+ *
+ * cmFindBase is a parent class for cmFindProgramCommand, cmFindPathCommand,
+ * and cmFindLibraryCommand, cmFindFileCommand
+ */
+class cmFindBase : public cmFindCommon
+{
+public:
+ cmFindBase();
+ /**
+ * This is called when the command is first encountered in
+ * the CMakeLists.txt file.
+ */
+ 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::vector<std::string> Names;
+
+ // CMAKE_*_PATH CMAKE_SYSTEM_*_PATH FRAMEWORK|LIBRARY|INCLUDE|PROGRAM
+ cmStdString 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);
+};
+
+
+
+#endif
diff --git a/Source/cmFindCommon.cxx b/Source/cmFindCommon.cxx
new file mode 100644
index 000000000..b44864e13
--- /dev/null
+++ b/Source/cmFindCommon.cxx
@@ -0,0 +1,505 @@
+/*============================================================================
+ 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 "cmFindCommon.h"
+
+//----------------------------------------------------------------------------
+cmFindCommon::cmFindCommon()
+{
+ this->FindRootPathMode = RootPathModeBoth;
+ this->NoDefaultPath = false;
+ this->NoCMakePath = false;
+ this->NoCMakeEnvironmentPath = false;
+ this->NoSystemEnvironmentPath = false;
+ this->NoCMakeSystemPath = false;
+
+ // OS X Bundle and Framework search policy. The default is to
+ // search frameworks first on apple.
+#if defined(__APPLE__)
+ this->SearchFrameworkFirst = true;
+ this->SearchAppBundleFirst = true;
+#else
+ this->SearchFrameworkFirst = false;
+ this->SearchAppBundleFirst = false;
+#endif
+ this->SearchFrameworkOnly = false;
+ this->SearchFrameworkLast = false;
+ this->SearchAppBundleOnly = false;
+ this->SearchAppBundleLast = false;
+}
+
+//----------------------------------------------------------------------------
+void cmFindCommon::GenerateDocumentation()
+{
+ // 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::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());
+ if (rootPathMode=="NEVER")
+ {
+ this->FindRootPathMode = RootPathModeNoRootPath;
+ }
+ else if (rootPathMode=="ONLY")
+ {
+ this->FindRootPathMode = RootPathModeOnlyRootPath;
+ }
+ else if (rootPathMode=="BOTH")
+ {
+ this->FindRootPathMode = RootPathModeBoth;
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmFindCommon::SelectDefaultMacMode()
+{
+ std::string ff = this->Makefile->GetSafeDefinition("CMAKE_FIND_FRAMEWORK");
+ if(ff == "NEVER")
+ {
+ this->SearchFrameworkLast = false;
+ this->SearchFrameworkFirst = false;
+ this->SearchFrameworkOnly = false;
+ }
+ else if(ff == "ONLY")
+ {
+ this->SearchFrameworkLast = false;
+ this->SearchFrameworkFirst = false;
+ this->SearchFrameworkOnly = true;
+ }
+ else if(ff == "FIRST")
+ {
+ this->SearchFrameworkLast = false;
+ this->SearchFrameworkFirst = true;
+ this->SearchFrameworkOnly = false;
+ }
+ else if(ff == "LAST")
+ {
+ this->SearchFrameworkLast = true;
+ this->SearchFrameworkFirst = false;
+ this->SearchFrameworkOnly = false;
+ }
+
+ std::string fab = this->Makefile->GetSafeDefinition("CMAKE_FIND_APPBUNDLE");
+ if(fab == "NEVER")
+ {
+ this->SearchAppBundleLast = false;
+ this->SearchAppBundleFirst = false;
+ this->SearchAppBundleOnly = false;
+ }
+ else if(fab == "ONLY")
+ {
+ this->SearchAppBundleLast = false;
+ this->SearchAppBundleFirst = false;
+ this->SearchAppBundleOnly = true;
+ }
+ else if(fab == "FIRST")
+ {
+ this->SearchAppBundleLast = false;
+ this->SearchAppBundleFirst = true;
+ this->SearchAppBundleOnly = false;
+ }
+ else if(fab == "LAST")
+ {
+ this->SearchAppBundleLast = true;
+ this->SearchAppBundleFirst = false;
+ this->SearchAppBundleOnly = false;
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmFindCommon::RerootPaths(std::vector<std::string>& paths)
+{
+#if 0
+ for(std::vector<std::string>::const_iterator i = paths.begin();
+ i != paths.end(); ++i)
+ {
+ fprintf(stderr, "[%s]\n", i->c_str());
+ }
+#endif
+
+ // Short-circuit if there is nothing to do.
+ if(this->FindRootPathMode == RootPathModeNoRootPath)
+ {
+ return;
+ }
+ const char* rootPath =
+ this->Makefile->GetDefinition("CMAKE_FIND_ROOT_PATH");
+ if((rootPath == 0) || (strlen(rootPath) == 0))
+ {
+ return;
+ }
+
+ // Construct the list of path roots with no trailing slashes.
+ std::vector<std::string> roots;
+ cmSystemTools::ExpandListArgument(rootPath, roots);
+ for(std::vector<std::string>::iterator ri = roots.begin();
+ ri != roots.end(); ++ri)
+ {
+ cmSystemTools::ConvertToUnixSlashes(*ri);
+ }
+
+ // Copy the original set of unrooted paths.
+ std::vector<std::string> unrootedPaths = paths;
+ paths.clear();
+
+ for(std::vector<std::string>::const_iterator ri = roots.begin();
+ ri != roots.end(); ++ri)
+ {
+ for(std::vector<std::string>::const_iterator ui = unrootedPaths.begin();
+ ui != unrootedPaths.end(); ++ui)
+ {
+ // Place the unrooted path under the current root if it is not
+ // 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()))
+ {
+ rootedDir = *ui;
+ }
+ else if(!ui->empty() && (*ui)[0] != '~')
+ {
+ // Start with the new root.
+ rootedDir = *ri;
+ rootedDir += "/";
+
+ // Append the original path with its old root removed.
+ rootedDir += cmSystemTools::SplitPathRootComponent(ui->c_str());
+ }
+
+ // Store the new path.
+ paths.push_back(rootedDir);
+ }
+ }
+
+ // If searching both rooted and unrooted paths add the original
+ // paths again.
+ if(this->FindRootPathMode == RootPathModeBoth)
+ {
+ paths.insert(paths.end(), unrootedPaths.begin(), unrootedPaths.end());
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmFindCommon::FilterPaths(std::vector<std::string>& paths,
+ const std::set<std::string>& ignore)
+{
+ // 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)
+ {
+ if (ignore.count(*pi) == 0)
+ {
+ paths.push_back(*pi);
+ }
+ }
+}
+
+
+//----------------------------------------------------------------------------
+void cmFindCommon::GetIgnoredPaths(std::vector<std::string>& ignore)
+{
+ // null-terminated list of paths.
+ static const char *paths[] =
+ { "CMAKE_SYSTEM_IGNORE_PATH", "CMAKE_IGNORE_PATH", 0 };
+
+ // Construct the list of path roots with no trailing slashes.
+ for(const char **pathName = paths; *pathName; ++pathName)
+ {
+ // Get the list of paths to ignore from the variable.
+ const char* ignorePath = this->Makefile->GetDefinition(*pathName);
+ if((ignorePath == 0) || (strlen(ignorePath) == 0))
+ {
+ continue;
+ }
+
+ cmSystemTools::ExpandListArgument(ignorePath, ignore);
+ }
+
+ for(std::vector<std::string>::iterator i = ignore.begin();
+ i != ignore.end(); ++i)
+ {
+ cmSystemTools::ConvertToUnixSlashes(*i);
+ }
+}
+
+
+//----------------------------------------------------------------------------
+void cmFindCommon::GetIgnoredPaths(std::set<std::string>& ignore)
+{
+ std::vector<std::string> ignoreVec;
+ GetIgnoredPaths(ignoreVec);
+ ignore.insert(ignoreVec.begin(), ignoreVec.end());
+}
+
+
+
+//----------------------------------------------------------------------------
+bool cmFindCommon::CheckCommonArgument(std::string const& arg)
+{
+ if(arg == "NO_DEFAULT_PATH")
+ {
+ this->NoDefaultPath = true;
+ }
+ else if(arg == "NO_CMAKE_ENVIRONMENT_PATH")
+ {
+ this->NoCMakeEnvironmentPath = true;
+ }
+ else if(arg == "NO_CMAKE_PATH")
+ {
+ this->NoCMakePath = true;
+ }
+ else if(arg == "NO_SYSTEM_ENVIRONMENT_PATH")
+ {
+ this->NoSystemEnvironmentPath = true;
+ }
+ else if(arg == "NO_CMAKE_SYSTEM_PATH")
+ {
+ this->NoCMakeSystemPath = true;
+ }
+ else if(arg == "NO_CMAKE_FIND_ROOT_PATH")
+ {
+ this->FindRootPathMode = RootPathModeNoRootPath;
+ }
+ else if(arg == "ONLY_CMAKE_FIND_ROOT_PATH")
+ {
+ this->FindRootPathMode = RootPathModeOnlyRootPath;
+ }
+ else if(arg == "CMAKE_FIND_ROOT_PATH_BOTH")
+ {
+ this->FindRootPathMode = RootPathModeBoth;
+ }
+ else
+ {
+ // The argument is not one of the above.
+ return false;
+ }
+
+ // The argument is one of the above.
+ return true;
+}
+
+//----------------------------------------------------------------------------
+void cmFindCommon::AddPathSuffix(std::string const& arg)
+{
+ std::string suffix = arg;
+
+ // Strip leading and trailing slashes.
+ if(suffix.empty())
+ {
+ return;
+ }
+ if(suffix[0] == '/')
+ {
+ suffix = suffix.substr(1, suffix.npos);
+ }
+ if(suffix.empty())
+ {
+ return;
+ }
+ if(suffix[suffix.size()-1] == '/')
+ {
+ suffix = suffix.substr(0, suffix.size()-1);
+ }
+ if(suffix.empty())
+ {
+ return;
+ }
+
+ // Store the suffix.
+ this->SearchPathSuffixes.push_back(suffix);
+}
+
+//----------------------------------------------------------------------------
+void cmFindCommon::AddUserPath(std::string const& p,
+ std::vector<std::string>& paths)
+{
+ // 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")
+ {
+ expanded = p;
+ cmSystemTools::ExpandRegistryValues(expanded, other_view);
+ cmSystemTools::GlobDirs(expanded.c_str(), paths);
+ }
+}
+
+//----------------------------------------------------------------------------
+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)
+{
+ if(in_path.empty())
+ {
+ return;
+ }
+
+ // Select the base path with which to interpret relative paths.
+ const char* relbase = 0;
+ if(pathType == CMakePath)
+ {
+ relbase = this->Makefile->GetCurrentDirectory();
+ }
+
+ // 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);
+
+ // 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 += "/";
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmFindCommon::SetMakefile(cmMakefile* makefile)
+{
+ cmCommand::SetMakefile(makefile);
+
+ // If we are building for Apple (OSX or also iphone), make sure
+ // that frameworks and bundles are searched first.
+ if(this->Makefile->IsOn("APPLE"))
+ {
+ this->SearchFrameworkFirst = true;
+ this->SearchAppBundleFirst = true;
+ }
+}
diff --git a/Source/cmFindCommon.h b/Source/cmFindCommon.h
new file mode 100644
index 000000000..542805faf
--- /dev/null
+++ b/Source/cmFindCommon.h
@@ -0,0 +1,101 @@
+/*============================================================================
+ 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 cmFindCommon_h
+#define cmFindCommon_h
+
+#include "cmCommand.h"
+
+/** \class cmFindCommon
+ * \brief Base class for FIND_XXX implementations.
+ *
+ * cmFindCommon is a parent class for cmFindBase,
+ * cmFindProgramCommand, cmFindPathCommand, cmFindLibraryCommand,
+ * cmFindFileCommand, and cmFindPackageCommand.
+ */
+class cmFindCommon : public cmCommand
+{
+public:
+ cmFindCommon();
+ ~cmFindCommon();
+ cmTypeMacro(cmFindCommon, cmCommand);
+
+protected:
+
+ enum RootPathMode { RootPathModeBoth,
+ RootPathModeOnlyRootPath,
+ RootPathModeNoRootPath };
+
+ enum PathType { FullPath, CMakePath, EnvPath };
+
+ /** Place a set of search paths under the search roots. */
+ void RerootPaths(std::vector<std::string>& paths);
+
+ /** Get ignored paths from CMAKE_[SYSTEM_]IGNORE_path variables. */
+ void GetIgnoredPaths(std::vector<std::string>& ignore);
+ 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);
+
+ /** Compute final search path list (reroot + trailing slash). */
+ void ComputeFinalPaths();
+
+ /** Compute the current default root path mode. */
+ void SelectDefaultRootPathMode();
+
+ /** Compute the current default bundle/framework search policy. */
+ void SelectDefaultMacMode();
+
+ virtual void GenerateDocumentation();
+
+ cmStdString 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;
+ bool NoCMakePath;
+ bool NoCMakeEnvironmentPath;
+ bool NoSystemEnvironmentPath;
+ 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;
+
+ bool SearchFrameworkFirst;
+ bool SearchFrameworkOnly;
+ bool SearchFrameworkLast;
+
+ bool SearchAppBundleFirst;
+ bool SearchAppBundleOnly;
+ bool SearchAppBundleLast;
+};
+
+#endif
diff --git a/Source/cmFindFileCommand.cxx b/Source/cmFindFileCommand.cxx
new file mode 100644
index 000000000..fa66fa11d
--- /dev/null
+++ b/Source/cmFindFileCommand.cxx
@@ -0,0 +1,30 @@
+/*============================================================================
+ 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 "cmFindFileCommand.h"
+#include "cmSystemTools.h"
+
+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
new file mode 100644
index 000000000..7d349d33c
--- /dev/null
+++ b/Source/cmFindFileCommand.h
@@ -0,0 +1,53 @@
+/*============================================================================
+ 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 cmFindFileCommand_h
+#define cmFindFileCommand_h
+
+#include "cmFindPathCommand.h"
+
+/** \class cmFindFileCommand
+ * \brief Define a command to search for an executable program.
+ *
+ * cmFindFileCommand is used to define a CMake variable
+ * that specifies an executable program. The command searches
+ * in the current path (e.g., PATH environment variable) for
+ * an executable that matches one of the supplied names.
+ */
+class cmFindFileCommand : public cmFindPathCommand
+{
+public:
+ cmFindFileCommand();
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ 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.";
+ }
+
+ cmTypeMacro(cmFindFileCommand, cmFindPathCommand);
+protected:
+ virtual void GenerateDocumentation();
+};
+
+
+
+#endif
diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx
new file mode 100644
index 000000000..6cdbbf2dc
--- /dev/null
+++ b/Source/cmFindLibraryCommand.cxx
@@ -0,0 +1,527 @@
+/*============================================================================
+ 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 "cmFindLibraryCommand.h"
+#include "cmCacheManager.h"
+#include <cmsys/Directory.hxx>
+#include <cmsys/stl/algorithm>
+
+cmFindLibraryCommand::cmFindLibraryCommand()
+{
+ this->EnvironmentPath = "LIB";
+}
+
+//----------------------------------------------------------------------------
+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,
+ "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"
+ "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 &)
+{
+ this->VariableDocumentation = "Path to a library.";
+ this->CMakePathName = "LIBRARY";
+ if(!this->ParseArguments(argsIn))
+ {
+ return false;
+ }
+ if(this->AlreadyInCache)
+ {
+ // If the user specifies the entry on the command line without a
+ // type we should add the type and docstring but keep the original
+ // value.
+ if(this->AlreadyInCacheWithoutMetaInfo)
+ {
+ this->Makefile->AddCacheDefinition(this->VariableName.c_str(), "",
+ this->VariableDocumentation.c_str(),
+ cmCacheManager::FILEPATH);
+ }
+ return true;
+ }
+
+ if(const char* abi_name =
+ this->Makefile->GetDefinition("CMAKE_INTERNAL_PLATFORM_ABI"))
+ {
+ std::string abi = abi_name;
+ if(abi.find("ELF N32") != abi.npos)
+ {
+ // Convert lib to lib32.
+ this->AddArchitecturePaths("32");
+ }
+ }
+
+ if(this->Makefile->GetCMakeInstance()
+ ->GetPropertyAsBool("FIND_LIBRARY_USE_LIB64_PATHS"))
+ {
+ // add special 64 bit paths if this is a 64 bit compile.
+ this->AddLib64Paths();
+ }
+
+ std::string library = this->FindLibrary();
+ if(library != "")
+ {
+ // Save the value in the cache
+ this->Makefile->AddCacheDefinition(this->VariableName.c_str(),
+ library.c_str(),
+ this->VariableDocumentation.c_str(),
+ cmCacheManager::FILEPATH);
+ return true;
+ }
+ std::string notfound = this->VariableName + "-NOTFOUND";
+ this->Makefile->AddCacheDefinition(this->VariableName.c_str(),
+ notfound.c_str(),
+ this->VariableDocumentation.c_str(),
+ cmCacheManager::FILEPATH);
+ return true;
+}
+
+//----------------------------------------------------------------------------
+void cmFindLibraryCommand::AddArchitecturePaths(const char* suffix)
+{
+ std::vector<std::string> newPaths;
+ bool found = false;
+ std::string subpath = "lib";
+ subpath += suffix;
+ subpath += "/";
+ for(std::vector<std::string>::iterator i = this->SearchPaths.begin();
+ i != this->SearchPaths.end(); ++i)
+ {
+ // Try replacing lib/ with lib<suffix>/
+ std::string s = *i;
+ cmSystemTools::ReplaceString(s, "lib/", subpath.c_str());
+ if((s != *i) && cmSystemTools::FileIsDirectory(s.c_str()))
+ {
+ found = true;
+ newPaths.push_back(s);
+ }
+
+ // Now look for lib<suffix>
+ s = *i;
+ s += suffix;
+ if(cmSystemTools::FileIsDirectory(s.c_str()))
+ {
+ found = true;
+ newPaths.push_back(s);
+ }
+ // now add the original unchanged path
+ if(cmSystemTools::FileIsDirectory(i->c_str()))
+ {
+ newPaths.push_back(*i);
+ }
+ }
+
+ // If any new paths were found replace the original set.
+ if(found)
+ {
+ this->SearchPaths = newPaths;
+ }
+}
+
+void cmFindLibraryCommand::AddLib64Paths()
+{
+ std::string voidsize =
+ this->Makefile->GetSafeDefinition("CMAKE_SIZEOF_VOID_P");
+ int size = atoi(voidsize.c_str());
+ if(size != 8)
+ {
+ return;
+ }
+ std::vector<std::string> path64;
+ bool found64 = false;
+ for(std::vector<std::string>::iterator i = this->SearchPaths.begin();
+ i != this->SearchPaths.end(); ++i)
+ {
+ std::string s = *i;
+ std::string s2 = *i;
+ cmSystemTools::ReplaceString(s, "lib/", "lib64/");
+ // try to replace lib with lib64 and see if it is there,
+ // then prepend it to the path
+ // Note that all paths have trailing slashes.
+ if((s != *i) && cmSystemTools::FileIsDirectory(s.c_str()))
+ {
+ path64.push_back(s);
+ found64 = true;
+ }
+ // now just add a 64 to the path name and if it is there,
+ // add it to the path
+ s2 += "64/";
+ if(cmSystemTools::FileIsDirectory(s2.c_str()))
+ {
+ found64 = true;
+ path64.push_back(s2);
+ }
+ // now add the original unchanged path
+ if(cmSystemTools::FileIsDirectory(i->c_str()))
+ {
+ path64.push_back(*i);
+ }
+ }
+ // now replace the SearchPaths with the 64 bit converted path
+ // if any 64 bit paths were discovered
+ if(found64)
+ {
+ this->SearchPaths = path64;
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string cmFindLibraryCommand::FindLibrary()
+{
+ std::string library;
+ if(this->SearchFrameworkFirst || this->SearchFrameworkOnly)
+ {
+ library = this->FindFrameworkLibrary();
+ }
+ if(library.empty() && !this->SearchFrameworkOnly)
+ {
+ library = this->FindNormalLibrary();
+ }
+ if(library.empty() && this->SearchFrameworkLast)
+ {
+ library = this->FindFrameworkLibrary();
+ }
+ return library;
+}
+
+//----------------------------------------------------------------------------
+struct cmFindLibraryHelper
+{
+ cmFindLibraryHelper(cmMakefile* mf);
+
+ // Context information.
+ cmMakefile* Makefile;
+ cmGlobalGenerator* GG;
+
+ // List of valid prefixes and suffixes.
+ std::vector<std::string> Prefixes;
+ std::vector<std::string> Suffixes;
+ std::string PrefixRegexStr;
+ std::string SuffixRegexStr;
+
+ // Keep track of the best library file found so far.
+ typedef std::vector<std::string>::size_type size_type;
+ std::string BestPath;
+ size_type BestPrefix;
+ size_type BestSuffix;
+
+ // Support for OpenBSD shared library naming: lib<name>.so.<major>.<minor>
+ bool OpenBSD;
+ unsigned int BestMajor;
+ unsigned int BestMinor;
+
+ // Current name under consideration.
+ cmsys::RegularExpression NameRegex;
+ bool TryRawName;
+ std::string RawName;
+
+ // Current full path under consideration.
+ std::string TestPath;
+
+ void RegexFromLiteral(std::string& out, std::string const& in);
+ 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(),
+ prefix) - this->Prefixes.begin();
+ }
+ size_type GetSuffixIndex(std::string const& suffix)
+ {
+ return cmsys_stl::find(this->Suffixes.begin(), this->Suffixes.end(),
+ suffix) - this->Suffixes.begin();
+ }
+ bool HasValidSuffix(std::string const& name);
+ void SetName(std::string const& name);
+ bool CheckDirectory(std::string const& path);
+};
+
+//----------------------------------------------------------------------------
+cmFindLibraryHelper::cmFindLibraryHelper(cmMakefile* mf):
+ Makefile(mf)
+{
+ this->GG = this->Makefile->GetLocalGenerator()->GetGlobalGenerator();
+
+ // Collect the list of library name prefixes/suffixes to try.
+ const char* prefixes_list =
+ this->Makefile->GetRequiredDefinition("CMAKE_FIND_LIBRARY_PREFIXES");
+ const char* suffixes_list =
+ this->Makefile->GetRequiredDefinition("CMAKE_FIND_LIBRARY_SUFFIXES");
+ cmSystemTools::ExpandListArgument(prefixes_list, this->Prefixes, true);
+ cmSystemTools::ExpandListArgument(suffixes_list, this->Suffixes, true);
+ this->RegexFromList(this->PrefixRegexStr, this->Prefixes);
+ this->RegexFromList(this->SuffixRegexStr, this->Suffixes);
+
+ // Check whether to use OpenBSD-style library version comparisons.
+ this->OpenBSD =
+ this->Makefile->GetCMakeInstance()
+ ->GetPropertyAsBool("FIND_LIBRARY_USE_OPENBSD_VERSIONING");
+
+ this->TryRawName = false;
+
+ // No library file has yet been found.
+ this->BestPrefix = this->Prefixes.size();
+ this->BestSuffix = this->Suffixes.size();
+ this->BestMajor = 0;
+ this->BestMinor = 0;
+}
+
+//----------------------------------------------------------------------------
+void cmFindLibraryHelper::RegexFromLiteral(std::string& out,
+ std::string const& in)
+{
+ for(std::string::const_iterator ci = in.begin(); ci != in.end(); ++ci)
+ {
+ char ch = *ci;
+ if(ch == '[' || ch == ']' || ch == '(' || ch == ')' || ch == '\\' ||
+ ch == '.' || ch == '*' || ch == '+' || ch == '?' || ch == '-' ||
+ ch == '^' || ch == '$')
+ {
+ out += "\\";
+ }
+#if defined(_WIN32) || defined(__APPLE__)
+ out += tolower(ch);
+#else
+ out += ch;
+#endif
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmFindLibraryHelper::RegexFromList(std::string& out,
+ std::vector<std::string> const& in)
+{
+ // Surround the list in parens so the '|' does not apply to anything
+ // else and the result can be checked after matching.
+ out += "(";
+ const char* sep = "";
+ for(std::vector<std::string>::const_iterator si = in.begin();
+ si != in.end(); ++si)
+ {
+ // Separate from previous item.
+ out += sep;
+ sep = "|";
+
+ // Append this item.
+ this->RegexFromLiteral(out, *si);
+ }
+ out += ")";
+}
+
+//----------------------------------------------------------------------------
+bool cmFindLibraryHelper::HasValidSuffix(std::string const& name)
+{
+ for(std::vector<std::string>::const_iterator si = this->Suffixes.begin();
+ si != this->Suffixes.end(); ++si)
+ {
+ std::string suffix = *si;
+ if(name.length() <= suffix.length())
+ {
+ continue;
+ }
+ // Check if the given name ends in a valid library suffix.
+ if(name.substr(name.size()-suffix.length()) == suffix)
+ {
+ return true;
+ }
+ // Check if a valid library suffix is somewhere in the name,
+ // this may happen e.g. for versioned shared libraries: libfoo.so.2
+ suffix += ".";
+ if(name.find(suffix) != name.npos)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+void cmFindLibraryHelper::SetName(std::string const& name)
+{
+ // Consider checking the raw name too.
+ this->TryRawName = this->HasValidSuffix(name);
+ this->RawName = name;
+
+ // Build a regular expression to match library names.
+ std::string regex = "^";
+ regex += this->PrefixRegexStr;
+ this->RegexFromLiteral(regex, name);
+ regex += this->SuffixRegexStr;
+ if(this->OpenBSD)
+ {
+ regex += "(\\.[0-9]+\\.[0-9]+)?";
+ }
+ regex += "$";
+ this->NameRegex.compile(regex.c_str());
+}
+
+//----------------------------------------------------------------------------
+bool cmFindLibraryHelper::CheckDirectory(std::string const& path)
+{
+ // If the original library name provided by the user matches one of
+ // the suffixes, try it first. This allows users to search
+ // specifically for a static library on some platforms (on MS tools
+ // one cannot tell just from the library name whether it is a static
+ // library or an import library).
+ if(this->TryRawName)
+ {
+ this->TestPath = path;
+ this->TestPath += this->RawName;
+ if(cmSystemTools::FileExists(this->TestPath.c_str(), true))
+ {
+ this->BestPath =
+ cmSystemTools::CollapseFullPath(this->TestPath.c_str());
+ cmSystemTools::ConvertToUnixSlashes(this->BestPath);
+ return true;
+ }
+ }
+
+ // 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();
+ fi != files.end(); ++fi)
+ {
+ std::string const& origName = *fi;
+#if defined(_WIN32) || defined(__APPLE__)
+ std::string testName = cmSystemTools::LowerCase(origName);
+#else
+ std::string const& testName = origName;
+#endif
+ if(this->NameRegex.find(testName))
+ {
+ this->TestPath = path;
+ this->TestPath += origName;
+ if(!cmSystemTools::FileIsDirectory(this->TestPath.c_str()))
+ {
+ // This is a matching file. Check if it is better than the
+ // best name found so far. Earlier prefixes are preferred,
+ // followed by earlier suffixes. For OpenBSD, shared library
+ // version extensions are compared.
+ size_type prefix = this->GetPrefixIndex(this->NameRegex.match(1));
+ size_type suffix = this->GetSuffixIndex(this->NameRegex.match(2));
+ unsigned int major = 0;
+ unsigned int minor = 0;
+ if(this->OpenBSD)
+ {
+ sscanf(this->NameRegex.match(3).c_str(), ".%u.%u", &major, &minor);
+ }
+ if(this->BestPath.empty() || prefix < this->BestPrefix ||
+ (prefix == this->BestPrefix && suffix < this->BestSuffix) ||
+ (prefix == this->BestPrefix && suffix == this->BestSuffix &&
+ (major > this->BestMajor ||
+ (major == this->BestMajor && minor > this->BestMinor))))
+ {
+ this->BestPath = this->TestPath;
+ this->BestPrefix = prefix;
+ this->BestSuffix = suffix;
+ this->BestMajor = major;
+ this->BestMinor = minor;
+ }
+ }
+ }
+ }
+
+ // Use the best candidate found in this directory, if any.
+ return !this->BestPath.empty();
+}
+
+//----------------------------------------------------------------------------
+std::string cmFindLibraryCommand::FindNormalLibrary()
+{
+ // Search the entire path for each name.
+ cmFindLibraryHelper helper(this->Makefile);
+ for(std::vector<std::string>::const_iterator ni = this->Names.begin();
+ ni != this->Names.end() ; ++ni)
+ {
+ // Switch to searching for this name.
+ std::string const& name = *ni;
+ helper.SetName(name);
+
+ // 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 library.
+ return "";
+}
+
+//----------------------------------------------------------------------------
+std::string cmFindLibraryCommand::FindFrameworkLibrary()
+{
+ // Search for a framework of each name in the entire search path.
+ for(std::vector<std::string>::const_iterator ni = this->Names.begin();
+ ni != this->Names.end() ; ++ni)
+ {
+ // Search the paths for a framework with this name.
+ std::string fwName = *ni;
+ fwName += ".framework";
+ std::string fwPath = cmSystemTools::FindDirectory(fwName.c_str(),
+ this->SearchPaths,
+ true);
+ if(!fwPath.empty())
+ {
+ return fwPath;
+ }
+ }
+
+ // No framework found.
+ return "";
+}
diff --git a/Source/cmFindLibraryCommand.h b/Source/cmFindLibraryCommand.h
new file mode 100644
index 000000000..b880be266
--- /dev/null
+++ b/Source/cmFindLibraryCommand.h
@@ -0,0 +1,75 @@
+/*============================================================================
+ 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 cmFindLibraryCommand_h
+#define cmFindLibraryCommand_h
+
+#include "cmFindBase.h"
+
+
+/** \class cmFindLibraryCommand
+ * \brief Define a command to search for a library.
+ *
+ * cmFindLibraryCommand is used to define a CMake variable
+ * that specifies a library. The command searches for a given
+ * file in a list of directories.
+ */
+class cmFindLibraryCommand : public cmFindBase
+{
+public:
+ cmFindLibraryCommand();
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmFindLibraryCommand;
+ }
+
+ /**
+ * 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 const char* GetName() const {return "find_library";}
+
+ /**
+ * Succinct documentation.
+ */
+ virtual const char* GetTerseDocumentation() const
+ {
+ return "Find a library.";
+ }
+ cmTypeMacro(cmFindLibraryCommand, cmFindBase);
+
+protected:
+ void AddArchitecturePaths(const char* suffix);
+ void AddLib64Paths();
+ std::string FindLibrary();
+ virtual void GenerateDocumentation();
+private:
+ std::string FindNormalLibrary();
+ std::string FindFrameworkLibrary();
+};
+
+
+
+#endif
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
new file mode 100644
index 000000000..be47f95d4
--- /dev/null
+++ b/Source/cmFindPackageCommand.cxx
@@ -0,0 +1,2636 @@
+/*============================================================================
+ 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 "cmFindPackageCommand.h"
+
+#include <cmsys/Directory.hxx>
+#include <cmsys/RegularExpression.hxx>
+
+#ifdef CMAKE_BUILD_WITH_CMAKE
+#include "cmVariableWatch.h"
+#endif
+
+#if defined(__HAIKU__)
+#include <StorageKit.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::cmFindPackageCommand()
+{
+ this->CMakePathName = "PACKAGE";
+ this->Quiet = false;
+ this->Required = false;
+ this->NoUserRegistry = false;
+ this->NoSystemRegistry = false;
+ this->NoBuilds = false;
+ this->UseConfigFiles = true;
+ this->UseFindModules = true;
+ this->DebugMode = false;
+ this->UseLib64Paths = false;
+ this->PolicyScope = true;
+ this->VersionMajor = 0;
+ this->VersionMinor = 0;
+ this->VersionPatch = 0;
+ this->VersionTweak = 0;
+ this->VersionCount = 0;
+ this->VersionExact = false;
+ this->VersionFoundMajor = 0;
+ this->VersionFoundMinor = 0;
+ this->VersionFoundPatch = 0;
+ 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 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."
+ ;
+}
+
+//----------------------------------------------------------------------------
+const char* cmFindPackageCommand::GetFullDocumentation() const
+{
+ if(this->CommandDocumentation.empty())
+ {
+ const_cast<cmFindPackageCommand *>(this)->GenerateDocumentation();
+ }
+ return this->CommandDocumentation.c_str();
+}
+
+//----------------------------------------------------------------------------
+bool cmFindPackageCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 1)
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ // Lookup required version of CMake.
+ if(const char* rv =
+ this->Makefile->GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION"))
+ {
+ unsigned int v[3] = {0,0,0};
+ sscanf(rv, "%u.%u.%u", &v[0], &v[1], &v[2]);
+ this->RequiredCMakeVersion = CMake_VERSION_ENCODE(v[0],v[1],v[2]);
+ }
+
+ // Check for debug mode.
+ this->DebugMode = this->Makefile->IsOn("CMAKE_FIND_DEBUG_MODE");
+
+ // Lookup target architecture, if any.
+ if(const char* arch =
+ this->Makefile->GetDefinition("CMAKE_LIBRARY_ARCHITECTURE"))
+ {
+ this->LibraryArchitecture = arch;
+ }
+
+ // Lookup whether lib64 paths should be used.
+ if(this->Makefile->PlatformIs64Bit() &&
+ this->Makefile->GetCMakeInstance()
+ ->GetPropertyAsBool("FIND_LIBRARY_USE_LIB64_PATHS"))
+ {
+ this->UseLib64Paths = true;
+ }
+
+ // Find the current root path mode.
+ this->SelectDefaultRootPathMode();
+
+ // Find the current bundle/framework search policy.
+ this->SelectDefaultMacMode();
+
+ // Record options.
+ this->Name = args[0];
+ std::string components;
+ const char* components_sep = "";
+ 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("");
+
+ // Parse the arguments.
+ enum Doing { DoingNone, DoingComponents, DoingOptionalComponents, DoingNames,
+ DoingPaths, DoingPathSuffixes, DoingConfigs, DoingHints };
+ Doing doing = DoingNone;
+ cmsys::RegularExpression version("^[0-9.]+$");
+ bool haveVersion = false;
+ std::set<unsigned int> configArgs;
+ std::set<unsigned int> moduleArgs;
+ for(unsigned int i=1; i < args.size(); ++i)
+ {
+ if(args[i] == "QUIET")
+ {
+ this->Quiet = true;
+ doing = DoingNone;
+ }
+ else if(args[i] == "EXACT")
+ {
+ this->VersionExact = true;
+ this->Compatibility_1_6 = false;
+ doing = DoingNone;
+ }
+ else if(args[i] == "MODULE")
+ {
+ moduleArgs.insert(i);
+ doing = DoingNone;
+ }
+ else if(args[i] == "CONFIG")
+ {
+ configArgs.insert(i);
+ doing = DoingNone;
+ }
+ else if(args[i] == "NO_MODULE")
+ {
+ configArgs.insert(i);
+ doing = DoingNone;
+ }
+ else if(args[i] == "REQUIRED")
+ {
+ this->Required = true;
+ doing = DoingComponents;
+ }
+ 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;
+ 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))
+ {
+ // Set a variable telling the find script whether this component
+ // is required.
+ const char* isRequired = "1";
+ if (doing == DoingOptionalComponents)
+ {
+ isRequired = "0";
+ optionalComponents.insert(args[i]);
+ }
+ else
+ {
+ requiredComponents.insert(args[i]);
+ }
+
+ std::string req_var = this->Name + "_FIND_REQUIRED_" + args[i];
+ this->AddFindDefinition(req_var.c_str(), isRequired);
+
+ // Append to the list of required components.
+ components += components_sep;
+ components += args[i];
+ components_sep = ";";
+ }
+ else if(doing == DoingNames)
+ {
+ this->Names.push_back(args[i]);
+ }
+ else if(doing == DoingPaths)
+ {
+ this->AddUserPath(args[i], this->UserPaths);
+ }
+ else if(doing == DoingHints)
+ {
+ this->AddUserPath(args[i], this->UserHints);
+ }
+ else if(doing == DoingPathSuffixes)
+ {
+ this->AddPathSuffix(args[i]);
+ }
+ else if(doing == DoingConfigs)
+ {
+ if(args[i].find_first_of(":/\\") != args[i].npos ||
+ cmSystemTools::GetFilenameLastExtension(args[i]) != ".cmake")
+ {
+ cmOStringStream 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());
+ return false;
+ }
+ this->Configs.push_back(args[i]);
+ }
+ else if(!haveVersion && version.find(args[i].c_str()))
+ {
+ haveVersion = true;
+ this->Version = args[i];
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "called with invalid argument \"" << args[i].c_str() << "\"";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+
+ std::vector<std::string> doubledComponents;
+ std::set_intersection(requiredComponents.begin(), requiredComponents.end(),
+ optionalComponents.begin(), optionalComponents.end(),
+ std::back_inserter(doubledComponents));
+ if(!doubledComponents.empty())
+ {
+ cmOStringStream 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());
+ return false;
+ }
+
+ // Maybe choose one mode exclusively.
+ this->UseFindModules = configArgs.empty();
+ this->UseConfigFiles = moduleArgs.empty();
+ if(!this->UseFindModules && !this->UseConfigFiles)
+ {
+ cmOStringStream e;
+ e << "given options exclusive to Module mode:\n";
+ for(std::set<unsigned int>::const_iterator si = moduleArgs.begin();
+ si != moduleArgs.end(); ++si)
+ {
+ e << " " << args[*si] << "\n";
+ }
+ e << "and options exclusive to Config mode:\n";
+ for(std::set<unsigned int>::const_iterator si = configArgs.begin();
+ si != configArgs.end(); ++si)
+ {
+ e << " " << args[*si] << "\n";
+ }
+ e << "The options are incompatible.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+
+ // Ignore EXACT with no version.
+ if(this->Version.empty() && this->VersionExact)
+ {
+ this->VersionExact = false;
+ this->Makefile->IssueMessage(
+ cmake::AUTHOR_WARNING, "Ignoring EXACT since no version is requested.");
+ }
+
+ if(this->Version.empty() || components.empty())
+ {
+ // Check whether we are recursing inside "Find<name>.cmake" within
+ // another find_package(<name>) call.
+ std::string mod = this->Name;
+ mod += "_FIND_MODULE";
+ if(this->Makefile->IsOn(mod.c_str()))
+ {
+ if(this->Version.empty())
+ {
+ // Get version information from the outer call if necessary.
+ // Requested version string.
+ std::string ver = this->Name;
+ ver += "_FIND_VERSION";
+ this->Version = this->Makefile->GetSafeDefinition(ver.c_str());
+
+ // Whether an exact version is required.
+ std::string exact = this->Name;
+ exact += "_FIND_VERSION_EXACT";
+ this->VersionExact = this->Makefile->IsOn(exact.c_str());
+ }
+ if(components.empty())
+ {
+ std::string components_var = this->Name + "_FIND_COMPONENTS";
+ components = this->Makefile->GetSafeDefinition(components_var.c_str());
+ }
+ }
+ }
+
+ if(!this->Version.empty())
+ {
+ // Try to parse the version number and store the results that were
+ // successfully parsed.
+ unsigned int parsed_major;
+ unsigned int parsed_minor;
+ unsigned int parsed_patch;
+ unsigned int parsed_tweak;
+ this->VersionCount = sscanf(this->Version.c_str(), "%u.%u.%u.%u",
+ &parsed_major, &parsed_minor,
+ &parsed_patch, &parsed_tweak);
+ switch(this->VersionCount)
+ {
+ case 4: this->VersionTweak = parsed_tweak; // no break!
+ case 3: this->VersionPatch = parsed_patch; // no break!
+ case 2: this->VersionMinor = parsed_minor; // no break!
+ case 1: this->VersionMajor = parsed_major; // no break!
+ default: break;
+ }
+ }
+
+ std::string disableFindPackageVar = "CMAKE_DISABLE_FIND_PACKAGE_";
+ disableFindPackageVar += this->Name;
+ if(this->Makefile->IsOn(disableFindPackageVar.c_str()))
+ {
+ if (this->Required)
+ {
+ cmOStringStream 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());
+ return false;
+ }
+
+ return true;
+ }
+
+
+ this->SetModuleVariables(components);
+
+ // See if there is a Find<package>.cmake module.
+ if(this->UseFindModules)
+ {
+ bool foundModule = false;
+ if(!this->FindModule(foundModule))
+ {
+ this->AppendSuccessInformation();
+ return false;
+ }
+ if(foundModule)
+ {
+ this->AppendSuccessInformation();
+ return true;
+ }
+ }
+
+ if(this->UseFindModules && this->UseConfigFiles &&
+ this->Makefile->IsOn("CMAKE_FIND_PACKAGE_WARN_NO_MODULE"))
+ {
+ cmOStringStream aw;
+ if(this->RequiredCMakeVersion >= CMake_VERSION_ENCODE(2,8,8))
+ {
+ aw << "find_package called without either MODULE or CONFIG option and "
+ "no Find" << this->Name << ".cmake module is in CMAKE_MODULE_PATH. "
+ "Add MODULE to exclusively request Module mode and fail if "
+ "Find" << this->Name << ".cmake is missing. "
+ "Add CONFIG to exclusively request Config mode and search for a "
+ "package configuration file provided by " << this->Name <<
+ " (" << this->Name << "Config.cmake or " <<
+ cmSystemTools::LowerCase(this->Name) << "-config.cmake). ";
+ }
+ else
+ {
+ aw << "find_package called without NO_MODULE option and no "
+ "Find" << this->Name << ".cmake module is in CMAKE_MODULE_PATH. "
+ "Add NO_MODULE to exclusively request Config mode and search for a "
+ "package configuration file provided by " << this->Name <<
+ " (" << this->Name << "Config.cmake or " <<
+ cmSystemTools::LowerCase(this->Name) << "-config.cmake). "
+ "Otherwise make Find" << this->Name << ".cmake available in "
+ "CMAKE_MODULE_PATH.";
+ }
+ aw << "\n"
+ "(Variable CMAKE_FIND_PACKAGE_WARN_NO_MODULE enabled this warning.)";
+ this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, aw.str());
+ }
+
+ // No find module. Assume the project has a CMake config file. Use
+ // a <package>_DIR cache variable to locate it.
+ this->Variable = this->Name;
+ this->Variable += "_DIR";
+
+ // Add the default name.
+ if(this->Names.empty())
+ {
+ this->Names.push_back(this->Name);
+ }
+
+ // Add the default configs.
+ if(this->Configs.empty())
+ {
+ for(std::vector<std::string>::const_iterator ni = this->Names.begin();
+ ni != this->Names.end(); ++ni)
+ {
+ std::string config = *ni;
+ config += "Config.cmake";
+ this->Configs.push_back(config);
+
+ config = cmSystemTools::LowerCase(*ni);
+ config += "-config.cmake";
+ this->Configs.push_back(config);
+ }
+ }
+
+ // get igonored paths from vars and reroot them.
+ std::vector<std::string> ignored;
+ this->GetIgnoredPaths(ignored);
+ this->RerootPaths(ignored);
+
+ // Construct a set of ignored paths
+ this->IgnoredPaths.clear();
+ this->IgnoredPaths.insert(ignored.begin(), ignored.end());
+
+ // Find and load the package.
+ bool result = this->HandlePackageMode();
+ this->AppendSuccessInformation();
+ return result;
+}
+
+
+//----------------------------------------------------------------------------
+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());
+
+ if(this->Quiet)
+ {
+ // Tell the module that is about to be read that it should find
+ // quietly.
+ std::string quietly = this->Name;
+ quietly += "_FIND_QUIETLY";
+ this->AddFindDefinition(quietly.c_str(), "1");
+ }
+
+ if(this->Required)
+ {
+ // Tell the module that is about to be read that it should report
+ // a fatal error if the package is not found.
+ std::string req = this->Name;
+ req += "_FIND_REQUIRED";
+ this->AddFindDefinition(req.c_str(), "1");
+ }
+
+ if(!this->Version.empty())
+ {
+ // Tell the module that is about to be read what version of the
+ // package has been requested.
+ std::string ver = this->Name;
+ ver += "_FIND_VERSION";
+ this->AddFindDefinition(ver.c_str(), this->Version.c_str());
+ char buf[64];
+ sprintf(buf, "%u", this->VersionMajor);
+ this->AddFindDefinition((ver+"_MAJOR").c_str(), buf);
+ sprintf(buf, "%u", this->VersionMinor);
+ this->AddFindDefinition((ver+"_MINOR").c_str(), buf);
+ sprintf(buf, "%u", this->VersionPatch);
+ this->AddFindDefinition((ver+"_PATCH").c_str(), buf);
+ sprintf(buf, "%u", this->VersionTweak);
+ this->AddFindDefinition((ver+"_TWEAK").c_str(), buf);
+ sprintf(buf, "%u", this->VersionCount);
+ this->AddFindDefinition((ver+"_COUNT").c_str(), 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");
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmFindPackageCommand::AddFindDefinition(const char* var, const char* val)
+{
+ if(const char* old = this->Makefile->GetDefinition(var))
+ {
+ this->OriginalDefs[var].exists = true;
+ this->OriginalDefs[var].value = old;
+ }
+ else
+ {
+ this->OriginalDefs[var].exists = false;
+ }
+ this->Makefile->AddDefinition(var, val);
+}
+
+//----------------------------------------------------------------------------
+void cmFindPackageCommand::RestoreFindDefinitions()
+{
+ for(std::map<cmStdString, 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());
+ }
+ else
+ {
+ this->Makefile->RemoveDefinition(i->first.c_str());
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmFindPackageCommand::FindModule(bool& found)
+{
+ std::string module = "Find";
+ module += this->Name;
+ module += ".cmake";
+ std::string mfile = this->Makefile->GetModulesFile(module.c_str());
+ if ( mfile.size() )
+ {
+ // 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");
+ bool result = this->ReadListFile(mfile.c_str(), DoPolicyScope);
+ this->Makefile->RemoveDefinition(var.c_str());
+ return result;
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmFindPackageCommand::HandlePackageMode()
+{
+ this->ConsideredConfigs.clear();
+
+ // Support old capitalization behavior.
+ std::string upperDir = cmSystemTools::UpperCase(this->Name);
+ 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());
+ }
+ }
+
+ // Try to load the config file if the directory is known
+ bool fileFound = false;
+ if (this->UseConfigFiles)
+ {
+ if(!cmSystemTools::IsOff(def))
+ {
+ // Get the directory from the variable value.
+ std::string dir = def;
+ cmSystemTools::ConvertToUnixSlashes(dir);
+
+ // Treat relative paths with respect to the current source dir.
+ if(!cmSystemTools::FileIsFullPath(dir.c_str()))
+ {
+ dir = "/" + dir;
+ dir = this->Makefile->GetCurrentDirectory() + dir;
+ }
+ // The file location was cached. Look for the correct file.
+ std::string file;
+ if (this->FindConfigFile(dir, file))
+ {
+ this->FileFound = file;
+ fileFound = true;
+ }
+ def = this->Makefile->GetDefinition(this->Variable.c_str());
+ }
+
+ // 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.
+ if(fileFound && this->FileFound.empty())
+ {
+ this->Makefile->IssueMessage(
+ cmake::INTERNAL_ERROR, "fileFound is true but FileFound is empty!");
+ fileFound = false;
+ }
+ }
+
+ std::string foundVar = this->Name;
+ foundVar += "_FOUND";
+
+ // If the directory for the config file was found, try to read the file.
+ bool result = true;
+ bool found = false;
+ bool configFileSetFOUNDFalse = false;
+
+ if(fileFound)
+ {
+ if ((this->Makefile->IsDefinitionSet(foundVar.c_str()))
+ && (this->Makefile->IsOn(foundVar.c_str()) == 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());
+ }
+
+ // Set the version variables before loading the config file.
+ // It may override them.
+ this->StoreVersionFound();
+
+ // Parse the configuration file.
+ if(this->ReadListFile(this->FileFound.c_str(), DoPolicyScope))
+ {
+ // The package has been found.
+ 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))
+ {
+ // we get here if the Config file has set Foo_FOUND actively to FALSE
+ found = false;
+ configFileSetFOUNDFalse = true;
+ }
+ }
+ else
+ {
+ // The configuration file is invalid.
+ result = false;
+ }
+ }
+
+ if (result && !found && (!this->Quiet || this->Required))
+ {
+ // The variable is not set.
+ cmOStringStream e;
+ cmOStringStream aw;
+ if (configFileSetFOUNDFalse)
+ {
+ e << "Found package configuration file:\n"
+ " " << this->FileFound << "\n"
+ "but it set " << foundVar << " to FALSE so package \"" <<
+ this->Name << "\" is considered to be NOT FOUND.";
+ }
+ // 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)
+ {
+ e << "Could not find a configuration file for package \""
+ << this->Name << "\" that "
+ << (this->VersionExact? "exactly matches" : "is compatible with")
+ << " requested version \"" << this->Version << "\".\n"
+ << "The following configuration files were considered but not "
+ "accepted:\n";
+ for(std::vector<ConfigFileInfo>::size_type i=0;
+ i<this->ConsideredConfigs.size(); i++)
+ {
+ e << " " << this->ConsideredConfigs[i].filename
+ << ", version: " << this->ConsideredConfigs[i].version << "\n";
+ }
+ }
+ else
+ {
+ std::string requestedVersionString;
+ if(!this->Version.empty())
+ {
+ requestedVersionString = " (requested version ";
+ requestedVersionString += this->Version;
+ requestedVersionString += ")";
+ }
+
+ if (this->UseConfigFiles)
+ {
+ if(this->UseFindModules)
+ {
+ e << "By not providing \"Find" << this->Name << ".cmake\" in "
+ "CMAKE_MODULE_PATH this project has asked CMake to find a "
+ "package configuration file provided by \""<<this->Name<< "\", "
+ "but CMake did not find one.\n";
+ }
+
+ if(this->Configs.size() == 1)
+ {
+ e << "Could not find a package configuration file named \""
+ << this->Configs[0] << "\" provided by package \""
+ << this->Name << "\"" << requestedVersionString <<".\n";
+ }
+ else
+ {
+ 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";
+ }
+ }
+
+ e << "Add the installation prefix of \"" << this->Name << "\" to "
+ "CMAKE_PREFIX_PATH or set \"" << this->Variable << "\" to a "
+ "directory containing one of the above files. "
+ "If \"" << this->Name << "\" provides a separate development "
+ "package or SDK, be sure it has been installed.";
+ }
+ else // if(!this->UseFindModules && !this->UseConfigFiles)
+ {
+ e << "No \"Find" << this->Name << ".cmake\" found in "
+ << "CMAKE_MODULE_PATH.";
+
+ aw<< "Find"<< this->Name <<".cmake must either be part of this "
+ "project itself, in this case adjust CMAKE_MODULE_PATH so that "
+ "it points to the correct location inside its source tree.\n"
+ "Or it must be installed by a package which has already been "
+ "found via find_package(). In this case make sure that "
+ "package has indeed been found and adjust CMAKE_MODULE_PATH to "
+ "contain the location where that package has installed "
+ "Find" << this->Name << ".cmake. This must be a location "
+ "provided by that package. This error in general means that "
+ "the buildsystem of this project is relying on a Find-module "
+ "without ensuring that it is actually available.\n";
+ }
+ }
+
+
+ this->Makefile->IssueMessage(
+ this->Required? cmake::FATAL_ERROR : cmake::WARNING, e.str());
+ if (this->Required)
+ {
+ cmSystemTools::SetFatalErrorOccured();
+ }
+
+ if (!aw.str().empty())
+ {
+ this->Makefile->IssueMessage(cmake::AUTHOR_WARNING,aw.str());
+ }
+ }
+
+ // Set a variable marking whether the package was found.
+ this->Makefile->AddDefinition(foundVar.c_str(), 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());
+ }
+ else
+ {
+ this->Makefile->RemoveDefinition(fileVar.c_str());
+ }
+
+ // 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;
+ consideredVersionsVar += "_CONSIDERED_VERSIONS";
+
+ std::string consideredConfigFiles;
+ std::string consideredVersions;
+
+ const char* sep = "";
+ for(std::vector<ConfigFileInfo>::size_type i=0;
+ i<this->ConsideredConfigs.size(); i++)
+ {
+ consideredConfigFiles += sep;
+ consideredVersions += sep;
+ consideredConfigFiles += this->ConsideredConfigs[i].filename;
+ consideredVersions += this->ConsideredConfigs[i].version;
+ sep = ";";
+ }
+
+ this->Makefile->AddDefinition(consideredConfigsVar.c_str(),
+ consideredConfigFiles.c_str());
+
+ this->Makefile->AddDefinition(consideredVersionsVar.c_str(),
+ consideredVersions.c_str());
+
+ return result;
+}
+
+//----------------------------------------------------------------------------
+bool cmFindPackageCommand::FindConfig()
+{
+ // Compute the set of search prefixes.
+ this->ComputePrefixes();
+
+ // Look for the project's configuration file.
+ bool found = false;
+
+ // Search for frameworks.
+ if(!found && (this->SearchFrameworkFirst || this->SearchFrameworkOnly))
+ {
+ found = this->FindFrameworkConfig();
+ }
+
+ // Search for apps.
+ if(!found && (this->SearchAppBundleFirst || this->SearchAppBundleOnly))
+ {
+ found = this->FindAppBundleConfig();
+ }
+
+ // Search prefixes.
+ if(!found && !(this->SearchFrameworkOnly || this->SearchAppBundleOnly))
+ {
+ found = this->FindPrefixedConfig();
+ }
+
+ // Search for frameworks.
+ if(!found && this->SearchFrameworkLast)
+ {
+ found = this->FindFrameworkConfig();
+ }
+
+ // Search for apps.
+ if(!found && this->SearchAppBundleLast)
+ {
+ found = this->FindAppBundleConfig();
+ }
+
+ // Store the entry in the cache so it can be set by the user.
+ std::string init;
+ if(found)
+ {
+ init = cmSystemTools::GetFilenamePath(this->FileFound);
+ }
+ else
+ {
+ init = this->Variable + "-NOTFOUND";
+ }
+ std::string help =
+ "The directory containing a CMake configuration file for ";
+ 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(),
+ init.c_str(), help.c_str(),
+ cmCacheManager::PATH, true);
+ return found;
+}
+
+//----------------------------------------------------------------------------
+bool cmFindPackageCommand::FindPrefixedConfig()
+{
+ std::vector<std::string>& prefixes = this->SearchPaths;
+ for(std::vector<std::string>::const_iterator pi = prefixes.begin();
+ pi != prefixes.end(); ++pi)
+ {
+ if(this->SearchPrefix(*pi))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmFindPackageCommand::FindFrameworkConfig()
+{
+ std::vector<std::string>& prefixes = this->SearchPaths;
+ for(std::vector<std::string>::const_iterator i = prefixes.begin();
+ i != prefixes.end(); ++i)
+ {
+ if(this->SearchFrameworkPrefix(*i))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmFindPackageCommand::FindAppBundleConfig()
+{
+ std::vector<std::string>& prefixes = this->SearchPaths;
+ for(std::vector<std::string>::const_iterator i = prefixes.begin();
+ i != prefixes.end(); ++i)
+ {
+ if(this->SearchAppBundlePrefix(*i))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmFindPackageCommand::ReadListFile(const char* f, PolicyScopeRule psr)
+{
+ if(this->Makefile->ReadListFile(this->Makefile->GetCurrentListFile(), f, 0,
+ !this->PolicyScope || psr == NoPolicyScope))
+ {
+ return true;
+ }
+ std::string e = "Error reading CMake code from \"";
+ e += f;
+ e += "\".";
+ this->SetError(e.c_str());
+ return false;
+}
+
+//----------------------------------------------------------------------------
+void cmFindPackageCommand::AppendToFoundProperty(bool found)
+{
+ std::vector<std::string> foundContents;
+ const char *foundProp =
+ this->Makefile->GetCMakeInstance()->GetProperty("PACKAGES_FOUND");
+ if (foundProp && *foundProp)
+ {
+ std::string tmp = foundProp;
+
+ cmSystemTools::ExpandListArgument(tmp, foundContents, false);
+ std::vector<std::string>::iterator nameIt = std::find(
+ foundContents.begin(), foundContents.end(), this->Name);
+ if(nameIt != foundContents.end())
+ {
+ foundContents.erase(nameIt);
+ }
+ }
+
+ std::vector<std::string> notFoundContents;
+ const char *notFoundProp =
+ this->Makefile->GetCMakeInstance()->GetProperty("PACKAGES_NOT_FOUND");
+ if (notFoundProp && *notFoundProp)
+ {
+ std::string tmp = notFoundProp;
+
+ cmSystemTools::ExpandListArgument(tmp, notFoundContents, false);
+ std::vector<std::string>::iterator nameIt = std::find(
+ notFoundContents.begin(), notFoundContents.end(), this->Name);
+ if(nameIt != notFoundContents.end())
+ {
+ notFoundContents.erase(nameIt);
+ }
+ }
+
+ if(found)
+ {
+ foundContents.push_back(this->Name);
+ }
+ else
+ {
+ notFoundContents.push_back(this->Name);
+ }
+
+
+ std::string tmp;
+ const char* sep ="";
+ for(size_t i=0; i<foundContents.size(); i++)
+ {
+ tmp += sep;
+ tmp += foundContents[i];
+ sep = ";";
+ }
+
+ 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());
+}
+
+//----------------------------------------------------------------------------
+void cmFindPackageCommand::AppendSuccessInformation()
+{
+ 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());
+ bool packageFound = ((cmSystemTools::IsOn(result))
+ || (cmSystemTools::IsOn(upperResult)));
+
+ this->AppendToFoundProperty(packageFound);
+
+ // Record whether the find was quiet or not, so this can be used
+ // e.g. in FeatureSummary.cmake
+ std::string quietInfoPropName = "_CMAKE_";
+ quietInfoPropName += this->Name;
+ quietInfoPropName += "_QUIET";
+ this->Makefile->GetCMakeInstance()->SetProperty(quietInfoPropName.c_str(),
+ this->Quiet ? "TRUE" : "FALSE");
+
+ // set a global property to record the required version of this package
+ std::string versionInfoPropName = "_CMAKE_";
+ versionInfoPropName += this->Name;
+ versionInfoPropName += "_REQUIRED_VERSION";
+ std::string versionInfo;
+ if(!this->Version.empty())
+ {
+ versionInfo = this->VersionExact ? "==" : ">=";
+ versionInfo += " ";
+ versionInfo += this->Version;
+ }
+ this->Makefile->GetCMakeInstance()->SetProperty(versionInfoPropName.c_str(),
+ versionInfo.c_str());
+ if (this->Required)
+ {
+ std::string requiredInfoPropName = "_CMAKE_";
+ requiredInfoPropName += this->Name;
+ requiredInfoPropName += "_TYPE";
+ this->Makefile->GetCMakeInstance()->SetProperty(
+ requiredInfoPropName.c_str(), "REQUIRED");
+ }
+
+
+ // Restore original state of "_FIND_" variables we set.
+ this->RestoreFindDefinitions();
+}
+
+//----------------------------------------------------------------------------
+void cmFindPackageCommand::ComputePrefixes()
+{
+ this->AddPrefixesCMakeVariable();
+ this->AddPrefixesCMakeEnvironment();
+ this->AddPrefixesUserHints();
+ this->AddPrefixesSystemEnvironment();
+ this->AddPrefixesUserRegistry();
+ this->AddPrefixesBuilds();
+ this->AddPrefixesCMakeSystemVariable();
+ this->AddPrefixesSystemRegistry();
+ this->AddPrefixesUserGuess();
+ this->ComputeFinalPaths();
+}
+
+//----------------------------------------------------------------------------
+void cmFindPackageCommand::AddPrefixesCMakeEnvironment()
+{
+ 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);
+ }
+
+ this->AddEnvPath("CMAKE_PREFIX_PATH");
+ this->AddEnvPath("CMAKE_FRAMEWORK_PATH");
+ this->AddEnvPath("CMAKE_APPBUNDLE_PATH");
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmFindPackageCommand::AddPrefixesCMakeVariable()
+{
+ if(!this->NoCMakePath && !this->NoDefaultPath)
+ {
+ this->AddCMakePath("CMAKE_PREFIX_PATH");
+ this->AddCMakePath("CMAKE_FRAMEWORK_PATH");
+ this->AddCMakePath("CMAKE_APPBUNDLE_PATH");
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmFindPackageCommand::AddPrefixesSystemEnvironment()
+{
+ if(!this->NoSystemEnvironmentPath && !this->NoDefaultPath)
+ {
+ // 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)
+ {
+ 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);
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmFindPackageCommand::AddPrefixesUserRegistry()
+{
+ 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)
+ {
+ dir.Append("cmake/packages");
+ dir.Append(this->Name.c_str());
+ this->LoadPackageRegistryDir(dir.Path());
+ }
+#else
+ if(const char* home = cmSystemTools::GetEnv("HOME"))
+ {
+ std::string dir = home;
+ dir += "/.cmake/packages/";
+ dir += this->Name;
+ this->LoadPackageRegistryDir(dir);
+ }
+#endif
+}
+
+//----------------------------------------------------------------------------
+void cmFindPackageCommand::AddPrefixesSystemRegistry()
+{
+ if(this->NoSystemRegistry || this->NoDefaultPath)
+ {
+ return;
+ }
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ this->LoadPackageRegistryWinSystem();
+#endif
+}
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+# include <windows.h>
+# undef GetCurrentDirectory
+ // http://msdn.microsoft.com/en-us/library/aa384253%28v=vs.85%29.aspx
+# if !defined(KEY_WOW64_32KEY)
+# define KEY_WOW64_32KEY 0x0200
+# endif
+# if !defined(KEY_WOW64_64KEY)
+# define KEY_WOW64_64KEY 0x0100
+# endif
+//----------------------------------------------------------------------------
+void cmFindPackageCommand::LoadPackageRegistryWinUser()
+{
+ // HKEY_CURRENT_USER\\Software shares 32-bit and 64-bit views.
+ this->LoadPackageRegistryWin(true, 0);
+}
+
+//----------------------------------------------------------------------------
+void cmFindPackageCommand::LoadPackageRegistryWinSystem()
+{
+ // 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);
+ }
+ else
+ {
+ this->LoadPackageRegistryWin(false, KEY_WOW64_32KEY);
+ this->LoadPackageRegistryWin(false, KEY_WOW64_64KEY);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmFindPackageCommand::LoadPackageRegistryWin(bool user,
+ unsigned int view)
+{
+ std::string key = "Software\\Kitware\\CMake\\Packages\\";
+ key += this->Name;
+ std::set<cmStdString> bad;
+ HKEY hKey;
+ if(RegOpenKeyEx(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);
+ 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,
+ 0, &valueType, (BYTE*)&data[0], &dataSize))
+ {
+ case ERROR_SUCCESS:
+ ++index;
+ if(valueType == REG_SZ)
+ {
+ data[dataSize] = 0;
+ cmsys_ios::stringstream ss(&data[0]);
+ if(!this->CheckPackageRegistryEntry(ss))
+ {
+ // The entry is invalid.
+ bad.insert(name);
+ }
+ }
+ break;
+ case ERROR_MORE_DATA:
+ data.resize(dataSize+1);
+ break;
+ case ERROR_NO_MORE_ITEMS: default: done = true; break;
+ }
+ }
+ RegCloseKey(hKey);
+ }
+
+ // Remove bad values if possible.
+ if(user && !bad.empty() &&
+ RegOpenKeyEx(HKEY_CURRENT_USER, key.c_str(),
+ 0, KEY_SET_VALUE|view, &hKey) == ERROR_SUCCESS)
+ {
+ for(std::set<cmStdString>::const_iterator vi = bad.begin();
+ vi != bad.end(); ++vi)
+ {
+ RegDeleteValue(hKey, vi->c_str());
+ }
+ RegCloseKey(hKey);
+ }
+}
+#else
+//----------------------------------------------------------------------------
+class cmFindPackageCommandHoldFile
+{
+ const char* File;
+public:
+ cmFindPackageCommandHoldFile(const char* f): File(f) {}
+ ~cmFindPackageCommandHoldFile()
+ { if(this->File) { cmSystemTools::RemoveFile(this->File); } }
+ void Release() { this->File = 0; }
+};
+
+//----------------------------------------------------------------------------
+void cmFindPackageCommand::LoadPackageRegistryDir(std::string const& dir)
+{
+ cmsys::Directory files;
+ if(!files.Load(dir.c_str()))
+ {
+ return;
+ }
+
+ std::string fname;
+ for(unsigned long i=0; i < files.GetNumberOfFiles(); ++i)
+ {
+ fname = dir;
+ fname += "/";
+ fname += files.GetFile(i);
+
+ if(!cmSystemTools::FileIsDirectory(fname.c_str()))
+ {
+ // 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))
+ {
+ // The file references an existing package, so release it.
+ holdFile.Release();
+ }
+ }
+ }
+
+ // TODO: Wipe out the directory if it is empty.
+}
+#endif
+
+//----------------------------------------------------------------------------
+bool cmFindPackageCommand::CheckPackageRegistryEntry(std::istream& is)
+{
+ // Parse the content of one package registry entry.
+ std::string fname;
+ if(cmSystemTools::GetLineFromStream(is, fname) &&
+ 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()))
+ {
+ fname = cmSystemTools::GetFilenamePath(fname);
+ }
+ this->AddPathInternal(fname, FullPath);
+ return true;
+ }
+ else
+ {
+ // The path does not exist. Assume the stream content is
+ // associated with an old package that no longer exists, and
+ // delete it to keep the package registry clean.
+ return false;
+ }
+ }
+ else
+ {
+ // The first line in the stream is not the full path to a file or
+ // directory. Assume the stream content was created by a future
+ // version of CMake that uses a different format, and leave it.
+ return true;
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmFindPackageCommand::AddPrefixesBuilds()
+{
+ 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);
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmFindPackageCommand::AddPrefixesCMakeSystemVariable()
+{
+ if(!this->NoCMakeSystemPath && !this->NoDefaultPath)
+ {
+ this->AddCMakePath("CMAKE_SYSTEM_PREFIX_PATH");
+ this->AddCMakePath("CMAKE_SYSTEM_FRAMEWORK_PATH");
+ this->AddCMakePath("CMAKE_SYSTEM_APPBUNDLE_PATH");
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmFindPackageCommand::AddPrefixesUserGuess()
+{
+ // Add guesses specified by the caller.
+ this->AddPathsInternal(this->UserPaths, CMakePath);
+}
+
+//----------------------------------------------------------------------------
+void cmFindPackageCommand::AddPrefixesUserHints()
+{
+ // Add hints specified by the caller.
+ this->AddPathsInternal(this->UserHints, CMakePath);
+}
+
+//----------------------------------------------------------------------------
+bool cmFindPackageCommand::SearchDirectory(std::string const& dir)
+{
+ assert(!dir.empty() && dir[dir.size()-1] == '/');
+
+ // Check each path suffix on this directory.
+ for(std::vector<std::string>::const_iterator
+ si = this->SearchPathSuffixes.begin();
+ si != this->SearchPathSuffixes.end(); ++si)
+ {
+ std::string d = dir;
+ if(!si->empty())
+ {
+ d += *si;
+ d += "/";
+ }
+ if(this->CheckDirectory(d))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmFindPackageCommand::CheckDirectory(std::string const& dir)
+{
+ assert(!dir.empty() && dir[dir.size()-1] == '/');
+
+ // Look for the file in this directory.
+ std::string d = dir.substr(0, dir.size()-1);
+ if(this->FindConfigFile(d, this->FileFound))
+ {
+ // Remove duplicate slashes.
+ cmSystemTools::ConvertToUnixSlashes(this->FileFound);
+ return true;
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmFindPackageCommand::FindConfigFile(std::string const& dir,
+ std::string& file)
+{
+ if (this->IgnoredPaths.count(dir))
+ {
+ return false;
+ }
+
+ for(std::vector<std::string>::const_iterator ci = this->Configs.begin();
+ ci != this->Configs.end(); ++ci)
+ {
+ file = dir;
+ file += "/";
+ file += *ci;
+ if(this->DebugMode)
+ {
+ fprintf(stderr, "Checking file [%s]\n", file.c_str());
+ }
+ if(cmSystemTools::FileExists(file.c_str(), true) &&
+ this->CheckVersion(file))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmFindPackageCommand::CheckVersion(std::string const& config_file)
+{
+ bool result = false; // by default, assume the version is not ok.
+ bool haveResult = false;
+ std::string version = "unknown";
+
+ // Get the filename without the .cmake extension.
+ std::string::size_type pos = config_file.rfind('.');
+ std::string version_file_base = config_file.substr(0, pos);
+
+ // Look for foo-config-version.cmake
+ std::string version_file = version_file_base;
+ version_file += "-version.cmake";
+ if ((haveResult == false)
+ && (cmSystemTools::FileExists(version_file.c_str(), true)))
+ {
+ result = this->CheckVersionFile(version_file, version);
+ haveResult = true;
+ }
+
+ // Look for fooConfigVersion.cmake
+ version_file = version_file_base;
+ version_file += "Version.cmake";
+ if ((haveResult == false)
+ && (cmSystemTools::FileExists(version_file.c_str(), true)))
+ {
+ result = this->CheckVersionFile(version_file, version);
+ haveResult = true;
+ }
+
+
+ // If no version was requested a versionless package is acceptable.
+ if ((haveResult == false) && (this->Version.empty()))
+ {
+ result = true;
+ haveResult = true;
+ }
+
+ ConfigFileInfo configFileInfo;
+ configFileInfo.filename = config_file;
+ configFileInfo.version = version;
+ this->ConsideredConfigs.push_back(configFileInfo);
+
+ return result;
+}
+
+//----------------------------------------------------------------------------
+bool cmFindPackageCommand::CheckVersionFile(std::string const& version_file,
+ std::string& result_version)
+{
+ // The version file will be loaded in an isolated scope.
+ cmMakefile::ScopePushPop varScope(this->Makefile);
+ cmMakefile::PolicyPushPop polScope(this->Makefile);
+ static_cast<void>(varScope);
+ static_cast<void>(polScope);
+
+ // Clear the output variables.
+ this->Makefile->RemoveDefinition("PACKAGE_VERSION");
+ this->Makefile->RemoveDefinition("PACKAGE_VERSION_UNSUITABLE");
+ this->Makefile->RemoveDefinition("PACKAGE_VERSION_COMPATIBLE");
+ this->Makefile->RemoveDefinition("PACKAGE_VERSION_EXACT");
+
+ // Set the input variables.
+ this->Makefile->AddDefinition("PACKAGE_FIND_NAME", this->Name.c_str());
+ this->Makefile->AddDefinition("PACKAGE_FIND_VERSION",
+ this->Version.c_str());
+ char buf[64];
+ sprintf(buf, "%u", this->VersionMajor);
+ this->Makefile->AddDefinition("PACKAGE_FIND_VERSION_MAJOR", buf);
+ sprintf(buf, "%u", this->VersionMinor);
+ this->Makefile->AddDefinition("PACKAGE_FIND_VERSION_MINOR", buf);
+ sprintf(buf, "%u", this->VersionPatch);
+ this->Makefile->AddDefinition("PACKAGE_FIND_VERSION_PATCH", buf);
+ sprintf(buf, "%u", this->VersionTweak);
+ this->Makefile->AddDefinition("PACKAGE_FIND_VERSION_TWEAK", buf);
+ sprintf(buf, "%u", this->VersionCount);
+ this->Makefile->AddDefinition("PACKAGE_FIND_VERSION_COUNT", buf);
+
+ // Load the version check file. Pass NoPolicyScope because we do
+ // our own policy push/pop independent of CMP0011.
+ bool suitable = false;
+ if(this->ReadListFile(version_file.c_str(), NoPolicyScope))
+ {
+ // Check the output variables.
+ bool okay = this->Makefile->IsOn("PACKAGE_VERSION_EXACT");
+ bool unsuitable = this->Makefile->IsOn("PACKAGE_VERSION_UNSUITABLE");
+ if(!okay && !this->VersionExact)
+ {
+ okay = this->Makefile->IsOn("PACKAGE_VERSION_COMPATIBLE");
+ }
+
+ // The package is suitable if the version is okay and not
+ // explicitly unsuitable.
+ suitable = !unsuitable && (okay || this->Version.empty());
+ if(suitable)
+ {
+ // Get the version found.
+ this->VersionFound =
+ this->Makefile->GetSafeDefinition("PACKAGE_VERSION");
+
+ // Try to parse the version number and store the results that were
+ // successfully parsed.
+ unsigned int parsed_major;
+ unsigned int parsed_minor;
+ unsigned int parsed_patch;
+ unsigned int parsed_tweak;
+ this->VersionFoundCount =
+ sscanf(this->VersionFound.c_str(), "%u.%u.%u.%u",
+ &parsed_major, &parsed_minor,
+ &parsed_patch, &parsed_tweak);
+ switch(this->VersionFoundCount)
+ {
+ case 4: this->VersionFoundTweak = parsed_tweak; // no break!
+ case 3: this->VersionFoundPatch = parsed_patch; // no break!
+ case 2: this->VersionFoundMinor = parsed_minor; // no break!
+ case 1: this->VersionFoundMajor = parsed_major; // no break!
+ default: break;
+ }
+ }
+ }
+
+ result_version = this->Makefile->GetSafeDefinition("PACKAGE_VERSION");
+ if (result_version.empty())
+ {
+ result_version = "unknown";
+ }
+
+ // Succeed if the version is suitable.
+ return suitable;
+}
+
+//----------------------------------------------------------------------------
+void cmFindPackageCommand::StoreVersionFound()
+{
+ // Store the whole version string.
+ std::string ver = this->Name;
+ ver += "_VERSION";
+ if(this->VersionFound.empty())
+ {
+ this->Makefile->RemoveDefinition(ver.c_str());
+ }
+ else
+ {
+ this->Makefile->AddDefinition(ver.c_str(), this->VersionFound.c_str());
+ }
+
+ // Store the version components.
+ char buf[64];
+ sprintf(buf, "%u", this->VersionFoundMajor);
+ this->Makefile->AddDefinition((ver+"_MAJOR").c_str(), buf);
+ sprintf(buf, "%u", this->VersionFoundMinor);
+ this->Makefile->AddDefinition((ver+"_MINOR").c_str(), buf);
+ sprintf(buf, "%u", this->VersionFoundPatch);
+ this->Makefile->AddDefinition((ver+"_PATCH").c_str(), buf);
+ sprintf(buf, "%u", this->VersionFoundTweak);
+ this->Makefile->AddDefinition((ver+"_TWEAK").c_str(), buf);
+ sprintf(buf, "%u", this->VersionFoundCount);
+ this->Makefile->AddDefinition((ver+"_COUNT").c_str(), buf);
+}
+
+//----------------------------------------------------------------------------
+#include <cmsys/Glob.hxx>
+#include <cmsys/String.h>
+#include <cmsys/auto_ptr.hxx>
+
+class cmFileList;
+class cmFileListGeneratorBase
+{
+public:
+ virtual ~cmFileListGeneratorBase() {}
+protected:
+ bool Consider(std::string const& fullPath, cmFileList& listing);
+private:
+ bool Search(cmFileList&);
+ virtual bool Search(std::string const& parent, cmFileList&) = 0;
+ virtual cmsys::auto_ptr<cmFileListGeneratorBase> Clone() const = 0;
+ friend class cmFileList;
+ cmFileListGeneratorBase* SetNext(cmFileListGeneratorBase const& next);
+ cmsys::auto_ptr<cmFileListGeneratorBase> Next;
+};
+
+class cmFileList
+{
+public:
+ cmFileList(): First(), Last(0) {}
+ virtual ~cmFileList() {}
+ cmFileList& operator/(cmFileListGeneratorBase const& rhs)
+ {
+ if(this->Last)
+ {
+ this->Last = this->Last->SetNext(rhs);
+ }
+ else
+ {
+ this->First = rhs.Clone();
+ this->Last = this->First.get();
+ }
+ return *this;
+ }
+ bool Search()
+ {
+ if(this->First.get())
+ {
+ return this->First->Search(*this);
+ }
+ return false;
+ }
+private:
+ virtual bool Visit(std::string const& fullPath) = 0;
+ friend class cmFileListGeneratorBase;
+ cmsys::auto_ptr<cmFileListGeneratorBase> First;
+ cmFileListGeneratorBase* Last;
+};
+
+class cmFindPackageFileList: public cmFileList
+{
+public:
+ cmFindPackageFileList(cmFindPackageCommand* fpc,
+ bool use_suffixes = true):
+ cmFileList(), FPC(fpc), UseSuffixes(use_suffixes) {}
+private:
+ bool Visit(std::string const& fullPath)
+ {
+ if(this->UseSuffixes)
+ {
+ return this->FPC->SearchDirectory(fullPath);
+ }
+ else
+ {
+ return this->FPC->CheckDirectory(fullPath);
+ }
+ }
+ cmFindPackageCommand* FPC;
+ bool UseSuffixes;
+};
+
+bool cmFileListGeneratorBase::Search(cmFileList& listing)
+{
+ return this->Search("", listing);
+}
+
+cmFileListGeneratorBase*
+cmFileListGeneratorBase::SetNext(cmFileListGeneratorBase const& next)
+{
+ this->Next = next.Clone();
+ return this->Next.get();
+}
+
+bool cmFileListGeneratorBase::Consider(std::string const& fullPath,
+ cmFileList& listing)
+{
+ if(this->Next.get())
+ {
+ return this->Next->Search(fullPath + "/", listing);
+ }
+ else
+ {
+ return listing.Visit(fullPath + "/");
+ }
+}
+
+class cmFileListGeneratorFixed: public cmFileListGeneratorBase
+{
+public:
+ cmFileListGeneratorFixed(std::string const& str):
+ cmFileListGeneratorBase(), String(str) {}
+ cmFileListGeneratorFixed(cmFileListGeneratorFixed const& r):
+ cmFileListGeneratorBase(), String(r.String) {}
+private:
+ std::string String;
+ virtual bool Search(std::string const& parent, cmFileList& lister)
+ {
+ std::string fullPath = parent + this->String;
+ return this->Consider(fullPath, lister);
+ }
+ virtual cmsys::auto_ptr<cmFileListGeneratorBase> Clone() const
+ {
+ cmsys::auto_ptr<cmFileListGeneratorBase>
+ g(new cmFileListGeneratorFixed(*this));
+ return g;
+ }
+};
+
+class cmFileListGeneratorEnumerate: public cmFileListGeneratorBase
+{
+public:
+ cmFileListGeneratorEnumerate(std::vector<std::string> const& v):
+ cmFileListGeneratorBase(), Vector(v) {}
+ cmFileListGeneratorEnumerate(cmFileListGeneratorEnumerate const& r):
+ cmFileListGeneratorBase(), Vector(r.Vector) {}
+private:
+ std::vector<std::string> const& Vector;
+ virtual bool Search(std::string const& parent, cmFileList& lister)
+ {
+ for(std::vector<std::string>::const_iterator i = this->Vector.begin();
+ i != this->Vector.end(); ++i)
+ {
+ if(this->Consider(parent + *i, lister))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ virtual cmsys::auto_ptr<cmFileListGeneratorBase> Clone() const
+ {
+ cmsys::auto_ptr<cmFileListGeneratorBase>
+ g(new cmFileListGeneratorEnumerate(*this));
+ return g;
+ }
+};
+
+class cmFileListGeneratorProject: public cmFileListGeneratorBase
+{
+public:
+ cmFileListGeneratorProject(std::vector<std::string> const& names):
+ cmFileListGeneratorBase(), Names(names) {}
+ cmFileListGeneratorProject(cmFileListGeneratorProject const& r):
+ cmFileListGeneratorBase(), Names(r.Names) {}
+private:
+ std::vector<std::string> const& Names;
+ virtual bool Search(std::string const& parent, cmFileList& lister)
+ {
+ // Construct a list of matches.
+ std::vector<std::string> matches;
+ cmsys::Directory d;
+ d.Load(parent.c_str());
+ for(unsigned long i=0; i < d.GetNumberOfFiles(); ++i)
+ {
+ const char* fname = d.GetFile(i);
+ if(strcmp(fname, ".") == 0 ||
+ strcmp(fname, "..") == 0)
+ {
+ continue;
+ }
+ for(std::vector<std::string>::const_iterator ni = this->Names.begin();
+ ni != this->Names.end(); ++ni)
+ {
+ if(cmsysString_strncasecmp(fname, ni->c_str(),
+ ni->length()) == 0)
+ {
+ matches.push_back(fname);
+ }
+ }
+ }
+
+ for(std::vector<std::string>::const_iterator i = matches.begin();
+ i != matches.end(); ++i)
+ {
+ if(this->Consider(parent + *i, lister))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ virtual cmsys::auto_ptr<cmFileListGeneratorBase> Clone() const
+ {
+ cmsys::auto_ptr<cmFileListGeneratorBase>
+ g(new cmFileListGeneratorProject(*this));
+ return g;
+ }
+};
+
+class cmFileListGeneratorMacProject: public cmFileListGeneratorBase
+{
+public:
+ cmFileListGeneratorMacProject(std::vector<std::string> const& names,
+ const char* ext):
+ cmFileListGeneratorBase(), Names(names), Extension(ext) {}
+ cmFileListGeneratorMacProject(cmFileListGeneratorMacProject const& r):
+ cmFileListGeneratorBase(), Names(r.Names), Extension(r.Extension) {}
+private:
+ std::vector<std::string> const& Names;
+ std::string Extension;
+ virtual bool Search(std::string const& parent, cmFileList& lister)
+ {
+ // Construct a list of matches.
+ std::vector<std::string> matches;
+ cmsys::Directory d;
+ d.Load(parent.c_str());
+ for(unsigned long i=0; i < d.GetNumberOfFiles(); ++i)
+ {
+ const char* fname = d.GetFile(i);
+ if(strcmp(fname, ".") == 0 ||
+ strcmp(fname, "..") == 0)
+ {
+ continue;
+ }
+ for(std::vector<std::string>::const_iterator ni = this->Names.begin();
+ ni != this->Names.end(); ++ni)
+ {
+ std::string name = *ni;
+ name += this->Extension;
+ if(cmsysString_strcasecmp(fname, name.c_str()) == 0)
+ {
+ matches.push_back(fname);
+ }
+ }
+ }
+
+ for(std::vector<std::string>::const_iterator i = matches.begin();
+ i != matches.end(); ++i)
+ {
+ if(this->Consider(parent + *i, lister))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ virtual cmsys::auto_ptr<cmFileListGeneratorBase> Clone() const
+ {
+ cmsys::auto_ptr<cmFileListGeneratorBase>
+ g(new cmFileListGeneratorMacProject(*this));
+ return g;
+ }
+};
+
+class cmFileListGeneratorCaseInsensitive: public cmFileListGeneratorBase
+{
+public:
+ cmFileListGeneratorCaseInsensitive(std::string const& str):
+ cmFileListGeneratorBase(), String(str) {}
+ cmFileListGeneratorCaseInsensitive(
+ cmFileListGeneratorCaseInsensitive const& r):
+ cmFileListGeneratorBase(), String(r.String) {}
+private:
+ std::string String;
+ virtual bool Search(std::string const& parent, cmFileList& lister)
+ {
+ // Look for matching files.
+ std::vector<std::string> matches;
+ cmsys::Directory d;
+ d.Load(parent.c_str());
+ for(unsigned long i=0; i < d.GetNumberOfFiles(); ++i)
+ {
+ const char* fname = d.GetFile(i);
+ if(strcmp(fname, ".") == 0 ||
+ strcmp(fname, "..") == 0)
+ {
+ continue;
+ }
+ if(cmsysString_strcasecmp(fname, this->String.c_str()) == 0)
+ {
+ if(this->Consider(parent + fname, lister))
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ virtual cmsys::auto_ptr<cmFileListGeneratorBase> Clone() const
+ {
+ cmsys::auto_ptr<cmFileListGeneratorBase>
+ g(new cmFileListGeneratorCaseInsensitive(*this));
+ return g;
+ }
+};
+
+class cmFileListGeneratorGlob: public cmFileListGeneratorBase
+{
+public:
+ cmFileListGeneratorGlob(std::string const& str):
+ cmFileListGeneratorBase(), Pattern(str) {}
+ cmFileListGeneratorGlob(cmFileListGeneratorGlob const& r):
+ cmFileListGeneratorBase(), Pattern(r.Pattern) {}
+private:
+ std::string Pattern;
+ virtual bool Search(std::string const& parent, cmFileList& lister)
+ {
+ // Glob the set of matching files.
+ std::string expr = parent;
+ expr += this->Pattern;
+ cmsys::Glob g;
+ if(!g.FindFiles(expr))
+ {
+ return false;
+ }
+ std::vector<std::string> const& files = g.GetFiles();
+
+ // Look for directories among the matches.
+ for(std::vector<std::string>::const_iterator fi = files.begin();
+ fi != files.end(); ++fi)
+ {
+ if(cmSystemTools::FileIsDirectory(fi->c_str()))
+ {
+ if(this->Consider(*fi, lister))
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ virtual cmsys::auto_ptr<cmFileListGeneratorBase> Clone() const
+ {
+ cmsys::auto_ptr<cmFileListGeneratorBase>
+ g(new cmFileListGeneratorGlob(*this));
+ return g;
+ }
+};
+
+//----------------------------------------------------------------------------
+bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
+{
+ assert(!prefix_in.empty() && prefix_in[prefix_in.size()-1] == '/');
+ if(this->DebugMode)
+ {
+ fprintf(stderr, "Checking prefix [%s]\n", prefix_in.c_str());
+ }
+
+ // Skip this if the prefix does not exist.
+ if(!cmSystemTools::FileIsDirectory(prefix_in.c_str()))
+ {
+ return false;
+ }
+
+ // PREFIX/ (useful on windows or in build trees)
+ if(this->SearchDirectory(prefix_in))
+ {
+ return true;
+ }
+
+ // Strip the trailing slash because the path generator is about to
+ // add one.
+ std::string prefix = prefix_in.substr(0, prefix_in.size()-1);
+
+ // PREFIX/(cmake|CMake)/ (useful on windows or in build trees)
+ {
+ cmFindPackageFileList lister(this);
+ lister
+ / cmFileListGeneratorFixed(prefix)
+ / cmFileListGeneratorCaseInsensitive("cmake");
+ if(lister.Search())
+ {
+ return true;
+ }
+ }
+
+ // PREFIX/(Foo|foo|FOO).*/
+ {
+ cmFindPackageFileList lister(this);
+ lister
+ / cmFileListGeneratorFixed(prefix)
+ / cmFileListGeneratorProject(this->Names);
+ if(lister.Search())
+ {
+ return true;
+ }
+ }
+
+ // PREFIX/(Foo|foo|FOO).*/(cmake|CMake)/
+ {
+ cmFindPackageFileList lister(this);
+ lister
+ / cmFileListGeneratorFixed(prefix)
+ / cmFileListGeneratorProject(this->Names)
+ / cmFileListGeneratorCaseInsensitive("cmake");
+ if(lister.Search())
+ {
+ return true;
+ }
+ }
+
+ // Construct list of common install locations (lib and share).
+ std::vector<std::string> common;
+ if(!this->LibraryArchitecture.empty())
+ {
+ common.push_back("lib/"+this->LibraryArchitecture);
+ }
+ if(this->UseLib64Paths)
+ {
+ common.push_back("lib64");
+ }
+ common.push_back("lib");
+ common.push_back("share");
+
+ // PREFIX/(lib/ARCH|lib|share)/cmake/(Foo|foo|FOO).*/
+ {
+ cmFindPackageFileList lister(this);
+ lister
+ / cmFileListGeneratorFixed(prefix)
+ / cmFileListGeneratorEnumerate(common)
+ / cmFileListGeneratorFixed("cmake")
+ / cmFileListGeneratorProject(this->Names);
+ if(lister.Search())
+ {
+ return true;
+ }
+ }
+
+ // PREFIX/(lib/ARCH|lib|share)/(Foo|foo|FOO).*/
+ {
+ cmFindPackageFileList lister(this);
+ lister
+ / cmFileListGeneratorFixed(prefix)
+ / cmFileListGeneratorEnumerate(common)
+ / cmFileListGeneratorProject(this->Names);
+ if(lister.Search())
+ {
+ return true;
+ }
+ }
+
+ // PREFIX/(lib/ARCH|lib|share)/(Foo|foo|FOO).*/(cmake|CMake)/
+ {
+ cmFindPackageFileList lister(this);
+ lister
+ / cmFileListGeneratorFixed(prefix)
+ / cmFileListGeneratorEnumerate(common)
+ / cmFileListGeneratorProject(this->Names)
+ / cmFileListGeneratorCaseInsensitive("cmake");
+ if(lister.Search())
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmFindPackageCommand::SearchFrameworkPrefix(std::string const& prefix_in)
+{
+ assert(!prefix_in.empty() && prefix_in[prefix_in.size()-1] == '/');
+ if(this->DebugMode)
+ {
+ fprintf(stderr, "Checking framework prefix [%s]\n", prefix_in.c_str());
+ }
+
+ // Strip the trailing slash because the path generator is about to
+ // add one.
+ std::string prefix = prefix_in.substr(0, prefix_in.size()-1);
+
+ // <prefix>/Foo.framework/Resources/
+ {
+ cmFindPackageFileList lister(this);
+ lister
+ / cmFileListGeneratorFixed(prefix)
+ / cmFileListGeneratorMacProject(this->Names, ".framework")
+ / cmFileListGeneratorFixed("Resources");
+ if(lister.Search())
+ {
+ return true;
+ }
+ }
+ // <prefix>/Foo.framework/Resources/CMake/
+ {
+ cmFindPackageFileList lister(this);
+ lister
+ / cmFileListGeneratorFixed(prefix)
+ / cmFileListGeneratorMacProject(this->Names, ".framework")
+ / cmFileListGeneratorFixed("Resources")
+ / cmFileListGeneratorCaseInsensitive("cmake");
+ if(lister.Search())
+ {
+ return true;
+ }
+ }
+
+ // <prefix>/Foo.framework/Versions/*/Resources/
+ {
+ cmFindPackageFileList lister(this);
+ lister
+ / cmFileListGeneratorFixed(prefix)
+ / cmFileListGeneratorMacProject(this->Names, ".framework")
+ / cmFileListGeneratorFixed("Versions")
+ / cmFileListGeneratorGlob("*/Resources");
+ if(lister.Search())
+ {
+ return true;
+ }
+ }
+
+ // <prefix>/Foo.framework/Versions/*/Resources/CMake/
+ {
+ cmFindPackageFileList lister(this);
+ lister
+ / cmFileListGeneratorFixed(prefix)
+ / cmFileListGeneratorMacProject(this->Names, ".framework")
+ / cmFileListGeneratorFixed("Versions")
+ / cmFileListGeneratorGlob("*/Resources")
+ / cmFileListGeneratorCaseInsensitive("cmake");
+ if(lister.Search())
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmFindPackageCommand::SearchAppBundlePrefix(std::string const& prefix_in)
+{
+ assert(!prefix_in.empty() && prefix_in[prefix_in.size()-1] == '/');
+ if(this->DebugMode)
+ {
+ fprintf(stderr, "Checking bundle prefix [%s]\n", prefix_in.c_str());
+ }
+
+ // Strip the trailing slash because the path generator is about to
+ // add one.
+ std::string prefix = prefix_in.substr(0, prefix_in.size()-1);
+
+ // <prefix>/Foo.app/Contents/Resources
+ {
+ cmFindPackageFileList lister(this);
+ lister
+ / cmFileListGeneratorFixed(prefix)
+ / cmFileListGeneratorMacProject(this->Names, ".app")
+ / cmFileListGeneratorFixed("Contents/Resources");
+ if(lister.Search())
+ {
+ return true;
+ }
+ }
+
+ // <prefix>/Foo.app/Contents/Resources/CMake
+ {
+ cmFindPackageFileList lister(this);
+ lister
+ / cmFileListGeneratorFixed(prefix)
+ / cmFileListGeneratorMacProject(this->Names, ".app")
+ / cmFileListGeneratorFixed("Contents/Resources")
+ / cmFileListGeneratorCaseInsensitive("cmake");
+ if(lister.Search())
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+// TODO: Debug cmsys::Glob double slash problem.
diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h
new file mode 100644
index 000000000..c3801220d
--- /dev/null
+++ b/Source/cmFindPackageCommand.h
@@ -0,0 +1,154 @@
+/*============================================================================
+ 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 cmFindPackageCommand_h
+#define cmFindPackageCommand_h
+
+#include "cmFindCommon.h"
+
+class cmFindPackageFileList;
+
+/** \class cmFindPackageCommand
+ * \brief Load settings from an external project.
+ *
+ * cmFindPackageCommand
+ */
+class cmFindPackageCommand : public cmFindCommon
+{
+public:
+ cmFindPackageCommand();
+
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmFindPackageCommand;
+ }
+
+ /**
+ * 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 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;
+
+ cmTypeMacro(cmFindPackageCommand, cmFindCommon);
+protected:
+ virtual void GenerateDocumentation();
+private:
+ 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 RestoreFindDefinitions();
+ bool HandlePackageMode();
+ bool FindConfig();
+ bool FindPrefixedConfig();
+ bool FindFrameworkConfig();
+ bool FindAppBundleConfig();
+ enum PolicyScopeRule { NoPolicyScope, DoPolicyScope };
+ bool ReadListFile(const char* f, PolicyScopeRule psr);
+ 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 LoadPackageRegistryWinUser();
+ void LoadPackageRegistryWinSystem();
+ void LoadPackageRegistryWin(bool user, unsigned int view);
+ bool CheckPackageRegistryEntry(std::istream& is);
+ bool SearchDirectory(std::string const& dir);
+ bool CheckDirectory(std::string const& dir);
+ bool FindConfigFile(std::string const& dir, std::string& file);
+ bool CheckVersion(std::string const& config_file);
+ bool CheckVersionFile(std::string const& version_file,
+ std::string& result_version);
+ bool SearchPrefix(std::string const& prefix);
+ bool SearchFrameworkPrefix(std::string const& prefix_in);
+ bool SearchAppBundlePrefix(std::string const& prefix_in);
+
+ friend class cmFindPackageFileList;
+
+ struct OriginalDef { bool exists; std::string value; };
+ std::map<cmStdString, OriginalDef> OriginalDefs;
+
+ std::string CommandDocumentation;
+ cmStdString Name;
+ cmStdString Variable;
+ cmStdString Version;
+ unsigned int VersionMajor;
+ unsigned int VersionMinor;
+ unsigned int VersionPatch;
+ unsigned int VersionTweak;
+ unsigned int VersionCount;
+ bool VersionExact;
+ cmStdString FileFound;
+ cmStdString VersionFound;
+ unsigned int VersionFoundMajor;
+ unsigned int VersionFoundMinor;
+ unsigned int VersionFoundPatch;
+ unsigned int VersionFoundTweak;
+ unsigned int VersionFoundCount;
+ unsigned int 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;
+ std::string LibraryArchitecture;
+ std::vector<std::string> Names;
+ std::vector<std::string> Configs;
+ std::set<std::string> IgnoredPaths;
+
+ struct ConfigFileInfo { std::string filename; std::string version; };
+ std::vector<ConfigFileInfo> ConsideredConfigs;
+};
+
+#endif
diff --git a/Source/cmFindPathCommand.cxx b/Source/cmFindPathCommand.cxx
new file mode 100644
index 000000000..846d187cb
--- /dev/null
+++ b/Source/cmFindPathCommand.cxx
@@ -0,0 +1,240 @@
+/*============================================================================
+ 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 "cmFindPathCommand.h"
+#include "cmCacheManager.h"
+
+#include <cmsys/Glob.hxx>
+
+cmFindPathCommand::cmFindPathCommand()
+{
+ this->EnvironmentPath = "INCLUDE";
+ 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", "");
+ 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 &)
+{
+ this->VariableDocumentation = "Path to a file.";
+ this->CMakePathName = "INCLUDE";
+ if(!this->ParseArguments(argsIn))
+ {
+ return false;
+ }
+ if(this->AlreadyInCache)
+ {
+ // If the user specifies the entry on the command line without a
+ // type we should add the type and docstring but keep the original
+ // value.
+ if(this->AlreadyInCacheWithoutMetaInfo)
+ {
+ this->Makefile->AddCacheDefinition(
+ this->VariableName.c_str(), "",
+ this->VariableDocumentation.c_str(),
+ (this->IncludeFileInPath ?
+ cmCacheManager::FILEPATH :cmCacheManager::PATH)
+ );
+ }
+ return true;
+ }
+
+ std::string result = this->FindHeader();
+ if(result.size() != 0)
+ {
+ this->Makefile->AddCacheDefinition
+ (this->VariableName.c_str(), result.c_str(),
+ this->VariableDocumentation.c_str(),
+ (this->IncludeFileInPath) ?
+ cmCacheManager::FILEPATH :cmCacheManager::PATH);
+ return true;
+ }
+ this->Makefile->AddCacheDefinition
+ (this->VariableName.c_str(),
+ (this->VariableName + "-NOTFOUND").c_str(),
+ this->VariableDocumentation.c_str(),
+ (this->IncludeFileInPath) ?
+ cmCacheManager::FILEPATH :cmCacheManager::PATH);
+ return true;
+}
+
+//----------------------------------------------------------------------------
+std::string cmFindPathCommand::FindHeader()
+{
+ std::string header;
+ if(this->SearchFrameworkFirst || this->SearchFrameworkOnly)
+ {
+ header = this->FindFrameworkHeader();
+ }
+ if(header.empty() && !this->SearchFrameworkOnly)
+ {
+ header = this->FindNormalHeader();
+ }
+ if(header.empty() && this->SearchFrameworkLast)
+ {
+ header = this->FindFrameworkHeader();
+ }
+ return header;
+}
+
+std::string
+cmFindPathCommand::FindHeaderInFramework(std::string const& file,
+ std::string const& dir)
+{
+ cmStdString fileName = file;
+ cmStdString frameWorkName;
+ cmStdString::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
+ if(pos != fileName.npos)
+ {
+ // remove the name from the slash;
+ fileName = fileName.substr(pos+1);
+ frameWorkName = file;
+ frameWorkName =
+ frameWorkName.substr(0, frameWorkName.size()-fileName.size()-1);
+ // if the framework has a path in it then just use the filename
+ if(frameWorkName.find("/") != frameWorkName.npos)
+ {
+ fileName = file;
+ frameWorkName = "";
+ }
+ if(frameWorkName.size())
+ {
+ std::string fpath = dir;
+ fpath += frameWorkName;
+ fpath += ".framework";
+ std::string intPath = fpath;
+ intPath += "/Headers/";
+ intPath += fileName;
+ if(cmSystemTools::FileExists(intPath.c_str()))
+ {
+ if(this->IncludeFileInPath)
+ {
+ return intPath;
+ }
+ return fpath;
+ }
+ }
+ }
+ // 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;
+ glob += "*.framework/Headers/";
+ glob += file;
+ cmsys::Glob globIt;
+ globIt.FindFiles(glob);
+ std::vector<std::string> files = globIt.GetFiles();
+ if(files.size())
+ {
+ cmStdString fheader = cmSystemTools::CollapseFullPath(files[0].c_str());
+ if(this->IncludeFileInPath)
+ {
+ return fheader;
+ }
+ fheader = cmSystemTools::GetFilenamePath(fheader);
+ return fheader;
+ }
+ return "";
+}
+
+//----------------------------------------------------------------------------
+std::string cmFindPathCommand::FindNormalHeader()
+{
+ std::string tryPath;
+ for(std::vector<std::string>::const_iterator ni = this->Names.begin();
+ ni != this->Names.end() ; ++ni)
+ {
+ for(std::vector<std::string>::const_iterator
+ p = this->SearchPaths.begin();
+ p != this->SearchPaths.end(); ++p)
+ {
+ tryPath = *p;
+ tryPath += *ni;
+ if(cmSystemTools::FileExists(tryPath.c_str()))
+ {
+ if(this->IncludeFileInPath)
+ {
+ return tryPath;
+ }
+ else
+ {
+ return *p;
+ }
+ }
+ }
+ }
+ return "";
+}
+
+//----------------------------------------------------------------------------
+std::string cmFindPathCommand::FindFrameworkHeader()
+{
+ for(std::vector<std::string>::const_iterator ni = this->Names.begin();
+ ni != this->Names.end() ; ++ni)
+ {
+ for(std::vector<std::string>::const_iterator
+ p = this->SearchPaths.begin();
+ p != this->SearchPaths.end(); ++p)
+ {
+ std::string fwPath = this->FindHeaderInFramework(*ni, *p);
+ if(!fwPath.empty())
+ {
+ return fwPath;
+ }
+ }
+ }
+ return "";
+}
diff --git a/Source/cmFindPathCommand.h b/Source/cmFindPathCommand.h
new file mode 100644
index 000000000..a61299011
--- /dev/null
+++ b/Source/cmFindPathCommand.h
@@ -0,0 +1,76 @@
+/*============================================================================
+ 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 cmFindPathCommand_h
+#define cmFindPathCommand_h
+
+#include "cmFindBase.h"
+
+
+/** \class cmFindPathCommand
+ * \brief Define a command to search for a library.
+ *
+ * cmFindPathCommand is used to define a CMake variable
+ * that specifies a library. The command searches for a given
+ * file in a list of directories.
+ */
+class cmFindPathCommand : public cmFindBase
+{
+public:
+ cmFindPathCommand();
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmFindPathCommand;
+ }
+
+ /**
+ * 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 const char* GetName() const {return "find_path";}
+
+ /**
+ * Succinct documentation.
+ */
+ virtual const char* GetTerseDocumentation() const
+ {
+ return "Find the directory containing a file.";
+ }
+
+ cmTypeMacro(cmFindPathCommand, cmFindBase);
+ bool IncludeFileInPath;
+protected:
+ virtual void GenerateDocumentation();
+private:
+ std::string FindHeaderInFramework(std::string const& file,
+ std::string const& dir);
+ std::string FindHeader();
+ std::string FindNormalHeader();
+ std::string FindFrameworkHeader();
+};
+
+
+
+#endif
diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx
new file mode 100644
index 000000000..00f5419c2
--- /dev/null
+++ b/Source/cmFindProgramCommand.cxx
@@ -0,0 +1,191 @@
+/*============================================================================
+ 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 "cmFindProgramCommand.h"
+#include "cmCacheManager.h"
+#include <stdlib.h>
+
+#if defined(__APPLE__)
+#include <CoreFoundation/CoreFoundation.h>
+#endif
+
+void cmFindProgramCommand::GenerateDocumentation()
+{
+ 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");
+}
+
+// cmFindProgramCommand
+bool cmFindProgramCommand
+::InitialPass(std::vector<std::string> const& argsIn, cmExecutionStatus &)
+{
+ this->VariableDocumentation = "Path to a program.";
+ this->CMakePathName = "PROGRAM";
+ // call cmFindBase::ParseArguments
+ if(!this->ParseArguments(argsIn))
+ {
+ return false;
+ }
+ if(this->AlreadyInCache)
+ {
+ // If the user specifies the entry on the command line without a
+ // type we should add the type and docstring but keep the original
+ // value.
+ if(this->AlreadyInCacheWithoutMetaInfo)
+ {
+ this->Makefile->AddCacheDefinition(this->VariableName.c_str(), "",
+ this->VariableDocumentation.c_str(),
+ cmCacheManager::FILEPATH);
+ }
+ return true;
+ }
+
+ std::string result = FindProgram(this->Names);
+ if(result != "")
+ {
+ // Save the value in the cache
+ this->Makefile->AddCacheDefinition(this->VariableName.c_str(),
+ result.c_str(),
+ this->VariableDocumentation.c_str(),
+ cmCacheManager::FILEPATH);
+
+ return true;
+ }
+ this->Makefile->AddCacheDefinition(this->VariableName.c_str(),
+ (this->VariableName + "-NOTFOUND").c_str(),
+ this->VariableDocumentation.c_str(),
+ cmCacheManager::FILEPATH);
+ return true;
+}
+
+std::string cmFindProgramCommand::FindProgram(std::vector<std::string> names)
+{
+ std::string program = "";
+
+ if(this->SearchAppBundleFirst || this->SearchAppBundleOnly)
+ {
+ program = FindAppBundle(names);
+ }
+ if(program.empty() && !this->SearchAppBundleOnly)
+ {
+ program = cmSystemTools::FindProgram(names, this->SearchPaths, true);
+ }
+
+ if(program.empty() && this->SearchAppBundleLast)
+ {
+ program = this->FindAppBundle(names);
+ }
+ return program;
+}
+
+std::string cmFindProgramCommand
+::FindAppBundle(std::vector<std::string> names)
+{
+ for(std::vector<std::string>::const_iterator name = names.begin();
+ name != names.end() ; ++name)
+ {
+
+ std::string appName = *name + std::string(".app");
+ std::string appPath = cmSystemTools::FindDirectory(appName.c_str(),
+ this->SearchPaths,
+ true);
+
+ if ( !appPath.empty() )
+ {
+ std::string executable = GetBundleExecutable(appPath);
+ if (!executable.empty())
+ {
+ return cmSystemTools::CollapseFullPath(executable.c_str());
+ }
+ }
+ }
+
+ // Couldn't find app bundle
+ return "";
+}
+
+std::string cmFindProgramCommand::GetBundleExecutable(std::string bundlePath)
+{
+ std::string executable = "";
+ (void)bundlePath;
+#if defined(__APPLE__)
+ // Started with an example on developer.apple.com about finding bundles
+ // and modified from that.
+
+ // Get a CFString of the app bundle path
+ // XXX - Is it safe to assume everything is in UTF8?
+ CFStringRef bundlePathCFS =
+ CFStringCreateWithCString(kCFAllocatorDefault ,
+ bundlePath.c_str(), kCFStringEncodingUTF8 );
+
+ // Make a CFURLRef from the CFString representation of the
+ // bundle’s path.
+ CFURLRef bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
+ bundlePathCFS,
+ kCFURLPOSIXPathStyle,
+ true );
+
+ // Make a bundle instance using the URLRef.
+ CFBundleRef appBundle = CFBundleCreate( kCFAllocatorDefault, bundleURL );
+
+ // returned executableURL is relative to <appbundle>/Contents/MacOS/
+ CFURLRef executableURL = CFBundleCopyExecutableURL(appBundle);
+
+ if (executableURL != NULL)
+ {
+ const int MAX_OSX_PATH_SIZE = 1024;
+ char buffer[MAX_OSX_PATH_SIZE];
+
+ // Convert the CFString to a C string
+ CFStringGetCString( CFURLGetString(executableURL), buffer,
+ MAX_OSX_PATH_SIZE, kCFStringEncodingUTF8 );
+
+ // And finally to a c++ string
+ executable = bundlePath + "/Contents/MacOS/" + std::string(buffer);
+ // Only release CFURLRef if it's not null
+ CFRelease( executableURL );
+ }
+
+ // Any CF objects returned from functions with "create" or
+ // "copy" in their names must be released by us!
+ CFRelease( bundlePathCFS );
+ CFRelease( bundleURL );
+ CFRelease( appBundle );
+#endif
+
+ return executable;
+}
+
diff --git a/Source/cmFindProgramCommand.h b/Source/cmFindProgramCommand.h
new file mode 100644
index 000000000..c1b14f912
--- /dev/null
+++ b/Source/cmFindProgramCommand.h
@@ -0,0 +1,75 @@
+/*============================================================================
+ 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 cmFindProgramCommand_h
+#define cmFindProgramCommand_h
+
+#include "cmFindBase.h"
+
+/** \class cmFindProgramCommand
+ * \brief Define a command to search for an executable program.
+ *
+ * cmFindProgramCommand is used to define a CMake variable
+ * that specifies an executable program. The command searches
+ * in the current path (e.g., PATH environment variable) for
+ * an executable that matches one of the supplied names.
+ */
+class cmFindProgramCommand : public cmFindBase
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmFindProgramCommand;
+ }
+
+ /**
+ * 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 const char* GetName() const { return "find_program";}
+
+ /**
+ * Succinct documentation.
+ */
+ virtual const char* GetTerseDocumentation() const
+ {
+ return "Find an executable 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 GetBundleExecutable(std::string bundlePath);
+
+};
+
+
+
+#endif
diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx
new file mode 100644
index 000000000..74966c9c8
--- /dev/null
+++ b/Source/cmForEachCommand.cxx
@@ -0,0 +1,246 @@
+/*============================================================================
+ 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 "cmForEachCommand.h"
+
+#include <cmsys/auto_ptr.hxx>
+
+bool cmForEachFunctionBlocker::
+IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf,
+ cmExecutionStatus &inStatus)
+{
+ if (!cmSystemTools::Strucmp(lff.Name.c_str(),"foreach"))
+ {
+ // record the number of nested foreach commands
+ this->Depth++;
+ }
+ else if (!cmSystemTools::Strucmp(lff.Name.c_str(),"endforeach"))
+ {
+ // if this is the endofreach for this statement
+ if (!this->Depth)
+ {
+ // Remove the function blocker for this scope or bail.
+ cmsys::auto_ptr<cmFunctionBlocker>
+ fb(mf.RemoveFunctionBlocker(this, lff));
+ if(!fb.get()) { return false; }
+
+ // at end of for each execute recorded commands
+ // store the old value
+ std::string oldDef;
+ if (mf.GetDefinition(this->Args[0].c_str()))
+ {
+ oldDef = mf.GetDefinition(this->Args[0].c_str());
+ }
+ 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());
+ // Invoke all the functions that were collected in the block.
+ cmExecutionStatus status;
+ for(unsigned int c = 0; c < this->Functions.size(); ++c)
+ {
+ status.Clear();
+ mf.ExecuteCommand(this->Functions[c],status);
+ if (status.GetReturnInvoked())
+ {
+ inStatus.SetReturnInvoked(true);
+ // restore the variable to its prior value
+ mf.AddDefinition(this->Args[0].c_str(),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());
+ return true;
+ }
+ if(cmSystemTools::GetFatalErrorOccured() )
+ {
+ return true;
+ }
+ }
+ }
+ // restore the variable to its prior value
+ mf.AddDefinition(this->Args[0].c_str(),oldDef.c_str());
+ return true;
+ }
+ else
+ {
+ // close out a nested foreach
+ this->Depth--;
+ }
+ }
+
+ // record the command
+ this->Functions.push_back(lff);
+
+ // always return true
+ return true;
+}
+
+bool cmForEachFunctionBlocker::
+ShouldRemove(const cmListFileFunction& lff, cmMakefile& mf)
+{
+ if(!cmSystemTools::Strucmp(lff.Name.c_str(),"endforeach"))
+ {
+ std::vector<std::string> expandedArguments;
+ mf.ExpandArguments(lff.Arguments, expandedArguments);
+ // if the endforeach has arguments then make sure
+ // they match the begin foreach arguments
+ if ((expandedArguments.empty() ||
+ (expandedArguments[0] == this->Args[0])))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool cmForEachCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 1)
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+ if(args.size() > 1 && args[1] == "IN")
+ {
+ return this->HandleInMode(args);
+ }
+
+ // create a function blocker
+ cmForEachFunctionBlocker *f = new cmForEachFunctionBlocker();
+ if ( args.size() > 1 )
+ {
+ if ( args[1] == "RANGE" )
+ {
+ int start = 0;
+ int stop = 0;
+ int step = 0;
+ if ( args.size() == 3 )
+ {
+ stop = atoi(args[2].c_str());
+ }
+ if ( args.size() == 4 )
+ {
+ start = atoi(args[2].c_str());
+ stop = atoi(args[3].c_str());
+ }
+ if ( args.size() == 5 )
+ {
+ start = atoi(args[2].c_str());
+ stop = atoi(args[3].c_str());
+ step = atoi(args[4].c_str());
+ }
+ if ( step == 0 )
+ {
+ if ( start > stop )
+ {
+ step = -1;
+ }
+ else
+ {
+ step = 1;
+ }
+ }
+ if (
+ (start > stop && step > 0) ||
+ (start < stop && step < 0) ||
+ step == 0
+ )
+ {
+ cmOStringStream str;
+ str << "called with incorrect range specification: start ";
+ str << start << ", stop " << stop << ", step " << step;
+ this->SetError(str.str().c_str());
+ return false;
+ }
+ std::vector<std::string> range;
+ char buffer[100];
+ range.push_back(args[0]);
+ int cc;
+ for ( cc = start; ; cc += step )
+ {
+ if ( (step > 0 && cc > stop) || (step < 0 && cc < stop) )
+ {
+ break;
+ }
+ sprintf(buffer, "%d", cc);
+ range.push_back(buffer);
+ if ( cc == stop )
+ {
+ break;
+ }
+ }
+ f->Args = range;
+ }
+ else
+ {
+ f->Args = args;
+ }
+ }
+ else
+ {
+ f->Args = args;
+ }
+ this->Makefile->AddFunctionBlocker(f);
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmForEachCommand::HandleInMode(std::vector<std::string> const& args)
+{
+ cmsys::auto_ptr<cmForEachFunctionBlocker> f(new cmForEachFunctionBlocker());
+ f->Args.push_back(args[0]);
+
+ enum Doing { DoingNone, DoingLists, DoingItems };
+ Doing doing = DoingNone;
+ for(unsigned int i=2; i < args.size(); ++i)
+ {
+ if(doing == DoingItems)
+ {
+ f->Args.push_back(args[i]);
+ }
+ else if(args[i] == "LISTS")
+ {
+ doing = DoingLists;
+ }
+ else if(args[i] == "ITEMS")
+ {
+ doing = DoingItems;
+ }
+ else if(doing == DoingLists)
+ {
+ const char* value = this->Makefile->GetDefinition(args[i].c_str());
+ if(value && *value)
+ {
+ cmSystemTools::ExpandListArgument(value, f->Args, true);
+ }
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "Unknown argument:\n" << " " << args[i] << "\n";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return true;
+ }
+ }
+
+ this->Makefile->AddFunctionBlocker(f.release()); // TODO: pass auto_ptr
+ return true;
+}
diff --git a/Source/cmForEachCommand.h b/Source/cmForEachCommand.h
new file mode 100644
index 000000000..ae50005be
--- /dev/null
+++ b/Source/cmForEachCommand.h
@@ -0,0 +1,116 @@
+/*============================================================================
+ 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 cmForEachCommand_h
+#define cmForEachCommand_h
+
+#include "cmCommand.h"
+#include "cmFunctionBlocker.h"
+#include "cmListFileCache.h"
+
+class cmForEachFunctionBlocker : public cmFunctionBlocker
+{
+public:
+ cmForEachFunctionBlocker() {this->Depth = 0;}
+ virtual ~cmForEachFunctionBlocker() {}
+ virtual bool IsFunctionBlocked(const cmListFileFunction& lff,
+ cmMakefile &mf,
+ cmExecutionStatus &);
+ virtual bool ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf);
+
+ std::vector<std::string> Args;
+ std::vector<cmListFileFunction> Functions;
+private:
+ int Depth;
+};
+
+/// Starts foreach() ... endforeach() block
+class cmForEachCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmForEachCommand;
+ }
+
+ /**
+ * 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 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."
+ ;
+ }
+
+ cmTypeMacro(cmForEachCommand, cmCommand);
+private:
+ bool HandleInMode(std::vector<std::string> const& args);
+};
+
+
+#endif
diff --git a/Source/cmFunctionBlocker.h b/Source/cmFunctionBlocker.h
new file mode 100644
index 000000000..9ee0b5c2d
--- /dev/null
+++ b/Source/cmFunctionBlocker.h
@@ -0,0 +1,48 @@
+/*============================================================================
+ 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 cmFunctionBlocker_h
+#define cmFunctionBlocker_h
+
+#include "cmStandardIncludes.h"
+#include "cmExecutionStatus.h"
+#include "cmListFileCache.h"
+class cmMakefile;
+
+class cmFunctionBlocker
+{
+public:
+ /**
+ * should a function be blocked
+ */
+ virtual bool IsFunctionBlocked(const cmListFileFunction& lff,
+ cmMakefile&mf,
+ cmExecutionStatus &status) = 0;
+
+ /**
+ * should this function blocker be removed, useful when one function adds a
+ * blocker and another must remove it
+ */
+ virtual bool ShouldRemove(const cmListFileFunction&,
+ cmMakefile&) {return false;}
+
+ virtual ~cmFunctionBlocker() {}
+
+ /** Set/Get the context in which this blocker is created. */
+ void SetStartingContext(cmListFileContext const& lfc)
+ { this->StartingContext = lfc; }
+ cmListFileContext const& GetStartingContext()
+ { return this->StartingContext; }
+private:
+ cmListFileContext StartingContext;
+};
+
+#endif
diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx
new file mode 100644
index 000000000..ce36145f4
--- /dev/null
+++ b/Source/cmFunctionCommand.cxx
@@ -0,0 +1,300 @@
+/*============================================================================
+ 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 "cmFunctionCommand.h"
+
+#include "cmake.h"
+
+// define the class for function commands
+class cmFunctionHelperCommand : public cmCommand
+{
+public:
+ cmFunctionHelperCommand() {}
+
+ ///! clean up any memory allocated by the function
+ ~cmFunctionHelperCommand() {};
+
+ /**
+ * This is used to avoid including this command
+ * in documentation. This is mainly used by
+ * cmMacroHelperCommand and cmFunctionHelperCommand
+ * which cannot provide appropriate documentation.
+ */
+ virtual bool ShouldAppearInDocumentation() const
+ {
+ return false;
+ }
+
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ cmFunctionHelperCommand *newC = new cmFunctionHelperCommand;
+ // we must copy when we clone
+ newC->Args = this->Args;
+ newC->Functions = this->Functions;
+ newC->Policies = this->Policies;
+ return newC;
+ }
+
+ /**
+ * This determines if the command is invoked when in script mode.
+ */
+ virtual bool IsScriptable() const { return true; }
+
+ /**
+ * This is called when the command is first encountered in
+ * the CMakeLists.txt file.
+ */
+ virtual bool InvokeInitialPass(const std::vector<cmListFileArgument>& args,
+ cmExecutionStatus &);
+
+ virtual bool InitialPass(std::vector<std::string> const&,
+ 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();
+ }
+
+ cmTypeMacro(cmFunctionHelperCommand, cmCommand);
+
+ std::vector<std::string> Args;
+ std::vector<cmListFileFunction> Functions;
+ cmPolicies::PolicyMap Policies;
+};
+
+
+bool cmFunctionHelperCommand::InvokeInitialPass
+(const std::vector<cmListFileArgument>& args,
+ cmExecutionStatus & inStatus)
+{
+ // Expand the argument list to the function.
+ std::vector<std::string> expandedArgs;
+ this->Makefile->ExpandArguments(args, expandedArgs);
+
+ // make sure the number of arguments passed is at least the number
+ // required by the signature
+ if (expandedArgs.size() < this->Args.size() - 1)
+ {
+ std::string errorMsg =
+ "Function invoked with incorrect arguments for function named: ";
+ errorMsg += this->Args[0];
+ this->SetError(errorMsg.c_str());
+ 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);
+
+ // set the value of argc
+ cmOStringStream strStream;
+ strStream << expandedArgs.size();
+ this->Makefile->AddDefinition("ARGC",strStream.str().c_str());
+ this->Makefile->MarkVariableAsUsed("ARGC");
+
+ // set the values for ARGV0 ARGV1 ...
+ for (unsigned int t = 0; t < expandedArgs.size(); ++t)
+ {
+ cmOStringStream tmpStream;
+ tmpStream << "ARGV" << t;
+ this->Makefile->AddDefinition(tmpStream.str().c_str(),
+ expandedArgs[t].c_str());
+ this->Makefile->MarkVariableAsUsed(tmpStream.str().c_str());
+ }
+
+ // define the formal arguments
+ for (unsigned int j = 1; j < this->Args.size(); ++j)
+ {
+ this->Makefile->AddDefinition(this->Args[j].c_str(),
+ 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 ++;
+ }
+ this->Makefile->AddDefinition("ARGV", argvDef.c_str());
+ this->Makefile->MarkVariableAsUsed("ARGV");
+ this->Makefile->AddDefinition("ARGN", argnDef.c_str());
+ this->Makefile->MarkVariableAsUsed("ARGN");
+
+ // Invoke all the functions that were collected in the block.
+ // for each function
+ for(unsigned int c = 0; c < this->Functions.size(); ++c)
+ {
+ cmExecutionStatus status;
+ if (!this->Makefile->ExecuteCommand(this->Functions[c],status) ||
+ status.GetNestedError())
+ {
+ // The error message should have already included the call stack
+ // so we do not need to report an error here.
+ lexScope.Quiet();
+ polScope.Quiet();
+ inStatus.SetNestedError(true);
+ return false;
+ }
+ if (status.GetReturnInvoked())
+ {
+ return true;
+ }
+ }
+
+ // pop scope on the makefile
+ return true;
+}
+
+bool cmFunctionFunctionBlocker::
+IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf,
+ cmExecutionStatus &)
+{
+ // record commands until we hit the ENDFUNCTION
+ // at the ENDFUNCTION call we shift gears and start looking for invocations
+ if(!cmSystemTools::Strucmp(lff.Name.c_str(),"function"))
+ {
+ this->Depth++;
+ }
+ else if(!cmSystemTools::Strucmp(lff.Name.c_str(),"endfunction"))
+ {
+ // 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;
+ 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);
+
+ // remove the function blocker now that the function is defined
+ mf.RemoveFunctionBlocker(this, lff);
+ return true;
+ }
+ else
+ {
+ // decrement for each nested function that ends
+ this->Depth--;
+ }
+ }
+
+ // if it wasn't an endfunction and we are not executing then we must be
+ // recording
+ this->Functions.push_back(lff);
+ return true;
+}
+
+
+bool cmFunctionFunctionBlocker::
+ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf)
+{
+ if(!cmSystemTools::Strucmp(lff.Name.c_str(),"endfunction"))
+ {
+ std::vector<std::string> expandedArguments;
+ mf.ExpandArguments(lff.Arguments, expandedArguments);
+ // if the endfunction has arguments then make sure
+ // they match the ones in the openeing function command
+ if ((expandedArguments.empty() ||
+ (expandedArguments[0] == this->Args[0])))
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool cmFunctionCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 1)
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ // 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);
+ }
+ this->Makefile->AddFunctionBlocker(f);
+ return true;
+}
+
diff --git a/Source/cmFunctionCommand.h b/Source/cmFunctionCommand.h
new file mode 100644
index 000000000..43c8e2983
--- /dev/null
+++ b/Source/cmFunctionCommand.h
@@ -0,0 +1,104 @@
+/*============================================================================
+ 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 cmFunctionCommand_h
+#define cmFunctionCommand_h
+
+#include "cmCommand.h"
+#include "cmFunctionBlocker.h"
+
+class cmFunctionFunctionBlocker : public cmFunctionBlocker
+{
+public:
+ cmFunctionFunctionBlocker() {this->Depth=0;}
+ virtual ~cmFunctionFunctionBlocker() {}
+ virtual bool IsFunctionBlocked(const cmListFileFunction&,
+ cmMakefile &mf,
+ cmExecutionStatus &);
+ virtual bool ShouldRemove(const cmListFileFunction&, cmMakefile &mf);
+
+ std::vector<std::string> Args;
+ std::vector<cmListFileFunction> Functions;
+ int Depth;
+};
+
+/// Starts function() ... endfunction() block
+class cmFunctionCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmFunctionCommand;
+ }
+
+ /**
+ * 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 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 argument past the last expected argument."
+ "\n"
+ "See the cmake_policy() command documentation for the behavior of "
+ "policies inside functions."
+ ;
+ }
+
+ cmTypeMacro(cmFunctionCommand, cmCommand);
+};
+
+
+#endif
diff --git a/Source/cmGeneratedFileStream.cxx b/Source/cmGeneratedFileStream.cxx
new file mode 100644
index 000000000..1a391ede9
--- /dev/null
+++ b/Source/cmGeneratedFileStream.cxx
@@ -0,0 +1,260 @@
+/*============================================================================
+ 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 "cmGeneratedFileStream.h"
+
+#include "cmSystemTools.h"
+
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+# include <cm_zlib.h>
+#endif
+
+//----------------------------------------------------------------------------
+cmGeneratedFileStream::cmGeneratedFileStream():
+ cmGeneratedFileStreamBase(), Stream()
+{
+}
+
+//----------------------------------------------------------------------------
+cmGeneratedFileStream::cmGeneratedFileStream(const char* name, bool quiet):
+ cmGeneratedFileStreamBase(name),
+ Stream(TempName.c_str())
+{
+ // Check if the file opened.
+ if(!*this && !quiet)
+ {
+ cmSystemTools::Error("Cannot open file for write: ",
+ this->TempName.c_str());
+ cmSystemTools::ReportLastSystemError("");
+ }
+}
+
+//----------------------------------------------------------------------------
+cmGeneratedFileStream::~cmGeneratedFileStream()
+{
+ // This is the first destructor called. Check the status of the
+ // stream and give the information to the private base. Next the
+ // stream will be destroyed which will close the temporary file.
+ // Finally the base destructor will be called to replace the
+ // destination file.
+ this->Okay = (*this)?true:false;
+}
+
+//----------------------------------------------------------------------------
+cmGeneratedFileStream&
+cmGeneratedFileStream::Open(const char* name, bool quiet, bool binaryFlag)
+{
+ // Store the file name and construct the temporary file name.
+ this->cmGeneratedFileStreamBase::Open(name);
+
+ // Open the temporary output file.
+ if ( binaryFlag )
+ {
+ this->Stream::open(this->TempName.c_str(),
+ std::ios::out | std::ios::binary);
+ }
+ else
+ {
+ this->Stream::open(this->TempName.c_str(), std::ios::out);
+ }
+
+ // Check if the file opened.
+ if(!*this && !quiet)
+ {
+ cmSystemTools::Error("Cannot open file for write: ",
+ this->TempName.c_str());
+ cmSystemTools::ReportLastSystemError("");
+ }
+ return *this;
+}
+
+//----------------------------------------------------------------------------
+bool
+cmGeneratedFileStream::Close()
+{
+ // Save whether the temporary output file is valid before closing.
+ this->Okay = (*this)?true:false;
+
+ // Close the temporary output file.
+ this->Stream::close();
+
+ // Remove the temporary file (possibly by renaming to the real file).
+ return this->cmGeneratedFileStreamBase::Close();
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratedFileStream::SetCopyIfDifferent(bool copy_if_different)
+{
+ this->CopyIfDifferent = copy_if_different;
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratedFileStream::SetCompression(bool compression)
+{
+ this->Compress = compression;
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratedFileStream::SetCompressionExtraExtension(bool ext)
+{
+ this->CompressExtraExtension = ext;
+}
+
+//----------------------------------------------------------------------------
+cmGeneratedFileStreamBase::cmGeneratedFileStreamBase():
+ Name(),
+ TempName(),
+ CopyIfDifferent(false),
+ Okay(false),
+ Compress(false),
+ CompressExtraExtension(true)
+{
+}
+
+//----------------------------------------------------------------------------
+cmGeneratedFileStreamBase::cmGeneratedFileStreamBase(const char* name):
+ Name(),
+ TempName(),
+ CopyIfDifferent(false),
+ Okay(false),
+ Compress(false),
+ CompressExtraExtension(true)
+{
+ this->Open(name);
+}
+
+//----------------------------------------------------------------------------
+cmGeneratedFileStreamBase::~cmGeneratedFileStreamBase()
+{
+ this->Close();
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratedFileStreamBase::Open(const char* name)
+{
+ // Save the original name of the file.
+ this->Name = name;
+
+ // Create the name of the temporary file.
+ this->TempName = name;
+#if defined(__VMS)
+ this->TempName += "_tmp";
+#else
+ this->TempName += ".tmp";
+#endif
+
+ // Make sure the temporary file that will be used is not present.
+ cmSystemTools::RemoveFile(this->TempName.c_str());
+
+ std::string dir = cmSystemTools::GetFilenamePath(this->TempName);
+ cmSystemTools::MakeDirectory(dir.c_str());
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratedFileStreamBase::Close()
+{
+ bool replaced = false;
+
+ std::string resname = this->Name;
+ if ( this->Compress && this->CompressExtraExtension )
+ {
+ resname += ".gz";
+ }
+
+ // Only consider replacing the destination file if no error
+ // occurred.
+ if(!this->Name.empty() &&
+ this->Okay &&
+ (!this->CopyIfDifferent ||
+ cmSystemTools::FilesDiffer(this->TempName.c_str(), resname.c_str())))
+ {
+ // The destination is to be replaced. Rename the temporary to the
+ // destination atomically.
+ if ( this->Compress )
+ {
+ std::string gzname = this->TempName + ".temp.gz";
+ if ( this->CompressFile(this->TempName.c_str(), gzname.c_str()) )
+ {
+ this->RenameFile(gzname.c_str(), resname.c_str());
+ }
+ cmSystemTools::RemoveFile(gzname.c_str());
+ }
+ else
+ {
+ this->RenameFile(this->TempName.c_str(), resname.c_str());
+ }
+
+ replaced = true;
+ }
+
+ // Else, the destination was not replaced.
+ //
+ // Always delete the temporary file. We never want it to stay around.
+ cmSystemTools::RemoveFile(this->TempName.c_str());
+
+ return replaced;
+}
+
+//----------------------------------------------------------------------------
+#ifdef CMAKE_BUILD_WITH_CMAKE
+int cmGeneratedFileStreamBase::CompressFile(const char* oldname,
+ const char* newname)
+{
+ gzFile gf = gzopen(newname, "w");
+ if ( !gf )
+ {
+ return 0;
+ }
+ FILE* ifs = fopen(oldname, "r");
+ if ( !ifs )
+ {
+ return 0;
+ }
+ size_t res;
+ const size_t BUFFER_SIZE = 1024;
+ char buffer[BUFFER_SIZE];
+ while ( (res = fread(buffer, 1, BUFFER_SIZE, ifs)) > 0 )
+ {
+ if ( !gzwrite(gf, buffer, static_cast<int>(res)) )
+ {
+ fclose(ifs);
+ gzclose(gf);
+ return 0;
+ }
+ }
+ fclose(ifs);
+ gzclose(gf);
+ return 1;
+}
+#else
+int cmGeneratedFileStreamBase::CompressFile(const char*, const char*)
+{
+ return 0;
+}
+#endif
+
+//----------------------------------------------------------------------------
+int cmGeneratedFileStreamBase::RenameFile(const char* oldname,
+ const char* newname)
+{
+ return cmSystemTools::RenameFile(oldname, newname);
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratedFileStream::SetName(const char* fname)
+{
+ if ( !fname )
+ {
+ this->Name = "";
+ return;
+ }
+ this->Name = fname;
+}
diff --git a/Source/cmGeneratedFileStream.h b/Source/cmGeneratedFileStream.h
new file mode 100644
index 000000000..dac9c7b40
--- /dev/null
+++ b/Source/cmGeneratedFileStream.h
@@ -0,0 +1,152 @@
+/*============================================================================
+ 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 cmGeneratedFileStream_h
+#define cmGeneratedFileStream_h
+
+#include "cmStandardIncludes.h"
+
+#if defined(__sgi) && !defined(__GNUC__)
+# pragma set woff 1375 /* base class destructor not virtual */
+#endif
+
+// This is the first base class of cmGeneratedFileStream. It will be
+// created before and destroyed after the ofstream portion and can
+// therefore be used to manage the temporary file.
+class cmGeneratedFileStreamBase
+{
+protected:
+ // This constructor does not prepare the temporary file. The open
+ // method must be used.
+ cmGeneratedFileStreamBase();
+
+ // This constructor prepares the temporary output file.
+ cmGeneratedFileStreamBase(const char* name);
+
+ // The destructor renames the temporary output file to the real name.
+ ~cmGeneratedFileStreamBase();
+
+ // Internal methods to handle the temporary file. Open is always
+ // called before the real stream is opened. Close is always called
+ // after the real stream is closed and Okay is set to whether the
+ // real stream was still valid for writing when it was closed.
+ void Open(const char* name);
+ bool Close();
+
+ // Internal file replacement implementation.
+ int RenameFile(const char* oldname, const char* newname);
+
+ // Internal file compression implementation.
+ int CompressFile(const char* oldname, const char* newname);
+
+ // The name of the final destination file for the output.
+ std::string Name;
+
+ // The name of the temporary file.
+ std::string TempName;
+
+ // Whether to do a copy-if-different.
+ bool CopyIfDifferent;
+
+ // Whether the real file stream was valid when it was closed.
+ bool Okay;
+
+ // Whether the destionation file is compressed
+ bool Compress;
+
+ // Whether the destionation file is compressed
+ bool CompressExtraExtension;
+};
+
+/** \class cmGeneratedFileStream
+ * \brief Output stream for generated files.
+ *
+ * File generation should be atomic so that if CMake is killed then a
+ * generated file is either the original version or the complete new
+ * version. This stream is used to make sure file generation is
+ * atomic. Optionally the output file is only replaced if its
+ * contents have changed to prevent the file modification time from
+ * being updated.
+ */
+class cmGeneratedFileStream: private cmGeneratedFileStreamBase,
+ public std::ofstream
+{
+public:
+ typedef std::ofstream Stream;
+
+ /**
+ * This constructor prepares a default stream. The open method must
+ * be used before writing to the stream.
+ */
+ cmGeneratedFileStream();
+
+ /**
+ * This constructor takes the name of the file to be generated. It
+ * automatically generates a name for the temporary file. If the
+ * file cannot be opened an error message is produced unless the
+ * second argument is set to true.
+ */
+ cmGeneratedFileStream(const char* name, bool quiet=false);
+
+ /**
+ * The destructor checks the stream status to be sure the temporary
+ * file was successfully written before allowing the original to be
+ * replaced.
+ */
+ ~cmGeneratedFileStream();
+
+ /**
+ * Open an output file by name. This should be used only with a
+ * non-open stream. It automatically generates a name for the
+ * temporary file. If the file cannot be opened an error message is
+ * produced unless the second argument is set to true.
+ */
+ cmGeneratedFileStream& Open(const char* name, bool quiet=false,
+ bool binaryFlag=false);
+
+ /**
+ * Close the output file. This should be used only with an open
+ * stream. The temporary file is atomically renamed to the
+ * destionation file if the stream is still valid when this method
+ * is called.
+ */
+ bool Close();
+
+ /**
+ * Set whether copy-if-different is done.
+ */
+ void SetCopyIfDifferent(bool copy_if_different);
+
+ /**
+ * Set whether compression is done.
+ */
+ void SetCompression(bool compression);
+
+ /**
+ * Set whether compression has extra extension
+ */
+ void SetCompressionExtraExtension(bool ext);
+
+ /**
+ * 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);
+
+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
new file mode 100644
index 000000000..f88ab0b71
--- /dev/null
+++ b/Source/cmGeneratorExpression.cxx
@@ -0,0 +1,193 @@
+/*============================================================================
+ 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 "cmGeneratorExpression.h"
+
+#include "cmMakefile.h"
+#include "cmTarget.h"
+
+//----------------------------------------------------------------------------
+cmGeneratorExpression::cmGeneratorExpression(
+ cmMakefile* mf, const char* config,
+ cmListFileBacktrace const& backtrace, bool quiet):
+ Makefile(mf), Config(config), Backtrace(backtrace), Quiet(quiet)
+{
+ this->TargetInfo.compile("^\\$<TARGET"
+ "(|_SONAME|_LINKER)" // File with what purpose?
+ "_FILE(|_NAME|_DIR):" // Filename component.
+ "([A-Za-z0-9_.-]+)" // Target name.
+ ">$");
+}
+
+//----------------------------------------------------------------------------
+const char* cmGeneratorExpression::Process(std::string const& input)
+{
+ return this->Process(input.c_str());
+}
+
+//----------------------------------------------------------------------------
+const char* cmGeneratorExpression::Process(const char* input)
+{
+ this->Data.clear();
+
+ // We construct and evaluate expressions directly in the output
+ // buffer. Each expression is replaced by its own output value
+ // after evaluation. A stack of barriers records the starting
+ // indices of open (pending) expressions.
+ for(const char* c = input; *c; ++c)
+ {
+ if(c[0] == '$' && c[1] == '<')
+ {
+ this->Barriers.push(this->Data.size());
+ this->Data.push_back('$');
+ this->Data.push_back('<');
+ c += 1;
+ }
+ else if(c[0] == '>' && !this->Barriers.empty())
+ {
+ this->Data.push_back('>');
+ if(!this->Evaluate()) { break; }
+ this->Barriers.pop();
+ }
+ else
+ {
+ this->Data.push_back(c[0]);
+ }
+ }
+
+ // Return a null-terminated output value.
+ this->Data.push_back('\0');
+ return &*this->Data.begin();
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorExpression::Evaluate()
+{
+ // The top-most barrier points at the beginning of the expression.
+ size_t barrier = this->Barriers.top();
+
+ // Construct a null-terminated representation of the expression.
+ this->Data.push_back('\0');
+ const char* expr = &*(this->Data.begin()+barrier);
+
+ // Evaluate the expression.
+ std::string result;
+ if(this->Evaluate(expr, result))
+ {
+ // Success. Replace the expression with its evaluation result.
+ this->Data.erase(this->Data.begin()+barrier, this->Data.end());
+ this->Data.insert(this->Data.end(), result.begin(), result.end());
+ return true;
+ }
+ else if(!this->Quiet)
+ {
+ // Failure. Report the error message.
+ cmOStringStream e;
+ e << "Error evaluating generator expression:\n"
+ << " " << expr << "\n"
+ << result;
+ this->Makefile->GetCMakeInstance()
+ ->IssueMessage(cmake::FATAL_ERROR, e.str().c_str(),
+ this->Backtrace);
+ return false;
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorExpression::Evaluate(const char* expr, std::string& result)
+{
+ if(this->TargetInfo.find(expr))
+ {
+ if(!this->EvaluateTargetInfo(result))
+ {
+ return false;
+ }
+ }
+ else if(strcmp(expr, "$<CONFIGURATION>") == 0)
+ {
+ result = this->Config? this->Config : "";
+ }
+ else
+ {
+ result = "Expression syntax not recognized.";
+ return false;
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorExpression::EvaluateTargetInfo(std::string& result)
+{
+ // Lookup the referenced target.
+ std::string name = this->TargetInfo.match(3);
+ cmTarget* target = this->Makefile->FindTargetToUse(name.c_str());
+ if(!target)
+ {
+ result = "No target \"" + name + "\"";
+ return false;
+ }
+ if(target->GetType() >= cmTarget::UTILITY &&
+ target->GetType() != cmTarget::UNKNOWN_LIBRARY)
+ {
+ result = "Target \"" + name + "\" is not an executable or library.";
+ return false;
+ }
+ this->Targets.insert(target);
+
+ // Lookup the target file with the given purpose.
+ std::string purpose = this->TargetInfo.match(1);
+ if(purpose == "")
+ {
+ // The target implementation file (.so.1.2, .dll, .exe, .a).
+ result = target->GetFullPath(this->Config, false, true);
+ }
+ else if(purpose == "_LINKER")
+ {
+ // The file used to link to the target (.so, .lib, .a).
+ if(!target->IsLinkable())
+ {
+ result = ("TARGET_LINKER_FILE is allowed only for libraries and "
+ "executables with ENABLE_EXPORTS.");
+ return false;
+ }
+ result = target->GetFullPath(this->Config, target->HasImportLibrary());
+ }
+ else if(purpose == "_SONAME")
+ {
+ // The target soname file (.so.1).
+ if(target->IsDLLPlatform())
+ {
+ result = "TARGET_SONAME_FILE is not allowed for DLL target platforms.";
+ return false;
+ }
+ if(target->GetType() != cmTarget::SHARED_LIBRARY)
+ {
+ result = "TARGET_SONAME_FILE is allowed only for SHARED libraries.";
+ return false;
+ }
+ result = target->GetDirectory(this->Config);
+ result += "/";
+ result += target->GetSOName(this->Config);
+ }
+
+ // Extract the requested portion of the full path.
+ std::string part = this->TargetInfo.match(2);
+ if(part == "_NAME")
+ {
+ result = cmSystemTools::GetFilenameName(result);
+ }
+ else if(part == "_DIR")
+ {
+ result = cmSystemTools::GetFilenamePath(result);
+ }
+ return true;
+}
diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h
new file mode 100644
index 000000000..1a9d4c6e9
--- /dev/null
+++ b/Source/cmGeneratorExpression.h
@@ -0,0 +1,58 @@
+/*============================================================================
+ 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"
+
+#include <stack>
+
+#include <cmsys/RegularExpression.hxx>
+
+class cmTarget;
+class cmMakefile;
+class cmListFileBacktrace;
+
+/** \class cmGeneratorExpression
+ * \brief Evaluate generate-time query expression syntax.
+ *
+ * cmGeneratorExpression instances are used by build system generator
+ * implementations to evaluate the $<> generator expression syntax.
+ * Generator expressions are evaluated just before the generate step
+ * writes strings into the build system. They have knowledge of the
+ * build configuration which is not available at configure time.
+ */
+class cmGeneratorExpression
+{
+public:
+ /** Construct with an evaluation context and configuration. */
+ cmGeneratorExpression(cmMakefile* mf, const char* config,
+ cmListFileBacktrace const& backtrace,
+ bool quiet = false);
+
+ /** Evaluate generator expressions in a string. */
+ const char* Process(std::string const& input);
+ const char* Process(const char* input);
+
+ /** Get set of targets found during evaluations. */
+ std::set<cmTarget*> const& GetTargets() const
+ { return this->Targets; }
+private:
+ cmMakefile* Makefile;
+ const char* Config;
+ cmListFileBacktrace const& Backtrace;
+ bool Quiet;
+ std::vector<char> Data;
+ std::stack<size_t> Barriers;
+ cmsys::RegularExpression TargetInfo;
+ std::set<cmTarget*> Targets;
+ bool Evaluate();
+ bool Evaluate(const char* expr, std::string& result);
+ bool EvaluateTargetInfo(std::string& result);
+};
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
new file mode 100644
index 000000000..6e2e23da5
--- /dev/null
+++ b/Source/cmGeneratorTarget.cxx
@@ -0,0 +1,177 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2012 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 "cmGeneratorTarget.h"
+
+#include "cmTarget.h"
+#include "cmMakefile.h"
+#include "cmLocalGenerator.h"
+#include "cmGlobalGenerator.h"
+#include "cmSourceFile.h"
+
+//----------------------------------------------------------------------------
+cmGeneratorTarget::cmGeneratorTarget(cmTarget* t): Target(t)
+{
+ this->Makefile = this->Target->GetMakefile();
+ this->LocalGenerator = this->Makefile->GetLocalGenerator();
+ this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator();
+ this->ClassifySources();
+ this->LookupObjectLibraries();
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::ClassifySources()
+{
+ 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)
+ {
+ cmSourceFile* sf = *si;
+ std::string ext = cmSystemTools::LowerCase(sf->GetExtension());
+ if(sf->GetCustomCommand())
+ {
+ this->CustomCommands.push_back(sf);
+ }
+ else if(sf->GetPropertyAsBool("HEADER_FILE_ONLY"))
+ {
+ this->HeaderSources.push_back(sf);
+ }
+ else if(sf->GetPropertyAsBool("EXTERNAL_OBJECT"))
+ {
+ this->ExternalObjects.push_back(sf);
+ if(isObjLib) { badObjLib.push_back(sf); }
+ }
+ else if(sf->GetLanguage())
+ {
+ this->ObjectSources.push_back(sf);
+ }
+ else if(ext == "def")
+ {
+ this->ModuleDefinitionFile = sf->GetFullPath();
+ if(isObjLib) { badObjLib.push_back(sf); }
+ }
+ else if(ext == "idl")
+ {
+ this->IDLSources.push_back(sf);
+ if(isObjLib) { badObjLib.push_back(sf); }
+ }
+ else if(header.find(sf->GetFullPath().c_str()))
+ {
+ this->HeaderSources.push_back(sf);
+ }
+ else if(this->GlobalGenerator->IgnoreFile(sf->GetExtension().c_str()))
+ {
+ // 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);
+ }
+ else
+ {
+ this->ExtraSources.push_back(sf);
+ if(isObjLib && ext != "txt")
+ {
+ badObjLib.push_back(sf);
+ }
+ }
+ }
+
+ if(!badObjLib.empty())
+ {
+ cmOStringStream e;
+ e << "OBJECT library \"" << this->Target->GetName() << "\" contains:\n";
+ for(std::vector<cmSourceFile*>::iterator i = badObjLib.begin();
+ i != badObjLib.end(); ++i)
+ {
+ e << " " << (*i)->GetLocation().GetName() << "\n";
+ }
+ e << "but may contain only headers and sources that compile.";
+ this->GlobalGenerator->GetCMakeInstance()
+ ->IssueMessage(cmake::FATAL_ERROR, e.str(),
+ this->Target->GetBacktrace());
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::LookupObjectLibraries()
+{
+ std::vector<std::string> const& objLibs =
+ this->Target->GetObjectLibraries();
+ for(std::vector<std::string>::const_iterator oli = objLibs.begin();
+ oli != objLibs.end(); ++oli)
+ {
+ std::string const& objLibName = *oli;
+ if(cmTarget* objLib = this->Makefile->FindTargetToUse(objLibName.c_str()))
+ {
+ if(objLib->GetType() == cmTarget::OBJECT_LIBRARY)
+ {
+ if(this->Target->GetType() != cmTarget::EXECUTABLE &&
+ this->Target->GetType() != cmTarget::STATIC_LIBRARY &&
+ this->Target->GetType() != cmTarget::SHARED_LIBRARY &&
+ this->Target->GetType() != cmTarget::MODULE_LIBRARY)
+ {
+ this->GlobalGenerator->GetCMakeInstance()
+ ->IssueMessage(cmake::FATAL_ERROR,
+ "Only executables and non-OBJECT libraries may "
+ "reference target objects.",
+ this->Target->GetBacktrace());
+ return;
+ }
+ this->Target->AddUtility(objLib->GetName());
+ this->ObjectLibraries.push_back(objLib);
+ }
+ else
+ {
+ 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;
+ }
+ }
+ 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;
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::UseObjectLibraries(std::vector<std::string>& objs)
+{
+ for(std::vector<cmTarget*>::const_iterator
+ ti = this->ObjectLibraries.begin();
+ ti != this->ObjectLibraries.end(); ++ti)
+ {
+ 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 obj = ogt->ObjectDirectory;
+ obj += ogt->Objects[*si];
+ objs.push_back(obj);
+ }
+ }
+}
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
new file mode 100644
index 000000000..5c7578d94
--- /dev/null
+++ b/Source/cmGeneratorTarget.h
@@ -0,0 +1,63 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2012 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 cmGeneratorTarget_h
+#define cmGeneratorTarget_h
+
+#include "cmStandardIncludes.h"
+
+class cmCustomCommand;
+class cmGlobalGenerator;
+class cmLocalGenerator;
+class cmMakefile;
+class cmSourceFile;
+class cmTarget;
+
+class cmGeneratorTarget
+{
+public:
+ cmGeneratorTarget(cmTarget*);
+
+ cmTarget* Target;
+ cmMakefile* Makefile;
+ cmLocalGenerator* LocalGenerator;
+ cmGlobalGenerator* 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::string ModuleDefinitionFile;
+
+ std::map<cmSourceFile const*, std::string> Objects;
+ std::set<cmSourceFile const*> ExplicitObjectName;
+
+ /** 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);
+
+private:
+ void ClassifySources();
+ void LookupObjectLibraries();
+
+ cmGeneratorTarget(cmGeneratorTarget const&);
+ void operator=(cmGeneratorTarget const&);
+};
+
+#endif
diff --git a/Source/cmGetCMakePropertyCommand.cxx b/Source/cmGetCMakePropertyCommand.cxx
new file mode 100644
index 000000000..8bb54877e
--- /dev/null
+++ b/Source/cmGetCMakePropertyCommand.cxx
@@ -0,0 +1,77 @@
+/*============================================================================
+ 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 "cmGetCMakePropertyCommand.h"
+
+#include "cmake.h"
+
+// cmGetCMakePropertyCommand
+bool cmGetCMakePropertyCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 2 )
+ {
+ this->SetError("called with incorrect number of arguments");
+ 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)
+ {
+ output = vars[0];
+ }
+ for ( cc = 1; cc < vars.size(); ++cc )
+ {
+ output += ";";
+ output += vars[cc];
+ }
+ }
+ else if ( args[1] == "MACROS" )
+ {
+ this->Makefile->GetListOfMacros(output);
+ }
+ 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;
+ }
+ }
+ else
+ {
+ const char *prop =
+ this->Makefile->GetCMakeInstance()->GetProperty(args[1].c_str());
+ if (prop)
+ {
+ output = prop;
+ }
+ }
+
+ this->Makefile->AddDefinition(variable.c_str(), output.c_str());
+
+ return true;
+}
diff --git a/Source/cmGetCMakePropertyCommand.h b/Source/cmGetCMakePropertyCommand.h
new file mode 100644
index 000000000..0a5917cfd
--- /dev/null
+++ b/Source/cmGetCMakePropertyCommand.h
@@ -0,0 +1,72 @@
+/*============================================================================
+ 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 cmGetCMakePropertyCommand_h
+#define cmGetCMakePropertyCommand_h
+
+#include "cmCommand.h"
+
+class cmGetCMakePropertyCommand : public cmCommand
+{
+public:
+ virtual cmCommand* Clone()
+ {
+ return new cmGetCMakePropertyCommand;
+ }
+
+ /**
+ * This is called when the command is first encountered in
+ * the input 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 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.";
+ }
+
+ cmTypeMacro(cmGetCMakePropertyCommand, cmCommand);
+};
+
+
+
+#endif
diff --git a/Source/cmGetDirectoryPropertyCommand.cxx b/Source/cmGetDirectoryPropertyCommand.cxx
new file mode 100644
index 000000000..5714b5079
--- /dev/null
+++ b/Source/cmGetDirectoryPropertyCommand.cxx
@@ -0,0 +1,96 @@
+/*============================================================================
+ 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 "cmGetDirectoryPropertyCommand.h"
+
+#include "cmake.h"
+
+// cmGetDirectoryPropertyCommand
+bool cmGetDirectoryPropertyCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 2 )
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ 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;
+ if (*i == "DIRECTORY")
+ {
+ ++i;
+ if (i == args.end())
+ {
+ this->SetError
+ ("DIRECTORY argument provided without subsequent arguments");
+ return false;
+ }
+ std::string sd = *i;
+ // make sure the start dir is a full path
+ if (!cmSystemTools::FileIsFullPath(sd.c_str()))
+ {
+ sd = this->Makefile->GetStartDirectory();
+ sd += "/";
+ sd += *i;
+ }
+
+ // The local generators are associated with collapsed paths.
+ sd = cmSystemTools::CollapseFullPath(sd.c_str());
+
+ // lookup the makefile from the directory name
+ cmLocalGenerator *lg =
+ this->Makefile->GetLocalGenerator()->GetGlobalGenerator()->
+ FindLocalGenerator(sd.c_str());
+ if (!lg)
+ {
+ this->SetError
+ ("DIRECTORY argument provided but requested directory not found. "
+ "This could be because the directory argument was invalid or, "
+ "it is valid but has not been processed yet.");
+ return false;
+ }
+ dir = lg->GetMakefile();
+ ++i;
+ }
+
+ // OK, now we have the directory to process, we just get the requested
+ // information out of it
+
+ if ( *i == "DEFINITION" )
+ {
+ ++i;
+ if (i == args.end())
+ {
+ this->SetError("A request for a variable definition was made without "
+ "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());
+ return true;
+ }
+
+ const char *prop = dir->GetProperty(i->c_str());
+ if (prop)
+ {
+ this->Makefile->AddDefinition(variable.c_str(), prop);
+ return true;
+ }
+ this->Makefile->AddDefinition(variable.c_str(), "");
+ return true;
+}
+
diff --git a/Source/cmGetDirectoryPropertyCommand.h b/Source/cmGetDirectoryPropertyCommand.h
new file mode 100644
index 000000000..901b90cff
--- /dev/null
+++ b/Source/cmGetDirectoryPropertyCommand.h
@@ -0,0 +1,78 @@
+/*============================================================================
+ 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 cmGetDirectoryPropertyCommand_h
+#define cmGetDirectoryPropertyCommand_h
+
+#include "cmCommand.h"
+
+class cmGetDirectoryPropertyCommand : public cmCommand
+{
+public:
+ virtual cmCommand* Clone()
+ {
+ return new cmGetDirectoryPropertyCommand;
+ }
+
+ /**
+ * This is called when the command is first encountered in
+ * the input 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 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.";
+ }
+
+ cmTypeMacro(cmGetDirectoryPropertyCommand, cmCommand);
+};
+
+
+
+#endif
diff --git a/Source/cmGetFilenameComponentCommand.cxx b/Source/cmGetFilenameComponentCommand.cxx
new file mode 100644
index 000000000..1a31d5428
--- /dev/null
+++ b/Source/cmGetFilenameComponentCommand.cxx
@@ -0,0 +1,139 @@
+/*============================================================================
+ 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 "cmGetFilenameComponentCommand.h"
+#include "cmSystemTools.h"
+
+// cmGetFilenameComponentCommand
+bool cmGetFilenameComponentCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 3)
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ // 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")
+ {
+ const char* cacheValue = this->Makefile->GetDefinition(args[0].c_str());
+ if(cacheValue && !cmSystemTools::IsNOTFOUND(cacheValue))
+ {
+ return true;
+ }
+ }
+
+ std::string result;
+ std::string filename = args[1];
+ if(filename.find("[HKEY") != filename.npos)
+ {
+ // Check 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;
+ }
+ cmSystemTools::ExpandRegistryValues(filename, view);
+ if(filename.find("/registry") != filename.npos)
+ {
+ std::string other = args[1];
+ cmSystemTools::ExpandRegistryValues(other, other_view);
+ if(other.find("/registry") == other.npos)
+ {
+ filename = other;
+ }
+ }
+ }
+ std::string storeArgs;
+ std::string programArgs;
+ if (args[2] == "PATH")
+ {
+ result = cmSystemTools::GetFilenamePath(filename);
+ }
+ else if (args[2] == "NAME")
+ {
+ result = cmSystemTools::GetFilenameName(filename);
+ }
+ else if (args[2] == "PROGRAM")
+ {
+ for(unsigned int i=2; i < args.size(); ++i)
+ {
+ if(args[i] == "PROGRAM_ARGS")
+ {
+ i++;
+ if(i < args.size())
+ {
+ storeArgs = args[i];
+ }
+ }
+ }
+ cmSystemTools::SplitProgramFromArgs(filename.c_str(),
+ result, programArgs);
+ }
+ else if (args[2] == "EXT")
+ {
+ result = cmSystemTools::GetFilenameExtension(filename);
+ }
+ else if (args[2] == "NAME_WE")
+ {
+ result = cmSystemTools::GetFilenameWithoutExtension(filename);
+ }
+ else if (args[2] == "ABSOLUTE" ||
+ args[2] == "REALPATH")
+ {
+ // 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());
+ if(args[2] == "REALPATH")
+ {
+ // Resolve symlinks if possible
+ result = cmSystemTools::GetRealPath(result.c_str());
+ }
+ }
+ else
+ {
+ std::string err = "unknown component " + args[2];
+ this->SetError(err.c_str());
+ return false;
+ }
+
+ if(args.size() == 4 && args[3] == "CACHE")
+ {
+ if(programArgs.size() && storeArgs.size())
+ {
+ this->Makefile->AddCacheDefinition
+ (storeArgs.c_str(), programArgs.c_str(),
+ "", args[2] == "PATH" ? cmCacheManager::FILEPATH
+ : cmCacheManager::STRING);
+ }
+ this->Makefile->AddCacheDefinition
+ (args[0].c_str(), result.c_str(), "",
+ args[2] == "PATH" ? cmCacheManager::FILEPATH
+ : cmCacheManager::STRING);
+ }
+ else
+ {
+ if(programArgs.size() && storeArgs.size())
+ {
+ this->Makefile->AddDefinition(storeArgs.c_str(), programArgs.c_str());
+ }
+ this->Makefile->AddDefinition(args[0].c_str(), result.c_str());
+ }
+
+ return true;
+}
+
diff --git a/Source/cmGetFilenameComponentCommand.h b/Source/cmGetFilenameComponentCommand.h
new file mode 100644
index 000000000..0c8e57a26
--- /dev/null
+++ b/Source/cmGetFilenameComponentCommand.h
@@ -0,0 +1,91 @@
+/*============================================================================
+ 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 cmGetFilenameComponentCommand_h
+#define cmGetFilenameComponentCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmGetFilenameComponentCommand
+ * \brief Get a specific component of a filename.
+ *
+ * cmGetFilenameComponentCommand is a utility command used to get the path,
+ * name, extension or name without extension of a full filename.
+ */
+class cmGetFilenameComponentCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmGetFilenameComponentCommand;
+ }
+
+ /**
+ * 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 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\n"
+ " PATH|ABSOLUTE|NAME|EXT|NAME_WE|REALPATH\n"
+ " [CACHE])\n"
+ "Set <VAR> to be the path (PATH), file name (NAME), file "
+ "extension (EXT), file name without extension (NAME_WE) of FileName, "
+ "the full path (ABSOLUTE), or the full path with all symlinks "
+ "resolved (REALPATH). "
+ "Note that the path is converted to Unix slashes format and has 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.\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.";
+ }
+
+ cmTypeMacro(cmGetFilenameComponentCommand, cmCommand);
+};
+
+
+
+#endif
diff --git a/Source/cmGetPropertyCommand.cxx b/Source/cmGetPropertyCommand.cxx
new file mode 100644
index 000000000..7d3335887
--- /dev/null
+++ b/Source/cmGetPropertyCommand.cxx
@@ -0,0 +1,381 @@
+/*============================================================================
+ 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 "cmGetPropertyCommand.h"
+
+#include "cmake.h"
+#include "cmTest.h"
+#include "cmPropertyDefinition.h"
+
+//----------------------------------------------------------------------------
+cmGetPropertyCommand::cmGetPropertyCommand()
+{
+ this->InfoType = OutValue;
+}
+
+//----------------------------------------------------------------------------
+bool cmGetPropertyCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 3 )
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ // The cmake variable in which to store the result.
+ this->Variable = args[0];
+
+ // Get the scope from which to get the property.
+ cmProperty::ScopeType scope;
+ if(args[1] == "GLOBAL")
+ {
+ scope = cmProperty::GLOBAL;
+ }
+ else if(args[1] == "DIRECTORY")
+ {
+ scope = cmProperty::DIRECTORY;
+ }
+ else if(args[1] == "TARGET")
+ {
+ scope = cmProperty::TARGET;
+ }
+ else if(args[1] == "SOURCE")
+ {
+ scope = cmProperty::SOURCE_FILE;
+ }
+ else if(args[1] == "TEST")
+ {
+ scope = cmProperty::TEST;
+ }
+ else if(args[1] == "VARIABLE")
+ {
+ scope = cmProperty::VARIABLE;
+ }
+ else if(args[1] == "CACHE")
+ {
+ scope = cmProperty::CACHE;
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "given invalid scope " << args[1] << ". "
+ << "Valid scopes are "
+ << "GLOBAL, DIRECTORY, TARGET, SOURCE, TEST, VARIABLE, CACHE.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+
+ // Parse remaining arguments.
+ enum Doing { DoingNone, DoingName, DoingProperty, DoingType };
+ Doing doing = DoingName;
+ for(unsigned int i=2; i < args.size(); ++i)
+ {
+ if(args[i] == "PROPERTY")
+ {
+ doing = DoingProperty;
+ }
+ else if(args[i] == "BRIEF_DOCS")
+ {
+ doing = DoingNone;
+ this->InfoType = OutBriefDoc;
+ }
+ else if(args[i] == "FULL_DOCS")
+ {
+ doing = DoingNone;
+ this->InfoType = OutFullDoc;
+ }
+ else if(args[i] == "SET")
+ {
+ doing = DoingNone;
+ this->InfoType = OutSet;
+ }
+ else if(args[i] == "DEFINED")
+ {
+ doing = DoingNone;
+ this->InfoType = OutDefined;
+ }
+ else if(doing == DoingName)
+ {
+ doing = DoingNone;
+ this->Name = args[i];
+ }
+ else if(doing == DoingProperty)
+ {
+ doing = DoingNone;
+ this->PropertyName = args[i];
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "given invalid argument \"" << args[i] << "\".";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+
+ // Make sure a property name was found.
+ if(this->PropertyName.empty())
+ {
+ this->SetError("not given a PROPERTY <name> argument.");
+ return false;
+ }
+
+ // Compute requested output.
+ if(this->InfoType == OutBriefDoc)
+ {
+ // Lookup brief documentation.
+ std::string output;
+ if(cmPropertyDefinition* def =
+ this->Makefile->GetCMakeInstance()->
+ GetPropertyDefinition(this->PropertyName.c_str(), scope))
+ {
+ output = def->GetShortDescription();
+ }
+ else
+ {
+ output = "NOTFOUND";
+ }
+ this->Makefile->AddDefinition(this->Variable.c_str(), 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))
+ {
+ output = def->GetFullDescription();
+ }
+ else
+ {
+ output = "NOTFOUND";
+ }
+ this->Makefile->AddDefinition(this->Variable.c_str(), output.c_str());
+ }
+ else if(this->InfoType == OutDefined)
+ {
+ // Lookup if the property is defined
+ if(this->Makefile->GetCMakeInstance()->
+ GetPropertyDefinition(this->PropertyName.c_str(), scope))
+ {
+ this->Makefile->AddDefinition(this->Variable.c_str(), "1");
+ }
+ else
+ {
+ this->Makefile->AddDefinition(this->Variable.c_str(), "0");
+ }
+ }
+ else
+ {
+ // Dispatch property getting.
+ switch(scope)
+ {
+ case cmProperty::GLOBAL: return this->HandleGlobalMode();
+ case cmProperty::DIRECTORY: return this->HandleDirectoryMode();
+ case cmProperty::TARGET: return this->HandleTargetMode();
+ case cmProperty::SOURCE_FILE: return this->HandleSourceMode();
+ case cmProperty::TEST: return this->HandleTestMode();
+ case cmProperty::VARIABLE: return this->HandleVariableMode();
+ case cmProperty::CACHE: return this->HandleCacheMode();
+
+ case cmProperty::CACHED_VARIABLE:
+ break; // should never happen
+ }
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmGetPropertyCommand::StoreResult(const char* value)
+{
+ if(this->InfoType == OutSet)
+ {
+ this->Makefile->AddDefinition(this->Variable.c_str(), value? "1":"0");
+ }
+ else // if(this->InfoType == OutValue)
+ {
+ if(value)
+ {
+ this->Makefile->AddDefinition(this->Variable.c_str(), value);
+ }
+ else
+ {
+ this->Makefile->RemoveDefinition(this->Variable.c_str());
+ }
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmGetPropertyCommand::HandleGlobalMode()
+{
+ if(!this->Name.empty())
+ {
+ this->SetError("given name for GLOBAL scope.");
+ return false;
+ }
+
+ // Get the property.
+ cmake* cm = this->Makefile->GetCMakeInstance();
+ return this->StoreResult(cm->GetProperty(this->PropertyName.c_str()));
+}
+
+//----------------------------------------------------------------------------
+bool cmGetPropertyCommand::HandleDirectoryMode()
+{
+ // Default to the current directory.
+ cmMakefile* mf = this->Makefile;
+
+ // Lookup the directory if given.
+ if(!this->Name.empty())
+ {
+ // Construct the directory name. Interpret relative paths with
+ // respect to the current directory.
+ std::string dir = this->Name;
+ if(!cmSystemTools::FileIsFullPath(dir.c_str()))
+ {
+ dir = this->Makefile->GetCurrentDirectory();
+ dir += "/";
+ dir += this->Name;
+ }
+
+ // The local generators are associated with collapsed paths.
+ dir = cmSystemTools::CollapseFullPath(dir.c_str());
+
+ // 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
+ {
+ // Could not find the directory.
+ this->SetError
+ ("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.");
+ return false;
+ }
+ }
+
+ // Get the property.
+ return this->StoreResult(mf->GetProperty(this->PropertyName.c_str()));
+}
+
+//----------------------------------------------------------------------------
+bool cmGetPropertyCommand::HandleTargetMode()
+{
+ if(this->Name.empty())
+ {
+ this->SetError("not given name for TARGET scope.");
+ return false;
+ }
+
+ if(cmTarget* target = this->Makefile->FindTargetToUse(this->Name.c_str()))
+ {
+ return this->StoreResult(target->GetProperty(this->PropertyName.c_str()));
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "could not find TARGET " << this->Name
+ << ". Perhaps it has not yet been created.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmGetPropertyCommand::HandleSourceMode()
+{
+ if(this->Name.empty())
+ {
+ this->SetError("not given name for SOURCE scope.");
+ return false;
+ }
+
+ // Get the source file.
+ if(cmSourceFile* sf =
+ this->Makefile->GetOrCreateSource(this->Name.c_str()))
+ {
+ return
+ this->StoreResult(sf->GetPropertyForUser(this->PropertyName.c_str()));
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "given SOURCE name that could not be found or created: "
+ << this->Name;
+ this->SetError(e.str().c_str());
+ return false;
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmGetPropertyCommand::HandleTestMode()
+{
+ if(this->Name.empty())
+ {
+ this->SetError("not given name for TEST scope.");
+ return false;
+ }
+
+ // Loop over all tests looking for matching names.
+ if(cmTest* test = this->Makefile->GetTest(this->Name.c_str()))
+ {
+ return this->StoreResult(test->GetProperty(this->PropertyName.c_str()));
+ }
+
+ // If not found it is an error.
+ cmOStringStream e;
+ e << "given TEST name that does not exist: " << this->Name;
+ this->SetError(e.str().c_str());
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmGetPropertyCommand::HandleVariableMode()
+{
+ if(!this->Name.empty())
+ {
+ this->SetError("given name for VARIABLE scope.");
+ return false;
+ }
+
+ return this->StoreResult
+ (this->Makefile->GetDefinition(this->PropertyName.c_str()));
+}
+
+//----------------------------------------------------------------------------
+bool cmGetPropertyCommand::HandleCacheMode()
+{
+ if(this->Name.empty())
+ {
+ this->SetError("not given name for CACHE scope.");
+ return false;
+ }
+
+ const char* value = 0;
+ cmCacheManager::CacheIterator it =
+ this->Makefile->GetCacheManager()->GetCacheIterator(this->Name.c_str());
+ if(!it.IsAtEnd())
+ {
+ value = it.GetProperty(this->PropertyName.c_str());
+ }
+ this->StoreResult(value);
+ return true;
+}
diff --git a/Source/cmGetPropertyCommand.h b/Source/cmGetPropertyCommand.h
new file mode 100644
index 000000000..dca262725
--- /dev/null
+++ b/Source/cmGetPropertyCommand.h
@@ -0,0 +1,117 @@
+/*============================================================================
+ 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 cmGetPropertyCommand_h
+#define cmGetPropertyCommand_h
+
+#include "cmCommand.h"
+
+class cmGetPropertyCommand : public cmCommand
+{
+public:
+ cmGetPropertyCommand();
+
+ virtual cmCommand* Clone()
+ {
+ return new cmGetPropertyCommand;
+ }
+
+ /**
+ * This is called when the command is first encountered in
+ * the input 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 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.";
+ }
+
+ cmTypeMacro(cmGetPropertyCommand, cmCommand);
+private:
+ enum OutType { OutValue, OutDefined, OutBriefDoc, OutFullDoc, OutSet };
+ std::string Variable;
+ std::string Name;
+ std::string PropertyName;
+ OutType InfoType;
+
+ // Implementation of result storage.
+ bool StoreResult(const char* value);
+
+ // Implementation of each property type.
+ bool HandleGlobalMode();
+ bool HandleDirectoryMode();
+ bool HandleTargetMode();
+ bool HandleSourceMode();
+ bool HandleTestMode();
+ bool HandleVariableMode();
+ bool HandleCacheMode();
+};
+
+#endif
diff --git a/Source/cmGetSourceFilePropertyCommand.cxx b/Source/cmGetSourceFilePropertyCommand.cxx
new file mode 100644
index 000000000..3d85e6d7d
--- /dev/null
+++ b/Source/cmGetSourceFilePropertyCommand.cxx
@@ -0,0 +1,52 @@
+/*============================================================================
+ 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 "cmGetSourceFilePropertyCommand.h"
+
+#include "cmSourceFile.h"
+
+// cmSetSourceFilePropertyCommand
+bool cmGetSourceFilePropertyCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() != 3 )
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+ const char* var = args[0].c_str();
+ const char* file = args[1].c_str();
+ cmSourceFile* sf = this->Makefile->GetSource(file);
+
+ // for the location we must create a source file first
+ if (!sf && args[2] == "LOCATION")
+ {
+ sf = this->Makefile->GetOrCreateSource(file);
+ }
+ if(sf)
+ {
+ if(args[2] == "LANGUAGE")
+ {
+ this->Makefile->AddDefinition(var, sf->GetLanguage());
+ return true;
+ }
+ const char *prop = sf->GetPropertyForUser(args[2].c_str());
+ if (prop)
+ {
+ this->Makefile->AddDefinition(var, prop);
+ return true;
+ }
+ }
+
+ this->Makefile->AddDefinition(var, "NOTFOUND");
+ return true;
+}
+
diff --git a/Source/cmGetSourceFilePropertyCommand.h b/Source/cmGetSourceFilePropertyCommand.h
new file mode 100644
index 000000000..6d52503b5
--- /dev/null
+++ b/Source/cmGetSourceFilePropertyCommand.h
@@ -0,0 +1,66 @@
+/*============================================================================
+ 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 cmGetSourceFilePropertyCommand_h
+#define cmGetSourceFilePropertyCommand_h
+
+#include "cmCommand.h"
+
+class cmGetSourceFilePropertyCommand : public cmCommand
+{
+public:
+ virtual cmCommand* Clone()
+ {
+ return new cmGetSourceFilePropertyCommand;
+ }
+
+ /**
+ * This is called when the command is first encountered in
+ * the input file.
+ */
+ 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 "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.";
+ }
+
+ cmTypeMacro(cmGetSourceFilePropertyCommand, cmCommand);
+};
+
+
+
+#endif
diff --git a/Source/cmGetTargetPropertyCommand.cxx b/Source/cmGetTargetPropertyCommand.cxx
new file mode 100644
index 000000000..1947139c9
--- /dev/null
+++ b/Source/cmGetTargetPropertyCommand.cxx
@@ -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.
+============================================================================*/
+#include "cmGetTargetPropertyCommand.h"
+
+// cmSetTargetPropertyCommand
+bool cmGetTargetPropertyCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() != 3 )
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+ std::string var = args[0].c_str();
+ const char* targetName = args[1].c_str();
+
+ if(cmTarget* tgt = this->Makefile->FindTargetToUse(targetName))
+ {
+ cmTarget& target = *tgt;
+ const char *prop = target.GetProperty(args[2].c_str());
+ if (prop)
+ {
+ this->Makefile->AddDefinition(var.c_str(), prop);
+ return true;
+ }
+ }
+ this->Makefile->AddDefinition(var.c_str(), (var+"-NOTFOUND").c_str());
+ return true;
+}
+
diff --git a/Source/cmGetTargetPropertyCommand.h b/Source/cmGetTargetPropertyCommand.h
new file mode 100644
index 000000000..b60abea4c
--- /dev/null
+++ b/Source/cmGetTargetPropertyCommand.h
@@ -0,0 +1,68 @@
+/*============================================================================
+ 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 cmGetTargetPropertyCommand_h
+#define cmGetTargetPropertyCommand_h
+
+#include "cmCommand.h"
+
+class cmGetTargetPropertyCommand : public cmCommand
+{
+public:
+ virtual cmCommand* Clone()
+ {
+ return new cmGetTargetPropertyCommand;
+ }
+
+ /**
+ * This is called when the command is first encountered in
+ * the input file.
+ */
+ 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 "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.";
+ }
+
+ cmTypeMacro(cmGetTargetPropertyCommand, cmCommand);
+};
+
+
+
+#endif
diff --git a/Source/cmGetTestPropertyCommand.cxx b/Source/cmGetTestPropertyCommand.cxx
new file mode 100644
index 000000000..0e0e2c09b
--- /dev/null
+++ b/Source/cmGetTestPropertyCommand.cxx
@@ -0,0 +1,42 @@
+/*============================================================================
+ 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 "cmGetTestPropertyCommand.h"
+
+#include "cmake.h"
+#include "cmTest.h"
+
+// cmGetTestPropertyCommand
+bool cmGetTestPropertyCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 3 )
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ std::string testName = args[0];
+ std::string var = args[2];
+ cmTest *test = this->Makefile->GetTest(testName.c_str());
+ if (test)
+ {
+ const char *prop = test->GetProperty(args[1].c_str());
+ if (prop)
+ {
+ this->Makefile->AddDefinition(var.c_str(), prop);
+ return true;
+ }
+ }
+ this->Makefile->AddDefinition(var.c_str(), "NOTFOUND");
+ return true;
+}
+
diff --git a/Source/cmGetTestPropertyCommand.h b/Source/cmGetTestPropertyCommand.h
new file mode 100644
index 000000000..af6bafaf3
--- /dev/null
+++ b/Source/cmGetTestPropertyCommand.h
@@ -0,0 +1,65 @@
+/*============================================================================
+ 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 cmGetTestPropertyCommand_h
+#define cmGetTestPropertyCommand_h
+
+#include "cmCommand.h"
+
+class cmGetTestPropertyCommand : public cmCommand
+{
+public:
+ virtual cmCommand* Clone()
+ {
+ return new cmGetTestPropertyCommand;
+ }
+
+ /**
+ * This is called when the command is first encountered in
+ * the input file.
+ */
+ 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 "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.";
+ }
+
+ cmTypeMacro(cmGetTestPropertyCommand, cmCommand);
+};
+
+
+
+#endif
diff --git a/Source/cmGlobalBorlandMakefileGenerator.cxx b/Source/cmGlobalBorlandMakefileGenerator.cxx
new file mode 100644
index 000000000..b87b7e186
--- /dev/null
+++ b/Source/cmGlobalBorlandMakefileGenerator.cxx
@@ -0,0 +1,63 @@
+/*============================================================================
+ 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 "cmGlobalBorlandMakefileGenerator.h"
+#include "cmLocalUnixMakefileGenerator3.h"
+#include "cmMakefile.h"
+#include "cmake.h"
+
+cmGlobalBorlandMakefileGenerator::cmGlobalBorlandMakefileGenerator()
+{
+ this->EmptyRuleHackDepends = "NUL";
+ this->FindMakeProgramFile = "CMakeBorlandFindMake.cmake";
+ this->ForceUnixPaths = false;
+ this->ToolSupportsColor = true;
+ this->UseLinkScript = false;
+}
+
+
+void cmGlobalBorlandMakefileGenerator
+::EnableLanguage(std::vector<std::string>const& l,
+ cmMakefile *mf,
+ bool optional)
+{
+ std::string outdir = this->CMakeInstance->GetStartOutputDirectory();
+ mf->AddDefinition("BORLAND", "1");
+ mf->AddDefinition("CMAKE_GENERATOR_CC", "bcc32");
+ mf->AddDefinition("CMAKE_GENERATOR_CXX", "bcc32");
+ this->cmGlobalUnixMakefileGenerator3::EnableLanguage(l, mf, optional);
+}
+
+///! Create a local generator appropriate to this Global Generator
+cmLocalGenerator *cmGlobalBorlandMakefileGenerator::CreateLocalGenerator()
+{
+ cmLocalUnixMakefileGenerator3* lg = new cmLocalUnixMakefileGenerator3;
+ lg->SetIncludeDirective("!include");
+ lg->SetWindowsShell(true);
+ lg->SetDefineWindowsNULL(true);
+ lg->SetMakefileVariableSize(32);
+ lg->SetPassMakeflags(true);
+ lg->SetGlobalGenerator(this);
+ lg->SetUnixCD(false);
+ lg->SetMakeCommandEscapeTargetTwice(true);
+ lg->SetBorlandMakeCurlyHack(true);
+ return lg;
+}
+
+
+//----------------------------------------------------------------------------
+void cmGlobalBorlandMakefileGenerator
+::GetDocumentation(cmDocumentationEntry& entry) const
+{
+ entry.Name = this->GetName();
+ entry.Brief = "Generates Borland makefiles.";
+ entry.Full = "";
+}
diff --git a/Source/cmGlobalBorlandMakefileGenerator.h b/Source/cmGlobalBorlandMakefileGenerator.h
new file mode 100644
index 000000000..0d3868989
--- /dev/null
+++ b/Source/cmGlobalBorlandMakefileGenerator.h
@@ -0,0 +1,48 @@
+/*============================================================================
+ 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 cmGlobalBorlandMakefileGenerator_h
+#define cmGlobalBorlandMakefileGenerator_h
+
+#include "cmGlobalNMakeMakefileGenerator.h"
+
+/** \class cmGlobalBorlandMakefileGenerator
+ * \brief Write a Borland makefiles.
+ *
+ * cmGlobalBorlandMakefileGenerator manages nmake build process for a tree
+ */
+class cmGlobalBorlandMakefileGenerator : public cmGlobalNMakeMakefileGenerator
+{
+public:
+ cmGlobalBorlandMakefileGenerator();
+ static cmGlobalGenerator* New()
+ { return new cmGlobalBorlandMakefileGenerator; }
+
+ ///! Get the name for the generator.
+ virtual const char* GetName() const {
+ return cmGlobalBorlandMakefileGenerator::GetActualName();}
+ static const char* GetActualName() {return "Borland Makefiles";}
+
+ /** Get the documentation entry for this generator. */
+ virtual void GetDocumentation(cmDocumentationEntry& entry) const;
+
+ ///! Create a local generator appropriate to this Global Generator
+ virtual cmLocalGenerator *CreateLocalGenerator();
+
+ /**
+ * Try to determine system infomation such as shared library
+ * extension, pthreads, byte order etc.
+ */
+ virtual void EnableLanguage(std::vector<std::string>const& languages,
+ cmMakefile *, bool optional);
+};
+
+#endif
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
new file mode 100644
index 000000000..a47ca3677
--- /dev/null
+++ b/Source/cmGlobalGenerator.cxx
@@ -0,0 +1,2510 @@
+/*============================================================================
+ 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.
+============================================================================*/
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#include "windows.h" // this must be first to define GetCurrentDirectory
+#endif
+
+#include "cmGlobalGenerator.h"
+#include "cmLocalGenerator.h"
+#include "cmExternalMakefileProjectGenerator.h"
+#include "cmake.h"
+#include "cmMakefile.h"
+#include "cmQtAutomoc.h"
+#include "cmSourceFile.h"
+#include "cmVersion.h"
+#include "cmExportInstallFileGenerator.h"
+#include "cmComputeTargetDepends.h"
+#include "cmGeneratedFileStream.h"
+#include "cmGeneratorTarget.h"
+
+#include <cmsys/Directory.hxx>
+
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+# include <cmsys/MD5.h>
+#endif
+
+#include <stdlib.h> // required for atof
+
+#include <assert.h>
+
+cmGlobalGenerator::cmGlobalGenerator()
+{
+ // By default the .SYMBOLIC dependency is not needed on symbolic rules.
+ this->NeedSymbolicMark = false;
+
+ // by default use the native paths
+ this->ForceUnixPaths = false;
+
+ // By default do not try to support color.
+ this->ToolSupportsColor = false;
+
+ // By default do not use link scripts.
+ this->UseLinkScript = false;
+
+ // Whether an install target is needed.
+ this->InstallTargetEnabled = false;
+
+ // how long to let try compiles run
+ this->TryCompileTimeout = 0;
+
+ this->ExtraGenerator = 0;
+ this->CurrentLocalGenerator = 0;
+ this->TryCompileOuterMakefile = 0;
+}
+
+cmGlobalGenerator::~cmGlobalGenerator()
+{
+ // Delete any existing cmLocalGenerators
+ for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i)
+ {
+ delete this->LocalGenerators[i];
+ }
+ this->LocalGenerators.clear();
+
+ if (this->ExtraGenerator)
+ {
+ delete this->ExtraGenerator;
+ }
+
+ this->ClearGeneratorTargets();
+ this->ClearExportSets();
+}
+
+void cmGlobalGenerator::ResolveLanguageCompiler(const std::string &lang,
+ cmMakefile *mf,
+ bool optional) {
+ std::string langComp = "CMAKE_";
+ langComp += lang;
+ langComp += "_COMPILER";
+
+ if(!mf->GetDefinition(langComp.c_str()))
+ {
+ if(!optional)
+ {
+ cmSystemTools::Error(langComp.c_str(),
+ " not set, after EnableLanguage");
+ }
+ return;
+ }
+ const char* name = mf->GetRequiredDefinition(langComp.c_str());
+ std::string path;
+ if(!cmSystemTools::FileIsFullPath(name))
+ {
+ path = cmSystemTools::FindProgram(name);
+ }
+ else
+ {
+ path = name;
+ }
+ if((path.size() == 0 || !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;
+ }
+ std::string doc = lang;
+ doc += " compiler.";
+ const char* cname = this->GetCMakeInstance()->
+ GetCacheManager()->GetCacheValue(langComp.c_str());
+ std::string changeVars;
+ if(cname && (path != cname) && (optional==false))
+ {
+ std::string cnameString = cname;
+ std::string pathString = path;
+ // get rid of potentially multiple slashes:
+ cmSystemTools::ConvertToUnixSlashes(cnameString);
+ cmSystemTools::ConvertToUnixSlashes(pathString);
+ if (cnameString != pathString)
+ {
+ const char* cvars =
+ this->GetCMakeInstance()->GetProperty(
+ "__CMAKE_DELETE_CACHE_CHANGE_VARS_");
+ if(cvars)
+ {
+ changeVars += cvars;
+ changeVars += ";";
+ }
+ changeVars += langComp;
+ changeVars += ";";
+ changeVars += cname;
+ this->GetCMakeInstance()->SetProperty(
+ "__CMAKE_DELETE_CACHE_CHANGE_VARS_",
+ changeVars.c_str());
+ }
+ }
+ mf->AddCacheDefinition(langComp.c_str(), path.c_str(),
+ doc.c_str(), cmCacheManager::FILEPATH);
+}
+
+// Find the make program for the generator, required for try compiles
+void cmGlobalGenerator::FindMakeProgram(cmMakefile* mf)
+{
+ if(this->FindMakeProgramFile.size() == 0)
+ {
+ cmSystemTools::Error(
+ "Generator implementation error, "
+ "all generators must specify this->FindMakeProgramFile");
+ }
+ if(!mf->GetDefinition("CMAKE_MAKE_PROGRAM")
+ || cmSystemTools::IsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM")))
+ {
+ std::string setMakeProgram =
+ mf->GetModulesFile(this->FindMakeProgramFile.c_str());
+ if(setMakeProgram.size())
+ {
+ mf->ReadListFile(0, setMakeProgram.c_str());
+ }
+ }
+ if(!mf->GetDefinition("CMAKE_MAKE_PROGRAM")
+ || cmSystemTools::IsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM")))
+ {
+ cmOStringStream 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.";
+ cmSystemTools::Error(err.str().c_str());
+ cmSystemTools::SetFatalErrorOccured();
+ return;
+ }
+ std::string makeProgram = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM");
+ // if there are spaces in the make program use short path
+ // but do not short path the actual program name, as
+ // this can cause trouble with VSExpress
+ if(makeProgram.find(' ') != makeProgram.npos)
+ {
+ std::string dir;
+ std::string file;
+ cmSystemTools::SplitProgramPath(makeProgram.c_str(),
+ dir, file);
+ std::string saveFile = file;
+ cmSystemTools::GetShortPath(makeProgram.c_str(), makeProgram);
+ cmSystemTools::SplitProgramPath(makeProgram.c_str(),
+ 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);
+ }
+}
+
+// enable the given language
+//
+// The following files are loaded in this order:
+//
+// First figure out what OS we are running on:
+//
+// CMakeSystem.cmake - configured file created by CMakeDetermineSystem.cmake
+// CMakeDetermineSystem.cmake - figure out os info and create
+// CMakeSystem.cmake IF CMAKE_SYSTEM
+// not set
+// CMakeSystem.cmake - configured file created by
+// CMakeDetermineSystem.cmake IF CMAKE_SYSTEM_LOADED
+
+// Next try and enable all languages found in the languages vector
+//
+// FOREACH LANG in languages
+// CMake(LANG)Compiler.cmake - configured file create by
+// CMakeDetermine(LANG)Compiler.cmake
+// CMakeDetermine(LANG)Compiler.cmake - Finds compiler for LANG and
+// creates CMake(LANG)Compiler.cmake
+// CMake(LANG)Compiler.cmake - configured file created by
+// CMakeDetermine(LANG)Compiler.cmake
+//
+// CMakeSystemSpecificInformation.cmake
+// - includes Platform/${CMAKE_SYSTEM_NAME}.cmake
+// may use compiler stuff
+
+// FOREACH LANG in languages
+// CMake(LANG)Information.cmake
+// - loads Platform/${CMAKE_SYSTEM_NAME}-${COMPILER}.cmake
+// CMakeTest(LANG)Compiler.cmake
+// - Make sure the compiler works with a try compile if
+// CMakeDetermine(LANG) was loaded
+//
+// Now load a few files that can override values set in any of the above
+// (PROJECTNAME)Compatibility.cmake
+// - load any backwards compatibility stuff for current project
+// ${CMAKE_USER_MAKE_RULES_OVERRIDE}
+// - allow users a chance to override system variables
+//
+//
+
+void
+cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
+ cmMakefile *mf, bool)
+{
+ if(languages.size() == 0)
+ {
+ cmSystemTools::Error("EnableLanguage must have a lang specified!");
+ cmSystemTools::SetFatalErrorOccured();
+ return;
+ }
+
+ if(this->TryCompileOuterMakefile)
+ {
+ // In a try-compile we can only enable languages provided by caller.
+ for(std::vector<std::string>::const_iterator li = languages.begin();
+ li != languages.end(); ++li)
+ {
+ if(*li == "NONE")
+ {
+ this->SetLanguageEnabled("NONE", mf);
+ }
+ else
+ {
+ const char* lang = li->c_str();
+ if(this->LanguagesReady.find(lang) == this->LanguagesReady.end())
+ {
+ cmOStringStream e;
+ e << "The test project needs language "
+ << lang << " which is not enabled.";
+ this->TryCompileOuterMakefile
+ ->IssueMessage(cmake::FATAL_ERROR, e.str());
+ cmSystemTools::SetFatalErrorOccured();
+ return;
+ }
+ }
+ }
+ }
+
+ mf->AddDefinition("RUN_CONFIGURE", true);
+ std::string rootBin = mf->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())
+ {
+ rootBin = this->ConfiguredFilesPath;
+ }
+
+ // set the dir for parent files so they can be used by modules
+ mf->AddDefinition("CMAKE_PLATFORM_ROOT_BIN",rootBin.c_str());
+
+ // find and make sure CMAKE_MAKE_PROGRAM is defined
+ this->FindMakeProgram(mf);
+
+ // try and load the CMakeSystem.cmake if it is there
+ std::string fpath = rootBin;
+ if(!mf->GetDefinition("CMAKE_SYSTEM_LOADED"))
+ {
+ fpath += "/CMakeSystem.cmake";
+ if(cmSystemTools::FileExists(fpath.c_str()))
+ {
+ mf->ReadListFile(0,fpath.c_str());
+ }
+ }
+ // Load the CMakeDetermineSystem.cmake file and find out
+ // what platform we are running on
+ if (!mf->GetDefinition("CMAKE_SYSTEM"))
+ {
+#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;
+ 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());
+ // 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());
+ }
+ std::map<cmStdString, bool> needTestLanguage;
+ std::map<cmStdString, bool> needSetLanguageEnabledMaps;
+ // foreach language
+ // load the CMakeDetermine(LANG)Compiler.cmake file to find
+ // the compiler
+
+ for(std::vector<std::string>::const_iterator l = languages.begin();
+ l != languages.end(); ++l)
+ {
+ const char* lang = l->c_str();
+ needSetLanguageEnabledMaps[lang] = false;
+ if(*l == "NONE")
+ {
+ this->SetLanguageEnabled("NONE", mf);
+ continue;
+ }
+ std::string loadedLang = "CMAKE_";
+ loadedLang += lang;
+ loadedLang += "_COMPILER_LOADED";
+ // If the existing build tree was already configured with this
+ // version of CMake then try to load the configured file first
+ // to avoid duplicate compiler tests.
+ unsigned int cacheMajor = mf->GetCacheMajorVersion();
+ unsigned int cacheMinor = mf->GetCacheMinorVersion();
+ unsigned int selfMajor = cmVersion::GetMajorVersion();
+ unsigned int selfMinor = cmVersion::GetMinorVersion();
+ if((this->CMakeInstance->GetIsInTryCompile() ||
+ (selfMajor == cacheMajor && selfMinor == cacheMinor))
+ && !mf->GetDefinition(loadedLang.c_str()))
+ {
+ fpath = rootBin;
+ fpath += "/CMake";
+ fpath += lang;
+ fpath += "Compiler.cmake";
+ if(cmSystemTools::FileExists(fpath.c_str()))
+ {
+ if(!mf->ReadListFile(0,fpath.c_str()))
+ {
+ cmSystemTools::Error("Could not find cmake module file:",
+ fpath.c_str());
+ }
+ // if this file was found then the language was already determined
+ // to be working
+ needTestLanguage[lang] = false;
+ this->SetLanguageEnabledFlag(lang, mf);
+ needSetLanguageEnabledMaps[lang] = true;
+ // this can only be called after loading CMake(LANG)Compiler.cmake
+ }
+ }
+
+ if(!this->GetLanguageEnabled(lang) )
+ {
+ if (this->CMakeInstance->GetIsInTryCompile())
+ {
+ cmSystemTools::Error("This should not have happen. "
+ "If you see this message, you are probably "
+ "using a broken CMakeLists.txt file or a "
+ "problematic release of CMake");
+ }
+ // if the CMake(LANG)Compiler.cmake file was not found then
+ // load CMakeDetermine(LANG)Compiler.cmake
+ std::string determineCompiler = "CMakeDetermine";
+ determineCompiler += lang;
+ determineCompiler += "Compiler.cmake";
+ std::string determineFile =
+ mf->GetModulesFile(determineCompiler.c_str());
+ if(!mf->ReadListFile(0,determineFile.c_str()))
+ {
+ cmSystemTools::Error("Could not find cmake module file:",
+ determineFile.c_str());
+ }
+ needTestLanguage[lang] = true;
+ // Some generators like visual studio should not use the env variables
+ // So the global generator can specify that in this variable
+ if(!mf->GetDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV"))
+ {
+ // put ${CMake_(LANG)_COMPILER_ENV_VAR}=${CMAKE_(LANG)_COMPILER
+ // into the environment, in case user scripts want to run
+ // configure, or sub cmakes
+ std::string compilerName = "CMAKE_";
+ compilerName += lang;
+ compilerName += "_COMPILER";
+ std::string compilerEnv = "CMAKE_";
+ compilerEnv += lang;
+ compilerEnv += "_COMPILER_ENV_VAR";
+ std::string envVar = mf->GetRequiredDefinition(compilerEnv.c_str());
+ std::string envVarValue =
+ mf->GetRequiredDefinition(compilerName.c_str());
+ std::string env = envVar;
+ env += "=";
+ env += envVarValue;
+ cmSystemTools::PutEnv(env.c_str());
+ }
+
+ // if determineLanguage was called then load the file it
+ // configures CMake(LANG)Compiler.cmake
+ fpath = rootBin;
+ fpath += "/CMake";
+ fpath += lang;
+ fpath += "Compiler.cmake";
+ if(!mf->ReadListFile(0,fpath.c_str()))
+ {
+ cmSystemTools::Error("Could not find cmake module file:",
+ fpath.c_str());
+ }
+ this->SetLanguageEnabledFlag(lang, mf);
+ needSetLanguageEnabledMaps[lang] = true;
+ // this can only be called after loading CMake(LANG)Compiler.cmake
+ // the language must be enabled for try compile to work, but we do
+ // not know if it is a working compiler yet so set the test language
+ // flag
+ needTestLanguage[lang] = true;
+ } // end if(!this->GetLanguageEnabled(lang) )
+ } // end loop over languages
+
+ // **** Load the system specific information if not yet loaded
+ if (!mf->GetDefinition("CMAKE_SYSTEM_SPECIFIC_INFORMATION_LOADED"))
+ {
+ fpath = mf->GetModulesFile("CMakeSystemSpecificInformation.cmake");
+ if(!mf->ReadListFile(0,fpath.c_str()))
+ {
+ cmSystemTools::Error("Could not find cmake module file:",
+ fpath.c_str());
+ }
+ }
+ // loop over languages again loading CMake(LANG)Information.cmake
+ //
+ for(std::vector<std::string>::const_iterator l = languages.begin();
+ l != languages.end(); ++l)
+ {
+ const char* lang = l->c_str();
+ if(*l == "NONE")
+ {
+ this->SetLanguageEnabled("NONE", mf);
+ continue;
+ }
+ std::string langLoadedVar = "CMAKE_";
+ langLoadedVar += lang;
+ langLoadedVar += "_INFORMATION_LOADED";
+ if (!mf->GetDefinition(langLoadedVar.c_str()))
+ {
+ fpath = "CMake";
+ fpath += lang;
+ fpath += "Information.cmake";
+ std::string informationFile = mf->GetModulesFile(fpath.c_str());
+ if (informationFile.empty())
+ {
+ cmSystemTools::Error("Could not find cmake module file:",
+ fpath.c_str());
+ }
+ else if(!mf->ReadListFile(0, informationFile.c_str()))
+ {
+ cmSystemTools::Error("Could not process cmake module file:",
+ informationFile.c_str());
+ }
+ }
+ if (needSetLanguageEnabledMaps[lang])
+ {
+ this->SetLanguageEnabledMaps(lang, mf);
+ }
+ 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 (!this->CMakeInstance->GetIsInTryCompile())
+ {
+ std::string testLang = "CMakeTest";
+ testLang += lang;
+ testLang += "Compiler.cmake";
+ std::string ifpath = mf->GetModulesFile(testLang.c_str());
+ if(!mf->ReadListFile(0,ifpath.c_str()))
+ {
+ cmSystemTools::Error("Could not find cmake module file:",
+ ifpath.c_str());
+ }
+ std::string compilerWorks = "CMAKE_";
+ compilerWorks += lang;
+ compilerWorks += "_COMPILER_WORKS";
+ // 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
+ {
+ // 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());
+ }
+ }
+ }
+ } // end if in try compile
+ } // end need test language
+ // Store the shared library flags so that we can satisfy CMP0018
+ std::string sharedLibFlagsVar = "CMAKE_SHARED_LIBRARY_";
+ sharedLibFlagsVar += lang;
+ sharedLibFlagsVar += "_FLAGS";
+ const char* sharedLibFlags =
+ mf->GetSafeDefinition(sharedLibFlagsVar.c_str());
+ if (sharedLibFlags)
+ {
+ this->LanguageToOriginalSharedLibFlags[lang] = sharedLibFlags;
+ }
+ } // end for each language
+
+ // Now load files that can override any settings on the platform or for
+ // the project First load the project compatibility file if it is in
+ // cmake
+ std::string projectCompatibility = mf->GetDefinition("CMAKE_ROOT");
+ projectCompatibility += "/Modules/";
+ projectCompatibility += mf->GetSafeDefinition("PROJECT_NAME");
+ projectCompatibility += "Compatibility.cmake";
+ if(cmSystemTools::FileExists(projectCompatibility.c_str()))
+ {
+ mf->ReadListFile(0,projectCompatibility.c_str());
+ }
+}
+
+//----------------------------------------------------------------------------
+const char*
+cmGlobalGenerator::GetLanguageOutputExtension(cmSourceFile const& source)
+{
+ if(const char* lang = source.GetLanguage())
+ {
+ if(this->LanguageToOutputExtension.count(lang) > 0)
+ {
+ return this->LanguageToOutputExtension[lang].c_str();
+ }
+ }
+ else
+ {
+ // if no language is found then check to see if it is already an
+ // ouput extension for some language. In that case it should be ignored
+ // and in this map, so it will not be compiled but will just be used.
+ std::string const& ext = source.GetExtension();
+ if(!ext.empty())
+ {
+ if(this->OutputExtensions.count(ext))
+ {
+ return ext.c_str();
+ }
+ }
+ }
+ return "";
+}
+
+
+const char* cmGlobalGenerator::GetLanguageFromExtension(const char* ext)
+{
+ // if there is an extension and it starts with . then move past the
+ // . because the extensions are not stored with a . in the map
+ if(ext && *ext == '.')
+ {
+ ++ext;
+ }
+ if(this->ExtensionToLanguage.count(ext) > 0)
+ {
+ return this->ExtensionToLanguage[ext].c_str();
+ }
+ return 0;
+}
+
+/* SetLanguageEnabled() is now split in two parts:
+at first the enabled-flag is set. This can then be used in EnabledLanguage()
+for checking whether the language is already enabled. After setting this
+flag still the values from the cmake variables have to be copied into the
+internal maps, this is done in SetLanguageEnabledMaps() which is called
+after the system- and compiler specific files have been loaded.
+
+This split was done originally so that compiler-specific configuration
+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)
+{
+ this->SetLanguageEnabledFlag(l, mf);
+ this->SetLanguageEnabledMaps(l, mf);
+}
+
+void cmGlobalGenerator::SetLanguageEnabledFlag(const char* l, cmMakefile* mf)
+{
+ this->LanguageEnabled[l] = true;
+
+ // Fill the language-to-extension map with the current variable
+ // settings to make sure it is available for the try_compile()
+ // command source file signature. In SetLanguageEnabledMaps this
+ // will be done again to account for any compiler- or
+ // platform-specific entries.
+ this->FillExtensionToLanguageMap(l, mf);
+}
+
+void cmGlobalGenerator::SetLanguageEnabledMaps(const char* l, cmMakefile* mf)
+{
+ // use LanguageToLinkerPreference to detect whether this functions has
+ // run before
+ if (this->LanguageToLinkerPreference.find(l) !=
+ this->LanguageToLinkerPreference.end())
+ {
+ return;
+ }
+
+ std::string linkerPrefVar = std::string("CMAKE_") +
+ std::string(l) + std::string("_LINKER_PREFERENCE");
+ const char* linkerPref = mf->GetDefinition(linkerPrefVar.c_str());
+ 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
+ // tested. So if there is a custom language out there and it is
+ // "Prefered", set its preference high
+ if (linkerPref[0]=='P')
+ {
+ preference = 100;
+ }
+ else
+ {
+ preference = 0;
+ }
+ }
+ }
+
+ if (preference < 0)
+ {
+ std::string msg = linkerPrefVar;
+ msg += " is negative, adjusting it to 0";
+ cmSystemTools::Message(msg.c_str(), "Warning");
+ preference = 0;
+ }
+
+ this->LanguageToLinkerPreference[l] = preference;
+
+ std::string outputExtensionVar = std::string("CMAKE_") +
+ std::string(l) + std::string("_OUTPUT_EXTENSION");
+ const char* outputExtension = mf->GetDefinition(outputExtensionVar.c_str());
+ if(outputExtension)
+ {
+ this->LanguageToOutputExtension[l] = outputExtension;
+ this->OutputExtensions[outputExtension] = outputExtension;
+ if(outputExtension[0] == '.')
+ {
+ this->OutputExtensions[outputExtension+1] = outputExtension+1;
+ }
+ }
+
+ // The map was originally filled by SetLanguageEnabledFlag, but
+ // since then the compiler- and platform-specific files have been
+ // loaded which might have added more entries.
+ this->FillExtensionToLanguageMap(l, mf);
+
+ std::string ignoreExtensionsVar = std::string("CMAKE_") +
+ std::string(l) + std::string("_IGNORE_EXTENSIONS");
+ std::string ignoreExts = mf->GetSafeDefinition(ignoreExtensionsVar.c_str());
+ std::vector<std::string> extensionList;
+ cmSystemTools::ExpandListArgument(ignoreExts, extensionList);
+ for(std::vector<std::string>::iterator i = extensionList.begin();
+ i != extensionList.end(); ++i)
+ {
+ this->IgnoreExtensions[*i] = true;
+ }
+
+}
+
+void cmGlobalGenerator::FillExtensionToLanguageMap(const char* 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::vector<std::string> extensionList;
+ cmSystemTools::ExpandListArgument(exts, extensionList);
+ for(std::vector<std::string>::iterator i = extensionList.begin();
+ i != extensionList.end(); ++i)
+ {
+ this->ExtensionToLanguage[*i] = l;
+ }
+}
+
+bool cmGlobalGenerator::IgnoreFile(const char* l)
+{
+ if(this->GetLanguageFromExtension(l))
+ {
+ return false;
+ }
+ return (this->IgnoreExtensions.count(l) > 0);
+}
+
+bool cmGlobalGenerator::GetLanguageEnabled(const char* l) const
+{
+ return (this->LanguageEnabled.find(l)!= this->LanguageEnabled.end());
+}
+
+void cmGlobalGenerator::ClearEnabledLanguages()
+{
+ this->LanguageEnabled.clear();
+}
+
+bool cmGlobalGenerator::IsDependedOn(const char* project,
+ cmTarget* targetIn)
+{
+ // 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)
+ {
+ 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;
+ }
+ }
+ }
+ return false;
+}
+
+void cmGlobalGenerator::Configure()
+{
+ this->FirstTimeProgress = 0.0f;
+ this->ClearGeneratorTargets();
+ this->ClearExportSets();
+ // Delete any existing cmLocalGenerators
+ unsigned int i;
+ for (i = 0; i < this->LocalGenerators.size(); ++i)
+ {
+ delete this->LocalGenerators[i];
+ }
+ this->LocalGenerators.clear();
+ this->TargetDependencies.clear();
+ this->TotalTargets.clear();
+ this->LocalGeneratorToTargetMap.clear();
+ this->ProjectMap.clear();
+ this->RuleHashes.clear();
+ this->DirectoryContentMap.clear();
+ this->BinaryDirectories.clear();
+
+ // start with this directory
+ cmLocalGenerator *lg = this->CreateLocalGenerator();
+ this->LocalGenerators.push_back(lg);
+
+ // set the Start directories
+ cmMakefile* mf = lg->GetMakefile();
+ lg->GetMakefile()->SetStartDirectory
+ (this->CMakeInstance->GetStartDirectory());
+ lg->GetMakefile()->SetStartOutputDirectory
+ (this->CMakeInstance->GetStartOutputDirectory());
+ lg->GetMakefile()->MakeStartDirectoriesCurrent();
+
+ this->BinaryDirectories.insert(mf->GetStartOutputDirectory());
+
+ // now do it
+ lg->Configure();
+
+ // 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()));
+ this->GetCMakeInstance()->AddCacheEntry
+ ("CMAKE_NUMBER_OF_LOCAL_GENERATORS", num,
+ "number of local generators", cmCacheManager::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();
+
+ if ( this->CMakeInstance->GetWorkingMode() == cmake::NORMAL_MODE)
+ {
+ const char* msg = "Configuring done";
+ if(cmSystemTools::GetErrorOccuredFlag())
+ {
+ msg = "Configuring incomplete, errors occurred!";
+ }
+ this->CMakeInstance->UpdateProgress(msg, -1);
+ }
+}
+
+bool cmGlobalGenerator::CheckALLOW_DUPLICATE_CUSTOM_TARGETS()
+{
+ // If the property is not enabled then okay.
+ if(!this->CMakeInstance
+ ->GetPropertyAsBool("ALLOW_DUPLICATE_CUSTOM_TARGETS"))
+ {
+ return true;
+ }
+
+ // This generator does not support duplicate custom targets.
+ cmOStringStream e;
+ e << "This project has enabled the ALLOW_DUPLICATE_CUSTOM_TARGETS "
+ << "global property. "
+ << "The \"" << this->GetName() << "\" generator does not support "
+ << "duplicate custom targets. "
+ << "Consider using a Makefiles generator or fix the project to not "
+ << "use duplicat target names.";
+ cmSystemTools::Error(e.str().c_str());
+ return false;
+}
+
+void cmGlobalGenerator::Generate()
+{
+ // Some generators track files replaced during the Generate.
+ // Start with an empty vector:
+ this->FilesReplacedDuringGenerate.clear();
+
+ // Check whether this generator is allowed to run.
+ if(!this->CheckALLOW_DUPLICATE_CUSTOM_TARGETS())
+ {
+ return;
+ }
+
+ // Check that all targets are valid.
+ if(!this->CheckTargets())
+ {
+ return;
+ }
+
+ // Iterate through all targets and set up automoc for those which have
+ // the AUTOMOC property set
+ this->CreateAutomocTargets();
+
+ // For each existing cmLocalGenerator
+ unsigned int i;
+
+ // Put a copy of each global target in every directory.
+ cmTargets globalTargets;
+ this->CreateDefaultGlobalTargets(&globalTargets);
+ 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);
+ }
+ }
+
+ // Add generator specific helper commands
+ for (i = 0; i < this->LocalGenerators.size(); ++i)
+ {
+ this->LocalGenerators[i]->AddHelperCommands();
+ }
+
+ // 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)
+ {
+ this->LocalGenerators[i]->TraceDependencies();
+ }
+
+ // Compute the manifest of main targets generated.
+ for (i = 0; i < this->LocalGenerators.size(); ++i)
+ {
+ this->LocalGenerators[i]->GenerateTargetManifest();
+ }
+
+ // Create per-target generator information.
+ this->CreateGeneratorTargets();
+
+ // Compute the inter-target dependencies.
+ if(!this->ComputeTargetDepends())
+ {
+ return;
+ }
+
+ // Create a map from local generator to the complete set of targets
+ // it builds by default.
+ this->FillLocalGeneratorToTargetMap();
+
+ // Generate project files
+ for (i = 0; i < this->LocalGenerators.size(); ++i)
+ {
+ this->SetCurrentLocalGenerator(this->LocalGenerators[i]);
+ this->LocalGenerators[i]->Generate();
+ 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);
+
+ // Update rule hashes.
+ this->CheckRuleHashes();
+
+ this->WriteSummary();
+
+ if (this->ExtraGenerator != 0)
+ {
+ this->ExtraGenerator->Generate();
+ }
+
+ this->CMakeInstance->UpdateProgress("Generating done", -1);
+}
+
+//----------------------------------------------------------------------------
+bool cmGlobalGenerator::ComputeTargetDepends()
+{
+ cmComputeTargetDepends ctd(this);
+ if(!ctd.Compute())
+ {
+ return false;
+ }
+ std::vector<cmTarget*> const& targets = ctd.GetTargets();
+ for(std::vector<cmTarget*>::const_iterator ti = targets.begin();
+ ti != targets.end(); ++ti)
+ {
+ ctd.GetTargetDirectDepends(*ti, this->TargetDependencies[*ti]);
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmGlobalGenerator::CheckTargets()
+{
+ // 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::UTILITY)
+ {
+ if(!target.FindSourceFiles())
+ {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalGenerator::CreateAutomocTargets()
+{
+#ifdef CMAKE_BUILD_WITH_CMAKE
+ 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)
+ {
+ if(target.GetPropertyAsBool("AUTOMOC") && !target.IsImported())
+ {
+ cmQtAutomoc automoc;
+ automoc.SetupAutomocTarget(&target);
+ }
+ }
+ }
+ }
+#endif
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalGenerator::CreateGeneratorTargets()
+{
+ // Construct per-target generator information.
+ 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* t = &ti->second;
+ cmGeneratorTarget* gt = new cmGeneratorTarget(t);
+ this->GeneratorTargets[t] = gt;
+ this->ComputeTargetObjects(gt);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalGenerator::ClearGeneratorTargets()
+{
+ for(GeneratorTargetsType::iterator i = this->GeneratorTargets.begin();
+ i != this->GeneratorTargets.end(); ++i)
+ {
+ delete i->second;
+ }
+ this->GeneratorTargets.clear();
+}
+
+//----------------------------------------------------------------------------
+cmGeneratorTarget* cmGlobalGenerator::GetGeneratorTarget(cmTarget* t) const
+{
+ GeneratorTargetsType::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;
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalGenerator::ComputeTargetObjects(cmGeneratorTarget*) const
+{
+ // Implemented in generator subclasses that need this.
+}
+
+void cmGlobalGenerator::CheckLocalGenerators()
+{
+ std::map<cmStdString, cmStdString> notFoundMap;
+// std::set<cmStdString> notFoundMap;
+ // after it is all done do a ConfigureFinalPass
+ cmCacheManager* manager = 0;
+ for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i)
+ {
+ manager = this->LocalGenerators[i]->GetMakefile()->GetCacheManager();
+ this->LocalGenerators[i]->ConfigureFinalPass();
+ cmTargets & targets =
+ this->LocalGenerators[i]->GetMakefile()->GetTargets();
+ for (cmTargets::iterator l = targets.begin();
+ l != targets.end(); l++)
+ {
+ const cmTarget::LinkLibraryVectorType& libs =
+ l->second.GetOriginalLinkLibraries();
+ for(cmTarget::LinkLibraryVectorType::const_iterator lib = libs.begin();
+ lib != libs.end(); ++lib)
+ {
+ if(lib->first.size() > 9 &&
+ 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"))
+ {
+ varName += " (ADVANCED)";
+ }
+ std::string text = notFoundMap[varName];
+ text += "\n linked by target \"";
+ text += l->second.GetName();
+ text += "\" in directory ";
+ text+=this->LocalGenerators[i]->GetMakefile()->GetCurrentDirectory();
+ notFoundMap[varName] = text;
+ }
+ }
+ std::vector<std::string> incs;
+ this->LocalGenerators[i]->GetIncludeDirectories(incs, &l->second);
+
+ for( std::vector<std::string>::const_iterator incDir = incs.begin();
+ incDir != incs.end(); ++incDir)
+ {
+ if(incDir->size() > 9 &&
+ 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"))
+ {
+ varName += " (ADVANCED)";
+ }
+ std::string text = notFoundMap[varName];
+ text += "\n used as include directory in directory ";
+ text += this->LocalGenerators[i]
+ ->GetMakefile()->GetCurrentDirectory();
+ notFoundMap[varName] = text;
+ }
+ }
+ }
+ this->CMakeInstance->UpdateProgress
+ ("Configuring", 0.9f+0.1f*(static_cast<float>(i)+1.0f)/
+ static_cast<float>(this->LocalGenerators.size()));
+ }
+
+ if(notFoundMap.size())
+ {
+ std::string notFoundVars;
+ for(std::map<cmStdString, cmStdString>::const_iterator
+ ii = notFoundMap.begin();
+ ii != notFoundMap.end();
+ ++ii)
+ {
+ notFoundVars += ii->first;
+ notFoundVars += ii->second;
+ notFoundVars += "\n";
+ }
+ cmSystemTools::Error("The following variables are used in this project, "
+ "but they are set to NOTFOUND.\n"
+ "Please set them or make sure they are set and "
+ "tested correctly in the CMake files:\n",
+ notFoundVars.c_str());
+ }
+}
+
+int cmGlobalGenerator::TryCompile(const char *srcdir, const char *bindir,
+ const char *projectName,
+ const char *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 CMAKE_NUMBER_OF_LOCAL_GENERATORS 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%
+ this->FirstTimeProgress += ((1.0f - this->FirstTimeProgress) /30.0f);
+ if(this->FirstTimeProgress > 0.95f)
+ {
+ this->FirstTimeProgress = 0.95f;
+ }
+ this->CMakeInstance->UpdateProgress("Configuring",
+ 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))
+ {
+ newTarget += target;
+#if 0
+#if defined(_WIN32) || defined(__CYGWIN__)
+ std::string tmp = target;
+ // if the target does not already end in . something
+ // then assume .exe
+ if(tmp.size() < 4 || tmp[tmp.size()-4] != '.')
+ {
+ newTarget += ".exe";
+ }
+#endif // WIN32
+#endif
+ }
+ const char* config = mf->GetDefinition("CMAKE_TRY_COMPILE_CONFIGURATION");
+ return this->Build(srcdir,bindir,projectName,
+ newTarget.c_str(),
+ output,makeCommand.c_str(),config,false,fast,
+ this->TryCompileTimeout);
+}
+
+std::string cmGlobalGenerator
+::GenerateBuildCommand(const char* makeProgram, const char *projectName,
+ const char* additionalOptions, const char *targetName,
+ const char* config, bool ignoreErrors, bool)
+{
+ // Project name and config are not used yet.
+ (void)projectName;
+ (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;
+}
+
+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,
+ double timeout,
+ cmSystemTools::OutputOption outputflag,
+ const char* extraOptions,
+ std::vector<std::string> const& nativeOptions)
+{
+ /**
+ * Run an executable command and put the stdout in output.
+ */
+ std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
+ cmSystemTools::ChangeDirectory(bindir);
+ if(output)
+ {
+ *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)
+ {
+ outputPtr = &outputBuffer;
+ }
+
+ // should we do a clean first?
+ if (clean)
+ {
+ std::string cleanCommand =
+ this->GenerateBuildCommand(makeCommandCSTR, projectName,
+ 0, "clean", config, false, fast);
+ if(output)
+ {
+ *output += "\nRun Clean Command:";
+ *output += cleanCommand;
+ *output += "\n";
+ }
+
+ if (!cmSystemTools::RunSingleCommand(cleanCommand.c_str(), 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";
+ }
+
+ // return to the original directory
+ cmSystemTools::ChangeDirectory(cwd.c_str());
+ return 1;
+ }
+ if (output)
+ {
+ *output += *outputPtr;
+ }
+ }
+
+ // now build
+ std::string makeCommand =
+ this->GenerateBuildCommand(makeCommandCSTR, projectName,
+ 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);
+ }
+
+ if (!cmSystemTools::RunSingleCommand(command, 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";
+ }
+
+ // return to the original directory
+ cmSystemTools::ChangeDirectory(cwd.c_str());
+ return 1;
+ }
+ if (output)
+ {
+ *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))
+ {
+ retVal = 1;
+ }
+
+ cmSystemTools::ChangeDirectory(cwd.c_str());
+ return retVal;
+}
+
+void cmGlobalGenerator::AddLocalGenerator(cmLocalGenerator *lg)
+{
+ this->LocalGenerators.push_back(lg);
+
+ // update progress
+ // estimate how many lg there will be
+ const char *numGenC =
+ this->CMakeInstance->GetCacheManager()->GetCacheValue
+ ("CMAKE_NUMBER_OF_LOCAL_GENERATORS");
+
+ if (!numGenC)
+ {
+ // If CMAKE_NUMBER_OF_LOCAL_GENERATORS 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%
+ this->FirstTimeProgress += ((1.0f - this->FirstTimeProgress) /30.0f);
+ if(this->FirstTimeProgress > 0.95f)
+ {
+ this->FirstTimeProgress = 0.95f;
+ }
+ this->CMakeInstance->UpdateProgress("Configuring",
+ this->FirstTimeProgress);
+ return;
+ }
+
+ int numGen = atoi(numGenC);
+ float prog = 0.9f*static_cast<float>(this->LocalGenerators.size())/
+ static_cast<float>(numGen);
+ if (prog > 0.9f)
+ {
+ prog = 0.9f;
+ }
+ this->CMakeInstance->UpdateProgress("Configuring", prog);
+}
+
+void cmGlobalGenerator::AddInstallComponent(const char* component)
+{
+ if(component && *component)
+ {
+ this->InstallComponents.insert(component);
+ }
+}
+
+void cmGlobalGenerator::AddTargetToExports(const char* exportSetName,
+ cmTarget* target,
+ cmInstallTargetGenerator* archive,
+ cmInstallTargetGenerator* runTime,
+ cmInstallTargetGenerator* library,
+ cmInstallTargetGenerator* framework,
+ cmInstallTargetGenerator* bundle,
+ cmInstallFilesGenerator* headers)
+{
+ if ((exportSetName) && (*exportSetName) && (target))
+ {
+ cmTargetExport* te = new cmTargetExport(target, archive, runTime, library,
+ framework, bundle, headers);
+ this->ExportSets[exportSetName].push_back(te);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalGenerator::ClearExportSets()
+{
+ for(std::map<cmStdString, std::vector<cmTargetExport*> >::iterator
+ setIt = this->ExportSets.begin();
+ setIt != this->ExportSets.end(); ++setIt)
+ {
+ for(unsigned int i = 0; i < setIt->second.size(); ++i)
+ {
+ delete setIt->second[i];
+ }
+ }
+ this->ExportSets.clear();
+}
+
+const std::vector<cmTargetExport*>* cmGlobalGenerator::GetExportSet(
+ const char* name) const
+{
+ std::map<cmStdString, std::vector<cmTargetExport*> >::const_iterator
+ exportSetIt = this->ExportSets.find(name);
+ if (exportSetIt != this->ExportSets.end())
+ {
+ return &exportSetIt->second;
+ }
+
+ return 0;
+}
+
+
+void cmGlobalGenerator::EnableInstallTarget()
+{
+ this->InstallTargetEnabled = true;
+}
+
+cmLocalGenerator *cmGlobalGenerator::CreateLocalGenerator()
+{
+ cmLocalGenerator *lg = new cmLocalGenerator;
+ lg->SetGlobalGenerator(this);
+ return lg;
+}
+
+void cmGlobalGenerator::EnableLanguagesFromGenerator(cmGlobalGenerator *gen,
+ cmMakefile* mf)
+{
+ this->SetConfiguredFilesPath(gen);
+ this->TryCompileOuterMakefile = mf;
+ const char* make =
+ gen->GetCMakeInstance()->GetCacheDefinition("CMAKE_MAKE_PROGRAM");
+ this->GetCMakeInstance()->AddCacheEntry("CMAKE_MAKE_PROGRAM", make,
+ "make program",
+ cmCacheManager::FILEPATH);
+ // copy the enabled languages
+ this->LanguageEnabled = gen->LanguageEnabled;
+ this->LanguagesReady = gen->LanguagesReady;
+ this->ExtensionToLanguage = gen->ExtensionToLanguage;
+ this->IgnoreExtensions = gen->IgnoreExtensions;
+ this->LanguageToOutputExtension = gen->LanguageToOutputExtension;
+ this->LanguageToLinkerPreference = gen->LanguageToLinkerPreference;
+ this->OutputExtensions = gen->OutputExtensions;
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalGenerator::SetConfiguredFilesPath(cmGlobalGenerator* gen)
+{
+ if(!gen->ConfiguredFilesPath.empty())
+ {
+ this->ConfiguredFilesPath = gen->ConfiguredFilesPath;
+ }
+ else
+ {
+ this->ConfiguredFilesPath = gen->CMakeInstance->GetHomeOutputDirectory();
+ this->ConfiguredFilesPath += cmake::GetCMakeFilesDirectory();
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalGenerator::GetDocumentation(cmDocumentationEntry& entry) const
+{
+ entry.Name = this->GetName();
+ entry.Brief = "";
+ entry.Full = "";
+}
+
+bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root,
+ cmLocalGenerator* gen)
+{
+ if(!gen || gen == root)
+ {
+ // No directory excludes itself.
+ return false;
+ }
+
+ if(gen->GetMakefile()->GetPropertyAsBool("EXCLUDE_FROM_ALL"))
+ {
+ // This directory is excluded from its parent.
+ return true;
+ }
+
+ // This directory is included in its parent. Check whether the
+ // parent is excluded.
+ return this->IsExcluded(root, gen->GetParent());
+}
+
+bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root,
+ cmTarget& target)
+{
+ if(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());
+ }
+}
+
+void cmGlobalGenerator::GetEnabledLanguages(std::vector<std::string>& lang)
+{
+ for(std::map<cmStdString, bool>::iterator i =
+ this->LanguageEnabled.begin(); i != this->LanguageEnabled.end(); ++i)
+ {
+ lang.push_back(i->first);
+ }
+}
+
+int cmGlobalGenerator::GetLinkerPreference(const char* lang)
+{
+ std::map<cmStdString, int>::const_iterator it =
+ this->LanguageToLinkerPreference.find(lang);
+ if (it != this->LanguageToLinkerPreference.end())
+ {
+ return it->second;
+ }
+ return 0;
+}
+
+void cmGlobalGenerator::FillProjectMap()
+{
+ this->ProjectMap.clear(); // make sure we start with a clean map
+ unsigned int i;
+ for(i = 0; i < this->LocalGenerators.size(); ++i)
+ {
+ // for each local generator add all projects
+ cmLocalGenerator *lg = this->LocalGenerators[i];
+ std::string name;
+ do
+ {
+ if (name != lg->GetMakefile()->GetProjectName())
+ {
+ name = lg->GetMakefile()->GetProjectName();
+ this->ProjectMap[name].push_back(this->LocalGenerators[i]);
+ }
+ lg = lg->GetParent();
+ }
+ while (lg);
+ }
+}
+
+
+// Build a map that contains a the set of targets used by each local
+// generator directory level.
+void cmGlobalGenerator::FillLocalGeneratorToTargetMap()
+{
+ 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)
+ {
+ cmLocalGenerator* lg = *lgi;
+ cmMakefile* mf = lg->GetMakefile();
+ cmTargets& targets = mf->GetTargets();
+ for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t)
+ {
+ 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);
+ }
+ }
+ }
+ }
+}
+
+
+///! Find a local generator by its startdirectory
+cmLocalGenerator* cmGlobalGenerator::FindLocalGenerator(const char* start_dir)
+{
+ std::vector<cmLocalGenerator*>* gens = &this->LocalGenerators;
+ for(unsigned int i = 0; i < gens->size(); ++i)
+ {
+ std::string sd = (*gens)[i]->GetMakefile()->GetStartDirectory();
+ if (sd == start_dir)
+ {
+ return (*gens)[i];
+ }
+ }
+ return 0;
+}
+
+
+//----------------------------------------------------------------------------
+cmTarget*
+cmGlobalGenerator::FindTarget(const char* project, const char* name)
+{
+ // if project specific
+ if(project)
+ {
+ std::vector<cmLocalGenerator*>* gens = &this->ProjectMap[project];
+ for(unsigned int i = 0; i < gens->size(); ++i)
+ {
+ cmTarget* ret = (*gens)[i]->GetMakefile()->FindTarget(name);
+ if(ret)
+ {
+ return ret;
+ }
+ }
+ }
+ // if all projects/directories
+ else
+ {
+ 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 0;
+}
+
+//----------------------------------------------------------------------------
+bool cmGlobalGenerator::NameResolvesToFramework(const std::string& libname)
+{
+ if(cmSystemTools::IsPathToFramework(libname.c_str()))
+ {
+ return true;
+ }
+
+ if(cmTarget* tgt = this->FindTarget(0, libname.c_str()))
+ {
+ if(tgt->IsFrameworkOnApple())
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+//----------------------------------------------------------------------------
+inline std::string removeQuotes(const std::string& s)
+{
+ if(s[0] == '\"' && s[s.size()-1] == '\"')
+ {
+ return s.substr(1, s.size()-2);
+ }
+ 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();
+ const char* cmakeCfgIntDir = this->GetCMakeCFGIntDir();
+ const char* cmakeCommand = mf->GetRequiredDefinition("CMAKE_COMMAND");
+
+ // CPack
+ std::string workingDir = mf->GetStartOutputDirectory();
+ cmCustomCommandLines cpackCommandLines;
+ std::vector<std::string> depends;
+ cmCustomCommandLine singleLine;
+ singleLine.push_back(this->GetCMakeInstance()->GetCPackCommand());
+ if ( cmakeCfgIntDir && *cmakeCfgIntDir && cmakeCfgIntDir[0] != '.' )
+ {
+ singleLine.push_back("-C");
+ singleLine.push_back(cmakeCfgIntDir);
+ }
+ singleLine.push_back("--config");
+ std::string configFile = mf->GetStartOutputDirectory();;
+ configFile += "/CPackConfig.cmake";
+ std::string relConfigFile = "./CPackConfig.cmake";
+ singleLine.push_back(relConfigFile);
+ cpackCommandLines.push_back(singleLine);
+ if ( this->GetPreinstallTargetName() )
+ {
+ depends.push_back(this->GetPreinstallTargetName());
+ }
+ else
+ {
+ const char* noPackageAll =
+ mf->GetDefinition("CMAKE_SKIP_PACKAGE_ALL_DEPENDENCY");
+ if(!noPackageAll || cmSystemTools::IsOff(noPackageAll))
+ {
+ depends.push_back(this->GetAllTargetName());
+ }
+ }
+ if(cmSystemTools::FileExists(configFile.c_str()))
+ {
+ (*targets)[this->GetPackageTargetName()]
+ = this->CreateGlobalTarget(this->GetPackageTargetName(),
+ "Run CPack packaging tool...",
+ &cpackCommandLines, depends,
+ workingDir.c_str());
+ }
+ // CPack source
+ const char* packageSourceTargetName = this->GetPackageSourceTargetName();
+ if ( packageSourceTargetName )
+ {
+ cpackCommandLines.erase(cpackCommandLines.begin(),
+ cpackCommandLines.end());
+ singleLine.erase(singleLine.begin(), singleLine.end());
+ depends.erase(depends.begin(), depends.end());
+ singleLine.push_back(this->GetCMakeInstance()->GetCPackCommand());
+ singleLine.push_back("--config");
+ configFile = mf->GetStartOutputDirectory();;
+ configFile += "/CPackSourceConfig.cmake";
+ relConfigFile = "./CPackSourceConfig.cmake";
+ singleLine.push_back(relConfigFile);
+ if(cmSystemTools::FileExists(configFile.c_str()))
+ {
+ singleLine.push_back(configFile);
+ cpackCommandLines.push_back(singleLine);
+ (*targets)[packageSourceTargetName]
+ = this->CreateGlobalTarget(packageSourceTargetName,
+ "Run CPack packaging tool for source...",
+ &cpackCommandLines, depends,
+ workingDir.c_str()
+ );
+ }
+ }
+
+ // Test
+ if(mf->IsOn("CMAKE_TESTING_ENABLED"))
+ {
+ cpackCommandLines.erase(cpackCommandLines.begin(),
+ cpackCommandLines.end());
+ singleLine.erase(singleLine.begin(), singleLine.end());
+ depends.erase(depends.begin(), depends.end());
+ singleLine.push_back(this->GetCMakeInstance()->GetCTestCommand());
+ singleLine.push_back("--force-new-ctest-process");
+ if(cmakeCfgIntDir && *cmakeCfgIntDir && cmakeCfgIntDir[0] != '.')
+ {
+ singleLine.push_back("-C");
+ singleLine.push_back(cmakeCfgIntDir);
+ }
+ else // TODO: This is a hack. Should be something to do with the generator
+ {
+ singleLine.push_back("$(ARGS)");
+ }
+ cpackCommandLines.push_back(singleLine);
+ (*targets)[this->GetTestTargetName()]
+ = this->CreateGlobalTarget(this->GetTestTargetName(),
+ "Running tests...", &cpackCommandLines, depends, 0);
+ }
+
+ //Edit Cache
+ const char* editCacheTargetName = this->GetEditCacheTargetName();
+ if ( editCacheTargetName )
+ {
+ cpackCommandLines.erase(cpackCommandLines.begin(),
+ cpackCommandLines.end());
+ 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"))
+ {
+ singleLine.push_back(mf->GetDefinition("CMAKE_EDIT_COMMAND"));
+ 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);
+ }
+ else
+ {
+ singleLine.push_back(cmakeCommand);
+ singleLine.push_back("-i");
+ singleLine.push_back(".");
+ cpackCommandLines.push_back(singleLine);
+ (*targets)[editCacheTargetName] =
+ this->CreateGlobalTarget(
+ editCacheTargetName,
+ "Running interactive CMake command-line interface...",
+ &cpackCommandLines, depends, 0);
+ }
+ }
+
+ //Rebuild Cache
+ const char* rebuildCacheTargetName = this->GetRebuildCacheTargetName();
+ if ( rebuildCacheTargetName )
+ {
+ cpackCommandLines.erase(cpackCommandLines.begin(),
+ cpackCommandLines.end());
+ singleLine.erase(singleLine.begin(), singleLine.end());
+ depends.erase(depends.begin(), depends.end());
+ singleLine.push_back(cmakeCommand);
+ 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);
+ }
+
+ //Install
+ if(this->InstallTargetEnabled)
+ {
+ if(!cmakeCfgIntDir || !*cmakeCfgIntDir || cmakeCfgIntDir[0] == '.')
+ {
+ std::set<cmStdString>* componentsSet = &this->InstallComponents;
+ cpackCommandLines.erase(cpackCommandLines.begin(),
+ cpackCommandLines.end());
+ depends.erase(depends.begin(), depends.end());
+ cmOStringStream ostr;
+ if ( componentsSet->size() > 0 )
+ {
+ ostr << "Available install components are:";
+ std::set<cmStdString>::iterator it;
+ for (
+ it = componentsSet->begin();
+ it != componentsSet->end();
+ ++ it )
+ {
+ ostr << " \"" << it->c_str() << "\"";
+ }
+ }
+ else
+ {
+ ostr << "Only default component available";
+ }
+ singleLine.push_back(ostr.str().c_str());
+ (*targets)["list_install_components"]
+ = this->CreateGlobalTarget("list_install_components",
+ ostr.str().c_str(),
+ &cpackCommandLines, depends, 0);
+ }
+ std::string cmd = cmakeCommand;
+ cpackCommandLines.erase(cpackCommandLines.begin(),
+ cpackCommandLines.end());
+ singleLine.erase(singleLine.begin(), singleLine.end());
+ depends.erase(depends.begin(), depends.end());
+ if ( this->GetPreinstallTargetName() )
+ {
+ depends.push_back(this->GetPreinstallTargetName());
+ }
+ else
+ {
+ const char* noall =
+ mf->GetDefinition("CMAKE_SKIP_INSTALL_ALL_DEPENDENCY");
+ if(!noall || cmSystemTools::IsOff(noall))
+ {
+ depends.push_back(this->GetAllTargetName());
+ }
+ }
+ if(mf->GetDefinition("CMake_BINARY_DIR"))
+ {
+ // 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());
+ if ( cmakeCfgIntDir && *cmakeCfgIntDir && cmakeCfgIntDir[0] != '.' )
+ {
+ std::string cfgArg = "-DBUILD_TYPE=";
+ cfgArg += mf->GetDefinition("CMAKE_CFG_INTDIR");
+ singleLine.push_back(cfgArg);
+ }
+ singleLine.push_back("-P");
+ singleLine.push_back("cmake_install.cmake");
+ cpackCommandLines.push_back(singleLine);
+ (*targets)[this->GetInstallTargetName()] =
+ this->CreateGlobalTarget(
+ this->GetInstallTargetName(), "Install the project...",
+ &cpackCommandLines, depends, 0);
+
+ // install_local
+ if(const char* install_local = this->GetInstallLocalTargetName())
+ {
+ cmCustomCommandLine localCmdLine = singleLine;
+
+ localCmdLine.insert(localCmdLine.begin()+1,
+ "-DCMAKE_INSTALL_LOCAL_ONLY=1");
+ cpackCommandLines.erase(cpackCommandLines.begin(),
+ cpackCommandLines.end());
+ cpackCommandLines.push_back(localCmdLine);
+
+ (*targets)[install_local] =
+ this->CreateGlobalTarget(
+ install_local, "Installing only the local directory...",
+ &cpackCommandLines, depends, 0);
+ }
+
+ // install_strip
+ const char* install_strip = this->GetInstallStripTargetName();
+ if((install_strip !=0) && (mf->IsSet("CMAKE_STRIP")))
+ {
+ cmCustomCommandLine stripCmdLine = singleLine;
+
+ stripCmdLine.insert(stripCmdLine.begin()+1,"-DCMAKE_INSTALL_DO_STRIP=1");
+ cpackCommandLines.erase(cpackCommandLines.begin(),
+ cpackCommandLines.end());
+ cpackCommandLines.push_back(stripCmdLine);
+
+ (*targets)[install_strip] =
+ this->CreateGlobalTarget(
+ install_strip, "Installing the project stripped...",
+ &cpackCommandLines, depends, 0);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+const char* cmGlobalGenerator::GetPredefinedTargetsFolder()
+{
+ const char* prop =
+ this->GetCMakeInstance()->GetProperty("PREDEFINED_TARGETS_FOLDER");
+
+ if (prop)
+ {
+ return prop;
+ }
+
+ return "CMakePredefinedTargets";
+}
+
+//----------------------------------------------------------------------------
+bool cmGlobalGenerator::UseFolderProperty()
+{
+ const char* prop = this->GetCMakeInstance()->GetProperty("USE_FOLDERS");
+
+ // If this property is defined, let the setter turn this on or off...
+ //
+ if (prop)
+ {
+ return cmSystemTools::IsOn(prop);
+ }
+
+ // By default, this feature is OFF, since it is not supported in the
+ // Visual Studio Express editions:
+ //
+ return false;
+}
+
+//----------------------------------------------------------------------------
+cmTarget cmGlobalGenerator::CreateGlobalTarget(
+ const char* name, const char* message,
+ const cmCustomCommandLines* commandLines,
+ std::vector<std::string> depends,
+ const char* workingDirectory)
+{
+ // Package
+ cmTarget target;
+ target.GetProperties().SetCMakeInstance(this->CMakeInstance);
+ target.SetType(cmTarget::GLOBAL_TARGET, name);
+ target.SetProperty("EXCLUDE_FROM_ALL","TRUE");
+
+ std::vector<std::string> no_outputs;
+ 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);
+ target.SetProperty("EchoString", message);
+ std::vector<std::string>::iterator dit;
+ for ( dit = depends.begin(); dit != depends.end(); ++ dit )
+ {
+ target.AddUtility(dit->c_str());
+ }
+
+ // Organize in the "predefined targets" folder:
+ //
+ if (this->UseFolderProperty())
+ {
+ target.SetProperty("FOLDER", this->GetPredefinedTargetsFolder());
+ }
+
+ return target;
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmGlobalGenerator::GenerateRuleFile(std::string const& output) const
+{
+ std::string ruleFile = output;
+ ruleFile += ".rule";
+ const char* dir = this->GetCMakeCFGIntDir();
+ if(dir && dir[0] == '$')
+ {
+ cmSystemTools::ReplaceString(ruleFile, dir,
+ cmake::GetCMakeFilesDirectory());
+ }
+ return ruleFile;
+}
+
+//----------------------------------------------------------------------------
+std::string cmGlobalGenerator::GetSharedLibFlagsForLanguage(
+ std::string const& l)
+{
+ if(this->LanguageToOriginalSharedLibFlags.count(l) > 0)
+ {
+ return this->LanguageToOriginalSharedLibFlags[l];
+ }
+ return "";
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalGenerator::AppendDirectoryForConfig(const char*, const char*,
+ const char*, std::string&)
+{
+ // Subclasses that support multiple configurations should implement
+ // this method to append the subdirectory for the given build
+ // configuration.
+}
+
+//----------------------------------------------------------------------------
+cmGlobalGenerator::TargetDependSet const&
+cmGlobalGenerator::GetTargetDirectDepends(cmTarget & target)
+{
+ return this->TargetDependencies[&target];
+}
+
+void cmGlobalGenerator::AddTarget(cmTarget* t)
+{
+ if(t->IsImported())
+ {
+ this->ImportedTargets[t->GetName()] = t;
+ }
+ else
+ {
+ this->TotalTargets[t->GetName()] = t;
+ }
+}
+
+void cmGlobalGenerator::SetExternalMakefileProjectGenerator(
+ cmExternalMakefileProjectGenerator *extraGenerator)
+{
+ this->ExtraGenerator = extraGenerator;
+ if (this->ExtraGenerator!=0)
+ {
+ this->ExtraGenerator->SetGlobalGenerator(this);
+ }
+}
+
+const char* cmGlobalGenerator::GetExtraGeneratorName() const
+{
+ return this->ExtraGenerator==0 ? 0 : this->ExtraGenerator->GetName();
+}
+
+void cmGlobalGenerator::FileReplacedDuringGenerate(const std::string& filename)
+{
+ this->FilesReplacedDuringGenerate.push_back(filename);
+}
+
+void
+cmGlobalGenerator
+::GetFilesReplacedDuringGenerate(std::vector<std::string>& filenames)
+{
+ filenames.clear();
+ std::copy(
+ this->FilesReplacedDuringGenerate.begin(),
+ this->FilesReplacedDuringGenerate.end(),
+ std::back_inserter(filenames));
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalGenerator::GetTargetSets(TargetDependSet& projectTargets,
+ TargetDependSet& originalTargets,
+ cmLocalGenerator* root,
+ GeneratorVector const& generators)
+{
+ // loop over all local generators
+ for(std::vector<cmLocalGenerator*>::const_iterator i = generators.begin();
+ i != generators.end(); ++i)
+ {
+ // check to make sure generator is not excluded
+ if(this->IsExcluded(root, *i))
+ {
+ continue;
+ }
+ cmMakefile* mf = (*i)->GetMakefile();
+ // Get the targets in the makefile
+ cmTargets &tgts = mf->GetTargets();
+ // loop over all the targets
+ for (cmTargets::iterator l = tgts.begin(); l != tgts.end(); ++l)
+ {
+ cmTarget* target = &l->second;
+ if(this->IsRootOnlyTarget(target) &&
+ target->GetMakefile() != root->GetMakefile())
+ {
+ continue;
+ }
+ // put the target in the set of original targets
+ originalTargets.insert(target);
+ // Get the set of targets that depend on target
+ this->AddTargetDepends(target, projectTargets);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmGlobalGenerator::IsRootOnlyTarget(cmTarget* target)
+{
+ return (target->GetType() == cmTarget::GLOBAL_TARGET ||
+ strcmp(target->GetName(), this->GetAllTargetName()) == 0);
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalGenerator::AddTargetDepends(cmTarget* target,
+ TargetDependSet& projectTargets)
+{
+ // add the target itself
+ if(projectTargets.insert(target).second)
+ {
+ // This is the first time we have encountered the target.
+ // Recursively follow its dependencies.
+ TargetDependSet const& ts = this->GetTargetDirectDepends(*target);
+ for(TargetDependSet::const_iterator i = ts.begin(); i != ts.end(); ++i)
+ {
+ cmTarget* dtarget = *i;
+ this->AddTargetDepends(dtarget, projectTargets);
+ }
+ }
+}
+
+
+//----------------------------------------------------------------------------
+void cmGlobalGenerator::AddToManifest(const char* config,
+ 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);
+}
+
+//----------------------------------------------------------------------------
+std::set<cmStdString> const&
+cmGlobalGenerator::GetDirectoryContent(std::string const& dir, bool needDisk)
+{
+ DirectoryContent& dc = this->DirectoryContentMap[dir];
+ if(needDisk && !dc.LoadedFromDisk)
+ {
+ // Load the directory content from disk.
+ cmsys::Directory d;
+ if(d.Load(dir.c_str()))
+ {
+ unsigned long n = d.GetNumberOfFiles();
+ for(unsigned long i = 0; i < n; ++i)
+ {
+ const char* f = d.GetFile(i);
+ if(strcmp(f, ".") != 0 && strcmp(f, "..") != 0)
+ {
+ dc.insert(f);
+ }
+ }
+ }
+ dc.LoadedFromDisk = true;
+ }
+ return dc;
+}
+
+//----------------------------------------------------------------------------
+void
+cmGlobalGenerator::AddRuleHash(const std::vector<std::string>& outputs,
+ std::string const& content)
+{
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ // Ignore if there are no outputs.
+ if(outputs.empty())
+ {
+ return;
+ }
+
+ // Compute a hash of the rule.
+ RuleHash hash;
+ {
+ unsigned char const* data =
+ reinterpret_cast<unsigned char const*>(content.c_str());
+ int length = static_cast<int>(content.length());
+ cmsysMD5* sum = cmsysMD5_New();
+ cmsysMD5_Initialize(sum);
+ cmsysMD5_Append(sum, data, length);
+ cmsysMD5_FinalizeHex(sum, hash.Data);
+ cmsysMD5_Delete(sum);
+ }
+
+ // 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);
+
+ // Associate the hash with this output.
+ this->RuleHashes[fname] = hash;
+#else
+ (void)outputs;
+ (void)content;
+#endif
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalGenerator::CheckRuleHashes()
+{
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ std::string home = this->GetCMakeInstance()->GetHomeOutputDirectory();
+ std::string pfile = home;
+ pfile += this->GetCMakeInstance()->GetCMakeFilesDirectory();
+ pfile += "/CMakeRuleHashes.txt";
+ this->CheckRuleHashes(pfile, home);
+ this->WriteRuleHashes(pfile);
+#endif
+}
+
+//----------------------------------------------------------------------------
+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);
+#else
+ std::ifstream fin(pfile.c_str(), std::ios::in);
+#endif
+ if(!fin)
+ {
+ return;
+ }
+ std::string line;
+ std::string fname;
+ while(cmSystemTools::GetLineFromStream(fin, line))
+ {
+ // Line format is a 32-byte hex string followed by a space
+ // followed by a file name (with no escaping).
+
+ // Skip blank and comment lines.
+ if(line.size() < 34 || line[0] == '#')
+ {
+ continue;
+ }
+
+ // Get the filename.
+ fname = line.substr(33, line.npos);
+
+ // Look for a hash for this file's rule.
+ std::map<cmStdString, RuleHash>::const_iterator rhi =
+ this->RuleHashes.find(fname);
+ if(rhi != this->RuleHashes.end())
+ {
+ // Compare the rule hash in the file to that we were given.
+ if(strncmp(line.c_str(), rhi->second.Data, 32) != 0)
+ {
+ // 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());
+ }
+ }
+ else
+ {
+ // We have no hash for a rule previously listed. This may be a
+ // case where a user has turned off a build option and might
+ // want to turn it back on later, so do not delete the file.
+ // Instead, we keep the rule hash as long as the file exists so
+ // 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());
+ if(cmSystemTools::FileExists(fpath.c_str()))
+ {
+ RuleHash hash;
+ strncpy(hash.Data, line.c_str(), 32);
+ this->RuleHashes[fname] = hash;
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+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());
+ }
+ else
+ {
+ cmGeneratedFileStream fout(pfile.c_str());
+ fout << "# Hashes of file build rules.\n";
+ for(std::map<cmStdString, RuleHash>::const_iterator
+ rhi = this->RuleHashes.begin(); rhi != this->RuleHashes.end(); ++rhi)
+ {
+ fout.write(rhi->second.Data, 32);
+ fout << " " << rhi->first << "\n";
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalGenerator::WriteSummary()
+{
+ cmMakefile* mf = this->LocalGenerators[0]->GetMakefile();
+
+ // Record all target directories in a central location.
+ std::string fname = mf->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)
+ {
+ this->WriteSummary(ti->second);
+ fout << ti->second->GetSupportDirectory() << "\n";
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalGenerator::WriteSummary(cmTarget* target)
+{
+ // Place the labels file in a per-target support directory.
+ std::string dir = target->GetSupportDirectory();
+ std::string file = dir;
+ file += "/Labels.txt";
+
+ // Check whether labels are enabled for this target.
+ if(const char* value = target->GetProperty("LABELS"))
+ {
+ cmSystemTools::MakeDirectory(dir.c_str());
+ cmGeneratedFileStream fout(file.c_str());
+
+ // List the target-wide labels. All sources in the target get
+ // these labels.
+ std::vector<std::string> labels;
+ cmSystemTools::ExpandListArgument(value, labels);
+ if(!labels.empty())
+ {
+ fout << "# Target labels\n";
+ for(std::vector<std::string>::const_iterator li = labels.begin();
+ li != labels.end(); ++li)
+ {
+ fout << " " << *li << "\n";
+ }
+ }
+
+ // List the source files with any per-source labels.
+ fout << "# Source files and their labels\n";
+ std::vector<cmSourceFile*> const& sources = target->GetSourceFiles();
+ for(std::vector<cmSourceFile*>::const_iterator si = sources.begin();
+ si != sources.end(); ++si)
+ {
+ cmSourceFile* sf = *si;
+ fout << sf->GetFullPath() << "\n";
+ if(const char* svalue = sf->GetProperty("LABELS"))
+ {
+ labels.clear();
+ cmSystemTools::ExpandListArgument(svalue, labels);
+ for(std::vector<std::string>::const_iterator li = labels.begin();
+ li != labels.end(); ++li)
+ {
+ fout << " " << *li << "\n";
+ }
+ }
+ }
+ }
+ else
+ {
+ cmSystemTools::RemoveFile(file.c_str());
+ }
+}
+
+//----------------------------------------------------------------------------
+// static
+std::string cmGlobalGenerator::EscapeJSON(const std::string& s) {
+ std::string result;
+ for (std::string::size_type i = 0; i < s.size(); ++i) {
+ if (s[i] == '"' || s[i] == '\\') {
+ result += '\\';
+ }
+ result += s[i];
+ }
+ return result;
+}
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
new file mode 100644
index 000000000..ce9179379
--- /dev/null
+++ b/Source/cmGlobalGenerator.h
@@ -0,0 +1,407 @@
+/*============================================================================
+ 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 cmGlobalGenerator_h
+#define cmGlobalGenerator_h
+
+#include "cmStandardIncludes.h"
+
+#include "cmTarget.h" // For cmTargets
+#include "cmTargetDepend.h" // For cmTargetDependSet
+#include "cmSystemTools.h" // for cmSystemTools::OutputOption
+class cmake;
+class cmGeneratorTarget;
+class cmMakefile;
+class cmLocalGenerator;
+class cmExternalMakefileProjectGenerator;
+class cmTarget;
+class cmTargetExport;
+class cmInstallTargetGenerator;
+class cmInstallFilesGenerator;
+
+/** \class cmGlobalGenerator
+ * \brief Responable for overseeing the generation process for the entire tree
+ *
+ * Subclasses of this class generate makefiles for various
+ * platforms.
+ */
+class cmGlobalGenerator
+{
+public:
+ ///! Free any memory allocated with the GlobalGenerator
+ cmGlobalGenerator();
+ virtual ~cmGlobalGenerator();
+
+ ///! Create a local generator appropriate to this Global Generator
+ virtual cmLocalGenerator *CreateLocalGenerator();
+
+ ///! Get the name for this generator
+ virtual const char *GetName() const { return "Generic"; };
+
+ /** Get the documentation entry for this generator. */
+ virtual void GetDocumentation(cmDocumentationEntry& entry) const;
+
+ /**
+ * Create LocalGenerators and process the CMakeLists files. This does not
+ * actually produce any makefiles, DSPs, etc.
+ */
+ virtual void Configure();
+
+ /**
+ * 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();
+
+ /**
+ * Set/Get and Clear the enabled languages.
+ */
+ void SetLanguageEnabled(const char*, cmMakefile* mf);
+ bool GetLanguageEnabled(const char*) const;
+ void ClearEnabledLanguages();
+ void GetEnabledLanguages(std::vector<std::string>& lang);
+ /**
+ * Try to determine system infomation such as shared library
+ * extension, pthreads, byte order etc.
+ */
+ virtual void EnableLanguage(std::vector<std::string>const& languages,
+ cmMakefile *, bool optional);
+
+ /**
+ * Resolve the CMAKE_<lang>_COMPILER setting for the given language.
+ * Intended to be called from EnableLanguage.
+ */
+ void ResolveLanguageCompiler(const std::string &lang, cmMakefile *mf,
+ bool optional);
+
+ /**
+ * Try to determine system infomation, get it from another generator
+ */
+ virtual 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);
+
+
+ /**
+ * Build a file given the following information. This is a more direct call
+ * that is used by both CTest and TryCompile. If target name is NULL or
+ * 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,
+ 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* additionalOptions,
+ const char *targetName,
+ const char* config, bool ignoreErrors, bool fast);
+
+
+ ///! Set the CMake instance
+ void SetCMakeInstance(cmake *cm);
+
+ ///! Get the CMake instance
+ cmake *GetCMakeInstance() { return this->CMakeInstance; };
+ const cmake *GetCMakeInstance() const { return this->CMakeInstance; };
+
+ void SetConfiguredFilesPath(cmGlobalGenerator* gen);
+ const std::vector<cmLocalGenerator *>& GetLocalGenerators() const {
+ return this->LocalGenerators;}
+
+ cmLocalGenerator* GetCurrentLocalGenerator()
+ {return this->CurrentLocalGenerator;}
+
+ void SetCurrentLocalGenerator(cmLocalGenerator* lg)
+ {this->CurrentLocalGenerator = lg;}
+
+ void AddLocalGenerator(cmLocalGenerator *lg);
+
+ ///! Set an generator for an "external makefile based project"
+ void SetExternalMakefileProjectGenerator(
+ cmExternalMakefileProjectGenerator *extraGenerator);
+
+ const char* GetExtraGeneratorName() const;
+
+ void AddInstallComponent(const char* component);
+
+ const std::set<cmStdString>* GetInstallComponents() const
+ { return &InstallComponents; }
+
+ ///! Add one installed target to the sets of the exports
+ void AddTargetToExports(const char* exportSet, cmTarget* target,
+ cmInstallTargetGenerator* archive,
+ cmInstallTargetGenerator* runTime,
+ cmInstallTargetGenerator* library,
+ cmInstallTargetGenerator* framework,
+ cmInstallTargetGenerator* bundle,
+ cmInstallFilesGenerator* publicHeaders);
+ ///! Get the export target set with the given name
+ const std::vector<cmTargetExport*>* GetExportSet(const char* name) const;
+
+ /** Add a file to the manifest of generated targets for a configuration. */
+ void AddToManifest(const char* config, std::string const& f);
+
+ void EnableInstallTarget();
+
+ int TryCompileTimeout;
+
+ bool GetForceUnixPaths() const { return this->ForceUnixPaths; }
+ bool GetToolSupportsColor() const { return this->ToolSupportsColor; }
+
+ ///! return the language for the given extension
+ const char* GetLanguageFromExtension(const char* ext);
+ ///! 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);
+ ///! What is the object file extension for a given source file?
+ const char* GetLanguageOutputExtension(cmSourceFile const&);
+
+ ///! What is the configurations directory variable called?
+ virtual const char* GetCMakeCFGIntDir() const { return "."; }
+
+ /** Get whether the generator should use a script for link commands. */
+ bool GetUseLinkScript() const { return this->UseLinkScript; }
+
+ /** Get whether the generator should produce special marks on rules
+ producing symbolic (non-file) outputs. */
+ bool GetNeedSymbolicMark() const { return this->NeedSymbolicMark; }
+
+ /*
+ * Determine what program to use for building the project.
+ */
+ void FindMakeProgram(cmMakefile*);
+
+ ///! Find a target by name by searching the local generators.
+ cmTarget* FindTarget(const char* project, const char* name);
+
+ /** Determine if a name resolves to a framework on disk or a built target
+ that is a framework. */
+ bool NameResolvesToFramework(const std::string& libname);
+
+ /** If check to see if the target is linked to by any other
+ target in the project */
+ bool IsDependedOn(const char* project, cmTarget* target);
+ ///! Find a local generator by its startdirectory
+ cmLocalGenerator* FindLocalGenerator(const char* start_dir);
+
+ /** 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,
+ 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
+ they do not yet exist. */
+ std::set<cmStdString> const& GetDirectoryContent(std::string const& dir,
+ bool needDisk = true);
+
+ void AddTarget(cmTarget* t);
+
+ virtual const char* GetAllTargetName() const { return "ALL_BUILD"; }
+ virtual const char* GetInstallTargetName() const { return "INSTALL"; }
+ virtual const char* GetInstallLocalTargetName() const { return 0; }
+ virtual const char* GetInstallStripTargetName() const { return 0; }
+ virtual const char* GetPreinstallTargetName() const { return 0; }
+ virtual const char* GetTestTargetName() const { return "RUN_TESTS"; }
+ virtual const char* GetPackageTargetName() const { return "PACKAGE"; }
+ virtual const char* GetPackageSourceTargetName() const { return 0; }
+ virtual const char* GetEditCacheTargetName() const { return 0; }
+ virtual const char* GetRebuildCacheTargetName() const { return 0; }
+ virtual const char* GetCleanTargetName() const { return 0; }
+
+ // 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);
+
+ /** Get per-target generator information. */
+ cmGeneratorTarget* GetGeneratorTarget(cmTarget*) const;
+
+ const std::map<cmStdString, std::vector<cmLocalGenerator*> >& GetProjectMap()
+ const {return this->ProjectMap;}
+
+ // track files replaced during a Generate
+ void FileReplacedDuringGenerate(const std::string& filename);
+ void GetFilesReplacedDuringGenerate(std::vector<std::string>& filenames);
+
+ void AddRuleHash(const std::vector<std::string>& outputs,
+ std::string const& content);
+
+ /** Return whether the given binary directory is unused. */
+ bool BinaryDirectoryIsNew(const char* 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);
+
+ /** 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);
+
+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,
+ 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);
+
+ virtual bool ComputeTargetDepends();
+
+ virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS();
+
+ bool CheckTargets();
+ void CreateAutomocTargets();
+
+
+ // 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 CreateDefaultGlobalTargets(cmTargets* targets);
+ cmTarget CreateGlobalTarget(const char* name, const char* message,
+ const cmCustomCommandLines* commandLines,
+ std::vector<std::string> depends, const char* workingDir);
+
+ bool NeedSymbolicMark;
+ bool UseLinkScript;
+ bool ForceUnixPaths;
+ bool ToolSupportsColor;
+ cmStdString FindMakeProgramFile;
+ cmStdString ConfiguredFilesPath;
+ cmake *CMakeInstance;
+ std::vector<cmLocalGenerator *> LocalGenerators;
+ cmLocalGenerator* CurrentLocalGenerator;
+ // 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;
+
+ // Set of named installation components requested by the project.
+ std::set<cmStdString> InstallComponents;
+ bool InstallTargetEnabled;
+ // Sets of named target exports
+ std::map<cmStdString, std::vector<cmTargetExport*> > ExportSets;
+ void ClearExportSets();
+
+ // Manifest of all targets that will be built for each configuration.
+ // This is computed just before local generators generate.
+ cmTargetManifest TargetManifest;
+
+ // All targets in the entire project.
+ std::map<cmStdString,cmTarget *> TotalTargets;
+ std::map<cmStdString,cmTarget *> ImportedTargets;
+
+ virtual const char* GetPredefinedTargetsFolder();
+ virtual bool UseFolderProperty();
+
+private:
+ 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;
+
+ // Record hashes for rules and outputs.
+ struct RuleHash { char Data[32]; };
+ std::map<cmStdString, 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);
+
+ cmExternalMakefileProjectGenerator* ExtraGenerator;
+
+ // track files replaced during a Generate
+ std::vector<std::string> FilesReplacedDuringGenerate;
+
+ // Store computed inter-target dependencies.
+ typedef std::map<cmTarget *, TargetDependSet> TargetDependMap;
+ TargetDependMap TargetDependencies;
+
+ // Per-target generator information.
+ typedef std::map<cmTarget*, cmGeneratorTarget*> GeneratorTargetsType;
+ GeneratorTargetsType GeneratorTargets;
+ void CreateGeneratorTargets();
+ void ClearGeneratorTargets();
+ virtual void ComputeTargetObjects(cmGeneratorTarget* gt) const;
+
+ // Cache directory content and target files to be built.
+ struct DirectoryContent: public std::set<cmStdString>
+ {
+ typedef std::set<cmStdString> derived;
+ bool LoadedFromDisk;
+ DirectoryContent(): LoadedFromDisk(false) {}
+ DirectoryContent(DirectoryContent const& dc):
+ derived(dc), LoadedFromDisk(dc.LoadedFromDisk) {}
+ };
+ std::map<cmStdString, DirectoryContent> DirectoryContentMap;
+
+ // Set of binary directories on disk.
+ std::set<cmStdString> BinaryDirectories;
+};
+
+#endif
diff --git a/Source/cmGlobalJOMMakefileGenerator.cxx b/Source/cmGlobalJOMMakefileGenerator.cxx
new file mode 100644
index 000000000..411e28bf1
--- /dev/null
+++ b/Source/cmGlobalJOMMakefileGenerator.cxx
@@ -0,0 +1,69 @@
+/*============================================================================
+ 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 "cmGlobalJOMMakefileGenerator.h"
+#include "cmLocalUnixMakefileGenerator3.h"
+#include "cmMakefile.h"
+
+cmGlobalJOMMakefileGenerator::cmGlobalJOMMakefileGenerator()
+{
+ this->FindMakeProgramFile = "CMakeJOMFindMake.cmake";
+ this->ForceUnixPaths = false;
+ this->ToolSupportsColor = true;
+ this->UseLinkScript = false;
+}
+
+void cmGlobalJOMMakefileGenerator
+::EnableLanguage(std::vector<std::string>const& l,
+ cmMakefile *mf,
+ bool optional)
+{
+ // 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) const
+{
+ entry.Name = this->GetName();
+ entry.Brief = "Generates JOM makefiles.";
+ entry.Full = "";
+}
diff --git a/Source/cmGlobalJOMMakefileGenerator.h b/Source/cmGlobalJOMMakefileGenerator.h
new file mode 100644
index 000000000..08be4b4fc
--- /dev/null
+++ b/Source/cmGlobalJOMMakefileGenerator.h
@@ -0,0 +1,49 @@
+/*============================================================================
+ 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 cmGlobalJOMMakefileGenerator_h
+#define cmGlobalJOMMakefileGenerator_h
+
+#include "cmGlobalUnixMakefileGenerator3.h"
+
+/** \class cmGlobalJOMMakefileGenerator
+ * \brief Write a JOM makefiles.
+ *
+ * cmGlobalJOMMakefileGenerator manages nmake build process for a tree
+ */
+class cmGlobalJOMMakefileGenerator : public cmGlobalUnixMakefileGenerator3
+{
+public:
+ cmGlobalJOMMakefileGenerator();
+ static cmGlobalGenerator* New() {
+ return new cmGlobalJOMMakefileGenerator; }
+ ///! Get the name for the generator.
+ virtual const char* 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";}
+
+ /** Get the documentation entry for this generator. */
+ virtual void GetDocumentation(cmDocumentationEntry& entry) const;
+
+ ///! Create a local generator appropriate to this Global Generator
+ virtual cmLocalGenerator *CreateLocalGenerator();
+
+ /**
+ * Try to determine system infomation such as shared library
+ * extension, pthreads, byte order etc.
+ */
+ virtual void EnableLanguage(std::vector<std::string>const& languages,
+ cmMakefile *, bool optional);
+};
+
+#endif
diff --git a/Source/cmGlobalKdevelopGenerator.cxx b/Source/cmGlobalKdevelopGenerator.cxx
new file mode 100644
index 000000000..f69944847
--- /dev/null
+++ b/Source/cmGlobalKdevelopGenerator.cxx
@@ -0,0 +1,619 @@
+/*============================================================================
+ 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 "cmGlobalKdevelopGenerator.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/Directory.hxx>
+
+//----------------------------------------------------------------------------
+void cmGlobalKdevelopGenerator
+::GetDocumentation(cmDocumentationEntry& entry, const char*) 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()
+:cmExternalMakefileProjectGenerator()
+{
+ this->SupportedGlobalGenerators.push_back("Unix Makefiles");
+#ifdef CMAKE_USE_NINJA
+ this->SupportedGlobalGenerators.push_back("Ninja");
+#endif
+}
+
+void cmGlobalKdevelopGenerator::Generate()
+{
+ // for each sub project in the project create
+ // a kdevelop project
+ for (std::map<cmStdString, 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 cmakeFilePattern("CMakeLists.txt;*.cmake;");
+ std::string fileToOpen;
+ const std::vector<cmLocalGenerator*>& lgs= it->second;
+ // create the project.kdevelop.filelist file
+ if(!this->CreateFilelistFile(lgs, outputDir, projectDir,
+ projectName, cmakeFilePattern, fileToOpen))
+ {
+ cmSystemTools::Error("Can not create filelist file");
+ return;
+ }
+ //try to find the name of an executable so we have something to
+ //run from kdevelop for now just pick the first executable found
+ std::string executable;
+ 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++)
+ {
+ if (ti->second.GetType()==cmTarget::EXECUTABLE)
+ {
+ executable = ti->second.GetProperty("LOCATION");
+ break;
+ }
+ }
+ if (!executable.empty())
+ {
+ break;
+ }
+ }
+
+ // now create a project file
+ this->CreateProjectFile(outputDir, projectDir, projectName,
+ executable, cmakeFilePattern, fileToOpen);
+ }
+}
+
+bool cmGlobalKdevelopGenerator
+::CreateFilelistFile(const std::vector<cmLocalGenerator*>& lgs,
+ const std::string& outputDir,
+ const std::string& projectDirIn,
+ const std::string& projectname,
+ std::string& cmakeFilePattern,
+ std::string& fileToOpen)
+{
+ std::string projectDir = projectDirIn + "/";
+ std::string filename = outputDir+ "/" + projectname +".kdevelop.filelist";
+
+ std::set<cmStdString> files;
+ std::string tmp;
+
+ 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;
+ cmSystemTools::ReplaceString(tmp, projectDir.c_str(), "");
+ // make sure the file is part of this source tree
+ if ((tmp[0]!='/') &&
+ (strstr(tmp.c_str(),
+ cmake::GetCMakeFilesDirectoryPostSlash())==0))
+ {
+ files.insert(tmp);
+ tmp=cmSystemTools::GetFilenameName(tmp);
+ //add all files which dont match the default
+ // */CMakeLists.txt;*cmake; to the file pattern
+ if ((tmp!="CMakeLists.txt")
+ && (strstr(tmp.c_str(), ".cmake")==0))
+ {
+ cmakeFilePattern+=tmp+";";
+ }
+ }
+ }
+
+ //get all sources
+ cmTargets& targets=makefile->GetTargets();
+ for (cmTargets::iterator ti = targets.begin();
+ ti != targets.end(); ti++)
+ {
+ const std::vector<cmSourceFile*>& sources=ti->second.GetSourceFiles();
+ for (std::vector<cmSourceFile*>::const_iterator si=sources.begin();
+ si!=sources.end(); si++)
+ {
+ tmp=(*si)->GetFullPath();
+ std::string headerBasename=cmSystemTools::GetFilenamePath(tmp);
+ headerBasename+="/";
+ headerBasename+=cmSystemTools::GetFilenameWithoutExtension(tmp);
+
+ cmSystemTools::ReplaceString(tmp, projectDir.c_str(), "");
+
+ if ((tmp[0]!='/') &&
+ (strstr(tmp.c_str(),
+ cmake::GetCMakeFilesDirectoryPostSlash())==0) &&
+ (cmSystemTools::GetFilenameExtension(tmp)!=".moc"))
+ {
+ files.insert(tmp);
+
+ // check if there's a matching header around
+ for(std::vector<std::string>::const_iterator
+ ext = makefile->GetHeaderExtensions().begin();
+ ext != makefile->GetHeaderExtensions().end(); ++ext)
+ {
+ std::string hname=headerBasename;
+ hname += ".";
+ hname += *ext;
+ if(cmSystemTools::FileExists(hname.c_str()))
+ {
+ cmSystemTools::ReplaceString(hname, projectDir.c_str(), "");
+ files.insert(hname);
+ break;
+ }
+ }
+ }
+ }
+ for (std::vector<std::string>::const_iterator lt=listFiles.begin();
+ lt!=listFiles.end(); lt++)
+ {
+ tmp=*lt;
+ cmSystemTools::ReplaceString(tmp, projectDir.c_str(), "");
+ if ((tmp[0]!='/') &&
+ (strstr(tmp.c_str(),
+ cmake::GetCMakeFilesDirectoryPostSlash())==0))
+ {
+ files.insert(tmp.c_str());
+ }
+ }
+ }
+ }
+
+ //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());
+ if (oldFilelist)
+ {
+ while (cmSystemTools::GetLineFromStream(oldFilelist, tmp))
+ {
+ if (tmp[0]=='/')
+ {
+ continue;
+ }
+ std::string completePath=projectDir+tmp;
+ if (cmSystemTools::FileExists(completePath.c_str()))
+ {
+ files.insert(tmp);
+ }
+ }
+ oldFilelist.close();
+ }
+
+ //now write the new filename
+ cmGeneratedFileStream fout(filename.c_str());
+ if(!fout)
+ {
+ return false;
+ }
+
+ fileToOpen="";
+ for (std::set<cmStdString>::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());
+ // just select the first source file
+ if (fileToOpen.empty())
+ {
+ std::string ext = cmSystemTools::GetFilenameExtension(tmp);
+ if ((ext==".c") || (ext==".cc") || (ext==".cpp") || (ext==".cxx")
+ || (ext==".C") || (ext==".h") || (ext==".hpp"))
+ {
+ fileToOpen=tmp;
+ }
+ }
+ // make it relative to the project dir
+ cmSystemTools::ReplaceString(tmp, projectDir.c_str(), "");
+ // only put relative paths
+ if (tmp.size() && tmp[0] != '/')
+ {
+ fout << tmp.c_str() <<"\n";
+ }
+ }
+ return true;
+}
+
+
+/* create the project file, if it already exists, merge it with the
+existing one, otherwise create a new one */
+void cmGlobalKdevelopGenerator
+::CreateProjectFile(const std::string& outputDir,
+ const std::string& projectDir,
+ const std::string& projectname,
+ const std::string& executable,
+ const std::string& cmakeFilePattern,
+ const std::string& fileToOpen)
+{
+ this->Blacklist.clear();
+
+ std::string filename=outputDir+"/";
+ filename+=projectname+".kdevelop";
+ std::string sessionFilename=outputDir+"/";
+ sessionFilename+=projectname+".kdevses";
+
+ if (cmSystemTools::FileExists(filename.c_str()))
+ {
+ this->MergeProjectFiles(outputDir, projectDir, filename,
+ executable, cmakeFilePattern,
+ fileToOpen, sessionFilename);
+ }
+ else
+ {
+ // add all subdirectories which are cmake build directories to the
+ // 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()))
+ {
+ size_t numf = d.GetNumberOfFiles();
+ for (unsigned int i = 0; i < numf; i++)
+ {
+ std::string nextFile = d.GetFile(i);
+ if ((nextFile!=".") && (nextFile!=".."))
+ {
+ std::string tmp = projectDir;
+ tmp += "/";
+ tmp += nextFile;
+ if (cmSystemTools::FileIsDirectory(tmp.c_str()))
+ {
+ tmp += "/CMakeCache.txt";
+ if ((nextFile == "CMakeFiles")
+ || (cmSystemTools::FileExists(tmp.c_str())))
+ {
+ this->Blacklist.push_back(nextFile);
+ }
+ }
+ }
+ }
+ }
+ this->CreateNewProjectFile(outputDir, projectDir, filename,
+ executable, cmakeFilePattern,
+ fileToOpen, sessionFilename);
+ }
+
+}
+
+void cmGlobalKdevelopGenerator
+::MergeProjectFiles(const std::string& outputDir,
+ const std::string& projectDir,
+ const std::string& filename,
+ const std::string& executable,
+ const std::string& cmakeFilePattern,
+ const std::string& fileToOpen,
+ const std::string& sessionFilename)
+{
+ std::ifstream oldProjectFile(filename.c_str());
+ if (!oldProjectFile)
+ {
+ this->CreateNewProjectFile(outputDir, projectDir, filename,
+ executable, cmakeFilePattern,
+ fileToOpen, sessionFilename);
+ return;
+ }
+
+ /* Read the existing project file (line by line), copy all lines
+ into the new project file, except the ones which can be reliably
+ set from contents of the CMakeLists.txt */
+ std::string tmp;
+ std::vector<std::string> lines;
+ while (cmSystemTools::GetLineFromStream(oldProjectFile, tmp))
+ {
+ lines.push_back(tmp);
+ }
+ oldProjectFile.close();
+
+ cmGeneratedFileStream fout(filename.c_str());
+ if(!fout)
+ {
+ return;
+ }
+
+ for (std::vector<std::string>::const_iterator it=lines.begin();
+ it!=lines.end(); it++)
+ {
+ const char* line=(*it).c_str();
+ // skip these tags as they are always replaced
+ if ((strstr(line, "<projectdirectory>")!=0)
+ || (strstr(line, "<projectmanagement>")!=0)
+ || (strstr(line, "<absoluteprojectpath>")!=0)
+ || (strstr(line, "<filelistdirectory>")!=0)
+ || (strstr(line, "<buildtool>")!=0)
+ || (strstr(line, "<builddir>")!=0))
+ {
+ continue;
+ }
+
+ // output the line from the file if it is not one of the above tags
+ fout<<*it<<"\n";
+ // if this is the <general> tag output the stuff that goes in the
+ // general tag
+ if (strstr(line, "<general>"))
+ {
+ fout<< " <projectmanagement>KDevCustomProject</projectmanagement>\n";
+ fout<< " <projectdirectory>" <<projectDir.c_str()
+ << "</projectdirectory>\n"; //this one is important
+ fout<<" <absoluteprojectpath>true</absoluteprojectpath>\n";
+ //and this one
+ }
+ // inside kdevcustomproject the <filelistdirectory> must be put
+ if (strstr(line, "<kdevcustomproject>"))
+ {
+ fout<<" <filelistdirectory>"<<outputDir.c_str()
+ <<"</filelistdirectory>\n";
+ }
+ // buildtool and builddir go inside <build>
+ if (strstr(line, "<build>"))
+ {
+ fout<<" <buildtool>make</buildtool>\n";
+ fout<<" <builddir>"<<outputDir.c_str()<<"</builddir>\n";
+ }
+ }
+}
+
+void cmGlobalKdevelopGenerator
+::CreateNewProjectFile(const std::string& outputDir,
+ const std::string& projectDir,
+ const std::string& filename,
+ const std::string& executable,
+ const std::string& cmakeFilePattern,
+ const std::string& fileToOpen,
+ const std::string& sessionFilename)
+{
+ cmGeneratedFileStream fout(filename.c_str());
+ if(!fout)
+ {
+ return;
+ }
+
+ // check for a version control system
+ bool hasSvn = cmSystemTools::FileExists((projectDir + "/.svn").c_str());
+ bool hasCvs = cmSystemTools::FileExists((projectDir + "/CVS").c_str());
+
+ bool enableCxx = (this->GlobalGenerator->GetLanguageEnabled("C")
+ || this->GlobalGenerator->GetLanguageEnabled("CXX"));
+ bool enableFortran = this->GlobalGenerator->GetLanguageEnabled("Fortran");
+ std::string primaryLanguage = "C++";
+ if (enableFortran && !enableCxx)
+ {
+ primaryLanguage="Fortran77";
+ }
+
+ fout<<"<?xml version = '1.0'?>\n"
+ "<kdevelop>\n"
+ " <general>\n"
+ " <author></author>\n"
+ " <email></email>\n"
+ " <version>$VERSION$</version>\n"
+ " <projectmanagement>KDevCustomProject</projectmanagement>\n"
+ " <primarylanguage>" << primaryLanguage << "</primarylanguage>\n"
+ " <ignoreparts/>\n"
+ " <projectdirectory>" << projectDir.c_str() <<
+ "</projectdirectory>\n"; //this one is important
+ fout<<" <absoluteprojectpath>true</absoluteprojectpath>\n"; //and this one
+
+ // setup additional languages
+ fout<<" <secondaryLanguages>\n";
+ if (enableFortran && enableCxx)
+ {
+ fout<<" <language>Fortran</language>\n";
+ }
+ if (enableCxx)
+ {
+ fout<<" <language>C</language>\n";
+ }
+ fout<<" </secondaryLanguages>\n";
+
+ if (hasSvn)
+ {
+ fout << " <versioncontrol>kdevsubversion</versioncontrol>\n";
+ }
+ else if (hasCvs)
+ {
+ fout << " <versioncontrol>kdevcvsservice</versioncontrol>\n";
+ }
+
+ fout<<" </general>\n"
+ " <kdevcustomproject>\n"
+ " <filelistdirectory>" << outputDir.c_str() <<
+ "</filelistdirectory>\n"
+ " <run>\n"
+ " <mainprogram>" << executable.c_str() << "</mainprogram>\n"
+ " <directoryradio>custom</directoryradio>\n"
+ " <customdirectory>"<<outputDir.c_str()<<"</customdirectory>\n"
+ " <programargs></programargs>\n"
+ " <terminal>false</terminal>\n"
+ " <autocompile>true</autocompile>\n"
+ " <envvars/>\n"
+ " </run>\n"
+ " <build>\n"
+ " <buildtool>make</buildtool>\n"; //this one is important
+ fout<<" <builddir>"<<outputDir.c_str()<<"</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")
+ << " </makebin>\n"
+ " <selectedenvironment>default</selectedenvironment>\n"
+ " <environments>\n"
+ " <default>\n"
+ " <envvar value=\"1\" name=\"VERBOSE\" />\n"
+ " <envvar value=\"1\" name=\"CMAKE_NO_VERBOSE\" />\n"
+ " </default>\n"
+ " </environments>\n"
+ " </make>\n";
+
+ fout<<" <blacklist>\n";
+ for(std::vector<std::string>::const_iterator dirIt=this->Blacklist.begin();
+ dirIt != this->Blacklist.end();
+ ++dirIt)
+ {
+ fout<<" <path>" << dirIt->c_str() << "</path>\n";
+ }
+ fout<<" </blacklist>\n";
+
+ fout<<" </kdevcustomproject>\n"
+ " <kdevfilecreate>\n"
+ " <filetypes/>\n"
+ " <useglobaltypes>\n"
+ " <type ext=\"ui\" />\n"
+ " <type ext=\"cpp\" />\n"
+ " <type ext=\"h\" />\n"
+ " </useglobaltypes>\n"
+ " </kdevfilecreate>\n"
+ " <kdevdoctreeview>\n"
+ " <projectdoc>\n"
+ " <userdocDir>html/</userdocDir>\n"
+ " <apidocDir>html/</apidocDir>\n"
+ " </projectdoc>\n"
+ " <ignoreqt_xml/>\n"
+ " <ignoredoxygen/>\n"
+ " <ignorekdocs/>\n"
+ " <ignoretocs/>\n"
+ " <ignoredevhelp/>\n"
+ " </kdevdoctreeview>\n";
+
+ if (enableCxx)
+ {
+ fout<<" <cppsupportpart>\n"
+ " <filetemplates>\n"
+ " <interfacesuffix>.h</interfacesuffix>\n"
+ " <implementationsuffix>.cpp</implementationsuffix>\n"
+ " </filetemplates>\n"
+ " </cppsupportpart>\n"
+ " <kdevcppsupport>\n"
+ " <codecompletion>\n"
+ " <includeGlobalFunctions>true</includeGlobalFunctions>\n"
+ " <includeTypes>true</includeTypes>\n"
+ " <includeEnums>true</includeEnums>\n"
+ " <includeTypedefs>false</includeTypedefs>\n"
+ " <automaticCodeCompletion>true</automaticCodeCompletion>\n"
+ " <automaticArgumentsHint>true</automaticArgumentsHint>\n"
+ " <automaticHeaderCompletion>true</automaticHeaderCompletion>\n"
+ " <codeCompletionDelay>250</codeCompletionDelay>\n"
+ " <argumentsHintDelay>400</argumentsHintDelay>\n"
+ " <headerCompletionDelay>250</headerCompletionDelay>\n"
+ " </codecompletion>\n"
+ " <references/>\n"
+ " </kdevcppsupport>\n";
+ }
+
+ if (enableFortran)
+ {
+ fout<<" <kdevfortransupport>\n"
+ " <ftnchek>\n"
+ " <division>false</division>\n"
+ " <extern>false</extern>\n"
+ " <declare>false</declare>\n"
+ " <pure>false</pure>\n"
+ " <argumentsall>false</argumentsall>\n"
+ " <commonall>false</commonall>\n"
+ " <truncationall>false</truncationall>\n"
+ " <usageall>false</usageall>\n"
+ " <f77all>false</f77all>\n"
+ " <portabilityall>false</portabilityall>\n"
+ " <argumentsonly/>\n"
+ " <commononly/>\n"
+ " <truncationonly/>\n"
+ " <usageonly/>\n"
+ " <f77only/>\n"
+ " <portabilityonly/>\n"
+ " </ftnchek>\n"
+ " </kdevfortransupport>\n";
+ }
+
+ // set up file groups. maybe this can be used with the CMake SOURCE_GROUP()
+ // command
+ fout<<" <kdevfileview>\n"
+ " <groups>\n"
+ " <group pattern=\"" << cmakeFilePattern.c_str() <<
+ "\" name=\"CMake\" />\n";
+
+ if (enableCxx)
+ {
+ fout<<" <group pattern=\"*.h;*.hxx;*.hpp\" name=\"Header\" />\n"
+ " <group pattern=\"*.c\" name=\"C Sources\" />\n"
+ " <group pattern=\"*.cpp;*.C;*.cxx;*.cc\" name=\"C++ Sources\""
+ "/>\n";
+ }
+
+ if (enableFortran)
+ {
+ fout<<" <group pattern=\"*.f;*.F;*.f77;*.F77;*.f90;*.F90;*.for;*.f95;"
+ "*.F95\" name=\"Fortran Sources\" />\n";
+ }
+
+ fout<<" <group pattern=\"*.ui\" name=\"Qt Designer files\" />\n"
+ " <hidenonprojectfiles>true</hidenonprojectfiles>\n"
+ " </groups>\n"
+ " <tree>\n"
+ " <hidepatterns>*.o,*.lo,CVS,*~,cmake*</hidepatterns>\n"
+ " <hidenonprojectfiles>true</hidenonprojectfiles>\n"
+ " </tree>\n"
+ " </kdevfileview>\n"
+ "</kdevelop>\n";
+
+ if (sessionFilename.empty())
+ {
+ return;
+ }
+
+ // and a session file, so that kdevelop opens a file if it opens the
+ // project the first time
+ cmGeneratedFileStream devses(sessionFilename.c_str());
+ if(!devses)
+ {
+ return;
+ }
+ devses<<"<?xml version = '1.0' encoding = \'UTF-8\'?>\n"
+ "<!DOCTYPE KDevPrjSession>\n"
+ "<KDevPrjSession>\n"
+ " <DocsAndViews NumberOfDocuments=\"1\" >\n"
+ " <Doc0 NumberOfViews=\"1\" URL=\"file://" << fileToOpen.c_str() <<
+ "\" >\n"
+ " <View0 line=\"0\" Type=\"Source\" />\n"
+ " </Doc0>\n"
+ " </DocsAndViews>\n"
+ "</KDevPrjSession>\n";
+}
+
diff --git a/Source/cmGlobalKdevelopGenerator.h b/Source/cmGlobalKdevelopGenerator.h
new file mode 100644
index 000000000..a1ad39d44
--- /dev/null
+++ b/Source/cmGlobalKdevelopGenerator.h
@@ -0,0 +1,92 @@
+/*============================================================================
+ 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.
+============================================================================*/
+#ifndef cmGlobalKdevelopGenerator_h
+#define cmGlobalKdevelopGenerator_h
+
+#include "cmExternalMakefileProjectGenerator.h"
+
+class cmLocalGenerator;
+
+/** \class cmGlobalKdevelopGenerator
+ * \brief Write Unix Makefiles accompanied by KDevelop3 project files.
+ *
+ * cmGlobalKdevelopGenerator produces a project file for KDevelop 3 (KDevelop
+ * > 3.1.1). The project is based on the "Custom Makefile based C/C++"
+ * project of KDevelop. Such a project consists of Unix Makefiles in the
+ * build directory together with a \<your_project\>.kdevelop project file,
+ * which contains the project settings and a \<your_project\>.kdevelop.filelist
+ * file, which lists the source files relative to the kdevelop project
+ * directory. The kdevelop project directory is the base source directory.
+ */
+class cmGlobalKdevelopGenerator : public cmExternalMakefileProjectGenerator
+{
+public:
+ cmGlobalKdevelopGenerator();
+
+ virtual const char* GetName() const
+ { return cmGlobalKdevelopGenerator::GetActualName();}
+ static const char* 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;
+
+ virtual void Generate();
+private:
+ /*** Create the foo.kdevelop.filelist file, return false if it doesn't
+ succeed. If the file already exists the contents will be merged.
+ */
+ bool CreateFilelistFile(const std::vector<cmLocalGenerator*>& lgs,
+ const std::string& outputDir,
+ const std::string& projectDirIn,
+ const std::string& projectname,
+ std::string& cmakeFilePattern,
+ std::string& fileToOpen);
+
+ /** Create the foo.kdevelop file. This one calls MergeProjectFiles()
+ if it already exists, otherwise createNewProjectFile() The project
+ files will be created in \a outputDir (in the build tree), the
+ kdevelop project dir will be set to \a projectDir (in the source
+ tree). \a cmakeFilePattern consists of a lists of all cmake
+ listfiles used by this CMakeLists.txt */
+ void CreateProjectFile(const std::string& outputDir,
+ const std::string& projectDir,
+ const std::string& projectname,
+ const std::string& executable,
+ const std::string& cmakeFilePattern,
+ const std::string& fileToOpen);
+
+ /*** Reads the old foo.kdevelop line by line and only replaces the
+ "important" lines
+ */
+ void MergeProjectFiles(const std::string& outputDir,
+ const std::string& projectDir,
+ const std::string& filename,
+ const std::string& executable,
+ const std::string& cmakeFilePattern,
+ const std::string& fileToOpen,
+ const std::string& sessionFilename);
+ ///! Creates a new foo.kdevelop and a new foo.kdevses file
+ void CreateNewProjectFile(const std::string& outputDir,
+ const std::string& projectDir,
+ const std::string& filename,
+ const std::string& executable,
+ const std::string& cmakeFilePattern,
+ const std::string& fileToOpen,
+ const std::string& sessionFilename);
+
+ std::vector<std::string> Blacklist;
+};
+
+#endif
diff --git a/Source/cmGlobalMSYSMakefileGenerator.cxx b/Source/cmGlobalMSYSMakefileGenerator.cxx
new file mode 100644
index 000000000..820e7e605
--- /dev/null
+++ b/Source/cmGlobalMSYSMakefileGenerator.cxx
@@ -0,0 +1,115 @@
+/*============================================================================
+ 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 "cmGlobalMSYSMakefileGenerator.h"
+#include "cmLocalUnixMakefileGenerator3.h"
+#include "cmMakefile.h"
+#include "cmake.h"
+
+cmGlobalMSYSMakefileGenerator::cmGlobalMSYSMakefileGenerator()
+{
+ this->FindMakeProgramFile = "CMakeMSYSFindMake.cmake";
+ this->ForceUnixPaths = true;
+ this->ToolSupportsColor = true;
+ this->UseLinkScript = false;
+}
+
+std::string
+cmGlobalMSYSMakefileGenerator::FindMinGW(std::string const& makeloc)
+{
+ std::string fstab = makeloc;
+ fstab += "/../etc/fstab";
+ std::ifstream fin(fstab.c_str());
+ std::string path;
+ std::string mount;
+ std::string mingwBin;
+ while(fin)
+ {
+ fin >> path;
+ fin >> mount;
+ if(mount == "/mingw")
+ {
+ mingwBin = path;
+ mingwBin += "/bin";
+ }
+ }
+ return mingwBin;
+}
+
+void cmGlobalMSYSMakefileGenerator
+::EnableLanguage(std::vector<std::string>const& l,
+ cmMakefile *mf,
+ bool optional)
+{
+ this->FindMakeProgram(mf);
+ std::string makeProgram = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM");
+ std::vector<std::string> locations;
+ std::string makeloc = cmSystemTools::GetProgramPath(makeProgram.c_str());
+ locations.push_back(this->FindMinGW(makeloc));
+ locations.push_back(makeloc);
+ 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("MSYS", "1");
+ 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);
+
+ if(!mf->IsSet("CMAKE_AR") &&
+ !this->CMakeInstance->GetIsInTryCompile() &&
+ !(1==l.size() && l[0]=="NONE"))
+ {
+ cmSystemTools::Error
+ ("CMAKE_AR was not found, please set to archive program. ",
+ mf->GetDefinition("CMAKE_AR"));
+ }
+}
+
+///! 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) const
+{
+ entry.Name = this->GetName();
+ 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
new file mode 100644
index 000000000..b5294acd5
--- /dev/null
+++ b/Source/cmGlobalMSYSMakefileGenerator.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 cmGlobalMSYSMakefileGenerator_h
+#define cmGlobalMSYSMakefileGenerator_h
+
+#include "cmGlobalUnixMakefileGenerator3.h"
+
+/** \class cmGlobalMSYSMakefileGenerator
+ * \brief Write a NMake makefiles.
+ *
+ * cmGlobalMSYSMakefileGenerator manages nmake build process for a tree
+ */
+class cmGlobalMSYSMakefileGenerator : public cmGlobalUnixMakefileGenerator3
+{
+public:
+ cmGlobalMSYSMakefileGenerator();
+ static cmGlobalGenerator* New() {
+ return new cmGlobalMSYSMakefileGenerator; }
+
+ ///! Get the name for the generator.
+ virtual const char* GetName() const {
+ return cmGlobalMSYSMakefileGenerator::GetActualName();}
+ static const char* GetActualName() {return "MSYS Makefiles";}
+
+ /** Get the documentation entry for this generator. */
+ virtual void GetDocumentation(cmDocumentationEntry& entry) const;
+
+ ///! Create a local generator appropriate to this Global Generator
+ virtual cmLocalGenerator *CreateLocalGenerator();
+
+ /**
+ * Try to determine system infomation such as shared library
+ * extension, pthreads, byte order etc.
+ */
+ virtual void EnableLanguage(std::vector<std::string>const& languages,
+ cmMakefile *, bool optional);
+
+private:
+ std::string FindMinGW(std::string const& makeloc);
+};
+
+#endif
diff --git a/Source/cmGlobalMinGWMakefileGenerator.cxx b/Source/cmGlobalMinGWMakefileGenerator.cxx
new file mode 100644
index 000000000..a9e779847
--- /dev/null
+++ b/Source/cmGlobalMinGWMakefileGenerator.cxx
@@ -0,0 +1,80 @@
+/*============================================================================
+ 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 "cmGlobalMinGWMakefileGenerator.h"
+#include "cmLocalUnixMakefileGenerator3.h"
+#include "cmMakefile.h"
+
+cmGlobalMinGWMakefileGenerator::cmGlobalMinGWMakefileGenerator()
+{
+ this->FindMakeProgramFile = "CMakeMinGWFindMake.cmake";
+ this->ForceUnixPaths = true;
+ this->ToolSupportsColor = true;
+ this->UseLinkScript = true;
+}
+
+void cmGlobalMinGWMakefileGenerator
+::EnableLanguage(std::vector<std::string>const& l,
+ cmMakefile *mf,
+ bool optional)
+{
+ 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());
+ 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) const
+{
+ entry.Name = this->GetName();
+ 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
new file mode 100644
index 000000000..366146b0a
--- /dev/null
+++ b/Source/cmGlobalMinGWMakefileGenerator.h
@@ -0,0 +1,47 @@
+/*============================================================================
+ 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 cmGlobalMinGWMakefileGenerator_h
+#define cmGlobalMinGWMakefileGenerator_h
+
+#include "cmGlobalUnixMakefileGenerator3.h"
+
+/** \class cmGlobalMinGWMakefileGenerator
+ * \brief Write a NMake makefiles.
+ *
+ * cmGlobalMinGWMakefileGenerator manages nmake build process for a tree
+ */
+class cmGlobalMinGWMakefileGenerator : public cmGlobalUnixMakefileGenerator3
+{
+public:
+ cmGlobalMinGWMakefileGenerator();
+ static cmGlobalGenerator* New() {
+ return new cmGlobalMinGWMakefileGenerator; }
+ ///! Get the name for the generator.
+ virtual const char* GetName() const {
+ return cmGlobalMinGWMakefileGenerator::GetActualName();}
+ static const char* GetActualName() {return "MinGW Makefiles";}
+
+ /** Get the documentation entry for this generator. */
+ virtual void GetDocumentation(cmDocumentationEntry& entry) const;
+
+ ///! Create a local generator appropriate to this Global Generator
+ virtual cmLocalGenerator *CreateLocalGenerator();
+
+ /**
+ * Try to determine system infomation such as shared library
+ * extension, pthreads, byte order etc.
+ */
+ virtual void EnableLanguage(std::vector<std::string>const& languages,
+ cmMakefile *, bool optional);
+};
+
+#endif
diff --git a/Source/cmGlobalNMakeMakefileGenerator.cxx b/Source/cmGlobalNMakeMakefileGenerator.cxx
new file mode 100644
index 000000000..c3c15e70f
--- /dev/null
+++ b/Source/cmGlobalNMakeMakefileGenerator.cxx
@@ -0,0 +1,69 @@
+/*============================================================================
+ 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 "cmGlobalNMakeMakefileGenerator.h"
+#include "cmLocalUnixMakefileGenerator3.h"
+#include "cmMakefile.h"
+
+cmGlobalNMakeMakefileGenerator::cmGlobalNMakeMakefileGenerator()
+{
+ this->FindMakeProgramFile = "CMakeNMakeFindMake.cmake";
+ this->ForceUnixPaths = false;
+ this->ToolSupportsColor = true;
+ this->UseLinkScript = false;
+}
+
+void cmGlobalNMakeMakefileGenerator
+::EnableLanguage(std::vector<std::string>const& l,
+ cmMakefile *mf,
+ bool optional)
+{
+ // 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) const
+{
+ entry.Name = this->GetName();
+ entry.Brief = "Generates NMake makefiles.";
+ entry.Full = "";
+}
diff --git a/Source/cmGlobalNMakeMakefileGenerator.h b/Source/cmGlobalNMakeMakefileGenerator.h
new file mode 100644
index 000000000..70a8c1909
--- /dev/null
+++ b/Source/cmGlobalNMakeMakefileGenerator.h
@@ -0,0 +1,47 @@
+/*============================================================================
+ 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 cmGlobalNMakeMakefileGenerator_h
+#define cmGlobalNMakeMakefileGenerator_h
+
+#include "cmGlobalUnixMakefileGenerator3.h"
+
+/** \class cmGlobalNMakeMakefileGenerator
+ * \brief Write a NMake makefiles.
+ *
+ * cmGlobalNMakeMakefileGenerator manages nmake build process for a tree
+ */
+class cmGlobalNMakeMakefileGenerator : public cmGlobalUnixMakefileGenerator3
+{
+public:
+ cmGlobalNMakeMakefileGenerator();
+ static cmGlobalGenerator* New() {
+ return new cmGlobalNMakeMakefileGenerator; }
+ ///! Get the name for the generator.
+ virtual const char* GetName() const {
+ return cmGlobalNMakeMakefileGenerator::GetActualName();}
+ static const char* GetActualName() {return "NMake Makefiles";}
+
+ /** Get the documentation entry for this generator. */
+ virtual void GetDocumentation(cmDocumentationEntry& entry) const;
+
+ ///! Create a local generator appropriate to this Global Generator
+ virtual cmLocalGenerator *CreateLocalGenerator();
+
+ /**
+ * Try to determine system infomation such as shared library
+ * extension, pthreads, byte order etc.
+ */
+ virtual void EnableLanguage(std::vector<std::string>const& languages,
+ cmMakefile *, bool optional);
+};
+
+#endif
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
new file mode 100644
index 000000000..3f3cfbbb1
--- /dev/null
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -0,0 +1,1076 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2011 Peter Collingbourne <peter@pcc.me.uk>
+ Copyright 2011 Nicolas Despres <nicolas.despres@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 "cmGlobalNinjaGenerator.h"
+#include "cmLocalNinjaGenerator.h"
+#include "cmMakefile.h"
+#include "cmGeneratedFileStream.h"
+#include "cmGeneratorTarget.h"
+#include "cmVersion.h"
+
+const char* cmGlobalNinjaGenerator::NINJA_BUILD_FILE = "build.ninja";
+const char* cmGlobalNinjaGenerator::NINJA_RULES_FILE = "rules.ninja";
+const char* cmGlobalNinjaGenerator::INDENT = " ";
+
+void cmGlobalNinjaGenerator::Indent(std::ostream& os, int count)
+{
+ for(int i = 0; i < count; ++i)
+ os << cmGlobalNinjaGenerator::INDENT;
+}
+
+void cmGlobalNinjaGenerator::WriteDivider(std::ostream& os)
+{
+ os
+ << "# ======================================"
+ << "=======================================\n";
+}
+
+void cmGlobalNinjaGenerator::WriteComment(std::ostream& os,
+ const std::string& comment)
+{
+ if (comment.empty())
+ return;
+
+ std::string replace = comment;
+ std::string::size_type lpos = 0;
+ std::string::size_type rpos;
+ os << "\n#############################################\n";
+ while((rpos = replace.find('\n', lpos)) != std::string::npos)
+ {
+ os << "# " << replace.substr(lpos, rpos - lpos) << "\n";
+ lpos = rpos + 1;
+ }
+ os << "# " << replace.substr(lpos) << "\n\n";
+}
+
+static bool IsIdentChar(char c)
+{
+ return
+ ('a' <= c && c <= 'z') ||
+ ('+' <= c && c <= '9') || // +,-./ and numbers
+ ('A' <= c && c <= 'Z') ||
+ (c == '_') || (c == '$') || (c == '\\') ||
+ (c == ' ') || (c == ':');
+}
+
+std::string cmGlobalNinjaGenerator::EncodeIdent(const std::string &ident,
+ std::ostream &vars) {
+ if (std::find_if(ident.begin(), ident.end(),
+ std::not1(std::ptr_fun(IsIdentChar))) != ident.end()) {
+ static unsigned VarNum = 0;
+ cmOStringStream names;
+ names << "ident" << VarNum++;
+ vars << names.str() << " = " << ident << "\n";
+ return "$" + names.str();
+ } else {
+ std::string result = ident;
+ cmSystemTools::ReplaceString(result, " ", "$ ");
+ cmSystemTools::ReplaceString(result, ":", "$:");
+ return result;
+ }
+}
+
+std::string cmGlobalNinjaGenerator::EncodeLiteral(const std::string &lit)
+{
+ std::string result = lit;
+ cmSystemTools::ReplaceString(result, "$", "$$");
+ return result;
+}
+
+std::string cmGlobalNinjaGenerator::EncodePath(const std::string &path)
+{
+ std::string result = path;
+#ifdef _WIN32
+ if(UsingMinGW)
+ cmSystemTools::ReplaceString(result, "\\", "/");
+ else
+ cmSystemTools::ReplaceString(result, "/", "\\");
+#endif
+ return EncodeLiteral(result);
+}
+
+void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os,
+ const std::string& comment,
+ const std::string& rule,
+ const cmNinjaDeps& outputs,
+ const cmNinjaDeps& explicitDeps,
+ const cmNinjaDeps& implicitDeps,
+ const cmNinjaDeps& orderOnlyDeps,
+ const cmNinjaVars& variables,
+ int cmdLineLimit)
+{
+ // Make sure there is a rule.
+ if(rule.empty())
+ {
+ cmSystemTools::Error("No rule for WriteBuildStatement! called "
+ "with comment: ",
+ comment.c_str());
+ return;
+ }
+
+ // Make sure there is at least one output file.
+ if(outputs.empty())
+ {
+ cmSystemTools::Error("No output files for WriteBuildStatement! called "
+ "with comment: ",
+ comment.c_str());
+ return;
+ }
+
+ cmGlobalNinjaGenerator::WriteComment(os, comment);
+
+ cmOStringStream arguments;
+
+ // TODO: Better formatting for when there are multiple input/output files.
+
+ // Write explicit dependencies.
+ for(cmNinjaDeps::const_iterator i = explicitDeps.begin();
+ i != explicitDeps.end();
+ ++i)
+ arguments << " " << EncodeIdent(EncodePath(*i), os);
+
+ // Write implicit dependencies.
+ if(!implicitDeps.empty())
+ {
+ arguments << " |";
+ for(cmNinjaDeps::const_iterator i = implicitDeps.begin();
+ i != implicitDeps.end();
+ ++i)
+ arguments << " " << EncodeIdent(EncodePath(*i), os);
+ }
+
+ // Write order-only dependencies.
+ if(!orderOnlyDeps.empty())
+ {
+ arguments << " ||";
+ for(cmNinjaDeps::const_iterator i = orderOnlyDeps.begin();
+ i != orderOnlyDeps.end();
+ ++i)
+ arguments << " " << EncodeIdent(EncodePath(*i), os);
+ }
+
+ arguments << "\n";
+
+ cmOStringStream build;
+
+ // Write outputs files.
+ build << "build";
+ for(cmNinjaDeps::const_iterator i = outputs.begin();
+ i != outputs.end(); ++i)
+ build << " " << EncodeIdent(EncodePath(*i), os);
+ build << ":";
+
+ // Write the rule.
+ build << " " << rule;
+
+ // Write the variables bound to this build statement.
+ cmOStringStream 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();
+ const std::string assignments = variable_assignments.str();
+ const std::string args = arguments.str();
+ if (cmdLineLimit > 0
+ && args.size() + buildstr.size() + assignments.size()
+ > (size_t) cmdLineLimit)
+ buildstr += "_RSPFILE";
+
+ os << buildstr << args << assignments;
+}
+
+void cmGlobalNinjaGenerator::WritePhonyBuild(std::ostream& os,
+ const std::string& comment,
+ const cmNinjaDeps& outputs,
+ const cmNinjaDeps& explicitDeps,
+ const cmNinjaDeps& implicitDeps,
+ const cmNinjaDeps& orderOnlyDeps,
+ const cmNinjaVars& variables)
+{
+ cmGlobalNinjaGenerator::WriteBuild(os,
+ comment,
+ "phony",
+ outputs,
+ explicitDeps,
+ implicitDeps,
+ orderOnlyDeps,
+ variables);
+}
+
+void cmGlobalNinjaGenerator::AddCustomCommandRule()
+{
+ this->AddRule("CUSTOM_COMMAND",
+ "$COMMAND",
+ "$DESC",
+ "Rule for running custom commands.",
+ /*depfile*/ "",
+ /*rspfile*/ "",
+ /*rspcontent*/ "",
+ /*restat*/ true);
+}
+
+void
+cmGlobalNinjaGenerator::WriteCustomCommandBuild(const std::string& command,
+ const std::string& description,
+ const std::string& comment,
+ const cmNinjaDeps& outputs,
+ const cmNinjaDeps& deps,
+ const cmNinjaDeps& orderOnlyDeps)
+{
+ std::string cmd = command;
+#ifdef _WIN32
+ if (cmd.empty())
+ // TODO Shouldn't an empty command be handled by ninja?
+ cmd = "cmd.exe /c";
+#endif
+
+ this->AddCustomCommandRule();
+
+ cmNinjaVars vars;
+ vars["COMMAND"] = cmd;
+ vars["DESC"] = EncodeLiteral(description);
+
+ cmGlobalNinjaGenerator::WriteBuild(*this->BuildFileStream,
+ comment,
+ "CUSTOM_COMMAND",
+ outputs,
+ deps,
+ cmNinjaDeps(),
+ orderOnlyDeps,
+ vars);
+}
+
+void
+cmGlobalNinjaGenerator::AddMacOSXContentRule()
+{
+ cmLocalGenerator *lg = this->LocalGenerators[0];
+ cmMakefile* mfRoot = lg->GetMakefile();
+
+ cmOStringStream cmd;
+ cmd << lg->ConvertToOutputFormat(
+ mfRoot->GetRequiredDefinition("CMAKE_COMMAND"),
+ 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."
+ /*depfile*/ "",
+ /*rspfile*/ "");
+}
+
+void
+cmGlobalNinjaGenerator::WriteMacOSXContentBuild(const std::string& input,
+ const std::string& output)
+{
+ this->AddMacOSXContentRule();
+
+ cmNinjaDeps outputs;
+ outputs.push_back(output);
+ cmNinjaDeps deps;
+ deps.push_back(input);
+ cmNinjaVars vars;
+
+ cmGlobalNinjaGenerator::WriteBuild(*this->BuildFileStream,
+ "",
+ "COPY_OSX_CONTENT",
+ outputs,
+ deps,
+ cmNinjaDeps(),
+ cmNinjaDeps(),
+ cmNinjaVars());
+}
+
+void cmGlobalNinjaGenerator::WriteRule(std::ostream& os,
+ const std::string& name,
+ 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,
+ bool generator)
+{
+ // Make sure the rule has a name.
+ if(name.empty())
+ {
+ cmSystemTools::Error("No name given for WriteRuleStatement! called "
+ "with comment: ",
+ comment.c_str());
+ return;
+ }
+
+ // Make sure a command is given.
+ if(command.empty())
+ {
+ cmSystemTools::Error("No command given for WriteRuleStatement! called "
+ "with comment: ",
+ comment.c_str());
+ return;
+ }
+
+ cmGlobalNinjaGenerator::WriteComment(os, comment);
+
+ // Write the rule.
+ os << "rule " << name << "\n";
+
+ // Write the depfile if any.
+ if(!depfile.empty())
+ {
+ cmGlobalNinjaGenerator::Indent(os, 1);
+ os << "depfile = " << depfile << "\n";
+ }
+
+ // Write the command.
+ cmGlobalNinjaGenerator::Indent(os, 1);
+ os << "command = " << command << "\n";
+
+ // Write the description if any.
+ if(!description.empty())
+ {
+ cmGlobalNinjaGenerator::Indent(os, 1);
+ os << "description = " << description << "\n";
+ }
+
+ if(!rspfile.empty())
+ {
+ if (rspcontent.empty())
+ {
+ cmSystemTools::Error("No rspfile_content given!", comment.c_str());
+ return;
+ }
+ cmGlobalNinjaGenerator::Indent(os, 1);
+ os << "rspfile = " << rspfile << "\n";
+ cmGlobalNinjaGenerator::Indent(os, 1);
+ os << "rspfile_content = " << rspcontent << "\n";
+ }
+
+ if(restat)
+ {
+ cmGlobalNinjaGenerator::Indent(os, 1);
+ os << "restat = 1\n";
+ }
+
+ if(generator)
+ {
+ cmGlobalNinjaGenerator::Indent(os, 1);
+ os << "generator = 1\n";
+ }
+
+ os << "\n";
+}
+
+void cmGlobalNinjaGenerator::WriteVariable(std::ostream& os,
+ const std::string& name,
+ const std::string& value,
+ const std::string& comment,
+ int indent)
+{
+ // Make sure we have a name.
+ if(name.empty())
+ {
+ cmSystemTools::Error("No name given for WriteVariable! called "
+ "with comment: ",
+ comment.c_str());
+ return;
+ }
+
+ // Do not add a variable if the value is empty.
+ std::string val = cmSystemTools::TrimWhitespace(value);
+ if(val.empty())
+ {
+ return;
+ }
+
+ cmGlobalNinjaGenerator::WriteComment(os, comment);
+ cmGlobalNinjaGenerator::Indent(os, indent);
+ os << name << " = " << val << "\n";
+}
+
+void cmGlobalNinjaGenerator::WriteInclude(std::ostream& os,
+ const std::string& filename,
+ const std::string& comment)
+{
+ cmGlobalNinjaGenerator::WriteComment(os, comment);
+ os << "include " << filename << "\n";
+}
+
+void cmGlobalNinjaGenerator::WriteDefault(std::ostream& os,
+ const cmNinjaDeps& targets,
+ const std::string& comment)
+{
+ cmGlobalNinjaGenerator::WriteComment(os, comment);
+ os << "default";
+ for(cmNinjaDeps::const_iterator i = targets.begin(); i != targets.end(); ++i)
+ os << " " << *i;
+ os << "\n";
+}
+
+
+cmGlobalNinjaGenerator::cmGlobalNinjaGenerator()
+ : cmGlobalGenerator()
+ , BuildFileStream(0)
+ , RulesFileStream(0)
+ , CompileCommandsStream(0)
+ , Rules()
+ , AllDependencies()
+{
+ // // Ninja is not ported to non-Unix OS yet.
+ // this->ForceUnixPaths = true;
+ this->FindMakeProgramFile = "CMakeNinjaFindMake.cmake";
+}
+
+
+//----------------------------------------------------------------------------
+// Virtual public methods.
+
+cmLocalGenerator* cmGlobalNinjaGenerator::CreateLocalGenerator()
+{
+ cmLocalGenerator* lg = new cmLocalNinjaGenerator;
+ lg->SetGlobalGenerator(this);
+ return lg;
+}
+
+void cmGlobalNinjaGenerator
+::GetDocumentation(cmDocumentationEntry& entry) const
+{
+ entry.Name = this->GetName();
+ 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.";
+}
+
+// Implemented in all cmGlobaleGenerator sub-classes.
+// Used in:
+// Source/cmLocalGenerator.cxx
+// Source/cmake.cxx
+void cmGlobalNinjaGenerator::Generate()
+{
+ this->OpenBuildFileStream();
+ this->OpenRulesFileStream();
+
+ this->cmGlobalGenerator::Generate();
+
+ this->WriteAssumedSourceDependencies();
+ this->WriteTargetAliases(*this->BuildFileStream);
+ this->WriteBuiltinTargets(*this->BuildFileStream);
+
+ if (cmSystemTools::GetErrorOccuredFlag()) {
+ this->RulesFileStream->setstate(std::ios_base::failbit);
+ this->BuildFileStream->setstate(std::ios_base::failbit);
+ }
+
+ this->CloseCompileCommandsStream();
+ this->CloseRulesFileStream();
+ this->CloseBuildFileStream();
+}
+
+// Implemented in all cmGlobaleGenerator sub-classes.
+// Used in:
+// Source/cmMakefile.cxx:
+void cmGlobalNinjaGenerator
+::EnableLanguage(std::vector<std::string>const& languages,
+ cmMakefile *mf,
+ bool optional)
+{
+ std::string path;
+ for(std::vector<std::string>::const_iterator l = languages.begin();
+ l != languages.end(); ++l)
+ {
+ std::vector<std::string> language;
+ language.push_back(*l);
+
+ if(*l == "NONE")
+ {
+ this->cmGlobalGenerator::EnableLanguage(language, mf, optional);
+ continue;
+ }
+ else if(*l == "Fortran")
+ {
+ std::string message = "The \"";
+ message += this->GetName();
+ message += "\" generator does not support the language \"";
+ message += *l;
+ message += "\" yet.";
+ cmSystemTools::Error(message.c_str());
+ }
+ else if(*l == "RC")
+ {
+ // check if mingw is used
+ if(mf->IsOn("CMAKE_COMPILER_IS_MINGW"))
+ {
+ UsingMinGW = true;
+ if(!mf->GetDefinition("CMAKE_RC_COMPILER"))
+ {
+ std::string windres = cmSystemTools::FindProgram("windres");
+ if(windres.empty())
+ {
+ std::string compiler_path;
+ std::string::size_type prefix = std::string::npos;
+ if (mf->GetDefinition("CMAKE_C_COMPILER"))
+ {
+ compiler_path = mf->GetDefinition("CMAKE_C_COMPILER");
+ prefix = compiler_path.rfind("gcc");
+ }
+ else if (mf->GetDefinition("CMAKE_CXX_COMPILER"))
+ {
+ compiler_path = mf->GetDefinition("CMAKE_CXX_COMPILER");
+ prefix = compiler_path.rfind("++");
+ prefix--;
+ }
+ if (prefix != std::string::npos)
+ {
+ windres = compiler_path.substr(0, prefix) + "windres";
+ windres = cmSystemTools::FindProgram(windres.c_str());
+ }
+ }
+ if(!windres.empty())
+ mf->AddDefinition("CMAKE_RC_COMPILER", windres.c_str());
+ }
+ }
+ }
+ this->cmGlobalGenerator::EnableLanguage(language, mf, optional);
+ this->ResolveLanguageCompiler(*l, mf, optional);
+ }
+}
+
+bool cmGlobalNinjaGenerator::UsingMinGW = false;
+
+// Implemented by:
+// cmGlobalUnixMakefileGenerator3
+// cmGlobalVisualStudio10Generator
+// cmGlobalVisualStudio6Generator
+// cmGlobalVisualStudio7Generator
+// cmGlobalXCodeGenerator
+// Called by:
+// cmGlobalGenerator::Build()
+std::string cmGlobalNinjaGenerator
+::GenerateBuildCommand(const char* makeProgram,
+ const char* projectName,
+ const char* additionalOptions,
+ const char* targetName,
+ const char* config,
+ bool ignoreErrors,
+ bool fast)
+{
+ // Project name and config are not used yet.
+ (void)projectName;
+ (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 += " ";
+ makeCommand += additionalOptions;
+ }
+ if(targetName)
+ {
+ if(strcmp(targetName, "clean") == 0)
+ {
+ makeCommand += " -t clean";
+ }
+ else
+ {
+ makeCommand += " ";
+ makeCommand += targetName;
+ }
+ }
+
+ return makeCommand;
+}
+
+//----------------------------------------------------------------------------
+// Non-virtual public methods.
+
+void cmGlobalNinjaGenerator::AddRule(const std::string& name,
+ 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,
+ bool generator)
+{
+ // Do not add the same rule twice.
+ if (this->HasRule(name))
+ {
+ return;
+ }
+
+ this->Rules.insert(name);
+ cmGlobalNinjaGenerator::WriteRule(*this->RulesFileStream,
+ name,
+ command,
+ description,
+ comment,
+ depfile,
+ rspfile,
+ rspcontent,
+ restat,
+ generator);
+
+ this->RuleCmdLength[name] = (int) command.size();
+}
+
+bool cmGlobalNinjaGenerator::HasRule(const std::string &name)
+{
+ RulesSetType::const_iterator rule = this->Rules.find(name);
+ return (rule != this->Rules.end());
+}
+
+//----------------------------------------------------------------------------
+// Private virtual overrides
+
+// TODO: Refactor to combine with cmGlobalUnixMakefileGenerator3 impl.
+void cmGlobalNinjaGenerator::ComputeTargetObjects(cmGeneratorTarget* gt) const
+{
+ cmTarget* target = gt->Target;
+
+ // 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;
+ }
+}
+
+//----------------------------------------------------------------------------
+// Private methods
+
+void cmGlobalNinjaGenerator::OpenBuildFileStream()
+{
+ // Compute Ninja's build file path.
+ std::string buildFilePath =
+ this->GetCMakeInstance()->GetHomeOutputDirectory();
+ buildFilePath += "/";
+ buildFilePath += cmGlobalNinjaGenerator::NINJA_BUILD_FILE;
+
+ // Get a stream where to generate things.
+ if (!this->BuildFileStream)
+ {
+ this->BuildFileStream = new cmGeneratedFileStream(buildFilePath.c_str());
+ if (!this->BuildFileStream)
+ {
+ // An error message is generated by the constructor if it cannot
+ // open the file.
+ return;
+ }
+ }
+
+ // Write the do not edit header.
+ this->WriteDisclaimer(*this->BuildFileStream);
+
+ // Write a comment about this file.
+ *this->BuildFileStream
+ << "# This file contains all the build statements describing the\n"
+ << "# compilation DAG.\n\n"
+ ;
+}
+
+void cmGlobalNinjaGenerator::CloseBuildFileStream()
+{
+ if (this->BuildFileStream)
+ {
+ delete this->BuildFileStream;
+ this->BuildFileStream = 0;
+ }
+ else
+ {
+ cmSystemTools::Error("Build file stream was not open.");
+ }
+}
+
+void cmGlobalNinjaGenerator::OpenRulesFileStream()
+{
+ // Compute Ninja's build file path.
+ std::string rulesFilePath =
+ this->GetCMakeInstance()->GetHomeOutputDirectory();
+ rulesFilePath += "/";
+ rulesFilePath += cmGlobalNinjaGenerator::NINJA_RULES_FILE;
+
+ // Get a stream where to generate things.
+ if (!this->RulesFileStream)
+ {
+ this->RulesFileStream = new cmGeneratedFileStream(rulesFilePath.c_str());
+ if (!this->RulesFileStream)
+ {
+ // An error message is generated by the constructor if it cannot
+ // open the file.
+ return;
+ }
+ }
+
+ // Write the do not edit header.
+ this->WriteDisclaimer(*this->RulesFileStream);
+
+ // Write comment about this file.
+ *this->RulesFileStream
+ << "# This file contains all the rules used to get the outputs files\n"
+ << "# built from the input files.\n"
+ << "# It is included in the main '" << NINJA_BUILD_FILE << "'.\n\n"
+ ;
+}
+
+void cmGlobalNinjaGenerator::CloseRulesFileStream()
+{
+ if (this->RulesFileStream)
+ {
+ delete this->RulesFileStream;
+ this->RulesFileStream = 0;
+ }
+ else
+ {
+ cmSystemTools::Error("Rules file stream was not open.");
+ }
+}
+
+void cmGlobalNinjaGenerator::AddCXXCompileCommand(
+ const std::string &commandLine,
+ const std::string &sourceFile)
+{
+ // Compute Ninja's build file path.
+ std::string buildFileDir =
+ this->GetCMakeInstance()->GetHomeOutputDirectory();
+ if (!this->CompileCommandsStream)
+ {
+ std::string buildFilePath = buildFileDir + "/compile_commands.json";
+
+ // Get a stream where to generate things.
+ this->CompileCommandsStream =
+ new cmGeneratedFileStream(buildFilePath.c_str());
+ *this->CompileCommandsStream << "[";
+ } else {
+ *this->CompileCommandsStream << "," << std::endl;
+ }
+
+ std::string sourceFileName = sourceFile;
+ if (!cmSystemTools::FileIsFullPath(sourceFileName.c_str()))
+ {
+ sourceFileName = cmSystemTools::CollapseFullPath(
+ sourceFileName.c_str(),
+ this->GetCMakeInstance()->GetHomeOutputDirectory());
+ }
+
+
+ *this->CompileCommandsStream << "\n{\n"
+ << " \"directory\": \""
+ << cmGlobalGenerator::EscapeJSON(buildFileDir) << "\",\n"
+ << " \"command\": \""
+ << cmGlobalGenerator::EscapeJSON(commandLine) << "\",\n"
+ << " \"file\": \""
+ << cmGlobalGenerator::EscapeJSON(sourceFileName) << "\"\n"
+ << "}";
+}
+
+void cmGlobalNinjaGenerator::CloseCompileCommandsStream()
+{
+ if (this->CompileCommandsStream)
+ {
+ *this->CompileCommandsStream << "\n]";
+ delete this->CompileCommandsStream;
+ this->CompileCommandsStream = 0;
+ }
+
+}
+
+void cmGlobalNinjaGenerator::WriteDisclaimer(std::ostream& os)
+{
+ os
+ << "# CMAKE generated file: DO NOT EDIT!\n"
+ << "# Generated by \"" << this->GetName() << "\""
+ << " Generator, CMake Version "
+ << cmVersion::GetMajorVersion() << "."
+ << cmVersion::GetMinorVersion() << "\n\n";
+}
+
+void cmGlobalNinjaGenerator::AddDependencyToAll(cmTarget* target)
+{
+ this->AppendTargetOutputs(target, this->AllDependencies);
+}
+
+void cmGlobalNinjaGenerator::AddDependencyToAll(const std::string& input)
+{
+ this->AllDependencies.push_back(input);
+}
+
+void cmGlobalNinjaGenerator::WriteAssumedSourceDependencies()
+{
+ for (std::map<std::string, std::set<std::string> >::iterator
+ i = this->AssumedSourceDependencies.begin();
+ i != this->AssumedSourceDependencies.end(); ++i) {
+ cmNinjaDeps deps;
+ std::copy(i->second.begin(), i->second.end(), std::back_inserter(deps));
+ WriteCustomCommandBuild(/*command=*/"", /*description=*/"",
+ "Assume dependencies for generated source file.",
+ cmNinjaDeps(1, i->first), deps);
+ }
+}
+
+void
+cmGlobalNinjaGenerator
+::AppendTargetOutputs(cmTarget* target, cmNinjaDeps& outputs)
+{
+ const char* configName =
+ target->GetMakefile()->GetDefinition("CMAKE_BUILD_TYPE");
+ cmLocalNinjaGenerator *ng =
+ static_cast<cmLocalNinjaGenerator *>(this->LocalGenerators[0]);
+
+ 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).c_str()));
+ break;
+
+ case cmTarget::OBJECT_LIBRARY:
+ case cmTarget::UTILITY: {
+ std::string path = ng->ConvertToNinjaPath(
+ target->GetMakefile()->GetStartOutputDirectory());
+ if (path.empty() || path == ".")
+ outputs.push_back(target->GetName());
+ else {
+ path += "/";
+ path += target->GetName();
+ outputs.push_back(path);
+ }
+ break;
+ }
+
+ case cmTarget::GLOBAL_TARGET:
+ // Always use the target in HOME instead of an unused duplicate in a
+ // subdirectory.
+ outputs.push_back(target->GetName());
+ break;
+
+ default:
+ return;
+ }
+}
+
+void
+cmGlobalNinjaGenerator
+::AppendTargetDepends(cmTarget* target, cmNinjaDeps& outputs)
+{
+ if (target->GetType() == cmTarget::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::copy(utils.begin(), utils.end(), std::back_inserter(outputs));
+ } else {
+ cmTargetDependSet const& targetDeps =
+ this->GetTargetDirectDepends(*target);
+ for (cmTargetDependSet::const_iterator i = targetDeps.begin();
+ i != targetDeps.end(); ++i) {
+ this->AppendTargetOutputs(*i, outputs);
+ }
+ }
+}
+
+void cmGlobalNinjaGenerator::AddTargetAlias(const std::string& alias,
+ cmTarget* target) {
+ cmNinjaDeps outputs;
+ this->AppendTargetOutputs(target, outputs);
+ // Mark the target's outputs as ambiguous to ensure that no other target uses
+ // the output as an alias.
+ for (cmNinjaDeps::iterator i = outputs.begin(); i != outputs.end(); ++i)
+ TargetAliases[*i] = 0;
+
+ // Insert the alias into the map. If the alias was already present in the
+ // map and referred to another target, mark it as ambiguous.
+ std::pair<TargetAliasMap::iterator, bool> newAlias =
+ TargetAliases.insert(std::make_pair(alias, target));
+ if (newAlias.second && newAlias.first->second != target)
+ newAlias.first->second = 0;
+}
+
+void cmGlobalNinjaGenerator::WriteTargetAliases(std::ostream& os)
+{
+ cmGlobalNinjaGenerator::WriteDivider(os);
+ os << "# Target aliases.\n\n";
+
+ for (TargetAliasMap::iterator i = TargetAliases.begin();
+ i != TargetAliases.end(); ++i) {
+ // Don't write ambiguous aliases.
+ if (!i->second)
+ continue;
+
+ cmNinjaDeps deps;
+ this->AppendTargetOutputs(i->second, deps);
+
+ cmGlobalNinjaGenerator::WritePhonyBuild(os,
+ "",
+ cmNinjaDeps(1, i->first),
+ deps);
+ }
+}
+
+void cmGlobalNinjaGenerator::WriteBuiltinTargets(std::ostream& os)
+{
+ // Write headers.
+ cmGlobalNinjaGenerator::WriteDivider(os);
+ os << "# Built-in targets\n\n";
+
+ this->WriteTargetAll(os);
+ this->WriteTargetRebuildManifest(os);
+ this->WriteTargetClean(os);
+ this->WriteTargetHelp(os);
+}
+
+void cmGlobalNinjaGenerator::WriteTargetAll(std::ostream& os)
+{
+ cmNinjaDeps outputs;
+ outputs.push_back("all");
+
+ cmGlobalNinjaGenerator::WritePhonyBuild(os,
+ "The main all target.",
+ outputs,
+ this->AllDependencies);
+
+ cmGlobalNinjaGenerator::WriteDefault(os,
+ outputs,
+ "Make the all target the default.");
+}
+
+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)
+ << " -H"
+ << lg->ConvertToOutputFormat(mfRoot->GetHomeDirectory(),
+ cmLocalGenerator::SHELL)
+ << " -B"
+ << lg->ConvertToOutputFormat(mfRoot->GetHomeOutputDirectory(),
+ cmLocalGenerator::SHELL);
+ WriteRule(*this->RulesFileStream,
+ "RERUN_CMAKE",
+ cmd.str(),
+ "Re-running CMake...",
+ "Rule for re-running cmake.",
+ /*depfile=*/ "",
+ /*rspfile=*/ "",
+ /*rspcontent*/ "",
+ /*restat=*/ false,
+ /*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());
+ }
+ std::sort(implicitDeps.begin(), implicitDeps.end());
+ implicitDeps.erase(std::unique(implicitDeps.begin(), implicitDeps.end()),
+ implicitDeps.end());
+ implicitDeps.push_back("CMakeCache.txt");
+
+ WriteBuild(os,
+ "Re-run CMake if any of its inputs changed.",
+ "RERUN_CMAKE",
+ /*outputs=*/ cmNinjaDeps(1, NINJA_BUILD_FILE),
+ /*explicitDeps=*/ cmNinjaDeps(),
+ implicitDeps,
+ /*orderOnlyDeps=*/ cmNinjaDeps(),
+ /*variables=*/ cmNinjaVars());
+
+ WritePhonyBuild(os,
+ "A missing CMake input file is not an error.",
+ implicitDeps,
+ cmNinjaDeps());
+}
+
+std::string cmGlobalNinjaGenerator::ninjaCmd() const
+{
+ cmLocalGenerator* lgen = this->LocalGenerators[0];
+ if (lgen) {
+ return lgen->ConvertToOutputFormat(
+ lgen->GetMakefile()->GetRequiredDefinition("CMAKE_MAKE_PROGRAM"),
+ cmLocalGenerator::SHELL);
+ }
+ return "ninja";
+}
+
+void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os)
+{
+ WriteRule(*this->RulesFileStream,
+ "CLEAN",
+ (ninjaCmd() + " -t clean").c_str(),
+ "Cleaning all built files...",
+ "Rule for cleaning all built files.",
+ /*depfile=*/ "",
+ /*rspfile=*/ "",
+ /*rspcontent*/ "",
+ /*restat=*/ false,
+ /*generator=*/ false);
+ WriteBuild(os,
+ "Clean all the built files.",
+ "CLEAN",
+ /*outputs=*/ cmNinjaDeps(1, "clean"),
+ /*explicitDeps=*/ cmNinjaDeps(),
+ /*implicitDeps=*/ cmNinjaDeps(),
+ /*orderOnlyDeps=*/ cmNinjaDeps(),
+ /*variables=*/ cmNinjaVars());
+}
+
+void cmGlobalNinjaGenerator::WriteTargetHelp(std::ostream& os)
+{
+ WriteRule(*this->RulesFileStream,
+ "HELP",
+ (ninjaCmd() + " -t targets").c_str(),
+ "All primary targets available:",
+ "Rule for printing all primary targets available.",
+ /*depfile=*/ "",
+ /*rspfile=*/ "",
+ /*rspcontent*/ "",
+ /*restat=*/ false,
+ /*generator=*/ false);
+ WriteBuild(os,
+ "Print all primary targets available.",
+ "HELP",
+ /*outputs=*/ cmNinjaDeps(1, "help"),
+ /*explicitDeps=*/ cmNinjaDeps(),
+ /*implicitDeps=*/ cmNinjaDeps(),
+ /*orderOnlyDeps=*/ cmNinjaDeps(),
+ /*variables=*/ cmNinjaVars());
+}
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
new file mode 100644
index 000000000..b2fe24327
--- /dev/null
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -0,0 +1,370 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2011 Peter Collingbourne <peter@pcc.me.uk>
+ Copyright 2011 Nicolas Despres <nicolas.despres@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 cmGlobalNinjaGenerator_h
+# define cmGlobalNinjaGenerator_h
+
+# include "cmGlobalGenerator.h"
+# include "cmNinjaTypes.h"
+
+//#define NINJA_GEN_VERBOSE_FILES
+
+class cmLocalGenerator;
+class cmGeneratedFileStream;
+class cmGeneratorTarget;
+
+/**
+ * \class cmGlobalNinjaGenerator
+ * \brief Write a build.ninja file.
+ *
+ * The main differences between this generator and the UnixMakefile
+ * generator family are:
+ * - We don't care about VERBOSE variable or RULE_MESSAGES property since
+ * it is handle by Ninja's -v option.
+ * - We don't care about computing any progress status since Ninja manages
+ * it itself.
+ * - We don't care about generating a clean target since Ninja already have
+ * a clean tool.
+ * - We generate one build.ninja and one rules.ninja per project.
+ * - We try to minimize the number of generated rules: one per target and
+ * language.
+ * - We use Ninja special variable $in and $out to produce nice output.
+ * - We extensively use Ninja variable overloading system to minimize the
+ * number of generated rules.
+ */
+class cmGlobalNinjaGenerator : public cmGlobalGenerator
+{
+public:
+ /// The default name of Ninja's build file. Typically: build.ninja.
+ static const char* NINJA_BUILD_FILE;
+
+ /// The default name of Ninja's rules file. Typically: rules.ninja.
+ /// It is included in the main build.ninja file.
+ static const char* NINJA_RULES_FILE;
+
+ /// The indentation string used when generating Ninja's build file.
+ static const char* INDENT;
+
+ /// Write @a count times INDENT level to output stream @a os.
+ static void Indent(std::ostream& os, int count);
+
+ /// Write a divider in the given output stream @a os.
+ static void WriteDivider(std::ostream& os);
+
+ 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);
+
+ /**
+ * Write the given @a comment to the output stream @a os. It
+ * handles new line character properly.
+ */
+ static void WriteComment(std::ostream& os, const std::string& comment);
+
+ /**
+ * 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.
+ * @warning no escaping of any kind is done here.
+ */
+ static void WriteBuild(std::ostream& os,
+ const std::string& comment,
+ const std::string& rule,
+ const cmNinjaDeps& outputs,
+ const cmNinjaDeps& explicitDeps,
+ const cmNinjaDeps& implicitDeps,
+ const cmNinjaDeps& orderOnlyDeps,
+ const cmNinjaVars& variables,
+ int cmdLineLimit = -1);
+
+ /**
+ * Helper to write a build statement with the special 'phony' rule.
+ */
+ static void WritePhonyBuild(std::ostream& os,
+ const std::string& comment,
+ const cmNinjaDeps& outputs,
+ const cmNinjaDeps& explicitDeps,
+ const cmNinjaDeps& implicitDeps = cmNinjaDeps(),
+ const cmNinjaDeps& orderOnlyDeps = cmNinjaDeps(),
+ const cmNinjaVars& variables = cmNinjaVars());
+
+ void WriteCustomCommandBuild(const std::string& command,
+ const std::string& description,
+ const std::string& comment,
+ const cmNinjaDeps& outputs,
+ const cmNinjaDeps& deps = cmNinjaDeps(),
+ const cmNinjaDeps& orderOnlyDeps = cmNinjaDeps());
+ void WriteMacOSXContentBuild(const std::string& input,
+ const std::string& output);
+
+ /**
+ * Write a rule statement named @a name to @a os with the @a comment,
+ * the mandatory @a command, the @a depfile and the @a description.
+ * It also writes the variables bound to this rule statement.
+ * @warning no escaping of any kind is done here.
+ */
+ static void WriteRule(std::ostream& os,
+ const std::string& name,
+ 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,
+ bool generator);
+
+ /**
+ * Write a variable named @a name to @a os with value @a value and an
+ * optional @a comment. An @a indent level can be specified.
+ * @warning no escaping of any kind is done here.
+ */
+ static void WriteVariable(std::ostream& os,
+ const std::string& name,
+ const std::string& value,
+ const std::string& comment = "",
+ int indent = 0);
+
+ /**
+ * Write an include statement including @a filename with an optional
+ * @a comment to the @a os stream.
+ */
+ static void WriteInclude(std::ostream& os,
+ const std::string& filename,
+ const std::string& comment = "");
+
+ /**
+ * Write a default target statement specifying @a targets as
+ * the default targets.
+ */
+ static void WriteDefault(std::ostream& os,
+ const cmNinjaDeps& targets,
+ const std::string& comment = "");
+
+
+ static bool IsMinGW() { return UsingMinGW; }
+
+
+public:
+ /// Default constructor.
+ cmGlobalNinjaGenerator();
+
+ /// Convenience method for creating an instance of this class.
+ static cmGlobalGenerator* New() {
+ return new cmGlobalNinjaGenerator; }
+
+ /// Destructor.
+ virtual ~cmGlobalNinjaGenerator() { }
+
+ /// Overloaded methods. @see cmGlobalGenerator::CreateLocalGenerator()
+ virtual cmLocalGenerator* CreateLocalGenerator();
+
+ /// Overloaded methods. @see cmGlobalGenerator::GetName().
+ virtual const char* GetName() const {
+ return cmGlobalNinjaGenerator::GetActualName(); }
+
+ /// @return the name of this generator.
+ static const char* GetActualName() { return "Ninja"; }
+
+ /// Overloaded methods. @see cmGlobalGenerator::GetDocumentation()
+ virtual void GetDocumentation(cmDocumentationEntry& entry) const;
+
+ /// 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* additionalOptions,
+ const char* targetName,
+ const char* config,
+ bool ignoreErrors,
+ bool fast);
+
+ // Setup target names
+ virtual const char* GetAllTargetName() const { return "all"; }
+ virtual const char* GetInstallTargetName() const { return "install"; }
+ virtual const char* GetInstallLocalTargetName() const {
+ return "install/local";
+ }
+ virtual const char* GetInstallStripTargetName() const {
+ return "install/strip";
+ }
+ virtual const char* GetTestTargetName() const { return "test"; }
+ virtual const char* GetPackageTargetName() const { return "package"; }
+ virtual const char* GetPackageSourceTargetName() const {
+ return "package_source";
+ }
+ virtual const char* GetEditCacheTargetName() const {
+ return "edit_cache";
+ }
+ virtual const char* GetRebuildCacheTargetName() const {
+ return "rebuild_cache";
+ }
+ virtual const char* GetCleanTargetName() const { return "clean"; }
+
+
+ cmGeneratedFileStream* GetBuildFileStream() const {
+ return this->BuildFileStream; }
+
+ cmGeneratedFileStream* GetRulesFileStream() const {
+ return this->RulesFileStream; }
+
+ void AddCXXCompileCommand(const std::string &commandLine,
+ const std::string &sourceFile);
+
+ /**
+ * Add a rule to the generated build system.
+ * Call WriteRule() behind the scene but perform some check before like:
+ * - Do not add twice the same rule.
+ */
+ void AddRule(const std::string& name,
+ 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);
+
+ bool HasRule(const std::string& name);
+
+ void AddCustomCommandRule();
+ void AddMacOSXContentRule();
+
+ bool HasCustomCommandOutput(const std::string &output) {
+ return this->CustomCommandOutputs.find(output) !=
+ this->CustomCommandOutputs.end();
+ }
+
+ /// Called when we have seen the given custom command. Returns true
+ /// if we has seen it before.
+ bool SeenCustomCommand(cmCustomCommand const *cc) {
+ return !this->CustomCommands.insert(cc).second;
+ }
+
+ /// Called when we have seen the given custom command output.
+ void SeenCustomCommandOutput(const std::string &output) {
+ this->CustomCommandOutputs.insert(output);
+ // We don't need the assumed dependencies anymore, because we have
+ // an output.
+ this->AssumedSourceDependencies.erase(output);
+ }
+
+ void AddAssumedSourceDependencies(const std::string &source,
+ const cmNinjaDeps &deps) {
+ std::set<std::string> &ASD = this->AssumedSourceDependencies[source];
+ // Because we may see the same source file multiple times (same source
+ // specified in multiple targets), compute the union of any assumed
+ // dependencies.
+ ASD.insert(deps.begin(), deps.end());
+ }
+
+ void AppendTargetOutputs(cmTarget* target, cmNinjaDeps& outputs);
+ void AppendTargetDepends(cmTarget* target, cmNinjaDeps& outputs);
+ void AddDependencyToAll(cmTarget* target);
+ void AddDependencyToAll(const std::string& input);
+
+ const std::vector<cmLocalGenerator*>& GetLocalGenerators() const {
+ return LocalGenerators; }
+
+ bool IsExcluded(cmLocalGenerator* root, cmTarget& target) {
+ return cmGlobalGenerator::IsExcluded(root, target); }
+
+ int GetRuleCmdLength(const std::string& name) {
+ return RuleCmdLength[name]; }
+
+ void AddTargetAlias(const std::string& alias, cmTarget* target);
+
+
+protected:
+
+ /// Overloaded methods.
+ /// @see cmGlobalGenerator::CheckALLOW_DUPLICATE_CUSTOM_TARGETS()
+ virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() { return true; }
+
+
+private:
+
+ /// @see cmGlobalGenerator::ComputeTargetObjects
+ virtual void ComputeTargetObjects(cmGeneratorTarget* gt) const;
+
+ void OpenBuildFileStream();
+ void CloseBuildFileStream();
+
+ void CloseCompileCommandsStream();
+
+ void OpenRulesFileStream();
+ void CloseRulesFileStream();
+
+ /// Write the common disclaimer text at the top of each build file.
+ void WriteDisclaimer(std::ostream& os);
+
+ void WriteAssumedSourceDependencies();
+
+ void WriteTargetAliases(std::ostream& os);
+
+ void WriteBuiltinTargets(std::ostream& os);
+ void WriteTargetAll(std::ostream& os);
+ void WriteTargetRebuildManifest(std::ostream& os);
+ void WriteTargetClean(std::ostream& os);
+ void WriteTargetHelp(std::ostream& os);
+
+ std::string ninjaCmd() const;
+
+
+ /// The file containing the build statement. (the relation ship of the
+ /// compilation DAG).
+ cmGeneratedFileStream* BuildFileStream;
+ /// The file containing the rule statements. (The action attached to each
+ /// edge of the compilation DAG).
+ cmGeneratedFileStream* RulesFileStream;
+ cmGeneratedFileStream* CompileCommandsStream;
+
+ /// The type used to store the set of rules added to the generated build
+ /// system.
+ typedef std::set<std::string> RulesSetType;
+
+ /// The set of rules added to the generated build system.
+ RulesSetType Rules;
+
+ /// Length of rule command, used by rsp file evaluation
+ std::map<std::string, int> RuleCmdLength;
+
+ /// The set of dependencies to add to the "all" target.
+ cmNinjaDeps AllDependencies;
+
+ /// 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 mapping from source file to assumed dependencies.
+ std::map<std::string, std::set<std::string> > AssumedSourceDependencies;
+
+ typedef std::map<std::string, cmTarget*> TargetAliasMap;
+ TargetAliasMap TargetAliases;
+
+ static cmLocalGenerator* LocalGenerator;
+
+ static bool UsingMinGW;
+
+};
+
+#endif // ! cmGlobalNinjaGenerator_h
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
new file mode 100644
index 000000000..ebd82194c
--- /dev/null
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -0,0 +1,1059 @@
+/*============================================================================
+ 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 "cmGlobalUnixMakefileGenerator3.h"
+#include "cmLocalUnixMakefileGenerator3.h"
+#include "cmMakefileTargetGenerator.h"
+#include "cmMakefile.h"
+#include "cmake.h"
+#include "cmGeneratedFileStream.h"
+#include "cmSourceFile.h"
+#include "cmTarget.h"
+#include "cmGeneratorTarget.h"
+
+cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3()
+{
+ // This type of makefile always requires unix style paths
+ this->ForceUnixPaths = true;
+ this->FindMakeProgramFile = "CMakeUnixFindMake.cmake";
+ this->ToolSupportsColor = true;
+
+#if defined(_WIN32) || defined(__VMS)
+ this->UseLinkScript = false;
+#else
+ this->UseLinkScript = true;
+#endif
+ this->CommandDatabase = NULL;
+}
+
+void cmGlobalUnixMakefileGenerator3
+::EnableLanguage(std::vector<std::string>const& languages,
+ cmMakefile *mf,
+ bool optional)
+{
+ this->cmGlobalGenerator::EnableLanguage(languages, mf, optional);
+ for(std::vector<std::string>::const_iterator l = languages.begin();
+ l != languages.end(); ++l)
+ {
+ if(*l == "NONE")
+ {
+ continue;
+ }
+ this->ResolveLanguageCompiler(*l, mf, optional);
+ }
+}
+
+///! Create a local generator appropriate to this Global Generator
+cmLocalGenerator *cmGlobalUnixMakefileGenerator3::CreateLocalGenerator()
+{
+ cmLocalGenerator* lg = new cmLocalUnixMakefileGenerator3;
+ lg->SetGlobalGenerator(this);
+ return lg;
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalUnixMakefileGenerator3
+::GetDocumentation(cmDocumentationEntry& entry) const
+{
+ entry.Name = this->GetName();
+ 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
+{
+ cmTarget* target = gt->Target;
+ cmLocalUnixMakefileGenerator3* lg =
+ static_cast<cmLocalUnixMakefileGenerator3*>(gt->LocalGenerator);
+
+ // 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;
+ bool hasSourceExtension = true;
+ std::string objectName = gt->LocalGenerator
+ ->GetObjectFileNameWithoutTarget(*sf, dir_max,
+ &hasSourceExtension);
+ gt->Objects[sf] = objectName;
+ lg->AddLocalObjectFile(target, sf, objectName, hasSourceExtension);
+ }
+}
+
+void cmGlobalUnixMakefileGenerator3::Generate()
+{
+ // first do superclass method
+ this->cmGlobalGenerator::Generate();
+
+ // initialize progress
+ unsigned long total = 0;
+ for(ProgressMapType::const_iterator pmi = this->ProgressMap.begin();
+ pmi != this->ProgressMap.end(); ++pmi)
+ {
+ total += pmi->second.NumberOfActions;
+ }
+
+ // write each target's progress.make this loop is done twice. Bascially the
+ // Generate pass counts all the actions, the first loop below determines
+ // how many actions have progress updates for each target and writes to
+ // corrrect variable values for everything except the all targets. The
+ // second loop actually writes out correct values for the all targets as
+ // well. This is because the all targets require more information that is
+ // computed in the first loop.
+ unsigned long current = 0;
+ for(ProgressMapType::iterator pmi = this->ProgressMap.begin();
+ pmi != this->ProgressMap.end(); ++pmi)
+ {
+ pmi->second.WriteProgressVariables(total, current);
+ }
+ for(unsigned int i = 0; i < this->LocalGenerators.size(); ++i)
+ {
+ cmLocalUnixMakefileGenerator3 *lg =
+ static_cast<cmLocalUnixMakefileGenerator3 *>(this->LocalGenerators[i]);
+ std::string markFileName = lg->GetMakefile()->GetStartOutputDirectory();
+ markFileName += "/";
+ markFileName += cmake::GetCMakeFilesDirectory();
+ markFileName += "/progress.marks";
+ cmGeneratedFileStream markFile(markFileName.c_str());
+ markFile << this->CountProgressMarksInAll(lg) << "\n";
+ }
+
+ // write the main makefile
+ this->WriteMainMakefile2();
+ this->WriteMainCMakefile();
+
+ if (this->CommandDatabase != NULL) {
+ *this->CommandDatabase << std::endl << "]";
+ delete this->CommandDatabase;
+ this->CommandDatabase = NULL;
+ }
+}
+
+void cmGlobalUnixMakefileGenerator3::AddCXXCompileCommand(
+ const std::string &sourceFile, const std::string &workingDirectory,
+ const std::string &compileCommand) {
+ if (this->CommandDatabase == NULL)
+ {
+ std::string commandDatabaseName =
+ std::string(this->GetCMakeInstance()->GetHomeOutputDirectory())
+ + "/compile_commands.json";
+ this->CommandDatabase =
+ new cmGeneratedFileStream(commandDatabaseName.c_str());
+ *this->CommandDatabase << "[" << std::endl;
+ } else {
+ *this->CommandDatabase << "," << std::endl;
+ }
+ *this->CommandDatabase << "{" << std::endl
+ << " \"directory\": \""
+ << cmGlobalGenerator::EscapeJSON(workingDirectory) << "\","
+ << std::endl
+ << " \"command\": \"" <<
+ cmGlobalGenerator::EscapeJSON(compileCommand) << "\","
+ << std::endl
+ << " \"file\": \"" <<
+ cmGlobalGenerator::EscapeJSON(sourceFile) << "\""
+ << std::endl << "}";
+}
+
+void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2()
+{
+ // Open the output file. This should not be copy-if-different
+ // because the check-build-system step compares the makefile time to
+ // see if the build system must be regenerated.
+ std::string makefileName =
+ this->GetCMakeInstance()->GetHomeOutputDirectory();
+ makefileName += cmake::GetCMakeFilesDirectory();
+ makefileName += "/Makefile2";
+ cmGeneratedFileStream makefileStream(makefileName.c_str());
+ if(!makefileStream)
+ {
+ return;
+ }
+
+ // get a local generator for some useful methods
+ cmLocalUnixMakefileGenerator3 *lg =
+ static_cast<cmLocalUnixMakefileGenerator3 *>(this->LocalGenerators[0]);
+
+ // Write the do not edit header.
+ lg->WriteDisclaimer(makefileStream);
+
+ // Write the main entry point target. This must be the VERY first
+ // target so that make with no arguments will run it.
+ // Just depend on the all target to drive the build.
+ std::vector<std::string> depends;
+ std::vector<std::string> no_commands;
+ depends.push_back("all");
+
+ // Write the rule.
+ lg->WriteMakeRule(makefileStream,
+ "Default target executed when no arguments are "
+ "given to make.",
+ "default_target",
+ depends,
+ no_commands, true);
+
+ depends.clear();
+
+ // The all and preinstall rules might never have any dependencies
+ // added to them.
+ if(this->EmptyRuleHackDepends != "")
+ {
+ depends.push_back(this->EmptyRuleHackDepends);
+ }
+
+ // Write and empty all:
+ lg->WriteMakeRule(makefileStream,
+ "The main recursive all target", "all",
+ depends, no_commands, true);
+
+ // Write an empty preinstall:
+ lg->WriteMakeRule(makefileStream,
+ "The main recursive preinstall target", "preinstall",
+ depends, no_commands, true);
+
+ // Write out the "special" stuff
+ lg->WriteSpecialTargetsTop(makefileStream);
+
+ // write the target convenience rules
+ unsigned int i;
+ for (i = 0; i < this->LocalGenerators.size(); ++i)
+ {
+ lg =
+ static_cast<cmLocalUnixMakefileGenerator3 *>(this->LocalGenerators[i]);
+ this->WriteConvenienceRules2(makefileStream,lg);
+ }
+
+ lg = static_cast<cmLocalUnixMakefileGenerator3 *>(this->LocalGenerators[0]);
+ lg->WriteSpecialTargetsBottom(makefileStream);
+}
+
+
+//----------------------------------------------------------------------------
+void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
+{
+ // Open the output file. This should not be copy-if-different
+ // because the check-build-system step compares the makefile time to
+ // see if the build system must be regenerated.
+ std::string cmakefileName =
+ this->GetCMakeInstance()->GetHomeOutputDirectory();
+ cmakefileName += cmake::GetCMakeFilesDirectory();
+ cmakefileName += "/Makefile.cmake";
+ cmGeneratedFileStream cmakefileStream(cmakefileName.c_str());
+ if(!cmakefileStream)
+ {
+ return;
+ }
+
+ std::string makefileName =
+ this->GetCMakeInstance()->GetHomeOutputDirectory();
+ makefileName += "/Makefile";
+
+ // get a local generator for some useful methods
+ cmLocalUnixMakefileGenerator3 *lg =
+ static_cast<cmLocalUnixMakefileGenerator3 *>(this->LocalGenerators[0]);
+
+ // Write the do not edit header.
+ lg->WriteDisclaimer(cmakefileStream);
+
+ // Save the generator name
+ cmakefileStream
+ << "# The generator used is:\n"
+ << "SET(CMAKE_DEPENDS_GENERATOR \"" << this->GetName() << "\")\n\n";
+
+ // for each cmMakefile get its list of dependencies
+ std::vector<std::string> lfiles;
+ for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i)
+ {
+ lg =
+ static_cast<cmLocalUnixMakefileGenerator3 *>(this->LocalGenerators[i]);
+
+ // Get the list of files contributing to this generation step.
+ lfiles.insert(lfiles.end(),lg->GetMakefile()->GetListFiles().begin(),
+ lg->GetMakefile()->GetListFiles().end());
+ }
+ // Sort the list and remove duplicates.
+ std::sort(lfiles.begin(), lfiles.end(), std::less<std::string>());
+#if !defined(__VMS) // The Compaq STL on VMS crashes, so accept duplicates.
+ std::vector<std::string>::iterator new_end =
+ std::unique(lfiles.begin(),lfiles.end());
+ lfiles.erase(new_end, lfiles.end());
+#endif
+
+ // reset lg to the first makefile
+ lg = static_cast<cmLocalUnixMakefileGenerator3 *>(this->LocalGenerators[0]);
+
+ // Build the path to the cache file.
+ std::string cache = this->GetCMakeInstance()->GetHomeOutputDirectory();
+ cache += "/CMakeCache.txt";
+
+ // Save the list to the cmake file.
+ cmakefileStream
+ << "# The top level Makefile was generated from the following files:\n"
+ << "SET(CMAKE_MAKEFILE_DEPENDS\n"
+ << " \""
+ << lg->Convert(cache.c_str(),
+ cmLocalGenerator::START_OUTPUT).c_str() << "\"\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()
+ << "\"\n";
+ }
+ cmakefileStream
+ << " )\n\n";
+
+ // Build the path to the cache check file.
+ std::string check = this->GetCMakeInstance()->GetHomeOutputDirectory();
+ check += cmake::GetCMakeFilesDirectory();
+ check += "/cmake.check_cache";
+
+ // Set the corresponding makefile in the cmake file.
+ cmakefileStream
+ << "# The corresponding makefile is:\n"
+ << "SET(CMAKE_MAKEFILE_OUTPUTS\n"
+ << " \""
+ << lg->Convert(makefileName.c_str(),
+ cmLocalGenerator::START_OUTPUT).c_str() << "\"\n"
+ << " \""
+ << lg->Convert(check.c_str(),
+ cmLocalGenerator::START_OUTPUT).c_str() << "\"\n";
+ cmakefileStream << " )\n\n";
+
+ // CMake must rerun if a byproduct is missing.
+ {
+ cmakefileStream
+ << "# Byproducts of CMake generate step:\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()
+ << "\"\n";
+ }
+
+ // add in all the directory information files
+ std::string tmpStr;
+ for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i)
+ {
+ lg =
+ static_cast<cmLocalUnixMakefileGenerator3 *>(this->LocalGenerators[i]);
+ tmpStr = lg->GetMakefile()->GetStartOutputDirectory();
+ tmpStr += cmake::GetCMakeFilesDirectory();
+ tmpStr += "/CMakeDirectoryInformation.cmake";
+ cmakefileStream << " \"" <<
+ lg->Convert(tmpStr.c_str(),cmLocalGenerator::HOME_OUTPUT).c_str()
+ << "\"\n";
+ }
+ cmakefileStream << " )\n\n";
+ }
+
+ this->WriteMainCMakefileLanguageRules(cmakefileStream,
+ this->LocalGenerators);
+}
+
+void cmGlobalUnixMakefileGenerator3
+::WriteMainCMakefileLanguageRules(cmGeneratedFileStream& cmakefileStream,
+ std::vector<cmLocalGenerator *> &lGenerators
+ )
+{
+ cmLocalUnixMakefileGenerator3 *lg;
+
+ // now list all the target info files
+ cmakefileStream
+ << "# Dependency information for all targets:\n";
+ cmakefileStream
+ << "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++)
+ {
+ 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))
+ {
+ std::string tname = lg->GetRelativeTargetDirectory(l->second);
+ tname += "/DependInfo.cmake";
+ cmSystemTools::ConvertToUnixSlashes(tname);
+ cmakefileStream << " \"" << tname.c_str() << "\"\n";
+ }
+ }
+ }
+ cmakefileStream << " )\n";
+}
+
+//----------------------------------------------------------------------------
+void
+cmGlobalUnixMakefileGenerator3
+::WriteDirectoryRule2(std::ostream& ruleFileStream,
+ cmLocalUnixMakefileGenerator3* lg,
+ const char* pass, bool check_all,
+ bool check_relink)
+{
+ // Get the relative path to the subdirectory from the top.
+ std::string makeTarget = lg->GetMakefile()->GetStartOutputDirectory();
+ 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)
+ {
+ 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))
+ {
+ // Add this to the list of depends rules in this directory.
+ if((!check_all || !l->second.GetPropertyAsBool("EXCLUDE_FROM_ALL")) &&
+ (!check_relink ||
+ l->second.NeedRelinkBeforeInstall(lg->ConfigurationName.c_str())))
+ {
+ std::string tname = lg->GetRelativeTargetDirectory(l->second);
+ tname += "/";
+ tname += pass;
+ depends.push_back(tname);
+ }
+ }
+ }
+
+ // 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)
+ {
+ cmLocalUnixMakefileGenerator3* slg =
+ static_cast<cmLocalUnixMakefileGenerator3*>(*sdi);
+ std::string subdir = slg->GetMakefile()->GetStartOutputDirectory();
+ subdir += "/";
+ subdir += pass;
+ depends.push_back(subdir);
+ }
+
+ // Work-around for makes that drop rules that have no dependencies
+ // or commands.
+ if(depends.empty() && this->EmptyRuleHackDepends != "")
+ {
+ depends.push_back(this->EmptyRuleHackDepends);
+ }
+
+ // Write the rule.
+ std::string doc = "Convenience name for \"";
+ doc += pass;
+ doc += "\" pass in the directory.";
+ std::vector<std::string> no_commands;
+ lg->WriteMakeRule(ruleFileStream, doc.c_str(),
+ makeTarget.c_str(), depends, no_commands, true);
+}
+
+//----------------------------------------------------------------------------
+void
+cmGlobalUnixMakefileGenerator3
+::WriteDirectoryRules2(std::ostream& ruleFileStream,
+ cmLocalUnixMakefileGenerator3* lg)
+{
+ // Only subdirectories need these rules.
+ if(!lg->GetParent())
+ {
+ return;
+ }
+
+ // Begin the directory-level rules section.
+ std::string dir = lg->GetMakefile()->GetStartOutputDirectory();
+ dir = lg->Convert(dir.c_str(), cmLocalGenerator::HOME_OUTPUT,
+ cmLocalGenerator::MAKEFILE);
+ lg->WriteDivider(ruleFileStream);
+ ruleFileStream
+ << "# Directory level rules for directory "
+ << dir << "\n\n";
+
+ // Write directory-level rules for "all".
+ this->WriteDirectoryRule2(ruleFileStream, lg, "all", true, false);
+
+ // Write directory-level rules for "clean".
+ this->WriteDirectoryRule2(ruleFileStream, lg, "clean", false, false);
+
+ // Write directory-level rules for "preinstall".
+ this->WriteDirectoryRule2(ruleFileStream, lg, "preinstall", true, true);
+}
+
+
+std::string cmGlobalUnixMakefileGenerator3
+::GenerateBuildCommand(const char* makeProgram, const char *projectName,
+ const char* additionalOptions, const char *targetName,
+ const char* config, bool ignoreErrors, bool fast)
+{
+ // Project name and config are not used yet.
+ (void)projectName;
+ (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 && strlen(targetName))
+ {
+ cmLocalUnixMakefileGenerator3 *lg;
+ if (this->LocalGenerators.size())
+ {
+ lg = static_cast<cmLocalUnixMakefileGenerator3 *>
+ (this->LocalGenerators[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();
+ }
+
+ 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())
+ {
+ delete lg;
+ }
+ }
+ return makeCommand;
+}
+
+//----------------------------------------------------------------------------
+void
+cmGlobalUnixMakefileGenerator3
+::WriteConvenienceRules(std::ostream& ruleFileStream,
+ std::set<cmStdString> &emitted)
+{
+ std::vector<std::string> depends;
+ std::vector<std::string> commands;
+
+ depends.push_back("cmake_check_build_system");
+
+ // write the target convenience rules
+ unsigned int i;
+ cmLocalUnixMakefileGenerator3 *lg;
+ for (i = 0; i < this->LocalGenerators.size(); ++i)
+ {
+ 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)
+ {
+ // 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 &&
+ // 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)))
+ {
+ // Add a rule to build the target by name.
+ lg->WriteDivider(ruleFileStream);
+ ruleFileStream
+ << "# Target rules for targets named "
+ << t->second.GetName() << "\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()));
+ depends.clear();
+ depends.push_back("cmake_check_build_system");
+ lg->WriteMakeRule(ruleFileStream,
+ "Build rule for target.",
+ t->second.GetName(), depends, commands,
+ true);
+
+ // Add a fast rule to build the target
+ std::string localName = lg->GetRelativeTargetDirectory(t->second);
+ std::string makefileName;
+ makefileName = localName;
+ makefileName += "/build.make";
+ depends.clear();
+ commands.clear();
+ std::string makeTargetName = localName;
+ makeTargetName += "/build";
+ localName = t->second.GetName();
+ localName += "/fast";
+ commands.push_back(lg->GetRecursiveMakeCall
+ (makefileName.c_str(), makeTargetName.c_str()));
+ lg->WriteMakeRule(ruleFileStream, "fast build rule for target.",
+ localName.c_str(), depends, commands, true);
+
+ // Add a local name for the rule to relink the target before
+ // installation.
+ if(t->second.NeedRelinkBeforeInstall(lg->ConfigurationName.c_str()))
+ {
+ makeTargetName = lg->GetRelativeTargetDirectory(t->second);
+ makeTargetName += "/preinstall";
+ localName = t->second.GetName();
+ localName += "/preinstall";
+ depends.clear();
+ commands.clear();
+ commands.push_back(lg->GetRecursiveMakeCall
+ (makefileName.c_str(), makeTargetName.c_str()));
+ lg->WriteMakeRule(ruleFileStream,
+ "Manual pre-install relink rule for target.",
+ localName.c_str(), depends, commands, true);
+ }
+ }
+ }
+ }
+}
+
+
+//----------------------------------------------------------------------------
+void
+cmGlobalUnixMakefileGenerator3
+::WriteConvenienceRules2(std::ostream& ruleFileStream,
+ cmLocalUnixMakefileGenerator3 *lg)
+{
+ std::vector<std::string> depends;
+ std::vector<std::string> commands;
+ std::string localName;
+ std::string makeTargetName;
+
+
+ // write the directory level rules for this local gen
+ this->WriteDirectoryRules2(ruleFileStream,lg);
+
+ 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)
+ {
+ 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)))
+ {
+ std::string makefileName;
+ // Add a rule to build the target by name.
+ localName = lg->GetRelativeTargetDirectory(t->second);
+ makefileName = localName;
+ makefileName += "/build.make";
+
+ bool needRequiresStep = this->NeedRequiresStep(t->second);
+
+ lg->WriteDivider(ruleFileStream);
+ ruleFileStream
+ << "# Target rules for target "
+ << localName << "\n\n";
+
+ commands.clear();
+ makeTargetName = localName;
+ makeTargetName += "/depend";
+ commands.push_back(lg->GetRecursiveMakeCall
+ (makefileName.c_str(),makeTargetName.c_str()));
+
+ // add requires if we need it for this generator
+ if (needRequiresStep)
+ {
+ makeTargetName = localName;
+ makeTargetName += "/requires";
+ commands.push_back(lg->GetRecursiveMakeCall
+ (makefileName.c_str(),makeTargetName.c_str()));
+ }
+ makeTargetName = localName;
+ makeTargetName += "/build";
+ commands.push_back(lg->GetRecursiveMakeCall
+ (makefileName.c_str(),makeTargetName.c_str()));
+
+ // Write the rule.
+ localName += "/all";
+ depends.clear();
+
+ std::string progressDir =
+ lg->GetMakefile()->GetHomeOutputDirectory();
+ progressDir += cmake::GetCMakeFilesDirectory();
+ {
+ 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());
+ }
+ progressDir = "Built target ";
+ progressDir += t->first;
+ lg->AppendEcho(commands,progressDir.c_str());
+
+ this->AppendGlobalTargetDepends(depends,t->second);
+ lg->WriteMakeRule(ruleFileStream, "All Build rule for target.",
+ localName.c_str(), depends, commands, true);
+
+ // add the all/all dependency
+ if(!this->IsExcluded(this->LocalGenerators[0], t->second))
+ {
+ depends.clear();
+ depends.push_back(localName);
+ commands.clear();
+ lg->WriteMakeRule(ruleFileStream, "Include target in all.",
+ "all", depends, commands, true);
+ }
+
+ // Write the rule.
+ commands.clear();
+ progressDir = lg->GetMakefile()->GetHomeOutputDirectory();
+ progressDir += cmake::GetCMakeFilesDirectory();
+
+ {
+ // TODO: Convert the total progress count to a make variable.
+ cmOStringStream progCmd;
+ progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start ";
+ // # in target
+ progCmd << lg->Convert(progressDir.c_str(),
+ cmLocalGenerator::FULL,
+ cmLocalGenerator::SHELL);
+ //
+ std::set<cmTarget *> emitted;
+ progCmd << " "
+ << this->CountProgressMarksInTarget(&t->second, emitted);
+ commands.push_back(progCmd.str());
+ }
+ std::string tmp = cmake::GetCMakeFilesDirectoryPostSlash();
+ tmp += "Makefile2";
+ commands.push_back(lg->GetRecursiveMakeCall
+ (tmp.c_str(),localName.c_str()));
+ {
+ cmOStringStream progCmd;
+ progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; // # 0
+ progCmd << lg->Convert(progressDir.c_str(),
+ cmLocalGenerator::FULL,
+ cmLocalGenerator::SHELL);
+ progCmd << " 0";
+ commands.push_back(progCmd.str());
+ }
+ depends.clear();
+ depends.push_back("cmake_check_build_system");
+ localName = lg->GetRelativeTargetDirectory(t->second);
+ localName += "/rule";
+ lg->WriteMakeRule(ruleFileStream,
+ "Build rule for subdir invocation for target.",
+ localName.c_str(), 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);
+
+ // Add rules to prepare the target for installation.
+ if(t->second.NeedRelinkBeforeInstall(lg->ConfigurationName.c_str()))
+ {
+ localName = lg->GetRelativeTargetDirectory(t->second);
+ localName += "/preinstall";
+ depends.clear();
+ commands.clear();
+ commands.push_back(lg->GetRecursiveMakeCall
+ (makefileName.c_str(), localName.c_str()));
+ lg->WriteMakeRule(ruleFileStream,
+ "Pre-install relink rule for target.",
+ localName.c_str(), depends, commands, true);
+
+ if(!this->IsExcluded(this->LocalGenerators[0], t->second))
+ {
+ depends.clear();
+ depends.push_back(localName);
+ commands.clear();
+ lg->WriteMakeRule(ruleFileStream, "Prepare target for install.",
+ "preinstall", depends, commands, true);
+ }
+ }
+
+ // add the clean rule
+ localName = lg->GetRelativeTargetDirectory(t->second);
+ makeTargetName = localName;
+ makeTargetName += "/clean";
+ depends.clear();
+ commands.clear();
+ commands.push_back(lg->GetRecursiveMakeCall
+ (makefileName.c_str(), makeTargetName.c_str()));
+ lg->WriteMakeRule(ruleFileStream, "clean rule for target.",
+ makeTargetName.c_str(), depends, commands, true);
+ commands.clear();
+ depends.push_back(makeTargetName);
+ lg->WriteMakeRule(ruleFileStream, "clean rule for target.",
+ "clean", depends, commands, true);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+size_t
+cmGlobalUnixMakefileGenerator3
+::CountProgressMarksInTarget(cmTarget* target,
+ std::set<cmTarget*>& emitted)
+{
+ size_t count = 0;
+ if(emitted.insert(target).second)
+ {
+ count = this->ProgressMap[target].Marks.size();
+ TargetDependSet const& depends = this->GetTargetDirectDepends(*target);
+ for(TargetDependSet::const_iterator di = depends.begin();
+ di != depends.end(); ++di)
+ {
+ count += this->CountProgressMarksInTarget(*di, emitted);
+ }
+ }
+ return count;
+}
+
+//----------------------------------------------------------------------------
+size_t
+cmGlobalUnixMakefileGenerator3
+::CountProgressMarksInAll(cmLocalUnixMakefileGenerator3* 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();
+ t != targets.end(); ++t)
+ {
+ count += this->CountProgressMarksInTarget(*t, emitted);
+ }
+ return count;
+}
+
+//----------------------------------------------------------------------------
+void
+cmGlobalUnixMakefileGenerator3::RecordTargetProgress(
+ cmMakefileTargetGenerator* tg)
+{
+ TargetProgress& tp = this->ProgressMap[tg->GetTarget()];
+ 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)
+{
+ cmGeneratedFileStream fout(this->VariableFile.c_str());
+ for(unsigned long i = 1; i <= this->NumberOfActions; ++i)
+ {
+ fout << "CMAKE_PROGRESS_" << i << " = ";
+ if (total <= 100)
+ {
+ unsigned long num = i + current;
+ fout << num;
+ this->Marks.push_back(num);
+ }
+ else if (((i+current)*100)/total > ((i-1+current)*100)/total)
+ {
+ unsigned long num = ((i+current)*100)/total;
+ fout << num;
+ this->Marks.push_back(num);
+ }
+ fout << "\n";
+ }
+ fout << "\n";
+ current += this->NumberOfActions;
+}
+
+//----------------------------------------------------------------------------
+void
+cmGlobalUnixMakefileGenerator3
+::AppendGlobalTargetDepends(std::vector<std::string>& depends,
+ cmTarget& 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;
+ cmLocalUnixMakefileGenerator3* lg3 =
+ static_cast<cmLocalUnixMakefileGenerator3*>
+ (dep->GetMakefile()->GetLocalGenerator());
+ std::string tgtName = lg3->GetRelativeTargetDirectory(*dep);
+ tgtName += "/all";
+ depends.push_back(tgtName);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalUnixMakefileGenerator3::WriteHelpRule
+(std::ostream& ruleFileStream, cmLocalUnixMakefileGenerator3 *lg)
+{
+ // add the help target
+ std::string path;
+ std::vector<std::string> no_depends;
+ std::vector<std::string> commands;
+ lg->AppendEcho(commands,"The following are some of the valid targets "
+ "for this Makefile:");
+ lg->AppendEcho(commands,"... all (the default if no target is provided)");
+ lg->AppendEcho(commands,"... clean");
+ lg->AppendEcho(commands,"... depend");
+
+ // Keep track of targets already listed.
+ std::set<cmStdString> emittedTargets;
+
+ // for each local generator
+ unsigned int i;
+ cmLocalUnixMakefileGenerator3 *lg2;
+ for (i = 0; i < this->LocalGenerators.size(); ++i)
+ {
+ lg2 =
+ 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())
+ {
+ // 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)
+ {
+ 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))
+ {
+ if(emittedTargets.insert(t->second.GetName()).second)
+ {
+ path = "... ";
+ path += t->second.GetName();
+ lg->AppendEcho(commands,path.c_str());
+ }
+ }
+ }
+ }
+ }
+ std::vector<cmStdString> const& localHelp = lg->GetLocalHelp();
+ for(std::vector<cmStdString>::const_iterator o = localHelp.begin();
+ o != localHelp.end(); ++o)
+ {
+ path = "... ";
+ path += *o;
+ lg->AppendEcho(commands, path.c_str());
+ }
+ lg->WriteMakeRule(ruleFileStream, "Help Target",
+ "help",
+ no_depends, commands, true);
+ ruleFileStream << "\n\n";
+}
+
+
+bool cmGlobalUnixMakefileGenerator3
+::NeedRequiresStep(cmTarget const& target)
+{
+ std::set<cmStdString> languages;
+ target.GetLanguages(languages);
+ for(std::set<cmStdString>::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()))
+ {
+ return true;
+ }
+ }
+ return false;
+}
diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h
new file mode 100644
index 000000000..e6dd09d6d
--- /dev/null
+++ b/Source/cmGlobalUnixMakefileGenerator3.h
@@ -0,0 +1,189 @@
+/*============================================================================
+ 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 cmGlobalUnixMakefileGenerator3_h
+#define cmGlobalUnixMakefileGenerator3_h
+
+#include "cmGlobalGenerator.h"
+
+class cmGeneratedFileStream;
+class cmMakefileTargetGenerator;
+class cmLocalUnixMakefileGenerator3;
+
+/** \class cmGlobalUnixMakefileGenerator3
+ * \brief Write a Unix makefiles.
+ *
+ * cmGlobalUnixMakefileGenerator3 manages UNIX build process for a tree
+
+
+ The basic approach of this generator is to produce Makefiles that will all
+ be run with the current working directory set to the Home Output
+ directory. The one exception to this is the subdirectory Makefiles which are
+ created as a convenience and just cd up to the Home Output directory and
+ invoke the main Makefiles.
+
+ The make process starts with Makefile. Makefile should only contain the
+ targets the user is likely to invoke directly from a make command line. No
+ internal targets should be in this file. Makefile2 contains the internal
+ targets that are required to make the process work.
+
+ Makefile2 in turn will recursively make targets in the correct order. Each
+ target has its own directory \<target\>.dir and its own makefile build.make in
+ that directory. Also in that directory is a couple makefiles per source file
+ used by the target. Typically these are named source.obj.build.make and
+ source.obj.build.depend.make. The source.obj.build.make contains the rules
+ for building, cleaning, and computing dependencies for the given source
+ file. The build.depend.make contains additional dependencies that were
+ computed during dependency scanning. An additional file called
+ source.obj.depend is used as a marker to indicate when dependencies must be
+ rescanned.
+
+ Rules for custom commands follow the same model as rules for source files.
+
+ */
+
+class cmGlobalUnixMakefileGenerator3 : public cmGlobalGenerator
+{
+public:
+ cmGlobalUnixMakefileGenerator3();
+ static cmGlobalGenerator* New() {
+ return new cmGlobalUnixMakefileGenerator3; }
+
+ ///! Get the name for the generator.
+ virtual const char* GetName() const {
+ return cmGlobalUnixMakefileGenerator3::GetActualName();}
+ static const char* GetActualName() {return "Unix Makefiles";}
+
+ /** Get the documentation entry for this generator. */
+ virtual void GetDocumentation(cmDocumentationEntry& entry) const;
+
+ ///! Create a local generator appropriate to this Global Generator3
+ virtual cmLocalGenerator *CreateLocalGenerator();
+
+ /**
+ * Try to determine system infomation such as shared library
+ * extension, pthreads, byte order etc.
+ */
+ virtual void EnableLanguage(std::vector<std::string>const& languages,
+ cmMakefile *, bool optional);
+
+ /**
+ * 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();
+
+
+ void WriteMainCMakefileLanguageRules(cmGeneratedFileStream& cmakefileStream,
+ std::vector<cmLocalGenerator *> &);
+
+ // write out the help rule listing the valid targets
+ void WriteHelpRule(std::ostream& ruleFileStream,
+ cmLocalUnixMakefileGenerator3 *);
+
+ // write the top level target rules
+ void WriteConvenienceRules(std::ostream& ruleFileStream,
+ std::set<cmStdString> &emitted);
+
+ /** Get the command to use for a target that has no rule. This is
+ used for multiple output dependencies and for cmake_force. */
+ std::string GetEmptyRuleHackCommand() { return this->EmptyRuleHackCommand; }
+
+ /** Get the fake dependency to use when a rule has no real commands
+ or dependencies. */
+ std::string GetEmptyRuleHackDepends() { return this->EmptyRuleHackDepends; }
+
+ // change the build command for speed
+ virtual std::string GenerateBuildCommand
+ (const char* makeProgram,
+ const char *projectName, const char* additionalOptions,
+ const char *targetName,
+ const char* config, bool ignoreErrors, bool fast);
+
+ /** Record per-target progress information. */
+ void RecordTargetProgress(cmMakefileTargetGenerator* tg);
+
+ void AddCXXCompileCommand(const std::string &sourceFile,
+ const std::string &workingDirectory,
+ const std::string &compileCommand);
+
+protected:
+ void WriteMainMakefile2();
+ void WriteMainCMakefile();
+
+ void WriteConvenienceRules2(std::ostream& ruleFileStream,
+ cmLocalUnixMakefileGenerator3*);
+
+ void WriteDirectoryRule2(std::ostream& ruleFileStream,
+ cmLocalUnixMakefileGenerator3* lg,
+ const char* pass, bool check_all,
+ bool check_relink);
+ void WriteDirectoryRules2(std::ostream& ruleFileStream,
+ cmLocalUnixMakefileGenerator3* lg);
+
+ void AppendGlobalTargetDepends(std::vector<std::string>& depends,
+ cmTarget& target);
+
+ // does this generator need a requires step for any of its targets
+ bool NeedRequiresStep(cmTarget const&);
+
+ // Target name hooks for superclass.
+ const char* GetAllTargetName() const { return "all"; }
+ const char* GetInstallTargetName() const { return "install"; }
+ const char* GetInstallLocalTargetName() const { return "install/local"; }
+ const char* GetInstallStripTargetName() const { return "install/strip"; }
+ const char* GetPreinstallTargetName() const { return "preinstall"; }
+ const char* GetTestTargetName() const { return "test"; }
+ const char* GetPackageTargetName() const { return "package"; }
+ const char* GetPackageSourceTargetName() const { return "package_source"; }
+ const char* GetEditCacheTargetName() const { return "edit_cache"; }
+ const char* GetRebuildCacheTargetName() const { return "rebuild_cache"; }
+ const char* GetCleanTargetName() const { return "clean"; }
+
+ virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() { 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
+ // that might not do anything but might have other dependencies
+ // added later. If non-empty this variable holds a fake dependency
+ // that can be added.
+ std::string EmptyRuleHackDepends;
+
+ // Some make programs (Watcom) do not like rules with no commands.
+ // If non-empty this variable holds a bogus command that may be put
+ // in the rule to satisfy the make program.
+ std::string EmptyRuleHackCommand;
+
+ // Store per-target progress counters.
+ struct TargetProgress
+ {
+ TargetProgress(): NumberOfActions(0) {}
+ unsigned long NumberOfActions;
+ std::string VariableFile;
+ 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;
+ ProgressMapType ProgressMap;
+
+ size_t CountProgressMarksInTarget(cmTarget* target,
+ std::set<cmTarget*>& emitted);
+ size_t CountProgressMarksInAll(cmLocalUnixMakefileGenerator3* lg);
+
+ cmGeneratedFileStream *CommandDatabase;
+private:
+ virtual void ComputeTargetObjects(cmGeneratorTarget* gt) const;
+};
+
+#endif
diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx
new file mode 100644
index 000000000..947a1c99d
--- /dev/null
+++ b/Source/cmGlobalVisualStudio10Generator.cxx
@@ -0,0 +1,286 @@
+/*============================================================================
+ 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 "windows.h" // this must be first to define GetCurrentDirectory
+#include "cmGlobalVisualStudio10Generator.h"
+#include "cmLocalVisualStudio10Generator.h"
+#include "cmMakefile.h"
+#include "cmSourceFile.h"
+#include "cmake.h"
+
+
+cmGlobalVisualStudio10Generator::cmGlobalVisualStudio10Generator()
+{
+ 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);
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio10Generator::AddPlatformDefinitions(cmMakefile* mf)
+{
+ mf->AddDefinition("MSVC10", "1");
+ mf->AddDefinition("MSVC_C_ARCHITECTURE_ID", "X86");
+ mf->AddDefinition("MSVC_CXX_ARCHITECTURE_ID", "X86");
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio10Generator::WriteSLNHeader(std::ostream& fout)
+{
+ fout << "Microsoft Visual Studio Solution File, Format Version 11.00\n";
+ fout << "# Visual Studio 2010\n";
+}
+
+///! Create a local generator appropriate to this Global Generator
+cmLocalGenerator *cmGlobalVisualStudio10Generator::CreateLocalGenerator()
+{
+ cmLocalVisualStudio10Generator* lg =
+ new cmLocalVisualStudio10Generator(cmLocalVisualStudioGenerator::VS10);
+ lg->SetPlatformName(this->GetPlatformName());
+ lg->SetGlobalGenerator(this);
+ return lg;
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio10Generator::Generate()
+{
+ this->LongestSource = LongestSourcePath();
+ this->cmGlobalVisualStudio8Generator::Generate();
+ if(this->LongestSource.Length > 0)
+ {
+ cmMakefile* mf = this->LongestSource.Target->GetMakefile();
+ cmOStringStream e;
+ e <<
+ "The binary and/or source directory paths may be too long to generate "
+ "Visual Studio 10 files for this project. "
+ "Consider choosing shorter directory names to build this project with "
+ "Visual Studio 10. "
+ "A more detailed explanation follows."
+ "\n"
+ "There is a bug in the VS 10 IDE that renders property dialog fields "
+ "blank for files referenced by full path in the project file. "
+ "However, CMake must reference at least one file by full path:\n"
+ " " << 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() << "/"
+ << 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());
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio10Generator
+::GetDocumentation(cmDocumentationEntry& entry) const
+{
+ entry.Name = this->GetName();
+ entry.Brief = "Generates Visual Studio 10 project files.";
+ entry.Full = "";
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio10Generator
+::EnableLanguage(std::vector<std::string>const & lang,
+ cmMakefile *mf, bool optional)
+{
+ cmGlobalVisualStudio8Generator::EnableLanguage(lang, mf, optional);
+}
+
+//----------------------------------------------------------------------------
+const char* cmGlobalVisualStudio10Generator::GetPlatformToolset()
+{
+ if(!this->PlatformToolset.empty())
+ {
+ return this->PlatformToolset.c_str();
+ }
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+std::string cmGlobalVisualStudio10Generator::GetUserMacrosDirectory()
+{
+ 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))
+ {
+ 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
+ }
+
+ // path is (correctly) still empty if we did not read the base value from
+ // the Registry value
+ return path;
+}
+
+//----------------------------------------------------------------------------
+std::string cmGlobalVisualStudio10Generator::GetUserMacrosRegKeyBase()
+{
+ return "Software\\Microsoft\\VisualStudio\\10.0\\vsmacros";
+}
+
+
+std::string cmGlobalVisualStudio10Generator
+::GenerateBuildCommand(const char* makeProgram,
+ const char *projectName,
+ const char* additionalOptions, const char *targetName,
+ const char* config, bool ignoreErrors, bool fast)
+{
+ // now build the test
+ std::string makeCommand
+ = cmSystemTools::ConvertToOutputPath(makeProgram);
+ std::string lowerCaseCommand = makeCommand;
+ cmSystemTools::LowerCase(lowerCaseCommand);
+
+ // If makeProgram is devenv, parent class knows how to generate command:
+ if (lowerCaseCommand.find("devenv") != std::string::npos ||
+ lowerCaseCommand.find("VCExpress") != std::string::npos)
+ {
+ return cmGlobalVisualStudio7Generator::GenerateBuildCommand(makeProgram,
+ projectName, additionalOptions, targetName, config, ignoreErrors, fast);
+ }
+
+ // 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)
+ {
+ cmSystemTools::GetShortPath(makeCommand.c_str(), makeCommand);
+ }
+ // msbuild.exe CxxOnly.sln /t:Build /p:Configuration=Debug /target:ALL_BUILD
+ if(!targetName || strlen(targetName) == 0)
+ {
+ targetName = "ALL_BUILD";
+ }
+ bool clean = false;
+ if ( targetName && strcmp(targetName, "clean") == 0 )
+ {
+ clean = true;
+ makeCommand += " ";
+ makeCommand += projectName;
+ makeCommand += ".sln ";
+ makeCommand += "/t:Clean ";
+ }
+ else
+ {
+ makeCommand += " ";
+ makeCommand += targetName;
+ makeCommand += ".vcxproj ";
+ }
+ makeCommand += "/p:Configuration=";
+ if(config && strlen(config))
+ {
+ makeCommand += config;
+ }
+ else
+ {
+ makeCommand += "Debug";
+ }
+ if ( additionalOptions )
+ {
+ makeCommand += " ";
+ makeCommand += additionalOptions;
+ }
+ return makeCommand;
+}
+
+//----------------------------------------------------------------------------
+bool cmGlobalVisualStudio10Generator::Find64BitTools(cmMakefile* mf)
+{
+ if(!this->PlatformToolset.empty())
+ {
+ 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
+ // c:/Program Files (x86)/MSBuild/Microsoft.Cpp/v4.0/Platforms/
+ // {Itanium,Win32,x64}/PlatformToolsets/{v100,v90,Windows7.1SDK}
+ std::string winSDK_7_1;
+ if(cmSystemTools::ReadRegistryValue(
+ "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\"
+ "Windows\\v7.1;InstallationFolder", winSDK_7_1))
+ {
+ cmOStringStream m;
+ m << "Found Windows SDK v7.1: " << winSDK_7_1;
+ mf->DisplayStatus(m.str().c_str(), -1);
+ this->PlatformToolset = "Windows7.1SDK";
+ return true;
+ }
+ else
+ {
+ cmOStringStream 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";
+ mf->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmGlobalVisualStudio10Generator
+::GenerateRuleFile(std::string const& output) const
+{
+ // The VS 10 generator needs to create the .rule files on disk.
+ // Hide them away under the CMakeFiles directory.
+ std::string ruleDir = this->GetCMakeInstance()->GetHomeOutputDirectory();
+ ruleDir += cmake::GetCMakeFilesDirectory();
+ ruleDir += "/";
+ ruleDir += cmSystemTools::ComputeStringMD5(
+ cmSystemTools::GetFilenamePath(output).c_str());
+ std::string ruleFile = ruleDir + "/";
+ ruleFile += cmSystemTools::GetFilenameName(output);
+ ruleFile += ".rule";
+ return ruleFile;
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio10Generator::PathTooLong(
+ cmTarget* target, cmSourceFile* sf, std::string const& sfRel)
+{
+ size_t len = (strlen(target->GetMakefile()->GetCurrentOutputDirectory()) +
+ 1 + sfRel.length());
+ if(len > this->LongestSource.Length)
+ {
+ this->LongestSource.Length = len;
+ this->LongestSource.Target = target;
+ this->LongestSource.SourceFile = sf;
+ this->LongestSource.SourceRel = sfRel;
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmGlobalVisualStudio10Generator::UseFolderProperty()
+{
+ return IsExpressEdition() ? false : cmGlobalGenerator::UseFolderProperty();
+}
diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h
new file mode 100644
index 000000000..060cdfff3
--- /dev/null
+++ b/Source/cmGlobalVisualStudio10Generator.h
@@ -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.
+============================================================================*/
+#ifndef cmGlobalVisualStudio10Generator_h
+#define cmGlobalVisualStudio10Generator_h
+
+#include "cmGlobalVisualStudio8Generator.h"
+
+
+/** \class cmGlobalVisualStudio10Generator
+ * \brief Write a Unix makefiles.
+ *
+ * cmGlobalVisualStudio10Generator manages UNIX build process for a tree
+ */
+class cmGlobalVisualStudio10Generator :
+ public cmGlobalVisualStudio8Generator
+{
+public:
+ cmGlobalVisualStudio10Generator();
+ static cmGlobalGenerator* New() {
+ return new cmGlobalVisualStudio10Generator; }
+
+ virtual std::string
+ GenerateBuildCommand(const char* makeProgram,
+ const char *projectName,
+ const char* additionalOptions, const char *targetName,
+ const char* config, bool ignoreErrors, bool);
+
+ ///! Get the name for the generator.
+ virtual const char* GetName() const {
+ return cmGlobalVisualStudio10Generator::GetActualName();}
+ static const char* GetActualName() {return "Visual Studio 10";}
+ virtual void AddPlatformDefinitions(cmMakefile* mf);
+
+ /** Get the documentation entry for this generator. */
+ virtual void GetDocumentation(cmDocumentationEntry& entry) const;
+
+ ///! create the correct local generator
+ virtual cmLocalGenerator *CreateLocalGenerator();
+
+ virtual void Generate();
+
+ /**
+ * Try to determine system infomation 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);
+
+ /** Is the installed VS an Express edition? */
+ bool IsExpressEdition() const { return this->ExpressEdition; }
+
+ /** The toolset name for the target platform. */
+ const char* GetPlatformToolset();
+
+ /**
+ * 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();
+
+ /**
+ * 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);
+
+ /** 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,
+ std::string const& sfRel);
+protected:
+ virtual const char* GetIDEVersion() { return "10.0"; }
+
+ std::string PlatformToolset;
+ bool ExpressEdition;
+
+ bool UseFolderProperty();
+
+private:
+ struct LongestSourcePath
+ {
+ LongestSourcePath(): Length(0), Target(0), SourceFile(0) {}
+ size_t Length;
+ cmTarget* Target;
+ cmSourceFile* SourceFile;
+ std::string SourceRel;
+ };
+ LongestSourcePath LongestSource;
+};
+#endif
diff --git a/Source/cmGlobalVisualStudio10IA64Generator.cxx b/Source/cmGlobalVisualStudio10IA64Generator.cxx
new file mode 100644
index 000000000..5f70f6bba
--- /dev/null
+++ b/Source/cmGlobalVisualStudio10IA64Generator.cxx
@@ -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.
+============================================================================*/
+#include "cmGlobalVisualStudio10IA64Generator.h"
+#include "cmMakefile.h"
+#include "cmake.h"
+
+//----------------------------------------------------------------------------
+cmGlobalVisualStudio10IA64Generator::cmGlobalVisualStudio10IA64Generator()
+{
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio10IA64Generator
+::GetDocumentation(cmDocumentationEntry& entry) const
+{
+ entry.Name = this->GetName();
+ entry.Brief = "Generates Visual Studio 10 Itanium project files.";
+ entry.Full = "";
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio10IA64Generator
+::AddPlatformDefinitions(cmMakefile* mf)
+{
+ this->cmGlobalVisualStudio10Generator::AddPlatformDefinitions(mf);
+ mf->AddDefinition("CMAKE_FORCE_IA64", "TRUE");
+ mf->AddDefinition("MSVC_C_ARCHITECTURE_ID", "x64");
+ mf->AddDefinition("MSVC_CXX_ARCHITECTURE_ID", "x64");
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio10IA64Generator
+::EnableLanguage(std::vector<std::string> const& languages,
+ cmMakefile* mf, bool optional)
+{
+ if(this->IsExpressEdition() && !this->Find64BitTools(mf))
+ {
+ return;
+ }
+ this->cmGlobalVisualStudio10Generator
+ ::EnableLanguage(languages, mf, optional);
+}
diff --git a/Source/cmGlobalVisualStudio10IA64Generator.h b/Source/cmGlobalVisualStudio10IA64Generator.h
new file mode 100644
index 000000000..a088272ef
--- /dev/null
+++ b/Source/cmGlobalVisualStudio10IA64Generator.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 cmGlobalVisualStudio10IA64Generator_h
+#define cmGlobalVisualStudio10IA64Generator_h
+
+#include "cmGlobalVisualStudio10Generator.h"
+
+class cmGlobalVisualStudio10IA64Generator :
+ public cmGlobalVisualStudio10Generator
+{
+public:
+ cmGlobalVisualStudio10IA64Generator();
+ static cmGlobalGenerator* New() {
+ return new cmGlobalVisualStudio10IA64Generator; }
+
+ ///! Get the name for the generator.
+ virtual const char* GetName() const {
+ return cmGlobalVisualStudio10IA64Generator::GetActualName();}
+ static const char* GetActualName() {return "Visual Studio 10 IA64";}
+
+ virtual const char* GetPlatformName() const {return "Itanium";}
+
+ /** Get the documentation entry for this generator. */
+ virtual void GetDocumentation(cmDocumentationEntry& entry) const;
+
+ virtual void AddPlatformDefinitions(cmMakefile* mf);
+
+ virtual void EnableLanguage(std::vector<std::string>const& languages,
+ cmMakefile *, bool optional);
+};
+#endif
diff --git a/Source/cmGlobalVisualStudio10Win64Generator.cxx b/Source/cmGlobalVisualStudio10Win64Generator.cxx
new file mode 100644
index 000000000..49dc47364
--- /dev/null
+++ b/Source/cmGlobalVisualStudio10Win64Generator.cxx
@@ -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.
+============================================================================*/
+#include "cmGlobalVisualStudio10Win64Generator.h"
+#include "cmMakefile.h"
+#include "cmake.h"
+
+//----------------------------------------------------------------------------
+cmGlobalVisualStudio10Win64Generator::cmGlobalVisualStudio10Win64Generator()
+{
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio10Win64Generator
+::GetDocumentation(cmDocumentationEntry& entry) const
+{
+ entry.Name = this->GetName();
+ entry.Brief = "Generates Visual Studio 10 Win64 project files.";
+ entry.Full = "";
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio10Win64Generator
+::AddPlatformDefinitions(cmMakefile* mf)
+{
+ this->cmGlobalVisualStudio10Generator::AddPlatformDefinitions(mf);
+ mf->AddDefinition("CMAKE_FORCE_WIN64", "TRUE");
+ mf->AddDefinition("MSVC_C_ARCHITECTURE_ID", "x64");
+ mf->AddDefinition("MSVC_CXX_ARCHITECTURE_ID", "x64");
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio10Win64Generator
+::EnableLanguage(std::vector<std::string> const& languages,
+ cmMakefile* mf, bool optional)
+{
+ if(this->IsExpressEdition() && !this->Find64BitTools(mf))
+ {
+ return;
+ }
+ this->cmGlobalVisualStudio10Generator
+ ::EnableLanguage(languages, mf, optional);
+}
diff --git a/Source/cmGlobalVisualStudio10Win64Generator.h b/Source/cmGlobalVisualStudio10Win64Generator.h
new file mode 100644
index 000000000..8a2de4c0a
--- /dev/null
+++ b/Source/cmGlobalVisualStudio10Win64Generator.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 cmGlobalVisualStudio10Win64Generator_h
+#define cmGlobalVisualStudio10Win64Generator_h
+
+#include "cmGlobalVisualStudio10Generator.h"
+
+class cmGlobalVisualStudio10Win64Generator :
+ public cmGlobalVisualStudio10Generator
+{
+public:
+ cmGlobalVisualStudio10Win64Generator();
+ static cmGlobalGenerator* New() {
+ return new cmGlobalVisualStudio10Win64Generator; }
+
+ ///! Get the name for the generator.
+ virtual const char* GetName() const {
+ return cmGlobalVisualStudio10Win64Generator::GetActualName();}
+ static const char* GetActualName() {return "Visual Studio 10 Win64";}
+
+ virtual const char* GetPlatformName() const {return "x64";}
+
+ /** Get the documentation entry for this generator. */
+ virtual void GetDocumentation(cmDocumentationEntry& entry) const;
+
+ virtual void AddPlatformDefinitions(cmMakefile* mf);
+
+ virtual void EnableLanguage(std::vector<std::string>const& languages,
+ cmMakefile *, bool optional);
+};
+#endif
diff --git a/Source/cmGlobalVisualStudio11ARMGenerator.cxx b/Source/cmGlobalVisualStudio11ARMGenerator.cxx
new file mode 100644
index 000000000..fef1aba61
--- /dev/null
+++ b/Source/cmGlobalVisualStudio11ARMGenerator.cxx
@@ -0,0 +1,32 @@
+/*============================================================================
+ 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.
+============================================================================*/
+#include "cmGlobalVisualStudio11ARMGenerator.h"
+#include "cmMakefile.h"
+#include "cmake.h"
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio11ARMGenerator
+::GetDocumentation(cmDocumentationEntry& entry) const
+{
+ entry.Name = this->GetName();
+ entry.Brief = "Generates Visual Studio 11 ARM project files.";
+ entry.Full = "";
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio11ARMGenerator
+::AddPlatformDefinitions(cmMakefile* mf)
+{
+ this->cmGlobalVisualStudio11Generator::AddPlatformDefinitions(mf);
+ mf->AddDefinition("MSVC_C_ARCHITECTURE_ID", "ARM");
+ mf->AddDefinition("MSVC_CXX_ARCHITECTURE_ID", "ARM");
+}
diff --git a/Source/cmGlobalVisualStudio11ARMGenerator.h b/Source/cmGlobalVisualStudio11ARMGenerator.h
new file mode 100644
index 000000000..77e142994
--- /dev/null
+++ b/Source/cmGlobalVisualStudio11ARMGenerator.h
@@ -0,0 +1,37 @@
+/*============================================================================
+ 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 cmGlobalVisualStudio11ARMGenerator_h
+#define cmGlobalVisualStudio11ARMGenerator_h
+
+#include "cmGlobalVisualStudio11Generator.h"
+
+class cmGlobalVisualStudio11ARMGenerator :
+ public cmGlobalVisualStudio11Generator
+{
+public:
+ cmGlobalVisualStudio11ARMGenerator() {}
+ static cmGlobalGenerator* New() {
+ return new cmGlobalVisualStudio11ARMGenerator; }
+
+ ///! Get the name for the generator.
+ virtual const char* GetName() const {
+ return cmGlobalVisualStudio11ARMGenerator::GetActualName();}
+ static const char* GetActualName() {return "Visual Studio 11 ARM";}
+
+ virtual const char* GetPlatformName() const {return "ARM";}
+
+ /** Get the documentation entry for this generator. */
+ virtual void GetDocumentation(cmDocumentationEntry& entry) const;
+
+ virtual void AddPlatformDefinitions(cmMakefile* mf);
+};
+#endif
diff --git a/Source/cmGlobalVisualStudio11Generator.cxx b/Source/cmGlobalVisualStudio11Generator.cxx
new file mode 100644
index 000000000..be7fd5572
--- /dev/null
+++ b/Source/cmGlobalVisualStudio11Generator.cxx
@@ -0,0 +1,56 @@
+/*============================================================================
+ 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.
+============================================================================*/
+#include "cmGlobalVisualStudio11Generator.h"
+#include "cmLocalVisualStudio10Generator.h"
+#include "cmMakefile.h"
+
+//----------------------------------------------------------------------------
+cmGlobalVisualStudio11Generator::cmGlobalVisualStudio11Generator()
+{
+ this->FindMakeProgramFile = "CMakeVS11FindMake.cmake";
+ this->ExpressEdition = false; // TODO: VS 11 Express support
+ this->PlatformToolset = "v110";
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio11Generator::AddPlatformDefinitions(cmMakefile* mf)
+{
+ mf->AddDefinition("MSVC11", "1");
+ mf->AddDefinition("MSVC_C_ARCHITECTURE_ID", "X86");
+ mf->AddDefinition("MSVC_CXX_ARCHITECTURE_ID", "X86");
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio11Generator::WriteSLNHeader(std::ostream& fout)
+{
+ fout << "Microsoft Visual Studio Solution File, Format Version 12.00\n";
+ fout << "# Visual Studio 11\n";
+}
+
+//----------------------------------------------------------------------------
+cmLocalGenerator *cmGlobalVisualStudio11Generator::CreateLocalGenerator()
+{
+ cmLocalVisualStudio10Generator* lg =
+ new cmLocalVisualStudio10Generator(cmLocalVisualStudioGenerator::VS11);
+ lg->SetPlatformName(this->GetPlatformName());
+ lg->SetGlobalGenerator(this);
+ return lg;
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio11Generator
+::GetDocumentation(cmDocumentationEntry& entry) const
+{
+ entry.Name = this->GetName();
+ entry.Brief = "Generates Visual Studio 11 project files.";
+ entry.Full = "";
+}
diff --git a/Source/cmGlobalVisualStudio11Generator.h b/Source/cmGlobalVisualStudio11Generator.h
new file mode 100644
index 000000000..7e8f6aa4e
--- /dev/null
+++ b/Source/cmGlobalVisualStudio11Generator.h
@@ -0,0 +1,46 @@
+/*============================================================================
+ 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 cmGlobalVisualStudio11Generator_h
+#define cmGlobalVisualStudio11Generator_h
+
+#include "cmGlobalVisualStudio10Generator.h"
+
+
+/** \class cmGlobalVisualStudio11Generator */
+class cmGlobalVisualStudio11Generator:
+ public cmGlobalVisualStudio10Generator
+{
+public:
+ cmGlobalVisualStudio11Generator();
+ static cmGlobalGenerator* New() {
+ return new cmGlobalVisualStudio11Generator; }
+
+ ///! Get the name for the generator.
+ virtual const char* GetName() const {
+ return cmGlobalVisualStudio11Generator::GetActualName();}
+ static const char* GetActualName() {return "Visual Studio 11";}
+ virtual void AddPlatformDefinitions(cmMakefile* mf);
+
+ virtual void WriteSLNHeader(std::ostream& fout);
+
+ /** Get the documentation entry for this generator. */
+ virtual void GetDocumentation(cmDocumentationEntry& entry) const;
+
+ ///! create the correct local generator
+ virtual cmLocalGenerator *CreateLocalGenerator();
+
+ /** TODO: VS 11 user macro support. */
+ virtual std::string GetUserMacrosDirectory() { return ""; }
+protected:
+ virtual const char* GetIDEVersion() { return "11.0"; }
+};
+#endif
diff --git a/Source/cmGlobalVisualStudio11Win64Generator.cxx b/Source/cmGlobalVisualStudio11Win64Generator.cxx
new file mode 100644
index 000000000..10c902753
--- /dev/null
+++ b/Source/cmGlobalVisualStudio11Win64Generator.cxx
@@ -0,0 +1,33 @@
+/*============================================================================
+ 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.
+============================================================================*/
+#include "cmGlobalVisualStudio11Win64Generator.h"
+#include "cmMakefile.h"
+#include "cmake.h"
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio11Win64Generator
+::GetDocumentation(cmDocumentationEntry& entry) const
+{
+ entry.Name = this->GetName();
+ entry.Brief = "Generates Visual Studio 11 Win64 project files.";
+ entry.Full = "";
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio11Win64Generator
+::AddPlatformDefinitions(cmMakefile* mf)
+{
+ this->cmGlobalVisualStudio11Generator::AddPlatformDefinitions(mf);
+ mf->AddDefinition("CMAKE_FORCE_WIN64", "TRUE");
+ mf->AddDefinition("MSVC_C_ARCHITECTURE_ID", "x64");
+ mf->AddDefinition("MSVC_CXX_ARCHITECTURE_ID", "x64");
+}
diff --git a/Source/cmGlobalVisualStudio11Win64Generator.h b/Source/cmGlobalVisualStudio11Win64Generator.h
new file mode 100644
index 000000000..53f19538c
--- /dev/null
+++ b/Source/cmGlobalVisualStudio11Win64Generator.h
@@ -0,0 +1,37 @@
+/*============================================================================
+ 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 cmGlobalVisualStudio11Win64Generator_h
+#define cmGlobalVisualStudio11Win64Generator_h
+
+#include "cmGlobalVisualStudio11Generator.h"
+
+class cmGlobalVisualStudio11Win64Generator :
+ public cmGlobalVisualStudio11Generator
+{
+public:
+ cmGlobalVisualStudio11Win64Generator() {}
+ static cmGlobalGenerator* New() {
+ return new cmGlobalVisualStudio11Win64Generator; }
+
+ ///! Get the name for the generator.
+ virtual const char* GetName() const {
+ return cmGlobalVisualStudio11Win64Generator::GetActualName();}
+ static const char* GetActualName() {return "Visual Studio 11 Win64";}
+
+ virtual const char* GetPlatformName() const {return "x64";}
+
+ /** Get the documentation entry for this generator. */
+ virtual void GetDocumentation(cmDocumentationEntry& entry) const;
+
+ virtual void AddPlatformDefinitions(cmMakefile* mf);
+};
+#endif
diff --git a/Source/cmGlobalVisualStudio6Generator.cxx b/Source/cmGlobalVisualStudio6Generator.cxx
new file mode 100644
index 000000000..fe44e200e
--- /dev/null
+++ b/Source/cmGlobalVisualStudio6Generator.cxx
@@ -0,0 +1,424 @@
+/*============================================================================
+ 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 "cmGlobalVisualStudio6Generator.h"
+#include "cmLocalVisualStudio6Generator.h"
+#include "cmMakefile.h"
+#include "cmake.h"
+#include "cmGeneratedFileStream.h"
+
+// Utility function to make a valid VS6 *.dsp filename out
+// of a CMake target name:
+//
+std::string GetVS6TargetName(const std::string& targetName)
+{
+ std::string name(targetName);
+
+ // Eliminate hyphens. VS6 cannot handle hyphens in *.dsp filenames...
+ // Replace them with underscores.
+ //
+ cmSystemTools::ReplaceString(name, "-", "_");
+
+ return name;
+}
+
+cmGlobalVisualStudio6Generator::cmGlobalVisualStudio6Generator()
+{
+ this->FindMakeProgramFile = "CMakeVS6FindMake.cmake";
+}
+
+void cmGlobalVisualStudio6Generator
+::EnableLanguage(std::vector<std::string>const& lang,
+ cmMakefile *mf,
+ bool optional)
+{
+ mf->AddDefinition("CMAKE_GENERATOR_CC", "cl");
+ mf->AddDefinition("CMAKE_GENERATOR_CXX", "cl");
+ mf->AddDefinition("CMAKE_GENERATOR_RC", "rc");
+ mf->AddDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV", "1");
+ mf->AddDefinition("CMAKE_GENERATOR_Fortran", "ifort");
+ mf->AddDefinition("MSVC_C_ARCHITECTURE_ID", "X86");
+ mf->AddDefinition("MSVC_CXX_ARCHITECTURE_ID", "X86");
+ mf->AddDefinition("MSVC60", "1");
+ this->GenerateConfigurations(mf);
+ this->cmGlobalGenerator::EnableLanguage(lang, mf, optional);
+}
+
+void cmGlobalVisualStudio6Generator::GenerateConfigurations(cmMakefile* mf)
+{
+ std::string fname= mf->GetRequiredDefinition("CMAKE_ROOT");
+ const char* def= mf->GetDefinition( "MSPROJECT_TEMPLATE_DIRECTORY");
+ if(def)
+ {
+ fname = def;
+ }
+ else
+ {
+ fname += "/Templates";
+ }
+ fname += "/CMakeVisualStudio6Configurations.cmake";
+ if(!mf->ReadListFile(mf->GetCurrentListFile(), fname.c_str()))
+ {
+ cmSystemTools::Error("Cannot open ", fname.c_str(),
+ ". Please copy this file from the main "
+ "CMake/Templates directory and edit it for "
+ "your build configurations.");
+ }
+ else if(!mf->GetDefinition("CMAKE_CONFIGURATION_TYPES"))
+ {
+ cmSystemTools::Error("CMAKE_CONFIGURATION_TYPES not set by ",
+ fname.c_str(),
+ ". Please copy this file from the main "
+ "CMake/Templates directory and edit it for "
+ "your build configurations.");
+ }
+}
+
+std::string cmGlobalVisualStudio6Generator
+::GenerateBuildCommand(const char* makeProgram,
+ const char *projectName,
+ const char* additionalOptions,
+ const char *targetName,
+ const char* config,
+ bool ignoreErrors,
+ bool)
+{
+ // Ingoring errors is not implemented in visual studio 6
+ (void) ignoreErrors;
+
+ // 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 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 "";
+ }
+ makeCommand = cmSystemTools::ConvertToOutputPath(makeCommand.c_str());
+
+ // 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)
+ {
+ cmSystemTools::GetShortPath(makeCommand.c_str(), makeCommand);
+ }
+#endif
+ makeCommand += " ";
+ makeCommand += projectName;
+ makeCommand += ".dsw /MAKE \"";
+ bool clean = false;
+ if ( targetName && strcmp(targetName, "clean") == 0 )
+ {
+ clean = true;
+ targetName = "ALL_BUILD";
+ }
+ if (targetName && strlen(targetName))
+ {
+ makeCommand += targetName;
+ }
+ else
+ {
+ makeCommand += "ALL_BUILD";
+ }
+ makeCommand += " - ";
+ if(config && strlen(config))
+ {
+ makeCommand += config;
+ }
+ else
+ {
+ makeCommand += "Debug";
+ }
+ if(clean)
+ {
+ makeCommand += "\" /CLEAN";
+ }
+ else
+ {
+ makeCommand += "\" /BUILD";
+ }
+ if ( additionalOptions )
+ {
+ makeCommand += " ";
+ makeCommand += additionalOptions;
+ }
+ return makeCommand;
+}
+
+///! Create a local generator appropriate to this Global Generator
+cmLocalGenerator *cmGlobalVisualStudio6Generator::CreateLocalGenerator()
+{
+ cmLocalGenerator *lg = new cmLocalVisualStudio6Generator;
+ lg->SetGlobalGenerator(this);
+ return lg;
+}
+
+
+void cmGlobalVisualStudio6Generator::Generate()
+{
+ // first do the superclass method
+ this->cmGlobalVisualStudioGenerator::Generate();
+
+ // Now write out the DSW
+ this->OutputDSWFile();
+}
+
+// Write a DSW file to the stream
+void cmGlobalVisualStudio6Generator
+::WriteDSWFile(std::ostream& fout,cmLocalGenerator* root,
+ std::vector<cmLocalGenerator*>& generators)
+{
+ // Write out the header for a DSW file
+ this->WriteDSWHeader(fout);
+
+ // Collect all targets under this root generator and the transitive
+ // closure of their dependencies.
+ TargetDependSet projectTargets;
+ TargetDependSet originalTargets;
+ this->GetTargetSets(projectTargets, originalTargets, root, generators);
+ OrderedTargetDependSet orderedProjectTargets(projectTargets);
+
+ for(OrderedTargetDependSet::const_iterator
+ tt = orderedProjectTargets.begin();
+ tt != orderedProjectTargets.end(); ++tt)
+ {
+ cmTarget* target = *tt;
+ cmMakefile* mf = target->GetMakefile();
+ // Write the project into the DSW file
+ const char* expath = target->GetProperty("EXTERNAL_MSPROJECT");
+ if(expath)
+ {
+ std::string project = target->GetName();
+ std::string location = expath;
+ this->WriteExternalProject(fout, project.c_str(),
+ location.c_str(), target->GetUtilities());
+ }
+ else
+ {
+ std::string dspname = GetVS6TargetName(target->GetName());
+ std::string dir = target->GetMakefile()->GetStartOutputDirectory();
+ dir = root->Convert(dir.c_str(), cmLocalGenerator::START_OUTPUT);
+ this->WriteProject(fout, dspname.c_str(), dir.c_str(), *target);
+ }
+ }
+
+ // Write the footer for the DSW file
+ this->WriteDSWFooter(fout);
+}
+
+void cmGlobalVisualStudio6Generator
+::OutputDSWFile(cmLocalGenerator* root,
+ std::vector<cmLocalGenerator*>& generators)
+{
+ if(generators.size() == 0)
+ {
+ return;
+ }
+ std::string fname = root->GetMakefile()->GetStartOutputDirectory();
+ fname += "/";
+ fname += root->GetMakefile()->GetProjectName();
+ fname += ".dsw";
+ std::ofstream fout(fname.c_str());
+ if(!fout)
+ {
+ cmSystemTools::Error("Error can not open DSW file for write: ",
+ fname.c_str());
+ cmSystemTools::ReportLastSystemError("");
+ return;
+ }
+ this->WriteDSWFile(fout, root, generators);
+}
+
+// output the DSW file
+void cmGlobalVisualStudio6Generator::OutputDSWFile()
+{
+ std::map<cmStdString, std::vector<cmLocalGenerator*> >::iterator it;
+ for(it = this->ProjectMap.begin(); it!= this->ProjectMap.end(); ++it)
+ {
+ this->OutputDSWFile(it->second[0], it->second);
+ }
+}
+
+// Write a dsp file into the DSW file,
+// 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)
+{
+ fout << "#########################################################"
+ "######################\n\n";
+ fout << "Project: \"" << dspname << "\"="
+ << dir << "\\" << dspname << ".dsp - Package Owner=<4>\n\n";
+ fout << "Package=<5>\n{{{\n}}}\n\n";
+ fout << "Package=<4>\n";
+ fout << "{{{\n";
+ VSDependSet const& depends = this->VSTargetDepends[&target];
+ for(VSDependSet::const_iterator di = depends.begin();
+ di != depends.end(); ++di)
+ {
+ const char* name = di->c_str();
+ fout << "Begin Project Dependency\n";
+ fout << "Project_Dep_Name " << GetVS6TargetName(name) << "\n";
+ fout << "End Project Dependency\n";
+ }
+ fout << "}}}\n\n";
+
+ UtilityDependsMap::iterator ui = this->UtilityDepends.find(&target);
+ if(ui != this->UtilityDepends.end())
+ {
+ const char* uname = ui->second.c_str();
+ fout << "Project: \"" << uname << "\"="
+ << dir << "\\" << uname << ".dsp - Package Owner=<4>\n\n";
+ fout <<
+ "Package=<5>\n{{{\n}}}\n\n"
+ "Package=<4>\n"
+ "{{{\n"
+ "Begin Project Dependency\n"
+ "Project_Dep_Name " << dspname << "\n"
+ "End Project Dependency\n"
+ "}}}\n\n";
+ ;
+ }
+}
+
+
+// Write a dsp file into the DSW file,
+// Note, that dependencies from executables to
+// the libraries it uses are also done here
+void cmGlobalVisualStudio6Generator::WriteExternalProject(std::ostream& fout,
+ const char* name,
+ const char* location,
+ const std::set<cmStdString>& dependencies)
+{
+ fout << "#########################################################"
+ "######################\n\n";
+ fout << "Project: \"" << name << "\"="
+ << location << " - Package Owner=<4>\n\n";
+ fout << "Package=<5>\n{{{\n}}}\n\n";
+ fout << "Package=<4>\n";
+ fout << "{{{\n";
+
+
+ std::set<cmStdString>::const_iterator i, end;
+ // write dependencies.
+ i = dependencies.begin();
+ end = dependencies.end();
+ for(;i!= end; ++i)
+ {
+ fout << "Begin Project Dependency\n";
+ fout << "Project_Dep_Name " << GetVS6TargetName(*i) << "\n";
+ fout << "End Project Dependency\n";
+ }
+ fout << "}}}\n\n";
+}
+
+
+
+// Standard end of dsw file
+void cmGlobalVisualStudio6Generator::WriteDSWFooter(std::ostream& fout)
+{
+ fout << "######################################################"
+ "#########################\n\n";
+ fout << "Global:\n\n";
+ fout << "Package=<5>\n{{{\n}}}\n\n";
+ fout << "Package=<3>\n{{{\n}}}\n\n";
+ fout << "#####################################################"
+ "##########################\n\n";
+}
+
+
+// ouput standard header for dsw file
+void cmGlobalVisualStudio6Generator::WriteDSWHeader(std::ostream& fout)
+{
+ fout << "Microsoft Developer Studio Workspace File, Format Version 6.00\n";
+ fout << "# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\n\n";
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmGlobalVisualStudio6Generator::WriteUtilityDepend(cmTarget* target)
+{
+ std::string pname = target->GetName();
+ pname += "_UTILITY";
+ pname = GetVS6TargetName(pname.c_str());
+ std::string fname = target->GetMakefile()->GetStartOutputDirectory();
+ fname += "/";
+ fname += pname;
+ fname += ".dsp";
+ cmGeneratedFileStream fout(fname.c_str());
+ fout.SetCopyIfDifferent(true);
+ fout <<
+ "# Microsoft Developer Studio Project File - Name=\""
+ << pname << "\" - Package Owner=<4>\n"
+ "# Microsoft Developer Studio Generated Build File, Format Version 6.00\n"
+ "# ** DO NOT EDIT **\n"
+ "\n"
+ "# TARGTYPE \"Win32 (x86) Generic Project\" 0x010a\n"
+ "\n"
+ "CFG=" << pname << " - Win32 Debug\n"
+ "!MESSAGE \"" << pname << " - Win32 Debug\""
+ " (based on \"Win32 (x86) Generic Project\")\n"
+ "!MESSAGE \"" << pname << " - Win32 Release\" "
+ "(based on \"Win32 (x86) Generic Project\")\n"
+ "!MESSAGE \"" << pname << " - Win32 MinSizeRel\" "
+ "(based on \"Win32 (x86) Generic Project\")\n"
+ "!MESSAGE \"" << pname << " - Win32 RelWithDebInfo\" "
+ "(based on \"Win32 (x86) Generic Project\")\n"
+ "\n"
+ "# Begin Project\n"
+ "# Begin Target\n"
+ "# Name \"" << pname << " - Win32 Debug\"\n"
+ "# Name \"" << pname << " - Win32 Release\"\n"
+ "# Name \"" << pname << " - Win32 MinSizeRel\"\n"
+ "# Name \"" << pname << " - Win32 RelWithDebInfo\"\n"
+ "# End Target\n"
+ "# End Project\n"
+ ;
+ return pname;
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio6Generator
+::GetDocumentation(cmDocumentationEntry& entry) const
+{
+ entry.Name = this->GetName();
+ entry.Brief = "Generates Visual Studio 6 project files.";
+ entry.Full = "";
+}
+
+//----------------------------------------------------------------------------
+void
+cmGlobalVisualStudio6Generator
+::AppendDirectoryForConfig(const char* prefix,
+ const char* config,
+ const char* suffix,
+ std::string& dir)
+{
+ if(config)
+ {
+ dir += prefix;
+ dir += config;
+ dir += suffix;
+ }
+}
diff --git a/Source/cmGlobalVisualStudio6Generator.h b/Source/cmGlobalVisualStudio6Generator.h
new file mode 100644
index 000000000..da08a125b
--- /dev/null
+++ b/Source/cmGlobalVisualStudio6Generator.h
@@ -0,0 +1,102 @@
+/*============================================================================
+ 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 cmGlobalVisualStudio6Generator_h
+#define cmGlobalVisualStudio6Generator_h
+
+#include "cmGlobalVisualStudioGenerator.h"
+
+class cmTarget;
+
+/** \class cmGlobalVisualStudio6Generator
+ * \brief Write a Unix makefiles.
+ *
+ * cmGlobalVisualStudio6Generator manages UNIX build process for a tree
+ */
+class cmGlobalVisualStudio6Generator : public cmGlobalVisualStudioGenerator
+{
+public:
+ cmGlobalVisualStudio6Generator();
+ static cmGlobalGenerator* New() {
+ return new cmGlobalVisualStudio6Generator; }
+
+ ///! Get the name for the generator.
+ virtual const char* GetName() const {
+ return cmGlobalVisualStudio6Generator::GetActualName();}
+ static const char* GetActualName() {return "Visual Studio 6";}
+
+ /** Get the documentation entry for this generator. */
+ virtual void GetDocumentation(cmDocumentationEntry& entry) const;
+
+ ///! Create a local generator appropriate to this Global Generator
+ virtual cmLocalGenerator *CreateLocalGenerator();
+
+ /**
+ * Try to determine system infomation such as shared library
+ * extension, pthreads, byte order etc.
+ */
+ virtual void EnableLanguage(std::vector<std::string>const& languages,
+ cmMakefile *, bool optional);
+
+ /**
+ * 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* 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();
+
+ /**
+ * Generate the DSW workspace file.
+ */
+ virtual void OutputDSWFile();
+ virtual void OutputDSWFile(cmLocalGenerator* root,
+ std::vector<cmLocalGenerator*>& generators);
+ virtual void WriteDSWFile(std::ostream& fout,
+ cmLocalGenerator* root,
+ std::vector<cmLocalGenerator*>& generators);
+
+ /** Append the subdirectory for the given configuration. */
+ virtual void AppendDirectoryForConfig(const char* prefix,
+ const char* config,
+ const char* suffix,
+ std::string& dir);
+
+ ///! What is the configurations directory variable called?
+ virtual const char* GetCMakeCFGIntDir() const { return "$(IntDir)"; }
+
+protected:
+ virtual const char* GetIDEVersion() { return "6.0"; }
+private:
+ 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);
+ void WriteExternalProject(std::ostream& fout,
+ const char* name, const char* path,
+ const std::set<cmStdString>& dependencies);
+ void WriteDSWFooter(std::ostream& fout);
+ virtual std::string WriteUtilityDepend(cmTarget* target);
+};
+
+#endif
diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx
new file mode 100644
index 000000000..d6b653ca6
--- /dev/null
+++ b/Source/cmGlobalVisualStudio71Generator.cxx
@@ -0,0 +1,329 @@
+/*============================================================================
+ 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 "windows.h" // this must be first to define GetCurrentDirectory
+#include "cmGlobalVisualStudio71Generator.h"
+#include "cmLocalVisualStudio7Generator.h"
+#include "cmMakefile.h"
+#include "cmake.h"
+
+//----------------------------------------------------------------------------
+cmGlobalVisualStudio71Generator::cmGlobalVisualStudio71Generator()
+{
+ 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;
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio71Generator::AddPlatformDefinitions(cmMakefile* mf)
+{
+ this->cmGlobalVisualStudio7Generator::AddPlatformDefinitions(mf);
+ mf->RemoveDefinition("MSVC70");
+ mf->AddDefinition("MSVC71", "1");
+}
+
+//----------------------------------------------------------------------------
+std::string cmGlobalVisualStudio71Generator::GetUserMacrosDirectory()
+{
+ // Macros not supported on Visual Studio 7.1 and earlier because
+ // they do not appear to work *during* a build when called by an
+ // outside agent...
+ //
+ return "";
+
+#if 0
+ //
+ // The COM result from calling a Visual Studio macro with 7.1 indicates
+ // that the call succeeds, but the macro does not appear to execute...
+ //
+ // So, I am leaving this code here to show how to do it, but have not
+ // yet figured out what the issue is in terms of why the macro does not
+ // appear to execute...
+ //
+ std::string base;
+ std::string path;
+
+ // base begins with the VisualStudioProjectsLocation reg value...
+ if (cmSystemTools::ReadRegistryValue(
+ "HKEY_CURRENT_USER\\Software\\Microsoft\\VisualStudio\\7.1;"
+ "VisualStudioProjectsLocation",
+ base))
+ {
+ cmSystemTools::ConvertToUnixSlashes(base);
+
+ // 7.1 macros folder:
+ path = base + "/VSMacros71";
+ }
+
+ // path is (correctly) still empty if we did not read the base value from
+ // the Registry value
+ return path;
+#endif
+}
+
+//----------------------------------------------------------------------------
+std::string cmGlobalVisualStudio71Generator::GetUserMacrosRegKeyBase()
+{
+ // Macros not supported on Visual Studio 7.1 and earlier because
+ // they do not appear to work *during* a build when called by an
+ // outside agent...
+ //
+ return "";
+
+#if 0
+ return "Software\\Microsoft\\VisualStudio\\7.1\\vsmacros";
+#endif
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio71Generator
+::WriteSLNFile(std::ostream& fout,
+ cmLocalGenerator* root,
+ std::vector<cmLocalGenerator*>& generators)
+{
+ // Write out the header for a SLN file
+ this->WriteSLNHeader(fout);
+
+ // Collect all targets under this root generator and the transitive
+ // closure of their dependencies.
+ TargetDependSet projectTargets;
+ TargetDependSet originalTargets;
+ this->GetTargetSets(projectTargets, originalTargets, root, generators);
+ OrderedTargetDependSet orderedProjectTargets(projectTargets);
+
+ this->WriteTargetsToSolution(fout, root, orderedProjectTargets);
+
+ bool useFolderProperty = this->UseFolderProperty();
+ if (useFolderProperty)
+ {
+ this->WriteFolders(fout);
+ }
+
+ // Write out the configurations information for the solution
+ fout << "Global\n";
+ // Write out the configurations for the solution
+ this->WriteSolutionConfigurations(fout);
+ fout << "\tGlobalSection(" << this->ProjectConfigurationSectionName
+ << ") = postSolution\n";
+ // Write out the configurations for all the targets in the project
+ this->WriteTargetConfigurations(fout, root, orderedProjectTargets);
+ fout << "\tEndGlobalSection\n";
+
+ if (useFolderProperty)
+ {
+ // Write out project folders
+ fout << "\tGlobalSection(NestedProjects) = preSolution\n";
+ this->WriteFoldersContent(fout);
+ fout << "\tEndGlobalSection\n";
+ }
+
+ // Write the footer for the SLN file
+ this->WriteSLNFooter(fout);
+}
+
+//----------------------------------------------------------------------------
+void
+cmGlobalVisualStudio71Generator
+::WriteSolutionConfigurations(std::ostream& fout)
+{
+ fout << "\tGlobalSection(SolutionConfiguration) = preSolution\n";
+ for(std::vector<std::string>::iterator i = this->Configurations.begin();
+ i != this->Configurations.end(); ++i)
+ {
+ fout << "\t\t" << *i << " = " << *i << "\n";
+ }
+ fout << "\tEndGlobalSection\n";
+}
+
+//----------------------------------------------------------------------------
+// Write a dsp file into the SLN file,
+// Note, that dependencies from executables to
+// the libraries it uses are also done here
+void
+cmGlobalVisualStudio71Generator::WriteProject(std::ostream& fout,
+ const char* dspname,
+ const char* dir,
+ cmTarget& t)
+{
+ // check to see if this is a fortran build
+ const char* ext = ".vcproj";
+ const char* project =
+ "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"";
+ if(this->TargetIsFortranOnly(t))
+ {
+ ext = ".vfproj";
+ project = "Project(\"{6989167D-11E4-40FE-8C1A-2192A86A7E90}\") = \"";
+ }
+ const char* targetExt = t.GetProperty("GENERATOR_FILE_NAME_EXT");
+ if(targetExt)
+ {
+ ext = targetExt;
+ }
+
+ std::string guid = this->GetGUID(dspname);
+ fout << project
+ << dspname << "\", \""
+ << this->ConvertToSolutionPath(dir) << (dir[0]? "\\":"")
+ << dspname << ext << "\", \"{" << guid << "}\"\n";
+ fout << "\tProjectSection(ProjectDependencies) = postProject\n";
+ this->WriteProjectDepends(fout, dspname, dir, t);
+ fout << "\tEndProjectSection\n";
+
+ fout <<"EndProject\n";
+
+ UtilityDependsMap::iterator ui = this->UtilityDepends.find(&t);
+ if(ui != this->UtilityDepends.end())
+ {
+ const char* uname = ui->second.c_str();
+ fout << "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \""
+ << uname << "\", \""
+ << this->ConvertToSolutionPath(dir) << (dir[0]? "\\":"")
+ << uname << ".vcproj" << "\", \"{"
+ << this->GetGUID(uname) << "}\"\n"
+ << "\tProjectSection(ProjectDependencies) = postProject\n"
+ << "\t\t{" << guid << "} = {" << guid << "}\n"
+ << "\tEndProjectSection\n"
+ << "EndProject\n";
+ }
+}
+
+//----------------------------------------------------------------------------
+// Write a dsp file into the SLN file,
+// Note, that dependencies from executables to
+// the libraries it uses are also done here
+void
+cmGlobalVisualStudio71Generator
+::WriteProjectDepends(std::ostream& fout,
+ const char*,
+ const char*, cmTarget& 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)
+ {
+ std::string m = "Target: ";
+ m += target.GetName();
+ m += " depends on unknown target: ";
+ m += name;
+ cmSystemTools::Error(m.c_str());
+ }
+ fout << "\t\t{" << guid << "} = {" << guid << "}\n";
+ }
+}
+
+//----------------------------------------------------------------------------
+// Write a dsp file into the SLN file, Note, that dependencies from
+// executables to the libraries it uses are also done here
+void cmGlobalVisualStudio71Generator
+::WriteExternalProject(std::ostream& fout,
+ const char* name,
+ const char* location,
+ const char* typeGuid,
+ const std::set<cmStdString>& depends)
+{
+ fout << "Project(\"{"
+ << (typeGuid ? typeGuid : "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942")
+ << "}\") = \""
+ << name << "\", \""
+ << this->ConvertToSolutionPath(location) << "\", \"{"
+ << this->GetGUID(name)
+ << "}\"\n";
+
+ // write out the dependencies here VS 7.1 includes dependencies with the
+ // project instead of in the global section
+ if(!depends.empty())
+ {
+ fout << "\tProjectSection(ProjectDependencies) = postProject\n";
+ std::set<cmStdString>::const_iterator it;
+ for(it = depends.begin(); it != depends.end(); ++it)
+ {
+ if(it->size() > 0)
+ {
+ fout << "\t\t{"
+ << this->GetGUID(it->c_str())
+ << "} = {"
+ << this->GetGUID(it->c_str())
+ << "}\n";
+ }
+ }
+ fout << "\tEndProjectSection\n";
+ }
+
+ fout << "EndProject\n";
+
+
+}
+
+//----------------------------------------------------------------------------
+// Write a dsp file into the SLN file, Note, that dependencies from
+// executables to the libraries it uses are also done here
+void cmGlobalVisualStudio71Generator
+::WriteProjectConfigurations(std::ostream& fout, const char* name,
+ bool partOfDefaultBuild,
+ const char* platformMapping)
+{
+ std::string guid = this->GetGUID(name);
+ for(std::vector<std::string>::iterator i = this->Configurations.begin();
+ i != this->Configurations.end(); ++i)
+ {
+ fout << "\t\t{" << guid << "}." << *i
+ << ".ActiveCfg = " << *i << "|"
+ << (platformMapping ? platformMapping : "Win32") << std::endl;
+ if(partOfDefaultBuild)
+ {
+ fout << "\t\t{" << guid << "}." << *i
+ << ".Build.0 = " << *i << "|"
+ << (platformMapping ? platformMapping : "Win32") << std::endl;
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+// Standard end of dsw file
+void cmGlobalVisualStudio71Generator::WriteSLNFooter(std::ostream& fout)
+{
+ fout << "\tGlobalSection(ExtensibilityGlobals) = postSolution\n"
+ << "\tEndGlobalSection\n"
+ << "\tGlobalSection(ExtensibilityAddIns) = postSolution\n"
+ << "\tEndGlobalSection\n"
+ << "EndGlobal\n";
+}
+
+//----------------------------------------------------------------------------
+// ouput standard header for dsw file
+void cmGlobalVisualStudio71Generator::WriteSLNHeader(std::ostream& fout)
+{
+ fout << "Microsoft Visual Studio Solution File, Format Version 8.00\n";
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio71Generator
+::GetDocumentation(cmDocumentationEntry& entry) const
+{
+ entry.Name = this->GetName();
+ entry.Brief = "Generates Visual Studio .NET 2003 project files.";
+ entry.Full = "";
+}
diff --git a/Source/cmGlobalVisualStudio71Generator.h b/Source/cmGlobalVisualStudio71Generator.h
new file mode 100644
index 000000000..503b708e5
--- /dev/null
+++ b/Source/cmGlobalVisualStudio71Generator.h
@@ -0,0 +1,79 @@
+/*============================================================================
+ 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 cmGlobalVisualStudio71Generator_h
+#define cmGlobalVisualStudio71Generator_h
+
+#include "cmGlobalVisualStudio7Generator.h"
+
+
+/** \class cmGlobalVisualStudio71Generator
+ * \brief Write a Unix makefiles.
+ *
+ * cmGlobalVisualStudio71Generator manages UNIX build process for a tree
+ */
+class cmGlobalVisualStudio71Generator : public cmGlobalVisualStudio7Generator
+{
+public:
+ cmGlobalVisualStudio71Generator();
+ static cmGlobalGenerator* New()
+ { return new cmGlobalVisualStudio71Generator; }
+
+ ///! Get the name for the generator.
+ virtual const char* GetName() const {
+ return cmGlobalVisualStudio71Generator::GetActualName();}
+ static const char* GetActualName() {return "Visual Studio 7 .NET 2003";}
+
+ /** Get the documentation entry for this generator. */
+ virtual void GetDocumentation(cmDocumentationEntry& entry) const;
+
+ ///! 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
+ * Studio does not implement support for VB macros.
+ */
+ virtual std::string GetUserMacrosDirectory();
+
+ /**
+ * What is the reg key path to "vsmacros" for this version of Visual
+ * Studio?
+ */
+ virtual std::string GetUserMacrosRegKeyBase();
+
+protected:
+ virtual const char* GetIDEVersion() { return "7.1"; }
+ virtual void AddPlatformDefinitions(cmMakefile* mf);
+ virtual void WriteSLNFile(std::ostream& fout,
+ cmLocalGenerator* root,
+ std::vector<cmLocalGenerator*>& generators);
+ virtual void WriteSolutionConfigurations(std::ostream& fout);
+ virtual void WriteProject(std::ostream& fout,
+ const char* name, const char* path, cmTarget &t);
+ virtual void WriteProjectDepends(std::ostream& fout,
+ const char* name, const char* path, cmTarget &t);
+ virtual void WriteProjectConfigurations(std::ostream& fout,
+ const char* name,
+ bool partOfDefaultBuild,
+ const char* platformMapping = NULL);
+ virtual void WriteExternalProject(std::ostream& fout,
+ const char* name,
+ const char* path,
+ const char* typeGuid,
+ const std::set<cmStdString>& depends);
+ virtual void WriteSLNFooter(std::ostream& fout);
+ virtual void WriteSLNHeader(std::ostream& fout);
+
+ std::string ProjectConfigurationSectionName;
+};
+#endif
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
new file mode 100644
index 000000000..6332d0b10
--- /dev/null
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -0,0 +1,821 @@
+/*============================================================================
+ 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 "windows.h" // this must be first to define GetCurrentDirectory
+#include "cmGlobalVisualStudio7Generator.h"
+#include "cmGeneratedFileStream.h"
+#include "cmLocalVisualStudio7Generator.h"
+#include "cmMakefile.h"
+#include "cmake.h"
+
+cmGlobalVisualStudio7Generator::cmGlobalVisualStudio7Generator()
+{
+ this->FindMakeProgramFile = "CMakeVS7FindMake.cmake";
+}
+
+
+void cmGlobalVisualStudio7Generator
+::EnableLanguage(std::vector<std::string>const & lang,
+ cmMakefile *mf, bool optional)
+{
+ mf->AddDefinition("CMAKE_GENERATOR_CC", "cl");
+ mf->AddDefinition("CMAKE_GENERATOR_CXX", "cl");
+ mf->AddDefinition("CMAKE_GENERATOR_RC", "rc");
+ mf->AddDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV", "1");
+ mf->AddDefinition("CMAKE_GENERATOR_FC", "ifort");
+ this->AddPlatformDefinitions(mf);
+
+ // 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
+ // cmLocalGenerator::ConstructScript, to add an extra PATH
+ // to all custom commands. This is because the VS IDE
+ // does not use the environment it is run in, and this allows
+ // for running commands and using dll's that the IDE environment
+ // does not know about.
+ const char* extraPath = cmSystemTools::GetEnv("CMAKE_MSVCIDE_RUN_PATH");
+ if(extraPath)
+ {
+ mf->AddCacheDefinition
+ ("CMAKE_MSVCIDE_RUN_PATH", extraPath,
+ "Saved environment variable CMAKE_MSVCIDE_RUN_PATH",
+ cmCacheManager::STATIC);
+ }
+
+}
+
+void cmGlobalVisualStudio7Generator::AddPlatformDefinitions(cmMakefile* mf)
+{
+ mf->AddDefinition("MSVC70", "1");
+ mf->AddDefinition("MSVC_C_ARCHITECTURE_ID", "X86");
+ mf->AddDefinition("MSVC_CXX_ARCHITECTURE_ID", "X86");
+}
+
+std::string cmGlobalVisualStudio7Generator
+::GenerateBuildCommand(const char* makeProgram,
+ const char *projectName,
+ const char* additionalOptions, const char *targetName,
+ const char* config, bool ignoreErrors, bool)
+{
+ // Ingoring errors is not implemented in visual studio 6
+ (void) ignoreErrors;
+
+ // now build the test
+ std::string makeCommand =
+ cmSystemTools::ConvertToOutputPath(makeProgram);
+ std::string lowerCaseCommand = makeCommand;
+ cmSystemTools::LowerCase(lowerCaseCommand);
+
+ // 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)
+ {
+ cmSystemTools::GetShortPath(makeCommand.c_str(), makeCommand);
+ }
+#endif
+ makeCommand += " ";
+ makeCommand += projectName;
+ makeCommand += ".sln ";
+ bool clean = false;
+ if ( targetName && strcmp(targetName, "clean") == 0 )
+ {
+ clean = true;
+ targetName = "ALL_BUILD";
+ }
+ if(clean)
+ {
+ makeCommand += "/clean ";
+ }
+ else
+ {
+ makeCommand += "/build ";
+ }
+
+ if(config && strlen(config))
+ {
+ makeCommand += config;
+ }
+ else
+ {
+ makeCommand += "Debug";
+ }
+ makeCommand += " /project ";
+
+ if (targetName && strlen(targetName))
+ {
+ makeCommand += targetName;
+ }
+ else
+ {
+ makeCommand += "ALL_BUILD";
+ }
+ if ( additionalOptions )
+ {
+ makeCommand += " ";
+ makeCommand += additionalOptions;
+ }
+ return makeCommand;
+}
+
+///! Create a local generator appropriate to this Global Generator
+cmLocalGenerator *cmGlobalVisualStudio7Generator::CreateLocalGenerator()
+{
+ cmLocalVisualStudio7Generator *lg =
+ new cmLocalVisualStudio7Generator(cmLocalVisualStudioGenerator::VS7);
+ lg->SetExtraFlagTable(this->GetExtraFlagTableVS7());
+ lg->SetGlobalGenerator(this);
+ return lg;
+}
+
+void cmGlobalVisualStudio7Generator::GenerateConfigurations(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)
+ {
+ this->Configurations.push_back("Debug");
+ this->Configurations.push_back("Release");
+ }
+
+ // 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)
+ {
+ configs += ";";
+ configs += this->Configurations[i];
+ }
+
+ 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);
+}
+
+void cmGlobalVisualStudio7Generator::Generate()
+{
+ // first do the superclass method
+ this->cmGlobalVisualStudioGenerator::Generate();
+
+ // Now write out the DSW
+ this->OutputSLNFile();
+ // If any solution or project files changed during the generation,
+ // tell Visual Studio to reload them...
+ if(!cmSystemTools::GetErrorOccuredFlag())
+ {
+ this->CallVisualStudioMacro(MacroReload);
+ }
+}
+
+void cmGlobalVisualStudio7Generator
+::OutputSLNFile(cmLocalGenerator* root,
+ std::vector<cmLocalGenerator*>& generators)
+{
+ if(generators.size() == 0)
+ {
+ return;
+ }
+ this->CurrentProject = root->GetMakefile()->GetProjectName();
+ std::string fname = root->GetMakefile()->GetStartOutputDirectory();
+ fname += "/";
+ fname += root->GetMakefile()->GetProjectName();
+ fname += ".sln";
+ cmGeneratedFileStream fout(fname.c_str());
+ fout.SetCopyIfDifferent(true);
+ if(!fout)
+ {
+ return;
+ }
+ this->WriteSLNFile(fout, root, generators);
+ if (fout.Close())
+ {
+ this->FileReplacedDuringGenerate(fname);
+ }
+}
+
+// output the SLN file
+void cmGlobalVisualStudio7Generator::OutputSLNFile()
+{
+ std::map<cmStdString, std::vector<cmLocalGenerator*> >::iterator it;
+ for(it = this->ProjectMap.begin(); it!= this->ProjectMap.end(); ++it)
+ {
+ this->OutputSLNFile(it->second[0], it->second);
+ }
+}
+
+
+void cmGlobalVisualStudio7Generator::WriteTargetConfigurations(
+ std::ostream& fout,
+ cmLocalGenerator* root,
+ OrderedTargetDependSet const& projectTargets)
+{
+ // loop over again and write out configurations for each target
+ // in the solution
+ for(OrderedTargetDependSet::const_iterator tt =
+ projectTargets.begin(); tt != projectTargets.end(); ++tt)
+ {
+ cmTarget* target = *tt;
+ const char* expath = target->GetProperty("EXTERNAL_MSPROJECT");
+ if(expath)
+ {
+ this->WriteProjectConfigurations(
+ fout, target->GetName(),
+ true, target->GetProperty("VS_PLATFORM_MAPPING"));
+ }
+ else
+ {
+ bool partOfDefaultBuild = this->IsPartOfDefaultBuild(
+ root->GetMakefile()->GetProjectName(), target);
+ const char *vcprojName =
+ target->GetProperty("GENERATOR_FILE_NAME");
+ if (vcprojName)
+ {
+ this->WriteProjectConfigurations(fout, vcprojName,
+ partOfDefaultBuild);
+ }
+ }
+ }
+}
+
+
+void cmGlobalVisualStudio7Generator::WriteTargetsToSolution(
+ std::ostream& fout,
+ cmLocalGenerator* root,
+ OrderedTargetDependSet const& projectTargets)
+{
+ for(OrderedTargetDependSet::const_iterator tt =
+ projectTargets.begin(); tt != projectTargets.end(); ++tt)
+ {
+ cmTarget* target = *tt;
+ bool written = false;
+
+ // handle external vc project files
+ const char* expath = target->GetProperty("EXTERNAL_MSPROJECT");
+ if(expath)
+ {
+ std::string project = target->GetName();
+ std::string location = expath;
+
+ this->WriteExternalProject(fout,
+ project.c_str(),
+ location.c_str(),
+ target->GetProperty("VS_PROJECT_TYPE"),
+ target->GetUtilities());
+ written = true;
+ }
+ else
+ {
+ const char *vcprojName =
+ target->GetProperty("GENERATOR_FILE_NAME");
+ if(vcprojName)
+ {
+ cmMakefile* tmf = target->GetMakefile();
+ std::string dir = tmf->GetStartOutputDirectory();
+ dir = root->Convert(dir.c_str(),
+ cmLocalGenerator::START_OUTPUT);
+ if(dir == ".")
+ {
+ dir = ""; // msbuild cannot handle ".\" prefix
+ }
+ this->WriteProject(fout, vcprojName, dir.c_str(),
+ *target);
+ written = true;
+ }
+ }
+
+ // Create "solution folder" information from FOLDER target property
+ //
+ if (written && this->UseFolderProperty())
+ {
+ const char *targetFolder = target->GetProperty("FOLDER");
+ if (targetFolder)
+ {
+ std::vector<cmsys::String> tokens =
+ cmSystemTools::SplitString(targetFolder, '/', false);
+
+ std::string cumulativePath = "";
+
+ for(std::vector<cmsys::String>::iterator iter = tokens.begin();
+ iter != tokens.end(); ++iter)
+ {
+ if(!iter->size())
+ {
+ continue;
+ }
+
+ if (cumulativePath.empty())
+ {
+ cumulativePath = "CMAKE_FOLDER_GUID_" + *iter;
+ }
+ else
+ {
+ VisualStudioFolders[cumulativePath].insert(
+ cumulativePath + "/" + *iter);
+
+ cumulativePath = cumulativePath + "/" + *iter;
+ }
+
+ this->CreateGUID(cumulativePath.c_str());
+ }
+
+ if (!cumulativePath.empty())
+ {
+ VisualStudioFolders[cumulativePath].insert(target->GetName());
+ }
+ }
+ }
+ }
+}
+
+
+void cmGlobalVisualStudio7Generator::WriteTargetDepends(
+ std::ostream& fout,
+ OrderedTargetDependSet const& projectTargets
+ )
+{
+ for(OrderedTargetDependSet::const_iterator tt =
+ projectTargets.begin(); tt != projectTargets.end(); ++tt)
+ {
+ cmTarget* target = *tt;
+ cmMakefile* mf = target->GetMakefile();
+ const char *vcprojName =
+ target->GetProperty("GENERATOR_FILE_NAME");
+ if (vcprojName)
+ {
+ std::string dir = mf->GetStartDirectory();
+ this->WriteProjectDepends(fout, vcprojName,
+ dir.c_str(), *target);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+// Write a SLN file to the stream
+void cmGlobalVisualStudio7Generator
+::WriteSLNFile(std::ostream& fout,
+ cmLocalGenerator* root,
+ std::vector<cmLocalGenerator*>& generators)
+{
+ // Write out the header for a SLN file
+ this->WriteSLNHeader(fout);
+
+ // Collect all targets under this root generator and the transitive
+ // closure of their dependencies.
+ TargetDependSet projectTargets;
+ TargetDependSet originalTargets;
+ this->GetTargetSets(projectTargets, originalTargets, root, generators);
+ OrderedTargetDependSet orderedProjectTargets(projectTargets);
+
+ this->WriteTargetsToSolution(fout, root, orderedProjectTargets);
+
+ bool useFolderProperty = this->UseFolderProperty();
+ if (useFolderProperty)
+ {
+ this->WriteFolders(fout);
+ }
+
+ // Write out the configurations information for the solution
+ fout << "Global\n"
+ << "\tGlobalSection(SolutionConfiguration) = preSolution\n";
+
+ int c = 0;
+ for(std::vector<std::string>::iterator i = this->Configurations.begin();
+ i != this->Configurations.end(); ++i)
+ {
+ fout << "\t\tConfigName." << c << " = " << *i << "\n";
+ c++;
+ }
+ fout << "\tEndGlobalSection\n";
+ // Write out project(target) depends
+ fout << "\tGlobalSection(ProjectDependencies) = postSolution\n";
+ this->WriteTargetDepends(fout, orderedProjectTargets);
+ fout << "\tEndGlobalSection\n";
+
+ if (useFolderProperty)
+ {
+ // Write out project folders
+ fout << "\tGlobalSection(NestedProjects) = preSolution\n";
+ this->WriteFoldersContent(fout);
+ fout << "\tEndGlobalSection\n";
+ }
+
+ // Write out the configurations for all the targets in the project
+ fout << "\tGlobalSection(ProjectConfiguration) = postSolution\n";
+ this->WriteTargetConfigurations(fout, root, orderedProjectTargets);
+ fout << "\tEndGlobalSection\n";
+
+ // Write the footer for the SLN file
+ this->WriteSLNFooter(fout);
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio7Generator::WriteFolders(std::ostream& fout)
+{
+ const char *prefix = "CMAKE_FOLDER_GUID_";
+ const std::string::size_type skip_prefix = strlen(prefix);
+ std::string guidProjectTypeFolder = "2150E333-8FDC-42A3-9474-1A3956D46DE8";
+ for(std::map<std::string,std::set<std::string> >::iterator iter =
+ VisualStudioFolders.begin(); iter != VisualStudioFolders.end(); ++iter)
+ {
+ std::string fullName = iter->first;
+ std::string guid = this->GetGUID(fullName.c_str());
+
+ cmSystemTools::ReplaceString(fullName, "/", "\\");
+ if (cmSystemTools::StringStartsWith(fullName.c_str(), prefix))
+ {
+ fullName = fullName.substr(skip_prefix);
+ }
+
+ std::string nameOnly = cmSystemTools::GetFilenameName(fullName);
+
+ fout << "Project(\"{" <<
+ guidProjectTypeFolder << "}\") = \"" <<
+ nameOnly << "\", \"" <<
+ fullName << "\", \"{" <<
+ guid <<
+ "}\"\nEndProject\n";
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio7Generator::WriteFoldersContent(std::ostream& fout)
+{
+ for(std::map<std::string,std::set<std::string> >::iterator iter =
+ VisualStudioFolders.begin(); iter != VisualStudioFolders.end(); ++iter)
+ {
+ std::string key(iter->first);
+ std::string guidParent(this->GetGUID(key.c_str()));
+
+ for(std::set<std::string>::iterator it = iter->second.begin();
+ it != iter->second.end(); ++it)
+ {
+ std::string value(*it);
+ std::string guid(this->GetGUID(value.c_str()));
+
+ fout << "\t\t{" << guid << "} = {" << guidParent << "}\n";
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmGlobalVisualStudio7Generator::ConvertToSolutionPath(const char* path)
+{
+ // Convert to backslashes. Do not use ConvertToOutputPath because
+ // we will add quoting ourselves, and we know these projects always
+ // use windows slashes.
+ std::string d = path;
+ std::string::size_type pos = 0;
+ while((pos = d.find('/', pos)) != d.npos)
+ {
+ d[pos++] = '\\';
+ }
+ return d;
+}
+
+// Write a dsp file into the SLN file,
+// 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)
+{
+ // check to see if this is a fortran build
+ const char* ext = ".vcproj";
+ const char* project =
+ "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"";
+ if(this->TargetIsFortranOnly(target))
+ {
+ ext = ".vfproj";
+ project = "Project(\"{6989167D-11E4-40FE-8C1A-2192A86A7E90}\") = \"";
+ }
+
+ fout << project
+ << dspname << "\", \""
+ << this->ConvertToSolutionPath(dir) << (dir[0]? "\\":"")
+ << dspname << ext << "\", \"{"
+ << this->GetGUID(dspname) << "}\"\nEndProject\n";
+
+ UtilityDependsMap::iterator ui = this->UtilityDepends.find(&target);
+ if(ui != this->UtilityDepends.end())
+ {
+ const char* uname = ui->second.c_str();
+ fout << "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \""
+ << uname << "\", \""
+ << this->ConvertToSolutionPath(dir) << (dir[0]? "\\":"")
+ << uname << ".vcproj" << "\", \"{"
+ << this->GetGUID(uname) << "}\"\n"
+ << "EndProject\n";
+ }
+}
+
+
+
+// Write a dsp file into the SLN file,
+// Note, that dependencies from executables to
+// the libraries it uses are also done here
+void
+cmGlobalVisualStudio7Generator
+::WriteProjectDepends(std::ostream& fout,
+ const char* dspname,
+ const char*, cmTarget& target)
+{
+ int depcount = 0;
+ std::string dspguid = this->GetGUID(dspname);
+ 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)
+ {
+ std::string m = "Target: ";
+ m += target.GetName();
+ m += " depends on unknown target: ";
+ m += name;
+ cmSystemTools::Error(m.c_str());
+ }
+ fout << "\t\t{" << dspguid << "}." << depcount << " = {" << guid << "}\n";
+ depcount++;
+ }
+
+ UtilityDependsMap::iterator ui = this->UtilityDepends.find(&target);
+ if(ui != this->UtilityDepends.end())
+ {
+ const char* uname = ui->second.c_str();
+ fout << "\t\t{" << this->GetGUID(uname) << "}.0 = {" << dspguid << "}\n";
+ }
+}
+
+
+// Write a dsp file into the SLN file, Note, that dependencies from
+// executables to the libraries it uses are also done here
+void cmGlobalVisualStudio7Generator
+::WriteProjectConfigurations(std::ostream& fout, const char* name,
+ bool partOfDefaultBuild,
+ const char* platformMapping)
+{
+ std::string guid = this->GetGUID(name);
+ for(std::vector<std::string>::iterator i = this->Configurations.begin();
+ i != this->Configurations.end(); ++i)
+ {
+ fout << "\t\t{" << guid << "}." << *i
+ << ".ActiveCfg = " << *i << "|"
+ << (platformMapping ? platformMapping : "Win32") << "\n";
+ if(partOfDefaultBuild)
+ {
+ fout << "\t\t{" << guid << "}." << *i
+ << ".Build.0 = " << *i << "|"
+ << (platformMapping ? platformMapping : "Win32") << "\n";
+ }
+ }
+}
+
+
+
+// Write a dsp file into the SLN file,
+// Note, that dependencies from executables to
+// the libraries it uses are also done here
+void cmGlobalVisualStudio7Generator::WriteExternalProject(std::ostream& fout,
+ const char* name,
+ const char* location,
+ const char* typeGuid,
+ const std::set<cmStdString>&)
+{
+ std::string d = cmSystemTools::ConvertToOutputPath(location);
+ fout << "Project("
+ << "\"{"
+ << (typeGuid ? typeGuid : "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942")
+ << "}\") = \""
+ << name << "\", \""
+ << this->ConvertToSolutionPath(location) << "\", \"{"
+ << this->GetGUID(name)
+ << "}\"\n";
+ fout << "EndProject\n";
+}
+
+
+
+// Standard end of dsw file
+void cmGlobalVisualStudio7Generator::WriteSLNFooter(std::ostream& fout)
+{
+ fout << "\tGlobalSection(ExtensibilityGlobals) = postSolution\n"
+ << "\tEndGlobalSection\n"
+ << "\tGlobalSection(ExtensibilityAddIns) = postSolution\n"
+ << "\tEndGlobalSection\n"
+ << "EndGlobal\n";
+}
+
+
+// ouput standard header for dsw file
+void cmGlobalVisualStudio7Generator::WriteSLNHeader(std::ostream& fout)
+{
+ fout << "Microsoft Visual Studio Solution File, Format Version 7.00\n";
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmGlobalVisualStudio7Generator::WriteUtilityDepend(cmTarget* target)
+{
+ std::string pname = target->GetName();
+ pname += "_UTILITY";
+ std::string fname = target->GetMakefile()->GetStartOutputDirectory();
+ 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"
+ "<VisualStudioProject\n"
+ "\tProjectType=\"Visual C++\"\n"
+ "\tVersion=\"" << this->GetIDEVersion() << "0\"\n"
+ "\tName=\"" << pname << "\"\n"
+ "\tProjectGUID=\"{" << guid << "}\"\n"
+ "\tKeyword=\"Win32Proj\">\n"
+ "\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)
+ {
+ fout <<
+ "\t\t<Configuration\n"
+ "\t\t\tName=\"" << *i << "|Win32\"\n"
+ "\t\t\tOutputDirectory=\"" << *i << "\"\n"
+ "\t\t\tIntermediateDirectory=\"" << pname << ".dir\\" << *i << "\"\n"
+ "\t\t\tConfigurationType=\"10\"\n"
+ "\t\t\tUseOfMFC=\"0\"\n"
+ "\t\t\tATLMinimizesCRunTimeLibraryUsage=\"FALSE\"\n"
+ "\t\t\tCharacterSet=\"2\">\n"
+ "\t\t</Configuration>\n"
+ ;
+ }
+ fout <<
+ "\t</Configurations>\n"
+ "\t<Files></Files>\n"
+ "\t<Globals></Globals>\n"
+ "</VisualStudioProject>\n"
+ ;
+
+ if(fout.Close())
+ {
+ this->FileReplacedDuringGenerate(fname);
+ }
+ return pname;
+}
+
+std::string cmGlobalVisualStudio7Generator::GetGUID(const char* name)
+{
+ std::string guidStoreName = name;
+ guidStoreName += "_GUID_CMAKE";
+ const char* storedGUID =
+ this->CMakeInstance->GetCacheDefinition(guidStoreName.c_str());
+ if(storedGUID)
+ {
+ return std::string(storedGUID);
+ }
+ cmSystemTools::Error("Unknown Target referenced : ",
+ name);
+ return "";
+}
+
+
+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<std::string> *cmGlobalVisualStudio7Generator::GetConfigurations()
+{
+ return &this->Configurations;
+};
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio7Generator
+::GetDocumentation(cmDocumentationEntry& entry) const
+{
+ entry.Name = this->GetName();
+ entry.Brief = "Generates Visual Studio .NET 2002 project files.";
+ entry.Full = "";
+}
+
+//----------------------------------------------------------------------------
+void
+cmGlobalVisualStudio7Generator
+::AppendDirectoryForConfig(const char* prefix,
+ const char* config,
+ const char* suffix,
+ std::string& dir)
+{
+ if(config)
+ {
+ dir += prefix;
+ dir += config;
+ dir += suffix;
+ }
+}
+
+bool cmGlobalVisualStudio7Generator::IsPartOfDefaultBuild(const char* project,
+ cmTarget* target)
+{
+ if(target->GetPropertyAsBool("EXCLUDE_FROM_DEFAULT_BUILD"))
+ {
+ return false;
+ }
+ // 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)
+ {
+ return false;
+ }
+ if(type == cmTarget::UTILITY)
+ {
+ return this->IsDependedOn(project, target);
+ }
+ // default is to be part of the build
+ return true;
+}
+
+//----------------------------------------------------------------------------
+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}
+};
+cmIDEFlagTable const* cmGlobalVisualStudio7Generator::GetExtraFlagTableVS7()
+{
+ return cmVS7ExtraFlagTable;
+}
diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h
new file mode 100644
index 000000000..9b9107db7
--- /dev/null
+++ b/Source/cmGlobalVisualStudio7Generator.h
@@ -0,0 +1,156 @@
+/*============================================================================
+ 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 cmGlobalVisualStudio7Generator_h
+#define cmGlobalVisualStudio7Generator_h
+
+#include "cmGlobalVisualStudioGenerator.h"
+
+class cmTarget;
+struct cmIDEFlagTable;
+
+/** \class cmGlobalVisualStudio7Generator
+ * \brief Write a Unix makefiles.
+ *
+ * cmGlobalVisualStudio7Generator manages UNIX build process for a tree
+ */
+class cmGlobalVisualStudio7Generator : public cmGlobalVisualStudioGenerator
+{
+public:
+ cmGlobalVisualStudio7Generator();
+ static cmGlobalGenerator* New() {
+ return new cmGlobalVisualStudio7Generator; }
+
+ ///! Get the name for the generator.
+ virtual const char* GetName() const {
+ return cmGlobalVisualStudio7Generator::GetActualName();}
+ static const char* GetActualName() {return "Visual Studio 7";}
+
+ ///! Create a local generator appropriate to this Global Generator
+ virtual cmLocalGenerator *CreateLocalGenerator();
+
+ /** Get the documentation entry for this generator. */
+ virtual void GetDocumentation(cmDocumentationEntry& entry) const;
+
+ /**
+ * Try to determine system infomation such as shared library
+ * extension, pthreads, byte order etc.
+ */
+ virtual void EnableLanguage(std::vector<std::string>const& languages,
+ cmMakefile *, bool optional);
+
+ /**
+ * 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* 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();
+
+ /**
+ * 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);
+
+ /** Append the subdirectory for the given configuration. */
+ virtual void AppendDirectoryForConfig(const char* prefix,
+ const char* config,
+ const char* suffix,
+ std::string& dir);
+
+ ///! What is the configurations directory variable called?
+ virtual const char* GetCMakeCFGIntDir() const { return "$(OutDir)"; }
+
+ /** Return true if the target project file should have the option
+ LinkLibraryDependencies and link to .sln dependencies. */
+ virtual bool NeedLinkLibraryDependencies(cmTarget&) { return false; }
+
+protected:
+ virtual const char* GetIDEVersion() { return "7.0"; }
+
+ static cmIDEFlagTable const* GetExtraFlagTableVS7();
+ 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);
+ virtual void WriteProjectDepends(std::ostream& fout,
+ const char* name, const char* path, cmTarget &t);
+ virtual void WriteProjectConfigurations(std::ostream& fout,
+ const char* name,
+ bool partOfDefaultBuild,
+ const char* platformMapping = NULL);
+ virtual void WriteSLNFooter(std::ostream& fout);
+ virtual void WriteSLNHeader(std::ostream& fout);
+ virtual std::string WriteUtilityDepend(cmTarget* target);
+ virtual void AddPlatformDefinitions(cmMakefile* mf);
+
+ virtual void WriteTargetsToSolution(
+ std::ostream& fout,
+ cmLocalGenerator* root,
+ OrderedTargetDependSet const& projectTargets);
+ virtual void WriteTargetDepends(
+ std::ostream& fout,
+ OrderedTargetDependSet const& projectTargets);
+ virtual void WriteTargetConfigurations(
+ std::ostream& fout,
+ cmLocalGenerator* root,
+ OrderedTargetDependSet const& projectTargets);
+
+ void GenerateConfigurations(cmMakefile* mf);
+
+ virtual void WriteExternalProject(std::ostream& fout,
+ const char* name,
+ const char* path,
+ const char* typeGuid,
+ const std::set<cmStdString>&
+ dependencies);
+
+ std::string ConvertToSolutionPath(const char* path);
+
+ bool IsPartOfDefaultBuild(const char* project,
+ cmTarget* target);
+ std::vector<std::string> Configurations;
+ std::map<cmStdString, cmStdString> GUIDMap;
+
+ virtual void WriteFolders(std::ostream& fout);
+ virtual void WriteFoldersContent(std::ostream& fout);
+ std::map<std::string,std::set<std::string> > VisualStudioFolders;
+
+ // Set during OutputSLNFile with the name of the current project.
+ // There is one SLN file per project.
+ std::string CurrentProject;
+};
+
+#define CMAKE_CHECK_BUILD_SYSTEM_TARGET "ZERO_CHECK"
+
+#endif
diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx
new file mode 100644
index 000000000..e7c42327d
--- /dev/null
+++ b/Source/cmGlobalVisualStudio8Generator.cxx
@@ -0,0 +1,376 @@
+/*============================================================================
+ 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 "windows.h" // this must be first to define GetCurrentDirectory
+#include "cmGlobalVisualStudio8Generator.h"
+#include "cmLocalVisualStudio7Generator.h"
+#include "cmMakefile.h"
+#include "cmake.h"
+#include "cmGeneratedFileStream.h"
+
+//----------------------------------------------------------------------------
+cmGlobalVisualStudio8Generator::cmGlobalVisualStudio8Generator()
+{
+ this->FindMakeProgramFile = "CMakeVS8FindMake.cmake";
+ this->ProjectConfigurationSectionName = "ProjectConfigurationPlatforms";
+ this->ArchitectureId = "X86";
+}
+
+//----------------------------------------------------------------------------
+///! Create a local generator appropriate to this Global Generator
+cmLocalGenerator *cmGlobalVisualStudio8Generator::CreateLocalGenerator()
+{
+ cmLocalVisualStudio7Generator *lg =
+ new cmLocalVisualStudio7Generator(cmLocalVisualStudioGenerator::VS8);
+ lg->SetPlatformName(this->GetPlatformName());
+ lg->SetExtraFlagTable(this->GetExtraFlagTableVS8());
+ lg->SetGlobalGenerator(this);
+ return lg;
+}
+
+//----------------------------------------------------------------------------
+// ouput standard header for dsw file
+void cmGlobalVisualStudio8Generator::WriteSLNHeader(std::ostream& fout)
+{
+ fout << "Microsoft Visual Studio Solution File, Format Version 9.00\n";
+ fout << "# Visual Studio 2005\n";
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio8Generator
+::GetDocumentation(cmDocumentationEntry& entry) const
+{
+ entry.Name = this->GetName();
+ entry.Brief = "Generates Visual Studio .NET 2005 project files.";
+ entry.Full = "";
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio8Generator::AddPlatformDefinitions(cmMakefile* mf)
+{
+ mf->AddDefinition("MSVC_C_ARCHITECTURE_ID", this->ArchitectureId);
+ mf->AddDefinition("MSVC_CXX_ARCHITECTURE_ID", this->ArchitectureId);
+ mf->AddDefinition("MSVC80", "1");
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio8Generator::Configure()
+{
+ this->cmGlobalVisualStudio7Generator::Configure();
+ this->CreateGUID(CMAKE_CHECK_BUILD_SYSTEM_TARGET);
+}
+
+//----------------------------------------------------------------------------
+std::string cmGlobalVisualStudio8Generator::GetUserMacrosDirectory()
+{
+ // Some VS8 sp0 versions cannot run macros.
+ // See http://support.microsoft.com/kb/928209
+ const char* vc8sp1Registry =
+ "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\8.0\\"
+ "InstalledProducts\\KB926601;";
+ const char* vc8exSP1Registry =
+ "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\8.0\\"
+ "InstalledProducts\\KB926748;";
+ std::string vc8sp1;
+ if (!cmSystemTools::ReadRegistryValue(vc8sp1Registry, vc8sp1) &&
+ !cmSystemTools::ReadRegistryValue(vc8exSP1Registry, vc8sp1))
+ {
+ return "";
+ }
+
+ std::string base;
+ std::string path;
+
+ // base begins with the VisualStudioProjectsLocation reg value...
+ if (cmSystemTools::ReadRegistryValue(
+ "HKEY_CURRENT_USER\\Software\\Microsoft\\VisualStudio\\8.0;"
+ "VisualStudioProjectsLocation",
+ base))
+ {
+ cmSystemTools::ConvertToUnixSlashes(base);
+
+ // 8.0 macros folder:
+ path = base + "/VSMacros80";
+ }
+
+ // path is (correctly) still empty if we did not read the base value from
+ // the Registry value
+ return path;
+}
+
+//----------------------------------------------------------------------------
+std::string cmGlobalVisualStudio8Generator::GetUserMacrosRegKeyBase()
+{
+ return "Software\\Microsoft\\VisualStudio\\8.0\\vsmacros";
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio8Generator::AddCheckTarget()
+{
+ // Add a special target on which all other targets depend that
+ // checks the build system and optionally re-runs CMake.
+ const char* no_working_directory = 0;
+ std::vector<std::string> no_depends;
+ std::vector<cmLocalGenerator*> const& generators = this->LocalGenerators;
+ cmLocalVisualStudio7Generator* lg =
+ static_cast<cmLocalVisualStudio7Generator*>(generators[0]);
+ cmMakefile* mf = lg->GetMakefile();
+
+ // Skip the target if no regeneration is to be done.
+ if(mf->IsOn("CMAKE_SUPPRESS_REGENERATION"))
+ {
+ return;
+ }
+
+ 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);
+
+ // Organize in the "predefined targets" folder:
+ //
+ if (this->UseFolderProperty())
+ {
+ tgt->SetProperty("FOLDER", this->GetPredefinedTargetsFolder());
+ }
+
+ // Create a list of all stamp files for this project.
+ std::vector<std::string> stamps;
+ std::string stampList = cmake::GetCMakeFilesDirectoryPostSlash();
+ stampList += "generate.stamp.list";
+ {
+ std::string stampListFile =
+ generators[0]->GetMakefile()->GetCurrentOutputDirectory();
+ stampListFile += "/";
+ stampListFile += stampList;
+ std::string stampFile;
+ cmGeneratedFileStream fout(stampListFile.c_str());
+ for(std::vector<cmLocalGenerator*>::const_iterator
+ gi = generators.begin(); gi != generators.end(); ++gi)
+ {
+ stampFile = (*gi)->GetMakefile()->GetCurrentOutputDirectory();
+ stampFile += "/";
+ stampFile += cmake::GetCMakeFilesDirectoryPostSlash();
+ stampFile += "generate.stamp";
+ fout << stampFile << "\n";
+ stamps.push_back(stampFile);
+ }
+ }
+
+ // Add a custom rule to re-run CMake if any input files changed.
+ {
+ // Collect the input files used to generate all targets in this
+ // project.
+ std::vector<std::string> listFiles;
+ for(unsigned int j = 0; j < generators.size(); ++j)
+ {
+ cmMakefile* lmf = generators[j]->GetMakefile();
+ listFiles.insert(listFiles.end(), lmf->GetListFiles().begin(),
+ lmf->GetListFiles().end());
+ }
+ // Sort the list of input files and remove duplicates.
+ std::sort(listFiles.begin(), listFiles.end(),
+ std::less<std::string>());
+ std::vector<std::string>::iterator new_end =
+ std::unique(listFiles.begin(), listFiles.end());
+ listFiles.erase(new_end, listFiles.end());
+
+ // 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);
+ std::string argH = "-H";
+ argH += lg->Convert(mf->GetHomeDirectory(),
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::UNCHANGED, true);
+ commandLine.push_back(argH);
+ std::string argB = "-B";
+ argB += lg->Convert(mf->GetHomeOutputDirectory(),
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::UNCHANGED, true);
+ commandLine.push_back(argB);
+ commandLine.push_back("--check-stamp-list");
+ commandLine.push_back(stampList.c_str());
+ commandLine.push_back("--vs-solution-file");
+ commandLine.push_back("\"$(SolutionPath)\"");
+ cmCustomCommandLines commandLines;
+ commandLines.push_back(commandLine);
+
+ // Add the rule. Note that we cannot use the CMakeLists.txt
+ // 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;
+ const char* no_working_directory = 0;
+ if(cmSourceFile* file =
+ mf->AddCustomCommandToOutput(
+ stamps, listFiles,
+ no_main_dependency, commandLines, "Checking Build System",
+ no_working_directory, true))
+ {
+ tgt->AddSourceFile(file);
+ }
+ else
+ {
+ cmSystemTools::Error("Error adding rule for ", stamps[0].c_str());
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio8Generator::Generate()
+{
+ 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)
+ {
+ if(ti->first != CMAKE_CHECK_BUILD_SYSTEM_TARGET)
+ {
+ ti->second->AddUtility(CMAKE_CHECK_BUILD_SYSTEM_TARGET);
+ }
+ }
+
+ // Now perform the main generation.
+ this->cmGlobalVisualStudio7Generator::Generate();
+}
+
+//----------------------------------------------------------------------------
+void
+cmGlobalVisualStudio8Generator
+::WriteSolutionConfigurations(std::ostream& fout)
+{
+ fout << "\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n";
+ for(std::vector<std::string>::iterator i = this->Configurations.begin();
+ i != this->Configurations.end(); ++i)
+ {
+ fout << "\t\t" << *i << "|" << this->GetPlatformName()
+ << " = " << *i << "|" << this->GetPlatformName() << "\n";
+ }
+ fout << "\tEndGlobalSection\n";
+}
+
+//----------------------------------------------------------------------------
+void
+cmGlobalVisualStudio8Generator
+::WriteProjectConfigurations(std::ostream& fout, const char* name,
+ bool partOfDefaultBuild,
+ const char* platformMapping)
+{
+ std::string guid = this->GetGUID(name);
+ for(std::vector<std::string>::iterator i = this->Configurations.begin();
+ i != this->Configurations.end(); ++i)
+ {
+ fout << "\t\t{" << guid << "}." << *i
+ << "|" << this->GetPlatformName() << ".ActiveCfg = " << *i << "|"
+ << (platformMapping ? platformMapping : this->GetPlatformName())
+ << "\n";
+ if(partOfDefaultBuild)
+ {
+ fout << "\t\t{" << guid << "}." << *i
+ << "|" << this->GetPlatformName() << ".Build.0 = " << *i << "|"
+ << (platformMapping ? platformMapping : this->GetPlatformName())
+ << "\n";
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmGlobalVisualStudio8Generator::ComputeTargetDepends()
+{
+ // Skip over the cmGlobalVisualStudioGenerator implementation!
+ // We do not need the support that VS <= 7.1 needs.
+ return this->cmGlobalGenerator::ComputeTargetDepends();
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio8Generator::WriteProjectDepends(
+ std::ostream& fout, const char*, const char*, cmTarget& t)
+{
+ TargetDependSet const& unordered = this->GetTargetDirectDepends(t);
+ OrderedTargetDependSet depends(unordered);
+ for(OrderedTargetDependSet::const_iterator i = depends.begin();
+ i != depends.end(); ++i)
+ {
+ std::string guid = this->GetGUID((*i)->GetName());
+ fout << "\t\t{" << guid << "} = {" << guid << "}\n";
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmGlobalVisualStudio8Generator::NeedLinkLibraryDependencies(
+ cmTarget& target)
+{
+ // Look for utility dependencies that magically link.
+ for(std::set<cmStdString>::const_iterator ui =
+ target.GetUtilities().begin();
+ ui != target.GetUtilities().end(); ++ui)
+ {
+ if(cmTarget* depTarget = this->FindTarget(0, ui->c_str()))
+ {
+ if(depTarget->GetProperty("EXTERNAL_MSPROJECT"))
+ {
+ // This utility dependency names an external .vcproj target.
+ // We use LinkLibraryDependencies="true" to link to it without
+ // predicting the .lib file location or name.
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+static cmVS7FlagTable cmVS8ExtraFlagTable[] =
+{
+ {"CallingConvention", "Gd", "cdecl", "0", 0 },
+ {"CallingConvention", "Gr", "fastcall", "1", 0 },
+ {"CallingConvention", "Gz", "stdcall", "2", 0 },
+
+ {"Detect64BitPortabilityProblems", "Wp64",
+ "Detect 64Bit Portability Problems", "true", 0 },
+ {"ErrorReporting", "errorReport:prompt", "Report immediately", "1", 0 },
+ {"ErrorReporting", "errorReport:queue", "Queue for next login", "2", 0 },
+ // Precompiled header and related options. Note that the
+ // UsePrecompiledHeader entries are marked as "Continue" so that the
+ // corresponding PrecompiledHeaderThrough entry can be found.
+ {"UsePrecompiledHeader", "Yu", "Use Precompiled Header", "2",
+ cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},
+ {"PrecompiledHeaderThrough", "Yu", "Precompiled Header Name", "",
+ cmVS7FlagTable::UserValueRequired},
+ // There is no YX option in the VS8 IDE.
+
+ // Exception handling mode. If no entries match, it will be FALSE.
+ {"ExceptionHandling", "GX", "enable c++ exceptions", "1", 0},
+ {"ExceptionHandling", "EHsc", "enable c++ exceptions", "1", 0},
+ {"ExceptionHandling", "EHa", "enable SEH exceptions", "2", 0},
+
+ {"EnablePREfast", "analyze", "", "true", 0},
+ {"EnablePREfast", "analyze-", "", "false", 0},
+
+ // Language options
+ {"TreatWChar_tAsBuiltInType", "Zc:wchar_t",
+ "wchar_t is a built-in type", "true", 0},
+ {"TreatWChar_tAsBuiltInType", "Zc:wchar_t-",
+ "wchar_t is not a built-in type", "false", 0},
+
+ {0,0,0,0,0}
+};
+cmIDEFlagTable const* cmGlobalVisualStudio8Generator::GetExtraFlagTableVS8()
+{
+ return cmVS8ExtraFlagTable;
+}
diff --git a/Source/cmGlobalVisualStudio8Generator.h b/Source/cmGlobalVisualStudio8Generator.h
new file mode 100644
index 000000000..7dae42907
--- /dev/null
+++ b/Source/cmGlobalVisualStudio8Generator.h
@@ -0,0 +1,88 @@
+/*============================================================================
+ 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 cmGlobalVisualStudio8Generator_h
+#define cmGlobalVisualStudio8Generator_h
+
+#include "cmGlobalVisualStudio71Generator.h"
+
+
+/** \class cmGlobalVisualStudio8Generator
+ * \brief Write a Unix makefiles.
+ *
+ * cmGlobalVisualStudio8Generator manages UNIX build process for a tree
+ */
+class cmGlobalVisualStudio8Generator : public cmGlobalVisualStudio71Generator
+{
+public:
+ cmGlobalVisualStudio8Generator();
+ static cmGlobalGenerator* New() {
+ return new cmGlobalVisualStudio8Generator; }
+
+ ///! Get the name for the generator.
+ virtual const char* GetName() const {
+ return cmGlobalVisualStudio8Generator::GetActualName();}
+ static const char* GetActualName() {return "Visual Studio 8 2005";}
+
+ virtual const char* GetPlatformName() const {return "Win32";}
+
+ /** Get the documentation entry for this generator. */
+ virtual void GetDocumentation(cmDocumentationEntry& entry) const;
+
+ ///! Create a local generator appropriate to this Global Generator
+ virtual cmLocalGenerator *CreateLocalGenerator();
+
+ /**
+ * 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
+ * current user? Returns the empty string if this version of Visual
+ * Studio does not implement support for VB macros.
+ */
+ virtual std::string GetUserMacrosDirectory();
+
+ /**
+ * What is the reg key path to "vsmacros" for this version of Visual
+ * Studio?
+ */
+ virtual std::string GetUserMacrosRegKeyBase();
+
+ /** Return true if the target project file should have the option
+ LinkLibraryDependencies and link to .sln dependencies. */
+ virtual bool NeedLinkLibraryDependencies(cmTarget& target);
+
+protected:
+ virtual const char* GetIDEVersion() { return "8.0"; }
+
+ virtual bool VSLinksDependencies() const { return false; }
+
+ void AddCheckTarget();
+
+ static cmIDEFlagTable const* GetExtraFlagTableVS8();
+ virtual void AddPlatformDefinitions(cmMakefile* mf);
+ virtual void WriteSLNHeader(std::ostream& fout);
+ virtual void WriteSolutionConfigurations(std::ostream& fout);
+ virtual void WriteProjectConfigurations(std::ostream& fout,
+ const char* name,
+ bool partOfDefaultBuild,
+ const char* platformMapping = NULL);
+ virtual bool ComputeTargetDepends();
+ virtual void WriteProjectDepends(std::ostream& fout, const char* name,
+ const char* path, cmTarget &t);
+
+ const char* ArchitectureId;
+};
+#endif
diff --git a/Source/cmGlobalVisualStudio8Win64Generator.cxx b/Source/cmGlobalVisualStudio8Win64Generator.cxx
new file mode 100644
index 000000000..60e45b840
--- /dev/null
+++ b/Source/cmGlobalVisualStudio8Win64Generator.cxx
@@ -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.
+============================================================================*/
+#include "windows.h" // this must be first to define GetCurrentDirectory
+#include "cmGlobalVisualStudio8Win64Generator.h"
+#include "cmLocalVisualStudio7Generator.h"
+#include "cmMakefile.h"
+#include "cmake.h"
+
+
+
+cmGlobalVisualStudio8Win64Generator::cmGlobalVisualStudio8Win64Generator()
+{
+ this->ArchitectureId = "x64";
+}
+
+///! Create a local generator appropriate to this Global Generator
+cmLocalGenerator *cmGlobalVisualStudio8Win64Generator::CreateLocalGenerator()
+{
+ cmLocalVisualStudio7Generator *lg
+ = new cmLocalVisualStudio7Generator(cmLocalVisualStudioGenerator::VS8);
+ lg->SetPlatformName(this->GetPlatformName());
+ lg->SetExtraFlagTable(this->GetExtraFlagTableVS8());
+ lg->SetGlobalGenerator(this);
+ return lg;
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio8Win64Generator
+::GetDocumentation(cmDocumentationEntry& entry) const
+{
+ entry.Name = this->GetName();
+ entry.Brief = "Generates Visual Studio .NET 2005 Win64 project files.";
+ entry.Full = "";
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio8Win64Generator
+::AddPlatformDefinitions(cmMakefile* mf)
+{
+ this->cmGlobalVisualStudio8Generator::AddPlatformDefinitions(mf);
+ mf->AddDefinition("CMAKE_FORCE_WIN64", "TRUE");
+}
diff --git a/Source/cmGlobalVisualStudio8Win64Generator.h b/Source/cmGlobalVisualStudio8Win64Generator.h
new file mode 100644
index 000000000..084ba697c
--- /dev/null
+++ b/Source/cmGlobalVisualStudio8Win64Generator.h
@@ -0,0 +1,50 @@
+/*============================================================================
+ 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 cmGlobalVisualStudio8Win64Generator_h
+#define cmGlobalVisualStudio8Win64Generator_h
+
+#include "cmGlobalVisualStudio8Generator.h"
+
+
+/** \class cmGlobalVisualStudio8Win64Generator
+ * \brief Write a Unix makefiles.
+ *
+ * cmGlobalVisualStudio8Win64Generator manages UNIX build process for a tree
+ */
+class cmGlobalVisualStudio8Win64Generator :
+ public cmGlobalVisualStudio8Generator
+{
+public:
+ cmGlobalVisualStudio8Win64Generator();
+ static cmGlobalGenerator* New() {
+ return new cmGlobalVisualStudio8Win64Generator; }
+
+ ///! Get the name for the generator.
+ virtual const char* GetName() const {
+ return cmGlobalVisualStudio8Win64Generator::GetActualName();}
+ static const char* GetActualName() {return "Visual Studio 8 2005 Win64";}
+
+ virtual const char* GetPlatformName() const {return "x64";}
+
+ /** Get the documentation entry for this generator. */
+ virtual void GetDocumentation(cmDocumentationEntry& entry) const;
+
+ ///! create the correct local generator
+ virtual cmLocalGenerator *CreateLocalGenerator();
+
+ /**
+ * Try to determine system infomation such as shared library
+ * extension, pthreads, byte order etc.
+ */
+ virtual void AddPlatformDefinitions(cmMakefile *);
+};
+#endif
diff --git a/Source/cmGlobalVisualStudio9Generator.cxx b/Source/cmGlobalVisualStudio9Generator.cxx
new file mode 100644
index 000000000..f082675eb
--- /dev/null
+++ b/Source/cmGlobalVisualStudio9Generator.cxx
@@ -0,0 +1,99 @@
+/*============================================================================
+ 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 "windows.h" // this must be first to define GetCurrentDirectory
+#include "cmGlobalVisualStudio9Generator.h"
+#include "cmLocalVisualStudio7Generator.h"
+#include "cmMakefile.h"
+#include "cmake.h"
+
+
+
+cmGlobalVisualStudio9Generator::cmGlobalVisualStudio9Generator()
+{
+ this->FindMakeProgramFile = "CMakeVS9FindMake.cmake";
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio9Generator::AddPlatformDefinitions(cmMakefile* mf)
+{
+ mf->AddDefinition("MSVC_C_ARCHITECTURE_ID", this->ArchitectureId);
+ mf->AddDefinition("MSVC_CXX_ARCHITECTURE_ID", this->ArchitectureId);
+ mf->AddDefinition("MSVC90", "1");
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio9Generator::WriteSLNHeader(std::ostream& fout)
+{
+ fout << "Microsoft Visual Studio Solution File, Format Version 10.00\n";
+ 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
+::GetDocumentation(cmDocumentationEntry& entry) const
+{
+ entry.Name = this->GetName();
+ entry.Brief = "Generates Visual Studio 9 2008 project files.";
+ entry.Full = "";
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio9Generator
+::EnableLanguage(std::vector<std::string>const & lang,
+ cmMakefile *mf, bool optional)
+{
+ cmGlobalVisualStudio8Generator::EnableLanguage(lang, mf, optional);
+}
+
+//----------------------------------------------------------------------------
+std::string cmGlobalVisualStudio9Generator::GetUserMacrosDirectory()
+{
+ std::string base;
+ std::string path;
+
+ // base begins with the VisualStudioProjectsLocation reg value...
+ if (cmSystemTools::ReadRegistryValue(
+ "HKEY_CURRENT_USER\\Software\\Microsoft\\VisualStudio\\9.0;"
+ "VisualStudioProjectsLocation",
+ base))
+ {
+ 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
+ }
+
+ // path is (correctly) still empty if we did not read the base value from
+ // the Registry value
+ return path;
+}
+
+//----------------------------------------------------------------------------
+std::string cmGlobalVisualStudio9Generator::GetUserMacrosRegKeyBase()
+{
+ return "Software\\Microsoft\\VisualStudio\\9.0\\vsmacros";
+}
diff --git a/Source/cmGlobalVisualStudio9Generator.h b/Source/cmGlobalVisualStudio9Generator.h
new file mode 100644
index 000000000..bfb03c4c5
--- /dev/null
+++ b/Source/cmGlobalVisualStudio9Generator.h
@@ -0,0 +1,66 @@
+/*============================================================================
+ 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 cmGlobalVisualStudio9Generator_h
+#define cmGlobalVisualStudio9Generator_h
+
+#include "cmGlobalVisualStudio8Generator.h"
+
+
+/** \class cmGlobalVisualStudio9Generator
+ * \brief Write a Unix makefiles.
+ *
+ * cmGlobalVisualStudio9Generator manages UNIX build process for a tree
+ */
+class cmGlobalVisualStudio9Generator :
+ public cmGlobalVisualStudio8Generator
+{
+public:
+ cmGlobalVisualStudio9Generator();
+ static cmGlobalGenerator* New() {
+ return new cmGlobalVisualStudio9Generator; }
+
+ ///! Get the name for the generator.
+ virtual const char* GetName() const {
+ return cmGlobalVisualStudio9Generator::GetActualName();}
+ static const char* GetActualName() {return "Visual Studio 9 2008";}
+ virtual void AddPlatformDefinitions(cmMakefile* mf);
+
+ /** Get the documentation entry for this generator. */
+ virtual void GetDocumentation(cmDocumentationEntry& entry) const;
+
+ ///! create the correct local generator
+ virtual cmLocalGenerator *CreateLocalGenerator();
+
+ /**
+ * Try to determine system infomation 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);
+
+ /**
+ * 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();
+
+ /**
+ * What is the reg key path to "vsmacros" for this version of Visual
+ * Studio?
+ */
+ virtual std::string GetUserMacrosRegKeyBase();
+protected:
+ virtual const char* GetIDEVersion() { return "9.0"; }
+};
+#endif
diff --git a/Source/cmGlobalVisualStudio9IA64Generator.cxx b/Source/cmGlobalVisualStudio9IA64Generator.cxx
new file mode 100644
index 000000000..993340ae8
--- /dev/null
+++ b/Source/cmGlobalVisualStudio9IA64Generator.cxx
@@ -0,0 +1,48 @@
+/*============================================================================
+ 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 "cmGlobalVisualStudio9IA64Generator.h"
+#include "cmLocalVisualStudio7Generator.h"
+#include "cmMakefile.h"
+
+
+cmGlobalVisualStudio9IA64Generator::cmGlobalVisualStudio9IA64Generator()
+{
+ this->ArchitectureId = "Itanium";
+}
+
+///! Create a local generator appropriate to this Global Generator
+cmLocalGenerator *cmGlobalVisualStudio9IA64Generator::CreateLocalGenerator()
+{
+ cmLocalVisualStudio7Generator *lg =
+ new cmLocalVisualStudio7Generator(cmLocalVisualStudioGenerator::VS9);
+ lg->SetPlatformName(this->GetPlatformName());
+ lg->SetExtraFlagTable(this->GetExtraFlagTableVS8());
+ lg->SetGlobalGenerator(this);
+ return lg;
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio9IA64Generator
+::GetDocumentation(cmDocumentationEntry& entry) const
+{
+ entry.Name = this->GetName();
+ entry.Brief = "Generates Visual Studio 9 2008 Itanium project files.";
+ entry.Full = "";
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio9IA64Generator
+::AddPlatformDefinitions(cmMakefile* mf)
+{
+ cmGlobalVisualStudio9Generator::AddPlatformDefinitions(mf);
+ mf->AddDefinition("CMAKE_FORCE_IA64", "TRUE");
+}
diff --git a/Source/cmGlobalVisualStudio9IA64Generator.h b/Source/cmGlobalVisualStudio9IA64Generator.h
new file mode 100644
index 000000000..e33ee1550
--- /dev/null
+++ b/Source/cmGlobalVisualStudio9IA64Generator.h
@@ -0,0 +1,50 @@
+/*============================================================================
+ 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 cmGlobalVisualStudio9IA64Generator_h
+#define cmGlobalVisualStudio9IA64Generator_h
+
+#include "cmGlobalVisualStudio9Generator.h"
+
+
+/** \class cmGlobalVisualStudio8IA64Generator
+ * \brief Write a Unix makefiles.
+ *
+ * cmGlobalVisualStudio8IA64Generator manages UNIX build process for a tree
+ */
+class cmGlobalVisualStudio9IA64Generator :
+ public cmGlobalVisualStudio9Generator
+{
+public:
+ cmGlobalVisualStudio9IA64Generator();
+ static cmGlobalGenerator* New() {
+ return new cmGlobalVisualStudio9IA64Generator; }
+
+ ///! Get the name for the generator.
+ virtual const char* GetName() const {
+ return cmGlobalVisualStudio9IA64Generator::GetActualName();}
+ static const char* GetActualName() {return "Visual Studio 9 2008 IA64";}
+
+ virtual const char* GetPlatformName() const {return "Itanium";}
+
+ /** Get the documentation entry for this generator. */
+ virtual void GetDocumentation(cmDocumentationEntry& entry) const;
+
+ ///! create the correct local generator
+ virtual cmLocalGenerator *CreateLocalGenerator();
+
+ /**
+ * Try to determine system infomation such as shared library
+ * extension, pthreads, byte order etc.
+ */
+ virtual void AddPlatformDefinitions(cmMakefile *);
+};
+#endif
diff --git a/Source/cmGlobalVisualStudio9Win64Generator.cxx b/Source/cmGlobalVisualStudio9Win64Generator.cxx
new file mode 100644
index 000000000..08f537d1a
--- /dev/null
+++ b/Source/cmGlobalVisualStudio9Win64Generator.cxx
@@ -0,0 +1,48 @@
+/*============================================================================
+ 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 "cmGlobalVisualStudio9Win64Generator.h"
+#include "cmLocalVisualStudio7Generator.h"
+#include "cmMakefile.h"
+
+
+cmGlobalVisualStudio9Win64Generator::cmGlobalVisualStudio9Win64Generator()
+{
+ this->ArchitectureId = "x64";
+}
+
+///! Create a local generator appropriate to this Global Generator
+cmLocalGenerator *cmGlobalVisualStudio9Win64Generator::CreateLocalGenerator()
+{
+ cmLocalVisualStudio7Generator *lg =
+ new cmLocalVisualStudio7Generator(cmLocalVisualStudioGenerator::VS9);
+ lg->SetPlatformName(this->GetPlatformName());
+ lg->SetExtraFlagTable(this->GetExtraFlagTableVS8());
+ lg->SetGlobalGenerator(this);
+ return lg;
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio9Win64Generator
+::GetDocumentation(cmDocumentationEntry& entry) const
+{
+ entry.Name = this->GetName();
+ entry.Brief = "Generates Visual Studio 9 2008 Win64 project files.";
+ entry.Full = "";
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio9Win64Generator
+::AddPlatformDefinitions(cmMakefile* mf)
+{
+ cmGlobalVisualStudio9Generator::AddPlatformDefinitions(mf);
+ mf->AddDefinition("CMAKE_FORCE_WIN64", "TRUE");
+}
diff --git a/Source/cmGlobalVisualStudio9Win64Generator.h b/Source/cmGlobalVisualStudio9Win64Generator.h
new file mode 100644
index 000000000..f6dcc03cd
--- /dev/null
+++ b/Source/cmGlobalVisualStudio9Win64Generator.h
@@ -0,0 +1,50 @@
+/*============================================================================
+ 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 cmGlobalVisualStudio9Win64Generator_h
+#define cmGlobalVisualStudio9Win64Generator_h
+
+#include "cmGlobalVisualStudio9Generator.h"
+
+
+/** \class cmGlobalVisualStudio8Win64Generator
+ * \brief Write a Unix makefiles.
+ *
+ * cmGlobalVisualStudio8Win64Generator manages UNIX build process for a tree
+ */
+class cmGlobalVisualStudio9Win64Generator :
+ public cmGlobalVisualStudio9Generator
+{
+public:
+ cmGlobalVisualStudio9Win64Generator();
+ static cmGlobalGenerator* New() {
+ return new cmGlobalVisualStudio9Win64Generator; }
+
+ ///! Get the name for the generator.
+ virtual const char* GetName() const {
+ return cmGlobalVisualStudio9Win64Generator::GetActualName();}
+ static const char* GetActualName() {return "Visual Studio 9 2008 Win64";}
+
+ virtual const char* GetPlatformName() const {return "x64";}
+
+ /** Get the documentation entry for this generator. */
+ virtual void GetDocumentation(cmDocumentationEntry& entry) const;
+
+ ///! create the correct local generator
+ virtual cmLocalGenerator *CreateLocalGenerator();
+
+ /**
+ * Try to determine system infomation such as shared library
+ * extension, pthreads, byte order etc.
+ */
+ virtual void AddPlatformDefinitions(cmMakefile *);
+};
+#endif
diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx
new file mode 100644
index 000000000..2a918c925
--- /dev/null
+++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -0,0 +1,861 @@
+/*============================================================================
+ 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 "cmGlobalVisualStudioGenerator.h"
+
+#include "cmCallVisualStudioMacro.h"
+#include "cmGeneratorTarget.h"
+#include "cmLocalVisualStudioGenerator.h"
+#include "cmMakefile.h"
+#include "cmSourceFile.h"
+#include "cmTarget.h"
+
+//----------------------------------------------------------------------------
+cmGlobalVisualStudioGenerator::cmGlobalVisualStudioGenerator()
+{
+}
+
+//----------------------------------------------------------------------------
+cmGlobalVisualStudioGenerator::~cmGlobalVisualStudioGenerator()
+{
+}
+
+//----------------------------------------------------------------------------
+std::string cmGlobalVisualStudioGenerator::GetRegistryBase()
+{
+ std::string key = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\";
+ key += this->GetIDEVersion();
+ return key;
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudioGenerator::Generate()
+{
+ // 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;
+ 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())
+ {
+ // Use no actual command lines so that the target itself is not
+ // considered always out of date.
+ cmTarget* allBuild =
+ gen[0]->GetMakefile()->
+ AddUtilityCommand("ALL_BUILD", true, no_working_dir,
+ no_depends, no_commands, false,
+ "Build all projects");
+
+#if 0
+ // Can't activate this code because we want ALL_BUILD
+ // selected as the default "startup project" when first
+ // opened in Visual Studio... And if it's nested in a
+ // folder, then that doesn't happen.
+ //
+ // Organize in the "predefined targets" folder:
+ //
+ if (this->UseFolderProperty())
+ {
+ allBuild->SetProperty("FOLDER", this->GetPredefinedTargetsFolder());
+ }
+#endif
+
+ // Now make all targets depend on the ALL_BUILD target
+ cmTargets targets;
+ for(std::vector<cmLocalGenerator*>::iterator i = gen.begin();
+ i != gen.end(); ++i)
+ {
+ cmTargets& targets = (*i)->GetMakefile()->GetTargets();
+ for(cmTargets::iterator t = targets.begin();
+ t != targets.end(); ++t)
+ {
+ if(!this->IsExcluded(gen[0], t->second))
+ {
+ allBuild->AddUtility(t->second.GetName());
+ }
+ }
+ }
+ }
+ }
+
+ // Configure CMake Visual Studio macros, for this user on this version
+ // of Visual Studio.
+ this->ConfigureCMakeVisualStudioMacros();
+
+ // Add CMakeLists.txt with custom command to rerun CMake.
+ for(std::vector<cmLocalGenerator*>::const_iterator
+ lgi = this->LocalGenerators.begin();
+ lgi != this->LocalGenerators.end(); ++lgi)
+ {
+ cmLocalVisualStudioGenerator* lg =
+ static_cast<cmLocalVisualStudioGenerator*>(*lgi);
+ lg->AddCMakeListsRules();
+ }
+
+ // Run all the local generators.
+ this->cmGlobalGenerator::Generate();
+}
+
+//----------------------------------------------------------------------------
+void
+cmGlobalVisualStudioGenerator
+::ComputeTargetObjects(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();
+ dir += "/";
+ std::string tgtDir = lg->GetTargetDirectory(*gt->Target);
+ if(!tgtDir.empty())
+ {
+ dir += tgtDir;
+ dir += "/";
+ }
+ const char* cd = this->GetCMakeCFGIntDir();
+ if(cd && *cd)
+ {
+ dir += cd;
+ dir += "/";
+ }
+ gt->ObjectDirectory = dir;
+}
+
+//----------------------------------------------------------------------------
+bool IsVisualStudioMacrosFileRegistered(const std::string& macrosFile,
+ const std::string& regKeyBase,
+ std::string& nextAvailableSubKeyName);
+
+void RegisterVisualStudioMacros(const std::string& macrosFile,
+ const std::string& regKeyBase);
+
+//----------------------------------------------------------------------------
+#define CMAKE_VSMACROS_FILENAME \
+ "CMakeVSMacros2.vsmacros"
+
+#define CMAKE_VSMACROS_RELOAD_MACRONAME \
+ "Macros.CMakeVSMacros2.Macros.ReloadProjects"
+
+#define CMAKE_VSMACROS_STOP_MACRONAME \
+ "Macros.CMakeVSMacros2.Macros.StopBuild"
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudioGenerator::ConfigureCMakeVisualStudioMacros()
+{
+ cmMakefile* mf = this->LocalGenerators[0]->GetMakefile();
+ std::string dir = this->GetUserMacrosDirectory();
+
+ if (mf != 0 && dir != "")
+ {
+ std::string src = mf->GetRequiredDefinition("CMAKE_ROOT");
+ src += "/Templates/" CMAKE_VSMACROS_FILENAME;
+
+ std::string dst = dir + "/CMakeMacros/" CMAKE_VSMACROS_FILENAME;
+
+ // Copy the macros file to the user directory only if the
+ // destination does not exist or the source location is newer.
+ // This will allow the user to edit the macros for development
+ // purposes but newer versions distributed with CMake will replace
+ // older versions in user directories.
+ int res;
+ if(!cmSystemTools::FileTimeCompare(src.c_str(), dst.c_str(), &res) ||
+ res > 0)
+ {
+ if (!cmSystemTools::CopyFileAlways(src.c_str(), dst.c_str()))
+ {
+ std::ostringstream oss;
+ oss << "Could not copy from: " << src << std::endl;
+ oss << " to: " << dst << std::endl;
+ cmSystemTools::Message(oss.str().c_str(), "Warning");
+ }
+ }
+
+ RegisterVisualStudioMacros(dst, this->GetUserMacrosRegKeyBase());
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmGlobalVisualStudioGenerator
+::CallVisualStudioMacro(MacroName m,
+ const char* vsSolutionFile)
+{
+ // If any solution or project files changed during the generation,
+ // tell Visual Studio to reload them...
+ cmMakefile* mf = this->LocalGenerators[0]->GetMakefile();
+ 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 != "")
+ {
+ std::string macrosFile = dir + "/CMakeMacros/" CMAKE_VSMACROS_FILENAME;
+ std::string nextSubkeyName;
+ if (cmSystemTools::FileExists(macrosFile.c_str()) &&
+ IsVisualStudioMacrosFileRegistered(macrosFile,
+ this->GetUserMacrosRegKeyBase(), nextSubkeyName)
+ )
+ {
+ std::string topLevelSlnName;
+ if(vsSolutionFile)
+ {
+ topLevelSlnName = vsSolutionFile;
+ }
+ else
+ {
+ topLevelSlnName = mf->GetStartOutputDirectory();
+ topLevelSlnName += "/";
+ topLevelSlnName += mf->GetProjectName();
+ topLevelSlnName += ".sln";
+ }
+
+ if(m == MacroReload)
+ {
+ std::vector<std::string> filenames;
+ this->GetFilesReplacedDuringGenerate(filenames);
+ if (filenames.size() > 0)
+ {
+ // Convert vector to semi-colon delimited string of filenames:
+ std::string projects;
+ std::vector<std::string>::iterator it = filenames.begin();
+ if (it != filenames.end())
+ {
+ projects = *it;
+ ++it;
+ }
+ for (; it != filenames.end(); ++it)
+ {
+ projects += ";";
+ projects += *it;
+ }
+ cmCallVisualStudioMacro::CallMacro(topLevelSlnName,
+ CMAKE_VSMACROS_RELOAD_MACRONAME, projects,
+ this->GetCMakeInstance()->GetDebugOutput());
+ }
+ }
+ else if(m == MacroStop)
+ {
+ cmCallVisualStudioMacro::CallMacro(topLevelSlnName,
+ CMAKE_VSMACROS_STOP_MACRONAME, "",
+ this->GetCMakeInstance()->GetDebugOutput());
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string cmGlobalVisualStudioGenerator::GetUserMacrosDirectory()
+{
+ return "";
+}
+
+//----------------------------------------------------------------------------
+std::string cmGlobalVisualStudioGenerator::GetUserMacrosRegKeyBase()
+{
+ return "";
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudioGenerator::FillLinkClosure(cmTarget* target,
+ TargetSet& linked)
+{
+ if(linked.insert(target).second)
+ {
+ TargetDependSet const& depends = this->GetTargetDirectDepends(*target);
+ for(TargetDependSet::const_iterator di = depends.begin();
+ di != depends.end(); ++di)
+ {
+ if(di->IsLink())
+ {
+ this->FillLinkClosure(*di, linked);
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+cmGlobalVisualStudioGenerator::TargetSet const&
+cmGlobalVisualStudioGenerator::GetTargetLinkClosure(cmTarget* target)
+{
+ TargetSetMap::iterator i = this->TargetLinkClosure.find(target);
+ if(i == this->TargetLinkClosure.end())
+ {
+ TargetSetMap::value_type entry(target, TargetSet());
+ i = this->TargetLinkClosure.insert(entry).first;
+ this->FillLinkClosure(target, i->second);
+ }
+ return i->second;
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudioGenerator::FollowLinkDepends(
+ cmTarget* target, std::set<cmTarget*>& linked)
+{
+ if(linked.insert(target).second &&
+ target->GetType() == cmTarget::STATIC_LIBRARY)
+ {
+ // Static library targets do not list their link dependencies so
+ // we must follow them transitively now.
+ TargetDependSet const& depends = this->GetTargetDirectDepends(*target);
+ for(TargetDependSet::const_iterator di = depends.begin();
+ di != depends.end(); ++di)
+ {
+ if(di->IsLink())
+ {
+ this->FollowLinkDepends(*di, linked);
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmGlobalVisualStudioGenerator::ComputeTargetDepends()
+{
+ if(!this->cmGlobalGenerator::ComputeTargetDepends())
+ {
+ return false;
+ }
+ std::map<cmStdString, 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();
+ ti != targets.end(); ++ti)
+ {
+ this->ComputeVSTargetDepends(ti->second);
+ }
+ }
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+static bool VSLinkable(cmTarget* t)
+{
+ return t->IsLinkable() || t->GetType() == cmTarget::OBJECT_LIBRARY;
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudioGenerator::ComputeVSTargetDepends(cmTarget& target)
+{
+ if(this->VSTargetDepends.find(&target) != this->VSTargetDepends.end())
+ {
+ return;
+ }
+ 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
+ // library cause that library to be linked. We use an intermedite
+ // empty utility target to express the dependency. (VS 8 and above
+ // provide a project file "LinkLibraryDependencies" setting to
+ // choose whether to activate this behavior. We disable it except
+ // when linking external project files.)
+ //
+ // (2) We cannot let static libraries depend directly on targets to
+ // which they "link" because the librarian tool will copy the
+ // targets into the static library. While the work-around for
+ // behavior (1) would also avoid this, it would create a large
+ // number of extra utility targets for little gain. Instead, use
+ // the above work-around only for dependencies explicitly added by
+ // the add_dependencies() command. Approximate link dependencies by
+ // 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);
+
+ 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)
+ {
+ for(TargetDependSet::const_iterator di = depends.begin();
+ di != depends.end(); ++di)
+ {
+ cmTargetDepend dep = *di;
+ if(dep.IsLink())
+ {
+ this->FollowLinkDepends(dep, linkDepends);
+ }
+ }
+ }
+
+ // Collext explicit util dependencies (add_dependencies).
+ std::set<cmTarget*> utilDepends;
+ for(TargetDependSet::const_iterator di = depends.begin();
+ di != depends.end(); ++di)
+ {
+ cmTargetDepend dep = *di;
+ if(dep.IsUtil())
+ {
+ this->FollowLinkDepends(dep, utilDepends);
+ }
+ }
+
+ // Collect all targets linked by this target so we can avoid
+ // intermediate targets below.
+ TargetSet linked;
+ if(target.GetType() != cmTarget::STATIC_LIBRARY)
+ {
+ linked = this->GetTargetLinkClosure(&target);
+ }
+
+ // Emit link dependencies.
+ for(std::set<cmTarget*>::iterator di = linkDepends.begin();
+ di != linkDepends.end(); ++di)
+ {
+ cmTarget* dep = *di;
+ vsTargetDepend.insert(dep->GetName());
+ }
+
+ // Emit util dependencies. Possibly use intermediate targets.
+ for(std::set<cmTarget*>::iterator di = utilDepends.begin();
+ di != utilDepends.end(); ++di)
+ {
+ cmTarget* dep = *di;
+ if(allowLinkable || !VSLinkable(dep) || linked.count(dep))
+ {
+ // Direct dependency allowed.
+ vsTargetDepend.insert(dep->GetName());
+ }
+ else
+ {
+ // Direct dependency on linkable target not allowed.
+ // Use an intermediate utility target.
+ vsTargetDepend.insert(this->GetUtilityDepend(dep));
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string cmGlobalVisualStudioGenerator::GetUtilityDepend(cmTarget* target)
+{
+ UtilityDependsMap::iterator i = this->UtilityDepends.find(target);
+ if(i == this->UtilityDepends.end())
+ {
+ std::string name = this->WriteUtilityDepend(target);
+ UtilityDependsMap::value_type entry(target, name);
+ i = this->UtilityDepends.insert(entry).first;
+ }
+ return i->second;
+}
+
+//----------------------------------------------------------------------------
+#include <windows.h>
+
+//----------------------------------------------------------------------------
+bool IsVisualStudioMacrosFileRegistered(const std::string& macrosFile,
+ const std::string& regKeyBase,
+ std::string& nextAvailableSubKeyName)
+{
+ bool macrosRegistered = false;
+
+ std::string s1;
+ std::string s2;
+
+ // Make lowercase local copies, convert to Unix slashes, and
+ // see if the resulting strings are the same:
+ s1 = cmSystemTools::LowerCase(macrosFile);
+ cmSystemTools::ConvertToUnixSlashes(s1);
+
+ std::string keyname;
+ HKEY hkey = NULL;
+ LONG result = ERROR_SUCCESS;
+ DWORD index = 0;
+
+ keyname = regKeyBase + "\\OtherProjects7";
+ hkey = NULL;
+ result = RegOpenKeyEx(HKEY_CURRENT_USER, 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]);
+ FILETIME lastWriteTime;
+ lastWriteTime.dwHighDateTime = 0;
+ lastWriteTime.dwLowDateTime = 0;
+
+ while (ERROR_SUCCESS == RegEnumKeyEx(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);
+ if (ERROR_SUCCESS == result)
+ {
+ DWORD valueType = REG_SZ;
+ CHAR data1[256];
+ DWORD cch_data1 = sizeof(data1)/sizeof(data1[0]);
+ RegQueryValueEx(hsubkey, "Path", 0, &valueType,
+ (LPBYTE) &data1[0], &cch_data1);
+
+ DWORD data2 = 0;
+ DWORD cch_data2 = sizeof(data2);
+ RegQueryValueEx(hsubkey, "Security", 0, &valueType,
+ (LPBYTE) &data2, &cch_data2);
+
+ DWORD data3 = 0;
+ DWORD cch_data3 = sizeof(data3);
+ RegQueryValueEx(hsubkey, "StorageFormat", 0, &valueType,
+ (LPBYTE) &data3, &cch_data3);
+
+ s2 = cmSystemTools::LowerCase(data1);
+ cmSystemTools::ConvertToUnixSlashes(s2);
+ if (s2 == s1)
+ {
+ macrosRegistered = true;
+ }
+
+ std::string fullname(data1);
+ std::string filename;
+ std::string filepath;
+ std::string filepathname;
+ std::string filepathpath;
+ if (cmSystemTools::FileExists(fullname.c_str()))
+ {
+ filename = cmSystemTools::GetFilenameName(fullname);
+ filepath = cmSystemTools::GetFilenamePath(fullname);
+ filepathname = cmSystemTools::GetFilenameName(filepath);
+ filepathpath = cmSystemTools::GetFilenamePath(filepath);
+ }
+
+ //std::cout << keyname << "\\" << subkeyname << ":" << std::endl;
+ //std::cout << " Path: " << data1 << std::endl;
+ //std::cout << " Security: " << data2 << std::endl;
+ //std::cout << " StorageFormat: " << data3 << std::endl;
+ //std::cout << " filename: " << filename << std::endl;
+ //std::cout << " filepath: " << filepath << std::endl;
+ //std::cout << " filepathname: " << filepathname << std::endl;
+ //std::cout << " filepathpath: " << filepathpath << std::endl;
+ //std::cout << std::endl;
+
+ RegCloseKey(hsubkey);
+ }
+ else
+ {
+ std::cout << "error opening subkey: " << subkeyname << std::endl;
+ std::cout << std::endl;
+ }
+
+ ++index;
+ cch_subkeyname = sizeof(subkeyname)/sizeof(subkeyname[0]);
+ cch_keyclass = sizeof(keyclass)/sizeof(keyclass[0]);
+ lastWriteTime.dwHighDateTime = 0;
+ lastWriteTime.dwLowDateTime = 0;
+ }
+
+ RegCloseKey(hkey);
+ }
+ else
+ {
+ std::cout << "error opening key: " << keyname << std::endl;
+ std::cout << std::endl;
+ }
+
+
+ // Pass back next available sub key name, assuming sub keys always
+ // follow the expected naming scheme. Expected naming scheme is that
+ // the subkeys of OtherProjects7 is 0 to n-1, so it's ok to use "n"
+ // as the name of the next subkey.
+ std::ostringstream ossNext;
+ ossNext << index;
+ nextAvailableSubKeyName = ossNext.str();
+
+
+ keyname = regKeyBase + "\\RecordingProject7";
+ hkey = NULL;
+ result = RegOpenKeyEx(HKEY_CURRENT_USER, 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,
+ (LPBYTE) &data1[0], &cch_data1);
+
+ DWORD data2 = 0;
+ DWORD cch_data2 = sizeof(data2);
+ RegQueryValueEx(hkey, "Security", 0, &valueType,
+ (LPBYTE) &data2, &cch_data2);
+
+ DWORD data3 = 0;
+ DWORD cch_data3 = sizeof(data3);
+ RegQueryValueEx(hkey, "StorageFormat", 0, &valueType,
+ (LPBYTE) &data3, &cch_data3);
+
+ s2 = cmSystemTools::LowerCase(data1);
+ cmSystemTools::ConvertToUnixSlashes(s2);
+ if (s2 == s1)
+ {
+ macrosRegistered = true;
+ }
+
+ //std::cout << keyname << ":" << std::endl;
+ //std::cout << " Path: " << data1 << std::endl;
+ //std::cout << " Security: " << data2 << std::endl;
+ //std::cout << " StorageFormat: " << data3 << std::endl;
+ //std::cout << std::endl;
+
+ RegCloseKey(hkey);
+ }
+ else
+ {
+ std::cout << "error opening key: " << keyname << std::endl;
+ std::cout << std::endl;
+ }
+
+ return macrosRegistered;
+}
+
+//----------------------------------------------------------------------------
+void WriteVSMacrosFileRegistryEntry(
+ const std::string& nextAvailableSubKeyName,
+ const std::string& macrosFile,
+ const std::string& regKeyBase)
+{
+ std::string keyname = regKeyBase + "\\OtherProjects7";
+ HKEY hkey = NULL;
+ LONG result = RegOpenKeyEx(HKEY_CURRENT_USER, 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);
+ if (ERROR_SUCCESS == result)
+ {
+ DWORD dw = 0;
+
+ std::string s(macrosFile);
+ cmSystemTools::ReplaceString(s, "/", "\\");
+
+ result = RegSetValueEx(hsubkey, "Path", 0, REG_SZ, (LPBYTE) s.c_str(),
+ static_cast<DWORD>(strlen(s.c_str()) + 1));
+ if (ERROR_SUCCESS != result)
+ {
+ std::cout << "error result 1: " << result << std::endl;
+ std::cout << std::endl;
+ }
+
+ // 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",
+ 0, REG_DWORD, (LPBYTE) &dw, sizeof(DWORD));
+ if (ERROR_SUCCESS != result)
+ {
+ std::cout << "error result 2: " << result << std::endl;
+ std::cout << std::endl;
+ }
+
+ // StorageFormat value is always "0" for sample macros files
+ dw = 0;
+ result = RegSetValueEx(hsubkey, "StorageFormat",
+ 0, REG_DWORD, (LPBYTE) &dw, sizeof(DWORD));
+ if (ERROR_SUCCESS != result)
+ {
+ std::cout << "error result 3: " << result << std::endl;
+ std::cout << std::endl;
+ }
+
+ RegCloseKey(hsubkey);
+ }
+ else
+ {
+ std::cout << "error creating subkey: "
+ << nextAvailableSubKeyName << std::endl;
+ std::cout << std::endl;
+ }
+ RegCloseKey(hkey);
+ }
+ else
+ {
+ std::cout << "error opening key: " << keyname << std::endl;
+ std::cout << std::endl;
+ }
+}
+
+//----------------------------------------------------------------------------
+void RegisterVisualStudioMacros(const std::string& macrosFile,
+ const std::string& regKeyBase)
+{
+ bool macrosRegistered;
+ std::string nextAvailableSubKeyName;
+
+ macrosRegistered = IsVisualStudioMacrosFileRegistered(macrosFile,
+ regKeyBase, nextAvailableSubKeyName);
+
+ if (!macrosRegistered)
+ {
+ int count = cmCallVisualStudioMacro::
+ GetNumberOfRunningVisualStudioInstances("ALL");
+
+ // Only register the macros file if there are *no* instances of Visual
+ // Studio running. If we register it while one is running, first, it has
+ // no effect on the running instance; second, and worse, Visual Studio
+ // removes our newly added registration entry when it quits. Instead,
+ // emit a warning asking the user to exit all running Visual Studio
+ // instances...
+ //
+ if (0 != count)
+ {
+ std::ostringstream oss;
+ oss << "Could not register CMake's Visual Studio macros file '"
+ << CMAKE_VSMACROS_FILENAME "' while Visual Studio is running."
+ << " Please exit all running instances of Visual Studio before"
+ << " continuing." << std::endl
+ << std::endl
+ << "CMake needs to register Visual Studio macros when its macros"
+ << " file is updated or when it detects that its current macros file"
+ << " is no longer registered with Visual Studio."
+ << std::endl;
+ cmSystemTools::Message(oss.str().c_str(), "Warning");
+
+ // Count them again now that the warning is over. In the case of a GUI
+ // warning, the user may have gone to close Visual Studio and then come
+ // back to the CMake GUI and clicked ok on the above warning. If so,
+ // then register the macros *now* if the count is *now* 0...
+ //
+ count = cmCallVisualStudioMacro::
+ GetNumberOfRunningVisualStudioInstances("ALL");
+
+ // Also re-get the nextAvailableSubKeyName in case Visual Studio
+ // wrote out new registered macros information as it was exiting:
+ //
+ if (0 == count)
+ {
+ IsVisualStudioMacrosFileRegistered(macrosFile, regKeyBase,
+ nextAvailableSubKeyName);
+ }
+ }
+
+ // Do another if check - 'count' may have changed inside the above if:
+ //
+ if (0 == count)
+ {
+ WriteVSMacrosFileRegistryEntry(nextAvailableSubKeyName, macrosFile,
+ regKeyBase);
+ }
+ }
+}
+bool cmGlobalVisualStudioGenerator::TargetIsFortranOnly(cmTarget& target)
+{
+ // check to see if this is a fortran build
+ std::set<cmStdString> languages;
+ target.GetLanguages(languages);
+ if(languages.size() == 1)
+ {
+ if(*languages.begin() == "Fortran")
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool
+cmGlobalVisualStudioGenerator::TargetCompare
+::operator()(cmTarget const* l, cmTarget const* r) const
+{
+ // Make sure ALL_BUILD is first so it is the default active project.
+ if(strcmp(r->GetName(), "ALL_BUILD") == 0)
+ {
+ return false;
+ }
+ if(strcmp(l->GetName(), "ALL_BUILD") == 0)
+ {
+ return true;
+ }
+ return strcmp(l->GetName(), r->GetName()) < 0;
+}
+
+//----------------------------------------------------------------------------
+cmGlobalVisualStudioGenerator::OrderedTargetDependSet
+::OrderedTargetDependSet(TargetDependSet const& targets)
+{
+ for(TargetDependSet::const_iterator ti =
+ targets.begin(); ti != targets.end(); ++ti)
+ {
+ this->insert(*ti);
+ }
+}
+
+//----------------------------------------------------------------------------
+cmGlobalVisualStudioGenerator::OrderedTargetDependSet
+::OrderedTargetDependSet(TargetSet const& targets)
+{
+ for(TargetSet::const_iterator ti = targets.begin();
+ ti != targets.end(); ++ti)
+ {
+ this->insert(*ti);
+ }
+}
diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h
new file mode 100644
index 000000000..b62ba229d
--- /dev/null
+++ b/Source/cmGlobalVisualStudioGenerator.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 cmGlobalVisualStudioGenerator_h
+#define cmGlobalVisualStudioGenerator_h
+
+#include "cmGlobalGenerator.h"
+
+/** \class cmGlobalVisualStudioGenerator
+ * \brief Base class for global Visual Studio generators.
+ *
+ * cmGlobalVisualStudioGenerator provides functionality common to all
+ * global Visual Studio generators.
+ */
+class cmGlobalVisualStudioGenerator : public cmGlobalGenerator
+{
+public:
+ cmGlobalVisualStudioGenerator();
+ virtual ~cmGlobalVisualStudioGenerator();
+
+ /**
+ * Basic generate implementation for all VS generators.
+ */
+ virtual void Generate();
+
+ /**
+ * Configure CMake's Visual Studio macros file into the user's Visual
+ * Studio macros directory.
+ */
+ virtual void ConfigureCMakeVisualStudioMacros();
+
+ /**
+ * 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();
+
+ /**
+ * What is the reg key path to "vsmacros" for this version of Visual
+ * Studio?
+ */
+ virtual std::string GetUserMacrosRegKeyBase();
+
+ enum MacroName {MacroReload, MacroStop};
+
+ /**
+ * Call the ReloadProjects macro if necessary based on
+ * GetFilesReplacedDuringGenerate results.
+ */
+ virtual void CallVisualStudioMacro(MacroName m,
+ const char* vsSolutionFile = 0);
+
+ // return true if target is fortran only
+ bool TargetIsFortranOnly(cmTarget& t);
+
+ /** Get the top-level registry key for this VS version. */
+ std::string GetRegistryBase();
+
+ /** 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 true; }
+
+ class TargetSet: public std::set<cmTarget*> {};
+ struct TargetCompare
+ {
+ bool operator()(cmTarget const* l, cmTarget const* r) const;
+ };
+ class OrderedTargetDependSet;
+
+protected:
+ // 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.
+ virtual bool VSLinksDependencies() const { return true; }
+
+ virtual const char* GetIDEVersion() = 0;
+
+ virtual bool ComputeTargetDepends();
+ class VSDependSet: public std::set<cmStdString> {};
+ class VSDependMap: public std::map<cmTarget*, 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;
+ UtilityDependsMap UtilityDepends;
+private:
+ void ComputeTargetObjects(cmGeneratorTarget* gt) const;
+
+ void FollowLinkDepends(cmTarget* target, std::set<cmTarget*>& linked);
+
+ class TargetSetMap: public std::map<cmTarget*, TargetSet> {};
+ TargetSetMap TargetLinkClosure;
+ void FillLinkClosure(cmTarget* target, TargetSet& linked);
+ TargetSet const& GetTargetLinkClosure(cmTarget* target);
+};
+
+class cmGlobalVisualStudioGenerator::OrderedTargetDependSet:
+ public std::multiset<cmTargetDepend,
+ cmGlobalVisualStudioGenerator::TargetCompare>
+{
+public:
+ typedef cmGlobalGenerator::TargetDependSet TargetDependSet;
+ typedef cmGlobalVisualStudioGenerator::TargetSet TargetSet;
+ OrderedTargetDependSet(TargetDependSet const&);
+ OrderedTargetDependSet(TargetSet const&);
+};
+
+#endif
diff --git a/Source/cmGlobalWatcomWMakeGenerator.cxx b/Source/cmGlobalWatcomWMakeGenerator.cxx
new file mode 100644
index 000000000..8c6dff9bd
--- /dev/null
+++ b/Source/cmGlobalWatcomWMakeGenerator.cxx
@@ -0,0 +1,66 @@
+/*============================================================================
+ 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 "cmGlobalWatcomWMakeGenerator.h"
+#include "cmLocalUnixMakefileGenerator3.h"
+#include "cmMakefile.h"
+
+cmGlobalWatcomWMakeGenerator::cmGlobalWatcomWMakeGenerator()
+{
+ this->FindMakeProgramFile = "CMakeFindWMake.cmake";
+ this->ForceUnixPaths = false;
+ this->ToolSupportsColor = true;
+ this->NeedSymbolicMark = true;
+ this->EmptyRuleHackCommand = "@cd .";
+}
+
+void cmGlobalWatcomWMakeGenerator
+::EnableLanguage(std::vector<std::string>const& l,
+ cmMakefile *mf,
+ bool optional)
+{
+ // pick a default
+ mf->AddDefinition("WATCOM", "1");
+ mf->AddDefinition("CMAKE_QUOTE_INCLUDE_PATHS", "1");
+ 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) const
+{
+ entry.Name = this->GetName();
+ entry.Brief = "Generates Watcom WMake makefiles.";
+ entry.Full = "";
+}
diff --git a/Source/cmGlobalWatcomWMakeGenerator.h b/Source/cmGlobalWatcomWMakeGenerator.h
new file mode 100644
index 000000000..b416bb181
--- /dev/null
+++ b/Source/cmGlobalWatcomWMakeGenerator.h
@@ -0,0 +1,46 @@
+/*============================================================================
+ 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 cmGlobalWatcomWMakeGenerator_h
+#define cmGlobalWatcomWMakeGenerator_h
+
+#include "cmGlobalUnixMakefileGenerator3.h"
+
+/** \class cmGlobalWatcomWMakeGenerator
+ * \brief Write a NMake makefiles.
+ *
+ * cmGlobalWatcomWMakeGenerator manages nmake build process for a tree
+ */
+class cmGlobalWatcomWMakeGenerator : public cmGlobalUnixMakefileGenerator3
+{
+public:
+ cmGlobalWatcomWMakeGenerator();
+ static cmGlobalGenerator* New() { return new cmGlobalWatcomWMakeGenerator; }
+ ///! Get the name for the generator.
+ virtual const char* GetName() const {
+ return cmGlobalWatcomWMakeGenerator::GetActualName();}
+ static const char* GetActualName() {return "Watcom WMake";}
+
+ /** Get the documentation entry for this generator. */
+ virtual void GetDocumentation(cmDocumentationEntry& entry) const;
+
+ ///! Create a local generator appropriate to this Global Generator
+ virtual cmLocalGenerator *CreateLocalGenerator();
+
+ /**
+ * Try to determine system infomation such as shared library
+ * extension, pthreads, byte order etc.
+ */
+ virtual void EnableLanguage(std::vector<std::string>const& languages,
+ cmMakefile *, bool optional);
+};
+
+#endif
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
new file mode 100644
index 000000000..938977bfb
--- /dev/null
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -0,0 +1,3757 @@
+/*============================================================================
+ 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 "cmGlobalXCodeGenerator.h"
+#include "cmLocalXCodeGenerator.h"
+#include "cmMakefile.h"
+#include "cmXCodeObject.h"
+#include "cmXCode21Object.h"
+#include "cmake.h"
+#include "cmGeneratedFileStream.h"
+#include "cmComputeLinkInformation.h"
+#include "cmSourceFile.h"
+#include "cmCustomCommandGenerator.h"
+#include "cmGeneratorTarget.h"
+
+#include <cmsys/auto_ptr.hxx>
+
+//----------------------------------------------------------------------------
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+#include "cmXMLParser.h"
+
+// parse the xml file storing the installed version of Xcode on
+// the machine
+class cmXcodeVersionParser : public cmXMLParser
+{
+public:
+ cmXcodeVersionParser(): Version("1.5") {}
+ void StartElement(const char* , const char** )
+ {
+ this->Data = "";
+ }
+ void EndElement(const char* name)
+ {
+ if(strcmp(name, "key") == 0)
+ {
+ this->Key = this->Data;
+ }
+ else if(strcmp(name, "string") == 0)
+ {
+ if(this->Key == "CFBundleShortVersionString")
+ {
+ this->Version = this->Data;
+ }
+ }
+ }
+ void CharacterDataHandler(const char* data, int length)
+ {
+ this->Data.append(data, length);
+ }
+ std::string Version;
+ std::string Key;
+ std::string Data;
+};
+#endif
+
+// Builds either an object list or a space-separated string from the
+// given inputs.
+class cmGlobalXCodeGenerator::BuildObjectListOrString
+{
+ cmGlobalXCodeGenerator *Generator;
+ cmXCodeObject *Group;
+ bool Empty;
+ std::string String;
+
+public:
+ BuildObjectListOrString(cmGlobalXCodeGenerator *gen, bool buildObjectList)
+ : Generator(gen), Group(0), Empty(true)
+ {
+ if (buildObjectList)
+ {
+ this->Group = this->Generator->CreateObject(cmXCodeObject::OBJECT_LIST);
+ }
+ }
+
+ bool IsEmpty() const { return this->Empty; }
+
+ void Add(const char *newString)
+ {
+ this->Empty = false;
+
+ if (this->Group)
+ {
+ this->Group->AddObject(this->Generator->CreateString(newString));
+ }
+ else
+ {
+ this->String += newString;
+ this->String += ' ';
+ }
+ }
+
+ const std::string &GetString() const { return this->String; }
+
+ cmXCodeObject *CreateList()
+ {
+ if (this->Group)
+ {
+ return this->Group;
+ }
+ else
+ {
+ return this->Generator->CreateString(this->String.c_str());
+ }
+ }
+};
+
+//----------------------------------------------------------------------------
+cmGlobalXCodeGenerator::cmGlobalXCodeGenerator(std::string const& version)
+{
+ this->VersionString = version;
+
+ // Compute an integer form of the version number.
+ unsigned int v[2] = {0,0};
+ 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;
+}
+
+//----------------------------------------------------------------------------
+cmGlobalGenerator* cmGlobalXCodeGenerator::New()
+{
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ cmXcodeVersionParser parser;
+ if (cmSystemTools::FileExists(
+ "/Applications/Xcode.app/Contents/version.plist"))
+ {
+ parser.ParseFile
+ ("/Applications/Xcode.app/Contents/version.plist");
+ }
+ else
+ {
+ parser.ParseFile
+ ("/Developer/Applications/Xcode.app/Contents/version.plist");
+ }
+ cmsys::auto_ptr<cmGlobalXCodeGenerator>
+ gg(new cmGlobalXCodeGenerator(parser.Version));
+ if (gg->XcodeVersion == 20)
+ {
+ cmSystemTools::Message("Xcode 2.0 not really supported by cmake, "
+ "using Xcode 15 generator\n");
+ gg->XcodeVersion = 15;
+ }
+ return gg.release();
+#else
+ std::cerr << "CMake should be built with cmake to use Xcode, "
+ "default to Xcode 1.5\n";
+ return new cmGlobalXCodeGenerator;
+#endif
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalXCodeGenerator::EnableLanguage(std::vector<std::string>const&
+ lang,
+ cmMakefile * mf, bool optional)
+{
+ mf->AddDefinition("XCODE","1");
+ mf->AddDefinition("XCODE_VERSION", this->VersionString.c_str());
+ if(this->XcodeVersion == 15)
+ {
+ }
+ else
+ {
+ if(!mf->GetDefinition("CMAKE_CONFIGURATION_TYPES"))
+ {
+ mf->AddCacheDefinition(
+ "CMAKE_CONFIGURATION_TYPES",
+ "Debug;Release;MinSizeRel;RelWithDebInfo",
+ "Semicolon separated list of supported configuration types, "
+ "only supports Debug, Release, MinSizeRel, and RelWithDebInfo, "
+ "anything else will be ignored.",
+ cmCacheManager::STRING);
+ }
+ }
+ mf->AddDefinition("CMAKE_GENERATOR_CC", "gcc");
+ mf->AddDefinition("CMAKE_GENERATOR_CXX", "g++");
+ mf->AddDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV", "1");
+ this->cmGlobalGenerator::EnableLanguage(lang, mf, optional);
+ const char* osxArch =
+ mf->GetDefinition("CMAKE_OSX_ARCHITECTURES");
+ const char* sysroot =
+ mf->GetDefinition("CMAKE_OSX_SYSROOT");
+ if(osxArch && sysroot)
+ {
+ this->Architectures.clear();
+ cmSystemTools::ExpandListArgument(std::string(osxArch),
+ this->Architectures);
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string cmGlobalXCodeGenerator
+::GenerateBuildCommand(const char* makeProgram,
+ const char *projectName,
+ const char* additionalOptions,
+ const char *targetName,
+ const char* config,
+ bool ignoreErrors,
+ bool)
+{
+ // Config is not used yet
+ (void) ignoreErrors;
+
+ // 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 += " -project ";
+ makeCommand += projectName;
+ makeCommand += ".xcode";
+ if(this->XcodeVersion > 20)
+ {
+ makeCommand += "proj";
+ }
+
+ bool clean = false;
+ if ( targetName && strcmp(targetName, "clean") == 0 )
+ {
+ clean = true;
+ targetName = "ALL_BUILD";
+ }
+ if(clean)
+ {
+ makeCommand += " clean";
+ }
+ else
+ {
+ makeCommand += " build";
+ }
+ makeCommand += " -target ";
+ // if it is a null string for config don't use it
+ if(config && *config == 0)
+ {
+ config = 0;
+ }
+ if (targetName && strlen(targetName))
+ {
+ makeCommand += targetName;
+ }
+ else
+ {
+ makeCommand += "ALL_BUILD";
+ }
+ if(this->XcodeVersion == 15)
+ {
+ makeCommand += " -buildstyle Development ";
+ }
+ else
+ {
+ makeCommand += " -configuration ";
+ makeCommand += config?config:"Debug";
+ }
+ if ( additionalOptions )
+ {
+ makeCommand += " ";
+ makeCommand += additionalOptions;
+ }
+ return makeCommand;
+}
+
+//----------------------------------------------------------------------------
+///! Create a local generator appropriate to this Global Generator
+cmLocalGenerator *cmGlobalXCodeGenerator::CreateLocalGenerator()
+{
+ cmLocalGenerator *lg = new cmLocalXCodeGenerator;
+ lg->SetGlobalGenerator(this);
+ return lg;
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalXCodeGenerator::Generate()
+{
+ std::map<cmStdString, 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)
+ {
+ cmLocalGenerator* root = it->second[0];
+ this->SetGenerationRoot(root);
+ // add ALL_BUILD, INSTALL, etc
+ this->AddExtraTargets(root, it->second);
+ }
+ this->ForceLinkerLanguages();
+ this->cmGlobalGenerator::Generate();
+ if(cmSystemTools::GetErrorOccuredFlag())
+ {
+ return;
+ }
+ for(it = this->ProjectMap.begin(); it!= this->ProjectMap.end(); ++it)
+ {
+ cmLocalGenerator* root = it->second[0];
+ this->SetGenerationRoot(root);
+ // now create the project
+ this->OutputXCodeProject(root, it->second);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalXCodeGenerator::SetGenerationRoot(cmLocalGenerator* root)
+{
+ this->CurrentProject = root->GetMakefile()->GetProjectName();
+ this->SetCurrentLocalGenerator(root);
+ cmSystemTools::SplitPath(this->CurrentMakefile->GetCurrentDirectory(),
+ this->ProjectSourceDirectoryComponents);
+ cmSystemTools::SplitPath(this->CurrentMakefile->GetCurrentOutputDirectory(),
+ this->ProjectOutputDirectoryComponents);
+
+ this->CurrentXCodeHackMakefile =
+ root->GetMakefile()->GetCurrentOutputDirectory();
+ this->CurrentXCodeHackMakefile += "/CMakeScripts";
+ cmSystemTools::MakeDirectory(this->CurrentXCodeHackMakefile.c_str());
+ this->CurrentXCodeHackMakefile += "/XCODE_DEPEND_HELPER.make";
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmGlobalXCodeGenerator::PostBuildMakeTarget(std::string const& tName,
+ std::string const& configName)
+{
+ std::string target = tName;
+ cmSystemTools::ReplaceString(target, " ", "_");
+ std::string out = "PostBuild." + target;
+ if(this->XcodeVersion > 20)
+ {
+ out += "." + configName;
+ }
+ return out;
+}
+
+//----------------------------------------------------------------------------
+#define CMAKE_CHECK_BUILD_SYSTEM_TARGET "ZERO_CHECK"
+
+//----------------------------------------------------------------------------
+void
+cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
+ std::vector<cmLocalGenerator*>& gens)
+{
+ cmMakefile* mf = root->GetMakefile();
+
+ // Add ALL_BUILD
+ const char* no_working_directory = 0;
+ std::vector<std::string> no_depends;
+ mf->AddUtilityCommand("ALL_BUILD", true, no_depends,
+ no_working_directory,
+ "echo", "Build all projects");
+ cmTarget* allbuild = mf->FindTarget("ALL_BUILD");
+
+ // Refer to the main build configuration file for easy editing.
+ std::string listfile = mf->GetStartDirectory();
+ listfile += "/";
+ listfile += "CMakeLists.txt";
+ allbuild->AddSource(listfile.c_str());
+
+ // Add XCODE depend helper
+ std::string dir = mf->GetCurrentOutputDirectory();
+ cmCustomCommandLine makecommand;
+ makecommand.push_back("make");
+ makecommand.push_back("-C");
+ makecommand.push_back(dir.c_str());
+ makecommand.push_back("-f");
+ makecommand.push_back(this->CurrentXCodeHackMakefile.c_str());
+ makecommand.push_back(""); // placeholder, see below
+
+ // Add ZERO_CHECK
+ bool regenerate = !mf->IsOn("CMAKE_SUPPRESS_REGENERATION");
+ if (regenerate)
+ {
+ this->CreateReRunCMakeFile(root, gens);
+ std::string file = this->ConvertToRelativeForMake(
+ this->CurrentReRunCMakeMakefile.c_str());
+ cmSystemTools::ReplaceString(file, "\\ ", " ");
+ mf->AddUtilityCommand(CMAKE_CHECK_BUILD_SYSTEM_TARGET, true, no_depends,
+ no_working_directory,
+ "make", "-f", file.c_str());
+ }
+
+ // now make the allbuild depend on all the non-utility targets
+ // in the project
+ for(std::vector<cmLocalGenerator*>::iterator i = gens.begin();
+ i != gens.end(); ++i)
+ {
+ cmLocalGenerator* lg = *i;
+ if(this->IsExcluded(root, *i))
+ {
+ continue;
+ }
+
+ cmTargets& tgts = lg->GetMakefile()->GetTargets();
+ for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++)
+ {
+ cmTarget& target = l->second;
+
+ if (regenerate && (l->first != CMAKE_CHECK_BUILD_SYSTEM_TARGET))
+ {
+ target.AddUtility(CMAKE_CHECK_BUILD_SYSTEM_TARGET);
+ }
+
+ // make all exe, shared libs and modules
+ // run the depend check makefile as a post build rule
+ // this will make sure that when the next target is built
+ // things are up-to-date
+ if((target.GetType() == cmTarget::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))
+ {
+ makecommand[makecommand.size()-1] =
+ this->PostBuildMakeTarget(target.GetName(), "$(CONFIGURATION)");
+ cmCustomCommandLines commandLines;
+ commandLines.push_back(makecommand);
+ lg->GetMakefile()->AddCustomCommandToTarget(target.GetName(),
+ no_depends,
+ commandLines,
+ cmTarget::POST_BUILD,
+ "Depend check for xcode",
+ dir.c_str());
+ }
+
+ if(!target.GetPropertyAsBool("EXCLUDE_FROM_ALL"))
+ {
+ allbuild->AddUtility(target.GetName());
+ }
+
+ // Refer to the build configuration file for easy editing.
+ listfile = lg->GetMakefile()->GetStartDirectory();
+ listfile += "/";
+ listfile += "CMakeLists.txt";
+ target.AddSource(listfile.c_str());
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+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)
+ {
+ std::vector<std::string> const& lf = (*gi)->GetMakefile()->GetListFiles();
+ lfiles.insert(lfiles.end(), lf.begin(), lf.end());
+ }
+
+ // sort the array
+ std::sort(lfiles.begin(), lfiles.end(), std::less<std::string>());
+ 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 += "/CMakeScripts";
+ cmSystemTools::MakeDirectory(this->CurrentReRunCMakeMakefile.c_str());
+ this->CurrentReRunCMakeMakefile += "/ReRunCMake.make";
+ cmGeneratedFileStream makefileStream
+ (this->CurrentReRunCMakeMakefile.c_str());
+ makefileStream.SetCopyIfDifferent(true);
+ makefileStream << "# Generated by CMake, DO NOT EDIT\n";
+ makefileStream << cmake::GetCMakeFilesDirectoryPostSlash();
+ makefileStream << "cmake.check_cache: ";
+ for(std::vector<std::string>::const_iterator i = lfiles.begin();
+ i != lfiles.end(); ++i)
+ {
+ makefileStream << "\\\n" << this->ConvertToRelativeForMake(i->c_str());
+ }
+ std::string cmake = mf->GetRequiredDefinition("CMAKE_COMMAND");
+ makefileStream << "\n\t" << this->ConvertToRelativeForMake(cmake.c_str())
+ << " -H" << this->ConvertToRelativeForMake(
+ mf->GetHomeDirectory())
+ << " -B" << this->ConvertToRelativeForMake(
+ mf->GetHomeOutputDirectory()) << "\n";
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalXCodeGenerator::ClearXCodeObjects()
+{
+ this->TargetDoneSet.clear();
+ for(unsigned int i = 0; i < this->XCodeObjects.size(); ++i)
+ {
+ delete this->XCodeObjects[i];
+ }
+ this->XCodeObjects.clear();
+ this->XCodeObjectIDs.clear();
+ this->GroupMap.clear();
+ this->GroupNameMap.clear();
+ this->TargetGroup.clear();
+ this->FileRefs.clear();
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalXCodeGenerator::addObject(cmXCodeObject *obj)
+{
+ if(obj->GetType() == cmXCodeObject::OBJECT)
+ {
+ cmStdString id = obj->GetId();
+
+ // If this is a duplicate id, it's an error:
+ //
+ if(this->XCodeObjectIDs.count(id))
+ {
+ cmSystemTools::Error(
+ "Xcode generator: duplicate object ids not allowed");
+ }
+
+ this->XCodeObjectIDs.insert(id);
+ }
+
+ this->XCodeObjects.push_back(obj);
+}
+
+//----------------------------------------------------------------------------
+cmXCodeObject*
+cmGlobalXCodeGenerator::CreateObject(cmXCodeObject::PBXType ptype)
+{
+ cmXCodeObject* obj;
+ if(this->XcodeVersion == 15)
+ {
+ obj = new cmXCodeObject(ptype, cmXCodeObject::OBJECT);
+ }
+ else
+ {
+ obj = new cmXCode21Object(ptype, cmXCodeObject::OBJECT);
+ }
+ this->addObject(obj);
+ return obj;
+}
+
+//----------------------------------------------------------------------------
+cmXCodeObject*
+cmGlobalXCodeGenerator::CreateObject(cmXCodeObject::Type type)
+{
+ cmXCodeObject* obj = new cmXCodeObject(cmXCodeObject::None, type);
+ this->addObject(obj);
+ return obj;
+}
+
+//----------------------------------------------------------------------------
+cmXCodeObject*
+cmGlobalXCodeGenerator::CreateString(const char* s)
+{
+ cmXCodeObject* obj = this->CreateObject(cmXCodeObject::STRING);
+ obj->SetString(s);
+ return obj;
+}
+
+//----------------------------------------------------------------------------
+cmXCodeObject* cmGlobalXCodeGenerator
+::CreateObjectReference(cmXCodeObject* ref)
+{
+ cmXCodeObject* obj = this->CreateObject(cmXCodeObject::OBJECT_REF);
+ obj->SetObject(ref);
+ return obj;
+}
+
+//----------------------------------------------------------------------------
+cmStdString
+GetGroupMapKeyFromPath(cmTarget& cmtarget, const std::string& fullpath)
+{
+ cmStdString key(cmtarget.GetName());
+ key += "-";
+ key += fullpath;
+ return key;
+}
+
+//----------------------------------------------------------------------------
+cmStdString
+GetGroupMapKey(cmTarget& cmtarget, cmSourceFile* sf)
+{
+ return GetGroupMapKeyFromPath(cmtarget, sf->GetFullPath());
+}
+
+//----------------------------------------------------------------------------
+cmXCodeObject*
+cmGlobalXCodeGenerator::CreateXCodeSourceFileFromPath(
+ const std::string &fullpath,
+ cmTarget& cmtarget,
+ const std::string &lang)
+{
+ // 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);
+
+ cmXCodeObject* buildFile = this->CreateObject(cmXCodeObject::PBXBuildFile);
+ buildFile->SetComment(fileRef->GetComment());
+ buildFile->AddAttribute("fileRef", this->CreateObjectReference(fileRef));
+
+ return buildFile;
+}
+
+//----------------------------------------------------------------------------
+cmXCodeObject*
+cmGlobalXCodeGenerator::CreateXCodeSourceFile(cmLocalGenerator* lg,
+ cmSourceFile* sf,
+ cmTarget& cmtarget)
+{
+ // Add flags from target and source file properties.
+ std::string flags;
+ if(cmtarget.GetProperty("COMPILE_FLAGS"))
+ {
+ lg->AppendFlags(flags, cmtarget.GetProperty("COMPILE_FLAGS"));
+ }
+ const char* srcfmt = sf->GetProperty("Fortran_FORMAT");
+ switch(this->CurrentLocalGenerator->GetFortranFormat(srcfmt))
+ {
+ case cmLocalGenerator::FortranFormatFixed: flags="-fixed "+flags; break;
+ case cmLocalGenerator::FortranFormatFree: flags="-free "+flags; break;
+ default: break;
+ }
+ lg->AppendFlags(flags, sf->GetProperty("COMPILE_FLAGS"));
+
+ // Add per-source definitions.
+ BuildObjectListOrString flagsBuild(this, false);
+ this->AppendDefines(flagsBuild,
+ sf->GetProperty("COMPILE_DEFINITIONS"), true);
+ if (!flagsBuild.IsEmpty())
+ {
+ if (flags.size())
+ {
+ flags += ' ';
+ }
+ flags += flagsBuild.GetString();
+ }
+
+ const char* lang =
+ this->CurrentLocalGenerator->GetSourceFileLanguage(*sf);
+ if (!lang)
+ {
+ lang = "";
+ }
+
+ cmXCodeObject* buildFile =
+ this->CreateXCodeSourceFileFromPath(sf->GetFullPath(), cmtarget, lang);
+ cmXCodeObject* fileRef = buildFile->GetObject("fileRef")->GetObject();
+
+ cmXCodeObject* settings =
+ this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
+ settings->AddAttribute("COMPILER_FLAGS", this->CreateString(flags.c_str()));
+
+ // 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);
+
+ // Is this a "private" or "public" framework header file?
+ // Set the ATTRIBUTES attribute appropriately...
+ //
+ if(cmtarget.IsFrameworkOnApple())
+ {
+ if(tsFlags.Type == cmTarget::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)
+ {
+ cmXCodeObject* attrs = this->CreateObject(cmXCodeObject::OBJECT_LIST);
+ attrs->AddObject(this->CreateString("Public"));
+ settings->AddAttribute("ATTRIBUTES", attrs);
+ isResource = true;
+ }
+ }
+
+ if(cmtarget.IsCFBundleOnApple())
+ {
+ cmtarget.SetProperty("PREFIX", "");
+ cmtarget.SetProperty("SUFFIX", "");
+ }
+
+ // Add the fileRef to the top level Resources group/folder if it is not
+ // already there.
+ //
+ if(isResource && this->ResourcesGroupChildren &&
+ !this->ResourcesGroupChildren->HasObject(fileRef))
+ {
+ this->ResourcesGroupChildren->AddObject(fileRef);
+ }
+
+ buildFile->AddAttribute("settings", settings);
+ return buildFile;
+}
+
+//----------------------------------------------------------------------------
+std::string
+GetSourcecodeValueFromFileExtension(const std::string& _ext,
+ const std::string& lang)
+{
+ std::string ext = cmSystemTools::LowerCase(_ext);
+ std::string sourcecode = "sourcecode";
+
+ if(ext == "o")
+ {
+ sourcecode = "compiled.mach-o.objfile";
+ }
+ else if(ext == "xib")
+ {
+ sourcecode = "file.xib";
+ }
+ else if(ext == "storyboard")
+ {
+ sourcecode = "file.storyboard";
+ }
+ else if(ext == "mm")
+ {
+ sourcecode += ".cpp.objcpp";
+ }
+ else if(ext == "m")
+ {
+ sourcecode += ".c.objc";
+ }
+ else if(ext == "xib")
+ {
+ sourcecode += ".file.xib";
+ }
+ else if(ext == "plist")
+ {
+ sourcecode += ".text.plist";
+ }
+ else if(ext == "h")
+ {
+ sourcecode += ".c.h";
+ }
+ else if(ext == "hxx" || ext == "hpp" || ext == "txx"
+ || ext == "pch" || ext == "hh")
+ {
+ sourcecode += ".cpp.h";
+ }
+ else if(ext == "png" || ext == "gif" || ext == "jpg")
+ {
+ sourcecode = "image";
+ }
+ else if(ext == "txt")
+ {
+ sourcecode += ".text";
+ }
+ else if(lang == "CXX")
+ {
+ sourcecode += ".cpp.cpp";
+ }
+ else if(lang == "C")
+ {
+ sourcecode += ".c.c";
+ }
+ else if(lang == "Fortran")
+ {
+ sourcecode += ".fortran.f90";
+ }
+ //else
+ // {
+ // // Already specialized above or we leave sourcecode == "sourcecode"
+ // // which is probably the most correct choice. Extensionless headers,
+ // // for example... Or file types unknown to Xcode that do not map to a
+ // // valid lastKnownFileType value.
+ // }
+
+ return sourcecode;
+}
+
+//----------------------------------------------------------------------------
+cmXCodeObject*
+cmGlobalXCodeGenerator::CreateXCodeFileReferenceFromPath(
+ const std::string &fullpath,
+ cmTarget& cmtarget,
+ const std::string &lang)
+{
+ std::string fname = fullpath;
+ cmXCodeObject* fileRef = this->FileRefs[fname];
+ if(!fileRef)
+ {
+ fileRef = this->CreateObject(cmXCodeObject::PBXFileReference);
+ std::string comment = fname;
+ fileRef->SetComment(fname.c_str());
+ this->FileRefs[fname] = fileRef;
+ }
+ cmStdString key = GetGroupMapKeyFromPath(cmtarget, fullpath);
+ cmXCodeObject* group = this->GroupMap[key];
+ cmXCodeObject* children = group->GetObject("children");
+ if (!children->HasObject(fileRef))
+ {
+ children->AddObject(fileRef);
+ }
+ fileRef->AddAttribute("fileEncoding", this->CreateString("4"));
+
+ // Compute the extension.
+ std::string ext;
+ std::string realExt =
+ cmSystemTools::GetFilenameLastExtension(fullpath);
+ if(!realExt.empty())
+ {
+ // Extension without the leading '.'.
+ ext = realExt.substr(1);
+ }
+
+ std::string sourcecode = GetSourcecodeValueFromFileExtension(ext, lang);
+
+ fileRef->AddAttribute("lastKnownFileType",
+ this->CreateString(sourcecode.c_str()));
+
+ // Store the file path relative to the top of the source tree.
+ std::string path = this->RelativeToSource(fullpath.c_str());
+ std::string name = cmSystemTools::GetFilenameName(path.c_str());
+ const char* sourceTree = (cmSystemTools::FileIsFullPath(path.c_str())?
+ "<absolute>" : "SOURCE_ROOT");
+ fileRef->AddAttribute("name", this->CreateString(name.c_str()));
+ fileRef->AddAttribute("path", this->CreateString(path.c_str()));
+ fileRef->AddAttribute("sourceTree", this->CreateString(sourceTree));
+ if(this->XcodeVersion == 15)
+ {
+ fileRef->AddAttribute("refType", this->CreateString("4"));
+ }
+ return fileRef;
+}
+
+//----------------------------------------------------------------------------
+cmXCodeObject*
+cmGlobalXCodeGenerator::CreateXCodeFileReference(cmSourceFile* sf,
+ cmTarget& cmtarget)
+{
+ const char* lang =
+ this->CurrentLocalGenerator->GetSourceFileLanguage(*sf);
+ if (!lang)
+ {
+ lang = "";
+ }
+
+ return this->CreateXCodeFileReferenceFromPath(
+ sf->GetFullPath(), cmtarget, lang);
+}
+
+//----------------------------------------------------------------------------
+bool cmGlobalXCodeGenerator::SpecialTargetEmitted(std::string const& tname)
+{
+ if(tname == "ALL_BUILD" || tname == "XCODE_DEPEND_HELPER" ||
+ tname == "install" || tname == "package" || tname == "RUN_TESTS" ||
+ tname == CMAKE_CHECK_BUILD_SYSTEM_TARGET )
+ {
+ if(this->TargetDoneSet.find(tname) != this->TargetDoneSet.end())
+ {
+ return true;
+ }
+ this->TargetDoneSet.insert(tname);
+ return false;
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalXCodeGenerator::SetCurrentLocalGenerator(cmLocalGenerator* gen)
+{
+ this->CurrentLocalGenerator = gen;
+ this->CurrentMakefile = gen->GetMakefile();
+ std::string outdir =
+ cmSystemTools::CollapseFullPath(this->CurrentMakefile->
+ GetCurrentOutputDirectory());
+ cmSystemTools::SplitPath(outdir.c_str(),
+ this->CurrentOutputDirectoryComponents);
+
+ // Select the current set of configuration types.
+ this->CurrentConfigurationTypes.clear();
+ this->CurrentMakefile->GetConfigurations(this->CurrentConfigurationTypes);
+ if(this->CurrentConfigurationTypes.empty())
+ {
+ this->CurrentConfigurationTypes.push_back("");
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+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++)
+ {
+ cmTarget& cmtarget = l->second;
+
+ // make sure ALL_BUILD, INSTALL, etc are only done once
+ if(this->SpecialTargetEmitted(l->first.c_str()))
+ {
+ continue;
+ }
+
+ if(cmtarget.GetType() == cmTarget::UTILITY ||
+ cmtarget.GetType() == cmTarget::GLOBAL_TARGET)
+ {
+ targets.push_back(this->CreateUtilityTarget(cmtarget));
+ continue;
+ }
+
+ // organize the sources
+ std::vector<cmSourceFile*> const &classes = cmtarget.GetSourceFiles();
+ std::vector<cmXCodeObject*> externalObjFiles;
+ std::vector<cmXCodeObject*> headerFiles;
+ std::vector<cmXCodeObject*> resourceFiles;
+ std::vector<cmXCodeObject*> sourceFiles;
+ for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
+ i != classes.end(); ++i)
+ {
+ cmXCodeObject* xsf =
+ this->CreateXCodeSourceFile(this->CurrentLocalGenerator,
+ *i, cmtarget);
+ cmXCodeObject* fr = xsf->GetObject("fileRef");
+ cmXCodeObject* filetype =
+ fr->GetObject()->GetObject("lastKnownFileType");
+
+ cmTarget::SourceFileFlags tsFlags =
+ cmtarget.GetTargetSourceFileFlags(*i);
+
+ if(strcmp(filetype->GetString(), "compiled.mach-o.objfile") == 0)
+ {
+ externalObjFiles.push_back(xsf);
+ }
+ else if(this->IsHeaderFile(*i) ||
+ (tsFlags.Type == cmTarget::SourceFileTypePrivateHeader) ||
+ (tsFlags.Type == cmTarget::SourceFileTypePublicHeader))
+ {
+ headerFiles.push_back(xsf);
+ }
+ else if(tsFlags.Type == cmTarget::SourceFileTypeResource)
+ {
+ resourceFiles.push_back(xsf);
+ }
+ else if(!(*i)->GetPropertyAsBool("HEADER_FILE_ONLY"))
+ {
+ // 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) &&
+ !this->IgnoreFile((*i)->GetExtension().c_str()))
+ {
+ sourceFiles.push_back(xsf);
+ }
+ }
+ }
+
+ // Add object library contents as external objects. (Equivalent to
+ // the externalObjFiles above, except each one is not a cmSourceFile
+ // within the target.)
+ std::vector<std::string> objs;
+ this->GetGeneratorTarget(&cmtarget)->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, "");
+ 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();
+
+ cmXCodeObject* buildFiles = 0;
+
+ // create source build phase
+ cmXCodeObject* sourceBuildPhase = 0;
+ if (!sourceFiles.empty())
+ {
+ sourceBuildPhase =
+ this->CreateObject(cmXCodeObject::PBXSourcesBuildPhase);
+ sourceBuildPhase->SetComment("Sources");
+ sourceBuildPhase->AddAttribute("buildActionMask",
+ this->CreateString("2147483647"));
+ buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
+ for(std::vector<cmXCodeObject*>::iterator i = sourceFiles.begin();
+ i != sourceFiles.end(); ++i)
+ {
+ buildFiles->AddObject(*i);
+ }
+ sourceBuildPhase->AddAttribute("files", buildFiles);
+ sourceBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing",
+ this->CreateString("0"));
+ }
+
+ // create header build phase - only for framework targets
+ cmXCodeObject* headerBuildPhase = 0;
+ if (!headerFiles.empty() && isFrameworkTarget)
+ {
+ headerBuildPhase =
+ this->CreateObject(cmXCodeObject::PBXHeadersBuildPhase);
+ headerBuildPhase->SetComment("Headers");
+ headerBuildPhase->AddAttribute("buildActionMask",
+ this->CreateString("2147483647"));
+ buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
+ for(std::vector<cmXCodeObject*>::iterator i = headerFiles.begin();
+ i != headerFiles.end(); ++i)
+ {
+ buildFiles->AddObject(*i);
+ }
+ headerBuildPhase->AddAttribute("files", buildFiles);
+ headerBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing",
+ this->CreateString("0"));
+ }
+
+ // create resource build phase - only for framework or bundle targets
+ cmXCodeObject* resourceBuildPhase = 0;
+ if (!resourceFiles.empty() &&
+ (isFrameworkTarget || isBundleTarget || isCFBundleTarget))
+ {
+ resourceBuildPhase =
+ this->CreateObject(cmXCodeObject::PBXResourcesBuildPhase);
+ resourceBuildPhase->SetComment("Resources");
+ resourceBuildPhase->AddAttribute("buildActionMask",
+ this->CreateString("2147483647"));
+ buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
+ for(std::vector<cmXCodeObject*>::iterator i = resourceFiles.begin();
+ i != resourceFiles.end(); ++i)
+ {
+ buildFiles->AddObject(*i);
+ }
+ resourceBuildPhase->AddAttribute("files", buildFiles);
+ resourceBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing",
+ this->CreateString("0"));
+ }
+
+ // create vector of "non-resource content file" build phases - only for
+ // framework or bundle targets
+ std::vector<cmXCodeObject*> contentBuildPhases;
+ if (isFrameworkTarget || isBundleTarget || isCFBundleTarget)
+ {
+ typedef std::map<cmStdString, 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)
+ {
+ bundleFiles[tsFlags.MacFolder].push_back(*i);
+ }
+ }
+ mapOfVectorOfSourceFiles::iterator mit;
+ for ( mit = bundleFiles.begin(); mit != bundleFiles.end(); ++ mit )
+ {
+ cmXCodeObject* copyFilesBuildPhase =
+ this->CreateObject(cmXCodeObject::PBXCopyFilesBuildPhase);
+ copyFilesBuildPhase->SetComment("Copy files");
+ copyFilesBuildPhase->AddAttribute("buildActionMask",
+ this->CreateString("2147483647"));
+ copyFilesBuildPhase->AddAttribute("dstSubfolderSpec",
+ this->CreateString("6"));
+ cmOStringStream ostr;
+ if (cmtarget.IsFrameworkOnApple())
+ {
+ // dstPath in frameworks is relative to Versions/<version>
+ ostr << mit->first;
+ }
+ else if ( mit->first != "MacOS" )
+ {
+ // dstPath in bundles is relative to Contents/MacOS
+ ostr << "../" << mit->first.c_str();
+ }
+ copyFilesBuildPhase->AddAttribute("dstPath",
+ this->CreateString(ostr.str().c_str()));
+ copyFilesBuildPhase->AddAttribute(
+ "runOnlyForDeploymentPostprocessing", this->CreateString("0"));
+ buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
+ copyFilesBuildPhase->AddAttribute("files", buildFiles);
+ std::vector<cmSourceFile*>::iterator sfIt;
+ for ( sfIt = mit->second.begin(); sfIt != mit->second.end(); ++ sfIt )
+ {
+ cmXCodeObject* xsf =
+ this->CreateXCodeSourceFile(this->CurrentLocalGenerator,
+ *sfIt, cmtarget);
+ buildFiles->AddObject(xsf);
+ }
+ contentBuildPhases.push_back(copyFilesBuildPhase);
+ }
+ }
+
+ // create framework build phase
+ cmXCodeObject* frameworkBuildPhase = 0;
+ if (!externalObjFiles.empty())
+ {
+ frameworkBuildPhase =
+ this->CreateObject(cmXCodeObject::PBXFrameworksBuildPhase);
+ frameworkBuildPhase->SetComment("Frameworks");
+ frameworkBuildPhase->AddAttribute("buildActionMask",
+ this->CreateString("2147483647"));
+ buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
+ frameworkBuildPhase->AddAttribute("files", buildFiles);
+ for(std::vector<cmXCodeObject*>::iterator i = externalObjFiles.begin();
+ i != externalObjFiles.end(); ++i)
+ {
+ buildFiles->AddObject(*i);
+ }
+ frameworkBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing",
+ this->CreateString("0"));
+ }
+
+ // create list of build phases and create the Xcode target
+ cmXCodeObject* buildPhases =
+ this->CreateObject(cmXCodeObject::OBJECT_LIST);
+
+ this->CreateCustomCommands(buildPhases, sourceBuildPhase,
+ headerBuildPhase, resourceBuildPhase,
+ contentBuildPhases,
+ frameworkBuildPhase, cmtarget);
+
+ targets.push_back(this->CreateXCodeTarget(cmtarget, buildPhases));
+ }
+}
+
+//----------------------------------------------------------------------------
+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)
+ {
+ this->ForceLinkerLanguage(*ti->second);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalXCodeGenerator::ForceLinkerLanguage(cmTarget& cmtarget)
+{
+ // This matters only for targets that link.
+ if(cmtarget.GetType() != cmTarget::EXECUTABLE &&
+ cmtarget.GetType() != cmTarget::SHARED_LIBRARY &&
+ cmtarget.GetType() != cmTarget::MODULE_LIBRARY)
+ {
+ return;
+ }
+
+ const char* llang = cmtarget.GetLinkerLanguage("NOCONFIG");
+ if(!llang) { return; }
+
+ // If the language is compiled as a source trust Xcode to link with it.
+ cmTarget::LinkImplementation const* impl =
+ cmtarget.GetLinkImplementation("NOCONFIG");
+ for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
+ li != impl->Languages.end(); ++li)
+ {
+ if(*li == llang) { return; }
+ }
+
+ // 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();
+ fname += cmake::GetCMakeFilesDirectory();
+ fname += "/";
+ fname += cmtarget.GetName();
+ fname += "-CMakeForceLinker";
+ fname += ".";
+ fname += cmSystemTools::LowerCase(llang);
+ {
+ cmGeneratedFileStream fout(fname.c_str());
+ fout << "\n";
+ }
+ if(cmSourceFile* sf = mf->GetOrCreateSource(fname.c_str()))
+ {
+ sf->SetProperty("LANGUAGE", llang);
+ cmtarget.AddSourceFile(sf);
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmGlobalXCodeGenerator::IsHeaderFile(cmSourceFile* sf)
+{
+ const std::vector<std::string>& hdrExts =
+ this->CurrentMakefile->GetHeaderExtensions();
+ return (std::find(hdrExts.begin(), hdrExts.end(), sf->GetExtension()) !=
+ hdrExts.end());
+}
+
+//----------------------------------------------------------------------------
+cmXCodeObject*
+cmGlobalXCodeGenerator::CreateBuildPhase(const char* name,
+ const char* name2,
+ cmTarget& cmtarget,
+ const std::vector<cmCustomCommand>&
+ commands)
+{
+ if(commands.size() == 0 && strcmp(name, "CMake ReRun") != 0)
+ {
+ return 0;
+ }
+ cmXCodeObject* buildPhase =
+ this->CreateObject(cmXCodeObject::PBXShellScriptBuildPhase);
+ buildPhase->AddAttribute("buildActionMask",
+ this->CreateString("2147483647"));
+ cmXCodeObject* buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
+ buildPhase->AddAttribute("files", buildFiles);
+ buildPhase->AddAttribute("name",
+ this->CreateString(name));
+ buildPhase->AddAttribute("runOnlyForDeploymentPostprocessing",
+ this->CreateString("0"));
+ buildPhase->AddAttribute("shellPath",
+ this->CreateString("/bin/sh"));
+ this->AddCommandsToBuildPhase(buildPhase, cmtarget, commands,
+ name2);
+ return buildPhase;
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalXCodeGenerator::CreateCustomCommands(cmXCodeObject* buildPhases,
+ cmXCodeObject*
+ sourceBuildPhase,
+ cmXCodeObject*
+ headerBuildPhase,
+ cmXCodeObject*
+ resourceBuildPhase,
+ std::vector<cmXCodeObject*>
+ contentBuildPhases,
+ cmXCodeObject*
+ frameworkBuildPhase,
+ cmTarget& cmtarget)
+{
+ std::vector<cmCustomCommand> const & prebuild
+ = cmtarget.GetPreBuildCommands();
+ std::vector<cmCustomCommand> const & prelink
+ = cmtarget.GetPreLinkCommands();
+ std::vector<cmCustomCommand> const & postbuild
+ = cmtarget.GetPostBuildCommands();
+ std::vector<cmSourceFile*>const &classes = cmtarget.GetSourceFiles();
+ // add all the sources
+ std::vector<cmCustomCommand> commands;
+ for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
+ i != classes.end(); ++i)
+ {
+ if((*i)->GetCustomCommand())
+ {
+ commands.push_back(*(*i)->GetCustomCommand());
+ }
+ }
+ // create prebuild phase
+ cmXCodeObject* cmakeRulesBuildPhase =
+ this->CreateBuildPhase("CMake Rules",
+ "cmakeRulesBuildPhase",
+ cmtarget, commands);
+ // create prebuild phase
+ cmXCodeObject* preBuildPhase =
+ this->CreateBuildPhase("CMake PreBuild Rules", "preBuildCommands",
+ cmtarget, prebuild);
+ // create prelink phase
+ cmXCodeObject* preLinkPhase =
+ this->CreateBuildPhase("CMake PreLink Rules", "preLinkCommands",
+ cmtarget, prelink);
+ // create postbuild phase
+ cmXCodeObject* postBuildPhase =
+ this->CreateBuildPhase("CMake PostBuild Rules", "postBuildPhase",
+ cmtarget, postbuild);
+
+ // The order here is the order they will be built in.
+ // The order "headers, resources, sources" mimics a native project generated
+ // from an xcode template...
+ //
+ if(preBuildPhase)
+ {
+ buildPhases->AddObject(preBuildPhase);
+ }
+ if(cmakeRulesBuildPhase)
+ {
+ buildPhases->AddObject(cmakeRulesBuildPhase);
+ }
+ if(headerBuildPhase)
+ {
+ buildPhases->AddObject(headerBuildPhase);
+ }
+ if(resourceBuildPhase)
+ {
+ buildPhases->AddObject(resourceBuildPhase);
+ }
+ std::vector<cmXCodeObject*>::iterator cit;
+ for (cit = contentBuildPhases.begin(); cit != contentBuildPhases.end();
+ ++cit)
+ {
+ buildPhases->AddObject(*cit);
+ }
+ if(sourceBuildPhase)
+ {
+ buildPhases->AddObject(sourceBuildPhase);
+ }
+ if(preLinkPhase)
+ {
+ buildPhases->AddObject(preLinkPhase);
+ }
+ if(frameworkBuildPhase)
+ {
+ buildPhases->AddObject(frameworkBuildPhase);
+ }
+ if(postBuildPhase)
+ {
+ buildPhases->AddObject(postBuildPhase);
+ }
+}
+
+//----------------------------------------------------------------------------
+// This function removes each occurence of the flag and returns the last one
+// (i.e., the dominant flag in GCC)
+std::string cmGlobalXCodeGenerator::ExtractFlag(const char* flag,
+ std::string& flags)
+{
+ std::string retFlag;
+ std::string::size_type pos = flags.rfind(flag);
+ bool saved = false;
+ while(pos != flags.npos)
+ {
+ if(pos == 0 || flags[pos-1]==' ')
+ {
+ while(pos < flags.size() && flags[pos] != ' ')
+ {
+ if(!saved)
+ {
+ retFlag += flags[pos];
+ }
+ flags[pos] = ' ';
+ pos++;
+ }
+ }
+ saved = true;
+ pos = flags.rfind(flag);
+ }
+ return retFlag;
+}
+
+//----------------------------------------------------------------------------
+void
+cmGlobalXCodeGenerator::AddCommandsToBuildPhase(cmXCodeObject* buildphase,
+ cmTarget& target,
+ std::vector<cmCustomCommand>
+ const & commands,
+ const char* name)
+{
+
+ // 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)
+ {
+ 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;
+ }
+ }
+ }
+ }
+
+ std::string dir = this->CurrentMakefile->GetCurrentOutputDirectory();
+ dir += "/CMakeScripts";
+ cmSystemTools::MakeDirectory(dir.c_str());
+ std::string makefile = dir;
+ makefile += "/";
+ makefile += target.GetName();
+ makefile += "_";
+ makefile += name;
+ makefile += ".make";
+
+ for (std::vector<std::string>::const_iterator currentConfig=
+ this->CurrentConfigurationTypes.begin();
+ currentConfig!=this->CurrentConfigurationTypes.end();
+ currentConfig++ )
+ {
+ this->CreateCustomRulesMakefile(makefile.c_str(),
+ target,
+ commands,
+ currentConfig->c_str(),
+ multipleOutputPairs);
+ }
+
+ std::string cdir = this->CurrentMakefile->GetCurrentOutputDirectory();
+ cdir = this->ConvertToRelativeForXCode(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",
+ this->CreateString("0"));
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalXCodeGenerator
+::CreateCustomRulesMakefile(const char* makefileBasename,
+ cmTarget& target,
+ std::vector<cmCustomCommand>
+ const & commands,
+ const char* configName,
+ const std::map<cmStdString,
+ cmStdString>& multipleOutputPairs
+ )
+{
+ std::string makefileName=makefileBasename;
+ if(this->XcodeVersion > 20)
+ {
+ makefileName+=configName;
+ }
+ cmGeneratedFileStream makefileStream(makefileName.c_str());
+ if(!makefileStream)
+ {
+ return;
+ }
+ makefileStream.SetCopyIfDifferent(true);
+ makefileStream << "# Generated by CMake, DO NOT EDIT\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;
+ int count = 0;
+ for(std::vector<cmCustomCommand>::const_iterator i = commands.begin();
+ i != commands.end(); ++i)
+ {
+ cmCustomCommand const& cc = *i;
+ if(!cc.GetCommandLines().empty())
+ {
+ const std::vector<std::string>& outputs = cc.GetOutputs();
+ if(!outputs.empty())
+ {
+ for(std::vector<std::string>::const_iterator o = outputs.begin();
+ o != outputs.end(); ++o)
+ {
+ makefileStream
+ << "\\\n\t" << this->ConvertToRelativeForMake(o->c_str());
+ }
+ }
+ else
+ {
+ cmOStringStream str;
+ str << "_buildpart_" << count++ ;
+ tname[&cc] = std::string(target.GetName()) + str.str();
+ makefileStream << "\\\n\t" << tname[&cc];
+ }
+ }
+ }
+ makefileStream << "\n\n";
+ for(std::vector<cmCustomCommand>::const_iterator i = commands.begin();
+ i != commands.end(); ++i)
+ {
+ cmCustomCommand const& cc = *i;
+ if(!cc.GetCommandLines().empty())
+ {
+ cmCustomCommandGenerator ccg(cc, configName, this->CurrentMakefile);
+ makefileStream << "\n";
+ const std::vector<std::string>& outputs = cc.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 << ": ";
+ }
+ else
+ {
+ // There are no outputs. Use the generated force rule name.
+ makefileStream << tname[&cc] << ": ";
+ }
+ for(std::vector<std::string>::const_iterator d =
+ cc.GetDepends().begin();
+ d != cc.GetDepends().end(); ++d)
+ {
+ std::string dep;
+ if(this->CurrentLocalGenerator
+ ->GetRealDependency(d->c_str(), configName, dep))
+ {
+ makefileStream << "\\\n" <<
+ this->ConvertToRelativeForMake(dep.c_str());
+ }
+ }
+ makefileStream << "\n";
+
+ if(const char* comment = cc.GetComment())
+ {
+ std::string echo_cmd = "echo ";
+ echo_cmd += (this->CurrentLocalGenerator->
+ EscapeForShell(comment, cc.GetEscapeAllowMakeVars()));
+ makefileStream << "\t" << echo_cmd.c_str() << "\n";
+ }
+
+ // Add each command line to the set of commands.
+ for(unsigned int c = 0; c < ccg.GetNumberOfCommands(); ++c)
+ {
+ // Build the command line in a single string.
+ std::string cmd2 = ccg.GetCommand(c);
+ cmSystemTools::ReplaceString(cmd2, "/./", "/");
+ cmd2 = this->ConvertToRelativeForMake(cmd2.c_str());
+ std::string cmd;
+ if(cc.GetWorkingDirectory())
+ {
+ cmd += "cd ";
+ cmd += this->ConvertToRelativeForMake(cc.GetWorkingDirectory());
+ cmd += " && ";
+ }
+ cmd += cmd2;
+ ccg.AppendArguments(c, cmd);
+ makefileStream << "\t" << cmd.c_str() << "\n";
+ }
+ }
+ }
+
+ // 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)
+{
+ std::string flags;
+ 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) ||
+ shared);
+
+ const char* lang = target.GetLinkerLanguage(configName);
+ std::string cflags;
+ if(lang)
+ {
+ // 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");
+ }
+
+ // Add language-specific flags.
+ this->CurrentLocalGenerator->AddLanguageFlags(flags, lang, configName);
+
+ // Add shared-library flags if needed.
+ this->CurrentLocalGenerator->AddCMP0018Flags(flags, &target, lang);
+ }
+ else if(binary)
+ {
+ cmSystemTools::Error
+ ("CMake can not determine linker language for target:",
+ target.GetName());
+ return;
+ }
+
+ // Add define flags
+ this->CurrentLocalGenerator->
+ AppendFlags(defFlags,
+ this->CurrentMakefile->GetDefineFlags());
+
+ // Add preprocessor definitions for this target and configuration.
+ BuildObjectListOrString ppDefs(this, this->XcodeVersion >= 30);
+ if(this->XcodeVersion > 15)
+ {
+ this->AppendDefines(ppDefs,
+ "CMAKE_INTDIR=\"$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)\"");
+ }
+ if(const char* exportMacro = target.GetExportMacro())
+ {
+ // Add the export symbol definition for shared library objects.
+ this->AppendDefines(ppDefs, exportMacro);
+ }
+ this->AppendDefines
+ (ppDefs, this->CurrentMakefile->GetProperty("COMPILE_DEFINITIONS"));
+ this->AppendDefines(ppDefs, target.GetProperty("COMPILE_DEFINITIONS"));
+ if(configName)
+ {
+ std::string defVarName = "COMPILE_DEFINITIONS_";
+ defVarName += cmSystemTools::UpperCase(configName);
+ this->AppendDefines
+ (ppDefs, this->CurrentMakefile->GetProperty(defVarName.c_str()));
+ this->AppendDefines(ppDefs, target.GetProperty(defVarName.c_str()));
+ }
+ buildSettings->AddAttribute
+ ("GCC_PREPROCESSOR_DEFINITIONS", ppDefs.CreateList());
+
+ std::string extraLinkOptions;
+ if(target.GetType() == cmTarget::EXECUTABLE)
+ {
+ extraLinkOptions =
+ this->CurrentMakefile->GetRequiredDefinition("CMAKE_EXE_LINKER_FLAGS");
+ std::string var = "CMAKE_EXE_LINKER_FLAGS_";
+ var += cmSystemTools::UpperCase(configName);
+ std::string val =
+ this->CurrentMakefile->GetSafeDefinition(var.c_str());
+ if(val.size())
+ {
+ extraLinkOptions += " ";
+ extraLinkOptions += val;
+ }
+ }
+ if(target.GetType() == cmTarget::SHARED_LIBRARY)
+ {
+ extraLinkOptions = this->CurrentMakefile->
+ GetRequiredDefinition("CMAKE_SHARED_LINKER_FLAGS");
+ }
+ if(target.GetType() == cmTarget::MODULE_LIBRARY)
+ {
+ extraLinkOptions = this->CurrentMakefile->
+ GetRequiredDefinition("CMAKE_MODULE_LINKER_FLAGS");
+ }
+
+ const char* linkFlagsProp = "LINK_FLAGS";
+ if(target.GetType() == cmTarget::OBJECT_LIBRARY ||
+ target.GetType() == cmTarget::STATIC_LIBRARY)
+ {
+ linkFlagsProp = "STATIC_LIBRARY_FLAGS";
+ }
+ const char* targetLinkFlags = target.GetProperty(linkFlagsProp);
+ if(targetLinkFlags)
+ {
+ extraLinkOptions += " ";
+ extraLinkOptions += targetLinkFlags;
+ }
+ if(configName && *configName)
+ {
+ std::string linkFlagsVar = linkFlagsProp;
+ linkFlagsVar += "_";
+ linkFlagsVar += cmSystemTools::UpperCase(configName);
+ if(const char* linkFlags = target.GetProperty(linkFlagsVar.c_str()))
+ {
+ extraLinkOptions += " ";
+ extraLinkOptions += linkFlags;
+ }
+ }
+
+ // Set target-specific architectures.
+ std::vector<std::string> archs;
+ target.GetAppleArchs(configName, archs);
+ if(!archs.empty())
+ {
+ // Enable ARCHS attribute.
+ buildSettings->AddAttribute("ONLY_ACTIVE_ARCH",
+ this->CreateString("NO"));
+
+ // Store ARCHS value.
+ if(archs.size() == 1)
+ {
+ buildSettings->AddAttribute("ARCHS",
+ this->CreateString(archs[0].c_str()));
+ }
+ else
+ {
+ cmXCodeObject* archObjects =
+ this->CreateObject(cmXCodeObject::OBJECT_LIST);
+ for(std::vector<std::string>::iterator i = archs.begin();
+ i != archs.end(); i++)
+ {
+ archObjects->AddObject(this->CreateString((*i).c_str()));
+ }
+ buildSettings->AddAttribute("ARCHS", archObjects);
+ }
+ }
+
+ // Get the product name components.
+ std::string pnprefix;
+ std::string pnbase;
+ std::string pnsuffix;
+
+ target.GetFullNameComponents(pnprefix, pnbase, pnsuffix, configName);
+
+ // 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)
+ {
+ if(this->XcodeVersion >= 21)
+ {
+ if(!target.UsesDefaultOutputDir(configName, false))
+ {
+ std::string pncdir = target.GetDirectory(configName);
+ buildSettings->AddAttribute("CONFIGURATION_BUILD_DIR",
+ this->CreateString(pncdir.c_str()));
+ }
+ }
+ else
+ {
+ buildSettings->AddAttribute("OBJROOT",
+ this->CreateString(pndir.c_str()));
+ pndir = target.GetDirectory(configName);
+ }
+
+ buildSettings->AddAttribute("EXECUTABLE_PREFIX",
+ this->CreateString(pnprefix.c_str()));
+ buildSettings->AddAttribute("EXECUTABLE_SUFFIX",
+ this->CreateString(pnsuffix.c_str()));
+ }
+ else if(target.GetType() == cmTarget::OBJECT_LIBRARY)
+ {
+ pnprefix = "lib";
+ pnbase = target.GetName();
+ pnsuffix = ".a";
+
+ if(this->XcodeVersion >= 21)
+ {
+ std::string pncdir = this->GetObjectsNormalDirectory(
+ this->CurrentProject, configName, &target);
+ buildSettings->AddAttribute("CONFIGURATION_BUILD_DIR",
+ this->CreateString(pncdir.c_str()));
+ }
+ else
+ {
+ buildSettings->AddAttribute("OBJROOT",
+ this->CreateString(pndir.c_str()));
+ pndir = this->GetObjectsNormalDirectory(
+ this->CurrentProject, configName, &target);
+ }
+ }
+
+ // Store the product name for all target types.
+ buildSettings->AddAttribute("PRODUCT_NAME",
+ this->CreateString(pnbase.c_str()));
+ buildSettings->AddAttribute("SYMROOT",
+ this->CreateString(pndir.c_str()));
+
+ // Handle settings for each target type.
+ switch(target.GetType())
+ {
+ case cmTarget::OBJECT_LIBRARY:
+ case cmTarget::STATIC_LIBRARY:
+ {
+ buildSettings->AddAttribute("LIBRARY_STYLE",
+ this->CreateString("STATIC"));
+ break;
+ }
+
+ case cmTarget::MODULE_LIBRARY:
+ {
+ buildSettings->AddAttribute("LIBRARY_STYLE",
+ this->CreateString("BUNDLE"));
+ if (target.GetPropertyAsBool("BUNDLE"))
+ {
+ // 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",
+ "-bundle");
+ if(!createFlags.empty())
+ {
+ extraLinkOptions += " ";
+ extraLinkOptions += createFlags;
+ }
+ std::string plist = this->ComputeInfoPListLocation(target);
+ // 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)",
+ plist.c_str());
+ std::string path =
+ this->ConvertToRelativeForXCode(plist.c_str());
+ buildSettings->AddAttribute("INFOPLIST_FILE",
+ this->CreateString(path.c_str()));
+ }
+ else if(this->XcodeVersion >= 22)
+ {
+ buildSettings->AddAttribute("MACH_O_TYPE",
+ this->CreateString("mh_bundle"));
+ buildSettings->AddAttribute("GCC_DYNAMIC_NO_PIC",
+ this->CreateString("NO"));
+ // Add the flags to create an executable.
+ std::string createFlags =
+ this->LookupFlags("CMAKE_", lang, "_LINK_FLAGS", "");
+ if(!createFlags.empty())
+ {
+ extraLinkOptions += " ";
+ extraLinkOptions += createFlags;
+ }
+ }
+ else
+ {
+ // Add the flags to create a module.
+ std::string createFlags =
+ this->LookupFlags("CMAKE_SHARED_MODULE_CREATE_", lang, "_FLAGS",
+ "-bundle");
+ if(!createFlags.empty())
+ {
+ extraLinkOptions += " ";
+ extraLinkOptions += createFlags;
+ }
+ }
+ break;
+ }
+ case cmTarget::SHARED_LIBRARY:
+ {
+ if(target.GetPropertyAsBool("FRAMEWORK"))
+ {
+ std::string version = target.GetFrameworkVersion();
+ buildSettings->AddAttribute("FRAMEWORK_VERSION",
+ this->CreateString(version.c_str()));
+
+ std::string plist = this->ComputeInfoPListLocation(target);
+ // 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)",
+ plist.c_str());
+ std::string path =
+ this->ConvertToRelativeForXCode(plist.c_str());
+ buildSettings->AddAttribute("INFOPLIST_FILE",
+ this->CreateString(path.c_str()));
+ }
+ else
+ {
+ // Add the flags to create a shared library.
+ std::string createFlags =
+ this->LookupFlags("CMAKE_SHARED_LIBRARY_CREATE_", lang, "_FLAGS",
+ "-dynamiclib");
+ if(!createFlags.empty())
+ {
+ extraLinkOptions += " ";
+ extraLinkOptions += createFlags;
+ }
+ }
+
+ buildSettings->AddAttribute("LIBRARY_STYLE",
+ this->CreateString("DYNAMIC"));
+ break;
+ }
+ case cmTarget::EXECUTABLE:
+ {
+ // Add the flags to create an executable.
+ std::string createFlags =
+ this->LookupFlags("CMAKE_", lang, "_LINK_FLAGS", "");
+ if(!createFlags.empty())
+ {
+ extraLinkOptions += " ";
+ extraLinkOptions += createFlags;
+ }
+
+ // Handle bundles and normal executables separately.
+ if(target.GetPropertyAsBool("MACOSX_BUNDLE"))
+ {
+ std::string plist = this->ComputeInfoPListLocation(target);
+ // 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)",
+ plist.c_str());
+ std::string path =
+ this->ConvertToRelativeForXCode(plist.c_str());
+ buildSettings->AddAttribute("INFOPLIST_FILE",
+ this->CreateString(path.c_str()));
+
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ if(this->XcodeVersion >= 22 && this->XcodeVersion < 40)
+ {
+ buildSettings->AddAttribute("PREBINDING",
+ this->CreateString("NO"));
+ }
+
+ BuildObjectListOrString dirs(this, this->XcodeVersion >= 30);
+ BuildObjectListOrString fdirs(this, this->XcodeVersion >= 30);
+ std::vector<std::string> includes;
+ this->CurrentLocalGenerator->GetIncludeDirectories(includes, &target);
+ std::set<cmStdString> emitted;
+ emitted.insert("/System/Library/Frameworks");
+ for(std::vector<std::string>::iterator i = includes.begin();
+ i != includes.end(); ++i)
+ {
+ if(this->NameResolvesToFramework(i->c_str()))
+ {
+ std::string frameworkDir = *i;
+ frameworkDir += "/../";
+ frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir.c_str());
+ if(emitted.insert(frameworkDir).second)
+ {
+ fdirs.Add(this->XCodeEscapePath(frameworkDir.c_str()).c_str());
+ }
+ }
+ else
+ {
+ std::string incpath =
+ this->XCodeEscapePath(i->c_str());
+ dirs.Add(incpath.c_str());
+ }
+ }
+ std::vector<std::string>& frameworks = target.GetFrameworks();
+ if(frameworks.size())
+ {
+ for(std::vector<std::string>::iterator fmIt = frameworks.begin();
+ fmIt != frameworks.end(); ++fmIt)
+ {
+ if(emitted.insert(*fmIt).second)
+ {
+ fdirs.Add(this->XCodeEscapePath(fmIt->c_str()).c_str());
+ }
+ }
+ }
+ if(!fdirs.IsEmpty())
+ {
+ buildSettings->AddAttribute("FRAMEWORK_SEARCH_PATHS",
+ fdirs.CreateList());
+ }
+ if(!dirs.IsEmpty())
+ {
+ 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")
+ {
+ flags += " ";
+ flags += 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 )
+ {
+ cflags += " ";
+ cflags += gflagc;
+ flags += " ";
+ flags += gflag;
+ debugStr = "NO";
+ }
+ if( gflag == "-g0" || gflag.size() == 0 )
+ {
+ debugStr = "NO";
+ }
+
+ buildSettings->AddAttribute("GCC_GENERATE_DEBUGGING_SYMBOLS",
+ this->CreateString(debugStr));
+ buildSettings->AddAttribute("GCC_OPTIMIZATION_LEVEL",
+ this->CreateString(optLevel));
+ buildSettings->AddAttribute("GCC_SYMBOLS_PRIVATE_EXTERN",
+ 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
+ {
+ flags += " ";
+ flags += defFlags;
+ 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");
+ switch(this->CurrentLocalGenerator->GetFortranFormat(tgtfmt))
+ {
+ case cmLocalGenerator::FortranFormatFixed: format = "fixed"; break;
+ case cmLocalGenerator::FortranFormatFree: format = "free"; break;
+ default: break;
+ }
+ if(format)
+ {
+ buildSettings->AddAttribute("IFORT_LANG_SRCFMT",
+ this->CreateString(format));
+ }
+
+ // Create the INSTALL_PATH attribute.
+ std::string install_name_dir;
+ if(target.GetType() == cmTarget::SHARED_LIBRARY)
+ {
+ // Get the install_name directory for the build tree.
+ install_name_dir = target.GetInstallNameDirForBuildTree(configName, true);
+ if(install_name_dir.empty())
+ {
+ // Xcode will not pass the -install_name option at all if INSTALL_PATH
+ // is not given or is empty. We must explicitly put the flag in the
+ // link flags to create an install_name with just the library soname.
+ extraLinkOptions += " -install_name ";
+ extraLinkOptions += target.GetFullName(configName);
+ }
+ else
+ {
+ // Convert to a path for the native build tool.
+ cmSystemTools::ConvertToUnixSlashes(install_name_dir);
+ // do not escape spaces on this since it is only a single path
+ }
+ }
+ buildSettings->AddAttribute("INSTALL_PATH",
+ this->CreateString(install_name_dir.c_str()));
+
+ buildSettings->AddAttribute("OTHER_LDFLAGS",
+ this->CreateString(extraLinkOptions.c_str()));
+ buildSettings->AddAttribute("OTHER_REZFLAGS",
+ this->CreateString(""));
+ buildSettings->AddAttribute("SECTORDER_FLAGS",
+ this->CreateString(""));
+ buildSettings->AddAttribute("USE_HEADERMAP",
+ this->CreateString("NO"));
+ if (this->XcodeVersion >= 30)
+ {
+ cmXCodeObject *group = this->CreateObject(cmXCodeObject::OBJECT_LIST);
+ group->AddObject(this->CreateString("-Wmost"));
+ group->AddObject(this->CreateString("-Wno-four-char-constants"));
+ group->AddObject(this->CreateString("-Wno-unknown-pragmas"));
+ buildSettings->AddAttribute("WARNING_CFLAGS", group);
+ }
+ else
+ {
+ buildSettings->AddAttribute("WARNING_CFLAGS",
+ this->CreateString(
+ "-Wmost -Wno-four-char-constants"
+ " -Wno-unknown-pragmas"));
+ }
+
+ // Runtime version information.
+ if(target.GetType() == cmTarget::SHARED_LIBRARY)
+ {
+ int major;
+ int minor;
+ int patch;
+
+ // VERSION -> current_version
+ target.GetTargetVersion(false, major, minor, patch);
+ cmOStringStream v;
+
+ // Xcode always wants at least 1.0.0 or nothing
+ if(!(major == 0 && minor == 0 && patch == 0))
+ {
+ v << major << "." << minor << "." << patch;
+ }
+ buildSettings->AddAttribute("DYLIB_CURRENT_VERSION",
+ this->CreateString(v.str().c_str()));
+
+ // SOVERSION -> compatibility_version
+ target.GetTargetVersion(true, major, minor, patch);
+ cmOStringStream vso;
+
+ // Xcode always wants at least 1.0.0 or nothing
+ if(!(major == 0 && minor == 0 && patch == 0))
+ {
+ vso << major << "." << minor << "." << patch;
+ }
+ buildSettings->AddAttribute("DYLIB_COMPATIBILITY_VERSION",
+ this->CreateString(vso.str().c_str()));
+ }
+ // 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();
+ i != props.end(); ++i)
+ {
+ if(i->first.find("XCODE_ATTRIBUTE_") == 0)
+ {
+ buildSettings->AddAttribute(i->first.substr(16).c_str(),
+ this->CreateString(i->second.GetValue()));
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+cmXCodeObject*
+cmGlobalXCodeGenerator::CreateUtilityTarget(cmTarget& cmtarget)
+{
+ cmXCodeObject* shellBuildPhase =
+ this->CreateObject(cmXCodeObject::PBXShellScriptBuildPhase);
+ shellBuildPhase->AddAttribute("buildActionMask",
+ this->CreateString("2147483647"));
+ cmXCodeObject* buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
+ shellBuildPhase->AddAttribute("files", buildFiles);
+ cmXCodeObject* inputPaths = this->CreateObject(cmXCodeObject::OBJECT_LIST);
+ shellBuildPhase->AddAttribute("inputPaths", inputPaths);
+ cmXCodeObject* outputPaths = this->CreateObject(cmXCodeObject::OBJECT_LIST);
+ shellBuildPhase->AddAttribute("outputPaths", outputPaths);
+ shellBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing",
+ this->CreateString("0"));
+ shellBuildPhase->AddAttribute("shellPath",
+ this->CreateString("/bin/sh"));
+ shellBuildPhase->AddAttribute("shellScript",
+ this->CreateString(
+ "# shell script goes here\nexit 0"));
+ shellBuildPhase->AddAttribute("showEnvVarsInLog",
+ this->CreateString("0"));
+
+ cmXCodeObject* target =
+ this->CreateObject(cmXCodeObject::PBXAggregateTarget);
+ target->SetComment(cmtarget.GetName());
+ cmXCodeObject* buildPhases =
+ this->CreateObject(cmXCodeObject::OBJECT_LIST);
+ std::vector<cmXCodeObject*> emptyContentVector;
+ this->CreateCustomCommands(buildPhases, 0, 0, 0, emptyContentVector, 0,
+ cmtarget);
+ target->AddAttribute("buildPhases", buildPhases);
+ if(this->XcodeVersion > 20)
+ {
+ this->AddConfigurations(target, cmtarget);
+ }
+ else
+ {
+ const char* theConfig =
+ this->CurrentMakefile->GetDefinition("CMAKE_BUILD_TYPE");
+ cmXCodeObject* buildSettings =
+ this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
+ this->CreateBuildSettings(cmtarget, 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);
+
+ // Add source files without build rules for editing convenience.
+ if(cmtarget.GetType() == cmTarget::UTILITY)
+ {
+ std::vector<cmSourceFile*> const& sources = cmtarget.GetSourceFiles();
+ for(std::vector<cmSourceFile*>::const_iterator i = sources.begin();
+ i != sources.end(); ++i)
+ {
+ if(!(*i)->GetPropertyAsBool("GENERATED"))
+ {
+ this->CreateXCodeFileReference(*i, cmtarget);
+ }
+ }
+ }
+
+ target->SetId(this->GetOrCreateId(
+ cmtarget.GetName(), target->GetId()).c_str());
+
+ return target;
+}
+
+//----------------------------------------------------------------------------
+std::string cmGlobalXCodeGenerator::AddConfigurations(cmXCodeObject* target,
+ cmTarget& cmtarget)
+{
+ std::string configTypes =
+ this->CurrentMakefile->GetRequiredDefinition("CMAKE_CONFIGURATION_TYPES");
+ std::vector<std::string> configVectorIn;
+ std::vector<std::string> configVector;
+ configVectorIn.push_back(configTypes);
+ cmSystemTools::ExpandList(configVectorIn, configVector);
+ cmXCodeObject* configlist =
+ this->CreateObject(cmXCodeObject::XCConfigurationList);
+ cmXCodeObject* buildConfigurations =
+ this->CreateObject(cmXCodeObject::OBJECT_LIST);
+ configlist->AddAttribute("buildConfigurations", buildConfigurations);
+ std::string comment = "Build configuration list for ";
+ comment += cmXCodeObject::PBXTypeNames[target->GetIsA()];
+ comment += " \"";
+ comment += cmtarget.GetName();
+ comment += "\"";
+ configlist->SetComment(comment.c_str());
+ target->AddAttribute("buildConfigurationList",
+ this->CreateObjectReference(configlist));
+ for(unsigned int i = 0; i < configVector.size(); ++i)
+ {
+ cmXCodeObject* config =
+ this->CreateObject(cmXCodeObject::XCBuildConfiguration);
+ buildConfigurations->AddObject(config);
+ cmXCodeObject* buildSettings =
+ this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
+ this->CreateBuildSettings(cmtarget, 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())
+ {
+ configlist->AddAttribute("defaultConfigurationName",
+ this->CreateString(configVector[0].c_str()));
+ configlist->AddAttribute("defaultConfigurationIsVisible",
+ this->CreateString("0"));
+ return configVector[0];
+ }
+ return "";
+}
+
+//----------------------------------------------------------------------------
+const char* cmGlobalXCodeGenerator::GetTargetFileType(cmTarget& cmtarget)
+{
+ switch(cmtarget.GetType())
+ {
+ case cmTarget::OBJECT_LIBRARY:
+ case cmTarget::STATIC_LIBRARY:
+ return "archive.ar";
+ case cmTarget::MODULE_LIBRARY:
+ if (cmtarget.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")?
+ "wrapper.framework" : "compiled.mach-o.dylib");
+ case cmTarget::EXECUTABLE:
+ return "compiled.mach-o.executable";
+ default: break;
+ }
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+const char* cmGlobalXCodeGenerator::GetTargetProductType(cmTarget& cmtarget)
+{
+ switch(cmtarget.GetType())
+ {
+ case cmTarget::OBJECT_LIBRARY:
+ case cmTarget::STATIC_LIBRARY:
+ return "com.apple.product-type.library.static";
+ case cmTarget::MODULE_LIBRARY:
+ if (cmtarget.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")?
+ "com.apple.product-type.framework" :
+ "com.apple.product-type.library.dynamic");
+ case cmTarget::EXECUTABLE:
+ return (cmtarget.GetPropertyAsBool("MACOSX_BUNDLE")?
+ "com.apple.product-type.application" :
+ "com.apple.product-type.tool");
+ default: break;
+ }
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+cmXCodeObject*
+cmGlobalXCodeGenerator::CreateXCodeTarget(cmTarget& cmtarget,
+ cmXCodeObject* buildPhases)
+{
+ cmXCodeObject* target =
+ this->CreateObject(cmXCodeObject::PBXNativeTarget);
+ target->AddAttribute("buildPhases", buildPhases);
+ cmXCodeObject* buildRules = this->CreateObject(cmXCodeObject::OBJECT_LIST);
+ target->AddAttribute("buildRules", buildRules);
+ std::string defConfig;
+ if(this->XcodeVersion > 20)
+ {
+ defConfig = this->AddConfigurations(target, cmtarget);
+ }
+ else
+ {
+ cmXCodeObject* buildSettings =
+ this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
+ defConfig = this->CurrentMakefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
+ this->CreateBuildSettings(cmtarget, 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()));
+
+ cmXCodeObject* fileRef =
+ this->CreateObject(cmXCodeObject::PBXFileReference);
+ if(const char* fileType = this->GetTargetFileType(cmtarget))
+ {
+ fileRef->AddAttribute("explicitFileType", this->CreateString(fileType));
+ }
+ std::string fullName;
+ if(cmtarget.GetType() == cmTarget::OBJECT_LIBRARY)
+ {
+ fullName = "lib";
+ fullName += cmtarget.GetName();
+ fullName += ".a";
+ }
+ else
+ {
+ fullName = cmtarget.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());
+ target->AddAttribute("productReference",
+ this->CreateObjectReference(fileRef));
+ if(const char* productType = this->GetTargetProductType(cmtarget))
+ {
+ target->AddAttribute("productType", this->CreateString(productType));
+ }
+ target->SetTarget(&cmtarget);
+ target->SetId(this->GetOrCreateId(
+ cmtarget.GetName(), target->GetId()).c_str());
+ return target;
+}
+
+//----------------------------------------------------------------------------
+cmXCodeObject* cmGlobalXCodeGenerator::FindXCodeTarget(cmTarget* t)
+{
+ if(!t)
+ {
+ return 0;
+ }
+ for(std::vector<cmXCodeObject*>::iterator i = this->XCodeObjects.begin();
+ i != this->XCodeObjects.end(); ++i)
+ {
+ cmXCodeObject* o = *i;
+ if(o->GetTarget() == t)
+ {
+ return o;
+ }
+ }
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+std::string cmGlobalXCodeGenerator::GetOrCreateId(const char* name,
+ const char* id)
+{
+ std::string guidStoreName = name;
+ guidStoreName += "_GUID_CMAKE";
+ const char* storedGUID =
+ this->CMakeInstance->GetCacheDefinition(guidStoreName.c_str());
+
+ if(storedGUID)
+ {
+ return storedGUID;
+ }
+
+ this->CMakeInstance->AddCacheEntry(guidStoreName.c_str(),
+ id, "Stored Xcode object GUID", cmCacheManager::INTERNAL);
+
+ return id;
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalXCodeGenerator::AddDependTarget(cmXCodeObject* target,
+ cmXCodeObject* dependTarget)
+{
+ // make sure a target does not depend on itself
+ if(target == dependTarget)
+ {
+ return;
+ }
+ // now avoid circular references if dependTarget already
+ // depends on target then skip it. Circular references crashes
+ // xcode
+ cmXCodeObject* dependTargetDepends =
+ dependTarget->GetObject("dependencies");
+ if(dependTargetDepends)
+ {
+ if(dependTargetDepends->HasObject(target->GetPBXTargetDependency()))
+ {
+ return;
+ }
+ }
+
+ cmXCodeObject* targetdep = dependTarget->GetPBXTargetDependency();
+ if(!targetdep)
+ {
+ cmXCodeObject* container =
+ this->CreateObject(cmXCodeObject::PBXContainerItemProxy);
+ container->SetComment("PBXContainerItemProxy");
+ container->AddAttribute("containerPortal",
+ this->CreateObjectReference(this->RootObject));
+ container->AddAttribute("proxyType", this->CreateString("1"));
+ container->AddAttribute("remoteGlobalIDString",
+ this->CreateObjectReference(dependTarget));
+ container->AddAttribute("remoteInfo",
+ this->CreateString(
+ dependTarget->GetTarget()->GetName()));
+ targetdep =
+ this->CreateObject(cmXCodeObject::PBXTargetDependency);
+ targetdep->SetComment("PBXTargetDependency");
+ targetdep->AddAttribute("target",
+ this->CreateObjectReference(dependTarget));
+ targetdep->AddAttribute("targetProxy",
+ this->CreateObjectReference(container));
+ dependTarget->SetPBXTargetDependency(targetdep);
+ }
+
+ cmXCodeObject* depends = target->GetObject("dependencies");
+ if(!depends)
+ {
+ cmSystemTools::
+ Error("target does not have dependencies attribute error..");
+
+ }
+ else
+ {
+ depends->AddUniqueObject(targetdep);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalXCodeGenerator::AppendOrAddBuildSetting(cmXCodeObject* settings,
+ const char* attribute,
+ const char* value)
+{
+ if(settings)
+ {
+ cmXCodeObject* attr = settings->GetObject(attribute);
+ if(!attr)
+ {
+ settings->AddAttribute(attribute, this->CreateString(value));
+ }
+ else
+ {
+ std::string oldValue = attr->GetString();
+ oldValue += " ";
+ oldValue += value;
+ attr->SetString(oldValue.c_str());
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalXCodeGenerator
+::AppendBuildSettingAttribute(cmXCodeObject* target,
+ const char* attribute,
+ const char* value,
+ const char* configName)
+{
+ if(this->XcodeVersion < 21)
+ {
+ // There is only one configuration. Add the setting to the buildSettings
+ // of the target.
+ this->AppendOrAddBuildSetting(target->GetObject("buildSettings"),
+ attribute, value);
+ }
+ else
+ {
+ // There are multiple configurations. Add the setting to the
+ // buildSettings of the configuration name given.
+ cmXCodeObject* configurationList =
+ target->GetObject("buildConfigurationList")->GetObject();
+ cmXCodeObject* buildConfigs =
+ configurationList->GetObject("buildConfigurations");
+ std::vector<cmXCodeObject*> list = buildConfigs->GetObjectList();
+ // each configuration and the target itself has a buildSettings in it
+ //list.push_back(target);
+ for(std::vector<cmXCodeObject*>::iterator i = list.begin();
+ i != list.end(); ++i)
+ {
+ if(configName)
+ {
+ if(strcmp((*i)->GetObject("name")->GetString(), configName) == 0)
+ {
+ cmXCodeObject* settings = (*i)->GetObject("buildSettings");
+ this->AppendOrAddBuildSetting(settings, attribute, value);
+ }
+ }
+ else
+ {
+ cmXCodeObject* settings = (*i)->GetObject("buildSettings");
+ this->AppendOrAddBuildSetting(settings, attribute, value);
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalXCodeGenerator
+::AddDependAndLinkInformation(cmXCodeObject* target)
+{
+ cmTarget* cmtarget = target->GetTarget();
+ if(!cmtarget)
+ {
+ cmSystemTools::Error("Error no target on xobject\n");
+ return;
+ }
+
+ // Add dependencies on other CMake targets.
+ TargetDependSet const& deps = this->GetTargetDirectDepends(*cmtarget);
+ for(TargetDependSet::const_iterator i = deps.begin(); i != deps.end(); ++i)
+ {
+ if(cmXCodeObject* dptarget = this->FindXCodeTarget(*i))
+ {
+ this->AddDependTarget(target, dptarget);
+ }
+ }
+
+ // Skip link information for static libraries.
+ if(cmtarget->GetType() == cmTarget::OBJECT_LIBRARY ||
+ cmtarget->GetType() == cmTarget::STATIC_LIBRARY)
+ {
+ return;
+ }
+
+ // Loop over configuration types and set per-configuration info.
+ for(std::vector<std::string>::iterator i =
+ this->CurrentConfigurationTypes.begin();
+ i != this->CurrentConfigurationTypes.end(); ++i)
+ {
+ // Get the current configuration name.
+ const char* configName = i->c_str();
+ if(!*configName)
+ {
+ configName = 0;
+ }
+
+ // Compute the link library and directory information.
+ cmComputeLinkInformation* pcli = cmtarget->GetLinkInformation(configName);
+ if(!pcli)
+ {
+ continue;
+ }
+ cmComputeLinkInformation& cli = *pcli;
+
+ // Add dependencies directly on library files.
+ {
+ std::vector<std::string> const& libDeps = cli.GetDepends();
+ for(std::vector<std::string>::const_iterator j = libDeps.begin();
+ j != libDeps.end(); ++j)
+ {
+ target->AddDependLibrary(configName, j->c_str());
+ }
+ }
+
+ // add the library search paths
+ {
+ std::vector<std::string> const& libDirs = cli.GetDirectories();
+ std::string linkDirs;
+ for(std::vector<std::string>::const_iterator libDir = libDirs.begin();
+ libDir != libDirs.end(); ++libDir)
+ {
+ if(libDir->size() && *libDir != "/usr/lib")
+ {
+ if(this->XcodeVersion > 15)
+ {
+ // Now add the same one but append
+ // $(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) to it:
+ linkDirs += " ";
+ linkDirs += this->XCodeEscapePath(
+ (*libDir + "/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)").c_str());
+ }
+ linkDirs += " ";
+ linkDirs += this->XCodeEscapePath(libDir->c_str());
+ }
+ }
+ this->AppendBuildSettingAttribute(target, "LIBRARY_SEARCH_PATHS",
+ linkDirs.c_str(), configName);
+ }
+
+ // add the framework search paths
+ {
+ const char* sep = "";
+ std::string fdirs;
+ std::vector<std::string> const& fwDirs = cli.GetFrameworkPaths();
+ for(std::vector<std::string>::const_iterator fdi = fwDirs.begin();
+ fdi != fwDirs.end(); ++fdi)
+ {
+ fdirs += sep;
+ sep = " ";
+ fdirs += this->XCodeEscapePath(fdi->c_str());
+ }
+ if(!fdirs.empty())
+ {
+ this->AppendBuildSettingAttribute(target, "FRAMEWORK_SEARCH_PATHS",
+ fdirs.c_str(), configName);
+ }
+ }
+
+ // now add the link libraries
+ {
+ std::string linkLibs;
+ const char* sep = "";
+ typedef cmComputeLinkInformation::ItemVector ItemVector;
+ ItemVector const& libNames = cli.GetItems();
+ for(ItemVector::const_iterator li = libNames.begin();
+ li != libNames.end(); ++li)
+ {
+ linkLibs += sep;
+ sep = " ";
+ if(li->IsPath)
+ {
+ linkLibs += this->XCodeEscapePath(li->Value.c_str());
+ }
+ else
+ {
+ linkLibs += li->Value;
+ }
+ if(li->Target && !li->Target->IsImported())
+ {
+ target->AddDependTarget(configName, li->Target->GetName());
+ }
+ }
+ this->AppendBuildSettingAttribute(target, "OTHER_LDFLAGS",
+ linkLibs.c_str(), configName);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalXCodeGenerator::CreateGroups(cmLocalGenerator* root,
+ std::vector<cmLocalGenerator*>&
+ generators)
+{
+ for(std::vector<cmLocalGenerator*>::iterator i = generators.begin();
+ i != generators.end(); ++i)
+ {
+ if(this->IsExcluded(root, *i))
+ {
+ continue;
+ }
+ cmMakefile* mf = (*i)->GetMakefile();
+ std::vector<cmSourceGroup> sourceGroups = mf->GetSourceGroups();
+ cmTargets &tgts = mf->GetTargets();
+ for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++)
+ {
+ cmTarget& cmtarget = l->second;
+
+ // 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)
+ {
+ continue;
+ }
+
+ // add the soon to be generated Info.plist file as a source for a
+ // MACOSX_BUNDLE file
+ if(cmtarget.GetPropertyAsBool("MACOSX_BUNDLE"))
+ {
+ std::string plist = this->ComputeInfoPListLocation(cmtarget);
+ cmSourceFile* sf = mf->GetOrCreateSource(plist.c_str(), true);
+ cmtarget.AddSourceFile(sf);
+ }
+
+ std::vector<cmSourceFile*> classes = cmtarget.GetSourceFiles();
+
+ // Put cmSourceFile instances in proper groups:
+ for(std::vector<cmSourceFile*>::const_iterator s = classes.begin();
+ s != classes.end(); s++)
+ {
+ cmSourceFile* sf = *s;
+ // Add the file to the list of sources.
+ std::string const& source = sf->GetFullPath();
+ cmSourceGroup& sourceGroup =
+ mf->FindSourceGroup(source.c_str(), sourceGroups);
+ cmXCodeObject* pbxgroup =
+ this->CreateOrGetPBXGroup(cmtarget, &sourceGroup);
+ cmStdString key = GetGroupMapKey(cmtarget, sf);
+ this->GroupMap[key] = pbxgroup;
+ }
+
+ // Put OBJECT_LIBRARY objects in proper groups:
+ std::vector<std::string> objs;
+ this->GetGeneratorTarget(&cmtarget)->UseObjectLibraries(objs);
+ for(std::vector<std::string>::const_iterator
+ oi = objs.begin(); oi != objs.end(); ++oi)
+ {
+ std::string const& source = *oi;
+ cmSourceGroup& sourceGroup =
+ mf->FindSourceGroup(source.c_str(), sourceGroups);
+ cmXCodeObject* pbxgroup =
+ this->CreateOrGetPBXGroup(cmtarget, &sourceGroup);
+ cmStdString key = GetGroupMapKeyFromPath(cmtarget, source);
+ this->GroupMap[key] = pbxgroup;
+ }
+ }
+ }
+}
+
+cmXCodeObject *cmGlobalXCodeGenerator
+::CreatePBXGroup(cmXCodeObject *parent, cmStdString name)
+{
+ cmXCodeObject* parentChildren = NULL;
+ if(parent)
+ parentChildren = parent->GetObject("children");
+ cmXCodeObject* group = this->CreateObject(cmXCodeObject::PBXGroup);
+ cmXCodeObject* groupChildren =
+ this->CreateObject(cmXCodeObject::OBJECT_LIST);
+ group->AddAttribute("name", this->CreateString(name.c_str()));
+ group->AddAttribute("children", groupChildren);
+ if(this->XcodeVersion == 15)
+ {
+ group->AddAttribute("refType", this->CreateString("4"));
+ }
+ group->AddAttribute("sourceTree", this->CreateString("<group>"));
+ if(parentChildren)
+ parentChildren->AddObject(group);
+ return group;
+}
+
+//----------------------------------------------------------------------------
+cmXCodeObject* cmGlobalXCodeGenerator
+::CreateOrGetPBXGroup(cmTarget& cmtarget, cmSourceGroup* sg)
+{
+ cmStdString s;
+ cmStdString target;
+ const char *targetFolder= cmtarget.GetProperty("FOLDER");
+ if(targetFolder) {
+ target = targetFolder;
+ target += "/";
+ }
+ target += cmtarget.GetName();
+ s = target + "/";
+ s += sg->GetFullName();
+ std::map<cmStdString, cmXCodeObject* >::iterator it =
+ this->GroupNameMap.find(s);
+ if(it != this->GroupNameMap.end())
+ {
+ return it->second;
+ }
+
+ it = this->TargetGroup.find(target);
+ cmXCodeObject* tgroup = 0;
+ if(it != this->TargetGroup.end())
+ {
+ tgroup = it->second;
+ }
+ else
+ {
+ std::vector<std::string> tgt_folders =
+ cmSystemTools::tokenize(target, "/");
+ cmStdString 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())
+ {
+ tgroup = this->CreatePBXGroup(tgroup,tgt_folders[i]);
+ this->TargetGroup[curr_tgt_folder] = tgroup;
+ }
+ else
+ {
+ tgroup = it->second;
+ continue;
+ }
+ if(i == 0)
+ {
+ this->SourcesGroupChildren->AddObject(tgroup);
+ }
+ curr_tgt_folder += "/";
+ }
+ }
+ this->TargetGroup[target] = tgroup;
+
+ // If it's the default source group (empty name) then put the source file
+ // directly in the tgroup...
+ //
+ if (cmStdString(sg->GetFullName()) == "")
+ {
+ this->GroupNameMap[s] = tgroup;
+ return tgroup;
+ }
+
+ //It's a recursive folder structure, let's find the real parent group
+ if(std::string(sg->GetFullName()) != std::string(sg->GetName()))
+ {
+ std::vector<std::string> folders =
+ cmSystemTools::tokenize(sg->GetFullName(), "\\");
+ cmStdString curr_folder = cmtarget.GetName();
+ 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 =
+ this->GroupNameMap.find(curr_folder);
+ //Create new folder
+ if(i_folder == this->GroupNameMap.end())
+ {
+ cmXCodeObject *group = this->CreatePBXGroup(tgroup,folders[i]);
+ this->GroupNameMap[curr_folder] = group;
+ tgroup = group;
+ }
+ else
+ {
+ tgroup = i_folder->second;
+ }
+ curr_folder = curr_folder + "\\";
+ }
+ return tgroup;
+ }
+ cmXCodeObject *group = this->CreatePBXGroup(tgroup,sg->GetName());
+ this->GroupNameMap[s] = group;
+ return group;
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalXCodeGenerator
+::CreateXCodeObjects(cmLocalGenerator* root,
+ std::vector<cmLocalGenerator*>&
+ generators)
+{
+ this->ClearXCodeObjects();
+ this->RootObject = 0;
+ this->SourcesGroupChildren = 0;
+ this->ResourcesGroupChildren = 0;
+ this->MainGroupChildren = 0;
+ cmXCodeObject* group = this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
+ group->AddAttribute("COPY_PHASE_STRIP", this->CreateString("NO"));
+ cmXCodeObject* developBuildStyle =
+ this->CreateObject(cmXCodeObject::PBXBuildStyle);
+ cmXCodeObject* listObjs = this->CreateObject(cmXCodeObject::OBJECT_LIST);
+ if(this->XcodeVersion == 15)
+ {
+ developBuildStyle->AddAttribute("name",
+ this->CreateString("Development"));
+ developBuildStyle->AddAttribute("buildSettings", group);
+ listObjs->AddObject(developBuildStyle);
+ group = this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
+ group->AddAttribute("COPY_PHASE_STRIP", this->CreateString("YES"));
+ cmXCodeObject* deployBuildStyle =
+ this->CreateObject(cmXCodeObject::PBXBuildStyle);
+ deployBuildStyle->AddAttribute("name", this->CreateString("Deployment"));
+ deployBuildStyle->AddAttribute("buildSettings", group);
+ listObjs->AddObject(deployBuildStyle);
+ }
+ else
+ {
+ for(unsigned int i = 0; i < this->CurrentConfigurationTypes.size(); ++i)
+ {
+ cmXCodeObject* buildStyle =
+ this->CreateObject(cmXCodeObject::PBXBuildStyle);
+ const char* name = this->CurrentConfigurationTypes[i].c_str();
+ buildStyle->AddAttribute("name", this->CreateString(name));
+ buildStyle->SetComment(name);
+ cmXCodeObject* sgroup =
+ this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
+ sgroup->AddAttribute("COPY_PHASE_STRIP", this->CreateString("NO"));
+ buildStyle->AddAttribute("buildSettings", sgroup);
+ listObjs->AddObject(buildStyle);
+ }
+ }
+
+ cmXCodeObject* mainGroup = this->CreateObject(cmXCodeObject::PBXGroup);
+ this->MainGroupChildren =
+ this->CreateObject(cmXCodeObject::OBJECT_LIST);
+ mainGroup->AddAttribute("children", this->MainGroupChildren);
+ if(this->XcodeVersion == 15)
+ {
+ mainGroup->AddAttribute("refType", this->CreateString("4"));
+ }
+ mainGroup->AddAttribute("sourceTree", this->CreateString("<group>"));
+
+ cmXCodeObject* sourcesGroup = this->CreateObject(cmXCodeObject::PBXGroup);
+ this->SourcesGroupChildren =
+ this->CreateObject(cmXCodeObject::OBJECT_LIST);
+ sourcesGroup->AddAttribute("name", this->CreateString("Sources"));
+ sourcesGroup->AddAttribute("children", this->SourcesGroupChildren);
+ if(this->XcodeVersion == 15)
+ {
+ sourcesGroup->AddAttribute("refType", this->CreateString("4"));
+ }
+ sourcesGroup->AddAttribute("sourceTree", this->CreateString("<group>"));
+ this->MainGroupChildren->AddObject(sourcesGroup);
+
+ cmXCodeObject* resourcesGroup = this->CreateObject(cmXCodeObject::PBXGroup);
+ this->ResourcesGroupChildren =
+ this->CreateObject(cmXCodeObject::OBJECT_LIST);
+ resourcesGroup->AddAttribute("name", this->CreateString("Resources"));
+ resourcesGroup->AddAttribute("children", this->ResourcesGroupChildren);
+ if(this->XcodeVersion == 15)
+ {
+ resourcesGroup->AddAttribute("refType", this->CreateString("4"));
+ }
+ resourcesGroup->AddAttribute("sourceTree", this->CreateString("<group>"));
+ this->MainGroupChildren->AddObject(resourcesGroup);
+
+ // now create the cmake groups
+ this->CreateGroups(root, generators);
+
+ cmXCodeObject* productGroup = this->CreateObject(cmXCodeObject::PBXGroup);
+ productGroup->AddAttribute("name", this->CreateString("Products"));
+ if(this->XcodeVersion == 15)
+ {
+ productGroup->AddAttribute("refType", this->CreateString("4"));
+ }
+ productGroup->AddAttribute("sourceTree", this->CreateString("<group>"));
+ cmXCodeObject* productGroupChildren =
+ this->CreateObject(cmXCodeObject::OBJECT_LIST);
+ productGroup->AddAttribute("children", productGroupChildren);
+ this->MainGroupChildren->AddObject(productGroup);
+
+
+ this->RootObject = this->CreateObject(cmXCodeObject::PBXProject);
+ this->RootObject->SetComment("Project object");
+
+ std::string project_id = "PROJECT_";
+ project_id += root->GetMakefile()->GetProjectName();
+ this->RootObject->SetId(this->GetOrCreateId(
+ project_id.c_str(), this->RootObject->GetId()).c_str());
+
+ group = this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
+ this->RootObject->AddAttribute("mainGroup",
+ this->CreateObjectReference(mainGroup));
+ this->RootObject->AddAttribute("buildSettings", group);
+ this->RootObject->AddAttribute("buildStyles", listObjs);
+ this->RootObject->AddAttribute("hasScannedForEncodings",
+ this->CreateString("0"));
+ if (this->XcodeVersion >= 30)
+ {
+ group = this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
+ group->AddAttribute("BuildIndependentTargetsInParallel",
+ this->CreateString("YES"));
+ this->RootObject->AddAttribute("attributes", group);
+ if (this->XcodeVersion >= 32)
+ this->RootObject->AddAttribute("compatibilityVersion",
+ this->CreateString("Xcode 3.2"));
+ else if (this->XcodeVersion >= 31)
+ this->RootObject->AddAttribute("compatibilityVersion",
+ this->CreateString("Xcode 3.1"));
+ else
+ this->RootObject->AddAttribute("compatibilityVersion",
+ this->CreateString("Xcode 3.0"));
+ }
+ // Point Xcode at the top of the source tree.
+ {
+ std::string pdir =
+ this->RelativeToBinary(root->GetMakefile()->GetCurrentDirectory());
+ this->RootObject->AddAttribute("projectDirPath",
+ this->CreateString(pdir.c_str()));
+ this->RootObject->AddAttribute("projectRoot", this->CreateString(""));
+ }
+ cmXCodeObject* configlist =
+ this->CreateObject(cmXCodeObject::XCConfigurationList);
+ cmXCodeObject* buildConfigurations =
+ this->CreateObject(cmXCodeObject::OBJECT_LIST);
+ std::vector<cmXCodeObject*> 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);
+ cmXCodeObject* configRelease =
+ this->CreateObject(cmXCodeObject::XCBuildConfiguration);
+ configRelease->AddAttribute("name", this->CreateString("Release"));
+ configs.push_back(configRelease);
+ }
+ else
+ {
+ for(unsigned int i = 0; i < this->CurrentConfigurationTypes.size(); ++i)
+ {
+ const char* name = this->CurrentConfigurationTypes[i].c_str();
+ if (0 == i)
+ {
+ defaultConfigName = name;
+ }
+ cmXCodeObject* config =
+ this->CreateObject(cmXCodeObject::XCBuildConfiguration);
+ config->AddAttribute("name", this->CreateString(name));
+ configs.push_back(config);
+ }
+ }
+ for(std::vector<cmXCodeObject*>::iterator c = configs.begin();
+ c != configs.end(); ++c)
+ {
+ buildConfigurations->AddObject(*c);
+ }
+ configlist->AddAttribute("buildConfigurations", buildConfigurations);
+
+ std::string comment = "Build configuration list for PBXProject ";
+ comment += " \"";
+ comment += this->CurrentProject;
+ comment += "\"";
+ configlist->SetComment(comment.c_str());
+ configlist->AddAttribute("defaultConfigurationIsVisible",
+ this->CreateString("0"));
+ configlist->AddAttribute("defaultConfigurationName",
+ this->CreateString(defaultConfigName));
+ cmXCodeObject* buildSettings =
+ 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* sysrootDefault =
+ this->CurrentMakefile->GetDefinition("CMAKE_OSX_SYSROOT_DEFAULT");
+ const char* deploymentTarget =
+ this->CurrentMakefile->GetDefinition("CMAKE_OSX_DEPLOYMENT_TARGET");
+ if(osxArch && sysroot)
+ {
+ bool flagsUsed = false;
+ // recompute this as it may have been changed since enable language
+ this->Architectures.clear();
+ cmSystemTools::ExpandListArgument(std::string(osxArch),
+ this->Architectures);
+ flagsUsed = true;
+ 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)
+ {
+ archString += sep;
+ archString += *i;
+ sep = " ";
+ }
+ buildSettings->AddAttribute("ARCHS",
+ this->CreateString(archString.c_str()));
+ if(!flagsUsed && sysrootDefault &&
+ strcmp(sysroot, sysrootDefault) != 0)
+ {
+ buildSettings->AddAttribute("SDKROOT",
+ this->CreateString(sysroot));
+ }
+ }
+ if(deploymentTarget && *deploymentTarget)
+ {
+ buildSettings->AddAttribute("MACOSX_DEPLOYMENT_TARGET",
+ this->CreateString(deploymentTarget));
+ }
+
+ // 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())));
+ }
+ }
+ }
+
+ std::string symroot = root->GetMakefile()->GetCurrentOutputDirectory();
+ symroot += "/build";
+ buildSettings->AddAttribute("SYMROOT", this->CreateString(symroot.c_str()));
+
+ for( std::vector<cmXCodeObject*>::iterator i = configs.begin();
+ i != configs.end(); ++i)
+ {
+ (*i)->AddAttribute("buildSettings", buildSettings);
+ }
+
+ this->RootObject->AddAttribute("buildConfigurationList",
+ this->CreateObjectReference(configlist));
+
+ std::vector<cmXCodeObject*> targets;
+ for(std::vector<cmLocalGenerator*>::iterator i = generators.begin();
+ i != generators.end(); ++i)
+ {
+ if(!this->IsExcluded(root, *i))
+ {
+ this->CreateXCodeTargets(*i, targets);
+ }
+ }
+ // loop over all targets and add link and depend info
+ for(std::vector<cmXCodeObject*>::iterator i = targets.begin();
+ i != targets.end(); ++i)
+ {
+ cmXCodeObject* t = *i;
+ this->AddDependAndLinkInformation(t);
+ }
+ // now create xcode depend hack makefile
+ this->CreateXCodeDependHackTarget(targets);
+ // now add all targets to the root object
+ cmXCodeObject* allTargets = this->CreateObject(cmXCodeObject::OBJECT_LIST);
+ for(std::vector<cmXCodeObject*>::iterator i = targets.begin();
+ i != targets.end(); ++i)
+ {
+ cmXCodeObject* t = *i;
+ allTargets->AddObject(t);
+ cmXCodeObject* productRef = t->GetObject("productReference");
+ if(productRef)
+ {
+ productGroupChildren->AddObject(productRef->GetObject());
+ }
+ }
+ this->RootObject->AddAttribute("targets", allTargets);
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmGlobalXCodeGenerator::GetObjectsNormalDirectory(
+ const std::string &projName,
+ const std::string &configName,
+ const cmTarget *t) const
+{
+ std::string dir =
+ t->GetMakefile()->GetCurrentOutputDirectory();
+ dir += "/";
+ dir += projName;
+ dir += ".build/";
+ dir += configName;
+ dir += "/";
+ dir += t->GetName();
+ dir += ".build/Objects-normal/";
+
+ return dir;
+}
+
+//----------------------------------------------------------------------------
+void
+cmGlobalXCodeGenerator::CreateXCodeDependHackTarget(
+ std::vector<cmXCodeObject*>& targets)
+{
+ cmGeneratedFileStream
+ makefileStream(this->CurrentXCodeHackMakefile.c_str());
+ if(!makefileStream)
+ {
+ cmSystemTools::Error("Could not create",
+ this->CurrentXCodeHackMakefile.c_str());
+ return;
+ }
+ makefileStream.SetCopyIfDifferent(true);
+ // one more pass for external depend information not handled
+ // correctly by xcode
+ makefileStream << "# DO NOT EDIT\n";
+ makefileStream << "# This makefile makes sure all linkable targets are\n";
+ makefileStream << "# up-to-date with anything they link to\n"
+ "default:\n"
+ "\techo \"Do not invoke directly\"\n"
+ "\n";
+ makefileStream
+ << "# For each target create a dummy rule "
+ "so the target does not have to exist\n";
+ std::set<cmStdString> emitted;
+ for(std::vector<cmXCodeObject*>::iterator i = targets.begin();
+ i != targets.end(); ++i)
+ {
+ cmXCodeObject* target = *i;
+ std::map<cmStdString, cmXCodeObject::StringVec> const& deplibs =
+ target->GetDependLibraries();
+ for(std::map<cmStdString, cmXCodeObject::StringVec>::const_iterator ci
+ = deplibs.begin(); ci != deplibs.end(); ++ci)
+ {
+ for(cmXCodeObject::StringVec::const_iterator d = ci->second.begin();
+ d != ci->second.end(); ++d)
+ {
+ if(emitted.insert(*d).second)
+ {
+ makefileStream <<
+ this->ConvertToRelativeForMake(d->c_str()) << ":\n";
+ }
+ }
+ }
+ }
+ makefileStream << "\n\n";
+
+ // Write rules to help Xcode relink things at the right time.
+ makefileStream <<
+ "# Rules to remove targets that are older than anything to which they\n"
+ "# link. This forces Xcode to relink the targets from scratch. It\n"
+ "# does not seem to check these dependencies itself.\n";
+ for(std::vector<std::string>::const_iterator
+ ct = this->CurrentConfigurationTypes.begin();
+ ct != this->CurrentConfigurationTypes.end(); ++ct)
+ {
+ const char* configName = 0;
+ if(!ct->empty())
+ {
+ configName = ct->c_str();
+ }
+ for(std::vector<cmXCodeObject*>::iterator i = targets.begin();
+ i != targets.end(); ++i)
+ {
+ cmXCodeObject* target = *i;
+ cmTarget* t =target->GetTarget();
+
+ if(t->GetType() == cmTarget::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)
+ {
+ // Declare an entry point for the target post-build phase.
+ makefileStream << this->PostBuildMakeTarget(t->GetName(), *ct)
+ << ":\n";
+ }
+
+ if(t->GetType() == cmTarget::EXECUTABLE ||
+ t->GetType() == cmTarget::SHARED_LIBRARY ||
+ t->GetType() == cmTarget::MODULE_LIBRARY)
+ {
+ std::string tfull = t->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
+ 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();
+ d != deptgts.end(); ++d)
+ {
+ makefileStream << this->PostBuildMakeTarget(*d, *ct) << ": "
+ << trel << "\n";
+ }
+ }
+
+ // Create a rule for this target.
+ makefileStream << trel << ":";
+
+ // List dependencies if any exist.
+ std::map<cmStdString, 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();
+ d != deplibs.end(); ++d)
+ {
+ makefileStream << "\\\n\t" <<
+ this->ConvertToRelativeForMake(d->c_str());
+ }
+ }
+ // Write the action to remove the target if it is out of date.
+ makefileStream << "\n";
+ makefileStream << "\t/bin/rm -f "
+ << this->ConvertToRelativeForMake(tfull.c_str())
+ << "\n";
+ // if building for more than one architecture
+ // then remove those exectuables as well
+ if(this->Architectures.size() > 1)
+ {
+ std::string universal = this->GetObjectsNormalDirectory(
+ this->CurrentProject, configName, t);
+ for( std::vector<std::string>::iterator arch =
+ this->Architectures.begin();
+ arch != this->Architectures.end(); ++arch)
+ {
+ std::string universalFile = universal;
+ universalFile += *arch;
+ universalFile += "/";
+ universalFile += t->GetFullName(configName);
+ makefileStream << "\t/bin/rm -f "
+ <<
+ this->ConvertToRelativeForMake(universalFile.c_str())
+ << "\n";
+ }
+ }
+ makefileStream << "\n\n";
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmGlobalXCodeGenerator::OutputXCodeProject(cmLocalGenerator* root,
+ std::vector<cmLocalGenerator*>&
+ generators)
+{
+ if(generators.size() == 0)
+ {
+ return;
+ }
+ // Skip local generators that are excluded from this project.
+ for(std::vector<cmLocalGenerator*>::iterator g = generators.begin();
+ g != generators.end(); ++g)
+ {
+ if(this->IsExcluded(root, *g))
+ {
+ continue;
+ }
+ }
+
+ this->CreateXCodeObjects(root,
+ generators);
+ std::string xcodeDir = root->GetMakefile()->GetStartOutputDirectory();
+ xcodeDir += "/";
+ xcodeDir += root->GetMakefile()->GetProjectName();
+ xcodeDir += ".xcode";
+ if(this->XcodeVersion > 20)
+ {
+ xcodeDir += "proj";
+ }
+ cmSystemTools::MakeDirectory(xcodeDir.c_str());
+ std::string xcodeProjFile = xcodeDir + "/project.pbxproj";
+ cmGeneratedFileStream fout(xcodeProjFile.c_str());
+ fout.SetCopyIfDifferent(true);
+ if(!fout)
+ {
+ return;
+ }
+ this->WriteXCodePBXProj(fout, root, generators);
+ this->ClearXCodeObjects();
+
+ // Since this call may have created new cache entries, save the cache:
+ //
+ root->GetMakefile()->GetCacheManager()->SaveCache(
+ root->GetMakefile()->GetHomeOutputDirectory());
+}
+
+//----------------------------------------------------------------------------
+void
+cmGlobalXCodeGenerator::WriteXCodePBXProj(std::ostream& fout,
+ cmLocalGenerator* ,
+ std::vector<cmLocalGenerator*>& )
+{
+ fout << "// !$*UTF8*$!\n";
+ fout << "{\n";
+ cmXCodeObject::Indent(1, fout);
+ fout << "archiveVersion = 1;\n";
+ cmXCodeObject::Indent(1, fout);
+ fout << "classes = {\n";
+ cmXCodeObject::Indent(1, fout);
+ fout << "};\n";
+ cmXCodeObject::Indent(1, fout);
+ if(this->XcodeVersion >= 21)
+ {
+ if (this->XcodeVersion >= 32)
+ fout << "objectVersion = 46;\n";
+ else if (this->XcodeVersion >= 31)
+ fout << "objectVersion = 45;\n";
+ else if (this->XcodeVersion >= 30)
+ fout << "objectVersion = 44;\n";
+ else
+ fout << "objectVersion = 42;\n";
+ cmXCode21Object::PrintList(this->XCodeObjects, fout);
+ }
+ else
+ {
+ fout << "objectVersion = 39;\n";
+ cmXCodeObject::PrintList(this->XCodeObjects, fout);
+ }
+ cmXCodeObject::Indent(1, fout);
+ fout << "rootObject = " << this->RootObject->GetId() << ";\n";
+ fout << "}\n";
+}
+
+//----------------------------------------------------------------------------
+const char* cmGlobalXCodeGenerator::GetCMakeCFGIntDir() const
+{
+ return this->XcodeVersion >= 21 ?
+ "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)" : ".";
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalXCodeGenerator::GetDocumentation(cmDocumentationEntry& entry)
+ const
+{
+ entry.Name = this->GetName();
+ entry.Brief = "Generate Xcode project files.";
+ entry.Full = "";
+}
+
+//----------------------------------------------------------------------------
+std::string cmGlobalXCodeGenerator::ConvertToRelativeForMake(const char* p)
+{
+ if ( !this->CurrentMakefile->IsOn("CMAKE_USE_RELATIVE_PATHS") )
+ {
+ return cmSystemTools::ConvertToOutputPath(p);
+ }
+ else
+ {
+ std::string ret =
+ this->CurrentLocalGenerator->
+ ConvertToRelativePath(this->CurrentOutputDirectoryComponents, p);
+ return cmSystemTools::ConvertToOutputPath(ret.c_str());
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string cmGlobalXCodeGenerator::ConvertToRelativeForXCode(const char* p)
+{
+ 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());
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string cmGlobalXCodeGenerator::RelativeToSource(const char* p)
+{
+ // We force conversion because Xcode breakpoints do not work unless
+ // they are in a file named relative to the source tree.
+ return this->CurrentLocalGenerator->
+ ConvertToRelativePath(this->ProjectSourceDirectoryComponents, p, true);
+}
+
+//----------------------------------------------------------------------------
+std::string cmGlobalXCodeGenerator::RelativeToBinary(const char* p)
+{
+ return this->CurrentLocalGenerator->
+ ConvertToRelativePath(this->ProjectOutputDirectoryComponents, p);
+}
+
+//----------------------------------------------------------------------------
+std::string cmGlobalXCodeGenerator::XCodeEscapePath(const char* p)
+{
+ std::string ret = p;
+ if(ret.find(' ') != ret.npos)
+ {
+ std::string t = ret;
+ ret = "\"";
+ ret += t;
+ ret += "\"";
+ }
+ return ret;
+}
+
+//----------------------------------------------------------------------------
+void
+cmGlobalXCodeGenerator
+::AppendDirectoryForConfig(const char* prefix,
+ const char* config,
+ const char* suffix,
+ std::string& dir)
+{
+ if(this->XcodeVersion > 20)
+ {
+ if(config)
+ {
+ dir += prefix;
+ dir += config;
+ dir += suffix;
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string cmGlobalXCodeGenerator::LookupFlags(const char* varNamePrefix,
+ const char* varNameLang,
+ const char* varNameSuffix,
+ const char* default_flags)
+{
+ if(varNameLang)
+ {
+ std::string varName = varNamePrefix;
+ varName += varNameLang;
+ varName += varNameSuffix;
+ if(const char* varValue =
+ this->CurrentMakefile->GetDefinition(varName.c_str()))
+ {
+ if(*varValue)
+ {
+ return varValue;
+ }
+ }
+ }
+ return default_flags;
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalXCodeGenerator::AppendDefines(BuildObjectListOrString& defs,
+ const char* defines_list,
+ bool dflag)
+{
+ // Skip this if there are no definitions.
+ if(!defines_list)
+ {
+ return;
+ }
+
+ // Expand the list of definitions.
+ std::vector<std::string> defines;
+ cmSystemTools::ExpandListArgument(defines_list, defines);
+
+ // Store the definitions in the string.
+ this->AppendDefines(defs, defines, dflag);
+}
+
+//----------------------------------------------------------------------------
+void
+cmGlobalXCodeGenerator::AppendDefines(BuildObjectListOrString& defs,
+ std::vector<std::string> const& defines,
+ bool dflag)
+{
+ // GCC_PREPROCESSOR_DEFINITIONS is a space-separated list of definitions.
+ std::string def;
+ for(std::vector<std::string>::const_iterator di = defines.begin();
+ di != defines.end(); ++di)
+ {
+ // Start with -D if requested.
+ def = dflag? "-D": "";
+ def += *di;
+
+ // Append the flag with needed escapes.
+ std::string tmp;
+ this->AppendFlag(tmp, def);
+ defs.Add(tmp.c_str());
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalXCodeGenerator::AppendFlag(std::string& flags,
+ std::string const& flag)
+{
+ // Short-circuit for an empty flag.
+ if(flag.empty())
+ {
+ return;
+ }
+
+ // Separate from previous flags.
+ if(!flags.empty())
+ {
+ flags += " ";
+ }
+
+ // Check if the flag needs quoting.
+ bool quoteFlag =
+ flag.find_first_of("`~!@#$%^&*()+={}[]|:;\"'<>,.? ") != flag.npos;
+
+ // 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
+ // Note that in the code below we need one more level of escapes for
+ // C string syntax in this source file.
+ //
+ // The final level of escaping is done when the string is stored
+ // into the project file by cmXCodeObject::PrintString.
+
+ if(quoteFlag)
+ {
+ // Open single quote.
+ flags += "'";
+ }
+
+ // Flag value with escaped quotes and backslashes.
+ for(const char* c = flag.c_str(); *c; ++c)
+ {
+ if(*c == '\'')
+ {
+ if (this->XcodeVersion >= 40)
+ {
+ flags += "'\\\\''";
+ }
+ else
+ {
+ flags += "\\\\'";
+ }
+ }
+ else if(*c == '\\')
+ {
+ flags += "\\\\\\\\";
+ }
+ else
+ {
+ flags += *c;
+ }
+ }
+
+ if(quoteFlag)
+ {
+ // Close single quote.
+ flags += "'";
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmGlobalXCodeGenerator::ComputeInfoPListLocation(cmTarget& target)
+{
+ std::string plist = target.GetMakefile()->GetCurrentOutputDirectory();
+ plist += cmake::GetCMakeFilesDirectory();
+ plist += "/";
+ plist += target.GetName();
+ plist += ".dir/Info.plist";
+ return plist;
+}
+
+//----------------------------------------------------------------------------
+// Return true if the generated build tree may contain multiple builds.
+// i.e. "Can I build Debug and Release in the same tree?"
+bool cmGlobalXCodeGenerator::IsMultiConfig()
+{
+ // Old Xcode 1.5 is single config:
+ if(this->XcodeVersion == 15)
+ {
+ return false;
+ }
+
+ // Newer Xcode versions are multi config:
+ return true;
+}
+
+ //----------------------------------------------------------------------------
+void
+cmGlobalXCodeGenerator
+::ComputeTargetObjects(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 dir = this->GetObjectsNormalDirectory(
+ this->CurrentProject, configName, gt->Target);
+ if(this->XcodeVersion >= 21)
+ {
+ dir += "$(CURRENT_ARCH)/";
+ }
+ else
+ {
+#ifdef __ppc__
+ dir += "ppc/";
+#endif
+#ifdef __i386
+ dir += "i386/";
+#endif
+ }
+ gt->ObjectDirectory = dir;
+}
diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h
new file mode 100644
index 000000000..800963b9c
--- /dev/null
+++ b/Source/cmGlobalXCodeGenerator.h
@@ -0,0 +1,239 @@
+/*============================================================================
+ 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 cmGlobalXCodeGenerator_h
+#define cmGlobalXCodeGenerator_h
+
+#include "cmGlobalGenerator.h"
+#include "cmXCodeObject.h"
+#include "cmCustomCommand.h"
+class cmTarget;
+class cmSourceFile;
+class cmSourceGroup;
+
+
+/** \class cmGlobalXCodeGenerator
+ * \brief Write a Unix makefiles.
+ *
+ * cmGlobalXCodeGenerator manages UNIX build process for a tree
+ */
+class cmGlobalXCodeGenerator : public cmGlobalGenerator
+{
+public:
+ cmGlobalXCodeGenerator(std::string const& version);
+ static cmGlobalGenerator* New();
+
+ ///! Get the name for the generator.
+ virtual const char* GetName() const {
+ return cmGlobalXCodeGenerator::GetActualName();}
+ static const char* GetActualName() {return "Xcode";}
+
+ /** Get the documentation entry for this generator. */
+ virtual void GetDocumentation(cmDocumentationEntry& entry) const;
+
+ ///! Create a local generator appropriate to this Global Generator
+ virtual cmLocalGenerator *CreateLocalGenerator();
+
+ /**
+ * Try to determine system infomation such as shared library
+ * extension, pthreads, byte order etc.
+ */
+ virtual void EnableLanguage(std::vector<std::string>const& languages,
+ cmMakefile *, bool optional);
+ /**
+ * 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* 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();
+
+ /** Append the subdirectory for the given configuration. */
+ virtual void AppendDirectoryForConfig(const char* prefix,
+ const char* config,
+ const char* suffix,
+ std::string& dir);
+
+ ///! What is the configurations directory variable called?
+ virtual const char* GetCMakeCFGIntDir() const;
+
+ void SetCurrentLocalGenerator(cmLocalGenerator*);
+
+ /** 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();
+
+private:
+ cmXCodeObject* CreateOrGetPBXGroup(cmTarget& cmtarget,
+ cmSourceGroup* sg);
+ cmXCodeObject* CreatePBXGroup(cmXCodeObject *parent,
+ cmStdString name);
+ void 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,
+ cmXCodeObject* headerBuildPhase,
+ cmXCodeObject* resourceBuildPhase,
+ std::vector<cmXCodeObject*> contentBuildPhases,
+ cmXCodeObject* frameworkBuildPhase,
+ cmTarget& cmtarget);
+
+ std::string ComputeInfoPListLocation(cmTarget& target);
+
+ void AddCommandsToBuildPhase(cmXCodeObject* buildphase,
+ cmTarget& target,
+ std::vector<cmCustomCommand>
+ const & commands,
+ const char* commandFileName);
+
+ void CreateCustomRulesMakefile(const char* makefileBasename,
+ cmTarget& target,
+ std::vector<cmCustomCommand> const & commands,
+ const char* configName,
+ const std::map<cmStdString, cmStdString>&
+ multipleOutputPairs
+ );
+
+ cmXCodeObject* FindXCodeTarget(cmTarget*);
+ std::string GetOrCreateId(const char* name, const char* 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* CreateObjectReference(cmXCodeObject*);
+ cmXCodeObject* CreateXCodeTarget(cmTarget& target,
+ 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 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);
+ void AddDependAndLinkInformation(cmXCodeObject* target);
+ void CreateBuildSettings(cmTarget& target,
+ cmXCodeObject* buildSettings,
+ const char* buildType);
+ std::string ExtractFlag(const char* flag, std::string& flags);
+ // delete all objects in the this->XCodeObjects vector.
+ void ClearXCodeObjects();
+ void 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);
+ cmXCodeObject* CreateXCodeSourceFileFromPath(const std::string &fullpath,
+ cmTarget& cmtarget,
+ const std::string &lang);
+ cmXCodeObject* CreateXCodeFileReference(cmSourceFile* sf,
+ cmTarget& cmtarget);
+ cmXCodeObject* CreateXCodeSourceFile(cmLocalGenerator* gen,
+ cmSourceFile* sf,
+ cmTarget& cmtarget);
+ void CreateXCodeTargets(cmLocalGenerator* gen,
+ std::vector<cmXCodeObject*>&);
+ bool IsHeaderFile(cmSourceFile*);
+ void AddDependTarget(cmXCodeObject* target,
+ cmXCodeObject* dependTarget);
+ void CreateXCodeDependHackTarget(std::vector<cmXCodeObject*>& targets);
+ bool SpecialTargetEmitted(std::string const& tname);
+ void SetGenerationRoot(cmLocalGenerator* root);
+ void AddExtraTargets(cmLocalGenerator* root,
+ std::vector<cmLocalGenerator*>& gens);
+ cmXCodeObject* CreateBuildPhase(const char* name,
+ const char* name2,
+ cmTarget& cmtarget,
+ 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);
+
+ class BuildObjectListOrString;
+ friend class BuildObjectListOrString;
+
+ void AppendDefines(BuildObjectListOrString& defs, const char* defines_list,
+ bool dflag = false);
+ void AppendDefines(BuildObjectListOrString& defs,
+ std::vector<std::string> const& defines,
+ bool dflag = false);
+ void AppendFlag(std::string& flags, std::string const& flag);
+
+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::vector<cmXCodeObject*> XCodeObjects;
+ cmXCodeObject* RootObject;
+private:
+ void ComputeTargetObjects(cmGeneratorTarget* gt) const;
+
+ std::string GetObjectsNormalDirectory(
+ const std::string &projName,
+ const std::string &configName,
+ const cmTarget *t) const;
+
+ void addObject(cmXCodeObject *obj);
+ std::string PostBuildMakeTarget(std::string const& tName,
+ std::string const& configName);
+ cmXCodeObject* MainGroupChildren;
+ cmXCodeObject* SourcesGroupChildren;
+ cmXCodeObject* ResourcesGroupChildren;
+ cmMakefile* CurrentMakefile;
+ cmLocalGenerator* CurrentLocalGenerator;
+ std::vector<std::string> CurrentConfigurationTypes;
+ std::string CurrentReRunCMakeMakefile;
+ std::string CurrentXCodeHackMakefile;
+ std::string CurrentProject;
+ std::set<cmStdString> 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::vector<std::string> Architectures;
+};
+
+#endif
diff --git a/Source/cmGraphAdjacencyList.h b/Source/cmGraphAdjacencyList.h
new file mode 100644
index 000000000..0149d33bd
--- /dev/null
+++ b/Source/cmGraphAdjacencyList.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 cmGraphAdjacencyList_h
+#define cmGraphAdjacencyList_h
+
+#include "cmStandardIncludes.h"
+
+/**
+ * Graph edge representation. Most use cases just need the
+ * destination vertex, so we support conversion to/from an int. We
+ * also store boolean to indicate whether an edge is "strong".
+ */
+class cmGraphEdge
+{
+public:
+ cmGraphEdge(): Dest(0), Strong(true) {}
+ cmGraphEdge(int n): Dest(n), Strong(true) {}
+ cmGraphEdge(int n, bool s): Dest(n), Strong(s) {}
+ cmGraphEdge(cmGraphEdge const& r): Dest(r.Dest), Strong(r.Strong) {}
+ operator int() const { return this->Dest; }
+
+ bool IsStrong() const { return this->Strong; }
+private:
+ int Dest;
+ bool Strong;
+};
+struct cmGraphEdgeList: public std::vector<cmGraphEdge> {};
+struct cmGraphNodeList: public std::vector<int> {};
+struct cmGraphAdjacencyList: public std::vector<cmGraphEdgeList> {};
+
+#endif
diff --git a/Source/cmGraphVizWriter.cxx b/Source/cmGraphVizWriter.cxx
new file mode 100644
index 000000000..15bad5265
--- /dev/null
+++ b/Source/cmGraphVizWriter.cxx
@@ -0,0 +1,587 @@
+/*============================================================================
+ 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 "cmGraphVizWriter.h"
+#include "cmMakefile.h"
+#include "cmLocalGenerator.h"
+#include "cmGlobalGenerator.h"
+#include "cmGeneratedFileStream.h"
+
+#include <memory>
+
+
+
+static const char* getShapeForTarget(const cmTarget* target)
+{
+ if (!target)
+ {
+ return "ellipse";
+ }
+
+ switch ( target->GetType() )
+ {
+ case cmTarget::EXECUTABLE:
+ return "house";
+ case cmTarget::STATIC_LIBRARY:
+ return "diamond";
+ case cmTarget::SHARED_LIBRARY:
+ return "polygon";
+ case cmTarget::MODULE_LIBRARY:
+ return "octagon";
+ default:
+ break;
+ }
+
+ return "box";
+}
+
+
+cmGraphVizWriter::cmGraphVizWriter(const std::vector<cmLocalGenerator*>&
+ localGenerators)
+:GraphType("digraph")
+,GraphName("GG")
+,GraphHeader("node [\n fontsize = \"12\"\n];")
+,GraphNodePrefix("node")
+,GenerateForExecutables(true)
+,GenerateForStaticLibs(true)
+,GenerateForSharedLibs(true)
+,GenerateForModuleLibs(true)
+,GenerateForExternals(true)
+,LocalGenerators(localGenerators)
+,HaveTargetsAndLibs(false)
+{
+}
+
+
+void cmGraphVizWriter::ReadSettings(const char* settingsFileName,
+ const char* fallbackSettingsFileName)
+{
+ cmake cm;
+ cmGlobalGenerator ggi;
+ ggi.SetCMakeInstance(&cm);
+ std::auto_ptr<cmLocalGenerator> lg(ggi.CreateLocalGenerator());
+ cmMakefile *mf = lg->GetMakefile();
+
+ const char* inFileName = settingsFileName;
+
+ if ( !cmSystemTools::FileExists(inFileName) )
+ {
+ inFileName = fallbackSettingsFileName;
+ if ( !cmSystemTools::FileExists(inFileName) )
+ {
+ return;
+ }
+ }
+
+ if ( !mf->ReadListFile(0, inFileName) )
+ {
+ cmSystemTools::Error("Problem opening GraphViz options file: ",
+ inFileName);
+ return;
+ }
+
+ std::cout << "Reading GraphViz options file: " << inFileName << std::endl;
+
+#define __set_if_set(var, cmakeDefinition) \
+ { \
+ const char* value = mf->GetDefinition(cmakeDefinition); \
+ if ( value ) \
+ { \
+ var = value; \
+ } \
+ }
+
+ __set_if_set(this->GraphType, "GRAPHVIZ_GRAPH_TYPE");
+ __set_if_set(this->GraphName, "GRAPHVIZ_GRAPH_NAME");
+ __set_if_set(this->GraphHeader, "GRAPHVIZ_GRAPH_HEADER");
+ __set_if_set(this->GraphNodePrefix, "GRAPHVIZ_NODE_PREFIX");
+
+#define __set_bool_if_set(var, cmakeDefinition) \
+ { \
+ const char* value = mf->GetDefinition(cmakeDefinition); \
+ if ( value ) \
+ { \
+ var = mf->IsOn(cmakeDefinition); \
+ } \
+ }
+
+ __set_bool_if_set(this->GenerateForExecutables, "GRAPHVIZ_EXECUTABLES");
+ __set_bool_if_set(this->GenerateForStaticLibs, "GRAPHVIZ_STATIC_LIBS");
+ __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");
+
+ cmStdString ignoreTargetsRegexes;
+ __set_if_set(ignoreTargetsRegexes, "GRAPHVIZ_IGNORE_TARGETS");
+
+ this->TargetsToIgnoreRegex.clear();
+ if (ignoreTargetsRegexes.size() > 0)
+ {
+ std::vector<std::string> ignoreTargetsRegExVector;
+ cmSystemTools::ExpandListArgument(ignoreTargetsRegexes,
+ ignoreTargetsRegExVector);
+ for(std::vector<std::string>::const_iterator itvIt
+ = ignoreTargetsRegExVector.begin();
+ itvIt != ignoreTargetsRegExVector.end();
+ ++ itvIt )
+ {
+ cmStdString currentRegexString(*itvIt);
+ cmsys::RegularExpression currentRegex;
+ if (!currentRegex.compile(currentRegexString.c_str()))
+ {
+ std::cerr << "Could not compile bad regex \"" << currentRegexString
+ << "\"" << std::endl;
+ }
+ this->TargetsToIgnoreRegex.push_back(currentRegex);
+ }
+ }
+
+}
+
+
+// Iterate over all targets and write for each one a graph which shows
+// which other targets depend on it.
+void cmGraphVizWriter::WriteTargetDependersFiles(const char* fileName)
+{
+ this->CollectTargetsAndLibs();
+
+ for(std::map<cmStdString, const cmTarget*>::const_iterator ptrIt =
+ this->TargetPtrs.begin();
+ ptrIt != this->TargetPtrs.end();
+ ++ptrIt)
+ {
+ if (ptrIt->second == NULL)
+ {
+ continue;
+ }
+
+ if (this->GenerateForTargetType(ptrIt->second->GetType()) == false)
+ {
+ continue;
+ }
+
+ std::string currentFilename = fileName;
+ currentFilename += ".";
+ currentFilename += ptrIt->first;
+ currentFilename += ".dependers";
+
+ cmGeneratedFileStream str(currentFilename.c_str());
+ if ( !str )
+ {
+ return;
+ }
+
+ std::set<std::string> insertedConnections;
+ std::set<std::string> insertedNodes;
+
+ std::cout << "Writing " << currentFilename << "..." << std::endl;
+ this->WriteHeader(str);
+
+ this->WriteDependerConnections(ptrIt->first.c_str(),
+ insertedNodes, insertedConnections, str);
+
+ this->WriteFooter(str);
+ }
+}
+
+
+// Iterate over all targets and write for each one a graph which shows
+// on which targets it depends.
+void cmGraphVizWriter::WritePerTargetFiles(const char* fileName)
+{
+ this->CollectTargetsAndLibs();
+
+ for(std::map<cmStdString, const cmTarget*>::const_iterator ptrIt =
+ this->TargetPtrs.begin();
+ ptrIt != this->TargetPtrs.end();
+ ++ptrIt)
+ {
+ if (ptrIt->second == NULL)
+ {
+ continue;
+ }
+
+ if (this->GenerateForTargetType(ptrIt->second->GetType()) == false)
+ {
+ continue;
+ }
+
+ std::set<std::string> insertedConnections;
+ std::set<std::string> insertedNodes;
+
+ std::string currentFilename = fileName;
+ currentFilename += ".";
+ currentFilename += ptrIt->first;
+ cmGeneratedFileStream str(currentFilename.c_str());
+ if ( !str )
+ {
+ return;
+ }
+
+ std::cout << "Writing " << currentFilename << "..." << std::endl;
+ this->WriteHeader(str);
+
+ this->WriteConnections(ptrIt->first.c_str(),
+ insertedNodes, insertedConnections, str);
+ this->WriteFooter(str);
+ }
+
+}
+
+
+void cmGraphVizWriter::WriteGlobalFile(const char* fileName)
+{
+ this->CollectTargetsAndLibs();
+
+ cmGeneratedFileStream str(fileName);
+ if ( !str )
+ {
+ return;
+ }
+ this->WriteHeader(str);
+
+ std::cout << "Writing " << fileName << "..." << std::endl;
+
+ std::set<std::string> insertedConnections;
+ std::set<std::string> insertedNodes;
+
+ for(std::map<cmStdString, const cmTarget*>::const_iterator ptrIt =
+ this->TargetPtrs.begin();
+ ptrIt != this->TargetPtrs.end();
+ ++ptrIt)
+ {
+ if (ptrIt->second == NULL)
+ {
+ continue;
+ }
+
+ if (this->GenerateForTargetType(ptrIt->second->GetType()) == false)
+ {
+ continue;
+ }
+
+ this->WriteConnections(ptrIt->first.c_str(),
+ insertedNodes, insertedConnections, str);
+ }
+ this->WriteFooter(str);
+}
+
+
+void cmGraphVizWriter::WriteHeader(cmGeneratedFileStream& str) const
+{
+ str << this->GraphType << " " << this->GraphName << " {" << std::endl;
+ str << this->GraphHeader << std::endl;
+}
+
+
+void cmGraphVizWriter::WriteFooter(cmGeneratedFileStream& str) const
+{
+ str << "}" << std::endl;
+}
+
+
+void cmGraphVizWriter::WriteConnections(const char* 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);
+
+ if (targetPtrIt == this->TargetPtrs.end()) // not found at all
+ {
+ return;
+ }
+
+ this->WriteNode(targetName, targetPtrIt->second, insertedNodes, str);
+
+ if (targetPtrIt->second == NULL) // it's an external library
+ {
+ return;
+ }
+
+
+ std::string myNodeName = this->TargetNamesNodes.find(targetName)->second;
+
+ const cmTarget::LinkLibraryVectorType* ll =
+ &(targetPtrIt->second->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 =
+ this->TargetNamesNodes.find(libName);
+
+ // can happen e.g. if GRAPHVIZ_TARGET_IGNORE_REGEX is used
+ if(libNameIt == this->TargetNamesNodes.end())
+ {
+ continue;
+ }
+
+ std::string connectionName = myNodeName;
+ connectionName += "-";
+ connectionName += libNameIt->second;
+ if (insertedConnections.find(connectionName) == insertedConnections.end())
+ {
+ insertedConnections.insert(connectionName);
+ this->WriteNode(libName, this->TargetPtrs.find(libName)->second,
+ insertedNodes, str);
+
+ str << " \"" << myNodeName.c_str() << "\" -> \""
+ << libNameIt->second.c_str() << "\"";
+ str << " // " << targetName << " -> " << libName << std::endl;
+ this->WriteConnections(libName, insertedNodes, insertedConnections, str);
+ }
+ }
+
+}
+
+
+void cmGraphVizWriter::WriteDependerConnections(const char* 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);
+
+ if (targetPtrIt == this->TargetPtrs.end()) // not found at all
+ {
+ return;
+ }
+
+ this->WriteNode(targetName, targetPtrIt->second, insertedNodes, str);
+
+ if (targetPtrIt->second == NULL) // it's an external library
+ {
+ return;
+ }
+
+
+ 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();
+ dependerIt != this->TargetPtrs.end();
+ ++dependerIt)
+ {
+ if (dependerIt->second == NULL)
+ {
+ continue;
+ }
+
+ if (this->GenerateForTargetType(dependerIt->second->GetType()) == false)
+ {
+ continue;
+ }
+
+ // 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());
+
+ for (cmTarget::LinkLibraryVectorType::const_iterator llit = ll->begin();
+ llit != ll->end();
+ ++ llit )
+ {
+ std::string libName = llit->first.c_str();
+ if (libName == targetName)
+ {
+ // So this target links against targetName.
+ std::map<cmStdString, cmStdString>::const_iterator dependerNodeNameIt =
+ this->TargetNamesNodes.find(dependerIt->first);
+
+ if(dependerNodeNameIt != this->TargetNamesNodes.end())
+ {
+ std::string connectionName = dependerNodeNameIt->second;
+ connectionName += "-";
+ connectionName += myNodeName;
+
+ if (insertedConnections.find(connectionName) ==
+ insertedConnections.end())
+ {
+ insertedConnections.insert(connectionName);
+ this->WriteNode(dependerIt->first.c_str(), dependerIt->second,
+ insertedNodes, str);
+
+ str << " \"" << dependerNodeNameIt->second << "\" -> \""
+ << myNodeName << "\"";
+ str << " // " <<targetName<< " -> " <<dependerIt->first<<std::endl;
+ this->WriteDependerConnections(dependerIt->first.c_str(),
+ insertedNodes, insertedConnections, str);
+ }
+
+
+ }
+ break;
+ }
+ }
+ }
+
+}
+
+
+void cmGraphVizWriter::WriteNode(const char* targetName,
+ const cmTarget* 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 =
+ this->TargetNamesNodes.find(targetName);
+
+ str << " \"" << nameIt->second.c_str() << "\" [ label=\""
+ << targetName << "\" shape=\"" << getShapeForTarget(target)
+ << "\"];" << std::endl;
+ }
+}
+
+
+void cmGraphVizWriter::CollectTargetsAndLibs()
+{
+ if (this->HaveTargetsAndLibs == false)
+ {
+ this->HaveTargetsAndLibs = true;
+ int cnt = this->CollectAllTargets();
+ if (this->GenerateForExternals)
+ {
+ this->CollectAllExternalLibs(cnt);
+ }
+ }
+}
+
+
+int cmGraphVizWriter::CollectAllTargets()
+{
+ int cnt = 0;
+ // First pass get the list of all cmake targets
+ for (std::vector<cmLocalGenerator*>::const_iterator lit =
+ this->LocalGenerators.begin();
+ lit != this->LocalGenerators.end();
+ ++ lit )
+ {
+ const cmTargets* targets = &((*lit)->GetMakefile()->GetTargets());
+ for ( cmTargets::const_iterator tit = targets->begin();
+ tit != targets->end();
+ ++ tit )
+ {
+ const char* realTargetName = tit->first.c_str();
+ if(this->IgnoreThisTarget(realTargetName))
+ {
+ // Skip ignored targets
+ continue;
+ }
+ //std::cout << "Found target: " << tit->first.c_str() << std::endl;
+ cmOStringStream ostr;
+ ostr << this->GraphNodePrefix << cnt++;
+ this->TargetNamesNodes[realTargetName] = ostr.str();
+ this->TargetPtrs[realTargetName] = &tit->second;
+ }
+ }
+
+ return cnt;
+}
+
+
+int cmGraphVizWriter::CollectAllExternalLibs(int cnt)
+{
+ // Ok, now find all the stuff we link to that is not in cmake
+ for (std::vector<cmLocalGenerator*>::const_iterator lit =
+ this->LocalGenerators.begin();
+ lit != this->LocalGenerators.end();
+ ++ lit )
+ {
+ const cmTargets* targets = &((*lit)->GetMakefile()->GetTargets());
+ for ( cmTargets::const_iterator tit = targets->begin();
+ tit != targets->end();
+ ++ tit )
+ {
+ const char* realTargetName = tit->first.c_str();
+ if (this->IgnoreThisTarget(realTargetName))
+ {
+ // Skip ignored targets
+ continue;
+ }
+ const cmTarget::LinkLibraryVectorType* ll =
+ &(tit->second.GetOriginalLinkLibraries());
+ for (cmTarget::LinkLibraryVectorType::const_iterator llit = ll->begin();
+ llit != ll->end();
+ ++ llit )
+ {
+ const char* libName = llit->first.c_str();
+ if (this->IgnoreThisTarget(libName))
+ {
+ // Skip ignored targets
+ continue;
+ }
+
+ std::map<cmStdString, const cmTarget*>::const_iterator tarIt =
+ this->TargetPtrs.find(libName);
+ if ( tarIt == this->TargetPtrs.end() )
+ {
+ cmOStringStream ostr;
+ ostr << this->GraphNodePrefix << cnt++;
+ this->TargetNamesNodes[libName] = ostr.str();
+ this->TargetPtrs[libName] = NULL;
+ //str << " \"" << ostr.c_str() << "\" [ label=\"" << libName
+ //<< "\" shape=\"ellipse\"];" << std::endl;
+ }
+ }
+ }
+ }
+ return cnt;
+}
+
+
+bool cmGraphVizWriter::IgnoreThisTarget(const char* name)
+{
+ for(std::vector<cmsys::RegularExpression>::iterator itvIt
+ = this->TargetsToIgnoreRegex.begin();
+ itvIt != this->TargetsToIgnoreRegex.end();
+ ++ itvIt )
+ {
+ cmsys::RegularExpression& regEx = *itvIt;
+ if (regEx.is_valid())
+ {
+ if (regEx.find(name))
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+
+bool cmGraphVizWriter::GenerateForTargetType(cmTarget::TargetType targetType)
+ const
+{
+ switch (targetType)
+ {
+ case cmTarget::EXECUTABLE:
+ return this->GenerateForExecutables;
+ case cmTarget::STATIC_LIBRARY:
+ return this->GenerateForStaticLibs;
+ case cmTarget::SHARED_LIBRARY:
+ return this->GenerateForSharedLibs;
+ case cmTarget::MODULE_LIBRARY:
+ return this->GenerateForModuleLibs;
+ default:
+ break;
+ }
+ return false;
+}
diff --git a/Source/cmGraphVizWriter.h b/Source/cmGraphVizWriter.h
new file mode 100644
index 000000000..f784aa0a1
--- /dev/null
+++ b/Source/cmGraphVizWriter.h
@@ -0,0 +1,89 @@
+#ifndef CMGRAPHVIZWRITER_H
+#define CMGRAPHVIZWRITER_H
+/*============================================================================
+ 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"
+#include "cmLocalGenerator.h"
+#include "cmGeneratedFileStream.h"
+#include "cmTarget.h"
+#include <cmsys/RegularExpression.hxx>
+
+
+/** This class implements writing files for graphviz (dot) for graphs
+ * representing the dependencies between the targets in the project. */
+class cmGraphVizWriter
+{
+public:
+
+ cmGraphVizWriter(const std::vector<cmLocalGenerator*>& localGenerators);
+
+ void ReadSettings(const char* settingsFileName,
+ const char* fallbackSettingsFileName);
+
+ void WritePerTargetFiles(const char* fileName);
+ void WriteTargetDependersFiles(const char* fileName);
+
+ void WriteGlobalFile(const char* fileName);
+
+protected:
+
+ void CollectTargetsAndLibs();
+
+ int CollectAllTargets();
+
+ int CollectAllExternalLibs(int cnt);
+
+ void WriteHeader(cmGeneratedFileStream& str) const;
+
+ void WriteConnections(const char* targetName,
+ std::set<std::string>& insertedNodes,
+ std::set<std::string>& insertedConnections,
+ cmGeneratedFileStream& str) const;
+
+ void WriteDependerConnections(const char* targetName,
+ std::set<std::string>& insertedNodes,
+ std::set<std::string>& insertedConnections,
+ cmGeneratedFileStream& str) const;
+
+ void WriteNode(const char* targetName, const cmTarget* target,
+ std::set<std::string>& insertedNodes,
+ cmGeneratedFileStream& str) const;
+
+ void WriteFooter(cmGeneratedFileStream& str) const;
+
+ bool IgnoreThisTarget(const char* name);
+
+ bool GenerateForTargetType(cmTarget::TargetType targetType) const;
+
+ cmStdString GraphType;
+ cmStdString GraphName;
+ cmStdString GraphHeader;
+ cmStdString GraphNodePrefix;
+
+ bool GenerateForExecutables;
+ bool GenerateForStaticLibs;
+ bool GenerateForSharedLibs;
+ bool GenerateForModuleLibs;
+ bool GenerateForExternals;
+
+ std::vector<cmsys::RegularExpression> TargetsToIgnoreRegex;
+
+ const std::vector<cmLocalGenerator*>& LocalGenerators;
+
+ std::map<cmStdString, const cmTarget*> TargetPtrs;
+ // maps from the actual target names to node names in dot:
+ std::map<cmStdString, cmStdString> TargetNamesNodes;
+
+ bool HaveTargetsAndLibs;
+};
+
+#endif
diff --git a/Source/cmHexFileConverter.cxx b/Source/cmHexFileConverter.cxx
new file mode 100644
index 000000000..2ff794573
--- /dev/null
+++ b/Source/cmHexFileConverter.cxx
@@ -0,0 +1,265 @@
+/*============================================================================
+ 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 "cmHexFileConverter.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#define INTEL_HEX_MIN_LINE_LENGTH (1+8 +2)
+#define INTEL_HEX_MAX_LINE_LENGTH (1+8+(256*2)+2)
+#define MOTOROLA_SREC_MIN_LINE_LENGTH (2+2+4 +2)
+#define MOTOROLA_SREC_MAX_LINE_LENGTH (2+2+8+(256*2)+2)
+
+// might go to SystemTools ?
+static bool cm_IsHexChar(char c)
+{
+ return (((c >= '0') && (c <= '9'))
+ || ((c >= 'a') && (c <= 'f'))
+ || ((c >= 'A') && (c <= 'F')));
+}
+
+static unsigned int ChompStrlen(const char* line)
+{
+ if (line == 0)
+ {
+ return 0;
+ }
+ unsigned int length = static_cast<unsigned int>(strlen(line));
+ if ((line[length-1] == '\n') || (line[length-1] == '\r'))
+ {
+ length--;
+ }
+ if ((line[length-1] == '\n') || (line[length-1] == '\r'))
+ {
+ length--;
+ }
+ return length;
+}
+
+static bool OutputBin(FILE* file, const char * buf,
+ unsigned int startIndex, unsigned int stopIndex)
+{
+ bool success = true;
+ char hexNumber[3];
+ hexNumber[2] = '\0';
+ char outBuf[256];
+ unsigned int outBufCount = 0;
+ for (unsigned int i = startIndex; i < stopIndex; i += 2)
+ {
+ hexNumber[0] = buf[i];
+ hexNumber[1] = buf[i+1];
+ unsigned int convertedByte = 0;
+ if (sscanf(hexNumber, "%x", &convertedByte) != 1)
+ {
+ success = false;
+ break;
+ }
+ outBuf[outBufCount] = static_cast<char>(convertedByte & 0xff);
+ outBufCount++;
+ }
+ if (success)
+ {
+ success = (fwrite(outBuf, 1, outBufCount, file)==outBufCount);
+ }
+ return success;
+}
+
+// see http://www.die.net/doc/linux/man/man5/srec.5.html
+static bool ConvertMotorolaSrecLine(const char* buf, FILE* outFile)
+{
+ unsigned int slen = ChompStrlen(buf);
+ if ((slen < MOTOROLA_SREC_MIN_LINE_LENGTH)
+ || (slen > MOTOROLA_SREC_MAX_LINE_LENGTH))
+ {
+ return false;
+ }
+
+ // line length must be even
+ if (slen % 2 == 1)
+ {
+ return false;
+ }
+
+ if (buf[0] != 'S')
+ {
+ return false;
+ }
+
+ unsigned int dataStart = 0;
+ // ignore extra address records
+ if ((buf[1] == '5') || (buf[1] == '7') || (buf[1] == '8') || (buf[1] == '9'))
+ {
+ return true;
+ }
+ else if (buf[1] == '1')
+ {
+ dataStart = 8;
+ }
+ else if (buf[1] == '2')
+ {
+ dataStart = 10;
+ }
+ else if (buf[1] == '3')
+ {
+ dataStart = 12;
+ }
+ else // unknown record type
+ {
+ return false;
+ }
+
+ // ignore the last two bytes (checksum)
+ return OutputBin(outFile, buf, dataStart, slen - 2);
+}
+
+// see http://en.wikipedia.org/wiki/Intel_hex
+static bool ConvertIntelHexLine(const char* buf, FILE* outFile)
+{
+ unsigned int slen = ChompStrlen(buf);
+ if ((slen < INTEL_HEX_MIN_LINE_LENGTH)
+ || (slen > INTEL_HEX_MAX_LINE_LENGTH))
+ {
+ return false;
+ }
+
+ // line length must be odd
+ if (slen % 2 == 0)
+ {
+ return false;
+ }
+
+ if ((buf[0] != ':') || (buf[7] != '0'))
+ {
+ return false;
+ }
+
+ unsigned int dataStart = 0;
+ if ((buf[8] == '0') || (buf[8] == '1'))
+ {
+ dataStart = 9;
+ }
+ // ignore extra address records
+ else if ((buf[8] == '2') || (buf[8] == '3') || (buf[8] == '4')
+ || (buf[8] == '5'))
+ {
+ return true;
+ }
+ else // unknown record type
+ {
+ return false;
+ }
+
+// ignore the last two bytes (checksum)
+ return OutputBin(outFile, buf, dataStart, slen - 2);
+}
+
+cmHexFileConverter::FileType cmHexFileConverter::DetermineFileType(
+ const char* inFileName)
+{
+ char buf[1024];
+ FILE* inFile = fopen(inFileName, "rb");
+ if (inFile == 0)
+ {
+ return Binary;
+ }
+
+ if(!fgets(buf, 1024, inFile))
+ {
+ buf[0] = 0;
+ }
+ fclose(inFile);
+ FileType type = Binary;
+ unsigned int minLineLength = 0;
+ unsigned int maxLineLength = 0;
+ if (buf[0] == ':') // might be an intel hex file
+ {
+ type = IntelHex;
+ minLineLength = INTEL_HEX_MIN_LINE_LENGTH;
+ maxLineLength = INTEL_HEX_MAX_LINE_LENGTH;
+ }
+ else if (buf[0] == 'S') // might be a motorola srec file
+ {
+ type = MotorolaSrec;
+ minLineLength = MOTOROLA_SREC_MIN_LINE_LENGTH;
+ maxLineLength = MOTOROLA_SREC_MAX_LINE_LENGTH;
+ }
+ else
+ {
+ return Binary;
+ }
+
+ unsigned int slen = ChompStrlen(buf);
+ if ((slen < minLineLength) || (slen > maxLineLength))
+ {
+ return Binary;
+ }
+
+ for (unsigned int i = 1; i < slen; i++)
+ {
+ if (!cm_IsHexChar(buf[i]))
+ {
+ return Binary;
+ }
+ }
+ return type;
+}
+
+bool cmHexFileConverter::TryConvert(const char* inFileName,
+ const char* outFileName)
+{
+ FileType type = DetermineFileType(inFileName);
+ if (type == Binary)
+ {
+ return false;
+ }
+
+ // try to open the file
+ FILE* inFile = fopen(inFileName, "rb");
+ FILE* outFile = fopen(outFileName, "wb");
+ if ((inFile == 0) || (outFile == 0))
+ {
+ if (inFile != 0)
+ {
+ fclose(inFile);
+ }
+ if (outFile != 0)
+ {
+ fclose(outFile);
+ }
+ return false;
+ }
+
+ // convert them line by line
+ bool success = false;
+ char buf[1024];
+ while (fgets(buf, 1024, inFile) != 0)
+ {
+ if (type == MotorolaSrec)
+ {
+ success = ConvertMotorolaSrecLine(buf, outFile);
+ }
+ else if (type == IntelHex)
+ {
+ success = ConvertIntelHexLine(buf, outFile);
+ }
+ if (success == false)
+ {
+ break;
+ }
+ }
+
+ // close them again
+ fclose(inFile);
+ fclose(outFile);
+ return success;
+}
+
diff --git a/Source/cmHexFileConverter.h b/Source/cmHexFileConverter.h
new file mode 100644
index 000000000..94c757f79
--- /dev/null
+++ b/Source/cmHexFileConverter.h
@@ -0,0 +1,28 @@
+/*============================================================================
+ 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 cmHexFileConverter_h
+#define cmHexFileConverter_h
+
+/** \class cmHexFileConverter
+ * \brief Can detects Intel Hex and Motorola S-record files and convert them
+ * to binary files.
+ *
+ */
+class cmHexFileConverter
+{
+public:
+ enum FileType {Binary, IntelHex, MotorolaSrec};
+ static FileType DetermineFileType(const char* inFileName);
+ static bool TryConvert(const char* inFileName, const char* outFileName);
+};
+
+#endif
diff --git a/Source/cmIDEFlagTable.h b/Source/cmIDEFlagTable.h
new file mode 100644
index 000000000..e372c0a15
--- /dev/null
+++ b/Source/cmIDEFlagTable.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 cmIDEFlagTable_h
+#define cmIDEFlagTable_h
+
+// This is a table mapping XML tag IDE names to command line options
+struct cmIDEFlagTable
+{
+ const char* IDEName; // name used in the IDE xml file
+ const char* commandFlag; // command line flag
+ const char* comment; // comment
+ const char* value; // string value
+ unsigned int special; // flags for special handling requests
+ enum
+ {
+ UserValue = (1<<0), // flag contains a user-specified value
+ UserIgnored = (1<<1), // ignore any user value
+ UserRequired = (1<<2), // match only when user value is non-empty
+ Continue = (1<<3), // continue looking for matching entries
+ SemicolonAppendable = (1<<4), // a flag that if specified multiple times
+ // should have its value appended to the
+ // old value with semicolons (e.g.
+ // /NODEFAULTLIB: =>
+ // IgnoreDefaultLibraryNames)
+
+ UserValueIgnored = UserValue | UserIgnored,
+ UserValueRequired = UserValue | UserRequired
+ };
+};
+
+#endif
diff --git a/Source/cmIDEOptions.cxx b/Source/cmIDEOptions.cxx
new file mode 100644
index 000000000..d9c0e87e9
--- /dev/null
+++ b/Source/cmIDEOptions.cxx
@@ -0,0 +1,179 @@
+/*============================================================================
+ 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 "cmIDEOptions.h"
+
+#include "cmSystemTools.h"
+
+//----------------------------------------------------------------------------
+cmIDEOptions::cmIDEOptions()
+{
+ this->DoingDefine = false;
+ this->AllowDefine = true;
+ this->AllowSlash = false;
+ for(int i=0; i < FlagTableCount; ++i)
+ {
+ this->FlagTable[i] = 0;
+ }
+}
+
+//----------------------------------------------------------------------------
+cmIDEOptions::~cmIDEOptions()
+{
+}
+
+//----------------------------------------------------------------------------
+void cmIDEOptions::HandleFlag(const char* flag)
+{
+ // If the last option was -D then this option is the definition.
+ if(this->DoingDefine)
+ {
+ this->DoingDefine = false;
+ this->Defines.push_back(flag);
+ return;
+ }
+
+ // Look for known arguments.
+ if(flag[0] == '-' || (this->AllowSlash && flag[0] == '/'))
+ {
+ // Look for preprocessor definitions.
+ if(this->AllowDefine && flag[1] == 'D')
+ {
+ if(flag[2] == '\0')
+ {
+ // The next argument will have the definition.
+ this->DoingDefine = true;
+ }
+ else
+ {
+ // Store this definition.
+ this->Defines.push_back(flag+2);
+ }
+ return;
+ }
+
+ // Look through the available flag tables.
+ bool flag_handled = false;
+ for(int i=0; i < FlagTableCount && this->FlagTable[i]; ++i)
+ {
+ if(this->CheckFlagTable(this->FlagTable[i], flag, flag_handled))
+ {
+ return;
+ }
+ }
+
+ // If any map entry handled the flag we are done.
+ if(flag_handled)
+ {
+ return;
+ }
+ }
+
+ // This option is not known. Store it in the output flags.
+ this->StoreUnknownFlag(flag);
+}
+
+//----------------------------------------------------------------------------
+bool cmIDEOptions::CheckFlagTable(cmIDEFlagTable const* table,
+ const char* flag, bool& flag_handled)
+{
+ // Look for an entry in the flag table matching this flag.
+ for(cmIDEFlagTable const* entry = table; entry->IDEName; ++entry)
+ {
+ bool entry_found = false;
+ if(entry->special & cmIDEFlagTable::UserValue)
+ {
+ // This flag table entry accepts a user-specified value. If
+ // 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 &&
+ (!(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;
+ }
+ entry_found = true;
+ }
+ }
+ else if(strcmp(flag+1, entry->commandFlag) == 0)
+ {
+ // This flag table entry provides a fixed value.
+ this->FlagMap[entry->IDEName] = entry->value;
+ entry_found = true;
+ }
+
+ // If the flag has been handled by an entry not requesting a
+ // search continuation we are done.
+ if(entry_found && !(entry->special & cmIDEFlagTable::Continue))
+ {
+ return true;
+ }
+
+ // If the entry was found the flag has been handled.
+ flag_handled = flag_handled || entry_found;
+ }
+
+ return false;
+}
+
+//----------------------------------------------------------------------------
+void cmIDEOptions::AddDefine(const std::string& def)
+{
+ this->Defines.push_back(def);
+}
+
+//----------------------------------------------------------------------------
+void cmIDEOptions::AddDefines(const char* defines)
+{
+ if(defines)
+ {
+ // Expand the list of definitions.
+ cmSystemTools::ExpandListArgument(defines, this->Defines);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmIDEOptions::AddFlag(const char* flag, const char* value)
+{
+ this->FlagMap[flag] = value;
+}
+
+//----------------------------------------------------------------------------
+void cmIDEOptions::RemoveFlag(const char* flag)
+{
+ this->FlagMap.erase(flag);
+}
diff --git a/Source/cmIDEOptions.h b/Source/cmIDEOptions.h
new file mode 100644
index 000000000..a5be8fbd5
--- /dev/null
+++ b/Source/cmIDEOptions.h
@@ -0,0 +1,60 @@
+/*============================================================================
+ 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 cmIDEOptions_h
+#define cmIDEOptions_h
+
+#include "cmStandardIncludes.h"
+#include "cmIDEFlagTable.h"
+
+/** \class cmIDEOptions
+ * \brief Superclass for IDE option processing
+ */
+class cmIDEOptions
+{
+public:
+ cmIDEOptions();
+ virtual ~cmIDEOptions();
+
+ // Store definitions and flags.
+ void AddDefine(const std::string& define);
+ void AddDefines(const char* defines);
+ void AddFlag(const char* flag, const char* value);
+ void RemoveFlag(const char* flag);
+
+protected:
+ // create a map of xml tags to the values they should have in the output
+ // for example, "BufferSecurityCheck" = "TRUE"
+ // first fill this table with the values for the configuration
+ // Debug, Release, etc,
+ // 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;
+
+ // Preprocessor definitions.
+ std::vector<std::string> Defines;
+
+ // Unrecognized flags that get no special handling.
+ cmStdString FlagString;
+
+ bool DoingDefine;
+ bool AllowDefine;
+ bool AllowSlash;
+ enum { FlagTableCount = 16 };
+ cmIDEFlagTable const* FlagTable[FlagTableCount];
+ void HandleFlag(const char* flag);
+ bool CheckFlagTable(cmIDEFlagTable const* table, const char* flag,
+ bool& flag_handled);
+ virtual void StoreUnknownFlag(const char* flag) = 0;
+};
+
+#endif
diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx
new file mode 100644
index 000000000..ffc0f35b8
--- /dev/null
+++ b/Source/cmIfCommand.cxx
@@ -0,0 +1,947 @@
+/*============================================================================
+ 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 "cmIfCommand.h"
+#include "cmStringCommand.h"
+
+#include <stdlib.h> // required for atof
+#include <list>
+#include <cmsys/RegularExpression.hxx>
+
+
+static std::string cmIfCommandError(
+ cmMakefile* mf, std::vector<std::string> const& args)
+{
+ cmLocalGenerator* lg = mf->GetLocalGenerator();
+ std::string err = "given arguments:\n ";
+ for(std::vector<std::string>::const_iterator i = args.begin();
+ i != args.end(); ++i)
+ {
+ err += " ";
+ err += lg->EscapeForCMake(i->c_str());
+ }
+ err += "\n";
+ return err;
+}
+
+//=========================================================================
+bool cmIfFunctionBlocker::
+IsFunctionBlocked(const cmListFileFunction& lff,
+ cmMakefile &mf,
+ cmExecutionStatus &inStatus)
+{
+ // we start by recording all the functions
+ if (!cmSystemTools::Strucmp(lff.Name.c_str(),"if"))
+ {
+ this->ScopeDepth++;
+ }
+ if (!cmSystemTools::Strucmp(lff.Name.c_str(),"endif"))
+ {
+ this->ScopeDepth--;
+ // if this is the endif for this if statement, then start executing
+ if (!this->ScopeDepth)
+ {
+ // Remove the function blocker for this scope or bail.
+ cmsys::auto_ptr<cmFunctionBlocker>
+ fb(mf.RemoveFunctionBlocker(this, lff));
+ if(!fb.get()) { return false; }
+
+ // execute the functions for the true parts of the if statement
+ cmExecutionStatus status;
+ int scopeDepth = 0;
+ for(unsigned int c = 0; c < this->Functions.size(); ++c)
+ {
+ // keep track of scope depth
+ if (!cmSystemTools::Strucmp(this->Functions[c].Name.c_str(),"if"))
+ {
+ scopeDepth++;
+ }
+ if (!cmSystemTools::Strucmp(this->Functions[c].Name.c_str(),"endif"))
+ {
+ scopeDepth--;
+ }
+ // watch for our state change
+ if (scopeDepth == 0 &&
+ !cmSystemTools::Strucmp(this->Functions[c].Name.c_str(),"else"))
+ {
+ this->IsBlocking = this->HasRun;
+ this->HasRun = true;
+
+ // if trace is enabled, print a (trivially) evaluated "else"
+ // statement
+ if(!this->IsBlocking && mf.GetCMakeInstance()->GetTrace())
+ {
+ mf.PrintCommandTrace(this->Functions[c]);
+ }
+ }
+ else if (scopeDepth == 0 && !cmSystemTools::Strucmp
+ (this->Functions[c].Name.c_str(),"elseif"))
+ {
+ if (this->HasRun)
+ {
+ this->IsBlocking = true;
+ }
+ 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())
+ {
+ mf.PrintCommandTrace(this->Functions[c]);
+ }
+
+ std::string errorString;
+
+ std::vector<std::string> expandedArguments;
+ mf.ExpandArguments(this->Functions[c].Arguments,
+ expandedArguments);
+
+ cmake::MessageType messType;
+ bool isTrue =
+ cmIfCommand::IsTrue(expandedArguments, errorString,
+ &mf, messType);
+
+ if (errorString.size())
+ {
+ std::string err = cmIfCommandError(&mf, expandedArguments);
+ err += errorString;
+ mf.IssueMessage(messType, err);
+ if (messType == cmake::FATAL_ERROR)
+ {
+ cmSystemTools::SetFatalErrorOccured();
+ return true;
+ }
+ }
+
+ if (isTrue)
+ {
+ this->IsBlocking = false;
+ this->HasRun = true;
+ }
+ }
+ }
+
+ // should we execute?
+ else if (!this->IsBlocking)
+ {
+ status.Clear();
+ mf.ExecuteCommand(this->Functions[c],status);
+ if (status.GetReturnInvoked())
+ {
+ inStatus.SetReturnInvoked(true);
+ return true;
+ }
+ if (status.GetBreakInvoked())
+ {
+ inStatus.SetBreakInvoked(true);
+ return true;
+ }
+ }
+ }
+ return true;
+ }
+ }
+
+ // record the command
+ this->Functions.push_back(lff);
+
+ // always return true
+ return true;
+}
+
+//=========================================================================
+bool cmIfFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
+ cmMakefile&)
+{
+ if (!cmSystemTools::Strucmp(lff.Name.c_str(),"endif"))
+ {
+ // if the endif has arguments, then make sure
+ // they match the arguments of the matching if
+ if (lff.Arguments.size() == 0 ||
+ lff.Arguments == this->Args)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+//=========================================================================
+bool cmIfCommand
+::InvokeInitialPass(const std::vector<cmListFileArgument>& args,
+ cmExecutionStatus &)
+{
+ std::string errorString;
+
+ std::vector<std::string> expandedArguments;
+ this->Makefile->ExpandArguments(args, expandedArguments);
+
+ cmake::MessageType status;
+ bool isTrue =
+ cmIfCommand::IsTrue(expandedArguments,errorString,
+ this->Makefile, status);
+
+ if (errorString.size())
+ {
+ std::string err = cmIfCommandError(this->Makefile, expandedArguments);
+ err += errorString;
+ if (status == cmake::FATAL_ERROR)
+ {
+ this->SetError(err.c_str());
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+ else
+ {
+ this->Makefile->IssueMessage(status, err);
+ }
+ }
+
+ cmIfFunctionBlocker *f = new cmIfFunctionBlocker();
+ // if is isn't true block the commands
+ f->ScopeDepth = 1;
+ f->IsBlocking = !isTrue;
+ if (isTrue)
+ {
+ f->HasRun = true;
+ }
+ f->Args = args;
+ this->Makefile->AddFunctionBlocker(f);
+
+ 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;
+ }
+
+ //=========================================================================
+ enum Op { OpLess, OpEqual, OpGreater };
+ bool HandleVersionCompare(Op op, const char* lhs_str, const char* rhs_str)
+ {
+ // Parse out up to 4 components.
+ unsigned int lhs[4] = {0,0,0,0};
+ unsigned int rhs[4] = {0,0,0,0};
+ sscanf(lhs_str, "%u.%u.%u.%u", &lhs[0], &lhs[1], &lhs[2], &lhs[3]);
+ sscanf(rhs_str, "%u.%u.%u.%u", &rhs[0], &rhs[1], &rhs[2], &rhs[3]);
+
+ // Do component-wise comparison.
+ for(unsigned int i=0; i < 4; ++i)
+ {
+ if(lhs[i] < rhs[i])
+ {
+ // lhs < rhs, so true if operation is LESS
+ return op == OpLess;
+ }
+ else if(lhs[i] > rhs[i])
+ {
+ // lhs > rhs, so true if operation is GREATER
+ return op == OpGreater;
+ }
+ }
+ // lhs == rhs, so true if operation is EQUAL
+ return op == OpEqual;
+ }
+
+ //=========================================================================
+ // 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);
+ Op op = OpEqual;
+ if(*argP1 == "VERSION_LESS")
+ {
+ op = OpLess;
+ }
+ else if(*argP1 == "VERSION_GREATER")
+ {
+ op = OpGreater;
+ }
+ bool result = HandleVersionCompare(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
new file mode 100644
index 000000000..94e4d998a
--- /dev/null
+++ b/Source/cmIfCommand.h
@@ -0,0 +1,261 @@
+/*============================================================================
+ 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 cmIfCommand_h
+#define cmIfCommand_h
+
+#include "cmCommand.h"
+#include "cmFunctionBlocker.h"
+
+class cmIfFunctionBlocker : public cmFunctionBlocker
+{
+public:
+ cmIfFunctionBlocker() {
+ this->HasRun = false; this->ScopeDepth = 0; }
+ virtual ~cmIfFunctionBlocker() {}
+ virtual bool IsFunctionBlocked(const cmListFileFunction& lff,
+ cmMakefile &mf,
+ cmExecutionStatus &);
+ virtual bool ShouldRemove(const cmListFileFunction& lff,
+ cmMakefile &mf);
+
+ std::vector<cmListFileArgument> Args;
+ std::vector<cmListFileFunction> Functions;
+ bool IsBlocking;
+ bool HasRun;
+ unsigned int ScopeDepth;
+};
+
+/// Starts an if block
+class cmIfCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmIfCommand;
+ }
+
+ /**
+ * This overrides the default InvokeInitialPass implementation.
+ * It records the arguments before expansion.
+ */
+ virtual bool InvokeInitialPass(const std::vector<cmListFileArgument>& args,
+ cmExecutionStatus &);
+
+ /**
+ * This is called when the command is first encountered in
+ * the CMakeLists.txt file.
+ */
+ virtual bool InitialPass(std::vector<std::string> const&,
+ 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.";
+ }
+
+ /**
+ * 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, \"\", "
+ "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.\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);
+
+ cmTypeMacro(cmIfCommand, cmCommand);
+};
+
+
+#endif
diff --git a/Source/cmIncludeCommand.cxx b/Source/cmIncludeCommand.cxx
new file mode 100644
index 000000000..0d5f67b78
--- /dev/null
+++ b/Source/cmIncludeCommand.cxx
@@ -0,0 +1,116 @@
+/*============================================================================
+ 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 "cmIncludeCommand.h"
+
+
+// cmIncludeCommand
+bool cmIncludeCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if (args.size()< 1 || args.size() > 4)
+ {
+ this->SetError("called with wrong number of arguments. "
+ "Include only takes one file.");
+ return false;
+ }
+ bool optional = false;
+ bool noPolicyScope = false;
+ std::string fname = args[0];
+ std::string resultVarName;
+
+ for (unsigned int i=1; i<args.size(); i++)
+ {
+ if (args[i] == "OPTIONAL")
+ {
+ if (optional)
+ {
+ this->SetError("called with invalid arguments: OPTIONAL used twice");
+ return false;
+ }
+ optional = true;
+ }
+ else if(args[i] == "RESULT_VARIABLE")
+ {
+ if (resultVarName.size() > 0)
+ {
+ this->SetError("called with invalid arguments: "
+ "only one result variable allowed");
+ return false;
+ }
+ if(++i < args.size())
+ {
+ resultVarName = args[i];
+ }
+ else
+ {
+ this->SetError("called with no value for RESULT_VARIABLE.");
+ return false;
+ }
+ }
+ else if(args[i] == "NO_POLICY_SCOPE")
+ {
+ noPolicyScope = true;
+ }
+ else if(i > 1) // compat.: in previous cmake versions the second
+ // parameter was ignore if it wasn't "OPTIONAL"
+ {
+ std::string errorText = "called with invalid argument: ";
+ errorText += args[i];
+ this->SetError(errorText.c_str());
+ return false;
+ }
+ }
+
+ if(fname.empty())
+ {
+ this->Makefile->IssueMessage(cmake::AUTHOR_WARNING,
+ "include() given empty file name (ignored).");
+ return true;
+ }
+
+ if(!cmSystemTools::FileIsFullPath(fname.c_str()))
+ {
+ // Not a path. Maybe module.
+ std::string module = fname;
+ module += ".cmake";
+ std::string mfile = this->Makefile->GetModulesFile(module.c_str());
+ if ( mfile.size() )
+ {
+ fname = mfile.c_str();
+ }
+ }
+ std::string fullFilePath;
+ bool readit =
+ this->Makefile->ReadListFile( this->Makefile->GetCurrentListFile(),
+ fname.c_str(), &fullFilePath,
+ noPolicyScope);
+
+ // add the location of the included file if a result variable was given
+ if (resultVarName.size())
+ {
+ this->Makefile->AddDefinition(resultVarName.c_str(),
+ readit?fullFilePath.c_str():"NOTFOUND");
+ }
+
+ if(!optional && !readit && !cmSystemTools::GetFatalErrorOccured())
+ {
+ std::string m =
+ "could not find load file:\n"
+ " ";
+ m += fname;
+ this->SetError(m.c_str());
+ return false;
+ }
+ return true;
+}
+
+
diff --git a/Source/cmIncludeCommand.h b/Source/cmIncludeCommand.h
new file mode 100644
index 000000000..c46c02d71
--- /dev/null
+++ b/Source/cmIncludeCommand.h
@@ -0,0 +1,92 @@
+/*============================================================================
+ 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 cmIncludeCommand_h
+#define cmIncludeCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmIncludeCommand
+ * \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.
+ */
+class cmIncludeCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmIncludeCommand;
+ }
+
+ /**
+ * 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 const char* GetName() const {return "include";}
+
+ /**
+ * Succinct documentation.
+ */
+ virtual const char* GetTerseDocumentation() const
+ {
+ return "Read CMake listfile code from the given file.";
+ }
+
+ /**
+ * More documentation.
+ */
+ virtual const char* GetFullDocumentation() const
+ {
+ return
+ " include(<file|module> [OPTIONAL] [RESULT_VARIABLE <VAR>]\n"
+ " [NO_POLICY_SCOPE])\n"
+ "Reads CMake listfile code from the given file. Commands in the file "
+ "are processed immediately as if they were written in place of the "
+ "include command. 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."
+ ;
+ }
+
+ cmTypeMacro(cmIncludeCommand, cmCommand);
+};
+
+
+
+#endif
diff --git a/Source/cmIncludeDirectoryCommand.cxx b/Source/cmIncludeDirectoryCommand.cxx
new file mode 100644
index 000000000..9e6f4b6ef
--- /dev/null
+++ b/Source/cmIncludeDirectoryCommand.cxx
@@ -0,0 +1,120 @@
+/*============================================================================
+ 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 "cmIncludeDirectoryCommand.h"
+
+// cmIncludeDirectoryCommand
+bool cmIncludeDirectoryCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 1 )
+ {
+ return true;
+ }
+
+ std::vector<std::string>::const_iterator i = args.begin();
+
+ bool before = this->Makefile->IsOn("CMAKE_INCLUDE_DIRECTORIES_BEFORE");
+ bool system = false;
+
+ if ((*i) == "BEFORE")
+ {
+ before = true;
+ ++i;
+ }
+ else if ((*i) == "AFTER")
+ {
+ before = false;
+ ++i;
+ }
+
+ for(; i != args.end(); ++i)
+ {
+ if(*i == "SYSTEM")
+ {
+ system = true;
+ continue;
+ }
+ if(i->size() == 0)
+ {
+ this->SetError("given empty-string as include directory.");
+ return false;
+ }
+
+ this->AddDirectory(i->c_str(),before,system);
+
+ }
+ return true;
+}
+
+// do a lot of cleanup on the arguments because this is one place where folks
+// sometimes take the output of a program and pass it directly into this
+// command not thinking that a single argument could be filled with spaces
+// and newlines etc liek below:
+//
+// " /foo/bar
+// /boo/hoo /dingle/berry "
+//
+// ideally that should be three separate arguments but when sucking the
+// output from a program and passing it into a command the cleanup doesn't
+// always happen
+//
+void cmIncludeDirectoryCommand::AddDirectory(const char *i,
+ bool before,
+ bool system)
+{
+ // break apart any line feed arguments
+ std::string ret = i;
+ std::string::size_type pos = 0;
+ if((pos = ret.find('\n', pos)) != std::string::npos)
+ {
+ if (pos)
+ {
+ this->AddDirectory(ret.substr(0,pos).c_str(), before, system);
+ }
+ if (ret.size()-pos-1)
+ {
+ this->AddDirectory(ret.substr(pos+1,ret.size()-pos-1).c_str(),
+ before, system);
+ }
+ return;
+ }
+
+ // remove any leading or trailing spaces and \r
+ std::string::size_type b = ret.find_first_not_of(" \r");
+ std::string::size_type e = ret.find_last_not_of(" \r");
+ if ((b!=ret.npos) && (e!=ret.npos))
+ {
+ ret.assign(ret, b, 1+e-b); // copy the remaining substring
+ }
+ else
+ {
+ return; // if we get here, we had only whitespace in the string
+ }
+
+ if (!cmSystemTools::IsOff(ret.c_str()))
+ {
+ cmSystemTools::ConvertToUnixSlashes(ret);
+ if(!cmSystemTools::FileIsFullPath(ret.c_str()))
+ {
+ std::string tmp = this->Makefile->GetStartDirectory();
+ tmp += "/";
+ tmp += ret;
+ ret = tmp;
+ }
+ }
+ this->Makefile->AddIncludeDirectory(ret.c_str(), before);
+ if(system)
+ {
+ this->Makefile->AddSystemIncludeDirectory(ret.c_str());
+ }
+}
+
diff --git a/Source/cmIncludeDirectoryCommand.h b/Source/cmIncludeDirectoryCommand.h
new file mode 100644
index 000000000..dcc116aa8
--- /dev/null
+++ b/Source/cmIncludeDirectoryCommand.h
@@ -0,0 +1,89 @@
+/*============================================================================
+ 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 cmIncludeDirectoryCommand_h
+#define cmIncludeDirectoryCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmIncludeDirectoryCommand
+ * \brief Add include directories to the build.
+ *
+ * cmIncludeDirectoryCommand is used to specify directory locations
+ * to search for included files.
+ */
+class cmIncludeDirectoryCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmIncludeDirectoryCommand;
+ }
+
+ /**
+ * 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 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. "
+ "These 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. "
+ "If the SYSTEM option is given, the compiler will be told the "
+ "directories are meant as system include directories on some "
+ "platforms.";
+ }
+
+ cmTypeMacro(cmIncludeDirectoryCommand, cmCommand);
+
+protected:
+ // used internally
+ void AddDirectory(const char *arg, bool before, bool system);
+};
+
+
+
+#endif
diff --git a/Source/cmIncludeExternalMSProjectCommand.cxx b/Source/cmIncludeExternalMSProjectCommand.cxx
new file mode 100644
index 000000000..d219c169a
--- /dev/null
+++ b/Source/cmIncludeExternalMSProjectCommand.cxx
@@ -0,0 +1,101 @@
+/*============================================================================
+ 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 "cmIncludeExternalMSProjectCommand.h"
+
+// cmIncludeExternalMSProjectCommand
+bool cmIncludeExternalMSProjectCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 2)
+ {
+ this->SetError("INCLUDE_EXTERNAL_MSPROJECT called with incorrect "
+ "number of arguments");
+ return false;
+ }
+// only compile this for win32 to avoid coverage errors
+#ifdef _WIN32
+ if(this->Makefile->GetDefinition("WIN32"))
+ {
+ enum Doing { DoingNone, DoingType, DoingGuid, DoingPlatform };
+
+ Doing doing = DoingNone;
+
+ std::string customType;
+ std::string customGuid;
+ std::string platformMapping;
+
+ std::vector<std::string> depends;
+ for (unsigned int i=2; i<args.size(); ++i)
+ {
+ if (args[i] == "TYPE")
+ {
+ doing = DoingType;
+ }
+ else if (args[i] == "GUID")
+ {
+ doing = DoingGuid;
+ }
+ else if (args[i] == "PLATFORM")
+ {
+ doing = DoingPlatform;
+ }
+ else
+ {
+ switch (doing)
+ {
+ case DoingNone: depends.push_back(args[i]); break;
+ case DoingType: customType = args[i]; break;
+ case DoingGuid: customGuid = args[i]; break;
+ case DoingPlatform: platformMapping = args[i]; break;
+ }
+ doing = DoingNone;
+ }
+ }
+
+ // Hack together a utility target storing enough information
+ // to reproduce the target inclusion.
+ std::string utility_name = args[0];
+
+ std::string path = args[1];
+ cmSystemTools::ConvertToUnixSlashes(path);
+
+ if (!customGuid.empty())
+ {
+ std::string guidVariable = utility_name + "_GUID_CMAKE";
+ this->Makefile->GetCMakeInstance()->AddCacheEntry(
+ guidVariable.c_str(), customGuid.c_str(),
+ "Stored GUID", cmCacheManager::INTERNAL);
+ }
+
+ // Create a target instance for this utility.
+ cmTarget* target=this->Makefile->AddNewTarget(cmTarget::UTILITY,
+ utility_name.c_str());
+
+ target->SetProperty("GENERATOR_FILE_NAME", utility_name.c_str());
+ target->SetProperty("EXTERNAL_MSPROJECT", path.c_str());
+ target->SetProperty("EXCLUDE_FROM_ALL", "FALSE");
+
+ if (!customType.empty())
+ target->SetProperty("VS_PROJECT_TYPE",customType.c_str());
+ if (!platformMapping.empty())
+ target->SetProperty("VS_PLATFORM_MAPPING",platformMapping.c_str());
+
+ for (std::vector<std::string>::const_iterator it = depends.begin();
+ it != depends.end();
+ ++it)
+ {
+ target->AddUtility(it->c_str());
+ }
+ }
+#endif
+ return true;
+}
diff --git a/Source/cmIncludeExternalMSProjectCommand.h b/Source/cmIncludeExternalMSProjectCommand.h
new file mode 100644
index 000000000..2b2ed0d15
--- /dev/null
+++ b/Source/cmIncludeExternalMSProjectCommand.h
@@ -0,0 +1,84 @@
+/*============================================================================
+ 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 cmIncludeExternalMSProjectCommand_h
+#define cmIncludeExternalMSProjectCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmIncludeExternalMSProjectCommand
+ * \brief Specify an external MS project file for inclusion in the workspace.
+ *
+ * cmIncludeExternalMSProjectCommand is used to specify an externally
+ * generated Microsoft project file for inclusion in the default workspace
+ * generated by CMake.
+ */
+class cmIncludeExternalMSProjectCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmIncludeExternalMSProjectCommand;
+ }
+
+ /**
+ * 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 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.";
+ }
+
+ cmTypeMacro(cmIncludeExternalMSProjectCommand, cmCommand);
+};
+
+
+
+#endif
diff --git a/Source/cmIncludeRegularExpressionCommand.cxx b/Source/cmIncludeRegularExpressionCommand.cxx
new file mode 100644
index 000000000..b0d8325d3
--- /dev/null
+++ b/Source/cmIncludeRegularExpressionCommand.cxx
@@ -0,0 +1,32 @@
+/*============================================================================
+ 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 "cmIncludeRegularExpressionCommand.h"
+
+// cmIncludeRegularExpressionCommand
+bool cmIncludeRegularExpressionCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if((args.size() < 1) || (args.size() > 2))
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+ this->Makefile->SetIncludeRegularExpression(args[0].c_str());
+
+ if(args.size() > 1)
+ {
+ this->Makefile->SetComplainRegularExpression(args[1].c_str());
+ }
+
+ return true;
+}
+
diff --git a/Source/cmIncludeRegularExpressionCommand.h b/Source/cmIncludeRegularExpressionCommand.h
new file mode 100644
index 000000000..7c633c0a3
--- /dev/null
+++ b/Source/cmIncludeRegularExpressionCommand.h
@@ -0,0 +1,75 @@
+/*============================================================================
+ 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 cmIncludeRegularExpressionCommand_h
+#define cmIncludeRegularExpressionCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmIncludeRegularExpressionCommand
+ * \brief Set the regular expression for following #includes.
+ *
+ * cmIncludeRegularExpressionCommand is used to specify the regular expression
+ * that determines whether to follow a #include file in dependency checking.
+ */
+class cmIncludeRegularExpressionCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmIncludeRegularExpressionCommand;
+ }
+
+ /**
+ * 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 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)";
+ }
+
+ cmTypeMacro(cmIncludeRegularExpressionCommand, cmCommand);
+};
+
+
+
+#endif
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx
new file mode 100644
index 000000000..401673460
--- /dev/null
+++ b/Source/cmInstallCommand.cxx
@@ -0,0 +1,1335 @@
+/*============================================================================
+ 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 "cmInstallCommand.h"
+
+#include "cmInstallDirectoryGenerator.h"
+#include "cmInstallFilesGenerator.h"
+#include "cmInstallScriptGenerator.h"
+#include "cmInstallTargetGenerator.h"
+#include "cmInstallExportGenerator.h"
+#include "cmInstallCommandArguments.h"
+
+#include <cmsys/Glob.hxx>
+
+static cmInstallTargetGenerator* CreateInstallTargetGenerator(cmTarget& target,
+ const cmInstallCommandArguments& args, bool impLib, bool forceOpt = false)
+{
+ return new cmInstallTargetGenerator(target, args.GetDestination().c_str(),
+ impLib, args.GetPermissions().c_str(),
+ args.GetConfigurations(), args.GetComponent().c_str(),
+ args.GetOptional() || forceOpt);
+}
+
+static cmInstallFilesGenerator* CreateInstallFilesGenerator(
+ const std::vector<std::string>& absFiles,
+ const cmInstallCommandArguments& args, bool programs)
+{
+ return new cmInstallFilesGenerator(absFiles, args.GetDestination().c_str(),
+ programs, args.GetPermissions().c_str(),
+ args.GetConfigurations(), args.GetComponent().c_str(),
+ args.GetRename().c_str(), args.GetOptional());
+}
+
+
+// cmInstallCommand
+bool cmInstallCommand::InitialPass(std::vector<std::string> const& args,
+ cmExecutionStatus &)
+{
+ // Allow calling with no arguments so that arguments may be built up
+ // using a variable that may be left empty.
+ if(args.empty())
+ {
+ return true;
+ }
+
+ // Enable the install target.
+ this->Makefile->GetLocalGenerator()
+ ->GetGlobalGenerator()->EnableInstallTarget();
+
+ this->DefaultComponentName = this->Makefile->GetSafeDefinition(
+ "CMAKE_INSTALL_DEFAULT_COMPONENT_NAME");
+ if (this->DefaultComponentName.empty())
+ {
+ this->DefaultComponentName = "Unspecified";
+ }
+
+ // Switch among the command modes.
+ if(args[0] == "SCRIPT")
+ {
+ return this->HandleScriptMode(args);
+ }
+ else if(args[0] == "CODE")
+ {
+ return this->HandleScriptMode(args);
+ }
+ else if(args[0] == "TARGETS")
+ {
+ return this->HandleTargetsMode(args);
+ }
+ else if(args[0] == "FILES")
+ {
+ return this->HandleFilesMode(args);
+ }
+ else if(args[0] == "PROGRAMS")
+ {
+ return this->HandleFilesMode(args);
+ }
+ else if(args[0] == "DIRECTORY")
+ {
+ return this->HandleDirectoryMode(args);
+ }
+ else if(args[0] == "EXPORT")
+ {
+ return this->HandleExportMode(args);
+ }
+
+ // Unknown mode.
+ cmStdString e = "called with unknown mode ";
+ e += args[0];
+ this->SetError(e.c_str());
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmInstallCommand::HandleScriptMode(std::vector<std::string> const& args)
+{
+ std::string component = this->DefaultComponentName;
+ int componentCount = 0;
+ bool doing_script = false;
+ bool doing_code = false;
+
+ // Scan the args once for COMPONENT. Only allow one.
+ //
+ for(size_t i=0; i < args.size(); ++i)
+ {
+ if(args[i] == "COMPONENT" && i+1 < args.size())
+ {
+ ++componentCount;
+ ++i;
+ component = args[i];
+ }
+ }
+
+ if(componentCount>1)
+ {
+ this->SetError("given more than one COMPONENT for the SCRIPT or CODE "
+ "signature of the INSTALL command. "
+ "Use multiple INSTALL commands with one COMPONENT each.");
+ return false;
+ }
+
+ // Scan the args again, this time adding install generators each time we
+ // encounter a SCRIPT or CODE arg:
+ //
+ for(size_t i=0; i < args.size(); ++i)
+ {
+ if(args[i] == "SCRIPT")
+ {
+ doing_script = true;
+ doing_code = false;
+ }
+ else if(args[i] == "CODE")
+ {
+ doing_script = false;
+ doing_code = true;
+ }
+ else if(args[i] == "COMPONENT")
+ {
+ doing_script = false;
+ doing_code = false;
+ }
+ else if(doing_script)
+ {
+ doing_script = false;
+ std::string script = args[i];
+ if(!cmSystemTools::FileIsFullPath(script.c_str()))
+ {
+ script = this->Makefile->GetCurrentDirectory();
+ script += "/";
+ script += args[i];
+ }
+ if(cmSystemTools::FileIsDirectory(script.c_str()))
+ {
+ this->SetError("given a directory as value of SCRIPT argument.");
+ return false;
+ }
+ this->Makefile->AddInstallGenerator(
+ new cmInstallScriptGenerator(script.c_str(), false,
+ component.c_str()));
+ }
+ else if(doing_code)
+ {
+ doing_code = false;
+ std::string code = args[i];
+ this->Makefile->AddInstallGenerator(
+ new cmInstallScriptGenerator(code.c_str(), true,
+ component.c_str()));
+ }
+ }
+
+ if(doing_script)
+ {
+ this->SetError("given no value for SCRIPT argument.");
+ return false;
+ }
+ if(doing_code)
+ {
+ this->SetError("given no value for CODE argument.");
+ return false;
+ }
+
+ //Tell the global generator about any installation component names specified.
+ this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
+ ->AddInstallComponent(component.c_str());
+
+ return true;
+}
+
+
+/*struct InstallPart
+{
+ InstallPart(cmCommandArgumentsHelper* helper, const char* key,
+ cmCommandArgumentGroup* group);
+ cmCAStringVector argVector;
+ cmInstallCommandArguments args;
+};*/
+
+//----------------------------------------------------------------------------
+bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
+{
+ // This is the TARGETS mode.
+ std::vector<cmTarget*> targets;
+
+ cmCommandArgumentsHelper argHelper;
+ cmCommandArgumentGroup group;
+ cmCAStringVector genericArgVector (&argHelper,0);
+ cmCAStringVector archiveArgVector (&argHelper,"ARCHIVE",&group);
+ cmCAStringVector libraryArgVector (&argHelper,"LIBRARY",&group);
+ cmCAStringVector runtimeArgVector (&argHelper,"RUNTIME",&group);
+ cmCAStringVector frameworkArgVector (&argHelper,"FRAMEWORK",&group);
+ cmCAStringVector bundleArgVector (&argHelper,"BUNDLE",&group);
+ cmCAStringVector privateHeaderArgVector(&argHelper,"PRIVATE_HEADER",&group);
+ cmCAStringVector publicHeaderArgVector (&argHelper,"PUBLIC_HEADER",&group);
+ cmCAStringVector resourceArgVector (&argHelper,"RESOURCE",&group);
+ genericArgVector.Follows(0);
+ group.Follows(&genericArgVector);
+
+ argHelper.Parse(&args, 0);
+
+ // now parse the generic args (i.e. the ones not specialized on LIBRARY/
+ // ARCHIVE, RUNTIME etc. (see above)
+ // These generic args also contain the targets and the export stuff
+ std::vector<std::string> unknownArgs;
+ cmInstallCommandArguments genericArgs(this->DefaultComponentName);
+ cmCAStringVector targetList(&genericArgs.Parser, "TARGETS");
+ cmCAString exports(&genericArgs.Parser,"EXPORT", &genericArgs.ArgumentGroup);
+ targetList.Follows(0);
+ genericArgs.ArgumentGroup.Follows(&targetList);
+ genericArgs.Parse(&genericArgVector.GetVector(), &unknownArgs);
+ bool success = genericArgs.Finalize();
+
+ cmInstallCommandArguments archiveArgs(this->DefaultComponentName);
+ cmInstallCommandArguments libraryArgs(this->DefaultComponentName);
+ cmInstallCommandArguments runtimeArgs(this->DefaultComponentName);
+ cmInstallCommandArguments frameworkArgs(this->DefaultComponentName);
+ cmInstallCommandArguments bundleArgs(this->DefaultComponentName);
+ cmInstallCommandArguments privateHeaderArgs(this->DefaultComponentName);
+ cmInstallCommandArguments publicHeaderArgs(this->DefaultComponentName);
+ cmInstallCommandArguments resourceArgs(this->DefaultComponentName);
+
+ // now parse the args for specific parts of the target (e.g. LIBRARY,
+ // RUNTIME, ARCHIVE etc.
+ archiveArgs.Parse (&archiveArgVector.GetVector(), &unknownArgs);
+ libraryArgs.Parse (&libraryArgVector.GetVector(), &unknownArgs);
+ runtimeArgs.Parse (&runtimeArgVector.GetVector(), &unknownArgs);
+ frameworkArgs.Parse (&frameworkArgVector.GetVector(), &unknownArgs);
+ bundleArgs.Parse (&bundleArgVector.GetVector(), &unknownArgs);
+ privateHeaderArgs.Parse(&privateHeaderArgVector.GetVector(), &unknownArgs);
+ publicHeaderArgs.Parse (&publicHeaderArgVector.GetVector(), &unknownArgs);
+ resourceArgs.Parse (&resourceArgVector.GetVector(), &unknownArgs);
+
+ if(!unknownArgs.empty())
+ {
+ // Unknown argument.
+ cmOStringStream e;
+ e << "TARGETS given unknown argument \"" << unknownArgs[0] << "\".";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+
+ // apply generic args
+ archiveArgs.SetGenericArguments(&genericArgs);
+ libraryArgs.SetGenericArguments(&genericArgs);
+ runtimeArgs.SetGenericArguments(&genericArgs);
+ frameworkArgs.SetGenericArguments(&genericArgs);
+ bundleArgs.SetGenericArguments(&genericArgs);
+ privateHeaderArgs.SetGenericArguments(&genericArgs);
+ publicHeaderArgs.SetGenericArguments(&genericArgs);
+ resourceArgs.SetGenericArguments(&genericArgs);
+
+ success = success && archiveArgs.Finalize();
+ success = success && libraryArgs.Finalize();
+ success = success && runtimeArgs.Finalize();
+ success = success && frameworkArgs.Finalize();
+ success = success && bundleArgs.Finalize();
+ success = success && privateHeaderArgs.Finalize();
+ success = success && publicHeaderArgs.Finalize();
+ success = success && resourceArgs.Finalize();
+
+ if(!success)
+ {
+ return false;
+ }
+
+ // Enforce argument rules too complex to specify for the
+ // general-purpose parser.
+ if(archiveArgs.GetNamelinkOnly() ||
+ runtimeArgs.GetNamelinkOnly() ||
+ frameworkArgs.GetNamelinkOnly() ||
+ bundleArgs.GetNamelinkOnly() ||
+ privateHeaderArgs.GetNamelinkOnly() ||
+ publicHeaderArgs.GetNamelinkOnly() ||
+ resourceArgs.GetNamelinkOnly())
+ {
+ this->SetError(
+ "TARGETS given NAMELINK_ONLY option not in LIBRARY group. "
+ "The NAMELINK_ONLY option may be specified only following LIBRARY."
+ );
+ return false;
+ }
+ if(archiveArgs.GetNamelinkSkip() ||
+ runtimeArgs.GetNamelinkSkip() ||
+ frameworkArgs.GetNamelinkSkip() ||
+ bundleArgs.GetNamelinkSkip() ||
+ privateHeaderArgs.GetNamelinkSkip() ||
+ publicHeaderArgs.GetNamelinkSkip() ||
+ resourceArgs.GetNamelinkSkip())
+ {
+ this->SetError(
+ "TARGETS given NAMELINK_SKIP option not in LIBRARY group. "
+ "The NAMELINK_SKIP option may be specified only following LIBRARY."
+ );
+ return false;
+ }
+ if(libraryArgs.GetNamelinkOnly() && libraryArgs.GetNamelinkSkip())
+ {
+ this->SetError(
+ "TARGETS given NAMELINK_ONLY and NAMELINK_SKIP. "
+ "At most one of these two options may be specified."
+ );
+ return false;
+ }
+
+ // Select the mode for installing symlinks to versioned shared libraries.
+ cmInstallTargetGenerator::NamelinkModeType
+ namelinkMode = cmInstallTargetGenerator::NamelinkModeNone;
+ if(libraryArgs.GetNamelinkOnly())
+ {
+ namelinkMode = cmInstallTargetGenerator::NamelinkModeOnly;
+ }
+ else if(libraryArgs.GetNamelinkSkip())
+ {
+ namelinkMode = cmInstallTargetGenerator::NamelinkModeSkip;
+ }
+
+ // Check if there is something to do.
+ if(targetList.GetVector().empty())
+ {
+ return true;
+ }
+
+ // Check whether this is a DLL platform.
+ bool dll_platform = (this->Makefile->IsOn("WIN32") ||
+ this->Makefile->IsOn("CYGWIN") ||
+ this->Makefile->IsOn("MINGW"));
+
+ for(std::vector<std::string>::const_iterator
+ targetIt=targetList.GetVector().begin();
+ targetIt!=targetList.GetVector().end();
+ ++targetIt)
+ {
+ // Lookup this target in the current directory.
+ if(cmTarget* target=this->Makefile->FindTarget(targetIt->c_str()))
+ {
+ // 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)
+ {
+ cmOStringStream e;
+ e << "TARGETS given target \"" << (*targetIt)
+ << "\" which is not an executable, library, or module.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ else if(target->GetType() == cmTarget::OBJECT_LIBRARY)
+ {
+ cmOStringStream e;
+ e << "TARGETS given OBJECT library \"" << (*targetIt)
+ << "\" which may not be installed.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ // Store the target in the list to be installed.
+ targets.push_back(target);
+ }
+ else
+ {
+ // Did not find the target.
+ cmOStringStream e;
+ e << "TARGETS given target \"" << (*targetIt)
+ << "\" which does not exist in this directory.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+
+ // Keep track of whether we will be performing an installation of
+ // any files of the given type.
+ bool installsArchive = false;
+ bool installsLibrary = false;
+ bool installsRuntime = false;
+ bool installsFramework = false;
+ bool installsBundle = false;
+ bool installsPrivateHeader = false;
+ bool installsPublicHeader = false;
+ bool installsResource = false;
+
+ // Generate install script code to install the given targets.
+ for(std::vector<cmTarget*>::iterator ti = targets.begin();
+ ti != targets.end(); ++ti)
+ {
+ // Handle each target type.
+ cmTarget& target = *(*ti);
+ cmInstallTargetGenerator* archiveGenerator = 0;
+ cmInstallTargetGenerator* libraryGenerator = 0;
+ cmInstallTargetGenerator* runtimeGenerator = 0;
+ cmInstallTargetGenerator* frameworkGenerator = 0;
+ cmInstallTargetGenerator* bundleGenerator = 0;
+ cmInstallFilesGenerator* privateHeaderGenerator = 0;
+ cmInstallFilesGenerator* publicHeaderGenerator = 0;
+ cmInstallFilesGenerator* resourceGenerator = 0;
+
+ // Track whether this is a namelink-only rule.
+ bool namelinkOnly = false;
+
+ switch(target.GetType())
+ {
+ case cmTarget::SHARED_LIBRARY:
+ {
+ // Shared libraries are handled differently on DLL and non-DLL
+ // platforms. All windows platforms are DLL platforms including
+ // cygwin. Currently no other platform is a DLL platform.
+ if(dll_platform)
+ {
+ // When in namelink only mode skip all libraries on Windows.
+ if(namelinkMode == cmInstallTargetGenerator::NamelinkModeOnly)
+ {
+ continue;
+ }
+
+ // This is a DLL platform.
+ if(!archiveArgs.GetDestination().empty())
+ {
+ // The import library uses the ARCHIVE properties.
+ archiveGenerator = CreateInstallTargetGenerator(target,
+ archiveArgs, true);
+ }
+ if(!runtimeArgs.GetDestination().empty())
+ {
+ // The DLL uses the RUNTIME properties.
+ runtimeGenerator = CreateInstallTargetGenerator(target,
+ runtimeArgs, false);
+ }
+ if ((archiveGenerator==0) && (runtimeGenerator==0))
+ {
+ this->SetError("Library TARGETS given no DESTINATION!");
+ return false;
+ }
+ }
+ else
+ {
+ // This is a non-DLL platform.
+ // If it is marked with FRAMEWORK property use the FRAMEWORK set of
+ // INSTALL properties. Otherwise, use the LIBRARY properties.
+ if(target.IsFrameworkOnApple())
+ {
+ // When in namelink only mode skip frameworks.
+ if(namelinkMode == cmInstallTargetGenerator::NamelinkModeOnly)
+ {
+ continue;
+ }
+
+ // Use the FRAMEWORK properties.
+ if (!frameworkArgs.GetDestination().empty())
+ {
+ frameworkGenerator = CreateInstallTargetGenerator(target,
+ frameworkArgs, false);
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "TARGETS given no FRAMEWORK DESTINATION for shared library "
+ "FRAMEWORK target \"" << target.GetName() << "\".";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+ else
+ {
+ // The shared library uses the LIBRARY properties.
+ if (!libraryArgs.GetDestination().empty())
+ {
+ libraryGenerator = CreateInstallTargetGenerator(target,
+ libraryArgs, false);
+ libraryGenerator->SetNamelinkMode(namelinkMode);
+ namelinkOnly =
+ (namelinkMode == cmInstallTargetGenerator::NamelinkModeOnly);
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "TARGETS given no LIBRARY DESTINATION for shared library "
+ "target \"" << target.GetName() << "\".";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+ }
+ }
+ break;
+ case cmTarget::STATIC_LIBRARY:
+ {
+ // Static libraries use ARCHIVE properties.
+ if (!archiveArgs.GetDestination().empty())
+ {
+ archiveGenerator = CreateInstallTargetGenerator(target, archiveArgs,
+ false);
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "TARGETS given no ARCHIVE DESTINATION for static library "
+ "target \"" << target.GetName() << "\".";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+ break;
+ case cmTarget::MODULE_LIBRARY:
+ {
+ // Modules use LIBRARY properties.
+ if (!libraryArgs.GetDestination().empty())
+ {
+ libraryGenerator = CreateInstallTargetGenerator(target, libraryArgs,
+ false);
+ libraryGenerator->SetNamelinkMode(namelinkMode);
+ namelinkOnly =
+ (namelinkMode == cmInstallTargetGenerator::NamelinkModeOnly);
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "TARGETS given no LIBRARY DESTINATION for module target \""
+ << target.GetName() << "\".";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+ break;
+ case cmTarget::EXECUTABLE:
+ {
+ if(target.IsAppBundleOnApple())
+ {
+ // Application bundles use the BUNDLE properties.
+ if (!bundleArgs.GetDestination().empty())
+ {
+ bundleGenerator = CreateInstallTargetGenerator(target, bundleArgs,
+ false);
+ }
+ else if(!runtimeArgs.GetDestination().empty())
+ {
+ bool failure = false;
+ if(this->CheckCMP0006(failure))
+ {
+ // For CMake 2.4 compatibility fallback to the RUNTIME
+ // properties.
+ bundleGenerator =
+ CreateInstallTargetGenerator(target, runtimeArgs, false);
+ }
+ else if(failure)
+ {
+ return false;
+ }
+ }
+ if(!bundleGenerator)
+ {
+ cmOStringStream e;
+ e << "TARGETS given no BUNDLE DESTINATION for MACOSX_BUNDLE "
+ "executable target \"" << target.GetName() << "\".";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+ else
+ {
+ // Executables use the RUNTIME properties.
+ if (!runtimeArgs.GetDestination().empty())
+ {
+ runtimeGenerator = CreateInstallTargetGenerator(target,
+ runtimeArgs, false);
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "TARGETS given no RUNTIME DESTINATION for executable "
+ "target \"" << target.GetName() << "\".";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+
+ // On DLL platforms an executable may also have an import
+ // library. Install it to the archive destination if it
+ // exists.
+ if(dll_platform && !archiveArgs.GetDestination().empty() &&
+ target.IsExecutableWithExports())
+ {
+ // The import library uses the ARCHIVE properties.
+ archiveGenerator = CreateInstallTargetGenerator(target,
+ archiveArgs, true, true);
+ }
+ }
+ break;
+ default:
+ // This should never happen due to the above type check.
+ // Ignore the case.
+ break;
+ }
+
+ // These well-known sets of files are installed *automatically* for
+ // FRAMEWORK SHARED library targets on the Mac as part of installing the
+ // FRAMEWORK. For other target types or on other platforms, they are not
+ // installed automatically and so we need to create install files
+ // generators for them.
+ bool createInstallGeneratorsForTargetFileSets = true;
+
+ if(target.IsFrameworkOnApple())
+ {
+ createInstallGeneratorsForTargetFileSets = false;
+ }
+
+ if(createInstallGeneratorsForTargetFileSets && !namelinkOnly)
+ {
+ const char* files = target.GetProperty("PRIVATE_HEADER");
+ if ((files) && (*files))
+ {
+ std::vector<std::string> relFiles;
+ cmSystemTools::ExpandListArgument(files, relFiles);
+ std::vector<std::string> absFiles;
+ if (!this->MakeFilesFullPath("PRIVATE_HEADER", relFiles, absFiles))
+ {
+ return false;
+ }
+
+ // Create the files install generator.
+ if (!privateHeaderArgs.GetDestination().empty())
+ {
+ privateHeaderGenerator =
+ CreateInstallFilesGenerator(absFiles, privateHeaderArgs, false);
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "INSTALL TARGETS - target " << target.GetName() << " has "
+ << "PRIVATE_HEADER files but no PRIVATE_HEADER DESTINATION.";
+ cmSystemTools::Message(e.str().c_str(), "Warning");
+ }
+ }
+
+ files = target.GetProperty("PUBLIC_HEADER");
+ if ((files) && (*files))
+ {
+ std::vector<std::string> relFiles;
+ cmSystemTools::ExpandListArgument(files, relFiles);
+ std::vector<std::string> absFiles;
+ if (!this->MakeFilesFullPath("PUBLIC_HEADER", relFiles, absFiles))
+ {
+ return false;
+ }
+
+ // Create the files install generator.
+ if (!publicHeaderArgs.GetDestination().empty())
+ {
+ publicHeaderGenerator =
+ CreateInstallFilesGenerator(absFiles, publicHeaderArgs, false);
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "INSTALL TARGETS - target " << target.GetName() << " has "
+ << "PUBLIC_HEADER files but no PUBLIC_HEADER DESTINATION.";
+ cmSystemTools::Message(e.str().c_str(), "Warning");
+ }
+ }
+
+ files = target.GetProperty("RESOURCE");
+ if ((files) && (*files))
+ {
+ std::vector<std::string> relFiles;
+ cmSystemTools::ExpandListArgument(files, relFiles);
+ std::vector<std::string> absFiles;
+ if (!this->MakeFilesFullPath("RESOURCE", relFiles, absFiles))
+ {
+ return false;
+ }
+
+ // Create the files install generator.
+ if (!resourceArgs.GetDestination().empty())
+ {
+ resourceGenerator = CreateInstallFilesGenerator(absFiles,
+ resourceArgs, false);
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "INSTALL TARGETS - target " << target.GetName() << " has "
+ << "RESOURCE files but no RESOURCE DESTINATION.";
+ cmSystemTools::Message(e.str().c_str(), "Warning");
+ }
+ }
+ }
+
+ // Keep track of whether we're installing anything in each category
+ installsArchive = installsArchive || archiveGenerator != 0;
+ installsLibrary = installsLibrary || libraryGenerator != 0;
+ installsRuntime = installsRuntime || runtimeGenerator != 0;
+ installsFramework = installsFramework || frameworkGenerator != 0;
+ installsBundle = installsBundle || bundleGenerator != 0;
+ installsPrivateHeader = installsPrivateHeader
+ || privateHeaderGenerator != 0;
+ installsPublicHeader = installsPublicHeader || publicHeaderGenerator != 0;
+ installsResource = installsResource || resourceGenerator;
+
+ this->Makefile->AddInstallGenerator(archiveGenerator);
+ this->Makefile->AddInstallGenerator(libraryGenerator);
+ this->Makefile->AddInstallGenerator(runtimeGenerator);
+ this->Makefile->AddInstallGenerator(frameworkGenerator);
+ this->Makefile->AddInstallGenerator(bundleGenerator);
+ this->Makefile->AddInstallGenerator(privateHeaderGenerator);
+ this->Makefile->AddInstallGenerator(publicHeaderGenerator);
+ this->Makefile->AddInstallGenerator(resourceGenerator);
+
+ // Add this install rule to an export if one was specified and
+ // this is not a namelink-only rule.
+ if(!exports.GetString().empty() && !namelinkOnly)
+ {
+ this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
+ ->AddTargetToExports(exports.GetCString(), &target,
+ archiveGenerator, runtimeGenerator,
+ libraryGenerator, frameworkGenerator,
+ bundleGenerator, publicHeaderGenerator);
+ }
+ }
+
+ // Tell the global generator about any installation component names
+ // specified
+ if (installsArchive)
+ {
+ this->Makefile->GetLocalGenerator()->
+ GetGlobalGenerator()
+ ->AddInstallComponent(archiveArgs.GetComponent().c_str());
+ }
+ if (installsLibrary)
+ {
+ this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
+ ->AddInstallComponent(libraryArgs.GetComponent().c_str());
+ }
+ if (installsRuntime)
+ {
+ this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
+ ->AddInstallComponent(runtimeArgs.GetComponent().c_str());
+ }
+ if (installsFramework)
+ {
+ this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
+ ->AddInstallComponent(frameworkArgs.GetComponent().c_str());
+ }
+ if (installsBundle)
+ {
+ this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
+ ->AddInstallComponent(bundleArgs.GetComponent().c_str());
+ }
+ if (installsPrivateHeader)
+ {
+ this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
+ ->AddInstallComponent(privateHeaderArgs.GetComponent().c_str());
+ }
+ if (installsPublicHeader)
+ {
+ this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
+ ->AddInstallComponent(publicHeaderArgs.GetComponent().c_str());
+ }
+ if (installsResource)
+ {
+ this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
+ ->AddInstallComponent(resourceArgs.GetComponent().c_str());
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmInstallCommand::HandleFilesMode(std::vector<std::string> const& args)
+{
+ // This is the FILES mode.
+ bool programs = (args[0] == "PROGRAMS");
+ cmInstallCommandArguments ica(this->DefaultComponentName);
+ cmCAStringVector files(&ica.Parser, programs ? "PROGRAMS" : "FILES");
+ files.Follows(0);
+ ica.ArgumentGroup.Follows(&files);
+ std::vector<std::string> unknownArgs;
+ ica.Parse(&args, &unknownArgs);
+
+ if(!unknownArgs.empty())
+ {
+ // Unknown argument.
+ cmOStringStream e;
+ e << args[0] << " given unknown argument \"" << unknownArgs[0] << "\".";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+
+ // Check if there is something to do.
+ if(files.GetVector().empty())
+ {
+ return true;
+ }
+
+ if(!ica.GetRename().empty() && files.GetVector().size() > 1)
+ {
+ // The rename option works only with one file.
+ cmOStringStream e;
+ e << args[0] << " given RENAME option with more than one file.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+
+ std::vector<std::string> absFiles;
+ if (!this->MakeFilesFullPath(args[0].c_str(), files.GetVector(), absFiles))
+ {
+ return false;
+ }
+
+ if (!ica.Finalize())
+ {
+ return false;
+ }
+
+ if(ica.GetDestination().empty())
+ {
+ // A destination is required.
+ cmOStringStream e;
+ e << args[0] << " given no DESTINATION!";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+
+ // Create the files install generator.
+ this->Makefile->AddInstallGenerator(
+ CreateInstallFilesGenerator(absFiles, ica, programs));
+
+ //Tell the global generator about any installation component names specified.
+ this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
+ ->AddInstallComponent(ica.GetComponent().c_str());
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool
+cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args)
+{
+ enum Doing { DoingNone, DoingDirs, DoingDestination, DoingPattern,
+ DoingRegex, DoingPermsFile, DoingPermsDir, DoingPermsMatch,
+ DoingConfigurations, DoingComponent };
+ Doing doing = DoingDirs;
+ bool in_match_mode = false;
+ bool optional = false;
+ std::vector<std::string> dirs;
+ const char* destination = 0;
+ std::string permissions_file;
+ std::string permissions_dir;
+ std::vector<std::string> configurations;
+ std::string component = this->DefaultComponentName;
+ std::string literal_args;
+ for(unsigned int i=1; i < args.size(); ++i)
+ {
+ if(args[i] == "DESTINATION")
+ {
+ if(in_match_mode)
+ {
+ cmOStringStream e;
+ e << args[0] << " does not allow \""
+ << args[i] << "\" after PATTERN or REGEX.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+
+ // Switch to setting the destination property.
+ doing = DoingDestination;
+ }
+ else if(args[i] == "OPTIONAL")
+ {
+ if(in_match_mode)
+ {
+ cmOStringStream e;
+ e << args[0] << " does not allow \""
+ << args[i] << "\" after PATTERN or REGEX.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+
+ // Mark the rule as optional.
+ optional = true;
+ doing = DoingNone;
+ }
+ else if(args[i] == "PATTERN")
+ {
+ // Switch to a new pattern match rule.
+ doing = DoingPattern;
+ in_match_mode = true;
+ }
+ else if(args[i] == "REGEX")
+ {
+ // Switch to a new regex match rule.
+ doing = DoingRegex;
+ in_match_mode = true;
+ }
+ else if(args[i] == "EXCLUDE")
+ {
+ // Add this property to the current match rule.
+ if(!in_match_mode || doing == DoingPattern || doing == DoingRegex)
+ {
+ cmOStringStream e;
+ e << args[0] << " does not allow \""
+ << args[i] << "\" before a PATTERN or REGEX is given.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ literal_args += " EXCLUDE";
+ doing = DoingNone;
+ }
+ else if(args[i] == "PERMISSIONS")
+ {
+ if(!in_match_mode)
+ {
+ cmOStringStream e;
+ e << args[0] << " does not allow \""
+ << args[i] << "\" before a PATTERN or REGEX is given.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+
+ // Switch to setting the current match permissions property.
+ literal_args += " PERMISSIONS";
+ doing = DoingPermsMatch;
+ }
+ else if(args[i] == "FILE_PERMISSIONS")
+ {
+ if(in_match_mode)
+ {
+ cmOStringStream e;
+ e << args[0] << " does not allow \""
+ << args[i] << "\" after PATTERN or REGEX.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+
+ // Switch to setting the file permissions property.
+ doing = DoingPermsFile;
+ }
+ else if(args[i] == "DIRECTORY_PERMISSIONS")
+ {
+ if(in_match_mode)
+ {
+ cmOStringStream e;
+ e << args[0] << " does not allow \""
+ << args[i] << "\" after PATTERN or REGEX.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+
+ // Switch to setting the directory permissions property.
+ doing = DoingPermsDir;
+ }
+ else if(args[i] == "USE_SOURCE_PERMISSIONS")
+ {
+ if(in_match_mode)
+ {
+ cmOStringStream e;
+ e << args[0] << " does not allow \""
+ << args[i] << "\" after PATTERN or REGEX.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+
+ // Add this option literally.
+ literal_args += " USE_SOURCE_PERMISSIONS";
+ doing = DoingNone;
+ }
+ else if(args[i] == "FILES_MATCHING")
+ {
+ if(in_match_mode)
+ {
+ cmOStringStream e;
+ e << args[0] << " does not allow \""
+ << args[i] << "\" after PATTERN or REGEX.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+
+ // Add this option literally.
+ literal_args += " FILES_MATCHING";
+ doing = DoingNone;
+ }
+ else if(args[i] == "CONFIGURATIONS")
+ {
+ if(in_match_mode)
+ {
+ cmOStringStream e;
+ e << args[0] << " does not allow \""
+ << args[i] << "\" after PATTERN or REGEX.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+
+ // Switch to setting the configurations property.
+ doing = DoingConfigurations;
+ }
+ else if(args[i] == "COMPONENT")
+ {
+ if(in_match_mode)
+ {
+ cmOStringStream e;
+ e << args[0] << " does not allow \""
+ << args[i] << "\" after PATTERN or REGEX.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+
+ // Switch to setting the component property.
+ doing = DoingComponent;
+ }
+ else if(doing == DoingDirs)
+ {
+ // Convert this directory to a full path.
+ std::string dir = args[i];
+ if(!cmSystemTools::FileIsFullPath(dir.c_str()))
+ {
+ dir = this->Makefile->GetCurrentDirectory();
+ dir += "/";
+ dir += args[i];
+ }
+
+ // Make sure the name is a directory.
+ if(cmSystemTools::FileExists(dir.c_str()) &&
+ !cmSystemTools::FileIsDirectory(dir.c_str()))
+ {
+ cmOStringStream e;
+ e << args[0] << " given non-directory \""
+ << args[i] << "\" to install.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+
+ // Store the directory for installation.
+ dirs.push_back(dir);
+ }
+ else if(doing == DoingConfigurations)
+ {
+ configurations.push_back(args[i]);
+ }
+ else if(doing == DoingDestination)
+ {
+ destination = args[i].c_str();
+ doing = DoingNone;
+ }
+ else if(doing == DoingPattern)
+ {
+ // Convert the pattern to a regular expression. Require a
+ // leading slash and trailing end-of-string in the matched
+ // string to make sure the pattern matches only whole file
+ // names.
+ literal_args += " REGEX \"/";
+ std::string regex = cmsys::Glob::PatternToRegex(args[i], false);
+ cmSystemTools::ReplaceString(regex, "\\", "\\\\");
+ literal_args += regex;
+ literal_args += "$\"";
+ doing = DoingNone;
+ }
+ else if(doing == DoingRegex)
+ {
+ literal_args += " REGEX \"";
+ // Match rules are case-insensitive on some platforms.
+#if defined(_WIN32) || defined(__APPLE__) || defined(__CYGWIN__)
+ std::string regex = cmSystemTools::LowerCase(args[i]);
+#else
+ std::string regex = args[i];
+#endif
+ cmSystemTools::ReplaceString(regex, "\\", "\\\\");
+ literal_args += regex;
+ literal_args += "\"";
+ doing = DoingNone;
+ }
+ else if(doing == DoingComponent)
+ {
+ component = args[i];
+ doing = DoingNone;
+ }
+ else if(doing == DoingPermsFile)
+ {
+ // Check the requested permission.
+ if(!cmInstallCommandArguments::CheckPermissions(args[i],permissions_file))
+ {
+ cmOStringStream e;
+ e << args[0] << " given invalid file permission \""
+ << args[i] << "\".";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+ else if(doing == DoingPermsDir)
+ {
+ // Check the requested permission.
+ if(!cmInstallCommandArguments::CheckPermissions(args[i],permissions_dir))
+ {
+ cmOStringStream e;
+ e << args[0] << " given invalid directory permission \""
+ << args[i] << "\".";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+ else if(doing == DoingPermsMatch)
+ {
+ // Check the requested permission.
+ if(!cmInstallCommandArguments::CheckPermissions(args[i], literal_args))
+ {
+ cmOStringStream e;
+ e << args[0] << " given invalid permission \""
+ << args[i] << "\".";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+ else
+ {
+ // Unknown argument.
+ cmOStringStream e;
+ e << args[0] << " given unknown argument \"" << args[i] << "\".";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+
+ // Support installing an empty directory.
+ if(dirs.empty() && destination)
+ {
+ dirs.push_back("");
+ }
+
+ // Check if there is something to do.
+ if(dirs.empty())
+ {
+ return true;
+ }
+ if(!destination)
+ {
+ // A destination is required.
+ cmOStringStream e;
+ e << args[0] << " given no DESTINATION!";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+
+ // Create the directory install generator.
+ this->Makefile->AddInstallGenerator(
+ new cmInstallDirectoryGenerator(dirs, destination,
+ permissions_file.c_str(),
+ permissions_dir.c_str(),
+ configurations,
+ component.c_str(),
+ literal_args.c_str(),
+ optional));
+
+ // Tell the global generator about any installation component names
+ // specified.
+ this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
+ ->AddInstallComponent(component.c_str());
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args)
+{
+ // This is the EXPORT mode.
+ cmInstallCommandArguments ica(this->DefaultComponentName);
+ cmCAString exp(&ica.Parser, "EXPORT");
+ cmCAString name_space(&ica.Parser, "NAMESPACE", &ica.ArgumentGroup);
+ cmCAString filename(&ica.Parser, "FILE", &ica.ArgumentGroup);
+ exp.Follows(0);
+
+ ica.ArgumentGroup.Follows(&exp);
+ std::vector<std::string> unknownArgs;
+ ica.Parse(&args, &unknownArgs);
+
+ if (!unknownArgs.empty())
+ {
+ // Unknown argument.
+ cmOStringStream e;
+ e << args[0] << " given unknown argument \"" << unknownArgs[0] << "\".";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+
+ if (!ica.Finalize())
+ {
+ return false;
+ }
+
+ // Make sure there is a destination.
+ if(ica.GetDestination().empty())
+ {
+ // A destination is required.
+ cmOStringStream e;
+ e << args[0] << " given no DESTINATION!";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+
+ // Check the file name.
+ std::string fname = filename.GetString();
+ if(fname.find_first_of(":/\\") != fname.npos)
+ {
+ cmOStringStream 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());
+ return false;
+ }
+
+ // Check the file extension.
+ if(!fname.empty() &&
+ cmSystemTools::GetFilenameLastExtension(fname) != ".cmake")
+ {
+ cmOStringStream 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());
+ return false;
+ }
+
+ // Construct the file name.
+ if(fname.empty())
+ {
+ fname = exp.GetString();
+ fname += ".cmake";
+
+ if(fname.find_first_of(":/\\") != fname.npos)
+ {
+ cmOStringStream 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());
+ return false;
+ }
+ }
+
+ // Create the export install generator.
+ cmInstallExportGenerator* exportGenerator =
+ new cmInstallExportGenerator(
+ exp.GetCString(), ica.GetDestination().c_str(),
+ ica.GetPermissions().c_str(), ica.GetConfigurations(),
+ ica.GetComponent().c_str(), fname.c_str(),
+ name_space.GetCString(), this->Makefile);
+ this->Makefile->AddInstallGenerator(exportGenerator);
+
+ return true;
+}
+
+bool cmInstallCommand::MakeFilesFullPath(const char* modeName,
+ const std::vector<std::string>& relFiles,
+ std::vector<std::string>& absFiles)
+{
+ for(std::vector<std::string>::const_iterator fileIt = relFiles.begin();
+ fileIt != relFiles.end();
+ ++fileIt)
+ {
+ std::string file = (*fileIt);
+ if(!cmSystemTools::FileIsFullPath(file.c_str()))
+ {
+ file = this->Makefile->GetCurrentDirectory();
+ file += "/";
+ file += *fileIt;
+ }
+
+ // Make sure the file is not a directory.
+ if(cmSystemTools::FileIsDirectory(file.c_str()))
+ {
+ cmOStringStream e;
+ e << modeName << " given directory \"" << (*fileIt) << "\" to install.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ // Store the file for installation.
+ absFiles.push_back(file);
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmInstallCommand::CheckCMP0006(bool& failure)
+{
+ switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0006))
+ {
+ case cmPolicies::WARN:
+ {
+ this->Makefile->IssueMessage(
+ cmake::AUTHOR_WARNING,
+ this->Makefile->GetPolicies()->GetPolicyWarning(cmPolicies::CMP0006)
+ );
+ }
+ case cmPolicies::OLD:
+ // OLD behavior is to allow compatibility
+ return true;
+ case cmPolicies::NEW:
+ // NEW behavior is to disallow compatibility
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ failure = true;
+ this->Makefile->IssueMessage(
+ cmake::FATAL_ERROR,
+ this->Makefile->GetPolicies()
+ ->GetRequiredPolicyError(cmPolicies::CMP0006)
+ );
+ break;
+ }
+ return false;
+}
diff --git a/Source/cmInstallCommand.h b/Source/cmInstallCommand.h
new file mode 100644
index 000000000..76e622e81
--- /dev/null
+++ b/Source/cmInstallCommand.h
@@ -0,0 +1,352 @@
+/*============================================================================
+ 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 cmInstallCommand_h
+#define cmInstallCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmInstallCommand
+ * \brief Specifies where to install some files
+ *
+ * cmInstallCommand is a general-purpose interface command for
+ * specifying install rules.
+ */
+class cmInstallCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmInstallCommand;
+ }
+
+ /**
+ * 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 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.\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"
+ " [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)."
+ "\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"
+ " [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. "
+ "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"
+ ;
+ }
+
+ cmTypeMacro(cmInstallCommand, cmCommand);
+
+private:
+ bool HandleScriptMode(std::vector<std::string> const& args);
+ bool HandleTargetsMode(std::vector<std::string> const& args);
+ bool HandleFilesMode(std::vector<std::string> const& args);
+ bool HandleDirectoryMode(std::vector<std::string> const& args);
+ bool HandleExportMode(std::vector<std::string> const& args);
+ bool MakeFilesFullPath(const char* modeName,
+ const std::vector<std::string>& relFiles,
+ std::vector<std::string>& absFiles);
+ bool CheckCMP0006(bool& failure);
+
+ std::string DefaultComponentName;
+};
+
+
+#endif
diff --git a/Source/cmInstallCommandArguments.cxx b/Source/cmInstallCommandArguments.cxx
new file mode 100644
index 000000000..8e48f08e6
--- /dev/null
+++ b/Source/cmInstallCommandArguments.cxx
@@ -0,0 +1,205 @@
+/*============================================================================
+ 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 "cmInstallCommandArguments.h"
+#include "cmSystemTools.h"
+
+// Table of valid permissions.
+const char* cmInstallCommandArguments::PermissionsTable[] =
+{
+ "OWNER_READ", "OWNER_WRITE", "OWNER_EXECUTE",
+ "GROUP_READ", "GROUP_WRITE", "GROUP_EXECUTE",
+ "WORLD_READ", "WORLD_WRITE", "WORLD_EXECUTE",
+ "SETUID", "SETGID", 0
+};
+
+const std::string cmInstallCommandArguments::EmptyString;
+
+cmInstallCommandArguments::cmInstallCommandArguments(
+ const std::string& defaultComponent)
+:Parser()
+,ArgumentGroup()
+,Destination (&Parser, "DESTINATION" , &ArgumentGroup)
+,Component (&Parser, "COMPONENT" , &ArgumentGroup)
+,Rename (&Parser, "RENAME" , &ArgumentGroup)
+,Permissions (&Parser, "PERMISSIONS" , &ArgumentGroup)
+,Configurations(&Parser, "CONFIGURATIONS", &ArgumentGroup)
+,Optional (&Parser, "OPTIONAL" , &ArgumentGroup)
+,NamelinkOnly (&Parser, "NAMELINK_ONLY" , &ArgumentGroup)
+,NamelinkSkip (&Parser, "NAMELINK_SKIP" , &ArgumentGroup)
+,GenericArguments(0)
+,DefaultComponentName(defaultComponent)
+{
+}
+
+const std::string& cmInstallCommandArguments::GetDestination() const
+{
+ if (!this->DestinationString.empty())
+ {
+ return this->DestinationString;
+ }
+ if (this->GenericArguments!=0)
+ {
+ return this->GenericArguments->GetDestination();
+ }
+ return this->EmptyString;
+}
+
+const std::string& cmInstallCommandArguments::GetComponent() const
+{
+ if (!this->Component.GetString().empty())
+ {
+ return this->Component.GetString();
+ }
+ if (this->GenericArguments!=0)
+ {
+ return this->GenericArguments->GetComponent();
+ }
+ if (!this->DefaultComponentName.empty())
+ {
+ return this->DefaultComponentName;
+ }
+ static std::string unspecifiedComponent = "Unspecified";
+ return unspecifiedComponent;
+}
+
+const std::string& cmInstallCommandArguments::GetRename() const
+{
+ if (!this->Rename.GetString().empty())
+ {
+ return this->Rename.GetString();
+ }
+ if (this->GenericArguments!=0)
+ {
+ return this->GenericArguments->GetRename();
+ }
+ return this->EmptyString;
+}
+
+const std::string& cmInstallCommandArguments::GetPermissions() const
+{
+ if (!this->PermissionsString.empty())
+ {
+ return this->PermissionsString;
+ }
+ if (this->GenericArguments!=0)
+ {
+ return this->GenericArguments->GetPermissions();
+ }
+ return this->EmptyString;
+}
+
+bool cmInstallCommandArguments::GetOptional() const
+{
+ if (this->Optional.IsEnabled())
+ {
+ return true;
+ }
+ if (this->GenericArguments!=0)
+ {
+ return this->GenericArguments->GetOptional();
+ }
+ return false;
+}
+
+bool cmInstallCommandArguments::GetNamelinkOnly() const
+{
+ if (this->NamelinkOnly.IsEnabled())
+ {
+ return true;
+ }
+ if (this->GenericArguments!=0)
+ {
+ return this->GenericArguments->GetNamelinkOnly();
+ }
+ return false;
+}
+
+bool cmInstallCommandArguments::GetNamelinkSkip() const
+{
+ if (this->NamelinkSkip.IsEnabled())
+ {
+ return true;
+ }
+ if (this->GenericArguments!=0)
+ {
+ return this->GenericArguments->GetNamelinkSkip();
+ }
+ return false;
+}
+
+const std::vector<std::string>&
+ cmInstallCommandArguments::GetConfigurations() const
+{
+ if (!this->Configurations.GetVector().empty())
+ {
+ return this->Configurations.GetVector();
+ }
+ if (this->GenericArguments!=0)
+ {
+ return this->GenericArguments->GetConfigurations();
+ }
+ return this->Configurations.GetVector();
+}
+
+
+bool cmInstallCommandArguments::Finalize()
+{
+ if (!this->CheckPermissions())
+ {
+ return false;
+ }
+ this->DestinationString = this->Destination.GetString();
+ cmSystemTools::ConvertToUnixSlashes(this->DestinationString);
+ return true;
+}
+
+void cmInstallCommandArguments::Parse(const std::vector<std::string>* args,
+ std::vector<std::string>* unconsumedArgs)
+{
+ this->Parser.Parse(args, unconsumedArgs);
+}
+
+
+bool cmInstallCommandArguments::CheckPermissions()
+{
+ this->PermissionsString = "";
+ for(std::vector<std::string>::const_iterator
+ permIt = this->Permissions.GetVector().begin();
+ permIt != this->Permissions.GetVector().end();
+ ++permIt)
+ {
+ if (!this->CheckPermissions(*permIt, this->PermissionsString))
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool cmInstallCommandArguments::CheckPermissions(
+ const std::string& onePermission, std::string& permissions)
+{
+ // Check the permission against the table.
+ for(const char** valid = cmInstallCommandArguments::PermissionsTable;
+ *valid; ++valid)
+ {
+ if(onePermission == *valid)
+ {
+ // This is a valid permission.
+ permissions += " ";
+ permissions += onePermission;
+ return true;
+ }
+ }
+ // This is not a valid permission.
+ return false;
+}
diff --git a/Source/cmInstallCommandArguments.h b/Source/cmInstallCommandArguments.h
new file mode 100644
index 000000000..01f7d5679
--- /dev/null
+++ b/Source/cmInstallCommandArguments.h
@@ -0,0 +1,68 @@
+/*============================================================================
+ 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 cmInstallCommandArguments_h
+#define cmInstallCommandArguments_h
+
+#include "cmStandardIncludes.h"
+#include "cmCommandArgumentsHelper.h"
+
+class cmInstallCommandArguments
+{
+ public:
+ cmInstallCommandArguments(const std::string& defaultComponent);
+ void SetGenericArguments(cmInstallCommandArguments* args)
+ {this->GenericArguments = args;}
+ void Parse(const std::vector<std::string>* args,
+ std::vector<std::string>* unconsumedArgs);
+
+ // Compute destination path.and check permissions
+ bool Finalize();
+
+ const std::string& GetDestination() const;
+ const std::string& GetComponent() const;
+ const std::string& GetRename() const;
+ const std::string& GetPermissions() const;
+ const std::vector<std::string>& GetConfigurations() const;
+ bool GetOptional() const;
+ bool GetNamelinkOnly() const;
+ bool GetNamelinkSkip() const;
+
+ // once HandleDirectoryMode() is also switched to using
+ // cmInstallCommandArguments then these two functions can become non-static
+ // private member functions without arguments
+ static bool CheckPermissions(const std::string& onePerm,
+ std::string& perm);
+ cmCommandArgumentsHelper Parser;
+ cmCommandArgumentGroup ArgumentGroup;
+ private:
+ cmInstallCommandArguments(); // disabled
+ cmCAString Destination;
+ cmCAString Component;
+ cmCAString Rename;
+ cmCAStringVector Permissions;
+ cmCAStringVector Configurations;
+ cmCAEnabler Optional;
+ cmCAEnabler NamelinkOnly;
+ cmCAEnabler NamelinkSkip;
+
+ std::string DestinationString;
+ std::string PermissionsString;
+
+ cmInstallCommandArguments* GenericArguments;
+ static const char* PermissionsTable[];
+ static const std::string EmptyString;
+ std::string DefaultComponentName;
+ bool CheckPermissions();
+};
+
+#endif
diff --git a/Source/cmInstallDirectoryGenerator.cxx b/Source/cmInstallDirectoryGenerator.cxx
new file mode 100644
index 000000000..ddf7d08cc
--- /dev/null
+++ b/Source/cmInstallDirectoryGenerator.cxx
@@ -0,0 +1,52 @@
+/*============================================================================
+ 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 "cmInstallDirectoryGenerator.h"
+
+#include "cmTarget.h"
+
+//----------------------------------------------------------------------------
+cmInstallDirectoryGenerator
+::cmInstallDirectoryGenerator(std::vector<std::string> const& dirs,
+ const char* dest,
+ const char* file_permissions,
+ const char* dir_permissions,
+ std::vector<std::string> const& configurations,
+ const char* component,
+ const char* literal_args,
+ bool optional):
+ cmInstallGenerator(dest, configurations, component), Directories(dirs),
+ FilePermissions(file_permissions), DirPermissions(dir_permissions),
+ LiteralArguments(literal_args), Optional(optional)
+{
+}
+
+//----------------------------------------------------------------------------
+cmInstallDirectoryGenerator
+::~cmInstallDirectoryGenerator()
+{
+}
+
+//----------------------------------------------------------------------------
+void
+cmInstallDirectoryGenerator::GenerateScriptActions(std::ostream& os,
+ Indent const& indent)
+{
+ // Write code to install the directories.
+ const char* no_rename = 0;
+ this->AddInstallRule(os, cmInstallType_DIRECTORY,
+ this->Directories,
+ this->Optional,
+ this->FilePermissions.c_str(),
+ this->DirPermissions.c_str(),
+ no_rename, this->LiteralArguments.c_str(),
+ indent);
+}
diff --git a/Source/cmInstallDirectoryGenerator.h b/Source/cmInstallDirectoryGenerator.h
new file mode 100644
index 000000000..d76ef3c4c
--- /dev/null
+++ b/Source/cmInstallDirectoryGenerator.h
@@ -0,0 +1,42 @@
+/*============================================================================
+ 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 cmInstallDirectoryGenerator_h
+#define cmInstallDirectoryGenerator_h
+
+#include "cmInstallGenerator.h"
+
+/** \class cmInstallDirectoryGenerator
+ * \brief Generate directory installation rules.
+ */
+class cmInstallDirectoryGenerator: public cmInstallGenerator
+{
+public:
+ cmInstallDirectoryGenerator(std::vector<std::string> const& dirs,
+ const char* dest,
+ const char* file_permissions,
+ const char* dir_permissions,
+ std::vector<std::string> const& configurations,
+ const char* component,
+ const char* literal_args,
+ bool optional = false);
+ virtual ~cmInstallDirectoryGenerator();
+
+protected:
+ virtual void GenerateScriptActions(std::ostream& os, Indent const& indent);
+ std::vector<std::string> Directories;
+ std::string FilePermissions;
+ std::string DirPermissions;
+ std::string LiteralArguments;
+ bool Optional;
+};
+
+#endif
diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx
new file mode 100644
index 000000000..28a19d740
--- /dev/null
+++ b/Source/cmInstallExportGenerator.cxx
@@ -0,0 +1,229 @@
+/*============================================================================
+ 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 "cmInstallExportGenerator.h"
+
+#include <stdio.h>
+
+#include "cmake.h"
+#include "cmInstallTargetGenerator.h"
+#include "cmGeneratedFileStream.h"
+#include "cmMakefile.h"
+#include "cmLocalGenerator.h"
+#include "cmGlobalGenerator.h"
+
+#include "cmInstallFilesGenerator.h"
+
+#include "cmExportInstallFileGenerator.h"
+
+//----------------------------------------------------------------------------
+cmInstallExportGenerator::cmInstallExportGenerator(
+ const char* name,
+ const char* destination,
+ const char* file_permissions,
+ std::vector<std::string> const& configurations,
+ const char* component,
+ const char* filename, const char* name_space,
+ cmMakefile* mf)
+ :cmInstallGenerator(destination, configurations, component)
+ ,Name(name)
+ ,FilePermissions(file_permissions)
+ ,FileName(filename)
+ ,Namespace(name_space)
+ ,Makefile(mf)
+{
+ this->EFGen = new cmExportInstallFileGenerator(this);
+}
+
+//----------------------------------------------------------------------------
+cmInstallExportGenerator::~cmInstallExportGenerator()
+{
+ delete this->EFGen;
+}
+
+//----------------------------------------------------------------------------
+void cmInstallExportGenerator::ComputeTempDir()
+{
+ // Choose a temporary directory in which to generate the import
+ // files to be installed.
+ this->TempDir = this->Makefile->GetCurrentOutputDirectory();
+ this->TempDir += cmake::GetCMakeFilesDirectory();
+ this->TempDir += "/Export";
+ if(this->Destination.empty())
+ {
+ return;
+ }
+ else
+ {
+ this->TempDir += "/";
+ }
+
+ // Enforce a maximum length.
+ bool useMD5 = false;
+#if defined(_WIN32) || defined(__CYGWIN__)
+ std::string::size_type const max_total_len = 250;
+#else
+ std::string::size_type const max_total_len = 1000;
+#endif
+ if(this->TempDir.size() < max_total_len)
+ {
+ // Keep the total path length below the limit.
+ std::string::size_type max_len = max_total_len - this->TempDir.size();
+ if(this->Destination.size() > max_len)
+ {
+ useMD5 = true;
+ }
+ }
+ else
+ {
+ useMD5 = true;
+ }
+ if(useMD5)
+ {
+ // Replace the destination path with a hash to keep it short.
+ this->TempDir +=
+ cmSystemTools::ComputeStringMD5(this->Destination.c_str());
+ }
+ else
+ {
+ std::string dest = this->Destination;
+ // Avoid unix full paths.
+ if(dest[0] == '/')
+ {
+ dest[0] = '_';
+ }
+ // Avoid windows full paths by removing colons.
+ cmSystemTools::ReplaceString(dest, ":", "_");
+ // Avoid relative paths that go up the tree.
+ cmSystemTools::ReplaceString(dest, "../", "__/");
+ // Avoid spaces.
+ cmSystemTools::ReplaceString(dest, " ", "_");
+ this->TempDir += dest;
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmInstallExportGenerator::GenerateScript(std::ostream& os)
+{
+ // Get the export set requested.
+ ExportSet const* exportSet =
+ this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
+ ->GetExportSet(this->Name.c_str());
+
+ // Skip empty sets.
+ if(!exportSet)
+ {
+ cmOStringStream e;
+ e << "INSTALL(EXPORT) given unknown export \"" << this->Name << "\"";
+ cmSystemTools::Error(e.str().c_str());
+ return;
+ }
+
+ // Create the temporary directory in which to store the files.
+ this->ComputeTempDir();
+ cmSystemTools::MakeDirectory(this->TempDir.c_str());
+
+ // Construct a temporary location for the file.
+ this->MainImportFile = this->TempDir;
+ this->MainImportFile += "/";
+ this->MainImportFile += this->FileName;
+
+ // Generate the import file for this export set.
+ this->EFGen->SetName(this->Name.c_str());
+ this->EFGen->SetExportSet(exportSet);
+ this->EFGen->SetExportFile(this->MainImportFile.c_str());
+ this->EFGen->SetNamespace(this->Namespace.c_str());
+ if(this->ConfigurationTypes->empty())
+ {
+ if(this->ConfigurationName && *this->ConfigurationName)
+ {
+ this->EFGen->AddConfiguration(this->ConfigurationName);
+ }
+ else
+ {
+ this->EFGen->AddConfiguration("");
+ }
+ }
+ else
+ {
+ for(std::vector<std::string>::const_iterator
+ ci = this->ConfigurationTypes->begin();
+ ci != this->ConfigurationTypes->end(); ++ci)
+ {
+ this->EFGen->AddConfiguration(ci->c_str());
+ }
+ }
+ this->EFGen->GenerateImportFile();
+
+ // Perform the main install script generation.
+ this->cmInstallGenerator::GenerateScript(os);
+}
+
+//----------------------------------------------------------------------------
+void
+cmInstallExportGenerator::GenerateScriptConfigs(std::ostream& os,
+ Indent const& indent)
+{
+ // Create the main install rules first.
+ this->cmInstallGenerator::GenerateScriptConfigs(os, indent);
+
+ // 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
+ 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,
+ this->FilePermissions.c_str(), 0, 0, 0,
+ indent.Next());
+ os << indent << "ENDIF(" << config_test << ")\n";
+ files.clear();
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmInstallExportGenerator::GenerateScriptActions(std::ostream& os,
+ Indent const& indent)
+{
+ // Remove old per-configuration export files if the main changes.
+ std::string installedDir = "$ENV{DESTDIR}";
+ installedDir += this->GetInstallDestination();
+ installedDir += "/";
+ std::string installedFile = installedDir;
+ installedFile += this->FileName;
+ 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"
+ << indentN << " \"" << installedFile << "\"\n"
+ << indentN << " \"" << this->MainImportFile << "\")\n";
+ 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
+ << "\\\" 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";
+
+ // Install the main export file.
+ std::vector<std::string> files;
+ files.push_back(this->MainImportFile);
+ this->AddInstallRule(os, cmInstallType_FILES, files, false,
+ this->FilePermissions.c_str(), 0, 0, 0, indent);
+}
diff --git a/Source/cmInstallExportGenerator.h b/Source/cmInstallExportGenerator.h
new file mode 100644
index 000000000..1ff6e38e6
--- /dev/null
+++ b/Source/cmInstallExportGenerator.h
@@ -0,0 +1,58 @@
+/*============================================================================
+ 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 cmInstallExportGenerator_h
+#define cmInstallExportGenerator_h
+
+#include "cmInstallGenerator.h"
+
+class cmExportInstallFileGenerator;
+class cmInstallFilesGenerator;
+class cmInstallTargetGenerator;
+class cmTarget;
+class cmTargetExport;
+class cmMakefile;
+
+/** \class cmInstallExportGenerator
+ * \brief Generate rules for creating an export files.
+ */
+class cmInstallExportGenerator: public cmInstallGenerator
+{
+public:
+ cmInstallExportGenerator(const char* name,
+ const char* dest, const char* file_permissions,
+ const std::vector<std::string>& configurations,
+ const char* component,
+ const char* filename, const char* name_space,
+ cmMakefile* mf);
+ ~cmInstallExportGenerator();
+protected:
+ typedef std::vector<cmTargetExport*> ExportSet;
+
+ virtual void GenerateScript(std::ostream& os);
+ virtual void GenerateScriptConfigs(std::ostream& os, Indent const& indent);
+ virtual void GenerateScriptActions(std::ostream& os, Indent const& indent);
+ void GenerateImportFile(ExportSet const* exportSet);
+ void GenerateImportFile(const char* config, ExportSet const* exportSet);
+ void ComputeTempDir();
+
+ std::string Name;
+ std::string FilePermissions;
+ std::string FileName;
+ std::string Namespace;
+ cmMakefile* Makefile;
+
+ std::string TempDir;
+ std::string MainImportFile;
+ cmExportInstallFileGenerator* EFGen;
+};
+
+#endif
diff --git a/Source/cmInstallFilesCommand.cxx b/Source/cmInstallFilesCommand.cxx
new file mode 100644
index 000000000..cc62c4bac
--- /dev/null
+++ b/Source/cmInstallFilesCommand.cxx
@@ -0,0 +1,181 @@
+/*============================================================================
+ 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 "cmInstallFilesCommand.h"
+
+#include "cmInstallFilesGenerator.h"
+
+// cmExecutableCommand
+bool cmInstallFilesCommand
+::InitialPass(std::vector<std::string> const& argsIn, cmExecutionStatus &)
+{
+ if(argsIn.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->Destination = args[0];
+
+ if((args.size() > 1) && (args[1] == "FILES"))
+ {
+ this->IsFilesForm = true;
+ for(std::vector<std::string>::const_iterator s = args.begin()+2;
+ s != args.end(); ++s)
+ {
+ // Find the source location for each file listed.
+ std::string f = this->FindInstallSource(s->c_str());
+ this->Files.push_back(f);
+ }
+ this->CreateInstallGenerator();
+ }
+ 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->Makefile->GetLocalGenerator()->GetGlobalGenerator()
+ ->AddInstallComponent(this->Makefile->GetSafeDefinition(
+ "CMAKE_INSTALL_DEFAULT_COMPONENT_NAME"));
+
+ return true;
+}
+
+void cmInstallFilesCommand::FinalPass()
+{
+ // No final pass for "FILES" form of arguments.
+ if(this->IsFilesForm)
+ {
+ return;
+ }
+
+ std::string testf;
+ std::string ext = this->FinalArgs[0];
+
+ // two different options
+ if (this->FinalArgs.size() > 1)
+ {
+ // now put the files into the list
+ std::vector<std::string>::iterator s = this->FinalArgs.begin();
+ ++s;
+ // for each argument, get the files
+ for (;s != this->FinalArgs.end(); ++s)
+ {
+ // replace any variables
+ std::string temps = *s;
+ if (cmSystemTools::GetFilenamePath(temps).size() > 0)
+ {
+ testf = cmSystemTools::GetFilenamePath(temps) + "/" +
+ cmSystemTools::GetFilenameWithoutLastExtension(temps) + ext;
+ }
+ else
+ {
+ testf = cmSystemTools::GetFilenameWithoutLastExtension(temps) + ext;
+ }
+
+ // add to the result
+ this->Files.push_back(this->FindInstallSource(testf.c_str()));
+ }
+ }
+ 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::vector<std::string>::iterator s = files.begin();
+ // for each argument, get the files
+ for (;s != files.end(); ++s)
+ {
+ this->Files.push_back(this->FindInstallSource(s->c_str()));
+ }
+ }
+
+ this->CreateInstallGenerator();
+}
+
+void cmInstallFilesCommand::CreateInstallGenerator() const
+{
+ // Construct the destination. This command always installs under
+ // the prefix. We skip the leading slash given by the user.
+ std::string destination = this->Destination.substr(1);
+ cmSystemTools::ConvertToUnixSlashes(destination);
+ if(destination.empty())
+ {
+ destination = ".";
+ }
+
+ // Use a file install generator.
+ const char* no_permissions = "";
+ const char* no_rename = "";
+ std::string no_component = this->Makefile->GetSafeDefinition(
+ "CMAKE_INSTALL_DEFAULT_COMPONENT_NAME");
+ std::vector<std::string> no_configurations;
+ this->Makefile->AddInstallGenerator(
+ new cmInstallFilesGenerator(this->Files,
+ destination.c_str(), false,
+ no_permissions, no_configurations,
+ no_component.c_str(), no_rename));
+}
+
+
+/**
+ * Find a file in the build or source tree for installation given a
+ * relative path from the CMakeLists.txt file. This will favor files
+ * present in the build tree. If a full path is given, it is just
+ * returned.
+ */
+std::string cmInstallFilesCommand::FindInstallSource(const char* name) const
+{
+ if(cmSystemTools::FileIsFullPath(name))
+ {
+ // This is a full path.
+ return name;
+ }
+
+ // This is a relative path.
+ std::string tb = this->Makefile->GetCurrentOutputDirectory();
+ tb += "/";
+ tb += name;
+ std::string ts = this->Makefile->GetCurrentDirectory();
+ ts += "/";
+ ts += name;
+
+ if(cmSystemTools::FileExists(tb.c_str()))
+ {
+ // The file exists in the binary tree. Use it.
+ return tb;
+ }
+ else if(cmSystemTools::FileExists(ts.c_str()))
+ {
+ // The file exists in the source tree. Use it.
+ return ts;
+ }
+ else
+ {
+ // The file doesn't exist. Assume it will be present in the
+ // binary tree when the install occurs.
+ return tb;
+ }
+}
diff --git a/Source/cmInstallFilesCommand.h b/Source/cmInstallFilesCommand.h
new file mode 100644
index 000000000..d3c7ed67f
--- /dev/null
+++ b/Source/cmInstallFilesCommand.h
@@ -0,0 +1,114 @@
+/*============================================================================
+ 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 cmInstallFilesCommand_h
+#define cmInstallFilesCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmInstallFilesCommand
+ * \brief Specifies where to install some files
+ *
+ * cmInstallFilesCommand specifies the relative path where a list of
+ * files should be installed.
+ */
+class cmInstallFilesCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmInstallFilesCommand;
+ }
+
+ /**
+ * 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 const char* GetName() const { return "install_files";}
+
+ /**
+ * Succinct documentation.
+ */
+ virtual const char* GetTerseDocumentation() const
+ {
+ return "Deprecated. Use the install(FILES ) command instead.";
+ }
+
+ /**
+ * This is called at the end after all the information
+ * specified by the command is accumulated. Most commands do
+ * not implement this method. At this point, reading and
+ * writing to the cache can be done.
+ */
+ 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:
+ void CreateInstallGenerator() const;
+ std::string FindInstallSource(const char* name) const;
+
+ private:
+ std::vector<std::string> FinalArgs;
+ bool IsFilesForm;
+ std::string Destination;
+ std::vector<std::string> Files;
+};
+
+
+#endif
diff --git a/Source/cmInstallFilesGenerator.cxx b/Source/cmInstallFilesGenerator.cxx
new file mode 100644
index 000000000..ec02bc76a
--- /dev/null
+++ b/Source/cmInstallFilesGenerator.cxx
@@ -0,0 +1,50 @@
+/*============================================================================
+ 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 "cmInstallFilesGenerator.h"
+
+//----------------------------------------------------------------------------
+cmInstallFilesGenerator
+::cmInstallFilesGenerator(std::vector<std::string> const& files,
+ const char* dest, bool programs,
+ const char* file_permissions,
+ std::vector<std::string> const& configurations,
+ const char* component,
+ const char* rename,
+ bool optional):
+ cmInstallGenerator(dest, configurations, component),
+ Files(files), Programs(programs),
+ FilePermissions(file_permissions),
+ Rename(rename), Optional(optional)
+{
+}
+
+//----------------------------------------------------------------------------
+cmInstallFilesGenerator
+::~cmInstallFilesGenerator()
+{
+}
+
+//----------------------------------------------------------------------------
+void cmInstallFilesGenerator::GenerateScriptActions(std::ostream& os,
+ Indent const& indent)
+{
+ // Write code to install the files.
+ const char* no_dir_permissions = 0;
+ this->AddInstallRule(os,
+ (this->Programs
+ ? cmInstallType_PROGRAMS
+ : cmInstallType_FILES),
+ this->Files,
+ this->Optional,
+ this->FilePermissions.c_str(), no_dir_permissions,
+ this->Rename.c_str(), 0, indent);
+}
diff --git a/Source/cmInstallFilesGenerator.h b/Source/cmInstallFilesGenerator.h
new file mode 100644
index 000000000..871335c64
--- /dev/null
+++ b/Source/cmInstallFilesGenerator.h
@@ -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.
+============================================================================*/
+#ifndef cmInstallFilesGenerator_h
+#define cmInstallFilesGenerator_h
+
+#include "cmInstallGenerator.h"
+
+/** \class cmInstallFilesGenerator
+ * \brief Generate file installation rules.
+ */
+class cmInstallFilesGenerator: public cmInstallGenerator
+{
+public:
+ cmInstallFilesGenerator(std::vector<std::string> const& files,
+ const char* dest, bool programs,
+ const char* file_permissions,
+ std::vector<std::string> const& configurations,
+ const char* component,
+ const char* rename,
+ bool optional = false);
+ virtual ~cmInstallFilesGenerator();
+
+protected:
+ virtual void GenerateScriptActions(std::ostream& os, Indent const& indent);
+ std::vector<std::string> Files;
+ bool Programs;
+ std::string FilePermissions;
+ std::string Rename;
+ bool Optional;
+};
+
+#endif
diff --git a/Source/cmInstallGenerator.cxx b/Source/cmInstallGenerator.cxx
new file mode 100644
index 000000000..3be2c2b14
--- /dev/null
+++ b/Source/cmInstallGenerator.cxx
@@ -0,0 +1,182 @@
+/*============================================================================
+ 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 "cmInstallGenerator.h"
+
+#include "cmSystemTools.h"
+
+//----------------------------------------------------------------------------
+cmInstallGenerator
+::cmInstallGenerator(const char* destination,
+ std::vector<std::string> const& configurations,
+ const char* component):
+ cmScriptGenerator("CMAKE_INSTALL_CONFIG_NAME", configurations),
+ Destination(destination? destination:""),
+ Component(component? component:"")
+{
+}
+
+//----------------------------------------------------------------------------
+cmInstallGenerator
+::~cmInstallGenerator()
+{
+}
+
+//----------------------------------------------------------------------------
+void cmInstallGenerator
+::AddInstallRule(
+ std::ostream& os,
+ cmInstallType type,
+ std::vector<std::string> const& files,
+ bool optional /* = false */,
+ const char* permissions_file /* = 0 */,
+ const char* permissions_dir /* = 0 */,
+ const char* rename /* = 0 */,
+ const char* literal_args /* = 0 */,
+ Indent const& indent
+ )
+{
+ // Use the FILE command to install the file.
+ std::string stype;
+ switch(type)
+ {
+ case cmInstallType_DIRECTORY: stype = "DIRECTORY"; break;
+ case cmInstallType_PROGRAMS: stype = "PROGRAM"; break;
+ case cmInstallType_EXECUTABLE: stype = "EXECUTABLE"; break;
+ case cmInstallType_STATIC_LIBRARY: stype = "STATIC_LIBRARY"; break;
+ case cmInstallType_SHARED_LIBRARY: stype = "SHARED_LIBRARY"; break;
+ case cmInstallType_MODULE_LIBRARY: stype = "MODULE"; break;
+ 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";
+ os << indent << " \"";
+ for(std::vector<std::string>::const_iterator fi = files.begin();
+ fi != files.end(); ++fi)
+ {
+ if (fi!=files.begin())
+ {
+ os << ";";
+ }
+ os << dest << "/";
+ if (rename && *rename)
+ {
+ os << rename;
+ }
+ else
+ {
+ os << cmSystemTools::GetFilenameName(*fi);
+ }
+ }
+ os << "\")\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 << "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 << "FILE(INSTALL DESTINATION \"" << dest << "\" TYPE " << stype.c_str();
+ if(optional)
+ {
+ os << " OPTIONAL";
+ }
+ if(permissions_file && *permissions_file)
+ {
+ os << " PERMISSIONS" << permissions_file;
+ }
+ if(permissions_dir && *permissions_dir)
+ {
+ os << " DIR_PERMISSIONS" << permissions_dir;
+ }
+ if(rename && *rename)
+ {
+ os << " RENAME \"" << rename << "\"";
+ }
+ os << " FILES";
+ if(files.size() == 1)
+ {
+ os << " \"" << files[0] << "\"";
+ }
+ else
+ {
+ for(std::vector<std::string>::const_iterator fi = files.begin();
+ fi != files.end(); ++fi)
+ {
+ os << "\n" << indent << " \"" << *fi << "\"";
+ }
+ os << "\n" << indent << " ";
+ if(!(literal_args && *literal_args))
+ {
+ os << " ";
+ }
+ }
+ if(literal_args && *literal_args)
+ {
+ os << literal_args;
+ }
+ os << ")\n";
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmInstallGenerator::CreateComponentTest(const char* component)
+{
+ std::string result = "NOT CMAKE_INSTALL_COMPONENT OR "
+ "\"${CMAKE_INSTALL_COMPONENT}\" STREQUAL \"";
+ result += component;
+ result += "\"";
+ return result;
+}
+
+//----------------------------------------------------------------------------
+void cmInstallGenerator::GenerateScript(std::ostream& os)
+{
+ // Track indentation.
+ Indent indent;
+
+ // Begin this block of installation.
+ std::string component_test =
+ this->CreateComponentTest(this->Component.c_str());
+ 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";
+}
+
+//----------------------------------------------------------------------------
+bool cmInstallGenerator::InstallsForConfig(const char* config)
+{
+ return this->GeneratesForConfig(config);
+}
+
+//----------------------------------------------------------------------------
+std::string cmInstallGenerator::GetInstallDestination() const
+{
+ std::string result;
+ if(!this->Destination.empty() &&
+ !cmSystemTools::FileIsFullPath(this->Destination.c_str()))
+ {
+ result = "${CMAKE_INSTALL_PREFIX}/";
+ }
+ result += this->Destination;
+ return result;
+}
diff --git a/Source/cmInstallGenerator.h b/Source/cmInstallGenerator.h
new file mode 100644
index 000000000..c89ab8ac5
--- /dev/null
+++ b/Source/cmInstallGenerator.h
@@ -0,0 +1,63 @@
+/*============================================================================
+ 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 cmInstallGenerator_h
+#define cmInstallGenerator_h
+
+#include "cmInstallType.h"
+#include "cmScriptGenerator.h"
+
+class cmLocalGenerator;
+
+/** \class cmInstallGenerator
+ * \brief Support class for generating install scripts.
+ *
+ */
+class cmInstallGenerator: public cmScriptGenerator
+{
+public:
+ cmInstallGenerator(const char* destination,
+ std::vector<std::string> const& configurations,
+ const char* component);
+ virtual ~cmInstallGenerator();
+
+ void AddInstallRule(
+ std::ostream& os, cmInstallType type,
+ std::vector<std::string> const& files,
+ bool optional = false,
+ const char* permissions_file = 0,
+ const char* permissions_dir = 0,
+ const char* rename = 0,
+ const char* literal_args = 0,
+ 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;
+
+ /** Test if this generator installs something for a given configuration. */
+ bool InstallsForConfig(const char*);
+
+protected:
+ virtual void GenerateScript(std::ostream& os);
+
+ std::string CreateComponentTest(const char* component);
+
+ // Information shared by most generator types.
+ std::string Destination;
+ std::string Component;
+};
+
+#endif
diff --git a/Source/cmInstallProgramsCommand.cxx b/Source/cmInstallProgramsCommand.cxx
new file mode 100644
index 000000000..3a0a3223b
--- /dev/null
+++ b/Source/cmInstallProgramsCommand.cxx
@@ -0,0 +1,142 @@
+/*============================================================================
+ 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 "cmInstallProgramsCommand.h"
+#include "cmInstallFilesGenerator.h"
+// cmExecutableCommand
+bool cmInstallProgramsCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 2)
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ // Enable the install target.
+ this->Makefile->GetLocalGenerator()
+ ->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->Makefile->GetLocalGenerator()->GetGlobalGenerator()
+ ->AddInstallComponent(this->Makefile->GetSafeDefinition(
+ "CMAKE_INSTALL_DEFAULT_COMPONENT_NAME"));
+
+ return true;
+}
+
+void cmInstallProgramsCommand::FinalPass()
+{
+ bool files_mode = false;
+ if(!this->FinalArgs.empty() && this->FinalArgs[0] == "FILES")
+ {
+ files_mode = true;
+ }
+
+ // two different options
+ if (this->FinalArgs.size() > 1 || files_mode)
+ {
+ // for each argument, get the programs
+ std::vector<std::string>::iterator s = this->FinalArgs.begin();
+ if(files_mode)
+ {
+ // Skip the FILES argument in files mode.
+ ++s;
+ }
+ for(;s != this->FinalArgs.end(); ++s)
+ {
+ // add to the result
+ this->Files.push_back(this->FindInstallSource(s->c_str()));
+ }
+ }
+ else // reg exp list
+ {
+ std::vector<std::string> programs;
+ cmSystemTools::Glob(this->Makefile->GetCurrentDirectory(),
+ this->FinalArgs[0].c_str(), programs);
+
+ std::vector<std::string>::iterator s = programs.begin();
+ // for each argument, get the programs
+ for (;s != programs.end(); ++s)
+ {
+ this->Files.push_back(this->FindInstallSource(s->c_str()));
+ }
+ }
+
+ // Construct the destination. This command always installs under
+ // the prefix. We skip the leading slash given by the user.
+ std::string destination = this->Destination.substr(1);
+ cmSystemTools::ConvertToUnixSlashes(destination);
+ if(destination.empty())
+ {
+ destination = ".";
+ }
+
+ // Use a file install generator.
+ const char* no_permissions = "";
+ const char* no_rename = "";
+ std::string no_component = this->Makefile->GetSafeDefinition(
+ "CMAKE_INSTALL_DEFAULT_COMPONENT_NAME");
+ std::vector<std::string> no_configurations;
+ this->Makefile->AddInstallGenerator(
+ new cmInstallFilesGenerator(this->Files,
+ destination.c_str(), true,
+ no_permissions, no_configurations,
+ no_component.c_str(), no_rename));
+}
+
+/**
+ * Find a file in the build or source tree for installation given a
+ * relative path from the CMakeLists.txt file. This will favor files
+ * present in the build tree. If a full path is given, it is just
+ * returned.
+ */
+std::string cmInstallProgramsCommand
+::FindInstallSource(const char* name) const
+{
+ if(cmSystemTools::FileIsFullPath(name))
+ {
+ // This is a full path.
+ return name;
+ }
+
+ // This is a relative path.
+ std::string tb = this->Makefile->GetCurrentOutputDirectory();
+ tb += "/";
+ tb += name;
+ std::string ts = this->Makefile->GetCurrentDirectory();
+ ts += "/";
+ ts += name;
+
+ if(cmSystemTools::FileExists(tb.c_str()))
+ {
+ // The file exists in the binary tree. Use it.
+ return tb;
+ }
+ else if(cmSystemTools::FileExists(ts.c_str()))
+ {
+ // The file exists in the source tree. Use it.
+ return ts;
+ }
+ else
+ {
+ // The file doesn't exist. Assume it will be present in the
+ // binary tree when the install occurs.
+ return tb;
+ }
+}
diff --git a/Source/cmInstallProgramsCommand.h b/Source/cmInstallProgramsCommand.h
new file mode 100644
index 000000000..29c84a09f
--- /dev/null
+++ b/Source/cmInstallProgramsCommand.h
@@ -0,0 +1,108 @@
+/*============================================================================
+ 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 cmInstallProgramsCommand_h
+#define cmInstallProgramsCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmInstallProgramsCommand
+ * \brief Specifies where to install some programs
+ *
+ * cmInstallProgramsCommand specifies the relative path where a list of
+ * programs should be installed.
+ */
+class cmInstallProgramsCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmInstallProgramsCommand;
+ }
+
+ /**
+ * 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 const char* GetName() const { return "install_programs";}
+
+ /**
+ * Succinct documentation.
+ */
+ virtual const char* GetTerseDocumentation() const
+ {
+ return "Deprecated. Use the install(PROGRAMS ) command instead.";
+ }
+
+ /**
+ * This is called at the end after all the information
+ * specified by the command is accumulated. Most commands do
+ * not implement this method. At this point, reading and
+ * writing to the cache can be done.
+ */
+ virtual void FinalPass();
+
+ 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:
+ std::string FindInstallSource(const char* name) const;
+private:
+ std::vector<std::string> FinalArgs;
+ std::string Destination;
+ std::vector<std::string> Files;
+};
+
+
+#endif
diff --git a/Source/cmInstallScriptGenerator.cxx b/Source/cmInstallScriptGenerator.cxx
new file mode 100644
index 000000000..bcfbe63c5
--- /dev/null
+++ b/Source/cmInstallScriptGenerator.cxx
@@ -0,0 +1,47 @@
+/*============================================================================
+ 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 "cmInstallScriptGenerator.h"
+
+//----------------------------------------------------------------------------
+cmInstallScriptGenerator
+::cmInstallScriptGenerator(const char* script, bool code,
+ const char* component) :
+ cmInstallGenerator(0, std::vector<std::string>(), component),
+ Script(script), Code(code)
+{
+}
+
+//----------------------------------------------------------------------------
+cmInstallScriptGenerator
+::~cmInstallScriptGenerator()
+{
+}
+
+//----------------------------------------------------------------------------
+void cmInstallScriptGenerator::GenerateScript(std::ostream& os)
+{
+ Indent indent;
+ std::string component_test =
+ this->CreateComponentTest(this->Component.c_str());
+ os << indent << "IF(" << component_test << ")\n";
+
+ if(this->Code)
+ {
+ os << indent.Next() << this->Script << "\n";
+ }
+ else
+ {
+ os << indent.Next() << "INCLUDE(\"" << this->Script << "\")\n";
+ }
+
+ os << indent << "ENDIF(" << component_test << ")\n\n";
+}
diff --git a/Source/cmInstallScriptGenerator.h b/Source/cmInstallScriptGenerator.h
new file mode 100644
index 000000000..54a7b2195
--- /dev/null
+++ b/Source/cmInstallScriptGenerator.h
@@ -0,0 +1,33 @@
+/*============================================================================
+ 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 cmInstallScriptGenerator_h
+#define cmInstallScriptGenerator_h
+
+#include "cmInstallGenerator.h"
+
+/** \class cmInstallScriptGenerator
+ * \brief Generate target installation rules.
+ */
+class cmInstallScriptGenerator: public cmInstallGenerator
+{
+public:
+ cmInstallScriptGenerator(const char* script, bool code,
+ const char* component);
+ virtual ~cmInstallScriptGenerator();
+
+protected:
+ virtual void GenerateScript(std::ostream& os);
+ std::string Script;
+ bool Code;
+};
+
+#endif
diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx
new file mode 100644
index 000000000..5f9b6585e
--- /dev/null
+++ b/Source/cmInstallTargetGenerator.cxx
@@ -0,0 +1,738 @@
+/*============================================================================
+ 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 "cmInstallTargetGenerator.h"
+
+#include "cmComputeLinkInformation.h"
+#include "cmGlobalGenerator.h"
+#include "cmLocalGenerator.h"
+#include "cmMakefile.h"
+#include "cmake.h"
+
+#include <assert.h>
+
+//----------------------------------------------------------------------------
+cmInstallTargetGenerator
+::cmInstallTargetGenerator(cmTarget& t, 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)
+{
+ this->ActionsPerConfig = true;
+ this->NamelinkMode = NamelinkModeNone;
+ this->Target->SetHaveInstallRule(true);
+}
+
+//----------------------------------------------------------------------------
+cmInstallTargetGenerator
+::~cmInstallTargetGenerator()
+{
+}
+
+//----------------------------------------------------------------------------
+void cmInstallTargetGenerator::GenerateScript(std::ostream& os)
+{
+ // Warn if installing an exclude-from-all target.
+ if(this->Target->GetPropertyAsBool("EXCLUDE_FROM_ALL"))
+ {
+ cmOStringStream 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 "
+ << "not define behavior for this case.";
+ cmSystemTools::Message(msg.str().c_str(), "Warning");
+ }
+
+ // Perform the main install script generation.
+ this->cmInstallGenerator::GenerateScript(os);
+}
+
+//----------------------------------------------------------------------------
+void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
+ const char* 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 += cmake::GetCMakeFilesDirectory();
+ fromDirConfig += "/CMakeRelink.dir/";
+ }
+ else
+ {
+ fromDirConfig = this->Target->GetDirectory(config, this->ImportLibrary);
+ fromDirConfig += "/";
+ }
+ std::string toDir = this->GetInstallDestination();
+ 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();
+ 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,
+ "cmInstallTargetGenerator created with non-installable target.");
+ return;
+ }
+ if(targetType == cmTarget::EXECUTABLE)
+ {
+ // There is a bug in cmInstallCommand if this fails.
+ assert(this->NamelinkMode == NamelinkModeNone);
+
+ std::string targetName;
+ std::string targetNameReal;
+ std::string targetNameImport;
+ std::string targetNamePDB;
+ this->Target->GetExecutableNames(targetName, targetNameReal,
+ targetNameImport, targetNamePDB,
+ config);
+ if(this->ImportLibrary)
+ {
+ std::string from1 = fromDirConfig + targetNameImport;
+ std::string to1 = toDir + targetNameImport;
+ filesFrom.push_back(from1);
+ filesTo.push_back(to1);
+ std::string targetNameImportLib;
+ if(this->Target->GetImplibGNUtoMS(targetNameImport,
+ targetNameImportLib))
+ {
+ filesFrom.push_back(fromDirConfig + targetNameImportLib);
+ filesTo.push_back(toDir + targetNameImportLib);
+ }
+
+ // An import library looks like a static library.
+ type = cmInstallType_STATIC_LIBRARY;
+ }
+ else
+ {
+ std::string from1 = fromDirConfig + targetName;
+ std::string to1 = toDir + targetName;
+
+ // Handle OSX Bundles.
+ if(this->Target->IsAppBundleOnApple())
+ {
+ // 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 += targetName;
+ }
+ else
+ {
+ // Tweaks apply to the real file, so list it first.
+ if(targetNameReal != targetName)
+ {
+ std::string from2 = fromDirConfig + targetNameReal;
+ std::string to2 = toDir += targetNameReal;
+ filesFrom.push_back(from2);
+ filesTo.push_back(to2);
+ }
+ }
+
+ filesFrom.push_back(from1);
+ filesTo.push_back(to1);
+ }
+ }
+ else
+ {
+ std::string targetName;
+ std::string targetNameSO;
+ std::string targetNameReal;
+ std::string targetNameImport;
+ std::string targetNamePDB;
+ this->Target->GetLibraryNames(targetName, targetNameSO, targetNameReal,
+ targetNameImport, targetNamePDB,
+ config);
+ if(this->ImportLibrary)
+ {
+ // There is a bug in cmInstallCommand if this fails.
+ assert(this->NamelinkMode == NamelinkModeNone);
+
+ std::string from1 = fromDirConfig + targetNameImport;
+ std::string to1 = toDir + targetNameImport;
+ filesFrom.push_back(from1);
+ filesTo.push_back(to1);
+ std::string targetNameImportLib;
+ if(this->Target->GetImplibGNUtoMS(targetNameImport,
+ targetNameImportLib))
+ {
+ filesFrom.push_back(fromDirConfig + targetNameImportLib);
+ filesTo.push_back(toDir + targetNameImportLib);
+ }
+
+ // An import library looks like a static library.
+ type = cmInstallType_STATIC_LIBRARY;
+ }
+ else if(this->Target->IsFrameworkOnApple())
+ {
+ // There is a bug in cmInstallCommand if this fails.
+ assert(this->NamelinkMode == NamelinkModeNone);
+
+ // Install the whole framework directory.
+ type = cmInstallType_DIRECTORY;
+ literal_args += " USE_SOURCE_PERMISSIONS";
+ std::string from1 = fromDirConfig + targetName + ".framework";
+
+ // Tweaks apply to the binary inside the bundle.
+ std::string to1 = toDir + targetName;
+ to1 += ".framework/Versions/";
+ to1 += this->Target->GetFrameworkVersion();
+ to1 += "/";
+ to1 += targetName;
+
+ filesFrom.push_back(from1);
+ filesTo.push_back(to1);
+ }
+ else
+ {
+ bool haveNamelink = false;
+
+ // Library link name.
+ std::string fromName = fromDirConfig + targetName;
+ std::string toName = toDir + targetName;
+
+ // Library interface name.
+ std::string fromSOName;
+ std::string toSOName;
+ if(targetNameSO != targetName)
+ {
+ haveNamelink = true;
+ fromSOName = fromDirConfig + targetNameSO;
+ toSOName = toDir + targetNameSO;
+ }
+
+ // Library implementation name.
+ std::string fromRealName;
+ std::string toRealName;
+ if(targetNameReal != targetName &&
+ targetNameReal != targetNameSO)
+ {
+ haveNamelink = true;
+ fromRealName = fromDirConfig + targetNameReal;
+ toRealName = toDir + targetNameReal;
+ }
+
+ // Add the names based on the current namelink mode.
+ if(haveNamelink)
+ {
+ // With a namelink we need to check the mode.
+ if(this->NamelinkMode == NamelinkModeOnly)
+ {
+ // Install the namelink only.
+ filesFrom.push_back(fromName);
+ filesTo.push_back(toName);
+ }
+ else
+ {
+ // Install the real file if it has its own name.
+ if(!fromRealName.empty())
+ {
+ filesFrom.push_back(fromRealName);
+ filesTo.push_back(toRealName);
+ }
+
+ // Install the soname link if it has its own name.
+ if(!fromSOName.empty())
+ {
+ filesFrom.push_back(fromSOName);
+ filesTo.push_back(toSOName);
+ }
+
+ // Install the namelink if it is not to be skipped.
+ if(this->NamelinkMode != NamelinkModeSkip)
+ {
+ filesFrom.push_back(fromName);
+ filesTo.push_back(toName);
+ }
+ }
+ }
+ else
+ {
+ // Without a namelink there will be only one file. Install it
+ // if this is not a namelink-only rule.
+ if(this->NamelinkMode != NamelinkModeOnly)
+ {
+ filesFrom.push_back(fromName);
+ filesTo.push_back(toName);
+ }
+ }
+ }
+ }
+
+ // If this fails the above code is buggy.
+ assert(filesFrom.size() == filesTo.size());
+
+ // Skip this rule if no files are to be installed for the target.
+ if(filesFrom.empty())
+ {
+ return;
+ }
+
+ // Add pre-installation tweaks.
+ this->AddTweak(os, indent, config, filesTo,
+ &cmInstallTargetGenerator::PreReplacementTweaks);
+
+ // Write code to install the target file.
+ const char* no_dir_permissions = 0;
+ const char* no_rename = 0;
+ bool optional = this->Optional || this->ImportLibrary;
+ this->AddInstallRule(os, type, filesFrom,
+ optional,
+ this->FilePermissions.c_str(), no_dir_permissions,
+ no_rename, literal_args.c_str(),
+ indent);
+
+ // Add post-installation tweaks.
+ this->AddTweak(os, indent, config, filesTo,
+ &cmInstallTargetGenerator::PostReplacementTweaks);
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmInstallTargetGenerator::GetInstallFilename(const char* config) const
+{
+ NameType nameType = this->ImportLibrary? NameImplib : NameNormal;
+ return
+ cmInstallTargetGenerator::GetInstallFilename(this->Target, config,
+ nameType);
+}
+
+//----------------------------------------------------------------------------
+std::string cmInstallTargetGenerator::GetInstallFilename(cmTarget* target,
+ const char* config,
+ NameType nameType)
+{
+ std::string fname;
+ // Compute the name of the library.
+ if(target->GetType() == cmTarget::EXECUTABLE)
+ {
+ std::string targetName;
+ std::string targetNameReal;
+ std::string targetNameImport;
+ std::string targetNamePDB;
+ target->GetExecutableNames(targetName, targetNameReal,
+ targetNameImport, targetNamePDB,
+ config);
+ if(nameType == NameImplib)
+ {
+ // Use the import library name.
+ if(!target->GetImplibGNUtoMS(targetNameImport, fname,
+ "${CMAKE_IMPORT_LIBRARY_SUFFIX}"))
+ {
+ fname = targetNameImport;
+ }
+ }
+ else if(nameType == NameReal)
+ {
+ // Use the canonical name.
+ fname = targetNameReal;
+ }
+ else
+ {
+ // Use the canonical name.
+ fname = targetName;
+ }
+ }
+ else
+ {
+ std::string targetName;
+ std::string targetNameSO;
+ std::string targetNameReal;
+ std::string targetNameImport;
+ std::string targetNamePDB;
+ target->GetLibraryNames(targetName, targetNameSO, targetNameReal,
+ targetNameImport, targetNamePDB, config);
+ if(nameType == NameImplib)
+ {
+ // Use the import library name.
+ if(!target->GetImplibGNUtoMS(targetNameImport, fname,
+ "${CMAKE_IMPORT_LIBRARY_SUFFIX}"))
+ {
+ fname = targetNameImport;
+ }
+ }
+ else if(nameType == NameSO)
+ {
+ // Use the soname.
+ fname = targetNameSO;
+ }
+ else if(nameType == NameReal)
+ {
+ // Use the real name.
+ fname = targetNameReal;
+ }
+ else
+ {
+ // Use the canonical name.
+ fname = targetName;
+ }
+ }
+
+ return fname;
+}
+
+//----------------------------------------------------------------------------
+void
+cmInstallTargetGenerator
+::AddTweak(std::ostream& os, Indent const& indent, const char* config,
+ std::string const& file, TweakMethod tweak)
+{
+ cmOStringStream tw;
+ (this->*tweak)(tw, indent.Next(), config, file);
+ std::string tws = tw.str();
+ if(!tws.empty())
+ {
+ os << indent << "IF(EXISTS \"" << file << "\" AND\n"
+ << indent << " NOT IS_SYMLINK \"" << file << "\")\n";
+ os << tws;
+ os << indent << "ENDIF()\n";
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmInstallTargetGenerator
+::AddTweak(std::ostream& os, Indent const& indent, const char* config,
+ std::vector<std::string> const& files, TweakMethod tweak)
+{
+ if(files.size() == 1)
+ {
+ // Tweak a single file.
+ this->AddTweak(os, indent, config, this->GetDestDirPath(files[0]), tweak);
+ }
+ else
+ {
+ // Generate a foreach loop to tweak multiple files.
+ cmOStringStream 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";
+ for(std::vector<std::string>::const_iterator i = files.begin();
+ i != files.end(); ++i)
+ {
+ os << indent2 << "\"" << this->GetDestDirPath(*i) << "\"\n";
+ }
+ os << indent2 << ")\n";
+ os << tws;
+ os << indent << "ENDFOREACH()\n";
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string cmInstallTargetGenerator::GetDestDirPath(std::string const& file)
+{
+ // Construct the path of the file on disk after installation on
+ // which tweaks may be performed.
+ std::string toDestDirPath = "$ENV{DESTDIR}";
+ if(file[0] != '/' && file[0] != '$')
+ {
+ toDestDirPath += "/";
+ }
+ toDestDirPath += file;
+ return toDestDirPath;
+}
+
+//----------------------------------------------------------------------------
+void cmInstallTargetGenerator::PreReplacementTweaks(std::ostream& os,
+ Indent const& indent,
+ const char* config,
+ std::string const& file)
+{
+ this->AddRPathCheckRule(os, indent, config, file);
+}
+
+//----------------------------------------------------------------------------
+void cmInstallTargetGenerator::PostReplacementTweaks(std::ostream& os,
+ Indent const& indent,
+ const char* config,
+ std::string const& file)
+{
+ this->AddInstallNamePatchRule(os, indent, config, file);
+ this->AddChrpathPatchRule(os, indent, config, file);
+ this->AddRanlibRule(os, indent, file);
+ this->AddStripRule(os, indent, file);
+}
+
+//----------------------------------------------------------------------------
+void
+cmInstallTargetGenerator
+::AddInstallNamePatchRule(std::ostream& os, Indent const& indent,
+ const char* 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))
+ {
+ return;
+ }
+
+ // Fix the install_name settings in installed binaries.
+ std::string installNameTool =
+ this->Target->GetMakefile()->GetSafeDefinition("CMAKE_INSTALL_NAME_TOOL");
+
+ if(!installNameTool.size())
+ {
+ 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;
+ 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)
+ {
+ cmTarget* tgt = *j;
+
+ // The install_name of an imported target does not change.
+ if(tgt->IsImported())
+ {
+ continue;
+ }
+
+ // If the build tree and install tree use different path
+ // components of the install_name field then we need to create a
+ // mapping to be applied after installation.
+ std::string for_build = tgt->GetInstallNameDirForBuildTree(config);
+ std::string for_install = tgt->GetInstallNameDirForInstallTree(config);
+ if(for_build != for_install)
+ {
+ // The directory portions differ. Append the filename to
+ // create the mapping.
+ std::string fname =
+ this->GetInstallFilename(tgt, config, NameSO);
+
+ // Map from the build-tree install_name.
+ for_build += fname;
+
+ // Map to the install-tree install_name.
+ for_install += fname;
+
+ // Store the mapping entry.
+ install_name_remap[for_build] = for_install;
+ }
+ }
+ }
+
+ // Edit the install_name of the target itself if necessary.
+ std::string new_id;
+ if(this->Target->GetType() == cmTarget::SHARED_LIBRARY)
+ {
+ std::string for_build =
+ this->Target->GetInstallNameDirForBuildTree(config);
+ std::string for_install =
+ this->Target->GetInstallNameDirForInstallTree(config);
+
+ if(this->Target->IsFrameworkOnApple() && for_install.empty())
+ {
+ // Frameworks seem to have an id corresponding to their own full
+ // path.
+ // ...
+ // for_install = fullDestPath_without_DESTDIR_or_name;
+ }
+
+ // If the install name will change on installation set the new id
+ // on the installed file.
+ if(for_build != for_install)
+ {
+ // Prepare to refer to the install-tree install_name.
+ new_id = for_install;
+ new_id += this->GetInstallFilename(this->Target, config, NameSO);
+ }
+ }
+
+ // Write a rule to run install_name_tool to set the install-tree
+ // install_name value and references.
+ if(!new_id.empty() || !install_name_remap.empty())
+ {
+ os << indent << "EXECUTE_PROCESS(COMMAND \"" << installNameTool;
+ os << "\"";
+ if(!new_id.empty())
+ {
+ os << "\n" << indent << " -id \"" << new_id << "\"";
+ }
+ for(std::map<cmStdString, cmStdString>::const_iterator
+ i = install_name_remap.begin();
+ i != install_name_remap.end(); ++i)
+ {
+ os << "\n" << indent << " -change \""
+ << i->first << "\" \"" << i->second << "\"";
+ }
+ os << "\n" << indent << " \"" << toDestDirPath << "\")\n";
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmInstallTargetGenerator
+::AddRPathCheckRule(std::ostream& os, Indent const& indent,
+ const char* config, std::string const& toDestDirPath)
+{
+ // Skip the chrpath if the target does not need it.
+ if(this->ImportLibrary || !this->Target->IsChrpathUsed(config))
+ {
+ return;
+ }
+
+ // Get the link information for this target.
+ // It can provide the RPATH.
+ cmComputeLinkInformation* cli = this->Target->GetLinkInformation(config);
+ if(!cli)
+ {
+ return;
+ }
+
+ // Get the install RPATH from the link information.
+ std::string newRpath = cli->GetChrpathString();
+
+ // 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"
+ << indent << " FILE \"" << toDestDirPath << "\"\n"
+ << indent << " RPATH \"" << newRpath << "\")\n";
+}
+
+//----------------------------------------------------------------------------
+void
+cmInstallTargetGenerator
+::AddChrpathPatchRule(std::ostream& os, Indent const& indent,
+ const char* config, std::string const& toDestDirPath)
+{
+ // Skip the chrpath if the target does not need it.
+ if(this->ImportLibrary || !this->Target->IsChrpathUsed(config))
+ {
+ return;
+ }
+
+ // Get the link information for this target.
+ // It can provide the RPATH.
+ cmComputeLinkInformation* cli = this->Target->GetLinkInformation(config);
+ if(!cli)
+ {
+ return;
+ }
+
+ // Construct the original rpath string to be replaced.
+ std::string oldRpath = cli->GetRPathString(false);
+
+ // Get the install RPATH from the link information.
+ std::string newRpath = cli->GetChrpathString();
+
+ // Skip the rule if the paths are identical
+ if(oldRpath == newRpath)
+ {
+ return;
+ }
+
+ // 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";
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmInstallTargetGenerator::AddStripRule(std::ostream& os,
+ Indent const& indent,
+ const std::string& toDestDirPath)
+{
+
+ // don't strip static 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)
+ {
+ return;
+ }
+
+ // Don't handle OSX Bundles.
+ if(this->Target->GetMakefile()->IsOn("APPLE") &&
+ this->Target->GetPropertyAsBool("MACOSX_BUNDLE"))
+ {
+ return;
+ }
+
+ if(! this->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")
+ << "\" \"" << toDestDirPath << "\")\n";
+ os << indent << "ENDIF(CMAKE_INSTALL_DO_STRIP)\n";
+}
+
+//----------------------------------------------------------------------------
+void
+cmInstallTargetGenerator::AddRanlibRule(std::ostream& os,
+ Indent const& indent,
+ const std::string& toDestDirPath)
+{
+ // Static libraries need ranlib on this platform.
+ if(this->Target->GetType() != cmTarget::STATIC_LIBRARY)
+ {
+ return;
+ }
+
+ // Perform post-installation processing on the file depending
+ // on its type.
+ if(!this->Target->GetMakefile()->IsOn("APPLE"))
+ {
+ return;
+ }
+
+ std::string ranlib =
+ this->Target->GetMakefile()->GetRequiredDefinition("CMAKE_RANLIB");
+ if(ranlib.empty())
+ {
+ return;
+ }
+
+ os << indent << "EXECUTE_PROCESS(COMMAND \""
+ << ranlib << "\" \"" << toDestDirPath << "\")\n";
+}
diff --git a/Source/cmInstallTargetGenerator.h b/Source/cmInstallTargetGenerator.h
new file mode 100644
index 000000000..b48d45661
--- /dev/null
+++ b/Source/cmInstallTargetGenerator.h
@@ -0,0 +1,102 @@
+/*============================================================================
+ 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 cmInstallTargetGenerator_h
+#define cmInstallTargetGenerator_h
+
+#include "cmInstallGenerator.h"
+#include "cmTarget.h"
+
+/** \class cmInstallTargetGenerator
+ * \brief Generate target installation rules.
+ */
+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
+ );
+ virtual ~cmInstallTargetGenerator();
+
+ /** Select the policy for installing shared library linkable name
+ symlinks. */
+ enum NamelinkModeType
+ {
+ NamelinkModeNone,
+ NamelinkModeOnly,
+ NamelinkModeSkip
+ };
+ void SetNamelinkMode(NamelinkModeType mode) { this->NamelinkMode = mode; }
+ NamelinkModeType GetNamelinkMode() const { return this->NamelinkMode; }
+
+ std::string GetInstallFilename(const char* config) const;
+
+ enum NameType
+ {
+ NameNormal,
+ NameImplib,
+ NameSO,
+ NameReal
+ };
+
+ static std::string GetInstallFilename(cmTarget*target, const char* config,
+ NameType nameType = NameNormal);
+
+ cmTarget* GetTarget() const { return this->Target; }
+ bool IsImportLibrary() const { return this->ImportLibrary; }
+
+protected:
+ virtual void GenerateScript(std::ostream& os);
+ virtual void GenerateScriptForConfig(std::ostream& os,
+ const char* config,
+ Indent const& indent);
+ typedef void (cmInstallTargetGenerator::*TweakMethod)(
+ std::ostream&, Indent const&, const char*, std::string const&
+ );
+ void AddTweak(std::ostream& os, Indent const& indent,
+ const char* config, std::string const& file,
+ TweakMethod tweak);
+ void AddTweak(std::ostream& os, Indent const& indent,
+ const char* 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);
+ void PostReplacementTweaks(std::ostream& os, Indent const& indent,
+ const char* config, std::string const& file);
+ void AddInstallNamePatchRule(std::ostream& os, Indent const& indent,
+ const char* config,
+ const std::string& toDestDirPath);
+ void AddChrpathPatchRule(std::ostream& os, Indent const& indent,
+ const char* config,
+ std::string const& toDestDirPath);
+ void AddRPathCheckRule(std::ostream& os, Indent const& indent,
+ const char* 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);
+
+ cmTarget* Target;
+ bool ImportLibrary;
+ std::string FilePermissions;
+ bool Optional;
+ NamelinkModeType NamelinkMode;
+};
+
+#endif
diff --git a/Source/cmInstallTargetsCommand.cxx b/Source/cmInstallTargetsCommand.cxx
new file mode 100644
index 000000000..277ccea43
--- /dev/null
+++ b/Source/cmInstallTargetsCommand.cxx
@@ -0,0 +1,66 @@
+/*============================================================================
+ 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 "cmInstallTargetsCommand.h"
+
+// cmExecutableCommand
+bool cmInstallTargetsCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 2 )
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ // Enable the install target.
+ this->Makefile->GetLocalGenerator()
+ ->GetGlobalGenerator()->EnableInstallTarget();
+
+ cmTargets &tgts = this->Makefile->GetTargets();
+ std::vector<std::string>::const_iterator s = args.begin();
+ ++s;
+ std::string runtime_dir = "/bin";
+ for (;s != args.end(); ++s)
+ {
+ if (*s == "RUNTIME_DIRECTORY")
+ {
+ ++s;
+ if ( s == args.end() )
+ {
+ this->SetError("called with RUNTIME_DIRECTORY but no actual "
+ "directory");
+ return false;
+ }
+
+ runtime_dir = *s;
+ }
+ else if (tgts.find(*s) != tgts.end())
+ {
+ tgts[*s].SetInstallPath(args[0].c_str());
+ tgts[*s].SetRuntimeInstallPath(runtime_dir.c_str());
+ tgts[*s].SetHaveInstallRule(true);
+ }
+ else
+ {
+ std::string str = "Cannot find target: \"" + *s + "\" to install.";
+ this->SetError(str.c_str());
+ return false;
+ }
+ }
+
+ this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
+ ->AddInstallComponent(this->Makefile->GetSafeDefinition(
+ "CMAKE_INSTALL_DEFAULT_COMPONENT_NAME"));
+
+ return true;
+}
+
diff --git a/Source/cmInstallTargetsCommand.h b/Source/cmInstallTargetsCommand.h
new file mode 100644
index 000000000..e05462faa
--- /dev/null
+++ b/Source/cmInstallTargetsCommand.h
@@ -0,0 +1,81 @@
+/*============================================================================
+ 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 cmInstallTargetsCommand_h
+#define cmInstallTargetsCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmInstallTargetsCommand
+ * \brief Specifies where to install some targets
+ *
+ * cmInstallTargetsCommand specifies the relative path where a list of
+ * targets should be installed. The targets can be executables or
+ * libraries.
+ */
+class cmInstallTargetsCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmInstallTargetsCommand;
+ }
+
+ /**
+ * 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 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;
+ }
+
+ cmTypeMacro(cmInstallTargetsCommand, cmCommand);
+};
+
+
+#endif
diff --git a/Source/cmInstallType.h b/Source/cmInstallType.h
new file mode 100644
index 000000000..a8373682c
--- /dev/null
+++ b/Source/cmInstallType.h
@@ -0,0 +1,29 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2012 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 cmInstallType_h
+#define cmInstallType_h
+
+/**
+ * Enumerate types known to file(INSTALL).
+ */
+enum cmInstallType
+{
+ cmInstallType_EXECUTABLE,
+ cmInstallType_STATIC_LIBRARY,
+ cmInstallType_SHARED_LIBRARY,
+ cmInstallType_MODULE_LIBRARY,
+ cmInstallType_FILES,
+ cmInstallType_PROGRAMS,
+ cmInstallType_DIRECTORY
+};
+
+#endif
diff --git a/Source/cmLinkDirectoriesCommand.cxx b/Source/cmLinkDirectoriesCommand.cxx
new file mode 100644
index 000000000..4412414a4
--- /dev/null
+++ b/Source/cmLinkDirectoriesCommand.cxx
@@ -0,0 +1,70 @@
+/*============================================================================
+ 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 "cmLinkDirectoriesCommand.h"
+
+// cmLinkDirectoriesCommand
+bool cmLinkDirectoriesCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 1 )
+ {
+ return true;
+ }
+
+ for(std::vector<std::string>::const_iterator i = args.begin();
+ i != args.end(); ++i)
+ {
+ this->AddLinkDir(*i);
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+void cmLinkDirectoriesCommand::AddLinkDir(std::string const& dir)
+{
+ std::string unixPath = dir;
+ cmSystemTools::ConvertToUnixSlashes(unixPath);
+ if(!cmSystemTools::FileIsFullPath(unixPath.c_str()))
+ {
+ bool convertToAbsolute = false;
+ cmOStringStream 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);
+ 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);
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ case cmPolicies::NEW:
+ // NEW behavior converts
+ convertToAbsolute = true;
+ break;
+ }
+ if (convertToAbsolute)
+ {
+ std::string tmp = this->Makefile->GetStartDirectory();
+ tmp += "/";
+ tmp += unixPath;
+ unixPath = tmp;
+ }
+ }
+ this->Makefile->AddLinkDirectory(unixPath.c_str());
+}
diff --git a/Source/cmLinkDirectoriesCommand.h b/Source/cmLinkDirectoriesCommand.h
new file mode 100644
index 000000000..a7cd58340
--- /dev/null
+++ b/Source/cmLinkDirectoriesCommand.h
@@ -0,0 +1,84 @@
+/*============================================================================
+ 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 cmLinkDirectoriesCommand_h
+#define cmLinkDirectoriesCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmLinkDirectoriesCommand
+ * \brief Define a list of directories containing files to link.
+ *
+ * cmLinkDirectoriesCommand is used to specify a list
+ * of directories containing files to link into executable(s).
+ * Note that the command supports the use of CMake built-in variables
+ * such as CMAKE_BINARY_DIR and CMAKE_SOURCE_DIR.
+ */
+class cmLinkDirectoriesCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmLinkDirectoriesCommand;
+ }
+
+ /**
+ * 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 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. "
+ "For historical reasons, relative paths given to this command are "
+ "passed to the linker unchanged "
+ "(unlike many CMake commands which interpret them relative to the "
+ "current source directory).\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."
+ ;
+ }
+
+ cmTypeMacro(cmLinkDirectoriesCommand, cmCommand);
+private:
+ void AddLinkDir(std::string const& dir);
+};
+
+
+
+#endif
diff --git a/Source/cmLinkLibrariesCommand.cxx b/Source/cmLinkLibrariesCommand.cxx
new file mode 100644
index 000000000..c4458aa6a
--- /dev/null
+++ b/Source/cmLinkLibrariesCommand.cxx
@@ -0,0 +1,59 @@
+/*============================================================================
+ 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 "cmLinkLibrariesCommand.h"
+
+// cmLinkLibrariesCommand
+bool cmLinkLibrariesCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 1 )
+ {
+ return true;
+ }
+ // add libraries, nothe that there is an optional prefix
+ // of debug and optimized than can be used
+ for(std::vector<std::string>::const_iterator i = args.begin();
+ i != args.end(); ++i)
+ {
+ if (*i == "debug")
+ {
+ ++i;
+ if(i == args.end())
+ {
+ this->SetError("The \"debug\" argument must be followed by "
+ "a library");
+ return false;
+ }
+ this->Makefile->AddLinkLibrary(i->c_str(),
+ cmTarget::DEBUG);
+ }
+ else if (*i == "optimized")
+ {
+ ++i;
+ if(i == args.end())
+ {
+ this->SetError("The \"optimized\" argument must be followed by "
+ "a library");
+ return false;
+ }
+ this->Makefile->AddLinkLibrary(i->c_str(),
+ cmTarget::OPTIMIZED);
+ }
+ else
+ {
+ this->Makefile->AddLinkLibrary(i->c_str());
+ }
+ }
+
+ return true;
+}
+
diff --git a/Source/cmLinkLibrariesCommand.h b/Source/cmLinkLibrariesCommand.h
new file mode 100644
index 000000000..2c0212cef
--- /dev/null
+++ b/Source/cmLinkLibrariesCommand.h
@@ -0,0 +1,83 @@
+/*============================================================================
+ 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 cmLinkLibrariesCommand_h
+#define cmLinkLibrariesCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmLinkLibrariesCommand
+ * \brief Specify a list of libraries to link into executables.
+ *
+ * cmLinkLibrariesCommand is used to specify a list of libraries to link
+ * into executable(s) or shared objects. The names of the libraries
+ * should be those defined by the LIBRARY(library) command(s).
+ */
+class cmLinkLibrariesCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmLinkLibrariesCommand;
+ }
+
+ /**
+ * 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 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;
+ }
+
+ cmTypeMacro(cmLinkLibrariesCommand, cmCommand);
+};
+
+
+
+#endif
diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx
new file mode 100644
index 000000000..908f3b060
--- /dev/null
+++ b/Source/cmListCommand.cxx
@@ -0,0 +1,608 @@
+/*============================================================================
+ 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 "cmListCommand.h"
+#include <cmsys/RegularExpression.hxx>
+#include <cmsys/SystemTools.hxx>
+
+#include <stdlib.h> // required for atoi
+#include <ctype.h>
+//----------------------------------------------------------------------------
+bool cmListCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 1)
+ {
+ this->SetError("must be called with at least one argument.");
+ return false;
+ }
+
+ const std::string &subCommand = args[0];
+ if(subCommand == "LENGTH")
+ {
+ return this->HandleLengthCommand(args);
+ }
+ if(subCommand == "GET")
+ {
+ return this->HandleGetCommand(args);
+ }
+ if(subCommand == "APPEND")
+ {
+ return this->HandleAppendCommand(args);
+ }
+ if(subCommand == "FIND")
+ {
+ return this->HandleFindCommand(args);
+ }
+ if(subCommand == "INSERT")
+ {
+ return this->HandleInsertCommand(args);
+ }
+ if(subCommand == "REMOVE_AT")
+ {
+ return this->HandleRemoveAtCommand(args);
+ }
+ if(subCommand == "REMOVE_ITEM")
+ {
+ return this->HandleRemoveItemCommand(args);
+ }
+ if(subCommand == "REMOVE_DUPLICATES")
+ {
+ return this->HandleRemoveDuplicatesCommand(args);
+ }
+ if(subCommand == "SORT")
+ {
+ return this->HandleSortCommand(args);
+ }
+ if(subCommand == "REVERSE")
+ {
+ return this->HandleReverseCommand(args);
+ }
+
+ std::string e = "does not recognize sub-command "+subCommand;
+ this->SetError(e.c_str());
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmListCommand::GetListString(std::string& listString, const char* var)
+{
+ if ( !var )
+ {
+ return false;
+ }
+ // get the old value
+ const char* cacheValue
+ = this->Makefile->GetDefinition(var);
+ if(!cacheValue)
+ {
+ return false;
+ }
+ listString = cacheValue;
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmListCommand::GetList(std::vector<std::string>& list, const char* var)
+{
+ std::string listString;
+ if ( !this->GetListString(listString, var) )
+ {
+ return false;
+ }
+ // if the size of the list
+ if(listString.size() == 0)
+ {
+ 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)
+ {
+ return true;
+ }
+ // if we have empty elements we need to check policy CMP0007
+ switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0007))
+ {
+ case cmPolicies::WARN:
+ {
+ // Default is to warn and use old behavior
+ // OLD behavior is to allow compatibility, so recall
+ // ExpandListArgument without the true which will remove
+ // empty values
+ list.clear();
+ cmSystemTools::ExpandListArgument(listString, list);
+ std::string warn = this->Makefile->GetPolicies()->
+ GetPolicyWarning(cmPolicies::CMP0007);
+ warn += " List has value = [";
+ warn += listString;
+ warn += "].";
+ this->Makefile->IssueMessage(cmake::AUTHOR_WARNING,
+ warn);
+ return true;
+ }
+ case cmPolicies::OLD:
+ // OLD behavior is to allow compatibility, so recall
+ // ExpandListArgument without the true which will remove
+ // empty values
+ list.clear();
+ cmSystemTools::ExpandListArgument(listString, list);
+ return true;
+ case cmPolicies::NEW:
+ return true;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ this->Makefile->IssueMessage(
+ cmake::FATAL_ERROR,
+ this->Makefile->GetPolicies()
+ ->GetRequiredPolicyError(cmPolicies::CMP0007)
+ );
+ return false;
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmListCommand::HandleLengthCommand(std::vector<std::string> const& args)
+{
+ if(args.size() != 3)
+ {
+ this->SetError("sub-command LENGTH requires two arguments.");
+ return false;
+ }
+
+ const std::string& listName = args[1];
+ const std::string& variableName = args[args.size() - 1];
+ std::vector<std::string> varArgsExpanded;
+ // 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());
+ size_t length = varArgsExpanded.size();
+ char buffer[1024];
+ sprintf(buffer, "%d", static_cast<int>(length));
+
+ this->Makefile->AddDefinition(variableName.c_str(), buffer);
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmListCommand::HandleGetCommand(std::vector<std::string> const& args)
+{
+ if(args.size() < 4)
+ {
+ this->SetError("sub-command GET requires at least three arguments.");
+ return false;
+ }
+
+ const std::string& listName = args[1];
+ const std::string& variableName = args[args.size() - 1];
+ // expand the variable
+ std::vector<std::string> varArgsExpanded;
+ if ( !this->GetList(varArgsExpanded, listName.c_str()) )
+ {
+ this->Makefile->AddDefinition(variableName.c_str(), "NOTFOUND");
+ return true;
+ }
+ // FIXME: Add policy to make non-existing lists an error like empty lists.
+ if(varArgsExpanded.empty())
+ {
+ this->SetError("GET given empty list");
+ return false;
+ }
+
+ std::string value;
+ size_t cc;
+ const char* sep = "";
+ 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;
+ str << "index: " << item << " out of range (-"
+ << varArgsExpanded.size() << ", "
+ << varArgsExpanded.size()-1 << ")";
+ this->SetError(str.str().c_str());
+ return false;
+ }
+ value += varArgsExpanded[item];
+ }
+
+ this->Makefile->AddDefinition(variableName.c_str(), value.c_str());
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmListCommand::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& 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 )
+ {
+ if(listString.size())
+ {
+ listString += ";";
+ }
+ listString += args[cc];
+ }
+
+ this->Makefile->AddDefinition(listName.c_str(), listString.c_str());
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmListCommand::HandleFindCommand(std::vector<std::string> const& args)
+{
+ if(args.size() != 4)
+ {
+ this->SetError("sub-command FIND requires three arguments.");
+ return false;
+ }
+
+ const std::string& listName = args[1];
+ const std::string& variableName = args[args.size() - 1];
+ // expand the variable
+ std::vector<std::string> varArgsExpanded;
+ if ( !this->GetList(varArgsExpanded, listName.c_str()) )
+ {
+ this->Makefile->AddDefinition(variableName.c_str(), "-1");
+ return true;
+ }
+
+ std::vector<std::string>::iterator it;
+ unsigned int index = 0;
+ for ( it = varArgsExpanded.begin(); it != varArgsExpanded.end(); ++ it )
+ {
+ if ( *it == args[2] )
+ {
+ char indexString[32];
+ sprintf(indexString, "%d", index);
+ this->Makefile->AddDefinition(variableName.c_str(), indexString);
+ return true;
+ }
+ index++;
+ }
+
+ this->Makefile->AddDefinition(variableName.c_str(), "-1");
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmListCommand::HandleInsertCommand(std::vector<std::string> const& args)
+{
+ if(args.size() < 4)
+ {
+ this->SetError("sub-command INSERT requires at least three arguments.");
+ return false;
+ }
+
+ const std::string& listName = args[1];
+
+ // expand the variable
+ int item = atoi(args[2].c_str());
+ std::vector<std::string> varArgsExpanded;
+ if((!this->GetList(varArgsExpanded, listName.c_str())
+ || varArgsExpanded.empty()) && item != 0)
+ {
+ cmOStringStream str;
+ str << "index: " << item << " out of range (0, 0)";
+ this->SetError(str.str().c_str());
+ return false;
+ }
+
+ if ( varArgsExpanded.size() != 0 )
+ {
+ size_t nitem = varArgsExpanded.size();
+ if ( item < 0 )
+ {
+ item = (int)nitem + item;
+ }
+ if ( item < 0 || nitem <= (size_t)item )
+ {
+ cmOStringStream str;
+ str << "index: " << item << " out of range (-"
+ << varArgsExpanded.size() << ", "
+ << (varArgsExpanded.size() == 0?0:(varArgsExpanded.size()-1)) << ")";
+ this->SetError(str.str().c_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 = ";";
+ }
+
+ this->Makefile->AddDefinition(listName.c_str(), value.c_str());
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmListCommand
+::HandleRemoveItemCommand(std::vector<std::string> const& args)
+{
+ if(args.size() < 3)
+ {
+ this->SetError("sub-command REMOVE_ITEM requires two or more arguments.");
+ return false;
+ }
+
+ const std::string& listName = args[1];
+ // expand the variable
+ std::vector<std::string> varArgsExpanded;
+ if ( !this->GetList(varArgsExpanded, listName.c_str()) )
+ {
+ 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 = ";";
+ }
+
+ this->Makefile->AddDefinition(listName.c_str(), value.c_str());
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmListCommand
+::HandleReverseCommand(std::vector<std::string> const& args)
+{
+ if(args.size() < 2)
+ {
+ this->SetError("sub-command REVERSE requires a list as an argument.");
+ return false;
+ }
+
+ const std::string& listName = args[1];
+ // expand the variable
+ std::vector<std::string> varArgsExpanded;
+ if ( !this->GetList(varArgsExpanded, listName.c_str()) )
+ {
+ 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 = ";";
+ }
+
+ this->Makefile->AddDefinition(listName.c_str(), value.c_str());
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmListCommand
+::HandleRemoveDuplicatesCommand(std::vector<std::string> const& args)
+{
+ if(args.size() < 2)
+ {
+ this->SetError(
+ "sub-command REMOVE_DUPLICATES requires a list as an argument.");
+ return false;
+ }
+
+ const std::string& listName = args[1];
+ // expand the variable
+ std::vector<std::string> varArgsExpanded;
+ if ( !this->GetList(varArgsExpanded, listName.c_str()) )
+ {
+ 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 = ";";
+ }
+
+
+ this->Makefile->AddDefinition(listName.c_str(), value.c_str());
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmListCommand
+::HandleSortCommand(std::vector<std::string> const& args)
+{
+ if(args.size() < 2)
+ {
+ this->SetError("sub-command SORT requires a list as an argument.");
+ return false;
+ }
+
+ const std::string& listName = args[1];
+ // expand the variable
+ std::vector<std::string> varArgsExpanded;
+ if ( !this->GetList(varArgsExpanded, listName.c_str()) )
+ {
+ this->SetError("sub-command SORT requires list to be present.");
+ return false;
+ }
+
+ 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());
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmListCommand::HandleRemoveAtCommand(
+ std::vector<std::string> const& args)
+{
+ if(args.size() < 3)
+ {
+ this->SetError("sub-command REMOVE_AT requires at least "
+ "two arguments.");
+ return false;
+ }
+
+ const std::string& listName = args[1];
+ // expand the variable
+ std::vector<std::string> varArgsExpanded;
+ if ( !this->GetList(varArgsExpanded, listName.c_str()) )
+ {
+ this->SetError("sub-command REMOVE_AT requires list to be present.");
+ return false;
+ }
+ // FIXME: Add policy to make non-existing lists an error like empty lists.
+ if(varArgsExpanded.empty())
+ {
+ this->SetError("REMOVE_AT given empty list");
+ return false;
+ }
+
+ size_t cc;
+ std::vector<size_t> removed;
+ 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;
+ str << "index: " << item << " out of range (-"
+ << varArgsExpanded.size() << ", "
+ << varArgsExpanded.size()-1 << ")";
+ this->SetError(str.str().c_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;
+ }
+ }
+
+ if ( !found )
+ {
+ value += sep;
+ value += varArgsExpanded[cc];
+ sep = ";";
+ }
+ }
+
+ this->Makefile->AddDefinition(listName.c_str(), value.c_str());
+ return true;
+}
+
diff --git a/Source/cmListCommand.h b/Source/cmListCommand.h
new file mode 100644
index 000000000..f20aa8a8f
--- /dev/null
+++ b/Source/cmListCommand.h
@@ -0,0 +1,128 @@
+/*============================================================================
+ 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 cmListCommand_h
+#define cmListCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmListCommand
+ * \brief Common list operations
+ *
+ */
+class cmListCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmListCommand;
+ }
+
+ /**
+ * 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 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"
+ ;
+ }
+
+ cmTypeMacro(cmListCommand, cmCommand);
+protected:
+ bool HandleLengthCommand(std::vector<std::string> const& args);
+ bool HandleGetCommand(std::vector<std::string> const& args);
+ bool HandleAppendCommand(std::vector<std::string> const& args);
+ bool HandleFindCommand(std::vector<std::string> const& args);
+ bool HandleInsertCommand(std::vector<std::string> const& args);
+ bool HandleRemoveAtCommand(std::vector<std::string> const& args);
+ bool HandleRemoveItemCommand(std::vector<std::string> const& args);
+ bool HandleRemoveDuplicatesCommand(std::vector<std::string> const& args);
+ bool HandleSortCommand(std::vector<std::string> const& args);
+ 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);
+};
+
+
+#endif
diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx
new file mode 100644
index 000000000..84cb8fd83
--- /dev/null
+++ b/Source/cmListFileCache.cxx
@@ -0,0 +1,314 @@
+/*============================================================================
+ 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 "cmListFileCache.h"
+
+#include "cmListFileLexer.h"
+#include "cmSystemTools.h"
+#include "cmMakefile.h"
+#include "cmVersion.h"
+
+#include <cmsys/RegularExpression.hxx>
+
+#ifdef __BORLANDC__
+# pragma warn -8060 /* possibly incorrect assignment */
+#endif
+
+bool cmListFileCacheParseFunction(cmListFileLexer* lexer,
+ cmListFileFunction& function,
+ const char* filename);
+
+bool cmListFile::ParseFile(const char* filename,
+ bool topLevel,
+ cmMakefile *mf)
+{
+ if(!cmSystemTools::FileExists(filename))
+ {
+ return false;
+ }
+
+ // Create the scanner.
+ cmListFileLexer* lexer = cmListFileLexer_New();
+ if(!lexer)
+ {
+ cmSystemTools::Error("cmListFileCache: error allocating lexer ");
+ return false;
+ }
+
+ // Open the file.
+ if(!cmListFileLexer_SetFileName(lexer, filename))
+ {
+ cmListFileLexer_Delete(lexer);
+ cmSystemTools::Error("cmListFileCache: error can not open file ",
+ filename);
+ return false;
+ }
+
+ // Use a simple recursive-descent parser to process the token
+ // stream.
+ this->ModifiedTime = cmSystemTools::ModifiedTime(filename);
+ bool parseError = false;
+ bool haveNewline = true;
+ cmListFileLexer_Token* token;
+ while(!parseError && (token = cmListFileLexer_Scan(lexer)))
+ {
+ if(token->type == cmListFileLexer_Token_Newline)
+ {
+ haveNewline = true;
+ }
+ else if(token->type == cmListFileLexer_Token_Identifier)
+ {
+ if(haveNewline)
+ {
+ haveNewline = false;
+ cmListFileFunction inFunction;
+ inFunction.Name = token->text;
+ inFunction.FilePath = filename;
+ inFunction.Line = token->line;
+ if(cmListFileCacheParseFunction(lexer, inFunction, filename))
+ {
+ this->Functions.push_back(inFunction);
+ }
+ else
+ {
+ parseError = true;
+ }
+ }
+ else
+ {
+ cmOStringStream error;
+ error << "Error in cmake code at\n"
+ << filename << ":" << token->line << ":\n"
+ << "Parse error. Expected a newline, got "
+ << cmListFileLexer_GetTypeAsString(lexer, token->type)
+ << " with text \"" << token->text << "\".";
+ cmSystemTools::Error(error.str().c_str());
+ parseError = true;
+ }
+ }
+ else
+ {
+ cmOStringStream error;
+ error << "Error in cmake code at\n"
+ << filename << ":" << token->line << ":\n"
+ << "Parse error. Expected a command name, got "
+ << cmListFileLexer_GetTypeAsString(lexer, token->type)
+ << " with text \""
+ << token->text << "\".";
+ cmSystemTools::Error(error.str().c_str());
+ parseError = true;
+ }
+ }
+ if (parseError)
+ {
+ this->ModifiedTime = 0;
+ }
+
+ cmListFileLexer_Delete(lexer);
+
+ // do we need a cmake_policy(VERSION call?
+ if(topLevel)
+ {
+ bool hasVersion = false;
+ // search for the right policy command
+ for(std::vector<cmListFileFunction>::iterator i
+ = this->Functions.begin();
+ i != this->Functions.end(); ++i)
+ {
+ if (cmSystemTools::LowerCase(i->Name) == "cmake_minimum_required")
+ {
+ hasVersion = true;
+ break;
+ }
+ }
+ // if no policy command is found this is an error if they use any
+ // non advanced functions or a lot of functions
+ if(!hasVersion)
+ {
+ bool isProblem = true;
+ if (this->Functions.size() < 30)
+ {
+ // the list of simple commands DO NOT ADD TO THIS LIST!!!!!
+ // these commands must have backwards compatibility forever and
+ // and that is a lot longer than your tiny mind can comprehend mortal
+ std::set<std::string> allowedCommands;
+ allowedCommands.insert("project");
+ allowedCommands.insert("set");
+ allowedCommands.insert("if");
+ allowedCommands.insert("endif");
+ allowedCommands.insert("else");
+ allowedCommands.insert("elseif");
+ allowedCommands.insert("add_executable");
+ allowedCommands.insert("add_library");
+ allowedCommands.insert("target_link_libraries");
+ allowedCommands.insert("option");
+ allowedCommands.insert("message");
+ isProblem = false;
+ for(std::vector<cmListFileFunction>::iterator i
+ = this->Functions.begin();
+ i != this->Functions.end(); ++i)
+ {
+ std::string name = cmSystemTools::LowerCase(i->Name);
+ if (allowedCommands.find(name) == allowedCommands.end())
+ {
+ isProblem = true;
+ break;
+ }
+ }
+ }
+
+ if (isProblem)
+ {
+ // Tell the top level cmMakefile to diagnose
+ // this violation of CMP0000.
+ mf->SetCheckCMP0000(true);
+
+ // Implicitly set the version for the user.
+ mf->SetPolicyVersion("2.4");
+ }
+ }
+ }
+
+ if(topLevel)
+ {
+ bool hasProject = false;
+ // search for a project command
+ for(std::vector<cmListFileFunction>::iterator i
+ = this->Functions.begin();
+ i != this->Functions.end(); ++i)
+ {
+ if(cmSystemTools::LowerCase(i->Name) == "project")
+ {
+ hasProject = true;
+ break;
+ }
+ }
+ // if no project command is found, add one
+ if(!hasProject)
+ {
+ cmListFileFunction project;
+ project.Name = "PROJECT";
+ cmListFileArgument prj("Project", false, filename, 0);
+ project.Arguments.push_back(prj);
+ this->Functions.insert(this->Functions.begin(),project);
+ }
+ }
+ if(parseError)
+ {
+ return false;
+ }
+ return true;
+}
+
+bool cmListFileCacheParseFunction(cmListFileLexer* lexer,
+ cmListFileFunction& function,
+ const char* filename)
+{
+ // Command name has already been parsed. Read the left paren.
+ cmListFileLexer_Token* token;
+ if(!(token = cmListFileLexer_Scan(lexer)))
+ {
+ cmOStringStream error;
+ error << "Error in cmake code at\n"
+ << filename << ":" << cmListFileLexer_GetCurrentLine(lexer) << ":\n"
+ << "Parse error. Function missing opening \"(\".";
+ cmSystemTools::Error(error.str().c_str());
+ return false;
+ }
+ if(token->type != cmListFileLexer_Token_ParenLeft)
+ {
+ cmOStringStream error;
+ error << "Error in cmake code at\n"
+ << filename << ":" << cmListFileLexer_GetCurrentLine(lexer) << ":\n"
+ << "Parse error. Expected \"(\", got "
+ << cmListFileLexer_GetTypeAsString(lexer, token->type)
+ << " with text \"" << token->text << "\".";
+ cmSystemTools::Error(error.str().c_str());
+ return false;
+ }
+
+ // Arguments.
+ unsigned long lastLine = cmListFileLexer_GetCurrentLine(lexer);
+ unsigned long parenDepth = 0;
+ while((token = cmListFileLexer_Scan(lexer)))
+ {
+ if(token->type == cmListFileLexer_Token_ParenLeft)
+ {
+ parenDepth++;
+ cmListFileArgument a("(",
+ false, filename, token->line);
+ function.Arguments.push_back(a);
+ }
+ else if(token->type == cmListFileLexer_Token_ParenRight)
+ {
+ if (parenDepth == 0)
+ {
+ return true;
+ }
+ parenDepth--;
+ cmListFileArgument a(")",
+ false, filename, token->line);
+ function.Arguments.push_back(a);
+ }
+ else if(token->type == cmListFileLexer_Token_Identifier ||
+ token->type == cmListFileLexer_Token_ArgumentUnquoted)
+ {
+ cmListFileArgument a(token->text,
+ false, filename, token->line);
+ function.Arguments.push_back(a);
+ }
+ else if(token->type == cmListFileLexer_Token_ArgumentQuoted)
+ {
+ cmListFileArgument a(token->text,
+ true, filename, token->line);
+ function.Arguments.push_back(a);
+ }
+ else if(token->type != cmListFileLexer_Token_Newline)
+ {
+ // Error.
+ cmOStringStream error;
+ error << "Error in cmake code at\n"
+ << filename << ":" << cmListFileLexer_GetCurrentLine(lexer)
+ << ":\n"
+ << "Parse error. Function missing ending \")\". "
+ << "Instead found "
+ << cmListFileLexer_GetTypeAsString(lexer, token->type)
+ << " with text \"" << token->text << "\".";
+ cmSystemTools::Error(error.str().c_str());
+ return false;
+ }
+ lastLine = cmListFileLexer_GetCurrentLine(lexer);
+ }
+
+ cmOStringStream error;
+ error << "Error in cmake code at\n"
+ << filename << ":" << lastLine << ":\n"
+ << "Parse error. Function missing ending \")\". "
+ << "End of file reached.";
+ cmSystemTools::Error(error.str().c_str());
+
+ return false;
+}
+
+//----------------------------------------------------------------------------
+std::ostream& operator<<(std::ostream& os, cmListFileContext const& lfc)
+{
+ os << lfc.FilePath;
+ if(lfc.Line)
+ {
+ os << ":" << lfc.Line;
+ if(!lfc.Name.empty())
+ {
+ os << " (" << lfc.Name << ")";
+ }
+ }
+ return os;
+}
diff --git a/Source/cmListFileCache.h b/Source/cmListFileCache.h
new file mode 100644
index 000000000..ec5886dbd
--- /dev/null
+++ b/Source/cmListFileCache.h
@@ -0,0 +1,79 @@
+/*============================================================================
+ 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 cmListFileCache_h
+#define cmListFileCache_h
+
+#include "cmStandardIncludes.h"
+
+/** \class cmListFileCache
+ * \brief A class to cache list file contents.
+ *
+ * cmListFileCache is a class used to cache the contents of parsed
+ * cmake list files.
+ */
+
+class cmMakefile;
+
+struct cmListFileArgument
+{
+ cmListFileArgument(): Value(), Quoted(false), FilePath(0), Line(0) {}
+ cmListFileArgument(const cmListFileArgument& r):
+ Value(r.Value), Quoted(r.Quoted), FilePath(r.FilePath), Line(r.Line) {}
+ cmListFileArgument(const std::string& v, bool q, const char* file,
+ long line): Value(v), Quoted(q),
+ FilePath(file), Line(line) {}
+ bool operator == (const cmListFileArgument& r) const
+ {
+ return (this->Value == r.Value) && (this->Quoted == r.Quoted);
+ }
+ bool operator != (const cmListFileArgument& r) const
+ {
+ return !(*this == r);
+ }
+ std::string Value;
+ bool Quoted;
+ const char* FilePath;
+ long Line;
+};
+
+struct cmListFileContext
+{
+ std::string Name;
+ std::string FilePath;
+ long Line;
+ cmListFileContext(): Name(), FilePath(), Line(0) {}
+};
+
+std::ostream& operator<<(std::ostream&, cmListFileContext const&);
+
+struct cmListFileFunction: public cmListFileContext
+{
+ std::vector<cmListFileArgument> Arguments;
+};
+
+class cmListFileBacktrace: public std::vector<cmListFileContext> {};
+
+struct cmListFile
+{
+ cmListFile()
+ :ModifiedTime(0)
+ {
+ }
+ bool ParseFile(const char* path,
+ bool topLevel,
+ cmMakefile *mf);
+
+ long int ModifiedTime;
+ std::vector<cmListFileFunction> Functions;
+};
+
+#endif
diff --git a/Source/cmListFileLexer.c b/Source/cmListFileLexer.c
new file mode 100644
index 000000000..df5dc2b65
--- /dev/null
+++ b/Source/cmListFileLexer.c
@@ -0,0 +1,2316 @@
+#line 2 "cmListFileLexer.c"
+
+#line 4 "cmListFileLexer.c"
+
+#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 31
+#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
+#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;
+#endif /* ! C99 */
+
+/* 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 /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_CONST
+
+#endif /* __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
+
+int cmListFileLexer_yylex_init (yyscan_t* scanner);
+
+/* 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 cmListFileLexer_yyrestart(yyin ,yyscanner )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#define YY_BUF_SIZE 16384
+#endif
+
+#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
+
+ /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires
+ * access to the local variable yy_act. Since yyless() is a macro, it would break
+ * existing scanners that call yyless() from OUTSIDE cmListFileLexer_yylex.
+ * One obvious solution it to make yy_act a global. I tried that, and saw
+ * a 5% performance hit in a non-yylineno scanner, because yy_act is
+ * normally declared as a register variable-- so it is not worth it.
+ */
+ #define YY_LESS_LINENO(n) \
+ do { \
+ int yyl;\
+ for ( yyl = n; yyl < yyleng; ++yyl )\
+ if ( yytext[yyl] == '\n' )\
+ --yylineno;\
+ }while(0)
+
+/* 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 )
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef unsigned int 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 cmListFileLexer_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 cmListFileLexer_yyrestart (FILE *input_file ,yyscan_t yyscanner );
+void cmListFileLexer_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+YY_BUFFER_STATE cmListFileLexer_yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
+void cmListFileLexer_yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void cmListFileLexer_yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void cmListFileLexer_yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+void cmListFileLexer_yypop_buffer_state (yyscan_t yyscanner );
+
+static void cmListFileLexer_yyensure_buffer_stack (yyscan_t yyscanner );
+static void cmListFileLexer_yy_load_buffer_state (yyscan_t yyscanner );
+static void cmListFileLexer_yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );
+
+#define YY_FLUSH_BUFFER cmListFileLexer_yy_flush_buffer(YY_CURRENT_BUFFER ,yyscanner)
+
+YY_BUFFER_STATE cmListFileLexer_yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
+YY_BUFFER_STATE cmListFileLexer_yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
+YY_BUFFER_STATE cmListFileLexer_yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
+
+void *cmListFileLexer_yyalloc (yy_size_t ,yyscan_t yyscanner );
+void *cmListFileLexer_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
+void cmListFileLexer_yyfree (void * ,yyscan_t yyscanner );
+
+#define yy_new_buffer cmListFileLexer_yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){ \
+ cmListFileLexer_yyensure_buffer_stack (yyscanner); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ cmListFileLexer_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 ){\
+ cmListFileLexer_yyensure_buffer_stack (yyscanner); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ cmListFileLexer_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 cmListFileLexer_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 14
+#define YY_END_OF_BUFFER 15
+/* 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[39] =
+ { 0,
+ 0, 0, 0, 0, 15, 6, 12, 1, 7, 2,
+ 6, 3, 4, 6, 13, 8, 9, 10, 11, 6,
+ 0, 6, 0, 2, 0, 5, 6, 8, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 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, 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,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 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[13] =
+ { 0,
+ 1, 1, 2, 1, 3, 1, 1, 1, 4, 4,
+ 4, 1
+ } ;
+
+static yyconst flex_int16_t yy_base[48] =
+ { 0,
+ 0, 0, 10, 20, 34, 32, 89, 89, 89, 0,
+ 23, 89, 89, 35, 0, 18, 89, 89, 44, 0,
+ 49, 21, 0, 0, 19, 0, 0, 15, 59, 0,
+ 18, 0, 15, 12, 11, 10, 9, 89, 64, 68,
+ 72, 76, 80, 13, 84, 12, 10
+ } ;
+
+static yyconst flex_int16_t yy_def[48] =
+ { 0,
+ 38, 1, 39, 39, 38, 38, 38, 38, 38, 40,
+ 6, 38, 38, 6, 41, 42, 38, 38, 42, 6,
+ 38, 6, 43, 40, 44, 14, 6, 42, 42, 21,
+ 21, 45, 46, 44, 47, 46, 47, 0, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38
+ } ;
+
+static yyconst flex_int16_t yy_nxt[102] =
+ { 0,
+ 6, 7, 8, 7, 9, 10, 11, 12, 13, 6,
+ 14, 15, 17, 37, 18, 36, 34, 30, 20, 30,
+ 27, 19, 17, 20, 18, 35, 29, 27, 33, 29,
+ 25, 19, 20, 38, 38, 38, 21, 38, 22, 38,
+ 38, 20, 20, 23, 26, 26, 28, 38, 28, 30,
+ 30, 38, 38, 20, 38, 31, 38, 38, 30, 30,
+ 32, 28, 38, 28, 16, 16, 16, 16, 24, 38,
+ 24, 24, 27, 38, 27, 27, 28, 38, 38, 28,
+ 20, 38, 20, 20, 30, 38, 30, 30, 5, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+
+ 38
+ } ;
+
+static yyconst flex_int16_t yy_chk[102] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 3, 47, 3, 46, 44, 37, 36, 35,
+ 34, 3, 4, 33, 4, 31, 28, 25, 22, 16,
+ 11, 4, 6, 5, 0, 0, 6, 0, 6, 0,
+ 0, 6, 6, 6, 14, 14, 19, 0, 19, 21,
+ 21, 0, 0, 21, 0, 21, 0, 0, 21, 21,
+ 21, 29, 0, 29, 39, 39, 39, 39, 40, 0,
+ 40, 40, 41, 0, 41, 41, 42, 0, 0, 42,
+ 43, 0, 43, 43, 45, 0, 45, 45, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+
+ 38
+ } ;
+
+/* Table of booleans, true if rule could match eol. */
+static yyconst flex_int32_t yy_rule_can_match_eol[15] =
+ { 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.
+ */
+#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 "cmListFileLexer.in.l"
+#line 2 "cmListFileLexer.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.
+============================================================================*/
+/*
+
+This file must be translated to C and modified to build everywhere.
+
+Run flex like this:
+
+ flex --prefix=cmListFileLexer_yy -ocmListFileLexer.c cmListFileLexer.in.l
+
+Modify cmListFileLexer.c:
+ - remove TABs
+ - remove the yyunput function
+ - add a statement "(void)yyscanner;" to the top of these methods:
+ yy_fatal_error, cmListFileLexer_yyalloc, cmListFileLexer_yyrealloc, cmListFileLexer_yyfree
+ - remove all YY_BREAK lines occurring right after return statements
+ - remove the isatty forward declaration
+
+*/
+
+#include "cmStandardLexer.h"
+
+/* Setup the proper cmListFileLexer_yylex declaration. */
+#define YY_EXTRA_TYPE cmListFileLexer*
+#define YY_DECL int cmListFileLexer_yylex (yyscan_t yyscanner, cmListFileLexer* lexer)
+
+#include "cmListFileLexer.h"
+
+/*--------------------------------------------------------------------------*/
+struct cmListFileLexer_s
+{
+ cmListFileLexer_Token token;
+ int line;
+ int column;
+ int size;
+ FILE* file;
+ char* string_buffer;
+ char* string_position;
+ int string_left;
+ yyscan_t scanner;
+};
+
+static void cmListFileLexerSetToken(cmListFileLexer* lexer, const char* text,
+ int length);
+static void cmListFileLexerAppend(cmListFileLexer* lexer, const char* text,
+ int length);
+static int cmListFileLexerInput(cmListFileLexer* lexer, char* buffer,
+ size_t bufferSize);
+static void cmListFileLexerInit(cmListFileLexer* lexer);
+static void cmListFileLexerDestroy(cmListFileLexer* lexer);
+
+/* Replace the lexer input function. */
+#undef YY_INPUT
+#define YY_INPUT(buf, result, max_size) \
+ { result = cmListFileLexerInput(cmListFileLexer_yyget_extra(yyscanner), buf, max_size); }
+
+/*--------------------------------------------------------------------------*/
+
+#line 568 "cmListFileLexer.c"
+
+#define INITIAL 0
+#define STRING 1
+
+#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 */
+
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int cmListFileLexer_yylex_destroy (yyscan_t yyscanner );
+
+int cmListFileLexer_yyget_debug (yyscan_t yyscanner );
+
+void cmListFileLexer_yyset_debug (int debug_flag ,yyscan_t yyscanner );
+
+YY_EXTRA_TYPE cmListFileLexer_yyget_extra (yyscan_t yyscanner );
+
+void cmListFileLexer_yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
+
+FILE *cmListFileLexer_yyget_in (yyscan_t yyscanner );
+
+void cmListFileLexer_yyset_in (FILE * in_str ,yyscan_t yyscanner );
+
+FILE *cmListFileLexer_yyget_out (yyscan_t yyscanner );
+
+void cmListFileLexer_yyset_out (FILE * out_str ,yyscan_t yyscanner );
+
+int cmListFileLexer_yyget_leng (yyscan_t yyscanner );
+
+char *cmListFileLexer_yyget_text (yyscan_t yyscanner );
+
+int cmListFileLexer_yyget_lineno (yyscan_t yyscanner );
+
+void cmListFileLexer_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 cmListFileLexer_yywrap (yyscan_t yyscanner );
+#else
+extern int cmListFileLexer_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
+
+#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
+#define YY_READ_BUF_SIZE 8192
+#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 (void) fwrite( yytext, yyleng, 1, yyout )
+#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 cmListFileLexer_yylex (yyscan_t yyscanner);
+
+#define YY_DECL int cmListFileLexer_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 \
+ YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp, *yy_bp;
+ register int yy_act;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+#line 100 "cmListFileLexer.in.l"
+
+
+#line 787 "cmListFileLexer.c"
+
+ if ( yyg->yy_init )
+ {
+ yyg->yy_init = 0;
+
+#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 ) {
+ cmListFileLexer_yyensure_buffer_stack (yyscanner);
+ YY_CURRENT_BUFFER_LVALUE =
+ cmListFileLexer_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+ }
+
+ cmListFileLexer_yy_load_buffer_state(yyscanner );
+ }
+
+ while ( 1 ) /* 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_match:
+ do
+ {
+ register 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 >= 39 )
+ 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] != 89 );
+
+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;
+
+ if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )
+ {
+ int yyl;
+ for ( yyl = 0; yyl < yyleng; ++yyl )
+ if ( yytext[yyl] == '\n' )
+
+ do{ yylineno++;
+ yycolumn=0;
+ }while(0)
+;
+ }
+
+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:
+/* rule 1 can match eol */
+YY_RULE_SETUP
+#line 102 "cmListFileLexer.in.l"
+{
+ lexer->token.type = cmListFileLexer_Token_Newline;
+ cmListFileLexerSetToken(lexer, yytext, yyleng);
+ ++lexer->line;
+ lexer->column = 1;
+ return 1;
+}
+case 2:
+YY_RULE_SETUP
+#line 110 "cmListFileLexer.in.l"
+{
+ lexer->column += yyleng;
+}
+ YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 114 "cmListFileLexer.in.l"
+{
+ lexer->token.type = cmListFileLexer_Token_ParenLeft;
+ cmListFileLexerSetToken(lexer, yytext, yyleng);
+ lexer->column += yyleng;
+ return 1;
+}
+case 4:
+YY_RULE_SETUP
+#line 121 "cmListFileLexer.in.l"
+{
+ lexer->token.type = cmListFileLexer_Token_ParenRight;
+ cmListFileLexerSetToken(lexer, yytext, yyleng);
+ lexer->column += yyleng;
+ return 1;
+}
+case 5:
+YY_RULE_SETUP
+#line 128 "cmListFileLexer.in.l"
+{
+ lexer->token.type = cmListFileLexer_Token_Identifier;
+ cmListFileLexerSetToken(lexer, yytext, yyleng);
+ lexer->column += yyleng;
+ return 1;
+}
+case 6:
+YY_RULE_SETUP
+#line 135 "cmListFileLexer.in.l"
+{
+ lexer->token.type = cmListFileLexer_Token_ArgumentUnquoted;
+ cmListFileLexerSetToken(lexer, yytext, yyleng);
+ lexer->column += yyleng;
+ return 1;
+}
+case 7:
+YY_RULE_SETUP
+#line 142 "cmListFileLexer.in.l"
+{
+ lexer->token.type = cmListFileLexer_Token_ArgumentQuoted;
+ cmListFileLexerSetToken(lexer, "", 0);
+ lexer->column += yyleng;
+ BEGIN(STRING);
+}
+ YY_BREAK
+case 8:
+/* rule 8 can match eol */
+YY_RULE_SETUP
+#line 149 "cmListFileLexer.in.l"
+{
+ cmListFileLexerAppend(lexer, yytext, yyleng);
+ lexer->column += yyleng;
+}
+ YY_BREAK
+case 9:
+/* rule 9 can match eol */
+YY_RULE_SETUP
+#line 154 "cmListFileLexer.in.l"
+{
+ cmListFileLexerAppend(lexer, yytext, yyleng);
+ ++lexer->line;
+ lexer->column = 1;
+}
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 160 "cmListFileLexer.in.l"
+{
+ lexer->column += yyleng;
+ BEGIN(INITIAL);
+ return 1;
+}
+case 11:
+YY_RULE_SETUP
+#line 166 "cmListFileLexer.in.l"
+{
+ cmListFileLexerAppend(lexer, yytext, yyleng);
+ lexer->column += yyleng;
+}
+ YY_BREAK
+case YY_STATE_EOF(STRING):
+#line 171 "cmListFileLexer.in.l"
+{
+ lexer->token.type = cmListFileLexer_Token_BadString;
+ BEGIN(INITIAL);
+ return 1;
+}
+case 12:
+YY_RULE_SETUP
+#line 177 "cmListFileLexer.in.l"
+{
+ lexer->column += yyleng;
+}
+ YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 181 "cmListFileLexer.in.l"
+{
+ lexer->token.type = cmListFileLexer_Token_BadCharacter;
+ cmListFileLexerSetToken(lexer, yytext, yyleng);
+ lexer->column += yyleng;
+ return 1;
+}
+case YY_STATE_EOF(INITIAL):
+#line 188 "cmListFileLexer.in.l"
+{
+ lexer->token.type = cmListFileLexer_Token_None;
+ cmListFileLexerSetToken(lexer, 0, 0);
+ return 0;
+}
+case 14:
+YY_RULE_SETUP
+#line 194 "cmListFileLexer.in.l"
+ECHO;
+ YY_BREAK
+#line 1025 "cmListFileLexer.c"
+
+ 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
+ * cmListFileLexer_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 ( cmListFileLexer_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 cmListFileLexer_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;
+ register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ register char *source = yyg->yytext_ptr;
+ register 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
+ {
+ 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;
+
+ 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. */
+ cmListFileLexer_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;
+ cmListFileLexer_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;
+
+ 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)
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ yy_current_state = yyg->yy_start;
+
+ for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp )
+ {
+ register 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 >= 39 )
+ 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)
+{
+ register int yy_is_jam;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ register char *yy_cp = yyg->yy_c_buf_p;
+
+ register 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 >= 39 )
+ 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 == 38);
+
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+#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. */
+ cmListFileLexer_yyrestart(yyin ,yyscanner);
+
+ /*FALLTHROUGH*/
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( cmListFileLexer_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;
+
+ if ( c == '\n' )
+
+ do{ yylineno++;
+ yycolumn=0;
+ }while(0)
+;
+
+ 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 cmListFileLexer_yyrestart (FILE * input_file , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if ( ! YY_CURRENT_BUFFER ){
+ cmListFileLexer_yyensure_buffer_stack (yyscanner);
+ YY_CURRENT_BUFFER_LVALUE =
+ cmListFileLexer_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+ }
+
+ cmListFileLexer_yy_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner);
+ cmListFileLexer_yy_load_buffer_state(yyscanner );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ * @param yyscanner The scanner object.
+ */
+ void cmListFileLexer_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
+ * cmListFileLexer_yypop_buffer_state();
+ * cmListFileLexer_yypush_buffer_state(new_buffer);
+ */
+ cmListFileLexer_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;
+ cmListFileLexer_yy_load_buffer_state(yyscanner );
+
+ /* We don't actually know whether we did this switch during
+ * EOF (cmListFileLexer_yywrap()) processing, but the only time this flag
+ * is looked at is after cmListFileLexer_yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ yyg->yy_did_buffer_switch_on_eof = 1;
+}
+
+static void cmListFileLexer_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 cmListFileLexer_yy_create_buffer (FILE * file, int size , yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) cmListFileLexer_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in cmListFileLexer_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 *) cmListFileLexer_yyalloc(b->yy_buf_size + 2 ,yyscanner );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in cmListFileLexer_yy_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ cmListFileLexer_yy_init_buffer(b,file ,yyscanner);
+
+ return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with cmListFileLexer_yy_create_buffer()
+ * @param yyscanner The scanner object.
+ */
+ void cmListFileLexer_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 )
+ cmListFileLexer_yyfree((void *) b->yy_ch_buf ,yyscanner );
+
+ cmListFileLexer_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 cmListFileLexer_yyrestart() or at EOF.
+ */
+ static void cmListFileLexer_yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner)
+
+{
+ int oerrno = errno;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ cmListFileLexer_yy_flush_buffer(b ,yyscanner);
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then cmListFileLexer_yy_init_buffer was _probably_
+ * called from cmListFileLexer_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 cmListFileLexer_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 )
+ cmListFileLexer_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 cmListFileLexer_yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if (new_buffer == NULL)
+ return;
+
+ cmListFileLexer_yyensure_buffer_stack(yyscanner);
+
+ /* This block is copied from cmListFileLexer_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 cmListFileLexer_yy_switch_to_buffer. */
+ cmListFileLexer_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 cmListFileLexer_yypop_buffer_state (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ cmListFileLexer_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) {
+ cmListFileLexer_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 cmListFileLexer_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**)cmListFileLexer_yyalloc
+ (num_to_alloc * sizeof(struct yy_buffer_state*)
+ , yyscanner);
+
+ 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**)cmListFileLexer_yyrealloc
+ (yyg->yy_buffer_stack,
+ num_to_alloc * sizeof(struct yy_buffer_state*)
+ , yyscanner);
+
+ /* 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 cmListFileLexer_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) cmListFileLexer_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in cmListFileLexer_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;
+
+ cmListFileLexer_yy_switch_to_buffer(b ,yyscanner );
+
+ return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to cmListFileLexer_yylex() will
+ * scan from a @e copy of @a str.
+ * @param str 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
+ * cmListFileLexer_yy_scan_bytes() instead.
+ */
+YY_BUFFER_STATE cmListFileLexer_yy_scan_string (yyconst char * yy_str , yyscan_t yyscanner)
+{
+
+ return cmListFileLexer_yy_scan_bytes(yy_str,strlen(yy_str) ,yyscanner);
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to cmListFileLexer_yylex() will
+ * scan from a @e copy of @a bytes.
+ * @param bytes the byte buffer to scan
+ * @param 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 cmListFileLexer_yy_scan_bytes (yyconst char * bytes, int 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 = len + 2;
+ buf = (char *) cmListFileLexer_yyalloc(n ,yyscanner );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in cmListFileLexer_yy_scan_bytes()" );
+
+ for ( i = 0; i < len; ++i )
+ buf[i] = bytes[i];
+
+ buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = cmListFileLexer_yy_scan_buffer(buf,n ,yyscanner);
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in cmListFileLexer_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 yyscanner)
+{
+ (void)yyscanner;
+ (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 cmListFileLexer_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 cmListFileLexer_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 cmListFileLexer_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 *cmListFileLexer_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 *cmListFileLexer_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 cmListFileLexer_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 *cmListFileLexer_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 cmListFileLexer_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 cmListFileLexer_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( "cmListFileLexer_yyset_lineno called with no buffer" , yyscanner);
+
+ yylineno = line_number;
+}
+
+/** Set the current column.
+ * @param line_number
+ * @param yyscanner The scanner object.
+ */
+void cmListFileLexer_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( "cmListFileLexer_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 cmListFileLexer_yy_switch_to_buffer
+ */
+void cmListFileLexer_yyset_in (FILE * in_str , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyin = in_str ;
+}
+
+void cmListFileLexer_yyset_out (FILE * out_str , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyout = out_str ;
+}
+
+int cmListFileLexer_yyget_debug (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yy_flex_debug;
+}
+
+void cmListFileLexer_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 */
+
+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 once per scanner lifetime. */
+
+ 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 = 1;
+ yyg->yy_start = 0;
+ yyg->yy_start_stack_ptr = 0;
+ yyg->yy_start_stack_depth = 0;
+ yyg->yy_start_stack = (int *) 0;
+
+/* 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
+ * cmListFileLexer_yylex_init()
+ */
+ return 0;
+}
+
+/* User-visible API */
+
+/* cmListFileLexer_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 cmListFileLexer_yylex_init(yyscan_t* ptr_yy_globals)
+
+{
+ if (ptr_yy_globals == NULL){
+ errno = EINVAL;
+ return 1;
+ }
+
+ *ptr_yy_globals = (yyscan_t) cmListFileLexer_yyalloc ( sizeof( struct yyguts_t ), NULL );
+
+ if (*ptr_yy_globals == NULL){
+ errno = ENOMEM;
+ return 1;
+ }
+
+ memset(*ptr_yy_globals,0,sizeof(struct yyguts_t));
+
+ return yy_init_globals ( *ptr_yy_globals );
+}
+
+/* cmListFileLexer_yylex_destroy is for both reentrant and non-reentrant scanners. */
+int cmListFileLexer_yylex_destroy (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* Pop the buffer stack, destroying each element. */
+ while(YY_CURRENT_BUFFER){
+ cmListFileLexer_yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ cmListFileLexer_yypop_buffer_state(yyscanner);
+ }
+
+ /* Destroy the stack itself. */
+ cmListFileLexer_yyfree(yyg->yy_buffer_stack ,yyscanner);
+ yyg->yy_buffer_stack = NULL;
+
+ /* Destroy the start condition stack. */
+ cmListFileLexer_yyfree(yyg->yy_start_stack ,yyscanner );
+ yyg->yy_start_stack = NULL;
+
+ /* Destroy the main struct (reentrant only). */
+ cmListFileLexer_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)
+{
+ register int i;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ 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)
+{
+ register int n;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+}
+#endif
+
+void *cmListFileLexer_yyalloc (yy_size_t size , yyscan_t yyscanner)
+{
+ (void)yyscanner;
+ return (void *) malloc( size );
+}
+
+void *cmListFileLexer_yyrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner)
+{
+ /* 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.
+ */
+ (void)yyscanner;
+ return (void *) realloc( (char *) ptr, size );
+}
+
+void cmListFileLexer_yyfree (void * ptr , yyscan_t yyscanner)
+{
+ (void)yyscanner;
+ free( (char *) ptr ); /* see cmListFileLexer_yyrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#undef YY_NEW_FILE
+#undef YY_FLUSH_BUFFER
+#undef yy_set_bol
+#undef yy_new_buffer
+#undef yy_set_interactive
+#undef yytext_ptr
+#undef YY_DO_BEFORE_ACTION
+
+#ifdef YY_DECL_IS_OURS
+#undef YY_DECL_IS_OURS
+#undef YY_DECL
+#endif
+#line 194 "cmListFileLexer.in.l"
+
+
+
+/*--------------------------------------------------------------------------*/
+static void cmListFileLexerSetToken(cmListFileLexer* lexer, const char* text,
+ int length)
+{
+ /* Set the token line and column number. */
+ lexer->token.line = lexer->line;
+ lexer->token.column = lexer->column;
+
+ /* Use the same buffer if possible. */
+ if(lexer->token.text)
+ {
+ if(text && length < lexer->size)
+ {
+ strcpy(lexer->token.text, text);
+ lexer->token.length = length;
+ return;
+ }
+ free(lexer->token.text);
+ lexer->token.text = 0;
+ lexer->size = 0;
+ }
+
+ /* Need to extend the buffer. */
+ if(text)
+ {
+ lexer->token.text = strdup(text);
+ lexer->token.length = length;
+ lexer->size = length+1;
+ }
+ else
+ {
+ lexer->token.length = 0;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+static void cmListFileLexerAppend(cmListFileLexer* lexer, const char* text,
+ int length)
+{
+ char* temp;
+ int newSize;
+
+ /* If the appended text will fit in the buffer, do not reallocate. */
+ newSize = lexer->token.length + length + 1;
+ if(lexer->token.text && newSize <= lexer->size)
+ {
+ strcpy(lexer->token.text+lexer->token.length, text);
+ lexer->token.length += length;
+ return;
+ }
+
+ /* We need to extend the buffer. */
+ temp = (char*)malloc(newSize);
+ if(lexer->token.text)
+ {
+ memcpy(temp, lexer->token.text, lexer->token.length);
+ free(lexer->token.text);
+ }
+ memcpy(temp+lexer->token.length, text, length);
+ temp[lexer->token.length+length] = 0;
+ lexer->token.text = temp;
+ lexer->token.length += length;
+ lexer->size = newSize;
+}
+
+/*--------------------------------------------------------------------------*/
+static int cmListFileLexerInput(cmListFileLexer* lexer, char* buffer,
+ size_t bufferSize)
+{
+ if(lexer)
+ {
+ if(lexer->file)
+ {
+ return (int)fread(buffer, 1, bufferSize, lexer->file);
+ }
+ else if(lexer->string_left)
+ {
+ int length = lexer->string_left;
+ if((int)bufferSize < length) { length = (int)bufferSize; }
+ memcpy(buffer, lexer->string_position, length);
+ lexer->string_position += length;
+ lexer->string_left -= length;
+ return length;
+ }
+ }
+ return 0;
+}
+
+/*--------------------------------------------------------------------------*/
+static void cmListFileLexerInit(cmListFileLexer* lexer)
+{
+ if(lexer->file || lexer->string_buffer)
+ {
+ cmListFileLexer_yylex_init(&lexer->scanner);
+ cmListFileLexer_yyset_extra(lexer, lexer->scanner);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+static void cmListFileLexerDestroy(cmListFileLexer* lexer)
+{
+ if(lexer->file || lexer->string_buffer)
+ {
+ cmListFileLexer_yylex_destroy(lexer->scanner);
+ if(lexer->file)
+ {
+ fclose(lexer->file);
+ lexer->file = 0;
+ }
+ if(lexer->string_buffer)
+ {
+ free(lexer->string_buffer);
+ lexer->string_buffer = 0;
+ lexer->string_left = 0;
+ lexer->string_position = 0;
+ }
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+cmListFileLexer* cmListFileLexer_New()
+{
+ cmListFileLexer* lexer = (cmListFileLexer*)malloc(sizeof(cmListFileLexer));
+ if(!lexer)
+ {
+ return 0;
+ }
+ memset(lexer, 0, sizeof(*lexer));
+ lexer->line = 1;
+ lexer->column = 1;
+ return lexer;
+}
+
+/*--------------------------------------------------------------------------*/
+void cmListFileLexer_Delete(cmListFileLexer* lexer)
+{
+ cmListFileLexer_SetFileName(lexer, 0);
+ free(lexer);
+}
+
+/*--------------------------------------------------------------------------*/
+int cmListFileLexer_SetFileName(cmListFileLexer* lexer, const char* name)
+{
+ int result = 1;
+ cmListFileLexerDestroy(lexer);
+ if(name)
+ {
+ lexer->file = fopen(name, "r");
+ if(!lexer->file)
+ {
+ result = 0;
+ }
+ }
+ cmListFileLexerInit(lexer);
+ return result;
+}
+
+/*--------------------------------------------------------------------------*/
+int cmListFileLexer_SetString(cmListFileLexer* lexer, const char* text)
+{
+ int result = 1;
+ cmListFileLexerDestroy(lexer);
+ if(text)
+ {
+ int length = (int)strlen(text);
+ lexer->string_buffer = (char*)malloc(length+1);
+ if(lexer->string_buffer)
+ {
+ strcpy(lexer->string_buffer, text);
+ lexer->string_position = lexer->string_buffer;
+ lexer->string_left = length;
+ }
+ else
+ {
+ result = 0;
+ }
+ }
+ cmListFileLexerInit(lexer);
+ return result;
+}
+
+/*--------------------------------------------------------------------------*/
+cmListFileLexer_Token* cmListFileLexer_Scan(cmListFileLexer* lexer)
+{
+ if(!lexer->file)
+ {
+ return 0;
+ }
+ if(cmListFileLexer_yylex(lexer->scanner, lexer))
+ {
+ return &lexer->token;
+ }
+ else
+ {
+ cmListFileLexer_SetFileName(lexer, 0);
+ return 0;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+long cmListFileLexer_GetCurrentLine(cmListFileLexer* lexer)
+{
+ if(lexer->file)
+ {
+ return lexer->line;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+long cmListFileLexer_GetCurrentColumn(cmListFileLexer* lexer)
+{
+ if(lexer->file)
+ {
+ return lexer->column;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+const char* cmListFileLexer_GetTypeAsString(cmListFileLexer* lexer,
+ cmListFileLexer_Type type)
+{
+ (void)lexer;
+ switch(type)
+ {
+ case cmListFileLexer_Token_None: return "nothing";
+ case cmListFileLexer_Token_Newline: return "newline";
+ case cmListFileLexer_Token_Identifier: return "identifier";
+ case cmListFileLexer_Token_ParenLeft: return "left paren";
+ case cmListFileLexer_Token_ParenRight: return "right paren";
+ case cmListFileLexer_Token_ArgumentUnquoted: return "unquoted argument";
+ case cmListFileLexer_Token_ArgumentQuoted: return "quoted argument";
+ case cmListFileLexer_Token_BadCharacter: return "bad character";
+ case cmListFileLexer_Token_BadString: return "unterminated string";
+ }
+ return "unknown token";
+}
diff --git a/Source/cmListFileLexer.h b/Source/cmListFileLexer.h
new file mode 100644
index 000000000..5f4db33c4
--- /dev/null
+++ b/Source/cmListFileLexer.h
@@ -0,0 +1,59 @@
+/*============================================================================
+ 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 cmListFileLexer_h
+#define cmListFileLexer_h
+
+typedef enum cmListFileLexer_Type_e
+{
+ cmListFileLexer_Token_None,
+ cmListFileLexer_Token_Newline,
+ cmListFileLexer_Token_Identifier,
+ cmListFileLexer_Token_ParenLeft,
+ cmListFileLexer_Token_ParenRight,
+ cmListFileLexer_Token_ArgumentUnquoted,
+ cmListFileLexer_Token_ArgumentQuoted,
+ cmListFileLexer_Token_BadCharacter,
+ cmListFileLexer_Token_BadString
+} cmListFileLexer_Type;
+
+typedef struct cmListFileLexer_Token_s cmListFileLexer_Token;
+struct cmListFileLexer_Token_s
+{
+ cmListFileLexer_Type type;
+ char* text;
+ int length;
+ int line;
+ int column;
+};
+
+typedef struct cmListFileLexer_s cmListFileLexer;
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+cmListFileLexer* cmListFileLexer_New();
+int cmListFileLexer_SetFileName(cmListFileLexer*, const char*);
+int cmListFileLexer_SetString(cmListFileLexer*, const char*);
+cmListFileLexer_Token* cmListFileLexer_Scan(cmListFileLexer*);
+long cmListFileLexer_GetCurrentLine(cmListFileLexer*);
+long cmListFileLexer_GetCurrentColumn(cmListFileLexer*);
+const char* cmListFileLexer_GetTypeAsString(cmListFileLexer*,
+ cmListFileLexer_Type);
+void cmListFileLexer_Delete(cmListFileLexer*);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif
diff --git a/Source/cmListFileLexer.in.l b/Source/cmListFileLexer.in.l
new file mode 100644
index 000000000..41e817b1a
--- /dev/null
+++ b/Source/cmListFileLexer.in.l
@@ -0,0 +1,417 @@
+%{
+/*============================================================================
+ 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.
+============================================================================*/
+/*
+
+This file must be translated to C and modified to build everywhere.
+
+Run flex like this:
+
+ flex --prefix=cmListFileLexer_yy -ocmListFileLexer.c cmListFileLexer.in.l
+
+Modify cmListFileLexer.c:
+ - remove TABs
+ - remove the yyunput function
+ - add a statement "(void)yyscanner;" to the top of these methods:
+ yy_fatal_error, cmListFileLexer_yyalloc, cmListFileLexer_yyrealloc, cmListFileLexer_yyfree
+ - remove all YY_BREAK lines occurring right after return statements
+ - remove the isatty forward declaration
+
+*/
+
+#include "cmStandardLexer.h"
+
+/* Setup the proper cmListFileLexer_yylex declaration. */
+#define YY_EXTRA_TYPE cmListFileLexer*
+#define YY_DECL int cmListFileLexer_yylex (yyscan_t yyscanner, cmListFileLexer* lexer)
+
+#include "cmListFileLexer.h"
+
+/*--------------------------------------------------------------------------*/
+struct cmListFileLexer_s
+{
+ cmListFileLexer_Token token;
+ int line;
+ int column;
+ int size;
+ FILE* file;
+ char* string_buffer;
+ char* string_position;
+ int string_left;
+ yyscan_t scanner;
+};
+
+static void cmListFileLexerSetToken(cmListFileLexer* lexer, const char* text,
+ int length);
+static void cmListFileLexerAppend(cmListFileLexer* lexer, const char* text,
+ int length);
+static int cmListFileLexerInput(cmListFileLexer* lexer, char* buffer,
+ size_t bufferSize);
+static void cmListFileLexerInit(cmListFileLexer* lexer);
+static void cmListFileLexerDestroy(cmListFileLexer* lexer);
+
+/* Replace the lexer input function. */
+#undef YY_INPUT
+#define YY_INPUT(buf, result, max_size) \
+ { result = cmListFileLexerInput(cmListFileLexer_yyget_extra(yyscanner), buf, max_size); }
+
+/*--------------------------------------------------------------------------*/
+%}
+
+%option reentrant
+%option yylineno
+%option noyywrap
+%pointer
+%x STRING
+
+MAKEVAR \$\([A-Za-z0-9_]*\)
+
+%%
+
+\n {
+ lexer->token.type = cmListFileLexer_Token_Newline;
+ cmListFileLexerSetToken(lexer, yytext, yyleng);
+ ++lexer->line;
+ lexer->column = 1;
+ return 1;
+}
+
+#.* {
+ lexer->column += yyleng;
+}
+
+\( {
+ lexer->token.type = cmListFileLexer_Token_ParenLeft;
+ cmListFileLexerSetToken(lexer, yytext, yyleng);
+ lexer->column += yyleng;
+ return 1;
+}
+
+\) {
+ lexer->token.type = cmListFileLexer_Token_ParenRight;
+ cmListFileLexerSetToken(lexer, yytext, yyleng);
+ lexer->column += yyleng;
+ return 1;
+}
+
+[A-Za-z_][A-Za-z0-9_]+ {
+ lexer->token.type = cmListFileLexer_Token_Identifier;
+ cmListFileLexerSetToken(lexer, yytext, yyleng);
+ lexer->column += yyleng;
+ return 1;
+}
+
+({MAKEVAR}|[^ \t\r\n\(\)#\\\"]|\\.)({MAKEVAR}|[^ \t\r\n\(\)#\\\"]|\\.|\"({MAKEVAR}|[^\r\n\(\)#\\\"]|\\.)*\")* {
+ lexer->token.type = cmListFileLexer_Token_ArgumentUnquoted;
+ cmListFileLexerSetToken(lexer, yytext, yyleng);
+ lexer->column += yyleng;
+ return 1;
+}
+
+\" {
+ lexer->token.type = cmListFileLexer_Token_ArgumentQuoted;
+ cmListFileLexerSetToken(lexer, "", 0);
+ lexer->column += yyleng;
+ BEGIN(STRING);
+}
+
+<STRING>([^\\\n\"]|\\(.|\n))+ {
+ cmListFileLexerAppend(lexer, yytext, yyleng);
+ lexer->column += yyleng;
+}
+
+<STRING>\n {
+ cmListFileLexerAppend(lexer, yytext, yyleng);
+ ++lexer->line;
+ lexer->column = 1;
+}
+
+<STRING>\" {
+ lexer->column += yyleng;
+ BEGIN(INITIAL);
+ return 1;
+}
+
+<STRING>. {
+ cmListFileLexerAppend(lexer, yytext, yyleng);
+ lexer->column += yyleng;
+}
+
+<STRING><<EOF>> {
+ lexer->token.type = cmListFileLexer_Token_BadString;
+ BEGIN(INITIAL);
+ return 1;
+}
+
+[ \t\r] {
+ lexer->column += yyleng;
+}
+
+. {
+ lexer->token.type = cmListFileLexer_Token_BadCharacter;
+ cmListFileLexerSetToken(lexer, yytext, yyleng);
+ lexer->column += yyleng;
+ return 1;
+}
+
+<<EOF>> {
+ lexer->token.type = cmListFileLexer_Token_None;
+ cmListFileLexerSetToken(lexer, 0, 0);
+ return 0;
+}
+
+%%
+
+/*--------------------------------------------------------------------------*/
+static void cmListFileLexerSetToken(cmListFileLexer* lexer, const char* text,
+ int length)
+{
+ /* Set the token line and column number. */
+ lexer->token.line = lexer->line;
+ lexer->token.column = lexer->column;
+
+ /* Use the same buffer if possible. */
+ if(lexer->token.text)
+ {
+ if(text && length < lexer->size)
+ {
+ strcpy(lexer->token.text, text);
+ lexer->token.length = length;
+ return;
+ }
+ free(lexer->token.text);
+ lexer->token.text = 0;
+ lexer->size = 0;
+ }
+
+ /* Need to extend the buffer. */
+ if(text)
+ {
+ lexer->token.text = strdup(text);
+ lexer->token.length = length;
+ lexer->size = length+1;
+ }
+ else
+ {
+ lexer->token.length = 0;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+static void cmListFileLexerAppend(cmListFileLexer* lexer, const char* text,
+ int length)
+{
+ char* temp;
+ int newSize;
+
+ /* If the appended text will fit in the buffer, do not reallocate. */
+ newSize = lexer->token.length + length + 1;
+ if(lexer->token.text && newSize <= lexer->size)
+ {
+ strcpy(lexer->token.text+lexer->token.length, text);
+ lexer->token.length += length;
+ return;
+ }
+
+ /* We need to extend the buffer. */
+ temp = malloc(newSize);
+ if(lexer->token.text)
+ {
+ memcpy(temp, lexer->token.text, lexer->token.length);
+ free(lexer->token.text);
+ }
+ memcpy(temp+lexer->token.length, text, length);
+ temp[lexer->token.length+length] = 0;
+ lexer->token.text = temp;
+ lexer->token.length += length;
+ lexer->size = newSize;
+}
+
+/*--------------------------------------------------------------------------*/
+static int cmListFileLexerInput(cmListFileLexer* lexer, char* buffer,
+ size_t bufferSize)
+{
+ if(lexer)
+ {
+ if(lexer->file)
+ {
+ return (int)fread(buffer, 1, bufferSize, lexer->file);
+ }
+ else if(lexer->string_left)
+ {
+ int length = lexer->string_left;
+ if((int)bufferSize < length) { length = (int)bufferSize; }
+ memcpy(buffer, lexer->string_position, length);
+ lexer->string_position += length;
+ lexer->string_left -= length;
+ return length;
+ }
+ }
+ return 0;
+}
+
+/*--------------------------------------------------------------------------*/
+static void cmListFileLexerInit(cmListFileLexer* lexer)
+{
+ if(lexer->file || lexer->string_buffer)
+ {
+ cmListFileLexer_yylex_init(&lexer->scanner);
+ cmListFileLexer_yyset_extra(lexer, lexer->scanner);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+static void cmListFileLexerDestroy(cmListFileLexer* lexer)
+{
+ if(lexer->file || lexer->string_buffer)
+ {
+ cmListFileLexer_yylex_destroy(lexer->scanner);
+ if(lexer->file)
+ {
+ fclose(lexer->file);
+ lexer->file = 0;
+ }
+ if(lexer->string_buffer)
+ {
+ free(lexer->string_buffer);
+ lexer->string_buffer = 0;
+ lexer->string_left = 0;
+ lexer->string_position = 0;
+ }
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+cmListFileLexer* cmListFileLexer_New()
+{
+ cmListFileLexer* lexer = (cmListFileLexer*)malloc(sizeof(cmListFileLexer));
+ if(!lexer)
+ {
+ return 0;
+ }
+ memset(lexer, 0, sizeof(*lexer));
+ lexer->line = 1;
+ lexer->column = 1;
+ return lexer;
+}
+
+/*--------------------------------------------------------------------------*/
+void cmListFileLexer_Delete(cmListFileLexer* lexer)
+{
+ cmListFileLexer_SetFileName(lexer, 0);
+ free(lexer);
+}
+
+/*--------------------------------------------------------------------------*/
+int cmListFileLexer_SetFileName(cmListFileLexer* lexer, const char* name)
+{
+ int result = 1;
+ cmListFileLexerDestroy(lexer);
+ if(name)
+ {
+ lexer->file = fopen(name, "r");
+ if(!lexer->file)
+ {
+ result = 0;
+ }
+ }
+ cmListFileLexerInit(lexer);
+ return result;
+}
+
+/*--------------------------------------------------------------------------*/
+int cmListFileLexer_SetString(cmListFileLexer* lexer, const char* text)
+{
+ int result = 1;
+ cmListFileLexerDestroy(lexer);
+ if(text)
+ {
+ int length = (int)strlen(text);
+ lexer->string_buffer = (char*)malloc(length+1);
+ if(lexer->string_buffer)
+ {
+ strcpy(lexer->string_buffer, text);
+ lexer->string_position = lexer->string_buffer;
+ lexer->string_left = length;
+ }
+ else
+ {
+ result = 0;
+ }
+ }
+ cmListFileLexerInit(lexer);
+ return result;
+}
+
+/*--------------------------------------------------------------------------*/
+cmListFileLexer_Token* cmListFileLexer_Scan(cmListFileLexer* lexer)
+{
+ if(!lexer->file)
+ {
+ return 0;
+ }
+ if(cmListFileLexer_yylex(lexer->scanner, lexer))
+ {
+ return &lexer->token;
+ }
+ else
+ {
+ cmListFileLexer_SetFileName(lexer, 0);
+ return 0;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+long cmListFileLexer_GetCurrentLine(cmListFileLexer* lexer)
+{
+ if(lexer->file)
+ {
+ return lexer->line;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+long cmListFileLexer_GetCurrentColumn(cmListFileLexer* lexer)
+{
+ if(lexer->file)
+ {
+ return lexer->column;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+const char* cmListFileLexer_GetTypeAsString(cmListFileLexer* lexer,
+ cmListFileLexer_Type type)
+{
+ (void)lexer;
+ switch(type)
+ {
+ case cmListFileLexer_Token_None: return "nothing";
+ case cmListFileLexer_Token_Newline: return "newline";
+ case cmListFileLexer_Token_Identifier: return "identifier";
+ case cmListFileLexer_Token_ParenLeft: return "left paren";
+ case cmListFileLexer_Token_ParenRight: return "right paren";
+ case cmListFileLexer_Token_ArgumentUnquoted: return "unquoted argument";
+ case cmListFileLexer_Token_ArgumentQuoted: return "quoted argument";
+ case cmListFileLexer_Token_BadCharacter: return "bad character";
+ case cmListFileLexer_Token_BadString: return "unterminated string";
+ }
+ return "unknown token";
+}
diff --git a/Source/cmLoadCacheCommand.cxx b/Source/cmLoadCacheCommand.cxx
new file mode 100644
index 000000000..a239e55bf
--- /dev/null
+++ b/Source/cmLoadCacheCommand.cxx
@@ -0,0 +1,196 @@
+/*============================================================================
+ 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 "cmLoadCacheCommand.h"
+
+#include <cmsys/RegularExpression.hxx>
+
+// cmLoadCacheCommand
+bool cmLoadCacheCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if (args.size()< 1)
+ {
+ this->SetError("called with wrong number of arguments.");
+ }
+
+ if(args.size() >= 2 && args[1] == "READ_WITH_PREFIX")
+ {
+ return this->ReadWithPrefix(args);
+ }
+
+ // Cache entries to be excluded from the import list.
+ // If this set is empty, all cache entries are brought in
+ // and they can not be overridden.
+ bool excludeFiles=false;
+ unsigned int i;
+ std::set<cmStdString> excludes;
+
+ for(i=0; i<args.size(); i++)
+ {
+ if (excludeFiles)
+ {
+ excludes.insert(args[i]);
+ }
+ if (args[i] == "EXCLUDE")
+ {
+ excludeFiles=true;
+ }
+ if (excludeFiles && (args[i] == "INCLUDE_INTERNALS"))
+ {
+ break;
+ }
+ }
+
+ // Internal cache entries to be imported.
+ // If this set is empty, no internal cache entries are
+ // brought in.
+ bool includeFiles=false;
+ std::set<cmStdString> includes;
+
+ for(i=0; i<args.size(); i++)
+ {
+ if (includeFiles)
+ {
+ includes.insert(args[i]);
+ }
+ if (args[i] == "INCLUDE_INTERNALS")
+ {
+ includeFiles=true;
+ }
+ if (includeFiles && (args[i] == "EXCLUDE"))
+ {
+ break;
+ }
+ }
+
+ // Loop over each build directory listed in the arguments. Each
+ // directory has a cache file.
+ for(i=0; i<args.size(); i++)
+ {
+ if ((args[i] == "EXCLUDE") || (args[i] == "INCLUDE_INTERNALS"))
+ {
+ break;
+ }
+ this->Makefile->GetCacheManager()->LoadCache(args[i].c_str(), false,
+ excludes, includes);
+ }
+
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmLoadCacheCommand::ReadWithPrefix(std::vector<std::string> const& args)
+{
+ // Make sure we have a prefix.
+ if(args.size() < 3)
+ {
+ this->SetError("READ_WITH_PREFIX form must specify a prefix.");
+ return false;
+ }
+
+ // Make sure the cache file exists.
+ std::string cacheFile = args[0]+"/CMakeCache.txt";
+ if(!cmSystemTools::FileExists(cacheFile.c_str()))
+ {
+ std::string e = "Cannot load cache file from " + cacheFile;
+ this->SetError(e.c_str());
+ 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]);
+ }
+
+ // Read the cache file.
+ std::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
+ // for small buffer sizes.
+ const int bufferSize = 4096;
+ char buffer[bufferSize];
+ std::string line;
+ while(fin)
+ {
+ // Read a block of the file.
+ fin.read(buffer, bufferSize);
+ if(fin.gcount())
+ {
+ // Parse for newlines directly.
+ const char* i = buffer;
+ const char* end = buffer+fin.gcount();
+ while(i != end)
+ {
+ const char* begin = i;
+ while(i != end && *i != '\n') { ++i; }
+ if(i == begin || *(i-1) != '\r')
+ {
+ // Include this portion of the line.
+ line += std::string(begin, i-begin);
+ }
+ else
+ {
+ // Include this portion of the line.
+ // Don't include the \r in a \r\n pair.
+ line += std::string(begin, i-1-begin);
+ }
+ if(i != end)
+ {
+ // Completed a line.
+ this->CheckLine(line.c_str());
+ line = "";
+
+ // Skip the newline character.
+ ++i;
+ }
+ }
+ }
+ }
+ if(line.length())
+ {
+ // Partial last line.
+ this->CheckLine(line.c_str());
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+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))
+ {
+ // Found a real entry. See if this one was requested.
+ if(this->VariablesToRead.find(var) != this->VariablesToRead.end())
+ {
+ // This was requested. Set this variable locally with the given
+ // prefix.
+ var = this->Prefix + var;
+ if(value.length())
+ {
+ this->Makefile->AddDefinition(var.c_str(), value.c_str());
+ }
+ else
+ {
+ this->Makefile->RemoveDefinition(var.c_str());
+ }
+ }
+ }
+}
diff --git a/Source/cmLoadCacheCommand.h b/Source/cmLoadCacheCommand.h
new file mode 100644
index 000000000..ac50f8d39
--- /dev/null
+++ b/Source/cmLoadCacheCommand.h
@@ -0,0 +1,89 @@
+/*============================================================================
+ 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 cmLoadCacheCommand_h
+#define cmLoadCacheCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmLoadCacheCommand
+ * \brief load a cache file
+ *
+ * cmLoadCacheCommand loads the non internal values of a cache file
+ */
+class cmLoadCacheCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmLoadCacheCommand;
+ }
+
+ /**
+ * 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 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.";
+ }
+
+ cmTypeMacro(cmLoadCacheCommand, cmCommand);
+protected:
+
+ std::set<cmStdString> VariablesToRead;
+ std::string Prefix;
+
+ bool ReadWithPrefix(std::vector<std::string> const& args);
+ void CheckLine(const char* line);
+};
+
+
+#endif
diff --git a/Source/cmLoadCommandCommand.cxx b/Source/cmLoadCommandCommand.cxx
new file mode 100644
index 000000000..3a0115c96
--- /dev/null
+++ b/Source/cmLoadCommandCommand.cxx
@@ -0,0 +1,315 @@
+/*============================================================================
+ 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 "cmLoadCommandCommand.h"
+#include "cmCPluginAPI.h"
+#include "cmCPluginAPI.cxx"
+#include "cmDynamicLoader.h"
+
+#include <cmsys/DynamicLoader.hxx>
+
+#include <stdlib.h>
+
+#ifdef __QNX__
+# include <malloc.h> /* for malloc/free on QNX */
+#endif
+
+#include <signal.h>
+extern "C" void TrapsForSignalsCFunction(int sig);
+
+
+// a class for loadabple commands
+class cmLoadedCommand : public cmCommand
+{
+public:
+ cmLoadedCommand() {
+ memset(&this->info,0,sizeof(this->info));
+ this->info.CAPI = &cmStaticCAPI;
+ }
+
+ ///! clean up any memory allocated by the plugin
+ ~cmLoadedCommand();
+
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ cmLoadedCommand *newC = new cmLoadedCommand;
+ // we must copy when we clone
+ memcpy(&newC->info,&this->info,sizeof(info));
+ return newC;
+ }
+
+ /**
+ * This is called when the command is first encountered in
+ * the CMakeLists.txt file.
+ */
+ virtual bool InitialPass(std::vector<std::string> const& args,
+ cmExecutionStatus &);
+
+ /**
+ * This is called at the end after all the information
+ * specified by the command is accumulated. Most commands do
+ * not implement this method. At this point, reading and
+ * writing to the cache can be done.
+ */
+ virtual void FinalPass();
+ virtual bool HasFinalPass() const
+ { return this->info.FinalPass? true:false; }
+
+ /**
+ * The name of the command as specified in CMakeList.txt.
+ */
+ virtual const char* 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)
+ {
+ fprintf(stderr, "CMake loaded command %s crashed with signal: %d.\n",
+ cmLoadedCommand::LastName, sig);
+ }
+ static void InstallSignalHandlers(const char* name, int remove = 0)
+ {
+ cmLoadedCommand::LastName = name;
+ if(!name)
+ {
+ cmLoadedCommand::LastName = "????";
+ }
+
+ if(!remove)
+ {
+ signal(SIGSEGV, TrapsForSignalsCFunction);
+#ifdef SIGBUS
+ signal(SIGBUS, TrapsForSignalsCFunction);
+#endif
+ signal(SIGILL, TrapsForSignalsCFunction);
+ }
+ else
+ {
+ signal(SIGSEGV, 0);
+#ifdef SIGBUS
+ signal(SIGBUS, 0);
+#endif
+ signal(SIGILL, 0);
+ }
+ }
+
+ /**
+ * 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;
+};
+
+extern "C" void TrapsForSignalsCFunction(int sig)
+{
+ cmLoadedCommand::TrapsForSignals(sig);
+}
+
+
+const char* cmLoadedCommand::LastName = 0;
+
+bool cmLoadedCommand::InitialPass(std::vector<std::string> const& args,
+ cmExecutionStatus &)
+{
+ if (!info.InitialPass)
+ {
+ return true;
+ }
+
+ // clear the error string
+ if (this->info.Error)
+ {
+ free(this->info.Error);
+ }
+
+ // create argc and argv and then invoke the command
+ int argc = static_cast<int> (args.size());
+ char **argv = 0;
+ if (argc)
+ {
+ argv = (char **)malloc(argc*sizeof(char *));
+ }
+ int i;
+ for (i = 0; i < argc; ++i)
+ {
+ argv[i] = strdup(args[i].c_str());
+ }
+ cmLoadedCommand::InstallSignalHandlers(info.Name);
+ int result = info.InitialPass((void *)&info,
+ (void *)this->Makefile,argc,argv);
+ cmLoadedCommand::InstallSignalHandlers(info.Name, 1);
+ cmFreeArguments(argc,argv);
+
+ if (result)
+ {
+ return true;
+ }
+
+ /* Initial Pass must have failed so set the error string */
+ if (this->info.Error)
+ {
+ this->SetError(this->info.Error);
+ }
+ return false;
+}
+
+void cmLoadedCommand::FinalPass()
+{
+ if (this->info.FinalPass)
+ {
+ cmLoadedCommand::InstallSignalHandlers(info.Name);
+ this->info.FinalPass((void *)&this->info,(void *)this->Makefile);
+ cmLoadedCommand::InstallSignalHandlers(info.Name, 1);
+ }
+}
+
+cmLoadedCommand::~cmLoadedCommand()
+{
+ if (this->info.Destructor)
+ {
+ cmLoadedCommand::InstallSignalHandlers(info.Name);
+ this->info.Destructor((void *)&this->info);
+ cmLoadedCommand::InstallSignalHandlers(info.Name, 1);
+ }
+ if (this->info.Error)
+ {
+ free(this->info.Error);
+ }
+}
+
+// cmLoadCommandCommand
+bool cmLoadCommandCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 1 )
+ {
+ return true;
+ }
+
+ // Construct a variable to report what file was loaded, if any.
+ // Start by removing the definition in case of failure.
+ std::string reportVar = "CMAKE_LOADED_COMMAND_";
+ reportVar += args[0];
+ this->Makefile->RemoveDefinition(reportVar.c_str());
+
+ // the file must exist
+ std::string moduleName =
+ this->Makefile->GetRequiredDefinition("CMAKE_SHARED_MODULE_PREFIX");
+ moduleName += "cm" + args[0];
+ moduleName +=
+ this->Makefile->GetRequiredDefinition("CMAKE_SHARED_MODULE_SUFFIX");
+
+ // search for the file
+ std::vector<std::string> path;
+ for (unsigned int j = 1; j < args.size(); j++)
+ {
+ // expand variables
+ std::string exp = args[j];
+ cmSystemTools::ExpandRegistryValues(exp);
+
+ // Glob the entry in case of wildcards.
+ cmSystemTools::GlobDirs(exp.c_str(), path);
+ }
+
+ // Try to find the program.
+ std::string fullPath = cmSystemTools::FindFile(moduleName.c_str(), path);
+ if (fullPath == "")
+ {
+ cmOStringStream e;
+ e << "Attempt to load command failed from file \""
+ << moduleName << "\"";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+
+ // try loading the shared library / dll
+ cmsys::DynamicLoader::LibraryHandle lib
+ = cmDynamicLoader::OpenLibrary(fullPath.c_str());
+ if(!lib)
+ {
+ std::string err = "Attempt to load the library ";
+ err += fullPath + " failed.";
+ const char* error = cmsys::DynamicLoader::LastError();
+ if ( error )
+ {
+ err += " Additional error info is:\n";
+ err += error;
+ }
+ this->SetError(err.c_str());
+ return false;
+ }
+
+ // Report what file was loaded for this command.
+ this->Makefile->AddDefinition(reportVar.c_str(), fullPath.c_str());
+
+ // find the init function
+ std::string initFuncName = args[0] + "Init";
+ CM_INIT_FUNCTION initFunction
+ = (CM_INIT_FUNCTION)
+ cmsys::DynamicLoader::GetSymbolAddress(lib, initFuncName.c_str());
+ if ( !initFunction )
+ {
+ initFuncName = "_";
+ initFuncName += args[0];
+ initFuncName += "Init";
+ initFunction = (CM_INIT_FUNCTION)(
+ cmsys::DynamicLoader::GetSymbolAddress(lib, initFuncName.c_str()));
+ }
+ // if the symbol is found call it to set the name on the
+ // function blocker
+ if(initFunction)
+ {
+ // create a function blocker and set it up
+ cmLoadedCommand *f = new cmLoadedCommand();
+ (*initFunction)(&f->info);
+ this->Makefile->AddCommand(f);
+ return true;
+ }
+ this->SetError("Attempt to load command failed. "
+ "No init function found.");
+ return false;
+}
+
diff --git a/Source/cmLoadCommandCommand.h b/Source/cmLoadCommandCommand.h
new file mode 100644
index 000000000..651701948
--- /dev/null
+++ b/Source/cmLoadCommandCommand.h
@@ -0,0 +1,75 @@
+/*============================================================================
+ 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 cmLoadCommandCommand_h
+#define cmLoadCommandCommand_h
+
+#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 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.";
+ }
+
+ cmTypeMacro(cmLoadCommandCommand, cmCommand);
+};
+
+
+
+#endif
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
new file mode 100644
index 000000000..0cfb36bc3
--- /dev/null
+++ b/Source/cmLocalGenerator.cxx
@@ -0,0 +1,3278 @@
+/*============================================================================
+ 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 "cmLocalGenerator.h"
+
+#include "cmComputeLinkInformation.h"
+#include "cmGeneratedFileStream.h"
+#include "cmGlobalGenerator.h"
+#include "cmInstallGenerator.h"
+#include "cmInstallFilesGenerator.h"
+#include "cmInstallScriptGenerator.h"
+#include "cmInstallTargetGenerator.h"
+#include "cmMakefile.h"
+#include "cmSourceFile.h"
+#include "cmTest.h"
+#include "cmTestGenerator.h"
+#include "cmVersion.h"
+#include "cmake.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>
+#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;
+ this->EmitUniversalBinaryFlags = true;
+ this->IsMakefileGenerator = false;
+ this->RelativePathsConfigured = false;
+ this->PathConversionsSetup = false;
+ this->BackwardsCompatibility = 0;
+ this->BackwardsCompatibilityFinal = false;
+}
+
+cmLocalGenerator::~cmLocalGenerator()
+{
+ delete this->Makefile;
+}
+
+//----------------------------------------------------------------------------
+class cmLocalGeneratorCurrent
+{
+ 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());
+
+ // 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 (!(*sdi)->Configured)
+ {
+ this->Makefile->ConfigureSubDirectory(*sdi);
+ }
+ }
+
+ // 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;
+}
+
+//----------------------------------------------------------------------------
+void cmLocalGenerator::ComputeObjectMaxPath()
+{
+ // Choose a maximum object file name length.
+#if defined(_WIN32) || defined(__CYGWIN__)
+ this->ObjectPathMax = 250;
+#else
+ this->ObjectPathMax = 1000;
+#endif
+ const char* plen = this->Makefile->GetDefinition("CMAKE_OBJECT_PATH_MAX");
+ if(plen && *plen)
+ {
+ unsigned int pmax;
+ if(sscanf(plen, "%u", &pmax) == 1)
+ {
+ if(pmax >= 128)
+ {
+ this->ObjectPathMax = pmax;
+ }
+ else
+ {
+ cmOStringStream 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());
+ }
+ }
+ else
+ {
+ cmOStringStream 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->ObjectMaxPathViolations.clear();
+}
+
+//----------------------------------------------------------------------------
+void cmLocalGenerator::ReadInputFile()
+{
+ // Look for the CMakeLists.txt file.
+ std::string currentStart = this->Makefile->GetStartDirectory();
+ currentStart += "/CMakeLists.txt";
+ if(cmSystemTools::FileExists(currentStart.c_str(), true))
+ {
+ this->Makefile->ReadListFile(currentStart.c_str());
+ return;
+ }
+
+ if(!this->Parent)
+ {
+ return;
+ }
+
+ // 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)
+ {
+ const char* projectFilename = 0;
+ if (this->IsMakefileGenerator == false) // only use of this variable
+ {
+ projectFilename = t->second.GetName();
+ }
+ t->second.TraceDependencies(projectFilename);
+ }
+}
+
+void cmLocalGenerator::GenerateTestFiles()
+{
+ if ( !this->Makefile->IsOn("CMAKE_TESTING_ENABLED") )
+ {
+ return;
+ }
+
+ // Compute the set of configurations.
+ std::vector<std::string> configurationTypes;
+ const char* config =
+ this->Makefile->GetConfigurations(configurationTypes, false);
+
+ std::string file = this->Makefile->GetStartOutputDirectory();
+ file += "/";
+ file += "CTestTestfile.cmake";
+
+ cmGeneratedFileStream fout(file.c_str());
+ fout.SetCopyIfDifferent(true);
+
+ fout << "# CMake generated Testfile for " << std::endl
+ << "# Source directory: "
+ << this->Makefile->GetStartDirectory() << std::endl
+ << "# Build directory: "
+ << this->Makefile->GetStartOutputDirectory() << std::endl
+ << "# " << std::endl
+ << "# This file includes the relevent testing commands "
+ << "required for " << std::endl
+ << "# testing this directory and lists subdirectories to "
+ << "be tested as well." << std::endl;
+
+ const char* testIncludeFile =
+ this->Makefile->GetProperty("TEST_INCLUDE_FILE");
+ if ( testIncludeFile )
+ {
+ fout << "INCLUDE(\"" << testIncludeFile << "\")" << std::endl;
+ }
+
+ // Ask each test generator to write its code.
+ std::vector<cmTestGenerator*> const&
+ testers = this->Makefile->GetTestGenerators();
+ for(std::vector<cmTestGenerator*>::const_iterator gi = testers.begin();
+ gi != testers.end(); ++gi)
+ {
+ (*gi)->Generate(fout, config, configurationTypes);
+ }
+ if ( this->Children.size())
+ {
+ size_t i;
+ for(i = 0; i < this->Children.size(); ++i)
+ {
+ fout << "SUBDIRS(";
+ std::string outP =
+ this->Children[i]->GetMakefile()->GetStartOutputDirectory();
+ fout << this->Convert(outP.c_str(),START_OUTPUT);
+ fout << ")" << std::endl;
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmLocalGenerator::GenerateInstallRules()
+{
+ // Compute the install prefix.
+ const char* prefix = this->Makefile->GetDefinition("CMAKE_INSTALL_PREFIX");
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ std::string prefix_win32;
+ if(!prefix)
+ {
+ if(!cmSystemTools::GetEnv("SystemDrive", prefix_win32))
+ {
+ prefix_win32 = "C:";
+ }
+ const char* project_name = this->Makefile->GetDefinition("PROJECT_NAME");
+ if(project_name && project_name[0])
+ {
+ prefix_win32 += "/Program Files/";
+ prefix_win32 += project_name;
+ }
+ else
+ {
+ prefix_win32 += "/InstalledCMakeProject";
+ }
+ prefix = prefix_win32.c_str();
+ }
+#elif defined(__HAIKU__)
+ if (!prefix)
+ {
+ BPath dir;
+ if (find_directory(B_COMMON_DIRECTORY, &dir) == B_OK)
+ {
+ prefix = dir.Path();
+ }
+ else
+ {
+ prefix = "/boot/common";
+ }
+ }
+#else
+ if (!prefix)
+ {
+ prefix = "/usr/local";
+ }
+#endif
+
+ // Compute the set of configurations.
+ std::vector<std::string> configurationTypes;
+ const char* config =
+ this->Makefile->GetConfigurations(configurationTypes, false);
+
+ // Choose a default install configuration.
+ const char* default_config = config;
+ const char* default_order[] = {"RELEASE", "MINSIZEREL",
+ "RELWITHDEBINFO", "DEBUG", 0};
+ for(const char** c = default_order; *c && !default_config; ++c)
+ {
+ for(std::vector<std::string>::iterator i = configurationTypes.begin();
+ i != configurationTypes.end(); ++i)
+ {
+ if(cmSystemTools::UpperCase(*i) == *c)
+ {
+ default_config = i->c_str();
+ }
+ }
+ }
+ if(!default_config && !configurationTypes.empty())
+ {
+ default_config = configurationTypes[0].c_str();
+ }
+ if(!default_config)
+ {
+ default_config = "Release";
+ }
+
+ // 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);
+ int toplevel_install = 0;
+ if ( currdir == homedir )
+ {
+ toplevel_install = 1;
+ }
+ file += "/cmake_install.cmake";
+ cmGeneratedFileStream fout(file.c_str());
+ fout.SetCopyIfDifferent(true);
+
+ // Write the header.
+ fout << "# Install script for directory: "
+ << this->Makefile->GetCurrentDirectory() << 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 "
+ << "\"${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"
+ " 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: "
+ "\\\"${CMAKE_INSTALL_CONFIG_NAME}\\\"\")\n"
+ "ENDIF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)\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"
+ "\n";
+
+ // Copy user-specified install options to the install code.
+ if(const char* so_no_exe =
+ this->Makefile->GetDefinition("CMAKE_INSTALL_SO_NO_EXE"))
+ {
+ 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"
+ "\n";
+ }
+
+ // Ask each install generator to write its code.
+ std::vector<cmInstallGenerator*> const& installers =
+ this->Makefile->GetInstallGenerators();
+ for(std::vector<cmInstallGenerator*>::const_iterator
+ gi = installers.begin();
+ gi != installers.end(); ++gi)
+ {
+ (*gi)->Generate(fout, config, configurationTypes);
+ }
+
+ // Write rules from old-style specification stored in targets.
+ this->GenerateTargetInstallRules(fout, config, configurationTypes);
+
+ // Include install scripts from subdirectories.
+ if(!this->Children.empty())
+ {
+ 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)
+ {
+ if(!(*ci)->GetMakefile()->GetPropertyAsBool("EXCLUDE_FROM_ALL"))
+ {
+ std::string odir = (*ci)->GetMakefile()->GetStartOutputDirectory();
+ cmSystemTools::ConvertToUnixSlashes(odir);
+ fout << " INCLUDE(\"" << odir.c_str()
+ << "/cmake_install.cmake\")" << std::endl;
+ }
+ }
+ fout << "\n";
+ fout << "ENDIF(NOT CMAKE_INSTALL_LOCAL_ONLY)\n\n";
+ }
+
+ // Record the install manifest.
+ if ( toplevel_install )
+ {
+ fout <<
+ "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;
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmLocalGenerator::GenerateTargetManifest()
+{
+ // Collect the set of configuration types.
+ std::vector<std::string> configNames;
+ this->Makefile->GetConfigurations(configNames);
+
+ // Add our targets to the manifest for each configuration.
+ cmTargets& targets = this->Makefile->GetTargets();
+ for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t)
+ {
+ cmTarget& target = t->second;
+ if(configNames.empty())
+ {
+ target.GenerateTargetManifest(0);
+ }
+ else
+ {
+ for(std::vector<std::string>::iterator ci = configNames.begin();
+ ci != configNames.end(); ++ci)
+ {
+ const char* config = ci->c_str();
+ target.GenerateTargetManifest(config);
+ }
+ }
+ }
+}
+
+void cmLocalGenerator::AddCustomCommandToCreateObject(const char* ofname,
+ const char* lang,
+ cmSourceFile& source,
+ cmTarget& 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, 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, cmTarget& 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.GetFullName();
+ // Executable :
+ // Shared Library:
+ // Static Library:
+ // Shared Module:
+ std::string linkLibs; // should be set
+ std::string flags; // should be set
+ std::string linkFlags; // should be set
+ this->GetTargetFlags(linkLibs, flags, linkFlags, target);
+ 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.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.AddSourceFile
+ (this->Makefile->GetSource(targetFullPath.c_str()));
+}
+
+
+void cmLocalGenerator
+::CreateCustomTargetsAndCommands(std::set<cmStdString> const& lang)
+{
+ cmTargets &tgts = this->Makefile->GetTargets();
+ for(cmTargets::iterator l = tgts.begin();
+ l != tgts.end(); l++)
+ {
+ cmTarget& 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.GetLinkerLanguage();
+ if(!llang)
+ {
+ cmSystemTools::Error
+ ("CMake can not determine linker language for 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;
+ }
+ }
+}
+
+// List of variables that are replaced when
+// rules are expanced. These variables are
+// replaced in the form <var> with GetSafeDefinition(var).
+// ${LANG} is replaced in the variable first with all enabled
+// languages.
+static const char* ruleReplaceVars[] =
+{
+ "CMAKE_${LANG}_COMPILER",
+ "CMAKE_SHARED_LIBRARY_CREATE_${LANG}_FLAGS",
+ "CMAKE_SHARED_MODULE_CREATE_${LANG}_FLAGS",
+ "CMAKE_SHARED_MODULE_${LANG}_FLAGS",
+ "CMAKE_SHARED_LIBRARY_${LANG}_FLAGS",
+ "CMAKE_${LANG}_LINK_FLAGS",
+ "CMAKE_SHARED_LIBRARY_SONAME_${LANG}_FLAG",
+ "CMAKE_${LANG}_ARCHIVE",
+ "CMAKE_AR",
+ "CMAKE_CURRENT_SOURCE_DIR",
+ "CMAKE_CURRENT_BINARY_DIR",
+ "CMAKE_RANLIB",
+ "CMAKE_LINKER",
+ 0
+};
+
+std::string
+cmLocalGenerator::ExpandRuleVariable(std::string const& variable,
+ const RuleVariables& replaceValues)
+{
+ if(replaceValues.LinkFlags)
+ {
+ if(variable == "LINK_FLAGS")
+ {
+ return replaceValues.LinkFlags;
+ }
+ }
+ if(replaceValues.Flags)
+ {
+ if(variable == "FLAGS")
+ {
+ return replaceValues.Flags;
+ }
+ }
+
+ if(replaceValues.Source)
+ {
+ if(variable == "SOURCE")
+ {
+ return replaceValues.Source;
+ }
+ }
+ if(replaceValues.PreprocessedSource)
+ {
+ if(variable == "PREPROCESSED_SOURCE")
+ {
+ return replaceValues.PreprocessedSource;
+ }
+ }
+ if(replaceValues.AssemblySource)
+ {
+ if(variable == "ASSEMBLY_SOURCE")
+ {
+ return replaceValues.AssemblySource;
+ }
+ }
+ if(replaceValues.Object)
+ {
+ if(variable == "OBJECT")
+ {
+ return replaceValues.Object;
+ }
+ }
+ if(replaceValues.ObjectDir)
+ {
+ if(variable == "OBJECT_DIR")
+ {
+ return replaceValues.ObjectDir;
+ }
+ }
+ if(replaceValues.Objects)
+ {
+ if(variable == "OBJECTS")
+ {
+ return replaceValues.Objects;
+ }
+ }
+ if(replaceValues.ObjectsQuoted)
+ {
+ if(variable == "OBJECTS_QUOTED")
+ {
+ return replaceValues.ObjectsQuoted;
+ }
+ }
+ if(replaceValues.Defines && variable == "DEFINES")
+ {
+ return replaceValues.Defines;
+ }
+ if(replaceValues.TargetPDB )
+ {
+ if(variable == "TARGET_PDB")
+ {
+ return replaceValues.TargetPDB;
+ }
+ }
+ if(replaceValues.DependencyFile )
+ {
+ if(variable == "DEP_FILE")
+ {
+ return replaceValues.DependencyFile;
+ }
+ }
+
+ if(replaceValues.Target)
+ {
+ if(variable == "TARGET_QUOTED")
+ {
+ std::string targetQuoted = replaceValues.Target;
+ if(targetQuoted.size() && targetQuoted[0] != '\"')
+ {
+ targetQuoted = '\"';
+ targetQuoted += replaceValues.Target;
+ targetQuoted += '\"';
+ }
+ return targetQuoted;
+ }
+ if(variable == "TARGET_UNQUOTED")
+ {
+ std::string unquoted = replaceValues.Target;
+ std::string::size_type sz = unquoted.size();
+ if(sz > 2 && unquoted[0] == '\"' && unquoted[sz-1] == '\"')
+ {
+ unquoted = unquoted.substr(1, sz-2);
+ }
+ return unquoted;
+ }
+ if(replaceValues.LanguageCompileFlags)
+ {
+ if(variable == "LANGUAGE_COMPILE_FLAGS")
+ {
+ return replaceValues.LanguageCompileFlags;
+ }
+ }
+ if(replaceValues.Target)
+ {
+ if(variable == "TARGET")
+ {
+ return replaceValues.Target;
+ }
+ }
+ if(variable == "TARGET_IMPLIB")
+ {
+ return this->TargetImplib;
+ }
+ if(variable == "TARGET_VERSION_MAJOR")
+ {
+ if(replaceValues.TargetVersionMajor)
+ {
+ return replaceValues.TargetVersionMajor;
+ }
+ else
+ {
+ return "0";
+ }
+ }
+ if(variable == "TARGET_VERSION_MINOR")
+ {
+ if(replaceValues.TargetVersionMinor)
+ {
+ return replaceValues.TargetVersionMinor;
+ }
+ else
+ {
+ return "0";
+ }
+ }
+ if(replaceValues.Target)
+ {
+ if(variable == "TARGET_BASE")
+ {
+ // Strip the last extension off the target name.
+ std::string targetBase = replaceValues.Target;
+ std::string::size_type pos = targetBase.rfind(".");
+ if(pos != targetBase.npos)
+ {
+ return targetBase.substr(0, pos);
+ }
+ else
+ {
+ return targetBase;
+ }
+ }
+ }
+ }
+ if(variable == "TARGET_SONAME" || variable == "SONAME_FLAG" ||
+ variable == "TARGET_INSTALLNAME_DIR")
+ {
+ // All these variables depend on TargetSOName
+ if(replaceValues.TargetSOName)
+ {
+ if(variable == "TARGET_SONAME")
+ {
+ return replaceValues.TargetSOName;
+ }
+ if(variable == "SONAME_FLAG" && replaceValues.SONameFlag)
+ {
+ return replaceValues.SONameFlag;
+ }
+ if(replaceValues.TargetInstallNameDir &&
+ variable == "TARGET_INSTALLNAME_DIR")
+ {
+ return replaceValues.TargetInstallNameDir;
+ }
+ }
+ return "";
+ }
+ if(replaceValues.LinkLibraries)
+ {
+ if(variable == "LINK_LIBRARIES")
+ {
+ return replaceValues.LinkLibraries;
+ }
+ }
+ if(replaceValues.Language)
+ {
+ if(variable == "LANGUAGE")
+ {
+ return replaceValues.Language;
+ }
+ }
+ if(replaceValues.CMTarget)
+ {
+ if(variable == "TARGET_NAME")
+ {
+ return replaceValues.CMTarget->GetName();
+ }
+ if(variable == "TARGET_TYPE")
+ {
+ return cmTarget::GetTargetTypeName(replaceValues.CMTarget->GetType());
+ }
+ }
+ if(replaceValues.Output)
+ {
+ if(variable == "OUTPUT")
+ {
+ return replaceValues.Output;
+ }
+ }
+ if(variable == "CMAKE_COMMAND")
+ {
+ const char* cmcommand =
+ this->GetMakefile()->GetDefinition("CMAKE_COMMAND");
+ return this->Convert(cmcommand, FULL, SHELL);
+ }
+ std::vector<std::string> enabledLanguages;
+ this->GlobalGenerator->GetEnabledLanguages(enabledLanguages);
+ // loop over language specific replace variables
+ int pos = 0;
+ while(ruleReplaceVars[pos])
+ {
+ for(std::vector<std::string>::iterator i = enabledLanguages.begin();
+ i != enabledLanguages.end(); ++i)
+ {
+ const char* lang = i->c_str();
+ std::string actualReplace = ruleReplaceVars[pos];
+ // 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;
+ if(actualReplace == "CMAKE_${LANG}_COMPILER")
+ {
+ std::string arg1 = actualReplace + "_ARG1";
+ cmSystemTools::ReplaceString(arg1, "${LANG}", lang);
+ compilerArg1 = this->Makefile->GetDefinition(arg1.c_str());
+ }
+ if(actualReplace.find("${LANG}") != actualReplace.npos)
+ {
+ cmSystemTools::ReplaceString(actualReplace, "${LANG}", lang);
+ }
+ if(actualReplace == variable)
+ {
+ std::string replace =
+ this->Makefile->GetSafeDefinition(variable.c_str());
+ // 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());
+ // if there is a required first argument to the compiler add it
+ // to the compiler string
+ if(compilerArg1)
+ {
+ ret += " ";
+ ret += compilerArg1;
+ }
+ return ret;
+ }
+ return replace;
+ }
+ }
+ pos++;
+ }
+ return variable;
+}
+
+
+void
+cmLocalGenerator::ExpandRuleVariables(std::string& s,
+ const RuleVariables& replaceValues)
+{
+ std::vector<std::string> enabledLanguages;
+ this->GlobalGenerator->GetEnabledLanguages(enabledLanguages);
+ this->InsertRuleLauncher(s, replaceValues.CMTarget,
+ replaceValues.RuleLauncher);
+ std::string::size_type start = s.find('<');
+ // no variables to expand
+ if(start == s.npos)
+ {
+ return;
+ }
+ std::string::size_type pos = 0;
+ std::string expandedInput;
+ while(start != s.npos && start < s.size()-2)
+ {
+ std::string::size_type end = s.find('>', start);
+ // if we find a < with no > we are done
+ if(end == s.npos)
+ {
+ return;
+ }
+ char c = s[start+1];
+ // if the next char after the < is not A-Za-z then
+ // skip it and try to find the next < in the string
+ if(!isalpha(c))
+ {
+ start = s.find('<', start+1);
+ }
+ else
+ {
+ // extract the var
+ std::string var = s.substr(start+1, end - start-1);
+ std::string replace = this->ExpandRuleVariable(var,
+ replaceValues);
+ expandedInput += s.substr(pos, start-pos);
+ expandedInput += replace;
+ // move to next one
+ start = s.find('<', start+var.size()+2);
+ pos = end+1;
+ }
+ }
+ // add the rest of the input
+ expandedInput += s.substr(pos, s.size()-pos);
+ s = expandedInput;
+}
+
+//----------------------------------------------------------------------------
+const char* cmLocalGenerator::GetRuleLauncher(cmTarget* target,
+ const char* prop)
+{
+ if(target)
+ {
+ return target->GetProperty(prop);
+ }
+ else
+ {
+ return this->Makefile->GetProperty(prop);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmLocalGenerator::InsertRuleLauncher(std::string& s, cmTarget* target,
+ const char* prop)
+{
+ if(const char* val = this->GetRuleLauncher(target, prop))
+ {
+ cmOStringStream wrapped;
+ wrapped << val << " " << s;
+ s = wrapped.str();
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmLocalGenerator::ConvertToOutputForExistingCommon(const char* remote,
+ std::string const& result)
+{
+ // 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());
+}
+
+//----------------------------------------------------------------------------
+std::string cmLocalGenerator::GetIncludeFlags(
+ const std::vector<std::string> &includes,
+ const char* lang, bool forResponseFile)
+{
+ if(!lang)
+ {
+ return "";
+ }
+
+ cmOStringStream includeFlags;
+
+ std::string flagVar = "CMAKE_INCLUDE_FLAG_";
+ flagVar += lang;
+ const char* includeFlag =
+ this->Makefile->GetSafeDefinition(flagVar.c_str());
+ flagVar = "CMAKE_INCLUDE_FLAG_SEP_";
+ flagVar += lang;
+ const char* sep = this->Makefile->GetDefinition(flagVar.c_str());
+ bool quotePaths = false;
+ if(this->Makefile->GetDefinition("CMAKE_QUOTE_INCLUDE_PATHS"))
+ {
+ quotePaths = true;
+ }
+ bool repeatFlag = true;
+ // should the include flag be repeated like ie. -IA -IB
+ if(!sep)
+ {
+ sep = " ";
+ }
+ else
+ {
+ // if there is a separator then the flag is not repeated but is only
+ // given once i.e. -classpath a:b:c
+ repeatFlag = false;
+ }
+
+ // Support special system include flag if it is available and the
+ // normal flag is repeated for each directory.
+ std::string sysFlagVar = "CMAKE_INCLUDE_SYSTEM_FLAG_";
+ sysFlagVar += lang;
+ const char* sysIncludeFlag = 0;
+ if(repeatFlag)
+ {
+ sysIncludeFlag = this->Makefile->GetDefinition(sysFlagVar.c_str());
+ }
+
+ bool flagUsed = false;
+ std::set<cmStdString> 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")
+ && cmSystemTools::IsPathToFramework(i->c_str()))
+ {
+ std::string frameworkDir = *i;
+ frameworkDir += "/../";
+ frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir.c_str());
+ if(emitted.insert(frameworkDir).second)
+ {
+ OutputFormat format = forResponseFile? RESPONSE : SHELL;
+ includeFlags
+ << "-F" << this->Convert(frameworkDir.c_str(),
+ START_OUTPUT, format, true)
+ << " ";
+ }
+ continue;
+ }
+
+ std::string include = *i;
+ if(!flagUsed || repeatFlag)
+ {
+ if(sysIncludeFlag &&
+ this->Makefile->IsSystemIncludeDirectory(i->c_str()))
+ {
+ includeFlags << sysIncludeFlag;
+ }
+ else
+ {
+ includeFlags << includeFlag;
+ }
+ 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] != '\"')
+ {
+ includeFlags << "\"";
+ }
+ includeFlags << includePath;
+ if(quotePaths && includePath.size() && includePath[0] != '\"')
+ {
+ includeFlags << "\"";
+ }
+ includeFlags << sep;
+ }
+ std::string flags = includeFlags.str();
+ // remove trailing separators
+ if((sep[0] != ' ') && flags.size()>0 && flags[flags.size()-1] == sep[0])
+ {
+ flags[flags.size()-1] = ' ';
+ }
+ return flags;
+}
+
+//----------------------------------------------------------------------------
+void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs,
+ cmTarget* target,
+ const char* lang)
+{
+ // Need to decide whether to automatically include the source and
+ // binary directories at the beginning of the include path.
+ bool includeSourceDir = false;
+ bool includeBinaryDir = false;
+
+ // When automatic include directories are requested for a build then
+ // include the source and binary directories at the beginning of the
+ // include path to approximate include file behavior for an
+ // in-source build. This does not account for the case of a source
+ // file in a subdirectory of the current source directory but we
+ // cannot fix this because not all native build tools support
+ // per-source-file include paths.
+ if(this->Makefile->IsOn("CMAKE_INCLUDE_CURRENT_DIR"))
+ {
+ includeSourceDir = true;
+ 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;
+
+ // Store the automatic include paths.
+ if(includeBinaryDir)
+ {
+ if(emitted.find(
+ this->Makefile->GetStartOutputDirectory()) == emitted.end())
+ {
+ dirs.push_back(this->Makefile->GetStartOutputDirectory());
+ emitted.insert(this->Makefile->GetStartOutputDirectory());
+ }
+ }
+ if(includeSourceDir)
+ {
+ if(emitted.find(this->Makefile->GetStartDirectory()) == emitted.end())
+ {
+ dirs.push_back(this->Makefile->GetStartDirectory());
+ emitted.insert(this->Makefile->GetStartDirectory());
+ }
+ }
+
+ // 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()))
+ {
+ 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);
+ }
+ }
+
+ // Get the target-specific include directories.
+ std::vector<std::string> includes;
+ if(target)
+ {
+ includes = target->GetIncludeDirectories();
+ }
+
+ // 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();
+ 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(emitted.insert(*i).second)
+ {
+ dirs.push_back(*i);
+ }
+ }
+ }
+ }
+
+ // Construct the final ordered include directory list.
+ for(std::vector<std::string>::const_iterator i = includes.begin();
+ i != includes.end(); ++i)
+ {
+ if(emitted.insert(*i).second)
+ {
+ dirs.push_back(*i);
+ }
+ }
+}
+
+void cmLocalGenerator::GetTargetFlags(std::string& linkLibs,
+ std::string& flags,
+ std::string& linkFlags,
+ cmTarget& target)
+{
+ std::string buildType =
+ this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
+ buildType = cmSystemTools::UpperCase(buildType);
+ const char* libraryLinkVariable =
+ "CMAKE_SHARED_LINKER_FLAGS"; // default to shared library
+
+ switch(target.GetType())
+ {
+ case cmTarget::STATIC_LIBRARY:
+ {
+ const char* targetLinkFlags =
+ target.GetProperty("STATIC_LIBRARY_FLAGS");
+ if(targetLinkFlags)
+ {
+ linkFlags += targetLinkFlags;
+ linkFlags += " ";
+ }
+ if(!buildType.empty())
+ {
+ std::string build = "STATIC_LIBRARY_FLAGS_";
+ build += buildType;
+ targetLinkFlags = target.GetProperty(build.c_str());
+ if(targetLinkFlags)
+ {
+ linkFlags += targetLinkFlags;
+ linkFlags += " ";
+ }
+ }
+ }
+ break;
+ case cmTarget::MODULE_LIBRARY:
+ libraryLinkVariable = "CMAKE_MODULE_LINKER_FLAGS";
+ case cmTarget::SHARED_LIBRARY:
+ {
+ linkFlags = this->Makefile->GetSafeDefinition(libraryLinkVariable);
+ linkFlags += " ";
+ if(!buildType.empty())
+ {
+ std::string build = libraryLinkVariable;
+ build += "_";
+ build += buildType;
+ linkFlags += this->Makefile->GetSafeDefinition(build.c_str());
+ linkFlags += " ";
+ }
+ if(this->Makefile->IsOn("WIN32") &&
+ !(this->Makefile->IsOn("CYGWIN") || this->Makefile->IsOn("MINGW")))
+ {
+ const std::vector<cmSourceFile*>& sources = target.GetSourceFiles();
+ for(std::vector<cmSourceFile*>::const_iterator i = sources.begin();
+ i != sources.end(); ++i)
+ {
+ cmSourceFile* sf = *i;
+ if(sf->GetExtension() == "def")
+ {
+ linkFlags +=
+ this->Makefile->GetSafeDefinition("CMAKE_LINK_DEF_FILE_FLAG");
+ linkFlags += this->Convert(sf->GetFullPath().c_str(),
+ FULL, SHELL);
+ linkFlags += " ";
+ }
+ }
+ }
+ const char* targetLinkFlags = target.GetProperty("LINK_FLAGS");
+ if(targetLinkFlags)
+ {
+ linkFlags += targetLinkFlags;
+ linkFlags += " ";
+ }
+ if(!buildType.empty())
+ {
+ std::string configLinkFlags = "LINK_FLAGS_";
+ configLinkFlags += buildType;
+ targetLinkFlags = target.GetProperty(configLinkFlags.c_str());
+ if(targetLinkFlags)
+ {
+ linkFlags += targetLinkFlags;
+ linkFlags += " ";
+ }
+ }
+ cmOStringStream linklibsStr;
+ this->OutputLinkLibraries(linklibsStr, target, false);
+ linkLibs = linklibsStr.str();
+ }
+ break;
+ case cmTarget::EXECUTABLE:
+ {
+ linkFlags +=
+ this->Makefile->GetSafeDefinition("CMAKE_EXE_LINKER_FLAGS");
+ linkFlags += " ";
+ if(!buildType.empty())
+ {
+ std::string build = "CMAKE_EXE_LINKER_FLAGS_";
+ build += buildType;
+ linkFlags += this->Makefile->GetSafeDefinition(build.c_str());
+ linkFlags += " ";
+ }
+ const char* linkLanguage = target.GetLinkerLanguage();
+ if(!linkLanguage)
+ {
+ cmSystemTools::Error
+ ("CMake can not determine linker language for target:",
+ target.GetName());
+ return;
+ }
+ this->AddLanguageFlags(flags, linkLanguage, buildType.c_str());
+ cmOStringStream linklibs;
+ this->OutputLinkLibraries(linklibs, target, false);
+ linkLibs = linklibs.str();
+ 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 += " ";
+ }
+ if ( target.GetPropertyAsBool("WIN32_EXECUTABLE") )
+ {
+ linkFlags +=
+ this->Makefile->GetSafeDefinition("CMAKE_CREATE_WIN32_EXE");
+ linkFlags += " ";
+ }
+ else
+ {
+ linkFlags +=
+ this->Makefile->GetSafeDefinition("CMAKE_CREATE_CONSOLE_EXE");
+ linkFlags += " ";
+ }
+ if (target.IsExecutableWithExports())
+ {
+ std::string exportFlagVar = "CMAKE_EXE_EXPORTS_";
+ exportFlagVar += linkLanguage;
+ exportFlagVar += "_FLAG";
+
+ linkFlags +=
+ this->Makefile->GetSafeDefinition(exportFlagVar.c_str());
+ linkFlags += " ";
+ }
+ const char* targetLinkFlags = target.GetProperty("LINK_FLAGS");
+ if(targetLinkFlags)
+ {
+ linkFlags += targetLinkFlags;
+ linkFlags += " ";
+ }
+ if(!buildType.empty())
+ {
+ std::string configLinkFlags = "LINK_FLAGS_";
+ configLinkFlags += buildType;
+ targetLinkFlags = target.GetProperty(configLinkFlags.c_str());
+ if(targetLinkFlags)
+ {
+ linkFlags += targetLinkFlags;
+ linkFlags += " ";
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+std::string cmLocalGenerator::ConvertToLinkReference(std::string const& lib)
+{
+#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"))
+ {
+ // Search for the last space.
+ std::string::size_type pos = lib.rfind(' ');
+ if(pos != lib.npos)
+ {
+ // Find the slash after the last space, if any.
+ pos = lib.find('/', pos);
+
+ // Convert the portion of the path with a space to a short path.
+ std::string sp;
+ if(cmSystemTools::GetShortPath(lib.substr(0, pos).c_str(), sp))
+ {
+ // Append the rest of the path with no space.
+ sp += lib.substr(pos);
+
+ // Convert to an output path.
+ return this->Convert(sp.c_str(), NONE, SHELL);
+ }
+ }
+ }
+#endif
+
+ // Normal behavior.
+ return this->Convert(lib.c_str(), START_OUTPUT, SHELL);
+}
+
+/**
+ * Output the linking rules on a command line. For executables,
+ * targetLibrary should be a NULL pointer. For libraries, it should point
+ * to the name of the library. This will not link a library against itself.
+ */
+void cmLocalGenerator::OutputLinkLibraries(std::ostream& fout,
+ cmTarget& tgt,
+ bool relink)
+{
+ const char* config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE");
+ cmComputeLinkInformation* pcli = tgt.GetLinkInformation(config);
+ if(!pcli)
+ {
+ return;
+ }
+ cmComputeLinkInformation& cli = *pcli;
+
+ // Collect library linking flags command line options.
+ std::string linkLibs;
+
+ const char* linkLanguage = cli.GetLinkLanguage();
+
+ std::string libPathFlag =
+ this->Makefile->GetRequiredDefinition("CMAKE_LIBRARY_PATH_FLAG");
+ std::string libPathTerminator =
+ 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 )
+ {
+ linkLibs = this->Makefile->GetSafeDefinition(linkFlagsVar.c_str());
+ 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)
+ {
+ linkLibs += "-F";
+ linkLibs += this->Convert(fdi->c_str(), NONE, SHELL, false);
+ linkLibs += " ";
+ }
+
+ // Append the library search path flags.
+ std::vector<std::string> const& libDirs = cli.GetDirectories();
+ for(std::vector<std::string>::const_iterator libDir = libDirs.begin();
+ libDir != libDirs.end(); ++libDir)
+ {
+ std::string libpath = this->ConvertToOutputForExisting(libDir->c_str());
+ linkLibs += libPathFlag;
+ linkLibs += libpath;
+ linkLibs += libPathTerminator;
+ linkLibs += " ";
+ }
+
+ // Append the link items.
+ typedef cmComputeLinkInformation::ItemVector ItemVector;
+ ItemVector const& items = cli.GetItems();
+ for(ItemVector::const_iterator li = items.begin(); li != items.end(); ++li)
+ {
+ if(li->IsPath)
+ {
+ linkLibs += this->ConvertToLinkReference(li->Value);
+ }
+ else
+ {
+ linkLibs += li->Value;
+ }
+ linkLibs += " ";
+ }
+
+ // 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::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 += " ";
+ }
+ fout << rpath;
+ }
+ else
+ {
+ // All rpath entries are combined ("-Wl,-rpath,a:b:c").
+ std::string rpath = cli.GetRPathString(relink);
+
+ // Store the rpath option in the stream.
+ if(!rpath.empty())
+ {
+ fout << cli.GetRuntimeFlag();
+ fout << this->EscapeForShell(rpath.c_str(), true);
+ fout << " ";
+ }
+ }
+
+ // Add the linker runtime search path if any.
+ std::string rpath_link = cli.GetRPathLinkString();
+ if(!cli.GetRPathLinkFlag().empty() && !rpath_link.empty())
+ {
+ fout << cli.GetRPathLinkFlag();
+ fout << this->EscapeForShell(rpath_link.c_str(), true);
+ fout << " ";
+ }
+
+ // Add standard libraries for this language.
+ std::string standardLibsVar = "CMAKE_";
+ standardLibsVar += cli.GetLinkLanguage();
+ standardLibsVar += "_STANDARD_LIBRARIES";
+ if(const char* stdLibs =
+ this->Makefile->GetDefinition(standardLibsVar.c_str()))
+ {
+ fout << stdLibs << " ";
+ }
+}
+
+
+//----------------------------------------------------------------------------
+void cmLocalGenerator::AddArchitectureFlags(std::string& flags,
+ cmTarget* target,
+ const char *lang,
+ const char* config)
+{
+ // Only add Mac OS X specific flags on Darwin platforms (OSX and iphone):
+ if(!this->Makefile->IsOn("APPLE"))
+ {
+ return;
+ }
+
+ if(this->EmitUniversalBinaryFlags)
+ {
+ std::vector<std::string> archs;
+ target->GetAppleArchs(config, archs);
+ const char* sysroot =
+ this->Makefile->GetDefinition("CMAKE_OSX_SYSROOT");
+ const char* sysrootDefault =
+ this->Makefile->GetDefinition("CMAKE_OSX_SYSROOT_DEFAULT");
+ const char* deploymentTarget =
+ this->Makefile->GetDefinition("CMAKE_OSX_DEPLOYMENT_TARGET");
+ std::string isysrootVar = std::string("CMAKE_") + lang + "_HAS_ISYSROOT";
+ bool hasIsysroot = this->Makefile->IsOn(isysrootVar.c_str());
+ std::string deploymentTargetFlagVar =
+ std::string("CMAKE_") + lang + "_OSX_DEPLOYMENT_TARGET_FLAG";
+ const char* deploymentTargetFlag =
+ this->Makefile->GetDefinition(deploymentTargetFlagVar.c_str());
+ bool flagsUsed = false;
+ if(!archs.empty() && sysroot && lang && (lang[0] =='C' || lang[0] == 'F'))
+ {
+ // if there is more than one arch add the -arch and
+ // -isysroot flags, or if there is one arch flag, but
+ // it is not the default -arch flag for the system, then
+ // add it. Otherwize do not add -arch and -isysroot
+ if(archs[0] != "")
+ {
+ for( std::vector<std::string>::iterator i = archs.begin();
+ i != archs.end(); ++i)
+ {
+ flags += " -arch ";
+ flags += *i;
+ }
+ if(hasIsysroot)
+ {
+ flags += " -isysroot ";
+ flags += sysroot;
+ }
+ flagsUsed = true;
+ }
+ }
+
+ if(!flagsUsed && sysroot && sysrootDefault &&
+ strcmp(sysroot, sysrootDefault) != 0 && hasIsysroot)
+ {
+ flags += " -isysroot ";
+ flags += sysroot;
+ }
+
+ if (deploymentTargetFlag && *deploymentTargetFlag &&
+ deploymentTarget && *deploymentTarget)
+ {
+ flags += " ";
+ flags += deploymentTargetFlag;
+ flags += deploymentTarget;
+ }
+ }
+}
+
+
+//----------------------------------------------------------------------------
+void cmLocalGenerator::AddLanguageFlags(std::string& flags,
+ const char* lang,
+ const char* config)
+{
+ // Add language-specific flags.
+ std::string flagsVar = "CMAKE_";
+ flagsVar += lang;
+ flagsVar += "_FLAGS";
+ this->AddConfigVariableFlags(flags, flagsVar.c_str(), config);
+}
+
+//----------------------------------------------------------------------------
+bool cmLocalGenerator::GetRealDependency(const char* inName,
+ const char* config,
+ std::string& dep)
+{
+ // Older CMake code may specify the dependency using the target
+ // output file rather than the target name. Such code would have
+ // been written before there was support for target properties that
+ // modify the name so stripping down to just the file name should
+ // produce the target name in this case.
+ std::string name = cmSystemTools::GetFilenameName(inName);
+ if(cmSystemTools::GetFilenameLastExtension(name) == ".exe")
+ {
+ name = cmSystemTools::GetFilenameWithoutLastExtension(name);
+ }
+
+ // Look for a CMake target with the given name.
+ if(cmTarget* target = this->Makefile->FindTargetToUse(name.c_str()))
+ {
+ // make sure it is not just a coincidence that the target name
+ // found is part of the inName
+ if(cmSystemTools::FileIsFullPath(inName))
+ {
+ std::string tLocation;
+ if(target->GetType() >= cmTarget::EXECUTABLE &&
+ target->GetType() <= cmTarget::MODULE_LIBRARY)
+ {
+ tLocation = target->GetLocation(config);
+ tLocation = cmSystemTools::GetFilenamePath(tLocation);
+ tLocation = cmSystemTools::CollapseFullPath(tLocation.c_str());
+ }
+ std::string depLocation = cmSystemTools::GetFilenamePath(
+ std::string(inName));
+ depLocation = cmSystemTools::CollapseFullPath(depLocation.c_str());
+ if(depLocation != tLocation)
+ {
+ // it is a full path to a depend that has the same name
+ // as a target but is in a different location so do not use
+ // the target as the depend
+ dep = inName;
+ return true;
+ }
+ }
+ switch (target->GetType())
+ {
+ case cmTarget::EXECUTABLE:
+ case cmTarget::STATIC_LIBRARY:
+ case cmTarget::SHARED_LIBRARY:
+ case cmTarget::MODULE_LIBRARY:
+ case cmTarget::UNKNOWN_LIBRARY:
+ dep = target->GetLocation(config);
+ return true;
+ case cmTarget::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:
+ // A utility target has no file on which to depend. This was listed
+ // only to get the target-level dependency.
+ return false;
+ }
+ }
+
+ // The name was not that of a CMake target. It must name a file.
+ if(cmSystemTools::FileIsFullPath(inName))
+ {
+ // This is a full path. Return it as given.
+ dep = inName;
+ return true;
+ }
+
+ // Check for a source file in this directory that matches the
+ // dependency.
+ if(cmSourceFile* sf = this->Makefile->GetSource(inName))
+ {
+ dep = sf->GetFullPath();
+ return true;
+ }
+
+ // Treat the name as relative to the source directory in which it
+ // was given.
+ dep = this->Makefile->GetCurrentDirectory();
+ dep += "/";
+ dep += inName;
+ return true;
+}
+
+//----------------------------------------------------------------------------
+void cmLocalGenerator::AddSharedFlags(std::string& flags,
+ const char* lang,
+ bool shared)
+{
+ std::string flagsVar;
+
+ // Add flags for dealing with shared libraries for this language.
+ if(shared)
+ {
+ flagsVar = "CMAKE_SHARED_LIBRARY_";
+ flagsVar += lang;
+ flagsVar += "_FLAGS";
+ this->AppendFlags(flags, this->Makefile->GetDefinition(flagsVar.c_str()));
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmLocalGenerator::AddCMP0018Flags(std::string &flags, cmTarget* target,
+ std::string const& lang)
+{
+ int targetType = target->GetType();
+
+ bool shared = ((targetType == cmTarget::SHARED_LIBRARY) ||
+ (targetType == cmTarget::MODULE_LIBRARY));
+
+ if (this->GetShouldUseOldFlags(shared, lang))
+ {
+ this->AddSharedFlags(flags, lang.c_str(), shared);
+ }
+ else
+ {
+ // Add position independendent flags, if needed.
+ if (target->GetPropertyAsBool("POSITION_INDEPENDENT_CODE"))
+ {
+ this->AddPositionIndependentFlags(flags, lang, targetType);
+ }
+ if (shared)
+ {
+ this->AppendFeatureOptions(flags, lang.c_str(), "DLL");
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmLocalGenerator::GetShouldUseOldFlags(bool shared,
+ const std::string &lang) const
+{
+ std::string originalFlags =
+ this->GlobalGenerator->GetSharedLibFlagsForLanguage(lang);
+ if (shared)
+ {
+ std::string flagsVar = "CMAKE_SHARED_LIBRARY_";
+ flagsVar += lang;
+ flagsVar += "_FLAGS";
+ const char* flags =
+ this->Makefile->GetSafeDefinition(flagsVar.c_str());
+
+ if (flags && flags != originalFlags)
+ {
+ switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0018))
+ {
+ case cmPolicies::WARN:
+ {
+ cmOStringStream 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);
+
+ this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, e.str());
+ // fall through to OLD behaviour
+ }
+ case cmPolicies::OLD:
+ return true;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::NEW:
+ default:
+ return false;
+ }
+ }
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+void cmLocalGenerator::AddPositionIndependentFlags(std::string& flags,
+ std::string const& lang,
+ int targetType)
+{
+ const char* picFlags = 0;
+
+ if(targetType == cmTarget::EXECUTABLE)
+ {
+ std::string flagsVar = "CMAKE_";
+ flagsVar += lang;
+ flagsVar += "_COMPILE_OPTIONS_PIE";
+ picFlags = this->Makefile->GetSafeDefinition(flagsVar.c_str());
+ }
+ if (!picFlags)
+ {
+ std::string flagsVar = "CMAKE_";
+ flagsVar += lang;
+ flagsVar += "_COMPILE_OPTIONS_PIC";
+ picFlags = this->Makefile->GetSafeDefinition(flagsVar.c_str());
+ }
+ if (picFlags)
+ {
+ std::vector<std::string> options;
+ cmSystemTools::ExpandListArgument(picFlags, options);
+ for(std::vector<std::string>::const_iterator oi = options.begin();
+ oi != options.end(); ++oi)
+ {
+ this->AppendFlags(flags, this->EscapeForShell(oi->c_str()).c_str());
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmLocalGenerator::AddConfigVariableFlags(std::string& flags,
+ const char* var,
+ const char* config)
+{
+ // Add the flags from the variable itself.
+ std::string flagsVar = var;
+ this->AppendFlags(flags, this->Makefile->GetDefinition(flagsVar.c_str()));
+ // Add the flags from the build-type specific variable.
+ if(config && *config)
+ {
+ flagsVar += "_";
+ flagsVar += cmSystemTools::UpperCase(config);
+ this->AppendFlags(flags, this->Makefile->GetDefinition(flagsVar.c_str()));
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmLocalGenerator::AppendFlags(std::string& flags,
+ const char* newFlags)
+{
+ if(newFlags && *newFlags)
+ {
+ std::string newf = newFlags;
+ if(flags.size())
+ {
+ flags += " ";
+ }
+ flags += newFlags;
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmLocalGenerator::AppendDefines(std::string& defines,
+ const char* defines_list,
+ const char* lang)
+{
+ // Short-circuit if there are no definitions.
+ if(!defines_list)
+ {
+ return;
+ }
+
+ // Expand the list of definitions.
+ std::vector<std::string> defines_vec;
+ cmSystemTools::ExpandListArgument(defines_list, defines_vec);
+
+ // Short-circuit if there are no definitions.
+ if(defines_vec.empty())
+ {
+ return;
+ }
+
+ // Lookup the define flag for the current language.
+ std::string dflag = "-D";
+ if(lang)
+ {
+ std::string defineFlagVar = "CMAKE_";
+ defineFlagVar += lang;
+ defineFlagVar += "_DEFINE_FLAG";
+ const char* df = this->Makefile->GetDefinition(defineFlagVar.c_str());
+ if(df && *df)
+ {
+ dflag = df;
+ }
+ }
+
+ // Add each definition to the command line with appropriate escapes.
+ const char* dsep = defines.empty()? "" : " ";
+ for(std::vector<std::string>::const_iterator di = defines_vec.begin();
+ di != defines_vec.end(); ++di)
+ {
+ // Skip unsupported definitions.
+ if(!this->CheckDefinition(*di))
+ {
+ continue;
+ }
+
+ // Separate from previous definitions.
+ defines += dsep;
+ dsep = " ";
+
+ // Append the definition with proper escaping.
+ defines += dflag;
+ if(this->WatcomWMake)
+ {
+ // The Watcom compiler does its own command line parsing instead
+ // of using the windows shell rules. Definitions are one of
+ // -DNAME
+ // -DNAME=<cpp-token>
+ // -DNAME="c-string with spaces and other characters(?@#$)"
+ //
+ // Watcom will properly parse each of these cases from the
+ // command line without any escapes. However we still have to
+ // get the '$' and '#' characters through WMake as '$$' and
+ // '$#'.
+ for(const char* c = di->c_str(); *c; ++c)
+ {
+ if(*c == '$' || *c == '#')
+ {
+ defines += '$';
+ }
+ defines += *c;
+ }
+ }
+ else
+ {
+ // Make the definition appear properly on the command line. Use
+ // -DNAME="value" instead of -D"NAME=value" to help VS6 parser.
+ std::string::size_type eq = di->find("=");
+ defines += di->substr(0, eq);
+ if(eq != di->npos)
+ {
+ defines += "=";
+ defines += this->EscapeForShell(di->c_str() + eq + 1, true);
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmLocalGenerator::AppendFeatureOptions(
+ std::string& flags, const char* 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()))
+ {
+ std::vector<std::string> options;
+ cmSystemTools::ExpandListArgument(optionList, options);
+ for(std::vector<std::string>::const_iterator oi = options.begin();
+ oi != options.end(); ++oi)
+ {
+ this->AppendFlags(flags, this->EscapeForShell(oi->c_str()).c_str());
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmLocalGenerator::ConstructComment(const cmCustomCommand& cc,
+ const char* default_comment)
+{
+ // Check for a comment provided with the command.
+ if(cc.GetComment())
+ {
+ return cc.GetComment();
+ }
+
+ // Construct a reasonable default comment if possible.
+ if(!cc.GetOutputs().empty())
+ {
+ std::string comment;
+ comment = "Generating ";
+ const char* sep = "";
+ for(std::vector<std::string>::const_iterator o = cc.GetOutputs().begin();
+ o != cc.GetOutputs().end(); ++o)
+ {
+ comment += sep;
+ comment += this->Convert(o->c_str(), cmLocalGenerator::START_OUTPUT);
+ sep = ", ";
+ }
+ 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;
+ }
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+std::string cmLocalGenerator::Convert(const char* source,
+ RelativeRoot relative,
+ OutputFormat output,
+ bool optional)
+{
+ // 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);
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string cmLocalGenerator::FindRelativePathTopSource()
+{
+ // 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())
+ {
+ std::string parentTop = parent->FindRelativePathTopSource();
+ if(cmSystemTools::IsSubDirectory(
+ this->Makefile->GetStartDirectory(), parentTop.c_str()))
+ {
+ return parentTop;
+ }
+ }
+
+ // 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())
+ {
+ std::string parentTop = parent->FindRelativePathTopBinary();
+ if(cmSystemTools::IsSubDirectory(
+ this->Makefile->GetStartOutputDirectory(), parentTop.c_str()))
+ {
+ return parentTop;
+ }
+ }
+
+ // 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));
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmLocalGenerator::ConvertToRelativePath(const std::vector<std::string>& local,
+ const char* in_remote, bool force)
+{
+ // 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;
+}
+
+//----------------------------------------------------------------------------
+void
+cmLocalGenerator
+::GenerateTargetInstallRules(
+ std::ostream& os, const char* 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)
+ {
+ // Include the user-specified pre-install script for this target.
+ if(const char* preinstall = l->second.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() != "")
+ {
+ // 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);
+ cmSystemTools::ConvertToUnixSlashes(destination);
+ if(destination.empty())
+ {
+ destination = ".";
+ }
+
+ // Generate the proper install generator for this target type.
+ switch(l->second.GetType())
+ {
+ case cmTarget::EXECUTABLE:
+ case cmTarget::STATIC_LIBRARY:
+ case cmTarget::MODULE_LIBRARY:
+ {
+ // Use a target install generator.
+ cmInstallTargetGenerator g(l->second, destination.c_str(), false);
+ g.Generate(os, config, configurationTypes);
+ }
+ break;
+ case cmTarget::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);
+ g1.Generate(os, config, configurationTypes);
+ // We also skip over the leading slash given by the user.
+ destination = l->second.GetRuntimeInstallPath().substr(1);
+ cmSystemTools::ConvertToUnixSlashes(destination);
+ cmInstallTargetGenerator g2(l->second, destination.c_str(), false);
+ g2.Generate(os, config, configurationTypes);
+#else
+ // Use a target install generator.
+ cmInstallTargetGenerator g(l->second, destination.c_str(), false);
+ g.Generate(os, config, configurationTypes);
+#endif
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ // Include the user-specified post-install script for this target.
+ if(const char* postinstall = l->second.GetProperty("POST_INSTALL_SCRIPT"))
+ {
+ cmInstallScriptGenerator g(postinstall, false, 0);
+ g.Generate(os, config, configurationTypes);
+ }
+ }
+}
+
+#if defined(CM_LG_ENCODE_OBJECT_NAMES)
+static std::string cmLocalGeneratorMD5(const char* input)
+{
+ char md5out[32];
+ cmsysMD5* md5 = cmsysMD5_New();
+ cmsysMD5_Initialize(md5);
+ cmsysMD5_Append(md5, reinterpret_cast<unsigned char const*>(input), -1);
+ cmsysMD5_FinalizeHex(md5, md5out);
+ cmsysMD5_Delete(md5);
+ return std::string(md5out, 32);
+}
+
+static bool
+cmLocalGeneratorShortenObjectName(std::string& objName,
+ std::string::size_type max_len)
+{
+ // Replace the beginning of the path portion of the object name with
+ // its own md5 sum.
+ std::string::size_type pos = objName.find('/', objName.size()-max_len+32);
+ if(pos != objName.npos)
+ {
+ std::string md5name = cmLocalGeneratorMD5(objName.substr(0, pos).c_str());
+ md5name += objName.substr(pos);
+ objName = md5name;
+
+ // The object name is now short enough.
+ return true;
+ }
+ else
+ {
+ // The object name could not be shortened enough.
+ return false;
+ }
+}
+
+static
+bool cmLocalGeneratorCheckObjectName(std::string& objName,
+ std::string::size_type dir_len,
+ std::string::size_type max_total_len)
+{
+ // Enforce the maximum file name length if possible.
+ std::string::size_type max_obj_len = max_total_len;
+ if(dir_len < max_total_len)
+ {
+ max_obj_len = max_total_len - dir_len;
+ if(objName.size() > max_obj_len)
+ {
+ // The current object file name is too long. Try to shorten it.
+ return cmLocalGeneratorShortenObjectName(objName, max_obj_len);
+ }
+ else
+ {
+ // The object file name is short enough.
+ return true;
+ }
+ }
+ else
+ {
+ // The build directory in which the object will be stored is
+ // already too deep.
+ return false;
+ }
+}
+#endif
+
+//----------------------------------------------------------------------------
+std::string&
+cmLocalGenerator
+::CreateSafeUniqueObjectFileName(const char* sin,
+ std::string const& dir_max)
+{
+ // Look for an existing mapped name for this object file.
+ std::map<cmStdString,cmStdString>::iterator it =
+ this->UniqueObjectNamesMap.find(sin);
+
+ // If no entry exists create one.
+ if(it == this->UniqueObjectNamesMap.end())
+ {
+ // Start with the original name.
+ std::string ssin = sin;
+
+ // Avoid full paths by removing leading slashes.
+ std::string::size_type pos = 0;
+ for(;pos < ssin.size() && ssin[pos] == '/'; ++pos)
+ {
+ }
+ ssin = ssin.substr(pos);
+
+ // Avoid full paths by removing colons.
+ cmSystemTools::ReplaceString(ssin, ":", "_");
+
+ // Avoid relative paths that go up the tree.
+ cmSystemTools::ReplaceString(ssin, "../", "__/");
+
+ // Avoid spaces.
+ cmSystemTools::ReplaceString(ssin, " ", "_");
+
+ // Mangle the name if necessary.
+ if(this->Makefile->IsOn("CMAKE_MANGLE_OBJECT_FILE_NAMES"))
+ {
+ bool done;
+ int cc = 0;
+ char rpstr[100];
+ sprintf(rpstr, "_p_");
+ cmSystemTools::ReplaceString(ssin, "+", rpstr);
+ std::string sssin = sin;
+ do
+ {
+ done = true;
+ for ( it = this->UniqueObjectNamesMap.begin();
+ it != this->UniqueObjectNamesMap.end();
+ ++ it )
+ {
+ if ( it->second == ssin )
+ {
+ done = false;
+ }
+ }
+ if ( done )
+ {
+ break;
+ }
+ sssin = ssin;
+ cmSystemTools::ReplaceString(ssin, "_p_", rpstr);
+ sprintf(rpstr, "_p%d_", cc++);
+ }
+ while ( !done );
+ }
+
+#if defined(CM_LG_ENCODE_OBJECT_NAMES)
+ if(!cmLocalGeneratorCheckObjectName(ssin, dir_max.size(),
+ this->ObjectPathMax))
+ {
+ // Warn if this is the first time the path has been seen.
+ if(this->ObjectMaxPathViolations.insert(dir_max).second)
+ {
+ cmOStringStream m;
+ m << "The object file directory\n"
+ << " " << dir_max << "\n"
+ << "has " << dir_max.size() << " characters. "
+ << "The maximum full path to an object file is "
+ << this->ObjectPathMax << " characters "
+ << "(see CMAKE_OBJECT_PATH_MAX). "
+ << "Object file\n"
+ << " " << ssin << "\n"
+ << "cannot be safely placed under this directory. "
+ << "The build may not work correctly.";
+ this->Makefile->IssueMessage(cmake::WARNING, m.str());
+ }
+ }
+#else
+ (void)dir_max;
+#endif
+
+ // Insert the newly mapped object file name.
+ std::map<cmStdString, cmStdString>::value_type e(sin, ssin);
+ it = this->UniqueObjectNamesMap.insert(e).first;
+ }
+
+ // Return the map entry.
+ return it->second;
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmLocalGenerator
+::GetObjectFileNameWithoutTarget(const cmSourceFile& source,
+ std::string const& dir_max,
+ bool* hasSourceExtension)
+{
+ // Construct the object file name using the full path to the source
+ // file which is its only unique identification.
+ const char* fullPath = source.GetFullPath().c_str();
+
+ // Try referencing the source relative to the source tree.
+ std::string relFromSource = this->Convert(fullPath, START);
+ assert(!relFromSource.empty());
+ bool relSource = !cmSystemTools::FileIsFullPath(relFromSource.c_str());
+ bool subSource = relSource && relFromSource[0] != '.';
+
+ // Try referencing the source relative to the binary tree.
+ std::string relFromBinary = this->Convert(fullPath, START_OUTPUT);
+ assert(!relFromBinary.empty());
+ bool relBinary = !cmSystemTools::FileIsFullPath(relFromBinary.c_str());
+ bool subBinary = relBinary && relFromBinary[0] != '.';
+
+ // Select a nice-looking reference to the source file to construct
+ // the object file name.
+ std::string objectName;
+ if((relSource && !relBinary) || (subSource && !subBinary))
+ {
+ objectName = relFromSource;
+ }
+ else if((relBinary && !relSource) || (subBinary && !subSource))
+ {
+ objectName = relFromBinary;
+ }
+ else if(relFromBinary.length() < relFromSource.length())
+ {
+ objectName = relFromBinary;
+ }
+ else
+ {
+ objectName = relFromSource;
+ }
+
+ // if it is still a full path check for the try compile case
+ // try compile never have in source sources, and should not
+ // have conflicting source file names in the same target
+ if(cmSystemTools::FileIsFullPath(objectName.c_str()))
+ {
+ if(this->GetGlobalGenerator()->GetCMakeInstance()->GetIsInTryCompile())
+ {
+ objectName = cmSystemTools::GetFilenameName(source.GetFullPath());
+ }
+ }
+
+ // Replace the original source file extension with the object file
+ // extension.
+ bool keptSourceExtension = true;
+ if(!source.GetPropertyAsBool("KEEP_EXTENSION"))
+ {
+ // 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);
+ if(!replaceExt)
+ {
+ if(const char* lang = source.GetLanguage())
+ {
+ std::string repVar = "CMAKE_";
+ repVar += lang;
+ repVar += "_OUTPUT_EXTENSION_REPLACE";
+ replaceExt = this->Makefile->IsOn(repVar.c_str());
+ }
+ }
+
+ // Remove the source extension if it is to be replaced.
+ if(replaceExt)
+ {
+ keptSourceExtension = false;
+ std::string::size_type dot_pos = objectName.rfind(".");
+ if(dot_pos != std::string::npos)
+ {
+ objectName = objectName.substr(0, dot_pos);
+ }
+ }
+
+ // Store the new extension.
+ objectName +=
+ this->GlobalGenerator->GetLanguageOutputExtension(source);
+ }
+ if(hasSourceExtension)
+ {
+ *hasSourceExtension = keptSourceExtension;
+ }
+
+ // Convert to a safe name.
+ return this->CreateSafeUniqueObjectFileName(objectName.c_str(), dir_max);
+}
+
+//----------------------------------------------------------------------------
+const char*
+cmLocalGenerator
+::GetSourceFileLanguage(const cmSourceFile& source)
+{
+ return source.GetLanguage();
+}
+
+//----------------------------------------------------------------------------
+std::string cmLocalGenerator::EscapeForShellOldStyle(const char* 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; *ch != '\0'; ++ch)
+ {
+ if(*ch == ' ')
+ {
+ result += '\\';
+ }
+ result += *ch;
+ }
+ return result;
+#endif
+}
+
+//----------------------------------------------------------------------------
+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;
+}
+
+//----------------------------------------------------------------------------
+std::string cmLocalGenerator::EscapeForShell(const char* str, bool makeVars,
+ bool forEcho)
+{
+ // 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]);
+}
+
+//----------------------------------------------------------------------------
+std::string cmLocalGenerator::EscapeForCMake(const char* str)
+{
+ // 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;
+}
+
+//----------------------------------------------------------------------------
+cmLocalGenerator::FortranFormat
+cmLocalGenerator::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;
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmLocalGenerator::GetTargetDirectory(cmTarget const&) const
+{
+ cmSystemTools::Error("GetTargetDirectory"
+ " called on cmLocalGenerator");
+ return "";
+}
+
+//----------------------------------------------------------------------------
+unsigned int cmLocalGenerator::GetBackwardsCompatibility()
+{
+ // The computed version may change until the project is fully
+ // configured.
+ if(!this->BackwardsCompatibilityFinal)
+ {
+ unsigned int major = 0;
+ unsigned int minor = 0;
+ unsigned int patch = 0;
+ if(const char* value
+ = this->Makefile->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY"))
+ {
+ switch(sscanf(value, "%u.%u.%u", &major, &minor, &patch))
+ {
+ case 2: patch = 0; break;
+ case 1: minor = 0; patch = 0; break;
+ default: break;
+ }
+ }
+ this->BackwardsCompatibility = CMake_VERSION_ENCODE(major, minor, patch);
+ this->BackwardsCompatibilityFinal = this->Configured;
+ }
+
+ return this->BackwardsCompatibility;
+}
+
+//----------------------------------------------------------------------------
+bool cmLocalGenerator::NeedBackwardsCompatibility(unsigned int major,
+ unsigned int minor,
+ unsigned int patch)
+{
+ // Check the policy to decide whether to pay attention to this
+ // variable.
+ switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0001))
+ {
+ case cmPolicies::WARN:
+ // WARN is just OLD without warning because user code does not
+ // always affect whether this check is done.
+ case cmPolicies::OLD:
+ // Old behavior is to check the variable.
+ break;
+ case cmPolicies::NEW:
+ // New behavior is to ignore the variable.
+ return false;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ // This will never be the case because the only way to require
+ // the setting is to require the user to specify version policy
+ // 2.6 or higher. Once we add that requirement then this whole
+ // method can be removed anyway.
+ return false;
+ }
+
+ // Compatibility is needed if CMAKE_BACKWARDS_COMPATIBILITY is set
+ // equal to or lower than the given version.
+ unsigned int actual_compat = this->GetBackwardsCompatibility();
+ return (actual_compat &&
+ actual_compat <= CMake_VERSION_ENCODE(major, minor, patch));
+}
+
+//----------------------------------------------------------------------------
+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;
+ }
+ }
+ 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;
+ e << "WARNING: Preprocessor definitions containing '#' 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;
+ }
+
+ // Assume it is supported.
+ return true;
+}
+
+//----------------------------------------------------------------------------
+static void cmLGInfoProp(cmMakefile* mf, cmTarget* target, const char* prop)
+{
+ if(const char* val = target->GetProperty(prop))
+ {
+ mf->AddDefinition(prop, val);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmLocalGenerator::GenerateAppleInfoPList(cmTarget* target,
+ const char* targetName,
+ const char* fname)
+{
+ // Find the Info.plist template.
+ const char* in = target->GetProperty("MACOSX_BUNDLE_INFO_PLIST");
+ std::string inFile = (in && *in)? in : "MacOSXBundleInfo.plist.in";
+ if(!cmSystemTools::FileIsFullPath(inFile.c_str()))
+ {
+ std::string inMod = this->Makefile->GetModulesFile(inFile.c_str());
+ if(!inMod.empty())
+ {
+ inFile = inMod;
+ }
+ }
+ if(!cmSystemTools::FileExists(inFile.c_str(), true))
+ {
+ cmOStringStream e;
+ e << "Target " << target->GetName() << " Info.plist template \""
+ << inFile << "\" could not be found.";
+ cmSystemTools::Error(e.str().c_str());
+ return;
+ }
+
+ // Convert target properties to variables in an isolated makefile
+ // scope to configure the file. If properties are set they will
+ // 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);
+ cmLGInfoProp(mf, target, "MACOSX_BUNDLE_INFO_STRING");
+ cmLGInfoProp(mf, target, "MACOSX_BUNDLE_ICON_FILE");
+ cmLGInfoProp(mf, target, "MACOSX_BUNDLE_GUI_IDENTIFIER");
+ cmLGInfoProp(mf, target, "MACOSX_BUNDLE_LONG_VERSION_STRING");
+ cmLGInfoProp(mf, target, "MACOSX_BUNDLE_BUNDLE_NAME");
+ cmLGInfoProp(mf, target, "MACOSX_BUNDLE_SHORT_VERSION_STRING");
+ 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)
+{
+ // Find the Info.plist template.
+ const char* in = target->GetProperty("MACOSX_FRAMEWORK_INFO_PLIST");
+ std::string inFile = (in && *in)? in : "MacOSXFrameworkInfo.plist.in";
+ if(!cmSystemTools::FileIsFullPath(inFile.c_str()))
+ {
+ std::string inMod = this->Makefile->GetModulesFile(inFile.c_str());
+ if(!inMod.empty())
+ {
+ inFile = inMod;
+ }
+ }
+ if(!cmSystemTools::FileExists(inFile.c_str(), true))
+ {
+ cmOStringStream e;
+ e << "Target " << target->GetName() << " Info.plist template \""
+ << inFile << "\" could not be found.";
+ cmSystemTools::Error(e.str().c_str());
+ return;
+ }
+
+ // Convert target properties to variables in an isolated makefile
+ // scope to configure the file. If properties are set they will
+ // 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);
+ 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
new file mode 100644
index 000000000..39b493fb1
--- /dev/null
+++ b/Source/cmLocalGenerator.h
@@ -0,0 +1,441 @@
+/*============================================================================
+ 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 cmLocalGenerator_h
+#define cmLocalGenerator_h
+
+#include "cmStandardIncludes.h"
+
+class cmMakefile;
+class cmGlobalGenerator;
+class cmTarget;
+class cmTargetManifest;
+class cmSourceFile;
+class cmCustomCommand;
+
+/** \class cmLocalGenerator
+ * \brief Create required build files for a directory.
+ *
+ * Subclasses of this abstract class generate makefiles, DSP, etc for various
+ * platforms. This class should never be constructed directly. A
+ * GlobalGenerator will create it and invoke the appropriate commands on it.
+ */
+class cmLocalGenerator
+{
+public:
+ cmLocalGenerator();
+ virtual ~cmLocalGenerator();
+
+ /**
+ * Generate the makefile for this directory.
+ */
+ virtual void Generate() {}
+
+ /**
+ * Process the CMakeLists files for this directory to fill in the
+ * Makefile ivar
+ */
+ virtual void Configure();
+
+ /**
+ * Calls TraceVSDependencies() on all targets of this generator.
+ */
+ virtual void TraceDependencies();
+
+ virtual void AddHelperCommands() {}
+
+ /**
+ * Perform any final calculations prior to generation
+ */
+ virtual void ConfigureFinalPass();
+
+ /**
+ * Generate the install rules files in this directory.
+ */
+ virtual void GenerateInstallRules();
+
+ /**
+ * Generate the test files for tests.
+ */
+ virtual void GenerateTestFiles();
+
+ /**
+ * Generate a manifest of target files that will be built.
+ */
+ virtual void GenerateTargetManifest();
+
+ ///! Get the makefile for this generator
+ cmMakefile *GetMakefile() {
+ return this->Makefile; };
+
+ ///! Get the makefile for this generator, const version
+ const cmMakefile *GetMakefile() const {
+ return this->Makefile; };
+
+ ///! Get the GlobalGenerator this is associated with
+ cmGlobalGenerator *GetGlobalGenerator() {
+ 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, cmTarget* 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);
+ void AddConfigVariableFlags(std::string& flags, const char* var,
+ const char* config);
+ ///! Append flags to a string.
+ virtual void AppendFlags(std::string& flags, const char* newFlags);
+ ///! Get the include flags for the current makefile and language
+ std::string GetIncludeFlags(const std::vector<std::string> &includes,
+ const char* lang, bool forResponseFile = false);
+
+ /**
+ * Encode a list of preprocessor definitions for the compiler
+ * command line.
+ */
+ void AppendDefines(std::string& defines, const char* defines_list,
+ const char* lang);
+
+ /** Lookup and append options associated with a particular feature. */
+ void AppendFeatureOptions(std::string& flags, const char* lang,
+ const char* feature);
+
+ /** \brief Get absolute path to dependency \a name
+ *
+ * Translate a dependency as given in CMake code to the name to
+ * appear in a generated build file.
+ * - If \a name is a utility target, returns false.
+ * - If \a name is a CMake target, it will be transformed to the real output
+ * location of that target for the given configuration.
+ * - If \a name is the full path to a file, it will be returned.
+ * - Otherwise \a name is treated as a relative path with respect to
+ * the source directory of this generator. This should only be
+ * used for dependencies of custom commands.
+ */
+ bool GetRealDependency(const char* name, const char* 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);
+
+ /** Called from command-line hook to clear dependencies. */
+ virtual void ClearDependencies(cmMakefile* /* mf */,
+ bool /* verbose */) {}
+
+ /** Called from command-line hook to update dependencies. */
+ virtual bool UpdateDependencies(const char* /* tgtInfo */,
+ bool /*verbose*/,
+ bool /*color*/)
+ { return true; }
+
+ /** Get the include flags for the current makefile and language. */
+ void GetIncludeDirectories(std::vector<std::string>& dirs,
+ cmTarget* target,
+ const char* lang = "C");
+
+ /** Compute the language used to compile the given source file. */
+ const char* 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>&) {}
+
+ // Create a struct to hold the varibles passed into
+ // ExpandRuleVariables
+ struct RuleVariables
+ {
+ RuleVariables()
+ {
+ memset(this, 0, sizeof(*this));
+ }
+ cmTarget* CMTarget;
+ const char* TargetPDB;
+ const char* TargetVersionMajor;
+ const char* TargetVersionMinor;
+ const char* Language;
+ const char* Objects;
+ const char* Target;
+ const char* LinkLibraries;
+ const char* Source;
+ const char* AssemblySource;
+ const char* PreprocessedSource;
+ const char* Output;
+ const char* Object;
+ const char* ObjectDir;
+ const char* Flags;
+ const char* ObjectsQuoted;
+ const char* SONameFlag;
+ const char* TargetSOName;
+ const char* TargetInstallNameDir;
+ const char* LinkFlags;
+ const char* LanguageCompileFlags;
+ const char* Defines;
+ const char* RuleLauncher;
+ const char* DependencyFile;
+ };
+
+ /** 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;
+
+ /**
+ * Get the level of backwards compatibility requested by the project
+ * in this directory. This is the value of the CMake variable
+ * CMAKE_BACKWARDS_COMPATIBILITY whose format is
+ * "major.minor[.patch]". The returned integer is encoded as
+ *
+ * CMake_VERSION_ENCODE(major, minor, patch)
+ *
+ * and is monotonically increasing with the CMake version.
+ */
+ unsigned int GetBackwardsCompatibility();
+
+ /**
+ * Test whether compatibility is set to a given version or lower.
+ */
+ bool NeedBackwardsCompatibility(unsigned int major,
+ unsigned int minor,
+ unsigned int patch = 0xFFu);
+
+ /**
+ * Generate a Mac OS X application bundle Info.plist file.
+ */
+ void GenerateAppleInfoPList(cmTarget* target, const char* targetName,
+ const char* fname);
+
+ /**
+ * Generate a Mac OS X framework Info.plist file.
+ */
+ void GenerateFrameworkInfoPList(cmTarget* target,
+ const char* targetName,
+ const char* fname);
+ /** Construct a comment for a custom command. */
+ std::string ConstructComment(const cmCustomCommand& cc,
+ const char* default_comment = "");
+ // Compute object file names.
+ std::string GetObjectFileNameWithoutTarget(const cmSourceFile& source,
+ std::string const& dir_max,
+ bool* hasSourceExtension = 0);
+
+ /** Fill out these strings for the given target. Libraries to link,
+ * flags, and linkflags. */
+ void GetTargetFlags(std::string& linkLibs,
+ std::string& flags,
+ std::string& linkFlags,
+ cmTarget&target);
+
+protected:
+ ///! put all the libraries for a target on into the given stream
+ virtual void OutputLinkLibraries(std::ostream&, cmTarget&, bool relink);
+
+ // Expand rule variables in CMake of the type found in language rules
+ void ExpandRuleVariables(std::string& string,
+ const RuleVariables& replaceValues);
+ // Expand rule variables in a single string
+ 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, cmTarget& 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,
+ cmTarget& 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&);
+
+ // Handle old-style install rules stored in the targets.
+ void GenerateTargetInstallRules(
+ std::ostream& os, const char* config,
+ std::vector<std::string> const& configurationTypes);
+
+ std::string& CreateSafeUniqueObjectFileName(const char* 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);
+
+ /** 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;
+ 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::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;
+ bool EmitUniversalBinaryFlags;
+ // A type flag is not nice. It's used only in TraceDependencies().
+ bool IsMakefileGenerator;
+ // 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;
+ bool BackwardsCompatibilityFinal;
+private:
+ std::string ConvertToOutputForExistingCommon(const char* remote,
+ std::string const& result);
+
+ void AddSharedFlags(std::string& flags, const char* lang, bool shared);
+ bool GetShouldUseOldFlags(bool shared, const std::string &lang) const;
+ void AddPositionIndependentFlags(std::string& flags, std::string const& l,
+ int targetType);
+};
+
+#endif
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
new file mode 100644
index 000000000..d902f4ef7
--- /dev/null
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -0,0 +1,395 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2011 Peter Collingbourne <peter@pcc.me.uk>
+ Copyright 2011 Nicolas Despres <nicolas.despres@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 "cmLocalNinjaGenerator.h"
+#include "cmCustomCommandGenerator.h"
+#include "cmMakefile.h"
+#include "cmGlobalNinjaGenerator.h"
+#include "cmNinjaTargetGenerator.h"
+#include "cmGeneratedFileStream.h"
+#include "cmSourceFile.h"
+#include "cmComputeLinkInformation.h"
+#include "cmake.h"
+
+#include <assert.h>
+
+cmLocalNinjaGenerator::cmLocalNinjaGenerator()
+ : cmLocalGenerator()
+ , ConfigName("")
+ , HomeRelativeOutputPath("")
+{
+ this->IsMakefileGenerator = true;
+#ifdef _WIN32
+ this->WindowsShell = true;
+#endif
+ this->TargetImplib = "$TARGET_IMPLIB";
+}
+
+//----------------------------------------------------------------------------
+// Virtual public methods.
+
+cmLocalNinjaGenerator::~cmLocalNinjaGenerator()
+{
+}
+
+void cmLocalNinjaGenerator::Generate()
+{
+ this->SetConfigName();
+
+ this->WriteProcessedMakefile(this->GetBuildFileStream());
+#ifdef NINJA_GEN_VERBOSE_FILES
+ this->WriteProcessedMakefile(this->GetRulesFileStream());
+#endif
+
+ this->WriteBuildFileTop();
+
+ cmTargets& targets = this->GetMakefile()->GetTargets();
+ for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t)
+ {
+ cmNinjaTargetGenerator* tg = cmNinjaTargetGenerator::New(&t->second);
+ 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);
+ delete tg;
+ }
+ }
+
+ 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
+{
+ std::string dir = cmake::GetCMakeFilesDirectoryPostSlash();
+ dir += target.GetName();
+#if defined(__VMS)
+ dir += "_dir";
+#else
+ dir += ".dir";
+#endif
+ return dir;
+}
+
+//----------------------------------------------------------------------------
+// Non-virtual public methods.
+
+const cmGlobalNinjaGenerator*
+cmLocalNinjaGenerator::GetGlobalNinjaGenerator() const
+{
+ return
+ static_cast<const cmGlobalNinjaGenerator*>(this->GetGlobalGenerator());
+}
+
+cmGlobalNinjaGenerator* cmLocalNinjaGenerator::GetGlobalNinjaGenerator()
+{
+ return static_cast<cmGlobalNinjaGenerator*>(this->GetGlobalGenerator());
+}
+
+//----------------------------------------------------------------------------
+// Virtual protected methods.
+
+std::string
+cmLocalNinjaGenerator::ConvertToLinkReference(std::string const& lib)
+{
+ return this->Convert(lib.c_str(), HOME_OUTPUT, SHELL);
+}
+
+std::string
+cmLocalNinjaGenerator::ConvertToIncludeReference(std::string const& path)
+{
+ return this->Convert(path.c_str(), HOME_OUTPUT, SHELL);
+}
+
+//----------------------------------------------------------------------------
+// Private methods.
+
+cmGeneratedFileStream& cmLocalNinjaGenerator::GetBuildFileStream() const
+{
+ return *this->GetGlobalNinjaGenerator()->GetBuildFileStream();
+}
+
+cmGeneratedFileStream& cmLocalNinjaGenerator::GetRulesFileStream() const
+{
+ return *this->GetGlobalNinjaGenerator()->GetRulesFileStream();
+}
+
+const cmake* cmLocalNinjaGenerator::GetCMakeInstance() const
+{
+ return this->GetGlobalGenerator()->GetCMakeInstance();
+}
+
+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->WriteNinjaFilesInclusion(this->GetBuildFileStream());
+
+ // For the rule file.
+ this->WriteProjectHeader(this->GetRulesFileStream());
+}
+
+void cmLocalNinjaGenerator::WriteProjectHeader(std::ostream& os)
+{
+ cmGlobalNinjaGenerator::WriteDivider(os);
+ os
+ << "# Project: " << this->GetMakefile()->GetProjectName() << std::endl
+ << "# Configuration: " << this->ConfigName << std::endl
+ ;
+ cmGlobalNinjaGenerator::WriteDivider(os);
+}
+
+void cmLocalNinjaGenerator::WriteNinjaFilesInclusion(std::ostream& os)
+{
+ cmGlobalNinjaGenerator::WriteDivider(os);
+ os
+ << "# Include auxiliary files.\n"
+ << "\n"
+ ;
+ cmGlobalNinjaGenerator::WriteInclude(os,
+ cmGlobalNinjaGenerator::NINJA_RULES_FILE,
+ "Include rules file.");
+ os << "\n";
+}
+
+void cmLocalNinjaGenerator::SetConfigName()
+{
+ // Store the configuration name that will be generated.
+ if(const char* config =
+ this->GetMakefile()->GetDefinition("CMAKE_BUILD_TYPE"))
+ {
+ // Use the build type given by the user.
+ this->ConfigName = config;
+ }
+ else
+ {
+ // No configuration type given.
+ this->ConfigName = "";
+ }
+}
+
+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())
+ 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)
+{
+ this->GetGlobalNinjaGenerator()->AppendTargetOutputs(target, outputs);
+}
+
+void
+cmLocalNinjaGenerator
+::AppendTargetDepends(cmTarget* target, cmNinjaDeps& outputs)
+{
+ this->GetGlobalNinjaGenerator()->AppendTargetDepends(target, outputs);
+}
+
+void cmLocalNinjaGenerator::AppendCustomCommandDeps(const cmCustomCommand *cc,
+ cmNinjaDeps &ninjaDeps)
+{
+ const std::vector<std::string> &deps = cc->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()));
+ }
+}
+
+std::string cmLocalNinjaGenerator::BuildCommandLine(
+ const std::vector<std::string> &cmdLines)
+{
+ // If we have no commands but we need to build a command anyway, use ":".
+ // This happens when building a POST_BUILD value for link targets that
+ // don't use POST_BUILD.
+ if (cmdLines.empty())
+#ifdef _WIN32
+ return "cd .";
+#else
+ return ":";
+#endif
+
+ cmOStringStream cmd;
+ for (std::vector<std::string>::const_iterator li = cmdLines.begin();
+ li != cmdLines.end(); ++li) {
+ if (li != cmdLines.begin()) {
+ cmd << " && ";
+#ifdef _WIN32
+ } else if (cmdLines.size() > 1) {
+ cmd << "cmd.exe /c ";
+#endif
+ }
+ cmd << *li;
+ }
+ return cmd.str();
+}
+
+void cmLocalNinjaGenerator::AppendCustomCommandLines(const cmCustomCommand *cc,
+ 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();
+
+ cmOStringStream cdCmd;
+ cdCmd << "cd " << this->ConvertToOutputFormat(wd, SHELL);
+ cmdLines.push_back(cdCmd.str());
+ }
+ for (unsigned i = 0; i != ccg.GetNumberOfCommands(); ++i) {
+ cmdLines.push_back(this->ConvertToOutputFormat(ccg.GetCommand(i).c_str(),
+ SHELL));
+ std::string& cmd = cmdLines.back();
+ ccg.AppendArguments(i, cmd);
+ }
+}
+
+void
+cmLocalNinjaGenerator::WriteCustomCommandBuildStatement(
+ cmCustomCommand const *cc, const cmNinjaDeps& orderOnlyDeps)
+{
+ if (this->GetGlobalNinjaGenerator()->SeenCustomCommand(cc))
+ return;
+
+ const std::vector<std::string> &outputs = cc->GetOutputs();
+ cmNinjaDeps ninjaOutputs(outputs.size()), ninjaDeps;
+
+ std::transform(outputs.begin(), outputs.end(),
+ ninjaOutputs.begin(), MapToNinjaPath());
+ this->AppendCustomCommandDeps(cc, ninjaDeps);
+
+ for (cmNinjaDeps::iterator i = ninjaOutputs.begin(); i != ninjaOutputs.end();
+ ++i)
+ this->GetGlobalNinjaGenerator()->SeenCustomCommandOutput(*i);
+
+ std::vector<std::string> cmdLines;
+ this->AppendCustomCommandLines(cc, cmdLines);
+
+ if (cmdLines.empty()) {
+ cmGlobalNinjaGenerator::WritePhonyBuild(this->GetBuildFileStream(),
+ "Phony custom command for " +
+ ninjaOutputs[0],
+ ninjaOutputs,
+ ninjaDeps,
+ cmNinjaDeps(),
+ orderOnlyDeps,
+ cmNinjaVars());
+ } else {
+ this->GetGlobalNinjaGenerator()->WriteCustomCommandBuild(
+ this->BuildCommandLine(cmdLines),
+ this->ConstructComment(*cc),
+ "Custom command for " + ninjaOutputs[0],
+ ninjaOutputs,
+ ninjaDeps,
+ orderOnlyDeps);
+ }
+}
+
+void cmLocalNinjaGenerator::AddCustomCommandTarget(cmCustomCommand const* cc,
+ cmTarget* target)
+{
+ this->CustomCommandTargets[cc].insert(target);
+}
+
+void cmLocalNinjaGenerator::WriteCustomCommandBuildStatements()
+{
+ for (CustomCommandTargetMap::iterator i = this->CustomCommandTargets.begin();
+ i != this->CustomCommandTargets.end(); ++i) {
+ // A custom command may appear on multiple targets. However, some build
+ // systems exist where the target dependencies on some of the targets are
+ // overspecified, leading to a dependency cycle. If we assume all target
+ // dependencies are a superset of the true target dependencies for this
+ // custom command, we can take the set intersection of all target
+ // dependencies to obtain a correct dependency list.
+ //
+ // FIXME: This won't work in certain obscure scenarios involving indirect
+ // dependencies.
+ std::set<cmTarget*>::iterator j = i->second.begin();
+ assert(j != i->second.end());
+ std::vector<std::string> ccTargetDeps;
+ this->AppendTargetDepends(*j, ccTargetDeps);
+ std::sort(ccTargetDeps.begin(), ccTargetDeps.end());
+ ++j;
+
+ for (; j != i->second.end(); ++j) {
+ std::vector<std::string> jDeps, depsIntersection;
+ this->AppendTargetDepends(*j, jDeps);
+ std::sort(jDeps.begin(), jDeps.end());
+ std::set_intersection(ccTargetDeps.begin(), ccTargetDeps.end(),
+ jDeps.begin(), jDeps.end(),
+ std::back_inserter(depsIntersection));
+ ccTargetDeps = depsIntersection;
+ }
+
+ this->WriteCustomCommandBuildStatement(i->first, ccTargetDeps);
+ }
+}
diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h
new file mode 100644
index 000000000..c450841af
--- /dev/null
+++ b/Source/cmLocalNinjaGenerator.h
@@ -0,0 +1,133 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2011 Peter Collingbourne <peter@pcc.me.uk>
+ Copyright 2011 Nicolas Despres <nicolas.despres@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 cmLocalNinjaGenerator_h
+# define cmLocalNinjaGenerator_h
+
+# include "cmLocalGenerator.h"
+# include "cmNinjaTypes.h"
+
+class cmGlobalNinjaGenerator;
+class cmGeneratedFileStream;
+class cmake;
+
+/**
+ * \class cmLocalNinjaGenerator
+ * \brief Write a local build.ninja file.
+ *
+ * cmLocalNinjaGenerator produces a local build.ninja file from its
+ * member Makefile.
+ */
+class cmLocalNinjaGenerator : public cmLocalGenerator
+{
+public:
+ /// Default constructor.
+ cmLocalNinjaGenerator();
+
+ /// 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;
+
+ 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);
+ }
+
+ std::string BuildCommandLine(const std::vector<std::string> &cmdLines);
+
+ void AppendTargetOutputs(cmTarget* target, cmNinjaDeps& outputs);
+ void AppendTargetDepends(cmTarget* target, cmNinjaDeps& outputs);
+
+ void AddCustomCommandTarget(cmCustomCommand const* cc, cmTarget* target);
+ void AppendCustomCommandLines(const cmCustomCommand *cc,
+ std::vector<std::string> &cmdLines);
+ void AppendCustomCommandDeps(const cmCustomCommand *cc,
+ cmNinjaDeps &ninjaDeps);
+
+ virtual std::string ConvertToLinkReference(std::string const& lib);
+
+
+protected:
+ virtual std::string ConvertToIncludeReference(std::string const& path);
+
+
+private:
+ cmGeneratedFileStream& GetBuildFileStream() const;
+ cmGeneratedFileStream& GetRulesFileStream() const;
+
+ void WriteBuildFileTop();
+ void WriteProjectHeader(std::ostream& os);
+ void WriteNinjaFilesInclusion(std::ostream& os);
+ void WriteProcessedMakefile(std::ostream& os);
+
+ void SetConfigName();
+
+ void WriteCustomCommandRule();
+ void WriteCustomCommandBuildStatement(cmCustomCommand const *cc,
+ const cmNinjaDeps& orderOnlyDeps);
+
+ void WriteCustomCommandBuildStatements();
+
+
+ std::string ConfigName;
+ std::string HomeRelativeOutputPath;
+
+ typedef std::map<cmCustomCommand const*, std::set<cmTarget*> >
+ CustomCommandTargetMap;
+ CustomCommandTargetMap CustomCommandTargets;
+};
+
+#endif // ! cmLocalNinjaGenerator_h
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
new file mode 100644
index 000000000..db93529dd
--- /dev/null
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -0,0 +1,2258 @@
+/*============================================================================
+ 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 "cmLocalUnixMakefileGenerator3.h"
+
+#include "cmGeneratedFileStream.h"
+#include "cmGlobalUnixMakefileGenerator3.h"
+#include "cmMakefile.h"
+#include "cmMakefileTargetGenerator.h"
+#include "cmSourceFile.h"
+#include "cmake.h"
+#include "cmVersion.h"
+#include "cmFileTimeComparison.h"
+#include "cmCustomCommandGenerator.h"
+
+// Include dependency scanners for supported languages. Only the
+// C/C++ scanner is needed for bootstrapping CMake.
+#include "cmDependsC.h"
+#ifdef CMAKE_BUILD_WITH_CMAKE
+# include "cmDependsFortran.h"
+# include "cmDependsJava.h"
+# include <cmsys/Terminal.h>
+#endif
+
+#include <cmsys/auto_ptr.hxx>
+
+#include <memory> // auto_ptr
+#include <queue>
+
+//----------------------------------------------------------------------------
+// Escape special characters in Makefile dependency lines
+class cmMakeSafe
+{
+public:
+ cmMakeSafe(const char* s): Data(s) {}
+ cmMakeSafe(std::string const& s): Data(s.c_str()) {}
+private:
+ const char* Data;
+ friend std::ostream& operator<<(std::ostream& os,
+ cmMakeSafe const& self)
+ {
+ for(const char* c = self.Data; *c; ++c)
+ {
+ switch (*c)
+ {
+ case '=': os << "$(EQUALS)"; break;
+ default: os << *c; break;
+ }
+ }
+ return os;
+ }
+};
+
+//----------------------------------------------------------------------------
+// Helper function used below.
+static std::string cmSplitExtension(std::string const& in, std::string& base)
+{
+ std::string ext;
+ std::string::size_type dot_pos = in.rfind(".");
+ if(dot_pos != std::string::npos)
+ {
+ // Remove the extension first in case &base == &in.
+ ext = in.substr(dot_pos, std::string::npos);
+ base = in.substr(0, dot_pos);
+ }
+ else
+ {
+ base = in;
+ }
+ return ext;
+}
+
+//----------------------------------------------------------------------------
+cmLocalUnixMakefileGenerator3::cmLocalUnixMakefileGenerator3()
+{
+ 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;
+ this->MakeCommandEscapeTargetTwice = false;
+ this->IsMakefileGenerator = true;
+ this->BorlandMakeCurlyHack = false;
+}
+
+//----------------------------------------------------------------------------
+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 = "";
+ }
+
+ // Record whether some options are enabled to avoid checking many
+ // times later.
+ if(!this->GetGlobalGenerator()->GetCMakeInstance()->GetIsInTryCompile())
+ {
+ this->ColorMakefile = this->Makefile->IsOn("CMAKE_COLOR_MAKEFILE");
+ }
+ this->SkipPreprocessedSourceRules =
+ this->Makefile->IsOn("CMAKE_SKIP_PREPROCESSED_SOURCE_RULES");
+ this->SkipAssemblySourceRules =
+ this->Makefile->IsOn("CMAKE_SKIP_ASSEMBLY_SOURCE_RULES");
+
+ // Generate the rule files for each target.
+ cmTargets& targets = this->Makefile->GetTargets();
+ cmGlobalUnixMakefileGenerator3* gg =
+ static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
+ for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t)
+ {
+ cmsys::auto_ptr<cmMakefileTargetGenerator> tg(
+ cmMakefileTargetGenerator::New(&(t->second)));
+ if (tg.get())
+ {
+ tg->WriteRuleFiles();
+ gg->RecordTargetProgress(tg.get());
+ }
+ }
+
+ // write the local Makefile
+ this->WriteLocalMakefile();
+
+ // Write the cmake file with information for this directory.
+ this->WriteDirectoryInformationFile();
+}
+
+//----------------------------------------------------------------------------
+void cmLocalUnixMakefileGenerator3::AddLocalObjectFile(
+ cmTarget* target, cmSourceFile* sf, std::string objNoTargetDir,
+ bool hasSourceExtension)
+{
+ if(cmSystemTools::FileIsFullPath(objNoTargetDir.c_str()))
+ {
+ objNoTargetDir = cmSystemTools::GetFilenameName(objNoTargetDir);
+ }
+ 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)
+ {
+ targets.push_back(lo->first);
+
+ std::string::size_type dot_pos = lo->first.rfind(".");
+ std::string base = lo->first.substr(0, dot_pos);
+ if(lo->second.HasPreprocessRule)
+ {
+ targets.push_back(base + ".i");
+ }
+
+ if(lo->second.HasAssembleRule)
+ {
+ targets.push_back(base + ".s");
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmLocalUnixMakefileGenerator3::WriteLocalMakefile()
+{
+ // generate the includes
+ std::string ruleFileName = "Makefile";
+
+ // Open the rule file. This should be copy-if-different because the
+ // rules may depend on this file itself.
+ std::string ruleFileNameFull = this->ConvertToFullPath(ruleFileName);
+ cmGeneratedFileStream ruleFileStream(ruleFileNameFull.c_str());
+ if(!ruleFileStream)
+ {
+ return;
+ }
+ // always write the top makefile
+ if (this->Parent)
+ {
+ ruleFileStream.SetCopyIfDifferent(true);
+ }
+
+ // write the all rules
+ this->WriteLocalAllRules(ruleFileStream);
+
+ // only write local targets unless at the top Keep track of targets already
+ // listed.
+ std::set<cmStdString> emittedTargets;
+ if (this->Parent)
+ {
+ // write our targets, and while doing it collect up the object
+ // file rules
+ this->WriteLocalMakefileTargets(ruleFileStream,emittedTargets);
+ }
+ else
+ {
+ cmGlobalUnixMakefileGenerator3 *gg =
+ static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
+ gg->WriteConvenienceRules(ruleFileStream,emittedTargets);
+ }
+
+ bool do_preprocess_rules =
+ this->GetCreatePreprocessedSourceRules();
+ bool do_assembly_rules =
+ this->GetCreateAssemblySourceRules();
+
+ // 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)
+ {
+ // Add a convenience rule for building the object file.
+ this->WriteObjectConvenienceRule(ruleFileStream,
+ "target to build an object file",
+ lo->first.c_str(), lo->second);
+
+ // Check whether preprocessing and assembly rules make sense.
+ // They make sense only for C and C++ sources.
+ bool lang_is_c_or_cxx = false;
+ for(std::vector<LocalObjectEntry>::const_iterator ei =
+ lo->second.begin(); ei != lo->second.end(); ++ei)
+ {
+ if(ei->Language == "C" || ei->Language == "CXX")
+ {
+ lang_is_c_or_cxx = true;
+ break;
+ }
+ }
+
+ // Add convenience rules for preprocessed and assembly files.
+ if(lang_is_c_or_cxx && (do_preprocess_rules || do_assembly_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;
+ }
+ }
+ }
+
+ // add a help target as long as there isn;t a real target named help
+ if(emittedTargets.insert("help").second)
+ {
+ cmGlobalUnixMakefileGenerator3 *gg =
+ static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
+ gg->WriteHelpRule(ruleFileStream,this);
+ }
+
+ this->WriteSpecialTargetsBottom(ruleFileStream);
+}
+
+//----------------------------------------------------------------------------
+void
+cmLocalUnixMakefileGenerator3
+::WriteObjectConvenienceRule(std::ostream& ruleFileStream,
+ const char* comment, const char* output,
+ LocalObjectInfo const& info)
+{
+ // If the rule includes the source file extension then create a
+ // version that has the extension removed. The help should include
+ // only the version without source extension.
+ bool inHelp = true;
+ if(info.HasSourceExtension)
+ {
+ // Remove the last extension. This should be kept.
+ std::string outBase1 = output;
+ std::string outExt1 = cmSplitExtension(outBase1, outBase1);
+
+ // Now remove the source extension and put back the last
+ // extension.
+ std::string outNoExt;
+ cmSplitExtension(outBase1, outNoExt);
+ outNoExt += outExt1;
+
+ // Add a rule to drive the rule below.
+ std::vector<std::string> depends;
+ depends.push_back(output);
+ std::vector<std::string> no_commands;
+ this->WriteMakeRule(ruleFileStream, 0,
+ outNoExt.c_str(), depends, no_commands, true, true);
+ inHelp = false;
+ }
+
+ // Recursively make the rule for each target using the object file.
+ std::vector<std::string> commands;
+ for(std::vector<LocalObjectEntry>::const_iterator t = info.begin();
+ t != info.end(); ++t)
+ {
+ std::string tgtMakefileName =
+ 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->CreateCDCommand(commands,
+ this->Makefile->GetHomeOutputDirectory(),
+ cmLocalGenerator::START_OUTPUT);
+
+ // Write the rule to the makefile.
+ std::vector<std::string> no_depends;
+ this->WriteMakeRule(ruleFileStream, comment,
+ output, no_depends, commands, true, inHelp);
+}
+
+//----------------------------------------------------------------------------
+void cmLocalUnixMakefileGenerator3
+::WriteLocalMakefileTargets(std::ostream& ruleFileStream,
+ std::set<cmStdString> &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::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))
+ {
+ emitted.insert(t->second.GetName());
+
+ // for subdirs add a rule to build this specific target by name.
+ localName = this->GetRelativeTargetDirectory(t->second);
+ localName += "/rule";
+ commands.clear();
+ depends.clear();
+
+ // Build the target for this pass.
+ std::string makefile2 = cmake::GetCMakeFilesDirectoryPostSlash();
+ makefile2 += "Makefile2";
+ commands.push_back(this->GetRecursiveMakeCall
+ (makefile2.c_str(),localName.c_str()));
+ this->CreateCDCommand(commands,
+ this->Makefile->GetHomeOutputDirectory(),
+ cmLocalGenerator::START_OUTPUT);
+ this->WriteMakeRule(ruleFileStream, "Convenience name for target.",
+ localName.c_str(), depends, commands, true);
+
+ // Add a target with the canonical name (no prefix, suffix or path).
+ if(localName != t->second.GetName())
+ {
+ commands.clear();
+ depends.push_back(localName);
+ this->WriteMakeRule(ruleFileStream, "Convenience name for target.",
+ t->second.GetName(), depends, commands, true);
+ }
+
+ // Add a fast rule to build the target
+ std::string makefileName = this->GetRelativeTargetDirectory(t->second);
+ makefileName += "/build.make";
+ // make sure the makefile name is suitable for a makefile
+ std::string makeTargetName =
+ this->GetRelativeTargetDirectory(t->second);
+ makeTargetName += "/build";
+ localName = t->second.GetName();
+ localName += "/fast";
+ depends.clear();
+ commands.clear();
+ commands.push_back(this->GetRecursiveMakeCall
+ (makefileName.c_str(), makeTargetName.c_str()));
+ this->CreateCDCommand(commands,
+ this->Makefile->GetHomeOutputDirectory(),
+ cmLocalGenerator::START_OUTPUT);
+ this->WriteMakeRule(ruleFileStream, "fast build rule for target.",
+ localName.c_str(), depends, commands, true);
+
+ // Add a local name for the rule to relink the target before
+ // installation.
+ if(t->second.NeedRelinkBeforeInstall(this->ConfigurationName.c_str()))
+ {
+ makeTargetName = this->GetRelativeTargetDirectory(t->second);
+ makeTargetName += "/preinstall";
+ localName = t->second.GetName();
+ localName += "/preinstall";
+ depends.clear();
+ commands.clear();
+ commands.push_back(this->GetRecursiveMakeCall
+ (makefile2.c_str(), makeTargetName.c_str()));
+ this->CreateCDCommand(commands,
+ this->Makefile->GetHomeOutputDirectory(),
+ cmLocalGenerator::START_OUTPUT);
+ this->WriteMakeRule(ruleFileStream,
+ "Manual pre-install relink rule for target.",
+ localName.c_str(), depends, commands, true);
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmLocalUnixMakefileGenerator3::WriteDirectoryInformationFile()
+{
+ std::string infoFileName = this->Makefile->GetStartOutputDirectory();
+ infoFileName += cmake::GetCMakeFilesDirectory();
+ infoFileName += "/CMakeDirectoryInformation.cmake";
+
+ // Open the output file.
+ cmGeneratedFileStream infoFileStream(infoFileName.c_str());
+ if(!infoFileStream)
+ {
+ return;
+ }
+
+ infoFileStream.SetCopyIfDifferent(true);
+ // Write the do not edit header.
+ this->WriteDisclaimer(infoFileStream);
+
+ // Setup relative path conversion tops.
+ infoFileStream
+ << "# Relative path conversion top directories.\n"
+ << "SET(CMAKE_RELATIVE_PATH_TOP_SOURCE \"" << this->RelativePathTopSource
+ << "\")\n"
+ << "SET(CMAKE_RELATIVE_PATH_TOP_BINARY \"" << this->RelativePathTopBinary
+ << "\")\n"
+ << "\n";
+
+ // Tell the dependency scanner to use unix paths if necessary.
+ if(cmSystemTools::GetForceUnixPaths())
+ {
+ infoFileStream
+ << "# Force unix paths in dependencies.\n"
+ << "SET(CMAKE_FORCE_UNIX_PATHS 1)\n"
+ << "\n";
+ }
+
+ // Store the include regular expressions for this directory.
+ infoFileStream
+ << "\n"
+ << "# The C and CXX include file regular expressions for "
+ << "this directory.\n";
+ infoFileStream
+ << "SET(CMAKE_C_INCLUDE_REGEX_SCAN ";
+ this->WriteCMakeArgument(infoFileStream,
+ this->Makefile->GetIncludeRegularExpression());
+ infoFileStream
+ << ")\n";
+ infoFileStream
+ << "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";
+ infoFileStream
+ << "SET(CMAKE_CXX_INCLUDE_REGEX_COMPLAIN "
+ "${CMAKE_C_INCLUDE_REGEX_COMPLAIN})\n";
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmLocalUnixMakefileGenerator3
+::ConvertToFullPath(const std::string& localPath)
+{
+ std::string dir = this->Makefile->GetStartOutputDirectory();
+ dir += "/";
+ dir += localPath;
+ return dir;
+}
+
+
+const std::string &cmLocalUnixMakefileGenerator3::GetHomeRelativeOutputPath()
+{
+ return this->HomeRelativeOutputPath;
+}
+
+
+//----------------------------------------------------------------------------
+void
+cmLocalUnixMakefileGenerator3
+::WriteMakeRule(std::ostream& os,
+ const char* comment,
+ const char* 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)
+ {
+ cmSystemTools::Error("No target for WriteMakeRule! called with comment: ",
+ comment);
+ return;
+ }
+
+ std::string replace;
+
+ // Write the comment describing the rule in the makefile.
+ if(comment)
+ {
+ replace = comment;
+ std::string::size_type lpos = 0;
+ std::string::size_type rpos;
+ while((rpos = replace.find('\n', lpos)) != std::string::npos)
+ {
+ os << "# " << replace.substr(lpos, rpos-lpos) << "\n";
+ lpos = rpos+1;
+ }
+ os << "# " << replace.substr(lpos) << "\n";
+ }
+
+ // Construct the left hand side of the rule.
+ replace = target;
+ std::string tgt = this->Convert(replace.c_str(),HOME_OUTPUT,MAKEFILE);
+ const char* space = "";
+ if(tgt.size() == 1)
+ {
+ // Add a space before the ":" to avoid drive letter confusion on
+ // Windows.
+ space = " ";
+ }
+
+ // Mark the rule as symbolic if requested.
+ if(symbolic)
+ {
+ if(const char* sym =
+ this->Makefile->GetDefinition("CMAKE_MAKE_SYMBOLIC_RULE"))
+ {
+ os << cmMakeSafe(tgt) << space << ": " << sym << "\n";
+ }
+ }
+
+ // Write the rule.
+ if(depends.empty())
+ {
+ // No dependencies. The commands will always run.
+ os << cmMakeSafe(tgt) << space << ":\n";
+ }
+ else
+ {
+ // Split dependencies into multiple rule lines. This allows for
+ // very long dependency lists even on older make implementations.
+ for(std::vector<std::string>::const_iterator dep = depends.begin();
+ dep != depends.end(); ++dep)
+ {
+ replace = *dep;
+ replace = this->Convert(replace.c_str(),HOME_OUTPUT,MAKEFILE);
+ 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 << ".PHONY : " << cmMakeSafe(tgt) << "\n";
+ }
+ os << "\n";
+ // Add the output to the local help if requested.
+ if(in_help)
+ {
+ this->LocalHelp.push_back(target);
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmLocalUnixMakefileGenerator3
+::ConvertShellCommand(std::string const& cmd, RelativeRoot root)
+{
+ if(this->WatcomWMake &&
+ cmSystemTools::FileIsFullPath(cmd.c_str()) &&
+ cmd.find_first_of("( )") != cmd.npos)
+ {
+ // On Watcom WMake use the windows short path for the command
+ // 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))
+ {
+ return this->Convert(scmd.c_str(), NONE, SHELL);
+ }
+ }
+ return this->Convert(cmd.c_str(), root, SHELL);
+}
+
+//----------------------------------------------------------------------------
+void
+cmLocalUnixMakefileGenerator3
+::WriteMakeVariables(std::ostream& makefileStream)
+{
+ this->WriteDivider(makefileStream);
+ makefileStream
+ << "# Set environment variables for the build.\n"
+ << "\n";
+ if(this->DefineWindowsNULL)
+ {
+ makefileStream
+ << "!IF \"$(OS)\" == \"Windows_NT\"\n"
+ << "NULL=\n"
+ << "!ELSE\n"
+ << "NULL=nul\n"
+ << "!ENDIF\n";
+ }
+ if(this->WindowsShell)
+ {
+ makefileStream
+ << "SHELL = cmd.exe\n"
+ << "\n";
+ }
+ else
+ {
+#if !defined(__VMS)
+ makefileStream
+ << "# The shell in which to execute make rules.\n"
+ << "SHELL = /bin/sh\n"
+ << "\n";
+#endif
+ }
+
+ std::string cmakecommand =
+ this->Makefile->GetRequiredDefinition("CMAKE_COMMAND");
+ makefileStream
+ << "# The CMake executable.\n"
+ << "CMAKE_COMMAND = "
+ << this->ConvertShellCommand(cmakecommand, FULL)
+ << "\n"
+ << "\n";
+ makefileStream
+ << "# The command to remove a file.\n"
+ << "RM = "
+ << this->ConvertShellCommand(cmakecommand, 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)
+ << "\n"
+ << "\n";
+ makefileStream
+ << "# The top-level build directory on which CMake was run.\n"
+ << "CMAKE_BINARY_DIR = "
+ << this->Convert(this->Makefile->GetHomeOutputDirectory(), FULL, SHELL)
+ << "\n"
+ << "\n";
+}
+
+//----------------------------------------------------------------------------
+void
+cmLocalUnixMakefileGenerator3
+::WriteSpecialTargetsTop(std::ostream& makefileStream)
+{
+ this->WriteDivider(makefileStream);
+ makefileStream
+ << "# Special targets provided by cmake.\n"
+ << "\n";
+
+ std::vector<std::string> no_commands;
+ std::vector<std::string> no_depends;
+
+ // Special target to cleanup operation of make tool.
+ // This should be the first target except for the default_target in
+ // the interface Makefile.
+ this->WriteMakeRule(
+ makefileStream, "Disable implicit rules so canonical targets will work.",
+ ".SUFFIXES", no_depends, no_commands, false);
+
+ if(!this->NMake && !this->WatcomWMake && !this->BorlandMakeCurlyHack)
+ {
+ // turn off RCS and SCCS automatic stuff from gmake
+ makefileStream
+ << "# Remove some rules from gmake that .SUFFIXES does not remove.\n"
+ << "SUFFIXES =\n\n";
+ }
+ // Add a fake suffix to keep HP happy. Must be max 32 chars for SGI make.
+ std::vector<std::string> depends;
+ 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->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE"))
+ {
+ makefileStream
+ << "# Produce verbose output by default.\n"
+ << "VERBOSE = 1\n"
+ << "\n";
+ }
+ if(this->SilentNoColon)
+ {
+ makefileStream << "$(VERBOSE).SILENT\n";
+ }
+ else
+ {
+ this->WriteMakeRule(makefileStream,
+ "Suppress display of executed commands.",
+ "$(VERBOSE).SILENT",
+ no_depends,
+ no_commands, false);
+ }
+
+ // Work-around for makes that drop rules that have no dependencies
+ // or commands.
+ std::string hack = gg->GetEmptyRuleHackDepends();
+ if(!hack.empty())
+ {
+ no_depends.push_back(hack);
+ }
+ std::string hack_cmd = gg->GetEmptyRuleHackCommand();
+ if(!hack_cmd.empty())
+ {
+ no_commands.push_back(hack_cmd);
+ }
+
+ // Special symbolic target that never exists to force dependers to
+ // run their rules.
+ this->WriteMakeRule
+ (makefileStream,
+ "A target that is always out of date.",
+ "cmake_force", no_depends, no_commands, true);
+
+ // Variables for reference by other rules.
+ this->WriteMakeVariables(makefileStream);
+}
+
+//----------------------------------------------------------------------------
+void cmLocalUnixMakefileGenerator3
+::WriteSpecialTargetsBottom(std::ostream& makefileStream)
+{
+ this->WriteDivider(makefileStream);
+ makefileStream
+ << "# Special targets to cleanup operation of make.\n"
+ << "\n";
+
+ // Write special "cmake_check_build_system" target to run cmake with
+ // the --check-build-system flag.
+ {
+ // Build command to run CMake to check if anything needs regenerating.
+ std::string cmakefileName = cmake::GetCMakeFilesDirectoryPostSlash();
+ cmakefileName += "Makefile.cmake";
+ 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 += " 0";
+
+ std::vector<std::string> no_depends;
+ std::vector<std::string> commands;
+ commands.push_back(runRule);
+ if(this->Parent)
+ {
+ this->CreateCDCommand(commands,
+ this->Makefile->GetHomeOutputDirectory(),
+ cmLocalGenerator::START_OUTPUT);
+ }
+ this->WriteMakeRule(makefileStream,
+ "Special rule to run CMake to check the build system "
+ "integrity.\n"
+ "No rule that depends on this can have "
+ "commands that come from listfiles\n"
+ "because they might be regenerated.",
+ "cmake_check_build_system",
+ no_depends,
+ commands, true);
+ }
+}
+
+
+
+//----------------------------------------------------------------------------
+void
+cmLocalUnixMakefileGenerator3
+::WriteConvenienceRule(std::ostream& ruleFileStream,
+ const char* realTarget,
+ const char* helpTarget)
+{
+ // A rule is only needed if the names are different.
+ if(strcmp(realTarget, helpTarget) != 0)
+ {
+ // The helper target depends on the real target.
+ std::vector<std::string> depends;
+ depends.push_back(realTarget);
+
+ // There are no commands.
+ std::vector<std::string> no_commands;
+
+ // Write the rule.
+ this->WriteMakeRule(ruleFileStream, "Convenience name for target.",
+ helpTarget, depends, no_commands, true);
+ }
+}
+
+
+//----------------------------------------------------------------------------
+std::string
+cmLocalUnixMakefileGenerator3
+::GetRelativeTargetDirectory(cmTarget const& target)
+{
+ std::string dir = this->HomeRelativeOutputPath;
+ dir += this->GetTargetDirectory(target);
+ return this->Convert(dir.c_str(),NONE,UNCHANGED);
+}
+
+
+
+//----------------------------------------------------------------------------
+void cmLocalUnixMakefileGenerator3::AppendFlags(std::string& flags,
+ const char* newFlags)
+{
+ if(this->WatcomWMake && newFlags && *newFlags)
+ {
+ std::string newf = newFlags;
+ if(newf.find("\\\"") != newf.npos)
+ {
+ cmSystemTools::ReplaceString(newf, "\\\"", "\"");
+ this->cmLocalGenerator::AppendFlags(flags, newf.c_str());
+ return;
+ }
+ }
+ this->cmLocalGenerator::AppendFlags(flags, newFlags);
+}
+
+//----------------------------------------------------------------------------
+void
+cmLocalUnixMakefileGenerator3
+::AppendRuleDepend(std::vector<std::string>& depends,
+ const char* ruleFileName)
+{
+ // Add a dependency on the rule file itself unless an option to skip
+ // it is specifically enabled by the user or project.
+ const char* nodep =
+ this->Makefile->GetDefinition("CMAKE_SKIP_RULE_DEPENDENCY");
+ if(!nodep || cmSystemTools::IsOff(nodep))
+ {
+ depends.push_back(ruleFileName);
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmLocalUnixMakefileGenerator3
+::AppendRuleDepends(std::vector<std::string>& depends,
+ std::vector<std::string> const& ruleFiles)
+{
+ // Add a dependency on the rule file itself unless an option to skip
+ // it is specifically enabled by the user or project.
+ if(!this->Makefile->IsOn("CMAKE_SKIP_RULE_DEPENDENCY"))
+ {
+ depends.insert(depends.end(), ruleFiles.begin(), ruleFiles.end());
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmLocalUnixMakefileGenerator3
+::AppendCustomDepends(std::vector<std::string>& depends,
+ const std::vector<cmCustomCommand>& ccs)
+{
+ for(std::vector<cmCustomCommand>::const_iterator i = ccs.begin();
+ i != ccs.end(); ++i)
+ {
+ this->AppendCustomDepend(depends, *i);
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmLocalUnixMakefileGenerator3
+::AppendCustomDepend(std::vector<std::string>& depends,
+ const cmCustomCommand& cc)
+{
+ for(std::vector<std::string>::const_iterator d = cc.GetDepends().begin();
+ d != cc.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(),
+ dep))
+ {
+ depends.push_back(dep);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmLocalUnixMakefileGenerator3
+::AppendCustomCommands(std::vector<std::string>& commands,
+ const std::vector<cmCustomCommand>& ccs,
+ cmTarget* target,
+ cmLocalGenerator::RelativeRoot relative)
+{
+ for(std::vector<cmCustomCommand>::const_iterator i = ccs.begin();
+ i != ccs.end(); ++i)
+ {
+ this->AppendCustomCommand(commands, *i, target, true, relative);
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmLocalUnixMakefileGenerator3
+::AppendCustomCommand(std::vector<std::string>& commands,
+ const cmCustomCommand& cc,
+ cmTarget* target,
+ bool echo_comment,
+ cmLocalGenerator::RelativeRoot relative,
+ std::ostream* content)
+{
+ // Optionally create a command to display the custom command's
+ // comment text. This is used for pre-build, pre-link, and
+ // post-build command comments. Custom build step commands have
+ // their comments generated elsewhere.
+ if(echo_comment)
+ {
+ const char* comment = cc.GetComment();
+ if(comment && *comment)
+ {
+ this->AppendEcho(commands, comment,
+ cmLocalUnixMakefileGenerator3::EchoGenerate);
+ }
+ }
+
+ // if the command specified a working directory use it.
+ const char* dir = this->Makefile->GetStartOutputDirectory();
+ const char* workingDir = cc.GetWorkingDirectory();
+ if(workingDir)
+ {
+ dir = workingDir;
+ }
+ if(content)
+ {
+ *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;
+ for(unsigned int c = 0; c < ccg.GetNumberOfCommands(); ++c)
+ {
+ // Build the command line in a single string.
+ std::string cmd = ccg.GetCommand(c);
+ if (cmd.size())
+ {
+ // Use "call " before any invocations of .bat or .cmd files
+ // invoked as custom commands in the WindowsShell.
+ //
+ bool useCall = false;
+
+ if (this->WindowsShell)
+ {
+ std::string suffix;
+ if (cmd.size() > 4)
+ {
+ suffix = cmSystemTools::LowerCase(cmd.substr(cmd.size()-4));
+ if (suffix == ".bat" || suffix == ".cmd")
+ {
+ useCall = true;
+ }
+ }
+ }
+
+ cmSystemTools::ReplaceString(cmd, "/./", "/");
+ // 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)
+ {
+ cmd = this->Convert(cmd.c_str(),START_OUTPUT);
+ }
+ bool has_slash = cmd.find("/") != cmd.npos;
+ if(had_slash && !has_slash)
+ {
+ // This command was specified as a path to a file in the
+ // current directory. Add a leading "./" so it can run
+ // without the current directory being in the search path.
+ cmd = "./" + cmd;
+ }
+ std::string launcher =
+ this->MakeLauncher(cc, target, workingDir? NONE : START_OUTPUT);
+ cmd = launcher + this->ConvertShellCommand(cmd, NONE);
+
+ ccg.AppendArguments(c, cmd);
+ if(content)
+ {
+ // Rule content does not include the launcher.
+ *content << (cmd.c_str()+launcher.size());
+ }
+ if(this->BorlandMakeCurlyHack)
+ {
+ // Borland Make has a very strange bug. If the first curly
+ // brace anywhere in the command string is a left curly, it
+ // must be written {{} instead of just {. Otherwise some
+ // curly braces are removed. The hack can be skipped if the
+ // first curly brace is the last character.
+ std::string::size_type lcurly = cmd.find("{");
+ if(lcurly != cmd.npos && lcurly < (cmd.size()-1))
+ {
+ std::string::size_type rcurly = cmd.find("}");
+ if(rcurly == cmd.npos || rcurly > lcurly)
+ {
+ // The first curly is a left curly. Use the hack.
+ std::string hack_cmd = cmd.substr(0, lcurly);
+ hack_cmd += "{{}";
+ hack_cmd += cmd.substr(lcurly+1);
+ cmd = hack_cmd;
+ }
+ }
+ }
+ if (launcher.empty())
+ {
+ if (useCall)
+ {
+ cmd = "call " + cmd;
+ }
+ else if (this->NMake && cmd[0]=='"')
+ {
+ cmd = "echo >nul && " + cmd;
+ }
+ }
+ commands1.push_back(cmd);
+ }
+ }
+
+ // Setup the proper working directory for the commands.
+ this->CreateCDCommand(commands1, dir, relative);
+
+ // push back the custom commands
+ commands.insert(commands.end(), commands1.begin(), commands1.end());
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmLocalUnixMakefileGenerator3::MakeLauncher(const cmCustomCommand& cc,
+ cmTarget* target,
+ RelativeRoot relative)
+{
+ // Short-circuit if there is no launcher.
+ const char* prop = "RULE_LAUNCH_CUSTOM";
+ const char* val = this->GetRuleLauncher(target, prop);
+ if(!(val && *val))
+ {
+ return "";
+ }
+
+ // Expand rules in the empty string. It may insert the launcher and
+ // perform replacements.
+ RuleVariables vars;
+ vars.RuleLauncher = prop;
+ vars.CMTarget = target;
+ std::string output;
+ const std::vector<std::string>& outputs = cc.GetOutputs();
+ if(!outputs.empty())
+ {
+ output = this->Convert(outputs[0].c_str(), relative, SHELL);
+ }
+ vars.Output = output.c_str();
+
+ std::string launcher;
+ this->ExpandRuleVariables(launcher, vars);
+ if(!launcher.empty())
+ {
+ launcher += " ";
+ }
+ return launcher;
+}
+
+//----------------------------------------------------------------------------
+void
+cmLocalUnixMakefileGenerator3
+::AppendCleanCommand(std::vector<std::string>& commands,
+ const std::vector<std::string>& files,
+ cmTarget& target, const char* filename)
+{
+ 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);
+ 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";
+ }
+ fout << ")\n";
+ 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";
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmLocalUnixMakefileGenerator3::AppendEcho(std::vector<std::string>& commands,
+ const char* text,
+ EchoColor color)
+{
+ // 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.
+ // This color set is readable on both black and white backgrounds.
+ switch(color)
+ {
+ case EchoNormal:
+ break;
+ case EchoDepend:
+ color_name = "--magenta --bold ";
+ break;
+ case EchoBuild:
+ color_name = "--green ";
+ break;
+ case EchoLink:
+ color_name = "--red --bold ";
+ break;
+ case EchoGenerate:
+ color_name = "--blue --bold ";
+ break;
+ case EchoGlobal:
+ color_name = "--cyan ";
+ break;
+ }
+ }
+#else
+ (void)color;
+#endif
+
+ // Echo one line at a time.
+ std::string line;
+ line.reserve(200);
+ for(const char* c = text;; ++c)
+ {
+ if(*c == '\n' || *c == '\0')
+ {
+ // Avoid writing a blank last line on end-of-string.
+ if(*c != '\0' || !line.empty())
+ {
+ // Add a command to echo this line.
+ std::string cmd;
+ if(color_name.empty())
+ {
+ // Use the native echo command.
+ cmd = "@echo ";
+ cmd += this->EscapeForShell(line.c_str(), 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());
+ }
+ commands.push_back(cmd);
+ }
+
+ // Reset the line to emtpy.
+ line = "";
+
+ // Terminate on end-of-string.
+ if(*c == '\0')
+ {
+ return;
+ }
+ }
+ else if(*c != '\r')
+ {
+ // Append this character to the current line.
+ line += *c;
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmLocalUnixMakefileGenerator3
+::CreateMakeVariable(const char* sin, const char* s2in)
+{
+ std::string s = sin;
+ std::string s2 = s2in;
+ std::string unmodified = s;
+ unmodified += s2;
+ // if there is no restriction on the length of make variables
+ // and there are no "." charactors in the string, then return the
+ // unmodified combination.
+ if((!this->MakefileVariableSize && unmodified.find('.') == s.npos)
+ && (!this->MakefileVariableSize && unmodified.find('+') == s.npos)
+ && (!this->MakefileVariableSize && unmodified.find('-') == s.npos))
+ {
+ return unmodified;
+ }
+
+ // see if the variable has been defined before and return
+ // the modified version of the variable
+ std::map<cmStdString, cmStdString>::iterator i =
+ this->MakeVariableMap.find(unmodified);
+ if(i != this->MakeVariableMap.end())
+ {
+ return i->second;
+ }
+ // start with the unmodified variable
+ std::string ret = unmodified;
+ // if this there is no value for this->MakefileVariableSize then
+ // the string must have bad characters in it
+ if(!this->MakefileVariableSize)
+ {
+ cmSystemTools::ReplaceString(ret, ".", "_");
+ cmSystemTools::ReplaceString(ret, "-", "__");
+ cmSystemTools::ReplaceString(ret, "+", "___");
+ int ni = 0;
+ char buffer[5];
+ // make sure the _ version is not already used, if
+ // it is used then add number to the end of the variable
+ while(this->ShortMakeVariableMap.count(ret) && ni < 1000)
+ {
+ ++ni;
+ sprintf(buffer, "%04d", ni);
+ ret = unmodified + buffer;
+ }
+ this->ShortMakeVariableMap[ret] = "1";
+ this->MakeVariableMap[unmodified] = ret;
+ return ret;
+ }
+
+ // if the string is greater the 32 chars it is an invalid vairable name
+ // for borland make
+ if(static_cast<int>(ret.size()) > this->MakefileVariableSize)
+ {
+ int keep = this->MakefileVariableSize - 8;
+ int size = keep + 3;
+ std::string str1 = s;
+ std::string str2 = s2;
+ // we must shorten the combined string by 4 charactors
+ // keep no more than 24 charactors from the second string
+ if(static_cast<int>(str2.size()) > keep)
+ {
+ str2 = str2.substr(0, keep);
+ }
+ if(static_cast<int>(str1.size()) + static_cast<int>(str2.size()) > size)
+ {
+ str1 = str1.substr(0, size - str2.size());
+ }
+ char buffer[5];
+ int ni = 0;
+ sprintf(buffer, "%04d", ni);
+ ret = str1 + str2 + buffer;
+ while(this->ShortMakeVariableMap.count(ret) && ni < 1000)
+ {
+ ++ni;
+ sprintf(buffer, "%04d", ni);
+ ret = str1 + str2 + buffer;
+ }
+ if(ni == 1000)
+ {
+ cmSystemTools::Error("Borland makefile variable length too long");
+ return unmodified;
+ }
+ // once an unused variable is found
+ this->ShortMakeVariableMap[ret] = "1";
+ }
+ // always make an entry into the unmodified to variable map
+ this->MakeVariableMap[unmodified] = ret;
+ return ret;
+}
+
+//----------------------------------------------------------------------------
+bool cmLocalUnixMakefileGenerator3::UpdateDependencies(const char* tgtInfo,
+ bool verbose,
+ bool color)
+{
+ // read in the target info file
+ if(!this->Makefile->ReadListFile(0, tgtInfo) ||
+ cmSystemTools::GetErrorOccuredFlag())
+ {
+ cmSystemTools::Error("Target DependInfo.cmake file not found");
+ }
+
+ // Check if any multiple output pairs have a missing file.
+ this->CheckMultipleOutputs(verbose);
+
+ std::string dir = cmSystemTools::GetFilenamePath(tgtInfo);
+ std::string internalDependFile = dir + "/depend.internal";
+ std::string dependFile = dir + "/depend.make";
+
+ // If the target DependInfo.cmake file has changed since the last
+ // time dependencies were scanned then force rescanning. This may
+ // happen when a new source file is added and CMake regenerates the
+ // project but no other sources were touched.
+ bool needRescanDependInfo = false;
+ cmFileTimeComparison* ftc =
+ this->GlobalGenerator->GetCMakeInstance()->GetFileComparison();
+ {
+ int result;
+ if(!ftc->FileTimeCompare(internalDependFile.c_str(), tgtInfo, &result) ||
+ result < 0)
+ {
+ if(verbose)
+ {
+ cmOStringStream msg;
+ msg << "Dependee \"" << tgtInfo
+ << "\" is newer than depender \""
+ << internalDependFile << "\"." << std::endl;
+ cmSystemTools::Stdout(msg.str().c_str());
+ }
+ needRescanDependInfo = true;
+ }
+ }
+
+ // 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();
+ dirInfoFile += cmake::GetCMakeFilesDirectory();
+ dirInfoFile += "/CMakeDirectoryInformation.cmake";
+ {
+ int result;
+ if(!ftc->FileTimeCompare(internalDependFile.c_str(),
+ dirInfoFile.c_str(), &result) || result < 0)
+ {
+ if(verbose)
+ {
+ cmOStringStream msg;
+ msg << "Dependee \"" << dirInfoFile
+ << "\" is newer than depender \""
+ << internalDependFile << "\"." << std::endl;
+ cmSystemTools::Stdout(msg.str().c_str());
+ }
+ needRescanDirInfo = true;
+ }
+ }
+
+ // Check the implicit dependencies to see if they are up to date.
+ // The build.make file may have explicit dependencies for the object
+ // files but these will not affect the scanning process so they need
+ // not be considered.
+ std::map<std::string, cmDepends::DependencyVector> validDependencies;
+ bool needRescanDependencies = false;
+ if (needRescanDirInfo == false)
+ {
+ cmDependsC checker;
+ checker.SetVerbose(verbose);
+ checker.SetFileComparison(ftc);
+ // cmDependsC::Check() fills the vector validDependencies() with the
+ // dependencies for those files where they are still valid, i.e. neither
+ // the files themselves nor any files they depend on have changed.
+ // We don't do that if the CMakeDirectoryInformation.cmake file has
+ // changed, because then potentially all dependencies have changed.
+ // This information is given later on to cmDependsC, which then only
+ // rescans the files where it did not get valid dependencies via this
+ // dependency vector. This means that in the normal case, when only
+ // few or one file have been edited, then also only this one file is
+ // actually scanned again, instead of all files for this target.
+ needRescanDependencies = !checker.Check(dependFile.c_str(),
+ internalDependFile.c_str(),
+ validDependencies);
+ }
+
+ if(needRescanDependInfo || needRescanDirInfo || needRescanDependencies)
+ {
+ // The dependencies must be regenerated.
+ std::string targetName = cmSystemTools::GetFilenameName(dir);
+ 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);
+ }
+
+ // The dependencies are already up-to-date.
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool
+cmLocalUnixMakefileGenerator3
+::ScanDependencies(const char* targetDir,
+ std::map<std::string, cmDepends::DependencyVector>& validDeps)
+{
+ // Read the directory information file.
+ cmMakefile* mf = this->Makefile;
+ bool haveDirectoryInfo = false;
+ std::string dirInfoFile = this->Makefile->GetStartOutputDirectory();
+ dirInfoFile += cmake::GetCMakeFilesDirectory();
+ dirInfoFile += "/CMakeDirectoryInformation.cmake";
+ if(mf->ReadListFile(0, dirInfoFile.c_str()) &&
+ !cmSystemTools::GetErrorOccuredFlag())
+ {
+ haveDirectoryInfo = true;
+ }
+
+ // Lookup useful directory information.
+ if(haveDirectoryInfo)
+ {
+ // Test whether we need to force Unix paths.
+ if(const char* force = mf->GetDefinition("CMAKE_FORCE_UNIX_PATHS"))
+ {
+ if(!cmSystemTools::IsOff(force))
+ {
+ cmSystemTools::SetForceUnixPaths(true);
+ }
+ }
+
+ // Setup relative path top directories.
+ this->RelativePathsConfigured = true;
+ if(const char* relativePathTopSource =
+ mf->GetDefinition("CMAKE_RELATIVE_PATH_TOP_SOURCE"))
+ {
+ this->RelativePathTopSource = relativePathTopSource;
+ }
+ if(const char* relativePathTopBinary =
+ mf->GetDefinition("CMAKE_RELATIVE_PATH_TOP_BINARY"))
+ {
+ this->RelativePathTopBinary = relativePathTopBinary;
+ }
+ }
+ else
+ {
+ cmSystemTools::Error("Directory Information file not found");
+ }
+
+ // create the file stream for the depends file
+ std::string dir = targetDir;
+
+ // Open the make depends file. This should be copy-if-different
+ // because the make tool may try to reload it needlessly otherwise.
+ std::string ruleFileNameFull = dir;
+ ruleFileNameFull += "/depend.make";
+ cmGeneratedFileStream ruleFileStream(ruleFileNameFull.c_str());
+ ruleFileStream.SetCopyIfDifferent(true);
+ if(!ruleFileStream)
+ {
+ return false;
+ }
+
+ // Open the cmake dependency tracking file. This should not be
+ // copy-if-different because dependencies are re-scanned when it is
+ // older than the DependInfo.cmake.
+ std::string internalRuleFileNameFull = dir;
+ internalRuleFileNameFull += "/depend.internal";
+ cmGeneratedFileStream
+ internalRuleFileStream(internalRuleFileNameFull.c_str());
+ if(!internalRuleFileStream)
+ {
+ return false;
+ }
+
+ this->WriteDisclaimer(ruleFileStream);
+ this->WriteDisclaimer(internalRuleFileStream);
+
+ // for each language we need to scan, scan it
+ const char *langStr = mf->GetSafeDefinition("CMAKE_DEPENDS_LANGUAGES");
+ std::vector<std::string> langs;
+ cmSystemTools::ExpandListArgument(langStr, langs);
+ for (std::vector<std::string>::iterator li =
+ langs.begin(); li != langs.end(); ++li)
+ {
+ // construct the checker
+ std::string lang = li->c_str();
+
+ // 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);
+ }
+#ifdef CMAKE_BUILD_WITH_CMAKE
+ else if(lang == "Fortran")
+ {
+ scanner = new cmDependsFortran(this);
+ }
+ else if(lang == "Java")
+ {
+ scanner = new cmDependsJava();
+ }
+#endif
+
+ if (scanner)
+ {
+ scanner->SetLocalGenerator(this);
+ scanner->SetFileComparison
+ (this->GlobalGenerator->GetCMakeInstance()->GetFileComparison());
+ scanner->SetLanguage(lang.c_str());
+ scanner->SetTargetDirectory(dir.c_str());
+ scanner->Write(ruleFileStream, internalRuleFileStream);
+
+ // free the scanner for this language
+ delete scanner;
+ }
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+void cmLocalUnixMakefileGenerator3::CheckMultipleOutputs(bool verbose)
+{
+ cmMakefile* mf = this->Makefile;
+
+ // Get the string listing the multiple output pairs.
+ const char* pairs_string = mf->GetDefinition("CMAKE_MULTIPLE_OUTPUT_PAIRS");
+ if(!pairs_string)
+ {
+ return;
+ }
+
+ // Convert the string to a list and preserve empty entries.
+ std::vector<std::string> pairs;
+ cmSystemTools::ExpandListArgument(pairs_string, pairs, true);
+ for(std::vector<std::string>::const_iterator i = pairs.begin();
+ i != pairs.end() && (i+1) != pairs.end();)
+ {
+ const std::string& depender = *i++;
+ const std::string& dependee = *i++;
+
+ // If the depender is missing then delete the dependee to make
+ // sure both will be regenerated.
+ if(cmSystemTools::FileExists(dependee.c_str()) &&
+ !cmSystemTools::FileExists(depender.c_str()))
+ {
+ if(verbose)
+ {
+ cmOStringStream 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());
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmLocalUnixMakefileGenerator3
+::WriteLocalAllRules(std::ostream& ruleFileStream)
+{
+ this->WriteDisclaimer(ruleFileStream);
+
+ // Write the main entry point target. This must be the VERY first
+ // target so that make with no arguments will run it.
+ {
+ // Just depend on the all target to drive the build.
+ std::vector<std::string> depends;
+ std::vector<std::string> no_commands;
+ depends.push_back("all");
+
+ // Write the rule.
+ this->WriteMakeRule(ruleFileStream,
+ "Default target executed when no arguments are "
+ "given to make.",
+ "default_target",
+ depends,
+ no_commands, true);
+ }
+
+ this->WriteSpecialTargetsTop(ruleFileStream);
+
+ // Include the progress variables for the target.
+ // Write all global targets
+ this->WriteDivider(ruleFileStream);
+ ruleFileStream
+ << "# Targets provided globally by CMake.\n"
+ << "\n";
+ cmTargets* targets = &(this->Makefile->GetTargets());
+ cmTargets::iterator glIt;
+ for ( glIt = targets->begin(); glIt != targets->end(); ++ glIt )
+ {
+ if ( glIt->second.GetType() == cmTarget::GLOBAL_TARGET )
+ {
+ std::string targetString = "Special rule for the target " + glIt->first;
+ std::vector<std::string> commands;
+ std::vector<std::string> depends;
+
+ const char* text = glIt->second.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());
+ }
+ this->AppendEcho(commands, text,
+ cmLocalUnixMakefileGenerator3::EchoGlobal);
+
+ // Global targets store their rules in pre- and post-build commands.
+ this->AppendCustomDepends(depends,
+ glIt->second.GetPreBuildCommands());
+ this->AppendCustomDepends(depends,
+ glIt->second.GetPostBuildCommands());
+ this->AppendCustomCommands(commands,
+ glIt->second.GetPreBuildCommands(),
+ &glIt->second,
+ cmLocalGenerator::START_OUTPUT);
+ this->AppendCustomCommands(commands,
+ glIt->second.GetPostBuildCommands(),
+ &glIt->second,
+ cmLocalGenerator::START_OUTPUT);
+ std::string targetName = glIt->second.GetName();
+ this->WriteMakeRule(ruleFileStream, targetString.c_str(),
+ targetName.c_str(), depends, commands, true);
+
+ // Provide a "/fast" version of the target.
+ depends.clear();
+ if((targetName == "install")
+ || (targetName == "install_local")
+ || (targetName == "install_strip"))
+ {
+ // Provide a fast install target that does not depend on all
+ // but has the same command.
+ depends.push_back("preinstall/fast");
+ }
+ else
+ {
+ // Just forward to the real target so at least it will work.
+ depends.push_back(targetName);
+ commands.clear();
+ }
+ targetName += "/fast";
+ this->WriteMakeRule(ruleFileStream, targetString.c_str(),
+ targetName.c_str(), depends, commands, true);
+ }
+ }
+
+ std::vector<std::string> depends;
+ std::vector<std::string> commands;
+
+ // Write the all rule.
+ std::string dir;
+ std::string recursiveTarget = this->Makefile->GetStartOutputDirectory();
+ recursiveTarget += "/all";
+
+ depends.push_back("cmake_check_build_system");
+
+ std::string progressDir = this->Makefile->GetHomeOutputDirectory();
+ progressDir += cmake::GetCMakeFilesDirectory();
+ {
+ cmOStringStream progCmd;
+ progCmd <<
+ "$(CMAKE_COMMAND) -E cmake_progress_start ";
+ progCmd << this->Convert(progressDir.c_str(),
+ 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(),
+ cmLocalGenerator::FULL,
+ cmLocalGenerator::SHELL);
+ commands.push_back(progCmd.str());
+ }
+ std::string mf2Dir = cmake::GetCMakeFilesDirectoryPostSlash();
+ mf2Dir += "Makefile2";
+ commands.push_back(this->GetRecursiveMakeCall(mf2Dir.c_str(),
+ recursiveTarget.c_str()));
+ this->CreateCDCommand(commands,
+ this->Makefile->GetHomeOutputDirectory(),
+ cmLocalGenerator::START_OUTPUT);
+ {
+ cmOStringStream progCmd;
+ progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; // # 0
+ progCmd << this->Convert(progressDir.c_str(),
+ cmLocalGenerator::FULL,
+ cmLocalGenerator::SHELL);
+ progCmd << " 0";
+ commands.push_back(progCmd.str());
+ }
+ this->WriteMakeRule(ruleFileStream, "The main all target", "all",
+ depends, commands, true);
+
+ // Write the clean rule.
+ recursiveTarget = this->Makefile->GetStartOutputDirectory();
+ recursiveTarget += "/clean";
+ commands.clear();
+ depends.clear();
+ commands.push_back(this->GetRecursiveMakeCall(mf2Dir.c_str(),
+ recursiveTarget.c_str()));
+ this->CreateCDCommand(commands,
+ this->Makefile->GetHomeOutputDirectory(),
+ cmLocalGenerator::START_OUTPUT);
+ this->WriteMakeRule(ruleFileStream, "The main clean target", "clean",
+ depends, commands, true);
+ commands.clear();
+ depends.clear();
+ depends.push_back("clean");
+ this->WriteMakeRule(ruleFileStream, "The main clean target", "clean/fast",
+ depends, commands, true);
+
+ // Write the preinstall rule.
+ recursiveTarget = this->Makefile->GetStartOutputDirectory();
+ recursiveTarget += "/preinstall";
+ commands.clear();
+ depends.clear();
+ const char* noall =
+ this->Makefile->GetDefinition("CMAKE_SKIP_INSTALL_ALL_DEPENDENCY");
+ if(!noall || cmSystemTools::IsOff(noall))
+ {
+ // Drive the build before installing.
+ depends.push_back("all");
+ }
+ else
+ {
+ // At least make sure the build system is up to date.
+ depends.push_back("cmake_check_build_system");
+ }
+ commands.push_back
+ (this->GetRecursiveMakeCall(mf2Dir.c_str(), recursiveTarget.c_str()));
+ this->CreateCDCommand(commands,
+ this->Makefile->GetHomeOutputDirectory(),
+ cmLocalGenerator::START_OUTPUT);
+ this->WriteMakeRule(ruleFileStream, "Prepare targets for installation.",
+ "preinstall", depends, commands, true);
+ depends.clear();
+ this->WriteMakeRule(ruleFileStream, "Prepare targets for installation.",
+ "preinstall/fast", depends, commands, true);
+
+ // write the depend rule, really a recompute depends rule
+ depends.clear();
+ commands.clear();
+ std::string cmakefileName = cmake::GetCMakeFilesDirectoryPostSlash();
+ cmakefileName += "Makefile.cmake";
+ 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,
+ cmLocalGenerator::SHELL);
+ runRule += " 1";
+ commands.push_back(runRule);
+ this->CreateCDCommand(commands,
+ this->Makefile->GetHomeOutputDirectory(),
+ cmLocalGenerator::START_OUTPUT);
+ this->WriteMakeRule(ruleFileStream, "clear depends",
+ "depend",
+ depends, commands, true);
+}
+
+
+//----------------------------------------------------------------------------
+void cmLocalUnixMakefileGenerator3::ClearDependencies(cmMakefile* mf,
+ bool verbose)
+{
+ // Get the list of target files to check
+ const char* infoDef = mf->GetDefinition("CMAKE_DEPEND_INFO_FILES");
+ if(!infoDef)
+ {
+ return;
+ }
+ std::vector<std::string> files;
+ cmSystemTools::ExpandListArgument(infoDef, files);
+
+ // Each depend information file corresponds to a target. Clear the
+ // dependencies for that target.
+ cmDepends clearer;
+ clearer.SetVerbose(verbose);
+ for(std::vector<std::string>::iterator l = files.begin();
+ l != files.end(); ++l)
+ {
+ std::string dir = cmSystemTools::GetFilenamePath(l->c_str());
+
+ // Clear the implicit dependency makefile.
+ std::string dependFile = dir + "/depend.make";
+ clearer.Clear(dependFile.c_str());
+
+ // Remove the internal dependency check file to force
+ // regeneration.
+ std::string internalDependFile = dir + "/depend.internal";
+ cmSystemTools::RemoveFile(internalDependFile.c_str());
+ }
+}
+
+
+void cmLocalUnixMakefileGenerator3
+::WriteDependLanguageInfo(std::ostream& cmakefileStream, cmTarget &target)
+{
+ ImplicitDependLanguageMap const& implicitLangs =
+ this->GetImplicitDepends(target);
+
+ // list the languages
+ cmakefileStream
+ << "# The set of languages for which implicit dependencies are needed:\n";
+ cmakefileStream
+ << "SET(CMAKE_DEPENDS_LANGUAGES\n";
+ for(ImplicitDependLanguageMap::const_iterator
+ l = implicitLangs.begin(); l != implicitLangs.end(); ++l)
+ {
+ cmakefileStream << " \"" << l->first.c_str() << "\"\n";
+ }
+ cmakefileStream << " )\n";
+
+ // now list the files for each language
+ cmakefileStream
+ << "# The set of files for implicit dependencies of each language:\n";
+ for(ImplicitDependLanguageMap::const_iterator
+ l = implicitLangs.begin(); l != implicitLangs.end(); ++l)
+ {
+ cmakefileStream
+ << "SET(CMAKE_DEPENDS_CHECK_" << l->first.c_str() << "\n";
+ ImplicitDependFileMap const& implicitPairs = l->second;
+
+ // for each file pair
+ for(ImplicitDependFileMap::const_iterator pi = implicitPairs.begin();
+ pi != implicitPairs.end(); ++pi)
+ {
+ cmakefileStream << " \"" << pi->second << "\" ";
+ cmakefileStream << "\"" << pi->first << "\"\n";
+ }
+ cmakefileStream << " )\n";
+
+ // Tell the dependency scanner what compiler is used.
+ std::string cidVar = "CMAKE_";
+ cidVar += l->first;
+ cidVar += "_COMPILER_ID";
+ const char* cid = this->Makefile->GetDefinition(cidVar.c_str());
+ if(cid && *cid)
+ {
+ cmakefileStream
+ << "SET(CMAKE_" << l->first.c_str() << "_COMPILER_ID \""
+ << cid << "\")\n";
+ }
+ }
+
+ // Build a list of preprocessor definitions for the target.
+ std::vector<std::string> defines;
+ {
+ std::string defPropName = "COMPILE_DEFINITIONS_";
+ defPropName += cmSystemTools::UpperCase(this->ConfigurationName);
+ if(const char* ddefs = this->Makefile->GetProperty("COMPILE_DEFINITIONS"))
+ {
+ cmSystemTools::ExpandListArgument(ddefs, defines);
+ }
+ if(const char* cdefs = target.GetProperty("COMPILE_DEFINITIONS"))
+ {
+ cmSystemTools::ExpandListArgument(cdefs, defines);
+ }
+ if(const char* dcdefs = this->Makefile->GetProperty(defPropName.c_str()))
+ {
+ cmSystemTools::ExpandListArgument(dcdefs, defines);
+ }
+ if(const char* ccdefs = target.GetProperty(defPropName.c_str()))
+ {
+ cmSystemTools::ExpandListArgument(ccdefs, defines);
+ }
+ }
+ if(!defines.empty())
+ {
+ cmakefileStream
+ << "\n"
+ << "# Preprocessor definitions for this target.\n"
+ << "SET(CMAKE_TARGET_DEFINITIONS\n";
+ for(std::vector<std::string>::const_iterator di = defines.begin();
+ di != defines.end(); ++di)
+ {
+ cmakefileStream
+ << " " << this->EscapeForCMake(di->c_str()) << "\n";
+ }
+ cmakefileStream
+ << " )\n";
+ }
+
+ // Store include transform rule properties. Write the directory
+ // rules first because they may be overridden by later target rules.
+ std::vector<std::string> transformRules;
+ if(const char* xform =
+ this->Makefile->GetProperty("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM"))
+ {
+ cmSystemTools::ExpandListArgument(xform, transformRules);
+ }
+ if(const char* xform =
+ target.GetProperty("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM"))
+ {
+ cmSystemTools::ExpandListArgument(xform, transformRules);
+ }
+ if(!transformRules.empty())
+ {
+ cmakefileStream
+ << "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
+ << " )\n";
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmLocalUnixMakefileGenerator3::WriteDisclaimer(std::ostream& os)
+{
+ os
+ << "# CMAKE generated file: DO NOT EDIT!\n"
+ << "# Generated by \"" << this->GlobalGenerator->GetName() << "\""
+ << " Generator, CMake Version "
+ << cmVersion::GetMajorVersion() << "."
+ << cmVersion::GetMinorVersion() << "\n\n";
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmLocalUnixMakefileGenerator3
+::GetRecursiveMakeCall(const char *makefile, const char* tgt)
+{
+ // Call make on the given file.
+ std::string cmd;
+ cmd += "$(MAKE) -f ";
+ cmd += this->Convert(makefile,NONE,SHELL);
+ cmd += " ";
+
+ // Pass down verbosity level.
+ if(this->GetMakeSilentFlag().size())
+ {
+ cmd += this->GetMakeSilentFlag();
+ cmd += " ";
+ }
+
+ // Most unix makes will pass the command line flags to make down to
+ // 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())
+ {
+ cmd += "-$(MAKEFLAGS) ";
+ }
+
+ // Add the target.
+ if (tgt && tgt[0] != '\0')
+ {
+ // The make target is always relative to the top of the build tree.
+ std::string tgt2 = this->Convert(tgt, HOME_OUTPUT);
+
+ // The target may have been written with windows paths.
+ cmSystemTools::ConvertToOutputSlashes(tgt2);
+
+ // Escape one extra time if the make tool requires it.
+ if(this->MakeCommandEscapeTargetTwice)
+ {
+ tgt2 = this->EscapeForShell(tgt2.c_str(), 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);
+ }
+ return cmd;
+}
+
+//----------------------------------------------------------------------------
+void cmLocalUnixMakefileGenerator3::WriteDivider(std::ostream& os)
+{
+ os
+ << "#======================================"
+ << "=======================================\n";
+}
+
+//----------------------------------------------------------------------------
+void
+cmLocalUnixMakefileGenerator3
+::WriteCMakeArgument(std::ostream& os, const char* s)
+{
+ // Write the given string to the stream with escaping to get it back
+ // into CMake through the lexical scanner.
+ os << "\"";
+ for(const char* c = s; *c; ++c)
+ {
+ if(*c == '\\')
+ {
+ os << "\\\\";
+ }
+ else if(*c == '"')
+ {
+ os << "\\\"";
+ }
+ else
+ {
+ os << *c;
+ }
+ }
+ os << "\"";
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmLocalUnixMakefileGenerator3::ConvertToQuotedOutputPath(const char* p)
+{
+
+ // 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())
+ {
+ 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 = '\\';
+ }
+ }
+ }
+#endif
+
+ // 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)
+ {
+ // Only the last component can be empty to avoid double slashes.
+ if(components[i].length() > 0 || (i == (components.size()-1)))
+ {
+ if(!first)
+ {
+ result += slash;
+ }
+ result += components[i];
+ first = false;
+ }
+ }
+
+ // Close the quoted result.
+ result += "\"";
+
+ return result;
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmLocalUnixMakefileGenerator3
+::GetTargetDirectory(cmTarget const& target) const
+{
+ std::string dir = cmake::GetCMakeFilesDirectoryPostSlash();
+ dir += target.GetName();
+#if defined(__VMS)
+ dir += "_dir";
+#else
+ dir += ".dir";
+#endif
+ return dir;
+}
+
+//----------------------------------------------------------------------------
+cmLocalUnixMakefileGenerator3::ImplicitDependLanguageMap const&
+cmLocalUnixMakefileGenerator3::GetImplicitDepends(cmTarget const& tgt)
+{
+ return this->ImplicitDepends[tgt.GetName()];
+}
+
+//----------------------------------------------------------------------------
+void
+cmLocalUnixMakefileGenerator3::AddImplicitDepends(cmTarget const& tgt,
+ const char* lang,
+ const char* obj,
+ const char* src)
+{
+ this->ImplicitDepends[tgt.GetName()][lang][obj] = src;
+}
+
+//----------------------------------------------------------------------------
+void cmLocalUnixMakefileGenerator3
+::CreateCDCommand(std::vector<std::string>& commands, const char *tgtDir,
+ cmLocalGenerator::RelativeRoot relRetDir)
+{
+ const char* retDir = this->GetRelativeRootPath(relRetDir);
+
+ // do we need to cd?
+ if (!strcmp(tgtDir,retDir))
+ {
+ return;
+ }
+
+ // In a Windows shell we must change drive letter too. The shell
+ // 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 ";
+
+ if(!this->UnixCD)
+ {
+ // On Windows we must perform each step separately and then change
+ // back because the shell keeps the working directory between
+ // commands.
+ std::string cmd = cd_cmd;
+ cmd += this->ConvertToOutputForExisting(tgtDir, relRetDir);
+ commands.insert(commands.begin(),cmd);
+
+ // Change back to the starting directory.
+ cmd = cd_cmd;
+ cmd += this->ConvertToOutputForExisting(relRetDir, tgtDir);
+ commands.push_back(cmd);
+ }
+ else
+ {
+ // 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;
+ }
+ }
+}
diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h
new file mode 100644
index 000000000..e3749590b
--- /dev/null
+++ b/Source/cmLocalUnixMakefileGenerator3.h
@@ -0,0 +1,383 @@
+/*============================================================================
+ 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 cmLocalUnixMakefileGenerator3_h
+#define cmLocalUnixMakefileGenerator3_h
+
+#include "cmLocalGenerator.h"
+
+// for cmDepends::DependencyVector
+#include "cmDepends.h"
+
+class cmCustomCommand;
+class cmDependInformation;
+class cmDepends;
+class cmMakefileTargetGenerator;
+class cmTarget;
+class cmSourceFile;
+
+/** \class cmLocalUnixMakefileGenerator3
+ * \brief Write a LocalUnix makefiles.
+ *
+ * cmLocalUnixMakefileGenerator3 produces a LocalUnix makefile from its
+ * member Makefile.
+ */
+class cmLocalUnixMakefileGenerator3 : public cmLocalGenerator
+{
+public:
+ cmLocalUnixMakefileGenerator3();
+ virtual ~cmLocalUnixMakefileGenerator3();
+
+ /**
+ * Process the CMakeLists files for this directory to fill in the
+ * Makefile ivar
+ */
+ virtual void Configure();
+
+ /**
+ * 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();
+
+ // Write out a make rule
+ void WriteMakeRule(std::ostream& os,
+ const char* comment,
+ const char* target,
+ const std::vector<std::string>& depends,
+ const std::vector<std::string>& commands,
+ bool symbolic,
+ bool in_help = false);
+
+ // write the main variables used by the makefiles
+ 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.
+ */
+ void SetMakeCommandEscapeTargetTwice(bool b)
+ { this->MakeCommandEscapeTargetTwice = b; }
+
+ /**
+ * Set whether the Borland curly brace command line hack should be
+ * applied.
+ */
+ void SetBorlandMakeCurlyHack(bool b)
+ { this->BorlandMakeCurlyHack = b; }
+
+ // used in writing out Cmake files such as WriteDirectoryInformation
+ static void WriteCMakeArgument(std::ostream& os, const char* s);
+
+ /** creates the common disclaimer text at the top of each makefile */
+ void WriteDisclaimer(std::ostream& os);
+
+ // write a comment line #====... in the stream
+ void WriteDivider(std::ostream& os);
+
+ /** used to create a recursive make call */
+ std::string GetRecursiveMakeCall(const char *makefile, const char* tgt);
+
+ // append flags to a string
+ 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);
+
+ /** Get whether the makefile is to have color. */
+ bool GetColorMakefile() const { return this->ColorMakefile; }
+
+ virtual std::string GetTargetDirectory(cmTarget 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);
+
+ std::string CreateMakeVariable(const char* sin, const char* s2in);
+
+ /** Called from command-line hook to bring dependencies up to date
+ for a target. */
+ virtual bool UpdateDependencies(const char* tgtInfo,
+ bool verbose, bool color);
+
+ /** Called from command-line hook to clear dependencies. */
+ virtual void ClearDependencies(cmMakefile* mf, bool verbose);
+
+ /** write some extra rules such as make test etc */
+ void WriteSpecialTargetsTop(std::ostream& makefileStream);
+ void WriteSpecialTargetsBottom(std::ostream& makefileStream);
+
+ std::string GetRelativeTargetDirectory(cmTarget const& 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, cmStdString> {};
+ struct ImplicitDependLanguageMap:
+ public std::map<cmStdString, ImplicitDependFileMap> {};
+ struct ImplicitDependTargetMap:
+ public std::map<cmStdString, ImplicitDependLanguageMap> {};
+ ImplicitDependLanguageMap const& GetImplicitDepends(cmTarget const& tgt);
+
+ void AddImplicitDepends(cmTarget const& tgt, const char* 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; }
+
+ /** Get whether to create rules to generate preprocessed and
+ assembly sources. This could be converted to a variable lookup
+ later. */
+ bool GetCreatePreprocessedSourceRules()
+ {
+ return !this->SkipPreprocessedSourceRules;
+ }
+ bool GetCreateAssemblySourceRules()
+ {
+ return !this->SkipAssemblySourceRules;
+ }
+
+ // Fill the vector with the target names for the object files,
+ // preprocessed files and assembly files. Currently only used by the
+ // Eclipse generator.
+ void GetIndividualFileTargets(std::vector<std::string>& targets);
+
+protected:
+ void WriteLocalMakefile();
+
+
+ // write the target rules for the local Makefile into the stream
+ void WriteLocalMakefileTargets(std::ostream& ruleFileStream,
+ std::set<cmStdString> &emitted);
+
+ // this method Writes the Directory information files
+ void WriteDirectoryInformationFile();
+
+
+ // write the depend info
+ void WriteDependLanguageInfo(std::ostream& cmakefileStream, cmTarget &tgt);
+
+ // write the local help rule
+ void WriteHelpRule(std::ostream& ruleFileStream);
+
+ // this converts a file name that is relative to the StartOuputDirectory
+ // into a full path
+ std::string ConvertToFullPath(const std::string& localPath);
+
+
+ void WriteConvenienceRule(std::ostream& ruleFileStream,
+ const char* realTarget,
+ const char* helpTarget);
+
+ void WriteTargetDependRule(std::ostream& ruleFileStream,
+ cmTarget& target);
+ void WriteTargetCleanRule(std::ostream& ruleFileStream,
+ cmTarget& target,
+ const std::vector<std::string>& files);
+ void WriteTargetRequiresRule(std::ostream& ruleFileStream,
+ cmTarget& target,
+ const std::vector<std::string>& objects);
+
+ void AppendRuleDepend(std::vector<std::string>& depends,
+ const char* ruleFileName);
+ void AppendRuleDepends(std::vector<std::string>& depends,
+ std::vector<std::string> const& ruleFiles);
+ void AppendCustomDepends(std::vector<std::string>& depends,
+ const std::vector<cmCustomCommand>& ccs);
+ void AppendCustomDepend(std::vector<std::string>& depends,
+ const cmCustomCommand& cc);
+ void AppendCustomCommands(std::vector<std::string>& commands,
+ const std::vector<cmCustomCommand>& ccs,
+ cmTarget* target,
+ cmLocalGenerator::RelativeRoot relative =
+ cmLocalGenerator::HOME_OUTPUT);
+ void AppendCustomCommand(std::vector<std::string>& commands,
+ const cmCustomCommand& cc,
+ cmTarget* 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);
+
+ // Helper methods for dependeny updates.
+ bool ScanDependencies(const char* targetDir,
+ std::map<std::string, cmDepends::DependencyVector>& validDeps);
+ void CheckMultipleOutputs(bool verbose);
+
+private:
+ std::string ConvertShellCommand(std::string const& cmd, RelativeRoot root);
+ std::string MakeLauncher(const cmCustomCommand& cc, cmTarget* target,
+ RelativeRoot relative);
+
+ friend class cmMakefileTargetGenerator;
+ friend class cmMakefileExecutableTargetGenerator;
+ friend class cmMakefileLibraryTargetGenerator;
+ friend class cmMakefileUtilityTargetGenerator;
+ friend class cmGlobalUnixMakefileGenerator3;
+
+ 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;
+ std::string Language;
+ LocalObjectEntry(): Target(0), Language() {}
+ LocalObjectEntry(cmTarget* t, const char* lang):
+ Target(t), Language(lang) {}
+ };
+ struct LocalObjectInfo: public std::vector<LocalObjectEntry>
+ {
+ bool HasSourceExtension;
+ bool HasPreprocessRule;
+ bool HasAssembleRule;
+ LocalObjectInfo():HasSourceExtension(false), HasPreprocessRule(false),
+ HasAssembleRule(false) {}
+ };
+ std::map<cmStdString, LocalObjectInfo> LocalObjectFiles;
+ void WriteObjectConvenienceRule(std::ostream& ruleFileStream,
+ const char* comment, const char* output,
+ LocalObjectInfo const& info);
+
+ std::vector<cmStdString> LocalHelp;
+
+ /* does the work for each target */
+ std::map<cmStdString, cmStdString> MakeVariableMap;
+ std::map<cmStdString, cmStdString> ShortMakeVariableMap;
+};
+
+#endif
diff --git a/Source/cmLocalVisualStudio10Generator.cxx b/Source/cmLocalVisualStudio10Generator.cxx
new file mode 100644
index 000000000..ace7adfa1
--- /dev/null
+++ b/Source/cmLocalVisualStudio10Generator.cxx
@@ -0,0 +1,124 @@
+/*============================================================================
+ 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 "cmLocalVisualStudio10Generator.h"
+#include "cmTarget.h"
+#include "cmMakefile.h"
+#include "cmVisualStudio10TargetGenerator.h"
+#include "cmGlobalVisualStudio10Generator.h"
+#include <cm_expat.h>
+#include "cmXMLParser.h"
+class cmVS10XMLParser : public cmXMLParser
+{
+ public:
+ virtual void EndElement(const char* /* name */)
+ {
+ }
+ virtual void CharacterDataHandler(const char* data, int length)
+ {
+ if(this->DoGUID )
+ {
+ this->GUID.assign(data+1, length-2);
+ this->DoGUID = false;
+ }
+ }
+ virtual void StartElement(const char* name, const char**)
+ {
+ // once the GUID is found do nothing
+ if(this->GUID.size())
+ {
+ return;
+ }
+ if(strcmp("ProjectGUID", name) == 0 || strcmp("ProjectGuid", name) == 0)
+ {
+ this->DoGUID = true;
+ }
+ }
+ int InitializeParser()
+ {
+ this->DoGUID = false;
+ int ret = cmXMLParser::InitializeParser();
+ if(ret == 0)
+ {
+ return ret;
+ }
+ // visual studio projects have a strange encoding, but it is
+ // really utf-8
+ XML_SetEncoding(static_cast<XML_Parser>(this->Parser), "utf-8");
+ return 1;
+ }
+ std::string GUID;
+ bool DoGUID;
+};
+
+
+//----------------------------------------------------------------------------
+cmLocalVisualStudio10Generator::cmLocalVisualStudio10Generator(VSVersion v):
+ cmLocalVisualStudio7Generator(v)
+{
+}
+
+cmLocalVisualStudio10Generator::~cmLocalVisualStudio10Generator()
+{
+}
+
+void cmLocalVisualStudio10Generator::Generate()
+{
+
+ cmTargets &tgts = this->Makefile->GetTargets();
+ for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); ++l)
+ {
+ if(static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator)
+ ->TargetIsFortranOnly(l->second))
+ {
+ this->CreateSingleVCProj(l->first.c_str(),l->second);
+ }
+ else
+ {
+ cmVisualStudio10TargetGenerator tg(
+ &l->second, static_cast<cmGlobalVisualStudio10Generator*>(
+ this->GetGlobalGenerator()));
+ tg.Generate();
+ }
+ }
+ this->WriteStampFiles();
+}
+
+
+void cmLocalVisualStudio10Generator
+::ReadAndStoreExternalGUID(const char* name,
+ const char* path)
+{
+ cmVS10XMLParser parser;
+ parser.ParseFile(path);
+
+ // if we can not find a GUID then create one
+ if(parser.GUID.empty())
+ {
+ this->GlobalGenerator->CreateGUID(name);
+ return;
+ }
+
+ std::string guidStoreName = name;
+ guidStoreName += "_GUID_CMAKE";
+ // save the GUID in the cache
+ this->GlobalGenerator->GetCMakeInstance()->
+ AddCacheEntry(guidStoreName.c_str(),
+ parser.GUID.c_str(),
+ "Stored GUID",
+ cmCacheManager::INTERNAL);
+}
+
+//----------------------------------------------------------------------------
+const char* cmLocalVisualStudio10Generator::ReportErrorLabel() const
+{
+ return ":VCEnd";
+}
diff --git a/Source/cmLocalVisualStudio10Generator.h b/Source/cmLocalVisualStudio10Generator.h
new file mode 100644
index 000000000..699de4c00
--- /dev/null
+++ b/Source/cmLocalVisualStudio10Generator.h
@@ -0,0 +1,46 @@
+/*============================================================================
+ 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 cmLocalVisualStudio10Generator_h
+#define cmLocalVisualStudio10Generator_h
+
+#include "cmLocalVisualStudio7Generator.h"
+
+
+/** \class cmLocalVisualStudio10Generator
+ * \brief Write Visual Studio 10 project files.
+ *
+ * cmLocalVisualStudio10Generator produces a Visual Studio 10 project
+ * file for each target in its directory.
+ */
+class cmLocalVisualStudio10Generator : public cmLocalVisualStudio7Generator
+{
+public:
+ ///! Set cache only and recurse to false by default.
+ cmLocalVisualStudio10Generator(VSVersion v);
+
+ virtual ~cmLocalVisualStudio10Generator();
+
+
+ /**
+ * Generate the makefile for this directory.
+ */
+ virtual void Generate();
+ virtual void ReadAndStoreExternalGUID(const char* name,
+ const char* path);
+
+protected:
+ virtual const char* ReportErrorLabel() const;
+ virtual bool CustomCommandUseLocal() const { return true; }
+
+private:
+};
+#endif
diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx
new file mode 100644
index 000000000..5ab223b7e
--- /dev/null
+++ b/Source/cmLocalVisualStudio6Generator.cxx
@@ -0,0 +1,1904 @@
+/*============================================================================
+ 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 "cmGlobalGenerator.h"
+#include "cmLocalVisualStudio6Generator.h"
+#include "cmMakefile.h"
+#include "cmSystemTools.h"
+#include "cmSourceFile.h"
+#include "cmCacheManager.h"
+#include "cmGeneratorTarget.h"
+#include "cmake.h"
+
+#include "cmComputeLinkInformation.h"
+
+#include <cmsys/RegularExpression.hxx>
+
+cmLocalVisualStudio6Generator::cmLocalVisualStudio6Generator():
+ cmLocalVisualStudioGenerator(VS6)
+{
+}
+
+cmLocalVisualStudio6Generator::~cmLocalVisualStudio6Generator()
+{
+}
+
+//----------------------------------------------------------------------------
+// Helper class to write build events.
+class cmLocalVisualStudio6Generator::EventWriter
+{
+public:
+ EventWriter(cmLocalVisualStudio6Generator* lg,
+ const char* config, std::string& code):
+ LG(lg), Config(config), Code(code), First(true) {}
+ void Start(const char* event)
+ {
+ this->First = true;
+ this->Event = event;
+ }
+ void Finish()
+ {
+ this->Code += (this->First? "" : "\n");
+ }
+ void Write(std::vector<cmCustomCommand> const& ccs)
+ {
+ for(std::vector<cmCustomCommand>::const_iterator ci = ccs.begin();
+ ci != ccs.end(); ++ci)
+ {
+ this->Write(*ci);
+ }
+ }
+ void Write(cmCustomCommand const& cc)
+ {
+ if(this->First)
+ {
+ this->Code += this->Event + "_Cmds=";
+ this->First = false;
+ }
+ else
+ {
+ this->Code += "\\\n\t";
+ }
+ this->Code += this->LG->ConstructScript(cc, this->Config, "\\\n\t");
+ }
+private:
+ cmLocalVisualStudio6Generator* LG;
+ const char* 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++)
+ {
+ // 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);
+ }
+ }
+}
+
+void cmLocalVisualStudio6Generator::Generate()
+{
+ this->OutputDSPFile();
+}
+
+void cmLocalVisualStudio6Generator::OutputDSPFile()
+{
+ // If not an in source build, then create the output directory
+ if(strcmp(this->Makefile->GetStartOutputDirectory(),
+ this->Makefile->GetHomeDirectory()) != 0)
+ {
+ if(!cmSystemTools::MakeDirectory
+ (this->Makefile->GetStartOutputDirectory()))
+ {
+ cmSystemTools::Error("Error creating directory ",
+ this->Makefile->GetStartOutputDirectory());
+ }
+ }
+
+ // 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++)
+ {
+ switch(l->second.GetType())
+ {
+ case cmTarget::STATIC_LIBRARY:
+ case cmTarget::OBJECT_LIBRARY:
+ this->SetBuildType(STATIC_LIBRARY, l->first.c_str(), l->second);
+ break;
+ case cmTarget::SHARED_LIBRARY:
+ case cmTarget::MODULE_LIBRARY:
+ this->SetBuildType(DLL, l->first.c_str(), l->second);
+ break;
+ case cmTarget::EXECUTABLE:
+ this->SetBuildType(EXECUTABLE,l->first.c_str(), l->second);
+ break;
+ case cmTarget::UTILITY:
+ case cmTarget::GLOBAL_TARGET:
+ this->SetBuildType(UTILITY, l->first.c_str(), l->second);
+ break;
+ default:
+ cmSystemTools::Error("Bad target type", l->first.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");
+ if(!path)
+ {
+ // check to see if the dsp is going into a sub-directory
+ std::string::size_type pos = l->first.rfind('/');
+ if(pos != std::string::npos)
+ {
+ std::string dir = this->Makefile->GetStartOutputDirectory();
+ dir += "/";
+ dir += l->first.substr(0, pos);
+ if(!cmSystemTools::MakeDirectory(dir.c_str()))
+ {
+ cmSystemTools::Error("Error creating directory ", dir.c_str());
+ }
+ }
+ this->CreateSingleDSP(l->first.c_str(),l->second);
+ }
+ }
+}
+
+// Utility function to make a valid VS6 *.dsp filename out
+// of a CMake target name:
+//
+extern std::string GetVS6TargetName(const std::string& targetName);
+
+void cmLocalVisualStudio6Generator::CreateSingleDSP(const char *lname,
+ cmTarget &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 += "/";
+ fname += pname;
+ fname += ".dsp";
+ // save the name of the real dsp file
+ std::string realDSP = fname;
+ fname += ".cmake";
+ std::ofstream fout(fname.c_str());
+ if(!fout)
+ {
+ cmSystemTools::Error("Error Writing ", fname.c_str());
+ cmSystemTools::ReportLastSystemError("");
+ }
+ this->WriteDSPFile(fout,pname.c_str(),target);
+ fout.close();
+ // if the dsp file has changed, then write it.
+ cmSystemTools::CopyFileIfDifferent(fname.c_str(), realDSP.c_str());
+}
+
+
+void cmLocalVisualStudio6Generator::AddDSPBuildRule(cmTarget& tgt)
+{
+ 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();
+ makefileIn += "/";
+ makefileIn += "CMakeLists.txt";
+ if(!cmSystemTools::FileExists(makefileIn.c_str()))
+ {
+ return;
+ }
+ std::string comment = "Building Custom Rule ";
+ comment += makefileIn;
+ std::string args;
+ args = "-H";
+ args += this->Convert(this->Makefile->GetHomeDirectory(),
+ START_OUTPUT, UNCHANGED, true);
+ commandLine.push_back(args);
+ args = "-B";
+ args +=
+ this->Convert(this->Makefile->GetHomeOutputDirectory(),
+ START_OUTPUT, UNCHANGED, true);
+ commandLine.push_back(args);
+
+ std::vector<std::string> const& listFiles = this->Makefile->GetListFiles();
+
+ cmCustomCommandLines commandLines;
+ commandLines.push_back(commandLine);
+ const char* no_working_directory = 0;
+ this->Makefile->AddCustomCommandToOutput(dspname.c_str(), listFiles,
+ makefileIn.c_str(), commandLines,
+ comment.c_str(),
+ no_working_directory, true);
+ if(cmSourceFile* file = this->Makefile->GetSource(makefileIn.c_str()))
+ {
+ tgt.AddSourceFile(file);
+ }
+ else
+ {
+ cmSystemTools::Error("Error adding rule for ", makefileIn.c_str());
+ }
+}
+
+
+void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout,
+ const char *libName,
+ cmTarget &target)
+{
+ // For utility targets need custom command since pre- and post-
+ // build does not do anything in Visual Studio 6. In order for the
+ // rules to run in the correct order as custom commands, we need
+ // 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()))
+ {
+ // 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)
+ {
+ 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)
+ {
+ depends.insert(depends.end(),
+ cr->GetDepends().begin(), cr->GetDepends().end());
+ }
+
+ // 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)
+ {
+ this->AddUtilityCommandHack(target, count++, depends, *cr);
+ }
+ for (std::vector<cmCustomCommand>::const_iterator cr =
+ target.GetPostBuildCommands().begin();
+ cr != target.GetPostBuildCommands().end(); ++cr)
+ {
+ this->AddUtilityCommandHack(target, count++, depends, *cr);
+ }
+ }
+
+ // 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
+ std::vector<cmSourceFile*> const & classes = target.GetSourceFiles();
+
+ // 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++)
+ {
+ // Add the file to the list of sources.
+ std::string source = (*i)->GetFullPath();
+ cmSourceGroup& sourceGroup =
+ this->Makefile->FindSourceGroup(source.c_str(), sourceGroups);
+ 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"))
+ {
+ if(!cmSystemTools::FileExists(source.c_str()))
+ {
+ cmSystemTools::ReplaceString(source, "$(IntDir)/", "");
+#if defined(_WIN32) || defined(__CYGWIN__)
+ std::ofstream fout(source.c_str(),
+ std::ios::binary | std::ios::out
+ | std::ios::trunc);
+#else
+ std::ofstream fout(source.c_str(),
+ std::ios::out | std::ios::trunc);
+#endif
+ if(fout)
+ {
+ fout.write("# generated from CMake",22);
+ fout.flush();
+ fout.close();
+ }
+ }
+ }
+ }
+
+ // Write the DSP file's header.
+ this->WriteDSPHeader(fout, libName, target, sourceGroups);
+
+
+ // Loop through every source group.
+ for(std::vector<cmSourceGroup>::const_iterator sg = sourceGroups.begin();
+ sg != sourceGroups.end(); ++sg)
+ {
+ this->WriteGroup(&(*sg), target, fout, libName);
+ }
+
+ // Write the DSP file's footer.
+ this->WriteDSPFooter(fout);
+}
+
+void cmLocalVisualStudio6Generator
+::WriteGroup(const cmSourceGroup *sg, cmTarget& target,
+ std::ostream &fout, const char *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.
+
+ if(sourceFiles.empty() && sg->GetGroupChildren().empty())
+ {
+ return;
+ }
+
+ // If the group has a name, write the header.
+ std::string name = sg->GetName();
+ if(name != "")
+ {
+ this->WriteDSPBeginGroup(fout, name.c_str(), "");
+ }
+
+ // Loop through each source in the source group.
+ for(std::vector<const cmSourceFile *>::const_iterator sf =
+ sourceFiles.begin(); sf != sourceFiles.end(); ++sf)
+ {
+ 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())
+ {
+ objectNameDir = cmSystemTools::GetFilenamePath(gt->Objects[*sf]);
+ }
+
+ // Add per-source file flags.
+ if(const char* cflags = (*sf)->GetProperty("COMPILE_FLAGS"))
+ {
+ compileFlags += cflags;
+ }
+
+ const char* lang = this->GetSourceFileLanguage(*(*sf));
+ if(lang)
+ {
+ 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 ";
+ }
+ }
+
+ // Add per-source and per-configuration preprocessor definitions.
+ std::map<cmStdString, cmStdString> cdmap;
+ this->AppendDefines(compileFlags,
+ (*sf)->GetProperty("COMPILE_DEFINITIONS"), lang);
+ if(const char* cdefs = (*sf)->GetProperty("COMPILE_DEFINITIONS_DEBUG"))
+ {
+ this->AppendDefines(cdmap["DEBUG"], cdefs, lang);
+ }
+ if(const char* cdefs = (*sf)->GetProperty("COMPILE_DEFINITIONS_RELEASE"))
+ {
+ this->AppendDefines(cdmap["RELEASE"], cdefs, lang);
+ }
+ if(const char* cdefs =
+ (*sf)->GetProperty("COMPILE_DEFINITIONS_MINSIZEREL"))
+ {
+ this->AppendDefines(cdmap["MINSIZEREL"], cdefs, lang);
+ }
+ if(const char* cdefs =
+ (*sf)->GetProperty("COMPILE_DEFINITIONS_RELWITHDEBINFO"))
+ {
+ this->AppendDefines(cdmap["RELWITHDEBINFO"], cdefs, lang);
+ }
+
+ bool excludedFromBuild =
+ (lang && (*sf)->GetPropertyAsBool("HEADER_FILE_ONLY"));
+
+ // Check for extra object-file dependencies.
+ const char* dependsValue = (*sf)->GetProperty("OBJECT_DEPENDS");
+ if(dependsValue)
+ {
+ cmSystemTools::ExpandListArgument(dependsValue, depends);
+ }
+ if (GetVS6TargetName(source) != libName ||
+ target.GetType() == cmTarget::UTILITY ||
+ target.GetType() == cmTarget::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";
+ if(!depends.empty())
+ {
+ // Write out the dependencies for the rule.
+ fout << "USERDEP__HACK=";
+ for(std::vector<std::string>::const_iterator d = depends.begin();
+ d != depends.end(); ++d)
+ {
+ fout << "\\\n\t" <<
+ this->ConvertToOptionallyRelativeOutputPath(d->c_str());
+ }
+ fout << "\n";
+ }
+ if (command)
+ {
+ const char* flags = compileFlags.size() ? compileFlags.c_str(): 0;
+ this->WriteCustomRule(fout, source.c_str(), *command, flags);
+ }
+ else if(!compileFlags.empty() || !objectNameDir.empty() ||
+ excludedFromBuild || !cdmap.empty())
+ {
+ for(std::vector<std::string>::iterator i
+ = this->Configurations.begin();
+ i != this->Configurations.end(); ++i)
+ {
+ // Strip the subdirectory name out of the configuration name.
+ std::string config = this->GetConfigName(*i);
+ if (i == this->Configurations.begin())
+ {
+ fout << "!IF \"$(CFG)\" == " << i->c_str() << std::endl;
+ }
+ else
+ {
+ fout << "!ELSEIF \"$(CFG)\" == " << i->c_str() << std::endl;
+ }
+ if(excludedFromBuild)
+ {
+ fout << "# PROP Exclude_From_Build 1\n";
+ }
+ if(!compileFlags.empty())
+ {
+ fout << "\n# ADD CPP " << compileFlags << "\n\n";
+ }
+ std::map<cmStdString, cmStdString>::iterator cdi =
+ cdmap.find(cmSystemTools::UpperCase(config));
+ if(cdi != cdmap.end() && !cdi->second.empty())
+ {
+ fout << "\n# ADD CPP " << cdi->second << "\n\n";
+ }
+ if(!objectNameDir.empty())
+ {
+ // Setup an alternate object file directory.
+ fout << "\n# PROP Intermediate_Dir \""
+ << config << "/" << objectNameDir << "\"\n\n";
+ }
+ }
+ fout << "!ENDIF\n\n";
+ }
+ fout << "# End Source File\n";
+ }
+ }
+
+ std::vector<cmSourceGroup> const& children = sg->GetGroupChildren();
+
+ for(unsigned int i=0;i<children.size();++i)
+ {
+ this->WriteGroup(&children[i], target, fout, libName);
+ }
+
+
+
+
+ // If the group has a name, write the footer.
+ if(name != "")
+ {
+ this->WriteDSPEndGroup(fout);
+ }
+
+}
+
+
+void
+cmLocalVisualStudio6Generator
+::AddUtilityCommandHack(cmTarget& 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>");
+
+ // Add the rule with the given dependencies and commands.
+ const char* no_main_dependency = 0;
+ this->Makefile->AddCustomCommandToOutput(output,
+ depends,
+ no_main_dependency,
+ origCommand.GetCommandLines(),
+ comment.c_str(),
+ origCommand.GetWorkingDirectory());
+
+ // Replace the dependencies with the output of this rule so that the
+ // next rule added will run after this one.
+ depends.clear();
+ depends.push_back(output);
+
+ // Add a source file representing this output to the project.
+ cmSourceFile* outsf = this->Makefile->GetSourceFileWithOutput(output);
+ target.AddSourceFile(outsf);
+
+ // Free the fake output name.
+ delete [] output;
+}
+
+void
+cmLocalVisualStudio6Generator
+::WriteCustomRule(std::ostream& fout,
+ const char* source,
+ 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);
+ std::string script =
+ this->ConstructScript(command, config.c_str(), "\\\n\t");
+
+ if (i == this->Configurations.begin())
+ {
+ fout << "!IF \"$(CFG)\" == " << i->c_str() << std::endl;
+ }
+ else
+ {
+ fout << "!ELSEIF \"$(CFG)\" == " << i->c_str() << std::endl;
+ }
+ if(flags)
+ {
+ fout << "\n# ADD CPP " << flags << "\n\n";
+ }
+ // 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();
+ ++d)
+ {
+ // Lookup the real name of the dependency in case it is a CMake target.
+ std::string dep;
+ if(this->GetRealDependency(d->c_str(), config.c_str(), dep))
+ {
+ fout << "\\\n\t" <<
+ this->ConvertToOptionallyRelativeOutputPath(dep.c_str());
+ }
+ }
+ fout << "\n";
+
+ fout << "# PROP Ignore_Default_Tool 1\n";
+ fout << "# Begin Custom Build -";
+ if(!comment.empty())
+ {
+ fout << " " << comment.c_str();
+ }
+ fout << "\n\n";
+ if(command.GetOutputs().empty())
+ {
+ fout << source
+ << "_force : \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"\n\t";
+ fout << script.c_str() << "\n\n";
+ }
+ else
+ {
+ for(std::vector<std::string>::const_iterator o =
+ command.GetOutputs().begin();
+ o != command.GetOutputs().end();
+ ++o)
+ {
+ // Write a rule for every output generated by this command.
+ fout << this->ConvertToOptionallyRelativeOutputPath(o->c_str())
+ << " : \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"\n\t";
+ fout << script.c_str() << "\n\n";
+ }
+ }
+ fout << "# End Custom Build\n\n";
+ }
+
+ fout << "!ENDIF\n\n";
+}
+
+
+void cmLocalVisualStudio6Generator::WriteDSPBeginGroup(std::ostream& fout,
+ const char* group,
+ const char* filter)
+{
+ fout << "# Begin Group \"" << group << "\"\n"
+ "# PROP Default_Filter \"" << filter << "\"\n";
+}
+
+
+void cmLocalVisualStudio6Generator::WriteDSPEndGroup(std::ostream& fout)
+{
+ fout << "# End Group\n";
+}
+
+
+
+
+void cmLocalVisualStudio6Generator::SetBuildType(BuildType b,
+ const char* libName,
+ cmTarget& target)
+{
+ std::string root= this->Makefile->GetRequiredDefinition("CMAKE_ROOT");
+ const char *def=
+ this->Makefile->GetDefinition( "MSPROJECT_TEMPLATE_DIRECTORY");
+
+ if( def)
+ {
+ root = def;
+ }
+ else
+ {
+ root += "/Templates";
+ }
+
+ switch(b)
+ {
+ case STATIC_LIBRARY:
+ this->DSPHeaderTemplate = root;
+ this->DSPHeaderTemplate += "/staticLibHeader.dsptemplate";
+ this->DSPFooterTemplate = root;
+ this->DSPFooterTemplate += "/staticLibFooter.dsptemplate";
+ break;
+ case DLL:
+ this->DSPHeaderTemplate = root;
+ this->DSPHeaderTemplate += "/DLLHeader.dsptemplate";
+ this->DSPFooterTemplate = root;
+ this->DSPFooterTemplate += "/DLLFooter.dsptemplate";
+ break;
+ case EXECUTABLE:
+ if ( target.GetPropertyAsBool("WIN32_EXECUTABLE") )
+ {
+ this->DSPHeaderTemplate = root;
+ this->DSPHeaderTemplate += "/EXEWinHeader.dsptemplate";
+ this->DSPFooterTemplate = root;
+ this->DSPFooterTemplate += "/EXEFooter.dsptemplate";
+ }
+ else
+ {
+ this->DSPHeaderTemplate = root;
+ this->DSPHeaderTemplate += "/EXEHeader.dsptemplate";
+ this->DSPFooterTemplate = root;
+ this->DSPFooterTemplate += "/EXEFooter.dsptemplate";
+ }
+ break;
+ case UTILITY:
+ this->DSPHeaderTemplate = root;
+ this->DSPHeaderTemplate += "/UtilityHeader.dsptemplate";
+ this->DSPFooterTemplate = root;
+ this->DSPFooterTemplate += "/UtilityFooter.dsptemplate";
+ break;
+ }
+
+ // once the build type is set, determine what configurations are
+ // possible
+ std::ifstream fin(this->DSPHeaderTemplate.c_str());
+
+ cmsys::RegularExpression reg("# Name ");
+ if(!fin)
+ {
+ cmSystemTools::Error("Error Reading ", this->DSPHeaderTemplate.c_str());
+ }
+
+ // reset this->Configurations
+ this->Configurations.erase(this->Configurations.begin(),
+ this->Configurations.end());
+
+ // now add all the configurations possible
+ std::string vs6name = GetVS6TargetName(libName);
+ std::string line;
+ while(cmSystemTools::GetLineFromStream(fin, line))
+ {
+ cmSystemTools::ReplaceString(line, "OUTPUT_LIBNAME", vs6name.c_str());
+ if (reg.find(line))
+ {
+ this->Configurations.push_back(line.substr(reg.end()));
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+cmsys::auto_ptr<cmCustomCommand>
+cmLocalVisualStudio6Generator::MaybeCreateOutputDir(cmTarget& target,
+ const char* 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);
+
+ // Add a pre-link event to create the directory.
+ cmCustomCommandLine command;
+ command.push_back(this->Makefile->GetRequiredDefinition("CMAKE_COMMAND"));
+ command.push_back("-E");
+ command.push_back("make_directory");
+ command.push_back(outDir);
+ std::vector<std::string> no_output;
+ 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->SetEscapeOldStyle(false);
+ pcc->SetEscapeAllowMakeVars(true);
+ return pcc;
+}
+
+// look for custom rules on a target and collect them together
+std::string
+cmLocalVisualStudio6Generator::CreateTargetRules(cmTarget &target,
+ const char* configName,
+ const char * /* libName */)
+{
+ if (target.GetType() >= cmTarget::UTILITY )
+ {
+ return "";
+ }
+
+ std::string customRuleCode = "# Begin Special Build Tool\n";
+ EventWriter event(this, configName, customRuleCode);
+
+ // Write the pre-build and pre-link together (VS6 does not support both).
+ event.Start("PreLink");
+ event.Write(target.GetPreBuildCommands());
+ event.Write(target.GetPreLinkCommands());
+ cmsys::auto_ptr<cmCustomCommand> pcc(
+ this->MaybeCreateImplibDir(target, configName, false));
+ if(pcc.get())
+ {
+ event.Write(*pcc);
+ }
+ pcc = this->MaybeCreateOutputDir(target, configName);
+ if(pcc.get())
+ {
+ event.Write(*pcc);
+ }
+ event.Finish();
+
+ // Write the post-build rules.
+ event.Start("PostBuild");
+ event.Write(target.GetPostBuildCommands());
+ event.Finish();
+
+ customRuleCode += "# End Special Build Tool\n";
+ return customRuleCode;
+}
+
+
+inline std::string removeQuotes(const std::string& s)
+{
+ if(s[0] == '\"' && s[s.size()-1] == '\"')
+ {
+ return s.substr(1, s.size()-2);
+ }
+ return s;
+}
+
+
+std::string
+cmLocalVisualStudio6Generator::GetTargetIncludeOptions(cmTarget &target)
+{
+ std::string includeOptions;
+
+ // Setup /I and /LIBPATH options for the resulting DSP file. VS 6
+ // truncates long include paths so make it as short as possible if
+ // the length threatens this problem.
+ unsigned int maxIncludeLength = 3000;
+ bool useShortPath = false;
+ for(int j=0; j < 2; ++j)
+ {
+ std::vector<std::string> includes;
+ this->GetIncludeDirectories(includes, &target);
+
+ std::vector<std::string>::iterator i;
+ for(i = includes.begin(); i != includes.end(); ++i)
+ {
+ std::string tmp =
+ this->ConvertToOptionallyRelativeOutputPath(i->c_str());
+ if(useShortPath)
+ {
+ cmSystemTools::GetShortPath(tmp.c_str(), tmp);
+ }
+ includeOptions += " /I ";
+
+ // quote if not already quoted
+ if (tmp[0] != '"')
+ {
+ includeOptions += "\"";
+ includeOptions += tmp;
+ includeOptions += "\"";
+ }
+ else
+ {
+ includeOptions += tmp;
+ }
+ }
+
+ if(j == 0 && includeOptions.size() > maxIncludeLength)
+ {
+ includeOptions = "";
+ useShortPath = true;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ return includeOptions;
+}
+
+
+// Code in blocks surrounded by a test for this definition is needed
+// only for compatibility with user project's replacement DSP
+// templates. The CMake templates no longer use them.
+#define CM_USE_OLD_VS6
+
+void cmLocalVisualStudio6Generator
+::WriteDSPHeader(std::ostream& fout,
+ const char *libName, cmTarget &target,
+ std::vector<cmSourceGroup> &)
+{
+ bool targetBuilds = (target.GetType() >= cmTarget::EXECUTABLE &&
+ target.GetType() <= cmTarget::MODULE_LIBRARY);
+#ifdef CM_USE_OLD_VS6
+ // Lookup the library and executable output directories.
+ std::string libPath;
+ if(this->Makefile->GetDefinition("LIBRARY_OUTPUT_PATH"))
+ {
+ libPath = this->Makefile->GetDefinition("LIBRARY_OUTPUT_PATH");
+ }
+ std::string exePath;
+ if(this->Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH"))
+ {
+ exePath = this->Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH");
+ }
+
+ // Make sure there are trailing slashes.
+ if(!libPath.empty())
+ {
+ if(libPath[libPath.size()-1] != '/')
+ {
+ libPath += "/";
+ }
+ }
+ if(!exePath.empty())
+ {
+ if(exePath[exePath.size()-1] != '/')
+ {
+ exePath += "/";
+ }
+ }
+
+ std::set<std::string> pathEmitted;
+
+ // determine the link directories
+ std::string libOptions;
+ std::string libDebugOptions;
+ std::string libOptimizedOptions;
+
+ std::string libMultiLineOptions;
+ std::string libMultiLineOptionsForDebug;
+ std::string libMultiLineDebugOptions;
+ std::string libMultiLineOptimizedOptions;
+
+ if(libPath.size())
+ {
+ std::string lpath =
+ this->ConvertToOptionallyRelativeOutputPath(libPath.c_str());
+ if(lpath.size() == 0)
+ {
+ lpath = ".";
+ }
+ std::string lpathIntDir = libPath + "$(INTDIR)";
+ lpathIntDir =
+ this->ConvertToOptionallyRelativeOutputPath(lpathIntDir.c_str());
+ if(pathEmitted.insert(lpath).second)
+ {
+ libOptions += " /LIBPATH:";
+ libOptions += lpathIntDir;
+ libOptions += " ";
+ libOptions += " /LIBPATH:";
+ libOptions += lpath;
+ libOptions += " ";
+ libMultiLineOptions += "# ADD LINK32 /LIBPATH:";
+ libMultiLineOptions += lpathIntDir;
+ libMultiLineOptions += " ";
+ libMultiLineOptions += " /LIBPATH:";
+ libMultiLineOptions += lpath;
+ libMultiLineOptions += " \n";
+ libMultiLineOptionsForDebug += "# ADD LINK32 /LIBPATH:";
+ libMultiLineOptionsForDebug += lpathIntDir;
+ libMultiLineOptionsForDebug += " ";
+ libMultiLineOptionsForDebug += " /LIBPATH:";
+ libMultiLineOptionsForDebug += lpath;
+ libMultiLineOptionsForDebug += " \n";
+ }
+ }
+ if(exePath.size())
+ {
+ std::string lpath =
+ this->ConvertToOptionallyRelativeOutputPath(exePath.c_str());
+ if(lpath.size() == 0)
+ {
+ lpath = ".";
+ }
+ std::string lpathIntDir = exePath + "$(INTDIR)";
+ lpathIntDir =
+ this->ConvertToOptionallyRelativeOutputPath(lpathIntDir.c_str());
+
+ if(pathEmitted.insert(lpath).second)
+ {
+ libOptions += " /LIBPATH:";
+ libOptions += lpathIntDir;
+ libOptions += " ";
+ libOptions += " /LIBPATH:";
+ libOptions += lpath;
+ libOptions += " ";
+ libMultiLineOptions += "# ADD LINK32 /LIBPATH:";
+ libMultiLineOptions += lpathIntDir;
+ libMultiLineOptions += " ";
+ libMultiLineOptions += " /LIBPATH:";
+ libMultiLineOptions += lpath;
+ libMultiLineOptions += " \n";
+ libMultiLineOptionsForDebug += "# ADD LINK32 /LIBPATH:";
+ libMultiLineOptionsForDebug += lpathIntDir;
+ libMultiLineOptionsForDebug += " ";
+ libMultiLineOptionsForDebug += " /LIBPATH:";
+ libMultiLineOptionsForDebug += lpath;
+ libMultiLineOptionsForDebug += " \n";
+ }
+ }
+ std::vector<std::string>::const_iterator i;
+ const std::vector<std::string>& libdirs = target.GetLinkDirectories();
+ for(i = libdirs.begin(); i != libdirs.end(); ++i)
+ {
+ std::string path = *i;
+ if(path[path.size()-1] != '/')
+ {
+ path += "/";
+ }
+ std::string lpath =
+ this->ConvertToOptionallyRelativeOutputPath(path.c_str());
+ if(lpath.size() == 0)
+ {
+ lpath = ".";
+ }
+ std::string lpathIntDir = path + "$(INTDIR)";
+ lpathIntDir =
+ this->ConvertToOptionallyRelativeOutputPath(lpathIntDir.c_str());
+ if(pathEmitted.insert(lpath).second)
+ {
+ libOptions += " /LIBPATH:";
+ libOptions += lpathIntDir;
+ libOptions += " ";
+ libOptions += " /LIBPATH:";
+ libOptions += lpath;
+ libOptions += " ";
+
+ libMultiLineOptions += "# ADD LINK32 /LIBPATH:";
+ libMultiLineOptions += lpathIntDir;
+ libMultiLineOptions += " ";
+ libMultiLineOptions += " /LIBPATH:";
+ libMultiLineOptions += lpath;
+ libMultiLineOptions += " \n";
+ libMultiLineOptionsForDebug += "# ADD LINK32 /LIBPATH:";
+ libMultiLineOptionsForDebug += lpathIntDir;
+ libMultiLineOptionsForDebug += " ";
+ libMultiLineOptionsForDebug += " /LIBPATH:";
+ libMultiLineOptionsForDebug += lpath;
+ libMultiLineOptionsForDebug += " \n";
+ }
+ }
+ // find link libraries
+ const cmTarget::LinkLibraryVectorType& libs = target.GetLinkLibraries();
+ 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
+ && libName != GetVS6TargetName(j->first)) ||
+ (target.GetType()==cmTarget::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());
+ if(tgt)
+ {
+ lib = cmSystemTools::GetFilenameWithoutExtension
+ (tgt->GetFullName().c_str());
+ libDebug = cmSystemTools::GetFilenameWithoutExtension
+ (tgt->GetFullName("Debug").c_str());
+ lib += ".lib";
+ libDebug += ".lib";
+ }
+ else
+ {
+ lib = j->first.c_str();
+ libDebug = j->first.c_str();
+ if(j->first.find(".lib") == std::string::npos)
+ {
+ lib += ".lib";
+ libDebug += ".lib";
+ }
+ }
+ lib = this->ConvertToOptionallyRelativeOutputPath(lib.c_str());
+ libDebug =
+ this->ConvertToOptionallyRelativeOutputPath(libDebug.c_str());
+
+ if (j->second == cmTarget::GENERAL)
+ {
+ libOptions += " ";
+ libOptions += lib;
+ libMultiLineOptions += "# ADD LINK32 ";
+ libMultiLineOptions += lib;
+ libMultiLineOptions += "\n";
+ libMultiLineOptionsForDebug += "# ADD LINK32 ";
+ libMultiLineOptionsForDebug += libDebug;
+ libMultiLineOptionsForDebug += "\n";
+ }
+ if (j->second == cmTarget::DEBUG)
+ {
+ libDebugOptions += " ";
+ libDebugOptions += lib;
+
+ libMultiLineDebugOptions += "# ADD LINK32 ";
+ libMultiLineDebugOptions += libDebug;
+ libMultiLineDebugOptions += "\n";
+ }
+ if (j->second == cmTarget::OPTIMIZED)
+ {
+ libOptimizedOptions += " ";
+ libOptimizedOptions += lib;
+
+ libMultiLineOptimizedOptions += "# ADD LINK32 ";
+ libMultiLineOptimizedOptions += lib;
+ libMultiLineOptimizedOptions += "\n";
+ }
+ }
+ }
+#endif
+
+ // Get include options for this target.
+ std::string includeOptions = this->GetTargetIncludeOptions(target);
+
+ // Get extra linker options for this target type.
+ std::string extraLinkOptions;
+ std::string extraLinkOptionsDebug;
+ std::string extraLinkOptionsRelease;
+ std::string extraLinkOptionsMinSizeRel;
+ std::string extraLinkOptionsRelWithDebInfo;
+ if(target.GetType() == cmTarget::EXECUTABLE)
+ {
+ extraLinkOptions =
+ this->Makefile->GetRequiredDefinition("CMAKE_EXE_LINKER_FLAGS");
+ }
+ if(target.GetType() == cmTarget::SHARED_LIBRARY)
+ {
+ extraLinkOptions =
+ this->Makefile->GetRequiredDefinition("CMAKE_SHARED_LINKER_FLAGS");
+ }
+ if(target.GetType() == cmTarget::MODULE_LIBRARY)
+ {
+ extraLinkOptions =
+ this->Makefile->GetRequiredDefinition("CMAKE_MODULE_LINKER_FLAGS");
+ }
+
+ // Get extra linker options for this target.
+ if(const char* targetLinkFlags = target.GetProperty("LINK_FLAGS"))
+ {
+ extraLinkOptions += " ";
+ extraLinkOptions += targetLinkFlags;
+ }
+
+ if(const char* targetLinkFlags = target.GetProperty("LINK_FLAGS_DEBUG"))
+ {
+ extraLinkOptionsDebug += " ";
+ extraLinkOptionsDebug += targetLinkFlags;
+ }
+
+ if(const char* targetLinkFlags = target.GetProperty("LINK_FLAGS_RELEASE"))
+ {
+ extraLinkOptionsRelease += " ";
+ extraLinkOptionsRelease += targetLinkFlags;
+ }
+
+ if(const char* targetLinkFlags = target.GetProperty("LINK_FLAGS_MINSIZEREL"))
+ {
+ extraLinkOptionsMinSizeRel += " ";
+ extraLinkOptionsMinSizeRel += targetLinkFlags;
+ }
+
+ if(const char* targetLinkFlags =
+ 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)
+ {
+ cmSystemTools::Error
+ ("CMake can not determine linker language for target:",
+ target.GetName());
+ return;
+ }
+
+ // Compute the variable name to lookup standard libraries for this
+ // language.
+ std::string standardLibsVar = "CMAKE_";
+ standardLibsVar += linkLanguage;
+ standardLibsVar += "_STANDARD_LIBRARIES";
+
+ // Add standard libraries.
+ if(const char* stdLibs =
+ this->Makefile->GetDefinition(standardLibsVar.c_str()))
+ {
+ extraLinkOptions += " ";
+ extraLinkOptions += stdLibs;
+ }
+ }
+
+ // Compute version number information.
+ std::string targetVersionFlag;
+ if(target.GetType() == cmTarget::EXECUTABLE ||
+ target.GetType() == cmTarget::SHARED_LIBRARY ||
+ target.GetType() == cmTarget::MODULE_LIBRARY)
+ {
+ int major;
+ int minor;
+ target.GetTargetVersion(major, minor);
+ cmOStringStream targetVersionStream;
+ targetVersionStream << "/version:" << major << "." << minor;
+ targetVersionFlag = targetVersionStream.str();
+ }
+
+ // Compute the real name of the target.
+ std::string outputName =
+ "(OUTPUT_NAME is for libraries and executables only)";
+ std::string outputNameDebug = outputName;
+ 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)
+ {
+ 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)
+ {
+ outputName = target.GetName();
+ outputName += ".lib";
+ outputNameDebug = outputName;
+ outputNameRelease = outputName;
+ outputNameMinSizeRel = outputName;
+ outputNameRelWithDebInfo = outputName;
+ }
+
+ // Compute the output directory for the target.
+ std::string outputDirOld;
+ std::string outputDirDebug;
+ 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)
+ {
+#ifdef CM_USE_OLD_VS6
+ outputDirOld =
+ removeQuotes(this->ConvertToOptionallyRelativeOutputPath
+ (target.GetDirectory().c_str()));
+#endif
+ outputDirDebug =
+ removeQuotes(this->ConvertToOptionallyRelativeOutputPath(
+ target.GetDirectory("Debug").c_str()));
+ outputDirRelease =
+ removeQuotes(this->ConvertToOptionallyRelativeOutputPath(
+ target.GetDirectory("Release").c_str()));
+ outputDirMinSizeRel =
+ removeQuotes(this->ConvertToOptionallyRelativeOutputPath(
+ target.GetDirectory("MinSizeRel").c_str()));
+ outputDirRelWithDebInfo =
+ removeQuotes(this->ConvertToOptionallyRelativeOutputPath(
+ target.GetDirectory("RelWithDebInfo").c_str()));
+ }
+ else if(target.GetType() == cmTarget::OBJECT_LIBRARY)
+ {
+ std::string outputDir = cmake::GetCMakeFilesDirectoryPostSlash();
+ outputDirDebug = outputDir + "Debug";
+ outputDirRelease = outputDir + "Release";
+ outputDirMinSizeRel = outputDir + "MinSizeRel";
+ outputDirRelWithDebInfo = outputDir + "RelWithDebInfo";
+ }
+
+ // Compute the proper link information for the target.
+ std::string optionsDebug;
+ std::string optionsRelease;
+ std::string optionsMinSizeRel;
+ std::string optionsRelWithDebInfo;
+ if(target.GetType() == cmTarget::EXECUTABLE ||
+ target.GetType() == cmTarget::SHARED_LIBRARY ||
+ target.GetType() == cmTarget::MODULE_LIBRARY)
+ {
+ extraLinkOptionsDebug =
+ extraLinkOptions + " " + extraLinkOptionsDebug;
+ extraLinkOptionsRelease =
+ extraLinkOptions + " " + extraLinkOptionsRelease;
+ extraLinkOptionsMinSizeRel =
+ extraLinkOptions + " " + extraLinkOptionsMinSizeRel;
+ extraLinkOptionsRelWithDebInfo =
+ extraLinkOptions + " " + extraLinkOptionsRelWithDebInfo;
+ this->ComputeLinkOptions(target, "Debug", extraLinkOptionsDebug,
+ optionsDebug);
+ this->ComputeLinkOptions(target, "Release", extraLinkOptionsRelease,
+ optionsRelease);
+ this->ComputeLinkOptions(target, "MinSizeRel", extraLinkOptionsMinSizeRel,
+ optionsMinSizeRel);
+ this->ComputeLinkOptions(target, "RelWithDebInfo",
+ extraLinkOptionsRelWithDebInfo,
+ optionsRelWithDebInfo);
+ }
+
+ // Compute the path of the import library.
+ std::string targetImplibFlagDebug;
+ std::string targetImplibFlagRelease;
+ std::string targetImplibFlagMinSizeRel;
+ std::string targetImplibFlagRelWithDebInfo;
+ if(target.GetType() == cmTarget::SHARED_LIBRARY ||
+ target.GetType() == cmTarget::MODULE_LIBRARY ||
+ target.GetType() == cmTarget::EXECUTABLE)
+ {
+ std::string fullPathImpDebug = target.GetDirectory("Debug", true);
+ std::string fullPathImpRelease = target.GetDirectory("Release", true);
+ std::string fullPathImpMinSizeRel =
+ target.GetDirectory("MinSizeRel", true);
+ std::string fullPathImpRelWithDebInfo =
+ 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);
+
+ targetImplibFlagDebug = "/implib:";
+ targetImplibFlagRelease = "/implib:";
+ targetImplibFlagMinSizeRel = "/implib:";
+ targetImplibFlagRelWithDebInfo = "/implib:";
+ targetImplibFlagDebug +=
+ this->ConvertToOptionallyRelativeOutputPath(fullPathImpDebug.c_str());
+ targetImplibFlagRelease +=
+ this->ConvertToOptionallyRelativeOutputPath(fullPathImpRelease.c_str());
+ targetImplibFlagMinSizeRel +=
+ this->ConvertToOptionallyRelativeOutputPath(
+ fullPathImpMinSizeRel.c_str());
+ targetImplibFlagRelWithDebInfo +=
+ this->ConvertToOptionallyRelativeOutputPath(
+ fullPathImpRelWithDebInfo.c_str());
+ }
+
+#ifdef CM_USE_OLD_VS6
+ // Compute link information for the target.
+ if(extraLinkOptions.size())
+ {
+ libOptions += " ";
+ libOptions += extraLinkOptions;
+ libOptions += " ";
+ libMultiLineOptions += "# ADD LINK32 ";
+ libMultiLineOptions += extraLinkOptions;
+ libMultiLineOptions += " \n";
+ libMultiLineOptionsForDebug += "# ADD LINK32 ";
+ libMultiLineOptionsForDebug += extraLinkOptions;
+ libMultiLineOptionsForDebug += " \n";
+ }
+#endif
+
+ // are there any custom rules on the target itself
+ // only if the target is a lib or exe
+ std::string customRuleCodeRelease
+ = this->CreateTargetRules(target, "RELEASE", libName);
+ std::string customRuleCodeDebug
+ = this->CreateTargetRules(target, "DEBUG", libName);
+ std::string customRuleCodeMinSizeRel
+ = this->CreateTargetRules(target, "MINSIZEREL", libName);
+ std::string customRuleCodeRelWithDebInfo
+ = this->CreateTargetRules(target, "RELWITHDEBINFO", libName);
+
+ std::ifstream fin(this->DSPHeaderTemplate.c_str());
+ if(!fin)
+ {
+ cmSystemTools::Error("Error Reading ", this->DSPHeaderTemplate.c_str());
+ }
+ std::string staticLibOptions;
+ std::string staticLibOptionsDebug;
+ std::string staticLibOptionsRelease;
+ std::string staticLibOptionsMinSizeRel;
+ std::string staticLibOptionsRelWithDebInfo;
+ if(target.GetType() == cmTarget::STATIC_LIBRARY )
+ {
+ if(const char* libflags = target.GetProperty("STATIC_LIBRARY_FLAGS"))
+ {
+ staticLibOptions = libflags;
+ staticLibOptionsDebug = libflags;
+ staticLibOptionsRelease = libflags;
+ staticLibOptionsMinSizeRel = libflags;
+ staticLibOptionsRelWithDebInfo = libflags;
+ }
+ if(const char* libflagsDebug =
+ target.GetProperty("STATIC_LIBRARY_FLAGS_DEBUG"))
+ {
+ staticLibOptionsDebug += " ";
+ staticLibOptionsDebug = libflagsDebug;
+ }
+ if(const char* libflagsRelease =
+ target.GetProperty("STATIC_LIBRARY_FLAGS_RELEASE"))
+ {
+ staticLibOptionsRelease += " ";
+ staticLibOptionsRelease = libflagsRelease;
+ }
+ if(const char* libflagsMinSizeRel =
+ target.GetProperty("STATIC_LIBRARY_FLAGS_MINSIZEREL"))
+ {
+ staticLibOptionsMinSizeRel += " ";
+ staticLibOptionsMinSizeRel = libflagsMinSizeRel;
+ }
+ if(const char* libflagsRelWithDebInfo =
+ target.GetProperty("STATIC_LIBRARY_FLAGS_RELWITHDEBINFO"))
+ {
+ staticLibOptionsRelWithDebInfo += " ";
+ staticLibOptionsRelWithDebInfo = libflagsRelWithDebInfo;
+ }
+ std::string objects;
+ this->OutputObjects(target, "LIB", objects);
+ if(!objects.empty())
+ {
+ objects = "\n" + objects;
+ staticLibOptionsDebug += objects;
+ staticLibOptionsRelease += objects;
+ staticLibOptionsMinSizeRel += objects;
+ staticLibOptionsRelWithDebInfo += objects;
+ }
+ }
+
+ // Add the export symbol definition for shared library objects.
+ std::string exportSymbol;
+ if(const char* exportMacro = target.GetExportMacro())
+ {
+ exportSymbol = exportMacro;
+ }
+
+ std::string line;
+ std::string libnameExports;
+ if(exportSymbol.size())
+ {
+ libnameExports = "/D \"";
+ libnameExports += exportSymbol;
+ libnameExports += "\"";
+ }
+ while(cmSystemTools::GetLineFromStream(fin, line))
+ {
+ const char* mfcFlag = this->Makefile->GetDefinition("CMAKE_MFC_FLAG");
+ if(!mfcFlag)
+ {
+ mfcFlag = "0";
+ }
+ cmSystemTools::ReplaceString(line, "OUTPUT_LIBNAME_EXPORTS",
+ libnameExports.c_str());
+ cmSystemTools::ReplaceString(line, "CMAKE_MFC_FLAG",
+ mfcFlag);
+ if(target.GetType() == cmTarget::STATIC_LIBRARY ||
+ target.GetType() == cmTarget::OBJECT_LIBRARY)
+ {
+ cmSystemTools::ReplaceString(line, "CM_STATIC_LIB_ARGS_DEBUG",
+ staticLibOptionsDebug.c_str());
+ cmSystemTools::ReplaceString(line, "CM_STATIC_LIB_ARGS_RELEASE",
+ staticLibOptionsRelease.c_str());
+ cmSystemTools::ReplaceString(line, "CM_STATIC_LIB_ARGS_MINSIZEREL",
+ staticLibOptionsMinSizeRel.c_str());
+ cmSystemTools::ReplaceString(line, "CM_STATIC_LIB_ARGS_RELWITHDEBINFO",
+ staticLibOptionsRelWithDebInfo.c_str());
+ cmSystemTools::ReplaceString(line, "CM_STATIC_LIB_ARGS",
+ staticLibOptions.c_str());
+ }
+ if(this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE"))
+ {
+ cmSystemTools::ReplaceString(line, "/nologo", "");
+ }
+
+#ifdef CM_USE_OLD_VS6
+ cmSystemTools::ReplaceString(line, "CM_LIBRARIES",
+ libOptions.c_str());
+ cmSystemTools::ReplaceString(line, "CM_DEBUG_LIBRARIES",
+ libDebugOptions.c_str());
+ cmSystemTools::ReplaceString(line, "CM_OPTIMIZED_LIBRARIES",
+ libOptimizedOptions.c_str());
+ cmSystemTools::ReplaceString(line, "CM_MULTILINE_LIBRARIES_FOR_DEBUG",
+ libMultiLineOptionsForDebug.c_str());
+ cmSystemTools::ReplaceString(line, "CM_MULTILINE_LIBRARIES",
+ libMultiLineOptions.c_str());
+ cmSystemTools::ReplaceString(line, "CM_MULTILINE_DEBUG_LIBRARIES",
+ libMultiLineDebugOptions.c_str());
+ cmSystemTools::ReplaceString(line, "CM_MULTILINE_OPTIMIZED_LIBRARIES",
+ libMultiLineOptimizedOptions.c_str());
+#endif
+
+ // Substitute the rules for custom command. When specifying just the
+ // target name for the command the command can be different for
+ // different configs
+ cmSystemTools::ReplaceString(line, "CMAKE_CUSTOM_RULE_CODE_RELEASE",
+ customRuleCodeRelease.c_str());
+ cmSystemTools::ReplaceString(line, "CMAKE_CUSTOM_RULE_CODE_DEBUG",
+ customRuleCodeDebug.c_str());
+ cmSystemTools::ReplaceString(line, "CMAKE_CUSTOM_RULE_CODE_MINSIZEREL",
+ customRuleCodeMinSizeRel.c_str());
+ cmSystemTools::ReplaceString(line, "CMAKE_CUSTOM_RULE_CODE_RELWITHDEBINFO",
+ customRuleCodeRelWithDebInfo.c_str());
+
+ // Substitute the real output name into the template.
+ cmSystemTools::ReplaceString(line, "OUTPUT_NAME_DEBUG",
+ outputNameDebug.c_str());
+ cmSystemTools::ReplaceString(line, "OUTPUT_NAME_RELEASE",
+ outputNameRelease.c_str());
+ cmSystemTools::ReplaceString(line, "OUTPUT_NAME_MINSIZEREL",
+ outputNameMinSizeRel.c_str());
+ cmSystemTools::ReplaceString(line, "OUTPUT_NAME_RELWITHDEBINFO",
+ outputNameRelWithDebInfo.c_str());
+ cmSystemTools::ReplaceString(line, "OUTPUT_NAME", outputName.c_str());
+
+ // Substitute the proper link information into the template.
+ cmSystemTools::ReplaceString(line, "CM_MULTILINE_OPTIONS_DEBUG",
+ optionsDebug.c_str());
+ cmSystemTools::ReplaceString(line, "CM_MULTILINE_OPTIONS_RELEASE",
+ optionsRelease.c_str());
+ cmSystemTools::ReplaceString(line, "CM_MULTILINE_OPTIONS_MINSIZEREL",
+ optionsMinSizeRel.c_str());
+ cmSystemTools::ReplaceString(line, "CM_MULTILINE_OPTIONS_RELWITHDEBINFO",
+ optionsRelWithDebInfo.c_str());
+
+ cmSystemTools::ReplaceString(line, "BUILD_INCLUDES",
+ includeOptions.c_str());
+ cmSystemTools::ReplaceString(line, "TARGET_VERSION_FLAG",
+ targetVersionFlag.c_str());
+ cmSystemTools::ReplaceString(line, "TARGET_IMPLIB_FLAG_DEBUG",
+ targetImplibFlagDebug.c_str());
+ cmSystemTools::ReplaceString(line, "TARGET_IMPLIB_FLAG_RELEASE",
+ targetImplibFlagRelease.c_str());
+ cmSystemTools::ReplaceString(line, "TARGET_IMPLIB_FLAG_MINSIZEREL",
+ targetImplibFlagMinSizeRel.c_str());
+ cmSystemTools::ReplaceString(line, "TARGET_IMPLIB_FLAG_RELWITHDEBINFO",
+ targetImplibFlagRelWithDebInfo.c_str());
+
+ std::string vs6name = GetVS6TargetName(libName);
+ cmSystemTools::ReplaceString(line, "OUTPUT_LIBNAME", vs6name.c_str());
+
+#ifdef CM_USE_OLD_VS6
+ // because LIBRARY_OUTPUT_PATH and EXECUTABLE_OUTPUT_PATH
+ // are already quoted in the template file,
+ // we need to remove the quotes here, we still need
+ // to convert to output path for unix to win32 conversion
+ cmSystemTools::ReplaceString
+ (line, "LIBRARY_OUTPUT_PATH",
+ removeQuotes(this->ConvertToOptionallyRelativeOutputPath
+ (libPath.c_str())).c_str());
+ cmSystemTools::ReplaceString
+ (line, "EXECUTABLE_OUTPUT_PATH",
+ removeQuotes(this->ConvertToOptionallyRelativeOutputPath
+ (exePath.c_str())).c_str());
+#endif
+
+ if(targetBuilds || target.GetType() == cmTarget::OBJECT_LIBRARY)
+ {
+ cmSystemTools::ReplaceString(line, "OUTPUT_DIRECTORY_DEBUG",
+ outputDirDebug.c_str());
+ cmSystemTools::ReplaceString(line, "OUTPUT_DIRECTORY_RELEASE",
+ outputDirRelease.c_str());
+ cmSystemTools::ReplaceString(line, "OUTPUT_DIRECTORY_MINSIZEREL",
+ outputDirMinSizeRel.c_str());
+ cmSystemTools::ReplaceString(line, "OUTPUT_DIRECTORY_RELWITHDEBINFO",
+ outputDirRelWithDebInfo.c_str());
+ if(!outputDirOld.empty())
+ {
+ cmSystemTools::ReplaceString(line, "OUTPUT_DIRECTORY",
+ outputDirOld.c_str());
+ }
+ }
+
+ cmSystemTools::ReplaceString(line,
+ "EXTRA_DEFINES",
+ this->Makefile->GetDefineFlags());
+ const char* debugPostfix
+ = 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 flagsMinSize = " ";
+ std::string flagsDebug = " ";
+ std::string flagsDebugRel = " ";
+ if(target.GetType() >= cmTarget::EXECUTABLE &&
+ target.GetType() <= cmTarget::OBJECT_LIBRARY)
+ {
+ const char* linkLanguage = target.GetLinkerLanguage();
+ if(!linkLanguage)
+ {
+ cmSystemTools::Error
+ ("CMake can not determine linker language for target:",
+ target.GetName());
+ return;
+ }
+ // if CXX is on and the target contains cxx code then add the cxx flags
+ std::string baseFlagVar = "CMAKE_";
+ baseFlagVar += linkLanguage;
+ baseFlagVar += "_FLAGS";
+ flags = this->Makefile->GetSafeDefinition(baseFlagVar.c_str());
+
+ std::string flagVar = baseFlagVar + "_RELEASE";
+ flagsRelease = this->Makefile->GetSafeDefinition(flagVar.c_str());
+ flagsRelease += " -DCMAKE_INTDIR=\\\"Release\\\" ";
+
+ flagVar = baseFlagVar + "_MINSIZEREL";
+ flagsMinSize = this->Makefile->GetSafeDefinition(flagVar.c_str());
+ flagsMinSize += " -DCMAKE_INTDIR=\\\"MinSizeRel\\\" ";
+
+ flagVar = baseFlagVar + "_DEBUG";
+ flagsDebug = this->Makefile->GetSafeDefinition(flagVar.c_str());
+ flagsDebug += " -DCMAKE_INTDIR=\\\"Debug\\\" ";
+
+ flagVar = baseFlagVar + "_RELWITHDEBINFO";
+ flagsDebugRel = this->Makefile->GetSafeDefinition(flagVar.c_str());
+ flagsDebugRel += " -DCMAKE_INTDIR=\\\"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\"";
+ }
+
+ // Add per-target flags.
+ if(const char* targetFlags = target.GetProperty("COMPILE_FLAGS"))
+ {
+ flags += " ";
+ flags += targetFlags;
+ }
+
+ // Add per-target and per-configuration preprocessor definitions.
+ std::string defines = " ";
+ std::string debugDefines = " ";
+ std::string releaseDefines = " ";
+ std::string minsizeDefines = " ";
+ std::string debugrelDefines = " ";
+
+ this->AppendDefines(
+ defines,
+ this->Makefile->GetProperty("COMPILE_DEFINITIONS"), 0);
+ this->AppendDefines(
+ debugDefines,
+ this->Makefile->GetProperty("COMPILE_DEFINITIONS_DEBUG"),0);
+ this->AppendDefines(
+ releaseDefines,
+ this->Makefile->GetProperty("COMPILE_DEFINITIONS_RELEASE"), 0);
+ this->AppendDefines(
+ minsizeDefines,
+ this->Makefile->GetProperty("COMPILE_DEFINITIONS_MINSIZEREL"), 0);
+ this->AppendDefines(
+ debugrelDefines,
+ this->Makefile->GetProperty("COMPILE_DEFINITIONS_RELWITHDEBINFO"), 0);
+
+ this->AppendDefines(
+ defines,
+ target.GetProperty("COMPILE_DEFINITIONS"), 0);
+ this->AppendDefines(
+ debugDefines,
+ target.GetProperty("COMPILE_DEFINITIONS_DEBUG"), 0);
+ this->AppendDefines(
+ releaseDefines,
+ target.GetProperty("COMPILE_DEFINITIONS_RELEASE"), 0);
+ this->AppendDefines(
+ minsizeDefines,
+ target.GetProperty("COMPILE_DEFINITIONS_MINSIZEREL"), 0);
+ this->AppendDefines(
+ debugrelDefines,
+ target.GetProperty("COMPILE_DEFINITIONS_RELWITHDEBINFO"), 0);
+ flags += defines;
+ flagsDebug += debugDefines;
+ flagsRelease += releaseDefines;
+ flagsMinSize += minsizeDefines;
+ flagsDebugRel += 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",
+ flagsMinSize.c_str());
+ cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_DEBUG",
+ flagsDebug.c_str());
+ cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_RELWITHDEBINFO",
+ flagsDebugRel.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;
+ }
+}
+
+void cmLocalVisualStudio6Generator::WriteDSPFooter(std::ostream& fout)
+{
+ std::ifstream fin(this->DSPFooterTemplate.c_str());
+ if(!fin)
+ {
+ cmSystemTools::Error("Error Reading ",
+ this->DSPFooterTemplate.c_str());
+ }
+ std::string line;
+ while(cmSystemTools::GetLineFromStream(fin, line))
+ {
+ fout << line << std::endl;
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmLocalVisualStudio6Generator
+::ComputeLinkOptions(cmTarget& target,
+ const char* configName,
+ const std::string extraOptions,
+ std::string& options)
+{
+ // Compute the link information for this configuration.
+ cmComputeLinkInformation* pcli = target.GetLinkInformation(configName);
+ if(!pcli)
+ {
+ return;
+ }
+ cmComputeLinkInformation& cli = *pcli;
+ typedef cmComputeLinkInformation::ItemVector ItemVector;
+ ItemVector const& linkLibs = cli.GetItems();
+ std::vector<std::string> const& linkDirs = cli.GetDirectories();
+
+ this->OutputObjects(target, "LINK", options);
+
+ // Build the link options code.
+ for(std::vector<std::string>::const_iterator d = linkDirs.begin();
+ d != linkDirs.end(); ++d)
+ {
+ std::string dir = *d;
+ if(!dir.empty())
+ {
+ if(dir[dir.size()-1] != '/')
+ {
+ dir += "/";
+ }
+ dir += "$(IntDir)";
+ options += "# ADD LINK32 /LIBPATH:";
+ options += this->ConvertToOptionallyRelativeOutputPath(dir.c_str());
+ options += " /LIBPATH:";
+ options += this->ConvertToOptionallyRelativeOutputPath(d->c_str());
+ options += "\n";
+ }
+ }
+ for(ItemVector::const_iterator l = linkLibs.begin();
+ l != linkLibs.end(); ++l)
+ {
+ options += "# ADD LINK32 ";
+ if(l->IsPath)
+ {
+ options +=
+ this->ConvertToOptionallyRelativeOutputPath(l->Value.c_str());
+ }
+ else
+ {
+ options += l->Value;
+ }
+ options += "\n";
+ }
+
+ // Add extra options if any.
+ if(!extraOptions.empty())
+ {
+ options += "# ADD LINK32 ";
+ options += extraOptions;
+ options += "\n";
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmLocalVisualStudio6Generator
+::OutputObjects(cmTarget& 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);
+ 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 += "\n";
+ }
+}
+
+std::string
+cmLocalVisualStudio6Generator
+::GetTargetDirectory(cmTarget const&) const
+{
+ // No per-target directory for this generator (yet).
+ return "";
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmLocalVisualStudio6Generator
+::ComputeLongestObjectDirectory(cmTarget&) const
+{
+ // Compute the maximum length configuration name.
+ std::string config_max;
+ for(std::vector<std::string>::const_iterator
+ i = this->Configurations.begin();
+ i != this->Configurations.end(); ++i)
+ {
+ // Strip the subdirectory name out of the configuration name.
+ std::string config = this->GetConfigName(*i);
+ if(config.size() > config_max.size())
+ {
+ config_max = config;
+ }
+ }
+
+ // Compute the maximum length full path to the intermediate
+ // 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 += "/";
+ dir_max += config_max;
+ dir_max += "/";
+ return dir_max;
+}
+
+std::string
+cmLocalVisualStudio6Generator
+::GetConfigName(std::string const& configuration) const
+{
+ // Strip the subdirectory name out of the configuration name.
+ std::string config = configuration;
+ std::string::size_type pos = config.find_last_of(" ");
+ config = config.substr(pos+1, std::string::npos);
+ config = config.substr(0, config.size()-1);
+ return config;
+}
+
+//----------------------------------------------------------------------------
+bool
+cmLocalVisualStudio6Generator
+::CheckDefinition(std::string const& define) const
+{
+ // Perform the standard check first.
+ if(!this->cmLocalGenerator::CheckDefinition(define))
+ {
+ return false;
+ }
+
+ // Now do the VS6-specific check.
+ if(define.find_first_of(" ") != define.npos &&
+ define.find_first_of("\"$;") != define.npos)
+ {
+ cmOStringStream 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"
+ << "Consider defining the macro in a (configured) header file.\n";
+ cmSystemTools::Message(e.str().c_str());
+ return false;
+ }
+
+ // Assume it is supported.
+ return true;
+}
diff --git a/Source/cmLocalVisualStudio6Generator.h b/Source/cmLocalVisualStudio6Generator.h
new file mode 100644
index 000000000..1decc3531
--- /dev/null
+++ b/Source/cmLocalVisualStudio6Generator.h
@@ -0,0 +1,103 @@
+/*============================================================================
+ 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 cmLocalVisualStudio6Generator_h
+#define cmLocalVisualStudio6Generator_h
+
+#include "cmLocalVisualStudioGenerator.h"
+
+class cmTarget;
+class cmSourceFile;
+class cmSourceGroup;
+class cmCustomCommand;
+
+/** \class cmLocalVisualStudio6Generator
+ * \brief Write a LocalUnix makefiles.
+ *
+ * cmLocalVisualStudio6Generator produces a LocalUnix makefile from its
+ * member this->Makefile.
+ */
+class cmLocalVisualStudio6Generator : public cmLocalVisualStudioGenerator
+{
+public:
+ ///! Set cache only and recurse to false by default.
+ cmLocalVisualStudio6Generator();
+
+ virtual ~cmLocalVisualStudio6Generator();
+
+ virtual void AddHelperCommands();
+ virtual void AddCMakeListsRules();
+
+ /**
+ * Generate the makefile for this directory.
+ */
+ virtual void Generate();
+
+ void OutputDSPFile();
+
+ enum BuildType {STATIC_LIBRARY, DLL, EXECUTABLE, WIN32_EXECUTABLE, UTILITY};
+
+ /**
+ * Specify the type of the build: static, dll, or executable.
+ */
+ void SetBuildType(BuildType, const char* libName, cmTarget&);
+
+ virtual std::string GetTargetDirectory(cmTarget const& target) const;
+ virtual std::string ComputeLongestObjectDirectory(cmTarget&) 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 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 WriteDSPFooter(std::ostream& fout);
+ void AddDSPBuildRule(cmTarget& tgt);
+ void WriteCustomRule(std::ostream& fout,
+ const char* source,
+ const cmCustomCommand& command,
+ const char* flags);
+ void AddUtilityCommandHack(cmTarget& target, int count,
+ std::vector<std::string>& depends,
+ const cmCustomCommand& origCommand);
+ void WriteGroup(const cmSourceGroup *sg, cmTarget& target,
+ std::ostream &fout, const char *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,
+ const std::string extraOptions,
+ std::string& options);
+ void OutputObjects(cmTarget& target, const char* tool,
+ std::string& options);
+ std::string GetTargetIncludeOptions(cmTarget &target);
+ std::vector<std::string> Configurations;
+
+ std::string GetConfigName(std::string const& configuration) const;
+
+ // Special definition check for VS6.
+ virtual bool CheckDefinition(std::string const& define) const;
+};
+
+#endif
+
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
new file mode 100644
index 000000000..f2ab79d7e
--- /dev/null
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -0,0 +1,2215 @@
+/*============================================================================
+ 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 "cmGlobalVisualStudio7Generator.h"
+#include "cmLocalVisualStudio7Generator.h"
+#include "cmXMLParser.h"
+#include <cm_expat.h>
+#include "cmMakefile.h"
+#include "cmSystemTools.h"
+#include "cmSourceFile.h"
+#include "cmCacheManager.h"
+#include "cmGeneratorTarget.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
+{
+public:
+ cmLocalVisualStudio7GeneratorInternals(cmLocalVisualStudio7Generator* e):
+ 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);
+private:
+ cmLocalVisualStudio7Generator* LocalGenerator;
+};
+
+extern cmVS7FlagTable cmLocalVisualStudio7GeneratorFlagTable[];
+
+//----------------------------------------------------------------------------
+cmLocalVisualStudio7Generator::cmLocalVisualStudio7Generator(VSVersion v):
+ cmLocalVisualStudioGenerator(v)
+{
+ this->PlatformName = "Win32";
+ this->ExtraFlagTable = 0;
+ this->Internal = new cmLocalVisualStudio7GeneratorInternals(this);
+}
+
+cmLocalVisualStudio7Generator::~cmLocalVisualStudio7Generator()
+{
+ delete this->Internal;
+}
+
+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++)
+ {
+ const char* path = l->second.GetProperty("EXTERNAL_MSPROJECT");
+ if(path)
+ {
+ this->ReadAndStoreExternalGUID(
+ l->second.GetName(), path);
+ }
+ else
+ {
+ gg->CreateGUID(l->first.c_str());
+ }
+ }
+
+
+ this->FixGlobalTargets();
+}
+
+void cmLocalVisualStudio7Generator::Generate()
+{
+ this->WriteProjectFiles();
+ this->WriteStampFiles();
+}
+
+void cmLocalVisualStudio7Generator::AddCMakeListsRules()
+{
+ cmTargets &tgts = this->Makefile->GetTargets();
+ // Create the regeneration custom rule.
+ if(!this->Makefile->IsOn("CMAKE_SUPPRESS_REGENERATION"))
+ {
+ // Create a rule to regenerate the build system when the target
+ // specification source changes.
+ if(cmSourceFile* sf = this->CreateVCProjBuildRule())
+ {
+ // Add the rule to targets that need it.
+ for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); ++l)
+ {
+ if(l->first != CMAKE_CHECK_BUILD_SYSTEM_TARGET)
+ {
+ l->second.AddSourceFile(sf);
+ }
+ }
+ }
+ }
+}
+
+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();
+ l != tgts.end(); l++)
+ {
+ cmTarget& tgt = l->second;
+ if(tgt.GetType() == cmTarget::GLOBAL_TARGET)
+ {
+ std::vector<std::string> no_depends;
+ cmCustomCommandLine force_command;
+ force_command.push_back("cd");
+ 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();
+ force += cmake::GetCMakeFilesDirectory();
+ force += "/";
+ force += tgt.GetName();
+ force += "_force";
+ this->Makefile->AddCustomCommandToOutput(force.c_str(), no_depends,
+ no_main_dependency,
+ force_commands, " ", 0, true);
+ if(cmSourceFile* file =
+ this->Makefile->GetSourceFileWithOutput(force.c_str()))
+ {
+ tgt.AddSourceFile(file);
+ }
+ }
+ }
+}
+
+// TODO
+// for CommandLine= need to repleace quotes with &quot
+// write out configurations
+void cmLocalVisualStudio7Generator::WriteProjectFiles()
+{
+ // If not an in source build, then create the output directory
+ if(strcmp(this->Makefile->GetStartOutputDirectory(),
+ this->Makefile->GetHomeDirectory()) != 0)
+ {
+ if(!cmSystemTools::MakeDirectory
+ (this->Makefile->GetStartOutputDirectory()))
+ {
+ cmSystemTools::Error("Error creating directory ",
+ this->Makefile->GetStartOutputDirectory());
+ }
+ }
+
+ // Get the set of targets in this directory.
+ cmTargets &tgts = this->Makefile->GetTargets();
+
+ // Create the project file for each target.
+ for(cmTargets::iterator l = tgts.begin();
+ l != tgts.end(); l++)
+ {
+ // INCLUDE_EXTERNAL_MSPROJECT command only affects the workspace
+ // so don't build a projectfile for it
+ if(!l->second.GetProperty("EXTERNAL_MSPROJECT"))
+ {
+ this->CreateSingleVCProj(l->first.c_str(),l->second);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmLocalVisualStudio7Generator::WriteStampFiles()
+{
+ // Touch a timestamp file used to determine when the project file is
+ // out of date.
+ std::string stampName = this->Makefile->GetStartOutputDirectory();
+ stampName += cmake::GetCMakeFilesDirectory();
+ cmSystemTools::MakeDirectory(stampName.c_str());
+ stampName += "/";
+ stampName += "generate.stamp";
+ std::ofstream stamp(stampName.c_str());
+ stamp << "# CMake generation timestamp file this directory.\n";
+
+ // Create a helper file so CMake can determine when it is run
+ // through the rule created by CreateVCProjBuildRule whether it
+ // really needs to regenerate the project. This file lists its own
+ // dependencies. If any file listed in it is newer than itself then
+ // CMake must rerun. Otherwise the project files are up to date and
+ // the stamp file can just be touched.
+ std::string depName = stampName;
+ depName += ".depend";
+ std::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();
+ lf != listFiles.end(); ++lf)
+ {
+ depFile << *lf << std::endl;
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmLocalVisualStudio7Generator
+::CreateSingleVCProj(const char *lname, cmTarget &target)
+{
+ this->FortranProject =
+ static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator)
+ ->TargetIsFortranOnly(target);
+
+ // Intel Fortran for VS10 uses VS9 format ".vfproj" files.
+ VSVersion realVersion = this->Version;
+ if(this->FortranProject && this->Version >= VS10)
+ {
+ this->Version = VS9;
+ }
+
+ // add to the list of projects
+ std::string pname = lname;
+ target.SetProperty("GENERATOR_FILE_NAME",lname);
+ // create the dsp.cmake file
+ std::string fname;
+ fname = this->Makefile->GetStartOutputDirectory();
+ fname += "/";
+ fname += lname;
+ if(this->FortranProject)
+ {
+ fname += ".vfproj";
+ }
+ else
+ {
+ fname += ".vcproj";
+ }
+
+ // Generate the project file and replace it atomically with
+ // copy-if-different. We use a separate timestamp so that the IDE
+ // does not reload project files unnecessarily.
+ cmGeneratedFileStream fout(fname.c_str());
+ fout.SetCopyIfDifferent(true);
+ this->WriteVCProjFile(fout,lname,target);
+ if (fout.Close())
+ {
+ this->GlobalGenerator->FileReplacedDuringGenerate(fname);
+ }
+
+ this->Version = realVersion;
+}
+
+//----------------------------------------------------------------------------
+cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule()
+{
+ std::string stampName = this->Makefile->GetCurrentOutputDirectory();
+ 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();
+ makefileIn += "/";
+ makefileIn += "CMakeLists.txt";
+ makefileIn = cmSystemTools::CollapseFullPath(makefileIn.c_str());
+ if(!cmSystemTools::FileExists(makefileIn.c_str()))
+ {
+ return 0;
+ }
+ std::string comment = "Building Custom Rule ";
+ comment += makefileIn;
+ std::string args;
+ args = "-H";
+ args += this->Convert(this->Makefile->GetHomeDirectory(),
+ START_OUTPUT, UNCHANGED, true);
+ commandLine.push_back(args);
+ args = "-B";
+ args +=
+ this->Convert(this->Makefile->GetHomeOutputDirectory(),
+ START_OUTPUT, UNCHANGED, true);
+ commandLine.push_back(args);
+ commandLine.push_back("--check-stamp-file");
+ std::string stampFilename = this->Convert(stampName.c_str(), FULL,
+ SHELL);
+ commandLine.push_back(stampFilename.c_str());
+
+ std::vector<std::string> const& listFiles = this->Makefile->GetListFiles();
+
+ cmCustomCommandLines commandLines;
+ commandLines.push_back(commandLine);
+ const char* no_working_directory = 0;
+ std::string fullpathStampName = this->Convert(stampName.c_str(), FULL,
+ UNCHANGED);
+ this->Makefile->AddCustomCommandToOutput(fullpathStampName.c_str(),
+ listFiles, makefileIn.c_str(),
+ commandLines, comment.c_str(),
+ no_working_directory, true);
+ if(cmSourceFile* file = this->Makefile->GetSource(makefileIn.c_str()))
+ {
+ return file;
+ }
+ else
+ {
+ cmSystemTools::Error("Error adding rule for ", makefileIn.c_str());
+ return 0;
+ }
+}
+
+void cmLocalVisualStudio7Generator::WriteConfigurations(std::ostream& fout,
+ const char *libName,
+ cmTarget &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)
+ {
+ this->WriteConfiguration(fout, i->c_str(), libName, target);
+ }
+ fout << "\t</Configurations>\n";
+}
+cmVS7FlagTable cmLocalVisualStudio7GeneratorFortranFlagTable[] =
+{
+ {"Preprocess", "fpp", "Run Preprocessor on files", "preprocessYes", 0},
+ {"SuppressStartupBanner", "nologo", "SuppressStartupBanner", "true", 0},
+ {"SourceFileFormat", "fixed", "Use Fixed Format", "fileFormatFixed", 0},
+ {"SourceFileFormat", "free", "Use Free Format", "fileFormatFree", 0},
+ {"DebugInformationFormat", "Zi", "full debug", "debugEnabled", 0},
+ {"DebugInformationFormat", "debug:full", "full debug", "debugEnabled", 0},
+ {"DebugInformationFormat", "Z7", "c7 compat", "debugOldStyleInfo", 0},
+ {"DebugInformationFormat", "Zd", "line numbers", "debugLineInfoOnly", 0},
+ {"Optimization", "Od", "disable optimization", "optimizeDisabled", 0},
+ {"Optimization", "O1", "min space", "optimizeMinSpace", 0},
+ {"Optimization", "O3", "full optimize", "optimizeFull", 0},
+ {"GlobalOptimizations", "Og", "global optimize", "true", 0},
+ {"InlineFunctionExpansion", "Ob0", "", "expandDisable", 0},
+ {"InlineFunctionExpansion", "Ob1", "", "expandOnlyInline", 0},
+ {"FavorSizeOrSpeed", "Os", "", "favorSize", 0},
+ {"OmitFramePointers", "Oy-", "", "false", 0},
+ {"OptimizeForProcessor", "GB", "", "procOptimizeBlended", 0},
+ {"OptimizeForProcessor", "G5", "", "procOptimizePentium", 0},
+ {"OptimizeForProcessor", "G6", "", "procOptimizePentiumProThruIII", 0},
+ {"UseProcessorExtensions", "QzxK", "", "codeForStreamingSIMD", 0},
+ {"OptimizeForProcessor", "QaxN", "", "codeForPentium4", 0},
+ {"OptimizeForProcessor", "QaxB", "", "codeForPentiumM", 0},
+ {"OptimizeForProcessor", "QaxP", "", "codeForCodeNamedPrescott", 0},
+ {"OptimizeForProcessor", "QaxT", "", "codeForCore2Duo", 0},
+ {"OptimizeForProcessor", "QxK", "", "codeExclusivelyStreamingSIMD", 0},
+ {"OptimizeForProcessor", "QxN", "", "codeExclusivelyPentium4", 0},
+ {"OptimizeForProcessor", "QxB", "", "codeExclusivelyPentiumM", 0},
+ {"OptimizeForProcessor", "QxP", "", "codeExclusivelyCodeNamedPrescott", 0},
+ {"OptimizeForProcessor", "QxT", "", "codeExclusivelyCore2Duo", 0},
+ {"OptimizeForProcessor", "QxO", "", "codeExclusivelyCore2StreamingSIMD", 0},
+ {"OptimizeForProcessor", "QxS", "", "codeExclusivelyCore2StreamingSIMD4", 0},
+
+ {"ModulePath", "module:", "", "",
+ cmVS7FlagTable::UserValueRequired},
+ {"LoopUnrolling", "Qunroll:", "", "",
+ cmVS7FlagTable::UserValueRequired},
+ {"AutoParallelThreshold", "Qpar-threshold:", "", "",
+ cmVS7FlagTable::UserValueRequired},
+ {"HeapArrays", "heap-arrays:", "", "",
+ cmVS7FlagTable::UserValueRequired},
+ {"ObjectText", "bintext:", "", "",
+ cmVS7FlagTable::UserValueRequired},
+ {"Parallelization", "Qparallel", "", "true", 0},
+ {"PrefetchInsertion", "Qprefetch-", "", "false", 0},
+ {"BufferedIO", "assume:buffered_io", "", "true", 0},
+ {"CallingConvention", "iface:stdcall", "", "callConventionStdCall", 0},
+ {"CallingConvention", "iface:cref", "", "callConventionCRef", 0},
+ {"CallingConvention", "iface:stdref", "", "callConventionStdRef", 0},
+ {"CallingConvention", "iface:stdcall", "", "callConventionStdCall", 0},
+ {"CallingConvention", "iface:cvf", "", "callConventionCVF", 0},
+ {"EnableRecursion", "recursive", "", "true", 0},
+ {"ReentrantCode", "reentrancy", "", "true", 0},
+ // done up to Language
+ {0,0,0,0,0}
+};
+// fill the table here currently the comment field is not used for
+// anything other than documentation NOTE: Make sure the longer
+// commandFlag comes FIRST!
+cmVS7FlagTable cmLocalVisualStudio7GeneratorFlagTable[] =
+{
+ // option flags (some flags map to the same option)
+ {"BasicRuntimeChecks", "GZ", "Stack frame checks", "1", 0},
+ {"BasicRuntimeChecks", "RTCsu",
+ "Both stack and uninitialized checks", "3", 0},
+ {"BasicRuntimeChecks", "RTCs", "Stack frame checks", "1", 0},
+ {"BasicRuntimeChecks", "RTCu", "Uninitialized Variables ", "2", 0},
+ {"BasicRuntimeChecks", "RTC1",
+ "Both stack and uninitialized checks", "3", 0},
+ {"DebugInformationFormat", "Z7", "debug format", "1", 0},
+ {"DebugInformationFormat", "Zd", "debug format", "2", 0},
+ {"DebugInformationFormat", "Zi", "debug format", "3", 0},
+ {"DebugInformationFormat", "ZI", "debug format", "4", 0},
+ {"EnableEnhancedInstructionSet", "arch:SSE2",
+ "Use sse2 instructions", "2", 0},
+ {"EnableEnhancedInstructionSet", "arch:SSE",
+ "Use sse instructions", "1", 0},
+ {"FloatingPointModel", "fp:precise",
+ "Use precise floating point model", "0", 0},
+ {"FloatingPointModel", "fp:strict",
+ "Use strict floating point model", "1", 0},
+ {"FloatingPointModel", "fp:fast", "Use fast floating point model", "2", 0},
+ {"FavorSizeOrSpeed", "Ot", "Favor fast code", "1", 0},
+ {"FavorSizeOrSpeed", "Os", "Favor small code", "2", 0},
+ {"CompileAs", "TC", "Compile as c code", "1", 0},
+ {"CompileAs", "TP", "Compile as c++ code", "2", 0},
+ {"Optimization", "Od", "Non Debug", "0", 0},
+ {"Optimization", "O1", "Min Size", "1", 0},
+ {"Optimization", "O2", "Max Speed", "2", 0},
+ {"Optimization", "Ox", "Max Optimization", "3", 0},
+ {"OptimizeForProcessor", "GB", "Blended processor mode", "0", 0},
+ {"OptimizeForProcessor", "G5", "Pentium", "1", 0},
+ {"OptimizeForProcessor", "G6", "PPro PII PIII", "2", 0},
+ {"OptimizeForProcessor", "G7", "Pentium 4 or Athlon", "3", 0},
+ {"InlineFunctionExpansion", "Ob0", "no inlines", "0", 0},
+ {"InlineFunctionExpansion", "Ob1", "when inline keyword", "1", 0},
+ {"InlineFunctionExpansion", "Ob2", "any time you can inline", "2", 0},
+ {"RuntimeLibrary", "MTd", "Multithreded debug", "1", 0},
+ {"RuntimeLibrary", "MT", "Multithreded", "0", 0},
+ {"RuntimeLibrary", "MDd", "Multithreded dll debug", "3", 0},
+ {"RuntimeLibrary", "MD", "Multithreded dll", "2", 0},
+ {"RuntimeLibrary", "MLd", "Sinble Thread debug", "5", 0},
+ {"RuntimeLibrary", "ML", "Sinble Thread", "4", 0},
+ {"StructMemberAlignment", "Zp16", "struct align 16 byte ", "5", 0},
+ {"StructMemberAlignment", "Zp1", "struct align 1 byte ", "1", 0},
+ {"StructMemberAlignment", "Zp2", "struct align 2 byte ", "2", 0},
+ {"StructMemberAlignment", "Zp4", "struct align 4 byte ", "3", 0},
+ {"StructMemberAlignment", "Zp8", "struct align 8 byte ", "4", 0},
+ {"WarningLevel", "W0", "Warning level", "0", 0},
+ {"WarningLevel", "W1", "Warning level", "1", 0},
+ {"WarningLevel", "W2", "Warning level", "2", 0},
+ {"WarningLevel", "W3", "Warning level", "3", 0},
+ {"WarningLevel", "W4", "Warning level", "4", 0},
+ {"DisableSpecificWarnings", "wd", "Disable specific warnings", "",
+ cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+
+ // Precompiled header and related options. Note that the
+ // UsePrecompiledHeader entries are marked as "Continue" so that the
+ // corresponding PrecompiledHeaderThrough entry can be found.
+ {"UsePrecompiledHeader", "Yc", "Create Precompiled Header", "1",
+ cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},
+ {"PrecompiledHeaderThrough", "Yc", "Precompiled Header Name", "",
+ cmVS7FlagTable::UserValueRequired},
+ {"PrecompiledHeaderFile", "Fp", "Generated Precompiled Header", "",
+ cmVS7FlagTable::UserValue},
+ // The YX and Yu options are in a per-global-generator table because
+ // their values differ based on the VS IDE version.
+ {"ForcedIncludeFiles", "FI", "Forced include files", "",
+ cmVS7FlagTable::UserValueRequired | cmVS7FlagTable::SemicolonAppendable},
+
+ // boolean flags
+ {"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},
+ {"EnableFiberSafeOptimizations", "GT", "Enable Fiber-safe Optimizations",
+ "TRUE", 0},
+ {"EnableFunctionLevelLinking", "Gy",
+ "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},
+ {"RuntimeTypeInfo", "GR",
+ "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},
+ {"WholeProgramOptimization", "GL",
+ "Enables whole program optimization", "TRUE", 0},
+ {"WholeProgramOptimization", "GL-",
+ "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},
+ {0,0,0,0,0}
+};
+
+
+
+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},
+ {"LinkIncremental", "INCREMENTAL:NO", "link incremental", "1", 0},
+ {"LinkIncremental", "INCREMENTAL:YES", "link incremental", "2", 0},
+ {"CLRUnmanagedCodeCheck", "CLRUNMANAGEDCODECHECK:NO", "", "false", 0},
+ {"CLRUnmanagedCodeCheck", "CLRUNMANAGEDCODECHECK", "", "true", 0},
+ {"DataExecutionPrevention", "NXCOMPAT:NO",
+ "Not known to work with Windows Data Execution Prevention", "1", 0},
+ {"DataExecutionPrevention", "NXCOMPAT",
+ "Known to work with Windows Data Execution Prevention", "2", 0},
+ {"DelaySign", "DELAYSIGN:NO", "", "false", 0},
+ {"DelaySign", "DELAYSIGN", "", "true", 0},
+ {"EntryPointSymbol", "ENTRY:", "sets the starting address", "",
+ cmVS7FlagTable::UserValue},
+ {"IgnoreDefaultLibraryNames", "NODEFAULTLIB:", "default libs to ignore", "",
+ cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},
+ {"IgnoreAllDefaultLibraries", "NODEFAULTLIB", "ignore all default libs",
+ "TRUE", 0},
+ {"FixedBaseAddress", "FIXED:NO", "Generate a relocation section", "1", 0},
+ {"FixedBaseAddress", "FIXED", "Image must be loaded at a fixed address",
+ "2", 0},
+ {"EnableCOMDATFolding", "OPT:NOICF", "Do not remove redundant COMDATs",
+ "1", 0},
+ {"EnableCOMDATFolding", "OPT:ICF", "Remove redundant COMDATs", "2", 0},
+ {"ResourceOnlyDLL", "NOENTRY", "Create DLL with no entry point", "true", 0},
+ {"OptimizeReferences", "OPT:NOREF", "Keep unreferenced data", "1", 0},
+ {"OptimizeReferences", "OPT:REF", "Eliminate unreferenced data", "2", 0},
+ {"Profile", "PROFILE", "", "true", 0},
+ {"RandomizedBaseAddress", "DYNAMICBASE:NO",
+ "Image may not be rebased at load-time", "1", 0},
+ {"RandomizedBaseAddress", "DYNAMICBASE",
+ "Image may be rebased at load-time", "2", 0},
+ {"SetChecksum", "RELEASE", "Enable setting checksum in header", "true", 0},
+ {"SupportUnloadOfDelayLoadedDLL", "DELAY:UNLOAD", "", "true", 0},
+ {"TargetMachine", "MACHINE:I386", "Machine x86", "1", 0},
+ {"TargetMachine", "MACHINE:X86", "Machine x86", "1", 0},
+ {"TargetMachine", "MACHINE:AM33", "Machine AM33", "2", 0},
+ {"TargetMachine", "MACHINE:ARM", "Machine ARM", "3", 0},
+ {"TargetMachine", "MACHINE:EBC", "Machine EBC", "4", 0},
+ {"TargetMachine", "MACHINE:IA64", "Machine IA64", "5", 0},
+ {"TargetMachine", "MACHINE:M32R", "Machine M32R", "6", 0},
+ {"TargetMachine", "MACHINE:MIPS", "Machine MIPS", "7", 0},
+ {"TargetMachine", "MACHINE:MIPS16", "Machine MIPS16", "8", 0},
+ {"TargetMachine", "MACHINE:MIPSFPU)", "Machine MIPSFPU", "9", 0},
+ {"TargetMachine", "MACHINE:MIPSFPU16", "Machine MIPSFPU16", "10", 0},
+ {"TargetMachine", "MACHINE:MIPSR41XX", "Machine MIPSR41XX", "11", 0},
+ {"TargetMachine", "MACHINE:SH3", "Machine SH3", "12", 0},
+ {"TargetMachine", "MACHINE:SH3DSP", "Machine SH3DSP", "13", 0},
+ {"TargetMachine", "MACHINE:SH4", "Machine SH4", "14", 0},
+ {"TargetMachine", "MACHINE:SH5", "Machine SH5", "15", 0},
+ {"TargetMachine", "MACHINE:THUMB", "Machine THUMB", "16", 0},
+ {"TargetMachine", "MACHINE:X64", "Machine x64", "17", 0},
+ {"TurnOffAssemblyGeneration", "NOASSEMBLY",
+ "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},
+ {0,0,0,0,0}
+};
+
+//----------------------------------------------------------------------------
+// Helper class to write build event <Tool .../> elements.
+class cmLocalVisualStudio7Generator::EventWriter
+{
+public:
+ EventWriter(cmLocalVisualStudio7Generator* lg,
+ const char* config, std::ostream& os):
+ LG(lg), Config(config), Stream(os), First(true) {}
+ void Start(const char* tool)
+ {
+ this->First = true;
+ this->Stream << "\t\t\t<Tool\n\t\t\t\tName=\"" << tool << "\"";
+ }
+ void Finish()
+ {
+ this->Stream << (this->First? "" : "\"") << "/>\n";
+ }
+ void Write(std::vector<cmCustomCommand> const& ccs)
+ {
+ for(std::vector<cmCustomCommand>::const_iterator ci = ccs.begin();
+ ci != ccs.end(); ++ci)
+ {
+ this->Write(*ci);
+ }
+ }
+ void Write(cmCustomCommand const& cc)
+ {
+ if(this->First)
+ {
+ const char* comment = cc.GetComment();
+ if(comment && *comment)
+ {
+ this->Stream << "\nDescription=\""
+ << this->LG->EscapeForXML(comment) << "\"";
+ }
+ this->Stream << "\nCommandLine=\"";
+ this->First = false;
+ }
+ else
+ {
+ this->Stream << this->LG->EscapeForXML("\n");
+ }
+ std::string script = this->LG->ConstructScript(cc, this->Config);
+ this->Stream << this->LG->EscapeForXML(script.c_str());
+ }
+private:
+ cmLocalVisualStudio7Generator* LG;
+ const char* Config;
+ std::ostream& Stream;
+ bool First;
+};
+
+//----------------------------------------------------------------------------
+void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
+ const char* configName,
+ const char *libName,
+ cmTarget &target)
+{
+ const char* mfcFlag = this->Makefile->GetDefinition("CMAKE_MFC_FLAG");
+ if(!mfcFlag)
+ {
+ mfcFlag = "0";
+ }
+ fout << "\t\t<Configuration\n"
+ << "\t\t\tName=\"" << configName << "|" << this->PlatformName << "\"\n"
+ << "\t\t\tOutputDirectory=\"" << configName << "\"\n";
+ // This is an internal type to Visual Studio, it seems that:
+ // 4 == static library
+ // 2 == dll
+ // 1 == executable
+ // 10 == utility
+ const char* configType = "10";
+ const char* projectType = 0;
+ bool targetBuilds = true;
+ switch(target.GetType())
+ {
+ case cmTarget::OBJECT_LIBRARY:
+ targetBuilds = false; // TODO: PDB for object library?
+ case cmTarget::STATIC_LIBRARY:
+ projectType = "typeStaticLibrary";
+ configType = "4";
+ break;
+ case cmTarget::SHARED_LIBRARY:
+ case cmTarget::MODULE_LIBRARY:
+ projectType = "typeDynamicLibrary";
+ configType = "2";
+ break;
+ case cmTarget::EXECUTABLE:
+ configType = "1";
+ break;
+ case cmTarget::UTILITY:
+ case cmTarget::GLOBAL_TARGET:
+ configType = "10";
+ default:
+ targetBuilds = false;
+ break;
+ }
+ if(this->FortranProject && projectType)
+ {
+ configType = projectType;
+ }
+ std::string flags;
+ if(strcmp(configType, "10") != 0)
+ {
+ const char* linkLanguage = (this->FortranProject? "Fortran":
+ target.GetLinkerLanguage(configName));
+ if(!linkLanguage)
+ {
+ cmSystemTools::Error
+ ("CMake can not determine linker language for target:",
+ target.GetName());
+ return;
+ }
+ if(strcmp(linkLanguage, "C") == 0 || strcmp(linkLanguage, "CXX") == 0
+ || strcmp(linkLanguage, "Fortran") == 0)
+ {
+ std::string baseFlagVar = "CMAKE_";
+ baseFlagVar += linkLanguage;
+ baseFlagVar += "_FLAGS";
+ flags = this->Makefile->GetRequiredDefinition(baseFlagVar.c_str());
+ std::string flagVar = baseFlagVar + std::string("_") +
+ cmSystemTools::UpperCase(configName);
+ flags += " ";
+ flags += this->Makefile->GetRequiredDefinition(flagVar.c_str());
+ }
+ // set the correct language
+ if(strcmp(linkLanguage, "C") == 0)
+ {
+ flags += " /TC ";
+ }
+ if(strcmp(linkLanguage, "CXX") == 0)
+ {
+ flags += " /TP ";
+ }
+ }
+
+ if(this->FortranProject)
+ {
+ switch(this->GetFortranFormat(target.GetProperty("Fortran_FORMAT")))
+ {
+ case FortranFormatFixed: flags += " -fixed"; break;
+ case FortranFormatFree: flags += " -free"; break;
+ default: break;
+ }
+ }
+
+ // Add the target-specific flags.
+ if(const char* targetFlags = target.GetProperty("COMPILE_FLAGS"))
+ {
+ flags += " ";
+ flags += targetFlags;
+ }
+
+ std::string configUpper = cmSystemTools::UpperCase(configName);
+ std::string defPropName = "COMPILE_DEFINITIONS_";
+ defPropName += configUpper;
+
+ // Get preprocessor definitions for this directory.
+ std::string defineFlags = this->Makefile->GetDefineFlags();
+ Options::Tool t = Options::Compiler;
+ cmVS7FlagTable const* table = cmLocalVisualStudio7GeneratorFlagTable;
+ if(this->FortranProject)
+ {
+ t = Options::FortranCompiler;
+ table = cmLocalVisualStudio7GeneratorFortranFlagTable;
+ }
+ Options targetOptions(this, t,
+ table,
+ this->ExtraFlagTable);
+ targetOptions.FixExceptionHandlingDefault();
+ targetOptions.Parse(flags.c_str());
+ targetOptions.Parse(defineFlags.c_str());
+ targetOptions.ParseFinish();
+ targetOptions.AddDefines
+ (this->Makefile->GetProperty("COMPILE_DEFINITIONS"));
+ targetOptions.AddDefines(target.GetProperty("COMPILE_DEFINITIONS"));
+ targetOptions.AddDefines(this->Makefile->GetProperty(defPropName.c_str()));
+ targetOptions.AddDefines(target.GetProperty(defPropName.c_str()));
+ targetOptions.SetVerboseMakefile(
+ this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE"));
+
+ // Add a definition for the configuration name.
+ std::string configDefine = "CMAKE_INTDIR=\"";
+ configDefine += configName;
+ configDefine += "\"";
+ targetOptions.AddDefine(configDefine);
+
+ // Add the export symbol definition for shared library objects.
+ if(const char* exportMacro = target.GetExportMacro())
+ {
+ targetOptions.AddDefine(exportMacro);
+ }
+
+ // The intermediate directory name consists of a directory for the
+ // target and a subdirectory for the configuration name.
+ std::string intermediateDir = this->GetTargetDirectory(target);
+ intermediateDir += "/";
+ intermediateDir += configName;
+ 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";
+
+ // If unicode is enabled change the character set to unicode, if not
+ // then default to MBCS.
+ if(targetOptions.UsingUnicode())
+ {
+ fout << "\t\t\tCharacterSet=\"1\">\n";
+ }
+ else if(targetOptions.UsingSBCS())
+ {
+ fout << "\t\t\tCharacterSet=\"0\">\n";
+ }
+ else
+ {
+ fout << "\t\t\tCharacterSet=\"2\">\n";
+ }
+ const char* tool = "VCCLCompilerTool";
+ if(this->FortranProject)
+ {
+ tool = "VFFortranCompilerTool";
+ }
+ fout << "\t\t\t<Tool\n"
+ << "\t\t\t\tName=\"" << tool << "\"\n";
+ if(this->FortranProject)
+ {
+ const char* target_mod_dir =
+ target.GetProperty("Fortran_MODULE_DIRECTORY");
+ std::string modDir;
+ if(target_mod_dir)
+ {
+ modDir = this->Convert(target_mod_dir,
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::UNCHANGED);
+ }
+ else
+ {
+ modDir = ".";
+ }
+ fout << "\t\t\t\tModulePath=\""
+ << this->ConvertToXMLOutputPath(modDir.c_str())
+ << "\\$(ConfigurationName)\"\n";
+ }
+ targetOptions.OutputAdditionalOptions(fout, "\t\t\t\t", "\n");
+ fout << "\t\t\t\tAdditionalIncludeDirectories=\"";
+ std::vector<std::string> includes;
+ this->GetIncludeDirectories(includes, &target);
+ std::vector<std::string>::iterator i = includes.begin();
+ for(;i != includes.end(); ++i)
+ {
+ // output the include path
+ std::string ipath = this->ConvertToXMLOutputPath(i->c_str());
+ fout << ipath << ";";
+ // if this is fortran then output the include with
+ // a ConfigurationName on the end of it.
+ if(this->FortranProject)
+ {
+ ipath = i->c_str();
+ ipath += "/$(ConfigurationName)";
+ ipath = this->ConvertToXMLOutputPath(ipath.c_str());
+ fout << ipath << ";";
+ }
+ }
+ fout << "\"\n";
+ targetOptions.OutputFlagMap(fout, "\t\t\t\t");
+ targetOptions.OutputPreprocessorDefinitions(fout, "\t\t\t\t", "\n", "CXX");
+ fout << "\t\t\t\tAssemblerListingLocation=\"" << configName << "\"\n";
+ fout << "\t\t\t\tObjectFile=\"$(IntDir)\\\"\n";
+ if(targetBuilds)
+ {
+ // We need to specify a program database file name even for
+ // non-debug configurations because VS still creates .idb files.
+ fout << "\t\t\t\tProgramDataBaseFileName=\""
+ << this->ConvertToXMLOutputPathSingle(
+ target.GetDirectory(configName).c_str())
+ << "/"
+ << target.GetPDBName(configName) << "\"\n";
+ }
+ fout << "/>\n"; // end of <Tool Name=VCCLCompilerTool
+ tool = "VCCustomBuildTool";
+ if(this->FortranProject)
+ {
+ tool = "VFCustomBuildTool";
+ }
+ fout << "\t\t\t<Tool\n\t\t\t\tName=\"" << tool << "\"/>\n";
+ tool = "VCResourceCompilerTool";
+ if(this->FortranProject)
+ {
+ tool = "VFResourceCompilerTool";
+ }
+ fout << "\t\t\t<Tool\n\t\t\t\tName=\"" << tool << "\"\n"
+ << "\t\t\t\tAdditionalIncludeDirectories=\"";
+ for(i = includes.begin();i != includes.end(); ++i)
+ {
+ std::string ipath = this->ConvertToXMLOutputPath(i->c_str());
+ fout << ipath << ";";
+ }
+ // add the -D flags to the RC tool
+ fout << "\"";
+ targetOptions.OutputPreprocessorDefinitions(fout, "\n\t\t\t\t", "", "RC");
+ fout << "/>\n";
+ tool = "VCMIDLTool";
+ if(this->FortranProject)
+ {
+ tool = "VFMIDLTool";
+ }
+ fout << "\t\t\t<Tool\n\t\t\t\tName=\"" << tool << "\"\n";
+ fout << "\t\t\t\tAdditionalIncludeDirectories=\"";
+ for(i = includes.begin(); i != includes.end(); ++i)
+ {
+ std::string ipath = this->ConvertToXMLOutputPath(i->c_str());
+ fout << ipath << ";";
+ }
+ fout << "\"\n";
+ fout << "\t\t\t\tMkTypLibCompatible=\"FALSE\"\n";
+ if( this->PlatformName == "x64" )
+ {
+ fout << "\t\t\t\tTargetEnvironment=\"3\"\n";
+ }
+ else if( this->PlatformName == "ia64" )
+ {
+ fout << "\t\t\t\tTargetEnvironment=\"2\"\n";
+ }
+ else
+ {
+ fout << "\t\t\t\tTargetEnvironment=\"1\"\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";
+ fout << "\t\t\t\tDLLDataFileName=\"\"\n";
+ fout << "\t\t\t\tInterfaceIdentifierFileName=\"$(InputName)_i.c\"\n";
+ 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)
+ {
+ // Check the filesystem type where the target will be written.
+ 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* tool = "VCManifestTool";
+ if(this->FortranProject)
+ {
+ tool = "VFManifestTool";
+ }
+ fout << "\t\t\t<Tool\n\t\t\t\tName=\"" << tool << "\"\n"
+ << "\t\t\t\tUseFAT32Workaround=\"true\"\n"
+ << "\t\t\t/>\n";
+ }
+ }
+
+ this->OutputTargetRules(fout, configName, target, libName);
+ this->OutputBuildTool(fout, configName, target, targetOptions.IsDebug());
+ fout << "\t\t</Configuration>\n";
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmLocalVisualStudio7Generator
+::GetBuildTypeLinkerFlags(std::string rootLinkerFlags, const char* configName)
+{
+ std::string configTypeUpper = cmSystemTools::UpperCase(configName);
+ std::string extraLinkOptionsBuildTypeDef =
+ rootLinkerFlags + "_" + configTypeUpper;
+
+ std::string extraLinkOptionsBuildType =
+ this->Makefile->GetRequiredDefinition
+ (extraLinkOptionsBuildTypeDef.c_str());
+
+ return extraLinkOptionsBuildType;
+}
+
+void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
+ const char* configName,
+ cmTarget &target,
+ bool isDebug)
+{
+ cmGlobalVisualStudio7Generator* gg =
+ static_cast<cmGlobalVisualStudio7Generator*>(this->GlobalGenerator);
+ std::string temp;
+ std::string extraLinkOptions;
+ if(target.GetType() == cmTarget::EXECUTABLE)
+ {
+ extraLinkOptions =
+ this->Makefile->GetRequiredDefinition("CMAKE_EXE_LINKER_FLAGS")
+ + std::string(" ")
+ + GetBuildTypeLinkerFlags("CMAKE_EXE_LINKER_FLAGS", configName);
+ }
+ if(target.GetType() == cmTarget::SHARED_LIBRARY)
+ {
+ extraLinkOptions =
+ this->Makefile->GetRequiredDefinition("CMAKE_SHARED_LINKER_FLAGS")
+ + std::string(" ")
+ + GetBuildTypeLinkerFlags("CMAKE_SHARED_LINKER_FLAGS", configName);
+ }
+ if(target.GetType() == cmTarget::MODULE_LIBRARY)
+ {
+ extraLinkOptions =
+ this->Makefile->GetRequiredDefinition("CMAKE_MODULE_LINKER_FLAGS")
+ + std::string(" ")
+ + GetBuildTypeLinkerFlags("CMAKE_MODULE_LINKER_FLAGS", configName);
+ }
+
+ const char* targetLinkFlags = target.GetProperty("LINK_FLAGS");
+ if(targetLinkFlags)
+ {
+ extraLinkOptions += " ";
+ extraLinkOptions += targetLinkFlags;
+ }
+ std::string configTypeUpper = cmSystemTools::UpperCase(configName);
+ std::string linkFlagsConfig = "LINK_FLAGS_";
+ linkFlagsConfig += configTypeUpper;
+ targetLinkFlags = target.GetProperty(linkFlagsConfig.c_str());
+ if(targetLinkFlags)
+ {
+ extraLinkOptions += " ";
+ extraLinkOptions += targetLinkFlags;
+ }
+ Options linkOptions(this, Options::Linker,
+ cmLocalVisualStudio7GeneratorLinkFlagTable);
+ linkOptions.Parse(extraLinkOptions.c_str());
+ if(!this->ModuleDefinitionFile.empty())
+ {
+ std::string defFile =
+ this->ConvertToXMLOutputPath(this->ModuleDefinitionFile.c_str());
+ linkOptions.AddFlag("ModuleDefinitionFile", defFile.c_str());
+ }
+ switch(target.GetType())
+ {
+ case cmTarget::OBJECT_LIBRARY:
+ {
+ std::string libpath = this->GetTargetDirectory(target);
+ libpath += "/";
+ libpath += configName;
+ libpath += "/";
+ libpath += target.GetName();
+ libpath += ".lib";
+ const char* tool =
+ this->FortranProject? "VFLibrarianTool":"VCLibrarianTool";
+ fout << "\t\t\t<Tool\n"
+ << "\t\t\t\tName=\"" << tool << "\"\n";
+ fout << "\t\t\t\tOutputFile=\""
+ << this->ConvertToXMLOutputPathSingle(libpath.c_str()) << "\"/>\n";
+ break;
+ }
+ case cmTarget::STATIC_LIBRARY:
+ {
+ std::string targetNameFull = target.GetFullName(configName);
+ std::string libpath = target.GetDirectory(configName);
+ libpath += "/";
+ libpath += targetNameFull;
+ const char* tool = "VCLibrarianTool";
+ if(this->FortranProject)
+ {
+ tool = "VFLibrarianTool";
+ }
+ fout << "\t\t\t<Tool\n"
+ << "\t\t\t\tName=\"" << tool << "\"\n";
+
+ if(this->GetVersion() < VS8)
+ {
+ cmOStringStream libdeps;
+ this->Internal->OutputObjects(libdeps, &target);
+ if(!libdeps.str().empty())
+ {
+ fout << "\t\t\t\tAdditionalDependencies=\"" << libdeps.str() << "\"\n";
+ }
+ }
+ std::string libflags;
+ if(const char* flags = target.GetProperty("STATIC_LIBRARY_FLAGS"))
+ {
+ libflags += flags;
+ }
+ std::string libFlagsConfig = "STATIC_LIBRARY_FLAGS_";
+ libFlagsConfig += configTypeUpper;
+ if(const char* flagsConfig = target.GetProperty(libFlagsConfig.c_str()))
+ {
+ libflags += " ";
+ libflags += flagsConfig;
+ }
+ if(!libflags.empty())
+ {
+ fout << "\t\t\t\tAdditionalOptions=\"" << libflags << "\"\n";
+ }
+ fout << "\t\t\t\tOutputFile=\""
+ << this->ConvertToXMLOutputPathSingle(libpath.c_str()) << "\"/>\n";
+ break;
+ }
+ case cmTarget::SHARED_LIBRARY:
+ case cmTarget::MODULE_LIBRARY:
+ {
+ std::string targetName;
+ std::string targetNameSO;
+ std::string targetNameFull;
+ std::string targetNameImport;
+ std::string targetNamePDB;
+ target.GetLibraryNames(targetName, targetNameSO, targetNameFull,
+ targetNameImport, targetNamePDB, configName);
+
+ // Compute the link library and directory information.
+ cmComputeLinkInformation* pcli = target.GetLinkInformation(configName);
+ if(!pcli)
+ {
+ return;
+ }
+ cmComputeLinkInformation& cli = *pcli;
+ const char* linkLanguage = cli.GetLinkLanguage();
+
+ // Compute the variable name to lookup standard libraries for this
+ // language.
+ std::string standardLibsVar = "CMAKE_";
+ standardLibsVar += linkLanguage;
+ standardLibsVar += "_STANDARD_LIBRARIES";
+ const char* tool = "VCLinkerTool";
+ if(this->FortranProject)
+ {
+ tool = "VFLinkerTool";
+ }
+ fout << "\t\t\t<Tool\n"
+ << "\t\t\t\tName=\"" << tool << "\"\n";
+ if(!gg->NeedLinkLibraryDependencies(target))
+ {
+ fout << "\t\t\t\tLinkLibraryDependencies=\"false\"\n";
+ }
+ linkOptions.OutputAdditionalOptions(fout, "\t\t\t\t", "\n");
+ // Use the NOINHERIT macro to avoid getting VS project default
+ // 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)
+ {
+ this->Internal->OutputObjects(fout, &target, " ");
+ }
+ fout << " ";
+ this->Internal->OutputLibraries(fout, cli.GetItems());
+ fout << "\"\n";
+ temp = target.GetDirectory(configName);
+ temp += "/";
+ temp += targetNameFull;
+ fout << "\t\t\t\tOutputFile=\""
+ << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n";
+ this->WriteTargetVersionAttribute(fout, target);
+ linkOptions.OutputFlagMap(fout, "\t\t\t\t");
+ fout << "\t\t\t\tAdditionalLibraryDirectories=\"";
+ this->OutputLibraryDirectories(fout, cli.GetDirectories());
+ fout << "\"\n";
+ temp = target.GetDirectory(configName);
+ temp += "/";
+ temp += targetNamePDB;
+ fout << "\t\t\t\tProgramDatabaseFile=\"" <<
+ this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n";
+ if(isDebug)
+ {
+ fout << "\t\t\t\tGenerateDebugInformation=\"TRUE\"\n";
+ }
+ std::string stackVar = "CMAKE_";
+ stackVar += linkLanguage;
+ stackVar += "_STACK_SIZE";
+ const char* stackVal = this->Makefile->GetDefinition(stackVar.c_str());
+ if(stackVal)
+ {
+ fout << "\t\t\t\tStackReserveSize=\"" << stackVal << "\"\n";
+ }
+ temp = target.GetDirectory(configName, true);
+ temp += "/";
+ temp += targetNameImport;
+ fout << "\t\t\t\tImportLibrary=\""
+ << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"";
+ if(this->FortranProject)
+ {
+ fout << "\n\t\t\t\tLinkDLL=\"true\"";
+ }
+ fout << "/>\n";
+ }
+ break;
+ case cmTarget::EXECUTABLE:
+ {
+ std::string targetName;
+ std::string targetNameFull;
+ std::string targetNameImport;
+ std::string targetNamePDB;
+ target.GetExecutableNames(targetName, targetNameFull,
+ targetNameImport, targetNamePDB, configName);
+
+ // Compute the link library and directory information.
+ cmComputeLinkInformation* pcli = target.GetLinkInformation(configName);
+ if(!pcli)
+ {
+ return;
+ }
+ cmComputeLinkInformation& cli = *pcli;
+ const char* linkLanguage = cli.GetLinkLanguage();
+
+ // Compute the variable name to lookup standard libraries for this
+ // language.
+ std::string standardLibsVar = "CMAKE_";
+ standardLibsVar += linkLanguage;
+ standardLibsVar += "_STANDARD_LIBRARIES";
+ const char* tool = "VCLinkerTool";
+ if(this->FortranProject)
+ {
+ tool = "VFLinkerTool";
+ }
+ fout << "\t\t\t<Tool\n"
+ << "\t\t\t\tName=\"" << tool << "\"\n";
+ if(!gg->NeedLinkLibraryDependencies(target))
+ {
+ fout << "\t\t\t\tLinkLibraryDependencies=\"false\"\n";
+ }
+ linkOptions.OutputAdditionalOptions(fout, "\t\t\t\t", "\n");
+ // Use the NOINHERIT macro to avoid getting VS project default
+ // 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)
+ {
+ this->Internal->OutputObjects(fout, &target, " ");
+ }
+ fout << " ";
+ this->Internal->OutputLibraries(fout, cli.GetItems());
+ fout << "\"\n";
+ temp = target.GetDirectory(configName);
+ temp += "/";
+ temp += targetNameFull;
+ fout << "\t\t\t\tOutputFile=\""
+ << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n";
+ this->WriteTargetVersionAttribute(fout, target);
+ linkOptions.OutputFlagMap(fout, "\t\t\t\t");
+ fout << "\t\t\t\tAdditionalLibraryDirectories=\"";
+ this->OutputLibraryDirectories(fout, cli.GetDirectories());
+ fout << "\"\n";
+ std::string path = this->ConvertToXMLOutputPathSingle(
+ target.GetDirectory(configName).c_str());
+ fout << "\t\t\t\tProgramDatabaseFile=\""
+ << path << "/" << targetNamePDB
+ << "\"\n";
+ if(isDebug)
+ {
+ fout << "\t\t\t\tGenerateDebugInformation=\"TRUE\"\n";
+ }
+ if ( target.GetPropertyAsBool("WIN32_EXECUTABLE") )
+ {
+ fout << "\t\t\t\tSubSystem=\""
+ << (this->FortranProject? "subSystemWindows" : "2") << "\"\n";
+ }
+ else
+ {
+ fout << "\t\t\t\tSubSystem=\""
+ << (this->FortranProject? "subSystemConsole" : "1") << "\"\n";
+ }
+ std::string stackVar = "CMAKE_";
+ stackVar += linkLanguage;
+ stackVar += "_STACK_SIZE";
+ const char* stackVal = this->Makefile->GetDefinition(stackVar.c_str());
+ if(stackVal)
+ {
+ fout << "\t\t\t\tStackReserveSize=\"" << stackVal << "\"";
+ }
+ 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:
+ break;
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmLocalVisualStudio7Generator
+::WriteTargetVersionAttribute(std::ostream& fout, cmTarget& target)
+{
+ int major;
+ int minor;
+ target.GetTargetVersion(major, minor);
+ fout << "\t\t\t\tVersion=\"" << major << "." << minor << "\"\n";
+}
+
+//----------------------------------------------------------------------------
+void
+cmLocalVisualStudio7GeneratorInternals
+::OutputLibraries(std::ostream& fout, ItemVector const& libs)
+{
+ cmLocalVisualStudio7Generator* lg = this->LocalGenerator;
+ for(ItemVector::const_iterator l = libs.begin(); l != libs.end(); ++l)
+ {
+ if(l->IsPath)
+ {
+ std::string rel = lg->Convert(l->Value.c_str(),
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::UNCHANGED);
+ fout << lg->ConvertToXMLOutputPath(rel.c_str()) << " ";
+ }
+ else
+ {
+ fout << l->Value << " ";
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmLocalVisualStudio7GeneratorInternals
+::OutputObjects(std::ostream& fout, cmTarget* t, 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);
+ const char* sep = isep? isep : "";
+ for(std::vector<std::string>::const_iterator
+ oi = objs.begin(); oi != objs.end(); ++oi)
+ {
+ std::string rel = lg->Convert(oi->c_str(),
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::UNCHANGED);
+ fout << sep << lg->ConvertToXMLOutputPath(rel.c_str());
+ sep = " ";
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmLocalVisualStudio7Generator
+::OutputLibraryDirectories(std::ostream& fout,
+ std::vector<std::string> const& dirs)
+{
+ const char* comma = "";
+ for(std::vector<std::string>::const_iterator d = dirs.begin();
+ d != dirs.end(); ++d)
+ {
+ // Remove any trailing slash and skip empty paths.
+ std::string dir = *d;
+ if(dir[dir.size()-1] == '/')
+ {
+ dir = dir.substr(0, dir.size()-1);
+ }
+ if(dir.empty())
+ {
+ continue;
+ }
+
+ // Switch to a relative path specification if it is shorter.
+ if(cmSystemTools::FileIsFullPath(dir.c_str()))
+ {
+ std::string rel = this->Convert(dir.c_str(), START_OUTPUT, UNCHANGED);
+ if(rel.size() < dir.size())
+ {
+ dir = rel;
+ }
+ }
+
+ // First search a configuration-specific subdirectory and then the
+ // original directory.
+ fout << comma << this->ConvertToXMLOutputPath((dir+"/$(OutDir)").c_str())
+ << "," << this->ConvertToXMLOutputPath(dir.c_str());
+ comma = ",";
+ }
+}
+
+void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
+ const char *libName,
+ cmTarget &target)
+{
+ // get the configurations
+ std::vector<std::string> *configs =
+ static_cast<cmGlobalVisualStudio7Generator *>
+ (this->GlobalGenerator)->GetConfigurations();
+
+ // 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();
+ for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
+ i != classes.end(); i++)
+ {
+ // 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 =
+ this->Makefile->FindSourceGroup(source.c_str(), sourceGroups);
+ sourceGroup.AssignSource(*i);
+ }
+
+ // open the project
+ this->WriteProjectStart(fout, libName, target, sourceGroups);
+ // write the configuration information
+ this->WriteConfigurations(fout, libName, target);
+
+ fout << "\t<Files>\n";
+
+
+ // Loop through every source group.
+ for(unsigned int i = 0; i < sourceGroups.size(); ++i)
+ {
+ cmSourceGroup sg = sourceGroups[i];
+ this->WriteGroup(&sg, target, fout, libName, configs);
+ }
+
+ if(this->GetVersion() >= VS8)
+ {
+ // 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);
+ if(!objs.empty())
+ {
+ // TODO: Separate sub-filter for each object library used?
+ fout << "\t\t<Filter Name=\"Object Libraries\">\n";
+ for(std::vector<std::string>::const_iterator
+ oi = objs.begin(); oi != objs.end(); ++oi)
+ {
+ std::string o = this->ConvertToXMLOutputPathSingle(oi->c_str());
+ fout << "\t\t\t<File RelativePath=\"" << o << "\" />\n";
+ }
+ fout << "\t\t</Filter>\n";
+ }
+ }
+
+ fout << "\t</Files>\n";
+
+ // Write the VCProj file's footer.
+ this->WriteVCProjFooter(fout, target);
+}
+
+struct cmLVS7GFileConfig
+{
+ std::string ObjectName;
+ std::string CompileFlags;
+ std::string CompileDefs;
+ std::string CompileDefsConfig;
+ std::string AdditionalDeps;
+ bool ExcludedFromBuild;
+};
+
+class cmLocalVisualStudio7GeneratorFCInfo
+{
+public:
+ cmLocalVisualStudio7GeneratorFCInfo(cmLocalVisualStudio7Generator* lg,
+ cmTarget& target,
+ cmSourceFile const& sf,
+ std::vector<std::string>* configs);
+ std::map<cmStdString, cmLVS7GFileConfig> FileConfigMap;
+};
+
+cmLocalVisualStudio7GeneratorFCInfo
+::cmLocalVisualStudio7GeneratorFCInfo(cmLocalVisualStudio7Generator* lg,
+ cmTarget& target,
+ cmSourceFile const& sf,
+ std::vector<std::string>* configs)
+{
+ cmGeneratorTarget* gt =
+ lg->GetGlobalGenerator()->GetGeneratorTarget(&target);
+ std::string objectName;
+ if(gt->ExplicitObjectName.find(&sf) != gt->ExplicitObjectName.end())
+ {
+ objectName = gt->Objects[&sf];
+ }
+
+ // Compute per-source, per-config information.
+ for(std::vector<std::string>::iterator i = configs->begin();
+ i != configs->end(); ++i)
+ {
+ std::string configUpper = cmSystemTools::UpperCase(*i);
+ cmLVS7GFileConfig fc;
+ bool needfc = false;
+ if(!objectName.empty())
+ {
+ fc.ObjectName = objectName;
+ needfc = true;
+ }
+ if(const char* cflags = sf.GetProperty("COMPILE_FLAGS"))
+ {
+ fc.CompileFlags = cflags;
+ needfc = true;
+ }
+ if(lg->FortranProject)
+ {
+ switch(lg->GetFortranFormat(sf.GetProperty("Fortran_FORMAT")))
+ {
+ case cmLocalGenerator::FortranFormatFixed:
+ fc.CompileFlags = "-fixed " + fc.CompileFlags;
+ needfc = true;
+ break;
+ case cmLocalGenerator::FortranFormatFree:
+ fc.CompileFlags = "-free " + fc.CompileFlags;
+ needfc = true;
+ break;
+ default: break;
+ }
+ }
+ if(const char* cdefs = sf.GetProperty("COMPILE_DEFINITIONS"))
+ {
+ fc.CompileDefs = cdefs;
+ needfc = true;
+ }
+ std::string defPropName = "COMPILE_DEFINITIONS_";
+ defPropName += configUpper;
+ if(const char* ccdefs = sf.GetProperty(defPropName.c_str()))
+ {
+ fc.CompileDefsConfig = ccdefs;
+ needfc = true;
+ }
+
+ // Check for extra object-file dependencies.
+ if(const char* deps = sf.GetProperty("OBJECT_DEPENDS"))
+ {
+ std::vector<std::string> depends;
+ cmSystemTools::ExpandListArgument(deps, depends);
+ const char* sep = "";
+ for(std::vector<std::string>::iterator j = depends.begin();
+ j != depends.end(); ++j)
+ {
+ fc.AdditionalDeps += sep;
+ fc.AdditionalDeps += lg->ConvertToXMLOutputPath(j->c_str());
+ sep = ";";
+ needfc = true;
+ }
+ }
+
+ const char* lang =
+ lg->GlobalGenerator->GetLanguageFromExtension
+ (sf.GetExtension().c_str());
+ const char* sourceLang = lg->GetSourceFileLanguage(sf);
+ const char* linkLanguage = target.GetLinkerLanguage(i->c_str());
+ bool needForceLang = false;
+ // source file does not match its extension language
+ if(lang && sourceLang && strcmp(lang, sourceLang) != 0)
+ {
+ needForceLang = true;
+ lang = sourceLang;
+ }
+ // If HEADER_FILE_ONLY is set, we must suppress this generation in
+ // the project file
+ fc.ExcludedFromBuild =
+ (sf.GetPropertyAsBool("HEADER_FILE_ONLY"));
+ if(fc.ExcludedFromBuild)
+ {
+ needfc = true;
+ }
+
+ // if the source file does not match the linker language
+ // then force c or c++
+ if(needForceLang || (linkLanguage && lang
+ && strcmp(lang, linkLanguage) != 0))
+ {
+ if(strcmp(lang, "CXX") == 0)
+ {
+ // force a C++ file type
+ fc.CompileFlags += " /TP ";
+ needfc = true;
+ }
+ else if(strcmp(lang, "C") == 0)
+ {
+ // force to c
+ fc.CompileFlags += " /TC ";
+ needfc = true;
+ }
+ }
+
+ if(needfc)
+ {
+ this->FileConfigMap[*i] = fc;
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmLocalVisualStudio7Generator
+::ComputeLongestObjectDirectory(cmTarget& target) const
+{
+ std::vector<std::string> *configs =
+ static_cast<cmGlobalVisualStudio7Generator *>
+ (this->GlobalGenerator)->GetConfigurations();
+ // Compute the maximum length configuration name.
+ std::string config_max;
+ for(std::vector<std::string>::iterator i = configs->begin();
+ i != configs->end(); ++i)
+ {
+ if(i->size() > config_max.size())
+ {
+ config_max = *i;
+ }
+ }
+
+ // Compute the maximum length full path to the intermediate
+ // 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 += "/";
+ dir_max += this->GetTargetDirectory(target);
+ dir_max += "/";
+ dir_max += config_max;
+ dir_max += "/";
+ return dir_max;
+}
+
+void cmLocalVisualStudio7Generator
+::WriteGroup(const cmSourceGroup *sg, cmTarget& target,
+ std::ostream &fout, const char *libName,
+ std::vector<std::string> *configs)
+{
+ const std::vector<const cmSourceFile *> &sourceFiles =
+ sg->GetSourceFiles();
+ // If the group is empty, don't write it at all.
+ if(sourceFiles.empty() && sg->GetGroupChildren().empty())
+ {
+ return;
+ }
+
+ // If the group has a name, write the header.
+ std::string name = sg->GetName();
+ if(name != "")
+ {
+ this->WriteVCProjBeginGroup(fout, name.c_str(), "");
+ }
+
+ // 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 )
+ {
+ fout << "\t\t\t<File\n";
+ std::string d = this->ConvertToXMLOutputPathSingle(source.c_str());
+ // Tell MS-Dev what the source is. If the compiler knows how to
+ // build it, then it will.
+ fout << "\t\t\t\tRelativePath=\"" << d << "\">\n";
+ if(cmCustomCommand const* command = (*sf)->GetCustomCommand())
+ {
+ this->WriteCustomRule(fout, source.c_str(), *command, fcinfo);
+ }
+ else if(!fcinfo.FileConfigMap.empty())
+ {
+ const char* aCompilerTool = "VCCLCompilerTool";
+ const char* lang = "CXX";
+ if(this->FortranProject)
+ {
+ aCompilerTool = "VFFortranCompilerTool";
+ }
+ std::string ext = (*sf)->GetExtension();
+ ext = cmSystemTools::LowerCase(ext);
+ if(ext == "idl")
+ {
+ aCompilerTool = "VCMIDLTool";
+ if(this->FortranProject)
+ {
+ aCompilerTool = "VFMIDLTool";
+ }
+ }
+ if(ext == "rc")
+ {
+ aCompilerTool = "VCResourceCompilerTool";
+ lang = "RC";
+ if(this->FortranProject)
+ {
+ aCompilerTool = "VFResourceCompilerTool";
+ }
+ }
+ if(ext == "def")
+ {
+ aCompilerTool = "VCCustomBuildTool";
+ if(this->FortranProject)
+ {
+ aCompilerTool = "VFCustomBuildTool";
+ }
+ }
+ for(std::map<cmStdString, 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 << "\"";
+ if(fc.ExcludedFromBuild)
+ {
+ fout << " ExcludedFromBuild=\"true\"";
+ }
+ fout << ">\n";
+ fout << "\t\t\t\t\t<Tool\n"
+ << "\t\t\t\t\tName=\"" << aCompilerTool << "\"\n";
+ if(!fc.CompileFlags.empty() ||
+ !fc.CompileDefs.empty() ||
+ !fc.CompileDefsConfig.empty())
+ {
+ Options::Tool tool = Options::Compiler;
+ cmVS7FlagTable const* table =
+ cmLocalVisualStudio7GeneratorFlagTable;
+ if(this->FortranProject)
+ {
+ tool = Options::FortranCompiler;
+ table = cmLocalVisualStudio7GeneratorFortranFlagTable;
+ }
+ Options fileOptions(this, tool, table,
+ this->ExtraFlagTable);
+ fileOptions.Parse(fc.CompileFlags.c_str());
+ fileOptions.AddDefines(fc.CompileDefs.c_str());
+ fileOptions.AddDefines(fc.CompileDefsConfig.c_str());
+ fileOptions.OutputAdditionalOptions(fout, "\t\t\t\t\t", "\n");
+ fileOptions.OutputFlagMap(fout, "\t\t\t\t\t");
+ fileOptions.OutputPreprocessorDefinitions(fout,
+ "\t\t\t\t\t", "\n",
+ lang);
+ }
+ if(!fc.AdditionalDeps.empty())
+ {
+ fout << "\t\t\t\t\tAdditionalDependencies=\""
+ << fc.AdditionalDeps.c_str() << "\"\n";
+ }
+ if(!fc.ObjectName.empty())
+ {
+ fout << "\t\t\t\t\tObjectFile=\"$(IntDir)/"
+ << fc.ObjectName.c_str() << "\"\n";
+ }
+ fout << "\t\t\t\t\t/>\n"
+ << "\t\t\t\t</FileConfiguration>\n";
+ }
+ }
+ fout << "\t\t\t</File>\n";
+ }
+ }
+
+ std::vector<cmSourceGroup> const& children = sg->GetGroupChildren();
+
+ for(unsigned int i=0;i<children.size();++i)
+ {
+ this->WriteGroup(&children[i], target, fout, libName, configs);
+ }
+
+ // If the group has a name, write the footer.
+ if(name != "")
+ {
+ this->WriteVCProjEndGroup(fout);
+ }
+}
+
+void cmLocalVisualStudio7Generator::
+WriteCustomRule(std::ostream& fout,
+ const char* source,
+ const cmCustomCommand& command,
+ FCInfo& fcinfo)
+{
+ std::string comment = this->ConstructComment(command);
+
+ // 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)
+ {
+ compileTool = "VFCLCompilerTool";
+ }
+ const char* customTool = "VCCustomBuildTool";
+ if(this->FortranProject)
+ {
+ customTool = "VFCustomBuildTool";
+ }
+ for(i = configs->begin(); i != configs->end(); ++i)
+ {
+ cmLVS7GFileConfig const& fc = fcinfo.FileConfigMap[*i];
+ fout << "\t\t\t\t<FileConfiguration\n";
+ fout << "\t\t\t\t\tName=\"" << *i << "|" << this->PlatformName << "\">\n";
+ if(!fc.CompileFlags.empty())
+ {
+ fout << "\t\t\t\t\t<Tool\n"
+ << "\t\t\t\t\tName=\"" << compileTool << "\"\n"
+ << "\t\t\t\t\tAdditionalOptions=\""
+ << this->EscapeForXML(fc.CompileFlags.c_str()) << "\"/>\n";
+ }
+
+ std::string script = this->ConstructScript(command, i->c_str());
+ if(this->FortranProject)
+ {
+ cmSystemTools::ReplaceString(script, "$(Configuration)", i->c_str());
+ }
+ fout << "\t\t\t\t\t<Tool\n"
+ << "\t\t\t\t\tName=\"" << customTool << "\"\n"
+ << "\t\t\t\t\tDescription=\""
+ << this->EscapeForXML(comment.c_str()) << "\"\n"
+ << "\t\t\t\t\tCommandLine=\""
+ << this->EscapeForXML(script.c_str()) << "\"\n"
+ << "\t\t\t\t\tAdditionalDependencies=\"";
+ if(command.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);
+ depout << "Artificial dependency for a custom command.\n";
+ }
+ fout << this->ConvertToXMLOutputPath(source);
+ }
+ else
+ {
+ // Write out the dependencies for the rule.
+ for(std::vector<std::string>::const_iterator d =
+ command.GetDepends().begin();
+ d != command.GetDepends().end();
+ ++d)
+ {
+ // Get the real name of the dependency in case it is a CMake target.
+ std::string dep;
+ if(this->GetRealDependency(d->c_str(), i->c_str(), dep))
+ {
+ fout << this->ConvertToXMLOutputPath(dep.c_str())
+ << ";";
+ }
+ }
+ }
+ fout << "\"\n";
+ fout << "\t\t\t\t\tOutputs=\"";
+ if(command.GetOutputs().empty())
+ {
+ fout << source << "_force";
+ }
+ else
+ {
+ // 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();
+ ++o)
+ {
+ fout << sep << this->ConvertToXMLOutputPathSingle(o->c_str());
+ sep = ";";
+ }
+ }
+ fout << "\"/>\n";
+ fout << "\t\t\t\t</FileConfiguration>\n";
+ }
+}
+
+
+void cmLocalVisualStudio7Generator::WriteVCProjBeginGroup(std::ostream& fout,
+ const char* group,
+ const char* )
+{
+ fout << "\t\t<Filter\n"
+ << "\t\t\tName=\"" << group << "\"\n"
+ << "\t\t\tFilter=\"\">\n";
+}
+
+
+void cmLocalVisualStudio7Generator::WriteVCProjEndGroup(std::ostream& fout)
+{
+ fout << "\t\t</Filter>\n";
+}
+
+
+// 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*/)
+{
+ if (target.GetType() > cmTarget::GLOBAL_TARGET)
+ {
+ return;
+ }
+ EventWriter event(this, configName, fout);
+
+ // Add pre-build event.
+ const char* tool =
+ this->FortranProject? "VFPreBuildEventTool":"VCPreBuildEventTool";
+ event.Start(tool);
+ event.Write(target.GetPreBuildCommands());
+ event.Finish();
+
+ // Add pre-link event.
+ tool = this->FortranProject? "VFPreLinkEventTool":"VCPreLinkEventTool";
+ event.Start(tool);
+ event.Write(target.GetPreLinkCommands());
+ cmsys::auto_ptr<cmCustomCommand> pcc(
+ this->MaybeCreateImplibDir(target, configName, this->FortranProject));
+ if(pcc.get())
+ {
+ event.Write(*pcc);
+ }
+ event.Finish();
+
+ // Add post-build event.
+ tool = this->FortranProject? "VFPostBuildEventTool":"VCPostBuildEventTool";
+ event.Start(tool);
+ event.Write(target.GetPostBuildCommands());
+ event.Finish();
+}
+
+void cmLocalVisualStudio7Generator::WriteProjectSCC(std::ostream& fout,
+ cmTarget& 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");
+
+ if(vsProvider && vsLocalpath && vsProjectname)
+ {
+ fout << "\tSccProjectName=\"" << vsProjectname << "\"\n"
+ << "\tSccLocalPath=\"" << vsLocalpath << "\"\n"
+ << "\tSccProvider=\"" << vsProvider << "\"\n";
+
+ const char* vsAuxPath = target.GetProperty("VS_SCC_AUXPATH");
+ if(vsAuxPath)
+ {
+ fout << "\tSccAuxPath=\"" << vsAuxPath << "\"\n";
+ }
+ }
+}
+
+void
+cmLocalVisualStudio7Generator
+::WriteProjectStartFortran(std::ostream& fout,
+ const char *libName,
+ cmTarget & 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 = "9.10";
+ std::string vskey = gg->GetRegistryBase();
+ vskey += "\\Packages\\" CM_INTEL_PLUGIN_GUID ";ProductVersion";
+ cmSystemTools::ReadRegistryValue(vskey.c_str(), intelVersion,
+ cmSystemTools::KeyWOW64_32);
+ if (intelVersion.find("13") == 0 ||
+ intelVersion.find("12") == 0 ||
+ intelVersion.find("11") == 0)
+ {
+ // Version 11.x, 12.x, and 13.x actually use 11.0 in project files!
+ intelVersion = "11.0" ;
+ }
+ else if(intelVersion.find("10") == 0)
+ {
+ // Version 10.x actually uses 9.10 in project files!
+ intelVersion = "9.10";
+ }
+
+ fout << "<?xml version=\"1.0\" encoding = \"Windows-1252\"?>\n"
+ << "<VisualStudioProject\n"
+ << "\tProjectCreator=\"Intel Fortran\"\n"
+ << "\tVersion=\"" << intelVersion << "\"\n";
+ const char* keyword = target.GetProperty("VS_KEYWORD");
+ if(!keyword)
+ {
+ keyword = "Console Application";
+ }
+ const char* projectType = 0;
+ switch(target.GetType())
+ {
+ case cmTarget::STATIC_LIBRARY:
+ projectType = "typeStaticLibrary";
+ if(keyword)
+ {
+ keyword = "Static Library";
+ }
+ break;
+ case cmTarget::SHARED_LIBRARY:
+ case cmTarget::MODULE_LIBRARY:
+ projectType = "typeDynamicLibrary";
+ if(!keyword)
+ {
+ keyword = "Dll";
+ }
+ break;
+ case cmTarget::EXECUTABLE:
+ if(!keyword)
+ {
+ keyword = "Console Application";
+ }
+ projectType = 0;
+ break;
+ case cmTarget::UTILITY:
+ case cmTarget::GLOBAL_TARGET:
+ default:
+ break;
+ }
+ if(projectType)
+ {
+ fout << "\tProjectType=\"" << projectType << "\"\n";
+ }
+ this->WriteProjectSCC(fout, target);
+ fout<< "\tKeyword=\"" << keyword << "\">\n"
+ << "\tProjectGUID=\"{" << gg->GetGUID(libName) << "}\">\n"
+ << "\t<Platforms>\n"
+ << "\t\t<Platform\n\t\t\tName=\"" << this->PlatformName << "\"/>\n"
+ << "\t</Platforms>\n";
+}
+
+
+void
+cmLocalVisualStudio7Generator::WriteProjectStart(std::ostream& fout,
+ const char *libName,
+ cmTarget & target,
+ std::vector<cmSourceGroup> &)
+{
+ if(this->FortranProject)
+ {
+ this->WriteProjectStartFortran(fout, libName, target);
+ return;
+ }
+ fout << "<?xml version=\"1.0\" encoding = \"Windows-1252\"?>\n"
+ << "<VisualStudioProject\n"
+ << "\tProjectType=\"Visual C++\"\n";
+ if(this->Version == VS71)
+ {
+ fout << "\tVersion=\"7.10\"\n";
+ }
+ else
+ {
+ fout << "\tVersion=\"" << (this->Version/10) << ".00\"\n";
+ }
+ const char* projLabel = target.GetProperty("PROJECT_LABEL");
+ if(!projLabel)
+ {
+ projLabel = libName;
+ }
+ 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)
+ {
+ fout << "\tProjectGUID=\"{" << gg->GetGUID(libName) << "}\"\n";
+ }
+ this->WriteProjectSCC(fout, target);
+ fout << "\tKeyword=\"" << keyword << "\">\n"
+ << "\t<Platforms>\n"
+ << "\t\t<Platform\n\t\t\tName=\"" << this->PlatformName << "\"/>\n"
+ << "\t</Platforms>\n";
+}
+
+
+void cmLocalVisualStudio7Generator::WriteVCProjFooter(std::ostream& fout,
+ cmTarget &target)
+{
+ fout << "\t<Globals>\n";
+
+ cmPropertyMap const& props = target.GetProperties();
+ for(cmPropertyMap::const_iterator i = props.begin(); i != props.end(); ++i)
+ {
+ if(i->first.find("VS_GLOBAL_") == 0)
+ {
+ std::string name = i->first.substr(10);
+ if(name != "")
+ {
+ fout << "\t\t<Global\n"
+ << "\t\t\tName=\"" << name << "\"\n"
+ << "\t\t\tValue=\"" << i->second.GetValue() << "\"\n"
+ << "\t\t/>\n";
+ }
+ }
+ }
+
+ fout << "\t</Globals>\n"
+ << "</VisualStudioProject>\n";
+}
+
+std::string cmLocalVisualStudio7GeneratorEscapeForXML(const char* s)
+{
+ std::string ret = s;
+ cmSystemTools::ReplaceString(ret, "&", "&amp;");
+ cmSystemTools::ReplaceString(ret, "\"", "&quot;");
+ cmSystemTools::ReplaceString(ret, "<", "&lt;");
+ cmSystemTools::ReplaceString(ret, ">", "&gt;");
+ cmSystemTools::ReplaceString(ret, "\n", "&#x0D;&#x0A;");
+ return ret;
+}
+
+std::string cmLocalVisualStudio7Generator::EscapeForXML(const char* s)
+{
+ return cmLocalVisualStudio7GeneratorEscapeForXML(s);
+}
+
+std::string cmLocalVisualStudio7Generator
+::ConvertToXMLOutputPath(const char* path)
+{
+ std::string ret = this->ConvertToOptionallyRelativeOutputPath(path);
+ cmSystemTools::ReplaceString(ret, "&", "&amp;");
+ cmSystemTools::ReplaceString(ret, "\"", "&quot;");
+ cmSystemTools::ReplaceString(ret, "<", "&lt;");
+ cmSystemTools::ReplaceString(ret, ">", "&gt;");
+ return ret;
+}
+
+std::string cmLocalVisualStudio7Generator
+::ConvertToXMLOutputPathSingle(const char* path)
+{
+ std::string ret = this->ConvertToOptionallyRelativeOutputPath(path);
+ cmSystemTools::ReplaceString(ret, "\"", "");
+ cmSystemTools::ReplaceString(ret, "&", "&amp;");
+ cmSystemTools::ReplaceString(ret, "<", "&lt;");
+ cmSystemTools::ReplaceString(ret, ">", "&gt;");
+ return ret;
+}
+
+
+// This class is used to parse an existing vs 7 project
+// and extract the GUID
+class cmVS7XMLParser : public cmXMLParser
+{
+public:
+ virtual void EndElement(const char* /* name */)
+ {
+ }
+ virtual void StartElement(const char* name, const char** atts)
+ {
+ // once the GUID is found do nothing
+ if(this->GUID.size())
+ {
+ return;
+ }
+ int i =0;
+ if(strcmp("VisualStudioProject", name) == 0)
+ {
+ while(atts[i])
+ {
+ if(strcmp(atts[i], "ProjectGUID") == 0)
+ {
+ if(atts[i+1])
+ {
+ this->GUID = atts[i+1];
+ this->GUID = this->GUID.substr(1, this->GUID.size()-2);
+ }
+ else
+ {
+ this->GUID = "";
+ }
+ return;
+ }
+ ++i;
+ }
+ }
+ }
+ int InitializeParser()
+ {
+ int ret = cmXMLParser::InitializeParser();
+ if(ret == 0)
+ {
+ return ret;
+ }
+ // visual studio projects have a strange encoding, but it is
+ // really utf-8
+ XML_SetEncoding(static_cast<XML_Parser>(this->Parser), "utf-8");
+ return 1;
+ }
+ std::string GUID;
+};
+
+void cmLocalVisualStudio7Generator::ReadAndStoreExternalGUID(
+ const char* name,
+ const char* path)
+{
+ cmVS7XMLParser parser;
+ parser.ParseFile(path);
+ // if we can not find a GUID then create one
+ if(parser.GUID.size() == 0)
+ {
+ cmGlobalVisualStudio7Generator* gg =
+ static_cast<cmGlobalVisualStudio7Generator *>(this->GlobalGenerator);
+ gg->CreateGUID(name);
+ return;
+ }
+ std::string guidStoreName = name;
+ guidStoreName += "_GUID_CMAKE";
+ // save the GUID in the cache
+ this->GlobalGenerator->GetCMakeInstance()->
+ AddCacheEntry(guidStoreName.c_str(),
+ parser.GUID.c_str(),
+ "Stored GUID",
+ cmCacheManager::INTERNAL);
+}
+
+
+//----------------------------------------------------------------------------
+std::string cmLocalVisualStudio7Generator
+::GetTargetDirectory(cmTarget const& target) const
+{
+ std::string dir;
+ dir += target.GetName();
+ dir += ".dir";
+ return dir;
+}
+
+//----------------------------------------------------------------------------
+#include <windows.h>
+static bool cmLVS6G_IsFAT(const char* dir)
+{
+ if(dir[0] && dir[1] == ':')
+ {
+ char volRoot[4] = "_:/";
+ volRoot[0] = dir[0];
+ char fsName[16];
+ if(GetVolumeInformation(volRoot, 0, 0, 0, 0, 0, fsName, 16) &&
+ strstr(fsName, "FAT") != 0)
+ {
+ return true;
+ }
+ }
+ return false;
+}
diff --git a/Source/cmLocalVisualStudio7Generator.h b/Source/cmLocalVisualStudio7Generator.h
new file mode 100644
index 000000000..9aa408eda
--- /dev/null
+++ b/Source/cmLocalVisualStudio7Generator.h
@@ -0,0 +1,131 @@
+/*============================================================================
+ 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 cmLocalVisualStudio7Generator_h
+#define cmLocalVisualStudio7Generator_h
+
+#include "cmLocalVisualStudioGenerator.h"
+#include "cmVisualStudioGeneratorOptions.h"
+
+class cmTarget;
+class cmSourceFile;
+class cmCustomCommand;
+class cmSourceGroup;
+
+
+class cmLocalVisualStudio7GeneratorOptions;
+class cmLocalVisualStudio7GeneratorFCInfo;
+class cmLocalVisualStudio7GeneratorInternals;
+
+/** \class cmLocalVisualStudio7Generator
+ * \brief Write Visual Studio .NET project files.
+ *
+ * cmLocalVisualStudio7Generator produces a Visual Studio .NET project
+ * file for each target in its directory.
+ */
+class cmLocalVisualStudio7Generator : public cmLocalVisualStudioGenerator
+{
+public:
+ ///! Set cache only and recurse to false by default.
+ cmLocalVisualStudio7Generator(VSVersion v);
+
+ virtual ~cmLocalVisualStudio7Generator();
+
+ virtual void AddHelperCommands();
+
+ /**
+ * Generate the makefile for this directory.
+ */
+ virtual void Generate();
+
+ enum BuildType {STATIC_LIBRARY, DLL, EXECUTABLE, WIN32_EXECUTABLE, UTILITY};
+
+ /**
+ * Specify the type of the build: static, dll, or executable.
+ */
+ void SetBuildType(BuildType,const char *name);
+
+ void SetPlatformName(const char* n) { this->PlatformName = n;}
+
+ void SetExtraFlagTable(cmVS7FlagTable const* table)
+ { this->ExtraFlagTable = table; }
+ virtual std::string GetTargetDirectory(cmTarget const&) const;
+ cmSourceFile* CreateVCProjBuildRule();
+ void WriteStampFiles();
+ virtual std::string ComputeLongestObjectDirectory(cmTarget&) const;
+
+ virtual void ReadAndStoreExternalGUID(const char* name,
+ const char* path);
+ virtual void AddCMakeListsRules();
+protected:
+ void CreateSingleVCProj(const char *lname, cmTarget &tgt);
+private:
+ typedef cmVisualStudioGeneratorOptions Options;
+ typedef cmLocalVisualStudio7GeneratorFCInfo FCInfo;
+ std::string GetBuildTypeLinkerFlags(std::string rootLinkerFlags,
+ const char* 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 WriteConfigurations(std::ostream& fout,
+ const char *libName, cmTarget &tgt);
+ void WriteConfiguration(std::ostream& fout,
+ const char* configName,
+ const char* libName, cmTarget &tgt);
+ std::string EscapeForXML(const char* 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, bool debug);
+ 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 WriteVCProjBeginGroup(std::ostream& fout,
+ const char* group,
+ const char* filter);
+ void WriteVCProjEndGroup(std::ostream& fout);
+
+ void WriteCustomRule(std::ostream& fout,
+ const char* source,
+ const cmCustomCommand& command,
+ FCInfo& fcinfo);
+ void WriteTargetVersionAttribute(std::ostream& fout, cmTarget& target);
+
+ void WriteGroup(const cmSourceGroup *sg,
+ cmTarget& target, std::ostream &fout,
+ const char *libName, std::vector<std::string> *configs);
+
+ friend class cmLocalVisualStudio7GeneratorFCInfo;
+ friend class cmLocalVisualStudio7GeneratorInternals;
+
+ class EventWriter;
+ friend class EventWriter;
+
+ cmVS7FlagTable const* ExtraFlagTable;
+ std::string ModuleDefinitionFile;
+ bool FortranProject;
+ std::string PlatformName; // Win32 or x64
+ cmLocalVisualStudio7GeneratorInternals* Internal;
+};
+
+
+#endif
+
diff --git a/Source/cmLocalVisualStudioGenerator.cxx b/Source/cmLocalVisualStudioGenerator.cxx
new file mode 100644
index 000000000..4bcf4defd
--- /dev/null
+++ b/Source/cmLocalVisualStudioGenerator.cxx
@@ -0,0 +1,206 @@
+/*============================================================================
+ 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 "cmLocalVisualStudioGenerator.h"
+#include "cmGlobalGenerator.h"
+#include "cmMakefile.h"
+#include "cmSourceFile.h"
+#include "cmSystemTools.h"
+#include "cmCustomCommandGenerator.h"
+#include "windows.h"
+
+//----------------------------------------------------------------------------
+cmLocalVisualStudioGenerator::cmLocalVisualStudioGenerator(VSVersion v)
+{
+ this->WindowsShell = true;
+ this->WindowsVSIDE = true;
+ this->Version = v;
+}
+
+//----------------------------------------------------------------------------
+cmLocalVisualStudioGenerator::~cmLocalVisualStudioGenerator()
+{
+}
+
+//----------------------------------------------------------------------------
+cmsys::auto_ptr<cmCustomCommand>
+cmLocalVisualStudioGenerator::MaybeCreateImplibDir(cmTarget& target,
+ const char* config,
+ bool isFortran)
+{
+ cmsys::auto_ptr<cmCustomCommand> pcc;
+
+ // 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))
+ { return pcc; }
+ 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("-E");
+ command.push_back("make_directory");
+ command.push_back(impDir);
+ std::vector<std::string> no_output;
+ 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->SetEscapeOldStyle(false);
+ pcc->SetEscapeAllowMakeVars(true);
+ return pcc;
+}
+
+//----------------------------------------------------------------------------
+const char* cmLocalVisualStudioGenerator::ReportErrorLabel() const
+{
+ return ":VCReportError";
+}
+
+//----------------------------------------------------------------------------
+const char* cmLocalVisualStudioGenerator::GetReportErrorLabel() const
+{
+ return this->ReportErrorLabel();
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmLocalVisualStudioGenerator
+::ConstructScript(cmCustomCommand const& cc,
+ const char* configName,
+ const char* newline_text)
+{
+ bool useLocal = this->CustomCommandUseLocal();
+ const cmCustomCommandLines& commandLines = cc.GetCommandLines();
+ const char* workingDirectory = cc.GetWorkingDirectory();
+ cmCustomCommandGenerator ccg(cc, configName, this->Makefile);
+ RelativeRoot relativeRoot = workingDirectory? NONE : START_OUTPUT;
+
+ // Avoid leading or trailing newlines.
+ const char* newline = "";
+
+ // Line to check for error between commands.
+ std::string check_error = newline_text;
+ if(useLocal)
+ {
+ check_error += "if %errorlevel% neq 0 goto :cmEnd";
+ }
+ else
+ {
+ check_error += "if errorlevel 1 goto ";
+ check_error += this->GetReportErrorLabel();
+ }
+
+ // Store the script in a string.
+ std::string script;
+
+ // Open a local context.
+ if(useLocal)
+ {
+ script += newline;
+ newline = newline_text;
+ script += "setlocal";
+ }
+
+ if(workingDirectory)
+ {
+ // Change the working directory.
+ script += newline;
+ newline = newline_text;
+ script += "cd ";
+ script += this->Convert(workingDirectory, FULL, SHELL);
+ script += check_error;
+
+ // Change the working drive.
+ if(workingDirectory[0] && workingDirectory[1] == ':')
+ {
+ script += newline;
+ newline = newline_text;
+ script += workingDirectory[0];
+ script += workingDirectory[1];
+ script += check_error;
+ }
+ }
+
+ // for visual studio IDE add extra stuff to the PATH
+ // if CMAKE_MSVCIDE_RUN_PATH is set.
+ if(this->Makefile->GetDefinition("MSVC_IDE"))
+ {
+ const char* extraPath =
+ this->Makefile->GetDefinition("CMAKE_MSVCIDE_RUN_PATH");
+ if(extraPath)
+ {
+ script += newline;
+ newline = newline_text;
+ script += "set PATH=";
+ script += extraPath;
+ script += ";%PATH%";
+ }
+ }
+
+ // Write each command on a single line.
+ for(unsigned int c = 0; c < ccg.GetNumberOfCommands(); ++c)
+ {
+ // Start a new line.
+ script += newline;
+ newline = newline_text;
+
+ // Add this command line.
+ std::string cmd = ccg.GetCommand(c);
+
+ // Use "call " before any invocations of .bat or .cmd files
+ // invoked as custom commands.
+ //
+ std::string suffix;
+ if (cmd.size() > 4)
+ {
+ suffix = cmSystemTools::LowerCase(cmd.substr(cmd.size()-4));
+ if (suffix == ".bat" || suffix == ".cmd")
+ {
+ script += "call ";
+ }
+ }
+
+ script += this->Convert(cmd.c_str(), relativeRoot, SHELL);
+ ccg.AppendArguments(c, script);
+
+ // After each custom command, check for an error result.
+ // If there was an error, jump to the VCReportError label,
+ // skipping the run of any subsequent commands in this
+ // sequence.
+ script += check_error;
+ }
+
+ // Close the local context.
+ if(useLocal)
+ {
+ script += newline;
+ script += ":cmEnd";
+ script += newline;
+ script += "endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone";
+ script += newline;
+ script += ":cmErrorLevel";
+ script += newline;
+ script += "exit /b %1";
+ script += newline;
+ script += ":cmDone";
+ script += newline;
+ script += "if %errorlevel% neq 0 goto ";
+ script += this->GetReportErrorLabel();
+ }
+
+ return script;
+}
diff --git a/Source/cmLocalVisualStudioGenerator.h b/Source/cmLocalVisualStudioGenerator.h
new file mode 100644
index 000000000..9968592d1
--- /dev/null
+++ b/Source/cmLocalVisualStudioGenerator.h
@@ -0,0 +1,74 @@
+/*============================================================================
+ 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 cmLocalVisualStudioGenerator_h
+#define cmLocalVisualStudioGenerator_h
+
+#include "cmLocalGenerator.h"
+
+#include <cmsys/auto_ptr.hxx>
+
+class cmSourceFile;
+class cmSourceGroup;
+class cmCustomCommand;
+
+/** \class cmLocalVisualStudioGenerator
+ * \brief Base class for Visual Studio generators.
+ *
+ * cmLocalVisualStudioGenerator provides functionality common to all
+ * Visual Studio generators.
+ */
+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
+ };
+
+ cmLocalVisualStudioGenerator(VSVersion v);
+ 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");
+
+ /** 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; }
+
+ virtual std::string ComputeLongestObjectDirectory(cmTarget&) const = 0;
+
+ virtual void AddCMakeListsRules() = 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;
+};
+
+#endif
diff --git a/Source/cmLocalXCodeGenerator.cxx b/Source/cmLocalXCodeGenerator.cxx
new file mode 100644
index 000000000..551ebd30a
--- /dev/null
+++ b/Source/cmLocalXCodeGenerator.cxx
@@ -0,0 +1,35 @@
+/*============================================================================
+ 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 "cmLocalXCodeGenerator.h"
+#include "cmGlobalXCodeGenerator.h"
+#include "cmSourceFile.h"
+
+//----------------------------------------------------------------------------
+cmLocalXCodeGenerator::cmLocalXCodeGenerator()
+{
+ // the global generator does this, so do not
+ // put these flags into the language flags
+ this->EmitUniversalBinaryFlags = false;
+}
+
+//----------------------------------------------------------------------------
+cmLocalXCodeGenerator::~cmLocalXCodeGenerator()
+{
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmLocalXCodeGenerator::GetTargetDirectory(cmTarget const&) const
+{
+ // No per-target directory for this generator (yet).
+ return "";
+}
diff --git a/Source/cmLocalXCodeGenerator.h b/Source/cmLocalXCodeGenerator.h
new file mode 100644
index 000000000..eab228f6b
--- /dev/null
+++ b/Source/cmLocalXCodeGenerator.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 cmLocalXCodeGenerator_h
+#define cmLocalXCodeGenerator_h
+
+#include "cmLocalGenerator.h"
+
+/** \class cmLocalXCodeGenerator
+ * \brief Write a local Xcode project
+ *
+ * cmLocalXCodeGenerator produces a LocalUnix makefile from its
+ * member Makefile.
+ */
+class cmLocalXCodeGenerator : public cmLocalGenerator
+{
+public:
+ ///! Set cache only and recurse to false by default.
+ cmLocalXCodeGenerator();
+
+ virtual ~cmLocalXCodeGenerator();
+ virtual std::string GetTargetDirectory(cmTarget const& target) const;
+private:
+
+};
+
+#endif
+
diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx
new file mode 100644
index 000000000..259922759
--- /dev/null
+++ b/Source/cmMacroCommand.cxx
@@ -0,0 +1,350 @@
+/*============================================================================
+ 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 "cmMacroCommand.h"
+
+#include "cmake.h"
+
+// define the class for macro commands
+class cmMacroHelperCommand : public cmCommand
+{
+public:
+ cmMacroHelperCommand() {}
+
+ ///! clean up any memory allocated by the macro
+ ~cmMacroHelperCommand() {};
+
+ /**
+ * This is used to avoid including this command
+ * in documentation. This is mainly used by
+ * cmMacroHelperCommand and cmFunctionHelperCommand
+ * which cannot provide appropriate documentation.
+ */
+ virtual bool ShouldAppearInDocumentation() const
+ {
+ return false;
+ }
+
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ cmMacroHelperCommand *newC = new cmMacroHelperCommand;
+ // we must copy when we clone
+ newC->Args = this->Args;
+ newC->Functions = this->Functions;
+ newC->FilePath = this->FilePath;
+ newC->Policies = this->Policies;
+ return newC;
+ }
+
+ /**
+ * This determines if the command is invoked when in script mode.
+ */
+ virtual bool IsScriptable() const { return true; }
+
+ /**
+ * This is called when the command is first encountered in
+ * the CMakeLists.txt file.
+ */
+ virtual bool InvokeInitialPass(const std::vector<cmListFileArgument>& args,
+ cmExecutionStatus &);
+
+ virtual bool InitialPass(std::vector<std::string> const&,
+ 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();
+ }
+
+ cmTypeMacro(cmMacroHelperCommand, cmCommand);
+
+ std::vector<std::string> Args;
+ std::vector<cmListFileFunction> Functions;
+ cmPolicies::PolicyMap Policies;
+ std::string FilePath;
+};
+
+
+bool cmMacroHelperCommand::InvokeInitialPass
+(const std::vector<cmListFileArgument>& args,
+ cmExecutionStatus &inStatus)
+{
+ // Expand the argument list to the macro.
+ 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)
+ {
+ std::string errorMsg =
+ "Macro invoked with incorrect arguments for macro named: ";
+ errorMsg += this->Args[0];
+ this->SetError(errorMsg.c_str());
+ 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);
+
+ // set the value of argc
+ cmOStringStream 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())
+ {
+ this->FilePath = this->Functions[0].FilePath;
+ }
+ // Invoke all the functions that were collected in the block.
+ cmListFileFunction newLFF;
+ // for each function
+ for(unsigned int c = 0; c < this->Functions.size(); ++c)
+ {
+ // Replace the formal arguments and then invoke the command.
+ 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
+ for (std::vector<cmListFileArgument>::iterator k =
+ 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)
+ {
+ 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)
+ {
+ 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(tmps, "${ARGN}", argnDef.c_str());
+ }
+
+ // 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];
+
+ // repleace ARGV, compute it only once
+ if (!argvDefInitialized)
+ {
+ std::vector<std::string>::const_iterator eit;
+ for ( eit = expandedArgs.begin(); eit != expandedArgs.end(); ++eit )
+ {
+ if ( argvDef.size() > 0 )
+ {
+ argvDef += ";";
+ }
+ argvDef += *eit;
+ }
+ 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.Quoted = k->Quoted;
+ arg.FilePath = k->FilePath;
+ arg.Line = k->Line;
+ newLFF.Arguments.push_back(arg);
+ }
+ cmExecutionStatus status;
+ if(!this->Makefile->ExecuteCommand(newLFF, status) ||
+ status.GetNestedError())
+ {
+ // The error message should have already included the call stack
+ // so we do not need to report an error here.
+ lexScope.Quiet();
+ polScope.Quiet();
+ inStatus.SetNestedError(true);
+ return false;
+ }
+ if (status.GetReturnInvoked())
+ {
+ inStatus.SetReturnInvoked(true);
+ return true;
+ }
+ if (status.GetBreakInvoked())
+ {
+ inStatus.SetBreakInvoked(true);
+ return true;
+ }
+ }
+ return true;
+}
+
+bool cmMacroFunctionBlocker::
+IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf,
+ cmExecutionStatus &)
+{
+ // record commands until we hit the ENDMACRO
+ // at the ENDMACRO call we shift gears and start looking for invocations
+ if(!cmSystemTools::Strucmp(lff.Name.c_str(),"macro"))
+ {
+ this->Depth++;
+ }
+ else if(!cmSystemTools::Strucmp(lff.Name.c_str(),"endmacro"))
+ {
+ // 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());
+ // create a new command and add it to cmake
+ cmMacroHelperCommand *f = new cmMacroHelperCommand();
+ f->Args = this->Args;
+ f->Functions = this->Functions;
+ mf.RecordPolicies(f->Policies);
+ std::string newName = "_" + this->Args[0];
+ mf.GetCMakeInstance()->RenameCommand(this->Args[0].c_str(),
+ newName.c_str());
+ mf.AddCommand(f);
+
+ // remove the function blocker now that the macro is defined
+ mf.RemoveFunctionBlocker(this, lff);
+ return true;
+ }
+ else
+ {
+ // decrement for each nested macro that ends
+ this->Depth--;
+ }
+ }
+
+ // if it wasn't an endmacro and we are not executing then we must be
+ // recording
+ this->Functions.push_back(lff);
+ return true;
+}
+
+
+bool cmMacroFunctionBlocker::
+ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf)
+{
+ if(!cmSystemTools::Strucmp(lff.Name.c_str(),"endmacro"))
+ {
+ std::vector<std::string> expandedArguments;
+ mf.ExpandArguments(lff.Arguments, expandedArguments);
+ // if the endmacro has arguments make sure they
+ // match the arguments of the macro
+ if ((expandedArguments.empty() ||
+ (expandedArguments[0] == this->Args[0])))
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool cmMacroCommand::InitialPass(std::vector<std::string> const& args,
+ cmExecutionStatus &)
+{
+ if(args.size() < 1)
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ // 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);
+ }
+ this->Makefile->AddFunctionBlocker(f);
+ return true;
+}
+
diff --git a/Source/cmMacroCommand.h b/Source/cmMacroCommand.h
new file mode 100644
index 000000000..36e4b2f6b
--- /dev/null
+++ b/Source/cmMacroCommand.h
@@ -0,0 +1,110 @@
+/*============================================================================
+ 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 cmMacroCommand_h
+#define cmMacroCommand_h
+
+#include "cmCommand.h"
+#include "cmFunctionBlocker.h"
+
+class cmMacroFunctionBlocker : public cmFunctionBlocker
+{
+public:
+ cmMacroFunctionBlocker() {this->Depth=0;}
+ virtual ~cmMacroFunctionBlocker() {}
+ virtual bool IsFunctionBlocked(const cmListFileFunction&,
+ cmMakefile &mf,
+ cmExecutionStatus &);
+ virtual bool ShouldRemove(const cmListFileFunction&, cmMakefile &mf);
+
+ std::vector<std::string> Args;
+ std::vector<cmListFileFunction> Functions;
+ int Depth;
+};
+
+/// Starts macro() ... endmacro() block
+class cmMacroCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmMacroCommand;
+ }
+
+ /**
+ * 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 const char* 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 argument 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 you should look at "
+ "the function command."
+ "\n"
+ "See the cmake_policy() command documentation for the behavior of "
+ "policies inside macros."
+ ;
+ }
+ cmTypeMacro(cmMacroCommand, cmCommand);
+};
+
+
+#endif
diff --git a/Source/cmMakeDepend.cxx b/Source/cmMakeDepend.cxx
new file mode 100644
index 000000000..6055c5585
--- /dev/null
+++ b/Source/cmMakeDepend.cxx
@@ -0,0 +1,352 @@
+/*============================================================================
+ 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 <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 std::vector<std::string>& includes =
+ l->second.GetIncludeDirectories();
+ 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
new file mode 100644
index 000000000..185f4e356
--- /dev/null
+++ b/Source/cmMakeDepend.h
@@ -0,0 +1,150 @@
+/*============================================================================
+ 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
new file mode 100644
index 000000000..63be62734
--- /dev/null
+++ b/Source/cmMakeDirectoryCommand.cxx
@@ -0,0 +1,34 @@
+/*============================================================================
+ 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 "cmMakeDirectoryCommand.h"
+
+// cmMakeDirectoryCommand
+bool cmMakeDirectoryCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() != 1 )
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+ if ( !this->Makefile->CanIWriteThisFile(args[0].c_str()) )
+ {
+ std::string e = "attempted to create a directory: " + args[0]
+ + " into a source directory.";
+ this->SetError(e.c_str());
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+ cmSystemTools::MakeDirectory(args[0].c_str());
+ return true;
+}
+
diff --git a/Source/cmMakeDirectoryCommand.h b/Source/cmMakeDirectoryCommand.h
new file mode 100644
index 000000000..4e6e1d5ab
--- /dev/null
+++ b/Source/cmMakeDirectoryCommand.h
@@ -0,0 +1,85 @@
+/*============================================================================
+ 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 cmMakeDirectoryCommand_h
+#define cmMakeDirectoryCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmMakeDirectoryCommand
+ * \brief Specify auxiliary source code directories.
+ *
+ * cmMakeDirectoryCommand specifies source code directories
+ * that must be built as part of this build process. This directories
+ * are not recursively processed like the SUBDIR command (cmSubdirCommand).
+ * A side effect of this command is to create a subdirectory in the build
+ * directory structure.
+ */
+class cmMakeDirectoryCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmMakeDirectoryCommand;
+ }
+
+ /**
+ * 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 const char* 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);
+};
+
+
+
+#endif
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
new file mode 100644
index 000000000..7b6c450f1
--- /dev/null
+++ b/Source/cmMakefile.cxx
@@ -0,0 +1,4309 @@
+/*============================================================================
+ 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"
+#include "cmVersion.h"
+#include "cmCommand.h"
+#include "cmSourceFile.h"
+#include "cmSourceFileLocation.h"
+#include "cmSystemTools.h"
+#include "cmGlobalGenerator.h"
+#include "cmLocalGenerator.h"
+#include "cmCommands.h"
+#include "cmCacheManager.h"
+#include "cmFunctionBlocker.h"
+#include "cmListFileCache.h"
+#include "cmCommandArgumentParserHelper.h"
+#include "cmDocumentCompileDefinitions.h"
+#include "cmTest.h"
+#ifdef CMAKE_BUILD_WITH_CMAKE
+# include "cmVariableWatch.h"
+#endif
+#include "cmInstallGenerator.h"
+#include "cmTestGenerator.h"
+#include "cmDefinitions.h"
+#include "cmake.h"
+#include <stdlib.h> // required for atoi
+
+#include <cmsys/RegularExpression.hxx>
+
+#include <cmsys/auto_ptr.hxx>
+
+#include <stack>
+#include <ctype.h> // for isspace
+
+class cmMakefile::Internals
+{
+public:
+ std::stack<cmDefinitions, std::list<cmDefinitions> > VarStack;
+ std::stack<std::set<cmStdString> > VarInitStack;
+ std::stack<std::set<cmStdString> > VarUsageStack;
+};
+
+// default is not to be building executables
+cmMakefile::cmMakefile(): Internal(new Internals)
+{
+ 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);
+
+ // Initialize these first since AddDefaultDefinitions calls AddDefinition
+ this->WarnUnused = false;
+ this->CheckSystemVars = 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;
+}
+
+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;
+}
+
+//----------------------------------------------------------------------------
+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/.+-]+@)");
+
+ // Enter a policy level for this directory.
+ this->PushPolicy();
+
+ // Protect the directory-level policies.
+ this->PushPolicyBarrier();
+
+ // 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();
+}
+
+bool cmMakefile::NeedCacheCompatibility(int major, int minor)
+{
+ return this->GetCacheManager()->NeedCacheCompatibility(major, minor);
+}
+
+cmMakefile::~cmMakefile()
+{
+ 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++)
+ {
+ delete this->FinalPassCommands[i];
+ }
+ std::vector<cmFunctionBlocker*>::iterator pos;
+ for (pos = this->FunctionBlockers.begin();
+ pos != this->FunctionBlockers.end(); ++pos)
+ {
+ cmFunctionBlocker* b = *pos;
+ delete b;
+ }
+ 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
+{
+ 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";
+}
+
+void cmMakefile
+::PrintStringVector(const char* s,
+ const std::vector<std::pair<cmStdString, bool> >& v) 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";
+}
+
+
+// call print on all the classes in the makefile
+void cmMakefile::Print()
+{
+ // print the class lists
+ std::cout << "classes:\n";
+
+ 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
+}
+
+bool cmMakefile::CommandExists(const char* name) const
+{
+ return this->GetCMakeInstance()->CommandExists(name);
+}
+
+
+//----------------------------------------------------------------------------
+void cmMakefile::IssueMessage(cmake::MessageType t,
+ std::string const& text) const
+{
+ // Collect context information.
+ cmListFileBacktrace backtrace;
+ if(!this->CallStack.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);
+ }
+
+ // Issue the message.
+ this->GetCMakeInstance()->IssueMessage(t, text, backtrace);
+}
+
+//----------------------------------------------------------------------------
+bool cmMakefile::GetBacktrace(cmListFileBacktrace& backtrace) 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;
+}
+
+//----------------------------------------------------------------------------
+void cmMakefile::PrintCommandTrace(const cmListFileFunction& lff)
+{
+ cmOStringStream msg;
+ msg << lff.FilePath << "(" << lff.Line << "): ";
+ msg << lff.Name << "(";
+ for(std::vector<cmListFileArgument>::const_iterator i =
+ lff.Arguments.begin(); i != lff.Arguments.end(); ++i)
+ {
+ msg << i->Value;
+ msg << " ";
+ }
+ msg << ")";
+ cmSystemTools::Message(msg.str().c_str());
+}
+
+//----------------------------------------------------------------------------
+bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff,
+ cmExecutionStatus &status)
+{
+ bool result = true;
+
+ // quick return if blocked
+ if(this->IsFunctionBlocked(lff,status))
+ {
+ // No error.
+ return result;
+ }
+
+ std::string name = lff.Name;
+
+ // Place this call on the call stack.
+ cmMakefileCall stack_manager(this, lff, status);
+ static_cast<void>(stack_manager);
+
+ // Lookup the command prototype.
+ if(cmCommand* proto = this->GetCMakeInstance()->GetCommand(name.c_str()))
+ {
+ // Clone the prototype.
+ cmsys::auto_ptr<cmCommand> pcmd(proto->Clone());
+ pcmd->SetMakefile(this);
+
+ // Decide whether to invoke the command.
+ if(pcmd->GetEnabled() && !cmSystemTools::GetFatalErrorOccured() &&
+ (this->GetCMakeInstance()->GetWorkingMode() != cmake::SCRIPT_MODE
+ || pcmd->IsScriptable()))
+
+ {
+ // if trace is enabled, print out invoke information
+ if(this->GetCMakeInstance()->GetTrace())
+ {
+ this->PrintCommandTrace(lff);
+ }
+ // Try invoking the command.
+ if(!pcmd->InvokeInitialPass(lff.Arguments,status) ||
+ status.GetNestedError())
+ {
+ if(!status.GetNestedError())
+ {
+ // The command invocation requested that we report an error.
+ this->IssueMessage(cmake::FATAL_ERROR, pcmd->GetError());
+ }
+ result = false;
+ if ( this->GetCMakeInstance()->GetWorkingMode() != cmake::NORMAL_MODE)
+ {
+ cmSystemTools::SetFatalErrorOccured();
+ }
+ }
+ else if(pcmd->HasFinalPass())
+ {
+ // use the command
+ this->FinalPassCommands.push_back(pcmd.release());
+ }
+ }
+ else if ( this->GetCMakeInstance()->GetWorkingMode() == cmake::SCRIPT_MODE
+ && !pcmd->IsScriptable() )
+ {
+ std::string error = "Command ";
+ error += pcmd->GetName();
+ error += "() is not scriptable";
+ this->IssueMessage(cmake::FATAL_ERROR, error);
+ result = false;
+ cmSystemTools::SetFatalErrorOccured();
+ }
+ }
+ else
+ {
+ if(!cmSystemTools::GetFatalErrorOccured())
+ {
+ std::string error = "Unknown CMake command \"";
+ error += lff.Name;
+ error += "\".";
+ this->IssueMessage(cmake::FATAL_ERROR, error);
+ result = false;
+ cmSystemTools::SetFatalErrorOccured();
+ }
+ }
+
+ return result;
+}
+
+//----------------------------------------------------------------------------
+class cmMakefile::IncludeScope
+{
+public:
+ IncludeScope(cmMakefile* mf, const char* fname, bool noPolicyScope);
+ ~IncludeScope();
+ void Quiet() { this->ReportError = false; }
+private:
+ cmMakefile* Makefile;
+ const char* File;
+ bool NoPolicyScope;
+ bool CheckCMP0011;
+ bool ReportError;
+ void EnforceCMP0011();
+};
+
+//----------------------------------------------------------------------------
+cmMakefile::IncludeScope::IncludeScope(cmMakefile* mf, const char* fname,
+ bool noPolicyScope):
+ Makefile(mf), File(fname), NoPolicyScope(noPolicyScope),
+ CheckCMP0011(false), ReportError(true)
+{
+ if(!this->NoPolicyScope)
+ {
+ // Check CMP0011 to determine the policy scope type.
+ switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0011))
+ {
+ case cmPolicies::WARN:
+ // We need to push a scope to detect whether the script sets
+ // any policies that would affect the includer and therefore
+ // requires a warning. We use a weak scope to simulate OLD
+ // behavior by allowing policy changes to affect the includer.
+ this->Makefile->PushPolicy(true);
+ this->CheckCMP0011 = true;
+ break;
+ case cmPolicies::OLD:
+ // OLD behavior is to not push a scope at all.
+ this->NoPolicyScope = true;
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ // We should never make this policy required, but we handle it
+ // here just in case.
+ this->CheckCMP0011 = true;
+ case cmPolicies::NEW:
+ // NEW behavior is to push a (strong) scope.
+ this->Makefile->PushPolicy();
+ 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())
+ {
+ this->CheckCMP0011 = false;
+ }
+
+ // Pop the scope we pushed for the script.
+ this->Makefile->PopPolicy();
+
+ // We enforce the policy after the script's policy stack entry has
+ // been removed.
+ if(this->CheckCMP0011)
+ {
+ this->EnforceCMP0011();
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+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"
+ << "affects policy settings. "
+ << "CMake is implying the NO_POLICY_SCOPE option for compatibility, "
+ << "so the effects are applied to the including context.";
+ this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+ }
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ {
+ cmOStringStream e;
+ e << policies->GetRequiredPolicyError(cmPolicies::CMP0011) << "\n"
+ << "The included script\n " << this->File << "\n"
+ << "affects policy settings, so it requires this policy to be set.";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ }
+ break;
+ case cmPolicies::OLD:
+ case cmPolicies::NEW:
+ // The script set this policy. We assume the purpose of the
+ // script is to initialize policies for its includer, and since
+ // the policy is now set for later scripts, we do not warn.
+ break;
+ }
+}
+
+//----------------------------------------------------------------------------
+// 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)
+{
+ 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");
+
+ const char* external = 0;
+ std::string external_abs;
+
+ const char* filename = filename_in;
+ std::string filename_abs;
+
+ if (external_in)
+ {
+ 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();
+ }
+ }
+
+ // keep track of the current file being read
+ if (filename)
+ {
+ if(this->cmCurrentListFile != filename)
+ {
+ this->cmCurrentListFile = filename;
+ }
+ }
+
+ // Now read the input file
+ const char *filenametoread= filename;
+
+ if( external)
+ {
+ filenametoread= external;
+ }
+
+ 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");
+
+ // 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;
+ }
+ }
+
+ // push the listfile onto the stack
+ this->ListFileStack.push_back(filenametoread);
+ if(fullPath!=0)
+ {
+ *fullPath=filenametoread;
+ }
+ cmListFile cacheFile;
+ if( !cacheFile.ParseFile(filenametoread, requireProjectCommand, this) )
+ {
+ // 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;
+ }
+ // add this list file to the list of dependencies
+ this->ListFiles.push_back( filenametoread);
+
+ // Enforce balanced blocks (if/endif, function/endfunction, etc.).
+ {
+ LexicalPushPop lexScope(this);
+ IncludeScope incScope(this, filenametoread, noPolicyScope);
+
+ // Run the parsed commands.
+ const size_t numberFunctions = cacheFile.Functions.size();
+ for(size_t i =0; i < numberFunctions; ++i)
+ {
+ cmExecutionStatus status;
+ this->ExecuteCommand(cacheFile.Functions[i],status);
+ if(cmSystemTools::GetFatalErrorOccured())
+ {
+ // Exit early due to error.
+ lexScope.Quiet();
+ incScope.Quiet();
+ break;
+ }
+ if(status.GetReturnInvoked())
+ {
+ // Exit early due to return command.
+ break;
+ }
+ }
+ }
+
+ // If this is the directory-level CMakeLists.txt file then perform
+ // some extra checks.
+ if(this->ListFileStack.size() == 1)
+ {
+ this->EnforceDirectoryLevelRules();
+ }
+
+ 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");
+
+ // pop the listfile off the stack
+ this->ListFileStack.pop_back();
+
+ // Check for unused variables
+ this->CheckForUnusedVariables();
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+void cmMakefile::EnforceDirectoryLevelRules()
+{
+ // Diagnose a violation of CMP0000 if necessary.
+ if(this->CheckCMP0000)
+ {
+ cmOStringStream msg;
+ msg << "No cmake_minimum_required command is present. "
+ << "A line of code such as\n"
+ << " cmake_minimum_required(VERSION "
+ << cmVersion::GetMajorVersion() << "."
+ << cmVersion::GetMinorVersion()
+ << ")\n"
+ << "should be added at the top of the file. "
+ << "The version specified may be lower if you wish to "
+ << "support older CMake versions for this project. "
+ << "For more information run "
+ << "\"cmake --help-policy CMP0000\".";
+ switch (this->GetPolicyStatus(cmPolicies::CMP0000))
+ {
+ case cmPolicies::WARN:
+ // Warn because the user did not provide a mimimum required
+ // version.
+ this->IssueMessage(cmake::AUTHOR_WARNING, msg.str().c_str());
+ case cmPolicies::OLD:
+ // OLD behavior is to use policy version 2.4 set in
+ // cmListFileCache.
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::NEW:
+ // NEW behavior is to issue an error.
+ this->IssueMessage(cmake::FATAL_ERROR, msg.str().c_str());
+ cmSystemTools::SetFatalErrorOccured();
+ return;
+ }
+ }
+}
+
+void cmMakefile::AddCommand(cmCommand* wg)
+{
+ this->GetCMakeInstance()->AddCommand(wg);
+}
+
+// Set the make file
+void cmMakefile::SetLocalGenerator(cmLocalGenerator* lg)
+{
+ 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
+
+ this->WarnUnused = this->GetCMakeInstance()->GetWarnUnused();
+ this->CheckSystemVars = this->GetCMakeInstance()->GetCheckSystemVars();
+}
+
+bool cmMakefile::NeedBackwardsCompatibility(unsigned int major,
+ unsigned int minor,
+ unsigned int patch)
+{
+ if(this->LocalGenerator)
+ {
+ return
+ this->LocalGenerator->NeedBackwardsCompatibility(major, minor, patch);
+ }
+ else
+ {
+ return false;
+ }
+}
+
+void cmMakefile::FinalPass()
+{
+ // do all the variable expansions here
+ this->ExpandVariables();
+
+ // give all the commands a chance to do something
+ // after the file has been parsed before generation
+ for(std::vector<cmCommand*>::iterator i = this->FinalPassCommands.begin();
+ i != this->FinalPassCommands.end(); ++i)
+ {
+ (*i)->FinalPass();
+ }
+
+}
+
+// Generate the output file
+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();
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmMakefile::AddCustomCommandToTarget(const char* target,
+ const std::vector<std::string>& depends,
+ const cmCustomCommandLines& commandLines,
+ cmTarget::CustomCommandType type,
+ const char* comment,
+ const char* workingDir,
+ bool escapeOldStyle)
+{
+ // Find the target to which to add the custom command.
+ cmTargets::iterator ti = this->Targets.find(target);
+ if(ti != this->Targets.end())
+ {
+ if(ti->second.GetType() == cmTarget::OBJECT_LIBRARY)
+ {
+ 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;
+ }
+ // 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)
+ {
+ 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;
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+cmSourceFile*
+cmMakefile::AddCustomCommandToOutput(const std::vector<std::string>& outputs,
+ const std::vector<std::string>& depends,
+ const char* main_dependency,
+ const cmCustomCommandLines& commandLines,
+ const char* comment,
+ const char* workingDir,
+ bool replace,
+ bool escapeOldStyle)
+{
+ // Make sure there is at least one output.
+ if(outputs.empty())
+ {
+ cmSystemTools::Error("Attempt to add a custom rule with no output!");
+ return 0;
+ }
+
+ // Validate custom commands. TODO: More strict?
+ for(cmCustomCommandLines::const_iterator i=commandLines.begin();
+ i != commandLines.end(); ++i)
+ {
+ cmCustomCommandLine const& cl = *i;
+ if(!cl.empty() && !cl[0].empty() && cl[0][0] == '"')
+ {
+ cmOStringStream e;
+ e << "COMMAND may not contain literal quotes:\n " << cl[0] << "\n";
+ this->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return 0;
+ }
+ }
+
+ // Choose a source file on which to store the custom command.
+ cmSourceFile* file = 0;
+ if(main_dependency && main_dependency[0])
+ {
+ // The main dependency was specified. Use it unless a different
+ // custom command already used it.
+ file = this->GetSource(main_dependency);
+ if(file && file->GetCustomCommand() && !replace)
+ {
+ // The main dependency already has a custom command.
+ if(commandLines == file->GetCustomCommand()->GetCommandLines())
+ {
+ // The existing custom command is identical. Silently ignore
+ // the duplicate.
+ return file;
+ }
+ else
+ {
+ // The existing custom command is different. We need to
+ // generate a rule file for this new command.
+ file = 0;
+ }
+ }
+ else
+ {
+ // 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);
+ }
+ }
+
+ // Generate a rule file if the main dependency is not available.
+ if(!file)
+ {
+ cmGlobalGenerator* gg = this->LocalGenerator->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());
+ if(file && file->GetCustomCommand() && !replace)
+ {
+ // The rule file already exists.
+ if(commandLines != file->GetCustomCommand()->GetCommandLines())
+ {
+ cmSystemTools::Error("Attempt to add a custom rule to output \"",
+ outName.c_str(),
+ "\" which already has a custom rule.");
+ }
+ return file;
+ }
+
+ // Create a cmSourceFile for the rule file.
+ file = this->GetOrCreateSource(outName.c_str(), true);
+ file->SetProperty("__CMAKE_RULE", "1");
+ }
+
+ // Always create the output sources and mark them generated.
+ for(std::vector<std::string>::const_iterator o = outputs.begin();
+ o != outputs.end(); ++o)
+ {
+ if(cmSourceFile* out = this->GetOrCreateSource(o->c_str(), true))
+ {
+ out->SetProperty("GENERATED", "1");
+ }
+ }
+
+ // Construct a complete list of dependencies.
+ std::vector<std::string> depends2(depends);
+ if(main_dependency && main_dependency[0])
+ {
+ depends2.push_back(main_dependency);
+ }
+
+ // Attach the custom command to the file.
+ if(file)
+ {
+ cmCustomCommand* cc =
+ new cmCustomCommand(this, outputs, depends2, commandLines,
+ comment, workingDir);
+ cc->SetEscapeOldStyle(escapeOldStyle);
+ cc->SetEscapeAllowMakeVars(true);
+ file->SetCustomCommand(cc);
+ }
+ return file;
+}
+
+//----------------------------------------------------------------------------
+cmSourceFile*
+cmMakefile::AddCustomCommandToOutput(const char* output,
+ const std::vector<std::string>& depends,
+ const char* main_dependency,
+ const cmCustomCommandLines& commandLines,
+ const char* comment,
+ const char* workingDir,
+ bool replace,
+ bool escapeOldStyle)
+{
+ std::vector<std::string> outputs;
+ outputs.push_back(output);
+ return this->AddCustomCommandToOutput(outputs, depends, main_dependency,
+ commandLines, comment, workingDir,
+ replace, escapeOldStyle);
+}
+
+//----------------------------------------------------------------------------
+void
+cmMakefile::AddCustomCommandOldStyle(const char* target,
+ const std::vector<std::string>& outputs,
+ const std::vector<std::string>& depends,
+ const char* source,
+ const cmCustomCommandLines& commandLines,
+ const char* comment)
+{
+ // Translate the old-style signature to one of the new-style
+ // signatures.
+ if(strcmp(source, target) == 0)
+ {
+ // 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,
+ cmTarget::POST_BUILD, comment, 0);
+ return;
+ }
+
+ // Each output must get its own copy of this rule.
+ cmsys::RegularExpression sourceFiles("\\.(C|M|c|c\\+\\+|cc|cpp|cxx|m|mm|"
+ "rc|def|r|odl|idl|hpj|bat|h|h\\+\\+|"
+ "hm|hpp|hxx|in|txx|inl)$");
+ for(std::vector<std::string>::const_iterator oi = outputs.begin();
+ oi != outputs.end(); ++oi)
+ {
+ // Get the name of this output.
+ const char* output = oi->c_str();
+ cmSourceFile* sf;
+
+ // Choose whether to use a main dependency.
+ if(sourceFiles.find(source))
+ {
+ // The source looks like a real file. Use it as the main dependency.
+ sf = this->AddCustomCommandToOutput(output, depends, source,
+ commandLines, comment, 0);
+ }
+ else
+ {
+ // The source may not be a real file. Do not use a main dependency.
+ const char* no_main_dependency = 0;
+ std::vector<std::string> depends2 = depends;
+ depends2.push_back(source);
+ sf = this->AddCustomCommandToOutput(output, depends2, no_main_dependency,
+ commandLines, comment, 0);
+ }
+
+ // If the rule was added to the source (and not a .rule file),
+ // then add the source to the target to make sure the rule is
+ // included.
+ if(sf && !sf->GetPropertyAsBool("__CMAKE_RULE"))
+ {
+ if (this->Targets.find(target) != this->Targets.end())
+ {
+ this->Targets[target].AddSourceFile(sf);
+ }
+ else
+ {
+ cmSystemTools::Error("Attempt to add a custom rule to a target "
+ "that does not exist yet for target ", target);
+ return;
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+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)
+{
+ // Construct the command line for the custom command.
+ cmCustomCommandLine commandLine;
+ commandLine.push_back(command);
+ if(arg1)
+ {
+ commandLine.push_back(arg1);
+ }
+ if(arg2)
+ {
+ commandLine.push_back(arg2);
+ }
+ if(arg3)
+ {
+ commandLine.push_back(arg3);
+ }
+ if(arg4)
+ {
+ commandLine.push_back(arg4);
+ }
+ cmCustomCommandLines commandLines;
+ commandLines.push_back(commandLine);
+
+ // Call the real signature of this method.
+ this->AddUtilityCommand(utilityName, excludeFromAll, workingDirectory,
+ depends, commandLines);
+}
+
+//----------------------------------------------------------------------------
+cmTarget*
+cmMakefile::AddUtilityCommand(const char* utilityName,
+ bool excludeFromAll,
+ const char* workingDirectory,
+ const std::vector<std::string>& depends,
+ const cmCustomCommandLines& commandLines,
+ bool escapeOldStyle, const char* comment)
+{
+ // Create a target instance for this utility.
+ cmTarget* target = this->AddNewTarget(cmTarget::UTILITY, utilityName);
+ if (excludeFromAll)
+ {
+ target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
+ }
+ if(!comment)
+ {
+ // Use an empty comment to avoid generation of default comment.
+ comment = "";
+ }
+
+ // 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());
+ }
+ return target;
+}
+
+void cmMakefile::AddDefineFlag(const char* flag)
+{
+ if (!flag)
+ {
+ return;
+ }
+
+ // Update the string used for the old DEFINITIONS property.
+ this->AddDefineFlag(flag, this->DefineFlagsOrig);
+
+ // If this is really a definition, update COMPILE_DEFINITIONS.
+ if(this->ParseDefineFlag(flag, false))
+ {
+ return;
+ }
+
+ // Add this flag that does not look like a definition.
+ this->AddDefineFlag(flag, this->DefineFlags);
+}
+
+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;
+}
+
+
+void cmMakefile::RemoveDefineFlag(const char* flag)
+{
+ // Check the length of the flag to remove.
+ std::string::size_type len = strlen(flag);
+ if(len < 1)
+ {
+ return;
+ }
+
+ // Update the string used for the old DEFINITIONS property.
+ this->RemoveDefineFlag(flag, len, this->DefineFlagsOrig);
+
+ // If this is really a definition, update COMPILE_DEFINITIONS.
+ if(this->ParseDefineFlag(flag, true))
+ {
+ return;
+ }
+
+ // Remove this flag that does not look like a definition.
+ this->RemoveDefineFlag(flag, len, this->DefineFlags);
+}
+
+void cmMakefile::RemoveDefineFlag(const char* flag,
+ std::string::size_type len,
+ std::string& dflags)
+{
+ // Remove all instances of the flag that are surrounded by
+ // whitespace or the beginning/end of the string.
+ for(std::string::size_type lpos = dflags.find(flag, 0);
+ lpos != std::string::npos; lpos = dflags.find(flag, lpos))
+ {
+ std::string::size_type rpos = lpos + len;
+ if((lpos <= 0 || isspace(dflags[lpos-1])) &&
+ (rpos >= dflags.size() || isspace(dflags[rpos])))
+ {
+ dflags.erase(lpos, len);
+ }
+ else
+ {
+ ++lpos;
+ }
+ }
+}
+
+bool cmMakefile::ParseDefineFlag(std::string const& def, bool remove)
+{
+ // Create a regular expression to match valid definitions.
+ static cmsys::RegularExpression
+ valid("^[-/]D[A-Za-z_][A-Za-z0-9_]*(=.*)?$");
+
+ // Make sure the definition matches.
+ if(!valid.find(def.c_str()))
+ {
+ return false;
+ }
+
+ // VS6 IDE does not support definition values with spaces in
+ // combination with '"', '$', or ';'.
+ if((strcmp(this->LocalGenerator->GetGlobalGenerator()->GetName(),
+ "Visual Studio 6") == 0) &&
+ (def.find(" ") != def.npos && def.find_first_of("\"$;") != def.npos))
+ {
+ return false;
+ }
+
+ // Definitions with non-trivial values require a policy check.
+ static cmsys::RegularExpression
+ trivial("^[-/]D[A-Za-z_][A-Za-z0-9_]*(=[A-Za-z0-9_.]+)?$");
+ if(!trivial.find(def.c_str()))
+ {
+ // This definition has a non-trivial value.
+ switch(this->GetPolicyStatus(cmPolicies::CMP0005))
+ {
+ case cmPolicies::WARN:
+ this->IssueMessage(
+ cmake::AUTHOR_WARNING,
+ this->GetPolicies()->GetPolicyWarning(cmPolicies::CMP0005)
+ );
+ case cmPolicies::OLD:
+ // OLD behavior is to not escape the value. We should not
+ // convert the definition to use the property.
+ return false;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ this->IssueMessage(
+ cmake::FATAL_ERROR,
+ this->GetPolicies()->GetRequiredPolicyError(cmPolicies::CMP0005)
+ );
+ return false;
+ case cmPolicies::NEW:
+ // NEW behavior is to escape the value. Proceed to convert it
+ // to an entry in the property.
+ break;
+ }
+ }
+
+ // Get the definition part after the flag.
+ const char* define = def.c_str() + 2;
+
+ if(remove)
+ {
+ if(const char* cdefs = this->GetProperty("COMPILE_DEFINITIONS"))
+ {
+ // Expand the list.
+ std::vector<std::string> defs;
+ 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;
+ }
+ }
+
+ // Store the new list.
+ this->SetProperty("COMPILE_DEFINITIONS", ndefs.c_str());
+ }
+ }
+ else
+ {
+ // Append the definition to the directory property.
+ this->AppendProperty("COMPILE_DEFINITIONS", define);
+ }
+
+ return true;
+}
+
+void cmMakefile::AddLinkLibrary(const char* lib,
+ cmTarget::LinkLibraryType llt)
+{
+ cmTarget::LibraryID tmp;
+ tmp.first = lib;
+ tmp.second = llt;
+ this->LinkLibraries.push_back(tmp);
+}
+
+void cmMakefile::AddLinkLibraryForTarget(const char *target,
+ const char* lib,
+ cmTarget::LinkLibraryType llt)
+{
+ cmTargets::iterator i = this->Targets.find(target);
+ if ( i != this->Targets.end())
+ {
+ cmTarget* tgt =
+ this->GetCMakeInstance()->GetGlobalGenerator()->FindTarget(0,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) ||
+ tgt->IsExecutableWithExports()))
+ {
+ cmOStringStream e;
+ e << "Target \"" << lib << "\" of type "
+ << cmTarget::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());
+ }
+ }
+ }
+ i->second.AddLinkLibrary( *this, target, lib, llt );
+ }
+ else
+ {
+ cmOStringStream 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());
+ }
+}
+
+void cmMakefile::AddLinkDirectoryForTarget(const char *target,
+ const char* d)
+{
+ cmTargets::iterator i = this->Targets.find(target);
+ if ( i != this->Targets.end())
+ {
+ i->second.AddLinkDirectory( d );
+ }
+ else
+ {
+ cmSystemTools::Error
+ ("Attempt to add link directories to non-existant target: ",
+ target, " for directory ", d);
+ }
+}
+
+void cmMakefile::AddLinkLibrary(const char* lib)
+{
+ this->AddLinkLibrary(lib,cmTarget::GENERAL);
+}
+
+void cmMakefile::AddLinkDirectory(const char* dir)
+{
+ // 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);
+ }
+ }
+}
+
+void cmMakefile::InitializeFromParent()
+{
+ cmMakefile *parent = this->LocalGenerator->GetParent()->GetMakefile();
+
+ // Initialize definitions with the closure of the parent scope.
+ this->Internal->VarStack.top() = parent->Internal->VarStack.top().Closure();
+
+ // copy include paths
+ this->SetProperty("INCLUDE_DIRECTORIES",
+ parent->GetProperty("INCLUDE_DIRECTORIES"));
+ this->SystemIncludeDirectories = parent->SystemIncludeDirectories;
+
+ // define flags
+ this->DefineFlags = parent->DefineFlags;
+ this->DefineFlagsOrig = parent->DefineFlagsOrig;
+
+ // Include transform property. There is no per-config version.
+ {
+ const char* prop = "IMPLICIT_DEPENDS_INCLUDE_TRANSFORM";
+ this->SetProperty(prop, parent->GetProperty(prop));
+ }
+
+ // 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()));
+ }
+ }
+
+ // link libraries
+ this->LinkLibraries = parent->LinkLibraries;
+
+ // link directories
+ this->LinkDirectories = parent->LinkDirectories;
+
+ // the initial project name
+ this->ProjectName = parent->ProjectName;
+
+ // Copy include regular expressions.
+ this->IncludeFileRegularExpression = parent->IncludeFileRegularExpression;
+ this->ComplainFileRegularExpression = parent->ComplainFileRegularExpression;
+
+ // Imported targets.
+ this->ImportedTargets = parent->ImportedTargets;
+}
+
+void cmMakefile::ConfigureSubDirectory(cmLocalGenerator *lg2)
+{
+ // copy our variables from the child makefile
+ lg2->GetMakefile()->InitializeFromParent();
+ lg2->GetMakefile()->MakeStartDirectoriesCurrent();
+ if (this->GetCMakeInstance()->GetDebugOutput())
+ {
+ std::string msg=" Entering ";
+ msg += lg2->GetMakefile()->GetCurrentDirectory();
+ cmSystemTools::Message(msg.c_str());
+ }
+ // finally configure the subdir
+ lg2->Configure();
+ if (this->GetCMakeInstance()->GetDebugOutput())
+ {
+ std::string msg=" Returning to ";
+ msg += this->GetCurrentDirectory();
+ cmSystemTools::Message(msg.c_str());
+ }
+}
+
+void cmMakefile::AddSubDirectory(const char* sub,
+ bool excludeFromAll, bool preorder)
+{
+ // the source path must be made full if it isn't already
+ std::string srcPath = sub;
+ if (!cmSystemTools::FileIsFullPath(srcPath.c_str()))
+ {
+ srcPath = this->GetCurrentDirectory();
+ srcPath += "/";
+ srcPath += sub;
+ }
+
+ // binary path must be made full if it isn't already
+ std::string binPath = sub;
+ if (!cmSystemTools::FileIsFullPath(binPath.c_str()))
+ {
+ binPath = this->GetCurrentOutputDirectory();
+ binPath += "/";
+ binPath += sub;
+ }
+
+
+ this->AddSubDirectory(srcPath.c_str(), binPath.c_str(),
+ excludeFromAll, preorder, false);
+}
+
+
+void cmMakefile::AddSubDirectory(const char* srcPath, const char *binPath,
+ bool excludeFromAll, bool preorder,
+ bool immediate)
+{
+ // Make sure the binary directory is unique.
+ if(!this->EnforceUniqueDir(srcPath, 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);
+
+ // set the subdirs start dirs
+ lg2->GetMakefile()->SetStartDirectory(srcPath);
+ lg2->GetMakefile()->SetStartOutputDirectory(binPath);
+ if(excludeFromAll)
+ {
+ lg2->GetMakefile()->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
+ }
+ lg2->GetMakefile()->SetPreOrder(preorder);
+
+ if (immediate)
+ {
+ this->ConfigureSubDirectory(lg2);
+ }
+}
+
+//----------------------------------------------------------------------------
+void AddStringToProperty(cmProperty *prop, const char* name, const char* s,
+ bool before)
+{
+ if (!prop)
+ {
+ return;
+ }
+
+ // Don't worry about duplicates at this point. We eliminate them when
+ // we convert the property to a vector in GetIncludeDirectories.
+
+ if (before)
+ {
+ const char *val = prop->GetValue();
+ cmOStringStream oss;
+
+ if(val && *val)
+ {
+ oss << s << ";" << val;
+ }
+ else
+ {
+ oss << s;
+ }
+
+ std::string newVal = oss.str();
+ prop->Set(name, newVal.c_str());
+ }
+ else
+ {
+ prop->Append(name, s);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmMakefile::AddIncludeDirectory(const char* inc, bool before)
+{
+ if (!inc)
+ {
+ return;
+ }
+
+ // Directory property:
+ cmProperty *prop =
+ this->GetProperties().GetOrCreateProperty("INCLUDE_DIRECTORIES");
+ AddStringToProperty(prop, "INCLUDE_DIRECTORIES", inc, before);
+
+ // Property on each target:
+ for (cmTargets::iterator l = this->Targets.begin();
+ l != this->Targets.end(); ++l)
+ {
+ cmTarget &t = l->second;
+ prop = t.GetProperties().GetOrCreateProperty("INCLUDE_DIRECTORIES");
+ AddStringToProperty(prop, "INCLUDE_DIRECTORIES", inc, before);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmMakefile::AddSystemIncludeDirectory(const char* dir)
+{
+ this->SystemIncludeDirectories.insert(dir);
+}
+
+//----------------------------------------------------------------------------
+bool cmMakefile::IsSystemIncludeDirectory(const char* dir)
+{
+ return (this->SystemIncludeDirectories.find(dir) !=
+ this->SystemIncludeDirectories.end());
+}
+
+void cmMakefile::AddDefinition(const char* name, const char* value)
+{
+ if (!value )
+ {
+ return;
+ }
+
+#ifdef CMAKE_STRICT
+ if (this->GetCMakeInstance())
+ {
+ this->GetCMakeInstance()->
+ RecordPropertyAccess(name,cmProperty::VARIABLE);
+ }
+#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);
+
+#ifdef CMAKE_BUILD_WITH_CMAKE
+ cmVariableWatch* vv = this->GetVariableWatch();
+ if ( vv )
+ {
+ vv->VariableAccessed(name,
+ cmVariableWatch::VARIABLE_MODIFIED_ACCESS,
+ value,
+ this);
+ }
+#endif
+}
+
+
+void cmMakefile::AddCacheDefinition(const char* name, const char* value,
+ const char* doc,
+ cmCacheManager::CacheEntryType type,
+ bool force)
+{
+ const char* val = value;
+ cmCacheManager::CacheIterator it =
+ this->GetCacheManager()->GetCacheIterator(name);
+ if(!it.IsAtEnd() && (it.GetType() == cmCacheManager::UNINITIALIZED) &&
+ it.Initialized())
+ {
+ // 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();
+ }
+ if ( type == cmCacheManager::PATH || type == cmCacheManager::FILEPATH )
+ {
+ std::vector<std::string>::size_type cc;
+ std::vector<std::string> files;
+ std::string nvalue = "";
+ cmSystemTools::ExpandListArgument(val, files);
+ for ( cc = 0; cc < files.size(); cc ++ )
+ {
+ if(!cmSystemTools::IsOff(files[cc].c_str()))
+ {
+ files[cc] = cmSystemTools::CollapseFullPath(files[cc].c_str());
+ }
+ if ( cc > 0 )
+ {
+ nvalue += ";";
+ }
+ nvalue += files[cc];
+ }
+
+ this->GetCacheManager()->AddCacheEntry(name, nvalue.c_str(), doc, type);
+ val = it.GetValue();
+ }
+
+ }
+ this->GetCacheManager()->AddCacheEntry(name, val, doc, type);
+ // if there was a definition then remove it
+ this->Internal->VarStack.top().Set(name, 0);
+}
+
+
+void cmMakefile::AddDefinition(const char* name, bool value)
+{
+ this->Internal->VarStack.top().Set(name, value? "ON" : "OFF");
+ 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);
+#ifdef CMAKE_BUILD_WITH_CMAKE
+ cmVariableWatch* vv = this->GetVariableWatch();
+ if ( vv )
+ {
+ vv->VariableAccessed(name, cmVariableWatch::VARIABLE_MODIFIED_ACCESS,
+ value?"ON":"OFF", this);
+ }
+#endif
+}
+
+void cmMakefile::CheckForUnusedVariables() const
+{
+ if (!this->WarnUnused)
+ {
+ 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)
+ {
+ this->CheckForUnused("out of scope", it->c_str());
+ }
+}
+
+void cmMakefile::MarkVariableAsUsed(const char* 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;
+}
+
+bool cmMakefile::VariableUsed(const char* var) const
+{
+ if(this->Internal->VarUsageStack.top().find(var) !=
+ this->Internal->VarUsageStack.top().end())
+ {
+ return true;
+ }
+ return false;
+}
+
+void cmMakefile::CheckForUnused(const char* reason, const char* name) const
+{
+ if (this->WarnUnused && !this->VariableUsed(name))
+ {
+ cmStdString path;
+ cmListFileBacktrace bt;
+ if (this->CallStack.size())
+ {
+ const cmListFileContext* file = this->CallStack.back().Context;
+ bt.push_back(*file);
+ path = file->FilePath.c_str();
+ }
+ else
+ {
+ path = this->GetStartDirectory();
+ path += "/CMakeLists.txt";
+ cmListFileContext lfc;
+ lfc.FilePath = path;
+ lfc.Line = 0;
+ bt.push_back(lfc);
+ }
+ if (this->CheckSystemVars ||
+ cmSystemTools::IsSubDirectory(path.c_str(),
+ this->GetHomeDirectory()) ||
+ (cmSystemTools::IsSubDirectory(path.c_str(),
+ this->GetHomeOutputDirectory()) &&
+ !cmSystemTools::IsSubDirectory(path.c_str(),
+ cmake::GetCMakeFilesDirectory())))
+ {
+ cmOStringStream msg;
+ msg << "unused variable (" << reason << ") \'" << name << "\'";
+ this->GetCMakeInstance()->IssueMessage(cmake::AUTHOR_WARNING,
+ msg.str().c_str(),
+ bt);
+ }
+ }
+}
+
+void cmMakefile::RemoveDefinition(const char* name)
+{
+ this->Internal->VarStack.top().Set(name, 0);
+ if (this->Internal->VarUsageStack.size() &&
+ this->VariableInitialized(name))
+ {
+ this->CheckForUnused("unsetting", name);
+ this->Internal->VarUsageStack.top().erase(name);
+ }
+ this->Internal->VarInitStack.top().insert(name);
+#ifdef CMAKE_BUILD_WITH_CMAKE
+ cmVariableWatch* vv = this->GetVariableWatch();
+ if ( vv )
+ {
+ vv->VariableAccessed(name, cmVariableWatch::VARIABLE_REMOVED_ACCESS,
+ 0, this);
+ }
+#endif
+}
+
+void cmMakefile::RemoveCacheDefinition(const char* name)
+{
+ this->GetCacheManager()->RemoveCacheEntry(name);
+}
+
+void cmMakefile::SetProjectName(const char* p)
+{
+ this->ProjectName = p;
+}
+
+
+void cmMakefile::AddGlobalLinkInformation(const char* name, cmTarget& target)
+{
+ // for these targets do not add anything
+ switch(target.GetType())
+ {
+ case cmTarget::UTILITY:
+ case cmTarget::GLOBAL_TARGET:
+ return;
+ default:;
+ }
+ std::vector<std::string>::iterator j;
+ for(j = this->LinkDirectories.begin();
+ j != this->LinkDirectories.end(); ++j)
+ {
+ target.AddLinkDirectory(j->c_str());
+ }
+ target.MergeLinkLibraries( *this, name, this->LinkLibraries );
+}
+
+
+cmTarget* cmMakefile::AddLibrary(const char* lname, cmTarget::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))
+ {
+ this->IssueMessage(cmake::INTERNAL_ERROR,
+ "cmMakefile::AddLibrary given invalid target type.");
+ type = cmTarget::STATIC_LIBRARY;
+ }
+
+ cmTarget* target = this->AddNewTarget(type, lname);
+ // Clear its dependencies. Otherwise, dependencies might persist
+ // over changes in CMakeLists.txt, making the information stale and
+ // hence useless.
+ target->ClearDependencyInformation( *this, lname );
+ if(excludeFromAll)
+ {
+ target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
+ }
+ target->AddSources(srcs);
+ this->AddGlobalLinkInformation(lname, *target);
+ return target;
+}
+
+cmTarget* cmMakefile::AddExecutable(const char *exeName,
+ const std::vector<std::string> &srcs,
+ bool excludeFromAll)
+{
+ cmTarget* target = this->AddNewTarget(cmTarget::EXECUTABLE, exeName);
+ if(excludeFromAll)
+ {
+ target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
+ }
+ target->AddSources(srcs);
+ this->AddGlobalLinkInformation(exeName, *target);
+ return target;
+}
+
+//----------------------------------------------------------------------------
+cmTarget*
+cmMakefile::AddNewTarget(cmTarget::TargetType type, const char* 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);
+ return &it->second;
+}
+
+cmSourceFile *cmMakefile::GetSourceFileWithOutput(const char *cname)
+{
+ std::string name = cname;
+ std::string out;
+
+ // look through all the source files that have custom commands
+ // and see if the custom command has the passed source file as an output
+ for(std::vector<cmSourceFile*>::const_iterator i =
+ this->SourceFiles.begin(); i != this->SourceFiles.end(); ++i)
+ {
+ // does this source file have a custom command?
+ if ((*i)->GetCustomCommand())
+ {
+ // is the output of the custom command match the source files name
+ const std::vector<std::string>& outputs =
+ (*i)->GetCustomCommand()->GetOutputs();
+ for(std::vector<std::string>::const_iterator o = outputs.begin();
+ o != outputs.end(); ++o)
+ {
+ out = *o;
+ std::string::size_type pos = out.rfind(name);
+ // If the output matches exactly
+ if (pos != out.npos &&
+ pos == out.size() - name.size() &&
+ (pos ==0 || out[pos-1] == '/'))
+ {
+ return *i;
+ }
+ }
+ }
+ }
+
+ // otherwise return NULL
+ return 0;
+}
+
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+cmSourceGroup* cmMakefile::GetSourceGroup(const std::vector<std::string>&name)
+{
+ 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)
+
+ {
+ std::string sgName = sgIt->GetName();
+ if(sgName == name[0])
+ {
+ sg = &(*sgIt);
+ break;
+ }
+ }
+
+ if(sg != 0)
+ {
+ // 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());
+ if(sg == 0)
+ {
+ break;
+ }
+ }
+ }
+ return sg;
+}
+
+ void cmMakefile::AddSourceGroup(const char* name,
+ const char* regex)
+{
+ if (name)
+ {
+ std::vector<std::string> nameVector;
+ nameVector.push_back(name);
+ AddSourceGroup(nameVector, regex);
+ }
+}
+
+void cmMakefile::AddSourceGroup(const std::vector<std::string>& name,
+ const char* regex)
+{
+ cmSourceGroup* sg = 0;
+ std::vector<std::string> currentName;
+ int i = 0;
+ const int lastElement = static_cast<int>(name.size()-1);
+ for(i=lastElement; i>=0; --i)
+ {
+ currentName.assign(name.begin(), name.begin()+i+1);
+ sg = this->GetSourceGroup(currentName);
+ if(sg != 0)
+ {
+ break;
+ }
+ }
+
+ // i now contains the index of the last found component
+ if(i==lastElement)
+ {
+ // group already exists, replace its regular expression
+ if ( regex )
+ {
+ // We only want to set the regular expression. If there are already
+ // source files in the group, we don't want to remove them.
+ sg->SetGroupRegex(regex);
+ }
+ return;
+ }
+ else if(i==-1)
+ {
+ // group does not exists nor belong to any existing group
+ // add its first component
+ this->SourceGroups.push_back(cmSourceGroup(name[0].c_str(), regex));
+ 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))
+ {
+ std::string guidName = "SG_Filter_";
+ guidName += fullname;
+ gg->CreateGUID(guidName.c_str());
+ }
+ 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->SetGroupRegex(regex);
+}
+
+#endif
+
+void cmMakefile::AddExtraDirectory(const char* dir)
+{
+ this->AuxSourceDirectories.push_back(dir);
+}
+
+
+// expand CMAKE_BINARY_DIR and CMAKE_SOURCE_DIR in the
+// include and library directories.
+
+void cmMakefile::ExpandVariables()
+{
+ // Now expand variables in the include and link strings
+
+ // May not be necessary anymore... But may need a policy for strict
+ // backwards compatibility
+ const char *includeDirs = this->GetProperty("INCLUDE_DIRECTORIES");
+ if (includeDirs)
+ {
+ std::string dirs = includeDirs;
+ this->ExpandVariablesInString(dirs, true, true);
+ this->SetProperty("INCLUDE_DIRECTORIES", dirs.c_str());
+ }
+
+ // Also for each target's INCLUDE_DIRECTORIES property:
+ for (cmTargets::iterator l = this->Targets.begin();
+ l != this->Targets.end(); ++l)
+ {
+ cmTarget &t = l->second;
+ includeDirs = t.GetProperty("INCLUDE_DIRECTORIES");
+ if (includeDirs)
+ {
+ std::string dirs = includeDirs;
+ this->ExpandVariablesInString(dirs, true, true);
+ t.SetProperty("INCLUDE_DIRECTORIES", dirs.c_str());
+ }
+ }
+
+ for(std::vector<std::string>::iterator d = this->LinkDirectories.begin();
+ d != this->LinkDirectories.end(); ++d)
+ {
+ this->ExpandVariablesInString(*d, true, true);
+ }
+ for(cmTarget::LinkLibraryVectorType::iterator l =
+ this->LinkLibraries.begin();
+ l != this->LinkLibraries.end(); ++l)
+ {
+ this->ExpandVariablesInString(l->first, true, true);
+ }
+}
+
+bool cmMakefile::IsOn(const char* name) const
+{
+ const char* value = this->GetDefinition(name);
+ return cmSystemTools::IsOn(value);
+}
+
+bool cmMakefile::IsSet(const char* name) const
+{
+ const char* value = this->GetDefinition(name);
+ if ( !value )
+ {
+ return false;
+ }
+
+ if ( ! *value )
+ {
+ return false;
+ }
+
+ if ( cmSystemTools::IsNOTFOUND(value) )
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool cmMakefile::PlatformIs64Bit() const
+{
+ if(const char* sizeof_dptr = this->GetDefinition("CMAKE_SIZEOF_VOID_P"))
+ {
+ return atoi(sizeof_dptr) == 8;
+ }
+ return false;
+}
+
+const char* cmMakefile::GetSONameFlag(const char* language) const
+{
+ std::string name = "CMAKE_SHARED_LIBRARY_SONAME";
+ if(language)
+ {
+ name += "_";
+ name += language;
+ }
+ name += "_FLAG";
+ return GetDefinition(name.c_str());
+}
+
+bool cmMakefile::CanIWriteThisFile(const char* fileName)
+{
+ if ( !this->IsOn("CMAKE_DISABLE_SOURCE_CHANGES") )
+ {
+ return true;
+ }
+ // If we are doing an in-source build, than the test will always fail
+ if ( cmSystemTools::SameFile(this->GetHomeDirectory(),
+ this->GetHomeOutputDirectory()) )
+ {
+ if ( this->IsOn("CMAKE_DISABLE_IN_SOURCE_BUILD") )
+ {
+ return false;
+ }
+ return true;
+ }
+
+ // Check if this is subdirectory of the source tree but not a
+ // subdirectory of a build tree
+ if ( cmSystemTools::IsSubDirectory(fileName,
+ this->GetHomeDirectory()) &&
+ !cmSystemTools::IsSubDirectory(fileName,
+ this->GetHomeOutputDirectory()) )
+ {
+ return false;
+ }
+ return true;
+}
+
+const char* cmMakefile::GetRequiredDefinition(const char* name) const
+{
+ const char* ret = this->GetDefinition(name);
+ if(!ret)
+ {
+ cmSystemTools::Error("Error required internal CMake variable not "
+ "set, cmake may be not be built correctly.\n",
+ "Missing variable is:\n",
+ name);
+ return "";
+ }
+ return ret;
+}
+
+bool cmMakefile::IsDefinitionSet(const char* name) const
+{
+ const char* def = this->Internal->VarStack.top().Get(name);
+ this->Internal->VarUsageStack.top().insert(name);
+ if(!def)
+ {
+ def = this->GetCacheManager()->GetCacheValue(name);
+ }
+#ifdef CMAKE_BUILD_WITH_CMAKE
+ if(cmVariableWatch* vv = this->GetVariableWatch())
+ {
+ if(!def)
+ {
+ vv->VariableAccessed
+ (name, cmVariableWatch::UNKNOWN_VARIABLE_DEFINED_ACCESS,
+ def, this);
+ }
+ }
+#endif
+ return def?true:false;
+}
+
+const char* cmMakefile::GetDefinition(const char* 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);
+ if(!def)
+ {
+ def = this->GetCacheManager()->GetCacheValue(name);
+ }
+#ifdef CMAKE_BUILD_WITH_CMAKE
+ cmVariableWatch* vv = this->GetVariableWatch();
+ if ( vv )
+ {
+ if ( def )
+ {
+ vv->VariableAccessed(name, cmVariableWatch::VARIABLE_READ_ACCESS,
+ def, this);
+ }
+ else
+ {
+ // 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
+ {
+ vv->VariableAccessed(name,
+ cmVariableWatch::UNKNOWN_VARIABLE_READ_ACCESS, def, this);
+ }
+ }
+ }
+#endif
+ return def;
+}
+
+const char* cmMakefile::GetSafeDefinition(const char* def) const
+{
+ const char* ret = this->GetDefinition(def);
+ if(!ret)
+ {
+ return "";
+ }
+ return ret;
+}
+
+std::vector<std::string> cmMakefile
+::GetDefinitions(int cacheonly /* = 0 */) 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);
+ }
+ return res;
+}
+
+
+const char *cmMakefile::ExpandVariablesInString(std::string& source)
+{
+ return this->ExpandVariablesInString(source, false, false);
+}
+
+const char *cmMakefile::ExpandVariablesInString(std::string& source,
+ bool escapeQuotes,
+ bool noEscapes,
+ bool atOnly,
+ const char* filename,
+ long line,
+ bool removeEmpty,
+ bool replaceAt)
+{
+ if ( source.empty() || source.find_first_of("$@\\") == source.npos)
+ {
+ return source.c_str();
+ }
+
+ // Special-case the @ONLY mode.
+ if(atOnly)
+ {
+ if(!noEscapes || !removeEmpty || !replaceAt)
+ {
+ // 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.");
+ }
+
+ // Store an original copy of the input.
+ std::string input = source;
+
+ // Start with empty output.
+ source = "";
+
+ // Look for one @VAR@ at a time.
+ const char* in = input.c_str();
+ while(this->cmAtVarRegex.find(in))
+ {
+ // Get the range of the string to replace.
+ const char* first = in + this->cmAtVarRegex.start();
+ const char* last = in + this->cmAtVarRegex.end();
+
+ // Store the unchanged part of the string now.
+ source.append(in, first-in);
+
+ // Lookup the definition of VAR.
+ std::string var(first+1, last-first-2);
+ if(const char* val = this->GetDefinition(var.c_str()))
+ {
+ // Store the value in the output escaping as requested.
+ if(escapeQuotes)
+ {
+ source.append(cmSystemTools::EscapeQuotes(val));
+ }
+ else
+ {
+ source.append(val);
+ }
+ }
+
+ // Continue looking for @VAR@ further along the string.
+ in = last;
+ }
+
+ // Append the rest of the unchanged part of the string.
+ source.append(in);
+
+ return source.c_str();
+ }
+
+ // 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.
+
+ cmCommandArgumentParserHelper parser;
+ parser.SetMakefile(this);
+ parser.SetLineFile(line, filename);
+ parser.SetEscapeQuotes(escapeQuotes);
+ parser.SetNoEscapeMode(noEscapes);
+ parser.SetReplaceAtSyntax(replaceAt);
+ parser.SetRemoveEmpty(removeEmpty);
+ int res = parser.ParseString(source.c_str(), 0);
+ const char* emsg = parser.GetError();
+ if ( res && !emsg[0] )
+ {
+ source = parser.GetResult();
+ }
+ else
+ {
+ // Construct the main error message.
+ cmOStringStream error;
+ error << "Syntax error in cmake code ";
+ if(filename && line > 0)
+ {
+ // This filename and line number may be more specific than the
+ // command context because one command invocation can have
+ // arguments on multiple lines.
+ error << "at\n"
+ << " " << filename << ":" << line << "\n";
+ }
+ error << "when parsing string\n"
+ << " " << source.c_str() << "\n";
+ error << emsg;
+
+ // If the parser failed ("res" is false) then this is a real
+ // argument parsing error, so the policy applies. Otherwise the
+ // 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;
+ if(!res)
+ {
+ // This is a real argument parsing error. Use policy CMP0010 to
+ // decide whether it is an error.
+ switch(this->GetPolicyStatus(cmPolicies::CMP0010))
+ {
+ case cmPolicies::WARN:
+ error << "\n"
+ << (this->GetPolicies()
+ ->GetPolicyWarning(cmPolicies::CMP0010));
+ case cmPolicies::OLD:
+ // OLD behavior is to just warn and continue.
+ mtype = cmake::AUTHOR_WARNING;
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ error << "\n"
+ << (this->GetPolicies()
+ ->GetRequiredPolicyError(cmPolicies::CMP0010));
+ case cmPolicies::NEW:
+ // NEW behavior is to report the error.
+ cmSystemTools::SetFatalErrorOccured();
+ break;
+ }
+ }
+ this->IssueMessage(mtype, error.str());
+ }
+ return source.c_str();
+}
+
+void cmMakefile::RemoveVariablesInString(std::string& source,
+ bool atOnly) const
+{
+ if(!atOnly)
+ {
+ cmsys::RegularExpression var("(\\${[A-Za-z_0-9]*})");
+ while (var.find(source))
+ {
+ source.erase(var.start(),var.end() - var.start());
+ }
+ }
+
+ if(!atOnly)
+ {
+ cmsys::RegularExpression varb("(\\$ENV{[A-Za-z_0-9]*})");
+ while (varb.find(source))
+ {
+ source.erase(varb.start(),varb.end() - varb.start());
+ }
+ }
+ cmsys::RegularExpression var2("(@[A-Za-z_0-9]*@)");
+ while (var2.find(source))
+ {
+ source.erase(var2.start(),var2.end() - var2.start());
+ }
+}
+
+/**
+ * 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*
+cmMakefile::GetConfigurations(std::vector<std::string>& configs,
+ bool single) const
+{
+ if(this->LocalGenerator->GetGlobalGenerator()->IsMultiConfig())
+ {
+ if(const char* configTypes =
+ this->GetDefinition("CMAKE_CONFIGURATION_TYPES"))
+ {
+ cmSystemTools::ExpandListArgument(configTypes, configs);
+ }
+ return 0;
+ }
+ else
+ {
+ const char* buildType = this->GetDefinition("CMAKE_BUILD_TYPE");
+ if(single && buildType && *buildType)
+ {
+ configs.push_back(buildType);
+ }
+ return buildType;
+ }
+}
+
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+/**
+ * Find a source group whose regular expression matches the filename
+ * part of the given source name. Search backward through the list of
+ * source groups, and take the first matching group found. This way
+ * non-inherited SOURCE_GROUP commands will have precedence over
+ * inherited ones.
+ */
+cmSourceGroup&
+cmMakefile::FindSourceGroup(const char* source,
+ std::vector<cmSourceGroup> &groups)
+{
+ // First search for a group that lists the file explicitly.
+ for(std::vector<cmSourceGroup>::reverse_iterator sg = groups.rbegin();
+ sg != groups.rend(); ++sg)
+ {
+ cmSourceGroup *result = sg->MatchChildrenFiles(source);
+ if(result)
+ {
+ return *result;
+ }
+ }
+
+ // Now search for a group whose regex matches the file.
+ for(std::vector<cmSourceGroup>::reverse_iterator sg = groups.rbegin();
+ sg != groups.rend(); ++sg)
+ {
+ cmSourceGroup *result = sg->MatchChildrenRegex(source);
+ if(result)
+ {
+ return *result;
+ }
+ }
+
+
+ // Shouldn't get here, but just in case, return the default group.
+ return groups.front();
+}
+#endif
+
+bool cmMakefile::IsFunctionBlocked(const cmListFileFunction& lff,
+ cmExecutionStatus &status)
+{
+ // if there are no blockers get out of here
+ if (this->FunctionBlockers.begin() == this->FunctionBlockers.end())
+ {
+ return false;
+ }
+
+ // loop over all function blockers to see if any block this command
+ // evaluate in reverse, this is critical for balanced IF statements etc
+ std::vector<cmFunctionBlocker*>::reverse_iterator pos;
+ for (pos = this->FunctionBlockers.rbegin();
+ pos != this->FunctionBlockers.rend(); ++pos)
+ {
+ if((*pos)->IsFunctionBlocked(lff, *this, status))
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+//----------------------------------------------------------------------------
+void cmMakefile::PushFunctionBlockerBarrier()
+{
+ this->FunctionBlockerBarriers.push_back(this->FunctionBlockers.size());
+}
+
+//----------------------------------------------------------------------------
+void cmMakefile::PopFunctionBlockerBarrier(bool reportError)
+{
+ // Remove any extra entries pushed on the barrier.
+ FunctionBlockersType::size_type barrier =
+ this->FunctionBlockerBarriers.back();
+ while(this->FunctionBlockers.size() > barrier)
+ {
+ cmsys::auto_ptr<cmFunctionBlocker> fb(this->FunctionBlockers.back());
+ this->FunctionBlockers.pop_back();
+ if(reportError)
+ {
+ // Report the context in which the unclosed block was opened.
+ cmListFileContext const& lfc = fb->GetStartingContext();
+ cmOStringStream e;
+ e << "A logical block opening on the line\n"
+ << " " << lfc << "\n"
+ << "is not closed.";
+ this->IssueMessage(cmake::FATAL_ERROR, e.str());
+ reportError = false;
+ }
+ }
+
+ // Remove the barrier.
+ this->FunctionBlockerBarriers.pop_back();
+}
+
+bool cmMakefile::ExpandArguments(
+ std::vector<cmListFileArgument> const& inArgs,
+ std::vector<std::string>& outArgs)
+{
+ std::vector<cmListFileArgument>::const_iterator i;
+ std::string value;
+ outArgs.reserve(inArgs.size());
+ for(i = inArgs.begin(); i != inArgs.end(); ++i)
+ {
+ // Expand the variables in the argument.
+ value = i->Value;
+ this->ExpandVariablesInString(value, false, false, false,
+ i->FilePath, i->Line,
+ false, true);
+
+ // If the argument is quoted, it should be one argument.
+ // Otherwise, it may be a list of arguments.
+ if(i->Quoted)
+ {
+ outArgs.push_back(value);
+ }
+ else
+ {
+ cmSystemTools::ExpandListArgument(value, outArgs);
+ }
+ }
+ return !cmSystemTools::GetFatalErrorOccured();
+}
+
+//----------------------------------------------------------------------------
+void cmMakefile::AddFunctionBlocker(cmFunctionBlocker* fb)
+{
+ if(!this->CallStack.empty())
+ {
+ // Record the context in which the blocker is created.
+ fb->SetStartingContext(*(this->CallStack.back().Context));
+ }
+
+ this->FunctionBlockers.push_back(fb);
+}
+
+cmsys::auto_ptr<cmFunctionBlocker>
+cmMakefile::RemoveFunctionBlocker(cmFunctionBlocker* fb,
+ const cmListFileFunction& lff)
+{
+ // Find the function blocker stack barrier for the current scope.
+ // We only remove a blocker whose index is not less than the barrier.
+ FunctionBlockersType::size_type barrier = 0;
+ if(!this->FunctionBlockerBarriers.empty())
+ {
+ barrier = this->FunctionBlockerBarriers.back();
+ }
+
+ // Search for the function blocker whose scope this command ends.
+ for(FunctionBlockersType::size_type
+ i = this->FunctionBlockers.size(); i > barrier; --i)
+ {
+ std::vector<cmFunctionBlocker*>::iterator pos =
+ this->FunctionBlockers.begin() + (i - 1);
+ if (*pos == fb)
+ {
+ // Warn if the arguments do not match, but always remove.
+ if(!(*pos)->ShouldRemove(lff, *this))
+ {
+ cmListFileContext const& lfc = fb->GetStartingContext();
+ cmOStringStream e;
+ e << "A logical block opening on the line\n"
+ << " " << lfc << "\n"
+ << "closes on the line\n"
+ << " " << lff << "\n"
+ << "with mis-matching arguments.";
+ this->IssueMessage(cmake::AUTHOR_WARNING, e.str());
+ }
+ cmFunctionBlocker* b = *pos;
+ this->FunctionBlockers.erase(pos);
+ return cmsys::auto_ptr<cmFunctionBlocker>(b);
+ }
+ }
+
+ return cmsys::auto_ptr<cmFunctionBlocker>();
+}
+
+//----------------------------------------------------------------------------
+cmMakefile::LexicalPushPop::LexicalPushPop(cmMakefile* mf):
+ Makefile(mf), ReportError(true)
+{
+ this->Makefile->PushFunctionBlockerBarrier();
+}
+
+//----------------------------------------------------------------------------
+cmMakefile::LexicalPushPop::~LexicalPushPop()
+{
+ this->Makefile->PopFunctionBlockerBarrier(this->ReportError);
+}
+
+void cmMakefile::SetHomeDirectory(const char* dir)
+{
+ 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());
+ }
+}
+
+void cmMakefile::SetScriptModeFile(const char* scriptfile)
+{
+ this->AddDefinition("CMAKE_SCRIPT_MODE_FILE", scriptfile);
+}
+
+void cmMakefile::SetArgcArgv(const std::vector<std::string>& args)
+{
+ cmOStringStream 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;
+ tmpStream << "CMAKE_ARGV" << t;
+ this->AddDefinition(tmpStream.str().c_str(), args[t].c_str());
+ //this->MarkVariableAsUsed(tmpStream.str().c_str());
+ }
+}
+
+//----------------------------------------------------------------------------
+cmSourceFile* cmMakefile::GetSource(const char* sourceName)
+{
+ cmSourceFileLocation sfl(this, sourceName);
+ for(std::vector<cmSourceFile*>::const_iterator
+ sfi = this->SourceFiles.begin();
+ sfi != this->SourceFiles.end(); ++sfi)
+ {
+ cmSourceFile* sf = *sfi;
+ if(sf->Matches(sfl))
+ {
+ return sf;
+ }
+ }
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+cmSourceFile* cmMakefile::GetOrCreateSource(const char* sourceName,
+ bool generated)
+{
+ if(cmSourceFile* esf = this->GetSource(sourceName))
+ {
+ return esf;
+ }
+ else
+ {
+ cmSourceFile* sf = new cmSourceFile(this, sourceName);
+ if(generated)
+ {
+ sf->SetProperty("GENERATED", "1");
+ }
+ this->SourceFiles.push_back(sf);
+ return sf;
+ }
+}
+
+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);
+}
+
+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,
+ bool fast,
+ const std::vector<std::string> *cmakeArgs,
+ std::string *output)
+{
+ // does the binary directory exist ? If not create it...
+ if (!cmSystemTools::FileIsDirectory(bindir))
+ {
+ cmSystemTools::MakeDirectory(bindir);
+ }
+
+ // change to the tests directory and run cmake
+ // use the cmake object instead of calling cmake
+ std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
+ cmSystemTools::ChangeDirectory(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());
+ if (!gg)
+ {
+ cmSystemTools::Error(
+ "Internal CMake error, TryCompile bad GlobalGenerator");
+ // return to the original directory
+ cmSystemTools::ChangeDirectory(cwd.c_str());
+ return 1;
+ }
+ cm.SetGlobalGenerator(gg);
+
+ // do a configure
+ cm.SetHomeDirectory(srcdir);
+ cm.SetHomeOutputDirectory(bindir);
+ cm.SetStartDirectory(srcdir);
+ cm.SetStartOutputDirectory(bindir);
+ cm.SetCMakeCommand(cmakeCommand.c_str());
+ cm.LoadCache();
+ if(!gg->IsMultiConfig())
+ {
+ if(const char* config =
+ this->GetDefinition("CMAKE_TRY_COMPILE_CONFIGURATION"))
+ {
+ // Tell the single-configuration generator which one to use.
+ // 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);
+ }
+ }
+ // if cmake args were provided then pass them in
+ if (cmakeArgs)
+ {
+ // FIXME: Workaround to ignore unused CLI variables in try-compile.
+ //
+ // Ideally we should use SetArgs to honor options like --warn-unused-vars.
+ // However, there is a subtle problem when certain arguments are passed to
+ // a macro wrapping around try_compile or try_run that does not escape
+ // semicolons in its parameters but just passes ${ARGV} or ${ARGN}. In
+ // this case a list argument like "-DVAR=a;b" gets split into multiple
+ // cmake arguments "-DVAR=a" and "b". Currently SetCacheArgs ignores
+ // argument "b" and uses just "-DVAR=a", leading to a subtle bug in that
+ // the try_compile or try_run does not get the proper value of VAR. If we
+ // call SetArgs here then it would treat "b" as the source directory and
+ // cause an error such as "The source directory .../CMakeFiles/CMakeTmp/b
+ // does not exist", thus breaking the try_compile or try_run completely.
+ //
+ // Strictly speaking the bug is in the wrapper macro because the CMake
+ // language has always flattened nested lists and the macro should escape
+ // the semicolons in its arguments before forwarding them. However, this
+ // bug is so subtle that projects typically work anyway, usually because
+ // the value VAR=a is sufficient for the try_compile or try_run to get the
+ // correct result. Calling SetArgs here would break such projects that
+ // previously built. Instead we work around the issue by never reporting
+ // unused arguments and ignoring options such as --warn-unused-vars.
+ cm.SetWarnUnusedCli(false);
+ //cm.SetArgs(*cmakeArgs, true);
+
+ cm.SetCacheArgs(*cmakeArgs);
+ }
+ // to save time we pass the EnableLanguage info directly
+ gg->EnableLanguagesFromGenerator
+ (this->LocalGenerator->GetGlobalGenerator(), this);
+ if(this->IsOn("CMAKE_SUPPRESS_DEVELOPER_WARNINGS"))
+ {
+ cm.AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_WARNINGS",
+ "TRUE", "", cmCacheManager::INTERNAL);
+ }
+ else
+ {
+ cm.AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_WARNINGS",
+ "FALSE", "", cmCacheManager::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());
+ return 1;
+ }
+
+ if (cm.Generate() != 0)
+ {
+ cmSystemTools::Error(
+ "Internal CMake error, TryCompile generation of cmake failed");
+ // return to the original directory
+ cmSystemTools::ChangeDirectory(cwd.c_str());
+ 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());
+ return ret;
+}
+
+cmake *cmMakefile::GetCMakeInstance() const
+{
+ if ( this->LocalGenerator && this->LocalGenerator->GetGlobalGenerator() )
+ {
+ return this->LocalGenerator->GetGlobalGenerator()->GetCMakeInstance();
+ }
+ return 0;
+}
+
+#ifdef CMAKE_BUILD_WITH_CMAKE
+cmVariableWatch *cmMakefile::GetVariableWatch() const
+{
+ if ( this->GetCMakeInstance() &&
+ this->GetCMakeInstance()->GetVariableWatch() )
+ {
+ return this->GetCMakeInstance()->GetVariableWatch();
+ }
+ return 0;
+}
+#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
+{
+ return this->GetCMakeInstance()->GetCacheManager();
+}
+
+void cmMakefile::DisplayStatus(const char* message, float s)
+{
+ cmake* cm = this->GetLocalGenerator()->GetGlobalGenerator()
+ ->GetCMakeInstance();
+ if (cm->GetWorkingMode() == cmake::FIND_PACKAGE_MODE)
+ {
+ // don't output any STATUS message in FIND_PACKAGE_MODE, since they will
+ // directly be fed to the compiler, which will be confused.
+ return;
+ }
+ cm->UpdateProgress(message, s);
+}
+
+std::string cmMakefile::GetModulesFile(const char* filename)
+{
+ std::string result;
+
+ // We search the module always in CMAKE_ROOT and in CMAKE_MODULE_PATH,
+ // and then decide based on the policy setting which one to return.
+ // See CMP0017 for more details.
+ // The specific problem was that KDE 4.5.0 installs a
+ // FindPackageHandleStandardArgs.cmake which doesn't have the new features
+ // of FPHSA.cmake introduced in CMake 2.8.3 yet, and by setting
+ // CMAKE_MODULE_PATH also e.g. FindZLIB.cmake from cmake included
+ // FPHSA.cmake from kdelibs and not from CMake, and tried to use the
+ // new features, which were not there in the version from kdelibs, and so
+ // failed ("
+ std::string moduleInCMakeRoot;
+ std::string moduleInCMakeModulePath;
+
+ // Always search in CMAKE_MODULE_PATH:
+ const char* cmakeModulePath = this->GetDefinition("CMAKE_MODULE_PATH");
+ if(cmakeModulePath)
+ {
+ std::vector<std::string> modulePath;
+ cmSystemTools::ExpandListArgument(cmakeModulePath, modulePath);
+
+ //Look through the possible module directories.
+ for(std::vector<std::string>::iterator i = modulePath.begin();
+ i != modulePath.end(); ++i)
+ {
+ std::string itempl = *i;
+ cmSystemTools::ConvertToUnixSlashes(itempl);
+ itempl += "/";
+ itempl += filename;
+ if(cmSystemTools::FileExists(itempl.c_str()))
+ {
+ moduleInCMakeModulePath = itempl;
+ break;
+ }
+ }
+ }
+
+ // Always search in the standard modules location.
+ const char* cmakeRoot = this->GetDefinition("CMAKE_ROOT");
+ if(cmakeRoot)
+ {
+ moduleInCMakeRoot = cmakeRoot;
+ moduleInCMakeRoot += "/Modules/";
+ moduleInCMakeRoot += filename;
+ cmSystemTools::ConvertToUnixSlashes(moduleInCMakeRoot);
+ if(!cmSystemTools::FileExists(moduleInCMakeRoot.c_str()))
+ {
+ moduleInCMakeRoot = "";
+ }
+ }
+
+ // Normally, prefer the files found in CMAKE_MODULE_PATH. Only when the file
+ // 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)
+ {
+ result = moduleInCMakeRoot;
+ }
+
+ if ((moduleInCMakeModulePath.size()>0) && (moduleInCMakeRoot.size()>0))
+ {
+ const char* currentFile = this->GetDefinition("CMAKE_CURRENT_LIST_FILE");
+ if (currentFile && (strstr(currentFile, cmakeRoot) == currentFile))
+ {
+ switch (this->GetPolicyStatus(cmPolicies::CMP0017))
+ {
+ case cmPolicies::WARN:
+ {
+ cmOStringStream 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);
+
+ this->IssueMessage(cmake::AUTHOR_WARNING, e.str());
+ // break; // fall through to OLD behaviour
+ }
+ case cmPolicies::OLD:
+ result = moduleInCMakeModulePath;
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::NEW:
+ default:
+ result = moduleInCMakeRoot;
+ break;
+ }
+ }
+ }
+
+ return result;
+}
+
+void cmMakefile::ConfigureString(const std::string& input,
+ std::string& output, bool atOnly,
+ bool escapeQuotes)
+{
+ // Split input to handle one line at a time.
+ std::string::const_iterator lineStart = input.begin();
+ while(lineStart != input.end())
+ {
+ // Find the end of this line.
+ std::string::const_iterator lineEnd = lineStart;
+ while(lineEnd != input.end() && *lineEnd != '\n')
+ {
+ ++lineEnd;
+ }
+
+ // Copy the line.
+ std::string line(lineStart, lineEnd);
+
+ // Skip the newline character.
+ bool haveNewline = (lineEnd != input.end());
+ if(haveNewline)
+ {
+ ++lineEnd;
+ }
+
+ // Replace #cmakedefine instances.
+ if(this->cmDefineRegex.find(line))
+ {
+ const char* def =
+ this->GetDefinition(this->cmDefineRegex.match(1).c_str());
+ if(!cmSystemTools::IsOff(def))
+ {
+ cmSystemTools::ReplaceString(line, "#cmakedefine", "#define");
+ output += line;
+ }
+ else
+ {
+ output += "/* #undef ";
+ output += this->cmDefineRegex.match(1);
+ output += " */";
+ }
+ }
+ else if(this->cmDefine01Regex.find(line))
+ {
+ const char* def =
+ this->GetDefinition(this->cmDefine01Regex.match(1).c_str());
+ cmSystemTools::ReplaceString(line, "#cmakedefine01", "#define");
+ output += line;
+ if(!cmSystemTools::IsOff(def))
+ {
+ output += " 1";
+ }
+ else
+ {
+ output += " 0";
+ }
+ }
+ else
+ {
+ output += line;
+ }
+
+ if(haveNewline)
+ {
+ output += "\n";
+ }
+
+ // Move to the next line.
+ lineStart = lineEnd;
+ }
+
+ // Perform variable replacements.
+ this->ExpandVariablesInString(output, escapeQuotes, true,
+ atOnly, 0, -1, true);
+}
+
+int cmMakefile::ConfigureFile(const char* infile, const char* outfile,
+ bool copyonly, bool atOnly, bool escapeQuotes,
+ const cmNewLineStyle& newLine)
+{
+ int res = 1;
+ if ( !this->CanIWriteThisFile(outfile) )
+ {
+ cmSystemTools::Error("Attempt to write file: ",
+ outfile, " into a source directory.");
+ return 0;
+ }
+ if ( !cmSystemTools::FileExists(infile) )
+ {
+ cmSystemTools::Error("File ", infile, " does not exist.");
+ return 0;
+ }
+ std::string soutfile = outfile;
+ std::string sinfile = infile;
+ this->AddCMakeDependFile(infile);
+ cmSystemTools::ConvertToUnixSlashes(soutfile);
+ mode_t perm = 0;
+ cmSystemTools::GetPermissions(sinfile.c_str(), perm);
+ std::string::size_type pos = soutfile.rfind('/');
+ if(pos != std::string::npos)
+ {
+ std::string path = soutfile.substr(0, pos);
+ cmSystemTools::MakeDirectory(path.c_str());
+ }
+
+ if(copyonly)
+ {
+ if ( !cmSystemTools::CopyFileIfDifferent(sinfile.c_str(),
+ soutfile.c_str()))
+ {
+ return 0;
+ }
+ }
+ else
+ {
+ std::string newLineCharacters;
+ std::ios_base::openmode omode = std::ios_base::out | std::ios_base::trunc;
+ if (newLine.IsValid())
+ {
+ newLineCharacters = newLine.GetCharacters();
+ omode |= std::ios::binary;
+ }
+ else
+ {
+ newLineCharacters = "\n";
+ }
+ std::string tempOutputFile = soutfile;
+ tempOutputFile += ".tmp";
+ std::ofstream fout(tempOutputFile.c_str(), omode);
+ if(!fout)
+ {
+ cmSystemTools::Error(
+ "Could not open file for write in copy operation ",
+ tempOutputFile.c_str());
+ cmSystemTools::ReportLastSystemError("");
+ return 0;
+ }
+ std::ifstream fin(sinfile.c_str());
+ if(!fin)
+ {
+ cmSystemTools::Error("Could not open file for read in copy operation ",
+ sinfile.c_str());
+ return 0;
+ }
+
+ // now copy input to output and expand variables in the
+ // input file at the same time
+ std::string inLine;
+ std::string outLine;
+ while( cmSystemTools::GetLineFromStream(fin, inLine) )
+ {
+ outLine = "";
+ this->ConfigureString(inLine, outLine, atOnly, escapeQuotes);
+ fout << outLine.c_str() << newLineCharacters;
+ }
+ // close the files before attempting to copy
+ fin.close();
+ fout.close();
+ if ( !cmSystemTools::CopyFileIfDifferent(tempOutputFile.c_str(),
+ soutfile.c_str()) )
+ {
+ res = 0;
+ }
+ else
+ {
+ cmSystemTools::SetPermissions(soutfile.c_str(), perm);
+ }
+ cmSystemTools::RemoveFile(tempOutputFile.c_str());
+ }
+ return res;
+}
+
+void cmMakefile::SetProperty(const char* 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_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);
+}
+
+void cmMakefile::AppendProperty(const char* prop, const char* value,
+ bool asString)
+{
+ if (!prop)
+ {
+ return;
+ }
+
+ // handle special props
+ std::string propname = prop;
+
+ 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);
+}
+
+const char *cmMakefile::GetPropertyOrDefinition(const char* prop)
+{
+ const char *ret = this->GetProperty(prop, cmProperty::DIRECTORY);
+ if (!ret)
+ {
+ ret = this->GetDefinition(prop);
+ }
+ return ret;
+}
+
+const char *cmMakefile::GetProperty(const char* prop)
+{
+ return this->GetProperty(prop, cmProperty::DIRECTORY);
+}
+
+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();
+ }
+
+ 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)
+{
+ return cmSystemTools::IsOn(this->GetProperty(prop));
+}
+
+//----------------------------------------------------------------------------
+const char* cmMakefile::GetFeature(const char* feature, const char* config)
+{
+ // 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;
+}
+
+cmTarget* cmMakefile::FindTarget(const char* name)
+{
+ cmTargets& tgts = this->GetTargets();
+
+ cmTargets::iterator i = tgts.find ( name );
+ if ( i != tgts.end() )
+ {
+ return &i->second;
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+cmTest* cmMakefile::CreateTest(const char* testName)
+{
+ if ( !testName )
+ {
+ return 0;
+ }
+ cmTest* test = this->GetTest(testName);
+ if ( test )
+ {
+ return test;
+ }
+ test = new cmTest(this);
+ test->SetName(testName);
+ this->Tests[testName] = test;
+ return test;
+}
+
+//----------------------------------------------------------------------------
+cmTest* cmMakefile::GetTest(const char* testName) const
+{
+ if(testName)
+ {
+ std::map<cmStdString, cmTest*>::const_iterator
+ mi = this->Tests.find(testName);
+ if(mi != this->Tests.end())
+ {
+ return mi->second;
+ }
+ }
+ return 0;
+}
+
+std::string cmMakefile::GetListFileStack()
+{
+ cmOStringStream tmp;
+ size_t depth = this->ListFileStack.size();
+ if (depth > 0)
+ {
+ std::deque<cmStdString>::iterator it = this->ListFileStack.end();
+ do
+ {
+ if (depth != this->ListFileStack.size())
+ {
+ tmp << "\n ";
+ }
+ --it;
+ tmp << "[";
+ tmp << depth;
+ tmp << "]\t";
+ tmp << *it;
+ depth--;
+ }
+ while (it != this->ListFileStack.begin());
+ }
+ return tmp.str();
+}
+
+
+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);
+}
+
+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);
+ }
+}
+
+void cmMakefile::RaiseScope(const char *var, const char *varDef)
+{
+ if (!var || !strlen(var))
+ {
+ return;
+ }
+
+ cmDefinitions& cur = this->Internal->VarStack.top();
+ if(cmDefinitions* up = cur.GetParent())
+ {
+ // 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;
+ 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
+ ("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);
+}
+
+//----------------------------------------------------------------------------
+cmTarget*
+cmMakefile::AddImportedTarget(const char* name, cmTarget::TargetType type,
+ bool global)
+{
+ // Create the target.
+ cmsys::auto_ptr<cmTarget> target(new cmTarget);
+ target->SetType(type, name);
+ 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());
+ }
+
+ // Transfer ownership to this cmMakefile object.
+ this->ImportedTargetsOwned.push_back(target.get());
+ return target.release();
+}
+
+//----------------------------------------------------------------------------
+cmTarget* cmMakefile::FindTargetToUse(const char* name)
+{
+ // 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
+ imported = this->ImportedTargets.find(name);
+ if(imported != this->ImportedTargets.end())
+ {
+ return imported->second;
+ }
+
+ // Look for a target built in this directory.
+ if(cmTarget* t = this->FindTarget(name))
+ {
+ return t;
+ }
+
+ // Look for a target built in this project.
+ return this->LocalGenerator->GetGlobalGenerator()->FindTarget(0, name);
+}
+
+//----------------------------------------------------------------------------
+bool cmMakefile::EnforceUniqueName(std::string const& name, std::string& msg,
+ bool isCustom)
+{
+ if(cmTarget* existing = this->FindTargetToUse(name.c_str()))
+ {
+ // The name given conflicts with an existing target. Produce an
+ // error in a compatible way.
+ if(existing->IsImported())
+ {
+ // Imported targets were not supported in previous versions.
+ // This is new code, so we can make it an error.
+ cmOStringStream e;
+ e << "cannot create target \"" << name
+ << "\" because an imported target with the same name already exists.";
+ msg = e.str();
+ return false;
+ }
+ else
+ {
+ // target names must be globally unique
+ switch (this->GetPolicyStatus(cmPolicies::CMP0002))
+ {
+ case cmPolicies::WARN:
+ this->IssueMessage(cmake::AUTHOR_WARNING, this->GetPolicies()->
+ 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)
+ );
+ return true;
+ case cmPolicies::NEW:
+ break;
+ }
+
+ // 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 &&
+ this != existing->GetMakefile() &&
+ cm->GetPropertyAsBool("ALLOW_DUPLICATE_CUSTOM_TARGETS"))
+ {
+ return true;
+ }
+
+ // Produce an error that tells the user how to work around the
+ // problem.
+ cmOStringStream 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:
+ e << "an executable ";
+ break;
+ case cmTarget::STATIC_LIBRARY:
+ e << "a static library ";
+ break;
+ case cmTarget::SHARED_LIBRARY:
+ e << "a shared library ";
+ break;
+ case cmTarget::MODULE_LIBRARY:
+ e << "a module library ";
+ break;
+ case cmTarget::UTILITY:
+ e << "a custom target ";
+ break;
+ default: break;
+ }
+ e << "created in source directory \""
+ << existing->GetMakefile()->GetCurrentDirectory() << "\". "
+ << "See documentation for policy CMP0002 for more details.";
+ msg = e.str();
+ return false;
+ }
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmMakefile::EnforceUniqueDir(const char* srcPath, const char* binPath)
+{
+ // Make sure the binary directory is unique.
+ cmGlobalGenerator* gg = this->LocalGenerator->GetGlobalGenerator();
+ if(gg->BinaryDirectoryIsNew(binPath))
+ {
+ return true;
+ }
+ cmOStringStream e;
+ switch (this->GetPolicyStatus(cmPolicies::CMP0013))
+ {
+ case cmPolicies::WARN:
+ // Print the warning.
+ e << this->GetPolicies()->GetPolicyWarning(cmPolicies::CMP0013)
+ << "\n"
+ << "The binary directory\n"
+ << " " << binPath << "\n"
+ << "is already used to build a source directory. "
+ << "This command uses it to build source directory\n"
+ << " " << srcPath << "\n"
+ << "which can generate conflicting build files. "
+ << "CMake does not support this use case but it used "
+ << "to work accidentally and is being allowed for "
+ << "compatibility.";
+ this->IssueMessage(cmake::AUTHOR_WARNING, e.str());
+ case cmPolicies::OLD:
+ // OLD behavior does not warn.
+ return true;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ e << this->GetPolicies()->GetRequiredPolicyError(cmPolicies::CMP0013)
+ << "\n";
+ case cmPolicies::NEW:
+ // NEW behavior prints the error.
+ e << "The binary directory\n"
+ << " " << binPath << "\n"
+ << "is already used to build a source directory. "
+ << "It cannot be used to build source directory\n"
+ << " " << srcPath << "\n"
+ << "Specify a unique binary directory name.";
+ this->IssueMessage(cmake::FATAL_ERROR, e.str());
+ break;
+ }
+
+ return false;
+}
+
+//----------------------------------------------------------------------------
+cmPolicies::PolicyStatus
+cmMakefile::GetPolicyStatus(cmPolicies::PolicyID id)
+{
+ // Get the current setting of the policy.
+ cmPolicies::PolicyStatus cur = this->GetPolicyStatusInternal(id);
+
+ // 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)
+ {
+ if(cur == cmPolicies::REQUIRED_ALWAYS ||
+ cur == cmPolicies::REQUIRED_IF_USED)
+ {
+ return cur;
+ }
+ cmPolicies::PolicyStatus def = this->GetPolicies()->GetPolicyStatus(id);
+ if(def == cmPolicies::REQUIRED_ALWAYS ||
+ def == cmPolicies::REQUIRED_IF_USED)
+ {
+ return def;
+ }
+ }
+
+ // The current setting is okay.
+ return cur;
+}
+
+//----------------------------------------------------------------------------
+cmPolicies::PolicyStatus
+cmMakefile::GetPolicyStatusInternal(cmPolicies::PolicyID id)
+{
+ // Is the policy set in our stack?
+ for(PolicyStackType::reverse_iterator psi = this->PolicyStack.rbegin();
+ psi != this->PolicyStack.rend(); ++psi)
+ {
+ PolicyStackEntry::const_iterator pse = psi->find(id);
+ if(pse != psi->end())
+ {
+ return pse->second;
+ }
+ }
+
+ // 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);
+}
+
+bool cmMakefile::SetPolicy(const char *id,
+ cmPolicies::PolicyStatus status)
+{
+ cmPolicies::PolicyID pid;
+ if (!this->GetPolicies()->GetPolicyID(id, /* out */ pid))
+ {
+ cmOStringStream e;
+ e << "Policy \"" << id << "\" is not known to this version of CMake.";
+ this->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+ }
+ return this->SetPolicy(pid,status);
+}
+
+//----------------------------------------------------------------------------
+bool cmMakefile::SetPolicy(cmPolicies::PolicyID id,
+ cmPolicies::PolicyStatus status)
+{
+ // A REQUIRED_ALWAYS policy may be set only to NEW.
+ if(status != cmPolicies::NEW &&
+ this->GetPolicies()->GetPolicyStatus(id) ==
+ cmPolicies::REQUIRED_ALWAYS)
+ {
+ std::string msg =
+ this->GetPolicies()->GetRequiredAlwaysPolicyError(id);
+ this->IssueMessage(cmake::FATAL_ERROR, msg.c_str());
+ 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);
+ }
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+cmMakefile::PolicyPushPop::PolicyPushPop(cmMakefile* m, bool weak,
+ cmPolicies::PolicyMap const& pm):
+ Makefile(m), ReportError(true)
+{
+ this->Makefile->PushPolicy(weak, pm);
+ this->Makefile->PushPolicyBarrier();
+}
+
+//----------------------------------------------------------------------------
+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));
+}
+
+//----------------------------------------------------------------------------
+void cmMakefile::PopPolicy()
+{
+ if(this->PolicyStack.size() > this->PolicyBarriers.back())
+ {
+ this->PolicyStack.pop_back();
+ }
+ else
+ {
+ this->IssueMessage(cmake::FATAL_ERROR,
+ "cmake_policy POP without matching PUSH");
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmMakefile::PushPolicyBarrier()
+{
+ this->PolicyBarriers.push_back(this->PolicyStack.size());
+}
+
+//----------------------------------------------------------------------------
+void cmMakefile::PopPolicyBarrier(bool reportError)
+{
+ // Remove any extra entries pushed on the barrier.
+ PolicyStackType::size_type barrier = this->PolicyBarriers.back();
+ while(this->PolicyStack.size() > barrier)
+ {
+ if(reportError)
+ {
+ this->IssueMessage(cmake::FATAL_ERROR,
+ "cmake_policy PUSH without matching POP");
+ reportError = false;
+ }
+ this->PopPolicy();
+ }
+
+ // Remove the barrier.
+ this->PolicyBarriers.pop_back();
+}
+
+bool cmMakefile::SetPolicyVersion(const char *version)
+{
+ return this->GetCMakeInstance()->GetPolicies()->
+ ApplyPolicyVersion(this,version);
+}
+
+cmPolicies *cmMakefile::GetPolicies()
+{
+ if (!this->GetCMakeInstance())
+ {
+ return 0;
+ }
+ return this->GetCMakeInstance()->GetPolicies();
+}
+
+//----------------------------------------------------------------------------
+void cmMakefile::RecordPolicies(cmPolicies::PolicyMap& pm)
+{
+ /* Record the setting of every policy. */
+ typedef cmPolicies::PolicyID PolicyID;
+ for(PolicyID pid = cmPolicies::CMP0000;
+ pid != cmPolicies::CMPCOUNT; pid = PolicyID(pid+1))
+ {
+ pm[pid] = this->GetPolicyStatus(pid);
+ }
+}
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
new file mode 100644
index 000000000..8a0088b1a
--- /dev/null
+++ b/Source/cmMakefile.h
@@ -0,0 +1,1014 @@
+/*============================================================================
+ 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 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 "cmake.h"
+
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+#include "cmSourceGroup.h"
+#endif
+
+#include <cmsys/auto_ptr.hxx>
+#include <cmsys/RegularExpression.hxx>
+
+class cmFunctionBlocker;
+class cmCommand;
+class cmInstallGenerator;
+class cmLocalGenerator;
+class cmMakeDepend;
+class cmSourceFile;
+class cmTest;
+class cmTestGenerator;
+class cmVariableWatch;
+class cmake;
+class cmMakefileCall;
+class cmCMakePolicyCommand;
+
+/** \class cmMakefile
+ * \brief Process the input CMakeLists.txt file.
+ *
+ * Process and store into memory the input CMakeLists.txt file.
+ * Each CMakeLists.txt file is parsed and the commands found there
+ * are added into the build process.
+ */
+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);
+ /* 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);
+
+ /**
+ * Construct an empty makefile.
+ */
+ cmMakefile();
+ cmMakefile(const cmMakefile& mf);
+
+ /**
+ * 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);
+
+ /**
+ * Add a function blocker to this makefile
+ */
+ void AddFunctionBlocker(cmFunctionBlocker* fb);
+
+ /**
+ * Remove the function blocker whose scope ends with the given command.
+ * This returns ownership of the function blocker object.
+ */
+ 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,
+ bool fast,
+ const std::vector<std::string> *cmakeArgs,
+ std::string *output);
+
+ /**
+ * 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);
+
+ /**
+ * Perform FinalPass, Library dependency analysis etc before output of the
+ * makefile.
+ */
+ void ConfigureFinalPass();
+
+ /**
+ * run the final pass on all commands.
+ */
+ void FinalPass();
+
+ /**
+ * Print the object state to std::cout.
+ */
+ void Print();
+
+ /** Add a custom command to the build. */
+ void AddCustomCommandToTarget(const char* target,
+ const std::vector<std::string>& depends,
+ const cmCustomCommandLines& commandLines,
+ cmTarget::CustomCommandType type,
+ const char* comment, const char* workingDir,
+ bool escapeOldStyle = true);
+ cmSourceFile* AddCustomCommandToOutput(
+ const std::vector<std::string>& outputs,
+ const std::vector<std::string>& depends,
+ const char* main_dependency,
+ const cmCustomCommandLines& commandLines,
+ const char* comment, const char* workingDir,
+ bool replace = false,
+ bool escapeOldStyle = true);
+ cmSourceFile* AddCustomCommandToOutput(
+ const char* output,
+ const std::vector<std::string>& depends,
+ const char* main_dependency,
+ const cmCustomCommandLines& commandLines,
+ const char* comment, const char* workingDir,
+ bool replace = false,
+ bool escapeOldStyle = true);
+ void AddCustomCommandOldStyle(const char* target,
+ const std::vector<std::string>& outputs,
+ const std::vector<std::string>& depends,
+ const char* source,
+ const cmCustomCommandLines& commandLines,
+ const char* comment);
+
+ /**
+ * Add a define flag to the build.
+ */
+ void AddDefineFlag(const char* definition);
+ void RemoveDefineFlag(const char* definition);
+
+ /** Create a new imported target with the name and type given. */
+ cmTarget* AddImportedTarget(const char* name, cmTarget::TargetType type,
+ bool global);
+
+ cmTarget* AddNewTarget(cmTarget::TargetType type, const char* name);
+
+ /**
+ * Add an executable to the build.
+ */
+ cmTarget* AddExecutable(const char *exename,
+ const std::vector<std::string> &srcs,
+ bool excludeFromAll = false);
+
+ /**
+ * 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,
+ const char* workingDirectory,
+ const std::vector<std::string>& depends,
+ const cmCustomCommandLines& commandLines,
+ bool escapeOldStyle = true,
+ const char* comment = 0);
+
+ /**
+ * 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;
+ }
+
+ /**
+ * 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,
+ bool immediate);
+
+ /**
+ * Configure a subdirectory
+ */
+ void ConfigureSubDirectory(cmLocalGenerator *);
+
+ /**
+ * Add an include directory to the build.
+ */
+ void AddIncludeDirectory(const char*, bool before = false);
+
+ /**
+ * 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);
+ ///! Add a definition to this makefile and the global cmake cache.
+ void AddCacheDefinition(const char* name, const char* value,
+ const char* doc,
+ cmCacheManager::CacheEntryType type,
+ bool force = false);
+
+ /**
+ * Add bool variable definition to the build.
+ */
+ void AddDefinition(const char* 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);
+ ///! Remove a definition from the cache.
+ void RemoveCacheDefinition(const char* 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();
+ }
+
+ /** Get the configurations to be generated. */
+ const char* GetConfigurations(std::vector<std::string>& configs,
+ bool single = true) const;
+
+ /**
+ * Set the name of the library.
+ */
+ cmTarget* AddLibrary(const char *libname, cmTarget::TargetType type,
+ const std::vector<std::string> &srcs,
+ bool excludeFromAll = false);
+
+#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);
+
+ /**
+ * Add a source group for consideration when adding a new source.
+ * name is tokenized.
+ */
+ void AddSourceGroup(const std::vector<std::string>& name,
+ const char* regex=0);
+
+#endif
+
+ //@{
+ /**
+ * Set, Push, Pop policy values for CMake.
+ */
+ bool SetPolicy(cmPolicies::PolicyID id, cmPolicies::PolicyStatus status);
+ bool SetPolicy(const char *id, cmPolicies::PolicyStatus status);
+ cmPolicies::PolicyStatus GetPolicyStatus(cmPolicies::PolicyID id);
+ bool SetPolicyVersion(const char *version);
+ void RecordPolicies(cmPolicies::PolicyMap& pm);
+ //@}
+
+ /** Helper class to push and pop policies automatically. */
+ class PolicyPushPop
+ {
+ public:
+ PolicyPushPop(cmMakefile* m,
+ bool weak = false,
+ cmPolicies::PolicyMap const& pm = cmPolicies::PolicyMap());
+ ~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.
+ */
+ void AddExtraDirectory(const char* dir);
+
+
+ /**
+ * 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();
+ }
+ //@}
+
+ /**
+ * Set CMAKE_SCRIPT_MODE_FILE variable when running a -P script.
+ */
+ void SetScriptModeFile(const char* scriptfile);
+
+ /**
+ * Set CMAKE_ARGC, CMAKE_ARGV0 ... variables.
+ */
+ 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();
+ }
+
+ //@}
+
+ /**
+ * Set a regular expression that include files must match
+ * in order to be considered as part of the depend information.
+ */
+ void SetIncludeRegularExpression(const char* regex)
+ {
+ this->IncludeFileRegularExpression = regex;
+ }
+ const char* GetIncludeRegularExpression()
+ {
+ return this->IncludeFileRegularExpression.c_str();
+ }
+
+ /**
+ * 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)
+ {
+ this->ComplainFileRegularExpression = regex;
+ }
+ const char* GetComplainRegularExpression()
+ {
+ return this->ComplainFileRegularExpression.c_str();
+ }
+
+ /**
+ * Get the list of targets
+ */
+ cmTargets &GetTargets() { return this->Targets; }
+ /**
+ * Get the list of targets, const version
+ */
+ const cmTargets &GetTargets() const { return this->Targets; }
+
+ cmTarget* FindTarget(const char* name);
+
+ /** 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);
+
+ /**
+ * Mark include directories as system directories.
+ */
+ void AddSystemIncludeDirectory(const char* dir);
+ bool IsSystemIncludeDirectory(const char* dir);
+
+ /** 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);
+
+ /** 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);
+
+ /** 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,
+ 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;
+ /**
+ * 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;
+
+ /** Test a boolean cache entry to see if it is true or false,
+ * returns false if no entry defined.
+ */
+ bool IsOn(const char* name) const;
+ bool IsSet(const char* name) const;
+
+ /** Return whether the target platform is 64-bit. */
+ bool PlatformIs64Bit() const;
+
+ /** Retrieve soname flag for the specified language if supported */
+ const char* GetSONameFlag(const char* language) const;
+
+ /**
+ * Get a list of preprocessor define flags.
+ */
+ const char* GetDefineFlags()
+ {return this->DefineFlags.c_str();}
+
+ /**
+ * Make sure CMake can write this file
+ */
+ bool CanIWriteThisFile(const char* fileName);
+
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ /**
+ * Get the vector source groups.
+ */
+ const std::vector<cmSourceGroup>& GetSourceGroups() const
+ { return this->SourceGroups; }
+
+ /**
+ * Get the source group
+ */
+ cmSourceGroup* GetSourceGroup(const std::vector<std::string>&name);
+#endif
+
+ /**
+ * Get the vector of list files on which this makefile depends
+ */
+ const std::vector<std::string>& GetListFiles() const
+ { return this->ListFiles; }
+ ///! When the file changes cmake will be re-run from the build system.
+ void AddCMakeDependFile(const char* file)
+ { this->ListFiles.push_back(file);}
+
+ /**
+ * Get the list file stack as a string
+ */
+ std::string GetListFileStack();
+
+ /**
+ * Get the current context backtrace.
+ */
+ bool GetBacktrace(cmListFileBacktrace& backtrace) const;
+
+ /**
+ * Get the vector of files created by this makefile
+ */
+ const std::vector<std::string>& GetOutputFiles() const
+ { return this->OutputFiles; }
+ void AddCMakeOutputFile(const char* file)
+ { this->OutputFiles.push_back(file);}
+
+ /**
+ * Expand all defined variables in the string.
+ * Defined variables come from the this->Definitions map.
+ * They are expanded with ${var} where var is the
+ * 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, bool escapeQuotes,
+ bool noEscapes,
+ bool atOnly = false,
+ const char* filename = 0,
+ long line = -1,
+ bool removeEmpty = false,
+ bool replaceAt = true);
+
+ /**
+ * Remove any remaining variables in the string. Anything with ${var} or
+ * \@var\@ will be removed.
+ */
+ void RemoveVariablesInString(std::string& source,
+ bool atOnly = false) const;
+
+ /**
+ * Expand variables in the makefiles ivars such as link directories etc
+ */
+ void ExpandVariables();
+
+ /**
+ * Replace variables and #cmakedefine lines in the given string.
+ * See cmConfigureFileCommand for details.
+ */
+ void ConfigureString(const std::string& input, std::string& output,
+ bool atOnly, bool escapeQuotes);
+
+ /**
+ * Copy file but change lines acording to ConfigureString
+ */
+ int ConfigureFile(const char* infile, const char* outfile,
+ bool copyonly, bool atOnly, bool escapeQuotes,
+ const cmNewLineStyle& = cmNewLineStyle());
+
+
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ /**
+ * find what source group this source is in
+ */
+ cmSourceGroup& FindSourceGroup(const char* source,
+ std::vector<cmSourceGroup> &groups);
+#endif
+
+ /**
+ * Print a command's invocation
+ */
+ void PrintCommandTrace(const cmListFileFunction& lff);
+
+ /**
+ * Execute a single CMake command. Returns true if the command
+ * succeeded or false if it failed.
+ */
+ 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;
+
+ /**
+ * Get the variable watch. This is used to determine when certain variables
+ * are accessed.
+ */
+#ifdef CMAKE_BUILD_WITH_CMAKE
+ cmVariableWatch* GetVariableWatch() const;
+#endif
+
+ ///! Display progress or status message.
+ void DisplayStatus(const char*, float);
+
+ /**
+ * 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);
+ /**
+ * Get the instance
+ */
+ cmake *GetCMakeInstance() const;
+
+ /**
+ * Get all the source files this makefile knows about
+ */
+ const std::vector<cmSourceFile*> &GetSourceFiles() const
+ {return this->SourceFiles;}
+ std::vector<cmSourceFile*> &GetSourceFiles() {return this->SourceFiles;}
+
+ /**
+ * 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);
+
+ ///! Add a new cmTest to the list of tests for this makefile.
+ cmTest* CreateTest(const char* 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);
+
+ /**
+ * Return a location of a file in cmake or custom modules directory
+ */
+ std::string GetModulesFile(const char* name);
+
+ ///! 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; };
+
+ ///! 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 AddInstallGenerator(cmInstallGenerator* g)
+ { if(g) this->InstallGenerators.push_back(g); }
+ std::vector<cmInstallGenerator*>& GetInstallGenerators()
+ { return this->InstallGenerators; }
+
+ void AddTestGenerator(cmTestGenerator* g)
+ { if(g) this->TestGenerators.push_back(g); }
+ std::vector<cmTestGenerator*>& GetTestGenerators()
+ { return this->TestGenerators; }
+
+ // Define the properties
+ static void DefineProperties(cmake *cm);
+
+ // push and pop variable scopes
+ void PushScope();
+ void PopScope();
+ void RaiseScope(const char *var, const char *value);
+
+ /** Helper class to push and pop scopes automatically. */
+ class ScopePushPop
+ {
+ public:
+ ScopePushPop(cmMakefile* m): Makefile(m) { this->Makefile->PushScope(); }
+ ~ScopePushPop() { this->Makefile->PopScope(); }
+ private:
+ cmMakefile* Makefile;
+ };
+
+ void IssueMessage(cmake::MessageType t,
+ std::string const& text) const;
+
+ /** Set whether or not to report a CMP0000 violation. */
+ void SetCheckCMP0000(bool b) { this->CheckCMP0000 = b; }
+
+protected:
+ // add link libraries and directories to the target
+ void AddGlobalLinkInformation(const char* name, cmTarget& target);
+
+ // Check for a an unused variable
+ void CheckForUnused(const char* reason, const char* 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
+
+ // libraries, classes, and executables
+ cmTargets Targets;
+ std::vector<cmSourceFile*> SourceFiles;
+
+ // Tests
+ std::map<cmStdString, 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
+
+
+ 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;
+
+ // Track the value of the computed DEFINITIONS property.
+ void AddDefineFlag(const char*, std::string&);
+ void RemoveDefineFlag(const char*, std::string::size_type, std::string&);
+ std::string DefineFlagsOrig;
+
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ std::vector<cmSourceGroup> SourceGroups;
+#endif
+
+ std::vector<cmCommand*> FinalPassCommands;
+ cmLocalGenerator* LocalGenerator;
+ bool IsFunctionBlocked(const cmListFileFunction& lff,
+ cmExecutionStatus &status);
+
+private:
+ void Initialize();
+
+ bool ParseDefineFlag(std::string const& definition, bool remove);
+
+ bool EnforceUniqueDir(const char* srcPath, const char* binPath);
+
+ 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;
+
+ 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;
+
+ cmsys::RegularExpression cmDefineRegex;
+ cmsys::RegularExpression cmDefine01Regex;
+ cmsys::RegularExpression cmAtVarRegex;
+
+ cmPropertyMap Properties;
+
+ // should this makefile be processed before or after processing the parent
+ bool PreOrder;
+
+ // 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;
+ friend class cmMakefileCall;
+
+ cmTarget* FindBasicTarget(const char* name);
+ std::vector<cmTarget*> ImportedTargetsOwned;
+ std::map<cmStdString, cmTarget*> 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);
+ 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();
+};
+
+//----------------------------------------------------------------------------
+// Helper class to make sure the call stack is valid.
+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();
+ }
+private:
+ cmMakefile* Makefile;
+};
+
+#endif
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
new file mode 100644
index 000000000..ab5150a36
--- /dev/null
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -0,0 +1,448 @@
+/*============================================================================
+ 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 "cmMakefileExecutableTargetGenerator.h"
+
+#include "cmGeneratedFileStream.h"
+#include "cmGlobalUnixMakefileGenerator3.h"
+#include "cmLocalUnixMakefileGenerator3.h"
+#include "cmMakefile.h"
+#include "cmSourceFile.h"
+#include "cmTarget.h"
+#include "cmake.h"
+
+//----------------------------------------------------------------------------
+cmMakefileExecutableTargetGenerator
+::cmMakefileExecutableTargetGenerator(cmTarget* target):
+ cmMakefileTargetGenerator(target)
+{
+ this->CustomCommandDriver = OnDepends;
+ this->Target->GetExecutableNames(
+ this->TargetNameOut, this->TargetNameReal, this->TargetNameImport,
+ this->TargetNamePDB, this->ConfigName);
+
+ this->OSXBundleGenerator = new cmOSXBundleGenerator(this->Target,
+ this->TargetNameOut,
+ this->ConfigName);
+ this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
+ this->MacContentDirectory =
+ this->OSXBundleGenerator->GetMacContentDirectory();
+}
+
+//----------------------------------------------------------------------------
+cmMakefileExecutableTargetGenerator
+::~cmMakefileExecutableTargetGenerator()
+{
+ delete this->OSXBundleGenerator;
+}
+
+//----------------------------------------------------------------------------
+void cmMakefileExecutableTargetGenerator::WriteRuleFiles()
+{
+ // create the build.make file and directory, put in the common blocks
+ this->CreateRuleFile();
+
+ // write rules used to help build object files
+ this->WriteCommonCodeRules();
+
+ // write the per-target per-language flags
+ this->WriteTargetLanguageFlags();
+
+ // write in rules for object files and custom commands
+ this->WriteTargetBuildRules();
+
+ // write the link rules
+ this->WriteExecutableRule(false);
+ if(this->Target->NeedRelinkBeforeInstall(this->ConfigName))
+ {
+ // Write rules to link an installable version of the target.
+ this->WriteExecutableRule(true);
+ }
+
+ // Write the requires target.
+ this->WriteTargetRequiresRules();
+
+ // Write clean target
+ this->WriteTargetCleanRules();
+
+ // Write the dependency generation rule. This must be done last so
+ // that multiple output pair information is available.
+ this->WriteTargetDependRules();
+
+ // close the streams
+ this->CloseFileStreams();
+}
+
+
+
+//----------------------------------------------------------------------------
+void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
+{
+ std::vector<std::string> commands;
+
+ // Build list of dependencies.
+ std::vector<std::string> depends;
+ this->AppendLinkDepends(depends);
+
+ // Get the name of the executable to generate.
+ std::string targetName;
+ std::string targetNameReal;
+ std::string targetNameImport;
+ std::string targetNamePDB;
+ this->Target->GetExecutableNames
+ (targetName, targetNameReal, targetNameImport, targetNamePDB,
+ this->ConfigName);
+
+ // Construct the full path version of the names.
+ std::string outpath = this->Target->GetDirectory(this->ConfigName);
+ outpath += "/";
+ if(this->Target->IsAppBundleOnApple())
+ {
+ this->OSXBundleGenerator->CreateAppBundle(targetName, outpath);
+ }
+ std::string outpathImp;
+ if(relink)
+ {
+ outpath = this->Makefile->GetStartOutputDirectory();
+ outpath += cmake::GetCMakeFilesDirectory();
+ outpath += "/CMakeRelink.dir";
+ cmSystemTools::MakeDirectory(outpath.c_str());
+ outpath += "/";
+ if(!targetNameImport.empty())
+ {
+ outpathImp = outpath;
+ }
+ }
+ else
+ {
+ cmSystemTools::MakeDirectory(outpath.c_str());
+ if(!targetNameImport.empty())
+ {
+ outpathImp = this->Target->GetDirectory(this->ConfigName, true);
+ cmSystemTools::MakeDirectory(outpathImp.c_str());
+ outpathImp += "/";
+ }
+ }
+ std::string targetFullPath = outpath + targetName;
+ std::string targetFullPathReal = outpath + targetNameReal;
+ std::string targetFullPathPDB = outpath + targetNamePDB;
+ std::string targetFullPathImport = outpathImp + targetNameImport;
+ std::string targetOutPathPDB =
+ this->Convert(targetFullPathPDB.c_str(),
+ cmLocalGenerator::NONE,
+ cmLocalGenerator::SHELL);
+ // Convert to the output path to use in constructing commands.
+ std::string targetOutPath =
+ this->Convert(targetFullPath.c_str(),
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::SHELL);
+ std::string targetOutPathReal =
+ this->Convert(targetFullPathReal.c_str(),
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::SHELL);
+ std::string targetOutPathImport =
+ this->Convert(targetFullPathImport.c_str(),
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::SHELL);
+
+ // Get the language to use for linking this executable.
+ const char* linkLanguage =
+ this->Target->GetLinkerLanguage(this->ConfigName);
+
+ // Make sure we have a link language.
+ if(!linkLanguage)
+ {
+ cmSystemTools::Error("Cannot determine link language for target \"",
+ this->Target->GetName(), "\".");
+ return;
+ }
+
+ if(!this->NoRuleMessages)
+ {
+ // Add the link message.
+ std::string buildEcho = "Linking ";
+ buildEcho += linkLanguage;
+ buildEcho += " executable ";
+ buildEcho += targetOutPath;
+ this->LocalGenerator->AppendEcho(commands, buildEcho.c_str(),
+ cmLocalUnixMakefileGenerator3::EchoLink);
+ }
+
+ // Build a list of compiler flags and linker flags.
+ std::string flags;
+ std::string linkFlags;
+
+ // Add flags to create an executable.
+ this->LocalGenerator->
+ AddConfigVariableFlags(linkFlags, "CMAKE_EXE_LINKER_FLAGS",
+ this->ConfigName);
+
+
+ if(this->Target->GetPropertyAsBool("WIN32_EXECUTABLE"))
+ {
+ this->LocalGenerator->AppendFlags
+ (linkFlags, this->Makefile->GetDefinition("CMAKE_CREATE_WIN32_EXE"));
+ }
+ else
+ {
+ this->LocalGenerator->AppendFlags
+ (linkFlags, this->Makefile->GetDefinition("CMAKE_CREATE_CONSOLE_EXE"));
+ }
+
+ // Add symbol export flags if necessary.
+ if(this->Target->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()));
+ }
+
+ // Add language feature flags.
+ this->AddFeatureFlags(flags, linkLanguage);
+
+ this->LocalGenerator->AddArchitectureFlags(flags, this->Target,
+ linkLanguage, this->ConfigName);
+
+ // Add target-specific linker flags.
+ this->LocalGenerator->AppendFlags
+ (linkFlags, this->Target->GetProperty("LINK_FLAGS"));
+ std::string linkFlagsConfig = "LINK_FLAGS_";
+ linkFlagsConfig += cmSystemTools::UpperCase(this->ConfigName);
+ this->LocalGenerator->AppendFlags
+ (linkFlags, this->Target->GetProperty(linkFlagsConfig.c_str()));
+
+ 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(),
+ 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.
+ exeCleanFiles.push_back(this->Convert((targetFullPath+".manifest").c_str(),
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::UNCHANGED));
+#endif
+ if(targetNameReal != targetName)
+ {
+ exeCleanFiles.push_back(this->Convert(targetFullPathReal.c_str(),
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::UNCHANGED));
+ }
+ if(!targetNameImport.empty())
+ {
+ exeCleanFiles.push_back(this->Convert(targetFullPathImport.c_str(),
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::UNCHANGED));
+ std::string implib;
+ if(this->Target->GetImplibGNUtoMS(targetFullPathImport, implib))
+ {
+ exeCleanFiles.push_back(this->Convert(implib.c_str(),
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::UNCHANGED));
+ }
+ }
+
+ // List the PDB for cleaning only when the whole target is
+ // cleaned. We do not want to delete the .pdb file just before
+ // linking the target.
+ this->CleanFiles.push_back
+ (this->Convert(targetFullPathPDB.c_str(),
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::UNCHANGED));
+
+ // Add the pre-build and pre-link rules building but not when relinking.
+ if(!relink)
+ {
+ this->LocalGenerator
+ ->AppendCustomCommands(commands, this->Target->GetPreBuildCommands(),
+ this->Target);
+ this->LocalGenerator
+ ->AppendCustomCommands(commands, this->Target->GetPreLinkCommands(),
+ this->Target);
+ }
+
+ // Determine whether a link script will be used.
+ bool useLinkScript = this->GlobalGenerator->GetUseLinkScript();
+
+ // Construct the main link rule.
+ std::vector<std::string> real_link_commands;
+ std::string linkRuleVar = "CMAKE_";
+ linkRuleVar += linkLanguage;
+ linkRuleVar += "_LINK_EXECUTABLE";
+ std::string linkRule = this->GetLinkRule(linkRuleVar.c_str());
+ std::vector<std::string> commands1;
+ cmSystemTools::ExpandListArgument(linkRule, real_link_commands);
+ if(this->Target->IsExecutableWithExports())
+ {
+ // If a separate rule for creating an import library is specified
+ // add it now.
+ std::string implibRuleVar = "CMAKE_";
+ implibRuleVar += linkLanguage;
+ implibRuleVar += "_CREATE_IMPORT_LIBRARY";
+ if(const char* rule =
+ this->Makefile->GetDefinition(implibRuleVar.c_str()))
+ {
+ cmSystemTools::ExpandListArgument(rule, real_link_commands);
+ }
+ }
+
+ // Select whether to use a response file for objects.
+ bool useResponseFile = false;
+ {
+ std::string responseVar = "CMAKE_";
+ responseVar += linkLanguage;
+ responseVar += "_USE_RESPONSE_FILE_FOR_OBJECTS";
+ if(this->Makefile->IsOn(responseVar.c_str()))
+ {
+ useResponseFile = true;
+ }
+ }
+
+ // Expand the rule variables.
+ {
+ // Set path conversion for link script shells.
+ this->LocalGenerator->SetLinkScriptShell(useLinkScript);
+
+ // Collect up flags to link in needed libraries.
+ cmOStringStream linklibs;
+ this->LocalGenerator->OutputLinkLibraries(linklibs, *this->Target, relink);
+
+ // Construct object file lists that may be needed to expand the
+ // rule.
+ std::string buildObjs;
+ this->CreateObjectLists(useLinkScript, false, useResponseFile,
+ buildObjs, depends);
+
+ cmLocalGenerator::RuleVariables vars;
+ vars.RuleLauncher = "RULE_LAUNCH_LINK";
+ vars.CMTarget = this->Target;
+ vars.Language = linkLanguage;
+ vars.Objects = buildObjs.c_str();
+ std::string objdir = cmake::GetCMakeFilesDirectoryPostSlash();
+ objdir += this->Target->GetName();
+ objdir += ".dir";
+ objdir = this->Convert(objdir.c_str(),
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::SHELL);
+ vars.ObjectDir = objdir.c_str();
+ vars.Target = targetOutPathReal.c_str();
+ vars.TargetPDB = targetOutPathPDB.c_str();
+
+ // Setup the target version.
+ std::string targetVersionMajor;
+ std::string targetVersionMinor;
+ {
+ cmOStringStream majorStream;
+ cmOStringStream minorStream;
+ int major;
+ int minor;
+ this->Target->GetTargetVersion(major, minor);
+ majorStream << major;
+ minorStream << minor;
+ targetVersionMajor = majorStream.str();
+ targetVersionMinor = minorStream.str();
+ }
+ vars.TargetVersionMajor = targetVersionMajor.c_str();
+ vars.TargetVersionMinor = targetVersionMinor.c_str();
+
+ std::string linkString = linklibs.str();
+ vars.LinkLibraries = linkString.c_str();
+ vars.Flags = flags.c_str();
+ vars.LinkFlags = linkFlags.c_str();
+ // Expand placeholders in the commands.
+ this->LocalGenerator->TargetImplib = targetOutPathImport;
+ for(std::vector<std::string>::iterator i = real_link_commands.begin();
+ i != real_link_commands.end(); ++i)
+ {
+ this->LocalGenerator->ExpandRuleVariables(*i, vars);
+ }
+ this->LocalGenerator->TargetImplib = "";
+
+ // Restore path conversion to normal shells.
+ this->LocalGenerator->SetLinkScriptShell(false);
+ }
+
+ // Optionally convert the build rule to use a script to avoid long
+ // command lines in the make shell.
+ if(useLinkScript)
+ {
+ // Use a link script.
+ const char* name = (relink? "relink.txt" : "link.txt");
+ this->CreateLinkScript(name, real_link_commands, commands1, depends);
+ }
+ else
+ {
+ // No link script. Just use the link rule directly.
+ commands1 = real_link_commands;
+ }
+ this->LocalGenerator->CreateCDCommand
+ (commands1,
+ this->Makefile->GetStartOutputDirectory(),
+ cmLocalGenerator::HOME_OUTPUT);
+ commands.insert(commands.end(), commands1.begin(), commands1.end());
+ commands1.clear();
+
+ // Add a rule to create necessary symlinks for the library.
+ if(targetOutPath != targetOutPathReal)
+ {
+ std::string symlink = "$(CMAKE_COMMAND) -E cmake_symlink_executable ";
+ symlink += targetOutPathReal;
+ symlink += " ";
+ symlink += targetOutPath;
+ commands1.push_back(symlink);
+ this->LocalGenerator->CreateCDCommand(commands1,
+ this->Makefile->GetStartOutputDirectory(),
+ cmLocalGenerator::HOME_OUTPUT);
+ commands.insert(commands.end(), commands1.begin(), commands1.end());
+ commands1.clear();
+ }
+
+ // Add the post-build rules when building but not when relinking.
+ if(!relink)
+ {
+ this->LocalGenerator->
+ AppendCustomCommands(commands, this->Target->GetPostBuildCommands(),
+ this->Target);
+ }
+
+ // Write the build rule.
+ this->LocalGenerator->WriteMakeRule(*this->BuildFileStream,
+ 0,
+ targetFullPathReal.c_str(),
+ depends, commands, false);
+
+ // The symlink name for the target should depend on the real target
+ // so if the target version changes it rebuilds and recreates the
+ // symlink.
+ if(targetFullPath != targetFullPathReal)
+ {
+ depends.clear();
+ commands.clear();
+ depends.push_back(targetFullPathReal.c_str());
+ this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
+ targetFullPath.c_str(),
+ depends, commands, false);
+ }
+
+ // Write the main driver rule to build everything in this target.
+ this->WriteTargetDriverRule(targetFullPath.c_str(), relink);
+
+ // Clean all the possible executable names and symlinks.
+ this->CleanFiles.insert(this->CleanFiles.end(),
+ exeCleanFiles.begin(),
+ exeCleanFiles.end());
+}
diff --git a/Source/cmMakefileExecutableTargetGenerator.h b/Source/cmMakefileExecutableTargetGenerator.h
new file mode 100644
index 000000000..3b18166ff
--- /dev/null
+++ b/Source/cmMakefileExecutableTargetGenerator.h
@@ -0,0 +1,31 @@
+/*============================================================================
+ 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 cmMakefileExecutableTargetGenerator_h
+#define cmMakefileExecutableTargetGenerator_h
+
+#include "cmMakefileTargetGenerator.h"
+
+class cmMakefileExecutableTargetGenerator: public cmMakefileTargetGenerator
+{
+public:
+ cmMakefileExecutableTargetGenerator(cmTarget* target);
+ virtual ~cmMakefileExecutableTargetGenerator();
+
+ /* the main entry point for this class. Writes the Makefiles associated
+ with this target */
+ virtual void WriteRuleFiles();
+
+protected:
+ virtual void WriteExecutableRule(bool relink);
+};
+
+#endif
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
new file mode 100644
index 000000000..577e5fd07
--- /dev/null
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -0,0 +1,808 @@
+/*============================================================================
+ 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 "cmMakefileLibraryTargetGenerator.h"
+
+#include "cmGeneratedFileStream.h"
+#include "cmGlobalUnixMakefileGenerator3.h"
+#include "cmLocalUnixMakefileGenerator3.h"
+#include "cmMakefile.h"
+#include "cmSourceFile.h"
+#include "cmTarget.h"
+#include "cmake.h"
+
+#include <memory> // auto_ptr
+
+//----------------------------------------------------------------------------
+cmMakefileLibraryTargetGenerator
+::cmMakefileLibraryTargetGenerator(cmTarget* target):
+ cmMakefileTargetGenerator(target)
+{
+ cmOSXBundleGenerator::PrepareTargetProperties(this->Target);
+
+ this->CustomCommandDriver = OnDepends;
+ this->Target->GetLibraryNames(
+ this->TargetNameOut, this->TargetNameSO, this->TargetNameReal,
+ this->TargetNameImport, this->TargetNamePDB, this->ConfigName);
+
+ this->OSXBundleGenerator = new cmOSXBundleGenerator(this->Target,
+ this->TargetNameOut,
+ this->ConfigName);
+ this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
+ this->MacContentDirectory =
+ this->OSXBundleGenerator->GetMacContentDirectory();
+}
+
+//----------------------------------------------------------------------------
+cmMakefileLibraryTargetGenerator
+::~cmMakefileLibraryTargetGenerator()
+{
+ delete this->OSXBundleGenerator;
+}
+
+//----------------------------------------------------------------------------
+void cmMakefileLibraryTargetGenerator::WriteRuleFiles()
+{
+ // create the build.make file and directory, put in the common blocks
+ this->CreateRuleFile();
+
+ // write rules used to help build object files
+ this->WriteCommonCodeRules();
+
+ // write the per-target per-language flags
+ this->WriteTargetLanguageFlags();
+
+ // write in rules for object files and custom commands
+ this->WriteTargetBuildRules();
+
+ // write the link rules
+ // Write the rule for this target type.
+ switch(this->Target->GetType())
+ {
+ case cmTarget::STATIC_LIBRARY:
+ this->WriteStaticLibraryRules();
+ break;
+ case cmTarget::SHARED_LIBRARY:
+ this->WriteSharedLibraryRules(false);
+ if(this->Target->NeedRelinkBeforeInstall(this->ConfigName))
+ {
+ // Write rules to link an installable version of the target.
+ this->WriteSharedLibraryRules(true);
+ }
+ break;
+ case cmTarget::MODULE_LIBRARY:
+ this->WriteModuleLibraryRules(false);
+ if(this->Target->NeedRelinkBeforeInstall(this->ConfigName))
+ {
+ // Write rules to link an installable version of the target.
+ this->WriteModuleLibraryRules(true);
+ }
+ break;
+ case cmTarget::OBJECT_LIBRARY:
+ this->WriteObjectLibraryRules();
+ break;
+ default:
+ // If language is not known, this is an error.
+ cmSystemTools::Error("Unknown Library Type");
+ break;
+ }
+
+ // Write the requires target.
+ this->WriteTargetRequiresRules();
+
+ // Write clean target
+ this->WriteTargetCleanRules();
+
+ // Write the dependency generation rule. This must be done last so
+ // that multiple output pair information is available.
+ this->WriteTargetDependRules();
+
+ // close the streams
+ this->CloseFileStreams();
+}
+
+//----------------------------------------------------------------------------
+void cmMakefileLibraryTargetGenerator::WriteObjectLibraryRules()
+{
+ std::vector<std::string> commands;
+ std::vector<std::string> depends;
+
+ // Add post-build rules.
+ this->LocalGenerator->
+ AppendCustomCommands(commands, this->Target->GetPostBuildCommands(),
+ this->Target);
+
+ // Depend on the object files.
+ this->AppendObjectDepends(depends);
+
+ // Write the rule.
+ this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
+ this->Target->GetName(),
+ depends, commands, true);
+
+ // Write the main driver rule to build everything in this target.
+ this->WriteTargetDriverRule(this->Target->GetName(), false);
+}
+
+//----------------------------------------------------------------------------
+void cmMakefileLibraryTargetGenerator::WriteStaticLibraryRules()
+{
+ const char* linkLanguage =
+ this->Target->GetLinkerLanguage(this->ConfigName);
+ std::string linkRuleVar = "CMAKE_";
+ if (linkLanguage)
+ {
+ linkRuleVar += linkLanguage;
+ }
+ linkRuleVar += "_CREATE_STATIC_LIBRARY";
+
+ if(this->GetFeatureAsBool("INTERPROCEDURAL_OPTIMIZATION") &&
+ this->Makefile->GetDefinition((linkRuleVar+"_IPO").c_str()))
+ {
+ linkRuleVar += "_IPO";
+ }
+
+ std::string extraFlags;
+ this->LocalGenerator->AppendFlags
+ (extraFlags,this->Target->GetProperty("STATIC_LIBRARY_FLAGS"));
+ std::string staticLibraryFlagsConfig = "STATIC_LIBRARY_FLAGS_";
+ staticLibraryFlagsConfig += cmSystemTools::UpperCase(this->ConfigName);
+ this->LocalGenerator->AppendFlags
+ (extraFlags, this->Target->GetProperty(staticLibraryFlagsConfig.c_str()));
+ this->WriteLibraryRules(linkRuleVar.c_str(), extraFlags.c_str(), false);
+}
+
+//----------------------------------------------------------------------------
+void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink)
+{
+ if(this->Target->IsFrameworkOnApple())
+ {
+ this->WriteFrameworkRules(relink);
+ return;
+ }
+ const char* linkLanguage =
+ this->Target->GetLinkerLanguage(this->ConfigName);
+ std::string linkRuleVar = "CMAKE_";
+ if (linkLanguage)
+ {
+ linkRuleVar += linkLanguage;
+ }
+ linkRuleVar += "_CREATE_SHARED_LIBRARY";
+
+ std::string extraFlags;
+ this->LocalGenerator->AppendFlags
+ (extraFlags, this->Target->GetProperty("LINK_FLAGS"));
+ std::string linkFlagsConfig = "LINK_FLAGS_";
+ linkFlagsConfig += cmSystemTools::UpperCase(this->ConfigName);
+ this->LocalGenerator->AppendFlags
+ (extraFlags, this->Target->GetProperty(linkFlagsConfig.c_str()));
+
+ this->LocalGenerator->AddConfigVariableFlags
+ (extraFlags, "CMAKE_SHARED_LINKER_FLAGS", this->ConfigName);
+ this->AddModuleDefinitionFlag(extraFlags);
+
+ this->WriteLibraryRules(linkRuleVar.c_str(), extraFlags.c_str(), relink);
+}
+
+//----------------------------------------------------------------------------
+void cmMakefileLibraryTargetGenerator::WriteModuleLibraryRules(bool relink)
+{
+ const char* linkLanguage =
+ this->Target->GetLinkerLanguage(this->ConfigName);
+ std::string linkRuleVar = "CMAKE_";
+ if (linkLanguage)
+ {
+ linkRuleVar += linkLanguage;
+ }
+ linkRuleVar += "_CREATE_SHARED_MODULE";
+
+ std::string extraFlags;
+ this->LocalGenerator->AppendFlags(extraFlags,
+ this->Target->GetProperty("LINK_FLAGS"));
+ std::string linkFlagsConfig = "LINK_FLAGS_";
+ linkFlagsConfig += cmSystemTools::UpperCase(this->ConfigName);
+ this->LocalGenerator->AppendFlags
+ (extraFlags, this->Target->GetProperty(linkFlagsConfig.c_str()));
+ this->LocalGenerator->AddConfigVariableFlags
+ (extraFlags, "CMAKE_MODULE_LINKER_FLAGS", this->ConfigName);
+ this->AddModuleDefinitionFlag(extraFlags);
+
+ this->WriteLibraryRules(linkRuleVar.c_str(), extraFlags.c_str(), relink);
+}
+
+//----------------------------------------------------------------------------
+void cmMakefileLibraryTargetGenerator::WriteFrameworkRules(bool relink)
+{
+ const char* linkLanguage =
+ this->Target->GetLinkerLanguage(this->ConfigName);
+ std::string linkRuleVar = "CMAKE_";
+ if (linkLanguage)
+ {
+ linkRuleVar += linkLanguage;
+ }
+ linkRuleVar += "_CREATE_MACOSX_FRAMEWORK";
+
+ std::string extraFlags;
+ this->LocalGenerator->AppendFlags(extraFlags,
+ this->Target->GetProperty("LINK_FLAGS"));
+ std::string linkFlagsConfig = "LINK_FLAGS_";
+ linkFlagsConfig += cmSystemTools::UpperCase(this->ConfigName);
+ this->LocalGenerator->AppendFlags
+ (extraFlags, this->Target->GetProperty(linkFlagsConfig.c_str()));
+ this->LocalGenerator->AddConfigVariableFlags
+ (extraFlags, "CMAKE_MACOSX_FRAMEWORK_LINKER_FLAGS", this->ConfigName);
+
+ this->WriteLibraryRules(linkRuleVar.c_str(), extraFlags.c_str(), relink);
+}
+
+//----------------------------------------------------------------------------
+void cmMakefileLibraryTargetGenerator::WriteLibraryRules
+(const char* linkRuleVar, const char* extraFlags, bool relink)
+{
+ // TODO: Merge the methods that call this method to avoid
+ // code duplication.
+ std::vector<std::string> commands;
+
+ // Build list of dependencies.
+ std::vector<std::string> depends;
+ this->AppendLinkDepends(depends);
+
+ // Get the language to use for linking this library.
+ const char* linkLanguage =
+ this->Target->GetLinkerLanguage(this->ConfigName);
+
+ // Make sure we have a link language.
+ if(!linkLanguage)
+ {
+ cmSystemTools::Error("Cannot determine link language for target \"",
+ this->Target->GetName(), "\".");
+ return;
+ }
+
+ // Create set of linking flags.
+ std::string linkFlags;
+ this->LocalGenerator->AppendFlags(linkFlags, extraFlags);
+
+ // Add OSX version flags, if any.
+ if(this->Target->GetType() == cmTarget::SHARED_LIBRARY ||
+ this->Target->GetType() == cmTarget::MODULE_LIBRARY)
+ {
+ this->AppendOSXVerFlag(linkFlags, linkLanguage, "COMPATIBILITY", true);
+ this->AppendOSXVerFlag(linkFlags, linkLanguage, "CURRENT", false);
+ }
+
+ // Construct the name of the library.
+ std::string targetName;
+ std::string targetNameSO;
+ std::string targetNameReal;
+ std::string targetNameImport;
+ std::string targetNamePDB;
+ this->Target->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())
+ {
+ outpath = this->MacContentDirectory;
+ this->OSXBundleGenerator->CreateFramework(targetName);
+ }
+ else if(this->Target->IsCFBundleOnApple())
+ {
+ outpath = this->Target->GetDirectory(this->ConfigName);
+ outpath += "/";
+ this->OSXBundleGenerator->CreateCFBundle(targetName, outpath);
+ }
+ else if(relink)
+ {
+ outpath = this->Makefile->GetStartOutputDirectory();
+ outpath += cmake::GetCMakeFilesDirectory();
+ outpath += "/CMakeRelink.dir";
+ cmSystemTools::MakeDirectory(outpath.c_str());
+ outpath += "/";
+ if(!targetNameImport.empty())
+ {
+ outpathImp = outpath;
+ }
+ }
+ else
+ {
+ outpath = this->Target->GetDirectory(this->ConfigName);
+ cmSystemTools::MakeDirectory(outpath.c_str());
+ outpath += "/";
+ if(!targetNameImport.empty())
+ {
+ outpathImp = this->Target->GetDirectory(this->ConfigName, true);
+ cmSystemTools::MakeDirectory(outpathImp.c_str());
+ outpathImp += "/";
+ }
+ }
+
+ std::string targetFullPath = outpath + targetName;
+ std::string targetFullPathPDB = outpath + targetNamePDB;
+ std::string targetFullPathSO = outpath + targetNameSO;
+ std::string targetFullPathReal = outpath + targetNameReal;
+ std::string targetFullPathImport = outpathImp + targetNameImport;
+
+ // Construct the output path version of the names for use in command
+ // arguments.
+ std::string targetOutPathPDB =
+ this->Convert(targetFullPathPDB.c_str(),cmLocalGenerator::NONE,
+ cmLocalGenerator::SHELL);
+ std::string targetOutPath =
+ this->Convert(targetFullPath.c_str(),cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::SHELL);
+ std::string targetOutPathSO =
+ this->Convert(targetFullPathSO.c_str(),cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::SHELL);
+ std::string targetOutPathReal =
+ this->Convert(targetFullPathReal.c_str(),cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::SHELL);
+ std::string targetOutPathImport =
+ this->Convert(targetFullPathImport.c_str(),cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::SHELL);
+
+ if(!this->NoRuleMessages)
+ {
+ // Add the link message.
+ std::string buildEcho = "Linking ";
+ buildEcho += linkLanguage;
+ switch(this->Target->GetType())
+ {
+ case cmTarget::STATIC_LIBRARY:
+ buildEcho += " static library ";
+ break;
+ case cmTarget::SHARED_LIBRARY:
+ buildEcho += " shared library ";
+ break;
+ case cmTarget::MODULE_LIBRARY:
+ if (this->Target->IsCFBundleOnApple())
+ buildEcho += " CFBundle";
+ buildEcho += " shared module ";
+ break;
+ default:
+ buildEcho += " library ";
+ break;
+ }
+ buildEcho += targetOutPath.c_str();
+ this->LocalGenerator->AppendEcho(commands, buildEcho.c_str(),
+ cmLocalUnixMakefileGenerator3::EchoLink);
+ }
+
+ const char* forbiddenFlagVar = 0;
+ switch(this->Target->GetType())
+ {
+ case cmTarget::SHARED_LIBRARY:
+ forbiddenFlagVar = "_CREATE_SHARED_LIBRARY_FORBIDDEN_FLAGS";
+ break;
+ case cmTarget::MODULE_LIBRARY:
+ forbiddenFlagVar = "_CREATE_SHARED_MODULE_FORBIDDEN_FLAGS";
+ break;
+ default: break;
+ }
+
+ // Clean files associated with this library.
+ std::vector<std::string> libCleanFiles;
+ libCleanFiles.push_back(this->Convert(targetFullPath.c_str(),
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::UNCHANGED));
+ if(targetNameReal != targetName)
+ {
+ libCleanFiles.push_back(this->Convert(targetFullPathReal.c_str(),
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::UNCHANGED));
+ }
+ if(targetNameSO != targetName &&
+ targetNameSO != targetNameReal)
+ {
+ libCleanFiles.push_back(this->Convert(targetFullPathSO.c_str(),
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::UNCHANGED));
+ }
+ if(!targetNameImport.empty())
+ {
+ libCleanFiles.push_back(this->Convert(targetFullPathImport.c_str(),
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::UNCHANGED));
+ std::string implib;
+ if(this->Target->GetImplibGNUtoMS(targetFullPathImport, implib))
+ {
+ libCleanFiles.push_back(this->Convert(implib.c_str(),
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::UNCHANGED));
+ }
+ }
+
+ // List the PDB for cleaning only when the whole target is
+ // cleaned. We do not want to delete the .pdb file just before
+ // linking the target.
+ this->CleanFiles.push_back
+ (this->Convert(targetFullPathPDB.c_str(),
+ 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)
+ {
+ libCleanFiles.push_back(
+ this->Convert((targetFullPath+".manifest").c_str(),
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::UNCHANGED));
+ }
+#endif
+
+ 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)
+ {
+ this->LocalGenerator->AppendCleanCommand(commands1, libCleanFiles,
+ *this->Target, "target");
+ this->LocalGenerator->CreateCDCommand
+ (commands1,
+ this->Makefile->GetStartOutputDirectory(),
+ cmLocalGenerator::HOME_OUTPUT);
+ commands.insert(commands.end(), commands1.begin(), commands1.end());
+ commands1.clear();
+ }
+
+ // Add the pre-build and pre-link rules building but not when relinking.
+ if(!relink)
+ {
+ this->LocalGenerator
+ ->AppendCustomCommands(commands, this->Target->GetPreBuildCommands(),
+ this->Target);
+ this->LocalGenerator
+ ->AppendCustomCommands(commands, this->Target->GetPreLinkCommands(),
+ this->Target);
+ }
+
+ // 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;
+ {
+ std::string responseVar = "CMAKE_";
+ responseVar += linkLanguage;
+ responseVar += "_USE_RESPONSE_FILE_FOR_OBJECTS";
+ if(this->Makefile->IsOn(responseVar.c_str()))
+ {
+ useResponseFile = true;
+ }
+ }
+
+ // For static libraries there might be archiving rules.
+ bool haveStaticLibraryRule = false;
+ std::vector<std::string> archiveCreateCommands;
+ 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)
+ {
+ 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()))
+ {
+ cmSystemTools::ExpandListArgument(rule, archiveCreateCommands);
+ }
+ std::string arAppendVar = "CMAKE_";
+ arAppendVar += linkLanguage;
+ arAppendVar += "_ARCHIVE_APPEND";
+ if(const char* rule = this->Makefile->GetDefinition(arAppendVar.c_str()))
+ {
+ cmSystemTools::ExpandListArgument(rule, archiveAppendCommands);
+ }
+ std::string arFinishVar = "CMAKE_";
+ arFinishVar += linkLanguage;
+ arFinishVar += "_ARCHIVE_FINISH";
+ if(const char* rule = this->Makefile->GetDefinition(arFinishVar.c_str()))
+ {
+ cmSystemTools::ExpandListArgument(rule, archiveFinishCommands);
+ }
+ }
+
+ // Decide whether to use archiving rules.
+ bool useArchiveRules =
+ !haveStaticLibraryRule &&
+ !archiveCreateCommands.empty() && !archiveAppendCommands.empty();
+ if(useArchiveRules)
+ {
+ // Archiving rules are always run with a link script.
+ useLinkScript = true;
+
+ // Archiving rules never use a response file.
+ useResponseFile = false;
+
+ // Limit the length of individual object lists to less than the
+ // 32K command line length limit on Windows. We could make this a
+ // platform file variable but this should work everywhere.
+ archiveCommandLimit = 30000;
+ }
+
+ // Expand the rule variables.
+ std::vector<std::string> real_link_commands;
+ {
+ // Set path conversion for link script shells.
+ this->LocalGenerator->SetLinkScriptShell(useLinkScript);
+
+ // Collect up flags to link in needed libraries.
+ cmOStringStream linklibs;
+ if(this->Target->GetType() != cmTarget::STATIC_LIBRARY)
+ {
+ this->LocalGenerator
+ ->OutputLinkLibraries(linklibs, *this->Target, relink);
+ }
+
+ // Construct object file lists that may be needed to expand the
+ // rule.
+ std::string buildObjs;
+ this->CreateObjectLists(useLinkScript, useArchiveRules, useResponseFile,
+ buildObjs, depends);
+
+ cmLocalGenerator::RuleVariables vars;
+ vars.TargetPDB = targetOutPathPDB.c_str();
+
+ // Setup the target version.
+ std::string targetVersionMajor;
+ std::string targetVersionMinor;
+ {
+ cmOStringStream majorStream;
+ cmOStringStream minorStream;
+ int major;
+ int minor;
+ this->Target->GetTargetVersion(major, minor);
+ majorStream << major;
+ minorStream << minor;
+ targetVersionMajor = majorStream.str();
+ targetVersionMinor = minorStream.str();
+ }
+ vars.TargetVersionMajor = targetVersionMajor.c_str();
+ vars.TargetVersionMinor = targetVersionMinor.c_str();
+
+ vars.RuleLauncher = "RULE_LAUNCH_LINK";
+ vars.CMTarget = this->Target;
+ vars.Language = linkLanguage;
+ vars.Objects = buildObjs.c_str();
+ std::string objdir = cmake::GetCMakeFilesDirectoryPostSlash();
+ objdir += this->Target->GetName();
+ objdir += ".dir";
+ objdir = this->Convert(objdir.c_str(),
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::SHELL);
+ vars.ObjectDir = objdir.c_str();
+ vars.Target = targetOutPathReal.c_str();
+ std::string linkString = linklibs.str();
+ vars.LinkLibraries = linkString.c_str();
+ vars.ObjectsQuoted = buildObjs.c_str();
+ if (this->Target->HasSOName(this->ConfigName))
+ {
+ vars.SONameFlag = this->Makefile->GetSONameFlag(linkLanguage);
+ vars.TargetSOName= targetNameSO.c_str();
+ }
+ vars.LinkFlags = linkFlags.c_str();
+
+ // Compute the directory portion of the install_name setting.
+ std::string install_name_dir;
+ if(this->Target->GetType() == cmTarget::SHARED_LIBRARY)
+ {
+ // Get the install_name directory for the build tree.
+ install_name_dir =
+ this->Target->GetInstallNameDirForBuildTree(this->ConfigName);
+
+ // Set the rule variable replacement value.
+ if(install_name_dir.empty())
+ {
+ vars.TargetInstallNameDir = "";
+ }
+ else
+ {
+ // Convert to a path for the native build tool.
+ install_name_dir =
+ this->LocalGenerator->Convert(install_name_dir.c_str(),
+ cmLocalGenerator::NONE,
+ cmLocalGenerator::SHELL, false);
+ vars.TargetInstallNameDir = install_name_dir.c_str();
+ }
+ }
+
+ // Add language feature flags.
+ std::string langFlags;
+ this->AddFeatureFlags(langFlags, linkLanguage);
+
+ this->LocalGenerator->AddArchitectureFlags(langFlags, this->Target,
+ linkLanguage, this->ConfigName);
+
+ // remove any language flags that might not work with the
+ // particular os
+ if(forbiddenFlagVar)
+ {
+ this->RemoveForbiddenFlags(forbiddenFlagVar,
+ linkLanguage, langFlags);
+ }
+ vars.LanguageCompileFlags = langFlags.c_str();
+
+ // Construct the main link rule and expand placeholders.
+ this->LocalGenerator->TargetImplib = targetOutPathImport;
+ if(useArchiveRules)
+ {
+ // Construct the individual object list strings.
+ std::vector<std::string> object_strings;
+ this->WriteObjectsStrings(object_strings, archiveCommandLimit);
+
+ // Create the archive with the first set of objects.
+ std::vector<std::string>::iterator osi = object_strings.begin();
+ {
+ vars.Objects = osi->c_str();
+ for(std::vector<std::string>::const_iterator
+ i = archiveCreateCommands.begin();
+ i != archiveCreateCommands.end(); ++i)
+ {
+ std::string cmd = *i;
+ this->LocalGenerator->ExpandRuleVariables(cmd, vars);
+ real_link_commands.push_back(cmd);
+ }
+ }
+ // Append to the archive with the other object sets.
+ for(++osi; osi != object_strings.end(); ++osi)
+ {
+ vars.Objects = osi->c_str();
+ for(std::vector<std::string>::const_iterator
+ i = archiveAppendCommands.begin();
+ i != archiveAppendCommands.end(); ++i)
+ {
+ std::string cmd = *i;
+ this->LocalGenerator->ExpandRuleVariables(cmd, vars);
+ real_link_commands.push_back(cmd);
+ }
+ }
+ // Finish the archive.
+ vars.Objects = "";
+ for(std::vector<std::string>::const_iterator
+ i = archiveFinishCommands.begin();
+ i != archiveFinishCommands.end(); ++i)
+ {
+ std::string cmd = *i;
+ this->LocalGenerator->ExpandRuleVariables(cmd, vars);
+ real_link_commands.push_back(cmd);
+ }
+ }
+ else
+ {
+ // Get the set of commands.
+ std::string linkRule = this->GetLinkRule(linkRuleVar);
+ cmSystemTools::ExpandListArgument(linkRule, real_link_commands);
+
+ // Expand placeholders.
+ for(std::vector<std::string>::iterator i = real_link_commands.begin();
+ i != real_link_commands.end(); ++i)
+ {
+ this->LocalGenerator->ExpandRuleVariables(*i, vars);
+ }
+ }
+ this->LocalGenerator->TargetImplib = "";
+
+ // Restore path conversion to normal shells.
+ this->LocalGenerator->SetLinkScriptShell(false);
+ }
+
+ // Optionally convert the build rule to use a script to avoid long
+ // command lines in the make shell.
+ if(useLinkScript)
+ {
+ // Use a link script.
+ const char* name = (relink? "relink.txt" : "link.txt");
+ this->CreateLinkScript(name, real_link_commands, commands1, depends);
+ }
+ else
+ {
+ // No link script. Just use the link rule directly.
+ commands1 = real_link_commands;
+ }
+ this->LocalGenerator->CreateCDCommand
+ (commands1,
+ this->Makefile->GetStartOutputDirectory(),
+ cmLocalGenerator::HOME_OUTPUT);
+ commands.insert(commands.end(), commands1.begin(), commands1.end());
+ commands1.clear();
+
+ // Add a rule to create necessary symlinks for the library.
+ if(targetOutPath != targetOutPathReal)
+ {
+ std::string symlink = "$(CMAKE_COMMAND) -E cmake_symlink_library ";
+ symlink += targetOutPathReal;
+ symlink += " ";
+ symlink += targetOutPathSO;
+ symlink += " ";
+ symlink += targetOutPath;
+ commands1.push_back(symlink);
+ this->LocalGenerator->CreateCDCommand(commands1,
+ this->Makefile->GetStartOutputDirectory(),
+ cmLocalGenerator::HOME_OUTPUT);
+ commands.insert(commands.end(), commands1.begin(), commands1.end());
+ commands1.clear();
+ }
+ // Add the post-build rules when building but not when relinking.
+ if(!relink)
+ {
+ this->LocalGenerator->
+ AppendCustomCommands(commands, this->Target->GetPostBuildCommands(),
+ this->Target);
+ }
+
+ // 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;
+ if(targetNameSO != targetNameReal)
+ {
+ this->GenerateExtraOutput(targetFullPathSO.c_str(),
+ targetFullPathReal.c_str());
+ }
+ if(targetName != targetNameSO &&
+ targetName != targetNameReal)
+ {
+ this->GenerateExtraOutput(targetFullPath.c_str(),
+ targetFullPathReal.c_str());
+ }
+
+ // Write the main driver rule to build everything in this target.
+ this->WriteTargetDriverRule(targetFullPath.c_str(), relink);
+
+ // Clean all the possible library names and symlinks.
+ this->CleanFiles.insert(this->CleanFiles.end(),
+ libCleanFiles.begin(),libCleanFiles.end());
+}
+
+//----------------------------------------------------------------------------
+void
+cmMakefileLibraryTargetGenerator
+::AppendOSXVerFlag(std::string& flags, const char* lang,
+ const char* name, bool so)
+{
+ // Lookup the flag to specify the version.
+ std::string fvar = "CMAKE_";
+ fvar += lang;
+ fvar += "_OSX_";
+ fvar += name;
+ fvar += "_VERSION_FLAG";
+ const char* flag = this->Makefile->GetDefinition(fvar.c_str());
+
+ // Skip if no such flag.
+ if(!flag)
+ {
+ return;
+ }
+
+ // Lookup the target version information.
+ int major;
+ int minor;
+ int patch;
+ this->Target->GetTargetVersion(so, major, minor, patch);
+ if(major > 0 || minor > 0 || patch > 0)
+ {
+ // Append the flag since a non-zero version is specified.
+ cmOStringStream vflag;
+ vflag << flag << major << "." << minor << "." << patch;
+ this->LocalGenerator->AppendFlags(flags, vflag.str().c_str());
+ }
+}
diff --git a/Source/cmMakefileLibraryTargetGenerator.h b/Source/cmMakefileLibraryTargetGenerator.h
new file mode 100644
index 000000000..07f828b7d
--- /dev/null
+++ b/Source/cmMakefileLibraryTargetGenerator.h
@@ -0,0 +1,45 @@
+/*============================================================================
+ 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 cmMakefileLibraryTargetGenerator_h
+#define cmMakefileLibraryTargetGenerator_h
+
+#include "cmMakefileTargetGenerator.h"
+
+class cmMakefileLibraryTargetGenerator:
+ public cmMakefileTargetGenerator
+{
+public:
+ cmMakefileLibraryTargetGenerator(cmTarget* target);
+ virtual ~cmMakefileLibraryTargetGenerator();
+
+ /* the main entry point for this class. Writes the Makefiles associated
+ with this target */
+ virtual void WriteRuleFiles();
+
+protected:
+ void WriteObjectLibraryRules();
+ void WriteStaticLibraryRules();
+ void WriteSharedLibraryRules(bool relink);
+ void WriteModuleLibraryRules(bool relink);
+ void WriteLibraryRules(const char *linkRule, const char *extraFlags,
+ bool relink);
+ // MacOSX Framework support methods
+ void WriteFrameworkRules(bool relink);
+
+ // Store the computd framework version for OS X Frameworks.
+ std::string FrameworkVersion;
+
+ void AppendOSXVerFlag(std::string& flags, const char* lang,
+ const char* name, bool so);
+};
+
+#endif
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
new file mode 100644
index 000000000..0de182ede
--- /dev/null
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -0,0 +1,2009 @@
+/*============================================================================
+ 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 "cmMakefileTargetGenerator.h"
+
+#include "cmGeneratorTarget.h"
+#include "cmGeneratedFileStream.h"
+#include "cmGlobalGenerator.h"
+#include "cmGlobalUnixMakefileGenerator3.h"
+#include "cmLocalUnixMakefileGenerator3.h"
+#include "cmMakefile.h"
+#include "cmSourceFile.h"
+#include "cmTarget.h"
+#include "cmake.h"
+#include "cmComputeLinkInformation.h"
+
+#include "cmMakefileExecutableTargetGenerator.h"
+#include "cmMakefileLibraryTargetGenerator.h"
+#include "cmMakefileUtilityTargetGenerator.h"
+
+
+cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmTarget* 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();
+ 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"))
+ {
+ this->NoRuleMessages = cmSystemTools::IsOff(ruleStatus);
+ }
+ MacOSXContentGenerator = new MacOSXContentGeneratorType(this);
+}
+
+cmMakefileTargetGenerator::~cmMakefileTargetGenerator()
+{
+ delete MacOSXContentGenerator;
+}
+
+cmMakefileTargetGenerator *
+cmMakefileTargetGenerator::New(cmTarget *tgt)
+{
+ cmMakefileTargetGenerator *result = 0;
+
+ switch (tgt->GetType())
+ {
+ case cmTarget::EXECUTABLE:
+ result = new cmMakefileExecutableTargetGenerator(tgt);
+ break;
+ case cmTarget::STATIC_LIBRARY:
+ case cmTarget::SHARED_LIBRARY:
+ case cmTarget::MODULE_LIBRARY:
+ case cmTarget::OBJECT_LIBRARY:
+ result = new cmMakefileLibraryTargetGenerator(tgt);
+ break;
+ case cmTarget::UTILITY:
+ result = new cmMakefileUtilityTargetGenerator(tgt);
+ break;
+ default:
+ return result;
+ // break; /* unreachable */
+ }
+ return result;
+}
+
+//----------------------------------------------------------------------------
+void cmMakefileTargetGenerator::CreateRuleFile()
+{
+ // Create a directory for this target.
+ this->TargetBuildDirectory =
+ this->LocalGenerator->GetTargetDirectory(*this->Target);
+ this->TargetBuildDirectoryFull =
+ this->LocalGenerator->ConvertToFullPath(this->TargetBuildDirectory);
+ cmSystemTools::MakeDirectory(this->TargetBuildDirectoryFull.c_str());
+
+ // Construct the rule file name.
+ this->BuildFileName = this->TargetBuildDirectory;
+ this->BuildFileName += "/build.make";
+ this->BuildFileNameFull = this->TargetBuildDirectoryFull;
+ this->BuildFileNameFull += "/build.make";
+
+ // Construct the rule file name.
+ this->ProgressFileNameFull = this->TargetBuildDirectoryFull;
+ this->ProgressFileNameFull += "/progress.make";
+
+ // reset the progress count
+ this->NumberOfProgressActions = 0;
+
+ // Open the rule file. This should be copy-if-different because the
+ // rules may depend on this file itself.
+ this->BuildFileStream =
+ new cmGeneratedFileStream(this->BuildFileNameFull.c_str());
+ this->BuildFileStream->SetCopyIfDifferent(true);
+ if(!this->BuildFileStream)
+ {
+ return;
+ }
+ this->LocalGenerator->WriteDisclaimer(*this->BuildFileStream);
+ this->LocalGenerator->WriteSpecialTargetsTop(*this->BuildFileStream);
+}
+
+//----------------------------------------------------------------------------
+void cmMakefileTargetGenerator::WriteTargetBuildRules()
+{
+ // 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,
+ this->CleanFiles);
+ }
+
+ // add custom commands to the clean rules?
+ const char* clean_no_custom =
+ this->Makefile->GetProperty("CLEAN_NO_CUSTOM");
+ bool clean = cmSystemTools::IsOff(clean_no_custom);
+
+ // 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);
+ if (clean)
+ {
+ const std::vector<std::string>& outputs = cc->GetOutputs();
+ for(std::vector<std::string>::const_iterator o = outputs.begin();
+ o != outputs.end(); ++o)
+ {
+ this->CleanFiles.push_back
+ (this->Convert(o->c_str(),
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::UNCHANGED));
+ }
+ }
+ }
+ this->OSXBundleGenerator->GenerateMacOSXContentStatements(
+ this->GeneratorTarget->HeaderSources,
+ this->MacOSXContentGenerator);
+ this->OSXBundleGenerator->GenerateMacOSXContentStatements(
+ this->GeneratorTarget->ExtraSources,
+ this->MacOSXContentGenerator);
+ for(std::vector<cmSourceFile*>::const_iterator
+ si = this->GeneratorTarget->ExternalObjects.begin();
+ si != this->GeneratorTarget->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)
+ {
+ // Generate this object file's rule file.
+ this->WriteObjectRuleFiles(**si);
+ }
+
+ // Add object library contents as external objects.
+ this->GeneratorTarget->UseObjectLibraries(this->ExternalObjects);
+}
+
+//----------------------------------------------------------------------------
+void cmMakefileTargetGenerator::WriteCommonCodeRules()
+{
+ const char* root = (this->Makefile->IsOn("CMAKE_MAKE_INCLUDE_FROM_ROOT")?
+ "$(CMAKE_BINARY_DIR)/" : "");
+
+ // Include the dependencies for the target.
+ std::string dependFileNameFull = this->TargetBuildDirectoryFull;
+ dependFileNameFull += "/depend.make";
+ *this->BuildFileStream
+ << "# Include any dependencies generated for this target.\n"
+ << this->LocalGenerator->IncludeDirective << " " << root
+ << this->Convert(dependFileNameFull.c_str(),
+ cmLocalGenerator::HOME_OUTPUT,
+ cmLocalGenerator::MAKEFILE)
+ << "\n\n";
+
+ if(!this->NoRuleMessages)
+ {
+ // 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(),
+ cmLocalGenerator::HOME_OUTPUT,
+ cmLocalGenerator::MAKEFILE)
+ << "\n\n";
+ }
+
+ // make sure the depend file exists
+ if (!cmSystemTools::FileExists(dependFileNameFull.c_str()))
+ {
+ // Write an empty dependency file.
+ cmGeneratedFileStream depFileStream(dependFileNameFull.c_str());
+ depFileStream
+ << "# Empty dependencies file for " << this->Target->GetName() << ".\n"
+ << "# This may be replaced when dependencies are built." << std::endl;
+ }
+
+ // Open the flags file. This should be copy-if-different because the
+ // rules may depend on this file itself.
+ this->FlagFileNameFull = this->TargetBuildDirectoryFull;
+ this->FlagFileNameFull += "/flags.make";
+ this->FlagFileStream =
+ new cmGeneratedFileStream(this->FlagFileNameFull.c_str());
+ this->FlagFileStream->SetCopyIfDifferent(true);
+ if(!this->FlagFileStream)
+ {
+ return;
+ }
+ this->LocalGenerator->WriteDisclaimer(*this->FlagFileStream);
+
+ // 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(),
+ cmLocalGenerator::HOME_OUTPUT,
+ cmLocalGenerator::MAKEFILE)
+ << "\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->Target,
+ lang, this->ConfigName);
+
+ // Fortran-specific flags computed for this target.
+ if(l == "Fortran")
+ {
+ this->AddFortranFlags(flags);
+ }
+
+ this->LocalGenerator->AddCMP0018Flags(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());
+
+ 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::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, lang);
+ }
+
+ // Add preprocessor definitions for this target and configuration.
+ this->LocalGenerator->AppendDefines
+ (defines, this->Makefile->GetProperty("COMPILE_DEFINITIONS"), lang);
+ this->LocalGenerator->AppendDefines
+ (defines, this->Target->GetProperty("COMPILE_DEFINITIONS"), lang);
+ std::string defPropName = "COMPILE_DEFINITIONS_";
+ defPropName +=
+ cmSystemTools::UpperCase(this->LocalGenerator->ConfigurationName);
+ this->LocalGenerator->AppendDefines
+ (defines, this->Makefile->GetProperty(defPropName.c_str()), lang);
+ this->LocalGenerator->AppendDefines
+ (defines, this->Target->GetProperty(defPropName.c_str()), lang);
+
+ ByLanguageMap::value_type entry(l, defines);
+ 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
+ // things rebuild
+ for(std::set<cmStdString>::const_iterator l = languages.begin();
+ l != languages.end(); ++l)
+ {
+ cmStdString compiler = "CMAKE_";
+ compiler += *l;
+ compiler += "_COMPILER";
+ *this->FlagFileStream << "# compile " << l->c_str() << " with " <<
+ this->Makefile->GetSafeDefinition(compiler.c_str()) << "\n";
+ }
+
+ for(std::set<cmStdString>::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";
+ }
+
+ // Add target-specific flags.
+ if(this->Target->GetProperty("COMPILE_FLAGS"))
+ {
+ std::string flags;
+ this->LocalGenerator->AppendFlags
+ (flags, this->Target->GetProperty("COMPILE_FLAGS"));
+ *this->FlagFileStream << "# TARGET_FLAGS = " << flags << "\n\n";
+ }
+}
+
+
+//----------------------------------------------------------------------------
+void
+cmMakefileTargetGenerator::MacOSXContentGeneratorType::operator()
+ (cmSourceFile& source, const char* pkgloc)
+{
+ // Skip OS X content when not building a Framework or Bundle.
+ if(this->Generator->MacContentDirectory.empty())
+ {
+ return;
+ }
+
+ std::string macdir =
+ this->Generator->OSXBundleGenerator->InitMacOSXContentDirectory(pkgloc);
+
+ // Get the input file location.
+ std::string input = source.GetFullPath();
+
+ // Get the output file location.
+ std::string output = macdir;
+ output += "/";
+ output += cmSystemTools::GetFilenameName(input);
+ this->Generator->CleanFiles.push_back(
+ this->Generator->Convert(output.c_str(),
+ cmLocalGenerator::START_OUTPUT));
+ output = this->Generator->Convert(output.c_str(),
+ cmLocalGenerator::HOME_OUTPUT);
+
+ // Create a rule to copy the content into the bundle.
+ std::vector<std::string> depends;
+ std::vector<std::string> commands;
+ depends.push_back(input);
+ std::string copyEcho = "Copying OS X content ";
+ copyEcho += output;
+ this->Generator->LocalGenerator->AppendEcho(
+ commands, copyEcho.c_str(),
+ cmLocalUnixMakefileGenerator3::EchoBuild);
+ std::string copyCommand = "$(CMAKE_COMMAND) -E copy ";
+ copyCommand += this->Generator->Convert(input.c_str(),
+ cmLocalGenerator::NONE,
+ cmLocalGenerator::SHELL);
+ copyCommand += " ";
+ copyCommand += this->Generator->Convert(output.c_str(),
+ cmLocalGenerator::NONE,
+ cmLocalGenerator::SHELL);
+ commands.push_back(copyCommand);
+ this->Generator->LocalGenerator->WriteMakeRule(
+ *this->Generator->BuildFileStream, 0,
+ output.c_str(),
+ depends, commands, false);
+ this->Generator->ExtraFiles.insert(output);
+}
+
+//----------------------------------------------------------------------------
+void cmMakefileTargetGenerator::WriteObjectRuleFiles(cmSourceFile& source)
+{
+ // Identify the language of the source file.
+ const char* lang = this->LocalGenerator->GetSourceFileLanguage(source);
+ if(!lang)
+ {
+ // 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);
+ obj += "/";
+ obj += objectName;
+
+ // Avoid generating duplicate rules.
+ if(this->ObjectFiles.find(obj) == this->ObjectFiles.end())
+ {
+ this->ObjectFiles.insert(obj);
+ }
+ else
+ {
+ cmOStringStream err;
+ err << "Warning: Source file \""
+ << source.GetFullPath()
+ << "\" is listed multiple times for target \""
+ << this->Target->GetName()
+ << "\".";
+ cmSystemTools::Message(err.str().c_str(), "Warning");
+ return;
+ }
+
+ // 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());
+ cmSystemTools::MakeDirectory
+ (this->LocalGenerator->ConvertToFullPath(dir).c_str());
+
+ // Save this in the target's list of object files.
+ this->Objects.push_back(obj);
+ this->CleanFiles.push_back(obj);
+
+ // TODO: Remove
+ //std::string relativeObj
+ //= this->LocalGenerator->GetHomeRelativeOutputPath();
+ //relativeObj += obj;
+
+ // we compute some depends when writing the depend.make that we will also
+ // use in the build.make, same with depMakeFile
+ std::vector<std::string> depends;
+ 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();
+ objFullPath += "/";
+ objFullPath += obj;
+ objFullPath =
+ this->Convert(objFullPath.c_str(), cmLocalGenerator::FULL);
+ std::string srcFullPath =
+ this->Convert(source.GetFullPath().c_str(), cmLocalGenerator::FULL);
+ this->LocalGenerator->
+ AddImplicitDepends(*this->Target, lang,
+ objFullPath.c_str(),
+ srcFullPath.c_str());
+}
+
+//----------------------------------------------------------------------------
+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,
+ std::vector<std::string>& depends)
+{
+ this->LocalGenerator->AppendRuleDepend(depends,
+ this->FlagFileNameFull.c_str());
+ this->LocalGenerator->AppendRuleDepends(depends,
+ this->FlagFileDepends[lang]);
+
+ // generate the depend scanning rule
+ this->WriteObjectDependRules(source, depends);
+
+ std::string relativeObj = this->LocalGenerator->GetHomeRelativeOutputPath();
+ relativeObj += obj;
+ // Write the build rule.
+
+ // Build the set of compiler flags.
+ std::string flags;
+
+ // Add language-specific flags.
+ std::string langFlags = "$(";
+ langFlags += lang;
+ langFlags += "_FLAGS)";
+ this->LocalGenerator->AppendFlags(flags, langFlags.c_str());
+
+ // Add target-specific flags.
+ if(this->Target->GetProperty("COMPILE_FLAGS"))
+ {
+ std::string langIncludeExpr = "CMAKE_";
+ langIncludeExpr += lang;
+ langIncludeExpr += "_FLAG_REGEX";
+ const char* regex = this->Makefile->
+ GetDefinition(langIncludeExpr.c_str());
+ if(regex)
+ {
+ cmsys::RegularExpression r(regex);
+ std::vector<std::string> args;
+ cmSystemTools::ParseWindowsCommandLine(
+ this->Target->GetProperty("COMPILE_FLAGS"),
+ args);
+ for(std::vector<std::string>::iterator i = args.begin();
+ i != args.end(); ++i)
+ {
+ if(r.find(i->c_str()))
+ {
+ this->LocalGenerator->AppendFlags
+ (flags, i->c_str());
+ }
+ }
+ }
+ else
+ {
+ this->LocalGenerator->AppendFlags
+ (flags, this->Target->GetProperty("COMPILE_FLAGS"));
+ }
+ }
+
+ // Add Fortran format flags.
+ if(strcmp(lang, "Fortran") == 0)
+ {
+ this->AppendFortranFormatFlags(flags, source);
+ }
+
+ // Add flags from source file properties.
+ if (source.GetProperty("COMPILE_FLAGS"))
+ {
+ this->LocalGenerator->AppendFlags
+ (flags, source.GetProperty("COMPILE_FLAGS"));
+ *this->FlagFileStream << "# Custom flags: "
+ << relativeObj << "_FLAGS = "
+ << source.GetProperty("COMPILE_FLAGS")
+ << "\n"
+ << "\n";
+ }
+
+ // Add language-specific defines.
+ std::string defines = "$(";
+ defines += lang;
+ defines += "_DEFINES)";
+
+ // Add source-sepcific preprocessor definitions.
+ if(const char* compile_defs = source.GetProperty("COMPILE_DEFINITIONS"))
+ {
+ this->LocalGenerator->AppendDefines(defines, compile_defs, lang);
+ *this->FlagFileStream << "# Custom defines: "
+ << relativeObj << "_DEFINES = "
+ << compile_defs << "\n"
+ << "\n";
+ }
+ std::string configUpper =
+ cmSystemTools::UpperCase(this->LocalGenerator->ConfigurationName);
+ std::string defPropName = "COMPILE_DEFINITIONS_";
+ defPropName += configUpper;
+ if(const char* config_compile_defs =
+ source.GetProperty(defPropName.c_str()))
+ {
+ this->LocalGenerator->AppendDefines(defines, config_compile_defs, lang);
+ *this->FlagFileStream
+ << "# Custom defines: "
+ << relativeObj << "_DEFINES_" << configUpper
+ << " = " << config_compile_defs << "\n"
+ << "\n";
+ }
+
+ // 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(),
+ cmLocalGenerator::NONE,
+ cmLocalGenerator::SHELL);
+
+ // Construct the build message.
+ std::vector<std::string> no_commands;
+ std::vector<std::string> commands;
+
+ // add in a progress call if needed
+ this->AppendProgress(commands);
+
+ if(!this->NoRuleMessages)
+ {
+ std::string buildEcho = "Building ";
+ buildEcho += lang;
+ buildEcho += " object ";
+ buildEcho += relativeObj;
+ this->LocalGenerator->AppendEcho
+ (commands, buildEcho.c_str(), cmLocalUnixMakefileGenerator3::EchoBuild);
+ }
+
+ std::string targetOutPathPDB;
+ {
+ 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)
+ {
+ targetFullPathPDB = this->Target->GetDirectory(this->ConfigName);
+ targetFullPathPDB += "/";
+ targetFullPathPDB += this->Target->GetPDBName(this->ConfigName);
+ }
+ targetOutPathPDB =
+ this->Convert(targetFullPathPDB.c_str(),cmLocalGenerator::NONE,
+ cmLocalGenerator::SHELL);
+ }
+ cmLocalGenerator::RuleVariables vars;
+ vars.RuleLauncher = "RULE_LAUNCH_COMPILE";
+ vars.CMTarget = this->Target;
+ vars.Language = lang;
+ vars.TargetPDB = targetOutPathPDB.c_str();
+ vars.Source = sourceFile.c_str();
+ std::string shellObj =
+ this->Convert(obj.c_str(),
+ cmLocalGenerator::NONE,
+ cmLocalGenerator::SHELL).c_str();
+ vars.Object = shellObj.c_str();
+ std::string objectDir = cmSystemTools::GetFilenamePath(obj);
+ objectDir = this->Convert(objectDir.c_str(),
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::SHELL);
+ vars.ObjectDir = objectDir.c_str();
+ vars.Flags = flags.c_str();
+ vars.Defines = defines.c_str();
+
+ bool lang_is_c_or_cxx = ((strcmp(lang, "C") == 0) ||
+ (strcmp(lang, "CXX") == 0));
+
+ // Construct the compile rules.
+ {
+ std::string compileRuleVar = "CMAKE_";
+ compileRuleVar += lang;
+ compileRuleVar += "_COMPILE_OBJECT";
+ std::string compileRule =
+ this->Makefile->GetRequiredDefinition(compileRuleVar.c_str());
+ 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)
+ {
+ std::string compileCommand = compileCommands[0];
+ this->LocalGenerator->ExpandRuleVariables(compileCommand, vars);
+ std::string workingDirectory =
+ this->LocalGenerator->Convert(
+ this->Makefile->GetStartOutputDirectory(), 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));
+ this->GlobalGenerator->AddCXXCompileCommand(
+ source.GetFullPath(), workingDirectory, compileCommand);
+ }
+
+ // Expand placeholders in the commands.
+ for(std::vector<std::string>::iterator i = compileCommands.begin();
+ i != compileCommands.end(); ++i)
+ {
+ this->LocalGenerator->ExpandRuleVariables(*i, vars);
+ }
+
+ // Change the command working directory to the local build tree.
+ this->LocalGenerator->CreateCDCommand
+ (compileCommands,
+ this->Makefile->GetStartOutputDirectory(),
+ 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.
+ 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());
+ }
+ }
+
+ bool do_preprocess_rules = lang_is_c_or_cxx &&
+ this->LocalGenerator->GetCreatePreprocessedSourceRules();
+ bool do_assembly_rules = lang_is_c_or_cxx &&
+ this->LocalGenerator->GetCreateAssemblySourceRules();
+ if(do_preprocess_rules || do_assembly_rules)
+ {
+ std::vector<std::string> force_depends;
+ force_depends.push_back("cmake_force");
+ std::string::size_type dot_pos = relativeObj.rfind(".");
+ std::string relativeObjBase = relativeObj.substr(0, dot_pos);
+ dot_pos = obj.rfind(".");
+ std::string objBase = obj.substr(0, dot_pos);
+
+ if(do_preprocess_rules)
+ {
+ commands.clear();
+ std::string relativeObjI = relativeObjBase + ".i";
+ std::string objI = objBase + ".i";
+
+ std::string preprocessEcho = "Preprocessing ";
+ preprocessEcho += lang;
+ preprocessEcho += " source to ";
+ preprocessEcho += objI;
+ this->LocalGenerator->AppendEcho(
+ commands, preprocessEcho.c_str(),
+ cmLocalUnixMakefileGenerator3::EchoBuild
+ );
+
+ std::string preprocessRuleVar = "CMAKE_";
+ preprocessRuleVar += lang;
+ preprocessRuleVar += "_CREATE_PREPROCESSED_SOURCE";
+ if(const char* preprocessRule =
+ this->Makefile->GetDefinition(preprocessRuleVar.c_str()))
+ {
+ std::vector<std::string> preprocessCommands;
+ cmSystemTools::ExpandListArgument(preprocessRule, preprocessCommands);
+
+ std::string shellObjI =
+ this->Convert(objI.c_str(),
+ cmLocalGenerator::NONE,
+ cmLocalGenerator::SHELL).c_str();
+ vars.PreprocessedSource = shellObjI.c_str();
+
+ // Expand placeholders in the commands.
+ for(std::vector<std::string>::iterator i = preprocessCommands.begin();
+ i != preprocessCommands.end(); ++i)
+ {
+ this->LocalGenerator->ExpandRuleVariables(*i, vars);
+ }
+
+ this->LocalGenerator->CreateCDCommand
+ (preprocessCommands,
+ this->Makefile->GetStartOutputDirectory(),
+ cmLocalGenerator::HOME_OUTPUT);
+ commands.insert(commands.end(),
+ preprocessCommands.begin(),
+ preprocessCommands.end());
+ }
+ else
+ {
+ std::string cmd = "$(CMAKE_COMMAND) -E cmake_unimplemented_variable ";
+ cmd += preprocessRuleVar;
+ commands.push_back(cmd);
+ }
+
+ this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
+ relativeObjI.c_str(),
+ force_depends, commands, false);
+ }
+
+ if(do_assembly_rules)
+ {
+ commands.clear();
+ std::string relativeObjS = relativeObjBase + ".s";
+ std::string objS = objBase + ".s";
+
+ std::string assemblyEcho = "Compiling ";
+ assemblyEcho += lang;
+ assemblyEcho += " source to assembly ";
+ assemblyEcho += objS;
+ this->LocalGenerator->AppendEcho(
+ commands, assemblyEcho.c_str(),
+ cmLocalUnixMakefileGenerator3::EchoBuild
+ );
+
+ std::string assemblyRuleVar = "CMAKE_";
+ assemblyRuleVar += lang;
+ assemblyRuleVar += "_CREATE_ASSEMBLY_SOURCE";
+ if(const char* assemblyRule =
+ this->Makefile->GetDefinition(assemblyRuleVar.c_str()))
+ {
+ std::vector<std::string> assemblyCommands;
+ cmSystemTools::ExpandListArgument(assemblyRule, assemblyCommands);
+
+ std::string shellObjS =
+ this->Convert(objS.c_str(),
+ cmLocalGenerator::NONE,
+ cmLocalGenerator::SHELL).c_str();
+ vars.AssemblySource = shellObjS.c_str();
+
+ // Expand placeholders in the commands.
+ for(std::vector<std::string>::iterator i = assemblyCommands.begin();
+ i != assemblyCommands.end(); ++i)
+ {
+ this->LocalGenerator->ExpandRuleVariables(*i, vars);
+ }
+
+ this->LocalGenerator->CreateCDCommand
+ (assemblyCommands,
+ this->Makefile->GetStartOutputDirectory(),
+ cmLocalGenerator::HOME_OUTPUT);
+ commands.insert(commands.end(),
+ assemblyCommands.begin(),
+ assemblyCommands.end());
+ }
+ else
+ {
+ std::string cmd = "$(CMAKE_COMMAND) -E cmake_unimplemented_variable ";
+ cmd += assemblyRuleVar;
+ commands.push_back(cmd);
+ }
+
+ this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
+ relativeObjS.c_str(),
+ force_depends, commands, false);
+ }
+ }
+
+ // If the language needs provides-requires mode, create the
+ // corresponding targets.
+ std::string objectRequires = relativeObj;
+ objectRequires += ".requires";
+ std::vector<std::string> p_depends;
+ // always provide an empty requires target
+ this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
+ objectRequires.c_str(), p_depends,
+ no_commands, true);
+
+ // write a build rule to recursively build what this obj provides
+ std::string objectProvides = relativeObj;
+ objectProvides += ".provides";
+ std::string temp = relativeObj;
+ temp += ".provides.build";
+ std::vector<std::string> r_commands;
+ std::string tgtMakefileName =
+ this->LocalGenerator->GetRelativeTargetDirectory(*this->Target);
+ tgtMakefileName += "/build.make";
+ r_commands.push_back
+ (this->LocalGenerator->GetRecursiveMakeCall(tgtMakefileName.c_str(),
+ temp.c_str()));
+
+ p_depends.clear();
+ p_depends.push_back(objectRequires);
+ this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
+ objectProvides.c_str(), 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,
+ false);
+}
+
+//----------------------------------------------------------------------------
+void cmMakefileTargetGenerator::WriteTargetRequiresRules()
+{
+ std::vector<std::string> depends;
+ std::vector<std::string> no_commands;
+
+ // Construct the name of the dependency generation target.
+ std::string depTarget =
+ this->LocalGenerator->GetRelativeTargetDirectory(*this->Target);
+ depTarget += "/requires";
+
+ // This target drives dependency generation for all object files.
+ std::string relPath = this->LocalGenerator->GetHomeRelativeOutputPath();
+ std::string objTarget;
+ for(std::vector<std::string>::const_iterator obj = this->Objects.begin();
+ obj != this->Objects.end(); ++obj)
+ {
+ objTarget = relPath;
+ objTarget += *obj;
+ objTarget += ".requires";
+ depends.push_back(objTarget);
+ }
+
+ // Write the rule.
+ this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
+ depTarget.c_str(),
+ depends, no_commands, true);
+}
+
+//----------------------------------------------------------------------------
+void cmMakefileTargetGenerator::WriteTargetCleanRules()
+{
+ std::vector<std::string> depends;
+ std::vector<std::string> commands;
+
+ // Construct the clean target name.
+ std::string cleanTarget =
+ this->LocalGenerator->GetRelativeTargetDirectory(*this->Target);
+ cleanTarget += "/clean";
+
+ // Construct the clean command.
+ this->LocalGenerator->AppendCleanCommand(commands, this->CleanFiles,
+ *this->Target);
+ this->LocalGenerator->CreateCDCommand
+ (commands,
+ this->Makefile->GetStartOutputDirectory(),
+ cmLocalGenerator::HOME_OUTPUT);
+
+ // Write the rule.
+ this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
+ cleanTarget.c_str(),
+ depends, commands, true);
+}
+
+
+//----------------------------------------------------------------------------
+void cmMakefileTargetGenerator::WriteTargetDependRules()
+{
+ // must write the targets depend info file
+ std::string dir = this->LocalGenerator->GetTargetDirectory(*this->Target);
+ this->InfoFileNameFull = dir;
+ this->InfoFileNameFull += "/DependInfo.cmake";
+ this->InfoFileNameFull =
+ this->LocalGenerator->ConvertToFullPath(this->InfoFileNameFull);
+ this->InfoFileStream =
+ new cmGeneratedFileStream(this->InfoFileNameFull.c_str());
+ this->InfoFileStream->SetCopyIfDifferent(true);
+ if(!*this->InfoFileStream)
+ {
+ return;
+ }
+ this->LocalGenerator->
+ WriteDependLanguageInfo(*this->InfoFileStream,*this->Target);
+
+ // Store multiple output pairs in the depend info file.
+ if(!this->MultipleOutputPairs.empty())
+ {
+ *this->InfoFileStream
+ << "\n"
+ << "# Pairs of files generated by the same build rule.\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())
+ << "\n";
+ }
+ *this->InfoFileStream << " )\n\n";
+ }
+
+ // Store list of targets linked directly or transitively.
+ {
+ *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";
+ }
+ }
+ }
+ *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;
+ this->LocalGenerator->GetIncludeDirectories(includes, this->Target);
+ 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";
+
+ // and now write the rule to use it
+ std::vector<std::string> depends;
+ std::vector<std::string> commands;
+
+ // Construct the name of the dependency generation target.
+ std::string depTarget =
+ this->LocalGenerator->GetRelativeTargetDirectory(*this->Target);
+ depTarget += "/depend";
+
+ // Add a command to call CMake to scan dependencies. CMake will
+ // touch the corresponding depends file after scanning dependencies.
+ cmOStringStream depCmd;
+ // TODO: Account for source file properties and directory-level
+ // definitions when scanning for dependencies.
+#if !defined(_WIN32) || defined(__CYGWIN__)
+ // This platform supports symlinks, so cmSystemTools will translate
+ // paths. Make sure PWD is set to the original name of the home
+ // output directory to help cmSystemTools to create the same
+ // translation table for the dependency scanning process.
+ depCmd << "cd "
+ << (this->LocalGenerator->Convert(
+ this->Makefile->GetHomeOutputDirectory(),
+ cmLocalGenerator::FULL, cmLocalGenerator::SHELL))
+ << " && ";
+#endif
+ // Generate a call this signature:
+ //
+ // cmake -E cmake_depends <generator>
+ // <home-src-dir> <start-src-dir>
+ // <home-out-dir> <start-out-dir>
+ // <dep-info> --color=$(COLOR)
+ //
+ // This gives the dependency scanner enough information to recreate
+ // the state of our local generator sufficiently for its needs.
+ depCmd << "$(CMAKE_COMMAND) -E cmake_depends \""
+ << this->GlobalGenerator->GetName() << "\" "
+ << this->Convert(this->Makefile->GetHomeDirectory(),
+ cmLocalGenerator::FULL, cmLocalGenerator::SHELL)
+ << " "
+ << this->Convert(this->Makefile->GetStartDirectory(),
+ cmLocalGenerator::FULL, cmLocalGenerator::SHELL)
+ << " "
+ << this->Convert(this->Makefile->GetHomeOutputDirectory(),
+ cmLocalGenerator::FULL, cmLocalGenerator::SHELL)
+ << " "
+ << this->Convert(this->Makefile->GetStartOutputDirectory(),
+ cmLocalGenerator::FULL, cmLocalGenerator::SHELL)
+ << " "
+ << this->Convert(this->InfoFileNameFull.c_str(),
+ cmLocalGenerator::FULL, cmLocalGenerator::SHELL);
+ if(this->LocalGenerator->GetColorMakefile())
+ {
+ depCmd << " --color=$(COLOR)";
+ }
+ commands.push_back(depCmd.str());
+
+ // Make sure all custom command outputs in this target are built.
+ if(this->CustomCommandDriver == OnDepends)
+ {
+ this->DriveCustomCommands(depends);
+ }
+
+ // Write the rule.
+ this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
+ depTarget.c_str(),
+ depends, commands, true);
+}
+
+//----------------------------------------------------------------------------
+void
+cmMakefileTargetGenerator
+::DriveCustomCommands(std::vector<std::string>& depends)
+{
+ // Depend on all custom command outputs.
+ const std::vector<cmSourceFile*>& sources =
+ this->Target->GetSourceFiles();
+ 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);
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmMakefileTargetGenerator
+::WriteObjectDependRules(cmSourceFile& source,
+ std::vector<std::string>& depends)
+{
+ // Create the list of dependencies known at cmake time. These are
+ // shared between the object file and dependency scanning rule.
+ 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());
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmMakefileTargetGenerator
+::GenerateCustomRuleFile(const cmCustomCommand& cc)
+{
+ // Collect the commands.
+ std::vector<std::string> commands;
+ std::string comment = this->LocalGenerator->ConstructComment(cc);
+ if(!comment.empty())
+ {
+ // add in a progress call if needed
+ this->AppendProgress(commands);
+ if(!this->NoRuleMessages)
+ {
+ this->LocalGenerator
+ ->AppendEcho(commands, comment.c_str(),
+ cmLocalUnixMakefileGenerator3::EchoGenerate);
+ }
+ }
+
+ // Now append the actual user-specified commands.
+ cmOStringStream content;
+ this->LocalGenerator->AppendCustomCommand(commands, cc, this->Target, 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();
+
+ // 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);
+
+ // 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);
+ }
+
+ // Setup implicit dependency scanning.
+ for(cmCustomCommand::ImplicitDependsList::const_iterator
+ idi = cc.GetImplicitDepends().begin();
+ idi != cc.GetImplicitDepends().end(); ++idi)
+ {
+ std::string objFullPath =
+ this->Convert(outputs[0].c_str(), cmLocalGenerator::FULL);
+ std::string srcFullPath =
+ this->Convert(idi->second.c_str(), cmLocalGenerator::FULL);
+ this->LocalGenerator->
+ AddImplicitDepends(*this->Target, idi->first.c_str(),
+ objFullPath.c_str(),
+ srcFullPath.c_str());
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmMakefileTargetGenerator
+::GenerateExtraOutput(const char* out, const char* in, bool symbolic)
+{
+ // 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());
+}
+
+//----------------------------------------------------------------------------
+void
+cmMakefileTargetGenerator
+::WriteObjectsVariable(std::string& variableName,
+ std::string& variableNameExternal)
+{
+ // Write a make variable assignment that lists all objects for the
+ // target.
+ variableName =
+ this->LocalGenerator->CreateMakeVariable(this->Target->GetName(),
+ "_OBJECTS");
+ *this->BuildFileStream
+ << "# Object files for target " << this->Target->GetName() << "\n"
+ << variableName.c_str() << " =";
+ 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)
+ {
+ lineContinue = "\\";
+ }
+ for(std::vector<std::string>::const_iterator i = this->Objects.begin();
+ 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 << "\n";
+
+ // Write a make variable assignment that lists all external objects
+ // for the target.
+ variableNameExternal =
+ this->LocalGenerator->CreateMakeVariable(this->Target->GetName(),
+ "_EXTERNAL_OBJECTS");
+ *this->BuildFileStream
+ << "\n"
+ << "# External object files for target "
+ << this->Target->GetName() << "\n"
+ << variableNameExternal.c_str() << " =";
+ 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);
+ *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 << "\n" << "\n";
+}
+
+//----------------------------------------------------------------------------
+void
+cmMakefileTargetGenerator
+::WriteObjectsString(std::string& buildObjs)
+{
+ std::vector<std::string> objStrings;
+ this->WriteObjectsStrings(objStrings);
+ buildObjs = objStrings[0];
+}
+
+//----------------------------------------------------------------------------
+class cmMakefileTargetGeneratorObjectStrings
+{
+public:
+ cmMakefileTargetGeneratorObjectStrings(std::vector<std::string>& strings,
+ cmLocalUnixMakefileGenerator3* lg,
+ std::string::size_type limit):
+ Strings(strings), LocalGenerator(lg), LengthLimit(limit)
+ {
+ this->Space = "";
+ }
+ void Feed(std::string const& obj)
+ {
+ // Construct the name of the next object.
+ this->NextObject =
+ this->LocalGenerator->Convert(obj.c_str(),
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::RESPONSE);
+
+ // Roll over to next string if the limit will be exceeded.
+ if(this->LengthLimit != std::string::npos &&
+ (this->CurrentString.length() + 1 + this->NextObject.length()
+ > this->LengthLimit))
+ {
+ this->Strings.push_back(this->CurrentString);
+ this->CurrentString = "";
+ this->Space = "";
+ }
+
+ // Separate from previous object.
+ this->CurrentString += this->Space;
+ this->Space = " ";
+
+ // Append this object.
+ this->CurrentString += this->NextObject;
+ }
+ void Done()
+ {
+ this->Strings.push_back(this->CurrentString);
+ }
+private:
+ std::vector<std::string>& Strings;
+ cmLocalUnixMakefileGenerator3* LocalGenerator;
+ std::string::size_type LengthLimit;
+ std::string CurrentString;
+ std::string NextObject;
+ const char* Space;
+};
+
+//----------------------------------------------------------------------------
+void
+cmMakefileTargetGenerator
+::WriteObjectsStrings(std::vector<std::string>& objStrings,
+ std::string::size_type limit)
+{
+ cmMakefileTargetGeneratorObjectStrings
+ helper(objStrings, this->LocalGenerator, limit);
+ for(std::vector<std::string>::const_iterator i = this->Objects.begin();
+ i != this->Objects.end(); ++i)
+ {
+ helper.Feed(*i);
+ }
+ for(std::vector<std::string>::const_iterator i =
+ this->ExternalObjects.begin();
+ i != this->ExternalObjects.end(); ++i)
+ {
+ helper.Feed(*i);
+ }
+ helper.Done();
+}
+
+//----------------------------------------------------------------------------
+void cmMakefileTargetGenerator::WriteTargetDriverRule(const char* main_output,
+ bool relink)
+{
+ // Compute the name of the driver target.
+ std::string dir =
+ this->LocalGenerator->GetRelativeTargetDirectory(*this->Target);
+ std::string buildTargetRuleName = dir;
+ buildTargetRuleName += relink?"/preinstall":"/build";
+ buildTargetRuleName = this->Convert(buildTargetRuleName.c_str(),
+ 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);
+ }
+
+ const char* comment = 0;
+ if(relink)
+ {
+ // Setup the comment for the preinstall driver.
+ comment = "Rule to relink during preinstall.";
+ }
+ else
+ {
+ // Setup the comment for the main build driver.
+ comment = "Rule to build all files generated by this target.";
+
+ // Make sure all custom command outputs in this target are built.
+ if(this->CustomCommandDriver == OnBuild)
+ {
+ this->DriveCustomCommands(depends);
+ }
+
+ // 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);
+ }
+ }
+
+ // Write the driver rule.
+ std::vector<std::string> no_commands;
+ this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, comment,
+ buildTargetRuleName.c_str(),
+ 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;
+ this->LocalGenerator->GetIncludeDirectories(includes, this->Target);
+ std::vector<std::string>::iterator i;
+ // check all include directories for frameworks as this
+ // will already have added a -F for the framework
+ for(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;
+ std::vector<std::string>& frameworks = this->Target->GetFrameworks();
+ for(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)
+ {
+ return;
+ }
+
+ // Loop over all library dependencies.
+ const char* cfg = this->LocalGenerator->ConfigurationName.c_str();
+ if(cmComputeLinkInformation* cli = this->Target->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);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmMakefileTargetGenerator
+::AppendObjectDepends(std::vector<std::string>& depends)
+{
+ // Add dependencies on the compiled object files.
+ std::string relPath = this->LocalGenerator->GetHomeRelativeOutputPath();
+ std::string objTarget;
+ for(std::vector<std::string>::const_iterator obj = this->Objects.begin();
+ obj != this->Objects.end(); ++obj)
+ {
+ objTarget = relPath;
+ objTarget += *obj;
+ depends.push_back(objTarget);
+ }
+
+ // 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);
+ }
+
+ // Add a dependency on the rule file itself.
+ this->LocalGenerator->AppendRuleDepend(depends,
+ this->BuildFileNameFull.c_str());
+}
+
+//----------------------------------------------------------------------------
+void cmMakefileTargetGenerator
+::AppendLinkDepends(std::vector<std::string>& depends)
+{
+ this->AppendObjectDepends(depends);
+
+ // Add dependencies on targets that must be built first.
+ this->AppendTargetDepends(depends);
+
+ // Add a dependency on the link definitions file, if any.
+ if(!this->GeneratorTarget->ModuleDefinitionFile.empty())
+ {
+ depends.push_back(this->GeneratorTarget->ModuleDefinitionFile);
+ }
+
+ // Add user-specified dependencies.
+ if(const char* linkDepends =
+ this->Target->GetProperty("LINK_DEPENDS"))
+ {
+ cmSystemTools::ExpandListArgument(linkDepends, depends);
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string cmMakefileTargetGenerator::GetLinkRule(const char* linkRuleVar)
+{
+ std::string linkRule = this->Makefile->GetRequiredDefinition(linkRuleVar);
+ if(this->Target->HasImplibGNUtoMS())
+ {
+ std::string ruleVar = "CMAKE_";
+ ruleVar += this->Target->GetLinkerLanguage(this->ConfigName);
+ ruleVar += "_GNUtoMS_RULE";
+ if(const char* rule = this->Makefile->GetDefinition(ruleVar.c_str()))
+ {
+ linkRule += rule;
+ }
+ }
+ return linkRule;
+}
+
+//----------------------------------------------------------------------------
+void cmMakefileTargetGenerator
+::CloseFileStreams()
+{
+ delete this->BuildFileStream;
+ delete this->InfoFileStream;
+ delete this->FlagFileStream;
+}
+
+void cmMakefileTargetGenerator::RemoveForbiddenFlags(const char* flagVar,
+ const char* 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
+ // which fails, there may be more]
+
+ std::string removeFlags = "CMAKE_";
+ removeFlags += linkLang;
+ removeFlags += flagVar;
+ std::string removeflags =
+ this->Makefile->GetSafeDefinition(removeFlags.c_str());
+ 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(), "");
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmMakefileTargetGenerator
+::AddMultipleOutputPair(const char* depender, const char* dependee)
+{
+ MultipleOutputPairsType::value_type p(depender, dependee);
+ this->MultipleOutputPairs.insert(p);
+}
+
+//----------------------------------------------------------------------------
+void
+cmMakefileTargetGenerator
+::CreateLinkScript(const char* name,
+ std::vector<std::string> const& link_commands,
+ std::vector<std::string>& makefile_commands,
+ std::vector<std::string>& makefile_depends)
+{
+ // Create the link script file.
+ std::string linkScriptName = this->TargetBuildDirectoryFull;
+ linkScriptName += "/";
+ linkScriptName += name;
+ cmGeneratedFileStream linkScriptStream(linkScriptName.c_str());
+ linkScriptStream.SetCopyIfDifferent(true);
+ for(std::vector<std::string>::const_iterator cmd = link_commands.begin();
+ cmd != link_commands.end(); ++cmd)
+ {
+ // Do not write out empty commands or commands beginning in the
+ // shell no-op ":".
+ if(!cmd->empty() && (*cmd)[0] != ':')
+ {
+ linkScriptStream << *cmd << "\n";
+ }
+ }
+
+ // 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(),
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::SHELL);
+ link_command += " --verbose=$(VERBOSE)";
+ makefile_commands.push_back(link_command);
+ makefile_depends.push_back(linkScriptName);
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmMakefileTargetGenerator
+::CreateResponseFile(const char* name, std::string const& options,
+ std::vector<std::string>& makefile_depends)
+{
+ // Create the response file.
+ std::string responseFileNameFull = this->TargetBuildDirectoryFull;
+ responseFileNameFull += "/";
+ responseFileNameFull += name;
+ cmGeneratedFileStream responseStream(responseFileNameFull.c_str());
+ responseStream.SetCopyIfDifferent(true);
+ responseStream << options << "\n";
+
+ // Add a dependency so the target will rebuild when the set of
+ // objects changes.
+ makefile_depends.push_back(responseFileNameFull);
+
+ // Construct the name to be used on the command line.
+ std::string responseFileName = this->TargetBuildDirectory;
+ responseFileName += "/";
+ responseFileName += name;
+ return responseFileName;
+}
+
+//----------------------------------------------------------------------------
+void
+cmMakefileTargetGenerator
+::CreateObjectLists(bool useLinkScript, bool useArchiveRules,
+ bool useResponseFile, std::string& buildObjs,
+ std::vector<std::string>& makefile_depends)
+{
+ std::string variableName;
+ std::string variableNameExternal;
+ this->WriteObjectsVariable(variableName, variableNameExternal);
+ if(useResponseFile)
+ {
+ // MSVC response files cannot exceed 128K.
+ std::string::size_type const responseFileLimit = 131000;
+
+ // Construct the individual object list strings.
+ std::vector<std::string> object_strings;
+ this->WriteObjectsStrings(object_strings, responseFileLimit);
+
+ // Lookup the response file reference flag.
+ std::string responseFlagVar = "CMAKE_";
+ responseFlagVar += this->Target->GetLinkerLanguage(this->ConfigName);
+ responseFlagVar += "_RESPONSE_FILE_LINK_FLAG";
+ const char* responseFlag =
+ this->Makefile->GetDefinition(responseFlagVar.c_str());
+ if(!responseFlag)
+ {
+ responseFlag = "@";
+ }
+
+ // Write a response file for each string.
+ const char* sep = "";
+ for(unsigned int i = 0; i < object_strings.size(); ++i)
+ {
+ // Number the response files.
+ char rsp[32];
+ sprintf(rsp, "objects%u.rsp", i+1);
+
+ // Create this response file.
+ std::string objects_rsp =
+ this->CreateResponseFile(rsp, object_strings[i], makefile_depends);
+
+ // Separate from previous response file references.
+ buildObjs += sep;
+ sep = " ";
+
+ // Reference the response file.
+ buildObjs += responseFlag;
+ buildObjs += this->Convert(objects_rsp.c_str(),
+ cmLocalGenerator::NONE,
+ cmLocalGenerator::SHELL);
+ }
+ }
+ else if(useLinkScript)
+ {
+ if(!useArchiveRules)
+ {
+ this->WriteObjectsString(buildObjs);
+ }
+ }
+ else
+ {
+ buildObjs = "$(";
+ buildObjs += variableName;
+ buildObjs += ") $(";
+ buildObjs += variableNameExternal;
+ buildObjs += ")";
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmMakefileTargetGenerator::AddIncludeFlags(std::string& flags,
+ const char* lang)
+{
+ std::string responseVar = "CMAKE_";
+ responseVar += lang;
+ responseVar += "_USE_RESPONSE_FILE_FOR_INCLUDES";
+ bool useResponseFile = this->Makefile->IsOn(responseVar.c_str());
+
+
+ std::vector<std::string> includes;
+ this->LocalGenerator->GetIncludeDirectories(includes, this->Target, lang);
+
+ std::string includeFlags =
+ this->LocalGenerator->GetIncludeFlags(includes, lang, useResponseFile);
+ if(includeFlags.empty())
+ {
+ return;
+ }
+
+ if(useResponseFile)
+ {
+ std::string name = "includes_";
+ name += lang;
+ name += ".rsp";
+ std::string arg = "@" +
+ this->CreateResponseFile(name.c_str(), includeFlags,
+ this->FlagFileDepends[lang]);
+ this->LocalGenerator->AppendFlags(flags, arg.c_str());
+ }
+ 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;
+ this->LocalGenerator->GetIncludeDirectories(includes, this->Target);
+ 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");
+ }
+}
diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h
new file mode 100644
index 000000000..2798e5462
--- /dev/null
+++ b/Source/cmMakefileTargetGenerator.h
@@ -0,0 +1,279 @@
+/*============================================================================
+ 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 cmMakefileTargetGenerator_h
+#define cmMakefileTargetGenerator_h
+
+#include "cmLocalUnixMakefileGenerator3.h"
+#include "cmOSXBundleGenerator.h"
+
+class cmCustomCommand;
+class cmDependInformation;
+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
+{
+public:
+ // constructor to set the ivars
+ cmMakefileTargetGenerator(cmTarget* target);
+ virtual ~cmMakefileTargetGenerator();
+
+ // construct using this factory call
+ static cmMakefileTargetGenerator *New(cmTarget *tgt);
+
+ /* the main entry point for this class. Writes the Makefiles associated
+ with this target */
+ virtual void WriteRuleFiles() = 0;
+
+ /* return the number of actions that have progress reporting on them */
+ virtual unsigned long GetNumberOfProgressActions() {
+ return this->NumberOfProgressActions;}
+ std::string GetProgressFileNameFull()
+ { return this->ProgressFileNameFull; }
+
+ cmTarget* GetTarget() { return this->Target;}
+
+protected:
+
+ // create the file and directory etc
+ void CreateRuleFile();
+
+ // outputs the rules for object files and custom commands used by
+ // this target
+ void WriteTargetBuildRules();
+
+ // write some common code at the top of build.make
+ void WriteCommonCodeRules();
+ void WriteTargetLanguageFlags();
+
+ // write the provide require rules for this target
+ void WriteTargetRequiresRules();
+
+ // write the clean rules for this target
+ void WriteTargetCleanRules();
+
+ // write the depend rules for this target
+ void WriteTargetDependRules();
+
+ // write rules for Mac OS X Application Bundle content.
+ struct MacOSXContentGeneratorType :
+ cmOSXBundleGenerator::MacOSXContentGeneratorType
+ {
+ MacOSXContentGeneratorType(cmMakefileTargetGenerator* gen) :
+ Generator(gen) {}
+
+ void operator()(cmSourceFile& source, const char* pkgloc);
+
+ private:
+ cmMakefileTargetGenerator* Generator;
+ };
+ friend struct MacOSXContentGeneratorType;
+
+ // write the rules for an object
+ void WriteObjectRuleFiles(cmSourceFile& source);
+
+ // write the build rule for an object
+ void WriteObjectBuildFile(std::string &obj,
+ const char *lang,
+ cmSourceFile& source,
+ std::vector<std::string>& depends);
+
+ // write the depend.make file for an object
+ void WriteObjectDependRules(cmSourceFile& source,
+ std::vector<std::string>& depends);
+
+ // write the build rule for a custom command
+ void GenerateCustomRuleFile(const cmCustomCommand& cc);
+
+ // 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);
+
+ // write out the variable that lists the objects for this target
+ void WriteObjectsVariable(std::string& variableName,
+ std::string& variableNameExternal);
+ 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 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);
+
+ // Append object file dependencies.
+ void AppendObjectDepends(std::vector<std::string>& depends);
+
+ // Append link rule dependencies (objects, etc.).
+ 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);
+
+ /** Create a script to hold link rules and a command to invoke the
+ script at build time. */
+ void CreateLinkScript(const char* name,
+ std::vector<std::string> const& link_commands,
+ std::vector<std::string>& makefile_commands,
+ std::vector<std::string>& makefile_depends);
+
+ /** Create a response file with the given set of options. Returns
+ the relative path from the target build working directory to the
+ response file name. */
+ std::string CreateResponseFile(const char* name,
+ std::string const& options,
+ std::vector<std::string>& makefile_depends);
+
+ /** 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);
+
+ void AddIncludeFlags(std::string& flags, const char* lang);
+
+ virtual void CloseFileStreams();
+ void RemoveForbiddenFlags(const char* flagVar, const char* linkLang,
+ std::string& linkFlags);
+ cmTarget *Target;
+ cmGeneratorTarget* GeneratorTarget;
+ cmLocalUnixMakefileGenerator3 *LocalGenerator;
+ cmGlobalUnixMakefileGenerator3 *GlobalGenerator;
+ cmMakefile *Makefile;
+ const char *ConfigName;
+
+ enum CustomCommandDriveType { OnBuild, OnDepends, OnUtility };
+ CustomCommandDriveType CustomCommandDriver;
+
+ // the full path to the build file
+ std::string BuildFileName;
+ std::string BuildFileNameFull;
+
+ // the full path to the progress file
+ std::string ProgressFileNameFull;
+ unsigned long NumberOfProgressActions;
+ bool NoRuleMessages;
+
+ // the path to the directory the build file is in
+ std::string TargetBuildDirectory;
+ std::string TargetBuildDirectoryFull;
+
+ // the stream for the build file
+ cmGeneratedFileStream *BuildFileStream;
+
+ // the stream for the flag file
+ std::string FlagFileNameFull;
+ cmGeneratedFileStream *FlagFileStream;
+ class StringList: public std::vector<std::string> {};
+ std::map<cmStdString, StringList> FlagFileDepends;
+
+ // the stream for the info file
+ std::string InfoFileNameFull;
+ cmGeneratedFileStream *InfoFileStream;
+
+ // files to clean
+ std::vector<std::string> CleanFiles;
+
+ // objects used by this target
+ std::vector<std::string> Objects;
+ std::vector<std::string> ExternalObjects;
+
+ // Set of object file names that will be built in this directory.
+ std::set<cmStdString> ObjectFiles;
+
+ // Set of extra output files to be driven by the build.
+ std::set<cmStdString> ExtraFiles;
+
+ typedef std::map<cmStdString, cmStdString> MultipleOutputPairsType;
+ MultipleOutputPairsType MultipleOutputPairs;
+
+ // Target name info.
+ std::string TargetNameOut;
+ std::string TargetNameSO;
+ std::string TargetNameReal;
+ std::string TargetNameImport;
+ std::string TargetNamePDB;
+
+ // Mac OS X content info.
+ std::string MacContentDirectory;
+ std::set<cmStdString> 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
new file mode 100644
index 000000000..4456aa794
--- /dev/null
+++ b/Source/cmMakefileUtilityTargetGenerator.cxx
@@ -0,0 +1,123 @@
+/*============================================================================
+ 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 "cmMakefileUtilityTargetGenerator.h"
+
+#include "cmGeneratedFileStream.h"
+#include "cmGlobalUnixMakefileGenerator3.h"
+#include "cmLocalUnixMakefileGenerator3.h"
+#include "cmMakefile.h"
+#include "cmSourceFile.h"
+#include "cmTarget.h"
+
+//----------------------------------------------------------------------------
+cmMakefileUtilityTargetGenerator
+::cmMakefileUtilityTargetGenerator(cmTarget* target):
+ cmMakefileTargetGenerator(target)
+{
+ this->CustomCommandDriver = OnUtility;
+ this->OSXBundleGenerator = new cmOSXBundleGenerator(this->Target,
+ this->TargetNameOut,
+ this->ConfigName);
+ this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
+ this->MacContentDirectory =
+ this->OSXBundleGenerator->GetMacContentDirectory();
+}
+
+//----------------------------------------------------------------------------
+cmMakefileUtilityTargetGenerator
+::~cmMakefileUtilityTargetGenerator()
+{
+ delete this->OSXBundleGenerator;
+}
+
+//----------------------------------------------------------------------------
+void cmMakefileUtilityTargetGenerator::WriteRuleFiles()
+{
+ this->CreateRuleFile();
+
+ *this->BuildFileStream
+ << "# Utility rule file for " << this->Target->GetName() << ".\n\n";
+
+ if(!this->NoRuleMessages)
+ {
+ const char* root = (this->Makefile->IsOn("CMAKE_MAKE_INCLUDE_FROM_ROOT")?
+ "$(CMAKE_BINARY_DIR)/" : "");
+ // 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(),
+ cmLocalGenerator::HOME_OUTPUT,
+ cmLocalGenerator::MAKEFILE)
+ << "\n\n";
+ }
+
+ // write the custom commands for this target
+ this->WriteTargetBuildRules();
+
+ // Collect the commands and dependencies.
+ std::vector<std::string> commands;
+ std::vector<std::string> depends;
+
+ // Utility targets store their rules in pre- and post-build commands.
+ this->LocalGenerator->AppendCustomDepends
+ (depends, this->Target->GetPreBuildCommands());
+
+ this->LocalGenerator->AppendCustomDepends
+ (depends, this->Target->GetPostBuildCommands());
+
+ this->LocalGenerator->AppendCustomCommands
+ (commands, this->Target->GetPreBuildCommands(), this->Target);
+
+ // Depend on all custom command outputs for sources
+ this->DriveCustomCommands(depends);
+
+ this->LocalGenerator->AppendCustomCommands
+ (commands, this->Target->GetPostBuildCommands(), this->Target);
+
+ // Add dependencies on targets that must be built first.
+ this->AppendTargetDepends(depends);
+
+ // Add a dependency on the rule file itself.
+ this->LocalGenerator->AppendRuleDepend(depends,
+ this->BuildFileNameFull.c_str());
+
+ // If the rule is empty add the special empty rule dependency needed
+ // by some make tools.
+ if(depends.empty() && commands.empty())
+ {
+ std::string hack = this->GlobalGenerator->GetEmptyRuleHackDepends();
+ if(!hack.empty())
+ {
+ depends.push_back(hack);
+ }
+ }
+
+ // Write the rule.
+ this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
+ this->Target->GetName(),
+ depends, commands, true);
+
+ // Write the main driver rule to build everything in this target.
+ this->WriteTargetDriverRule(this->Target->GetName(), false);
+
+ // Write clean target
+ this->WriteTargetCleanRules();
+
+ // Write the dependency generation rule. This must be done last so
+ // that multiple output pair information is available.
+ this->WriteTargetDependRules();
+
+ // close the streams
+ this->CloseFileStreams();
+}
+
diff --git a/Source/cmMakefileUtilityTargetGenerator.h b/Source/cmMakefileUtilityTargetGenerator.h
new file mode 100644
index 000000000..fc47b3891
--- /dev/null
+++ b/Source/cmMakefileUtilityTargetGenerator.h
@@ -0,0 +1,32 @@
+/*============================================================================
+ 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 cmMakefileUtilityTargetGenerator_h
+#define cmMakefileUtilityTargetGenerator_h
+
+#include "cmMakefileTargetGenerator.h"
+
+class cmMakefileUtilityTargetGenerator:
+ public cmMakefileTargetGenerator
+{
+public:
+ cmMakefileUtilityTargetGenerator(cmTarget* target);
+ virtual ~cmMakefileUtilityTargetGenerator();
+
+ /* the main entry point for this class. Writes the Makefiles associated
+ with this target */
+ virtual void WriteRuleFiles();
+
+protected:
+
+};
+
+#endif
diff --git a/Source/cmMarkAsAdvancedCommand.cxx b/Source/cmMarkAsAdvancedCommand.cxx
new file mode 100644
index 000000000..a80f7ecd6
--- /dev/null
+++ b/Source/cmMarkAsAdvancedCommand.cxx
@@ -0,0 +1,62 @@
+/*============================================================================
+ 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 "cmMarkAsAdvancedCommand.h"
+
+// cmMarkAsAdvancedCommand
+bool cmMarkAsAdvancedCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 1 )
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ unsigned int i =0;
+ const char* value = "1";
+ bool overwrite = false;
+ if(args[0] == "CLEAR" || args[0] == "FORCE")
+ {
+ overwrite = true;
+ if(args[0] == "CLEAR")
+ {
+ value = "0";
+ }
+ i = 1;
+ }
+ 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() )
+ {
+ this->Makefile->GetCacheManager()
+ ->AddCacheEntry(variable.c_str(), 0, 0,
+ cmCacheManager::UNINITIALIZED);
+ overwrite = true;
+ }
+ it.Find(variable.c_str());
+ if ( it.IsAtEnd() )
+ {
+ cmSystemTools::Error("This should never happen...");
+ return false;
+ }
+ if ( !it.PropertyExists("ADVANCED") || overwrite )
+ {
+ it.SetProperty("ADVANCED", value);
+ }
+ }
+ return true;
+}
+
diff --git a/Source/cmMarkAsAdvancedCommand.h b/Source/cmMarkAsAdvancedCommand.h
new file mode 100644
index 000000000..3658dbbd3
--- /dev/null
+++ b/Source/cmMarkAsAdvancedCommand.h
@@ -0,0 +1,85 @@
+/*============================================================================
+ 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 cmMarkAsAdvancedCommand_h
+#define cmMarkAsAdvancedCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmMarkAsAdvancedCommand
+ * \brief mark_as_advanced command
+ *
+ * cmMarkAsAdvancedCommand implements the mark_as_advanced CMake command
+ */
+class cmMarkAsAdvancedCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmMarkAsAdvancedCommand;
+ }
+
+ /**
+ * 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 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.";
+ }
+
+ /**
+ * This determines if the command is invoked when in script mode.
+ * mark_as_advanced() will have no effect in script mode, but this will
+ * make many of the modules usable in cmake/ctest scripts, (among them
+ * FindUnixMake.cmake used by the CTEST_BUILD command.
+ */
+ virtual bool IsScriptable() const { return true; }
+
+ cmTypeMacro(cmMarkAsAdvancedCommand, cmCommand);
+};
+
+
+
+#endif
diff --git a/Source/cmMathCommand.cxx b/Source/cmMathCommand.cxx
new file mode 100644
index 000000000..3c1129d04
--- /dev/null
+++ b/Source/cmMathCommand.cxx
@@ -0,0 +1,61 @@
+/*============================================================================
+ 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 "cmMathCommand.h"
+
+#include "cmExprParserHelper.h"
+
+//----------------------------------------------------------------------------
+bool cmMathCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if ( args.size() < 1 )
+ {
+ this->SetError("must be called with at least one argument.");
+ return false;
+ }
+ const std::string &subCommand = args[0];
+ if(subCommand == "EXPR")
+ {
+ return this->HandleExprCommand(args);
+ }
+ std::string e = "does not recognize sub-command "+subCommand;
+ this->SetError(e.c_str());
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmMathCommand::HandleExprCommand(std::vector<std::string> const& args)
+{
+ if ( args.size() != 3 )
+ {
+ this->SetError("EXPR called with incorrect arguments.");
+ return false;
+ }
+
+ const std::string& outputVariable = args[1];
+ const std::string& expression = args[2];
+
+ cmExprParserHelper helper;
+ if ( !helper.ParseString(expression.c_str(), 0) )
+ {
+ std::string e = "cannot parse the expression: \""+expression+"\": ";
+ e += helper.GetError();
+ this->SetError(e.c_str());
+ return false;
+ }
+
+ char buffer[1024];
+ sprintf(buffer, "%d", helper.GetResult());
+
+ this->Makefile->AddDefinition(outputVariable.c_str(), buffer);
+ return true;
+}
diff --git a/Source/cmMathCommand.h b/Source/cmMathCommand.h
new file mode 100644
index 000000000..d62290428
--- /dev/null
+++ b/Source/cmMathCommand.h
@@ -0,0 +1,76 @@
+/*============================================================================
+ 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 cmMathCommand_h
+#define cmMathCommand_h
+
+#include "cmCommand.h"
+
+/// Mathematical expressions: math(EXPR ...) command.
+class cmMathCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmMathCommand;
+ }
+
+ /**
+ * 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 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 return 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.";
+ }
+
+ cmTypeMacro(cmMathCommand, cmCommand);
+protected:
+
+ bool HandleExprCommand(std::vector<std::string> const& args);
+};
+
+
+#endif
+
diff --git a/Source/cmMessageCommand.cxx b/Source/cmMessageCommand.cxx
new file mode 100644
index 000000000..e1dbf349d
--- /dev/null
+++ b/Source/cmMessageCommand.cxx
@@ -0,0 +1,82 @@
+/*============================================================================
+ 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 "cmMessageCommand.h"
+
+// cmLibraryCommand
+bool cmMessageCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 1 )
+ {
+ 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;
+ if (*i == "SEND_ERROR")
+ {
+ type = cmake::FATAL_ERROR;
+ ++i;
+ }
+ else if (*i == "FATAL_ERROR")
+ {
+ fatal = true;
+ type = cmake::FATAL_ERROR;
+ ++i;
+ }
+ else if (*i == "WARNING")
+ {
+ type = cmake::WARNING;
+ ++i;
+ }
+ else if (*i == "AUTHOR_WARNING")
+ {
+ type = cmake::AUTHOR_WARNING;
+ ++i;
+ }
+ else if (*i == "STATUS")
+ {
+ status = true;
+ ++i;
+ }
+
+ for(;i != args.end(); ++i)
+ {
+ message += *i;
+ }
+
+ if (type != cmake::MESSAGE)
+ {
+ this->Makefile->IssueMessage(type, message.c_str());
+ }
+ else
+ {
+ if (status)
+ {
+ this->Makefile->DisplayStatus(message.c_str(), -1);
+ }
+ else
+ {
+ cmSystemTools::Message(message.c_str());
+ }
+ }
+ if(fatal)
+ {
+ cmSystemTools::SetFatalErrorOccured();
+ }
+ return true;
+}
+
diff --git a/Source/cmMessageCommand.h b/Source/cmMessageCommand.h
new file mode 100644
index 000000000..03ab94b1c
--- /dev/null
+++ b/Source/cmMessageCommand.h
@@ -0,0 +1,91 @@
+/*============================================================================
+ 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 cmMessageCommand_h
+#define cmMessageCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmMessageCommand
+ * \brief Displays a message to the user
+ *
+ */
+class cmMessageCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmMessageCommand;
+ }
+
+ /**
+ * 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 const char* 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 but skip generation\n"
+ " FATAL_ERROR = CMake Error, stop all processing\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);
+};
+
+
+#endif
diff --git a/Source/cmNewLineStyle.cxx b/Source/cmNewLineStyle.cxx
new file mode 100644
index 000000000..6f7b6a949
--- /dev/null
+++ b/Source/cmNewLineStyle.cxx
@@ -0,0 +1,95 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 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.
+============================================================================*/
+#include "cmNewLineStyle.h"
+
+
+
+cmNewLineStyle::cmNewLineStyle() : NewLineStyle(Invalid)
+{
+}
+
+
+bool cmNewLineStyle::IsValid() const
+{
+ return NewLineStyle != Invalid;
+}
+
+
+bool cmNewLineStyle::ReadFromArguments(const std::vector<std::string>& args,
+ std::string& errorString)
+{
+ NewLineStyle = Invalid;
+
+ for (size_t i = 0; i< args.size(); i++)
+ {
+ if (args[i] == "NEWLINE_STYLE")
+ {
+ size_t const styleIndex = i + 1;
+ if (args.size() > styleIndex)
+ {
+ const std::string eol = args[styleIndex];
+ if (eol == "LF" || eol == "UNIX")
+ {
+ NewLineStyle = LF;
+ return true;
+ }
+ else if (eol == "CRLF" || eol == "WIN32" || eol == "DOS")
+ {
+ NewLineStyle = CRLF;
+ return true;
+ }
+ else
+ {
+ errorString = "NEWLINE_STYLE sets an unknown style, only LF, "
+ "CRLF, UNIX, DOS, and WIN32 are supported";
+ return false;
+ }
+ }
+ else
+ {
+ errorString = "NEWLINE_STYLE must set a style: "
+ "LF, CRLF, UNIX, DOS, or WIN32";
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+
+const std::string cmNewLineStyle::GetCharacters() const
+{
+ switch (NewLineStyle)
+ {
+ case Invalid:
+ return "";
+ case LF:
+ return "\n";
+ case CRLF:
+ return "\r\n";
+ default:
+ ;
+ };
+ return "";
+}
+
+
+void cmNewLineStyle::SetStyle(Style style)
+{
+ NewLineStyle = style;
+}
+
+
+cmNewLineStyle::Style cmNewLineStyle::GetStyle() const
+{
+ return NewLineStyle;
+}
diff --git a/Source/cmNewLineStyle.h b/Source/cmNewLineStyle.h
new file mode 100644
index 000000000..cae110604
--- /dev/null
+++ b/Source/cmNewLineStyle.h
@@ -0,0 +1,46 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 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 cmNewLineStyle_h
+#define cmNewLineStyle_h
+
+#include "cmStandardIncludes.h"
+
+class cmNewLineStyle
+{
+public:
+
+ cmNewLineStyle();
+
+ enum Style
+ {
+ Invalid,
+ // LF = '\n', 0x0A, 10
+ // CR = '\r', 0x0D, 13
+ LF, // Unix
+ CRLF // Dos
+ };
+
+ void SetStyle(Style);
+ Style GetStyle() const;
+
+ bool IsValid() const;
+
+ bool ReadFromArguments(const std::vector<std::string>& args,
+ std::string &errorString);
+
+ const std::string GetCharacters() const;
+
+private:
+ Style NewLineStyle;
+};
+
+#endif
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
new file mode 100644
index 000000000..a923d6068
--- /dev/null
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -0,0 +1,636 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2011 Peter Collingbourne <peter@pcc.me.uk>
+ Copyright 2011 Nicolas Despres <nicolas.despres@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 "cmNinjaNormalTargetGenerator.h"
+#include "cmLocalNinjaGenerator.h"
+#include "cmGlobalNinjaGenerator.h"
+#include "cmSourceFile.h"
+#include "cmGeneratedFileStream.h"
+#include "cmMakefile.h"
+#include "cmOSXBundleGenerator.h"
+
+#include <assert.h>
+#include <algorithm>
+
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+
+
+cmNinjaNormalTargetGenerator::
+cmNinjaNormalTargetGenerator(cmTarget* target)
+ : cmNinjaTargetGenerator(target)
+ , TargetNameOut()
+ , TargetNameSO()
+ , TargetNameReal()
+ , TargetNameImport()
+ , TargetNamePDB()
+ , TargetLinkLanguage(0)
+{
+ cmOSXBundleGenerator::PrepareTargetProperties(target);
+
+ this->TargetLinkLanguage = target->GetLinkerLanguage(this->GetConfigName());
+ if (target->GetType() == cmTarget::EXECUTABLE)
+ target->GetExecutableNames(this->TargetNameOut,
+ this->TargetNameReal,
+ this->TargetNameImport,
+ this->TargetNamePDB,
+ GetLocalGenerator()->GetConfigName());
+ else
+ target->GetLibraryNames(this->TargetNameOut,
+ this->TargetNameSO,
+ this->TargetNameReal,
+ this->TargetNameImport,
+ this->TargetNamePDB,
+ GetLocalGenerator()->GetConfigName());
+
+ if(target->GetType() != cmTarget::OBJECT_LIBRARY)
+ {
+ // on Windows the output dir is already needed at compile time
+ // ensure the directory exists (OutDir test)
+ EnsureDirectoryExists(target->GetDirectory(this->GetConfigName()));
+ }
+
+ this->OSXBundleGenerator = new cmOSXBundleGenerator(target,
+ this->TargetNameOut,
+ this->GetConfigName());
+ this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
+}
+
+cmNinjaNormalTargetGenerator::~cmNinjaNormalTargetGenerator()
+{
+ delete this->OSXBundleGenerator;
+}
+
+void cmNinjaNormalTargetGenerator::Generate()
+{
+ if (!this->TargetLinkLanguage) {
+ cmSystemTools::Error("CMake can not determine linker language for target:",
+ this->GetTarget()->GetName());
+ return;
+ }
+
+ // Write the rules for each language.
+ this->WriteLanguagesRules();
+
+ // Write the build statements
+ this->WriteObjectBuildStatements();
+
+ if(this->GetTarget()->GetType() == cmTarget::OBJECT_LIBRARY)
+ {
+ this->WriteObjectLibStatement();
+ }
+ else
+ {
+ this->WriteLinkRule(false); // write rule without rspfile support
+ this->WriteLinkRule(true); // write rule with rspfile support
+ this->WriteLinkStatement();
+ }
+}
+
+void cmNinjaNormalTargetGenerator::WriteLanguagesRules()
+{
+#ifdef NINJA_GEN_VERBOSE_FILES
+ cmGlobalNinjaGenerator::WriteDivider(this->GetRulesFileStream());
+ this->GetRulesFileStream()
+ << "# Rules for each languages for "
+ << cmTarget::GetTargetTypeName(this->GetTarget()->GetType())
+ << " target "
+ << this->GetTargetName()
+ << "\n\n";
+#endif
+
+ std::set<cmStdString> languages;
+ this->GetTarget()->GetLanguages(languages);
+ for(std::set<cmStdString>::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:
+ return "static library";
+ case cmTarget::SHARED_LIBRARY:
+ return "shared library";
+ case cmTarget::MODULE_LIBRARY:
+ if (this->GetTarget()->IsCFBundleOnApple())
+ return "CFBundle shared module";
+ else
+ return "shared module";
+ case cmTarget::EXECUTABLE:
+ return "executable";
+ default:
+ return 0;
+ }
+}
+
+std::string
+cmNinjaNormalTargetGenerator
+::LanguageLinkerRule() const
+{
+ return std::string(this->TargetLinkLanguage)
+ + "_"
+ + cmTarget::GetTargetTypeName(this->GetTarget()->GetType())
+ + "_LINKER";
+}
+
+void
+cmNinjaNormalTargetGenerator
+::WriteLinkRule(bool useResponseFile)
+{
+ cmTarget::TargetType targetType = this->GetTarget()->GetType();
+ std::string ruleName = this->LanguageLinkerRule();
+ if (useResponseFile)
+ ruleName += "_RSPFILE";
+
+ // Select whether to use a response file for objects.
+ std::string rspfile;
+ std::string rspcontent;
+
+ if (!this->GetGlobalGenerator()->HasRule(ruleName)) {
+ cmLocalGenerator::RuleVariables vars;
+ vars.RuleLauncher = "RULE_LAUNCH_LINK";
+ vars.CMTarget = this->GetTarget();
+ vars.Language = this->TargetLinkLanguage;
+
+ std::string responseFlag;
+ if (!useResponseFile) {
+ vars.Objects = "$in";
+ vars.LinkLibraries = "$LINK_LIBRARIES";
+ } else {
+ // handle response file
+ std::string cmakeLinkVar = std::string("CMAKE_") +
+ this->TargetLinkLanguage + "_RESPONSE_FILE_LINK_FLAG";
+ const char * flag = GetMakefile()->GetDefinition(cmakeLinkVar.c_str());
+ if(flag) {
+ responseFlag = flag;
+ } else {
+ responseFlag = "@";
+ }
+ rspfile = "$out.rsp";
+ responseFlag += rspfile;
+ rspcontent = "$in $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.SONameFlag = "$SONAME_FLAG";
+ vars.TargetSOName = "$SONAME";
+ vars.TargetInstallNameDir = "$INSTALLNAME_DIR";
+ vars.TargetPDB = "$TARGET_PDB";
+
+ // Setup the target version.
+ std::string targetVersionMajor;
+ std::string targetVersionMinor;
+ {
+ cmOStringStream majorStream;
+ cmOStringStream minorStream;
+ int major;
+ int minor;
+ this->GetTarget()->GetTargetVersion(major, minor);
+ majorStream << major;
+ minorStream << minor;
+ targetVersionMajor = majorStream.str();
+ targetVersionMinor = minorStream.str();
+ }
+ vars.TargetVersionMajor = targetVersionMajor.c_str();
+ vars.TargetVersionMinor = targetVersionMinor.c_str();
+
+ vars.Flags = "$FLAGS";
+ vars.LinkFlags = "$LINK_FLAGS";
+
+ std::string langFlags;
+ if (targetType != cmTarget::EXECUTABLE) {
+ this->GetLocalGenerator()->AddLanguageFlags(langFlags,
+ this->TargetLinkLanguage,
+ this->GetConfigName());
+ langFlags += " $ARCH_FLAGS";
+ vars.LanguageCompileFlags = langFlags.c_str();
+ }
+
+ // Rule for linking library/executable.
+ std::vector<std::string> linkCmds = this->ComputeLinkCmd();
+ for(std::vector<std::string>::iterator i = linkCmds.begin();
+ i != linkCmds.end();
+ ++i)
+ {
+ this->GetLocalGenerator()->ExpandRuleVariables(*i, vars);
+ }
+ linkCmds.insert(linkCmds.begin(), "$PRE_LINK");
+ linkCmds.push_back("$POST_BUILD");
+ std::string linkCmd =
+ this->GetLocalGenerator()->BuildCommandLine(linkCmds);
+
+ // Write the linker rule with response file if needed.
+ cmOStringStream comment;
+ comment << "Rule for linking " << this->TargetLinkLanguage << " "
+ << this->GetVisibleTypeName() << ".";
+ cmOStringStream description;
+ description << "Linking " << this->TargetLinkLanguage << " "
+ << this->GetVisibleTypeName() << " $out";
+ this->GetGlobalGenerator()->AddRule(ruleName,
+ linkCmd,
+ description.str(),
+ comment.str(),
+ /*depfile*/ "",
+ rspfile,
+ rspcontent);
+ }
+
+ if (this->TargetNameOut != this->TargetNameReal) {
+ std::string cmakeCommand =
+ this->GetLocalGenerator()->ConvertToOutputFormat(
+ this->GetMakefile()->GetRequiredDefinition("CMAKE_COMMAND"),
+ cmLocalGenerator::SHELL);
+ if (targetType == cmTarget::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.");
+ 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.");
+ }
+}
+
+std::vector<std::string>
+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;
+ }
+ }
+
+ // 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");
+
+ // 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());
+ cmSystemTools::ExpandListArgument(linkCmd, linkCmds);
+ }
+ {
+ std::string linkCmdVar = "CMAKE_";
+ linkCmdVar += this->TargetLinkLanguage;
+ linkCmdVar += "_ARCHIVE_FINISH";
+ const char *linkCmd =
+ this->GetMakefile()->GetRequiredDefinition(linkCmdVar.c_str());
+ 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;
+ }
+ default:
+ assert(0 && "Unexpected target type");
+ }
+ return std::vector<std::string>();
+}
+
+void cmNinjaNormalTargetGenerator::WriteLinkStatement()
+{
+ cmTarget::TargetType targetType = this->GetTarget()->GetType();
+
+ std::string targetOutput = ConvertToNinjaPath(
+ this->GetTarget()->GetFullPath(this->GetConfigName()).c_str());
+ std::string targetOutputReal = ConvertToNinjaPath(
+ this->GetTarget()->GetFullPath(this->GetConfigName(),
+ /*implib=*/false,
+ /*realpath=*/true).c_str());
+ std::string targetOutputImplib = ConvertToNinjaPath(
+ this->GetTarget()->GetFullPath(this->GetConfigName(),
+ /*implib=*/true).c_str());
+
+ if (this->GetTarget()->IsAppBundleOnApple())
+ {
+ // Create the app bundle
+ std::string outpath;
+ this->OSXBundleGenerator->CreateAppBundle(this->TargetNameOut, outpath);
+
+ // Calculate the output path
+ targetOutput = outpath + this->TargetNameOut;
+ targetOutput = this->ConvertToNinjaPath(targetOutput.c_str());
+ targetOutputReal = outpath + this->TargetNameReal;
+ targetOutputReal = this->ConvertToNinjaPath(targetOutputReal.c_str());
+ }
+ else if (this->GetTarget()->IsFrameworkOnApple())
+ {
+ // Create the library framework.
+ this->OSXBundleGenerator->CreateFramework(this->TargetNameOut);
+ }
+ else if(this->GetTarget()->IsCFBundleOnApple())
+ {
+ // Create the core foundation bundle.
+ std::string outpath;
+ this->OSXBundleGenerator->CreateCFBundle(this->TargetNameOut, outpath);
+ }
+
+ // Write comments.
+ cmGlobalNinjaGenerator::WriteDivider(this->GetBuildFileStream());
+ this->GetBuildFileStream()
+ << "# Link build statements for "
+ << cmTarget::GetTargetTypeName(targetType)
+ << " target "
+ << this->GetTargetName()
+ << "\n\n";
+
+ cmNinjaDeps emptyDeps;
+ cmNinjaVars vars;
+
+ // Compute the comment.
+ cmOStringStream comment;
+ comment << "Link the " << this->GetVisibleTypeName() << " "
+ << targetOutputReal;
+
+ // Compute outputs.
+ cmNinjaDeps outputs;
+ outputs.push_back(targetOutputReal);
+
+ // Compute specific libraries to link with.
+ cmNinjaDeps explicitDeps = this->GetObjects();
+ cmNinjaDeps implicitDeps = this->ComputeLinkDeps();
+
+ this->GetLocalGenerator()->GetTargetFlags(vars["LINK_LIBRARIES"],
+ vars["FLAGS"],
+ vars["LINK_FLAGS"],
+ *this->GetTarget());
+
+ this->AddModuleDefinitionFlag(vars["LINK_FLAGS"]);
+
+ // 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->GetTarget(),
+ 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);
+ 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);
+ }
+ }
+ }
+
+ std::string path;
+ if (!this->TargetNameImport.empty()) {
+ path = this->GetLocalGenerator()->ConvertToOutputFormat(
+ targetOutputImplib.c_str(), cmLocalGenerator::SHELL);
+ vars["TARGET_IMPLIB"] = path;
+ EnsureParentDirectoryExists(path);
+ }
+
+ cmMakefile* mf = this->GetMakefile();
+ if (mf->GetDefinition("MSVC_C_ARCHITECTURE_ID") ||
+ mf->GetDefinition("MSVC_CXX_ARCHITECTURE_ID"))
+ {
+ path = this->GetTargetPDB();
+ vars["TARGET_PDB"] = this->GetLocalGenerator()->ConvertToOutputFormat(
+ ConvertToNinjaPath(path.c_str()).c_str(),
+ cmLocalGenerator::SHELL);
+ EnsureParentDirectoryExists(path);
+ }
+ else
+ {
+ // It is common to place debug symbols at a specific place,
+ // so we need a plain target name in the rule available.
+ std::string prefix;
+ std::string base;
+ std::string suffix;
+ this->GetTarget()->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"))
+ {
+ path = GetTarget()->GetSupportDirectory();
+ vars["OBJECT_DIR"] = ConvertToNinjaPath(path.c_str());
+ EnsureDirectoryExists(path);
+ // ar.exe can't handle backslashes in rsp files (implictly used by gcc)
+ std::string& linkLibraries = vars["LINK_LIBRARIES"];
+ std::replace(linkLibraries.begin(), linkLibraries.end(), '\\', '/');
+ }
+
+ std::vector<cmCustomCommand> *cmdLists[3] = {
+ &this->GetTarget()->GetPreBuildCommands(),
+ &this->GetTarget()->GetPreLinkCommands(),
+ &this->GetTarget()->GetPostBuildCommands()
+ };
+
+ std::vector<std::string> preLinkCmdLines, postBuildCmdLines;
+ std::vector<std::string> *cmdLineLists[3] = {
+ &preLinkCmdLines,
+ &preLinkCmdLines,
+ &postBuildCmdLines
+ };
+
+ 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]);
+ }
+ }
+
+ // If we have any PRE_LINK commands, we need to go back to HOME_OUTPUT for
+ // the link commands.
+ if (!preLinkCmdLines.empty()) {
+ path = this->GetLocalGenerator()->ConvertToOutputFormat(
+ this->GetMakefile()->GetHomeOutputDirectory(),
+ cmLocalGenerator::SHELL);
+ preLinkCmdLines.push_back("cd " + path);
+ }
+
+ vars["PRE_LINK"] =
+ this->GetLocalGenerator()->BuildCommandLine(preLinkCmdLines);
+ std::string postBuildCmdLine =
+ this->GetLocalGenerator()->BuildCommandLine(postBuildCmdLines);
+
+ cmNinjaVars symlinkVars;
+ if (targetOutput == targetOutputReal) {
+ vars["POST_BUILD"] = postBuildCmdLine;
+ } else {
+ vars["POST_BUILD"] = ":";
+ symlinkVars["POST_BUILD"] = postBuildCmdLine;
+ }
+
+ int linkRuleLength = this->GetGlobalGenerator()->
+ GetRuleCmdLength(this->LanguageLinkerRule());
+#ifdef _WIN32
+ int commandLineLengthLimit = 8000 - linkRuleLength;
+#elif defined(__linux) || defined(__APPLE__)
+ // for instance ARG_MAX is 2096152 on Ubuntu or 262144 on Mac
+ int commandLineLengthLimit = ((int)sysconf(_SC_ARG_MAX))
+ - linkRuleLength - 1000;
+#else
+ int commandLineLengthLimit = -1;
+#endif
+
+ // Write the build statement for this target.
+ cmGlobalNinjaGenerator::WriteBuild(this->GetBuildFileStream(),
+ comment.str(),
+ this->LanguageLinkerRule(),
+ outputs,
+ explicitDeps,
+ implicitDeps,
+ emptyDeps,
+ vars,
+ commandLineLengthLimit);
+
+ if (targetOutput != targetOutputReal) {
+ if (targetType == cmTarget::EXECUTABLE) {
+ cmGlobalNinjaGenerator::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) {
+ symlinkVars["SONAME"] = soName;
+ } else {
+ symlinkVars["SONAME"] = "";
+ symlinks.push_back(soName);
+ }
+ symlinks.push_back(targetOutput);
+ cmGlobalNinjaGenerator::WriteBuild(this->GetBuildFileStream(),
+ "Create library symlink " + targetOutput,
+ "CMAKE_SYMLINK_LIBRARY",
+ symlinks,
+ cmNinjaDeps(1, targetOutputReal),
+ emptyDeps,
+ emptyDeps,
+ symlinkVars);
+ }
+ }
+
+ if (!this->TargetNameImport.empty()) {
+ // Since using multiple outputs would mess up the $out variable, use an
+ // alias for the import library.
+ cmGlobalNinjaGenerator::WritePhonyBuild(this->GetBuildFileStream(),
+ "Alias for import library.",
+ cmNinjaDeps(1, targetOutputImplib),
+ cmNinjaDeps(1, targetOutputReal));
+ }
+
+ // Add aliases for the file name and the target name.
+ this->GetGlobalGenerator()->AddTargetAlias(this->TargetNameOut,
+ this->GetTarget());
+ this->GetGlobalGenerator()->AddTargetAlias(this->GetTargetName(),
+ this->GetTarget());
+}
+
+//----------------------------------------------------------------------------
+void cmNinjaNormalTargetGenerator::WriteObjectLibStatement()
+{
+ // Write a phony output that depends on all object files.
+ cmNinjaDeps outputs;
+ this->GetLocalGenerator()->AppendTargetOutputs(this->GetTarget(), outputs);
+ cmNinjaDeps depends = this->GetObjects();
+ cmGlobalNinjaGenerator::WritePhonyBuild(this->GetBuildFileStream(),
+ "Object library "
+ + this->GetTargetName(),
+ outputs,
+ depends);
+
+ // Add aliases for the target name.
+ this->GetGlobalGenerator()->AddTargetAlias(this->GetTargetName(),
+ this->GetTarget());
+}
diff --git a/Source/cmNinjaNormalTargetGenerator.h b/Source/cmNinjaNormalTargetGenerator.h
new file mode 100644
index 000000000..284804b08
--- /dev/null
+++ b/Source/cmNinjaNormalTargetGenerator.h
@@ -0,0 +1,52 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2011 Peter Collingbourne <peter@pcc.me.uk>
+ Copyright 2011 Nicolas Despres <nicolas.despres@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 cmNinjaNormalTargetGenerator_h
+# define cmNinjaNormalTargetGenerator_h
+
+# include "cmNinjaTargetGenerator.h"
+# include "cmNinjaTypes.h"
+# include "cmStandardIncludes.h"
+
+# include <set>
+
+class cmSourceFile;
+class cmOSXBundleGenerator;
+
+class cmNinjaNormalTargetGenerator : public cmNinjaTargetGenerator
+{
+public:
+ cmNinjaNormalTargetGenerator(cmTarget* target);
+ ~cmNinjaNormalTargetGenerator();
+
+ void Generate();
+
+private:
+ std::string LanguageLinkerRule() const;
+ const char* GetVisibleTypeName() const;
+ void WriteLanguagesRules();
+ void WriteLinkRule(bool useResponseFile);
+ void WriteLinkStatement();
+ void WriteObjectLibStatement();
+ std::vector<std::string> ComputeLinkCmd();
+
+private:
+ // Target name info.
+ std::string TargetNameOut;
+ std::string TargetNameSO;
+ std::string TargetNameReal;
+ std::string TargetNameImport;
+ std::string TargetNamePDB;
+ const char *TargetLinkLanguage;
+};
+
+#endif // ! cmNinjaNormalTargetGenerator_h
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
new file mode 100644
index 000000000..3532c8ba4
--- /dev/null
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -0,0 +1,689 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2011 Peter Collingbourne <peter@pcc.me.uk>
+ Copyright 2011 Nicolas Despres <nicolas.despres@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 "cmNinjaTargetGenerator.h"
+#include "cmGlobalNinjaGenerator.h"
+#include "cmLocalNinjaGenerator.h"
+#include "cmGeneratedFileStream.h"
+#include "cmGeneratorTarget.h"
+#include "cmNinjaNormalTargetGenerator.h"
+#include "cmNinjaUtilityTargetGenerator.h"
+#include "cmSystemTools.h"
+#include "cmMakefile.h"
+#include "cmComputeLinkInformation.h"
+#include "cmSourceFile.h"
+#include "cmCustomCommandGenerator.h"
+
+#include <algorithm>
+
+cmNinjaTargetGenerator *
+cmNinjaTargetGenerator::New(cmTarget* target)
+{
+ switch (target->GetType())
+ {
+ case cmTarget::EXECUTABLE:
+ case cmTarget::SHARED_LIBRARY:
+ case cmTarget::STATIC_LIBRARY:
+ case cmTarget::MODULE_LIBRARY:
+ case cmTarget::OBJECT_LIBRARY:
+ return new cmNinjaNormalTargetGenerator(target);
+
+ case cmTarget::UTILITY:
+ return new cmNinjaUtilityTargetGenerator(target);;
+
+ case cmTarget::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)
+ return new cmNinjaUtilityTargetGenerator(target);
+ // else fallthrough
+ }
+
+ default:
+ return 0;
+ }
+}
+
+cmNinjaTargetGenerator::cmNinjaTargetGenerator(cmTarget* target)
+ :
+ MacOSXContentGenerator(0),
+ OSXBundleGenerator(0),
+ MacContentFolders(),
+ Target(target),
+ Makefile(target->GetMakefile()),
+ LocalGenerator(
+ static_cast<cmLocalNinjaGenerator*>(Makefile->GetLocalGenerator())),
+ Objects()
+{
+ this->GeneratorTarget =
+ this->GetGlobalGenerator()->GetGeneratorTarget(target);
+ MacOSXContentGenerator = new MacOSXContentGeneratorType(this);
+}
+
+cmNinjaTargetGenerator::~cmNinjaTargetGenerator()
+{
+ delete this->MacOSXContentGenerator;
+}
+
+cmGeneratedFileStream& cmNinjaTargetGenerator::GetBuildFileStream() const
+{
+ return *this->GetGlobalGenerator()->GetBuildFileStream();
+}
+
+cmGeneratedFileStream& cmNinjaTargetGenerator::GetRulesFileStream() const
+{
+ return *this->GetGlobalGenerator()->GetRulesFileStream();
+}
+
+cmGlobalNinjaGenerator* cmNinjaTargetGenerator::GetGlobalGenerator() const
+{
+ return this->LocalGenerator->GetGlobalNinjaGenerator();
+}
+
+const char* cmNinjaTargetGenerator::GetConfigName() const
+{
+ return this->LocalGenerator->GetConfigName();
+}
+
+// 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)
+{
+ // Add language-specific flags.
+ this->LocalGenerator->AddLanguageFlags(flags, lang, this->GetConfigName());
+
+ if(this->GetFeatureAsBool("INTERPROCEDURAL_OPTIMIZATION"))
+ {
+ this->LocalGenerator->AppendFeatureOptions(flags, lang, "IPO");
+ }
+}
+
+// TODO: Most of the code is picked up from
+// void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink),
+// void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
+// Refactor it.
+std::string
+cmNinjaTargetGenerator::ComputeFlagsForObject(cmSourceFile *source,
+ const std::string& language)
+{
+ std::string flags;
+
+ this->AddFeatureFlags(flags, language.c_str());
+
+ this->GetLocalGenerator()->AddArchitectureFlags(flags,
+ this->GetTarget(),
+ language.c_str(),
+ this->GetConfigName());
+
+ // TODO: Fortran support.
+ // // Fortran-specific flags computed for this target.
+ // if(*l == "Fortran")
+ // {
+ // this->AddFortranFlags(flags);
+ // }
+
+ // Add shared-library flags if needed.
+ this->LocalGenerator->AddCMP0018Flags(flags, this->Target,
+ language.c_str());
+
+ // Add include directory flags.
+ {
+ std::vector<std::string> includes;
+ this->LocalGenerator->GetIncludeDirectories(includes, this->Target,
+ language.c_str());
+ std::string includeFlags =
+ this->LocalGenerator->GetIncludeFlags(includes, language.c_str(),
+ language == "RC" ? true : false); // full include paths for RC
+ // needed by cmcldeps
+ if(cmGlobalNinjaGenerator::IsMinGW())
+ 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 and source-specific flags.
+ this->LocalGenerator->AppendFlags(flags,
+ this->Target->GetProperty("COMPILE_FLAGS"));
+ this->LocalGenerator->AppendFlags(flags,
+ source->GetProperty("COMPILE_FLAGS"));
+
+ // TODO: Handle Apple frameworks.
+
+ return flags;
+}
+
+// TODO: Refactor with
+// void cmMakefileTargetGenerator::WriteTargetLanguageFlags().
+std::string
+cmNinjaTargetGenerator::
+ComputeDefines(cmSourceFile *source, const std::string& language)
+{
+ std::string defines;
+
+ // Add the export symbol definition for shared library objects.
+ if(const char* exportMacro = this->Target->GetExportMacro())
+ {
+ this->LocalGenerator->AppendDefines(defines, exportMacro,
+ language.c_str());
+ }
+
+ // Add preprocessor definitions for this target and configuration.
+ this->LocalGenerator->AppendDefines
+ (defines,
+ this->Makefile->GetProperty("COMPILE_DEFINITIONS"),
+ language.c_str());
+ this->LocalGenerator->AppendDefines
+ (defines,
+ this->Target->GetProperty("COMPILE_DEFINITIONS"),
+ language.c_str());
+ this->LocalGenerator->AppendDefines
+ (defines,
+ source->GetProperty("COMPILE_DEFINITIONS"),
+ language.c_str());
+ {
+ std::string defPropName = "COMPILE_DEFINITIONS_";
+ defPropName += cmSystemTools::UpperCase(this->GetConfigName());
+ this->LocalGenerator->AppendDefines
+ (defines,
+ this->Makefile->GetProperty(defPropName.c_str()),
+ language.c_str());
+ this->LocalGenerator->AppendDefines
+ (defines,
+ this->Target->GetProperty(defPropName.c_str()),
+ language.c_str());
+ this->LocalGenerator->AppendDefines
+ (defines,
+ source->GetProperty(defPropName.c_str()),
+ language.c_str());
+ }
+
+ return defines;
+}
+
+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)
+ return cmNinjaDeps();
+
+ cmComputeLinkInformation* cli =
+ this->Target->GetLinkInformation(this->GetConfigName());
+ if(!cli)
+ return cmNinjaDeps();
+
+ const std::vector<std::string> &deps = cli->GetDepends();
+ cmNinjaDeps result(deps.size());
+ std::transform(deps.begin(), deps.end(), result.begin(), MapToNinjaPath());
+
+ // Add a dependency on the link definitions file, if any.
+ if(!this->ModuleDefinitionFile.empty())
+ {
+ result.push_back(this->ModuleDefinitionFile);
+ }
+
+ return result;
+}
+
+std::string
+cmNinjaTargetGenerator
+::GetSourceFilePath(cmSourceFile* source) const
+{
+ return ConvertToNinjaPath(source->GetFullPath().c_str());
+}
+
+std::string
+cmNinjaTargetGenerator
+::GetObjectFilePath(cmSourceFile* 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);
+ path += "/";
+ path += objectName;
+ return path;
+}
+
+std::string cmNinjaTargetGenerator::GetTargetOutputDir() const
+{
+ std::string dir = this->Target->GetDirectory(this->GetConfigName());
+ return ConvertToNinjaPath(dir.c_str());
+}
+
+std::string
+cmNinjaTargetGenerator
+::GetTargetFilePath(const std::string& name) const
+{
+ std::string path = this->GetTargetOutputDir();
+ if (path.empty() || path == ".")
+ return name;
+ path += "/";
+ path += name;
+ return path;
+}
+
+std::string cmNinjaTargetGenerator::GetTargetName() const
+{
+ return this->Target->GetName();
+}
+
+std::string cmNinjaTargetGenerator::GetTargetPDB() const
+{
+ 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)
+ {
+ targetFullPathPDB = this->Target->GetDirectory(this->GetConfigName());
+ targetFullPathPDB += "/";
+ targetFullPathPDB += this->Target->GetPDBName(this->GetConfigName());
+ }
+
+ return targetFullPathPDB.c_str();
+}
+
+
+void
+cmNinjaTargetGenerator
+::WriteLanguageRules(const std::string& language)
+{
+#ifdef NINJA_GEN_VERBOSE_FILES
+ this->GetRulesFileStream()
+ << "# Rules for language " << language << "\n\n";
+#endif
+ this->WriteCompileRule(language);
+}
+
+void
+cmNinjaTargetGenerator
+::WriteCompileRule(const std::string& language)
+{
+ cmLocalGenerator::RuleVariables vars;
+ vars.RuleLauncher = "RULE_LAUNCH_COMPILE";
+ vars.CMTarget = this->GetTarget();
+ std::string lang = language;
+ vars.Language = lang.c_str();
+ vars.Source = "$in";
+ vars.Object = "$out";
+ std::string flags = "$FLAGS";
+ vars.Defines = "$DEFINES";
+ vars.TargetPDB = "$TARGET_PDB";
+
+
+ cmMakefile* mf = this->GetMakefile();
+
+ bool useClDeps = false;
+ std::string clDepsBinary;
+ std::string clShowPrefix;
+ if (lang == "C" || lang == "CXX" || lang == "RC")
+ {
+ const char* depsPtr = mf->GetDefinition("CMAKE_CMCLDEPS_EXECUTABLE");
+ const char* showPtr = mf->GetDefinition("CMAKE_CL_SHOWINCLUDE_PREFIX");
+ if (depsPtr && showPtr)
+ {
+ // don't wrap for try_compile,
+ // TODO but why doesn't it work with cmcldeps?
+ const std::string projectName = mf->GetProjectName() ?
+ mf->GetProjectName() : "";
+ if (projectName != "CMAKE_TRY_COMPILE")
+ {
+ useClDeps = true;
+ std::string qu = "\"";
+ clDepsBinary = qu + depsPtr + qu;
+ clShowPrefix = qu + showPtr + qu;
+ vars.DependencyFile = "$DEP_FILE";
+ }
+ }
+ }
+
+
+ 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 : "";
+ 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();
+
+
+ // Rule for compiling object file.
+ std::string compileCmdVar = "CMAKE_";
+ compileCmdVar += language;
+ compileCmdVar += "_COMPILE_OBJECT";
+ std::string compileCmd = mf->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, vars);
+
+ std::string cmdLine =
+ this->GetLocalGenerator()->BuildCommandLine(compileCmds);
+
+ if(useClDeps)
+ {
+ std::string cl = mf->GetDefinition("CMAKE_C_COMPILER");
+ cl = "\"" + cl + "\" ";
+ cmdLine = clDepsBinary + " " + lang + " $in \"$DEP_FILE\" $out "
+ + clShowPrefix + " " + cl + cmdLine;
+ }
+
+ // 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),
+ cmdLine,
+ description.str(),
+ comment.str(),
+ depfile);
+}
+
+void
+cmNinjaTargetGenerator
+::WriteObjectBuildStatements()
+{
+ // Write comments.
+ cmGlobalNinjaGenerator::WriteDivider(this->GetBuildFileStream());
+ this->GetBuildFileStream()
+ << "# Object build statements for "
+ << cmTarget::GetTargetTypeName(this->GetTarget()->GetType())
+ << " target "
+ << this->GetTargetName()
+ << "\n\n";
+
+ for(std::vector<cmSourceFile*>::const_iterator
+ si = this->GeneratorTarget->CustomCommands.begin();
+ si != this->GeneratorTarget->CustomCommands.end(); ++si)
+ {
+ cmCustomCommand const* cc = (*si)->GetCustomCommand();
+ this->GetLocalGenerator()->AddCustomCommandTarget(cc, this->GetTarget());
+ }
+ this->OSXBundleGenerator->GenerateMacOSXContentStatements(
+ this->GeneratorTarget->HeaderSources,
+ this->MacOSXContentGenerator);
+ this->OSXBundleGenerator->GenerateMacOSXContentStatements(
+ this->GeneratorTarget->ExtraSources,
+ this->MacOSXContentGenerator);
+ for(std::vector<cmSourceFile*>::const_iterator
+ si = this->GeneratorTarget->ExternalObjects.begin();
+ si != this->GeneratorTarget->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)
+ {
+ this->WriteObjectBuildStatement(*si);
+ }
+ if(!this->GeneratorTarget->ModuleDefinitionFile.empty())
+ {
+ this->ModuleDefinitionFile = this->ConvertToNinjaPath(
+ this->GeneratorTarget->ModuleDefinitionFile.c_str());
+ }
+
+ {
+ // 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)
+ {
+ this->Objects.push_back(ConvertToNinjaPath(oi->c_str()));
+ }
+ }
+
+ this->GetBuildFileStream() << "\n";
+}
+
+void
+cmNinjaTargetGenerator
+::WriteObjectBuildStatement(cmSourceFile* source)
+{
+ cmNinjaDeps emptyDeps;
+
+ 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);
+
+ if(const char* objectDeps = source->GetProperty("OBJECT_DEPENDS")) {
+ std::vector<std::string> depList;
+ cmSystemTools::ExpandListArgument(objectDeps, depList);
+ std::transform(depList.begin(), depList.end(),
+ std::back_inserter(orderOnlyDeps), 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)
+ {
+ cmCustomCommand const* cc = (*si)->GetCustomCommand();
+ const std::vector<std::string>& ccoutputs = cc->GetOutputs();
+ std::transform(ccoutputs.begin(), ccoutputs.end(),
+ std::back_inserter(orderOnlyDeps), MapToNinjaPath());
+ }
+
+ // If the source file is GENERATED and does not have a custom command
+ // (either attached to this source file or another one), assume that one of
+ // the target dependencies, OBJECT_DEPENDS or header file custom commands
+ // will rebuild the file.
+ if (source->GetPropertyAsBool("GENERATED") && !source->GetCustomCommand() &&
+ !this->GetGlobalGenerator()->HasCustomCommandOutput(sourceFileName)) {
+ this->GetGlobalGenerator()->AddAssumedSourceDependencies(sourceFileName,
+ orderOnlyDeps);
+ }
+
+ cmNinjaVars vars;
+ vars["FLAGS"] = this->ComputeFlagsForObject(source, language);
+ vars["DEFINES"] = this->ComputeDefines(source, language);
+ vars["DEP_FILE"] = objectFileName + ".d";;
+ EnsureParentDirectoryExists(objectFileName);
+
+ // TODO move to GetTargetPDB
+ cmMakefile* mf = this->GetMakefile();
+ if (mf->GetDefinition("MSVC_C_ARCHITECTURE_ID") ||
+ mf->GetDefinition("MSVC_CXX_ARCHITECTURE_ID"))
+ {
+ vars["TARGET_PDB"] = this->GetLocalGenerator()->ConvertToOutputFormat(
+ ConvertToNinjaPath(GetTargetPDB().c_str()).c_str(),
+ cmLocalGenerator::SHELL);
+ }
+
+ 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());
+ }
+
+ escapedSourceFileName =
+ this->LocalGenerator->ConvertToOutputFormat(
+ escapedSourceFileName.c_str(), cmLocalGenerator::SHELL);
+
+ compileObjectVars.Source = escapedSourceFileName.c_str();
+ compileObjectVars.Object = objectFileName.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);
+ }
+
+ cmGlobalNinjaGenerator::WriteBuild(this->GetBuildFileStream(),
+ comment,
+ rule,
+ outputs,
+ explicitDeps,
+ emptyDeps,
+ orderOnlyDeps,
+ vars);
+
+ if(const char* objectOutputs = source->GetProperty("OBJECT_OUTPUTS")) {
+ std::vector<std::string> outputList;
+ cmSystemTools::ExpandListArgument(objectOutputs, outputList);
+ std::transform(outputList.begin(), outputList.end(), outputList.begin(),
+ MapToNinjaPath());
+ cmGlobalNinjaGenerator::WritePhonyBuild(this->GetBuildFileStream(),
+ "Additional output files.",
+ outputList,
+ outputs);
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmNinjaTargetGenerator
+::AddModuleDefinitionFlag(std::string& flags)
+{
+ if(this->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->ModuleDefinitionFile.c_str()));
+ this->LocalGenerator->AppendFlags(flags, flag.c_str());
+}
+
+void
+cmNinjaTargetGenerator
+::EnsureDirectoryExists(const std::string& dir)
+{
+ cmSystemTools::MakeDirectory(dir.c_str());
+}
+
+void
+cmNinjaTargetGenerator
+::EnsureParentDirectoryExists(const std::string& path)
+{
+ EnsureDirectoryExists(cmSystemTools::GetParentDirectory(path.c_str()));
+}
+
+
+//----------------------------------------------------------------------------
+void
+cmNinjaTargetGenerator::MacOSXContentGeneratorType::operator()(
+ cmSourceFile& source, const char* pkgloc)
+{
+ // Skip OS X content when not building a Framework or Bundle.
+ if(this->Generator->OSXBundleGenerator->GetMacContentDirectory().empty())
+ {
+ return;
+ }
+
+ std::string macdir =
+ this->Generator->OSXBundleGenerator->InitMacOSXContentDirectory(pkgloc);
+
+ // Get the input file location.
+ std::string input = source.GetFullPath();
+ input =
+ this->Generator->GetLocalGenerator()->ConvertToNinjaPath(input.c_str());
+
+ // Get the output file location.
+ std::string output = macdir;
+ output += "/";
+ output += cmSystemTools::GetFilenameName(input);
+ output =
+ this->Generator->GetLocalGenerator()->ConvertToNinjaPath(output.c_str());
+
+ // Write a build statement to copy the content into the bundle.
+ this->Generator->GetGlobalGenerator()->WriteMacOSXContentBuild(input,
+ output);
+
+ // Add as a dependency of all target so that it gets called.
+ this->Generator->GetGlobalGenerator()->AddDependencyToAll(output);
+}
diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h
new file mode 100644
index 000000000..84573cec2
--- /dev/null
+++ b/Source/cmNinjaTargetGenerator.h
@@ -0,0 +1,151 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2011 Peter Collingbourne <peter@pcc.me.uk>
+ Copyright 2011 Nicolas Despres <nicolas.despres@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 cmNinjaTargetGenerator_h
+#define cmNinjaTargetGenerator_h
+
+#include "cmStandardIncludes.h"
+#include "cmNinjaTypes.h"
+#include "cmLocalNinjaGenerator.h"
+#include "cmOSXBundleGenerator.h"
+
+class cmTarget;
+class cmGlobalNinjaGenerator;
+class cmGeneratedFileStream;
+class cmGeneratorTarget;
+class cmMakefile;
+class cmSourceFile;
+class cmCustomCommand;
+
+class cmNinjaTargetGenerator
+{
+public:
+ /// Create a cmNinjaTargetGenerator according to the @a target's type.
+ static cmNinjaTargetGenerator* New(cmTarget* target);
+
+ /// Build a NinjaTargetGenerator.
+ cmNinjaTargetGenerator(cmTarget* target);
+
+ /// Destructor.
+ virtual ~cmNinjaTargetGenerator();
+
+ virtual void Generate() = 0;
+
+ std::string GetTargetPDB() const;
+ std::string GetTargetName() const;
+
+protected:
+ cmGeneratedFileStream& GetBuildFileStream() const;
+ cmGeneratedFileStream& GetRulesFileStream() const;
+
+ cmTarget* GetTarget() const
+ { return this->Target; }
+
+ cmLocalNinjaGenerator* GetLocalGenerator() const
+ { return this->LocalGenerator; }
+
+ cmGlobalNinjaGenerator* GetGlobalGenerator() const;
+
+ cmMakefile* GetMakefile() const
+ { return this->Makefile; }
+
+ const char* GetConfigName() const;
+
+ std::string LanguageCompilerRule(const std::string& lang) const
+ { return lang + "_COMPILER"; }
+
+ const char* GetFeature(const char* feature);
+ bool GetFeatureAsBool(const char* feature);
+ void AddFeatureFlags(std::string& flags, const char* lang);
+
+ /**
+ * 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,
+ const std::string& language);
+
+ std::string ComputeDefines(cmSourceFile *source,
+ const std::string& language);
+
+ std::string ConvertToNinjaPath(const char *path) const {
+ return this->GetLocalGenerator()->ConvertToNinjaPath(path);
+ }
+ cmLocalNinjaGenerator::map_to_ninja_path MapToNinjaPath() const {
+ return this->GetLocalGenerator()->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;
+
+ /// @return the object file path for the given @a source.
+ std::string GetObjectFilePath(cmSourceFile* source) const;
+
+ /// @return the file path where the target named @a name is generated.
+ std::string GetTargetFilePath(const std::string& name) const;
+
+ /// @return the output path for the target.
+ virtual std::string GetTargetOutputDir() const;
+
+ void WriteLanguageRules(const std::string& language);
+ void WriteCompileRule(const std::string& language);
+ void WriteObjectBuildStatements();
+ void WriteObjectBuildStatement(cmSourceFile* source);
+ void WriteCustomCommandBuildStatement(cmCustomCommand *cc);
+
+ 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);
+ void EnsureParentDirectoryExists(const std::string& path);
+
+ // write rules for Mac OS X Application Bundle content.
+ struct MacOSXContentGeneratorType :
+ cmOSXBundleGenerator::MacOSXContentGeneratorType
+ {
+ MacOSXContentGeneratorType(cmNinjaTargetGenerator* g) :
+ Generator(g) {}
+
+ void operator()(cmSourceFile& source, const char* pkgloc);
+
+ private:
+ cmNinjaTargetGenerator* Generator;
+ };
+ friend struct MacOSXContentGeneratorType;
+
+protected:
+ MacOSXContentGeneratorType* MacOSXContentGenerator;
+ // Properly initialized by sub-classes.
+ cmOSXBundleGenerator* OSXBundleGenerator;
+ std::set<cmStdString> MacContentFolders;
+
+
+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;
+};
+
+#endif // ! cmNinjaTargetGenerator_h
diff --git a/Source/cmNinjaTypes.h b/Source/cmNinjaTypes.h
new file mode 100644
index 000000000..498f6b639
--- /dev/null
+++ b/Source/cmNinjaTypes.h
@@ -0,0 +1,19 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2011 Peter Collingbourne <peter@pcc.me.uk>
+ Copyright 2011 Nicolas Despres <nicolas.despres@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 cmNinjaTypes_h
+# define cmNinjaTypes_h
+
+typedef std::vector<std::string> cmNinjaDeps;
+typedef std::map<std::string, std::string> cmNinjaVars;
+
+#endif // ! cmNinjaTypes_h
diff --git a/Source/cmNinjaUtilityTargetGenerator.cxx b/Source/cmNinjaUtilityTargetGenerator.cxx
new file mode 100644
index 000000000..9c2fd13dd
--- /dev/null
+++ b/Source/cmNinjaUtilityTargetGenerator.cxx
@@ -0,0 +1,116 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2011 Peter Collingbourne <peter@pcc.me.uk>
+ Copyright 2011 Nicolas Despres <nicolas.despres@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 "cmNinjaUtilityTargetGenerator.h"
+#include "cmCustomCommand.h"
+#include "cmGeneratedFileStream.h"
+#include "cmGlobalNinjaGenerator.h"
+#include "cmMakefile.h"
+#include "cmSourceFile.h"
+#include "cmTarget.h"
+
+cmNinjaUtilityTargetGenerator::cmNinjaUtilityTargetGenerator(cmTarget *target)
+ : cmNinjaTargetGenerator(target) {}
+
+cmNinjaUtilityTargetGenerator::~cmNinjaUtilityTargetGenerator() {}
+
+void cmNinjaUtilityTargetGenerator::Generate()
+{
+ std::vector<std::string> commands;
+ cmNinjaDeps deps, outputs;
+
+ const std::vector<cmCustomCommand> *cmdLists[2] = {
+ &this->GetTarget()->GetPreBuildCommands(),
+ &this->GetTarget()->GetPostBuildCommands()
+ };
+
+ 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);
+ }
+ }
+
+ const std::vector<cmSourceFile*>& sources =
+ this->GetTarget()->GetSourceFiles();
+ for(std::vector<cmSourceFile*>::const_iterator source = sources.begin();
+ source != sources.end(); ++source)
+ {
+ if(cmCustomCommand* cc = (*source)->GetCustomCommand())
+ {
+ this->GetLocalGenerator()->AddCustomCommandTarget(cc, this->GetTarget());
+
+ // Depend on all custom command outputs.
+ const std::vector<std::string>& ccOutputs = cc->GetOutputs();
+ std::transform(ccOutputs.begin(), ccOutputs.end(),
+ std::back_inserter(deps), MapToNinjaPath());
+ }
+ }
+
+ this->GetLocalGenerator()->AppendTargetOutputs(this->GetTarget(), outputs);
+ this->GetLocalGenerator()->AppendTargetDepends(this->GetTarget(), deps);
+
+ if (commands.empty()) {
+ cmGlobalNinjaGenerator::WritePhonyBuild(this->GetBuildFileStream(),
+ "Utility command for "
+ + this->GetTargetName(),
+ outputs,
+ deps);
+ } else {
+ std::string command =
+ this->GetLocalGenerator()->BuildCommandLine(commands);
+ const char *echoStr = this->GetTarget()->GetProperty("EchoString");
+ std::string desc;
+ if (echoStr)
+ desc = echoStr;
+ else
+ desc = "Running utility command for " + this->GetTargetName();
+
+ // TODO: fix problematic global targets. For now, search and replace the
+ // makefile vars.
+ cmSystemTools::ReplaceString(
+ command,
+ "$(CMAKE_SOURCE_DIR)",
+ this->GetLocalGenerator()->ConvertToOutputFormat(
+ this->GetTarget()->GetMakefile()->GetHomeDirectory(),
+ cmLocalGenerator::SHELL).c_str());
+ cmSystemTools::ReplaceString(
+ command,
+ "$(CMAKE_BINARY_DIR)",
+ this->GetLocalGenerator()->ConvertToOutputFormat(
+ this->GetTarget()->GetMakefile()->GetHomeOutputDirectory(),
+ cmLocalGenerator::SHELL).c_str());
+ cmSystemTools::ReplaceString(command, "$(ARGS)", "");
+
+ if (command.find('$') != std::string::npos)
+ return;
+
+ std::string utilCommandName = cmake::GetCMakeFilesDirectoryPostSlash();
+ utilCommandName += this->GetTargetName() + ".util";
+
+ this->GetGlobalGenerator()->WriteCustomCommandBuild(
+ command,
+ desc,
+ "Utility command for " + this->GetTargetName(),
+ cmNinjaDeps(1, utilCommandName),
+ deps);
+
+ cmGlobalNinjaGenerator::WritePhonyBuild(this->GetBuildFileStream(),
+ "",
+ outputs,
+ cmNinjaDeps(1, utilCommandName));
+ }
+
+ this->GetGlobalGenerator()->AddTargetAlias(this->GetTargetName(),
+ this->GetTarget());
+}
diff --git a/Source/cmNinjaUtilityTargetGenerator.h b/Source/cmNinjaUtilityTargetGenerator.h
new file mode 100644
index 000000000..8b82ce49a
--- /dev/null
+++ b/Source/cmNinjaUtilityTargetGenerator.h
@@ -0,0 +1,30 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2011 Peter Collingbourne <peter@pcc.me.uk>
+ Copyright 2011 Nicolas Despres <nicolas.despres@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 cmNinjaUtilityTargetGenerator_h
+# define cmNinjaUtilityTargetGenerator_h
+
+# include "cmNinjaTargetGenerator.h"
+# include "cmNinjaTypes.h"
+
+class cmSourceFile;
+
+class cmNinjaUtilityTargetGenerator : public cmNinjaTargetGenerator
+{
+public:
+ cmNinjaUtilityTargetGenerator(cmTarget* target);
+ ~cmNinjaUtilityTargetGenerator();
+
+ void Generate();
+};
+
+#endif // ! cmNinjaUtilityTargetGenerator_h
diff --git a/Source/cmOSXBundleGenerator.cxx b/Source/cmOSXBundleGenerator.cxx
new file mode 100644
index 000000000..42fad0742
--- /dev/null
+++ b/Source/cmOSXBundleGenerator.cxx
@@ -0,0 +1,236 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2012 Nicolas Despres <nicolas.despres@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 "cmOSXBundleGenerator.h"
+#include "cmMakefile.h"
+#include "cmTarget.h"
+#include "cmLocalGenerator.h"
+
+#include <cassert>
+
+void cmOSXBundleGenerator::PrepareTargetProperties(cmTarget* target)
+{
+ if(target->IsCFBundleOnApple())
+ {
+ target->SetProperty("PREFIX", "");
+ target->SetProperty("SUFFIX", "");
+ }
+}
+
+//----------------------------------------------------------------------------
+cmOSXBundleGenerator::
+cmOSXBundleGenerator(cmTarget* target,
+ std::string targetNameOut,
+ const char* configName)
+ : Target(target)
+ , Makefile(target->GetMakefile())
+ , LocalGenerator(Makefile->GetLocalGenerator())
+ , TargetNameOut(targetNameOut)
+ , ConfigName(configName)
+ , MacContentDirectory()
+ , FrameworkVersion()
+ , MacContentFolders(0)
+{
+ if (this->MustSkip())
+ return;
+
+ this->MacContentDirectory =
+ this->Target->GetMacContentDirectory(this->ConfigName,
+ /*implib*/ false,
+ /*includeMacOS*/ false);
+ if(this->Target->IsFrameworkOnApple())
+ this->FrameworkVersion = this->Target->GetFrameworkVersion();
+}
+
+//----------------------------------------------------------------------------
+bool cmOSXBundleGenerator::MustSkip()
+{
+ return !this->Target->HaveWellDefinedOutputFiles();
+}
+
+//----------------------------------------------------------------------------
+void cmOSXBundleGenerator::CreateAppBundle(std::string& targetName,
+ std::string& outpath)
+{
+ if (this->MustSkip())
+ return;
+
+ // Compute bundle directory names.
+ outpath = this->MacContentDirectory;
+ outpath += "MacOS";
+ cmSystemTools::MakeDirectory(outpath.c_str());
+ outpath += "/";
+ this->Makefile->AddCMakeOutputFile(outpath.c_str());
+
+ // Configure the Info.plist file. Note that it needs the executable name
+ // to be set.
+ std::string plist = this->MacContentDirectory + "Info.plist";
+ this->LocalGenerator->GenerateAppleInfoPList(this->Target,
+ targetName.c_str(),
+ plist.c_str());
+ this->Makefile->AddCMakeOutputFile(plist.c_str());
+}
+
+//----------------------------------------------------------------------------
+void cmOSXBundleGenerator::CreateFramework(std::string const& targetName)
+{
+ if (this->MustSkip())
+ return;
+
+ assert(this->MacContentFolders);
+
+ // Configure the Info.plist file into the Resources directory.
+ this->MacContentFolders->insert("Resources");
+ std::string plist = this->MacContentDirectory + "Resources/Info.plist";
+ this->LocalGenerator->GenerateFrameworkInfoPList(this->Target,
+ targetName.c_str(),
+ plist.c_str());
+
+ // TODO: Use the cmMakefileTargetGenerator::ExtraFiles vector to
+ // drive rules to create these files at build time.
+ std::string oldName;
+ std::string newName;
+
+ // Compute the location of the top-level foo.framework directory.
+ std::string top = this->Target->GetDirectory(this->ConfigName);
+ top += "/";
+ top += this->TargetNameOut;
+ top += ".framework/";
+
+ // Make foo.framework/Versions
+ std::string versions = top;
+ versions += "Versions";
+ cmSystemTools::MakeDirectory(versions.c_str());
+
+ // Make foo.framework/Versions/version
+ std::string version = versions;
+ version += "/";
+ version += this->FrameworkVersion;
+ cmSystemTools::MakeDirectory(version.c_str());
+
+ // Current -> version
+ oldName = this->FrameworkVersion;
+ newName = versions;
+ newName += "/Current";
+ cmSystemTools::RemoveFile(newName.c_str());
+ cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str());
+ this->Makefile->AddCMakeOutputFile(newName.c_str());
+
+ // foo -> Versions/Current/foo
+ oldName = "Versions/Current/";
+ oldName += this->TargetNameOut;
+ newName = top;
+ newName += this->TargetNameOut;
+ cmSystemTools::RemoveFile(newName.c_str());
+ cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str());
+ this->Makefile->AddCMakeOutputFile(newName.c_str());
+
+ // Resources -> Versions/Current/Resources
+ if(this->MacContentFolders->find("Resources") !=
+ this->MacContentFolders->end())
+ {
+ oldName = "Versions/Current/Resources";
+ newName = top;
+ newName += "Resources";
+ cmSystemTools::RemoveFile(newName.c_str());
+ cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str());
+ this->Makefile->AddCMakeOutputFile(newName.c_str());
+ }
+
+ // Headers -> Versions/Current/Headers
+ if(this->MacContentFolders->find("Headers") !=
+ this->MacContentFolders->end())
+ {
+ oldName = "Versions/Current/Headers";
+ newName = top;
+ newName += "Headers";
+ cmSystemTools::RemoveFile(newName.c_str());
+ cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str());
+ this->Makefile->AddCMakeOutputFile(newName.c_str());
+ }
+
+ // PrivateHeaders -> Versions/Current/PrivateHeaders
+ if(this->MacContentFolders->find("PrivateHeaders") !=
+ this->MacContentFolders->end())
+ {
+ oldName = "Versions/Current/PrivateHeaders";
+ newName = top;
+ newName += "PrivateHeaders";
+ cmSystemTools::RemoveFile(newName.c_str());
+ cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str());
+ this->Makefile->AddCMakeOutputFile(newName.c_str());
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmOSXBundleGenerator::CreateCFBundle(std::string& targetName,
+ std::string& outpath)
+{
+ if (this->MustSkip())
+ return;
+
+ // Compute bundle directory names.
+ outpath = this->MacContentDirectory;
+ outpath += "MacOS";
+ cmSystemTools::MakeDirectory(outpath.c_str());
+ outpath += "/";
+ this->Makefile->AddCMakeOutputFile(outpath.c_str());
+
+ // Configure the Info.plist file. Note that it needs the executable name
+ // to be set.
+ std::string plist = this->MacContentDirectory;
+ plist += "Info.plist";
+ this->LocalGenerator->GenerateAppleInfoPList(this->Target,
+ targetName.c_str(),
+ plist.c_str());
+ this->Makefile->AddCMakeOutputFile(plist.c_str());
+}
+
+//----------------------------------------------------------------------------
+void
+cmOSXBundleGenerator::
+GenerateMacOSXContentStatements(std::vector<cmSourceFile*> const& sources,
+ MacOSXContentGeneratorType* generator)
+{
+ if (this->MustSkip())
+ return;
+
+ for(std::vector<cmSourceFile*>::const_iterator
+ si = sources.begin(); si != sources.end(); ++si)
+ {
+ cmTarget::SourceFileFlags tsFlags =
+ this->Target->GetTargetSourceFileFlags(*si);
+ if(tsFlags.Type != cmTarget::SourceFileTypeNormal)
+ {
+ (*generator)(**si, tsFlags.MacFolder);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmOSXBundleGenerator::InitMacOSXContentDirectory(const char* pkgloc)
+{
+ // Construct the full path to the content subdirectory.
+ std::string macdir = this->MacContentDirectory;
+ macdir += pkgloc;
+ cmSystemTools::MakeDirectory(macdir.c_str());
+
+ // Record use of this content location. Only the first level
+ // directory is needed.
+ {
+ std::string loc = pkgloc;
+ loc = loc.substr(0, loc.find('/'));
+ this->MacContentFolders->insert(loc);
+ }
+
+ return macdir;
+}
diff --git a/Source/cmOSXBundleGenerator.h b/Source/cmOSXBundleGenerator.h
new file mode 100644
index 000000000..01e3cbeb4
--- /dev/null
+++ b/Source/cmOSXBundleGenerator.h
@@ -0,0 +1,71 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2012 Nicolas Despres <nicolas.despres@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 cmOSXBundleGenerator_h
+#define cmOSXBundleGenerator_h
+
+#include "cmStandardIncludes.h"
+#include "cmSourceFile.h"
+
+#include <string>
+#include <set>
+
+class cmTarget;
+class cmMakefile;
+class cmLocalGenerator;
+
+class cmOSXBundleGenerator
+{
+public:
+ static void PrepareTargetProperties(cmTarget* target);
+
+ cmOSXBundleGenerator(cmTarget* target,
+ std::string targetNameOut,
+ const char* configName);
+
+ void CreateAppBundle(std::string& targetName, std::string& outpath);
+ void CreateFramework(std::string const& targetName);
+ void CreateCFBundle(std::string& targetName, std::string& outpath);
+
+ struct MacOSXContentGeneratorType
+ {
+ virtual ~MacOSXContentGeneratorType() {}
+ virtual void operator()(cmSourceFile& source, const char* pkgloc) = 0;
+ };
+
+ void GenerateMacOSXContentStatements(
+ std::vector<cmSourceFile*> const& sources,
+ MacOSXContentGeneratorType* generator);
+ std::string InitMacOSXContentDirectory(const char* pkgloc);
+
+ std::string GetMacContentDirectory() const
+ { return this->MacContentDirectory; }
+ std::string GetFrameworkVersion() const
+ { return this->FrameworkVersion; }
+ void SetMacContentFolders(std::set<cmStdString>* macContentFolders)
+ { this->MacContentFolders = macContentFolders; }
+
+private:
+ bool MustSkip();
+
+private:
+ cmTarget* Target;
+ cmMakefile* Makefile;
+ cmLocalGenerator* LocalGenerator;
+ std::string TargetNameOut;
+ const char* ConfigName;
+ std::string MacContentDirectory;
+ std::string FrameworkVersion;
+ std::set<cmStdString>* MacContentFolders;
+};
+
+
+#endif
diff --git a/Source/cmObject.h b/Source/cmObject.h
new file mode 100644
index 000000000..1a39aa76a
--- /dev/null
+++ b/Source/cmObject.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 cmObject_h
+#define cmObject_h
+
+#include "cmStandardIncludes.h"
+
+/** \class cmObject
+ * \brief Superclass for all commands and other classes in CMake.
+ *
+ * cmObject is the base class for all classes in CMake. It defines some
+ * methods such as GetNameOfClass, IsA, SafeDownCast.
+ */
+class cmObject
+{
+public:
+ /**
+ * Need virtual destructor to destroy real command type.
+ */
+ virtual ~cmObject() {}
+
+ /**
+ * The class name of the command.
+ */
+ virtual const char* GetNameOfClass() = 0;
+
+ /**
+ * Returns true if this class is the given class, or a subclass of it.
+ */
+ static bool IsTypeOf(const char *type)
+ { return !strcmp("cmObject", type); }
+
+ /**
+ * Returns true if this object is an instance of the given class or
+ * a subclass of it.
+ */
+ virtual bool IsA(const char *type)
+ { return cmObject::IsTypeOf(type); }
+};
+
+#endif
+
diff --git a/Source/cmOptionCommand.cxx b/Source/cmOptionCommand.cxx
new file mode 100644
index 000000000..af9d94bcf
--- /dev/null
+++ b/Source/cmOptionCommand.cxx
@@ -0,0 +1,71 @@
+/*============================================================================
+ 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 "cmOptionCommand.h"
+
+// cmOptionCommand
+bool cmOptionCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ bool argError = false;
+ if(args.size() < 2)
+ {
+ argError = true;
+ }
+ // for VTK 4.0 we have to support the option command with more than 3
+ // arguments if CMAKE_MINIMUM_REQUIRED_VERSION is not defined, if
+ // CMAKE_MINIMUM_REQUIRED_VERSION is defined, then we can have stricter
+ // checking.
+ if(this->Makefile->GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION"))
+ {
+ if(args.size() > 3)
+ {
+ argError = true;
+ }
+ }
+ 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());
+ 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())
+ {
+ if ( it.GetType() != cmCacheManager::UNINITIALIZED )
+ {
+ it.SetProperty("HELPSTRING", args[1].c_str());
+ return true;
+ }
+ if ( it.GetValue() )
+ {
+ initialValue = it.GetValue();
+ }
+ }
+ 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);
+ return true;
+}
diff --git a/Source/cmOptionCommand.h b/Source/cmOptionCommand.h
new file mode 100644
index 000000000..da3133237
--- /dev/null
+++ b/Source/cmOptionCommand.h
@@ -0,0 +1,78 @@
+/*============================================================================
+ 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 cmOptionCommand_h
+#define cmOptionCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmOptionCommand
+ * \brief Provide an option to the user
+ *
+ * cmOptionCommand provides an option for the user to select
+ */
+class cmOptionCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmOptionCommand;
+ }
+
+ /**
+ * 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 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."
+ ;
+ }
+
+ /**
+ * This determines if the command is invoked when in script mode.
+ */
+ virtual bool IsScriptable() const { return true; }
+
+ cmTypeMacro(cmOptionCommand, cmCommand);
+};
+
+
+
+#endif
diff --git a/Source/cmOrderDirectories.cxx b/Source/cmOrderDirectories.cxx
new file mode 100644
index 000000000..6e41768b0
--- /dev/null
+++ b/Source/cmOrderDirectories.cxx
@@ -0,0 +1,611 @@
+/*============================================================================
+ 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 "cmOrderDirectories.h"
+
+#include "cmGlobalGenerator.h"
+#include "cmSystemTools.h"
+#include "cmake.h"
+
+#include <assert.h>
+
+#include <algorithm>
+
+/*
+Directory ordering computation.
+ - Useful to compute a safe runtime library path order
+ - Need runtime path for supporting INSTALL_RPATH_USE_LINK_PATH
+ - Need runtime path at link time to pickup transitive link dependencies
+ for shared libraries.
+*/
+
+//----------------------------------------------------------------------------
+class cmOrderDirectoriesConstraint
+{
+public:
+ cmOrderDirectoriesConstraint(cmOrderDirectories* od,
+ std::string const& file):
+ OD(od), GlobalGenerator(od->GlobalGenerator)
+ {
+ this->FullPath = file;
+ this->Directory = cmSystemTools::GetFilenamePath(file);
+ this->FileName = cmSystemTools::GetFilenameName(file);
+ }
+ virtual ~cmOrderDirectoriesConstraint() {}
+
+ void AddDirectory()
+ {
+ this->DirectoryIndex = this->OD->AddOriginalDirectory(this->Directory);
+ }
+
+ virtual void Report(std::ostream& e) = 0;
+
+ void FindConflicts(unsigned int index)
+ {
+ 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))
+ {
+ // The library will be found in this directory but this is not
+ // the directory named for it. Add an entry to make sure the
+ // desired directory comes before this one.
+ cmOrderDirectories::ConflictPair p(this->DirectoryIndex, index);
+ this->OD->ConflictGraph[i].push_back(p);
+ }
+ }
+ }
+
+ void FindImplicitConflicts(cmOStringStream& 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))
+ {
+ // The library will be found in this directory but it is
+ // supposed to be found in an implicit search directory.
+ if(first)
+ {
+ first = false;
+ w << " ";
+ this->Report(w);
+ w << " in " << this->Directory << " may be hidden by files in:\n";
+ }
+ w << " " << dir << "\n";
+ }
+ }
+ }
+protected:
+ virtual bool FindConflict(std::string const& dir) = 0;
+
+ bool FileMayConflict(std::string const& dir, std::string const& name);
+
+ cmOrderDirectories* OD;
+ cmGlobalGenerator* GlobalGenerator;
+
+ // The location in which the item is supposed to be found.
+ std::string FullPath;
+ std::string Directory;
+ std::string FileName;
+
+ // The index assigned to the directory.
+ int DirectoryIndex;
+};
+
+//----------------------------------------------------------------------------
+bool cmOrderDirectoriesConstraint::FileMayConflict(std::string const& dir,
+ std::string const& name)
+{
+ // Check if the file exists on disk.
+ std::string file = dir;
+ file += "/";
+ file += name;
+ if(cmSystemTools::FileExists(file.c_str(), true))
+ {
+ // 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());
+ }
+
+ // Check if the file will be built by cmake.
+ std::set<cmStdString> const& files =
+ (this->GlobalGenerator->GetDirectoryContent(dir, false));
+ std::set<cmStdString>::const_iterator fi = files.find(name);
+ return fi != files.end();
+}
+
+//----------------------------------------------------------------------------
+class cmOrderDirectoriesConstraintSOName: public cmOrderDirectoriesConstraint
+{
+public:
+ cmOrderDirectoriesConstraintSOName(cmOrderDirectories* od,
+ std::string const& file,
+ const char* soname):
+ cmOrderDirectoriesConstraint(od, file), SOName(soname? soname : "")
+ {
+ if(this->SOName.empty())
+ {
+ // Try to guess the soname.
+ std::string soguess;
+ if(cmSystemTools::GuessLibrarySOName(file, soguess))
+ {
+ this->SOName = soguess;
+ }
+ }
+ }
+
+ virtual void Report(std::ostream& e)
+ {
+ e << "runtime library [";
+ if(this->SOName.empty())
+ {
+ e << this->FileName;
+ }
+ else
+ {
+ e << this->SOName;
+ }
+ e << "]";
+ }
+
+ virtual bool FindConflict(std::string const& dir);
+private:
+ // The soname of the shared library if it is known.
+ std::string SOName;
+};
+
+//----------------------------------------------------------------------------
+bool cmOrderDirectoriesConstraintSOName::FindConflict(std::string const& dir)
+{
+ // Determine which type of check to do.
+ if(!this->SOName.empty())
+ {
+ // We have the library soname. Check if it will be found.
+ if(this->FileMayConflict(dir, this->SOName))
+ {
+ return true;
+ }
+ }
+ else
+ {
+ // We do not have the soname. Look for files in the directory
+ // that may conflict.
+ std::set<cmStdString> const& files =
+ (this->GlobalGenerator
+ ->GetDirectoryContent(dir, true));
+
+ // Get the set of files that might conflict. Since we do not
+ // 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);
+ ++base[base.size()-1];
+ std::set<cmStdString>::const_iterator last = files.upper_bound(base);
+ if(first != last)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+class cmOrderDirectoriesConstraintLibrary: public cmOrderDirectoriesConstraint
+{
+public:
+ cmOrderDirectoriesConstraintLibrary(cmOrderDirectories* od,
+ std::string const& file):
+ cmOrderDirectoriesConstraint(od, file)
+ {
+ }
+
+ virtual void Report(std::ostream& e)
+ {
+ e << "link library [" << this->FileName << "]";
+ }
+
+ virtual bool FindConflict(std::string const& dir);
+};
+
+//----------------------------------------------------------------------------
+bool cmOrderDirectoriesConstraintLibrary::FindConflict(std::string const& dir)
+{
+ // We have the library file name. Check if it will be found.
+ if(this->FileMayConflict(dir, this->FileName))
+ {
+ return true;
+ }
+
+ // Now check if the file exists with other extensions the linker
+ // might consider.
+ 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);
+ for(std::vector<std::string>::iterator
+ i = this->OD->LinkExtensions.begin();
+ i != this->OD->LinkExtensions.end(); ++i)
+ {
+ if(*i != ext)
+ {
+ std::string fname = lib;
+ fname += *i;
+ if(this->FileMayConflict(dir, fname.c_str()))
+ {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+cmOrderDirectories::cmOrderDirectories(cmGlobalGenerator* gg,
+ cmTarget* target,
+ const char* purpose)
+{
+ this->GlobalGenerator = gg;
+ this->Target = target;
+ this->Purpose = purpose;
+ this->Computed = false;
+}
+
+//----------------------------------------------------------------------------
+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;
+ }
+}
+
+//----------------------------------------------------------------------------
+std::vector<std::string> const& cmOrderDirectories::GetOrderedDirectories()
+{
+ if(!this->Computed)
+ {
+ this->Computed = true;
+ this->CollectOriginalDirectories();
+ this->FindConflicts();
+ this->OrderDirectories();
+ }
+ return this->OrderedDirectories;
+}
+
+//----------------------------------------------------------------------------
+void cmOrderDirectories::AddRuntimeLibrary(std::string const& fullPath,
+ const char* soname)
+{
+ // Add the runtime library at most once.
+ if(this->EmmittedConstraintSOName.insert(fullPath).second)
+ {
+ // Implicit link directories need special handling.
+ if(!this->ImplicitDirectories.empty())
+ {
+ std::string dir = cmSystemTools::GetFilenamePath(fullPath);
+ if(this->ImplicitDirectories.find(dir) !=
+ this->ImplicitDirectories.end())
+ {
+ this->ImplicitDirEntries.push_back(
+ new cmOrderDirectoriesConstraintSOName(this, fullPath, soname));
+ return;
+ }
+ }
+
+ // Construct the runtime information entry for this library.
+ this->ConstraintEntries.push_back(
+ new cmOrderDirectoriesConstraintSOName(this, fullPath, soname));
+ }
+ else
+ {
+ // This can happen if the same library is linked multiple times.
+ // In that case the runtime information check need be done only
+ // once anyway. For shared libs we could add a check in AddItem
+ // to not repeat them.
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmOrderDirectories::AddLinkLibrary(std::string const& fullPath)
+{
+ // Link extension info is required for library constraints.
+ assert(!this->LinkExtensions.empty());
+
+ // Add the link library at most once.
+ if(this->EmmittedConstraintLibrary.insert(fullPath).second)
+ {
+ // Implicit link directories need special handling.
+ if(!this->ImplicitDirectories.empty())
+ {
+ std::string dir = cmSystemTools::GetFilenamePath(fullPath);
+ if(this->ImplicitDirectories.find(dir) !=
+ this->ImplicitDirectories.end())
+ {
+ this->ImplicitDirEntries.push_back(
+ new cmOrderDirectoriesConstraintLibrary(this, fullPath));
+ return;
+ }
+ }
+
+ // Construct the link library entry.
+ this->ConstraintEntries.push_back(
+ new cmOrderDirectoriesConstraintLibrary(this, fullPath));
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmOrderDirectories
+::AddUserDirectories(std::vector<std::string> const& extra)
+{
+ this->UserDirectories.insert(this->UserDirectories.end(),
+ extra.begin(), extra.end());
+}
+
+//----------------------------------------------------------------------------
+void
+cmOrderDirectories
+::AddLanguageDirectories(std::vector<std::string> const& dirs)
+{
+ this->LanguageDirectories.insert(this->LanguageDirectories.end(),
+ dirs.begin(), dirs.end());
+}
+
+//----------------------------------------------------------------------------
+void
+cmOrderDirectories
+::SetImplicitDirectories(std::set<cmStdString> const& implicitDirs)
+{
+ this->ImplicitDirectories = implicitDirs;
+}
+
+//----------------------------------------------------------------------------
+void
+cmOrderDirectories
+::SetLinkExtensionInfo(std::vector<std::string> const& linkExtensions,
+ std::string const& removeExtRegex)
+{
+ this->LinkExtensions = linkExtensions;
+ this->RemoveLibraryExtension.compile(removeExtRegex.c_str());
+}
+
+//----------------------------------------------------------------------------
+void cmOrderDirectories::CollectOriginalDirectories()
+{
+ // Add user directories specified for inclusion. These should be
+ // indexed first so their original order is preserved as much as
+ // possible subject to the constraints.
+ this->AddOriginalDirectories(this->UserDirectories);
+
+ // Add directories containing constraints.
+ for(unsigned int i=0; i < this->ConstraintEntries.size(); ++i)
+ {
+ this->ConstraintEntries[i]->AddDirectory();
+ }
+
+ // Add language runtime directories last.
+ this->AddOriginalDirectories(this->LanguageDirectories);
+}
+
+//----------------------------------------------------------------------------
+int cmOrderDirectories::AddOriginalDirectory(std::string const& dir)
+{
+ // Add the runtime directory with a unique index.
+ std::map<cmStdString, int>::iterator i =
+ this->DirectoryIndex.find(dir);
+ if(i == this->DirectoryIndex.end())
+ {
+ std::map<cmStdString, int>::value_type
+ entry(dir, static_cast<int>(this->OriginalDirectories.size()));
+ i = this->DirectoryIndex.insert(entry).first;
+ this->OriginalDirectories.push_back(dir);
+ }
+
+ return i->second;
+}
+
+//----------------------------------------------------------------------------
+void
+cmOrderDirectories
+::AddOriginalDirectories(std::vector<std::string> const& dirs)
+{
+ for(std::vector<std::string>::const_iterator di = dirs.begin();
+ di != dirs.end(); ++di)
+ {
+ // We never explicitly specify implicit link directories.
+ if(this->ImplicitDirectories.find(*di) !=
+ this->ImplicitDirectories.end())
+ {
+ continue;
+ }
+
+ // Skip the empty string.
+ if(di->empty())
+ {
+ continue;
+ }
+
+ // Add this directory.
+ this->AddOriginalDirectory(*di);
+ }
+}
+
+//----------------------------------------------------------------------------
+struct cmOrderDirectoriesCompare
+{
+ typedef std::pair<int, int> ConflictPair;
+
+ // The conflict pair is unique based on just the directory
+ // (first). The second element is only used for displaying
+ // information about why the entry is present.
+ bool operator()(ConflictPair const& l,
+ ConflictPair const& r)
+ {
+ return l.first == r.first;
+ }
+};
+
+//----------------------------------------------------------------------------
+void cmOrderDirectories::FindConflicts()
+{
+ // Allocate the conflict graph.
+ this->ConflictGraph.resize(this->OriginalDirectories.size());
+ this->DirectoryVisited.resize(this->OriginalDirectories.size(), 0);
+
+ // Find directories conflicting with each entry.
+ for(unsigned int i=0; i < this->ConstraintEntries.size(); ++i)
+ {
+ this->ConstraintEntries[i]->FindConflicts(i);
+ }
+
+ // Clean up the conflict graph representation.
+ for(std::vector<ConflictList>::iterator
+ i = this->ConflictGraph.begin();
+ i != this->ConflictGraph.end(); ++i)
+ {
+ // Sort the outgoing edges for each graph node so that the
+ // original order will be preserved as much as possible.
+ std::sort(i->begin(), i->end());
+
+ // Make the edge list unique so cycle detection will be reliable.
+ ConflictList::iterator last =
+ std::unique(i->begin(), i->end(), cmOrderDirectoriesCompare());
+ i->erase(last, i->end());
+ }
+
+ // Check items in implicit link directories.
+ this->FindImplicitConflicts();
+}
+
+//----------------------------------------------------------------------------
+void cmOrderDirectories::FindImplicitConflicts()
+{
+ // Check for items in implicit link directories that have conflicts
+ // in the explicit directories.
+ cmOStringStream conflicts;
+ for(unsigned int i=0; i < this->ImplicitDirEntries.size(); ++i)
+ {
+ this->ImplicitDirEntries[i]->FindImplicitConflicts(conflicts);
+ }
+
+ // Skip warning if there were no conflicts.
+ std::string text = conflicts.str();
+ if(text.empty())
+ {
+ return;
+ }
+
+ // Warn about the conflicts.
+ cmOStringStream w;
+ w << "Cannot generate a safe " << this->Purpose
+ << " for target " << this->Target->GetName()
+ << " because files in some directories may conflict with "
+ << " libraries in implicit directories:\n"
+ << text
+ << "Some of these libraries may not be found correctly.";
+ this->GlobalGenerator->GetCMakeInstance()
+ ->IssueMessage(cmake::WARNING, w.str(), this->Target->GetBacktrace());
+}
+
+//----------------------------------------------------------------------------
+void cmOrderDirectories::OrderDirectories()
+{
+ // Allow a cycle to be diagnosed once.
+ this->CycleDiagnosed = false;
+ this->WalkId = 0;
+
+ // Iterate through the directories in the original order.
+ for(unsigned int i=0; i < this->OriginalDirectories.size(); ++i)
+ {
+ // Start a new DFS from this node.
+ ++this->WalkId;
+ this->VisitDirectory(i);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmOrderDirectories::VisitDirectory(unsigned int i)
+{
+ // Skip nodes already visited.
+ if(this->DirectoryVisited[i])
+ {
+ if(this->DirectoryVisited[i] == this->WalkId)
+ {
+ // We have reached a node previously visited on this DFS.
+ // There is a cycle.
+ this->DiagnoseCycle();
+ }
+ return;
+ }
+
+ // We are now visiting this node so mark it.
+ this->DirectoryVisited[i] = this->WalkId;
+
+ // Visit the neighbors of the node first.
+ ConflictList const& clist = this->ConflictGraph[i];
+ for(ConflictList::const_iterator j = clist.begin();
+ j != clist.end(); ++j)
+ {
+ this->VisitDirectory(j->first);
+ }
+
+ // Now that all directories required to come before this one have
+ // been emmitted, emit this directory.
+ this->OrderedDirectories.push_back(this->OriginalDirectories[i]);
+}
+
+//----------------------------------------------------------------------------
+void cmOrderDirectories::DiagnoseCycle()
+{
+ // Report the cycle at most once.
+ if(this->CycleDiagnosed)
+ {
+ return;
+ }
+ this->CycleDiagnosed = true;
+
+ // Construct the message.
+ cmOStringStream e;
+ e << "Cannot generate a safe " << this->Purpose
+ << " for target " << this->Target->GetName()
+ << " because there is a cycle in the constraint graph:\n";
+
+ // Display the conflict graph.
+ for(unsigned int i=0; i < this->ConflictGraph.size(); ++i)
+ {
+ ConflictList const& clist = this->ConflictGraph[i];
+ e << " dir " << i << " is [" << this->OriginalDirectories[i] << "]\n";
+ for(ConflictList::const_iterator j = clist.begin();
+ j != clist.end(); ++j)
+ {
+ e << " dir " << j->first << " must precede it due to ";
+ this->ConstraintEntries[j->second]->Report(e);
+ e << "\n";
+ }
+ }
+ e << "Some of these libraries may not be found correctly.";
+ this->GlobalGenerator->GetCMakeInstance()
+ ->IssueMessage(cmake::WARNING, e.str(), this->Target->GetBacktrace());
+}
diff --git a/Source/cmOrderDirectories.h b/Source/cmOrderDirectories.h
new file mode 100644
index 000000000..96a75de17
--- /dev/null
+++ b/Source/cmOrderDirectories.h
@@ -0,0 +1,88 @@
+/*============================================================================
+ 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 cmOrderDirectories_h
+#define cmOrderDirectories_h
+
+#include "cmStandardIncludes.h"
+
+#include <cmsys/RegularExpression.hxx>
+
+class cmGlobalGenerator;
+class cmOrderDirectoriesConstraint;
+class cmOrderDirectoriesConstraintLibrary;
+class cmTarget;
+
+/** \class cmOrderDirectories
+ * \brief Compute a safe runtime path order for a set of shared libraries.
+ */
+class cmOrderDirectories
+{
+public:
+ cmOrderDirectories(cmGlobalGenerator* gg, cmTarget* 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 SetLinkExtensionInfo(std::vector<std::string> const& linkExtensions,
+ std::string const& removeExtRegex);
+
+ std::vector<std::string> const& GetOrderedDirectories();
+private:
+ cmGlobalGenerator* GlobalGenerator;
+ cmTarget* Target;
+ std::string Purpose;
+
+ bool Computed;
+
+ std::vector<std::string> OrderedDirectories;
+
+ std::vector<cmOrderDirectoriesConstraint*> ConstraintEntries;
+ std::vector<cmOrderDirectoriesConstraint*> ImplicitDirEntries;
+ std::vector<std::string> UserDirectories;
+ 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::vector<std::string> OriginalDirectories;
+ std::map<cmStdString, int> DirectoryIndex;
+ std::vector<int> DirectoryVisited;
+ void CollectOriginalDirectories();
+ int AddOriginalDirectory(std::string const& dir);
+ void AddOriginalDirectories(std::vector<std::string> const& dirs);
+ void FindConflicts();
+ void FindImplicitConflicts();
+ void OrderDirectories();
+ void VisitDirectory(unsigned int i);
+ void DiagnoseCycle();
+ bool CycleDiagnosed;
+ int WalkId;
+
+ // Adjacency-list representation of runtime path ordering graph.
+ // This maps from directory to those that must come *before* it.
+ // Each entry that must come before is a pair. The first element is
+ // the index of the directory that must come first. The second
+ // element is the index of the runtime library that added the
+ // constraint.
+ typedef std::pair<int, int> ConflictPair;
+ struct ConflictList: public std::vector<ConflictPair> {};
+ std::vector<ConflictList> ConflictGraph;
+
+ friend class cmOrderDirectoriesConstraint;
+ friend class cmOrderDirectoriesConstraintLibrary;
+};
+
+#endif
diff --git a/Source/cmOutputRequiredFilesCommand.cxx b/Source/cmOutputRequiredFilesCommand.cxx
new file mode 100644
index 000000000..be079c096
--- /dev/null
+++ b/Source/cmOutputRequiredFilesCommand.cxx
@@ -0,0 +1,240 @@
+/*============================================================================
+ 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 "cmOutputRequiredFilesCommand.h"
+#include "cmMakeDepend.h"
+
+class cmLBDepend : public cmMakeDepend
+{
+ /**
+ * Compute the depend information for this class.
+ */
+ virtual void DependWalk(cmDependInformation* info);
+};
+
+void cmLBDepend::DependWalk(cmDependInformation* info)
+{
+ std::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(!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
+ {
+ 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))
+ {
+ 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());
+ /// add the cxx file if it exists
+ std::string cxxFile = includeFile;
+ std::string::size_type pos = cxxFile.rfind('.');
+ if(pos != std::string::npos)
+ {
+ 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();
+ 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 + ".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 + ".c";
+ 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()))
+ {
+ 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());
+ }
+ }
+ }
+ }
+}
+
+// cmOutputRequiredFilesCommand
+bool cmOutputRequiredFilesCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() != 2 )
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ // store the arg for final pass
+ this->File = args[0];
+ this->OutputFile = args[1];
+
+ // compute the list of files
+ cmLBDepend md;
+ md.SetMakefile(this->Makefile);
+ md.AddSearchPath(this->Makefile->GetStartDirectory());
+ // 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");
+ if(!fout)
+ {
+ std::string err = "Can not open output file: ";
+ err += this->OutputFile;
+ this->SetError(err.c_str());
+ return false;
+ }
+ std::set<cmDependInformation const*> visited;
+ this->ListDependencies(info,fout, &visited);
+ fclose(fout);
+ }
+
+ return true;
+}
+
+void cmOutputRequiredFilesCommand::
+ListDependencies(cmDependInformation const *info,
+ FILE *fout,
+ std::set<cmDependInformation const*> *visited)
+{
+ // add info to the visited set
+ visited->insert(info);
+ // now recurse with info's dependencies
+ for(cmDependInformation::DependencySetType::const_iterator d =
+ info->DependencySet.begin();
+ d != info->DependencySet.end(); ++d)
+ {
+ if (visited->find(*d) == visited->end())
+ {
+ if(info->FullPath != "")
+ {
+ std::string tmp = (*d)->FullPath;
+ std::string::size_type pos = tmp.rfind('.');
+ if(pos != std::string::npos && (tmp.substr(pos) != ".h"))
+ {
+ tmp = tmp.substr(0, pos);
+ fprintf(fout,"%s\n",(*d)->FullPath.c_str());
+ }
+ }
+ this->ListDependencies(*d,fout,visited);
+ }
+ }
+}
+
diff --git a/Source/cmOutputRequiredFilesCommand.h b/Source/cmOutputRequiredFilesCommand.h
new file mode 100644
index 000000000..85d9095e2
--- /dev/null
+++ b/Source/cmOutputRequiredFilesCommand.h
@@ -0,0 +1,88 @@
+/*============================================================================
+ 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 cmOutputRequiredFilesCommand_h
+#define cmOutputRequiredFilesCommand_h
+
+#include "cmCommand.h"
+#include "cmMakeDepend.h"
+
+/** \class cmOutputRequiredFilesCommand
+ * \brief Output a list of required files for a source file
+ *
+ */
+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.
+ */
+ 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 "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;
+};
+
+
+
+#endif
diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx
new file mode 100644
index 000000000..79af4d700
--- /dev/null
+++ b/Source/cmPolicies.cxx
@@ -0,0 +1,859 @@
+#include "cmPolicies.h"
+#include "cmake.h"
+#include "cmMakefile.h"
+#include "cmSourceFile.h"
+#include "cmVersion.h"
+#include "cmVersionMacros.h"
+#include <map>
+#include <set>
+#include <queue>
+#include <assert.h>
+
+const char* cmPolicies::PolicyStatusNames[] = {
+ "OLD", "WARN", "NEW", "REQUIRED_IF_USED", "REQUIRED_ALWAYS"
+};
+
+class cmPolicy
+{
+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)
+ {
+ return true;
+ }
+ if (majorV > this->MajorVersionIntroduced)
+ {
+ return false;
+ }
+ if (minorV < this->MinorVersionIntroduced)
+ {
+ return true;
+ }
+ if (minorV > this->MinorVersionIntroduced)
+ {
+ return false;
+ }
+ if (patchV < this->PatchVersionIntroduced)
+ {
+ return true;
+ }
+ if (patchV > this->PatchVersionIntroduced)
+ {
+ 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 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 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 call 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);
+
+ 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);
+}
+
+cmPolicies::~cmPolicies()
+{
+ // free the policies
+ std::map<cmPolicies::PolicyID,cmPolicy *>::iterator i
+ = this->Policies.begin();
+ for (;i != this->Policies.end(); ++i)
+ {
+ delete i->second;
+ }
+}
+
+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)
+{
+ // 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;
+ }
+
+ this->Policies[iD] = new cmPolicy(iD, idString,
+ shortDescription,
+ longDescription,
+ majorVersionIntroduced,
+ minorVersionIntroduced,
+ patchVersionIntroduced,
+ tweakVersionIntroduced,
+ status);
+ this->PolicyStringMap[idString] = iD;
+}
+
+//----------------------------------------------------------------------------
+bool cmPolicies::ApplyPolicyVersion(cmMakefile *mf,
+ const char *version)
+{
+ std::string ver = "2.4.0";
+
+ if (version && strlen(version) > 0)
+ {
+ ver = version;
+ }
+
+ unsigned int majorVer = 2;
+ unsigned int minorVer = 0;
+ unsigned int patchVer = 0;
+ unsigned int tweakVer = 0;
+
+ // parse the string
+ if(sscanf(ver.c_str(), "%u.%u.%u.%u",
+ &majorVer, &minorVer, &patchVer, &tweakVer) < 2)
+ {
+ cmOStringStream e;
+ e << "Invalid policy version value \"" << ver << "\". "
+ << "A numeric major.minor[.patch[.tweak]] must be given.";
+ mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+ }
+
+ // it is an error if the policy version is less than 2.4
+ 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."
+ );
+ return false;
+ }
+
+ // It is an error if the policy version is greater than the running
+ // CMake.
+ if (majorVer > cmVersion::GetMajorVersion() ||
+ (majorVer == cmVersion::GetMajorVersion() &&
+ minorVer > cmVersion::GetMinorVersion()) ||
+ (majorVer == cmVersion::GetMajorVersion() &&
+ minorVer == cmVersion::GetMinorVersion() &&
+ patchVer > cmVersion::GetPatchVersion()) ||
+ (majorVer == cmVersion::GetMajorVersion() &&
+ minorVer == cmVersion::GetMinorVersion() &&
+ patchVer == cmVersion::GetPatchVersion() &&
+ tweakVer > cmVersion::GetTweakVersion()))
+ {
+ cmOStringStream 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 "
+ << "policies not known to this CMake. "
+ << "You may need a newer CMake version to build this project.";
+ mf->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return false;
+ }
+
+ // 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)
+ {
+ if (i->second->IsPolicyNewerThan(majorVer,minorVer,patchVer,tweakVer))
+ {
+ if(i->second->Status == cmPolicies::REQUIRED_ALWAYS)
+ {
+ ancientPolicies.push_back(i->first);
+ }
+ else
+ {
+ cmPolicies::PolicyStatus status = cmPolicies::WARN;
+ if(!this->GetPolicyDefault(mf, i->second->IDString, &status) ||
+ !mf->SetPolicy(i->second->ID, status))
+ {
+ return false;
+ }
+ }
+ }
+ else
+ {
+ if (!mf->SetPolicy(i->second->ID, cmPolicies::NEW))
+ {
+ return false;
+ }
+ }
+ }
+
+ // Make sure the project does not use any ancient policies.
+ if(!ancientPolicies.empty())
+ {
+ this->DiagnoseAncientPolicies(ancientPolicies,
+ majorVer, minorVer, patchVer, mf);
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+
+ 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;
+}
+
+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;
+ msg <<
+ "Policy " << pos->second->IDString << " is not set: "
+ "" << pos->second->ShortDescription << " "
+ "Run \"cmake --help-policy " << pos->second->IDString << "\" for "
+ "policy details. "
+ "Use the cmake_policy command to set the policy "
+ "and suppress this warning.";
+ return msg.str();
+}
+
+
+///! 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 warning text for undefined policy!";
+ }
+
+ cmOStringStream error;
+ error <<
+ "Policy " << pos->second->IDString << " is not set to NEW: "
+ "" << pos->second->ShortDescription << " "
+ "Run \"cmake --help-policy " << pos->second->IDString << "\" 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"
+ "or by upgrading all policies with the code\n"
+ " cmake_policy(VERSION " << pos->second->GetVersionString() <<
+ ") # or later\n"
+ "Run \"cmake --help-command cmake_policy\" for more information.";
+ return error.str();
+}
+
+///! Get the default status for a policy
+cmPolicies::PolicyStatus
+cmPolicies::GetPolicyStatus(cmPolicies::PolicyID id)
+{
+ // 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);
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmPolicies::GetRequiredAlwaysPolicyError(cmPolicies::PolicyID id)
+{
+ std::string pid = this->GetPolicyIDString(id);
+ cmOStringStream 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()
+ << ", and use of NEW behavior is now required."
+ << "\n"
+ << "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. "
+ << "Run cmake --help-policy " << pid << " for more information.";
+ return e.str();
+}
+
+//----------------------------------------------------------------------------
+void
+cmPolicies::DiagnoseAncientPolicies(std::vector<PolicyID> const& ancient,
+ unsigned int majorVer,
+ unsigned int minorVer,
+ unsigned int patchVer,
+ cmMakefile* mf)
+{
+ 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)
+ {
+ cmPolicy const* policy = this->Policies[*i];
+ e << " " << policy->IDString << ": " << policy->ShortDescription << "\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().c_str());
+}
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
new file mode 100644
index 000000000..6932565ab
--- /dev/null
+++ b/Source/cmPolicies.h
@@ -0,0 +1,130 @@
+/*============================================================================
+ 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 cmPolicies_h
+#define cmPolicies_h
+
+#include "cmCustomCommand.h"
+
+class cmake;
+class cmMakefile;
+class cmPolicy;
+
+/** \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>
+ * for an overview of this class's purpose
+ */
+class cmPolicies
+{
+public:
+ cmPolicies();
+ ~cmPolicies();
+
+ /// Status of a policy
+ enum PolicyStatus {
+ OLD, ///< Use old behavior
+ WARN, ///< Use old behavior but issue a warning
+ NEW, ///< Use new behavior
+ /// Issue an error if user doesn't set policy status to NEW and hits the
+ /// check
+ 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.
+
+ /** \brief Always the last entry.
+ *
+ * Useful mostly to avoid adding a comma the last policy when adding a new
+ * one.
+ */
+ CMPCOUNT
+ };
+
+ ///! convert a string policy ID into a number
+ bool GetPolicyID(const char *id, /* out */ cmPolicies::PolicyID &pid);
+ std::string GetPolicyIDString(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);
+
+ ///! Set a policy level for this listfile
+ bool ApplyPolicyVersion(cmMakefile *mf, const char *version);
+
+ ///! return a warning string for a given policy
+ std::string GetPolicyWarning(cmPolicies::PolicyID id);
+
+ ///! return an error string for when a required policy is unspecified
+ 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);
+
+ /** Represent a set of policy values. */
+ typedef std::map<PolicyID, PolicyStatus> PolicyMap;
+
+ 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);
+
+};
+
+#endif
diff --git a/Source/cmProcessTools.cxx b/Source/cmProcessTools.cxx
new file mode 100644
index 000000000..d2f7bf320
--- /dev/null
+++ b/Source/cmProcessTools.cxx
@@ -0,0 +1,90 @@
+/*============================================================================
+ 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 "cmProcessTools.h"
+
+#include <cmsys/Process.h>
+
+//----------------------------------------------------------------------------
+void cmProcessTools::RunProcess(struct cmsysProcess_s* cp,
+ OutputParser* out, OutputParser* err)
+{
+ cmsysProcess_Execute(cp);
+ char* data = 0;
+ int length = 0;
+ int p;
+ while((out||err) && (p=cmsysProcess_WaitForData(cp, &data, &length, 0), p))
+ {
+ if(out && p == cmsysProcess_Pipe_STDOUT)
+ {
+ if(!out->Process(data, length))
+ {
+ out = 0;
+ }
+ }
+ else if(err && p == cmsysProcess_Pipe_STDERR)
+ {
+ if(!err->Process(data, length))
+ {
+ err = 0;
+ }
+ }
+ }
+ cmsysProcess_WaitForExit(cp, 0);
+}
+
+
+//----------------------------------------------------------------------------
+cmProcessTools::LineParser::LineParser(char sep, bool ignoreCR):
+ Separator(sep), IgnoreCR(ignoreCR), Log(0), Prefix(0), LineEnd('\0')
+{
+}
+
+//----------------------------------------------------------------------------
+void cmProcessTools::LineParser::SetLog(std::ostream* log, const char* prefix)
+{
+ this->Log = log;
+ this->Prefix = prefix? prefix : "";
+}
+
+//----------------------------------------------------------------------------
+bool cmProcessTools::LineParser::ProcessChunk(const char* first, int length)
+{
+ const char* last = first + length;
+ for(const char* c = first; c != last; ++c)
+ {
+ if(*c == this->Separator || *c == '\0')
+ {
+ this->LineEnd = *c;
+
+ // Log this line.
+ if(this->Log && this->Prefix)
+ {
+ *this->Log << this->Prefix << this->Line << "\n";
+ }
+
+ // Hand this line to the subclass implementation.
+ if(!this->ProcessLine())
+ {
+ this->Line = "";
+ return false;
+ }
+
+ this->Line = "";
+ }
+ else if(*c != '\r' || !this->IgnoreCR)
+ {
+ // Append this character to the line under construction.
+ this->Line.append(1, *c);
+ }
+ }
+ return true;
+}
diff --git a/Source/cmProcessTools.h b/Source/cmProcessTools.h
new file mode 100644
index 000000000..439726dd0
--- /dev/null
+++ b/Source/cmProcessTools.h
@@ -0,0 +1,82 @@
+/*============================================================================
+ 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 cmProcessTools_h
+#define cmProcessTools_h
+
+#include "cmStandardIncludes.h"
+
+/** \class cmProcessTools
+ * \brief Helper classes for process output parsing
+ *
+ */
+class cmProcessTools
+{
+public:
+ /** Abstract interface for process output parsers. */
+ class OutputParser
+ {
+ public:
+ /** Process the given output data from a tool. Processing may be
+ done incrementally. Returns true if the parser is interested
+ in any more data and false if it is done. */
+ bool Process(const char* data, int length)
+ { return this->ProcessChunk(data, length); }
+ bool Process(const char* data)
+ { return this->Process(data, static_cast<int>(strlen(data))); }
+
+ virtual ~OutputParser() {}
+ protected:
+ /** Implement in a subclass to process a chunk of data. It should
+ return true only if it is interested in more data. */
+ virtual bool ProcessChunk(const char* data, int length) = 0;
+ };
+
+ /** Process output parser that extracts one line at a time. */
+ class LineParser: public OutputParser
+ {
+ public:
+ /** Construct with line separation character and choose whether to
+ ignore carriage returns. */
+ LineParser(char sep = '\n', bool ignoreCR = true);
+
+ /** 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;
+ virtual bool ProcessChunk(const char* data, int length);
+
+ /** Implement in a subclass to process one line of input. It
+ should return true only if it is interested in more data. */
+ virtual bool ProcessLine() = 0;
+ };
+
+ /** Trivial line handler for simple logging. */
+ class OutputLogger: public LineParser
+ {
+ public:
+ OutputLogger(std::ostream& log, const char* prefix = 0)
+ { this->SetLog(&log, prefix); }
+ private:
+ virtual bool ProcessLine() { return true; }
+ };
+
+ /** Run a process and send output to given parsers. */
+ static void RunProcess(struct cmsysProcess_s* cp,
+ OutputParser* out, OutputParser* err = 0);
+};
+
+#endif
diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx
new file mode 100644
index 000000000..fcf0a4903
--- /dev/null
+++ b/Source/cmProjectCommand.cxx
@@ -0,0 +1,100 @@
+/*============================================================================
+ 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 "cmProjectCommand.h"
+
+// cmProjectCommand
+bool cmProjectCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 1 )
+ {
+ this->SetError("PROJECT called with incorrect number of arguments");
+ return false;
+ }
+ this->Makefile->SetProjectName(args[0].c_str());
+
+ std::string bindir = args[0];
+ bindir += "_BINARY_DIR";
+ std::string srcdir = args[0];
+ srcdir += "_SOURCE_DIR";
+
+ this->Makefile->AddCacheDefinition
+ (bindir.c_str(),
+ this->Makefile->GetCurrentOutputDirectory(),
+ "Value Computed by CMake", cmCacheManager::STATIC);
+ this->Makefile->AddCacheDefinition
+ (srcdir.c_str(),
+ this->Makefile->GetCurrentDirectory(),
+ "Value Computed by CMake", cmCacheManager::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("PROJECT_NAME", args[0].c_str());
+
+ // Set the CMAKE_PROJECT_NAME variable to be the highest-level
+ // project name in the tree. If there are two project commands
+ // in the same CMakeLists.txt file, and it is the top level
+ // CMakeLists.txt file, then go with the last one, so that
+ // 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->AddDefinition("CMAKE_PROJECT_NAME", args[0].c_str());
+ this->Makefile->AddCacheDefinition
+ ("CMAKE_PROJECT_NAME",
+ args[0].c_str(),
+ "Value Computed by CMake", cmCacheManager::STATIC);
+ }
+
+ std::vector<std::string> languages;
+ if(args.size() > 1)
+ {
+ for(size_t i =1; i < args.size(); ++i)
+ {
+ languages.push_back(args[i]);
+ }
+ }
+ else
+ {
+ // if no language is specified do c and c++
+ languages.push_back("C");
+ languages.push_back("CXX");
+ }
+ this->Makefile->EnableLanguage(languages, false);
+ std::string extraInclude = "CMAKE_PROJECT_" + args[0] + "_INCLUDE";
+ const char* include = this->Makefile->GetDefinition(extraInclude.c_str());
+ if(include)
+ {
+ std::string fullFilePath;
+ bool readit =
+ this->Makefile->ReadListFile( this->Makefile->GetCurrentListFile(),
+ include);
+ if(!readit && !cmSystemTools::GetFatalErrorOccured())
+ {
+ std::string m =
+ "could not find file:\n"
+ " ";
+ m += include;
+ this->SetError(m.c_str());
+ return false;
+ }
+ }
+ return true;
+}
+
diff --git a/Source/cmProjectCommand.h b/Source/cmProjectCommand.h
new file mode 100644
index 000000000..88a1944b4
--- /dev/null
+++ b/Source/cmProjectCommand.h
@@ -0,0 +1,82 @@
+/*============================================================================
+ 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 cmProjectCommand_h
+#define cmProjectCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmProjectCommand
+ * \brief Specify the name for this build project.
+ *
+ * cmProjectCommand is used to specify a name for this build project.
+ * It is defined once per set of CMakeList.txt files (including
+ * all subdirectories). Currently it just sets the name of the workspace
+ * file for Microsoft Visual C++
+ */
+class cmProjectCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmProjectCommand;
+ }
+
+ /**
+ * 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 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.";
+ }
+
+ cmTypeMacro(cmProjectCommand, cmCommand);
+};
+
+
+
+#endif
diff --git a/Source/cmProperty.cxx b/Source/cmProperty.cxx
new file mode 100644
index 000000000..3b37cf3b8
--- /dev/null
+++ b/Source/cmProperty.cxx
@@ -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.
+============================================================================*/
+#include "cmProperty.h"
+#include "cmSystemTools.h"
+
+void cmProperty::Set(const char *name, const char *value)
+{
+ this->Name = name;
+ this->Value = value;
+ this->ValueHasBeenSet = true;
+}
+
+void cmProperty::Append(const char *name, const char *value, bool asString)
+{
+ this->Name = name;
+ if(!this->Value.empty() && *value && !asString)
+ {
+ this->Value += ";";
+ }
+ this->Value += value;
+ this->ValueHasBeenSet = true;
+}
+
+const char *cmProperty::GetValue() const
+{
+ if (this->ValueHasBeenSet)
+ {
+ return this->Value.c_str();
+ }
+ return 0;
+}
diff --git a/Source/cmProperty.h b/Source/cmProperty.h
new file mode 100644
index 000000000..e0fcd631e
--- /dev/null
+++ b/Source/cmProperty.h
@@ -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.
+============================================================================*/
+#ifndef cmProperty_h
+#define cmProperty_h
+
+#include "cmStandardIncludes.h"
+
+class cmProperty
+{
+public:
+ enum ScopeType { TARGET, SOURCE_FILE, DIRECTORY, GLOBAL, CACHE,
+ TEST, VARIABLE, CACHED_VARIABLE };
+
+ // set this property
+ void Set(const char *name, const char *value);
+
+ // append to this property
+ void Append(const char *name, const char *value, bool asString = false);
+
+ // get the value
+ const char *GetValue() const;
+
+ // construct with the value not set
+ cmProperty() { this->ValueHasBeenSet = false; };
+
+protected:
+ std::string Name;
+ std::string Value;
+ bool ValueHasBeenSet;
+};
+
+#endif
diff --git a/Source/cmPropertyDefinition.cxx b/Source/cmPropertyDefinition.cxx
new file mode 100644
index 000000000..b80c863f1
--- /dev/null
+++ b/Source/cmPropertyDefinition.cxx
@@ -0,0 +1,47 @@
+/*============================================================================
+ 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 "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,
+ const char *shortDescription,
+ const char *fullDescription,
+ const char *sec,
+ bool chain)
+{
+ this->Name = name;
+ this->Scope = scope;
+ this->Chained = chain;
+ if (shortDescription)
+ {
+ this->ShortDescription = shortDescription;
+ }
+ if (fullDescription)
+ {
+ this->FullDescription = fullDescription;
+ }
+ if (sec)
+ {
+ this->DocumentationSection = sec;
+ }
+}
+
diff --git a/Source/cmPropertyDefinition.h b/Source/cmPropertyDefinition.h
new file mode 100644
index 000000000..16bd148a7
--- /dev/null
+++ b/Source/cmPropertyDefinition.h
@@ -0,0 +1,70 @@
+/*============================================================================
+ 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 cmPropertyDefinition_h
+#define cmPropertyDefinition_h
+
+#include "cmProperty.h"
+
+/** \class cmPropertyDefinition
+ * \brief Property meta-information
+ *
+ * This class contains the following meta-information about property:
+ * - Name;
+ * - Various documentation strings;
+ * - The scope of the property;
+ * - If the property is chained.
+ */
+class cmPropertyDefinition
+{
+public:
+ /// Define this property
+ void DefineProperty(const char *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; };
+
+ /// Is the property chained?
+ bool IsChained() const { return this->Chained; };
+
+ /// Get the section if any
+ const std::string &GetDocumentationSection() const {
+ return this->DocumentationSection; };
+
+ /// Get the scope
+ cmProperty::ScopeType GetScope() const {
+ return this->Scope; };
+
+ /// Get the documentation (short version)
+ const std::string &GetShortDescription() const {
+ return this->ShortDescription; };
+
+ /// Get the documentation (full version)
+ const std::string &GetFullDescription() const {
+ return this->FullDescription; };
+
+protected:
+ std::string Name;
+ std::string ShortDescription;
+ std::string FullDescription;
+ std::string DocumentationSection;
+ cmProperty::ScopeType Scope;
+ bool Chained;
+};
+
+#endif
diff --git a/Source/cmPropertyDefinitionMap.cxx b/Source/cmPropertyDefinitionMap.cxx
new file mode 100644
index 000000000..fcdb93776
--- /dev/null
+++ b/Source/cmPropertyDefinitionMap.cxx
@@ -0,0 +1,125 @@
+/*============================================================================
+ 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 "cmPropertyDefinitionMap.h"
+#include "cmSystemTools.h"
+#include "cmDocumentationSection.h"
+
+void cmPropertyDefinitionMap
+::DefineProperty(const char *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);
+ }
+ }
+}
+
+bool cmPropertyDefinitionMap::IsPropertyDefined(const char *name)
+{
+ if (!name)
+ {
+ return false;
+ }
+
+ cmPropertyDefinitionMap::iterator it = this->find(name);
+ if (it == this->end())
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool cmPropertyDefinitionMap::IsPropertyChained(const char *name)
+{
+ if (!name)
+ {
+ return false;
+ }
+
+ cmPropertyDefinitionMap::iterator it = this->find(name);
+ if (it == this->end())
+ {
+ return false;
+ }
+
+ return it->second.IsChained();
+}
diff --git a/Source/cmPropertyDefinitionMap.h b/Source/cmPropertyDefinitionMap.h
new file mode 100644
index 000000000..c6f9d59cd
--- /dev/null
+++ b/Source/cmPropertyDefinitionMap.h
@@ -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.
+============================================================================*/
+#ifndef cmPropertyDefinitionMap_h
+#define cmPropertyDefinitionMap_h
+
+#include "cmPropertyDefinition.h"
+
+class cmDocumentationSection;
+
+class cmPropertyDefinitionMap :
+public std::map<cmStdString,cmPropertyDefinition>
+{
+public:
+ // define the property
+ void DefineProperty(const char *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);
+
+ // is a named property set to chain
+ bool IsPropertyChained(const char *name);
+
+ void GetPropertiesDocumentation(std::map<std::string,
+ cmDocumentationSection *>&) const;
+};
+
+#endif
+
diff --git a/Source/cmPropertyMap.cxx b/Source/cmPropertyMap.cxx
new file mode 100644
index 000000000..a4d0bf3d8
--- /dev/null
+++ b/Source/cmPropertyMap.cxx
@@ -0,0 +1,123 @@
+/*============================================================================
+ 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 "cmPropertyMap.h"
+#include "cmSystemTools.h"
+#include "cmake.h"
+
+cmProperty *cmPropertyMap::GetOrCreateProperty(const char *name)
+{
+ cmPropertyMap::iterator it = this->find(name);
+ cmProperty *prop;
+ if (it == this->end())
+ {
+ prop = &(*this)[name];
+ }
+ else
+ {
+ prop = &(it->second);
+ }
+ return prop;
+}
+
+void cmPropertyMap::SetProperty(const char *name, const char *value,
+ cmProperty::ScopeType scope)
+{
+ 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);
+}
+
+void cmPropertyMap::AppendProperty(const char* name, const char* value,
+ cmProperty::ScopeType scope, bool asString)
+{
+ // Skip if nothing to append.
+ if(!name || !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);
+}
+
+const char *cmPropertyMap
+::GetPropertyValue(const char *name,
+ cmProperty::ScopeType scope,
+ bool &chain) 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
+
+ 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
new file mode 100644
index 000000000..94275e2ac
--- /dev/null
+++ b/Source/cmPropertyMap.h
@@ -0,0 +1,43 @@
+/*============================================================================
+ 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 cmPropertyMap_h
+#define cmPropertyMap_h
+
+#include "cmProperty.h"
+
+class cmake;
+
+class cmPropertyMap : public std::map<cmStdString,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;
+
+ void SetCMakeInstance(cmake *cm) { this->CMakeInstance = cm; };
+
+ cmPropertyMap() { this->CMakeInstance = 0;};
+
+private:
+ cmake *CMakeInstance;
+};
+
+#endif
+
diff --git a/Source/cmQTWrapCPPCommand.cxx b/Source/cmQTWrapCPPCommand.cxx
new file mode 100644
index 000000000..1f1aed72f
--- /dev/null
+++ b/Source/cmQTWrapCPPCommand.cxx
@@ -0,0 +1,115 @@
+/*============================================================================
+ 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 "cmQTWrapCPPCommand.h"
+
+// cmQTWrapCPPCommand
+bool cmQTWrapCPPCommand::InitialPass(std::vector<std::string> const& argsIn,
+ cmExecutionStatus &)
+{
+ if(argsIn.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");
+
+ // Get the variable holding the list of sources.
+ std::string const& sourceList = args[1];
+ std::string sourceListValue =
+ this->Makefile->GetSafeDefinition(sourceList.c_str());
+
+ // Create a rule for all sources listed.
+ for(std::vector<std::string>::iterator j = (args.begin() + 2);
+ j != args.end(); ++j)
+ {
+ cmSourceFile *curr = this->Makefile->GetSource(j->c_str());
+ // 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();
+ newName += "/moc_";
+ newName += srcName;
+ newName += ".cxx";
+ cmSourceFile* sf =
+ this->Makefile->GetOrCreateSource(newName.c_str(), true);
+ if (curr)
+ {
+ sf->SetProperty("ABSTRACT", curr->GetProperty("ABSTRACT"));
+ }
+
+ // Compute the name of the header from which to generate the file.
+ std::string hname;
+ if(cmSystemTools::FileIsFullPath(j->c_str()))
+ {
+ hname = *j;
+ }
+ else
+ {
+ if(curr && curr->GetPropertyAsBool("GENERATED"))
+ {
+ hname = this->Makefile->GetCurrentOutputDirectory();
+ }
+ else
+ {
+ hname = this->Makefile->GetCurrentDirectory();
+ }
+ hname += "/";
+ hname += *j;
+ }
+
+ // Append the generated source file to the list.
+ if(!sourceListValue.empty())
+ {
+ sourceListValue += ";";
+ }
+ sourceListValue += newName;
+
+ // Create the custom command to generate the file.
+ cmCustomCommandLine commandLine;
+ commandLine.push_back(moc_exe);
+ commandLine.push_back("-o");
+ commandLine.push_back(newName);
+ commandLine.push_back(hname);
+
+ cmCustomCommandLines commandLines;
+ commandLines.push_back(commandLine);
+
+ std::vector<std::string> depends;
+ depends.push_back(moc_exe);
+ depends.push_back(hname);
+
+ const char* no_main_dependency = 0;
+ const char* no_working_dir = 0;
+ this->Makefile->AddCustomCommandToOutput(newName.c_str(),
+ depends,
+ no_main_dependency,
+ commandLines,
+ "Qt Wrapped File",
+ no_working_dir);
+ }
+ }
+
+ // Store the final list of source files.
+ this->Makefile->AddDefinition(sourceList.c_str(),
+ sourceListValue.c_str());
+ return true;
+}
diff --git a/Source/cmQTWrapCPPCommand.h b/Source/cmQTWrapCPPCommand.h
new file mode 100644
index 000000000..0184927c9
--- /dev/null
+++ b/Source/cmQTWrapCPPCommand.h
@@ -0,0 +1,74 @@
+/*============================================================================
+ 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 cmQTWrapCPPCommand_h
+#define cmQTWrapCPPCommand_h
+
+#include "cmCommand.h"
+
+#include "cmSourceFile.h"
+
+/** \class cmQTWrapCPPCommand
+ * \brief Create moc file rules for QT classes
+ *
+ * cmQTWrapCPPCommand is used to create wrappers for QT classes into
+ * normal C++
+ */
+class cmQTWrapCPPCommand : public cmCommand
+{
+public:
+ cmTypeMacro(cmQTWrapCPPCommand, cmCommand);
+
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmQTWrapCPPCommand;
+ }
+
+ /**
+ * 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 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.";
+ }
+};
+
+
+
+#endif
diff --git a/Source/cmQTWrapUICommand.cxx b/Source/cmQTWrapUICommand.cxx
new file mode 100644
index 000000000..bbecd8dcc
--- /dev/null
+++ b/Source/cmQTWrapUICommand.cxx
@@ -0,0 +1,166 @@
+/*============================================================================
+ 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 "cmQTWrapUICommand.h"
+
+// cmQTWrapUICommand
+bool cmQTWrapUICommand::InitialPass(std::vector<std::string> const& argsIn,
+ cmExecutionStatus &)
+{
+ if(argsIn.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");
+ const char* moc_exe =
+ this->Makefile->GetRequiredDefinition("QT_MOC_EXECUTABLE");
+
+ // Get the variable holding the list of sources.
+ std::string const& headerList = args[1];
+ std::string const& sourceList = args[2];
+ std::string headerListValue =
+ this->Makefile->GetSafeDefinition(headerList.c_str());
+ std::string sourceListValue =
+ this->Makefile->GetSafeDefinition(sourceList.c_str());
+
+ // Create rules for all sources listed.
+ for(std::vector<std::string>::iterator j = (args.begin() + 3);
+ j != args.end(); ++j)
+ {
+ cmSourceFile *curr = this->Makefile->GetSource(j->c_str());
+ // 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();
+ hName += "/";
+ hName += srcName;
+ hName += ".h";
+ std::string cxxName = this->Makefile->GetCurrentOutputDirectory();
+ cxxName += "/";
+ cxxName += srcName;
+ cxxName += ".cxx";
+ std::string mocName = this->Makefile->GetCurrentOutputDirectory();
+ mocName += "/moc_";
+ mocName += srcName;
+ mocName += ".cxx";
+
+ // Compute the name of the ui file from which to generate others.
+ std::string uiName;
+ if(cmSystemTools::FileIsFullPath(j->c_str()))
+ {
+ uiName = *j;
+ }
+ else
+ {
+ if(curr && curr->GetPropertyAsBool("GENERATED"))
+ {
+ uiName = this->Makefile->GetCurrentOutputDirectory();
+ }
+ else
+ {
+ uiName = this->Makefile->GetCurrentDirectory();
+ }
+ uiName += "/";
+ uiName += *j;
+ }
+
+ // create the list of headers
+ if(!headerListValue.empty())
+ {
+ headerListValue += ";";
+ }
+ headerListValue += hName;
+
+ // create the list of sources
+ if(!sourceListValue.empty())
+ {
+ sourceListValue += ";";
+ }
+ sourceListValue += cxxName;
+ sourceListValue += ";";
+ sourceListValue += mocName;
+
+ // set up .ui to .h and .cxx command
+ cmCustomCommandLine hCommand;
+ hCommand.push_back(uic_exe);
+ hCommand.push_back("-o");
+ hCommand.push_back(hName);
+ hCommand.push_back(uiName);
+ cmCustomCommandLines hCommandLines;
+ hCommandLines.push_back(hCommand);
+
+ cmCustomCommandLine cxxCommand;
+ cxxCommand.push_back(uic_exe);
+ cxxCommand.push_back("-impl");
+ cxxCommand.push_back(hName);
+ cxxCommand.push_back("-o");
+ cxxCommand.push_back(cxxName);
+ cxxCommand.push_back(uiName);
+ cmCustomCommandLines cxxCommandLines;
+ cxxCommandLines.push_back(cxxCommand);
+
+ cmCustomCommandLine mocCommand;
+ mocCommand.push_back(moc_exe);
+ mocCommand.push_back("-o");
+ mocCommand.push_back(mocName);
+ mocCommand.push_back(hName);
+ cmCustomCommandLines mocCommandLines;
+ mocCommandLines.push_back(mocCommand);
+
+ std::vector<std::string> depends;
+ depends.push_back(uiName);
+ const char* no_main_dependency = 0;
+ const char* no_comment = 0;
+ const char* no_working_dir = 0;
+ this->Makefile->AddCustomCommandToOutput(hName.c_str(),
+ depends,
+ no_main_dependency,
+ hCommandLines,
+ no_comment,
+ no_working_dir);
+
+ depends.push_back(hName);
+ this->Makefile->AddCustomCommandToOutput(cxxName.c_str(),
+ depends,
+ no_main_dependency,
+ cxxCommandLines,
+ no_comment,
+ no_working_dir);
+
+ depends.clear();
+ depends.push_back(hName);
+ this->Makefile->AddCustomCommandToOutput(mocName.c_str(),
+ depends,
+ no_main_dependency,
+ mocCommandLines,
+ no_comment,
+ no_working_dir);
+ }
+ }
+
+ // Store the final list of source files and headers.
+ this->Makefile->AddDefinition(sourceList.c_str(),
+ sourceListValue.c_str());
+ this->Makefile->AddDefinition(headerList.c_str(),
+ headerListValue.c_str());
+ return true;
+}
diff --git a/Source/cmQTWrapUICommand.h b/Source/cmQTWrapUICommand.h
new file mode 100644
index 000000000..744ae9838
--- /dev/null
+++ b/Source/cmQTWrapUICommand.h
@@ -0,0 +1,75 @@
+/*============================================================================
+ 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 cmQTWrapUICommand_h
+#define cmQTWrapUICommand_h
+
+#include "cmCommand.h"
+
+#include "cmSourceFile.h"
+
+/** \class cmQTWrapUICommand
+ * \brief Create .h and .cxx files rules for QT user interfaces files
+ *
+ * cmQTWrapUICommand is used to create wrappers for QT classes into normal C++
+ */
+class cmQTWrapUICommand : public cmCommand
+{
+public:
+ cmTypeMacro(cmQTWrapUICommand, cmCommand);
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmQTWrapUICommand;
+ }
+
+ /**
+ * 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 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.";
+ }
+};
+
+
+
+#endif
diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx
new file mode 100644
index 000000000..65ecdf73f
--- /dev/null
+++ b/Source/cmQtAutomoc.cxx
@@ -0,0 +1,1086 @@
+/*============================================================================
+ 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"
+
+#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::list<std::string>& headerExtensions)
+{
+ std::string header;
+ for(std::list<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;
+}
+
+
+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;
+ }
+ }
+}
+
+
+void cmQtAutomoc::SetupAutomocTarget(cmTarget* target)
+{
+ cmMakefile* makefile = target->GetMakefile();
+ const char* targetName = target->GetName();
+ // 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;
+ }
+
+ 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);
+
+ 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;
+
+ makefile->AddUtilityCommand(automocTargetName.c_str(), true,
+ workingDirectory.c_str(), depends,
+ commandLines, false, automocComment.c_str());
+ 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 = sf->GetFullPath();
+ 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 = makefile->GetProperty("INCLUDE_DIRECTORIES");
+ std::string _moc_incs = (tmp!=0 ? tmp : "");
+ tmp = makefile->GetProperty("DEFINITIONS");
+ std::string _moc_defs = (tmp!=0 ? tmp : "");
+ tmp = makefile->GetProperty("COMPILE_DEFINITIONS");
+ std::string _moc_compile_defs = (tmp!=0 ? tmp : "");
+ 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_incs",
+ cmLocalGenerator::EscapeForCMake(_moc_incs.c_str()).c_str());
+ makefile->AddDefinition("_moc_defs",
+ cmLocalGenerator::EscapeForCMake(_moc_defs.c_str()).c_str());
+ makefile->AddDefinition("_moc_compile_defs",
+ cmLocalGenerator::EscapeForCMake(_moc_compile_defs.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");
+
+ 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);
+
+ std::string mocCppFile = makefile->GetCurrentOutputDirectory();
+ mocCppFile += "/";
+ mocCppFile += automocTargetName;
+ mocCppFile += ".cpp";
+ cmSourceFile* mocCppSource = makefile->GetOrCreateSource(mocCppFile.c_str(),
+ true);
+ target->AddSourceFile(mocCppSource);
+
+ makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES",
+ mocCppFile.c_str(), false);
+}
+
+
+bool cmQtAutomoc::Run(const char* targetDirectory)
+{
+ bool success = true;
+ cmake cm;
+ cmGlobalGenerator* gg = this->CreateGlobalGenerator(&cm, targetDirectory);
+ cmMakefile* makefile = gg->GetCurrentLocalGenerator()->GetMakefile();
+
+ this->ReadAutomocInfoFile(makefile, targetDirectory);
+ this->ReadOldMocDefinitionsFile(makefile, targetDirectory);
+
+ this->Init();
+
+ if (this->QtMajorVersion == "4" || this->QtMajorVersion == "5")
+ {
+ success = this->RunAutomoc();
+ }
+
+ 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)
+{
+ 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");
+ this->MocCompileDefinitionsStr = makefile->GetSafeDefinition(
+ "AM_MOC_COMPILE_DEFINITIONS");
+ this->MocDefinitionsStr = makefile->GetSafeDefinition("AM_MOC_DEFINITIONS");
+ this->MocIncludesStr = makefile->GetSafeDefinition("AM_MOC_INCLUDES");
+ 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->RelaxedMode = makefile->IsOn("AM_RELAXED_MODE");
+
+ return true;
+}
+
+
+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->OldMocDefinitionsStr =
+ makefile->GetSafeDefinition("AM_OLD_MOC_DEFINITIONS");
+ }
+ 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_MOC_DEFINITIONS "
+ << cmLocalGenerator::EscapeForCMake(
+ this->Join(this->MocDefinitions, ' ').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);
+ if (!cdefList.empty())
+ {
+ for(std::vector<std::string>::const_iterator it = cdefList.begin();
+ it != cdefList.end();
+ ++it)
+ {
+ this->MocDefinitions.push_back("-D" + (*it));
+ }
+ }
+ else
+ {
+ std::string tmpMocDefs = this->MocDefinitionsStr;
+ cmSystemTools::ReplaceString(tmpMocDefs, " ", ";");
+
+ std::vector<std::string> defList;
+ cmSystemTools::ExpandListArgument(tmpMocDefs, defList);
+
+ for(std::vector<std::string>::const_iterator it = defList.begin();
+ it != defList.end();
+ ++it)
+ {
+ if (this->StartsWith(*it, "-D"))
+ {
+ this->MocDefinitions.push_back(*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()
+{
+ if (!cmsys::SystemTools::FileExists(this->OutMocCppFilename.c_str())
+ || (this->OldMocDefinitionsStr != this->Join(this->MocDefinitions, ' ')))
+ {
+ 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);
+
+ std::list<std::string> headerExtensions;
+ headerExtensions.push_back(".h");
+ headerExtensions.push_back(".hpp");
+ headerExtensions.push_back(".hxx");
+#if defined(_WIN32)
+ // not case sensitive, don't add ".H"
+#elif defined(__APPLE__)
+ // detect case-sensitive filesystem
+ long caseSensitive = pathconf(this->Srcdir.c_str(), _PC_CASE_SENSITIVE);
+ if (caseSensitive == 1)
+ {
+ headerExtensions.push_back(".H");
+ }
+#else
+ headerExtensions.push_back(".H");
+#endif
+
+ 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::list<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 simply 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::list<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 simply 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::list<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::list<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::list<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::list<std::string>& lst,char separator)
+{
+ if (lst.empty())
+ {
+ return "";
+ }
+
+ std::string result;
+ for (std::list<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
new file mode 100644
index 000000000..8cbbac19d
--- /dev/null
+++ b/Source/cmQtAutomoc.h
@@ -0,0 +1,92 @@
+/*============================================================================
+ 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);
+
+ void SetupAutomocTarget(cmTarget* target);
+
+private:
+ cmGlobalGenerator* CreateGlobalGenerator(cmake* cm,
+ const char* targetDirectory);
+
+ bool ReadAutomocInfoFile(cmMakefile* makefile,
+ const char* targetDirectory);
+ bool ReadOldMocDefinitionsFile(cmMakefile* makefile,
+ const char* targetDirectory);
+ void WriteOldMocDefinitionsFile(const char* targetDirectory);
+
+ bool RunAutomoc();
+ bool GenerateMoc(const std::string& sourceFile,
+ const std::string& mocFileName);
+ void ParseCppFile(const std::string& absFilename,
+ const std::list<std::string>& headerExtensions,
+ std::map<std::string, std::string>& includedMocs);
+ void StrictParseCppFile(const std::string& absFilename,
+ const std::list<std::string>& headerExtensions,
+ std::map<std::string, std::string>& includedMocs);
+ void SearchHeadersForCppFile(const std::string& absFilename,
+ const std::list<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::list<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 MocDefinitionsStr;
+ std::string MocIncludesStr;
+ std::string MocOptionsStr;
+ std::string ProjectBinaryDir;
+ std::string ProjectSourceDir;
+ std::string TargetName;
+
+ std::string OldMocDefinitionsStr;
+
+ 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/cmRemoveCommand.cxx b/Source/cmRemoveCommand.cxx
new file mode 100644
index 000000000..d80b3fe9f
--- /dev/null
+++ b/Source/cmRemoveCommand.cxx
@@ -0,0 +1,76 @@
+/*============================================================================
+ 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 "cmRemoveCommand.h"
+
+// cmRemoveCommand
+bool cmRemoveCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 1)
+ {
+ return true;
+ }
+
+ const char* variable = args[0].c_str(); // VAR is always first
+ // get the old value
+ const char* cacheValue
+ = this->Makefile->GetDefinition(variable);
+
+ // if there is no old value then return
+ if (!cacheValue)
+ {
+ return true;
+ }
+
+ // expand the variable
+ std::vector<std::string> varArgsExpanded;
+ cmSystemTools::ExpandListArgument(cacheValue, varArgsExpanded);
+
+ // expand the args
+ // 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]);
+ }
+ cmSystemTools::ExpandList(temp, argsExpanded);
+
+ // now create the new value
+ std::string value;
+ for(unsigned int j = 0; j < varArgsExpanded.size(); ++j)
+ {
+ int found = 0;
+ for(unsigned int k = 0; k < argsExpanded.size(); ++k)
+ {
+ if (varArgsExpanded[j] == argsExpanded[k])
+ {
+ found = 1;
+ break;
+ }
+ }
+ if (!found)
+ {
+ if (value.size())
+ {
+ value += ";";
+ }
+ value += varArgsExpanded[j];
+ }
+ }
+
+ // add the definition
+ this->Makefile->AddDefinition(variable, value.c_str());
+
+ return true;
+}
+
diff --git a/Source/cmRemoveCommand.h b/Source/cmRemoveCommand.h
new file mode 100644
index 000000000..c62d58f64
--- /dev/null
+++ b/Source/cmRemoveCommand.h
@@ -0,0 +1,81 @@
+/*============================================================================
+ 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 cmRemoveCommand_h
+#define cmRemoveCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmRemoveCommand
+ * \brief remove command
+ *
+ * cmRemoveCommand implements the remove CMake command
+ */
+class cmRemoveCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmRemoveCommand;
+ }
+
+ /**
+ * 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 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;
+ }
+
+ cmTypeMacro(cmRemoveCommand, cmCommand);
+};
+
+
+
+#endif
diff --git a/Source/cmRemoveDefinitionsCommand.cxx b/Source/cmRemoveDefinitionsCommand.cxx
new file mode 100644
index 000000000..b4be0f587
--- /dev/null
+++ b/Source/cmRemoveDefinitionsCommand.cxx
@@ -0,0 +1,31 @@
+/*============================================================================
+ 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 "cmRemoveDefinitionsCommand.h"
+
+// cmRemoveDefinitionsCommand
+bool cmRemoveDefinitionsCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ // it is OK to have no arguments
+ if(args.size() < 1 )
+ {
+ return true;
+ }
+
+ for(std::vector<std::string>::const_iterator i = args.begin();
+ i != args.end(); ++i)
+ {
+ this->Makefile->RemoveDefineFlag(i->c_str());
+ }
+ return true;
+}
+
diff --git a/Source/cmRemoveDefinitionsCommand.h b/Source/cmRemoveDefinitionsCommand.h
new file mode 100644
index 000000000..f0e906d15
--- /dev/null
+++ b/Source/cmRemoveDefinitionsCommand.h
@@ -0,0 +1,71 @@
+/*============================================================================
+ 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 cmRemoveDefinitionsCommand_h
+#define cmRemoveDefinitionsCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmRemoveDefinitionsCommand
+ * \brief Specify a list of compiler defines
+ *
+ * cmRemoveDefinitionsCommand specifies a list of compiler defines.
+ * These defines will
+ * be removed from the compile command.
+ */
+class cmRemoveDefinitionsCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmRemoveDefinitionsCommand;
+ }
+
+ /**
+ * 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 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.";
+ }
+
+ cmTypeMacro(cmRemoveDefinitionsCommand, cmCommand);
+};
+
+
+
+#endif
diff --git a/Source/cmReturnCommand.cxx b/Source/cmReturnCommand.cxx
new file mode 100644
index 000000000..51cc83fcd
--- /dev/null
+++ b/Source/cmReturnCommand.cxx
@@ -0,0 +1,21 @@
+/*============================================================================
+ 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 "cmReturnCommand.h"
+
+// cmReturnCommand
+bool cmReturnCommand::InitialPass(std::vector<std::string> const&,
+ cmExecutionStatus &status)
+{
+ status.SetReturnInvoked(true);
+ return true;
+}
+
diff --git a/Source/cmReturnCommand.h b/Source/cmReturnCommand.h
new file mode 100644
index 000000000..690ab79ca
--- /dev/null
+++ b/Source/cmReturnCommand.h
@@ -0,0 +1,81 @@
+/*============================================================================
+ 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 cmReturnCommand_h
+#define cmReturnCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmReturnCommand
+ * \brief Return from a directory or function
+ *
+ * cmReturnCommand returns from a directory or function
+ */
+class cmReturnCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmReturnCommand;
+ }
+
+ /**
+ * 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 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.";
+ }
+
+ cmTypeMacro(cmReturnCommand, cmCommand);
+};
+
+
+
+#endif
diff --git a/Source/cmScriptGenerator.cxx b/Source/cmScriptGenerator.cxx
new file mode 100644
index 000000000..cabe98a51
--- /dev/null
+++ b/Source/cmScriptGenerator.cxx
@@ -0,0 +1,237 @@
+/*============================================================================
+ 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 "cmScriptGenerator.h"
+
+#include "cmSystemTools.h"
+
+//----------------------------------------------------------------------------
+cmScriptGenerator
+::cmScriptGenerator(const char* config_var,
+ std::vector<std::string> const& configurations):
+ RuntimeConfigVariable(config_var),
+ Configurations(configurations),
+ ConfigurationName(0),
+ ConfigurationTypes(0),
+ ActionsPerConfig(false)
+{
+}
+
+//----------------------------------------------------------------------------
+cmScriptGenerator
+::~cmScriptGenerator()
+{
+}
+
+//----------------------------------------------------------------------------
+void
+cmScriptGenerator
+::Generate(std::ostream& os, const char* config,
+ std::vector<std::string> const& configurationTypes)
+{
+ this->ConfigurationName = config;
+ this->ConfigurationTypes = &configurationTypes;
+ this->GenerateScript(os);
+ this->ConfigurationName = 0;
+ this->ConfigurationTypes = 0;
+}
+
+//----------------------------------------------------------------------------
+static void cmScriptGeneratorEncodeConfig(const char* config,
+ std::string& result)
+{
+ for(const char* c = config; *c; ++c)
+ {
+ if(*c >= 'a' && *c <= 'z')
+ {
+ result += "[";
+ result += static_cast<char>(*c + 'A' - 'a');
+ result += *c;
+ result += "]";
+ }
+ else if(*c >= 'A' && *c <= 'Z')
+ {
+ result += "[";
+ result += *c;
+ result += static_cast<char>(*c + 'a' - 'A');
+ result += "]";
+ }
+ else
+ {
+ result += *c;
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmScriptGenerator::CreateConfigTest(const char* config)
+{
+ std::string result = "\"${";
+ result += this->RuntimeConfigVariable;
+ result += "}\" MATCHES \"^(";
+ if(config && *config)
+ {
+ cmScriptGeneratorEncodeConfig(config, result);
+ }
+ result += ")$\"";
+ return result;
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmScriptGenerator::CreateConfigTest(std::vector<std::string> const& configs)
+{
+ std::string result = "\"${";
+ result += this->RuntimeConfigVariable;
+ result += "}\" MATCHES \"^(";
+ const char* sep = "";
+ for(std::vector<std::string>::const_iterator ci = configs.begin();
+ ci != configs.end(); ++ci)
+ {
+ result += sep;
+ sep = "|";
+ cmScriptGeneratorEncodeConfig(ci->c_str(), result);
+ }
+ result += ")$\"";
+ return result;
+}
+
+//----------------------------------------------------------------------------
+void cmScriptGenerator::GenerateScript(std::ostream& os)
+{
+ // Track indentation.
+ Indent indent;
+
+ // Generate the script possibly with per-configuration code.
+ this->GenerateScriptConfigs(os, indent);
+}
+
+//----------------------------------------------------------------------------
+void cmScriptGenerator::GenerateScriptConfigs(std::ostream& os,
+ Indent const& indent)
+{
+ if(this->ActionsPerConfig)
+ {
+ this->GenerateScriptActionsPerConfig(os, indent);
+ }
+ else
+ {
+ this->GenerateScriptActionsOnce(os, indent);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmScriptGenerator::GenerateScriptActions(std::ostream& os,
+ Indent const& indent)
+{
+ if(this->ActionsPerConfig)
+ {
+ // This is reached for single-configuration build generators in a
+ // per-config script generator.
+ this->GenerateScriptForConfig(os, this->ConfigurationName, indent);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmScriptGenerator::GenerateScriptForConfig(std::ostream&, const char*,
+ Indent const&)
+{
+ // No actions for this generator.
+}
+
+//----------------------------------------------------------------------------
+bool cmScriptGenerator::GeneratesForConfig(const char* config)
+{
+ // If this is not a configuration-specific rule then we install.
+ if(this->Configurations.empty())
+ {
+ return true;
+ }
+
+ // This is a configuration-specific rule. Check if the config
+ // matches this rule.
+ std::string config_upper = cmSystemTools::UpperCase(config?config:"");
+ for(std::vector<std::string>::const_iterator i =
+ this->Configurations.begin();
+ i != this->Configurations.end(); ++i)
+ {
+ if(cmSystemTools::UpperCase(*i) == config_upper)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+void cmScriptGenerator::GenerateScriptActionsOnce(std::ostream& os,
+ Indent const& indent)
+{
+ if(this->Configurations.empty())
+ {
+ // This rule is for all configurations.
+ this->GenerateScriptActions(os, indent);
+ }
+ else
+ {
+ // Generate a per-configuration block.
+ std::string config_test = this->CreateConfigTest(this->Configurations);
+ os << indent << "IF(" << config_test << ")\n";
+ this->GenerateScriptActions(os, indent.Next());
+ os << indent << "ENDIF(" << config_test << ")\n";
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmScriptGenerator::GenerateScriptActionsPerConfig(std::ostream& os,
+ Indent const& indent)
+{
+ if(this->ConfigurationTypes->empty())
+ {
+ // In a single-configuration generator there is only one action
+ // and it applies if the runtime-requested configuration is among
+ // the rule's allowed configurations. The configuration built in
+ // the tree does not matter for this decision but will be used to
+ // generate proper target file names into the code.
+ this->GenerateScriptActionsOnce(os, indent);
+ }
+ else
+ {
+ // In a multi-configuration generator we produce a separate rule
+ // in a block for each configuration that is built. We restrict
+ // the list of configurations to those to which this rule applies.
+ bool first = true;
+ for(std::vector<std::string>::const_iterator i =
+ this->ConfigurationTypes->begin();
+ i != this->ConfigurationTypes->end(); ++i)
+ {
+ const char* config = i->c_str();
+ if(this->GeneratesForConfig(config))
+ {
+ // Generate a per-configuration block.
+ std::string config_test = this->CreateConfigTest(config);
+ os << indent << (first? "IF(" : "ELSEIF(") << config_test << ")\n";
+ this->GenerateScriptForConfig(os, config, indent.Next());
+ first = false;
+ }
+ }
+ if(!first)
+ {
+ if(this->NeedsScriptNoConfig())
+ {
+ os << indent << "ELSE()\n";
+ this->GenerateScriptNoConfig(os, indent.Next());
+ }
+ os << indent << "ENDIF()\n";
+ }
+ }
+}
diff --git a/Source/cmScriptGenerator.h b/Source/cmScriptGenerator.h
new file mode 100644
index 000000000..8b2ca335f
--- /dev/null
+++ b/Source/cmScriptGenerator.h
@@ -0,0 +1,96 @@
+/*============================================================================
+ 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 cmScriptGenerator_h
+#define cmScriptGenerator_h
+
+#include "cmStandardIncludes.h"
+
+class cmScriptGeneratorIndent
+{
+public:
+ cmScriptGeneratorIndent(): Level(0) {}
+ cmScriptGeneratorIndent(int level): Level(level) {}
+ void Write(std::ostream& os) const
+ {
+ for(int i=0; i < this->Level; ++i)
+ {
+ os << " ";
+ }
+ }
+ cmScriptGeneratorIndent Next(int step = 2) const
+ {
+ return cmScriptGeneratorIndent(this->Level + step);
+ }
+private:
+ int Level;
+};
+inline std::ostream& operator<<(std::ostream& os,
+ cmScriptGeneratorIndent const& indent)
+{
+ indent.Write(os);
+ return os;
+}
+
+/** \class cmScriptGenerator
+ * \brief Support class for generating install and test scripts.
+ *
+ */
+class cmScriptGenerator
+{
+public:
+ cmScriptGenerator(const char* config_var,
+ std::vector<std::string> const& configurations);
+ virtual ~cmScriptGenerator();
+
+ void Generate(std::ostream& os, const char* 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,
+ 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*);
+
+ std::string CreateConfigTest(const char* config);
+ std::string CreateConfigTest(std::vector<std::string> const& configs);
+ std::string CreateComponentTest(const char* component);
+
+ // Information shared by most generator types.
+ std::string RuntimeConfigVariable;
+ std::vector<std::string> const Configurations;
+
+ // Information used during generation.
+ const char* ConfigurationName;
+ std::vector<std::string> const* ConfigurationTypes;
+
+ // True if the subclass needs to generate an explicit rule for each
+ // configuration. False if the subclass only generates one rule for
+ // all enabled configurations.
+ bool ActionsPerConfig;
+
+private:
+ void GenerateScriptActionsOnce(std::ostream& os, Indent const& indent);
+ void GenerateScriptActionsPerConfig(std::ostream& os, Indent const& indent);
+};
+
+#endif
diff --git a/Source/cmSeparateArgumentsCommand.cxx b/Source/cmSeparateArgumentsCommand.cxx
new file mode 100644
index 000000000..6f620918b
--- /dev/null
+++ b/Source/cmSeparateArgumentsCommand.cxx
@@ -0,0 +1,109 @@
+/*============================================================================
+ 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 "cmSeparateArgumentsCommand.h"
+
+// cmSeparateArgumentsCommand
+bool cmSeparateArgumentsCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.empty())
+ {
+ this->SetError("must be given at least one argument.");
+ return false;
+ }
+
+ std::string var;
+ std::string command;
+ enum Mode { ModeOld, ModeUnix, ModeWindows };
+ Mode mode = ModeOld;
+ enum Doing { DoingNone, DoingVariable, DoingMode, DoingCommand };
+ Doing doing = DoingVariable;
+ for(unsigned int i=0; i < args.size(); ++i)
+ {
+ if(doing == DoingVariable)
+ {
+ var = args[i];
+ doing = DoingMode;
+ }
+ else if(doing == DoingMode && args[i] == "UNIX_COMMAND")
+ {
+ mode = ModeUnix;
+ doing = DoingCommand;
+ }
+ else if(doing == DoingMode && args[i] == "WINDOWS_COMMAND")
+ {
+ mode = ModeWindows;
+ doing = DoingCommand;
+ }
+ else if(doing == DoingCommand)
+ {
+ command = args[i];
+ doing = DoingNone;
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "given unknown argument " << args[i];
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+
+ if(mode == ModeOld)
+ {
+ // Original space-replacement version of command.
+ if(const char* def = this->Makefile->GetDefinition(var.c_str()))
+ {
+ std::string value = def;
+ cmSystemTools::ReplaceString(value, " ", ";");
+ this->Makefile->AddDefinition(var.c_str(), value.c_str());
+ }
+ }
+ else
+ {
+ // Parse the command line.
+ std::vector<std::string> vec;
+ if(mode == ModeUnix)
+ {
+ cmSystemTools::ParseUnixCommandLine(command.c_str(), vec);
+ }
+ else // if(mode == ModeWindows)
+ {
+ cmSystemTools::ParseWindowsCommandLine(command.c_str(), vec);
+ }
+
+ // Construct the result list value.
+ std::string value;
+ const char* sep = "";
+ for(std::vector<std::string>::const_iterator vi = vec.begin();
+ vi != vec.end(); ++vi)
+ {
+ // Separate from the previous argument.
+ value += sep;
+ sep = ";";
+
+ // Preserve semicolons.
+ for(std::string::const_iterator si = vi->begin();
+ si != vi->end(); ++si)
+ {
+ if(*si == ';')
+ {
+ value += '\\';
+ }
+ value += *si;
+ }
+ }
+ this->Makefile->AddDefinition(var.c_str(), value.c_str());
+ }
+
+ return true;
+}
diff --git a/Source/cmSeparateArgumentsCommand.h b/Source/cmSeparateArgumentsCommand.h
new file mode 100644
index 000000000..6a51a9223
--- /dev/null
+++ b/Source/cmSeparateArgumentsCommand.h
@@ -0,0 +1,92 @@
+/*============================================================================
+ 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 cmSeparateArgumentsCommand_h
+#define cmSeparateArgumentsCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmSeparateArgumentsCommand
+ * \brief separate_arguments command
+ *
+ * cmSeparateArgumentsCommand implements the separate_arguments CMake command
+ */
+class cmSeparateArgumentsCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmSeparateArgumentsCommand;
+ }
+
+ /**
+ * 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 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.";
+ }
+
+ cmTypeMacro(cmSeparateArgumentsCommand, cmCommand);
+};
+
+
+
+#endif
diff --git a/Source/cmSetCommand.cxx b/Source/cmSetCommand.cxx
new file mode 100644
index 000000000..d00fc86cf
--- /dev/null
+++ b/Source/cmSetCommand.cxx
@@ -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.
+============================================================================*/
+#include "cmSetCommand.h"
+
+// cmSetCommand
+bool cmSetCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 1 )
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ // watch for ENV signatures
+ const char* variable = args[0].c_str(); // VAR is always first
+ if (!strncmp(variable,"ENV{",4) && strlen(variable) > 5)
+ {
+ // what is the variable name
+ char *varName = new char [strlen(variable)];
+ strncpy(varName,variable+4,strlen(variable)-5);
+ varName[strlen(variable)-5] = '\0';
+ std::string putEnvArg = varName;
+ putEnvArg += "=";
+
+ // what is the current value if any
+ const char *currValue = getenv(varName);
+ delete [] varName;
+
+ // will it be set to something, then set it
+ if (args.size() > 1 && args[1].size())
+ {
+ // 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());
+ }
+ return true;
+ }
+
+ // if it will be cleared, then clear it if it isn;t already clear
+ if (currValue)
+ {
+ cmSystemTools::PutEnv(putEnvArg.c_str());
+ }
+ return true;
+ }
+
+ // SET (VAR) // Removes the definition of VAR.
+ if (args.size() == 1)
+ {
+ this->Makefile->RemoveDefinition(args[0].c_str());
+ return true;
+ }
+
+ // here are the remaining options
+ // SET (VAR value )
+ // 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
+ const char* docstring = 0; // required if cache
+
+ unsigned int ignoreLastArgs = 0;
+ // look for PARENT_SCOPE argument
+ if (args.size() > 1 && args[args.size()-1] == "PARENT_SCOPE")
+ {
+ parentScope = true;
+ ignoreLastArgs++;
+ }
+ else
+ {
+ // look for FORCE argument
+ if (args.size() > 4 && args[args.size()-1] == "FORCE")
+ {
+ force = true;
+ ignoreLastArgs++;
+ }
+
+ // check for cache signature
+ if (args.size() > 3 && args[args.size() - 3 - (force ? 1 : 0)] == "CACHE")
+ {
+ cache = true;
+ ignoreLastArgs+=3;
+ }
+ }
+
+ // 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];
+ }
+ }
+
+ if (parentScope)
+ {
+ if (value.empty())
+ {
+ this->Makefile->RaiseScope(variable, 0);
+ }
+ else
+ {
+ this->Makefile->RaiseScope(variable, value.c_str());
+ }
+ return true;
+ }
+
+
+ // we should be nice and try to catch some simple screwups if the last or
+ // next to last args are CACHE then they screwed up. If they used FORCE
+ // without CACHE they screwed up
+ if ((args[args.size() - 1] == "CACHE") ||
+ (args.size() > 1 && args[args.size() - 2] == "CACHE") ||
+ (force && !cache))
+ {
+ this->SetError("given invalid arguments for CACHE mode.");
+ return false;
+ }
+
+ if(cache)
+ {
+ std::string::size_type cacheStart = args.size() - 3 - (force ? 1 : 0);
+ type = cmCacheManager::StringToType(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))
+ {
+ // 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)
+ {
+ return true;
+ }
+ }
+
+ // if it is meant to be in the cache then define it in the cache
+ if(cache)
+ {
+ this->Makefile->AddCacheDefinition(variable,
+ value.c_str(),
+ docstring,
+ type, force);
+ }
+ else
+ {
+ // add the definition
+ this->Makefile->AddDefinition(variable, value.c_str());
+ }
+ return true;
+}
+
diff --git a/Source/cmSetCommand.h b/Source/cmSetCommand.h
new file mode 100644
index 000000000..2dd80e37f
--- /dev/null
+++ b/Source/cmSetCommand.h
@@ -0,0 +1,163 @@
+/*============================================================================
+ 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 cmSetCommand_h
+#define cmSetCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmSetCommand
+ * \brief Set a CMAKE variable
+ *
+ * cmSetCommand sets a variable to a value with expansion.
+ */
+class cmSetCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmSetCommand;
+ }
+
+ /**
+ * 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 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.";
+ }
+
+ cmTypeMacro(cmSetCommand, cmCommand);
+};
+
+
+
+#endif
diff --git a/Source/cmSetDirectoryPropertiesCommand.cxx b/Source/cmSetDirectoryPropertiesCommand.cxx
new file mode 100644
index 000000000..b956313a0
--- /dev/null
+++ b/Source/cmSetDirectoryPropertiesCommand.cxx
@@ -0,0 +1,70 @@
+/*============================================================================
+ 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 "cmSetDirectoryPropertiesCommand.h"
+
+#include "cmake.h"
+
+// cmSetDirectoryPropertiesCommand
+bool cmSetDirectoryPropertiesCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 1 )
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ std::string errors;
+ bool ret =
+ cmSetDirectoryPropertiesCommand::RunCommand(this->Makefile,
+ args.begin() + 1,
+ args.end(), errors);
+ if (!ret)
+ {
+ this->SetError(errors.c_str());
+ }
+ return ret;
+}
+
+bool cmSetDirectoryPropertiesCommand
+::RunCommand(cmMakefile *mf,
+ std::vector<std::string>::const_iterator ait,
+ std::vector<std::string>::const_iterator aitend,
+ std::string &errors)
+{
+ for (; ait != aitend; ait += 2 )
+ {
+ if ( ait +1 == aitend)
+ {
+ errors = "Wrong number of arguments";
+ return false;
+ }
+ const std::string& prop = *ait;
+ const std::string& value = *(ait+1);
+ if ( prop == "VARIABLES" )
+ {
+ errors =
+ "Variables and cache variables should be set using SET command";
+ return false;
+ }
+ else if ( prop == "MACROS" )
+ {
+ errors =
+ "Commands and macros cannot be set using SET_CMAKE_PROPERTIES";
+ return false;
+ }
+ mf->SetProperty(prop.c_str(), value.c_str());
+ }
+
+ return true;
+}
+
diff --git a/Source/cmSetDirectoryPropertiesCommand.h b/Source/cmSetDirectoryPropertiesCommand.h
new file mode 100644
index 000000000..ee401582a
--- /dev/null
+++ b/Source/cmSetDirectoryPropertiesCommand.h
@@ -0,0 +1,78 @@
+/*============================================================================
+ 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 cmSetDirectoryPropertiesCommand_h
+#define cmSetDirectoryPropertiesCommand_h
+
+#include "cmCommand.h"
+
+class cmSetDirectoryPropertiesCommand : public cmCommand
+{
+public:
+ virtual cmCommand* Clone()
+ {
+ return new cmSetDirectoryPropertiesCommand;
+ }
+
+ /**
+ * This is called when the command is first encountered in
+ * the input 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 const char* GetName() const { return "set_directory_properties";}
+
+ /**
+ * Succinct documentation.
+ */
+ virtual const char* GetTerseDocumentation() const
+ {
+ return "Set a property of the directory.";
+ }
+
+ /**
+ * Static entry point for use by other commands
+ */
+ static bool RunCommand(cmMakefile *mf,
+ std::vector<std::string>::const_iterator ait,
+ 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);
+};
+
+
+
+#endif
diff --git a/Source/cmSetPropertyCommand.cxx b/Source/cmSetPropertyCommand.cxx
new file mode 100644
index 000000000..cc10840fd
--- /dev/null
+++ b/Source/cmSetPropertyCommand.cxx
@@ -0,0 +1,483 @@
+/*============================================================================
+ 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 "cmSetPropertyCommand.h"
+#include "cmSetTargetPropertiesCommand.h"
+#include "cmSetTestsPropertiesCommand.h"
+#include "cmSetSourceFilesPropertiesCommand.h"
+
+#include "cmCacheManager.h"
+
+//----------------------------------------------------------------------------
+cmSetPropertyCommand::cmSetPropertyCommand()
+{
+ this->AppendMode = false;
+ this->AppendAsString = false;
+ this->Remove = true;
+}
+
+//----------------------------------------------------------------------------
+bool cmSetPropertyCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 2 )
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ // Get the scope on which to set the property.
+ std::vector<std::string>::const_iterator arg = args.begin();
+ cmProperty::ScopeType scope;
+ if(*arg == "GLOBAL")
+ {
+ scope = cmProperty::GLOBAL;
+ }
+ else if(*arg == "DIRECTORY")
+ {
+ scope = cmProperty::DIRECTORY;
+ }
+ else if(*arg == "TARGET")
+ {
+ scope = cmProperty::TARGET;
+ }
+ else if(*arg == "SOURCE")
+ {
+ scope = cmProperty::SOURCE_FILE;
+ }
+ else if(*arg == "TEST")
+ {
+ scope = cmProperty::TEST;
+ }
+ else if(*arg == "CACHE")
+ {
+ scope = cmProperty::CACHE;
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "given invalid scope " << *arg << ". "
+ << "Valid scopes are GLOBAL, DIRECTORY, TARGET, SOURCE, TEST, CACHE.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+
+ // Parse the rest of the arguments up to the values.
+ enum Doing { DoingNone, DoingNames, DoingProperty, DoingValues };
+ Doing doing = DoingNames;
+ const char* sep = "";
+ for(++arg; arg != args.end(); ++arg)
+ {
+ if(*arg == "PROPERTY")
+ {
+ doing = DoingProperty;
+ }
+ else if(*arg == "APPEND")
+ {
+ doing = DoingNone;
+ this->AppendMode = true;
+ this->AppendAsString = false;
+ }
+ else if(*arg == "APPEND_STRING")
+ {
+ doing = DoingNone;
+ this->AppendMode = true;
+ this->AppendAsString = true;
+ }
+ else if(doing == DoingNames)
+ {
+ this->Names.insert(*arg);
+ }
+ else if(doing == DoingProperty)
+ {
+ this->PropertyName = *arg;
+ doing = DoingValues;
+ }
+ else if(doing == DoingValues)
+ {
+ this->PropertyValue += sep;
+ sep = ";";
+ this->PropertyValue += *arg;
+ this->Remove = false;
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "given invalid argument \"" << *arg << "\".";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+
+ // Make sure a property name was found.
+ if(this->PropertyName.empty())
+ {
+ this->SetError("not given a PROPERTY <name> argument.");
+ return false;
+ }
+
+ // Dispatch property setting.
+ switch(scope)
+ {
+ case cmProperty::GLOBAL: return this->HandleGlobalMode();
+ case cmProperty::DIRECTORY: return this->HandleDirectoryMode();
+ case cmProperty::TARGET: return this->HandleTargetMode();
+ case cmProperty::SOURCE_FILE: return this->HandleSourceMode();
+ case cmProperty::TEST: return this->HandleTestMode();
+ case cmProperty::CACHE: return this->HandleCacheMode();
+
+ case cmProperty::VARIABLE:
+ case cmProperty::CACHED_VARIABLE:
+ break; // should never happen
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmSetPropertyCommand::HandleGlobalMode()
+{
+ if(!this->Names.empty())
+ {
+ this->SetError("given names for GLOBAL scope.");
+ return false;
+ }
+
+ // Set or append the property.
+ cmake* cm = this->Makefile->GetCMakeInstance();
+ const char* name = this->PropertyName.c_str();
+ const char *value = this->PropertyValue.c_str();
+ if (this->Remove)
+ {
+ value = 0;
+ }
+ if(this->AppendMode)
+ {
+ cm->AppendProperty(name, value, this->AppendAsString);
+ }
+ else
+ {
+ cm->SetProperty(name, value);
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmSetPropertyCommand::HandleDirectoryMode()
+{
+ if(this->Names.size() > 1)
+ {
+ this->SetError("allows at most one name for DIRECTORY scope.");
+ return false;
+ }
+
+ // Default to the current directory.
+ cmMakefile* mf = this->Makefile;
+
+ // Lookup the directory if given.
+ if(!this->Names.empty())
+ {
+ // Construct the directory name. Interpret relative paths with
+ // respect to the current directory.
+ std::string dir = *this->Names.begin();
+ if(!cmSystemTools::FileIsFullPath(dir.c_str()))
+ {
+ dir = this->Makefile->GetCurrentDirectory();
+ dir += "/";
+ dir += *this->Names.begin();
+ }
+
+ // The local generators are associated with collapsed paths.
+ dir = cmSystemTools::CollapseFullPath(dir.c_str());
+
+ // 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
+ {
+ // Could not find the directory.
+ this->SetError
+ ("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.");
+ return false;
+ }
+ }
+
+ // Set or append the property.
+ const char* name = this->PropertyName.c_str();
+ const char *value = this->PropertyValue.c_str();
+ if (this->Remove)
+ {
+ value = 0;
+ }
+ if(this->AppendMode)
+ {
+ mf->AppendProperty(name, value, this->AppendAsString);
+ }
+ else
+ {
+ mf->SetProperty(name, value);
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmSetPropertyCommand::HandleTargetMode()
+{
+ for(std::set<cmStdString>::const_iterator ni = this->Names.begin();
+ ni != this->Names.end(); ++ni)
+ {
+ if(cmTarget* target = this->Makefile->FindTargetToUse(ni->c_str()))
+ {
+ // Handle the current target.
+ if(!this->HandleTarget(target))
+ {
+ return false;
+ }
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "could not find TARGET " << *ni
+ << ". Perhaps it has not yet been created.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmSetPropertyCommand::HandleTarget(cmTarget* target)
+{
+ // Set or append the property.
+ const char* name = this->PropertyName.c_str();
+ const char *value = this->PropertyValue.c_str();
+ if (this->Remove)
+ {
+ value = 0;
+ }
+ if(this->AppendMode)
+ {
+ target->AppendProperty(name, value, this->AppendAsString);
+ }
+ else
+ {
+ target->SetProperty(name, value);
+ }
+
+ // Check the resulting value.
+ target->CheckProperty(name, this->Makefile);
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmSetPropertyCommand::HandleSourceMode()
+{
+ for(std::set<cmStdString>::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(!this->HandleSource(sf))
+ {
+ return false;
+ }
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "given SOURCE name that could not be found or created: " << *ni;
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmSetPropertyCommand::HandleSource(cmSourceFile* sf)
+{
+ // Set or append the property.
+ const char* name = this->PropertyName.c_str();
+ const char *value = this->PropertyValue.c_str();
+ if (this->Remove)
+ {
+ value = 0;
+ }
+
+ if(this->AppendMode)
+ {
+ sf->AppendProperty(name, value, this->AppendAsString);
+ }
+ else
+ {
+ sf->SetProperty(name, value);
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmSetPropertyCommand::HandleTestMode()
+{
+ // Look for tests with all names given.
+ std::set<cmStdString>::iterator next;
+ for(std::set<cmStdString>::iterator ni = this->Names.begin();
+ ni != this->Names.end(); ni = next)
+ {
+ next = ni;
+ ++next;
+ if(cmTest* test = this->Makefile->GetTest(ni->c_str()))
+ {
+ if(this->HandleTest(test))
+ {
+ this->Names.erase(ni);
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+
+ // Names that are still left were not found.
+ if(!this->Names.empty())
+ {
+ cmOStringStream e;
+ e << "given TEST names that do not exist:\n";
+ for(std::set<cmStdString>::const_iterator ni = this->Names.begin();
+ ni != this->Names.end(); ++ni)
+ {
+ e << " " << *ni << "\n";
+ }
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmSetPropertyCommand::HandleTest(cmTest* test)
+{
+ // Set or append the property.
+ const char* name = this->PropertyName.c_str();
+ const char *value = this->PropertyValue.c_str();
+ if (this->Remove)
+ {
+ value = 0;
+ }
+ if(this->AppendMode)
+ {
+ test->AppendProperty(name, value, this->AppendAsString);
+ }
+ else
+ {
+ test->SetProperty(name, value);
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmSetPropertyCommand::HandleCacheMode()
+{
+ if(this->PropertyName == "ADVANCED")
+ {
+ if(!this->Remove &&
+ !cmSystemTools::IsOn(this->PropertyValue.c_str()) &&
+ !cmSystemTools::IsOff(this->PropertyValue.c_str()))
+ {
+ cmOStringStream e;
+ e << "given non-boolean value \"" << this->PropertyValue
+ << "\" for CACHE property \"ADVANCED\". ";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+ else if(this->PropertyName == "TYPE")
+ {
+ if(!cmCacheManager::IsType(this->PropertyValue.c_str()))
+ {
+ cmOStringStream e;
+ e << "given invalid CACHE entry TYPE \"" << this->PropertyValue << "\"";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+ else if(this->PropertyName != "HELPSTRING" &&
+ this->PropertyName != "STRINGS" &&
+ this->PropertyName != "VALUE")
+ {
+ cmOStringStream e;
+ e << "given invalid CACHE property " << this->PropertyName << ". "
+ << "Settable CACHE properties are: "
+ << "ADVANCED, HELPSTRING, STRINGS, TYPE, and VALUE.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+
+ for(std::set<cmStdString>::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())
+ {
+ if(!this->HandleCacheEntry(it))
+ {
+ return false;
+ }
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "could not find CACHE variable " << *ni
+ << ". Perhaps it has not yet been created.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmSetPropertyCommand::HandleCacheEntry(cmCacheManager::CacheIterator& it)
+{
+ // Set or append the property.
+ const char* name = this->PropertyName.c_str();
+ const char* value = this->PropertyValue.c_str();
+ if (this->Remove)
+ {
+ value = 0;
+ }
+ if(this->AppendMode)
+ {
+ it.AppendProperty(name, value, this->AppendAsString);
+ }
+ else
+ {
+ it.SetProperty(name, value);
+ }
+
+ return true;
+}
diff --git a/Source/cmSetPropertyCommand.h b/Source/cmSetPropertyCommand.h
new file mode 100644
index 000000000..830299d46
--- /dev/null
+++ b/Source/cmSetPropertyCommand.h
@@ -0,0 +1,116 @@
+/*============================================================================
+ 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 cmSetsPropertiesCommand_h
+#define cmSetsPropertiesCommand_h
+
+#include "cmCommand.h"
+
+class cmSetPropertyCommand : public cmCommand
+{
+public:
+ cmSetPropertyCommand();
+
+ virtual cmCommand* Clone()
+ {
+ return new cmSetPropertyCommand;
+ }
+
+ /**
+ * This is called when the command is first encountered in
+ * the input file.
+ */
+ 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 "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."
+ ;
+ }
+
+ /**
+ * This determines if the command is invoked when in script mode.
+ */
+ virtual bool IsScriptable() const { return true; }
+
+ cmTypeMacro(cmSetPropertyCommand, cmCommand);
+
+private:
+ std::set<cmStdString> Names;
+ std::string PropertyName;
+ std::string PropertyValue;
+ bool Remove;
+ bool AppendMode;
+ bool AppendAsString;
+
+ // Implementation of each property type.
+ bool HandleGlobalMode();
+ bool HandleDirectoryMode();
+ bool HandleTargetMode();
+ bool HandleTarget(cmTarget* target);
+ bool HandleSourceMode();
+ bool HandleSource(cmSourceFile* sf);
+ bool HandleTestMode();
+ bool HandleTest(cmTest* test);
+ bool HandleCacheMode();
+ bool HandleCacheEntry(cmCacheManager::CacheIterator&);
+};
+
+
+
+#endif
diff --git a/Source/cmSetSourceFilesPropertiesCommand.cxx b/Source/cmSetSourceFilesPropertiesCommand.cxx
new file mode 100644
index 000000000..89ff4b18b
--- /dev/null
+++ b/Source/cmSetSourceFilesPropertiesCommand.cxx
@@ -0,0 +1,170 @@
+/*============================================================================
+ 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 "cmSetSourceFilesPropertiesCommand.h"
+
+#include "cmSourceFile.h"
+
+// cmSetSourceFilesPropertiesCommand
+bool cmSetSourceFilesPropertiesCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 2 )
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ // break the arguments into source file names and properties
+ int numFiles = 0;
+ std::vector<std::string>::const_iterator j;
+ j = args.begin();
+ // old style allows for specifier before PROPERTIES keyword
+ while (j != args.end() &&
+ *j != "ABSTRACT" &&
+ *j != "WRAP_EXCLUDE" &&
+ *j != "GENERATED" &&
+ *j != "COMPILE_FLAGS" &&
+ *j != "OBJECT_DEPENDS" &&
+ *j != "PROPERTIES")
+ {
+ numFiles++;
+ ++j;
+ }
+
+ // now call the worker function
+ std::string errors;
+ bool ret =
+ cmSetSourceFilesPropertiesCommand
+ ::RunCommand(this->Makefile,
+ args.begin(),
+ args.begin() + numFiles,
+ args.begin() + numFiles,
+ args.end(), errors);
+ if (!ret)
+ {
+ this->SetError(errors.c_str());
+ }
+ return ret;
+}
+
+bool cmSetSourceFilesPropertiesCommand
+::RunCommand(cmMakefile *mf,
+ std::vector<std::string>::const_iterator filebeg,
+ std::vector<std::string>::const_iterator fileend,
+ std::vector<std::string>::const_iterator propbeg,
+ std::vector<std::string>::const_iterator propend,
+ std::string &errors)
+{
+ std::vector<std::string> propertyPairs;
+ bool generated = false;
+ std::vector<std::string>::const_iterator j;
+ // build the property pairs
+ for(j= propbeg; j != propend;++j)
+ {
+ // old style allows for specifier before PROPERTIES keyword
+ if(*j == "ABSTRACT")
+ {
+ propertyPairs.push_back("ABSTRACT");
+ propertyPairs.push_back("1");
+ }
+ else if(*j == "WRAP_EXCLUDE")
+ {
+ propertyPairs.push_back("WRAP_EXCLUDE");
+ propertyPairs.push_back("1");
+ }
+ else if(*j == "GENERATED")
+ {
+ generated = true;
+ propertyPairs.push_back("GENERATED");
+ propertyPairs.push_back("1");
+ }
+ else if(*j == "COMPILE_FLAGS")
+ {
+ propertyPairs.push_back("COMPILE_FLAGS");
+ ++j;
+ if(j == propend)
+ {
+ errors = "called with incorrect number of arguments "
+ "COMPILE_FLAGS with no flags";
+ return false;
+ }
+ propertyPairs.push_back(*j);
+ }
+ else if(*j == "OBJECT_DEPENDS")
+ {
+ propertyPairs.push_back("OBJECT_DEPENDS");
+ ++j;
+ if(j == propend)
+ {
+ errors = "called with incorrect number of arguments "
+ "OBJECT_DEPENDS with no dependencies";
+ return false;
+ }
+ propertyPairs.push_back(*j);
+ }
+ else if(*j == "PROPERTIES")
+ {
+ // now loop through the rest of the arguments, new style
+ ++j;
+ while (j != propend)
+ {
+ propertyPairs.push_back(*j);
+ if(*j == "GENERATED")
+ {
+ ++j;
+ if(j != propend && cmSystemTools::IsOn(j->c_str()))
+ {
+ generated = true;
+ }
+ }
+ else
+ {
+ ++j;
+ }
+ if(j == propend)
+ {
+ errors = "called with incorrect number of arguments.";
+ return false;
+ }
+ propertyPairs.push_back(*j);
+ ++j;
+ }
+ // break out of the loop because j is already == end
+ break;
+ }
+ else
+ {
+ errors = "called with illegal arguments, maybe missing a "
+ "PROPERTIES specifier?";
+ return false;
+ }
+ }
+
+ // now loop over all the files
+ for(j= filebeg; j != fileend;++j)
+ {
+ // get the source file
+ cmSourceFile* sf =
+ mf->GetOrCreateSource(j->c_str(), 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());
+ }
+ }
+ }
+ return true;
+}
+
diff --git a/Source/cmSetSourceFilesPropertiesCommand.h b/Source/cmSetSourceFilesPropertiesCommand.h
new file mode 100644
index 000000000..2a67bc09f
--- /dev/null
+++ b/Source/cmSetSourceFilesPropertiesCommand.h
@@ -0,0 +1,74 @@
+/*============================================================================
+ 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 cmSetSourceFilesPropertiesCommand_h
+#define cmSetSourceFilesPropertiesCommand_h
+
+#include "cmCommand.h"
+
+class cmSetSourceFilesPropertiesCommand : public cmCommand
+{
+public:
+ virtual cmCommand* Clone()
+ {
+ return new cmSetSourceFilesPropertiesCommand;
+ }
+
+ /**
+ * This is called when the command is first encountered in
+ * the input file.
+ */
+ 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 "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).";
+ }
+
+ cmTypeMacro(cmSetSourceFilesPropertiesCommand, cmCommand);
+
+ static bool RunCommand(cmMakefile *mf,
+ std::vector<std::string>::const_iterator filebeg,
+ std::vector<std::string>::const_iterator fileend,
+ std::vector<std::string>::const_iterator propbeg,
+ std::vector<std::string>::const_iterator propend,
+ std::string &errors);
+};
+
+
+
+#endif
diff --git a/Source/cmSetTargetPropertiesCommand.cxx b/Source/cmSetTargetPropertiesCommand.cxx
new file mode 100644
index 000000000..45a305e32
--- /dev/null
+++ b/Source/cmSetTargetPropertiesCommand.cxx
@@ -0,0 +1,110 @@
+/*============================================================================
+ 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 "cmSetTargetPropertiesCommand.h"
+#include "cmLocalGenerator.h"
+#include "cmGlobalGenerator.h"
+
+// cmSetTargetPropertiesCommand
+bool cmSetTargetPropertiesCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 2 )
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ // 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())
+ {
+ propertyPairs.push_back(*j);
+ ++j;
+ if(j == args.end())
+ {
+ this->SetError("called with incorrect number of arguments.");
+ return false;
+ }
+ propertyPairs.push_back(*j);
+ ++j;
+ }
+ // break out of the loop because j is already == end
+ break;
+ }
+ else if (doingFiles)
+ {
+ numFiles++;
+ }
+ else
+ {
+ this->SetError("called with illegal arguments, maybe missing "
+ "a PROPERTIES specifier?");
+ return false;
+ }
+ }
+ if(propertyPairs.size() == 0)
+ {
+ 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)
+ {
+ bool ret = cmSetTargetPropertiesCommand::SetOneTarget
+ (args[i].c_str(),propertyPairs,this->Makefile);
+ if (!ret)
+ {
+ std::string message = "Can not find target to add properties to: ";
+ message += args[i];
+ this->SetError(message.c_str());
+ return false;
+ }
+ }
+ return true;
+}
+
+bool cmSetTargetPropertiesCommand
+::SetOneTarget(const char *tname,
+ std::vector<std::string> &propertyPairs,
+ cmMakefile *mf)
+{
+ if(cmTarget* target = mf->FindTargetToUse(tname))
+ {
+ // now loop through all the props and set them
+ unsigned int k;
+ for (k = 0; k < propertyPairs.size(); k = k + 2)
+ {
+ target->SetProperty(propertyPairs[k].c_str(),
+ propertyPairs[k+1].c_str());
+ target->CheckProperty(propertyPairs[k].c_str(), mf);
+ }
+ }
+ // if file is not already in the makefile, then add it
+ else
+ {
+ return false;
+ }
+ return true;
+}
diff --git a/Source/cmSetTargetPropertiesCommand.h b/Source/cmSetTargetPropertiesCommand.h
new file mode 100644
index 000000000..1bc429cfd
--- /dev/null
+++ b/Source/cmSetTargetPropertiesCommand.h
@@ -0,0 +1,168 @@
+/*============================================================================
+ 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 cmSetTargetsPropertiesCommand_h
+#define cmSetTargetsPropertiesCommand_h
+
+#include "cmCommand.h"
+
+class cmSetTargetPropertiesCommand : public cmCommand
+{
+public:
+ virtual cmCommand* Clone()
+ {
+ return new cmSetTargetPropertiesCommand;
+ }
+
+ /**
+ * This is called when the command is first encountered in
+ * the input file.
+ */
+ 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 "set_target_properties";}
+
+ /**
+ * Succinct documentation.
+ */
+ virtual const char* GetTerseDocumentation() const
+ {
+ return "Targets can have properties that affect how they are built.";
+ }
+
+ /**
+ * Used by this command and cmSetPropertiesCommand
+ */
+ static bool SetOneTarget(const char *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\"."
+ ;
+ }
+
+ cmTypeMacro(cmSetTargetPropertiesCommand, cmCommand);
+};
+
+
+
+#endif
diff --git a/Source/cmSetTestsPropertiesCommand.cxx b/Source/cmSetTestsPropertiesCommand.cxx
new file mode 100644
index 000000000..e4fee18f1
--- /dev/null
+++ b/Source/cmSetTestsPropertiesCommand.cxx
@@ -0,0 +1,117 @@
+/*============================================================================
+ 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 "cmSetTestsPropertiesCommand.h"
+
+#include "cmake.h"
+#include "cmTest.h"
+
+// cmSetTestsPropertiesCommand
+bool cmSetTestsPropertiesCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 1 )
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ // 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())
+ {
+ propertyPairs.push_back(*j);
+ ++j;
+ if(j == args.end())
+ {
+ this->SetError("called with incorrect number of arguments.");
+ return false;
+ }
+ propertyPairs.push_back(*j);
+ ++j;
+ }
+ // break out of the loop because j is already == end
+ break;
+ }
+ else if (doingFiles)
+ {
+ numFiles++;
+ }
+ else
+ {
+ this->SetError("called with illegal arguments, maybe "
+ "missing a PROPERTIES specifier?");
+ return false;
+ }
+ }
+ if(propertyPairs.size() == 0)
+ {
+ 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(),
+ propertyPairs,
+ this->Makefile, errors);
+ if (!ret)
+ {
+ this->SetError(errors.c_str());
+ return ret;
+ }
+ }
+
+ return true;
+}
+
+
+bool cmSetTestsPropertiesCommand
+::SetOneTest(const char *tname,
+ std::vector<std::string> &propertyPairs,
+ cmMakefile *mf, std::string &errors)
+{
+ if(cmTest* test = mf->GetTest(tname))
+ {
+ // now loop through all the props and set them
+ unsigned int k;
+ for (k = 0; k < propertyPairs.size(); k = k + 2)
+ {
+ test->SetProperty(propertyPairs[k].c_str(),
+ propertyPairs[k+1].c_str());
+ }
+ }
+ else
+ {
+ errors = "Can not find test to add properties to: ";
+ errors += tname;
+ return false;
+ }
+
+ return true;
+}
+
diff --git a/Source/cmSetTestsPropertiesCommand.h b/Source/cmSetTestsPropertiesCommand.h
new file mode 100644
index 000000000..10df17dd8
--- /dev/null
+++ b/Source/cmSetTestsPropertiesCommand.h
@@ -0,0 +1,81 @@
+/*============================================================================
+ 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 cmSetTestsPropertiesCommand_h
+#define cmSetTestsPropertiesCommand_h
+
+#include "cmCommand.h"
+
+class cmSetTestsPropertiesCommand : public cmCommand
+{
+public:
+ virtual cmCommand* Clone()
+ {
+ return new cmSetTestsPropertiesCommand;
+ }
+
+ /**
+ * This is called when the command is first encountered in
+ * the input file.
+ */
+ 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 "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";
+ }
+
+ cmTypeMacro(cmSetTestsPropertiesCommand, cmCommand);
+
+ static bool SetOneTest(const char *tname,
+ std::vector<std::string> &propertyPairs,
+ cmMakefile *mf,
+ std::string &errors);
+};
+
+
+
+#endif
diff --git a/Source/cmSiteNameCommand.cxx b/Source/cmSiteNameCommand.cxx
new file mode 100644
index 000000000..04e357ca8
--- /dev/null
+++ b/Source/cmSiteNameCommand.cxx
@@ -0,0 +1,95 @@
+/*============================================================================
+ 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 "cmSiteNameCommand.h"
+
+#include <cmsys/RegularExpression.hxx>
+
+// cmSiteNameCommand
+bool cmSiteNameCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() != 1 )
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+ std::vector<std::string> paths;
+ paths.push_back("/usr/bsd");
+ paths.push_back("/usr/sbin");
+ paths.push_back("/usr/bin");
+ paths.push_back("/bin");
+ paths.push_back("/sbin");
+ paths.push_back("/usr/local/bin");
+
+ const char* cacheValue
+ = this->Makefile->GetDefinition(args[0].c_str());
+ if(cacheValue)
+ {
+ return true;
+ }
+
+ const char *temp = this->Makefile->GetDefinition("HOSTNAME");
+ std::string hostname_cmd;
+ if(temp)
+ {
+ hostname_cmd = temp;
+ }
+ else
+ {
+ hostname_cmd = cmSystemTools::FindProgram("hostname", paths);
+ }
+
+ std::string siteName = "unknown";
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ std::string host;
+ if(cmSystemTools::ReadRegistryValue
+ ("HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\"
+ "Control\\ComputerName\\ComputerName;ComputerName", host))
+ {
+ siteName = host;
+ }
+#else
+ // try to find the hostname for this computer
+ if (!cmSystemTools::IsOff(hostname_cmd.c_str()))
+ {
+ std::string host;
+ cmSystemTools::RunSingleCommand(hostname_cmd.c_str(),
+ &host, 0, 0, cmSystemTools::OUTPUT_NONE);
+
+ // got the hostname
+ if (host.length())
+ {
+ // remove any white space from the host name
+ std::string hostRegExp = "[ \t\n\r]*([^\t\n\r ]*)[ \t\n\r]*";
+ cmsys::RegularExpression hostReg (hostRegExp.c_str());
+ if (hostReg.find(host.c_str()))
+ {
+ // strip whitespace
+ host = hostReg.match(1);
+ }
+
+ if(host.length())
+ {
+ siteName = host;
+ }
+ }
+ }
+#endif
+ this->Makefile->
+ AddCacheDefinition(args[0].c_str(),
+ siteName.c_str(),
+ "Name of the computer/site where compile is being run",
+ cmCacheManager::STRING);
+
+ return true;
+}
+
diff --git a/Source/cmSiteNameCommand.h b/Source/cmSiteNameCommand.h
new file mode 100644
index 000000000..532710cc1
--- /dev/null
+++ b/Source/cmSiteNameCommand.h
@@ -0,0 +1,72 @@
+/*============================================================================
+ 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 cmSiteNameCommand_h
+#define cmSiteNameCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmSiteNameCommand
+ * \brief site_name command
+ *
+ * cmSiteNameCommand implements the site_name CMake command
+ */
+class cmSiteNameCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmSiteNameCommand;
+ }
+
+ /**
+ * 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 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";
+ }
+
+ cmTypeMacro(cmSiteNameCommand, cmCommand);
+};
+
+
+
+#endif
diff --git a/Source/cmSourceFile.cxx b/Source/cmSourceFile.cxx
new file mode 100644
index 000000000..cd94753cb
--- /dev/null
+++ b/Source/cmSourceFile.cxx
@@ -0,0 +1,557 @@
+/*============================================================================
+ 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 "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):
+ Location(mf, name)
+{
+ this->CustomCommand = 0;
+ this->Properties.SetCMakeInstance(mf->GetCMakeInstance());
+ this->FindFullPathFailed = false;
+}
+
+//----------------------------------------------------------------------------
+cmSourceFile::~cmSourceFile()
+{
+ this->SetCustomCommand(0);
+}
+
+//----------------------------------------------------------------------------
+std::string const& cmSourceFile::GetExtension() const
+{
+ return this->Extension;
+}
+
+//----------------------------------------------------------------------------
+const char* cmSourceFile::GetLanguage()
+{
+ // If the language was set explicitly by the user then use it.
+ if(const char* lang = this->GetProperty("LANGUAGE"))
+ {
+ return lang;
+ }
+
+ // Perform computation needed to get the language if necessary.
+ if(this->FullPath.empty() && this->Language.empty())
+ {
+ // If a known extension is given or a known full path is given
+ // then trust that the current extension is sufficient to
+ // determine the language. This will fail only if the user
+ // specifies a full path to the source but leaves off the
+ // extension, which is kind of weird.
+ if(this->Location.ExtensionIsAmbiguous() &&
+ this->Location.DirectoryIsAmbiguous())
+ {
+ // Finalize the file location to get the extension and set the
+ // language.
+ this->GetFullPath();
+ }
+ else
+ {
+ // Use the known extension to get the language if possible.
+ std::string ext =
+ cmSystemTools::GetFilenameLastExtension(this->Location.GetName());
+ this->CheckLanguage(ext);
+ }
+ }
+
+ // Now try to determine the language.
+ return static_cast<cmSourceFile const*>(this)->GetLanguage();
+}
+
+//----------------------------------------------------------------------------
+const char* cmSourceFile::GetLanguage() const
+{
+ // If the language was set explicitly by the user then use it.
+ if(const char* lang = this->GetProperty("LANGUAGE"))
+ {
+ return lang;
+ }
+
+ // If the language was determined from the source file extension use it.
+ if(!this->Language.empty())
+ {
+ return this->Language.c_str();
+ }
+
+ // The language is not known.
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+cmSourceFileLocation const& cmSourceFile::GetLocation() const
+{
+ return this->Location;
+}
+
+//----------------------------------------------------------------------------
+std::string const& cmSourceFile::GetFullPath(std::string* error)
+{
+ if(this->FullPath.empty())
+ {
+ if(this->FindFullPath(error))
+ {
+ this->CheckExtension();
+ }
+ }
+ return this->FullPath;
+}
+
+//----------------------------------------------------------------------------
+std::string const& cmSourceFile::GetFullPath() const
+{
+ return this->FullPath;
+}
+
+//----------------------------------------------------------------------------
+bool cmSourceFile::FindFullPath(std::string* error)
+{
+ // If thie method has already failed once do not try again.
+ if(this->FindFullPathFailed)
+ {
+ return false;
+ }
+
+ // If the file is generated compute the location without checking on
+ // disk.
+ if(this->GetPropertyAsBool("GENERATED"))
+ {
+ // The file is either already a full path or is relative to the
+ // build directory for the target.
+ this->Location.DirectoryUseBinary();
+ this->FullPath = this->Location.GetDirectory();
+ this->FullPath += "/";
+ this->FullPath += this->Location.GetName();
+ return true;
+ }
+
+ // The file is not generated. It must exist on disk.
+ cmMakefile* mf = this->Location.GetMakefile();
+ const char* tryDirs[3] = {0, 0, 0};
+ if(this->Location.DirectoryIsAmbiguous())
+ {
+ tryDirs[0] = mf->GetCurrentDirectory();
+ tryDirs[1] = mf->GetCurrentOutputDirectory();
+ }
+ else
+ {
+ tryDirs[0] = "";
+ }
+ const std::vector<std::string>& srcExts = mf->GetSourceExtensions();
+ const std::vector<std::string>& hdrExts = mf->GetHeaderExtensions();
+ for(const char* const* di = tryDirs; *di; ++di)
+ {
+ std::string tryPath = this->Location.GetDirectory();
+ if(!tryPath.empty())
+ {
+ tryPath += "/";
+ }
+ tryPath += this->Location.GetName();
+ tryPath = cmSystemTools::CollapseFullPath(tryPath.c_str(), *di);
+ if(this->TryFullPath(tryPath.c_str(), 0))
+ {
+ 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()))
+ {
+ return true;
+ }
+ }
+ for(std::vector<std::string>::const_iterator ei = hdrExts.begin();
+ ei != hdrExts.end(); ++ei)
+ {
+ if(this->TryFullPath(tryPath.c_str(), ei->c_str()))
+ {
+ return true;
+ }
+ }
+ }
+
+ cmOStringStream e;
+ std::string missing = this->Location.GetDirectory();
+ if(!missing.empty())
+ {
+ missing += "/";
+ }
+ missing += this->Location.GetName();
+ e << "Cannot find source file:\n " << missing << "\nTried extensions";
+ for(std::vector<std::string>::const_iterator ext = srcExts.begin();
+ ext != srcExts.end(); ++ext)
+ {
+ e << " ." << *ext;
+ }
+ for(std::vector<std::string>::const_iterator ext = hdrExts.begin();
+ ext != hdrExts.end(); ++ext)
+ {
+ e << " ." << *ext;
+ }
+ if(error)
+ {
+ *error = e.str();
+ }
+ else
+ {
+ this->Location.GetMakefile()->IssueMessage(cmake::FATAL_ERROR, e.str());
+ }
+ this->FindFullPathFailed = true;
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmSourceFile::TryFullPath(const char* tp, const char* ext)
+{
+ std::string tryPath = tp;
+ if(ext && *ext)
+ {
+ tryPath += ".";
+ tryPath += ext;
+ }
+ if(cmSystemTools::FileExists(tryPath.c_str()))
+ {
+ this->FullPath = tryPath;
+ return true;
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+void cmSourceFile::CheckExtension()
+{
+ // Compute the extension.
+ std::string realExt =
+ cmSystemTools::GetFilenameLastExtension(this->FullPath);
+ if(!realExt.empty())
+ {
+ // Store the extension without the leading '.'.
+ this->Extension = realExt.substr(1);
+ }
+
+ // Look for object files.
+ if(this->Extension == "obj" ||
+ this->Extension == "o" ||
+ this->Extension == "lo")
+ {
+ this->SetProperty("EXTERNAL_OBJECT", "1");
+ }
+
+ // Try to identify the source file language from the extension.
+ if(this->Language.empty())
+ {
+ this->CheckLanguage(this->Extension);
+ }
+}
+
+//----------------------------------------------------------------------------
+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()))
+ {
+ this->Language = l;
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmSourceFile::Matches(cmSourceFileLocation const& loc)
+{
+ return this->Location.Matches(loc);
+}
+
+//----------------------------------------------------------------------------
+void cmSourceFile::SetProperty(const char* prop, const char* value)
+{
+ if (!prop)
+ {
+ return;
+ }
+
+ this->Properties.SetProperty(prop, value, cmProperty::SOURCE_FILE);
+}
+
+//----------------------------------------------------------------------------
+void cmSourceFile::AppendProperty(const char* prop, const char* value,
+ bool asString)
+{
+ if (!prop)
+ {
+ return;
+ }
+ this->Properties.AppendProperty(prop, value, cmProperty::SOURCE_FILE,
+ asString);
+}
+
+//----------------------------------------------------------------------------
+const char* cmSourceFile::GetPropertyForUser(const char *prop)
+{
+ // This method is a consequence of design history and backwards
+ // compatibility. GetProperty is (and should be) a const method.
+ // Computed properties should not be stored back in the property map
+ // but instead reference information already known. If they need to
+ // cache information in a mutable ivar to provide the return string
+ // safely then so be it.
+ //
+ // The LOCATION property is particularly problematic. The CMake
+ // language has very loose restrictions on the names that will match
+ // a given source file (for historical reasons). Implementing
+ // lookups correctly with such loose naming requires the
+ // 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)
+ {
+ // Commit to a location.
+ this->GetFullPath();
+ }
+
+ // Perform the normal property lookup.
+ return this->GetProperty(prop);
+}
+
+//----------------------------------------------------------------------------
+const char* cmSourceFile::GetProperty(const char* prop) const
+{
+ // Check for computed properties.
+ if(strcmp(prop, "LOCATION") == 0)
+ {
+ if(this->FullPath.empty())
+ {
+ return 0;
+ }
+ else
+ {
+ return this->FullPath.c_str();
+ }
+ }
+
+ bool chain = false;
+ const char *retVal =
+ this->Properties.GetPropertyValue(prop, cmProperty::SOURCE_FILE, chain);
+ if (chain)
+ {
+ cmMakefile* mf = this->Location.GetMakefile();
+ return mf->GetProperty(prop,cmProperty::SOURCE_FILE);
+ }
+
+ return retVal;
+}
+
+//----------------------------------------------------------------------------
+bool cmSourceFile::GetPropertyAsBool(const char* prop) const
+{
+ return cmSystemTools::IsOn(this->GetProperty(prop));
+}
+
+//----------------------------------------------------------------------------
+cmCustomCommand* cmSourceFile::GetCustomCommand()
+{
+ return this->CustomCommand;
+}
+
+//----------------------------------------------------------------------------
+cmCustomCommand const* cmSourceFile::GetCustomCommand() const
+{
+ return this->CustomCommand;
+}
+
+//----------------------------------------------------------------------------
+void cmSourceFile::SetCustomCommand(cmCustomCommand* cc)
+{
+ cmCustomCommand* old = this->CustomCommand;
+ 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 is 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 header 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 then "
+ "this source file should not be wrapped.");
+}
+
diff --git a/Source/cmSourceFile.h b/Source/cmSourceFile.h
new file mode 100644
index 000000000..ae012747d
--- /dev/null
+++ b/Source/cmSourceFile.h
@@ -0,0 +1,122 @@
+/*============================================================================
+ 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 cmSourceFile_h
+#define cmSourceFile_h
+
+#include "cmSourceFileLocation.h"
+#include "cmCustomCommand.h"
+#include "cmPropertyMap.h"
+
+class cmake;
+
+/** \class cmSourceFile
+ * \brief Represent a class loaded from a makefile.
+ *
+ * cmSourceFile is represents a class loaded from
+ * a makefile.
+ */
+class cmSourceFile
+{
+public:
+ /**
+ * Construct with the makefile storing the source and the initial
+ * name referencing it.
+ */
+ cmSourceFile(cmMakefile* mf, const char* name);
+
+ ~cmSourceFile();
+
+ /**
+ * Get the list of the custom commands for this source file
+ */
+ cmCustomCommand* GetCustomCommand();
+ cmCustomCommand const* GetCustomCommand() const;
+ 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;
+
+ /** 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);
+
+ /**
+ * The full path to the file. The non-const version of this method
+ * may attempt to locate the file on disk and finalize its location.
+ * The const version of this method may return an empty string if
+ * the non-const version has not yet been called (yes this is a
+ * horrible interface, but is necessary for backwards
+ * compatibility).
+ */
+ std::string const& GetFullPath(std::string* error = 0);
+ std::string const& GetFullPath() const;
+
+ /**
+ * Get the information currently known about the source file
+ * location without attempting to locate the file as GetFullPath
+ * would. See cmSourceFileLocation documentation.
+ */
+ cmSourceFileLocation const& GetLocation() const;
+
+ /**
+ * Get the file extension of this source file.
+ */
+ std::string const& GetExtension() const;
+
+ /**
+ * Get the language of the compiler to use for this source file.
+ */
+ const char* GetLanguage();
+ const char* 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); }
+
+ // Get the properties
+ cmPropertyMap &GetProperties() { return this->Properties; };
+
+ // Define the properties
+ static void DefineProperties(cmake *cm);
+
+ /**
+ * Check whether the given source file location could refer to this
+ * source.
+ */
+ bool Matches(cmSourceFileLocation const&);
+
+private:
+ cmSourceFileLocation Location;
+ cmPropertyMap Properties;
+ cmCustomCommand* CustomCommand;
+ std::string Extension;
+ std::string Language;
+ std::string FullPath;
+ bool FindFullPathFailed;
+
+ bool FindFullPath(std::string* error);
+ bool TryFullPath(const char* tryPath, const char* ext);
+ void CheckExtension();
+ void CheckLanguage(std::string const& ext);
+
+ std::vector<std::string> Depends;
+};
+
+// TODO: Factor out into platform information modules.
+#define CM_HEADER_REGEX "\\.(h|hh|h\\+\\+|hm|hpp|hxx|in|txx|inl)$"
+
+#endif
diff --git a/Source/cmSourceFileLocation.cxx b/Source/cmSourceFileLocation.cxx
new file mode 100644
index 000000000..5525b618a
--- /dev/null
+++ b/Source/cmSourceFileLocation.cxx
@@ -0,0 +1,289 @@
+/*============================================================================
+ 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 "cmSourceFileLocation.h"
+
+#include "cmMakefile.h"
+#include "cmLocalGenerator.h"
+#include "cmGlobalGenerator.h"
+#include "cmSystemTools.h"
+
+//----------------------------------------------------------------------------
+cmSourceFileLocation
+::cmSourceFileLocation(cmMakefile* mf, const char* name): Makefile(mf)
+{
+ 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)
+{
+ if(this->AmbiguousDirectory)
+ {
+ this->UpdateDirectory(name);
+ }
+ if(this->AmbiguousExtension)
+ {
+ this->UpdateExtension(name);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmSourceFileLocation::Update(cmSourceFileLocation const& loc)
+{
+ if(this->AmbiguousDirectory && !loc.AmbiguousDirectory)
+ {
+ this->Directory = loc.Directory;
+ this->AmbiguousDirectory = false;
+ }
+ if(this->AmbiguousExtension && !loc.AmbiguousExtension)
+ {
+ this->Name = loc.Name;
+ this->AmbiguousExtension = false;
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmSourceFileLocation::DirectoryUseSource()
+{
+ if(this->AmbiguousDirectory)
+ {
+ this->Directory =
+ cmSystemTools::CollapseFullPath(
+ this->Directory.c_str(), this->Makefile->GetCurrentDirectory());
+ this->AmbiguousDirectory = false;
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmSourceFileLocation::DirectoryUseBinary()
+{
+ if(this->AmbiguousDirectory)
+ {
+ this->Directory =
+ cmSystemTools::CollapseFullPath(
+ this->Directory.c_str(), this->Makefile->GetCurrentOutputDirectory());
+ this->AmbiguousDirectory = false;
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmSourceFileLocation::UpdateExtension(const char* name)
+{
+ // 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()) ||
+ std::find(srcExts.begin(), srcExts.end(), ext) != srcExts.end() ||
+ std::find(hdrExts.begin(), hdrExts.end(), ext) != hdrExts.end())
+ {
+ // This is a known extension. Use the given filename with extension.
+ this->Name = cmSystemTools::GetFilenameName(name);
+ this->AmbiguousExtension = false;
+ }
+ else
+ {
+ // This is not a known extension. See if the file exists on disk as
+ // named.
+ std::string tryPath;
+ if(this->AmbiguousDirectory)
+ {
+ // 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 += "/";
+ }
+ if(!this->Directory.empty())
+ {
+ tryPath += this->Directory;
+ tryPath += "/";
+ }
+ tryPath += this->Name;
+ if(cmSystemTools::FileExists(tryPath.c_str(), true))
+ {
+ // We found a source file named by the user on disk. Trust it's
+ // extension.
+ this->Name = cmSystemTools::GetFilenameName(name);
+ this->AmbiguousExtension = false;
+
+ // If the directory was ambiguous, it isn't anymore.
+ if(this->AmbiguousDirectory)
+ {
+ this->DirectoryUseSource();
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+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
+{
+ // This location's extension is not ambiguous but loc's extension
+ // is. See if the names match as-is.
+ if(this->Name == loc.Name)
+ {
+ return true;
+ }
+
+ // 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()] == '.'))
+ {
+ 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();
+ if(std::find(srcExts.begin(), srcExts.end(), ext) != srcExts.end())
+ {
+ return true;
+ }
+ const std::vector<std::string>& hdrExts = mf->GetHeaderExtensions();
+ if(std::find(hdrExts.begin(), hdrExts.end(), ext) != hdrExts.end())
+ {
+ return true;
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmSourceFileLocation::Matches(cmSourceFileLocation const& loc)
+{
+ 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)
+ {
+ return false;
+ }
+ }
+ else if(this->AmbiguousExtension)
+ {
+ // Only "this" extension is ambiguous.
+ if(!loc.MatchesAmbiguousExtension(*this))
+ {
+ return false;
+ }
+ }
+ else if(loc.AmbiguousExtension)
+ {
+ // Only "loc" extension is ambiguous.
+ if(!this->MatchesAmbiguousExtension(loc))
+ {
+ return false;
+ }
+ }
+ else
+ {
+ // Neither extension is ambiguous.
+ if(this->Name != loc.Name)
+ {
+ return false;
+ }
+ }
+
+ if(!this->AmbiguousDirectory && !loc.AmbiguousDirectory)
+ {
+ // Both sides have absolute directories.
+ if(this->Directory != loc.Directory)
+ {
+ return false;
+ }
+ }
+ else if(this->AmbiguousDirectory && loc.AmbiguousDirectory &&
+ this->Makefile == loc.Makefile)
+ {
+ // Both sides have directories relative to the same location.
+ if(this->Directory != loc.Directory)
+ {
+ 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 =
+ cmSystemTools::CollapseFullPath(
+ this->Directory.c_str(), this->Makefile->GetCurrentDirectory());
+ std::string binDir =
+ cmSystemTools::CollapseFullPath(
+ this->Directory.c_str(), this->Makefile->GetCurrentOutputDirectory());
+ if(srcDir != loc.Directory &&
+ binDir != loc.Directory)
+ {
+ return false;
+ }
+ }
+ else if(loc.AmbiguousDirectory)
+ {
+ // Compare possible directory combinations.
+ std::string srcDir =
+ cmSystemTools::CollapseFullPath(
+ loc.Directory.c_str(), loc.Makefile->GetCurrentDirectory());
+ std::string binDir =
+ cmSystemTools::CollapseFullPath(
+ loc.Directory.c_str(), loc.Makefile->GetCurrentOutputDirectory());
+ if(srcDir != this->Directory &&
+ binDir != this->Directory)
+ {
+ return false;
+ }
+ }
+
+ // File locations match.
+ this->Update(loc);
+ return true;
+}
diff --git a/Source/cmSourceFileLocation.h b/Source/cmSourceFileLocation.h
new file mode 100644
index 000000000..216dd07b8
--- /dev/null
+++ b/Source/cmSourceFileLocation.h
@@ -0,0 +1,101 @@
+/*============================================================================
+ 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 cmSourceFileLocation_h
+#define cmSourceFileLocation_h
+
+#include "cmStandardIncludes.h"
+
+class cmMakefile;
+
+/** \class cmSourceFileLocation
+ * \brief cmSourceFileLocation tracks knowledge about a source file location
+ *
+ * Source files can be referenced by a variety of names. The
+ * directory and/or extension may be omitted leading to a certain
+ * level of ambiguity about the source file location. This class is
+ * used by cmSourceFile to keep track of what is known about the
+ * source file location. Each reference may add some information
+ * about the directory or extension of the file.
+ */
+class cmSourceFileLocation
+{
+public:
+ /**
+ * Construct for a source file created in a given cmMakefile
+ * instance with an initial name.
+ */
+ cmSourceFileLocation(cmMakefile* mf, const char* name);
+
+ /**
+ * Return whether the givne source file location could refers to the
+ * same source file as this location given the level of ambiguity in
+ * each location.
+ */
+ bool Matches(cmSourceFileLocation const& loc);
+
+ /**
+ * Explicity state that the source file is located in the source tree.
+ */
+ void DirectoryUseSource();
+
+ /**
+ * Explicity state that the source file is located in the build tree.
+ */
+ void DirectoryUseBinary();
+
+ /**
+ * Return whether the directory containing the source is ambiguous.
+ */
+ bool DirectoryIsAmbiguous() const { return this->AmbiguousDirectory; }
+
+ /**
+ * Return whether the extension of the source name is ambiguous.
+ */
+ bool ExtensionIsAmbiguous() const { return this->AmbiguousExtension; }
+
+ /**
+ * Get the directory containing the file as best is currently known.
+ * If DirectoryIsAmbiguous() returns false this will be a full path.
+ * 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(); }
+
+ /**
+ * Get the file name as best is currently known. If
+ * ExtensionIsAmbiguous() returns true this name may not be the
+ * final name (but could be). Otherwise the returned name is the
+ * final name.
+ */
+ const char* GetName() const { return this->Name.c_str(); }
+
+ /**
+ * Get the cmMakefile instance for which the source file was created.
+ */
+ cmMakefile* GetMakefile() const { return this->Makefile; }
+private:
+ cmMakefile* Makefile;
+ bool AmbiguousDirectory;
+ bool AmbiguousExtension;
+ std::string Directory;
+ std::string Name;
+
+ bool MatchesAmbiguousExtension(cmSourceFileLocation const& loc) const;
+
+ // 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);
+};
+
+#endif
diff --git a/Source/cmSourceGroup.cxx b/Source/cmSourceGroup.cxx
new file mode 100644
index 000000000..2b34f2bfc
--- /dev/null
+++ b/Source/cmSourceGroup.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 "cmSourceGroup.h"
+
+class cmSourceGroupInternals
+{
+public:
+ std::vector<cmSourceGroup> GroupChildren;
+};
+
+//----------------------------------------------------------------------------
+cmSourceGroup::cmSourceGroup(const char* name, const char* regex,
+ const char* parentName): Name(name)
+{
+ this->Internal = new cmSourceGroupInternals;
+ this->SetGroupRegex(regex);
+ if(parentName)
+ {
+ this->FullName = parentName;
+ this->FullName += "\\";
+ }
+ this->FullName += this->Name;
+}
+
+//----------------------------------------------------------------------------
+cmSourceGroup::~cmSourceGroup()
+{
+ delete this->Internal;
+}
+
+//----------------------------------------------------------------------------
+cmSourceGroup::cmSourceGroup(cmSourceGroup const& r)
+{
+ this->Name = r.Name;
+ this->FullName = r.FullName;
+ this->GroupRegex = r.GroupRegex;
+ this->GroupFiles = r.GroupFiles;
+ this->SourceFiles = r.SourceFiles;
+ this->Internal = new cmSourceGroupInternals(*r.Internal);
+}
+
+//----------------------------------------------------------------------------
+cmSourceGroup& cmSourceGroup::operator=(cmSourceGroup const& r)
+{
+ this->Name = r.Name;
+ this->GroupRegex = r.GroupRegex;
+ this->GroupFiles = r.GroupFiles;
+ this->SourceFiles = r.SourceFiles;
+ *(this->Internal) = *(r.Internal);
+ return *this;
+}
+
+//----------------------------------------------------------------------------
+void cmSourceGroup::SetGroupRegex(const char* regex)
+{
+ if(regex)
+ {
+ this->GroupRegex.compile(regex);
+ }
+ else
+ {
+ this->GroupRegex.compile("^$");
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmSourceGroup::AddGroupFile(const char* name)
+{
+ this->GroupFiles.insert(name);
+}
+
+//----------------------------------------------------------------------------
+const char* cmSourceGroup::GetName() const
+{
+ return this->Name.c_str();
+}
+
+//----------------------------------------------------------------------------
+const char* cmSourceGroup::GetFullName() const
+{
+ return this->FullName.c_str();
+}
+
+//----------------------------------------------------------------------------
+bool cmSourceGroup::MatchesRegex(const char* name)
+{
+ return this->GroupRegex.find(name);
+}
+
+//----------------------------------------------------------------------------
+bool cmSourceGroup::MatchesFiles(const char* name)
+{
+ std::set<cmStdString>::const_iterator i = this->GroupFiles.find(name);
+ if(i != this->GroupFiles.end())
+ {
+ return true;
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+void cmSourceGroup::AssignSource(const cmSourceFile* sf)
+{
+ this->SourceFiles.push_back(sf);
+}
+
+//----------------------------------------------------------------------------
+const std::vector<const cmSourceFile*>& cmSourceGroup::GetSourceFiles() const
+{
+ return this->SourceFiles;
+}
+
+//----------------------------------------------------------------------------
+void cmSourceGroup::AddChild(cmSourceGroup child)
+{
+ this->Internal->GroupChildren.push_back(child);
+}
+
+//----------------------------------------------------------------------------
+cmSourceGroup *cmSourceGroup::lookupChild(const char* name)
+{
+ // initializing iterators
+ std::vector<cmSourceGroup>::iterator iter =
+ this->Internal->GroupChildren.begin();
+ std::vector<cmSourceGroup>::iterator end =
+ this->Internal->GroupChildren.end();
+
+ // st
+ for(;iter!=end; ++iter)
+ {
+ std::string sgName = iter->GetName();
+
+ // look if descenened is the one were looking for
+ if(sgName == name)
+ {
+ return &(*iter); // if it so return it
+ }
+ }
+
+ // if no child with this name was found return NULL
+ return NULL;
+}
+
+cmSourceGroup *cmSourceGroup::MatchChildrenFiles(const char *name)
+{
+ // initializing iterators
+ std::vector<cmSourceGroup>::iterator iter =
+ this->Internal->GroupChildren.begin();
+ std::vector<cmSourceGroup>::iterator end =
+ this->Internal->GroupChildren.end();
+
+ if(this->MatchesFiles(name))
+ {
+ return this;
+ }
+ for(;iter!=end;++iter)
+ {
+ cmSourceGroup *result = iter->MatchChildrenFiles(name);
+ if(result)
+ {
+ return result;
+ }
+ }
+ return 0;
+}
+
+
+cmSourceGroup *cmSourceGroup::MatchChildrenRegex(const char *name)
+{
+ // initializing iterators
+ std::vector<cmSourceGroup>::iterator iter =
+ this->Internal->GroupChildren.begin();
+ std::vector<cmSourceGroup>::iterator end =
+ this->Internal->GroupChildren.end();
+
+ if(this->MatchesRegex(name))
+ {
+ return this;
+ }
+ for(;iter!=end; ++iter)
+ {
+ cmSourceGroup *result = iter->MatchChildrenRegex(name);
+ if(result)
+ {
+ return result;
+ }
+ }
+ return 0;
+}
+
+std::vector<cmSourceGroup> const&
+cmSourceGroup::GetGroupChildren() const
+{
+ return this->Internal->GroupChildren;
+}
diff --git a/Source/cmSourceGroup.h b/Source/cmSourceGroup.h
new file mode 100644
index 000000000..641dcbd57
--- /dev/null
+++ b/Source/cmSourceGroup.h
@@ -0,0 +1,132 @@
+/*============================================================================
+ 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 cmSourceGroup_h
+#define cmSourceGroup_h
+
+#include "cmStandardIncludes.h"
+#include <cmsys/RegularExpression.hxx>
+
+class cmSourceFile;
+
+class cmSourceGroupInternals;
+
+/** \class cmSourceGroup
+ * \brief Hold a group of sources as specified by a SOURCE_GROUP command.
+ *
+ * cmSourceGroup holds a regular expression and a list of files. When
+ * local generators are about to generate the rules for a target's
+ * files, the set of source groups is consulted to group files
+ * together. A file is placed into the last source group that lists
+ * the file by name. If no group lists the file, it is placed into
+ * the last group whose regex matches it.
+ */
+class cmSourceGroup
+{
+public:
+ cmSourceGroup(const char* name, const char* regex,
+ const char* parentName=0);
+ cmSourceGroup(cmSourceGroup const& r);
+ ~cmSourceGroup();
+ cmSourceGroup& operator=(cmSourceGroup const&);
+
+ /**
+ * Set the regular expression for this group.
+ */
+ void SetGroupRegex(const char* regex);
+
+ /**
+ * Add a file name to the explicit list of files for this group.
+ */
+ void AddGroupFile(const char* name);
+
+ /**
+ * Add child to this sourcegroup
+ */
+ void AddChild(cmSourceGroup child);
+
+ /**
+ * Looks up child and returns it
+ */
+ cmSourceGroup *lookupChild(const char *name);
+
+ /**
+ * Get the name of this group.
+ */
+ const char* GetName() const;
+
+ /**
+ * Get the full path name for group.
+ */
+ const char* GetFullName() const;
+
+ /**
+ * Check if the given name matches this group's regex.
+ */
+ bool MatchesRegex(const char* name);
+
+ /**
+ * Check if the given name matches this group's explicit file list.
+ */
+ bool MatchesFiles(const char* name);
+
+ /**
+ * Check if the given name matches this group's explicit file list
+ * in children.
+ */
+ cmSourceGroup *MatchChildrenFiles(const char *name);
+
+ /**
+ * Check if the given name matches this group's regex in children.
+ */
+ cmSourceGroup *MatchChildrenRegex(const char *name);
+
+ /**
+ * Assign the given source file to this group. Used only by
+ * generators.
+ */
+ void AssignSource(const cmSourceFile* sf);
+
+ /**
+ * Get the list of the source files that have been assigned to this
+ * source group.
+ */
+ const std::vector<const cmSourceFile*>& GetSourceFiles() const;
+
+ std::vector<cmSourceGroup> const& GetGroupChildren() const;
+private:
+ /**
+ * The name of the source group.
+ */
+ std::string Name;
+ // Full path to group
+ std::string FullName;
+
+ /**
+ * The regular expression matching the files in the group.
+ */
+ cmsys::RegularExpression GroupRegex;
+
+ /**
+ * Set of file names explicitly added to this group.
+ */
+ std::set<cmStdString> GroupFiles;
+
+ /**
+ * Vector of all source files that have been assigned to
+ * this group.
+ */
+ std::vector<const cmSourceFile*> SourceFiles;
+
+ cmSourceGroupInternals* Internal;
+};
+
+#endif
diff --git a/Source/cmSourceGroupCommand.cxx b/Source/cmSourceGroupCommand.cxx
new file mode 100644
index 000000000..8e61d0a15
--- /dev/null
+++ b/Source/cmSourceGroupCommand.cxx
@@ -0,0 +1,102 @@
+/*============================================================================
+ 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 "cmSourceGroupCommand.h"
+
+// cmSourceGroupCommand
+bool cmSourceGroupCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 1)
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ std::string delimiter = "\\";
+ if(this->Makefile->GetDefinition("SOURCE_GROUP_DELIMITER"))
+ {
+ delimiter = this->Makefile->GetDefinition("SOURCE_GROUP_DELIMITER");
+ }
+
+ std::vector<std::string> folders =
+ cmSystemTools::tokenize(args[0], delimiter);
+
+ cmSourceGroup* sg = 0;
+ sg = this->Makefile->GetSourceGroup(folders);
+ if(!sg)
+ {
+ this->Makefile->AddSourceGroup(folders);
+ sg = this->Makefile->GetSourceGroup(folders);
+ }
+
+ if(!sg)
+ {
+ this->SetError("Could not create or find source group");
+ return false;
+ }
+ // If only two arguments are given, the pre-1.8 version of the
+ // command is being invoked.
+ if(args.size() == 2 && args[1] != "FILES")
+ {
+ sg->SetGroupRegex(args[1].c_str());
+ return true;
+ }
+
+ // Process arguments.
+ bool doingFiles = false;
+ for(unsigned int i=1; i < args.size(); ++i)
+ {
+ if(args[i] == "REGULAR_EXPRESSION")
+ {
+ // Next argument must specify the regex.
+ if(i+1 < args.size())
+ {
+ ++i;
+ sg->SetGroupRegex(args[i].c_str());
+ }
+ else
+ {
+ this->SetError("REGULAR_EXPRESSION argument given without a regex.");
+ return false;
+ }
+ doingFiles = false;
+ }
+ else if(args[i] == "FILES")
+ {
+ // Next arguments will specify files.
+ doingFiles = true;
+ }
+ else if(doingFiles)
+ {
+ // Convert name to full path and add to the group's list.
+ std::string src = args[i].c_str();
+ if(!cmSystemTools::FileIsFullPath(src.c_str()))
+ {
+ src = this->Makefile->GetCurrentDirectory();
+ src += "/";
+ src += args[i];
+ }
+ src = cmSystemTools::CollapseFullPath(src.c_str());
+ sg->AddGroupFile(src.c_str());
+ }
+ else
+ {
+ cmOStringStream err;
+ err << "Unknown argument \"" << args[i].c_str() << "\". "
+ << "Perhaps the FILES keyword is missing.\n";
+ this->SetError(err.str().c_str());
+ return false;
+ }
+ }
+
+ return true;
+}
diff --git a/Source/cmSourceGroupCommand.h b/Source/cmSourceGroupCommand.h
new file mode 100644
index 000000000..6a29fc810
--- /dev/null
+++ b/Source/cmSourceGroupCommand.h
@@ -0,0 +1,81 @@
+/*============================================================================
+ 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 cmSourceGroupCommand_h
+#define cmSourceGroupCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmSourceGroupCommand
+ * \brief Adds a cmSourceGroup to the cmMakefile.
+ *
+ * cmSourceGroupCommand is used to define cmSourceGroups which split up
+ * source files in to named, organized groups in the generated makefiles.
+ */
+class cmSourceGroupCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmSourceGroupCommand;
+ }
+
+ /**
+ * 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 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 is also supports the "
+ "format:\n"
+ " source_group(name regex)";
+ }
+
+ cmTypeMacro(cmSourceGroupCommand, cmCommand);
+};
+
+
+
+#endif
diff --git a/Source/cmStandardIncludes.cxx b/Source/cmStandardIncludes.cxx
new file mode 100644
index 000000000..a4bdb2e32
--- /dev/null
+++ b/Source/cmStandardIncludes.cxx
@@ -0,0 +1,16 @@
+/*============================================================================
+ 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
new file mode 100644
index 000000000..ea299ca90
--- /dev/null
+++ b/Source/cmStandardIncludes.h
@@ -0,0 +1,384 @@
+/*============================================================================
+ 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 header files as a function of the build process, compiler,
+ * and operating system.
+ */
+#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
+
+#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
+
+// we must have stl with the standard include style
+#include <vector>
+#include <string>
+#include <iterator>
+#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 */
+#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
+
+/* Poison this operator to avoid common mistakes. */
+extern void operator << (std::ostream&, const cmOStringStream&);
+
+/** Standard documentation entry for cmDocumentation's formatting. */
+struct cmDocumentationEntry
+{
+ std::string Name;
+ std::string Brief;
+ std::string Full;
+ cmDocumentationEntry(){};
+ cmDocumentationEntry(const char *doc[3])
+ { 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; };
+};
+
+/** Data structure to represent a single command line. */
+class cmCustomCommandLine: public std::vector<std::string>
+{
+public:
+ typedef std::vector<std::string> Superclass;
+ typedef Superclass::iterator iterator;
+ typedef Superclass::const_iterator const_iterator;
+};
+
+/** Data structure to represent a list of command lines. */
+class cmCustomCommandLines: public std::vector<cmCustomCommandLine>
+{
+public:
+ typedef std::vector<cmCustomCommandLine> Superclass;
+ typedef Superclass::iterator iterator;
+ 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) \
+virtual const char* GetNameOfClass() { return #thisClass; } \
+typedef superclass Superclass; \
+static bool IsTypeOf(const char *type) \
+{ \
+ if ( !strcmp(#thisClass,type) ) \
+ { \
+ return true; \
+ } \
+ return Superclass::IsTypeOf(type); \
+} \
+virtual bool IsA(const char *type) \
+{ \
+ return thisClass::IsTypeOf(type); \
+} \
+static thisClass* SafeDownCast(cmObject *c) \
+{ \
+ if ( c && c->IsA(#thisClass) ) \
+ { \
+ return static_cast<thisClass *>(c); \
+ } \
+ return 0;\
+}
+
+
+
+#endif
diff --git a/Source/cmStandardLexer.h b/Source/cmStandardLexer.h
new file mode 100644
index 000000000..acd636c43
--- /dev/null
+++ b/Source/cmStandardLexer.h
@@ -0,0 +1,73 @@
+/*============================================================================
+ 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 cmStandardLexer_h
+#define cmStandardLexer_h
+
+/* Disable some warnings. */
+#if defined(_MSC_VER)
+# pragma warning ( disable : 4127 )
+# pragma warning ( disable : 4131 )
+# pragma warning ( disable : 4244 )
+# pragma warning ( disable : 4251 )
+# pragma warning ( disable : 4267 )
+# pragma warning ( disable : 4305 )
+# pragma warning ( disable : 4309 )
+# pragma warning ( disable : 4706 )
+# 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>
+# if defined( _MSC_VER )
+# define isatty _isatty
+# endif
+# define YY_NO_UNISTD_H 1
+#endif
+
+/* Make sure malloc and free are available on QNX. */
+#ifdef __QNX__
+# include <malloc.h>
+#endif
+
+/* Disable features we do not need. */
+#define YY_NEVER_INTERACTIVE 1
+#define YY_NO_INPUT 1
+#define YY_NO_UNPUT 1
+#define ECHO
+
+#endif
diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx
new file mode 100644
index 000000000..ec10d571f
--- /dev/null
+++ b/Source/cmStringCommand.cxx
@@ -0,0 +1,881 @@
+/*============================================================================
+ 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 "cmStringCommand.h"
+#include "cmCryptoHash.h"
+
+#include <cmsys/RegularExpression.hxx>
+#include <cmsys/SystemTools.hxx>
+
+#include <stdlib.h> // required for atoi
+#include <ctype.h>
+#include <time.h>
+
+//----------------------------------------------------------------------------
+bool cmStringCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 1)
+ {
+ this->SetError("must be called with at least one argument.");
+ return false;
+ }
+
+ const std::string &subCommand = args[0];
+ if(subCommand == "REGEX")
+ {
+ return this->HandleRegexCommand(args);
+ }
+ else if(subCommand == "REPLACE")
+ {
+ return this->HandleReplaceCommand(args);
+ }
+ else if ( subCommand == "MD5" ||
+ subCommand == "SHA1" ||
+ subCommand == "SHA224" ||
+ subCommand == "SHA256" ||
+ subCommand == "SHA384" ||
+ subCommand == "SHA512" )
+ {
+ return this->HandleHashCommand(args);
+ }
+ else if(subCommand == "TOLOWER")
+ {
+ return this->HandleToUpperLowerCommand(args, false);
+ }
+ else if(subCommand == "TOUPPER")
+ {
+ return this->HandleToUpperLowerCommand(args, true);
+ }
+ else if(subCommand == "COMPARE")
+ {
+ return this->HandleCompareCommand(args);
+ }
+ else if(subCommand == "ASCII")
+ {
+ return this->HandleAsciiCommand(args);
+ }
+ else if(subCommand == "CONFIGURE")
+ {
+ return this->HandleConfigureCommand(args);
+ }
+ else if(subCommand == "LENGTH")
+ {
+ return this->HandleLengthCommand(args);
+ }
+ else if(subCommand == "SUBSTRING")
+ {
+ return this->HandleSubstringCommand(args);
+ }
+ else if(subCommand == "STRIP")
+ {
+ return this->HandleStripCommand(args);
+ }
+ else if(subCommand == "RANDOM")
+ {
+ return this->HandleRandomCommand(args);
+ }
+ else if(subCommand == "FIND")
+ {
+ return this->HandleFindCommand(args);
+ }
+
+ std::string e = "does not recognize sub-command "+subCommand;
+ this->SetError(e.c_str());
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmStringCommand::HandleHashCommand(std::vector<std::string> const& args)
+{
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ if(args.size() != 3)
+ {
+ cmOStringStream e;
+ e << args[0] << " requires an output variable and an input string";
+ this->SetError(e.str().c_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());
+ return true;
+ }
+ return false;
+#else
+ cmOStringStream e;
+ e << args[0] << " not available during bootstrap";
+ this->SetError(e.str().c_str());
+ return false;
+#endif
+}
+
+//----------------------------------------------------------------------------
+bool cmStringCommand::HandleToUpperLowerCommand(
+ std::vector<std::string> const& args, bool toUpper)
+{
+ if ( args.size() < 3 )
+ {
+ this->SetError("no output variable specified");
+ return false;
+ }
+
+ std::string outvar = args[2];
+ std::string output;
+
+ if (toUpper)
+ {
+ output = cmSystemTools::UpperCase(args[1]);
+ }
+ else
+ {
+ output = cmSystemTools::LowerCase(args[1]);
+ }
+
+ // Store the output in the provided variable.
+ this->Makefile->AddDefinition(outvar.c_str(), output.c_str());
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmStringCommand::HandleAsciiCommand(std::vector<std::string> const& args)
+{
+ if ( args.size() < 3 )
+ {
+ this->SetError("No output variable specified");
+ return false;
+ }
+ std::string::size_type cc;
+ std::string outvar = args[args.size()-1];
+ std::string output = "";
+ for ( cc = 1; cc < args.size()-1; cc ++ )
+ {
+ int ch = atoi(args[cc].c_str());
+ if ( ch > 0 && ch < 256 )
+ {
+ output += static_cast<char>(ch);
+ }
+ else
+ {
+ std::string error = "Character with code ";
+ error += args[cc];
+ error += " does not exist.";
+ this->SetError(error.c_str());
+ return false;
+ }
+ }
+ // Store the output in the provided variable.
+ this->Makefile->AddDefinition(outvar.c_str(), output.c_str());
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmStringCommand::HandleConfigureCommand(
+ std::vector<std::string> const& args)
+{
+ if ( args.size() < 2 )
+ {
+ this->SetError("No input string specified.");
+ return false;
+ }
+ else if ( args.size() < 3 )
+ {
+ this->SetError("No output variable specified.");
+ return false;
+ }
+
+ // Parse options.
+ bool escapeQuotes = false;
+ bool atOnly = false;
+ for(unsigned int i = 3; i < args.size(); ++i)
+ {
+ if(args[i] == "@ONLY")
+ {
+ atOnly = true;
+ }
+ else if(args[i] == "ESCAPE_QUOTES")
+ {
+ escapeQuotes = true;
+ }
+ else
+ {
+ cmOStringStream err;
+ err << "Unrecognized argument \"" << args[i] << "\"";
+ this->SetError(err.str().c_str());
+ return false;
+ }
+ }
+
+ // Configure the string.
+ std::string output;
+ 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());
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmStringCommand::HandleRegexCommand(std::vector<std::string> const& args)
+{
+ if(args.size() < 2)
+ {
+ this->SetError("sub-command REGEX requires a mode to be specified.");
+ return false;
+ }
+ std::string mode = args[1];
+ if(mode == "MATCH")
+ {
+ if(args.size() < 5)
+ {
+ this->SetError("sub-command REGEX, mode MATCH needs "
+ "at least 5 arguments total to command.");
+ return false;
+ }
+ return this->RegexMatch(args);
+ }
+ else if(mode == "MATCHALL")
+ {
+ if(args.size() < 5)
+ {
+ this->SetError("sub-command REGEX, mode MATCHALL needs "
+ "at least 5 arguments total to command.");
+ return false;
+ }
+ return this->RegexMatchAll(args);
+ }
+ else if(mode == "REPLACE")
+ {
+ if(args.size() < 6)
+ {
+ this->SetError("sub-command REGEX, mode REPLACE needs "
+ "at least 6 arguments total to command.");
+ return false;
+ }
+ return this->RegexReplace(args);
+ }
+
+ std::string e = "sub-command REGEX does not recognize mode "+mode;
+ this->SetError(e.c_str());
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmStringCommand::RegexMatch(std::vector<std::string> const& args)
+{
+ //"STRING(REGEX MATCH <regular_expression> <output variable>
+ // <input> [<input>...])\n";
+ 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);
+ // 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());
+ return false;
+ }
+
+ // Scan through the input for all matches.
+ std::string output;
+ if(re.find(input.c_str()))
+ {
+ this->StoreMatches(this->Makefile, 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 MATCH regex \""+regex+
+ "\" matched an empty string.";
+ this->SetError(e.c_str());
+ return false;
+ }
+ output = input.substr(l, r-l);
+ }
+
+ // Store the output in the provided variable.
+ this->Makefile->AddDefinition(outvar.c_str(), output.c_str());
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmStringCommand::RegexMatchAll(std::vector<std::string> const& args)
+{
+ //"STRING(REGEX MATCHALL <regular_expression> <output variable> <input>
+ // [<input>...])\n";
+ 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);
+ // Compile the regular expression.
+ cmsys::RegularExpression re;
+ if(!re.compile(regex.c_str()))
+ {
+ std::string e =
+ "sub-command REGEX, mode MATCHALL failed to compile regex \""+
+ regex+"\".";
+ this->SetError(e.c_str());
+ return false;
+ }
+
+ // 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);
+ 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());
+ return false;
+ }
+ if(output.length() > 0)
+ {
+ output += ";";
+ }
+ output += std::string(p+l, r-l);
+ p += r;
+ }
+
+ // Store the output in the provided variable.
+ this->Makefile->AddDefinition(outvar.c_str(), output.c_str());
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmStringCommand::RegexReplace(std::vector<std::string> const& args)
+{
+ //"STRING(REGEX REPLACE <regular_expression> <replace_expression>
+ // <output variable> <input> [<input>...])\n"
+ std::string regex = args[2];
+ std::string replace = args[3];
+ std::string outvar = args[4];
+
+ // Pull apart the replace expression to find the escaped [0-9] values.
+ std::vector<RegexReplacement> replacement;
+ std::string::size_type l = 0;
+ while(l < replace.length())
+ {
+ std::string::size_type r = replace.find("\\", l);
+ if(r == std::string::npos)
+ {
+ r = replace.length();
+ replacement.push_back(replace.substr(l, r-l));
+ }
+ else
+ {
+ if(r-l > 0)
+ {
+ replacement.push_back(replace.substr(l, r-l));
+ }
+ if(r == (replace.length()-1))
+ {
+ this->SetError("sub-command REGEX, mode REPLACE: "
+ "replace-expression ends in a backslash.");
+ return false;
+ }
+ if((replace[r+1] >= '0') && (replace[r+1] <= '9'))
+ {
+ replacement.push_back(replace[r+1]-'0');
+ }
+ else if(replace[r+1] == 'n')
+ {
+ replacement.push_back("\n");
+ }
+ else if(replace[r+1] == '\\')
+ {
+ replacement.push_back("\\");
+ }
+ else
+ {
+ std::string e = "sub-command REGEX, mode REPLACE: Unknown escape \"";
+ e += replace.substr(r, 2);
+ e += "\" in replace-expression.";
+ this->SetError(e.c_str());
+ return false;
+ }
+ r += 2;
+ }
+ 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);
+ // Compile the regular expression.
+ cmsys::RegularExpression re;
+ if(!re.compile(regex.c_str()))
+ {
+ std::string e =
+ "sub-command REGEX, mode REPLACE failed to compile regex \""+
+ regex+"\".";
+ this->SetError(e.c_str());
+ return false;
+ }
+
+ // 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);
+ std::string::size_type l2 = re.start();
+ std::string::size_type r = re.end();
+
+ // Concatenate the part of the input that was not matched.
+ output += input.substr(base, l2);
+
+ // Make sure the match had some text.
+ if(r-l2 == 0)
+ {
+ std::string e = "sub-command REGEX, mode REPLACE regex \""+
+ regex+"\" matched an empty string.";
+ this->SetError(e.c_str());
+ return false;
+ }
+
+ // Concatenate the replacement for the match.
+ for(unsigned int i=0; i < replacement.size(); ++i)
+ {
+ if(replacement[i].number < 0)
+ {
+ // This is just a plain-text part of the replacement.
+ output += replacement[i].value;
+ }
+ else
+ {
+ // Replace with part of the match.
+ int n = replacement[i].number;
+ std::string::size_type start = re.start(n);
+ std::string::size_type end = re.end(n);
+ std::string::size_type len = input.length()-base;
+ if((start != std::string::npos) && (end != std::string::npos) &&
+ (start <= len) && (end <= len))
+ {
+ output += input.substr(base+start, end-start);
+ }
+ else
+ {
+ std::string e =
+ "sub-command REGEX, mode REPLACE: replace expression \""+
+ replace+"\" contains an out-of-range escape for regex \""+
+ regex+"\".";
+ this->SetError(e.c_str());
+ return false;
+ }
+ }
+ }
+
+ // Move past the match.
+ base += r;
+ }
+
+ // Concatenate the text after the last match.
+ output += input.substr(base, input.length()-base);
+
+ // Store the output in the provided variable.
+ this->Makefile->AddDefinition(outvar.c_str(), 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);
+ mf->AddDefinition(name, "");
+ mf->MarkVariableAsUsed(name);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmStringCommand::StoreMatches(cmMakefile* mf,cmsys::RegularExpression& re)
+{
+ for (unsigned int i=0; i<10; i++)
+ {
+ 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)
+{
+ // check if all required parameters were passed
+ if(args.size() < 4 || args.size() > 5)
+ {
+ this->SetError("sub-command FIND requires 3 or 4 parameters.");
+ return false;
+ }
+
+ // check if the reverse flag was set or not
+ bool reverseMode = false;
+ if(args.size() == 5 && args[4] == "REVERSE")
+ {
+ reverseMode = true;
+ }
+
+ // if we have 5 arguments the last one must be REVERSE
+ if(args.size() == 5 && args[4] != "REVERSE")
+ {
+ this->SetError("sub-command FIND: unknown last parameter");
+ return false;
+ }
+
+ // local parameter names.
+ const std::string& sstring = args[1];
+ const std::string& schar = args[2];
+ const std::string& outvar = args[3];
+
+ // ensure that the user cannot accidentally specify REVERSE as a variable
+ if(outvar == "REVERSE")
+ {
+ this->SetError("sub-command FIND does not allow to select REVERSE as "
+ "the output variable. "
+ "Maybe you missed the actual output variable?");
+ return false;
+ }
+
+ // try to find the character and return its position
+ size_t pos;
+ if(!reverseMode)
+ {
+ pos = sstring.find(schar);
+ }
+ else
+ {
+ pos = sstring.rfind(schar);
+ }
+ if(std::string::npos != pos)
+ {
+ cmOStringStream s;
+ s << pos;
+ this->Makefile->AddDefinition(outvar.c_str(), 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");
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmStringCommand::HandleCompareCommand(std::vector<std::string> const&
+ args)
+{
+ if(args.size() < 2)
+ {
+ this->SetError("sub-command COMPARE requires a mode to be specified.");
+ return false;
+ }
+ std::string mode = args[1];
+ if((mode == "EQUAL") || (mode == "NOTEQUAL") ||
+ (mode == "LESS") || (mode == "GREATER"))
+ {
+ if(args.size() < 5)
+ {
+ std::string e = "sub-command COMPARE, mode ";
+ e += mode;
+ e += " needs at least 5 arguments total to command.";
+ this->SetError(e.c_str());
+ return false;
+ }
+
+ const std::string& left = args[2];
+ const std::string& right = args[3];
+ const std::string& outvar = args[4];
+ bool result;
+ if(mode == "LESS")
+ {
+ result = (left < right);
+ }
+ else if(mode == "GREATER")
+ {
+ result = (left > right);
+ }
+ else if(mode == "EQUAL")
+ {
+ result = (left == right);
+ }
+ else // if(mode == "NOTEQUAL")
+ {
+ result = !(left == right);
+ }
+ if(result)
+ {
+ this->Makefile->AddDefinition(outvar.c_str(), "1");
+ }
+ else
+ {
+ this->Makefile->AddDefinition(outvar.c_str(), "0");
+ }
+ return true;
+ }
+ std::string e = "sub-command COMPARE does not recognize mode "+mode;
+ this->SetError(e.c_str());
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmStringCommand::HandleReplaceCommand(std::vector<std::string> const&
+ args)
+{
+ if(args.size() < 5)
+ {
+ this->SetError("sub-command REPLACE requires at least four arguments.");
+ return false;
+ }
+
+ const std::string& matchExpression = args[1];
+ 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];
+ }
+
+ cmsys::SystemTools::ReplaceString(input, matchExpression.c_str(),
+ replaceExpression.c_str());
+
+ this->Makefile->AddDefinition(variableName.c_str(), input.c_str());
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmStringCommand::HandleSubstringCommand(std::vector<std::string> const&
+ args)
+{
+ if(args.size() != 5)
+ {
+ this->SetError("sub-command SUBSTRING requires four arguments.");
+ return false;
+ }
+
+ const std::string& stringValue = args[1];
+ int begin = atoi(args[2].c_str());
+ int end = atoi(args[3].c_str());
+ const std::string& variableName = args[4];
+
+ size_t stringLength = stringValue.size();
+ int intStringLength = static_cast<int>(stringLength);
+ if ( begin < 0 || begin > intStringLength )
+ {
+ cmOStringStream ostr;
+ ostr << "begin index: " << begin << " is out of range 0 - "
+ << stringLength;
+ this->SetError(ostr.str().c_str());
+ return false;
+ }
+ int leftOverLength = intStringLength - begin;
+ if ( end < -1 || end > leftOverLength )
+ {
+ cmOStringStream ostr;
+ ostr << "end index: " << end << " is out of range -1 - "
+ << leftOverLength;
+ this->SetError(ostr.str().c_str());
+ return false;
+ }
+
+ this->Makefile->AddDefinition(variableName.c_str(),
+ stringValue.substr(begin, end).c_str());
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmStringCommand
+::HandleLengthCommand(std::vector<std::string> const& args)
+{
+ if(args.size() != 3)
+ {
+ this->SetError("sub-command LENGTH requires two arguments.");
+ return false;
+ }
+
+ const std::string& stringValue = args[1];
+ const std::string& variableName = args[2];
+
+ size_t length = stringValue.size();
+ char buffer[1024];
+ sprintf(buffer, "%d", static_cast<int>(length));
+
+ this->Makefile->AddDefinition(variableName.c_str(), buffer);
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmStringCommand::HandleStripCommand(
+ std::vector<std::string> const& args)
+{
+ if(args.size() != 3)
+ {
+ this->SetError("sub-command STRIP requires two arguments.");
+ return false;
+ }
+
+ const std::string& stringValue = args[1];
+ const std::string& variableName = args[2];
+ size_t inStringLength = stringValue.size();
+ size_t startPos = inStringLength + 1;
+ size_t endPos = 0;
+ const char* ptr = stringValue.c_str();
+ size_t cc;
+ for ( cc = 0; cc < inStringLength; ++ cc )
+ {
+ if ( !isspace(*ptr) )
+ {
+ if ( startPos > inStringLength )
+ {
+ startPos = cc;
+ }
+ endPos = cc;
+ }
+ ++ ptr;
+ }
+
+ size_t outLength = 0;
+
+ // if the input string didn't contain any non-space characters, return
+ // an empty string
+ if (startPos > inStringLength)
+ {
+ outLength = 0;
+ startPos = 0;
+ }
+ else
+ {
+ outLength=endPos - startPos + 1;
+ }
+
+ this->Makefile->AddDefinition(variableName.c_str(),
+ stringValue.substr(startPos, outLength).c_str());
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmStringCommand
+::HandleRandomCommand(std::vector<std::string> const& args)
+{
+ if(args.size() < 2 || args.size() == 3 || args.size() == 5)
+ {
+ this->SetError("sub-command RANDOM requires at least one argument.");
+ return false;
+ }
+
+ static bool seeded = false;
+ bool force_seed = false;
+ unsigned int seed = 0;
+ int length = 5;
+ const char cmStringCommandDefaultAlphabet[] = "qwertyuiopasdfghjklzxcvbnm"
+ "QWERTYUIOPASDFGHJKLZXCVBNM"
+ "0123456789";
+ std::string alphabet;
+
+ if ( args.size() > 3 )
+ {
+ size_t i = 1;
+ size_t stopAt = args.size() - 2;
+
+ for ( ; i < stopAt; ++i )
+ {
+ if ( args[i] == "LENGTH" )
+ {
+ ++i;
+ length = atoi(args[i].c_str());
+ }
+ else if ( args[i] == "ALPHABET" )
+ {
+ ++i;
+ alphabet = args[i];
+ }
+ else if ( args[i] == "RANDOM_SEED" )
+ {
+ ++i;
+ seed = static_cast<unsigned int>(atoi(args[i].c_str()));
+ force_seed = true;
+ }
+ }
+ }
+ if ( !alphabet.size() )
+ {
+ alphabet = cmStringCommandDefaultAlphabet;
+ }
+
+ double sizeofAlphabet = static_cast<double>(alphabet.size());
+ if ( sizeofAlphabet < 1 )
+ {
+ this->SetError("sub-command RANDOM invoked with bad alphabet.");
+ return false;
+ }
+ if ( length < 1 )
+ {
+ this->SetError("sub-command RANDOM invoked with bad length.");
+ return false;
+ }
+ const std::string& variableName = args[args.size()-1];
+
+ std::vector<char> result;
+
+ if (!seeded || force_seed)
+ {
+ seeded = true;
+ srand(force_seed? seed : cmSystemTools::RandomSeed());
+ }
+
+ const char* alphaPtr = alphabet.c_str();
+ int cc;
+ for ( cc = 0; cc < length; cc ++ )
+ {
+ int idx=(int) (sizeofAlphabet* rand()/(RAND_MAX+1.0));
+ result.push_back(*(alphaPtr + idx));
+ }
+ result.push_back(0);
+
+ this->Makefile->AddDefinition(variableName.c_str(), &*result.begin());
+ return true;
+}
diff --git a/Source/cmStringCommand.h b/Source/cmStringCommand.h
new file mode 100644
index 000000000..3e585a5b3
--- /dev/null
+++ b/Source/cmStringCommand.h
@@ -0,0 +1,181 @@
+/*============================================================================
+ 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 cmStringCommand_h
+#define cmStringCommand_h
+
+#include "cmCommand.h"
+
+class cmMakefile;
+namespace cmsys
+{
+ class RegularExpression;
+}
+
+/** \class cmStringCommand
+ * \brief Common string operations
+ *
+ */
+class cmStringCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmStringCommand;
+ }
+
+ /**
+ * 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 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"
+ "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 a line\n"
+ " $ Matches at end of a line\n"
+ " . Matches any single character\n"
+ " [ ] Matches any character(s) inside the brackets\n"
+ " [^ ] Matches any character(s) not inside the brackets\n"
+ " - Matches any character in range on either side of a dash\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).";
+ }
+
+ 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);
+ bool HandleRegexCommand(std::vector<std::string> const& args);
+ bool RegexMatch(std::vector<std::string> const& args);
+ bool RegexMatchAll(std::vector<std::string> const& args);
+ bool RegexReplace(std::vector<std::string> const& args);
+ bool HandleHashCommand(std::vector<std::string> const& args);
+ bool HandleToUpperLowerCommand(std::vector<std::string> const& args,
+ bool toUpper);
+ bool HandleCompareCommand(std::vector<std::string> const& args);
+ 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 HandleStripCommand(std::vector<std::string> const& args);
+ bool HandleRandomCommand(std::vector<std::string> const& args);
+ bool HandleFindCommand(std::vector<std::string> const& args);
+
+ class RegexReplacement
+ {
+ public:
+ RegexReplacement(const char* s): number(-1), value(s) {}
+ RegexReplacement(const std::string& s): number(-1), value(s) {}
+ RegexReplacement(int n): number(n), value() {}
+ RegexReplacement() {};
+ int number;
+ std::string value;
+ };
+};
+
+
+#endif
diff --git a/Source/cmSubdirCommand.cxx b/Source/cmSubdirCommand.cxx
new file mode 100644
index 000000000..9fcbe77ec
--- /dev/null
+++ b/Source/cmSubdirCommand.cxx
@@ -0,0 +1,74 @@
+/*============================================================================
+ 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 "cmSubdirCommand.h"
+
+// cmSubdirCommand
+bool cmSubdirCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 1 )
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+ bool res = true;
+ bool excludeFromAll = false;
+ bool preorder = false;
+
+ for(std::vector<std::string>::const_iterator i = args.begin();
+ i != args.end(); ++i)
+ {
+ if(*i == "EXCLUDE_FROM_ALL")
+ {
+ excludeFromAll = true;
+ continue;
+ }
+ if(*i == "PREORDER")
+ {
+ preorder = true;
+ continue;
+ }
+
+ // if they specified a relative path then compute the full
+ std::string srcPath =
+ std::string(this->Makefile->GetCurrentDirectory()) +
+ "/" + i->c_str();
+ if (cmSystemTools::FileIsDirectory(srcPath.c_str()))
+ {
+ std::string binPath =
+ std::string(this->Makefile->GetCurrentOutputDirectory()) +
+ "/" + i->c_str();
+ this->Makefile->AddSubDirectory(srcPath.c_str(), binPath.c_str(),
+ excludeFromAll, preorder, false);
+ }
+ // otherwise it is a full path
+ else if ( cmSystemTools::FileIsDirectory(i->c_str()) )
+ {
+ // 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);
+ }
+ else
+ {
+ std::string error = "Incorrect SUBDIRS command. Directory: ";
+ error += *i + " does not exists.";
+ this->SetError(error.c_str());
+ res = false;
+ }
+ }
+ return res;
+}
+
diff --git a/Source/cmSubdirCommand.h b/Source/cmSubdirCommand.h
new file mode 100644
index 000000000..eedbfff92
--- /dev/null
+++ b/Source/cmSubdirCommand.h
@@ -0,0 +1,92 @@
+/*============================================================================
+ 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 cmSubdirCommand_h
+#define cmSubdirCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmSubdirCommand
+ * \brief Specify a list of subdirectories to build.
+ *
+ * cmSubdirCommand specifies a list of subdirectories to process
+ * by CMake. For each subdirectory listed, CMake will descend
+ * into that subdirectory and process any CMakeLists.txt found.
+ */
+class cmSubdirCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmSubdirCommand;
+ }
+
+ /**
+ * 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 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;
+ }
+
+ cmTypeMacro(cmSubdirCommand, cmCommand);
+};
+
+
+
+#endif
diff --git a/Source/cmSubdirDependsCommand.cxx b/Source/cmSubdirDependsCommand.cxx
new file mode 100644
index 000000000..2af7bf1c9
--- /dev/null
+++ b/Source/cmSubdirDependsCommand.cxx
@@ -0,0 +1,20 @@
+/*============================================================================
+ 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 "cmSubdirDependsCommand.h"
+
+// cmSubdirDependsCommand
+bool cmSubdirDependsCommand::InitialPass(std::vector<std::string> const& ,
+ cmExecutionStatus &)
+{
+ return true;
+}
+
diff --git a/Source/cmSubdirDependsCommand.h b/Source/cmSubdirDependsCommand.h
new file mode 100644
index 000000000..daf97cd2f
--- /dev/null
+++ b/Source/cmSubdirDependsCommand.h
@@ -0,0 +1,77 @@
+/*============================================================================
+ 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 cmSubdirDependsCommand_h
+#define cmSubdirDependsCommand_h
+
+#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 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;
+ }
+
+ cmTypeMacro(cmSubdirDependsCommand, cmCommand);
+};
+
+
+
+#endif
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
new file mode 100644
index 000000000..89f03f62c
--- /dev/null
+++ b/Source/cmSystemTools.cxx
@@ -0,0 +1,2948 @@
+/*============================================================================
+ 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.
+============================================================================*/
+#if defined(_MSC_VER) && _MSC_VER < 1300
+# define _WIN32_WINNT 0x0400 /* for wincrypt.h */
+#endif
+#include "cmSystemTools.h"
+#include <ctype.h>
+#include <errno.h>
+#include <time.h>
+#include <string.h>
+#include <stdlib.h>
+#ifdef __QNX__
+# include <malloc.h> /* for malloc/free on QNX */
+#endif
+#include <cmsys/Glob.hxx>
+#include <cmsys/RegularExpression.hxx>
+#include <cmsys/Directory.hxx>
+#include <cmsys/System.h>
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+# include "cmArchiveWrite.h"
+# include <cm_libarchive.h>
+# include <cmsys/Terminal.h>
+#endif
+#include <cmsys/stl/algorithm>
+
+#if defined(_WIN32)
+# include <windows.h>
+# include <wincrypt.h>
+#else
+# include <sys/time.h>
+# include <sys/types.h>
+# include <unistd.h>
+# include <utime.h>
+# include <sys/wait.h>
+#endif
+
+#include <sys/stat.h>
+
+#if defined(_WIN32) && \
+ (defined(_MSC_VER) || defined(__WATCOMC__) || \
+ defined(__BORLANDC__) || defined(__MINGW32__))
+# include <io.h>
+#endif
+
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+# include <memory> // auto_ptr
+# include <fcntl.h>
+# include "cmCryptoHash.h"
+#endif
+
+#if defined(CMAKE_USE_ELF_PARSER)
+# include "cmELF.h"
+#endif
+
+class cmSystemToolsFileTime
+{
+public:
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ FILETIME timeCreation;
+ FILETIME timeLastAccess;
+ FILETIME timeLastWrite;
+#else
+ struct utimbuf timeBuf;
+#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)
+extern __declspec( dllimport ) char** environ;
+# else
+extern char** environ;
+# endif
+#endif
+
+#ifdef _WIN32
+class cmSystemToolsWindowsHandle
+{
+public:
+ cmSystemToolsWindowsHandle(HANDLE h): handle_(h) {}
+ ~cmSystemToolsWindowsHandle()
+ {
+ if(this->handle_ != INVALID_HANDLE_VALUE)
+ {
+ CloseHandle(this->handle_);
+ }
+ }
+ operator bool() const { return this->handle_ != INVALID_HANDLE_VALUE; }
+ bool operator !() const { return this->handle_ == INVALID_HANDLE_VALUE; }
+ operator HANDLE() const { return this->handle_; }
+private:
+ HANDLE handle_;
+};
+#elif defined(__APPLE__)
+#include <crt_externs.h>
+#define environ (*_NSGetEnviron())
+#endif
+
+bool cmSystemTools::s_RunCommandHideConsole = false;
+bool cmSystemTools::s_DisableRunCommandOutput = false;
+bool cmSystemTools::s_ErrorOccured = false;
+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;
+
+// replace replace with with as many times as it shows up in source.
+// write the result into source.
+#if defined(_WIN32) && !defined(__CYGWIN__)
+void cmSystemTools::ExpandRegistryValues(std::string& source, KeyWOW64 view)
+{
+ // Regular expression to match anything inside [...] that begins in HKEY.
+ // Note that there is a special rule for regular expressions to match a
+ // close square-bracket inside a list delimited by square brackets.
+ // The "[^]]" part of this expression will match any character except
+ // a close square-bracket. The ']' character must be the first in the
+ // list of characters inside the [^...] block of the expression.
+ cmsys::RegularExpression regEntry("\\[(HKEY[^]]*)\\]");
+
+ // check for black line or comment
+ while (regEntry.find(source))
+ {
+ // the arguments are the second match
+ std::string key = regEntry.match(1);
+ std::string val;
+ if (ReadRegistryValue(key.c_str(), val, view))
+ {
+ std::string reg = "[";
+ reg += key + "]";
+ cmSystemTools::ReplaceString(source, reg.c_str(), val.c_str());
+ }
+ else
+ {
+ std::string reg = "[";
+ reg += key + "]";
+ cmSystemTools::ReplaceString(source, reg.c_str(), "/registry");
+ }
+ }
+}
+#else
+void cmSystemTools::ExpandRegistryValues(std::string& source, KeyWOW64)
+{
+ cmsys::RegularExpression regEntry("\\[(HKEY[^]]*)\\]");
+ while (regEntry.find(source))
+ {
+ // the arguments are the second match
+ std::string key = regEntry.match(1);
+ std::string val;
+ std::string reg = "[";
+ reg += key + "]";
+ cmSystemTools::ReplaceString(source, reg.c_str(), "/registry");
+ }
+
+}
+#endif
+
+std::string cmSystemTools::EscapeQuotes(const char* str)
+{
+ std::string result = "";
+ for(const char* ch = str; *ch != '\0'; ++ch)
+ {
+ if(*ch == '"')
+ {
+ result += '\\';
+ }
+ result += *ch;
+ }
+ return result;
+}
+
+std::string cmSystemTools::TrimWhitespace(const std::string& s)
+{
+ std::string::const_iterator start = s.begin();
+ while(start != s.end() && *start == ' ')
+ ++start;
+ if (start == s.end())
+ return "";
+
+ std::string::const_iterator stop = s.end()-1;
+ while(*stop == ' ')
+ --stop;
+ return std::string(start, stop+1);
+}
+
+void cmSystemTools::Error(const char* m1, const char* m2,
+ const char* m3, const char* m4)
+{
+ std::string message = "CMake Error: ";
+ if(m1)
+ {
+ message += m1;
+ }
+ if(m2)
+ {
+ message += m2;
+ }
+ if(m3)
+ {
+ message += m3;
+ }
+ if(m4)
+ {
+ message += m4;
+ }
+ cmSystemTools::s_ErrorOccured = true;
+ cmSystemTools::Message(message.c_str(),"Error");
+}
+
+void cmSystemTools::SetInterruptCallback(InterruptCallback f, void* clientData)
+{
+ s_InterruptCallback = f;
+ s_InterruptCallbackClientData = clientData;
+}
+
+bool cmSystemTools::GetInterruptFlag()
+{
+ if(s_InterruptCallback)
+ {
+ return (*s_InterruptCallback)(s_InterruptCallbackClientData);
+ }
+ return false;
+}
+
+void cmSystemTools::SetErrorCallback(ErrorCallback f, void* clientData)
+{
+ s_ErrorCallback = f;
+ s_ErrorCallbackClientData = clientData;
+}
+
+void cmSystemTools::SetStdoutCallback(StdoutCallback f, void* clientData)
+{
+ s_StdoutCallback = f;
+ s_StdoutCallbackClientData = clientData;
+}
+
+void cmSystemTools::Stdout(const char* s)
+{
+ if(s_StdoutCallback)
+ {
+ (*s_StdoutCallback)(s, static_cast<int>(strlen(s)),
+ s_StdoutCallbackClientData);
+ }
+ 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)
+{
+ if(s_StdoutCallback)
+ {
+ (*s_StdoutCallback)(s, length, s_StdoutCallbackClientData);
+ }
+ else
+ {
+ std::cout.write(s, length);
+ std::cout.flush();
+ }
+}
+
+void cmSystemTools::Message(const char* m1, const char *title)
+{
+ if(s_DisableMessages)
+ {
+ return;
+ }
+ if(s_ErrorCallback)
+ {
+ (*s_ErrorCallback)(m1, title, s_DisableMessages,
+ s_ErrorCallbackClientData);
+ return;
+ }
+ else
+ {
+ std::cerr << m1 << std::endl << std::flush;
+ }
+
+}
+
+
+void cmSystemTools::ReportLastSystemError(const char* msg)
+{
+ std::string m = msg;
+ m += ": System Error: ";
+ m += Superclass::GetLastSystemError();
+ cmSystemTools::Error(m.c_str());
+}
+
+bool cmSystemTools::IsInternallyOn(const char* val)
+{
+ if (!val)
+ {
+ return false;
+ }
+ std::basic_string<char> v = val;
+
+ 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");
+}
+
+bool cmSystemTools::IsOn(const char* val)
+{
+ if (!val)
+ {
+ return false;
+ }
+ std::basic_string<char> v = val;
+
+ 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");
+}
+
+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)
+ {
+ return ( strcmp(val, "NOTFOUND") == 0);
+ }
+ return ((strncmp((val + (len - lenNotFound)), notfound, lenNotFound) == 0));
+}
+
+
+bool cmSystemTools::IsOff(const char* val)
+{
+ if (!val || strlen(val) == 0)
+ {
+ return true;
+ }
+ std::basic_string<char> v = val;
+
+ 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");
+}
+
+//----------------------------------------------------------------------------
+void cmSystemTools::ParseWindowsCommandLine(const char* command,
+ std::vector<std::string>& args)
+{
+ // See the MSDN document "Parsing C Command-Line Arguments" at
+ // http://msdn2.microsoft.com/en-us/library/a1y7w461.aspx for rules
+ // of parsing the windows command line.
+
+ bool in_argument = false;
+ bool in_quotes = false;
+ int backslashes = 0;
+ std::string arg;
+ for(const char* c = command;*c; ++c)
+ {
+ if(*c == '\\')
+ {
+ ++backslashes;
+ in_argument = true;
+ }
+ else if(*c == '"')
+ {
+ int backslash_pairs = backslashes >> 1;
+ int backslash_escaped = backslashes & 1;
+ arg.append(backslash_pairs, '\\');
+ backslashes = 0;
+ if(backslash_escaped)
+ {
+ /* An odd number of backslashes precede this quote.
+ It is escaped. */
+ arg.append(1, '"');
+ }
+ else
+ {
+ /* An even number of backslashes precede this quote.
+ It is not escaped. */
+ in_quotes = !in_quotes;
+ }
+ in_argument = true;
+ }
+ else
+ {
+ arg.append(backslashes, '\\');
+ backslashes = 0;
+ if(isspace(*c))
+ {
+ if(in_quotes)
+ {
+ arg.append(1, *c);
+ }
+ else if(in_argument)
+ {
+ args.push_back(arg);
+ arg = "";
+ in_argument = false;
+ }
+ }
+ else
+ {
+ in_argument = true;
+ arg.append(1, *c);
+ }
+ }
+ }
+ arg.append(backslashes, '\\');
+ if(in_argument)
+ {
+ args.push_back(arg);
+ }
+}
+
+//----------------------------------------------------------------------------
+class cmSystemToolsArgV
+{
+ char** ArgV;
+public:
+ cmSystemToolsArgV(char** argv): ArgV(argv) {}
+ ~cmSystemToolsArgV()
+ {
+ for(char** arg = this->ArgV; arg && *arg; ++arg)
+ {
+ free(*arg);
+ }
+ free(this->ArgV);
+ }
+ void Store(std::vector<std::string>& args) const
+ {
+ for(char** arg = this->ArgV; arg && *arg; ++arg)
+ {
+ args.push_back(*arg);
+ }
+ }
+ void Store(std::vector<cmStdString>& args) const
+ {
+ for(char** arg = this->ArgV; arg && *arg; ++arg)
+ {
+ args.push_back(*arg);
+ }
+ }
+};
+
+//----------------------------------------------------------------------------
+void cmSystemTools::ParseUnixCommandLine(const char* command,
+ std::vector<std::string>& args)
+{
+ // Invoke the underlying parser.
+ cmSystemToolsArgV argv = cmsysSystem_Parse_CommandForUnix(command, 0);
+ argv.Store(args);
+}
+
+//----------------------------------------------------------------------------
+void cmSystemTools::ParseUnixCommandLine(const char* command,
+ std::vector<cmStdString>& args)
+{
+ // 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::string arg;
+
+ bool win_path = false;
+
+ if ((command[0] != '/' && command[1] == ':' && command[2] == '\\') ||
+ (command[0] == '\"' && command[1] != '/' && command[2] == ':'
+ && command[3] == '\\') ||
+ (command[0] == '\'' && command[1] != '/' && command[2] == ':'
+ && command[3] == '\\') ||
+ (command[0] == '\\' && command[1] == '\\'))
+ {
+ win_path = true;
+ }
+ // Split the command into an argv array.
+ for(const char* c = command; *c;)
+ {
+ // Skip over whitespace.
+ while(*c == ' ' || *c == '\t')
+ {
+ ++c;
+ }
+ arg = "";
+ if(*c == '"')
+ {
+ // Parse a quoted argument.
+ ++c;
+ while(*c && *c != '"')
+ {
+ arg.append(1, *c);
+ ++c;
+ }
+ if(*c)
+ {
+ ++c;
+ }
+ args.push_back(arg);
+ }
+ else if(*c == '\'')
+ {
+ // Parse a quoted argument.
+ ++c;
+ while(*c && *c != '\'')
+ {
+ arg.append(1, *c);
+ ++c;
+ }
+ if(*c)
+ {
+ ++c;
+ }
+ args.push_back(arg);
+ }
+ else if(*c)
+ {
+ // Parse an unquoted argument.
+ while(*c && *c != ' ' && *c != '\t')
+ {
+ if(*c == '\\' && !win_path)
+ {
+ ++c;
+ if(*c)
+ {
+ arg.append(1, *c);
+ ++c;
+ }
+ }
+ else
+ {
+ arg.append(1, *c);
+ ++c;
+ }
+ }
+ args.push_back(arg);
+ }
+ }
+
+ return args;
+}
+
+
+bool cmSystemTools::RunSingleCommand(std::vector<cmStdString>const& command,
+ std::string* output ,
+ int* retVal , const char* dir ,
+ OutputOption outputflag ,
+ double timeout )
+{
+ std::vector<const char*> argv;
+ for(std::vector<cmStdString>::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());
+ cmsysProcess_SetWorkingDirectory(cp, dir);
+ if(cmSystemTools::GetRunCommandHideConsole())
+ {
+ cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1);
+ }
+
+ cmsysProcess_SetTimeout(cp, timeout);
+ cmsysProcess_Execute(cp);
+
+ std::vector<char> tempOutput;
+ char* data;
+ int length;
+ int pipe;
+ if ( output || 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)
+ {
+ if(data[i] == '\0')
+ {
+ data[i] = ' ';
+ }
+ }
+ }
+ if ( output )
+ {
+ tempOutput.insert(tempOutput.end(), data, data+length);
+ }
+ if(outputflag != OUTPUT_NONE)
+ {
+ if(outputflag == OUTPUT_MERGE)
+ {
+ cmSystemTools::Stdout(data, length);
+ }
+ else
+ {
+ if(pipe == cmsysProcess_Pipe_STDERR)
+ {
+ cmSystemTools::Stderr(data, length);
+ }
+ else if(pipe == cmsysProcess_Pipe_STDOUT)
+ {
+ cmSystemTools::Stdout(data, length);
+ }
+ }
+ }
+ }
+ }
+
+ cmsysProcess_WaitForExit(cp, 0);
+ if ( output && tempOutput.begin() != tempOutput.end())
+ {
+ output->append(&*tempOutput.begin(), tempOutput.size());
+ }
+
+ bool result = true;
+ if(cmsysProcess_GetState(cp) == cmsysProcess_State_Exited)
+ {
+ if ( retVal )
+ {
+ *retVal = cmsysProcess_GetExitValue(cp);
+ }
+ else
+ {
+ if ( cmsysProcess_GetExitValue(cp) != 0 )
+ {
+ result = false;
+ }
+ }
+ }
+ else if(cmsysProcess_GetState(cp) == cmsysProcess_State_Exception)
+ {
+ const char* exception_str = cmsysProcess_GetExceptionString(cp);
+ if ( outputflag != OUTPUT_NONE )
+ {
+ std::cerr << exception_str << std::endl;
+ }
+ if ( output )
+ {
+ output->append(exception_str, strlen(exception_str));
+ }
+ result = false;
+ }
+ else if(cmsysProcess_GetState(cp) == cmsysProcess_State_Error)
+ {
+ const char* error_str = cmsysProcess_GetErrorString(cp);
+ if ( outputflag != OUTPUT_NONE )
+ {
+ std::cerr << error_str << std::endl;
+ }
+ if ( output )
+ {
+ output->append(error_str, strlen(error_str));
+ }
+ result = false;
+ }
+ else if(cmsysProcess_GetState(cp) == cmsysProcess_State_Expired)
+ {
+ const char* error_str = "Process terminated due to timeout\n";
+ if ( outputflag != OUTPUT_NONE )
+ {
+ std::cerr << error_str << std::endl;
+ }
+ if ( output )
+ {
+ output->append(error_str, strlen(error_str));
+ }
+ result = false;
+ }
+
+ cmsysProcess_Delete(cp);
+ return result;
+}
+
+bool cmSystemTools::RunSingleCommand(
+ const char* command,
+ std::string* output,
+ int *retVal,
+ const char* dir,
+ OutputOption outputflag,
+ double timeout)
+{
+ if(s_DisableRunCommandOutput)
+ {
+ outputflag = OUTPUT_NONE;
+ }
+
+ std::vector<cmStdString> 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;
+}
+#endif
+
+bool RunCommandViaPopen(const char* command,
+ const char* dir,
+ std::string& output,
+ int& retVal,
+ bool verbose,
+ int /*timeout*/)
+{
+ // 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)
+ {
+ cmSystemTools::Stdout("running ");
+ cmSystemTools::Stdout(command);
+ cmSystemTools::Stdout("\n");
+ }
+ 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
+}
+
+bool cmSystemTools::DoesFileExistWithExtensions(
+ const char* name,
+ const std::vector<std::string>& headerExts)
+{
+ std::string hname;
+
+ for( std::vector<std::string>::const_iterator ext = headerExts.begin();
+ ext != headerExts.end(); ++ext )
+ {
+ hname = name;
+ hname += ".";
+ hname += *ext;
+ if(cmSystemTools::FileExists(hname.c_str()))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+std::string cmSystemTools::FileExistsInParentDirectories(const char* fname,
+ const char* directory, const char* toplevel)
+{
+ std::string file = fname;
+ cmSystemTools::ConvertToUnixSlashes(file);
+ std::string dir = directory;
+ cmSystemTools::ConvertToUnixSlashes(dir);
+ std::string prevDir;
+ while(dir != prevDir)
+ {
+ std::string path = dir + "/" + file;
+ if ( cmSystemTools::FileExists(path.c_str()) )
+ {
+ return path;
+ }
+ if ( dir.size() < strlen(toplevel) )
+ {
+ break;
+ }
+ prevDir = dir;
+ dir = cmSystemTools::GetParentDirectory(dir.c_str());
+ }
+ return "";
+}
+
+bool cmSystemTools::cmCopyFile(const char* source, const char* destination)
+{
+ return Superclass::CopyFileAlways(source, destination);
+}
+
+bool cmSystemTools::CopyFileIfDifferent(const char* source,
+ const char* destination)
+{
+ return Superclass::CopyFileIfDifferent(source, destination);
+}
+
+//----------------------------------------------------------------------------
+bool cmSystemTools::RenameFile(const char* oldname, const char* newname)
+{
+#ifdef _WIN32
+ /* On Windows the move functions will not replace existing files.
+ Check if the destination exists. */
+ struct stat newFile;
+ if(stat(newname, &newFile) == 0)
+ {
+ /* The destination exists. We have to replace it carefully. The
+ MoveFileEx function does what we need but is not available on
+ Win9x. */
+ OSVERSIONINFO osv;
+ DWORD attrs;
+
+ /* Make sure the destination is not read only. */
+ attrs = GetFileAttributes(newname);
+ if(attrs & FILE_ATTRIBUTE_READONLY)
+ {
+ SetFileAttributes(newname, attrs & ~FILE_ATTRIBUTE_READONLY);
+ }
+
+ /* Check the windows version number. */
+ osv.dwOSVersionInfoSize = sizeof(osv);
+ GetVersionEx(&osv);
+ if(osv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
+ {
+ /* This is Win9x. There is no MoveFileEx implementation. We
+ cannot quite rename the file atomically. Just delete the
+ destination and then move the file. */
+ DeleteFile(newname);
+ return MoveFile(oldname, newname) != 0;
+ }
+ else
+ {
+ /* This is not Win9x. Use the MoveFileEx implementation. */
+ return MoveFileEx(oldname, newname, MOVEFILE_REPLACE_EXISTING) != 0;
+ }
+ }
+ else
+ {
+ /* The destination does not exist. Just move the file. */
+ return MoveFile(oldname, newname) != 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)
+{
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ cmCryptoHashMD5 md5;
+ std::string str = md5.HashFile(source);
+ strncpy(md5out, str.c_str(), 32);
+ return !str.empty();
+#else
+ (void)source;
+ (void)md5out;
+ cmSystemTools::Message("md5sum not supported in bootstrapping mode","Error");
+ return false;
+#endif
+}
+
+std::string cmSystemTools::ComputeStringMD5(const char* input)
+{
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ cmCryptoHashMD5 md5;
+ return md5.HashString(input);
+#else
+ (void)input;
+ cmSystemTools::Message("md5sum not supported in bootstrapping mode","Error");
+ return "";
+#endif
+}
+
+void cmSystemTools::Glob(const char *directory, const char *regexp,
+ std::vector<std::string>& files)
+{
+ cmsys::Directory d;
+ cmsys::RegularExpression reg(regexp);
+
+ if (d.Load(directory))
+ {
+ size_t numf;
+ unsigned int i;
+ numf = d.GetNumberOfFiles();
+ for (i = 0; i < numf; i++)
+ {
+ std::string fname = d.GetFile(i);
+ if (reg.find(fname))
+ {
+ files.push_back(fname);
+ }
+ }
+ }
+}
+
+
+void cmSystemTools::GlobDirs(const char *fullPath,
+ 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);
+ return;
+ }
+ std::string startPath = path.substr(0, pos);
+ std::string finishPath = path.substr(pos+2);
+
+ cmsys::Directory d;
+ if (d.Load(startPath.c_str()))
+ {
+ for (unsigned int i = 0; i < d.GetNumberOfFiles(); ++i)
+ {
+ if((std::string(d.GetFile(i)) != ".")
+ && (std::string(d.GetFile(i)) != ".."))
+ {
+ std::string fname = startPath;
+ fname +="/";
+ fname += d.GetFile(i);
+ if(cmSystemTools::FileIsDirectory(fname.c_str()))
+ {
+ fname += finishPath;
+ cmSystemTools::GlobDirs(fname.c_str(), files);
+ }
+ }
+ }
+ }
+}
+
+
+void cmSystemTools::ExpandList(std::vector<std::string> const& arguments,
+ std::vector<std::string>& newargs)
+{
+ std::vector<std::string>::const_iterator i;
+ for(i = arguments.begin();i != arguments.end(); ++i)
+ {
+ cmSystemTools::ExpandListArgument(*i, newargs);
+ }
+}
+
+void cmSystemTools::ExpandListArgument(const std::string& arg,
+ std::vector<std::string>& newargs,
+ bool emptyArgs)
+{
+ // If argument is empty, it is an empty list.
+ if(arg.length() == 0 && !emptyArgs)
+ {
+ return;
+ }
+ // if there are no ; in the name then just copy the current string
+ if(arg.find(';') == std::string::npos)
+ {
+ newargs.push_back(arg);
+ return;
+ }
+ std::vector<char> newArgVec;
+ // Break the string at non-escaped semicolons not nested in [].
+ int squareNesting = 0;
+ for(const char* c = arg.c_str(); *c; ++c)
+ {
+ switch(*c)
+ {
+ case '\\':
+ {
+ // We only want to allow escaping of semicolons. Other
+ // escapes should not be processed here.
+ ++c;
+ if(*c == ';')
+ {
+ newArgVec.push_back(*c);
+ }
+ else
+ {
+ newArgVec.push_back('\\');
+ if(*c)
+ {
+ newArgVec.push_back(*c);
+ }
+ else
+ {
+ // Terminate the loop properly.
+ --c;
+ }
+ }
+ } break;
+ case '[':
+ {
+ ++squareNesting;
+ newArgVec.push_back(*c);
+ } break;
+ case ']':
+ {
+ --squareNesting;
+ newArgVec.push_back(*c);
+ } break;
+ case ';':
+ {
+ // Break the string here if we are not nested inside square
+ // brackets.
+ if(squareNesting == 0)
+ {
+ if ( newArgVec.size() || emptyArgs )
+ {
+ // Add the last argument if the string is not empty.
+ newArgVec.push_back(0);
+ newargs.push_back(&*newArgVec.begin());
+ newArgVec.clear();
+ }
+ }
+ else
+ {
+ newArgVec.push_back(*c);
+ }
+ } break;
+ default:
+ {
+ // Just append this character.
+ newArgVec.push_back(*c);
+ } break;
+ }
+ }
+ if ( newArgVec.size() || emptyArgs )
+ {
+ // Add the last argument if the string is not empty.
+ newArgVec.push_back(0);
+ newargs.push_back(&*newArgVec.begin());
+ }
+}
+
+bool cmSystemTools::SimpleGlob(const cmStdString& glob,
+ std::vector<cmStdString>& files,
+ int type /* = 0 */)
+{
+ files.clear();
+ if ( glob[glob.size()-1] != '*' )
+ {
+ return false;
+ }
+ std::string path = cmSystemTools::GetFilenamePath(glob);
+ std::string ppath = cmSystemTools::GetFilenameName(glob);
+ ppath = ppath.substr(0, ppath.size()-1);
+ if ( path.size() == 0 )
+ {
+ path = "/";
+ }
+
+ bool res = false;
+ cmsys::Directory d;
+ if (d.Load(path.c_str()))
+ {
+ for (unsigned int i = 0; i < d.GetNumberOfFiles(); ++i)
+ {
+ if((std::string(d.GetFile(i)) != ".")
+ && (std::string(d.GetFile(i)) != ".."))
+ {
+ std::string fname = path;
+ if ( path[path.size()-1] != '/' )
+ {
+ fname +="/";
+ }
+ fname += d.GetFile(i);
+ std::string sfname = d.GetFile(i);
+ if ( type > 0 && cmSystemTools::FileIsDirectory(fname.c_str()) )
+ {
+ continue;
+ }
+ if ( type < 0 && !cmSystemTools::FileIsDirectory(fname.c_str()) )
+ {
+ continue;
+ }
+ if ( sfname.size() >= ppath.size() &&
+ sfname.substr(0, ppath.size()) ==
+ ppath )
+ {
+ files.push_back(fname);
+ res = true;
+ }
+ }
+ }
+ }
+ return res;
+}
+
+cmSystemTools::FileFormat cmSystemTools::GetFileFormat(const char* cext)
+{
+ if ( ! cext || *cext == 0 )
+ {
+ return cmSystemTools::NO_FILE_FORMAT;
+ }
+ //std::string ext = cmSystemTools::LowerCase(cext);
+ std::string ext = cext;
+ if ( ext == "c" || ext == ".c" ||
+ ext == "m" || ext == ".m"
+ ) { return cmSystemTools::C_FILE_FORMAT; }
+ if (
+ ext == "C" || ext == ".C" ||
+ ext == "M" || ext == ".M" ||
+ ext == "c++" || ext == ".c++" ||
+ ext == "cc" || ext == ".cc" ||
+ ext == "cpp" || ext == ".cpp" ||
+ ext == "cxx" || ext == ".cxx" ||
+ ext == "mm" || ext == ".mm"
+ ) { return cmSystemTools::CXX_FILE_FORMAT; }
+ if (
+ ext == "f" || ext == ".f" ||
+ ext == "F" || ext == ".F" ||
+ ext == "f77" || ext == ".f77" ||
+ ext == "f90" || ext == ".f90" ||
+ ext == "for" || ext == ".for" ||
+ ext == "f95" || ext == ".f95"
+ ) { return cmSystemTools::FORTRAN_FILE_FORMAT; }
+ if ( ext == "java" || ext == ".java" )
+ { return cmSystemTools::JAVA_FILE_FORMAT; }
+ if (
+ ext == "H" || ext == ".H" ||
+ ext == "h" || ext == ".h" ||
+ ext == "h++" || ext == ".h++" ||
+ ext == "hm" || ext == ".hm" ||
+ ext == "hpp" || ext == ".hpp" ||
+ ext == "hxx" || ext == ".hxx" ||
+ ext == "in" || ext == ".in" ||
+ ext == "txx" || ext == ".txx"
+ ) { return cmSystemTools::HEADER_FILE_FORMAT; }
+ if ( ext == "rc" || ext == ".rc" )
+ { return cmSystemTools::RESOURCE_FILE_FORMAT; }
+ if ( ext == "def" || ext == ".def" )
+ { return cmSystemTools::DEFINITION_FILE_FORMAT; }
+ if ( ext == "lib" || ext == ".lib" ||
+ ext == "a" || ext == ".a")
+ { return cmSystemTools::STATIC_LIBRARY_FILE_FORMAT; }
+ if ( ext == "o" || ext == ".o" ||
+ ext == "obj" || ext == ".obj")
+ { return cmSystemTools::OBJECT_FILE_FORMAT; }
+#ifdef __APPLE__
+ if ( ext == "dylib" || ext == ".dylib" )
+ { return cmSystemTools::SHARED_LIBRARY_FILE_FORMAT; }
+ if ( ext == "so" || ext == ".so" ||
+ ext == "bundle" || ext == ".bundle" )
+ { return cmSystemTools::MODULE_FILE_FORMAT; }
+#else // __APPLE__
+ if ( ext == "so" || ext == ".so" ||
+ ext == "sl" || ext == ".sl" ||
+ ext == "dll" || ext == ".dll" )
+ { return cmSystemTools::SHARED_LIBRARY_FILE_FORMAT; }
+#endif // __APPLE__
+ return cmSystemTools::UNKNOWN_FILE_FORMAT;
+}
+
+bool cmSystemTools::Split(const char* s, std::vector<cmStdString>& 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);
+ }
+ return res;
+}
+
+std::string cmSystemTools::ConvertToOutputPath(const char* path)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ if(s_ForceUnixPaths)
+ {
+ return cmSystemTools::ConvertToUnixOutputPath(path);
+ }
+ return cmSystemTools::ConvertToWindowsOutputPath(path);
+#else
+ return cmSystemTools::ConvertToUnixOutputPath(path);
+#endif
+}
+
+void cmSystemTools::ConvertToOutputSlashes(std::string& path)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ if(!s_ForceUnixPaths)
+ {
+ // Convert to windows slashes.
+ std::string::size_type pos = 0;
+ while((pos = path.find('/', pos)) != std::string::npos)
+ {
+ path[pos++] = '\\';
+ }
+ }
+#else
+ static_cast<void>(path);
+#endif
+}
+
+std::string cmSystemTools::ConvertToRunCommandPath(const char* path)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ return cmSystemTools::ConvertToWindowsOutputPath(path);
+#else
+ return cmSystemTools::ConvertToUnixOutputPath(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)
+{
+ if(!cmSystemTools::FileIsFullPath(local))
+ {
+ cmSystemTools::Error("RelativePath must be passed a full path to local: ",
+ local);
+ }
+ if(!cmSystemTools::FileIsFullPath(remote))
+ {
+ cmSystemTools::Error
+ ("RelativePath must be passed a full path to remote: ", remote);
+ }
+ return cmsys::SystemTools::RelativePath(local, remote);
+}
+
+#ifdef CMAKE_BUILD_WITH_CMAKE
+//----------------------------------------------------------------------
+bool cmSystemTools::UnsetEnv(const char* value)
+{
+#if !defined(HAVE_UNSETENV)
+ std::string var = value;
+ var += "=";
+ return cmSystemTools::PutEnv(var.c_str());
+#else
+ unsetenv(value);
+ return true;
+#endif
+}
+
+//----------------------------------------------------------------------
+std::vector<std::string> cmSystemTools::GetEnvironmentVariables()
+{
+ std::vector<std::string> env;
+ int cc;
+ for ( cc = 0; environ[cc]; ++ cc )
+ {
+ env.push_back(environ[cc]);
+ }
+ return env;
+}
+
+//----------------------------------------------------------------------
+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::SaveRestoreEnvironment::SaveRestoreEnvironment()
+{
+ this->Env = cmSystemTools::GetEnvironmentVariables();
+}
+
+//----------------------------------------------------------------------
+cmSystemTools::SaveRestoreEnvironment::~SaveRestoreEnvironment()
+{
+ // First clear everything in the current environment:
+ std::vector<std::string> currentEnv = GetEnvironmentVariables();
+ for(std::vector<std::string>::const_iterator
+ eit = currentEnv.begin(); eit != currentEnv.end(); ++eit)
+ {
+ std::string var(*eit);
+
+ std::string::size_type pos = var.find("=");
+ if (pos != std::string::npos)
+ {
+ var = var.substr(0, pos);
+ }
+
+ cmSystemTools::UnsetEnv(var.c_str());
+ }
+
+ // Then put back each entry from the original environment:
+ cmSystemTools::AppendEnv(this->Env);
+}
+#endif
+
+void cmSystemTools::EnableVSConsoleOutput()
+{
+ // Visual Studio 8 2005 (devenv.exe or VCExpress.exe) will not
+ // display output to the console unless this environment variable is
+ // set. We need it to capture the output of these build tools.
+ // Note for future work that one could pass "/out \\.\pipe\NAME" to
+ // either of these executables where NAME is created with
+ // CreateNamedPipe. This would bypass the internal buffering of the
+ // output and allow it to be captured on the fly.
+#ifdef _WIN32
+ cmSystemTools::PutEnv("vsconsoleoutput=1");
+#endif
+}
+
+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;
+}
+
+bool cmSystemTools::CreateTar(const char* outFileName,
+ const std::vector<cmStdString>& files,
+ bool gzip, bool bzip2, bool verbose)
+{
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
+ std::ofstream fout(outFileName, std::ios::out | cmsys_ios_binary);
+ if(!fout)
+ {
+ std::string e = "Cannot open output file \"";
+ e += outFileName;
+ e += "\": ";
+ e += cmSystemTools::GetLastSystemError();
+ cmSystemTools::Error(e.c_str());
+ return false;
+ }
+ cmArchiveWrite a(fout, (gzip? cmArchiveWrite::CompressGZip :
+ (bzip2? cmArchiveWrite::CompressBZip2 :
+ cmArchiveWrite::CompressNone)),
+ cmArchiveWrite::TypeTAR);
+ a.SetVerbose(verbose);
+ for(std::vector<cmStdString>::const_iterator i = files.begin();
+ i != files.end(); ++i)
+ {
+ std::string path = *i;
+ if(cmSystemTools::FileIsFullPath(path.c_str()))
+ {
+ // Get the relative path to the file.
+ path = cmSystemTools::RelativePath(cwd.c_str(), path.c_str());
+ }
+ if(!a.Add(path))
+ {
+ break;
+ }
+ }
+ if(!a)
+ {
+ cmSystemTools::Error(a.GetError().c_str());
+ return false;
+ }
+ return true;
+#else
+ (void)outFileName;
+ (void)files;
+ (void)gzip;
+ (void)verbose;
+ return false;
+#endif
+}
+
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+namespace{
+#define BSDTAR_FILESIZE_PRINTF "%lu"
+#define BSDTAR_FILESIZE_TYPE unsigned long
+ void
+ list_item_verbose(FILE *out, struct archive_entry *entry)
+{
+ char tmp[100];
+ size_t w;
+ const char *p;
+ const char *fmt;
+ time_t tim;
+ static time_t now;
+ size_t u_width = 6;
+ size_t gs_width = 13;
+
+ /*
+ * We avoid collecting the entire list in memory at once by
+ * listing things as we see them. However, that also means we can't
+ * just pre-compute the field widths. Instead, we start with guesses
+ * and just widen them as necessary. These numbers are completely
+ * arbitrary.
+ */
+ if (!now)
+ {
+ time(&now);
+ }
+ fprintf(out, "%s %d ",
+ archive_entry_strmode(entry),
+ archive_entry_nlink(entry));
+
+ /* Use uname if it's present, else uid. */
+ p = archive_entry_uname(entry);
+ if ((p == NULL) || (*p == '\0'))
+ {
+ sprintf(tmp, "%lu ",
+ (unsigned long)archive_entry_uid(entry));
+ p = tmp;
+ }
+ w = strlen(p);
+ if (w > u_width)
+ {
+ u_width = w;
+ }
+ fprintf(out, "%-*s ", (int)u_width, p);
+ /* Use gname if it's present, else gid. */
+ p = archive_entry_gname(entry);
+ if (p != NULL && p[0] != '\0')
+ {
+ fprintf(out, "%s", p);
+ w = strlen(p);
+ }
+ else
+ {
+ sprintf(tmp, "%lu",
+ (unsigned long)archive_entry_gid(entry));
+ w = strlen(tmp);
+ fprintf(out, "%s", tmp);
+ }
+
+ /*
+ * Print device number or file size, right-aligned so as to make
+ * total width of group and devnum/filesize fields be gs_width.
+ * If gs_width is too small, grow it.
+ */
+ if (archive_entry_filetype(entry) == AE_IFCHR
+ || archive_entry_filetype(entry) == AE_IFBLK)
+ {
+ sprintf(tmp, "%lu,%lu",
+ (unsigned long)archive_entry_rdevmajor(entry),
+ (unsigned long)archive_entry_rdevminor(entry));
+ }
+ else
+ {
+ /*
+ * Note the use of platform-dependent macros to format
+ * the filesize here. We need the format string and the
+ * corresponding type for the cast.
+ */
+ sprintf(tmp, BSDTAR_FILESIZE_PRINTF,
+ (BSDTAR_FILESIZE_TYPE)archive_entry_size(entry));
+ }
+ if (w + strlen(tmp) >= gs_width)
+ {
+ gs_width = w+strlen(tmp)+1;
+ }
+ fprintf(out, "%*s", (int)(gs_width - w), tmp);
+
+ /* Format the time using 'ls -l' conventions. */
+ tim = archive_entry_mtime(entry);
+#define HALF_YEAR (time_t)365 * 86400 / 2
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ /* Windows' strftime function does not support %e format. */
+#define DAY_FMT "%d"
+#else
+#define DAY_FMT "%e" /* Day number without leading zeros */
+#endif
+ if (tim < now - HALF_YEAR || tim > now + HALF_YEAR)
+ {
+ fmt = DAY_FMT " %b %Y";
+ }
+ else
+ {
+ fmt = DAY_FMT " %b %H:%M";
+ }
+ strftime(tmp, sizeof(tmp), fmt, localtime(&tim));
+ fprintf(out, " %s ", tmp);
+ fprintf(out, "%s", archive_entry_pathname(entry));
+
+ /* Extra information for links. */
+ if (archive_entry_hardlink(entry)) /* Hard link */
+ {
+ fprintf(out, " link to %s",
+ archive_entry_hardlink(entry));
+ }
+ else if (archive_entry_symlink(entry)) /* Symbolic link */
+ {
+ fprintf(out, " -> %s", archive_entry_symlink(entry));
+ }
+}
+#ifdef __BORLANDC__
+# pragma warn -8066 /* unreachable code */
+#endif
+
+long copy_data(struct archive *ar, struct archive *aw)
+{
+ long r;
+ const void *buff;
+ size_t size;
+#if defined(ARCHIVE_VERSION_NUMBER) && ARCHIVE_VERSION_NUMBER >= 3000000
+ __LA_INT64_T offset;
+#else
+ off_t offset;
+#endif
+
+ for (;;)
+ {
+ r = archive_read_data_block(ar, &buff, &size, &offset);
+ if (r == ARCHIVE_EOF)
+ {
+ return (ARCHIVE_OK);
+ }
+ if (r != ARCHIVE_OK)
+ {
+ return (r);
+ }
+ r = archive_write_data_block(aw, buff, size, offset);
+ if (r != ARCHIVE_OK)
+ {
+ cmSystemTools::Message("archive_write_data_block()",
+ archive_error_string(aw));
+ return (r);
+ }
+ }
+ return r;
+}
+
+bool extract_tar(const char* outFileName, bool verbose,
+ bool extract)
+{
+ struct archive* a = archive_read_new();
+ struct archive *ext = archive_write_disk_new();
+ archive_read_support_compression_all(a);
+ archive_read_support_format_all(a);
+ struct archive_entry *entry;
+ int r = archive_read_open_file(a, outFileName, 10240);
+ if(r)
+ {
+ cmSystemTools::Error("Problem with archive_read_open_file(): ",
+ archive_error_string(a));
+ return false;
+ }
+ for (;;)
+ {
+ r = archive_read_next_header(a, &entry);
+ if (r == ARCHIVE_EOF)
+ {
+ break;
+ }
+ if (r != ARCHIVE_OK)
+ {
+ cmSystemTools::Error("Problem with archive_read_next_header(): ",
+ archive_error_string(a));
+ }
+ if (verbose && extract)
+ {
+ cmSystemTools::Stdout("x ");
+ cmSystemTools::Stdout(archive_entry_pathname(entry));
+ }
+ if(verbose && !extract)
+ {
+ list_item_verbose(stdout, entry);
+ }
+ else if(!extract)
+ {
+ cmSystemTools::Stdout(archive_entry_pathname(entry));
+ }
+ if(extract)
+ {
+ r = archive_write_disk_set_options(ext, ARCHIVE_EXTRACT_TIME);
+ if (r != ARCHIVE_OK)
+ {
+ cmSystemTools::Error(
+ "Problem with archive_write_disk_set_options(): ",
+ archive_error_string(ext));
+ }
+
+ 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));
+ }
+ else
+ {
+ copy_data(a, ext);
+ r = archive_write_finish_entry(ext);
+ if (r != ARCHIVE_OK)
+ {
+ cmSystemTools::Error("Problem with archive_write_finish_entry(): ",
+ archive_error_string(ext));
+ }
+ }
+ }
+ if (verbose || !extract)
+ {
+ cmSystemTools::Stdout("\n");
+ }
+ }
+ archive_read_close(a);
+ archive_read_finish(a);
+ return true;
+
+}
+}
+#endif
+
+bool cmSystemTools::ExtractTar(const char* outFileName,
+ bool , bool verbose)
+{
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ return extract_tar(outFileName, verbose, true);
+#else
+ (void)outFileName;
+ (void)verbose;
+ return false;
+#endif
+}
+
+bool cmSystemTools::ListTar(const char* outFileName,
+ bool ,
+ bool verbose)
+{
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+ return extract_tar(outFileName, verbose, false);
+#else
+ (void)outFileName;
+ (void)verbose;
+ return false;
+#endif
+}
+
+int cmSystemTools::WaitForLine(cmsysProcess* process, std::string& line,
+ double timeout,
+ std::vector<char>& out,
+ std::vector<char>& err)
+{
+ line = "";
+ std::vector<char>::iterator outiter = out.begin();
+ std::vector<char>::iterator erriter = err.begin();
+ while(1)
+ {
+ // Check for a newline in stdout.
+ for(;outiter != out.end(); ++outiter)
+ {
+ if((*outiter == '\r') && ((outiter+1) == out.end()))
+ {
+ break;
+ }
+ else if(*outiter == '\n' || *outiter == '\0')
+ {
+ std::vector<char>::size_type length = outiter-out.begin();
+ if(length > 1 && *(outiter-1) == '\r')
+ {
+ --length;
+ }
+ if(length > 0)
+ {
+ line.append(&out[0], length);
+ }
+ out.erase(out.begin(), outiter+1);
+ return cmsysProcess_Pipe_STDOUT;
+ }
+ }
+
+ // Check for a newline in stderr.
+ for(;erriter != err.end(); ++erriter)
+ {
+ if((*erriter == '\r') && ((erriter+1) == err.end()))
+ {
+ break;
+ }
+ else if(*erriter == '\n' || *erriter == '\0')
+ {
+ std::vector<char>::size_type length = erriter-err.begin();
+ if(length > 1 && *(erriter-1) == '\r')
+ {
+ --length;
+ }
+ if(length > 0)
+ {
+ line.append(&err[0], length);
+ }
+ err.erase(err.begin(), erriter+1);
+ return cmsysProcess_Pipe_STDERR;
+ }
+ }
+
+ // No newlines found. Wait for more data from the process.
+ int length;
+ char* data;
+ int pipe = cmsysProcess_WaitForData(process, &data, &length, &timeout);
+ if(pipe == cmsysProcess_Pipe_Timeout)
+ {
+ // Timeout has been exceeded.
+ return pipe;
+ }
+ else if(pipe == cmsysProcess_Pipe_STDOUT)
+ {
+ // Append to the stdout buffer.
+ std::vector<char>::size_type size = out.size();
+ out.insert(out.end(), data, data+length);
+ outiter = out.begin()+size;
+ }
+ else if(pipe == cmsysProcess_Pipe_STDERR)
+ {
+ // Append to the stderr buffer.
+ std::vector<char>::size_type size = err.size();
+ err.insert(err.end(), data, data+length);
+ erriter = err.begin()+size;
+ }
+ else if(pipe == cmsysProcess_Pipe_None)
+ {
+ // Both stdout and stderr pipes have broken. Return leftover data.
+ if(!out.empty())
+ {
+ line.append(&out[0], outiter-out.begin());
+ out.erase(out.begin(), out.end());
+ return cmsysProcess_Pipe_STDOUT;
+ }
+ else if(!err.empty())
+ {
+ line.append(&err[0], erriter-err.begin());
+ err.erase(err.begin(), err.end());
+ return cmsysProcess_Pipe_STDERR;
+ }
+ else
+ {
+ return cmsysProcess_Pipe_None;
+ }
+ }
+ }
+}
+
+void cmSystemTools::DoNotInheritStdPipes()
+{
+#ifdef _WIN32
+ // Check to see if we are attached to a console
+ // if so, then do not stop the inherited pipes
+ // or stdout and stderr will not show up in dos
+ // shell windows
+ CONSOLE_SCREEN_BUFFER_INFO hOutInfo;
+ HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
+ if(GetConsoleScreenBufferInfo(hOut, &hOutInfo))
+ {
+ return;
+ }
+ {
+ HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
+ DuplicateHandle(GetCurrentProcess(), out,
+ GetCurrentProcess(), &out, 0, FALSE,
+ DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
+ SetStdHandle(STD_OUTPUT_HANDLE, out);
+ }
+ {
+ HANDLE out = GetStdHandle(STD_ERROR_HANDLE);
+ DuplicateHandle(GetCurrentProcess(), out,
+ GetCurrentProcess(), &out, 0, FALSE,
+ DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
+ SetStdHandle(STD_ERROR_HANDLE, out);
+ }
+#endif
+}
+
+//----------------------------------------------------------------------------
+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);
+ cmSystemToolsWindowsHandle hTo =
+ CreateFile(toFile, GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
+ if(!hFrom || !hTo)
+ {
+ return false;
+ }
+ FILETIME timeCreation;
+ FILETIME timeLastAccess;
+ FILETIME timeLastWrite;
+ if(!GetFileTime(hFrom, &timeCreation, &timeLastAccess, &timeLastWrite))
+ {
+ return false;
+ }
+ if(!SetFileTime(hTo, &timeCreation, &timeLastAccess, &timeLastWrite))
+ {
+ return false;
+ }
+#else
+ struct stat fromStat;
+ if(stat(fromFile, &fromStat) < 0)
+ {
+ return false;
+ }
+
+ struct utimbuf buf;
+ buf.actime = fromStat.st_atime;
+ buf.modtime = fromStat.st_mtime;
+ if(utime(toFile, &buf) < 0)
+ {
+ return false;
+ }
+#endif
+ return true;
+}
+
+//----------------------------------------------------------------------------
+cmSystemToolsFileTime* cmSystemTools::FileTimeNew()
+{
+ return new cmSystemToolsFileTime;
+}
+
+//----------------------------------------------------------------------------
+void cmSystemTools::FileTimeDelete(cmSystemToolsFileTime* t)
+{
+ delete t;
+}
+
+//----------------------------------------------------------------------------
+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);
+ if(!h)
+ {
+ return false;
+ }
+ if(!GetFileTime(h, &t->timeCreation, &t->timeLastAccess, &t->timeLastWrite))
+ {
+ return false;
+ }
+#else
+ struct stat st;
+ if(stat(fname, &st) < 0)
+ {
+ return false;
+ }
+ t->timeBuf.actime = st.st_atime;
+ t->timeBuf.modtime = st.st_mtime;
+#endif
+ return true;
+}
+
+//----------------------------------------------------------------------------
+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);
+ if(!h)
+ {
+ return false;
+ }
+ if(!SetFileTime(h, &t->timeCreation, &t->timeLastAccess, &t->timeLastWrite))
+ {
+ return false;
+ }
+#else
+ if(utime(fname, &t->timeBuf) < 0)
+ {
+ return false;
+ }
+#endif
+ return true;
+}
+
+//----------------------------------------------------------------------------
+#ifdef _WIN32
+# ifndef CRYPT_SILENT
+# define CRYPT_SILENT 0x40 /* Not defined by VS 6 version of header. */
+# endif
+static int WinCryptRandom(void* data, size_t size)
+{
+ int result = 0;
+ HCRYPTPROV hProvider = 0;
+ if(CryptAcquireContextW(&hProvider, 0, 0, PROV_RSA_FULL,
+ CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
+ {
+ result = CryptGenRandom(hProvider, (DWORD)size, (BYTE*)data)? 1:0;
+ CryptReleaseContext(hProvider, 0);
+ }
+ return result;
+}
+#endif
+
+//----------------------------------------------------------------------------
+unsigned int cmSystemTools::RandomSeed()
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ unsigned int seed = 0;
+
+ // Try using a real random source.
+ if(WinCryptRandom(&seed, sizeof(seed)))
+ {
+ return seed;
+ }
+
+ // Fall back to the time and pid.
+ FILETIME ft;
+ GetSystemTimeAsFileTime(&ft);
+ unsigned int t1 = static_cast<unsigned int>(ft.dwHighDateTime);
+ unsigned int t2 = static_cast<unsigned int>(ft.dwLowDateTime);
+ unsigned int pid = static_cast<unsigned int>(GetCurrentProcessId());
+ return t1 ^ t2 ^ pid;
+#else
+ union
+ {
+ unsigned int integer;
+ char bytes[sizeof(unsigned int)];
+ } seed;
+
+ // Try using a real random source.
+ std::ifstream fin("/dev/urandom");
+ if(fin && fin.read(seed.bytes, sizeof(seed)) &&
+ fin.gcount() == sizeof(seed))
+ {
+ return seed.integer;
+ }
+
+ // Fall back to the time and pid.
+ struct timeval t;
+ gettimeofday(&t, 0);
+ unsigned int pid = static_cast<unsigned int>(getpid());
+ unsigned int tv_sec = static_cast<unsigned int>(t.tv_sec);
+ unsigned int tv_usec = static_cast<unsigned int>(t.tv_usec);
+ // Since tv_usec never fills more than 11 bits we shift it to fill
+ // in the slow-changing high-order bits of tv_sec.
+ return tv_sec ^ (tv_usec << 21) ^ pid;
+#endif
+}
+
+//----------------------------------------------------------------------------
+static std::string cmSystemToolsExecutableDirectory;
+void cmSystemTools::FindExecutableDirectory(const char* argv0)
+{
+#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;
+#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());
+ }
+ else
+ {
+ // ???
+ }
+#endif
+}
+
+//----------------------------------------------------------------------------
+const char* cmSystemTools::GetExecutableDirectory()
+{
+ return cmSystemToolsExecutableDirectory.c_str();
+}
+
+//----------------------------------------------------------------------------
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+void cmSystemTools::MakefileColorEcho(int color, const char* message,
+ bool newline, bool enabled)
+{
+ // On some platforms (an MSYS prompt) cmsysTerminal may not be able
+ // to determine whether the stream is displayed on a tty. In this
+ // case it assumes no unless we tell it otherwise. Since we want
+ // color messages to be displayed for users we will assume yes.
+ // However, we can test for some situations when the answer is most
+ // likely no.
+ int assumeTTY = cmsysTerminal_Color_AssumeTTY;
+ if(cmSystemTools::GetEnv("DART_TEST_FROM_DART") ||
+ cmSystemTools::GetEnv("DASHBOARD_TEST_FROM_CTEST") ||
+ cmSystemTools::GetEnv("CTEST_INTERACTIVE_DEBUG_MODE"))
+ {
+ // Avoid printing color escapes during dashboard builds.
+ assumeTTY = 0;
+ }
+
+ if(enabled)
+ {
+ cmsysTerminal_cfprintf(color | assumeTTY, stdout, "%s%s",
+ message, newline? "\n" : "");
+ }
+ else
+ {
+ // Color is disabled. Print without color.
+ fprintf(stdout, "%s%s", message, newline? "\n" : "");
+ }
+}
+#endif
+
+//----------------------------------------------------------------------------
+bool cmSystemTools::GuessLibrarySOName(std::string const& fullPath,
+ std::string& soname)
+{
+ // For ELF shared libraries use a real parser to get the correct
+ // soname.
+#if defined(CMAKE_USE_ELF_PARSER)
+ cmELF elf(fullPath.c_str());
+ if(elf)
+ {
+ return elf.GetSOName(soname);
+ }
+#endif
+
+ // If the file is not a symlink we have no guess for its soname.
+ if(!cmSystemTools::FileIsSymlink(fullPath.c_str()))
+ {
+ return false;
+ }
+ if(!cmSystemTools::ReadSymlink(fullPath.c_str(), soname))
+ {
+ return false;
+ }
+
+ // If the symlink has a path component we have no guess for the soname.
+ if(!cmSystemTools::GetFilenamePath(soname).empty())
+ {
+ return false;
+ }
+
+ // If the symlink points at an extended version of the same name
+ // assume it is the soname.
+ std::string name = cmSystemTools::GetFilenameName(fullPath);
+ if(soname.length() > name.length() &&
+ soname.substr(0, name.length()) == name)
+ {
+ return true;
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+#if defined(CMAKE_USE_ELF_PARSER)
+std::string::size_type cmSystemToolsFindRPath(std::string const& have,
+ std::string const& want)
+{
+ // Search for the desired rpath.
+ std::string::size_type pos = have.find(want);
+
+ // If the path is not present we are done.
+ if(pos == std::string::npos)
+ {
+ return pos;
+ }
+
+ // Build a regex to match a properly separated path instance.
+ std::string regex_str = "(^|:)(";
+ for(std::string::const_iterator i = want.begin(); i != want.end(); ++i)
+ {
+ int ch = *i;
+ if(!(('a' <= ch && ch <= 'z') ||
+ ('A' <= ch && ch <= 'Z') ||
+ ('0' <= ch && ch <= '9')))
+ {
+ // Escape the non-alphanumeric character.
+ regex_str += "\\";
+ }
+ // Store the character.
+ regex_str.append(1, static_cast<char>(ch));
+ }
+ regex_str += ")(:|$)";
+
+ // Look for the separated path.
+ cmsys::RegularExpression regex(regex_str.c_str());
+ if(regex.find(have))
+ {
+ // Return the position of the path portion.
+ return regex.start(2);
+ }
+ else
+ {
+ // The desired rpath was not found.
+ return std::string::npos;
+ }
+}
+#endif
+
+#if defined(CMAKE_USE_ELF_PARSER)
+struct cmSystemToolsRPathInfo
+{
+ unsigned long Position;
+ unsigned long Size;
+ std::string Name;
+ std::string Value;
+};
+#endif
+
+//----------------------------------------------------------------------------
+bool cmSystemTools::ChangeRPath(std::string const& file,
+ std::string const& oldRPath,
+ std::string const& newRPath,
+ std::string* emsg,
+ bool* changed)
+{
+#if defined(CMAKE_USE_ELF_PARSER)
+ if(changed)
+ {
+ *changed = false;
+ }
+ int rp_count = 0;
+ cmSystemToolsRPathInfo rp[2];
+ {
+ // Parse the ELF binary.
+ cmELF elf(file.c_str());
+
+ // Get the RPATH and RUNPATH entries from it.
+ int se_count = 0;
+ cmELF::StringEntry const* se[2] = {0, 0};
+ const char* se_name[2] = {0, 0};
+ if(cmELF::StringEntry const* se_rpath = elf.GetRPath())
+ {
+ se[se_count] = se_rpath;
+ se_name[se_count] = "RPATH";
+ ++se_count;
+ }
+ if(cmELF::StringEntry const* se_runpath = elf.GetRunPath())
+ {
+ se[se_count] = se_runpath;
+ se_name[se_count] = "RUNPATH";
+ ++se_count;
+ }
+ if(se_count == 0)
+ {
+ if(newRPath.empty())
+ {
+ // The new rpath is empty and there is no rpath anyway so it is
+ // okay.
+ return true;
+ }
+ else
+ {
+ if(emsg)
+ {
+ *emsg = "No valid ELF RPATH or RUNPATH entry exists in the file; ";
+ *emsg += elf.GetErrorMessage();
+ }
+ return false;
+ }
+ }
+
+ for(int i=0; i < se_count; ++i)
+ {
+ // If both RPATH and RUNPATH refer to the same string literal it
+ // needs to be changed only once.
+ if(rp_count && rp[0].Position == se[i]->Position)
+ {
+ continue;
+ }
+
+ // Make sure the current rpath contains the old rpath.
+ std::string::size_type pos =
+ cmSystemToolsFindRPath(se[i]->Value, oldRPath);
+ if(pos == std::string::npos)
+ {
+ // If it contains the new rpath instead then it is okay.
+ if(cmSystemToolsFindRPath(se[i]->Value, newRPath) != std::string::npos)
+ {
+ continue;
+ }
+ if(emsg)
+ {
+ cmOStringStream e;
+ e << "The current " << se_name[i] << " is:\n"
+ << " " << se[i]->Value << "\n"
+ << "which does not contain:\n"
+ << " " << oldRPath << "\n"
+ << "as was expected.";
+ *emsg = e.str();
+ }
+ return false;
+ }
+
+ // Store information about the entry in the file.
+ rp[rp_count].Position = se[i]->Position;
+ rp[rp_count].Size = se[i]->Size;
+ rp[rp_count].Name = se_name[i];
+
+ // 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 += newRPath;
+ rp[rp_count].Value += se[i]->Value.substr(pos+oldRPath.length(),
+ oldRPath.npos);
+
+ // 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)
+ {
+ if(emsg)
+ {
+ *emsg = "The replacement path is too long for the ";
+ *emsg += se_name[i];
+ *emsg += " entry.";
+ }
+ return false;
+ }
+
+ // This entry is ready for update.
+ ++rp_count;
+ }
+ }
+
+ // If no runtime path needs to be changed, we are done.
+ if(rp_count == 0)
+ {
+ return true;
+ }
+
+ {
+ // Open the file for update.
+ std::ofstream f(file.c_str(),
+ std::ios::in | std::ios::out | std::ios::binary);
+ if(!f)
+ {
+ if(emsg)
+ {
+ *emsg = "Error opening file for update.";
+ }
+ return false;
+ }
+
+ // Store the new RPATH and RUNPATH strings.
+ for(int i=0; i < rp_count; ++i)
+ {
+ // Seek to the RPATH position.
+ if(!f.seekp(rp[i].Position))
+ {
+ if(emsg)
+ {
+ *emsg = "Error seeking to ";
+ *emsg += rp[i].Name;
+ *emsg += " position.";
+ }
+ return false;
+ }
+
+ // Write the new rpath. Follow it with enough null terminators to
+ // fill the string table entry.
+ f << rp[i].Value;
+ for(unsigned long j=rp[i].Value.length(); j < rp[i].Size; ++j)
+ {
+ f << '\0';
+ }
+
+ // Make sure it wrote correctly.
+ if(!f)
+ {
+ if(emsg)
+ {
+ *emsg = "Error writing the new ";
+ *emsg += rp[i].Name;
+ *emsg += " string to the file.";
+ }
+ return false;
+ }
+ }
+ }
+
+ // Everything was updated successfully.
+ if(changed)
+ {
+ *changed = true;
+ }
+ return true;
+#else
+ (void)file;
+ (void)oldRPath;
+ (void)newRPath;
+ (void)emsg;
+ (void)changed;
+ return false;
+#endif
+}
+
+//----------------------------------------------------------------------------
+bool cmSystemTools::VersionCompare(cmSystemTools::CompareOp op,
+ const char* lhss, const char* rhss)
+{
+ unsigned int lhs[4] = {0,0,0,0};
+ unsigned int rhs[4] = {0,0,0,0};
+ sscanf(lhss, "%u.%u.%u.%u", &lhs[0], &lhs[1], &lhs[2], &lhs[3]);
+ sscanf(rhss, "%u.%u.%u.%u", &rhs[0], &rhs[1], &rhs[2], &rhs[3]);
+
+ // Do component-wise comparison.
+ for(unsigned int i=0; i < 4; ++i)
+ {
+ if(lhs[i] < rhs[i])
+ {
+ // lhs < rhs, so true if operation is LESS
+ return op == cmSystemTools::OP_LESS;
+ }
+ else if(lhs[i] > rhs[i])
+ {
+ // lhs > rhs, so true if operation is GREATER
+ return op == cmSystemTools::OP_GREATER;
+ }
+ }
+ // lhs == rhs, so true if operation is EQUAL
+ return op == cmSystemTools::OP_EQUAL;
+}
+
+//----------------------------------------------------------------------------
+bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg,
+ bool* removed)
+{
+#if defined(CMAKE_USE_ELF_PARSER)
+ if(removed)
+ {
+ *removed = false;
+ }
+ int zeroCount = 0;
+ unsigned long zeroPosition[2] = {0,0};
+ unsigned long zeroSize[2] = {0,0};
+ unsigned long bytesBegin = 0;
+ std::vector<char> bytes;
+ {
+ // Parse the ELF binary.
+ cmELF elf(file.c_str());
+
+ // Get the RPATH and RUNPATH entries from it and sort them by index
+ // in the dynamic section header.
+ int se_count = 0;
+ cmELF::StringEntry const* se[2] = {0, 0};
+ if(cmELF::StringEntry const* se_rpath = elf.GetRPath())
+ {
+ se[se_count++] = se_rpath;
+ }
+ if(cmELF::StringEntry const* se_runpath = elf.GetRunPath())
+ {
+ se[se_count++] = se_runpath;
+ }
+ if(se_count == 0)
+ {
+ // There is no RPATH or RUNPATH anyway.
+ return true;
+ }
+ if(se_count == 2 && se[1]->IndexInSection < se[0]->IndexInSection)
+ {
+ cmsys_stl::swap(se[0], se[1]);
+ }
+
+ // Get the size of the dynamic section header.
+ unsigned int count = elf.GetDynamicEntryCount();
+ if(count == 0)
+ {
+ // This should happen only for invalid ELF files where a DT_NULL
+ // appears before the end of the table.
+ if(emsg)
+ {
+ *emsg = "DYNAMIC section contains a DT_NULL before the end.";
+ }
+ return false;
+ }
+
+ // Save information about the string entries to be zeroed.
+ zeroCount = se_count;
+ for(int i=0; i < se_count; ++i)
+ {
+ zeroPosition[i] = se[i]->Position;
+ zeroSize[i] = se[i]->Size;
+ }
+
+ // Get the range of file positions corresponding to each entry and
+ // the rest of the table after them.
+ unsigned long entryBegin[3] = {0,0,0};
+ unsigned long entryEnd[2] = {0,0};
+ for(int i=0; i < se_count; ++i)
+ {
+ entryBegin[i] = elf.GetDynamicEntryPosition(se[i]->IndexInSection);
+ entryEnd[i] = elf.GetDynamicEntryPosition(se[i]->IndexInSection+1);
+ }
+ entryBegin[se_count] = elf.GetDynamicEntryPosition(count);
+
+ // The data are to be written over the old table entries starting at
+ // the first one being removed.
+ bytesBegin = entryBegin[0];
+ unsigned long bytesEnd = entryBegin[se_count];
+
+ // Allocate a buffer to hold the part of the file to be written.
+ // Initialize it with zeros.
+ bytes.resize(bytesEnd - bytesBegin, 0);
+
+ // Read the part of the DYNAMIC section header that will move.
+ // The remainder of the buffer will be left with zeros which
+ // represent a DT_NULL entry.
+ char* data = &bytes[0];
+ for(int i=0; i < se_count; ++i)
+ {
+ // Read data between the entries being removed.
+ unsigned long sz = entryBegin[i+1] - entryEnd[i];
+ if(sz > 0 && !elf.ReadBytes(entryEnd[i], sz, data))
+ {
+ if(emsg)
+ {
+ *emsg = "Failed to read DYNAMIC section header.";
+ }
+ return false;
+ }
+ data += sz;
+ }
+ }
+
+ // Open the file for update.
+ std::ofstream f(file.c_str(),
+ std::ios::in | std::ios::out | std::ios::binary);
+ if(!f)
+ {
+ if(emsg)
+ {
+ *emsg = "Error opening file for update.";
+ }
+ return false;
+ }
+
+ // Write the new DYNAMIC table header.
+ if(!f.seekp(bytesBegin))
+ {
+ if(emsg)
+ {
+ *emsg = "Error seeking to DYNAMIC table header for RPATH.";
+ }
+ return false;
+ }
+ if(!f.write(&bytes[0], bytes.size()))
+ {
+ if(emsg)
+ {
+ *emsg = "Error replacing DYNAMIC table header.";
+ }
+ return false;
+ }
+
+ // Fill the RPATH and RUNPATH strings with zero bytes.
+ for(int i=0; i < zeroCount; ++i)
+ {
+ if(!f.seekp(zeroPosition[i]))
+ {
+ if(emsg)
+ {
+ *emsg = "Error seeking to RPATH position.";
+ }
+ return false;
+ }
+ for(unsigned long j=0; j < zeroSize[i]; ++j)
+ {
+ f << '\0';
+ }
+ if(!f)
+ {
+ if(emsg)
+ {
+ *emsg = "Error writing the empty rpath string to the file.";
+ }
+ return false;
+ }
+ }
+
+ // Everything was updated successfully.
+ if(removed)
+ {
+ *removed = true;
+ }
+ return true;
+#else
+ (void)file;
+ (void)emsg;
+ (void)removed;
+ return false;
+#endif
+}
+
+//----------------------------------------------------------------------------
+bool cmSystemTools::CheckRPath(std::string const& file,
+ std::string const& newRPath)
+{
+#if defined(CMAKE_USE_ELF_PARSER)
+ // Parse the ELF binary.
+ cmELF elf(file.c_str());
+
+ // Get the RPATH or RUNPATH entry from it.
+ cmELF::StringEntry const* se = elf.GetRPath();
+ if(!se)
+ {
+ se = elf.GetRunPath();
+ }
+
+ // Make sure the current rpath contains the new rpath.
+ if(newRPath.empty())
+ {
+ if(!se)
+ {
+ return true;
+ }
+ }
+ else
+ {
+ if(se &&
+ cmSystemToolsFindRPath(se->Value, newRPath) != std::string::npos)
+ {
+ return true;
+ }
+ }
+ return false;
+#else
+ (void)file;
+ (void)newRPath;
+ return false;
+#endif
+}
+
+//----------------------------------------------------------------------------
+bool cmSystemTools::RepeatedRemoveDirectory(const char* dir)
+{
+ // Windows sometimes locks files temporarily so try a few times.
+ for(int i = 0; i < 10; ++i)
+ {
+ if(cmSystemTools::RemoveADirectory(dir))
+ {
+ return true;
+ }
+ cmSystemTools::Delay(100);
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+std::vector<std::string> cmSystemTools::tokenize(const std::string& str,
+ const std::string& sep)
+{
+ std::vector<std::string> tokens;
+ std::string::size_type tokend = 0;
+
+ do
+ {
+ std::string::size_type tokstart=str.find_first_not_of(sep, tokend);
+ if (tokstart==std::string::npos)
+ {
+ break; // no more tokens
+ }
+ tokend=str.find_first_of(sep,tokstart);
+ if (tokend==std::string::npos)
+ {
+ tokens.push_back(str.substr(tokstart));
+ }
+ else
+ {
+ tokens.push_back(str.substr(tokstart,tokend-tokstart));
+ }
+ } while (tokend!=std::string::npos);
+
+ if (tokens.empty())
+ {
+ tokens.push_back("");
+ }
+ return tokens;
+}
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
new file mode 100644
index 000000000..69673c938
--- /dev/null
+++ b/Source/cmSystemTools.h
@@ -0,0 +1,480 @@
+/*============================================================================
+ 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 cmSystemTools_h
+#define cmSystemTools_h
+
+#include "cmStandardIncludes.h"
+
+#include <cmsys/SystemTools.hxx>
+#include <cmsys/Process.h>
+
+class cmSystemToolsFileTime;
+
+/** \class cmSystemTools
+ * \brief A collection of useful functions for CMake.
+ *
+ * cmSystemTools is a class that provides helper functions
+ * for the CMake build system.
+ */
+class cmSystemTools: public cmsys::SystemTools
+{
+public:
+ typedef cmsys::SystemTools Superclass;
+
+ /** Expand out any arguments in the vector that have ; separated
+ * strings into multiple arguments. A new vector is created
+ * containing the expanded versions of all arguments in argsIn.
+ */
+ static void ExpandList(std::vector<std::string> const& argsIn,
+ std::vector<std::string>& argsOut);
+ static void ExpandListArgument(const std::string& arg,
+ std::vector<std::string>& argsOut,
+ bool emptyArgs=false);
+
+ /**
+ * Look for and replace registry values in a string
+ */
+ static void ExpandRegistryValues(std::string& source,
+ KeyWOW64 view = KeyWOW64_Default);
+
+ ///! Escape quotes in a string.
+ static std::string EscapeQuotes(const char* str);
+
+ /**
+ * 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*);
+ /**
+ * Set the function used by GUI's 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);
+
+ /**
+ * Display an error message.
+ */
+ static void Error(const char* m, const char* m2=0,
+ const char* m3=0, const char* m4=0);
+
+ /**
+ * Display a message.
+ */
+ static void Message(const char* m, const char* title=0);
+
+ ///! 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);
+
+ ///! Send a string to stderr. Stdout callbacks will not be invoced.
+ static void Stderr(const char* s, int length);
+
+
+ typedef bool (*InterruptCallback)(void*);
+ static void SetInterruptCallback(InterruptCallback f, void* clientData=0);
+ static bool GetInterruptFlag();
+
+ ///! Return true if there was an error at any point.
+ static bool GetErrorOccuredFlag()
+ {
+ return cmSystemTools::s_ErrorOccured ||
+ cmSystemTools::s_FatalErrorOccured;
+ }
+ ///! If this is set to true, cmake stops processing commands.
+ static void SetFatalErrorOccured()
+ {
+ cmSystemTools::s_FatalErrorOccured = true;
+ }
+ static void SetErrorOccured()
+ {
+ cmSystemTools::s_ErrorOccured = true;
+ }
+ ///! Return true if there was an error at any point.
+ static bool GetFatalErrorOccured()
+ {
+ return cmSystemTools::s_FatalErrorOccured || GetInterruptFlag();
+ }
+
+ ///! Set the error occured flag and fatal error back to false
+ static void ResetErrorOccuredFlag()
+ {
+ cmSystemTools::s_FatalErrorOccured = false;
+ cmSystemTools::s_ErrorOccured = false;
+ }
+
+ /**
+ * Does a string indicates that CMake/CPack/CTest internally
+ * forced this value. This is not the same as On, but this
+ * may be considered as "internally switched on".
+ */
+ static bool IsInternallyOn(const char* val);
+ /**
+ * does a string indicate a true or on value ? This is not the same
+ * as ifdef.
+ */
+ static bool IsOn(const char* val);
+
+ /**
+ * does a string indicate a false or off value ? Note that this is
+ * not the same as !IsOn(...) because there are a number of
+ * ambiguous values such as "/usr/local/bin" a path will result in
+ * IsON and IsOff both returning false. Note that the special path
+ * NOTFOUND, *-NOTFOUND or IGNORE will cause IsOff to return true.
+ */
+ static bool IsOff(const char* val);
+
+ ///! Return true if value is NOTFOUND or ends in -NOTFOUND.
+ static bool IsNOTFOUND(const char* value);
+ ///! Return true if the path is a framework
+ static bool IsPathToFramework(const char* value);
+
+ static bool DoesFileExistWithExtensions(
+ const char *name,
+ const std::vector<std::string>& sourceExts);
+
+ /**
+ * Check if the given file exists in one of the parent directory of the
+ * given file or directory and if it does, return the name of the file.
+ * Toplevel specifies the top-most directory to where it will look.
+ */
+ static std::string FileExistsInParentDirectories(const char* fname,
+ const char* directory, const char* toplevel);
+
+ static void Glob(const char *directory, const char *regexp,
+ std::vector<std::string>& files);
+ static void GlobDirs(const char *fullPath, std::vector<std::string>& files);
+
+ /**
+ * Try to find a list of files that match the "simple" globbing
+ * expression. At this point in time the globbing expressions have
+ * to be in form: /directory/partial_file_name*. The * character has
+ * to be at the end of the string and it does not support ?
+ * []... The optional argument type specifies what kind of files you
+ * 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,
+ int type = 0);
+
+ ///! Copy a file.
+ static bool cmCopyFile(const char* source, const char* destination);
+ static bool CopyFileIfDifferent(const char* source,
+ const char* destination);
+
+ /** Rename a file or directory within a single disk volume (atomic
+ if possible). */
+ static bool RenameFile(const char* oldname, const char* newname);
+
+ ///! Compute the md5sum of a file
+ static bool ComputeFileMD5(const char* source, char* md5out);
+
+ /** Compute the md5sum of a string. */
+ static std::string ComputeStringMD5(const char* input);
+
+ /**
+ * 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
+ * it was received.
+ *
+ * If timeout is specified, the command will be terminated after
+ * timeout expires. Timeout is specified in seconds.
+ *
+ * Argument retVal should be a pointer to the location where the
+ * exit code will be stored. If the retVal is not specified and
+ * the program exits with a code other than 0, then the this
+ * function will return false.
+ *
+ * If the command has spaces in the path the caller MUST call
+ * cmSystemTools::ConvertToRunCommandPath on the command before passing
+ * it into this function or it will not work. The command must be correctly
+ * escaped for this to with spaces.
+ */
+ enum OutputOption
+ {
+ OUTPUT_NONE = 0,
+ OUTPUT_MERGE,
+ OUTPUT_NORMAL
+ };
+ static bool RunSingleCommand(const char* command, std::string* output = 0,
+ int* retVal = 0, const char* dir = 0,
+ OutputOption outputflag = OUTPUT_MERGE,
+ double timeout = 0.0);
+ /**
+ * In this version of RunSingleCommand, command[0] should be
+ * 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,
+ int* retVal = 0, const char* dir = 0,
+ OutputOption outputflag = OUTPUT_MERGE,
+ double timeout = 0.0);
+
+ /**
+ * Parse arguments out of a single string command
+ */
+ static std::vector<cmStdString> ParseArguments(const char* command);
+
+ /** Parse arguments out of a windows command line string. */
+ static void ParseWindowsCommandLine(const char* command,
+ std::vector<std::string>& args);
+
+ /** 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; }
+ static void DisableRunCommandOutput() {s_DisableRunCommandOutput = true; }
+ static void EnableRunCommandOutput() {s_DisableRunCommandOutput = false; }
+ static bool GetRunCommandOutput() { return s_DisableRunCommandOutput; }
+
+ /**
+ * Come constants for different file formats.
+ */
+ enum FileFormat {
+ NO_FILE_FORMAT = 0,
+ C_FILE_FORMAT,
+ CXX_FILE_FORMAT,
+ FORTRAN_FILE_FORMAT,
+ JAVA_FILE_FORMAT,
+ HEADER_FILE_FORMAT,
+ RESOURCE_FILE_FORMAT,
+ DEFINITION_FILE_FORMAT,
+ STATIC_LIBRARY_FILE_FORMAT,
+ SHARED_LIBRARY_FILE_FORMAT,
+ MODULE_FILE_FORMAT,
+ OBJECT_FILE_FORMAT,
+ UNKNOWN_FILE_FORMAT
+ };
+
+ enum CompareOp {
+ OP_LESS,
+ OP_GREATER,
+ OP_EQUAL
+ };
+
+ /**
+ * Compare versions
+ */
+ static bool VersionCompare(CompareOp op, const char* lhs, const char* 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.
+ */
+ static void SetRunCommandHideConsole(bool v){s_RunCommandHideConsole = v;}
+ static bool GetRunCommandHideConsole(){ return s_RunCommandHideConsole;}
+ /** Call cmSystemTools::Error with the message m, plus the
+ * result of strerror(errno)
+ */
+ static void ReportLastSystemError(const char* m);
+
+ /** a general output handler for cmsysProcess */
+ static int WaitForLine(cmsysProcess* process, std::string& line,
+ double timeout,
+ std::vector<char>& out,
+ std::vector<char>& err);
+
+ /** 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 void SetForceUnixPaths(bool v)
+ {
+ s_ForceUnixPaths = v;
+ }
+ static bool GetForceUnixPaths()
+ {
+ return s_ForceUnixPaths;
+ }
+
+ // ConvertToOutputPath use s_ForceUnixPaths
+ static std::string ConvertToOutputPath(const char* path);
+ static void ConvertToOutputSlashes(std::string& path);
+
+ // ConvertToRunCommandPath does not use s_ForceUnixPaths and should
+ // 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.
+ 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 std::string RelativePath(const char* local, const char* remote);
+
+#ifdef CMAKE_BUILD_WITH_CMAKE
+ /** Remove an environment variable */
+ static bool UnsetEnv(const char* value);
+
+ /** Get the list of all environment variables */
+ static std::vector<std::string> GetEnvironmentVariables();
+
+ /** Append multiple variables to the current environment. */
+ static void AppendEnv(std::vector<std::string> const& env);
+
+ /** Helper class to save and restore the environment.
+ Instantiate this class as an automatic variable on
+ the stack. Its constructor saves a copy of the current
+ environment and then its destructor restores the
+ original environment. */
+ class SaveRestoreEnvironment
+ {
+ public:
+ SaveRestoreEnvironment();
+ virtual ~SaveRestoreEnvironment();
+ private:
+ std::vector<std::string> Env;
+ };
+#endif
+
+ /** Setup the environment to enable VS 8 IDE output. */
+ static void EnableVSConsoleOutput();
+
+ /** Create tar */
+ static bool ListTar(const char* outFileName,
+ bool gzip, 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);
+ // 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
+ // if you want to be able to kill child processes and
+ // not get stuck waiting for all the output on the pipes.
+ static void DoNotInheritStdPipes();
+
+ /** Copy the file create/access/modify times from the file named by
+ the first argument to that named by the second. */
+ static bool CopyFileTime(const char* fromFile, const char* toFile);
+
+ /** Save and restore file times. */
+ static cmSystemToolsFileTime* FileTimeNew();
+ static void FileTimeDelete(cmSystemToolsFileTime*);
+ static bool FileTimeGet(const char* fname, cmSystemToolsFileTime* t);
+ static bool FileTimeSet(const char* fname, cmSystemToolsFileTime* t);
+
+ /** 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);
+
+ /** Get the directory containing the currently running executable. */
+ static const char* GetExecutableDirectory();
+
+#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,
+ std::string& soname);
+
+ /** Try to set the RPATH in an ELF binary. */
+ static bool ChangeRPath(std::string const& file,
+ std::string const& oldRPath,
+ std::string const& newRPath,
+ std::string* emsg = 0,
+ bool* changed = 0);
+
+ /** Try to remove the RPATH from an ELF binary. */
+ static bool RemoveRPath(std::string const& file, std::string* emsg = 0,
+ bool* removed = 0);
+
+ /** Check whether the RPATH in an ELF binary contains the path
+ given. */
+ static bool CheckRPath(std::string const& file,
+ std::string const& newRPath);
+
+ /** Remove a directory; repeat a few times in case of locked files. */
+ static bool RepeatedRemoveDirectory(const char* dir);
+
+ /** Tokenize a string */
+ static std::vector<std::string> tokenize(const std::string& str,
+ const std::string& sep);
+private:
+ static bool s_ForceUnixPaths;
+ static bool s_RunCommandHideConsole;
+ static bool s_ErrorOccured;
+ static bool s_FatalErrorOccured;
+ static bool s_DisableMessages;
+ static bool s_DisableRunCommandOutput;
+ static ErrorCallback s_ErrorCallback;
+ static StdoutCallback s_StdoutCallback;
+ static InterruptCallback s_InterruptCallback;
+ static void* s_ErrorCallbackClientData;
+ static void* s_StdoutCallbackClientData;
+ static void* s_InterruptCallbackClientData;
+
+ static std::string s_Windows9xComspecSubstitute;
+};
+
+#endif
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
new file mode 100644
index 000000000..775662cc3
--- /dev/null
+++ b/Source/cmTarget.cxx
@@ -0,0 +1,4825 @@
+/*============================================================================
+ 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 "cmTarget.h"
+#include "cmake.h"
+#include "cmMakefile.h"
+#include "cmSourceFile.h"
+#include "cmLocalGenerator.h"
+#include "cmGlobalGenerator.h"
+#include "cmComputeLinkInformation.h"
+#include "cmDocumentCompileDefinitions.h"
+#include "cmDocumentLocationUndefined.h"
+#include "cmListFileCache.h"
+#include "cmGeneratorExpression.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;
+};
+
+//----------------------------------------------------------------------------
+struct cmTarget::ImportInfo
+{
+ bool NoSOName;
+ std::string Location;
+ std::string SOName;
+ std::string ImportLibrary;
+ cmTarget::LinkInterface LinkInterface;
+};
+
+//----------------------------------------------------------------------------
+class cmTargetInternals
+{
+public:
+ cmTargetInternals()
+ {
+ this->SourceFileFlagsConstructed = false;
+ }
+ cmTargetInternals(cmTargetInternals const& r)
+ {
+ 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;
+ }
+ 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<cmStdString, OptionalLinkInterface> LinkInterfaceMapType;
+ LinkInterfaceMapType LinkInterfaceMap;
+
+ typedef std::map<cmStdString, cmTarget::OutputInfo> OutputInfoMapType;
+ OutputInfoMapType OutputInfoMap;
+
+ typedef std::map<cmStdString, cmTarget::ImportInfo> ImportInfoMapType;
+ ImportInfoMapType ImportInfoMap;
+
+ // Cache link implementation computation from each configuration.
+ typedef std::map<cmStdString, cmTarget::LinkImplementation> LinkImplMapType;
+ LinkImplMapType LinkImplMap;
+
+ typedef std::map<cmStdString, cmTarget::LinkClosure> LinkClosureMapType;
+ LinkClosureMapType LinkClosureMap;
+
+ struct SourceEntry { std::vector<cmSourceFile*> Depends; };
+ typedef std::map<cmSourceFile*, SourceEntry> SourceEntriesType;
+ SourceEntriesType SourceEntries;
+};
+
+//----------------------------------------------------------------------------
+cmTarget::cmTarget()
+{
+ this->Makefile = 0;
+ this->PolicyStatusCMP0003 = cmPolicies::WARN;
+ this->PolicyStatusCMP0004 = cmPolicies::WARN;
+ this->PolicyStatusCMP0008 = cmPolicies::WARN;
+ this->LinkLibrariesAnalyzed = false;
+ this->HaveInstallRule = false;
+ this->DLLPlatform = false;
+ this->IsApple = false;
+ this->IsImportedTarget = 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() macro. Currently Qt4 is 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.");
+
+ 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"
+ 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
+ ("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 our 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
+ ("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 "
+ "IMPORTED_LINK_INTERFACE_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.");
+
+ 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.");
+
+ 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
+ ("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.");
+
+ 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.");
+
+ 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_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.");
+
+ 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.");
+
+ 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
+ ("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
+ ("<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
+ ("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
+ ("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.");
+
+ 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 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.",
+ "An 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
+ ("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 "
+ "project or dsp file associated with this target.");
+
+ 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_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
+ ("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)
+{
+ this->Name = name;
+ // only add dependency information for library targets
+ this->TargetTypeValue = type;
+ if(this->TargetTypeValue >= STATIC_LIBRARY
+ && this->TargetTypeValue <= MODULE_LIBRARY)
+ {
+ this->RecordDependencies = true;
+ }
+ else
+ {
+ this->RecordDependencies = false;
+ }
+}
+
+//----------------------------------------------------------------------------
+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");
+
+ // Setup default property values.
+ this->SetPropertyDefault("INSTALL_NAME_DIR", "");
+ 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("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_INTERFACE_LIBRARIES", 0);
+ this->SetPropertyDefault("WIN32_EXECUTABLE", 0);
+ this->SetPropertyDefault("MACOSX_BUNDLE", 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_",
+ 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);
+ }
+
+ // 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);
+ }
+ }
+
+ // Save the backtrace of target construction.
+ this->Makefile->GetBacktrace(this->Internal->Backtrace);
+
+ // Initialize the INCLUDE_DIRECTORIES property based on the current value
+ // of the same directory property:
+ this->SetProperty("INCLUDE_DIRECTORIES",
+ this->Makefile->GetProperty("INCLUDE_DIRECTORIES"));
+
+ if(this->TargetTypeValue == cmTarget::SHARED_LIBRARY
+ || this->TargetTypeValue == cmTarget::MODULE_LIBRARY)
+ {
+ this->SetProperty("POSITION_INDEPENDENT_CODE", "True");
+ }
+ this->SetPropertyDefault("POSITION_INDEPENDENT_CODE", 0);
+
+ // Record current policies for later use.
+ this->PolicyStatusCMP0003 =
+ this->Makefile->GetPolicyStatus(cmPolicies::CMP0003);
+ this->PolicyStatusCMP0004 =
+ this->Makefile->GetPolicyStatus(cmPolicies::CMP0004);
+ this->PolicyStatusCMP0008 =
+ this->Makefile->GetPolicyStatus(cmPolicies::CMP0008);
+}
+
+//----------------------------------------------------------------------------
+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);
+}
+
+//----------------------------------------------------------------------------
+void cmTarget::ClearLinkMaps()
+{
+ this->Internal->LinkImplMap.clear();
+ this->Internal->LinkInterfaceMap.clear();
+ this->Internal->LinkClosureMap.clear();
+}
+
+//----------------------------------------------------------------------------
+cmListFileBacktrace const& cmTarget::GetBacktrace() const
+{
+ return this->Internal->Backtrace;
+}
+
+//----------------------------------------------------------------------------
+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;
+}
+
+//----------------------------------------------------------------------------
+bool cmTarget::IsExecutableWithExports()
+{
+ return (this->GetType() == cmTarget::EXECUTABLE &&
+ this->GetPropertyAsBool("ENABLE_EXPORTS"));
+}
+
+//----------------------------------------------------------------------------
+bool cmTarget::IsLinkable()
+{
+ return (this->GetType() == cmTarget::STATIC_LIBRARY ||
+ this->GetType() == cmTarget::SHARED_LIBRARY ||
+ this->GetType() == cmTarget::MODULE_LIBRARY ||
+ this->GetType() == cmTarget::UNKNOWN_LIBRARY ||
+ this->IsExecutableWithExports());
+}
+
+//----------------------------------------------------------------------------
+bool cmTarget::HasImportLibrary()
+{
+ return (this->DLLPlatform &&
+ (this->GetType() == cmTarget::SHARED_LIBRARY ||
+ this->IsExecutableWithExports()));
+}
+
+//----------------------------------------------------------------------------
+bool cmTarget::IsFrameworkOnApple()
+{
+ return (this->GetType() == cmTarget::SHARED_LIBRARY &&
+ this->Makefile->IsOn("APPLE") &&
+ this->GetPropertyAsBool("FRAMEWORK"));
+}
+
+//----------------------------------------------------------------------------
+bool cmTarget::IsAppBundleOnApple()
+{
+ return (this->GetType() == cmTarget::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"));
+}
+
+//----------------------------------------------------------------------------
+class cmTargetTraceDependencies
+{
+public:
+ cmTargetTraceDependencies(cmTarget* target, cmTargetInternals* internal,
+ const char* vsProjectFile);
+ 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,
+ const char* vsProjectFile):
+ 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 the VS project file to check dependencies on the rule to
+ // generate it.
+ if(vsProjectFile)
+ {
+ this->FollowName(vsProjectFile);
+ }
+
+ // 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)
+{
+ if(this->SourcesQueued.insert(sf).second)
+ {
+ this->SourceQueue.push(sf);
+
+ // Make sure this file is in the target.
+ this->Target->AddSourceFile(sf);
+ }
+}
+
+//----------------------------------------------------------------------------
+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)
+{
+ // 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(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(t->GetType() >= cmTarget::EXECUTABLE &&
+ t->GetType() <= cmTarget::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->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)
+ {
+ this->Target->AddUtility(util.c_str());
+ return true;
+ }
+ }
+ }
+ 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;
+ }
+ }
+
+ // The dependency does not name a target built in this project.
+ return false;
+}
+
+//----------------------------------------------------------------------------
+void
+cmTargetTraceDependencies
+::CheckCustomCommand(cmCustomCommand const& cc)
+{
+ // Transform command names that reference targets built in this
+ // project to corresponding target-level dependencies.
+ cmGeneratorExpression ge(this->Makefile, 0, cc.GetBacktrace(), true);
+ for(cmCustomCommandLines::const_iterator cit = cc.GetCommandLines().begin();
+ cit != cc.GetCommandLines().end(); ++cit)
+ {
+ std::string const& command = *cit->begin();
+ // Check for a target with this name.
+ if(cmTarget* t = this->Makefile->FindTargetToUse(command.c_str()))
+ {
+ 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());
+ }
+ }
+
+ // Check for target references in generator expressions.
+ for(cmCustomCommandLine::const_iterator cli = cit->begin();
+ cli != cit->end(); ++cli)
+ {
+ ge.Process(*cli);
+ }
+ }
+
+ // Add target-level dependencies referenced by generator expressions.
+ std::set<cmTarget*> targets = ge.GetTargets();
+ 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);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+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 cmTarget::TraceDependencies(const char* vsProjectFile)
+{
+ // 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(), vsProjectFile);
+ tracer.Trace();
+}
+
+//----------------------------------------------------------------------------
+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;
+}
+
+//----------------------------------------------------------------------------
+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);
+ }
+}
+
+//----------------------------------------------------------------------------
+std::vector<cmSourceFile*> const*
+cmTarget::GetSourceDepends(cmSourceFile* sf)
+{
+ typedef cmTargetInternals::SourceEntriesType SourceEntriesType;
+ SourceEntriesType::iterator i = this->Internal->SourceEntries.find(sf);
+ if(i != this->Internal->SourceEntries.end())
+ {
+ return &i->second.Depends;
+ }
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+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);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+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);
+
+ cmSourceFile* sf = this->Makefile->GetOrCreateSource(src.c_str());
+ this->AddSourceFile(sf);
+ return sf;
+}
+
+//----------------------------------------------------------------------------
+void cmTarget::ProcessSourceExpression(std::string const& expr)
+{
+ 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());
+ }
+}
+
+//----------------------------------------------------------------------------
+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;
+}
+
+//----------------------------------------------------------------------------
+void cmTarget::ConstructSourceFileFlags()
+{
+ if(this->Internal->SourceFileFlagsConstructed)
+ {
+ return;
+ }
+ this->Internal->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->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;
+ }
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmTarget::MergeLinkLibraries( cmMakefile& mf,
+ const char *selfname,
+ const LinkLibraryVectorType& libs )
+{
+ // Only add on libraries we haven't added on before.
+ // Assumption: the global link libraries could only grow, never shrink
+ LinkLibraryVectorType::const_iterator i = libs.begin();
+ i += this->PrevLinkedLibraries.size();
+ for( ; i != libs.end(); ++i )
+ {
+ // We call this so that the dependencies get written to the cache
+ this->AddLinkLibrary( mf, selfname, i->first.c_str(), i->second );
+ }
+ this->PrevLinkedLibraries = libs;
+}
+
+//----------------------------------------------------------------------------
+void cmTarget::AddLinkDirectory(const char* d)
+{
+ // Make sure we don't add unnecessary search directories.
+ if(this->LinkDirectoriesEmmitted.insert(d).second)
+ {
+ this->LinkDirectories.push_back(d);
+ }
+}
+
+//----------------------------------------------------------------------------
+const std::vector<std::string>& cmTarget::GetLinkDirectories()
+{
+ 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 )
+{
+ // Clear the dependencies. The cache variable must exist iff we are
+ // recording dependency information for this target.
+ std::string depname = target;
+ depname += "_LIB_DEPENDS";
+ if (this->RecordDependencies)
+ {
+ mf.AddCacheDefinition(depname.c_str(), "",
+ "Dependencies for target", cmCacheManager::STATIC);
+ }
+ else
+ {
+ if (mf.GetDefinition( depname.c_str() ))
+ {
+ std::string message = "Target ";
+ message += target;
+ message += " has dependency information when it shouldn't.\n";
+ message += "Your cache is probably stale. Please remove the entry\n ";
+ message += depname;
+ message += "\nfrom the cache.";
+ cmSystemTools::Error( message.c_str() );
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmTarget::NameResolvesToFramework(const std::string& libname)
+{
+ return this->GetMakefile()->GetLocalGenerator()->GetGlobalGenerator()->
+ NameResolvesToFramework(libname);
+}
+
+//----------------------------------------------------------------------------
+bool cmTarget::AddFramework(const std::string& libname, LinkLibraryType llt)
+{
+ (void)llt; // TODO: What is this?
+ if(this->NameResolvesToFramework(libname.c_str()))
+ {
+ std::string frameworkDir = libname;
+ frameworkDir += "/../";
+ frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir.c_str());
+ std::vector<std::string>::iterator i =
+ std::find(this->Frameworks.begin(),
+ this->Frameworks.end(), frameworkDir);
+ if(i == this->Frameworks.end())
+ {
+ this->Frameworks.push_back(frameworkDir);
+ }
+ return true;
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+void cmTarget::AddLinkLibrary(cmMakefile& mf,
+ const char *target, const char* lib,
+ LinkLibraryType llt)
+{
+ // Never add a self dependency, even if the user asks for it.
+ if(strcmp( target, lib ) == 0)
+ {
+ return;
+ }
+ this->AddFramework(lib, llt);
+ cmTarget::LibraryID tmp;
+ tmp.first = lib;
+ tmp.second = llt;
+ this->LinkLibraries.push_back( tmp );
+ 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
+ // be a trailing ";". These library names are not canonical, in that
+ // they may be "-framework x", "-ly", "/path/libz.a", etc.
+ // We shouldn't remove duplicates here because external libraries
+ // may be purposefully duplicated to handle recursive dependencies,
+ // and we removing one instance will break the link line. Duplicates
+ // will be appropriately eliminated at emit time.
+ if(this->RecordDependencies)
+ {
+ std::string targetEntry = target;
+ targetEntry += "_LIB_DEPENDS";
+ std::string dependencies;
+ const char* old_val = mf.GetDefinition( targetEntry.c_str() );
+ if( old_val )
+ {
+ dependencies += old_val;
+ }
+ switch (llt)
+ {
+ case cmTarget::GENERAL:
+ dependencies += "general";
+ break;
+ case cmTarget::DEBUG:
+ dependencies += "debug";
+ break;
+ case cmTarget::OPTIMIZED:
+ dependencies += "optimized";
+ break;
+ }
+ dependencies += ";";
+ dependencies += lib;
+ dependencies += ";";
+ mf.AddCacheDefinition( targetEntry.c_str(), dependencies.c_str(),
+ "Dependencies for the target",
+ cmCacheManager::STATIC );
+ }
+
+}
+
+//----------------------------------------------------------------------------
+void
+cmTarget::AnalyzeLibDependencies( const cmMakefile& mf )
+{
+ // There are two key parts of the dependency analysis: (1)
+ // determining the libraries in the link line, and (2) constructing
+ // the dependency graph for those libraries.
+ //
+ // The latter is done using the cache entries that record the
+ // dependencies of each library.
+ //
+ // The former is a more thorny issue, since it is not clear how to
+ // determine if two libraries listed on the link line refer to the a
+ // single library or not. For example, consider the link "libraries"
+ // /usr/lib/libtiff.so -ltiff
+ // Is this one library or two? The solution implemented here is the
+ // simplest (and probably the only practical) one: two libraries are
+ // the same if their "link strings" are identical. Thus, the two
+ // libraries above are considered distinct. This also means that for
+ // dependency analysis to be effective, the CMake user must specify
+ // libraries build by his project without using any linker flags or
+ // file extensions. That is,
+ // LINK_LIBRARIES( One Two )
+ // instead of
+ // LINK_LIBRARIES( -lOne ${binarypath}/libTwo.a )
+ // The former is probably what most users would do, but it never
+ // hurts to document the assumptions. :-) Therefore, in the analysis
+ // code, the "canonical name" of a library is simply its name as
+ // given to a LINK_LIBRARIES command.
+ //
+ // Also, we will leave the original link line intact; we will just add any
+ // dependencies that were missing.
+ //
+ // There is a problem with recursive external libraries
+ // (i.e. libraries with no dependency information that are
+ // recursively dependent). We must make sure that the we emit one of
+ // the libraries twice to satisfy the recursion, but we shouldn't
+ // emit it more times than necessary. In particular, we must make
+ // sure that handling this improbable case doesn't cost us when
+ // dealing with the common case of non-recursive libraries. The
+ // solution is to assume that the recursion is satisfied at one node
+ // of the dependency tree. To illustrate, assume libA and libB are
+ // extrenal and mutually dependent. Suppose libX depends on
+ // libA, and libY on libA and libX. Then
+ // TARGET_LINK_LIBRARIES( Y X A B A )
+ // TARGET_LINK_LIBRARIES( X A B A )
+ // TARGET_LINK_LIBRARIES( Exec Y )
+ // would result in "-lY -lX -lA -lB -lA". This is the correct way to
+ // specify the dependencies, since the mutual dependency of A and B
+ // is resolved *every time libA is specified*.
+ //
+ // Something like
+ // TARGET_LINK_LIBRARIES( Y X A B A )
+ // TARGET_LINK_LIBRARIES( X A B )
+ // TARGET_LINK_LIBRARIES( Exec Y )
+ // would result in "-lY -lX -lA -lB", and the mutual dependency
+ // information is lost. This is because in some case (Y), the mutual
+ // dependency of A and B is listed, while in another other case (X),
+ // it is not. Depending on which line actually emits A, the mutual
+ // dependency may or may not be on the final link line. We can't
+ // handle this pathalogical case cleanly without emitting extra
+ // libraries for the normal cases. Besides, the dependency
+ // information for X is wrong anyway: if we build an executable
+ // depending on X alone, we would not have the mutual dependency on
+ // A and B resolved.
+ //
+ // IMPROVEMENTS:
+ // -- The current algorithm will not always pick the "optimal" link line
+ // when recursive dependencies are present. It will instead break the
+ // cycles at an aribtrary point. The majority of projects won't have
+ // cyclic dependencies, so this is probably not a big deal. Note that
+ // the link line is always correct, just not necessary optimal.
+
+ {
+ // Expand variables in link library names. This is for backwards
+ // compatibility with very early CMake versions and should
+ // 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)
+ {
+ this->Makefile->ExpandVariablesInString(p->first, true, true);
+ }
+ }
+
+ typedef std::vector< std::string > LinkLine;
+
+ // The dependency map.
+ DependencyMap dep_map;
+
+ // 1. Build the dependency graph
+ //
+ for(LinkLibraryVectorType::reverse_iterator lib
+ = this->LinkLibraries.rbegin();
+ lib != this->LinkLibraries.rend(); ++lib)
+ {
+ this->GatherDependencies( 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 lib2 = lib;
+ lib2 != this->LinkLibraries.end(); ++lib2)
+ {
+ this->DeleteDependency( dep_map, *lib, *lib2);
+ }
+ }
+
+
+ // 3. Create the new link line by simply emitting any dependencies that are
+ // missing. Start from the back and keep adding.
+ //
+ std::set<DependencyMap::key_type> done, visited;
+ std::vector<DependencyMap::key_type> newLinkLibraries;
+ for(LinkLibraryVectorType::reverse_iterator lib =
+ this->LinkLibraries.rbegin();
+ lib != this->LinkLibraries.rend(); ++lib)
+ {
+ // skip zero size library entries, this may happen
+ // if a variable expands to nothing.
+ if (lib->first.size() != 0)
+ {
+ this->Emit( *lib, dep_map, done, visited, newLinkLibraries );
+ }
+ }
+
+ // 4. Add the new libraries to the link line.
+ //
+ for( std::vector<DependencyMap::key_type>::reverse_iterator k =
+ newLinkLibraries.rbegin();
+ k != newLinkLibraries.rend(); ++k )
+ {
+ // get the llt from the dep_map
+ this->LinkLibraries.push_back( std::make_pair(k->first,k->second) );
+ }
+ this->LinkLibrariesAnalyzed = true;
+}
+
+//----------------------------------------------------------------------------
+void cmTarget::InsertDependency( DependencyMap& depMap,
+ const LibraryID& lib,
+ const LibraryID& dep)
+{
+ depMap[lib].push_back(dep);
+}
+
+//----------------------------------------------------------------------------
+void cmTarget::DeleteDependency( 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
+ // external libraries that are specified multiple times.
+ DependencyMap::iterator map_itr = depMap.find( lib );
+ 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 );
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmTarget::Emit(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() )
+ {
+ return;
+ }
+
+ // Emit the dependencies only if this library node hasn't been
+ // visited before. If it has, then we have a cycle. The recursion
+ // that got us here should take care of everything.
+
+ if( visited.insert(lib).second )
+ {
+ if( dep_map.find(lib) != dep_map.end() ) // does it have dependencies?
+ {
+ const DependencyList& dep_on = dep_map.find( lib )->second;
+ DependencyList::const_reverse_iterator i;
+
+ // To cater for recursive external libraries, we must emit
+ // duplicates on this link line *unless* they were emitted by
+ // some other node, in which case we assume that the recursion
+ // was resolved then. We making the simplifying assumption that
+ // any duplicates on a single link line are on purpose, and must
+ // be preserved.
+
+ // This variable will keep track of the libraries that were
+ // emitted directory from the current node, and not from a
+ // recursive call. This way, if we come across a library that
+ // has already been emitted, we repeat it iff it has been
+ // emitted here.
+ std::set<DependencyMap::key_type> emitted_here;
+ for( i = dep_on.rbegin(); i != dep_on.rend(); ++i )
+ {
+ if( emitted_here.find(*i) != emitted_here.end() )
+ {
+ // a repeat. Must emit.
+ emitted.insert(*i);
+ link_line.push_back( *i );
+ }
+ else
+ {
+ // Emit only if no-one else has
+ if( emitted.find(*i) == emitted.end() )
+ {
+ // emit dependencies
+ Emit( *i, dep_map, emitted, visited, link_line );
+ // emit self
+ emitted.insert(*i);
+ emitted_here.insert(*i);
+ link_line.push_back( *i );
+ }
+ }
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmTarget::GatherDependencies( 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.
+ if( dep_map.find(lib) != dep_map.end() )
+ {
+ return;
+ }
+
+ const char* deps = mf.GetDefinition( (lib.first+"_LIB_DEPENDS").c_str() );
+ if( deps && strcmp(deps,"") != 0 )
+ {
+ // Make sure this library is in the map, even if it has an empty
+ // set of dependencies. This distinguishes the case of explicitly
+ // no dependencies with that of unspecified dependencies.
+ dep_map[lib];
+
+ // Parse the dependency information, which is a set of
+ // type, library pairs separated by ";". There is always a trailing ";".
+ cmTarget::LinkLibraryType llt = cmTarget::GENERAL;
+ std::string depline = deps;
+ std::string::size_type start = 0;
+ std::string::size_type end;
+ end = depline.find( ";", start );
+ while( end != std::string::npos )
+ {
+ std::string l = depline.substr( start, end-start );
+ if( l.size() != 0 )
+ {
+ if (l == "debug")
+ {
+ llt = cmTarget::DEBUG;
+ }
+ else if (l == "optimized")
+ {
+ llt = cmTarget::OPTIMIZED;
+ }
+ else if (l == "general")
+ {
+ llt = cmTarget::GENERAL;
+ }
+ else
+ {
+ LibraryID lib2(l,llt);
+ this->InsertDependency( dep_map, lib, lib2);
+ this->GatherDependencies( mf, lib2, dep_map);
+ llt = cmTarget::GENERAL;
+ }
+ }
+ start = end+1; // skip the ;
+ end = depline.find( ";", start );
+ }
+ // cannot depend on itself
+ this->DeleteDependency( dep_map, lib, lib);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmTarget::SetProperty(const char* prop, const char* value)
+{
+ if (!prop)
+ {
+ return;
+ }
+
+ this->Properties.SetProperty(prop, value, cmProperty::TARGET);
+ this->MaybeInvalidatePropertyCache(prop);
+}
+
+//----------------------------------------------------------------------------
+void cmTarget::AppendProperty(const char* prop, const char* value,
+ bool asString)
+{
+ if (!prop)
+ {
+ return;
+ }
+ this->Properties.AppendProperty(prop, value, cmProperty::TARGET, asString);
+ this->MaybeInvalidatePropertyCache(prop);
+}
+
+//----------------------------------------------------------------------------
+void cmTarget::MaybeInvalidatePropertyCache(const char* prop)
+{
+ // Wipe 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();
+ }
+}
+
+//----------------------------------------------------------------------------
+static void cmTargetCheckLINK_INTERFACE_LIBRARIES(
+ const char* prop, const char* value, cmMakefile* context, bool imported
+ )
+{
+ // Look for link-type keywords in the value.
+ static cmsys::RegularExpression
+ keys("(^|;)(debug|optimized|general)(;|$)");
+ if(!keys.find(value))
+ {
+ return;
+ }
+
+ // Support imported and non-imported versions of the property.
+ const char* base = (imported?
+ "IMPORTED_LINK_INTERFACE_LIBRARIES" :
+ "LINK_INTERFACE_LIBRARIES");
+
+ // Report an error.
+ cmOStringStream e;
+ e << "Property " << prop << " may not contain link-type keyword \""
+ << keys.match(2) << "\". "
+ << "The " << base << " property has a per-configuration "
+ << "version called " << base << "_<CONFIG> which may be "
+ << "used to specify per-configuration rules.";
+ if(!imported)
+ {
+ e << " "
+ << "Alternatively, an IMPORTED library may be created, configured "
+ << "with a per-configuration location, and then named in the "
+ << "property value. "
+ << "See the add_library command's IMPORTED mode for details."
+ << "\n"
+ << "If you have a list of libraries that already contains the "
+ << "keyword, use the target_link_libraries command with its "
+ << "LINK_INTERFACE_LIBRARIES mode to set the property. "
+ << "The command automatically recognizes link-type keywords and sets "
+ << "the LINK_INTERFACE_LIBRARIES and LINK_INTERFACE_LIBRARIES_DEBUG "
+ << "properties accordingly.";
+ }
+ context->IssueMessage(cmake::FATAL_ERROR, e.str());
+}
+
+//----------------------------------------------------------------------------
+void cmTarget::CheckProperty(const char* prop, cmMakefile* context)
+{
+ // Certain properties need checking.
+ if(strncmp(prop, "LINK_INTERFACE_LIBRARIES", 24) == 0)
+ {
+ if(const char* value = this->GetProperty(prop))
+ {
+ cmTargetCheckLINK_INTERFACE_LIBRARIES(prop, value, context, false);
+ }
+ }
+ if(strncmp(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES", 33) == 0)
+ {
+ if(const char* value = this->GetProperty(prop))
+ {
+ cmTargetCheckLINK_INTERFACE_LIBRARIES(prop, value, context, true);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmTarget::MarkAsImported()
+{
+ this->IsImportedTarget = true;
+}
+
+//----------------------------------------------------------------------------
+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);
+ 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 "";
+}
+
+//----------------------------------------------------------------------------
+const char* cmTarget::GetLocation(const char* config)
+{
+ 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();
+ if(!this->Location.empty())
+ {
+ this->Location += "/";
+ }
+ const char* cfgid = this->Makefile->GetDefinition("CMAKE_CFG_INTDIR");
+ if(cfgid && strcmp(cfgid, ".") != 0)
+ {
+ this->Location += cfgid;
+ this->Location += "/";
+ }
+ this->Location = this->BuildMacContentDirectory(this->Location, config);
+ 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))
+ {
+ // 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;
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+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);
+}
+
+//----------------------------------------------------------------------------
+const char *cmTarget::GetProperty(const char* prop)
+{
+ return this->GetProperty(prop, cmProperty::TARGET);
+}
+
+//----------------------------------------------------------------------------
+const char *cmTarget::GetProperty(const char* prop,
+ cmProperty::ScopeType scope)
+{
+ if(!prop)
+ {
+ return 0;
+ }
+
+ // 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(strcmp(prop,"LOCATION") == 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));
+ }
+
+ // Support "LOCATION_<CONFIG>".
+ if(strncmp(prop, "LOCATION_", 9) == 0)
+ {
+ std::string configName = prop+9;
+ this->SetProperty(prop, this->GetLocation(configName.c_str()));
+ }
+ else
+ {
+ // 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, len-9);
+ if(configName != "IMPORTED")
+ {
+ this->SetProperty(prop, this->GetLocation(configName.c_str()));
+ }
+ }
+ }
+ }
+
+ if (strcmp(prop,"IMPORTED") == 0)
+ {
+ return this->IsImported()?"TRUE":"FALSE";
+ }
+
+ if(!strcmp(prop,"SOURCES"))
+ {
+ cmOStringStream ss;
+ const char* sep = "";
+ for(std::vector<cmSourceFile*>::const_iterator
+ i = this->SourceFiles.begin();
+ i != this->SourceFiles.end(); ++i)
+ {
+ // 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())
+ {
+ sname += "/";
+ }
+ sname += location.GetName();
+
+ // Append this list entry.
+ ss << sname;
+ }
+ 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):
+ Config(config), Languages(languages) { this->Visited.insert(target); }
+ void Visit(cmTarget* target)
+ {
+ if(!target || !this->Visited.insert(target).second)
+ {
+ return;
+ }
+
+ cmTarget::LinkInterface const* iface =
+ target->GetLinkInterface(this->Config);
+ if(!iface) { return; }
+
+ for(std::vector<std::string>::const_iterator
+ li = iface->Languages.begin(); li != iface->Languages.end(); ++li)
+ {
+ this->Languages.insert(*li);
+ }
+
+ cmMakefile* mf = target->GetMakefile();
+ for(std::vector<std::string>::const_iterator
+ li = iface->Libraries.begin(); li != iface->Libraries.end(); ++li)
+ {
+ this->Visit(mf->FindTargetToUse(li->c_str()));
+ }
+ }
+private:
+ const char* Config;
+ std::set<cmStdString>& Languages;
+ std::set<cmTarget*> Visited;
+};
+
+//----------------------------------------------------------------------------
+const char* cmTarget::GetLinkerLanguage(const char* config)
+{
+ const char* lang = this->GetLinkClosure(config)->LinkerLanguage.c_str();
+ return *lang? lang : 0;
+}
+
+//----------------------------------------------------------------------------
+cmTarget::LinkClosure const* cmTarget::GetLinkClosure(const char* config)
+{
+ std::string key = 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);
+ 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)
+ {
+ this->Preference = preference;
+ this->Preferred.clear();
+ }
+ if(preference == this->Preference)
+ {
+ this->Preferred.insert(lang);
+ }
+ }
+ std::string Choose()
+ {
+ if(this->Preferred.empty())
+ {
+ return "";
+ }
+ else if(this->Preferred.size() > 1)
+ {
+ 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)
+ {
+ e << " " << *li << "\n";
+ }
+ 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)
+{
+ // Get languages built in this target.
+ std::set<cmStdString> languages;
+ LinkImplementation const* impl = this->GetLinkImplementation(config);
+ 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);
+ for(std::vector<std::string>::const_iterator li = impl->Libraries.begin();
+ li != impl->Libraries.end(); ++li)
+ {
+ cll.Visit(this->Makefile->FindTargetToUse(li->c_str()));
+ }
+
+ // Store the transitive closure of languages.
+ for(std::set<cmStdString>::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(std::set<cmStdString>::const_iterator sit = languages.begin();
+ sit != languages.end(); ++sit)
+ {
+ std::string propagates = "CMAKE_"+*sit+"_LINKER_PREFERENCE_PROPAGATES";
+ if(this->Makefile->IsOn(propagates.c_str()))
+ {
+ tsl.Consider(sit->c_str());
+ }
+ }
+
+ lc.LinkerLanguage = tsl.Choose();
+ }
+}
+
+//----------------------------------------------------------------------------
+const char* cmTarget::GetCreateRuleVariable()
+{
+ 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";
+ default:
+ break;
+ }
+ return "";
+}
+
+//----------------------------------------------------------------------------
+const char* cmTarget::GetSuffixVariableInternal(bool implib)
+{
+ switch(this->GetType())
+ {
+ case cmTarget::STATIC_LIBRARY:
+ return "CMAKE_STATIC_LIBRARY_SUFFIX";
+ case cmTarget::SHARED_LIBRARY:
+ return (implib
+ ? "CMAKE_IMPORT_LIBRARY_SUFFIX"
+ : "CMAKE_SHARED_LIBRARY_SUFFIX");
+ case cmTarget::MODULE_LIBRARY:
+ return (implib
+ ? "CMAKE_IMPORT_LIBRARY_SUFFIX"
+ : "CMAKE_SHARED_MODULE_SUFFIX");
+ case cmTarget::EXECUTABLE:
+ return (implib
+ ? "CMAKE_IMPORT_LIBRARY_SUFFIX"
+ : "CMAKE_EXECUTABLE_SUFFIX");
+ default:
+ break;
+ }
+ return "";
+}
+
+
+//----------------------------------------------------------------------------
+const char* cmTarget::GetPrefixVariableInternal(bool implib)
+{
+ switch(this->GetType())
+ {
+ case cmTarget::STATIC_LIBRARY:
+ return "CMAKE_STATIC_LIBRARY_PREFIX";
+ case cmTarget::SHARED_LIBRARY:
+ return (implib
+ ? "CMAKE_IMPORT_LIBRARY_PREFIX"
+ : "CMAKE_SHARED_LIBRARY_PREFIX");
+ case cmTarget::MODULE_LIBRARY:
+ return (implib
+ ? "CMAKE_IMPORT_LIBRARY_PREFIX"
+ : "CMAKE_SHARED_MODULE_PREFIX");
+ case cmTarget::EXECUTABLE:
+ return (implib? "CMAKE_IMPORT_LIBRARY_PREFIX" : "");
+ default:
+ break;
+ }
+ return "";
+}
+
+//----------------------------------------------------------------------------
+std::string cmTarget::GetPDBName(const char* config)
+{
+ std::string prefix;
+ std::string base;
+ std::string suffix;
+ this->GetFullNameInternal(config, false, prefix, base, suffix);
+ 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)));
+}
+
+//----------------------------------------------------------------------------
+std::string cmTarget::GetSOName(const char* config)
+{
+ if(this->IsImported())
+ {
+ // Lookup the imported soname.
+ if(cmTarget::ImportInfo const* info = this->GetImportInfo(config))
+ {
+ 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.
+ 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::IsImportedSharedLibWithoutSOName(const char* config)
+{
+ if(this->IsImported() && this->GetType() == cmTarget::SHARED_LIBRARY)
+ {
+ if(cmTarget::ImportInfo const* info = this->GetImportInfo(config))
+ {
+ 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->GetMacContentDirectory(config, implib);
+
+ // 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))
+ {
+ result = implib? info->ImportLibrary : info->Location;
+ }
+ if(result.empty())
+ {
+ result = this->GetName();
+ result += "-NOTFOUND";
+ }
+ return result;
+}
+
+//----------------------------------------------------------------------------
+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))
+ {
+ 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 do not have a prefix or a suffix
+ if(this->IsFrameworkOnApple())
+ {
+ targetPrefix = 0;
+ 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;
+
+ // 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 = prefix+base+".pdb";
+}
+
+//----------------------------------------------------------------------------
+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 = prefix+base+".pdb";
+}
+
+//----------------------------------------------------------------------------
+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 = dir;
+ 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,
+ 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()))
+ {
+ this->SetProperty(property, value);
+ }
+ else if(default_value)
+ {
+ this->SetProperty(property, default_value);
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmTarget::HaveBuildTreeRPATH()
+{
+ return (!this->GetPropertyAsBool("SKIP_BUILD_RPATH") &&
+ !this->LinkLibraries.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))
+ {
+ 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() || this->HaveInstallTreeRPATH();
+}
+
+//----------------------------------------------------------------------------
+std::string cmTarget::GetInstallNameDirForBuildTree(const char* config,
+ bool for_xcode)
+{
+ // 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(config, for_xcode);
+ }
+
+ // 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 = this->GetDirectory(config);
+ dir += "/";
+ if(this->IsFrameworkOnApple() && !for_xcode)
+ {
+ dir += this->GetFrameworkDirectory(config);
+ }
+ return dir;
+ }
+ else
+ {
+ return "";
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string cmTarget::GetInstallNameDirForInstallTree(const char* config,
+ bool for_xcode)
+{
+ if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
+ {
+ std::string dir;
+
+ if(!this->Makefile->IsOn("CMAKE_SKIP_RPATH") &&
+ !this->Makefile->IsOn("CMAKE_SKIP_INSTALL_RPATH"))
+ {
+ const char* install_name_dir = this->GetProperty("INSTALL_NAME_DIR");
+ if(install_name_dir && *install_name_dir)
+ {
+ dir = install_name_dir;
+ dir += "/";
+ }
+ }
+
+ if(this->IsFrameworkOnApple() && !for_xcode)
+ {
+ dir += this->GetFrameworkDirectory(config);
+ }
+
+ 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::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;
+ }
+}
+
+//----------------------------------------------------------------------------
+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);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmTarget::GetAppleArchs(const char* config,
+ std::vector<std::string>& archVec)
+{
+ const char* archs = 0;
+ if(config && *config)
+ {
+ std::string defVarName = "OSX_ARCHITECTURES_";
+ defVarName += cmSystemTools::UpperCase(config);
+ archs = this->GetProperty(defVarName.c_str());
+ }
+ if(!archs)
+ {
+ archs = this->GetProperty("OSX_ARCHITECTURES");
+ }
+ if(archs)
+ {
+ cmSystemTools::ExpandListArgument(std::string(archs), archVec);
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmTarget::IsChrpathUsed(const char* config)
+{
+#if defined(CMAKE_USE_ELF_PARSER)
+ // 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;
+ }
+
+ // Enable if the rpath flag uses a separator and the target uses ELF
+ // binaries.
+ if(const char* ll = this->GetLinkerLanguage(config))
+ {
+ 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)
+{
+ // 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";
+ }
+ typedef cmTargetInternals::ImportInfoMapType ImportInfoMapType;
+ ImportInfoMapType::const_iterator i =
+ this->Internal->ImportInfoMap.find(config_upper);
+ if(i == this->Internal->ImportInfoMap.end())
+ {
+ ImportInfo info;
+ this->ComputeImportInfo(config_upper, info);
+ ImportInfoMapType::value_type entry(config_upper, 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;
+}
+
+//----------------------------------------------------------------------------
+void cmTarget::ComputeImportInfo(std::string const& desired_config,
+ ImportInfo& info)
+{
+ // 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;
+
+ // Track the configuration-specific property suffix.
+ std::string suffix = "_";
+ suffix += desired_config;
+
+ // On a DLL platform there may be only IMPORTED_IMPLIB for a shared
+ // library or an executable with exports.
+ bool allowImp = this->HasImportLibrary();
+
+ // Look for a mapping from the current project's configuration to
+ // the imported project's configuration.
+ std::vector<std::string> mappedConfigs;
+ {
+ std::string mapProp = "MAP_IMPORTED_CONFIG_";
+ mapProp += desired_config;
+ if(const char* mapValue = this->GetProperty(mapProp.c_str()))
+ {
+ cmSystemTools::ExpandListArgument(mapValue, mappedConfigs);
+ }
+ }
+
+ // If a mapping was found, check its configurations.
+ const char* loc = 0;
+ const char* imp = 0;
+ for(std::vector<std::string>::const_iterator mci = mappedConfigs.begin();
+ !loc && !imp && mci != mappedConfigs.end(); ++mci)
+ {
+ // Look for this configuration.
+ std::string mcUpper = cmSystemTools::UpperCase(mci->c_str());
+ std::string locProp = "IMPORTED_LOCATION_";
+ locProp += mcUpper;
+ loc = this->GetProperty(locProp.c_str());
+ if(allowImp)
+ {
+ std::string impProp = "IMPORTED_IMPLIB_";
+ impProp += mcUpper;
+ imp = this->GetProperty(impProp.c_str());
+ }
+
+ // If it was found, use it for all properties below.
+ if(loc || imp)
+ {
+ suffix = "_";
+ suffix += mcUpper;
+ }
+ }
+
+ // If we needed to find one of the mapped configurations but did not
+ // then the target is not found. The project does not want any
+ // other configuration.
+ if(!mappedConfigs.empty() && !loc && !imp)
+ {
+ return;
+ }
+
+ // If we have not yet found it then there are no mapped
+ // configurations. Look for an exact-match.
+ if(!loc && !imp)
+ {
+ std::string locProp = "IMPORTED_LOCATION";
+ locProp += suffix;
+ loc = this->GetProperty(locProp.c_str());
+ if(allowImp)
+ {
+ std::string impProp = "IMPORTED_IMPLIB";
+ impProp += suffix;
+ imp = this->GetProperty(impProp.c_str());
+ }
+ }
+
+ // If we have not yet found it then there are no mapped
+ // configurations and no exact match.
+ if(!loc && !imp)
+ {
+ // The suffix computed above is not useful.
+ suffix = "";
+
+ // Look for a configuration-less location. This may be set by
+ // manually-written code.
+ loc = this->GetProperty("IMPORTED_LOCATION");
+ if(allowImp)
+ {
+ imp = this->GetProperty("IMPORTED_IMPLIB");
+ }
+ }
+
+ // If we have not yet found it then the project is willing to try
+ // any available configuration.
+ if(!loc && !imp)
+ {
+ std::vector<std::string> availableConfigs;
+ if(const char* iconfigs = this->GetProperty("IMPORTED_CONFIGURATIONS"))
+ {
+ cmSystemTools::ExpandListArgument(iconfigs, availableConfigs);
+ }
+ for(std::vector<std::string>::const_iterator
+ aci = availableConfigs.begin();
+ !loc && !imp && aci != availableConfigs.end(); ++aci)
+ {
+ suffix = "_";
+ suffix += cmSystemTools::UpperCase(*aci);
+ std::string locProp = "IMPORTED_LOCATION";
+ locProp += suffix;
+ loc = this->GetProperty(locProp.c_str());
+ if(allowImp)
+ {
+ std::string impProp = "IMPORTED_IMPLIB";
+ impProp += suffix;
+ imp = this->GetProperty(impProp.c_str());
+ }
+ }
+ }
+
+ // If we have not yet found it then the target is not available.
+ if(!loc && !imp)
+ {
+ 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 = "IMPORTED_LINK_INTERFACE_LIBRARIES";
+ linkProp += suffix;
+ if(const char* config_libs = this->GetProperty(linkProp.c_str()))
+ {
+ cmSystemTools::ExpandListArgument(config_libs,
+ info.LinkInterface.Libraries);
+ }
+ else if(const char* libs =
+ this->GetProperty("IMPORTED_LINK_INTERFACE_LIBRARIES"))
+ {
+ cmSystemTools::ExpandListArgument(libs,
+ 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->GetType() == cmTarget::STATIC_LIBRARY)
+ {
+ 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)
+{
+ // Imported targets have their own link interface.
+ if(this->IsImported())
+ {
+ if(cmTarget::ImportInfo const* info = this->GetImportInfo(config))
+ {
+ 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.
+ std::string key = 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);
+
+ // 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;
+}
+
+//----------------------------------------------------------------------------
+bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface)
+{
+ // 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;
+ if(this->GetType() == cmTarget::SHARED_LIBRARY ||
+ this->IsExecutableWithExports())
+ {
+ // Lookup the per-configuration property.
+ std::string propName = "LINK_INTERFACE_LIBRARIES";
+ propName += suffix;
+ explicitLibraries = this->GetProperty(propName.c_str());
+
+ // If not set, try the generic property.
+ if(!explicitLibraries)
+ {
+ explicitLibraries = this->GetProperty("LINK_INTERFACE_LIBRARIES");
+ }
+ }
+
+ // 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.
+ cmSystemTools::ExpandListArgument(explicitLibraries, iface.Libraries);
+
+ if(this->GetType() == cmTarget::SHARED_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);
+ 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.
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ // The link implementation is the default link interface.
+ LinkImplementation const* impl = this->GetLinkImplementation(config);
+ iface.Libraries = impl->Libraries;
+ iface.WrongConfigLibraries = impl->WrongConfigLibraries;
+ if(this->GetType() == cmTarget::STATIC_LIBRARY)
+ {
+ // Targets using this archive need its language runtime libraries.
+ iface.Languages = impl->Languages;
+ }
+ }
+
+ 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)
+{
+ // There is no link implementation for imported targets.
+ if(this->IsImported())
+ {
+ return 0;
+ }
+
+ // Lookup any existing link implementation for this configuration.
+ std::string key = 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);
+
+ // 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)
+{
+ // Compute which library configuration to link.
+ cmTarget::LinkLibraryType linkType = this->ComputeLinkType(config);
+
+ // Collect libraries directly linked in this configuration.
+ LinkLibraryVectorType const& llibs = this->GetOriginalLinkLibraries();
+ for(cmTarget::LinkLibraryVectorType::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->first);
+ if(item == this->GetName() || item.empty())
+ {
+ continue;
+ }
+
+ if(li->second == cmTarget::GENERAL || li->second == linkType)
+ {
+ // The entry is meant for this configuration.
+ impl.Libraries.push_back(item);
+ }
+ else
+ {
+ // 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;
+}
+
+//----------------------------------------------------------------------------
+cmComputeLinkInformation*
+cmTarget::GetLinkInformation(const char* config)
+{
+ // Lookup any existing information for this configuration.
+ std::map<cmStdString, cmComputeLinkInformation*>::iterator
+ i = this->LinkInformation.find(config?config:"");
+ 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.
+ std::map<cmStdString, cmComputeLinkInformation*>::value_type
+ entry(config?config:"", info);
+ i = this->LinkInformation.insert(entry).first;
+ }
+ return i->second;
+}
+
+//----------------------------------------------------------------------------
+std::vector<std::string> cmTarget::GetIncludeDirectories()
+{
+ std::vector<std::string> includes;
+ const char *prop = this->GetProperty("INCLUDE_DIRECTORIES");
+ if(prop)
+ {
+ cmSystemTools::ExpandListArgument(prop, includes);
+ }
+
+ std::set<std::string> uniqueIncludes;
+ std::vector<std::string> orderedAndUniqueIncludes;
+ for(std::vector<std::string>::const_iterator
+ li = includes.begin(); li != includes.end(); ++li)
+ {
+ if(uniqueIncludes.insert(*li).second)
+ {
+ orderedAndUniqueIncludes.push_back(*li);
+ }
+ }
+
+ return orderedAndUniqueIncludes;
+}
+
+//----------------------------------------------------------------------------
+std::string cmTarget::GetFrameworkDirectory(const char* config)
+{
+ std::string fpath;
+ fpath += this->GetFullName(config, false);
+ fpath += ".framework/Versions/";
+ fpath += this->GetFrameworkVersion();
+ fpath += "/";
+ return fpath;
+}
+
+//----------------------------------------------------------------------------
+std::string cmTarget::BuildMacContentDirectory(const std::string& base,
+ const char* config,
+ bool includeMacOS)
+{
+ std::string fpath = base;
+ if(this->IsAppBundleOnApple())
+ {
+ fpath += this->GetFullName(config, false);
+ fpath += ".app/Contents/";
+ if(includeMacOS)
+ fpath += "MacOS/";
+ }
+ if(this->IsFrameworkOnApple())
+ {
+ fpath += this->GetFrameworkDirectory(config);
+ }
+ if(this->IsCFBundleOnApple())
+ {
+ fpath += this->GetFullName(config, false);
+ fpath += ".";
+ const char *ext = this->GetProperty("BUNDLE_EXTENSION");
+ if (!ext)
+ {
+ ext = "bundle";
+ }
+ fpath += ext;
+ fpath += "/Contents/";
+ if(includeMacOS)
+ fpath += "MacOS/";
+ }
+ return fpath;
+}
+
+//----------------------------------------------------------------------------
+std::string cmTarget::GetMacContentDirectory(const char* config,
+ bool implib,
+ bool includeMacOS)
+{
+ // Start with the output directory for the target.
+ std::string fpath = this->GetDirectory(config, implib);
+ fpath += "/";
+ fpath = this->BuildMacContentDirectory(fpath, config, includeMacOS);
+ 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;
+}
+
+//----------------------------------------------------------------------------
+cmTargetInternalPointer
+::cmTargetInternalPointer(cmTargetInternalPointer const& r)
+{
+ // Ideally cmTarget instances should never be copied. However until
+ // we can make a sweep to remove that, this copy constructor avoids
+ // allowing the resources (Internals) to be copied.
+ this->Pointer = new cmTargetInternals(*r.Pointer);
+}
+
+//----------------------------------------------------------------------------
+cmTargetInternalPointer::~cmTargetInternalPointer()
+{
+ delete this->Pointer;
+}
+
+//----------------------------------------------------------------------------
+cmTargetInternalPointer&
+cmTargetInternalPointer::operator=(cmTargetInternalPointer const& r)
+{
+ if(this == &r) { return *this; } // avoid warning on HP about self check
+ // Ideally cmTarget instances should never be copied. However until
+ // we can make a sweep to remove that, this copy constructor avoids
+ // allowing the resources (Internals) to be copied.
+ cmTargetInternals* oldPointer = this->Pointer;
+ this->Pointer = new cmTargetInternals(*r.Pointer);
+ delete oldPointer;
+ return *this;
+}
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
new file mode 100644
index 000000000..a89c5d91b
--- /dev/null
+++ b/Source/cmTarget.h
@@ -0,0 +1,646 @@
+/*============================================================================
+ 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 cmTarget_h
+#define cmTarget_h
+
+#include "cmCustomCommand.h"
+#include "cmPropertyMap.h"
+#include "cmPolicies.h"
+
+#include <cmsys/auto_ptr.hxx>
+
+class cmake;
+class cmMakefile;
+class cmSourceFile;
+class cmGlobalGenerator;
+class cmComputeLinkInformation;
+class cmListFileBacktrace;
+
+struct cmTargetLinkInformationMap:
+ public std::map<cmStdString, cmComputeLinkInformation*>
+{
+ typedef std::map<cmStdString, cmComputeLinkInformation*> derived;
+ cmTargetLinkInformationMap() {}
+ cmTargetLinkInformationMap(cmTargetLinkInformationMap const& r);
+ ~cmTargetLinkInformationMap();
+};
+
+class cmTargetInternals;
+class cmTargetInternalPointer
+{
+public:
+ cmTargetInternalPointer();
+ cmTargetInternalPointer(cmTargetInternalPointer const& r);
+ ~cmTargetInternalPointer();
+ cmTargetInternalPointer& operator=(cmTargetInternalPointer const& r);
+ cmTargetInternals* operator->() const { return this->Pointer; }
+ cmTargetInternals* Get() const { return this->Pointer; }
+private:
+ cmTargetInternals* Pointer;
+};
+
+/** \class cmTarget
+ * \brief Represent a library or executable target loaded from a makefile.
+ *
+ * cmTarget represents a target loaded from
+ * a makefile.
+ */
+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
+ {
+ return this->TargetTypeValue;
+ }
+
+ /**
+ * Set the target type
+ */
+ void SetType(TargetType f, const char* name);
+
+ void MarkAsImported();
+
+ ///! Set/Get the name of the target
+ const char* GetName() const {return this->Name.c_str();}
+
+ ///! Set the cmMakefile that owns this target
+ void SetMakefile(cmMakefile *mf);
+ cmMakefile *GetMakefile() const { return this->Makefile;};
+
+ /** Get the status of policy CMP0003 when the target was created. */
+ cmPolicies::PolicyStatus GetPolicyStatusCMP0003() const
+ { return this->PolicyStatusCMP0003; }
+
+ /** Get the status of policy CMP0004 when the target was created. */
+ cmPolicies::PolicyStatus GetPolicyStatusCMP0004() const
+ { return this->PolicyStatusCMP0004; }
+
+ /** Get the status of policy CMP0008 when the target was created. */
+ cmPolicies::PolicyStatus GetPolicyStatusCMP0008() const
+ { return this->PolicyStatusCMP0008; }
+
+ /**
+ * Get the list of the custom commands for this target
+ */
+ std::vector<cmCustomCommand> &GetPreBuildCommands()
+ {return this->PreBuildCommands;}
+ std::vector<cmCustomCommand> &GetPreLinkCommands()
+ {return this->PreLinkCommands;}
+ std::vector<cmCustomCommand> &GetPostBuildCommands()
+ {return this->PostBuildCommands;}
+
+ ///! Return the list of frameworks being linked to this target
+ std::vector<std::string> &GetFrameworks() {return this->Frameworks;}
+
+ /**
+ * 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);
+
+ /**
+ * Add sources to the target.
+ */
+ void AddSources(std::vector<std::string> const& srcs);
+ cmSourceFile* AddSource(const char* src);
+
+ /**
+ * Get the list of the source files used by this target
+ */
+ enum LinkLibraryType {GENERAL, DEBUG, OPTIMIZED};
+
+ //* how we identify a library, by name and type
+ typedef std::pair<cmStdString, LinkLibraryType> LibraryID;
+
+ typedef std::vector<LibraryID > LinkLibraryVectorType;
+ const LinkLibraryVectorType &GetLinkLibraries() const {
+ return this->LinkLibraries;}
+ const LinkLibraryVectorType &GetOriginalLinkLibraries() const
+ {return this->OriginalLinkLibraries;}
+
+ /** 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);
+
+ // Check to see if a library is a framework and treat it different on Mac
+ bool NameResolvesToFramework(const std::string& libname);
+ bool AddFramework(const std::string& lib, LinkLibraryType llt);
+ void AddLinkLibrary(cmMakefile& mf,
+ const char *target, const char* lib,
+ LinkLibraryType llt);
+
+ void MergeLinkLibraries( cmMakefile& mf, const char* selfname,
+ const LinkLibraryVectorType& libs );
+
+ const std::vector<std::string>& GetLinkDirectories();
+
+ void AddLinkDirectory(const char* d);
+
+ /**
+ * Set the path where this target should be installed. This is relative to
+ * INSTALL_PREFIX
+ */
+ std::string GetInstallPath() {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;}
+ void SetRuntimeInstallPath(const char *name) {
+ this->RuntimeInstallPath = name; }
+
+ /**
+ * Get/Set whether there is an install rule for this target.
+ */
+ bool GetHaveInstallRule() { 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);}
+ ///! 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();
+
+ ///! 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);
+
+ 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;
+
+ LinkInterface(): Multiplicity(0) {}
+ };
+
+ /** Get the link interface for the given configuration. Returns 0
+ if the target cannot be linked. */
+ LinkInterface const* GetLinkInterface(const char* config);
+
+ /** 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);
+
+ /** 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);
+
+ /** 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 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(const char* vsProjectFile);
+
+ /**
+ * 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);
+
+ ///! Return the rule variable used to create this type of target,
+ // need to add CMAKE_(LANG) for full name.
+ const char* GetCreateRuleVariable();
+
+ /** 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);
+
+ /** 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();
+ bool HaveInstallTreeRPATH();
+
+ /** Return true if builtin chrpath will work for this target */
+ bool IsChrpathUsed(const char* config);
+
+ std::string GetInstallNameDirForBuildTree(const char* config,
+ bool for_xcode = false);
+ std::string GetInstallNameDirForInstallTree(const char* config,
+ bool for_xcode = false);
+
+ cmComputeLinkInformation* GetLinkInformation(const char* config);
+
+ // Get the properties
+ cmPropertyMap &GetProperties() { return this->Properties; };
+
+ // 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();
+
+ // 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;
+
+ /** Get the list of OS X target architectures to be built. */
+ void GetAppleArchs(const char* config, std::vector<std::string>& archVec);
+
+ /** 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();
+
+ /** 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();
+
+ /** Return whether this target is an executable Bundle on Apple. */
+ bool IsAppBundleOnApple();
+
+ /** Return the framework version string. Undefined if
+ IsFrameworkOnApple returns false. */
+ std::string GetFrameworkVersion();
+
+ /** 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);
+
+ /** Get the include directories for this target. */
+ std::vector<std::string> GetIncludeDirectories();
+
+ /** Append to @a base the mac content directory and return it. */
+ std::string BuildMacContentDirectory(const std::string& base,
+ const char* config = 0,
+ bool includeMacOS = true);
+
+ /** @return the mac content directory for this target. */
+ std::string GetMacContentDirectory(const char* config = 0,
+ bool implib = false,
+ bool includeMacOS = true);
+
+ /** @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 = 0);
+
+private:
+ /**
+ * A list of direct dependencies. Use in conjunction with DependencyMap.
+ */
+ typedef std::vector< LibraryID > DependencyList;
+
+ /**
+ * This map holds the dependency graph. map[x] returns a set of
+ * direct dependencies of x. Note that the direct depenencies are
+ * ordered. This is necessary to handle direct dependencies that
+ * themselves have no dependency information.
+ */
+ typedef std::map< LibraryID, DependencyList > DependencyMap;
+
+ /**
+ * Inserts \a dep at the end of the dependency list of \a lib.
+ */
+ void InsertDependency( 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);
+
+ /**
+ * Emits the library \a lib and all its dependencies into link_line.
+ * \a emitted keeps track of the libraries that have been emitted to
+ * avoid duplicates--it is more efficient than searching
+ * link_line. \a visited is used detect cycles. Note that \a
+ * 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);
+
+ /**
+ * 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 );
+
+ 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);
+
+ // 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);
+
+ 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);
+
+private:
+ std::string Name;
+ 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;
+ LinkLibraryVectorType PrevLinkedLibraries;
+ bool LinkLibrariesAnalyzed;
+ std::vector<std::string> Frameworks;
+ std::vector<std::string> LinkDirectories;
+ std::set<cmStdString> LinkDirectoriesEmmitted;
+ 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 IsImportedTarget;
+
+ // 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);
+
+ // Cache import information from properties for each configuration.
+ struct ImportInfo;
+ ImportInfo const* GetImportInfo(const char* config);
+ void ComputeImportInfo(std::string const& desired_config, ImportInfo& info);
+
+ cmTargetLinkInformationMap LinkInformation;
+
+ bool ComputeLinkInterface(const char* config, LinkInterface& iface);
+
+ void ComputeLinkImplementation(const char* config,
+ LinkImplementation& impl);
+ void ComputeLinkClosure(const char* config, LinkClosure& lc);
+
+ 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.
+ cmPolicies::PolicyStatus PolicyStatusCMP0003;
+ cmPolicies::PolicyStatus PolicyStatusCMP0004;
+ cmPolicies::PolicyStatus PolicyStatusCMP0008;
+
+ // Internal representation details.
+ friend class cmTargetInternals;
+ cmTargetInternalPointer Internal;
+
+ 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);
+};
+
+typedef std::map<cmStdString,cmTarget> cmTargets;
+
+class cmTargetSet: public std::set<cmStdString> {};
+class cmTargetManifest: public std::map<cmStdString, cmTargetSet> {};
+
+#endif
diff --git a/Source/cmTargetDepend.h b/Source/cmTargetDepend.h
new file mode 100644
index 000000000..258bacd6d
--- /dev/null
+++ b/Source/cmTargetDepend.h
@@ -0,0 +1,48 @@
+/*============================================================================
+ 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 cmTargetDepend_h
+#define cmTargetDepend_h
+
+#include "cmStandardIncludes.h"
+
+class cmTarget;
+
+/** One edge in the global target dependency graph.
+ It may be marked as a 'link' or 'util' edge or both. */
+class cmTargetDepend
+{
+ cmTarget* 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; }
+ friend bool operator < (cmTargetDepend const& l, cmTargetDepend const& r)
+ { return l.Target < r.Target; }
+ void SetType(bool strong) const
+ {
+ if(strong) { this->Util = true; }
+ else { this->Link = true; }
+ }
+ bool IsLink() const { return this->Link; }
+ bool IsUtil() const { return this->Util; }
+};
+
+/** Unordered set of (direct) dependencies of a target. */
+class cmTargetDependSet: public std::set<cmTargetDepend> {};
+
+#endif
diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx
new file mode 100644
index 000000000..dbea1c3bb
--- /dev/null
+++ b/Source/cmTargetLinkLibrariesCommand.cxx
@@ -0,0 +1,304 @@
+/*============================================================================
+ 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 "cmTargetLinkLibrariesCommand.h"
+
+const char* cmTargetLinkLibrariesCommand::LinkLibraryTypeNames[3] =
+{
+ "general",
+ "debug",
+ "optimized"
+};
+
+// cmTargetLinkLibrariesCommand
+bool cmTargetLinkLibrariesCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ // must have one argument
+ if(args.size() < 1)
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ // Lookup the target for which libraries are specified.
+ this->Target =
+ this->Makefile->GetCMakeInstance()
+ ->GetGlobalGenerator()->FindTarget(0, args[0].c_str());
+ if(!this->Target)
+ {
+ cmake::MessageType t = cmake::FATAL_ERROR; // fail by default
+ cmOStringStream 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,
+ // and accept, warn or fail respectively:
+ if (args.size() < 2)
+ {
+ switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0016))
+ {
+ case cmPolicies::WARN:
+ t = cmake::AUTHOR_WARNING;
+ // Print the warning.
+ 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);
+ 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);
+ break;
+ case cmPolicies::NEW: // NEW behavior prints the error.
+ default:
+ break;
+ }
+ }
+
+ // now actually print the message
+ switch(t)
+ {
+ case cmake::AUTHOR_WARNING:
+ this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, e.str());
+ break;
+ case cmake::FATAL_ERROR:
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ cmSystemTools::SetFatalErrorOccured();
+ break;
+ default:
+ break;
+ }
+ return true;
+ }
+
+ if(this->Target->GetType() == cmTarget::OBJECT_LIBRARY)
+ {
+ cmOStringStream e;
+ e << "Object library target \"" << args[0] << "\" "
+ << "may not link to anything.";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ cmSystemTools::SetFatalErrorOccured();
+ return true;
+ }
+
+ // but we might not have any libs after variable expansion
+ if(args.size() < 2)
+ {
+ return true;
+ }
+
+ // Keep track of link configuration specifiers.
+ cmTarget::LinkLibraryType llt = cmTarget::GENERAL;
+ bool haveLLT = false;
+
+ // Start with primary linking and switch to link interface
+ // specification if the keyword is encountered as the first argument.
+ this->CurrentProcessingState = ProcessingLinkLibraries;
+
+ // add libraries, nothe that there is an optional prefix
+ // of debug and optimized than can be used
+ for(unsigned int i=1; i < args.size(); ++i)
+ {
+ if(args[i] == "LINK_INTERFACE_LIBRARIES")
+ {
+ this->CurrentProcessingState = ProcessingLinkInterface;
+ if(i != 1)
+ {
+ this->Makefile->IssueMessage(
+ cmake::FATAL_ERROR,
+ "The LINK_INTERFACE_LIBRARIES option must appear as the second "
+ "argument, just after the target name."
+ );
+ return true;
+ }
+ }
+ else if(args[i] == "LINK_PUBLIC")
+ {
+ if(i != 1 && this->CurrentProcessingState != ProcessingPrivateInterface)
+ {
+ this->Makefile->IssueMessage(
+ cmake::FATAL_ERROR,
+ "The LINK_PUBLIC or LINK_PRIVATE option must appear as the second "
+ "argument, just after the target name."
+ );
+ return true;
+ }
+ this->CurrentProcessingState = ProcessingPublicInterface;
+ }
+ else if(args[i] == "LINK_PRIVATE")
+ {
+ if(i != 1 && this->CurrentProcessingState != ProcessingPublicInterface)
+ {
+ this->Makefile->IssueMessage(
+ cmake::FATAL_ERROR,
+ "The LINK_PUBLIC or LINK_PRIVATE option must appear as the second "
+ "argument, just after the target name."
+ );
+ return true;
+ }
+ this->CurrentProcessingState = ProcessingPrivateInterface;
+ }
+ else if(args[i] == "debug")
+ {
+ if(haveLLT)
+ {
+ this->LinkLibraryTypeSpecifierWarning(llt, cmTarget::DEBUG);
+ }
+ llt = cmTarget::DEBUG;
+ haveLLT = true;
+ }
+ else if(args[i] == "optimized")
+ {
+ if(haveLLT)
+ {
+ this->LinkLibraryTypeSpecifierWarning(llt, cmTarget::OPTIMIZED);
+ }
+ llt = cmTarget::OPTIMIZED;
+ haveLLT = true;
+ }
+ else if(args[i] == "general")
+ {
+ if(haveLLT)
+ {
+ this->LinkLibraryTypeSpecifierWarning(llt, cmTarget::GENERAL);
+ }
+ llt = cmTarget::GENERAL;
+ haveLLT = true;
+ }
+ else if(haveLLT)
+ {
+ // The link type was specified by the previous argument.
+ haveLLT = false;
+ this->HandleLibrary(args[i].c_str(), llt);
+ }
+ else
+ {
+ // Lookup old-style cache entry if type is unspecified. So if you
+ // do a target_link_libraries(foo optimized bar) it will stay optimized
+ // and not use the lookup. As there maybe the case where someone has
+ // 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;
+ std::string linkType = args[0];
+ linkType += "_LINK_TYPE";
+ const char* linkTypeString =
+ this->Makefile->GetDefinition( linkType.c_str() );
+ if(linkTypeString)
+ {
+ if(strcmp(linkTypeString, "debug") == 0)
+ {
+ llt = cmTarget::DEBUG;
+ }
+ if(strcmp(linkTypeString, "optimized") == 0)
+ {
+ llt = cmTarget::OPTIMIZED;
+ }
+ }
+ this->HandleLibrary(args[i].c_str(), llt);
+ }
+ }
+
+ // Make sure the last argument was not a library type specifier.
+ if(haveLLT)
+ {
+ cmOStringStream e;
+ e << "The \"" << this->LinkLibraryTypeNames[llt]
+ << "\" argument must be followed by a library.";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ cmSystemTools::SetFatalErrorOccured();
+ }
+
+ // If any of the LINK_ options were given, make sure the
+ // LINK_INTERFACE_LIBRARIES target property exists.
+ // Use of any of the new keywords implies awareness of
+ // this property. And if no libraries are named, it should
+ // result in an empty link interface.
+ if(this->CurrentProcessingState != ProcessingLinkLibraries &&
+ !this->Target->GetProperty("LINK_INTERFACE_LIBRARIES"))
+ {
+ this->Target->SetProperty("LINK_INTERFACE_LIBRARIES", "");
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+void
+cmTargetLinkLibrariesCommand
+::LinkLibraryTypeSpecifierWarning(int left, int right)
+{
+ cmOStringStream w;
+ w << "Link library type specifier \""
+ << this->LinkLibraryTypeNames[left] << "\" is followed by specifier \""
+ << this->LinkLibraryTypeNames[right] << "\" instead of a library name. "
+ << "The first specifier will be ignored.";
+ this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+}
+
+//----------------------------------------------------------------------------
+void
+cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib,
+ cmTarget::LinkLibraryType llt)
+{
+ // Handle normal case first.
+ if(this->CurrentProcessingState != ProcessingLinkInterface)
+ {
+ this->Makefile
+ ->AddLinkLibraryForTarget(this->Target->GetName(), lib, llt);
+ if (this->CurrentProcessingState != ProcessingPublicInterface)
+ {
+ // Not LINK_INTERFACE_LIBRARIES or LINK_PUBLIC, do not add to interface.
+ return;
+ }
+ }
+
+ // Get the list of configurations considered to be DEBUG.
+ std::vector<std::string> const& 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)
+ {
+ // Put in the DEBUG configuration interfaces.
+ for(std::vector<std::string>::const_iterator i = debugConfigs.begin();
+ i != debugConfigs.end(); ++i)
+ {
+ prop = "LINK_INTERFACE_LIBRARIES_";
+ prop += *i;
+ this->Target->AppendProperty(prop.c_str(), lib);
+ }
+ }
+ if(llt == cmTarget::OPTIMIZED || llt == cmTarget::GENERAL)
+ {
+ // Put in the non-DEBUG configuration interfaces.
+ this->Target->AppendProperty("LINK_INTERFACE_LIBRARIES", lib);
+
+ // Make sure the DEBUG configuration interfaces exist so that the
+ // general one will not be used as a fall-back.
+ for(std::vector<std::string>::const_iterator i = debugConfigs.begin();
+ i != debugConfigs.end(); ++i)
+ {
+ prop = "LINK_INTERFACE_LIBRARIES_";
+ prop += *i;
+ if(!this->Target->GetProperty(prop.c_str()))
+ {
+ this->Target->SetProperty(prop.c_str(), "");
+ }
+ }
+ }
+}
diff --git a/Source/cmTargetLinkLibrariesCommand.h b/Source/cmTargetLinkLibrariesCommand.h
new file mode 100644
index 000000000..63114d209
--- /dev/null
+++ b/Source/cmTargetLinkLibrariesCommand.h
@@ -0,0 +1,167 @@
+/*============================================================================
+ 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 cmTargetLinkLibrariesCommand_h
+#define cmTargetLinkLibrariesCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmTargetLinkLibrariesCommand
+ * \brief Specify a list of libraries to link into executables.
+ *
+ * cmTargetLinkLibrariesCommand is used to specify a list of libraries to link
+ * into executable(s) or shared objects. The names of the libraries
+ * should be those defined by the LIBRARY(library) command(s).
+ */
+class cmTargetLinkLibrariesCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmTargetLinkLibrariesCommand;
+ }
+
+ /**
+ * 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 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. "
+ "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. "
+ "See the LINK_INTERFACE_LIBRARIES target property to override the "
+ "set of transitive link dependencies for a 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 LINK_INTERFACE_LIBRARIES and its per-configuration equivalent "
+ "target properties instead of using them for linking. "
+ "Libraries specified as \"debug\" are appended to the "
+ "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 "
+ "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. "
+ "Libraries and targets following LINK_PUBLIC are linked to, and are "
+ "made part of the LINK_INTERFACE_LIBRARIES. Libraries and targets "
+ "following LINK_PRIVATE are linked to, but are not made part of the "
+ "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."
+ ")"
+ ;
+ }
+
+ cmTypeMacro(cmTargetLinkLibrariesCommand, cmCommand);
+private:
+ void LinkLibraryTypeSpecifierWarning(int left, int right);
+ static const char* LinkLibraryTypeNames[3];
+
+ cmTarget* Target;
+ enum ProcessingState {
+ ProcessingLinkLibraries,
+ ProcessingLinkInterface,
+ ProcessingPublicInterface,
+ ProcessingPrivateInterface
+ };
+
+ ProcessingState CurrentProcessingState;
+
+ void HandleLibrary(const char* lib, cmTarget::LinkLibraryType llt);
+};
+
+
+
+#endif
diff --git a/Source/cmTest.cxx b/Source/cmTest.cxx
new file mode 100644
index 000000000..502c1740d
--- /dev/null
+++ b/Source/cmTest.cxx
@@ -0,0 +1,205 @@
+/*============================================================================
+ 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 "cmTest.h"
+#include "cmSystemTools.h"
+
+#include "cmake.h"
+#include "cmMakefile.h"
+
+//----------------------------------------------------------------------------
+cmTest::cmTest(cmMakefile* mf)
+{
+ 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;
+}
+
+//----------------------------------------------------------------------------
+void cmTest::SetName(const char* name)
+{
+ if ( !name )
+ {
+ name = "";
+ }
+ this->Name = name;
+}
+
+//----------------------------------------------------------------------------
+void cmTest::SetCommand(std::vector<std::string> const& command)
+{
+ this->Command = command;
+}
+
+//----------------------------------------------------------------------------
+const char *cmTest::GetProperty(const char* prop) const
+{
+ bool chain = false;
+ const char *retVal =
+ this->Properties.GetPropertyValue(prop, cmProperty::TEST, chain);
+ if (chain)
+ {
+ return this->Makefile->GetProperty(prop,cmProperty::TEST);
+ }
+ return retVal;
+}
+
+//----------------------------------------------------------------------------
+bool cmTest::GetPropertyAsBool(const char* prop) const
+{
+ return cmSystemTools::IsOn(this->GetProperty(prop));
+}
+
+//----------------------------------------------------------------------------
+void cmTest::SetProperty(const char* prop, const char* value)
+{
+ if (!prop)
+ {
+ return;
+ }
+
+ this->Properties.SetProperty(prop, value, cmProperty::TEST);
+}
+
+//----------------------------------------------------------------------------
+void cmTest::AppendProperty(const char* 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: PASS_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.");
+}
diff --git a/Source/cmTest.h b/Source/cmTest.h
new file mode 100644
index 000000000..6223a01ea
--- /dev/null
+++ b/Source/cmTest.h
@@ -0,0 +1,80 @@
+/*============================================================================
+ 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 cmTest_h
+#define cmTest_h
+
+#include "cmCustomCommand.h"
+#include "cmPropertyMap.h"
+class cmMakefile;
+class cmListFileBacktrace;
+
+/** \class cmTest
+ * \brief Represent a test
+ *
+ * cmTest is representation of a test.
+ */
+class cmTest
+{
+public:
+ /**
+ */
+ cmTest(cmMakefile* mf);
+ ~cmTest();
+
+ ///! Set the test name
+ void SetName(const char* name);
+ const char* GetName() const { return this->Name.c_str(); }
+
+ void SetCommand(std::vector<std::string> const& command);
+ std::vector<std::string> const& GetCommand() const
+ {
+ 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);
+
+ /** Get the cmMakefile instance that owns this test. */
+ cmMakefile *GetMakefile() { return this->Makefile;};
+
+ /** Get the backtrace of the command that created this test. */
+ cmListFileBacktrace const& GetBacktrace() const;
+
+ /** Get/Set whether this is an old-style test. */
+ bool GetOldStyle() const { return this->OldStyle; }
+ void SetOldStyle(bool b) { this->OldStyle = b; }
+
+private:
+ cmPropertyMap Properties;
+ cmStdString Name;
+ std::vector<std::string> Command;
+
+ bool OldStyle;
+
+ cmMakefile* Makefile;
+ cmListFileBacktrace* Backtrace;
+};
+
+#endif
+
diff --git a/Source/cmTestGenerator.cxx b/Source/cmTestGenerator.cxx
new file mode 100644
index 000000000..e0892b282
--- /dev/null
+++ b/Source/cmTestGenerator.cxx
@@ -0,0 +1,184 @@
+/*============================================================================
+ 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 "cmTestGenerator.h"
+
+#include "cmGeneratorExpression.h"
+#include "cmLocalGenerator.h"
+#include "cmMakefile.h"
+#include "cmSystemTools.h"
+#include "cmTarget.h"
+#include "cmTest.h"
+
+//----------------------------------------------------------------------------
+cmTestGenerator
+::cmTestGenerator(cmTest* test,
+ std::vector<std::string> const& configurations):
+ cmScriptGenerator("CTEST_CONFIGURATION_TYPE", configurations),
+ Test(test)
+{
+ this->ActionsPerConfig = !test->GetOldStyle();
+ this->TestGenerated = false;
+}
+
+//----------------------------------------------------------------------------
+cmTestGenerator
+::~cmTestGenerator()
+{
+}
+
+//----------------------------------------------------------------------------
+void cmTestGenerator::GenerateScriptConfigs(std::ostream& os,
+ Indent const& indent)
+{
+ // First 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;
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmTestGenerator::GenerateScriptActions(std::ostream& os,
+ Indent const& indent)
+{
+ if(this->ActionsPerConfig)
+ {
+ // This is the per-config generation in a single-configuration
+ // build generator case. The superclass will call our per-config
+ // method.
+ this->cmScriptGenerator::GenerateScriptActions(os, indent);
+ }
+ else
+ {
+ // This is an old-style test, so there is only one config.
+ //assert(this->Test->GetOldStyle());
+ this->GenerateOldStyle(os, indent);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
+ const char* config,
+ Indent const& indent)
+{
+ this->TestGenerated = true;
+
+ // Set up generator expression evaluation context.
+ cmMakefile* mf = this->Test->GetMakefile();
+ cmGeneratorExpression ge(mf, config, this->Test->GetBacktrace());
+
+ // Start the test command.
+ os << indent << "ADD_TEST(" << this->Test->GetName() << " ";
+
+ // Get the test command line to be executed.
+ std::vector<std::string> const& command = this->Test->GetCommand();
+
+ // Check whether the command executable is a target whose name is to
+ // be translated.
+ std::string exe = command[0];
+ cmTarget* target = mf->FindTargetToUse(exe.c_str());
+ if(target && target->GetType() == cmTarget::EXECUTABLE)
+ {
+ // Use the target file on disk.
+ exe = target->GetFullPath(config);
+ }
+ else
+ {
+ // Use the command name given.
+ exe = ge.Process(exe.c_str());
+ cmSystemTools::ConvertToUnixSlashes(exe);
+ }
+
+ // Generate the command line with full escapes.
+ cmLocalGenerator* lg = mf->GetLocalGenerator();
+ os << lg->EscapeForCMake(exe.c_str());
+ for(std::vector<std::string>::const_iterator ci = command.begin()+1;
+ ci != command.end(); ++ci)
+ {
+ os << " " << lg->EscapeForCMake(ge.Process(*ci));
+ }
+
+ // Finish the test command.
+ os << ")\n";
+}
+
+//----------------------------------------------------------------------------
+void cmTestGenerator::GenerateScriptNoConfig(std::ostream& os,
+ Indent const& indent)
+{
+ os << indent << "ADD_TEST(" << this->Test->GetName() << " NOT_AVAILABLE)\n";
+}
+
+//----------------------------------------------------------------------------
+bool cmTestGenerator::NeedsScriptNoConfig() const
+{
+ return (this->TestGenerated && // test generated for at least one config
+ this->ActionsPerConfig && // test is config-aware
+ this->Configurations.empty() && // test runs in all configs
+ !this->ConfigurationTypes->empty()); // config-dependent command
+}
+
+//----------------------------------------------------------------------------
+void cmTestGenerator::GenerateOldStyle(std::ostream& fout,
+ Indent const& indent)
+{
+ this->TestGenerated = true;
+
+ // Get the test command line to be executed.
+ std::vector<std::string> const& command = this->Test->GetCommand();
+
+ std::string exe = command[0];
+ cmSystemTools::ConvertToUnixSlashes(exe);
+ fout << indent;
+ fout << "ADD_TEST(";
+ fout << this->Test->GetName() << " \"" << exe << "\"";
+
+ for(std::vector<std::string>::const_iterator argit = command.begin()+1;
+ argit != command.end(); ++argit)
+ {
+ // Just double-quote all arguments so they are re-parsed
+ // correctly by the test system.
+ fout << " \"";
+ for(std::string::const_iterator c = argit->begin();
+ c != argit->end(); ++c)
+ {
+ // Escape quotes within arguments. We should escape
+ // backslashes too but we cannot because it makes the result
+ // inconsistent with previous behavior of this command.
+ if((*c == '"'))
+ {
+ fout << '\\';
+ }
+ fout << *c;
+ }
+ fout << "\"";
+ }
+ fout << ")" << std::endl;
+}
diff --git a/Source/cmTestGenerator.h b/Source/cmTestGenerator.h
new file mode 100644
index 000000000..2c69fc3c5
--- /dev/null
+++ b/Source/cmTestGenerator.h
@@ -0,0 +1,45 @@
+/*============================================================================
+ 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 cmTestGenerator_h
+#define cmTestGenerator_h
+
+#include "cmScriptGenerator.h"
+
+class cmTest;
+
+/** \class cmTestGenerator
+ * \brief Support class for generating install scripts.
+ *
+ */
+class cmTestGenerator: public cmScriptGenerator
+{
+public:
+ cmTestGenerator(cmTest* test,
+ std::vector<std::string> const&
+ configurations = std::vector<std::string>());
+ virtual ~cmTestGenerator();
+
+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,
+ Indent const& indent);
+ virtual void GenerateScriptNoConfig(std::ostream& os, Indent const& indent);
+ virtual bool NeedsScriptNoConfig() const;
+ void GenerateOldStyle(std::ostream& os, Indent const& indent);
+
+ cmTest* Test;
+ bool TestGenerated;
+};
+
+#endif
diff --git a/Source/cmTryCompileCommand.cxx b/Source/cmTryCompileCommand.cxx
new file mode 100644
index 000000000..12ce015d2
--- /dev/null
+++ b/Source/cmTryCompileCommand.cxx
@@ -0,0 +1,42 @@
+/*============================================================================
+ 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 "cmTryCompileCommand.h"
+
+// cmTryCompileCommand
+bool cmTryCompileCommand
+::InitialPass(std::vector<std::string> const& argv, cmExecutionStatus &)
+{
+ if(argv.size() < 3)
+ {
+ return false;
+ }
+
+ if(this->Makefile->GetCMakeInstance()->GetWorkingMode() ==
+ cmake::FIND_PACKAGE_MODE)
+ {
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR,
+ "The TRY_COMPILE() command is not supported in --find-package mode.");
+ return false;
+ }
+
+ this->TryCompileCode(argv);
+
+ // if They specified clean then we clean up what we can
+ if (this->SrcFileSignature)
+ {
+ if(!this->Makefile->GetCMakeInstance()->GetDebugTryCompile())
+ {
+ this->CleanupFiles(this->BinaryDirectory.c_str());
+ }
+ }
+ return true;
+}
diff --git a/Source/cmTryCompileCommand.h b/Source/cmTryCompileCommand.h
new file mode 100644
index 000000000..68ec666ec
--- /dev/null
+++ b/Source/cmTryCompileCommand.h
@@ -0,0 +1,119 @@
+/*============================================================================
+ 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 cmTryCompileCommand_h
+#define cmTryCompileCommand_h
+
+#include "cmCoreTryCompile.h"
+
+/** \class cmTryCompileCommand
+ * \brief Specifies where to install some files
+ *
+ * cmTryCompileCommand is used to test if soucre code can be compiled
+ */
+class cmTryCompileCommand : public cmCoreTryCompile
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmTryCompileCommand;
+ }
+
+ /**
+ * 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 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>\n"
+ " [CMAKE_FLAGS flags...]\n"
+ " [COMPILE_DEFINITIONS flags...]\n"
+ " [OUTPUT_VARIABLE <var>]\n"
+ " [COPY_FILE <fileName>])\n"
+ "Try building a source file into an executable. "
+ "In this form the user need only supply a source file that defines "
+ "a 'main'. "
+ "CMake will create a CMakeLists.txt file to build the source "
+ "as an executable. "
+ "Specify COPY_FILE to get a copy of the linked executable at the "
+ "given fileName."
+ "\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. "
+ "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."
+ ;
+ }
+
+ cmTypeMacro(cmTryCompileCommand, cmCoreTryCompile);
+
+};
+
+
+#endif
diff --git a/Source/cmTryRunCommand.cxx b/Source/cmTryRunCommand.cxx
new file mode 100644
index 000000000..4fc0b13c0
--- /dev/null
+++ b/Source/cmTryRunCommand.cxx
@@ -0,0 +1,387 @@
+/*============================================================================
+ 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 "cmTryRunCommand.h"
+#include "cmCacheManager.h"
+#include "cmTryCompileCommand.h"
+
+// cmTryRunCommand
+bool cmTryRunCommand
+::InitialPass(std::vector<std::string> const& argv, cmExecutionStatus &)
+{
+ if(argv.size() < 4)
+ {
+ return false;
+ }
+
+ if(this->Makefile->GetCMakeInstance()->GetWorkingMode() ==
+ cmake::FIND_PACKAGE_MODE)
+ {
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR,
+ "The TRY_RUN() command is not supported in --find-package mode.");
+ return false;
+ }
+
+ // build an arg list for TryCompile and extract the runArgs,
+ std::vector<std::string> tryCompile;
+
+ this->CompileResultVariable = "";
+ this->RunResultVariable = "";
+ this->OutputVariable = "";
+ this->RunOutputVariable = "";
+ this->CompileOutputVariable = "";
+
+ std::string runArgs;
+ unsigned int i;
+ for (i = 1; i < argv.size(); ++i)
+ {
+ if (argv[i] == "ARGS")
+ {
+ ++i;
+ while (i < argv.size() && argv[i] != "COMPILE_DEFINITIONS" &&
+ argv[i] != "CMAKE_FLAGS")
+ {
+ runArgs += " ";
+ runArgs += argv[i];
+ ++i;
+ }
+ if (i < argv.size())
+ {
+ tryCompile.push_back(argv[i]);
+ }
+ }
+ else
+ {
+ if (argv[i] == "OUTPUT_VARIABLE")
+ {
+ if ( argv.size() <= (i+1) )
+ {
+ cmSystemTools::Error(
+ "OUTPUT_VARIABLE specified but there is no variable");
+ return false;
+ }
+ i++;
+ this->OutputVariable = argv[i];
+ }
+ else if (argv[i] == "RUN_OUTPUT_VARIABLE")
+ {
+ if (argv.size() <= (i + 1))
+ {
+ cmSystemTools::Error(
+ "RUN_OUTPUT_VARIABLE specified but there is no variable");
+ return false;
+ }
+ i++;
+ this->RunOutputVariable = argv[i];
+ }
+ else if (argv[i] == "COMPILE_OUTPUT_VARIABLE")
+ {
+ if (argv.size() <= (i + 1))
+ {
+ cmSystemTools::Error(
+ "COMPILE_OUTPUT_VARIABLE specified but there is no variable");
+ return false;
+ }
+ i++;
+ this->CompileOutputVariable = argv[i];
+ }
+ else
+ {
+ tryCompile.push_back(argv[i]);
+ }
+ }
+ }
+
+ // 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())))
+ {
+ cmSystemTools::Error(
+ "You cannot use OUTPUT_VARIABLE together with COMPILE_OUTPUT_VARIABLE "
+ "or RUN_OUTPUT_VARIABLE. Please use only COMPILE_OUTPUT_VARIABLE and/or "
+ "RUN_OUTPUT_VARIABLE.");
+ return false;
+ }
+
+ bool captureRunOutput = false;
+ if (this->OutputVariable.size())
+ {
+ captureRunOutput = true;
+ tryCompile.push_back("OUTPUT_VARIABLE");
+ tryCompile.push_back(this->OutputVariable);
+ }
+ if (this->CompileOutputVariable.size())
+ {
+ tryCompile.push_back("OUTPUT_VARIABLE");
+ tryCompile.push_back(this->CompileOutputVariable);
+ }
+ if (this->RunOutputVariable.size())
+ {
+ captureRunOutput = true;
+ }
+
+ this->RunResultVariable = argv[0];
+ this->CompileResultVariable = argv[1];
+
+ // do the try compile
+ int res = this->TryCompileCode(tryCompile);
+
+ // now try running the command if it compiled
+ if (!res)
+ {
+ if (this->OutputFile.size() == 0)
+ {
+ cmSystemTools::Error(this->FindErrorMessage.c_str());
+ }
+ else
+ {
+ // "run" it and capture the output
+ std::string runOutputContents;
+ if (this->Makefile->IsOn("CMAKE_CROSSCOMPILING"))
+ {
+ this->DoNotRunExecutable(runArgs,
+ argv[3],
+ captureRunOutput ? &runOutputContents : 0);
+ }
+ else
+ {
+ this->RunExecutable(runArgs, &runOutputContents);
+ }
+
+ // now put the output into the variables
+ if(this->RunOutputVariable.size())
+ {
+ this->Makefile->AddDefinition(this->RunOutputVariable.c_str(),
+ runOutputContents.c_str());
+ }
+
+ if(this->OutputVariable.size())
+ {
+ // 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());
+ if (compileOutput)
+ {
+ runOutputContents = std::string(compileOutput) + runOutputContents;
+ }
+ this->Makefile->AddDefinition(this->OutputVariable.c_str(),
+ runOutputContents.c_str());
+ }
+ }
+ }
+
+ // if we created a directory etc, then cleanup after ourselves
+ if(!this->Makefile->GetCMakeInstance()->GetDebugTryCompile())
+ {
+ this->CleanupFiles(this->BinaryDirectory.c_str());
+ }
+ return true;
+}
+
+void cmTryRunCommand::RunExecutable(const std::string& runArgs,
+ std::string* out)
+{
+ int retVal = -1;
+ std::string finalCommand = cmSystemTools::ConvertToRunCommandPath(
+ this->OutputFile.c_str());
+ if (runArgs.size())
+ {
+ finalCommand += runArgs;
+ }
+ int timeout = 0;
+ bool worked = cmSystemTools::RunSingleCommand(finalCommand.c_str(),
+ out, &retVal,
+ 0, cmSystemTools::OUTPUT_NONE, timeout);
+ // set the run var
+ char retChar[1000];
+ if (worked)
+ {
+ sprintf(retChar, "%i", retVal);
+ }
+ else
+ {
+ strcpy(retChar, "FAILED_TO_RUN");
+ }
+ this->Makefile->AddCacheDefinition(this->RunResultVariable.c_str(), retChar,
+ "Result of TRY_RUN",
+ cmCacheManager::INTERNAL);
+}
+
+/* This is only used when cross compiling. Instead of running the
+ executable, two cache variables are created which will hold the results
+ the executable would have produced.
+*/
+void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
+ const std::string& srcFile,
+ std::string* out
+ )
+{
+ // copy the executable out of the CMakeFiles/ directory, so it is not
+ // removed at the end of TRY_RUN and the user can run it manually
+ // on the target platform.
+ std::string copyDest = this->Makefile->GetHomeOutputDirectory();
+ copyDest += cmake::GetCMakeFilesDirectory();
+ copyDest += "/";
+ copyDest += cmSystemTools::GetFilenameWithoutExtension(
+ this->OutputFile.c_str());
+ copyDest += "-";
+ copyDest += this->RunResultVariable;
+ copyDest += cmSystemTools::GetFilenameExtension(this->OutputFile.c_str());
+ cmSystemTools::CopyFileAlways(this->OutputFile.c_str(), copyDest.c_str());
+
+ std::string resultFileName = this->Makefile->GetHomeOutputDirectory();
+ resultFileName += "/TryRunResults.cmake";
+
+ std::string detailsString = "For details see ";
+ detailsString += resultFileName;
+
+ std::string internalRunOutputName=this->RunResultVariable+"__TRYRUN_OUTPUT";
+ bool error = false;
+
+ if (this->Makefile->GetDefinition(this->RunResultVariable.c_str()) == 0)
+ {
+ // if the variables doesn't exist, create it with a helpful error text
+ // and mark it as advanced
+ std::string comment;
+ 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(),
+ "PLEASE_FILL_OUT-FAILED_TO_RUN",
+ comment.c_str(),
+ cmCacheManager::STRING);
+
+ cmCacheManager::CacheIterator it = this->Makefile->GetCacheManager()->
+ GetCacheIterator(this->RunResultVariable.c_str());
+ if ( !it.IsAtEnd() )
+ {
+ it.SetProperty("ADVANCED", "1");
+ }
+
+ error = true;
+ }
+
+ // is the output from the executable used ?
+ if (out!=0)
+ {
+ if (this->Makefile->GetDefinition(internalRunOutputName.c_str()) == 0)
+ {
+ // if the variables doesn't exist, create it with a helpful error text
+ // and mark it as advanced
+ std::string comment;
+ comment+="Output of TRY_RUN(), contains the text, which the executable "
+ "would have printed on stdout and stderr on its target platform.\n";
+ comment += detailsString;
+
+ this->Makefile->AddCacheDefinition(internalRunOutputName.c_str(),
+ "PLEASE_FILL_OUT-NOTFOUND",
+ comment.c_str(),
+ cmCacheManager::STRING);
+ cmCacheManager::CacheIterator it = this->Makefile->GetCacheManager()->
+ GetCacheIterator(internalRunOutputName.c_str());
+ if ( !it.IsAtEnd() )
+ {
+ it.SetProperty("ADVANCED", "1");
+ }
+
+ error = true;
+ }
+ }
+
+ if (error)
+ {
+ static bool firstTryRun = true;
+ std::ofstream file(resultFileName.c_str(),
+ firstTryRun ? std::ios::out : std::ios::app);
+ if ( file )
+ {
+ if (firstTryRun)
+ {
+ file << "# This file was generated by CMake because it detected "
+ "TRY_RUN() commands\n"
+ "# in crosscompiling mode. It will be overwritten by the next "
+ "CMake run.\n"
+ "# Copy it to a safe location, set the variables to "
+ "appropriate values\n"
+ "# and use it then to preset the CMake cache (using -C).\n\n";
+ }
+
+ std::string comment ="\n";
+ comment += this->RunResultVariable;
+ comment += "\n indicates whether the executable would have been able "
+ "to run on its\n"
+ " target platform. If so, set ";
+ comment += this->RunResultVariable;
+ comment += " to\n"
+ " the exit code (in many cases 0 for success), otherwise "
+ "enter \"FAILED_TO_RUN\".\n";
+ if (out!=0)
+ {
+ comment += internalRunOutputName;
+ comment += "\n contains the text the executable "
+ "would have printed on stdout and stderr.\n"
+ " If the executable would not have been able to run, set ";
+ comment += internalRunOutputName;
+ comment += " empty.\n"
+ " Otherwise check if the output is evaluated by the "
+ "calling CMake code. If so,\n"
+ " check what the source file would have printed when "
+ "called with the given arguments.\n";
+ }
+ comment += "The ";
+ comment += this->CompileResultVariable;
+ comment += " variable holds the build result for this TRY_RUN().\n\n"
+ "Source file : ";
+ comment += srcFile + "\n";
+ comment += "Executable : ";
+ comment += copyDest + "\n";
+ comment += "Run arguments : ";
+ comment += runArgs;
+ comment += "\n";
+ comment += " Called from: " + this->Makefile->GetListFileStack();
+ cmsys::SystemTools::ReplaceString(comment, "\n", "\n# ");
+ file << comment << "\n\n";
+
+ file << "SET( " << this->RunResultVariable << " \n \""
+ << this->Makefile->GetDefinition(this->RunResultVariable.c_str())
+ << "\"\n CACHE STRING \"Result from TRY_RUN\" FORCE)\n\n";
+
+ if (out!=0)
+ {
+ file << "SET( " << internalRunOutputName << " \n \""
+ << this->Makefile->GetDefinition(internalRunOutputName.c_str())
+ << "\"\n CACHE STRING \"Output from TRY_RUN\" FORCE)\n\n";
+ }
+ file.close();
+ }
+ firstTryRun = false;
+
+ std::string errorMessage = "TRY_RUN() invoked in cross-compiling mode, "
+ "please set the following cache variables "
+ "appropriately:\n";
+ errorMessage += " " + this->RunResultVariable + " (advanced)\n";
+ if (out!=0)
+ {
+ errorMessage += " " + internalRunOutputName + " (advanced)\n";
+ }
+ errorMessage += detailsString;
+ cmSystemTools::Error(errorMessage.c_str());
+ return;
+ }
+
+ if (out!=0)
+ {
+ (*out) = this->Makefile->GetDefinition(internalRunOutputName.c_str());
+ }
+}
diff --git a/Source/cmTryRunCommand.h b/Source/cmTryRunCommand.h
new file mode 100644
index 000000000..06a9118b6
--- /dev/null
+++ b/Source/cmTryRunCommand.h
@@ -0,0 +1,118 @@
+/*============================================================================
+ 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 cmTryRunCommand_h
+#define cmTryRunCommand_h
+
+#include "cmCoreTryCompile.h"
+
+/** \class cmTryRunCommand
+ * \brief Specifies where to install some files
+ *
+ * cmTryRunCommand is used to test if soucre code can be compiled
+ */
+class cmTryRunCommand : public cmCoreTryCompile
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmTryRunCommand;
+ }
+
+ /**
+ * 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 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 would have 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."
+ ;
+ }
+
+ cmTypeMacro(cmTryRunCommand, cmCoreTryCompile);
+private:
+ void RunExecutable(const std::string& runArgs,
+ std::string* runOutputContents);
+ void DoNotRunExecutable(const std::string& runArgs,
+ const std::string& srcFile,
+ std::string* runOutputContents);
+
+ std::string CompileResultVariable;
+ std::string RunResultVariable;
+ std::string OutputVariable;
+ std::string RunOutputVariable;
+ std::string CompileOutputVariable;
+};
+
+
+#endif
diff --git a/Source/cmUnsetCommand.cxx b/Source/cmUnsetCommand.cxx
new file mode 100644
index 000000000..5c0cfaa03
--- /dev/null
+++ b/Source/cmUnsetCommand.cxx
@@ -0,0 +1,59 @@
+/*============================================================================
+ 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 "cmUnsetCommand.h"
+
+// cmUnsetCommand
+bool cmUnsetCommand::InitialPass(std::vector<std::string> const& args,
+ cmExecutionStatus &)
+{
+ if(args.size() < 1 || args.size() > 2)
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ const char* variable = args[0].c_str();
+
+ // unset(ENV{VAR})
+ if (!strncmp(variable,"ENV{",4) && strlen(variable) > 5)
+ {
+ // what is the variable name
+ char *envVarName = new char [strlen(variable)];
+ strncpy(envVarName,variable+4,strlen(variable)-5);
+ envVarName[strlen(variable)-5] = '\0';
+
+#ifdef CMAKE_BUILD_WITH_CMAKE
+ cmSystemTools::UnsetEnv(envVarName);
+#endif
+ delete[] envVarName;
+ return true;
+ }
+ // unset(VAR)
+ else if (args.size() == 1)
+ {
+ this->Makefile->RemoveDefinition(variable);
+ return true;
+ }
+ // unset(VAR CACHE)
+ else if ((args.size() == 2) && (args[1] == "CACHE"))
+ {
+ this->Makefile->RemoveCacheDefinition(variable);
+ return true;
+ }
+ // ERROR: second argument isn't CACHE
+ else
+ {
+ this->SetError("called with an invalid second argument");
+ return false;
+ }
+}
+
diff --git a/Source/cmUnsetCommand.h b/Source/cmUnsetCommand.h
new file mode 100644
index 000000000..9cf95d98d
--- /dev/null
+++ b/Source/cmUnsetCommand.h
@@ -0,0 +1,79 @@
+/*============================================================================
+ 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 cmUnsetCommand_h
+#define cmUnsetCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmUnsetCommand
+ * \brief Unset a CMAKE variable
+ *
+ * cmUnsetCommand unsets or removes a variable.
+ */
+class cmUnsetCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmUnsetCommand;
+ }
+
+ /**
+ * 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 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.";
+ }
+
+ cmTypeMacro(cmUnsetCommand, cmCommand);
+};
+
+
+
+#endif
diff --git a/Source/cmUseMangledMesaCommand.cxx b/Source/cmUseMangledMesaCommand.cxx
new file mode 100644
index 000000000..0e6f28aeb
--- /dev/null
+++ b/Source/cmUseMangledMesaCommand.cxx
@@ -0,0 +1,131 @@
+/*============================================================================
+ 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 "cmUseMangledMesaCommand.h"
+#include "cmSystemTools.h"
+
+#include <cmsys/RegularExpression.hxx>
+
+// cmUseMangledMesaCommand
+bool cmUseMangledMesaCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ // expected two arguments:
+ // arguement one: the full path to gl_mangle.h
+ // arguement two : directory for output of edited headers
+ if(args.size() != 2)
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+ const char* inputDir = args[0].c_str();
+ std::string glh = inputDir;
+ glh += "/";
+ glh += "gl.h";
+ if(!cmSystemTools::FileExists(glh.c_str()))
+ {
+ std::string e = "Bad path to Mesa, could not find: ";
+ e += glh;
+ e += " ";
+ this->SetError(e.c_str());
+ return false;
+ }
+ const char* destDir = args[1].c_str();
+ std::vector<std::string> files;
+ cmSystemTools::Glob(inputDir, "\\.h$", files);
+ if(files.size() == 0)
+ {
+ cmSystemTools::Error("Could not open Mesa Directory ", inputDir);
+ return false;
+ }
+ cmSystemTools::MakeDirectory(destDir);
+ for(std::vector<std::string>::iterator i = files.begin();
+ i != files.end(); ++i)
+ {
+ std::string path = inputDir;
+ path += "/";
+ path += *i;
+ this->CopyAndFullPathMesaHeader(path.c_str(), destDir);
+ }
+
+ return true;
+}
+
+void
+cmUseMangledMesaCommand::
+CopyAndFullPathMesaHeader(const char* source,
+ const char* outdir)
+{
+ std::string dir, file;
+ cmSystemTools::SplitProgramPath(source, dir, file);
+ std::string outFile = outdir;
+ outFile += "/";
+ outFile += file;
+ std::string tempOutputFile = outFile;
+ tempOutputFile += ".tmp";
+ std::ofstream fout(tempOutputFile.c_str());
+ if(!fout)
+ {
+ cmSystemTools::Error("Could not open file for write in copy operation: ",
+ tempOutputFile.c_str(), outdir);
+ cmSystemTools::ReportLastSystemError("");
+ return;
+ }
+ std::ifstream fin(source);
+ if(!fin)
+ {
+ cmSystemTools::Error("Could not open file for read in copy operation",
+ source);
+ return;
+ }
+ // now copy input to output and expand variables in the
+ // input file at the same time
+ std::string inLine;
+ // regular expression for any #include line
+ cmsys::RegularExpression includeLine(
+ "^[ \t]*#[ \t]*include[ \t]*[<\"]([^\">]+)[\">]");
+ // regular expression for gl/ or GL/ in a file (match(1) of above)
+ cmsys::RegularExpression glDirLine("(gl|GL)(/|\\\\)([^<\"]+)");
+ // regular expression for gl GL or xmesa in a file (match(1) of above)
+ cmsys::RegularExpression glLine("(gl|GL|xmesa)");
+ while(cmSystemTools::GetLineFromStream(fin,inLine))
+ {
+ if(includeLine.find(inLine.c_str()))
+ {
+ std::string includeFile = includeLine.match(1);
+ if(glDirLine.find(includeFile.c_str()))
+ {
+ std::string gfile = glDirLine.match(3);
+ fout << "#include \"" << outdir << "/" << gfile.c_str() << "\"\n";
+ }
+ else if(glLine.find(includeFile.c_str()))
+ {
+ fout << "#include \"" << outdir << "/" <<
+ includeLine.match(1).c_str() << "\"\n";
+ }
+ else
+ {
+ fout << inLine << "\n";
+ }
+ }
+ else
+ {
+ fout << inLine << "\n";
+ }
+ }
+ // close the files before attempting to copy
+ fin.close();
+ fout.close();
+ cmSystemTools::CopyFileIfDifferent(tempOutputFile.c_str(),
+ outFile.c_str());
+ cmSystemTools::RemoveFile(tempOutputFile.c_str());
+}
+
diff --git a/Source/cmUseMangledMesaCommand.h b/Source/cmUseMangledMesaCommand.h
new file mode 100644
index 000000000..2f52960c4
--- /dev/null
+++ b/Source/cmUseMangledMesaCommand.h
@@ -0,0 +1,88 @@
+/*============================================================================
+ 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 cmUseMangledMesaCommand_h
+#define cmUseMangledMesaCommand_h
+
+#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 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 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
new file mode 100644
index 000000000..41c82c2ba
--- /dev/null
+++ b/Source/cmUtilitySourceCommand.cxx
@@ -0,0 +1,127 @@
+/*============================================================================
+ 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 "cmUtilitySourceCommand.h"
+
+// cmUtilitySourceCommand
+bool cmUtilitySourceCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 3)
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ std::vector<std::string>::const_iterator arg = args.begin();
+
+ // The first argument is the cache entry name.
+ std::string cacheEntry = *arg++;
+ const char* cacheValue =
+ this->Makefile->GetDefinition(cacheEntry.c_str());
+ // 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.
+ const char* intDir =
+ this->Makefile->GetRequiredDefinition("CMAKE_CFG_INTDIR");
+
+ bool haveCacheValue = false;
+ if (this->Makefile->IsOn("CMAKE_CROSSCOMPILING"))
+ {
+ haveCacheValue = (cacheValue != 0);
+ if (!haveCacheValue)
+ {
+ std::string msg = "UTILITY_SOURCE is used in cross compiling mode for ";
+ msg += cacheEntry;
+ msg += ". If your intention is to run this executable, you need to "
+ "preload the cache with the full path to a version of that "
+ "program, which runs on this build machine.";
+ cmSystemTools::Message(msg.c_str() ,"Warning");
+ }
+ }
+ else
+ {
+ haveCacheValue = (cacheValue &&
+ (strstr(cacheValue, "(IntDir)") == 0 ||
+ (intDir && strcmp(intDir, "$(IntDir)") == 0)) &&
+ (this->Makefile->GetCacheMajorVersion() != 0 &&
+ this->Makefile->GetCacheMinorVersion() != 0 ));
+ }
+
+ if(haveCacheValue)
+ {
+ return true;
+ }
+
+ // The second argument is the utility's executable name, which will be
+ // needed later.
+ std::string utilityName = *arg++;
+
+ // The third argument specifies the relative directory of the source
+ // of the utility.
+ std::string relativeSource = *arg++;
+ std::string utilitySource = this->Makefile->GetCurrentDirectory();
+ utilitySource = utilitySource+"/"+relativeSource;
+
+ // If the directory doesn't exist, the source has not been included.
+ if(!cmSystemTools::FileExists(utilitySource.c_str()))
+ { return true; }
+
+ // Make sure all the files exist in the source directory.
+ while(arg != args.end())
+ {
+ std::string file = utilitySource+"/"+*arg++;
+ if(!cmSystemTools::FileExists(file.c_str()))
+ { return true; }
+ }
+
+ // The source exists.
+ std::string cmakeCFGout =
+ this->Makefile->GetRequiredDefinition("CMAKE_CFG_INTDIR");
+ std::string utilityDirectory = this->Makefile->GetCurrentOutputDirectory();
+ std::string exePath;
+ if (this->Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH"))
+ {
+ exePath = this->Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH");
+ }
+ if(exePath.size())
+ {
+ utilityDirectory = exePath;
+ }
+ else
+ {
+ utilityDirectory += "/"+relativeSource;
+ }
+
+ // Construct the cache entry for the executable's location.
+ std::string utilityExecutable =
+ utilityDirectory+"/"+cmakeCFGout+"/"
+ +utilityName+this->Makefile->GetDefinition("CMAKE_EXECUTABLE_SUFFIX");
+
+ // make sure we remove any /./ in the name
+ cmSystemTools::ReplaceString(utilityExecutable, "/./", "/");
+
+ // Enter the value into the cache.
+ this->Makefile->AddCacheDefinition(cacheEntry.c_str(),
+ utilityExecutable.c_str(),
+ "Path to an internal program.",
+ cmCacheManager::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(),
+ utilityName.c_str(),
+ "Executable to project name.",
+ cmCacheManager::INTERNAL);
+
+ return true;
+}
+
diff --git a/Source/cmUtilitySourceCommand.h b/Source/cmUtilitySourceCommand.h
new file mode 100644
index 000000000..32afddadc
--- /dev/null
+++ b/Source/cmUtilitySourceCommand.h
@@ -0,0 +1,90 @@
+/*============================================================================
+ 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 cmUtilitySourceCommand_h
+#define cmUtilitySourceCommand_h
+
+#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.
+ */
+ 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);
+};
+
+
+
+#endif
diff --git a/Source/cmVS10CLFlagTable.h b/Source/cmVS10CLFlagTable.h
new file mode 100644
index 000000000..a7b1b3651
--- /dev/null
+++ b/Source/cmVS10CLFlagTable.h
@@ -0,0 +1,270 @@
+static cmVS7FlagTable cmVS10CLFlagTable[] =
+{
+
+ //Enum Properties
+ {"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", "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},
+
+ {"EnableEnhancedInstructionSet", "arch:SSE",
+ "Streaming SIMD Extensions (/arch:SSE)", "StreamingSIMDExtensions", 0},
+ {"EnableEnhancedInstructionSet", "arch:SSE2",
+ "Streaming SIMD Extensions 2 (/arch:SSE2)", "StreamingSIMDExtensions2", 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},
+
+ {"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
+ {"SuppressStartupBanner", "nologo-", "", "false", 0},
+ {"SuppressStartupBanner", "nologo", "", "true", 0},
+ {"TreatWarningAsError", "WX-", "", "false", 0},
+ {"TreatWarningAsError", "WX", "", "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},
+ {"BufferSecurityCheck", "GS-", "", "false", 0},
+ {"BufferSecurityCheck", "GS", "", "true", 0},
+ {"FunctionLevelLinking", "Gy-", "", "false", 0},
+ {"FunctionLevelLinking", "Gy", "", "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},
+ {"ShowIncludes", "showIncludes", "", "true", 0},
+ {"EnablePREfast", "analyze-", "", "false", 0},
+ {"EnablePREfast", "analyze", "", "true", 0},
+ {"UseFullPaths", "FC", "", "true", 0},
+ {"OmitDefaultLibName", "Zl", "", "true", 0},
+ {"UseUnicodeForAssemblerListing", "FAu", "", "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",
+ "Resolve #using References",
+ "", 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},
+ {"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/cmVS10LibFlagTable.h b/Source/cmVS10LibFlagTable.h
new file mode 100644
index 000000000..79aeeff71
--- /dev/null
+++ b/Source/cmVS10LibFlagTable.h
@@ -0,0 +1,102 @@
+static cmVS7FlagTable cmVS10LibFlagTable[] =
+{
+
+ //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 [TrackerLogDirectory] - no command line Switch.
+ // Skip [AdditionalOptions] - no command line Switch.
+ {0,0,0,0,0}
+};
diff --git a/Source/cmVS10LinkFlagTable.h b/Source/cmVS10LinkFlagTable.h
new file mode 100644
index 000000000..c60e8eb20
--- /dev/null
+++ b/Source/cmVS10LinkFlagTable.h
@@ -0,0 +1,305 @@
+static cmVS7FlagTable cmVS10LinkFlagTable[] =
+{
+
+ //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:WINDOWSCE",
+ "WindowsCE", "WindowsCE", 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},
+
+ {"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},
+
+ {"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},
+ {"GenerateDebugInformation", "DEBUG", "", "true", 0},
+ {"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},
+ {"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},
+ {"DelaySign", "DELAYSIGN:NO", "", "false", 0},
+ {"DelaySign", "DELAYSIGN", "", "true", 0},
+ {"CLRUnmanagedCodeCheck", "CLRUNMANAGEDCODECHECK:NO", "", "false", 0},
+ {"CLRUnmanagedCodeCheck", "CLRUNMANAGEDCODECHECK", "", "true", 0},
+ {"ImageHasSafeExceptionHandlers", "SAFESEH:NO", "", "false", 0},
+ {"ImageHasSafeExceptionHandlers", "SAFESEH", "", "true", 0},
+ {"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:", "", "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},
+
+ //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},
+ {"EntryPointSymbol", "ENTRY:",
+ "Entry Point",
+ "", cmVS7FlagTable::UserValue},
+ {"BaseAddress", "BASE:",
+ "Base Address",
+ "", cmVS7FlagTable::UserValue},
+ {"ImportLibrary", "IMPLIB:",
+ "Import Library",
+ "", cmVS7FlagTable::UserValue},
+ {"MergeSections", "MERGE:",
+ "Merge Sections",
+ "", cmVS7FlagTable::UserValue},
+ {"KeyFile", "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/cmVariableRequiresCommand.cxx b/Source/cmVariableRequiresCommand.cxx
new file mode 100644
index 000000000..0e97a832a
--- /dev/null
+++ b/Source/cmVariableRequiresCommand.cxx
@@ -0,0 +1,76 @@
+/*============================================================================
+ 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 "cmVariableRequiresCommand.h"
+#include "cmCacheManager.h"
+
+// cmLibraryCommand
+bool cmVariableRequiresCommand
+::InitialPass(std::vector<std::string>const& args, cmExecutionStatus &)
+{
+ if(args.size() < 3 )
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ std::string testVariable = args[0];
+ if(!this->Makefile->IsOn(testVariable.c_str()))
+ {
+ return true;
+ }
+ std::string resultVariable = args[1];
+ bool requirementsMet = true;
+ std::string notSet;
+ bool hasAdvanced = false;
+ for(unsigned int i = 2; i < args.size(); ++i)
+ {
+ if(!this->Makefile->IsOn(args[i].c_str()))
+ {
+ requirementsMet = false;
+ notSet += args[i];
+ notSet += "\n";
+ cmCacheManager::CacheIterator it =
+ this->Makefile->GetCacheManager()->GetCacheIterator(args[i].c_str());
+ if(!it.IsAtEnd() && it.GetPropertyAsBool("ADVANCED"))
+ {
+ hasAdvanced = true;
+ }
+ }
+ }
+ const char* reqVar = this->Makefile->GetDefinition(resultVariable.c_str());
+ // 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);
+ }
+
+ if(!requirementsMet)
+ {
+ std::string message = "Variable assertion failed:\n";
+ message += testVariable +
+ " Requires that the following unset variables are set:\n";
+ message += notSet;
+ message += "\nPlease set them, or set ";
+ message += testVariable + " to false, and re-configure.\n";
+ if(hasAdvanced)
+ {
+ message +=
+ "One or more of the required variables is advanced."
+ " To set the variable, you must turn on advanced mode in cmake.";
+ }
+ cmSystemTools::Error(message.c_str());
+ }
+
+ return true;
+}
diff --git a/Source/cmVariableRequiresCommand.h b/Source/cmVariableRequiresCommand.h
new file mode 100644
index 000000000..91c351e60
--- /dev/null
+++ b/Source/cmVariableRequiresCommand.h
@@ -0,0 +1,82 @@
+/*============================================================================
+ 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 cmVariableRequiresCommand_h
+#define cmVariableRequiresCommand_h
+
+#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.
+ */
+ 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);
+};
+
+
+#endif
diff --git a/Source/cmVariableWatch.cxx b/Source/cmVariableWatch.cxx
new file mode 100644
index 000000000..47bab1530
--- /dev/null
+++ b/Source/cmVariableWatch.cxx
@@ -0,0 +1,93 @@
+/*============================================================================
+ 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 "cmVariableWatch.h"
+
+static const char* const cmVariableWatchAccessStrings[] =
+{
+ "READ_ACCESS",
+ "UNKNOWN_READ_ACCESS",
+ "ALLOWED_UNKNOWN_READ_ACCESS",
+ "MODIFIED_ACCESS",
+ "REMOVED_ACCESS",
+ "NO_ACCESS"
+};
+
+const char* cmVariableWatch::GetAccessAsString(int access_type)
+{
+ if ( access_type < 0 || access_type >= cmVariableWatch::NO_ACCESS )
+ {
+ return "NO_ACCESS";
+ }
+ return cmVariableWatchAccessStrings[access_type];
+}
+
+cmVariableWatch::cmVariableWatch()
+{
+}
+
+cmVariableWatch::~cmVariableWatch()
+{
+}
+
+void cmVariableWatch::AddWatch(const std::string& variable,
+ WatchMethod method, void* client_data /*=0*/)
+{
+ cmVariableWatch::Pair p;
+ p.Method = method;
+ p.ClientData = client_data;
+ cmVariableWatch::VectorOfPairs* vp = &this->WatchMap[variable];
+ cmVariableWatch::VectorOfPairs::size_type cc;
+ for ( cc = 0; cc < vp->size(); cc ++ )
+ {
+ cmVariableWatch::Pair* pair = &(*vp)[cc];
+ if ( pair->Method == method )
+ {
+ (*vp)[cc] = p;
+ return;
+ }
+ }
+ vp->push_back(p);
+}
+
+void cmVariableWatch::RemoveWatch(const std::string& variable,
+ WatchMethod method)
+{
+ cmVariableWatch::VectorOfPairs* vp = &this->WatchMap[variable];
+ cmVariableWatch::VectorOfPairs::iterator it;
+ for ( it = vp->begin(); it != vp->end(); ++it )
+ {
+ if ( it->Method == method )
+ {
+ vp->erase(it);
+ return;
+ }
+ }
+}
+
+void cmVariableWatch::VariableAccessed(const std::string& variable,
+ int access_type,
+ const char* newValue,
+ const cmMakefile* mf) const
+{
+ cmVariableWatch::StringToVectorOfPairs::const_iterator mit =
+ this->WatchMap.find(variable);
+ if ( mit != this->WatchMap.end() )
+ {
+ const cmVariableWatch::VectorOfPairs* vp = &mit->second;
+ cmVariableWatch::VectorOfPairs::const_iterator it;
+ for ( it = vp->begin(); it != vp->end(); it ++ )
+ {
+ it->Method(variable, access_type, it->ClientData,
+ newValue, mf);
+ }
+ }
+}
diff --git a/Source/cmVariableWatch.h b/Source/cmVariableWatch.h
new file mode 100644
index 000000000..83e9e9799
--- /dev/null
+++ b/Source/cmVariableWatch.h
@@ -0,0 +1,80 @@
+/*============================================================================
+ 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 cmVariableWatch_h
+#define cmVariableWatch_h
+
+#include "cmStandardIncludes.h"
+
+class cmMakefile;
+
+/** \class cmVariableWatch
+ * \brief Helper class for watching of variable accesses.
+ *
+ * Calls function when variable is accessed
+ */
+class cmVariableWatch
+{
+public:
+ typedef void (*WatchMethod)(const std::string& variable, int access_type,
+ void* client_data, const char* newValue, const cmMakefile* mf);
+
+ cmVariableWatch();
+ ~cmVariableWatch();
+
+ /**
+ * Add watch to the variable
+ */
+ void AddWatch(const std::string& variable, WatchMethod method,
+ void* client_data=0);
+ void RemoveWatch(const std::string& variable, WatchMethod method);
+
+ /**
+ * This method is called when variable is accessed
+ */
+ void VariableAccessed(const std::string& variable, int access_type,
+ const char* newValue, const cmMakefile* mf) const;
+
+ /**
+ * Different access types.
+ */
+ enum
+ {
+ 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
+ };
+
+ /**
+ * Return the access as string
+ */
+ static const char* GetAccessAsString(int access_type);
+
+protected:
+ struct Pair
+ {
+ WatchMethod Method;
+ void* ClientData;
+ Pair() : Method(0), ClientData(0) {}
+ };
+
+ typedef std::vector< Pair > VectorOfPairs;
+ typedef std::map<cmStdString, VectorOfPairs > StringToVectorOfPairs;
+
+ StringToVectorOfPairs WatchMap;
+};
+
+
+#endif
diff --git a/Source/cmVariableWatchCommand.cxx b/Source/cmVariableWatchCommand.cxx
new file mode 100644
index 000000000..93c05afb7
--- /dev/null
+++ b/Source/cmVariableWatchCommand.cxx
@@ -0,0 +1,140 @@
+/*============================================================================
+ 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 "cmVariableWatchCommand.h"
+
+#include "cmVariableWatch.h"
+
+//----------------------------------------------------------------------------
+static void cmVariableWatchCommandVariableAccessed(
+ const std::string& variable, int access_type, void* client_data,
+ const char* newValue, const cmMakefile* mf)
+{
+ cmVariableWatchCommand* command
+ = static_cast<cmVariableWatchCommand*>(client_data);
+ command->VariableAccessed(variable, access_type, newValue, mf);
+}
+
+//----------------------------------------------------------------------------
+cmVariableWatchCommand::cmVariableWatchCommand()
+{
+ this->InCallback = false;
+}
+
+//----------------------------------------------------------------------------
+bool cmVariableWatchCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if ( args.size() < 1 )
+ {
+ this->SetError("must be called with at least one argument.");
+ return false;
+ }
+ std::string variable = args[0];
+ if ( args.size() > 1 )
+ {
+ std::string command = args[1];
+ this->Handlers[variable].Commands.push_back(args[1]);
+ }
+ if ( variable == "CMAKE_CURRENT_LIST_FILE" )
+ {
+ cmOStringStream ostr;
+ ostr << "cannot be set on the variable: " << variable.c_str();
+ this->SetError(ostr.str().c_str());
+ return false;
+ }
+
+ this->Makefile->GetCMakeInstance()->GetVariableWatch()->AddWatch(
+ variable, cmVariableWatchCommandVariableAccessed, this);
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+void cmVariableWatchCommand::VariableAccessed(const std::string& variable,
+ int access_type, const char* newValue, const cmMakefile* mf)
+{
+ if ( this->InCallback )
+ {
+ return;
+ }
+ this->InCallback = true;
+
+ cmListFileFunction newLFF;
+ cmVariableWatchCommandHandler *handler = &this->Handlers[variable];
+ cmVariableWatchCommandHandler::VectorOfCommands::iterator it;
+ cmListFileArgument arg;
+ bool processed = false;
+ const char* accessString = cmVariableWatch::GetAccessAsString(access_type);
+ const char* currentListFile = mf->GetDefinition("CMAKE_CURRENT_LIST_FILE");
+
+ /// Ultra bad!!
+ cmMakefile* makefile = const_cast<cmMakefile*>(mf);
+
+ std::string stack = makefile->GetProperty("LISTFILE_STACK");
+ for ( it = handler->Commands.begin(); it != handler->Commands.end();
+ ++ it )
+ {
+ std::string command = *it;
+ newLFF.Arguments.clear();
+ newLFF.Arguments.push_back(
+ cmListFileArgument(variable, true, "unknown", 9999));
+ newLFF.Arguments.push_back(
+ cmListFileArgument(accessString, true, "unknown", 9999));
+ newLFF.Arguments.push_back(
+ cmListFileArgument(newValue?newValue:"", true, "unknown", 9999));
+ newLFF.Arguments.push_back(
+ cmListFileArgument(currentListFile, true, "unknown", 9999));
+ newLFF.Arguments.push_back(
+ cmListFileArgument(stack, true, "unknown", 9999));
+ newLFF.Name = 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"
+ << "A command failed during the invocation of callback\""
+ << command << "\".";
+ cmSystemTools::Error(error.str().c_str());
+ this->InCallback = false;
+ return;
+ }
+ processed = true;
+ }
+ if ( !processed )
+ {
+ cmOStringStream msg;
+ msg << "* Variable \"" << variable.c_str() << "\" was accessed using "
+ << accessString << " in: " << currentListFile << std::endl;
+ msg << " The value of the variable: \"" << newValue << "\"" << std::endl;
+ msg << " The list file stack: " << stack.c_str();
+ cmSystemTools::Message(msg.str().c_str());
+ std::vector<std::string> vars = makefile->GetDefinitions();
+ cmOStringStream msg2;
+ size_t cc;
+ for ( cc = 0; cc < vars.size(); cc ++ )
+ {
+ if ( vars[cc] == variable )
+ {
+ continue;
+ }
+ msg2 << vars[cc] << " = \""
+ << makefile->GetDefinition(vars[cc].c_str()) << "\"" << std::endl;
+ }
+ //cmSystemTools::Message(msg2.str().c_str());
+ }
+ this->InCallback = false;
+}
diff --git a/Source/cmVariableWatchCommand.h b/Source/cmVariableWatchCommand.h
new file mode 100644
index 000000000..cb80736e6
--- /dev/null
+++ b/Source/cmVariableWatchCommand.h
@@ -0,0 +1,98 @@
+/*============================================================================
+ 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 cmVariableWatchCommand_h
+#define cmVariableWatchCommand_h
+
+#include "cmCommand.h"
+
+class cmVariableWatchCommandHandler
+{
+public:
+ typedef std::vector<std::string> VectorOfCommands;
+ VectorOfCommands Commands;
+};
+
+/** \class cmVariableWatchCommand
+ * \brief Watch when the variable changes and invoke command
+ *
+ */
+class cmVariableWatchCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmVariableWatchCommand;
+ }
+
+ //! Default constructor
+ cmVariableWatchCommand();
+
+ /**
+ * 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; }
+
+ /** This command does not really have a final pass but it needs to
+ stay alive since it owns variable watch callback information. */
+ virtual bool HasFinalPass() const { return true; }
+
+ /**
+ * 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>)";
+ }
+
+ cmTypeMacro(cmVariableWatchCommand, cmCommand);
+
+ void VariableAccessed(const std::string& variable, int access_type,
+ const char* newValue, const cmMakefile* mf);
+
+protected:
+ std::map<std::string, cmVariableWatchCommandHandler> Handlers;
+
+ bool InCallback;
+};
+
+
+#endif
+
+
diff --git a/Source/cmVersion.cxx b/Source/cmVersion.cxx
new file mode 100644
index 000000000..047d24d74
--- /dev/null
+++ b/Source/cmVersion.cxx
@@ -0,0 +1,24 @@
+/*============================================================================
+ 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 "cmVersion.h"
+
+#include "cmVersionMacros.h"
+
+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; }
+
+const char* cmVersion::GetCMakeVersion()
+{
+ return CMake_VERSION;
+}
diff --git a/Source/cmVersion.h b/Source/cmVersion.h
new file mode 100644
index 000000000..e31352476
--- /dev/null
+++ b/Source/cmVersion.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 cmVersion_h
+#define cmVersion_h
+
+#include "cmStandardIncludes.h"
+
+/** \class cmVersion
+ * \brief Helper class for providing CMake and CTest version information.
+ *
+ * Finds all version related information.
+ */
+class cmVersion
+{
+public:
+ /**
+ * Return major and minor version numbers for cmake.
+ */
+ static unsigned int GetMajorVersion();
+ static unsigned int GetMinorVersion();
+ static unsigned int GetPatchVersion();
+ static unsigned int GetTweakVersion();
+ static const char* GetCMakeVersion();
+};
+
+#define CMake_VERSION_ENCODE(major, minor, patch) \
+ ((major)*0x10000u + (minor)*0x100u + (patch))
+
+#endif
+
diff --git a/Source/cmVersionConfig.h.in b/Source/cmVersionConfig.h.in
new file mode 100644
index 000000000..76bc8fe94
--- /dev/null
+++ b/Source/cmVersionConfig.h.in
@@ -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.
+============================================================================*/
+#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
new file mode 100644
index 000000000..67f58ca41
--- /dev/null
+++ b/Source/cmVersionMacros.h
@@ -0,0 +1,22 @@
+/*============================================================================
+ 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 cmVersionMacros_h
+#define cmVersionMacros_h
+
+#include "cmVersionConfig.h"
+
+#define CMake_VERSION_TWEAK_IS_RELEASE(tweak) ((tweak) < 20000000)
+#if CMake_VERSION_TWEAK_IS_RELEASE(CMake_VERSION_TWEAK)
+# define CMake_VERSION_IS_RELEASE 1
+#endif
+
+#endif
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
new file mode 100644
index 000000000..9a97ab0e3
--- /dev/null
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -0,0 +1,1684 @@
+/*============================================================================
+ 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 "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 "cmVS10CLFlagTable.h"
+#include "cmVS10LinkFlagTable.h"
+#include "cmVS10LibFlagTable.h"
+
+#include <cmsys/auto_ptr.hxx>
+
+static std::string cmVS10EscapeXML(std::string arg)
+{
+ cmSystemTools::ReplaceString(arg, "&", "&amp;");
+ cmSystemTools::ReplaceString(arg, "<", "&lt;");
+ cmSystemTools::ReplaceString(arg, ">", "&gt;");
+ return arg;
+}
+
+static std::string cmVS10EscapeComment(std::string comment)
+{
+ // MSBuild takes the CDATA of a <Message></Message> element and just
+ // does "echo $CDATA" with no escapes. We must encode the string.
+ // http://technet.microsoft.com/en-us/library/cc772462%28WS.10%29.aspx
+ std::string echoable;
+ for(std::string::iterator c = comment.begin(); c != comment.end(); ++c)
+ {
+ switch (*c)
+ {
+ case '\r': break;
+ case '\n': echoable += '\t'; break;
+ case '"': /* no break */
+ case '|': /* no break */
+ case '&': /* no break */
+ case '<': /* no break */
+ case '>': /* no break */
+ case '^': echoable += '^'; /* no break */
+ default: echoable += *c; break;
+ }
+ }
+ return echoable;
+}
+
+cmVisualStudio10TargetGenerator::
+cmVisualStudio10TargetGenerator(cmTarget* target,
+ cmGlobalVisualStudio10Generator* gg)
+{
+ this->GlobalGenerator = gg;
+ this->Target = target;
+ this->GeneratorTarget = gg->GetGeneratorTarget(target);
+ this->Makefile = target->GetMakefile();
+ this->LocalGenerator =
+ (cmLocalVisualStudio7Generator*)
+ this->Makefile->GetLocalGenerator();
+ this->Name = this->Target->GetName();
+ this->GlobalGenerator->CreateGUID(this->Name.c_str());
+ this->GUID = this->GlobalGenerator->GetGUID(this->Name.c_str());
+ this->Platform = gg->GetPlatformName();
+ this->BuildFileStream = 0;
+}
+
+cmVisualStudio10TargetGenerator::~cmVisualStudio10TargetGenerator()
+{
+ for(OptionsMap::iterator i = this->ClOptions.begin();
+ i != this->ClOptions.end(); ++i)
+ {
+ delete i->second;
+ }
+ if(!this->BuildFileStream)
+ {
+ return;
+ }
+ if (this->BuildFileStream->Close())
+ {
+ this->GlobalGenerator
+ ->FileReplacedDuringGenerate(this->PathToVcxproj);
+ }
+ delete this->BuildFileStream;
+}
+
+void cmVisualStudio10TargetGenerator::WritePlatformConfigTag(
+ const char* tag,
+ const char* config,
+ int indentLevel,
+ const char* attribute,
+ const char* end,
+ std::ostream* stream)
+
+{
+ if(!stream)
+ {
+ stream = this->BuildFileStream;
+ }
+ stream->fill(' ');
+ stream->width(indentLevel*2 );
+ (*stream ) << "";
+ (*stream ) << "<" << tag
+ << " Condition=\"'$(Configuration)|$(Platform)'=='";
+ (*stream ) << config << "|" << this->Platform << "'\"";
+ if(attribute)
+ {
+ (*stream ) << attribute;
+ }
+ // close the tag
+ (*stream ) << ">";
+ if(end)
+ {
+ (*stream ) << end;
+ }
+}
+
+void cmVisualStudio10TargetGenerator::WriteString(const char* line,
+ int indentLevel)
+{
+ this->BuildFileStream->fill(' ');
+ this->BuildFileStream->width(indentLevel*2 );
+ // write an empty string to get the fill level indent to print
+ (*this->BuildFileStream ) << "";
+ (*this->BuildFileStream ) << line;
+}
+
+#define VS10_USER_PROPS "$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props"
+
+void cmVisualStudio10TargetGenerator::Generate()
+{
+ // do not generate external ms projects
+ if(this->Target->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",
+ ".vcxproj");
+ if(this->Target->GetType() <= cmTarget::OBJECT_LIBRARY)
+ {
+ if(!this->ComputeClOptions())
+ {
+ return;
+ }
+ }
+ cmMakefile* mf = this->Target->GetMakefile();
+ std::string path = mf->GetStartOutputDirectory();
+ path += "/";
+ path += this->Name;
+ path += ".vcxproj";
+ this->BuildFileStream =
+ new cmGeneratedFileStream(path.c_str());
+ this->PathToVcxproj = path;
+ this->BuildFileStream->SetCopyIfDifferent(true);
+
+ // Write the encoding header into the file
+ char magic[] = {0xEF,0xBB, 0xBF};
+ this->BuildFileStream->write(magic, 3);
+ this->WriteString("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n",0);
+ this->WriteString("<Project DefaultTargets=\"Build\" "
+ "ToolsVersion=\"4.0\" "
+ "xmlns=\"http://schemas.microsoft.com/"
+ "developer/msbuild/2003\">\n",
+ 0);
+ this->WriteProjectConfigurations();
+ this->WriteString("<PropertyGroup Label=\"Globals\">\n", 1);
+ this->WriteString("<ProjectGUID>", 2);
+ (*this->BuildFileStream) << "{" << this->GUID << "}</ProjectGUID>\n";
+
+ const char* vsProjectTypes =
+ this->Target->GetProperty("VS_GLOBAL_PROJECT_TYPES");
+ if(vsProjectTypes)
+ {
+ this->WriteString("<ProjectTypes>", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(vsProjectTypes) <<
+ "</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");
+
+ if( vsProjectName && vsLocalPath && vsProvider )
+ {
+ this->WriteString("<SccProjectName>", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(vsProjectName) <<
+ "</SccProjectName>\n";
+ this->WriteString("<SccLocalPath>", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(vsLocalPath) <<
+ "</SccLocalPath>\n";
+ this->WriteString("<SccProvider>", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(vsProvider) <<
+ "</SccProvider>\n";
+
+ const char* vsAuxPath = this->Target->GetProperty("VS_SCC_AUXPATH");
+ if( vsAuxPath )
+ {
+ this->WriteString("<SccAuxPath>", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(vsAuxPath) <<
+ "</SccAuxPath>\n";
+ }
+ }
+
+ const char* vsGlobalKeyword =
+ this->Target->GetProperty("VS_GLOBAL_KEYWORD");
+ if(!vsGlobalKeyword)
+ {
+ this->WriteString("<Keyword>Win32Proj</Keyword>\n", 2);
+ }
+ else
+ {
+ this->WriteString("<Keyword>", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(vsGlobalKeyword) <<
+ "</Keyword>\n";
+ }
+
+ this->WriteString("<Platform>", 2);
+ (*this->BuildFileStream) << this->Platform << "</Platform>\n";
+ const char* projLabel = this->Target->GetProperty("PROJECT_LABEL");
+ if(!projLabel)
+ {
+ projLabel = this->Name.c_str();
+ }
+ this->WriteString("<ProjectName>", 2);
+ (*this->BuildFileStream) << projLabel << "</ProjectName>\n";
+ this->WriteString("</PropertyGroup>\n", 1);
+ this->WriteString("<Import Project="
+ "\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n",
+ 1);
+ this->WriteProjectConfigurationValues();
+ this->WriteString(
+ "<Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n", 1);
+ this->WriteString("<ImportGroup Label=\"ExtensionSettings\">\n", 1);
+ this->WriteString("</ImportGroup>\n", 1);
+ this->WriteString("<ImportGroup Label=\"PropertySheets\">\n", 1);
+ this->WriteString("<Import Project=\"" VS10_USER_PROPS "\""
+ " Condition=\"exists('" VS10_USER_PROPS "')\""
+ " Label=\"LocalAppDataPlatform\" />", 2);
+ this->WriteString("</ImportGroup>\n", 1);
+ this->WriteString("<PropertyGroup Label=\"UserMacros\" />\n", 1);
+ this->WritePathAndIncrementalLinkOptions();
+ this->WriteItemDefinitionGroups();
+ this->WriteCustomCommands();
+ this->WriteAllSources();
+ this->WriteDotNetReferences();
+ this->WriteWinRTReferences();
+ this->WriteProjectReferences();
+ this->WriteString(
+ "<Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\""
+ " />\n", 1);
+ this->WriteString("<ImportGroup Label=\"ExtensionTargets\">\n", 1);
+ this->WriteString("</ImportGroup>\n", 1);
+ this->WriteString("</Project>", 0);
+ // The groups are stored in a separate file for VS 10
+ this->WriteGroups();
+}
+
+void cmVisualStudio10TargetGenerator::WriteDotNetReferences()
+{
+ std::vector<std::string> references;
+ if(const char* vsDotNetReferences =
+ this->Target->GetProperty("VS_DOTNET_REFERENCES"))
+ {
+ cmSystemTools::ExpandListArgument(vsDotNetReferences, references);
+ }
+ if(!references.empty())
+ {
+ this->WriteString("<ItemGroup>\n", 1);
+ for(std::vector<std::string>::iterator ri = references.begin();
+ ri != references.end(); ++ri)
+ {
+ this->WriteString("<Reference Include=\"", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(*ri) << "\">\n";
+ this->WriteString("<CopyLocalSatelliteAssemblies>true"
+ "</CopyLocalSatelliteAssemblies>\n", 3);
+ this->WriteString("<ReferenceOutputAssembly>true"
+ "</ReferenceOutputAssembly>\n", 3);
+ this->WriteString("</Reference>\n", 2);
+ }
+ this->WriteString("</ItemGroup>\n", 1);
+ }
+}
+
+void cmVisualStudio10TargetGenerator::WriteWinRTReferences()
+{
+ std::vector<std::string> references;
+ if(const char* vsWinRTReferences =
+ this->Target->GetProperty("VS_WINRT_REFERENCES"))
+ {
+ cmSystemTools::ExpandListArgument(vsWinRTReferences, references);
+ }
+ if(!references.empty())
+ {
+ this->WriteString("<ItemGroup>\n", 1);
+ for(std::vector<std::string>::iterator ri = references.begin();
+ ri != references.end(); ++ri)
+ {
+ this->WriteString("<Reference Include=\"", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(*ri) << "\">\n";
+ this->WriteString("<IsWinMDFile>true</IsWinMDFile>\n", 3);
+ this->WriteString("</Reference>\n", 2);
+ }
+ this->WriteString("</ItemGroup>\n", 1);
+ }
+}
+
+// ConfigurationType Application, Utility StaticLibrary DynamicLibrary
+
+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)
+ {
+ 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->WriteString("</ProjectConfiguration>\n", 2);
+ }
+ this->WriteString("</ItemGroup>\n", 1);
+}
+
+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)
+ {
+ this->WritePlatformConfigTag("PropertyGroup",
+ i->c_str(),
+ 1, " Label=\"Configuration\"", "\n");
+ std::string configType = "<ConfigurationType>";
+ switch(this->Target->GetType())
+ {
+ case cmTarget::SHARED_LIBRARY:
+ case cmTarget::MODULE_LIBRARY:
+ configType += "DynamicLibrary";
+ break;
+ case cmTarget::OBJECT_LIBRARY:
+ case cmTarget::STATIC_LIBRARY:
+ configType += "StaticLibrary";
+ break;
+ case cmTarget::EXECUTABLE:
+ configType += "Application";
+ break;
+ case cmTarget::UTILITY:
+ configType += "Utility";
+ 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";
+
+ std::string useOfMfcValue = "false";
+ if(mfcFlagValue == "1")
+ {
+ useOfMfcValue = "Static";
+ }
+ else if(mfcFlagValue == "2")
+ {
+ useOfMfcValue = "Dynamic";
+ }
+ 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("<Immersive>true</Immersive>\n", 2);
+ }
+ this->WriteString("</PropertyGroup>\n", 1);
+ }
+}
+
+void cmVisualStudio10TargetGenerator::WriteCustomCommands()
+{
+ this->SourcesVisited.clear();
+ for(std::vector<cmSourceFile*>::const_iterator
+ si = this->GeneratorTarget->CustomCommands.begin();
+ si != this->GeneratorTarget->CustomCommands.end(); ++si)
+ {
+ this->WriteCustomCommand(*si);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmVisualStudio10TargetGenerator::WriteCustomCommand(cmSourceFile* sf)
+{
+ if(this->SourcesVisited.insert(sf).second)
+ {
+ if(std::vector<cmSourceFile*> const* depends =
+ this->Target->GetSourceDepends(sf))
+ {
+ for(std::vector<cmSourceFile*>::const_iterator di = depends->begin();
+ di != depends->end(); ++di)
+ {
+ this->WriteCustomCommand(*di);
+ }
+ }
+ if(cmCustomCommand const* command = sf->GetCustomCommand())
+ {
+ this->WriteString("<ItemGroup>\n", 1);
+ this->WriteCustomRule(sf, *command);
+ this->WriteString("</ItemGroup>\n", 1);
+ }
+ }
+}
+
+void
+cmVisualStudio10TargetGenerator::WriteCustomRule(cmSourceFile* source,
+ cmCustomCommand const &
+ command)
+{
+ std::string sourcePath = source->GetFullPath();
+ // VS 10 will always rebuild a custom command attached to a .rule
+ // file that doesn't exist so create the file explicitly.
+ if (source->GetPropertyAsBool("__CMAKE_RULE"))
+ {
+ if(!cmSystemTools::FileExists(sourcePath.c_str()))
+ {
+ // 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());
+ if(fout)
+ {
+ fout << "# generated from CMake\n";
+ fout.flush();
+ fout.close();
+ }
+ else
+ {
+ std::string error = "Could not create file: [";
+ error += sourcePath;
+ error += "] ";
+ cmSystemTools::Error
+ (error.c_str(), cmSystemTools::GetLastSystemError().c_str());
+ }
+ }
+ }
+ 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)
+ {
+ std::string script =
+ cmVS10EscapeXML(lg->ConstructScript(command, i->c_str()));
+ 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();
+ for(std::vector<std::string>::const_iterator d =
+ command.GetDepends().begin();
+ d != command.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 ) << ";%(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();
+ ++o)
+ {
+ std::string out = *o;
+ this->ConvertToWindowsSlash(out);
+ (*this->BuildFileStream ) << sep << out;
+ sep = ";";
+ }
+ (*this->BuildFileStream ) << "</Outputs>\n";
+ }
+ this->WriteString("</CustomBuild>\n", 2);
+}
+
+std::string
+cmVisualStudio10TargetGenerator::ConvertPath(std::string const& path,
+ bool forceRelative)
+{
+ return forceRelative
+ ? cmSystemTools::RelativePath(
+ this->Makefile->GetCurrentOutputDirectory(), path.c_str())
+ : this->LocalGenerator->Convert(path.c_str(),
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::UNCHANGED);
+}
+
+void cmVisualStudio10TargetGenerator::ConvertToWindowsSlash(std::string& s)
+{
+ // first convert all of the slashes
+ std::string::size_type pos = 0;
+ while((pos = s.find('/', pos)) != std::string::npos)
+ {
+ s[pos] = '\\';
+ pos++;
+ }
+}
+void cmVisualStudio10TargetGenerator::WriteGroups()
+{
+ // collect up group information
+ std::vector<cmSourceGroup> sourceGroups =
+ this->Makefile->GetSourceGroups();
+ std::vector<cmSourceFile*> classes = this->Target->GetSourceFiles();
+
+ std::set<cmSourceGroup*> groupsUsed;
+ for(std::vector<cmSourceFile*>::const_iterator s = classes.begin();
+ s != classes.end(); s++)
+ {
+ cmSourceFile* sf = *s;
+ std::string const& source = sf->GetFullPath();
+ cmSourceGroup& sourceGroup =
+ this->Makefile->FindSourceGroup(source.c_str(), sourceGroups);
+ groupsUsed.insert(&sourceGroup);
+ }
+
+ this->AddMissingSourceGroups(groupsUsed, sourceGroups);
+
+ // Write out group file
+ std::string path = this->Makefile->GetStartOutputDirectory();
+ path += "/";
+ path += this->Name;
+ path += ".vcxproj.filters";
+ cmGeneratedFileStream fout(path.c_str());
+ fout.SetCopyIfDifferent(true);
+ char magic[] = {0xEF,0xBB, 0xBF};
+ fout.write(magic, 3);
+ cmGeneratedFileStream* save = this->BuildFileStream;
+ this->BuildFileStream = & fout;
+ this->WriteString("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+ "<Project "
+ "ToolsVersion=\"4.0\" "
+ "xmlns=\"http://schemas.microsoft.com/"
+ "developer/msbuild/2003\">\n",
+ 0);
+ for(ToolSourceMap::const_iterator ti = this->Tools.begin();
+ ti != this->Tools.end(); ++ti)
+ {
+ this->WriteGroupSources(ti->first.c_str(), ti->second, sourceGroups);
+ }
+
+ // Add object library contents as external objects.
+ std::vector<std::string> objs;
+ this->GeneratorTarget->UseObjectLibraries(objs);
+ if(!objs.empty())
+ {
+ this->WriteString("<ItemGroup>\n", 1);
+ 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->WriteString("<Filter>Object Libraries</Filter>\n", 3);
+ this->WriteString("</Object>\n", 2);
+ }
+ this->WriteString("</ItemGroup>\n", 1);
+ }
+
+ this->WriteString("<ItemGroup>\n", 1);
+ for(std::set<cmSourceGroup*>::iterator g = groupsUsed.begin();
+ g != groupsUsed.end(); ++g)
+ {
+ cmSourceGroup* sg = *g;
+ const char* name = sg->GetFullName();
+ if(strlen(name) != 0)
+ {
+ this->WriteString("<Filter Include=\"", 2);
+ (*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());
+ (*this->BuildFileStream)
+ << "{"
+ << guid << "}"
+ << "</UniqueIdentifier>\n";
+ this->WriteString("</Filter>\n", 2);
+ }
+ }
+ if(!objs.empty())
+ {
+ 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());
+ (*this->BuildFileStream) << "{" << guid << "}"
+ << "</UniqueIdentifier>\n";
+ this->WriteString("</Filter>\n", 2);
+ }
+ this->WriteString("</ItemGroup>\n", 1);
+ this->WriteString("</Project>\n", 0);
+ // restore stream pointer
+ this->BuildFileStream = save;
+
+ if (fout.Close())
+ {
+ this->GlobalGenerator->FileReplacedDuringGenerate(path);
+ }
+}
+
+// Add to groupsUsed empty source groups that have non-empty children.
+void
+cmVisualStudio10TargetGenerator::AddMissingSourceGroups(
+ std::set<cmSourceGroup*>& groupsUsed,
+ const std::vector<cmSourceGroup>& allGroups
+ )
+{
+ for(std::vector<cmSourceGroup>::const_iterator current = allGroups.begin();
+ current != allGroups.end(); ++current)
+ {
+ std::vector<cmSourceGroup> const& children = current->GetGroupChildren();
+ if(children.empty())
+ {
+ continue; // the group is really empty
+ }
+
+ this->AddMissingSourceGroups(groupsUsed, children);
+
+ cmSourceGroup* current_ptr = const_cast<cmSourceGroup*>(&(*current));
+ if(groupsUsed.find(current_ptr) != groupsUsed.end())
+ {
+ continue; // group has already been added to set
+ }
+
+ // check if it least one of the group's descendants is not empty
+ // (at least one child must already have been added)
+ std::vector<cmSourceGroup>::const_iterator child_it = children.begin();
+ while(child_it != children.end())
+ {
+ cmSourceGroup* child_ptr = const_cast<cmSourceGroup*>(&(*child_it));
+ if(groupsUsed.find(child_ptr) != groupsUsed.end())
+ {
+ break; // found a child that was already added => add current group too
+ }
+ child_it++;
+ }
+
+ if(child_it == children.end())
+ {
+ continue; // no descendants have source files => ignore this group
+ }
+
+ groupsUsed.insert(current_ptr);
+ }
+}
+
+void
+cmVisualStudio10TargetGenerator::
+WriteGroupSources(const char* name,
+ ToolSources const& sources,
+ std::vector<cmSourceGroup>& sourceGroups)
+{
+ this->WriteString("<ItemGroup>\n", 1);
+ for(ToolSources::const_iterator s = sources.begin();
+ s != sources.end(); ++s)
+ {
+ cmSourceFile* sf = s->SourceFile;
+ std::string const& source = sf->GetFullPath();
+ cmSourceGroup& sourceGroup =
+ this->Makefile->FindSourceGroup(source.c_str(), sourceGroups);
+ const char* filter = sourceGroup.GetFullName();
+ this->WriteString("<", 2);
+ std::string path = this->ConvertPath(source, s->RelativePath);
+ this->ConvertToWindowsSlash(path);
+ (*this->BuildFileStream) << name << " Include=\""
+ << path;
+ if(strlen(filter))
+ {
+ (*this->BuildFileStream) << "\">\n";
+ this->WriteString("<Filter>", 3);
+ (*this->BuildFileStream) << filter << "</Filter>\n";
+ this->WriteString("</", 2);
+ (*this->BuildFileStream) << name << ">\n";
+ }
+ else
+ {
+ (*this->BuildFileStream) << "\" />\n";
+ }
+ }
+ this->WriteString("</ItemGroup>\n", 1);
+}
+
+void cmVisualStudio10TargetGenerator::WriteSource(
+ const char* tool, cmSourceFile* 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.
+ bool forceRelative = false;
+ std::string sourceFile = this->ConvertPath(sf->GetFullPath(), false);
+ if(this->LocalGenerator->GetVersion() == cmLocalVisualStudioGenerator::VS10
+ && cmSystemTools::FileIsFullPath(sourceFile.c_str()))
+ {
+ // Normal path conversion resulted in a full path. VS 10 (but not 11)
+ // refuses to show the property page in the IDE for a source file with a
+ // full path (not starting in a '.' or '/' AFAICT). CMake <= 2.8.4 used a
+ // relative path but to allow deeper build trees CMake 2.8.[5678] used a
+ // full path except for custom commands. Custom commands do not work
+ // without a relative path, but they do not seem to be involved in tools
+ // with the above behavior. For other sources we now use a relative path
+ // when the combined path will not be too long so property pages appear.
+ std::string sourceRel = this->ConvertPath(sf->GetFullPath(), true);
+ size_t const maxLen = 250;
+ if(sf->GetCustomCommand() ||
+ ((strlen(this->Makefile->GetCurrentOutputDirectory()) + 1 +
+ sourceRel.length()) <= maxLen))
+ {
+ forceRelative = true;
+ sourceFile = sourceRel;
+ }
+ else
+ {
+ this->GlobalGenerator->PathTooLong(this->Target, sf, sourceRel);
+ }
+ }
+ this->ConvertToWindowsSlash(sourceFile);
+ this->WriteString("<", 2);
+ (*this->BuildFileStream ) << tool <<
+ " Include=\"" << 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)
+{
+ for(std::vector<cmSourceFile*>::const_iterator
+ si = sources.begin(); si != sources.end(); ++si)
+ {
+ this->WriteSource(tool, *si);
+ }
+}
+
+void cmVisualStudio10TargetGenerator::WriteAllSources()
+{
+ if(this->Target->GetType() > cmTarget::UTILITY)
+ {
+ return;
+ }
+ this->WriteString("<ItemGroup>\n", 1);
+
+ this->WriteSources("ClInclude", this->GeneratorTarget->HeaderSources);
+ this->WriteSources("Midl", this->GeneratorTarget->IDLSources);
+
+ for(std::vector<cmSourceFile*>::const_iterator
+ si = this->GeneratorTarget->ObjectSources.begin();
+ si != this->GeneratorTarget->ObjectSources.end(); ++si)
+ {
+ const char* lang = (*si)->GetLanguage();
+ bool cl = strcmp(lang, "C") == 0 || strcmp(lang, "CXX") == 0;
+ bool rc = strcmp(lang, "RC") == 0;
+ const char* tool = cl? "ClCompile" : (rc? "ResourceCompile" : "None");
+ this->WriteSource(tool, *si, " ");
+ // ouput any flags specific to this source file
+ if(cl && this->OutputSourceSpecificFlags(*si))
+ {
+ // if the source file has specific flags the tag
+ // is ended on a new line
+ this->WriteString("</ClCompile>\n", 2);
+ }
+ else if(rc && this->OutputSourceSpecificFlags(*si))
+ {
+ this->WriteString("</ResourceCompile>\n", 2);
+ }
+ else
+ {
+ (*this->BuildFileStream ) << " />\n";
+ }
+ }
+
+ for(std::vector<cmSourceFile*>::const_iterator
+ si = this->GeneratorTarget->ExternalObjects.begin();
+ si != this->GeneratorTarget->ExternalObjects.end(); ++si)
+ {
+ // 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.
+ std::vector<cmSourceFile*> const* d = this->Target->GetSourceDepends(*si);
+ this->WriteSource((d && !d->empty())? "None":"Object", *si);
+ }
+
+ this->WriteSources("None", this->GeneratorTarget->ExtraSources);
+
+ // Add object library contents as external objects.
+ std::vector<std::string> 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->WriteString("</ItemGroup>\n", 1);
+}
+
+bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
+ cmSourceFile* source)
+{
+ cmSourceFile& sf = *source;
+ cmLocalVisualStudio7Generator* lg = this->LocalGenerator;
+
+ std::string objectName;
+ if(this->GeneratorTarget->ExplicitObjectName.find(&sf)
+ != this->GeneratorTarget->ExplicitObjectName.end())
+ {
+ objectName = this->GeneratorTarget->Objects[&sf];
+ }
+ std::string flags;
+ std::string defines;
+ if(const char* cflags = sf.GetProperty("COMPILE_FLAGS"))
+ {
+ flags += cflags;
+ }
+ if(const char* cdefs = sf.GetProperty("COMPILE_DEFINITIONS"))
+ {
+ defines += cdefs;
+ }
+ const char* lang =
+ this->GlobalGenerator->GetLanguageFromExtension
+ (sf.GetExtension().c_str());
+ const char* sourceLang = this->LocalGenerator->GetSourceFileLanguage(sf);
+ const char* linkLanguage = this->Target->GetLinkerLanguage();
+ bool needForceLang = false;
+ // source file does not match its extension language
+ if(lang && sourceLang && strcmp(lang, sourceLang) != 0)
+ {
+ 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))
+ {
+ if(strcmp(lang, "CXX") == 0)
+ {
+ // force a C++ file type
+ flags += " /TP ";
+ }
+ else if(strcmp(lang, "C") == 0)
+ {
+ // force to c
+ flags += " /TC ";
+ }
+ }
+ 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())
+ {
+ (*this->BuildFileStream ) << firstString;
+ firstString = "";
+ hasFlags = true;
+ this->WriteString("<ObjectFileName>", 3);
+ (*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)
+ {
+ std::string configUpper = cmSystemTools::UpperCase(*config);
+ std::string configDefines = defines;
+ std::string defPropName = "COMPILE_DEFINITIONS_";
+ defPropName += configUpper;
+ if(const char* ccdefs = sf.GetProperty(defPropName.c_str()))
+ {
+ if(configDefines.size())
+ {
+ configDefines += ";";
+ }
+ configDefines += ccdefs;
+ }
+ // if we have flags or defines for this config then
+ // use them
+ if(flags.size() || configDefines.size())
+ {
+ (*this->BuildFileStream ) << firstString;
+ firstString = ""; // only do firstString once
+ hasFlags = true;
+ cmVisualStudioGeneratorOptions
+ clOptions(this->LocalGenerator,
+ cmVisualStudioGeneratorOptions::Compiler,
+ cmVS10CLFlagTable, 0, this);
+ clOptions.Parse(flags.c_str());
+ clOptions.AddDefines(configDefines.c_str());
+ clOptions.SetConfiguration((*config).c_str());
+ clOptions.OutputAdditionalOptions(*this->BuildFileStream, " ", "");
+ clOptions.OutputFlagMap(*this->BuildFileStream, " ");
+ clOptions.OutputPreprocessorDefinitions(*this->BuildFileStream,
+ " ", "\n", lang);
+ }
+ }
+ return hasFlags;
+}
+
+
+void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions()
+{
+ cmTarget::TargetType ttype = this->Target->GetType();
+ if(ttype > cmTarget::GLOBAL_TARGET)
+ {
+ return;
+ }
+
+ 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)
+ {
+ if(ttype >= cmTarget::UTILITY)
+ {
+ this->WritePlatformConfigTag("IntDir", config->c_str(), 3);
+ *this->BuildFileStream
+ << "$(Platform)\\$(Configuration)\\$(ProjectName)\\"
+ << "</IntDir>\n";
+ }
+ else
+ {
+ std::string intermediateDir = this->LocalGenerator->
+ GetTargetDirectory(*this->Target);
+ intermediateDir += "/";
+ intermediateDir += *config;
+ intermediateDir += "/";
+ std::string outDir;
+ std::string targetNameFull;
+ if(ttype == cmTarget::OBJECT_LIBRARY)
+ {
+ outDir = intermediateDir;
+ targetNameFull = this->Target->GetName();
+ targetNameFull += ".lib";
+ }
+ else
+ {
+ outDir = this->Target->GetDirectory(config->c_str()) + "/";
+ targetNameFull = this->Target->GetFullName(config->c_str());
+ }
+ this->ConvertToWindowsSlash(intermediateDir);
+ this->ConvertToWindowsSlash(outDir);
+
+ this->WritePlatformConfigTag("OutDir", config->c_str(), 3);
+ *this->BuildFileStream << outDir
+ << "</OutDir>\n";
+
+ this->WritePlatformConfigTag("IntDir", config->c_str(), 3);
+ *this->BuildFileStream << intermediateDir
+ << "</IntDir>\n";
+
+ this->WritePlatformConfigTag("TargetName", config->c_str(), 3);
+ *this->BuildFileStream
+ << cmSystemTools::GetFilenameWithoutLastExtension(
+ targetNameFull.c_str())
+ << "</TargetName>\n";
+
+ this->WritePlatformConfigTag("TargetExt", config->c_str(), 3);
+ *this->BuildFileStream
+ << cmSystemTools::GetFilenameLastExtension(targetNameFull.c_str())
+ << "</TargetExt>\n";
+
+ this->OutputLinkIncremental(*config);
+ }
+ }
+ this->WriteString("</PropertyGroup>\n", 2);
+}
+
+
+
+void
+cmVisualStudio10TargetGenerator::
+OutputLinkIncremental(std::string const& configName)
+{
+ std::string CONFIG = cmSystemTools::UpperCase(configName);
+ // 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)
+ {
+ return;
+ }
+ const char* linkType = "SHARED";
+ if(this->Target->GetType() == cmTarget::EXECUTABLE)
+ {
+ linkType = "EXE";
+ }
+
+ // assume incremental linking
+ const char* incremental = "true";
+ 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;
+ }
+ std::string linkFlagVarBase = "CMAKE_";
+ linkFlagVarBase += linkType;
+ linkFlagVarBase += "_LINKER_FLAGS";
+ std::string flags = this->
+ Target->GetMakefile()->GetRequiredDefinition(linkFlagVarBase.c_str());
+ std::string linkFlagVar = linkFlagVarBase + "_" + CONFIG;
+ flags += this->
+ Target->GetMakefile()->GetRequiredDefinition(linkFlagVar.c_str());
+ 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("_") + CONFIG;
+ flags +=
+ Target->GetMakefile()->GetRequiredDefinition(flagVar.c_str());
+ }
+ const char* targetLinkFlags = this->Target->GetProperty("LINK_FLAGS");
+ if(targetLinkFlags)
+ {
+ flags += " ";
+ flags += targetLinkFlags;
+ }
+ std::string flagsProp = "LINK_FLAGS_";
+ flagsProp += CONFIG;
+ if(const char* flagsConfig = this->Target->GetProperty(flagsProp.c_str()))
+ {
+ flags += " ";
+ flags += flagsConfig;
+ }
+ if(flags.find("INCREMENTAL:NO") != flags.npos)
+ {
+ incremental = "false";
+ }
+ this->WritePlatformConfigTag("LinkIncremental", configName.c_str(), 3);
+ *this->BuildFileStream << incremental
+ << "</LinkIncremental>\n";
+
+ const char* manifest = "true";
+ if(flags.find("MANIFEST:NO") != flags.npos)
+ {
+ manifest = "false";
+ }
+ this->WritePlatformConfigTag("GenerateManifest", configName.c_str(), 3);
+ *this->BuildFileStream << manifest
+ << "</GenerateManifest>\n";
+}
+
+//----------------------------------------------------------------------------
+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)
+ {
+ if(!this->ComputeClOptions(*i))
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmVisualStudio10TargetGenerator::ComputeClOptions(
+ std::string const& configName)
+{
+ // much of this was copied from here:
+ // copied from cmLocalVisualStudio7Generator.cxx 805
+ // TODO: Integrate code below with cmLocalVisualStudio7Generator.
+
+ cmsys::auto_ptr<Options> pOptions(
+ new Options(this->LocalGenerator, Options::Compiler,
+ cmVS10CLFlagTable));
+ Options& clOptions = *pOptions;
+
+ std::string flags;
+ // collect up flags for
+ if(this->Target->GetType() < cmTarget::UTILITY)
+ {
+ 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 ";
+ }
+ }
+ // Add the target-specific flags.
+ if(const char* targetFlags = this->Target->GetProperty("COMPILE_FLAGS"))
+ {
+ flags += " ";
+ flags += targetFlags;
+ }
+ std::string configUpper = cmSystemTools::UpperCase(configName);
+ std::string defPropName = "COMPILE_DEFINITIONS_";
+ defPropName += configUpper;
+
+ // Get preprocessor definitions for this directory.
+ std::string defineFlags = this->Target->GetMakefile()->GetDefineFlags();
+ clOptions.FixExceptionHandlingDefault();
+ clOptions.Parse(flags.c_str());
+ clOptions.Parse(defineFlags.c_str());
+ clOptions.AddDefines
+ (this->Makefile->GetProperty("COMPILE_DEFINITIONS"));
+ clOptions.AddDefines(this->Target->GetProperty("COMPILE_DEFINITIONS"));
+ clOptions.AddDefines(this->Makefile->GetProperty(defPropName.c_str()));
+ clOptions.AddDefines(this->Target->GetProperty(defPropName.c_str()));
+ 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())
+ {
+ clOptions.AddDefine(exportMacro);
+ }
+
+ this->ClOptions[configName] = pOptions.release();
+ return true;
+}
+
+//----------------------------------------------------------------------------
+void cmVisualStudio10TargetGenerator::WriteClOptions(
+ std::string const& configName,
+ std::vector<std::string> const& includes)
+{
+ Options& clOptions = *(this->ClOptions[configName]);
+ this->WriteString("<ClCompile>\n", 2);
+ clOptions.OutputAdditionalOptions(*this->BuildFileStream, " ", "");
+ this->OutputIncludes(includes);
+ clOptions.OutputFlagMap(*this->BuildFileStream, " ");
+
+ // 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);
+ }
+
+ clOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, " ",
+ "\n", "CXX");
+ this->WriteString("<AssemblerListingLocation>", 3);
+ *this->BuildFileStream << configName
+ << "</AssemblerListingLocation>\n";
+ this->WriteString("<ObjectFileName>$(IntDir)</ObjectFileName>\n", 3);
+ if(this->Target->GetType() != cmTarget::OBJECT_LIBRARY)
+ {
+ // TODO: PDB for object library?
+ this->WriteString("<ProgramDataBaseFileName>", 3);
+ *this->BuildFileStream << this->Target->GetDirectory(configName.c_str())
+ << "/"
+ << this->Target->GetPDBName(configName.c_str())
+ << "</ProgramDataBaseFileName>\n";
+ }
+ this->WriteString("</ClCompile>\n", 2);
+}
+
+void cmVisualStudio10TargetGenerator::
+OutputIncludes(std::vector<std::string> const & includes)
+{
+ this->WriteString("<AdditionalIncludeDirectories>", 3);
+ for(std::vector<std::string>::const_iterator i = includes.begin();
+ i != includes.end(); ++i)
+ {
+ *this->BuildFileStream << *i << ";";
+ }
+ this->WriteString("%(AdditionalIncludeDirectories)"
+ "</AdditionalIncludeDirectories>\n", 0);
+}
+
+
+
+void cmVisualStudio10TargetGenerator::
+WriteRCOptions(std::string const& configName,
+ std::vector<std::string> const & includes)
+{
+ this->WriteString("<ResourceCompile>\n", 2);
+ Options& clOptions = *(this->ClOptions[configName]);
+ clOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, " ",
+ "\n", "RC");
+ this->OutputIncludes(includes);
+ this->WriteString("</ResourceCompile>\n", 2);
+}
+
+
+void
+cmVisualStudio10TargetGenerator::WriteLibOptions(std::string const& config)
+{
+ if(this->Target->GetType() != cmTarget::STATIC_LIBRARY)
+ {
+ return;
+ }
+ const char* libflags = this->Target->GetProperty("STATIC_LIBRARY_FLAGS");
+ std::string flagsConfigVar = "STATIC_LIBRARY_FLAGS_";
+ flagsConfigVar += cmSystemTools::UpperCase(config);
+ const char* libflagsConfig =
+ this->Target->GetProperty(flagsConfigVar.c_str());
+ if(libflags || libflagsConfig)
+ {
+ this->WriteString("<Lib>\n", 2);
+ cmVisualStudioGeneratorOptions
+ libOptions(this->LocalGenerator,
+ cmVisualStudioGeneratorOptions::Linker,
+ cmVS10LibFlagTable, 0, this);
+ libOptions.Parse(libflags?libflags:"");
+ libOptions.Parse(libflagsConfig?libflagsConfig:"");
+ libOptions.OutputAdditionalOptions(*this->BuildFileStream, " ", "");
+ libOptions.OutputFlagMap(*this->BuildFileStream, " ");
+ this->WriteString("</Lib>\n", 2);
+ }
+}
+
+
+void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const&
+ config)
+{
+
+ // 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)
+ {
+ return;
+ }
+ const char* linkLanguage =
+ this->Target->GetLinkerLanguage(config.c_str());
+ if(!linkLanguage)
+ {
+ cmSystemTools::Error
+ ("CMake can not determine linker language for target:",
+ this->Name.c_str());
+ return;
+ }
+
+ this->WriteString("<Link>\n", 2);
+ std::string CONFIG = cmSystemTools::UpperCase(config);
+
+ const char* linkType = "SHARED";
+ if(this->Target->GetType() == cmTarget::MODULE_LIBRARY)
+ {
+ linkType = "MODULE";
+ }
+ if(this->Target->GetType() == cmTarget::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 += " ";
+ flags += stackVal;
+ }
+ // assume incremental linking
+ std::string linkFlagVarBase = "CMAKE_";
+ linkFlagVarBase += linkType;
+ linkFlagVarBase += "_LINKER_FLAGS";
+ flags += " ";
+ flags += this->
+ Target->GetMakefile()->GetRequiredDefinition(linkFlagVarBase.c_str());
+ std::string linkFlagVar = linkFlagVarBase + "_" + CONFIG;
+ flags += " ";
+ flags += this->
+ Target->GetMakefile()->GetRequiredDefinition(linkFlagVar.c_str());
+ const char* targetLinkFlags = this->Target->GetProperty("LINK_FLAGS");
+ if(targetLinkFlags)
+ {
+ flags += " ";
+ flags += targetLinkFlags;
+ }
+ std::string flagsProp = "LINK_FLAGS_";
+ flagsProp += CONFIG;
+ if(const char* flagsConfig = this->Target->GetProperty(flagsProp.c_str()))
+ {
+ flags += " ";
+ flags += flagsConfig;
+ }
+ cmVisualStudioGeneratorOptions
+ linkOptions(this->LocalGenerator,
+ cmVisualStudioGeneratorOptions::Linker,
+ cmVS10LinkFlagTable, 0, this);
+ if ( this->Target->GetPropertyAsBool("WIN32_EXECUTABLE") )
+ {
+ flags += " /SUBSYSTEM:WINDOWS";
+ }
+ else
+ {
+ flags += " /SUBSYSTEM:CONSOLE";
+ }
+ cmSystemTools::ReplaceString(flags, "/INCREMENTAL:YES", "");
+ cmSystemTools::ReplaceString(flags, "/INCREMENTAL:NO", "");
+ std::string standardLibsVar = "CMAKE_";
+ standardLibsVar += linkLanguage;
+ standardLibsVar += "_STANDARD_LIBRARIES";
+ std::string
+ libs = this->Makefile->GetSafeDefinition(standardLibsVar.c_str());
+ // Remove trailing spaces from libs
+ std::string::size_type pos = libs.size()-1;
+ if(libs.size() != 0)
+ {
+ while(libs[pos] == ' ')
+ {
+ pos--;
+ }
+ }
+ if(pos != libs.size()-1)
+ {
+ libs = libs.substr(0, pos+1);
+ }
+ // Replace spaces in libs with ;
+ cmSystemTools::ReplaceString(libs, " ", ";");
+ cmComputeLinkInformation* pcli =
+ this->Target->GetLinkInformation(config.c_str());
+ if(!pcli)
+ {
+ cmSystemTools::Error
+ ("CMake can not compute cmComputeLinkInformation for target:",
+ this->Name.c_str());
+ return;
+ }
+ // add the libraries for the target to libs string
+ cmComputeLinkInformation& cli = *pcli;
+ this->AddLibraries(cli, libs);
+ linkOptions.AddFlag("AdditionalDependencies", libs.c_str());
+
+ std::vector<std::string> const& ldirs = cli.GetDirectories();
+ const char* sep = "";
+ 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;
+ // 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");
+ }
+ std::string targetName;
+ std::string targetNameSO;
+ std::string targetNameFull;
+ std::string targetNameImport;
+ std::string targetNamePDB;
+ if(this->Target->GetType() == cmTarget::EXECUTABLE)
+ {
+ this->Target->GetExecutableNames(targetName, targetNameFull,
+ targetNameImport, targetNamePDB,
+ config.c_str());
+ }
+ else
+ {
+ this->Target->GetLibraryNames(targetName, targetNameSO, targetNameFull,
+ targetNameImport, targetNamePDB,
+ config.c_str());
+ }
+
+ std::string dir = this->Target->GetDirectory(config.c_str());
+ dir += "/";
+ std::string pdb = dir;
+ pdb += targetNamePDB;
+ std::string imLib = this->Target->GetDirectory(config.c_str(), true);
+ imLib += "/";
+ imLib += targetNameImport;
+
+ linkOptions.AddFlag("ImportLibrary", imLib.c_str());
+ linkOptions.AddFlag("ProgramDataBaseFile", pdb.c_str());
+ linkOptions.Parse(flags.c_str());
+ if(!this->GeneratorTarget->ModuleDefinitionFile.empty())
+ {
+ linkOptions.AddFlag("ModuleDefinitionFile",
+ this->GeneratorTarget->ModuleDefinitionFile.c_str());
+ }
+
+ linkOptions.RemoveFlag("GenerateManifest");
+ linkOptions.OutputAdditionalOptions(*this->BuildFileStream, " ", "");
+ linkOptions.OutputFlagMap(*this->BuildFileStream, " ");
+
+ this->WriteString("</Link>\n", 2);
+ if(!this->GlobalGenerator->NeedLinkLibraryDependencies(*this->Target))
+ {
+ this->WriteString("<ProjectReference>\n", 2);
+ this->WriteString(
+ " <LinkLibraryDependencies>false</LinkLibraryDependencies>\n", 2);
+ this->WriteString("</ProjectReference>\n", 2);
+ }
+}
+
+void cmVisualStudio10TargetGenerator::AddLibraries(
+ cmComputeLinkInformation& cli,
+ std::string& libstring)
+{
+ 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)
+ {
+ std::string path = this->LocalGenerator->
+ Convert(l->Value.c_str(),
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::UNCHANGED);
+ this->ConvertToWindowsSlash(path);
+ libstring += sep;
+ libstring += path;
+ }
+ else
+ {
+ libstring += sep;
+ libstring += l->Value;
+ }
+ }
+}
+
+
+void cmVisualStudio10TargetGenerator::
+WriteMidlOptions(std::string const& /*config*/,
+ std::vector<std::string> const & includes)
+{
+ this->WriteString("<Midl>\n", 2);
+ this->OutputIncludes(includes);
+ this->WriteString("<OutputDirectory>$(IntDir)</OutputDirectory>\n", 3);
+ this->WriteString("<HeaderFileName>%(Filename).h</HeaderFileName>\n", 3);
+ this->WriteString(
+ "<TypeLibraryName>%(Filename).tlb</TypeLibraryName>\n", 3);
+ this->WriteString(
+ "<InterfaceIdentifierFileName>"
+ "%(Filename)_i.c</InterfaceIdentifierFileName>\n", 3);
+ this->WriteString("<ProxyFileName>%(Filename)_p.c</ProxyFileName>\n",3);
+ this->WriteString("</Midl>\n", 2);
+}
+
+
+void cmVisualStudio10TargetGenerator::WriteItemDefinitionGroups()
+{
+ std::vector<std::string> *configs =
+ static_cast<cmGlobalVisualStudio7Generator *>
+ (this->GlobalGenerator)->GetConfigurations();
+ std::vector<std::string> includes;
+ this->LocalGenerator->GetIncludeDirectories(includes, this->Target);
+ for(std::vector<std::string>::iterator i = configs->begin();
+ i != configs->end(); ++i)
+ {
+ this->WritePlatformConfigTag("ItemDefinitionGroup", i->c_str(), 1);
+ *this->BuildFileStream << "\n";
+ // output cl compile flags <ClCompile></ClCompile>
+ if(this->Target->GetType() <= cmTarget::OBJECT_LIBRARY)
+ {
+ this->WriteClOptions(*i, includes);
+ // output rc compile flags <ResourceCompile></ResourceCompile>
+ this->WriteRCOptions(*i, includes);
+ }
+ // output midl flags <Midl></Midl>
+ this->WriteMidlOptions(*i, includes);
+ // write events
+ this->WriteEvents(*i);
+ // output link flags <Link></Link>
+ this->WriteLinkOptions(*i);
+ // output lib flags <Lib></Lib>
+ this->WriteLibOptions(*i);
+ this->WriteString("</ItemDefinitionGroup>\n", 1);
+ }
+}
+
+void
+cmVisualStudio10TargetGenerator::WriteEvents(std::string const& configName)
+{
+ this->WriteEvent("PreLinkEvent",
+ this->Target->GetPreLinkCommands(), configName);
+ this->WriteEvent("PreBuildEvent",
+ this->Target->GetPreBuildCommands(), configName);
+ this->WriteEvent("PostBuildEvent",
+ this->Target->GetPostBuildCommands(), configName);
+}
+
+void cmVisualStudio10TargetGenerator::WriteEvent(
+ const char* name,
+ std::vector<cmCustomCommand> & commands,
+ std::string const& configName)
+{
+ if(commands.size() == 0)
+ {
+ return;
+ }
+ this->WriteString("<", 2);
+ (*this->BuildFileStream ) << name << ">\n";
+ cmLocalVisualStudio7Generator* lg = this->LocalGenerator;
+ std::string script;
+ const char* pre = "";
+ std::string comment;
+ for(std::vector<cmCustomCommand>::iterator i = commands.begin();
+ i != commands.end(); ++i)
+ {
+ cmCustomCommand& command = *i;
+ comment += pre;
+ comment += lg->ConstructComment(command);
+ script += pre;
+ pre = "\n";
+ script +=
+ cmVS10EscapeXML(lg->ConstructScript(command, configName.c_str()));
+ }
+ comment = cmVS10EscapeComment(comment);
+ this->WriteString("<Message>",3);
+ (*this->BuildFileStream ) << cmVS10EscapeXML(comment) << "</Message>\n";
+ this->WriteString("<Command>", 3);
+ (*this->BuildFileStream ) << script;
+ (*this->BuildFileStream ) << "</Command>" << "\n";
+ this->WriteString("</", 2);
+ (*this->BuildFileStream ) << name << ">\n";
+}
+
+
+void cmVisualStudio10TargetGenerator::WriteProjectReferences()
+{
+ cmGlobalGenerator::TargetDependSet const& unordered
+ = this->GlobalGenerator->GetTargetDirectDepends(*this->Target);
+ typedef cmGlobalVisualStudioGenerator::OrderedTargetDependSet
+ OrderedTargetDependSet;
+ OrderedTargetDependSet depends(unordered);
+ this->WriteString("<ItemGroup>\n", 1);
+ for( OrderedTargetDependSet::const_iterator i = depends.begin();
+ i != depends.end(); ++i)
+ {
+ cmTarget* dt = *i;
+ // 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))
+ {
+ continue;
+ }
+ this->WriteString("<ProjectReference Include=\"", 2);
+ cmMakefile* mf = dt->GetMakefile();
+ std::string name = dt->GetName();
+ std::string path;
+ const char* p = dt->GetProperty("EXTERNAL_MSPROJECT");
+ if(p)
+ {
+ path = p;
+ }
+ else
+ {
+ path = mf->GetStartOutputDirectory();
+ path += "/";
+ path += dt->GetName();
+ path += ".vcxproj";
+ }
+ (*this->BuildFileStream) << path << "\">\n";
+ this->WriteString("<Project>", 3);
+ (*this->BuildFileStream)
+ << this->GlobalGenerator->GetGUID(name.c_str())
+ << "</Project>\n";
+ this->WriteString("</ProjectReference>\n", 2);
+ }
+ this->WriteString("</ItemGroup>\n", 1);
+}
diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h
new file mode 100644
index 000000000..2d5ec2a6b
--- /dev/null
+++ b/Source/cmVisualStudio10TargetGenerator.h
@@ -0,0 +1,114 @@
+/*============================================================================
+ 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 cmVisualStudioTargetGenerator_h
+#define cmVisualStudioTargetGenerator_h
+#include "cmStandardIncludes.h"
+
+class cmTarget;
+class cmMakefile;
+class cmGeneratorTarget;
+class cmGeneratedFileStream;
+class cmGlobalVisualStudio10Generator;
+class cmSourceFile;
+class cmCustomCommand;
+class cmLocalVisualStudio7Generator;
+class cmComputeLinkInformation;
+class cmVisualStudioGeneratorOptions;
+#include "cmSourceGroup.h"
+
+class cmVisualStudio10TargetGenerator
+{
+public:
+ cmVisualStudio10TargetGenerator(cmTarget* target,
+ cmGlobalVisualStudio10Generator* gg);
+ ~cmVisualStudio10TargetGenerator();
+ void Generate();
+ // used by cmVisualStudioGeneratorOptions
+ void WritePlatformConfigTag(
+ const char* tag,
+ const char* config,
+ int indentLevel,
+ const char* attribute = 0,
+ const char* end = 0,
+ std::ostream* strm = 0
+ );
+
+private:
+ struct ToolSource
+ {
+ cmSourceFile* SourceFile;
+ bool RelativePath;
+ };
+ struct ToolSources: public std::vector<ToolSource> {};
+
+ std::string ConvertPath(std::string const& path, bool forceRelative);
+ void ConvertToWindowsSlash(std::string& s);
+ 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 WriteAllSources();
+ void WriteDotNetReferences();
+ void WriteWinRTReferences();
+ void WritePathAndIncrementalLinkOptions();
+ void WriteItemDefinitionGroups();
+ bool ComputeClOptions();
+ bool ComputeClOptions(std::string const& configName);
+ void WriteClOptions(std::string const& config,
+ std::vector<std::string> const & includes);
+ void WriteRCOptions(std::string const& config,
+ std::vector<std::string> const & includes);
+ 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 OutputLinkIncremental(std::string const& configName);
+ void WriteCustomRule(cmSourceFile* source,
+ cmCustomCommand const & command);
+ void WriteCustomCommands();
+ void WriteCustomCommand(cmSourceFile* sf);
+ void WriteGroups();
+ void WriteProjectReferences();
+ bool OutputSourceSpecificFlags(cmSourceFile* source);
+ void AddLibraries(cmComputeLinkInformation& cli, std::string& libstring);
+ void WriteLibOptions(std::string const& config);
+ void WriteEvents(std::string const& configName);
+ void WriteEvent(const char* name, std::vector<cmCustomCommand> & 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);
+
+
+private:
+ typedef cmVisualStudioGeneratorOptions Options;
+ typedef std::map<cmStdString, Options*> OptionsMap;
+ OptionsMap ClOptions;
+ std::string PathToVcxproj;
+ cmTarget* Target;
+ cmGeneratorTarget* GeneratorTarget;
+ cmMakefile* Makefile;
+ std::string Platform;
+ std::string GUID;
+ std::string Name;
+ cmGlobalVisualStudio10Generator* GlobalGenerator;
+ cmGeneratedFileStream* BuildFileStream;
+ cmLocalVisualStudio7Generator* LocalGenerator;
+ std::set<cmSourceFile*> SourcesVisited;
+
+ typedef std::map<cmStdString, ToolSources> ToolSourceMap;
+ ToolSourceMap Tools;
+};
+
+#endif
diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx
new file mode 100644
index 000000000..9369af60c
--- /dev/null
+++ b/Source/cmVisualStudioGeneratorOptions.cxx
@@ -0,0 +1,370 @@
+#include "cmVisualStudioGeneratorOptions.h"
+#include "cmSystemTools.h"
+#include <cmsys/System.h>
+#include "cmVisualStudio10TargetGenerator.h"
+
+inline std::string cmVisualStudio10GeneratorOptionsEscapeForXML(const char* s)
+{
+ std::string ret = s;
+ cmSystemTools::ReplaceString(ret, "&", "&amp;");
+ cmSystemTools::ReplaceString(ret, "<", "&lt;");
+ cmSystemTools::ReplaceString(ret, ">", "&gt;");
+ return ret;
+}
+
+inline std::string cmVisualStudioGeneratorOptionsEscapeForXML(const char* s)
+{
+ std::string ret = s;
+ cmSystemTools::ReplaceString(ret, "&", "&amp;");
+ cmSystemTools::ReplaceString(ret, "\"", "&quot;");
+ cmSystemTools::ReplaceString(ret, "<", "&lt;");
+ cmSystemTools::ReplaceString(ret, ">", "&gt;");
+ cmSystemTools::ReplaceString(ret, "\n", "&#x0D;&#x0A;");
+ return ret;
+}
+
+//----------------------------------------------------------------------------
+cmVisualStudioGeneratorOptions
+::cmVisualStudioGeneratorOptions(cmLocalVisualStudioGenerator* lg,
+ Tool tool,
+ cmVS7FlagTable const* table,
+ cmVS7FlagTable const* extraTable,
+ cmVisualStudio10TargetGenerator* g):
+ cmIDEOptions(),
+ LocalGenerator(lg), Version(lg->GetVersion()), CurrentTool(tool),
+ TargetGenerator(g)
+{
+ // Store the given flag tables.
+ cmIDEFlagTable const** ft = this->FlagTable;
+ if(table) { *ft++ = table; }
+ if(extraTable) { *ft++ = extraTable; }
+
+ // 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;
+}
+
+//----------------------------------------------------------------------------
+void cmVisualStudioGeneratorOptions::FixExceptionHandlingDefault()
+{
+ // Exception handling is on by default because the platform file has
+ // "/EHsc" in the flags. Normally, that will override this
+ // initialization to off, but the user has the option of removing
+ // the flag to disable exception handling. When the user does
+ // remove the flag we need to override the IDE default of on.
+ switch (this->Version)
+ {
+ case cmLocalVisualStudioGenerator::VS7:
+ case cmLocalVisualStudioGenerator::VS71:
+ this->FlagMap["ExceptionHandling"] = "FALSE";
+ break;
+ case cmLocalVisualStudioGenerator::VS10:
+ case cmLocalVisualStudioGenerator::VS11:
+ // 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
+ // value
+ this->FlagMap["ExceptionHandling"] = "\n ";
+ break;
+ default:
+ this->FlagMap["ExceptionHandling"] = "0";
+ break;
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmVisualStudioGeneratorOptions::SetVerboseMakefile(bool verbose)
+{
+ // If verbose makefiles have been requested and the /nologo option
+ // was not given explicitly in the flags we want to add an attribute
+ // to the generated project to disable logo suppression. Otherwise
+ // the GUI default is to enable suppression.
+ //
+ // On Visual Studio 10 (and later!), the value of this attribute should be
+ // an empty string, instead of "FALSE", in order to avoid a warning:
+ // "cl ... warning D9035: option 'nologo-' has been deprecated"
+ //
+ if(verbose &&
+ this->FlagMap.find("SuppressStartupBanner") == this->FlagMap.end())
+ {
+ this->FlagMap["SuppressStartupBanner"] =
+ this->Version < cmLocalVisualStudioGenerator::VS10 ? "FALSE" : "";
+ }
+}
+
+bool cmVisualStudioGeneratorOptions::IsDebug()
+{
+ return this->FlagMap.find("DebugInformationFormat") != this->FlagMap.end();
+}
+
+//----------------------------------------------------------------------------
+bool cmVisualStudioGeneratorOptions::UsingUnicode()
+{
+ // Look for the a _UNICODE definition.
+ for(std::vector<std::string>::const_iterator di = this->Defines.begin();
+ di != this->Defines.end(); ++di)
+ {
+ if(*di == "_UNICODE")
+ {
+ return true;
+ }
+ }
+ return false;
+}
+//----------------------------------------------------------------------------
+bool cmVisualStudioGeneratorOptions::UsingSBCS()
+{
+ // Look for the a _SBCS definition.
+ for(std::vector<std::string>::const_iterator di = this->Defines.begin();
+ di != this->Defines.end(); ++di)
+ {
+ if(*di == "_SBCS")
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+void cmVisualStudioGeneratorOptions::Parse(const char* flags)
+{
+ // Parse the input string as a windows command line since the string
+ // is intended for writing directly into the build files.
+ std::vector<std::string> args;
+ cmSystemTools::ParseWindowsCommandLine(flags, args);
+
+ // Process flags that need to be represented specially in the IDE
+ // project file.
+ for(std::vector<std::string>::iterator ai = args.begin();
+ ai != args.end(); ++ai)
+ {
+ this->HandleFlag(ai->c_str());
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmVisualStudioGeneratorOptions::ParseFinish()
+{
+ if(this->CurrentTool == FortranCompiler)
+ {
+ // "RuntimeLibrary" attribute values:
+ // "rtMultiThreaded", "0", /threads /libs:static
+ // "rtMultiThreadedDLL", "2", /threads /libs:dll
+ // "rtMultiThreadedDebug", "1", /threads /dbglibs /libs:static
+ // "rtMultiThreadedDebugDLL", "3", /threads /dbglibs /libs:dll
+ // These seem unimplemented by the IDE:
+ // "rtSingleThreaded", "4", /libs:static
+ // "rtSingleThreadedDLL", "10", /libs:dll
+ // "rtSingleThreadedDebug", "5", /dbglibs /libs:static
+ // "rtSingleThreadedDebugDLL", "11", /dbglibs /libs:dll
+ std::string rl = "rtMultiThreaded";
+ rl += this->FortranRuntimeDebug? "Debug" : "";
+ rl += this->FortranRuntimeDLL? "DLL" : "";
+ this->FlagMap["RuntimeLibrary"] = rl;
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmVisualStudioGeneratorOptions::StoreUnknownFlag(const char* flag)
+{
+ // Look for Intel Fortran flags that do not map well in the flag table.
+ if(this->CurrentTool == FortranCompiler)
+ {
+ if(strcmp(flag, "/dbglibs") == 0)
+ {
+ this->FortranRuntimeDebug = true;
+ return;
+ }
+ if(strcmp(flag, "/threads") == 0)
+ {
+ this->FortranRuntimeMT = true;
+ return;
+ }
+ if(strcmp(flag, "/libs:dll") == 0)
+ {
+ this->FortranRuntimeDLL = true;
+ return;
+ }
+ if(strcmp(flag, "/libs:static") == 0)
+ {
+ this->FortranRuntimeDLL = false;
+ return;
+ }
+ }
+
+ // This option is not known. Store it in the output flags.
+ this->FlagString += " ";
+ this->FlagString +=
+ cmSystemTools::EscapeWindowsShellArgument(
+ flag,
+ cmsysSystem_Shell_Flag_AllowMakeVariables |
+ cmsysSystem_Shell_Flag_VSIDE);
+}
+
+//----------------------------------------------------------------------------
+void cmVisualStudioGeneratorOptions::SetConfiguration(const char* config)
+{
+ this->Configuration = config;
+}
+
+//----------------------------------------------------------------------------
+void
+cmVisualStudioGeneratorOptions
+::OutputPreprocessorDefinitions(std::ostream& fout,
+ const char* prefix,
+ const char* suffix,
+ const char* lang)
+{
+ if(this->Defines.empty())
+ {
+ return;
+ }
+ if(this->Version >= cmLocalVisualStudioGenerator::VS10)
+ {
+ // if there are configuration specifc flags, then
+ // use the configuration specific tag for PreprocessorDefinitions
+ if(this->Configuration.size())
+ {
+ fout << prefix;
+ this->TargetGenerator->WritePlatformConfigTag(
+ "PreprocessorDefinitions",
+ this->Configuration.c_str(),
+ 0,
+ 0, 0, &fout);
+ }
+ else
+ {
+ fout << prefix << "<PreprocessorDefinitions>";
+ }
+ }
+ else
+ {
+ fout << prefix << "PreprocessorDefinitions=\"";
+ }
+ const char* sep = "";
+ for(std::vector<std::string>::const_iterator di = this->Defines.begin();
+ di != this->Defines.end(); ++di)
+ {
+ // Escape the definition for the compiler.
+ std::string define;
+ if(this->Version < cmLocalVisualStudioGenerator::VS10)
+ {
+ define =
+ this->LocalGenerator->EscapeForShell(di->c_str(), true);
+ }
+ else
+ {
+ define = *di;
+ }
+ // Escape this flag for the IDE.
+ if(this->Version >= cmLocalVisualStudioGenerator::VS10)
+ {
+ define = cmVisualStudio10GeneratorOptionsEscapeForXML(define.c_str());
+
+ if(0 == strcmp(lang, "RC"))
+ {
+ cmSystemTools::ReplaceString(define, "\"", "\\\"");
+ }
+ }
+ else
+ {
+ define = cmVisualStudioGeneratorOptionsEscapeForXML(define.c_str());
+ }
+ // Store the flag in the project file.
+ fout << sep << define;
+ sep = ";";
+ }
+ if(this->Version >= cmLocalVisualStudioGenerator::VS10)
+ {
+ fout << ";%(PreprocessorDefinitions)</PreprocessorDefinitions>" << suffix;
+ }
+ else
+ {
+ fout << "\"" << suffix;
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmVisualStudioGeneratorOptions
+::OutputFlagMap(std::ostream& fout, const char* indent)
+{
+ if(this->Version >= cmLocalVisualStudioGenerator::VS10)
+ {
+ for(std::map<cmStdString, cmStdString>::iterator m = this->FlagMap.begin();
+ m != this->FlagMap.end(); ++m)
+ {
+ fout << indent;
+ if(this->Configuration.size())
+ {
+ this->TargetGenerator->WritePlatformConfigTag(
+ m->first.c_str(),
+ this->Configuration.c_str(),
+ 0,
+ 0, 0, &fout);
+ }
+ else
+ {
+ fout << "<" << m->first << ">";
+ }
+ fout << m->second;
+ if (m->first == "AdditionalIncludeDirectories")
+ {
+ fout << ";%(AdditionalIncludeDirectories)";
+ }
+ fout << "</" << m->first << ">\n";
+ }
+ }
+ else
+ {
+ for(std::map<cmStdString, cmStdString>::iterator m = this->FlagMap.begin();
+ m != this->FlagMap.end(); ++m)
+ {
+ fout << indent << m->first << "=\"" << m->second << "\"\n";
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmVisualStudioGeneratorOptions
+::OutputAdditionalOptions(std::ostream& fout,
+ const char* prefix,
+ const char* suffix)
+{
+ if(!this->FlagString.empty())
+ {
+ if(this->Version >= cmLocalVisualStudioGenerator::VS10)
+ {
+ fout << prefix;
+ if(this->Configuration.size())
+ {
+ this->TargetGenerator->WritePlatformConfigTag(
+ "AdditionalOptions",
+ this->Configuration.c_str(),
+ 0,
+ 0, 0, &fout);
+ }
+ else
+ {
+ fout << "<AdditionalOptions>";
+ }
+ fout << this->FlagString.c_str()
+ << " %(AdditionalOptions)</AdditionalOptions>\n";
+ }
+ else
+ {
+ fout << prefix << "AdditionalOptions=\"";
+ fout <<
+ cmVisualStudioGeneratorOptionsEscapeForXML(this->FlagString.c_str());
+ fout << "\"" << suffix;
+ }
+ }
+}
diff --git a/Source/cmVisualStudioGeneratorOptions.h b/Source/cmVisualStudioGeneratorOptions.h
new file mode 100644
index 000000000..a1a55daff
--- /dev/null
+++ b/Source/cmVisualStudioGeneratorOptions.h
@@ -0,0 +1,79 @@
+/*============================================================================
+ 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 cmVisualStudioGeneratorOptions_h
+#define cmVisualStudioGeneratorOptions_h
+
+#include "cmLocalVisualStudioGenerator.h"
+
+#include "cmIDEOptions.h"
+typedef cmIDEFlagTable cmVS7FlagTable;
+
+class cmVisualStudio10TargetGenerator;
+
+//----------------------------------------------------------------------------
+class cmVisualStudioGeneratorOptions: public cmIDEOptions
+{
+public:
+ // Construct an options table for a given tool.
+ enum Tool
+ {
+ Compiler,
+ Linker,
+ FortranCompiler
+ };
+ cmVisualStudioGeneratorOptions(cmLocalVisualStudioGenerator* lg,
+ Tool tool,
+ cmVS7FlagTable const* table,
+ cmVS7FlagTable const* extraTable = 0,
+ cmVisualStudio10TargetGenerator* g = 0);
+
+ // Store options from command line flags.
+ void Parse(const char* flags);
+ void ParseFinish();
+
+ // Fix the ExceptionHandling option to default to off.
+ void FixExceptionHandlingDefault();
+
+ // Store options for verbose builds.
+ void SetVerboseMakefile(bool verbose);
+
+ // Check for specific options.
+ bool UsingUnicode();
+ bool UsingSBCS();
+
+ bool IsDebug();
+ // Write options to output.
+ void OutputPreprocessorDefinitions(std::ostream& fout,
+ const char* prefix,
+ const char* suffix,
+ const char* lang);
+ void OutputFlagMap(std::ostream& fout, const char* indent);
+ void OutputAdditionalOptions(std::ostream& fout,
+ const char* prefix,
+ const char* suffix);
+ void SetConfiguration(const char* config);
+private:
+ cmLocalVisualStudioGenerator* LocalGenerator;
+ cmLocalVisualStudioGenerator::VSVersion Version;
+
+ std::string Configuration;
+ Tool CurrentTool;
+ cmVisualStudio10TargetGenerator* TargetGenerator;
+
+ bool FortranRuntimeDebug;
+ bool FortranRuntimeDLL;
+ bool FortranRuntimeMT;
+
+ virtual void StoreUnknownFlag(const char* flag);
+};
+
+#endif
diff --git a/Source/cmWhileCommand.cxx b/Source/cmWhileCommand.cxx
new file mode 100644
index 000000000..400034582
--- /dev/null
+++ b/Source/cmWhileCommand.cxx
@@ -0,0 +1,142 @@
+/*============================================================================
+ 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 "cmWhileCommand.h"
+#include "cmIfCommand.h"
+
+bool cmWhileFunctionBlocker::
+IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf,
+ cmExecutionStatus &inStatus)
+{
+ // at end of for each execute recorded commands
+ if (!cmSystemTools::Strucmp(lff.Name.c_str(),"while"))
+ {
+ // record the number of while commands past this one
+ this->Depth++;
+ }
+ else if (!cmSystemTools::Strucmp(lff.Name.c_str(),"endwhile"))
+ {
+ // if this is the endwhile for this while loop then execute
+ if (!this->Depth)
+ {
+ // Remove the function blocker for this scope or bail.
+ cmsys::auto_ptr<cmFunctionBlocker>
+ fb(mf.RemoveFunctionBlocker(this, lff));
+ if(!fb.get()) { return false; }
+
+ std::string errorString;
+
+ std::vector<std::string> expandedArguments;
+ mf.ExpandArguments(this->Args, expandedArguments);
+ cmake::MessageType messageType;
+ bool isTrue =
+ cmIfCommand::IsTrue(expandedArguments,errorString,
+ &mf, messageType);
+
+ while (isTrue)
+ {
+ if (errorString.size())
+ {
+ std::string err = "had incorrect arguments: ";
+ unsigned int i;
+ for(i =0; i < this->Args.size(); ++i)
+ {
+ err += (this->Args[i].Quoted?"\"":"");
+ err += this->Args[i].Value;
+ err += (this->Args[i].Quoted?"\"":"");
+ err += " ";
+ }
+ err += "(";
+ err += errorString;
+ err += ").";
+ mf.IssueMessage(messageType, err);
+ if (messageType == cmake::FATAL_ERROR)
+ {
+ cmSystemTools::SetFatalErrorOccured();
+ return true;
+ }
+ }
+
+ // Invoke all the functions that were collected in the block.
+ for(unsigned int c = 0; c < this->Functions.size(); ++c)
+ {
+ cmExecutionStatus status;
+ mf.ExecuteCommand(this->Functions[c],status);
+ if (status.GetReturnInvoked())
+ {
+ inStatus.SetReturnInvoked(true);
+ return true;
+ }
+ if (status.GetBreakInvoked())
+ {
+ return true;
+ }
+ if(cmSystemTools::GetFatalErrorOccured() )
+ {
+ return true;
+ }
+ }
+ expandedArguments.clear();
+ mf.ExpandArguments(this->Args, expandedArguments);
+ isTrue =
+ cmIfCommand::IsTrue(expandedArguments,errorString,
+ &mf, messageType);
+ }
+ return true;
+ }
+ else
+ {
+ // decrement for each nested while that ends
+ this->Depth--;
+ }
+ }
+
+ // record the command
+ this->Functions.push_back(lff);
+
+ // always return true
+ return true;
+}
+
+bool cmWhileFunctionBlocker::
+ShouldRemove(const cmListFileFunction& lff, cmMakefile& )
+{
+ if(!cmSystemTools::Strucmp(lff.Name.c_str(),"endwhile"))
+ {
+ // if the endwhile has arguments, then make sure
+ // they match the arguments of the matching while
+ if (lff.Arguments.size() == 0 ||
+ lff.Arguments == this->Args)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool cmWhileCommand
+::InvokeInitialPass(const std::vector<cmListFileArgument>& args,
+ cmExecutionStatus &)
+{
+ if(args.size() < 1)
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ // create a function blocker
+ cmWhileFunctionBlocker *f = new cmWhileFunctionBlocker();
+ f->Args = args;
+ this->Makefile->AddFunctionBlocker(f);
+
+ return true;
+}
+
diff --git a/Source/cmWhileCommand.h b/Source/cmWhileCommand.h
new file mode 100644
index 000000000..e111ae40d
--- /dev/null
+++ b/Source/cmWhileCommand.h
@@ -0,0 +1,101 @@
+/*============================================================================
+ 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 cmWhileCommand_h
+#define cmWhileCommand_h
+
+#include "cmCommand.h"
+#include "cmFunctionBlocker.h"
+#include "cmListFileCache.h"
+
+class cmWhileFunctionBlocker : public cmFunctionBlocker
+{
+public:
+ cmWhileFunctionBlocker() {this->Depth=0;}
+ virtual ~cmWhileFunctionBlocker() {}
+ virtual bool IsFunctionBlocked(const cmListFileFunction& lff,
+ cmMakefile &mf,
+ cmExecutionStatus &);
+ virtual bool ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf);
+
+ std::vector<cmListFileArgument> Args;
+ std::vector<cmListFileFunction> Functions;
+private:
+ int Depth;
+};
+
+/// \brief Starts a while loop
+class cmWhileCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmWhileCommand;
+ }
+
+ /**
+ * This overrides the default InvokeInitialPass implementation.
+ * It records the arguments before expansion.
+ */
+ virtual bool InvokeInitialPass(const std::vector<cmListFileArgument>& args,
+ cmExecutionStatus &);
+
+ /**
+ * This is called when the command is first encountered in
+ * the CMakeLists.txt file.
+ */
+ virtual bool InitialPass(std::vector<std::string> const&,
+ cmExecutionStatus &) { return false; }
+
+ /**
+ * 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 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.";
+ }
+
+ cmTypeMacro(cmWhileCommand, cmCommand);
+};
+
+
+#endif
diff --git a/Source/cmWin32ProcessExecution.cxx b/Source/cmWin32ProcessExecution.cxx
new file mode 100644
index 000000000..f37e0ff4e
--- /dev/null
+++ b/Source/cmWin32ProcessExecution.cxx
@@ -0,0 +1,940 @@
+/*============================================================================
+ 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);
+}
+
+/*
+ * Internal dictionary mapping popen* file pointers to process handles,
+ * for use when retrieving the process exit code. See _PyPclose() below
+ * for more information on this dictionary's use.
+ */
+static void *_PyPopenProcs = NULL;
+
+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
+ * the 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;
+ }
+ }
+
+ /*
+ * Insert the files we've created into the process dictionary
+ * all referencing the list with the process handle and the
+ * initial number of files (see description below in _PyPclose).
+ * Since if _PyPclose later tried to wait on a process when all
+ * handles weren't closed, it could create a deadlock with the
+ * child, we spend some energy here to try to ensure that we
+ * either insert all file handles into the dictionary or none
+ * at all. It's a little clumsy with the various popen modes
+ * and variable number of files involved.
+ */
+
+ /* 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();
+}
+
+/*
+ * Wrapper for fclose() to use for popen* files, so we can retrieve the
+ * exit code for the child process and return as a result of the close.
+ *
+ * This function uses the _PyPopenProcs dictionary in order to map the
+ * input file pointer to information about the process that was
+ * originally created by the popen* call that created the file pointer.
+ * The dictionary uses the file pointer as a key (with one entry
+ * inserted for each file returned by the original popen* call) and a
+ * single list object as the value for all files from a single call.
+ * The list object contains the Win32 process handle at [0], and a file
+ * count at [1], which is initialized to the total number of file
+ * handles using that list.
+ *
+ * This function closes whichever handle it is passed, and decrements
+ * the file count in the dictionary for the process handle pointed to
+ * by this file. On the last close (when the file count reaches zero),
+ * this function will wait for the child process and then return its
+ * exit code as the result of the close() operation. This permits the
+ * files to be closed in any order - it is always the close() of the
+ * final handle that will return the exit code.
+ */
+
+ /* RED_FLAG 31-Aug-2000 Tim
+ * This is always called (today!) between a pair of
+ * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
+ * macros. So the thread running this has no valid thread state, as
+ * far as Python is concerned. However, this calls some Python API
+ * functions that cannot be called safely without a valid thread
+ * state, in particular PyDict_GetItem.
+ * As a temporary hack (although it may last for years ...), we
+ * *rely* on not having a valid thread state in this function, in
+ * order to create our own "from scratch".
+ * This will deadlock if _PyPclose is ever called by a thread
+ * holding the global lock.
+ */
+
+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
new file mode 100644
index 000000000..def69a8cc
--- /dev/null
+++ b/Source/cmWin32ProcessExecution.h
@@ -0,0 +1,169 @@
+/*============================================================================
+ 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 wether 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
new file mode 100644
index 000000000..b2acb2bc1
--- /dev/null
+++ b/Source/cmWriteFileCommand.cxx
@@ -0,0 +1,93 @@
+/*============================================================================
+ 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 "cmWriteFileCommand.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+// cmLibraryCommand
+bool cmWriteFileCommand
+::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
+{
+ if(args.size() < 2 )
+ {
+ this->SetError("called with incorrect number of arguments");
+ return false;
+ }
+ std::string message;
+ std::vector<std::string>::const_iterator i = args.begin();
+
+ std::string fileName = *i;
+ bool overwrite = true;
+ i++;
+
+ for(;i != args.end(); ++i)
+ {
+ if ( *i == "APPEND" )
+ {
+ overwrite = false;
+ }
+ else
+ {
+ 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());
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+
+ std::string dir = cmSystemTools::GetFilenamePath(fileName);
+ cmSystemTools::MakeDirectory(dir.c_str());
+
+ mode_t mode = 0;
+
+ // Set permissions to writable
+ if ( cmSystemTools::GetPermissions(fileName.c_str(), mode) )
+ {
+ 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
+ );
+ }
+ // If GetPermissions fails, pretend like it is ok. File open will fail if
+ // the file is not writable
+ std::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());
+ return false;
+ }
+ file << message << std::endl;
+ file.close();
+ if(mode)
+ {
+ cmSystemTools::SetPermissions(fileName.c_str(), mode);
+ }
+
+ return true;
+}
+
diff --git a/Source/cmWriteFileCommand.h b/Source/cmWriteFileCommand.h
new file mode 100644
index 000000000..8808d32bb
--- /dev/null
+++ b/Source/cmWriteFileCommand.h
@@ -0,0 +1,85 @@
+/*============================================================================
+ 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 cmWriteFileCommand_h
+#define cmWriteFileCommand_h
+
+#include "cmCommand.h"
+
+/** \class cmWriteFileCommand
+ * \brief Writes a message to a file
+ *
+ */
+class cmWriteFileCommand : public cmCommand
+{
+public:
+ /**
+ * This is a virtual constructor for the command.
+ */
+ virtual cmCommand* Clone()
+ {
+ return new cmWriteFileCommand;
+ }
+
+ /**
+ * 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 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;
+ }
+
+ cmTypeMacro(cmWriteFileCommand, cmCommand);
+};
+
+
+#endif
diff --git a/Source/cmXCode21Object.cxx b/Source/cmXCode21Object.cxx
new file mode 100644
index 000000000..c679cd8bf
--- /dev/null
+++ b/Source/cmXCode21Object.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 "cmXCode21Object.h"
+#include "cmSystemTools.h"
+
+//----------------------------------------------------------------------------
+cmXCode21Object::cmXCode21Object(PBXType ptype, Type type)
+ :cmXCodeObject(ptype, type)
+{
+ this->Version = 21;
+}
+
+//----------------------------------------------------------------------------
+void cmXCode21Object::PrintComment(std::ostream& out)
+{
+ if(this->Comment.size() == 0)
+ {
+ cmXCodeObject* n = this->GetObject("name");
+ if(n)
+ {
+ this->Comment = n->GetString();
+ cmSystemTools::ReplaceString(this->Comment, "\"", "");
+ }
+ }
+ out << "/* ";
+ out << this->Comment;
+ out << " */";
+}
+
+//----------------------------------------------------------------------------
+void cmXCode21Object::PrintList(std::vector<cmXCodeObject*> const& v,
+ std::ostream& out, PBXType t)
+{
+ bool hasOne = false;
+ for(std::vector<cmXCodeObject*>::const_iterator i = v.begin();
+ i != v.end(); ++i)
+ {
+ cmXCodeObject* obj = *i;
+ if(obj->GetType() == OBJECT && obj->GetIsA() == t)
+ {
+ hasOne = true;
+ break;
+ }
+ }
+ if(!hasOne)
+ {
+ return;
+ }
+ out << "\n/* Begin " << PBXTypeNames[t] << " section */\n";
+ for(std::vector<cmXCodeObject*>::const_iterator i = v.begin();
+ i != v.end(); ++i)
+ {
+ cmXCodeObject* obj = *i;
+ if(obj->GetType() == OBJECT && obj->GetIsA() == t)
+ {
+ obj->Print(out);
+ }
+ }
+ out << "/* End " << PBXTypeNames[t] << " section */\n";
+}
+
+//----------------------------------------------------------------------------
+void cmXCode21Object::PrintList(std::vector<cmXCodeObject*> const& v,
+ std::ostream& out)
+{
+ cmXCodeObject::Indent(1, out);
+ out << "objects = {\n";
+ cmXCode21Object::PrintList(v, out, cmXCode21Object::PBXAggregateTarget);
+ cmXCode21Object::PrintList(v, out, cmXCode21Object::PBXBuildFile);
+ cmXCode21Object::PrintList(v, out, cmXCode21Object::PBXBuildStyle);
+ cmXCode21Object::PrintList(v, out, cmXCode21Object::PBXContainerItemProxy);
+ cmXCode21Object::PrintList(v, out, cmXCode21Object::PBXFileReference);
+ cmXCode21Object::PrintList(v, out,
+ cmXCode21Object::PBXFrameworksBuildPhase);
+ cmXCode21Object::PrintList(v, out, cmXCode21Object::PBXGroup);
+ cmXCode21Object::PrintList(v, out, cmXCode21Object::PBXHeadersBuildPhase);
+ cmXCode21Object::PrintList(v, out, cmXCode21Object::PBXNativeTarget);
+ cmXCode21Object::PrintList(v, out, cmXCode21Object::PBXProject);
+ cmXCode21Object::PrintList(v, out,
+ cmXCode21Object::PBXShellScriptBuildPhase);
+ cmXCode21Object::PrintList(v, out, cmXCode21Object::PBXResourcesBuildPhase);
+ cmXCode21Object::PrintList(v, out, cmXCode21Object::PBXSourcesBuildPhase);
+ cmXCode21Object::PrintList(v, out, cmXCode21Object::PBXCopyFilesBuildPhase);
+ cmXCode21Object::PrintList(v, out,
+ cmXCode21Object::PBXApplicationReference);
+ cmXCode21Object::PrintList(v, out,
+ cmXCode21Object::PBXExecutableFileReference);
+ cmXCode21Object::PrintList(v, out, cmXCode21Object::PBXLibraryReference);
+ cmXCode21Object::PrintList(v, out, cmXCode21Object::PBXToolTarget);
+ cmXCode21Object::PrintList(v, out, cmXCode21Object::PBXLibraryTarget);
+ cmXCode21Object::PrintList(v, out, cmXCode21Object::PBXTargetDependency);
+ cmXCode21Object::PrintList(v, out, cmXCode21Object::XCBuildConfiguration);
+ cmXCode21Object::PrintList(v, out, cmXCode21Object::XCConfigurationList);
+ cmXCodeObject::Indent(1, out);
+ out << "};\n";
+}
diff --git a/Source/cmXCode21Object.h b/Source/cmXCode21Object.h
new file mode 100644
index 000000000..cc3ab047b
--- /dev/null
+++ b/Source/cmXCode21Object.h
@@ -0,0 +1,28 @@
+/*============================================================================
+ 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 cmXCode21Object_h
+#define cmXCode21Object_h
+
+#include "cmXCodeObject.h"
+
+class cmXCode21Object : public cmXCodeObject
+{
+public:
+ cmXCode21Object(PBXType ptype, Type type);
+ virtual void PrintComment(std::ostream&);
+ static void PrintList(std::vector<cmXCodeObject*> const&,
+ std::ostream& out,
+ PBXType t);
+ static void PrintList(std::vector<cmXCodeObject*> const&,
+ std::ostream& out);
+};
+#endif
diff --git a/Source/cmXCodeObject.cxx b/Source/cmXCodeObject.cxx
new file mode 100644
index 000000000..30ade9637
--- /dev/null
+++ b/Source/cmXCodeObject.cxx
@@ -0,0 +1,273 @@
+/*============================================================================
+ 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 "cmXCodeObject.h"
+#include "cmSystemTools.h"
+
+#include <CoreFoundation/CoreFoundation.h> // CFUUIDCreate
+
+//----------------------------------------------------------------------------
+const char* cmXCodeObject::PBXTypeNames[] = {
+ "PBXGroup", "PBXBuildStyle", "PBXProject", "PBXHeadersBuildPhase",
+ "PBXSourcesBuildPhase", "PBXFrameworksBuildPhase", "PBXNativeTarget",
+ "PBXFileReference", "PBXBuildFile", "PBXContainerItemProxy",
+ "PBXTargetDependency", "PBXShellScriptBuildPhase",
+ "PBXResourcesBuildPhase", "PBXApplicationReference",
+ "PBXExecutableFileReference", "PBXLibraryReference", "PBXToolTarget",
+ "PBXLibraryTarget", "PBXAggregateTarget", "XCBuildConfiguration",
+ "XCConfigurationList",
+ "PBXCopyFilesBuildPhase",
+ "None"
+ };
+
+//----------------------------------------------------------------------------
+cmXCodeObject::~cmXCodeObject()
+{
+ this->Version = 15;
+}
+
+//----------------------------------------------------------------------------
+cmXCodeObject::cmXCodeObject(PBXType ptype, Type type)
+{
+ this->Version = 15;
+ this->PBXTargetDependencyValue = 0;
+ this->Target = 0;
+ this->Object =0;
+
+ this->IsA = ptype;
+
+ if(type == OBJECT)
+ {
+ // Set the Id of an Xcode object to a unique string for each instance.
+ // However the Xcode user file references certain Ids: for those cases,
+ // override the generated Id using SetId().
+ //
+ char cUuid[40] = {0};
+ CFUUIDRef uuid = CFUUIDCreate(kCFAllocatorDefault);
+ CFStringRef s = CFUUIDCreateString(kCFAllocatorDefault, uuid);
+ CFStringGetCString(s, cUuid, sizeof(cUuid), kCFStringEncodingUTF8);
+ this->Id = cUuid;
+ CFRelease(s);
+ CFRelease(uuid);
+ }
+ else
+ {
+ this->Id =
+ "Temporary cmake object, should not be referred to in Xcode file";
+ }
+
+ cmSystemTools::ReplaceString(this->Id, "-", "");
+ if(this->Id.size() > 24)
+ {
+ this->Id = this->Id.substr(0, 24);
+ }
+
+ this->TypeValue = type;
+ if(this->TypeValue == OBJECT)
+ {
+ this->AddAttribute("isa", 0);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmXCodeObject::Indent(int level, std::ostream& out)
+{
+ while(level)
+ {
+ out << " ";
+ level--;
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmXCodeObject::Print(std::ostream& out)
+{
+ std::string separator = "\n";
+ int indentFactor = 1;
+ 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 << " = {";
+ if(separator == "\n")
+ {
+ out << separator;
+ }
+ std::map<cmStdString, cmXCodeObject*>::iterator i;
+ cmXCodeObject::Indent(3*indentFactor, out);
+ out << "isa = " << PBXTypeNames[this->IsA] << ";" << separator;
+ for(i = this->ObjectAttributes.begin();
+ i != this->ObjectAttributes.end(); ++i)
+ {
+ cmXCodeObject* object = i->second;
+ if(i->first != "isa")
+ {
+ cmXCodeObject::Indent(3*indentFactor, out);
+ }
+ else
+ {
+ continue;
+ }
+ if(object->TypeValue == OBJECT_LIST)
+ {
+ out << i->first << " = (" << separator;
+ for(unsigned int k = 0; k < i->second->List.size(); k++)
+ {
+ cmXCodeObject::Indent(4*indentFactor, out);
+ out << i->second->List[k]->Id << " ";
+ i->second->List[k]->PrintComment(out);
+ out << "," << separator;
+ }
+ cmXCodeObject::Indent(3*indentFactor, out);
+ out << ");" << separator;
+ }
+ else if(object->TypeValue == ATTRIBUTE_GROUP)
+ {
+ std::map<cmStdString, cmXCodeObject*>::iterator j;
+ out << i->first << " = {" << separator;
+ for(j = object->ObjectAttributes.begin(); j !=
+ object->ObjectAttributes.end(); ++j)
+ {
+ cmXCodeObject::Indent(4 *indentFactor, out);
+
+ if(j->second->TypeValue == STRING)
+ {
+ cmXCodeObject::PrintString(out,j->first);
+ out << " = ";
+ j->second->PrintString(out);
+ out << ";";
+ }
+ else if(j->second->TypeValue == OBJECT_LIST)
+ {
+ cmXCodeObject::PrintString(out,j->first);
+ out << " = (";
+ for(unsigned int k = 0; k < j->second->List.size(); k++)
+ {
+ if(j->second->List[k]->TypeValue == STRING)
+ {
+ j->second->List[k]->PrintString(out);
+ out << ", ";
+ }
+ else
+ {
+ out << "List_" << k << "_TypeValue_IS_NOT_STRING, ";
+ }
+ }
+ out << ");";
+ }
+ else
+ {
+ cmXCodeObject::PrintString(out,j->first);
+ out << " = error_unexpected_TypeValue_" <<
+ j->second->TypeValue << ";";
+ }
+
+ out << separator;
+ }
+ cmXCodeObject::Indent(3 *indentFactor, out);
+ out << "};" << separator;
+ }
+ else if(object->TypeValue == OBJECT_REF)
+ {
+ cmXCodeObject::PrintString(out,i->first);
+ out << " = " << object->Object->Id;
+ if(object->Object->HasComment() && i->first != "remoteGlobalIDString")
+ {
+ out << " ";
+ object->Object->PrintComment(out);
+ }
+ out << ";" << separator;
+ }
+ else if(object->TypeValue == STRING)
+ {
+ cmXCodeObject::PrintString(out,i->first);
+ out << " = ";
+ object->PrintString(out);
+ out << ";" << separator;
+ }
+ else
+ {
+ out << "what is this?? " << i->first << "\n";
+ }
+ }
+ cmXCodeObject::Indent(2*indentFactor, out);
+ out << "};\n";
+}
+
+//----------------------------------------------------------------------------
+void cmXCodeObject::PrintList(std::vector<cmXCodeObject*> const& objs,
+ std::ostream& out)
+{
+ cmXCodeObject::Indent(1, out);
+ out << "objects = {\n";
+ for(unsigned int i = 0; i < objs.size(); ++i)
+ {
+ if(objs[i]->TypeValue == OBJECT)
+ {
+ objs[i]->Print(out);
+ }
+ }
+ cmXCodeObject::Indent(1, out);
+ out << "};\n";
+}
+
+//----------------------------------------------------------------------------
+void cmXCodeObject::CopyAttributes(cmXCodeObject* copy)
+{
+ this->ObjectAttributes = copy->ObjectAttributes;
+ this->List = copy->List;
+ this->String = copy->String;
+ this->Object = copy->Object;
+}
+
+//----------------------------------------------------------------------------
+void cmXCodeObject::PrintString(std::ostream& os,cmStdString 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);
+ const char* quote = needQuote? "\"" : "";
+
+ // Print the string, quoted and escaped as necessary.
+ os << quote;
+ for(std::string::const_iterator i = String.begin();
+ i != String.end(); ++i)
+ {
+ if(*i == '"')
+ {
+ // Escape double-quotes.
+ os << '\\';
+ }
+ os << *i;
+ }
+ os << quote;
+}
+
+void cmXCodeObject::PrintString(std::ostream& os) const
+{
+ cmXCodeObject::PrintString(os,this->String);
+}
+
+//----------------------------------------------------------------------------
+void cmXCodeObject::SetString(const char* s)
+{
+ this->String = s;
+}
diff --git a/Source/cmXCodeObject.h b/Source/cmXCodeObject.h
new file mode 100644
index 000000000..2fb96f30e
--- /dev/null
+++ b/Source/cmXCodeObject.h
@@ -0,0 +1,179 @@
+/*============================================================================
+ 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 cmXCodeObject_h
+#define cmXCodeObject_h
+
+#include "cmStandardIncludes.h"
+class cmTarget;
+
+class cmXCodeObject
+{
+public:
+ enum Type { OBJECT_LIST, STRING, ATTRIBUTE_GROUP, OBJECT_REF, OBJECT };
+ enum PBXType { PBXGroup, PBXBuildStyle, PBXProject, PBXHeadersBuildPhase,
+ PBXSourcesBuildPhase, PBXFrameworksBuildPhase,
+ PBXNativeTarget, PBXFileReference, PBXBuildFile,
+ PBXContainerItemProxy, PBXTargetDependency,
+ PBXShellScriptBuildPhase, PBXResourcesBuildPhase,
+ PBXApplicationReference, PBXExecutableFileReference,
+ PBXLibraryReference, PBXToolTarget, PBXLibraryTarget,
+ PBXAggregateTarget,XCBuildConfiguration,XCConfigurationList,
+ PBXCopyFilesBuildPhase,
+ None
+ };
+ class StringVec: public std::vector<cmStdString> {};
+ 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()
+ {
+ return this->String.c_str();
+ }
+
+ void AddAttribute(const char* name, cmXCodeObject* value)
+ {
+ this->ObjectAttributes[name] = value;
+ }
+
+ void SetObject(cmXCodeObject* value)
+ {
+ this->Object = value;
+ }
+ cmXCodeObject* GetObject()
+ {
+ return this->Object;
+ }
+ void AddObject(cmXCodeObject* value)
+ {
+ this->List.push_back(value);
+ }
+ bool HasObject(cmXCodeObject* o)
+ {
+ return !(std::find(this->List.begin(), this->List.end(), o)
+ == this->List.end());
+ }
+ void AddUniqueObject(cmXCodeObject* value)
+ {
+ if(std::find(this->List.begin(), this->List.end(), value)
+ == this->List.end())
+ {
+ this->List.push_back(value);
+ }
+ }
+ static void Indent(int level, std::ostream& out);
+ void Print(std::ostream& out);
+ virtual void PrintComment(std::ostream&) {};
+
+ static void PrintList(std::vector<cmXCodeObject*> const&,
+ std::ostream& out);
+ const char* GetId()
+ {
+ return this->Id.c_str();
+ }
+ void SetId(const char* id)
+ {
+ this->Id = id;
+ }
+ cmTarget* GetTarget()
+ {
+ return this->Target;
+ }
+ void SetTarget(cmTarget* t)
+ {
+ this->Target = t;
+ }
+ const char* GetComment() {return this->Comment.c_str();}
+ bool HasComment() { return (this->Comment.size() != 0);}
+ cmXCodeObject* GetObject(const char* name)
+ {
+ if(this->ObjectAttributes.count(name))
+ {
+ return this->ObjectAttributes[name];
+ }
+ return 0;
+ }
+ // serach the attribute list for an object of the specified type
+ cmXCodeObject* GetObject(cmXCodeObject::PBXType t)
+ {
+ for(std::vector<cmXCodeObject*>::iterator i = this->List.begin();
+ i != this->List.end(); ++i)
+ {
+ cmXCodeObject* o = *i;
+ if(o->IsA == t)
+ {
+ return o;
+ }
+ }
+ return 0;
+ }
+
+ cmXCodeObject* GetPBXTargetDependency()
+ {
+ return this->PBXTargetDependencyValue;
+ }
+ void SetPBXTargetDependency(cmXCodeObject* d)
+ {
+ this->PBXTargetDependencyValue = d;
+ }
+ void CopyAttributes(cmXCodeObject* );
+
+ void AddDependLibrary(const char* configName,
+ const char* l)
+ {
+ if(!configName)
+ {
+ configName = "";
+ }
+ this->DependLibraries[configName].push_back(l);
+ }
+ std::map<cmStdString, StringVec> const& GetDependLibraries()
+ {
+ return this->DependLibraries;
+ }
+ void AddDependTarget(const char* configName,
+ const char* tName)
+ {
+ if(!configName)
+ {
+ configName = "";
+ }
+ this->DependTargets[configName].push_back(tName);
+ }
+ std::map<cmStdString, 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);
+protected:
+ void PrintString(std::ostream& os) const;
+
+ cmTarget* Target;
+ Type TypeValue;
+ cmStdString Id;
+ PBXType IsA;
+ int Version;
+ cmStdString Comment;
+ cmStdString String;
+ cmXCodeObject* Object;
+ cmXCodeObject* PBXTargetDependencyValue;
+ std::vector<cmXCodeObject*> List;
+ std::map<cmStdString, StringVec> DependLibraries;
+ std::map<cmStdString, StringVec> DependTargets;
+ std::map<cmStdString, cmXCodeObject*> ObjectAttributes;
+};
+#endif
diff --git a/Source/cmXMLParser.cxx b/Source/cmXMLParser.cxx
new file mode 100644
index 000000000..46a1ca4aa
--- /dev/null
+++ b/Source/cmXMLParser.cxx
@@ -0,0 +1,237 @@
+/*============================================================================
+ 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 "cmXMLParser.h"
+
+#include <cm_expat.h>
+#include <ctype.h>
+
+//----------------------------------------------------------------------------
+cmXMLParser::cmXMLParser()
+{
+ this->Parser = 0;
+ this->ParseError = 0;
+}
+
+//----------------------------------------------------------------------------
+cmXMLParser::~cmXMLParser()
+{
+ if ( this->Parser )
+ {
+ this->CleanupParser();
+ }
+}
+
+//----------------------------------------------------------------------------
+int cmXMLParser::Parse(const char* string)
+{
+ return (int)this->InitializeParser() &&
+ this->ParseChunk(string, strlen(string)) &&
+ this->CleanupParser();
+}
+
+int cmXMLParser::ParseFile(const char* file)
+{
+ if ( !file )
+ {
+ return 0;
+ }
+
+ std::ifstream ifs(file);
+ if ( !ifs )
+ {
+ return 0;
+ }
+
+ cmOStringStream str;
+ str << ifs.rdbuf();
+ return this->Parse(str.str().c_str());
+}
+
+//----------------------------------------------------------------------------
+int cmXMLParser::InitializeParser()
+{
+ if ( this->Parser )
+ {
+ std::cerr << "Parser already initialized" << std::endl;
+ this->ParseError = 1;
+ return 0;
+ }
+
+ // Create the expat XML parser.
+ this->Parser = XML_ParserCreate(0);
+ XML_SetElementHandler(static_cast<XML_Parser>(this->Parser),
+ &cmXMLParserStartElement,
+ &cmXMLParserEndElement);
+ XML_SetCharacterDataHandler(static_cast<XML_Parser>(this->Parser),
+ &cmXMLParserCharacterDataHandler);
+ XML_SetUserData(static_cast<XML_Parser>(this->Parser), this);
+ this->ParseError = 0;
+ return 1;
+}
+
+//----------------------------------------------------------------------------
+int cmXMLParser::ParseChunk(const char* inputString,
+ std::string::size_type length)
+{
+ if ( !this->Parser )
+ {
+ std::cerr << "Parser not initialized" << std::endl;
+ this->ParseError = 1;
+ return 0;
+ }
+ int res;
+ res = this->ParseBuffer(inputString, length);
+ if ( res == 0 )
+ {
+ this->ParseError = 1;
+ }
+ return res;
+}
+
+//----------------------------------------------------------------------------
+int cmXMLParser::CleanupParser()
+{
+ if ( !this->Parser )
+ {
+ std::cerr << "Parser not initialized" << std::endl;
+ this->ParseError = 1;
+ return 0;
+ }
+ int result = !this->ParseError;
+ if(result)
+ {
+ // Tell the expat XML parser about the end-of-input.
+ if(!XML_Parse(static_cast<XML_Parser>(this->Parser), "", 0, 1))
+ {
+ this->ReportXmlParseError();
+ result = 0;
+ }
+ }
+
+ // Clean up the parser.
+ XML_ParserFree(static_cast<XML_Parser>(this->Parser));
+ this->Parser = 0;
+
+ return result;
+}
+
+//----------------------------------------------------------------------------
+int cmXMLParser::ParseBuffer(const char* buffer, std::string::size_type count)
+{
+ // Pass the buffer to the expat XML parser.
+ if(!XML_Parse(static_cast<XML_Parser>(this->Parser), buffer,
+ static_cast<int>(count), 0))
+ {
+ this->ReportXmlParseError();
+ return 0;
+ }
+ return 1;
+}
+
+//----------------------------------------------------------------------------
+int cmXMLParser::ParseBuffer(const char* buffer)
+{
+ return this->ParseBuffer(buffer, static_cast<int>(strlen(buffer)));
+}
+
+//----------------------------------------------------------------------------
+int cmXMLParser::ParsingComplete()
+{
+ // Default behavior is to parse to end of stream.
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+void cmXMLParser::StartElement(const char * name,
+ const char ** /*atts*/)
+{
+ std::cout << "Start element: " << name << std::endl;
+}
+
+//----------------------------------------------------------------------------
+void cmXMLParser::EndElement(const char * name)
+{
+ std::cout << "End element: " << name << std::endl;
+}
+
+//----------------------------------------------------------------------------
+void cmXMLParser::CharacterDataHandler(const char* /*inData*/,
+ int /*inLength*/)
+{
+}
+
+//----------------------------------------------------------------------------
+int cmXMLParser::IsSpace(char c)
+{
+ return isspace(c);
+}
+
+//----------------------------------------------------------------------------
+const char* cmXMLParser::FindAttribute(const char** atts,
+ const char* attribute)
+{
+ if(atts && attribute)
+ {
+ for(const char** a = atts; *a && *(a+1); a += 2)
+ {
+ if(strcmp(*a, attribute) == 0)
+ {
+ return *(a+1);
+ }
+ }
+ }
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+void cmXMLParserStartElement(void* parser, const char *name,
+ const char **atts)
+{
+ // Begin element handler that is registered with the XML_Parser.
+ // This just casts the user data to a cmXMLParser and calls
+ // StartElement.
+ static_cast<cmXMLParser*>(parser)->StartElement(name, atts);
+}
+
+//----------------------------------------------------------------------------
+void cmXMLParserEndElement(void* parser, const char *name)
+{
+ // End element handler that is registered with the XML_Parser. This
+ // just casts the user data to a cmXMLParser and calls EndElement.
+ static_cast<cmXMLParser*>(parser)->EndElement(name);
+}
+
+//----------------------------------------------------------------------------
+void cmXMLParserCharacterDataHandler(void* parser, const char* data,
+ int length)
+{
+ // Character data handler that is registered with the XML_Parser.
+ // This just casts the user data to a cmXMLParser and calls
+ // CharacterDataHandler.
+ static_cast<cmXMLParser*>(parser)->CharacterDataHandler(data, length);
+}
+
+//----------------------------------------------------------------------------
+void cmXMLParser::ReportXmlParseError()
+{
+ XML_Parser parser = static_cast<XML_Parser>(this->Parser);
+ this->ReportError(XML_GetCurrentLineNumber(parser),
+ XML_GetCurrentColumnNumber(parser),
+ XML_ErrorString(XML_GetErrorCode(parser)));
+}
+
+//----------------------------------------------------------------------------
+void cmXMLParser::ReportError(int line, int, const char* msg)
+{
+ std::cerr << "Error parsing XML in stream at line "
+ << line << ": " << msg << std::endl;
+}
diff --git a/Source/cmXMLParser.h b/Source/cmXMLParser.h
new file mode 100644
index 000000000..c72be5751
--- /dev/null
+++ b/Source/cmXMLParser.h
@@ -0,0 +1,112 @@
+/*============================================================================
+ 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 cmXMLParser_h
+#define cmXMLParser_h
+
+#include "cmStandardIncludes.h"
+
+extern "C"
+{
+ void cmXMLParserStartElement(void*, const char*, const char**);
+ void cmXMLParserEndElement(void*, const char*);
+ void cmXMLParserCharacterDataHandler(void*, const char*, int);
+}
+
+/** \class cmXMLParser
+ * \brief Helper class for performing XML parsing
+ *
+ * Superclass for all XML parsers.
+ */
+class cmXMLParser
+{
+public:
+ cmXMLParser();
+ virtual ~cmXMLParser();
+
+ //! Parse given XML string
+ virtual int Parse(const char* string);
+
+ //! Parse given XML file
+ virtual int ParseFile(const char* file);
+
+ /**
+ * When parsing fragments of XML or streaming XML, use the following
+ * three methods. InitializeParser method initialize parser but does
+ * not perform any actual parsing. ParseChunk parses framgent of
+ * XML. This has to match to what was already parsed. CleanupParser
+ * finishes parsing. If there were errors, CleanupParser will report
+ * them.
+ */
+ virtual int InitializeParser();
+ virtual int ParseChunk(const char* inputString,
+ std::string::size_type length);
+ virtual int CleanupParser();
+
+protected:
+ //! This variable is true if there was a parse error while parsing in
+ //chunks.
+ int ParseError;
+
+ //1 Expat parser structure. Exists only during call to Parse().
+ void* Parser;
+
+ /**
+ * Called before each block of input is read from the stream to check if
+ * parsing is complete. Can be replaced by subclasses to change the
+ * terminating condition for parsing. Parsing always stops when the end of
+ * file is reached in the stream.
+ */
+
+ virtual int ParsingComplete();
+
+ /**
+ * Called when a new element is opened in the XML source. Should be
+ * replaced by subclasses to handle each element. name = Name of new
+ * 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);
+
+ //! Called at the end of an element in the XML source opened when
+ //StartElement was called.
+ virtual void EndElement(const char* name);
+
+ //! Called when there is character data to handle.
+ virtual void CharacterDataHandler(const char* data, int length);
+
+ //! Called by Parse to report an XML syntax error.
+ virtual void ReportXmlParseError();
+
+ /** Called by ReportXmlParseError with basic error info. */
+ virtual void ReportError(int line, int column, const char* msg);
+
+ //! Utility for convenience of subclasses. Wraps isspace C library
+ // routine.
+ static int IsSpace(char c);
+
+ //! Send the given buffer to the XML parser.
+ virtual int ParseBuffer(const char* buffer,
+ std::string::size_type length);
+
+ //! Send the given c-style string to the XML parser.
+ int ParseBuffer(const char* buffer);
+
+ /** Helps subclasses search for attributes on elements. */
+ static const char* FindAttribute(const char** atts, const char* attribute);
+
+ //! Callbacks for the expat
+ friend void cmXMLParserStartElement(void*, const char*, const char**);
+ friend void cmXMLParserEndElement(void*, const char*);
+ friend void cmXMLParserCharacterDataHandler(void*, const char*, int);
+};
+
+#endif
diff --git a/Source/cmXMLSafe.cxx b/Source/cmXMLSafe.cxx
new file mode 100644
index 000000000..72fdc3466
--- /dev/null
+++ b/Source/cmXMLSafe.cxx
@@ -0,0 +1,102 @@
+/*============================================================================
+ 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 "cmXMLSafe.h"
+
+#include "cm_utf8.h"
+
+#include <cmsys/ios/iostream>
+#include <cmsys/ios/sstream>
+
+#include <string.h>
+#include <stdio.h>
+
+//----------------------------------------------------------------------------
+cmXMLSafe::cmXMLSafe(const char* s):
+ Data(s),
+ Size(static_cast<unsigned long>(strlen(s))),
+ DoQuotes(true)
+{
+}
+
+//----------------------------------------------------------------------------
+cmXMLSafe::cmXMLSafe(cmsys_stl::string const& s):
+ Data(s.c_str()),
+ Size(static_cast<unsigned long>(s.length())),
+ DoQuotes(true)
+{
+}
+
+//----------------------------------------------------------------------------
+cmXMLSafe& cmXMLSafe::Quotes(bool b)
+{
+ this->DoQuotes = b;
+ return *this;
+}
+
+//----------------------------------------------------------------------------
+cmsys_stl::string cmXMLSafe::str()
+{
+ cmsys_ios::ostringstream ss;
+ ss << *this;
+ return ss.str();
+}
+
+//----------------------------------------------------------------------------
+cmsys_ios::ostream& operator<<(cmsys_ios::ostream& os, cmXMLSafe const& self)
+{
+ char const* first = self.Data;
+ char const* last = self.Data + self.Size;
+ while(first != last)
+ {
+ unsigned int ch;
+ if(const char* next = cm_utf8_decode_character(first, last, &ch))
+ {
+ // http://www.w3.org/TR/REC-xml/#NT-Char
+ if((ch >= 0x20 && ch <= 0xD7FF) ||
+ (ch >= 0xE000 && ch <= 0xFFFD) ||
+ (ch >= 0x10000 && ch <= 0x10FFFF) ||
+ ch == 0x9 || ch == 0xA || ch == 0xD)
+ {
+ switch(ch)
+ {
+ // Escape XML control characters.
+ case '&': os << "&amp;"; break;
+ case '<': os << "&lt;"; break;
+ case '>': os << "&gt;"; break;
+ case '"': os << (self.DoQuotes? "&quot;" : "\""); break;
+ case '\'': os << (self.DoQuotes? "&apos;" : "'"); break;
+ case '\r': break; // Ignore CR
+ // Print the UTF-8 character.
+ default: os.write(first, next-first); break;
+ }
+ }
+ else
+ {
+ // Use a human-readable hex value for this invalid character.
+ char buf[16];
+ sprintf(buf, "%X", ch);
+ os << "[NON-XML-CHAR-0x" << buf << "]";
+ }
+
+ first = next;
+ }
+ else
+ {
+ ch = static_cast<unsigned char>(*first++);
+ // Use a human-readable hex value for this invalid byte.
+ char buf[16];
+ sprintf(buf, "%X", ch);
+ os << "[NON-UTF-8-BYTE-0x" << buf << "]";
+ }
+ }
+ return os;
+}
diff --git a/Source/cmXMLSafe.h b/Source/cmXMLSafe.h
new file mode 100644
index 000000000..cba9f390d
--- /dev/null
+++ b/Source/cmXMLSafe.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 cmXMLSafe_h
+#define cmXMLSafe_h
+
+#include <cmsys/stl/string>
+#include <cmsys/ios/iosfwd>
+
+/** \class cmXMLSafe
+ * \brief Write strings to XML with proper escapes
+ */
+class cmXMLSafe
+{
+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);
+
+ /** Specify whether to escape quotes too. This is needed when
+ writing the content of an attribute value. By default quotes
+ are escaped. */
+ cmXMLSafe& Quotes(bool b = true);
+
+ /** Get the escaped data as a string. */
+ cmsys_stl::string str();
+private:
+ char const* Data;
+ unsigned long Size;
+ bool DoQuotes;
+ friend cmsys_ios::ostream& operator<<(cmsys_ios::ostream&,
+ cmXMLSafe const&);
+};
+
+#endif
diff --git a/Source/cm_sha2.c b/Source/cm_sha2.c
new file mode 100644
index 000000000..12c39ed63
--- /dev/null
+++ b/Source/cm_sha2.c
@@ -0,0 +1,1613 @@
+/*
+ * FILE: sha2.c
+ * AUTHOR: Aaron D. Gifford
+ * http://www.aarongifford.com/computers/sha.html
+ *
+ * Copyright (c) 2000-2003, Aaron D. Gifford
+ * 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 copyright holder nor the names of contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(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 OR CONTRIBUTOR(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.
+ *
+ * $Id: sha2.c,v 1.4 2004/01/07 22:58:18 adg Exp $
+ */
+
+#include <string.h> /* memcpy()/memset() or bcopy()/bzero() */
+#include <assert.h> /* assert() */
+#include "cm_sha2.h" /* "sha2.h" -> "cm_sha2.h" renamed for CMake */
+
+/*
+ * ASSERT NOTE:
+ * Some sanity checking code is included using assert(). On my FreeBSD
+ * system, this additional code can be removed by compiling with NDEBUG
+ * defined. Check your own systems manpage on assert() to see how to
+ * compile WITHOUT the sanity checking code on your system.
+ *
+ * UNROLLED TRANSFORM LOOP NOTE:
+ * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform
+ * loop version for the hash transform rounds (defined using macros
+ * later in this file). Either define on the command line, for example:
+ *
+ * cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c
+ *
+ * or define below:
+ *
+ * #define SHA2_UNROLL_TRANSFORM
+ *
+ */
+
+
+/*** SHA-224/256/384/512 Machine Architecture Definitions *************/
+/*
+ * BYTE_ORDER NOTE:
+ *
+ * Please make sure that your system defines BYTE_ORDER. If your
+ * architecture is little-endian, make sure it also defines
+ * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are
+ * equivilent.
+ *
+ * If your system does not define the above, then you can do so by
+ * hand like this:
+ *
+ * #define LITTLE_ENDIAN 1234
+ * #define BIG_ENDIAN 4321
+ *
+ * And for little-endian machines, add:
+ *
+ * #define BYTE_ORDER LITTLE_ENDIAN
+ *
+ * Or for big-endian machines:
+ *
+ * #define BYTE_ORDER BIG_ENDIAN
+ *
+ * The FreeBSD machine this was written on defines BYTE_ORDER
+ * appropriately by including <sys/types.h> (which in turn includes
+ * <machine/endian.h> where the appropriate definitions are actually
+ * made).
+ */
+#if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN)
+/* CMake modification: use byte order from cmIML. */
+# include "cmIML/ABI.h"
+# 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
+#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
+#if defined(__clang__)
+# pragma clang diagnostic ignored "-Wcast-align"
+#endif
+
+/*** ENDIAN REVERSAL MACROS *******************************************/
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define REVERSE32(w,x) { \
+ sha_word32 tmp = (w); \
+ tmp = (tmp >> 16) | (tmp << 16); \
+ (x) = ((tmp & SHA_UINT32_C(0xff00ff00)) >> 8) | \
+ ((tmp & SHA_UINT32_C(0x00ff00ff)) << 8); \
+}
+#define REVERSE64(w,x) { \
+ sha_word64 tmp = (w); \
+ tmp = (tmp >> 32) | (tmp << 32); \
+ tmp = ((tmp & SHA_UINT64_C(0xff00ff00ff00ff00)) >> 8) | \
+ ((tmp & SHA_UINT64_C(0x00ff00ff00ff00ff)) << 8); \
+ (x) = ((tmp & SHA_UINT64_C(0xffff0000ffff0000)) >> 16) | \
+ ((tmp & SHA_UINT64_C(0x0000ffff0000ffff)) << 16); \
+}
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+
+/*
+ * Macro for incrementally adding the unsigned 64-bit integer n to the
+ * unsigned 128-bit integer (represented using a two-element array of
+ * 64-bit words):
+ */
+#define ADDINC128(w,n) { \
+ (w)[0] += (sha_word64)(n); \
+ if ((w)[0] < (n)) { \
+ (w)[1]++; \
+ } \
+}
+
+/*
+ * Macros for copying blocks of memory and for zeroing out ranges
+ * of memory. Using these macros makes it easy to switch from
+ * using memset()/memcpy() and using bzero()/bcopy().
+ *
+ * Please define either SHA2_USE_MEMSET_MEMCPY or define
+ * SHA2_USE_BZERO_BCOPY depending on which function set you
+ * choose to use:
+ */
+#if !defined(SHA2_USE_MEMSET_MEMCPY) && !defined(SHA2_USE_BZERO_BCOPY)
+/* Default to memset()/memcpy() if no option is specified */
+#define SHA2_USE_MEMSET_MEMCPY 1
+#endif
+#if defined(SHA2_USE_MEMSET_MEMCPY) && defined(SHA2_USE_BZERO_BCOPY)
+/* Abort with an error if BOTH options are defined */
+#error Define either SHA2_USE_MEMSET_MEMCPY or SHA2_USE_BZERO_BCOPY, not both!
+#endif
+
+#ifdef SHA2_USE_MEMSET_MEMCPY
+#define MEMSET_BZERO(p,l) memset((p), 0, (l))
+#define MEMCPY_BCOPY(d,s,l) memcpy((d), (s), (l))
+#endif
+#ifdef SHA2_USE_BZERO_BCOPY
+#define MEMSET_BZERO(p,l) bzero((p), (l))
+#define MEMCPY_BCOPY(d,s,l) bcopy((s), (d), (l))
+#endif
+
+
+/*** THE SIX LOGICAL FUNCTIONS ****************************************/
+/*
+ * Bit shifting and rotation (used by the six SHA-XYZ logical functions:
+ *
+ * NOTE: In the original SHA-256/384/512 document, the shift-right
+ * function was named R and the rotate-right function was called S.
+ * (See: http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf on the
+ * web.)
+ *
+ * The newer NIST FIPS 180-2 document uses a much clearer naming
+ * scheme, SHR for shift-right, ROTR for rotate-right, and ROTL for
+ * rotate-left. (See:
+ * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
+ * on the web.)
+ *
+ * WARNING: These macros must be used cautiously, since they reference
+ * supplied parameters sometimes more than once, and thus could have
+ * unexpected side-effects if used without taking this into account.
+ */
+/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */
+#define SHR(b,x) ((x) >> (b))
+/* 32-bit Rotate-right (used in SHA-256): */
+#define ROTR32(b,x) (((x) >> (b)) | ((x) << (32 - (b))))
+/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */
+#define ROTR64(b,x) (((x) >> (b)) | ((x) << (64 - (b))))
+/* 32-bit Rotate-left (used in SHA-1): */
+#define ROTL32(b,x) (((x) << (b)) | ((x) >> (32 - (b))))
+
+/* Two logical functions used in SHA-1, SHA-254, SHA-256, SHA-384, and SHA-512: */
+#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
+#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
+
+/* Function used in SHA-1: */
+#define Parity(x,y,z) ((x) ^ (y) ^ (z))
+
+/* Four logical functions used in SHA-256: */
+#define Sigma0_256(x) (ROTR32(2, (x)) ^ ROTR32(13, (x)) ^ ROTR32(22, (x)))
+#define Sigma1_256(x) (ROTR32(6, (x)) ^ ROTR32(11, (x)) ^ ROTR32(25, (x)))
+#define sigma0_256(x) (ROTR32(7, (x)) ^ ROTR32(18, (x)) ^ SHR( 3 , (x)))
+#define sigma1_256(x) (ROTR32(17, (x)) ^ ROTR32(19, (x)) ^ SHR( 10, (x)))
+
+/* Four of six logical functions used in SHA-384 and SHA-512: */
+#define Sigma0_512(x) (ROTR64(28, (x)) ^ ROTR64(34, (x)) ^ ROTR64(39, (x)))
+#define Sigma1_512(x) (ROTR64(14, (x)) ^ ROTR64(18, (x)) ^ ROTR64(41, (x)))
+#define sigma0_512(x) (ROTR64( 1, (x)) ^ ROTR64( 8, (x)) ^ SHR( 7, (x)))
+#define sigma1_512(x) (ROTR64(19, (x)) ^ ROTR64(61, (x)) ^ SHR( 6, (x)))
+
+/*** INTERNAL FUNCTION PROTOTYPES *************************************/
+
+/* SHA-224 and SHA-256: */
+void SHA256_Internal_Init(SHA_CTX*, const sha_word32*);
+void SHA256_Internal_Last(SHA_CTX*);
+void SHA256_Internal_Transform(SHA_CTX*, const sha_word32*);
+
+/* SHA-384 and SHA-512: */
+void SHA512_Internal_Init(SHA_CTX*, const sha_word64*);
+void SHA512_Internal_Last(SHA_CTX*);
+void SHA512_Internal_Transform(SHA_CTX*, const sha_word64*);
+
+
+/*** SHA2 INITIAL HASH VALUES AND CONSTANTS ***************************/
+
+/* Hash constant words K for SHA-1: */
+#define K1_0_TO_19 SHA_UINT32_C(0x5a827999)
+#define K1_20_TO_39 SHA_UINT32_C(0x6ed9eba1)
+#define K1_40_TO_59 SHA_UINT32_C(0x8f1bbcdc)
+#define K1_60_TO_79 SHA_UINT32_C(0xca62c1d6)
+
+/* Initial hash value H for SHA-1: */
+static const sha_word32 sha1_initial_hash_value[5] = {
+ SHA_UINT32_C(0x67452301),
+ SHA_UINT32_C(0xefcdab89),
+ SHA_UINT32_C(0x98badcfe),
+ SHA_UINT32_C(0x10325476),
+ SHA_UINT32_C(0xc3d2e1f0)
+};
+
+/* Hash constant words K for SHA-224 and SHA-256: */
+static const sha_word32 K256[64] = {
+ SHA_UINT32_C(0x428a2f98), SHA_UINT32_C(0x71374491),
+ SHA_UINT32_C(0xb5c0fbcf), SHA_UINT32_C(0xe9b5dba5),
+ SHA_UINT32_C(0x3956c25b), SHA_UINT32_C(0x59f111f1),
+ SHA_UINT32_C(0x923f82a4), SHA_UINT32_C(0xab1c5ed5),
+ SHA_UINT32_C(0xd807aa98), SHA_UINT32_C(0x12835b01),
+ SHA_UINT32_C(0x243185be), SHA_UINT32_C(0x550c7dc3),
+ SHA_UINT32_C(0x72be5d74), SHA_UINT32_C(0x80deb1fe),
+ SHA_UINT32_C(0x9bdc06a7), SHA_UINT32_C(0xc19bf174),
+ SHA_UINT32_C(0xe49b69c1), SHA_UINT32_C(0xefbe4786),
+ SHA_UINT32_C(0x0fc19dc6), SHA_UINT32_C(0x240ca1cc),
+ SHA_UINT32_C(0x2de92c6f), SHA_UINT32_C(0x4a7484aa),
+ SHA_UINT32_C(0x5cb0a9dc), SHA_UINT32_C(0x76f988da),
+ SHA_UINT32_C(0x983e5152), SHA_UINT32_C(0xa831c66d),
+ SHA_UINT32_C(0xb00327c8), SHA_UINT32_C(0xbf597fc7),
+ SHA_UINT32_C(0xc6e00bf3), SHA_UINT32_C(0xd5a79147),
+ SHA_UINT32_C(0x06ca6351), SHA_UINT32_C(0x14292967),
+ SHA_UINT32_C(0x27b70a85), SHA_UINT32_C(0x2e1b2138),
+ SHA_UINT32_C(0x4d2c6dfc), SHA_UINT32_C(0x53380d13),
+ SHA_UINT32_C(0x650a7354), SHA_UINT32_C(0x766a0abb),
+ SHA_UINT32_C(0x81c2c92e), SHA_UINT32_C(0x92722c85),
+ SHA_UINT32_C(0xa2bfe8a1), SHA_UINT32_C(0xa81a664b),
+ SHA_UINT32_C(0xc24b8b70), SHA_UINT32_C(0xc76c51a3),
+ SHA_UINT32_C(0xd192e819), SHA_UINT32_C(0xd6990624),
+ SHA_UINT32_C(0xf40e3585), SHA_UINT32_C(0x106aa070),
+ SHA_UINT32_C(0x19a4c116), SHA_UINT32_C(0x1e376c08),
+ SHA_UINT32_C(0x2748774c), SHA_UINT32_C(0x34b0bcb5),
+ SHA_UINT32_C(0x391c0cb3), SHA_UINT32_C(0x4ed8aa4a),
+ SHA_UINT32_C(0x5b9cca4f), SHA_UINT32_C(0x682e6ff3),
+ SHA_UINT32_C(0x748f82ee), SHA_UINT32_C(0x78a5636f),
+ SHA_UINT32_C(0x84c87814), SHA_UINT32_C(0x8cc70208),
+ SHA_UINT32_C(0x90befffa), SHA_UINT32_C(0xa4506ceb),
+ SHA_UINT32_C(0xbef9a3f7), SHA_UINT32_C(0xc67178f2)
+};
+
+/* Initial hash value H for SHA-224: */
+static const sha_word32 sha224_initial_hash_value[8] = {
+ SHA_UINT32_C(0xc1059ed8),
+ SHA_UINT32_C(0x367cd507),
+ SHA_UINT32_C(0x3070dd17),
+ SHA_UINT32_C(0xf70e5939),
+ SHA_UINT32_C(0xffc00b31),
+ SHA_UINT32_C(0x68581511),
+ SHA_UINT32_C(0x64f98fa7),
+ SHA_UINT32_C(0xbefa4fa4)
+};
+
+/* Initial hash value H for SHA-256: */
+static const sha_word32 sha256_initial_hash_value[8] = {
+ SHA_UINT32_C(0x6a09e667),
+ SHA_UINT32_C(0xbb67ae85),
+ SHA_UINT32_C(0x3c6ef372),
+ SHA_UINT32_C(0xa54ff53a),
+ SHA_UINT32_C(0x510e527f),
+ SHA_UINT32_C(0x9b05688c),
+ SHA_UINT32_C(0x1f83d9ab),
+ SHA_UINT32_C(0x5be0cd19)
+};
+
+/* Hash constant words K for SHA-384 and SHA-512: */
+static const sha_word64 K512[80] = {
+ SHA_UINT64_C(0x428a2f98d728ae22), SHA_UINT64_C(0x7137449123ef65cd),
+ SHA_UINT64_C(0xb5c0fbcfec4d3b2f), SHA_UINT64_C(0xe9b5dba58189dbbc),
+ SHA_UINT64_C(0x3956c25bf348b538), SHA_UINT64_C(0x59f111f1b605d019),
+ SHA_UINT64_C(0x923f82a4af194f9b), SHA_UINT64_C(0xab1c5ed5da6d8118),
+ SHA_UINT64_C(0xd807aa98a3030242), SHA_UINT64_C(0x12835b0145706fbe),
+ SHA_UINT64_C(0x243185be4ee4b28c), SHA_UINT64_C(0x550c7dc3d5ffb4e2),
+ SHA_UINT64_C(0x72be5d74f27b896f), SHA_UINT64_C(0x80deb1fe3b1696b1),
+ SHA_UINT64_C(0x9bdc06a725c71235), SHA_UINT64_C(0xc19bf174cf692694),
+ SHA_UINT64_C(0xe49b69c19ef14ad2), SHA_UINT64_C(0xefbe4786384f25e3),
+ SHA_UINT64_C(0x0fc19dc68b8cd5b5), SHA_UINT64_C(0x240ca1cc77ac9c65),
+ SHA_UINT64_C(0x2de92c6f592b0275), SHA_UINT64_C(0x4a7484aa6ea6e483),
+ SHA_UINT64_C(0x5cb0a9dcbd41fbd4), SHA_UINT64_C(0x76f988da831153b5),
+ SHA_UINT64_C(0x983e5152ee66dfab), SHA_UINT64_C(0xa831c66d2db43210),
+ SHA_UINT64_C(0xb00327c898fb213f), SHA_UINT64_C(0xbf597fc7beef0ee4),
+ SHA_UINT64_C(0xc6e00bf33da88fc2), SHA_UINT64_C(0xd5a79147930aa725),
+ SHA_UINT64_C(0x06ca6351e003826f), SHA_UINT64_C(0x142929670a0e6e70),
+ SHA_UINT64_C(0x27b70a8546d22ffc), SHA_UINT64_C(0x2e1b21385c26c926),
+ SHA_UINT64_C(0x4d2c6dfc5ac42aed), SHA_UINT64_C(0x53380d139d95b3df),
+ SHA_UINT64_C(0x650a73548baf63de), SHA_UINT64_C(0x766a0abb3c77b2a8),
+ SHA_UINT64_C(0x81c2c92e47edaee6), SHA_UINT64_C(0x92722c851482353b),
+ SHA_UINT64_C(0xa2bfe8a14cf10364), SHA_UINT64_C(0xa81a664bbc423001),
+ SHA_UINT64_C(0xc24b8b70d0f89791), SHA_UINT64_C(0xc76c51a30654be30),
+ SHA_UINT64_C(0xd192e819d6ef5218), SHA_UINT64_C(0xd69906245565a910),
+ SHA_UINT64_C(0xf40e35855771202a), SHA_UINT64_C(0x106aa07032bbd1b8),
+ SHA_UINT64_C(0x19a4c116b8d2d0c8), SHA_UINT64_C(0x1e376c085141ab53),
+ SHA_UINT64_C(0x2748774cdf8eeb99), SHA_UINT64_C(0x34b0bcb5e19b48a8),
+ SHA_UINT64_C(0x391c0cb3c5c95a63), SHA_UINT64_C(0x4ed8aa4ae3418acb),
+ SHA_UINT64_C(0x5b9cca4f7763e373), SHA_UINT64_C(0x682e6ff3d6b2b8a3),
+ SHA_UINT64_C(0x748f82ee5defb2fc), SHA_UINT64_C(0x78a5636f43172f60),
+ SHA_UINT64_C(0x84c87814a1f0ab72), SHA_UINT64_C(0x8cc702081a6439ec),
+ SHA_UINT64_C(0x90befffa23631e28), SHA_UINT64_C(0xa4506cebde82bde9),
+ SHA_UINT64_C(0xbef9a3f7b2c67915), SHA_UINT64_C(0xc67178f2e372532b),
+ SHA_UINT64_C(0xca273eceea26619c), SHA_UINT64_C(0xd186b8c721c0c207),
+ SHA_UINT64_C(0xeada7dd6cde0eb1e), SHA_UINT64_C(0xf57d4f7fee6ed178),
+ SHA_UINT64_C(0x06f067aa72176fba), SHA_UINT64_C(0x0a637dc5a2c898a6),
+ SHA_UINT64_C(0x113f9804bef90dae), SHA_UINT64_C(0x1b710b35131c471b),
+ SHA_UINT64_C(0x28db77f523047d84), SHA_UINT64_C(0x32caab7b40c72493),
+ SHA_UINT64_C(0x3c9ebe0a15c9bebc), SHA_UINT64_C(0x431d67c49c100d4c),
+ SHA_UINT64_C(0x4cc5d4becb3e42b6), SHA_UINT64_C(0x597f299cfc657e2a),
+ SHA_UINT64_C(0x5fcb6fab3ad6faec), SHA_UINT64_C(0x6c44198c4a475817)
+};
+
+/* Initial hash value H for SHA-384 */
+static const sha_word64 sha384_initial_hash_value[8] = {
+ SHA_UINT64_C(0xcbbb9d5dc1059ed8),
+ SHA_UINT64_C(0x629a292a367cd507),
+ SHA_UINT64_C(0x9159015a3070dd17),
+ SHA_UINT64_C(0x152fecd8f70e5939),
+ SHA_UINT64_C(0x67332667ffc00b31),
+ SHA_UINT64_C(0x8eb44a8768581511),
+ SHA_UINT64_C(0xdb0c2e0d64f98fa7),
+ SHA_UINT64_C(0x47b5481dbefa4fa4)
+};
+
+/* Initial hash value H for SHA-512 */
+static const sha_word64 sha512_initial_hash_value[8] = {
+ SHA_UINT64_C(0x6a09e667f3bcc908),
+ SHA_UINT64_C(0xbb67ae8584caa73b),
+ SHA_UINT64_C(0x3c6ef372fe94f82b),
+ SHA_UINT64_C(0xa54ff53a5f1d36f1),
+ SHA_UINT64_C(0x510e527fade682d1),
+ SHA_UINT64_C(0x9b05688c2b3e6c1f),
+ SHA_UINT64_C(0x1f83d9abfb41bd6b),
+ SHA_UINT64_C(0x5be0cd19137e2179)
+};
+
+/*
+ * Constant used by SHA224/256/384/512_End() functions for converting the
+ * digest to a readable hexadecimal character string:
+ */
+static const char *sha_hex_digits = "0123456789abcdef";
+
+
+/*** SHA-1: ***********************************************************/
+void SHA1_Init(SHA_CTX* context) {
+ /* Sanity check: */
+ assert(context != (SHA_CTX*)0);
+
+ MEMCPY_BCOPY(context->s1.state, sha1_initial_hash_value, sizeof(sha_word32) * 5);
+ MEMSET_BZERO(context->s1.buffer, 64);
+ context->s1.bitcount = 0;
+}
+
+#ifdef SHA2_UNROLL_TRANSFORM
+
+/* Unrolled SHA-1 round macros: */
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+
+#define ROUND1_0_TO_15(a,b,c,d,e) \
+ REVERSE32(*data++, W1[j]); \
+ (e) = ROTL32(5, (a)) + Ch((b), (c), (d)) + (e) + \
+ K1_0_TO_19 + W1[j]; \
+ (b) = ROTL32(30, (b)); \
+ j++;
+
+#else /* BYTE_ORDER == LITTLE_ENDIAN */
+
+#define ROUND1_0_TO_15(a,b,c,d,e) \
+ (e) = ROTL32(5, (a)) + Ch((b), (c), (d)) + (e) + \
+ K1_0_TO_19 + ( W1[j] = *data++ ); \
+ (b) = ROTL32(30, (b)); \
+ j++;
+
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+
+#define ROUND1_16_TO_19(a,b,c,d,e) \
+ T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; \
+ (e) = ROTL32(5, a) + Ch(b,c,d) + e + K1_0_TO_19 + ( W1[j&0x0f] = ROTL32(1, T1) ); \
+ (b) = ROTL32(30, b); \
+ j++;
+
+#define ROUND1_20_TO_39(a,b,c,d,e) \
+ T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; \
+ (e) = ROTL32(5, a) + Parity(b,c,d) + e + K1_20_TO_39 + ( W1[j&0x0f] = ROTL32(1, T1) ); \
+ (b) = ROTL32(30, b); \
+ j++;
+
+#define ROUND1_40_TO_59(a,b,c,d,e) \
+ T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; \
+ (e) = ROTL32(5, a) + Maj(b,c,d) + e + K1_40_TO_59 + ( W1[j&0x0f] = ROTL32(1, T1) ); \
+ (b) = ROTL32(30, b); \
+ j++;
+
+#define ROUND1_60_TO_79(a,b,c,d,e) \
+ T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; \
+ (e) = ROTL32(5, a) + Parity(b,c,d) + e + K1_60_TO_79 + ( W1[j&0x0f] = ROTL32(1, T1) ); \
+ (b) = ROTL32(30, b); \
+ j++;
+
+void SHA1_Internal_Transform(SHA_CTX* context, const sha_word32* data) {
+ sha_word32 a, b, c, d, e;
+ sha_word32 T1, *W1;
+ int j;
+
+ W1 = (sha_word32*)context->s1.buffer;
+
+ /* Initialize registers with the prev. intermediate value */
+ a = context->s1.state[0];
+ b = context->s1.state[1];
+ c = context->s1.state[2];
+ d = context->s1.state[3];
+ e = context->s1.state[4];
+
+ j = 0;
+
+ /* Rounds 0 to 15 unrolled: */
+ ROUND1_0_TO_15(a,b,c,d,e);
+ ROUND1_0_TO_15(e,a,b,c,d);
+ ROUND1_0_TO_15(d,e,a,b,c);
+ ROUND1_0_TO_15(c,d,e,a,b);
+ ROUND1_0_TO_15(b,c,d,e,a);
+ ROUND1_0_TO_15(a,b,c,d,e);
+ ROUND1_0_TO_15(e,a,b,c,d);
+ ROUND1_0_TO_15(d,e,a,b,c);
+ ROUND1_0_TO_15(c,d,e,a,b);
+ ROUND1_0_TO_15(b,c,d,e,a);
+ ROUND1_0_TO_15(a,b,c,d,e);
+ ROUND1_0_TO_15(e,a,b,c,d);
+ ROUND1_0_TO_15(d,e,a,b,c);
+ ROUND1_0_TO_15(c,d,e,a,b);
+ ROUND1_0_TO_15(b,c,d,e,a);
+ ROUND1_0_TO_15(a,b,c,d,e);
+
+ /* Rounds 16 to 19 unrolled: */
+ ROUND1_16_TO_19(e,a,b,c,d);
+ ROUND1_16_TO_19(d,e,a,b,c);
+ ROUND1_16_TO_19(c,d,e,a,b);
+ ROUND1_16_TO_19(b,c,d,e,a);
+
+ /* Rounds 20 to 39 unrolled: */
+ ROUND1_20_TO_39(a,b,c,d,e);
+ ROUND1_20_TO_39(e,a,b,c,d);
+ ROUND1_20_TO_39(d,e,a,b,c);
+ ROUND1_20_TO_39(c,d,e,a,b);
+ ROUND1_20_TO_39(b,c,d,e,a);
+ ROUND1_20_TO_39(a,b,c,d,e);
+ ROUND1_20_TO_39(e,a,b,c,d);
+ ROUND1_20_TO_39(d,e,a,b,c);
+ ROUND1_20_TO_39(c,d,e,a,b);
+ ROUND1_20_TO_39(b,c,d,e,a);
+ ROUND1_20_TO_39(a,b,c,d,e);
+ ROUND1_20_TO_39(e,a,b,c,d);
+ ROUND1_20_TO_39(d,e,a,b,c);
+ ROUND1_20_TO_39(c,d,e,a,b);
+ ROUND1_20_TO_39(b,c,d,e,a);
+ ROUND1_20_TO_39(a,b,c,d,e);
+ ROUND1_20_TO_39(e,a,b,c,d);
+ ROUND1_20_TO_39(d,e,a,b,c);
+ ROUND1_20_TO_39(c,d,e,a,b);
+ ROUND1_20_TO_39(b,c,d,e,a);
+
+ /* Rounds 40 to 59 unrolled: */
+ ROUND1_40_TO_59(a,b,c,d,e);
+ ROUND1_40_TO_59(e,a,b,c,d);
+ ROUND1_40_TO_59(d,e,a,b,c);
+ ROUND1_40_TO_59(c,d,e,a,b);
+ ROUND1_40_TO_59(b,c,d,e,a);
+ ROUND1_40_TO_59(a,b,c,d,e);
+ ROUND1_40_TO_59(e,a,b,c,d);
+ ROUND1_40_TO_59(d,e,a,b,c);
+ ROUND1_40_TO_59(c,d,e,a,b);
+ ROUND1_40_TO_59(b,c,d,e,a);
+ ROUND1_40_TO_59(a,b,c,d,e);
+ ROUND1_40_TO_59(e,a,b,c,d);
+ ROUND1_40_TO_59(d,e,a,b,c);
+ ROUND1_40_TO_59(c,d,e,a,b);
+ ROUND1_40_TO_59(b,c,d,e,a);
+ ROUND1_40_TO_59(a,b,c,d,e);
+ ROUND1_40_TO_59(e,a,b,c,d);
+ ROUND1_40_TO_59(d,e,a,b,c);
+ ROUND1_40_TO_59(c,d,e,a,b);
+ ROUND1_40_TO_59(b,c,d,e,a);
+
+ /* Rounds 60 to 79 unrolled: */
+ ROUND1_60_TO_79(a,b,c,d,e);
+ ROUND1_60_TO_79(e,a,b,c,d);
+ ROUND1_60_TO_79(d,e,a,b,c);
+ ROUND1_60_TO_79(c,d,e,a,b);
+ ROUND1_60_TO_79(b,c,d,e,a);
+ ROUND1_60_TO_79(a,b,c,d,e);
+ ROUND1_60_TO_79(e,a,b,c,d);
+ ROUND1_60_TO_79(d,e,a,b,c);
+ ROUND1_60_TO_79(c,d,e,a,b);
+ ROUND1_60_TO_79(b,c,d,e,a);
+ ROUND1_60_TO_79(a,b,c,d,e);
+ ROUND1_60_TO_79(e,a,b,c,d);
+ ROUND1_60_TO_79(d,e,a,b,c);
+ ROUND1_60_TO_79(c,d,e,a,b);
+ ROUND1_60_TO_79(b,c,d,e,a);
+ ROUND1_60_TO_79(a,b,c,d,e);
+ ROUND1_60_TO_79(e,a,b,c,d);
+ ROUND1_60_TO_79(d,e,a,b,c);
+ ROUND1_60_TO_79(c,d,e,a,b);
+ ROUND1_60_TO_79(b,c,d,e,a);
+
+ /* Compute the current intermediate hash value */
+ context->s1.state[0] += a;
+ context->s1.state[1] += b;
+ context->s1.state[2] += c;
+ context->s1.state[3] += d;
+ context->s1.state[4] += e;
+
+ /* Clean up */
+ a = b = c = d = e = T1 = 0;
+}
+
+#else /* SHA2_UNROLL_TRANSFORM */
+
+void SHA1_Internal_Transform(SHA_CTX* context, const sha_word32* data) {
+ sha_word32 a, b, c, d, e;
+ sha_word32 T1, *W1;
+ int j;
+
+ W1 = (sha_word32*)context->s1.buffer;
+
+ /* Initialize registers with the prev. intermediate value */
+ a = context->s1.state[0];
+ b = context->s1.state[1];
+ c = context->s1.state[2];
+ d = context->s1.state[3];
+ e = context->s1.state[4];
+ j = 0;
+ do {
+#if BYTE_ORDER == LITTLE_ENDIAN
+ T1 = data[j];
+ /* Copy data while converting to host byte order */
+ REVERSE32(*data++, W1[j]);
+ T1 = ROTL32(5, a) + Ch(b, c, d) + e + K1_0_TO_19 + W1[j];
+#else /* BYTE_ORDER == LITTLE_ENDIAN */
+ T1 = ROTL32(5, a) + Ch(b, c, d) + e + K1_0_TO_19 + (W1[j] = *data++);
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+ e = d;
+ d = c;
+ c = ROTL32(30, b);
+ b = a;
+ a = T1;
+ j++;
+ } while (j < 16);
+
+ do {
+ T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f];
+ T1 = ROTL32(5, a) + Ch(b,c,d) + e + K1_0_TO_19 + (W1[j&0x0f] = ROTL32(1, T1));
+ e = d;
+ d = c;
+ c = ROTL32(30, b);
+ b = a;
+ a = T1;
+ j++;
+ } while (j < 20);
+
+ do {
+ T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f];
+ T1 = ROTL32(5, a) + Parity(b,c,d) + e + K1_20_TO_39 + (W1[j&0x0f] = ROTL32(1, T1));
+ e = d;
+ d = c;
+ c = ROTL32(30, b);
+ b = a;
+ a = T1;
+ j++;
+ } while (j < 40);
+
+ do {
+ T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f];
+ T1 = ROTL32(5, a) + Maj(b,c,d) + e + K1_40_TO_59 + (W1[j&0x0f] = ROTL32(1, T1));
+ e = d;
+ d = c;
+ c = ROTL32(30, b);
+ b = a;
+ a = T1;
+ j++;
+ } while (j < 60);
+
+ do {
+ T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f];
+ T1 = ROTL32(5, a) + Parity(b,c,d) + e + K1_60_TO_79 + (W1[j&0x0f] = ROTL32(1, T1));
+ e = d;
+ d = c;
+ c = ROTL32(30, b);
+ b = a;
+ a = T1;
+ j++;
+ } while (j < 80);
+
+
+ /* Compute the current intermediate hash value */
+ context->s1.state[0] += a;
+ context->s1.state[1] += b;
+ context->s1.state[2] += c;
+ context->s1.state[3] += d;
+ context->s1.state[4] += e;
+
+ /* Clean up */
+ a = b = c = d = e = T1 = 0;
+}
+
+#endif /* SHA2_UNROLL_TRANSFORM */
+
+void SHA1_Update(SHA_CTX* context, const sha_byte *data, size_t len) {
+ unsigned int freespace, usedspace;
+ if (len == 0) {
+ /* Calling with no data is valid - we do nothing */
+ return;
+ }
+
+ /* Sanity check: */
+ assert(context != (SHA_CTX*)0 && data != (sha_byte*)0);
+
+ usedspace = (unsigned int)((context->s1.bitcount >> 3) % 64);
+ if (usedspace > 0) {
+ /* Calculate how much free space is available in the buffer */
+ freespace = 64 - usedspace;
+
+ if (len >= freespace) {
+ /* Fill the buffer completely and process it */
+ MEMCPY_BCOPY(&context->s1.buffer[usedspace], data, freespace);
+ context->s1.bitcount += freespace << 3;
+ len -= freespace;
+ data += freespace;
+ SHA1_Internal_Transform(context, (sha_word32*)context->s1.buffer);
+ } else {
+ /* The buffer is not yet full */
+ MEMCPY_BCOPY(&context->s1.buffer[usedspace], data, len);
+ context->s1.bitcount += len << 3;
+ /* Clean up: */
+ usedspace = freespace = 0;
+ return;
+ }
+ }
+ while (len >= 64) {
+ /* Process as many complete blocks as we can */
+ SHA1_Internal_Transform(context, (sha_word32*)data);
+ context->s1.bitcount += 512;
+ len -= 64;
+ data += 64;
+ }
+ if (len > 0) {
+ /* There's left-overs, so save 'em */
+ MEMCPY_BCOPY(context->s1.buffer, data, len);
+ context->s1.bitcount += len << 3;
+ }
+ /* Clean up: */
+ usedspace = freespace = 0;
+}
+
+void SHA1_Final(sha_byte digest[], SHA_CTX* context) {
+ sha_word32 *d = (sha_word32*)digest;
+ unsigned int usedspace;
+
+ /* Sanity check: */
+ assert(context != (SHA_CTX*)0);
+
+ if (digest == (sha_byte*)0) {
+ /*
+ * No digest buffer, so we can do nothing
+ * except clean up and go home
+ */
+ MEMSET_BZERO(context, sizeof(*context));
+ return;
+ }
+
+ usedspace = (unsigned int)((context->s1.bitcount >> 3) % 64);
+ if (usedspace == 0) {
+ /* Set-up for the last transform: */
+ MEMSET_BZERO(context->s1.buffer, 56);
+
+ /* Begin padding with a 1 bit: */
+ *context->s1.buffer = 0x80;
+ } else {
+ /* Begin padding with a 1 bit: */
+ context->s1.buffer[usedspace++] = 0x80;
+
+ if (usedspace <= 56) {
+ /* Set-up for the last transform: */
+ MEMSET_BZERO(&context->s1.buffer[usedspace], 56 - usedspace);
+ } else {
+ if (usedspace < 64) {
+ MEMSET_BZERO(&context->s1.buffer[usedspace], 64 - usedspace);
+ }
+ /* Do second-to-last transform: */
+ SHA1_Internal_Transform(context, (sha_word32*)context->s1.buffer);
+
+ /* And set-up for the last transform: */
+ MEMSET_BZERO(context->s1.buffer, 56);
+ }
+ /* Clean up: */
+ usedspace = 0;
+ }
+ /* Set the bit count: */
+#if BYTE_ORDER == LITTLE_ENDIAN
+ /* Convert FROM host byte order */
+ REVERSE64(context->s1.bitcount,context->s1.bitcount);
+#endif
+ *(sha_word64*)&context->s1.buffer[56] = context->s1.bitcount;
+
+ /* Final transform: */
+ SHA1_Internal_Transform(context, (sha_word32*)context->s1.buffer);
+
+ /* Save the hash data for output: */
+#if BYTE_ORDER == LITTLE_ENDIAN
+ {
+ /* Convert TO host byte order */
+ int j;
+ for (j = 0; j < (SHA1_DIGEST_LENGTH >> 2); j++) {
+ REVERSE32(context->s1.state[j],context->s1.state[j]);
+ *d++ = context->s1.state[j];
+ }
+ }
+#else
+ MEMCPY_BCOPY(d, context->s1.state, SHA1_DIGEST_LENGTH);
+#endif
+
+ /* Clean up: */
+ MEMSET_BZERO(context, sizeof(*context));
+}
+
+char *SHA1_End(SHA_CTX* context, char buffer[]) {
+ sha_byte digest[SHA1_DIGEST_LENGTH], *d = digest;
+ int i;
+
+ /* Sanity check: */
+ assert(context != (SHA_CTX*)0);
+
+ if (buffer != (char*)0) {
+ SHA1_Final(digest, context);
+
+ for (i = 0; i < SHA1_DIGEST_LENGTH; i++) {
+ *buffer++ = sha_hex_digits[(*d & 0xf0) >> 4];
+ *buffer++ = sha_hex_digits[*d & 0x0f];
+ d++;
+ }
+ *buffer = (char)0;
+ } else {
+ MEMSET_BZERO(context, sizeof(*context));
+ }
+ MEMSET_BZERO(digest, SHA1_DIGEST_LENGTH);
+ return buffer;
+}
+
+char* SHA1_Data(const sha_byte* data, size_t len, char digest[SHA1_DIGEST_STRING_LENGTH]) {
+ SHA_CTX context;
+
+ SHA1_Init(&context);
+ SHA1_Update(&context, data, len);
+ return SHA1_End(&context, digest);
+}
+
+
+/*** SHA-256: *********************************************************/
+void SHA256_Internal_Init(SHA_CTX* context, const sha_word32* ihv) {
+ /* Sanity check: */
+ assert(context != (SHA_CTX*)0);
+
+ MEMCPY_BCOPY(context->s256.state, ihv, sizeof(sha_word32) * 8);
+ MEMSET_BZERO(context->s256.buffer, 64);
+ context->s256.bitcount = 0;
+}
+
+void SHA256_Init(SHA_CTX* context) {
+ SHA256_Internal_Init(context, sha256_initial_hash_value);
+}
+
+#ifdef SHA2_UNROLL_TRANSFORM
+
+/* Unrolled SHA-256 round macros: */
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+
+#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \
+ REVERSE32(*data++, W256[j]); \
+ T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
+ K256[j] + W256[j]; \
+ (d) += T1; \
+ (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
+ j++
+
+
+#else /* BYTE_ORDER == LITTLE_ENDIAN */
+
+#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \
+ T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
+ K256[j] + (W256[j] = *data++); \
+ (d) += T1; \
+ (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
+ j++
+
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+
+#define ROUND256(a,b,c,d,e,f,g,h) \
+ s0 = W256[(j+1)&0x0f]; \
+ s0 = sigma0_256(s0); \
+ s1 = W256[(j+14)&0x0f]; \
+ s1 = sigma1_256(s1); \
+ T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \
+ (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \
+ (d) += T1; \
+ (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
+ j++
+
+void SHA256_Internal_Transform(SHA_CTX* context, const sha_word32* data) {
+ sha_word32 a, b, c, d, e, f, g, h, s0, s1;
+ sha_word32 T1, *W256;
+ int j;
+
+ W256 = (sha_word32*)context->s256.buffer;
+
+ /* Initialize registers with the prev. intermediate value */
+ a = context->s256.state[0];
+ b = context->s256.state[1];
+ c = context->s256.state[2];
+ d = context->s256.state[3];
+ e = context->s256.state[4];
+ f = context->s256.state[5];
+ g = context->s256.state[6];
+ h = context->s256.state[7];
+
+ j = 0;
+ do {
+ /* Rounds 0 to 15 (unrolled): */
+ ROUND256_0_TO_15(a,b,c,d,e,f,g,h);
+ ROUND256_0_TO_15(h,a,b,c,d,e,f,g);
+ ROUND256_0_TO_15(g,h,a,b,c,d,e,f);
+ ROUND256_0_TO_15(f,g,h,a,b,c,d,e);
+ ROUND256_0_TO_15(e,f,g,h,a,b,c,d);
+ ROUND256_0_TO_15(d,e,f,g,h,a,b,c);
+ ROUND256_0_TO_15(c,d,e,f,g,h,a,b);
+ ROUND256_0_TO_15(b,c,d,e,f,g,h,a);
+ } while (j < 16);
+
+ /* Now for the remaining rounds to 64: */
+ do {
+ ROUND256(a,b,c,d,e,f,g,h);
+ ROUND256(h,a,b,c,d,e,f,g);
+ ROUND256(g,h,a,b,c,d,e,f);
+ ROUND256(f,g,h,a,b,c,d,e);
+ ROUND256(e,f,g,h,a,b,c,d);
+ ROUND256(d,e,f,g,h,a,b,c);
+ ROUND256(c,d,e,f,g,h,a,b);
+ ROUND256(b,c,d,e,f,g,h,a);
+ } while (j < 64);
+
+ /* Compute the current intermediate hash value */
+ context->s256.state[0] += a;
+ context->s256.state[1] += b;
+ context->s256.state[2] += c;
+ context->s256.state[3] += d;
+ context->s256.state[4] += e;
+ context->s256.state[5] += f;
+ context->s256.state[6] += g;
+ context->s256.state[7] += h;
+
+ /* Clean up */
+ a = b = c = d = e = f = g = h = T1 = 0;
+}
+
+#else /* SHA2_UNROLL_TRANSFORM */
+
+void SHA256_Internal_Transform(SHA_CTX* context, const sha_word32* data) {
+ sha_word32 a, b, c, d, e, f, g, h, s0, s1;
+ sha_word32 T1, T2, *W256;
+ int j;
+
+ W256 = (sha_word32*)context->s256.buffer;
+
+ /* Initialize registers with the prev. intermediate value */
+ a = context->s256.state[0];
+ b = context->s256.state[1];
+ c = context->s256.state[2];
+ d = context->s256.state[3];
+ e = context->s256.state[4];
+ f = context->s256.state[5];
+ g = context->s256.state[6];
+ h = context->s256.state[7];
+
+ j = 0;
+ do {
+#if BYTE_ORDER == LITTLE_ENDIAN
+ /* Copy data while converting to host byte order */
+ REVERSE32(*data++,W256[j]);
+ /* Apply the SHA-256 compression function to update a..h */
+ T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
+#else /* BYTE_ORDER == LITTLE_ENDIAN */
+ /* Apply the SHA-256 compression function to update a..h with copy */
+ T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++);
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+ T2 = Sigma0_256(a) + Maj(a, b, c);
+ h = g;
+ g = f;
+ f = e;
+ e = d + T1;
+ d = c;
+ c = b;
+ b = a;
+ a = T1 + T2;
+
+ j++;
+ } while (j < 16);
+
+ do {
+ /* Part of the message block expansion: */
+ s0 = W256[(j+1)&0x0f];
+ s0 = sigma0_256(s0);
+ s1 = W256[(j+14)&0x0f];
+ s1 = sigma1_256(s1);
+
+ /* Apply the SHA-256 compression function to update a..h */
+ T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] +
+ (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0);
+ T2 = Sigma0_256(a) + Maj(a, b, c);
+ h = g;
+ g = f;
+ f = e;
+ e = d + T1;
+ d = c;
+ c = b;
+ b = a;
+ a = T1 + T2;
+
+ j++;
+ } while (j < 64);
+
+ /* Compute the current intermediate hash value */
+ context->s256.state[0] += a;
+ context->s256.state[1] += b;
+ context->s256.state[2] += c;
+ context->s256.state[3] += d;
+ context->s256.state[4] += e;
+ context->s256.state[5] += f;
+ context->s256.state[6] += g;
+ context->s256.state[7] += h;
+
+ /* Clean up */
+ a = b = c = d = e = f = g = h = T1 = T2 = 0;
+}
+
+#endif /* SHA2_UNROLL_TRANSFORM */
+
+void SHA256_Update(SHA_CTX* context, const sha_byte *data, size_t len) {
+ unsigned int freespace, usedspace;
+
+ if (len == 0) {
+ /* Calling with no data is valid - we do nothing */
+ return;
+ }
+
+ /* Sanity check: */
+ assert(context != (SHA_CTX*)0 && data != (sha_byte*)0);
+
+ usedspace = (unsigned int)((context->s256.bitcount >> 3) % 64);
+ if (usedspace > 0) {
+ /* Calculate how much free space is available in the buffer */
+ freespace = 64 - usedspace;
+
+ if (len >= freespace) {
+ /* Fill the buffer completely and process it */
+ MEMCPY_BCOPY(&context->s256.buffer[usedspace], data, freespace);
+ context->s256.bitcount += freespace << 3;
+ len -= freespace;
+ data += freespace;
+ SHA256_Internal_Transform(context, (sha_word32*)context->s256.buffer);
+ } else {
+ /* The buffer is not yet full */
+ MEMCPY_BCOPY(&context->s256.buffer[usedspace], data, len);
+ context->s256.bitcount += len << 3;
+ /* Clean up: */
+ usedspace = freespace = 0;
+ return;
+ }
+ }
+ while (len >= 64) {
+ /* Process as many complete blocks as we can */
+ SHA256_Internal_Transform(context, (sha_word32*)data);
+ context->s256.bitcount += 512;
+ len -= 64;
+ data += 64;
+ }
+ if (len > 0) {
+ /* There's left-overs, so save 'em */
+ MEMCPY_BCOPY(context->s256.buffer, data, len);
+ context->s256.bitcount += len << 3;
+ }
+ /* Clean up: */
+ usedspace = freespace = 0;
+}
+
+void SHA256_Internal_Last(SHA_CTX* context) {
+ unsigned int usedspace;
+
+ usedspace = (unsigned int)((context->s256.bitcount >> 3) % 64);
+#if BYTE_ORDER == LITTLE_ENDIAN
+ /* Convert FROM host byte order */
+ REVERSE64(context->s256.bitcount,context->s256.bitcount);
+#endif
+ if (usedspace > 0) {
+ /* Begin padding with a 1 bit: */
+ context->s256.buffer[usedspace++] = 0x80;
+
+ if (usedspace <= 56) {
+ /* Set-up for the last transform: */
+ MEMSET_BZERO(&context->s256.buffer[usedspace], 56 - usedspace);
+ } else {
+ if (usedspace < 64) {
+ MEMSET_BZERO(&context->s256.buffer[usedspace], 64 - usedspace);
+ }
+ /* Do second-to-last transform: */
+ SHA256_Internal_Transform(context, (sha_word32*)context->s256.buffer);
+
+ /* And set-up for the last transform: */
+ MEMSET_BZERO(context->s256.buffer, 56);
+ }
+ /* Clean up: */
+ usedspace = 0;
+ } else {
+ /* Set-up for the last transform: */
+ MEMSET_BZERO(context->s256.buffer, 56);
+
+ /* Begin padding with a 1 bit: */
+ *context->s256.buffer = 0x80;
+ }
+ /* Set the bit count: */
+ *(sha_word64*)&context->s256.buffer[56] = context->s256.bitcount;
+
+ /* Final transform: */
+ SHA256_Internal_Transform(context, (sha_word32*)context->s256.buffer);
+}
+
+void SHA256_Final(sha_byte digest[], SHA_CTX* context) {
+ sha_word32 *d = (sha_word32*)digest;
+
+ /* Sanity check: */
+ assert(context != (SHA_CTX*)0);
+
+ /* If no digest buffer is passed, we don't bother doing this: */
+ if (digest != (sha_byte*)0) {
+ SHA256_Internal_Last(context);
+
+ /* Save the hash data for output: */
+#if BYTE_ORDER == LITTLE_ENDIAN
+ {
+ /* Convert TO host byte order */
+ int j;
+ for (j = 0; j < (SHA256_DIGEST_LENGTH >> 2); j++) {
+ REVERSE32(context->s256.state[j],context->s256.state[j]);
+ *d++ = context->s256.state[j];
+ }
+ }
+#else
+ MEMCPY_BCOPY(d, context->s256.state, SHA256_DIGEST_LENGTH);
+#endif
+ }
+
+ /* Clean up state data: */
+ MEMSET_BZERO(context, sizeof(*context));
+}
+
+char *SHA256_End(SHA_CTX* context, char buffer[]) {
+ sha_byte digest[SHA256_DIGEST_LENGTH], *d = digest;
+ int i;
+
+ /* Sanity check: */
+ assert(context != (SHA_CTX*)0);
+
+ if (buffer != (char*)0) {
+ SHA256_Final(digest, context);
+
+ for (i = 0; i < SHA256_DIGEST_LENGTH; i++) {
+ *buffer++ = sha_hex_digits[(*d & 0xf0) >> 4];
+ *buffer++ = sha_hex_digits[*d & 0x0f];
+ d++;
+ }
+ *buffer = (char)0;
+ } else {
+ MEMSET_BZERO(context, sizeof(*context));
+ }
+ MEMSET_BZERO(digest, SHA256_DIGEST_LENGTH);
+ return buffer;
+}
+
+char* SHA256_Data(const sha_byte* data, size_t len, char digest[SHA256_DIGEST_STRING_LENGTH]) {
+ SHA_CTX context;
+
+ SHA256_Init(&context);
+ SHA256_Update(&context, data, len);
+ return SHA256_End(&context, digest);
+}
+
+
+/*** SHA-224: *********************************************************/
+void SHA224_Init(SHA_CTX* context) {
+ SHA256_Internal_Init(context, sha224_initial_hash_value);
+}
+
+void SHA224_Internal_Transform(SHA_CTX* context, const sha_word32* data) {
+ SHA256_Internal_Transform(context, data);
+}
+
+void SHA224_Update(SHA_CTX* context, const sha_byte *data, size_t len) {
+ SHA256_Update(context, data, len);
+}
+
+void SHA224_Final(sha_byte digest[], SHA_CTX* context) {
+ sha_word32 *d = (sha_word32*)digest;
+
+ /* Sanity check: */
+ assert(context != (SHA_CTX*)0);
+
+ /* If no digest buffer is passed, we don't bother doing this: */
+ if (digest != (sha_byte*)0) {
+ SHA256_Internal_Last(context);
+
+ /* Save the hash data for output: */
+#if BYTE_ORDER == LITTLE_ENDIAN
+ {
+ /* Convert TO host byte order */
+ int j;
+ for (j = 0; j < (SHA224_DIGEST_LENGTH >> 2); j++) {
+ REVERSE32(context->s256.state[j],context->s256.state[j]);
+ *d++ = context->s256.state[j];
+ }
+ }
+#else
+ MEMCPY_BCOPY(d, context->s256.state, SHA224_DIGEST_LENGTH);
+#endif
+ }
+
+ /* Clean up state data: */
+ MEMSET_BZERO(context, sizeof(*context));
+}
+
+char *SHA224_End(SHA_CTX* context, char buffer[]) {
+ sha_byte digest[SHA224_DIGEST_LENGTH], *d = digest;
+ int i;
+
+ /* Sanity check: */
+ assert(context != (SHA_CTX*)0);
+
+ if (buffer != (char*)0) {
+ SHA224_Final(digest, context);
+
+ for (i = 0; i < SHA224_DIGEST_LENGTH; i++) {
+ *buffer++ = sha_hex_digits[(*d & 0xf0) >> 4];
+ *buffer++ = sha_hex_digits[*d & 0x0f];
+ d++;
+ }
+ *buffer = (char)0;
+ } else {
+ MEMSET_BZERO(context, sizeof(*context));
+ }
+ MEMSET_BZERO(digest, SHA224_DIGEST_LENGTH);
+ return buffer;
+}
+
+char* SHA224_Data(const sha_byte* data, size_t len, char digest[SHA224_DIGEST_STRING_LENGTH]) {
+ SHA_CTX context;
+
+ SHA224_Init(&context);
+ SHA224_Update(&context, data, len);
+ return SHA224_End(&context, digest);
+}
+
+
+/*** SHA-512: *********************************************************/
+void SHA512_Internal_Init(SHA_CTX* context, const sha_word64* ihv) {
+ /* Sanity check: */
+ assert(context != (SHA_CTX*)0);
+
+ MEMCPY_BCOPY(context->s512.state, ihv, sizeof(sha_word64) * 8);
+ MEMSET_BZERO(context->s512.buffer, 128);
+ context->s512.bitcount[0] = context->s512.bitcount[1] = 0;
+}
+
+void SHA512_Init(SHA_CTX* context) {
+ SHA512_Internal_Init(context, sha512_initial_hash_value);
+}
+
+#ifdef SHA2_UNROLL_TRANSFORM
+
+/* Unrolled SHA-512 round macros: */
+#if BYTE_ORDER == LITTLE_ENDIAN
+
+#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \
+ REVERSE64(*data++, W512[j]); \
+ T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
+ K512[j] + W512[j]; \
+ (d) += T1, \
+ (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \
+ j++
+
+
+#else /* BYTE_ORDER == LITTLE_ENDIAN */
+
+#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \
+ T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
+ K512[j] + (W512[j] = *data++); \
+ (d) += T1; \
+ (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
+ j++
+
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+
+#define ROUND512(a,b,c,d,e,f,g,h) \
+ s0 = W512[(j+1)&0x0f]; \
+ s0 = sigma0_512(s0); \
+ s1 = W512[(j+14)&0x0f]; \
+ s1 = sigma1_512(s1); \
+ T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \
+ (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \
+ (d) += T1; \
+ (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
+ j++
+
+void SHA512_Internal_Transform(SHA_CTX* context, const sha_word64* data) {
+ sha_word64 a, b, c, d, e, f, g, h, s0, s1;
+ sha_word64 T1, *W512 = (sha_word64*)context->s512.buffer;
+ int j;
+
+ /* Initialize registers with the prev. intermediate value */
+ a = context->s512.state[0];
+ b = context->s512.state[1];
+ c = context->s512.state[2];
+ d = context->s512.state[3];
+ e = context->s512.state[4];
+ f = context->s512.state[5];
+ g = context->s512.state[6];
+ h = context->s512.state[7];
+
+ j = 0;
+ do {
+ ROUND512_0_TO_15(a,b,c,d,e,f,g,h);
+ ROUND512_0_TO_15(h,a,b,c,d,e,f,g);
+ ROUND512_0_TO_15(g,h,a,b,c,d,e,f);
+ ROUND512_0_TO_15(f,g,h,a,b,c,d,e);
+ ROUND512_0_TO_15(e,f,g,h,a,b,c,d);
+ ROUND512_0_TO_15(d,e,f,g,h,a,b,c);
+ ROUND512_0_TO_15(c,d,e,f,g,h,a,b);
+ ROUND512_0_TO_15(b,c,d,e,f,g,h,a);
+ } while (j < 16);
+
+ /* Now for the remaining rounds up to 79: */
+ do {
+ ROUND512(a,b,c,d,e,f,g,h);
+ ROUND512(h,a,b,c,d,e,f,g);
+ ROUND512(g,h,a,b,c,d,e,f);
+ ROUND512(f,g,h,a,b,c,d,e);
+ ROUND512(e,f,g,h,a,b,c,d);
+ ROUND512(d,e,f,g,h,a,b,c);
+ ROUND512(c,d,e,f,g,h,a,b);
+ ROUND512(b,c,d,e,f,g,h,a);
+ } while (j < 80);
+
+ /* Compute the current intermediate hash value */
+ context->s512.state[0] += a;
+ context->s512.state[1] += b;
+ context->s512.state[2] += c;
+ context->s512.state[3] += d;
+ context->s512.state[4] += e;
+ context->s512.state[5] += f;
+ context->s512.state[6] += g;
+ context->s512.state[7] += h;
+
+ /* Clean up */
+ a = b = c = d = e = f = g = h = T1 = 0;
+}
+
+#else /* SHA2_UNROLL_TRANSFORM */
+
+void SHA512_Internal_Transform(SHA_CTX* context, const sha_word64* data) {
+ sha_word64 a, b, c, d, e, f, g, h, s0, s1;
+ sha_word64 T1, T2, *W512 = (sha_word64*)context->s512.buffer;
+ int j;
+
+ /* Initialize registers with the prev. intermediate value */
+ a = context->s512.state[0];
+ b = context->s512.state[1];
+ c = context->s512.state[2];
+ d = context->s512.state[3];
+ e = context->s512.state[4];
+ f = context->s512.state[5];
+ g = context->s512.state[6];
+ h = context->s512.state[7];
+
+ j = 0;
+ do {
+#if BYTE_ORDER == LITTLE_ENDIAN
+ /* Convert TO host byte order */
+ REVERSE64(*data++, W512[j]);
+ /* Apply the SHA-512 compression function to update a..h */
+ T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];
+#else /* BYTE_ORDER == LITTLE_ENDIAN */
+ /* Apply the SHA-512 compression function to update a..h with copy */
+ T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++);
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+ T2 = Sigma0_512(a) + Maj(a, b, c);
+ h = g;
+ g = f;
+ f = e;
+ e = d + T1;
+ d = c;
+ c = b;
+ b = a;
+ a = T1 + T2;
+
+ j++;
+ } while (j < 16);
+
+ do {
+ /* Part of the message block expansion: */
+ s0 = W512[(j+1)&0x0f];
+ s0 = sigma0_512(s0);
+ s1 = W512[(j+14)&0x0f];
+ s1 = sigma1_512(s1);
+
+ /* Apply the SHA-512 compression function to update a..h */
+ T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] +
+ (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0);
+ T2 = Sigma0_512(a) + Maj(a, b, c);
+ h = g;
+ g = f;
+ f = e;
+ e = d + T1;
+ d = c;
+ c = b;
+ b = a;
+ a = T1 + T2;
+
+ j++;
+ } while (j < 80);
+
+ /* Compute the current intermediate hash value */
+ context->s512.state[0] += a;
+ context->s512.state[1] += b;
+ context->s512.state[2] += c;
+ context->s512.state[3] += d;
+ context->s512.state[4] += e;
+ context->s512.state[5] += f;
+ context->s512.state[6] += g;
+ context->s512.state[7] += h;
+
+ /* Clean up */
+ a = b = c = d = e = f = g = h = T1 = T2 = 0;
+}
+
+#endif /* SHA2_UNROLL_TRANSFORM */
+
+void SHA512_Update(SHA_CTX* context, const sha_byte *data, size_t len) {
+ unsigned int freespace, usedspace;
+
+ if (len == 0) {
+ /* Calling with no data is valid - we do nothing */
+ return;
+ }
+
+ /* Sanity check: */
+ assert(context != (SHA_CTX*)0 && data != (sha_byte*)0);
+
+ usedspace = (unsigned int)((context->s512.bitcount[0] >> 3) % 128);
+ if (usedspace > 0) {
+ /* Calculate how much free space is available in the buffer */
+ freespace = 128 - usedspace;
+
+ if (len >= freespace) {
+ /* Fill the buffer completely and process it */
+ MEMCPY_BCOPY(&context->s512.buffer[usedspace], data, freespace);
+ ADDINC128(context->s512.bitcount, freespace << 3);
+ len -= freespace;
+ data += freespace;
+ SHA512_Internal_Transform(context, (sha_word64*)context->s512.buffer);
+ } else {
+ /* The buffer is not yet full */
+ MEMCPY_BCOPY(&context->s512.buffer[usedspace], data, len);
+ ADDINC128(context->s512.bitcount, len << 3);
+ /* Clean up: */
+ usedspace = freespace = 0;
+ return;
+ }
+ }
+ while (len >= 128) {
+ /* Process as many complete blocks as we can */
+ SHA512_Internal_Transform(context, (sha_word64*)data);
+ ADDINC128(context->s512.bitcount, 1024);
+ len -= 128;
+ data += 128;
+ }
+ if (len > 0) {
+ /* There's left-overs, so save 'em */
+ MEMCPY_BCOPY(context->s512.buffer, data, len);
+ ADDINC128(context->s512.bitcount, len << 3);
+ }
+ /* Clean up: */
+ usedspace = freespace = 0;
+}
+
+void SHA512_Internal_Last(SHA_CTX* context) {
+ unsigned int usedspace;
+
+ usedspace = (unsigned int)((context->s512.bitcount[0] >> 3) % 128);
+#if BYTE_ORDER == LITTLE_ENDIAN
+ /* Convert FROM host byte order */
+ REVERSE64(context->s512.bitcount[0],context->s512.bitcount[0]);
+ REVERSE64(context->s512.bitcount[1],context->s512.bitcount[1]);
+#endif
+ if (usedspace > 0) {
+ /* Begin padding with a 1 bit: */
+ context->s512.buffer[usedspace++] = 0x80;
+
+ if (usedspace <= 112) {
+ /* Set-up for the last transform: */
+ MEMSET_BZERO(&context->s512.buffer[usedspace], 112 - usedspace);
+ } else {
+ if (usedspace < 128) {
+ MEMSET_BZERO(&context->s512.buffer[usedspace], 128 - usedspace);
+ }
+ /* Do second-to-last transform: */
+ SHA512_Internal_Transform(context, (sha_word64*)context->s512.buffer);
+
+ /* And set-up for the last transform: */
+ MEMSET_BZERO(context->s512.buffer, 112);
+ }
+ /* Clean up: */
+ usedspace = 0;
+ } else {
+ /* Prepare for final transform: */
+ MEMSET_BZERO(context->s512.buffer, 112);
+
+ /* Begin padding with a 1 bit: */
+ *context->s512.buffer = 0x80;
+ }
+ /* Store the length of input data (in bits): */
+ *(sha_word64*)&context->s512.buffer[112] = context->s512.bitcount[1];
+ *(sha_word64*)&context->s512.buffer[120] = context->s512.bitcount[0];
+
+ /* Final transform: */
+ SHA512_Internal_Transform(context, (sha_word64*)context->s512.buffer);
+}
+
+void SHA512_Final(sha_byte digest[], SHA_CTX* context) {
+ sha_word64 *d = (sha_word64*)digest;
+
+ /* Sanity check: */
+ assert(context != (SHA_CTX*)0);
+
+ /* If no digest buffer is passed, we don't bother doing this: */
+ if (digest != (sha_byte*)0) {
+ SHA512_Internal_Last(context);
+
+ /* Save the hash data for output: */
+#if BYTE_ORDER == LITTLE_ENDIAN
+ {
+ /* Convert TO host byte order */
+ int j;
+ for (j = 0; j < (SHA512_DIGEST_LENGTH >> 3); j++) {
+ REVERSE64(context->s512.state[j],context->s512.state[j]);
+ *d++ = context->s512.state[j];
+ }
+ }
+#else
+ MEMCPY_BCOPY(d, context->s512.state, SHA512_DIGEST_LENGTH);
+#endif
+ }
+
+ /* Zero out state data */
+ MEMSET_BZERO(context, sizeof(*context));
+}
+
+char *SHA512_End(SHA_CTX* context, char buffer[]) {
+ sha_byte digest[SHA512_DIGEST_LENGTH], *d = digest;
+ int i;
+
+ /* Sanity check: */
+ assert(context != (SHA_CTX*)0);
+
+ if (buffer != (char*)0) {
+ SHA512_Final(digest, context);
+
+ for (i = 0; i < SHA512_DIGEST_LENGTH; i++) {
+ *buffer++ = sha_hex_digits[(*d & 0xf0) >> 4];
+ *buffer++ = sha_hex_digits[*d & 0x0f];
+ d++;
+ }
+ *buffer = (char)0;
+ } else {
+ MEMSET_BZERO(context, sizeof(*context));
+ }
+ MEMSET_BZERO(digest, SHA512_DIGEST_LENGTH);
+ return buffer;
+}
+
+char* SHA512_Data(const sha_byte* data, size_t len, char digest[SHA512_DIGEST_STRING_LENGTH]) {
+ SHA_CTX context;
+
+ SHA512_Init(&context);
+ SHA512_Update(&context, data, len);
+ return SHA512_End(&context, digest);
+}
+
+
+/*** SHA-384: *********************************************************/
+void SHA384_Init(SHA_CTX* context) {
+ SHA512_Internal_Init(context, sha384_initial_hash_value);
+}
+
+void SHA384_Update(SHA_CTX* context, const sha_byte* data, size_t len) {
+ SHA512_Update(context, data, len);
+}
+
+void SHA384_Final(sha_byte digest[], SHA_CTX* context) {
+ sha_word64 *d = (sha_word64*)digest;
+
+ /* Sanity check: */
+ assert(context != (SHA_CTX*)0);
+
+ /* If no digest buffer is passed, we don't bother doing this: */
+ if (digest != (sha_byte*)0) {
+ SHA512_Internal_Last(context);
+
+ /* Save the hash data for output: */
+#if BYTE_ORDER == LITTLE_ENDIAN
+ {
+ /* Convert TO host byte order */
+ int j;
+ for (j = 0; j < (SHA384_DIGEST_LENGTH >> 3); j++) {
+ REVERSE64(context->s512.state[j],context->s512.state[j]);
+ *d++ = context->s512.state[j];
+ }
+ }
+#else
+ MEMCPY_BCOPY(d, context->s512.state, SHA384_DIGEST_LENGTH);
+#endif
+ }
+
+ /* Zero out state data */
+ MEMSET_BZERO(context, sizeof(*context));
+}
+
+char *SHA384_End(SHA_CTX* context, char buffer[]) {
+ sha_byte digest[SHA384_DIGEST_LENGTH], *d = digest;
+ int i;
+
+ /* Sanity check: */
+ assert(context != (SHA_CTX*)0);
+
+ if (buffer != (char*)0) {
+ SHA384_Final(digest, context);
+
+ for (i = 0; i < SHA384_DIGEST_LENGTH; i++) {
+ *buffer++ = sha_hex_digits[(*d & 0xf0) >> 4];
+ *buffer++ = sha_hex_digits[*d & 0x0f];
+ d++;
+ }
+ *buffer = (char)0;
+ } else {
+ MEMSET_BZERO(context, sizeof(*context));
+ }
+ MEMSET_BZERO(digest, SHA384_DIGEST_LENGTH);
+ return buffer;
+}
+
+char* SHA384_Data(const sha_byte* data, size_t len, char digest[SHA384_DIGEST_STRING_LENGTH]) {
+ SHA_CTX context;
+
+ SHA384_Init(&context);
+ SHA384_Update(&context, data, len);
+ return SHA384_End(&context, digest);
+}
diff --git a/Source/cm_sha2.h b/Source/cm_sha2.h
new file mode 100644
index 000000000..71395f06b
--- /dev/null
+++ b/Source/cm_sha2.h
@@ -0,0 +1,140 @@
+/*
+ * FILE: sha2.h
+ * AUTHOR: Aaron D. Gifford
+ * http://www.aarongifford.com/computers/sha.html
+ *
+ * Copyright (c) 2000-2003, Aaron D. Gifford
+ * 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 copyright holder nor the names of contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(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 OR CONTRIBUTOR(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.
+ *
+ * $Id: sha2.h,v 1.4 2004/01/07 19:06:18 adg Exp $
+ */
+
+#ifndef __SHA2_H__
+#define __SHA2_H__
+
+#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;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+ * Import u_intXX_t size_t type definitions from system headers. You
+ * may need to change this, or define these things yourself in this
+ * file.
+ */
+#include <sys/types.h>
+
+/*** SHA-224/256/384/512 Various Length Definitions *******************/
+
+/* Digest lengths for SHA-1/224/256/384/512 */
+#define SHA1_DIGEST_LENGTH 20
+#define SHA1_DIGEST_STRING_LENGTH (SHA1_DIGEST_LENGTH * 2 + 1)
+#define SHA224_DIGEST_LENGTH 28
+#define SHA224_DIGEST_STRING_LENGTH (SHA224_DIGEST_LENGTH * 2 + 1)
+#define SHA256_DIGEST_LENGTH 32
+#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1)
+#define SHA384_DIGEST_LENGTH 48
+#define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1)
+#define SHA512_DIGEST_LENGTH 64
+#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1)
+
+
+/*** SHA-224/256/384/512 Context Structures ***************************/
+
+typedef union _SHA_CTX {
+ /* SHA-1 uses this part of the union: */
+ struct {
+ cm_sha2_uint32_t state[5];
+ cm_sha2_uint64_t bitcount;
+ cm_sha2_uint8_t buffer[64];
+ } s1;
+
+ /* SHA-224 and SHA-256 use this part of the union: */
+ struct {
+ cm_sha2_uint32_t state[8];
+ cm_sha2_uint64_t bitcount;
+ cm_sha2_uint8_t buffer[64];
+ } s256;
+
+ /* SHA-384 and SHA-512 use this part of the union: */
+ struct {
+ cm_sha2_uint64_t state[8];
+ cm_sha2_uint64_t bitcount[2];
+ cm_sha2_uint8_t buffer[128];
+ } s512;
+} SHA_CTX;
+
+/*** SHA-256/384/512 Function Prototypes ******************************/
+
+void SHA1_Init(SHA_CTX*);
+void SHA1_Update(SHA_CTX*, const cm_sha2_uint8_t*, size_t);
+void SHA1_Final(cm_sha2_uint8_t[SHA1_DIGEST_LENGTH], SHA_CTX*);
+char* SHA1_End(SHA_CTX*, char[SHA1_DIGEST_STRING_LENGTH]);
+char* SHA1_Data(const cm_sha2_uint8_t*, size_t,
+ char[SHA1_DIGEST_STRING_LENGTH]);
+
+void SHA224_Init(SHA_CTX*);
+void SHA224_Update(SHA_CTX*, const cm_sha2_uint8_t*, size_t);
+void SHA224_Final(cm_sha2_uint8_t[SHA224_DIGEST_LENGTH], SHA_CTX*);
+char* SHA224_End(SHA_CTX*, char[SHA224_DIGEST_STRING_LENGTH]);
+char* SHA224_Data(const cm_sha2_uint8_t*, size_t,
+ char[SHA224_DIGEST_STRING_LENGTH]);
+
+void SHA256_Init(SHA_CTX*);
+void SHA256_Update(SHA_CTX*, const cm_sha2_uint8_t*, size_t);
+void SHA256_Final(cm_sha2_uint8_t[SHA256_DIGEST_LENGTH], SHA_CTX*);
+char* SHA256_End(SHA_CTX*, char[SHA256_DIGEST_STRING_LENGTH]);
+char* SHA256_Data(const cm_sha2_uint8_t*, size_t,
+ char[SHA256_DIGEST_STRING_LENGTH]);
+
+void SHA384_Init(SHA_CTX*);
+void SHA384_Update(SHA_CTX*, const cm_sha2_uint8_t*, size_t);
+void SHA384_Final(cm_sha2_uint8_t[SHA384_DIGEST_LENGTH], SHA_CTX*);
+char* SHA384_End(SHA_CTX*, char[SHA384_DIGEST_STRING_LENGTH]);
+char* SHA384_Data(const cm_sha2_uint8_t*, size_t,
+ char[SHA384_DIGEST_STRING_LENGTH]);
+
+void SHA512_Init(SHA_CTX*);
+void SHA512_Update(SHA_CTX*, const cm_sha2_uint8_t*, size_t);
+void SHA512_Final(cm_sha2_uint8_t[SHA512_DIGEST_LENGTH], SHA_CTX*);
+char* SHA512_End(SHA_CTX*, char[SHA512_DIGEST_STRING_LENGTH]);
+char* SHA512_Data(const cm_sha2_uint8_t*, size_t,
+ char[SHA512_DIGEST_STRING_LENGTH]);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __SHA2_H__ */
diff --git a/Source/cm_sha2_mangle.h b/Source/cm_sha2_mangle.h
new file mode 100644
index 000000000..e73d13141
--- /dev/null
+++ b/Source/cm_sha2_mangle.h
@@ -0,0 +1,51 @@
+/*============================================================================
+ 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 cm_sha2_mangle_h
+#define cm_sha2_mangle_h
+
+/* Mangle sha2 symbol names to avoid possible conflict with
+ implementations in other libraries to which CMake links. */
+#define SHA1_Data cmSHA1_Data
+#define SHA1_End cmSHA1_End
+#define SHA1_Final cmSHA1_Final
+#define SHA1_Init cmSHA1_Init
+#define SHA1_Internal_Transform cmSHA1_Internal_Transform
+#define SHA1_Update cmSHA1_Update
+#define SHA224_Data cmSHA224_Data
+#define SHA224_End cmSHA224_End
+#define SHA224_Final cmSHA224_Final
+#define SHA224_Init cmSHA224_Init
+#define SHA224_Internal_Transform cmSHA224_Internal_Transform
+#define SHA224_Update cmSHA224_Update
+#define SHA256_Data cmSHA256_Data
+#define SHA256_End cmSHA256_End
+#define SHA256_Final cmSHA256_Final
+#define SHA256_Init cmSHA256_Init
+#define SHA256_Internal_Init cmSHA256_Internal_Init
+#define SHA256_Internal_Last cmSHA256_Internal_Last
+#define SHA256_Internal_Transform cmSHA256_Internal_Transform
+#define SHA256_Update cmSHA256_Update
+#define SHA384_Data cmSHA384_Data
+#define SHA384_End cmSHA384_End
+#define SHA384_Final cmSHA384_Final
+#define SHA384_Init cmSHA384_Init
+#define SHA384_Update cmSHA384_Update
+#define SHA512_Data cmSHA512_Data
+#define SHA512_End cmSHA512_End
+#define SHA512_Final cmSHA512_Final
+#define SHA512_Init cmSHA512_Init
+#define SHA512_Internal_Init cmSHA512_Internal_Init
+#define SHA512_Internal_Last cmSHA512_Internal_Last
+#define SHA512_Internal_Transform cmSHA512_Internal_Transform
+#define SHA512_Update cmSHA512_Update
+
+#endif
diff --git a/Source/cm_utf8.c b/Source/cm_utf8.c
new file mode 100644
index 000000000..c9bf259ac
--- /dev/null
+++ b/Source/cm_utf8.c
@@ -0,0 +1,84 @@
+/*============================================================================
+ 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 "cm_utf8.h"
+
+/*
+ RFC 3629
+ 07-bit: 0xxxxxxx
+ 11-bit: 110xxxxx 10xxxxxx
+ 16-bit: 1110xxxx 10xxxxxx 10xxxxxx
+ 21-bit: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+
+ Pre-RFC Compatibility
+ 26-bit: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
+ 31-bit: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
+*/
+
+/* Number of leading ones before a zero in the byte. */
+static unsigned char const cm_utf8_ones[256] = {
+ 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,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,0,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,7,8
+};
+
+/* Mask away control bits from bytes with n leading ones. */
+static unsigned char const cm_utf8_mask[7] = {
+ 0xEF, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01
+};
+
+/* Minimum allowed value when first byte has n leading ones. */
+static unsigned int const cm_utf8_min[7] = {
+ 0, 0, 1u<<7, 1u<<11, 1u<<16, 1u<<21, 1u<<26 /*, 1u<<31 */
+};
+
+/*--------------------------------------------------------------------------*/
+const char* cm_utf8_decode_character(const char* first, const char* last,
+ unsigned int* pc)
+{
+ /* Count leading ones in the first byte. */
+ unsigned char c = (unsigned char)*first++;
+ unsigned char const ones = cm_utf8_ones[c];
+ switch(ones)
+ {
+ case 0: *pc = c; return first; /* One-byte character. */
+ case 1: case 7: case 8: return 0; /* Invalid leading byte. */
+ default: break;
+ }
+
+ /* Extract bits from this multi-byte character. */
+ {
+ unsigned int uc = c & cm_utf8_mask[ones];
+ int left;
+ for(left = ones-1; left && first != last; --left)
+ {
+ c = (unsigned char)*first++;
+ if(cm_utf8_ones[c] != 1)
+ {
+ return 0;
+ }
+ uc = (uc << 6) | (c & cm_utf8_mask[1]);
+ }
+
+ if(left > 0 || uc < cm_utf8_min[ones])
+ {
+ return 0;
+ }
+
+ *pc = uc;
+ return first;
+ }
+}
diff --git a/Source/cm_utf8.h b/Source/cm_utf8.h
new file mode 100644
index 000000000..06e2868d5
--- /dev/null
+++ b/Source/cm_utf8.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 cm_utf8_h
+#define cm_utf8_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Decode one UTF-8 character from the input byte range. On success,
+ stores the unicode character number in *pc and returns the first
+ position not extracted. On failure, returns 0. */
+const char* cm_utf8_decode_character(const char* first, const char* last,
+ unsigned int* pc);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
new file mode 100644
index 000000000..fdc42fa2b
--- /dev/null
+++ b/Source/cmake.cxx
@@ -0,0 +1,4529 @@
+/*============================================================================
+ 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 "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"
+
+#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>
+#endif
+
+#include <cmsys/Directory.hxx>
+#include <cmsys/Process.h>
+#include <cmsys/Glob.hxx>
+#include <cmsys/RegularExpression.hxx>
+
+// only build kdevelop generator on non-windows platforms
+// when not bootstrapping cmake
+#if !defined(_WIN32)
+# if defined(CMAKE_BUILD_WITH_CMAKE)
+# define CMAKE_USE_KDEVELOP
+# endif
+#endif
+
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+# define CMAKE_USE_ECLIPSE
+#endif
+
+#if defined(__MINGW32__) && !defined(CMAKE_BUILD_WITH_CMAKE)
+# define CMAKE_BOOT_MINGW
+#endif
+
+// include the generator
+#if defined(_WIN32) && !defined(__CYGWIN__)
+# if !defined(CMAKE_BOOT_MINGW)
+# include "cmGlobalVisualStudio6Generator.h"
+# include "cmGlobalVisualStudio7Generator.h"
+# include "cmGlobalVisualStudio71Generator.h"
+# include "cmGlobalVisualStudio8Generator.h"
+# include "cmGlobalVisualStudio9Generator.h"
+# include "cmGlobalVisualStudio9IA64Generator.h"
+# include "cmGlobalVisualStudio9Win64Generator.h"
+# include "cmGlobalVisualStudio10Generator.h"
+# include "cmGlobalVisualStudio10IA64Generator.h"
+# include "cmGlobalVisualStudio10Win64Generator.h"
+# include "cmGlobalVisualStudio11Generator.h"
+# include "cmGlobalVisualStudio11Win64Generator.h"
+# include "cmGlobalVisualStudio11ARMGenerator.h"
+# include "cmGlobalVisualStudio8Win64Generator.h"
+# include "cmGlobalBorlandMakefileGenerator.h"
+# include "cmGlobalNMakeMakefileGenerator.h"
+# include "cmGlobalJOMMakefileGenerator.h"
+# include "cmGlobalWatcomWMakeGenerator.h"
+# define CMAKE_HAVE_VS_GENERATORS
+# endif
+# include "cmGlobalMSYSMakefileGenerator.h"
+# include "cmGlobalMinGWMakefileGenerator.h"
+# include "cmWin32ProcessExecution.h"
+#else
+#endif
+#include "cmGlobalUnixMakefileGenerator3.h"
+#include "cmGlobalNinjaGenerator.h"
+
+
+#if defined(CMAKE_HAVE_VS_GENERATORS)
+#include "cmCallVisualStudioMacro.h"
+#endif
+
+#if !defined(CMAKE_BOOT_MINGW)
+# include "cmExtraCodeBlocksGenerator.h"
+#endif
+
+#ifdef CMAKE_USE_KDEVELOP
+# include "cmGlobalKdevelopGenerator.h"
+#endif
+
+#ifdef CMAKE_USE_ECLIPSE
+# include "cmExtraEclipseCDT4Generator.h"
+#endif
+
+#include <stdlib.h> // required for atoi
+
+#if defined( __APPLE__ )
+# if defined(CMAKE_BUILD_WITH_CMAKE)
+# include "cmGlobalXCodeGenerator.h"
+# define CMAKE_USE_XCODE 1
+# endif
+# include <sys/types.h>
+# include <sys/time.h>
+# include <sys/resource.h>
+#endif
+
+#include <sys/stat.h> // struct stat
+
+#include <memory> // auto_ptr
+
+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_COMPATABILITY 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*)
+{
+ cmake* cm = reinterpret_cast<cmake*>(ctx);
+ cm->MarkCliAsUsed(variable);
+}
+
+cmake::cmake()
+{
+ this->Trace = 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();
+
+#ifdef __APPLE__
+ struct rlimit rlp;
+ if(!getrlimit(RLIMIT_STACK, &rlp))
+ {
+ if(rlp.rlim_cur != rlp.rlim_max)
+ {
+ rlp.rlim_cur = rlp.rlim_max;
+ setrlimit(RLIMIT_STACK, &rlp);
+ }
+ }
+#endif
+
+ this->Verbose = false;
+ this->InTryCompile = false;
+ this->CacheManager = new cmCacheManager(this);
+ this->GlobalGenerator = 0;
+ this->ProgressCallback = 0;
+ this->ProgressCallbackClientData = 0;
+ this->CurrentWorkingMode = NORMAL_MODE;
+
+#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();
+ this->AddDefaultExtraGenerators();
+ this->AddDefaultCommands();
+
+ // Make sure we can capture the build tool output.
+ cmSystemTools::EnableVSConsoleOutput();
+}
+
+cmake::~cmake()
+{
+ delete this->CacheManager;
+ delete this->Policies;
+ if (this->GlobalGenerator)
+ {
+ delete this->GlobalGenerator;
+ this->GlobalGenerator = 0;
+ }
+ for(RegisteredCommandsMap::iterator j = this->Commands.begin();
+ j != this->Commands.end(); ++j)
+ {
+ delete (*j).second;
+ }
+#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());
+ }
+}
+
+// Parse the args
+bool cmake::SetCacheArgs(const std::vector<std::string>& args)
+{
+ bool findPackageMode = false;
+ for(unsigned int i=1; i < args.size(); ++i)
+ {
+ std::string arg = args[i];
+ if(arg.find("-D",0) == 0)
+ {
+ std::string entry = arg.substr(2);
+ if(entry.size() == 0)
+ {
+ ++i;
+ if(i < args.size())
+ {
+ entry = args[i];
+ }
+ else
+ {
+ cmSystemTools::Error("-D must be followed with VAR=VALUE.");
+ return false;
+ }
+ }
+ std::string var, value;
+ cmCacheManager::CacheEntryType type = cmCacheManager::UNINITIALIZED;
+ if(cmCacheManager::ParseEntry(entry.c_str(), var, value, type))
+ {
+ this->CacheManager->AddCacheEntry(var.c_str(), value.c_str(),
+ "No help, variable specified on the command line.", type);
+ if(this->WarnUnusedCli)
+ {
+ this->WatchUnusedCli(var.c_str());
+ }
+ }
+ else
+ {
+ std::cerr << "Parse error in command line argument: " << arg << "\n"
+ << "Should be: VAR:type=value\n";
+ cmSystemTools::Error("No cmake script provided.");
+ return false;
+ }
+ }
+ else if(arg.find("-Wno-dev",0) == 0)
+ {
+ this->SuppressDevWarnings = true;
+ this->DoSuppressDevWarnings = true;
+ }
+ else if(arg.find("-Wdev",0) == 0)
+ {
+ this->SuppressDevWarnings = false;
+ this->DoSuppressDevWarnings = true;
+ }
+ else if(arg.find("-U",0) == 0)
+ {
+ std::string entryPattern = arg.substr(2);
+ if(entryPattern.size() == 0)
+ {
+ ++i;
+ if(i < args.size())
+ {
+ entryPattern = args[i];
+ }
+ else
+ {
+ cmSystemTools::Error("-U must be followed with VAR.");
+ return false;
+ }
+ }
+ cmsys::RegularExpression regex(
+ cmsys::Glob::PatternToRegex(entryPattern.c_str(), 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() )
+ {
+ cmCacheManager::CacheEntryType t = it.GetType();
+ if(t != cmCacheManager::STATIC)
+ {
+ std::string entryName = it.GetName();
+ if (regex.find(entryName.c_str()))
+ {
+ entriesToDelete.push_back(entryName);
+ }
+ }
+ }
+
+ // now remove them from the cache
+ for(std::vector<std::string>::const_iterator currentEntry =
+ entriesToDelete.begin();
+ currentEntry != entriesToDelete.end();
+ ++currentEntry)
+ {
+ this->CacheManager->RemoveCacheEntry(currentEntry->c_str());
+ }
+ }
+ else if(arg.find("-C",0) == 0)
+ {
+ std::string path = arg.substr(2);
+ if ( path.size() == 0 )
+ {
+ ++i;
+ if(i < args.size())
+ {
+ path = args[i];
+ }
+ else
+ {
+ cmSystemTools::Error("-C must be followed by a file name.");
+ return false;
+ }
+ }
+ std::cerr << "loading initial cache file " << path.c_str() << "\n";
+ this->ReadListFile(args, path.c_str());
+ }
+ else if(arg.find("-P",0) == 0)
+ {
+ i++;
+ if(i >= args.size())
+ {
+ cmSystemTools::Error("-P must be followed by a file name.");
+ return false;
+ }
+ std::string path = args[i];
+ if ( path.size() == 0 )
+ {
+ cmSystemTools::Error("No cmake script provided.");
+ return false;
+ }
+ this->ReadListFile(args, path.c_str());
+ }
+ else if (arg.find("--find-package",0) == 0)
+ {
+ findPackageMode = true;
+ }
+ }
+
+ if (findPackageMode)
+ {
+ return this->FindPackage(args);
+ }
+
+ return true;
+}
+
+void cmake::ReadListFile(const std::vector<std::string>& args,
+ const char *path)
+{
+ // if a generator was not yet created, temporarily create one
+ cmGlobalGenerator *gg = this->GetGlobalGenerator();
+ bool created = false;
+
+ // if a generator was not specified use a generic one
+ if (!gg)
+ {
+ gg = new cmGlobalGenerator;
+ gg->SetCMakeInstance(this);
+ created = true;
+ }
+
+ // read in the list file to fill the cache
+ if(path)
+ {
+ std::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());
+ if (this->GetWorkingMode() != NORMAL_MODE)
+ {
+ std::string file(cmSystemTools::CollapseFullPath(path));
+ cmSystemTools::ConvertToUnixSlashes(file);
+ lg->GetMakefile()->SetScriptModeFile(file.c_str());
+
+ lg->GetMakefile()->SetArgcArgv(args);
+ }
+ if (!lg->GetMakefile()->ReadListFile(0, path))
+ {
+ cmSystemTools::Error("Error processing file:", path);
+ }
+ }
+
+ // free generic one if generated
+ if (created)
+ {
+ delete gg;
+ }
+}
+
+
+bool cmake::FindPackage(const std::vector<std::string>& args)
+{
+ // if a generator was not yet created, temporarily create one
+ cmGlobalGenerator *gg = new cmGlobalGenerator;
+ gg->SetCMakeInstance(this);
+ this->SetGlobalGenerator(gg);
+
+ // read in the list file to fill the cache
+ std::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());
+
+ mf->SetArgcArgv(args);
+
+ std::string systemFile = mf->GetModulesFile("CMakeFindPackageMode.cmake");
+ mf->ReadListFile(0, systemFile.c_str());
+
+ std::string language = mf->GetSafeDefinition("LANGUAGE");
+ std::string mode = mf->GetSafeDefinition("MODE");
+ std::string packageName = mf->GetSafeDefinition("NAME");
+ bool packageFound = mf->IsOn("PACKAGE_FOUND");
+ bool quiet = mf->IsOn("PACKAGE_QUIET");
+
+ if (!packageFound)
+ {
+ if (!quiet)
+ {
+ printf("%s not found.\n", packageName.c_str());
+ }
+ }
+ else if (mode == "EXIST")
+ {
+ if (!quiet)
+ {
+ printf("%s found.\n", packageName.c_str());
+ }
+ }
+ else if (mode == "COMPILE")
+ {
+ std::string includes = mf->GetSafeDefinition("PACKAGE_INCLUDE_DIRS");
+ std::vector<std::string> includeDirs;
+ cmSystemTools::ExpandListArgument(includes, includeDirs);
+
+ std::string includeFlags = lg->GetIncludeFlags(includeDirs,
+ language.c_str(), false);
+
+ std::string definitions = mf->GetSafeDefinition("PACKAGE_DEFINITIONS");
+ printf("%s %s\n", includeFlags.c_str(), definitions.c_str());
+ }
+ else if (mode == "LINK")
+ {
+ const char* targetName = "dummy";
+ std::vector<std::string> srcs;
+ cmTarget* tgt = mf->AddExecutable(targetName, srcs, true);
+ tgt->SetProperty("LINKER_LANGUAGE", language.c_str());
+
+ std::string libs = mf->GetSafeDefinition("PACKAGE_LIBRARIES");
+ std::vector<std::string> libList;
+ cmSystemTools::ExpandListArgument(libs, libList);
+ for(std::vector<std::string>::const_iterator libIt=libList.begin();
+ libIt != libList.end();
+ ++libIt)
+ {
+ mf->AddLinkLibraryForTarget(targetName, libIt->c_str(),
+ cmTarget::GENERAL);
+ }
+
+
+ std::string linkLibs;
+ std::string flags;
+ std::string linkFlags;
+ lg->GetTargetFlags(linkLibs, flags, linkFlags, *tgt);
+
+ printf("%s\n", linkLibs.c_str() );
+
+/* if ( use_win32 )
+ {
+ tgt->SetProperty("WIN32_EXECUTABLE", "ON");
+ }
+ if ( use_macbundle)
+ {
+ tgt->SetProperty("MACOSX_BUNDLE", "ON");
+ }*/
+ }
+
+ // free generic one if generated
+// this->SetGlobalGenerator(0); // setting 0-pointer is not possible
+// delete gg; // this crashes inside the cmake instance
+
+ return packageFound;
+}
+
+
+// Parse the args
+void cmake::SetArgs(const std::vector<std::string>& args,
+ bool directoriesSetBefore)
+{
+ bool directoriesSet = directoriesSetBefore;
+ for(unsigned int i=1; i < args.size(); ++i)
+ {
+ std::string arg = args[i];
+ if(arg.find("-H",0) == 0)
+ {
+ directoriesSet = true;
+ std::string path = arg.substr(2);
+ path = cmSystemTools::CollapseFullPath(path.c_str());
+ cmSystemTools::ConvertToUnixSlashes(path);
+ this->SetHomeDirectory(path.c_str());
+ }
+ else if(arg.find("-S",0) == 0)
+ {
+ // There is no local generate anymore. Ignore -S option.
+ }
+ else if(arg.find("-O",0) == 0)
+ {
+ // There is no local generate anymore. Ignore -O option.
+ }
+ else if(arg.find("-B",0) == 0)
+ {
+ directoriesSet = true;
+ std::string path = arg.substr(2);
+ path = cmSystemTools::CollapseFullPath(path.c_str());
+ cmSystemTools::ConvertToUnixSlashes(path);
+ this->SetHomeOutputDirectory(path.c_str());
+ }
+ else if((i < args.size()-1) && (arg.find("--check-build-system",0) == 0))
+ {
+ this->CheckBuildSystemArgument = args[++i];
+ this->ClearBuildSystem = (atoi(args[++i].c_str()) > 0);
+ }
+ else if((i < args.size()-1) && (arg.find("--check-stamp-file",0) == 0))
+ {
+ this->CheckStampFile = args[++i];
+ }
+ else if((i < args.size()-1) && (arg.find("--check-stamp-list",0) == 0))
+ {
+ this->CheckStampList = args[++i];
+ }
+#if defined(CMAKE_HAVE_VS_GENERATORS)
+ else if((i < args.size()-1) && (arg.find("--vs-solution-file",0) == 0))
+ {
+ this->VSSolutionFile = args[++i];
+ }
+#endif
+ else if(arg.find("-V",0) == 0)
+ {
+ this->Verbose = true;
+ }
+ else if(arg.find("-D",0) == 0)
+ {
+ // skip for now
+ }
+ else if(arg.find("-U",0) == 0)
+ {
+ // skip for now
+ }
+ else if(arg.find("-C",0) == 0)
+ {
+ // skip for now
+ }
+ else if(arg.find("-P",0) == 0)
+ {
+ // skip for now
+ i++;
+ }
+ else if(arg.find("--find-package",0) == 0)
+ {
+ // skip for now
+ i++;
+ }
+ else if(arg.find("-Wno-dev",0) == 0)
+ {
+ // skip for now
+ }
+ else if(arg.find("-Wdev",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());
+ cmSystemTools::ConvertToUnixSlashes(path);
+ this->GraphVizFile = path;
+ if ( this->GraphVizFile.empty() )
+ {
+ cmSystemTools::Error("No file specified for --graphviz");
+ }
+ }
+ else if(arg.find("--debug-trycompile",0) == 0)
+ {
+ std::cout << "debug trycompile on\n";
+ this->DebugTryCompileOn();
+ }
+ else if(arg.find("--debug-output",0) == 0)
+ {
+ std::cout << "Running with debug output on.\n";
+ this->SetDebugOutputOn(true);
+ }
+ else if(arg.find("--trace",0) == 0)
+ {
+ std::cout << "Running with trace output on.\n";
+ this->SetTrace(true);
+ }
+ else if(arg.find("--warn-uninitialized",0) == 0)
+ {
+ std::cout << "Warn about uninitialized values.\n";
+ this->SetWarnUninitialized(true);
+ }
+ else if(arg.find("--warn-unused-vars",0) == 0)
+ {
+ std::cout << "Finding unused variables.\n";
+ this->SetWarnUnused(true);
+ }
+ else if(arg.find("--no-warn-unused-cli",0) == 0)
+ {
+ std::cout << "Not searching for unused variables given on the " <<
+ "command line.\n";
+ this->SetWarnUnusedCli(false);
+ }
+ else if(arg.find("--check-system-vars",0) == 0)
+ {
+ std::cout << "Also check system files when warning about unused and " <<
+ "uninitialized variables.\n";
+ this->SetCheckSystemVars(true);
+ }
+ else if(arg.find("-G",0) == 0)
+ {
+ std::string value = arg.substr(2);
+ if(value.size() == 0)
+ {
+ ++i;
+ if(i >= args.size())
+ {
+ cmSystemTools::Error("No generator specified for -G");
+ return;
+ }
+ value = args[i];
+ }
+ cmGlobalGenerator* gen =
+ this->CreateGlobalGenerator(value.c_str());
+ if(!gen)
+ {
+ cmSystemTools::Error("Could not create named generator ",
+ value.c_str());
+ }
+ else
+ {
+ this->SetGlobalGenerator(gen);
+ }
+ }
+ // no option assume it is the path to the source
+ else
+ {
+ directoriesSet = true;
+ this->SetDirectoriesFromFile(arg.c_str());
+ }
+ }
+ if(!directoriesSet)
+ {
+ this->SetHomeOutputDirectory
+ (cmSystemTools::GetCurrentWorkingDirectory().c_str());
+ this->SetStartOutputDirectory
+ (cmSystemTools::GetCurrentWorkingDirectory().c_str());
+ this->SetHomeDirectory
+ (cmSystemTools::GetCurrentWorkingDirectory().c_str());
+ this->SetStartDirectory
+ (cmSystemTools::GetCurrentWorkingDirectory().c_str());
+ }
+
+ this->SetStartDirectory(this->GetHomeDirectory());
+ this->SetStartOutputDirectory(this->GetHomeOutputDirectory());
+}
+
+//----------------------------------------------------------------------------
+void cmake::SetDirectoriesFromFile(const char* arg)
+{
+ // Check if the argument refers to a CMakeCache.txt or
+ // CMakeLists.txt file.
+ std::string listPath;
+ std::string cachePath;
+ bool argIsFile = false;
+ if(cmSystemTools::FileIsDirectory(arg))
+ {
+ std::string path = cmSystemTools::CollapseFullPath(arg);
+ cmSystemTools::ConvertToUnixSlashes(path);
+ std::string cacheFile = path;
+ cacheFile += "/CMakeCache.txt";
+ std::string listFile = path;
+ listFile += "/CMakeLists.txt";
+ if(cmSystemTools::FileExists(cacheFile.c_str()))
+ {
+ cachePath = path;
+ }
+ if(cmSystemTools::FileExists(listFile.c_str()))
+ {
+ listPath = path;
+ }
+ }
+ else if(cmSystemTools::FileExists(arg))
+ {
+ argIsFile = true;
+ std::string fullPath = cmSystemTools::CollapseFullPath(arg);
+ std::string name = cmSystemTools::GetFilenameName(fullPath.c_str());
+ name = cmSystemTools::LowerCase(name);
+ if(name == "cmakecache.txt")
+ {
+ cachePath = cmSystemTools::GetFilenamePath(fullPath.c_str());
+ }
+ else if(name == "cmakelists.txt")
+ {
+ listPath = cmSystemTools::GetFilenamePath(fullPath.c_str());
+ }
+ }
+ else
+ {
+ // 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());
+ name = cmSystemTools::LowerCase(name);
+ if(name == "cmakecache.txt" || name == "cmakelists.txt")
+ {
+ argIsFile = true;
+ listPath = cmSystemTools::GetFilenamePath(fullPath.c_str());
+ }
+ else
+ {
+ listPath = fullPath;
+ }
+ }
+
+ // If there is a CMakeCache.txt file, use its settings.
+ if(cachePath.length() > 0)
+ {
+ cmCacheManager* cachem = this->GetCacheManager();
+ cmCacheManager::CacheIterator it = cachem->NewIterator();
+ if(cachem->LoadCache(cachePath.c_str()) &&
+ it.Find("CMAKE_HOME_DIRECTORY"))
+ {
+ this->SetHomeOutputDirectory(cachePath.c_str());
+ this->SetStartOutputDirectory(cachePath.c_str());
+ this->SetHomeDirectory(it.GetValue());
+ this->SetStartDirectory(it.GetValue());
+ return;
+ }
+ }
+
+ // If there is a CMakeLists.txt file, use it as the source tree.
+ if(listPath.length() > 0)
+ {
+ this->SetHomeDirectory(listPath.c_str());
+ this->SetStartDirectory(listPath.c_str());
+
+ 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());
+ }
+ 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());
+ }
+ return;
+ }
+
+ // We didn't find a CMakeLists.txt or CMakeCache.txt file from the
+ // argument. Assume it is the path to the source tree, and use the
+ // 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());
+}
+
+// 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();
+#if __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 direcory 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";
+ }
+#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 direcory there?
+ modules = cMakeRoot + "/Modules/CMake.cmake";
+ }
+ if (!cmSystemTools::FileExists(modules.c_str()))
+ {
+ // couldn't find modules
+ cmSystemTools::Error("Could not find CMAKE_ROOT !!!\n"
+ "CMake has most likely not been installed correctly.\n"
+ "Modules directory not found in\n",
+ cMakeRoot.c_str());
+ 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 ... - create a tar "
+ "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"
+ << " 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_MERGE, 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);
+ std::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")
+ {
+ cmQtAutomoc automoc;
+ bool automocSuccess = automoc.Run(args[2].c_str());
+ 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());
+ }
+#endif
+ }
+
+ ::CMakeCommandUsage(args[0].c_str());
+ return 1;
+}
+
+void cmake::AddExtraGenerator(const char* name,
+ CreateExtraGeneratorFunctionType newFunction)
+{
+ cmExternalMakefileProjectGenerator* extraGenerator = newFunction();
+ const std::vector<std::string>& supportedGlobalGenerators =
+ extraGenerator->GetSupportedGlobalGenerators();
+
+ for(std::vector<std::string>::const_iterator
+ it = supportedGlobalGenerators.begin();
+ it != supportedGlobalGenerators.end();
+ ++it )
+ {
+ std::string fullName = cmExternalMakefileProjectGenerator::
+ CreateFullGeneratorName(it->c_str(), name);
+ this->ExtraGenerators[fullName.c_str()] = newFunction;
+ }
+ delete extraGenerator;
+}
+
+void cmake::AddDefaultExtraGenerators()
+{
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ // e.g. kdevelop4 ?
+#endif
+
+ this->AddExtraGenerator(cmExtraCodeBlocksGenerator::GetActualName(),
+ &cmExtraCodeBlocksGenerator::New);
+
+#ifdef CMAKE_USE_ECLIPSE
+ this->AddExtraGenerator(cmExtraEclipseCDT4Generator::GetActualName(),
+ &cmExtraEclipseCDT4Generator::New);
+#endif
+
+#ifdef CMAKE_USE_KDEVELOP
+ this->AddExtraGenerator(cmGlobalKdevelopGenerator::GetActualName(),
+ &cmGlobalKdevelopGenerator::New);
+ // for kdevelop also add the generator with just the name of the
+ // extra generator, since it was this way since cmake 2.2
+ this->ExtraGenerators[cmGlobalKdevelopGenerator::GetActualName()]
+ = &cmGlobalKdevelopGenerator::New;
+#endif
+
+#endif
+}
+
+
+//----------------------------------------------------------------------------
+void cmake::GetRegisteredGenerators(std::vector<std::string>& names)
+{
+ for(RegisteredGeneratorsMap::const_iterator i = this->Generators.begin();
+ i != this->Generators.end(); ++i)
+ {
+ names.push_back(i->first);
+ }
+ for(RegisteredExtraGeneratorsMap::const_iterator
+ i = this->ExtraGenerators.begin();
+ i != this->ExtraGenerators.end(); ++i)
+ {
+ names.push_back(i->first);
+ }
+}
+
+cmGlobalGenerator* cmake::CreateGlobalGenerator(const char* name)
+{
+ cmGlobalGenerator* generator = 0;
+ cmExternalMakefileProjectGenerator* extraGenerator = 0;
+ RegisteredGeneratorsMap::const_iterator genIt = this->Generators.find(name);
+ if(genIt == this->Generators.end())
+ {
+ RegisteredExtraGeneratorsMap::const_iterator extraGenIt =
+ this->ExtraGenerators.find(name);
+ if (extraGenIt == this->ExtraGenerators.end())
+ {
+ return 0;
+ }
+ extraGenerator = (extraGenIt->second)();
+ genIt=this->Generators.find(extraGenerator->GetGlobalGeneratorName(name));
+ if(genIt == this->Generators.end())
+ {
+ delete extraGenerator;
+ return 0;
+ }
+ }
+
+ generator = (genIt->second)();
+ generator->SetCMakeInstance(this);
+ generator->SetExternalMakefileProjectGenerator(extraGenerator);
+ return generator;
+}
+
+void cmake::SetHomeDirectory(const char* dir)
+{
+ this->cmHomeDirectory = dir;
+ cmSystemTools::ConvertToUnixSlashes(this->cmHomeDirectory);
+}
+
+void cmake::SetHomeOutputDirectory(const char* lib)
+{
+ this->HomeOutputDirectory = lib;
+ cmSystemTools::ConvertToUnixSlashes(this->HomeOutputDirectory);
+}
+
+void cmake::SetGlobalGenerator(cmGlobalGenerator *gg)
+{
+ if(!gg)
+ {
+ cmSystemTools::Error("Error SetGlobalGenerator called with null");
+ return;
+ }
+ // delete the old generator
+ if (this->GlobalGenerator)
+ {
+ delete this->GlobalGenerator;
+ // restore the original environment variables CXX and CC
+ // Restore CC
+ std::string env = "CC=";
+ if(this->CCEnvironment.size())
+ {
+ env += this->CCEnvironment;
+ }
+ cmSystemTools::PutEnv(env.c_str());
+ env = "CXX=";
+ if(this->CXXEnvironment.size())
+ {
+ env += this->CXXEnvironment;
+ }
+ cmSystemTools::PutEnv(env.c_str());
+ }
+
+ // set the new
+ this->GlobalGenerator = gg;
+
+ // 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
+ (this->GlobalGenerator->GetForceUnixPaths());
+
+ // Save the environment variables CXX and CC
+ const char* cxx = getenv("CXX");
+ const char* cc = getenv("CC");
+ if(cxx)
+ {
+ this->CXXEnvironment = cxx;
+ }
+ else
+ {
+ this->CXXEnvironment = "";
+ }
+ if(cc)
+ {
+ this->CCEnvironment = cc;
+ }
+ else
+ {
+ 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.
+ std::string srcList = this->GetHomeDirectory();
+ srcList += "/CMakeLists.txt";
+ if(!cmSystemTools::FileExists(srcList.c_str()))
+ {
+ cmOStringStream err;
+ if(cmSystemTools::FileIsDirectory(this->GetHomeDirectory()))
+ {
+ err << "The source directory \"" << this->GetHomeDirectory()
+ << "\" does not appear to contain CMakeLists.txt.\n";
+ }
+ else if(cmSystemTools::FileExists(this->GetHomeDirectory()))
+ {
+ err << "The source directory \"" << this->GetHomeDirectory()
+ << "\" is a file, not a directory.\n";
+ }
+ else
+ {
+ err << "The source directory \"" << this->GetHomeDirectory()
+ << "\" does not exist.\n";
+ }
+ err << "Specify --help for usage, or press the help button on the CMake "
+ "GUI.";
+ cmSystemTools::Error(err.str().c_str());
+ return -2;
+ }
+
+ // do a sanity check on some values
+ if(this->CacheManager->GetCacheValue("CMAKE_HOME_DIRECTORY"))
+ {
+ std::string cacheStart =
+ this->CacheManager->GetCacheValue("CMAKE_HOME_DIRECTORY");
+ cacheStart += "/CMakeLists.txt";
+ std::string currentStart = this->GetHomeDirectory();
+ currentStart += "/CMakeLists.txt";
+ if(!cmSystemTools::SameFile(cacheStart.c_str(), currentStart.c_str()))
+ {
+ std::string message = "The source \"";
+ message += currentStart;
+ message += "\" does not match the source \"";
+ message += cacheStart;
+ message += "\" used to generate cache. ";
+ message += "Re-run cmake with a different source directory.";
+ cmSystemTools::Error(message.c_str());
+ return -2;
+ }
+ }
+ else
+ {
+ return 0;
+ }
+ return 1;
+}
+struct SaveCacheEntry
+{
+ std::string key;
+ std::string value;
+ std::string help;
+ cmCacheManager::CacheEntryType type;
+};
+
+int cmake::HandleDeleteCacheVariables(const char* var)
+{
+ std::vector<std::string> argsSplit;
+ cmSystemTools::ExpandListArgument(std::string(var), argsSplit);
+ // erase the property to avoid infinite recursion
+ this->SetProperty("__CMAKE_DELETE_CACHE_CHANGE_VARS_", "");
+ if(this->GetIsInTryCompile())
+ {
+ return 0;
+ }
+ cmCacheManager::CacheIterator ci = this->CacheManager->NewIterator();
+ std::vector<SaveCacheEntry> saved;
+ cmOStringStream 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"
+ << "The following variables have changed:\n";
+ for(std::vector<std::string>::iterator i = argsSplit.begin();
+ i != argsSplit.end(); ++i)
+ {
+ SaveCacheEntry save;
+ save.key = *i;
+ warning << *i << "= ";
+ i++;
+ save.value = *i;
+ warning << *i << "\n";
+ if(ci.Find(save.key.c_str()))
+ {
+ save.type = ci.GetType();
+ save.help = ci.GetProperty("HELPSTRING");
+ }
+ saved.push_back(save);
+ }
+
+ // remove the cache
+ this->CacheManager->DeleteCache(this->GetStartOutputDirectory());
+ // 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(),
+ i->help.c_str(), i->type);
+ }
+ cmSystemTools::Message(warning.str().c_str());
+ // avoid reconfigure if there were errors
+ if(!cmSystemTools::GetErrorOccuredFlag())
+ {
+ // re-run configure
+ return this->Configure();
+ }
+ return 0;
+}
+
+int cmake::Configure()
+{
+ if(this->DoSuppressDevWarnings)
+ {
+ if(this->SuppressDevWarnings)
+ {
+ this->CacheManager->
+ AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_WARNINGS", "TRUE",
+ "Suppress Warnings that are meant for"
+ " the author of the CMakeLists.txt files.",
+ cmCacheManager::INTERNAL);
+ }
+ else
+ {
+ this->CacheManager->
+ AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_WARNINGS", "FALSE",
+ "Suppress Warnings that are meant for"
+ " the author of the CMakeLists.txt files.",
+ cmCacheManager::INTERNAL);
+ }
+ }
+ int ret = this->ActualConfigure();
+ const char* delCacheVars =
+ this->GetProperty("__CMAKE_DELETE_CACHE_CHANGE_VARS_");
+ if(delCacheVars && delCacheVars[0] != 0)
+ {
+ return this->HandleDeleteCacheVariables(delCacheVars);
+ }
+ return ret;
+
+}
+
+int cmake::ActualConfigure()
+{
+ // Construct right now our path conversion table before it's too late:
+ this->UpdateConversionPathTable();
+ this->CleanupCommandsAndMacros();
+
+ int res = 0;
+ if ( this->GetWorkingMode() == NORMAL_MODE )
+ {
+ res = this->DoPreConfigureChecks();
+ }
+ if ( res < 0 )
+ {
+ return -2;
+ }
+ if ( !res )
+ {
+ this->CacheManager->AddCacheEntry
+ ("CMAKE_HOME_DIRECTORY",
+ this->GetHomeDirectory(),
+ "Start directory with the top level CMakeLists.txt file for this "
+ "project",
+ cmCacheManager::INTERNAL);
+ }
+
+ // no generator specified on the command line
+ if(!this->GlobalGenerator)
+ {
+ const char* genName =
+ this->CacheManager->GetCacheValue("CMAKE_GENERATOR");
+ const char* extraGenName =
+ this->CacheManager->GetCacheValue("CMAKE_EXTRA_GENERATOR");
+ if(genName)
+ {
+ std::string fullName = cmExternalMakefileProjectGenerator::
+ CreateFullGeneratorName(genName, extraGenName);
+ this->GlobalGenerator = this->CreateGlobalGenerator(fullName.c_str());
+ }
+ if(this->GlobalGenerator)
+ {
+ // 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
+ (this->GlobalGenerator->GetForceUnixPaths());
+ }
+ else
+ {
+#if defined(__BORLANDC__) && defined(_WIN32)
+ this->SetGlobalGenerator(new cmGlobalBorlandMakefileGenerator);
+#elif 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
+ const std::string vsregBase =
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\";
+ std::vector<std::string> vsVerions;
+ vsVerions.push_back("VisualStudio\\");
+ vsVerions.push_back("VCExpress\\");
+ struct VSRegistryEntryName
+ {
+ const char* MSVersion;
+ const char* GeneratorName;
+ };
+ VSRegistryEntryName version[] = {
+ {"6.0", "Visual Studio 6"},
+ {"7.0", "Visual Studio 7"},
+ {"7.1", "Visual Studio 7 .NET 2003"},
+ {"8.0", "Visual Studio 8 2005"},
+ {"9.0", "Visual Studio 9 2008"},
+ {"10.0", "Visual Studio 10"},
+ {0, 0}};
+ for(size_t b=0; b < vsVerions.size() && installedCompiler.empty(); b++)
+ {
+ for(int i =0; version[i].MSVersion != 0; i++)
+ {
+ std::string reg = vsregBase + vsVerions[b] + version[i].MSVersion;
+ reg += ";InstallDir]";
+ cmSystemTools::ExpandRegistryValues(reg,
+ cmSystemTools::KeyWOW64_32);
+ if (!(reg == "/registry"))
+ {
+ installedCompiler = version[i].GeneratorName;
+ }
+ }
+ }
+ cmGlobalGenerator* gen
+ = this->CreateGlobalGenerator(installedCompiler.c_str());
+ if(!gen)
+ {
+ gen = new cmGlobalNMakeMakefileGenerator;
+ }
+ this->SetGlobalGenerator(gen);
+ std::cout << "-- Building for: " << gen->GetName() << "\n";
+#else
+ this->SetGlobalGenerator(new cmGlobalUnixMakefileGenerator3);
+#endif
+ }
+ if(!this->GlobalGenerator)
+ {
+ cmSystemTools::Error("Could not create generator");
+ return -1;
+ }
+ }
+
+ const char* genName = this->CacheManager->GetCacheValue("CMAKE_GENERATOR");
+ if(genName)
+ {
+ if(strcmp(this->GlobalGenerator->GetName(), genName) != 0)
+ {
+ 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.";
+ cmSystemTools::Error(message.c_str());
+ return -2;
+ }
+ }
+ if(!this->CacheManager->GetCacheValue("CMAKE_GENERATOR"))
+ {
+ this->CacheManager->AddCacheEntry("CMAKE_GENERATOR",
+ this->GlobalGenerator->GetName(),
+ "Name of generator.",
+ cmCacheManager::INTERNAL);
+ this->CacheManager->AddCacheEntry("CMAKE_EXTRA_GENERATOR",
+ this->GlobalGenerator->GetExtraGeneratorName(),
+ "Name of external makefile project generator.",
+ cmCacheManager::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)
+ {
+ this->GlobalGenerator->ClearEnabledLanguages();
+ }
+
+ // Truncate log files
+ if (!this->InTryCompile)
+ {
+ this->TruncateOutputLog("CMakeOutput.log");
+ this->TruncateOutputLog("CMakeError.log");
+ }
+
+ // actually do the configure
+ this->GlobalGenerator->Configure();
+ // Before saving the cache
+ // if the project did not define one of the entries below, add them now
+ // so users can edit the values in the cache:
+
+ // We used to always present LIBRARY_OUTPUT_PATH and
+ // EXECUTABLE_OUTPUT_PATH. They are now documented as old-style and
+ // should no longer be used. Therefore we present them only if the
+ // project requires compatibility with CMake 2.4. We detect this
+ // here by looking for the old CMAKE_BACKWARDS_COMPATABILITY
+ // variable created when CMP0001 is not set to NEW.
+ if(this->GetCacheManager()->GetCacheValue("CMAKE_BACKWARDS_COMPATIBILITY"))
+ {
+ if(!this->CacheManager->GetCacheValue("LIBRARY_OUTPUT_PATH"))
+ {
+ this->CacheManager->AddCacheEntry
+ ("LIBRARY_OUTPUT_PATH", "",
+ "Single output directory for building all libraries.",
+ cmCacheManager::PATH);
+ }
+ if(!this->CacheManager->GetCacheValue("EXECUTABLE_OUTPUT_PATH"))
+ {
+ this->CacheManager->AddCacheEntry
+ ("EXECUTABLE_OUTPUT_PATH", "",
+ "Single output directory for building all executables.",
+ cmCacheManager::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");
+ }
+ // 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());
+ }
+ if(cmSystemTools::GetErrorOccuredFlag())
+ {
+ return -1;
+ }
+ return 0;
+}
+
+void cmake::PreLoadCMakeFiles()
+{
+ std::vector<std::string> args;
+ std::string pre_load = this->GetHomeDirectory();
+ if ( pre_load.size() > 0 )
+ {
+ pre_load += "/PreLoad.cmake";
+ if ( cmSystemTools::FileExists(pre_load.c_str()) )
+ {
+ this->ReadListFile(args, pre_load.c_str());
+ }
+ }
+ pre_load = this->GetHomeOutputDirectory();
+ if ( pre_load.size() > 0 )
+ {
+ pre_load += "/PreLoad.cmake";
+ if ( cmSystemTools::FileExists(pre_load.c_str()) )
+ {
+ this->ReadListFile(args, pre_load.c_str());
+ }
+ }
+}
+
+// handle a command line invocation
+int cmake::Run(const std::vector<std::string>& args, bool noconfigure)
+{
+ // Process the arguments
+ this->SetArgs(args);
+ if(cmSystemTools::GetErrorOccuredFlag())
+ {
+ return -1;
+ }
+
+ // If we are given a stamp list file check if it is really out of date.
+ if(!this->CheckStampList.empty() &&
+ cmakeCheckStampList(this->CheckStampList.c_str()))
+ {
+ return 0;
+ }
+
+ // If we are given a stamp file check if it is really out of date.
+ if(!this->CheckStampFile.empty() &&
+ cmakeCheckStampFile(this->CheckStampFile.c_str()))
+ {
+ return 0;
+ }
+
+ // set the cmake command
+ this->CMakeCommand = args[0];
+
+ if ( this->GetWorkingMode() == NORMAL_MODE )
+ {
+ // load the cache
+ if(this->LoadCache() < 0)
+ {
+ cmSystemTools::Error("Error executing cmake::LoadCache(). Aborting.\n");
+ return -1;
+ }
+ }
+ else
+ {
+ this->AddCMakePaths();
+ }
+ // Add any cache args
+ if ( !this->SetCacheArgs(args) )
+ {
+ cmSystemTools::Error("Problem processing arguments. Aborting.\n");
+ return -1;
+ }
+
+ // In script mode we terminate after running the script.
+ if(this->GetWorkingMode() != NORMAL_MODE)
+ {
+ if(cmSystemTools::GetErrorOccuredFlag())
+ {
+ return -1;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ // If MAKEFLAGS are given in the environment, remove the environment
+ // variable. This will prevent try-compile from succeeding when it
+ // should fail (if "-i" is an option). We cannot simply test
+ // whether "-i" is given and remove it because some make programs
+ // encode the MAKEFLAGS variable in a strange way.
+ if(getenv("MAKEFLAGS"))
+ {
+ cmSystemTools::PutEnv("MAKEFLAGS=");
+ }
+
+ this->PreLoadCMakeFiles();
+
+ std::string systemFile = this->GetHomeOutputDirectory();
+ systemFile += "/CMakeSystem.cmake";
+
+ if ( noconfigure )
+ {
+ return 0;
+ }
+
+ // now run the global generate
+ // Check the state of the build system to see if we need to regenerate.
+ if(!this->CheckBuildSystem())
+ {
+ 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)
+ {
+#if defined(CMAKE_HAVE_VS_GENERATORS)
+ if(!this->VSSolutionFile.empty() && this->GlobalGenerator)
+ {
+ // CMake is running to regenerate a Visual Studio build tree
+ // during a build from the VS IDE. The build files cannot be
+ // regenerated, so we should stop the build.
+ cmSystemTools::Message(
+ "CMake Configure step failed. "
+ "Build files cannot be regenerated correctly. "
+ "Attempting to stop IDE build.");
+ cmGlobalVisualStudioGenerator* gg =
+ static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator);
+ gg->CallVisualStudioMacro(cmGlobalVisualStudioGenerator::MacroStop,
+ this->VSSolutionFile.c_str());
+ }
+#endif
+ return ret;
+ }
+ ret = this->Generate();
+ 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;
+}
+
+int cmake::Generate()
+{
+ if(!this->GlobalGenerator)
+ {
+ return -1;
+ }
+ this->GlobalGenerator->Generate();
+ if(this->WarnUnusedCli)
+ {
+ this->RunCheckForUnusedVariables();
+ }
+ if(cmSystemTools::GetErrorOccuredFlag())
+ {
+ 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());
+ }
+ return 0;
+}
+
+void cmake::AddCacheEntry(const char* key, const char* value,
+ const char* helpString,
+ int type)
+{
+ this->CacheManager->AddCacheEntry(key, value,
+ helpString,
+ cmCacheManager::CacheEntryType(type));
+}
+
+const char* cmake::GetCacheDefinition(const char* name) const
+{
+ return this->CacheManager->GetCacheValue(name);
+}
+
+void cmake::AddDefaultCommands()
+{
+ std::list<cmCommand*> commands;
+ GetBootstrapCommands(commands);
+ GetPredefinedCommands(commands);
+ for(std::list<cmCommand*>::iterator i = commands.begin();
+ i != commands.end(); ++i)
+ {
+ this->AddCommand(*i);
+ }
+}
+
+void cmake::AddDefaultGenerators()
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+# if !defined(CMAKE_BOOT_MINGW)
+ this->Generators[cmGlobalVisualStudio6Generator::GetActualName()] =
+ &cmGlobalVisualStudio6Generator::New;
+ this->Generators[cmGlobalVisualStudio7Generator::GetActualName()] =
+ &cmGlobalVisualStudio7Generator::New;
+ this->Generators[cmGlobalVisualStudio10Generator::GetActualName()] =
+ &cmGlobalVisualStudio10Generator::New;
+ this->Generators[cmGlobalVisualStudio10IA64Generator::GetActualName()] =
+ &cmGlobalVisualStudio10IA64Generator::New;
+ this->Generators[cmGlobalVisualStudio10Win64Generator::GetActualName()] =
+ &cmGlobalVisualStudio10Win64Generator::New;
+ this->Generators[cmGlobalVisualStudio11Generator::GetActualName()] =
+ &cmGlobalVisualStudio11Generator::New;
+ this->Generators[cmGlobalVisualStudio11Win64Generator::GetActualName()] =
+ &cmGlobalVisualStudio11Win64Generator::New;
+ this->Generators[cmGlobalVisualStudio11ARMGenerator::GetActualName()] =
+ &cmGlobalVisualStudio11ARMGenerator::New;
+ this->Generators[cmGlobalVisualStudio71Generator::GetActualName()] =
+ &cmGlobalVisualStudio71Generator::New;
+ this->Generators[cmGlobalVisualStudio8Generator::GetActualName()] =
+ &cmGlobalVisualStudio8Generator::New;
+ this->Generators[cmGlobalVisualStudio9Generator::GetActualName()] =
+ &cmGlobalVisualStudio9Generator::New;
+ this->Generators[cmGlobalVisualStudio9IA64Generator::GetActualName()] =
+ &cmGlobalVisualStudio9IA64Generator::New;
+ this->Generators[cmGlobalVisualStudio9Win64Generator::GetActualName()] =
+ &cmGlobalVisualStudio9Win64Generator::New;
+ this->Generators[cmGlobalVisualStudio8Win64Generator::GetActualName()] =
+ &cmGlobalVisualStudio8Win64Generator::New;
+ this->Generators[cmGlobalBorlandMakefileGenerator::GetActualName()] =
+ &cmGlobalBorlandMakefileGenerator::New;
+ this->Generators[cmGlobalNMakeMakefileGenerator::GetActualName()] =
+ &cmGlobalNMakeMakefileGenerator::New;
+ this->Generators[cmGlobalJOMMakefileGenerator::GetActualName()] =
+ &cmGlobalJOMMakefileGenerator::New;
+ this->Generators[cmGlobalWatcomWMakeGenerator::GetActualName()] =
+ &cmGlobalWatcomWMakeGenerator::New;
+# endif
+ this->Generators[cmGlobalMSYSMakefileGenerator::GetActualName()] =
+ &cmGlobalMSYSMakefileGenerator::New;
+ this->Generators[cmGlobalMinGWMakefileGenerator::GetActualName()] =
+ &cmGlobalMinGWMakefileGenerator::New;
+#endif
+ this->Generators[cmGlobalUnixMakefileGenerator3::GetActualName()] =
+ &cmGlobalUnixMakefileGenerator3::New;
+ this->Generators[cmGlobalNinjaGenerator::GetActualName()] =
+ &cmGlobalNinjaGenerator::New;
+#ifdef CMAKE_USE_XCODE
+ this->Generators[cmGlobalXCodeGenerator::GetActualName()] =
+ &cmGlobalXCodeGenerator::New;
+#endif
+}
+
+int cmake::LoadCache()
+{
+ // could we not read the cache
+ if (!this->CacheManager->LoadCache(this->GetHomeOutputDirectory()))
+ {
+ // if it does exist, but isn't readable then warn the user
+ std::string cacheFile = this->GetHomeOutputDirectory();
+ cacheFile += "/CMakeCache.txt";
+ if(cmSystemTools::FileExists(cacheFile.c_str()))
+ {
+ cmSystemTools::Error(
+ "There is a CMakeCache.txt file for the current binary tree but "
+ "cmake does not have permission to read it. Please check the "
+ "permissions of the directory you are trying to run CMake on.");
+ return -1;
+ }
+ }
+
+ 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())
+ {
+ return -3;
+ }
+ return 0;
+}
+
+void cmake::SetProgressCallback(ProgressCallbackType f, void *cd)
+{
+ this->ProgressCallback = f;
+ this->ProgressCallbackClientData = cd;
+}
+
+void cmake::UpdateProgress(const char *msg, float prog)
+{
+ if(this->ProgressCallback && !this->InTryCompile)
+ {
+ (*this->ProgressCallback)(msg, prog, this->ProgressCallbackClientData);
+ return;
+ }
+}
+
+void cmake::GetCommandDocumentation(std::vector<cmDocumentationEntry>& v,
+ bool withCurrentCommands,
+ bool withCompatCommands) const
+{
+ for(RegisteredCommandsMap::const_iterator j = this->Commands.begin();
+ j != this->Commands.end(); ++j)
+ {
+ 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);
+ }
+}
+
+void cmake::GetPolicyDocumentation(std::vector<cmDocumentationEntry>& v)
+{
+ this->Policies->GetDocumentation(v);
+}
+
+void cmake::GetPropertiesDocumentation(std::map<std::string,
+ cmDocumentationSection *>& v)
+{
+ // 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)
+ {
+ i->second.GetPropertiesDocumentation(v);
+ }
+}
+
+void cmake::GetGeneratorDocumentation(std::vector<cmDocumentationEntry>& v)
+{
+ for(RegisteredGeneratorsMap::const_iterator i = this->Generators.begin();
+ i != this->Generators.end(); ++i)
+ {
+ cmDocumentationEntry e;
+ cmGlobalGenerator* generator = (i->second)();
+ generator->GetDocumentation(e);
+ delete generator;
+ v.push_back(e);
+ }
+ for(RegisteredExtraGeneratorsMap::const_iterator
+ i = this->ExtraGenerators.begin(); i != this->ExtraGenerators.end(); ++i)
+ {
+ cmDocumentationEntry e;
+ cmExternalMakefileProjectGenerator* generator = (i->second)();
+ generator->GetDocumentation(e, i->first.c_str());
+ e.Name = i->first;
+ delete generator;
+ v.push_back(e);
+ }
+}
+
+void cmake::UpdateConversionPathTable()
+{
+ // Update the path conversion table with any specified file:
+ const char* tablepath =
+ this->CacheManager->GetCacheValue("CMAKE_PATH_TRANSLATION_FILE");
+
+ if(tablepath)
+ {
+ std::ifstream table( tablepath );
+ if(!table)
+ {
+ cmSystemTools::Error("CMAKE_PATH_TRANSLATION_FILE set to ", tablepath,
+ ". CMake can not open file.");
+ cmSystemTools::ReportLastSystemError("CMake can not open file.");
+ }
+ else
+ {
+ std::string a, b;
+ while(!table.eof())
+ {
+ // two entries per line
+ table >> a; table >> b;
+ cmSystemTools::AddTranslationPath( a.c_str(), b.c_str());
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+int cmake::CheckBuildSystem()
+{
+ // We do not need to rerun CMake. Check dependency integrity. Use
+ // the make system's VERBOSE environment variable to enable verbose
+ // output. This can be skipped by 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));
+
+ // This method will check the integrity of the build system if the
+ // option was given on the command line. It reads the given file to
+ // determine whether CMake should rerun.
+
+ // If no file is provided for the check, we have to rerun.
+ if(this->CheckBuildSystemArgument.size() == 0)
+ {
+ if(verbose)
+ {
+ cmOStringStream msg;
+ msg << "Re-run cmake no build system arguments\n";
+ cmSystemTools::Stdout(msg.str().c_str());
+ }
+ return 1;
+ }
+
+ // If the file provided does not exist, we have to rerun.
+ if(!cmSystemTools::FileExists(this->CheckBuildSystemArgument.c_str()))
+ {
+ if(verbose)
+ {
+ cmOStringStream msg;
+ msg << "Re-run cmake missing file: "
+ << this->CheckBuildSystemArgument.c_str() << "\n";
+ cmSystemTools::Stdout(msg.str().c_str());
+ }
+ return 1;
+ }
+
+ // Read the rerun check file and use it to decide whether to do the
+ // global generate.
+ cmake cm;
+ cmGlobalGenerator gg;
+ gg.SetCMakeInstance(&cm);
+ std::auto_ptr<cmLocalGenerator> lg(gg.CreateLocalGenerator());
+ cmMakefile* mf = lg->GetMakefile();
+ if(!mf->ReadListFile(0, this->CheckBuildSystemArgument.c_str()) ||
+ cmSystemTools::GetErrorOccuredFlag())
+ {
+ if(verbose)
+ {
+ cmOStringStream msg;
+ msg << "Re-run cmake error reading : "
+ << this->CheckBuildSystemArgument.c_str() << "\n";
+ cmSystemTools::Stdout(msg.str().c_str());
+ }
+ // There was an error reading the file. Just rerun.
+ return 1;
+ }
+
+ if(this->ClearBuildSystem)
+ {
+ // Get the generator used for this build system.
+ const char* genName = mf->GetDefinition("CMAKE_DEPENDS_GENERATOR");
+ if(!genName || genName[0] == '\0')
+ {
+ genName = "Unix Makefiles";
+ }
+
+ // Create the generator and use it to clear the dependencies.
+ std::auto_ptr<cmGlobalGenerator>
+ ggd(this->CreateGlobalGenerator(genName));
+ if(ggd.get())
+ {
+ std::auto_ptr<cmLocalGenerator> lgd(ggd->CreateLocalGenerator());
+ lgd->ClearDependencies(mf, verbose);
+ }
+ }
+
+ // If any byproduct of makefile generation is missing we must re-run.
+ std::vector<std::string> products;
+ if(const char* productStr = mf->GetDefinition("CMAKE_MAKEFILE_PRODUCTS"))
+ {
+ cmSystemTools::ExpandListArgument(productStr, products);
+ }
+ for(std::vector<std::string>::const_iterator pi = products.begin();
+ pi != products.end(); ++pi)
+ {
+ if(!(cmSystemTools::FileExists(pi->c_str()) ||
+ cmSystemTools::FileIsSymlink(pi->c_str())))
+ {
+ if(verbose)
+ {
+ cmOStringStream msg;
+ msg << "Re-run cmake, missing byproduct: " << *pi << "\n";
+ cmSystemTools::Stdout(msg.str().c_str());
+ }
+ return 1;
+ }
+ }
+
+ // Get the set of dependencies and outputs.
+ std::vector<std::string> depends;
+ std::vector<std::string> outputs;
+ const char* dependsStr = mf->GetDefinition("CMAKE_MAKEFILE_DEPENDS");
+ const char* outputsStr = mf->GetDefinition("CMAKE_MAKEFILE_OUTPUTS");
+ if(dependsStr && outputsStr)
+ {
+ cmSystemTools::ExpandListArgument(dependsStr, depends);
+ cmSystemTools::ExpandListArgument(outputsStr, outputs);
+ }
+ if(depends.empty() || outputs.empty())
+ {
+ // Not enough information was provided to do the test. Just rerun.
+ if(verbose)
+ {
+ cmOStringStream msg;
+ msg << "Re-run cmake no CMAKE_MAKEFILE_DEPENDS "
+ "or CMAKE_MAKEFILE_OUTPUTS :\n";
+ cmSystemTools::Stdout(msg.str().c_str());
+ }
+ return 1;
+ }
+
+ // Find the newest dependency.
+ std::vector<std::string>::iterator dep = depends.begin();
+ std::string dep_newest = *dep++;
+ for(;dep != depends.end(); ++dep)
+ {
+ int result = 0;
+ if(this->FileComparison->FileTimeCompare(dep_newest.c_str(),
+ dep->c_str(), &result))
+ {
+ if(result < 0)
+ {
+ dep_newest = *dep;
+ }
+ }
+ else
+ {
+ if(verbose)
+ {
+ cmOStringStream msg;
+ msg << "Re-run cmake: build system dependency is missing\n";
+ cmSystemTools::Stdout(msg.str().c_str());
+ }
+ return 1;
+ }
+ }
+
+ // Find the oldest output.
+ std::vector<std::string>::iterator out = outputs.begin();
+ std::string out_oldest = *out++;
+ for(;out != outputs.end(); ++out)
+ {
+ int result = 0;
+ if(this->FileComparison->FileTimeCompare(out_oldest.c_str(),
+ out->c_str(), &result))
+ {
+ if(result > 0)
+ {
+ out_oldest = *out;
+ }
+ }
+ else
+ {
+ if(verbose)
+ {
+ cmOStringStream msg;
+ msg << "Re-run cmake: build system output is missing\n";
+ cmSystemTools::Stdout(msg.str().c_str());
+ }
+ return 1;
+ }
+ }
+
+ // If any output is older than any dependency then rerun.
+ {
+ int result = 0;
+ if(!this->FileComparison->FileTimeCompare(out_oldest.c_str(),
+ dep_newest.c_str(),
+ &result) ||
+ result < 0)
+ {
+ if(verbose)
+ {
+ cmOStringStream msg;
+ msg << "Re-run cmake file: " << out_oldest.c_str()
+ << " older than: " << dep_newest.c_str() << "\n";
+ cmSystemTools::Stdout(msg.str().c_str());
+ }
+ return 1;
+ }
+ }
+
+ // No need to rerun.
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+void cmake::TruncateOutputLog(const char* fname)
+{
+ std::string fullPath = this->GetHomeOutputDirectory();
+ fullPath += "/";
+ fullPath += fname;
+ struct stat st;
+ if ( ::stat(fullPath.c_str(), &st) )
+ {
+ return;
+ }
+ if ( !this->CacheManager->GetCacheValue("CMAKE_CACHEFILE_DIR") )
+ {
+ cmSystemTools::RemoveFile(fullPath.c_str());
+ return;
+ }
+ off_t fsize = st.st_size;
+ const off_t maxFileSize = 50 * 1024;
+ if ( fsize < maxFileSize )
+ {
+ //TODO: truncate file
+ return;
+ }
+}
+
+inline std::string removeQuotes(const std::string& s)
+{
+ if(s[0] == '\"' && s[s.size()-1] == '\"')
+ {
+ return s.substr(1, s.size()-2);
+ }
+ 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;
+}
+
+void cmake::GenerateGraphViz(const char* fileName) const
+{
+#ifdef CMAKE_BUILD_WITH_CMAKE
+ std::auto_ptr<cmGraphVizWriter> gvWriter(
+ new cmGraphVizWriter(this->GetGlobalGenerator()->GetLocalGenerators()));
+
+ std::string settingsFile = this->GetHomeOutputDirectory();
+ settingsFile += "/CMakeGraphVizOptions.cmake";
+ std::string fallbackSettingsFile = this->GetHomeDirectory();
+ fallbackSettingsFile += "/CMakeGraphVizOptions.cmake";
+
+ gvWriter->ReadSettings(settingsFile.c_str(), fallbackSettingsFile.c_str());
+
+ gvWriter->WritePerTargetFiles(fileName);
+ gvWriter->WriteTargetDependersFiles(fileName);
+ gvWriter->WriteGlobalFile(fileName);
+
+#endif
+}
+
+
+//----------------------------------------------------------------------------
+int cmake::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(!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;
+}
+
+//----------------------------------------------------------------------------
+int cmake::SymlinkExecutable(std::vector<std::string>& args)
+{
+ 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;
+}
+
+//----------------------------------------------------------------------------
+bool cmake::SymlinkInternal(std::string const& file, std::string const& link)
+{
+ 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
+}
+
+//----------------------------------------------------------------------------
+#ifdef CMAKE_BUILD_WITH_CMAKE
+int cmake::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;
+ 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;
+}
+#else
+int cmake::ExecuteEchoColor(std::vector<std::string>&)
+{
+ return 1;
+}
+#endif
+
+//----------------------------------------------------------------------------
+int cmake::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.
+ 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))
+ {
+ // 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
+ ("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);
+}
+
+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)
+{
+ FILE *progFile = fopen(filename,"w");
+ if (!progFile || !this->GlobalGenerator)
+ {
+ 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)
+ {
+ this->DebugConfigs.clear();
+ }
+
+ this->Properties.SetProperty(prop, value, cmProperty::GLOBAL);
+}
+
+void cmake::AppendProperty(const char* prop, const char* value, bool asString)
+{
+ if (!prop)
+ {
+ return;
+ }
+
+ // Special hook to invalidate cached value.
+ if(strcmp(prop, "DEBUG_CONFIGURATIONS") == 0)
+ {
+ this->DebugConfigs.clear();
+ }
+
+ 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)
+ {
+ 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)
+{
+ // so create the directory
+ std::string resultFile;
+ std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
+ std::string destPath = cwd + "/__cmake_systeminformation";
+ cmSystemTools::RemoveADirectory(destPath.c_str());
+ if (!cmSystemTools::MakeDirectory(destPath.c_str()))
+ {
+ std::cerr << "Error: --system-information must be run from a "
+ "writable directory!\n";
+ return 1;
+ }
+
+ // process the arguments
+ bool writeToStdout = true;
+ for(unsigned int i=1; i < args.size(); ++i)
+ {
+ std::string arg = args[i];
+ if(arg.find("-V",0) == 0)
+ {
+ this->Verbose = true;
+ }
+ else if(arg.find("-G",0) == 0)
+ {
+ std::string value = arg.substr(2);
+ if(value.size() == 0)
+ {
+ ++i;
+ if(i >= args.size())
+ {
+ cmSystemTools::Error("No generator specified for -G");
+ return -1;
+ }
+ value = args[i];
+ }
+ cmGlobalGenerator* gen =
+ this->CreateGlobalGenerator(value.c_str());
+ if(!gen)
+ {
+ cmSystemTools::Error("Could not create named generator ",
+ value.c_str());
+ }
+ else
+ {
+ this->SetGlobalGenerator(gen);
+ }
+ }
+ // no option assume it is the output file
+ else
+ {
+ if (!cmSystemTools::FileIsFullPath(arg.c_str()))
+ {
+ resultFile = cwd;
+ resultFile += "/";
+ }
+ resultFile += arg;
+ writeToStdout = false;
+ }
+ }
+
+
+ // we have to find the module directory, so we can copy the files
+ this->AddCMakePaths();
+ std::string modulesPath =
+ this->CacheManager->GetCacheValue("CMAKE_ROOT");
+ modulesPath += "/Modules";
+ std::string inFile = modulesPath;
+ inFile += "/SystemInformation.cmake";
+ std::string outFile = destPath;
+ outFile += "/CMakeLists.txt";
+
+ // Copy file
+ if(!cmSystemTools::cmCopyFile(inFile.c_str(), outFile.c_str()))
+ {
+ std::cerr << "Error copying file \"" << inFile.c_str()
+ << "\" to \"" << outFile.c_str() << "\".\n";
+ return 1;
+ }
+
+ // do we write to a file or to stdout?
+ if (resultFile.size() == 0)
+ {
+ resultFile = cwd;
+ resultFile += "/__cmake_systeminformation/results.txt";
+ }
+
+ // now run cmake on the CMakeLists file
+ cmSystemTools::ChangeDirectory(destPath.c_str());
+ std::vector<std::string> args2;
+ args2.push_back(args[0]);
+ args2.push_back(destPath);
+ std::string resultArg = "-DRESULT_FILE=";
+ resultArg += resultFile;
+ args2.push_back(resultArg);
+ int res = this->Run(args2, false);
+
+ if (res != 0)
+ {
+ std::cerr << "Error: --system-information failed on internal CMake!\n";
+ return res;
+ }
+
+ // change back to the original directory
+ cmSystemTools::ChangeDirectory(cwd.c_str());
+
+ // echo results to stdout if needed
+ if (writeToStdout)
+ {
+ FILE* fin = fopen(resultFile.c_str(), "r");
+ if(fin)
+ {
+ const int bufferSize = 4096;
+ char buffer[bufferSize];
+ size_t n;
+ while((n = fread(buffer, 1, bufferSize, fin)) > 0)
+ {
+ for(char* c = buffer; c < buffer+n; ++c)
+ {
+ putc(*c, stdout);
+ }
+ fflush(stdout);
+ }
+ fclose(fin);
+ }
+ }
+
+ // clean up the directory
+ cmSystemTools::RemoveADirectory(destPath.c_str());
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+static bool cmakeCheckStampFile(const char* stampName)
+{
+ // The stamp file does not exist. Use the stamp dependencies to
+ // determine whether it is really out of date. This works in
+ // conjunction with cmLocalVisualStudio7Generator to avoid
+ // repeatedly re-running CMake when the user rebuilds the entire
+ // solution.
+ std::string stampDepends = stampName;
+ stampDepends += ".depend";
+#if defined(_WIN32) || defined(__CYGWIN__)
+ std::ifstream fin(stampDepends.c_str(), std::ios::in | std::ios::binary);
+#else
+ std::ifstream fin(stampDepends.c_str(), std::ios::in);
+#endif
+ if(!fin)
+ {
+ // The stamp dependencies file cannot be read. Just assume the
+ // build system is really out of date.
+ std::cout << "CMake is re-running because " << stampName
+ << " dependency file is missing.\n";
+ return false;
+ }
+
+ // Compare the stamp dependencies against the dependency file itself.
+ cmFileTimeComparison ftc;
+ std::string dep;
+ while(cmSystemTools::GetLineFromStream(fin, dep))
+ {
+ int result;
+ if(dep.length() >= 1 && dep[0] != '#' &&
+ (!ftc.FileTimeCompare(stampDepends.c_str(), dep.c_str(), &result)
+ || result < 0))
+ {
+ // The stamp depends file is older than this dependency. The
+ // build system is really out of date.
+ std::cout << "CMake is re-running because " << stampName
+ << " is out-of-date.\n";
+ std::cout << " the file '" << dep << "'\n";
+ std::cout << " is newer than '" << stampDepends << "'\n";
+ std::cout << " result='" << result << "'\n";
+ return false;
+ }
+ }
+
+ // The build system is up to date. The stamp file has been removed
+ // by the VS IDE due to a "rebuild" request. Just restore it.
+ std::ofstream stamp(stampName);
+ stamp << "# CMake generation timestamp file this directory.\n";
+ if(stamp)
+ {
+ // Notify the user why CMake is not re-running. It is safe to
+ // just print to stdout here because this code is only reachable
+ // through an undocumented flag used by the VS generator.
+ std::cout << "CMake does not need to re-run because "
+ << stampName << " is up-to-date.\n";
+ return true;
+ }
+ else
+ {
+ cmSystemTools::Error("Cannot restore timestamp ", stampName);
+ return false;
+ }
+}
+
+//----------------------------------------------------------------------------
+static bool cmakeCheckStampList(const char* stampList)
+{
+ // If the stamp list does not exist CMake must rerun to generate it.
+ if(!cmSystemTools::FileExists(stampList))
+ {
+ std::cout << "CMake is re-running because generate.stamp.list "
+ << "is missing.\n";
+ return false;
+ }
+ std::ifstream fin(stampList);
+ if(!fin)
+ {
+ std::cout << "CMake is re-running because generate.stamp.list "
+ << "could not be read.\n";
+ return false;
+ }
+
+ // Check each stamp.
+ std::string stampName;
+ while(cmSystemTools::GetLineFromStream(fin, stampName))
+ {
+ if(!cmakeCheckStampFile(stampName.c_str()))
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+// For visual studio 2005 and newer manifest files need to be embeded 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)
+ {
+ 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 )
+ {
+ std::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);
+ }
+ }
+ bool hasIncremental = false;
+ bool hasManifest = true;
+ for(std::vector<std::string>::iterator i = expandedArgs.begin();
+ i != expandedArgs.end(); ++i)
+ {
+ if(cmSystemTools::Strucmp(i->c_str(), "/INCREMENTAL:YES") == 0)
+ {
+ hasIncremental = true;
+ }
+ if(cmSystemTools::Strucmp(i->c_str(), "/INCREMENTAL") == 0)
+ {
+ hasIncremental = true;
+ }
+ if(cmSystemTools::Strucmp(i->c_str(), "/MANIFEST:NO") == 0)
+ {
+ hasManifest = false;
+ }
+ }
+ if(hasIncremental && hasManifest)
+ {
+ if(verbose)
+ {
+ std::cout << "Visual Studio Incremental Link with embeded manifests\n";
+ }
+ return cmake::VisualStudioLinkIncremental(expandedArgs, type, verbose);
+ }
+ if(verbose)
+ {
+ if(!hasIncremental)
+ {
+ std::cout << "Visual Studio Non-Incremental Link\n";
+ }
+ else
+ {
+ std::cout << "Visual Studio Incremental Link without manifests\n";
+ }
+ }
+ 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)
+ {
+ targetName = i->substr(5);
+ }
+ }
+ 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)
+ {
+ std::cout << comment << ":\n";
+ for(std::vector<cmStdString>::iterator i = command.begin();
+ i != command.end(); ++i)
+ {
+ std::cout << i->c_str() << " ";
+ }
+ 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;
+}
+
+int cmake::VisualStudioLinkIncremental(std::vector<std::string>& args,
+ int type, bool verbose)
+{
+ // 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)
+ {
+ std::cout << "Create " << resourceInputFile.c_str() << "\n";
+ }
+ // Create input file for rc command
+ std::ofstream fout(resourceInputFile.c_str());
+ if(!fout)
+ {
+ return -1;
+ }
+ 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))
+ {
+ return -1;
+ }
+ // Now run the link command to link and create manifest
+ if(!cmake::RunCommand("LINK Pass 1", linkCommand, verbose))
+ {
+ return -1;
+ }
+ // 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)
+ {
+ return 0;
+ }
+ // 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)
+ {
+ return mtRet;
+ }
+ // update the resource file with the new manifest from the mt command.
+ if(!cmake::RunCommand("RC Pass 2", rcCommand, verbose))
+ {
+ return -1;
+ }
+ // Run the final incremental link that will put the new manifest resource
+ // into the file incrementally.
+ if(!cmake::RunCommand("FINAL LINK", linkCommand, verbose))
+ {
+ return -1;
+ }
+ return 0;
+}
+
+int cmake::VisualStudioLinkNonIncremental(std::vector<std::string>& args,
+ int type,
+ bool hasManifest,
+ bool verbose)
+{
+ 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))
+ {
+ return -1;
+ }
+ if(!hasManifest)
+ {
+ return 0;
+ }
+ 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)
+ {
+ outresource += "1";
+ }
+ else if(type == 2)
+ {
+ outresource += "2";
+ }
+ mtCommand.push_back(outresource);
+ // Now use the mt tool to embed the manifest into the exe or dll
+ if(!cmake::RunCommand("MT", mtCommand, verbose))
+ {
+ return -1;
+ }
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+void cmake::IssueMessage(cmake::MessageType t, std::string const& text,
+ cmListFileBacktrace const& backtrace)
+{
+ 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)
+ {
+ isError = true;
+ msg << "CMake Internal Error (please report a bug)";
+ }
+ else
+ {
+ 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)";
+ }
+ }
+
+ // 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;
+ }
+
+ // Add the message text.
+ {
+ msg << ":\n";
+ cmDocumentationFormatterText formatter;
+ formatter.SetIndent(" ");
+ formatter.PrintFormatted(msg, text.c_str());
+ }
+
+ // Add the rest of the context.
+ if(i != backtrace.end())
+ {
+ msg << "Call Stack (most recent call first):\n";
+ while(i != backtrace.end())
+ {
+ cmListFileContext const& lfc = *i;
+ msg << " " << lfc << "\n";
+ ++i;
+ }
+ }
+
+ // Add a note about warning suppression.
+ if(t == cmake::AUTHOR_WARNING)
+ {
+ msg <<
+ "This warning is for project developers. Use -Wno-dev to suppress it.";
+ }
+
+ // Add a terminating blank line.
+ msg << "\n";
+
+ // Output the message.
+ if(isError)
+ {
+ cmSystemTools::SetErrorOccured();
+ cmSystemTools::Message(msg.str().c_str(), "Error");
+ }
+ else
+ {
+ cmSystemTools::Message(msg.str().c_str(), "Warning");
+ }
+}
+
+//----------------------------------------------------------------------------
+std::vector<std::string> const& cmake::GetDebugConfigs()
+{
+ // Compute on-demand.
+ if(this->DebugConfigs.empty())
+ {
+ 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");
+ }
+ }
+ return this->DebugConfigs;
+}
+
+
+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)
+{
+ if(!cmSystemTools::FileIsDirectory(dir.c_str()))
+ {
+ 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::cerr << "Error: could not load cache\n";
+ return 1;
+ }
+ if(!it.Find("CMAKE_GENERATOR"))
+ {
+ std::cerr << "Error: could find generator in Cache\n";
+ return 1;
+ }
+ std::auto_ptr<cmGlobalGenerator> gen(
+ this->CreateGlobalGenerator(it.GetValue()));
+ std::string output;
+ std::string projName;
+ std::string makeProgram;
+ if(!it.Find("CMAKE_PROJECT_NAME"))
+ {
+ std::cerr << "Error: could not find CMAKE_PROJECT_NAME in Cache\n";
+ return 1;
+ }
+ projName = it.GetValue();
+ if(!it.Find("CMAKE_MAKE_PROGRAM"))
+ {
+ std::cerr << "Error: could not find CMAKE_MAKE_PROGRAM in Cache\n";
+ return 1;
+ }
+ 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);
+}
+
+void cmake::WatchUnusedCli(const char* var)
+{
+#ifdef CMAKE_BUILD_WITH_CMAKE
+ this->VariableWatch->AddWatch(var, cmWarnUnusedCliWarning, this);
+ if(this->UsedCliVariables.find(var) == this->UsedCliVariables.end())
+ {
+ this->UsedCliVariables[var] = false;
+ }
+#endif
+}
+
+void cmake::UnwatchUnusedCli(const char* var)
+{
+#ifdef CMAKE_BUILD_WITH_CMAKE
+ this->VariableWatch->RemoveWatch(var, cmWarnUnusedCliWarning);
+ this->UsedCliVariables.erase(var);
+#endif
+}
+
+void cmake::RunCheckForUnusedVariables()
+{
+#ifdef CMAKE_BUILD_WITH_CMAKE
+ bool haveUnused = false;
+ cmOStringStream msg;
+ msg << "Manually-specified variables were not used by the project:";
+ for(std::map<cmStdString, bool>::const_iterator
+ it = this->UsedCliVariables.begin();
+ it != this->UsedCliVariables.end(); ++it)
+ {
+ if(!it->second)
+ {
+ haveUnused = true;
+ msg << "\n " << it->first;
+ }
+ }
+ if(haveUnused)
+ {
+ this->IssueMessage(cmake::WARNING, msg.str(), cmListFileBacktrace());
+ }
+#endif
+}
diff --git a/Source/cmake.h b/Source/cmake.h
new file mode 100644
index 000000000..94c6f128f
--- /dev/null
+++ b/Source/cmake.h
@@ -0,0 +1,545 @@
+/*============================================================================
+ 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 cmake_h
+#define cmake_h
+
+#include "cmSystemTools.h"
+#include "cmPropertyDefinitionMap.h"
+#include "cmPropertyMap.h"
+
+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;
+
+/** \brief Represents a cmake invocation.
+ *
+ * This class represents a cmake invocation. It is the top level class when
+ * running cmake. Most cmake based GUIS should primarily create an instance
+ * of this class and communicate with it.
+ *
+ * The basic process for a GUI is as follows:
+ *
+ * -# Create a cmake instance
+ * -# Set the Home & Start 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)
+ * -# if you are using command line arguments with -D or -C flags then
+ * call SetCacheArgs (or if for some other reason you want to modify the
+ * cache), do it now.
+ * -# Finally call Configure
+ * -# 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
+ * you must at a minimum redo steps 2 through 7.
+ */
+
+class cmake
+{
+ public:
+ enum MessageType
+ { AUTHOR_WARNING,
+ FATAL_ERROR,
+ INTERNAL_ERROR,
+ MESSAGE,
+ WARNING,
+ LOG
+ };
+
+
+ /** \brief Describes the working modes of cmake */
+ enum WorkingMode
+ {
+ NORMAL_MODE, ///< Cmake runs to create project files
+ /** \brief Script mode (started by using -P).
+ *
+ * In script mode there is no generator and no cache. Also,
+ * languages are not enabled, so add_executable and things do
+ * nothing.
+ */
+ SCRIPT_MODE,
+ /** \brief A pkg-config like mode
+ *
+ * In this mode cmake just searches for a package and prints the results to
+ * stdout. This is similar to SCRIPT_MODE, but commands like add_library()
+ * work too, since they may be used e.g. in exported target files. Started
+ * via --find-package.
+ */
+ FIND_PACKAGE_MODE
+ };
+ typedef std::map<cmStdString, cmCommand*> RegisteredCommandsMap;
+
+ /// Default constructor
+ cmake();
+ /// Destructor
+ ~cmake();
+
+ static const char *GetCMakeFilesDirectory() {return "/CMakeFiles";};
+ static const char *GetCMakeFilesDirectoryPostSlash() {
+ 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.
+ */
+ 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();
+ }
+ //@}
+
+ /**
+ * Handle a command line invocation of cmake.
+ */
+ int Run(const std::vector<std::string>&args)
+ { return this->Run(args, false); }
+ int Run(const std::vector<std::string>&args, bool noconfigure);
+
+ /**
+ * Run the global generator Generate step.
+ */
+ int Generate();
+
+ /**
+ * Configure the cmMakefiles. This routine will create a GlobalGenerator if
+ * one has not already been set. It will then Call Configure on the
+ * GlobalGenerator. This in turn will read in an process all the CMakeList
+ * files for the tree. It will not produce any actual Makefiles, or
+ * workspaces. Generate does that. */
+ int Configure();
+ int ActualConfigure();
+
+ int LoadCache();
+ void PreLoadCMakeFiles();
+
+ ///! Create a GlobalGenerator
+ cmGlobalGenerator* CreateGlobalGenerator(const char* name);
+
+ ///! Return the global generator assigned to this instance of cmake
+ cmGlobalGenerator* GetGlobalGenerator() { return this->GlobalGenerator; }
+ ///! Return the global generator assigned to this instance of cmake, const
+ const cmGlobalGenerator* GetGlobalGenerator() const
+ { return this->GlobalGenerator; }
+
+ ///! Return the global generator assigned to this instance of cmake
+ void SetGlobalGenerator(cmGlobalGenerator *);
+
+ ///! Get the names of the current registered generators
+ void GetRegisteredGenerators(std::vector<std::string>& names);
+
+ ///! 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; }
+
+ /**
+ * Given a variable name, return its value (as a string).
+ */
+ const char* GetCacheDefinition(const char*) const;
+ ///! Add an entry into the cache
+ void AddCacheEntry(const char* 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; }
+
+ ///! Parse command line arguments that might set cache values
+ bool SetCacheArgs(const std::vector<std::string>&);
+
+ typedef void (*ProgressCallbackType)
+ (const char*msg, float progress, void *);
+ /**
+ * Set the function used by GUI's to receive progress updates
+ * Function gets passed: message as a const char*, a progress
+ * amount ranging from 0 to 1.0 and client data. The progress
+ * number provided may be negative in cases where a message is
+ * to be displayed without any progress percentage.
+ */
+ void SetProgressCallback(ProgressCallbackType f, void* clientData=0);
+
+ ///! 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);
+
+ // Get the properties
+ cmPropertyMap &GetProperties() { return this->Properties; };
+
+ ///! Do all the checks before running configure
+ int DoPreConfigureChecks();
+
+ void SetWorkingMode(WorkingMode mode) { this->CurrentWorkingMode = mode; }
+ WorkingMode GetWorkingMode() { return this->CurrentWorkingMode; }
+
+ ///! Debug the try compile stuff by not deleting the files
+ bool GetDebugTryCompile(){return this->DebugTryCompile;}
+ void DebugTryCompileOn(){this->DebugTryCompile = true;}
+
+ /**
+ * Generate CMAKE_ROOT and CMAKE_COMMAND cache entries
+ */
+ int AddCMakePaths();
+
+ /**
+ * Get the file comparison class
+ */
+ 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;}
+
+ // Do we want trace output during the cmake run.
+ bool GetTrace() { return this->Trace;}
+ void SetTrace(bool b) { this->Trace = b;}
+ bool GetWarnUninitialized() { return this->WarnUninitialized;}
+ void SetWarnUninitialized(bool b) { this->WarnUninitialized = b;}
+ bool GetWarnUnused() { return this->WarnUnused;}
+ void SetWarnUnused(bool b) { this->WarnUnused = b;}
+ bool GetWarnUnusedCli() { return this->WarnUnusedCli;}
+ void SetWarnUnusedCli(bool b) { this->WarnUnusedCli = b;}
+ bool GetCheckSystemVars() { return this->CheckSystemVars;}
+ void SetCheckSystemVars(bool b) { this->CheckSystemVars = b;}
+
+ 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);
+
+ // 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();
+
+ // record accesses of properties and variables
+ void RecordPropertyAccess(const char *name, cmProperty::ScopeType scope);
+ void ReportUndefinedPropertyAccesses(const char *filename);
+
+ // Define the properties
+ static void DefineProperties(cmake *cm);
+
+ void SetCMakeEditCommand(const char* s)
+ {
+ this->CMakeEditCommand = s;
+ }
+ void SetSuppressDevWarnings(bool v)
+ {
+ this->SuppressDevWarnings = v;
+ this->DoSuppressDevWarnings = true;
+ }
+
+ /** Display a message to the user. */
+ void IssueMessage(cmake::MessageType t, std::string const& text,
+ cmListFileBacktrace const& backtrace);
+ ///! 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);
+
+ 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;
+
+ typedef
+ cmExternalMakefileProjectGenerator* (*CreateExtraGeneratorFunctionType)();
+ typedef std::map<cmStdString,
+ CreateExtraGeneratorFunctionType> RegisteredExtraGeneratorsMap;
+
+ typedef cmGlobalGenerator* (*CreateGeneratorFunctionType)();
+ typedef std::map<cmStdString,
+ CreateGeneratorFunctionType> RegisteredGeneratorsMap;
+ RegisteredCommandsMap Commands;
+ RegisteredGeneratorsMap Generators;
+ RegisteredExtraGeneratorsMap ExtraGenerators;
+ void AddDefaultCommands();
+ void AddDefaultGenerators();
+ void AddDefaultExtraGenerators();
+ void AddExtraGenerator(const char* 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;
+
+ ///! read in a cmake list file to initialize the cache
+ void ReadListFile(const std::vector<std::string>& args, const char *path);
+ bool FindPackage(const std::vector<std::string>& args);
+
+ ///! Check if CMAKE_CACHEFILE_DIR is set. If it is not, delete the log file.
+ /// If it is set, truncate it to 50kb
+ void TruncateOutputLog(const char* fname);
+
+ /**
+ * Method called to check build system integrity at build time.
+ * Returns 1 if CMake should rerun and 0 otherwise.
+ */
+ int CheckBuildSystem();
+
+ void SetDirectoriesFromFile(const char* arg);
+
+ //! Make sure all commands are what they say they are and there is no
+ /// macros.
+ void CleanupCommandsAndMacros();
+
+ 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 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.
+ ProgressCallbackType ProgressCallback;
+ void* ProgressCallbackClientData;
+ bool Verbose;
+ bool InTryCompile;
+ WorkingMode CurrentWorkingMode;
+ bool DebugOutput;
+ bool Trace;
+ bool WarnUninitialized;
+ bool WarnUnused;
+ bool WarnUnusedCli;
+ bool CheckSystemVars;
+ std::map<cmStdString, 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;
+ bool ClearBuildSystem;
+ bool DebugTryCompile;
+ cmFileTimeComparison* FileComparison;
+ std::string GraphVizFile;
+ std::vector<std::string> DebugConfigs;
+
+ void UpdateConversionPathTable();
+};
+
+#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 makefile generator.", \
+ "CMake may support multiple native build systems on certain platforms. " \
+ "A makefile generator is responsible for generating a particular build " \
+ "system. Possible generator names are specified in the Generators " \
+ "section."},\
+ {"-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}
+#endif
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
new file mode 100644
index 000000000..11a426753
--- /dev/null
+++ b/Source/cmakemain.cxx
@@ -0,0 +1,658 @@
+/*============================================================================
+ 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 these first, otherwise there will be problems on Windows
+// with GetCurrentDirectory() being redefined
+#ifdef CMAKE_BUILD_WITH_CMAKE
+#include "cmDynamicLoader.h"
+#include "cmDocumentation.h"
+#endif
+
+#include "cmake.h"
+#include "cmCacheManager.h"
+#include "cmListFileCache.h"
+#include "cmakewizard.h"
+#include "cmSourceFile.h"
+#include "cmGlobalGenerator.h"
+#include "cmLocalGenerator.h"
+#include "cmMakefile.h"
+
+#ifdef CMAKE_BUILD_WITH_CMAKE
+//----------------------------------------------------------------------------
+static const char * cmDocumentationName[][3] =
+{
+ {0,
+ " cmake - Cross-Platform Makefile Generator.", 0},
+ {0,0,0}
+};
+
+//----------------------------------------------------------------------------
+static const char * cmDocumentationUsage[][3] =
+{
+ {0,
+ " cmake [options] <path-to-source>\n"
+ " cmake [options] <path-to-existing-build>", 0},
+ {0,0,0}
+};
+
+//----------------------------------------------------------------------------
+static const char * cmDocumentationDescription[][3] =
+{
+ {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}
+};
+
+#define CMAKE_BUILD_OPTIONS \
+ " <dir> = Project binary directory to be built.\n" \
+ " --target <tgt> = Build <tgt> instead of default targets.\n" \
+ " --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.\n" \
+ " -- = Pass remaining options to the native tool.\n"
+
+//----------------------------------------------------------------------------
+static const char * cmDocumentationOptions[][3] =
+{
+ 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 be then changed "
+ "with -D option. Changing some of the variable 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)."},
+ {"--graphviz=[file]", "Generate graphviz of dependencies.",
+ "Generate a graphviz input file that will contain all the library and "
+ "executable dependencies in the project."},
+ {"--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 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."},
+ {"--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 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-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}
+};
+
+//----------------------------------------------------------------------------
+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}
+};
+
+//----------------------------------------------------------------------------
+static const char * cmDocumentationNOTE[][3] =
+{
+ {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
+
+int do_cmake(int ac, char** av);
+static int do_build(int ac, char** av);
+
+static cmMakefile* cmakemainGetMakefile(void *clientdata)
+{
+ cmake* cm = (cmake *)clientdata;
+ if(cm && cm->GetDebugOutput())
+ {
+ cmGlobalGenerator* gg=cm->GetGlobalGenerator();
+ if (gg)
+ {
+ cmLocalGenerator* lg=gg->GetCurrentLocalGenerator();
+ if (lg)
+ {
+ cmMakefile* mf = lg->GetMakefile();
+ return mf;
+ }
+ }
+ }
+ return 0;
+}
+
+static std::string cmakemainGetStack(void *clientdata)
+{
+ std::string msg;
+ cmMakefile* mf=cmakemainGetMakefile(clientdata);
+ if (mf)
+ {
+ msg = mf->GetListFileStack();
+ if (!msg.empty())
+ {
+ msg = "\n Called from: " + msg;
+ }
+ }
+
+ return msg;
+}
+
+static void cmakemainErrorCallback(const char* m, const char*, bool&,
+ void *clientdata)
+{
+ std::cerr << m << cmakemainGetStack(clientdata) << std::endl << std::flush;
+}
+
+static void cmakemainProgressCallback(const char *m, float prog,
+ void* clientdata)
+{
+ cmMakefile* mf = cmakemainGetMakefile(clientdata);
+ std::string dir;
+ if ((mf) && (strstr(m, "Configuring")==m) && (prog<0))
+ {
+ dir = " ";
+ dir += mf->GetCurrentDirectory();
+ }
+ else if ((mf) && (strstr(m, "Generating")==m))
+ {
+ dir = " ";
+ dir += mf->GetCurrentOutputDirectory();
+ }
+
+ if ((prog < 0) || (!dir.empty()))
+ {
+ std::cout << "-- " << m << dir << cmakemainGetStack(clientdata)<<std::endl;
+ }
+
+ std::cout.flush();
+}
+
+
+int main(int ac, char** av)
+{
+ cmSystemTools::EnableMSVCDebugHook();
+ cmSystemTools::FindExecutableDirectory(av[0]);
+ if(ac > 1 && strcmp(av[1], "--build") == 0)
+ {
+ return do_build(ac, av);
+ }
+ int ret = do_cmake(ac, av);
+#ifdef CMAKE_BUILD_WITH_CMAKE
+ cmDynamicLoader::FlushCache();
+#endif
+ return ret;
+}
+
+int do_cmake(int ac, char** av)
+{
+ int nocwd = 0;
+
+ if ( cmSystemTools::GetCurrentWorkingDirectory().size() == 0 )
+ {
+ std::cerr << "Current working directory cannot be established."
+ << std::endl;
+ nocwd = 1;
+ }
+
+#ifdef CMAKE_BUILD_WITH_CMAKE
+ cmDocumentation doc;
+ doc.addCMakeStandardDocSections();
+ if(doc.CheckOptions(ac, av, "-E") || nocwd)
+ {
+ // Construct and print requested documentation.
+ cmake hcm;
+ 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]);
+ }
+ 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"))
+ {
+ doc.ClearSections();
+ doc.SetSection("NOTE", cmDocumentationNOTE);
+ doc.Print(cmDocumentation::UsageForm, 0, std::cerr);
+ return 1;
+ }
+ return result;
+ }
+#else
+ if ( nocwd || ac == 1 )
+ {
+ std::cout <<
+ "Bootstrap CMake should not be used outside CMake build process."
+ << std::endl;
+ return 0;
+ }
+#endif
+
+ bool wiz = false;
+ bool sysinfo = false;
+ bool command = false;
+ bool list_cached = false;
+ bool list_all_cached = false;
+ bool list_help = false;
+ bool view_only = false;
+ cmake::WorkingMode workingMode = cmake::NORMAL_MODE;
+ std::vector<std::string> args;
+ for(int i =0; i < ac; ++i)
+ {
+ if(!command && strcmp(av[i], "-i") == 0)
+ {
+ wiz = true;
+ }
+ else if(!command && 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)
+ {
+ view_only = true;
+ }
+ else if (!command && strcmp(av[i], "-L") == 0)
+ {
+ list_cached = true;
+ }
+ else if (!command && strcmp(av[i], "-LA") == 0)
+ {
+ list_all_cached = true;
+ }
+ else if (!command && strcmp(av[i], "-LH") == 0)
+ {
+ list_cached = true;
+ list_help = true;
+ }
+ else if (!command && strcmp(av[i], "-LAH") == 0)
+ {
+ list_all_cached = true;
+ list_help = true;
+ }
+ else if (!command && strncmp(av[i], "-P", strlen("-P")) == 0)
+ {
+ if ( i == ac -1 )
+ {
+ cmSystemTools::Error("No script specified for argument -P");
+ }
+ else
+ {
+ workingMode = cmake::SCRIPT_MODE;
+ args.push_back(av[i]);
+ i++;
+ args.push_back(av[i]);
+ }
+ }
+ else if (!command && strncmp(av[i], "--find-package",
+ strlen("--find-package")) == 0)
+ {
+ workingMode = cmake::FIND_PACKAGE_MODE;
+ args.push_back(av[i]);
+ }
+ else
+ {
+ 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;
+ int ret = cm.GetSystemInformation(args);
+ return ret;
+ }
+ cmake cm;
+ cmSystemTools::SetErrorCallback(cmakemainErrorCallback, (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() )
+ {
+ cmCacheManager::CacheEntryType t = it.GetType();
+ if ( t != cmCacheManager::INTERNAL && t != cmCacheManager::STATIC &&
+ t != cmCacheManager::UNINITIALIZED )
+ {
+ bool advanced = it.PropertyExists("ADVANCED");
+ if ( list_all_cached || !advanced)
+ {
+ if ( list_help )
+ {
+ std::cout << "// " << it.GetProperty("HELPSTRING") << std::endl;
+ }
+ std::cout << it.GetName() << ":" <<
+ cmCacheManager::TypeToString(it.GetType())
+ << "=" << it.GetValue() << std::endl;
+ if ( list_help )
+ {
+ std::cout << std::endl;
+ }
+ }
+ }
+ }
+ }
+
+ // Always return a non-negative value. Windows tools do not always
+ // interpret negative return values as errors.
+ if(res != 0)
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+//----------------------------------------------------------------------------
+static int do_build(int ac, char** av)
+{
+#ifndef CMAKE_BUILD_WITH_CMAKE
+ std::cerr << "This cmake does not support --build\n";
+ return -1;
+#else
+ std::string target;
+ std::string config = "Debug";
+ 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;
+ for(int i=2; i < ac; ++i)
+ {
+ if(doing == DoingNative)
+ {
+ nativeOptions.push_back(av[i]);
+ }
+ else if(strcmp(av[i], "--target") == 0)
+ {
+ doing = DoingTarget;
+ }
+ else if(strcmp(av[i], "--config") == 0)
+ {
+ doing = DoingConfig;
+ }
+ else if(strcmp(av[i], "--clean-first") == 0)
+ {
+ clean = true;
+ doing = DoingNone;
+ }
+ else if(strcmp(av[i], "--use-stderr") == 0)
+ {
+ outputflag = cmSystemTools::OUTPUT_NORMAL;
+ }
+ else if(strcmp(av[i], "--") == 0)
+ {
+ doing = DoingNative;
+ }
+ else
+ {
+ switch (doing)
+ {
+ case DoingDir:
+ dir = av[i];
+ doing = DoingNone;
+ break;
+ case DoingTarget:
+ target = av[i];
+ doing = DoingNone;
+ break;
+ case DoingConfig:
+ config = av[i];
+ doing = DoingNone;
+ break;
+ default:
+ std::cerr << "Unknown argument " << av[i] << std::endl;
+ dir = "";
+ break;
+ }
+ }
+ }
+ if(dir.empty())
+ {
+ std::cerr <<
+ "Usage: cmake --build <dir> [options] [-- [native-options]]\n"
+ "Options:\n"
+ CMAKE_BUILD_OPTIONS
+ ;
+ return 1;
+ }
+
+ // Hack for vs6 that passes ".\Debug" as "$(IntDir)" value:
+ //
+ if (cmSystemTools::StringStartsWith(config.c_str(), ".\\"))
+ {
+ config = config.substr(2);
+ }
+
+ cmake cm;
+ return cm.Build(dir, target, config, nativeOptions, clean, outputflag);
+#endif
+}
diff --git a/Source/cmaketest.h.in b/Source/cmaketest.h.in
new file mode 100644
index 000000000..aada52dba
--- /dev/null
+++ b/Source/cmaketest.h.in
@@ -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.
+============================================================================*/
+#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
new file mode 100644
index 000000000..cd427cb40
--- /dev/null
+++ b/Source/cmakewizard.cxx
@@ -0,0 +1,158 @@
+/*============================================================================
+ 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, 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, sizeof(buffer)-1, stdin))
+ {
+ buffer[0] = 0;
+ }
+ if(buffer[0])
+ {
+ 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
new file mode 100644
index 000000000..fcb2c7ae2
--- /dev/null
+++ b/Source/cmakewizard.h
@@ -0,0 +1,42 @@
+/*============================================================================
+ 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/cmakexbuild.cxx b/Source/cmakexbuild.cxx
new file mode 100644
index 000000000..8eaae4795
--- /dev/null
+++ b/Source/cmakexbuild.cxx
@@ -0,0 +1,92 @@
+/*============================================================================
+ 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 <cmsys/Process.h>
+#include "cmStandardIncludes.h"
+#include "cmSystemTools.h"
+
+// This is a wrapper program for xcodebuild
+// it calls xcodebuild, and does two things
+// it removes much of the output, all the setenv
+// stuff. Also, it checks for the text file busy
+// error, and re-runs xcodebuild until that error does
+// not show up.
+
+int RunXCode(std::vector<const char*>& argv, bool& hitbug)
+{
+ hitbug = false;
+ cmsysProcess* cp = cmsysProcess_New();
+ cmsysProcess_SetCommand(cp, &*argv.begin());
+ cmsysProcess_SetTimeout(cp, 0);
+ cmsysProcess_Execute(cp);
+ std::vector<char> out;
+ std::vector<char> err;
+ std::string line;
+ int pipe = cmSystemTools::WaitForLine(cp, line, 100.0, out, err);
+ while(pipe != cmsysProcess_Pipe_None)
+ {
+ if(line.find("/bin/sh: bad interpreter: Text file busy")
+ != line.npos)
+ {
+ hitbug = true;
+ std::cerr << "Hit xcodebuild bug : " << line << "\n";
+ }
+ // if the bug is hit, no more output should be generated
+ // because it may contain bogus errors
+ // also remove all output with setenv in it to tone down
+ // the verbosity of xcodebuild
+ if(!hitbug && (line.find("setenv") == line.npos))
+ {
+ if(pipe == cmsysProcess_Pipe_STDERR)
+ {
+ std::cerr << line << "\n";
+ }
+ else if(pipe == cmsysProcess_Pipe_STDOUT)
+ {
+ std::cout << line << "\n";
+ }
+ }
+ pipe = cmSystemTools::WaitForLine(cp, line, 100, out, err);
+ }
+ cmsysProcess_WaitForExit(cp, 0);
+ if(cmsysProcess_GetState(cp) == cmsysProcess_State_Exited)
+ {
+ return cmsysProcess_GetExitValue(cp);
+ }
+ if(cmsysProcess_GetState(cp) == cmsysProcess_State_Error)
+ {
+ return -1;
+ }
+ return -1;
+}
+
+int main(int ac, char*av[])
+{
+ std::vector<const char*> argv;
+ argv.push_back("xcodebuild");
+ for(int i =1; i < ac; i++)
+ {
+ argv.push_back(av[i]);
+ }
+ argv.push_back(0);
+ bool hitbug = true;
+ int ret = 0;
+ while(hitbug)
+ {
+ ret = RunXCode(argv, hitbug);
+ }
+ if(ret < 0)
+ {
+ return 255;
+ }
+ return ret;
+}
+
diff --git a/Source/cmcldeps.cxx b/Source/cmcldeps.cxx
new file mode 100644
index 000000000..69df88d2a
--- /dev/null
+++ b/Source/cmcldeps.cxx
@@ -0,0 +1,285 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+//
+// 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.
+
+
+// Wrapper around cl that adds /showIncludes to command line, and uses that to
+// generate .d files that match the style from gcc -MD.
+//
+// /showIncludes is equivalent to -MD, not -MMD, that is, system headers are
+// included.
+
+
+#include <windows.h>
+#include <sstream>
+#include <cmSystemTools.h>
+
+// We don't want any wildcard expansion.
+// See http://msdn.microsoft.com/en-us/library/zay8tzh6(v=vs.85).aspx
+void _setargv() {}
+
+static void Fatal(const char* msg, ...) {
+ va_list ap;
+ fprintf(stderr, "ninja: FATAL: ");
+ va_start(ap, msg);
+ vfprintf(stderr, msg, ap);
+ va_end(ap);
+ fprintf(stderr, "\n");
+ // On Windows, some tools may inject extra threads.
+ // exit() may block on locks held by those threads, so forcibly exit.
+ fflush(stderr);
+ fflush(stdout);
+ ExitProcess(1);
+}
+
+static void usage(const char* msg) {
+ Fatal("%s\n\nusage:\n "
+ "cmcldeps "
+ "<language C, CXX or RC> "
+ "<source file path> "
+ "<output path for *.d file> "
+ "<output path for *.obj file> "
+ "<prefix of /showIncludes> "
+ "<path to cl.exe> "
+ "<path to tool (cl or rc)> "
+ "<rest of command ...>\n", msg);
+}
+
+static std::string trimLeadingSpace(const std::string& cmdline) {
+ int i = 0;
+ for (; cmdline[i] == ' '; ++i)
+ ;
+ return cmdline.substr(i);
+}
+
+static void doEscape(std::string& str, const std::string& search,
+ const std::string& repl) {
+ std::string::size_type pos = 0;
+ while ((pos = str.find(search, pos)) != std::string::npos) {
+ str.replace(pos, search.size(), repl);
+ pos += repl.size();
+ }
+}
+
+// Strips one argument from the cmdline and returns it. "surrounding quotes"
+// are removed from the argument if there were any.
+static std::string getArg(std::string& cmdline) {
+ std::string ret;
+ bool in_quoted = false;
+ unsigned int i = 0;
+
+ cmdline = trimLeadingSpace(cmdline);
+
+ for (;; ++i) {
+ if (i >= cmdline.size())
+ usage("Couldn't parse arguments.");
+ if (!in_quoted && cmdline[i] == ' ')
+ break; // "a b" "x y"
+ if (cmdline[i] == '"')
+ in_quoted = !in_quoted;
+ }
+
+ ret = cmdline.substr(0, i);
+ if (ret[0] == '"' && ret[i - 1] == '"')
+ ret = ret.substr(1, ret.size() - 2);
+ cmdline = cmdline.substr(i);
+ return ret;
+}
+
+static void parseCommandLine(LPTSTR wincmdline,
+ std::string& lang,
+ std::string& srcfile,
+ std::string& dfile,
+ std::string& objfile,
+ std::string& prefix,
+ std::string& clpath,
+ std::string& binpath,
+ std::string& rest) {
+ std::string cmdline(wincmdline);
+ /* self */ getArg(cmdline);
+ lang = getArg(cmdline);
+ srcfile = getArg(cmdline);
+ dfile = getArg(cmdline);
+ objfile = getArg(cmdline);
+ prefix = getArg(cmdline);
+ clpath = getArg(cmdline);
+ binpath = getArg(cmdline);
+ rest = trimLeadingSpace(cmdline);
+}
+
+static void outputDepFile(const std::string& dfile, const std::string& objfile,
+ std::vector<std::string>& incs) {
+
+ if (dfile.empty())
+ return;
+
+ // strip duplicates
+ std::sort(incs.begin(), incs.end());
+ incs.erase(std::unique(incs.begin(), incs.end()), incs.end());
+
+ FILE* out = fopen(dfile.c_str(), "wb");
+
+ // FIXME should this be fatal or not? delete obj? delete d?
+ if (!out)
+ return;
+
+ std::string tmp = objfile;
+ doEscape(tmp, " ", "\\ ");
+ fprintf(out, "%s: \\\n", tmp.c_str());
+
+ std::vector<std::string>::iterator it = incs.begin();
+ for (; it != incs.end(); ++it) {
+ tmp = *it;
+ doEscape(tmp, "\\", "/");
+ doEscape(tmp, " ", "\\ ");
+ fprintf(out, "%s \\\n", tmp.c_str());
+ }
+
+ fprintf(out, "\n");
+ fclose(out);
+}
+
+
+bool startsWith(const std::string& str, const std::string& what) {
+ return str.compare(0, what.size(), what) == 0;
+}
+
+bool contains(const std::string& str, const std::string& what) {
+ return str.find(what) != std::string::npos;
+}
+
+std::string replace(const std::string& str, const std::string& what,
+ const std::string& replacement) {
+ size_t pos = str.find(what);
+ if (pos == std::string::npos)
+ return str;
+ std::string replaced = str;
+ return replaced.replace(pos, what.size(), replacement);
+}
+
+
+
+static int process( const std::string& srcfilename,
+ const std::string& dfile,
+ const std::string& objfile,
+ const std::string& prefix,
+ const std::string& cmd,
+ const std::string& dir = "",
+ bool quiet = false)
+{
+ std::string output;
+ // break up command line into a vector
+ std::vector<std::string> args;
+ cmSystemTools::ParseWindowsCommandLine(cmd.c_str(), args);
+ // convert to correct vector type for RunSingleCommand
+ std::vector<cmStdString> command;
+ for(std::vector<std::string>::iterator i = args.begin();
+ i != args.end(); ++i)
+ {
+ command.push_back(i->c_str());
+ }
+ // run the command
+ int exit_code = 0;
+ bool run = cmSystemTools::RunSingleCommand(command, &output, &exit_code,
+ dir.c_str(), cmSystemTools::OUTPUT_NONE);
+
+ // process the include directives and output everything else
+ std::stringstream ss(output);
+ std::string line;
+ std::vector<std::string> includes;
+ bool isFirstLine = true; // cl prints always first the source filename
+ while (std::getline(ss, line)) {
+ if (startsWith(line, prefix)) {
+ std::string inc = trimLeadingSpace(line.substr(prefix.size()).c_str());
+ if (inc[inc.size() - 1] == '\r') // blech, stupid \r\n
+ inc = inc.substr(0, inc.size() - 1);
+ includes.push_back(inc);
+ } else {
+ if (!isFirstLine || !startsWith(line, srcfilename)) {
+ if (!quiet || exit_code != 0) {
+ fprintf(stdout, "%s\n", line.c_str());
+ }
+ } else {
+ isFirstLine = false;
+ }
+ }
+ }
+
+ // don't update .d until/unless we succeed compilation
+ if (run && exit_code == 0)
+ outputDepFile(dfile, objfile, includes);
+
+ return exit_code;
+}
+
+
+int main() {
+
+ // Use the Win32 api instead of argc/argv so we can avoid interpreting the
+ // rest of command line after the .d and .obj. Custom parsing seemed
+ // preferable to the ugliness you get into in trying to re-escape quotes for
+ // subprocesses, so by avoiding argc/argv, the subprocess is called with
+ // the same command line verbatim.
+
+ std::string lang, srcfile, dfile, objfile, prefix, cl, binpath, rest;
+ parseCommandLine(GetCommandLine(), lang, srcfile, dfile, objfile,
+ prefix, cl, binpath, rest);
+
+ // needed to suppress filename output of msvc tools
+ std::string srcfilename;
+ std::string::size_type pos = srcfile.rfind("\\");
+ if (pos != std::string::npos) {
+ srcfilename = srcfile.substr(pos + 1);
+ }
+
+ std::string nol = " /nologo ";
+ std::string show = " /showIncludes ";
+ if (lang == "C" || lang == "CXX") {
+ return process(srcfilename, dfile, objfile, prefix,
+ binpath + nol + show + rest);
+ } else if (lang == "RC") {
+ // "misuse" cl.exe to get headers from .rc files
+
+ std::string clrest = rest;
+ // rc: /fo x.dir\x.rc.res -> cl: /out:x.dir\x.rc.res.dep.obj
+ clrest = replace(clrest, "/fo", "/out:");
+ clrest = replace(clrest, objfile, objfile + ".dep.obj ");
+
+ // rc: src\x\x.rc -> cl: /Tc src\x\x.rc
+ if (srcfile.find(" ") != std::string::npos)
+ srcfile = "\"" + srcfile + "\"";
+ clrest = replace(clrest, srcfile, "/Tc " + srcfile);
+
+ cl = "\"" + cl + "\" /P /DRC_INVOKED ";
+
+ // call cl in object dir so the .i is generated there
+ std::string objdir;
+ std::string::size_type pos = objfile.rfind("\\");
+ if (pos != std::string::npos) {
+ objdir = objfile.substr(0, pos);
+ }
+
+ // extract dependencies with cl.exe
+ int exit_code = process(srcfilename, dfile, objfile,
+ prefix, cl + nol + show + clrest, objdir, true);
+
+ if (exit_code != 0)
+ return exit_code;
+
+ // compile rc file with rc.exe
+ return process(srcfilename, "" , objfile, prefix, binpath + " " + rest);
+ }
+
+ usage("Invalid language specified.");
+ return 1;
+}
diff --git a/Source/cmparseMSBuildXML.py b/Source/cmparseMSBuildXML.py
new file mode 100755
index 000000000..4877e5913
--- /dev/null
+++ b/Source/cmparseMSBuildXML.py
@@ -0,0 +1,329 @@
+# This python script parses the spec files from MSBuild to create
+# mappings from compiler options to IDE XML specifications. For
+# more information see here:
+
+# http://blogs.msdn.com/vcblog/archive/2008/12/16/msbuild-task.aspx
+# "${PROGRAMFILES}/MSBuild/Microsoft.Cpp/v4.0/1033/cl.xml"
+# "${PROGRAMFILES}/MSBuild/Microsoft.Cpp/v4.0/1033/lib.xml"
+# "${PROGRAMFILES}/MSBuild/Microsoft.Cpp/v4.0/1033/link.xml"
+#
+# BoolProperty <Name>true|false</Name>
+# simple example:
+# <BoolProperty ReverseSwitch="Oy-" Name="OmitFramePointers"
+# Category="Optimization" Switch="Oy">
+# <BoolProperty.DisplayName> <BoolProperty.Description>
+# <CLCompile>
+# <OmitFramePointers>true</OmitFramePointers>
+# </ClCompile>
+#
+# argument means it might be this: /MP3
+# example with argument:
+# <BoolProperty Name="MultiProcessorCompilation" Category="General" Switch="MP">
+# <BoolProperty.DisplayName>
+# <sys:String>Multi-processor Compilation</sys:String>
+# </BoolProperty.DisplayName>
+# <BoolProperty.Description>
+# <sys:String>Multi-processor Compilation</sys:String>
+# </BoolProperty.Description>
+# <Argument Property="ProcessorNumber" IsRequired="false" />
+# </BoolProperty>
+# <CLCompile>
+# <MultiProcessorCompilation>true</MultiProcessorCompilation>
+# <ProcessorNumber>4</ProcessorNumber>
+# </ClCompile>
+# IntProperty
+# not used AFIT
+# <IntProperty Name="ProcessorNumber" Category="General" Visible="false">
+
+
+# per config options example
+# <EnableFiberSafeOptimizations Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</EnableFiberSafeOptimizations>
+#
+# EnumProperty
+# <EnumProperty Name="Optimization" Category="Optimization">
+# <EnumProperty.DisplayName>
+# <sys:String>Optimization</sys:String>
+# </EnumProperty.DisplayName>
+# <EnumProperty.Description>
+# <sys:String>Select option for code optimization; choose Custom to use specific optimization options. (/Od, /O1, /O2, /Ox)</sys:String>
+# </EnumProperty.Description>
+# <EnumValue Name="MaxSpeed" Switch="O2">
+# <EnumValue.DisplayName>
+# <sys:String>Maximize Speed</sys:String>
+# </EnumValue.DisplayName>
+# <EnumValue.Description>
+# <sys:String>Equivalent to /Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy</sys:String>
+# </EnumValue.Description>
+# </EnumValue>
+# <EnumValue Name="MinSpace" Switch="O1">
+# <EnumValue.DisplayName>
+# <sys:String>Minimize Size</sys:String>
+# </EnumValue.DisplayName>
+# <EnumValue.Description>
+# <sys:String>Equivalent to /Og /Os /Oy /Ob2 /Gs /GF /Gy</sys:String>
+# </EnumValue.Description>
+# </EnumValue>
+# example for O2 would be this:
+# <Optimization>MaxSpeed</Optimization>
+# example for O1 would be this:
+# <Optimization>MinSpace</Optimization>
+#
+# StringListProperty
+# <StringListProperty Name="PreprocessorDefinitions" Category="Preprocessor" Switch="D ">
+# <StringListProperty.DisplayName>
+# <sys:String>Preprocessor Definitions</sys:String>
+# </StringListProperty.DisplayName>
+# <StringListProperty.Description>
+# <sys:String>Defines a preprocessing symbols for your source file.</sys:String>
+# </StringListProperty.Description>
+# </StringListProperty>
+
+# <StringListProperty Subtype="folder" Name="AdditionalIncludeDirectories" Category="General" Switch="I">
+# <StringListProperty.DisplayName>
+# <sys:String>Additional Include Directories</sys:String>
+# </StringListProperty.DisplayName>
+# <StringListProperty.Description>
+# <sys:String>Specifies one or more directories to add to the include path; separate with semi-colons if more than one. (/I[path])</sys:String>
+# </StringListProperty.Description>
+# </StringListProperty>
+# StringProperty
+
+# Example add bill include:
+
+# <AdditionalIncludeDirectories>..\..\..\..\..\..\bill;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+
+
+import sys
+from xml.dom.minidom import parse, parseString
+
+def getText(node):
+ nodelist = node.childNodes
+ rc = ""
+ for child in nodelist:
+ if child.nodeType == child.TEXT_NODE:
+ rc = rc + child.data
+ return rc
+
+def print_tree(document, spaces=""):
+ for i in range(len(document.childNodes)):
+ if document.childNodes[i].nodeType == document.childNodes[i].ELEMENT_NODE:
+ print spaces+str(document.childNodes[i].nodeName )
+ print_tree(document.childNodes[i],spaces+"----")
+ pass
+
+###########################################################################################
+#Data structure that stores a property of MSBuild
+class Property:
+ #type = type of MSBuild property (ex. if the property is EnumProperty type should be "Enum")
+ #attributeNames = a list of any attributes that this property could have (ex. if this was a EnumProperty it should be ["Name","Category"])
+ #document = the dom file that's root node is the Property node (ex. if you were parsing a BoolProperty the root node should be something like <BoolProperty Name="RegisterOutput" Category="General" IncludeInCommandLine="false">
+ def __init__(self,type,attributeNames,document=None):
+ self.suffix_type = "Property"
+ self.prefix_type = type
+ self.attributeNames = attributeNames
+ self.attributes = {}
+ self.DisplayName = ""
+ self.Description = ""
+ self.argumentProperty = ""
+ self.argumentIsRequired = ""
+ self.values = []
+ if document is not None:
+ self.populate(document)
+ pass
+
+ #document = the dom file that's root node is the Property node (ex. if you were parsing a BoolProperty the root node should be something like <BoolProperty Name="RegisterOutput" Category="General" IncludeInCommandLine="false">
+ #spaces = do not use
+ def populate(self,document, spaces = ""):
+ if document.nodeName == self.prefix_type+self.suffix_type:
+ for i in self.attributeNames:
+ self.attributes[i] = document.getAttribute(i)
+ for i in range(len(document.childNodes)):
+ child = document.childNodes[i]
+ if child.nodeType == child.ELEMENT_NODE:
+ if child.nodeName == self.prefix_type+self.suffix_type+".DisplayName":
+ self.DisplayName = getText(child.childNodes[1])
+ if child.nodeName == self.prefix_type+self.suffix_type+".Description":
+ self.Description = getText(child.childNodes[1])
+ if child.nodeName == "Argument":
+ self.argumentProperty = child.getAttribute("Property")
+ self.argumentIsRequired = child.getAttribute("IsRequired")
+ if child.nodeName == self.prefix_type+"Value":
+ va = Property(self.prefix_type,["Name","Switch"])
+ va.suffix_type = "Value"
+ va.populate(child)
+ self.values.append(va)
+ self.populate(child,spaces+"----")
+ pass
+
+ #toString function
+ def __str__(self):
+ toReturn = self.prefix_type+self.suffix_type+":"
+ for i in self.attributeNames:
+ toReturn += "\n "+i+": "+self.attributes[i]
+ if self.argumentProperty != "":
+ toReturn += "\n Argument:\n Property: "+self.argumentProperty+"\n IsRequired: "+self.argumentIsRequired
+ for i in self.values:
+ toReturn+="\n "+str(i).replace("\n","\n ")
+ return toReturn
+###########################################################################################
+
+###########################################################################################
+#Class that populates itself from an MSBuild file and outputs it in CMake
+#format
+
+class MSBuildToCMake:
+ #document = the entire MSBuild xml file
+ def __init__(self,document=None):
+ self.enumProperties = []
+ self.stringProperties = []
+ self.stringListProperties = []
+ self.boolProperties = []
+ self.intProperties = []
+ if document!=None :
+ self.populate(document)
+ pass
+
+ #document = the entire MSBuild xml file
+ #spaces = don't use
+ #To add a new property (if they exist) copy and paste this code and fill in appropriate places
+ #
+ #if child.nodeName == "<Name>Property":
+ # self.<Name>Properties.append(Property("<Name>",[<List of attributes>],child))
+ #
+ #Replace <Name> with the name of the new property (ex. if property is StringProperty replace <Name> with String)
+ #Replace <List of attributes> with a list of attributes in your property's root node
+ #in the __init__ function add the line self.<Name>Properties = []
+ #
+ #That is all that is required to add new properties
+ #
+ def populate(self,document, spaces=""):
+ for i in range(len(document.childNodes)):
+ child = document.childNodes[i]
+ if child.nodeType == child.ELEMENT_NODE:
+ if child.nodeName == "EnumProperty":
+ self.enumProperties.append(Property("Enum",["Name","Category"],child))
+ if child.nodeName == "StringProperty":
+ self.stringProperties.append(Property("String",["Name","Subtype","Separator","Category","Visible","IncludeInCommandLine","Switch","ReadOnly"],child))
+ if child.nodeName == "StringListProperty":
+ self.stringListProperties.append(Property("StringList",["Name","Category","Switch","Subtype"],child))
+ if child.nodeName == "BoolProperty":
+ self.boolProperties.append(Property("Bool",["ReverseSwitch","Name","Category","Switch","SwitchPrefix","IncludeInCommandLine"],child))
+ if child.nodeName == "IntProperty":
+ self.intProperties.append(Property("Int",["Name","Category","Visible"],child))
+ self.populate(child,spaces+"----")
+ pass
+
+ #outputs information that CMake needs to know about MSBuild xml files
+ def toCMake(self):
+ toReturn = "static cmVS7FlagTable cmVS10CxxTable[] =\n{\n"
+ toReturn += "\n //Enum Properties\n"
+ lastProp = {}
+ for i in self.enumProperties:
+ if i.attributes["Name"] == "CompileAsManaged":
+ #write these out after the rest of the enumProperties
+ lastProp = i
+ continue
+ for j in i.values:
+ #hardcore Brad King's manual fixes for cmVS10CLFlagTable.h
+ if i.attributes["Name"] == "PrecompiledHeader" and j.attributes["Switch"] != "":
+ toReturn+=" {\""+i.attributes["Name"]+"\", \""+j.attributes["Switch"]+"\",\n \""+j.DisplayName+"\", \""+j.attributes["Name"]+"\",\n cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},\n"
+ else:
+ #default (normal, non-hardcoded) case
+ toReturn+=" {\""+i.attributes["Name"]+"\", \""+j.attributes["Switch"]+"\",\n \""+j.DisplayName+"\", \""+j.attributes["Name"]+"\", 0},\n"
+ toReturn += "\n"
+
+ if lastProp != {}:
+ for j in lastProp.values:
+ toReturn+=" {\""+lastProp.attributes["Name"]+"\", \""+j.attributes["Switch"]+"\",\n \""+j.DisplayName+"\", \""+j.attributes["Name"]+"\", 0},\n"
+ toReturn += "\n"
+
+ toReturn += "\n //Bool Properties\n"
+ for i in self.boolProperties:
+ if i.argumentProperty == "":
+ if i.attributes["ReverseSwitch"] != "":
+ toReturn += " {\""+i.attributes["Name"]+"\", \""+i.attributes["ReverseSwitch"]+"\", \"\", \"false\", 0},\n"
+ if i.attributes["Switch"] != "":
+ toReturn += " {\""+i.attributes["Name"]+"\", \""+i.attributes["Switch"]+"\", \"\", \"true\", 0},\n"
+
+ toReturn += "\n //Bool Properties With Argument\n"
+ for i in self.boolProperties:
+ if i.argumentProperty != "":
+ if i.attributes["ReverseSwitch"] != "":
+ toReturn += " {\""+i.attributes["Name"]+"\", \""+i.attributes["ReverseSwitch"]+"\", \"\", \"false\",\n cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},\n"
+ toReturn += " {\""+i.attributes["Name"]+"\", \""+i.attributes["ReverseSwitch"]+"\", \""+i.DisplayName+"\", \"\",\n cmVS7FlagTable::UserValueRequired},\n"
+ if i.attributes["Switch"] != "":
+ toReturn += " {\""+i.attributes["Name"]+"\", \""+i.attributes["Switch"]+"\", \"\", \"true\",\n cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},\n"
+ toReturn += " {\""+i.argumentProperty+"\", \""+i.attributes["Switch"]+"\", \""+i.DisplayName+"\", \"\",\n cmVS7FlagTable::UserValueRequired},\n"
+
+ toReturn += "\n //String List Properties\n"
+ for i in self.stringListProperties:
+ if i.attributes["Switch"] == "":
+ toReturn += " // Skip [" + i.attributes["Name"] + "] - no command line Switch.\n";
+ else:
+ toReturn +=" {\""+i.attributes["Name"]+"\", \""+i.attributes["Switch"]+"\",\n \""+i.DisplayName+"\",\n \"\", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable},\n"
+
+ toReturn += "\n //String Properties\n"
+ for i in self.stringProperties:
+ if i.attributes["Switch"] == "":
+ if i.attributes["Name"] == "PrecompiledHeaderFile":
+ #more hardcoding
+ toReturn += " {\"PrecompiledHeaderFile\", \"Yc\",\n"
+ toReturn += " \"Precompiled Header Name\",\n"
+ toReturn += " \"\", cmVS7FlagTable::UserValueRequired},\n"
+ toReturn += " {\"PrecompiledHeaderFile\", \"Yu\",\n"
+ toReturn += " \"Precompiled Header Name\",\n"
+ toReturn += " \"\", cmVS7FlagTable::UserValueRequired},\n"
+ else:
+ toReturn += " // Skip [" + i.attributes["Name"] + "] - no command line Switch.\n";
+ else:
+ toReturn +=" {\""+i.attributes["Name"]+"\", \""+i.attributes["Switch"]+i.attributes["Separator"]+"\",\n \""+i.DisplayName+"\",\n \"\", cmVS7FlagTable::UserValue},\n"
+
+ toReturn += " {0,0,0,0,0}\n};"
+ return toReturn
+ pass
+
+ #toString function
+ def __str__(self):
+ toReturn = ""
+ allList = [self.enumProperties,self.stringProperties,self.stringListProperties,self.boolProperties,self.intProperties]
+ for p in allList:
+ for i in p:
+ toReturn += "==================================================\n"+str(i).replace("\n","\n ")+"\n==================================================\n"
+
+ return toReturn
+###########################################################################################
+
+###########################################################################################
+# main function
+def main(argv):
+ xml_file = None
+ help = """
+ Please specify an input xml file with -x
+
+ Exiting...
+ Have a nice day :)"""
+ for i in range(0,len(argv)):
+ if argv[i] == "-x":
+ xml_file = argv[i+1]
+ if argv[i] == "-h":
+ print help
+ sys.exit(0)
+ pass
+ if xml_file == None:
+ print help
+ sys.exit(1)
+
+ f = open(xml_file,"r")
+ xml_str = f.read()
+ xml_dom = parseString(xml_str)
+
+ convertor = MSBuildToCMake(xml_dom)
+ print convertor.toCMake()
+
+ xml_dom.unlink()
+###########################################################################################
+# main entry point
+if __name__ == "__main__":
+ main(sys.argv)
+
+sys.exit(0)
diff --git a/Source/cmw9xcom.cxx b/Source/cmw9xcom.cxx
new file mode 100644
index 000000000..4ba274965
--- /dev/null
+++ b/Source/cmw9xcom.cxx
@@ -0,0 +1,45 @@
+/*============================================================================
+ 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 arg = argv[cc];
+ if ( (arg.find_first_of(" ") != arg.npos) &&
+ (arg.find_first_of("\"") == arg.npos) )
+ {
+ arg = "\"" + arg + "\"";
+ }
+ command += " ";
+ command += arg;
+ }
+
+ return cmWin32ProcessExecution::Windows9xHack(command.c_str());
+}
diff --git a/Source/ctest.cxx b/Source/ctest.cxx
new file mode 100644
index 000000000..d65077748
--- /dev/null
+++ b/Source/ctest.cxx
@@ -0,0 +1,343 @@
+/*============================================================================
+ 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 "cmCTest.h"
+#include "cmSystemTools.h"
+
+// Need these for documentation support.
+#include "cmake.h"
+#include "cmDocumentation.h"
+
+#include "CTest/cmCTestScriptHandler.h"
+#include "CTest/cmCTestLaunch.h"
+
+//----------------------------------------------------------------------------
+static const char * cmDocumentationName[][3] =
+{
+ {0,
+ " ctest - Testing driver provided by CMake.", 0},
+ {0,0,0}
+};
+
+//----------------------------------------------------------------------------
+static const char * cmDocumentationUsage[][3] =
+{
+ {0,
+ " ctest [options]", 0},
+ {0,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] =
+{
+ {"-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 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."},
+ {"-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 perform 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"},
+ {"-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."},
+ {"-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."},
+ {"--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 --built-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-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"
+ },
+
+ {"--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." },
+ {"--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}
+};
+
+// this is a test driver program for cmCTest.
+int main (int argc, char *argv[])
+{
+ cmSystemTools::DoNotInheritStdPipes();
+ cmSystemTools::EnableMSVCDebugHook();
+ cmSystemTools::FindExecutableDirectory(argv[0]);
+
+ // Dispatch 'ctest --launch' mode directly.
+ if(argc >= 2 && strcmp(argv[1], "--launch") == 0)
+ {
+ return cmCTestLaunch::Main(argc, argv);
+ }
+
+ int nocwd = 0;
+ cmCTest inst;
+
+ if ( cmSystemTools::GetCurrentWorkingDirectory().size() == 0 )
+ {
+ cmCTestLog(&inst, ERROR_MESSAGE,
+ "Current working directory cannot be established." << std::endl);
+ nocwd = 1;
+ }
+
+ // If there is a testing input file, check for documentation options
+ // only if there are actually arguments. We want running without
+ // arguments to run tests.
+ if(argc > 1 || !(cmSystemTools::FileExists("CTestTestfile.cmake") ||
+ cmSystemTools::FileExists("DartTestfile.txt")))
+ {
+ if(argc == 1)
+ {
+ cmCTestLog(&inst, ERROR_MESSAGE, "*********************************"
+ << std::endl
+ << "No test configuration file found!" << std::endl
+ << "*********************************" << std::endl);
+ }
+ cmDocumentation doc;
+ doc.addCTestStandardDocSections();
+ if(doc.CheckOptions(argc, argv) || nocwd)
+ {
+ // 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
+ return doc.PrintRequestedDocumentation(std::cout)? 0:1;
+#define cout no_cout_use_cmCTestLog
+ }
+ }
+
+#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)
+ {
+ args.push_back(argv[i]);
+ }
+ // run ctest
+ std::string output;
+ int res = inst.Run(args,&output);
+ cmCTestLog(&inst, OUTPUT, output);
+
+ return res;
+}
+
diff --git a/Source/kwsys/Base64.c b/Source/kwsys/Base64.c
new file mode 100644
index 000000000..d07bdd01b
--- /dev/null
+++ b/Source/kwsys/Base64.c
@@ -0,0 +1,279 @@
+/*============================================================================
+ 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(Base64.h)
+
+/* Work-around CMake dependency scanning limitation. This must
+ duplicate the above list of headers. */
+#if 0
+# include "Base64.h.in"
+#endif
+
+/*--------------------------------------------------------------------------*/
+static const unsigned char kwsysBase64EncodeTable[65] =
+"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+"abcdefghijklmnopqrstuvwxyz"
+"0123456789+/";
+
+/*--------------------------------------------------------------------------*/
+static const unsigned char kwsysBase64DecodeTable[256] =
+{
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0x3E,0xFF,0xFF,0xFF,0x3F,
+ 0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,
+ 0x3C,0x3D,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,
+ 0xFF,0x00,0x01,0x02,0x03,0x04,0x05,0x06,
+ 0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,
+ 0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,
+ 0x17,0x18,0x19,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x20,
+ 0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,
+ 0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,0x30,
+ 0x31,0x32,0x33,0xFF,0xFF,0xFF,0xFF,0xFF,
+ /*------------------------------------*/
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
+};
+
+/*--------------------------------------------------------------------------*/
+static unsigned char kwsysBase64EncodeChar(int c)
+{
+ return kwsysBase64EncodeTable[(unsigned char)c];
+}
+
+/*--------------------------------------------------------------------------*/
+static unsigned char kwsysBase64DecodeChar(unsigned char c)
+{
+ return kwsysBase64DecodeTable[c];
+}
+
+/*--------------------------------------------------------------------------*/
+/* Encode 3 bytes into a 4 byte string. */
+void kwsysBase64_Encode3(const unsigned char *src, unsigned char *dest)
+{
+ dest[0] = kwsysBase64EncodeChar((src[0] >> 2) & 0x3F);
+ dest[1] = kwsysBase64EncodeChar(((src[0] << 4) & 0x30)|((src[1] >> 4) & 0x0F));
+ dest[2] = kwsysBase64EncodeChar(((src[1] << 2) & 0x3C)|((src[2] >> 6) & 0x03));
+ dest[3] = kwsysBase64EncodeChar(src[2] & 0x3F);
+}
+
+/*--------------------------------------------------------------------------*/
+/* Encode 2 bytes into a 4 byte string. */
+void kwsysBase64_Encode2(const unsigned char *src, unsigned char *dest)
+{
+ dest[0] = kwsysBase64EncodeChar((src[0] >> 2) & 0x3F);
+ dest[1] = kwsysBase64EncodeChar(((src[0] << 4) & 0x30)|((src[1] >> 4) & 0x0F));
+ dest[2] = kwsysBase64EncodeChar(((src[1] << 2) & 0x3C));
+ dest[3] = '=';
+}
+
+/*--------------------------------------------------------------------------*/
+/* Encode 1 bytes into a 4 byte string. */
+void kwsysBase64_Encode1(const unsigned char *src, unsigned char *dest)
+{
+ dest[0] = kwsysBase64EncodeChar((src[0] >> 2) & 0x3F);
+ dest[1] = kwsysBase64EncodeChar(((src[0] << 4) & 0x30));
+ dest[2] = '=';
+ dest[3] = '=';
+}
+
+/*--------------------------------------------------------------------------*/
+/* Encode 'length' bytes from the input buffer and store the
+ encoded stream into the output buffer. Return the length of the encoded
+ buffer (output). Note that the output buffer must be allocated by the caller
+ (length * 1.5 should be a safe estimate). If 'mark_end' is true than an
+ extra set of 4 bytes is added to the end of the stream if the input is a
+ multiple of 3 bytes. These bytes are invalid chars and therefore they will
+ stop the decoder thus enabling the caller to decode a stream without
+ 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)
+{
+ const unsigned char *ptr = input;
+ const unsigned char *end = input + length;
+ unsigned char *optr = output;
+
+ /* Encode complete triplet */
+
+ while ((end - ptr) >= 3)
+ {
+ kwsysBase64_Encode3(ptr, optr);
+ ptr += 3;
+ optr += 4;
+ }
+
+ /* Encodes a 2-byte ending into 3 bytes and 1 pad byte and writes. */
+
+ if (end - ptr == 2)
+ {
+ kwsysBase64_Encode2(ptr, optr);
+ optr += 4;
+ }
+
+ /* Encodes a 1-byte ending into 2 bytes and 2 pad bytes */
+
+ else if (end - ptr == 1)
+ {
+ kwsysBase64_Encode1(ptr, optr);
+ optr += 4;
+ }
+
+ /* Do we need to mark the end */
+
+ else if (mark_end)
+ {
+ optr[0] = optr[1] = optr[2] = optr[3] = '=';
+ optr += 4;
+ }
+
+ return (unsigned long)(optr - output);
+}
+
+/*--------------------------------------------------------------------------*/
+/* Decode 4 bytes into a 3 byte string. */
+int kwsysBase64_Decode3(const unsigned char *src, unsigned char *dest)
+{
+ unsigned char d0, d1, d2, d3;
+
+ d0 = kwsysBase64DecodeChar(src[0]);
+ d1 = kwsysBase64DecodeChar(src[1]);
+ d2 = kwsysBase64DecodeChar(src[2]);
+ d3 = kwsysBase64DecodeChar(src[3]);
+
+ /* Make sure all characters were valid */
+
+ if (d0 == 0xFF || d1 == 0xFF || d2 == 0xFF || d3 == 0xFF)
+ {
+ return 0;
+ }
+
+ /* Decode the 3 bytes */
+
+ dest[0] = (unsigned char)(((d0 << 2) & 0xFC) | ((d1 >> 4) & 0x03));
+ dest[1] = (unsigned char)(((d1 << 4) & 0xF0) | ((d2 >> 2) & 0x0F));
+ dest[2] = (unsigned char)(((d2 << 6) & 0xC0) | ((d3 >> 0) & 0x3F));
+
+ /* Return the number of bytes actually decoded */
+
+ if (src[2] == '=')
+ {
+ return 1;
+ }
+ if (src[3] == '=')
+ {
+ return 2;
+ }
+ return 3;
+}
+
+/*--------------------------------------------------------------------------*/
+/* Decode bytes from the input buffer and store the decoded stream
+ into the output buffer until 'length' bytes have been decoded. Return the
+ real length of the decoded stream (which should be equal to 'length'). Note
+ that the output buffer must be allocated by the caller. If
+ 'max_input_length' is not null, then it specifies the number of encoded
+ bytes that should be at most read from the input buffer. In that case the
+ '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)
+{
+ const unsigned char *ptr = input;
+ unsigned char *optr = output;
+
+ /* Decode complete triplet */
+
+ if (max_input_length)
+ {
+ const unsigned char *end = input + max_input_length;
+ while (ptr < end)
+ {
+ int len = kwsysBase64_Decode3(ptr, optr);
+ optr += len;
+ if(len < 3)
+ {
+ return (unsigned long)(optr - output);
+ }
+ ptr += 4;
+ }
+ }
+ else
+ {
+ unsigned char *oend = output + length;
+ while ((oend - optr) >= 3)
+ {
+ int len = kwsysBase64_Decode3(ptr, optr);
+ optr += len;
+ if(len < 3)
+ {
+ return (unsigned long)(optr - output);
+ }
+ ptr += 4;
+ }
+
+ /* Decode the last triplet */
+
+ if (oend - optr == 2)
+ {
+ unsigned char temp[3];
+ int len = kwsysBase64_Decode3(ptr, temp);
+ if(len >= 2)
+ {
+ optr[0] = temp[0];
+ optr[1] = temp[1];
+ optr += 2;
+ }
+ else if(len > 0)
+ {
+ optr[0] = temp[0];
+ optr += 1;
+ }
+ }
+ else if (oend - optr == 1)
+ {
+ unsigned char temp[3];
+ int len = kwsysBase64_Decode3(ptr, temp);
+ if(len > 0)
+ {
+ optr[0] = temp[0];
+ optr += 1;
+ }
+ }
+ }
+
+ return (unsigned long)(optr - output);
+}
diff --git a/Source/kwsys/Base64.h.in b/Source/kwsys/Base64.h.in
new file mode 100644
index 000000000..346800768
--- /dev/null
+++ b/Source/kwsys/Base64.h.in
@@ -0,0 +1,120 @@
+/*============================================================================
+ 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@_Base64_h
+#define @KWSYS_NAMESPACE@_Base64_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 kwsysBase64 kwsys_ns(Base64)
+# define kwsysBase64_Decode kwsys_ns(Base64_Decode)
+# define kwsysBase64_Decode3 kwsys_ns(Base64_Decode3)
+# define kwsysBase64_Encode kwsys_ns(Base64_Encode)
+# define kwsysBase64_Encode1 kwsys_ns(Base64_Encode1)
+# define kwsysBase64_Encode2 kwsys_ns(Base64_Encode2)
+# define kwsysBase64_Encode3 kwsys_ns(Base64_Encode3)
+#endif
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+/**
+ * Encode 3 bytes into a 4 byte string.
+ */
+kwsysEXPORT void kwsysBase64_Encode3(const unsigned char *src,
+ unsigned char *dest);
+
+/**
+ * Encode 2 bytes into a 4 byte string.
+ */
+kwsysEXPORT void kwsysBase64_Encode2(const unsigned char *src,
+ unsigned char *dest);
+
+/**
+ * Encode 1 bytes into a 4 byte string.
+ */
+kwsysEXPORT void kwsysBase64_Encode1(const unsigned char *src,
+ unsigned char *dest);
+
+/**
+ * Encode 'length' bytes from the input buffer and store the encoded
+ * stream into the output buffer. Return the length of the encoded
+ * buffer (output). Note that the output buffer must be allocated by
+ * the caller (length * 1.5 should be a safe estimate). If 'mark_end'
+ * is true than an extra set of 4 bytes is added to the end of the
+ * stream if the input is a multiple of 3 bytes. These bytes are
+ * invalid chars and therefore they will stop the decoder thus
+ * enabling the caller to decode a stream without 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).
+ */
+kwsysEXPORT unsigned long kwsysBase64_Encode(const unsigned char *input,
+ unsigned long length,
+ unsigned char *output,
+ int mark_end);
+
+/**
+ * Decode 4 bytes into a 3 byte string. Returns the number of bytes
+ * actually decoded.
+ */
+kwsysEXPORT int kwsysBase64_Decode3(const unsigned char *src,
+ unsigned char *dest);
+
+/**
+ * Decode bytes from the input buffer and store the decoded stream
+ * into the output buffer until 'length' bytes have been decoded.
+ * Return the real length of the decoded stream (which should be equal
+ * to 'length'). Note that the output buffer must be allocated by the
+ * caller. If 'max_input_length' is not null, then it specifies the
+ * number of encoded bytes that should be at most read from the input
+ * buffer. In that case the '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).
+ */
+kwsysEXPORT unsigned long kwsysBase64_Decode(const unsigned char *input,
+ unsigned long length,
+ unsigned char *output,
+ unsigned long max_input_length);
+
+#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 !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
+# undef kwsysBase64
+# undef kwsysBase64_Decode
+# undef kwsysBase64_Decode3
+# undef kwsysBase64_Encode
+# undef kwsysBase64_Encode1
+# undef kwsysBase64_Encode2
+# undef kwsysBase64_Encode3
+# endif
+#endif
+
+#endif
diff --git a/Source/kwsys/CMakeEmptyInputFile.in b/Source/kwsys/CMakeEmptyInputFile.in
new file mode 100644
index 000000000..40b7ea245
--- /dev/null
+++ b/Source/kwsys/CMakeEmptyInputFile.in
@@ -0,0 +1 @@
+@CMAKE_EMPTY_INPUT_FILE_CONTENT@
diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt
new file mode 100644
index 000000000..a132357f3
--- /dev/null
+++ b/Source/kwsys/CMakeLists.txt
@@ -0,0 +1,1042 @@
+#=============================================================================
+# KWSys - Kitware System Library
+# 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.
+#=============================================================================
+
+# The Kitware System Library is intended to be included in other
+# projects. It is completely configurable in that the library's
+# namespace can be configured and the components that are included can
+# be selected invididually.
+
+# Typical usage is to import the kwsys directory tree into a
+# subdirectory under a parent project and enable the classes that will
+# be used. All classes are disabled by default. The CMake listfile
+# above this one configures the library as follows:
+#
+# SET(KWSYS_NAMESPACE foosys)
+# SET(KWSYS_USE_Directory 1) # Enable Directory class.
+# SUBDIRS(kwsys)
+#
+# Optional settings are as follows:
+#
+# KWSYS_HEADER_ROOT = The directory into which to generate the kwsys headers.
+# A directory called "${KWSYS_NAMESPACE}" will be
+# created under this root directory to hold the files.
+#
+# Example:
+#
+# 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
+# KWSYS_INSTALL_LIB_DIR which the libraries and headers from
+# KWSYS_INSTALL_INCLUDE_DIR kwsys should be installed by a "make install".
+# The values should be specified relative to
+# the installation prefix and NOT start with '/'.
+# KWSYS_INSTALL_DOC_DIR = The installation target directory for documentation
+# such as copyright information.
+#
+# KWSYS_INSTALL_COMPONENT_NAME_RUNTIME = Name of runtime and development
+# KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT installation components.
+# If not given the install rules
+# will not be in any component.
+#
+# KWSYS_INSTALL_EXPORT_NAME = The EXPORT option value for install(TARGETS) calls.
+#
+# Example:
+#
+# SET(KWSYS_INSTALL_BIN_DIR bin)
+# SET(KWSYS_INSTALL_LIB_DIR lib)
+# SET(KWSYS_INSTALL_INCLUDE_DIR include)
+# SET(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME Runtime)
+# SET(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT Development)
+
+# Once configured, kwsys should be used as follows from C or C++ code:
+#
+# #include <foosys/Directory.hxx>
+# ...
+# foosys::Directory directory;
+#
+
+# NOTE: This library is intended for internal use by Kitware-driven
+# projects. In order to keep it simple no attempt will be made to
+# maintain backward compatibility when changes are made to KWSys.
+# When an incompatible change is made Kitware's projects that use
+# KWSys will be fixed, but no notification will necessarily be sent to
+# any outside mailing list and no documentation of the change will be
+# written.
+
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6.3 FATAL_ERROR)
+
+#-----------------------------------------------------------------------------
+# If a namespace is not specified, use "kwsys" and enable testing.
+# This should be the case only when kwsys is not included inside
+# another project and is being tested.
+IF(NOT KWSYS_NAMESPACE)
+ SET(KWSYS_NAMESPACE "kwsys")
+ SET(KWSYS_STANDALONE 1)
+ENDIF(NOT KWSYS_NAMESPACE)
+
+#-----------------------------------------------------------------------------
+# The project name is that of the specified namespace.
+PROJECT(${KWSYS_NAMESPACE})
+
+# Tell CMake how to follow dependencies of sources in this directory.
+SET_PROPERTY(DIRECTORY
+ PROPERTY IMPLICIT_DEPENDS_INCLUDE_TRANSFORM
+ "KWSYS_HEADER(%)=<${KWSYS_NAMESPACE}/%>"
+ )
+
+# Select library components.
+IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
+ SET(KWSYS_ENABLE_C 1)
+ # Enable all components.
+ SET(KWSYS_USE_Base64 1)
+ SET(KWSYS_USE_Directory 1)
+ SET(KWSYS_USE_DynamicLoader 1)
+ SET(KWSYS_USE_Glob 1)
+ SET(KWSYS_USE_MD5 1)
+ SET(KWSYS_USE_Process 1)
+ SET(KWSYS_USE_RegularExpression 1)
+ SET(KWSYS_USE_Registry 1)
+ 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_String 1)
+ SET(KWSYS_USE_SystemInformation 1)
+ SET(KWSYS_USE_CPU 1)
+ENDIF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
+
+# Enforce component dependencies.
+IF(KWSYS_USE_SystemTools)
+ SET(KWSYS_USE_Directory 1)
+ENDIF(KWSYS_USE_SystemTools)
+IF(KWSYS_USE_Glob)
+ SET(KWSYS_USE_Directory 1)
+ SET(KWSYS_USE_SystemTools 1)
+ SET(KWSYS_USE_RegularExpression 1)
+ENDIF(KWSYS_USE_Glob)
+IF(KWSYS_USE_Process)
+ SET(KWSYS_USE_System 1)
+ENDIF(KWSYS_USE_Process)
+IF(KWSYS_USE_SystemInformation)
+ SET(KWSYS_USE_Process 1)
+ENDIF(KWSYS_USE_SystemInformation)
+
+# Setup the large file support default.
+IF(KWSYS_LFS_DISABLE)
+ SET(KWSYS_LFS_REQUESTED 0)
+ELSE(KWSYS_LFS_DISABLE)
+ SET(KWSYS_LFS_REQUESTED 1)
+ENDIF(KWSYS_LFS_DISABLE)
+
+# Enable testing if building standalone.
+IF(KWSYS_STANDALONE)
+ INCLUDE(Dart)
+ MARK_AS_ADVANCED(BUILD_TESTING DART_ROOT TCL_TCLSH)
+ IF(BUILD_TESTING)
+ ENABLE_TESTING()
+ ENDIF(BUILD_TESTING)
+ENDIF(KWSYS_STANDALONE)
+
+# Include helper macros.
+INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/kwsysPlatformTests.cmake)
+INCLUDE(CheckTypeSize)
+
+# Do full dependency headers.
+INCLUDE_REGULAR_EXPRESSION("^.*$")
+
+# Use new KWSYS_INSTALL_*_DIR variable names to control installation.
+# Take defaults from the old names. Note that there was no old name
+# for the bin dir, so we take the old lib dir name so DLLs will be
+# installed in a compatible way for old code.
+IF(NOT KWSYS_INSTALL_INCLUDE_DIR)
+ STRING(REGEX REPLACE "^/" "" KWSYS_INSTALL_INCLUDE_DIR
+ "${KWSYS_HEADER_INSTALL_DIR}")
+ENDIF(NOT KWSYS_INSTALL_INCLUDE_DIR)
+IF(NOT KWSYS_INSTALL_LIB_DIR)
+ STRING(REGEX REPLACE "^/" "" KWSYS_INSTALL_LIB_DIR
+ "${KWSYS_LIBRARY_INSTALL_DIR}")
+ENDIF(NOT KWSYS_INSTALL_LIB_DIR)
+IF(NOT KWSYS_INSTALL_BIN_DIR)
+ STRING(REGEX REPLACE "^/" "" KWSYS_INSTALL_BIN_DIR
+ "${KWSYS_LIBRARY_INSTALL_DIR}")
+ENDIF(NOT KWSYS_INSTALL_BIN_DIR)
+
+# Setup header install rules.
+SET(KWSYS_INSTALL_INCLUDE_OPTIONS)
+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)
+
+# Setup library install rules.
+SET(KWSYS_INSTALL_LIBRARY_RULE)
+IF(KWSYS_INSTALL_LIB_DIR)
+ IF(KWSYS_INSTALL_EXPORT_NAME)
+ LIST(APPEND KWSYS_INSTALL_LIBRARY_RULE EXPORT ${KWSYS_INSTALL_EXPORT_NAME})
+ ENDIF()
+ # Install the shared library to the lib directory.
+ SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
+ LIBRARY DESTINATION ${KWSYS_INSTALL_LIB_DIR}
+ )
+ # Assign the shared library to the runtime component.
+ IF(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME)
+ SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
+ COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_RUNTIME}
+ )
+ ENDIF(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME)
+
+ # Install the archive to the lib directory.
+ SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
+ ARCHIVE DESTINATION ${KWSYS_INSTALL_LIB_DIR}
+ )
+ # Assign the archive to the development component.
+ IF(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT)
+ SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
+ COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT}
+ )
+ ENDIF(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT)
+ENDIF(KWSYS_INSTALL_LIB_DIR)
+IF(KWSYS_INSTALL_BIN_DIR)
+ # Install the runtime library to the bin directory.
+ SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
+ RUNTIME DESTINATION ${KWSYS_INSTALL_BIN_DIR}
+ )
+ # Assign the runtime library to the runtime component.
+ IF(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME)
+ SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
+ COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_RUNTIME}
+ )
+ ENDIF(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME)
+ENDIF(KWSYS_INSTALL_BIN_DIR)
+
+# Do not support old KWSYS_*a_INSTALL_DIR variable names.
+SET(KWSYS_HEADER_INSTALL_DIR)
+SET(KWSYS_LIBRARY_INSTALL_DIR)
+
+# Generated source files will need this header.
+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)
+
+# Select plugin module file name convention.
+IF(NOT KWSYS_DynamicLoader_PREFIX)
+ SET(KWSYS_DynamicLoader_PREFIX ${CMAKE_SHARED_MODULE_PREFIX})
+ENDIF()
+IF(NOT KWSYS_DynamicLoader_SUFFIX)
+ SET(KWSYS_DynamicLoader_SUFFIX ${CMAKE_SHARED_MODULE_SUFFIX})
+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)
+
+#-----------------------------------------------------------------------------
+# Adjust compiler flags for some platforms.
+IF(NOT CMAKE_COMPILER_IS_GNUCXX)
+ IF(CMAKE_SYSTEM MATCHES "OSF1-V.*")
+ STRING(REGEX MATCH "-timplicit_local"
+ KWSYS_CXX_FLAGS_HAVE_IMPLICIT_LOCAL "${CMAKE_CXX_FLAGS}")
+ STRING(REGEX MATCH "-no_implicit_include"
+ 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)
+ 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.*")
+ 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)
+
+#-----------------------------------------------------------------------------
+# Configure Large File Support.
+KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_CSTDIO
+ "Checking whether header cstdio is available" DIRECT)
+SET(KWSYS_LFS_AVAILABLE 0)
+IF(KWSYS_LFS_REQUESTED)
+ # Large File Support is requested.
+ SET(KWSYS_LFS_REQUESTED 1)
+
+ # Check for large file support.
+ SET(KWSYS_PLATFORM_CXX_TEST_DEFINES
+ -DKWSYS_CXX_HAS_CSTDIO=${KWSYS_CXX_HAS_CSTDIO})
+ KWSYS_PLATFORM_CXX_TEST_RUN(KWSYS_LFS_WORKS
+ "Checking for Large File Support" DIRECT)
+ SET(KWSYS_PLATFORM_CXX_TEST_DEFINES)
+
+ IF(KWSYS_LFS_WORKS)
+ SET(KWSYS_LFS_AVAILABLE 1)
+ ENDIF(KWSYS_LFS_WORKS)
+ELSE(KWSYS_LFS_REQUESTED)
+ # Large File Support is not requested.
+ SET(KWSYS_LFS_REQUESTED 0)
+ENDIF(KWSYS_LFS_REQUESTED)
+
+#-----------------------------------------------------------------------------
+# 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)
+KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS___INT64
+ "Checking whether C++ compiler has '__int64'" DIRECT)
+IF(KWSYS_CXX_HAS___INT64)
+ KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_SAME_LONG_AND___INT64
+ "Checking whether long and __int64 are the same type" DIRECT)
+ IF(KWSYS_CXX_HAS_LONG_LONG)
+ KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_SAME_LONG_LONG_AND___INT64
+ "Checking whether long long and __int64 are the same type" DIRECT)
+ ENDIF()
+ENDIF()
+
+# Enable the "long long" type if it is available. It is standard in
+# C99 and C++03 but not in earlier standards.
+IF(KWSYS_CXX_HAS_LONG_LONG)
+ SET(KWSYS_USE_LONG_LONG 1)
+ELSE()
+ SET(KWSYS_USE_LONG_LONG 0)
+ENDIF()
+
+# Enable the "__int64" type if it is available and unique. It is not
+# standard.
+SET(KWSYS_USE___INT64 0)
+IF(KWSYS_CXX_HAS___INT64)
+ IF(NOT KWSYS_CXX_SAME_LONG_AND___INT64)
+ IF(NOT KWSYS_CXX_SAME_LONG_LONG_AND___INT64)
+ SET(KWSYS_USE___INT64 1)
+ ENDIF()
+ ENDIF()
+ENDIF()
+
+IF(KWSYS_USE_FundamentalType)
+ # 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)
+
+IF(KWSYS_USE_IOStream)
+ # Determine whether iostreams support long long.
+ IF(KWSYS_CXX_HAS_LONG_LONG)
+ 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_HAS_ISTREAM_LONG_LONG
+ "Checking if istream supports long long" DIRECT)
+ KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_HAS_OSTREAM_LONG_LONG
+ "Checking if ostream supports long long" DIRECT)
+ SET(KWSYS_PLATFORM_CXX_TEST_DEFINES)
+ ELSE()
+ SET(KWSYS_IOS_HAS_ISTREAM_LONG_LONG 0)
+ SET(KWSYS_IOS_HAS_OSTREAM_LONG_LONG 0)
+ ENDIF()
+ENDIF(KWSYS_USE_IOStream)
+
+IF(KWSYS_NAMESPACE MATCHES "^kwsys$")
+ SET(KWSYS_NAME_IS_KWSYS 1)
+ELSE(KWSYS_NAMESPACE MATCHES "^kwsys$")
+ SET(KWSYS_NAME_IS_KWSYS 0)
+ENDIF(KWSYS_NAMESPACE MATCHES "^kwsys$")
+
+# 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$")
+
+IF(KWSYS_BUILD_SHARED)
+ SET(KWSYS_BUILD_SHARED 1)
+ SET(KWSYS_LIBRARY_TYPE SHARED)
+ELSE(KWSYS_BUILD_SHARED)
+ SET(KWSYS_BUILD_SHARED 0)
+ SET(KWSYS_LIBRARY_TYPE STATIC)
+ENDIF(KWSYS_BUILD_SHARED)
+
+#-----------------------------------------------------------------------------
+# Configure some implementation details.
+
+KWSYS_PLATFORM_C_TEST(KWSYS_C_HAS_PTRDIFF_T
+ "Checking whether C compiler has ptrdiff_t in stddef.h" DIRECT)
+KWSYS_PLATFORM_C_TEST(KWSYS_C_HAS_SSIZE_T
+ "Checking whether C compiler has ssize_t in unistd.h" DIRECT)
+SET_SOURCE_FILES_PROPERTIES(ProcessUNIX.c System.c PROPERTIES
+ COMPILE_FLAGS "-DKWSYS_C_HAS_PTRDIFF_T=${KWSYS_C_HAS_PTRDIFF_T} -DKWSYS_C_HAS_SSIZE_T=${KWSYS_C_HAS_SSIZE_T}"
+ )
+
+IF(KWSYS_USE_SystemTools)
+ KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_SETENV
+ "Checking whether CXX compiler has setenv" DIRECT)
+ KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_UNSETENV
+ "Checking whether CXX compiler has unsetenv" DIRECT)
+ KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H
+ "Checking whether CXX compiler has environ in stdlib.h" DIRECT)
+ SET_SOURCE_FILES_PROPERTIES(SystemTools.cxx PROPERTIES
+ COMPILE_FLAGS "-DKWSYS_CXX_HAS_SETENV=${KWSYS_CXX_HAS_SETENV} -DKWSYS_CXX_HAS_UNSETENV=${KWSYS_CXX_HAS_UNSETENV} -DKWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H=${KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H}")
+ENDIF()
+
+IF(KWSYS_USE_SystemInformation)
+ SET_PROPERTY(SOURCE SystemInformation.cxx PROPERTY
+ COMPILE_DEFINITIONS KWSYS_USE_LONG_LONG=${KWSYS_USE_LONG_LONG}
+ KWSYS_USE___INT64=${KWSYS_USE___INT64})
+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)
+SET(KWSYS_HEADER_DIR "${KWSYS_HEADER_ROOT}/${KWSYS_NAMESPACE}")
+INCLUDE_DIRECTORIES(${KWSYS_HEADER_ROOT})
+
+#-----------------------------------------------------------------------------
+IF(KWSYS_INSTALL_DOC_DIR)
+ # Assign the license to the runtime component since it must be
+ # distributed with binary forms of this software.
+ IF(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME)
+ SET(KWSYS_INSTALL_LICENSE_OPTIONS ${KWSYS_INSTALL_LICENSE_OPTIONS}
+ COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_RUNTIME}
+ )
+ ENDIF(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME)
+
+ # 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)
+
+#-----------------------------------------------------------------------------
+# Build a list of classes and headers we need to implement the
+# selected components. Initialize with required components.
+SET(KWSYS_CLASSES)
+SET(KWSYS_H_FILES Configure SharedForward)
+SET(KWSYS_HXX_FILES Configure String
+ hashtable hash_fun hash_map hash_set
+ auto_ptr
+ )
+
+# Add selected C++ classes.
+SET(cppclasses
+ Directory DynamicLoader Glob RegularExpression SystemTools
+ CommandLineArguments Registry IOStream SystemInformation
+ )
+FOREACH(cpp ${cppclasses})
+ IF(KWSYS_USE_${cpp})
+ # Use the corresponding class.
+ SET(KWSYS_CLASSES ${KWSYS_CLASSES} ${cpp})
+
+ # 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)
+
+# Add selected C components.
+FOREACH(c
+ Process Base64 FundamentalType MD5 Terminal System String CPU
+ )
+ IF(KWSYS_USE_${c})
+ # Use the corresponding header file.
+ SET(KWSYS_H_FILES ${KWSYS_H_FILES} ${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)
+
+#-----------------------------------------------------------------------------
+# Build a list of sources for the library based on components that are
+# included.
+SET(KWSYS_C_SRCS)
+SET(KWSYS_CXX_SRCS)
+
+# Add the proper sources for this platform's Process implementation.
+IF(KWSYS_USE_Process)
+ IF(NOT UNIX)
+ # Use the Windows implementation. We need the encoded forwarding executable.
+ SET(KWSYS_C_SRCS ${KWSYS_C_SRCS} ProcessWin32.c
+ ${PROJECT_BINARY_DIR}/${KWSYS_NAMESPACE}ProcessFwd9xEnc.c)
+ SET_SOURCE_FILES_PROPERTIES(
+ ${PROJECT_BINARY_DIR}/${KWSYS_NAMESPACE}ProcessFwd9xEnc.c
+ PROPERTIES GENERATED 1)
+ ELSE(NOT UNIX)
+ # Use the UNIX implementation.
+ SET(KWSYS_C_SRCS ${KWSYS_C_SRCS} ProcessUNIX.c)
+ ENDIF(NOT UNIX)
+ENDIF(KWSYS_USE_Process)
+
+# Add selected C sources.
+FOREACH(c Base64 MD5 Terminal System String)
+ IF(KWSYS_USE_${c})
+ SET(KWSYS_C_SRCS ${KWSYS_C_SRCS} ${c}.c)
+ ENDIF(KWSYS_USE_${c})
+ENDFOREACH(c)
+
+# 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)
+
+ # Configure the header for this class.
+ CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/${c}.hxx.in ${KWSYS_HEADER_DIR}/${c}.hxx
+ @ONLY IMMEDIATE)
+ SET(KWSYS_CXX_SRCS ${KWSYS_CXX_SRCS} ${KWSYS_HEADER_DIR}/${c}.hxx)
+
+ # Create an install target for the header.
+ IF(KWSYS_INSTALL_INCLUDE_DIR)
+ INSTALL(FILES ${KWSYS_HEADER_DIR}/${c}.hxx
+ DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE}
+ ${KWSYS_INSTALL_INCLUDE_OPTIONS})
+ ENDIF(KWSYS_INSTALL_INCLUDE_DIR)
+ENDFOREACH(c)
+
+# Configure C headers.
+FOREACH(h ${KWSYS_H_FILES})
+ # Configure the header into the given directory.
+ CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/${h}.h.in ${KWSYS_HEADER_DIR}/${h}.h
+ @ONLY IMMEDIATE)
+ SET(KWSYS_C_SRCS ${KWSYS_C_SRCS} ${KWSYS_HEADER_DIR}/${h}.h)
+
+ # Create an install target for the header.
+ IF(KWSYS_INSTALL_INCLUDE_DIR)
+ INSTALL(FILES ${KWSYS_HEADER_DIR}/${h}.h
+ DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE}
+ ${KWSYS_INSTALL_INCLUDE_OPTIONS})
+ ENDIF(KWSYS_INSTALL_INCLUDE_DIR)
+ENDFOREACH(h)
+
+# Configure other C++ headers.
+FOREACH(h ${KWSYS_HXX_FILES})
+ # Configure the header into the given directory.
+ CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/${h}.hxx.in ${KWSYS_HEADER_DIR}/${h}.hxx
+ @ONLY IMMEDIATE)
+ SET(KWSYS_CXX_SRCS ${KWSYS_CXX_SRCS} ${KWSYS_HEADER_DIR}/${h}.hxx)
+
+ # Create an install target for the header.
+ IF(KWSYS_INSTALL_INCLUDE_DIR)
+ INSTALL(FILES ${KWSYS_HEADER_DIR}/${h}.hxx
+ DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE}
+ ${KWSYS_INSTALL_INCLUDE_OPTIONS})
+ ENDIF(KWSYS_INSTALL_INCLUDE_DIR)
+ENDFOREACH(h)
+
+#-----------------------------------------------------------------------------
+# Add the library with the configured name and list of sources.
+IF(KWSYS_C_SRCS OR KWSYS_CXX_SRCS)
+ ADD_LIBRARY(${KWSYS_NAMESPACE} ${KWSYS_LIBRARY_TYPE}
+ ${KWSYS_C_SRCS} ${KWSYS_CXX_SRCS})
+ SET_PROPERTY(TARGET ${KWSYS_NAMESPACE} PROPERTY LABELS ${KWSYS_LABELS_LIB})
+ IF(KWSYS_USE_DynamicLoader)
+ IF(UNIX)
+ TARGET_LINK_LIBRARIES(${KWSYS_NAMESPACE} ${CMAKE_DL_LIBS})
+ ENDIF(UNIX)
+ ENDIF(KWSYS_USE_DynamicLoader)
+
+ IF(KWSYS_USE_SystemInformation AND WIN32)
+ TARGET_LINK_LIBRARIES(${KWSYS_NAMESPACE} ws2_32)
+ ENDIF(KWSYS_USE_SystemInformation AND WIN32)
+
+ # Apply user-defined target properties to the library.
+ IF(KWSYS_PROPERTIES_CXX)
+ SET_TARGET_PROPERTIES(${KWSYS_NAMESPACE} PROPERTIES
+ ${KWSYS_PROPERTIES_CXX}
+ )
+ ENDIF(KWSYS_PROPERTIES_CXX)
+
+ # Create an install target for the library.
+ IF(KWSYS_INSTALL_LIBRARY_RULE)
+ INSTALL(TARGETS ${KWSYS_NAMESPACE} ${KWSYS_INSTALL_LIBRARY_RULE})
+ ENDIF(KWSYS_INSTALL_LIBRARY_RULE)
+ENDIF(KWSYS_C_SRCS OR KWSYS_CXX_SRCS)
+
+# Add a C-only library if requested.
+IF(KWSYS_ENABLE_C AND KWSYS_C_SRCS)
+ ADD_LIBRARY(${KWSYS_NAMESPACE}_c ${KWSYS_LIBRARY_TYPE} ${KWSYS_C_SRCS})
+ SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}_c PROPERTY LABELS ${KWSYS_LABELS_LIB})
+
+ # Apply user-defined target properties to the library.
+ IF(KWSYS_PROPERTIES_C)
+ SET_TARGET_PROPERTIES(${KWSYS_NAMESPACE} PROPERTIES
+ ${KWSYS_PROPERTIES_C}
+ )
+ ENDIF(KWSYS_PROPERTIES_C)
+
+ # Create an install target for the library.
+ IF(KWSYS_INSTALL_LIBRARY_RULE)
+ INSTALL(TARGETS ${KWSYS_NAMESPACE}_c ${KWSYS_INSTALL_LIBRARY_RULE})
+ ENDIF(KWSYS_INSTALL_LIBRARY_RULE)
+ENDIF(KWSYS_ENABLE_C AND KWSYS_C_SRCS)
+
+# 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}")
+
+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)
+
+#-----------------------------------------------------------------------------
+# Process execution on windows needs to build a forwarding executable
+# that works around a Win9x bug. We encode the executable into a C
+# file and build it into the library. Win9x platforms reproduce the
+# executable into a temporary directory when it is needed.
+IF(KWSYS_USE_Process)
+ IF(NOT UNIX)
+ # Build the forwarding executable itself and a program that will
+ # encode it into a C file.
+ ADD_EXECUTABLE(${KWSYS_NAMESPACE}ProcessFwd9x ProcessFwd9x.c)
+ ADD_EXECUTABLE(${KWSYS_NAMESPACE}EncodeExecutable EncodeExecutable.c)
+ SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}ProcessFwd9x PROPERTY RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
+ SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}EncodeExecutable PROPERTY RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
+ SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}ProcessFwd9x PROPERTY LABELS ${KWSYS_LABELS_EXE})
+ SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}EncodeExecutable PROPERTY LABELS ${KWSYS_LABELS_EXE})
+
+ SET(CFG_INTDIR "/${CMAKE_CFG_INTDIR}")
+ IF(CMAKE_BUILD_TOOL MATCHES "make")
+ SET(CFG_INTDIR "")
+ ENDIF(CMAKE_BUILD_TOOL MATCHES "make")
+
+ # Take advantage of a better custom command syntax if possible.
+ SET(CMD ${CMAKE_CURRENT_BINARY_DIR}${CFG_INTDIR}/${KWSYS_NAMESPACE}EncodeExecutable.exe)
+ SET(FWD ${CMAKE_CURRENT_BINARY_DIR}${CFG_INTDIR}/${KWSYS_NAMESPACE}ProcessFwd9x.exe)
+ ADD_CUSTOM_COMMAND(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${KWSYS_NAMESPACE}ProcessFwd9xEnc.c
+ COMMAND ${CMD}
+ ARGS ${FWD} ${CMAKE_CURRENT_BINARY_DIR}/${KWSYS_NAMESPACE}ProcessFwd9xEnc.c
+ ${KWSYS_NAMESPACE} ProcessFwd9x
+ DEPENDS ${CMD} ${FWD})
+
+ # Make sure build occurs in proper order.
+ ADD_DEPENDENCIES(${KWSYS_NAMESPACE} ${KWSYS_NAMESPACE}ProcessFwd9x
+ ${KWSYS_NAMESPACE}EncodeExecutable)
+ ENDIF(NOT UNIX)
+ENDIF(KWSYS_USE_Process)
+
+#-----------------------------------------------------------------------------
+# Setup testing if not being built as part of another project.
+IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
+ IF(BUILD_TESTING)
+ # Compute the location of executables.
+ SET(EXEC_DIR "${CMAKE_CURRENT_BINARY_DIR}")
+ IF(EXECUTABLE_OUTPUT_PATH)
+ SET(EXEC_DIR "${EXECUTABLE_OUTPUT_PATH}")
+ ENDIF(EXECUTABLE_OUTPUT_PATH)
+
+ # C tests
+ SET(KWSYS_C_TESTS
+ testEncode
+ testTerminal
+ )
+ IF(KWSYS_STANDALONE)
+ SET(KWSYS_C_TESTS ${KWSYS_C_TESTS} testFail)
+ ENDIF()
+ CREATE_TEST_SOURCELIST(
+ KWSYS_C_TEST_SRCS ${KWSYS_NAMESPACE}TestsC.c
+ ${KWSYS_C_TESTS}
+ )
+ ADD_EXECUTABLE(${KWSYS_NAMESPACE}TestsC ${KWSYS_C_TEST_SRCS})
+ SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestsC PROPERTY LABELS ${KWSYS_LABELS_EXE})
+ TARGET_LINK_LIBRARIES(${KWSYS_NAMESPACE}TestsC ${KWSYS_NAMESPACE}_c)
+ 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)
+
+ # C++ tests
+ IF(NOT WATCOM)
+ SET(KWSYS_CXX_TESTS
+ testAutoPtr
+ testHashSTL
+ )
+ ENDIF(NOT WATCOM)
+ SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
+ testRegistry
+ testIOS
+ testSystemTools
+ testCommandLineArguments
+ testCommandLineArguments1
+ )
+ IF(KWSYS_USE_SystemInformation)
+ SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS} testSystemInformation)
+ ENDIF(KWSYS_USE_SystemInformation)
+ 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)
+ CREATE_TEST_SOURCELIST(
+ KWSYS_CXX_TEST_SRCS ${KWSYS_NAMESPACE}TestsCxx.cxx
+ ${KWSYS_CXX_TESTS}
+ )
+ 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")
+ CONFIGURE_FILE(
+ ${PROJECT_SOURCE_DIR}/testSystemTools.h.in
+ ${PROJECT_BINARY_DIR}/testSystemTools.h)
+ INCLUDE_DIRECTORIES(${PROJECT_BINARY_DIR})
+
+ IF(CTEST_TEST_KWSYS)
+ 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)
+
+ SET(KWSYS_TEST_ARGS_testCommandLineArguments
+ --another-bool-variable
+ --long3=opt
+ --set-bool-arg1
+ -SSS ken brad bill andy
+ --some-bool-variable=true
+ --some-double-variable12.5
+ --some-int-variable 14
+ "--some-string-variable=test string with space"
+ --some-multi-argument 5 1 8 3 7 1 3 9 7 1
+ -N 12.5 -SS=andy -N 1.31 -N 22
+ -SS=bill -BBtrue -SS=brad
+ -BBtrue
+ -BBfalse
+ -SS=ken
+ -A
+ -C=test
+ --long2 hello
+ )
+ SET(KWSYS_TEST_ARGS_testCommandLineArguments1
+ --ignored
+ -n 24
+ --second-ignored
+ "-m=test value"
+ third-ignored
+ -p
+ some junk at the end
+ )
+ 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)
+
+ # Process tests.
+ ADD_EXECUTABLE(${KWSYS_NAMESPACE}TestProcess testProcess.c)
+ SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestProcess PROPERTY LABELS ${KWSYS_LABELS_EXE})
+ 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})
+ 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)
+
+ # Some Apple compilers produce bad optimizations in this source.
+ IF(APPLE AND "${CMAKE_C_COMPILER_ID}" MATCHES "^(GNU|LLVM)$")
+ SET_SOURCE_FILES_PROPERTIES(testProcess.c PROPERTIES COMPILE_FLAGS -O0)
+ ENDIF()
+
+ # Test SharedForward
+ CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/testSharedForward.c.in
+ ${PROJECT_BINARY_DIR}/testSharedForward.c @ONLY IMMEDIATE)
+ ADD_EXECUTABLE(${KWSYS_NAMESPACE}TestSharedForward
+ ${PROJECT_BINARY_DIR}/testSharedForward.c)
+ SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestSharedForward PROPERTY LABELS ${KWSYS_LABELS_EXE})
+ ADD_DEPENDENCIES(${KWSYS_NAMESPACE}TestSharedForward ${KWSYS_NAMESPACE}_c)
+ ADD_TEST(kwsys.testSharedForward ${EXEC_DIR}/${KWSYS_NAMESPACE}TestSharedForward 1)
+ SET_PROPERTY(TEST kwsys.testSharedForward PROPERTY LABELS ${KWSYS_LABELS_TEST})
+
+ # Configure some test properties.
+ IF(KWSYS_STANDALONE)
+ # We expect test to fail
+ SET_TESTS_PROPERTIES(kwsys.testFail PROPERTIES WILL_FAIL ON)
+ GET_TEST_PROPERTY(kwsys.testFail WILL_FAIL wfv)
+ SET_TESTS_PROPERTIES(kwsys.testRegistry PROPERTIES FAIL_REGULAR_EXPRESSION "ERROR_NOT_VALGRIND;FAIL;Test failed")
+ SET_TESTS_PROPERTIES(kwsys.testRegistry PROPERTIES PASS_REGULAR_EXPRESSION "Test passed")
+ SET_TESTS_PROPERTIES(kwsys.testFail PROPERTIES MEASUREMENT "Some Key=Some Value")
+ MESSAGE(STATUS "GET_TEST_PROPERTY returned: ${wfv}")
+ ENDIF()
+
+ # 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)
diff --git a/Source/kwsys/CPU.h.in b/Source/kwsys/CPU.h.in
new file mode 100644
index 000000000..ecd29d133
--- /dev/null
+++ b/Source/kwsys/CPU.h.in
@@ -0,0 +1,117 @@
+/*============================================================================
+ 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
+
+/* 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/CTestConfig.cmake b/Source/kwsys/CTestConfig.cmake
new file mode 100644
index 000000000..9ab6ed86c
--- /dev/null
+++ b/Source/kwsys/CTestConfig.cmake
@@ -0,0 +1,18 @@
+#=============================================================================
+# 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.
+#=============================================================================
+set (CTEST_PROJECT_NAME "kwsys")
+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)
diff --git a/Source/kwsys/CommandLineArguments.cxx b/Source/kwsys/CommandLineArguments.cxx
new file mode 100644
index 000000000..ece88ae89
--- /dev/null
+++ b/Source/kwsys/CommandLineArguments.cxx
@@ -0,0 +1,859 @@
+/*============================================================================
+ 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(CommandLineArguments.hxx)
+
+#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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef _MSC_VER
+# pragma warning (disable: 4786)
+#endif
+
+#if defined(__sgi) && !defined(__GNUC__)
+# pragma set woff 1375 /* base class destructor not virtual */
+#endif
+
+#if 0
+# define CommandLineArguments_DEBUG(x) \
+ kwsys_ios::cout << __LINE__ << " CLA: " << x << kwsys_ios::endl
+#else
+# define CommandLineArguments_DEBUG(x)
+#endif
+
+namespace KWSYS_NAMESPACE
+{
+
+//----------------------------------------------------------------------------
+//============================================================================
+struct CommandLineArgumentsCallbackStructure
+{
+ const char* Argument;
+ int ArgumentType;
+ CommandLineArguments::CallbackType Callback;
+ void* CallData;
+ void* Variable;
+ int VariableType;
+ const char* Help;
+};
+
+class CommandLineArgumentsVectorOfStrings :
+ public kwsys_stl::vector<kwsys::String> {};
+class CommandLineArgumentsSetOfStrings :
+ public kwsys_stl::set<kwsys::String> {};
+class CommandLineArgumentsMapOfStrucs :
+ public kwsys_stl::map<kwsys::String,
+ CommandLineArgumentsCallbackStructure> {};
+
+class CommandLineArgumentsInternal
+{
+public:
+ CommandLineArgumentsInternal()
+ {
+ this->UnknownArgumentCallback = 0;
+ this->ClientData = 0;
+ this->LastArgument = 0;
+ }
+
+ typedef CommandLineArgumentsVectorOfStrings VectorOfStrings;
+ typedef CommandLineArgumentsMapOfStrucs CallbacksMap;
+ typedef kwsys::String String;
+ typedef CommandLineArgumentsSetOfStrings SetOfStrings;
+
+ VectorOfStrings Argv;
+ String Argv0;
+ CallbacksMap Callbacks;
+
+ CommandLineArguments::ErrorCallbackType UnknownArgumentCallback;
+ void* ClientData;
+
+ VectorOfStrings::size_type LastArgument;
+
+ VectorOfStrings UnusedArguments;
+};
+//============================================================================
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+CommandLineArguments::CommandLineArguments()
+{
+ this->Internals = new CommandLineArguments::Internal;
+ this->Help = "";
+ this->LineLength = 80;
+ this->StoreUnusedArgumentsFlag = false;
+}
+
+//----------------------------------------------------------------------------
+CommandLineArguments::~CommandLineArguments()
+{
+ delete this->Internals;
+}
+
+//----------------------------------------------------------------------------
+void CommandLineArguments::Initialize(int argc, const char* const argv[])
+{
+ int cc;
+
+ this->Initialize();
+ this->Internals->Argv0 = argv[0];
+ for ( cc = 1; cc < argc; cc ++ )
+ {
+ this->ProcessArgument(argv[cc]);
+ }
+}
+
+//----------------------------------------------------------------------------
+void CommandLineArguments::Initialize(int argc, char* argv[])
+{
+ this->Initialize(argc, static_cast<const char* const*>(argv));
+}
+
+//----------------------------------------------------------------------------
+void CommandLineArguments::Initialize()
+{
+ this->Internals->Argv.clear();
+ this->Internals->LastArgument = 0;
+}
+
+//----------------------------------------------------------------------------
+void CommandLineArguments::ProcessArgument(const char* arg)
+{
+ this->Internals->Argv.push_back(arg);
+}
+
+//----------------------------------------------------------------------------
+bool CommandLineArguments::GetMatchedArguments(
+ kwsys_stl::vector<kwsys_stl::string>* matches,
+ const kwsys_stl::string& arg)
+{
+ matches->clear();
+ CommandLineArguments::Internal::CallbacksMap::iterator it;
+
+ // Does the argument match to any we know about?
+ for ( it = this->Internals->Callbacks.begin();
+ it != this->Internals->Callbacks.end();
+ it ++ )
+ {
+ const CommandLineArguments::Internal::String& parg = it->first;
+ CommandLineArgumentsCallbackStructure *cs = &it->second;
+ if (cs->ArgumentType == CommandLineArguments::NO_ARGUMENT ||
+ cs->ArgumentType == CommandLineArguments::SPACE_ARGUMENT)
+ {
+ if ( arg == parg )
+ {
+ matches->push_back(parg);
+ }
+ }
+ else if ( arg.find( parg ) == 0 )
+ {
+ matches->push_back(parg);
+ }
+ }
+ return matches->size() > 0;
+}
+
+//----------------------------------------------------------------------------
+int CommandLineArguments::Parse()
+{
+ kwsys_stl::vector<kwsys_stl::string>::size_type cc;
+ kwsys_stl::vector<kwsys_stl::string> matches;
+ if ( this->StoreUnusedArgumentsFlag )
+ {
+ this->Internals->UnusedArguments.clear();
+ }
+ for ( cc = 0; cc < this->Internals->Argv.size(); cc ++ )
+ {
+ const kwsys_stl::string& arg = this->Internals->Argv[cc];
+ CommandLineArguments_DEBUG("Process argument: " << arg);
+ this->Internals->LastArgument = cc;
+ if ( this->GetMatchedArguments(&matches, arg) )
+ {
+ // Ok, we found one or more arguments that match what user specified.
+ // Let's find the longest one.
+ CommandLineArguments::Internal::VectorOfStrings::size_type kk;
+ CommandLineArguments::Internal::VectorOfStrings::size_type maxidx = 0;
+ CommandLineArguments::Internal::String::size_type maxlen = 0;
+ for ( kk = 0; kk < matches.size(); kk ++ )
+ {
+ if ( matches[kk].size() > maxlen )
+ {
+ maxlen = matches[kk].size();
+ maxidx = kk;
+ }
+ }
+ // So, the longest one is probably the right one. Now see if it has any
+ // additional value
+ CommandLineArgumentsCallbackStructure *cs
+ = &this->Internals->Callbacks[matches[maxidx]];
+ const kwsys_stl::string& sarg = matches[maxidx];
+ if ( cs->Argument != sarg )
+ {
+ abort();
+ }
+ switch ( cs->ArgumentType )
+ {
+ case NO_ARGUMENT:
+ // No value
+ if ( !this->PopulateVariable(cs, 0) )
+ {
+ return 0;
+ }
+ break;
+ case SPACE_ARGUMENT:
+ if ( cc == this->Internals->Argv.size()-1 )
+ {
+ this->Internals->LastArgument --;
+ return 0;
+ }
+ CommandLineArguments_DEBUG("This is a space argument: " << arg
+ << " value: " << this->Internals->Argv[cc+1].c_str());
+ // Value is the next argument
+ if ( !this->PopulateVariable(cs, this->Internals->Argv[cc+1].c_str()) )
+ {
+ return 0;
+ }
+ cc ++;
+ break;
+ case EQUAL_ARGUMENT:
+ if ( arg.size() == sarg.size() || *(arg.c_str() + sarg.size()) != '=' )
+ {
+ this->Internals->LastArgument --;
+ return 0;
+ }
+ // Value is everythng followed the '=' sign
+ if ( !this->PopulateVariable(cs, arg.c_str() + sarg.size() + 1) )
+ {
+ return 0;
+ }
+ break;
+ case CONCAT_ARGUMENT:
+ // Value is whatever follows the argument
+ if ( !this->PopulateVariable(cs, arg.c_str() + sarg.size()) )
+ {
+ return 0;
+ }
+ break;
+ case MULTI_ARGUMENT:
+ // Suck in all the rest of the arguments
+ CommandLineArguments_DEBUG("This is a multi argument: " << arg);
+ for (cc++; cc < this->Internals->Argv.size(); ++ cc )
+ {
+ const kwsys_stl::string& marg = this->Internals->Argv[cc];
+ CommandLineArguments_DEBUG(" check multi argument value: " << marg);
+ if ( this->GetMatchedArguments(&matches, marg) )
+ {
+ CommandLineArguments_DEBUG("End of multi argument " << arg << " with value: " << marg);
+ break;
+ }
+ CommandLineArguments_DEBUG(" populate multi argument value: " << marg);
+ if ( !this->PopulateVariable(cs, marg.c_str()) )
+ {
+ return 0;
+ }
+ }
+ if ( cc != this->Internals->Argv.size() )
+ {
+ CommandLineArguments_DEBUG("Again End of multi argument " << arg);
+ cc--;
+ continue;
+ }
+ break;
+ default:
+ kwsys_ios::cerr << "Got unknown argument type: \"" << cs->ArgumentType << "\"" << kwsys_ios::endl;
+ this->Internals->LastArgument --;
+ return 0;
+ }
+ }
+ else
+ {
+ // Handle unknown arguments
+ if ( this->Internals->UnknownArgumentCallback )
+ {
+ if ( !this->Internals->UnknownArgumentCallback(arg.c_str(),
+ this->Internals->ClientData) )
+ {
+ this->Internals->LastArgument --;
+ return 0;
+ }
+ return 1;
+ }
+ else if ( this->StoreUnusedArgumentsFlag )
+ {
+ CommandLineArguments_DEBUG("Store unused argument " << arg);
+ this->Internals->UnusedArguments.push_back(arg.c_str());
+ }
+ else
+ {
+ kwsys_ios::cerr << "Got unknown argument: \"" << arg.c_str() << "\"" << kwsys_ios::endl;
+ this->Internals->LastArgument --;
+ return 0;
+ }
+ }
+ }
+ return 1;
+}
+
+//----------------------------------------------------------------------------
+void CommandLineArguments::GetRemainingArguments(int* argc, char*** argv)
+{
+ CommandLineArguments::Internal::VectorOfStrings::size_type size
+ = this->Internals->Argv.size() - this->Internals->LastArgument + 1;
+ CommandLineArguments::Internal::VectorOfStrings::size_type cc;
+
+ // Copy Argv0 as the first argument
+ char** args = new char*[ size ];
+ args[0] = new char[ this->Internals->Argv0.size() + 1 ];
+ strcpy(args[0], this->Internals->Argv0.c_str());
+ int cnt = 1;
+
+ // Copy everything after the LastArgument, since that was not parsed.
+ for ( cc = this->Internals->LastArgument+1;
+ cc < this->Internals->Argv.size(); cc ++ )
+ {
+ args[cnt] = new char[ this->Internals->Argv[cc].size() + 1];
+ strcpy(args[cnt], this->Internals->Argv[cc].c_str());
+ cnt ++;
+ }
+ *argc = cnt;
+ *argv = args;
+}
+
+//----------------------------------------------------------------------------
+void CommandLineArguments::GetUnusedArguments(int* argc, char*** argv)
+{
+ CommandLineArguments::Internal::VectorOfStrings::size_type size
+ = this->Internals->UnusedArguments.size() + 1;
+ CommandLineArguments::Internal::VectorOfStrings::size_type cc;
+
+ // Copy Argv0 as the first argument
+ char** args = new char*[ size ];
+ args[0] = new char[ this->Internals->Argv0.size() + 1 ];
+ strcpy(args[0], this->Internals->Argv0.c_str());
+ int cnt = 1;
+
+ // Copy everything after the LastArgument, since that was not parsed.
+ for ( cc = 0;
+ cc < this->Internals->UnusedArguments.size(); cc ++ )
+ {
+ kwsys::String &str = this->Internals->UnusedArguments[cc];
+ args[cnt] = new char[ str.size() + 1];
+ strcpy(args[cnt], str.c_str());
+ cnt ++;
+ }
+ *argc = cnt;
+ *argv = args;
+}
+
+//----------------------------------------------------------------------------
+void CommandLineArguments::DeleteRemainingArguments(int argc, char*** argv)
+{
+ int cc;
+ for ( cc = 0; cc < argc; ++ cc )
+ {
+ delete [] (*argv)[cc];
+ }
+ delete [] *argv;
+}
+
+//----------------------------------------------------------------------------
+void CommandLineArguments::AddCallback(const char* argument, ArgumentTypeEnum type,
+ CallbackType callback, void* call_data, const char* help)
+{
+ CommandLineArgumentsCallbackStructure s;
+ s.Argument = argument;
+ s.ArgumentType = type;
+ s.Callback = callback;
+ s.CallData = call_data;
+ s.VariableType = CommandLineArguments::NO_VARIABLE_TYPE;
+ s.Variable = 0;
+ s.Help = help;
+
+ this->Internals->Callbacks[argument] = s;
+ this->GenerateHelp();
+}
+
+//----------------------------------------------------------------------------
+void CommandLineArguments::AddArgument(const char* argument, ArgumentTypeEnum type,
+ VariableTypeEnum vtype, void* variable, const char* help)
+{
+ CommandLineArgumentsCallbackStructure s;
+ s.Argument = argument;
+ s.ArgumentType = type;
+ s.Callback = 0;
+ s.CallData = 0;
+ s.VariableType = vtype;
+ s.Variable = variable;
+ s.Help = help;
+
+ this->Internals->Callbacks[argument] = s;
+ this->GenerateHelp();
+}
+
+//----------------------------------------------------------------------------
+#define CommandLineArgumentsAddArgumentMacro(type, ctype) \
+ void CommandLineArguments::AddArgument(const char* argument, ArgumentTypeEnum type, \
+ ctype* variable, const char* help) \
+ { \
+ this->AddArgument(argument, type, CommandLineArguments::type##_TYPE, variable, help); \
+ }
+
+CommandLineArgumentsAddArgumentMacro(BOOL, bool)
+CommandLineArgumentsAddArgumentMacro(INT, int)
+CommandLineArgumentsAddArgumentMacro(DOUBLE, double)
+CommandLineArgumentsAddArgumentMacro(STRING, char*)
+CommandLineArgumentsAddArgumentMacro(STL_STRING, kwsys_stl::string)
+
+CommandLineArgumentsAddArgumentMacro(VECTOR_BOOL, kwsys_stl::vector<bool>)
+CommandLineArgumentsAddArgumentMacro(VECTOR_INT, kwsys_stl::vector<int>)
+CommandLineArgumentsAddArgumentMacro(VECTOR_DOUBLE, kwsys_stl::vector<double>)
+CommandLineArgumentsAddArgumentMacro(VECTOR_STRING, kwsys_stl::vector<char*>)
+CommandLineArgumentsAddArgumentMacro(VECTOR_STL_STRING, kwsys_stl::vector<kwsys_stl::string>)
+
+//----------------------------------------------------------------------------
+#define CommandLineArgumentsAddBooleanArgumentMacro(type, ctype) \
+ void CommandLineArguments::AddBooleanArgument(const char* argument, \
+ ctype* variable, const char* help) \
+ { \
+ this->AddArgument(argument, CommandLineArguments::NO_ARGUMENT, \
+ CommandLineArguments::type##_TYPE, variable, help); \
+ }
+
+CommandLineArgumentsAddBooleanArgumentMacro(BOOL, bool)
+CommandLineArgumentsAddBooleanArgumentMacro(INT, int)
+CommandLineArgumentsAddBooleanArgumentMacro(DOUBLE, double)
+CommandLineArgumentsAddBooleanArgumentMacro(STRING, char*)
+CommandLineArgumentsAddBooleanArgumentMacro(STL_STRING, kwsys_stl::string)
+
+//----------------------------------------------------------------------------
+void CommandLineArguments::SetClientData(void* client_data)
+{
+ this->Internals->ClientData = client_data;
+}
+
+//----------------------------------------------------------------------------
+void CommandLineArguments::SetUnknownArgumentCallback(
+ CommandLineArguments::ErrorCallbackType callback)
+{
+ this->Internals->UnknownArgumentCallback = callback;
+}
+
+//----------------------------------------------------------------------------
+const char* CommandLineArguments::GetHelp(const char* arg)
+{
+ CommandLineArguments::Internal::CallbacksMap::iterator it
+ = this->Internals->Callbacks.find(arg);
+ if ( it == this->Internals->Callbacks.end() )
+ {
+ return 0;
+ }
+
+ // Since several arguments may point to the same argument, find the one this
+ // one point to if this one is pointing to another argument.
+ CommandLineArgumentsCallbackStructure *cs = &(it->second);
+ for(;;)
+ {
+ CommandLineArguments::Internal::CallbacksMap::iterator hit
+ = this->Internals->Callbacks.find(cs->Help);
+ if ( hit == this->Internals->Callbacks.end() )
+ {
+ break;
+ }
+ cs = &(hit->second);
+ }
+ return cs->Help;
+}
+
+//----------------------------------------------------------------------------
+void CommandLineArguments::SetLineLength(unsigned int ll)
+{
+ if ( ll < 9 || ll > 1000 )
+ {
+ return;
+ }
+ this->LineLength = ll;
+ this->GenerateHelp();
+}
+
+//----------------------------------------------------------------------------
+const char* CommandLineArguments::GetArgv0()
+{
+ return this->Internals->Argv0.c_str();
+}
+
+//----------------------------------------------------------------------------
+unsigned int CommandLineArguments::GetLastArgument()
+{
+ return static_cast<unsigned int>(this->Internals->LastArgument + 1);
+}
+
+//----------------------------------------------------------------------------
+void CommandLineArguments::GenerateHelp()
+{
+ kwsys_ios::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,
+ CommandLineArguments::Internal::SetOfStrings > MapArgs;
+ MapArgs mp;
+ MapArgs::iterator mpit, smpit;
+ for ( it = this->Internals->Callbacks.begin();
+ it != this->Internals->Callbacks.end();
+ it ++ )
+ {
+ CommandLineArgumentsCallbackStructure *cs = &(it->second);
+ mpit = mp.find(cs->Help);
+ if ( mpit != mp.end() )
+ {
+ mpit->second.insert(it->first);
+ mp[it->first].insert(it->first);
+ }
+ else
+ {
+ mp[it->first].insert(it->first);
+ }
+ }
+ for ( it = this->Internals->Callbacks.begin();
+ it != this->Internals->Callbacks.end();
+ it ++ )
+ {
+ CommandLineArgumentsCallbackStructure *cs = &(it->second);
+ mpit = mp.find(cs->Help);
+ if ( mpit != mp.end() )
+ {
+ mpit->second.insert(it->first);
+ smpit = mp.find(it->first);
+ CommandLineArguments::Internal::SetOfStrings::iterator sit;
+ for ( sit = smpit->second.begin(); sit != smpit->second.end(); sit++ )
+ {
+ mpit->second.insert(*sit);
+ }
+ mp.erase(smpit);
+ }
+ else
+ {
+ mp[it->first].insert(it->first);
+ }
+ }
+
+ // Find the length of the longest string
+ CommandLineArguments::Internal::String::size_type maxlen = 0;
+ for ( mpit = mp.begin();
+ mpit != mp.end();
+ mpit ++ )
+ {
+ CommandLineArguments::Internal::SetOfStrings::iterator sit;
+ for ( sit = mpit->second.begin(); sit != mpit->second.end(); sit++ )
+ {
+ CommandLineArguments::Internal::String::size_type clen = sit->size();
+ switch ( this->Internals->Callbacks[*sit].ArgumentType )
+ {
+ case CommandLineArguments::NO_ARGUMENT: clen += 0; break;
+ case CommandLineArguments::CONCAT_ARGUMENT: clen += 3; break;
+ case CommandLineArguments::SPACE_ARGUMENT: clen += 4; break;
+ case CommandLineArguments::EQUAL_ARGUMENT: clen += 4; break;
+ }
+ if ( clen > maxlen )
+ {
+ maxlen = clen;
+ }
+ }
+ }
+
+ // Create format for that string
+ char format[80];
+ sprintf(format, " %%-%us ", static_cast<unsigned int>(maxlen));
+
+ maxlen += 4; // For the space before and after the option
+
+ // Print help for each option
+ for ( mpit = mp.begin();
+ mpit != mp.end();
+ mpit ++ )
+ {
+ CommandLineArguments::Internal::SetOfStrings::iterator sit;
+ for ( sit = mpit->second.begin(); sit != mpit->second.end(); sit++ )
+ {
+ str << kwsys_ios::endl;
+ char argument[100];
+ sprintf(argument, "%s", sit->c_str());
+ switch ( this->Internals->Callbacks[*sit].ArgumentType )
+ {
+ case CommandLineArguments::NO_ARGUMENT: break;
+ case CommandLineArguments::CONCAT_ARGUMENT: strcat(argument, "opt"); break;
+ case CommandLineArguments::SPACE_ARGUMENT: strcat(argument, " opt"); break;
+ case CommandLineArguments::EQUAL_ARGUMENT: strcat(argument, "=opt"); break;
+ case CommandLineArguments::MULTI_ARGUMENT: strcat(argument, " opt opt ..."); break;
+ }
+ char buffer[80];
+ sprintf(buffer, format, argument);
+ str << buffer;
+ }
+ const char* ptr = this->Internals->Callbacks[mpit->first].Help;
+ size_t len = strlen(ptr);
+ int cnt = 0;
+ while ( len > 0)
+ {
+ // If argument with help is longer than line length, split it on previous
+ // space (or tab) and continue on the next line
+ CommandLineArguments::Internal::String::size_type cc;
+ for ( cc = 0; ptr[cc]; cc ++ )
+ {
+ if ( *ptr == ' ' || *ptr == '\t' )
+ {
+ ptr ++;
+ len --;
+ }
+ }
+ if ( cnt > 0 )
+ {
+ for ( cc = 0; cc < maxlen; cc ++ )
+ {
+ str << " ";
+ }
+ }
+ CommandLineArguments::Internal::String::size_type skip = len;
+ if ( skip > this->LineLength - maxlen )
+ {
+ skip = this->LineLength - maxlen;
+ for ( cc = skip-1; cc > 0; cc -- )
+ {
+ if ( ptr[cc] == ' ' || ptr[cc] == '\t' )
+ {
+ break;
+ }
+ }
+ if ( cc != 0 )
+ {
+ skip = cc;
+ }
+ }
+ str.write(ptr, static_cast<kwsys_ios::streamsize>(skip));
+ str << kwsys_ios::endl;
+ ptr += skip;
+ len -= skip;
+ cnt ++;
+ }
+ }
+ /*
+ // This can help debugging help string
+ str << endl;
+ unsigned int cc;
+ for ( cc = 0; cc < this->LineLength; cc ++ )
+ {
+ str << cc % 10;
+ }
+ str << endl;
+ */
+ this->Help = str.str();
+}
+
+//----------------------------------------------------------------------------
+void CommandLineArguments::PopulateVariable(
+ bool* variable, const kwsys_stl::string& value)
+{
+ if ( value == "1" || value == "ON" || value == "on" || value == "On" ||
+ value == "TRUE" || value == "true" || value == "True" ||
+ value == "yes" || value == "Yes" || value == "YES" )
+ {
+ *variable = true;
+ }
+ else
+ {
+ *variable = false;
+ }
+}
+
+//----------------------------------------------------------------------------
+void CommandLineArguments::PopulateVariable(
+ int* variable, const kwsys_stl::string& value)
+{
+ char* res = 0;
+ *variable = static_cast<int>(strtol(value.c_str(), &res, 10));
+ //if ( res && *res )
+ // {
+ // Can handle non-int
+ // }
+}
+
+//----------------------------------------------------------------------------
+void CommandLineArguments::PopulateVariable(
+ double* variable, const kwsys_stl::string& value)
+{
+ char* res = 0;
+ *variable = strtod(value.c_str(), &res);
+ //if ( res && *res )
+ // {
+ // Can handle non-double
+ // }
+}
+
+//----------------------------------------------------------------------------
+void CommandLineArguments::PopulateVariable(
+ char** variable, const kwsys_stl::string& value)
+{
+ if ( *variable )
+ {
+ delete [] *variable;
+ *variable = 0;
+ }
+ *variable = new char[ value.size() + 1 ];
+ strcpy(*variable, value.c_str());
+}
+
+//----------------------------------------------------------------------------
+void CommandLineArguments::PopulateVariable(
+ kwsys_stl::string* variable, const kwsys_stl::string& value)
+{
+ *variable = value;
+}
+
+//----------------------------------------------------------------------------
+void CommandLineArguments::PopulateVariable(
+ kwsys_stl::vector<bool>* variable, const kwsys_stl::string& value)
+{
+ bool val = false;
+ if ( value == "1" || value == "ON" || value == "on" || value == "On" ||
+ value == "TRUE" || value == "true" || value == "True" ||
+ value == "yes" || value == "Yes" || value == "YES" )
+ {
+ val = true;
+ }
+ variable->push_back(val);
+}
+
+//----------------------------------------------------------------------------
+void CommandLineArguments::PopulateVariable(
+ kwsys_stl::vector<int>* variable, const kwsys_stl::string& value)
+{
+ char* res = 0;
+ variable->push_back(static_cast<int>(strtol(value.c_str(), &res, 10)));
+ //if ( res && *res )
+ // {
+ // Can handle non-int
+ // }
+}
+
+//----------------------------------------------------------------------------
+void CommandLineArguments::PopulateVariable(
+ kwsys_stl::vector<double>* variable, const kwsys_stl::string& value)
+{
+ char* res = 0;
+ variable->push_back(strtod(value.c_str(), &res));
+ //if ( res && *res )
+ // {
+ // Can handle non-int
+ // }
+}
+
+//----------------------------------------------------------------------------
+void CommandLineArguments::PopulateVariable(
+ kwsys_stl::vector<char*>* variable, const kwsys_stl::string& value)
+{
+ char* var = new char[ value.size() + 1 ];
+ strcpy(var, value.c_str());
+ variable->push_back(var);
+}
+
+//----------------------------------------------------------------------------
+void CommandLineArguments::PopulateVariable(
+ kwsys_stl::vector<kwsys_stl::string>* variable,
+ const kwsys_stl::string& value)
+{
+ variable->push_back(value);
+}
+
+//----------------------------------------------------------------------------
+bool CommandLineArguments::PopulateVariable(CommandLineArgumentsCallbackStructure* cs,
+ const char* value)
+{
+ // Call the callback
+ if ( cs->Callback )
+ {
+ if ( !cs->Callback(cs->Argument, value, cs->CallData) )
+ {
+ this->Internals->LastArgument --;
+ return 0;
+ }
+ }
+ CommandLineArguments_DEBUG("Set argument: " << cs->Argument << " to " << value);
+ if ( cs->Variable )
+ {
+ kwsys_stl::string var = "1";
+ if ( value )
+ {
+ var = value;
+ }
+ switch ( cs->VariableType )
+ {
+ case CommandLineArguments::INT_TYPE:
+ this->PopulateVariable(static_cast<int*>(cs->Variable), var);
+ break;
+ case CommandLineArguments::DOUBLE_TYPE:
+ this->PopulateVariable(static_cast<double*>(cs->Variable), var);
+ break;
+ case CommandLineArguments::STRING_TYPE:
+ this->PopulateVariable(static_cast<char**>(cs->Variable), var);
+ break;
+ case CommandLineArguments::STL_STRING_TYPE:
+ this->PopulateVariable(static_cast<kwsys_stl::string*>(cs->Variable), var);
+ break;
+ case CommandLineArguments::BOOL_TYPE:
+ this->PopulateVariable(static_cast<bool*>(cs->Variable), var);
+ break;
+ case CommandLineArguments::VECTOR_BOOL_TYPE:
+ this->PopulateVariable(static_cast<kwsys_stl::vector<bool>*>(cs->Variable), var);
+ break;
+ case CommandLineArguments::VECTOR_INT_TYPE:
+ this->PopulateVariable(static_cast<kwsys_stl::vector<int>*>(cs->Variable), var);
+ break;
+ case CommandLineArguments::VECTOR_DOUBLE_TYPE:
+ this->PopulateVariable(static_cast<kwsys_stl::vector<double>*>(cs->Variable), var);
+ break;
+ case CommandLineArguments::VECTOR_STRING_TYPE:
+ this->PopulateVariable(static_cast<kwsys_stl::vector<char*>*>(cs->Variable), var);
+ break;
+ case CommandLineArguments::VECTOR_STL_STRING_TYPE:
+ this->PopulateVariable(static_cast<kwsys_stl::vector<kwsys_stl::string>*>(cs->Variable), var);
+ break;
+ default:
+ kwsys_ios::cerr << "Got unknown variable type: \"" << cs->VariableType << "\"" << kwsys_ios::endl;
+ this->Internals->LastArgument --;
+ return 0;
+ }
+ }
+ return 1;
+}
+
+
+} // namespace KWSYS_NAMESPACE
diff --git a/Source/kwsys/CommandLineArguments.hxx.in b/Source/kwsys/CommandLineArguments.hxx.in
new file mode 100644
index 000000000..68e9600ef
--- /dev/null
+++ b/Source/kwsys/CommandLineArguments.hxx.in
@@ -0,0 +1,286 @@
+/*============================================================================
+ 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@_CommandLineArguments_hxx
+#define @KWSYS_NAMESPACE@_CommandLineArguments_hxx
+
+#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
+
+namespace @KWSYS_NAMESPACE@
+{
+
+class CommandLineArgumentsInternal;
+struct CommandLineArgumentsCallbackStructure;
+
+/** \class CommandLineArguments
+ * \brief Command line arguments processing code.
+ *
+ * Find specified arguments with optional options and execute specified methods
+ * or set given variables.
+ *
+ * The two interfaces it knows are callback based and variable based. For
+ * callback based, you have to register callback for particular argument using
+ * AddCallback method. When that argument is passed, the callback will be
+ * called with argument, value, and call data. For boolean (NO_ARGUMENT)
+ * arguments, the value is "1". If the callback returns 0 the argument parsing
+ * will stop with an error.
+ *
+ * For the variable interface you associate variable with each argument. When
+ * the argument is specified, the variable is set to the specified value casted
+ * to the apropriate type. For boolean (NO_ARGUMENT), the value is "1".
+ *
+ * Both interfaces can be used at the same time.
+ *
+ * Possible argument types are:
+ * NO_ARGUMENT - The argument takes no value : --A
+ * CONCAT_ARGUMENT - The argument takes value after no space : --Aval
+ * SPACE_ARGUMENT - The argument takes value after space : --A val
+ * EQUAL_ARGUMENT - The argument takes value after equal : --A=val
+ * MULTI_ARGUMENT - The argument takes values after space : --A val1 val2 val3 ...
+ *
+ * Example use:
+ *
+ * kwsys::CommandLineArguments arg;
+ * arg.Initialize(argc, argv);
+ * typedef kwsys::CommandLineArguments argT;
+ * arg.AddArgument("--something", argT::EQUAL_ARGUMENT, &some_variable,
+ * "This is help string for --something");
+ * if ( !arg.Parse() )
+ * {
+ * kwsys_ios::cerr << "Problem parsing arguments" << kwsys_ios::endl;
+ * res = 1;
+ * }
+ *
+ */
+
+class @KWSYS_NAMESPACE@_EXPORT CommandLineArguments
+{
+public:
+ CommandLineArguments();
+ ~CommandLineArguments();
+
+ /**
+ * Various argument types.
+ */
+ enum ArgumentTypeEnum {
+ NO_ARGUMENT,
+ CONCAT_ARGUMENT,
+ SPACE_ARGUMENT,
+ EQUAL_ARGUMENT,
+ MULTI_ARGUMENT
+ };
+
+ /**
+ * Various variable types. When using the variable interface, this specifies
+ * what type the variable is.
+ */
+ enum VariableTypeEnum {
+ NO_VARIABLE_TYPE = 0, // The variable is not specified
+ INT_TYPE, // The variable is integer (int)
+ BOOL_TYPE, // The variable is boolean (bool)
+ DOUBLE_TYPE, // The variable is float (double)
+ STRING_TYPE, // The variable is string (char*)
+ STL_STRING_TYPE, // The variable is string (char*)
+ VECTOR_INT_TYPE, // The variable is integer (int)
+ VECTOR_BOOL_TYPE, // The vairable is boolean (bool)
+ VECTOR_DOUBLE_TYPE, // The variable is float (double)
+ VECTOR_STRING_TYPE, // The variable is string (char*)
+ VECTOR_STL_STRING_TYPE, // The variable is string (char*)
+ LAST_VARIABLE_TYPE
+ };
+
+ /**
+ * Prototypes for callbacks for callback interface.
+ */
+ typedef int(*CallbackType)(const char* argument, const char* value,
+ void* call_data);
+ typedef int(*ErrorCallbackType)(const char* argument, void* client_data);
+
+ /**
+ * Initialize internal data structures. This should be called before parsing.
+ */
+ void Initialize(int argc, const char* const argv[]);
+ void Initialize(int argc, char* argv[]);
+
+ /**
+ * Initialize internal data structure and pass arguments one by one. This is
+ * convenience method for use from scripting languages where argc and argv
+ * are not available.
+ */
+ void Initialize();
+ void ProcessArgument(const char* arg);
+
+ /**
+ * This method will parse arguments and call apropriate methods.
+ */
+ int Parse();
+
+ /**
+ * This method will add a callback for a specific argument. The arguments to
+ * it are argument, argument type, callback method, and call data. The
+ * argument help specifies the help string used with this option. The
+ * callback and call_data can be skipped.
+ */
+ void AddCallback(const char* argument, ArgumentTypeEnum type,
+ CallbackType callback, void* call_data, const char* help);
+
+ /**
+ * Add handler for argument which is going to set the variable to the
+ * specified value. If the argument is specified, the option is casted to the
+ * apropriate type.
+ */
+ void AddArgument(const char* argument, ArgumentTypeEnum type,
+ bool* variable, const char* help);
+ void AddArgument(const char* argument, ArgumentTypeEnum type,
+ int* variable, const char* help);
+ void AddArgument(const char* argument, ArgumentTypeEnum type,
+ double* variable, const char* help);
+ void AddArgument(const char* argument, ArgumentTypeEnum type,
+ char** variable, const char* help);
+ void AddArgument(const char* argument, ArgumentTypeEnum type,
+ kwsys_stl::string* variable, const char* help);
+
+ /**
+ * Add handler for argument which is going to set the variable to the
+ * specified value. If the argument is specified, the option is casted to the
+ * apropriate type. This will handle the multi argument values.
+ */
+ void AddArgument(const char* argument, ArgumentTypeEnum type,
+ kwsys_stl::vector<bool>* variable, const char* help);
+ void AddArgument(const char* argument, ArgumentTypeEnum type,
+ kwsys_stl::vector<int>* variable, const char* help);
+ void AddArgument(const char* argument, ArgumentTypeEnum type,
+ kwsys_stl::vector<double>* variable, const char* help);
+ void AddArgument(const char* argument, ArgumentTypeEnum type,
+ kwsys_stl::vector<char*>* variable, const char* help);
+ void AddArgument(const char* argument, ArgumentTypeEnum type,
+ kwsys_stl::vector<kwsys_stl::string>* variable, const char* help);
+
+ /**
+ * Add handler for boolean argument. The argument does not take any option
+ * and if it is specified, the value of the variable is true/1, otherwise it
+ * is false/0.
+ */
+ void AddBooleanArgument(const char* argument,
+ bool* variable, const char* help);
+ void AddBooleanArgument(const char* argument,
+ int* variable, const char* help);
+ void AddBooleanArgument(const char* argument,
+ double* variable, const char* help);
+ void AddBooleanArgument(const char* argument,
+ char** variable, const char* help);
+ void AddBooleanArgument(const char* argument,
+ kwsys_stl::string* variable, const char* help);
+
+ /**
+ * Set the callbacks for error handling.
+ */
+ void SetClientData(void* client_data);
+ void SetUnknownArgumentCallback(ErrorCallbackType callback);
+
+ /**
+ * Get remaining arguments. It allocates space for argv, so you have to call
+ * delete[] on it.
+ */
+ void GetRemainingArguments(int* argc, char*** argv);
+ void DeleteRemainingArguments(int argc, char*** argv);
+
+ /**
+ * If StoreUnusedArguments is set to true, then all unknown arguments will be
+ * stored and the user can access the modified argc, argv without known
+ * arguments.
+ */
+ void StoreUnusedArguments(bool val) { this->StoreUnusedArgumentsFlag = val; }
+ void GetUnusedArguments(int* argc, char*** argv);
+
+ /**
+ * Return string containing help. If the argument is specified, only return
+ * help for that argument.
+ */
+ const char* GetHelp() { return this->Help.c_str(); }
+ const char* GetHelp(const char* arg);
+
+ /**
+ * Get / Set the help line length. This length is used when generating the
+ * help page. Default length is 80.
+ */
+ void SetLineLength(unsigned int);
+ unsigned int GetLineLength();
+
+ /**
+ * Get the executable name (argv0). This is only available when using
+ * Initialize with argc/argv.
+ */
+ const char* GetArgv0();
+
+ /**
+ * Get index of the last argument parsed. This is the last argument that was
+ * parsed ok in the original argc/argv list.
+ */
+ unsigned int GetLastArgument();
+
+protected:
+ void GenerateHelp();
+
+ //! This is internal method that registers variable with argument
+ void AddArgument(const char* argument, ArgumentTypeEnum type,
+ VariableTypeEnum vtype, void* variable, const char* help);
+
+ bool GetMatchedArguments(kwsys_stl::vector<kwsys_stl::string>* matches,
+ const kwsys_stl::string& arg);
+
+ //! Populate individual variables
+ bool PopulateVariable(CommandLineArgumentsCallbackStructure* cs,
+ const char* value);
+
+ //! Populate individual variables of type ...
+ void PopulateVariable(bool* variable, const kwsys_stl::string& value);
+ void PopulateVariable(int* variable, const kwsys_stl::string& value);
+ void PopulateVariable(double* variable, const kwsys_stl::string& value);
+ void PopulateVariable(char** variable, const kwsys_stl::string& value);
+ void PopulateVariable(kwsys_stl::string* variable, const kwsys_stl::string& value);
+ void PopulateVariable(kwsys_stl::vector<bool>* variable, const kwsys_stl::string& value);
+ void PopulateVariable(kwsys_stl::vector<int>* variable, const kwsys_stl::string& value);
+ void PopulateVariable(kwsys_stl::vector<double>* variable, const kwsys_stl::string& value);
+ void PopulateVariable(kwsys_stl::vector<char*>* variable, const kwsys_stl::string& value);
+ void PopulateVariable(kwsys_stl::vector<kwsys_stl::string>* variable, const kwsys_stl::string& value);
+
+ typedef CommandLineArgumentsInternal Internal;
+ Internal* Internals;
+ kwsys_stl::string Help;
+
+ unsigned int LineLength;
+
+ bool StoreUnusedArgumentsFlag;
+};
+
+} // namespace @KWSYS_NAMESPACE@
+
+/* 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
new file mode 100644
index 000000000..15986cfea
--- /dev/null
+++ b/Source/kwsys/Configure.h.in
@@ -0,0 +1,145 @@
+/*============================================================================
+ 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@_Configure_h
+#define @KWSYS_NAMESPACE@_Configure_h
+
+/* If we are building a kwsys .c or .cxx file, let it use the kwsys
+ namespace. When not building a kwsys source file these macros are
+ temporarily defined inside the headers that use them. */
+#if defined(KWSYS_NAMESPACE)
+# define kwsys_ns(x) @KWSYS_NAMESPACE@##x
+# define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT
+#endif
+
+/* Disable some warnings inside kwsys source files. */
+#if defined(KWSYS_NAMESPACE)
+# if defined(__BORLANDC__)
+# pragma warn -8027 /* function not inlined. */
+# endif
+# if defined(__INTEL_COMPILER)
+# pragma warning (disable: 1572) /* floating-point equality test */
+# endif
+# if defined(__sgi) && !defined(__GNUC__)
+# pragma set woff 3970 /* pointer to int conversion */
+# pragma set woff 3968 /* 64 bit conversion */
+# endif
+#endif
+
+/* Whether kwsys namespace is "kwsys". */
+#define @KWSYS_NAMESPACE@_NAME_IS_KWSYS @KWSYS_NAME_IS_KWSYS@
+
+/* If we are building a kwsys .c or .cxx file, suppress the Microsoft
+ deprecation warnings. */
+#if defined(KWSYS_NAMESPACE)
+# ifndef _CRT_NONSTDC_NO_DEPRECATE
+# define _CRT_NONSTDC_NO_DEPRECATE
+# endif
+# ifndef _CRT_SECURE_NO_DEPRECATE
+# define _CRT_SECURE_NO_DEPRECATE
+# endif
+# ifndef _SCL_SECURE_NO_DEPRECATE
+# define _SCL_SECURE_NO_DEPRECATE
+# endif
+#endif
+
+/* Whether Large File Support is requested. */
+#define @KWSYS_NAMESPACE@_LFS_REQUESTED @KWSYS_LFS_REQUESTED@
+
+/* Whether Large File Support is available. */
+#if @KWSYS_NAMESPACE@_LFS_REQUESTED
+# define @KWSYS_NAMESPACE@_LFS_AVAILABLE @KWSYS_LFS_AVAILABLE@
+#endif
+
+/* Setup Large File Support if requested. */
+#if @KWSYS_NAMESPACE@_LFS_REQUESTED
+ /* Since LFS is requested this header must be included before system
+ headers whether or not LFS is available. */
+# if 0 && (defined(_SYS_TYPES_H) || defined(_SYS_TYPES_INCLUDED))
+# error "@KWSYS_NAMESPACE@/Configure.h must be included before sys/types.h"
+# endif
+ /* Enable the large file API if it is available. */
+# if @KWSYS_NAMESPACE@_LFS_AVAILABLE && \
+ !defined(@KWSYS_NAMESPACE@_LFS_NO_DEFINES)
+# if !defined(_LARGEFILE_SOURCE) && \
+ !defined(@KWSYS_NAMESPACE@_LFS_NO_DEFINE_LARGEFILE_SOURCE)
+# define _LARGEFILE_SOURCE
+# endif
+# if !defined(_LARGEFILE64_SOURCE) && \
+ !defined(@KWSYS_NAMESPACE@_LFS_NO_DEFINE_LARGEFILE64_SOURCE)
+# define _LARGEFILE64_SOURCE
+# endif
+# if !defined(_LARGE_FILES) && \
+ !defined(@KWSYS_NAMESPACE@_LFS_NO_DEFINE_LARGE_FILES)
+# define _LARGE_FILES
+# endif
+# if !defined(_FILE_OFFSET_BITS) && \
+ !defined(@KWSYS_NAMESPACE@_LFS_NO_DEFINE_FILE_OFFSET_BITS)
+# define _FILE_OFFSET_BITS 64
+# endif
+# if 0 && (defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS < 64)
+# error "_FILE_OFFSET_BITS must be defined to at least 64"
+# endif
+# endif
+#endif
+
+/* Setup the export macro. */
+#if @KWSYS_BUILD_SHARED@
+# if defined(_WIN32) || defined(__CYGWIN__)
+# if defined(@KWSYS_NAMESPACE@_EXPORTS)
+# define @KWSYS_NAMESPACE@_EXPORT __declspec(dllexport)
+# else
+# define @KWSYS_NAMESPACE@_EXPORT __declspec(dllimport)
+# endif
+# elif __GNUC__ >= 4
+# define @KWSYS_NAMESPACE@_EXPORT __attribute__ ((visibility("default")))
+# else
+# define @KWSYS_NAMESPACE@_EXPORT
+# endif
+#else
+# define @KWSYS_NAMESPACE@_EXPORT
+#endif
+
+/* Enable warnings that are off by default but are useful. */
+#if !defined(@KWSYS_NAMESPACE@_NO_WARNING_ENABLE)
+# if defined(_MSC_VER)
+# pragma warning ( default : 4263 ) /* no override, call convention differs */
+# endif
+#endif
+
+/* Disable warnings that are on by default but occur in valid code. */
+#if !defined(@KWSYS_NAMESPACE@_NO_WARNING_DISABLE)
+# if defined(_MSC_VER)
+# pragma warning (disable: 4097) /* typedef is synonym for class */
+# pragma warning (disable: 4127) /* conditional expression is constant */
+# pragma warning (disable: 4244) /* possible loss in conversion */
+# pragma warning (disable: 4251) /* missing DLL-interface */
+# pragma warning (disable: 4305) /* truncation from type1 to type2 */
+# pragma warning (disable: 4309) /* truncation of constant value */
+# pragma warning (disable: 4514) /* unreferenced inline function */
+# pragma warning (disable: 4706) /* assignment in conditional expression */
+# pragma warning (disable: 4710) /* function not inlined */
+# pragma warning (disable: 4786) /* identifier truncated in debug info */
+# endif
+#endif
+
+/* MSVC 6.0 in release mode will warn about code it produces with its
+ optimizer. Disable the warnings specifically for this
+ configuration. Real warnings will be revealed by a debug build or
+ by other compilers. */
+#if !defined(@KWSYS_NAMESPACE@_NO_WARNING_DISABLE_BOGUS)
+# if defined(_MSC_VER) && (_MSC_VER < 1300) && defined(NDEBUG)
+# pragma warning ( disable : 4701 ) /* Variable may be used uninitialized. */
+# pragma warning ( disable : 4702 ) /* Unreachable code. */
+# endif
+#endif
+
+#endif
diff --git a/Source/kwsys/Configure.hxx.in b/Source/kwsys/Configure.hxx.in
new file mode 100644
index 000000000..716b84f09
--- /dev/null
+++ b/Source/kwsys/Configure.hxx.in
@@ -0,0 +1,175 @@
+/*============================================================================
+ 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@_Configure_hxx
+#define @KWSYS_NAMESPACE@_Configure_hxx
+
+/* 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@
+
+/* 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
+#endif
+
+#endif
diff --git a/Source/kwsys/Copyright.txt b/Source/kwsys/Copyright.txt
new file mode 100644
index 000000000..1549a7d5f
--- /dev/null
+++ b/Source/kwsys/Copyright.txt
@@ -0,0 +1,31 @@
+KWSys - Kitware System Library
+Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+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 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.
+
+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.
diff --git a/Source/kwsys/Directory.cxx b/Source/kwsys/Directory.cxx
new file mode 100644
index 000000000..b88474781
--- /dev/null
+++ b/Source/kwsys/Directory.cxx
@@ -0,0 +1,250 @@
+/*============================================================================
+ 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(Directory.hxx)
+
+#include KWSYS_HEADER(Configure.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.
+#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"
+#endif
+
+namespace KWSYS_NAMESPACE
+{
+
+//----------------------------------------------------------------------------
+class DirectoryInternals
+{
+public:
+ // Array of Files
+ kwsys_stl::vector<kwsys_stl::string> Files;
+
+ // Path to Open'ed directory
+ kwsys_stl::string Path;
+};
+
+//----------------------------------------------------------------------------
+Directory::Directory()
+{
+ this->Internal = new DirectoryInternals;
+}
+
+//----------------------------------------------------------------------------
+Directory::~Directory()
+{
+ delete this->Internal;
+}
+
+//----------------------------------------------------------------------------
+unsigned long Directory::GetNumberOfFiles() const
+{
+ return static_cast<unsigned long>(this->Internal->Files.size());
+}
+
+//----------------------------------------------------------------------------
+const char* Directory::GetFile(unsigned long dindex) const
+{
+ if ( dindex >= this->Internal->Files.size() )
+ {
+ return 0;
+ }
+ return this->Internal->Files[dindex].c_str();
+}
+
+//----------------------------------------------------------------------------
+const char* Directory::GetPath() const
+{
+ return this->Internal->Path.c_str();
+}
+
+//----------------------------------------------------------------------------
+void Directory::Clear()
+{
+ this->Internal->Path.resize(0);
+ this->Internal->Files.clear();
+}
+
+} // namespace KWSYS_NAMESPACE
+
+// First microsoft compilers
+
+#if defined(_MSC_VER) || defined(__WATCOMC__)
+#include <windows.h>
+#include <io.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+namespace KWSYS_NAMESPACE
+{
+
+bool Directory::Load(const char* name)
+{
+ this->Clear();
+#if _MSC_VER < 1300
+ long srchHandle;
+#else
+ intptr_t srchHandle;
+#endif
+ char* buf;
+ size_t n = strlen(name);
+ if ( name[n - 1] == '/' )
+ {
+ buf = new char[n + 1 + 1];
+ sprintf(buf, "%s*", name);
+ }
+ else
+ {
+ buf = new char[n + 2 + 1];
+ sprintf(buf, "%s/*", name);
+ }
+ struct _finddata_t data; // data of current file
+
+ // Now put them into the file array
+ srchHandle = _findfirst(buf, &data);
+ delete [] buf;
+
+ if ( srchHandle == -1 )
+ {
+ return 0;
+ }
+
+ // Loop through names
+ do
+ {
+ this->Internal->Files.push_back(data.name);
+ }
+ while ( _findnext(srchHandle, &data) != -1 );
+ this->Internal->Path = name;
+ return _findclose(srchHandle) != -1;
+}
+
+unsigned long Directory::GetNumberOfFilesInDirectory(const char* name)
+{
+#if _MSC_VER < 1300
+ long srchHandle;
+#else
+ intptr_t srchHandle;
+#endif
+ char* buf;
+ size_t n = strlen(name);
+ if ( name[n - 1] == '/' )
+ {
+ buf = new char[n + 1 + 1];
+ sprintf(buf, "%s*", name);
+ }
+ else
+ {
+ buf = new char[n + 2 + 1];
+ sprintf(buf, "%s/*", name);
+ }
+ struct _finddata_t data; // data of current file
+
+ // Now put them into the file array
+ srchHandle = _findfirst(buf, &data);
+ delete [] buf;
+
+ if ( srchHandle == -1 )
+ {
+ return 0;
+ }
+
+ // Loop through names
+ unsigned long count = 0;
+ do
+ {
+ count++;
+ }
+ while ( _findnext(srchHandle, &data) != -1 );
+ _findclose(srchHandle);
+ return count;
+}
+
+} // namespace KWSYS_NAMESPACE
+
+#else
+
+// Now the POSIX style directory access
+
+#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
+#endif
+
+namespace KWSYS_NAMESPACE
+{
+
+bool Directory::Load(const char* name)
+{
+ this->Clear();
+
+ if (!name)
+ {
+ return 0;
+ }
+ DIR* dir = opendir(name);
+
+ if (!dir)
+ {
+ return 0;
+ }
+
+ for (dirent* d = readdir(dir); d; d = readdir(dir) )
+ {
+ this->Internal->Files.push_back(d->d_name);
+ }
+ this->Internal->Path = name;
+ closedir(dir);
+ return 1;
+}
+
+unsigned long Directory::GetNumberOfFilesInDirectory(const char* name)
+{
+ DIR* dir = opendir(name);
+
+ if (!dir)
+ {
+ return 0;
+ }
+
+ unsigned long count = 0;
+ for (dirent* d = readdir(dir); d; d = readdir(dir) )
+ {
+ count++;
+ }
+ closedir(dir);
+ return count;
+}
+
+} // namespace KWSYS_NAMESPACE
+
+#endif
diff --git a/Source/kwsys/Directory.hxx.in b/Source/kwsys/Directory.hxx.in
new file mode 100644
index 000000000..05217c46d
--- /dev/null
+++ b/Source/kwsys/Directory.hxx.in
@@ -0,0 +1,80 @@
+/*============================================================================
+ 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@_Directory_hxx
+#define @KWSYS_NAMESPACE@_Directory_hxx
+
+#include <@KWSYS_NAMESPACE@/Configure.h>
+
+namespace @KWSYS_NAMESPACE@
+{
+
+class DirectoryInternals;
+
+/** \class Directory
+ * \brief Portable directory/filename traversal.
+ *
+ * Directory provides a portable way of finding the names of the files
+ * in a system directory.
+ *
+ * Directory currently works with Windows and Unix operating systems.
+ */
+class @KWSYS_NAMESPACE@_EXPORT Directory
+{
+public:
+ Directory();
+ ~Directory();
+
+ /**
+ * Load the specified directory and load the names of the files
+ * in that directory. 0 is returned if the directory can not be
+ * opened, 1 if it is opened.
+ */
+ bool Load(const char*);
+
+ /**
+ * Return the number of files in the current directory.
+ */
+ unsigned long GetNumberOfFiles() const;
+
+ /**
+ * Return the number of files in the specified directory.
+ * A higher performance static method.
+ */
+ static unsigned long GetNumberOfFilesInDirectory(const char*);
+
+ /**
+ * Return the file at the given index, the indexing is 0 based
+ */
+ const char* GetFile(unsigned long) const;
+
+ /**
+ * Return the path to Open'ed directory
+ */
+ const char* GetPath() const;
+
+ /**
+ * Clear the internal structure. Used internally at beginning of Load(...)
+ * to clear the cache.
+ */
+ void Clear();
+
+private:
+ // Private implementation details.
+ DirectoryInternals* Internal;
+
+ Directory(const Directory&); // Not implemented.
+ void operator=(const Directory&); // Not implemented.
+}; // End Class: Directory
+
+} // namespace @KWSYS_NAMESPACE@
+
+#endif
diff --git a/Source/kwsys/DynamicLoader.cxx b/Source/kwsys/DynamicLoader.cxx
new file mode 100644
index 000000000..c4ee09551
--- /dev/null
+++ b/Source/kwsys/DynamicLoader.cxx
@@ -0,0 +1,482 @@
+/*============================================================================
+ 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(DynamicLoader.hxx)
+
+#include KWSYS_HEADER(Configure.hxx)
+
+// Work-around CMake dependency scanning limitation. This must
+// duplicate the above list of headers.
+#if 0
+# include "DynamicLoader.hxx.in"
+# include "Configure.hxx.in"
+#endif
+
+// This file is actually 3 different implementations.
+// 1. HP machines which uses shl_load
+// 2. Mac OS X 10.2.x and earlier which uses NSLinkModule
+// 3. Windows which uses LoadLibrary
+// 4. Most unix systems (including Mac OS X 10.3 and later) which use dlopen
+// (default) Each part of the ifdef contains a complete implementation for
+// the static methods of DynamicLoader.
+
+// ---------------------------------------------------------------
+// 1. Implementation for HPUX machines
+#ifdef __hpux
+#include <errno.h>
+#include <dl.h>
+#define DYNAMICLOADER_DEFINED 1
+
+namespace KWSYS_NAMESPACE
+{
+
+//----------------------------------------------------------------------------
+DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname )
+{
+ return shl_load(libname, BIND_DEFERRED | DYNAMIC_PATH, 0L);
+}
+
+//----------------------------------------------------------------------------
+int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
+{
+ return !shl_unload(lib);
+}
+
+//----------------------------------------------------------------------------
+DynamicLoader::SymbolPointer
+DynamicLoader::GetSymbolAddress(DynamicLoader::LibraryHandle lib, const char* sym)
+{
+ void* addr;
+ int status;
+
+ /* TYPE_PROCEDURE Look for a function or procedure. (This used to be default)
+ * 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);
+ void* result = (status < 0) ? (void*)0 : addr;
+
+ // Hack to cast pointer-to-data to pointer-to-function.
+ return *reinterpret_cast<DynamicLoader::SymbolPointer*>(&result);
+}
+
+const char* DynamicLoader::LastError()
+{
+ // TODO: Need implementation with errno/strerror
+ /* If successful, shl_findsym returns an integer (int) value zero. If
+ * shl_findsym cannot find sym, it returns -1 and sets errno to zero.
+ * If any other errors occur, shl_findsym returns -1 and sets errno to one
+ * of these values (defined in <errno.h>):
+ * ENOEXEC
+ * A format error was detected in the specified library.
+ * ENOSYM
+ * A symbol on which sym depends could not be found.
+ * EINVAL
+ * The specified handle is invalid.
+ */
+
+ if( errno == ENOEXEC
+ || errno == ENOSYM
+ || errno == EINVAL )
+ {
+ return strerror(errno);
+ }
+ // else
+ return 0;
+}
+
+} // namespace KWSYS_NAMESPACE
+
+#endif //__hpux
+
+
+// ---------------------------------------------------------------
+// 2. Implementation for Mac OS X 10.2.x and earlier
+#ifdef __APPLE__
+#if MAC_OS_X_VERSION_MAX_ALLOWED < 1030
+#include <string.h> // for strlen
+#include <mach-o/dyld.h>
+#define DYNAMICLOADER_DEFINED 1
+
+namespace KWSYS_NAMESPACE
+{
+
+//----------------------------------------------------------------------------
+DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname )
+{
+ NSObjectFileImageReturnCode rc;
+ NSObjectFileImage image = 0;
+
+ rc = NSCreateObjectFileImageFromFile(libname, &image);
+ // rc == NSObjectFileImageInappropriateFile when trying to load a dylib file
+ if( rc != NSObjectFileImageSuccess )
+ {
+ return 0;
+ }
+ NSModule handle = NSLinkModule(image, libname,
+ NSLINKMODULE_OPTION_BINDNOW|NSLINKMODULE_OPTION_RETURN_ON_ERROR);
+ NSDestroyObjectFileImage(image);
+ return handle;
+}
+
+//----------------------------------------------------------------------------
+int DynamicLoader::CloseLibrary( DynamicLoader::LibraryHandle lib)
+{
+ // NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED
+ // With this option the memory for the module is not deallocated
+ // allowing pointers into the module to still be valid.
+ // You should use this option instead if your code experience some problems
+ // reported against Panther 10.3.9 (fixed in Tiger 10.4.2 and up)
+ bool success = NSUnLinkModule(lib, NSUNLINKMODULE_OPTION_NONE);
+ return success;
+}
+
+//----------------------------------------------------------------------------
+DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
+ DynamicLoader::LibraryHandle lib, const char* sym)
+{
+ void *result=0;
+ // Need to prepend symbols with '_' on Apple-gcc compilers
+ size_t len = strlen(sym);
+ char *rsym = new char[len + 1 + 1];
+ strcpy(rsym, "_");
+ strcat(rsym+1, sym);
+
+ NSSymbol symbol = NSLookupSymbolInModule(lib, rsym);
+ if(symbol)
+ {
+ result = NSAddressOfSymbol(symbol);
+ }
+
+ delete[] rsym;
+ // Hack to cast pointer-to-data to pointer-to-function.
+ return *reinterpret_cast<DynamicLoader::SymbolPointer*>(&result);
+}
+
+//----------------------------------------------------------------------------
+const char* DynamicLoader::LastError()
+{
+ return 0;
+}
+
+} // namespace KWSYS_NAMESPACE
+
+#endif // MAC_OS_X_VERSION_MAX_ALLOWED < 1030
+#endif // __APPLE__
+
+// ---------------------------------------------------------------
+// 3. Implementation for Windows win32 code but not cygwin
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#include <windows.h>
+#define DYNAMICLOADER_DEFINED 1
+
+namespace KWSYS_NAMESPACE
+{
+
+//----------------------------------------------------------------------------
+DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* 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
+ return lh;
+}
+
+//----------------------------------------------------------------------------
+int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
+{
+ return (int)FreeLibrary(lib);
+}
+
+//----------------------------------------------------------------------------
+DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
+ DynamicLoader::LibraryHandle lib, const char* sym)
+{
+ // TODO: The calling convention affects the name of the symbol. We
+ // should have a tool to help get the symbol with the desired
+ // calling convention. Currently we assume cdecl.
+ //
+ // Borland:
+ // __cdecl = "_func" (default)
+ // __fastcall = "@_func"
+ // __stdcall = "func"
+ //
+ // Watcom:
+ // __cdecl = "_func"
+ // __fastcall = "@_func@X"
+ // __stdcall = "_func@X"
+ // __watcall = "func_" (default)
+ //
+ // MSVC:
+ // __cdecl = "func" (default)
+ // __fastcall = "@_func@X"
+ // __stdcall = "_func@X"
+ //
+ // Note that the "@X" part of the name above is the total size (in
+ // bytes) of the arguments on the stack.
+ void *result;
+#if defined(__BORLANDC__) || defined(__WATCOMC__)
+ // Need to prepend symbols with '_'
+ size_t len = strlen(sym);
+ char *rsym = new char[len + 1 + 1];
+ strcpy(rsym, "_");
+ strcat(rsym, sym);
+#else
+ const char *rsym = sym;
+#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
+ // Hack to cast pointer-to-data to pointer-to-function.
+#ifdef __WATCOMC__
+ return *(DynamicLoader::SymbolPointer*)(&result);
+#else
+ return *reinterpret_cast<DynamicLoader::SymbolPointer*>(&result);
+#endif
+}
+
+//----------------------------------------------------------------------------
+const char* DynamicLoader::LastError()
+{
+ LPVOID lpMsgBuf=NULL;
+
+ FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ GetLastError(),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+ (LPTSTR) &lpMsgBuf,
+ 0,
+ NULL
+ );
+
+ if(!lpMsgBuf)
+ {
+ return NULL;
+ }
+
+ static char* str = 0;
+ delete [] str;
+ str = strcpy(new char[strlen((char*)lpMsgBuf)+1], (char*)lpMsgBuf);
+ // Free the buffer.
+ LocalFree( lpMsgBuf );
+ return str;
+}
+
+} // namespace KWSYS_NAMESPACE
+
+#endif //_WIN32
+
+// ---------------------------------------------------------------
+// 4. Implementation for BeOS
+#if defined __BEOS__
+
+#include <string.h> // for strerror()
+
+#include <be/kernel/image.h>
+#include <be/support/Errors.h>
+
+#define DYNAMICLOADER_DEFINED 1
+
+namespace KWSYS_NAMESPACE
+{
+
+static image_id last_dynamic_err = B_OK;
+
+//----------------------------------------------------------------------------
+DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* 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);
+ if (rc < 0)
+ {
+ last_dynamic_err = rc;
+ return 0;
+ }
+
+ return rc+1;
+}
+
+//----------------------------------------------------------------------------
+int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
+{
+ if (!lib)
+ {
+ last_dynamic_err = B_BAD_VALUE;
+ return 0;
+ }
+ else
+ {
+ // The function dlclose() returns 0 on success, and non-zero on error.
+ status_t rc = unload_add_on(lib-1);
+ if (rc != B_OK)
+ {
+ last_dynamic_err = rc;
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+//----------------------------------------------------------------------------
+DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
+ DynamicLoader::LibraryHandle lib, const char* sym)
+{
+ // Hack to cast pointer-to-data to pointer-to-function.
+ union
+ {
+ void* pvoid;
+ DynamicLoader::SymbolPointer psym;
+ } result;
+
+ result.psym = NULL;
+
+ if (!lib)
+ {
+ last_dynamic_err = B_BAD_VALUE;
+ }
+ else
+ {
+ // !!! 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);
+ if (rc != B_OK)
+ {
+ last_dynamic_err = rc;
+ result.psym = NULL;
+ }
+ }
+ return result.psym;
+}
+
+//----------------------------------------------------------------------------
+const char* DynamicLoader::LastError()
+{
+ const char *retval = strerror(last_dynamic_err);
+ last_dynamic_err = B_OK;
+ return retval;
+}
+
+} // namespace KWSYS_NAMESPACE
+#endif
+
+// ---------------------------------------------------------------
+// 5. Implementation for systems without dynamic libs
+// __gnu_blrts__ is IBM BlueGene/L
+// __LIBCATAMOUNT__ is defined on Catamount on Cray compute nodes
+#if defined(__gnu_blrts__) || defined(__LIBCATAMOUNT__) || defined(__CRAYXT_COMPUTE_LINUX_TARGET)
+#include <string.h> // for strerror()
+#define DYNAMICLOADER_DEFINED 1
+
+namespace KWSYS_NAMESPACE
+{
+
+//----------------------------------------------------------------------------
+DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname )
+{
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
+{
+ if (!lib)
+ {
+ return 0;
+ }
+
+ return 1;
+}
+
+//----------------------------------------------------------------------------
+DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
+ DynamicLoader::LibraryHandle lib, const char* sym)
+{
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+const char* DynamicLoader::LastError()
+ {
+ return "General error";
+ }
+
+} // namespace KWSYS_NAMESPACE
+#endif
+
+// ---------------------------------------------------------------
+// 6. Implementation for default UNIX machines.
+// if nothing has been defined then use this
+#ifndef DYNAMICLOADER_DEFINED
+#define DYNAMICLOADER_DEFINED 1
+// Setup for most unix machines
+#include <dlfcn.h>
+
+namespace KWSYS_NAMESPACE
+{
+
+//----------------------------------------------------------------------------
+DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname )
+{
+ return dlopen(libname, RTLD_LAZY);
+}
+
+//----------------------------------------------------------------------------
+int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
+{
+ if (lib)
+ {
+ // The function dlclose() returns 0 on success, and non-zero on error.
+ return !dlclose(lib);
+ }
+ // else
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
+ DynamicLoader::LibraryHandle lib, const char* sym)
+{
+ // Hack to cast pointer-to-data to pointer-to-function.
+ union
+ {
+ void* pvoid;
+ DynamicLoader::SymbolPointer psym;
+ } result;
+ result.pvoid = dlsym(lib, sym);
+ return result.psym;
+}
+
+//----------------------------------------------------------------------------
+const char* DynamicLoader::LastError()
+{
+ return dlerror();
+}
+
+} // namespace KWSYS_NAMESPACE
+
+#endif
diff --git a/Source/kwsys/DynamicLoader.hxx.in b/Source/kwsys/DynamicLoader.hxx.in
new file mode 100644
index 000000000..64468ecd3
--- /dev/null
+++ b/Source/kwsys/DynamicLoader.hxx.in
@@ -0,0 +1,101 @@
+/*============================================================================
+ 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@_DynamicLoader_hxx
+#define @KWSYS_NAMESPACE@_DynamicLoader_hxx
+
+#include <@KWSYS_NAMESPACE@/Configure.h>
+
+#if defined(__hpux)
+ #include <dl.h>
+#elif defined(_WIN32) && !defined(__CYGWIN__)
+ #include <windows.h>
+#elif defined(__APPLE__)
+ #include <AvailabilityMacros.h>
+ #if MAC_OS_X_VERSION_MAX_ALLOWED < 1030
+ #include <mach-o/dyld.h>
+ #endif
+#elif defined(__BEOS__)
+ #include <be/kernel/image.h>
+#endif
+
+namespace @KWSYS_NAMESPACE@
+{
+/** \class DynamicLoader
+ * \brief Portable loading of dynamic libraries or dll's.
+ *
+ * DynamicLoader provides a portable interface to loading dynamic
+ * libraries or dll's into a process.
+ *
+ * Directory currently works with Windows, Apple, HP-UX and Unix (POSIX)
+ * operating systems
+ *
+ * \warning dlopen on *nix system works the following way:
+ * If filename contains a slash ("/"), then it is interpreted as a (relative
+ * or absolute) pathname. Otherwise, the dynamic linker searches for the
+ * library as follows : see ld.so(8) for further details):
+ * Whereas this distinction does not exist on Win32. Therefore ideally you
+ * should be doing full path to garantee to have a consistent way of dealing
+ * with dynamic loading of shared library.
+ *
+ * \warning the Cygwin implementation do not use the Win32 HMODULE. Put extra
+ * condition so that we can include the correct declaration (POSIX)
+ */
+
+class @KWSYS_NAMESPACE@_EXPORT DynamicLoader
+{
+public:
+// Ugly stuff for library handles
+// They are different on several different OS's
+#if defined(__hpux)
+ typedef shl_t LibraryHandle;
+#elif defined(_WIN32) && !defined(__CYGWIN__)
+ typedef HMODULE LibraryHandle;
+#elif defined(__APPLE__)
+ #if MAC_OS_X_VERSION_MAX_ALLOWED < 1030
+ typedef NSModule LibraryHandle;
+ #else
+ typedef void* LibraryHandle;
+ #endif
+#elif defined(__BEOS__)
+ typedef image_id LibraryHandle;
+#else // POSIX
+ typedef void* LibraryHandle;
+#endif
+
+ // Return type from DynamicLoader::GetSymbolAddress.
+ typedef void (*SymbolPointer)();
+
+ /** 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*);
+
+ /** 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*);
+
+ /** Return the default module prefix for the current platform. */
+ static const char* LibPrefix() { return "@KWSYS_DynamicLoader_PREFIX@"; }
+
+ /** Return the default module suffix for the current platform. */
+ static const char* LibExtension() { return "@KWSYS_DynamicLoader_SUFFIX@"; }
+
+ /** Return the last error produced from a calls made on this class. */
+ static const char* LastError();
+}; // End Class: DynamicLoader
+
+} // namespace @KWSYS_NAMESPACE@
+
+#endif
diff --git a/Source/kwsys/EncodeExecutable.c b/Source/kwsys/EncodeExecutable.c
new file mode 100644
index 000000000..bc30568ff
--- /dev/null
+++ b/Source/kwsys/EncodeExecutable.c
@@ -0,0 +1,114 @@
+/*============================================================================
+ 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 <stdio.h>
+#ifdef __WATCOMC__
+#define _unlink unlink
+#endif
+int main(int argc, char* argv[])
+{
+ FILE* ifp;
+ FILE* ofp;
+ int i;
+ int n;
+ int count = 0;
+ unsigned char buffer[1024];
+
+ /* Check arguments. */
+ if(argc != 5)
+ {
+ fprintf(stderr, "Usage: %s <input> <output> <kwsys-name> <array>\n",
+ argv[0]);
+ return 1;
+ }
+
+ /* Open the input file. */
+ ifp = fopen(argv[1], "rb");
+ if(!ifp)
+ {
+ fprintf(stderr, "Cannot open input file: \"%s\"\n", argv[1]);
+ return 2;
+ }
+ ofp = fopen(argv[2], "w");
+ if(!ofp)
+ {
+ fprintf(stderr, "Cannot open output file: \"%s\"\n", argv[2]);
+ fclose(ifp);
+ return 2;
+ }
+
+ /* Prepend header comment. */
+ fprintf(ofp, "/*\n * DO NOT EDIT\n * This file is generated by:\n");
+ fprintf(ofp, " * %s\n */\n\n", argv[0]);
+ fprintf(ofp, "#include \"kwsysPrivate.h\"\n");
+ fprintf(ofp, "#include KWSYS_HEADER(Configure.h)\n\n");
+ fprintf(ofp, "#include <stdio.h>\n\n");
+ fprintf(ofp, "#if defined(_WIN32)\n");
+ fprintf(ofp, "# include <io.h>\n");
+ fprintf(ofp, "#else\n");
+ fprintf(ofp, "# include <unistd.h>\n");
+ fprintf(ofp, "#endif\n");
+ fprintf(ofp, "\n");
+ fprintf(ofp, "static void kwsys_unlink(const char* fname)\n");
+ fprintf(ofp, "{\n");
+ fprintf(ofp, "#if defined(__WATCOMC__)\n");
+ fprintf(ofp, " unlink(fname);\n");
+ fprintf(ofp, "#else\n");
+ fprintf(ofp, " _unlink(fname);\n");
+ fprintf(ofp, "#endif\n");
+ fprintf(ofp, "}\n");
+ fprintf(ofp, "\n");
+
+ /* Split file up in 1024-byte chunks. */
+ while((n = (int)fread(buffer, 1, 1024, ifp)) > 0)
+ {
+ fprintf(ofp, "static unsigned char kwsysEncodedArray%s_%d[%d] = {\n",
+ argv[4], count++, n);
+ for(i=0; i < n-1; ++i)
+ {
+ fprintf(ofp, "0x%02X", buffer[i]);
+ if(i%10 == 9)
+ {
+ fprintf(ofp, ",\n");
+ }
+ else
+ {
+ fprintf(ofp, ", ");
+ }
+ }
+ fprintf(ofp, "0x%02X};\n\n", buffer[n-1]);
+ }
+ fclose(ifp);
+
+ /* Provide a function to write the data to a file. */
+ fprintf(ofp, "extern %s_EXPORT int %sEncodedWriteArray%s(const char* fname)\n",
+ argv[3], argv[3], argv[4]);
+ fprintf(ofp, "{\n");
+ fprintf(ofp, " FILE* ofp = fopen(fname, \"wb\");\n");
+ fprintf(ofp, " if(!ofp) { return 0; }\n");
+ for(i=0; i < count; ++i)
+ {
+ fprintf(ofp, " if(fwrite(kwsysEncodedArray%s_%d, 1,\n"
+ " sizeof(kwsysEncodedArray%s_%d), ofp) !=\n"
+ " sizeof(kwsysEncodedArray%s_%d))\n",
+ argv[4], i, argv[4], i, argv[4], i);
+ fprintf(ofp, " {\n");
+ fprintf(ofp, " fclose(ofp);\n");
+ fprintf(ofp, " kwsys_unlink(fname);\n");
+ fprintf(ofp, " return 0;\n");
+ fprintf(ofp, " }\n");
+ }
+ fprintf(ofp, " fclose(ofp);\n");
+ fprintf(ofp, " return 1;\n");
+ fprintf(ofp, "}\n");
+ fclose(ofp);
+ return 0;
+}
diff --git a/Source/kwsys/ExtraTest.cmake.in b/Source/kwsys/ExtraTest.cmake.in
new file mode 100644
index 000000000..e8c0a1cdb
--- /dev/null
+++ b/Source/kwsys/ExtraTest.cmake.in
@@ -0,0 +1 @@
+MESSAGE("*** This message is generated by message inside a file that is included in DartTestfile.txt ***")
diff --git a/Source/kwsys/FundamentalType.h.in b/Source/kwsys/FundamentalType.h.in
new file mode 100644
index 000000000..ff200633a
--- /dev/null
+++ b/Source/kwsys/FundamentalType.h.in
@@ -0,0 +1,146 @@
+/*============================================================================
+ 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
new file mode 100644
index 000000000..513eb6408
--- /dev/null
+++ b/Source/kwsys/Glob.cxx
@@ -0,0 +1,516 @@
+/*============================================================================
+ 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(Glob.hxx)
+
+#include KWSYS_HEADER(Configure.hxx)
+
+#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.
+#if 0
+# include "Glob.hxx.in"
+# include "Directory.hxx.in"
+# 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 <ctype.h>
+#include <stdio.h>
+#include <string.h>
+namespace KWSYS_NAMESPACE
+{
+#if defined(_WIN32) || defined(__APPLE__) || defined(__CYGWIN__)
+// On Windows and apple, no difference between lower and upper case
+# define KWSYS_GLOB_CASE_INDEPENDENT
+#endif
+
+#if defined(_WIN32) || defined(__CYGWIN__)
+// Handle network paths
+# define KWSYS_GLOB_SUPPORT_NETWORK_PATHS
+#endif
+
+//----------------------------------------------------------------------------
+class GlobInternals
+{
+public:
+ kwsys_stl::vector<kwsys_stl::string> Files;
+ kwsys_stl::vector<kwsys::RegularExpression> Expressions;
+};
+
+//----------------------------------------------------------------------------
+Glob::Glob()
+{
+ this->Internals = new GlobInternals;
+ this->Recurse = false;
+ this->Relative = "";
+
+ this->RecurseThroughSymlinks = true;
+ // RecurseThroughSymlinks is true by default for backwards compatibility,
+ // not because it's a good idea...
+ this->FollowedSymlinkCount = 0;
+}
+
+//----------------------------------------------------------------------------
+Glob::~Glob()
+{
+ delete this->Internals;
+}
+
+//----------------------------------------------------------------------------
+kwsys_stl::vector<kwsys_stl::string>& Glob::GetFiles()
+{
+ return this->Internals->Files;
+}
+
+//----------------------------------------------------------------------------
+kwsys_stl::string Glob::PatternToRegex(const kwsys_stl::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;
+ i != pattern_last; ++i)
+ {
+ int c = *i;
+ if(c == '*')
+ {
+ // A '*' (not between brackets) matches any string.
+ // We modify this to not match slashes since the orignal glob
+ // pattern documentation was meant for matching file name
+ // components separated by slashes.
+ regex += "[^/]*";
+ }
+ else if(c == '?')
+ {
+ // A '?' (not between brackets) matches any single character.
+ // We modify this to not match slashes since the orignal glob
+ // pattern documentation was meant for matching file name
+ // components separated by slashes.
+ regex += "[^/]";
+ }
+ else if(c == '[')
+ {
+ // 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;
+
+ // The first character may be complementation '!' or '^'.
+ if(bracket_last != pattern_last &&
+ (*bracket_last == '!' || *bracket_last == '^'))
+ {
+ ++bracket_last;
+ }
+
+ // If the next character is a ']' it is included in the brackets
+ // because the bracket string may not be empty.
+ if(bracket_last != pattern_last && *bracket_last == ']')
+ {
+ ++bracket_last;
+ }
+
+ // Search for the closing ']'.
+ while(bracket_last != pattern_last && *bracket_last != ']')
+ {
+ ++bracket_last;
+ }
+
+ // Check whether we have a complete bracket string.
+ if(bracket_last == pattern_last)
+ {
+ // The bracket string did not end, so it was opened simply by
+ // a '[' that is supposed to be matched literally.
+ regex += "\\[";
+ }
+ else
+ {
+ // Convert the bracket string to its regex equivalent.
+ kwsys_stl::string::const_iterator k = bracket_first;
+
+ // Open the regex block.
+ regex += "[";
+
+ // A regex range complement uses '^' instead of '!'.
+ if(k != bracket_last && *k == '!')
+ {
+ regex += "^";
+ ++k;
+ }
+
+ // Convert the remaining characters.
+ for(; k != bracket_last; ++k)
+ {
+ // Backslashes must be escaped.
+ if(*k == '\\')
+ {
+ regex += "\\";
+ }
+
+ // Store this character.
+ regex += *k;
+ }
+
+ // Close the regex block.
+ regex += "]";
+
+ // Jump to the end of the bracket string.
+ i = bracket_last;
+ }
+ }
+ else
+ {
+ // A single character matches itself.
+ int ch = c;
+ if(!(('a' <= ch && ch <= 'z') ||
+ ('A' <= ch && ch <= 'Z') ||
+ ('0' <= ch && ch <= '9')))
+ {
+ // Escape the non-alphanumeric character.
+ regex += "\\";
+ }
+#if defined(KWSYS_GLOB_CASE_INDEPENDENT)
+ else
+ {
+ // On case-insensitive systems file names are converted to lower
+ // case before matching.
+ if(!preserve_case)
+ {
+ ch = tolower(ch);
+ }
+ }
+#endif
+ (void)preserve_case;
+ // Store the character.
+ regex.append(1, static_cast<char>(ch));
+ }
+ }
+
+ if(require_whole_string)
+ {
+ regex += "$";
+ }
+ return regex;
+}
+
+//----------------------------------------------------------------------------
+void Glob::RecurseDirectory(kwsys_stl::string::size_type start,
+ const kwsys_stl::string& dir)
+{
+ kwsys::Directory d;
+ if ( !d.Load(dir.c_str()) )
+ {
+ return;
+ }
+ unsigned long cc;
+ kwsys_stl::string fullname;
+ kwsys_stl::string realname;
+ kwsys_stl::string fname;
+ for ( cc = 0; cc < d.GetNumberOfFiles(); cc ++ )
+ {
+ fname = d.GetFile(cc);
+ if ( strcmp(fname.c_str(), ".") == 0 ||
+ strcmp(fname.c_str(), "..") == 0 )
+ {
+ continue;
+ }
+
+ if ( start == 0 )
+ {
+ realname = dir + fname;
+ }
+ else
+ {
+ realname = dir + "/" + fname;
+ }
+
+#if defined( KWSYS_GLOB_CASE_INDEPENDENT )
+ // On Windows and apple, no difference between lower and upper case
+ 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());
+
+ if ( isDir && (!isSymLink || this->RecurseThroughSymlinks) )
+ {
+ if (isSymLink)
+ {
+ ++this->FollowedSymlinkCount;
+ }
+ this->RecurseDirectory(start+1, realname);
+ }
+ else
+ {
+ if ( (this->Internals->Expressions.size() > 0) &&
+ this->Internals->Expressions[
+ this->Internals->Expressions.size()-1].find(fname.c_str()) )
+ {
+ this->AddFile(this->Internals->Files, realname.c_str());
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void Glob::ProcessDirectory(kwsys_stl::string::size_type start,
+ const kwsys_stl::string& dir)
+{
+ //kwsys_ios::cout << "ProcessDirectory: " << dir << kwsys_ios::endl;
+ bool last = ( start == this->Internals->Expressions.size()-1 );
+ if ( last && this->Recurse )
+ {
+ this->RecurseDirectory(start, dir);
+ return;
+ }
+
+ if ( start >= this->Internals->Expressions.size() )
+ {
+ return;
+ }
+
+ kwsys::Directory d;
+ if ( !d.Load(dir.c_str()) )
+ {
+ return;
+ }
+ unsigned long cc;
+ kwsys_stl::string fullname;
+ kwsys_stl::string realname;
+ kwsys_stl::string fname;
+ for ( cc = 0; cc < d.GetNumberOfFiles(); cc ++ )
+ {
+ fname = d.GetFile(cc);
+ if ( strcmp(fname.c_str(), ".") == 0 ||
+ strcmp(fname.c_str(), "..") == 0 )
+ {
+ continue;
+ }
+
+ if ( start == 0 )
+ {
+ realname = dir + fname;
+ }
+ else
+ {
+ realname = dir + "/" + fname;
+ }
+
+#if defined(KWSYS_GLOB_CASE_INDEPENDENT)
+ // On case-insensitive file systems convert to lower case for matching.
+ 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;
+
+ if ( !last &&
+ !kwsys::SystemTools::FileIsDirectory(realname.c_str()) )
+ {
+ continue;
+ }
+
+ if ( this->Internals->Expressions[start].find(fname.c_str()) )
+ {
+ if ( last )
+ {
+ this->AddFile(this->Internals->Files, realname.c_str());
+ }
+ else
+ {
+ this->ProcessDirectory(start+1, realname + "/");
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+bool Glob::FindFiles(const kwsys_stl::string& inexpr)
+{
+ kwsys_stl::string cexpr;
+ kwsys_stl::string::size_type cc;
+ kwsys_stl::string expr = inexpr;
+
+ this->Internals->Expressions.clear();
+ this->Internals->Files.clear();
+
+ if ( !kwsys::SystemTools::FileIsFullPath(expr.c_str()) )
+ {
+ expr = kwsys::SystemTools::GetCurrentWorkingDirectory();
+ expr += "/" + inexpr;
+ }
+ kwsys_stl::string fexpr = expr;
+
+ kwsys_stl::string::size_type skip = 0;
+ kwsys_stl::string::size_type last_slash = 0;
+ for ( cc = 0; cc < expr.size(); cc ++ )
+ {
+ if ( cc > 0 && expr[cc] == '/' && expr[cc-1] != '\\' )
+ {
+ last_slash = cc;
+ }
+ if ( cc > 0 &&
+ (expr[cc] == '[' || expr[cc] == '?' || expr[cc] == '*') &&
+ expr[cc-1] != '\\' )
+ {
+ break;
+ }
+ }
+ if ( last_slash > 0 )
+ {
+ //kwsys_ios::cout << "I can skip: " << fexpr.substr(0, last_slash)
+ //<< kwsys_ios::endl;
+ skip = last_slash;
+ }
+ if ( skip == 0 )
+ {
+#if defined( KWSYS_GLOB_SUPPORT_NETWORK_PATHS )
+ // Handle network paths
+ if ( expr[0] == '/' && expr[1] == '/' )
+ {
+ int cnt = 0;
+ for ( cc = 2; cc < expr.size(); cc ++ )
+ {
+ if ( expr[cc] == '/' )
+ {
+ cnt ++;
+ if ( cnt == 2 )
+ {
+ break;
+ }
+ }
+ }
+ skip = int(cc + 1);
+ }
+ else
+#endif
+ // Handle drive letters on Windows
+ if ( expr[1] == ':' && expr[0] != '/' )
+ {
+ skip = 2;
+ }
+ }
+
+ if ( skip > 0 )
+ {
+ expr = expr.substr(skip);
+ }
+
+ cexpr = "";
+ for ( cc = 0; cc < expr.size(); cc ++ )
+ {
+ int ch = expr[cc];
+ if ( ch == '/' )
+ {
+ if ( cexpr.size() > 0 )
+ {
+ this->AddExpression(cexpr.c_str());
+ }
+ cexpr = "";
+ }
+ else
+ {
+ cexpr.append(1, static_cast<char>(ch));
+ }
+ }
+ if ( cexpr.size() > 0 )
+ {
+ this->AddExpression(cexpr.c_str());
+ }
+
+ // Handle network paths
+ if ( skip > 0 )
+ {
+ this->ProcessDirectory(0, fexpr.substr(0, skip) + "/");
+ }
+ else
+ {
+ this->ProcessDirectory(0, "/");
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+void Glob::AddExpression(const char* expr)
+{
+ this->Internals->Expressions.push_back(
+ kwsys::RegularExpression(
+ this->PatternToRegex(expr).c_str()));
+}
+
+//----------------------------------------------------------------------------
+void Glob::SetRelative(const char* dir)
+{
+ if ( !dir )
+ {
+ this->Relative = "";
+ return;
+ }
+ this->Relative = dir;
+}
+
+//----------------------------------------------------------------------------
+const char* Glob::GetRelative()
+{
+ if ( this->Relative.empty() )
+ {
+ return 0;
+ }
+ return this->Relative.c_str();
+}
+
+//----------------------------------------------------------------------------
+void Glob::AddFile(kwsys_stl::vector<kwsys_stl::string>& files, const char* file)
+{
+ if ( !this->Relative.empty() )
+ {
+ files.push_back(kwsys::SystemTools::RelativePath(this->Relative.c_str(), file));
+ }
+ else
+ {
+ files.push_back(file);
+ }
+}
+
+} // namespace KWSYS_NAMESPACE
+
diff --git a/Source/kwsys/Glob.hxx.in b/Source/kwsys/Glob.hxx.in
new file mode 100644
index 000000000..88c343ce0
--- /dev/null
+++ b/Source/kwsys/Glob.hxx.in
@@ -0,0 +1,117 @@
+/*============================================================================
+ 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@_Glob_hxx
+#define @KWSYS_NAMESPACE@_Glob_hxx
+
+#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
+
+namespace @KWSYS_NAMESPACE@
+{
+
+class GlobInternals;
+
+/** \class Glob
+ * \brief Portable globbing searches.
+ *
+ * Globbing expressions are much simpler than regular
+ * expressions. This class will search for files using
+ * globbing expressions.
+ *
+ * Finds all files that match a given globbing expression.
+ */
+class @KWSYS_NAMESPACE@_EXPORT Glob
+{
+public:
+ Glob();
+ ~Glob();
+
+ //! Find all files that match the pattern.
+ bool FindFiles(const kwsys_stl::string& inexpr);
+
+ //! Return the list of files that matched.
+ kwsys_stl::vector<kwsys_stl::string>& GetFiles();
+
+ //! Set recurse to true to match subdirectories.
+ void RecurseOn() { this->SetRecurse(true); }
+ void RecurseOff() { this->SetRecurse(false); }
+ void SetRecurse(bool i) { this->Recurse = i; }
+ bool GetRecurse() { return this->Recurse; }
+
+ //! Set recurse through symlinks to true if recursion should traverse the
+ // linked-to directories
+ void RecurseThroughSymlinksOn() { this->SetRecurseThroughSymlinks(true); }
+ void RecurseThroughSymlinksOff() { this->SetRecurseThroughSymlinks(false); }
+ void SetRecurseThroughSymlinks(bool i) { this->RecurseThroughSymlinks = i; }
+ bool GetRecurseThroughSymlinks() { return this->RecurseThroughSymlinks; }
+
+ //! Get the number of symlinks followed through recursion
+ unsigned int GetFollowedSymlinkCount() { return this->FollowedSymlinkCount; }
+
+ //! Set relative to true to only show relative path to files.
+ void SetRelative(const char* dir);
+ const char* GetRelative();
+
+ /** Convert the given globbing pattern to a regular expression.
+ There is no way to quote meta-characters. The
+ require_whole_string argument specifies whether the regex is
+ automatically surrounded by "^" and "$" to match the whole
+ 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,
+ bool require_whole_string = true,
+ bool preserve_case = false);
+
+protected:
+ //! Process directory
+ void ProcessDirectory(kwsys_stl::string::size_type start,
+ const kwsys_stl::string& dir);
+
+ //! 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);
+
+ //! Add regular expression
+ void AddExpression(const char* expr);
+
+ //! Add a file to the list
+ void AddFile(kwsys_stl::vector<kwsys_stl::string>& files, const char* file);
+
+ GlobInternals* Internals;
+ bool Recurse;
+ kwsys_stl::string Relative;
+ bool RecurseThroughSymlinks;
+ unsigned int FollowedSymlinkCount;
+
+private:
+ Glob(const Glob&); // Not implemented.
+ void operator=(const Glob&); // Not implemented.
+};
+
+} // 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
new file mode 100644
index 000000000..57b696eb3
--- /dev/null
+++ b/Source/kwsys/IOStream.cxx
@@ -0,0 +1,281 @@
+/*============================================================================
+ 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(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 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
+
+// Implement the rest of this file only if it is needed.
+#if KWSYS_IOS_NEED_OPERATORS_LL
+
+# include <stdio.h> // sscanf, sprintf
+# include <string.h> // memchr
+
+# if defined(_MAX_INT_DIG)
+# define KWSYS_IOS_INT64_MAX_DIG _MAX_INT_DIG
+# else
+# define KWSYS_IOS_INT64_MAX_DIG 32
+# endif
+
+namespace KWSYS_NAMESPACE
+{
+
+// Scan an input stream for an integer value.
+static int IOStreamScanStream(kwsys_ios::istream& is, char* buffer)
+{
+ // Prepare to write to buffer.
+ char* out = buffer;
+ char* end = buffer + KWSYS_IOS_INT64_MAX_DIG - 1;
+
+ // Look for leading sign.
+ if(is.peek() == '+') { *out++ = '+'; is.ignore(); }
+ else if(is.peek() == '-') { *out++ = '-'; is.ignore(); }
+
+ // Determine the base. If not specified in the stream, try to
+ // 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; }
+ bool foundDigit = false;
+ bool foundNonZero = false;
+ if(is.peek() == '0')
+ {
+ foundDigit = true;
+ is.ignore();
+ if((is.peek() == 'x' || is.peek() == 'X') && (base == 0 || base == 16))
+ {
+ base = 16;
+ foundDigit = false;
+ is.ignore();
+ }
+ else if (base == 0)
+ {
+ base = 8;
+ }
+ }
+
+ // Determine the range of digits allowed for this number.
+ const char* digits = "0123456789abcdefABCDEF";
+ int maxDigitIndex = 10;
+ if(base == 8)
+ {
+ maxDigitIndex = 8;
+ }
+ else if(base == 16)
+ {
+ maxDigitIndex = 10+6+6;
+ }
+
+ // Scan until an invalid digit is found.
+ for(;is.peek() != EOF; is.ignore())
+ {
+ if(memchr(digits, *out = (char)is.peek(), maxDigitIndex) != 0)
+ {
+ if((foundNonZero || *out != '0') && out < end)
+ {
+ ++out;
+ foundNonZero = true;
+ }
+ foundDigit = true;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ // Correct the buffer contents for degenerate cases.
+ if(foundDigit && !foundNonZero)
+ {
+ *out++ = '0';
+ }
+ else if (!foundDigit)
+ {
+ out = buffer;
+ }
+
+ // Terminate the string in the buffer.
+ *out = '\0';
+
+ return base;
+}
+
+// Read an integer value from an input stream.
+template <class T>
+kwsys_ios::istream&
+IOStreamScanTemplate(kwsys_ios::istream& is, T& value, char type)
+{
+ int state = kwsys_ios::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
+
+ 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)
+ char format[] = "%I64_";
+ const int typeIndex = 4;
+# else
+ char format[] = "%ll_";
+ const int typeIndex = 3;
+# endif
+ switch(IOStreamScanStream(is, buffer))
+ {
+ case 8: format[typeIndex] = 'o'; break;
+ case 0: // Default to decimal if not told otherwise.
+ case 10: format[typeIndex] = type; break;
+ case 16: format[typeIndex] = 'x'; break;
+ };
+
+ // Use sscanf to parse the number from the buffer.
+ T result;
+ 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; }
+ else { value = result; }
+# if KWSYS_IOS_USE_ANSI
+ } catch(...) { state |= kwsys_ios::ios_base::badbit; }
+# endif
+ }
+
+# if KWSYS_IOS_USE_ANSI
+ is.setstate(kwsys_ios::ios_base::iostate(state));
+# else
+ is.clear(state);
+# endif
+ 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)
+{
+# if KWSYS_IOS_USE_ANSI
+ kwsys_ios::ostream::sentry okay(os);
+# else
+ kwsys_ios::ostream& okay = os;
+# endif
+ 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 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'; }
+ else { *f++ = 'x'; }
+ *f = '\0';
+
+ // Use sprintf to print to a buffer and then write the
+ // buffer to the stream.
+ 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
+ }
+ 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)
+{
+ return IOStreamScanTemplate(is, value, 'd');
+}
+
+// Implement input stream operator for IOStreamULL.
+kwsys_ios::istream& IOStreamScan(kwsys_ios::istream& is, IOStreamULL& value)
+{
+ return IOStreamScanTemplate(is, value, 'u');
+}
+# endif
+
+# if !KWSYS_IOS_HAS_OSTREAM_LONG_LONG
+// Implement output stream operator for IOStreamSLL.
+kwsys_ios::ostream& IOStreamPrint(kwsys_ios::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)
+{
+ return IOStreamPrintTemplate(os, value, 'u');
+}
+# endif
+
+} // namespace KWSYS_NAMESPACE
+
+#else
+
+namespace KWSYS_NAMESPACE
+{
+
+// Create one public symbol in this object file to avoid warnings from
+// archivers.
+void IOStreamSymbolToAvoidWarning()
+{
+}
+
+} // namespace KWSYS_NAMESPACE
+
+#endif // KWSYS_IOS_NEED_OPERATORS_LL
diff --git a/Source/kwsys/IOStream.hxx.in b/Source/kwsys/IOStream.hxx.in
new file mode 100644
index 000000000..9eb99e058
--- /dev/null
+++ b/Source/kwsys/IOStream.hxx.in
@@ -0,0 +1,146 @@
+/*============================================================================
+ 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@_IOStream_hxx
+#define @KWSYS_NAMESPACE@_IOStream_hxx
+
+#include <@KWSYS_NAMESPACE@/ios/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. */
+#define @KWSYS_NAMESPACE@_IOS_HAS_ISTREAM_LONG_LONG @KWSYS_IOS_HAS_ISTREAM_LONG_LONG@
+
+/* Whether ostream supports long long. */
+#define @KWSYS_NAMESPACE@_IOS_HAS_OSTREAM_LONG_LONG @KWSYS_IOS_HAS_OSTREAM_LONG_LONG@
+
+/* Size of type long long and 0 if not available. */
+#define @KWSYS_NAMESPACE@_IOS_SIZEOF_LONG_LONG @KWSYS_SIZEOF_LONG_LONG@
+
+/* Determine whether we need to define the streaming operators for
+ long long or __int64. */
+#if @KWSYS_NAMESPACE@_IOS_SIZEOF_LONG_LONG
+# if !@KWSYS_NAMESPACE@_IOS_HAS_ISTREAM_LONG_LONG || \
+ !@KWSYS_NAMESPACE@_IOS_HAS_OSTREAM_LONG_LONG
+# define @KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL 1
+ namespace @KWSYS_NAMESPACE@
+ {
+ typedef long long IOStreamSLL;
+ typedef unsigned long long IOStreamULL;
+ }
+# endif
+#elif defined(_MSC_VER) && _MSC_VER < 1300
+# define @KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL 1
+ namespace @KWSYS_NAMESPACE@
+ {
+ typedef __int64 IOStreamSLL;
+ typedef unsigned __int64 IOStreamULL;
+ }
+#endif
+#if !defined(@KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL)
+# define @KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL 0
+#endif
+
+#if @KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL
+# if !@KWSYS_NAMESPACE@_IOS_HAS_ISTREAM_LONG_LONG
+
+/* 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&);
+}
+
+/* Provide input stream operator for long long. */
+# if !defined(@KWSYS_NAMESPACE@_IOS_NO_ISTREAM_LONG_LONG) && \
+ !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)
+{
+ return @KWSYS_NAMESPACE@::IOStreamScan(is, value);
+}
+# endif
+
+/* Provide input stream operator for unsigned long long. */
+# if !defined(@KWSYS_NAMESPACE@_IOS_NO_ISTREAM_UNSIGNED_LONG_LONG) && \
+ !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)
+{
+ return @KWSYS_NAMESPACE@::IOStreamScan(is, value);
+}
+# endif
+# endif /* !@KWSYS_NAMESPACE@_IOS_HAS_ISTREAM_LONG_LONG */
+
+# if !@KWSYS_NAMESPACE@_IOS_HAS_OSTREAM_LONG_LONG
+
+/* 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);
+}
+
+/* Provide output stream operator for long long. */
+# if !defined(@KWSYS_NAMESPACE@_IOS_NO_OSTREAM_LONG_LONG) && \
+ !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)
+{
+ return @KWSYS_NAMESPACE@::IOStreamPrint(os, value);
+}
+# endif
+
+/* Provide output stream operator for unsigned long long. */
+# if !defined(@KWSYS_NAMESPACE@_IOS_NO_OSTREAM_UNSIGNED_LONG_LONG) && \
+ !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)
+{
+ return @KWSYS_NAMESPACE@::IOStreamPrint(os, value);
+}
+# endif
+# endif /* !@KWSYS_NAMESPACE@_IOS_HAS_OSTREAM_LONG_LONG */
+#endif /* @KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL */
+
+/* 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
+ access to the macros without a configured namespace. */
+#if defined(KWSYS_NAMESPACE)
+# define KWSYS_IOS_SIZEOF_LONG_LONG @KWSYS_NAMESPACE@_IOS_SIZEOF_LONG_LONG
+# define KWSYS_IOS_HAS_ISTREAM_LONG_LONG @KWSYS_NAMESPACE@_IOS_HAS_ISTREAM_LONG_LONG
+# define KWSYS_IOS_HAS_OSTREAM_LONG_LONG @KWSYS_NAMESPACE@_IOS_HAS_OSTREAM_LONG_LONG
+# define KWSYS_IOS_NEED_OPERATORS_LL @KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL
+#endif
+
+#endif
+
diff --git a/Source/kwsys/MD5.c b/Source/kwsys/MD5.c
new file mode 100644
index 000000000..56776a324
--- /dev/null
+++ b/Source/kwsys/MD5.c
@@ -0,0 +1,518 @@
+/*============================================================================
+ 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(MD5.h)
+
+/* Work-around CMake dependency scanning limitation. This must
+ duplicate the above list of headers. */
+#if 0
+# include "MD5.h.in"
+#endif
+
+#include <stddef.h> /* size_t */
+#include <stdlib.h> /* malloc, free */
+#include <string.h> /* memcpy, strlen */
+
+/*--------------------------------------------------------------------------*/
+
+/* This MD5 implementation has been taken from a third party. Slight
+ modifications to the arrangement of the code have been made to put
+ it in a single source file instead of a separate header and
+ implementation file. */
+
+#if defined(__clang__)
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wcast-align"
+#endif
+
+/*
+ Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ L. Peter Deutsch
+ ghost@aladdin.com
+
+ */
+/*
+ Independent implementation of MD5 (RFC 1321).
+
+ This code implements the MD5 Algorithm defined in RFC 1321, whose
+ text is available at
+ http://www.ietf.org/rfc/rfc1321.txt
+ The code is derived from the text of the RFC, including the test suite
+ (section A.5) but excluding the rest of Appendix A. It does not include
+ any code or documentation that is identified in the RFC as being
+ copyrighted.
+
+ The original and principal author of md5.c is L. Peter Deutsch
+ <ghost@aladdin.com>. Other authors are noted in the change history
+ that follows (in reverse chronological order):
+
+ 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
+ either statically or dynamically; added missing #include <string.h>
+ in library.
+ 2002-03-11 lpd Corrected argument list for main(), and added int return
+ type, in test program and T value program.
+ 2002-02-21 lpd Added missing #include <stdio.h> in test program.
+ 2000-07-03 lpd Patched to eliminate warnings about "constant is
+ unsigned in ANSI C, signed in traditional"; made test program
+ self-checking.
+ 1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
+ 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
+ 1999-05-03 lpd Original version.
+ */
+
+/*
+ * This package supports both compile-time and run-time determination of CPU
+ * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be
+ * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is
+ * defined as non-zero, the code will be compiled to run only on big-endian
+ * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to
+ * run on either big- or little-endian CPUs, but will run slightly less
+ * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.
+ */
+
+typedef unsigned char md5_byte_t; /* 8-bit byte */
+typedef unsigned int md5_word_t; /* 32-bit word */
+
+/* Define the state of the MD5 Algorithm. */
+typedef struct md5_state_s {
+ md5_word_t count[2]; /* message length in bits, lsw first */
+ md5_word_t abcd[4]; /* digest buffer */
+ md5_byte_t buf[64]; /* accumulate block */
+} md5_state_t;
+
+#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */
+#ifdef ARCH_IS_BIG_ENDIAN
+# define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
+#else
+# define BYTE_ORDER 0
+#endif
+
+#define T_MASK ((md5_word_t)~0)
+#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
+#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
+#define T3 0x242070db
+#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
+#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
+#define T6 0x4787c62a
+#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
+#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
+#define T9 0x698098d8
+#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
+#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
+#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
+#define T13 0x6b901122
+#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
+#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
+#define T16 0x49b40821
+#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
+#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
+#define T19 0x265e5a51
+#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
+#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
+#define T22 0x02441453
+#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
+#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
+#define T25 0x21e1cde6
+#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
+#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
+#define T28 0x455a14ed
+#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
+#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
+#define T31 0x676f02d9
+#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
+#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
+#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
+#define T35 0x6d9d6122
+#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
+#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
+#define T38 0x4bdecfa9
+#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
+#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
+#define T41 0x289b7ec6
+#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
+#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
+#define T44 0x04881d05
+#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
+#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
+#define T47 0x1fa27cf8
+#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
+#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
+#define T50 0x432aff97
+#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
+#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
+#define T53 0x655b59c3
+#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
+#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
+#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
+#define T57 0x6fa87e4f
+#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
+#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
+#define T60 0x4e0811a1
+#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
+#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
+#define T63 0x2ad7d2bb
+#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
+
+
+static void
+md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
+{
+ md5_word_t
+ a = pms->abcd[0], b = pms->abcd[1],
+ c = pms->abcd[2], d = pms->abcd[3];
+ md5_word_t t;
+#if BYTE_ORDER > 0
+ /* Define storage only for big-endian CPUs. */
+ md5_word_t X[16];
+#else
+ /* Define storage for little-endian or both types of CPUs. */
+ md5_word_t xbuf[16];
+ const md5_word_t *X;
+#endif
+
+ {
+#if BYTE_ORDER == 0
+ /*
+ * Determine dynamically whether this is a big-endian or
+ * little-endian machine, since we can use a more efficient
+ * algorithm on the latter.
+ */
+ static const int w = 1;
+
+ if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
+#endif
+#if BYTE_ORDER <= 0 /* little-endian */
+ {
+ /*
+ * On little-endian machines, we can process properly aligned
+ * data without copying it.
+ */
+ if (!((data - (const md5_byte_t *)0) & 3)) {
+ /* data are properly aligned */
+ X = (const md5_word_t *)data;
+ } else {
+ /* not aligned */
+ memcpy(xbuf, data, 64);
+ X = xbuf;
+ }
+ }
+#endif
+#if BYTE_ORDER == 0
+ else /* dynamic big-endian */
+#endif
+#if BYTE_ORDER >= 0 /* big-endian */
+ {
+ /*
+ * On big-endian machines, we must arrange the bytes in the
+ * right order.
+ */
+ const md5_byte_t *xp = data;
+ int i;
+
+# if BYTE_ORDER == 0
+ X = xbuf; /* (dynamic only) */
+# else
+# define xbuf X /* (static only) */
+# endif
+ for (i = 0; i < 16; ++i, xp += 4)
+ xbuf[i] = (md5_word_t)(xp[0] + (xp[1] << 8) +
+ (xp[2] << 16) + (xp[3] << 24));
+ }
+#endif
+ }
+
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
+
+ /* Round 1. */
+ /* Let [abcd k s i] denote the operation
+ a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
+#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
+#define SET(a, b, c, d, k, s, Ti)\
+ t = a + F(b,c,d) + X[k] + Ti;\
+ a = ROTATE_LEFT(t, s) + b
+ /* Do the following 16 operations. */
+ SET(a, b, c, d, 0, 7, T1);
+ SET(d, a, b, c, 1, 12, T2);
+ SET(c, d, a, b, 2, 17, T3);
+ SET(b, c, d, a, 3, 22, T4);
+ SET(a, b, c, d, 4, 7, T5);
+ SET(d, a, b, c, 5, 12, T6);
+ SET(c, d, a, b, 6, 17, T7);
+ SET(b, c, d, a, 7, 22, T8);
+ SET(a, b, c, d, 8, 7, T9);
+ SET(d, a, b, c, 9, 12, T10);
+ SET(c, d, a, b, 10, 17, T11);
+ SET(b, c, d, a, 11, 22, T12);
+ SET(a, b, c, d, 12, 7, T13);
+ SET(d, a, b, c, 13, 12, T14);
+ SET(c, d, a, b, 14, 17, T15);
+ SET(b, c, d, a, 15, 22, T16);
+#undef SET
+
+ /* Round 2. */
+ /* Let [abcd k s i] denote the operation
+ a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
+#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
+#define SET(a, b, c, d, k, s, Ti)\
+ t = a + G(b,c,d) + X[k] + Ti;\
+ a = ROTATE_LEFT(t, s) + b
+ /* Do the following 16 operations. */
+ SET(a, b, c, d, 1, 5, T17);
+ SET(d, a, b, c, 6, 9, T18);
+ SET(c, d, a, b, 11, 14, T19);
+ SET(b, c, d, a, 0, 20, T20);
+ SET(a, b, c, d, 5, 5, T21);
+ SET(d, a, b, c, 10, 9, T22);
+ SET(c, d, a, b, 15, 14, T23);
+ SET(b, c, d, a, 4, 20, T24);
+ SET(a, b, c, d, 9, 5, T25);
+ SET(d, a, b, c, 14, 9, T26);
+ SET(c, d, a, b, 3, 14, T27);
+ SET(b, c, d, a, 8, 20, T28);
+ SET(a, b, c, d, 13, 5, T29);
+ SET(d, a, b, c, 2, 9, T30);
+ SET(c, d, a, b, 7, 14, T31);
+ SET(b, c, d, a, 12, 20, T32);
+#undef SET
+
+ /* Round 3. */
+ /* Let [abcd k s t] denote the operation
+ a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define SET(a, b, c, d, k, s, Ti)\
+ t = a + H(b,c,d) + X[k] + Ti;\
+ a = ROTATE_LEFT(t, s) + b
+ /* Do the following 16 operations. */
+ SET(a, b, c, d, 5, 4, T33);
+ SET(d, a, b, c, 8, 11, T34);
+ SET(c, d, a, b, 11, 16, T35);
+ SET(b, c, d, a, 14, 23, T36);
+ SET(a, b, c, d, 1, 4, T37);
+ SET(d, a, b, c, 4, 11, T38);
+ SET(c, d, a, b, 7, 16, T39);
+ SET(b, c, d, a, 10, 23, T40);
+ SET(a, b, c, d, 13, 4, T41);
+ SET(d, a, b, c, 0, 11, T42);
+ SET(c, d, a, b, 3, 16, T43);
+ SET(b, c, d, a, 6, 23, T44);
+ SET(a, b, c, d, 9, 4, T45);
+ SET(d, a, b, c, 12, 11, T46);
+ SET(c, d, a, b, 15, 16, T47);
+ SET(b, c, d, a, 2, 23, T48);
+#undef SET
+
+ /* Round 4. */
+ /* Let [abcd k s t] denote the operation
+ a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
+#define I(x, y, z) ((y) ^ ((x) | ~(z)))
+#define SET(a, b, c, d, k, s, Ti)\
+ t = a + I(b,c,d) + X[k] + Ti;\
+ a = ROTATE_LEFT(t, s) + b
+ /* Do the following 16 operations. */
+ SET(a, b, c, d, 0, 6, T49);
+ SET(d, a, b, c, 7, 10, T50);
+ SET(c, d, a, b, 14, 15, T51);
+ SET(b, c, d, a, 5, 21, T52);
+ SET(a, b, c, d, 12, 6, T53);
+ SET(d, a, b, c, 3, 10, T54);
+ SET(c, d, a, b, 10, 15, T55);
+ SET(b, c, d, a, 1, 21, T56);
+ SET(a, b, c, d, 8, 6, T57);
+ SET(d, a, b, c, 15, 10, T58);
+ SET(c, d, a, b, 6, 15, T59);
+ SET(b, c, d, a, 13, 21, T60);
+ SET(a, b, c, d, 4, 6, T61);
+ SET(d, a, b, c, 11, 10, T62);
+ SET(c, d, a, b, 2, 15, T63);
+ SET(b, c, d, a, 9, 21, T64);
+#undef SET
+
+ /* Then perform the following additions. (That is increment each
+ of the four registers by the value it had before this block
+ was started.) */
+ pms->abcd[0] += a;
+ pms->abcd[1] += b;
+ pms->abcd[2] += c;
+ pms->abcd[3] += d;
+}
+
+/* Initialize the algorithm. */
+static void md5_init(md5_state_t *pms)
+{
+ pms->count[0] = pms->count[1] = 0;
+ pms->abcd[0] = 0x67452301;
+ pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
+ pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
+ pms->abcd[3] = 0x10325476;
+}
+
+/* Append a string to the message. */
+static void md5_append(md5_state_t *pms, const md5_byte_t *data, size_t nbytes)
+{
+ const md5_byte_t *p = data;
+ size_t left = nbytes;
+ size_t offset = (pms->count[0] >> 3) & 63;
+ md5_word_t nbits = (md5_word_t)(nbytes << 3);
+
+ if (nbytes <= 0)
+ return;
+
+ /* Update the message length. */
+ pms->count[1] += (md5_word_t)(nbytes >> 29);
+ pms->count[0] += nbits;
+ if (pms->count[0] < nbits)
+ pms->count[1]++;
+
+ /* Process an initial partial block. */
+ if (offset) {
+ size_t copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
+
+ memcpy(pms->buf + offset, p, copy);
+ if (offset + copy < 64)
+ return;
+ p += copy;
+ left -= copy;
+ md5_process(pms, pms->buf);
+ }
+
+ /* Process full blocks. */
+ for (; left >= 64; p += 64, left -= 64)
+ md5_process(pms, p);
+
+ /* Process a final partial block. */
+ if (left)
+ memcpy(pms->buf, p, left);
+}
+
+/* Finish the message and return the digest. */
+static void md5_finish(md5_state_t *pms, md5_byte_t digest[16])
+{
+ static const md5_byte_t pad[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
+ };
+ md5_byte_t data[8];
+ int i;
+
+ /* Save the length before padding. */
+ for (i = 0; i < 8; ++i)
+ data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
+ /* Pad to 56 bytes mod 64. */
+ md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
+ /* Append the length. */
+ md5_append(pms, data, 8);
+ for (i = 0; i < 16; ++i)
+ digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
+}
+
+#if defined(__clang__)
+# pragma clang diagnostic pop
+#endif
+
+/*--------------------------------------------------------------------------*/
+/* Wrap up the MD5 state in our opaque structure. */
+struct kwsysMD5_s
+{
+ md5_state_t md5_state;
+};
+
+/*--------------------------------------------------------------------------*/
+kwsysMD5* kwsysMD5_New(void)
+{
+ /* Allocate a process control structure. */
+ kwsysMD5* md5 = (kwsysMD5*)malloc(sizeof(kwsysMD5));
+ if(!md5)
+ {
+ return 0;
+ }
+ return md5;
+}
+
+/*--------------------------------------------------------------------------*/
+void kwsysMD5_Delete(kwsysMD5* md5)
+{
+ /* Make sure we have an instance. */
+ if(!md5)
+ {
+ return;
+ }
+
+ /* Free memory. */
+ free(md5);
+}
+
+/*--------------------------------------------------------------------------*/
+void kwsysMD5_Initialize(kwsysMD5* md5)
+{
+ md5_init(&md5->md5_state);
+}
+
+/*--------------------------------------------------------------------------*/
+void kwsysMD5_Append(kwsysMD5* md5, unsigned char const* data, int length)
+{
+ if(length < 0)
+ {
+ length = (int)strlen((char const*)data);
+ }
+ md5_append(&md5->md5_state, (md5_byte_t const*)data, (size_t)length);
+}
+
+/*--------------------------------------------------------------------------*/
+void kwsysMD5_Finalize(kwsysMD5* md5, unsigned char digest[16])
+{
+ md5_finish(&md5->md5_state, (md5_byte_t*)digest);
+}
+
+/*--------------------------------------------------------------------------*/
+void kwsysMD5_FinalizeHex(kwsysMD5* md5, char buffer[32])
+{
+ unsigned char digest[16];
+ kwsysMD5_Finalize(md5, digest);
+ kwsysMD5_DigestToHex(digest, buffer);
+}
+
+/*--------------------------------------------------------------------------*/
+void kwsysMD5_DigestToHex(unsigned char const digest[16], char buffer[32])
+{
+ /* Map from 4-bit index to hexadecimal representation. */
+ static char const hex[16] =
+ {'0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+
+ /* Map each 4-bit block separately. */
+ char* out = buffer;
+ int i;
+ for(i=0; i < 16; ++i)
+ {
+ *out++ = hex[digest[i] >> 4];
+ *out++ = hex[digest[i] & 0xF];
+ }
+}
diff --git a/Source/kwsys/MD5.h.in b/Source/kwsys/MD5.h.in
new file mode 100644
index 000000000..33344317d
--- /dev/null
+++ b/Source/kwsys/MD5.h.in
@@ -0,0 +1,107 @@
+/*============================================================================
+ 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@_MD5_h
+#define @KWSYS_NAMESPACE@_MD5_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 kwsysMD5 kwsys_ns(MD5)
+# define kwsysMD5_s kwsys_ns(MD5_s)
+# define kwsysMD5_New kwsys_ns(MD5_New)
+# define kwsysMD5_Delete kwsys_ns(MD5_Delete)
+# define kwsysMD5_Initialize kwsys_ns(MD5_Initialize)
+# define kwsysMD5_Append kwsys_ns(MD5_Append)
+# define kwsysMD5_Finalize kwsys_ns(MD5_Finalize)
+# define kwsysMD5_FinalizeHex kwsys_ns(MD5_FinalizeHex)
+# define kwsysMD5_DigestToHex kwsys_ns(MD5_DigestToHex)
+#endif
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+/**
+ * MD5 state data structure.
+ */
+typedef struct kwsysMD5_s kwsysMD5;
+
+/**
+ * Create a new MD5 instance. The returned instance is not initialized.
+ */
+kwsysEXPORT kwsysMD5* kwsysMD5_New(void);
+
+/**
+ * Delete an old MD5 instance.
+ */
+kwsysEXPORT void kwsysMD5_Delete(kwsysMD5* md5);
+
+/**
+ * Initialize a new MD5 digest.
+ */
+kwsysEXPORT void kwsysMD5_Initialize(kwsysMD5* md5);
+
+/**
+ * Append data to an MD5 digest. If the given length is negative,
+ * data will be read up to but not including a terminating null.
+ */
+kwsysEXPORT void kwsysMD5_Append(kwsysMD5* md5, unsigned char const* data,
+ int length);
+
+/**
+ * Finalize a MD5 digest and get the 16-byte hash value.
+ */
+kwsysEXPORT void kwsysMD5_Finalize(kwsysMD5* md5, unsigned char digest[16]);
+
+/**
+ * Finalize a MD5 digest and get the 32-bit hexadecimal representation.
+ */
+kwsysEXPORT void kwsysMD5_FinalizeHex(kwsysMD5* md5, char buffer[32]);
+
+/**
+ * Convert a MD5 digest 16-byte value to a 32-byte hexadecimal representation.
+ */
+kwsysEXPORT void kwsysMD5_DigestToHex(unsigned char const digest[16],
+ char buffer[32]);
+
+#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 !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
+# undef kwsysMD5
+# undef kwsysMD5_s
+# undef kwsysMD5_New
+# undef kwsysMD5_Delete
+# undef kwsysMD5_Initialize
+# undef kwsysMD5_Append
+# undef kwsysMD5_Finalize
+# undef kwsysMD5_FinalizeHex
+# undef kwsysMD5_DigestToHex
+# endif
+#endif
+
+#endif
diff --git a/Source/kwsys/Process.h.in b/Source/kwsys/Process.h.in
new file mode 100644
index 000000000..c5995eac1
--- /dev/null
+++ b/Source/kwsys/Process.h.in
@@ -0,0 +1,428 @@
+/*============================================================================
+ 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@_Process_h
+#define @KWSYS_NAMESPACE@_Process_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 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)
+#endif
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+/**
+ * Process control data structure.
+ */
+typedef struct kwsysProcess_s kwsysProcess;
+
+/* Platform-specific pipe handle type. */
+#if defined(_WIN32) && !defined(__CYGWIN__)
+typedef void* kwsysProcess_Pipe_Handle;
+#else
+typedef int kwsysProcess_Pipe_Handle;
+#endif
+
+/**
+ * Create a new Process instance.
+ */
+kwsysEXPORT kwsysProcess* kwsysProcess_New(void);
+
+/**
+ * Delete an existing Process instance. If the instance is currently
+ * executing a process, this blocks until the process terminates.
+ */
+kwsysEXPORT void kwsysProcess_Delete(kwsysProcess* cp);
+
+/**
+ * Set the command line to be executed. Argument is an array of
+ * pointers to the command and each argument. The array must end with
+ * a NULL pointer. Any previous command lines are removed. Returns
+ * 1 for success and 0 otherwise.
+ */
+kwsysEXPORT int kwsysProcess_SetCommand(kwsysProcess* cp,
+ char const* const* command);
+
+/**
+ * Add a command line to be executed. Argument is an array of
+ * pointers to the command and each argument. The array must end with
+ * a NULL pointer. If this is not the first command added, its
+ * standard input will be connected to the standard output of the
+ * previous command. Returns 1 for success and 0 otherwise.
+ */
+kwsysEXPORT int kwsysProcess_AddCommand(kwsysProcess* cp,
+ char const* const* command);
+
+/**
+ * Set the timeout in seconds for the child process. The timeout
+ * period begins when the child is executed. If the child has not
+ * terminated when the timeout expires, it will be killed. A
+ * non-positive (<= 0) value will disable the timeout.
+ */
+kwsysEXPORT void kwsysProcess_SetTimeout(kwsysProcess* cp, double timeout);
+
+/**
+ * Set the working directory for the child process. The working
+ * directory can be absolute or relative to the current directory.
+ * Returns 1 for success and 0 for failure.
+ */
+kwsysEXPORT int kwsysProcess_SetWorkingDirectory(kwsysProcess* cp,
+ const char* dir);
+
+/**
+ * Set the name of a file to be attached to the given pipe. Returns 1
+ * for success and 0 for failure.
+ */
+kwsysEXPORT int kwsysProcess_SetPipeFile(kwsysProcess* cp, int pipe,
+ const char* file);
+
+/**
+ * Set whether the given pipe in the child is shared with the parent
+ * process. The default is no for Pipe_STDOUT and Pipe_STDERR and yes
+ * for Pipe_STDIN.
+ */
+kwsysEXPORT void kwsysProcess_SetPipeShared(kwsysProcess* cp, int pipe,
+ int shared);
+
+/**
+ * Specify a platform-specific native pipe for use as one of the child
+ * interface pipes. The native pipe is specified by an array of two
+ * descriptors or handles. The first entry in the array (index 0)
+ * should be the read end of the pipe. The second entry in the array
+ * (index 1) should be the write end of the pipe. If a null pointer
+ * is given the option will be disabled.
+ *
+ * For Pipe_STDIN the native pipe is connected to the first child in
+ * the pipeline as its stdin. After the children are created the
+ * write end of the pipe will be closed in the child process and the
+ * read end will be closed in the parent process.
+ *
+ * For Pipe_STDOUT and Pipe_STDERR the pipe is connected to the last
+ * child as its stdout or stderr. After the children are created the
+ * write end of the pipe will be closed in the parent process and the
+ * read end will be closed in the child process.
+ */
+kwsysEXPORT void kwsysProcess_SetPipeNative(kwsysProcess* cp, int pipe,
+ kwsysProcess_Pipe_Handle p[2]);
+
+/**
+ * Get/Set a possibly platform-specific option. Possible options are:
+ *
+ * kwsysProcess_Option_Detach = Whether to detach the process.
+ * 0 = No (default)
+ * 1 = Yes
+ *
+ * kwsysProcess_Option_HideWindow = Whether to hide window on Windows.
+ * 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
+ */
+kwsysEXPORT int kwsysProcess_GetOption(kwsysProcess* cp, int optionId);
+kwsysEXPORT void kwsysProcess_SetOption(kwsysProcess* cp, int optionId,
+ int value);
+enum kwsysProcess_Option_e
+{
+ kwsysProcess_Option_HideWindow,
+ kwsysProcess_Option_Detach,
+ kwsysProcess_Option_Verbatim
+};
+
+/**
+ * Get the current state of the Process instance. Possible states are:
+ *
+ * kwsysProcess_State_Starting = Execute has not yet been called.
+ * kwsysProcess_State_Error = Error administrating the child process.
+ * kwsysProcess_State_Exception = Child process exited abnormally.
+ * kwsysProcess_State_Executing = Child process is currently running.
+ * kwsysProcess_State_Exited = Child process exited normally.
+ * kwsysProcess_State_Expired = Child process's timeout expired.
+ * kwsysProcess_State_Killed = Child process terminated by Kill method.
+ * kwsysProcess_State_Disowned = Child is no longer managed by this object.
+ */
+kwsysEXPORT int kwsysProcess_GetState(kwsysProcess* cp);
+enum kwsysProcess_State_e
+{
+ kwsysProcess_State_Starting,
+ kwsysProcess_State_Error,
+ kwsysProcess_State_Exception,
+ kwsysProcess_State_Executing,
+ kwsysProcess_State_Exited,
+ kwsysProcess_State_Expired,
+ kwsysProcess_State_Killed,
+ kwsysProcess_State_Disowned
+};
+
+/**
+ * When GetState returns "Exception", this method returns a
+ * platform-independent description of the exceptional behavior that
+ * caused the child to terminate abnormally. Possible exceptions are:
+ *
+ * kwsysProcess_Exception_None = No exceptional behavior occurred.
+ * kwsysProcess_Exception_Fault = Child crashed with a memory fault.
+ * kwsysProcess_Exception_Illegal = Child crashed with an illegal instruction.
+ * kwsysProcess_Exception_Interrupt = Child was interrupted by user (Cntl-C/Break).
+ * kwsysProcess_Exception_Numerical = Child crashed with a numerical exception.
+ * kwsysProcess_Exception_Other = Child terminated for another reason.
+ */
+kwsysEXPORT int kwsysProcess_GetExitException(kwsysProcess* cp);
+enum kwsysProcess_Exception_e
+{
+ kwsysProcess_Exception_None,
+ kwsysProcess_Exception_Fault,
+ kwsysProcess_Exception_Illegal,
+ kwsysProcess_Exception_Interrupt,
+ kwsysProcess_Exception_Numerical,
+ kwsysProcess_Exception_Other
+};
+
+/**
+ * When GetState returns "Exited" or "Exception", this method returns
+ * the platform-specific raw exit code of the process. UNIX platforms
+ * should use WIFEXITED/WEXITSTATUS and WIFSIGNALED/WTERMSIG to access
+ * this value. Windows users should compare the value to the various
+ * EXCEPTION_* values.
+ *
+ * If GetState returns "Exited", use GetExitValue to get the
+ * platform-independent child return value.
+ */
+kwsysEXPORT int kwsysProcess_GetExitCode(kwsysProcess* cp);
+
+/**
+ * When GetState returns "Exited", this method returns the child's
+ * platform-independent exit code (such as the value returned by the
+ * child's main).
+ */
+kwsysEXPORT int kwsysProcess_GetExitValue(kwsysProcess* cp);
+
+/**
+ * When GetState returns "Error", this method returns a string
+ * describing the problem. Otherwise, it returns NULL.
+ */
+kwsysEXPORT const char* kwsysProcess_GetErrorString(kwsysProcess* cp);
+
+/**
+ * When GetState returns "Exception", this method returns a string
+ * describing the problem. Otherwise, it returns NULL.
+ */
+kwsysEXPORT const char* kwsysProcess_GetExceptionString(kwsysProcess* cp);
+
+/**
+ * Start executing the child process.
+ */
+kwsysEXPORT void kwsysProcess_Execute(kwsysProcess* cp);
+
+/**
+ * Stop management of a detached child process. This closes any pipes
+ * being read. If the child was not created with the
+ * kwsysProcess_Option_Detach option, this method does nothing. This
+ * is because disowning a non-detached process will cause the child
+ * exit signal to be left unhandled until this process exits.
+ */
+kwsysEXPORT void kwsysProcess_Disown(kwsysProcess* cp);
+
+/**
+ * Block until data are available on a pipe, a timeout expires, or the
+ * child process terminates. Arguments are as follows:
+ *
+ * data = If data are read, the pointer to which this points is
+ * set to point to the data.
+ * length = If data are read, the integer to which this points is
+ * set to the length of the data read.
+ * timeout = Specifies the maximum time this call may block. Upon
+ * return after reading data, the time elapsed is subtracted
+ * from the timeout value. If this timeout expires, the
+ * value is set to 0. A NULL pointer passed for this argument
+ * indicates no timeout for the call. A negative or zero
+ * value passed for this argument may be used for polling
+ * and will always return immediately.
+ *
+ * Return value will be one of:
+ *
+ * Pipe_None = No more data will be available from the child process,
+ * ( == 0) or no process has been executed. WaitForExit should
+ * be called to wait for the process to terminate.
+ * Pipe_STDOUT = Data have been read from the child's stdout pipe.
+ * Pipe_STDERR = Data have been read from the child's stderr pipe.
+ * Pipe_Timeout = No data available within timeout specified for the
+ * call. Time elapsed has been subtracted from timeout
+ * argument.
+ */
+kwsysEXPORT int kwsysProcess_WaitForData(kwsysProcess* cp, char** data,
+ int* length, double* timeout);
+enum kwsysProcess_Pipes_e
+{
+ kwsysProcess_Pipe_None,
+ kwsysProcess_Pipe_STDIN,
+ kwsysProcess_Pipe_STDOUT,
+ kwsysProcess_Pipe_STDERR,
+ kwsysProcess_Pipe_Timeout=255
+};
+
+/**
+ * Block until the child process terminates or the given timeout
+ * expires. If no process is running, returns immediatly. The
+ * argument is:
+ *
+ * timeout = Specifies the maximum time this call may block. Upon
+ * returning due to child termination, the elapsed time
+ * is subtracted from the given value. A NULL pointer
+ * passed for this argument indicates no timeout for the
+ * call.
+ *
+ * Return value will be one of:
+ *
+ * 0 = Child did not terminate within timeout specified for
+ * the call. Time elapsed has been subtracted from timeout
+ * argument.
+ * 1 = Child has terminated or was not running.
+ */
+kwsysEXPORT int kwsysProcess_WaitForExit(kwsysProcess* cp, double* timeout);
+
+/**
+ * Forcefully terminate the child process that is currently running.
+ * The caller should call WaitForExit after this returns to wait for
+ * the child to terminate.
+ */
+kwsysEXPORT void kwsysProcess_Kill(kwsysProcess* cp);
+
+#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 !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
+# undef kwsysProcess
+# undef kwsysProcess_s
+# undef kwsysProcess_New
+# undef kwsysProcess_Delete
+# undef kwsysProcess_SetCommand
+# undef kwsysProcess_AddCommand
+# undef kwsysProcess_SetTimeout
+# undef kwsysProcess_SetWorkingDirectory
+# undef kwsysProcess_SetPipeFile
+# undef kwsysProcess_SetPipeNative
+# undef kwsysProcess_SetPipeShared
+# undef kwsysProcess_Option_Detach
+# undef kwsysProcess_Option_HideWindow
+# undef kwsysProcess_Option_Verbatim
+# undef kwsysProcess_GetOption
+# undef kwsysProcess_SetOption
+# undef kwsysProcess_Option_e
+# undef kwsysProcess_State_Starting
+# undef kwsysProcess_State_Error
+# undef kwsysProcess_State_Exception
+# undef kwsysProcess_State_Executing
+# undef kwsysProcess_State_Exited
+# undef kwsysProcess_State_Expired
+# undef kwsysProcess_State_Killed
+# undef kwsysProcess_State_Disowned
+# undef kwsysProcess_GetState
+# undef kwsysProcess_State_e
+# undef kwsysProcess_Exception_None
+# undef kwsysProcess_Exception_Fault
+# undef kwsysProcess_Exception_Illegal
+# undef kwsysProcess_Exception_Interrupt
+# undef kwsysProcess_Exception_Numerical
+# undef kwsysProcess_Exception_Other
+# undef kwsysProcess_GetExitException
+# undef kwsysProcess_Exception_e
+# undef kwsysProcess_GetExitCode
+# undef kwsysProcess_GetExitValue
+# undef kwsysProcess_GetErrorString
+# undef kwsysProcess_GetExceptionString
+# undef kwsysProcess_Execute
+# undef kwsysProcess_Disown
+# undef kwsysProcess_WaitForData
+# undef kwsysProcess_Pipes_e
+# undef kwsysProcess_Pipe_None
+# undef kwsysProcess_Pipe_STDIN
+# undef kwsysProcess_Pipe_STDOUT
+# undef kwsysProcess_Pipe_STDERR
+# undef kwsysProcess_Pipe_Timeout
+# undef kwsysProcess_Pipe_Handle
+# undef kwsysProcess_WaitForExit
+# undef kwsysProcess_Kill
+# endif
+#endif
+
+#endif
diff --git a/Source/kwsys/ProcessFwd9x.c b/Source/kwsys/ProcessFwd9x.c
new file mode 100644
index 000000000..536c54b67
--- /dev/null
+++ b/Source/kwsys/ProcessFwd9x.c
@@ -0,0 +1,211 @@
+/*============================================================================
+ 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.
+============================================================================*/
+
+/*
+ On Windows9x platforms, this executable is spawned between a parent
+ process and the child it is invoking to work around a bug. See the
+ Win32 implementation file for details.
+
+ Future Work: This executable must be linked statically against the C
+ runtime library before being encoded into the library. Building it
+ in this way may be hard because CMake has limited abilities to build
+ different targets with different configurations in the same
+ directory. We may just have to create and encode the executable
+ once instead of generating it during the build. This would be an
+ acceptable solution because the forwarding executable should not
+ change very often and is pretty simple.
+*/
+
+#ifdef _MSC_VER
+#pragma warning (push, 1)
+#endif
+#include <windows.h>
+#include <stdio.h>
+
+void ReportLastError(HANDLE errorPipe);
+
+int main()
+{
+ /* Process startup information for the real child. */
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
+
+ /* The result of waiting for the child to exit. */
+ DWORD waitResult;
+
+ /* The child's process return code. */
+ DWORD retVal;
+
+ /* The command line used to invoke this process. */
+ LPSTR commandLine = GetCommandLine();
+
+ /* Pointer that will be advanced to the beginning of the command
+ line of the real child process. */
+ LPSTR cmdLine = commandLine;
+
+ /* Handle to the error reporting pipe provided by the parent. This
+ is parsed off the command line. */
+ HANDLE errorPipe = 0;
+ HANDLE errorPipeOrig = 0;
+
+ /* Handle to the event the parent uses to tell us to resume the child.
+ This is parsed off the command line. */
+ HANDLE resumeEvent = 0;
+
+ /* Handle to the event the parent uses to tell us to kill the child.
+ This is parsed off the command line. */
+ HANDLE killEvent = 0;
+
+ /* Flag for whether to hide window of child process. */
+ int hideWindow = 0;
+
+ /* An array of the handles on which we wait when the child is
+ running. */
+ HANDLE waitHandles[2] = {0, 0};
+
+ /* Move the pointer past the name of this executable. */
+ if(*cmdLine == '"')
+ {
+ ++cmdLine;
+ while(*cmdLine && *cmdLine != '"') { ++cmdLine; }
+ if(*cmdLine) { ++cmdLine; }
+ }
+ else
+ {
+ while(*cmdLine && *cmdLine != ' ') { ++cmdLine; }
+ }
+
+ /* Parse the error pipe handle. */
+ while(*cmdLine && *cmdLine == ' ') { ++cmdLine; }
+ sscanf(cmdLine, "%p", &errorPipeOrig);
+
+ /* Parse the resume event handle. */
+ while(*cmdLine && *cmdLine != ' ') { ++cmdLine; }
+ while(*cmdLine && *cmdLine == ' ') { ++cmdLine; }
+ sscanf(cmdLine, "%p", &resumeEvent);
+
+ /* Parse the kill event handle. */
+ while(*cmdLine && *cmdLine != ' ') { ++cmdLine; }
+ while(*cmdLine && *cmdLine == ' ') { ++cmdLine; }
+ sscanf(cmdLine, "%p", &killEvent);
+
+ /* Parse the hide window flag. */
+ while(*cmdLine && *cmdLine != ' ') { ++cmdLine; }
+ while(*cmdLine && *cmdLine == ' ') { ++cmdLine; }
+ sscanf(cmdLine, "%d", &hideWindow);
+
+ /* Skip to the beginning of the command line of the real child. */
+ while(*cmdLine && *cmdLine != ' ') { ++cmdLine; }
+ while(*cmdLine && *cmdLine == ' ') { ++cmdLine; }
+
+ /* Create a non-inherited copy of the error pipe. We do not want
+ the child to get it. */
+ if(DuplicateHandle(GetCurrentProcess(), errorPipeOrig,
+ GetCurrentProcess(), &errorPipe,
+ 0, FALSE, DUPLICATE_SAME_ACCESS))
+ {
+ /* Have a non-inherited duplicate. Close the inherited one. */
+ CloseHandle(errorPipeOrig);
+ }
+ else
+ {
+ /* Could not duplicate handle. Report the error. */
+ ReportLastError(errorPipeOrig);
+ return 1;
+ }
+
+ /* Create the subprocess. */
+ ZeroMemory(&si, sizeof(si));
+ ZeroMemory(&pi, sizeof(pi));
+ si.cb = sizeof(si);
+ si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
+ si.wShowWindow = hideWindow?SW_HIDE:SW_SHOWDEFAULT;
+ si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
+ si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
+ si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
+ if(CreateProcess(0, cmdLine, 0, 0, TRUE, CREATE_SUSPENDED, 0, 0, &si, &pi))
+ {
+ /* Process created successfully. Close the error reporting pipe
+ to notify the parent of success. */
+ CloseHandle(errorPipe);
+ }
+ else
+ {
+ /* Error creating the process. Report the error to the parent
+ process through the special error reporting pipe. */
+ ReportLastError(errorPipe);
+ return 1;
+ }
+
+ /* Wait for resume or kill event from parent. */
+ waitHandles[0] = killEvent;
+ waitHandles[1] = resumeEvent;
+ waitResult = WaitForMultipleObjects(2, waitHandles, 0, INFINITE);
+
+ /* Check what happened. */
+ if(waitResult == WAIT_OBJECT_0)
+ {
+ /* We were asked to kill the child. */
+ TerminateProcess(pi.hProcess, 255);
+ WaitForSingleObject(pi.hProcess, INFINITE);
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
+ return 1;
+ }
+ else
+ {
+ /* We were asked to resume the child. */
+ ResumeThread(pi.hThread);
+ CloseHandle(pi.hThread);
+ }
+
+ /* Wait for subprocess to exit or for kill event from parent. */
+ waitHandles[0] = killEvent;
+ waitHandles[1] = pi.hProcess;
+ waitResult = WaitForMultipleObjects(2, waitHandles, 0, INFINITE);
+
+ /* Check what happened. */
+ if(waitResult == WAIT_OBJECT_0)
+ {
+ /* We were asked to kill the child. */
+ TerminateProcess(pi.hProcess, 255);
+ WaitForSingleObject(pi.hProcess, INFINITE);
+ CloseHandle(pi.hProcess);
+ return 1;
+ }
+ else
+ {
+ /* The child exited. Get the return code. */
+ GetExitCodeProcess(pi.hProcess, &retVal);
+ CloseHandle(pi.hProcess);
+ return retVal;
+ }
+}
+
+void ReportLastError(HANDLE errorPipe)
+{
+ LPVOID lpMsgBuf;
+ DWORD n;
+ 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
+ );
+ WriteFile(errorPipe, lpMsgBuf, strlen(lpMsgBuf)+1, &n, 0);
+ LocalFree( lpMsgBuf );
+}
diff --git a/Source/kwsys/ProcessUNIX.c b/Source/kwsys/ProcessUNIX.c
new file mode 100644
index 000000000..9c66a4486
--- /dev/null
+++ b/Source/kwsys/ProcessUNIX.c
@@ -0,0 +1,2753 @@
+/*============================================================================
+ 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(Process.h)
+#include KWSYS_HEADER(System.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"
+#endif
+
+/*
+
+Implementation for UNIX
+
+On UNIX, a child process is forked to exec the program. Three output
+pipes are read by the parent process using a select call to block
+until data are ready. Two of the pipes are stdout and stderr for the
+child. The third is a special pipe populated by a signal handler to
+indicate that a child has terminated. This is used in conjunction
+with the timeout on the select call to implement a timeout for program
+even when it closes stdout and stderr and at the same time avoiding
+races.
+
+*/
+
+
+/*
+
+TODO:
+
+We cannot create the pipeline of processes in suspended states. How
+do we cleanup processes already started when one fails to load? Right
+now we are just killing them, which is probably not the right thing to
+do.
+
+*/
+
+#include <stddef.h> /* ptrdiff_t */
+#include <stdio.h> /* snprintf */
+#include <stdlib.h> /* malloc, free */
+#include <string.h> /* strdup, strerror, memset */
+#include <sys/time.h> /* struct timeval */
+#include <sys/types.h> /* pid_t, fd_set */
+#include <sys/wait.h> /* waitpid */
+#include <sys/stat.h> /* open mode */
+#include <unistd.h> /* pipe, close, fork, execvp, select, _exit */
+#include <fcntl.h> /* fcntl */
+#include <errno.h> /* errno */
+#include <time.h> /* gettimeofday */
+#include <signal.h> /* sigaction */
+#include <dirent.h> /* DIR, dirent */
+#include <ctype.h> /* isspace */
+
+#ifdef __HAIKU__
+#undef __BEOS__
+#endif
+
+#if defined(__VMS)
+# define KWSYSPE_VMS_NONBLOCK , O_NONBLOCK
+#else
+# define KWSYSPE_VMS_NONBLOCK
+#endif
+
+#if defined(KWSYS_C_HAS_PTRDIFF_T) && KWSYS_C_HAS_PTRDIFF_T
+typedef ptrdiff_t kwsysProcess_ptrdiff_t;
+#else
+typedef int kwsysProcess_ptrdiff_t;
+#endif
+
+#if defined(KWSYS_C_HAS_SSIZE_T) && KWSYS_C_HAS_SSIZE_T
+typedef ssize_t kwsysProcess_ssize_t;
+#else
+typedef int kwsysProcess_ssize_t;
+#endif
+
+#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)
+{
+ snooze(msec);
+}
+#else
+# define kwsysProcess_usleep usleep
+#endif
+
+/*
+ * BeOS's select() works like WinSock: it's for networking only, and
+ * doesn't work with Unix file handles...socket and file handles are
+ * different namespaces (the same descriptor means different things in
+ * each context!)
+ *
+ * So on Unix-like systems where select() is flakey, we'll set the
+ * pipes' file handles to be non-blocking and just poll them directly
+ * without select().
+ */
+#if !defined(__BEOS__) && !defined(__VMS)
+# define KWSYSPE_USE_SELECT 1
+#endif
+
+/* Some platforms do not have siginfo on their signal handlers. */
+#if defined(SA_SIGINFO) && !defined(__BEOS__)
+# define KWSYSPE_USE_SIGINFO 1
+#endif
+
+/* The number of pipes for the child's output. The standard stdout
+ and stderr pipes are the first two. One more pipe is used to
+ detect when the child process has terminated. The third pipe is
+ not given to the child process, so it cannot close it until it
+ terminates. */
+#define KWSYSPE_PIPE_COUNT 3
+#define KWSYSPE_PIPE_STDOUT 0
+#define KWSYSPE_PIPE_STDERR 1
+#define KWSYSPE_PIPE_SIGNAL 2
+
+/* The maximum amount to read from a pipe at a time. */
+#define KWSYSPE_PIPE_BUFFER_SIZE 1024
+
+/* Keep track of times using a signed representation. Switch to the
+ native (possibly unsigned) representation only when calling native
+ functions. */
+typedef struct timeval kwsysProcessTimeNative;
+typedef struct kwsysProcessTime_s kwsysProcessTime;
+struct kwsysProcessTime_s
+{
+ long tv_sec;
+ long tv_usec;
+};
+
+typedef struct kwsysProcessCreateInformation_s
+{
+ int StdIn;
+ int StdOut;
+ int StdErr;
+ int ErrorPipe[2];
+} kwsysProcessCreateInformation;
+
+/*--------------------------------------------------------------------------*/
+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);
+static void kwsysProcessDestroy(kwsysProcess* cp);
+static int kwsysProcessSetupOutputPipeFile(int* p, const char* name);
+static int kwsysProcessSetupOutputPipeNative(int* p, int des[2]);
+static int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout,
+ kwsysProcessTime* timeoutTime);
+static int kwsysProcessGetTimeoutLeft(kwsysProcessTime* timeoutTime,
+ double* userTimeout,
+ kwsysProcessTimeNative* timeoutLength,
+ int zeroIsExpired);
+static kwsysProcessTime kwsysProcessTimeGetCurrent(void);
+static double kwsysProcessTimeToDouble(kwsysProcessTime t);
+static kwsysProcessTime kwsysProcessTimeFromDouble(double d);
+static int kwsysProcessTimeLess(kwsysProcessTime in1, kwsysProcessTime in2);
+static kwsysProcessTime kwsysProcessTimeAdd(kwsysProcessTime in1, kwsysProcessTime in2);
+static kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1, kwsysProcessTime in2);
+static void kwsysProcessSetExitException(kwsysProcess* cp, int sig);
+static void kwsysProcessChildErrorExit(int errorPipe);
+static void kwsysProcessRestoreDefaultSignalHandlers(void);
+static pid_t kwsysProcessFork(kwsysProcess* cp,
+ kwsysProcessCreateInformation* si);
+static void kwsysProcessKill(pid_t process_id);
+#if defined(__VMS)
+static int kwsysProcessSetVMSFeature(const char* name, int value);
+#endif
+static int kwsysProcessesAdd(kwsysProcess* cp);
+static void kwsysProcessesRemove(kwsysProcess* cp);
+#if KWSYSPE_USE_SIGINFO
+static void kwsysProcessesSignalHandler(int signum, siginfo_t* info,
+ void* ucontext);
+#else
+static void kwsysProcessesSignalHandler(int signum);
+#endif
+
+/*--------------------------------------------------------------------------*/
+/* Structure containing data used to implement the child's execution. */
+struct kwsysProcess_s
+{
+ /* The command lines to execute. */
+ char*** Commands;
+ int NumberOfCommands;
+
+ /* Descriptors for the read ends of the child's output pipes and
+ the signal pipe. */
+ int PipeReadEnds[KWSYSPE_PIPE_COUNT];
+
+ /* 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;
+
+ /* Flag for whether the children were terminated by a faild select. */
+ int SelectError;
+
+ /* The timeout length. */
+ double Timeout;
+
+ /* The working directory for the process. */
+ char* WorkingDirectory;
+
+ /* Whether to create the child as a detached process. */
+ int OptionDetach;
+
+ /* Whether the child was created as a detached process. */
+ int Detached;
+
+ /* Whether to treat command lines as verbatim. */
+ int Verbatim;
+
+ /* Time at which the child started. Negative for no timeout. */
+ kwsysProcessTime StartTime;
+
+ /* Time at which the child will timeout. Negative for no timeout. */
+ kwsysProcessTime TimeoutTime;
+
+ /* Flag for whether the timeout expired. */
+ int TimeoutExpired;
+
+ /* The number of pipes left open during execution. */
+ int PipesLeft;
+
+#if KWSYSPE_USE_SELECT
+ /* File descriptor set for call to select. */
+ fd_set PipeSet;
+#endif
+
+ /* The number of children still executing. */
+ int CommandsLeft;
+
+ /* The current status of the child process. */
+ int State;
+
+ /* The exceptional behavior that terminated the child process, if
+ * any. */
+ int ExitException;
+
+ /* The exit code of the child process. */
+ int ExitCode;
+
+ /* The exit value of the child process, if any. */
+ int ExitValue;
+
+ /* Whether the process was killed. */
+ int Killed;
+
+ /* Buffer for error message in case of failure. */
+ char ErrorMessage[KWSYSPE_PIPE_BUFFER_SIZE+1];
+
+ /* Description for the ExitException. */
+ char ExitExceptionString[KWSYSPE_PIPE_BUFFER_SIZE+1];
+
+ /* The exit codes of each child process in the pipeline. */
+ int* CommandExitCodes;
+
+ /* Name of files to which stdin and stdout pipes are attached. */
+ char* PipeFileSTDIN;
+ char* PipeFileSTDOUT;
+ char* PipeFileSTDERR;
+
+ /* Whether each pipe is shared with the parent process. */
+ int PipeSharedSTDIN;
+ int PipeSharedSTDOUT;
+ int PipeSharedSTDERR;
+
+ /* Native pipes provided by the user. */
+ int PipeNativeSTDIN[2];
+ int PipeNativeSTDOUT[2];
+ int PipeNativeSTDERR[2];
+
+ /* The real working directory of this process. */
+ int RealWorkingDirectoryLength;
+ char* RealWorkingDirectory;
+};
+
+/*--------------------------------------------------------------------------*/
+kwsysProcess* kwsysProcess_New(void)
+{
+ /* Allocate a process control structure. */
+ kwsysProcess* cp = (kwsysProcess*)malloc(sizeof(kwsysProcess));
+ if(!cp)
+ {
+ return 0;
+ }
+ memset(cp, 0, sizeof(kwsysProcess));
+
+ /* Share stdin with the parent process by default. */
+ cp->PipeSharedSTDIN = 1;
+
+ /* No native pipes by default. */
+ cp->PipeNativeSTDIN[0] = -1;
+ cp->PipeNativeSTDIN[1] = -1;
+ cp->PipeNativeSTDOUT[0] = -1;
+ cp->PipeNativeSTDOUT[1] = -1;
+ cp->PipeNativeSTDERR[0] = -1;
+ cp->PipeNativeSTDERR[1] = -1;
+
+ /* Set initial status. */
+ cp->State = kwsysProcess_State_Starting;
+
+ return cp;
+}
+
+/*--------------------------------------------------------------------------*/
+void kwsysProcess_Delete(kwsysProcess* cp)
+{
+ /* Make sure we have an instance. */
+ if(!cp)
+ {
+ return;
+ }
+
+ /* If the process is executing, wait for it to finish. */
+ if(cp->State == kwsysProcess_State_Executing)
+ {
+ if(cp->Detached)
+ {
+ kwsysProcess_Disown(cp);
+ }
+ else
+ {
+ kwsysProcess_WaitForExit(cp, 0);
+ }
+ }
+
+ /* Free memory. */
+ kwsysProcess_SetCommand(cp, 0);
+ kwsysProcess_SetWorkingDirectory(cp, 0);
+ kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDIN, 0);
+ kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDOUT, 0);
+ kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDERR, 0);
+ if(cp->CommandExitCodes)
+ {
+ free(cp->CommandExitCodes);
+ }
+ free(cp);
+}
+
+/*--------------------------------------------------------------------------*/
+int kwsysProcess_SetCommand(kwsysProcess* cp, char const* const* command)
+{
+ int i;
+ if(!cp)
+ {
+ return 0;
+ }
+ for(i=0; i < cp->NumberOfCommands; ++i)
+ {
+ char** c = cp->Commands[i];
+ while(*c)
+ {
+ free(*c++);
+ }
+ free(cp->Commands[i]);
+ }
+ cp->NumberOfCommands = 0;
+ if(cp->Commands)
+ {
+ free(cp->Commands);
+ cp->Commands = 0;
+ }
+ if(command)
+ {
+ return kwsysProcess_AddCommand(cp, command);
+ }
+ return 1;
+}
+
+/*--------------------------------------------------------------------------*/
+int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command)
+{
+ int newNumberOfCommands;
+ char*** newCommands;
+
+ /* Make sure we have a command to add. */
+ if(!cp || !command || !*command)
+ {
+ return 0;
+ }
+
+ /* Allocate a new array for command pointers. */
+ newNumberOfCommands = cp->NumberOfCommands + 1;
+ if(!(newCommands =
+ (char***)malloc(sizeof(char**) *(size_t)(newNumberOfCommands))))
+ {
+ /* Out of memory. */
+ return 0;
+ }
+
+ /* Copy any existing commands into the new array. */
+ {
+ int i;
+ for(i=0; i < cp->NumberOfCommands; ++i)
+ {
+ newCommands[i] = cp->Commands[i];
+ }
+ }
+
+ /* Add the new command. */
+ if(cp->Verbatim)
+ {
+ /* In order to run the given command line verbatim we need to
+ parse it. */
+ newCommands[cp->NumberOfCommands] =
+ kwsysSystem_Parse_CommandForUnix(*command, 0);
+ if(!newCommands[cp->NumberOfCommands])
+ {
+ /* Out of memory. */
+ free(newCommands);
+ return 0;
+ }
+ }
+ else
+ {
+ /* Copy each argument string individually. */
+ char const* const* c = command;
+ kwsysProcess_ptrdiff_t n = 0;
+ kwsysProcess_ptrdiff_t i = 0;
+ while(*c++);
+ n = c - command - 1;
+ newCommands[cp->NumberOfCommands] =
+ (char**)malloc((size_t)(n+1)*sizeof(char*));
+ if(!newCommands[cp->NumberOfCommands])
+ {
+ /* Out of memory. */
+ free(newCommands);
+ return 0;
+ }
+ for(i=0; i < n; ++i)
+ {
+ newCommands[cp->NumberOfCommands][i] = strdup(command[i]);
+ if(!newCommands[cp->NumberOfCommands][i])
+ {
+ break;
+ }
+ }
+ if(i < n)
+ {
+ /* Out of memory. */
+ for(;i > 0; --i)
+ {
+ free(newCommands[cp->NumberOfCommands][i-1]);
+ }
+ free(newCommands);
+ return 0;
+ }
+ newCommands[cp->NumberOfCommands][n] = 0;
+ }
+
+ /* Successfully allocated new command array. Free the old array. */
+ free(cp->Commands);
+ cp->Commands = newCommands;
+ cp->NumberOfCommands = newNumberOfCommands;
+
+ return 1;
+}
+
+/*--------------------------------------------------------------------------*/
+void kwsysProcess_SetTimeout(kwsysProcess* cp, double timeout)
+{
+ if(!cp)
+ {
+ return;
+ }
+ cp->Timeout = timeout;
+ if(cp->Timeout < 0)
+ {
+ cp->Timeout = 0;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+int kwsysProcess_SetWorkingDirectory(kwsysProcess* cp, const char* dir)
+{
+ if(!cp)
+ {
+ return 0;
+ }
+ if(cp->WorkingDirectory == dir)
+ {
+ return 1;
+ }
+ if(cp->WorkingDirectory && dir && strcmp(cp->WorkingDirectory, dir) == 0)
+ {
+ return 1;
+ }
+ if(cp->WorkingDirectory)
+ {
+ free(cp->WorkingDirectory);
+ cp->WorkingDirectory = 0;
+ }
+ if(dir)
+ {
+ cp->WorkingDirectory = (char*)malloc(strlen(dir) + 1);
+ if(!cp->WorkingDirectory)
+ {
+ return 0;
+ }
+ strcpy(cp->WorkingDirectory, dir);
+ }
+ return 1;
+}
+
+/*--------------------------------------------------------------------------*/
+int kwsysProcess_SetPipeFile(kwsysProcess* cp, int prPipe, const char* file)
+{
+ char** pfile;
+ if(!cp)
+ {
+ return 0;
+ }
+ switch(prPipe)
+ {
+ case kwsysProcess_Pipe_STDIN: pfile = &cp->PipeFileSTDIN; break;
+ case kwsysProcess_Pipe_STDOUT: pfile = &cp->PipeFileSTDOUT; break;
+ case kwsysProcess_Pipe_STDERR: pfile = &cp->PipeFileSTDERR; break;
+ default: return 0;
+ }
+ if(*pfile)
+ {
+ free(*pfile);
+ *pfile = 0;
+ }
+ if(file)
+ {
+ *pfile = malloc(strlen(file)+1);
+ if(!*pfile)
+ {
+ return 0;
+ }
+ strcpy(*pfile, file);
+ }
+
+ /* If we are redirecting the pipe, do not share it or use a native
+ pipe. */
+ if(*pfile)
+ {
+ kwsysProcess_SetPipeNative(cp, prPipe, 0);
+ kwsysProcess_SetPipeShared(cp, prPipe, 0);
+ }
+ return 1;
+}
+
+/*--------------------------------------------------------------------------*/
+void kwsysProcess_SetPipeShared(kwsysProcess* cp, int prPipe, int shared)
+{
+ if(!cp)
+ {
+ return;
+ }
+
+ switch(prPipe)
+ {
+ case kwsysProcess_Pipe_STDIN: cp->PipeSharedSTDIN = shared?1:0; break;
+ case kwsysProcess_Pipe_STDOUT: cp->PipeSharedSTDOUT = shared?1:0; break;
+ case kwsysProcess_Pipe_STDERR: cp->PipeSharedSTDERR = shared?1:0; break;
+ default: return;
+ }
+
+ /* If we are sharing the pipe, do not redirect it to a file or use a
+ native pipe. */
+ if(shared)
+ {
+ kwsysProcess_SetPipeFile(cp, prPipe, 0);
+ kwsysProcess_SetPipeNative(cp, prPipe, 0);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+void kwsysProcess_SetPipeNative(kwsysProcess* cp, int prPipe, int p[2])
+{
+ int* pPipeNative = 0;
+
+ if(!cp)
+ {
+ return;
+ }
+
+ switch(prPipe)
+ {
+ case kwsysProcess_Pipe_STDIN: pPipeNative = cp->PipeNativeSTDIN; break;
+ case kwsysProcess_Pipe_STDOUT: pPipeNative = cp->PipeNativeSTDOUT; break;
+ case kwsysProcess_Pipe_STDERR: pPipeNative = cp->PipeNativeSTDERR; break;
+ default: return;
+ }
+
+ /* Copy the native pipe descriptors provided. */
+ if(p)
+ {
+ pPipeNative[0] = p[0];
+ pPipeNative[1] = p[1];
+ }
+ else
+ {
+ pPipeNative[0] = -1;
+ pPipeNative[1] = -1;
+ }
+
+ /* If we are using a native pipe, do not share it or redirect it to
+ a file. */
+ if(p)
+ {
+ kwsysProcess_SetPipeFile(cp, prPipe, 0);
+ kwsysProcess_SetPipeShared(cp, prPipe, 0);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+int kwsysProcess_GetOption(kwsysProcess* cp, int optionId)
+{
+ if(!cp)
+ {
+ return 0;
+ }
+
+ switch(optionId)
+ {
+ case kwsysProcess_Option_Detach: return cp->OptionDetach;
+ case kwsysProcess_Option_Verbatim: return cp->Verbatim;
+ default: return 0;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+void kwsysProcess_SetOption(kwsysProcess* cp, int optionId, int value)
+{
+ if(!cp)
+ {
+ return;
+ }
+
+ switch(optionId)
+ {
+ case kwsysProcess_Option_Detach: cp->OptionDetach = value; break;
+ case kwsysProcess_Option_Verbatim: cp->Verbatim = value; break;
+ default: break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+int kwsysProcess_GetState(kwsysProcess* cp)
+{
+ return cp? cp->State : kwsysProcess_State_Error;
+}
+
+/*--------------------------------------------------------------------------*/
+int kwsysProcess_GetExitException(kwsysProcess* cp)
+{
+ return cp? cp->ExitException : kwsysProcess_Exception_Other;
+}
+
+/*--------------------------------------------------------------------------*/
+int kwsysProcess_GetExitCode(kwsysProcess* cp)
+{
+ return cp? cp->ExitCode : 0;
+}
+
+/*--------------------------------------------------------------------------*/
+int kwsysProcess_GetExitValue(kwsysProcess* cp)
+{
+ return cp? cp->ExitValue : -1;
+}
+
+/*--------------------------------------------------------------------------*/
+const char* kwsysProcess_GetErrorString(kwsysProcess* cp)
+{
+ if(!cp)
+ {
+ return "Process management structure could not be allocated";
+ }
+ else if(cp->State == kwsysProcess_State_Error)
+ {
+ return cp->ErrorMessage;
+ }
+ return "Success";
+}
+
+/*--------------------------------------------------------------------------*/
+const char* kwsysProcess_GetExceptionString(kwsysProcess* cp)
+{
+ if(!cp)
+ {
+ return "GetExceptionString called with NULL process management structure";
+ }
+ else if(cp->State == kwsysProcess_State_Exception)
+ {
+ return cp->ExitExceptionString;
+ }
+ return "No exception";
+}
+
+/*--------------------------------------------------------------------------*/
+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)
+ {
+ return;
+ }
+
+ /* Make sure we have something to run. */
+ if(cp->NumberOfCommands < 1)
+ {
+ strcpy(cp->ErrorMessage, "No command");
+ cp->State = kwsysProcess_State_Error;
+ return;
+ }
+
+ /* Initialize the control structure for a new process. */
+ if(!kwsysProcessInitialize(cp))
+ {
+ strcpy(cp->ErrorMessage, "Out of memory");
+ cp->State = kwsysProcess_State_Error;
+ return;
+ }
+
+#if defined(__VMS)
+ /* Make sure pipes behave like streams on VMS. */
+ if(!kwsysProcessSetVMSFeature("DECC$STREAM_PIPE", 1))
+ {
+ kwsysProcessCleanup(cp, 1);
+ return;
+ }
+#endif
+
+ /* Save the real working directory of this process and change to
+ the working directory for the child processes. This is needed
+ to make pipe file paths evaluate correctly. */
+ if(cp->WorkingDirectory)
+ {
+ int r;
+ if(!getcwd(cp->RealWorkingDirectory,
+ (size_t)(cp->RealWorkingDirectoryLength)))
+ {
+ kwsysProcessCleanup(cp, 1);
+ return;
+ }
+
+ /* Some platforms specify that the chdir call may be
+ interrupted. Repeat the call until it finishes. */
+ while(((r = chdir(cp->WorkingDirectory)) < 0) && (errno == EINTR));
+ if(r < 0)
+ {
+ kwsysProcessCleanup(cp, 1);
+ return;
+ }
+ }
+
+ /* If not running a detached child, add this object to the global
+ set of process objects that wish to be notified when a child
+ exits. */
+ if(!cp->OptionDetach)
+ {
+ if(!kwsysProcessesAdd(cp))
+ {
+ kwsysProcessCleanup(cp, 1);
+ return;
+ }
+ }
+
+ /* Setup the stderr pipe to be shared by all processes. */
+ {
+ /* Create the pipe. */
+ int p[2];
+ if(pipe(p KWSYSPE_VMS_NONBLOCK) < 0)
+ {
+ kwsysProcessCleanup(cp, 1);
+ return;
+ }
+
+ /* Store the pipe. */
+ cp->PipeReadEnds[KWSYSPE_PIPE_STDERR] = p[0];
+ si.StdErr = 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;
+ }
+
+ /* Set to non-blocking in case select lies, or for the polling
+ implementation. */
+ 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(!kwsysProcessSetupOutputPipeFile(&si.StdErr, cp->PipeFileSTDERR))
+ {
+ kwsysProcessCleanup(cp, 1);
+ kwsysProcessCleanupDescriptor(&si.StdErr);
+ 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)
+ {
+ kwsysProcessCleanupDescriptor(&si.StdErr);
+ si.StdErr = 2;
+ }
+
+ /* 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(!kwsysProcessSetupOutputPipeNative(&si.StdErr, cp->PipeNativeSTDERR))
+ {
+ kwsysProcessCleanup(cp, 1);
+ kwsysProcessCleanupDescriptor(&si.StdErr);
+ return;
+ }
+ }
+
+ /* The timeout period starts now. */
+ cp->StartTime = kwsysProcessTimeGetCurrent();
+ cp->TimeoutTime.tv_sec = -1;
+ cp->TimeoutTime.tv_usec = -1;
+
+ /* Create the pipeline of processes. */
+ {
+ int readEnd = -1;
+ int failed = 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))
+ {
+ failed = 1;
+ }
+
+ if(failed)
+ {
+ kwsysProcessCleanup(cp, 1);
+
+ /* Release resources that may have been allocated for this
+ process before an error occurred. */
+ kwsysProcessCleanupDescriptor(&readEnd);
+ if(si.StdIn != 0)
+ {
+ kwsysProcessCleanupDescriptor(&si.StdIn);
+ }
+ if(si.StdOut != 1)
+ {
+ kwsysProcessCleanupDescriptor(&si.StdOut);
+ }
+ if(si.StdErr != 2)
+ {
+ kwsysProcessCleanupDescriptor(&si.StdErr);
+ }
+ kwsysProcessCleanupDescriptor(&si.ErrorPipe[0]);
+ kwsysProcessCleanupDescriptor(&si.ErrorPipe[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)
+ {
+ kwsysProcessCleanupDescriptor(&si.StdErr);
+ }
+
+ /* Restore the working directory. */
+ if(cp->RealWorkingDirectory)
+ {
+ /* Some platforms specify that the chdir call may be
+ interrupted. Repeat the call until it finishes. */
+ while((chdir(cp->RealWorkingDirectory) < 0) && (errno == EINTR));
+ free(cp->RealWorkingDirectory);
+ cp->RealWorkingDirectory = 0;
+ }
+
+ /* All the pipes are now open. */
+ cp->PipesLeft = KWSYSPE_PIPE_COUNT;
+
+ /* The process has now started. */
+ cp->State = kwsysProcess_State_Executing;
+ cp->Detached = cp->OptionDetach;
+}
+
+/*--------------------------------------------------------------------------*/
+kwsysEXPORT void kwsysProcess_Disown(kwsysProcess* cp)
+{
+ /* Make sure a detached child process is running. */
+ if(!cp || !cp->Detached || cp->State != kwsysProcess_State_Executing ||
+ cp->TimeoutExpired || cp->Killed)
+ {
+ return;
+ }
+
+ /* Close all the pipes safely. */
+ kwsysProcessClosePipes(cp);
+
+ /* We will not wait for exit, so cleanup now. */
+ kwsysProcessCleanup(cp, 0);
+
+ /* The process has been disowned. */
+ cp->State = kwsysProcess_State_Disowned;
+}
+
+/*--------------------------------------------------------------------------*/
+typedef struct kwsysProcessWaitData_s
+{
+ int Expired;
+ int PipeId;
+ int User;
+ double* UserTimeout;
+ kwsysProcessTime TimeoutTime;
+} kwsysProcessWaitData;
+static int kwsysProcessWaitForPipe(kwsysProcess* cp, char** data, int* length,
+ kwsysProcessWaitData* wd);
+
+/*--------------------------------------------------------------------------*/
+int kwsysProcess_WaitForData(kwsysProcess* cp, char** data, int* length,
+ double* userTimeout)
+{
+ kwsysProcessTime userStartTime = {0, 0};
+ kwsysProcessWaitData wd =
+ {
+ 0,
+ kwsysProcess_Pipe_None,
+ 0,
+ 0,
+ {0, 0}
+ };
+ wd.UserTimeout = userTimeout;
+ /* Make sure we are executing a process. */
+ if(!cp || cp->State != kwsysProcess_State_Executing || cp->Killed ||
+ cp->TimeoutExpired)
+ {
+ return kwsysProcess_Pipe_None;
+ }
+
+ /* Record the time at which user timeout period starts. */
+ if(userTimeout)
+ {
+ userStartTime = kwsysProcessTimeGetCurrent();
+ }
+
+ /* Calculate the time at which a timeout will expire, and whether it
+ is the user or process timeout. */
+ wd.User = kwsysProcessGetTimeoutTime(cp, userTimeout,
+ &wd.TimeoutTime);
+
+ /* Data can only be available when pipes are open. If the process
+ is not running, cp->PipesLeft will be 0. */
+ while(cp->PipesLeft > 0 &&
+ !kwsysProcessWaitForPipe(cp, data, length, &wd)) {}
+
+ /* Update the user timeout. */
+ if(userTimeout)
+ {
+ kwsysProcessTime userEndTime = kwsysProcessTimeGetCurrent();
+ kwsysProcessTime difference = kwsysProcessTimeSubtract(userEndTime,
+ userStartTime);
+ double d = kwsysProcessTimeToDouble(difference);
+ *userTimeout -= d;
+ if(*userTimeout < 0)
+ {
+ *userTimeout = 0;
+ }
+ }
+
+ /* Check what happened. */
+ if(wd.PipeId)
+ {
+ /* Data are ready on a pipe. */
+ return wd.PipeId;
+ }
+ else if(wd.Expired)
+ {
+ /* A timeout has expired. */
+ if(wd.User)
+ {
+ /* The user timeout has expired. It has no time left. */
+ return kwsysProcess_Pipe_Timeout;
+ }
+ else
+ {
+ /* The process timeout has expired. Kill the children now. */
+ kwsysProcess_Kill(cp);
+ cp->Killed = 0;
+ cp->TimeoutExpired = 1;
+ return kwsysProcess_Pipe_None;
+ }
+ }
+ else
+ {
+ /* No pipes are left open. */
+ return kwsysProcess_Pipe_None;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcessWaitForPipe(kwsysProcess* cp, char** data, int* length,
+ kwsysProcessWaitData* wd)
+{
+ int i;
+ kwsysProcessTimeNative timeoutLength;
+
+#if KWSYSPE_USE_SELECT
+ int numReady = 0;
+ int max = -1;
+ kwsysProcessTimeNative* timeout = 0;
+
+ /* Check for any open pipes with data reported ready by the last
+ call to select. According to "man select_tut" we must deal
+ with all descriptors reported by a call to select before
+ passing them to another select call. */
+ for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
+ {
+ if(cp->PipeReadEnds[i] >= 0 &&
+ FD_ISSET(cp->PipeReadEnds[i], &cp->PipeSet))
+ {
+ kwsysProcess_ssize_t n;
+
+ /* We are handling this pipe now. Remove it from the set. */
+ FD_CLR(cp->PipeReadEnds[i], &cp->PipeSet);
+
+ /* The pipe is ready to read without blocking. Keep trying to
+ read until the operation is not interrupted. */
+ while(((n = read(cp->PipeReadEnds[i], cp->PipeBuffer,
+ KWSYSPE_PIPE_BUFFER_SIZE)) < 0) && (errno == EINTR));
+ if(n > 0)
+ {
+ /* We have data on this pipe. */
+ if(i == KWSYSPE_PIPE_SIGNAL)
+ {
+ /* A child process has terminated. */
+ kwsysProcessDestroy(cp);
+ }
+ else if(data && length)
+ {
+ /* Report this data. */
+ *data = cp->PipeBuffer;
+ *length = (int)(n);
+ switch(i)
+ {
+ case KWSYSPE_PIPE_STDOUT:
+ wd->PipeId = kwsysProcess_Pipe_STDOUT; break;
+ case KWSYSPE_PIPE_STDERR:
+ wd->PipeId = kwsysProcess_Pipe_STDERR; break;
+ };
+ return 1;
+ }
+ }
+ else if(n < 0 && errno == EAGAIN)
+ {
+ /* No data are really ready. The select call lied. See the
+ "man select" page on Linux for cases when this occurs. */
+ }
+ else
+ {
+ /* We are done reading from this pipe. */
+ kwsysProcessCleanupDescriptor(&cp->PipeReadEnds[i]);
+ --cp->PipesLeft;
+ }
+ }
+ }
+
+ /* If we have data, break early. */
+ if(wd->PipeId)
+ {
+ return 1;
+ }
+
+ /* Make sure the set is empty (it should always be empty here
+ anyway). */
+ FD_ZERO(&cp->PipeSet);
+
+ /* Setup a timeout if required. */
+ if(wd->TimeoutTime.tv_sec < 0)
+ {
+ timeout = 0;
+ }
+ else
+ {
+ timeout = &timeoutLength;
+ }
+ if(kwsysProcessGetTimeoutLeft(&wd->TimeoutTime,
+ wd->User?wd->UserTimeout:0,
+ &timeoutLength, 0))
+ {
+ /* Timeout has already expired. */
+ wd->Expired = 1;
+ return 1;
+ }
+
+ /* Add the pipe reading ends that are still open. */
+ max = -1;
+ for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
+ {
+ if(cp->PipeReadEnds[i] >= 0)
+ {
+ FD_SET(cp->PipeReadEnds[i], &cp->PipeSet);
+ if(cp->PipeReadEnds[i] > max)
+ {
+ max = cp->PipeReadEnds[i];
+ }
+ }
+ }
+
+ /* Make sure we have a non-empty set. */
+ if(max < 0)
+ {
+ /* All pipes have closed. Child has terminated. */
+ return 1;
+ }
+
+ /* Run select to block until data are available. Repeat call
+ until it is not interrupted. */
+ while(((numReady = select(max+1, &cp->PipeSet, 0, 0, timeout)) < 0) &&
+ (errno == EINTR));
+
+ /* Check result of select. */
+ if(numReady == 0)
+ {
+ /* Select's timeout expired. */
+ wd->Expired = 1;
+ return 1;
+ }
+ else if(numReady < 0)
+ {
+ /* Select returned an error. Leave the error description in the
+ pipe buffer. */
+ strncpy(cp->ErrorMessage, strerror(errno), KWSYSPE_PIPE_BUFFER_SIZE);
+
+ /* Kill the children now. */
+ kwsysProcess_Kill(cp);
+ cp->Killed = 0;
+ cp->SelectError = 1;
+ }
+
+ return 0;
+#else
+ /* Poll pipes for data since we do not have select. */
+ for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
+ {
+ if(cp->PipeReadEnds[i] >= 0)
+ {
+ const int fd = cp->PipeReadEnds[i];
+ int n = read(fd, cp->PipeBuffer, KWSYSPE_PIPE_BUFFER_SIZE);
+ if(n > 0)
+ {
+ /* We have data on this pipe. */
+ if(i == KWSYSPE_PIPE_SIGNAL)
+ {
+ /* A child process has terminated. */
+ kwsysProcessDestroy(cp);
+ }
+ else if(data && length)
+ {
+ /* Report this data. */
+ *data = cp->PipeBuffer;
+ *length = n;
+ switch(i)
+ {
+ case KWSYSPE_PIPE_STDOUT:
+ wd->PipeId = kwsysProcess_Pipe_STDOUT; break;
+ case KWSYSPE_PIPE_STDERR:
+ wd->PipeId = kwsysProcess_Pipe_STDERR; break;
+ };
+ }
+ return 1;
+ }
+ else if (n == 0) /* EOF */
+ {
+ /* We are done reading from this pipe. */
+#if defined(__VMS)
+ if(!cp->CommandsLeft)
+#endif
+ {
+ kwsysProcessCleanupDescriptor(&cp->PipeReadEnds[i]);
+ --cp->PipesLeft;
+ }
+ }
+ else if (n < 0) /* error */
+ {
+#if defined(__VMS)
+ if(!cp->CommandsLeft)
+ {
+ kwsysProcessCleanupDescriptor(&cp->PipeReadEnds[i]);
+ --cp->PipesLeft;
+ }
+ else
+#endif
+ if((errno != EINTR) && (errno != EAGAIN))
+ {
+ strncpy(cp->ErrorMessage,strerror(errno),
+ KWSYSPE_PIPE_BUFFER_SIZE);
+ /* Kill the children now. */
+ kwsysProcess_Kill(cp);
+ cp->Killed = 0;
+ cp->SelectError = 1;
+ return 1;
+ }
+ }
+ }
+ }
+
+ /* If we have data, break early. */
+ if(wd->PipeId)
+ {
+ return 1;
+ }
+
+ if(kwsysProcessGetTimeoutLeft(&wd->TimeoutTime, wd->User?wd->UserTimeout:0,
+ &timeoutLength, 1))
+ {
+ /* Timeout has already expired. */
+ wd->Expired = 1;
+ return 1;
+ }
+
+ /* Sleep a little, try again. */
+ {
+ unsigned int msec = ((timeoutLength.tv_sec * 1000) +
+ (timeoutLength.tv_usec / 1000));
+ if (msec > 100000)
+ {
+ msec = 100000; /* do not sleep more than 100 milliseconds at a time */
+ }
+ kwsysProcess_usleep(msec);
+ }
+ return 0;
+#endif
+}
+
+/*--------------------------------------------------------------------------*/
+int kwsysProcess_WaitForExit(kwsysProcess* cp, double* userTimeout)
+{
+ int status = 0;
+ int prPipe = 0;
+
+ /* Make sure we are executing a process. */
+ if(!cp || cp->State != kwsysProcess_State_Executing)
+ {
+ return 1;
+ }
+
+ /* Wait for all the pipes to close. Ignore all data. */
+ while((prPipe = kwsysProcess_WaitForData(cp, 0, 0, userTimeout)) > 0)
+ {
+ if(prPipe == kwsysProcess_Pipe_Timeout)
+ {
+ return 0;
+ }
+ }
+
+ /* Check if there was an error in one of the waitpid calls. */
+ if(cp->State == kwsysProcess_State_Error)
+ {
+ /* The error message is already in its buffer. Tell
+ kwsysProcessCleanup to not create it. */
+ kwsysProcessCleanup(cp, 0);
+ return 1;
+ }
+
+ /* Check whether the child reported an error invoking the process. */
+ if(cp->SelectError)
+ {
+ /* The error message is already in its buffer. Tell
+ kwsysProcessCleanup to not create it. */
+ kwsysProcessCleanup(cp, 0);
+ cp->State = kwsysProcess_State_Error;
+ return 1;
+ }
+
+ /* Use the status of the last process in the pipeline. */
+ status = cp->CommandExitCodes[cp->NumberOfCommands-1];
+
+ /* Determine the outcome. */
+ if(cp->Killed)
+ {
+ /* We killed the child. */
+ cp->State = kwsysProcess_State_Killed;
+ }
+ else if(cp->TimeoutExpired)
+ {
+ /* The timeout expired. */
+ cp->State = kwsysProcess_State_Expired;
+ }
+ else if(WIFEXITED(status))
+ {
+ /* The child exited normally. */
+ cp->State = kwsysProcess_State_Exited;
+ cp->ExitException = kwsysProcess_Exception_None;
+ cp->ExitCode = status;
+ cp->ExitValue = (int)WEXITSTATUS(status);
+ }
+ else if(WIFSIGNALED(status))
+ {
+ /* The child received an unhandled signal. */
+ cp->State = kwsysProcess_State_Exception;
+ cp->ExitCode = status;
+ kwsysProcessSetExitException(cp, (int)WTERMSIG(status));
+ }
+ else
+ {
+ /* Error getting the child return code. */
+ strcpy(cp->ErrorMessage, "Error getting child return code.");
+ cp->State = kwsysProcess_State_Error;
+ }
+
+ /* Normal cleanup. */
+ kwsysProcessCleanup(cp, 0);
+ return 1;
+}
+
+/*--------------------------------------------------------------------------*/
+void kwsysProcess_Kill(kwsysProcess* cp)
+{
+ int i;
+
+ /* Make sure we are executing a process. */
+ if(!cp || cp->State != kwsysProcess_State_Executing)
+ {
+ return;
+ }
+
+ /* First close the child exit report pipe write end to avoid causing a
+ SIGPIPE when the child terminates and our signal handler tries to
+ report it after we have already closed the read end. */
+ kwsysProcessCleanupDescriptor(&cp->SignalPipe);
+
+#if !defined(__APPLE__)
+ /* Close all the pipe read ends. Do this before killing the
+ children because Cygwin has problems killing processes that are
+ blocking to wait for writing to their output pipes. */
+ kwsysProcessClosePipes(cp);
+#endif
+
+ /* Kill the children. */
+ cp->Killed = 1;
+ for(i=0; i < cp->NumberOfCommands; ++i)
+ {
+ int status;
+ if(cp->ForkPIDs[i])
+ {
+ /* Kill the child. */
+ kwsysProcessKill(cp->ForkPIDs[i]);
+
+ /* Reap the child. Keep trying until the call is not
+ interrupted. */
+ while((waitpid(cp->ForkPIDs[i], &status, 0) < 0) && (errno == EINTR));
+ }
+ }
+
+#if defined(__APPLE__)
+ /* Close all the pipe read ends. Do this after killing the
+ children because OS X has problems closing pipe read ends whose
+ pipes are full and still have an open write end. */
+ kwsysProcessClosePipes(cp);
+#endif
+
+ cp->CommandsLeft = 0;
+}
+
+/*--------------------------------------------------------------------------*/
+/* Initialize a process control structure for kwsysProcess_Execute. */
+static int kwsysProcessInitialize(kwsysProcess* cp)
+{
+ int i;
+ for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
+ {
+ cp->PipeReadEnds[i] = -1;
+ }
+ cp->SignalPipe = -1;
+ cp->SelectError = 0;
+ cp->StartTime.tv_sec = -1;
+ cp->StartTime.tv_usec = -1;
+ cp->TimeoutTime.tv_sec = -1;
+ cp->TimeoutTime.tv_usec = -1;
+ cp->TimeoutExpired = 0;
+ cp->PipesLeft = 0;
+ cp->CommandsLeft = 0;
+#if KWSYSPE_USE_SELECT
+ FD_ZERO(&cp->PipeSet);
+#endif
+ cp->State = kwsysProcess_State_Starting;
+ cp->Killed = 0;
+ cp->ExitException = kwsysProcess_Exception_None;
+ cp->ExitCode = 1;
+ cp->ExitValue = 1;
+ cp->ErrorMessage[0] = 0;
+ strcpy(cp->ExitExceptionString, "No exception");
+
+ if(cp->ForkPIDs)
+ {
+ free(cp->ForkPIDs);
+ }
+ 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));
+
+ if(cp->CommandExitCodes)
+ {
+ free(cp->CommandExitCodes);
+ }
+ cp->CommandExitCodes = (int*)malloc(sizeof(int)*
+ (size_t)(cp->NumberOfCommands));
+ if(!cp->CommandExitCodes)
+ {
+ return 0;
+ }
+ memset(cp->CommandExitCodes, 0, sizeof(int)*(size_t)(cp->NumberOfCommands));
+
+ /* Allocate memory to save the real working directory. */
+ if ( cp->WorkingDirectory )
+ {
+#if defined(MAXPATHLEN)
+ cp->RealWorkingDirectoryLength = MAXPATHLEN;
+#elif defined(PATH_MAX)
+ cp->RealWorkingDirectoryLength = PATH_MAX;
+#else
+ cp->RealWorkingDirectoryLength = 4096;
+#endif
+ cp->RealWorkingDirectory =
+ malloc((size_t)(cp->RealWorkingDirectoryLength));
+ if(!cp->RealWorkingDirectory)
+ {
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+/*--------------------------------------------------------------------------*/
+/* Free all resources used by the given kwsysProcess instance that were
+ allocated by kwsysProcess_Execute. */
+static void kwsysProcessCleanup(kwsysProcess* cp, int error)
+{
+ int i;
+
+ if(error)
+ {
+ /* We are cleaning up due to an error. Report the error message
+ if one has not been provided already. */
+ if(cp->ErrorMessage[0] == 0)
+ {
+ strncpy(cp->ErrorMessage, strerror(errno), KWSYSPE_PIPE_BUFFER_SIZE);
+ }
+
+ /* Set the error state. */
+ cp->State = kwsysProcess_State_Error;
+
+ /* Kill any children already started. */
+ if(cp->ForkPIDs)
+ {
+ int status;
+ for(i=0; i < cp->NumberOfCommands; ++i)
+ {
+ if(cp->ForkPIDs[i])
+ {
+ /* Kill the child. */
+ kwsysProcessKill(cp->ForkPIDs[i]);
+
+ /* Reap the child. Keep trying until the call is not
+ interrupted. */
+ while((waitpid(cp->ForkPIDs[i], &status, 0) < 0) &&
+ (errno == EINTR));
+ }
+ }
+ }
+
+ /* Restore the working directory. */
+ if(cp->RealWorkingDirectory)
+ {
+ while((chdir(cp->RealWorkingDirectory) < 0) && (errno == EINTR));
+ }
+ }
+
+ /* If not creating a detached child, remove this object from the
+ global set of process objects that wish to be notified when a
+ child exits. */
+ if(!cp->OptionDetach)
+ {
+ kwsysProcessesRemove(cp);
+ }
+
+ /* Free memory. */
+ if(cp->ForkPIDs)
+ {
+ free(cp->ForkPIDs);
+ cp->ForkPIDs = 0;
+ }
+ if(cp->RealWorkingDirectory)
+ {
+ free(cp->RealWorkingDirectory);
+ cp->RealWorkingDirectory = 0;
+ }
+
+ /* Close pipe handles. */
+ for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
+ {
+ kwsysProcessCleanupDescriptor(&cp->PipeReadEnds[i]);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+/* Close the given file descriptor if it is open. Reset its value to -1. */
+static void kwsysProcessCleanupDescriptor(int* pfd)
+{
+ if(pfd && *pfd >= 0)
+ {
+ /* Keep trying to close until it is not interrupted by a
+ * signal. */
+ while((close(*pfd) < 0) && (errno == EINTR));
+ *pfd = -1;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+static void kwsysProcessClosePipes(kwsysProcess* cp)
+{
+ int i;
+
+ /* Close any pipes that are still open. */
+ for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
+ {
+ if(cp->PipeReadEnds[i] >= 0)
+ {
+#if KWSYSPE_USE_SELECT
+ /* If the pipe was reported by the last call to select, we must
+ read from it. This is needed to satisfy the suggestions from
+ "man select_tut" and is not needed for the polling
+ implementation. Ignore the data. */
+ if(FD_ISSET(cp->PipeReadEnds[i], &cp->PipeSet))
+ {
+ /* We are handling this pipe now. Remove it from the set. */
+ FD_CLR(cp->PipeReadEnds[i], &cp->PipeSet);
+
+ /* The pipe is ready to read without blocking. Keep trying to
+ read until the operation is not interrupted. */
+ while((read(cp->PipeReadEnds[i], cp->PipeBuffer,
+ KWSYSPE_PIPE_BUFFER_SIZE) < 0) && (errno == EINTR));
+ }
+#endif
+
+ /* We are done reading from this pipe. */
+ kwsysProcessCleanupDescriptor(&cp->PipeReadEnds[i]);
+ --cp->PipesLeft;
+ }
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcessSetNonBlocking(int fd)
+{
+ int flags = fcntl(fd, F_GETFL);
+ if(flags >= 0)
+ {
+ flags = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
+ }
+ return flags >= 0;
+}
+
+/*--------------------------------------------------------------------------*/
+#if defined(__VMS)
+int decc$set_child_standard_streams(int fd1, int fd2, int fd3);
+#endif
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
+ kwsysProcessCreateInformation* si, int* readEnd)
+{
+ /* 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;
+ }
+
+ /* 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)
+ {
+ 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))
+ {
+ 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)
+ {
+ return 0;
+ }
+
+ /* Set close-on-exec flag on the error pipe's write end. */
+ if(fcntl(si->ErrorPipe[1], F_SETFD, FD_CLOEXEC) < 0)
+ {
+ return 0;
+ }
+
+ /* Fork off a child process. */
+#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. */
+ cp->ForkPIDs[prIndex] = vfork();
+#else
+ cp->ForkPIDs[prIndex] = kwsysProcessFork(cp, si);
+#endif
+ if(cp->ForkPIDs[prIndex] < 0)
+ {
+ return 0;
+ }
+
+ if(cp->ForkPIDs[prIndex] == 0)
+ {
+#if defined(__VMS)
+ /* 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(si->ErrorPipe[0]);
+
+ /* Setup the stdin, stdout, and stderr pipes. */
+ if(si->StdIn > 0)
+ {
+ dup2(si->StdIn, 0);
+ }
+ else if(si->StdIn < 0)
+ {
+ close(0);
+ }
+ if(si->StdOut != 1)
+ {
+ dup2(si->StdOut, 1);
+ }
+ if(si->StdErr != 2)
+ {
+ dup2(si->StdErr, 2);
+ }
+
+ /* Clear the close-on-exec flag for stdin, stdout, and stderr.
+ All other pipe handles will be closed when exec succeeds. */
+ fcntl(0, F_SETFD, 0);
+ fcntl(1, F_SETFD, 0);
+ fcntl(2, F_SETFD, 0);
+
+ /* Restore all default signal handlers. */
+ kwsysProcessRestoreDefaultSignalHandlers();
+#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? */
+
+ /* Failure. Report error to parent and terminate. */
+ kwsysProcessChildErrorExit(si->ErrorPipe[1]);
+ }
+
+#if defined(__VMS)
+ /* Restore the standard pipes of this process. */
+ decc$set_child_standard_streams(0, 1, 2);
+#endif
+
+ /* 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. */
+ {
+ kwsysProcess_ssize_t total = 0;
+ kwsysProcess_ssize_t n = 1;
+ /* Read the entire error message up to the length of our buffer. */
+ while(total < KWSYSPE_PIPE_BUFFER_SIZE && n > 0)
+ {
+ /* Keep trying to read until the operation is not interrupted. */
+ while(((n = read(si->ErrorPipe[0], cp->ErrorMessage+total,
+ (size_t)(KWSYSPE_PIPE_BUFFER_SIZE-total))) < 0) &&
+ (errno == EINTR));
+ if(n > 0)
+ {
+ total += n;
+ }
+ }
+
+ /* We are done with the error reporting pipe read end. */
+ kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]);
+
+ if(total > 0)
+ {
+ /* The child failed to execute the process. */
+ return 0;
+ }
+ }
+
+ /* 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;
+}
+
+/*--------------------------------------------------------------------------*/
+static void kwsysProcessDestroy(kwsysProcess* cp)
+{
+ /* A child process has terminated. Reap it if it is one handled by
+ this object. */
+ int i;
+ for(i=0; i < cp->NumberOfCommands; ++i)
+ {
+ if(cp->ForkPIDs[i])
+ {
+ int result;
+ while(((result = waitpid(cp->ForkPIDs[i],
+ &cp->CommandExitCodes[i], WNOHANG)) < 0) &&
+ (errno == EINTR));
+ if(result > 0)
+ {
+ /* This child has termianted. */
+ cp->ForkPIDs[i] = 0;
+ if(--cp->CommandsLeft == 0)
+ {
+ /* All children have terminated. Close the signal pipe
+ write end so that no more notifications are sent to this
+ object. */
+ kwsysProcessCleanupDescriptor(&cp->SignalPipe);
+
+ /* TODO: Once the children have terminated, switch
+ WaitForData to use a non-blocking read to get the
+ rest of the data from the pipe. This is needed when
+ grandchildren keep the output pipes open. */
+ }
+ }
+ else if(result < 0 && cp->State != kwsysProcess_State_Error)
+ {
+ /* Unexpected error. Report the first time this happens. */
+ strncpy(cp->ErrorMessage, strerror(errno), KWSYSPE_PIPE_BUFFER_SIZE);
+ cp->State = kwsysProcess_State_Error;
+ }
+ }
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcessSetupOutputPipeFile(int* p, const char* name)
+{
+ int fout;
+ if(!name)
+ {
+ return 1;
+ }
+
+ /* Close the existing descriptor. */
+ kwsysProcessCleanupDescriptor(p);
+
+ /* Open a file for the pipe to write. */
+ if((fout = open(name, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0)
+ {
+ return 0;
+ }
+
+ /* Set close-on-exec flag on the pipe's end. */
+ if(fcntl(fout, F_SETFD, FD_CLOEXEC) < 0)
+ {
+ return 0;
+ }
+
+ /* Assign the replacement descriptor. */
+ *p = fout;
+ return 1;
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcessSetupOutputPipeNative(int* p, int des[2])
+{
+ /* Close the existing descriptor. */
+ kwsysProcessCleanupDescriptor(p);
+
+ /* Set close-on-exec flag on the pipe's ends. The proper end will
+ be dup2-ed into the standard descriptor number after fork but
+ before exec. */
+ if((fcntl(des[0], F_SETFD, FD_CLOEXEC) < 0) ||
+ (fcntl(des[1], F_SETFD, FD_CLOEXEC) < 0))
+ {
+ return 0;
+ }
+
+ /* Assign the replacement descriptor. */
+ *p = des[1];
+ return 1;
+}
+
+/*--------------------------------------------------------------------------*/
+/* Get the time at which either the process or user timeout will
+ expire. Returns 1 if the user timeout is first, and 0 otherwise. */
+static int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout,
+ kwsysProcessTime* timeoutTime)
+{
+ /* The first time this is called, we need to calculate the time at
+ which the child will timeout. */
+ if(cp->Timeout > 0 && cp->TimeoutTime.tv_sec < 0)
+ {
+ kwsysProcessTime length = kwsysProcessTimeFromDouble(cp->Timeout);
+ cp->TimeoutTime = kwsysProcessTimeAdd(cp->StartTime, length);
+ }
+
+ /* Start with process timeout. */
+ *timeoutTime = cp->TimeoutTime;
+
+ /* Check if the user timeout is earlier. */
+ if(userTimeout)
+ {
+ kwsysProcessTime currentTime = kwsysProcessTimeGetCurrent();
+ kwsysProcessTime userTimeoutLength = kwsysProcessTimeFromDouble(*userTimeout);
+ kwsysProcessTime userTimeoutTime = kwsysProcessTimeAdd(currentTime,
+ userTimeoutLength);
+ if(timeoutTime->tv_sec < 0 ||
+ kwsysProcessTimeLess(userTimeoutTime, *timeoutTime))
+ {
+ *timeoutTime = userTimeoutTime;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/*--------------------------------------------------------------------------*/
+/* Get the length of time before the given timeout time arrives.
+ Returns 1 if the time has already arrived, and 0 otherwise. */
+static int kwsysProcessGetTimeoutLeft(kwsysProcessTime* timeoutTime,
+ double* userTimeout,
+ kwsysProcessTimeNative* timeoutLength,
+ int zeroIsExpired)
+{
+ if(timeoutTime->tv_sec < 0)
+ {
+ /* No timeout time has been requested. */
+ return 0;
+ }
+ else
+ {
+ /* Calculate the remaining time. */
+ kwsysProcessTime currentTime = kwsysProcessTimeGetCurrent();
+ kwsysProcessTime timeLeft = kwsysProcessTimeSubtract(*timeoutTime,
+ currentTime);
+ if(timeLeft.tv_sec < 0 && userTimeout && *userTimeout <= 0)
+ {
+ /* Caller has explicitly requested a zero timeout. */
+ timeLeft.tv_sec = 0;
+ timeLeft.tv_usec = 0;
+ }
+
+ if(timeLeft.tv_sec < 0 ||
+ (timeLeft.tv_sec == 0 && timeLeft.tv_usec == 0 && zeroIsExpired))
+ {
+ /* Timeout has already expired. */
+ return 1;
+ }
+ else
+ {
+ /* There is some time left. */
+ timeoutLength->tv_sec = timeLeft.tv_sec;
+ timeoutLength->tv_usec = timeLeft.tv_usec;
+ return 0;
+ }
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+static kwsysProcessTime kwsysProcessTimeGetCurrent(void)
+{
+ kwsysProcessTime current;
+ kwsysProcessTimeNative current_native;
+ gettimeofday(&current_native, 0);
+ current.tv_sec = (long)current_native.tv_sec;
+ current.tv_usec = (long)current_native.tv_usec;
+ return current;
+}
+
+/*--------------------------------------------------------------------------*/
+static double kwsysProcessTimeToDouble(kwsysProcessTime t)
+{
+ return (double)t.tv_sec + (double)(t.tv_usec)*0.000001;
+}
+
+/*--------------------------------------------------------------------------*/
+static kwsysProcessTime kwsysProcessTimeFromDouble(double d)
+{
+ kwsysProcessTime t;
+ t.tv_sec = (long)d;
+ t.tv_usec = (long)((d-(double)(t.tv_sec))*1000000);
+ return t;
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcessTimeLess(kwsysProcessTime in1, kwsysProcessTime in2)
+{
+ return ((in1.tv_sec < in2.tv_sec) ||
+ ((in1.tv_sec == in2.tv_sec) && (in1.tv_usec < in2.tv_usec)));
+}
+
+/*--------------------------------------------------------------------------*/
+static kwsysProcessTime kwsysProcessTimeAdd(kwsysProcessTime in1, kwsysProcessTime in2)
+{
+ 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)
+ {
+ out.tv_usec -= 1000000;
+ out.tv_sec += 1;
+ }
+ return out;
+}
+
+/*--------------------------------------------------------------------------*/
+static kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1, kwsysProcessTime in2)
+{
+ kwsysProcessTime out;
+ out.tv_sec = in1.tv_sec - in2.tv_sec;
+ out.tv_usec = in1.tv_usec - in2.tv_usec;
+ if(out.tv_usec < 0)
+ {
+ out.tv_usec += 1000000;
+ out.tv_sec -= 1;
+ }
+ return out;
+}
+
+/*--------------------------------------------------------------------------*/
+#define KWSYSPE_CASE(type, str) \
+ cp->ExitException = kwsysProcess_Exception_##type; \
+ strcpy(cp->ExitExceptionString, str)
+static void kwsysProcessSetExitException(kwsysProcess* cp, int sig)
+{
+ switch (sig)
+ {
+#ifdef SIGSEGV
+ case SIGSEGV: KWSYSPE_CASE(Fault, "Segmentation fault"); break;
+#endif
+#ifdef SIGBUS
+# if !defined(SIGSEGV) || SIGBUS != SIGSEGV
+ case SIGBUS: KWSYSPE_CASE(Fault, "Bus error"); break;
+# endif
+#endif
+#ifdef SIGFPE
+ case SIGFPE: KWSYSPE_CASE(Numerical, "Floating-point exception"); break;
+#endif
+#ifdef SIGILL
+ case SIGILL: KWSYSPE_CASE(Illegal, "Illegal instruction"); break;
+#endif
+#ifdef SIGINT
+ case SIGINT: KWSYSPE_CASE(Interrupt, "User interrupt"); break;
+#endif
+#ifdef SIGABRT
+ case SIGABRT: KWSYSPE_CASE(Other, "Child aborted"); break;
+#endif
+#ifdef SIGKILL
+ case SIGKILL: KWSYSPE_CASE(Other, "Child killed"); break;
+#endif
+#ifdef SIGTERM
+ case SIGTERM: KWSYSPE_CASE(Other, "Child terminated"); break;
+#endif
+#ifdef SIGHUP
+ case SIGHUP: KWSYSPE_CASE(Other, "SIGHUP"); break;
+#endif
+#ifdef SIGQUIT
+ case SIGQUIT: KWSYSPE_CASE(Other, "SIGQUIT"); break;
+#endif
+#ifdef SIGTRAP
+ case SIGTRAP: KWSYSPE_CASE(Other, "SIGTRAP"); break;
+#endif
+#ifdef SIGIOT
+# if !defined(SIGABRT) || SIGIOT != SIGABRT
+ case SIGIOT: KWSYSPE_CASE(Other, "SIGIOT"); break;
+# endif
+#endif
+#ifdef SIGUSR1
+ case SIGUSR1: KWSYSPE_CASE(Other, "SIGUSR1"); break;
+#endif
+#ifdef SIGUSR2
+ case SIGUSR2: KWSYSPE_CASE(Other, "SIGUSR2"); break;
+#endif
+#ifdef SIGPIPE
+ case SIGPIPE: KWSYSPE_CASE(Other, "SIGPIPE"); break;
+#endif
+#ifdef SIGALRM
+ case SIGALRM: KWSYSPE_CASE(Other, "SIGALRM"); break;
+#endif
+#ifdef SIGSTKFLT
+ case SIGSTKFLT: KWSYSPE_CASE(Other, "SIGSTKFLT"); break;
+#endif
+#ifdef SIGCHLD
+ case SIGCHLD: KWSYSPE_CASE(Other, "SIGCHLD"); break;
+#elif defined(SIGCLD)
+ case SIGCLD: KWSYSPE_CASE(Other, "SIGCLD"); break;
+#endif
+#ifdef SIGCONT
+ case SIGCONT: KWSYSPE_CASE(Other, "SIGCONT"); break;
+#endif
+#ifdef SIGSTOP
+ case SIGSTOP: KWSYSPE_CASE(Other, "SIGSTOP"); break;
+#endif
+#ifdef SIGTSTP
+ case SIGTSTP: KWSYSPE_CASE(Other, "SIGTSTP"); break;
+#endif
+#ifdef SIGTTIN
+ case SIGTTIN: KWSYSPE_CASE(Other, "SIGTTIN"); break;
+#endif
+#ifdef SIGTTOU
+ case SIGTTOU: KWSYSPE_CASE(Other, "SIGTTOU"); break;
+#endif
+#ifdef SIGURG
+ case SIGURG: KWSYSPE_CASE(Other, "SIGURG"); break;
+#endif
+#ifdef SIGXCPU
+ case SIGXCPU: KWSYSPE_CASE(Other, "SIGXCPU"); break;
+#endif
+#ifdef SIGXFSZ
+ case SIGXFSZ: KWSYSPE_CASE(Other, "SIGXFSZ"); break;
+#endif
+#ifdef SIGVTALRM
+ case SIGVTALRM: KWSYSPE_CASE(Other, "SIGVTALRM"); break;
+#endif
+#ifdef SIGPROF
+ case SIGPROF: KWSYSPE_CASE(Other, "SIGPROF"); break;
+#endif
+#ifdef SIGWINCH
+ case SIGWINCH: KWSYSPE_CASE(Other, "SIGWINCH"); break;
+#endif
+#ifdef SIGPOLL
+ case SIGPOLL: KWSYSPE_CASE(Other, "SIGPOLL"); break;
+#endif
+#ifdef SIGIO
+# if !defined(SIGPOLL) || SIGIO != SIGPOLL
+ case SIGIO: KWSYSPE_CASE(Other, "SIGIO"); break;
+# endif
+#endif
+#ifdef SIGPWR
+ case SIGPWR: KWSYSPE_CASE(Other, "SIGPWR"); break;
+#endif
+#ifdef SIGSYS
+ case SIGSYS: KWSYSPE_CASE(Other, "SIGSYS"); break;
+#endif
+#ifdef SIGUNUSED
+# if !defined(SIGSYS) || SIGUNUSED != SIGSYS
+ case SIGUNUSED: KWSYSPE_CASE(Other, "SIGUNUSED"); break;
+# endif
+#endif
+ default:
+ cp->ExitException = kwsysProcess_Exception_Other;
+ sprintf(cp->ExitExceptionString, "Signal %d", sig);
+ break;
+ }
+}
+#undef KWSYSPE_CASE
+
+/*--------------------------------------------------------------------------*/
+/* When the child process encounters an error before its program is
+ invoked, this is called to report the error to the parent and
+ exit. */
+static void kwsysProcessChildErrorExit(int errorPipe)
+{
+ /* Construct the error message. */
+ char buffer[KWSYSPE_PIPE_BUFFER_SIZE];
+ kwsysProcess_ssize_t result;
+ strncpy(buffer, strerror(errno), KWSYSPE_PIPE_BUFFER_SIZE);
+
+ /* Report the error to the parent through the special pipe. */
+ result=write(errorPipe, buffer, strlen(buffer));
+ (void)result;
+
+ /* Terminate without cleanup. */
+ _exit(1);
+}
+
+/*--------------------------------------------------------------------------*/
+/* Restores all signal handlers to their default values. */
+static void kwsysProcessRestoreDefaultSignalHandlers(void)
+{
+ struct sigaction act;
+ memset(&act, 0, sizeof(struct sigaction));
+ act.sa_handler = SIG_DFL;
+#ifdef SIGHUP
+ sigaction(SIGHUP, &act, 0);
+#endif
+#ifdef SIGINT
+ sigaction(SIGINT, &act, 0);
+#endif
+#ifdef SIGQUIT
+ sigaction(SIGQUIT, &act, 0);
+#endif
+#ifdef SIGILL
+ sigaction(SIGILL, &act, 0);
+#endif
+#ifdef SIGTRAP
+ sigaction(SIGTRAP, &act, 0);
+#endif
+#ifdef SIGABRT
+ sigaction(SIGABRT, &act, 0);
+#endif
+#ifdef SIGIOT
+ sigaction(SIGIOT, &act, 0);
+#endif
+#ifdef SIGBUS
+ sigaction(SIGBUS, &act, 0);
+#endif
+#ifdef SIGFPE
+ sigaction(SIGFPE, &act, 0);
+#endif
+#ifdef SIGUSR1
+ sigaction(SIGUSR1, &act, 0);
+#endif
+#ifdef SIGSEGV
+ sigaction(SIGSEGV, &act, 0);
+#endif
+#ifdef SIGUSR2
+ sigaction(SIGUSR2, &act, 0);
+#endif
+#ifdef SIGPIPE
+ sigaction(SIGPIPE, &act, 0);
+#endif
+#ifdef SIGALRM
+ sigaction(SIGALRM, &act, 0);
+#endif
+#ifdef SIGTERM
+ sigaction(SIGTERM, &act, 0);
+#endif
+#ifdef SIGSTKFLT
+ sigaction(SIGSTKFLT, &act, 0);
+#endif
+#ifdef SIGCLD
+ sigaction(SIGCLD, &act, 0);
+#endif
+#ifdef SIGCHLD
+ sigaction(SIGCHLD, &act, 0);
+#endif
+#ifdef SIGCONT
+ sigaction(SIGCONT, &act, 0);
+#endif
+#ifdef SIGTSTP
+ sigaction(SIGTSTP, &act, 0);
+#endif
+#ifdef SIGTTIN
+ sigaction(SIGTTIN, &act, 0);
+#endif
+#ifdef SIGTTOU
+ sigaction(SIGTTOU, &act, 0);
+#endif
+#ifdef SIGURG
+ sigaction(SIGURG, &act, 0);
+#endif
+#ifdef SIGXCPU
+ sigaction(SIGXCPU, &act, 0);
+#endif
+#ifdef SIGXFSZ
+ sigaction(SIGXFSZ, &act, 0);
+#endif
+#ifdef SIGVTALRM
+ sigaction(SIGVTALRM, &act, 0);
+#endif
+#ifdef SIGPROF
+ sigaction(SIGPROF, &act, 0);
+#endif
+#ifdef SIGWINCH
+ sigaction(SIGWINCH, &act, 0);
+#endif
+#ifdef SIGPOLL
+ sigaction(SIGPOLL, &act, 0);
+#endif
+#ifdef SIGIO
+ sigaction(SIGIO, &act, 0);
+#endif
+#ifdef SIGPWR
+ sigaction(SIGPWR, &act, 0);
+#endif
+#ifdef SIGSYS
+ sigaction(SIGSYS, &act, 0);
+#endif
+#ifdef SIGUNUSED
+ sigaction(SIGUNUSED, &act, 0);
+#endif
+}
+
+/*--------------------------------------------------------------------------*/
+static void kwsysProcessExit(void)
+{
+ _exit(0);
+}
+
+/*--------------------------------------------------------------------------*/
+#if !defined(__VMS)
+static pid_t kwsysProcessFork(kwsysProcess* cp,
+ kwsysProcessCreateInformation* si)
+{
+ /* Create a detached process if requested. */
+ if(cp->OptionDetach)
+ {
+ /* Create an intermediate process. */
+ pid_t middle_pid = fork();
+ if(middle_pid < 0)
+ {
+ /* Fork failed. Return as if we were not detaching. */
+ return middle_pid;
+ }
+ else if(middle_pid == 0)
+ {
+ /* This is the intermediate process. Create the real child. */
+ pid_t child_pid = fork();
+ if(child_pid == 0)
+ {
+ /* This is the real child process. There is nothing to do here. */
+ return 0;
+ }
+ else
+ {
+ /* Use the error pipe to report the pid to the real parent. */
+ while((write(si->ErrorPipe[1], &child_pid, sizeof(child_pid)) < 0) &&
+ (errno == EINTR));
+
+ /* Exit without cleanup. The parent holds all resources. */
+ kwsysProcessExit();
+ return 0; /* Never reached, but avoids SunCC warning. */
+ }
+ }
+ else
+ {
+ /* This is the original parent process. The intermediate
+ process will use the error pipe to report the pid of the
+ detached child. */
+ pid_t child_pid;
+ int status;
+ while((read(si->ErrorPipe[0], &child_pid, sizeof(child_pid)) < 0) &&
+ (errno == EINTR));
+
+ /* Wait for the intermediate process to exit and clean it up. */
+ while((waitpid(middle_pid, &status, 0) < 0) && (errno == EINTR));
+ return child_pid;
+ }
+ }
+ else
+ {
+ /* Not creating a detached process. Use normal fork. */
+ return fork();
+ }
+}
+#endif
+
+/*--------------------------------------------------------------------------*/
+/* We try to obtain process information by invoking the ps command.
+ Here we define the command to call on each platform and the
+ corresponding parsing format string. The parsing format should
+ have two integers to store: the pid and then the ppid. */
+#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) \
+ || defined(__OpenBSD__) || defined(__GLIBC__) || defined(__GNU__)
+# define KWSYSPE_PS_COMMAND "ps axo pid,ppid"
+# define KWSYSPE_PS_FORMAT "%d %d\n"
+#elif defined(__sun) && (defined(__SVR4) || defined(__svr4__)) /* Solaris */
+# define KWSYSPE_PS_COMMAND "ps -e -o pid,ppid"
+# define KWSYSPE_PS_FORMAT "%d %d\n"
+#elif defined(__hpux) || defined(__sun__) || defined(__sgi) || defined(_AIX) \
+ || defined(__sparc)
+# define KWSYSPE_PS_COMMAND "ps -ef"
+# define KWSYSPE_PS_FORMAT "%*s %d %d %*[^\n]\n"
+#elif defined(__QNX__)
+# define KWSYSPE_PS_COMMAND "ps -Af"
+# define KWSYSPE_PS_FORMAT "%*d %d %d %*[^\n]\n"
+#elif defined(__CYGWIN__)
+# define KWSYSPE_PS_COMMAND "ps aux"
+# define KWSYSPE_PS_FORMAT "%d %d %*[^\n]\n"
+#endif
+
+/*--------------------------------------------------------------------------*/
+static void kwsysProcessKill(pid_t process_id)
+{
+#if defined(__linux__) || defined(__CYGWIN__)
+ DIR* procdir;
+#endif
+
+ /* Suspend the process to be sure it will not create more children. */
+ kill(process_id, SIGSTOP);
+
+ /* Kill all children if we can find them. */
+#if defined(__linux__) || defined(__CYGWIN__)
+ /* First try using the /proc filesystem. */
+ if((procdir = opendir("/proc")) != NULL)
+ {
+#if defined(MAXPATHLEN)
+ char fname[MAXPATHLEN];
+#elif defined(PATH_MAX)
+ char fname[PATH_MAX];
+#else
+ char fname[4096];
+#endif
+ char buffer[KWSYSPE_PIPE_BUFFER_SIZE+1];
+ struct dirent* d;
+
+ /* Each process has a directory in /proc whose name is the pid.
+ Within this directory is a file called stat that has the
+ following format:
+
+ pid (command line) status ppid ...
+
+ We want to get the ppid for all processes. Those that have
+ process_id as their parent should be recursively killed. */
+ for(d = readdir(procdir); d; d = readdir(procdir))
+ {
+ int pid;
+ if(sscanf(d->d_name, "%d", &pid) == 1 && pid != 0)
+ {
+ struct stat finfo;
+ sprintf(fname, "/proc/%d/stat", pid);
+ if(stat(fname, &finfo) == 0)
+ {
+ FILE* f = fopen(fname, "r");
+ if(f)
+ {
+ size_t nread = fread(buffer, 1, KWSYSPE_PIPE_BUFFER_SIZE, f);
+ buffer[nread] = '\0';
+ if(nread > 0)
+ {
+ const char* rparen = strrchr(buffer, ')');
+ int ppid;
+ if(rparen && (sscanf(rparen+1, "%*s %d", &ppid) == 1))
+ {
+ if(ppid == process_id)
+ {
+ /* Recursively kill this child and its children. */
+ kwsysProcessKill(pid);
+ }
+ }
+ }
+ fclose(f);
+ }
+ }
+ }
+ }
+ closedir(procdir);
+ }
+ else
+#endif
+ {
+#if defined(KWSYSPE_PS_COMMAND)
+ /* Try running "ps" to get the process information. */
+ FILE* ps = popen(KWSYSPE_PS_COMMAND, "r");
+
+ /* Make sure the process started and provided a valid header. */
+ if(ps && fscanf(ps, "%*[^\n]\n") != EOF)
+ {
+ /* Look for processes whose parent is the process being killed. */
+ int pid, ppid;
+ while(fscanf(ps, KWSYSPE_PS_FORMAT, &pid, &ppid) == 2)
+ {
+ if(ppid == process_id)
+ {
+ /* Recursively kill this child and its children. */
+ kwsysProcessKill(pid);
+ }
+ }
+ }
+
+ /* We are done with the ps process. */
+ if(ps)
+ {
+ pclose(ps);
+ }
+#endif
+ }
+
+ /* Kill the process. */
+ kill(process_id, SIGKILL);
+
+#if defined(__APPLE__)
+ /* On OS X 10.3 the above SIGSTOP occasionally prevents the SIGKILL
+ from working. Just in case, we resume the child and kill it
+ again. There is a small race condition in this obscure case. If
+ the child manages to fork again between these two signals, we
+ will not catch its children. */
+ kill(process_id, SIGCONT);
+ kill(process_id, SIGKILL);
+#endif
+}
+
+/*--------------------------------------------------------------------------*/
+#if defined(__VMS)
+int decc$feature_get_index(const char* name);
+int decc$feature_set_value(int index, int mode, int value);
+static int kwsysProcessSetVMSFeature(const char* name, int value)
+{
+ int i;
+ errno = 0;
+ i = decc$feature_get_index(name);
+ return i >= 0 && (decc$feature_set_value(i, 1, value) >= 0 || errno == 0);
+}
+#endif
+
+/*--------------------------------------------------------------------------*/
+/* Global set of executing processes for use by the signal handler.
+ This global instance will be zero-initialized by the compiler. */
+typedef struct kwsysProcessInstances_s
+{
+ int Count;
+ int Size;
+ kwsysProcess** Processes;
+} kwsysProcessInstances;
+static kwsysProcessInstances kwsysProcesses;
+
+/* The old SIGCHLD handler. */
+static struct sigaction kwsysProcessesOldSigChldAction;
+
+/*--------------------------------------------------------------------------*/
+static void kwsysProcessesUpdate(kwsysProcessInstances* newProcesses)
+{
+ /* Block SIGCHLD 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);
+ sigprocmask(SIG_BLOCK, &newset, &oldset);
+
+ /* Store the new set in that seen by the signal handler. */
+ kwsysProcesses = *newProcesses;
+
+ /* Restore the signal mask to the previous setting. */
+ sigprocmask(SIG_SETMASK, &oldset, 0);
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcessesAdd(kwsysProcess* cp)
+{
+ /* Create a pipe through which the signal handler can notify the
+ given process object that a child has exited. */
+ {
+ /* Create the pipe. */
+ int p[2];
+ if(pipe(p KWSYSPE_VMS_NONBLOCK) < 0)
+ {
+ return 0;
+ }
+
+ /* Store the pipes now to be sure they are cleaned up later. */
+ cp->PipeReadEnds[KWSYSPE_PIPE_SIGNAL] = p[0];
+ cp->SignalPipe = p[1];
+
+ /* Switch the pipe to non-blocking mode so that reading a byte can
+ be an atomic test-and-set. */
+ if(!kwsysProcessSetNonBlocking(p[0]) ||
+ !kwsysProcessSetNonBlocking(p[1]))
+ {
+ return 0;
+ }
+
+ /* The children do not need this pipe. 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))
+ {
+ return 0;
+ }
+ }
+
+ /* Attempt to add the given signal pipe to the signal handler set. */
+ {
+
+ /* Make sure there is enough space for the new signal pipe. */
+ kwsysProcessInstances oldProcesses = kwsysProcesses;
+ kwsysProcessInstances newProcesses = oldProcesses;
+ if(oldProcesses.Count == oldProcesses.Size)
+ {
+ /* Start with enough space for a small number of process instances
+ and double the size each time more is needed. */
+ newProcesses.Size = oldProcesses.Size? oldProcesses.Size*2 : 4;
+
+ /* Try allocating the new block of memory. */
+ if((newProcesses.Processes = ((kwsysProcess**)
+ malloc((size_t)(newProcesses.Size)*
+ sizeof(kwsysProcess*)))))
+ {
+ /* Copy the old pipe set to the new memory. */
+ if(oldProcesses.Count > 0)
+ {
+ memcpy(newProcesses.Processes, oldProcesses.Processes,
+ ((size_t)(oldProcesses.Count) * sizeof(kwsysProcess*)));
+ }
+ }
+ else
+ {
+ /* Failed to allocate memory for the new signal pipe set. */
+ return 0;
+ }
+ }
+
+ /* Append the new signal pipe to the set. */
+ newProcesses.Processes[newProcesses.Count++] = cp;
+
+ /* Store the new set in that seen by the signal handler. */
+ kwsysProcessesUpdate(&newProcesses);
+
+ /* Free the original pipes if new ones were allocated. */
+ if(newProcesses.Processes != oldProcesses.Processes)
+ {
+ free(oldProcesses.Processes);
+ }
+
+ /* If this is the first process, enable the signal handler. */
+ if(newProcesses.Count == 1)
+ {
+ /* Install our handler for SIGCHLD. Repeat call until it is not
+ interrupted. */
+ struct sigaction newSigChldAction;
+ memset(&newSigChldAction, 0, sizeof(struct sigaction));
+#if KWSYSPE_USE_SIGINFO
+ newSigChldAction.sa_sigaction = kwsysProcessesSignalHandler;
+ newSigChldAction.sa_flags = SA_NOCLDSTOP | SA_SIGINFO;
+# ifdef SA_RESTART
+ newSigChldAction.sa_flags |= SA_RESTART;
+# endif
+#else
+ newSigChldAction.sa_handler = kwsysProcessesSignalHandler;
+ newSigChldAction.sa_flags = SA_NOCLDSTOP;
+#endif
+ while((sigaction(SIGCHLD, &newSigChldAction,
+ &kwsysProcessesOldSigChldAction) < 0) &&
+ (errno == EINTR));
+ }
+ }
+
+ return 1;
+}
+
+/*--------------------------------------------------------------------------*/
+static void kwsysProcessesRemove(kwsysProcess* cp)
+{
+ /* Attempt to remove the given signal pipe from the signal handler set. */
+ {
+ /* Find the given process in the set. */
+ kwsysProcessInstances newProcesses = kwsysProcesses;
+ int i;
+ for(i=0; i < newProcesses.Count; ++i)
+ {
+ if(newProcesses.Processes[i] == cp)
+ {
+ break;
+ }
+ }
+ if(i < newProcesses.Count)
+ {
+ /* Remove the process from the set. */
+ --newProcesses.Count;
+ for(; i < newProcesses.Count; ++i)
+ {
+ newProcesses.Processes[i] = newProcesses.Processes[i+1];
+ }
+
+ /* If this was the last process, disable the signal handler. */
+ if(newProcesses.Count == 0)
+ {
+ /* Restore the SIGCHLD handler. Repeat call until it is not
+ interrupted. */
+ while((sigaction(SIGCHLD, &kwsysProcessesOldSigChldAction, 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. */
+ newProcesses.Size = 0;
+ free(newProcesses.Processes);
+ newProcesses.Processes = 0;
+ }
+
+ /* Store the new set in that seen by the signal handler. */
+ kwsysProcessesUpdate(&newProcesses);
+ }
+ }
+
+ /* Close the pipe through which the signal handler may have notified
+ the given process object that a child has exited. */
+ kwsysProcessCleanupDescriptor(&cp->SignalPipe);
+}
+
+/*--------------------------------------------------------------------------*/
+static void kwsysProcessesSignalHandler(int signum
+#if KWSYSPE_USE_SIGINFO
+ , siginfo_t* info, void* ucontext
+#endif
+ )
+{
+ (void)signum;
+#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)
+ {
+ /* 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);
+ status=write(cp->SignalPipe, &buf, 1);
+ (void)status;
+ }
+ }
+
+#if !KWSYSPE_USE_SIGINFO
+ /* Re-Install our handler for SIGCHLD. Repeat call until it is not
+ interrupted. */
+ {
+ struct sigaction newSigChldAction;
+ memset(&newSigChldAction, 0, sizeof(struct sigaction));
+ newSigChldAction.sa_handler = kwsysProcessesSignalHandler;
+ newSigChldAction.sa_flags = SA_NOCLDSTOP;
+ while((sigaction(SIGCHLD, &newSigChldAction,
+ &kwsysProcessesOldSigChldAction) < 0) &&
+ (errno == EINTR));
+ }
+#endif
+}
diff --git a/Source/kwsys/ProcessWin32.c b/Source/kwsys/ProcessWin32.c
new file mode 100644
index 000000000..5aa4d8bf6
--- /dev/null
+++ b/Source/kwsys/ProcessWin32.c
@@ -0,0 +1,2952 @@
+/*============================================================================
+ 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(Process.h)
+#include KWSYS_HEADER(System.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"
+#endif
+
+/*
+
+Implementation for Windows
+
+On windows, a thread is created to wait for data on each pipe. The
+threads are synchronized with the main thread to simulate the use of
+a UNIX-style select system call.
+
+On Windows9x platforms, a small WIN32 console application is spawned
+in-between the calling process and the actual child to be executed.
+This is to work-around a problem with connecting pipes from WIN16
+console applications to WIN32 applications.
+
+For more information, please check Microsoft Knowledge Base Articles
+Q190351 and Q150956.
+
+*/
+
+#ifdef _MSC_VER
+#pragma warning (push, 1)
+#endif
+#include <windows.h> /* Windows API */
+#include <string.h> /* strlen, strdup */
+#include <stdio.h> /* sprintf */
+#include <io.h> /* _unlink */
+#ifdef __WATCOMC__
+#define _unlink unlink
+#endif
+
+#ifndef _MAX_FNAME
+#define _MAX_FNAME 4096
+#endif
+#ifndef _MAX_PATH
+#define _MAX_PATH 4096
+#endif
+
+#ifdef _MSC_VER
+#pragma warning (pop)
+#pragma warning (disable: 4514)
+#pragma warning (disable: 4706)
+#endif
+
+#if defined(__BORLANDC__)
+# pragma warn -8004 /* assigned a value that is never used */
+# pragma warn -8060 /* Assignment inside if() condition. */
+#endif
+
+/* There are pipes for the process pipeline's stdout and stderr. */
+#define KWSYSPE_PIPE_COUNT 2
+#define KWSYSPE_PIPE_STDOUT 0
+#define KWSYSPE_PIPE_STDERR 1
+
+/* The maximum amount to read from a pipe at a time. */
+#define KWSYSPE_PIPE_BUFFER_SIZE 1024
+
+/* Debug output macro. */
+#if 0
+# define KWSYSPE_DEBUG(x) \
+( \
+ (void*)cp == (void*)0x00226DE0? \
+ ( \
+ fprintf(stderr, "%d/%p/%d ", (int)GetCurrentProcessId(), cp, __LINE__), \
+ fprintf x, \
+ fflush(stderr), \
+ 1 \
+ ) : (1) \
+)
+#else
+# define KWSYSPE_DEBUG(x) (void)1
+#endif
+
+#define kwsysEncodedWriteArrayProcessFwd9x kwsys_ns(EncodedWriteArrayProcessFwd9x)
+
+typedef LARGE_INTEGER kwsysProcessTime;
+
+typedef struct kwsysProcessCreateInformation_s
+{
+ /* Windows child startup control data. */
+ STARTUPINFO StartupInfo;
+
+ /* Special error reporting pipe for Win9x forwarding executable. */
+ HANDLE ErrorPipeRead;
+ HANDLE ErrorPipeWrite;
+} kwsysProcessCreateInformation;
+
+/*--------------------------------------------------------------------------*/
+typedef struct kwsysProcessPipeData_s kwsysProcessPipeData;
+static DWORD WINAPI kwsysProcessPipeThreadRead(LPVOID ptd);
+static void kwsysProcessPipeThreadReadPipe(kwsysProcess* cp,
+ kwsysProcessPipeData* td);
+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 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 void kwsysProcessCleanupHandle(PHANDLE h);
+static void kwsysProcessCleanupHandleSafe(PHANDLE h, DWORD nStdHandle);
+static void kwsysProcessCleanup(kwsysProcess* cp, int 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,
+ double* userTimeout,
+ kwsysProcessTime* timeoutLength);
+static kwsysProcessTime kwsysProcessTimeGetCurrent(void);
+static DWORD kwsysProcessTimeToDWORD(kwsysProcessTime t);
+static double kwsysProcessTimeToDouble(kwsysProcessTime t);
+static kwsysProcessTime kwsysProcessTimeFromDouble(double d);
+static int kwsysProcessTimeLess(kwsysProcessTime in1, kwsysProcessTime in2);
+static kwsysProcessTime kwsysProcessTimeAdd(kwsysProcessTime in1, kwsysProcessTime in2);
+static kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1, kwsysProcessTime in2);
+static void kwsysProcessSetExitException(kwsysProcess* cp, int code);
+static void kwsysProcessKillTree(int pid);
+static void kwsysProcessDisablePipeThreads(kwsysProcess* cp);
+extern kwsysEXPORT int kwsysEncodedWriteArrayProcessFwd9x(const char* fname);
+
+/*--------------------------------------------------------------------------*/
+/* A structure containing synchronization data for each thread. */
+typedef struct kwsysProcessPipeSync_s kwsysProcessPipeSync;
+struct kwsysProcessPipeSync_s
+{
+ /* Handle to the thread. */
+ HANDLE Thread;
+
+ /* Semaphore indicating to the thread that a process has started. */
+ HANDLE Ready;
+
+ /* Semaphore indicating to the thread that it should begin work. */
+ HANDLE Go;
+
+ /* Semaphore indicating thread has reset for another process. */
+ HANDLE Reset;
+};
+
+/*--------------------------------------------------------------------------*/
+/* A structure containing data for each pipe's threads. */
+struct kwsysProcessPipeData_s
+{
+ /* ------------- Data managed per instance of kwsysProcess ------------- */
+
+ /* Synchronization data for reading thread. */
+ kwsysProcessPipeSync Reader;
+
+ /* Synchronization data for waking thread. */
+ kwsysProcessPipeSync Waker;
+
+ /* Index of this pipe. */
+ int Index;
+
+ /* The kwsysProcess instance owning this pipe. */
+ kwsysProcess* Process;
+
+ /* ------------- Data managed per call to Execute ------------- */
+
+ /* Buffer for data read in this pipe's thread. */
+ char DataBuffer[KWSYSPE_PIPE_BUFFER_SIZE];
+
+ /* The length of the data stored in the buffer. */
+ DWORD DataLength;
+
+ /* Whether the pipe has been closed. */
+ int Closed;
+
+ /* Handle for the read end of this pipe. */
+ HANDLE Read;
+
+ /* Handle for the write end of this pipe. */
+ HANDLE Write;
+};
+
+/*--------------------------------------------------------------------------*/
+/* Structure containing data used to implement the child's execution. */
+struct kwsysProcess_s
+{
+ /* ------------- Data managed per instance of kwsysProcess ------------- */
+
+ /* The status of the process structure. */
+ int State;
+
+ /* The command lines to execute. */
+ char** Commands;
+ int NumberOfCommands;
+
+ /* The exit code of each command. */
+ DWORD* CommandExitCodes;
+
+ /* The working directory for the child process. */
+ char* WorkingDirectory;
+
+ /* Whether to create the child as a detached process. */
+ int OptionDetach;
+
+ /* Whether the child was created as a detached process. */
+ int Detached;
+
+ /* Whether to hide the child process's window. */
+ int HideWindow;
+
+ /* Whether to treat command lines as verbatim. */
+ int Verbatim;
+
+ /* On Win9x platforms, the path to the forwarding executable. */
+ char* Win9x;
+
+ /* On Win9x platforms, the resume event for the forwarding executable. */
+ HANDLE Win9xResumeEvent;
+
+ /* On Win9x platforms, the kill event for the forwarding executable. */
+ HANDLE Win9xKillEvent;
+
+ /* Mutex to protect the shared index used by threads to report data. */
+ HANDLE SharedIndexMutex;
+
+ /* Semaphore used by threads to signal data ready. */
+ HANDLE Full;
+
+ /* Whether we are currently deleting this kwsysProcess instance. */
+ int Deleting;
+
+ /* Data specific to each pipe and its thread. */
+ kwsysProcessPipeData Pipe[KWSYSPE_PIPE_COUNT];
+
+ /* Name of files to which stdin and stdout pipes are attached. */
+ char* PipeFileSTDIN;
+ char* PipeFileSTDOUT;
+ char* PipeFileSTDERR;
+
+ /* Whether each pipe is shared with the parent process. */
+ int PipeSharedSTDIN;
+ int PipeSharedSTDOUT;
+ int PipeSharedSTDERR;
+
+ /* Native pipes provided by the user. */
+ HANDLE PipeNativeSTDIN[2];
+ HANDLE PipeNativeSTDOUT[2];
+ HANDLE PipeNativeSTDERR[2];
+
+ /* Handle to automatically delete the Win9x forwarding executable. */
+ HANDLE Win9xHandle;
+
+ /* ------------- Data managed per call to Execute ------------- */
+
+ /* The exceptional behavior that terminated the process, if any. */
+ int ExitException;
+
+ /* The process exit code. */
+ DWORD ExitCode;
+
+ /* The process return code, if any. */
+ int ExitValue;
+
+ /* Index of last pipe to report data, if any. */
+ int CurrentIndex;
+
+ /* Index shared by threads to report data. */
+ int SharedIndex;
+
+ /* The timeout length. */
+ double Timeout;
+
+ /* Time at which the child started. */
+ kwsysProcessTime StartTime;
+
+ /* Time at which the child will timeout. Negative for no timeout. */
+ kwsysProcessTime TimeoutTime;
+
+ /* Flag for whether the process was killed. */
+ int Killed;
+
+ /* Flag for whether the timeout expired. */
+ int TimeoutExpired;
+
+ /* Flag for whether the process has terminated. */
+ int Terminated;
+
+ /* The number of pipes still open during execution and while waiting
+ for pipes to close after process termination. */
+ int PipesLeft;
+
+ /* Buffer for error messages (possibly from Win9x child). */
+ char ErrorMessage[KWSYSPE_PIPE_BUFFER_SIZE+1];
+
+ /* Description for the ExitException. */
+ char ExitExceptionString[KWSYSPE_PIPE_BUFFER_SIZE+1];
+
+ /* Windows process information data. */
+ PROCESS_INFORMATION* ProcessInformation;
+
+ /* Data and process termination events for which to wait. */
+ PHANDLE ProcessEvents;
+ int ProcessEventsLength;
+
+ /* Real working directory of our own process. */
+ DWORD RealWorkingDirectoryLength;
+ char* RealWorkingDirectory;
+};
+
+/*--------------------------------------------------------------------------*/
+kwsysProcess* kwsysProcess_New(void)
+{
+ int i;
+
+ /* Process control structure. */
+ kwsysProcess* cp;
+
+ /* Path to Win9x forwarding executable. */
+ char* win9x = 0;
+
+ /* Windows version number data. */
+ OSVERSIONINFO osv;
+
+ /* Allocate a process control structure. */
+ cp = (kwsysProcess*)malloc(sizeof(kwsysProcess));
+ if(!cp)
+ {
+ /* Could not allocate memory for the control structure. */
+ return 0;
+ }
+ ZeroMemory(cp, sizeof(*cp));
+
+ /* Share stdin with the parent process by default. */
+ cp->PipeSharedSTDIN = 1;
+
+ /* Set initial status. */
+ cp->State = kwsysProcess_State_Starting;
+
+ /* Choose a method of running the child based on version of
+ windows. */
+ ZeroMemory(&osv, sizeof(osv));
+ osv.dwOSVersionInfoSize = sizeof(osv);
+ GetVersionEx(&osv);
+ if(osv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
+ {
+ /* This is Win9x. We need the console forwarding executable to
+ work-around a Windows 9x bug. */
+ char fwdName[_MAX_FNAME+1] = "";
+ char tempDir[_MAX_PATH+1] = "";
+
+ /* We will try putting the executable in the system temp
+ directory. Note that the returned path already has a trailing
+ slash. */
+ DWORD length = GetTempPath(_MAX_PATH+1, tempDir);
+
+ /* Construct the executable name from the process id and kwsysProcess
+ instance. This should be unique. */
+ sprintf(fwdName, KWSYS_NAMESPACE_STRING "pew9xfwd_%ld_%p.exe",
+ GetCurrentProcessId(), cp);
+
+ /* If we have a temp directory, use it. */
+ if(length > 0 && length <= _MAX_PATH)
+ {
+ /* Allocate a buffer to hold the forwarding executable path. */
+ size_t tdlen = strlen(tempDir);
+ win9x = (char*)malloc(tdlen + strlen(fwdName) + 2);
+ if(!win9x)
+ {
+ kwsysProcess_Delete(cp);
+ return 0;
+ }
+
+ /* Construct the full path to the forwarding executable. */
+ sprintf(win9x, "%s%s", tempDir, fwdName);
+ }
+
+ /* If we found a place to put the forwarding executable, try to
+ write it. */
+ if(win9x)
+ {
+ if(!kwsysEncodedWriteArrayProcessFwd9x(win9x))
+ {
+ /* Failed to create forwarding executable. Give up. */
+ free(win9x);
+ kwsysProcess_Delete(cp);
+ return 0;
+ }
+
+ /* Get a handle to the file that will delete it when closed. */
+ cp->Win9xHandle = CreateFile(win9x, GENERIC_READ, FILE_SHARE_READ, 0,
+ OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, 0);
+ if(cp->Win9xHandle == INVALID_HANDLE_VALUE)
+ {
+ /* We were not able to get a read handle for the forwarding
+ executable. It will not be deleted properly. Give up. */
+ _unlink(win9x);
+ free(win9x);
+ kwsysProcess_Delete(cp);
+ return 0;
+ }
+ }
+ else
+ {
+ /* Failed to find a place to put forwarding executable. */
+ kwsysProcess_Delete(cp);
+ return 0;
+ }
+ }
+
+ /* Save the path to the forwarding executable. */
+ cp->Win9x = win9x;
+
+ /* Initially no thread owns the mutex. Initialize semaphore to 1. */
+ if(!(cp->SharedIndexMutex = CreateSemaphore(0, 1, 1, 0)))
+ {
+ kwsysProcess_Delete(cp);
+ return 0;
+ }
+
+ /* Initially no data are available. Initialize semaphore to 0. */
+ if(!(cp->Full = CreateSemaphore(0, 0, 1, 0)))
+ {
+ kwsysProcess_Delete(cp);
+ return 0;
+ }
+
+ if(cp->Win9x)
+ {
+ SECURITY_ATTRIBUTES sa;
+ ZeroMemory(&sa, sizeof(sa));
+ sa.nLength = sizeof(sa);
+ sa.bInheritHandle = TRUE;
+
+ /* Create an event to tell the forwarding executable to resume the
+ child. */
+ if(!(cp->Win9xResumeEvent = CreateEvent(&sa, TRUE, 0, 0)))
+ {
+ kwsysProcess_Delete(cp);
+ return 0;
+ }
+
+ /* Create an event to tell the forwarding executable to kill the
+ child. */
+ if(!(cp->Win9xKillEvent = CreateEvent(&sa, TRUE, 0, 0)))
+ {
+ kwsysProcess_Delete(cp);
+ return 0;
+ }
+ }
+
+ /* Create the thread to read each pipe. */
+ for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
+ {
+ DWORD dummy=0;
+
+ /* Assign the thread its index. */
+ cp->Pipe[i].Index = i;
+
+ /* Give the thread a pointer back to the kwsysProcess instance. */
+ cp->Pipe[i].Process = cp;
+
+ /* No process is yet running. Initialize semaphore to 0. */
+ if(!(cp->Pipe[i].Reader.Ready = CreateSemaphore(0, 0, 1, 0)))
+ {
+ kwsysProcess_Delete(cp);
+ return 0;
+ }
+
+ /* The pipe is not yet reset. Initialize semaphore to 0. */
+ if(!(cp->Pipe[i].Reader.Reset = CreateSemaphore(0, 0, 1, 0)))
+ {
+ kwsysProcess_Delete(cp);
+ return 0;
+ }
+
+ /* The thread's buffer is initially empty. Initialize semaphore to 1. */
+ if(!(cp->Pipe[i].Reader.Go = CreateSemaphore(0, 1, 1, 0)))
+ {
+ kwsysProcess_Delete(cp);
+ return 0;
+ }
+
+ /* Create the reading thread. It will block immediately. The
+ thread will not make deeply nested calls, so we need only a
+ small stack. */
+ if(!(cp->Pipe[i].Reader.Thread = CreateThread(0, 1024,
+ kwsysProcessPipeThreadRead,
+ &cp->Pipe[i], 0, &dummy)))
+ {
+ kwsysProcess_Delete(cp);
+ return 0;
+ }
+
+ /* No process is yet running. Initialize semaphore to 0. */
+ if(!(cp->Pipe[i].Waker.Ready = CreateSemaphore(0, 0, 1, 0)))
+ {
+ kwsysProcess_Delete(cp);
+ return 0;
+ }
+
+ /* The pipe is not yet reset. Initialize semaphore to 0. */
+ if(!(cp->Pipe[i].Waker.Reset = CreateSemaphore(0, 0, 1, 0)))
+ {
+ kwsysProcess_Delete(cp);
+ return 0;
+ }
+
+ /* The waker should not wake immediately. Initialize semaphore to 0. */
+ if(!(cp->Pipe[i].Waker.Go = CreateSemaphore(0, 0, 1, 0)))
+ {
+ kwsysProcess_Delete(cp);
+ return 0;
+ }
+
+ /* Create the waking thread. It will block immediately. The
+ thread will not make deeply nested calls, so we need only a
+ small stack. */
+ if(!(cp->Pipe[i].Waker.Thread = CreateThread(0, 1024,
+ kwsysProcessPipeThreadWake,
+ &cp->Pipe[i], 0, &dummy)))
+ {
+ kwsysProcess_Delete(cp);
+ return 0;
+ }
+ }
+
+ return cp;
+}
+
+/*--------------------------------------------------------------------------*/
+void kwsysProcess_Delete(kwsysProcess* cp)
+{
+ int i;
+
+ /* Make sure we have an instance. */
+ if(!cp)
+ {
+ return;
+ }
+
+ /* If the process is executing, wait for it to finish. */
+ if(cp->State == kwsysProcess_State_Executing)
+ {
+ if(cp->Detached)
+ {
+ kwsysProcess_Disown(cp);
+ }
+ else
+ {
+ kwsysProcess_WaitForExit(cp, 0);
+ }
+ }
+
+ /* We are deleting the kwsysProcess instance. */
+ cp->Deleting = 1;
+
+ /* Terminate each of the threads. */
+ for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
+ {
+ /* Terminate this reading thread. */
+ if(cp->Pipe[i].Reader.Thread)
+ {
+ /* Signal the thread we are ready for it. It will terminate
+ immediately since Deleting is set. */
+ ReleaseSemaphore(cp->Pipe[i].Reader.Ready, 1, 0);
+
+ /* Wait for the thread to exit. */
+ WaitForSingleObject(cp->Pipe[i].Reader.Thread, INFINITE);
+
+ /* Close the handle to the thread. */
+ kwsysProcessCleanupHandle(&cp->Pipe[i].Reader.Thread);
+ }
+
+ /* Terminate this waking thread. */
+ if(cp->Pipe[i].Waker.Thread)
+ {
+ /* Signal the thread we are ready for it. It will terminate
+ immediately since Deleting is set. */
+ ReleaseSemaphore(cp->Pipe[i].Waker.Ready, 1, 0);
+
+ /* Wait for the thread to exit. */
+ WaitForSingleObject(cp->Pipe[i].Waker.Thread, INFINITE);
+
+ /* Close the handle to the thread. */
+ kwsysProcessCleanupHandle(&cp->Pipe[i].Waker.Thread);
+ }
+
+ /* Cleanup the pipe's semaphores. */
+ kwsysProcessCleanupHandle(&cp->Pipe[i].Reader.Ready);
+ kwsysProcessCleanupHandle(&cp->Pipe[i].Reader.Go);
+ kwsysProcessCleanupHandle(&cp->Pipe[i].Reader.Reset);
+ kwsysProcessCleanupHandle(&cp->Pipe[i].Waker.Ready);
+ kwsysProcessCleanupHandle(&cp->Pipe[i].Waker.Go);
+ kwsysProcessCleanupHandle(&cp->Pipe[i].Waker.Reset);
+ }
+
+ /* Close the shared semaphores. */
+ kwsysProcessCleanupHandle(&cp->SharedIndexMutex);
+ kwsysProcessCleanupHandle(&cp->Full);
+
+ /* Close the Win9x resume and kill event handles. */
+ if(cp->Win9x)
+ {
+ kwsysProcessCleanupHandle(&cp->Win9xResumeEvent);
+ kwsysProcessCleanupHandle(&cp->Win9xKillEvent);
+ }
+
+ /* Free memory. */
+ kwsysProcess_SetCommand(cp, 0);
+ kwsysProcess_SetWorkingDirectory(cp, 0);
+ kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDIN, 0);
+ kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDOUT, 0);
+ kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDERR, 0);
+ if(cp->CommandExitCodes)
+ {
+ free(cp->CommandExitCodes);
+ }
+ if(cp->Win9x)
+ {
+ /* Close our handle to the forwarding executable file. This will
+ cause it to be deleted. */
+ kwsysProcessCleanupHandle(&cp->Win9xHandle);
+ }
+ free(cp);
+}
+
+/*--------------------------------------------------------------------------*/
+int kwsysProcess_SetCommand(kwsysProcess* cp, char const* const* command)
+{
+ int i;
+ if(!cp)
+ {
+ return 0;
+ }
+ for(i=0; i < cp->NumberOfCommands; ++i)
+ {
+ free(cp->Commands[i]);
+ }
+ cp->NumberOfCommands = 0;
+ if(cp->Commands)
+ {
+ free(cp->Commands);
+ cp->Commands = 0;
+ }
+ if(command)
+ {
+ return kwsysProcess_AddCommand(cp, command);
+ }
+ return 1;
+}
+
+/*--------------------------------------------------------------------------*/
+int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command)
+{
+ int newNumberOfCommands;
+ char** newCommands;
+
+ /* Make sure we have a command to add. */
+ if(!cp || !command || !*command)
+ {
+ return 0;
+ }
+
+ /* Allocate a new array for command pointers. */
+ newNumberOfCommands = cp->NumberOfCommands + 1;
+ if(!(newCommands = (char**)malloc(sizeof(char*) * newNumberOfCommands)))
+ {
+ /* Out of memory. */
+ return 0;
+ }
+
+ /* Copy any existing commands into the new array. */
+ {
+ int i;
+ for(i=0; i < cp->NumberOfCommands; ++i)
+ {
+ newCommands[i] = cp->Commands[i];
+ }
+ }
+
+ /* 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])
+ {
+ /* Out of memory. */
+ 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;
+ cp->NumberOfCommands = newNumberOfCommands;
+ return 1;
+}
+
+/*--------------------------------------------------------------------------*/
+void kwsysProcess_SetTimeout(kwsysProcess* cp, double timeout)
+{
+ if(!cp)
+ {
+ return;
+ }
+ cp->Timeout = timeout;
+ if(cp->Timeout < 0)
+ {
+ cp->Timeout = 0;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+int kwsysProcess_SetWorkingDirectory(kwsysProcess* cp, const char* dir)
+{
+ if(!cp)
+ {
+ return 0;
+ }
+ if(cp->WorkingDirectory)
+ {
+ free(cp->WorkingDirectory);
+ cp->WorkingDirectory = 0;
+ }
+ if(dir && dir[0])
+ {
+ /* We must convert the working directory to a full path. */
+ DWORD length = GetFullPathName(dir, 0, 0, 0);
+ if(length > 0)
+ {
+ cp->WorkingDirectory = (char*)malloc(length);
+ if(!cp->WorkingDirectory)
+ {
+ return 0;
+ }
+ if(!GetFullPathName(dir, length, cp->WorkingDirectory, 0))
+ {
+ free(cp->WorkingDirectory);
+ cp->WorkingDirectory = 0;
+ return 0;
+ }
+ }
+ }
+ return 1;
+}
+
+/*--------------------------------------------------------------------------*/
+int kwsysProcess_SetPipeFile(kwsysProcess* cp, int pipe, const char* file)
+{
+ char** pfile;
+ if(!cp)
+ {
+ return 0;
+ }
+ switch(pipe)
+ {
+ case kwsysProcess_Pipe_STDIN: pfile = &cp->PipeFileSTDIN; break;
+ case kwsysProcess_Pipe_STDOUT: pfile = &cp->PipeFileSTDOUT; break;
+ case kwsysProcess_Pipe_STDERR: pfile = &cp->PipeFileSTDERR; break;
+ default: return 0;
+ }
+ if(*pfile)
+ {
+ free(*pfile);
+ *pfile = 0;
+ }
+ if(file)
+ {
+ *pfile = (char*)malloc(strlen(file)+1);
+ if(!*pfile)
+ {
+ return 0;
+ }
+ strcpy(*pfile, file);
+ }
+
+ /* If we are redirecting the pipe, do not share it or use a native
+ pipe. */
+ if(*pfile)
+ {
+ kwsysProcess_SetPipeNative(cp, pipe, 0);
+ kwsysProcess_SetPipeShared(cp, pipe, 0);
+ }
+
+ return 1;
+}
+
+/*--------------------------------------------------------------------------*/
+void kwsysProcess_SetPipeShared(kwsysProcess* cp, int pipe, int shared)
+{
+ if(!cp)
+ {
+ return;
+ }
+
+ switch(pipe)
+ {
+ case kwsysProcess_Pipe_STDIN: cp->PipeSharedSTDIN = shared?1:0; break;
+ case kwsysProcess_Pipe_STDOUT: cp->PipeSharedSTDOUT = shared?1:0; break;
+ case kwsysProcess_Pipe_STDERR: cp->PipeSharedSTDERR = shared?1:0; break;
+ default: return;
+ }
+
+ /* If we are sharing the pipe, do not redirect it to a file or use a
+ native pipe. */
+ if(shared)
+ {
+ kwsysProcess_SetPipeFile(cp, pipe, 0);
+ kwsysProcess_SetPipeNative(cp, pipe, 0);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+void kwsysProcess_SetPipeNative(kwsysProcess* cp, int pipe, HANDLE p[2])
+{
+ HANDLE* pPipeNative = 0;
+
+ if(!cp)
+ {
+ return;
+ }
+
+ switch(pipe)
+ {
+ case kwsysProcess_Pipe_STDIN: pPipeNative = cp->PipeNativeSTDIN; break;
+ case kwsysProcess_Pipe_STDOUT: pPipeNative = cp->PipeNativeSTDOUT; break;
+ case kwsysProcess_Pipe_STDERR: pPipeNative = cp->PipeNativeSTDERR; break;
+ default: return;
+ }
+
+ /* Copy the native pipe handles provided. */
+ if(p)
+ {
+ pPipeNative[0] = p[0];
+ pPipeNative[1] = p[1];
+ }
+ else
+ {
+ pPipeNative[0] = 0;
+ pPipeNative[1] = 0;
+ }
+
+ /* If we are using a native pipe, do not share it or redirect it to
+ a file. */
+ if(p)
+ {
+ kwsysProcess_SetPipeFile(cp, pipe, 0);
+ kwsysProcess_SetPipeShared(cp, pipe, 0);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+int kwsysProcess_GetOption(kwsysProcess* cp, int optionId)
+{
+ if(!cp)
+ {
+ return 0;
+ }
+
+ switch(optionId)
+ {
+ case kwsysProcess_Option_Detach: return cp->OptionDetach;
+ case kwsysProcess_Option_HideWindow: return cp->HideWindow;
+ case kwsysProcess_Option_Verbatim: return cp->Verbatim;
+ default: return 0;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+void kwsysProcess_SetOption(kwsysProcess* cp, int optionId, int value)
+{
+ if(!cp)
+ {
+ return;
+ }
+
+ switch(optionId)
+ {
+ case kwsysProcess_Option_Detach: cp->OptionDetach = value; break;
+ case kwsysProcess_Option_HideWindow: cp->HideWindow = value; break;
+ case kwsysProcess_Option_Verbatim: cp->Verbatim = value; break;
+ default: break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+int kwsysProcess_GetState(kwsysProcess* cp)
+{
+ return cp? cp->State : kwsysProcess_State_Error;
+}
+
+/*--------------------------------------------------------------------------*/
+int kwsysProcess_GetExitException(kwsysProcess* cp)
+{
+ return cp? cp->ExitException : kwsysProcess_Exception_Other;
+}
+
+/*--------------------------------------------------------------------------*/
+int kwsysProcess_GetExitValue(kwsysProcess* cp)
+{
+ return cp? cp->ExitValue : -1;
+}
+
+/*--------------------------------------------------------------------------*/
+int kwsysProcess_GetExitCode(kwsysProcess* cp)
+{
+ return cp? cp->ExitCode : 0;
+}
+
+/*--------------------------------------------------------------------------*/
+const char* kwsysProcess_GetErrorString(kwsysProcess* cp)
+{
+ if(!cp)
+ {
+ return "Process management structure could not be allocated";
+ }
+ else if(cp->State == kwsysProcess_State_Error)
+ {
+ return cp->ErrorMessage;
+ }
+ return "Success";
+}
+
+/*--------------------------------------------------------------------------*/
+const char* kwsysProcess_GetExceptionString(kwsysProcess* cp)
+{
+ if(!cp)
+ {
+ return "GetExceptionString called with NULL process management structure";
+ }
+ else if(cp->State == kwsysProcess_State_Exception)
+ {
+ return cp->ExitExceptionString;
+ }
+ return "No exception";
+}
+
+/*--------------------------------------------------------------------------*/
+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)
+ {
+ return;
+ }
+
+ /* Make sure we have something to run. */
+ if(cp->NumberOfCommands < 1)
+ {
+ strcpy(cp->ErrorMessage, "No command");
+ cp->State = kwsysProcess_State_Error;
+ return;
+ }
+
+ /* Initialize the control structure for a new process. */
+ if(!kwsysProcessInitialize(cp))
+ {
+ strcpy(cp->ErrorMessage, "Out of memory");
+ cp->State = kwsysProcess_State_Error;
+ return;
+ }
+
+ /* Save the real working directory of this process and change to
+ the working directory for the child processes. This is needed
+ to make pipe file paths evaluate correctly. */
+ if(cp->WorkingDirectory)
+ {
+ if(!GetCurrentDirectory(cp->RealWorkingDirectoryLength,
+ cp->RealWorkingDirectory))
+ {
+ kwsysProcessCleanup(cp, 1);
+ return;
+ }
+ SetCurrentDirectory(cp->WorkingDirectory);
+ }
+
+ /* Reset the Win9x resume and kill events. */
+ if(cp->Win9x)
+ {
+ if(!ResetEvent(cp->Win9xResumeEvent))
+ {
+ kwsysProcessCleanup(cp, 1);
+ return;
+ }
+ if(!ResetEvent(cp->Win9xKillEvent))
+ {
+ kwsysProcessCleanup(cp, 1);
+ return;
+ }
+ }
+
+ /* 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))
+ {
+ kwsysProcessCleanup(cp, 1);
+ return;
+ }
+
+ /* 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))
+ {
+ kwsysProcessCleanup(cp, 1);
+ kwsysProcessCleanupHandle(&si.StartupInfo.hStdError);
+ 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(!kwsysProcessSetupOutputPipeFile(&si.StartupInfo.hStdError,
+ cp->PipeFileSTDERR))
+ {
+ kwsysProcessCleanup(cp, 1);
+ kwsysProcessCleanupHandle(&si.StartupInfo.hStdError);
+ 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)
+ {
+ if(!kwsysProcessSetupSharedPipe(STD_ERROR_HANDLE,
+ &si.StartupInfo.hStdError))
+ {
+ kwsysProcessCleanup(cp, 1);
+ kwsysProcessCleanupHandleSafe(&si.StartupInfo.hStdError,
+ STD_ERROR_HANDLE);
+ 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])
+ {
+ if(!kwsysProcessSetupPipeNative(&si.StartupInfo.hStdError,
+ cp->PipeNativeSTDERR, 1))
+ {
+ kwsysProcessCleanup(cp, 1);
+ kwsysProcessCleanupHandleSafe(&si.StartupInfo.hStdError,
+ STD_ERROR_HANDLE);
+ return;
+ }
+ }
+
+ /* Create the pipeline of processes. */
+ {
+ HANDLE readEnd = 0;
+ for(i=0; i < cp->NumberOfCommands; ++i)
+ {
+ if(kwsysProcessCreate(cp, i, &si, &readEnd))
+ {
+ 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);
+ kwsysProcessCleanupHandle(&si.ErrorPipeRead);
+ kwsysProcessCleanupHandle(&si.ErrorPipeWrite);
+ 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);
+
+ /* Restore the working directory. */
+ if(cp->RealWorkingDirectory)
+ {
+ SetCurrentDirectory(cp->RealWorkingDirectory);
+ free(cp->RealWorkingDirectory);
+ cp->RealWorkingDirectory = 0;
+ }
+
+ /* The timeout period starts now. */
+ cp->StartTime = kwsysProcessTimeGetCurrent();
+ cp->TimeoutTime = kwsysProcessTimeFromDouble(-1);
+
+ /* All processes in the pipeline have been started in suspended
+ mode. Resume them all now. */
+ if(cp->Win9x)
+ {
+ SetEvent(cp->Win9xResumeEvent);
+ }
+ else
+ {
+ for(i=0; i < cp->NumberOfCommands; ++i)
+ {
+ ResumeThread(cp->ProcessInformation[i].hThread);
+ }
+ }
+
+ /* ---- It is no longer safe to call kwsysProcessCleanup. ----- */
+ /* Tell the pipe threads that a process has started. */
+ for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
+ {
+ ReleaseSemaphore(cp->Pipe[i].Reader.Ready, 1, 0);
+ ReleaseSemaphore(cp->Pipe[i].Waker.Ready, 1, 0);
+ }
+
+ /* We don't care about the children's main threads. */
+ for(i=0; i < cp->NumberOfCommands; ++i)
+ {
+ kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hThread);
+ }
+
+ /* No pipe has reported data. */
+ cp->CurrentIndex = KWSYSPE_PIPE_COUNT;
+ cp->PipesLeft = KWSYSPE_PIPE_COUNT;
+
+ /* The process has now started. */
+ cp->State = kwsysProcess_State_Executing;
+ cp->Detached = cp->OptionDetach;
+}
+
+/*--------------------------------------------------------------------------*/
+void kwsysProcess_Disown(kwsysProcess* cp)
+{
+ int i;
+
+ /* Make sure we are executing a detached process. */
+ if(!cp || !cp->Detached || cp->State != kwsysProcess_State_Executing ||
+ cp->TimeoutExpired || cp->Killed || cp->Terminated)
+ {
+ return;
+ }
+
+ /* Disable the reading threads. */
+ kwsysProcessDisablePipeThreads(cp);
+
+ /* Wait for all pipe threads to reset. */
+ for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
+ {
+ WaitForSingleObject(cp->Pipe[i].Reader.Reset, INFINITE);
+ WaitForSingleObject(cp->Pipe[i].Waker.Reset, INFINITE);
+ }
+
+ /* We will not wait for exit, so cleanup now. */
+ kwsysProcessCleanup(cp, 0);
+
+ /* The process has been disowned. */
+ cp->State = kwsysProcess_State_Disowned;
+}
+
+/*--------------------------------------------------------------------------*/
+
+int kwsysProcess_WaitForData(kwsysProcess* cp, char** data, int* length,
+ double* userTimeout)
+{
+ kwsysProcessTime userStartTime;
+ kwsysProcessTime timeoutLength;
+ kwsysProcessTime timeoutTime;
+ DWORD timeout;
+ int user;
+ int done = 0;
+ int expired = 0;
+ int pipeId = kwsysProcess_Pipe_None;
+ DWORD w;
+
+ /* Make sure we are executing a process. */
+ if(!cp || cp->State != kwsysProcess_State_Executing || cp->Killed ||
+ cp->TimeoutExpired)
+ {
+ return kwsysProcess_Pipe_None;
+ }
+
+ /* Record the time at which user timeout period starts. */
+ userStartTime = kwsysProcessTimeGetCurrent();
+
+ /* Calculate the time at which a timeout will expire, and whether it
+ is the user or process timeout. */
+ user = kwsysProcessGetTimeoutTime(cp, userTimeout, &timeoutTime);
+
+ /* Loop until we have a reason to return. */
+ while(!done && cp->PipesLeft > 0)
+ {
+ /* If we previously got data from a thread, let it know we are
+ done with the data. */
+ if(cp->CurrentIndex < KWSYSPE_PIPE_COUNT)
+ {
+ KWSYSPE_DEBUG((stderr, "releasing reader %d\n", cp->CurrentIndex));
+ ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Reader.Go, 1, 0);
+ cp->CurrentIndex = KWSYSPE_PIPE_COUNT;
+ }
+
+ /* Setup a timeout if required. */
+ if(kwsysProcessGetTimeoutLeft(&timeoutTime, user?userTimeout:0,
+ &timeoutLength))
+ {
+ /* Timeout has already expired. */
+ expired = 1;
+ break;
+ }
+ if(timeoutTime.QuadPart < 0)
+ {
+ timeout = INFINITE;
+ }
+ else
+ {
+ timeout = kwsysProcessTimeToDWORD(timeoutLength);
+ }
+
+ /* Wait for a pipe's thread to signal or a process to terminate. */
+ w = WaitForMultipleObjects(cp->ProcessEventsLength, cp->ProcessEvents,
+ 0, timeout);
+ if(w == WAIT_TIMEOUT)
+ {
+ /* Timeout has expired. */
+ expired = 1;
+ done = 1;
+ }
+ else if(w == WAIT_OBJECT_0)
+ {
+ /* Save the index of the reporting thread and release the mutex.
+ The thread will block until we signal its Empty mutex. */
+ cp->CurrentIndex = cp->SharedIndex;
+ ReleaseSemaphore(cp->SharedIndexMutex, 1, 0);
+
+ /* Data are available or a pipe closed. */
+ if(cp->Pipe[cp->CurrentIndex].Closed)
+ {
+ /* The pipe closed at the write end. Close the read end and
+ inform the wakeup thread it is done with this process. */
+ kwsysProcessCleanupHandle(&cp->Pipe[cp->CurrentIndex].Read);
+ ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Waker.Go, 1, 0);
+ KWSYSPE_DEBUG((stderr, "wakeup %d\n", cp->CurrentIndex));
+ --cp->PipesLeft;
+ }
+ else if(data && length)
+ {
+ /* Report this data. */
+ *data = cp->Pipe[cp->CurrentIndex].DataBuffer;
+ *length = cp->Pipe[cp->CurrentIndex].DataLength;
+ switch(cp->CurrentIndex)
+ {
+ case KWSYSPE_PIPE_STDOUT:
+ pipeId = kwsysProcess_Pipe_STDOUT; break;
+ case KWSYSPE_PIPE_STDERR:
+ pipeId = kwsysProcess_Pipe_STDERR; break;
+ }
+ done = 1;
+ }
+ }
+ else
+ {
+ /* A process has terminated. */
+ kwsysProcessDestroy(cp, w-WAIT_OBJECT_0);
+ }
+ }
+
+ /* Update the user timeout. */
+ if(userTimeout)
+ {
+ kwsysProcessTime userEndTime = kwsysProcessTimeGetCurrent();
+ kwsysProcessTime difference = kwsysProcessTimeSubtract(userEndTime,
+ userStartTime);
+ double d = kwsysProcessTimeToDouble(difference);
+ *userTimeout -= d;
+ if(*userTimeout < 0)
+ {
+ *userTimeout = 0;
+ }
+ }
+
+ /* Check what happened. */
+ if(pipeId)
+ {
+ /* Data are ready on a pipe. */
+ return pipeId;
+ }
+ else if(expired)
+ {
+ /* A timeout has expired. */
+ if(user)
+ {
+ /* The user timeout has expired. It has no time left. */
+ return kwsysProcess_Pipe_Timeout;
+ }
+ else
+ {
+ /* The process timeout has expired. Kill the child now. */
+ KWSYSPE_DEBUG((stderr, "killing child because timeout expired\n"));
+ kwsysProcess_Kill(cp);
+ cp->TimeoutExpired = 1;
+ cp->Killed = 0;
+ return kwsysProcess_Pipe_None;
+ }
+ }
+ else
+ {
+ /* The children have terminated and no more data are available. */
+ return kwsysProcess_Pipe_None;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+int kwsysProcess_WaitForExit(kwsysProcess* cp, double* userTimeout)
+{
+ int i;
+ int pipe;
+
+ /* Make sure we are executing a process. */
+ if(!cp || cp->State != kwsysProcess_State_Executing)
+ {
+ return 1;
+ }
+
+ /* Wait for the process to terminate. Ignore all data. */
+ while((pipe = kwsysProcess_WaitForData(cp, 0, 0, userTimeout)) > 0)
+ {
+ if(pipe == kwsysProcess_Pipe_Timeout)
+ {
+ /* The user timeout has expired. */
+ return 0;
+ }
+ }
+
+ KWSYSPE_DEBUG((stderr, "no more data\n"));
+
+ /* When the last pipe closes in WaitForData, the loop terminates
+ without releasing the pipe's thread. Release it now. */
+ if(cp->CurrentIndex < KWSYSPE_PIPE_COUNT)
+ {
+ KWSYSPE_DEBUG((stderr, "releasing reader %d\n", cp->CurrentIndex));
+ ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Reader.Go, 1, 0);
+ cp->CurrentIndex = KWSYSPE_PIPE_COUNT;
+ }
+
+ /* Wait for all pipe threads to reset. */
+ for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
+ {
+ KWSYSPE_DEBUG((stderr, "waiting reader reset %d\n", i));
+ WaitForSingleObject(cp->Pipe[i].Reader.Reset, INFINITE);
+ KWSYSPE_DEBUG((stderr, "waiting waker reset %d\n", i));
+ WaitForSingleObject(cp->Pipe[i].Waker.Reset, INFINITE);
+ }
+
+ /* ---- It is now safe again to call kwsysProcessCleanup. ----- */
+ /* Close all the pipes. */
+ kwsysProcessCleanup(cp, 0);
+
+ /* Determine the outcome. */
+ if(cp->Killed)
+ {
+ /* We killed the child. */
+ cp->State = kwsysProcess_State_Killed;
+ }
+ else if(cp->TimeoutExpired)
+ {
+ /* The timeout expired. */
+ cp->State = kwsysProcess_State_Expired;
+ }
+ else
+ {
+ /* The children exited. Report the outcome of the last process. */
+ cp->ExitCode = cp->CommandExitCodes[cp->NumberOfCommands-1];
+ if((cp->ExitCode & 0xF0000000) == 0xC0000000)
+ {
+ /* Child terminated due to exceptional behavior. */
+ cp->State = kwsysProcess_State_Exception;
+ cp->ExitValue = 1;
+ kwsysProcessSetExitException(cp, cp->ExitCode);
+ }
+ else
+ {
+ /* Child exited without exception. */
+ cp->State = kwsysProcess_State_Exited;
+ cp->ExitException = kwsysProcess_Exception_None;
+ cp->ExitValue = cp->ExitCode;
+ }
+ }
+
+ return 1;
+}
+
+/*--------------------------------------------------------------------------*/
+void kwsysProcess_Kill(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, "kill: child not executing\n"));
+ return;
+ }
+
+ /* Disable the reading threads. */
+ KWSYSPE_DEBUG((stderr, "kill: disabling pipe threads\n"));
+ kwsysProcessDisablePipeThreads(cp);
+
+ /* Skip actually killing the child if it has already terminated. */
+ if(cp->Terminated)
+ {
+ KWSYSPE_DEBUG((stderr, "kill: child already terminated\n"));
+ return;
+ }
+
+ /* Kill the children. */
+ cp->Killed = 1;
+ if(cp->Win9x)
+ {
+ /* Windows 9x. Tell the forwarding executable to kill the child. */
+ SetEvent(cp->Win9xKillEvent);
+ }
+ else
+ {
+ /* Not Windows 9x. Just terminate the children. */
+ for(i=0; i < cp->NumberOfCommands; ++i)
+ {
+ kwsysProcessKillTree(cp->ProcessInformation[i].dwProcessId);
+ // close the handle if we kill it
+ kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hThread);
+ kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hProcess);
+ }
+ }
+
+ /* We are killing the children and ignoring all data. Do not wait
+ for them to exit. */
+}
+
+/*--------------------------------------------------------------------------*/
+
+/*
+ Function executed for each pipe's thread. Argument is a pointer to
+ the kwsysProcessPipeData instance for this thread.
+*/
+DWORD WINAPI kwsysProcessPipeThreadRead(LPVOID ptd)
+{
+ kwsysProcessPipeData* td = (kwsysProcessPipeData*)ptd;
+ kwsysProcess* cp = td->Process;
+
+ /* Wait for a process to be ready. */
+ while((WaitForSingleObject(td->Reader.Ready, INFINITE), !cp->Deleting))
+ {
+ /* Read output from the process for this thread's pipe. */
+ kwsysProcessPipeThreadReadPipe(cp, td);
+
+ /* Signal the main thread we have reset for a new process. */
+ ReleaseSemaphore(td->Reader.Reset, 1, 0);
+ }
+ return 0;
+}
+
+/*--------------------------------------------------------------------------*/
+
+/*
+ Function called in each pipe's thread to handle data for one
+ execution of a subprocess.
+*/
+void kwsysProcessPipeThreadReadPipe(kwsysProcess* cp, kwsysProcessPipeData* td)
+{
+ /* Wait for space in the thread's buffer. */
+ while((KWSYSPE_DEBUG((stderr, "wait for read %d\n", td->Index)),
+ WaitForSingleObject(td->Reader.Go, INFINITE), !td->Closed))
+ {
+ KWSYSPE_DEBUG((stderr, "reading %d\n", td->Index));
+
+ /* Read data from the pipe. This may block until data are available. */
+ if(!ReadFile(td->Read, td->DataBuffer, KWSYSPE_PIPE_BUFFER_SIZE,
+ &td->DataLength, 0))
+ {
+ if(GetLastError() != ERROR_BROKEN_PIPE)
+ {
+ /* UNEXPECTED failure to read the pipe. */
+ }
+
+ /* The pipe closed. There are no more data to read. */
+ td->Closed = 1;
+ KWSYSPE_DEBUG((stderr, "read closed %d\n", td->Index));
+ }
+
+ KWSYSPE_DEBUG((stderr, "read %d\n", td->Index));
+
+ /* Wait for our turn to be handled by the main thread. */
+ WaitForSingleObject(cp->SharedIndexMutex, INFINITE);
+
+ KWSYSPE_DEBUG((stderr, "reporting read %d\n", td->Index));
+
+ /* Tell the main thread we have something to report. */
+ cp->SharedIndex = td->Index;
+ ReleaseSemaphore(cp->Full, 1, 0);
+ }
+
+ /* We were signalled to exit with our buffer empty. Reset the
+ mutex for a new process. */
+ KWSYSPE_DEBUG((stderr, "self releasing reader %d\n", td->Index));
+ ReleaseSemaphore(td->Reader.Go, 1, 0);
+}
+
+/*--------------------------------------------------------------------------*/
+
+/*
+ Function executed for each pipe's thread. Argument is a pointer to
+ the kwsysProcessPipeData instance for this thread.
+*/
+DWORD WINAPI kwsysProcessPipeThreadWake(LPVOID ptd)
+{
+ kwsysProcessPipeData* td = (kwsysProcessPipeData*)ptd;
+ kwsysProcess* cp = td->Process;
+
+ /* Wait for a process to be ready. */
+ while((WaitForSingleObject(td->Waker.Ready, INFINITE), !cp->Deleting))
+ {
+ /* Wait for a possible wakeup. */
+ kwsysProcessPipeThreadWakePipe(cp, td);
+
+ /* Signal the main thread we have reset for a new process. */
+ ReleaseSemaphore(td->Waker.Reset, 1, 0);
+ }
+ return 0;
+}
+
+/*--------------------------------------------------------------------------*/
+
+/*
+ Function called in each pipe's thread to handle reading thread
+ wakeup for one execution of a subprocess.
+*/
+void kwsysProcessPipeThreadWakePipe(kwsysProcess* cp, kwsysProcessPipeData* td)
+{
+ (void)cp;
+
+ /* Wait for a possible wake command. */
+ KWSYSPE_DEBUG((stderr, "wait for wake %d\n", td->Index));
+ WaitForSingleObject(td->Waker.Go, INFINITE);
+ KWSYSPE_DEBUG((stderr, "waking %d\n", td->Index));
+
+ /* If the pipe is not closed, we need to wake up the reading thread. */
+ if(!td->Closed)
+ {
+ DWORD dummy;
+ KWSYSPE_DEBUG((stderr, "waker %d writing byte\n", td->Index));
+ WriteFile(td->Write, "", 1, &dummy, 0);
+ KWSYSPE_DEBUG((stderr, "waker %d wrote byte\n", td->Index));
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+/* Initialize a process control structure for kwsysProcess_Execute. */
+int kwsysProcessInitialize(kwsysProcess* cp)
+{
+ /* Reset internal status flags. */
+ cp->TimeoutExpired = 0;
+ cp->Terminated = 0;
+ cp->Killed = 0;
+ cp->ExitException = kwsysProcess_Exception_None;
+ cp->ExitCode = 1;
+ cp->ExitValue = 1;
+
+ /* Reset error data. */
+ cp->ErrorMessage[0] = 0;
+ strcpy(cp->ExitExceptionString, "No exception");
+
+ /* Allocate process information for each process. */
+ cp->ProcessInformation =
+ (PROCESS_INFORMATION*)malloc(sizeof(PROCESS_INFORMATION) *
+ cp->NumberOfCommands);
+ if(!cp->ProcessInformation)
+ {
+ return 0;
+ }
+ ZeroMemory(cp->ProcessInformation,
+ sizeof(PROCESS_INFORMATION) * cp->NumberOfCommands);
+ if(cp->CommandExitCodes)
+ {
+ free(cp->CommandExitCodes);
+ }
+ cp->CommandExitCodes = (DWORD*)malloc(sizeof(DWORD)*cp->NumberOfCommands);
+ if(!cp->CommandExitCodes)
+ {
+ return 0;
+ }
+ ZeroMemory(cp->CommandExitCodes, sizeof(DWORD)*cp->NumberOfCommands);
+
+ /* Allocate event wait array. The first event is cp->Full, the rest
+ are the process termination events. */
+ cp->ProcessEvents = (PHANDLE)malloc(sizeof(HANDLE)*(cp->NumberOfCommands+1));
+ if(!cp->ProcessEvents)
+ {
+ return 0;
+ }
+ ZeroMemory(cp->ProcessEvents, sizeof(HANDLE) * (cp->NumberOfCommands+1));
+ cp->ProcessEvents[0] = cp->Full;
+ cp->ProcessEventsLength = cp->NumberOfCommands+1;
+
+ /* Allocate space to save the real working directory of this process. */
+ if(cp->WorkingDirectory)
+ {
+ cp->RealWorkingDirectoryLength = GetCurrentDirectory(0, 0);
+ if(cp->RealWorkingDirectoryLength > 0)
+ {
+ cp->RealWorkingDirectory = (char*)malloc(cp->RealWorkingDirectoryLength);
+ if(!cp->RealWorkingDirectory)
+ {
+ return 0;
+ }
+ }
+ }
+
+ return 1;
+}
+
+/*--------------------------------------------------------------------------*/
+int kwsysProcessCreate(kwsysProcess* cp, int index,
+ kwsysProcessCreateInformation* si,
+ PHANDLE readEnd)
+{
+ /* 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;
+
+ /* This function is done with this handle. */
+ *readEnd = 0;
+ }
+ else if(cp->PipeFileSTDIN)
+ {
+ /* 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)
+ {
+ return 0;
+ }
+ /* 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))
+ {
+ return 0;
+ }
+ }
+ else if(cp->PipeNativeSTDIN[0])
+ {
+ /* Use the provided native pipe. */
+ if(!kwsysProcessSetupPipeNative(&si->StartupInfo.hStdInput,
+ cp->PipeNativeSTDIN, 0))
+ {
+ return 0;
+ }
+ }
+ else
+ {
+ /* Explicitly give the child no stdin. */
+ si->StartupInfo.hStdInput = INVALID_HANDLE_VALUE;
+ }
+
+ /* Setup the process's stdout. */
+ {
+ DWORD maybeClose = DUPLICATE_CLOSE_SOURCE;
+ HANDLE writeEnd;
+
+ /* Create the output pipe for this process. Neither end is directly
+ inherited. */
+ if(!CreatePipe(readEnd, &writeEnd, 0, 0))
+ {
+ return 0;
+ }
+
+ /* 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)))
+ {
+ return 0;
+ }
+ 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)
+ {
+ if(!kwsysProcessSetupOutputPipeFile(&si->StartupInfo.hStdOutput,
+ cp->PipeFileSTDOUT))
+ {
+ return 0;
+ }
+ }
+
+ /* 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(!kwsysProcessSetupSharedPipe(STD_OUTPUT_HANDLE,
+ &si->StartupInfo.hStdOutput))
+ {
+ return 0;
+ }
+ }
+
+ /* 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(!kwsysProcessSetupPipeNative(&si->StartupInfo.hStdOutput,
+ cp->PipeNativeSTDOUT, 1))
+ {
+ return 0;
+ }
+ }
+
+ /* Create the child process. */
+ {
+ BOOL r;
+ char* realCommand;
+ if(cp->Win9x)
+ {
+ /* Create an error reporting pipe for the forwarding executable.
+ Neither end is directly inherited. */
+ if(!CreatePipe(&si->ErrorPipeRead, &si->ErrorPipeWrite, 0, 0))
+ {
+ return 0;
+ }
+
+ /* Create an inherited duplicate of the write end. This also closes
+ the non-inherited version. */
+ if(!DuplicateHandle(GetCurrentProcess(), si->ErrorPipeWrite,
+ GetCurrentProcess(), &si->ErrorPipeWrite,
+ 0, TRUE, (DUPLICATE_CLOSE_SOURCE |
+ DUPLICATE_SAME_ACCESS)))
+ {
+ return 0;
+ }
+
+ /* The forwarding executable is given a handle to the error pipe
+ and resume and kill events. */
+ realCommand = (char*)malloc(strlen(cp->Win9x)+strlen(cp->Commands[index])+100);
+ if(!realCommand)
+ {
+ return 0;
+ }
+ sprintf(realCommand, "%s %p %p %p %d %s", cp->Win9x,
+ si->ErrorPipeWrite, cp->Win9xResumeEvent, cp->Win9xKillEvent,
+ cp->HideWindow, cp->Commands[index]);
+ }
+ else
+ {
+ realCommand = cp->Commands[index];
+ }
+
+ /* Create the child in a suspended state so we can wait until all
+ children have been created before running any one. */
+ r = CreateProcess(0, realCommand, 0, 0, TRUE,
+ cp->Win9x? 0 : CREATE_SUSPENDED, 0, 0,
+ &si->StartupInfo, &cp->ProcessInformation[index]);
+ if(cp->Win9x)
+ {
+ /* Free memory. */
+ free(realCommand);
+
+ /* Close the error pipe write end so we can detect when the
+ forwarding executable closes it. */
+ kwsysProcessCleanupHandle(&si->ErrorPipeWrite);
+ if(r)
+ {
+ /* Wait for the forwarding executable to report an error or
+ close the error pipe to report success. */
+ DWORD total = 0;
+ DWORD n = 1;
+ while(total < KWSYSPE_PIPE_BUFFER_SIZE && n > 0)
+ {
+ if(ReadFile(si->ErrorPipeRead, cp->ErrorMessage+total,
+ KWSYSPE_PIPE_BUFFER_SIZE-total, &n, 0))
+ {
+ total += n;
+ }
+ else
+ {
+ n = 0;
+ }
+ }
+ if(total > 0 || GetLastError() != ERROR_BROKEN_PIPE)
+ {
+ /* The forwarding executable could not run the process, or
+ there was an error reading from its error pipe. Preserve
+ the last error while cleaning up the forwarding executable
+ so the cleanup our caller does reports the proper error. */
+ DWORD error = GetLastError();
+ kwsysProcessCleanupHandle(&cp->ProcessInformation[index].hThread);
+ kwsysProcessCleanupHandle(&cp->ProcessInformation[index].hProcess);
+ SetLastError(error);
+ return 0;
+ }
+ }
+ kwsysProcessCleanupHandle(&si->ErrorPipeRead);
+ }
+
+ if(!r)
+ {
+ return 0;
+ }
+ }
+
+ /* 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;
+}
+
+/*--------------------------------------------------------------------------*/
+void kwsysProcessDestroy(kwsysProcess* cp, int event)
+{
+ int i;
+ int index;
+
+ /* Find the process index for the termination event. */
+ for(index=0; index < cp->NumberOfCommands; ++index)
+ {
+ if(cp->ProcessInformation[index].hProcess == cp->ProcessEvents[event])
+ {
+ break;
+ }
+ }
+
+ /* Check the exit code of the process. */
+ GetExitCodeProcess(cp->ProcessInformation[index].hProcess,
+ &cp->CommandExitCodes[index]);
+
+ /* Close the process handle for the terminated process. */
+ kwsysProcessCleanupHandle(&cp->ProcessInformation[index].hProcess);
+
+ /* Remove the process from the available events. */
+ cp->ProcessEventsLength -= 1;
+ for(i=event; i < cp->ProcessEventsLength; ++i)
+ {
+ cp->ProcessEvents[i] = cp->ProcessEvents[i+1];
+ }
+
+ /* Check if all processes have terminated. */
+ if(cp->ProcessEventsLength == 1)
+ {
+ cp->Terminated = 1;
+
+ /* Close our copies of the pipe write handles so the pipe threads
+ can detect end-of-data. */
+ for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
+ {
+ /* TODO: If the child created its own child (our grandchild)
+ which inherited a copy of the pipe write-end then the pipe
+ may not close and we will still need the waker write pipe.
+ However we still want to be able to detect end-of-data in the
+ normal case. The reader thread will have to switch to using
+ PeekNamedPipe to read the last bit of data from the pipe
+ without blocking. This is equivalent to using a non-blocking
+ read on posix. */
+ KWSYSPE_DEBUG((stderr, "closing wakeup write %d\n", i));
+ kwsysProcessCleanupHandle(&cp->Pipe[i].Write);
+ }
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+int kwsysProcessSetupOutputPipeFile(PHANDLE phandle, const char* name)
+{
+ HANDLE fout;
+ if(!name)
+ {
+ return 1;
+ }
+
+ /* Close the existing inherited handle. */
+ kwsysProcessCleanupHandle(phandle);
+
+ /* Create a handle to write a file for the pipe. */
+ fout = CreateFile(name, GENERIC_WRITE, FILE_SHARE_READ, 0,
+ CREATE_ALWAYS, 0, 0);
+ 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;
+ }
+
+ /* Assign the replacement handle. */
+ *phandle = fout;
+ return 1;
+}
+
+/*--------------------------------------------------------------------------*/
+int 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. */
+ 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;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+int kwsysProcessSetupPipeNative(PHANDLE handle, HANDLE p[2], int isWrite)
+{
+ /* Close the existing inherited 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;
+}
+
+/*--------------------------------------------------------------------------*/
+
+/* 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)))
+ {
+ CloseHandle(*h);
+ *h = 0;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+/* Close all handles created by kwsysProcess_Execute. */
+void kwsysProcessCleanup(kwsysProcess* cp, int error)
+{
+ int i;
+ /* If this is an error case, report the error. */
+ if(error)
+ {
+ /* Construct an error message if one has not been provided already. */
+ 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,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ cp->ErrorMessage, 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());
+ }
+ }
+
+ /* Remove trailing period and newline, if any. */
+ kwsysProcessCleanErrorMessage(cp);
+
+ /* Set the error state. */
+ cp->State = kwsysProcess_State_Error;
+
+ /* Cleanup any processes already started in a suspended state. */
+ if(cp->ProcessInformation)
+ {
+ if(cp->Win9x)
+ {
+ SetEvent(cp->Win9xKillEvent);
+ }
+ else
+ {
+ for(i=0; i < cp->NumberOfCommands; ++i)
+ {
+ if(cp->ProcessInformation[i].hProcess)
+ {
+ TerminateProcess(cp->ProcessInformation[i].hProcess, 255);
+ WaitForSingleObject(cp->ProcessInformation[i].hProcess, INFINITE);
+ }
+ }
+ }
+ for(i=0; i < cp->NumberOfCommands; ++i)
+ {
+ kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hThread);
+ kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hProcess);
+ }
+ }
+
+ /* Restore the working directory. */
+ if(cp->RealWorkingDirectory)
+ {
+ SetCurrentDirectory(cp->RealWorkingDirectory);
+ }
+ }
+
+ /* Free memory. */
+ if(cp->ProcessInformation)
+ {
+ free(cp->ProcessInformation);
+ cp->ProcessInformation = 0;
+ }
+ if(cp->ProcessEvents)
+ {
+ free(cp->ProcessEvents);
+ cp->ProcessEvents = 0;
+ }
+ if(cp->RealWorkingDirectory)
+ {
+ free(cp->RealWorkingDirectory);
+ cp->RealWorkingDirectory = 0;
+ }
+
+ /* Close each pipe. */
+ for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
+ {
+ kwsysProcessCleanupHandle(&cp->Pipe[i].Write);
+ kwsysProcessCleanupHandle(&cp->Pipe[i].Read);
+ cp->Pipe[i].Closed = 0;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+void kwsysProcessCleanErrorMessage(kwsysProcess* cp)
+{
+ /* Remove trailing period and newline, if any. */
+ size_t length = strlen(cp->ErrorMessage);
+ if(cp->ErrorMessage[length-1] == '\n')
+ {
+ cp->ErrorMessage[length-1] = 0;
+ --length;
+ if(length > 0 && cp->ErrorMessage[length-1] == '\r')
+ {
+ cp->ErrorMessage[length-1] = 0;
+ --length;
+ }
+ }
+ if(length > 0 && cp->ErrorMessage[length-1] == '.')
+ {
+ cp->ErrorMessage[length-1] = 0;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+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,
+ kwsysProcessTime* timeoutTime)
+{
+ /* The first time this is called, we need to calculate the time at
+ which the child will timeout. */
+ if(cp->Timeout && cp->TimeoutTime.QuadPart < 0)
+ {
+ kwsysProcessTime length = kwsysProcessTimeFromDouble(cp->Timeout);
+ cp->TimeoutTime = kwsysProcessTimeAdd(cp->StartTime, length);
+ }
+
+ /* Start with process timeout. */
+ *timeoutTime = cp->TimeoutTime;
+
+ /* Check if the user timeout is earlier. */
+ if(userTimeout)
+ {
+ kwsysProcessTime currentTime = kwsysProcessTimeGetCurrent();
+ kwsysProcessTime userTimeoutLength = kwsysProcessTimeFromDouble(*userTimeout);
+ kwsysProcessTime userTimeoutTime = kwsysProcessTimeAdd(currentTime,
+ userTimeoutLength);
+ if(timeoutTime->QuadPart < 0 ||
+ kwsysProcessTimeLess(userTimeoutTime, *timeoutTime))
+ {
+ *timeoutTime = userTimeoutTime;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/*--------------------------------------------------------------------------*/
+/* Get the length of time before the given timeout time arrives.
+ Returns 1 if the time has already arrived, and 0 otherwise. */
+int kwsysProcessGetTimeoutLeft(kwsysProcessTime* timeoutTime,
+ double* userTimeout,
+ kwsysProcessTime* timeoutLength)
+{
+ if(timeoutTime->QuadPart < 0)
+ {
+ /* No timeout time has been requested. */
+ return 0;
+ }
+ else
+ {
+ /* Calculate the remaining time. */
+ kwsysProcessTime currentTime = kwsysProcessTimeGetCurrent();
+ *timeoutLength = kwsysProcessTimeSubtract(*timeoutTime, currentTime);
+
+ if(timeoutLength->QuadPart < 0 && userTimeout && *userTimeout <= 0)
+ {
+ /* Caller has explicitly requested a zero timeout. */
+ timeoutLength->QuadPart = 0;
+ }
+
+ if(timeoutLength->QuadPart < 0)
+ {
+ /* Timeout has already expired. */
+ return 1;
+ }
+ else
+ {
+ /* There is some time left. */
+ return 0;
+ }
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+kwsysProcessTime kwsysProcessTimeGetCurrent()
+{
+ kwsysProcessTime current;
+ FILETIME ft;
+ GetSystemTimeAsFileTime(&ft);
+ current.LowPart = ft.dwLowDateTime;
+ current.HighPart = ft.dwHighDateTime;
+ return current;
+}
+
+/*--------------------------------------------------------------------------*/
+DWORD kwsysProcessTimeToDWORD(kwsysProcessTime t)
+{
+ return (DWORD)(t.QuadPart * 0.0001);
+}
+
+/*--------------------------------------------------------------------------*/
+double kwsysProcessTimeToDouble(kwsysProcessTime t)
+{
+ return t.QuadPart * 0.0000001;
+}
+
+/*--------------------------------------------------------------------------*/
+kwsysProcessTime kwsysProcessTimeFromDouble(double d)
+{
+ kwsysProcessTime t;
+ t.QuadPart = (LONGLONG)(d*10000000);
+ return t;
+}
+
+/*--------------------------------------------------------------------------*/
+int kwsysProcessTimeLess(kwsysProcessTime in1, kwsysProcessTime in2)
+{
+ return in1.QuadPart < in2.QuadPart;
+}
+
+/*--------------------------------------------------------------------------*/
+kwsysProcessTime kwsysProcessTimeAdd(kwsysProcessTime in1, kwsysProcessTime in2)
+{
+ kwsysProcessTime out;
+ out.QuadPart = in1.QuadPart + in2.QuadPart;
+ return out;
+}
+
+/*--------------------------------------------------------------------------*/
+kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1, kwsysProcessTime in2)
+{
+ kwsysProcessTime out;
+ out.QuadPart = in1.QuadPart - in2.QuadPart;
+ return out;
+}
+
+/*--------------------------------------------------------------------------*/
+#define KWSYSPE_CASE(type, str) \
+ cp->ExitException = kwsysProcess_Exception_##type; \
+ strcpy(cp->ExitExceptionString, str)
+static void kwsysProcessSetExitException(kwsysProcess* cp, int code)
+{
+ switch (code)
+ {
+ case STATUS_CONTROL_C_EXIT:
+ KWSYSPE_CASE(Interrupt, "User interrupt"); break;
+
+ case STATUS_FLOAT_DENORMAL_OPERAND:
+ KWSYSPE_CASE(Numerical, "Floating-point exception (denormal operand)"); break;
+ case STATUS_FLOAT_DIVIDE_BY_ZERO:
+ KWSYSPE_CASE(Numerical, "Divide-by-zero"); break;
+ case STATUS_FLOAT_INEXACT_RESULT:
+ KWSYSPE_CASE(Numerical, "Floating-point exception (inexact result)"); break;
+ case STATUS_FLOAT_INVALID_OPERATION:
+ KWSYSPE_CASE(Numerical, "Invalid floating-point operation"); break;
+ case STATUS_FLOAT_OVERFLOW:
+ KWSYSPE_CASE(Numerical, "Floating-point overflow"); break;
+ case STATUS_FLOAT_STACK_CHECK:
+ KWSYSPE_CASE(Numerical, "Floating-point stack check failed"); break;
+ case STATUS_FLOAT_UNDERFLOW:
+ KWSYSPE_CASE(Numerical, "Floating-point underflow"); break;
+#ifdef STATUS_FLOAT_MULTIPLE_FAULTS
+ case STATUS_FLOAT_MULTIPLE_FAULTS:
+ KWSYSPE_CASE(Numerical, "Floating-point exception (multiple faults)"); break;
+#endif
+#ifdef STATUS_FLOAT_MULTIPLE_TRAPS
+ case STATUS_FLOAT_MULTIPLE_TRAPS:
+ KWSYSPE_CASE(Numerical, "Floating-point exception (multiple traps)"); break;
+#endif
+ case STATUS_INTEGER_DIVIDE_BY_ZERO:
+ KWSYSPE_CASE(Numerical, "Integer divide-by-zero"); break;
+ case STATUS_INTEGER_OVERFLOW:
+ KWSYSPE_CASE(Numerical, "Integer overflow"); break;
+
+ case STATUS_DATATYPE_MISALIGNMENT:
+ KWSYSPE_CASE(Fault, "Datatype misalignment"); break;
+ case STATUS_ACCESS_VIOLATION:
+ KWSYSPE_CASE(Fault, "Access violation"); break;
+ case STATUS_IN_PAGE_ERROR:
+ KWSYSPE_CASE(Fault, "In-page error"); break;
+ case STATUS_INVALID_HANDLE:
+ KWSYSPE_CASE(Fault, "Invalid hanlde"); break;
+ case STATUS_NONCONTINUABLE_EXCEPTION:
+ KWSYSPE_CASE(Fault, "Noncontinuable exception"); break;
+ case STATUS_INVALID_DISPOSITION:
+ KWSYSPE_CASE(Fault, "Invalid disposition"); break;
+ case STATUS_ARRAY_BOUNDS_EXCEEDED:
+ KWSYSPE_CASE(Fault, "Array bounds exceeded"); break;
+ case STATUS_STACK_OVERFLOW:
+ KWSYSPE_CASE(Fault, "Stack overflow"); break;
+
+ case STATUS_ILLEGAL_INSTRUCTION:
+ KWSYSPE_CASE(Illegal, "Illegal instruction"); break;
+ case STATUS_PRIVILEGED_INSTRUCTION:
+ KWSYSPE_CASE(Illegal, "Privileged instruction"); break;
+
+ case STATUS_NO_MEMORY:
+ default:
+ cp->ExitException = kwsysProcess_Exception_Other;
+ sprintf(cp->ExitExceptionString, "Exit code 0x%x\n", code);
+ break;
+ }
+}
+#undef KWSYSPE_CASE
+
+typedef struct kwsysProcess_List_s kwsysProcess_List;
+static kwsysProcess_List* kwsysProcess_List_New(void);
+static void kwsysProcess_List_Delete(kwsysProcess_List* self);
+static int kwsysProcess_List_Update(kwsysProcess_List* self);
+static int kwsysProcess_List_NextProcess(kwsysProcess_List* self);
+static int kwsysProcess_List_GetCurrentProcessId(kwsysProcess_List* self);
+static int kwsysProcess_List_GetCurrentParentId(kwsysProcess_List* self);
+
+/*--------------------------------------------------------------------------*/
+/* Windows NT 4 API definitions. */
+#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
+typedef LONG NTSTATUS;
+typedef LONG KPRIORITY;
+typedef struct _UNICODE_STRING UNICODE_STRING;
+struct _UNICODE_STRING
+{
+ USHORT Length;
+ USHORT MaximumLength;
+ PWSTR Buffer;
+};
+
+/* The process information structure. Declare only enough to get
+ process identifiers. The rest may be ignored because we use the
+ NextEntryDelta to move through an array of instances. */
+typedef struct _SYSTEM_PROCESS_INFORMATION SYSTEM_PROCESS_INFORMATION;
+typedef SYSTEM_PROCESS_INFORMATION* PSYSTEM_PROCESS_INFORMATION;
+struct _SYSTEM_PROCESS_INFORMATION
+{
+ ULONG NextEntryDelta;
+ ULONG ThreadCount;
+ ULONG Reserved1[6];
+ LARGE_INTEGER CreateTime;
+ LARGE_INTEGER UserTime;
+ LARGE_INTEGER KernelTime;
+ UNICODE_STRING ProcessName;
+ KPRIORITY BasePriority;
+ ULONG ProcessId;
+ ULONG InheritedFromProcessId;
+};
+
+/*--------------------------------------------------------------------------*/
+/* Toolhelp32 API definitions. */
+#define TH32CS_SNAPPROCESS 0x00000002
+#if defined(_WIN64)
+typedef unsigned __int64 ProcessULONG_PTR;
+#else
+typedef unsigned long ProcessULONG_PTR;
+#endif
+typedef struct tagPROCESSENTRY32 PROCESSENTRY32;
+typedef PROCESSENTRY32* LPPROCESSENTRY32;
+struct tagPROCESSENTRY32
+{
+ DWORD dwSize;
+ DWORD cntUsage;
+ DWORD th32ProcessID;
+ ProcessULONG_PTR th32DefaultHeapID;
+ DWORD th32ModuleID;
+ DWORD cntThreads;
+ DWORD th32ParentProcessID;
+ LONG pcPriClassBase;
+ DWORD dwFlags;
+ char szExeFile[MAX_PATH];
+};
+
+/*--------------------------------------------------------------------------*/
+/* Windows API function types. */
+typedef HANDLE (WINAPI* CreateToolhelp32SnapshotType)(DWORD, DWORD);
+typedef BOOL (WINAPI* Process32FirstType)(HANDLE, LPPROCESSENTRY32);
+typedef BOOL (WINAPI* Process32NextType)(HANDLE, LPPROCESSENTRY32);
+typedef NTSTATUS (WINAPI* ZwQuerySystemInformationType)(ULONG, PVOID,
+ ULONG, PULONG);
+
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List__New_NT4(kwsysProcess_List* self);
+static int kwsysProcess_List__New_Snapshot(kwsysProcess_List* self);
+static void kwsysProcess_List__Delete_NT4(kwsysProcess_List* self);
+static void kwsysProcess_List__Delete_Snapshot(kwsysProcess_List* self);
+static int kwsysProcess_List__Update_NT4(kwsysProcess_List* self);
+static int kwsysProcess_List__Update_Snapshot(kwsysProcess_List* self);
+static int kwsysProcess_List__Next_NT4(kwsysProcess_List* self);
+static int kwsysProcess_List__Next_Snapshot(kwsysProcess_List* self);
+static int kwsysProcess_List__GetProcessId_NT4(kwsysProcess_List* self);
+static int kwsysProcess_List__GetProcessId_Snapshot(kwsysProcess_List* self);
+static int kwsysProcess_List__GetParentId_NT4(kwsysProcess_List* self);
+static int kwsysProcess_List__GetParentId_Snapshot(kwsysProcess_List* self);
+
+struct kwsysProcess_List_s
+{
+ /* Implementation switches at runtime based on version of Windows. */
+ int NT4;
+
+ /* Implementation functions and data for NT 4. */
+ ZwQuerySystemInformationType P_ZwQuerySystemInformation;
+ char* Buffer;
+ int BufferSize;
+ PSYSTEM_PROCESS_INFORMATION CurrentInfo;
+
+ /* Implementation functions and data for other Windows versions. */
+ CreateToolhelp32SnapshotType P_CreateToolhelp32Snapshot;
+ Process32FirstType P_Process32First;
+ Process32NextType P_Process32Next;
+ HANDLE Snapshot;
+ PROCESSENTRY32 CurrentEntry;
+};
+
+/*--------------------------------------------------------------------------*/
+static kwsysProcess_List* kwsysProcess_List_New(void)
+{
+ OSVERSIONINFO osv;
+ kwsysProcess_List* self;
+
+ /* Allocate and initialize the list object. */
+ if(!(self = (kwsysProcess_List*)malloc(sizeof(kwsysProcess_List))))
+ {
+ return 0;
+ }
+ memset(self, 0, sizeof(*self));
+
+ /* Select an implementation. */
+ ZeroMemory(&osv, sizeof(osv));
+ osv.dwOSVersionInfoSize = sizeof(osv);
+ GetVersionEx(&osv);
+ self->NT4 = (osv.dwPlatformId == VER_PLATFORM_WIN32_NT &&
+ osv.dwMajorVersion < 5)? 1:0;
+
+ /* Initialize the selected implementation. */
+ if(!(self->NT4?
+ kwsysProcess_List__New_NT4(self) :
+ kwsysProcess_List__New_Snapshot(self)))
+ {
+ kwsysProcess_List_Delete(self);
+ return 0;
+ }
+
+ /* Update to the current set of processes. */
+ if(!kwsysProcess_List_Update(self))
+ {
+ kwsysProcess_List_Delete(self);
+ return 0;
+ }
+ return self;
+}
+
+/*--------------------------------------------------------------------------*/
+static void kwsysProcess_List_Delete(kwsysProcess_List* self)
+{
+ if(self)
+ {
+ if(self->NT4)
+ {
+ kwsysProcess_List__Delete_NT4(self);
+ }
+ else
+ {
+ kwsysProcess_List__Delete_Snapshot(self);
+ }
+ free(self);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List_Update(kwsysProcess_List* self)
+{
+ return self? (self->NT4?
+ kwsysProcess_List__Update_NT4(self) :
+ kwsysProcess_List__Update_Snapshot(self)) : 0;
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List_GetCurrentProcessId(kwsysProcess_List* self)
+{
+ return self? (self->NT4?
+ kwsysProcess_List__GetProcessId_NT4(self) :
+ kwsysProcess_List__GetProcessId_Snapshot(self)) : -1;
+
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List_GetCurrentParentId(kwsysProcess_List* self)
+{
+ return self? (self->NT4?
+ kwsysProcess_List__GetParentId_NT4(self) :
+ kwsysProcess_List__GetParentId_Snapshot(self)) : -1;
+
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List_NextProcess(kwsysProcess_List* self)
+{
+ return (self? (self->NT4?
+ kwsysProcess_List__Next_NT4(self) :
+ kwsysProcess_List__Next_Snapshot(self)) : 0);
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List__New_NT4(kwsysProcess_List* self)
+{
+ /* Get a handle to the NT runtime module that should already be
+ 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");
+ if(hNT)
+ {
+ /* Get pointers to the needed API functions. */
+ self->P_ZwQuerySystemInformation =
+ ((ZwQuerySystemInformationType)
+ GetProcAddress(hNT, "ZwQuerySystemInformation"));
+ }
+ if(!self->P_ZwQuerySystemInformation)
+ {
+ return 0;
+ }
+
+ /* Allocate an initial process information buffer. */
+ self->BufferSize = 32768;
+ self->Buffer = (char*)malloc(self->BufferSize);
+ return self->Buffer? 1:0;
+}
+
+/*--------------------------------------------------------------------------*/
+static void kwsysProcess_List__Delete_NT4(kwsysProcess_List* self)
+{
+ /* Free the process information buffer. */
+ if(self->Buffer)
+ {
+ free(self->Buffer);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List__Update_NT4(kwsysProcess_List* self)
+{
+ self->CurrentInfo = 0;
+ for(;;)
+ {
+ /* Query number 5 is for system process list. */
+ NTSTATUS status =
+ self->P_ZwQuerySystemInformation(5, self->Buffer, self->BufferSize, 0);
+ if(status == STATUS_INFO_LENGTH_MISMATCH)
+ {
+ /* The query requires a bigger buffer. */
+ int newBufferSize = self->BufferSize * 2;
+ char* newBuffer = (char*)malloc(newBufferSize);
+ if(newBuffer)
+ {
+ free(self->Buffer);
+ self->Buffer = newBuffer;
+ self->BufferSize = newBufferSize;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ else if(status >= 0)
+ {
+ /* The query succeeded. Initialize traversal of the process list. */
+ self->CurrentInfo = (PSYSTEM_PROCESS_INFORMATION)self->Buffer;
+ return 1;
+ }
+ else
+ {
+ /* The query failed. */
+ return 0;
+ }
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List__Next_NT4(kwsysProcess_List* self)
+{
+ if(self->CurrentInfo)
+ {
+ if(self->CurrentInfo->NextEntryDelta > 0)
+ {
+ self->CurrentInfo = ((PSYSTEM_PROCESS_INFORMATION)
+ ((char*)self->CurrentInfo +
+ self->CurrentInfo->NextEntryDelta));
+ return 1;
+ }
+ self->CurrentInfo = 0;
+ }
+ return 0;
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List__GetProcessId_NT4(kwsysProcess_List* self)
+{
+ return self->CurrentInfo? self->CurrentInfo->ProcessId : -1;
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List__GetParentId_NT4(kwsysProcess_List* self)
+{
+ return self->CurrentInfo? self->CurrentInfo->InheritedFromProcessId : -1;
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List__New_Snapshot(kwsysProcess_List* self)
+{
+ /* Get a handle to the Windows runtime module that should already be
+ 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");
+ if(hKernel)
+ {
+ self->P_CreateToolhelp32Snapshot =
+ ((CreateToolhelp32SnapshotType)
+ GetProcAddress(hKernel, "CreateToolhelp32Snapshot"));
+ self->P_Process32First =
+ ((Process32FirstType)
+ GetProcAddress(hKernel, "Process32First"));
+ self->P_Process32Next =
+ ((Process32NextType)
+ GetProcAddress(hKernel, "Process32Next"));
+ }
+ return (self->P_CreateToolhelp32Snapshot &&
+ self->P_Process32First &&
+ self->P_Process32Next)? 1:0;
+}
+
+/*--------------------------------------------------------------------------*/
+static void kwsysProcess_List__Delete_Snapshot(kwsysProcess_List* self)
+{
+ if(self->Snapshot)
+ {
+ CloseHandle(self->Snapshot);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List__Update_Snapshot(kwsysProcess_List* self)
+{
+ if(self->Snapshot)
+ {
+ CloseHandle(self->Snapshot);
+ }
+ if(!(self->Snapshot =
+ self->P_CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)))
+ {
+ return 0;
+ }
+ ZeroMemory(&self->CurrentEntry, sizeof(self->CurrentEntry));
+ self->CurrentEntry.dwSize = sizeof(self->CurrentEntry);
+ if(!self->P_Process32First(self->Snapshot, &self->CurrentEntry))
+ {
+ CloseHandle(self->Snapshot);
+ self->Snapshot = 0;
+ return 0;
+ }
+ return 1;
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List__Next_Snapshot(kwsysProcess_List* self)
+{
+ if(self->Snapshot)
+ {
+ if(self->P_Process32Next(self->Snapshot, &self->CurrentEntry))
+ {
+ return 1;
+ }
+ CloseHandle(self->Snapshot);
+ self->Snapshot = 0;
+ }
+ return 0;
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List__GetProcessId_Snapshot(kwsysProcess_List* self)
+{
+ return self->Snapshot? self->CurrentEntry.th32ProcessID : -1;
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysProcess_List__GetParentId_Snapshot(kwsysProcess_List* self)
+{
+ return self->Snapshot? self->CurrentEntry.th32ParentProcessID : -1;
+}
+
+/*--------------------------------------------------------------------------*/
+static void kwsysProcessKill(DWORD pid)
+{
+ HANDLE h = OpenProcess(PROCESS_TERMINATE, 0, pid);
+ if(h)
+ {
+ TerminateProcess(h, 255);
+ WaitForSingleObject(h, INFINITE);
+ CloseHandle(h);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+static void kwsysProcessKillTree(int pid)
+{
+ kwsysProcess_List* plist = kwsysProcess_List_New();
+ kwsysProcessKill(pid);
+ if(plist)
+ {
+ do
+ {
+ if(kwsysProcess_List_GetCurrentParentId(plist) == pid)
+ {
+ int ppid = kwsysProcess_List_GetCurrentProcessId(plist);
+ kwsysProcessKillTree(ppid);
+ }
+ } while(kwsysProcess_List_NextProcess(plist));
+ kwsysProcess_List_Delete(plist);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+static void kwsysProcessDisablePipeThreads(kwsysProcess* cp)
+{
+ int i;
+
+ /* If data were just reported data, release the pipe's thread. */
+ if(cp->CurrentIndex < KWSYSPE_PIPE_COUNT)
+ {
+ KWSYSPE_DEBUG((stderr, "releasing reader %d\n", cp->CurrentIndex));
+ ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Reader.Go, 1, 0);
+ cp->CurrentIndex = KWSYSPE_PIPE_COUNT;
+ }
+
+ /* Wakeup all reading threads that are not on closed pipes. */
+ for(i=0; i < KWSYSPE_PIPE_COUNT; ++i)
+ {
+ /* The wakeup threads will write one byte to the pipe write ends.
+ If there are no data in the pipe then this is enough to wakeup
+ the reading threads. If there are already data in the pipe
+ this may block. We cannot use PeekNamedPipe to check whether
+ there are data because an outside process might still be
+ writing data if we are disowning it. Also, PeekNamedPipe will
+ block if checking a pipe on which the reading thread is
+ currently calling ReadPipe. Therefore we need a separate
+ thread to call WriteFile. If it blocks, that is okay because
+ it will unblock when we close the read end and break the pipe
+ below. */
+ if(cp->Pipe[i].Read)
+ {
+ KWSYSPE_DEBUG((stderr, "releasing waker %d\n", i));
+ ReleaseSemaphore(cp->Pipe[i].Waker.Go, 1, 0);
+ }
+ }
+
+ /* Tell pipe threads to reset until we run another process. */
+ while(cp->PipesLeft > 0)
+ {
+ /* The waking threads will cause all reading threads to report.
+ Wait for the next one and save its index. */
+ KWSYSPE_DEBUG((stderr, "waiting for reader\n"));
+ WaitForSingleObject(cp->Full, INFINITE);
+ cp->CurrentIndex = cp->SharedIndex;
+ ReleaseSemaphore(cp->SharedIndexMutex, 1, 0);
+ KWSYSPE_DEBUG((stderr, "got reader %d\n", cp->CurrentIndex));
+
+ /* We are done reading this pipe. Close its read handle. */
+ cp->Pipe[cp->CurrentIndex].Closed = 1;
+ kwsysProcessCleanupHandle(&cp->Pipe[cp->CurrentIndex].Read);
+ --cp->PipesLeft;
+
+ /* Tell the reading thread we are done with the data. It will
+ reset immediately because the pipe is closed. */
+ ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Reader.Go, 1, 0);
+ }
+}
diff --git a/Source/kwsys/README.txt b/Source/kwsys/README.txt
new file mode 100644
index 000000000..ba03f8dde
--- /dev/null
+++ b/Source/kwsys/README.txt
@@ -0,0 +1,10 @@
+KWSys provides a platform-independent API to many common system
+features that are implemented differently on every platform. This
+library is intended to be shared among many projects, so it has a
+configurable namespace. Each project should configure KWSys to use a
+namespace unique to itself. See comments in CMakeLists.txt for
+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.
diff --git a/Source/kwsys/Registry.cxx b/Source/kwsys/Registry.cxx
new file mode 100644
index 000000000..cd521c966
--- /dev/null
+++ b/Source/kwsys/Registry.cxx
@@ -0,0 +1,818 @@
+/*============================================================================
+ 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(Registry.hxx)
+
+#include KWSYS_HEADER(Configure.hxx)
+#include KWSYS_HEADER(ios/iostream)
+#include KWSYS_HEADER(stl/string)
+#include KWSYS_HEADER(stl/map)
+#include KWSYS_HEADER(ios/iostream)
+#include KWSYS_HEADER(ios/fstream)
+#include KWSYS_HEADER(ios/sstream)
+// Work-around CMake dependency scanning limitation. This must
+// duplicate the above list of headers.
+#if 0
+# include "Registry.hxx.in"
+# include "Configure.hxx.in"
+# include "kwsys_stl.hxx.in"
+# include "kwsys_stl_string.hxx.in"
+# include "kwsys_stl_map.hxx.in"
+# include "kwsys_ios_iostream.h.in"
+# include "kwsys_ios_fstream.h.in"
+# include "kwsys_ios_sstream.h.in"
+#endif
+
+#include <ctype.h> // for isspace
+#include <stdio.h>
+#include <string.h> /* strlen, strncpy */
+#include <stdlib.h> /* getenv */
+
+#ifdef _WIN32
+# include <windows.h>
+#endif
+
+
+namespace KWSYS_NAMESPACE
+{
+class RegistryHelper {
+public:
+ RegistryHelper(Registry::RegistryType registryType);
+ virtual ~RegistryHelper();
+
+ // Read a value from the registry.
+ virtual bool ReadValue(const char *key, const char **value);
+
+ // Delete a key from the registry.
+ virtual bool DeleteKey(const char *key);
+
+ // Delete a value from a given key.
+ virtual bool DeleteValue(const char *key);
+
+ // Set value in a given key.
+ virtual bool SetValue(const char *key, const char *value);
+
+ // Open the registry at toplevel/subkey.
+ virtual bool Open(const char *toplevel, const char *subkey,
+ int readonly);
+
+ // Close the registry.
+ virtual bool Close();
+
+ // Set the value of changed
+ void SetChanged(bool b) { m_Changed = b; }
+ void SetTopLevel(const char* tl);
+ const char* GetTopLevel() { return m_TopLevel.c_str(); }
+
+ //! Read from local or global scope. On Windows this mean from local machine
+ // or local user. On unix this will read from $HOME/.Projectrc or
+ // /etc/Project
+ void SetGlobalScope(bool b);
+ bool GetGlobalScope();
+
+ kwsys_stl::string EncodeKey(const char* str);
+ kwsys_stl::string EncodeValue(const char* str);
+ kwsys_stl::string DecodeValue(const char* str);
+
+protected:
+ bool m_Changed;
+ kwsys_stl::string m_TopLevel;
+ bool m_GlobalScope;
+
+#ifdef _WIN32
+ HKEY HKey;
+#endif
+ // Strip trailing and ending spaces.
+ char *Strip(char *str);
+ void SetSubKey(const char* sk);
+ kwsys_stl::string CreateKey(const char *key);
+
+ typedef kwsys_stl::map<kwsys_stl::string, kwsys_stl::string> StringToStringMap;
+ StringToStringMap EntriesMap;
+ kwsys_stl::string m_SubKey;
+ bool m_Empty;
+ bool m_SubKeySpecified;
+ kwsys_stl::string m_HomeDirectory;
+
+ Registry::RegistryType m_RegistryType;
+};
+
+//----------------------------------------------------------------------------
+#define Registry_BUFFER_SIZE 8192
+
+//----------------------------------------------------------------------------
+Registry::Registry(Registry::RegistryType registryType)
+{
+ m_Opened = false;
+ m_Locked = false;
+ this->Helper = 0;
+ this->Helper = new RegistryHelper(registryType);
+}
+
+//----------------------------------------------------------------------------
+Registry::~Registry()
+{
+ if ( m_Opened )
+ {
+ kwsys_ios::cerr << "Registry::Close should be "
+ "called here. The registry is not closed."
+ << kwsys_ios::endl;
+ }
+ delete this->Helper;
+}
+
+//----------------------------------------------------------------------------
+void Registry::SetGlobalScope(bool b)
+{
+ this->Helper->SetGlobalScope(b);
+}
+
+//----------------------------------------------------------------------------
+bool Registry::GetGlobalScope()
+{
+ return this->Helper->GetGlobalScope();
+}
+
+//----------------------------------------------------------------------------
+bool Registry::Open(const char *toplevel,
+ const char *subkey, int readonly)
+{
+ bool res = false;
+ if ( m_Locked )
+ {
+ return res;
+ }
+ if ( m_Opened )
+ {
+ if ( !this->Close() )
+ {
+ return res;
+ }
+ }
+ if ( !toplevel || !*toplevel )
+ {
+ kwsys_ios::cerr << "Registry::Opened() Toplevel not defined"
+ << kwsys_ios::endl;
+ return res;
+ }
+
+ if ( isspace(toplevel[0]) ||
+ isspace(toplevel[strlen(toplevel)-1]) )
+ {
+ kwsys_ios::cerr << "Toplevel has to start with letter or number and end"
+ " with one" << kwsys_ios::endl;
+ return res;
+ }
+
+ res = this->Helper->Open(toplevel, subkey, readonly);
+ if ( readonly != Registry::READONLY )
+ {
+ m_Locked = true;
+ }
+
+ if ( res )
+ {
+ m_Opened = true;
+ this->Helper->SetTopLevel(toplevel);
+ }
+ return res;
+}
+
+//----------------------------------------------------------------------------
+bool Registry::Close()
+{
+ bool res = false;
+ if ( m_Opened )
+ {
+ res = this->Helper->Close();
+ }
+
+ if ( res )
+ {
+ m_Opened = false;
+ m_Locked = false;
+ this->Helper->SetChanged(false);
+ }
+ return res;
+}
+
+//----------------------------------------------------------------------------
+bool Registry::ReadValue(const char *subkey,
+ const char *key,
+ const char **value)
+{
+ bool res = false;
+ bool open = false;
+ if ( ! value )
+ {
+ return res;
+ }
+ *value = 0;
+ if ( !m_Opened )
+ {
+ if ( !this->Open(this->GetTopLevel(), subkey,
+ Registry::READONLY) )
+ {
+ return res;
+ }
+ open = true;
+ }
+ res = this->Helper->ReadValue(key, value);
+
+ if ( open )
+ {
+ if ( !this->Close() )
+ {
+ res = false;
+ }
+ }
+ return res;
+}
+
+//----------------------------------------------------------------------------
+bool Registry::DeleteKey(const char *subkey, const char *key)
+{
+ bool res = false;
+ bool open = false;
+ if ( !m_Opened )
+ {
+ if ( !this->Open(this->GetTopLevel(), subkey,
+ Registry::READWRITE) )
+ {
+ return res;
+ }
+ open = true;
+ }
+
+ res = this->Helper->DeleteKey(key);
+ if ( res )
+ {
+ this->Helper->SetChanged(true);
+ }
+
+ if ( open )
+ {
+ if ( !this->Close() )
+ {
+ res = false;
+ }
+ }
+ return res;
+}
+
+//----------------------------------------------------------------------------
+bool Registry::DeleteValue(const char *subkey, const char *key)
+{
+ bool res = false;
+ bool open = false;
+ if ( !m_Opened )
+ {
+ if ( !this->Open(this->GetTopLevel(), subkey,
+ Registry::READWRITE) )
+ {
+ return res;
+ }
+ open = true;
+ }
+
+ res = this->Helper->DeleteValue(key);
+ if ( res )
+ {
+ this->Helper->SetChanged(true);
+ }
+
+ if ( open )
+ {
+ if ( !this->Close() )
+ {
+ res = false;
+ }
+ }
+ return res;
+}
+
+//----------------------------------------------------------------------------
+bool Registry::SetValue(const char *subkey, const char *key,
+ const char *value)
+{
+ bool res = false;
+ bool open = false;
+ if ( !m_Opened )
+ {
+ if ( !this->Open(this->GetTopLevel(), subkey,
+ Registry::READWRITE) )
+ {
+ return res;
+ }
+ open = true;
+ }
+
+ res = this->Helper->SetValue( key, value );
+ if ( res )
+ {
+ this->Helper->SetChanged(true);
+ }
+
+ if ( open )
+ {
+ if ( !this->Close() )
+ {
+ res = false;
+ }
+ }
+ return res;
+}
+
+//----------------------------------------------------------------------------
+const char* Registry::GetTopLevel()
+{
+ return this->Helper->GetTopLevel();
+}
+
+//----------------------------------------------------------------------------
+void Registry::SetTopLevel(const char* tl)
+{
+ this->Helper->SetTopLevel(tl);
+}
+
+//----------------------------------------------------------------------------
+void RegistryHelper::SetTopLevel(const char* tl)
+{
+ if ( tl )
+ {
+ m_TopLevel = tl;
+ }
+ else
+ {
+ m_TopLevel = "";
+ }
+}
+
+//----------------------------------------------------------------------------
+RegistryHelper::RegistryHelper(Registry::RegistryType registryType)
+{
+ m_Changed = false;
+ m_TopLevel = "";
+ m_SubKey = "";
+ m_SubKeySpecified = false;
+ m_Empty = true;
+ m_GlobalScope = false;
+ m_RegistryType = registryType;
+}
+
+//----------------------------------------------------------------------------
+RegistryHelper::~RegistryHelper()
+{
+}
+
+
+//----------------------------------------------------------------------------
+bool RegistryHelper::Open(const char *toplevel, const char *subkey,
+ int readonly)
+{
+ this->EntriesMap.clear();
+ m_Empty = 1;
+
+#ifdef _WIN32
+ if ( m_RegistryType == Registry::WIN32_REGISTRY)
+ {
+ HKEY scope = HKEY_CURRENT_USER;
+ if ( this->GetGlobalScope() )
+ {
+ scope = HKEY_LOCAL_MACHINE;
+ }
+ int res = 0;
+ kwsys_ios::ostringstream str;
+ DWORD dwDummy;
+ str << "Software\\Kitware\\" << toplevel << "\\" << subkey;
+ if ( readonly == Registry::READONLY )
+ {
+ res = ( RegOpenKeyEx(scope, str.str().c_str(),
+ 0, KEY_READ, &this->HKey) == ERROR_SUCCESS );
+ }
+ else
+ {
+ char lpClass[] = "";
+ res = ( RegCreateKeyEx(scope, str.str().c_str(),
+ 0, lpClass, REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE,
+ NULL, &this->HKey, &dwDummy) == ERROR_SUCCESS );
+ }
+ if ( res != 0 )
+ {
+ this->SetSubKey( subkey );
+ }
+ return (res != 0);
+ }
+#endif
+ if ( m_RegistryType == Registry::FILE_REGISTRY )
+ {
+ bool res = false;
+ int cc;
+ kwsys_ios::ostringstream str;
+ const char* homeDirectory;
+ if ( (homeDirectory = getenv("HOME")) == 0 )
+ {
+ if ( (homeDirectory = getenv("USERPROFILE")) == 0 )
+ {
+ return false;
+ }
+ }
+ m_HomeDirectory = homeDirectory;
+ str << m_HomeDirectory.c_str() << "/." << toplevel << "rc";
+ if ( readonly == Registry::READWRITE )
+ {
+ kwsys_ios::ofstream ofs( str.str().c_str(), kwsys_ios::ios::out|kwsys_ios::ios::app );
+ if ( ofs.fail() )
+ {
+ return false;
+ }
+ ofs.close();
+ }
+
+ kwsys_ios::ifstream *ifs = new kwsys_ios::ifstream(str.str().c_str(), kwsys_ios::ios::in
+#ifndef KWSYS_IOS_USE_ANSI
+ | kwsys_ios::ios::nocreate
+#endif
+ );
+ if ( !ifs )
+ {
+ return false;
+ }
+ if ( ifs->fail())
+ {
+ delete ifs;
+ return false;
+ }
+
+ res = true;
+ char buffer[Registry_BUFFER_SIZE];
+ while( !ifs->fail() )
+ {
+ ifs->getline(buffer, Registry_BUFFER_SIZE);
+ if ( ifs->fail() || ifs->eof() )
+ {
+ break;
+ }
+ char *line = this->Strip(buffer);
+ if ( *line == '#' || *line == 0 )
+ {
+ // Comment
+ continue;
+ }
+ int linelen = static_cast<int>(strlen(line));
+ for ( cc = 0; cc < linelen; cc++ )
+ {
+ if ( line[cc] == '=' )
+ {
+ char *key = new char[ cc+1 ];
+ strncpy( key, line, cc );
+ key[cc] = 0;
+ char *value = line + cc + 1;
+ char *nkey = this->Strip(key);
+ char *nvalue = this->Strip(value);
+ this->EntriesMap[nkey] = this->DecodeValue(nvalue);
+ m_Empty = 0;
+ delete [] key;
+ break;
+ }
+ }
+ }
+ ifs->close();
+ this->SetSubKey( subkey );
+ delete ifs;
+ return res;
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool RegistryHelper::Close()
+{
+#ifdef _WIN32
+ if ( m_RegistryType == Registry::WIN32_REGISTRY)
+ {
+ int res;
+ res = ( RegCloseKey(this->HKey) == ERROR_SUCCESS );
+ return (res != 0);
+ }
+#endif
+ if ( m_RegistryType == Registry::FILE_REGISTRY )
+ {
+ if ( !m_Changed )
+ {
+ this->SetSubKey(0);
+ return true;
+ }
+
+ kwsys_ios::ostringstream str;
+ str << m_HomeDirectory.c_str() << "/." << this->GetTopLevel() << "rc";
+ kwsys_ios::ofstream *ofs = new kwsys_ios::ofstream(str.str().c_str(), kwsys_ios::ios::out);
+ if ( !ofs )
+ {
+ return false;
+ }
+ if ( ofs->fail())
+ {
+ delete ofs;
+ return false;
+ }
+ *ofs << "# This file is automatically generated by the application" << kwsys_ios::endl
+ << "# If you change any lines or add new lines, note that all" << kwsys_ios::endl
+ << "# comments and empty lines will be deleted. Every line has" << kwsys_ios::endl
+ << "# to be in format: " << kwsys_ios::endl
+ << "# key = value" << kwsys_ios::endl
+ << "#" << kwsys_ios::endl;
+
+ if ( !this->EntriesMap.empty() )
+ {
+ RegistryHelper::StringToStringMap::iterator it;
+ for ( it = this->EntriesMap.begin();
+ it != this->EntriesMap.end();
+ ++ it )
+ {
+ *ofs << it->first.c_str() << " = " << this->EncodeValue(it->second.c_str()).c_str() << kwsys_ios::endl;
+ }
+ }
+ this->EntriesMap.clear();
+ ofs->close();
+ delete ofs;
+ this->SetSubKey(0);
+ m_Empty = 1;
+ return true;
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool RegistryHelper::ReadValue(const char *skey, const char **value)
+
+{
+#ifdef _WIN32
+ if ( m_RegistryType == Registry::WIN32_REGISTRY)
+ {
+ kwsys_stl::string key = this->CreateKey( skey );
+ if ( key.empty() )
+ {
+ return false;
+ }
+ DWORD dwType, dwSize;
+ dwType = REG_SZ;
+ char buffer[1024]; // Replace with RegQueryInfoKey
+ dwSize = sizeof(buffer);
+ int res = ( RegQueryValueEx(this->HKey, skey, NULL, &dwType,
+ (BYTE *)buffer, &dwSize) == ERROR_SUCCESS );
+ if ( !res )
+ {
+ return false;
+ }
+ this->EntriesMap[key] = buffer;
+ RegistryHelper::StringToStringMap::iterator it
+ = this->EntriesMap.find(key);
+ *value = it->second.c_str();
+ return true;
+ }
+#endif
+ if ( m_RegistryType == Registry::FILE_REGISTRY )
+ {
+ bool res = false;
+ kwsys_stl::string key = this->CreateKey( skey );
+ if ( key.empty() )
+ {
+ return false;
+ }
+
+ RegistryHelper::StringToStringMap::iterator it
+ = this->EntriesMap.find(key);
+ if ( it != this->EntriesMap.end() )
+ {
+ *value = it->second.c_str();
+ res = true;
+ }
+ return res;
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool RegistryHelper::DeleteKey(const char* skey)
+{
+#ifdef _WIN32
+ if ( m_RegistryType == Registry::WIN32_REGISTRY)
+ {
+ int res = ( RegDeleteKey( this->HKey, skey ) == ERROR_SUCCESS );
+ return (res != 0);
+ }
+#endif
+ if ( m_RegistryType == Registry::FILE_REGISTRY )
+ {
+ kwsys_stl::string key = this->CreateKey( skey );
+ if ( key.empty() )
+ {
+ return false;
+ }
+ this->EntriesMap.erase(key);
+ return true;
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool RegistryHelper::DeleteValue(const char *skey)
+{
+#ifdef _WIN32
+ if ( m_RegistryType == Registry::WIN32_REGISTRY)
+ {
+ int res = ( RegDeleteValue( this->HKey, skey ) == ERROR_SUCCESS );
+ return (res != 0);
+ }
+#endif
+ if ( m_RegistryType == Registry::FILE_REGISTRY )
+ {
+ kwsys_stl::string key = this->CreateKey( skey );
+ if ( key.empty() )
+ {
+ return false;
+ }
+ this->EntriesMap.erase(key);
+ return true;
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool RegistryHelper::SetValue(const char *skey, const char *value)
+{
+#ifdef _WIN32
+ if ( m_RegistryType == Registry::WIN32_REGISTRY)
+ {
+ DWORD len = (DWORD)(value ? strlen(value) : 0);
+ int res = ( RegSetValueEx(this->HKey, skey, 0, REG_SZ,
+ (CONST BYTE *)(const char *)value,
+ len+1) == ERROR_SUCCESS );
+ return (res != 0);
+ }
+#endif
+ if ( m_RegistryType == Registry::FILE_REGISTRY )
+ {
+ kwsys_stl::string key = this->CreateKey( skey );
+ if ( key.empty() )
+ {
+ return 0;
+ }
+ this->EntriesMap[key] = value;
+ return 1;
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+kwsys_stl::string RegistryHelper::CreateKey( const char *key )
+{
+ if ( !m_SubKeySpecified || m_SubKey.empty() || !key )
+ {
+ return "";
+ }
+ kwsys_ios::ostringstream ostr;
+ ostr << this->EncodeKey(this->m_SubKey.c_str()).c_str()
+ << "\\" << this->EncodeKey(key).c_str();
+ return ostr.str();
+}
+
+//----------------------------------------------------------------------------
+void RegistryHelper::SetSubKey(const char* sk)
+{
+ if ( !sk )
+ {
+ m_SubKey = "";
+ m_SubKeySpecified = false;
+ }
+ else
+ {
+ m_SubKey = sk;
+ m_SubKeySpecified = true;
+ }
+}
+
+//----------------------------------------------------------------------------
+char *RegistryHelper::Strip(char *str)
+{
+ int cc;
+ size_t len;
+ char *nstr;
+ if ( !str )
+ {
+ return NULL;
+ }
+ len = strlen(str);
+ nstr = str;
+ for( cc=0; cc < static_cast<int>(len); cc++ )
+ {
+ if ( !isspace( *nstr ) )
+ {
+ break;
+ }
+ nstr ++;
+ }
+ for( cc= static_cast<int>(strlen(nstr))-1; cc>=0; cc-- )
+ {
+ if ( !isspace( nstr[cc] ) )
+ {
+ nstr[cc+1] = 0;
+ break;
+ }
+ }
+ return nstr;
+}
+
+//----------------------------------------------------------------------------
+void RegistryHelper::SetGlobalScope(bool b)
+{
+ m_GlobalScope = b;
+}
+
+//----------------------------------------------------------------------------
+bool RegistryHelper::GetGlobalScope()
+{
+ return m_GlobalScope;
+}
+
+//----------------------------------------------------------------------------
+kwsys_stl::string RegistryHelper::EncodeKey(const char* str)
+{
+ kwsys_ios::ostringstream ostr;
+ while ( *str )
+ {
+ switch ( *str )
+ {
+ case '%': case '=': case '\n': case '\r': case '\t':
+ char buffer[4];
+ sprintf(buffer, "%%%02X", *str);
+ ostr << buffer;
+ break;
+ default:
+ ostr << *str;
+ }
+ str ++;
+ }
+ return ostr.str();
+}
+
+//----------------------------------------------------------------------------
+kwsys_stl::string RegistryHelper::EncodeValue(const char* str)
+{
+ kwsys_ios::ostringstream ostr;
+ while ( *str )
+ {
+ switch ( *str )
+ {
+ case '%': case '=': case '\n': case '\r': case '\t':
+ char buffer[4];
+ sprintf(buffer, "%%%02X", *str);
+ ostr << buffer;
+ break;
+ default:
+ ostr << *str;
+ }
+ str ++;
+ }
+ return ostr.str();
+}
+
+//----------------------------------------------------------------------------
+kwsys_stl::string RegistryHelper::DecodeValue(const char* str)
+{
+ kwsys_ios::ostringstream ostr;
+ while ( *str )
+ {
+ unsigned int val;
+ switch ( *str )
+ {
+ case '%':
+ if ( *(str+1) && *(str+2) && sscanf(str+1, "%x", &val) == 1 )
+ {
+ ostr << static_cast<char>(val);
+ str += 2;
+ }
+ else
+ {
+ ostr << *str;
+ }
+ break;
+ default:
+ ostr << *str;
+ }
+ str ++;
+ }
+ return ostr.str();
+}
+
+} // namespace KWSYS_NAMESPACE
diff --git a/Source/kwsys/Registry.hxx.in b/Source/kwsys/Registry.hxx.in
new file mode 100644
index 000000000..ed9b01072
--- /dev/null
+++ b/Source/kwsys/Registry.hxx.in
@@ -0,0 +1,107 @@
+/*============================================================================
+ 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@_Registry_hxx
+#define @KWSYS_NAMESPACE@_Registry_hxx
+
+#include <@KWSYS_NAMESPACE@/Configure.h>
+
+#include <@KWSYS_NAMESPACE@/stl/string>
+
+namespace @KWSYS_NAMESPACE@
+{
+
+class RegistryHelper;
+
+/** \class Registry
+ * \brief Portable registry class
+ *
+ * This class abstracts the storing of data that can be restored
+ * when the program executes again. On Win32 platform it is
+ * implemented using the registry and on unix as a file in
+ * the user's home directory.
+ */
+class @KWSYS_NAMESPACE@_EXPORT Registry
+{
+public:
+ enum RegistryType
+ {
+#ifdef _WIN32
+ WIN32_REGISTRY,
+#endif
+ FILE_REGISTRY
+ };
+
+#ifdef _WIN32
+ Registry(RegistryType registryType = WIN32_REGISTRY);
+#else
+ Registry(RegistryType registryType = FILE_REGISTRY);
+#endif
+
+ virtual ~Registry();
+
+ //! Read a value from the registry.
+ bool ReadValue(const char *subkey, const char *key, const char **value);
+
+ //! Delete a key from the registry.
+ bool DeleteKey(const char *subkey, const char *key);
+
+ //! Delete a value from a given key.
+ bool DeleteValue(const char *subkey, const char *key);
+
+ //! Set value in a given key.
+ bool SetValue(const char *subkey, const char *key,
+ const char *value);
+
+ //! Open the registry at toplevel/subkey.
+ bool Open(const char *toplevel, const char *subkey,
+ int readonly);
+
+ //! Close the registry.
+ bool Close();
+
+ //! Read from local or global scope. On Windows this mean from local machine
+ // or local user. On unix this will read from $HOME/.Projectrc or
+ // /etc/Project
+ void GlobalScopeOn() { this->SetGlobalScope(1); }
+ void GlobalScopeOff() { this->SetGlobalScope(0); }
+ void SetGlobalScope(bool b);
+ bool GetGlobalScope();
+
+ // Set or get the toplevel registry key.
+ void SetTopLevel(const char* tl);
+ const char* GetTopLevel();
+
+ // Return true if registry opened
+ bool GetOpened() { return m_Opened; }
+
+ // Should the registry be locked?
+ bool GetLocked() { return m_Locked; }
+
+ enum {
+ READONLY,
+ READWRITE
+ };
+
+ // Return true if the character is space.
+ int IsSpace(char c);
+
+private:
+ RegistryHelper* Helper;
+
+ bool m_Opened;
+
+ bool m_Locked;
+}; // End Class: Registry
+
+} // namespace @KWSYS_NAMESPACE@
+
+#endif
diff --git a/Source/kwsys/RegularExpression.cxx b/Source/kwsys/RegularExpression.cxx
new file mode 100644
index 000000000..f6eeebae4
--- /dev/null
+++ b/Source/kwsys/RegularExpression.cxx
@@ -0,0 +1,1251 @@
+/*============================================================================
+ 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.
+============================================================================*/
+//
+// Copyright (C) 1991 Texas Instruments Incorporated.
+//
+// Permission is granted to any individual or institution to use, copy, modify
+// and distribute this software, provided that this complete copyright and
+// permission notice is maintained, intact, in all copies and supporting
+// documentation.
+//
+// Texas Instruments Incorporated provides this software "as is" without
+// express or implied warranty.
+//
+//
+// Created: MNF 06/13/89 Initial Design and Implementation
+// Updated: LGO 08/09/89 Inherit from Generic
+// Updated: MBN 09/07/89 Added conditional exception handling
+// Updated: MBN 12/15/89 Sprinkled "const" qualifiers all over the place!
+// Updated: DLS 03/22/91 New lite version
+//
+
+#include "kwsysPrivate.h"
+#include KWSYS_HEADER(RegularExpression.hxx)
+
+// Work-around CMake dependency scanning limitation. This must
+// duplicate the above list of headers.
+#if 0
+# include "RegularExpression.hxx.in"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+namespace KWSYS_NAMESPACE
+{
+
+// RegularExpression -- Copies the given regular expression.
+RegularExpression::RegularExpression (const RegularExpression& rxp) {
+ if ( !rxp.program )
+ {
+ this->program = 0;
+ return;
+ }
+ int ind;
+ this->progsize = rxp.progsize; // Copy regular expression size
+ this->program = new char[this->progsize]; // Allocate storage
+ for(ind=this->progsize; ind-- != 0;) // Copy regular expresion
+ this->program[ind] = rxp.program[ind];
+ this->startp[0] = rxp.startp[0]; // Copy pointers into last
+ this->endp[0] = rxp.endp[0]; // Successful "find" operation
+ this->regmust = rxp.regmust; // Copy field
+ if (rxp.regmust != 0) {
+ char* dum = rxp.program;
+ ind = 0;
+ while (dum != rxp.regmust) {
+ ++dum;
+ ++ind;
+ }
+ this->regmust = this->program + ind;
+ }
+ this->regstart = rxp.regstart; // Copy starting index
+ this->reganch = rxp.reganch; // Copy remaining private data
+ this->regmlen = rxp.regmlen; // Copy remaining private data
+}
+
+// operator= -- Copies the given regular expression.
+RegularExpression& RegularExpression::operator= (const RegularExpression& rxp)
+{
+ if(this == &rxp)
+ {
+ return *this;
+ }
+ if ( !rxp.program )
+ {
+ this->program = 0;
+ return *this;
+ }
+ int ind;
+ this->progsize = rxp.progsize; // Copy regular expression size
+ delete [] this->program;
+ this->program = new char[this->progsize]; // Allocate storage
+ for(ind=this->progsize; ind-- != 0;) // Copy regular expresion
+ this->program[ind] = rxp.program[ind];
+ this->startp[0] = rxp.startp[0]; // Copy pointers into last
+ this->endp[0] = rxp.endp[0]; // Successful "find" operation
+ this->regmust = rxp.regmust; // Copy field
+ if (rxp.regmust != 0) {
+ char* dum = rxp.program;
+ ind = 0;
+ while (dum != rxp.regmust) {
+ ++dum;
+ ++ind;
+ }
+ this->regmust = this->program + ind;
+ }
+ this->regstart = rxp.regstart; // Copy starting index
+ this->reganch = rxp.reganch; // Copy remaining private data
+ this->regmlen = rxp.regmlen; // Copy remaining private data
+
+ return *this;
+}
+
+// operator== -- Returns true if two regular expressions have the same
+// compiled program for pattern matching.
+bool RegularExpression::operator== (const RegularExpression& rxp) const {
+ if (this != &rxp) { // Same address?
+ int ind = this->progsize; // Get regular expression size
+ if (ind != rxp.progsize) // If different size regexp
+ return false; // Return failure
+ while(ind-- != 0) // Else while still characters
+ if(this->program[ind] != rxp.program[ind]) // If regexp are different
+ return false; // Return failure
+ }
+ return true; // Else same, return success
+}
+
+
+// deep_equal -- Returns true if have the same compiled regular expressions
+// and the same start and end pointers.
+
+bool RegularExpression::deep_equal (const RegularExpression& rxp) const {
+ int ind = this->progsize; // Get regular expression size
+ if (ind != rxp.progsize) // If different size regexp
+ return false; // Return failure
+ while(ind-- != 0) // Else while still characters
+ if(this->program[ind] != rxp.program[ind]) // If regexp are different
+ return false; // Return failure
+ return (this->startp[0] == rxp.startp[0] && // Else if same start/end ptrs,
+ this->endp[0] == rxp.endp[0]); // Return true
+}
+
+// The remaining code in this file is derived from the regular expression code
+// whose copyright statement appears below. It has been changed to work
+// with the class concepts of C++ and COOL.
+
+/*
+ * compile and find
+ *
+ * Copyright (c) 1986 by University of Toronto.
+ * Written by Henry Spencer. Not derived from licensed software.
+ *
+ * Permission is granted to anyone to use this software for any
+ * purpose on any computer system, and to redistribute it freely,
+ * subject to the following restrictions:
+ *
+ * 1. The author is not responsible for the consequences of use of
+ * this software, no matter how awful, even if they arise
+ * from defects in it.
+ *
+ * 2. The origin of this software must not be misrepresented, either
+ * by explicit claim or by omission.
+ *
+ * 3. Altered versions must be plainly marked as such, and must not
+ * be misrepresented as being the original software.
+ *
+ * Beware that some of this code is subtly aware of the way operator
+ * precedence is structured in regular expressions. Serious changes in
+ * regular-expression syntax might require a total rethink.
+ */
+
+/*
+ * The "internal use only" fields in regexp.h are present to pass info from
+ * compile to execute that permits the execute phase to run lots faster on
+ * simple cases. They are:
+ *
+ * regstart char that must begin a match; '\0' if none obvious
+ * reganch is the match anchored (at beginning-of-line only)?
+ * regmust string (pointer into program) that match must include, or NULL
+ * regmlen length of regmust string
+ *
+ * Regstart and reganch permit very fast decisions on suitable starting points
+ * for a match, cutting down the work a lot. Regmust permits fast rejection
+ * of lines that cannot possibly match. The regmust tests are costly enough
+ * that compile() supplies a regmust only if the r.e. contains something
+ * potentially expensive (at present, the only such thing detected is * or +
+ * at the start of the r.e., which can involve a lot of backup). Regmlen is
+ * supplied because the test in find() needs it and compile() is computing
+ * it anyway.
+ */
+
+/*
+ * Structure for regexp "program". This is essentially a linear encoding
+ * of a nondeterministic finite-state machine (aka syntax charts or
+ * "railroad normal form" in parsing technology). Each node is an opcode
+ * plus a "next" pointer, possibly plus an operand. "Next" pointers of
+ * all nodes except BRANCH implement concatenation; a "next" pointer with
+ * a BRANCH on both ends of it is connecting two alternatives. (Here we
+ * have one of the subtle syntax dependencies: an individual BRANCH (as
+ * opposed to a collection of them) is never concatenated with anything
+ * because of operator precedence.) The operand of some types of node is
+ * a literal string; for others, it is a node leading into a sub-FSM. In
+ * particular, the operand of a BRANCH node is the first node of the branch.
+ * (NB this is *not* a tree structure: the tail of the branch connects
+ * to the thing following the set of BRANCHes.) The opcodes are:
+ */
+
+// definition number opnd? meaning
+#define END 0 // no End of program.
+#define BOL 1 // no Match "" at beginning of line.
+#define EOL 2 // no Match "" at end of line.
+#define ANY 3 // no Match any one character.
+#define ANYOF 4 // str Match any character in this string.
+#define ANYBUT 5 // str Match any character not in this
+ // string.
+#define BRANCH 6 // node Match this alternative, or the
+ // next...
+#define BACK 7 // no Match "", "next" ptr points backward.
+#define EXACTLY 8 // str Match this string.
+#define NOTHING 9 // no Match empty string.
+#define STAR 10 // node Match this (simple) thing 0 or more
+ // times.
+#define PLUS 11 // node Match this (simple) thing 1 or more
+ // times.
+#define OPEN 20 // no Mark this point in input as start of
+ // #n.
+// OPEN+1 is number 1, etc.
+#define CLOSE 30 // no Analogous to OPEN.
+
+/*
+ * Opcode notes:
+ *
+ * BRANCH The set of branches constituting a single choice are hooked
+ * together with their "next" pointers, since precedence prevents
+ * anything being concatenated to any individual branch. The
+ * "next" pointer of the last BRANCH in a choice points to the
+ * thing following the whole choice. This is also where the
+ * final "next" pointer of each individual branch points; each
+ * branch starts with the operand node of a BRANCH node.
+ *
+ * BACK Normal "next" pointers all implicitly point forward; BACK
+ * exists to make loop structures possible.
+ *
+ * STAR,PLUS '?', and complex '*' and '+', are implemented as circular
+ * BRANCH structures using BACK. Simple cases (one character
+ * per match) are implemented with STAR and PLUS for speed
+ * and to minimize recursive plunges.
+ *
+ * OPEN,CLOSE ...are numbered at compile time.
+ */
+
+/*
+ * A node is one char of opcode followed by two chars of "next" pointer.
+ * "Next" pointers are stored as two 8-bit pieces, high order first. The
+ * value is a positive offset from the opcode of the node containing it.
+ * An operand, if any, simply follows the node. (Note that much of the
+ * code generation knows about this implicit relationship.)
+ *
+ * Using two bytes for the "next" pointer is vast overkill for most things,
+ * but allows patterns to get big without disasters.
+ */
+
+#define OP(p) (*(p))
+#define NEXT(p) (((*((p)+1)&0377)<<8) + (*((p)+2)&0377))
+#define OPERAND(p) ((p) + 3)
+
+const unsigned char MAGIC = 0234;
+/*
+ * Utility definitions.
+ */
+
+#define UCHARAT(p) (reinterpret_cast<const unsigned char*>(p))[0]
+
+
+#define FAIL(m) { regerror(m); return(0); }
+#define ISMULT(c) ((c) == '*' || (c) == '+' || (c) == '?')
+#define META "^$.[()|?+*\\"
+
+
+/*
+ * Flags to be passed up and down.
+ */
+#define HASWIDTH 01 // Known never to match null string.
+#define SIMPLE 02 // Simple enough to be STAR/PLUS operand.
+#define SPSTART 04 // Starts with * or +.
+#define WORST 0 // Worst case.
+
+
+
+/////////////////////////////////////////////////////////////////////////
+//
+// COMPILE AND ASSOCIATED FUNCTIONS
+//
+/////////////////////////////////////////////////////////////////////////
+
+
+/*
+ * Global work variables for compile().
+ */
+static const char* regparse; // Input-scan pointer.
+static int regnpar; // () count.
+static char regdummy;
+static char* regcode; // Code-emit pointer; &regdummy = don't.
+static long regsize; // Code size.
+
+/*
+ * Forward declarations for compile()'s friends.
+ */
+// #ifndef static
+// #define static static
+// #endif
+static char* reg (int, int*);
+static char* regbranch (int*);
+static char* regpiece (int*);
+static char* regatom (int*);
+static char* regnode (char);
+static const char* regnext (register const char*);
+static char* regnext (register char*);
+static void regc (char);
+static void reginsert (char, char*);
+static void regtail (char*, const char*);
+static void regoptail (char*, const char*);
+
+#ifdef STRCSPN
+static int strcspn ();
+#endif
+
+
+
+/*
+ * We can't allocate space until we know how big the compiled form will be,
+ * but we can't compile it (and thus know how big it is) until we've got a
+ * place to put the code. So we cheat: we compile it twice, once with code
+ * generation turned off and size counting turned on, and once "for real".
+ * This also means that we don't allocate space until we are sure that the
+ * thing really will compile successfully, and we never have to move the
+ * code and thus invalidate pointers into it. (Note that it has to be in
+ * one piece because free() must be able to free it all.)
+ *
+ * Beware that the optimization-preparation code in here knows about some
+ * of the structure of the compiled regexp.
+ */
+
+
+// compile -- compile a regular expression into internal code
+// for later pattern matching.
+
+bool RegularExpression::compile (const char* exp) {
+ register const char* scan;
+ register const char* longest;
+ register size_t len;
+ int flags;
+
+ if (exp == 0) {
+ //RAISE Error, SYM(RegularExpression), SYM(No_Expr),
+ printf ("RegularExpression::compile(): No expression supplied.\n");
+ return false;
+ }
+
+ // First pass: determine size, legality.
+ regparse = exp;
+ regnpar = 1;
+ regsize = 0L;
+ regcode = &regdummy;
+ regc(static_cast<char>(MAGIC));
+ if(!reg(0, &flags))
+ {
+ printf ("RegularExpression::compile(): Error in compile.\n");
+ return false;
+ }
+ this->startp[0] = this->endp[0] = this->searchstring = 0;
+
+ // Small enough for pointer-storage convention?
+ if (regsize >= 32767L) { // Probably could be 65535L.
+ //RAISE Error, SYM(RegularExpression), SYM(Expr_Too_Big),
+ printf ("RegularExpression::compile(): Expression too big.\n");
+ return false;
+ }
+
+ // Allocate space.
+//#ifndef WIN32
+ if (this->program != 0) delete [] this->program;
+//#endif
+ this->program = new char[regsize];
+ this->progsize = static_cast<int>(regsize);
+
+ if (this->program == 0) {
+ //RAISE Error, SYM(RegularExpression), SYM(Out_Of_Memory),
+ printf ("RegularExpression::compile(): Out of memory.\n");
+ return false;
+ }
+
+ // Second pass: emit code.
+ regparse = exp;
+ regnpar = 1;
+ regcode = this->program;
+ regc(static_cast<char>(MAGIC));
+ reg(0, &flags);
+
+ // Dig out information for optimizations.
+ this->regstart = '\0'; // Worst-case defaults.
+ this->reganch = 0;
+ this->regmust = 0;
+ this->regmlen = 0;
+ scan = this->program + 1; // First BRANCH.
+ if (OP(regnext(scan)) == END) { // Only one top-level choice.
+ scan = OPERAND(scan);
+
+ // Starting-point info.
+ if (OP(scan) == EXACTLY)
+ this->regstart = *OPERAND(scan);
+ else if (OP(scan) == BOL)
+ this->reganch++;
+
+ //
+ // If there's something expensive in the r.e., find the longest
+ // literal string that must appear and make it the regmust. Resolve
+ // ties in favor of later strings, since the regstart check works
+ // with the beginning of the r.e. and avoiding duplication
+ // strengthens checking. Not a strong reason, but sufficient in the
+ // absence of others.
+ //
+ if (flags & SPSTART) {
+ longest = 0;
+ len = 0;
+ for (; scan != 0; scan = regnext(scan))
+ if (OP(scan) == EXACTLY && strlen(OPERAND(scan)) >= len) {
+ longest = OPERAND(scan);
+ len = strlen(OPERAND(scan));
+ }
+ this->regmust = longest;
+ this->regmlen = len;
+ }
+ }
+ return true;
+}
+
+
+/*
+ - reg - regular expression, i.e. main body or parenthesized thing
+ *
+ * Caller must absorb opening parenthesis.
+ *
+ * Combining parenthesis handling with the base level of regular expression
+ * is a trifle forced, but the need to tie the tails of the branches to what
+ * follows makes it hard to avoid.
+ */
+static char* reg (int paren, int *flagp) {
+ register char* ret;
+ register char* br;
+ register char* ender;
+ register int parno =0;
+ int flags;
+
+ *flagp = HASWIDTH; // Tentatively.
+
+ // Make an OPEN node, if parenthesized.
+ if (paren) {
+ if (regnpar >= RegularExpression::NSUBEXP) {
+ //RAISE Error, SYM(RegularExpression), SYM(Too_Many_Parens),
+ printf ("RegularExpression::compile(): Too many parentheses.\n");
+ return 0;
+ }
+ parno = regnpar;
+ regnpar++;
+ ret = regnode(static_cast<char>(OPEN + parno));
+ }
+ else
+ ret = 0;
+
+ // Pick up the branches, linking them together.
+ br = regbranch(&flags);
+ if (br == 0)
+ return (0);
+ if (ret != 0)
+ regtail(ret, br); // OPEN -> first.
+ else
+ ret = br;
+ if (!(flags & HASWIDTH))
+ *flagp &= ~HASWIDTH;
+ *flagp |= flags & SPSTART;
+ while (*regparse == '|') {
+ regparse++;
+ br = regbranch(&flags);
+ if (br == 0)
+ return (0);
+ regtail(ret, br); // BRANCH -> BRANCH.
+ if (!(flags & HASWIDTH))
+ *flagp &= ~HASWIDTH;
+ *flagp |= flags & SPSTART;
+ }
+
+ // Make a closing node, and hook it on the end.
+ ender = regnode(static_cast<char>((paren) ? CLOSE + parno : END));
+ regtail(ret, ender);
+
+ // Hook the tails of the branches to the closing node.
+ for (br = ret; br != 0; br = regnext(br))
+ regoptail(br, ender);
+
+ // Check for proper termination.
+ if (paren && *regparse++ != ')') {
+ //RAISE Error, SYM(RegularExpression), SYM(Unmatched_Parens),
+ printf ("RegularExpression::compile(): Unmatched parentheses.\n");
+ return 0;
+ }
+ else if (!paren && *regparse != '\0') {
+ if (*regparse == ')') {
+ //RAISE Error, SYM(RegularExpression), SYM(Unmatched_Parens),
+ printf ("RegularExpression::compile(): Unmatched parentheses.\n");
+ return 0;
+ }
+ else {
+ //RAISE Error, SYM(RegularExpression), SYM(Internal_Error),
+ printf ("RegularExpression::compile(): Internal error.\n");
+ return 0;
+ }
+ // NOTREACHED
+ }
+ return (ret);
+}
+
+
+/*
+ - regbranch - one alternative of an | operator
+ *
+ * Implements the concatenation operator.
+ */
+static char* regbranch (int *flagp) {
+ register char* ret;
+ register char* chain;
+ register char* latest;
+ int flags;
+
+ *flagp = WORST; // Tentatively.
+
+ ret = regnode(BRANCH);
+ chain = 0;
+ while (*regparse != '\0' && *regparse != '|' && *regparse != ')') {
+ latest = regpiece(&flags);
+ if (latest == 0)
+ return (0);
+ *flagp |= flags & HASWIDTH;
+ if (chain == 0) // First piece.
+ *flagp |= flags & SPSTART;
+ else
+ regtail(chain, latest);
+ chain = latest;
+ }
+ if (chain == 0) // Loop ran zero times.
+ regnode(NOTHING);
+
+ return (ret);
+}
+
+
+/*
+ - regpiece - something followed by possible [*+?]
+ *
+ * Note that the branching code sequences used for ? and the general cases
+ * of * and + are somewhat optimized: they use the same NOTHING node as
+ * both the endmarker for their branch list and the body of the last branch.
+ * It might seem that this node could be dispensed with entirely, but the
+ * endmarker role is not redundant.
+ */
+static char* regpiece (int *flagp) {
+ register char* ret;
+ register char op;
+ register char* next;
+ int flags;
+
+ ret = regatom(&flags);
+ if (ret == 0)
+ return (0);
+
+ op = *regparse;
+ if (!ISMULT(op)) {
+ *flagp = flags;
+ return (ret);
+ }
+
+ if (!(flags & HASWIDTH) && op != '?') {
+ //RAISE Error, SYM(RegularExpression), SYM(Empty_Operand),
+ printf ("RegularExpression::compile() : *+ operand could be empty.\n");
+ return 0;
+ }
+ *flagp = (op != '+') ? (WORST | SPSTART) : (WORST | HASWIDTH);
+
+ if (op == '*' && (flags & SIMPLE))
+ reginsert(STAR, ret);
+ else if (op == '*') {
+ // Emit x* as (x&|), where & means "self".
+ reginsert(BRANCH, ret); // Either x
+ regoptail(ret, regnode(BACK)); // and loop
+ regoptail(ret, ret); // back
+ regtail(ret, regnode(BRANCH)); // or
+ regtail(ret, regnode(NOTHING)); // null.
+ }
+ else if (op == '+' && (flags & SIMPLE))
+ reginsert(PLUS, ret);
+ else if (op == '+') {
+ // Emit x+ as x(&|), where & means "self".
+ next = regnode(BRANCH); // Either
+ regtail(ret, next);
+ regtail(regnode(BACK), ret); // loop back
+ regtail(next, regnode(BRANCH)); // or
+ regtail(ret, regnode(NOTHING)); // null.
+ }
+ else if (op == '?') {
+ // Emit x? as (x|)
+ reginsert(BRANCH, ret); // Either x
+ regtail(ret, regnode(BRANCH)); // or
+ next = regnode(NOTHING);// null.
+ regtail(ret, next);
+ regoptail(ret, next);
+ }
+ regparse++;
+ if (ISMULT(*regparse)) {
+ //RAISE Error, SYM(RegularExpression), SYM(Nested_Operand),
+ printf ("RegularExpression::compile(): Nested *?+.\n");
+ return 0;
+ }
+ return (ret);
+}
+
+
+/*
+ - regatom - the lowest level
+ *
+ * Optimization: gobbles an entire sequence of ordinary characters so that
+ * it can turn them into a single node, which is smaller to store and
+ * faster to run. Backslashed characters are exceptions, each becoming a
+ * separate node; the code is simpler that way and it's not worth fixing.
+ */
+static char* regatom (int *flagp) {
+ register char* ret;
+ int flags;
+
+ *flagp = WORST; // Tentatively.
+
+ switch (*regparse++) {
+ case '^':
+ ret = regnode(BOL);
+ break;
+ case '$':
+ ret = regnode(EOL);
+ break;
+ case '.':
+ ret = regnode(ANY);
+ *flagp |= HASWIDTH | SIMPLE;
+ break;
+ case '[':{
+ register int rxpclass;
+ register int rxpclassend;
+
+ if (*regparse == '^') { // Complement of range.
+ ret = regnode(ANYBUT);
+ regparse++;
+ }
+ else
+ ret = regnode(ANYOF);
+ if (*regparse == ']' || *regparse == '-')
+ regc(*regparse++);
+ while (*regparse != '\0' && *regparse != ']') {
+ if (*regparse == '-') {
+ regparse++;
+ if (*regparse == ']' || *regparse == '\0')
+ regc('-');
+ else {
+ rxpclass = UCHARAT(regparse - 2) + 1;
+ rxpclassend = UCHARAT(regparse);
+ if (rxpclass > rxpclassend + 1) {
+ //RAISE Error, SYM(RegularExpression), SYM(Invalid_Range),
+ printf ("RegularExpression::compile(): Invalid range in [].\n");
+ return 0;
+ }
+ for (; rxpclass <= rxpclassend; rxpclass++)
+ regc(static_cast<char>(rxpclass));
+ regparse++;
+ }
+ }
+ else
+ regc(*regparse++);
+ }
+ regc('\0');
+ if (*regparse != ']') {
+ //RAISE Error, SYM(RegularExpression), SYM(Unmatched_Bracket),
+ printf ("RegularExpression::compile(): Unmatched [].\n");
+ return 0;
+ }
+ regparse++;
+ *flagp |= HASWIDTH | SIMPLE;
+ }
+ break;
+ case '(':
+ ret = reg(1, &flags);
+ if (ret == 0)
+ return (0);
+ *flagp |= flags & (HASWIDTH | SPSTART);
+ break;
+ case '\0':
+ case '|':
+ case ')':
+ //RAISE Error, SYM(RegularExpression), SYM(Internal_Error),
+ printf ("RegularExpression::compile(): Internal error.\n"); // Never here
+ return 0;
+ case '?':
+ case '+':
+ case '*':
+ //RAISE Error, SYM(RegularExpression), SYM(No_Operand),
+ printf ("RegularExpression::compile(): ?+* follows nothing.\n");
+ return 0;
+ case '\\':
+ if (*regparse == '\0') {
+ //RAISE Error, SYM(RegularExpression), SYM(Trailing_Backslash),
+ printf ("RegularExpression::compile(): Trailing backslash.\n");
+ return 0;
+ }
+ ret = regnode(EXACTLY);
+ regc(*regparse++);
+ regc('\0');
+ *flagp |= HASWIDTH | SIMPLE;
+ break;
+ default:{
+ register int len;
+ register char ender;
+
+ regparse--;
+ len = int(strcspn(regparse, META));
+ if (len <= 0) {
+ //RAISE Error, SYM(RegularExpression), SYM(Internal_Error),
+ printf ("RegularExpression::compile(): Internal error.\n");
+ return 0;
+ }
+ ender = *(regparse + len);
+ if (len > 1 && ISMULT(ender))
+ len--; // Back off clear of ?+* operand.
+ *flagp |= HASWIDTH;
+ if (len == 1)
+ *flagp |= SIMPLE;
+ ret = regnode(EXACTLY);
+ while (len > 0) {
+ regc(*regparse++);
+ len--;
+ }
+ regc('\0');
+ }
+ break;
+ }
+ return (ret);
+}
+
+
+/*
+ - regnode - emit a node
+ Location.
+ */
+static char* regnode (char op) {
+ register char* ret;
+ register char* ptr;
+
+ ret = regcode;
+ if (ret == &regdummy) {
+ regsize += 3;
+ return (ret);
+ }
+
+ ptr = ret;
+ *ptr++ = op;
+ *ptr++ = '\0'; // Null "next" pointer.
+ *ptr++ = '\0';
+ regcode = ptr;
+
+ return (ret);
+}
+
+
+/*
+ - regc - emit (if appropriate) a byte of code
+ */
+static void regc (char b) {
+ if (regcode != &regdummy)
+ *regcode++ = b;
+ else
+ regsize++;
+}
+
+
+/*
+ - reginsert - insert an operator in front of already-emitted operand
+ *
+ * Means relocating the operand.
+ */
+static void reginsert (char op, char* opnd) {
+ register char* src;
+ register char* dst;
+ register char* place;
+
+ if (regcode == &regdummy) {
+ regsize += 3;
+ return;
+ }
+
+ src = regcode;
+ regcode += 3;
+ dst = regcode;
+ while (src > opnd)
+ *--dst = *--src;
+
+ place = opnd; // Op node, where operand used to be.
+ *place++ = op;
+ *place++ = '\0';
+ *place = '\0';
+}
+
+
+/*
+ - regtail - set the next-pointer at the end of a node chain
+ */
+static void regtail (char* p, const char* val) {
+ register char* scan;
+ register char* temp;
+ register int offset;
+
+ if (p == &regdummy)
+ return;
+
+ // Find last node.
+ scan = p;
+ for (;;) {
+ temp = regnext(scan);
+ if (temp == 0)
+ break;
+ scan = temp;
+ }
+
+ if (OP(scan) == BACK)
+ offset = int(scan - val);
+ else
+ offset = int(val - scan);
+ *(scan + 1) = static_cast<char>((offset >> 8) & 0377);
+ *(scan + 2) = static_cast<char>(offset & 0377);
+}
+
+
+/*
+ - regoptail - regtail on operand of first argument; nop if operandless
+ */
+static void regoptail (char* p, const char* val) {
+ // "Operandless" and "op != BRANCH" are synonymous in practice.
+ if (p == 0 || p == &regdummy || OP(p) != BRANCH)
+ return;
+ regtail(OPERAND(p), val);
+}
+
+
+
+////////////////////////////////////////////////////////////////////////
+//
+// find and friends
+//
+////////////////////////////////////////////////////////////////////////
+
+
+/*
+ * Global work variables for find().
+ */
+static const char* reginput; // String-input pointer.
+static const char* regbol; // Beginning of input, for ^ check.
+static const char* *regstartp; // Pointer to startp array.
+static const char* *regendp; // Ditto for endp.
+
+/*
+ * Forwards.
+ */
+static int regtry (const char*, const char* *,
+ const char* *, const char*);
+static int regmatch (const char*);
+static int regrepeat (const char*);
+
+#ifdef DEBUG
+int regnarrate = 0;
+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.
+
+bool RegularExpression::find (const char* string) {
+ register const char* s;
+
+ this->searchstring = string;
+
+ if (!this->program)
+ {
+ return false;
+ }
+
+ // Check validity of program.
+ if (UCHARAT(this->program) != MAGIC) {
+ //RAISE Error, SYM(RegularExpression), SYM(Internal_Error),
+ printf ("RegularExpression::find(): Compiled regular expression corrupted.\n");
+ return 0;
+ }
+
+ // If there is a "must appear" string, look for it.
+ if (this->regmust != 0) {
+ s = string;
+ while ((s = strchr(s, this->regmust[0])) != 0) {
+ if (strncmp(s, this->regmust, this->regmlen) == 0)
+ break; // Found it.
+ s++;
+ }
+ if (s == 0) // Not present.
+ return (0);
+ }
+
+ // Mark beginning of line for ^ .
+ regbol = string;
+
+ // Simplest case: anchored match need be tried only once.
+ if (this->reganch)
+ return (regtry(string, this->startp, this->endp, this->program) != 0);
+
+ // Messy cases: unanchored match.
+ s = string;
+ if (this->regstart != '\0')
+ // We know what char it must start with.
+ while ((s = strchr(s, this->regstart)) != 0) {
+ if (regtry(s, this->startp, this->endp, this->program))
+ return (1);
+ s++;
+
+ }
+ else
+ // We don't -- general case.
+ do {
+ if (regtry(s, this->startp, this->endp, this->program))
+ return (1);
+ } while (*s++ != '\0');
+
+ // Failure.
+ return (0);
+}
+
+
+/*
+ - regtry - try match at specific point
+ 0 failure, 1 success
+ */
+static int regtry (const char* string, const char* *start,
+ const char* *end, const char* prog) {
+ register int i;
+ register const char* *sp1;
+ register const char* *ep;
+
+ reginput = string;
+ regstartp = start;
+ regendp = end;
+
+ sp1 = start;
+ ep = end;
+ for (i = RegularExpression::NSUBEXP; i > 0; i--) {
+ *sp1++ = 0;
+ *ep++ = 0;
+ }
+ if (regmatch(prog + 1)) {
+ start[0] = string;
+ end[0] = reginput;
+ return (1);
+ }
+ else
+ return (0);
+}
+
+
+/*
+ - regmatch - main matching routine
+ *
+ * Conceptually the strategy is simple: check to see whether the current
+ * node matches, call self recursively to see whether the rest matches,
+ * and then act accordingly. In practice we make some effort to avoid
+ * recursion, in particular by going through "ordinary" nodes (that don't
+ * need to know whether the rest of the match failed) by a loop instead of
+ * by recursion.
+ * 0 failure, 1 success
+ */
+static int regmatch (const char* prog) {
+ register const char* scan; // Current node.
+ const char* next; // Next node.
+
+ scan = prog;
+
+ while (scan != 0) {
+
+ next = regnext(scan);
+
+ switch (OP(scan)) {
+ case BOL:
+ if (reginput != regbol)
+ return (0);
+ break;
+ case EOL:
+ if (*reginput != '\0')
+ return (0);
+ break;
+ case ANY:
+ if (*reginput == '\0')
+ return (0);
+ reginput++;
+ break;
+ case EXACTLY:{
+ register size_t len;
+ register const char* opnd;
+
+ opnd = OPERAND(scan);
+ // Inline the first character, for speed.
+ if (*opnd != *reginput)
+ return (0);
+ len = strlen(opnd);
+ if (len > 1 && strncmp(opnd, reginput, len) != 0)
+ return (0);
+ reginput += len;
+ }
+ break;
+ case ANYOF:
+ if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) == 0)
+ return (0);
+ reginput++;
+ break;
+ case ANYBUT:
+ if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) != 0)
+ return (0);
+ reginput++;
+ break;
+ case NOTHING:
+ break;
+ case BACK:
+ break;
+ case OPEN + 1:
+ case OPEN + 2:
+ case OPEN + 3:
+ case OPEN + 4:
+ case OPEN + 5:
+ case OPEN + 6:
+ case OPEN + 7:
+ case OPEN + 8:
+ case OPEN + 9:{
+ register int no;
+ register const char* save;
+
+ no = OP(scan) - OPEN;
+ save = reginput;
+
+ if (regmatch(next)) {
+
+ //
+ // Don't set startp if some later invocation of the
+ // same parentheses already has.
+ //
+ if (regstartp[no] == 0)
+ regstartp[no] = save;
+ return (1);
+ }
+ else
+ return (0);
+ }
+// break;
+ case CLOSE + 1:
+ case CLOSE + 2:
+ case CLOSE + 3:
+ case CLOSE + 4:
+ case CLOSE + 5:
+ case CLOSE + 6:
+ case CLOSE + 7:
+ case CLOSE + 8:
+ case CLOSE + 9:{
+ register int no;
+ register const char* save;
+
+ no = OP(scan) - CLOSE;
+ save = reginput;
+
+ if (regmatch(next)) {
+
+ //
+ // Don't set endp if some later invocation of the
+ // same parentheses already has.
+ //
+ if (regendp[no] == 0)
+ regendp[no] = save;
+ return (1);
+ }
+ else
+ return (0);
+ }
+// break;
+ case BRANCH:{
+
+ register const char* save;
+
+ if (OP(next) != BRANCH) // No choice.
+ next = OPERAND(scan); // Avoid recursion.
+ else {
+ do {
+ save = reginput;
+ if (regmatch(OPERAND(scan)))
+ return (1);
+ reginput = save;
+ scan = regnext(scan);
+ } while (scan != 0 && OP(scan) == BRANCH);
+ return (0);
+ // NOTREACHED
+ }
+ }
+ break;
+ case STAR:
+ case PLUS:{
+ register char nextch;
+ register int no;
+ register const char* save;
+ register int min_no;
+
+ //
+ // Lookahead to avoid useless match attempts when we know
+ // what character comes next.
+ //
+ nextch = '\0';
+ if (OP(next) == EXACTLY)
+ nextch = *OPERAND(next);
+ min_no = (OP(scan) == STAR) ? 0 : 1;
+ save = reginput;
+ no = regrepeat(OPERAND(scan));
+ while (no >= min_no) {
+ // If it could work, try it.
+ if (nextch == '\0' || *reginput == nextch)
+ if (regmatch(next))
+ return (1);
+ // Couldn't or didn't -- back up.
+ no--;
+ reginput = save + no;
+ }
+ return (0);
+ }
+// break;
+ case END:
+ return (1); // Success!
+
+ default:
+ //RAISE Error, SYM(RegularExpression), SYM(Internal_Error),
+ printf ("RegularExpression::find(): Internal error -- memory corrupted.\n");
+ return 0;
+ }
+ scan = next;
+ }
+
+ //
+ // We get here only if there's trouble -- normally "case END" is the
+ // terminating point.
+ //
+ //RAISE Error, SYM(RegularExpression), SYM(Internal_Error),
+ printf ("RegularExpression::find(): Internal error -- corrupted pointers.\n");
+ return (0);
+}
+
+
+/*
+ - regrepeat - repeatedly match something simple, report how many
+ */
+static int regrepeat (const char* p) {
+ register int count = 0;
+ register const char* scan;
+ register const char* opnd;
+
+ scan = reginput;
+ opnd = OPERAND(p);
+ switch (OP(p)) {
+ case ANY:
+ count = int(strlen(scan));
+ scan += count;
+ break;
+ case EXACTLY:
+ while (*opnd == *scan) {
+ count++;
+ scan++;
+ }
+ break;
+ case ANYOF:
+ while (*scan != '\0' && strchr(opnd, *scan) != 0) {
+ count++;
+ scan++;
+ }
+ break;
+ case ANYBUT:
+ while (*scan != '\0' && strchr(opnd, *scan) == 0) {
+ count++;
+ scan++;
+ }
+ break;
+ default: // Oh dear. Called inappropriately.
+ //RAISE Error, SYM(RegularExpression), SYM(Internal_Error),
+ printf ("cm RegularExpression::find(): Internal error.\n");
+ return 0;
+ }
+ reginput = scan;
+ return (count);
+}
+
+
+/*
+ - regnext - dig the "next" pointer out of a node
+ */
+static const char* regnext (register const char* p) {
+ register int offset;
+
+ if (p == &regdummy)
+ return (0);
+
+ offset = NEXT(p);
+ if (offset == 0)
+ return (0);
+
+ if (OP(p) == BACK)
+ return (p - offset);
+ else
+ return (p + offset);
+}
+
+static char* regnext (register char* p) {
+ register int offset;
+
+ if (p == &regdummy)
+ return (0);
+
+ offset = NEXT(p);
+ if (offset == 0)
+ return (0);
+
+ if (OP(p) == BACK)
+ return (p - offset);
+ else
+ return (p + offset);
+}
+
+} // namespace KWSYS_NAMESPACE
diff --git a/Source/kwsys/RegularExpression.hxx.in b/Source/kwsys/RegularExpression.hxx.in
new file mode 100644
index 000000000..62e9cad23
--- /dev/null
+++ b/Source/kwsys/RegularExpression.hxx.in
@@ -0,0 +1,414 @@
+/*============================================================================
+ 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.
+============================================================================*/
+// Original Copyright notice:
+// Copyright (C) 1991 Texas Instruments Incorporated.
+//
+// Permission is granted to any individual or institution to use, copy, modify,
+// and distribute this software, provided that this complete copyright and
+// permission notice is maintained, intact, in all copies and supporting
+// documentation.
+//
+// Texas Instruments Incorporated provides this software "as is" without
+// express or implied warranty.
+//
+// Created: MNF 06/13/89 Initial Design and Implementation
+// Updated: LGO 08/09/89 Inherit from Generic
+// Updated: MBN 09/07/89 Added conditional exception handling
+// Updated: MBN 12/15/89 Sprinkled "const" qualifiers all over the place!
+// Updated: DLS 03/22/91 New lite version
+//
+
+#ifndef @KWSYS_NAMESPACE@_RegularExpression_hxx
+#define @KWSYS_NAMESPACE@_RegularExpression_hxx
+
+#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
+
+/* Disable useless Borland warnings. KWSys tries not to force things
+ on its includers, but there is no choice here. */
+#if defined(__BORLANDC__)
+# pragma warn -8027 /* function not inlined. */
+#endif
+
+namespace @KWSYS_NAMESPACE@
+{
+
+/** \class RegularExpression
+ * \brief Implements pattern matching with regular expressions.
+ *
+ * This is the header file for the regular expression class. An object of
+ * this class contains a regular expression, in a special "compiled" format.
+ * This compiled format consists of several slots all kept as the objects
+ * private data. The RegularExpression class provides a convenient way to
+ * represent regular expressions. It makes it easy to search for the same
+ * regular expression in many different strings without having to compile a
+ * string to regular expression format more than necessary.
+ *
+ * This class implements pattern matching via regular expressions.
+ * A regular expression allows a programmer to specify complex
+ * patterns that can be searched for and matched against the
+ * character string of a string object. In its simplest form, a
+ * regular expression is a sequence of characters used to
+ * search for exact character matches. However, many times the
+ * exact sequence to be found is not known, or only a match at
+ * the beginning or end of a string is desired. The RegularExpression regu-
+ * lar expression class implements regular expression pattern
+ * matching as is found and implemented in many UNIX commands
+ * and utilities.
+ *
+ * Example: The perl code
+ *
+ * $filename =~ m"([a-z]+)\.cc";
+ * print $1;
+ *
+ * Is written as follows in C++
+ *
+ * RegularExpression re("([a-z]+)\\.cc");
+ * re.find(filename);
+ * cerr << re.match(1);
+ *
+ *
+ * The regular expression class provides a convenient mechanism
+ * for specifying and manipulating regular expressions. The
+ * regular expression object allows specification of such pat-
+ * terns by using the following regular expression metacharac-
+ * ters:
+ *
+ * ^ Matches at beginning of a line
+ *
+ * $ Matches at end of a line
+ *
+ * . Matches any single character
+ *
+ * [ ] Matches any character(s) inside the brackets
+ *
+ * [^ ] Matches any character(s) not inside the brackets
+ *
+ * - Matches any character in range on either side of a dash
+ *
+ * * Matches preceding pattern zero or more times
+ *
+ * + Matches preceding pattern one or more times
+ *
+ * ? Matches preceding pattern zero or once only
+ *
+ * () Saves a matched expression and uses it in a later match
+ *
+ * Note that more than one of these metacharacters can be used
+ * in a single regular expression in order to create complex
+ * search patterns. For example, the pattern [^ab1-9] says to
+ * match any character sequence that does not begin with the
+ * characters "ab" followed by numbers in the series one
+ * through nine.
+ *
+ * There are three constructors for RegularExpression. One just creates an
+ * empty RegularExpression object. Another creates a RegularExpression
+ * object and initializes it with a regular expression that is given in the
+ * form of a char*. The third takes a reference to a RegularExpression
+ * object as an argument and creates an object initialized with the
+ * information from the given RegularExpression object.
+ *
+ * The find member function finds the first occurence of the regualr
+ * expression of that object in the string given to find as an argument. Find
+ * returns a boolean, and if true, mutates the private data appropriately.
+ * Find sets pointers to the beginning and end of the thing last found, they
+ * are pointers into the actual string that was searched. The start and end
+ * member functions return indicies into the searched string that correspond
+ * to the beginning and end pointers respectively. The compile member
+ * function takes a char* and puts the compiled version of the char* argument
+ * into the object's private data fields. The == and != operators only check
+ * the to see if the compiled regular expression is the same, and the
+ * deep_equal functions also checks to see if the start and end pointers are
+ * the same. The is_valid function returns false if program is set to NULL,
+ * (i.e. there is no valid compiled exression). The set_invalid function sets
+ * the program to NULL (Warning: this deletes the compiled expression). The
+ * following examples may help clarify regular expression usage:
+ *
+ * * The regular expression "^hello" matches a "hello" only at the
+ * beginning of a line. It would match "hello there" but not "hi,
+ * hello there".
+ *
+ * * The regular expression "long$" matches a "long" only at the end
+ * of a line. It would match "so long\0", but not "long ago".
+ *
+ * * The regular expression "t..t..g" will match anything that has a
+ * "t" then any two characters, another "t", any two characters and
+ * then a "g". It will match "testing", or "test again" but would
+ * not match "toasting"
+ *
+ * * The regular expression "[1-9ab]" matches any number one through
+ * nine, and the characters "a" and "b". It would match "hello 1"
+ * or "begin", but would not match "no-match".
+ *
+ * * The regular expression "[^1-9ab]" matches any character that is
+ * not a number one through nine, or an "a" or "b". It would NOT
+ * match "hello 1" or "begin", but would match "no-match".
+ *
+ * * The regular expression "br* " matches something that begins with
+ * a "b", is followed by zero or more "r"s, and ends in a space. It
+ * would match "brrrrr ", and "b ", but would not match "brrh ".
+ *
+ * * The regular expression "br+ " matches something that begins with
+ * a "b", is followed by one or more "r"s, and ends in a space. It
+ * would match "brrrrr ", and "br ", but would not match "b " or
+ * "brrh ".
+ *
+ * * The regular expression "br? " matches something that begins with
+ * a "b", is followed by zero or one "r"s, and ends in a space. It
+ * would match "br ", and "b ", but would not match "brrrr " or
+ * "brrh ".
+ *
+ * * The regular expression "(..p)b" matches something ending with pb
+ * and beginning with whatever the two characters before the first p
+ * encounterd in the line were. It would find "repb" in "rep drepa
+ * qrepb". The regular expression "(..p)a" would find "repa qrepb"
+ * in "rep drepa qrepb"
+ *
+ * * The regular expression "d(..p)" matches something ending with p,
+ * beginning with d, and having two characters in between that are
+ * the same as the two characters before the first p encounterd in
+ * the line. It would match "drepa qrepb" in "rep drepa qrepb".
+ *
+ */
+class @KWSYS_NAMESPACE@_EXPORT RegularExpression
+{
+public:
+ /**
+ * Instantiate RegularExpression with program=NULL.
+ */
+ inline RegularExpression ();
+
+ /**
+ * Instantiate RegularExpression with compiled char*.
+ */
+ inline RegularExpression (char const*);
+
+ /**
+ * Instantiate RegularExpression as a copy of another regular expression.
+ */
+ RegularExpression (RegularExpression const&);
+
+ /**
+ * Destructor.
+ */
+ inline ~RegularExpression();
+
+ /**
+ * Compile a regular expression into internal code
+ * for later pattern matching.
+ */
+ bool compile (char const*);
+
+ /**
+ * Matches the regular expression to the given string.
+ * Returns true if found, and sets start and end indexes accordingly.
+ */
+ bool find (char const*);
+
+ /**
+ * 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&);
+
+ /**
+ * Index to start of first find.
+ */
+ inline kwsys_stl::string::size_type start() const;
+
+ /**
+ * Index to end of first find.
+ */
+ inline kwsys_stl::string::size_type end() const;
+
+ /**
+ * Copy the given regular expression.
+ */
+ RegularExpression& operator= (const RegularExpression& rxp);
+
+ /**
+ * Returns true if two regular expressions have the same
+ * compiled program for pattern matching.
+ */
+ bool operator== (RegularExpression const&) const;
+
+ /**
+ * Returns true if two regular expressions have different
+ * compiled program for pattern matching.
+ */
+ inline bool operator!= (RegularExpression const&) const;
+
+ /**
+ * Returns true if have the same compiled regular expressions
+ * and the same start and end pointers.
+ */
+ bool deep_equal (RegularExpression const&) const;
+
+ /**
+ * True if the compiled regexp is valid.
+ */
+ inline bool is_valid() const;
+
+ /**
+ * Marks the regular expression as invalid.
+ */
+ inline void set_invalid();
+
+ /**
+ * 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;
+
+ enum { NSUBEXP = 10 };
+private:
+ const char* startp[NSUBEXP];
+ const char* endp[NSUBEXP];
+ 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
+ char* program;
+ int progsize;
+ const char* searchstring;
+};
+
+/**
+ * Create an empty regular expression.
+ */
+inline RegularExpression::RegularExpression ()
+{
+ this->program = 0;
+}
+
+/**
+ * Creates a regular expression from string s, and
+ * compiles s.
+ */
+inline RegularExpression::RegularExpression (const char* s)
+{
+ this->program = 0;
+ if ( s )
+ {
+ this->compile(s);
+ }
+}
+
+/**
+ * Destroys and frees space allocated for the regular expression.
+ */
+inline RegularExpression::~RegularExpression ()
+{
+//#ifndef WIN32
+ delete [] this->program;
+//#endif
+}
+
+/**
+ * Set the start position for the regular expression.
+ */
+inline kwsys_stl::string::size_type RegularExpression::start () const
+{
+ return static_cast<kwsys_stl::string::size_type>(
+ this->startp[0] - searchstring);
+}
+
+
+/**
+ * Returns the start/end index of the last item found.
+ */
+inline kwsys_stl::string::size_type RegularExpression::end () const
+{
+ return static_cast<kwsys_stl::string::size_type>(
+ this->endp[0] - searchstring);
+}
+
+/**
+ * Returns true if two regular expressions have different
+ * compiled program for pattern matching.
+ */
+inline bool RegularExpression::operator!= (const RegularExpression& r) const
+{
+ return(!(*this == r));
+}
+
+/**
+ * Returns true if a valid regular expression is compiled
+ * and ready for pattern matching.
+ */
+inline bool RegularExpression::is_valid () const
+{
+ return (this->program != 0);
+}
+
+
+inline void RegularExpression::set_invalid ()
+{
+//#ifndef WIN32
+ delete [] this->program;
+//#endif
+ this->program = 0;
+}
+
+/**
+ * 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
+{
+ return static_cast<kwsys_stl::string::size_type>(
+ this->startp[n] - searchstring);
+}
+
+
+/**
+ * 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
+{
+ return static_cast<kwsys_stl::string::size_type>(
+ this->endp[n] - searchstring);
+}
+
+/**
+ * Return nth submatch as a string.
+ */
+inline kwsys_stl::string RegularExpression::match(int n) const
+{
+ if (this->startp[n]==0)
+ {
+ return kwsys_stl::string("");
+ }
+ else
+ {
+ return kwsys_stl::string(this->startp[n],
+ static_cast<kwsys_stl::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
new file mode 100644
index 000000000..8521099ad
--- /dev/null
+++ b/Source/kwsys/SharedForward.h.in
@@ -0,0 +1,922 @@
+/*============================================================================
+ 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@_SharedForward_h
+#define @KWSYS_NAMESPACE@_SharedForward_h
+
+/*
+ This header is used to create a forwarding executable sets up the
+ shared library search path and replaces itself with a real
+ executable. This is useful when creating installations on UNIX with
+ shared libraries that will run from any install directory. Typical
+ usage:
+
+ #if defined(CMAKE_INTDIR)
+ # define CONFIG_DIR_PRE CMAKE_INTDIR "/"
+ # define CONFIG_DIR_POST "/" CMAKE_INTDIR
+ #else
+ # define CONFIG_DIR_PRE ""
+ # define CONFIG_DIR_POST ""
+ #endif
+ #define @KWSYS_NAMESPACE@_SHARED_FORWARD_DIR_BUILD "/path/to/foo-build/bin"
+ #define @KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_BUILD "." CONFIG_DIR_POST
+ #define @KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_INSTALL "../lib/foo-1.2"
+ #define @KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_BUILD CONFIG_DIR_PRE "foo-real"
+ #define @KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_INSTALL "../lib/foo-1.2/foo-real"
+ #define @KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_COMMAND "--command"
+ #define @KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_PRINT "--print"
+ #define @KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_LDD "--ldd"
+ #if defined(CMAKE_INTDIR)
+ # define @KWSYS_NAMESPACE@_SHARED_FORWARD_CONFIG_NAME CMAKE_INTDIR
+ #endif
+ #include <@KWSYS_NAMESPACE@/SharedForward.h>
+ int main(int argc, char** argv)
+ {
+ return @KWSYS_NAMESPACE@_shared_forward_to_real(argc, argv);
+ }
+
+ Specify search and executable paths relative to the forwarding
+ executable location or as full paths. Include no trailing slash.
+ In the case of a multi-configuration build, when CMAKE_INTDIR is
+ defined, the DIR_BUILD setting should point at the directory above
+ the executable (the one containing the per-configuration
+ subdirectory specified by CMAKE_INTDIR). Then PATH_BUILD entries
+ and EXE_BUILD should be specified relative to this location and use
+ CMAKE_INTDIR as necessary. In the above example imagine appending
+ the PATH_BUILD or EXE_BUILD setting to the DIR_BUILD setting. The
+ result should form a valid path with per-configuration subdirectory.
+
+ Additional paths may be specified in the PATH_BUILD and PATH_INSTALL
+ variables by using comma-separated strings. For example:
+
+ #define @KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_BUILD \
+ "." CONFIG_DIR_POST, "/path/to/bar-build" CONFIG_DIR_POST
+ #define @KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_INSTALL \
+ "../lib/foo-1.2", "../lib/bar-4.5"
+
+ See the comments below for specific explanations of each macro.
+*/
+
+/*--------------------------------------------------------------------------*/
+
+/* Full path to the directory in which this executable is built. Do
+ not include a trailing slash. */
+#if !defined(@KWSYS_NAMESPACE@_SHARED_FORWARD_DIR_BUILD)
+# error "Must define @KWSYS_NAMESPACE@_SHARED_FORWARD_DIR_BUILD"
+#endif
+#if !defined(KWSYS_SHARED_FORWARD_DIR_BUILD)
+# define KWSYS_SHARED_FORWARD_DIR_BUILD @KWSYS_NAMESPACE@_SHARED_FORWARD_DIR_BUILD
+#endif
+
+/* Library search path for build tree. */
+#if !defined(@KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_BUILD)
+# error "Must define @KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_BUILD"
+#endif
+#if !defined(KWSYS_SHARED_FORWARD_PATH_BUILD)
+# define KWSYS_SHARED_FORWARD_PATH_BUILD @KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_BUILD
+#endif
+
+/* Library search path for install tree. */
+#if !defined(@KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_INSTALL)
+# error "Must define @KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_INSTALL"
+#endif
+#if !defined(KWSYS_SHARED_FORWARD_PATH_INSTALL)
+# define KWSYS_SHARED_FORWARD_PATH_INSTALL @KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_INSTALL
+#endif
+
+/* The real executable to which to forward in the build tree. */
+#if !defined(@KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_BUILD)
+# error "Must define @KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_BUILD"
+#endif
+#if !defined(KWSYS_SHARED_FORWARD_EXE_BUILD)
+# define KWSYS_SHARED_FORWARD_EXE_BUILD @KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_BUILD
+#endif
+
+/* The real executable to which to forward in the install tree. */
+#if !defined(@KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_INSTALL)
+# error "Must define @KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_INSTALL"
+#endif
+#if !defined(KWSYS_SHARED_FORWARD_EXE_INSTALL)
+# define KWSYS_SHARED_FORWARD_EXE_INSTALL @KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_INSTALL
+#endif
+
+/* The configuration name with which this executable was built (Debug/Release). */
+#if defined(@KWSYS_NAMESPACE@_SHARED_FORWARD_CONFIG_NAME)
+# define KWSYS_SHARED_FORWARD_CONFIG_NAME @KWSYS_NAMESPACE@_SHARED_FORWARD_CONFIG_NAME
+#else
+# undef KWSYS_SHARED_FORWARD_CONFIG_NAME
+#endif
+
+/* Create command line option to replace executable. */
+#if defined(@KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_COMMAND)
+# if !defined(KWSYS_SHARED_FORWARD_OPTION_COMMAND)
+# define KWSYS_SHARED_FORWARD_OPTION_COMMAND @KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_COMMAND
+# endif
+#else
+# undef KWSYS_SHARED_FORWARD_OPTION_COMMAND
+#endif
+
+/* Create command line option to print environment setting and exit. */
+#if defined(@KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_PRINT)
+# if !defined(KWSYS_SHARED_FORWARD_OPTION_PRINT)
+# define KWSYS_SHARED_FORWARD_OPTION_PRINT @KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_PRINT
+# endif
+#else
+# undef KWSYS_SHARED_FORWARD_OPTION_PRINT
+#endif
+
+/* Create command line option to run ldd or equivalent. */
+#if defined(@KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_LDD)
+# if !defined(KWSYS_SHARED_FORWARD_OPTION_LDD)
+# define KWSYS_SHARED_FORWARD_OPTION_LDD @KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_LDD
+# endif
+#else
+# undef KWSYS_SHARED_FORWARD_OPTION_LDD
+#endif
+
+/*--------------------------------------------------------------------------*/
+/* Include needed system headers. */
+
+#include <stddef.h> /* size_t */
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+# include <io.h>
+# include <windows.h>
+# include <process.h>
+# define KWSYS_SHARED_FORWARD_ESCAPE_ARGV /* re-escape argv for execvp */
+#else
+# include <unistd.h>
+# include <sys/stat.h>
+#endif
+
+/*--------------------------------------------------------------------------*/
+/* Configuration for this platform. */
+
+/* The path separator for this platform. */
+#if defined(_WIN32) && !defined(__CYGWIN__)
+# define KWSYS_SHARED_FORWARD_PATH_SEP ';'
+# define KWSYS_SHARED_FORWARD_PATH_SLASH '\\'
+#else
+# define KWSYS_SHARED_FORWARD_PATH_SEP ':'
+# define KWSYS_SHARED_FORWARD_PATH_SLASH '/'
+#endif
+static const char kwsys_shared_forward_path_sep[2] = {KWSYS_SHARED_FORWARD_PATH_SEP, 0};
+static const char kwsys_shared_forward_path_slash[2] = {KWSYS_SHARED_FORWARD_PATH_SLASH, 0};
+
+/* The maximum length of a file name. */
+#if defined(PATH_MAX)
+# define KWSYS_SHARED_FORWARD_MAXPATH PATH_MAX
+#elif defined(MAXPATHLEN)
+# define KWSYS_SHARED_FORWARD_MAXPATH MAXPATHLEN
+#else
+# define KWSYS_SHARED_FORWARD_MAXPATH 16384
+#endif
+
+/* Select the environment variable holding the shared library runtime
+ search path for this platform and build configuration. Also select
+ ldd command equivalent. */
+
+/* Linux */
+#if defined(__linux)
+# define KWSYS_SHARED_FORWARD_LDD "ldd"
+# define KWSYS_SHARED_FORWARD_LDD_N 1
+# define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY_PATH"
+
+/* FreeBSD */
+#elif defined(__FreeBSD__)
+# define KWSYS_SHARED_FORWARD_LDD "ldd"
+# define KWSYS_SHARED_FORWARD_LDD_N 1
+# define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY_PATH"
+
+/* OpenBSD */
+#elif defined(__OpenBSD__)
+# define KWSYS_SHARED_FORWARD_LDD "ldd"
+# define KWSYS_SHARED_FORWARD_LDD_N 1
+# define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY_PATH"
+
+/* OSX */
+#elif defined(__APPLE__)
+# define KWSYS_SHARED_FORWARD_LDD "otool", "-L"
+# define KWSYS_SHARED_FORWARD_LDD_N 2
+# define KWSYS_SHARED_FORWARD_LDPATH "DYLD_LIBRARY_PATH"
+
+/* AIX */
+#elif defined(_AIX)
+# define KWSYS_SHARED_FORWARD_LDD "dump", "-H"
+# define KWSYS_SHARED_FORWARD_LDD_N 2
+# define KWSYS_SHARED_FORWARD_LDPATH "LIBPATH"
+
+/* SUN */
+#elif defined(__sun)
+# define KWSYS_SHARED_FORWARD_LDD "ldd"
+# define KWSYS_SHARED_FORWARD_LDD_N 1
+# include <sys/isa_defs.h>
+# if defined(_ILP32)
+# define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY_PATH"
+# elif defined(_LP64)
+# define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY_PATH_64"
+# endif
+
+/* HP-UX */
+#elif defined(__hpux)
+# define KWSYS_SHARED_FORWARD_LDD "chatr"
+# define KWSYS_SHARED_FORWARD_LDD_N 1
+# if defined(__LP64__)
+# define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY_PATH"
+# else
+# define KWSYS_SHARED_FORWARD_LDPATH "SHLIB_PATH"
+# endif
+
+/* SGI MIPS */
+#elif defined(__sgi) && defined(_MIPS_SIM)
+# define KWSYS_SHARED_FORWARD_LDD "ldd"
+# define KWSYS_SHARED_FORWARD_LDD_N 1
+# if _MIPS_SIM == _ABIO32
+# define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY_PATH"
+# elif _MIPS_SIM == _ABIN32
+# define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARYN32_PATH"
+# elif _MIPS_SIM == _ABI64
+# define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY64_PATH"
+# endif
+
+/* Cygwin */
+#elif defined(__CYGWIN__)
+# define KWSYS_SHARED_FORWARD_LDD "cygcheck" /* TODO: cygwin 1.7 has ldd */
+# define KWSYS_SHARED_FORWARD_LDD_N 1
+# define KWSYS_SHARED_FORWARD_LDPATH "PATH"
+
+/* Windows */
+#elif defined(_WIN32)
+# define KWSYS_SHARED_FORWARD_LDPATH "PATH"
+
+/* Guess on this unknown system. */
+#else
+# define KWSYS_SHARED_FORWARD_LDD "ldd"
+# define KWSYS_SHARED_FORWARD_LDD_N 1
+# define KWSYS_SHARED_FORWARD_LDPATH "LD_LIBRARY_PATH"
+#endif
+
+#ifdef KWSYS_SHARED_FORWARD_ESCAPE_ARGV
+/*--------------------------------------------------------------------------*/
+typedef struct kwsys_sf_arg_info_s
+{
+ const char* arg;
+ int size;
+ int quote;
+} kwsys_sf_arg_info;
+
+/*--------------------------------------------------------------------------*/
+static kwsys_sf_arg_info kwsys_sf_get_arg_info(const char* in)
+{
+ /* Initialize information. */
+ kwsys_sf_arg_info info;
+
+ /* String iterator. */
+ const char* c;
+
+ /* Keep track of how many backslashes have been encountered in a row. */
+ int windows_backslashes = 0;
+
+ /* Start with the length of the original argument, plus one for
+ either a terminating null or a separating space. */
+ info.arg = in;
+ info.size = (int)strlen(in) + 1;
+ info.quote = 0;
+
+ /* Scan the string for characters that require escaping or quoting. */
+ for(c=in; *c; ++c)
+ {
+ /* Check whether this character needs quotes. */
+ if(strchr(" \t?'#&<>|^", *c))
+ {
+ info.quote = 1;
+ }
+
+ /* 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. */
+ info.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 the argument needs surrounding quotes. */
+ if(info.quote)
+ {
+ /* Surrounding quotes are needed. Allocate space for them. */
+ info.size += 2;
+
+ /* We must escape all ending backslashes when quoting on windows. */
+ info.size += windows_backslashes;
+ }
+
+ return info;
+}
+
+/*--------------------------------------------------------------------------*/
+static char* kwsys_sf_get_arg(kwsys_sf_arg_info info, char* out)
+{
+ /* 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. */
+ if(info.quote)
+ {
+ /* Add the opening quote for this argument. */
+ *out++ = '"';
+ }
+
+ /* Scan the string for characters that require escaping or quoting. */
+ for(c=info.arg; *c; ++c)
+ {
+ /* 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;
+ }
+
+ /* Store this character. */
+ *out++ = *c;
+ }
+
+ if(info.quote)
+ {
+ /* 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;
+}
+#endif
+
+/*--------------------------------------------------------------------------*/
+/* Function to convert a logical or relative path to a physical full path. */
+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,
+ out_path, 0);
+ return n > 0 && n <= KWSYS_SHARED_FORWARD_MAXPATH;
+#else
+ /* Implementation for UNIX. */
+ return realpath(in_path, out_path) != 0;
+#endif
+}
+
+/*--------------------------------------------------------------------------*/
+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,
+ OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ HANDLE h2 = CreateFile(file2, GENERIC_READ, FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ if(h1 != INVALID_HANDLE_VALUE && h2 != INVALID_HANDLE_VALUE)
+ {
+ BY_HANDLE_FILE_INFORMATION fi1;
+ BY_HANDLE_FILE_INFORMATION fi2;
+ GetFileInformationByHandle(h1, &fi1);
+ GetFileInformationByHandle(h2, &fi2);
+ result = (fi1.dwVolumeSerialNumber == fi2.dwVolumeSerialNumber &&
+ fi1.nFileIndexHigh == fi2.nFileIndexHigh &&
+ fi1.nFileIndexLow == fi2.nFileIndexLow);
+ }
+ CloseHandle(h1);
+ CloseHandle(h2);
+ return result;
+#else
+ struct stat fs1, fs2;
+ return (stat(file1, &fs1) == 0 && stat(file2, &fs2) == 0 &&
+ memcmp(&fs2.st_dev, &fs1.st_dev, sizeof(fs1.st_dev)) == 0 &&
+ memcmp(&fs2.st_ino, &fs1.st_ino, sizeof(fs1.st_ino)) == 0 &&
+ fs2.st_size == fs1.st_size);
+#endif
+}
+
+/*--------------------------------------------------------------------------*/
+/* Function to report a system error message. */
+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 |
+ FORMAT_MESSAGE_IGNORE_INSERTS, 0, original,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ message, KWSYS_SHARED_FORWARD_MAXPATH, 0);
+ if(length < 1 || length > KWSYS_SHARED_FORWARD_MAXPATH)
+ {
+ /* FormatMessage failed. Use a default message. */
+ _snprintf(message, KWSYS_SHARED_FORWARD_MAXPATH,
+ "Error 0x%X (FormatMessage failed with error 0x%X)",
+ original, GetLastError());
+ }
+#else
+ /* Implementation for UNIX. */
+ strcpy(message, strerror(errno));
+#endif
+}
+
+/*--------------------------------------------------------------------------*/
+/* Functions to execute a child process. */
+static void kwsys_shared_forward_execvp(const char* cmd,
+ char const* const* argv)
+{
+#ifdef KWSYS_SHARED_FORWARD_ESCAPE_ARGV
+ /* Count the number of arguments. */
+ int argc = 0;
+ {
+ char const* const* argvc;
+ for(argvc = argv; *argvc; ++argvc,++argc) {}
+ }
+
+ /* Create the escaped arguments. */
+ {
+ char** nargv = (char**)malloc((argc+1) * sizeof(char*));
+ int i;
+ for(i=0; i < argc; ++i)
+ {
+ kwsys_sf_arg_info info = kwsys_sf_get_arg_info(argv[i]);
+ nargv[i] = (char*)malloc(info.size);
+ kwsys_sf_get_arg(info, nargv[i]);
+ }
+ nargv[argc] = 0;
+
+ /* Replace the command line to be used. */
+ argv = (char const* const*)nargv;
+ }
+#endif
+
+ /* Invoke the child process. */
+#if defined(_MSC_VER)
+ _execvp(cmd, argv);
+#elif defined(__MINGW32__)
+ execvp(cmd, argv);
+#else
+ execvp(cmd, (char* const*)argv);
+#endif
+}
+
+/*--------------------------------------------------------------------------*/
+/* Function to get the directory containing the given file or directory. */
+static void kwsys_shared_forward_dirname(const char* begin, char* result)
+{
+ /* Find the location of the last slash. */
+ int last_slash_index = -1;
+ const char* end = begin + strlen(begin);
+ for(;begin <= end && last_slash_index < 0; --end)
+ {
+ if(*end == '/' || *end == '\\')
+ {
+ last_slash_index = (int)(end-begin);
+ }
+ }
+
+ /* Handle each case of the index of the last slash. */
+ if(last_slash_index < 0)
+ {
+ /* No slashes. */
+ strcpy(result, ".");
+ }
+ else if(last_slash_index == 0)
+ {
+ /* Only one leading slash. */
+ strcpy(result, kwsys_shared_forward_path_slash);
+ }
+#if defined(_WIN32)
+ else if(last_slash_index == 2 && begin[1] == ':')
+ {
+ /* Only one leading drive letter and slash. */
+ strncpy(result, begin, (size_t)last_slash_index);
+ result[last_slash_index] = KWSYS_SHARED_FORWARD_PATH_SLASH;
+ result[last_slash_index+1] = 0;
+ }
+#endif
+ else
+ {
+ /* A non-leading slash. */
+ strncpy(result, begin, (size_t)last_slash_index);
+ result[last_slash_index] = 0;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+/* Function to check if a file exists and is executable. */
+static int kwsys_shared_forward_is_executable(const char* f)
+{
+#if defined(_MSC_VER)
+# define KWSYS_SHARED_FORWARD_ACCESS _access
+#else
+# define KWSYS_SHARED_FORWARD_ACCESS access
+#endif
+#if defined(X_OK)
+# define KWSYS_SHARED_FORWARD_ACCESS_OK X_OK
+#else
+# define KWSYS_SHARED_FORWARD_ACCESS_OK 04
+#endif
+ if(KWSYS_SHARED_FORWARD_ACCESS(f, KWSYS_SHARED_FORWARD_ACCESS_OK) == 0)
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+/* Function to locate the executable currently running. */
+static int kwsys_shared_forward_self_path(const char* argv0, char* result)
+{
+ /* Check whether argv0 has a slash. */
+ int has_slash = 0;
+ const char* p = argv0;
+ for(;*p && !has_slash; ++p)
+ {
+ if(*p == '/' || *p == '\\')
+ {
+ has_slash = 1;
+ }
+ }
+
+ if(has_slash)
+ {
+ /* There is a slash. Use the dirname of the given location. */
+ kwsys_shared_forward_dirname(argv0, result);
+ return 1;
+ }
+ else
+ {
+ /* There is no slash. Search the PATH for the executable. */
+ const char* path = getenv("PATH");
+ const char* begin = path;
+ const char* end = begin + (begin?strlen(begin):0);
+ const char* first = begin;
+ while(first != end)
+ {
+ /* Store the end of this path entry. */
+ const char* last;
+
+ /* Skip all path separators. */
+ for(;*first && *first == KWSYS_SHARED_FORWARD_PATH_SEP; ++first);
+
+ /* Find the next separator. */
+ for(last = first;*last && *last != KWSYS_SHARED_FORWARD_PATH_SEP; ++last);
+
+ /* If we got a non-empty directory, look for the executable there. */
+ if(first < last)
+ {
+ /* Determine the length without trailing slash. */
+ size_t length = (size_t)(last-first);
+ if(*(last-1) == '/' || *(last-1) == '\\')
+ {
+ --length;
+ }
+
+ /* Construct the name of the executable in this location. */
+ strncpy(result, first, length);
+ result[length] = KWSYS_SHARED_FORWARD_PATH_SLASH;
+ strcpy(result+(length)+1, argv0);
+
+ /* Check if it exists and is executable. */
+ if(kwsys_shared_forward_is_executable(result))
+ {
+ /* Found it. */
+ result[length] = 0;
+ return 1;
+ }
+ }
+
+ /* Move to the next directory in the path. */
+ first = last;
+ }
+ }
+
+ /* We could not find the executable. */
+ return 0;
+}
+
+/*--------------------------------------------------------------------------*/
+/* Function to convert a specified path to a full path. If it is not
+ already full, it is taken relative to the self path. */
+static int kwsys_shared_forward_fullpath(const char* self_path,
+ const char* in_path,
+ char* result,
+ const char* desc)
+{
+ /* Check the specified path type. */
+ if(in_path[0] == '/')
+ {
+ /* Already a full path. */
+ strcpy(result, in_path);
+ }
+#if defined(_WIN32)
+ else if(in_path[0] && in_path[1] == ':')
+ {
+ /* Already a full path. */
+ strcpy(result, in_path);
+ }
+#endif
+ else
+ {
+ /* Relative to self path. */
+ char temp_path[KWSYS_SHARED_FORWARD_MAXPATH];
+ strcpy(temp_path, self_path);
+ strcat(temp_path, kwsys_shared_forward_path_slash);
+ strcat(temp_path, in_path);
+ if(!kwsys_shared_forward_realpath(temp_path, result))
+ {
+ if(desc)
+ {
+ char msgbuf[KWSYS_SHARED_FORWARD_MAXPATH];
+ kwsys_shared_forward_strerror(msgbuf);
+ fprintf(stderr, "Error converting %s \"%s\" to real path: %s\n",
+ desc, temp_path, msgbuf);
+ }
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/*--------------------------------------------------------------------------*/
+/* Function to compute the library search path and executable name
+ based on the self path. */
+static int kwsys_shared_forward_get_settings(const char* self_path,
+ char* ldpath, char* exe)
+{
+ /* Possible search paths. */
+ static const char* search_path_build[] = {KWSYS_SHARED_FORWARD_PATH_BUILD, 0};
+ static const char* search_path_install[] = {KWSYS_SHARED_FORWARD_PATH_INSTALL, 0};
+
+ /* Chosen paths. */
+ const char** search_path;
+ const char* exe_path;
+
+ /* Get the real name of the build and self paths. */
+#if defined(KWSYS_SHARED_FORWARD_CONFIG_NAME)
+ char build_path[] = KWSYS_SHARED_FORWARD_DIR_BUILD "/" KWSYS_SHARED_FORWARD_CONFIG_NAME;
+ char self_path_logical[KWSYS_SHARED_FORWARD_MAXPATH];
+#else
+ char build_path[] = KWSYS_SHARED_FORWARD_DIR_BUILD;
+ const char* self_path_logical = self_path;
+#endif
+ char build_path_real[KWSYS_SHARED_FORWARD_MAXPATH];
+ char self_path_real[KWSYS_SHARED_FORWARD_MAXPATH];
+ if(!kwsys_shared_forward_realpath(self_path, self_path_real))
+ {
+ char msgbuf[KWSYS_SHARED_FORWARD_MAXPATH];
+ kwsys_shared_forward_strerror(msgbuf);
+ fprintf(stderr, "Error converting self path \"%s\" to real path: %s\n",
+ self_path, msgbuf);
+ return 0;
+ }
+
+ /* Check whether we are running in the build tree or an install tree. */
+ if(kwsys_shared_forward_realpath(build_path, build_path_real) &&
+ kwsys_shared_forward_samepath(self_path_real, build_path_real))
+ {
+ /* Running in build tree. Use the build path and exe. */
+ search_path = search_path_build;
+#if defined(_WIN32)
+ exe_path = KWSYS_SHARED_FORWARD_EXE_BUILD ".exe";
+#else
+ exe_path = KWSYS_SHARED_FORWARD_EXE_BUILD;
+#endif
+
+#if defined(KWSYS_SHARED_FORWARD_CONFIG_NAME)
+ /* Remove the configuration directory from self_path. */
+ kwsys_shared_forward_dirname(self_path, self_path_logical);
+#endif
+ }
+ else
+ {
+ /* Running in install tree. Use the install path and exe. */
+ search_path = search_path_install;
+#if defined(_WIN32)
+ exe_path = KWSYS_SHARED_FORWARD_EXE_INSTALL ".exe";
+#else
+ exe_path = KWSYS_SHARED_FORWARD_EXE_INSTALL;
+#endif
+
+#if defined(KWSYS_SHARED_FORWARD_CONFIG_NAME)
+ /* Use the original self path directory. */
+ strcpy(self_path_logical, self_path);
+#endif
+ }
+
+ /* Construct the runtime search path. */
+ {
+ const char** dir;
+ for(dir = search_path; *dir; ++dir)
+ {
+ /* Add seperator between path components. */
+ if(dir != search_path)
+ {
+ strcat(ldpath, kwsys_shared_forward_path_sep);
+ }
+
+ /* Add this path component. */
+ if(!kwsys_shared_forward_fullpath(self_path_logical, *dir,
+ ldpath+strlen(ldpath),
+ "runtime path entry"))
+ {
+ return 0;
+ }
+ }
+ }
+
+ /* Construct the executable location. */
+ if(!kwsys_shared_forward_fullpath(self_path_logical, exe_path, exe,
+ "executable file"))
+ {
+ return 0;
+ }
+ return 1;
+}
+
+/*--------------------------------------------------------------------------*/
+/* Function to print why execution of a command line failed. */
+static void kwsys_shared_forward_print_failure(char const* const* argv)
+{
+ char msg[KWSYS_SHARED_FORWARD_MAXPATH];
+ char const* const* arg = argv;
+ kwsys_shared_forward_strerror(msg);
+ fprintf(stderr, "Error running");
+ for(; *arg; ++arg)
+ {
+ fprintf(stderr, " \"%s\"", *arg);
+ }
+ fprintf(stderr, ": %s\n", msg);
+}
+
+/* Static storage space to store the updated environment variable. */
+static char kwsys_shared_forward_ldpath[KWSYS_SHARED_FORWARD_MAXPATH*16] = KWSYS_SHARED_FORWARD_LDPATH "=";
+
+/*--------------------------------------------------------------------------*/
+/* Main driver function to be called from main. */
+static int @KWSYS_NAMESPACE@_shared_forward_to_real(int argc, char** argv_in)
+{
+ char const** argv = (char const**)argv_in;
+ /* Get the directory containing this executable. */
+ char self_path[KWSYS_SHARED_FORWARD_MAXPATH];
+ if(kwsys_shared_forward_self_path(argv[0], self_path))
+ {
+ /* Found this executable. Use it to get the library directory. */
+ char exe[KWSYS_SHARED_FORWARD_MAXPATH];
+ if(kwsys_shared_forward_get_settings(self_path,
+ kwsys_shared_forward_ldpath, exe))
+ {
+ /* Append the old runtime search path. */
+ const char* old_ldpath = getenv(KWSYS_SHARED_FORWARD_LDPATH);
+ if(old_ldpath)
+ {
+ strcat(kwsys_shared_forward_ldpath, kwsys_shared_forward_path_sep);
+ strcat(kwsys_shared_forward_ldpath, old_ldpath);
+ }
+
+ /* Store the environment variable. */
+ putenv(kwsys_shared_forward_ldpath);
+
+#if defined(KWSYS_SHARED_FORWARD_OPTION_COMMAND)
+ /* Look for the command line replacement option. */
+ if(argc > 1 && strcmp(argv[1], KWSYS_SHARED_FORWARD_OPTION_COMMAND) == 0)
+ {
+ if(argc > 2)
+ {
+ /* Use the command line given. */
+ strcpy(exe, argv[2]);
+ argv += 2;
+ argc -= 2;
+ }
+ else
+ {
+ /* The option was not given an executable. */
+ fprintf(stderr, "Option " KWSYS_SHARED_FORWARD_OPTION_COMMAND
+ " must be followed by a command line.\n");
+ return 1;
+ }
+ }
+#endif
+
+#if defined(KWSYS_SHARED_FORWARD_OPTION_PRINT)
+ /* Look for the print command line option. */
+ if(argc > 1 && strcmp(argv[1], KWSYS_SHARED_FORWARD_OPTION_PRINT) == 0)
+ {
+ fprintf(stdout, "%s\n", kwsys_shared_forward_ldpath);
+ fprintf(stdout, "%s\n", exe);
+ return 0;
+ }
+#endif
+
+#if defined(KWSYS_SHARED_FORWARD_OPTION_LDD)
+ /* Look for the ldd command line option. */
+ if(argc > 1 && strcmp(argv[1], KWSYS_SHARED_FORWARD_OPTION_LDD) == 0)
+ {
+# if defined(KWSYS_SHARED_FORWARD_LDD)
+ /* Use the named ldd-like executable and arguments. */
+ char const* ldd_argv[] = {KWSYS_SHARED_FORWARD_LDD, 0, 0};
+ ldd_argv[KWSYS_SHARED_FORWARD_LDD_N] = exe;
+ kwsys_shared_forward_execvp(ldd_argv[0], ldd_argv);
+
+ /* Report why execution failed. */
+ kwsys_shared_forward_print_failure(ldd_argv);
+ return 1;
+# else
+ /* We have no ldd-like executable available on this platform. */
+ fprintf(stderr, "No ldd-like tool is known to this executable.\n");
+ return 1;
+# endif
+ }
+#endif
+
+ /* Replace this process with the real executable. */
+ argv[0] = exe;
+ kwsys_shared_forward_execvp(argv[0], argv);
+
+ /* Report why execution failed. */
+ kwsys_shared_forward_print_failure(argv);
+ }
+ else
+ {
+ /* Could not convert self path to the library directory. */
+ }
+ }
+ else
+ {
+ /* Could not find this executable. */
+ fprintf(stderr, "Error locating executable \"%s\".\n", argv[0]);
+ }
+
+ /* Avoid unused argument warning. */
+ (void)argc;
+
+ /* Exit with failure. */
+ return 1;
+}
+
+#else
+# error "@KWSYS_NAMESPACE@/SharedForward.h should be included only once."
+#endif
diff --git a/Source/kwsys/String.c b/Source/kwsys/String.c
new file mode 100644
index 000000000..ed4a6c52a
--- /dev/null
+++ b/Source/kwsys/String.c
@@ -0,0 +1,115 @@
+/*============================================================================
+ 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 KWSYS_STRING_C
+/*
+All code in this source file is conditionally compiled to work-around
+template definition auto-search on VMS. Other source files in this
+directory that use the stl string cause the compiler to load this
+source to try to get the definition of the string template. This
+condition blocks the compiler from seeing the symbols defined here.
+*/
+#include "kwsysPrivate.h"
+#include KWSYS_HEADER(String.h)
+
+/* Work-around CMake dependency scanning limitation. This must
+ duplicate the above list of headers. */
+#if 0
+# include "String.h.in"
+#endif
+
+/* Select an implementation for strcasecmp. */
+#if defined(_MSC_VER)
+# define KWSYS_STRING_USE_STRICMP
+# include <string.h>
+#elif defined(__GNUC__)
+# define KWSYS_STRING_USE_STRCASECMP
+# include <strings.h>
+#else
+/* Table to convert upper case letters to lower case and leave all
+ other characters alone. */
+static char kwsysString_strcasecmp_tolower[] =
+{
+ '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
+ '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
+ '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
+ '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
+ '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
+ '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
+ '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
+ '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
+ '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
+ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
+ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
+ '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
+ '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
+ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
+ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
+ '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
+ '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
+ '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
+ '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
+ '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
+ '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
+ '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
+ '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
+ '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
+ '\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
+ '\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
+ '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
+ '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',
+ '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
+ '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
+ '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
+ '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377'
+};
+#endif
+
+/*--------------------------------------------------------------------------*/
+int kwsysString_strcasecmp(const char* lhs, const char* rhs)
+{
+#if defined(KWSYS_STRING_USE_STRICMP)
+ return _stricmp(lhs, rhs);
+#elif defined(KWSYS_STRING_USE_STRCASECMP)
+ return strcasecmp(lhs, rhs);
+#else
+ const char* const lower = kwsysString_strcasecmp_tolower;
+ unsigned char const* us1 = (unsigned char const*)lhs;
+ unsigned char const* us2 = (unsigned char const*)rhs;
+ int result;
+ while((result = lower[*us1] - lower[*us2++], result == 0) && *us1++)
+ {
+ }
+ return result;
+#endif
+}
+
+/*--------------------------------------------------------------------------*/
+int kwsysString_strncasecmp(const char* lhs, const char* rhs, size_t n)
+{
+#if defined(KWSYS_STRING_USE_STRICMP)
+ return _strnicmp(lhs, rhs, n);
+#elif defined(KWSYS_STRING_USE_STRCASECMP)
+ return strncasecmp(lhs, rhs, n);
+#else
+ const char* const lower = kwsysString_strcasecmp_tolower;
+ unsigned char const* us1 = (unsigned char const*)lhs;
+ unsigned char const* us2 = (unsigned char const*)rhs;
+ int result = 0;
+ while(n && (result = lower[*us1] - lower[*us2++], result == 0) && *us1++)
+ {
+ --n;
+ }
+ return result;
+#endif
+}
+
+#endif /* KWSYS_STRING_C */
diff --git a/Source/kwsys/String.h.in b/Source/kwsys/String.h.in
new file mode 100644
index 000000000..f5bab6e1a
--- /dev/null
+++ b/Source/kwsys/String.h.in
@@ -0,0 +1,67 @@
+/*============================================================================
+ 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@_String_h
+#define @KWSYS_NAMESPACE@_String_h
+
+#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
+ 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 kwsysString_strcasecmp kwsys_ns(String_strcasecmp)
+# define kwsysString_strncasecmp kwsys_ns(String_strncasecmp)
+#endif
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+/**
+ * Compare two strings ignoring the case of the characters. The
+ * integer returned is negative, zero, or positive if the first string
+ * is found to be less than, equal to, or greater than the second
+ * string, respectively.
+ */
+kwsysEXPORT int kwsysString_strcasecmp(const char* lhs, const char* rhs);
+
+/**
+ * Identical to String_strcasecmp except that only the first n
+ * characters are considered.
+ */
+kwsysEXPORT int kwsysString_strncasecmp(const char* lhs, const char* rhs,
+ size_t n);
+
+#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 !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
+# undef kwsysString_strcasecmp
+# undef kwsysString_strncasecmp
+# endif
+#endif
+
+#endif
diff --git a/Source/kwsys/String.hxx.in b/Source/kwsys/String.hxx.in
new file mode 100644
index 000000000..4386c9eb7
--- /dev/null
+++ b/Source/kwsys/String.hxx.in
@@ -0,0 +1,65 @@
+/*============================================================================
+ 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@_String_hxx
+#define @KWSYS_NAMESPACE@_String_hxx
+
+#include <@KWSYS_NAMESPACE@/stl/string>
+
+namespace @KWSYS_NAMESPACE@
+{
+
+/** \class String
+ * \brief Short-name version of the STL basic_string class template.
+ *
+ * The standard library "string" type is actually a typedef for
+ * "basic_string<..long argument list..>". This string class is
+ * 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
+{
+ /** The original string type. */
+ typedef @KWSYS_NAMESPACE@_stl::string stl_string;
+
+public:
+
+ /** String member types. */
+ typedef stl_string::value_type value_type;
+ typedef stl_string::pointer pointer;
+ typedef stl_string::reference reference;
+ typedef stl_string::const_reference const_reference;
+ typedef stl_string::size_type size_type;
+ typedef stl_string::difference_type difference_type;
+ typedef stl_string::iterator iterator;
+ typedef stl_string::const_iterator const_iterator;
+ typedef stl_string::reverse_iterator reverse_iterator;
+ typedef stl_string::const_reverse_iterator const_reverse_iterator;
+
+ /** String constructors. */
+ String(): stl_string() {}
+ String(const value_type* s): stl_string(s) {}
+ String(const value_type* s, size_type n): stl_string(s, n) {}
+ String(const stl_string& s, size_type pos=0, size_type n=npos):
+ stl_string(s, pos, n) {}
+}; // End Class: String
+
+#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));
+ }
+#endif
+
+} // namespace @KWSYS_NAMESPACE@
+
+#endif
diff --git a/Source/kwsys/System.c b/Source/kwsys/System.c
new file mode 100644
index 000000000..5d178bfa2
--- /dev/null
+++ b/Source/kwsys/System.c
@@ -0,0 +1,856 @@
+/*============================================================================
+ 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(System.h)
+
+/* Work-around CMake dependency scanning limitation. This must
+ duplicate the above list of headers. */
+#if 0
+# include "System.h.in"
+#endif
+
+#include <stddef.h> /* ptrdiff_t */
+#include <stdlib.h> /* malloc, free */
+#include <string.h> /* strlen */
+#include <ctype.h> /* isalpha */
+
+#include <stdio.h>
+
+#if defined(KWSYS_C_HAS_PTRDIFF_T) && KWSYS_C_HAS_PTRDIFF_T
+typedef ptrdiff_t kwsysSystem_ptrdiff_t;
+#else
+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,
+ int* size, char c)
+{
+ /* Allocate space for the character. */
+ if((*end - *begin) >= *size)
+ {
+ kwsysSystem_ptrdiff_t length = *end - *begin;
+ char* newBuffer = (char*)malloc((size_t)(*size*2));
+ if(!newBuffer)
+ {
+ return 0;
+ }
+ memcpy(newBuffer, *begin, (size_t)(length)*sizeof(char));
+ if(*begin != local)
+ {
+ free(*begin);
+ }
+ *begin = newBuffer;
+ *end = *begin + length;
+ *size *= 2;
+ }
+
+ /* Store the character. */
+ *(*end)++ = c;
+ return 1;
+}
+
+/*--------------------------------------------------------------------------*/
+static int kwsysSystem__AppendArgument(char** local,
+ char*** begin, char*** end,
+ int* size,
+ char* arg_local,
+ char** arg_begin, char** arg_end,
+ int* arg_size)
+{
+ /* Append a null-terminator to the argument string. */
+ if(!kwsysSystem__AppendByte(arg_local, arg_begin, arg_end, arg_size, '\0'))
+ {
+ return 0;
+ }
+
+ /* Allocate space for the argument pointer. */
+ if((*end - *begin) >= *size)
+ {
+ kwsysSystem_ptrdiff_t length = *end - *begin;
+ char** newPointers = (char**)malloc((size_t)(*size)*2*sizeof(char*));
+ if(!newPointers)
+ {
+ return 0;
+ }
+ memcpy(newPointers, *begin, (size_t)(length)*sizeof(char*));
+ if(*begin != local)
+ {
+ free(*begin);
+ }
+ *begin = newPointers;
+ *end = *begin + length;
+ *size *= 2;
+ }
+
+ /* Allocate space for the argument string. */
+ **end = (char*)malloc((size_t)(*arg_end - *arg_begin));
+ if(!**end)
+ {
+ return 0;
+ }
+
+ /* Store the argument in the command array. */
+ memcpy(**end, *arg_begin,(size_t)(*arg_end - *arg_begin));
+ ++(*end);
+
+ /* Reset the argument to be empty. */
+ *arg_end = *arg_begin;
+
+ return 1;
+}
+
+/*--------------------------------------------------------------------------*/
+#define KWSYSPE_LOCAL_BYTE_COUNT 1024
+#define KWSYSPE_LOCAL_ARGS_COUNT 32
+static char** kwsysSystem__ParseUnixCommand(const char* command, int flags)
+{
+ /* Create a buffer for argument pointers during parsing. */
+ char* local_pointers[KWSYSPE_LOCAL_ARGS_COUNT];
+ int pointers_size = KWSYSPE_LOCAL_ARGS_COUNT;
+ char** pointer_begin = local_pointers;
+ char** pointer_end = pointer_begin;
+
+ /* Create a buffer for argument strings during parsing. */
+ char local_buffer[KWSYSPE_LOCAL_BYTE_COUNT];
+ int buffer_size = KWSYSPE_LOCAL_BYTE_COUNT;
+ char* buffer_begin = local_buffer;
+ char* buffer_end = buffer_begin;
+
+ /* Parse the command string. Try to behave like a UNIX shell. */
+ char** newCommand = 0;
+ const char* c = command;
+ int in_argument = 0;
+ int in_escape = 0;
+ int in_single = 0;
+ int in_double = 0;
+ int failed = 0;
+ for(;*c; ++c)
+ {
+ if(in_escape)
+ {
+ /* This character is escaped so do no special handling. */
+ if(!in_argument)
+ {
+ in_argument = 1;
+ }
+ if(!kwsysSystem__AppendByte(local_buffer, &buffer_begin,
+ &buffer_end, &buffer_size, *c))
+ {
+ failed = 1;
+ break;
+ }
+ in_escape = 0;
+ }
+ else if(*c == '\\')
+ {
+ /* The next character should be escaped. */
+ in_escape = 1;
+ }
+ else if(*c == '\'' && !in_double)
+ {
+ /* Enter or exit single-quote state. */
+ if(in_single)
+ {
+ in_single = 0;
+ }
+ else
+ {
+ in_single = 1;
+ if(!in_argument)
+ {
+ in_argument = 1;
+ }
+ }
+ }
+ else if(*c == '"' && !in_single)
+ {
+ /* Enter or exit double-quote state. */
+ if(in_double)
+ {
+ in_double = 0;
+ }
+ else
+ {
+ in_double = 1;
+ if(!in_argument)
+ {
+ in_argument = 1;
+ }
+ }
+ }
+ else if(isspace((unsigned char) *c))
+ {
+ if(in_argument)
+ {
+ if(in_single || in_double)
+ {
+ /* This space belongs to a quoted argument. */
+ if(!kwsysSystem__AppendByte(local_buffer, &buffer_begin,
+ &buffer_end, &buffer_size, *c))
+ {
+ failed = 1;
+ break;
+ }
+ }
+ else
+ {
+ /* This argument has been terminated by whitespace. */
+ if(!kwsysSystem__AppendArgument(local_pointers, &pointer_begin,
+ &pointer_end, &pointers_size,
+ local_buffer, &buffer_begin,
+ &buffer_end, &buffer_size))
+ {
+ failed = 1;
+ break;
+ }
+ in_argument = 0;
+ }
+ }
+ }
+ else
+ {
+ /* This character belong to an argument. */
+ if(!in_argument)
+ {
+ in_argument = 1;
+ }
+ if(!kwsysSystem__AppendByte(local_buffer, &buffer_begin,
+ &buffer_end, &buffer_size, *c))
+ {
+ failed = 1;
+ break;
+ }
+ }
+ }
+
+ /* Finish the last argument. */
+ if(in_argument)
+ {
+ if(!kwsysSystem__AppendArgument(local_pointers, &pointer_begin,
+ &pointer_end, &pointers_size,
+ local_buffer, &buffer_begin,
+ &buffer_end, &buffer_size))
+ {
+ failed = 1;
+ }
+ }
+
+ /* If we still have memory allocate space for the new command
+ buffer. */
+ if(!failed)
+ {
+ kwsysSystem_ptrdiff_t n = pointer_end - pointer_begin;
+ newCommand = (char**)malloc((size_t)(n+1)*sizeof(char*));
+ }
+
+ if(newCommand)
+ {
+ /* Copy the arguments into the new command buffer. */
+ kwsysSystem_ptrdiff_t n = pointer_end - pointer_begin;
+ memcpy(newCommand, pointer_begin, sizeof(char*)*(size_t)(n));
+ newCommand[n] = 0;
+ }
+ else
+ {
+ /* Free arguments already allocated. */
+ while(pointer_end != pointer_begin)
+ {
+ free(*(--pointer_end));
+ }
+ }
+
+ /* Free temporary buffers. */
+ if(pointer_begin != local_pointers)
+ {
+ free(pointer_begin);
+ }
+ if(buffer_begin != local_buffer)
+ {
+ free(buffer_begin);
+ }
+
+ /* The flags argument is currently unused. */
+ (void)flags;
+
+ /* Return the final command buffer. */
+ return newCommand;
+}
+
+/*--------------------------------------------------------------------------*/
+char** kwsysSystem_Parse_CommandForUnix(const char* command, int flags)
+{
+ /* Validate the flags. */
+ if(flags != 0)
+ {
+ return 0;
+ }
+
+ /* Forward to our internal implementation. */
+ return kwsysSystem__ParseUnixCommand(command, flags);
+}
diff --git a/Source/kwsys/System.h.in b/Source/kwsys/System.h.in
new file mode 100644
index 000000000..549db900c
--- /dev/null
+++ b/Source/kwsys/System.h.in
@@ -0,0 +1,162 @@
+/*============================================================================
+ 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@_System_h
+#define @KWSYS_NAMESPACE@_System_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 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)
+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
+ * argument strings. Each string is null-terminated and the last
+ * entry in the array is a NULL pointer (just like argv). It is the
+ * caller's responsibility to free() the strings and the array of
+ * pointers to them.
+ *
+ * On failure, returns NULL. Failure occurs only on invalid flags or
+ * when memory cannot be allocated; never due to content of the input
+ * string. Missing close-quotes are treated as if the necessary
+ * closing quote appears.
+ *
+ * By default single- and double-quoted arguments are supported, and
+ * any character may be escaped by a backslash. The flags argument is
+ * reserved for future use, and must be zero (or the call will fail).
+ */
+kwsysEXPORT char** kwsysSystem_Parse_CommandForUnix(const char* command,
+ int flags);
+
+#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 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
+
+#endif
diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx
new file mode 100644
index 000000000..e1ee873b4
--- /dev/null
+++ b/Source/kwsys/SystemInformation.cxx
@@ -0,0 +1,3675 @@
+/*============================================================================
+ 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 _WIN32
+# include <winsock.h> // WSADATA, include before sys/types.h
+#endif
+
+// TODO:
+// We need an alternative implementation for many functions in this file
+// when USE_ASM_INSTRUCTIONS gets defined as 0.
+//
+// Consider using these on Win32/Win64 for some of them:
+//
+// IsProcessorFeaturePresent
+// http://msdn.microsoft.com/en-us/library/ms724482(VS.85).aspx
+//
+// GetProcessMemoryInfo
+// 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)
+
+// Work-around CMake dependency scanning limitation. This must
+// duplicate the above list of headers.
+#if 0
+# 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"
+#endif
+
+#ifndef WIN32
+# include <sys/utsname.h> // int uname(struct utsname *buf);
+#endif
+
+#ifdef _WIN32
+# include <windows.h>
+#endif
+
+#ifdef __APPLE__
+#include <sys/sysctl.h>
+#include <mach/vm_statistics.h>
+#include <mach/host_info.h>
+#include <mach/mach.h>
+#include <mach/mach_types.h>
+#endif
+
+#ifdef __linux
+# include <sys/types.h>
+# include <unistd.h>
+# include <fcntl.h>
+# include <ctype.h> // int isdigit(int c);
+# include <errno.h> // extern int errno;
+# include <sys/time.h>
+#elif defined( __hpux )
+# include <sys/param.h>
+# include <sys/pstat.h>
+#endif
+
+#ifdef __HAIKU__
+#include <OS.h>
+#endif
+
+#include <memory.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+
+namespace KWSYS_NAMESPACE
+{
+
+// Create longlong
+#if KWSYS_USE_LONG_LONG
+ typedef long long LongLong;
+#elif KWSYS_USE___INT64
+ typedef __int64 LongLong;
+#else
+# error "No Long Long"
+#endif
+
+
+// Define SystemInformationImplementation class
+typedef void (*DELAY_FUNC)(unsigned int uiMS);
+
+
+class SystemInformationImplementation
+{
+public:
+ SystemInformationImplementation ();
+ ~SystemInformationImplementation ();
+
+ const char * GetVendorString();
+ const char * GetVendorID();
+ kwsys_stl::string GetTypeID();
+ kwsys_stl::string GetFamilyID();
+ kwsys_stl::string GetModelID();
+ kwsys_stl::string GetSteppingCode();
+ const char * GetExtendedProcessorName();
+ const char * GetProcessorSerialNumber();
+ int GetProcessorCacheSize();
+ unsigned int GetLogicalProcessorsPerPhysical();
+ float GetProcessorClockFrequency();
+ int GetProcessorAPICID();
+ int GetProcessorCacheXSize(long int);
+ bool DoesCPUSupportFeature(long int);
+
+ const char * GetOSName();
+ const char * GetHostname();
+ const char * GetOSRelease();
+ const char * GetOSVersion();
+ const char * GetOSPlatform();
+
+ bool Is64Bits();
+
+ unsigned int GetNumberOfLogicalCPU(); // per physical cpu
+ unsigned int GetNumberOfPhysicalCPU();
+
+ bool DoesCPUSupportCPUID();
+
+ // Retrieve memory information in megabyte.
+ size_t GetTotalVirtualMemory();
+ size_t GetAvailableVirtualMemory();
+ size_t GetTotalPhysicalMemory();
+ size_t GetAvailablePhysicalMemory();
+
+ /** Run the different checks */
+ void RunCPUCheck();
+ void RunOSCheck();
+ void RunMemoryCheck();
+
+public:
+ typedef struct tagID
+ {
+ int Type;
+ int Family;
+ int Model;
+ int Revision;
+ int ExtendedFamily;
+ int ExtendedModel;
+ kwsys_stl::string ProcessorName;
+ kwsys_stl::string Vendor;
+ kwsys_stl::string SerialNumber;
+ } ID;
+
+ typedef struct tagCPUPowerManagement
+ {
+ bool HasVoltageID;
+ bool HasFrequencyID;
+ bool HasTempSenseDiode;
+ } CPUPowerManagement;
+
+ typedef struct tagCPUExtendedFeatures
+ {
+ bool Has3DNow;
+ bool Has3DNowPlus;
+ bool SupportsMP;
+ bool HasMMXPlus;
+ bool HasSSEMMX;
+ bool SupportsHyperthreading;
+ unsigned int LogicalProcessorsPerPhysical;
+ int APIC_ID;
+ CPUPowerManagement PowerManagement;
+ } CPUExtendedFeatures;
+
+ typedef struct CPUtagFeatures
+ {
+ bool HasFPU;
+ bool HasTSC;
+ bool HasMMX;
+ bool HasSSE;
+ bool HasSSEFP;
+ bool HasSSE2;
+ bool HasIA64;
+ bool HasAPIC;
+ bool HasCMOV;
+ bool HasMTRR;
+ bool HasACPI;
+ bool HasSerial;
+ bool HasThermal;
+ int CPUSpeed;
+ int L1CacheSize;
+ int L2CacheSize;
+ int L3CacheSize;
+ CPUExtendedFeatures ExtendedFeatures;
+ } CPUFeatures;
+
+ enum Manufacturer
+ {
+ AMD, Intel, NSC, UMC, Cyrix, NexGen, IDT, Rise, Transmeta, Sun, IBM,
+ Motorola, UnknownManufacturer
+ };
+
+protected:
+ // Functions.
+ bool RetrieveCPUFeatures();
+ bool RetrieveCPUIdentity();
+ bool RetrieveCPUCacheDetails();
+ bool RetrieveClassicalCPUCacheDetails();
+ bool RetrieveCPUClockSpeed();
+ bool RetrieveClassicalCPUClockSpeed();
+ bool RetrieveCPUExtendedLevelSupport(int);
+ bool RetrieveExtendedCPUFeatures();
+ bool RetrieveProcessorSerialNumber();
+ bool RetrieveCPUPowerManagement();
+ bool RetrieveClassicalCPUIdentity();
+ bool RetrieveExtendedCPUIdentity();
+
+ Manufacturer ChipManufacturer;
+ CPUFeatures Features;
+ ID ChipID;
+ float CPUSpeedInMHz;
+ unsigned int NumberOfLogicalCPU;
+ unsigned int NumberOfPhysicalCPU;
+
+ int CPUCount();
+ unsigned char LogicalCPUPerPhysicalCPU();
+ unsigned char GetAPICId();
+ unsigned int IsHyperThreadingSupported();
+ LongLong GetCyclesDifference(DELAY_FUNC, unsigned int);
+
+ // For Linux and Cygwin, /proc/cpuinfo formats are slightly different
+ int RetreiveInformationFromCpuInfoFile();
+ kwsys_stl::string ExtractValueFromCpuInfoFile(kwsys_stl::string buffer,
+ const char* word, size_t init=0);
+
+ static void Delay (unsigned int);
+ static void DelayOverhead (unsigned int);
+
+ void FindManufacturer();
+
+ // For Mac
+ bool ParseSysCtl();
+ void CallSwVers();
+ void TrimNewline(kwsys_stl::string&);
+ kwsys_stl::string ExtractValueFromSysCtl(const char* word);
+ kwsys_stl::string SysCtlBuffer;
+
+ // For Solaris
+ bool QuerySolarisInfo();
+ kwsys_stl::string ParseValueFromKStat(const char* arguments);
+ kwsys_stl::string RunProcess(kwsys_stl::vector<const char*> args);
+
+ //For Haiku OS
+ bool QueryHaikuInfo();
+
+ //For QNX
+ bool QueryQNXMemory();
+ bool QueryQNXProcessor();
+
+ // Evaluate the memory information.
+ int QueryMemory();
+ size_t TotalVirtualMemory;
+ size_t AvailableVirtualMemory;
+ size_t TotalPhysicalMemory;
+ size_t AvailablePhysicalMemory;
+
+ size_t CurrentPositionInFile;
+
+ // 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;
+};
+
+
+SystemInformation::SystemInformation()
+{
+ this->Implementation = new SystemInformationImplementation;
+}
+
+SystemInformation::~SystemInformation()
+{
+ delete this->Implementation;
+}
+
+const char * SystemInformation::GetVendorString()
+{
+ return this->Implementation->GetVendorString();
+}
+
+const char * SystemInformation::GetVendorID()
+{
+ return this->Implementation->GetVendorID();
+}
+
+kwsys_stl::string SystemInformation::GetTypeID()
+{
+ return this->Implementation->GetTypeID();
+}
+
+kwsys_stl::string SystemInformation::GetFamilyID()
+{
+ return this->Implementation->GetFamilyID();
+}
+
+kwsys_stl::string SystemInformation::GetModelID()
+{
+ return this->Implementation->GetModelID();
+}
+
+kwsys_stl::string SystemInformation::GetSteppingCode()
+{
+ return this->Implementation->GetSteppingCode();
+}
+
+const char * SystemInformation::GetExtendedProcessorName()
+{
+ return this->Implementation->GetExtendedProcessorName();
+}
+
+const char * SystemInformation::GetProcessorSerialNumber()
+{
+ return this->Implementation->GetProcessorSerialNumber();
+}
+
+int SystemInformation::GetProcessorCacheSize()
+{
+ return this->Implementation->GetProcessorCacheSize();
+}
+
+unsigned int SystemInformation::GetLogicalProcessorsPerPhysical()
+{
+ return this->Implementation->GetLogicalProcessorsPerPhysical();
+}
+
+float SystemInformation::GetProcessorClockFrequency()
+{
+ return this->Implementation->GetProcessorClockFrequency();
+}
+
+int SystemInformation::GetProcessorAPICID()
+{
+ return this->Implementation->GetProcessorAPICID();
+}
+
+int SystemInformation::GetProcessorCacheXSize(long int l)
+{
+ return this->Implementation->GetProcessorCacheXSize(l);
+}
+
+bool SystemInformation::DoesCPUSupportFeature(long int i)
+{
+ return this->Implementation->DoesCPUSupportFeature(i);
+}
+
+const char * SystemInformation::GetOSName()
+{
+ return this->Implementation->GetOSName();
+}
+
+const char * SystemInformation::GetHostname()
+{
+ return this->Implementation->GetHostname();
+}
+
+const char * SystemInformation::GetOSRelease()
+{
+ return this->Implementation->GetOSRelease();
+}
+
+const char * SystemInformation::GetOSVersion()
+{
+ return this->Implementation->GetOSVersion();
+}
+
+const char * SystemInformation::GetOSPlatform()
+{
+ return this->Implementation->GetOSPlatform();
+}
+
+bool SystemInformation::Is64Bits()
+{
+ return this->Implementation->Is64Bits();
+}
+
+unsigned int SystemInformation::GetNumberOfLogicalCPU() // per physical cpu
+{
+ return this->Implementation->GetNumberOfLogicalCPU();
+}
+
+unsigned int SystemInformation::GetNumberOfPhysicalCPU()
+{
+ return this->Implementation->GetNumberOfPhysicalCPU();
+}
+
+bool SystemInformation::DoesCPUSupportCPUID()
+{
+ return this->Implementation->DoesCPUSupportCPUID();
+}
+
+// Retrieve memory information in megabyte.
+size_t SystemInformation::GetTotalVirtualMemory()
+{
+ return this->Implementation->GetTotalVirtualMemory();
+}
+
+size_t SystemInformation::GetAvailableVirtualMemory()
+{
+ return this->Implementation->GetAvailableVirtualMemory();
+}
+
+size_t SystemInformation::GetTotalPhysicalMemory()
+{
+ return this->Implementation->GetTotalPhysicalMemory();
+}
+
+size_t SystemInformation::GetAvailablePhysicalMemory()
+{
+ return this->Implementation->GetAvailablePhysicalMemory();
+}
+
+/** Run the different checks */
+void SystemInformation::RunCPUCheck()
+{
+ this->Implementation->RunCPUCheck();
+}
+
+void SystemInformation::RunOSCheck()
+{
+ this->Implementation->RunOSCheck();
+}
+
+void SystemInformation::RunMemoryCheck()
+{
+ this->Implementation->RunMemoryCheck();
+}
+
+
+// --------------------------------------------------------------
+// SystemInformationImplementation starts here
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1300) && !defined(_WIN64)
+#define USE_ASM_INSTRUCTIONS 1
+#else
+#define USE_ASM_INSTRUCTIONS 0
+#endif
+
+#define STORE_TLBCACHE_INFO(x,y) x = (x < y) ? y : x
+#define TLBCACHE_INFO_UNITS (15)
+#define CLASSICAL_CPU_FREQ_LOOP 10000000
+#define RDTSC_INSTRUCTION _asm _emit 0x0f _asm _emit 0x31
+
+#define CPUID_AWARE_COMPILER
+#ifdef CPUID_AWARE_COMPILER
+ #define CPUID_INSTRUCTION cpuid
+#else
+ #define CPUID_INSTRUCTION _asm _emit 0x0f _asm _emit 0xa2
+#endif
+
+#define MMX_FEATURE 0x00000001
+#define MMX_PLUS_FEATURE 0x00000002
+#define SSE_FEATURE 0x00000004
+#define SSE2_FEATURE 0x00000008
+#define AMD_3DNOW_FEATURE 0x00000010
+#define AMD_3DNOW_PLUS_FEATURE 0x00000020
+#define IA64_FEATURE 0x00000040
+#define MP_CAPABLE 0x00000080
+#define HYPERTHREAD_FEATURE 0x00000100
+#define SERIALNUMBER_FEATURE 0x00000200
+#define APIC_FEATURE 0x00000400
+#define SSE_FP_FEATURE 0x00000800
+#define SSE_MMX_FEATURE 0x00001000
+#define CMOV_FEATURE 0x00002000
+#define MTRR_FEATURE 0x00004000
+#define L1CACHE_FEATURE 0x00008000
+#define L2CACHE_FEATURE 0x00010000
+#define L3CACHE_FEATURE 0x00020000
+#define ACPI_FEATURE 0x00040000
+#define THERMALMONITOR_FEATURE 0x00080000
+#define TEMPSENSEDIODE_FEATURE 0x00100000
+#define FREQUENCYID_FEATURE 0x00200000
+#define VOLTAGEID_FREQUENCY 0x00400000
+
+// Status Flag
+#define HT_NOT_CAPABLE 0
+#define HT_ENABLED 1
+#define HT_DISABLED 2
+#define HT_SUPPORTED_NOT_ENABLED 3
+#define HT_CANNOT_DETECT 4
+
+// EDX[28] Bit 28 is set if HT is supported
+#define HT_BIT 0x10000000
+
+// EAX[11:8] Bit 8-11 contains family processor ID.
+#define FAMILY_ID 0x0F00
+#define PENTIUM4_ID 0x0F00
+// EAX[23:20] Bit 20-23 contains extended family processor ID
+#define EXT_FAMILY_ID 0x0F00000
+// EBX[23:16] Bit 16-23 in ebx contains the number of logical
+#define NUM_LOGICAL_BITS 0x00FF0000
+// processors per physical processor when execute cpuid with
+// eax set to 1
+// EBX[31:24] Bits 24-31 (8 bits) return the 8-bit unique
+#define INITIAL_APIC_ID_BITS 0xFF000000
+// initial APIC ID for the processor this code is running on.
+// Default value = 0xff if HT is not supported
+
+
+SystemInformationImplementation::SystemInformationImplementation()
+{
+ this->TotalVirtualMemory = 0;
+ this->AvailableVirtualMemory = 0;
+ this->TotalPhysicalMemory = 0;
+ this->AvailablePhysicalMemory = 0;
+ this->CurrentPositionInFile = 0;
+ this->ChipManufacturer = UnknownManufacturer;
+ memset(&this->Features, 0, sizeof(CPUFeatures));
+ this->ChipID.Type = 0;
+ this->ChipID.Family = 0;
+ this->ChipID.Model = 0;
+ this->ChipID.Revision = 0;
+ this->ChipID.ExtendedFamily = 0;
+ this->ChipID.ExtendedModel = 0;
+ this->CPUSpeedInMHz = 0;
+ this->NumberOfLogicalCPU = 0;
+ this->NumberOfPhysicalCPU = 0;
+ this->OSName = "";
+ this->Hostname = "";
+ this->OSRelease = "";
+ this->OSVersion = "";
+ this->OSPlatform = "";
+}
+
+SystemInformationImplementation::~SystemInformationImplementation()
+{
+}
+
+void SystemInformationImplementation::RunCPUCheck()
+{
+#ifdef WIN32
+ // Check to see if this processor supports CPUID.
+ bool supportsCPUID = DoesCPUSupportCPUID();
+
+ if (supportsCPUID)
+ {
+ // Retrieve the CPU details.
+ RetrieveCPUIdentity();
+ RetrieveCPUFeatures();
+ }
+
+ // These two may be called without support for the CPUID instruction.
+ // (But if the instruction is there, they should be called *after*
+ // the above call to RetrieveCPUIdentity... that's why the two if
+ // blocks exist with the same "if (supportsCPUID)" logic...
+ //
+ if (!RetrieveCPUClockSpeed())
+ {
+ RetrieveClassicalCPUClockSpeed();
+ }
+
+ if (supportsCPUID)
+ {
+ // Retrieve cache information.
+ if (!RetrieveCPUCacheDetails())
+ {
+ RetrieveClassicalCPUCacheDetails();
+ }
+
+ // Retrieve the extended CPU details.
+ if (!RetrieveExtendedCPUIdentity())
+ {
+ RetrieveClassicalCPUIdentity();
+ }
+
+ RetrieveExtendedCPUFeatures();
+ RetrieveCPUPowerManagement();
+
+ // Now attempt to retrieve the serial number (if possible).
+ RetrieveProcessorSerialNumber();
+ }
+
+ this->CPUCount();
+
+#elif defined(__APPLE__)
+ this->ParseSysCtl();
+#elif defined (__SVR4) && defined (__sun)
+ this->QuerySolarisInfo();
+#elif defined(__HAIKU__)
+ this->QueryHaikuInfo();
+#elif defined(__QNX__)
+ this->QueryQNXProcessor();
+#else
+ this->RetreiveInformationFromCpuInfoFile();
+#endif
+}
+
+void SystemInformationImplementation::RunOSCheck()
+{
+ this->QueryOSInformation();
+}
+
+void SystemInformationImplementation::RunMemoryCheck()
+{
+#if defined(__APPLE__)
+ this->ParseSysCtl();
+#elif defined (__SVR4) && defined (__sun)
+ this->QuerySolarisInfo();
+#elif defined(__HAIKU__)
+ this->QueryHaikuInfo();
+#elif defined(__QNX__)
+ this->QueryQNXMemory();
+#else
+ this->QueryMemory();
+#endif
+}
+
+/** Get the vendor string */
+const char * SystemInformationImplementation::GetVendorString()
+{
+ return this->ChipID.Vendor.c_str();
+}
+
+/** Get the OS Name */
+const char * SystemInformationImplementation::GetOSName()
+{
+ return this->OSName.c_str();
+}
+
+/** Get the hostname */
+const char* SystemInformationImplementation::GetHostname()
+{
+ return this->Hostname.c_str();
+}
+
+/** Get the OS release */
+const char* SystemInformationImplementation::GetOSRelease()
+{
+ return this->OSRelease.c_str();
+}
+
+/** Get the OS version */
+const char* SystemInformationImplementation::GetOSVersion()
+{
+ return this->OSVersion.c_str();
+}
+
+/** Get the OS platform */
+const char* SystemInformationImplementation::GetOSPlatform()
+{
+ return this->OSPlatform.c_str();
+}
+
+/** Get the vendor ID */
+const char * SystemInformationImplementation::GetVendorID()
+{
+ // Return the vendor ID.
+ switch (this->ChipManufacturer)
+ {
+ case Intel:
+ return "Intel Corporation";
+ case AMD:
+ return "Advanced Micro Devices";
+ case NSC:
+ return "National Semiconductor";
+ case Cyrix:
+ return "Cyrix Corp., VIA Inc.";
+ case NexGen:
+ return "NexGen Inc., Advanced Micro Devices";
+ case IDT:
+ return "IDT\\Centaur, Via Inc.";
+ case UMC:
+ return "United Microelectronics Corp.";
+ case Rise:
+ return "Rise";
+ case Transmeta:
+ return "Transmeta";
+ case Sun:
+ return "Sun Microelectronics";
+ case IBM:
+ return "IBM";
+ case Motorola:
+ return "Motorola";
+ default:
+ return "Unknown Manufacturer";
+ }
+}
+
+/** Return the type ID of the CPU */
+kwsys_stl::string SystemInformationImplementation::GetTypeID()
+{
+ kwsys_ios::ostringstream str;
+ str << this->ChipID.Type;
+ return str.str();
+}
+
+/** Return the family of the CPU present */
+kwsys_stl::string SystemInformationImplementation::GetFamilyID()
+{
+ kwsys_ios::ostringstream str;
+ str << this->ChipID.Family;
+ return str.str();
+}
+
+// Return the model of CPU present */
+kwsys_stl::string SystemInformationImplementation::GetModelID()
+{
+ kwsys_ios::ostringstream str;
+ str << this->ChipID.Model;
+ return str.str();
+}
+
+/** Return the stepping code of the CPU present. */
+kwsys_stl::string SystemInformationImplementation::GetSteppingCode()
+{
+ kwsys_ios::ostringstream str;
+ str << this->ChipID.Revision;
+ return str.str();
+}
+
+/** Return the stepping code of the CPU present. */
+const char * SystemInformationImplementation::GetExtendedProcessorName()
+{
+ return this->ChipID.ProcessorName.c_str();
+}
+
+/** Return the serial number of the processor
+ * in hexadecimal: xxxx-xxxx-xxxx-xxxx-xxxx-xxxx. */
+const char * SystemInformationImplementation::GetProcessorSerialNumber()
+{
+ return this->ChipID.SerialNumber.c_str();
+}
+
+/** Return the logical processors per physical */
+unsigned int SystemInformationImplementation::GetLogicalProcessorsPerPhysical()
+{
+ return this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical;
+}
+
+/** Return the processor clock frequency. */
+float SystemInformationImplementation::GetProcessorClockFrequency()
+{
+ return this->CPUSpeedInMHz;
+}
+
+/** Return the APIC ID. */
+int SystemInformationImplementation::GetProcessorAPICID()
+{
+ return this->Features.ExtendedFeatures.APIC_ID;
+}
+
+/** Return the L1 cache size. */
+int SystemInformationImplementation::GetProcessorCacheSize()
+{
+ return this->Features.L1CacheSize;
+}
+
+/** Return the chosen cache size. */
+int SystemInformationImplementation::GetProcessorCacheXSize(long int dwCacheID)
+{
+ switch (dwCacheID)
+ {
+ case L1CACHE_FEATURE:
+ return this->Features.L1CacheSize;
+ case L2CACHE_FEATURE:
+ return this->Features.L2CacheSize;
+ case L3CACHE_FEATURE:
+ return this->Features.L3CacheSize;
+ }
+ return -1;
+}
+
+
+bool SystemInformationImplementation::DoesCPUSupportFeature(long int dwFeature)
+{
+ bool bHasFeature = false;
+
+ // Check for MMX instructions.
+ if (((dwFeature & MMX_FEATURE) != 0) && this->Features.HasMMX) bHasFeature = true;
+
+ // Check for MMX+ instructions.
+ if (((dwFeature & MMX_PLUS_FEATURE) != 0) && this->Features.ExtendedFeatures.HasMMXPlus) bHasFeature = true;
+
+ // Check for SSE FP instructions.
+ if (((dwFeature & SSE_FEATURE) != 0) && this->Features.HasSSE) bHasFeature = true;
+
+ // Check for SSE FP instructions.
+ if (((dwFeature & SSE_FP_FEATURE) != 0) && this->Features.HasSSEFP) bHasFeature = true;
+
+ // Check for SSE MMX instructions.
+ if (((dwFeature & SSE_MMX_FEATURE) != 0) && this->Features.ExtendedFeatures.HasSSEMMX) bHasFeature = true;
+
+ // Check for SSE2 instructions.
+ if (((dwFeature & SSE2_FEATURE) != 0) && this->Features.HasSSE2) bHasFeature = true;
+
+ // Check for 3DNow! instructions.
+ if (((dwFeature & AMD_3DNOW_FEATURE) != 0) && this->Features.ExtendedFeatures.Has3DNow) bHasFeature = true;
+
+ // Check for 3DNow+ instructions.
+ if (((dwFeature & AMD_3DNOW_PLUS_FEATURE) != 0) && this->Features.ExtendedFeatures.Has3DNowPlus) bHasFeature = true;
+
+ // Check for IA64 instructions.
+ if (((dwFeature & IA64_FEATURE) != 0) && this->Features.HasIA64) bHasFeature = true;
+
+ // Check for MP capable.
+ if (((dwFeature & MP_CAPABLE) != 0) && this->Features.ExtendedFeatures.SupportsMP) bHasFeature = true;
+
+ // Check for a serial number for the processor.
+ if (((dwFeature & SERIALNUMBER_FEATURE) != 0) && this->Features.HasSerial) bHasFeature = true;
+
+ // Check for a local APIC in the processor.
+ if (((dwFeature & APIC_FEATURE) != 0) && this->Features.HasAPIC) bHasFeature = true;
+
+ // Check for CMOV instructions.
+ if (((dwFeature & CMOV_FEATURE) != 0) && this->Features.HasCMOV) bHasFeature = true;
+
+ // Check for MTRR instructions.
+ if (((dwFeature & MTRR_FEATURE) != 0) && this->Features.HasMTRR) bHasFeature = true;
+
+ // Check for L1 cache size.
+ if (((dwFeature & L1CACHE_FEATURE) != 0) && (this->Features.L1CacheSize != -1)) bHasFeature = true;
+
+ // Check for L2 cache size.
+ if (((dwFeature & L2CACHE_FEATURE) != 0) && (this->Features.L2CacheSize != -1)) bHasFeature = true;
+
+ // Check for L3 cache size.
+ if (((dwFeature & L3CACHE_FEATURE) != 0) && (this->Features.L3CacheSize != -1)) bHasFeature = true;
+
+ // Check for ACPI capability.
+ if (((dwFeature & ACPI_FEATURE) != 0) && this->Features.HasACPI) bHasFeature = true;
+
+ // Check for thermal monitor support.
+ if (((dwFeature & THERMALMONITOR_FEATURE) != 0) && this->Features.HasThermal) bHasFeature = true;
+
+ // Check for temperature sensing diode support.
+ if (((dwFeature & TEMPSENSEDIODE_FEATURE) != 0) && this->Features.ExtendedFeatures.PowerManagement.HasTempSenseDiode) bHasFeature = true;
+
+ // Check for frequency ID support.
+ if (((dwFeature & FREQUENCYID_FEATURE) != 0) && this->Features.ExtendedFeatures.PowerManagement.HasFrequencyID) bHasFeature = true;
+
+ // Check for voltage ID support.
+ if (((dwFeature & VOLTAGEID_FREQUENCY) != 0) && this->Features.ExtendedFeatures.PowerManagement.HasVoltageID) bHasFeature = true;
+
+ return bHasFeature;
+}
+
+
+void SystemInformationImplementation::Delay(unsigned int uiMS)
+{
+#ifdef WIN32
+ LARGE_INTEGER Frequency, StartCounter, EndCounter;
+ __int64 x;
+
+ // Get the frequency of the high performance counter.
+ if (!QueryPerformanceFrequency (&Frequency)) return;
+ x = Frequency.QuadPart / 1000 * uiMS;
+
+ // Get the starting position of the counter.
+ QueryPerformanceCounter (&StartCounter);
+
+ do {
+ // Get the ending position of the counter.
+ QueryPerformanceCounter (&EndCounter);
+ } while (EndCounter.QuadPart - StartCounter.QuadPart < x);
+#endif
+ (void)uiMS;
+}
+
+
+bool SystemInformationImplementation::DoesCPUSupportCPUID()
+{
+#if USE_ASM_INSTRUCTIONS
+ // Use SEH to determine CPUID presence
+ __try {
+ _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
+ ; these registers to change.
+ push eax
+ push ebx
+ push ecx
+ push edx
+#endif
+ ; <<CPUID>>
+ mov eax, 0
+ CPUID_INSTRUCTION
+
+#ifdef CPUID_AWARE_COMPILER
+ pop edx
+ pop ecx
+ pop ebx
+ pop eax
+#endif
+ }
+ }
+ __except(1)
+ {
+ // Stop the class from trying to use CPUID again!
+ return false;
+ }
+
+ // The cpuid instruction succeeded.
+ return true;
+
+#else
+ // Assume no cpuid instruction.
+ return false;
+#endif
+}
+
+
+bool SystemInformationImplementation::RetrieveCPUFeatures()
+{
+#if USE_ASM_INSTRUCTIONS
+ int localCPUFeatures = 0;
+ int localCPUAdvanced = 0;
+
+ // Use assembly to detect CPUID information...
+ __try {
+ _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
+ ; these registers to change.
+ push eax
+ push ebx
+ push ecx
+ push edx
+#endif
+ ; <<CPUID>>
+ ; eax = 1 --> eax: CPU ID - bits 31..16 - unused, bits 15..12 - type, bits 11..8 - family, bits 7..4 - model, bits 3..0 - mask revision
+ ; ebx: 31..24 - default APIC ID, 23..16 - logical processsor ID, 15..8 - CFLUSH chunk size , 7..0 - brand ID
+ ; edx: CPU feature flags
+ mov eax,1
+ CPUID_INSTRUCTION
+ mov localCPUFeatures, edx
+ mov localCPUAdvanced, ebx
+
+#ifdef CPUID_AWARE_COMPILER
+ pop edx
+ pop ecx
+ pop ebx
+ pop eax
+#endif
+ }
+ }
+ __except(1)
+ {
+ return false;
+ }
+
+ // Retrieve the features of CPU present.
+ this->Features.HasFPU = ((localCPUFeatures & 0x00000001) != 0); // FPU Present --> Bit 0
+ this->Features.HasTSC = ((localCPUFeatures & 0x00000010) != 0); // TSC Present --> Bit 4
+ this->Features.HasAPIC = ((localCPUFeatures & 0x00000200) != 0); // APIC Present --> Bit 9
+ this->Features.HasMTRR = ((localCPUFeatures & 0x00001000) != 0); // MTRR Present --> Bit 12
+ this->Features.HasCMOV = ((localCPUFeatures & 0x00008000) != 0); // CMOV Present --> Bit 15
+ this->Features.HasSerial = ((localCPUFeatures & 0x00040000) != 0); // Serial Present --> Bit 18
+ this->Features.HasACPI = ((localCPUFeatures & 0x00400000) != 0); // ACPI Capable --> Bit 22
+ this->Features.HasMMX = ((localCPUFeatures & 0x00800000) != 0); // MMX Present --> Bit 23
+ this->Features.HasSSE = ((localCPUFeatures & 0x02000000) != 0); // SSE Present --> Bit 25
+ this->Features.HasSSE2 = ((localCPUFeatures & 0x04000000) != 0); // SSE2 Present --> Bit 26
+ this->Features.HasThermal = ((localCPUFeatures & 0x20000000) != 0); // Thermal Monitor Present --> Bit 29
+ this->Features.HasIA64 = ((localCPUFeatures & 0x40000000) != 0); // IA64 Present --> Bit 30
+
+ // Retrieve extended SSE capabilities if SSE is available.
+ if (this->Features.HasSSE) {
+
+ // Attempt to __try some SSE FP instructions.
+ __try
+ {
+ // Perform: orps xmm0, xmm0
+ _asm
+ {
+ _emit 0x0f
+ _emit 0x56
+ _emit 0xc0
+ }
+
+ // SSE FP capable processor.
+ this->Features.HasSSEFP = true;
+ }
+ __except(1)
+ {
+ // bad instruction - processor or OS cannot handle SSE FP.
+ this->Features.HasSSEFP = false;
+ }
+ }
+ else
+ {
+ // Set the advanced SSE capabilities to not available.
+ this->Features.HasSSEFP = false;
+ }
+
+ // Retrieve Intel specific extended features.
+ if (this->ChipManufacturer == Intel)
+ {
+ this->Features.ExtendedFeatures.SupportsHyperthreading = ((localCPUFeatures & 0x10000000) != 0); // Intel specific: Hyperthreading --> Bit 28
+ this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical = (this->Features.ExtendedFeatures.SupportsHyperthreading) ? ((localCPUAdvanced & 0x00FF0000) >> 16) : 1;
+
+ if ((this->Features.ExtendedFeatures.SupportsHyperthreading) && (this->Features.HasAPIC))
+ {
+ // Retrieve APIC information if there is one present.
+ this->Features.ExtendedFeatures.APIC_ID = ((localCPUAdvanced & 0xFF000000) >> 24);
+ }
+ }
+
+ return true;
+
+#else
+ return false;
+#endif
+}
+
+
+/** Find the manufacturer given the vendor id */
+void SystemInformationImplementation::FindManufacturer()
+{
+ if (this->ChipID.Vendor == "GenuineIntel") this->ChipManufacturer = Intel; // Intel Corp.
+ else if (this->ChipID.Vendor == "UMC UMC UMC ") this->ChipManufacturer = UMC; // United Microelectronics Corp.
+ else if (this->ChipID.Vendor == "AuthenticAMD") this->ChipManufacturer = AMD; // Advanced Micro Devices
+ else if (this->ChipID.Vendor == "AMD ISBETTER") this->ChipManufacturer = AMD; // Advanced Micro Devices (1994)
+ else if (this->ChipID.Vendor == "CyrixInstead") this->ChipManufacturer = Cyrix; // Cyrix Corp., VIA Inc.
+ else if (this->ChipID.Vendor == "NexGenDriven") this->ChipManufacturer = NexGen; // NexGen Inc. (now AMD)
+ else if (this->ChipID.Vendor == "CentaurHauls") this->ChipManufacturer = IDT; // IDT/Centaur (now VIA)
+ else if (this->ChipID.Vendor == "RiseRiseRise") this->ChipManufacturer = Rise; // Rise
+ else if (this->ChipID.Vendor == "GenuineTMx86") this->ChipManufacturer = Transmeta; // Transmeta
+ else if (this->ChipID.Vendor == "TransmetaCPU") this->ChipManufacturer = Transmeta; // Transmeta
+ else if (this->ChipID.Vendor == "Geode By NSC") this->ChipManufacturer = NSC; // National Semiconductor
+ else if (this->ChipID.Vendor == "Sun") this->ChipManufacturer = Sun; // Sun Microelectronics
+ else if (this->ChipID.Vendor == "IBM") this->ChipManufacturer = IBM; // IBM Microelectronics
+ else if (this->ChipID.Vendor == "Motorola") this->ChipManufacturer = Motorola; // Motorola Microelectronics
+ else this->ChipManufacturer = UnknownManufacturer; // Unknown manufacturer
+}
+
+
+/** */
+bool SystemInformationImplementation::RetrieveCPUIdentity()
+{
+#if USE_ASM_INSTRUCTIONS
+ int localCPUVendor[3];
+ int localCPUSignature;
+
+ // Use assembly to detect CPUID information...
+ __try
+ {
+ _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
+ ; these registers to change.
+ push eax
+ push ebx
+ push ecx
+ push edx
+#endif
+ ; <<CPUID>>
+ ; eax = 0 --> eax: maximum value of CPUID instruction.
+ ; ebx: part 1 of 3; CPU signature.
+ ; edx: part 2 of 3; CPU signature.
+ ; ecx: part 3 of 3; CPU signature.
+ mov eax, 0
+ CPUID_INSTRUCTION
+ mov localCPUVendor[0 * TYPE int], ebx
+ mov localCPUVendor[1 * TYPE int], edx
+ mov localCPUVendor[2 * TYPE int], ecx
+
+ ; <<CPUID>>
+ ; eax = 1 --> eax: CPU ID - bits 31..16 - unused, bits 15..12 - type, bits 11..8 - family, bits 7..4 - model, bits 3..0 - mask revision
+ ; ebx: 31..24 - default APIC ID, 23..16 - logical processsor ID, 15..8 - CFLUSH chunk size , 7..0 - brand ID
+ ; edx: CPU feature flags
+ mov eax,1
+ CPUID_INSTRUCTION
+ mov localCPUSignature, eax
+
+#ifdef CPUID_AWARE_COMPILER
+ pop edx
+ pop ecx
+ pop ebx
+ pop eax
+#endif
+ }
+ }
+ __except(1)
+ {
+ return false;
+ }
+
+ // Process the returned information.
+ char vbuf[13];
+ memcpy (&(vbuf[0]), &(localCPUVendor[0]), sizeof (int));
+ memcpy (&(vbuf[4]), &(localCPUVendor[1]), sizeof (int));
+ memcpy (&(vbuf[8]), &(localCPUVendor[2]), sizeof (int));
+ vbuf[12] = '\0';
+ this->ChipID.Vendor = vbuf;
+
+ this->FindManufacturer();
+
+ // Retrieve the family of CPU present.
+ this->ChipID.ExtendedFamily = ((localCPUSignature & 0x0FF00000) >> 20); // Bits 27..20 Used
+ this->ChipID.ExtendedModel = ((localCPUSignature & 0x000F0000) >> 16); // Bits 19..16 Used
+ this->ChipID.Type = ((localCPUSignature & 0x0000F000) >> 12); // Bits 15..12 Used
+ this->ChipID.Family = ((localCPUSignature & 0x00000F00) >> 8); // Bits 11..8 Used
+ this->ChipID.Model = ((localCPUSignature & 0x000000F0) >> 4); // Bits 7..4 Used
+ this->ChipID.Revision = ((localCPUSignature & 0x0000000F) >> 0); // Bits 3..0 Used
+
+ return true;
+
+#else
+ return false;
+#endif
+}
+
+
+/** */
+bool SystemInformationImplementation::RetrieveCPUCacheDetails()
+{
+#if USE_ASM_INSTRUCTIONS
+ int L1Cache[4] = { 0, 0, 0, 0 };
+ int L2Cache[4] = { 0, 0, 0, 0 };
+
+ // Check to see if what we are about to do is supported...
+ if (RetrieveCPUExtendedLevelSupport (0x80000005))
+ {
+ // Use assembly to retrieve the L1 cache information ...
+ __try
+ {
+ _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
+ ; these registers to change.
+ push eax
+ push ebx
+ push ecx
+ push edx
+#endif
+ ; <<CPUID>>
+ ; eax = 0x80000005 --> eax: L1 cache information - Part 1 of 4.
+ ; ebx: L1 cache information - Part 2 of 4.
+ ; edx: L1 cache information - Part 3 of 4.
+ ; ecx: L1 cache information - Part 4 of 4.
+ mov eax, 0x80000005
+ CPUID_INSTRUCTION
+ mov L1Cache[0 * TYPE int], eax
+ mov L1Cache[1 * TYPE int], ebx
+ mov L1Cache[2 * TYPE int], ecx
+ mov L1Cache[3 * TYPE int], edx
+
+#ifdef CPUID_AWARE_COMPILER
+ pop edx
+ pop ecx
+ pop ebx
+ pop eax
+#endif
+ }
+ }
+ __except(1)
+ {
+ return false;
+ }
+ // Save the L1 data cache size (in KB) from ecx: bits 31..24 as well as data cache size from edx: bits 31..24.
+ this->Features.L1CacheSize = ((L1Cache[2] & 0xFF000000) >> 24);
+ this->Features.L1CacheSize += ((L1Cache[3] & 0xFF000000) >> 24);
+ }
+ else
+ {
+ // Store -1 to indicate the cache could not be queried.
+ this->Features.L1CacheSize = -1;
+ }
+
+ // Check to see if what we are about to do is supported...
+ if (RetrieveCPUExtendedLevelSupport (0x80000006))
+ {
+ // Use assembly to retrieve the L2 cache information ...
+ __try
+ {
+ _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
+ ; these registers to change.
+ push eax
+ push ebx
+ push ecx
+ push edx
+#endif
+ ; <<CPUID>>
+ ; eax = 0x80000006 --> eax: L2 cache information - Part 1 of 4.
+ ; ebx: L2 cache information - Part 2 of 4.
+ ; edx: L2 cache information - Part 3 of 4.
+ ; ecx: L2 cache information - Part 4 of 4.
+ mov eax, 0x80000006
+ CPUID_INSTRUCTION
+ mov L2Cache[0 * TYPE int], eax
+ mov L2Cache[1 * TYPE int], ebx
+ mov L2Cache[2 * TYPE int], ecx
+ mov L2Cache[3 * TYPE int], edx
+
+#ifdef CPUID_AWARE_COMPILER
+ pop edx
+ pop ecx
+ pop ebx
+ pop eax
+#endif
+ }
+ }
+ __except(1)
+ {
+ return false;
+ }
+ // Save the L2 unified cache size (in KB) from ecx: bits 31..16.
+ this->Features.L2CacheSize = ((L2Cache[2] & 0xFFFF0000) >> 16);
+ }
+ else
+ {
+ // Store -1 to indicate the cache could not be queried.
+ this->Features.L2CacheSize = -1;
+ }
+
+ // Define L3 as being not present as we cannot test for it.
+ this->Features.L3CacheSize = -1;
+
+#endif
+
+ // Return failure if we cannot detect either cache with this method.
+ return ((this->Features.L1CacheSize == -1) && (this->Features.L2CacheSize == -1)) ? false : true;
+}
+
+
+/** */
+bool SystemInformationImplementation::RetrieveClassicalCPUCacheDetails()
+{
+#if USE_ASM_INSTRUCTIONS
+ int TLBCode = -1, TLBData = -1, L1Code = -1, L1Data = -1, L1Trace = -1, L2Unified = -1, L3Unified = -1;
+ int TLBCacheData[4] = { 0, 0, 0, 0 };
+ int TLBPassCounter = 0;
+ int TLBCacheUnit = 0;
+
+
+ do {
+ // Use assembly to retrieve the L2 cache information ...
+ __try {
+ _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
+ ; these registers to change.
+ push eax
+ push ebx
+ push ecx
+ push edx
+#endif
+ ; <<CPUID>>
+ ; eax = 2 --> eax: TLB and cache information - Part 1 of 4.
+ ; ebx: TLB and cache information - Part 2 of 4.
+ ; ecx: TLB and cache information - Part 3 of 4.
+ ; edx: TLB and cache information - Part 4 of 4.
+ mov eax, 2
+ CPUID_INSTRUCTION
+ mov TLBCacheData[0 * TYPE int], eax
+ mov TLBCacheData[1 * TYPE int], ebx
+ mov TLBCacheData[2 * TYPE int], ecx
+ mov TLBCacheData[3 * TYPE int], edx
+
+#ifdef CPUID_AWARE_COMPILER
+ pop edx
+ pop ecx
+ pop ebx
+ pop eax
+#endif
+ }
+ }
+ __except(1)
+ {
+ return false;
+ }
+
+ int bob = ((TLBCacheData[0] & 0x00FF0000) >> 16);
+ (void)bob;
+ // Process the returned TLB and cache information.
+ for (int nCounter = 0; nCounter < TLBCACHE_INFO_UNITS; nCounter ++)
+ {
+ // First of all - decide which unit we are dealing with.
+ switch (nCounter)
+ {
+ // eax: bits 8..15 : bits 16..23 : bits 24..31
+ case 0: TLBCacheUnit = ((TLBCacheData[0] & 0x0000FF00) >> 8); break;
+ case 1: TLBCacheUnit = ((TLBCacheData[0] & 0x00FF0000) >> 16); break;
+ case 2: TLBCacheUnit = ((TLBCacheData[0] & 0xFF000000) >> 24); break;
+
+ // ebx: bits 0..7 : bits 8..15 : bits 16..23 : bits 24..31
+ case 3: TLBCacheUnit = ((TLBCacheData[1] & 0x000000FF) >> 0); break;
+ case 4: TLBCacheUnit = ((TLBCacheData[1] & 0x0000FF00) >> 8); break;
+ case 5: TLBCacheUnit = ((TLBCacheData[1] & 0x00FF0000) >> 16); break;
+ case 6: TLBCacheUnit = ((TLBCacheData[1] & 0xFF000000) >> 24); break;
+
+ // ecx: bits 0..7 : bits 8..15 : bits 16..23 : bits 24..31
+ case 7: TLBCacheUnit = ((TLBCacheData[2] & 0x000000FF) >> 0); break;
+ case 8: TLBCacheUnit = ((TLBCacheData[2] & 0x0000FF00) >> 8); break;
+ case 9: TLBCacheUnit = ((TLBCacheData[2] & 0x00FF0000) >> 16); break;
+ case 10: TLBCacheUnit = ((TLBCacheData[2] & 0xFF000000) >> 24); break;
+
+ // edx: bits 0..7 : bits 8..15 : bits 16..23 : bits 24..31
+ case 11: TLBCacheUnit = ((TLBCacheData[3] & 0x000000FF) >> 0); break;
+ case 12: TLBCacheUnit = ((TLBCacheData[3] & 0x0000FF00) >> 8); break;
+ case 13: TLBCacheUnit = ((TLBCacheData[3] & 0x00FF0000) >> 16); break;
+ case 14: TLBCacheUnit = ((TLBCacheData[3] & 0xFF000000) >> 24); break;
+
+ // Default case - an error has occured.
+ default: return false;
+ }
+
+ // Now process the resulting unit to see what it means....
+ switch (TLBCacheUnit)
+ {
+ case 0x00: break;
+ case 0x01: STORE_TLBCACHE_INFO (TLBCode, 4); break;
+ case 0x02: STORE_TLBCACHE_INFO (TLBCode, 4096); break;
+ case 0x03: STORE_TLBCACHE_INFO (TLBData, 4); break;
+ case 0x04: STORE_TLBCACHE_INFO (TLBData, 4096); break;
+ case 0x06: STORE_TLBCACHE_INFO (L1Code, 8); break;
+ case 0x08: STORE_TLBCACHE_INFO (L1Code, 16); break;
+ case 0x0a: STORE_TLBCACHE_INFO (L1Data, 8); break;
+ case 0x0c: STORE_TLBCACHE_INFO (L1Data, 16); break;
+ case 0x10: STORE_TLBCACHE_INFO (L1Data, 16); break; // <-- FIXME: IA-64 Only
+ case 0x15: STORE_TLBCACHE_INFO (L1Code, 16); break; // <-- FIXME: IA-64 Only
+ case 0x1a: STORE_TLBCACHE_INFO (L2Unified, 96); break; // <-- FIXME: IA-64 Only
+ case 0x22: STORE_TLBCACHE_INFO (L3Unified, 512); break;
+ case 0x23: STORE_TLBCACHE_INFO (L3Unified, 1024); break;
+ case 0x25: STORE_TLBCACHE_INFO (L3Unified, 2048); break;
+ case 0x29: STORE_TLBCACHE_INFO (L3Unified, 4096); break;
+ case 0x39: STORE_TLBCACHE_INFO (L2Unified, 128); break;
+ case 0x3c: STORE_TLBCACHE_INFO (L2Unified, 256); break;
+ case 0x40: STORE_TLBCACHE_INFO (L2Unified, 0); break; // <-- FIXME: No integrated L2 cache (P6 core) or L3 cache (P4 core).
+ case 0x41: STORE_TLBCACHE_INFO (L2Unified, 128); break;
+ case 0x42: STORE_TLBCACHE_INFO (L2Unified, 256); break;
+ case 0x43: STORE_TLBCACHE_INFO (L2Unified, 512); break;
+ case 0x44: STORE_TLBCACHE_INFO (L2Unified, 1024); break;
+ case 0x45: STORE_TLBCACHE_INFO (L2Unified, 2048); break;
+ case 0x50: STORE_TLBCACHE_INFO (TLBCode, 4096); break;
+ case 0x51: STORE_TLBCACHE_INFO (TLBCode, 4096); break;
+ case 0x52: STORE_TLBCACHE_INFO (TLBCode, 4096); break;
+ case 0x5b: STORE_TLBCACHE_INFO (TLBData, 4096); break;
+ case 0x5c: STORE_TLBCACHE_INFO (TLBData, 4096); break;
+ case 0x5d: STORE_TLBCACHE_INFO (TLBData, 4096); break;
+ case 0x66: STORE_TLBCACHE_INFO (L1Data, 8); break;
+ case 0x67: STORE_TLBCACHE_INFO (L1Data, 16); break;
+ case 0x68: STORE_TLBCACHE_INFO (L1Data, 32); break;
+ case 0x70: STORE_TLBCACHE_INFO (L1Trace, 12); break;
+ case 0x71: STORE_TLBCACHE_INFO (L1Trace, 16); break;
+ case 0x72: STORE_TLBCACHE_INFO (L1Trace, 32); break;
+ case 0x77: STORE_TLBCACHE_INFO (L1Code, 16); break; // <-- FIXME: IA-64 Only
+ case 0x79: STORE_TLBCACHE_INFO (L2Unified, 128); break;
+ case 0x7a: STORE_TLBCACHE_INFO (L2Unified, 256); break;
+ case 0x7b: STORE_TLBCACHE_INFO (L2Unified, 512); break;
+ case 0x7c: STORE_TLBCACHE_INFO (L2Unified, 1024); break;
+ case 0x7e: STORE_TLBCACHE_INFO (L2Unified, 256); break;
+ case 0x81: STORE_TLBCACHE_INFO (L2Unified, 128); break;
+ case 0x82: STORE_TLBCACHE_INFO (L2Unified, 256); break;
+ case 0x83: STORE_TLBCACHE_INFO (L2Unified, 512); break;
+ case 0x84: STORE_TLBCACHE_INFO (L2Unified, 1024); break;
+ case 0x85: STORE_TLBCACHE_INFO (L2Unified, 2048); break;
+ case 0x88: STORE_TLBCACHE_INFO (L3Unified, 2048); break; // <-- FIXME: IA-64 Only
+ case 0x89: STORE_TLBCACHE_INFO (L3Unified, 4096); break; // <-- FIXME: IA-64 Only
+ case 0x8a: STORE_TLBCACHE_INFO (L3Unified, 8192); break; // <-- FIXME: IA-64 Only
+ case 0x8d: STORE_TLBCACHE_INFO (L3Unified, 3096); break; // <-- FIXME: IA-64 Only
+ case 0x90: STORE_TLBCACHE_INFO (TLBCode, 262144); break; // <-- FIXME: IA-64 Only
+ case 0x96: STORE_TLBCACHE_INFO (TLBCode, 262144); break; // <-- FIXME: IA-64 Only
+ case 0x9b: STORE_TLBCACHE_INFO (TLBCode, 262144); break; // <-- FIXME: IA-64 Only
+
+ // Default case - an error has occured.
+ default: return false;
+ }
+ }
+
+ // Increment the TLB pass counter.
+ TLBPassCounter ++;
+ } while ((TLBCacheData[0] & 0x000000FF) > TLBPassCounter);
+
+ // Ok - we now have the maximum TLB, L1, L2, and L3 sizes...
+ if ((L1Code == -1) && (L1Data == -1) && (L1Trace == -1))
+ {
+ this->Features.L1CacheSize = -1;
+ }
+ else if ((L1Code == -1) && (L1Data == -1) && (L1Trace != -1))
+ {
+ this->Features.L1CacheSize = L1Trace;
+ }
+ else if ((L1Code != -1) && (L1Data == -1))
+ {
+ this->Features.L1CacheSize = L1Code;
+ }
+ else if ((L1Code == -1) && (L1Data != -1))
+ {
+ this->Features.L1CacheSize = L1Data;
+ }
+ else if ((L1Code != -1) && (L1Data != -1))
+ {
+ this->Features.L1CacheSize = L1Code + L1Data;
+ }
+ else
+ {
+ this->Features.L1CacheSize = -1;
+ }
+
+ // Ok - we now have the maximum TLB, L1, L2, and L3 sizes...
+ if (L2Unified == -1)
+ {
+ this->Features.L2CacheSize = -1;
+ }
+ else
+ {
+ this->Features.L2CacheSize = L2Unified;
+ }
+
+ // Ok - we now have the maximum TLB, L1, L2, and L3 sizes...
+ if (L3Unified == -1)
+ {
+ this->Features.L3CacheSize = -1;
+ }
+ else
+ {
+ this->Features.L3CacheSize = L3Unified;
+ }
+
+ return true;
+
+#else
+ return false;
+#endif
+}
+
+
+/** */
+bool SystemInformationImplementation::RetrieveCPUClockSpeed()
+{
+ bool retrieved = false;
+
+#if defined(_WIN32)
+ // First of all we check to see if the RDTSC (0x0F, 0x31) instruction is
+ // supported. If not, we fallback to trying to read this value from the
+ // registry:
+ //
+ if (!this->Features.HasTSC)
+ {
+ HKEY hKey = NULL;
+ LONG err = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+ "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 0,
+ KEY_READ, &hKey);
+
+ if (ERROR_SUCCESS == err)
+ {
+ DWORD dwType = 0;
+ DWORD data = 0;
+ DWORD dwSize = sizeof(DWORD);
+
+ err = RegQueryValueEx(hKey, "~MHz", 0,
+ &dwType, (LPBYTE) &data, &dwSize);
+
+ if (ERROR_SUCCESS == err)
+ {
+ this->CPUSpeedInMHz = (float) data;
+ retrieved = true;
+ }
+
+ RegCloseKey(hKey);
+ hKey = NULL;
+ }
+
+ return retrieved;
+ }
+
+ unsigned int uiRepetitions = 1;
+ unsigned int uiMSecPerRepetition = 50;
+ __int64 i64Total = 0;
+ __int64 i64Overhead = 0;
+
+ for (unsigned int nCounter = 0; nCounter < uiRepetitions; nCounter ++)
+ {
+ i64Total += GetCyclesDifference (SystemInformationImplementation::Delay,
+ uiMSecPerRepetition);
+ i64Overhead +=
+ GetCyclesDifference (SystemInformationImplementation::DelayOverhead,
+ uiMSecPerRepetition);
+ }
+
+ // Calculate the MHz speed.
+ i64Total -= i64Overhead;
+ i64Total /= uiRepetitions;
+ i64Total /= uiMSecPerRepetition;
+ i64Total /= 1000;
+
+ // Save the CPU speed.
+ this->CPUSpeedInMHz = (float) i64Total;
+
+ retrieved = true;
+#endif
+
+ return retrieved;
+}
+
+
+/** */
+bool SystemInformationImplementation::RetrieveClassicalCPUClockSpeed()
+{
+#if USE_ASM_INSTRUCTIONS
+ LARGE_INTEGER liStart, liEnd, liCountsPerSecond;
+ double dFrequency, dDifference;
+
+ // Attempt to get a starting tick count.
+ QueryPerformanceCounter (&liStart);
+
+ __try
+ {
+ _asm
+ {
+ mov eax, 0x80000000
+ mov ebx, CLASSICAL_CPU_FREQ_LOOP
+ Timer_Loop:
+ bsf ecx,eax
+ dec ebx
+ jnz Timer_Loop
+ }
+ }
+ __except(1)
+ {
+ return false;
+ }
+
+ // Attempt to get a starting tick count.
+ QueryPerformanceCounter (&liEnd);
+
+ // Get the difference... NB: This is in seconds....
+ QueryPerformanceFrequency (&liCountsPerSecond);
+ dDifference = (((double) liEnd.QuadPart - (double) liStart.QuadPart) / (double) liCountsPerSecond.QuadPart);
+
+ // Calculate the clock speed.
+ if (this->ChipID.Family == 3)
+ {
+ // 80386 processors.... Loop time is 115 cycles!
+ dFrequency = (((CLASSICAL_CPU_FREQ_LOOP * 115) / dDifference) / 1000000);
+ }
+ else if (this->ChipID.Family == 4)
+ {
+ // 80486 processors.... Loop time is 47 cycles!
+ dFrequency = (((CLASSICAL_CPU_FREQ_LOOP * 47) / dDifference) / 1000000);
+ }
+ else if (this->ChipID.Family == 5)
+ {
+ // Pentium processors.... Loop time is 43 cycles!
+ dFrequency = (((CLASSICAL_CPU_FREQ_LOOP * 43) / dDifference) / 1000000);
+ }
+
+ // Save the clock speed.
+ this->Features.CPUSpeed = (int) dFrequency;
+
+ return true;
+
+#else
+ return false;
+#endif
+}
+
+
+/** */
+bool SystemInformationImplementation::RetrieveCPUExtendedLevelSupport(int CPULevelToCheck)
+{
+ int MaxCPUExtendedLevel = 0;
+
+ // The extended CPUID is supported by various vendors starting with the following CPU models:
+ //
+ // Manufacturer & Chip Name | Family Model Revision
+ //
+ // AMD K6, K6-2 | 5 6 x
+ // Cyrix GXm, Cyrix III "Joshua" | 5 4 x
+ // IDT C6-2 | 5 8 x
+ // VIA Cyrix III | 6 5 x
+ // Transmeta Crusoe | 5 x x
+ // Intel Pentium 4 | f x x
+ //
+
+ // We check to see if a supported processor is present...
+ if (this->ChipManufacturer == AMD)
+ {
+ if (this->ChipID.Family < 5) return false;
+ if ((this->ChipID.Family == 5) && (this->ChipID.Model < 6)) return false;
+ }
+ else if (this->ChipManufacturer == Cyrix)
+ {
+ if (this->ChipID.Family < 5) return false;
+ if ((this->ChipID.Family == 5) && (this->ChipID.Model < 4)) return false;
+ if ((this->ChipID.Family == 6) && (this->ChipID.Model < 5)) return false;
+ }
+ else if (this->ChipManufacturer == IDT)
+ {
+ if (this->ChipID.Family < 5) return false;
+ if ((this->ChipID.Family == 5) && (this->ChipID.Model < 8)) return false;
+ }
+ else if (this->ChipManufacturer == Transmeta)
+ {
+ if (this->ChipID.Family < 5) return false;
+ }
+ else if (this->ChipManufacturer == Intel)
+ {
+ if (this->ChipID.Family < 0xf)
+ {
+ return false;
+ }
+ }
+
+#if USE_ASM_INSTRUCTIONS
+
+ // Use assembly to detect CPUID information...
+ __try {
+ _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
+ ; these registers to change.
+ push eax
+ push ebx
+ push ecx
+ push edx
+#endif
+ ; <<CPUID>>
+ ; eax = 0x80000000 --> eax: maximum supported extended level
+ mov eax,0x80000000
+ CPUID_INSTRUCTION
+ mov MaxCPUExtendedLevel, eax
+
+#ifdef CPUID_AWARE_COMPILER
+ pop edx
+ pop ecx
+ pop ebx
+ pop eax
+#endif
+ }
+ }
+ __except(1)
+ {
+ return false;
+ }
+#endif
+
+ // Now we have to check the level wanted vs level returned...
+ int nLevelWanted = (CPULevelToCheck & 0x7FFFFFFF);
+ int nLevelReturn = (MaxCPUExtendedLevel & 0x7FFFFFFF);
+
+ // Check to see if the level provided is supported...
+ if (nLevelWanted > nLevelReturn)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+
+/** */
+bool SystemInformationImplementation::RetrieveExtendedCPUFeatures()
+{
+
+ // Check that we are not using an Intel processor as it does not support this.
+ if (this->ChipManufacturer == Intel)
+ {
+ return false;
+ }
+
+ // Check to see if what we are about to do is supported...
+ if (!RetrieveCPUExtendedLevelSupport(static_cast<int>(0x80000001)))
+ {
+ return false;
+ }
+
+#if USE_ASM_INSTRUCTIONS
+ int localCPUExtendedFeatures = 0;
+
+ // Use assembly to detect CPUID information...
+ __try
+ {
+ _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
+ ; these registers to change.
+ push eax
+ push ebx
+ push ecx
+ push edx
+#endif
+ ; <<CPUID>>
+ ; eax = 0x80000001 --> eax: CPU ID - bits 31..16 - unused, bits 15..12 - type, bits 11..8 - family, bits 7..4 - model, bits 3..0 - mask revision
+ ; ebx: 31..24 - default APIC ID, 23..16 - logical processsor ID, 15..8 - CFLUSH chunk size , 7..0 - brand ID
+ ; edx: CPU feature flags
+ mov eax,0x80000001
+ CPUID_INSTRUCTION
+ mov localCPUExtendedFeatures, edx
+
+#ifdef CPUID_AWARE_COMPILER
+ pop edx
+ pop ecx
+ pop ebx
+ pop eax
+#endif
+ }
+ }
+ __except(1)
+ {
+ return false;
+ }
+
+ // Retrieve the extended features of CPU present.
+ this->Features.ExtendedFeatures.Has3DNow = ((localCPUExtendedFeatures & 0x80000000) != 0); // 3DNow Present --> Bit 31.
+ this->Features.ExtendedFeatures.Has3DNowPlus = ((localCPUExtendedFeatures & 0x40000000) != 0); // 3DNow+ Present -- > Bit 30.
+ this->Features.ExtendedFeatures.HasSSEMMX = ((localCPUExtendedFeatures & 0x00400000) != 0); // SSE MMX Present --> Bit 22.
+ this->Features.ExtendedFeatures.SupportsMP = ((localCPUExtendedFeatures & 0x00080000) != 0); // MP Capable -- > Bit 19.
+
+ // Retrieve AMD specific extended features.
+ if (this->ChipManufacturer == AMD)
+ {
+ this->Features.ExtendedFeatures.HasMMXPlus = ((localCPUExtendedFeatures & 0x00400000) != 0); // AMD specific: MMX-SSE --> Bit 22
+ }
+
+ // Retrieve Cyrix specific extended features.
+ if (this->ChipManufacturer == Cyrix)
+ {
+ this->Features.ExtendedFeatures.HasMMXPlus = ((localCPUExtendedFeatures & 0x01000000) != 0); // Cyrix specific: Extended MMX --> Bit 24
+ }
+
+ return true;
+
+#else
+ return false;
+#endif
+}
+
+
+/** */
+bool SystemInformationImplementation::RetrieveProcessorSerialNumber()
+{
+ // Check to see if the processor supports the processor serial number.
+ if (!this->Features.HasSerial)
+ {
+ return false;
+ }
+
+#if USE_ASM_INSTRUCTIONS
+ int SerialNumber[3];
+
+ // Use assembly to detect CPUID information...
+ __try {
+ _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
+ ; these registers to change.
+ push eax
+ push ebx
+ push ecx
+ push edx
+#endif
+ ; <<CPUID>>
+ ; eax = 3 --> ebx: top 32 bits are the processor signature bits --> NB: Transmeta only ?!?
+ ; ecx: middle 32 bits are the processor signature bits
+ ; edx: bottom 32 bits are the processor signature bits
+ mov eax, 3
+ CPUID_INSTRUCTION
+ mov SerialNumber[0 * TYPE int], ebx
+ mov SerialNumber[1 * TYPE int], ecx
+ mov SerialNumber[2 * TYPE int], edx
+
+#ifdef CPUID_AWARE_COMPILER
+ pop edx
+ pop ecx
+ pop ebx
+ pop eax
+#endif
+ }
+ }
+ __except(1)
+ {
+ return false;
+ }
+
+ // Process the returned information.
+ char sn[128];
+ sprintf (sn, "%.2x%.2x-%.2x%.2x-%.2x%.2x-%.2x%.2x-%.2x%.2x-%.2x%.2x",
+ ((SerialNumber[0] & 0xff000000) >> 24),
+ ((SerialNumber[0] & 0x00ff0000) >> 16),
+ ((SerialNumber[0] & 0x0000ff00) >> 8),
+ ((SerialNumber[0] & 0x000000ff) >> 0),
+ ((SerialNumber[1] & 0xff000000) >> 24),
+ ((SerialNumber[1] & 0x00ff0000) >> 16),
+ ((SerialNumber[1] & 0x0000ff00) >> 8),
+ ((SerialNumber[1] & 0x000000ff) >> 0),
+ ((SerialNumber[2] & 0xff000000) >> 24),
+ ((SerialNumber[2] & 0x00ff0000) >> 16),
+ ((SerialNumber[2] & 0x0000ff00) >> 8),
+ ((SerialNumber[2] & 0x000000ff) >> 0));
+ this->ChipID.SerialNumber = sn;
+ return true;
+
+#else
+ return false;
+#endif
+}
+
+
+/** */
+bool SystemInformationImplementation::RetrieveCPUPowerManagement()
+{
+ // Check to see if what we are about to do is supported...
+ if (!RetrieveCPUExtendedLevelSupport(static_cast<int>(0x80000007)))
+ {
+ this->Features.ExtendedFeatures.PowerManagement.HasFrequencyID = false;
+ this->Features.ExtendedFeatures.PowerManagement.HasVoltageID = false;
+ this->Features.ExtendedFeatures.PowerManagement.HasTempSenseDiode = false;
+ return false;
+ }
+
+#if USE_ASM_INSTRUCTIONS
+ int localCPUPowerManagement = 0;
+
+
+ // Use assembly to detect CPUID information...
+ __try {
+ _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
+ ; these registers to change.
+ push eax
+ push ebx
+ push ecx
+ push edx
+#endif
+ ; <<CPUID>>
+ ; eax = 0x80000007 --> edx: get processor power management
+ mov eax,0x80000007
+ CPUID_INSTRUCTION
+ mov localCPUPowerManagement, edx
+
+#ifdef CPUID_AWARE_COMPILER
+ pop edx
+ pop ecx
+ pop ebx
+ pop eax
+#endif
+ }
+ }
+ __except(1)
+ {
+ return false;
+ }
+
+ // Check for the power management capabilities of the CPU.
+ this->Features.ExtendedFeatures.PowerManagement.HasTempSenseDiode = ((localCPUPowerManagement & 0x00000001) != 0);
+ this->Features.ExtendedFeatures.PowerManagement.HasFrequencyID = ((localCPUPowerManagement & 0x00000002) != 0);
+ this->Features.ExtendedFeatures.PowerManagement.HasVoltageID = ((localCPUPowerManagement & 0x00000004) != 0);
+
+ return true;
+
+#else
+ return false;
+#endif
+}
+
+void SystemInformationStripLeadingSpace(kwsys_stl::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)
+ {
+ str = str.substr(pos);
+ }
+}
+
+/** */
+bool SystemInformationImplementation::RetrieveExtendedCPUIdentity()
+{
+ // Check to see if what we are about to do is supported...
+ if (!RetrieveCPUExtendedLevelSupport(static_cast<int>(0x80000002)))
+ return false;
+ if (!RetrieveCPUExtendedLevelSupport(static_cast<int>(0x80000003)))
+ return false;
+ if (!RetrieveCPUExtendedLevelSupport(static_cast<int>(0x80000004)))
+ return false;
+
+#if USE_ASM_INSTRUCTIONS
+ int CPUExtendedIdentity[12];
+
+ // Use assembly to detect CPUID information...
+ __try {
+ _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
+ ; these registers to change.
+ push eax
+ push ebx
+ push ecx
+ push edx
+#endif
+ ; <<CPUID>>
+ ; eax = 0x80000002 --> eax, ebx, ecx, edx: get processor name string (part 1)
+ mov eax,0x80000002
+ CPUID_INSTRUCTION
+ mov CPUExtendedIdentity[0 * TYPE int], eax
+ mov CPUExtendedIdentity[1 * TYPE int], ebx
+ mov CPUExtendedIdentity[2 * TYPE int], ecx
+ mov CPUExtendedIdentity[3 * TYPE int], edx
+
+ ; <<CPUID>>
+ ; eax = 0x80000003 --> eax, ebx, ecx, edx: get processor name string (part 2)
+ mov eax,0x80000003
+ CPUID_INSTRUCTION
+ mov CPUExtendedIdentity[4 * TYPE int], eax
+ mov CPUExtendedIdentity[5 * TYPE int], ebx
+ mov CPUExtendedIdentity[6 * TYPE int], ecx
+ mov CPUExtendedIdentity[7 * TYPE int], edx
+
+ ; <<CPUID>>
+ ; eax = 0x80000004 --> eax, ebx, ecx, edx: get processor name string (part 3)
+ mov eax,0x80000004
+ CPUID_INSTRUCTION
+ mov CPUExtendedIdentity[8 * TYPE int], eax
+ mov CPUExtendedIdentity[9 * TYPE int], ebx
+ mov CPUExtendedIdentity[10 * TYPE int], ecx
+ mov CPUExtendedIdentity[11 * TYPE int], edx
+
+#ifdef CPUID_AWARE_COMPILER
+ pop edx
+ pop ecx
+ pop ebx
+ pop eax
+#endif
+ }
+ }
+ __except(1)
+ {
+ return false;
+ }
+
+ // Process the returned information.
+ char nbuf[49];
+ memcpy (&(nbuf[0]), &(CPUExtendedIdentity[0]), sizeof (int));
+ memcpy (&(nbuf[4]), &(CPUExtendedIdentity[1]), sizeof (int));
+ memcpy (&(nbuf[8]), &(CPUExtendedIdentity[2]), sizeof (int));
+ memcpy (&(nbuf[12]), &(CPUExtendedIdentity[3]), sizeof (int));
+ memcpy (&(nbuf[16]), &(CPUExtendedIdentity[4]), sizeof (int));
+ memcpy (&(nbuf[20]), &(CPUExtendedIdentity[5]), sizeof (int));
+ memcpy (&(nbuf[24]), &(CPUExtendedIdentity[6]), sizeof (int));
+ memcpy (&(nbuf[28]), &(CPUExtendedIdentity[7]), sizeof (int));
+ memcpy (&(nbuf[32]), &(CPUExtendedIdentity[8]), sizeof (int));
+ memcpy (&(nbuf[36]), &(CPUExtendedIdentity[9]), sizeof (int));
+ memcpy (&(nbuf[40]), &(CPUExtendedIdentity[10]), sizeof (int));
+ memcpy (&(nbuf[44]), &(CPUExtendedIdentity[11]), sizeof (int));
+ nbuf[48] = '\0';
+ this->ChipID.ProcessorName = nbuf;
+
+ // Because some manufacturers have leading white space - we have to post-process the name.
+ SystemInformationStripLeadingSpace(this->ChipID.ProcessorName);
+ return true;
+#else
+ return false;
+#endif
+}
+
+
+/** */
+bool SystemInformationImplementation::RetrieveClassicalCPUIdentity()
+{
+ // Start by decided which manufacturer we are using....
+ switch (this->ChipManufacturer)
+ {
+ case Intel:
+ // Check the family / model / revision to determine the CPU ID.
+ switch (this->ChipID.Family) {
+ case 3:
+ this->ChipID.ProcessorName = "Newer i80386 family";
+ break;
+ case 4:
+ switch (this->ChipID.Model) {
+ case 0: this->ChipID.ProcessorName = "i80486DX-25/33"; break;
+ case 1: this->ChipID.ProcessorName = "i80486DX-50"; break;
+ case 2: this->ChipID.ProcessorName = "i80486SX"; break;
+ case 3: this->ChipID.ProcessorName = "i80486DX2"; break;
+ case 4: this->ChipID.ProcessorName = "i80486SL"; break;
+ case 5: this->ChipID.ProcessorName = "i80486SX2"; break;
+ case 7: this->ChipID.ProcessorName = "i80486DX2 WriteBack"; break;
+ case 8: this->ChipID.ProcessorName = "i80486DX4"; break;
+ case 9: this->ChipID.ProcessorName = "i80486DX4 WriteBack"; break;
+ default: this->ChipID.ProcessorName = "Unknown 80486 family"; return false;
+ }
+ break;
+ case 5:
+ switch (this->ChipID.Model)
+ {
+ case 0: this->ChipID.ProcessorName = "P5 A-Step"; break;
+ case 1: this->ChipID.ProcessorName = "P5"; break;
+ case 2: this->ChipID.ProcessorName = "P54C"; break;
+ case 3: this->ChipID.ProcessorName = "P24T OverDrive"; break;
+ case 4: this->ChipID.ProcessorName = "P55C"; break;
+ case 7: this->ChipID.ProcessorName = "P54C"; break;
+ case 8: this->ChipID.ProcessorName = "P55C (0.25micron)"; break;
+ default: this->ChipID.ProcessorName = "Unknown Pentium family"; return false;
+ }
+ break;
+ case 6:
+ switch (this->ChipID.Model)
+ {
+ case 0: this->ChipID.ProcessorName = "P6 A-Step"; break;
+ case 1: this->ChipID.ProcessorName = "P6"; break;
+ case 3: this->ChipID.ProcessorName = "Pentium II (0.28 micron)"; break;
+ case 5: this->ChipID.ProcessorName = "Pentium II (0.25 micron)"; break;
+ case 6: this->ChipID.ProcessorName = "Pentium II With On-Die L2 Cache"; break;
+ case 7: this->ChipID.ProcessorName = "Pentium III (0.25 micron)"; break;
+ case 8: this->ChipID.ProcessorName = "Pentium III (0.18 micron) With 256 KB On-Die L2 Cache "; break;
+ case 0xa: this->ChipID.ProcessorName = "Pentium III (0.18 micron) With 1 Or 2 MB On-Die L2 Cache "; break;
+ case 0xb: this->ChipID.ProcessorName = "Pentium III (0.13 micron) With 256 Or 512 KB On-Die L2 Cache "; break;
+ case 23: this->ChipID.ProcessorName = "Intel(R) Core(TM)2 Duo CPU T9500 @ 2.60GHz"; break;
+ default: this->ChipID.ProcessorName = "Unknown P6 family"; return false;
+ }
+ break;
+ case 7:
+ this->ChipID.ProcessorName = "Intel Merced (IA-64)";
+ break;
+ case 0xf:
+ // Check the extended family bits...
+ switch (this->ChipID.ExtendedFamily)
+ {
+ case 0:
+ switch (this->ChipID.Model)
+ {
+ case 0: this->ChipID.ProcessorName = "Pentium IV (0.18 micron)"; break;
+ case 1: this->ChipID.ProcessorName = "Pentium IV (0.18 micron)"; break;
+ case 2: this->ChipID.ProcessorName = "Pentium IV (0.13 micron)"; break;
+ default: this->ChipID.ProcessorName = "Unknown Pentium 4 family"; return false;
+ }
+ break;
+ case 1:
+ this->ChipID.ProcessorName = "Intel McKinley (IA-64)";
+ break;
+ default:
+ this->ChipID.ProcessorName = "Pentium";
+ }
+ break;
+ default:
+ this->ChipID.ProcessorName = "Unknown Intel family";
+ return false;
+ }
+ break;
+
+ case AMD:
+ // Check the family / model / revision to determine the CPU ID.
+ switch (this->ChipID.Family)
+ {
+ case 4:
+ switch (this->ChipID.Model)
+ {
+ case 3: this->ChipID.ProcessorName = "80486DX2"; break;
+ case 7: this->ChipID.ProcessorName = "80486DX2 WriteBack"; break;
+ case 8: this->ChipID.ProcessorName = "80486DX4"; break;
+ case 9: this->ChipID.ProcessorName = "80486DX4 WriteBack"; break;
+ case 0xe: this->ChipID.ProcessorName = "5x86"; break;
+ case 0xf: this->ChipID.ProcessorName = "5x86WB"; break;
+ default: this->ChipID.ProcessorName = "Unknown 80486 family"; return false;
+ }
+ break;
+ case 5:
+ switch (this->ChipID.Model)
+ {
+ case 0: this->ChipID.ProcessorName = "SSA5 (PR75, PR90 = PR100)"; break;
+ case 1: this->ChipID.ProcessorName = "5k86 (PR120 = PR133)"; break;
+ case 2: this->ChipID.ProcessorName = "5k86 (PR166)"; break;
+ case 3: this->ChipID.ProcessorName = "5k86 (PR200)"; break;
+ case 6: this->ChipID.ProcessorName = "K6 (0.30 micron)"; break;
+ case 7: this->ChipID.ProcessorName = "K6 (0.25 micron)"; break;
+ case 8: this->ChipID.ProcessorName = "K6-2"; break;
+ case 9: this->ChipID.ProcessorName = "K6-III"; break;
+ case 0xd: this->ChipID.ProcessorName = "K6-2+ or K6-III+ (0.18 micron)"; break;
+ default: this->ChipID.ProcessorName = "Unknown 80586 family"; return false;
+ }
+ break;
+ case 6:
+ switch (this->ChipID.Model)
+ {
+ case 1: this->ChipID.ProcessorName = "Athlon- (0.25 micron)"; break;
+ case 2: this->ChipID.ProcessorName = "Athlon- (0.18 micron)"; break;
+ case 3: this->ChipID.ProcessorName = "Duron- (SF core)"; break;
+ case 4: this->ChipID.ProcessorName = "Athlon- (Thunderbird core)"; break;
+ case 6: this->ChipID.ProcessorName = "Athlon- (Palomino core)"; break;
+ case 7: this->ChipID.ProcessorName = "Duron- (Morgan core)"; break;
+ case 8:
+ if (this->Features.ExtendedFeatures.SupportsMP)
+ this->ChipID.ProcessorName = "Athlon - MP (Thoroughbred core)";
+ else this->ChipID.ProcessorName = "Athlon - XP (Thoroughbred core)";
+ break;
+ default: this->ChipID.ProcessorName = "Unknown K7 family"; return false;
+ }
+ break;
+ default:
+ this->ChipID.ProcessorName = "Unknown AMD family";
+ return false;
+ }
+ break;
+
+ case Transmeta:
+ switch (this->ChipID.Family)
+ {
+ case 5:
+ switch (this->ChipID.Model)
+ {
+ case 4: this->ChipID.ProcessorName = "Crusoe TM3x00 and TM5x00"; break;
+ default: this->ChipID.ProcessorName = "Unknown Crusoe family"; return false;
+ }
+ break;
+ default:
+ this->ChipID.ProcessorName = "Unknown Transmeta family";
+ return false;
+ }
+ break;
+
+ case Rise:
+ switch (this->ChipID.Family)
+ {
+ case 5:
+ switch (this->ChipID.Model)
+ {
+ case 0: this->ChipID.ProcessorName = "mP6 (0.25 micron)"; break;
+ case 2: this->ChipID.ProcessorName = "mP6 (0.18 micron)"; break;
+ default: this->ChipID.ProcessorName = "Unknown Rise family"; return false;
+ }
+ break;
+ default:
+ this->ChipID.ProcessorName = "Unknown Rise family";
+ return false;
+ }
+ break;
+
+ case UMC:
+ switch (this->ChipID.Family)
+ {
+ case 4:
+ switch (this->ChipID.Model)
+ {
+ case 1: this->ChipID.ProcessorName = "U5D"; break;
+ case 2: this->ChipID.ProcessorName = "U5S"; break;
+ default: this->ChipID.ProcessorName = "Unknown UMC family"; return false;
+ }
+ break;
+ default:
+ this->ChipID.ProcessorName = "Unknown UMC family";
+ return false;
+ }
+ break;
+
+ case IDT:
+ switch (this->ChipID.Family)
+ {
+ case 5:
+ switch (this->ChipID.Model)
+ {
+ case 4: this->ChipID.ProcessorName = "C6"; break;
+ case 8: this->ChipID.ProcessorName = "C2"; break;
+ case 9: this->ChipID.ProcessorName = "C3"; break;
+ default: this->ChipID.ProcessorName = "Unknown IDT\\Centaur family"; return false;
+ }
+ break;
+ case 6:
+ switch (this->ChipID.Model)
+ {
+ case 6: this->ChipID.ProcessorName = "VIA Cyrix III - Samuel"; break;
+ default: this->ChipID.ProcessorName = "Unknown IDT\\Centaur family"; return false;
+ }
+ break;
+ default:
+ this->ChipID.ProcessorName = "Unknown IDT\\Centaur family";
+ return false;
+ }
+ break;
+
+ case Cyrix:
+ switch (this->ChipID.Family)
+ {
+ case 4:
+ switch (this->ChipID.Model)
+ {
+ case 4: this->ChipID.ProcessorName = "MediaGX GX = GXm"; break;
+ case 9: this->ChipID.ProcessorName = "5x86"; break;
+ default: this->ChipID.ProcessorName = "Unknown Cx5x86 family"; return false;
+ }
+ break;
+ case 5:
+ switch (this->ChipID.Model)
+ {
+ case 2: this->ChipID.ProcessorName = "Cx6x86"; break;
+ case 4: this->ChipID.ProcessorName = "MediaGX GXm"; break;
+ default: this->ChipID.ProcessorName = "Unknown Cx6x86 family"; return false;
+ }
+ break;
+ case 6:
+ switch (this->ChipID.Model)
+ {
+ case 0: this->ChipID.ProcessorName = "6x86MX"; break;
+ case 5: this->ChipID.ProcessorName = "Cyrix M2 Core"; break;
+ case 6: this->ChipID.ProcessorName = "WinChip C5A Core"; break;
+ case 7: this->ChipID.ProcessorName = "WinChip C5B\\C5C Core"; break;
+ case 8: this->ChipID.ProcessorName = "WinChip C5C-T Core"; break;
+ default: this->ChipID.ProcessorName = "Unknown 6x86MX\\Cyrix III family"; return false;
+ }
+ break;
+ default:
+ this->ChipID.ProcessorName = "Unknown Cyrix family";
+ return false;
+ }
+ break;
+
+ case NexGen:
+ switch (this->ChipID.Family)
+ {
+ case 5:
+ switch (this->ChipID.Model)
+ {
+ case 0: this->ChipID.ProcessorName = "Nx586 or Nx586FPU"; break;
+ default: this->ChipID.ProcessorName = "Unknown NexGen family"; return false;
+ }
+ break;
+ default:
+ this->ChipID.ProcessorName = "Unknown NexGen family";
+ return false;
+ }
+ break;
+
+ case NSC:
+ this->ChipID.ProcessorName = "Cx486SLC \\ DLC \\ Cx486S A-Step";
+ break;
+ default:
+ this->ChipID.ProcessorName = "Unknown family"; // We cannot identify the processor.
+ return false;
+ }
+
+ return true;
+}
+
+
+/** Extract a value from the CPUInfo file */
+kwsys_stl::string SystemInformationImplementation::ExtractValueFromCpuInfoFile(kwsys_stl::string buffer,const char* word,size_t init)
+{
+ size_t pos = buffer.find(word,init);
+ if(pos != buffer.npos)
+ {
+ this->CurrentPositionInFile = pos;
+ pos = buffer.find(":",pos);
+ size_t pos2 = buffer.find("\n",pos);
+ if(pos!=buffer.npos && pos2!=buffer.npos)
+ {
+ return buffer.substr(pos+2,pos2-pos-2);
+ }
+ }
+ this->CurrentPositionInFile = buffer.npos;
+ return "";
+}
+
+/** Query for the cpu status */
+int SystemInformationImplementation::RetreiveInformationFromCpuInfoFile()
+{
+ this->NumberOfLogicalCPU = 0;
+ this->NumberOfPhysicalCPU = 0;
+ kwsys_stl::string buffer;
+
+ FILE *fd = fopen("/proc/cpuinfo", "r" );
+ if ( !fd )
+ {
+ kwsys_ios::cout << "Problem opening /proc/cpuinfo" << kwsys_ios::endl;
+ return 0;
+ }
+
+ size_t fileSize = 0;
+ while(!feof(fd))
+ {
+ buffer += static_cast<char>(fgetc(fd));
+ fileSize++;
+ }
+ fclose( fd );
+ buffer.resize(fileSize-2);
+ // Number of logical CPUs (combination of multiple processors, multi-core
+ // and hyperthreading)
+ size_t pos = buffer.find("processor\t");
+ while(pos != buffer.npos)
+ {
+ this->NumberOfLogicalCPU++;
+ pos = buffer.find("processor\t",pos+1);
+ }
+
+#ifdef __linux
+ // Find the largest physical id.
+ int maxId = -1;
+ kwsys_stl::string idc =
+ this->ExtractValueFromCpuInfoFile(buffer,"physical id");
+ while(this->CurrentPositionInFile != buffer.npos)
+ {
+ int id = atoi(idc.c_str());
+ if(id > maxId)
+ {
+ maxId=id;
+ }
+ idc = this->ExtractValueFromCpuInfoFile(buffer,"physical id",
+ this->CurrentPositionInFile+1);
+ }
+ // 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 =
+ this->ExtractValueFromCpuInfoFile(buffer,"cpu cores");
+ int numberOfCoresPerCPU=atoi(cores.c_str());
+ this->NumberOfPhysicalCPU=static_cast<unsigned int>(
+ numberOfCoresPerCPU*(maxId+1));
+
+#else // __CYGWIN__
+ // does not have "physical id" entries, neither "cpu cores"
+ // this has to be fixed for hyper-threading.
+ kwsys_stl::string cpucount =
+ this->ExtractValueFromCpuInfoFile(buffer,"cpu count");
+ this->NumberOfPhysicalCPU=
+ this->NumberOfLogicalCPU = atoi(cpucount.c_str());
+#endif
+ // gotta have one, and if this is 0 then we get a / by 0n
+ // beter to have a bad answer than a crash
+ if(this->NumberOfPhysicalCPU <= 0)
+ {
+ this->NumberOfPhysicalCPU = 1;
+ }
+ // LogicalProcessorsPerPhysical>1 => hyperthreading.
+ this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical=
+ this->NumberOfLogicalCPU/this->NumberOfPhysicalCPU;
+
+ // CPU speed (checking only the first proc
+ kwsys_stl::string CPUSpeed = this->ExtractValueFromCpuInfoFile(buffer,"cpu MHz");
+ this->CPUSpeedInMHz = static_cast<float>(atof(CPUSpeed.c_str()));
+
+ // Chip family
+ this->ChipID.Family = atoi(this->ExtractValueFromCpuInfoFile(buffer,"cpu family").c_str());
+
+ // Chip Vendor
+ this->ChipID.Vendor = this->ExtractValueFromCpuInfoFile(buffer,"vendor_id");
+ this->FindManufacturer();
+
+ // Chip Model
+ this->ChipID.Model = atoi(this->ExtractValueFromCpuInfoFile(buffer,"model").c_str());
+ this->RetrieveClassicalCPUIdentity();
+
+ // L1 Cache size
+ kwsys_stl::string cacheSize = this->ExtractValueFromCpuInfoFile(buffer,"cache size");
+ pos = cacheSize.find(" KB");
+ if(pos!=cacheSize.npos)
+ {
+ cacheSize = cacheSize.substr(0,pos);
+ }
+ this->Features.L1CacheSize = atoi(cacheSize.c_str());
+ return 1;
+}
+
+/** Query for the memory status */
+int SystemInformationImplementation::QueryMemory()
+{
+ this->TotalVirtualMemory = 0;
+ this->TotalPhysicalMemory = 0;
+ this->AvailableVirtualMemory = 0;
+ this->AvailablePhysicalMemory = 0;
+#ifdef __CYGWIN__
+ return 0;
+#elif defined(_WIN32)
+#if _MSC_VER < 1300
+ MEMORYSTATUS ms;
+ unsigned long tv, tp, av, ap;
+ ms.dwLength = sizeof(ms);
+ GlobalMemoryStatus(&ms);
+ #define MEM_VAL(value) dw##value
+#else
+ MEMORYSTATUSEX ms;
+ DWORDLONG tv, tp, av, ap;
+ ms.dwLength = sizeof(ms);
+ if (0 == GlobalMemoryStatusEx(&ms))
+ {
+ return 0;
+ }
+#define MEM_VAL(value) ull##value
+#endif
+ tv = ms.MEM_VAL(TotalVirtual);
+ tp = ms.MEM_VAL(TotalPhys);
+ av = ms.MEM_VAL(AvailVirtual);
+ ap = ms.MEM_VAL(AvailPhys);
+ this->TotalVirtualMemory = tv>>10>>10;
+ this->TotalPhysicalMemory = tp>>10>>10;
+ this->AvailableVirtualMemory = av>>10>>10;
+ this->AvailablePhysicalMemory = ap>>10>>10;
+ return 1;
+#elif defined(__linux)
+ unsigned long tv=0;
+ unsigned long tp=0;
+ unsigned long av=0;
+ unsigned long ap=0;
+
+ char buffer[1024]; // for reading lines
+
+ int linuxMajor = 0;
+ int linuxMinor = 0;
+
+ // Find the Linux kernel version first
+ struct utsname unameInfo;
+ int errorFlag = uname(&unameInfo);
+ if( errorFlag!=0 )
+ {
+ kwsys_ios::cout << "Problem calling uname(): " << strerror(errno) << kwsys_ios::endl;
+ return 0;
+ }
+
+ if( unameInfo.release!=0 && strlen(unameInfo.release)>=3 )
+ {
+ // release looks like "2.6.3-15mdk-i686-up-4GB"
+ char majorChar=unameInfo.release[0];
+ char minorChar=unameInfo.release[2];
+
+ if( isdigit(majorChar) )
+ {
+ linuxMajor=majorChar-'0';
+ }
+
+ if( isdigit(minorChar) )
+ {
+ linuxMinor=minorChar-'0';
+ }
+ }
+
+ FILE *fd = fopen("/proc/meminfo", "r" );
+ if ( !fd )
+ {
+ kwsys_ios::cout << "Problem opening /proc/meminfo" << kwsys_ios::endl;
+ return 0;
+ }
+
+ if( linuxMajor>=3 || ( (linuxMajor>=2) && (linuxMinor>=6) ) )
+ {
+ // new /proc/meminfo format since kernel 2.6.x
+ // Rigorously, this test should check from the developping version 2.5.x
+ // that introduced the new format...
+
+ enum { mMemTotal, mMemFree, mBuffers, mCached, mSwapTotal, mSwapFree };
+ const char* format[6] =
+ { "MemTotal:%lu kB", "MemFree:%lu kB", "Buffers:%lu kB",
+ "Cached:%lu kB", "SwapTotal:%lu kB", "SwapFree:%lu kB" };
+ bool have[6] = { false, false, false, false, false, false };
+ unsigned long value[6];
+ int count = 0;
+ while(fgets(buffer, sizeof(buffer), fd))
+ {
+ for(int i=0; i < 6; ++i)
+ {
+ if(!have[i] && sscanf(buffer, format[i], &value[i]) == 1)
+ {
+ have[i] = true;
+ ++count;
+ }
+ }
+ }
+ if(count == 6)
+ {
+ this->TotalPhysicalMemory = value[mMemTotal] / 1024;
+ this->AvailablePhysicalMemory =
+ (value[mMemFree] + value[mBuffers] + value[mCached]) / 1024;
+ this->TotalVirtualMemory = value[mSwapTotal] / 1024;
+ this->AvailableVirtualMemory = value[mSwapFree] / 1024;
+ }
+ else
+ {
+ kwsys_ios::cout << "Problem parsing /proc/meminfo" << kwsys_ios::endl;
+ fclose(fd);
+ return 0;
+ }
+ }
+ else
+ {
+ // /proc/meminfo format for kernel older than 2.6.x
+
+ unsigned long temp;
+ unsigned long cachedMem;
+ unsigned long buffersMem;
+ char *r=fgets(buffer, sizeof(buffer), fd); // Skip "total: used:..."
+ int status=0;
+ if(r==buffer)
+ {
+ status+=fscanf(fd, "Mem: %lu %lu %lu %lu %lu %lu\n",
+ &tp, &temp, &ap, &temp, &buffersMem, &cachedMem);
+ }
+ if(status==6)
+ {
+ status+=fscanf(fd, "Swap: %lu %lu %lu\n", &tv, &temp, &av);
+ }
+ if(status==9)
+ {
+ this->TotalVirtualMemory = tv>>10>>10;
+ this->TotalPhysicalMemory = tp>>10>>10;
+ this->AvailableVirtualMemory = av>>10>>10;
+ this->AvailablePhysicalMemory = (ap+buffersMem+cachedMem)>>10>>10;
+ }
+ else
+ {
+ kwsys_ios::cout << "Problem parsing /proc/meminfo" << kwsys_ios::endl;
+ fclose(fd);
+ return 0;
+ }
+ }
+ fclose( fd );
+ return 1;
+#elif defined(__hpux)
+ unsigned long tv=0;
+ unsigned long tp=0;
+ unsigned long av=0;
+ unsigned long ap=0;
+ struct pst_static pst;
+ struct pst_dynamic pdy;
+
+ unsigned long ps = 0;
+ if (pstat_getstatic(&pst, sizeof(pst), (size_t) 1, 0) != -1)
+ {
+ ps = pst.page_size;
+ tp = pst.physical_memory *ps;
+ tv = (pst.physical_memory + pst.pst_maxmem) * ps;
+ if (pstat_getdynamic(&pdy, sizeof(pdy), (size_t) 1, 0) != -1)
+ {
+ ap = tp - pdy.psd_rm * ps;
+ av = tv - pdy.psd_vm;
+ this->TotalVirtualMemory = tv>>10>>10;
+ this->TotalPhysicalMemory = tp>>10>>10;
+ this->AvailableVirtualMemory = av>>10>>10;
+ this->AvailablePhysicalMemory = ap>>10>>10;
+ return 1;
+ }
+ }
+ return 0;
+#else
+ return 0;
+#endif
+
+
+}
+
+/** */
+size_t SystemInformationImplementation::GetTotalVirtualMemory()
+{
+ return this->TotalVirtualMemory;
+}
+
+/** */
+size_t SystemInformationImplementation::GetAvailableVirtualMemory()
+{
+ return this->AvailableVirtualMemory;
+}
+
+size_t SystemInformationImplementation::GetTotalPhysicalMemory()
+{
+ return this->TotalPhysicalMemory;
+}
+
+/** */
+size_t SystemInformationImplementation::GetAvailablePhysicalMemory()
+{
+ return this->AvailablePhysicalMemory;
+}
+
+/** Get Cycle differences */
+LongLong SystemInformationImplementation::GetCyclesDifference (DELAY_FUNC DelayFunction,
+ unsigned int uiParameter)
+{
+#if USE_ASM_INSTRUCTIONS
+
+ unsigned int edx1, eax1;
+ unsigned int edx2, eax2;
+
+ // Calculate the frequency of the CPU instructions.
+ __try {
+ _asm {
+ push uiParameter ; push parameter param
+ mov ebx, DelayFunction ; store func in ebx
+
+ RDTSC_INSTRUCTION
+
+ mov esi, eax ; esi = eax
+ mov edi, edx ; edi = edx
+
+ call ebx ; call the delay functions
+
+ RDTSC_INSTRUCTION
+
+ pop ebx
+
+ mov edx2, edx ; edx2 = edx
+ mov eax2, eax ; eax2 = eax
+
+ mov edx1, edi ; edx2 = edi
+ mov eax1, esi ; eax2 = esi
+ }
+ }
+ __except(1)
+ {
+ return -1;
+ }
+
+ return ((((__int64) edx2 << 32) + eax2) - (((__int64) edx1 << 32) + eax1));
+
+#else
+ (void)DelayFunction;
+ (void)uiParameter;
+ return -1;
+#endif
+}
+
+
+/** Compute the delay overhead */
+void SystemInformationImplementation::DelayOverhead(unsigned int uiMS)
+{
+#if defined(_WIN32)
+ LARGE_INTEGER Frequency, StartCounter, EndCounter;
+ __int64 x;
+
+ // Get the frequency of the high performance counter.
+ if(!QueryPerformanceFrequency (&Frequency))
+ {
+ return;
+ }
+ x = Frequency.QuadPart / 1000 * uiMS;
+
+ // Get the starting position of the counter.
+ QueryPerformanceCounter (&StartCounter);
+
+ do {
+ // Get the ending position of the counter.
+ QueryPerformanceCounter (&EndCounter);
+ } while (EndCounter.QuadPart - StartCounter.QuadPart == x);
+#endif
+ (void)uiMS;
+}
+
+/** Return the number of logical CPU per physical CPUs Works only for windows */
+unsigned char SystemInformationImplementation::LogicalCPUPerPhysicalCPU(void)
+{
+#ifdef __APPLE__
+ size_t len = 4;
+ int cores_per_package = 0;
+ int err = sysctlbyname("machdep.cpu.cores_per_package", &cores_per_package, &len, NULL, 0);
+ if (err != 0)
+ {
+ return 1; // That name was not found, default to 1
+ }
+ return static_cast<unsigned char>(cores_per_package);
+#else
+ unsigned int Regebx = 0;
+#if USE_ASM_INSTRUCTIONS
+ if (!this->IsHyperThreadingSupported())
+ {
+ return static_cast<unsigned char>(1); // HT not supported
+ }
+ __asm
+ {
+ mov eax, 1
+ cpuid
+ mov Regebx, ebx
+ }
+#endif
+ return static_cast<unsigned char> ((Regebx & NUM_LOGICAL_BITS) >> 16);
+#endif
+}
+
+
+/** Works only for windows */
+unsigned int SystemInformationImplementation::IsHyperThreadingSupported()
+{
+#if USE_ASM_INSTRUCTIONS
+ unsigned int Regedx = 0,
+ Regeax = 0,
+ VendorId[3] = {0, 0, 0};
+ __try // Verify cpuid instruction is supported
+ {
+ __asm
+ {
+ xor eax, eax // call cpuid with eax = 0
+ cpuid // Get vendor id string
+ mov VendorId, ebx
+ mov VendorId + 4, edx
+ mov VendorId + 8, ecx
+
+ mov eax, 1 // call cpuid with eax = 1
+ cpuid
+ mov Regeax, eax // eax contains family processor type
+ mov Regedx, edx // edx has info about the availability of hyper-Threading
+ }
+ }
+ __except (EXCEPTION_EXECUTE_HANDLER)
+ {
+ return(0); // cpuid is unavailable
+ }
+
+ if (((Regeax & FAMILY_ID) == PENTIUM4_ID) || (Regeax & EXT_FAMILY_ID))
+ {
+ if (VendorId[0] == 'uneG')
+ {
+ if (VendorId[1] == 'Ieni')
+ {
+ if (VendorId[2] == 'letn')
+ {
+ return(Regedx & HT_BIT); // Genuine Intel with hyper-Threading technology
+ }
+ }
+ }
+ }
+#endif
+
+ return 0; // Not genuine Intel processor
+}
+
+
+/** Return the APIC Id. Works only for windows. */
+unsigned char SystemInformationImplementation::GetAPICId()
+{
+ unsigned int Regebx = 0;
+
+#if USE_ASM_INSTRUCTIONS
+ if (!this->IsHyperThreadingSupported())
+ {
+ return static_cast<unsigned char>(-1); // HT not supported
+ } // Logical processor = 1
+ __asm
+ {
+ mov eax, 1
+ cpuid
+ mov Regebx, ebx
+ }
+#endif
+
+ return static_cast<unsigned char>((Regebx & INITIAL_APIC_ID_BITS) >> 24);
+}
+
+
+/** Count the number of CPUs. Works only on windows. */
+int SystemInformationImplementation::CPUCount()
+{
+#if defined(_WIN32)
+ unsigned char StatusFlag = 0;
+ SYSTEM_INFO info;
+
+ this->NumberOfPhysicalCPU = 0;
+ this->NumberOfLogicalCPU = 0;
+ info.dwNumberOfProcessors = 0;
+ GetSystemInfo (&info);
+
+ // Number of physical processors in a non-Intel system
+ // or in a 32-bit Intel system with Hyper-Threading technology disabled
+ this->NumberOfPhysicalCPU = (unsigned char) info.dwNumberOfProcessors;
+
+ if (this->IsHyperThreadingSupported())
+ {
+ unsigned char HT_Enabled = 0;
+ this->NumberOfLogicalCPU = this->LogicalCPUPerPhysicalCPU();
+ if (this->NumberOfLogicalCPU >= 1) // >1 Doesn't mean HT is enabled in the BIOS
+ {
+ HANDLE hCurrentProcessHandle;
+#ifndef _WIN64
+# define DWORD_PTR DWORD
+#endif
+ DWORD_PTR dwProcessAffinity;
+ DWORD_PTR dwSystemAffinity;
+ DWORD dwAffinityMask;
+
+ // Calculate the appropriate shifts and mask based on the
+ // number of logical processors.
+ unsigned int i = 1;
+ unsigned char PHY_ID_MASK = 0xFF;
+ //unsigned char PHY_ID_SHIFT = 0;
+
+ while (i < this->NumberOfLogicalCPU)
+ {
+ i *= 2;
+ PHY_ID_MASK <<= 1;
+ // PHY_ID_SHIFT++;
+ }
+
+ hCurrentProcessHandle = GetCurrentProcess();
+ GetProcessAffinityMask(hCurrentProcessHandle, &dwProcessAffinity,
+ &dwSystemAffinity);
+
+ // Check if available process affinity mask is equal to the
+ // available system affinity mask
+ if (dwProcessAffinity != dwSystemAffinity)
+ {
+ StatusFlag = HT_CANNOT_DETECT;
+ this->NumberOfPhysicalCPU = (unsigned char)-1;
+ return StatusFlag;
+ }
+
+ dwAffinityMask = 1;
+ while (dwAffinityMask != 0 && dwAffinityMask <= dwProcessAffinity)
+ {
+ // Check if this CPU is available
+ if (dwAffinityMask & dwProcessAffinity)
+ {
+ if (SetProcessAffinityMask(hCurrentProcessHandle,
+ dwAffinityMask))
+ {
+ unsigned char APIC_ID, LOG_ID;
+ Sleep(0); // Give OS time to switch CPU
+
+ APIC_ID = GetAPICId();
+ LOG_ID = APIC_ID & ~PHY_ID_MASK;
+
+ if (LOG_ID != 0)
+ {
+ HT_Enabled = 1;
+ }
+ }
+ }
+ dwAffinityMask = dwAffinityMask << 1;
+ }
+ // Reset the processor affinity
+ SetProcessAffinityMask(hCurrentProcessHandle, dwProcessAffinity);
+
+ if (this->NumberOfLogicalCPU == 1) // Normal P4 : HT is disabled in hardware
+ {
+ StatusFlag = HT_DISABLED;
+ }
+ else
+ {
+ if (HT_Enabled)
+ {
+ // Total physical processors in a Hyper-Threading enabled system.
+ this->NumberOfPhysicalCPU /= (this->NumberOfLogicalCPU);
+ StatusFlag = HT_ENABLED;
+ }
+ else
+ {
+ StatusFlag = HT_SUPPORTED_NOT_ENABLED;
+ }
+ }
+ }
+ }
+ else
+ {
+ // Processors do not have Hyper-Threading technology
+ StatusFlag = HT_NOT_CAPABLE;
+ this->NumberOfLogicalCPU = 1;
+ }
+ return StatusFlag;
+#else
+ return 0;
+#endif
+}
+
+
+/** Return the number of logical CPUs on the system */
+unsigned int SystemInformationImplementation::GetNumberOfLogicalCPU()
+{
+ return this->NumberOfLogicalCPU;
+}
+
+
+/** Return the number of physical CPUs on the system */
+unsigned int SystemInformationImplementation::GetNumberOfPhysicalCPU()
+{
+ return this->NumberOfPhysicalCPU;
+}
+
+
+/** For Mac use sysctlbyname calls to find system info */
+bool SystemInformationImplementation::ParseSysCtl()
+{
+#if defined(__APPLE__)
+ int err = 0;
+ uint64_t value = 0;
+ size_t len = sizeof(value);
+ sysctlbyname("hw.memsize", &value, &len, NULL, 0);
+ this->TotalPhysicalMemory = static_cast< size_t >( value/1048576 );
+
+ // Parse values for Mac
+ this->AvailablePhysicalMemory = 0;
+ vm_statistics_data_t vmstat;
+ mach_msg_type_number_t count = HOST_VM_INFO_COUNT;
+ if ( host_statistics(mach_host_self(), HOST_VM_INFO,
+ (host_info_t) &vmstat, &count) == KERN_SUCCESS )
+ {
+ err = sysctlbyname("hw.pagesize", &value, &len, NULL, 0);
+ int64_t available_memory = vmstat.free_count * value;
+ this->AvailablePhysicalMemory = static_cast< size_t >( available_memory / 1048576 );
+ }
+
+#ifdef VM_SWAPUSAGE
+ // Virtual memory.
+ int mib[2] = { CTL_VM, VM_SWAPUSAGE };
+ size_t miblen = sizeof(mib) / sizeof(mib[0]);
+ struct xsw_usage swap;
+ len = sizeof(struct xsw_usage);
+ err = sysctl(mib, miblen, &swap, &len, NULL, 0);
+ if (err == 0)
+ {
+ this->AvailableVirtualMemory = static_cast< size_t >( swap.xsu_avail/1048576 );
+ this->TotalVirtualMemory = static_cast< size_t >( swap.xsu_total/1048576 );
+ }
+#else
+ this->AvailableVirtualMemory = 0;
+ this->TotalVirtualMemory = 0;
+#endif
+
+// CPU Info
+ len = sizeof(this->NumberOfPhysicalCPU);
+ sysctlbyname("hw.physicalcpu", &this->NumberOfPhysicalCPU, &len, NULL, 0);
+ sysctlbyname("hw.logicalcpu", &this->NumberOfLogicalCPU, &len, NULL, 0);
+ this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical =
+ this->LogicalCPUPerPhysicalCPU();
+
+ len = sizeof(value);
+ sysctlbyname("hw.cpufrequency", &value, &len, NULL, 0);
+ this->CPUSpeedInMHz = static_cast< float >( value )/ 1000000;
+
+
+ // Chip family
+ len = sizeof(this->ChipID.Family);
+ //Seems only the intel chips will have this name so if this fails it is
+ //probably a PPC machine
+ err = sysctlbyname("machdep.cpu.family",
+ &this->ChipID.Family, &len, NULL, 0);
+ if (err != 0) // Go back to names we know but are less descriptive
+ {
+ this->ChipID.Family = 0;
+ char retBuf[32];
+ ::memset(retBuf, 0, 32);
+ 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)
+ {
+ this->ChipID.Vendor = "IBM";
+ len = 4;
+ err = sysctlbyname("hw.cputype", &this->ChipID.Family, &len, NULL, 0);
+ err = sysctlbyname("hw.cpusubtype", &this->ChipID.Model, &len, NULL, 0);
+ this->FindManufacturer();
+ }
+ }
+ else // Should be an Intel Chip.
+ {
+ len = sizeof(this->ChipID.Family);
+ err =
+ sysctlbyname("machdep.cpu.family", &this->ChipID.Family, &len, NULL, 0);
+
+ char retBuf[128];
+ ::memset(retBuf, 0, 128);
+ len = 128;
+ err = sysctlbyname("machdep.cpu.vendor", retBuf, &len, NULL, 0);
+ // Chip Vendor
+ this->ChipID.Vendor = retBuf;
+ this->FindManufacturer();
+
+ ::memset(retBuf, 0, 128);
+ err =
+ sysctlbyname("machdep.cpu.brand_string",
+ retBuf, &len, NULL, 0);
+ this->ChipID.ProcessorName = retBuf;
+
+ // Chip Model
+ len = sizeof(value);
+ err = sysctlbyname("machdep.cpu.model", &value, &len, NULL, 0);
+ this->ChipID.Model = static_cast< int >( value );
+ }
+ // Cache size
+ len = sizeof(value);
+ err = sysctlbyname("hw.l1icachesize", &value, &len, NULL, 0);
+ this->Features.L1CacheSize = static_cast< int >( value );
+ err = sysctlbyname("hw.l2cachesize", &value, &len, NULL, 0);
+ this->Features.L2CacheSize = static_cast< int >( value );
+
+ return true;
+#else
+ return false;
+#endif
+}
+
+
+/** Extract a value from sysctl command */
+kwsys_stl::string SystemInformationImplementation::ExtractValueFromSysCtl(const char* word)
+{
+ size_t pos = this->SysCtlBuffer.find(word);
+ if(pos != this->SysCtlBuffer.npos)
+ {
+ pos = this->SysCtlBuffer.find(": ",pos);
+ size_t pos2 = this->SysCtlBuffer.find("\n",pos);
+ if(pos!=this->SysCtlBuffer.npos && pos2!=this->SysCtlBuffer.npos)
+ {
+ return this->SysCtlBuffer.substr(pos+2,pos2-pos-2);
+ }
+ }
+ return "";
+}
+
+
+/** Run a given process */
+kwsys_stl::string SystemInformationImplementation::RunProcess(kwsys_stl::vector<const char*> args)
+{
+ kwsys_stl::string buffer = "";
+
+ // Run the application
+ kwsysProcess* gp = kwsysProcess_New();
+ kwsysProcess_SetCommand(gp, &*args.begin());
+ kwsysProcess_SetOption(gp,kwsysProcess_Option_HideWindow,1);
+
+ kwsysProcess_Execute(gp);
+
+ char* data = NULL;
+ int length;
+ double timeout = 255;
+
+ while(kwsysProcess_WaitForData(gp,&data,&length,&timeout)) // wait for 1s
+ {
+ for(int i=0;i<length;i++)
+ {
+ buffer += data[i];
+ }
+ }
+ kwsysProcess_WaitForExit(gp, 0);
+
+ int result = 0;
+ switch(kwsysProcess_GetState(gp))
+ {
+ case kwsysProcess_State_Exited:
+ {
+ result = kwsysProcess_GetExitValue(gp);
+ } break;
+ case kwsysProcess_State_Error:
+ {
+ kwsys_ios::cerr << "Error: Could not run " << args[0] << ":\n";
+ kwsys_ios::cerr << kwsysProcess_GetErrorString(gp) << "\n";
+ } break;
+ case kwsysProcess_State_Exception:
+ {
+ kwsys_ios::cerr << "Error: " << args[0]
+ << " terminated with an exception: "
+ << kwsysProcess_GetExceptionString(gp) << "\n";
+ } break;
+ case kwsysProcess_State_Starting:
+ case kwsysProcess_State_Executing:
+ case kwsysProcess_State_Expired:
+ case kwsysProcess_State_Killed:
+ {
+ // Should not get here.
+ kwsys_ios::cerr << "Unexpected ending state after running " << args[0]
+ << kwsys_ios::endl;
+ } break;
+ }
+ kwsysProcess_Delete(gp);
+ if(result)
+ {
+ kwsys_ios::cerr << "Error " << args[0] << " returned :" << result << "\n";
+ }
+ return buffer;
+}
+
+
+kwsys_stl::string SystemInformationImplementation::ParseValueFromKStat(const char* arguments)
+{
+ kwsys_stl::vector<const char*> args;
+ args.clear();
+ args.push_back("kstat");
+ args.push_back("-p");
+
+ kwsys_stl::string command = arguments;
+ size_t start = command.npos;
+ size_t pos = command.find(' ',0);
+ while(pos!=command.npos)
+ {
+ bool inQuotes = false;
+ // Check if we are between quotes
+ size_t b0 = command.find('"',0);
+ size_t b1 = command.find('"',b0+1);
+ while(b0 != command.npos && b1 != command.npos && b1>b0)
+ {
+ if(pos>b0 && pos<b1)
+ {
+ inQuotes = true;
+ break;
+ }
+ b0 = command.find('"',b1+1);
+ b1 = command.find('"',b0+1);
+ }
+
+ if(!inQuotes)
+ {
+ kwsys_stl::string arg = command.substr(start+1,pos-start-1);
+
+ // Remove the quotes if any
+ size_t quotes = arg.find('"');
+ while(quotes != arg.npos)
+ {
+ arg.erase(quotes,1);
+ quotes = arg.find('"');
+ }
+ args.push_back(arg.c_str());
+ start = pos;
+ }
+ pos = command.find(' ',pos+1);
+ }
+ kwsys_stl::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);
+
+ kwsys_stl::string value = "";
+ for(size_t i=buffer.size()-1;i>0;i--)
+ {
+ if(buffer[i] == ' ' || buffer[i] == '\t')
+ {
+ break;
+ }
+ if(buffer[i] != '\n' && buffer[i] != '\r')
+ {
+ kwsys_stl::string val = value;
+ value = buffer[i];
+ value += val;
+ }
+ }
+ return value;
+}
+
+
+/** Querying for system information from Solaris */
+bool SystemInformationImplementation::QuerySolarisInfo()
+{
+ // Parse values
+ this->NumberOfPhysicalCPU = static_cast<unsigned int>(
+ atoi(this->ParseValueFromKStat("-n syste_misc -s ncpus").c_str()));
+ this->NumberOfLogicalCPU = this->NumberOfPhysicalCPU;
+
+ if(this->NumberOfPhysicalCPU!=0)
+ {
+ this->NumberOfLogicalCPU /= this->NumberOfPhysicalCPU;
+ }
+
+ this->CPUSpeedInMHz = static_cast<float>(atoi(this->ParseValueFromKStat("-s clock_MHz").c_str()));
+
+ // Chip family
+ this->ChipID.Family = 0;
+
+ // Chip Vendor
+ this->ChipID.Vendor = "Sun";
+ this->FindManufacturer();
+
+ // Chip Model
+ this->ChipID.ProcessorName = this->ParseValueFromKStat("-s cpu_type");
+ this->ChipID.Model = 0;
+
+ // Cache size
+ this->Features.L1CacheSize = 0;
+ this->Features.L2CacheSize = 0;
+
+ char* tail;
+ unsigned long totalMemory =
+ strtoul(this->ParseValueFromKStat("-s physmem").c_str(),&tail,0);
+ this->TotalPhysicalMemory = totalMemory/1024;
+ this->TotalPhysicalMemory *= 8192;
+ this->TotalPhysicalMemory /= 1024;
+
+ // Undefined values (for now at least)
+ this->TotalVirtualMemory = 0;
+ this->AvailablePhysicalMemory = 0;
+ this->AvailableVirtualMemory = 0;
+
+ return true;
+}
+
+
+/** Querying for system information from Haiku OS */
+bool SystemInformationImplementation::QueryHaikuInfo()
+{
+#if defined(__HAIKU__)
+
+ system_info info;
+ get_system_info(&info);
+
+ this->NumberOfPhysicalCPU = info.cpu_count;
+ this->CPUSpeedInMHz = info.cpu_clock_speed / 1000000.0F;
+
+ // Physical Memory
+ this->TotalPhysicalMemory = (info.max_pages * B_PAGE_SIZE) / (1024 * 1024) ;
+ this->AvailablePhysicalMemory = this->TotalPhysicalMemory -
+ ((info.used_pages * B_PAGE_SIZE) / (1024 * 1024));
+
+
+ // NOTE: get_system_info_etc is currently a private call so just set to 0
+ // until it becomes public
+ this->TotalVirtualMemory = 0;
+ this->AvailableVirtualMemory = 0;
+
+ // Retrieve cpuid_info union for cpu 0
+ cpuid_info cpu_info;
+ get_cpuid(&cpu_info, 0, 0);
+
+ // Chip Vendor
+ // Use a temporary buffer so that we can add NULL termination to the string
+ char vbuf[13];
+ strncpy(vbuf, cpu_info.eax_0.vendor_id, 12);
+ vbuf[12] = '\0';
+ this->ChipID.Vendor = vbuf;
+
+ this->FindManufacturer();
+
+ // Retrieve cpuid_info union for cpu 0 this time using a register value of 1
+ get_cpuid(&cpu_info, 1, 0);
+
+ this->NumberOfLogicalCPU = cpu_info.eax_1.logical_cpus;
+
+ // Chip type
+ this->ChipID.Type = cpu_info.eax_1.type;
+
+ // Chip family
+ this->ChipID.Family = cpu_info.eax_1.family;
+
+ // Chip Model
+ this->ChipID.Model = cpu_info.eax_1.model;
+
+ // Chip Revision
+ this->ChipID.Revision = cpu_info.eax_1.stepping;
+
+ // Chip Extended Family
+ this->ChipID.ExtendedFamily = cpu_info.eax_1.extended_family;
+
+ // Chip Extended Model
+ this->ChipID.ExtendedModel = cpu_info.eax_1.extended_model;
+
+ // Get ChipID.ProcessorName from other information already gathered
+ this->RetrieveClassicalCPUIdentity();
+
+ // Cache size
+ this->Features.L1CacheSize = 0;
+ this->Features.L2CacheSize = 0;
+
+ return true;
+
+#else
+ return false;
+#endif
+}
+
+bool SystemInformationImplementation::QueryQNXMemory()
+{
+#if defined(__QNX__)
+ kwsys_stl::string buffer;
+ kwsys_stl::vector<const char*> args;
+ args.clear();
+
+ args.push_back("showmem");
+ args.push_back("-S");
+ args.push_back(0);
+ buffer = this->RunProcess(args);
+ args.clear();
+
+ size_t pos = buffer.find("System RAM:");
+ if (pos == buffer.npos)
+ return false;
+ pos = buffer.find(":", pos);
+ size_t pos2 = buffer.find("M (", pos);
+ if (pos2 == buffer.npos)
+ return false;
+
+ pos++;
+ while (buffer[pos] == ' ')
+ pos++;
+
+ this->TotalPhysicalMemory = atoi(buffer.substr(pos, pos2 - pos).c_str());
+ return true;
+#endif
+ return false;
+}
+
+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;
+ args.clear();
+
+ args.push_back("pidin");
+ args.push_back("info");
+ args.push_back(0);
+ buffer = this->RunProcess(args);
+ args.clear();
+
+ size_t pos = buffer.find("Processor1:");
+ if (pos == buffer.npos)
+ return false;
+
+ size_t pos2 = buffer.find("MHz", pos);
+ if (pos2 == buffer.npos)
+ return false;
+
+ size_t pos3 = pos2;
+ while (buffer[pos3] != ' ')
+ --pos3;
+
+ this->CPUSpeedInMHz = atoi(buffer.substr(pos3 + 1, pos2 - pos3 - 1).c_str());
+
+ pos2 = buffer.find(" Stepping", pos);
+ if (pos2 != buffer.npos)
+ {
+ pos2 = buffer.find(" ", pos2 + 1);
+ if (pos2 != buffer.npos && pos2 < pos3)
+ {
+ this->ChipID.Revision = atoi(buffer.substr(pos2 + 1, pos3 - pos2).c_str());
+ }
+ }
+
+ this->NumberOfPhysicalCPU = 0;
+ do
+ {
+ pos = buffer.find("\nProcessor", pos + 1);
+ ++this->NumberOfPhysicalCPU;
+ } while (pos != buffer.npos);
+ this->NumberOfLogicalCPU = 1;
+
+ return true;
+#else
+ return false;
+#endif
+}
+
+/** Query the operating system information */
+bool SystemInformationImplementation::QueryOSInformation()
+{
+#if defined(_WIN32)
+
+ this->OSName = "Windows";
+
+ OSVERSIONINFOEX 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);
+ if (!bOsVersionInfoEx)
+ {
+ osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
+ if (!GetVersionEx ((OSVERSIONINFO *) &osvi))
+ {
+ return false;
+ }
+ }
+
+ switch (osvi.dwPlatformId)
+ {
+ case VER_PLATFORM_WIN32_NT:
+ // Test for the product.
+ if (osvi.dwMajorVersion <= 4)
+ {
+ this->OSRelease = "NT";
+ }
+ if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0)
+ {
+ this->OSRelease = "2000";
+ }
+ if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1)
+ {
+ this->OSRelease = "XP";
+ }
+ // XP Professional x64
+ if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2)
+ {
+ this->OSRelease = "XP";
+ }
+#ifdef VER_NT_WORKSTATION
+ // Test for product type.
+ if (bOsVersionInfoEx)
+ {
+ if (osvi.wProductType == VER_NT_WORKSTATION)
+ {
+ if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0)
+ {
+ this->OSRelease = "Vista";
+ }
+ if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 1)
+ {
+ this->OSRelease = "7";
+ }
+// VER_SUITE_PERSONAL may not be defined
+#ifdef VER_SUITE_PERSONAL
+ else
+ {
+ if (osvi.wSuiteMask & VER_SUITE_PERSONAL)
+ {
+ this->OSRelease += " Personal";
+ }
+ else
+ {
+ this->OSRelease += " Professional";
+ }
+ }
+#endif
+ }
+ else if (osvi.wProductType == VER_NT_SERVER)
+ {
+ // Check for .NET Server instead of Windows XP.
+ if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1)
+ {
+ this->OSRelease = ".NET";
+ }
+
+ // Continue with the type detection.
+ if (osvi.wSuiteMask & VER_SUITE_DATACENTER)
+ {
+ this->OSRelease += " DataCenter Server";
+ }
+ else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
+ {
+ this->OSRelease += " Advanced Server";
+ }
+ else
+ {
+ this->OSRelease += " Server";
+ }
+ }
+
+ sprintf (operatingSystem, "%s (Build %ld)", osvi.szCSDVersion, osvi.dwBuildNumber & 0xFFFF);
+ this->OSVersion = operatingSystem;
+ }
+ else
+#endif // VER_NT_WORKSTATION
+ {
+ HKEY hKey;
+ char 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);
+ RegCloseKey (hKey);
+
+ if (lstrcmpi ("WINNT", szProductType) == 0)
+ {
+ this->OSRelease += " Professional";
+ }
+ if (lstrcmpi ("LANMANNT", szProductType) == 0)
+ {
+ // Decide between Windows 2000 Advanced Server and Windows .NET Enterprise Server.
+ if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1)
+ {
+ this->OSRelease += " Standard Server";
+ }
+ else
+ {
+ this->OSRelease += " Server";
+ }
+ }
+ if (lstrcmpi ("SERVERNT", szProductType) == 0)
+ {
+ // Decide between Windows 2000 Advanced Server and Windows .NET Enterprise Server.
+ if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1)
+ {
+ this->OSRelease += " Enterprise Server";
+ }
+ else
+ {
+ this->OSRelease += " Advanced Server";
+ }
+ }
+ }
+
+ // Display version, service pack (if any), and build number.
+ if (osvi.dwMajorVersion <= 4)
+ {
+ // NB: NT 4.0 and earlier.
+ sprintf (operatingSystem, "version %ld.%ld %s (Build %ld)",
+ osvi.dwMajorVersion,
+ osvi.dwMinorVersion,
+ osvi.szCSDVersion,
+ osvi.dwBuildNumber & 0xFFFF);
+ this->OSVersion = operatingSystem;
+ }
+ else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1)
+ {
+ // Windows XP and .NET server.
+ typedef BOOL (CALLBACK* LPFNPROC) (HANDLE, BOOL *);
+ HINSTANCE hKernelDLL;
+ LPFNPROC DLLProc;
+
+ // Load the Kernel32 DLL.
+ hKernelDLL = LoadLibrary ("kernel32");
+ if (hKernelDLL != NULL) {
+ // Only XP and .NET Server support IsWOW64Process so... Load dynamically!
+ DLLProc = (LPFNPROC) GetProcAddress (hKernelDLL, "IsWow64Process");
+
+ // If the function address is valid, call the function.
+ if (DLLProc != NULL) (DLLProc) (GetCurrentProcess (), &bIsWindows64Bit);
+ else bIsWindows64Bit = false;
+
+ // Free the DLL module.
+ FreeLibrary (hKernelDLL);
+ }
+ }
+ else
+ {
+ // Windows 2000 and everything else.
+ sprintf (operatingSystem,"%s (Build %ld)", osvi.szCSDVersion, osvi.dwBuildNumber & 0xFFFF);
+ this->OSVersion = operatingSystem;
+ }
+ break;
+
+ case VER_PLATFORM_WIN32_WINDOWS:
+ // Test for the product.
+ if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0)
+ {
+ this->OSRelease = "95";
+ if(osvi.szCSDVersion[1] == 'C')
+ {
+ this->OSRelease += "OSR 2.5";
+ }
+ else if(osvi.szCSDVersion[1] == 'B')
+ {
+ this->OSRelease += "OSR 2";
+ }
+ }
+
+ if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10)
+ {
+ this->OSRelease = "98";
+ if (osvi.szCSDVersion[1] == 'A' )
+ {
+ this->OSRelease += "SE";
+ }
+ }
+
+ if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90)
+ {
+ this->OSRelease = "Me";
+ }
+ break;
+
+ case VER_PLATFORM_WIN32s:
+ this->OSRelease = "Win32s";
+ break;
+
+ default:
+ this->OSRelease = "Unknown";
+ break;
+ }
+
+ // Get the hostname
+ WORD wVersionRequested;
+ WSADATA wsaData;
+ char name[255];
+ wVersionRequested = MAKEWORD(2,0);
+
+ if ( WSAStartup( wVersionRequested, &wsaData ) == 0 )
+ {
+ gethostname(name,sizeof(name));
+ WSACleanup( );
+ }
+ this->Hostname = name;
+
+ const char* arch = getenv("PROCESSOR_ARCHITECTURE");
+ if(arch)
+ {
+ this->OSPlatform = arch;
+ }
+
+#else
+
+ struct utsname unameInfo;
+ int errorFlag = uname(&unameInfo);
+ if(errorFlag == 0)
+ {
+ this->OSName = unameInfo.sysname;
+ this->Hostname = unameInfo.nodename;
+ this->OSRelease = unameInfo.release;
+ this->OSVersion = unameInfo.version;
+ this->OSPlatform = unameInfo.machine;
+ }
+
+#ifdef __APPLE__
+ this->CallSwVers();
+#endif
+
+#endif
+
+ return true;
+
+}
+
+
+void SystemInformationImplementation::CallSwVers()
+{
+#ifdef __APPLE__
+ kwsys_stl::string output;
+ kwsys_stl::vector<const char*> args;
+ args.clear();
+
+ args.push_back("sw_vers");
+ args.push_back("-productName");
+ args.push_back(0);
+ output = this->RunProcess(args);
+ this->TrimNewline(output);
+ this->OSName = output;
+ args.clear();
+
+ args.push_back("sw_vers");
+ args.push_back("-productVersion");
+ args.push_back(0);
+ output = this->RunProcess(args);
+ this->TrimNewline(output);
+ this->OSRelease = output;
+ args.clear();
+
+ args.push_back("sw_vers");
+ args.push_back("-buildVersion");
+ args.push_back(0);
+ output = this->RunProcess(args);
+ this->TrimNewline(output);
+ this->OSVersion = output;
+#endif
+}
+
+
+void SystemInformationImplementation::TrimNewline(kwsys_stl::string& output)
+{
+ // remove \r
+ kwsys_stl::string::size_type pos=0;
+ while((pos = output.find("\r", pos)) != kwsys_stl::string::npos)
+ {
+ output.erase(pos);
+ }
+
+ // remove \n
+ pos = 0;
+ while((pos = output.find("\n", pos)) != kwsys_stl::string::npos)
+ {
+ output.erase(pos);
+ }
+}
+
+
+/** Return true if the machine is 64 bits */
+bool SystemInformationImplementation::Is64Bits()
+{
+ return (sizeof(void*) == 8);
+}
+
+
+} // namespace @KWSYS_NAMESPACE@
diff --git a/Source/kwsys/SystemInformation.hxx.in b/Source/kwsys/SystemInformation.hxx.in
new file mode 100644
index 000000000..b6ebe6aee
--- /dev/null
+++ b/Source/kwsys/SystemInformation.hxx.in
@@ -0,0 +1,88 @@
+/*============================================================================
+ 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@_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 <stddef.h> /* size_t */
+
+namespace @KWSYS_NAMESPACE@
+{
+
+
+// forward declare the implementation class
+class SystemInformationImplementation;
+
+class @KWSYS_NAMESPACE@_EXPORT SystemInformation
+{
+
+public:
+ SystemInformation ();
+ ~SystemInformation ();
+
+ const char * GetVendorString();
+ const char * GetVendorID();
+ kwsys_stl::string GetTypeID();
+ kwsys_stl::string GetFamilyID();
+ kwsys_stl::string GetModelID();
+ kwsys_stl::string GetSteppingCode();
+ const char * GetExtendedProcessorName();
+ const char * GetProcessorSerialNumber();
+ int GetProcessorCacheSize();
+ unsigned int GetLogicalProcessorsPerPhysical();
+ float GetProcessorClockFrequency();
+ int GetProcessorAPICID();
+ int GetProcessorCacheXSize(long int);
+ bool DoesCPUSupportFeature(long int);
+
+ const char * GetOSName();
+ const char * GetHostname();
+ const char * GetOSRelease();
+ const char * GetOSVersion();
+ const char * GetOSPlatform();
+
+ bool Is64Bits();
+
+ unsigned int GetNumberOfLogicalCPU(); // per physical cpu
+ unsigned int GetNumberOfPhysicalCPU();
+
+ bool DoesCPUSupportCPUID();
+
+ // Retrieve memory information in megabyte.
+ size_t GetTotalVirtualMemory();
+ size_t GetAvailableVirtualMemory();
+ size_t GetTotalPhysicalMemory();
+ size_t GetAvailablePhysicalMemory();
+
+ /** Run the different checks */
+ void RunCPUCheck();
+ void RunOSCheck();
+ void RunMemoryCheck();
+private:
+ SystemInformationImplementation* Implementation;
+
+};
+} // 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
new file mode 100644
index 000000000..66850e9ac
--- /dev/null
+++ b/Source/kwsys/SystemTools.cxx
@@ -0,0 +1,4856 @@
+/*============================================================================
+ 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(RegularExpression.hxx)
+#include KWSYS_HEADER(SystemTools.hxx)
+#include KWSYS_HEADER(Directory.hxx)
+
+#include KWSYS_HEADER(ios/iostream)
+#include KWSYS_HEADER(ios/fstream)
+#include KWSYS_HEADER(ios/sstream)
+
+#include KWSYS_HEADER(stl/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"
+#endif
+
+#ifdef _MSC_VER
+# pragma warning (disable: 4786)
+#endif
+
+#if defined(__sgi) && !defined(__GNUC__)
+# pragma set woff 1375 /* base class destructor not virtual */
+#endif
+
+#include <ctype.h>
+#include <errno.h>
+#ifdef __QNX__
+# include <malloc.h> /* for malloc/free on QNX */
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <time.h>
+
+// support for realpath call
+#ifndef _WIN32
+#include <sys/time.h>
+#include <utime.h>
+#include <limits.h>
+#include <sys/wait.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <pwd.h>
+#ifndef __VMS
+#include <sys/param.h>
+#include <termios.h>
+#endif
+#include <signal.h> /* sigprocmask */
+#endif
+
+// Windows API.
+#if defined(_WIN32)
+# include <windows.h>
+#elif defined (__CYGWIN__)
+# include <windows.h>
+# undef _WIN32
+#endif
+
+#if !KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H
+extern char **environ;
+#endif
+
+#ifdef __CYGWIN__
+extern "C" void cygwin_conv_to_win32_path(const char *path, char *win32_path);
+#endif
+
+// getpwnam doesn't exist on Windows and Cray Xt3/Catamount
+// same for TIOCGWINSZ
+#if defined(_WIN32) || defined (__LIBCATAMOUNT__)
+# undef HAVE_GETPWNAM
+# undef HAVE_TTY_INFO
+#else
+# define HAVE_GETPWNAM 1
+# define HAVE_TTY_INFO 1
+#endif
+
+#define VTK_URL_PROTOCOL_REGEX "([a-zA-Z0-9]*)://(.*)"
+#define VTK_URL_REGEX "([a-zA-Z0-9]*)://(([A-Za-z0-9]+)(:([^:@]+))?@)?([^:@/]+)(:([0-9]+))?/(.+)?"
+
+#ifdef _MSC_VER
+#include <sys/utime.h>
+#else
+#include <utime.h>
+#endif
+
+
+// This is a hack to prevent warnings about these functions being
+// declared but not referenced.
+#if defined(__sgi) && !defined(__GNUC__)
+# include <sys/termios.h>
+namespace KWSYS_NAMESPACE
+{
+class SystemToolsHack
+{
+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
+
+#if defined(_WIN32) && (defined(_MSC_VER) || defined(__WATCOMC__) ||defined(__BORLANDC__) || defined(__MINGW32__))
+#include <io.h>
+#include <direct.h>
+#define _unlink unlink
+#endif
+
+/* The maximum length of a file name. */
+#if defined(PATH_MAX)
+# define KWSYS_SYSTEMTOOLS_MAXPATH PATH_MAX
+#elif defined(MAXPATHLEN)
+# define KWSYS_SYSTEMTOOLS_MAXPATH MAXPATHLEN
+#else
+# define KWSYS_SYSTEMTOOLS_MAXPATH 16384
+#endif
+#if defined(__WATCOMC__)
+#include <direct.h>
+#define _mkdir mkdir
+#define _rmdir rmdir
+#define _getcwd getcwd
+#define _chdir chdir
+#endif
+
+#if defined(__HAIKU__)
+#include <os/kernel/OS.h>
+#include <os/storage/Path.h>
+#endif
+
+#if defined(__BEOS__) && !defined(__ZETA__) && !defined(__HAIKU__)
+#include <be/kernel/OS.h>
+#include <be/storage/Path.h>
+
+// BeOS 5 doesn't have usleep(), but it has snooze(), which is identical.
+static inline void usleep(unsigned int msec)
+{
+ ::snooze(msec);
+}
+
+// BeOS 5 also doesn't have realpath(), but its C++ API offers something close.
+static inline char *realpath(const char *path, char *resolved_path)
+{
+ const size_t maxlen = KWSYS_SYSTEMTOOLS_MAXPATH;
+ snprintf(resolved_path, maxlen, "%s", path);
+ BPath normalized(resolved_path, NULL, true);
+ const char *resolved = normalized.Path();
+ if (resolved != NULL) // NULL == No such file.
+ {
+ if (snprintf(resolved_path, maxlen, "%s", resolved) < maxlen)
+ {
+ return resolved_path;
+ }
+ }
+ return NULL; // something went wrong.
+}
+#endif
+
+#if defined(_WIN32) && (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__) || defined(__MINGW32__))
+inline int Mkdir(const char* dir)
+{
+ return _mkdir(dir);
+}
+inline int Rmdir(const char* dir)
+{
+ return _rmdir(dir);
+}
+inline const char* Getcwd(char* buf, unsigned int len)
+{
+ const char* ret = _getcwd(buf, len);
+ if(!ret)
+ {
+ fprintf(stderr, "No current working directory.\n");
+ abort();
+ }
+ // make sure the drive letter is capital
+ if(strlen(buf) > 1 && buf[1] == ':')
+ {
+ buf[0] = toupper(buf[0]);
+ }
+ return ret;
+}
+inline int Chdir(const char* dir)
+{
+ #if defined(__BORLANDC__)
+ return chdir(dir);
+ #else
+ return _chdir(dir);
+ #endif
+}
+inline void Realpath(const char *path, kwsys_stl::string & resolved_path)
+{
+ char *ptemp;
+ char fullpath[MAX_PATH];
+ if( GetFullPathName(path, sizeof(fullpath), fullpath, &ptemp) )
+ {
+ resolved_path = fullpath;
+ KWSYS_NAMESPACE::SystemTools::ConvertToUnixSlashes(resolved_path);
+ }
+ else
+ {
+ resolved_path = path;
+ }
+}
+#else
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+inline int Mkdir(const char* dir)
+{
+ return mkdir(dir, 00777);
+}
+inline int Rmdir(const char* dir)
+{
+ return rmdir(dir);
+}
+inline const char* Getcwd(char* buf, unsigned int len)
+{
+ const char* ret = getcwd(buf, len);
+ if(!ret)
+ {
+ fprintf(stderr, "No current working directory\n");
+ abort();
+ }
+ return ret;
+}
+
+inline int Chdir(const char* dir)
+{
+ return chdir(dir);
+}
+inline void Realpath(const char *path, kwsys_stl::string & resolved_path)
+{
+ char resolved_name[KWSYS_SYSTEMTOOLS_MAXPATH];
+
+ char *ret = realpath(path, resolved_name);
+ if(ret)
+ {
+ resolved_path = ret;
+ }
+ else
+ {
+ // if path resolution fails, return what was passed in
+ resolved_path = path;
+ }
+}
+#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
+
+namespace KWSYS_NAMESPACE
+{
+
+double SystemTools::GetTime(void)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ FILETIME ft;
+ GetSystemTimeAsFileTime(&ft);
+ return (429.4967296*ft.dwHighDateTime
+ + 0.0000001*ft.dwLowDateTime
+ - 11644473600.0);
+#else
+ struct timeval t;
+ gettimeofday(&t, 0);
+ return 1.0*double(t.tv_sec) + 0.000001*double(t.tv_usec);
+#endif
+}
+
+class SystemToolsTranslationMap :
+ public kwsys_stl::map<kwsys_stl::string,kwsys_stl::string>
+{
+};
+
+// 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)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ const char* pathSep = ";";
+#else
+ const char* pathSep = ":";
+#endif
+ if(!env)
+ {
+ env = "PATH";
+ }
+ const char* cpathEnv = SystemTools::GetEnv(env);
+ if ( !cpathEnv )
+ {
+ return;
+ }
+
+ kwsys_stl::string pathEnv = cpathEnv;
+
+ // A hack to make the below algorithm work.
+ if(!pathEnv.empty() && pathEnv[pathEnv.length()-1] != pathSep[0])
+ {
+ pathEnv += pathSep;
+ }
+ kwsys_stl::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)
+ {
+ path.push_back(pathEnv.substr(start, endpos-start));
+ start = endpos+1;
+ }
+ else
+ {
+ done = true;
+ }
+ }
+ for(kwsys_stl::vector<kwsys_stl::string>::iterator i = path.begin();
+ i != path.end(); ++i)
+ {
+ SystemTools::ConvertToUnixSlashes(*i);
+ }
+}
+
+const char* SystemTools::GetEnv(const char* key)
+{
+ return getenv(key);
+}
+
+bool SystemTools::GetEnv(const char* key, kwsys_stl::string& result)
+{
+ const char* v = getenv(key);
+ if(v)
+ {
+ result = v;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+//----------------------------------------------------------------------------
+
+#if defined(__CYGWIN__) || defined(__GLIBC__)
+# define KWSYS_PUTENV_NAME /* putenv("A") removes A. */
+#elif defined(_WIN32)
+# define KWSYS_PUTENV_EMPTY /* putenv("A=") removes A. */
+#endif
+
+#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)
+{
+ if(const char* eq = strchr(env, '='))
+ {
+ std::string name(env, eq-env);
+ unsetenv(name.c_str());
+ }
+ else
+ {
+ unsetenv(env);
+ }
+ 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)
+{
+ int err = 0;
+ const char* eq = strchr(env, '=');
+ size_t const len = eq? (size_t)(eq-env) : strlen(env);
+# ifdef KWSYS_PUTENV_EMPTY
+ size_t const sz = len + 2;
+# else
+ size_t const sz = len + 1;
+# endif
+ char local_buf[256];
+ char* buf = sz > sizeof(local_buf) ? (char*)malloc(sz) : local_buf;
+ if(!buf)
+ {
+ return -1;
+ }
+ strncpy(buf, env, len);
+# ifdef KWSYS_PUTENV_EMPTY
+ buf[len] = '=';
+ buf[len+1] = 0;
+ if(putenv(buf) < 0)
+ {
+ err = errno;
+ }
+# else
+ buf[len] = 0;
+ if(putenv(buf) < 0 && errno != EINVAL)
+ {
+ err = errno;
+ }
+# endif
+ if(buf != local_buf)
+ {
+ free(buf);
+ }
+ if(err)
+ {
+ errno = err;
+ return -1;
+ }
+ return 0;
+}
+
+#else
+/* Manipulate the "environ" global directly. */
+static int kwsysUnPutEnv(const char* env)
+{
+ const char* eq = strchr(env, '=');
+ size_t const len = eq? (size_t)(eq-env) : strlen(env);
+ int in = 0;
+ int out = 0;
+ while(environ[in])
+ {
+ if(strlen(environ[in]) > len &&
+ environ[in][len] == '=' &&
+ strncmp(env, environ[in], len) == 0)
+ {
+ ++in;
+ }
+ else
+ {
+ environ[out++] = environ[in++];
+ }
+ }
+ while(out < in)
+ {
+ environ[out++] = 0;
+ }
+ return 0;
+}
+#endif
+
+//----------------------------------------------------------------------------
+
+#if KWSYS_CXX_HAS_SETENV
+
+/* 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)
+{
+ if(const char* eq = strchr(env, '='))
+ {
+ std::string name(env, eq-env);
+ return setenv(name.c_str(), eq+1, 1) == 0;
+ }
+ else
+ {
+ return kwsysUnPutEnv(env) == 0;
+ }
+}
+
+bool SystemTools::UnPutEnv(const char* env)
+{
+ return kwsysUnPutEnv(env) == 0;
+}
+
+#else
+
+/* putenv("A=B") will set A=B in the environment. Most putenv implementations
+ put their argument directly in the environment. They never free the memory
+ on program exit. Keep an active set of pointers to memory we allocate and
+ pass to putenv, one per environment key. At program exit remove any
+ environment values that may still reference memory we allocated. Then free
+ the memory. This will not affect any environment values we never set. */
+
+# ifdef __INTEL_COMPILER
+# pragma warning disable 444 /* base has non-virtual destructor */
+# endif
+
+/* Order by environment key only (VAR from VAR=VALUE). */
+struct kwsysEnvCompare
+{
+ bool operator() (const char* l, const char* r) const
+ {
+ const char* leq = strchr(l, '=');
+ const char* req = strchr(r, '=');
+ size_t llen = leq? (leq-l) : strlen(l);
+ size_t rlen = req? (req-r) : strlen(r);
+ if(llen == rlen)
+ {
+ return strncmp(l,r,llen) < 0;
+ }
+ else
+ {
+ return strcmp(l,r) < 0;
+ }
+ }
+};
+
+class kwsysEnv: public kwsys_stl::set<const char*, kwsysEnvCompare>
+{
+ class Free
+ {
+ const char* Env;
+ public:
+ Free(const char* env): Env(env) {}
+ ~Free() { free(const_cast<char*>(this->Env)); }
+ };
+public:
+ typedef kwsys_stl::set<const char*, kwsysEnvCompare> derived;
+ ~kwsysEnv()
+ {
+ for(derived::iterator i = this->begin(); i != this->end(); ++i)
+ {
+ kwsysUnPutEnv(*i);
+ free(const_cast<char*>(*i));
+ }
+ }
+ const char* Release(const char* env)
+ {
+ const char* old = 0;
+ derived::iterator i = this->find(env);
+ if(i != this->end())
+ {
+ old = *i;
+ this->erase(i);
+ }
+ return old;
+ }
+ bool Put(const char* env)
+ {
+ Free oldEnv(this->Release(env));
+ static_cast<void>(oldEnv);
+ char* newEnv = strdup(env);
+ this->insert(newEnv);
+ return putenv(newEnv) == 0;
+ }
+ bool UnPut(const char* env)
+ {
+ Free oldEnv(this->Release(env));
+ static_cast<void>(oldEnv);
+ return kwsysUnPutEnv(env) == 0;
+ }
+};
+
+static kwsysEnv kwsysEnvInstance;
+
+bool SystemTools::PutEnv(const char* env)
+{
+ return kwsysEnvInstance.Put(env);
+}
+
+bool SystemTools::UnPutEnv(const char* env)
+{
+ return kwsysEnvInstance.UnPut(env);
+}
+
+#endif
+
+//----------------------------------------------------------------------------
+
+const char* SystemTools::GetExecutableExtension()
+{
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(__VMS)
+ return ".exe";
+#else
+ return "";
+#endif
+}
+
+
+bool SystemTools::MakeDirectory(const char* path)
+{
+ if(!path)
+ {
+ return false;
+ }
+ if(SystemTools::FileExists(path))
+ {
+ return true;
+ }
+ kwsys_stl::string dir = path;
+ if(dir.size() == 0)
+ {
+ return false;
+ }
+ SystemTools::ConvertToUnixSlashes(dir);
+
+ kwsys_stl::string::size_type pos = dir.find(':');
+ if(pos == kwsys_stl::string::npos)
+ {
+ pos = 0;
+ }
+ kwsys_stl::string topdir;
+ while((pos = dir.find('/', pos)) != kwsys_stl::string::npos)
+ {
+ topdir = dir.substr(0, pos);
+ Mkdir(topdir.c_str());
+ pos++;
+ }
+ if(dir[dir.size()-1] == '/')
+ {
+ topdir = dir.substr(0, dir.size());
+ }
+ else
+ {
+ topdir = dir;
+ }
+ if(Mkdir(topdir.c_str()) != 0)
+ {
+ // There is a bug in the Borland Run time library which makes MKDIR
+ // return EACCES when it should return EEXISTS
+ // if it is some other error besides directory exists
+ // then return false
+ if( (errno != EEXIST)
+#ifdef __BORLANDC__
+ && (errno != EACCES)
+#endif
+ )
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+
+// 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)
+{
+ const char *src = source.c_str();
+ char *searchPos = const_cast<char *>(strstr(src,replace));
+
+ // get out quick if string is not found
+ if (!searchPos)
+ {
+ return;
+ }
+
+ // 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;
+
+ // initialize the result
+ source.erase(source.begin(),source.end());
+ do
+ {
+ *searchPos = '\0';
+ source += currentPos;
+ currentPos = searchPos + replaceSize;
+ // replace
+ source += with;
+ searchPos = strstr(currentPos,replace);
+ }
+ while (searchPos);
+
+ // copy any trailing text
+ source += currentPos;
+ free(orig);
+}
+
+#if defined(KEY_WOW64_32KEY) && defined(KEY_WOW64_64KEY)
+# define KWSYS_ST_KEY_WOW64_32KEY KEY_WOW64_32KEY
+# define KWSYS_ST_KEY_WOW64_64KEY KEY_WOW64_64KEY
+#else
+# define KWSYS_ST_KEY_WOW64_32KEY 0x0200
+# define KWSYS_ST_KEY_WOW64_64KEY 0x0100
+#endif
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+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"),
+ "IsWow64Process");
+ if(wow64p == NULL)
+ {
+ return mode;
+ }
+
+ if(view == SystemTools::KeyWOW64_32)
+ {
+ return mode | KWSYS_ST_KEY_WOW64_32KEY;
+ }
+ else if(view == SystemTools::KeyWOW64_64)
+ {
+ return mode | KWSYS_ST_KEY_WOW64_64KEY;
+ }
+ return mode;
+}
+#endif
+
+// Read a registry value.
+// Example :
+// HKEY_LOCAL_MACHINE\SOFTWARE\Python\PythonCore\2.1\InstallPath
+// => will return the data of the "default" value of the key
+// HKEY_LOCAL_MACHINE\SOFTWARE\Scriptics\Tcl\8.4;Root
+// => 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,
+ KeyWOW64 view)
+{
+ bool valueset = false;
+ kwsys_stl::string primary = key;
+ kwsys_stl::string second;
+ kwsys_stl::string valuename;
+
+ size_t start = primary.find("\\");
+ if (start == kwsys_stl::string::npos)
+ {
+ return false;
+ }
+
+ size_t valuenamepos = primary.find(";");
+ if (valuenamepos != kwsys_stl::string::npos)
+ {
+ valuename = primary.substr(valuenamepos+1);
+ }
+
+ second = primary.substr(start+1, valuenamepos-start-1);
+ primary = primary.substr(0, start);
+
+ HKEY primaryKey = HKEY_CURRENT_USER;
+ if (primary == "HKEY_CURRENT_USER")
+ {
+ primaryKey = HKEY_CURRENT_USER;
+ }
+ if (primary == "HKEY_CURRENT_CONFIG")
+ {
+ primaryKey = HKEY_CURRENT_CONFIG;
+ }
+ if (primary == "HKEY_CLASSES_ROOT")
+ {
+ primaryKey = HKEY_CLASSES_ROOT;
+ }
+ if (primary == "HKEY_LOCAL_MACHINE")
+ {
+ primaryKey = HKEY_LOCAL_MACHINE;
+ }
+ if (primary == "HKEY_USERS")
+ {
+ primaryKey = HKEY_USERS;
+ }
+
+ HKEY hKey;
+ if(RegOpenKeyEx(primaryKey,
+ second.c_str(),
+ 0,
+ SystemToolsMakeRegistryMode(KEY_READ, view),
+ &hKey) != ERROR_SUCCESS)
+ {
+ return false;
+ }
+ else
+ {
+ DWORD dwType, dwSize;
+ dwSize = 1023;
+ char data[1024];
+ if(RegQueryValueEx(hKey,
+ (LPTSTR)valuename.c_str(),
+ NULL,
+ &dwType,
+ (BYTE *)data,
+ &dwSize) == ERROR_SUCCESS)
+ {
+ if (dwType == REG_SZ)
+ {
+ value = data;
+ valueset = true;
+ }
+ else if (dwType == REG_EXPAND_SZ)
+ {
+ char expanded[1024];
+ DWORD dwExpandedSize = sizeof(expanded)/sizeof(expanded[0]);
+ if(ExpandEnvironmentStrings(data, expanded, dwExpandedSize))
+ {
+ value = expanded;
+ valueset = true;
+ }
+ }
+ }
+
+ RegCloseKey(hKey);
+ }
+
+ return valueset;
+}
+#else
+bool SystemTools::ReadRegistryValue(const char *, kwsys_stl::string &,
+ KeyWOW64)
+{
+ return false;
+}
+#endif
+
+
+// Write a registry value.
+// Example :
+// HKEY_LOCAL_MACHINE\SOFTWARE\Python\PythonCore\2.1\InstallPath
+// => will set the data of the "default" value of the key
+// HKEY_LOCAL_MACHINE\SOFTWARE\Scriptics\Tcl\8.4;Root
+// => 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,
+ KeyWOW64 view)
+{
+ kwsys_stl::string primary = key;
+ kwsys_stl::string second;
+ kwsys_stl::string valuename;
+
+ size_t start = primary.find("\\");
+ if (start == kwsys_stl::string::npos)
+ {
+ return false;
+ }
+
+ size_t valuenamepos = primary.find(";");
+ if (valuenamepos != kwsys_stl::string::npos)
+ {
+ valuename = primary.substr(valuenamepos+1);
+ }
+
+ second = primary.substr(start+1, valuenamepos-start-1);
+ primary = primary.substr(0, start);
+
+ HKEY primaryKey = HKEY_CURRENT_USER;
+ if (primary == "HKEY_CURRENT_USER")
+ {
+ primaryKey = HKEY_CURRENT_USER;
+ }
+ if (primary == "HKEY_CURRENT_CONFIG")
+ {
+ primaryKey = HKEY_CURRENT_CONFIG;
+ }
+ if (primary == "HKEY_CLASSES_ROOT")
+ {
+ primaryKey = HKEY_CLASSES_ROOT;
+ }
+ if (primary == "HKEY_LOCAL_MACHINE")
+ {
+ primaryKey = HKEY_LOCAL_MACHINE;
+ }
+ if (primary == "HKEY_USERS")
+ {
+ primaryKey = HKEY_USERS;
+ }
+
+ HKEY hKey;
+ DWORD dwDummy;
+ char lpClass[] = "";
+ if(RegCreateKeyEx(primaryKey,
+ second.c_str(),
+ 0,
+ lpClass,
+ REG_OPTION_NON_VOLATILE,
+ SystemToolsMakeRegistryMode(KEY_WRITE, view),
+ NULL,
+ &hKey,
+ &dwDummy) != ERROR_SUCCESS)
+ {
+ return false;
+ }
+
+ if(RegSetValueEx(hKey,
+ (LPTSTR)valuename.c_str(),
+ 0,
+ REG_SZ,
+ (CONST BYTE *)value,
+ (DWORD)(strlen(value) + 1)) == ERROR_SUCCESS)
+ {
+ return true;
+ }
+ return false;
+}
+#else
+bool SystemTools::WriteRegistryValue(const char *, const char *, KeyWOW64)
+{
+ return false;
+}
+#endif
+
+// Delete a registry value.
+// Example :
+// HKEY_LOCAL_MACHINE\SOFTWARE\Python\PythonCore\2.1\InstallPath
+// => will delete the data of the "default" value of the key
+// HKEY_LOCAL_MACHINE\SOFTWARE\Scriptics\Tcl\8.4;Root
+// => will delete the data of the "Root" value of the key
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+bool SystemTools::DeleteRegistryValue(const char *key, KeyWOW64 view)
+{
+ kwsys_stl::string primary = key;
+ kwsys_stl::string second;
+ kwsys_stl::string valuename;
+
+ size_t start = primary.find("\\");
+ if (start == kwsys_stl::string::npos)
+ {
+ return false;
+ }
+
+ size_t valuenamepos = primary.find(";");
+ if (valuenamepos != kwsys_stl::string::npos)
+ {
+ valuename = primary.substr(valuenamepos+1);
+ }
+
+ second = primary.substr(start+1, valuenamepos-start-1);
+ primary = primary.substr(0, start);
+
+ HKEY primaryKey = HKEY_CURRENT_USER;
+ if (primary == "HKEY_CURRENT_USER")
+ {
+ primaryKey = HKEY_CURRENT_USER;
+ }
+ if (primary == "HKEY_CURRENT_CONFIG")
+ {
+ primaryKey = HKEY_CURRENT_CONFIG;
+ }
+ if (primary == "HKEY_CLASSES_ROOT")
+ {
+ primaryKey = HKEY_CLASSES_ROOT;
+ }
+ if (primary == "HKEY_LOCAL_MACHINE")
+ {
+ primaryKey = HKEY_LOCAL_MACHINE;
+ }
+ if (primary == "HKEY_USERS")
+ {
+ primaryKey = HKEY_USERS;
+ }
+
+ HKEY hKey;
+ if(RegOpenKeyEx(primaryKey,
+ second.c_str(),
+ 0,
+ SystemToolsMakeRegistryMode(KEY_WRITE, view),
+ &hKey) != ERROR_SUCCESS)
+ {
+ return false;
+ }
+ else
+ {
+ if(RegDeleteValue(hKey,
+ (LPTSTR)valuename.c_str()) == ERROR_SUCCESS)
+ {
+ RegCloseKey(hKey);
+ return true;
+ }
+ }
+ return false;
+}
+#else
+bool SystemTools::DeleteRegistryValue(const char *, KeyWOW64)
+{
+ return false;
+}
+#endif
+
+bool SystemTools::SameFile(const char* file1, const char* file2)
+{
+#ifdef _WIN32
+ HANDLE hFile1, hFile2;
+
+ hFile1 = CreateFile( file1,
+ GENERIC_READ,
+ FILE_SHARE_READ ,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS,
+ NULL
+ );
+ hFile2 = CreateFile( file2,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS,
+ NULL
+ );
+ if( hFile1 == INVALID_HANDLE_VALUE || hFile2 == INVALID_HANDLE_VALUE)
+ {
+ if(hFile1 != INVALID_HANDLE_VALUE)
+ {
+ CloseHandle(hFile1);
+ }
+ if(hFile2 != INVALID_HANDLE_VALUE)
+ {
+ CloseHandle(hFile2);
+ }
+ return false;
+ }
+
+ BY_HANDLE_FILE_INFORMATION fiBuf1;
+ BY_HANDLE_FILE_INFORMATION fiBuf2;
+ GetFileInformationByHandle( hFile1, &fiBuf1 );
+ GetFileInformationByHandle( hFile2, &fiBuf2 );
+ CloseHandle(hFile1);
+ CloseHandle(hFile2);
+ return (fiBuf1.dwVolumeSerialNumber == fiBuf2.dwVolumeSerialNumber &&
+ fiBuf1.nFileIndexHigh == fiBuf2.nFileIndexHigh &&
+ fiBuf1.nFileIndexLow == fiBuf2.nFileIndexLow);
+#else
+ struct stat fileStat1, fileStat2;
+ if (stat(file1, &fileStat1) == 0 && stat(file2, &fileStat2) == 0)
+ {
+ // see if the files are the same file
+ // check the device inode and size
+ if(memcmp(&fileStat2.st_dev, &fileStat1.st_dev, sizeof(fileStat1.st_dev)) == 0 &&
+ memcmp(&fileStat2.st_ino, &fileStat1.st_ino, sizeof(fileStat1.st_ino)) == 0 &&
+ fileStat2.st_size == fileStat1.st_size
+ )
+ {
+ return true;
+ }
+ }
+ return false;
+#endif
+}
+
+//----------------------------------------------------------------------------
+#if defined(_WIN32) || defined(__CYGWIN__)
+static bool WindowsFileExists(const char* filename)
+{
+ WIN32_FILE_ATTRIBUTE_DATA fd;
+ return GetFileAttributesExA(filename, GetFileExInfoStandard, &fd) != 0;
+}
+#endif
+
+//----------------------------------------------------------------------------
+bool SystemTools::FileExists(const char* filename)
+{
+ if(!(filename && *filename))
+ {
+ return false;
+ }
+#if defined(__CYGWIN__)
+ // Convert filename to native windows path if possible.
+ char winpath[MAX_PATH];
+ if(SystemTools::PathCygwinToWin32(filename, winpath))
+ {
+ return WindowsFileExists(winpath);
+ }
+ return access(filename, R_OK) == 0;
+#elif defined(_WIN32)
+ return WindowsFileExists(filename);
+#else
+ return access(filename, R_OK) == 0;
+#endif
+}
+
+//----------------------------------------------------------------------------
+bool SystemTools::FileExists(const char* filename, bool isFile)
+{
+ if(SystemTools::FileExists(filename))
+ {
+ // If isFile is set return not FileIsDirectory,
+ // so this will only be true if it is a file
+ return !isFile || !SystemTools::FileIsDirectory(filename);
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+#ifdef __CYGWIN__
+bool SystemTools::PathCygwinToWin32(const char *path, char *win32_path)
+{
+ SystemToolsTranslationMap::iterator i =
+ SystemTools::Cyg2Win32Map->find(path);
+
+ if (i != SystemTools::Cyg2Win32Map->end())
+ {
+ strncpy(win32_path, i->second.c_str(), MAX_PATH);
+ }
+ else
+ {
+ cygwin_conv_to_win32_path(path, win32_path);
+ SystemToolsTranslationMap::value_type entry(path, win32_path);
+ SystemTools::Cyg2Win32Map->insert(entry);
+ }
+ return win32_path[0] != 0;
+}
+#endif
+
+bool SystemTools::Touch(const char* filename, bool create)
+{
+ if(create && !SystemTools::FileExists(filename))
+ {
+ FILE* file = fopen(filename, "a+b");
+ if(file)
+ {
+ fclose(file);
+ return true;
+ }
+ return false;
+ }
+#ifdef _MSC_VER
+#define utime _utime
+#define utimbuf _utimbuf
+#endif
+ struct stat fromStat;
+ if(stat(filename, &fromStat) < 0)
+ {
+ return false;
+ }
+ struct utimbuf buf;
+ buf.actime = fromStat.st_atime;
+ buf.modtime = static_cast<time_t>(SystemTools::GetTime());
+ if(utime(filename, &buf) < 0)
+ {
+ return false;
+ }
+ return true;
+}
+
+bool SystemTools::FileTimeCompare(const char* f1, const char* f2,
+ int* result)
+{
+ // Default to same time.
+ *result = 0;
+#if !defined(_WIN32) || defined(__CYGWIN__)
+ // POSIX version. Use stat function to get file modification time.
+ struct stat s1;
+ if(stat(f1, &s1) != 0)
+ {
+ return false;
+ }
+ struct stat s2;
+ if(stat(f2, &s2) != 0)
+ {
+ return false;
+ }
+# if KWSYS_STAT_HAS_ST_MTIM
+ // Compare using nanosecond resolution.
+ if(s1.st_mtim.tv_sec < s2.st_mtim.tv_sec)
+ {
+ *result = -1;
+ }
+ else if(s1.st_mtim.tv_sec > s2.st_mtim.tv_sec)
+ {
+ *result = 1;
+ }
+ else if(s1.st_mtim.tv_nsec < s2.st_mtim.tv_nsec)
+ {
+ *result = -1;
+ }
+ else if(s1.st_mtim.tv_nsec > s2.st_mtim.tv_nsec)
+ {
+ *result = 1;
+ }
+# else
+ // Compare using 1 second resolution.
+ if(s1.st_mtime < s2.st_mtime)
+ {
+ *result = -1;
+ }
+ else if(s1.st_mtime > s2.st_mtime)
+ {
+ *result = 1;
+ }
+# endif
+#else
+ // 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))
+ {
+ return false;
+ }
+ if(!GetFileAttributesEx(f2, GetFileExInfoStandard, &f2d))
+ {
+ return false;
+ }
+
+ // Compare the file times using resolution provided by system call.
+ *result = (int)CompareFileTime(&f1d.ftLastWriteTime, &f2d.ftLastWriteTime);
+#endif
+ return true;
+}
+
+
+// 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)
+{
+ kwsys_stl::string n;
+ if(s.size() == 0)
+ {
+ return n;
+ }
+ n.resize(s.size());
+ n[0] = static_cast<kwsys_stl::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]));
+ }
+ return n;
+}
+
+// Return capitalized words
+kwsys_stl::string SystemTools::CapitalizedWords(const kwsys_stl::string& s)
+{
+ kwsys_stl::string n(s);
+ for (size_t i = 0; i < s.size(); i++)
+ {
+#if defined(_MSC_VER) && defined (_MT) && defined (_DEBUG)
+ // MS has an assert that will fail if s[i] < 0; setting
+ // LC_CTYPE using setlocale() does *not* help. Painful.
+ if ((int)s[i] >= 0 && isalpha(s[i]) &&
+ (i == 0 || ((int)s[i - 1] >= 0 && isspace(s[i - 1]))))
+#else
+ if (isalpha(s[i]) && (i == 0 || isspace(s[i - 1])))
+#endif
+ {
+ n[i] = static_cast<kwsys_stl::string::value_type>(toupper(s[i]));
+ }
+ }
+ return n;
+}
+
+// Return uncapitalized words
+kwsys_stl::string SystemTools::UnCapitalizedWords(const kwsys_stl::string& s)
+{
+ kwsys_stl::string n(s);
+ for (size_t i = 0; i < s.size(); i++)
+ {
+#if defined(_MSC_VER) && defined (_MT) && defined (_DEBUG)
+ // MS has an assert that will fail if s[i] < 0; setting
+ // LC_CTYPE using setlocale() does *not* help. Painful.
+ if ((int)s[i] >= 0 && isalpha(s[i]) &&
+ (i == 0 || ((int)s[i - 1] >= 0 && isspace(s[i - 1]))))
+#else
+ if (isalpha(s[i]) && (i == 0 || isspace(s[i - 1])))
+#endif
+ {
+ n[i] = static_cast<kwsys_stl::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)
+{
+ kwsys_stl::string n;
+ if (s.size())
+ {
+ n.reserve(s.size());
+ n += s[0];
+ for (size_t i = 1; i < s.size(); i++)
+ {
+ if (isupper(s[i]) && !isspace(s[i - 1]) && !isupper(s[i - 1]))
+ {
+ n += ' ';
+ }
+ n += s[i];
+ }
+ }
+ return n;
+}
+
+char* SystemTools::AppendStrings(const char* str1, const char* str2)
+{
+ if (!str1)
+ {
+ return SystemTools::DuplicateString(str2);
+ }
+ if (!str2)
+ {
+ return SystemTools::DuplicateString(str1);
+ }
+ size_t len1 = strlen(str1);
+ char *newstr = new char[len1 + strlen(str2) + 1];
+ if (!newstr)
+ {
+ return 0;
+ }
+ strcpy(newstr, str1);
+ strcat(newstr + len1, str2);
+ return newstr;
+}
+
+char* SystemTools::AppendStrings(
+ const char* str1, const char* str2, const char* str3)
+{
+ if (!str1)
+ {
+ return SystemTools::AppendStrings(str2, str3);
+ }
+ if (!str2)
+ {
+ return SystemTools::AppendStrings(str1, str3);
+ }
+ if (!str3)
+ {
+ return SystemTools::AppendStrings(str1, str2);
+ }
+
+ size_t len1 = strlen(str1), len2 = strlen(str2);
+ char *newstr = new char[len1 + len2 + strlen(str3) + 1];
+ if (!newstr)
+ {
+ return 0;
+ }
+ strcpy(newstr, str1);
+ strcat(newstr + len1, str2);
+ strcat(newstr + len1 + len2, str3);
+ return newstr;
+}
+
+// Return a lower case string
+kwsys_stl::string SystemTools::LowerCase(const kwsys_stl::string& s)
+{
+ kwsys_stl::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]));
+ }
+ return n;
+}
+
+// Return a lower case string
+kwsys_stl::string SystemTools::UpperCase(const kwsys_stl::string& s)
+{
+ kwsys_stl::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]));
+ }
+ return n;
+}
+
+// Count char in string
+size_t SystemTools::CountChar(const char* str, char c)
+{
+ size_t count = 0;
+
+ if (str)
+ {
+ while (*str)
+ {
+ if (*str == c)
+ {
+ ++count;
+ }
+ ++str;
+ }
+ }
+ return count;
+}
+
+// Remove chars in string
+char* SystemTools::RemoveChars(const char* str, const char *toremove)
+{
+ if (!str)
+ {
+ return NULL;
+ }
+ char *clean_str = new char [strlen(str) + 1];
+ char *ptr = clean_str;
+ while (*str)
+ {
+ const char *str2 = toremove;
+ while (*str2 && *str != *str2)
+ {
+ ++str2;
+ }
+ if (!*str2)
+ {
+ *ptr++ = *str;
+ }
+ ++str;
+ }
+ *ptr = '\0';
+ return clean_str;
+}
+
+// Remove chars in string
+char* SystemTools::RemoveCharsButUpperHex(const char* str)
+{
+ if (!str)
+ {
+ return 0;
+ }
+ char *clean_str = new char [strlen(str) + 1];
+ char *ptr = clean_str;
+ while (*str)
+ {
+ if ((*str >= '0' && *str <= '9') || (*str >= 'A' && *str <= 'F'))
+ {
+ *ptr++ = *str;
+ }
+ ++str;
+ }
+ *ptr = '\0';
+ return clean_str;
+}
+
+// Replace chars in string
+char* SystemTools::ReplaceChars(char* str, const char *toreplace, char replacement)
+{
+ if (str)
+ {
+ char *ptr = str;
+ while (*ptr)
+ {
+ const char *ptr2 = toreplace;
+ while (*ptr2)
+ {
+ if (*ptr == *ptr2)
+ {
+ *ptr = replacement;
+ }
+ ++ptr2;
+ }
+ ++ptr;
+ }
+ }
+ return str;
+}
+
+// Returns if string starts with another string
+bool SystemTools::StringStartsWith(const char* str1, const char* str2)
+{
+ if (!str1 || !str2)
+ {
+ return false;
+ }
+ size_t len1 = strlen(str1), len2 = strlen(str2);
+ return len1 >= len2 && !strncmp(str1, str2, len2) ? true : false;
+}
+
+// Returns if string ends with another string
+bool SystemTools::StringEndsWith(const char* str1, const char* str2)
+{
+ if (!str1 || !str2)
+ {
+ return false;
+ }
+ size_t len1 = strlen(str1), len2 = strlen(str2);
+ return len1 >= len2 && !strncmp(str1 + (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)
+{
+ if (!str1 || !str2)
+ {
+ return NULL;
+ }
+
+ size_t len1 = strlen(str1), len2 = strlen(str2);
+ if (len1 >= len2)
+ {
+ const char *ptr = str1 + len1 - len2;
+ do
+ {
+ if (!strncmp(ptr, str2, len2))
+ {
+ return ptr;
+ }
+ } while (ptr-- != str1);
+ }
+
+ return NULL;
+}
+
+// Duplicate string
+char* SystemTools::DuplicateString(const char* str)
+{
+ if (str)
+ {
+ char *newstr = new char [strlen(str) + 1];
+ return strcpy(newstr, str);
+ }
+ return NULL;
+}
+
+// Return a cropped string
+kwsys_stl::string SystemTools::CropString(const kwsys_stl::string& s,
+ size_t max_len)
+{
+ if (!s.size() || max_len == 0 || max_len >= s.size())
+ {
+ return s;
+ }
+
+ kwsys_stl::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);
+
+ if (max_len > 2)
+ {
+ n[middle] = '.';
+ if (max_len > 3)
+ {
+ n[middle - 1] = '.';
+ if (max_len > 4)
+ {
+ n[middle + 1] = '.';
+ }
+ }
+ }
+
+ return n;
+}
+
+//----------------------------------------------------------------------------
+kwsys_stl::vector<kwsys::String> SystemTools::SplitString(const char* p, char sep, bool isPath)
+{
+ kwsys_stl::string path = p;
+ kwsys_stl::vector<kwsys::String> paths;
+ if(path.empty())
+ {
+ return paths;
+ }
+ if(isPath && path[0] == '/')
+ {
+ 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)
+ {
+ paths.push_back(path.substr(pos1, pos2-pos1));
+ pos1 = pos2+1;
+ pos2 = path.find(sep, pos1+1);
+ }
+ paths.push_back(path.substr(pos1, pos2-pos1));
+
+ return paths;
+}
+
+//----------------------------------------------------------------------------
+int SystemTools::EstimateFormatLength(const char *format, va_list ap)
+{
+ if (!format)
+ {
+ return 0;
+ }
+
+ // Quick-hack attempt at estimating the length of the string.
+ // Should never under-estimate.
+
+ // Start with the length of the format string itself.
+
+ size_t length = strlen(format);
+
+ // Increase the length for every argument in the format.
+
+ const char* cur = format;
+ while(*cur)
+ {
+ if(*cur++ == '%')
+ {
+ // Skip "%%" since it doesn't correspond to a va_arg.
+ if(*cur != '%')
+ {
+ while(!int(isalpha(*cur)))
+ {
+ ++cur;
+ }
+ switch (*cur)
+ {
+ case 's':
+ {
+ // Check the length of the string.
+ char* s = va_arg(ap, char*);
+ if(s)
+ {
+ length += strlen(s);
+ }
+ } break;
+ case 'e':
+ case 'f':
+ case 'g':
+ {
+ // Assume the argument contributes no more than 64 characters.
+ length += 64;
+
+ // Eat the argument.
+ static_cast<void>(va_arg(ap, double));
+ } break;
+ default:
+ {
+ // Assume the argument contributes no more than 64 characters.
+ length += 64;
+
+ // Eat the argument.
+ static_cast<void>(va_arg(ap, int));
+ } break;
+ }
+ }
+
+ // Move past the characters just tested.
+ ++cur;
+ }
+ }
+
+ return static_cast<int>(length);
+}
+
+kwsys_stl::string SystemTools::EscapeChars(
+ const char *str,
+ const char *chars_to_escape,
+ char escape_char)
+{
+ kwsys_stl::string n;
+ if (str)
+ {
+ if (!chars_to_escape | !*chars_to_escape)
+ {
+ n.append(str);
+ }
+ else
+ {
+ n.reserve(strlen(str));
+ while (*str)
+ {
+ const char *ptr = chars_to_escape;
+ while (*ptr)
+ {
+ if (*str == *ptr)
+ {
+ n += escape_char;
+ break;
+ }
+ ++ptr;
+ }
+ n += *str;
+ ++str;
+ }
+ }
+ }
+ return n;
+}
+
+#ifdef __VMS
+static void ConvertVMSToUnix(kwsys_stl::string& path)
+{
+ kwsys_stl::string::size_type rootEnd = path.find(":[");
+ kwsys_stl::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);
+ const char* pathCString = pathPart.c_str();
+ const char* pos0 = pathCString;
+ for (kwsys_stl::string::size_type pos = 0; *pos0; ++ pos )
+ {
+ if ( *pos0 == '.' )
+ {
+ pathPart[pos] = '/';
+ }
+ pos0 ++;
+ }
+ path = "/"+ root + "/" + pathPart;
+ }
+}
+#endif
+
+// convert windows slashes to unix slashes
+void SystemTools::ConvertToUnixSlashes(kwsys_stl::string& path)
+{
+ const char* pathCString = path.c_str();
+ bool hasDoubleSlash = false;
+#ifdef __VMS
+ ConvertVMSToUnix(path);
+#else
+ const char* pos0 = pathCString;
+ const char* pos1 = pathCString+1;
+ for (kwsys_stl::string::size_type pos = 0; *pos0; ++ pos )
+ {
+ // make sure we don't convert an escaped space to a unix slash
+ if ( *pos0 == '\\' && *pos1 != ' ' )
+ {
+ path[pos] = '/';
+ }
+
+ // Also, reuse the loop to check for slash followed by another slash
+ if (*pos1 == '/' && *(pos1+1) == '/' && !hasDoubleSlash)
+ {
+#ifdef _WIN32
+ // However, on windows if the first characters are both slashes,
+ // then keep them that way, so that network paths can be handled.
+ if ( pos > 0)
+ {
+ hasDoubleSlash = true;
+ }
+#else
+ hasDoubleSlash = true;
+#endif
+ }
+
+ pos0 ++;
+ pos1 ++;
+ }
+
+ if ( hasDoubleSlash )
+ {
+ SystemTools::ReplaceString(path, "//", "/");
+ }
+#endif
+ // remove any trailing slash
+ if(!path.empty())
+ {
+ // if there is a tilda ~ then replace it with HOME
+ pathCString = path.c_str();
+ if(pathCString[0] == '~' && (pathCString[1] == '/' || pathCString[1] == '\0'))
+ {
+ const char* homeEnv = SystemTools::GetEnv("HOME");
+ if (homeEnv)
+ {
+ path.replace(0,1,homeEnv);
+ }
+ }
+#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);
+ passwd* pw = getpwnam(user.c_str());
+ if(pw)
+ {
+ path.replace(0, idx, pw->pw_dir);
+ }
+ }
+#endif
+ // remove trailing slash if the path is more than
+ // a single /
+ pathCString = path.c_str();
+ if(path.size() > 1 && *(pathCString+(path.size()-1)) == '/')
+ {
+ // if it is c:/ then do not remove the trailing slash
+ if(!((path.size() == 3 && pathCString[1] == ':')))
+ {
+ path = path.substr(0, path.size()-1);
+ }
+ }
+ }
+}
+
+// change // to /, and escape any spaces in the path
+kwsys_stl::string SystemTools::ConvertToUnixOutputPath(const char* path)
+{
+ kwsys_stl::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)
+ {
+ ret.erase(pos, 1);
+ }
+ // escape spaces and () in the path
+ if(ret.find_first_of(" ") != kwsys_stl::string::npos)
+ {
+ kwsys_stl::string result = "";
+ char lastch = 1;
+ for(const char* ch = ret.c_str(); *ch != '\0'; ++ch)
+ {
+ // if it is already escaped then don't try to escape it again
+ if((*ch == ' ') && lastch != '\\')
+ {
+ result += '\\';
+ }
+ result += *ch;
+ lastch = *ch;
+ }
+ ret = result;
+ }
+ return ret;
+}
+
+kwsys_stl::string SystemTools::ConvertToOutputPath(const char* path)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ return SystemTools::ConvertToWindowsOutputPath(path);
+#else
+ return SystemTools::ConvertToUnixOutputPath(path);
+#endif
+}
+
+// remove double slashes not at the start
+kwsys_stl::string SystemTools::ConvertToWindowsOutputPath(const char* path)
+{
+ kwsys_stl::string ret;
+ // make it big enough for all of path and double quotes
+ ret.reserve(strlen(path)+3);
+ // put path into the string
+ ret.assign(path);
+ ret = path;
+ kwsys_stl::string::size_type pos = 0;
+ // first convert all of the slashes
+ while((pos = ret.find('/', pos)) != kwsys_stl::string::npos)
+ {
+ ret[pos] = '\\';
+ pos++;
+ }
+ // check for really small paths
+ if(ret.size() < 2)
+ {
+ return ret;
+ }
+ // now clean up a bit and remove double slashes
+ // Only if it is not the first position in the path which is a network
+ // path on windows
+ pos = 1; // start at position 1
+ if(ret[0] == '\"')
+ {
+ pos = 2; // if the string is already quoted then start at 2
+ if(ret.size() < 3)
+ {
+ return ret;
+ }
+ }
+ while((pos = ret.find("\\\\", pos)) != kwsys_stl::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
+ && ret[0] != '\"')
+ {
+ ret.insert(static_cast<kwsys_stl::string::size_type>(0),
+ static_cast<kwsys_stl::string::size_type>(1), '\"');
+ ret.append(1, '\"');
+ }
+ return ret;
+}
+
+bool SystemTools::CopyFileIfDifferent(const char* source,
+ const char* 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;
+ SystemTools::ConvertToUnixSlashes(new_destination);
+ new_destination += '/';
+ kwsys_stl::string source_name = source;
+ new_destination += SystemTools::GetFilenameName(source_name);
+ if(SystemTools::FilesDiffer(source, new_destination.c_str()))
+ {
+ return SystemTools::CopyFileAlways(source, destination);
+ }
+ else
+ {
+ // the files are the same so the copy is done return
+ // true
+ return true;
+ }
+ }
+ // source and destination are files so do a copy if they
+ // are different
+ if(SystemTools::FilesDiffer(source, destination))
+ {
+ return SystemTools::CopyFileAlways(source, destination);
+ }
+ // at this point the files must be the same so return true
+ return true;
+}
+
+#define KWSYS_ST_BUFFER 4096
+
+bool SystemTools::FilesDiffer(const char* source,
+ const char* destination)
+{
+ struct stat statSource;
+ if (stat(source, &statSource) != 0)
+ {
+ return true;
+ }
+
+ struct stat statDestination;
+ if (stat(destination, &statDestination) != 0)
+ {
+ return true;
+ }
+
+ if(statSource.st_size != statDestination.st_size)
+ {
+ return true;
+ }
+
+ if(statSource.st_size == 0)
+ {
+ return false;
+ }
+
+#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));
+#else
+ kwsys_ios::ifstream finSource(source);
+ kwsys_ios::ifstream finDestination(destination);
+#endif
+ if(!finSource || !finDestination)
+ {
+ return true;
+ }
+
+ // 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);
+ 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)
+ {
+ return true;
+ }
+
+ // If this block differs the file differs.
+ if(memcmp(static_cast<const void*>(source_buf),
+ static_cast<const void*>(dest_buf),
+ static_cast<size_t>(nnext)) != 0)
+ {
+ return true;
+ }
+
+ // Update the byte count remaining.
+ nleft -= nnext;
+ }
+
+ // No differences found.
+ return false;
+}
+
+
+//----------------------------------------------------------------------------
+/**
+ * Copy a file named by "source" to the file named by "destination".
+ */
+bool SystemTools::CopyFileAlways(const char* source, const char* destination)
+{
+ // If files are the same do not copy
+ if ( SystemTools::SameFile(source, destination) )
+ {
+ return true;
+ }
+ mode_t perm = 0;
+ bool perms = SystemTools::GetPermissions(source, perm);
+
+ 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))
+ {
+ 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();
+ }
+
+ // Create destination directory
+
+ kwsys_stl::string destination_dir = destination;
+ destination_dir = SystemTools::GetFilenamePath(destination_dir);
+ SystemTools::MakeDirectory(destination_dir.c_str());
+
+ // Open files
+
+#if defined(_WIN32) || defined(__CYGWIN__)
+ kwsys_ios::ifstream fin(source,
+ kwsys_ios::ios::binary | kwsys_ios::ios::in);
+#else
+ kwsys_ios::ifstream fin(source);
+#endif
+ 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);
+
+#if defined(_WIN32) || defined(__CYGWIN__)
+ kwsys_ios::ofstream fout(destination,
+ kwsys_ios::ios::binary | kwsys_ios::ios::out | kwsys_ios::ios::trunc);
+#else
+ kwsys_ios::ofstream fout(destination,
+ kwsys_ios::ios::out | kwsys_ios::ios::trunc);
+#endif
+ 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())
+ {
+ fout.write(buffer, fin.gcount());
+ }
+ }
+
+ // 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();
+
+ if(!fout)
+ {
+ return false;
+ }
+ if ( perms )
+ {
+ if ( !SystemTools::SetPermissions(destination, perm) )
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool SystemTools::CopyAFile(const char* source, const char* destination,
+ bool always)
+{
+ if(always)
+ {
+ return SystemTools::CopyFileAlways(source, destination);
+ }
+ else
+ {
+ return SystemTools::CopyFileIfDifferent(source, destination);
+ }
+}
+
+/**
+ * Copy a directory content from "source" directory to the directory named by
+ * "destination".
+ */
+bool SystemTools::CopyADirectory(const char* source, const char* destination,
+ bool always)
+{
+ Directory dir;
+ dir.Load(source);
+ size_t fileNum;
+ if ( !SystemTools::MakeDirectory(destination) )
+ {
+ return false;
+ }
+ 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;
+ fullPath += "/";
+ fullPath += dir.GetFile(static_cast<unsigned long>(fileNum));
+ if(SystemTools::FileIsDirectory(fullPath.c_str()))
+ {
+ kwsys_stl::string fullDestPath = destination;
+ fullDestPath += "/";
+ fullDestPath += dir.GetFile(static_cast<unsigned long>(fileNum));
+ if (!SystemTools::CopyADirectory(fullPath.c_str(),
+ fullDestPath.c_str(),
+ always))
+ {
+ return false;
+ }
+ }
+ else
+ {
+ if(!SystemTools::CopyAFile(fullPath.c_str(), destination, always))
+ {
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+
+// return size of file; also returns zero if no file exists
+unsigned long SystemTools::FileLength(const char* filename)
+{
+ struct stat fs;
+ if (stat(filename, &fs) != 0)
+ {
+ return 0;
+ }
+ else
+ {
+ return static_cast<unsigned long>(fs.st_size);
+ }
+}
+
+int SystemTools::Strucmp(const char *s1, const char *s2)
+{
+ // lifted from Graphvis http://www.graphviz.org
+ while ((*s1 != '\0')
+ && (tolower(*s1) == tolower(*s2)))
+ {
+ s1++;
+ s2++;
+ }
+
+ return tolower(*s1) - tolower(*s2);
+}
+
+// return file's modified time
+long int SystemTools::ModifiedTime(const char* filename)
+{
+ struct stat fs;
+ if (stat(filename, &fs) != 0)
+ {
+ return 0;
+ }
+ else
+ {
+ return static_cast<long int>(fs.st_mtime);
+ }
+}
+
+// return file's creation time
+long int SystemTools::CreationTime(const char* filename)
+{
+ struct stat fs;
+ if (stat(filename, &fs) != 0)
+ {
+ return 0;
+ }
+ else
+ {
+ return fs.st_ctime >= 0 ? static_cast<long int>(fs.st_ctime) : 0;
+ }
+}
+
+bool SystemTools::ConvertDateMacroString(const char *str, time_t *tmt)
+{
+ if (!str || !tmt || strlen(str) > 11)
+ {
+ return false;
+ }
+
+ struct tm tmt2;
+
+ // __DATE__
+ // The compilation date of the current source file. The date is a string
+ // literal of the form Mmm dd yyyy. The month name Mmm is the same as for
+ // dates generated by the library function asctime declared in TIME.H.
+
+ // index: 012345678901
+ // format: Mmm dd yyyy
+ // example: Dec 19 2003
+
+ static char month_names[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
+
+ char buffer[12];
+ strcpy(buffer, str);
+
+ buffer[3] = 0;
+ char *ptr = strstr(month_names, buffer);
+ if (!ptr)
+ {
+ return false;
+ }
+
+ int month = static_cast<int>((ptr - month_names) / 3);
+ int day = atoi(buffer + 4);
+ int year = atoi(buffer + 7);
+
+ tmt2.tm_isdst = -1;
+ tmt2.tm_hour = 0;
+ tmt2.tm_min = 0;
+ tmt2.tm_sec = 0;
+ tmt2.tm_wday = 0;
+ tmt2.tm_yday = 0;
+ tmt2.tm_mday = day;
+ tmt2.tm_mon = month;
+ tmt2.tm_year = year - 1900;
+
+ *tmt = mktime(&tmt2);
+ return true;
+}
+
+bool SystemTools::ConvertTimeStampMacroString(const char *str, time_t *tmt)
+{
+ if (!str || !tmt || strlen(str) > 26)
+ {
+ return false;
+ }
+
+ struct tm tmt2;
+
+ // __TIMESTAMP__
+ // The date and time of the last modification of the current source file,
+ // expressed as a string literal in the form Ddd Mmm Date hh:mm:ss yyyy,
+ /// where Ddd is the abbreviated day of the week and Date is an integer
+ // from 1 to 31.
+
+ // index: 0123456789
+ // 0123456789
+ // 0123456789
+ // format: Ddd Mmm Date hh:mm:ss yyyy
+ // example: Fri Dec 19 14:34:58 2003
+
+ static char month_names[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
+
+ char buffer[27];
+ strcpy(buffer, str);
+
+ buffer[7] = 0;
+ char *ptr = strstr(month_names, buffer + 4);
+ if (!ptr)
+ {
+ return false;
+ }
+
+ int month = static_cast<int>((ptr - month_names) / 3);
+ int day = atoi(buffer + 8);
+ int hour = atoi(buffer + 11);
+ int min = atoi(buffer + 14);
+ int sec = atoi(buffer + 17);
+ int year = atoi(buffer + 20);
+
+ tmt2.tm_isdst = -1;
+ tmt2.tm_hour = hour;
+ tmt2.tm_min = min;
+ tmt2.tm_sec = sec;
+ tmt2.tm_wday = 0;
+ tmt2.tm_yday = 0;
+ tmt2.tm_mday = day;
+ tmt2.tm_mon = month;
+ tmt2.tm_year = year - 1900;
+
+ *tmt = mktime(&tmt2);
+ return true;
+}
+
+kwsys_stl::string SystemTools::GetLastSystemError()
+{
+ int e = errno;
+ return strerror(e);
+}
+
+bool SystemTools::RemoveFile(const char* source)
+{
+#ifdef _WIN32
+ mode_t mode;
+ if ( !SystemTools::GetPermissions(source, mode) )
+ {
+ 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 )
+ {
+ SystemTools::SetPermissions(source, mode);
+ }
+#endif
+ return res;
+}
+
+bool SystemTools::RemoveADirectory(const char* source)
+{
+ // Add write permission to the directory so we can modify its
+ // content to remove files and directories from it.
+ mode_t mode;
+ if(SystemTools::GetPermissions(source, mode))
+ {
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ mode |= S_IWRITE;
+#else
+ mode |= S_IWUSR;
+#endif
+ SystemTools::SetPermissions(source, mode);
+ }
+
+ Directory dir;
+ dir.Load(source);
+ 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;
+ fullPath += "/";
+ fullPath += dir.GetFile(static_cast<unsigned long>(fileNum));
+ if(SystemTools::FileIsDirectory(fullPath.c_str()) &&
+ !SystemTools::FileIsSymlink(fullPath.c_str()))
+ {
+ if (!SystemTools::RemoveADirectory(fullPath.c_str()))
+ {
+ return false;
+ }
+ }
+ else
+ {
+ if(!SystemTools::RemoveFile(fullPath.c_str()))
+ {
+ return false;
+ }
+ }
+ }
+ }
+
+ return (Rmdir(source) == 0);
+}
+
+/**
+ */
+size_t SystemTools::GetMaximumFilePathLength()
+{
+ return KWSYS_SYSTEMTOOLS_MAXPATH;
+}
+
+/**
+ * Find the file the given name. Searches the given path and then
+ * 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,
+ bool no_system_path)
+{
+ // Add the system search path to our path first
+ kwsys_stl::vector<kwsys_stl::string> path;
+ if (!no_system_path)
+ {
+ SystemTools::GetPath(path, "CMAKE_FILE_PATH");
+ SystemTools::GetPath(path);
+ }
+ // now add the additional paths
+ {
+ for(kwsys_stl::vector<kwsys_stl::string>::const_iterator i = userPaths.begin();
+ i != userPaths.end(); ++i)
+ {
+ path.push_back(*i);
+ }
+ }
+ // Add a trailing slash to all paths to aid the search process.
+ {
+ for(kwsys_stl::vector<kwsys_stl::string>::iterator i = path.begin();
+ i != path.end(); ++i)
+ {
+ kwsys_stl::string& p = *i;
+ if(p.empty() || p[p.size()-1] != '/')
+ {
+ p += "/";
+ }
+ }
+ }
+ // now look for the file
+ kwsys_stl::string tryPath;
+ for(kwsys_stl::vector<kwsys_stl::string>::const_iterator p = path.begin();
+ p != path.end(); ++p)
+ {
+ tryPath = *p;
+ tryPath += name;
+ if(SystemTools::FileExists(tryPath.c_str()))
+ {
+ return tryPath;
+ }
+ }
+ // Couldn't find the file.
+ return "";
+}
+
+/**
+ * Find the file the given name. Searches the given path and then
+ * 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,
+ bool no_system_path)
+{
+ kwsys_stl::string tryPath = SystemTools::FindName(name, userPaths, no_system_path);
+ if(tryPath != "" && !SystemTools::FileIsDirectory(tryPath.c_str()))
+ {
+ return SystemTools::CollapseFullPath(tryPath.c_str());
+ }
+ // Couldn't find the file.
+ return "";
+}
+
+/**
+ * Find the directory the given name. Searches the given path and then
+ * 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,
+ bool no_system_path)
+{
+ kwsys_stl::string tryPath = SystemTools::FindName(name, userPaths, no_system_path);
+ if(tryPath != "" && SystemTools::FileIsDirectory(tryPath.c_str()))
+ {
+ return SystemTools::CollapseFullPath(tryPath.c_str());
+ }
+ // Couldn't find the file.
+ return "";
+}
+
+/**
+ * Find the executable with the given name. Searches the given path and then
+ * 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(
+ const char* nameIn,
+ const kwsys_stl::vector<kwsys_stl::string>& userPaths,
+ bool no_system_path)
+{
+ if(!nameIn || !*nameIn)
+ {
+ return "";
+ }
+ kwsys_stl::string name = nameIn;
+ kwsys_stl::vector<kwsys_stl::string> extensions;
+#if defined (_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__)
+ bool hasExtension = false;
+ // 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)
+ {
+ 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 =
+ extensions.begin(); i != extensions.end(); ++i)
+ {
+ tryPath = name;
+ tryPath += *i;
+ if(SystemTools::FileExists(tryPath.c_str()) &&
+ !SystemTools::FileIsDirectory(tryPath.c_str()))
+ {
+ return SystemTools::CollapseFullPath(tryPath.c_str());
+ }
+ }
+ }
+ // now try just the name
+ tryPath = name;
+ if(SystemTools::FileExists(tryPath.c_str()) &&
+ !SystemTools::FileIsDirectory(tryPath.c_str()))
+ {
+ return SystemTools::CollapseFullPath(tryPath.c_str());
+ }
+ // now construct the path
+ kwsys_stl::vector<kwsys_stl::string> path;
+ // Add the system search path to our path.
+ if (!no_system_path)
+ {
+ SystemTools::GetPath(path);
+ }
+ // now add the additional paths
+ {
+ for(kwsys_stl::vector<kwsys_stl::string>::const_iterator i =
+ userPaths.begin(); i != userPaths.end(); ++i)
+ {
+ path.push_back(*i);
+ }
+ }
+ // Add a trailing slash to all paths to aid the search process.
+ {
+ for(kwsys_stl::vector<kwsys_stl::string>::iterator i = path.begin();
+ i != path.end(); ++i)
+ {
+ kwsys_stl::string& p = *i;
+ if(p.empty() || p[p.size()-1] != '/')
+ {
+ p += "/";
+ }
+ }
+ }
+ // Try each path
+ for(kwsys_stl::vector<kwsys_stl::string>::iterator p = path.begin();
+ p != path.end(); ++p)
+ {
+#ifdef _WIN32
+ // Remove double quotes from the path on windows
+ SystemTools::ReplaceString(*p, "\"", "");
+#endif
+ // first try with extensions
+ if(extensions.size())
+ {
+ 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.c_str()) &&
+ !SystemTools::FileIsDirectory(tryPath.c_str()))
+ {
+ return SystemTools::CollapseFullPath(tryPath.c_str());
+ }
+ }
+ }
+ // now try it without them
+ tryPath = *p;
+ tryPath += name;
+ if(SystemTools::FileExists(tryPath.c_str()) &&
+ !SystemTools::FileIsDirectory(tryPath.c_str()))
+ {
+ return SystemTools::CollapseFullPath(tryPath.c_str());
+ }
+ }
+ // 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,
+ bool noSystemPath)
+{
+ for(kwsys_stl::vector<kwsys_stl::string>::const_iterator it = names.begin();
+ it != names.end() ; ++it)
+ {
+ // Try to find the program.
+ kwsys_stl::string result = SystemTools::FindProgram(it->c_str(),
+ path,
+ noSystemPath);
+ if ( !result.empty() )
+ {
+ return result;
+ }
+ }
+ return "";
+}
+
+/**
+ * Find the library with the given name. Searches the given path and then
+ * 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)
+{
+ // See if the executable exists as written.
+ if(SystemTools::FileExists(name) &&
+ !SystemTools::FileIsDirectory(name))
+ {
+ return SystemTools::CollapseFullPath(name);
+ }
+
+ // Add the system search path to our path.
+ kwsys_stl::vector<kwsys_stl::string> path;
+ SystemTools::GetPath(path);
+ // now add the additional paths
+ {
+ for(kwsys_stl::vector<kwsys_stl::string>::const_iterator i = userPaths.begin();
+ i != userPaths.end(); ++i)
+ {
+ path.push_back(*i);
+ }
+ }
+ // Add a trailing slash to all paths to aid the search process.
+ {
+ for(kwsys_stl::vector<kwsys_stl::string>::iterator i = path.begin();
+ i != path.end(); ++i)
+ {
+ kwsys_stl::string& p = *i;
+ if(p.empty() || p[p.size()-1] != '/')
+ {
+ p += "/";
+ }
+ }
+ }
+ kwsys_stl::string tryPath;
+ for(kwsys_stl::vector<kwsys_stl::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()))
+ {
+ return SystemTools::CollapseFullPath(tryPath.c_str());
+ }
+#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()))
+ {
+ return SystemTools::CollapseFullPath(tryPath.c_str());
+ }
+#else
+ tryPath = *p;
+ tryPath += "lib";
+ tryPath += name;
+ tryPath += ".so";
+ if(SystemTools::FileExists(tryPath.c_str())
+ && !SystemTools::FileIsDirectory(tryPath.c_str()))
+ {
+ return SystemTools::CollapseFullPath(tryPath.c_str());
+ }
+ tryPath = *p;
+ tryPath += "lib";
+ tryPath += name;
+ tryPath += ".a";
+ if(SystemTools::FileExists(tryPath.c_str())
+ && !SystemTools::FileIsDirectory(tryPath.c_str()))
+ {
+ return SystemTools::CollapseFullPath(tryPath.c_str());
+ }
+ tryPath = *p;
+ tryPath += "lib";
+ tryPath += name;
+ tryPath += ".sl";
+ if(SystemTools::FileExists(tryPath.c_str())
+ && !SystemTools::FileIsDirectory(tryPath.c_str()))
+ {
+ return SystemTools::CollapseFullPath(tryPath.c_str());
+ }
+ tryPath = *p;
+ tryPath += "lib";
+ tryPath += name;
+ tryPath += ".dylib";
+ if(SystemTools::FileExists(tryPath.c_str())
+ && !SystemTools::FileIsDirectory(tryPath.c_str()))
+ {
+ return SystemTools::CollapseFullPath(tryPath.c_str());
+ }
+ tryPath = *p;
+ tryPath += "lib";
+ tryPath += name;
+ tryPath += ".dll";
+ if(SystemTools::FileExists(tryPath.c_str())
+ && !SystemTools::FileIsDirectory(tryPath.c_str()))
+ {
+ return SystemTools::CollapseFullPath(tryPath.c_str());
+ }
+#endif
+ }
+
+ // Couldn't find the library.
+ return "";
+}
+
+kwsys_stl::string SystemTools::GetRealPath(const char* path)
+{
+ kwsys_stl::string ret;
+ Realpath(path, ret);
+ return ret;
+}
+
+bool SystemTools::FileIsDirectory(const char* name)
+{
+ // Remove any trailing slash from the name.
+ char buffer[KWSYS_SYSTEMTOOLS_MAXPATH];
+ size_t last = strlen(name)-1;
+ if(last > 0 && (name[last] == '/' || name[last] == '\\')
+ && strcmp(name, "/") !=0)
+ {
+ memcpy(buffer, name, last);
+ buffer[last] = 0;
+ name = buffer;
+ }
+
+ // Now check the file node type.
+ 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
+ }
+ else
+ {
+ return false;
+ }
+}
+
+bool SystemTools::FileIsSymlink(const char* name)
+{
+#if defined( _WIN32 )
+ (void)name;
+ return false;
+#else
+ struct stat fs;
+ if(lstat(name, &fs) == 0)
+ {
+ return S_ISLNK(fs.st_mode);
+ }
+ else
+ {
+ return false;
+ }
+#endif
+}
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+bool SystemTools::CreateSymlink(const char*, const char*)
+{
+ return false;
+}
+#else
+bool SystemTools::CreateSymlink(const char* origName, const char* newName)
+{
+ return symlink(origName, newName) >= 0;
+}
+#endif
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+bool SystemTools::ReadSymlink(const char*, kwsys_stl::string&)
+{
+ return false;
+}
+#else
+bool SystemTools::ReadSymlink(const char* newName,
+ kwsys_stl::string& origName)
+{
+ char buf[KWSYS_SYSTEMTOOLS_MAXPATH+1];
+ int count =
+ static_cast<int>(readlink(newName, buf, KWSYS_SYSTEMTOOLS_MAXPATH));
+ if(count >= 0)
+ {
+ // Add null-terminator.
+ buf[count] = 0;
+ origName = buf;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+#endif
+
+int SystemTools::ChangeDirectory(const char *dir)
+{
+ return Chdir(dir);
+}
+
+kwsys_stl::string SystemTools::GetCurrentWorkingDirectory(bool collapse)
+{
+ char buf[2048];
+ const char* cwd = Getcwd(buf, 2048);
+ kwsys_stl::string path;
+ if ( cwd )
+ {
+ path = cwd;
+ }
+ if(collapse)
+ {
+ return SystemTools::CollapseFullPath(path.c_str());
+ }
+ return path;
+}
+
+kwsys_stl::string SystemTools::GetProgramPath(const char* in_name)
+{
+ kwsys_stl::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)
+{
+ dir = in_name;
+ file = "";
+ SystemTools::ConvertToUnixSlashes(dir);
+
+ if(!SystemTools::FileIsDirectory(dir.c_str()))
+ {
+ kwsys_stl::string::size_type slashPos = dir.rfind("/");
+ if(slashPos != kwsys_stl::string::npos)
+ {
+ file = dir.substr(slashPos+1);
+ dir = dir.substr(0, slashPos);
+ }
+ else
+ {
+ file = dir;
+ dir = "";
+ }
+ }
+ if(!(dir == "") && !SystemTools::FileIsDirectory(dir.c_str()))
+ {
+ kwsys_stl::string oldDir = in_name;
+ SystemTools::ConvertToUnixSlashes(oldDir);
+ dir = in_name;
+ return false;
+ }
+ return true;
+}
+
+bool SystemTools::FindProgramPath(const char* argv0,
+ kwsys_stl::string& pathOut,
+ kwsys_stl::string& errorMsg,
+ const char* exeName,
+ const char* buildDir,
+ const char* installPrefix )
+{
+ kwsys_stl::vector<kwsys_stl::string> failures;
+ kwsys_stl::string self = argv0 ? argv0 : "";
+ failures.push_back(self);
+ SystemTools::ConvertToUnixSlashes(self);
+ self = SystemTools::FindProgram(self.c_str());
+ if(!SystemTools::FileExists(self.c_str()))
+ {
+ if(buildDir)
+ {
+ kwsys_stl::string intdir = ".";
+#ifdef CMAKE_INTDIR
+ intdir = CMAKE_INTDIR;
+#endif
+ self = buildDir;
+ self += "/bin/";
+ self += intdir;
+ self += "/";
+ self += exeName;
+ self += SystemTools::GetExecutableExtension();
+ }
+ }
+ if(installPrefix)
+ {
+ if(!SystemTools::FileExists(self.c_str()))
+ {
+ failures.push_back(self);
+ self = installPrefix;
+ self += "/bin/";
+ self += exeName;
+ }
+ }
+ if(!SystemTools::FileExists(self.c_str()))
+ {
+ failures.push_back(self);
+ kwsys_ios::ostringstream msg;
+ msg << "Can not find the command line program ";
+ if (exeName)
+ {
+ msg << exeName;
+ }
+ msg << "\n";
+ if (argv0)
+ {
+ msg << " argv[0] = \"" << argv0 << "\"\n";
+ }
+ msg << " Attempted paths:\n";
+ kwsys_stl::vector<kwsys_stl::string>::iterator i;
+ for(i=failures.begin(); i != failures.end(); ++i)
+ {
+ msg << " \"" << i->c_str() << "\"\n";
+ }
+ errorMsg = msg.str();
+ return false;
+ }
+ pathOut = self;
+ return true;
+}
+
+
+kwsys_stl::string SystemTools::CollapseFullPath(const char* in_relative)
+{
+ return SystemTools::CollapseFullPath(in_relative, 0);
+}
+
+void SystemTools::AddTranslationPath(const char * a, const char * b)
+{
+ kwsys_stl::string path_a = a;
+ kwsys_stl::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() ) )
+ {
+ // 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 )
+ {
+ // Before inserting make sure path ends with '/'
+ if(path_a.size() && path_a[path_a.size() -1] != '/')
+ {
+ path_a += '/';
+ }
+ if(path_b.size() && path_b[path_b.size() -1] != '/')
+ {
+ path_b += '/';
+ }
+ if( !(path_a == path_b) )
+ {
+ SystemTools::TranslationMap->insert(
+ SystemToolsTranslationMap::value_type(path_a, path_b));
+ }
+ }
+ }
+}
+
+void SystemTools::AddKeepPath(const char* dir)
+{
+ kwsys_stl::string cdir;
+ Realpath(SystemTools::CollapseFullPath(dir).c_str(), cdir);
+ SystemTools::AddTranslationPath(cdir.c_str(), dir);
+}
+
+void SystemTools::CheckTranslationPath(kwsys_stl::string & path)
+{
+ // Do not translate paths that are too short to have meaningful
+ // translations.
+ if(path.size() < 2)
+ {
+ return;
+ }
+
+ // Always add a trailing slash before translation. It does not
+ // matter if this adds an extra slash, but we do not want to
+ // translate part of a directory (like the foo part of foo-dir).
+ 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;
+ for(it = SystemTools::TranslationMap->begin();
+ it != SystemTools::TranslationMap->end();
+ ++it )
+ {
+ // We need to check of the path is a substring of the other path
+ if(path.find( it->first ) == 0)
+ {
+ path = path.replace( 0, it->first.size(), it->second);
+ }
+ }
+
+ // Remove the trailing slash we added before.
+ path.erase(path.end()-1, path.end());
+}
+
+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)
+{
+ for(kwsys_stl::vector<kwsys_stl::string>::const_iterator i = first;
+ i != last; ++i)
+ {
+ if(*i == "..")
+ {
+ if(out_components.begin() != out_components.end())
+ {
+ out_components.erase(out_components.end()-1, out_components.end());
+ }
+ }
+ else if(!(*i == ".") && !(*i == ""))
+ {
+ out_components.push_back(*i);
+ }
+ }
+}
+
+kwsys_stl::string SystemTools::CollapseFullPath(const char* in_path,
+ const char* in_base)
+{
+ // Collect the output path components.
+ kwsys_stl::vector<kwsys_stl::string> out_components;
+
+ // Split the input path components.
+ kwsys_stl::vector<kwsys_stl::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;
+ if(in_base)
+ {
+ // Use the given base path.
+ SystemTools::SplitPath(in_base, base_components);
+ }
+ else
+ {
+ // Use the current working directory as a base path.
+ char buf[2048];
+ if(const char* cwd = Getcwd(buf, 2048))
+ {
+ SystemTools::SplitPath(cwd, base_components);
+ }
+ else
+ {
+ // ??
+ }
+ }
+
+ // 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.
+ kwsys_stl::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.c_str(), in_path);
+
+ SystemTools::CheckTranslationPath(newPath);
+#ifdef _WIN32
+ newPath = SystemTools::GetActualCaseForPath(newPath.c_str());
+ SystemTools::ConvertToUnixSlashes(newPath);
+#endif
+ // Return the reconstructed path.
+ return newPath;
+}
+
+// compute the relative path from here to there
+kwsys_stl::string SystemTools::RelativePath(const char* local, const char* remote)
+{
+ if(!SystemTools::FileIsFullPath(local))
+ {
+ return "";
+ }
+ if(!SystemTools::FileIsFullPath(remote))
+ {
+ return "";
+ }
+
+ // 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
+ // count up how many matching directory names there are from the start
+ unsigned int sameCount = 0;
+ while(
+ ((sameCount <= (localSplit.size()-1)) && (sameCount <= (remoteSplit.size()-1)))
+ &&
+// for windows and apple do a case insensitive string compare
+#if defined(_WIN32) || defined(__APPLE__)
+ SystemTools::Strucmp(localSplit[sameCount].c_str(),
+ remoteSplit[sameCount].c_str()) == 0
+#else
+ localSplit[sameCount] == remoteSplit[sameCount]
+#endif
+ )
+ {
+ // put the common parts of the path into the commonPath array
+ commonPath.push_back(localSplit[sameCount]);
+ // erase the common parts of the path from the original path arrays
+ localSplit[sameCount] = "";
+ remoteSplit[sameCount] = "";
+ sameCount++;
+ }
+
+ // If there is nothing in common at all then just return the full
+ // path. This is the case only on windows when the paths have
+ // different drive letters. On unix two full paths always at least
+ // have the root "/" in common so we will return a relative path
+ // that passes through the root directory.
+ if(sameCount == 0)
+ {
+ return remote;
+ }
+
+ // for each entry that is not common in the local path
+ // add a ../ to the finalpath array, this gets us out of the local
+ // path into the remote dir
+ for(unsigned int i = 0; i < localSplit.size(); ++i)
+ {
+ if(localSplit[i].size())
+ {
+ 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();
+ vit != remoteSplit.end(); ++vit)
+ {
+ if(vit->size())
+ {
+ finalPath.push_back(*vit);
+ }
+ }
+ kwsys_stl::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();
+ vit1 != finalPath.end(); ++vit1)
+ {
+ if(relativePath.size() && relativePath[relativePath.size()-1] != '/')
+ {
+ relativePath += "/";
+ }
+ relativePath += *vit1;
+ }
+ return relativePath;
+}
+
+#ifdef _WIN32
+static int GetCasePathName(const kwsys_stl::string & pathIn,
+ kwsys_stl::string & casePath)
+{
+ kwsys_stl::vector<kwsys_stl::string> path_components;
+ SystemTools::SplitPath(pathIn.c_str(), path_components);
+ if(path_components[0].empty()) // First component always exists.
+ {
+ // Relative paths cannot be converted.
+ casePath = "";
+ return 0;
+ }
+
+ // Start with root component.
+ kwsys_stl::vector<kwsys_stl::string>::size_type idx = 0;
+ casePath = path_components[idx++];
+ const char* sep = "";
+
+ // If network path, fill casePath with server/share so FindFirstFile
+ // will work after that. Maybe someday call other APIs to get
+ // actual case of servers and shares.
+ if(path_components.size() > 2 && path_components[0] == "//")
+ {
+ casePath += path_components[idx++];
+ casePath += "/";
+ casePath += path_components[idx++];
+ sep = "/";
+ }
+
+ for(; idx < path_components.size(); idx++)
+ {
+ casePath += sep;
+ sep = "/";
+ kwsys_stl::string test_str = casePath;
+ test_str += path_components[idx];
+
+ WIN32_FIND_DATA findData;
+ HANDLE hFind = ::FindFirstFile(test_str.c_str(), &findData);
+ if (INVALID_HANDLE_VALUE != hFind)
+ {
+ casePath += findData.cFileName;
+ ::FindClose(hFind);
+ }
+ else
+ {
+ casePath = "";
+ return 0;
+ }
+ }
+ return (int)casePath.size();
+}
+#endif
+
+
+//----------------------------------------------------------------------------
+kwsys_stl::string SystemTools::GetActualCaseForPath(const char* 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())
+ {
+ return i->second;
+ }
+ int len = GetCasePathName(p, casePath);
+ if(len == 0 || len > MAX_PATH+1)
+ {
+ return p;
+ }
+ (*SystemTools::LongPathMap)[p] = casePath;
+ return casePath;
+#endif
+}
+
+//----------------------------------------------------------------------------
+const char* SystemTools::SplitPathRootComponent(const char* p,
+ kwsys_stl::string* root)
+{
+ // Identify the root component.
+ const char* c = p;
+ if((c[0] == '/' && c[1] == '/') || (c[0] == '\\' && c[1] == '\\'))
+ {
+ // Network path.
+ if(root)
+ {
+ *root = "//";
+ }
+ c += 2;
+ }
+ else if(c[0] == '/' || c[0] == '\\')
+ {
+ // Unix path (or Windows path w/out drive letter).
+ if(root)
+ {
+ *root = "/";
+ }
+ c += 1;
+ }
+ else if(c[0] && c[1] == ':' && (c[2] == '/' || c[2] == '\\'))
+ {
+ // Windows path.
+ if(root)
+ {
+ (*root) = "_:/";
+ (*root)[0] = c[0];
+ }
+ c += 3;
+ }
+ else if(c[0] && c[1] == ':')
+ {
+ // Path relative to a windows drive working directory.
+ if(root)
+ {
+ (*root) = "_:";
+ (*root)[0] = c[0];
+ }
+ c += 2;
+ }
+ else if(c[0] == '~')
+ {
+ // Home directory. The returned root should always have a
+ // trailing slash so that appending components as
+ // c[0]c[1]/c[2]/... works. The remaining path returned should
+ // skip the first slash if it exists:
+ //
+ // "~" : root = "~/" , return ""
+ // "~/ : root = "~/" , return ""
+ // "~/x : root = "~/" , return "x"
+ // "~u" : root = "~u/", return ""
+ // "~u/" : root = "~u/", return ""
+ // "~u/x" : root = "~u/", return "x"
+ size_t n = 1;
+ while(c[n] && c[n] != '/')
+ {
+ ++n;
+ }
+ if(root)
+ {
+ root->assign(c, n);
+ *root += '/';
+ }
+ if(c[n] == '/')
+ {
+ ++n;
+ }
+ c += n;
+ }
+ else
+ {
+ // Relative path.
+ if(root)
+ {
+ *root = "";
+ }
+ }
+
+ // Return the remaining path.
+ return c;
+}
+
+//----------------------------------------------------------------------------
+void SystemTools::SplitPath(const char* p,
+ kwsys_stl::vector<kwsys_stl::string>& components,
+ bool expand_home_dir)
+{
+ const char* c = p;
+ components.clear();
+
+ // Identify the root component.
+ {
+ kwsys_stl::string root;
+ c = SystemTools::SplitPathRootComponent(c, &root);
+
+ // Expand home directory references if requested.
+ if(expand_home_dir && !root.empty() && root[0] == '~')
+ {
+ kwsys_stl::string homedir;
+ root = root.substr(0, root.size()-1);
+ if(root.size() == 1)
+ {
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ if(const char* userp = getenv("USERPROFILE"))
+ {
+ homedir = userp;
+ }
+ else
+#endif
+ if(const char* h = getenv("HOME"))
+ {
+ homedir = h;
+ }
+ }
+#ifdef HAVE_GETPWNAM
+ else if(passwd* pw = getpwnam(root.c_str()+1))
+ {
+ if(pw->pw_dir)
+ {
+ homedir = pw->pw_dir;
+ }
+ }
+#endif
+ if(!homedir.empty() && (homedir[homedir.size()-1] == '/' ||
+ homedir[homedir.size()-1] == '\\'))
+ {
+ homedir = homedir.substr(0, homedir.size()-1);
+ }
+ SystemTools::SplitPath(homedir.c_str(), components);
+ }
+ else
+ {
+ components.push_back(root);
+ }
+ }
+
+ // Parse the remaining components.
+ const char* first = c;
+ const char* last = first;
+ for(;*last; ++last)
+ {
+ 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)));
+ first = last+1;
+ }
+ }
+
+ // 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)));
+ }
+}
+
+//----------------------------------------------------------------------------
+kwsys_stl::string
+SystemTools::JoinPath(const kwsys_stl::vector<kwsys_stl::string>& components)
+{
+ return SystemTools::JoinPath(components.begin(), components.end());
+}
+
+//----------------------------------------------------------------------------
+kwsys_stl::string
+SystemTools
+::JoinPath(kwsys_stl::vector<kwsys_stl::string>::const_iterator first,
+ kwsys_stl::vector<kwsys_stl::string>::const_iterator last)
+{
+ // Construct result in a single string.
+ kwsys_stl::string result;
+
+ // The first two components do not add a slash.
+ if(first != last)
+ {
+ result.append(*first++);
+ }
+ if(first != last)
+ {
+ result.append(*first++);
+ }
+
+ // All remaining components are always separated with a slash.
+ while(first != last)
+ {
+ result.append("/");
+ result.append((*first++));
+ }
+
+ // Return the concatenated result.
+ return result;
+}
+
+//----------------------------------------------------------------------------
+bool SystemTools::ComparePath(const char* c1, const char* c2)
+{
+#if defined(_WIN32) || defined(__APPLE__)
+# ifdef _MSC_VER
+ return _stricmp(c1, c2) == 0;
+# elif defined(__APPLE__) || defined(__GNUC__)
+ return strcasecmp(c1, c2) == 0;
+#else
+ return SystemTools::Strucmp(c1, c2) == 0;
+# endif
+#else
+ return strcmp(c1, c2) == 0;
+#endif
+}
+
+//----------------------------------------------------------------------------
+bool SystemTools::Split(const char* str, kwsys_stl::vector<kwsys_stl::string>& lines, char separator)
+{
+ kwsys_stl::string data(str);
+ kwsys_stl::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)
+ {
+ // Line ends at end of string without a newline.
+ lines.push_back(data.substr(lpos));
+ return false;
+ }
+ else
+ {
+ // Line ends in a "\n", remove the character.
+ lines.push_back(data.substr(lpos, rpos-lpos));
+ }
+ lpos = rpos+1;
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool SystemTools::Split(const char* str, kwsys_stl::vector<kwsys_stl::string>& lines)
+{
+ kwsys_stl::string data(str);
+ kwsys_stl::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)
+ {
+ // Line ends at end of string without a newline.
+ lines.push_back(data.substr(lpos));
+ return false;
+ }
+ if((rpos > lpos) && (data[rpos-1] == '\r'))
+ {
+ // Line ends in a "\r\n" pair, remove both characters.
+ lines.push_back(data.substr(lpos, (rpos-1)-lpos));
+ }
+ else
+ {
+ // Line ends in a "\n", remove the character.
+ lines.push_back(data.substr(lpos, rpos-lpos));
+ }
+ lpos = rpos+1;
+ }
+ return true;
+}
+
+/**
+ * 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)
+{
+ kwsys_stl::string fn = filename;
+ SystemTools::ConvertToUnixSlashes(fn);
+
+ kwsys_stl::string::size_type slash_pos = fn.rfind("/");
+ if(slash_pos != kwsys_stl::string::npos)
+ {
+ kwsys_stl::string ret = fn.substr(0, slash_pos);
+ if(ret.size() == 2 && ret[1] == ':')
+ {
+ return ret + '/';
+ }
+ if(ret.size() == 0)
+ {
+ return "/";
+ }
+ return ret;
+ }
+ else
+ {
+ return "";
+ }
+}
+
+
+/**
+ * Return file name of a full filename (i.e. file name without path).
+ */
+kwsys_stl::string SystemTools::GetFilenameName(const kwsys_stl::string& filename)
+{
+#if defined(_WIN32)
+ kwsys_stl::string::size_type slash_pos = filename.find_last_of("/\\");
+#else
+ kwsys_stl::string::size_type slash_pos = filename.find_last_of("/");
+#endif
+ if(slash_pos != kwsys_stl::string::npos)
+ {
+ return filename.substr(slash_pos + 1);
+ }
+ else
+ {
+ return 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)
+{
+ kwsys_stl::string name = SystemTools::GetFilenameName(filename);
+ kwsys_stl::string::size_type dot_pos = name.find(".");
+ if(dot_pos != kwsys_stl::string::npos)
+ {
+ return name.substr(dot_pos);
+ }
+ else
+ {
+ return "";
+ }
+}
+
+/**
+ * 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)
+{
+ kwsys_stl::string name = SystemTools::GetFilenameName(filename);
+ kwsys_stl::string::size_type dot_pos = name.rfind(".");
+ if(dot_pos != kwsys_stl::string::npos)
+ {
+ return name.substr(dot_pos);
+ }
+ else
+ {
+ return "";
+ }
+}
+
+/**
+ * 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)
+{
+ kwsys_stl::string name = SystemTools::GetFilenameName(filename);
+ kwsys_stl::string::size_type dot_pos = name.find(".");
+ if(dot_pos != kwsys_stl::string::npos)
+ {
+ return name.substr(0, dot_pos);
+ }
+ else
+ {
+ return name;
+ }
+}
+
+
+/**
+ * Return file name without extension of a full filename (i.e. without path).
+ * Warning: it considers the last extension (for example: removes .gz
+ * from .tar.gz)
+ */
+kwsys_stl::string
+SystemTools::GetFilenameWithoutLastExtension(const kwsys_stl::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)
+ {
+ return name.substr(0, dot_pos);
+ }
+ else
+ {
+ return name;
+ }
+}
+
+bool SystemTools::FileHasSignature(const char *filename,
+ const char *signature,
+ long offset)
+{
+ if (!filename || !signature)
+ {
+ return false;
+ }
+
+ FILE *fp;
+ fp = fopen(filename, "rb");
+ if (!fp)
+ {
+ return false;
+ }
+
+ fseek(fp, offset, SEEK_SET);
+
+ bool res = false;
+ size_t signature_len = strlen(signature);
+ char *buffer = new char [signature_len];
+
+ if (fread(buffer, 1, signature_len, fp) == signature_len)
+ {
+ res = (!strncmp(buffer, signature, signature_len) ? true : false);
+ }
+
+ delete [] buffer;
+
+ fclose(fp);
+ return res;
+}
+
+SystemTools::FileTypeEnum
+SystemTools::DetectFileType(const char *filename,
+ unsigned long length,
+ double percent_bin)
+{
+ if (!filename || percent_bin < 0)
+ {
+ return SystemTools::FileTypeUnknown;
+ }
+
+ FILE *fp;
+ fp = fopen(filename, "rb");
+ if (!fp)
+ {
+ return SystemTools::FileTypeUnknown;
+ }
+
+ // Allocate buffer and read bytes
+
+ unsigned char *buffer = new unsigned char [length];
+ size_t read_length = fread(buffer, 1, length, fp);
+ fclose(fp);
+ if (read_length == 0)
+ {
+ return SystemTools::FileTypeUnknown;
+ }
+
+ // Loop over contents and count
+
+ size_t text_count = 0;
+
+ const unsigned char *ptr = buffer;
+ const unsigned char *buffer_end = buffer + read_length;
+
+ while (ptr != buffer_end)
+ {
+ if ((*ptr >= 0x20 && *ptr <= 0x7F) ||
+ *ptr == '\n' ||
+ *ptr == '\r' ||
+ *ptr == '\t')
+ {
+ text_count++;
+ }
+ ptr++;
+ }
+
+ delete [] buffer;
+
+ double current_percent_bin =
+ (static_cast<double>(read_length - text_count) /
+ static_cast<double>(read_length));
+
+ if (current_percent_bin >= percent_bin)
+ {
+ return SystemTools::FileTypeBinary;
+ }
+
+ return SystemTools::FileTypeText;
+}
+
+bool SystemTools::LocateFileInDir(const char *filename,
+ const char *dir,
+ kwsys_stl::string& filename_found,
+ int try_filename_dirs)
+{
+ if (!filename || !dir)
+ {
+ return false;
+ }
+
+ // Get the basename of 'filename'
+
+ kwsys_stl::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;
+ if (!SystemTools::FileIsDirectory(dir))
+ {
+#if defined( _WIN32 )
+ size_t dir_len = strlen(dir);
+ if (dir_len < 2 || dir[dir_len - 1] != ':')
+ {
+#endif
+ real_dir = SystemTools::GetFilenamePath(dir);
+ dir = real_dir.c_str();
+#if defined( _WIN32 )
+ }
+#endif
+ }
+
+ // Try to find the file in 'dir'
+
+ bool res = false;
+ if (filename_base.size() && 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;
+ if (need_slash)
+ {
+ temp += "/";
+ }
+ temp += filename_base;
+
+ if (SystemTools::FileExists(temp.c_str()))
+ {
+ res = true;
+ filename_found = temp;
+ }
+
+ // If not found, we can try harder by appending part of the file to
+ // to the directory to look inside.
+ // Example: if we were looking for /foo/bar/yo.txt in /d1/d2, then
+ // try to find yo.txt in /d1/d2/bar, then /d1/d2/foo/bar, etc.
+
+ else if (try_filename_dirs)
+ {
+ kwsys_stl::string filename_dir(filename);
+ kwsys_stl::string filename_dir_base;
+ kwsys_stl::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] == ':')
+#else
+ if (!filename_dir_base.size())
+#endif
+ {
+ break;
+ }
+
+ filename_dir_bases = filename_dir_base + "/" + filename_dir_bases;
+
+ temp = dir;
+ if (need_slash)
+ {
+ temp += "/";
+ }
+ temp += filename_dir_bases;
+
+ res = SystemTools::LocateFileInDir(
+ filename_base.c_str(), temp.c_str(), filename_found, 0);
+
+ } while (!res && filename_dir_base.size());
+ }
+ }
+
+ return res;
+}
+
+bool SystemTools::FileIsFullPath(const char* in_name)
+{
+ kwsys_stl::string name = in_name;
+#if defined(_WIN32) || defined(__CYGWIN__)
+ // On Windows, the name must be at least two characters long.
+ if(name.length() < 2)
+ {
+ return false;
+ }
+ if(name[1] == ':')
+ {
+ return true;
+ }
+ if(name[0] == '\\')
+ {
+ return true;
+ }
+#else
+ // On UNIX, the name must be at least one character long.
+ if(name.length() < 1)
+ {
+ return false;
+ }
+#endif
+#if !defined(_WIN32)
+ if(name[0] == '~')
+ {
+ return true;
+ }
+#endif
+ // 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] == '/')
+ {
+ return true;
+ }
+ return false;
+}
+
+bool SystemTools::GetShortPath(const char* path, kwsys_stl::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 the path passed in has quotes around it, first remove the quotes
+ if (path[0] == '"' && path[strlen(path)-1] == '"')
+ {
+ strcpy(tempPath,path+1);
+ tempPath[strlen(tempPath)-1] = '\0';
+ }
+ else
+ {
+ strcpy(tempPath,path);
+ }
+
+ buffer[0] = 0;
+ ret = GetShortPathName(tempPath, buffer, size);
+
+ if(buffer[0] == 0 || ret > size)
+ {
+ delete [] buffer;
+ delete [] tempPath;
+ return false;
+ }
+ else
+ {
+ shortPath = buffer;
+ delete [] buffer;
+ delete [] tempPath;
+ return true;
+ }
+#else
+ shortPath = path;
+ return true;
+#endif
+}
+
+void SystemTools::SplitProgramFromArgs(const char* path,
+ kwsys_stl::string& program, kwsys_stl::string& args)
+{
+ // see if this is a full path to a program
+ // if so then set program to path and args to nothing
+ if(SystemTools::FileExists(path))
+ {
+ program = path;
+ args = "";
+ return;
+ }
+ // 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())
+ {
+ program = findProg;
+ args = "";
+ return;
+ }
+
+ // 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)
+ {
+ kwsys_stl::string tryProg = dir.substr(0, spacePos);
+ // See if the file exists
+ if(SystemTools::FileExists(tryProg.c_str()))
+ {
+ program = tryProg;
+ // remove trailing spaces from program
+ kwsys_stl::string::size_type pos = program.size()-1;
+ while(program[pos] == ' ')
+ {
+ program.erase(pos);
+ pos--;
+ }
+ args = dir.substr(spacePos, dir.size()-spacePos);
+ return;
+ }
+ // Now try and find the the program in the path
+ findProg = SystemTools::FindProgram(tryProg.c_str(), e);
+ if(findProg.size())
+ {
+ program = findProg;
+ // remove trailing spaces from program
+ kwsys_stl::string::size_type pos = program.size()-1;
+ while(program[pos] == ' ')
+ {
+ program.erase(pos);
+ pos--;
+ }
+ args = dir.substr(spacePos, dir.size()-spacePos);
+ return;
+ }
+ // move past the space for the next search
+ spacePos--;
+ spacePos = dir.rfind(' ', spacePos);
+ }
+
+ program = "";
+ args = "";
+}
+
+kwsys_stl::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);
+}
+
+kwsys_stl::string SystemTools::MakeCindentifier(const char* s)
+{
+ kwsys_stl::string str(s);
+ if (str.find_first_of("0123456789") == 0)
+ {
+ str = "_" + str;
+ }
+
+ kwsys_stl::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)
+ {
+ str[pos] = '_';
+ }
+ return str;
+}
+
+// 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* has_newline /* = 0 */,
+ long sizeLimit /* = -1 */)
+{
+ const int bufferSize = 1024;
+ char buffer[bufferSize];
+ bool haveData = false;
+ bool haveNewline = false;
+
+ // Start with an empty line.
+ line = "";
+
+ long leftToRead = sizeLimit;
+
+ // Early short circuit return if stream is no good. Just return
+ // false and the empty line. (Probably means caller tried to
+ // create a file stream with a non-existent file name...)
+ //
+ if(!is)
+ {
+ if(has_newline)
+ {
+ *has_newline = false;
+ }
+ return false;
+ }
+
+ // If no characters are read from the stream, the end of file has
+ // been reached. Clear the fail bit just before reading.
+ while(!haveNewline &&
+ leftToRead != 0 &&
+ (is.clear(is.rdstate() & ~kwsys_ios::ios::failbit),
+ is.getline(buffer, bufferSize), is.gcount() > 0))
+ {
+ // We have read at least one byte.
+ haveData = true;
+
+ // If newline character was read the gcount includes the character
+ // but the buffer does not: the end of line has been reached.
+ size_t length = strlen(buffer);
+ if(length < static_cast<size_t>(is.gcount()))
+ {
+ haveNewline = true;
+ }
+
+ // Avoid storing a carriage return character.
+ if(length > 0 && buffer[length-1] == '\r')
+ {
+ buffer[length-1] = 0;
+ }
+
+ // if we read too much then truncate the buffer
+ if (leftToRead > 0)
+ {
+ if (static_cast<long>(length) > leftToRead)
+ {
+ buffer[leftToRead-1] = 0;
+ leftToRead = 0;
+ }
+ else
+ {
+ leftToRead -= static_cast<long>(length);
+ }
+ }
+
+ // Append the data read to the line.
+ line.append(buffer);
+ }
+
+ // Return the results.
+ if(has_newline)
+ {
+ *has_newline = haveNewline;
+ }
+ return haveData;
+}
+
+int SystemTools::GetTerminalWidth()
+{
+ int width = -1;
+#ifdef HAVE_TTY_INFO
+ struct winsize ws;
+ char *columns; /* Unix98 environment variable */
+ if(ioctl(1, TIOCGWINSZ, &ws) != -1 && ws.ws_col>0 && ws.ws_row>0)
+ {
+ width = ws.ws_col;
+ }
+ if(!isatty(STDOUT_FILENO))
+ {
+ width = -1;
+ }
+ columns = getenv("COLUMNS");
+ if(columns && *columns)
+ {
+ long t;
+ char *endptr;
+ t = strtol(columns, &endptr, 0);
+ if(endptr && !*endptr && (t>0) && (t<1000))
+ {
+ width = static_cast<int>(t);
+ }
+ }
+ if ( width < 9 )
+ {
+ width = -1;
+ }
+#endif
+ return width;
+}
+
+bool SystemTools::GetPermissions(const char* file, mode_t& mode)
+{
+ if ( !file )
+ {
+ return false;
+ }
+
+ struct stat st;
+ if ( stat(file, &st) < 0 )
+ {
+ return false;
+ }
+ mode = st.st_mode;
+ return true;
+}
+
+bool SystemTools::SetPermissions(const char* file, mode_t mode)
+{
+ if ( !file )
+ {
+ return false;
+ }
+ if ( !SystemTools::FileExists(file) )
+ {
+ return false;
+ }
+ if ( chmod(file, mode) < 0 )
+ {
+ return false;
+ }
+
+ return true;
+}
+
+kwsys_stl::string SystemTools::GetParentDirectory(const char* fileOrDir)
+{
+ return SystemTools::GetFilenamePath(fileOrDir);
+}
+
+bool SystemTools::IsSubDirectory(const char* cSubdir, const char* cDir)
+{
+ if(!*cDir)
+ {
+ return false;
+ }
+ kwsys_stl::string subdir = cSubdir;
+ kwsys_stl::string dir = cDir;
+ SystemTools::ConvertToUnixSlashes(dir);
+ kwsys_stl::string path = subdir;
+ do
+ {
+ path = SystemTools::GetParentDirectory(path.c_str());
+ if(SystemTools::ComparePath(dir.c_str(), path.c_str()))
+ {
+ return true;
+ }
+ }
+ while ( path.size() > dir.size() );
+ return false;
+}
+
+void SystemTools::Delay(unsigned int msec)
+{
+#ifdef _WIN32
+ Sleep(msec);
+#else
+ // The sleep function gives 1 second resolution and the usleep
+ // function gives 1e-6 second resolution but on some platforms has a
+ // maximum sleep time of 1 second. This could be re-implemented to
+ // use select with masked signals or pselect to mask signals
+ // atomically. If select is given empty sets and zero as the max
+ // file descriptor but a non-zero timeout it can be used to block
+ // for a precise amount of time.
+ if(msec >= 1000)
+ {
+ sleep(msec / 1000);
+ usleep((msec % 1000) * 1000);
+ }
+ else
+ {
+ usleep(msec * 1000);
+ }
+#endif
+}
+
+void SystemTools::ConvertWindowsCommandLineToUnixArguments(
+ const char *cmd_line, int *argc, char ***argv)
+{
+ if (!cmd_line || !argc || !argv)
+ {
+ return;
+ }
+
+ // A space delimites an argument except when it is inside a quote
+
+ (*argc) = 1;
+
+ size_t cmd_line_len = strlen(cmd_line);
+
+ size_t i;
+ 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] == '\"')
+ {
+ i++;
+ while (cmd_line[i] != '\"' && i < cmd_line_len)
+ {
+ i++;
+ }
+ (*argc)++;
+ }
+ else
+ {
+ while (!isspace(cmd_line[i]) && i < cmd_line_len)
+ {
+ i++;
+ }
+ (*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] == '\"')
+ {
+ i++;
+ pos = i;
+ while (cmd_line[i] != '\"' && i < cmd_line_len)
+ {
+ i++;
+ }
+ memcpy((*argv)[argc_idx], &cmd_line[pos], i - pos);
+ (*argv)[argc_idx][i - pos] = '\0';
+ argc_idx++;
+ }
+ else
+ {
+ pos = i;
+ while (!isspace(cmd_line[i]) && i < cmd_line_len)
+ {
+ i++;
+ }
+ 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";
+ }
+ else
+ {
+ res += "Microsoft Windows Server 2008 family";
+ }
+#else
+ res += "Microsoft Windows Vista or Windows Server 2008";
+#endif
+ }
+
+ if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2)
+ {
+ res += "Microsoft Windows Server 2003 family";
+ }
+
+ if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1)
+ {
+ res += "Microsoft Windows XP";
+ }
+
+ if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0)
+ {
+ res += "Microsoft Windows 2000";
+ }
+
+ if (osvi.dwMajorVersion <= 4)
+ {
+ res += "Microsoft Windows NT";
+ }
+
+ // Test for specific product on Windows NT 4.0 SP6 and later.
+
+ if (bOsVersionInfoEx)
+ {
+ // Test for the workstation type.
+
+#if (_MSC_VER >= 1300)
+ if (osvi.wProductType == VER_NT_WORKSTATION)
+ {
+ if (osvi.dwMajorVersion == 4)
+ {
+ res += " Workstation 4.0";
+ }
+ else if (osvi.dwMajorVersion == 5)
+ {
+ if (osvi.wSuiteMask & VER_SUITE_PERSONAL)
+ {
+ res += " Home Edition";
+ }
+ else
+ {
+ res += " Professional";
+ }
+ }
+ }
+
+ // Test for the server type.
+
+ else if (osvi.wProductType == VER_NT_SERVER)
+ {
+ if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2)
+ {
+ if (osvi.wSuiteMask & VER_SUITE_DATACENTER)
+ {
+ res += " Datacenter Edition";
+ }
+ else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
+ {
+ res += " Enterprise Edition";
+ }
+ else if (osvi.wSuiteMask == VER_SUITE_BLADE)
+ {
+ res += " Web Edition";
+ }
+ else
+ {
+ res += " Standard Edition";
+ }
+ }
+
+ else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0)
+ {
+ if (osvi.wSuiteMask & VER_SUITE_DATACENTER)
+ {
+ res += " Datacenter Server";
+ }
+ else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
+ {
+ res += " Advanced Server";
+ }
+ else
+ {
+ res += " Server";
+ }
+ }
+
+ else if (osvi.dwMajorVersion <= 4) // Windows NT 4.0
+ {
+ if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
+ {
+ res += " Server 4.0, Enterprise Edition";
+ }
+ else
+ {
+ res += " Server 4.0";
+ }
+ }
+ }
+#endif // Visual Studio 7 and up
+ }
+
+ // Test for specific product on Windows NT 4.0 SP5 and earlier
+
+ else
+ {
+ HKEY hKey;
+ #define BUFSIZE 80
+ char szProductType[BUFSIZE];
+ DWORD dwBufLen=BUFSIZE;
+ LONG lRet;
+
+ lRet = RegOpenKeyEx(
+ HKEY_LOCAL_MACHINE,
+ "SYSTEM\\CurrentControlSet\\Control\\ProductOptions",
+ 0, KEY_QUERY_VALUE, &hKey);
+ if (lRet != ERROR_SUCCESS)
+ {
+ return 0;
+ }
+
+ lRet = RegQueryValueEx(hKey, "ProductType", NULL, NULL,
+ (LPBYTE) szProductType, &dwBufLen);
+
+ if ((lRet != ERROR_SUCCESS) || (dwBufLen > BUFSIZE))
+ {
+ return 0;
+ }
+
+ RegCloseKey(hKey);
+
+ if (lstrcmpi("WINNT", szProductType) == 0)
+ {
+ res += " Workstation";
+ }
+ if (lstrcmpi("LANMANNT", szProductType) == 0)
+ {
+ res += " Server";
+ }
+ if (lstrcmpi("SERVERNT", szProductType) == 0)
+ {
+ res += " Advanced Server";
+ }
+
+ res += " ";
+ sprintf(buffer, "%ld", osvi.dwMajorVersion);
+ res += buffer;
+ res += ".";
+ sprintf(buffer, "%ld", osvi.dwMinorVersion);
+ res += buffer;
+ }
+
+ // Display service pack (if any) and build number.
+
+ if (osvi.dwMajorVersion == 4 &&
+ lstrcmpi(osvi.szCSDVersion, "Service Pack 6") == 0)
+ {
+ HKEY hKey;
+ LONG lRet;
+
+ // Test for SP6 versus SP6a.
+
+ lRet = RegOpenKeyEx(
+ HKEY_LOCAL_MACHINE,
+ "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Hotfix\\Q246009",
+ 0, KEY_QUERY_VALUE, &hKey);
+
+ if (lRet == ERROR_SUCCESS)
+ {
+ res += " Service Pack 6a (Build ";
+ sprintf(buffer, "%ld", osvi.dwBuildNumber & 0xFFFF);
+ res += buffer;
+ res += ")";
+ }
+ else // Windows NT 4.0 prior to SP6a
+ {
+ res += " ";
+ res += osvi.szCSDVersion;
+ res += " (Build ";
+ sprintf(buffer, "%ld", osvi.dwBuildNumber & 0xFFFF);
+ res += buffer;
+ res += ")";
+ }
+
+ RegCloseKey(hKey);
+ }
+ else // Windows NT 3.51 and earlier or Windows 2000 and later
+ {
+ res += " ";
+ res += osvi.szCSDVersion;
+ res += " (Build ";
+ sprintf(buffer, "%ld", osvi.dwBuildNumber & 0xFFFF);
+ res += buffer;
+ res += ")";
+ }
+
+ break;
+
+ // Test for the Windows 95 product family.
+
+ case VER_PLATFORM_WIN32_WINDOWS:
+
+ if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0)
+ {
+ res += "Microsoft Windows 95";
+ if (osvi.szCSDVersion[1] == 'C' || osvi.szCSDVersion[1] == 'B')
+ {
+ res += " OSR2";
+ }
+ }
+
+ if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10)
+ {
+ res += "Microsoft Windows 98";
+ if (osvi.szCSDVersion[1] == 'A')
+ {
+ res += " SE";
+ }
+ }
+
+ if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90)
+ {
+ res += "Microsoft Windows Millennium Edition";
+ }
+ break;
+
+ case VER_PLATFORM_WIN32s:
+
+ res += "Microsoft Win32s";
+ break;
+ }
+#endif
+
+ return res;
+}
+
+// ----------------------------------------------------------------------
+bool SystemTools::ParseURLProtocol( const kwsys_stl::string& URL,
+ kwsys_stl::string& protocol,
+ kwsys_stl::string& dataglom )
+{
+ // match 0 entire url
+ // match 1 protocol
+ // match 2 dataglom following protocol://
+ kwsys::RegularExpression urlRe( VTK_URL_PROTOCOL_REGEX );
+
+ if ( ! urlRe.find( URL ) ) return false;
+
+ protocol = urlRe.match( 1 );
+ dataglom = urlRe.match( 2 );
+
+ return true;
+}
+
+// ----------------------------------------------------------------------
+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 )
+{
+ kwsys::RegularExpression urlRe( VTK_URL_REGEX );
+ if ( ! urlRe.find( URL ) ) return false;
+
+ // match 0 URL
+ // match 1 protocol
+ // match 2 mangled user
+ // match 3 username
+ // match 4 mangled password
+ // match 5 password
+ // match 6 hostname
+ // match 7 mangled port
+ // match 8 dataport
+ // match 9 database name
+
+ protocol = urlRe.match( 1 );
+ username = urlRe.match( 3 );
+ password = urlRe.match( 5 );
+ hostname = urlRe.match( 6 );
+ dataport = urlRe.match( 8 );
+ database = urlRe.match( 9 );
+
+ return true;
+}
+
+// ----------------------------------------------------------------------
+// These must NOT be initialized. Default initialization to zero is
+// necessary.
+unsigned int SystemToolsManagerCount;
+SystemToolsTranslationMap *SystemTools::TranslationMap;
+SystemToolsTranslationMap *SystemTools::LongPathMap;
+#ifdef __CYGWIN__
+SystemToolsTranslationMap *SystemTools::Cyg2Win32Map;
+#endif
+
+// SystemToolsManager manages the SystemTools singleton.
+// SystemToolsManager should be included in any translation unit
+// that will use SystemTools or that implements the singleton
+// pattern. It makes sure that the SystemTools singleton is created
+// before and destroyed after all other singletons in CMake.
+
+SystemToolsManager::SystemToolsManager()
+{
+ if(++SystemToolsManagerCount == 1)
+ {
+ SystemTools::ClassInitialize();
+ }
+}
+
+SystemToolsManager::~SystemToolsManager()
+{
+ if(--SystemToolsManagerCount == 0)
+ {
+ SystemTools::ClassFinalize();
+ }
+}
+
+#if defined(__VMS)
+// On VMS we configure the run time C library to be more UNIX like.
+// http://h71000.www7.hp.com/doc/732final/5763/5763pro_004.html
+extern "C" int decc$feature_get_index(char *name);
+extern "C" int decc$feature_set_value(int index, int mode, int value);
+static int SetVMSFeature(char* name, int value)
+{
+ int i;
+ errno = 0;
+ i = decc$feature_get_index(name);
+ return i >= 0 && (decc$feature_set_value(i, 1, value) >= 0 || errno == 0);
+}
+#endif
+
+void SystemTools::ClassInitialize()
+{
+#ifdef __VMS
+ SetVMSFeature("DECC$FILENAME_UNIX_ONLY", 1);
+#endif
+ // Allocate the translation map first.
+ SystemTools::TranslationMap = new SystemToolsTranslationMap;
+ SystemTools::LongPathMap = new SystemToolsTranslationMap;
+#ifdef __CYGWIN__
+ SystemTools::Cyg2Win32Map = new SystemToolsTranslationMap;
+#endif
+
+ // Add some special translation paths for unix. These are not added
+ // for windows because drive letters need to be maintained. Also,
+ // there are not sym-links and mount points on windows anyway.
+#if !defined(_WIN32) || defined(__CYGWIN__)
+ // The tmp path is frequently a logical path so always keep it:
+ SystemTools::AddKeepPath("/tmp/");
+
+ // If the current working directory is a logical path then keep the
+ // logical name.
+ if(const char* pwd = getenv("PWD"))
+ {
+ char buf[2048];
+ if(const char* cwd = Getcwd(buf, 2048))
+ {
+ // 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;
+
+ // Test progressively shorter logical-to-physical mappings.
+ kwsys_stl::string pwd_str = pwd;
+ kwsys_stl::string cwd_str = cwd;
+ kwsys_stl::string pwd_path;
+ Realpath(pwd, pwd_path);
+ while(cwd_str == pwd_path && cwd_str != pwd_str)
+ {
+ // The current pair of paths is a working logical mapping.
+ cwd_changed = cwd_str;
+ pwd_changed = pwd_str;
+
+ // 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());
+ 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());
+ }
+ }
+ }
+#endif
+}
+
+void SystemTools::ClassFinalize()
+{
+ delete SystemTools::TranslationMap;
+ delete SystemTools::LongPathMap;
+#ifdef __CYGWIN__
+ delete SystemTools::Cyg2Win32Map;
+#endif
+}
+
+
+} // namespace KWSYS_NAMESPACE
+
+#if defined(_MSC_VER) && defined(_DEBUG)
+# include <crtdbg.h>
+# include <stdio.h>
+# include <stdlib.h>
+namespace KWSYS_NAMESPACE
+{
+
+static int SystemToolsDebugReport(int, char* message, int*)
+{
+ fprintf(stderr, "%s", message);
+ fflush(stderr);
+ return 1; // no further reporting required
+}
+
+void SystemTools::EnableMSVCDebugHook()
+{
+ if (getenv("DART_TEST_FROM_DART"))
+ {
+ _CrtSetReportHook(SystemToolsDebugReport);
+ }
+}
+
+} // namespace KWSYS_NAMESPACE
+#else
+namespace KWSYS_NAMESPACE
+{
+void SystemTools::EnableMSVCDebugHook() {}
+} // namespace KWSYS_NAMESPACE
+#endif
diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in
new file mode 100644
index 000000000..5171125ce
--- /dev/null
+++ b/Source/kwsys/SystemTools.hxx.in
@@ -0,0 +1,904 @@
+/*============================================================================
+ 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@_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.h>
+#include <@KWSYS_NAMESPACE@/String.hxx>
+
+#include <sys/types.h>
+
+// Required for va_list
+#include <stdarg.h>
+#if @KWSYS_NAMESPACE@_STL_HAVE_STD && !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
+// what the user does. This hack solves this problem by moving va_list to our
+// own namespace that is local for kwsys.
+namespace std {} // Required for platforms that do not have std namespace
+namespace @KWSYS_NAMESPACE@_VA_LIST
+{
+ using namespace std;
+ typedef va_list hack_va_list;
+}
+namespace @KWSYS_NAMESPACE@
+{
+ typedef @KWSYS_NAMESPACE@_VA_LIST::hack_va_list va_list;
+}
+#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 SystemToolsManager
+ * \brief Use to make sure SystemTools is initialized before it is used
+ * and is the last static object destroyed
+ */
+class @KWSYS_NAMESPACE@_EXPORT SystemToolsManager
+{
+public:
+ SystemToolsManager();
+ ~SystemToolsManager();
+};
+
+// This instance will show up in any translation unit that uses
+// SystemTools. It will make sure SystemTools is initialized
+// before it is used and is the last static object destroyed.
+static SystemToolsManager SystemToolsManagerInstance;
+
+/** \class SystemTools
+ * \brief A collection of useful platform-independent system functions.
+ */
+class @KWSYS_NAMESPACE@_EXPORT SystemTools
+{
+public:
+
+ /** -----------------------------------------------------------------
+ * String Manipulation Routines
+ * -----------------------------------------------------------------
+ */
+
+ /**
+ * Replace symbols in str that are not valid in C identifiers as
+ * defined by the 1999 standard, ie. anything except [A-Za-z0-9_].
+ * They are replaced with `_' and if the first character is a digit
+ * then an underscore is prepended. Note that this can produce
+ * identifiers that the standard reserves (_[A-Z].* and __.*).
+ */
+ static kwsys_stl::string MakeCindentifier(const char* s);
+
+ /**
+ * Replace replace all occurences of the string in the source string.
+ */
+ static void ReplaceString(kwsys_stl::string& source,
+ const char* replace,
+ const char* 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&);
+
+ /**
+ * 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&);
+
+ /**
+ * 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&);
+
+ /**
+ * Return a lower case string
+ */
+ static kwsys_stl::string LowerCase(const kwsys_stl::string&);
+
+ /**
+ * Return a lower case string
+ */
+ static kwsys_stl::string UpperCase(const kwsys_stl::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')
+ */
+ static char* RemoveChars(const char* str, const char *toremove);
+
+ /**
+ * Remove remove all but 0->9, A->F characters from a string.
+ * 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 StringEndsWith(const char* 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);
+
+ /** 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 = '/',
+ 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
+ */
+ static bool ConvertDateMacroString(const char *str, time_t *tmt);
+ static bool ConvertTimeStampMacroString(const char *str, time_t *tmt);
+
+ /**
+ * 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);
+
+ /**
+ * Return string with space added between capitalized words
+ * (i.e. EatMyShorts becomes Eat My Shorts )
+ * (note that IEatShorts becomes IEat Shorts)
+ */
+ static kwsys_stl::string AddSpaceBetweenCapitalizedWords(
+ const kwsys_stl::string&);
+
+ /**
+ * Append two or more strings and produce new one.
+ * Programmer must 'delete []' the resulting string, which was allocated
+ * with 'new'.
+ * Return 0 if inputs are empty or there was an error
+ */
+ static char* AppendStrings(
+ const char* str1, const char* str2);
+ static char* AppendStrings(
+ const char* str1, const char* str2, const char* str3);
+
+ /**
+ * Estimate the length of the string that will be produced
+ * from printing the given format string and arguments. The
+ * returned length will always be at least as large as the string
+ * that will result from printing.
+ * WARNING: since va_arg is called to iterate of the argument list,
+ * you will not be able to use this 'ap' anymore from the beginning.
+ * It's up to you to call va_end though.
+ */
+ static int EstimateFormatLength(const char *format, va_list ap);
+
+ /**
+ * Escape specific characters in 'str'.
+ */
+ static kwsys_stl::string EscapeChars(
+ const char *str, const char *chars_to_escape, char escape_char = '\\');
+
+ /** -----------------------------------------------------------------
+ * Filename Manipulation Routines
+ * -----------------------------------------------------------------
+ */
+
+ /**
+ * Replace Windows file system slashes with Unix-style slashes.
+ */
+ static void ConvertToUnixSlashes(kwsys_stl::string& path);
+
+ /**
+ * For windows this calls ConvertToWindowsOutputPath and for unix
+ * it calls ConvertToUnixOutputPath
+ */
+ static kwsys_stl::string ConvertToOutputPath(const char*);
+
+ /**
+ * 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*);
+
+ /**
+ * Convert the path to string that can be used in a windows project or
+ * makefile. Double slashes are removed if they are not at the start of
+ * 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*);
+
+ /**
+ * Return true if a file exists in the current directory.
+ * 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.
+ */
+ static bool FileExists(const char* filename, bool isFile);
+ static bool FileExists(const char* filename);
+
+ /**
+ * Converts Cygwin path to Win32 path. Uses dictionary container for
+ * caching and calls to cygwin_conv_to_win32_path from Cygwin dll
+ * for actual translation. Returns true on success, else false.
+ */
+#ifdef __CYGWIN__
+ static bool PathCygwinToWin32(const char *path, char *win32_path);
+#endif
+
+ /**
+ * Return file length
+ */
+ static unsigned long FileLength(const char *filename);
+
+ /**
+ Change the modification time or create a file
+ */
+ static bool Touch(const char* 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,
+ int* result);
+
+ /**
+ * Get the file extension (including ".") needed for an executable
+ * on the current platform ("" for unix, ".exe" for Windows).
+ */
+ static const char* GetExecutableExtension();
+
+ /**
+ * Given a path that exists on a windows machine, return the
+ * actuall case of the path as it was created. If the file
+ * does not exist path is returned unchanged. This does nothing
+ * on unix but return path.
+ */
+ static kwsys_stl::string GetActualCaseForPath(const char* 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,
+ bool errorReport = true);
+
+ /**
+ * Given argv[0] for a unix program find the full path to a running
+ * executable. argv0 can be null for windows WinMain programs
+ * in this case GetModuleFileName will be used to find the path
+ * 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.
+ * 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,
+ const char* exeName = 0,
+ const char* buildDir = 0,
+ const char* installPrefix = 0);
+
+ /**
+ * Given a path to a file or directory, convert it to a full path.
+ * This collapses away relative paths relative to the cwd argument
+ * (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,
+ const char* 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.
+ */
+ static kwsys_stl::string GetRealPath(const char* path);
+
+ /**
+ * Split a path name into its root component and the rest of the
+ * path. The root component is one of the following:
+ * "/" = UNIX full path
+ * "c:/" = Windows full path (can be any drive letter)
+ * "c:" = Windows drive-letter relative path (can be any drive letter)
+ * "//" = Network path
+ * "~/" = Home path for current user
+ * "~u/" = Home path for user 'u'
+ * "" = Relative path
+ *
+ * A pointer to the rest of the path after the root component is
+ * returned. The root component is stored in the "root" string if
+ * given.
+ */
+ static const char* SplitPathRootComponent(const char* p,
+ kwsys_stl::string* root=0);
+
+ /**
+ * Split a path name into its basic components. The first component
+ * always exists and is the root returned by SplitPathRootComponent.
+ * The remaining components form the path. If there is a trailing
+ * slash then the last component is the empty string. The
+ * components can be recombined as "c[0]c[1]/c[2]/.../c[n]" to
+ * produce the original path. Home directory references are
+ * 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,
+ 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);
+
+ /**
+ * Compare a path or components of a path.
+ */
+ static bool ComparePath(const char* c1, const char* c2);
+
+
+ /**
+ * Return path of a full filename (no trailing slashes)
+ */
+ static kwsys_stl::string GetFilenamePath(const kwsys_stl::string&);
+
+ /**
+ * Return file name of a full filename (i.e. file name without path)
+ */
+ static kwsys_stl::string GetFilenameName(const kwsys_stl::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);
+
+ /**
+ * Return longest file extension of a full filename (dot included)
+ */
+ static kwsys_stl::string GetFilenameExtension(const kwsys_stl::string&);
+
+ /**
+ * Return shortest file extension of a full filename (dot included)
+ */
+ static kwsys_stl::string GetFilenameLastExtension(
+ const kwsys_stl::string& filename);
+
+ /**
+ * Return file name without extension of a full filename
+ */
+ static kwsys_stl::string GetFilenameWithoutExtension(
+ const kwsys_stl::string&);
+
+ /**
+ * Return file name without its last (shortest) extension
+ */
+ static kwsys_stl::string GetFilenameWithoutLastExtension(
+ const kwsys_stl::string&);
+
+ /**
+ * Return whether the path represents a full path (not relative)
+ */
+ 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);
+
+ /**
+ * 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
+ * written version of getline. Returns true if any data were read before the
+ * 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,
+ bool* has_newline=0,
+ long sizeLimit=-1);
+
+ /**
+ * Get the parent directory of the directory or file
+ */
+ static kwsys_stl::string GetParentDirectory(const char* fileOrDir);
+
+ /**
+ * Check if the given file or directory is in subdirectory of dir
+ */
+ static bool IsSubDirectory(const char* fileOrDir, const char* dir);
+
+ /** -----------------------------------------------------------------
+ * File Manipulation Routines
+ * -----------------------------------------------------------------
+ */
+
+ /**
+ * 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.
+ */
+ static bool MakeDirectory(const char* path);
+
+ /**
+ * Copy the source file to the destination file only
+ * if the two files differ.
+ */
+ static bool CopyFileIfDifferent(const char* source,
+ const char* destination);
+
+ /**
+ * Compare the contents of two files. Return true if different
+ */
+ static bool FilesDiffer(const char* source, const char* destination);
+
+ /**
+ * Return true if the two files are the same file
+ */
+ static bool SameFile(const char* file1, const char* file2);
+
+ /**
+ * Copy a file.
+ */
+ static bool CopyFileAlways(const char* source, const char* 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,
+ bool always = true);
+
+ /**
+ * Copy content directory to another directory with all files and
+ * subdirectories. If the "always" argument is true all files are
+ * 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,
+ bool always = true);
+
+ /**
+ * Remove a file
+ */
+ static bool RemoveFile(const char* source);
+
+ /**
+ * Remove a directory
+ */
+ static bool RemoveADirectory(const char* source);
+
+ /**
+ * Get the maximum full file path length
+ */
+ static size_t GetMaximumFilePathLength();
+
+ /**
+ * 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>(),
+ 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>(),
+ bool no_system_path = false);
+
+ /**
+ * Find an executable in the system PATH, with optional extra paths
+ */
+ static kwsys_stl::string FindProgram(
+ const char* name,
+ const kwsys_stl::vector<kwsys_stl::string>& path =
+ kwsys_stl::vector<kwsys_stl::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>(),
+ 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);
+
+ /**
+ * Return true if the file is a directory
+ */
+ static bool FileIsDirectory(const char* name);
+
+ /**
+ * Return true if the file is a symlink
+ */
+ static bool FileIsSymlink(const char* name);
+
+ /**
+ * Return true if the file has a given signature (first set of bytes)
+ */
+ static bool FileHasSignature(
+ const char* filename, const char *signature, long offset = 0);
+
+ /**
+ * Attempt to detect and return the type of a file.
+ * Up to 'length' bytes are read from the file, if more than 'percent_bin' %
+ * of the bytes are non-textual elements, the file is considered binary,
+ * otherwise textual. Textual elements are bytes in the ASCII [0x20, 0x7E]
+ * range, but also \\n, \\r, \\t.
+ * The algorithm is simplistic, and should probably check for usual file
+ * extensions, 'magic' signature, unicode, etc.
+ */
+ enum FileTypeEnum
+ {
+ FileTypeUnknown,
+ FileTypeBinary,
+ FileTypeText
+ };
+ static SystemTools::FileTypeEnum DetectFileType(
+ 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.
+ */
+ static bool CreateSymlink(const char* origName, const char* newName);
+
+ /**
+ * Read the contents of a symbolic link. Returns whether reading
+ * succeded.
+ */
+ static bool ReadSymlink(const char* newName, kwsys_stl::string& origName);
+
+ /**
+ * Try to locate the file 'filename' in the directory 'dir'.
+ * If 'filename' is a fully qualified filename, the basename of the file is
+ * used to check for its existence in 'dir'.
+ * If 'dir' is not a directory, GetFilenamePath() is called on 'dir' to
+ * get its directory first (thus, you can pass a filename as 'dir', as
+ * a convenience).
+ * '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,
+ * 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,
+ 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.
+ 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);
+
+ /**
+ * Return file's modified time
+ */
+ static long int ModifiedTime(const char* filename);
+
+ /**
+ * Return file's creation time (Win32: works only for NTFS, not FAT)
+ */
+ static long int CreationTime(const char* filename);
+
+ /**
+ * Get and set permissions of the file.
+ */
+ static bool GetPermissions(const char* file, mode_t& mode);
+ static bool SetPermissions(const char* file, mode_t mode);
+
+ /** -----------------------------------------------------------------
+ * Time Manipulation Routines
+ * -----------------------------------------------------------------
+ */
+
+ /** Get current time in seconds since Posix Epoch (Jan 1, 1970). */
+ static double GetTime();
+
+ /**
+ * Get current date/time
+ */
+ static kwsys_stl::string GetCurrentDateTime(const char* format);
+
+ /** -----------------------------------------------------------------
+ * Registry Manipulation Routines
+ * -----------------------------------------------------------------
+ */
+
+ /**
+ * Specify access to the 32-bit or 64-bit application view of
+ * registry values. The default is to match the currently running
+ * binary type.
+ */
+ enum KeyWOW64 { KeyWOW64_Default, KeyWOW64_32, KeyWOW64_64 };
+
+ /**
+ * Read a registry value
+ */
+ static bool ReadRegistryValue(const char *key, kwsys_stl::string &value,
+ KeyWOW64 view = KeyWOW64_Default);
+
+ /**
+ * Write a registry value
+ */
+ static bool WriteRegistryValue(const char *key, const char *value,
+ KeyWOW64 view = KeyWOW64_Default);
+
+ /**
+ * Delete a registry value
+ */
+ static bool DeleteRegistryValue(const char *key,
+ KeyWOW64 view = KeyWOW64_Default);
+
+ /** -----------------------------------------------------------------
+ * Environment Manipulation Routines
+ * -----------------------------------------------------------------
+ */
+
+ /**
+ * Add the paths from the environment variable PATH to the
+ * 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,
+ 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);
+
+ /** Put a string into the environment
+ of the form var=value */
+ static bool PutEnv(const char* 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);
+
+ /**
+ * Get current working directory CWD
+ */
+ static kwsys_stl::string GetCurrentWorkingDirectory(bool collapse =true);
+
+ /**
+ * Change directory the the directory specified
+ */
+ static int ChangeDirectory(const char* dir);
+
+ /**
+ * Get the result of strerror(errno)
+ */
+ static kwsys_stl::string GetLastSystemError();
+
+ /**
+ * When building DEBUG with MSVC, this enables a hook that prevents
+ * error dialogs from popping up if the program is being run from
+ * DART.
+ */
+ static void EnableMSVCDebugHook();
+
+ /**
+ * Get the width of the terminal window. The code may or may not work, so
+ * make sure you have some resonable defaults prepared if the code returns
+ * some bogus size.
+ */
+ static int GetTerminalWidth();
+
+ /**
+ * Add an entry in the path translation table.
+ */
+ static void AddTranslationPath(const char * dir, const char * refdir);
+
+ /**
+ * If dir is different after CollapseFullPath is called,
+ * Then insert it into the path translation table
+ */
+ static void AddKeepPath(const char* dir);
+
+ /**
+ * Update path by going through the Path Translation table;
+ */
+ static void CheckTranslationPath(kwsys_stl::string & path);
+
+ /**
+ * Delay the execution for a specified amount of time specified
+ * in miliseconds
+ */
+ static void Delay(unsigned int msec);
+
+ /**
+ * 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);
+
+ /** -----------------------------------------------------------------
+ * URL Manipulation Routines
+ * -----------------------------------------------------------------
+ */
+
+ /**
+ * Parse a character string :
+ * protocol://dataglom
+ * 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 );
+
+ /**
+ * Parse a string (a URL without protocol prefix) with the form:
+ * protocol://[[username[':'password]'@']hostname[':'dataport]]'/'[datapath]
+ * and fill protocol, username, password, hostname, dataport, and datapath
+ * 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 );
+
+private:
+ /**
+ * Allocate the stl map that serve as the Path Translation table.
+ */
+ static void ClassInitialize();
+
+ /**
+ * Deallocate the stl map that serve as the Path Translation table.
+ */
+ static void ClassFinalize();
+
+ /**
+ * This method prevents warning on SGI
+ */
+ SystemToolsManager* GetSystemToolsManager()
+ {
+ return &SystemToolsManagerInstance;
+ }
+
+ /**
+ * 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>(),
+ bool no_system_path = false);
+
+
+ /**
+ * Path translation table from dir to refdir
+ * Each time 'dir' will be found it will be replace by 'refdir'
+ */
+ static SystemToolsTranslationMap *TranslationMap;
+ static SystemToolsTranslationMap *LongPathMap;
+#ifdef __CYGWIN__
+ static SystemToolsTranslationMap *Cyg2Win32Map;
+#endif
+ friend class SystemToolsManager;
+};
+
+} // 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
new file mode 100644
index 000000000..25832c2b1
--- /dev/null
+++ b/Source/kwsys/Terminal.c
@@ -0,0 +1,432 @@
+/*============================================================================
+ 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(Terminal.h)
+
+/* Work-around CMake dependency scanning limitation. This must
+ duplicate the above list of headers. */
+#if 0
+# include "Terminal.h.in"
+#endif
+
+/*--------------------------------------------------------------------------*/
+/* Configure support for this platform. */
+#if defined(_WIN32) || defined(__CYGWIN__)
+# define KWSYS_TERMINAL_SUPPORT_CONSOLE
+#endif
+#if !defined(_WIN32)
+# define KWSYS_TERMINAL_ISATTY_WORKS
+#endif
+
+/*--------------------------------------------------------------------------*/
+/* Include needed system APIs. */
+
+#include <stdlib.h> /* getenv */
+#include <string.h> /* strcmp */
+#include <stdarg.h> /* va_list */
+
+#if defined(KWSYS_TERMINAL_SUPPORT_CONSOLE)
+# include <windows.h> /* SetConsoleTextAttribute */
+# include <io.h> /* _get_osfhandle */
+#endif
+
+#if defined(KWSYS_TERMINAL_ISATTY_WORKS)
+# include <unistd.h> /* isatty */
+#else
+# include <sys/stat.h> /* fstat */
+#endif
+
+/*--------------------------------------------------------------------------*/
+static int kwsysTerminalStreamIsVT100(FILE* stream, int default_vt100,
+ int default_tty);
+static void kwsysTerminalSetVT100Color(FILE* stream, int color);
+#if defined(KWSYS_TERMINAL_SUPPORT_CONSOLE)
+static HANDLE kwsysTerminalGetStreamHandle(FILE* stream);
+static void kwsysTerminalSetConsoleColor(HANDLE hOut,
+ CONSOLE_SCREEN_BUFFER_INFO* hOutInfo,
+ FILE* stream,
+ int color);
+#endif
+
+/*--------------------------------------------------------------------------*/
+void kwsysTerminal_cfprintf(int color, FILE* stream, const char* format, ...)
+{
+ /* Setup the stream with the given color if possible. */
+ int pipeIsConsole = 0;
+ int pipeIsVT100 = 0;
+ int default_vt100 = color & kwsysTerminal_Color_AssumeVT100;
+ int default_tty = color & kwsysTerminal_Color_AssumeTTY;
+#if defined(KWSYS_TERMINAL_SUPPORT_CONSOLE)
+ CONSOLE_SCREEN_BUFFER_INFO hOutInfo;
+ HANDLE hOut = kwsysTerminalGetStreamHandle(stream);
+ if(GetConsoleScreenBufferInfo(hOut, &hOutInfo))
+ {
+ pipeIsConsole = 1;
+ kwsysTerminalSetConsoleColor(hOut, &hOutInfo, stream, color);
+ }
+#endif
+ if(!pipeIsConsole && kwsysTerminalStreamIsVT100(stream,
+ default_vt100, default_tty))
+ {
+ pipeIsVT100 = 1;
+ kwsysTerminalSetVT100Color(stream, color);
+ }
+
+ /* Format the text into the stream. */
+ {
+ va_list var_args;
+ va_start(var_args, format);
+ vfprintf(stream, format, var_args);
+ va_end(var_args);
+ }
+
+ /* Restore the normal color state for the stream. */
+#if defined(KWSYS_TERMINAL_SUPPORT_CONSOLE)
+ if(pipeIsConsole)
+ {
+ kwsysTerminalSetConsoleColor(hOut, &hOutInfo, stream,
+ kwsysTerminal_Color_Normal);
+ }
+#endif
+ if(pipeIsVT100)
+ {
+ kwsysTerminalSetVT100Color(stream, kwsysTerminal_Color_Normal);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+/* Detect cases when a stream is definately 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
+ file. */
+ struct stat stream_stat;
+ if(fstat(fileno(stream), &stream_stat) == 0)
+ {
+ if(stream_stat.st_mode & S_IFREG)
+ {
+ return 1;
+ }
+ }
+ return 0;
+}
+#endif
+
+/*--------------------------------------------------------------------------*/
+/* List of terminal names known to support VT100 color escape sequences. */
+static const char* kwsysTerminalVT100Names[] =
+{
+ "Eterm",
+ "ansi",
+ "color-xterm",
+ "con132x25",
+ "con132x30",
+ "con132x43",
+ "con132x60",
+ "con80x25",
+ "con80x28",
+ "con80x30",
+ "con80x43",
+ "con80x50",
+ "con80x60",
+ "cons25",
+ "console",
+ "cygwin",
+ "dtterm",
+ "eterm-color",
+ "gnome",
+ "gnome-256color",
+ "konsole",
+ "konsole-256color",
+ "kterm",
+ "linux",
+ "msys",
+ "linux-c",
+ "mach-color",
+ "mlterm",
+ "putty",
+ "rxvt",
+ "rxvt-256color",
+ "rxvt-cygwin",
+ "rxvt-cygwin-native",
+ "rxvt-unicode",
+ "rxvt-unicode-256color",
+ "screen",
+ "screen-256color",
+ "screen-256color-bce",
+ "screen-bce",
+ "screen-w",
+ "screen.linux",
+ "vt100",
+ "xterm",
+ "xterm-16color",
+ "xterm-256color",
+ "xterm-88color",
+ "xterm-color",
+ "xterm-debian",
+ 0
+};
+
+/*--------------------------------------------------------------------------*/
+/* Detect whether a stream is displayed in a VT100-compatible terminal. */
+static int kwsysTerminalStreamIsVT100(FILE* stream, int default_vt100,
+ int default_tty)
+{
+ /* If running inside emacs the terminal is not VT100. Some emacs
+ seem to claim the TERM is xterm even though they do not support
+ VT100 escapes. */
+ const char* emacs = getenv("EMACS");
+ if(emacs && *emacs == 't')
+ {
+ return 0;
+ }
+
+ /* Check for a valid terminal. */
+ if(!default_vt100)
+ {
+ const char** t = 0;
+ const char* term = getenv("TERM");
+ if(term)
+ {
+ for(t = kwsysTerminalVT100Names; *t && strcmp(term, *t) != 0; ++t) {}
+ }
+ if(!(t && *t))
+ {
+ return 0;
+ }
+ }
+
+#if defined(KWSYS_TERMINAL_ISATTY_WORKS)
+ /* Make sure the stream is a tty. */
+ (void)default_tty;
+ return isatty(fileno(stream))? 1:0;
+#else
+ /* Check for cases in which the stream is definately not a tty. */
+ if(kwsysTerminalStreamIsNotInteractive(stream))
+ {
+ return 0;
+ }
+
+ /* Use the provided default for whether this is a tty. */
+ return default_tty;
+#endif
+}
+
+/*--------------------------------------------------------------------------*/
+/* VT100 escape sequence strings. */
+#define KWSYS_TERMINAL_VT100_NORMAL "\33[0m"
+#define KWSYS_TERMINAL_VT100_BOLD "\33[1m"
+#define KWSYS_TERMINAL_VT100_UNDERLINE "\33[4m"
+#define KWSYS_TERMINAL_VT100_BLINK "\33[5m"
+#define KWSYS_TERMINAL_VT100_INVERSE "\33[7m"
+#define KWSYS_TERMINAL_VT100_FOREGROUND_BLACK "\33[30m"
+#define KWSYS_TERMINAL_VT100_FOREGROUND_RED "\33[31m"
+#define KWSYS_TERMINAL_VT100_FOREGROUND_GREEN "\33[32m"
+#define KWSYS_TERMINAL_VT100_FOREGROUND_YELLOW "\33[33m"
+#define KWSYS_TERMINAL_VT100_FOREGROUND_BLUE "\33[34m"
+#define KWSYS_TERMINAL_VT100_FOREGROUND_MAGENTA "\33[35m"
+#define KWSYS_TERMINAL_VT100_FOREGROUND_CYAN "\33[36m"
+#define KWSYS_TERMINAL_VT100_FOREGROUND_WHITE "\33[37m"
+#define KWSYS_TERMINAL_VT100_BACKGROUND_BLACK "\33[40m"
+#define KWSYS_TERMINAL_VT100_BACKGROUND_RED "\33[41m"
+#define KWSYS_TERMINAL_VT100_BACKGROUND_GREEN "\33[42m"
+#define KWSYS_TERMINAL_VT100_BACKGROUND_YELLOW "\33[43m"
+#define KWSYS_TERMINAL_VT100_BACKGROUND_BLUE "\33[44m"
+#define KWSYS_TERMINAL_VT100_BACKGROUND_MAGENTA "\33[45m"
+#define KWSYS_TERMINAL_VT100_BACKGROUND_CYAN "\33[46m"
+#define KWSYS_TERMINAL_VT100_BACKGROUND_WHITE "\33[47m"
+
+/*--------------------------------------------------------------------------*/
+/* Write VT100 escape sequences to the stream for the given color. */
+static void kwsysTerminalSetVT100Color(FILE* stream, int color)
+{
+ if(color == kwsysTerminal_Color_Normal)
+ {
+ fprintf(stream, KWSYS_TERMINAL_VT100_NORMAL);
+ return;
+ }
+
+ switch(color & kwsysTerminal_Color_ForegroundMask)
+ {
+ case kwsysTerminal_Color_Normal:
+ fprintf(stream, KWSYS_TERMINAL_VT100_NORMAL);
+ break;
+ case kwsysTerminal_Color_ForegroundBlack:
+ fprintf(stream, KWSYS_TERMINAL_VT100_FOREGROUND_BLACK);
+ break;
+ case kwsysTerminal_Color_ForegroundRed:
+ fprintf(stream, KWSYS_TERMINAL_VT100_FOREGROUND_RED);
+ break;
+ case kwsysTerminal_Color_ForegroundGreen:
+ fprintf(stream, KWSYS_TERMINAL_VT100_FOREGROUND_GREEN);
+ break;
+ case kwsysTerminal_Color_ForegroundYellow:
+ fprintf(stream, KWSYS_TERMINAL_VT100_FOREGROUND_YELLOW);
+ break;
+ case kwsysTerminal_Color_ForegroundBlue:
+ fprintf(stream, KWSYS_TERMINAL_VT100_FOREGROUND_BLUE);
+ break;
+ case kwsysTerminal_Color_ForegroundMagenta:
+ fprintf(stream, KWSYS_TERMINAL_VT100_FOREGROUND_MAGENTA);
+ break;
+ case kwsysTerminal_Color_ForegroundCyan:
+ fprintf(stream, KWSYS_TERMINAL_VT100_FOREGROUND_CYAN);
+ break;
+ case kwsysTerminal_Color_ForegroundWhite:
+ fprintf(stream, KWSYS_TERMINAL_VT100_FOREGROUND_WHITE);
+ break;
+ }
+ switch(color & kwsysTerminal_Color_BackgroundMask)
+ {
+ case kwsysTerminal_Color_BackgroundBlack:
+ fprintf(stream, KWSYS_TERMINAL_VT100_BACKGROUND_BLACK);
+ break;
+ case kwsysTerminal_Color_BackgroundRed:
+ fprintf(stream, KWSYS_TERMINAL_VT100_BACKGROUND_RED);
+ break;
+ case kwsysTerminal_Color_BackgroundGreen:
+ fprintf(stream, KWSYS_TERMINAL_VT100_BACKGROUND_GREEN);
+ break;
+ case kwsysTerminal_Color_BackgroundYellow:
+ fprintf(stream, KWSYS_TERMINAL_VT100_BACKGROUND_YELLOW);
+ break;
+ case kwsysTerminal_Color_BackgroundBlue:
+ fprintf(stream, KWSYS_TERMINAL_VT100_BACKGROUND_BLUE);
+ break;
+ case kwsysTerminal_Color_BackgroundMagenta:
+ fprintf(stream, KWSYS_TERMINAL_VT100_BACKGROUND_MAGENTA);
+ break;
+ case kwsysTerminal_Color_BackgroundCyan:
+ fprintf(stream, KWSYS_TERMINAL_VT100_BACKGROUND_CYAN);
+ break;
+ case kwsysTerminal_Color_BackgroundWhite:
+ fprintf(stream, KWSYS_TERMINAL_VT100_BACKGROUND_WHITE);
+ break;
+ }
+ if(color & kwsysTerminal_Color_ForegroundBold)
+ {
+ fprintf(stream, KWSYS_TERMINAL_VT100_BOLD);
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+#if defined(KWSYS_TERMINAL_SUPPORT_CONSOLE)
+
+# define KWSYS_TERMINAL_MASK_FOREGROUND \
+ (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY)
+# define KWSYS_TERMINAL_MASK_BACKGROUND \
+ (BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY)
+
+/* Get the Windows handle for a FILE stream. */
+static HANDLE kwsysTerminalGetStreamHandle(FILE* stream)
+{
+ /* Get the C-library file descriptor from the stream. */
+ int fd = fileno(stream);
+
+# if defined(__CYGWIN__)
+ /* Cygwin seems to have an extra pipe level. If the file descriptor
+ corresponds to stdout or stderr then obtain the matching windows
+ handle directly. */
+ if(fd == fileno(stdout))
+ {
+ return GetStdHandle(STD_OUTPUT_HANDLE);
+ }
+ else if(fd == fileno(stderr))
+ {
+ return GetStdHandle(STD_ERROR_HANDLE);
+ }
+# endif
+
+ /* Get the underlying Windows handle for the descriptor. */
+ return (HANDLE)_get_osfhandle(fd);
+}
+
+/* Set color attributes in a Windows console. */
+static void kwsysTerminalSetConsoleColor(HANDLE hOut,
+ CONSOLE_SCREEN_BUFFER_INFO* hOutInfo,
+ FILE* stream,
+ int color)
+{
+ WORD attributes = 0;
+ switch(color & kwsysTerminal_Color_ForegroundMask)
+ {
+ case kwsysTerminal_Color_Normal:
+ attributes |= hOutInfo->wAttributes & KWSYS_TERMINAL_MASK_FOREGROUND;
+ break;
+ case kwsysTerminal_Color_ForegroundBlack:
+ attributes |= 0;
+ break;
+ case kwsysTerminal_Color_ForegroundRed:
+ attributes |= FOREGROUND_RED;
+ break;
+ case kwsysTerminal_Color_ForegroundGreen:
+ attributes |= FOREGROUND_GREEN;
+ break;
+ case kwsysTerminal_Color_ForegroundYellow:
+ attributes |= FOREGROUND_RED | FOREGROUND_GREEN;
+ break;
+ case kwsysTerminal_Color_ForegroundBlue:
+ attributes |= FOREGROUND_BLUE;
+ break;
+ case kwsysTerminal_Color_ForegroundMagenta:
+ attributes |= FOREGROUND_RED | FOREGROUND_BLUE;
+ break;
+ case kwsysTerminal_Color_ForegroundCyan:
+ attributes |= FOREGROUND_BLUE | FOREGROUND_GREEN;
+ break;
+ case kwsysTerminal_Color_ForegroundWhite:
+ attributes |= FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
+ break;
+ }
+ switch(color & kwsysTerminal_Color_BackgroundMask)
+ {
+ case kwsysTerminal_Color_Normal:
+ attributes |= hOutInfo->wAttributes & KWSYS_TERMINAL_MASK_BACKGROUND;
+ break;
+ case kwsysTerminal_Color_BackgroundBlack:
+ attributes |= 0;
+ break;
+ case kwsysTerminal_Color_BackgroundRed:
+ attributes |= BACKGROUND_RED;
+ break;
+ case kwsysTerminal_Color_BackgroundGreen:
+ attributes |= BACKGROUND_GREEN;
+ break;
+ case kwsysTerminal_Color_BackgroundYellow:
+ attributes |= BACKGROUND_RED | BACKGROUND_GREEN;
+ break;
+ case kwsysTerminal_Color_BackgroundBlue:
+ attributes |= BACKGROUND_BLUE;
+ break;
+ case kwsysTerminal_Color_BackgroundMagenta:
+ attributes |= BACKGROUND_RED | BACKGROUND_BLUE;
+ break;
+ case kwsysTerminal_Color_BackgroundCyan:
+ attributes |= BACKGROUND_BLUE | BACKGROUND_GREEN;
+ break;
+ case kwsysTerminal_Color_BackgroundWhite:
+ attributes |= BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED;
+ break;
+ }
+ if(color & kwsysTerminal_Color_ForegroundBold)
+ {
+ attributes |= FOREGROUND_INTENSITY;
+ }
+ if(color & kwsysTerminal_Color_BackgroundBold)
+ {
+ attributes |= BACKGROUND_INTENSITY;
+ }
+ fflush(stream);
+ SetConsoleTextAttribute(hOut, attributes);
+}
+#endif
diff --git a/Source/kwsys/Terminal.h.in b/Source/kwsys/Terminal.h.in
new file mode 100644
index 000000000..108cba017
--- /dev/null
+++ b/Source/kwsys/Terminal.h.in
@@ -0,0 +1,159 @@
+/*============================================================================
+ 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@_Terminal_h
+#define @KWSYS_NAMESPACE@_Terminal_h
+
+#include <@KWSYS_NAMESPACE@/Configure.h>
+
+#include <stdio.h> /* For file stream type FILE. */
+
+/* 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 kwsysTerminal_cfprintf kwsys_ns(Terminal_cfprintf)
+# define kwsysTerminal_Color_e kwsys_ns(Terminal_Color_e)
+# define kwsysTerminal_Color_Normal kwsys_ns(Terminal_Color_Normal)
+# define kwsysTerminal_Color_ForegroundBlack kwsys_ns(Terminal_Color_ForegroundBlack)
+# define kwsysTerminal_Color_ForegroundRed kwsys_ns(Terminal_Color_ForegroundRed)
+# define kwsysTerminal_Color_ForegroundGreen kwsys_ns(Terminal_Color_ForegroundGreen)
+# define kwsysTerminal_Color_ForegroundYellow kwsys_ns(Terminal_Color_ForegroundYellow)
+# define kwsysTerminal_Color_ForegroundBlue kwsys_ns(Terminal_Color_ForegroundBlue)
+# define kwsysTerminal_Color_ForegroundMagenta kwsys_ns(Terminal_Color_ForegroundMagenta)
+# define kwsysTerminal_Color_ForegroundCyan kwsys_ns(Terminal_Color_ForegroundCyan)
+# define kwsysTerminal_Color_ForegroundWhite kwsys_ns(Terminal_Color_ForegroundWhite)
+# define kwsysTerminal_Color_ForegroundMask kwsys_ns(Terminal_Color_ForegroundMask)
+# define kwsysTerminal_Color_BackgroundBlack kwsys_ns(Terminal_Color_BackgroundBlack)
+# define kwsysTerminal_Color_BackgroundRed kwsys_ns(Terminal_Color_BackgroundRed)
+# define kwsysTerminal_Color_BackgroundGreen kwsys_ns(Terminal_Color_BackgroundGreen)
+# define kwsysTerminal_Color_BackgroundYellow kwsys_ns(Terminal_Color_BackgroundYellow)
+# define kwsysTerminal_Color_BackgroundBlue kwsys_ns(Terminal_Color_BackgroundBlue)
+# define kwsysTerminal_Color_BackgroundMagenta kwsys_ns(Terminal_Color_BackgroundMagenta)
+# define kwsysTerminal_Color_BackgroundCyan kwsys_ns(Terminal_Color_BackgroundCyan)
+# define kwsysTerminal_Color_BackgroundWhite kwsys_ns(Terminal_Color_BackgroundWhite)
+# define kwsysTerminal_Color_BackgroundMask kwsys_ns(Terminal_Color_BackgroundMask)
+# define kwsysTerminal_Color_ForegroundBold kwsys_ns(Terminal_Color_ForegroundBold)
+# define kwsysTerminal_Color_BackgroundBold kwsys_ns(Terminal_Color_BackgroundBold)
+# define kwsysTerminal_Color_AssumeTTY kwsys_ns(Terminal_Color_AssumeTTY)
+# define kwsysTerminal_Color_AssumeVT100 kwsys_ns(Terminal_Color_AssumeVT100)
+# define kwsysTerminal_Color_AttributeMask kwsys_ns(Terminal_Color_AttributeMask)
+#endif
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+/**
+ * Write colored and formatted text to a stream. Color is used only
+ * for streams supporting it. The color specification is constructed
+ * by bitwise-OR-ing enumeration values. At most one foreground and
+ * one background value may be given.
+ *
+ * Whether the a stream supports color is usually automatically
+ * detected, but with two exceptions:
+ *
+ * - When the stream is displayed in a terminal supporting VT100
+ * color but using an intermediate pipe for communication the
+ * detection of a tty fails. (This typically occurs for a shell
+ * running in an rxvt terminal in MSYS.) If the caller knows this
+ * to be the case, the attribute Color_AssumeTTY may be included in
+ * the color specification.
+ *
+ * - When the stream is displayed in a terminal whose TERM
+ * environment variable is not set or is set to a value that is not
+ * known to support VT100 colors. If the caller knows this to be
+ * the case, the attribute Color_AssumeVT100 may be included in the
+ * color specification.
+ */
+kwsysEXPORT void kwsysTerminal_cfprintf(int color, FILE* stream,
+ const char* format, ...);
+enum kwsysTerminal_Color_e
+{
+ /* Normal Text */
+ kwsysTerminal_Color_Normal = 0,
+
+ /* Foreground Color */
+ kwsysTerminal_Color_ForegroundBlack = 0x1,
+ kwsysTerminal_Color_ForegroundRed = 0x2,
+ kwsysTerminal_Color_ForegroundGreen = 0x3,
+ kwsysTerminal_Color_ForegroundYellow = 0x4,
+ kwsysTerminal_Color_ForegroundBlue = 0x5,
+ kwsysTerminal_Color_ForegroundMagenta = 0x6,
+ kwsysTerminal_Color_ForegroundCyan = 0x7,
+ kwsysTerminal_Color_ForegroundWhite = 0x8,
+ kwsysTerminal_Color_ForegroundMask = 0xF,
+
+ /* Background Color */
+ kwsysTerminal_Color_BackgroundBlack = 0x10,
+ kwsysTerminal_Color_BackgroundRed = 0x20,
+ kwsysTerminal_Color_BackgroundGreen = 0x30,
+ kwsysTerminal_Color_BackgroundYellow = 0x40,
+ kwsysTerminal_Color_BackgroundBlue = 0x50,
+ kwsysTerminal_Color_BackgroundMagenta = 0x60,
+ kwsysTerminal_Color_BackgroundCyan = 0x70,
+ kwsysTerminal_Color_BackgroundWhite = 0x80,
+ kwsysTerminal_Color_BackgroundMask = 0xF0,
+
+ /* Attributes */
+ kwsysTerminal_Color_ForegroundBold = 0x100,
+ kwsysTerminal_Color_BackgroundBold = 0x200,
+ kwsysTerminal_Color_AssumeTTY = 0x400,
+ kwsysTerminal_Color_AssumeVT100 = 0x800,
+ kwsysTerminal_Color_AttributeMask = 0xF00
+};
+
+#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 !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
+# undef kwsysTerminal_cfprintf
+# undef kwsysTerminal_Color_e
+# undef kwsysTerminal_Color_Normal
+# undef kwsysTerminal_Color_ForegroundBlack
+# undef kwsysTerminal_Color_ForegroundRed
+# undef kwsysTerminal_Color_ForegroundGreen
+# undef kwsysTerminal_Color_ForegroundYellow
+# undef kwsysTerminal_Color_ForegroundBlue
+# undef kwsysTerminal_Color_ForegroundMagenta
+# undef kwsysTerminal_Color_ForegroundCyan
+# undef kwsysTerminal_Color_ForegroundWhite
+# undef kwsysTerminal_Color_ForegroundMask
+# undef kwsysTerminal_Color_BackgroundBlack
+# undef kwsysTerminal_Color_BackgroundRed
+# undef kwsysTerminal_Color_BackgroundGreen
+# undef kwsysTerminal_Color_BackgroundYellow
+# undef kwsysTerminal_Color_BackgroundBlue
+# undef kwsysTerminal_Color_BackgroundMagenta
+# undef kwsysTerminal_Color_BackgroundCyan
+# undef kwsysTerminal_Color_BackgroundWhite
+# undef kwsysTerminal_Color_BackgroundMask
+# undef kwsysTerminal_Color_ForegroundBold
+# undef kwsysTerminal_Color_BackgroundBold
+# undef kwsysTerminal_Color_AssumeTTY
+# undef kwsysTerminal_Color_AssumeVT100
+# undef kwsysTerminal_Color_AttributeMask
+# endif
+#endif
+
+#endif
diff --git a/Source/kwsys/auto_ptr.hxx.in b/Source/kwsys/auto_ptr.hxx.in
new file mode 100644
index 000000000..857b1db3c
--- /dev/null
+++ b/Source/kwsys/auto_ptr.hxx.in
@@ -0,0 +1,201 @@
+/*============================================================================
+ 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@_auto_ptr_hxx
+#define @KWSYS_NAMESPACE@_auto_ptr_hxx
+
+#include <@KWSYS_NAMESPACE@/Configure.hxx>
+
+// The HP compiler and VS6 cannot handle the conversions necessary to use
+// auto_ptr_ref to pass an auto_ptr returned from one function
+// directly to another function as in use_auto_ptr(get_auto_ptr()).
+// We instead use const_cast to achieve the syntax on those platforms.
+// We do not use const_cast on other platforms to maintain the C++
+// standard design and guarantee that if an auto_ptr is bound
+// to a reference-to-const then ownership will be maintained.
+#if defined(__HP_aCC) || (defined(_MSC_VER) && _MSC_VER <= 1200)
+# define @KWSYS_NAMESPACE@_AUTO_PTR_REF 0
+# define @KWSYS_NAMESPACE@_AUTO_PTR_CONST const
+# define @KWSYS_NAMESPACE@_AUTO_PTR_CAST(a) cast(a)
+#else
+# define @KWSYS_NAMESPACE@_AUTO_PTR_REF 1
+# define @KWSYS_NAMESPACE@_AUTO_PTR_CONST
+# define @KWSYS_NAMESPACE@_AUTO_PTR_CAST(a) a
+#endif
+
+namespace @KWSYS_NAMESPACE@
+{
+
+template <class X> class auto_ptr;
+
+#if @KWSYS_NAMESPACE@_AUTO_PTR_REF
+namespace detail
+{
+// The auto_ptr_ref template is supposed to be a private member of
+// auto_ptr but Borland 5.8 cannot handle it. Instead put it in
+// a private namespace.
+template <class Y> struct auto_ptr_ref
+{
+ Y* p_;
+
+ // The extra constructor argument prevents implicit conversion to
+ // auto_ptr_ref from auto_ptr through the constructor. Normally
+ // this should be done with the explicit keyword but Borland 5.x
+ // generates code in the conversion operator to call itself
+ // infinately.
+ auto_ptr_ref(Y* p, int): p_(p) {}
+};
+}
+#endif
+
+/** C++98 Standard Section 20.4.5 - Template class auto_ptr. */
+template <class X>
+class auto_ptr
+{
+#if !@KWSYS_NAMESPACE@_AUTO_PTR_REF
+ template <typename Y>
+ static inline auto_ptr<Y>& cast(auto_ptr<Y> const& a)
+ { return const_cast<auto_ptr<Y>&>(a); }
+#endif
+
+ /** The pointer to the object held. */
+ X* x_;
+
+public:
+ /** The type of object held by the auto_ptr. */
+ typedef X element_type;
+
+ /** Construct from an auto_ptr holding a compatible object. This
+ transfers ownership to the newly constructed auto_ptr. */
+ template <class Y>
+ auto_ptr(auto_ptr<Y> @KWSYS_NAMESPACE@_AUTO_PTR_CONST& a) throw():
+ x_(@KWSYS_NAMESPACE@_AUTO_PTR_CAST(a).release())
+ {
+ }
+
+ /** Assign from an auto_ptr holding a compatible object. This
+ transfers ownership to the left-hand-side of the assignment. */
+ template <class Y>
+ auto_ptr& operator=(auto_ptr<Y> @KWSYS_NAMESPACE@_AUTO_PTR_CONST& a) throw()
+ {
+ this->reset(@KWSYS_NAMESPACE@_AUTO_PTR_CAST(a).release());
+ return *this;
+ }
+
+ /**
+ * Explicitly construct from a raw pointer. This is typically
+ * called with the result of operator new. For example:
+ *
+ * auto_ptr<X> ptr(new X());
+ */
+ explicit auto_ptr(X* p=0) throw(): x_(p)
+ {
+ }
+
+ /** Construct from another auto_ptr holding an object of the same
+ type. This transfers ownership to the newly constructed
+ auto_ptr. */
+ auto_ptr(auto_ptr @KWSYS_NAMESPACE@_AUTO_PTR_CONST& a) throw():
+ x_(@KWSYS_NAMESPACE@_AUTO_PTR_CAST(a).release())
+ {
+ }
+
+ /** Assign from another auto_ptr holding an object of the same type.
+ This transfers ownership to the newly constructed auto_ptr. */
+ auto_ptr& operator=(auto_ptr @KWSYS_NAMESPACE@_AUTO_PTR_CONST& a) throw()
+ {
+ this->reset(@KWSYS_NAMESPACE@_AUTO_PTR_CAST(a).release());
+ return *this;
+ }
+
+ /** Destruct and delete the object held. */
+ ~auto_ptr() throw()
+ {
+ // Assume object destructor is nothrow.
+ delete this->x_;
+ }
+
+ /** Dereference and return a reference to the object held. */
+ X& operator*() const throw()
+ {
+ return *this->x_;
+ }
+
+ /** Return a pointer to the object held. */
+ X* operator->() const throw()
+ {
+ return this->x_;
+ }
+
+ /** Return a pointer to the object held. */
+ X* get() const throw()
+ {
+ return this->x_;
+ }
+
+ /** Return a pointer to the object held and reset to hold no object.
+ This transfers ownership to the caller. */
+ X* release() throw()
+ {
+ X* x = this->x_;
+ this->x_ = 0;
+ return x;
+ }
+
+ /** Assume ownership of the given object. The object previously
+ held is deleted. */
+ void reset(X* p=0) throw()
+ {
+ if(this->x_ != p)
+ {
+ // Assume object destructor is nothrow.
+ delete this->x_;
+ this->x_ = p;
+ }
+ }
+
+ /** Convert to an auto_ptr holding an object of a compatible type.
+ This transfers ownership to the returned auto_ptr. */
+ template <class Y> operator auto_ptr<Y>() throw()
+ {
+ return auto_ptr<Y>(this->release());
+ }
+
+#if @KWSYS_NAMESPACE@_AUTO_PTR_REF
+ /** Construct from an auto_ptr_ref. This is used when the
+ constructor argument is a call to a function returning an
+ auto_ptr. */
+ auto_ptr(detail::auto_ptr_ref<X> r) throw(): x_(r.p_)
+ {
+ }
+
+ /** Assign from an auto_ptr_ref. This is used when a function
+ returning an auto_ptr is passed on the right-hand-side of an
+ assignment. */
+ auto_ptr& operator=(detail::auto_ptr_ref<X> r) throw()
+ {
+ this->reset(r.p_);
+ return *this;
+ }
+
+ /** Convert to an auto_ptr_ref. This is used when a function
+ returning an auto_ptr is the argument to the constructor of
+ another auto_ptr. */
+ template <class Y> operator detail::auto_ptr_ref<Y>() throw()
+ {
+ return detail::auto_ptr_ref<Y>(this->release(), 1);
+ }
+#endif
+};
+
+} // namespace @KWSYS_NAMESPACE@
+
+#endif
diff --git a/Source/kwsys/hash_fun.hxx.in b/Source/kwsys/hash_fun.hxx.in
new file mode 100644
index 000000000..6f787ddc5
--- /dev/null
+++ b/Source/kwsys/hash_fun.hxx.in
@@ -0,0 +1,149 @@
+/*============================================================================
+ 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.
+============================================================================*/
+/*
+ * Copyright (c) 1996
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+#ifndef @KWSYS_NAMESPACE@_hash_fun_hxx
+#define @KWSYS_NAMESPACE@_hash_fun_hxx
+
+#include <@KWSYS_NAMESPACE@/Configure.hxx>
+#include <@KWSYS_NAMESPACE@/cstddef> // size_t
+#include <@KWSYS_NAMESPACE@/stl/string> // string
+
+namespace @KWSYS_NAMESPACE@
+{
+
+template <class _Key> struct hash { };
+
+inline size_t _stl_hash_string(const char* __s)
+{
+ unsigned long __h = 0;
+ for ( ; *__s; ++__s)
+ __h = 5*__h + *__s;
+
+ return size_t(__h);
+}
+
+@KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+struct hash<char*> {
+ size_t operator()(const char* __s) const { return _stl_hash_string(__s); }
+};
+
+@KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+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()); }
+};
+
+#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()); }
+};
+#endif
+
+@KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+struct hash<char> {
+ size_t operator()(char __x) const { return __x; }
+};
+
+@KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+struct hash<unsigned char> {
+ size_t operator()(unsigned char __x) const { return __x; }
+};
+
+@KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+struct hash<signed char> {
+ size_t operator()(unsigned char __x) const { return __x; }
+};
+
+@KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+struct hash<short> {
+ size_t operator()(short __x) const { return __x; }
+};
+
+@KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+struct hash<unsigned short> {
+ size_t operator()(unsigned short __x) const { return __x; }
+};
+
+@KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+struct hash<int> {
+ size_t operator()(int __x) const { return __x; }
+};
+
+@KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+struct hash<unsigned int> {
+ size_t operator()(unsigned int __x) const { return __x; }
+};
+
+@KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+struct hash<long> {
+ size_t operator()(long __x) const { return __x; }
+};
+
+@KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+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
+struct hash<long long> {
+ size_t operator()(long long __x) const { return __x; }
+};
+
+@KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+struct hash<unsigned long long> {
+ size_t operator()(unsigned long long __x) const { return __x; }
+};
+#elif @KWSYS_USE___INT64@
+@KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+struct hash<__int64> {
+ size_t operator()(__int64 __x) const { return __x; }
+};
+@KWSYS_NAMESPACE@_CXX_DEFINE_SPECIALIZATION
+struct hash<unsigned __int64> {
+ size_t operator()(unsigned __int64 __x) const { return __x; }
+};
+#endif // use long long or __int64
+
+} // namespace @KWSYS_NAMESPACE@
+
+#endif
diff --git a/Source/kwsys/hash_map.hxx.in b/Source/kwsys/hash_map.hxx.in
new file mode 100644
index 000000000..6d4379d8e
--- /dev/null
+++ b/Source/kwsys/hash_map.hxx.in
@@ -0,0 +1,461 @@
+/*============================================================================
+ 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.
+============================================================================*/
+/*
+ * Copyright (c) 1996
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+#ifndef @KWSYS_NAMESPACE@_hash_map_hxx
+#define @KWSYS_NAMESPACE@_hash_map_hxx
+
+#include <@KWSYS_NAMESPACE@/hashtable.hxx>
+#include <@KWSYS_NAMESPACE@/hash_fun.hxx>
+#include <@KWSYS_NAMESPACE@/stl/functional> // equal_to
+
+#if defined(_MSC_VER)
+# pragma warning (push)
+# pragma warning (disable:4284)
+# pragma warning (disable:4786)
+#endif
+
+#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
+# pragma set woff 1174
+# pragma set woff 1375
+#endif
+
+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>
+{
+ const T1& operator()(const @KWSYS_NAMESPACE@_stl::pair<T1, T2>& __x) const
+ { return __x.first; }
+};
+
+// Forward declaration of equality operator; needed for friend declaration.
+
+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 hash_map;
+
+template <class _Key, class _Tp, class _HashFn, class _EqKey, class _Alloc>
+bool operator==(const hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc>&,
+ const hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc>&);
+
+template <class _Key, class _Tp, class _HashFcn, class _EqualKey,
+ class _Alloc>
+class hash_map
+{
+private:
+ typedef hashtable<@KWSYS_NAMESPACE@_stl::pair<const _Key,_Tp>,_Key,_HashFcn,
+ hash_select1st<const _Key,_Tp>,_EqualKey,_Alloc> _Ht;
+ _Ht _M_ht;
+
+public:
+ typedef typename _Ht::key_type key_type;
+ typedef _Tp data_type;
+ typedef _Tp mapped_type;
+ typedef typename _Ht::value_type value_type;
+ typedef typename _Ht::hasher hasher;
+ typedef typename _Ht::key_equal key_equal;
+
+ typedef typename _Ht::size_type size_type;
+ typedef typename _Ht::difference_type difference_type;
+ typedef typename _Ht::pointer pointer;
+ typedef typename _Ht::const_pointer const_pointer;
+ typedef typename _Ht::reference reference;
+ typedef typename _Ht::const_reference const_reference;
+
+ typedef typename _Ht::iterator iterator;
+ typedef typename _Ht::const_iterator const_iterator;
+
+ typedef typename _Ht::allocator_type allocator_type;
+
+ hasher hash_funct() const { return _M_ht.hash_funct(); }
+ key_equal key_eq() const { return _M_ht.key_eq(); }
+ allocator_type get_allocator() const { return _M_ht.get_allocator(); }
+
+public:
+ hash_map() : _M_ht(100, hasher(), key_equal(), allocator_type()) {}
+ explicit hash_map(size_type __n)
+ : _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
+ hash_map(size_type __n, const hasher& __hf)
+ : _M_ht(__n, __hf, key_equal(), allocator_type()) {}
+ hash_map(size_type __n, const hasher& __hf, const key_equal& __eql,
+ 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())
+ { _M_ht.insert_unique(__f, __l); }
+ template <class _InputIterator>
+ hash_map(_InputIterator __f, _InputIterator __l, size_type __n)
+ : _M_ht(__n, hasher(), key_equal(), allocator_type())
+ { _M_ht.insert_unique(__f, __l); }
+ template <class _InputIterator>
+ hash_map(_InputIterator __f, _InputIterator __l, size_type __n,
+ const hasher& __hf)
+ : _M_ht(__n, __hf, key_equal(), allocator_type())
+ { _M_ht.insert_unique(__f, __l); }
+ template <class _InputIterator>
+ hash_map(_InputIterator __f, _InputIterator __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); }
+
+#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&);
+
+ iterator begin() { return _M_ht.begin(); }
+ iterator end() { return _M_ht.end(); }
+ const_iterator begin() const { return _M_ht.begin(); }
+ const_iterator end() const { return _M_ht.end(); }
+
+public:
+ @KWSYS_NAMESPACE@_stl::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)
+ { return _M_ht.insert_unique_noresize(__obj); }
+
+ iterator find(const key_type& __key) { return _M_ht.find(__key); }
+ const_iterator find(const key_type& __key) const
+ { return _M_ht.find(__key); }
+
+ _Tp& operator[](const key_type& __key) {
+ return _M_ht.find_or_insert(value_type(__key, _Tp())).second;
+ }
+
+ 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)
+ { return _M_ht.equal_range(__key); }
+ @KWSYS_NAMESPACE@_stl::pair<const_iterator, const_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); }
+ void erase(iterator __it) { _M_ht.erase(__it); }
+ void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); }
+ void clear() { _M_ht.clear(); }
+
+ void resize(size_type __hint) { _M_ht.resize(__hint); }
+ size_type bucket_count() const { return _M_ht.bucket_count(); }
+ size_type max_bucket_count() const { return _M_ht.max_bucket_count(); }
+ size_type elems_in_bucket(size_type __n) const
+ { return _M_ht.elems_in_bucket(__n); }
+};
+
+template <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc>
+bool
+operator==(const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1,
+ const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2)
+{
+ return __hm1._M_ht == __hm2._M_ht;
+}
+
+template <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc>
+inline bool
+operator!=(const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1,
+ const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2) {
+ return !(__hm1 == __hm2);
+}
+
+template <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc>
+inline void
+swap(hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1,
+ hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2)
+{
+ __hm1.swap(__hm2);
+}
+
+// Forward declaration of equality operator; needed for friend declaration.
+
+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 hash_multimap;
+
+template <class _Key, class _Tp, class _HF, class _EqKey, class _Alloc>
+bool
+operator==(const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm1,
+ const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm2);
+
+template <class _Key, class _Tp, class _HashFcn, class _EqualKey,
+ class _Alloc>
+class hash_multimap
+{
+private:
+ typedef hashtable<@KWSYS_NAMESPACE@_stl::pair<const _Key, _Tp>, _Key, _HashFcn,
+ hash_select1st<const _Key, _Tp>, _EqualKey, _Alloc>
+ _Ht;
+ _Ht _M_ht;
+
+public:
+ typedef typename _Ht::key_type key_type;
+ typedef _Tp data_type;
+ typedef _Tp mapped_type;
+ typedef typename _Ht::value_type value_type;
+ typedef typename _Ht::hasher hasher;
+ typedef typename _Ht::key_equal key_equal;
+
+ typedef typename _Ht::size_type size_type;
+ typedef typename _Ht::difference_type difference_type;
+ typedef typename _Ht::pointer pointer;
+ typedef typename _Ht::const_pointer const_pointer;
+ typedef typename _Ht::reference reference;
+ typedef typename _Ht::const_reference const_reference;
+
+ typedef typename _Ht::iterator iterator;
+ typedef typename _Ht::const_iterator const_iterator;
+
+ typedef typename _Ht::allocator_type allocator_type;
+
+ hasher hash_funct() const { return _M_ht.hash_funct(); }
+ key_equal key_eq() const { return _M_ht.key_eq(); }
+ allocator_type get_allocator() const { return _M_ht.get_allocator(); }
+
+public:
+ hash_multimap() : _M_ht(100, hasher(), key_equal(), allocator_type()) {}
+ explicit hash_multimap(size_type __n)
+ : _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
+ hash_multimap(size_type __n, const hasher& __hf)
+ : _M_ht(__n, __hf, key_equal(), allocator_type()) {}
+ hash_multimap(size_type __n, const hasher& __hf, const key_equal& __eql,
+ 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())
+ { _M_ht.insert_equal(__f, __l); }
+ template <class _InputIterator>
+ hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n)
+ : _M_ht(__n, hasher(), key_equal(), allocator_type())
+ { _M_ht.insert_equal(__f, __l); }
+ template <class _InputIterator>
+ hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n,
+ const hasher& __hf)
+ : _M_ht(__n, __hf, key_equal(), allocator_type())
+ { _M_ht.insert_equal(__f, __l); }
+ template <class _InputIterator>
+ hash_multimap(_InputIterator __f, _InputIterator __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); }
+
+#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&);
+
+ iterator begin() { return _M_ht.begin(); }
+ iterator end() { return _M_ht.end(); }
+ const_iterator begin() const { return _M_ht.begin(); }
+ const_iterator end() const { return _M_ht.end(); }
+
+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); }
+
+ iterator find(const key_type& __key) { return _M_ht.find(__key); }
+ const_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)
+ { return _M_ht.equal_range(__key); }
+ @KWSYS_NAMESPACE@_stl::pair<const_iterator, const_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); }
+ void erase(iterator __it) { _M_ht.erase(__it); }
+ void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); }
+ void clear() { _M_ht.clear(); }
+
+public:
+ void resize(size_type __hint) { _M_ht.resize(__hint); }
+ size_type bucket_count() const { return _M_ht.bucket_count(); }
+ size_type max_bucket_count() const { return _M_ht.max_bucket_count(); }
+ size_type elems_in_bucket(size_type __n) const
+ { return _M_ht.elems_in_bucket(__n); }
+};
+
+template <class _Key, class _Tp, class _HF, class _EqKey, class _Alloc>
+bool
+operator==(const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm1,
+ const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm2)
+{
+ return __hm1._M_ht == __hm2._M_ht;
+}
+
+template <class _Key, class _Tp, class _HF, class _EqKey, class _Alloc>
+inline bool
+operator!=(const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm1,
+ const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm2) {
+ return !(__hm1 == __hm2);
+}
+
+template <class _Key, class _Tp, class _HashFcn, class _EqlKey, class _Alloc>
+inline void
+swap(hash_multimap<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1,
+ hash_multimap<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2)
+{
+ __hm1.swap(__hm2);
+}
+
+} // namespace @KWSYS_NAMESPACE@
+
+#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
+# pragma reset woff 1174
+# pragma reset woff 1375
+#endif
+
+#if defined(_MSC_VER)
+# pragma warning (pop)
+#endif
+
+#endif
diff --git a/Source/kwsys/hash_set.hxx.in b/Source/kwsys/hash_set.hxx.in
new file mode 100644
index 000000000..5ee01a594
--- /dev/null
+++ b/Source/kwsys/hash_set.hxx.in
@@ -0,0 +1,445 @@
+/*============================================================================
+ 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.
+============================================================================*/
+/*
+ * Copyright (c) 1996
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+#ifndef @KWSYS_NAMESPACE@_hash_set_hxx
+#define @KWSYS_NAMESPACE@_hash_set_hxx
+
+#include <@KWSYS_NAMESPACE@/hashtable.hxx>
+#include <@KWSYS_NAMESPACE@/hash_fun.hxx>
+#include <@KWSYS_NAMESPACE@/stl/functional> // equal_to
+
+#if defined(_MSC_VER)
+# pragma warning (push)
+# pragma warning (disable:4284)
+# pragma warning (disable:4786)
+#endif
+
+#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
+# pragma set woff 1174
+# pragma set woff 1375
+#endif
+
+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>
+{
+ const _Tp& operator()(const _Tp& __x) const { return __x; }
+};
+
+// Forward declaration of equality operator; needed for friend declaration.
+
+template <class _Value,
+ class _HashFcn = hash<_Value>,
+ class _EqualKey = @KWSYS_NAMESPACE@_stl::equal_to<_Value>,
+ class _Alloc = @KWSYS_NAMESPACE@_HASH_DEFAULT_ALLOCATOR(char) >
+class hash_set;
+
+template <class _Value, class _HashFcn, class _EqualKey, class _Alloc>
+bool
+operator==(const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs1,
+ const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs2);
+
+template <class _Value, class _HashFcn, class _EqualKey, class _Alloc>
+class hash_set
+{
+private:
+ typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>,
+ _EqualKey, _Alloc> _Ht;
+ _Ht _M_ht;
+
+public:
+ typedef typename _Ht::key_type key_type;
+ typedef typename _Ht::value_type value_type;
+ typedef typename _Ht::hasher hasher;
+ typedef typename _Ht::key_equal key_equal;
+
+ typedef typename _Ht::size_type size_type;
+ typedef typename _Ht::difference_type difference_type;
+ typedef typename _Ht::const_pointer pointer;
+ typedef typename _Ht::const_pointer const_pointer;
+ typedef typename _Ht::const_reference reference;
+ typedef typename _Ht::const_reference const_reference;
+
+ typedef typename _Ht::const_iterator iterator;
+ typedef typename _Ht::const_iterator const_iterator;
+
+ typedef typename _Ht::allocator_type allocator_type;
+
+ hasher hash_funct() const { return _M_ht.hash_funct(); }
+ key_equal key_eq() const { return _M_ht.key_eq(); }
+ allocator_type get_allocator() const { return _M_ht.get_allocator(); }
+
+public:
+ hash_set()
+ : _M_ht(100, hasher(), key_equal(), allocator_type()) {}
+ explicit hash_set(size_type __n)
+ : _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
+ hash_set(size_type __n, const hasher& __hf)
+ : _M_ht(__n, __hf, key_equal(), allocator_type()) {}
+ hash_set(size_type __n, const hasher& __hf, const key_equal& __eql,
+ 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())
+ { _M_ht.insert_unique(__f, __l); }
+ template <class _InputIterator>
+ hash_set(_InputIterator __f, _InputIterator __l, size_type __n)
+ : _M_ht(__n, hasher(), key_equal(), allocator_type())
+ { _M_ht.insert_unique(__f, __l); }
+ template <class _InputIterator>
+ hash_set(_InputIterator __f, _InputIterator __l, size_type __n,
+ const hasher& __hf)
+ : _M_ht(__n, __hf, key_equal(), allocator_type())
+ { _M_ht.insert_unique(__f, __l); }
+ template <class _InputIterator>
+ hash_set(_InputIterator __f, _InputIterator __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); }
+#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(); }
+ size_type max_size() const { return _M_ht.max_size(); }
+ 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&);
+
+ 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)
+ {
+ 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);
+ }
+#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)
+ {
+ typedef typename _Ht::iterator _Ht_iterator;
+ @KWSYS_NAMESPACE@_stl::pair<_Ht_iterator, bool> __p =
+ _M_ht.insert_unique_noresize(__obj);
+ return @KWSYS_NAMESPACE@_stl::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
+ { return _M_ht.equal_range(__key); }
+
+ size_type erase(const key_type& __key) {return _M_ht.erase(__key); }
+ void erase(iterator __it) { _M_ht.erase(__it); }
+ void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); }
+ void clear() { _M_ht.clear(); }
+
+public:
+ void resize(size_type __hint) { _M_ht.resize(__hint); }
+ size_type bucket_count() const { return _M_ht.bucket_count(); }
+ size_type max_bucket_count() const { return _M_ht.max_bucket_count(); }
+ size_type elems_in_bucket(size_type __n) const
+ { return _M_ht.elems_in_bucket(__n); }
+};
+
+template <class _Value, class _HashFcn, class _EqualKey, class _Alloc>
+bool
+operator==(const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs1,
+ const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs2)
+{
+ return __hs1._M_ht == __hs2._M_ht;
+}
+
+template <class _Value, class _HashFcn, class _EqualKey, class _Alloc>
+inline bool
+operator!=(const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs1,
+ const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs2) {
+ return !(__hs1 == __hs2);
+}
+
+template <class _Val, class _HashFcn, class _EqualKey, class _Alloc>
+inline void
+swap(hash_set<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1,
+ hash_set<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2)
+{
+ __hs1.swap(__hs2);
+}
+
+template <class _Value,
+ class _HashFcn = hash<_Value>,
+ class _EqualKey = @KWSYS_NAMESPACE@_stl::equal_to<_Value>,
+ class _Alloc = @KWSYS_NAMESPACE@_HASH_DEFAULT_ALLOCATOR(char) >
+class hash_multiset;
+
+template <class _Val, class _HashFcn, class _EqualKey, class _Alloc>
+bool
+operator==(const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1,
+ const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2);
+
+
+template <class _Value, class _HashFcn, class _EqualKey, class _Alloc>
+class hash_multiset
+{
+private:
+ typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>,
+ _EqualKey, _Alloc> _Ht;
+ _Ht _M_ht;
+
+public:
+ typedef typename _Ht::key_type key_type;
+ typedef typename _Ht::value_type value_type;
+ typedef typename _Ht::hasher hasher;
+ typedef typename _Ht::key_equal key_equal;
+
+ typedef typename _Ht::size_type size_type;
+ typedef typename _Ht::difference_type difference_type;
+ typedef typename _Ht::const_pointer pointer;
+ typedef typename _Ht::const_pointer const_pointer;
+ typedef typename _Ht::const_reference reference;
+ typedef typename _Ht::const_reference const_reference;
+
+ typedef typename _Ht::const_iterator iterator;
+ typedef typename _Ht::const_iterator const_iterator;
+
+ typedef typename _Ht::allocator_type allocator_type;
+
+ hasher hash_funct() const { return _M_ht.hash_funct(); }
+ key_equal key_eq() const { return _M_ht.key_eq(); }
+ allocator_type get_allocator() const { return _M_ht.get_allocator(); }
+
+public:
+ hash_multiset()
+ : _M_ht(100, hasher(), key_equal(), allocator_type()) {}
+ explicit hash_multiset(size_type __n)
+ : _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
+ hash_multiset(size_type __n, const hasher& __hf)
+ : _M_ht(__n, __hf, key_equal(), allocator_type()) {}
+ hash_multiset(size_type __n, const hasher& __hf, const key_equal& __eql,
+ 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())
+ { _M_ht.insert_equal(__f, __l); }
+ template <class _InputIterator>
+ hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n)
+ : _M_ht(__n, hasher(), key_equal(), allocator_type())
+ { _M_ht.insert_equal(__f, __l); }
+ template <class _InputIterator>
+ hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n,
+ const hasher& __hf)
+ : _M_ht(__n, __hf, key_equal(), allocator_type())
+ { _M_ht.insert_equal(__f, __l); }
+ template <class _InputIterator>
+ hash_multiset(_InputIterator __f, _InputIterator __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); }
+#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(); }
+ size_type max_size() const { return _M_ht.max_size(); }
+ 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&);
+
+ iterator begin() const { return _M_ht.begin(); }
+ iterator end() const { return _M_ht.end(); }
+
+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); }
+
+ 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
+ { return _M_ht.equal_range(__key); }
+
+ size_type erase(const key_type& __key) {return _M_ht.erase(__key); }
+ void erase(iterator __it) { _M_ht.erase(__it); }
+ void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); }
+ void clear() { _M_ht.clear(); }
+
+public:
+ void resize(size_type __hint) { _M_ht.resize(__hint); }
+ size_type bucket_count() const { return _M_ht.bucket_count(); }
+ size_type max_bucket_count() const { return _M_ht.max_bucket_count(); }
+ size_type elems_in_bucket(size_type __n) const
+ { return _M_ht.elems_in_bucket(__n); }
+};
+
+template <class _Val, class _HashFcn, class _EqualKey, class _Alloc>
+bool
+operator==(const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1,
+ const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2)
+{
+ return __hs1._M_ht == __hs2._M_ht;
+}
+
+template <class _Val, class _HashFcn, class _EqualKey, class _Alloc>
+inline bool
+operator!=(const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1,
+ const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2) {
+ return !(__hs1 == __hs2);
+}
+
+template <class _Val, class _HashFcn, class _EqualKey, class _Alloc>
+inline void
+swap(hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1,
+ hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2) {
+ __hs1.swap(__hs2);
+}
+
+} // namespace @KWSYS_NAMESPACE@
+
+#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
+# pragma reset woff 1174
+# pragma reset woff 1375
+#endif
+
+#if defined(_MSC_VER)
+# pragma warning (pop)
+#endif
+
+#endif
diff --git a/Source/kwsys/hashtable.hxx.in b/Source/kwsys/hashtable.hxx.in
new file mode 100644
index 000000000..c83550304
--- /dev/null
+++ b/Source/kwsys/hashtable.hxx.in
@@ -0,0 +1,1275 @@
+/*============================================================================
+ 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.
+============================================================================*/
+/*
+ * Copyright (c) 1996
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+#ifdef __BORLANDC__
+# pragma warn -8027 /* 'for' not inlined. */
+# pragma warn -8026 /* 'exception' not inlined. */
+#endif
+
+#ifndef @KWSYS_NAMESPACE@_hashtable_hxx
+#define @KWSYS_NAMESPACE@_hashtable_hxx
+
+#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
+
+#if defined(_MSC_VER)
+# pragma warning (push)
+# pragma warning (disable:4284)
+# pragma warning (disable:4786)
+# pragma warning (disable:4512) /* no assignment operator for class */
+#endif
+#if defined(__sgi) && !defined(__GNUC__)
+# pragma set woff 3970 /* pointer to int conversion */ 3321 3968
+#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;
+};
+
+template <class _Val, class _Key, class _HashFcn,
+ class _ExtractKey, class _EqualKey,
+ class _Alloc = @KWSYS_NAMESPACE@_HASH_DEFAULT_ALLOCATOR(char) >
+class hashtable;
+
+template <class _Val, class _Key, class _HashFcn,
+ class _ExtractKey, class _EqualKey, class _Alloc>
+struct _Hashtable_iterator;
+
+template <class _Val, class _Key, class _HashFcn,
+ class _ExtractKey, class _EqualKey, class _Alloc>
+struct _Hashtable_const_iterator;
+
+template <class _Val, class _Key, class _HashFcn,
+ class _ExtractKey, class _EqualKey, class _Alloc>
+struct _Hashtable_iterator {
+ typedef hashtable<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>
+ _Hashtable;
+ typedef _Hashtable_iterator<_Val, _Key, _HashFcn,
+ _ExtractKey, _EqualKey, _Alloc>
+ iterator;
+ typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn,
+ _ExtractKey, _EqualKey, _Alloc>
+ const_iterator;
+ typedef _Hashtable_node<_Val> _Node;
+
+ typedef @KWSYS_NAMESPACE@_stl::forward_iterator_tag iterator_category;
+ typedef _Val value_type;
+ typedef ptrdiff_t difference_type;
+ typedef size_t size_type;
+ typedef _Val& reference;
+ typedef _Val* pointer;
+
+ _Node* _M_cur;
+ _Hashtable* _M_ht;
+
+ _Hashtable_iterator(_Node* __n, _Hashtable* __tab)
+ : _M_cur(__n), _M_ht(__tab) {}
+ _Hashtable_iterator() {}
+ reference operator*() const { return _M_cur->_M_val; }
+ pointer operator->() const { return &(operator*()); }
+ iterator& operator++();
+ iterator operator++(int);
+ bool operator==(const iterator& __it) const
+ { return _M_cur == __it._M_cur; }
+ bool operator!=(const iterator& __it) const
+ { return _M_cur != __it._M_cur; }
+};
+
+
+template <class _Val, class _Key, class _HashFcn,
+ class _ExtractKey, class _EqualKey, class _Alloc>
+struct _Hashtable_const_iterator {
+ typedef hashtable<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>
+ _Hashtable;
+ typedef _Hashtable_iterator<_Val,_Key,_HashFcn,
+ _ExtractKey,_EqualKey,_Alloc>
+ iterator;
+ typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn,
+ _ExtractKey, _EqualKey, _Alloc>
+ const_iterator;
+ typedef _Hashtable_node<_Val> _Node;
+
+ typedef @KWSYS_NAMESPACE@_stl::forward_iterator_tag iterator_category;
+ typedef _Val value_type;
+ typedef ptrdiff_t difference_type;
+ typedef size_t size_type;
+ typedef const _Val& reference;
+ typedef const _Val* pointer;
+
+ const _Node* _M_cur;
+ const _Hashtable* _M_ht;
+
+ _Hashtable_const_iterator(const _Node* __n, const _Hashtable* __tab)
+ : _M_cur(__n), _M_ht(__tab) {}
+ _Hashtable_const_iterator() {}
+ _Hashtable_const_iterator(const iterator& __it)
+ : _M_cur(__it._M_cur), _M_ht(__it._M_ht) {}
+ reference operator*() const { return _M_cur->_M_val; }
+ pointer operator->() const { return &(operator*()); }
+ const_iterator& operator++();
+ const_iterator operator++(int);
+ bool operator==(const const_iterator& __it) const
+ { return _M_cur == __it._M_cur; }
+ bool operator!=(const const_iterator& __it) const
+ { return _M_cur != __it._M_cur; }
+};
+
+// Note: assumes long is at least 32 bits.
+enum { _stl_num_primes = 31 };
+
+// create a function with a static local to that function that returns
+// the static
+static inline const unsigned long* get_stl_prime_list() {
+
+static const unsigned long _stl_prime_list[_stl_num_primes] =
+{
+ 5ul, 11ul, 23ul,
+ 53ul, 97ul, 193ul, 389ul, 769ul,
+ 1543ul, 3079ul, 6151ul, 12289ul, 24593ul,
+ 49157ul, 98317ul, 196613ul, 393241ul, 786433ul,
+ 1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul,
+ 50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul,
+ 1610612741ul, 3221225473ul, 4294967291ul
+};
+
+return &_stl_prime_list[0]; }
+
+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);
+ return pos == __last ? *(__last - 1) : *pos;
+}
+
+// Forward declaration of operator==.
+
+template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
+class hashtable;
+
+template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
+bool operator==(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1,
+ const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2);
+
+// Hashtables handle allocators a bit differently than other containers
+// do. If we're using standard-conforming allocators, then a hashtable
+// unconditionally has a member variable to hold its allocator, even if
+// it so happens that all instances of the allocator type are identical.
+// This is because, for hashtables, this extra storage is negligible.
+// Additionally, a base class wouldn't serve any other purposes; it
+// wouldn't, for example, simplify the exception-handling code.
+
+template <class _Val, class _Key, class _HashFcn,
+ class _ExtractKey, class _EqualKey, class _Alloc>
+class hashtable {
+public:
+ typedef _Key key_type;
+ typedef _Val value_type;
+ typedef _HashFcn hasher;
+ typedef _EqualKey key_equal;
+
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef value_type* pointer;
+ typedef const value_type* const_pointer;
+ typedef value_type& reference;
+ typedef const value_type& const_reference;
+
+ hasher hash_funct() const { return _M_hash; }
+ key_equal key_eq() const { return _M_equals; }
+
+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
+
+private:
+ _M_node_allocator_type _M_node_allocator;
+ hasher _M_hash;
+ key_equal _M_equals;
+ _ExtractKey _M_get_key;
+ _M_buckets_type _M_buckets;
+ size_type _M_num_elements;
+
+ _Node* _M_get_node() { return _M_node_allocator.allocate(1); }
+ void _M_put_node(_Node* __p) { _M_node_allocator.deallocate(__p, 1); }
+
+public:
+ typedef _Hashtable_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>
+ iterator;
+ typedef _Hashtable_const_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,
+ _Alloc>
+ const_iterator;
+
+ friend struct
+ _Hashtable_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>;
+ friend struct
+ _Hashtable_const_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>;
+
+public:
+ hashtable(size_type __n,
+ const _HashFcn& __hf,
+ const _EqualKey& __eql,
+ const _ExtractKey& __ext,
+ const allocator_type& __a = allocator_type())
+ : _M_node_allocator(__a),
+ _M_hash(__hf),
+ _M_equals(__eql),
+ _M_get_key(__ext),
+ @KWSYS_NAMESPACE@_HASH_BUCKETS_INIT(__a),
+ _M_num_elements(0)
+ {
+ _M_initialize_buckets(__n);
+ }
+
+ hashtable(size_type __n,
+ const _HashFcn& __hf,
+ const _EqualKey& __eql,
+ const allocator_type& __a = allocator_type())
+ : _M_node_allocator(__a),
+ _M_hash(__hf),
+ _M_equals(__eql),
+ _M_get_key(_ExtractKey()),
+ @KWSYS_NAMESPACE@_HASH_BUCKETS_INIT(__a),
+ _M_num_elements(0)
+ {
+ _M_initialize_buckets(__n);
+ }
+
+ hashtable(const hashtable& __ht)
+ : _M_node_allocator(__ht.get_allocator()),
+ _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_num_elements(0)
+ {
+ _M_copy_from(__ht);
+ }
+
+ hashtable& operator= (const hashtable& __ht)
+ {
+ if (&__ht != this) {
+ clear();
+ _M_hash = __ht._M_hash;
+ _M_equals = __ht._M_equals;
+ _M_get_key = __ht._M_get_key;
+ _M_copy_from(__ht);
+ }
+ return *this;
+ }
+
+ ~hashtable() { clear(); }
+
+ size_type size() const { return _M_num_elements; }
+ size_type max_size() const { return size_type(-1); }
+ bool empty() const { return size() == 0; }
+
+ 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);
+ _M_buckets.swap(__ht._M_buckets);
+ @KWSYS_NAMESPACE@_stl::swap(_M_num_elements, __ht._M_num_elements);
+ }
+
+ iterator begin()
+ {
+ for (size_type __n = 0; __n < _M_buckets.size(); ++__n)
+ if (_M_buckets[__n])
+ return iterator(_M_buckets[__n], this);
+ return end();
+ }
+
+ iterator end() { return iterator(0, this); }
+
+ const_iterator begin() const
+ {
+ for (size_type __n = 0; __n < _M_buckets.size(); ++__n)
+ if (_M_buckets[__n])
+ return const_iterator(_M_buckets[__n], this);
+ return end();
+ }
+
+ const_iterator end() const { return const_iterator(0, this); }
+
+ friend bool operator==@KWSYS_NAMESPACE@_CXX_NULL_TEMPLATE_ARGS(const hashtable&,
+ const hashtable&);
+
+public:
+
+ size_type bucket_count() const { return _M_buckets.size(); }
+
+ size_type max_bucket_count() const
+ { return get_stl_prime_list()[(int)_stl_num_primes - 1]; }
+
+ size_type elems_in_bucket(size_type __bucket) const
+ {
+ size_type __result = 0;
+ for (_Node* __cur = _M_buckets[__bucket]; __cur; __cur = __cur->_M_next)
+ __result += 1;
+ return __result;
+ }
+
+ @KWSYS_NAMESPACE@_stl::pair<iterator, bool> insert_unique(const value_type& __obj)
+ {
+ resize(_M_num_elements + 1);
+ return insert_unique_noresize(__obj);
+ }
+
+ iterator insert_equal(const value_type& __obj)
+ {
+ resize(_M_num_elements + 1);
+ return insert_equal_noresize(__obj);
+ }
+
+ @KWSYS_NAMESPACE@_stl::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));
+ }
+
+ template <class _InputIterator>
+ void insert_equal(_InputIterator __f, _InputIterator __l)
+ {
+ insert_equal(__f, __l,
+ @KWSYS_NAMESPACE@_HASH_ITERATOR_CATEGORY(_InputIterator, __f));
+ }
+
+ template <class _InputIterator>
+ void insert_unique(_InputIterator __f, _InputIterator __l,
+ @KWSYS_NAMESPACE@_stl::input_iterator_tag)
+ {
+ for ( ; __f != __l; ++__f)
+ insert_unique(*__f);
+ }
+
+ template <class _InputIterator>
+ void insert_equal(_InputIterator __f, _InputIterator __l,
+ @KWSYS_NAMESPACE@_stl::input_iterator_tag)
+ {
+ for ( ; __f != __l; ++__f)
+ insert_equal(*__f);
+ }
+
+ template <class _ForwardIterator>
+ void insert_unique(_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_unique_noresize(*__f);
+ }
+
+ 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)
+ {
+ 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);
+ resize(_M_num_elements + __n);
+ for ( ; __n > 0; --__n, ++__f)
+ insert_equal_noresize(*__f);
+ }
+#endif
+
+ reference find_or_insert(const value_type& __obj);
+
+ iterator find(const key_type& __key)
+ {
+ size_type __n = _M_bkt_num_key(__key);
+ _Node* __first;
+ for ( __first = _M_buckets[__n];
+ __first && !_M_equals(_M_get_key(__first->_M_val), __key);
+ __first = __first->_M_next)
+ {}
+ return iterator(__first, this);
+ }
+
+ const_iterator find(const key_type& __key) const
+ {
+ size_type __n = _M_bkt_num_key(__key);
+ const _Node* __first;
+ for ( __first = _M_buckets[__n];
+ __first && !_M_equals(_M_get_key(__first->_M_val), __key);
+ __first = __first->_M_next)
+ {}
+ return const_iterator(__first, this);
+ }
+
+ size_type count(const key_type& __key) const
+ {
+ const size_type __n = _M_bkt_num_key(__key);
+ size_type __result = 0;
+
+ for (const _Node* __cur = _M_buckets[__n]; __cur; __cur = __cur->_M_next)
+ if (_M_equals(_M_get_key(__cur->_M_val), __key))
+ ++__result;
+ return __result;
+ }
+
+ @KWSYS_NAMESPACE@_stl::pair<iterator, iterator>
+ equal_range(const key_type& __key);
+
+ @KWSYS_NAMESPACE@_stl::pair<const_iterator, const_iterator>
+ equal_range(const key_type& __key) const;
+
+ size_type erase(const key_type& __key);
+ void erase(const iterator& __it);
+ void erase(iterator __first, iterator __last);
+
+ void erase(const const_iterator& __it);
+ void erase(const_iterator __first, const_iterator __last);
+
+ void resize(size_type __num_elements_hint);
+ void clear();
+
+private:
+ size_type _M_next_size(size_type __n) const
+ { return _stl_next_prime(__n); }
+
+ void _M_initialize_buckets(size_type __n)
+ {
+ const size_type __n_buckets = _M_next_size(__n);
+ _M_buckets.reserve(__n_buckets);
+ _M_buckets.insert(_M_buckets.end(), __n_buckets, (_Node*) 0);
+ _M_num_elements = 0;
+ }
+
+ size_type _M_bkt_num_key(const key_type& __key) const
+ {
+ return _M_bkt_num_key(__key, _M_buckets.size());
+ }
+
+ size_type _M_bkt_num(const value_type& __obj) const
+ {
+ return _M_bkt_num_key(_M_get_key(__obj));
+ }
+
+ size_type _M_bkt_num_key(const key_type& __key, size_t __n) const
+ {
+ return _M_hash(__key) % __n;
+ }
+
+ size_type _M_bkt_num(const value_type& __obj, size_t __n) const
+ {
+ return _M_bkt_num_key(_M_get_key(__obj), __n);
+ }
+
+ void construct(_Val* p, const _Val& v)
+ {
+ new (p) _Val(v);
+ }
+ void destroy(_Val* p)
+ {
+ (void)p;
+ p->~_Val();
+ }
+
+ _Node* _M_new_node(const value_type& __obj)
+ {
+ _Node* __n = _M_get_node();
+ __n->_M_next = 0;
+ try {
+ construct(&__n->_M_val, __obj);
+ return __n;
+ }
+ catch(...) {_M_put_node(__n); throw;}
+ }
+
+ void _M_delete_node(_Node* __n)
+ {
+ destroy(&__n->_M_val);
+ _M_put_node(__n);
+ }
+
+ void _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last);
+ void _M_erase_bucket(const size_type __n, _Node* __last);
+
+ void _M_copy_from(const hashtable& __ht);
+
+};
+
+template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
+ class _All>
+_Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&
+_Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++()
+{
+ const _Node* __old = _M_cur;
+ _M_cur = _M_cur->_M_next;
+ if (!_M_cur) {
+ size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val);
+ while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size())
+ _M_cur = _M_ht->_M_buckets[__bucket];
+ }
+ return *this;
+}
+
+template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
+ class _All>
+inline _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>
+_Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++(int)
+{
+ iterator __tmp = *this;
+ ++*this;
+ return __tmp;
+}
+
+template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
+ class _All>
+_Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&
+_Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++()
+{
+ const _Node* __old = _M_cur;
+ _M_cur = _M_cur->_M_next;
+ if (!_M_cur) {
+ size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val);
+ while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size())
+ _M_cur = _M_ht->_M_buckets[__bucket];
+ }
+ return *this;
+}
+
+template <class _Val, class _Key, class _HF, class _ExK, class _EqK,
+ class _All>
+inline _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>
+_Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++(int)
+{
+ const_iterator __tmp = *this;
+ ++*this;
+ return __tmp;
+}
+
+template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
+bool operator==(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1,
+ const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2)
+{
+ typedef typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::_Node _Node;
+ if (__ht1._M_buckets.size() != __ht2._M_buckets.size())
+ return false;
+ for (int __n = 0; __n < __ht1._M_buckets.size(); ++__n) {
+ _Node* __cur1 = __ht1._M_buckets[__n];
+ _Node* __cur2 = __ht2._M_buckets[__n];
+ for ( ; __cur1 && __cur2 && __cur1->_M_val == __cur2->_M_val;
+ __cur1 = __cur1->_M_next, __cur2 = __cur2->_M_next)
+ {}
+ if (__cur1 || __cur2)
+ return false;
+ }
+ return true;
+}
+
+template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
+inline bool operator!=(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1,
+ const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2) {
+ return !(__ht1 == __ht2);
+}
+
+template <class _Val, class _Key, class _HF, class _Extract, class _EqKey,
+ class _All>
+inline void swap(hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht1,
+ hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht2) {
+ __ht1.swap(__ht2);
+}
+
+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>
+hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
+ ::insert_unique_noresize(const value_type& __obj)
+{
+ const size_type __n = _M_bkt_num(__obj);
+ _Node* __first = _M_buckets[__n];
+
+ 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);
+
+ _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);
+}
+
+template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
+typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator
+hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
+ ::insert_equal_noresize(const value_type& __obj)
+{
+ const size_type __n = _M_bkt_num(__obj);
+ _Node* __first = _M_buckets[__n];
+
+ for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
+ if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) {
+ _Node* __tmp = _M_new_node(__obj);
+ __tmp->_M_next = __cur->_M_next;
+ __cur->_M_next = __tmp;
+ ++_M_num_elements;
+ return iterator(__tmp, this);
+ }
+
+ _Node* __tmp = _M_new_node(__obj);
+ __tmp->_M_next = __first;
+ _M_buckets[__n] = __tmp;
+ ++_M_num_elements;
+ return iterator(__tmp, this);
+}
+
+template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
+typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::reference
+hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::find_or_insert(const value_type& __obj)
+{
+ resize(_M_num_elements + 1);
+
+ size_type __n = _M_bkt_num(__obj);
+ _Node* __first = _M_buckets[__n];
+
+ for (_Node* __cur = __first; __cur; __cur = __cur->_M_next)
+ if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj)))
+ return __cur->_M_val;
+
+ _Node* __tmp = _M_new_node(__obj);
+ __tmp->_M_next = __first;
+ _M_buckets[__n] = __tmp;
+ ++_M_num_elements;
+ return __tmp->_M_val;
+}
+
+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>
+hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::equal_range(const key_type& __key)
+{
+ typedef @KWSYS_NAMESPACE@_stl::pair<iterator, iterator> _Pii;
+ const size_type __n = _M_bkt_num_key(__key);
+
+ for (_Node* __first = _M_buckets[__n]; __first; __first = __first->_M_next)
+ if (_M_equals(_M_get_key(__first->_M_val), __key)) {
+ for (_Node* __cur = __first->_M_next; __cur; __cur = __cur->_M_next)
+ if (!_M_equals(_M_get_key(__cur->_M_val), __key))
+ return _Pii(iterator(__first, this), iterator(__cur, this));
+ for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m)
+ if (_M_buckets[__m])
+ return _Pii(iterator(__first, this),
+ iterator(_M_buckets[__m], this));
+ return _Pii(iterator(__first, this), end());
+ }
+ return _Pii(end(), end());
+}
+
+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>
+hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
+ ::equal_range(const key_type& __key) const
+{
+ typedef @KWSYS_NAMESPACE@_stl::pair<const_iterator, const_iterator> _Pii;
+ const size_type __n = _M_bkt_num_key(__key);
+
+ for (const _Node* __first = _M_buckets[__n] ;
+ __first;
+ __first = __first->_M_next) {
+ if (_M_equals(_M_get_key(__first->_M_val), __key)) {
+ for (const _Node* __cur = __first->_M_next;
+ __cur;
+ __cur = __cur->_M_next)
+ if (!_M_equals(_M_get_key(__cur->_M_val), __key))
+ return _Pii(const_iterator(__first, this),
+ const_iterator(__cur, this));
+ for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m)
+ if (_M_buckets[__m])
+ return _Pii(const_iterator(__first, this),
+ const_iterator(_M_buckets[__m], this));
+ return _Pii(const_iterator(__first, this), end());
+ }
+ }
+ return _Pii(end(), end());
+}
+
+template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
+typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::size_type
+hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const key_type& __key)
+{
+ const size_type __n = _M_bkt_num_key(__key);
+ _Node* __first = _M_buckets[__n];
+ size_type __erased = 0;
+
+ if (__first) {
+ _Node* __cur = __first;
+ _Node* __next = __cur->_M_next;
+ while (__next) {
+ if (_M_equals(_M_get_key(__next->_M_val), __key)) {
+ __cur->_M_next = __next->_M_next;
+ _M_delete_node(__next);
+ __next = __cur->_M_next;
+ ++__erased;
+ --_M_num_elements;
+ }
+ else {
+ __cur = __next;
+ __next = __cur->_M_next;
+ }
+ }
+ if (_M_equals(_M_get_key(__first->_M_val), __key)) {
+ _M_buckets[__n] = __first->_M_next;
+ _M_delete_node(__first);
+ ++__erased;
+ --_M_num_elements;
+ }
+ }
+ return __erased;
+}
+
+template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
+void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const iterator& __it)
+{
+ _Node* __p = __it._M_cur;
+ if (__p) {
+ const size_type __n = _M_bkt_num(__p->_M_val);
+ _Node* __cur = _M_buckets[__n];
+
+ if (__cur == __p) {
+ _M_buckets[__n] = __cur->_M_next;
+ _M_delete_node(__cur);
+ --_M_num_elements;
+ }
+ else {
+ _Node* __next = __cur->_M_next;
+ while (__next) {
+ if (__next == __p) {
+ __cur->_M_next = __next->_M_next;
+ _M_delete_node(__next);
+ --_M_num_elements;
+ break;
+ }
+ else {
+ __cur = __next;
+ __next = __cur->_M_next;
+ }
+ }
+ }
+ }
+}
+
+template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
+void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
+ ::erase(iterator __first, iterator __last)
+{
+ size_type __f_bucket = __first._M_cur ?
+ _M_bkt_num(__first._M_cur->_M_val) : _M_buckets.size();
+ size_type __l_bucket = __last._M_cur ?
+ _M_bkt_num(__last._M_cur->_M_val) : _M_buckets.size();
+
+ if (__first._M_cur == __last._M_cur)
+ return;
+ else if (__f_bucket == __l_bucket)
+ _M_erase_bucket(__f_bucket, __first._M_cur, __last._M_cur);
+ else {
+ _M_erase_bucket(__f_bucket, __first._M_cur, 0);
+ for (size_type __n = __f_bucket + 1; __n < __l_bucket; ++__n)
+ _M_erase_bucket(__n, 0);
+ if (__l_bucket != _M_buckets.size())
+ _M_erase_bucket(__l_bucket, __last._M_cur);
+ }
+}
+
+template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
+inline void
+hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const_iterator __first,
+ const_iterator __last)
+{
+ erase(iterator(const_cast<_Node*>(__first._M_cur),
+ const_cast<hashtable*>(__first._M_ht)),
+ iterator(const_cast<_Node*>(__last._M_cur),
+ const_cast<hashtable*>(__last._M_ht)));
+}
+
+template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
+inline void
+hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const const_iterator& __it)
+{
+ erase(iterator(const_cast<_Node*>(__it._M_cur),
+ const_cast<hashtable*>(__it._M_ht)));
+}
+
+template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
+void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
+ ::resize(size_type __num_elements_hint)
+{
+ const size_type __old_n = _M_buckets.size();
+ if (__num_elements_hint > __old_n) {
+ 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));
+ try {
+ for (size_type __bucket = 0; __bucket < __old_n; ++__bucket) {
+ _Node* __first = _M_buckets[__bucket];
+ while (__first) {
+ size_type __new_bucket = _M_bkt_num(__first->_M_val, __n);
+ _M_buckets[__bucket] = __first->_M_next;
+ __first->_M_next = __tmp[__new_bucket];
+ __tmp[__new_bucket] = __first;
+ __first = _M_buckets[__bucket];
+ }
+ }
+ _M_buckets.swap(__tmp);
+ }
+ catch(...) {
+ for (size_type __bucket = 0; __bucket < __tmp.size(); ++__bucket) {
+ while (__tmp[__bucket]) {
+ _Node* __next = __tmp[__bucket]->_M_next;
+ _M_delete_node(__tmp[__bucket]);
+ __tmp[__bucket] = __next;
+ }
+ }
+ throw;
+ }
+ }
+ }
+}
+
+template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
+void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
+ ::_M_erase_bucket(const size_type __n, _Node* __first, _Node* __last)
+{
+ _Node* __cur = _M_buckets[__n];
+ if (__cur == __first)
+ _M_erase_bucket(__n, __last);
+ else {
+ _Node* __next;
+ for (__next = __cur->_M_next;
+ __next != __first;
+ __cur = __next, __next = __cur->_M_next)
+ ;
+ while (__next != __last) {
+ __cur->_M_next = __next->_M_next;
+ _M_delete_node(__next);
+ __next = __cur->_M_next;
+ --_M_num_elements;
+ }
+ }
+}
+
+template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
+void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
+ ::_M_erase_bucket(const size_type __n, _Node* __last)
+{
+ _Node* __cur = _M_buckets[__n];
+ while (__cur != __last) {
+ _Node* __next = __cur->_M_next;
+ _M_delete_node(__cur);
+ __cur = __next;
+ _M_buckets[__n] = __cur;
+ --_M_num_elements;
+ }
+}
+
+template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
+void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::clear()
+{
+ for (size_type __i = 0; __i < _M_buckets.size(); ++__i) {
+ _Node* __cur = _M_buckets[__i];
+ while (__cur != 0) {
+ _Node* __next = __cur->_M_next;
+ _M_delete_node(__cur);
+ __cur = __next;
+ }
+ _M_buckets[__i] = 0;
+ }
+ _M_num_elements = 0;
+}
+
+
+template <class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All>
+void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
+ ::_M_copy_from(const hashtable& __ht)
+{
+ _M_buckets.clear();
+ _M_buckets.reserve(__ht._M_buckets.size());
+ _M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (_Node*) 0);
+ try {
+ for (size_type __i = 0; __i < __ht._M_buckets.size(); ++__i) {
+ const _Node* __cur = __ht._M_buckets[__i];
+ if (__cur) {
+ _Node* __copy = _M_new_node(__cur->_M_val);
+ _M_buckets[__i] = __copy;
+
+ for (_Node* __next = __cur->_M_next;
+ __next;
+ __cur = __next, __next = __cur->_M_next) {
+ __copy->_M_next = _M_new_node(__next->_M_val);
+ __copy = __copy->_M_next;
+ }
+ }
+ }
+ _M_num_elements = __ht._M_num_elements;
+ }
+ catch(...) {clear(); throw;}
+}
+
+} // 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
+
+#if defined(_MSC_VER)
+# pragma warning (pop)
+#endif
+
+#endif
diff --git a/Source/kwsys/kwsysHeaderDump.pl b/Source/kwsys/kwsysHeaderDump.pl
new file mode 100755
index 000000000..0dc4a5204
--- /dev/null
+++ b/Source/kwsys/kwsysHeaderDump.pl
@@ -0,0 +1,50 @@
+#!/usr/bin/perl
+#=============================================================================
+# 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.
+#=============================================================================
+
+if ( $#ARGV+1 < 2 )
+{
+ print "Usage: ./kwsysHeaderDump.pl <name> <header>\n";
+ exit(1);
+}
+
+$name = $ARGV[0];
+$max = 0;
+open(INFILE, $ARGV[1]);
+while (chomp ($line = <INFILE>))
+{
+ if (($line !~ /^\#/) &&
+ ($line =~ s/.*kwsys${name}_([A-Za-z0-9_]*).*/\1/) &&
+ ($i{$line}++ < 1))
+ {
+ push(@lines, "$line");
+ if (length($line) > $max)
+ {
+ $max = length($line);
+ }
+ }
+}
+close(INFILE);
+
+$width = $max + 13;
+print sprintf("#define %-${width}s kwsys_ns(${name})\n", "kwsys${name}");
+foreach $l (@lines)
+{
+ print sprintf("#define %-${width}s kwsys_ns(${name}_$l)\n",
+ "kwsys${name}_$l");
+}
+print "\n";
+print sprintf("# undef kwsys${name}\n");
+foreach $l (@lines)
+{
+ print sprintf("# undef kwsys${name}_$l\n");
+}
diff --git a/Source/kwsys/kwsysPlatformTests.cmake b/Source/kwsys/kwsysPlatformTests.cmake
new file mode 100644
index 000000000..d042450ee
--- /dev/null
+++ b/Source/kwsys/kwsysPlatformTests.cmake
@@ -0,0 +1,216 @@
+#=============================================================================
+# 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.
+#=============================================================================
+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$")
+ MESSAGE(STATUS "${description}")
+ TRY_COMPILE(${var}_COMPILED
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/${KWSYS_PLATFORM_TEST_FILE_${lang}}
+ COMPILE_DEFINITIONS -DTEST_${var} ${KWSYS_PLATFORM_TEST_DEFINES} ${KWSYS_PLATFORM_TEST_EXTRA_FLAGS}
+ OUTPUT_VARIABLE OUTPUT)
+ IF(${var}_COMPILED)
+ FILE(APPEND
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "${description} compiled with the following output:\n${OUTPUT}\n\n")
+ ELSE(${var}_COMPILED)
+ 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)
+ IF(${invert} MATCHES INVERT)
+ IF(${var}_COMPILED)
+ MESSAGE(STATUS "${description} - no")
+ ELSE(${var}_COMPILED)
+ MESSAGE(STATUS "${description} - yes")
+ ENDIF(${var}_COMPILED)
+ ELSE(${invert} MATCHES INVERT)
+ IF(${var}_COMPILED)
+ MESSAGE(STATUS "${description} - yes")
+ ELSE(${var}_COMPILED)
+ MESSAGE(STATUS "${description} - no")
+ ENDIF(${var}_COMPILED)
+ ENDIF(${invert} MATCHES INVERT)
+ ENDIF("${var}_COMPILED" MATCHES "^${var}_COMPILED$")
+ IF(${invert} MATCHES INVERT)
+ IF(${var}_COMPILED)
+ SET(${var} 0)
+ ELSE(${var}_COMPILED)
+ SET(${var} 1)
+ ENDIF(${var}_COMPILED)
+ ELSE(${invert} MATCHES INVERT)
+ IF(${var}_COMPILED)
+ SET(${var} 1)
+ ELSE(${var}_COMPILED)
+ SET(${var} 0)
+ ENDIF(${var}_COMPILED)
+ ENDIF(${invert} MATCHES INVERT)
+ENDMACRO(KWSYS_PLATFORM_TEST)
+
+MACRO(KWSYS_PLATFORM_TEST_RUN lang var description invert)
+ IF("${var}" MATCHES "^${var}$")
+ MESSAGE(STATUS "${description}")
+ TRY_RUN(${var} ${var}_COMPILED
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/${KWSYS_PLATFORM_TEST_FILE_${lang}}
+ COMPILE_DEFINITIONS -DTEST_${var} ${KWSYS_PLATFORM_TEST_DEFINES} ${KWSYS_PLATFORM_TEST_EXTRA_FLAGS}
+ OUTPUT_VARIABLE OUTPUT)
+
+ # Note that ${var} will be a 0 return value on success.
+ IF(${var}_COMPILED)
+ IF(${var})
+ 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})
+ 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)
+ 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)
+
+ IF(${invert} MATCHES INVERT)
+ IF(${var}_COMPILED)
+ IF(${var})
+ MESSAGE(STATUS "${description} - yes")
+ ELSE(${var})
+ MESSAGE(STATUS "${description} - no")
+ ENDIF(${var})
+ ELSE(${var}_COMPILED)
+ MESSAGE(STATUS "${description} - failed to compile")
+ ENDIF(${var}_COMPILED)
+ ELSE(${invert} MATCHES INVERT)
+ IF(${var}_COMPILED)
+ IF(${var})
+ MESSAGE(STATUS "${description} - no")
+ ELSE(${var})
+ MESSAGE(STATUS "${description} - yes")
+ ENDIF(${var})
+ ELSE(${var}_COMPILED)
+ MESSAGE(STATUS "${description} - failed to compile")
+ ENDIF(${var}_COMPILED)
+ ENDIF(${invert} MATCHES INVERT)
+ ENDIF("${var}" MATCHES "^${var}$")
+
+ IF(${invert} MATCHES INVERT)
+ IF(${var}_COMPILED)
+ IF(${var})
+ SET(${var} 1)
+ ELSE(${var})
+ SET(${var} 0)
+ ENDIF(${var})
+ ELSE(${var}_COMPILED)
+ SET(${var} 1)
+ ENDIF(${var}_COMPILED)
+ ELSE(${invert} MATCHES INVERT)
+ IF(${var}_COMPILED)
+ IF(${var})
+ SET(${var} 0)
+ ELSE(${var})
+ SET(${var} 1)
+ ENDIF(${var})
+ ELSE(${var}_COMPILED)
+ SET(${var} 0)
+ ENDIF(${var}_COMPILED)
+ ENDIF(${invert} MATCHES INVERT)
+ENDMACRO(KWSYS_PLATFORM_TEST_RUN)
+
+MACRO(KWSYS_PLATFORM_C_TEST var description invert)
+ SET(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_C_TEST_DEFINES})
+ SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS ${KWSYS_PLATFORM_C_TEST_EXTRA_FLAGS})
+ KWSYS_PLATFORM_TEST(C "${var}" "${description}" "${invert}")
+ SET(KWSYS_PLATFORM_TEST_DEFINES)
+ SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS)
+ENDMACRO(KWSYS_PLATFORM_C_TEST)
+
+MACRO(KWSYS_PLATFORM_C_TEST_RUN var description invert)
+ SET(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_C_TEST_DEFINES})
+ SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS ${KWSYS_PLATFORM_C_TEST_EXTRA_FLAGS})
+ 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)
+
+MACRO(KWSYS_PLATFORM_CXX_TEST var description invert)
+ SET(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_CXX_TEST_DEFINES})
+ SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS ${KWSYS_PLATFORM_CXX_TEST_EXTRA_FLAGS})
+ KWSYS_PLATFORM_TEST(CXX "${var}" "${description}" "${invert}")
+ SET(KWSYS_PLATFORM_TEST_DEFINES)
+ SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS)
+ENDMACRO(KWSYS_PLATFORM_CXX_TEST)
+
+MACRO(KWSYS_PLATFORM_CXX_TEST_RUN var description invert)
+ SET(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_CXX_TEST_DEFINES})
+ SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS ${KWSYS_PLATFORM_CXX_TEST_EXTRA_FLAGS})
+ 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)
+
+#-----------------------------------------------------------------------------
+# KWSYS_PLATFORM_INFO_TEST(lang var description)
+#
+# Compile test named by ${var} and store INFO strings extracted from binary.
+MACRO(KWSYS_PLATFORM_INFO_TEST lang var description)
+ # We can implement this macro on CMake 2.6 and above.
+ IF("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.6)
+ SET(${var} "")
+ ELSE()
+ # Choose a location for the result binary.
+ SET(KWSYS_PLATFORM_INFO_FILE
+ ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/${var}.bin)
+
+ # Compile the test binary.
+ IF(NOT EXISTS ${KWSYS_PLATFORM_INFO_FILE})
+ MESSAGE(STATUS "${description}")
+ TRY_COMPILE(${var}_COMPILED
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/${KWSYS_PLATFORM_TEST_FILE_${lang}}
+ COMPILE_DEFINITIONS -DTEST_${var}
+ ${KWSYS_PLATFORM_${lang}_TEST_DEFINES}
+ ${KWSYS_PLATFORM_${lang}_TEST_EXTRA_FLAGS}
+ OUTPUT_VARIABLE OUTPUT
+ COPY_FILE ${KWSYS_PLATFORM_INFO_FILE}
+ )
+ IF(${var}_COMPILED)
+ FILE(APPEND
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "${description} compiled with the following output:\n${OUTPUT}\n\n")
+ ELSE()
+ FILE(APPEND
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "${description} failed to compile with the following output:\n${OUTPUT}\n\n")
+ ENDIF()
+ IF(${var}_COMPILED)
+ MESSAGE(STATUS "${description} - compiled")
+ ELSE()
+ MESSAGE(STATUS "${description} - failed")
+ ENDIF()
+ ENDIF()
+
+ # Parse info strings out of the compiled binary.
+ IF(${var}_COMPILED)
+ FILE(STRINGS ${KWSYS_PLATFORM_INFO_FILE} ${var} REGEX "INFO:[A-Za-z0-9]+\\[[^]]*\\]")
+ ELSE()
+ SET(${var} "")
+ ENDIF()
+
+ SET(KWSYS_PLATFORM_INFO_FILE)
+ ENDIF()
+ENDMACRO()
diff --git a/Source/kwsys/kwsysPlatformTestsC.c b/Source/kwsys/kwsysPlatformTestsC.c
new file mode 100644
index 000000000..e602964bb
--- /dev/null
+++ b/Source/kwsys/kwsysPlatformTestsC.c
@@ -0,0 +1,100 @@
+/*============================================================================
+ 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.
+============================================================================*/
+/*
+ Macros to define main() in a cross-platform way.
+
+ Usage:
+
+ int KWSYS_PLATFORM_TEST_C_MAIN()
+ {
+ return 0;
+ }
+
+ int KWSYS_PLATFORM_TEST_C_MAIN_ARGS(argc, argv)
+ {
+ (void)argc; (void)argv;
+ return 0;
+ }
+*/
+#if defined(__CLASSIC_C__)
+# define KWSYS_PLATFORM_TEST_C_MAIN() \
+ main()
+# define KWSYS_PLATFORM_TEST_C_MAIN_ARGS(argc, argv) \
+ main(argc,argv) int argc; char* argv[];
+#else
+# define KWSYS_PLATFORM_TEST_C_MAIN() \
+ main(void)
+# define KWSYS_PLATFORM_TEST_C_MAIN_ARGS(argc, argv) \
+ main(int argc, char* argv[])
+#endif
+
+/*--------------------------------------------------------------------------*/
+#ifdef TEST_KWSYS_C_HAS_PTRDIFF_T
+#include <stddef.h>
+int f(ptrdiff_t n) { return n > 0; }
+int KWSYS_PLATFORM_TEST_C_MAIN()
+{
+ char* p = 0;
+ ptrdiff_t d = p - p;
+ (void)d;
+ return f(p - p);
+}
+#endif
+
+/*--------------------------------------------------------------------------*/
+#ifdef TEST_KWSYS_C_HAS_SSIZE_T
+#include <unistd.h>
+int f(ssize_t n) { return (int)n; }
+int KWSYS_PLATFORM_TEST_C_MAIN()
+{
+ ssize_t n = 0;
+ return f(n);
+}
+#endif
+
+/*--------------------------------------------------------------------------*/
+#ifdef TEST_KWSYS_C_TYPE_MACROS
+char* info_macros =
+#if defined(__SIZEOF_SHORT__)
+"INFO:macro[__SIZEOF_SHORT__]\n"
+#endif
+#if defined(__SIZEOF_INT__)
+"INFO:macro[__SIZEOF_INT__]\n"
+#endif
+#if defined(__SIZEOF_LONG__)
+"INFO:macro[__SIZEOF_LONG__]\n"
+#endif
+#if defined(__SIZEOF_LONG_LONG__)
+"INFO:macro[__SIZEOF_LONG_LONG__]\n"
+#endif
+#if defined(__SHORT_MAX__)
+"INFO:macro[__SHORT_MAX__]\n"
+#endif
+#if defined(__INT_MAX__)
+"INFO:macro[__INT_MAX__]\n"
+#endif
+#if defined(__LONG_MAX__)
+"INFO:macro[__LONG_MAX__]\n"
+#endif
+#if defined(__LONG_LONG_MAX__)
+"INFO:macro[__LONG_LONG_MAX__]\n"
+#endif
+ "";
+
+int KWSYS_PLATFORM_TEST_C_MAIN_ARGS(argc, argv)
+{
+ int require = 0;
+ require += info_macros[argc];
+ (void)argv;
+ return require;
+}
+#endif
diff --git a/Source/kwsys/kwsysPlatformTestsCXX.cxx b/Source/kwsys/kwsysPlatformTestsCXX.cxx
new file mode 100644
index 000000000..7b73d06df
--- /dev/null
+++ b/Source/kwsys/kwsysPlatformTestsCXX.cxx
@@ -0,0 +1,516 @@
+/*============================================================================
+ 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.
+============================================================================*/
+// 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()
+{
+ long long n = 0;
+ return static_cast<int>(f(n));
+}
+#endif
+
+#ifdef TEST_KWSYS_CXX_HAS___INT64
+__int64 f(__int64 n) { return n; }
+int main()
+{
+ __int64 n = 0;
+ return static_cast<int>(f(n));
+}
+#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());
+}
+int main()
+{
+ f(kwsys_stl::vector<int>());
+ return 0;
+}
+#endif
+
+#ifdef TEST_KWSYS_STAT_HAS_ST_MTIM
+#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;
+ return 0;
+}
+#endif
+
+#ifdef TEST_KWSYS_CXX_SAME_LONG_AND___INT64
+void function(long**) {}
+int main()
+{
+ __int64** p = 0;
+ function(p);
+ return 0;
+}
+#endif
+
+#ifdef TEST_KWSYS_CXX_SAME_LONG_LONG_AND___INT64
+void function(long long**) {}
+int main()
+{
+ __int64** p = 0;
+ function(p);
+ return 0;
+}
+#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)
+{
+ return (is >> x)? 1:0;
+}
+int main()
+{
+ long long x = 0;
+ return test_istream(kwsys_ios::cin, x);
+}
+#endif
+
+#ifdef TEST_KWSYS_IOS_HAS_OSTREAM_LONG_LONG
+int test_ostream(kwsys_ios::ostream& os, long long x)
+{
+ return (os << x)? 1:0;
+}
+int main()
+{
+ long long 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;
+}
+#endif
+
+#ifdef TEST_KWSYS_LFS_WORKS
+/* Return 0 when LFS is available and 1 otherwise. */
+#define _LARGEFILE_SOURCE
+#define _LARGEFILE64_SOURCE
+#define _LARGE_FILES
+#define _FILE_OFFSET_BITS 64
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <assert.h>
+#if KWSYS_CXX_HAS_CSTDIO
+# include <cstdio>
+#endif
+#include <stdio.h>
+
+int main(int, char **argv)
+{
+ /* check that off_t can hold 2^63 - 1 and perform basic operations... */
+#define OFF_T_64 (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ if (OFF_T_64 % 2147483647 != 1)
+ return 1;
+
+ // stat breaks on SCO OpenServer
+ struct stat buf;
+ stat( argv[0], &buf );
+ if (!S_ISREG(buf.st_mode))
+ return 2;
+
+ FILE *file = fopen( argv[0], "r" );
+ off_t offset = ftello( file );
+ fseek( file, offset, SEEK_CUR );
+ fclose( file );
+ return 0;
+}
+#endif
+
+#ifdef TEST_KWSYS_CXX_HAS_SETENV
+#include <stdlib.h>
+int main()
+{
+ return setenv("A", "B", 1);
+}
+#endif
+
+#ifdef TEST_KWSYS_CXX_HAS_UNSETENV
+#include <stdlib.h>
+int main()
+{
+ unsetenv("A");
+ return 0;
+}
+#endif
+
+#ifdef TEST_KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H
+#include <stdlib.h>
+int main()
+{
+ char* e = environ[0];
+ return e? 0:1;
+}
+#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
diff --git a/Source/kwsys/kwsysPrivate.h b/Source/kwsys/kwsysPrivate.h
new file mode 100644
index 000000000..3a26c26fb
--- /dev/null
+++ b/Source/kwsys/kwsysPrivate.h
@@ -0,0 +1,41 @@
+/*============================================================================
+ 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
+# error "Do not include kwsysPrivate.h outside of kwsys c and cxx files."
+#endif
+
+#ifndef _kwsysPrivate_h
+#define _kwsysPrivate_h
+
+/*
+ Define KWSYS_HEADER macro to help the c and cxx files include kwsys
+ headers from the configured namespace directory. The macro can be
+ used like this:
+
+ #include KWSYS_HEADER(Directory.hxx)
+ #include KWSYS_HEADER(std/vector)
+*/
+#define KWSYS_HEADER(x) KWSYS_HEADER0(KWSYS_NAMESPACE/x)
+#define KWSYS_HEADER0(x) KWSYS_HEADER1(x)
+#define KWSYS_HEADER1(x) <x>
+
+/*
+ Define KWSYS_NAMESPACE_STRING to be a string constant containing the
+ name configured for this instance of the kwsys library.
+*/
+#define KWSYS_NAMESPACE_STRING KWSYS_NAMESPACE_STRING0(KWSYS_NAMESPACE)
+#define KWSYS_NAMESPACE_STRING0(x) KWSYS_NAMESPACE_STRING1(x)
+#define KWSYS_NAMESPACE_STRING1(x) #x
+
+#else
+# error "kwsysPrivate.h included multiple times."
+#endif
diff --git a/Source/kwsys/kwsys_cstddef.hxx.in b/Source/kwsys/kwsys_cstddef.hxx.in
new file mode 100644
index 000000000..925c03084
--- /dev/null
+++ b/Source/kwsys/kwsys_cstddef.hxx.in
@@ -0,0 +1,35 @@
+/*============================================================================
+ 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
new file mode 100644
index 000000000..4b1a8cfcc
--- /dev/null
+++ b/Source/kwsys/kwsys_ios_fstream.h.in
@@ -0,0 +1,46 @@
+/*============================================================================
+ 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
new file mode 100644
index 000000000..f4fafebc2
--- /dev/null
+++ b/Source/kwsys/kwsys_ios_iosfwd.h.in
@@ -0,0 +1,49 @@
+/*============================================================================
+ 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
new file mode 100644
index 000000000..43fc4d579
--- /dev/null
+++ b/Source/kwsys/kwsys_ios_iostream.h.in
@@ -0,0 +1,99 @@
+/*============================================================================
+ 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
new file mode 100644
index 000000000..29d250c7a
--- /dev/null
+++ b/Source/kwsys/kwsys_ios_sstream.h.in
@@ -0,0 +1,199 @@
+/*============================================================================
+ 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
new file mode 100644
index 000000000..610e6d471
--- /dev/null
+++ b/Source/kwsys/kwsys_stl.hxx.in
@@ -0,0 +1,49 @@
+/*============================================================================
+ 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
new file mode 100644
index 000000000..cd312cb8e
--- /dev/null
+++ b/Source/kwsys/kwsys_stl_string.hxx.in
@@ -0,0 +1,123 @@
+/*============================================================================
+ 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/testAutoPtr.cxx b/Source/kwsys/testAutoPtr.cxx
new file mode 100644
index 000000000..ed75ff447
--- /dev/null
+++ b/Source/kwsys/testAutoPtr.cxx
@@ -0,0 +1,166 @@
+/*============================================================================
+ 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 __BORLANDC__
+# pragma warn -8027 /* 'for' not inlined. */
+# pragma warn -8026 /* exception not inlined. */
+#endif
+#include "kwsysPrivate.h"
+#include KWSYS_HEADER(auto_ptr.hxx)
+// Work-around CMake dependency scanning limitation. This must
+// duplicate the above list of headers.
+#if 0
+# include "auto_ptr.hxx.in"
+#endif
+
+#include <stdio.h>
+
+#define ASSERT(x,y) if (!(x)) { printf("FAIL: " y "\n"); status = 1; }
+
+int instances = 0; // don't declare as static
+
+struct A
+{
+ A() { ++instances; }
+ ~A() { --instances; }
+ A* self() {return this; }
+};
+struct B: public A {};
+
+static int function_call(kwsys::auto_ptr<A> a)
+{
+ return a.get()? 1:0;
+}
+
+static A* get_A(A& a) { return &a; }
+
+static kwsys::auto_ptr<A> generate_auto_ptr_A()
+{
+ return kwsys::auto_ptr<A>(new A);
+}
+
+static kwsys::auto_ptr<B> generate_auto_ptr_B()
+{
+ return kwsys::auto_ptr<B>(new B);
+}
+
+int testAutoPtr(int, char*[])
+{
+ int status = 0;
+
+ // Keep everything in a subscope so we can detect leaks.
+ {
+ kwsys::auto_ptr<A> pa0;
+ kwsys::auto_ptr<A> pa1(new A());
+ kwsys::auto_ptr<B> pb1(new B());
+ kwsys::auto_ptr<B> pb2(new B());
+ kwsys::auto_ptr<A> pa2(new B());
+
+ A* ptr = get_A(*pa1);
+ ASSERT(ptr == pa1.get(),
+ "auto_ptr does not return correct object when dereferenced");
+ ptr = pa1->self();
+ ASSERT(ptr == pa1.get(),
+ "auto_ptr does not return correct pointer from operator->");
+
+ A* before = pa0.get();
+ pa0.reset(new A());
+ ASSERT(pa0.get() && pa0.get() != before,
+ "auto_ptr empty after reset(new A())");
+
+ before = pa0.get();
+ pa0.reset(new B());
+ ASSERT(pa0.get() && pa0.get() != before,
+ "auto_ptr empty after reset(new B())");
+
+ delete pa0.release();
+ ASSERT(!pa0.get(), "auto_ptr holds an object after release()");
+
+ kwsys::auto_ptr<A> pa3(pb1);
+ ASSERT(!pb1.get(),
+ "auto_ptr full after being used to construct another");
+ ASSERT(pa3.get(),
+ "auto_ptr empty after construction from another");
+
+ {
+ kwsys::auto_ptr<A> pa;
+ pa = pa3;
+ ASSERT(!pa3.get(),
+ "auto_ptr full after assignment to another");
+ ASSERT(pa.get(),
+ "auto_ptr empty after assignment from another");
+ }
+
+ {
+ kwsys::auto_ptr<A> pa;
+ pa = pb2;
+ ASSERT(!pb2.get(),
+ "auto_ptr full after assignment to compatible");
+ ASSERT(pa.get(),
+ "auto_ptr empty after assignment from compatible");
+ }
+
+ {
+ int receive = function_call(pa2);
+ ASSERT(receive,
+ "auto_ptr did not receive ownership in called function");
+ ASSERT(!pa2.get(),
+ "auto_ptr did not release ownership to called function");
+ }
+
+ {
+ int received = function_call(generate_auto_ptr_A());
+ ASSERT(received,
+ "auto_ptr in called function did not take ownership "
+ "from factory function");
+ }
+
+#if 0
+ // Is this allowed by the standard?
+ {
+ int received = function_call(generate_auto_ptr_B());
+ ASSERT(received,
+ "auto_ptr in called function did not take ownership "
+ "from factory function with conversion");
+ }
+#endif
+
+ {
+ kwsys::auto_ptr<A> pa(generate_auto_ptr_A());
+ ASSERT(pa.get(),
+ "auto_ptr empty after construction from factory function");
+ }
+
+ {
+ kwsys::auto_ptr<A> pa;
+ pa = generate_auto_ptr_A();
+ ASSERT(pa.get(),
+ "auto_ptr empty after assignment from factory function");
+ }
+
+ {
+ kwsys::auto_ptr<A> pa(generate_auto_ptr_B());
+ ASSERT(pa.get(),
+ "auto_ptr empty after construction from compatible factory function");
+ }
+
+ {
+ kwsys::auto_ptr<A> pa;
+ pa = generate_auto_ptr_B();
+ ASSERT(pa.get(),
+ "auto_ptr empty after assignment from compatible factory function");
+ }
+ }
+
+ ASSERT(instances == 0, "auto_ptr leaked an object");
+
+ return status;
+}
diff --git a/Source/kwsys/testCommandLineArguments.cxx b/Source/kwsys/testCommandLineArguments.cxx
new file mode 100644
index 000000000..e75a87e86
--- /dev/null
+++ b/Source/kwsys/testCommandLineArguments.cxx
@@ -0,0 +1,187 @@
+/*============================================================================
+ 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(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 <stddef.h> /* size_t */
+#include <string.h> /* strcmp */
+
+void* random_ptr = reinterpret_cast<void*>(0x123);
+
+int argument(const char* arg, const char* value, void* call_data)
+{
+ kwsys_ios::cout << "Got argument: \"" << arg << "\" value: \"" << (value?value:"(null)") << "\"" << kwsys_ios::endl;
+ if ( call_data != random_ptr )
+ {
+ kwsys_ios::cerr << "Problem processing call_data" << kwsys_ios::endl;
+ return 0;
+ }
+ return 1;
+}
+
+int unknown_argument(const char* argument, void* call_data)
+{
+ kwsys_ios::cout << "Got unknown argument: \"" << argument << "\"" << kwsys_ios::endl;
+ if ( call_data != random_ptr )
+ {
+ kwsys_ios::cerr << "Problem processing call_data" << kwsys_ios::endl;
+ return 0;
+ }
+ return 1;
+}
+
+bool CompareTwoItemsOnList(bool i1, bool i2) { return i1 == i2; }
+bool CompareTwoItemsOnList(int i1, int i2) { return i1 == i2; }
+bool CompareTwoItemsOnList(double i1, double i2) { return i1 == i2; }
+bool CompareTwoItemsOnList(const char* i1,
+ const char* i2) { return strcmp(i1, i2) == 0; }
+bool CompareTwoItemsOnList(const kwsys_stl::string& i1,
+ const kwsys_stl::string& i2) { return i1 == i2; }
+
+int testCommandLineArguments(int argc, char* argv[])
+{
+ // Example run: ./testCommandLineArguments --some-int-variable 4
+ // --another-bool-variable --some-bool-variable=yes
+ // --some-stl-string-variable=foobar --set-bool-arg1 --set-bool-arg2
+ // --some-string-variable=hello
+
+ int res = 0;
+ kwsys::CommandLineArguments arg;
+ arg.Initialize(argc, argv);
+
+ // For error handling
+ arg.SetClientData(random_ptr);
+ arg.SetUnknownArgumentCallback(unknown_argument);
+
+ int some_int_variable = 10;
+ double some_double_variable = 10.10;
+ char* some_string_variable = 0;
+ kwsys_stl::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;
+ int valid_numbers[] = { 5, 1, 8, 3, 7, 1, 3, 9, 7, 1 };
+
+ kwsys_stl::vector<double> doubles_argument;
+ double valid_doubles[] = { 12.5, 1.31, 22 };
+
+ kwsys_stl::vector<bool> bools_argument;
+ bool valid_bools[] = { true, true, false };
+
+ kwsys_stl::vector<char*> strings_argument;
+ const char* valid_strings[] = { "andy", "bill", "brad", "ken" };
+
+ kwsys_stl::vector<kwsys_stl::string> stl_strings_argument;
+ kwsys_stl::string valid_stl_strings[] = { "ken", "brad", "bill", "andy" };
+
+ typedef kwsys::CommandLineArguments argT;
+
+ arg.AddArgument("--some-int-variable", argT::SPACE_ARGUMENT, &some_int_variable, "Set some random int variable");
+ arg.AddArgument("--some-double-variable", argT::CONCAT_ARGUMENT, &some_double_variable, "Set some random double variable");
+ arg.AddArgument("--some-string-variable", argT::EQUAL_ARGUMENT, &some_string_variable, "Set some random string variable");
+ arg.AddArgument("--some-stl-string-variable", argT::EQUAL_ARGUMENT, &some_stl_string_variable, "Set some random stl string variable");
+ arg.AddArgument("--some-bool-variable", argT::EQUAL_ARGUMENT, &some_bool_variable, "Set some random bool variable");
+ arg.AddArgument("--another-bool-variable", argT::NO_ARGUMENT, &some_bool_variable1, "Set some random bool variable 1");
+ arg.AddBooleanArgument("--set-bool-arg1", &bool_arg1, "Test AddBooleanArgument 1");
+ arg.AddBooleanArgument("--set-bool-arg2", &bool_arg2, "Test AddBooleanArgument 2");
+ arg.AddArgument("--some-multi-argument", argT::MULTI_ARGUMENT, &numbers_argument, "Some multiple values variable");
+ arg.AddArgument("-N", argT::SPACE_ARGUMENT, &doubles_argument, "Some explicit multiple values variable");
+ arg.AddArgument("-BB", argT::CONCAT_ARGUMENT, &bools_argument, "Some explicit multiple values variable");
+ arg.AddArgument("-SS", argT::EQUAL_ARGUMENT, &strings_argument, "Some explicit multiple values variable");
+ arg.AddArgument("-SSS", argT::MULTI_ARGUMENT, &stl_strings_argument, "Some explicit multiple values variable");
+
+ arg.AddCallback("-A", argT::NO_ARGUMENT, argument, random_ptr, "Some option -A. This option has a multiline comment. It should demonstrate how the code splits lines.");
+ arg.AddCallback("-B", argT::SPACE_ARGUMENT, argument, random_ptr, "Option -B takes argument with space");
+ arg.AddCallback("-C", argT::EQUAL_ARGUMENT, argument, random_ptr, "Option -C takes argument after =");
+ arg.AddCallback("-D", argT::CONCAT_ARGUMENT, argument, random_ptr, "This option takes concatinated argument");
+ arg.AddCallback("--long1", argT::NO_ARGUMENT, argument, random_ptr, "-A");
+ arg.AddCallback("--long2", argT::SPACE_ARGUMENT, argument, random_ptr, "-B");
+ arg.AddCallback("--long3", argT::EQUAL_ARGUMENT, argument, random_ptr, "Same as -C but a bit different");
+ arg.AddCallback("--long4", argT::CONCAT_ARGUMENT, argument, random_ptr, "-C");
+
+ if ( !arg.Parse() )
+ {
+ kwsys_ios::cerr << "Problem parsing arguments" << kwsys_ios::endl;
+ res = 1;
+ }
+ kwsys_ios::cout << "Help: " << arg.GetHelp() << kwsys_ios::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;
+ if ( some_string_variable && strcmp(some_string_variable, "test string with space") == 0)
+ {
+ kwsys_ios::cout << "Some string variable was set to: " << some_string_variable << kwsys_ios::endl;
+ delete [] some_string_variable;
+ }
+ else
+ {
+ kwsys_ios::cerr << "Problem setting string variable" << kwsys_ios::endl;
+ res = 1;
+ }
+ size_t cc;
+#define CompareTwoLists(list1, list_valid, lsize) \
+ if ( list1.size() != lsize ) \
+ { \
+ kwsys_ios::cerr << "Problem setting " #list1 ". Size is: " << list1.size() \
+ << " should be: " << lsize << kwsys_ios::endl; \
+ res = 1; \
+ } \
+ else \
+ { \
+ kwsys_ios::cout << #list1 " argument set:"; \
+ for ( cc =0; cc < lsize; ++ cc ) \
+ { \
+ kwsys_ios::cout << " " << list1[cc]; \
+ if ( !CompareTwoItemsOnList(list1[cc], list_valid[cc]) ) \
+ { \
+ kwsys_ios::cerr << "Problem setting " #list1 ". Value of " \
+ << cc << " is: [" << list1[cc] << "] <> [" \
+ << list_valid[cc] << "]" << kwsys_ios::endl; \
+ res = 1; \
+ break; \
+ } \
+ } \
+ kwsys_ios::cout << kwsys_ios::endl; \
+ }
+
+ CompareTwoLists(numbers_argument, valid_numbers, 10);
+ CompareTwoLists(doubles_argument, valid_doubles, 3);
+ CompareTwoLists(bools_argument, valid_bools, 3);
+ CompareTwoLists(strings_argument, valid_strings, 4);
+ CompareTwoLists(stl_strings_argument, valid_stl_strings, 4);
+
+ kwsys_ios::cout << "Some STL String variable was set to: " << some_stl_string_variable.c_str() << kwsys_ios::endl;
+ kwsys_ios::cout << "Some bool variable was set to: " << some_bool_variable << kwsys_ios::endl;
+ kwsys_ios::cout << "Some bool variable was set to: " << some_bool_variable1 << kwsys_ios::endl;
+ kwsys_ios::cout << "bool_arg1 variable was set to: " << bool_arg1 << kwsys_ios::endl;
+ kwsys_ios::cout << "bool_arg2 variable was set to: " << bool_arg2 << kwsys_ios::endl;
+ kwsys_ios::cout << kwsys_ios::endl;
+
+ for ( cc = 0; cc < strings_argument.size(); ++ cc )
+ {
+ delete [] strings_argument[cc];
+ strings_argument[cc] = 0;
+ }
+ return res;
+}
diff --git a/Source/kwsys/testCommandLineArguments1.cxx b/Source/kwsys/testCommandLineArguments1.cxx
new file mode 100644
index 000000000..0860c2abc
--- /dev/null
+++ b/Source/kwsys/testCommandLineArguments1.cxx
@@ -0,0 +1,106 @@
+/*============================================================================
+ 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(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 <string.h> /* strcmp */
+
+int testCommandLineArguments1(int argc, char* argv[])
+{
+ kwsys::CommandLineArguments arg;
+ arg.Initialize(argc, argv);
+
+ int n = 0;
+ char* m = 0;
+ kwsys_stl::string p;
+ int res = 0;
+
+ typedef kwsys::CommandLineArguments argT;
+ arg.AddArgument("-n", argT::SPACE_ARGUMENT, &n, "Argument N");
+ arg.AddArgument("-m", argT::EQUAL_ARGUMENT, &m, "Argument M");
+ arg.AddBooleanArgument("-p", &p, "Argument P");
+
+ arg.StoreUnusedArguments(true);
+
+ if ( !arg.Parse() )
+ {
+ kwsys_ios::cerr << "Problem parsing arguments" << kwsys_ios::endl;
+ res = 1;
+ }
+ if ( n != 24 )
+ {
+ kwsys_ios::cout << "Problem setting N. Value of N: " << n << kwsys_ios::endl;
+ res = 1;
+ }
+ if ( !m || strcmp(m, "test value") != 0 )
+ {
+ kwsys_ios::cout << "Problem setting M. Value of M: " << m << kwsys_ios::endl;
+ res = 1;
+ }
+ if ( p != "1" )
+ {
+ kwsys_ios::cout << "Problem setting P. Value of P: " << p.c_str() << kwsys_ios::endl;
+ res = 1;
+ }
+ kwsys_ios::cout << "Value of N: " << n << kwsys_ios::endl;
+ kwsys_ios::cout << "Value of M: " << m << kwsys_ios::endl;
+ kwsys_ios::cout << "Value of P: " << p.c_str() << kwsys_ios::endl;
+ if ( m )
+ {
+ delete [] m;
+ }
+
+ char** newArgv = 0;
+ int newArgc = 0;
+ arg.GetUnusedArguments(&newArgc, &newArgv);
+ int cc;
+ const char* valid_unused_args[9] = {
+ 0, "--ignored", "--second-ignored", "third-ignored",
+ "some", "junk", "at", "the", "end"
+ };
+ if ( newArgc != 9 )
+ {
+ kwsys_ios::cerr << "Bad number of unused arguments: " << newArgc << kwsys_ios::endl;
+ res = 1;
+ }
+ for ( cc = 0; cc < newArgc; ++ cc )
+ {
+ kwsys_ios::cout << "Unused argument[" << cc << "] = [" << newArgv[cc] << "]"
+ << kwsys_ios::endl;
+ if ( cc >= 9 )
+ {
+ kwsys_ios::cerr << "Too many unused arguments: " << cc << kwsys_ios::endl;
+ res = 1;
+ }
+ else if ( valid_unused_args[cc] &&
+ strcmp(valid_unused_args[cc], newArgv[cc]) != 0 )
+ {
+ kwsys_ios::cerr << "Bad unused argument [" << cc << "] \""
+ << newArgv[cc] << "\" should be: \"" << valid_unused_args[cc] << "\""
+ << kwsys_ios::endl;
+ res = 1;
+ }
+ }
+ arg.DeleteRemainingArguments(newArgc, &newArgv);
+
+ return res;
+}
+
diff --git a/Source/kwsys/testDynamicLoader.cxx b/Source/kwsys/testDynamicLoader.cxx
new file mode 100644
index 000000000..a7adbcad9
--- /dev/null
+++ b/Source/kwsys/testDynamicLoader.cxx
@@ -0,0 +1,133 @@
+/*============================================================================
+ 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(DynamicLoader.hxx)
+#include KWSYS_HEADER(ios/iostream)
+#include KWSYS_HEADER(stl/string)
+
+#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 with <> instead of "" to avoid getting any in-source copy
+// left on disk.
+#include <testSystemTools.h>
+
+kwsys_stl::string GetLibName(const char* lname)
+{
+ // Construct proper name of lib
+ kwsys_stl::string slname;
+ slname = EXECUTABLE_OUTPUT_PATH;
+#ifdef CMAKE_INTDIR
+ slname += "/";
+ slname += CMAKE_INTDIR;
+#endif
+ slname += "/";
+ slname += kwsys::DynamicLoader::LibPrefix();
+ slname += lname;
+ slname += kwsys::DynamicLoader::LibExtension();
+
+ return slname;
+}
+
+/* libname = Library name (proper prefix, proper extension)
+ * System = symbol to lookup in libname
+ * r1: should OpenLibrary succeed ?
+ * r2: should GetSymbolAddress succeed ?
+ * r3: should CloseLibrary succeed ?
+ */
+int TestDynamicLoader(const char* libname, const char* symbol, int r1, int r2, int r3)
+{
+ kwsys_ios::cerr << "Testing: " << libname << kwsys_ios::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;
+ 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;
+ return 1;
+ }
+#ifndef __APPLE__
+ int s = kwsys::DynamicLoader::CloseLibrary(l);
+ if( (r3 && !s) || (!r3 && s) )
+ {
+ kwsys_ios::cerr
+ << kwsys::DynamicLoader::LastError() << kwsys_ios::endl;
+ return 1;
+ }
+#else
+ (void)r3;
+#endif
+ return 0;
+}
+
+int testDynamicLoader(int argc, char *argv[])
+{
+#if defined(_WIN32)
+ SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
+#elif defined(__BEOS__) || defined(__HAIKU__)
+ disable_debugger(1);
+#endif
+ int res = 0;
+ if( argc == 3 )
+ {
+ // User specify a libname and symbol to check.
+ res = TestDynamicLoader(argv[1], argv[2],1,1,1);
+ return res;
+ }
+
+// dlopen() on Syllable before 11/22/2007 doesn't return 0 on error
+#ifndef __SYLLABLE__
+ // Make sure that inexistant lib is giving correct result
+ res += TestDynamicLoader("azerty_", "foo_bar",0,0,0);
+ // Make sure that random binary file cannnot be assimilated as dylib
+ res += TestDynamicLoader(TEST_SYSTEMTOOLS_BIN_FILE, "wp",0,0,0);
+#endif
+
+#ifdef __linux__
+ // This one is actually fun to test, since dlopen is by default loaded...wonder why :)
+ res += TestDynamicLoader("foobar.lib", "dlopen",0,1,0);
+ res += TestDynamicLoader("libdl.so", "dlopen",1,1,1);
+ res += TestDynamicLoader("libdl.so", "TestDynamicLoader",1,0,1);
+#endif
+ // Now try on the generated library
+ kwsys_stl::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);
+ res += TestDynamicLoader(libname.c_str(), "TestDynamicLoaderData",1,1,1);
+ res += TestDynamicLoader(libname.c_str(), "_TestDynamicLoaderData",1,0,1);
+
+ return res;
+}
diff --git a/Source/kwsys/testDynload.c b/Source/kwsys/testDynload.c
new file mode 100644
index 000000000..ba60becbd
--- /dev/null
+++ b/Source/kwsys/testDynload.c
@@ -0,0 +1,22 @@
+/*============================================================================
+ 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 _WIN32
+#define DL_EXPORT __declspec( dllexport )
+#else
+#define DL_EXPORT
+#endif
+
+DL_EXPORT int TestDynamicLoaderData = 0;
+
+DL_EXPORT void TestDynamicLoaderSymbolPointer()
+{
+}
diff --git a/Source/kwsys/testEncode.c b/Source/kwsys/testEncode.c
new file mode 100644
index 000000000..26d483b6f
--- /dev/null
+++ b/Source/kwsys/testEncode.c
@@ -0,0 +1,76 @@
+/*============================================================================
+ 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(MD5.h)
+
+/* Work-around CMake dependency scanning limitation. This must
+ duplicate the above list of headers. */
+#if 0
+# include "MD5.h.in"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+static const unsigned char testMD5input1[] =
+" A quick brown fox jumps over the lazy dog.\n"
+" This is sample text for MD5 sum input.\n";
+static const char testMD5output1[] = "8f146af46ed4f267921bb937d4d3500c";
+
+static const int testMD5input2len = 28;
+static const unsigned char testMD5input2[] = "the cow jumped over the moon";
+static const char testMD5output2[] = "a2ad137b746138fae4e5adca9c85d3ae";
+
+static int testMD5_1(kwsysMD5* md5)
+{
+ char md5out[33];
+ kwsysMD5_Initialize(md5);
+ kwsysMD5_Append(md5, testMD5input1, -1);
+ kwsysMD5_FinalizeHex(md5, md5out);
+ md5out[32] = 0;
+ printf("md5sum 1: expected [%s]\n"
+ " got [%s]\n",
+ testMD5output1, md5out);
+ return (strcmp(md5out, testMD5output1) != 0)? 1:0;
+}
+
+static int testMD5_2(kwsysMD5* md5)
+{
+ unsigned char digest[16];
+ char md5out[33];
+ kwsysMD5_Initialize(md5);
+ kwsysMD5_Append(md5, testMD5input2, testMD5input2len);
+ kwsysMD5_Finalize(md5, digest);
+ kwsysMD5_DigestToHex(digest, md5out);
+ md5out[32] = 0;
+ printf("md5sum 2: expected [%s]\n"
+ " got [%s]\n",
+ testMD5output2, md5out);
+ return (strcmp(md5out, testMD5output2) != 0)? 1:0;
+}
+
+int testEncode(int argc, char* argv[])
+{
+ int result = 0;
+ (void)argc;
+ (void)argv;
+
+ /* Test MD5 digest. */
+ {
+ kwsysMD5* md5 = kwsysMD5_New();
+ result |= testMD5_1(md5);
+ result |= testMD5_2(md5);
+ kwsysMD5_Delete(md5);
+ }
+
+ return result;
+}
diff --git a/Source/kwsys/testFail.c b/Source/kwsys/testFail.c
new file mode 100644
index 000000000..7e062c175
--- /dev/null
+++ b/Source/kwsys/testFail.c
@@ -0,0 +1,35 @@
+/*============================================================================
+ 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int testFail(int argc, char* argv[])
+{
+ char* env = getenv("DASHBOARD_TEST_FROM_CTEST");
+ int oldCtest = 0;
+ if(env)
+ {
+ if(strcmp(env, "1") == 0)
+ {
+ oldCtest = 1;
+ }
+ printf("DASHBOARD_TEST_FROM_CTEST = %s\n", env);
+ }
+ printf("%s: This test intentionally fails\n", argv[0]);
+ if(oldCtest)
+ {
+ printf("The version of ctest is not able to handle intentionally failing tests, so pass.\n");
+ return 0;
+ }
+ return argc;
+}
diff --git a/Source/kwsys/testHashSTL.cxx b/Source/kwsys/testHashSTL.cxx
new file mode 100644
index 000000000..b861a5b32
--- /dev/null
+++ b/Source/kwsys/testHashSTL.cxx
@@ -0,0 +1,75 @@
+/*============================================================================
+ 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(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.
+#if 0
+# include "hash_map.hxx.in"
+# include "hash_set.hxx.in"
+# include "hashtable.hxx.in"
+# include "kwsys_ios_iostream.h.in"
+#endif
+
+#if defined(_MSC_VER)
+# pragma warning (disable:4786)
+#endif
+
+#if defined(__sgi) && !defined(__GNUC__)
+# pragma set woff 1468 /* inline function cannot be explicitly instantiated */
+#endif
+
+template class kwsys::hash_map<const char*, int>;
+template class kwsys::hash_set<int>;
+
+bool test_hash_map()
+{
+ typedef kwsys::hash_map<const char*, int> mtype;
+ mtype m;
+ const char* keys[] = {"hello", "world"};
+ m[keys[0]] = 1;
+ m.insert(mtype::value_type(keys[1], 2));
+ 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;
+ sum += mi->second;
+ }
+ return sum == 3;
+}
+
+bool test_hash_set()
+{
+ typedef kwsys::hash_set<int> stype;
+ stype s;
+ s.insert(1);
+ s.insert(2);
+ int sum = 0;
+ for(stype::iterator si = s.begin(); si != s.end(); ++si)
+ {
+ kwsys_ios::cout << "Found entry [" << *si << "]" << kwsys_ios::endl;
+ sum += *si;
+ }
+ return sum == 3;
+}
+
+int testHashSTL(int, char*[])
+{
+ bool result = true;
+ result = test_hash_map() && result;
+ result = test_hash_set() && result;
+ return result? 0:1;
+}
diff --git a/Source/kwsys/testIOS.cxx b/Source/kwsys/testIOS.cxx
new file mode 100644
index 000000000..3b971e268
--- /dev/null
+++ b/Source/kwsys/testIOS.cxx
@@ -0,0 +1,167 @@
+/*============================================================================
+ 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(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 <string.h> /* strlen */
+
+int testIOS(int, char*[])
+{
+ kwsys_ios::ostringstream ostr;
+ const char hello[] = "hello";
+ ostr << hello;
+ if(ostr.str() != hello)
+ {
+ kwsys_ios::cerr << "failed to write hello to ostr" << kwsys_ios::endl;
+ return 1;
+ }
+ const char world[] = "world";
+ kwsys_ios::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;
+ 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 unsigned int narray = sizeof(array); // 180
+ kwsys_ios::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;
+ return 1;
+ }
+
+ kwsys_ios::istringstream istr(" 10 20 str ");
+ kwsys_stl::string s;
+ int x;
+ if(istr >> x)
+ {
+ if(x != 10)
+ {
+ kwsys_ios::cerr << "x != 10" << kwsys_ios::endl;
+ return 1;
+ }
+ }
+ else
+ {
+ kwsys_ios::cerr << "Failed to read 10 from istr" << kwsys_ios::endl;
+ return 1;
+ }
+ if(istr >> x)
+ {
+ if(x != 20)
+ {
+ kwsys_ios::cerr << "x != 20" << kwsys_ios::endl;
+ return 1;
+ }
+ }
+ else
+ {
+ kwsys_ios::cerr << "Failed to read 20 from istr" << kwsys_ios::endl;
+ return 1;
+ }
+ if(istr >> s)
+ {
+ if(s != "str")
+ {
+ kwsys_ios::cerr << "s != \"str\"" << kwsys_ios::endl;
+ return 1;
+ }
+ }
+ else
+ {
+ kwsys_ios::cerr << "Failed to read str from istr" << kwsys_ios::endl;
+ return 1;
+ }
+ if(istr >> s)
+ {
+ kwsys_ios::cerr << "Able to read past end of stream" << kwsys_ios::endl;
+ return 1;
+ }
+ else
+ {
+ // Clear the failure.
+ istr.clear(istr.rdstate() & ~kwsys_ios::ios::eofbit);
+ istr.clear(istr.rdstate() & ~kwsys_ios::ios::failbit);
+ }
+ istr.str("30");
+ if(istr >> x)
+ {
+ if(x != 30)
+ {
+ kwsys_ios::cerr << "x != 30" << kwsys_ios::endl;
+ return 1;
+ }
+ }
+ else
+ {
+ kwsys_ios::cerr << "Failed to read 30 from istr" << kwsys_ios::endl;
+ return 1;
+ }
+
+ kwsys_ios::stringstream sstr;
+ sstr << "40 str2";
+ if(sstr >> x)
+ {
+ if(x != 40)
+ {
+ kwsys_ios::cerr << "x != 40" << kwsys_ios::endl;
+ return 1;
+ }
+ }
+ else
+ {
+ kwsys_ios::cerr << "Failed to read 40 from sstr" << kwsys_ios::endl;
+ return 1;
+ }
+ if(sstr >> s)
+ {
+ if(s != "str2")
+ {
+ kwsys_ios::cerr << "s != \"str2\"" << kwsys_ios::endl;
+ return 1;
+ }
+ }
+ else
+ {
+ kwsys_ios::cerr << "Failed to read str2 from sstr" << kwsys_ios::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);
+ }
+
+ kwsys_ios::cout << "IOS tests passed" << kwsys_ios::endl;
+ return 0;
+}
diff --git a/Source/kwsys/testProcess.c b/Source/kwsys/testProcess.c
new file mode 100644
index 000000000..877002a14
--- /dev/null
+++ b/Source/kwsys/testProcess.c
@@ -0,0 +1,526 @@
+/*============================================================================
+ 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(Process.h)
+
+/* Work-around CMake dependency scanning limitation. This must
+ duplicate the above list of headers. */
+#if 0
+# include "Process.h.in"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if defined(_WIN32)
+# include <windows.h>
+#else
+# include <unistd.h>
+#endif
+
+#if defined(__BORLANDC__)
+# pragma warn -8060 /* possibly incorrect assignment */
+#endif
+
+#if defined(__BEOS__) && !defined(__ZETA__) && !defined(__HAIKU__)
+/* 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)
+{
+ snooze(msec);
+}
+#else
+# define testProcess_usleep usleep
+#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 test1(int argc, const char* argv[])
+{
+ (void)argc; (void)argv;
+ fprintf(stdout, "Output on stdout from test returning 0.\n");
+ fprintf(stderr, "Output on stderr from test returning 0.\n");
+ return 0;
+}
+
+int test2(int argc, const char* argv[])
+{
+ (void)argc; (void)argv;
+ fprintf(stdout, "Output on stdout from test returning 123.\n");
+ fprintf(stderr, "Output on stderr from test returning 123.\n");
+ return 123;
+}
+
+int test3(int argc, const char* argv[])
+{
+ (void)argc; (void)argv;
+ fprintf(stdout, "Output before sleep on stdout from timeout test.\n");
+ fprintf(stderr, "Output before sleep on stderr from timeout test.\n");
+ fflush(stdout);
+ fflush(stderr);
+#if defined(_WIN32)
+ Sleep(15000);
+#else
+ sleep(15);
+#endif
+ fprintf(stdout, "Output after sleep on stdout from timeout test.\n");
+ fprintf(stderr, "Output after sleep on stderr from timeout test.\n");
+ return 0;
+}
+
+int test4(int argc, const char* argv[])
+{
+#if defined(_WIN32)
+ /* Avoid error diagnostic popups since we are crashing on purpose. */
+ SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
+#elif defined(__BEOS__) || defined(__HAIKU__)
+ /* Avoid error diagnostic popups since we are crashing on purpose. */
+ disable_debugger(1);
+#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");
+ fflush(stdout);
+ fflush(stderr);
+#if defined(__clang__)
+ *(int*)1 = 0; /* Clang warns about 0-ptr; undefined behavior. */
+#else
+ *(int*)0 = 0;
+#endif
+ fprintf(stdout, "Output after crash on stdout from crash test.\n");
+ fprintf(stderr, "Output after crash on stderr from crash test.\n");
+ return 0;
+}
+
+int test5(int argc, const char* argv[])
+{
+ int r;
+ const char* cmd[4];
+ (void)argc;
+ cmd[0] = argv[0];
+ cmd[1] = "run";
+ cmd[2] = "4";
+ cmd[3] = 0;
+ fprintf(stdout, "Output on stdout before recursive test.\n");
+ fprintf(stderr, "Output on stderr before recursive test.\n");
+ fflush(stdout);
+ fflush(stderr);
+ r = runChild(cmd, kwsysProcess_State_Exception,
+ kwsysProcess_Exception_Fault, 1, 1, 1, 0, 15, 0, 1, 0);
+ fprintf(stdout, "Output on stdout after recursive test.\n");
+ fprintf(stderr, "Output on stderr after recursive test.\n");
+ fflush(stdout);
+ fflush(stderr);
+ return r;
+}
+
+#define TEST6_SIZE (4096*2)
+void test6(int argc, const char* argv[])
+{
+ int i;
+ char runaway[TEST6_SIZE+1];
+ (void)argc; (void)argv;
+ for(i=0;i < TEST6_SIZE;++i)
+ {
+ runaway[i] = '.';
+ }
+ runaway[TEST6_SIZE] = '\n';
+
+ /* Generate huge amounts of output to test killing. */
+ for(;;)
+ {
+ fwrite(runaway, 1, TEST6_SIZE+1, stdout);
+ fflush(stdout);
+ }
+}
+
+/* Define MINPOLL to be one more than the number of times output is
+ written. Define MAXPOLL to be the largest number of times a loop
+ delaying 1/10th of a second should ever have to poll. */
+#define MINPOLL 5
+#define MAXPOLL 20
+int test7(int argc, const char* argv[])
+{
+ (void)argc; (void)argv;
+ fprintf(stdout, "Output on stdout before sleep.\n");
+ fprintf(stderr, "Output on stderr before sleep.\n");
+ fflush(stdout);
+ fflush(stderr);
+ /* Sleep for 1 second. */
+#if defined(_WIN32)
+ Sleep(1000);
+#else
+ sleep(1);
+#endif
+ fprintf(stdout, "Output on stdout after sleep.\n");
+ fprintf(stderr, "Output on stderr after sleep.\n");
+ fflush(stdout);
+ fflush(stderr);
+ return 0;
+}
+
+int test8(int argc, const char* argv[])
+{
+ /* Create a disowned grandchild to test handling of processes
+ that exit before their children. */
+ int r;
+ const char* cmd[4];
+ (void)argc;
+ cmd[0] = argv[0];
+ cmd[1] = "run";
+ cmd[2] = "108";
+ 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_Disowned, kwsysProcess_Exception_None,
+ 1, 1, 1, 0, 10, 0, 1, 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;
+}
+
+int test8_grandchild(int argc, const char* argv[])
+{
+ (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);
+ /* TODO: Instead of closing pipes here leave them open to make sure
+ the grandparent can stop listening when the parent exits. This
+ part of the test cannot be enabled until the feature is
+ implemented. */
+ fclose(stdout);
+ fclose(stderr);
+#if defined(_WIN32)
+ Sleep(15000);
+#else
+ sleep(15);
+#endif
+ return 0;
+}
+
+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 result = 0;
+ char* data = 0;
+ int length = 0;
+ double userTimeout = 0;
+ double* pUserTimeout = 0;
+ kwsysProcess_SetCommand(kp, cmd);
+ if(timeout >= 0)
+ {
+ kwsysProcess_SetTimeout(kp, timeout);
+ }
+ if(share)
+ {
+ kwsysProcess_SetPipeShared(kp, kwsysProcess_Pipe_STDOUT, 1);
+ kwsysProcess_SetPipeShared(kp, kwsysProcess_Pipe_STDERR, 1);
+ }
+ if(disown)
+ {
+ kwsysProcess_SetOption(kp, kwsysProcess_Option_Detach, 1);
+ }
+ kwsysProcess_Execute(kp);
+
+ if(poll)
+ {
+ pUserTimeout = &userTimeout;
+ }
+
+ if(!share && !disown)
+ {
+ int p;
+ while((p = kwsysProcess_WaitForData(kp, &data, &length, pUserTimeout)))
+ {
+ if(output)
+ {
+ if(poll && p == kwsysProcess_Pipe_Timeout)
+ {
+ fprintf(stdout, "WaitForData timeout reached.\n");
+ fflush(stdout);
+
+ /* Count the number of times we polled without getting data.
+ If it is excessive then kill the child and fail. */
+ if(++poll >= MAXPOLL)
+ {
+ fprintf(stdout, "Poll count reached limit %d.\n",
+ MAXPOLL);
+ kwsysProcess_Kill(kp);
+ }
+ }
+ else
+ {
+ fwrite(data, 1, (size_t) length, stdout);
+ fflush(stdout);
+ }
+ }
+ 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);
+#endif
+ }
+ }
+ }
+
+ if(disown)
+ {
+ kwsysProcess_Disown(kp);
+ }
+ else
+ {
+ kwsysProcess_WaitForExit(kp, 0);
+ }
+
+ switch (kwsysProcess_GetState(kp))
+ {
+ case kwsysProcess_State_Starting:
+ printf("No process has been executed.\n"); break;
+ case kwsysProcess_State_Executing:
+ printf("The process is still executing.\n"); break;
+ case kwsysProcess_State_Expired:
+ printf("Child was killed when timeout expired.\n"); break;
+ case kwsysProcess_State_Exited:
+ printf("Child exited with value = %d\n",
+ kwsysProcess_GetExitValue(kp));
+ result = ((exception != kwsysProcess_GetExitException(kp)) ||
+ (value != kwsysProcess_GetExitValue(kp))); break;
+ case kwsysProcess_State_Killed:
+ printf("Child was killed by parent.\n"); break;
+ case kwsysProcess_State_Exception:
+ printf("Child terminated abnormally: %s\n",
+ kwsysProcess_GetExceptionString(kp));
+ result = ((exception != kwsysProcess_GetExitException(kp)) ||
+ (value != kwsysProcess_GetExitValue(kp))); break;
+ case kwsysProcess_State_Disowned:
+ printf("Child was disowned.\n"); break;
+ case kwsysProcess_State_Error:
+ printf("Error in administrating child process: [%s]\n",
+ kwsysProcess_GetErrorString(kp)); break;
+ };
+
+ if(result)
+ {
+ if(exception != kwsysProcess_GetExitException(kp))
+ {
+ fprintf(stderr, "Mismatch in exit exception. "
+ "Should have been %d, was %d.\n",
+ exception, kwsysProcess_GetExitException(kp));
+ }
+ if(value != kwsysProcess_GetExitValue(kp))
+ {
+ fprintf(stderr, "Mismatch in exit value. "
+ "Should have been %d, was %d.\n",
+ value, kwsysProcess_GetExitValue(kp));
+ }
+ }
+
+ if(kwsysProcess_GetState(kp) != state)
+ {
+ fprintf(stderr, "Mismatch in state. "
+ "Should have been %d, was %d.\n",
+ state, kwsysProcess_GetState(kp));
+ result = 1;
+ }
+
+ /* We should have polled more times than there were data if polling
+ was enabled. */
+ if(poll && poll < MINPOLL)
+ {
+ fprintf(stderr, "Poll count is %d, which is less than %d.\n",
+ poll, MINPOLL);
+ result = 1;
+ }
+
+ return result;
+}
+
+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 result = 1;
+ kwsysProcess* kp = kwsysProcess_New();
+ if(!kp)
+ {
+ fprintf(stderr, "kwsysProcess_New returned NULL!\n");
+ return 1;
+ }
+ while(repeat-- > 0)
+ {
+ result = runChild2(kp, cmd, state, exception, value, share,
+ output, delay, timeout, poll, disown);
+ }
+ kwsysProcess_Delete(kp);
+ return result;
+}
+
+int main(int argc, const char* argv[])
+{
+ int n = 0;
+#if 0
+ {
+ HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
+ DuplicateHandle(GetCurrentProcess(), out,
+ GetCurrentProcess(), &out, 0, FALSE,
+ DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
+ SetStdHandle(STD_OUTPUT_HANDLE, out);
+ }
+ {
+ HANDLE out = GetStdHandle(STD_ERROR_HANDLE);
+ DuplicateHandle(GetCurrentProcess(), out,
+ GetCurrentProcess(), &out, 0, FALSE,
+ DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
+ SetStdHandle(STD_ERROR_HANDLE, out);
+ }
+#endif
+ if(argc == 2)
+ {
+ n = atoi(argv[1]);
+ }
+ else if(argc == 3 && strcmp(argv[1], "run") == 0)
+ {
+ n = atoi(argv[2]);
+ }
+ /* Check arguments. */
+ if(((n >= 1 && n <= 8) || n == 108) && argc == 3)
+ {
+ /* This is the child process for a requested test number. */
+ switch (n)
+ {
+ case 1: return test1(argc, argv);
+ case 2: return test2(argc, argv);
+ case 3: return test3(argc, argv);
+ case 4: return test4(argc, argv);
+ case 5: return test5(argc, argv);
+ case 6: test6(argc, argv); return 0;
+ case 7: return test7(argc, argv);
+ case 8: return test8(argc, argv);
+ case 108: return test8_grandchild(argc, argv);
+ }
+ fprintf(stderr, "Invalid test number %d.\n", n);
+ return 1;
+ }
+ else if(n >= 1 && n <= 8)
+ {
+ /* This is the parent process for a requested test number. */
+ int states[8] =
+ {
+ kwsysProcess_State_Exited,
+ kwsysProcess_State_Exited,
+ kwsysProcess_State_Expired,
+ kwsysProcess_State_Exception,
+ kwsysProcess_State_Exited,
+ kwsysProcess_State_Expired,
+ kwsysProcess_State_Exited,
+ kwsysProcess_State_Exited
+ };
+ int exceptions[8] =
+ {
+ kwsysProcess_Exception_None,
+ kwsysProcess_Exception_None,
+ kwsysProcess_Exception_None,
+ kwsysProcess_Exception_Fault,
+ kwsysProcess_Exception_None,
+ kwsysProcess_Exception_None,
+ kwsysProcess_Exception_None,
+ kwsysProcess_Exception_None
+ };
+ 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 r;
+ const char* cmd[4];
+#ifdef _WIN32
+ char* argv0 = 0;
+ if(n == 0 && (argv0 = strdup(argv[0])))
+ {
+ /* Try converting to forward slashes to see if it works. */
+ char* c;
+ for(c=argv0; *c; ++c)
+ {
+ if(*c == '\\')
+ {
+ *c = '/';
+ }
+ }
+ cmd[0] = argv0;
+ }
+ else
+ {
+ cmd[0] = argv[0];
+ }
+#else
+ cmd[0] = argv[0];
+#endif
+ cmd[1] = "run";
+ cmd[2] = argv[1];
+ cmd[3] = 0;
+ fprintf(stdout, "Output on stdout before test %d.\n", n);
+ 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,
+ outputs[n-1], delays[n-1], timeouts[n-1],
+ polls[n-1], repeat[n-1], 0);
+ fprintf(stdout, "Output on stdout after test %d.\n", n);
+ fprintf(stderr, "Output on stderr after test %d.\n", n);
+ fflush(stdout);
+ fflush(stderr);
+#if _WIN32
+ if(argv0) { free(argv0); }
+#endif
+ return r;
+ }
+ else if(argc > 2 && strcmp(argv[1], "0") == 0)
+ {
+ /* This is the special debugging test to run a given command
+ line. */
+ const char** cmd = argv+2;
+ int state = kwsysProcess_State_Exited;
+ 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);
+ return r;
+ }
+ else
+ {
+ /* Improper usage. */
+ fprintf(stdout, "Usage: %s <test number>\n", argv[0]);
+ return 1;
+ }
+}
diff --git a/Source/kwsys/testRegistry.cxx b/Source/kwsys/testRegistry.cxx
new file mode 100644
index 000000000..7e9b0d49b
--- /dev/null
+++ b/Source/kwsys/testRegistry.cxx
@@ -0,0 +1,109 @@
+/*============================================================================
+ 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(Registry.hxx)
+#include KWSYS_HEADER(ios/iostream)
+#include <string.h>
+
+// Work-around CMake dependency scanning limitation. This must
+// duplicate the above list of headers.
+#if 0
+# include "Registry.hxx.in"
+# include "kwsys_ios_iostream.h.in"
+#endif
+
+#define IFT(x,res) if ( !x ) \
+ { \
+ res = 1; \
+ kwsys_ios::cout << "Error in: " << #x << kwsys_ios::endl; \
+ }
+#define IFNT(x,res) if ( x ) \
+ { \
+ res = 1; \
+ kwsys_ios::cout << "Error in: " << #x << kwsys_ios::endl; \
+ }
+
+#define CHE(x,y,res) if ( x && strcmp(x,y) ) \
+ { \
+ res = 1; \
+ kwsys_ios::cout << "Error, " << x << " != " << y << kwsys_ios::endl; \
+ }
+
+int testRegistry(int, char*[])
+{
+ int res = 0;
+
+ kwsys::Registry reg;
+ reg.SetTopLevel("TestRegistry");
+
+ IFT(reg.SetValue("TestSubkey", "TestKey1", "Test Value 1"), res);
+ IFT(reg.SetValue("TestSubkey1", "TestKey2", "Test Value 2"), res);
+ IFT(reg.SetValue("TestSubkey", "TestKey3", "Test Value 3"), res);
+ IFT(reg.SetValue("TestSubkey2", "TestKey4", "Test Value 4"), res);
+
+ const char *buffer;
+ IFT(reg.ReadValue("TestSubkey", "TestKey1", &buffer), res);
+ CHE(buffer, "Test Value 1", res);
+ IFT(reg.ReadValue("TestSubkey1", "TestKey2", &buffer), res);
+ CHE(buffer, "Test Value 2", res);
+ IFT(reg.ReadValue("TestSubkey", "TestKey3", &buffer), res);
+ CHE(buffer, "Test Value 3", res);
+ IFT(reg.ReadValue("TestSubkey2", "TestKey4", &buffer), res);
+ CHE(buffer, "Test Value 4", res);
+
+ IFT(reg.SetValue("TestSubkey", "TestKey1", "New Test Value 1"), res);
+ IFT(reg.SetValue("TestSubkey1", "TestKey2", "New Test Value 2"), res);
+ IFT(reg.SetValue("TestSubkey", "TestKey3", "New Test Value 3"), res);
+ IFT(reg.SetValue("TestSubkey2", "TestKey4", "New Test Value 4"), res);
+
+ IFT(reg.ReadValue("TestSubkey", "TestKey1", &buffer), res);
+ CHE(buffer, "New Test Value 1", res);
+ IFT(reg.ReadValue("TestSubkey1", "TestKey2", &buffer), res);
+ CHE(buffer, "New Test Value 2", res);
+ IFT(reg.ReadValue("TestSubkey", "TestKey3", &buffer), res);
+ CHE(buffer, "New Test Value 3", res);
+ IFT(reg.ReadValue("TestSubkey2", "TestKey4", &buffer), res);
+ CHE(buffer, "New Test Value 4", res);
+
+ IFT( reg.DeleteValue("TestSubkey", "TestKey1"), res);
+ IFNT(reg.ReadValue( "TestSubkey", "TestKey1", &buffer), res);
+ IFT( reg.DeleteValue("TestSubkey1", "TestKey2"), res);
+ IFNT(reg.ReadValue( "TestSubkey1", "TestKey2", &buffer), res);
+ IFT( reg.DeleteValue("TestSubkey", "TestKey3"), res);
+ IFNT(reg.ReadValue( "TestSubkey", "TestKey3", &buffer), res);
+ IFT( reg.DeleteValue("TestSubkey2", "TestKey4"), res);
+ IFNT(reg.ReadValue( "TestSubkey2", "TestKey5", &buffer), res);
+
+ const char* longStringWithNewLines = "Value with embedded CR and LF characters CR='\015' LF='\012' CRLF='\015\012'";
+ IFT(reg.SetValue("TestSubkeyWithVeryLongInFactSoLongItsHardToImagineAnybodyWouldReallyDoItLongName", "TestKey1", longStringWithNewLines), res);
+ IFT(reg.ReadValue("TestSubkeyWithVeryLongInFactSoLongItsHardToImagineAnybodyWouldReallyDoItLongName", "TestKey1", &buffer), res);
+ CHE(buffer, longStringWithNewLines, res);
+ IFT(reg.DeleteValue("TestSubkeyWithVeryLongInFactSoLongItsHardToImagineAnybodyWouldReallyDoItLongName", "TestKey1"), res);
+ IFNT(reg.ReadValue("TestSubkeyWithVeryLongInFactSoLongItsHardToImagineAnybodyWouldReallyDoItLongName", "TestKey1", &buffer), res);
+
+ IFT(reg.SetValue("TestSubkeyWith = EqualSignChar", "TestKey = 1", "Some value"), res);
+ IFT(reg.ReadValue("TestSubkeyWith = EqualSignChar", "TestKey = 1", &buffer), res);
+ CHE(buffer, "Some value", res);
+ IFT(reg.DeleteValue("TestSubkeyWith = EqualSignChar", "TestKey = 1"), res);
+ IFNT(reg.ReadValue("TestSubkeyWith = EqualSignChar", "TestKey = 1", &buffer), res);
+
+ if ( res )
+ {
+ kwsys_ios::cout << "Test failed" << kwsys_ios::endl;
+ }
+ else
+ {
+ kwsys_ios::cout << "Test passed" << kwsys_ios::endl;
+ }
+ return res;
+}
diff --git a/Source/kwsys/testSharedForward.c.in b/Source/kwsys/testSharedForward.c.in
new file mode 100644
index 000000000..ee753efa3
--- /dev/null
+++ b/Source/kwsys/testSharedForward.c.in
@@ -0,0 +1,36 @@
+/*============================================================================
+ 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.
+============================================================================*/
+#if defined(CMAKE_INTDIR)
+# define CONFIG_DIR_PRE CMAKE_INTDIR "/"
+# define CONFIG_DIR_POST "/" CMAKE_INTDIR
+#else
+# define CONFIG_DIR_PRE ""
+# define CONFIG_DIR_POST ""
+#endif
+#define @KWSYS_NAMESPACE@_SHARED_FORWARD_DIR_BUILD "@EXEC_DIR@"
+#define @KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_BUILD "." CONFIG_DIR_POST
+#define @KWSYS_NAMESPACE@_SHARED_FORWARD_PATH_INSTALL 0
+#define @KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_BUILD \
+ CONFIG_DIR_PRE "@KWSYS_NAMESPACE@TestProcess"
+#define @KWSYS_NAMESPACE@_SHARED_FORWARD_EXE_INSTALL \
+ "@KWSYS_NAMESPACE@TestProcess"
+#define @KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_COMMAND "--command"
+#define @KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_PRINT "--print"
+#define @KWSYS_NAMESPACE@_SHARED_FORWARD_OPTION_LDD "--ldd"
+#if defined(CMAKE_INTDIR)
+# define @KWSYS_NAMESPACE@_SHARED_FORWARD_CONFIG_NAME CMAKE_INTDIR
+#endif
+#include <@KWSYS_NAMESPACE@/SharedForward.h>
+int main(int argc, char** argv)
+{
+ return @KWSYS_NAMESPACE@_shared_forward_to_real(argc, argv);
+}
diff --git a/Source/kwsys/testSystemInformation.cxx b/Source/kwsys/testSystemInformation.cxx
new file mode 100644
index 000000000..b3afc9de9
--- /dev/null
+++ b/Source/kwsys/testSystemInformation.cxx
@@ -0,0 +1,65 @@
+/*============================================================================
+ 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(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
+
+#define printMethod(inof, m) kwsys_ios::cout << #m << ": " \
+<< info.m() << "\n"
+
+#define printMethod2(inof, m, unit) kwsys_ios::cout << #m << ": " \
+<< info.m() << " " << unit << "\n"
+
+int testSystemInformation(int, char*[])
+{
+ kwsys::SystemInformation info;
+ info.RunCPUCheck();
+ info.RunOSCheck();
+ info.RunMemoryCheck();
+ printMethod(info, GetOSName);
+ printMethod(info, GetHostname);
+ printMethod(info, GetOSRelease);
+ printMethod(info, GetOSVersion);
+ printMethod(info, GetOSPlatform);
+ printMethod(info, GetVendorString);
+ printMethod(info, GetVendorID);
+ printMethod(info, GetTypeID);
+ printMethod(info, GetFamilyID);
+ printMethod(info, GetModelID);
+ printMethod(info, GetExtendedProcessorName);
+ printMethod(info, GetProcessorSerialNumber);
+ printMethod2(info, GetProcessorCacheSize, "KB");
+ printMethod(info, GetLogicalProcessorsPerPhysical);
+ printMethod2(info, GetProcessorClockFrequency, "MHz");
+ printMethod(info, Is64Bits);
+ printMethod(info, GetNumberOfLogicalCPU);
+ printMethod(info, GetNumberOfPhysicalCPU);
+ printMethod(info, DoesCPUSupportCPUID);
+ printMethod(info, GetProcessorAPICID);
+ printMethod2(info, GetTotalVirtualMemory, "MB");
+ printMethod2(info, GetAvailableVirtualMemory, "MB");
+ printMethod2(info, GetTotalPhysicalMemory, "MB");
+ printMethod2(info, GetAvailablePhysicalMemory, "MB");
+
+ //int GetProcessorCacheXSize(long int);
+// bool DoesCPUSupportFeature(long int);
+ return 0;
+}
diff --git a/Source/kwsys/testSystemTools.bin b/Source/kwsys/testSystemTools.bin
new file mode 100644
index 000000000..961a4043b
--- /dev/null
+++ b/Source/kwsys/testSystemTools.bin
Binary files differ
diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx
new file mode 100644
index 000000000..3ac0cb399
--- /dev/null
+++ b/Source/kwsys/testSystemTools.cxx
@@ -0,0 +1,414 @@
+/*============================================================================
+ 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(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 <string.h> /* strcmp */
+
+//----------------------------------------------------------------------------
+const char* toUnixPaths[][2] =
+{
+ { "/usr/local/bin/passwd", "/usr/local/bin/passwd" },
+ { "/usr/lo cal/bin/pa sswd", "/usr/lo cal/bin/pa sswd" },
+ { "/usr/lo\\ cal/bin/pa\\ sswd", "/usr/lo\\ cal/bin/pa\\ sswd" },
+ { "c:/usr/local/bin/passwd", "c:/usr/local/bin/passwd" },
+ { "c:/usr/lo cal/bin/pa sswd", "c:/usr/lo cal/bin/pa sswd" },
+ { "c:/usr/lo\\ cal/bin/pa\\ sswd", "c:/usr/lo\\ cal/bin/pa\\ sswd" },
+ { "\\usr\\local\\bin\\passwd", "/usr/local/bin/passwd" },
+ { "\\usr\\lo cal\\bin\\pa sswd", "/usr/lo cal/bin/pa sswd" },
+ { "\\usr\\lo\\ cal\\bin\\pa\\ sswd", "/usr/lo\\ cal/bin/pa\\ sswd" },
+ { "c:\\usr\\local\\bin\\passwd", "c:/usr/local/bin/passwd" },
+ { "c:\\usr\\lo cal\\bin\\pa sswd", "c:/usr/lo cal/bin/pa sswd" },
+ { "c:\\usr\\lo\\ cal\\bin\\pa\\ sswd", "c:/usr/lo\\ cal/bin/pa\\ sswd" },
+ { "\\\\usr\\local\\bin\\passwd", "//usr/local/bin/passwd" },
+ { "\\\\usr\\lo cal\\bin\\pa sswd", "//usr/lo cal/bin/pa sswd" },
+ { "\\\\usr\\lo\\ cal\\bin\\pa\\ sswd", "//usr/lo\\ cal/bin/pa\\ sswd" },
+ {0, 0}
+};
+
+bool CheckConvertToUnixSlashes(kwsys_stl::string input,
+ kwsys_stl::string output)
+{
+ kwsys_stl::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;
+ return false;
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+const char* checkEscapeChars[][4] =
+{
+ { "1 foo 2 bar 2", "12", "\\", "\\1 foo \\2 bar \\2"},
+ { " {} ", "{}", "#", " #{#} "},
+ {0, 0, 0, 0}
+};
+
+bool CheckEscapeChars(kwsys_stl::string input,
+ const char *chars_to_escape,
+ char escape_char,
+ kwsys_stl::string output)
+{
+ kwsys_stl::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;
+ return false;
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool CheckFileOperations()
+{
+ bool res = true;
+
+ if (kwsys::SystemTools::DetectFileType(TEST_SYSTEMTOOLS_BIN_FILE) !=
+ kwsys::SystemTools::FileTypeBinary)
+ {
+ kwsys_ios::cerr
+ << "Problem with DetectFileType - failed to detect type of: "
+ << TEST_SYSTEMTOOLS_BIN_FILE << kwsys_ios::endl;
+ res = false;
+ }
+
+ if (kwsys::SystemTools::DetectFileType(TEST_SYSTEMTOOLS_SRC_FILE) !=
+ kwsys::SystemTools::FileTypeText)
+ {
+ kwsys_ios::cerr
+ << "Problem with DetectFileType - failed to detect type of: "
+ << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+ res = false;
+ }
+
+ if (kwsys::SystemTools::FileLength(TEST_SYSTEMTOOLS_BIN_FILE) != 766)
+ {
+ kwsys_ios::cerr
+ << "Problem with FileLength - incorrect length for: "
+ << TEST_SYSTEMTOOLS_BIN_FILE << kwsys_ios::endl;
+ res = false;
+ }
+
+ return res;
+}
+
+//----------------------------------------------------------------------------
+bool CheckStringOperations()
+{
+ bool res = true;
+
+ kwsys_stl::string test = "mary had a little lamb.";
+ if (kwsys::SystemTools::CapitalizedWords(test) != "Mary Had A Little Lamb.")
+ {
+ kwsys_ios::cerr
+ << "Problem with CapitalizedWords "
+ << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+ res = false;
+ }
+
+ test = "Mary Had A Little Lamb.";
+ if (kwsys::SystemTools::UnCapitalizedWords(test) !=
+ "mary had a little lamb.")
+ {
+ kwsys_ios::cerr
+ << "Problem with UnCapitalizedWords "
+ << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+ res = false;
+ }
+
+ test = "MaryHadTheLittleLamb.";
+ if (kwsys::SystemTools::AddSpaceBetweenCapitalizedWords(test) !=
+ "Mary Had The Little Lamb.")
+ {
+ kwsys_ios::cerr
+ << "Problem with AddSpaceBetweenCapitalizedWords "
+ << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+ res = false;
+ }
+
+ char * cres =
+ kwsys::SystemTools::AppendStrings("Mary Had A"," Little Lamb.");
+ if (strcmp(cres,"Mary Had A Little Lamb."))
+ {
+ kwsys_ios::cerr
+ << "Problem with AppendStrings "
+ << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+ res = false;
+ }
+ delete [] cres;
+
+ cres =
+ kwsys::SystemTools::AppendStrings("Mary Had"," A ","Little Lamb.");
+ if (strcmp(cres,"Mary Had A Little Lamb."))
+ {
+ kwsys_ios::cerr
+ << "Problem with AppendStrings "
+ << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+ res = false;
+ }
+ delete [] cres;
+
+ if (kwsys::SystemTools::CountChar("Mary Had A Little Lamb.",'a') != 3)
+ {
+ kwsys_ios::cerr
+ << "Problem with CountChar "
+ << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+ res = false;
+ }
+
+ cres =
+ kwsys::SystemTools::RemoveChars("Mary Had A Little Lamb.","aeiou");
+ if (strcmp(cres,"Mry Hd A Lttl Lmb."))
+ {
+ kwsys_ios::cerr
+ << "Problem with RemoveChars "
+ << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+ res = false;
+ }
+ delete [] cres;
+
+ cres =
+ kwsys::SystemTools::RemoveCharsButUpperHex("Mary Had A Little Lamb.");
+ if (strcmp(cres,"A"))
+ {
+ kwsys_ios::cerr
+ << "Problem with RemoveCharsButUpperHex "
+ << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+ res = false;
+ }
+ delete [] cres;
+
+ char *cres2 = new char [strlen("Mary Had A Little Lamb.")+1];
+ strcpy(cres2,"Mary Had A Little Lamb.");
+ kwsys::SystemTools::ReplaceChars(cres2,"aeiou",'X');
+ if (strcmp(cres2,"MXry HXd A LXttlX LXmb."))
+ {
+ kwsys_ios::cerr
+ << "Problem with ReplaceChars "
+ << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+ res = false;
+ }
+ delete [] cres2;
+
+ if (!kwsys::SystemTools::StringStartsWith("Mary Had A Little Lamb.",
+ "Mary "))
+ {
+ kwsys_ios::cerr
+ << "Problem with StringStartsWith "
+ << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+ res = false;
+ }
+
+ if (!kwsys::SystemTools::StringEndsWith("Mary Had A Little Lamb.",
+ " Lamb."))
+ {
+ kwsys_ios::cerr
+ << "Problem with StringEndsWith "
+ << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+ res = false;
+ }
+
+ cres = kwsys::SystemTools::DuplicateString("Mary Had A Little Lamb.");
+ if (strcmp(cres,"Mary Had A Little Lamb."))
+ {
+ kwsys_ios::cerr
+ << "Problem with DuplicateString "
+ << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+ res = false;
+ }
+ delete [] cres;
+
+ test = "Mary Had A Little Lamb.";
+ if (kwsys::SystemTools::CropString(test,13) !=
+ "Mary ...Lamb.")
+ {
+ kwsys_ios::cerr
+ << "Problem with CropString "
+ << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+ res = false;
+ }
+
+ kwsys_stl::vector<kwsys_stl::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
+ << "Problem with Split "
+ << TEST_SYSTEMTOOLS_SRC_FILE << kwsys_ios::endl;
+ res = false;
+ }
+
+ if (kwsys::SystemTools::ConvertToWindowsOutputPath
+ ("L://Local Mojo/Hex Power Pack/Iffy Voodoo") !=
+ "\"L:\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\"")
+ {
+ kwsys_ios::cerr
+ << "Problem with ConvertToWindowsOutputPath "
+ << kwsys_ios::endl;
+ res = false;
+ }
+
+ if (kwsys::SystemTools::ConvertToWindowsOutputPath
+ ("//grayson/Local Mojo/Hex Power Pack/Iffy Voodoo") !=
+ "\"\\\\grayson\\Local Mojo\\Hex Power Pack\\Iffy Voodoo\"")
+ {
+ kwsys_ios::cerr
+ << "Problem with ConvertToWindowsOutputPath "
+ << kwsys_ios::endl;
+ res = false;
+ }
+
+ if (kwsys::SystemTools::ConvertToUnixOutputPath
+ ("//Local Mojo/Hex Power Pack/Iffy Voodoo") !=
+ "//Local\\ Mojo/Hex\\ Power\\ Pack/Iffy\\ Voodoo")
+ {
+ kwsys_ios::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];
+ }
+ delete [] targv;
+
+ return res;
+}
+
+//----------------------------------------------------------------------------
+
+bool CheckPutEnv(const char* env, const char* name, const char* value)
+{
+ if(!kwsys::SystemTools::PutEnv(env))
+ {
+ kwsys_ios::cerr << "PutEnv(\"" << env
+ << "\") failed!" << kwsys_ios::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;
+ return false;
+ }
+ return true;
+}
+
+bool CheckUnPutEnv(const char* env, const char* name)
+{
+ if(!kwsys::SystemTools::UnPutEnv(env))
+ {
+ kwsys_ios::cerr << "UnPutEnv(\"" << env << "\") failed!"
+ << kwsys_ios::endl;
+ return false;
+ }
+ if(const char* v = kwsys::SystemTools::GetEnv(name))
+ {
+ kwsys_ios::cerr << "GetEnv(\"" << name << "\") returned \""
+ << v << "\", not (null)!" << kwsys_ios::endl;
+ return false;
+ }
+ return true;
+}
+
+bool CheckEnvironmentOperations()
+{
+ bool res = true;
+ res &= CheckPutEnv("A=B", "A", "B");
+ res &= CheckPutEnv("B=C", "B", "C");
+ res &= CheckPutEnv("C=D", "C", "D");
+ res &= CheckPutEnv("D=E", "D", "E");
+ res &= CheckUnPutEnv("A", "A");
+ res &= CheckUnPutEnv("B=", "B");
+ res &= CheckUnPutEnv("C=D", "C");
+ /* Leave "D=E" in environment so a memory checker can test for leaks. */
+ return res;
+}
+
+//----------------------------------------------------------------------------
+int testSystemTools(int, char*[])
+{
+ bool res = true;
+
+ int cc;
+ for ( cc = 0; toUnixPaths[cc][0]; cc ++ )
+ {
+ res &= CheckConvertToUnixSlashes(toUnixPaths[cc][0], toUnixPaths[cc][1]);
+ }
+
+ // Special check for ~
+ kwsys_stl::string output;
+ if(kwsys::SystemTools::GetEnv("HOME", output))
+ {
+ output += "/foo bar/lala";
+ res &= CheckConvertToUnixSlashes("~/foo bar/lala", output);
+ }
+
+ for (cc = 0; checkEscapeChars[cc][0]; cc ++ )
+ {
+ res &= CheckEscapeChars(checkEscapeChars[cc][0], checkEscapeChars[cc][1],
+ *checkEscapeChars[cc][2], checkEscapeChars[cc][3]);
+ }
+
+ res &= CheckFileOperations();
+
+ res &= CheckStringOperations();
+
+ res &= CheckEnvironmentOperations();
+
+ return res ? 0 : 1;
+}
diff --git a/Source/kwsys/testSystemTools.h.in b/Source/kwsys/testSystemTools.h.in
new file mode 100644
index 000000000..4b94bb6af
--- /dev/null
+++ b/Source/kwsys/testSystemTools.h.in
@@ -0,0 +1,20 @@
+/*============================================================================
+ 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@_testSystemtools_h
+#define @KWSYS_NAMESPACE@_testSystemtools_h
+
+#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@"
+
+#endif
diff --git a/Source/kwsys/testTerminal.c b/Source/kwsys/testTerminal.c
new file mode 100644
index 000000000..0d2d7a77b
--- /dev/null
+++ b/Source/kwsys/testTerminal.c
@@ -0,0 +1,31 @@
+/*============================================================================
+ 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(Terminal.h)
+
+/* Work-around CMake dependency scanning limitation. This must
+ duplicate the above list of headers. */
+#if 0
+# include "Terminal.h.in"
+#endif
+
+int testTerminal(int argc, char* argv[])
+{
+ (void)argc;
+ (void)argv;
+ kwsysTerminal_cfprintf(kwsysTerminal_Color_ForegroundYellow |
+ kwsysTerminal_Color_BackgroundBlue |
+ kwsysTerminal_Color_AssumeTTY,
+ stdout, "Hello %s!", "World");
+ fprintf(stdout, "\n");
+ return 0;
+}
diff --git a/Templates/AppleInfo.plist b/Templates/AppleInfo.plist
new file mode 100644
index 000000000..1f68ccf92
--- /dev/null
+++ b/Templates/AppleInfo.plist
@@ -0,0 +1,36 @@
+<?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>${APPLE_GUI_EXECUTABLE}</string>
+ <key>CFBundleGetInfoString</key>
+ <string>${APPLE_GUI_INFO_STRING}</string>
+ <key>CFBundleIconFile</key>
+ <string>${APPLE_GUI_ICON}</string>
+ <key>CFBundleIdentifier</key>
+ <string>${APPLE_GUI_IDENTIFIER}</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleLongVersionString</key>
+ <string>${APPLE_GUI_LONG_VERSION_STRING}</string>
+ <key>CFBundleName</key>
+ <string>${APPLE_GUI_BUNDLE_NAME}</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>${APPLE_GUI_SHORT_VERSION_STRING}</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>${APPLE_GUI_BUNDLE_VERSION}</string>
+ <key>CSResourcesFileMapped</key>
+ <true/>
+ <key>LSRequiresCarbon</key>
+ <true/>
+ <key>NSHumanReadableCopyright</key>
+ <string>${APPLE_GUI_COPYRIGHT}</string>
+</dict>
+</plist>
diff --git a/Templates/CMakeVSMacros1.vsmacros b/Templates/CMakeVSMacros1.vsmacros
new file mode 100644
index 000000000..60487d91c
--- /dev/null
+++ b/Templates/CMakeVSMacros1.vsmacros
Binary files differ
diff --git a/Templates/CMakeVSMacros2.vsmacros b/Templates/CMakeVSMacros2.vsmacros
new file mode 100644
index 000000000..5ba27991a
--- /dev/null
+++ b/Templates/CMakeVSMacros2.vsmacros
Binary files differ
diff --git a/Templates/CMakeVisualStudio6Configurations.cmake b/Templates/CMakeVisualStudio6Configurations.cmake
new file mode 100644
index 000000000..a9db2eeba
--- /dev/null
+++ b/Templates/CMakeVisualStudio6Configurations.cmake
@@ -0,0 +1,3 @@
+# When the dll templates are changed, this list should be
+# updated with the list of possible configurations.
+SET(CMAKE_CONFIGURATION_TYPES Debug Release MinSizeRel RelWithDebInfo)
diff --git a/Templates/CPack.GenericDescription.txt b/Templates/CPack.GenericDescription.txt
new file mode 100644
index 000000000..9ca1802ad
--- /dev/null
+++ b/Templates/CPack.GenericDescription.txt
@@ -0,0 +1,5 @@
+DESCRIPTION
+===========
+
+This is an installer created using CPack (http://www.cmake.org). No additional installation instructions provided.
+
diff --git a/Templates/CPack.GenericLicense.txt b/Templates/CPack.GenericLicense.txt
new file mode 100644
index 000000000..c211bb370
--- /dev/null
+++ b/Templates/CPack.GenericLicense.txt
@@ -0,0 +1,5 @@
+LICENSE
+=======
+
+This is an installer created using CPack (http://www.cmake.org). No license provided.
+
diff --git a/Templates/CPack.GenericWelcome.txt b/Templates/CPack.GenericWelcome.txt
new file mode 100644
index 000000000..5330087b1
--- /dev/null
+++ b/Templates/CPack.GenericWelcome.txt
@@ -0,0 +1 @@
+Welcome to installation. This program will guide you through the installation of this software.
diff --git a/Templates/CPackConfig.cmake.in b/Templates/CPackConfig.cmake.in
new file mode 100644
index 000000000..79b8d93ae
--- /dev/null
+++ b/Templates/CPackConfig.cmake.in
@@ -0,0 +1,12 @@
+# This file will be configured to contain variables for CPack. These variables
+# should be set in the CMake list file of the project before CPack module is
+# included. The list of available CPACK_xxx variables and their associated
+# documentation may be obtained using
+# cpack --help-variable-list
+#
+# Some variables are common to all generators (e.g. CPACK_PACKAGE_NAME)
+# and some are specific to a generator
+# (e.g. CPACK_NSIS_EXTRA_INSTALL_COMMANDS). The generator specific variables
+# usually begin with CPACK_<GENNAME>_xxxx.
+
+@_CPACK_OTHER_VARIABLES_@
diff --git a/Templates/CTestScript.cmake.in b/Templates/CTestScript.cmake.in
new file mode 100644
index 000000000..63bd26f47
--- /dev/null
+++ b/Templates/CTestScript.cmake.in
@@ -0,0 +1,33 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.4)
+
+# This is a template for the CTest script for this system
+
+SET(CTEST_SITE "@SITE@")
+SET(CTEST_BUILD_NAME "@BUILDNAME@")
+
+# ---
+SET(CTEST_SOURCE_DIRECTORY "@CMAKE_SOURCE_DIR@")
+SET(CTEST_BINARY_DIRECTORY "@CMAKE_BINARY_DIR@")
+SET(CTEST_UPDATE_COMMAND "@UPDATE_COMMAND@")
+SET(CTEST_UPDATE_OPTIONS "@UPDATE_OPTIONS@")
+SET(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@")
+SET(CTEST_BUILD_CONFIGURATION "Release")
+#SET(CTEST_MEMORYCHECK_COMMAND "@MEMORYCHECK_COMMAND@")
+#SET(CTEST_MEMORYCHECK_SUPPRESSIONS_FILE "@MEMORYCHECK_SUPPRESSIONS_FILE@")
+#SET(CTEST_MEMORYCHECK_COMMAND_OPTIONS "@MEMORYCHECK_COMMAND_OPTIONS@")
+#SET(CTEST_COVERAGE_COMMAND "@COVERAGE_COMMAND@")
+SET(CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
+
+#CTEST_EMPTY_BINARY_DIRECTORY(${CTEST_BINARY_DIRECTORY})
+
+SET(CTEST_DROP_METHOD "@DROP_METHOD@")
+
+CTEST_START(Experimental TRACK Weekly)
+CTEST_UPDATE(SOURCE "${CTEST_SOURCE_DIRECTORY}")
+CTEST_CONFIGURE(BUILD "${CTEST_BINARY_DIRECTORY}")
+CTEST_READ_CUSTOM_FILES("${CTEST_BINARY_DIRECTORY}")
+CTEST_BUILD(BUILD "${CTEST_BINARY_DIRECTORY}")
+CTEST_TEST(BUILD "${CTEST_BINARY_DIRECTORY}")
+#CTEST_MEMCHECK(BUILD "${CTEST_BINARY_DIRECTORY}")
+#CTEST_COVERAGE(BUILD "${CTEST_BINARY_DIRECTORY}")
+CTEST_SUBMIT()
diff --git a/Templates/DLLFooter.dsptemplate b/Templates/DLLFooter.dsptemplate
new file mode 100644
index 000000000..0d0682a7b
--- /dev/null
+++ b/Templates/DLLFooter.dsptemplate
@@ -0,0 +1,4 @@
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/Templates/DLLHeader.dsptemplate b/Templates/DLLHeader.dsptemplate
new file mode 100644
index 000000000..c752fdbf4
--- /dev/null
+++ b/Templates/DLLHeader.dsptemplate
@@ -0,0 +1,192 @@
+# Microsoft Developer Studio Project File - Name="OUTPUT_LIBNAME" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=OUTPUT_LIBNAME - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "OUTPUT_LIBNAME.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "OUTPUT_LIBNAME.mak" CFG="OUTPUT_LIBNAME - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "OUTPUT_LIBNAME - Win32 MinSizeRel" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "OUTPUT_LIBNAME - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "OUTPUT_LIBNAME - Win32 RelWithDebInfo" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "OUTPUT_LIBNAME - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# ITK DSP Header file
+# This file is read by the build system of itk, and is used as the top part of
+# a microsoft project dsp header file
+# IF this is in a dsp file, then it is not the header, but has
+# already been used, so do not edit here...
+
+# variables to REPLACE
+#
+# BUILD_INCLUDES == include path
+# EXTRA_DEFINES == compiler defines
+# OUTPUT_DIRECTORY == override in output directory
+# OUTPUT_LIBNAME == name of output library
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "OUTPUT_LIBNAME - Win32 Release"
+
+# PROP BASE Use_MFC CMAKE_MFC_FLAG
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC CMAKE_MFC_FLAG
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "OUTPUT_DIRECTORY_RELEASE"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /D "WIN32" /D "_WINDOWS" /D "_USRDLL" OUTPUT_LIBNAME_EXPORTS /FD /c
+# ADD CPP /nologo /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /FD /c
+# ADD CPP BUILD_INCLUDES EXTRA_DEFINES OUTPUT_LIBNAME_EXPORTS
+# ADD CPP CMAKE_CXX_FLAGS
+# ADD CPP CMAKE_CXX_FLAGS_RELEASE
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC BUILD_INCLUDES /l 0x409 /d "NDEBUG"
+# ADD RSC COMPILE_DEFINITIONS
+# ADD RSC COMPILE_DEFINITIONS_RELEASE
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 /nologo /dll /machine:I386
+# ADD LINK32 /nologo /dll TARGET_VERSION_FLAG /machine:I386 /out:"OUTPUT_DIRECTORY_RELEASE/OUTPUT_NAME_RELEASE" TARGET_IMPLIB_FLAG_RELEASE
+CM_MULTILINE_OPTIONS_RELEASE
+
+CMAKE_CUSTOM_RULE_CODE_RELEASE
+
+!ELSEIF "$(CFG)" == "OUTPUT_LIBNAME - Win32 Debug"
+
+# PROP BASE Use_MFC CMAKE_MFC_FLAG
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC CMAKE_MFC_FLAG
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "OUTPUT_DIRECTORY_DEBUG"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" OUTPUT_LIBNAME_EXPORTS /FD /c
+# ADD CPP /nologo /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_USRDLL" /FD /c
+# ADD CPP BUILD_INCLUDES EXTRA_DEFINES OUTPUT_LIBNAME_EXPORTS
+# ADD CPP CMAKE_CXX_FLAGS
+# ADD CPP CMAKE_CXX_FLAGS_DEBUG
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC BUILD_INCLUDES /l 0x409 /d "_DEBUG"
+# ADD RSC COMPILE_DEFINITIONS
+# ADD RSC COMPILE_DEFINITIONS_DEBUG
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 /nologo /dll TARGET_VERSION_FLAG /debug /machine:I386 /out:"OUTPUT_DIRECTORY_DEBUG/OUTPUT_NAME_DEBUG" /pdbtype:sept TARGET_IMPLIB_FLAG_DEBUG
+CM_MULTILINE_OPTIONS_DEBUG
+
+CMAKE_CUSTOM_RULE_CODE_DEBUG
+
+!ELSEIF "$(CFG)" == "OUTPUT_LIBNAME - Win32 MinSizeRel"
+
+# PROP BASE Use_MFC CMAKE_MFC_FLAG
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "MinSizeRel"
+# PROP BASE Intermediate_Dir "MinSizeRel"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC CMAKE_MFC_FLAG
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "OUTPUT_DIRECTORY_MINSIZEREL"
+# PROP Intermediate_Dir "MinSizeRel"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /FD /c OUTPUT_LIBNAME_EXPORTS
+# SUBTRACT BASE CPP /YX
+# ADD CPP /nologo /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /FD /c
+# ADD CPP BUILD_INCLUDES EXTRA_DEFINES OUTPUT_LIBNAME_EXPORTS
+# ADD CPP CMAKE_CXX_FLAGS
+# ADD CPP CMAKE_CXX_FLAGS_MINSIZEREL
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC BUILD_INCLUDES /l 0x409 /d "NDEBUG"
+# ADD RSC COMPILE_DEFINITIONS
+# ADD RSC COMPILE_DEFINITIONS_MINSIZEREL
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 /nologo /dll /machine:I386
+# ADD LINK32 /nologo /dll TARGET_VERSION_FLAG /machine:I386 /out:"OUTPUT_DIRECTORY_MINSIZEREL/OUTPUT_NAME_MINSIZEREL" TARGET_IMPLIB_FLAG_MINSIZEREL
+CM_MULTILINE_OPTIONS_MINSIZEREL
+
+CMAKE_CUSTOM_RULE_CODE_MINSIZEREL
+
+!ELSEIF "$(CFG)" == "OUTPUT_LIBNAME - Win32 RelWithDebInfo"
+
+# PROP BASE Use_MFC CMAKE_MFC_FLAG
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "RelWithDebInfo"
+# PROP BASE Intermediate_Dir "RelWithDebInfo"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC CMAKE_MFC_FLAG
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "OUTPUT_DIRECTORY_RELWITHDEBINFO"
+# PROP Intermediate_Dir "RelWithDebInfo"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /D "WIN32" /D "_WINDOWS" /D "_USRDLL" OUTPUT_LIBNAME_EXPORTS /FD /c
+# ADD CPP /nologo /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /FD /c
+# ADD CPP BUILD_INCLUDES EXTRA_DEFINES OUTPUT_LIBNAME_EXPORTS
+# ADD CPP CMAKE_CXX_FLAGS
+# ADD CPP CMAKE_CXX_FLAGS_RELWITHDEBINFO
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC BUILD_INCLUDES /l 0x409 /d "NDEBUG"
+# ADD RSC COMPILE_DEFINITIONS
+# ADD RSC COMPILE_DEFINITIONS_RELWITHDEBINFO
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 /nologo /dll /machine:I386 /pdbtype:sept
+# ADD LINK32 /nologo /dll TARGET_VERSION_FLAG /debug /machine:I386 /pdbtype:sept /out:"OUTPUT_DIRECTORY_RELWITHDEBINFO/OUTPUT_NAME_RELWITHDEBINFO" TARGET_IMPLIB_FLAG_RELWITHDEBINFO
+CM_MULTILINE_OPTIONS_RELWITHDEBINFO
+
+CMAKE_CUSTOM_RULE_CODE_RELWITHDEBINFO
+
+!ENDIF
+
+# Begin Target
+
+# Name "OUTPUT_LIBNAME - Win32 Release"
+# Name "OUTPUT_LIBNAME - Win32 Debug"
+# Name "OUTPUT_LIBNAME - Win32 MinSizeRel"
+# Name "OUTPUT_LIBNAME - Win32 RelWithDebInfo"
diff --git a/Templates/EXEFooter.dsptemplate b/Templates/EXEFooter.dsptemplate
new file mode 100644
index 000000000..0d0682a7b
--- /dev/null
+++ b/Templates/EXEFooter.dsptemplate
@@ -0,0 +1,4 @@
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/Templates/EXEHeader.dsptemplate b/Templates/EXEHeader.dsptemplate
new file mode 100644
index 000000000..f48eaccbc
--- /dev/null
+++ b/Templates/EXEHeader.dsptemplate
@@ -0,0 +1,183 @@
+# Microsoft Developer Studio Project File - Name="pcbuilder" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# CM DSP Header file
+# This file is read by the build system of cm, and is used as the top part of
+# a microsoft project dsp header file
+# IF this is in a dsp file, then it is not the header, but has
+# already been used, so do not edit here...
+
+# variables to REPLACE
+#
+# BUILD_INCLUDES == include path
+# OUTPUT_DIRECTORY == override in output directory
+# EXTRA_DEFINES == compiler defines
+# OUTPUT_LIBNAME == name of output library
+# CM_LIBRARIES == libraries linked in
+# TARGTYPE "Win32 (x86) Application" 0x0103
+
+CFG=OUTPUT_LIBNAME - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "OUTPUT_LIBNAME.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "OUTPUT_LIBNAME.mak" CFG="OUTPUT_LIBNAME - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "OUTPUT_LIBNAME - Win32 MinSizeRel" (based on "Win32 (x86) Application")
+!MESSAGE "OUTPUT_LIBNAME - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "OUTPUT_LIBNAME - Win32 RelWithDebInfo" (based on "Win32 (x86) Application")
+!MESSAGE "OUTPUT_LIBNAME - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "OUTPUT_LIBNAME - Win32 Release"
+
+# PROP BASE Use_MFC CMAKE_MFC_FLAG
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC CMAKE_MFC_FLAG
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "OUTPUT_DIRECTORY_RELEASE"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /FD /c
+# ADD CPP /nologo /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /FD /c
+# ADD CPP BUILD_INCLUDES EXTRA_DEFINES OUTPUT_LIBNAME_EXPORTS
+# ADD CPP CMAKE_CXX_FLAGS
+# ADD CPP CMAKE_CXX_FLAGS_RELEASE
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC BUILD_INCLUDES /l 0x409 /d "NDEBUG"
+# ADD RSC COMPILE_DEFINITIONS
+# ADD RSC COMPILE_DEFINITIONS_RELEASE
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 /nologo /subsystem:console /machine:I386 /IGNORE:4089
+# ADD LINK32 /nologo /subsystem:console /machine:I386 /IGNORE:4089 TARGET_VERSION_FLAG
+# ADD LINK32 /out:"OUTPUT_DIRECTORY_RELEASE\OUTPUT_NAME_RELEASE" TARGET_IMPLIB_FLAG_RELEASE
+CM_MULTILINE_OPTIONS_RELEASE
+
+CMAKE_CUSTOM_RULE_CODE_RELEASE
+
+!ELSEIF "$(CFG)" == "OUTPUT_LIBNAME - Win32 Debug"
+
+# PROP BASE Use_MFC CMAKE_MFC_FLAG
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC CMAKE_MFC_FLAG
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "OUTPUT_DIRECTORY_DEBUG"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /FD /GZ /c
+# ADD CPP /nologo /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /FD /GZ /c
+# ADD CPP BUILD_INCLUDES EXTRA_DEFINES OUTPUT_LIBNAME_EXPORTS
+# ADD CPP CMAKE_CXX_FLAGS
+# ADD CPP CMAKE_CXX_FLAGS_DEBUG
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC BUILD_INCLUDES /l 0x409 /d "_DEBUG"
+# ADD RSC COMPILE_DEFINITIONS
+# ADD RSC COMPILE_DEFINITIONS_DEBUG
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /IGNORE:4089
+# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /IGNORE:4089 TARGET_VERSION_FLAG
+# ADD LINK32 /out:"OUTPUT_DIRECTORY_DEBUG\OUTPUT_NAME_DEBUG" TARGET_IMPLIB_FLAG_DEBUG
+CM_MULTILINE_OPTIONS_DEBUG
+
+CMAKE_CUSTOM_RULE_CODE_DEBUG
+
+!ELSEIF "$(CFG)" == "OUTPUT_LIBNAME - Win32 MinSizeRel"
+# PROP BASE Use_MFC CMAKE_MFC_FLAG
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "MinSizeRel"
+# PROP BASE Intermediate_Dir "MinSizeRel"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC CMAKE_MFC_FLAG
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "OUTPUT_DIRECTORY_MINSIZEREL"
+# PROP Intermediate_Dir "MinSizeRel"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /FD /c
+# ADD CPP /nologo /D "WIN32" BUILD_INCLUDES EXTRA_DEFINES /D "NDEBUG" /D "_CONSOLE" /FD /c
+# ADD CPP BUILD_INCLUDES EXTRA_DEFINES OUTPUT_LIBNAME_EXPORTS
+# ADD CPP CMAKE_CXX_FLAGS
+# ADD CPP CMAKE_CXX_FLAGS_MINSIZEREL
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC BUILD_INCLUDES /l 0x409 /d "NDEBUG"
+# ADD RSC COMPILE_DEFINITIONS
+# ADD RSC COMPILE_DEFINITIONS_MINSIZEREL
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 /nologo /subsystem:console /machine:I386 /IGNORE:4089
+# ADD LINK32 /nologo /subsystem:console /machine:I386 /IGNORE:4089 TARGET_VERSION_FLAG
+# ADD LINK32 /out:"OUTPUT_DIRECTORY_MINSIZEREL\OUTPUT_NAME_MINSIZEREL" TARGET_IMPLIB_FLAG_MINSIZEREL
+CM_MULTILINE_OPTIONS_MINSIZEREL
+
+CMAKE_CUSTOM_RULE_CODE_MINSIZEREL
+
+!ELSEIF "$(CFG)" == "OUTPUT_LIBNAME - Win32 RelWithDebInfo"
+
+# PROP BASE Use_MFC CMAKE_MFC_FLAG
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "RelWithDebInfo"
+# PROP BASE Intermediate_Dir "RelWithDebInfo"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC CMAKE_MFC_FLAG
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "OUTPUT_DIRECTORY_RELWITHDEBINFO"
+# PROP Intermediate_Dir "RelWithDebInfo"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /FD /c
+# ADD CPP /nologo /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /FD /c
+# ADD CPP BUILD_INCLUDES EXTRA_DEFINES OUTPUT_LIBNAME_EXPORTS
+# ADD CPP CMAKE_CXX_FLAGS
+# ADD CPP CMAKE_CXX_FLAGS_RELWITHDEBINFO
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC BUILD_INCLUDES /l 0x409 /d "NDEBUG"
+# ADD RSC COMPILE_DEFINITIONS
+# ADD RSC COMPILE_DEFINITIONS_RELWITHDEBINFO
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 /nologo /subsystem:console /debug /machine:I386 /IGNORE:4089
+# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /IGNORE:4089 TARGET_VERSION_FLAG
+# ADD LINK32 /out:"OUTPUT_DIRECTORY_RELWITHDEBINFO\OUTPUT_NAME_RELWITHDEBINFO" TARGET_IMPLIB_FLAG_RELWITHDEBINFO
+CM_MULTILINE_OPTIONS_RELWITHDEBINFO
+
+CMAKE_CUSTOM_RULE_CODE_RELWITHDEBINFO
+
+!ENDIF
+
+# Begin Target
+
+# Name "OUTPUT_LIBNAME - Win32 Release"
+# Name "OUTPUT_LIBNAME - Win32 Debug"
+# Name "OUTPUT_LIBNAME - Win32 MinSizeRel"
+# Name "OUTPUT_LIBNAME - Win32 RelWithDebInfo"
diff --git a/Templates/EXEWinHeader.dsptemplate b/Templates/EXEWinHeader.dsptemplate
new file mode 100644
index 000000000..e0d226479
--- /dev/null
+++ b/Templates/EXEWinHeader.dsptemplate
@@ -0,0 +1,187 @@
+# Microsoft Developer Studio Project File - Name="pcbuilder" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# CM DSP Header file
+# This file is read by the build system of cm, and is used as the top part of
+# a microsoft project dsp header file
+# IF this is in a dsp file, then it is not the header, but has
+# already been used, so do not edit here...
+
+# variables to REPLACE
+#
+# BUILD_INCLUDES == include path
+# OUTPUT_DIRECTORY == override in output directory
+# EXTRA_DEFINES == compiler defines
+# OUTPUT_LIBNAME == name of output library
+# CM_LIBRARIES == libraries linked in
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=OUTPUT_LIBNAME - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "OUTPUT_LIBNAME.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "OUTPUT_LIBNAME.mak" CFG="OUTPUT_LIBNAME - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "OUTPUT_LIBNAME - Win32 MinSizeRel" (based on "Win32 (x86) Application")
+!MESSAGE "OUTPUT_LIBNAME - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "OUTPUT_LIBNAME - Win32 RelWithDebInfo" (based on "Win32 (x86) Application")
+!MESSAGE "OUTPUT_LIBNAME - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "OUTPUT_LIBNAME - Win32 Release"
+
+# PROP BASE Use_MFC CMAKE_MFC_FLAG
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC CMAKE_MFC_FLAG
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "OUTPUT_DIRECTORY_RELEASE"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP BUILD_INCLUDES EXTRA_DEFINES OUTPUT_LIBNAME_EXPORTS
+# ADD CPP CMAKE_CXX_FLAGS
+# ADD CPP CMAKE_CXX_FLAGS_RELEASE
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC BUILD_INCLUDES /l 0x409 /d "NDEBUG"
+# ADD RSC COMPILE_DEFINITIONS
+# ADD RSC COMPILE_DEFINITIONS_RELEASE
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 /nologo /subsystem:windows /machine:I386 /IGNORE:4089
+# ADD LINK32 /nologo /subsystem:windows /machine:I386 /IGNORE:4089 TARGET_VERSION_FLAG
+# ADD LINK32 /out:"OUTPUT_DIRECTORY_RELEASE\OUTPUT_NAME_RELEASE" TARGET_IMPLIB_FLAG_RELEASE
+CM_MULTILINE_OPTIONS_RELEASE
+
+CMAKE_CUSTOM_RULE_CODE_RELEASE
+
+!ELSEIF "$(CFG)" == "OUTPUT_LIBNAME - Win32 Debug"
+
+# PROP BASE Use_MFC CMAKE_MFC_FLAG
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC CMAKE_MFC_FLAG
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "OUTPUT_DIRECTORY_DEBUG"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /GZ /c
+# ADD CPP BUILD_INCLUDES EXTRA_DEFINES OUTPUT_LIBNAME_EXPORTS
+# ADD CPP CMAKE_CXX_FLAGS
+# ADD CPP CMAKE_CXX_FLAGS_DEBUG
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC BUILD_INCLUDES /l 0x409 /d "_DEBUG"
+# ADD RSC COMPILE_DEFINITIONS
+# ADD RSC COMPILE_DEFINITIONS_DEBUG
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept /IGNORE:4089
+# ADD LINK32 /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept /IGNORE:4089 TARGET_VERSION_FLAG
+# ADD LINK32 /out:"OUTPUT_DIRECTORY_DEBUG\OUTPUT_NAME_DEBUG" TARGET_IMPLIB_FLAG_DEBUG
+CM_MULTILINE_OPTIONS_DEBUG
+
+CMAKE_CUSTOM_RULE_CODE_DEBUG
+
+!ELSEIF "$(CFG)" == "OUTPUT_LIBNAME - Win32 MinSizeRel"
+# PROP BASE Use_MFC CMAKE_MFC_FLAG
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "MinSizeRel"
+# PROP BASE Intermediate_Dir "MinSizeRel"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC CMAKE_MFC_FLAG
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "OUTPUT_DIRECTORY_MINSIZEREL"
+# PROP Intermediate_Dir "MinSizeRel"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP BUILD_INCLUDES EXTRA_DEFINES OUTPUT_LIBNAME_EXPORTS
+# ADD CPP CMAKE_CXX_FLAGS
+# ADD CPP CMAKE_CXX_FLAGS_MINSIZEREL
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC BUILD_INCLUDES /l 0x409 /d "NDEBUG"
+# ADD RSC COMPILE_DEFINITIONS
+# ADD RSC COMPILE_DEFINITIONS_MINSIZEREL
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 /nologo /subsystem:windows /machine:I386 /pdbtype:sept /IGNORE:4089
+# ADD LINK32 /nologo /subsystem:windows /machine:I386 /pdbtype:sept /IGNORE:4089 TARGET_VERSION_FLAG
+# ADD LINK32 /out:"OUTPUT_DIRECTORY_MINSIZEREL\OUTPUT_NAME_MINSIZEREL" TARGET_IMPLIB_FLAG_MINSIZEREL
+CM_MULTILINE_OPTIONS_MINSIZEREL
+
+CMAKE_CUSTOM_RULE_CODE_MINSIZEREL
+
+!ELSEIF "$(CFG)" == "OUTPUT_LIBNAME - Win32 RelWithDebInfo"
+
+# PROP BASE Use_MFC CMAKE_MFC_FLAG
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "RelWithDebInfo"
+# PROP BASE Intermediate_Dir "RelWithDebInfo"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC CMAKE_MFC_FLAG
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "OUTPUT_DIRECTORY_RELWITHDEBINFO"
+# PROP Intermediate_Dir "RelWithDebInfo"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP BUILD_INCLUDES EXTRA_DEFINES OUTPUT_LIBNAME_EXPORTS
+# ADD CPP CMAKE_CXX_FLAGS
+# ADD CPP CMAKE_CXX_FLAGS_RELWITHDEBINFO
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC BUILD_INCLUDES /l 0x409 /d "NDEBUG"
+# ADD RSC COMPILE_DEFINITIONS
+# ADD RSC COMPILE_DEFINITIONS_RELWITHDEBINFO
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 /nologo /subsystem:windows /machine:I386 /IGNORE:4089
+# ADD LINK32 /nologo /subsystem:windows /debug /machine:I386 /IGNORE:4089 TARGET_VERSION_FLAG
+# ADD LINK32 /out:"OUTPUT_DIRECTORY_RELWITHDEBINFO\OUTPUT_NAME_RELWITHDEBINFO" TARGET_IMPLIB_FLAG_RELWITHDEBINFO
+CM_MULTILINE_OPTIONS_RELWITHDEBINFO
+
+CMAKE_CUSTOM_RULE_CODE_RELWITHDEBINFO
+
+!ENDIF
+
+# Begin Target
+
+# Name "OUTPUT_LIBNAME - Win32 Release"
+# Name "OUTPUT_LIBNAME - Win32 Debug"
+# Name "OUTPUT_LIBNAME - Win32 MinSizeRel"
+# Name "OUTPUT_LIBNAME - Win32 RelWithDebInfo"
diff --git a/Templates/TestDriver.cxx.in b/Templates/TestDriver.cxx.in
new file mode 100644
index 000000000..9e5303004
--- /dev/null
+++ b/Templates/TestDriver.cxx.in
@@ -0,0 +1,155 @@
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+@CMAKE_TESTDRIVER_EXTRA_INCLUDES@
+
+
+/* Forward declare test functions. */
+@CMAKE_FORWARD_DECLARE_TESTS@
+
+/* Create map. */
+
+typedef int (*MainFuncPointer)(int , char*[]);
+typedef struct
+{
+ const char* name;
+ MainFuncPointer func;
+} functionMapEntry;
+
+functionMapEntry cmakeGeneratedFunctionMapEntries[] = {
+ @CMAKE_FUNCTION_TABLE_ENTIRES@
+ {0,0}
+};
+
+/* Allocate and create a lowercased copy of string
+ (note that it has to be free'd manually) */
+
+char* lowercase(const char *string)
+{
+ char *new_string, *p;
+
+#ifdef __cplusplus
+ new_string = static_cast<char *>(malloc(sizeof(char) *
+ static_cast<size_t>(strlen(string) + 1)));
+#else
+ new_string = (char *)(malloc(sizeof(char) * (size_t)(strlen(string) + 1)));
+#endif
+
+ if (!new_string)
+ {
+ return 0;
+ }
+ strcpy(new_string, string);
+ p = new_string;
+ while (*p != 0)
+ {
+#ifdef __cplusplus
+ *p = static_cast<char>(tolower(*p));
+#else
+ *p = (char)(tolower(*p));
+#endif
+
+ ++p;
+ }
+ return new_string;
+}
+
+int main(int ac, char *av[])
+{
+ int i, NumTests, testNum, partial_match;
+ char *arg, *test_name;
+ int count;
+ int testToRun = -1;
+
+ @CMAKE_TESTDRIVER_ARGVC_FUNCTION@
+
+ for(count =0; cmakeGeneratedFunctionMapEntries[count].name != 0; count++)
+ {
+ }
+ NumTests = count;
+ /* If no test name was given */
+ /* process command line with user function. */
+ if (ac < 2)
+ {
+ /* Ask for a test. */
+ printf("Available tests:\n");
+ for (i =0; i < NumTests; ++i)
+ {
+ printf("%3d. %s\n", i, cmakeGeneratedFunctionMapEntries[i].name);
+ }
+ 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");
+ return -1;
+ }
+ if (testNum >= NumTests)
+ {
+ printf("%3d is an invalid test number.\n", testNum);
+ return -1;
+ }
+ testToRun = testNum;
+ ac--;
+ av++;
+ }
+ partial_match = 0;
+ arg = 0;
+ /* If partial match is requested. */
+ if(testToRun == -1 && ac > 1)
+ {
+ partial_match = (strcmp(av[1], "-R") == 0) ? 1 : 0;
+ }
+ if (partial_match && ac < 3)
+ {
+ printf("-R needs an additional parameter.\n");
+ return -1;
+ }
+ if(testToRun == -1)
+ {
+ arg = lowercase(av[1 + partial_match]);
+ }
+ for (i =0; i < NumTests && testToRun == -1; ++i)
+ {
+ test_name = lowercase(cmakeGeneratedFunctionMapEntries[i].name);
+ if (partial_match && strstr(test_name, arg) != NULL)
+ {
+ testToRun = i;
+ ac -=2;
+ av += 2;
+ }
+ else if (!partial_match && strcmp(test_name, arg) == 0)
+ {
+ testToRun = i;
+ ac--;
+ av++;
+ }
+ free(test_name);
+ }
+ if(arg)
+ {
+ free(arg);
+ }
+ if(testToRun != -1)
+ {
+ int result;
+@CMAKE_TESTDRIVER_BEFORE_TESTMAIN@
+ result = (*cmakeGeneratedFunctionMapEntries[testToRun].func)(ac, av);
+@CMAKE_TESTDRIVER_AFTER_TESTMAIN@
+ return result;
+ }
+
+
+ /* Nothing was run, display the test names. */
+ printf("Available tests:\n");
+ for (i =0; i < NumTests; ++i)
+ {
+ printf("%3d. %s\n", i, cmakeGeneratedFunctionMapEntries[i].name);
+ }
+ printf("Failed: %s is an invalid test name.\n", av[1]);
+
+ return -1;
+}
diff --git a/Templates/UtilityFooter.dsptemplate b/Templates/UtilityFooter.dsptemplate
new file mode 100644
index 000000000..941fb446a
--- /dev/null
+++ b/Templates/UtilityFooter.dsptemplate
@@ -0,0 +1,2 @@
+# End Target
+# End Project
diff --git a/Templates/UtilityHeader.dsptemplate b/Templates/UtilityHeader.dsptemplate
new file mode 100644
index 000000000..509f597f1
--- /dev/null
+++ b/Templates/UtilityHeader.dsptemplate
@@ -0,0 +1,95 @@
+# Microsoft Developer Studio Project File - Name="OUTPUT_LIBNAME" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Generic Project" 0x010a
+
+CFG=OUTPUT_LIBNAME - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "OUTPUT_LIBNAME.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "OUTPUT_LIBNAME.mak" CFG="OUTPUT_LIBNAME - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "OUTPUT_LIBNAME - Win32 MinSizeRel" (based on "Win32 (x86) Generic Project")
+!MESSAGE "OUTPUT_LIBNAME - Win32 Release" (based on "Win32 (x86) Generic Project")
+!MESSAGE "OUTPUT_LIBNAME - Win32 RelWithDebInfo" (based on "Win32 (x86) Generic Project")
+!MESSAGE "OUTPUT_LIBNAME - Win32 Debug" (based on "Win32 (x86) Generic Project")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+MTL=midl.exe
+
+!IF "$(CFG)" == "OUTPUT_LIBNAME - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+
+CMAKE_CUSTOM_RULE_CODE_RELEASE
+
+!ELSEIF "$(CFG)" == "OUTPUT_LIBNAME - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+
+CMAKE_CUSTOM_RULE_CODE_DEBUG
+
+!ELSEIF "$(CFG)" == "OUTPUT_LIBNAME - Win32 MinSizeRel"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "MinSizeRel"
+# PROP BASE Intermediate_Dir "MinSizeRel"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Intermediate_Dir "MinSizeRel"
+# PROP Target_Dir ""
+
+CMAKE_CUSTOM_RULE_CODE_MINSIZEREL
+
+!ELSEIF "$(CFG)" == "OUTPUT_LIBNAME - Win32 RelWithDebInfo"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "RelWithDebInfo"
+# PROP BASE Intermediate_Dir "RelWithDebInfo"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Intermediate_Dir "RelWithDebInfo"
+# PROP Target_Dir ""
+
+CMAKE_CUSTOM_RULE_CODE_RELWITHDEBINFO
+
+!ENDIF
+
+# Begin Target
+
+# Name "OUTPUT_LIBNAME - Win32 Release"
+# Name "OUTPUT_LIBNAME - Win32 Debug"
+# Name "OUTPUT_LIBNAME - Win32 MinSizeRel"
+# Name "OUTPUT_LIBNAME - Win32 RelWithDebInfo"
diff --git a/Templates/cygwin-package.sh.in b/Templates/cygwin-package.sh.in
new file mode 100755
index 000000000..8482e7e4d
--- /dev/null
+++ b/Templates/cygwin-package.sh.in
@@ -0,0 +1,103 @@
+#!/bin/sh
+
+# this is a sample shell script used for building a cmake
+# based project for a cygwin setup package.
+
+# get the current directory
+TOP_DIR=`cd \`echo "$0" | sed -n '/\//{s/\/[^\/]*$//;p;}'\`;pwd`
+
+# create build directory
+mkdirs()
+{
+ (
+ mkdir -p "$TOP_DIR/@CPACK_PACKAGE_FILE_NAME@/.build"
+ )
+}
+
+# cd into
+# untar source tree and apply patch
+prep()
+{
+ (
+ cd "$TOP_DIR" &&
+ tar xvfj @CPACK_PACKAGE_FILE_NAME@.tar.bz2
+ patch -p0 < "@CPACK_PACKAGE_FILE_NAME@-@CPACK_CYGWIN_PATCH_NUMBER@.patch" &&
+ mkdirs
+ )
+}
+
+# configure the build tree in .build directory
+# of the source tree
+conf()
+{
+ (
+ cd "$TOP_DIR/@CPACK_PACKAGE_FILE_NAME@/.build" &&
+ cmake ..
+ )
+}
+
+# build the package in the .build directory
+build()
+{
+ (
+ cd "$TOP_DIR/@CPACK_PACKAGE_FILE_NAME@/.build" &&
+ make &&
+ make test
+ )
+}
+
+# clean the build tree
+clean()
+{
+ (
+ cd "$TOP_DIR/@CPACK_PACKAGE_FILE_NAME@/.build" &&
+ make clean
+ )
+}
+
+# create the package
+pkg()
+{
+ (
+ cd "$TOP_DIR/@CPACK_PACKAGE_FILE_NAME@/.build" &&
+ cpack &&
+ mv @CPACK_PACKAGE_FILE_NAME@-@CPACK_CYGWIN_PATCH_NUMBER@.tar.bz2 "$TOP_DIR"
+ )
+}
+
+# create the source package
+spkg()
+{
+ (
+ cd "$TOP_DIR/@CPACK_PACKAGE_FILE_NAME@/.build" &&
+ cpack --config CPackSourceConfig.cmake &&
+ mv @CPACK_PACKAGE_FILE_NAME@-@CPACK_CYGWIN_PATCH_NUMBER@-src.tar.bz2 "$TOP_DIR"
+ )
+}
+
+# clean up
+finish()
+{
+ (
+ rm -rf "@CPACK_PACKAGE_FILE_NAME@"
+ )
+}
+
+case $1 in
+ prep) prep ; STATUS=$? ;;
+ mkdirs) mkdirs ; STATUS=$? ;;
+ conf) conf ; STATUS=$? ;;
+ build) build ; STATUS=$? ;;
+ clean) clean ; STATUS=$? ;;
+ package) pkg ; STATUS=$? ;;
+ pkg) pkg ; STATUS=$? ;;
+ src-package) spkg ; STATUS=$? ;;
+ spkg) spkg ; STATUS=$? ;;
+ finish) finish ; STATUS=$? ;;
+ all) (
+ prep && conf && build && pkg && spkg && finish ;
+ STATUS=$?
+ ) ;;
+ *) echo "Error: bad argument (all or one of these: prep mkdirs conf build clean package pkg src-package spkg finish)" ; exit 1 ;;
+esac
+exit ${STATUS}
diff --git a/Templates/staticLibFooter.dsptemplate b/Templates/staticLibFooter.dsptemplate
new file mode 100644
index 000000000..0d0682a7b
--- /dev/null
+++ b/Templates/staticLibFooter.dsptemplate
@@ -0,0 +1,4 @@
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/Templates/staticLibHeader.dsptemplate b/Templates/staticLibHeader.dsptemplate
new file mode 100644
index 000000000..16b784e17
--- /dev/null
+++ b/Templates/staticLibHeader.dsptemplate
@@ -0,0 +1,173 @@
+# Microsoft Developer Studio Project File - Name="OUTPUT_LIBNAME" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# CMAKE DSP Header file
+# This file is read by the CMAKE, and is used as the top part of
+# a microsoft project dsp header file
+# IF this is in a dsp file, then it is not the header, but has
+# already been used, so do not edit in that case.
+
+# variables to REPLACE
+#
+# BUILD_INCLUDES == include path
+# EXTRA_DEFINES == compiler defines
+# OUTPUT_DIRECTORY == override in output directory
+# OUTPUT_LIBNAME == name of output library
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=OUTPUT_LIBNAME - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "OUTPUT_LIBNAME.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "OUTPUT_LIBNAME.mak" CFG="OUTPUT_LIBNAME - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "OUTPUT_LIBNAME - Win32 MinSizeRel" (based on "Win32 (x86) Static Library")
+!MESSAGE "OUTPUT_LIBNAME - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "OUTPUT_LIBNAME - Win32 RelWithDebInfo" (based on "Win32 (x86) Static Library")
+!MESSAGE "OUTPUT_LIBNAME - Win32 Debug" (based on "Win32 (x86) Static Library")
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "OUTPUT_LIBNAME - Win32 Release"
+
+# PROP BASE Use_MFC CMAKE_MFC_FLAG
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC CMAKE_MFC_FLAG
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "OUTPUT_DIRECTORY_RELEASE"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /D "WIN32" /D "NDEBUG" /D "_LIB" /FD /c
+# ADD CPP /nologo /D "NDEBUG" /D "WIN32" /D "_LIB" /FD /c
+# ADD CPP BUILD_INCLUDES EXTRA_DEFINES
+# ADD CPP CMAKE_CXX_FLAGS
+# ADD CPP CMAKE_CXX_FLAGS_RELEASE
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC BUILD_INCLUDES /l 0x409 /d "NDEBUG"
+# ADD RSC COMPILE_DEFINITIONS
+# ADD RSC COMPILE_DEFINITIONS_RELEASE
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"OUTPUT_DIRECTORY_RELEASE/OUTPUT_NAME_RELEASE" CM_STATIC_LIB_ARGS_RELEASE
+
+CMAKE_CUSTOM_RULE_CODE_RELEASE
+
+!ELSEIF "$(CFG)" == "OUTPUT_LIBNAME - Win32 Debug"
+
+# PROP BASE Use_MFC CMAKE_MFC_FLAG
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC CMAKE_MFC_FLAG
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "OUTPUT_DIRECTORY_DEBUG"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /D "WIN32" /D "_DEBUG" /D "_LIB" /FD /c
+# ADD CPP /nologo /D "_DEBUG" /D "WIN32" /D "_LIB" /FD /GZ /c
+# ADD CPP BUILD_INCLUDES EXTRA_DEFINES
+# ADD CPP CMAKE_CXX_FLAGS
+# ADD CPP CMAKE_CXX_FLAGS_DEBUG
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC BUILD_INCLUDES /l 0x409 /d "_DEBUG"
+# ADD RSC COMPILE_DEFINITIONS
+# ADD RSC COMPILE_DEFINITIONS_DEBUG
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"OUTPUT_DIRECTORY_DEBUG/OUTPUT_NAME_DEBUG" CM_STATIC_LIB_ARGS_DEBUG
+
+CMAKE_CUSTOM_RULE_CODE_DEBUG
+
+!ELSEIF "$(CFG)" == "OUTPUT_LIBNAME - Win32 MinSizeRel"
+
+# PROP BASE Use_MFC CMAKE_MFC_FLAG
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "MinSizeRel"
+# PROP BASE Intermediate_Dir "MinSizeRel"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC CMAKE_MFC_FLAG
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "OUTPUT_DIRECTORY_MINSIZEREL"
+# PROP Intermediate_Dir "MinSizeRel"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_USRDLL" /D "_ATL_DLL" /FD /c
+# ADD CPP /nologo /D "NDEBUG" /D "_ATL_DLL" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /FD /c
+# ADD CPP BUILD_INCLUDES EXTRA_DEFINES
+# ADD CPP CMAKE_CXX_FLAGS
+# ADD CPP CMAKE_CXX_FLAGS_MINSIZEREL
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC BUILD_INCLUDES /l 0x409 /d "NDEBUG"
+# ADD RSC COMPILE_DEFINITIONS
+# ADD RSC COMPILE_DEFINITIONS_MINSIZEREL
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"OUTPUT_DIRECTORY_MINSIZEREL/OUTPUT_NAME_MINSIZEREL" CM_STATIC_LIB_ARGS_MINSIZEREL
+
+CMAKE_CUSTOM_RULE_CODE_MINSIZEREL
+
+!ELSEIF "$(CFG)" == "OUTPUT_LIBNAME - Win32 RelWithDebInfo"
+
+# PROP BASE Use_MFC CMAKE_MFC_FLAG
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "RelWithDebInfo"
+# PROP BASE Intermediate_Dir "RelWithDebInfo"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC CMAKE_MFC_FLAG
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "OUTPUT_DIRECTORY_RELWITHDEBINFO"
+# PROP Intermediate_Dir "RelWithDebInfo"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /D "WIN32" /D "NDEBUG" /D "_LIB" /FD /c
+# ADD CPP /nologo /D "NDEBUG" /D "WIN32" /D "_LIB" /FD /c
+# ADD CPP BUILD_INCLUDES EXTRA_DEFINES
+# ADD CPP CMAKE_CXX_FLAGS
+# ADD CPP CMAKE_CXX_FLAGS_RELWITHDEBINFO
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC BUILD_INCLUDES /l 0x409 /d "NDEBUG"
+# ADD RSC COMPILE_DEFINITIONS
+# ADD RSC COMPILE_DEFINITIONS_RELWITHDEBINFO
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"OUTPUT_DIRECTORY_RELWITHDEBINFO/OUTPUT_NAME_RELWITHDEBINFO" CM_STATIC_LIB_ARGS_RELWITHDEBINFO
+
+CMAKE_CUSTOM_RULE_CODE_RELWITHDEBINFO
+
+!ENDIF
+
+# Begin Target
+
+# Name "OUTPUT_LIBNAME - Win32 Release"
+# Name "OUTPUT_LIBNAME - Win32 Debug"
+# Name "OUTPUT_LIBNAME - Win32 MinSizeRel"
+# Name "OUTPUT_LIBNAME - Win32 RelWithDebInfo"
+
diff --git a/Tests/.NoDartCoverage b/Tests/.NoDartCoverage
new file mode 100644
index 000000000..3c9972938
--- /dev/null
+++ b/Tests/.NoDartCoverage
@@ -0,0 +1 @@
+# do not do coverage in this directory
diff --git a/Tests/Architecture/CMakeLists.txt b/Tests/Architecture/CMakeLists.txt
new file mode 100644
index 000000000..927ce3fed
--- /dev/null
+++ b/Tests/Architecture/CMakeLists.txt
@@ -0,0 +1,59 @@
+cmake_minimum_required(VERSION 2.8)
+project(Architecture C)
+
+function(test_for_xcode4 result_var)
+ set(${result_var} 0 PARENT_SCOPE)
+ if(APPLE)
+ execute_process(COMMAND xcodebuild -version
+ OUTPUT_VARIABLE ov RESULT_VARIABLE rv
+ )
+ if("${rv}" STREQUAL "0")
+ if(ov MATCHES "^Xcode 4.[0-9].*$")
+ set(${result_var} 1 PARENT_SCOPE)
+ endif()
+ endif()
+ endif()
+endfunction()
+
+test_for_xcode4(is_xcode4)
+
+set(arch0 i386)
+set(arch1 ppc)
+
+if(is_xcode4)
+ # Xcode 4, use modern architectures as defaults
+ # Arch 'ppc' no longer works: tools no longer available starting with Xcode 4
+ set(arch0 i386)
+ set(arch1 x86_64)
+endif()
+
+add_library(foo foo.c)
+if(CMAKE_OSX_ARCHITECTURES)
+ get_property(archs TARGET foo PROPERTY OSX_ARCHITECTURES)
+ if(NOT "${CMAKE_OSX_ARCHITECTURES}" STREQUAL "${archs}")
+ message(FATAL_ERROR
+ "OSX_ARCHITECTURES property not initialized by CMAKE_OSX_ARCHITECTURES.\n"
+ "Expected [${CMAKE_OSX_ARCHITECTURES}], got [${archs}]."
+ )
+ endif()
+ list(LENGTH archs archs_len)
+ if(archs_len GREATER 1)
+ list(GET archs 0 arch0)
+ list(GET archs 1 arch1)
+ endif()
+endif()
+
+message("is_xcode4='${is_xcode4}'")
+message("archs='${archs}'")
+message("arch0='${arch0}'")
+message("arch1='${arch1}'")
+
+set_property(TARGET foo PROPERTY OSX_ARCHITECTURES ${arch0})
+set_property(TARGET foo PROPERTY OSX_ARCHITECTURES_DEBUG ${arch1})
+
+add_executable(bar bar.c)
+target_link_libraries(bar foo)
+
+set_property(TARGET bar PROPERTY OUTPUT_NAME Architecture)
+set_property(TARGET bar PROPERTY OSX_ARCHITECTURES ${arch1})
+set_property(TARGET bar PROPERTY OSX_ARCHITECTURES_DEBUG ${arch0})
diff --git a/Tests/Architecture/bar.c b/Tests/Architecture/bar.c
new file mode 100644
index 000000000..923c89c9a
--- /dev/null
+++ b/Tests/Architecture/bar.c
@@ -0,0 +1,2 @@
+extern int foo(void);
+int main() { return foo(); }
diff --git a/Tests/Architecture/foo.c b/Tests/Architecture/foo.c
new file mode 100644
index 000000000..e35694ba0
--- /dev/null
+++ b/Tests/Architecture/foo.c
@@ -0,0 +1 @@
+int foo(void) { return 0; }
diff --git a/Tests/ArgumentExpansion/CMakeLists.txt b/Tests/ArgumentExpansion/CMakeLists.txt
new file mode 100644
index 000000000..a24636f58
--- /dev/null
+++ b/Tests/ArgumentExpansion/CMakeLists.txt
@@ -0,0 +1,60 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(ArgumentExpansion)
+
+function (argument_tester expected expected_len)
+ list(LENGTH ARGN argn_len)
+ list(LENGTH ${expected} expected_received_len)
+
+ if (NOT ${expected_received_len} EQUAL ${expected_len})
+ message(STATUS "Unexpected: Expanding expected values isn't working")
+ endif (NOT ${expected_received_len} EQUAL ${expected_len})
+
+ if (${argn_len} EQUAL ${expected_len})
+ set(i 0)
+ while (i LESS ${argn_len})
+ list(GET ARGN ${i} argn_value)
+ list(GET ${expected} ${i} expected_value)
+
+ if (NOT "${argn_value}" STREQUAL "${expected_value}")
+ message(STATUS "Unexpected: Argument ${i} doesn't match")
+ message(STATUS " Expected: ${expected_value}")
+ message(STATUS " Received: ${argn_value}")
+ endif ()
+
+ math(EXPR i "${i} + 1")
+ endwhile (i LESS ${argn_len})
+ else (${argn_len} EQUAL ${expected_len})
+ message(STATUS "Unexpected: Lengths of arguments don't match")
+ message(STATUS " Expected: ${expected_len}")
+ message(STATUS " Received: ${argn_len}")
+ endif (${argn_len} EQUAL ${expected_len})
+endfunction (argument_tester expected)
+
+set(empty_test)
+message(STATUS "Test: Empty arguments")
+argument_tester(empty_test 0 ${empty_test})
+
+set(single_arg_test
+ "single arg")
+message(STATUS "Test: Single argument")
+argument_tester(single_arg_test 1 ${single_arg_test})
+
+set(multiple_arg_test
+ "first arg"
+ "second arg")
+message(STATUS "Test: Multiple arguments")
+argument_tester(multiple_arg_test 2 ${multiple_arg_test})
+
+set(nested_list_arg_test
+ "${multiple_arg_test}"
+ "first arg"
+ "second arg")
+message(STATUS "Test: Nested list argument flattens")
+argument_tester(nested_list_arg_test 4 ${nested_list_arg_test})
+
+set(semicolon_arg_test
+ "pre\;post")
+set(semicolon_arg_test_flat "pre;post")
+message(STATUS "Test: Semicolon argument flattens")
+argument_tester(semicolon_arg_test_flat 2 ${semicolon_arg_test})
diff --git a/Tests/Assembler/CMakeLists.txt b/Tests/Assembler/CMakeLists.txt
new file mode 100644
index 000000000..456e4961f
--- /dev/null
+++ b/Tests/Assembler/CMakeLists.txt
@@ -0,0 +1,33 @@
+cmake_minimum_required (VERSION 2.6)
+project(Assembler C)
+message("CTEST_FULL_OUTPUT ")
+set(CMAKE_VERBOSE_MAKEFILE 1)
+
+set(SRCS)
+
+# (at least) the following toolchains can process assembler files directly
+# and also generate assembler files from C:
+if("${CMAKE_GENERATOR}" MATCHES "Makefile")
+ if(("${CMAKE_C_COMPILER_ID}" MATCHES "^(GNU|HP|SunPro|XL)$") OR ("${CMAKE_C_COMPILER_ID}" STREQUAL "Intel" AND UNIX))
+ set(C_FLAGS "${CMAKE_C_FLAGS}")
+ separate_arguments(C_FLAGS)
+ set(SRCS main.s)
+ add_custom_command(
+ OUTPUT main.s
+ COMMAND ${CMAKE_C_COMPILER} ${C_FLAGS} -S ${CMAKE_CURRENT_SOURCE_DIR}/main.c -o main.s
+ DEPENDS main.c
+ VERBATIM
+ )
+ endif(("${CMAKE_C_COMPILER_ID}" MATCHES "^(GNU|HP|SunPro|XL)$") OR ("${CMAKE_C_COMPILER_ID}" STREQUAL "Intel" AND UNIX))
+endif("${CMAKE_GENERATOR}" MATCHES "Makefile")
+
+
+if(SRCS)
+ set(CMAKE_ASM_FLAGS "${CMAKE_C_FLAGS}")
+ enable_language(ASM OPTIONAL)
+else(SRCS)
+ message(STATUS "No assembler enabled, using C")
+ set(SRCS main.c)
+endif(SRCS)
+
+add_executable(HelloAsm ${SRCS})
diff --git a/Tests/Assembler/main-linux-x86-gas.s b/Tests/Assembler/main-linux-x86-gas.s
new file mode 100644
index 000000000..da8e84591
--- /dev/null
+++ b/Tests/Assembler/main-linux-x86-gas.s
@@ -0,0 +1,28 @@
+ .section .rodata
+ .align 4
+.LC0:
+ .string "hello assembler world, %d arguments given\n"
+ .text
+.globl main
+ .type main, @function
+main:
+ leal 4(%esp), %ecx
+ andl $-16, %esp
+ pushl -4(%ecx)
+ pushl %ebp
+ movl %esp, %ebp
+ pushl %ecx
+ subl $20, %esp
+ movl (%ecx), %eax
+ movl %eax, 4(%esp)
+ movl $.LC0, (%esp)
+ call printf
+ movl $0, %eax
+ addl $20, %esp
+ popl %ecx
+ popl %ebp
+ leal -4(%ecx), %esp
+ ret
+ .size main, .-main
+ .ident "GCC: (GNU) 4.1.2 20060928 (prerelease) (Ubuntu 4.1.1-13ubuntu5)"
+ .section .note.GNU-stack,"",@progbits
diff --git a/Tests/Assembler/main.c b/Tests/Assembler/main.c
new file mode 100644
index 000000000..95de0b5d1
--- /dev/null
+++ b/Tests/Assembler/main.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+
+#ifdef __CLASSIC_C__
+int main(){
+ int argc;
+ char*argv[];
+#else
+int main(int argc, char*argv[]){
+#endif
+ printf("hello assembler world, %d arguments given\n", argc);
+ return 0;
+}
diff --git a/Tests/BuildDepends/CMakeLists.txt b/Tests/BuildDepends/CMakeLists.txt
new file mode 100644
index 000000000..5e36d11b4
--- /dev/null
+++ b/Tests/BuildDepends/CMakeLists.txt
@@ -0,0 +1,225 @@
+# this test creates a static library and an executable
+# the source to the library is then changed
+# and the build is done on the executable and if things
+# are working the executable should relink with the new
+# value. The subdir Project contains the CMakelists.txt
+# and source files for the test project.
+cmake_minimum_required (VERSION 2.6)
+project(BuildDepends)
+
+# This entire test takes place during the initial
+# configure step. It should not run again when the
+# project is built.
+set(CMAKE_SUPPRESS_REGENERATION 1)
+
+# Xcode needs some help with the fancy dependencies in this test.
+if("${CMAKE_GENERATOR}" MATCHES "Xcode")
+ set(HELP_XCODE 1)
+endif("${CMAKE_GENERATOR}" MATCHES "Xcode")
+function(help_xcode_depends)
+ if(HELP_XCODE)
+ file(GLOB_RECURSE MACRO_OBJS
+ ${BuildDepends_BINARY_DIR}/Project/zot_macro_*.o*
+ )
+ if(MACRO_OBJS)
+ message("Helping Xcode by removing objects [${MACRO_OBJS}]")
+ file(REMOVE ${MACRO_OBJS})
+ endif(MACRO_OBJS)
+ endif(HELP_XCODE)
+endfunction(help_xcode_depends)
+
+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")
+ set(TEST_LINK_DEPENDS ${BuildDepends_BINARY_DIR}/Project/linkdep.txt)
+ file(WRITE ${TEST_LINK_DEPENDS} "1")
+endif()
+list(APPEND _cmake_options "-DTEST_LINK_DEPENDS=${TEST_LINK_DEPENDS}")
+
+list(APPEND _cmake_options "-DCMAKE_FORCE_DEPFILES=1")
+
+file(MAKE_DIRECTORY ${BuildDepends_BINARY_DIR}/Project)
+message("Creating Project/foo.cxx")
+write_file(${BuildDepends_BINARY_DIR}/Project/foo.cxx
+ "const char* foo() { return \"foo\";}" )
+
+file(WRITE ${BuildDepends_BINARY_DIR}/Project/zot.hxx.in
+ "static const char* zot = \"zot\";\n")
+file(WRITE ${BuildDepends_BINARY_DIR}/Project/zot_custom.hxx.in
+ "static const char* zot_custom = \"zot_custom\";\n")
+file(WRITE ${BuildDepends_BINARY_DIR}/Project/zot_macro_dir.hxx
+ "static const char* zot_macro_dir = \"zot_macro_dir\";\n")
+file(WRITE ${BuildDepends_BINARY_DIR}/Project/zot_macro_tgt.hxx
+ "static const char* zot_macro_tgt = \"zot_macro_tgt\";\n")
+
+help_xcode_depends()
+
+message("Building project first time")
+try_compile(RESULT
+ ${BuildDepends_BINARY_DIR}/Project
+ ${BuildDepends_SOURCE_DIR}/Project
+ testRebuild
+ CMAKE_FLAGS ${_cmake_options}
+ OUTPUT_VARIABLE OUTPUT)
+if(HELP_XCODE)
+ try_compile(RESULT
+ ${BuildDepends_BINARY_DIR}/Project
+ ${BuildDepends_SOURCE_DIR}/Project
+ testRebuild
+ OUTPUT_VARIABLE OUTPUT)
+ try_compile(RESULT
+ ${BuildDepends_BINARY_DIR}/Project
+ ${BuildDepends_SOURCE_DIR}/Project
+ testRebuild
+ OUTPUT_VARIABLE OUTPUT)
+endif(HELP_XCODE)
+
+message("Output from first build:\n${OUTPUT}")
+if(NOT RESULT)
+ message(SEND_ERROR "Could not build test project (1)!")
+endif(NOT RESULT)
+
+set(bar ${BuildDepends_BINARY_DIR}/Project/bar${CMAKE_EXECUTABLE_SUFFIX})
+if(EXISTS
+ "${BuildDepends_BINARY_DIR}/Project/Debug/bar${CMAKE_EXECUTABLE_SUFFIX}" )
+ message("found debug")
+ set(bar
+ "${BuildDepends_BINARY_DIR}/Project/Debug/bar${CMAKE_EXECUTABLE_SUFFIX}")
+endif(EXISTS
+ "${BuildDepends_BINARY_DIR}/Project/Debug/bar${CMAKE_EXECUTABLE_SUFFIX}")
+set(zot ${BuildDepends_BINARY_DIR}/Project/zot${CMAKE_EXECUTABLE_SUFFIX})
+if(EXISTS
+ "${BuildDepends_BINARY_DIR}/Project/Debug/zot${CMAKE_EXECUTABLE_SUFFIX}" )
+ message("found debug")
+ set(zot
+ "${BuildDepends_BINARY_DIR}/Project/Debug/zot${CMAKE_EXECUTABLE_SUFFIX}")
+endif(EXISTS
+ "${BuildDepends_BINARY_DIR}/Project/Debug/zot${CMAKE_EXECUTABLE_SUFFIX}")
+
+message("Running ${bar} ")
+execute_process(COMMAND ${bar} OUTPUT_VARIABLE out RESULT_VARIABLE runResult)
+string(REGEX REPLACE "[\r\n]" " " out "${out}")
+message("Run result: ${runResult} Output: \"${out}\"")
+
+if("${out}" STREQUAL "foo ")
+ message("Worked!")
+else("${out}" STREQUAL "foo ")
+ message(SEND_ERROR "Project did not initially build properly: ${out}")
+endif("${out}" STREQUAL "foo ")
+
+message("Running ${zot} ")
+execute_process(COMMAND ${zot} OUTPUT_VARIABLE out RESULT_VARIABLE runResult)
+string(REGEX REPLACE "[\r\n]" " " out "${out}")
+message("Run result: ${runResult} Output: \"${out}\"")
+
+set(VALUE_UNCHANGED "[zot] [zot_custom] [zot_macro_dir] [zot_macro_tgt] ")
+if("${out}" STREQUAL "${VALUE_UNCHANGED}")
+ message("Worked!")
+else("${out}" STREQUAL "${VALUE_UNCHANGED}")
+ message(SEND_ERROR "Project did not initially build properly: ${out}")
+endif("${out}" STREQUAL "${VALUE_UNCHANGED}")
+
+message("Waiting 3 seconds...")
+# any additional argument will cause ${bar} to wait forever
+execute_process(COMMAND ${bar} -infinite TIMEOUT 3 OUTPUT_VARIABLE out)
+
+message("Modifying Project/foo.cxx")
+write_file(${BuildDepends_BINARY_DIR}/Project/foo.cxx
+ "const char* foo() { return \"foo changed\";}" )
+file(WRITE ${BuildDepends_BINARY_DIR}/Project/zot.hxx.in
+ "static const char* zot = \"zot changed\";\n")
+file(WRITE ${BuildDepends_BINARY_DIR}/Project/zot_custom.hxx.in
+ "static const char* zot_custom = \"zot_custom changed\";\n")
+file(WRITE ${BuildDepends_BINARY_DIR}/Project/zot_macro_dir.hxx
+ "static const char* zot_macro_dir = \"zot_macro_dir changed\";\n")
+file(WRITE ${BuildDepends_BINARY_DIR}/Project/zot_macro_tgt.hxx
+ "static const char* zot_macro_tgt = \"zot_macro_tgt changed\";\n")
+
+if(TEST_LINK_DEPENDS)
+ file(WRITE ${TEST_LINK_DEPENDS} "2")
+endif()
+
+help_xcode_depends()
+
+message("Building project second time")
+try_compile(RESULT
+ ${BuildDepends_BINARY_DIR}/Project
+ ${BuildDepends_SOURCE_DIR}/Project
+ testRebuild
+ CMAKE_FLAGS ${_cmake_options}
+ OUTPUT_VARIABLE OUTPUT)
+
+# Xcode is in serious need of help here
+if(HELP_XCODE OR HELP_NINJA)
+ try_compile(RESULT
+ ${BuildDepends_BINARY_DIR}/Project
+ ${BuildDepends_SOURCE_DIR}/Project
+ testRebuild
+ OUTPUT_VARIABLE OUTPUT)
+ try_compile(RESULT
+ ${BuildDepends_BINARY_DIR}/Project
+ ${BuildDepends_SOURCE_DIR}/Project
+ testRebuild
+ OUTPUT_VARIABLE OUTPUT)
+endif()
+
+message("Output from second build:\n${OUTPUT}")
+if(NOT RESULT)
+ message(SEND_ERROR "Could not build test project (2)!")
+endif(NOT RESULT)
+if(EXISTS
+ "${BuildDepends_BINARY_DIR}/Project/Debug/bar${CMAKE_EXECUTABLE_SUFFIX}" )
+ message("found debug")
+endif(EXISTS
+ "${BuildDepends_BINARY_DIR}/Project/Debug/bar${CMAKE_EXECUTABLE_SUFFIX}")
+if(EXISTS
+ "${BuildDepends_BINARY_DIR}/Project/Debug/zot${CMAKE_EXECUTABLE_SUFFIX}" )
+ message("found debug")
+endif(EXISTS
+ "${BuildDepends_BINARY_DIR}/Project/Debug/zot${CMAKE_EXECUTABLE_SUFFIX}")
+
+message("Running ${bar} ")
+execute_process(COMMAND ${bar} OUTPUT_VARIABLE out RESULT_VARIABLE runResult)
+string(REGEX REPLACE "[\r\n]" " " out "${out}")
+message("Run result: ${runResult} Output: \"${out}\"")
+
+if("${out}" STREQUAL "foo changed ")
+ message("Worked!")
+else("${out}" STREQUAL "foo changed ")
+ message(SEND_ERROR "Project did not rebuild properly!")
+endif("${out}" STREQUAL "foo changed ")
+
+message("Running ${zot} ")
+execute_process(COMMAND ${zot} OUTPUT_VARIABLE out RESULT_VARIABLE runResult)
+string(REGEX REPLACE "[\r\n]" " " out "${out}")
+message("Run result: ${runResult} Output: \"${out}\"")
+
+set(VALUE_CHANGED
+ "[zot changed] [zot_custom changed] [zot_macro_dir changed] [zot_macro_tgt changed] "
+ )
+if("${out}" STREQUAL "${VALUE_CHANGED}")
+ message("Worked!")
+else("${out}" STREQUAL "${VALUE_CHANGED}")
+ message(SEND_ERROR "Project did not rebuild properly!")
+endif("${out}" STREQUAL "${VALUE_CHANGED}")
+
+if(TEST_LINK_DEPENDS)
+ set(linkdep ${BuildDepends_BINARY_DIR}/Project/linkdep${CMAKE_EXECUTABLE_SUFFIX})
+ if(${linkdep} IS_NEWER_THAN ${TEST_LINK_DEPENDS})
+ message("LINK_DEPENDS worked")
+ else()
+ message(SEND_ERROR "LINK_DEPENDS failed. Executable
+ ${linkdep}
+is not newer than dependency
+ ${TEST_LINK_DEPENDS}
+")
+ endif()
+endif()
diff --git a/Tests/BuildDepends/Project/CMakeLists.txt b/Tests/BuildDepends/Project/CMakeLists.txt
new file mode 100644
index 000000000..ed8b8bf5d
--- /dev/null
+++ b/Tests/BuildDepends/Project/CMakeLists.txt
@@ -0,0 +1,109 @@
+cmake_minimum_required(VERSION 2.6)
+project(testRebuild)
+
+function(test_for_xcode4 result_var)
+ set(${result_var} 0 PARENT_SCOPE)
+ if(APPLE)
+ execute_process(COMMAND xcodebuild -version
+ OUTPUT_VARIABLE ov RESULT_VARIABLE rv
+ )
+ if("${rv}" STREQUAL "0")
+ if(ov MATCHES "^Xcode 4.[0-9].*$")
+ set(${result_var} 1 PARENT_SCOPE)
+ endif()
+ endif()
+ endif()
+endfunction()
+
+if(APPLE)
+ # only use multi-arch if the sysroot exists on this machine
+ # Ninja needs -M which could not be used with multiple -arch flags
+ if(EXISTS "${CMAKE_OSX_SYSROOT}" AND NOT "${CMAKE_GENERATOR}" MATCHES "Ninja")
+ set(CMAKE_OSX_ARCHITECTURES "ppc;i386")
+ test_for_xcode4(is_xcode4)
+ if(is_xcode4)
+ # Xcode 4, use modern architectures as defaults
+ # Arch 'ppc' no longer works: tools no longer available starting with Xcode 4
+ set(CMAKE_OSX_ARCHITECTURES i386 x86_64)
+ endif()
+ endif()
+endif(APPLE)
+
+add_library(foo STATIC ${testRebuild_BINARY_DIR}/foo.cxx)
+set_target_properties(foo PROPERTIES OUTPUT_NAME "foolib")
+# Add a generated header that regenerates when the generator is
+# rebuilt.
+add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/regen.h
+ COMMAND generator ${CMAKE_CURRENT_BINARY_DIR}/regen.h regen
+ DEPENDS generator # adds file-level dependency to re-run rule
+ )
+
+# Add a generated header that does NOT regenerate when the generator
+# is rebuilt.
+add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/noregen.h
+ COMMAND generator ${CMAKE_CURRENT_BINARY_DIR}/noregen.h noregen
+ )
+
+# Test that the generator rebuilds when the static library source file
+# changes. This should cause regen.h to be recreated also.
+add_executable(generator generator.cxx)
+target_link_libraries(generator foo)
+set_target_properties(generator PROPERTIES OUTPUT_NAME "gen")
+
+# Build an executable to drive the build and rebuild.
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+add_executable(bar bar.cxx
+ ${CMAKE_CURRENT_BINARY_DIR}/regen.h
+ ${CMAKE_CURRENT_BINARY_DIR}/noregen.h
+ )
+
+#-----------------------------------------------------------------------------
+IF("${CMAKE_GENERATOR}" MATCHES "Make")
+ # Test the IMPLICIT_DEPENDS feature.
+ SET(ZOT_DEPENDS IMPLICIT_DEPENDS CXX ${CMAKE_CURRENT_SOURCE_DIR}/dep.cxx)
+ SET(ZOT_CUSTOM_DEP
+ IMPLICIT_DEPENDS CXX ${CMAKE_CURRENT_SOURCE_DIR}/dep_custom.cxx)
+ELSE("${CMAKE_GENERATOR}" MATCHES "Make")
+ # No IMPLICIT_DEPENDS...just depend directly.
+ SET(ZOT_DEPENDS DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/zot.hxx.in)
+ SET(ZOT_CUSTOM_DEP DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/zot_custom.hxx.in)
+ENDIF("${CMAKE_GENERATOR}" MATCHES "Make")
+add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/zot.hxx
+ COMMAND ${CMAKE_COMMAND} -E copy
+ ${CMAKE_CURRENT_BINARY_DIR}/zot.hxx.in
+ ${CMAKE_CURRENT_BINARY_DIR}/zot.hxx
+ ${ZOT_DEPENDS}
+ )
+
+add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/zot_custom.hxx
+ COMMAND ${CMAKE_COMMAND} -E copy
+ ${CMAKE_CURRENT_BINARY_DIR}/zot_custom.hxx.in
+ ${CMAKE_CURRENT_BINARY_DIR}/zot_custom.hxx
+ ${ZOT_CUSTOM_DEP}
+ )
+add_custom_target(zot_custom ALL DEPENDS
+ ${CMAKE_CURRENT_BINARY_DIR}/zot_custom.hxx)
+
+add_executable(zot zot.cxx ${CMAKE_CURRENT_BINARY_DIR}/zot.hxx
+ zot_macro_dir.cxx zot_macro_tgt.cxx)
+add_dependencies(zot zot_custom)
+
+# Test the #include line macro transformation rule support.
+set_property(
+ TARGET zot
+ PROPERTY IMPLICIT_DEPENDS_INCLUDE_TRANSFORM "ZOT_TGT(%)=<zot_%_tgt.hxx>"
+ )
+
+set_property(
+ DIRECTORY
+ PROPERTY IMPLICIT_DEPENDS_INCLUDE_TRANSFORM "ZOT_DIR(%)=<zot_%_dir.hxx>"
+ )
+
+if(TEST_LINK_DEPENDS)
+ add_executable(linkdep linkdep.cxx)
+ set_property(TARGET linkdep PROPERTY LINK_DEPENDS ${TEST_LINK_DEPENDS})
+endif()
diff --git a/Tests/BuildDepends/Project/bar.cxx b/Tests/BuildDepends/Project/bar.cxx
new file mode 100644
index 000000000..25d8bd21b
--- /dev/null
+++ b/Tests/BuildDepends/Project/bar.cxx
@@ -0,0 +1,25 @@
+#include <stdio.h>
+#include <string.h>
+#include <regen.h>
+#include <noregen.h>
+
+int main(int argc, char** argv)
+{
+ /* Make sure the noregen header was not regenerated. */
+ if(strcmp("foo", noregen_string) != 0)
+ {
+ printf("FAILED: noregen.h was regenerated!\n");
+ return 1;
+ }
+
+ /* 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/dep.cxx b/Tests/BuildDepends/Project/dep.cxx
new file mode 100644
index 000000000..6cfebe37c
--- /dev/null
+++ b/Tests/BuildDepends/Project/dep.cxx
@@ -0,0 +1 @@
+#include <zot.hxx.in>
diff --git a/Tests/BuildDepends/Project/dep_custom.cxx b/Tests/BuildDepends/Project/dep_custom.cxx
new file mode 100644
index 000000000..b6ac54847
--- /dev/null
+++ b/Tests/BuildDepends/Project/dep_custom.cxx
@@ -0,0 +1 @@
+#include <zot_custom.hxx.in>
diff --git a/Tests/BuildDepends/Project/generator.cxx b/Tests/BuildDepends/Project/generator.cxx
new file mode 100644
index 000000000..92a122de8
--- /dev/null
+++ b/Tests/BuildDepends/Project/generator.cxx
@@ -0,0 +1,24 @@
+#include <stdio.h>
+
+extern const char* foo();
+
+int main(int argc, const char* argv[])
+{
+ if(argc < 3)
+ {
+ fprintf(stderr, "Must specify output file and symbol prefix!");
+ return 1;
+ }
+ if(FILE* fout = fopen(argv[1], "w"))
+ {
+ fprintf(fout, "static const char* %s_string = \"%s\";\n", argv[2],
+ foo());
+ fclose(fout);
+ }
+ else
+ {
+ fprintf(stderr, "Could not open output file \"%s\"", argv[1]);
+ return 1;
+ }
+ return 0;
+}
diff --git a/Tests/BuildDepends/Project/linkdep.cxx b/Tests/BuildDepends/Project/linkdep.cxx
new file mode 100644
index 000000000..f8b643afb
--- /dev/null
+++ b/Tests/BuildDepends/Project/linkdep.cxx
@@ -0,0 +1,4 @@
+int main()
+{
+ return 0;
+}
diff --git a/Tests/BuildDepends/Project/zot.cxx b/Tests/BuildDepends/Project/zot.cxx
new file mode 100644
index 000000000..775fd3b43
--- /dev/null
+++ b/Tests/BuildDepends/Project/zot.cxx
@@ -0,0 +1,14 @@
+#include <zot.hxx>
+#include <zot_custom.hxx>
+#include <stdio.h>
+
+const char* zot_macro_dir_f();
+const char* zot_macro_tgt_f();
+
+int main()
+{
+ printf("[%s] [%s] [%s] [%s]\n", zot, zot_custom,
+ zot_macro_dir_f(), zot_macro_tgt_f());
+ fflush(stdout);
+ return 0;
+}
diff --git a/Tests/BuildDepends/Project/zot_macro_dir.cxx b/Tests/BuildDepends/Project/zot_macro_dir.cxx
new file mode 100644
index 000000000..733a4b37f
--- /dev/null
+++ b/Tests/BuildDepends/Project/zot_macro_dir.cxx
@@ -0,0 +1,7 @@
+#define ZOT_DIR(x) <zot_##x##_dir.hxx>
+#include ZOT_DIR(macro)
+
+const char* zot_macro_dir_f()
+{
+ return zot_macro_dir;
+}
diff --git a/Tests/BuildDepends/Project/zot_macro_tgt.cxx b/Tests/BuildDepends/Project/zot_macro_tgt.cxx
new file mode 100644
index 000000000..182ee16fd
--- /dev/null
+++ b/Tests/BuildDepends/Project/zot_macro_tgt.cxx
@@ -0,0 +1,7 @@
+#define ZOT_TGT(x) <zot_##x##_tgt.hxx>
+#include ZOT_TGT(macro)
+
+const char* zot_macro_tgt_f()
+{
+ return zot_macro_tgt;
+}
diff --git a/Tests/BundleGeneratorTest/BundleIcon.icns b/Tests/BundleGeneratorTest/BundleIcon.icns
new file mode 100644
index 000000000..8808dd62d
--- /dev/null
+++ b/Tests/BundleGeneratorTest/BundleIcon.icns
Binary files differ
diff --git a/Tests/BundleGeneratorTest/CMakeLists.txt b/Tests/BundleGeneratorTest/CMakeLists.txt
new file mode 100644
index 000000000..e1fc2c1d4
--- /dev/null
+++ b/Tests/BundleGeneratorTest/CMakeLists.txt
@@ -0,0 +1,33 @@
+PROJECT(BundleGeneratorTest)
+
+CMAKE_MINIMUM_REQUIRED(VERSION 2.7)
+
+# Build a shared library and install it in lib/
+ADD_LIBRARY(Library SHARED Library.cxx)
+INSTALL(TARGETS Library DESTINATION lib)
+
+# Build an executable and install it in bin/
+ADD_EXECUTABLE(Executable Executable.cxx)
+TARGET_LINK_LIBRARIES(Executable Library)
+INSTALL(TARGETS Executable DESTINATION bin)
+
+# Use the bundle-generator for packaging ...
+SET(CPACK_GENERATOR "Bundle")
+SET(CPACK_BUNDLE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/BundleIcon.icns")
+SET(CPACK_BUNDLE_NAME "BundleGeneratorTest")
+SET(CPACK_BUNDLE_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Info.plist")
+SET(CPACK_BUNDLE_STARTUP_COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/StartupCommand")
+SET(CPACK_PACKAGE_DESCRIPTION "Project for testing OSX bundle generation")
+
+# The custom volume icon is a copy of the normal Mac OSX volume icon, but
+# on a white background. This is to differentiate it from the normal one
+# so that you can verify that the custom icon is being used by doing a
+# visual inspection of the mounted volume... This was added when fixing
+# issue #7523...
+#
+SET(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/CustomVolumeIcon.icns")
+
+SET(CPACK_PACKAGE_NAME "BundleGeneratorTest")
+SET(CPACK_PACKAGE_VERSION "0.1")
+
+INCLUDE(CPack)
diff --git a/Tests/BundleGeneratorTest/CustomVolumeIcon.icns b/Tests/BundleGeneratorTest/CustomVolumeIcon.icns
new file mode 100644
index 000000000..3862a5191
--- /dev/null
+++ b/Tests/BundleGeneratorTest/CustomVolumeIcon.icns
Binary files differ
diff --git a/Tests/BundleGeneratorTest/Executable.cxx b/Tests/BundleGeneratorTest/Executable.cxx
new file mode 100644
index 000000000..8107f783a
--- /dev/null
+++ b/Tests/BundleGeneratorTest/Executable.cxx
@@ -0,0 +1,8 @@
+extern void print_message(const char* const Message);
+
+int main(int argc, char* argv[])
+{
+ print_message("Howdy, World!\n");
+ return 0;
+}
+
diff --git a/Tests/BundleGeneratorTest/Info.plist b/Tests/BundleGeneratorTest/Info.plist
new file mode 100644
index 000000000..e5a7d0047
--- /dev/null
+++ b/Tests/BundleGeneratorTest/Info.plist
@@ -0,0 +1,14 @@
+<?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>CFBundleExecutable</key>
+ <string>BundleGeneratorTest</string>
+ <key>CFBundleIconFile</key>
+ <string>BundleGeneratorTest.icns</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ </dict>
+</plist>
diff --git a/Tests/BundleGeneratorTest/Library.cxx b/Tests/BundleGeneratorTest/Library.cxx
new file mode 100644
index 000000000..1403c6824
--- /dev/null
+++ b/Tests/BundleGeneratorTest/Library.cxx
@@ -0,0 +1,7 @@
+#include <iostream>
+
+void print_message(const char* const Message)
+{
+ std::cout << Message;
+}
+
diff --git a/Tests/BundleGeneratorTest/StartupCommand b/Tests/BundleGeneratorTest/StartupCommand
new file mode 100755
index 000000000..5bc5ad237
--- /dev/null
+++ b/Tests/BundleGeneratorTest/StartupCommand
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+BUNDLE="`echo "$0" | sed -e 's/\/Contents\/MacOS\/.*//'`"
+RESOURCES="$BUNDLE/Contents/Resources"
+
+echo "BUNDLE: $BUNDLE"
+echo "RESOURCES: $RESOURCES"
+
+export DYLD_LIBRARY_PATH=$RESOURCES/lib
+
+exec "$RESOURCES/bin/Executable"
+
diff --git a/Tests/BundleTest/BundleLib.cxx b/Tests/BundleTest/BundleLib.cxx
new file mode 100644
index 000000000..b68ee25dd
--- /dev/null
+++ b/Tests/BundleTest/BundleLib.cxx
@@ -0,0 +1,70 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+
+int fileExists(char* filename)
+{
+#ifndef R_OK
+# define R_OK 04
+#endif
+ if ( access(filename, R_OK) != 0 )
+ {
+ printf("Cannot find file: %s\n", filename);
+ return 0;
+ }
+ return 1;
+}
+
+int findBundleFile(char* exec, const char* file)
+{
+ int res;
+ char* nexec = strdup(exec);
+ char* fpath = (char*)malloc(strlen(exec) + 100);
+ int cc;
+ int cnt = 0;
+ printf("Process executable name: %s\n", exec);
+
+ // Remove the executable name and directory name
+ for ( cc = strlen(nexec)-1; cc > 0; cc -- )
+ {
+ if ( nexec[cc] == '/' )
+ {
+ nexec[cc] = 0;
+ if ( cnt == 1 )
+ {
+ break;
+ }
+ cnt ++;
+ }
+ }
+ printf("Process executable path: %s\n", nexec);
+ sprintf(fpath, "%s/%s", nexec, file);
+ printf("Check for file: %s\n", fpath);
+ res = fileExists(fpath);
+ free(nexec);
+ free(fpath);
+ return res;
+}
+
+int foo(char *exec)
+{
+ // Call a CoreFoundation function...
+ //
+ CFBundleRef br = CFBundleGetMainBundle();
+ (void) br;
+
+ int res1 = findBundleFile(exec, "Resources/randomResourceFile.plist");
+ int res2 = findBundleFile(exec, "MacOS/SomeRandomFile.txt");
+ int res3 = findBundleFile(exec, "MacOS/ChangeLog.txt");
+ if ( !res1 ||
+ !res2 ||
+ !res3 )
+ {
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/Tests/BundleTest/BundleSubDir/CMakeLists.txt b/Tests/BundleTest/BundleSubDir/CMakeLists.txt
new file mode 100644
index 000000000..322b2a7d2
--- /dev/null
+++ b/Tests/BundleTest/BundleSubDir/CMakeLists.txt
@@ -0,0 +1,36 @@
+ADD_CUSTOM_COMMAND(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/randomResourceFile.plist"
+ COMMAND /bin/cp
+ ARGS "${BundleTest_SOURCE_DIR}/randomResourceFile.plist.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/randomResourceFile.plist")
+
+SET_SOURCE_FILES_PROPERTIES(
+ "${CMAKE_CURRENT_BINARY_DIR}/randomResourceFile.plist"
+ PROPERTIES
+ MACOSX_PACKAGE_LOCATION Resources
+ )
+
+SET_SOURCE_FILES_PROPERTIES(
+ "${BundleTest_SOURCE_DIR}/SomeRandomFile.txt"
+ "${BundleTest_SOURCE_DIR}/../../ChangeLog.txt"
+ PROPERTIES
+ MACOSX_PACKAGE_LOCATION MacOS
+ )
+
+ADD_EXECUTABLE(SecondBundle
+ MACOSX_BUNDLE
+ "${BundleTest_SOURCE_DIR}/BundleTest.cxx"
+ "${BundleTest_SOURCE_DIR}/SomeRandomFile.txt"
+ "${BundleTest_SOURCE_DIR}/../../ChangeLog.txt"
+ "${CMAKE_CURRENT_BINARY_DIR}/randomResourceFile.plist"
+ )
+TARGET_LINK_LIBRARIES(SecondBundle BundleTestLib)
+
+# Test bundle installation.
+INSTALL(TARGETS SecondBundle DESTINATION Applications)
+
+# Test whether bundles respect the output name. Since the library is
+# installed into a location that uses this output name this will fail if the
+# bundle does not respect the name. Also the executable will not be found by
+# the test driver if this does not work.
+SET_TARGET_PROPERTIES(SecondBundle PROPERTIES OUTPUT_NAME SecondBundleExe)
diff --git a/Tests/BundleTest/BundleTest.cxx b/Tests/BundleTest/BundleTest.cxx
new file mode 100644
index 000000000..a66d601d3
--- /dev/null
+++ b/Tests/BundleTest/BundleTest.cxx
@@ -0,0 +1,20 @@
+#include <stdio.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+
+extern int foo(char* exec);
+
+int main(int argc, char* argv[])
+{
+ printf("Started with: %d arguments\n", argc);
+
+ // Call a CoreFoundation function... but pull in the link dependency on "-framework
+ // CoreFoundation" via CMake's dependency chaining mechanism. This code exists to
+ // verify that the chaining mechanism works with "-framework blah" style
+ // link dependencies.
+ //
+ CFBundleRef br = CFBundleGetMainBundle();
+ (void) br;
+
+ return foo(argv[0]);
+}
diff --git a/Tests/BundleTest/CMakeLists.txt b/Tests/BundleTest/CMakeLists.txt
new file mode 100644
index 000000000..5342f49bd
--- /dev/null
+++ b/Tests/BundleTest/CMakeLists.txt
@@ -0,0 +1,104 @@
+cmake_minimum_required (VERSION 2.6)
+PROJECT(BundleTest)
+SET(MACOSX_BUNDLE_INFO_STRING "bundle_info_string")
+SET(CMAKE_MacOSX_Content_COMPILE_OBJECT "\"${CMAKE_COMMAND}\" -E copy_if_different <SOURCE> <OBJECT>")
+
+ADD_CUSTOM_COMMAND(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/randomResourceFile.plist"
+ COMMAND /bin/cp
+ ARGS "${CMAKE_CURRENT_SOURCE_DIR}/randomResourceFile.plist.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/randomResourceFile.plist")
+
+SET_SOURCE_FILES_PROPERTIES(
+ "${CMAKE_CURRENT_BINARY_DIR}/randomResourceFile.plist"
+ PROPERTIES
+ MACOSX_PACKAGE_LOCATION Resources
+ )
+
+SET_SOURCE_FILES_PROPERTIES(
+ SomeRandomFile.txt
+ "${BundleTest_SOURCE_DIR}/../../ChangeLog.txt"
+ PROPERTIES
+ MACOSX_PACKAGE_LOCATION MacOS
+ )
+
+SET(EXECUTABLE_OUTPUT_PATH "${CMAKE_CURRENT_BINARY_DIR}/foobar")
+
+# Test building a bundle linking to a shared library where the
+# shared library links to CoreFoundation, but the executable does not
+# explicitly link to CoreFoundation, but the executable does *depend*
+# on CoreFoundation. There should be a link failure for the executable
+# if CMake's dependency chaining for libraries with "-framework
+# blah" style dependencies gets broken...
+#
+ADD_LIBRARY(BundleTestLib SHARED BundleLib.cxx)
+TARGET_LINK_LIBRARIES(BundleTestLib "-framework CoreFoundation")
+
+ADD_EXECUTABLE(BundleTest
+ MACOSX_BUNDLE
+ BundleTest.cxx
+ SomeRandomFile.txt
+ "${BundleTest_SOURCE_DIR}/../../ChangeLog.txt"
+ "${CMAKE_CURRENT_BINARY_DIR}/randomResourceFile.plist"
+ )
+TARGET_LINK_LIBRARIES(BundleTest BundleTestLib)
+#
+# DO NOT: TARGET_LINK_LIBRARIES(BundleTest "-framework CoreFoundation")
+# (see above comments about CoreFoundation)
+#
+
+# Test bundle installation.
+#INSTALL(TARGETS BundleTestLib DESTINATION Applications/BundleTestExe.app/Contents/Plugins)
+INSTALL(TARGETS BundleTestLib DESTINATION Applications/SecondBundleExe.app/Contents/Plugins)
+INSTALL(TARGETS BundleTest DESTINATION Applications)
+
+# Test whether bundles respect the output name. Since the library is
+# installed into a location that uses this output name this will fail if the
+# bundle does not respect the name. Also the executable will not be found by
+# the test driver if this does not work.
+SET_TARGET_PROPERTIES(BundleTest PROPERTIES OUTPUT_NAME BundleTestExe)
+
+# Test executable versioning if it is supported.
+IF(NOT XCODE)
+ SET_TARGET_PROPERTIES(BundleTest PROPERTIES VERSION 1)
+ENDIF(NOT XCODE)
+
+# Make sure the executable can find its installed library.
+SET_TARGET_PROPERTIES(BundleTestLib PROPERTIES
+ INSTALL_NAME_DIR "@executable_path/../Plugins")
+
+INCLUDE(CPack)
+
+# test the framework find stuff
+IF(EXISTS /usr/lib/libtcl.dylib
+ AND EXISTS /System/Library/Frameworks/Tcl.framework)
+ SET(TCL NOTFOUND)
+ FIND_LIBRARY(TCL tcl)
+ MESSAGE("frame: ${TCL}")
+ IF(NOT "${TCL}" MATCHES .framework)
+ MESSAGE(FATAL_ERROR "Could not find tcl framework, found ${TCL}")
+ ENDIF(NOT "${TCL}" MATCHES .framework)
+ SET(TCL NOTFOUND)
+ SET(CMAKE_FIND_FRAMEWORK LAST)
+ FIND_LIBRARY(TCL tcl)
+ IF("${TCL}" MATCHES .framework)
+ MESSAGE(FATAL_ERROR "Found framework and should have found dylib ${TCL}")
+ ENDIF("${TCL}" MATCHES .framework)
+ SET(TCL NOTFOUND)
+ SET(CMAKE_FIND_FRAMEWORK NEVER)
+ FIND_LIBRARY(TCL tcl)
+ IF("${TCL}" MATCHES .framework)
+ MESSAGE(FATAL_ERROR "Found framework and should have found dylib ${TCL}")
+ ENDIF("${TCL}" MATCHES .framework)
+ MESSAGE("not frame: ${TCL}")
+ SET(TCL NOTFOUND)
+ SET(CMAKE_FIND_FRAMEWORK FIRST)
+ FIND_LIBRARY(TCL tcl)
+ IF(NOT "${TCL}" MATCHES .framework)
+ MESSAGE(FATAL_ERROR "Could not find tcl framework, found ${TCL}")
+ ENDIF(NOT "${TCL}" MATCHES .framework)
+ MESSAGE("frame: ${TCL}")
+ENDIF(EXISTS /usr/lib/libtcl.dylib
+ AND EXISTS /System/Library/Frameworks/Tcl.framework)
+
+SUBDIRS(BundleSubDir)
diff --git a/Tests/BundleTest/SomeRandomFile.txt b/Tests/BundleTest/SomeRandomFile.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/BundleTest/SomeRandomFile.txt
diff --git a/Tests/BundleTest/randomResourceFile.plist.in b/Tests/BundleTest/randomResourceFile.plist.in
new file mode 100644
index 000000000..cfe3222b6
--- /dev/null
+++ b/Tests/BundleTest/randomResourceFile.plist.in
@@ -0,0 +1,9 @@
+<?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>Package</key>
+ <string>CMake</string>
+</dict>
+</plist>
+
diff --git a/Tests/BundleUtilities/CMakeLists.txt b/Tests/BundleUtilities/CMakeLists.txt
new file mode 100644
index 000000000..8f24afe9a
--- /dev/null
+++ b/Tests/BundleUtilities/CMakeLists.txt
@@ -0,0 +1,133 @@
+cmake_minimum_required(VERSION 2.8)
+project(BundleUtilities)
+
+###### the various types of dependencies we can have
+
+# a shared library
+add_library(shared SHARED shared.cpp shared.h)
+
+# another shared library
+add_library(shared2 SHARED shared2.cpp shared2.h)
+
+
+# a framework library
+add_library(framework SHARED framework.cpp framework.h)
+# TODO: fix problems with local frameworks without rpaths
+#set_target_properties(framework PROPERTIES FRAMEWORK 1)
+
+# make sure rpaths are not helping BundleUtilities or the executables
+set_target_properties(shared shared2 framework PROPERTIES
+ SKIP_BUILD_RPATH 1)
+
+
+###### test a Bundle application using dependencies
+
+# a loadable module (depends on shared2)
+# 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"
+ BUILD_WITH_INSTALL_RPATH 1)
+
+# add custom target to install and test the app
+add_custom_target(testbundleutils1_test ALL
+ COMMAND ${CMAKE_COMMAND}
+ "-DINPUT=${loc}"
+ "-DMODULE=${module_loc}"
+ "-DINPUTDIR=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}"
+ "-DOUTPUTDIR=${CMAKE_CURRENT_BINARY_DIR}/testdir1"
+ -P "${CMAKE_CURRENT_SOURCE_DIR}/bundleutils.cmake"
+ DEPENDS testbundleutils1 module1
+ )
+
+add_dependencies(testbundleutils1_test testbundleutils1)
+
+
+
+###### test a non-Bundle application using dependencies
+
+# a loadable module (depends on shared2)
+# 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"
+ BUILD_WITH_INSTALL_RPATH 1)
+
+# add custom target to install and test the app
+add_custom_target(testbundleutils2_test ALL
+ COMMAND ${CMAKE_COMMAND}
+ "-DINPUT=${loc}"
+ "-DMODULE=${module_loc}"
+ "-DINPUTDIR=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}"
+ "-DOUTPUTDIR=${CMAKE_CURRENT_BINARY_DIR}/testdir2"
+ -P "${CMAKE_CURRENT_SOURCE_DIR}/bundleutils.cmake"
+ DEPENDS testbundleutils1 module2
+ )
+add_dependencies(testbundleutils2_test testbundleutils2)
+
+
+if(APPLE AND NOT CMAKE_SYSTEM_VERSION VERSION_LESS 9.0)
+###### Test a Bundle application using dependencies
+###### and @rpaths on Mac OS X 10.5 or greater
+
+ # a shared library
+ add_library(shared-3 SHARED shared.cpp shared.h)
+
+ # another shared library
+ add_library(shared2-3 SHARED shared2.cpp shared2.h)
+
+ # a framework library
+ add_library(framework-3 SHARED framework.cpp framework.h)
+ set_target_properties(framework-3 PROPERTIES FRAMEWORK 1)
+
+ # build dependencies with @rpath install name
+ set_target_properties(shared-3 shared2-3 framework-3 PROPERTIES
+ INSTALL_NAME_DIR "@rpath"
+ BUILD_WITH_INSTALL_RPATH 1)
+
+ # a loadable module (depends on shared2)
+ # 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/")
+
+ # add custom target to install and test the app
+ add_custom_target(testbundleutils3_test ALL
+ COMMAND ${CMAKE_COMMAND}
+ "-DINPUT=${loc}"
+ "-DMODULE=${module_loc}"
+ "-DINPUTDIR=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}"
+ "-DOUTPUTDIR=${CMAKE_CURRENT_BINARY_DIR}/testdir3"
+ -P "${CMAKE_CURRENT_SOURCE_DIR}/bundleutils.cmake"
+ DEPENDS testbundleutils3 module3
+ )
+
+ add_dependencies(testbundleutils3_test testbundleutils3)
+endif()
diff --git a/Tests/BundleUtilities/bundleutils.cmake b/Tests/BundleUtilities/bundleutils.cmake
new file mode 100644
index 000000000..46765e733
--- /dev/null
+++ b/Tests/BundleUtilities/bundleutils.cmake
@@ -0,0 +1,45 @@
+
+# clean passed in arguments
+get_filename_component(INPUT ${INPUT} ABSOLUTE)
+get_filename_component(INPUTDIR ${INPUTDIR} ABSOLUTE)
+
+message("INPUT = ${INPUT}")
+message("MODULE = ${MODULE}")
+message("INPUTDIR = ${INPUTDIR}")
+message("OUTPUTDIR = ${OUTPUTDIR}")
+
+# compute location to install/test things
+file(RELATIVE_PATH relative_exe "${INPUTDIR}" "${INPUT}")
+set(OUTPUT "${OUTPUTDIR}/${relative_exe}")
+message("OUTPUT = ${OUTPUT}")
+get_filename_component(EXE_DIR "${OUTPUT}" PATH)
+get_filename_component(MODULE_NAME "${MODULE}" NAME)
+set(OUTPUT_MODULE "${EXE_DIR}/${MODULE_NAME}")
+message("OUTPUTMODULE = ${OUTPUT_MODULE}")
+
+# clean output dir
+file(REMOVE_RECURSE "${OUTPUTDIR}")
+# copy the app and plugin to installation/testing directory
+configure_file("${INPUT}" "${OUTPUT}" COPYONLY)
+configure_file("${MODULE}" "${OUTPUT_MODULE}" COPYONLY)
+
+# have BundleUtilities grab all dependencies and
+# check that the app runs
+
+# for this test we'll override location to put all dependencies
+# (in the same dir as the app)
+# this shouldn't be necessary except for the non-bundle case on Mac
+function(gp_item_default_embedded_path_override item path)
+ set(path "@executable_path" PARENT_SCOPE)
+endfunction(gp_item_default_embedded_path_override)
+
+include(BundleUtilities)
+fixup_bundle("${OUTPUT}" "${OUTPUT_MODULE}" "${INPUTDIR}")
+
+# make sure we can run the app
+message("Executing ${OUTPUT} in ${EXE_DIR}")
+execute_process(COMMAND "${OUTPUT}" RESULT_VARIABLE result OUTPUT_VARIABLE out ERROR_VARIABLE out WORKING_DIRECTORY "${EXE_DIR}")
+
+if(NOT result STREQUAL "0")
+ message(FATAL_ERROR " failed to execute test program\n${out}")
+endif(NOT result STREQUAL "0")
diff --git a/Tests/BundleUtilities/framework.cpp b/Tests/BundleUtilities/framework.cpp
new file mode 100644
index 000000000..abda195ed
--- /dev/null
+++ b/Tests/BundleUtilities/framework.cpp
@@ -0,0 +1,8 @@
+
+#include "framework.h"
+#include "stdio.h"
+
+void framework()
+{
+ printf("framework\n");
+}
diff --git a/Tests/BundleUtilities/framework.h b/Tests/BundleUtilities/framework.h
new file mode 100644
index 000000000..bdd10f05d
--- /dev/null
+++ b/Tests/BundleUtilities/framework.h
@@ -0,0 +1,17 @@
+
+#ifndef framework_h
+#define framework_h
+
+#ifdef WIN32
+# ifdef framework_EXPORTS
+# define FRAMEWORK_EXPORT __declspec(dllexport)
+# else
+# define FRAMEWORK_EXPORT __declspec(dllimport)
+# endif
+#else
+# define FRAMEWORK_EXPORT
+#endif
+
+void FRAMEWORK_EXPORT framework();
+
+#endif
diff --git a/Tests/BundleUtilities/module.cpp b/Tests/BundleUtilities/module.cpp
new file mode 100644
index 000000000..ee1b542fb
--- /dev/null
+++ b/Tests/BundleUtilities/module.cpp
@@ -0,0 +1,10 @@
+
+#include "module.h"
+#include "stdio.h"
+#include "shared2.h"
+
+void module()
+{
+ printf("module\n");
+ shared2();
+}
diff --git a/Tests/BundleUtilities/module.h b/Tests/BundleUtilities/module.h
new file mode 100644
index 000000000..0659bc742
--- /dev/null
+++ b/Tests/BundleUtilities/module.h
@@ -0,0 +1,7 @@
+
+#ifndef module_h
+#define module_h
+
+void module();
+
+#endif
diff --git a/Tests/BundleUtilities/shared.cpp b/Tests/BundleUtilities/shared.cpp
new file mode 100644
index 000000000..e5e7dc5ae
--- /dev/null
+++ b/Tests/BundleUtilities/shared.cpp
@@ -0,0 +1,8 @@
+
+#include "shared.h"
+#include "stdio.h"
+
+void shared()
+{
+ printf("shared\n");
+}
diff --git a/Tests/BundleUtilities/shared.h b/Tests/BundleUtilities/shared.h
new file mode 100644
index 000000000..3588fb88e
--- /dev/null
+++ b/Tests/BundleUtilities/shared.h
@@ -0,0 +1,17 @@
+
+#ifndef shared_h
+#define shared_h
+
+#ifdef WIN32
+# ifdef shared_EXPORTS
+# define SHARED_EXPORT __declspec(dllexport)
+# else
+# define SHARED_EXPORT __declspec(dllimport)
+# endif
+#else
+# define SHARED_EXPORT
+#endif
+
+void SHARED_EXPORT shared();
+
+#endif
diff --git a/Tests/BundleUtilities/shared2.cpp b/Tests/BundleUtilities/shared2.cpp
new file mode 100644
index 000000000..84af5d061
--- /dev/null
+++ b/Tests/BundleUtilities/shared2.cpp
@@ -0,0 +1,8 @@
+
+#include "shared2.h"
+#include "stdio.h"
+
+void shared2()
+{
+ printf("shared2\n");
+}
diff --git a/Tests/BundleUtilities/shared2.h b/Tests/BundleUtilities/shared2.h
new file mode 100644
index 000000000..d53546cb0
--- /dev/null
+++ b/Tests/BundleUtilities/shared2.h
@@ -0,0 +1,17 @@
+
+#ifndef shared2_h
+#define shared2_h
+
+#ifdef WIN32
+# ifdef shared2_EXPORTS
+# define SHARED2_EXPORT __declspec(dllexport)
+# else
+# define SHARED2_EXPORT __declspec(dllimport)
+# endif
+#else
+# define SHARED2_EXPORT
+#endif
+
+void SHARED2_EXPORT shared2();
+
+#endif
diff --git a/Tests/BundleUtilities/testbundleutils1.cpp b/Tests/BundleUtilities/testbundleutils1.cpp
new file mode 100644
index 000000000..23d3cbd2e
--- /dev/null
+++ b/Tests/BundleUtilities/testbundleutils1.cpp
@@ -0,0 +1,33 @@
+
+#include "framework.h"
+#include "shared.h"
+#include "stdio.h"
+
+#if defined(WIN32)
+#include <windows.h>
+#else
+#include "dlfcn.h"
+#endif
+
+int main(int, char**)
+{
+ framework();
+ shared();
+
+#if defined(WIN32)
+ HANDLE lib = LoadLibraryA("module1.dll");
+ if(!lib)
+ {
+ printf("Failed to open module1\n");
+ }
+#else
+ void* lib = dlopen("module1.so", RTLD_LAZY);
+ if(!lib)
+ {
+ printf("Failed to open module1\n%s\n", dlerror());
+ }
+#endif
+
+
+ return lib == 0 ? 1 : 0;
+}
diff --git a/Tests/BundleUtilities/testbundleutils2.cpp b/Tests/BundleUtilities/testbundleutils2.cpp
new file mode 100644
index 000000000..319be8984
--- /dev/null
+++ b/Tests/BundleUtilities/testbundleutils2.cpp
@@ -0,0 +1,33 @@
+
+#include "framework.h"
+#include "shared.h"
+#include "stdio.h"
+
+#if defined(WIN32)
+#include <windows.h>
+#else
+#include "dlfcn.h"
+#endif
+
+int main(int, char**)
+{
+ framework();
+ shared();
+
+#if defined(WIN32)
+ HANDLE lib = LoadLibraryA("module2.dll");
+ if(!lib)
+ {
+ printf("Failed to open module2\n");
+ }
+#else
+ void* lib = dlopen("module2.so", RTLD_LAZY);
+ if(!lib)
+ {
+ printf("Failed to open module2\n%s\n", dlerror());
+ }
+#endif
+
+
+ return lib == 0 ? 1 : 0;
+}
diff --git a/Tests/BundleUtilities/testbundleutils3.cpp b/Tests/BundleUtilities/testbundleutils3.cpp
new file mode 100644
index 000000000..9df13e988
--- /dev/null
+++ b/Tests/BundleUtilities/testbundleutils3.cpp
@@ -0,0 +1,33 @@
+
+#include "framework.h"
+#include "shared.h"
+#include "stdio.h"
+
+#if defined(WIN32)
+#include <windows.h>
+#else
+#include "dlfcn.h"
+#endif
+
+int main(int, char**)
+{
+ framework();
+ shared();
+
+#if defined(WIN32)
+ HANDLE lib = LoadLibraryA("module3.dll");
+ if(!lib)
+ {
+ printf("Failed to open module3\n");
+ }
+#else
+ void* lib = dlopen("module3.so", RTLD_LAZY);
+ if(!lib)
+ {
+ printf("Failed to open module3\n%s\n", dlerror());
+ }
+#endif
+
+
+ return lib == 0 ? 1 : 0;
+}
diff --git a/Tests/CFBundleTest/CMakeLists.txt b/Tests/CFBundleTest/CMakeLists.txt
new file mode 100644
index 000000000..8fd9efdc6
--- /dev/null
+++ b/Tests/CFBundleTest/CMakeLists.txt
@@ -0,0 +1,56 @@
+#this is adapted from FireBreath (http://www.firebreath.org)
+
+cmake_minimum_required(VERSION 2.8)
+
+project(CFBundleTest)
+
+include(PluginConfig.cmake)
+
+message ("Creating Mac Browser Plugin project ${PROJECT_NAME}")
+set(SOURCES
+ np_macmain.cpp
+ Localized.r
+ ${CMAKE_CURRENT_BINARY_DIR}/Info.plist
+ ${CMAKE_CURRENT_BINARY_DIR}/InfoPlist.strings
+ ${CMAKE_CURRENT_BINARY_DIR}/Localized.rsrc
+)
+
+add_library( ${PROJECT_NAME} MODULE
+ ${SOURCES}
+ )
+
+set (RCFILES ${CMAKE_CURRENT_SOURCE_DIR}/Localized.r)
+
+configure_file(Info.plist.in ${CMAKE_CURRENT_BINARY_DIR}/Info.plist)
+configure_file(InfoPlist.strings.in ${CMAKE_CURRENT_BINARY_DIR}/InfoPlist.strings)
+
+# Compile the resource file
+find_program(RC_COMPILER Rez NO_DEFAULT_PATHS PATHS /Developer/Tools)
+if(NOT RC_COMPILER)
+ message(FATAL_ERROR "could not find Rez to build resources from .r file...")
+endif()
+
+execute_process(COMMAND
+ ${RC_COMPILER} ${RCFILES} -useDF -o ${CMAKE_CURRENT_BINARY_DIR}/Localized.rsrc
+ )
+
+set_source_files_properties(
+ ${CMAKE_CURRENT_BINARY_DIR}/Localized.rsrc
+ PROPERTIES GENERATED 1
+ )
+# note that for some reason, the makefile and xcode generators use a different
+# property to indicate where the Info.plist file is :-/ For that reason, we
+# specify it twice so it will work both places
+set_target_properties(CFBundleTest PROPERTIES
+ BUNDLE 1
+ BUNDLE_EXTENSION plugin
+ XCODE_ATTRIBUTE_WRAPPER_EXTENSION plugin #sets the extension to .plugin
+ XCODE_ATTRIBUTE_MACH_O_TYPE mh_bundle
+ XCODE_ATTRIBUTE_INFOPLIST_FILE ${CMAKE_CURRENT_BINARY_DIR}/Info.plist
+ MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_BINARY_DIR}/Info.plist
+ LINK_FLAGS "-Wl,-exported_symbols_list,\"${CMAKE_CURRENT_SOURCE_DIR}/ExportList_plugin.txt\"")
+
+set_source_files_properties(
+ ${CMAKE_CURRENT_BINARY_DIR}/InfoPlist.strings
+ ${CMAKE_CURRENT_BINARY_DIR}/Localized.rsrc
+ PROPERTIES MACOSX_PACKAGE_LOCATION "Resources/English.lproj")
diff --git a/Tests/CFBundleTest/ExportList_plugin.txt b/Tests/CFBundleTest/ExportList_plugin.txt
new file mode 100644
index 000000000..31d6f640d
--- /dev/null
+++ b/Tests/CFBundleTest/ExportList_plugin.txt
@@ -0,0 +1,3 @@
+_NP_GetEntryPoints
+_NP_Initialize
+_NP_Shutdown
diff --git a/Tests/CFBundleTest/Info.plist.in b/Tests/CFBundleTest/Info.plist.in
new file mode 100644
index 000000000..638002f34
--- /dev/null
+++ b/Tests/CFBundleTest/Info.plist.in
@@ -0,0 +1,54 @@
+<?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>English</string>
+ <key>CFBundleExecutable</key>
+ <string>${PLUGIN_NAME}</string>
+ <key>CFBundleGetInfoString</key>
+ <string>${PLUGIN_NAME} ${FBSTRING_PLUGIN_VERSION}, ${FBSTRING_LegalCopyright}</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.${ACTIVEX_PROGID}</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>BRPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>${PLUGIN_NAME} ${FBSTRING_PLUGIN_VERSION}</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>${FBSTRING_PLUGIN_VERSION}</string>
+ <key>CFPlugInDynamicRegisterFunction</key>
+ <string></string>
+ <key>CFPlugInDynamicRegistration</key>
+ <string>NO</string>
+ <key>CFPlugInFactories</key>
+ <dict>
+ <key>00000000-0000-0000-0000-000000000000</key>
+ <string>MyFactoryFunction</string>
+ </dict>
+ <key>CFPlugInTypes</key>
+ <dict>
+ <key>00000000-0000-0000-0000-000000000000</key>
+ <array>
+ <string>00000000-0000-0000-0000-000000000000</string>
+ </array>
+ </dict>
+ <key>CFPlugInUnloadFunction</key>
+ <string></string>
+ <key>WebPluginName</key>
+ <string>${FBSTRING_ProductName}</string>
+ <key>WebPluginDescription</key>
+ <string>${FBSTRING_FileDescription}</string>
+ <key>WebPluginMIMETypes</key>
+ <dict>
+ <key>${FBSTRING_MIMEType}</key>
+ <dict>
+ <key>WebPluginTypeDescription</key>
+ <string>${FBSTRING_FileDescription}</string>
+ </dict>
+ </dict>
+</dict>
+</plist>
diff --git a/Tests/CFBundleTest/InfoPlist.strings.in b/Tests/CFBundleTest/InfoPlist.strings.in
new file mode 100644
index 000000000..790ead05d
--- /dev/null
+++ b/Tests/CFBundleTest/InfoPlist.strings.in
@@ -0,0 +1,4 @@
+/* Localized versions of Info.plist keys */
+
+CFBundleName = "${PLUGIN_NAME}.plugin";
+NSHumanReadableCopyright = "${FBSTRING_LegalCopyright}";
diff --git a/Tests/CFBundleTest/Localized.r b/Tests/CFBundleTest/Localized.r
new file mode 100644
index 000000000..e988e262c
--- /dev/null
+++ b/Tests/CFBundleTest/Localized.r
@@ -0,0 +1,18 @@
+#include <CoreServices/CoreServices.r>
+
+resource 'STR#' (126)
+{ {
+ "${FBSTRING_LegalCopyright}",
+ "${FBSTRING_ProductName}"
+} };
+
+resource 'STR#' (127)
+{ {
+ "${FBSTRING_FileDescription}"
+} };
+
+resource 'STR#' (128)
+{ {
+ "${FBSTRING_MIMEType}",
+ "${FBSTRING_FileExtents}"
+} };
diff --git a/Tests/CFBundleTest/Localized.rsrc b/Tests/CFBundleTest/Localized.rsrc
new file mode 100644
index 000000000..cbf35235b
--- /dev/null
+++ b/Tests/CFBundleTest/Localized.rsrc
Binary files differ
diff --git a/Tests/CFBundleTest/PluginConfig.cmake b/Tests/CFBundleTest/PluginConfig.cmake
new file mode 100644
index 000000000..763ddcc1c
--- /dev/null
+++ b/Tests/CFBundleTest/PluginConfig.cmake
@@ -0,0 +1,21 @@
+#/**********************************************************\
+# Auto-Generated Plugin Configuration file
+# for CFTestPlugin
+#\**********************************************************/
+
+set(PLUGIN_NAME "CFTestPlugin")
+set(PLUGIN_PREFIX "CFTP")
+set(COMPANY_NAME "FBDevTeam")
+
+set(MOZILLA_PLUGINID "@firebreath.googlecode.com/CFTestPlugin")
+
+# strings
+set(FBSTRING_CompanyName "Firebreath Dev Team")
+set(FBSTRING_FileDescription "CFBundle Test Plugin - Plugin for testing cmake patch to improve FireBreath project generation")
+set(FBSTRING_PLUGIN_VERSION "1.0.0")
+set(FBSTRING_LegalCopyright "Copyright 2010 Firebreath Dev Team")
+set(FBSTRING_PluginFileName "np${PLUGIN_NAME}.dll")
+set(FBSTRING_ProductName "CFTestPlugin")
+set(FBSTRING_FileExtents "")
+set(FBSTRING_PluginName "CFTestPlugin")
+set(FBSTRING_MIMEType "application/x-fbtestplugin")
diff --git a/Tests/CFBundleTest/README.txt b/Tests/CFBundleTest/README.txt
new file mode 100644
index 000000000..86c146333
--- /dev/null
+++ b/Tests/CFBundleTest/README.txt
@@ -0,0 +1,16 @@
+
+CFBundle test project. The generated .plugin/ bundle from either makefiles or Xcode should look like this:
+
+./Contents
+./Contents/Info.plist
+./Contents/MacOS
+./Contents/MacOS/CFBundleTest
+./Contents/Resources
+./Contents/Resources/English.lproj
+./Contents/Resources/English.lproj/InfoPlist.strings
+./Contents/Resources/English.lproj/Localized.rsrc
+
+file Contents/MacOS/CFBundleTest should return something like:
+Contents/MacOS/CFBundleTest: Mach-O 64-bit bundle x86_64
+
+It is okay if it is a 32 bit binary; if it is not Mach-O, or is spelled differently, it is not okay.
diff --git a/Tests/CFBundleTest/VerifyResult.cmake b/Tests/CFBundleTest/VerifyResult.cmake
new file mode 100644
index 000000000..e62290052
--- /dev/null
+++ b/Tests/CFBundleTest/VerifyResult.cmake
@@ -0,0 +1,32 @@
+if(NOT DEFINED CTEST_CONFIGURATION_TYPE)
+ message(FATAL_ERROR "expected variable CTEST_CONFIGURATION_TYPE not defined")
+endif()
+
+if(NOT DEFINED dir)
+ message(FATAL_ERROR "expected variable dir not defined")
+endif()
+
+if(NOT DEFINED gen)
+ message(FATAL_ERROR "expected variable gen not defined")
+endif()
+
+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()
+ set(expected_filename "${dir}/${CTEST_CONFIGURATION_TYPE}/CFBundleTest.plugin/Contents/MacOS/CFBundleTest")
+endif()
+
+if(NOT EXISTS "${expected_filename}")
+ message(FATAL_ERROR "test fails: expected output file does not exist [${expected_filename}]")
+endif()
+
+file(COPY "${expected_filename}"
+ DESTINATION "${dir}/LatestBuildResult"
+ )
diff --git a/Tests/CFBundleTest/np_macmain.cpp b/Tests/CFBundleTest/np_macmain.cpp
new file mode 100644
index 000000000..78004d002
--- /dev/null
+++ b/Tests/CFBundleTest/np_macmain.cpp
@@ -0,0 +1,49 @@
+/***********************************************************\
+ Written by: Richard Bateman (taxilian)
+
+ Based on the default np_macmain.cpp from FireBreath
+ http://firebreath.googlecode.com
+
+ This file has been stripped to prevent it from accidently
+ doing anything useful.
+\***********************************************************/
+
+
+#include <stdio.h>
+
+typedef void (*NPP_ShutdownProcPtr)(void);
+typedef short NPError;
+
+#pragma GCC visibility push(default)
+
+struct NPNetscapeFuncs;
+struct NPPluginFuncs;
+
+extern "C" {
+ NPError NP_Initialize(NPNetscapeFuncs *browserFuncs);
+ NPError NP_GetEntryPoints(NPPluginFuncs *pluginFuncs);
+ NPError NP_Shutdown(void);
+}
+
+#pragma GCC visibility pop
+
+void initPluginModule()
+{
+}
+
+NPError NP_GetEntryPoints(NPPluginFuncs* pFuncs)
+{
+ printf("NP_GetEntryPoints()\n");
+ return 0;
+}
+
+NPError NP_Initialize(NPNetscapeFuncs* pFuncs)
+{
+ printf("NP_Initialize()\n");
+ return 0;
+}
+
+NPError NP_Shutdown()
+{
+ return 0;
+}
diff --git a/Tests/CMakeBuildTest.cmake.in b/Tests/CMakeBuildTest.cmake.in
new file mode 100644
index 000000000..a8bb75090
--- /dev/null
+++ b/Tests/CMakeBuildTest.cmake.in
@@ -0,0 +1,59 @@
+# create the binary directory
+make_directory("@CMAKE_BUILD_TEST_BINARY_DIR@")
+
+# remove the CMakeCache.txt file from the source dir
+# if there is one, so that in-source cmake tests
+# still pass
+message("Remove: @CMAKE_BUILD_TEST_SOURCE_DIR@/CMakeCache.txt")
+file(REMOVE "@CMAKE_BUILD_TEST_SOURCE_DIR@/CMakeCache.txt")
+
+# run cmake in the binary directory
+message("running: ${CMAKE_COMMAND}")
+execute_process(COMMAND "${CMAKE_COMMAND}"
+ "@CMAKE_BUILD_TEST_SOURCE_DIR@"
+ "-G@CMAKE_TEST_GENERATOR@"
+ WORKING_DIRECTORY "@CMAKE_BUILD_TEST_BINARY_DIR@"
+ RESULT_VARIABLE RESULT)
+if(RESULT)
+ message(FATAL_ERROR "Error running cmake command")
+endif(RESULT)
+
+# Now use the --build option to build the project
+message("running: ${CMAKE_COMMAND} --build")
+execute_process(COMMAND "${CMAKE_COMMAND}"
+ --build "@CMAKE_BUILD_TEST_BINARY_DIR@" --config Debug
+ RESULT_VARIABLE RESULT)
+if(RESULT)
+ message(FATAL_ERROR "Error running cmake --build")
+endif(RESULT)
+
+# check for configuration types
+set(CMAKE_CONFIGURATION_TYPES @CMAKE_CONFIGURATION_TYPES@)
+# run the executable out of the Debug directory if there
+# are configuration types
+if(CMAKE_CONFIGURATION_TYPES)
+ set(RUN_TEST "@CMAKE_BUILD_TEST_BINARY_DIR@/Debug/@CMAKE_BUILD_TEST_EXE@")
+else(CMAKE_CONFIGURATION_TYPES)
+ set(RUN_TEST "@CMAKE_BUILD_TEST_BINARY_DIR@/@CMAKE_BUILD_TEST_EXE@")
+endif(CMAKE_CONFIGURATION_TYPES)
+# run the test results
+message("running [${RUN_TEST}]")
+execute_process(COMMAND "${RUN_TEST}" RESULT_VARIABLE RESULT)
+if(RESULT)
+ message(FATAL_ERROR "Error running test @CMAKE_BUILD_TEST_EXE@")
+endif(RESULT)
+
+# build it again with clean and only @CMAKE_BUILD_TEST_EXE@ target
+execute_process(COMMAND "${CMAKE_COMMAND}"
+ --build "@CMAKE_BUILD_TEST_BINARY_DIR@" --config Debug
+ --clean-first --target @CMAKE_BUILD_TEST_EXE@
+ RESULT_VARIABLE RESULT)
+if(RESULT)
+ message(FATAL_ERROR "Error running cmake --build")
+endif(RESULT)
+
+# run it again after clean
+execute_process(COMMAND "${RUN_TEST}" RESULT_VARIABLE RESULT)
+if(RESULT)
+ message(FATAL_ERROR "Error running test @CMAKE_BUILD_TEST_EXE@ after clean ")
+endif(RESULT)
diff --git a/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt b/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt
new file mode 100644
index 000000000..1faa88848
--- /dev/null
+++ b/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt
@@ -0,0 +1,58 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(target_link_libraries)
+
+file(WRITE
+ "${CMAKE_CURRENT_BINARY_DIR}/main.cxx"
+ "int main() { return 0; }
+"
+)
+
+add_executable(
+ target_link_libraries
+ "${CMAKE_CURRENT_BINARY_DIR}/main.cxx"
+)
+
+macro(ASSERT_PROPERTY _target _property _value)
+ get_target_property(_out ${_target} ${_property})
+ if (NOT _out)
+ set(_out "")
+ endif()
+ if (NOT "${_out}" STREQUAL "${_value}")
+ message(SEND_ERROR "Target ${_target} does not have property ${_property} with value ${_value}. Actual value: ${_out}")
+ endif()
+endmacro()
+
+include(GenerateExportHeader)
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+add_library(depA SHARED depA.cpp)
+generate_export_header(depA)
+
+add_library(depB SHARED depB.cpp)
+generate_export_header(depB)
+
+target_link_libraries(depB LINK_PRIVATE depA)
+
+add_library(depC SHARED depC.cpp)
+generate_export_header(depC)
+
+target_link_libraries(depC LINK_PUBLIC depA)
+
+assert_property(depA LINK_INTERFACE_LIBRARIES "")
+assert_property(depB LINK_INTERFACE_LIBRARIES "")
+assert_property(depC LINK_INTERFACE_LIBRARIES "depA")
+
+add_executable(targetA targetA.cpp)
+
+target_link_libraries(targetA LINK_INTERFACE_LIBRARIES depA depB)
+
+assert_property(targetA LINK_INTERFACE_LIBRARIES "depA;depB")
+
+set_target_properties(targetA PROPERTIES LINK_INTERFACE_LIBRARIES "")
+
+assert_property(targetA LINK_INTERFACE_LIBRARIES "")
+
+target_link_libraries(targetA depB depC)
+
+assert_property(targetA LINK_INTERFACE_LIBRARIES "")
diff --git a/Tests/CMakeCommands/target_link_libraries/depA.cpp b/Tests/CMakeCommands/target_link_libraries/depA.cpp
new file mode 100644
index 000000000..c2e8e7b9a
--- /dev/null
+++ b/Tests/CMakeCommands/target_link_libraries/depA.cpp
@@ -0,0 +1,7 @@
+
+#include "depA.h"
+
+int DepA::foo()
+{
+ return 0;
+}
diff --git a/Tests/CMakeCommands/target_link_libraries/depA.h b/Tests/CMakeCommands/target_link_libraries/depA.h
new file mode 100644
index 000000000..7a859488b
--- /dev/null
+++ b/Tests/CMakeCommands/target_link_libraries/depA.h
@@ -0,0 +1,7 @@
+
+#include "depa_export.h"
+
+struct DEPA_EXPORT DepA
+{
+ int foo();
+};
diff --git a/Tests/CMakeCommands/target_link_libraries/depB.cpp b/Tests/CMakeCommands/target_link_libraries/depB.cpp
new file mode 100644
index 000000000..97e5be274
--- /dev/null
+++ b/Tests/CMakeCommands/target_link_libraries/depB.cpp
@@ -0,0 +1,11 @@
+
+#include "depB.h"
+
+#include "depA.h"
+
+int DepB::foo()
+{
+ DepA a;
+
+ return 0;
+}
diff --git a/Tests/CMakeCommands/target_link_libraries/depB.h b/Tests/CMakeCommands/target_link_libraries/depB.h
new file mode 100644
index 000000000..e617813ba
--- /dev/null
+++ b/Tests/CMakeCommands/target_link_libraries/depB.h
@@ -0,0 +1,7 @@
+
+#include "depb_export.h"
+
+struct DEPB_EXPORT DepB
+{
+ int foo();
+};
diff --git a/Tests/CMakeCommands/target_link_libraries/depC.cpp b/Tests/CMakeCommands/target_link_libraries/depC.cpp
new file mode 100644
index 000000000..60bed592f
--- /dev/null
+++ b/Tests/CMakeCommands/target_link_libraries/depC.cpp
@@ -0,0 +1,13 @@
+
+#include "depC.h"
+
+int DepC::foo()
+{
+ return 0;
+}
+
+DepA DepC::getA()
+{
+ DepA a;
+ return a;
+}
diff --git a/Tests/CMakeCommands/target_link_libraries/depC.h b/Tests/CMakeCommands/target_link_libraries/depC.h
new file mode 100644
index 000000000..4d65c9eb3
--- /dev/null
+++ b/Tests/CMakeCommands/target_link_libraries/depC.h
@@ -0,0 +1,12 @@
+
+#include "depc_export.h"
+
+#include "depA.h"
+
+struct DEPC_EXPORT DepC
+{
+ int foo();
+
+ DepA getA();
+
+};
diff --git a/Tests/CMakeCommands/target_link_libraries/targetA.cpp b/Tests/CMakeCommands/target_link_libraries/targetA.cpp
new file mode 100644
index 000000000..3c6472e9a
--- /dev/null
+++ b/Tests/CMakeCommands/target_link_libraries/targetA.cpp
@@ -0,0 +1,12 @@
+
+#include "depB.h"
+#include "depC.h"
+
+int main(int argc, char **argv)
+{
+ DepA a;
+ DepB b;
+ DepC c;
+
+ return a.foo() + b.foo() + c.foo();
+}
diff --git a/Tests/CMakeInstall.cmake b/Tests/CMakeInstall.cmake
new file mode 100644
index 000000000..5f814d91b
--- /dev/null
+++ b/Tests/CMakeInstall.cmake
@@ -0,0 +1,51 @@
+# Define option CMake_TEST_INSTALL, and enable by default for dashboards.
+set(_default 0)
+if(DEFINED ENV{DASHBOARD_TEST_FROM_CTEST})
+ set(_default 1)
+endif()
+option(CMake_TEST_INSTALL "Test CMake Installation" ${_default})
+mark_as_advanced(CMake_TEST_INSTALL)
+
+if(CMake_TEST_INSTALL)
+ # Do not build during the test.
+ set(CMAKE_SKIP_INSTALL_ALL_DEPENDENCY 1)
+
+ # Install to a test directory.
+ set(CMake_TEST_INSTALL_PREFIX ${CMake_BINARY_DIR}/Tests/CMakeInstall)
+ set(CMAKE_INSTALL_PREFIX "${CMake_TEST_INSTALL_PREFIX}")
+
+ 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}")
+ 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)
+
+ # Avoid running this test simultaneously with other tests:
+ set_tests_properties(CMake.Install PROPERTIES RUN_SERIAL ON)
+
+ # TODO: Make all other tests depend on this one, and then drive them
+ # with the installed CTest.
+else()
+ set(CMake_TEST_INSTALL_PREFIX)
+endif()
diff --git a/Tests/CMakeLib/CMakeLists.txt b/Tests/CMakeLib/CMakeLists.txt
new file mode 100644
index 000000000..4e819f470
--- /dev/null
+++ b/Tests/CMakeLib/CMakeLists.txt
@@ -0,0 +1,39 @@
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMake_BINARY_DIR}/Source
+ ${CMake_SOURCE_DIR}/Source
+ )
+
+set(CMakeLib_TESTS
+ testGeneratedFileStream
+ testSystemTools
+ testUTF8
+ testXMLParser
+ testXMLSafe
+ )
+
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/testXMLParser.h.in
+ ${CMAKE_CURRENT_BINARY_DIR}/testXMLParser.h @ONLY)
+
+create_test_sourcelist(CMakeLib_TEST_SRCS CMakeLibTests.cxx ${CMakeLib_TESTS})
+add_executable(CMakeLibTests ${CMakeLib_TEST_SRCS})
+target_link_libraries(CMakeLibTests 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 CMakeLibTests
+ PRE_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CFG_INTDIR}"
+ )
+endif()
+
+foreach(test ${CMakeLib_TESTS})
+ add_test(CMakeLib.${test} CMakeLibTests ${test})
+endforeach()
+
+if(TEST_CompileCommandOutput)
+ add_executable(runcompilecommands run_compile_commands.cxx)
+ target_link_libraries(runcompilecommands CMakeLib)
+endif()
diff --git a/Tests/CMakeLib/run_compile_commands.cxx b/Tests/CMakeLib/run_compile_commands.cxx
new file mode 100644
index 000000000..dc1ce24f7
--- /dev/null
+++ b/Tests/CMakeLib/run_compile_commands.cxx
@@ -0,0 +1,141 @@
+#include "cmSystemTools.h"
+
+class CompileCommandParser {
+public:
+ class CommandType: public std::map<cmStdString, cmStdString>
+ {
+ public:
+ cmStdString const& at(cmStdString const& k) const
+ {
+ const_iterator i = this->find(k);
+ if(i != this->end()) { return i->second; }
+ static cmStdString emptyString;
+ return emptyString;
+ }
+ };
+ typedef std::vector<CommandType> TranslationUnitsType;
+
+ CompileCommandParser(std::ifstream *input)
+ {
+ this->Input = input;
+ }
+
+ void Parse()
+ {
+ NextNonWhitespace();
+ ParseTranslationUnits();
+ }
+
+ const TranslationUnitsType& GetTranslationUnits()
+ {
+ return this->TranslationUnits;
+ }
+
+private:
+ void ParseTranslationUnits()
+ {
+ this->TranslationUnits = TranslationUnitsType();
+ ExpectOrDie('[', "at start of compile command file\n");
+ do
+ {
+ ParseTranslationUnit();
+ this->TranslationUnits.push_back(this->Command);
+ } while(Expect(','));
+ ExpectOrDie(']', "at end of array");
+ }
+
+ void ParseTranslationUnit()
+ {
+ this->Command = CommandType();
+ if(!Expect('{')) return;
+ if(Expect('}')) return;
+ do
+ {
+ ParseString();
+ std::string name = this->String;
+ ExpectOrDie(':', "between name and value");
+ ParseString();
+ std::string value = this->String;
+ this->Command[name] = value;
+ } while(Expect(','));
+ ExpectOrDie('}', "at end of object");
+ }
+
+ void ParseString()
+ {
+ this->String = "";
+ if(!Expect('"')) return;
+ while (!Expect('"'))
+ {
+ Expect('\\');
+ this->String.append(1,C);
+ Next();
+ }
+ }
+
+ bool Expect(char c)
+ {
+ if(this->C == c)
+ {
+ NextNonWhitespace();
+ return true;
+ }
+ return false;
+ }
+
+ void ExpectOrDie(char c, const std::string & message)
+ {
+ if (!Expect(c))
+ ErrorExit(std::string("'") + c + "' expected " + message + ".");
+ }
+
+ void NextNonWhitespace()
+ {
+ do { Next(); } while (IsWhitespace());
+ }
+
+ void Next()
+ {
+ this->C = char(Input->get());
+ if (this->Input->bad()) ErrorExit("Unexpected end of file.");
+ }
+
+ void ErrorExit(const std::string &message) {
+ std::cout << "ERROR: " << message;
+ exit(1);
+ }
+
+ bool IsWhitespace()
+ {
+ return (this->C == ' ' || this->C == '\t' ||
+ this->C == '\n' || this->C == '\r');
+ }
+
+ char C;
+ TranslationUnitsType TranslationUnits;
+ CommandType Command;
+ std::string String;
+ std::ifstream *Input;
+};
+
+int main ()
+{
+ std::ifstream file("compile_commands.json");
+ CompileCommandParser parser(&file);
+ parser.Parse();
+ for(CompileCommandParser::TranslationUnitsType::const_iterator
+ it = parser.GetTranslationUnits().begin(),
+ end = parser.GetTranslationUnits().end(); it != end; ++it)
+ {
+ std::vector<cmStdString> command;
+ cmSystemTools::ParseUnixCommandLine(it->at("command").c_str(), command);
+ if (!cmSystemTools::RunSingleCommand(
+ command, 0, 0, it->at("directory").c_str()))
+ {
+ std::cout << "ERROR: Failed to run command \""
+ << command[0] << "\"" << std::endl;
+ exit(1);
+ }
+ }
+ return 0;
+}
diff --git a/Tests/CMakeLib/testGeneratedFileStream.cxx b/Tests/CMakeLib/testGeneratedFileStream.cxx
new file mode 100644
index 000000000..f8ca4af94
--- /dev/null
+++ b/Tests/CMakeLib/testGeneratedFileStream.cxx
@@ -0,0 +1,100 @@
+/*============================================================================
+ 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.
+============================================================================*/
+#include "cmGeneratedFileStream.h"
+#include "cmSystemTools.h"
+
+#define cmFailed(m1, m2) \
+ std::cout << "FAILED: " << m1 << m2 << "\n"; failed=1
+
+int testGeneratedFileStream(int, char*[])
+{
+ int failed = 0;
+ cmGeneratedFileStream gm;
+ std::string file1 = "generatedFile1";
+ std::string file2 = "generatedFile2";
+ std::string file3 = "generatedFile3";
+ std::string file4 = "generatedFile4";
+ std::string file1tmp = file1 + ".tmp";
+ std::string file2tmp = file2 + ".tmp";
+ std::string file3tmp = file3 + ".tmp";
+ std::string file4tmp = file4 + ".tmp";
+ gm.Open(file1.c_str());
+ gm << "This is generated file 1";
+ gm.Close();
+ gm.Open(file2.c_str());
+ gm << "This is generated file 2";
+ gm.Close();
+ gm.Open(file3.c_str());
+ gm << "This is generated file 3";
+ gm.Close();
+ gm.Open(file4.c_str());
+ gm << "This is generated file 4";
+ gm.Close();
+ if ( cmSystemTools::FileExists(file1.c_str()) )
+ {
+ if ( cmSystemTools::FileExists(file2.c_str()) )
+ {
+ if ( cmSystemTools::FileExists(file3.c_str()) )
+ {
+ if ( cmSystemTools::FileExists(file4.c_str()) )
+ {
+ if ( cmSystemTools::FileExists(file1tmp.c_str()) )
+ {
+ cmFailed("Something wrong with cmGeneratedFileStream. Temporary file is still here: ", file1tmp.c_str());
+ }
+ else if ( cmSystemTools::FileExists(file2tmp.c_str()) )
+ {
+ cmFailed("Something wrong with cmGeneratedFileStream. Temporary file is still here: ", file2tmp.c_str());
+ }
+ else if ( cmSystemTools::FileExists(file3tmp.c_str()) )
+ {
+ cmFailed("Something wrong with cmGeneratedFileStream. Temporary file is still here: ", file3tmp.c_str());
+ }
+ else if ( cmSystemTools::FileExists(file4tmp.c_str()) )
+ {
+ cmFailed("Something wrong with cmGeneratedFileStream. Temporary file is still here: ", file4tmp.c_str());
+ }
+ else
+ {
+ std::cout << "cmGeneratedFileStream works\n";
+ }
+ }
+ else
+ {
+ cmFailed("Something wrong with cmGeneratedFileStream. Cannot find file: ", file4.c_str());
+ }
+ }
+ else
+ {
+ cmFailed("Something wrong with cmGeneratedFileStream. Found file: ", file3.c_str());
+ }
+ }
+ else
+ {
+ cmFailed("Something wrong with cmGeneratedFileStream. Cannot find file: ", file2.c_str());
+ }
+ }
+ else
+ {
+ cmFailed("Something wrong with cmGeneratedFileStream. Cannot find file: ", file1.c_str());
+ }
+ cmSystemTools::RemoveFile(file1.c_str());
+ cmSystemTools::RemoveFile(file2.c_str());
+ cmSystemTools::RemoveFile(file3.c_str());
+ cmSystemTools::RemoveFile(file4.c_str());
+ cmSystemTools::RemoveFile(file1tmp.c_str());
+ cmSystemTools::RemoveFile(file2tmp.c_str());
+ cmSystemTools::RemoveFile(file3tmp.c_str());
+ cmSystemTools::RemoveFile(file4tmp.c_str());
+
+ return failed;
+}
diff --git a/Tests/CMakeLib/testSystemTools.cxx b/Tests/CMakeLib/testSystemTools.cxx
new file mode 100644
index 000000000..9309ae332
--- /dev/null
+++ b/Tests/CMakeLib/testSystemTools.cxx
@@ -0,0 +1,33 @@
+/*============================================================================
+ 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.
+============================================================================*/
+#include "cmSystemTools.h"
+
+#define cmPassed(m) std::cout << "Passed: " << m << "\n"
+#define cmFailed(m) std::cout << "FAILED: " << m << "\n"; failed=1
+
+int testSystemTools(int, char*[])
+{
+ int failed = 0;
+ // ----------------------------------------------------------------------
+ // Test cmSystemTools::UpperCase
+ std::string str = "abc";
+ std::string strupper = "ABC";
+ if(cmSystemTools::UpperCase(str) == strupper)
+ {
+ cmPassed("cmSystemTools::UpperCase is working");
+ }
+ else
+ {
+ cmFailed("cmSystemTools::UpperCase is working");
+ }
+ return failed;
+}
diff --git a/Tests/CMakeLib/testUTF8.cxx b/Tests/CMakeLib/testUTF8.cxx
new file mode 100644
index 000000000..4ab96cf01
--- /dev/null
+++ b/Tests/CMakeLib/testUTF8.cxx
@@ -0,0 +1,125 @@
+/*============================================================================
+ 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 <cm_utf8.h>
+
+#include <string.h>
+#include <stdio.h>
+
+typedef char test_utf8_char[5];
+
+static void test_utf8_char_print(test_utf8_char const c)
+{
+ unsigned char const* d = reinterpret_cast<unsigned char const*>(c);
+ printf("[0x%02X,0x%02X,0x%02X,0x%02X]",
+ (int)d[0], (int)d[1], (int)d[2], (int)d[3]);
+}
+
+struct test_utf8_entry
+{
+ int n;
+ test_utf8_char str;
+ unsigned int chr;
+};
+
+static test_utf8_entry const good_entry[] = {
+ {1, "\x20\x00\x00\x00", 0x0020}, /* Space. */
+ {2, "\xC2\xA9\x00\x00", 0x00A9}, /* Copyright. */
+ {3, "\xE2\x80\x98\x00", 0x2018}, /* Open-single-quote. */
+ {3, "\xE2\x80\x99\x00", 0x2019}, /* Close-single-quote. */
+ {4, "\xF0\xA3\x8E\xB4", 0x233B4}, /* Example from RFC 3629. */
+ {0, {0,0,0,0,0}, 0}
+};
+
+static test_utf8_char const bad_chars[] = {
+ "\x80\x00\x00\x00",
+ "\xC0\x00\x00\x00",
+ "\xE0\x00\x00\x00",
+ "\xE0\x80\x80\x00",
+ "\xF0\x80\x80\x80",
+ {0,0,0,0,0}
+};
+
+static void report_good(bool passed, test_utf8_char const c)
+{
+ printf("%s: decoding good ", passed?"pass":"FAIL");
+ test_utf8_char_print(c);
+ printf(" (%s) ", c);
+}
+
+static void report_bad(bool passed, test_utf8_char const c)
+{
+ printf("%s: decoding bad ", passed?"pass":"FAIL");
+ test_utf8_char_print(c);
+ printf(" ");
+}
+
+static bool decode_good(test_utf8_entry const entry)
+{
+ unsigned int uc;
+ if(const char* e = cm_utf8_decode_character(entry.str, entry.str+4, &uc))
+ {
+ int used = static_cast<int>(e-entry.str);
+ if(uc != entry.chr)
+ {
+ report_good(false, entry.str);
+ printf("expected 0x%04X, got 0x%04X\n", entry.chr, uc);
+ return false;
+ }
+ if(used != entry.n)
+ {
+ report_good(false, entry.str);
+ printf("had %d bytes, used %d\n", entry.n, used);
+ return false;
+ }
+ report_good(true, entry.str);
+ printf("got 0x%04X\n", uc);
+ return true;
+ }
+ report_good(false, entry.str);
+ printf("failed\n");
+ return false;
+}
+
+static bool decode_bad(test_utf8_char const s)
+{
+ unsigned int uc = 0xFFFFu;
+ const char* e = cm_utf8_decode_character(s, s+4, &uc);
+ if(e)
+ {
+ report_bad(false, s);
+ printf("expected failure, got 0x%04X\n", uc);
+ return false;
+ }
+ report_bad(true, s);
+ printf("failed as expected\n");
+ return true;
+}
+
+int testUTF8(int, char*[])
+{
+ int result = 0;
+ for(test_utf8_entry const* e = good_entry; e->n; ++e)
+ {
+ if(!decode_good(*e))
+ {
+ result = 1;
+ }
+ }
+ for(test_utf8_char const* c = bad_chars; (*c)[0]; ++c)
+ {
+ if(!decode_bad(*c))
+ {
+ result = 1;
+ }
+ }
+ return result;
+}
diff --git a/Tests/CMakeLib/testXMLParser.cxx b/Tests/CMakeLib/testXMLParser.cxx
new file mode 100644
index 000000000..54ed5dc90
--- /dev/null
+++ b/Tests/CMakeLib/testXMLParser.cxx
@@ -0,0 +1,17 @@
+#include "testXMLParser.h"
+
+#include "cmXMLParser.h"
+
+#include <cmsys/ios/iostream>
+
+int testXMLParser(int, char*[])
+{
+ // TODO: Derive from parser and check attributes.
+ cmXMLParser parser;
+ if(!parser.ParseFile(SOURCE_DIR "/testXMLParser.xml"))
+ {
+ cmsys_ios::cerr << "cmXMLParser failed!" << cmsys_ios::endl;
+ return 1;
+ }
+ return 0;
+}
diff --git a/Tests/CMakeLib/testXMLParser.h.in b/Tests/CMakeLib/testXMLParser.h.in
new file mode 100644
index 000000000..da0b2757b
--- /dev/null
+++ b/Tests/CMakeLib/testXMLParser.h.in
@@ -0,0 +1,6 @@
+#ifndef testXMLParser_h
+#define testXMLParser_h
+
+#define SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@"
+
+#endif
diff --git a/Tests/CMakeLib/testXMLParser.xml b/Tests/CMakeLib/testXMLParser.xml
new file mode 100644
index 000000000..5a13f070a
--- /dev/null
+++ b/Tests/CMakeLib/testXMLParser.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Document>
+ <Element attr="1"/>
+</Document>
diff --git a/Tests/CMakeLib/testXMLSafe.cxx b/Tests/CMakeLib/testXMLSafe.cxx
new file mode 100644
index 000000000..60442fab7
--- /dev/null
+++ b/Tests/CMakeLib/testXMLSafe.cxx
@@ -0,0 +1,47 @@
+/*============================================================================
+ 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 <cmXMLSafe.h>
+
+#include "cmStandardIncludes.h"
+
+struct test_pair
+{
+ const char* in;
+ const char* out;
+};
+
+static test_pair const pairs[] = {
+ {"copyright \xC2\xA9", "copyright \xC2\xA9"},
+ {"form-feed \f", "form-feed [NON-XML-CHAR-0xC]"},
+ {"angles <>", "angles &lt;&gt;"},
+ {"ampersand &", "ampersand &amp;"},
+ {"bad-byte \x80", "bad-byte [NON-UTF-8-BYTE-0x80]"},
+ {0,0}
+};
+
+int testXMLSafe(int, char*[])
+{
+ int result = 0;
+ for(test_pair const* p = pairs; p->in; ++p)
+ {
+ cmXMLSafe xs(p->in);
+ cmOStringStream oss;
+ oss << xs;
+ std::string out = oss.str();
+ if(out != p->out)
+ {
+ printf("expected [%s], got [%s]\n", p->out, out.c_str());
+ result = 1;
+ }
+ }
+ return result;
+}
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
new file mode 100644
index 000000000..27ae3a072
--- /dev/null
+++ b/Tests/CMakeLists.txt
@@ -0,0 +1,2404 @@
+# a macro for tests that have a simple format where the name matches the
+# directory and project
+MACRO(ADD_TEST_MACRO NAME COMMAND)
+ STRING(REPLACE "." "/" dir "${NAME}")
+ STRING(REGEX REPLACE "[^.]*\\." "" proj "${NAME}")
+ ADD_TEST(${NAME} ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/${dir}"
+ "${CMake_BINARY_DIR}/Tests/${dir}"
+ --build-two-config
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-project ${proj}
+ ${${NAME}_EXTRA_OPTIONS}
+ --test-command ${COMMAND} ${ARGN})
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/${dir}")
+ENDMACRO(ADD_TEST_MACRO)
+
+MACRO(REGEX_ESCAPE_STRING _OUT _IN)
+ # Escape special regex metacharacters with a backslash
+ string(REGEX REPLACE "([$^.[|*+?()]|])" "\\\\\\1" ${_OUT} "${_IN}")
+ENDMACRO(REGEX_ESCAPE_STRING _OUT _IN)
+
+INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/CheckFortran.cmake)
+
+# Fake a user home directory to avoid polluting the real one.
+IF(DEFINED ENV{HOME} AND NOT CTEST_NO_TEST_HOME)
+ SET(TEST_HOME "${CMake_BINARY_DIR}/Tests/CMakeFiles/TestHome")
+ FILE(MAKE_DIRECTORY "${TEST_HOME}")
+ FILE(WRITE "${TEST_HOME}/.cvspass" ":pserver:anoncvs@www.cmake.org:/cvsroot/KWSys A\n")
+ SET(TEST_HOME_ENV_CODE "# Fake a user home directory to avoid polluting the real one.
+# But provide original ENV{HOME} value in ENV{CTEST_REAL_HOME} for tests that
+# need access to the real HOME directory.
+SET(ENV{CTEST_REAL_HOME} \"\$ENV{HOME}\")
+SET(ENV{HOME} \"${TEST_HOME}\")
+")
+ENDIF()
+
+# Choose a default configuration for CTest tests.
+SET(CTestTest_CONFIG Debug)
+IF(NOT CMAKE_CONFIGURATION_TYPES AND CMAKE_BUILD_TYPE)
+ SET(CTestTest_CONFIG ${CMAKE_BUILD_TYPE})
+ENDIF()
+
+CONFIGURE_FILE(${CMake_SOURCE_DIR}/Tests/EnforceConfig.cmake.in
+ ${CMake_BINARY_DIR}/Tests/EnforceConfig.cmake @ONLY)
+
+# Testing
+IF(BUILD_TESTING)
+ IF("${CMAKE_TEST_GENERATOR}" MATCHES "Unix Makefiles" OR ("${CMAKE_TEST_GENERATOR}" MATCHES Ninja AND NOT WIN32))
+ SET(TEST_CompileCommandOutput 1)
+ ENDIF()
+
+ ADD_SUBDIRECTORY(CMakeLib)
+ ADD_SUBDIRECTORY(CMakeOnly)
+ ADD_SUBDIRECTORY(RunCMake)
+
+ ADD_SUBDIRECTORY(FindPackageModeMakefileTest)
+
+ # Collect a list of all test build directories.
+ SET(TEST_BUILD_DIRS)
+
+ # Should the long tests be run?
+ OPTION(CMAKE_RUN_LONG_TESTS
+ "Should the long tests be run (such as Bootstrap)." ON)
+ MARK_AS_ADVANCED(CMAKE_RUN_LONG_TESTS)
+
+ IF (CMAKE_RUN_LONG_TESTS)
+ OPTION(CTEST_TEST_CTEST
+ "Should the tests that run a full sub ctest process be run?"
+ OFF)
+ MARK_AS_ADVANCED(CTEST_TEST_CTEST)
+
+ OPTION(TEST_KDE4_STABLE_BRANCH
+ "Should the KDE4 stable branch test be run?"
+ OFF)
+ MARK_AS_ADVANCED(TEST_KDE4_STABLE_BRANCH)
+ ENDIF (CMAKE_RUN_LONG_TESTS)
+
+ # Should tests that use CVS be run?
+ #
+ set(do_cvs_tests 0)
+
+ if(EXISTS ${CMAKE_ROOT}/Modules/FindCVS.cmake)
+ find_package(CVS QUIET)
+ else(EXISTS ${CMAKE_ROOT}/Modules/FindCVS.cmake)
+ find_program(CVS_EXECUTABLE NAMES cvs)
+ endif(EXISTS ${CMAKE_ROOT}/Modules/FindCVS.cmake)
+
+ if(CVS_EXECUTABLE)
+ set(do_cvs_tests 1)
+ endif(CVS_EXECUTABLE)
+
+ if(do_cvs_tests AND NOT UNIX)
+ if("${CVS_EXECUTABLE}" MATCHES "cygwin")
+ set(do_cvs_tests 0)
+ endif("${CVS_EXECUTABLE}" MATCHES "cygwin")
+ endif(do_cvs_tests AND NOT UNIX)
+
+ # Should CPack tests be run? By default, yes, but...
+ #
+ # Disable packaging test on Apple 10.3 and below. PackageMaker starts
+ # DiskManagementTool as root and disowns it
+ # (http://lists.apple.com/archives/installer-dev/2005/Jul/msg00005.html).
+ # It is left holding open pipe handles and preventing ProcessUNIX from
+ # detecting end-of-data even after its immediate child exits. Then
+ # the test hangs until it times out and is killed. This is a
+ # well-known bug in kwsys process execution that I would love to get
+ # time to fix.
+ #
+ OPTION(CTEST_TEST_CPACK
+ "Should the tests that use '--build-target package' be run?"
+ ON)
+ MARK_AS_ADVANCED(CTEST_TEST_CPACK)
+ SET(CTEST_TEST_OSX_ARCH 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]")
+ MESSAGE(STATUS "Forcing CTEST_TEST_CPACK=OFF on OSX < 10.4")
+ MESSAGE(STATUS "OSX_VERSION='${OSX_VERSION}'")
+ SET(CTEST_TEST_CPACK OFF)
+ ELSE(OSX_VERSION MATCHES "^10\\.[0123]" OR OSX_VERSION MATCHES "ProductVersion:\t10\\.[0123]")
+ SET(CTEST_TEST_OSX_ARCH 1)
+ ENDIF(OSX_VERSION MATCHES "^10\\.[0123]" OR OSX_VERSION MATCHES "ProductVersion:\t10\\.[0123]")
+ ENDIF(APPLE)
+
+ # Use 1500 or CTEST_TEST_TIMEOUT for long test timeout value,
+ # whichever is greater.
+ SET(CMAKE_LONG_TEST_TIMEOUT 1500)
+ IF(CTEST_TEST_TIMEOUT)
+ SET(CMAKE_LONG_TEST_TIMEOUT ${CTEST_TEST_TIMEOUT})
+ ENDIF(CTEST_TEST_TIMEOUT)
+ IF(CMAKE_LONG_TEST_TIMEOUT LESS 1500)
+ SET(CMAKE_LONG_TEST_TIMEOUT 1500)
+ ENDIF(CMAKE_LONG_TEST_TIMEOUT LESS 1500)
+
+ # 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)
+ # assume no resources building to test
+ SET(TEST_RESOURCES FALSE)
+ # for windows and cygwin assume we have resources
+ IF(WIN32 OR CYGWIN)
+ 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")
+ SET(TEST_RESOURCES FALSE)
+ ENDIF()
+ IF(TEST_RESOURCES)
+ ADD_TEST_MACRO(VSResource VSResource)
+ ENDIF()
+ 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_Fortran_COMPILER)
+ ADD_TEST_MACRO(FortranOnly FortranOnly)
+ ENDIF()
+ # test Visual Studio GNU Fortran mixing with cmake_add_fortran_subdirectory
+ # run this project if we have a working fortran compiler or
+ # the test is enabled with CMAKE_TEST_CMAKE_ADD_FORTRAN cache variable.
+ # If you enable the test, CMake should find the MinGW fortran install,
+ # or in some cases you might need to set the PATH so that cmake can find
+ # the gfortran from mingw.
+ IF(CMAKE_Fortran_COMPILER OR CMAKE_TEST_CMAKE_ADD_FORTRAN)
+ SET(CMAKE_SKIP_VSGNUFortran FALSE)
+ # disable test for apple builds using ifort if they are building
+ # more than one architecture, as ifort does not support that.
+ IF(APPLE AND (CMAKE_Fortran_COMPILER MATCHES ifort))
+ LIST(LENGTH CMAKE_OSX_ARCHITECTURES len)
+ IF("${len}" GREATER 1)
+ MESSAGE(STATUS "Skip VSGNUFortran for ifort dual cpu mac build")
+ SET(CMAKE_SKIP_VSGNUFortran TRUE)
+ ENDIF()
+ ENDIF()
+ IF((CMAKE_C_COMPILER MATCHES lsb)
+ AND (CMAKE_Fortran_COMPILER MATCHES ifort))
+ MESSAGE(STATUS "Skip VSGNUFortran for ifort and lsb compilers")
+ SET(CMAKE_SKIP_VSGNUFortran TRUE)
+ ENDIF()
+ IF(NOT CMAKE_SKIP_VSGNUFortran)
+ ADD_TEST_MACRO(VSGNUFortran ${CMAKE_COMMAND} -P runtest.cmake)
+ ENDIF()
+ ENDIF()
+ ADD_TEST_MACRO(COnly COnly)
+ ADD_TEST_MACRO(CxxOnly CxxOnly)
+ ADD_TEST_MACRO(IPO COnly/COnly)
+ ADD_TEST_MACRO(OutDir runtime/OutDir)
+ ADD_TEST_MACRO(ObjectLibrary UseCshared)
+ ADD_TEST_MACRO(NewlineArgs NewlineArgs)
+ ADD_TEST_MACRO(SetLang SetLang)
+ ADD_TEST_MACRO(ExternalOBJ ExternalOBJ)
+ ADD_TEST_MACRO(LoadCommand LoadedCommand)
+ ADD_TEST_MACRO(LinkDirectory bin/LinkDirectory)
+ ADD_TEST_MACRO(LinkLanguage LinkLanguage)
+ ADD_TEST_MACRO(LinkLine LinkLine)
+ ADD_TEST_MACRO(MacroTest miniMacroTest)
+ ADD_TEST_MACRO(FunctionTest miniFunctionTest)
+ ADD_TEST_MACRO(ReturnTest ReturnTest)
+ ADD_TEST_MACRO(Properties Properties)
+ ADD_TEST_MACRO(Assembler HelloAsm)
+ ADD_TEST_MACRO(SourceGroups SourceGroups)
+ ADD_TEST_MACRO(Preprocess Preprocess)
+ ADD_TEST_MACRO(ExportImport ExportImport)
+ ADD_TEST_MACRO(Unset Unset)
+ ADD_TEST_MACRO(PolicyScope PolicyScope)
+ ADD_TEST_MACRO(EmptyLibrary EmptyLibrary)
+ 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")
+ ADD_TEST_MACRO(Policy0002 Policy0002)
+ ENDIF("${CMAKE_TEST_GENERATOR}" MATCHES "Make")
+ IF(CTEST_TEST_OSX_ARCH)
+ ADD_TEST_MACRO(Architecture Architecture)
+ SET_TESTS_PROPERTIES(Architecture PROPERTIES
+ PASS_REGULAR_EXPRESSION "(file is not of required architecture|does not match cputype|not the architecture being linked)")
+ ENDIF(CTEST_TEST_OSX_ARCH)
+
+ LIST(APPEND TEST_BUILD_DIRS ${CMake_TEST_INSTALL_PREFIX})
+
+ IF(NOT QT4_FOUND)
+ FIND_PACKAGE(Qt4)
+ ENDIF(NOT QT4_FOUND)
+
+ IF(QT4_FOUND)
+ # test whether the Qt4 which has been found works, on some machines
+ # which run nightly builds there were errors like "wrong file format"
+ # for libQtCore.so. So first check it works, and only if it does add
+ # the automoc test.
+ INCLUDE(CheckCXXSourceCompiles)
+ SET(_save_CMAKE_REQUIRED_INCLUDES "${CMAKE_REQUIRED_INCLUDES}")
+ SET(_save_CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}")
+
+ SET(CMAKE_REQUIRED_INCLUDES ${QT_INCLUDES})
+ SET(CMAKE_REQUIRED_LIBRARIES ${QT_QTCORE_LIBRARIES})
+
+ CHECK_CXX_SOURCE_COMPILES("#include <QCoreApplication>\n int main() {return (qApp == 0 ? 0 : 1); }\n"
+ QT4_WORKS)
+
+ SET(CMAKE_REQUIRED_INCLUDES "${_save_CMAKE_REQUIRED_INCLUDES}")
+ SET(CMAKE_REQUIRED_LIBRARIES "${_save_CMAKE_REQUIRED_LIBRARIES}")
+ ENDIF()
+
+ # run test for BundleUtilities on supported platforms/compilers
+ if(MSVC OR
+ CMAKE_SYSTEM_NAME MATCHES "Linux" OR
+ CMAKE_SYSTEM_NAME MATCHES "Darwin")
+ if(NOT "${CMAKE_TEST_GENERATOR}" STREQUAL "Watcom WMake")
+
+ ADD_TEST(BundleUtilities ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/BundleUtilities"
+ "${CMake_BINARY_DIR}/Tests/BundleUtilities"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-project BundleUtilities
+ )
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/BundleUtilities")
+
+ # run test for DeployQt4 on supported platforms/compilers (which depends on BundleUtilities)
+ # this test also depends on the existence of the standard qtiff plugin
+ if(QT4_WORKS AND QT_QTSQL_FOUND)
+ ADD_TEST(Qt4Deploy ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/Qt4Deploy"
+ "${CMake_BINARY_DIR}/Tests/Qt4Deploy"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-project Qt4Deploy
+ --build-options
+ -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
+ -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}
+ )
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Qt4Deploy")
+ endif()
+
+ endif()
+ endif()
+
+ SET(CMAKE_BUILD_TEST_SOURCE_DIR "${CMake_SOURCE_DIR}/Tests/COnly")
+ SET(CMAKE_BUILD_TEST_BINARY_DIR "${CMake_BINARY_DIR}/Tests/CMakeBuildCOnly")
+ SET(CMAKE_BUILD_TEST_EXE COnly)
+ CONFIGURE_FILE("${CMake_SOURCE_DIR}/Tests/CMakeBuildTest.cmake.in"
+ "${CMake_BINARY_DIR}/Tests/CMakeBuildTest.cmake" @ONLY)
+ ADD_TEST(CMakeBuildTest ${CMAKE_CMAKE_COMMAND} -P
+ "${CMake_BINARY_DIR}/Tests/CMakeBuildTest.cmake")
+ LIST(APPEND TEST_BUILD_DIRS ${CMAKE_BUILD_TEST_BINARY_DIR})
+ # now do it again for a project that has two project commands
+ SET(CMAKE_BUILD_TEST_SOURCE_DIR "${CMake_SOURCE_DIR}/Tests/DoubleProject")
+ SET(CMAKE_BUILD_TEST_BINARY_DIR "${CMake_BINARY_DIR}/Tests/DoubleProject")
+ SET(CMAKE_BUILD_TEST_EXE just_silly)
+ CONFIGURE_FILE("${CMake_SOURCE_DIR}/Tests/CMakeBuildTest.cmake.in"
+ "${CMake_BINARY_DIR}/Tests/CMakeBuildDoubleProjectTest.cmake" @ONLY)
+ ADD_TEST(CMakeDoubleProject ${CMAKE_CMAKE_COMMAND} -P
+ "${CMake_BINARY_DIR}/Tests/CMakeBuildDoubleProjectTest.cmake")
+ LIST(APPEND TEST_BUILD_DIRS ${CMAKE_BUILD_TEST_BINARY_DIR})
+
+ ADD_TEST_MACRO(Module.CheckTypeSize CheckTypeSize)
+
+ ADD_TEST_MACRO(Module.GenerateExportHeader GenerateExportHeader)
+
+ if (APPLE OR CMAKE_CXX_COMPILER_ID MATCHES "GNU")
+ include(CheckCXXCompilerFlag)
+ check_cxx_compiler_flag(-fPIE run_pic_test)
+ else()
+ if (CMAKE_CXX_COMPILER_ID MATCHES "PGI"
+ OR CMAKE_CXX_COMPILER_ID MATCHES "PathScale"
+ OR CMAKE_SYSTEM_NAME MATCHES "IRIX64"
+ OR CMAKE_CXX_COMPILER_ID MATCHES "Intel")
+ set(run_pic_test 0)
+ else()
+ set(run_pic_test 1)
+ endif()
+ endif()
+
+ if (run_pic_test)
+ ADD_TEST_MACRO(PositionIndependentTargets PositionIndependentTargets)
+ endif()
+
+ ADD_TEST(LinkFlags-prepare
+ ${CMAKE_CTEST_COMMAND} -C \${CTEST_CONFIGURATION_TYPE}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/LinkFlags"
+ "${CMake_BINARY_DIR}/Tests/LinkFlags"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-project LinkFlags
+ --build-target LinkFlags
+ --build-options -DTEST_CONFIG=\${CTEST_CONFIGURATION_TYPE}
+ )
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/LinkFlags")
+
+ MACRO(ADD_LINK_FLAGS_TEST name depends)
+ ADD_TEST(LinkFlags-${name}
+ ${CMAKE_CMAKE_COMMAND} --build "${CMake_BINARY_DIR}/Tests/LinkFlags"
+ --target LinkFlags_${name} --config \${CTEST_CONFIGURATION_TYPE}
+ )
+ SET_TESTS_PROPERTIES(LinkFlags-${name} PROPERTIES
+ PASS_REGULAR_EXPRESSION "BADFLAG" DEPENDS LinkFlags-${depends})
+ ENDMACRO()
+ ADD_LINK_FLAGS_TEST(lib prepare)
+ ADD_LINK_FLAGS_TEST(dll lib)
+ ADD_LINK_FLAGS_TEST(exe dll)
+ ADD_LINK_FLAGS_TEST(lib_config exe)
+ ADD_LINK_FLAGS_TEST(dll_config lib_config)
+ ADD_LINK_FLAGS_TEST(exe_config dll_config)
+
+ # If we are running right now with a UnixMakefiles based generator,
+ # 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")
+ # check which generators we have
+ EXEC_PROGRAM(${CMAKE_CMAKE_COMMAND} ARGS --help OUTPUT_VARIABLE cmakeOutput )
+ # check for the Eclipse generator
+ IF ("${cmakeOutput}" MATCHES Eclipse)
+ ADD_TEST(Simple_EclipseGenerator ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/Simple"
+ "${CMake_BINARY_DIR}/Tests/Simple_EclipseGenerator"
+ --build-two-config
+ --build-generator "Eclipse CDT4 - Unix Makefiles"
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-project Simple
+ --test-command Simple)
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Simple_EclipseGenerator")
+ ENDIF ("${cmakeOutput}" MATCHES Eclipse)
+
+ # check for the CodeBlocks generator
+ IF ("${cmakeOutput}" MATCHES CodeBlocks)
+ ADD_TEST(Simple_CodeBlocksGenerator ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/Simple"
+ "${CMake_BINARY_DIR}/Tests/Simple_CodeBlocksGenerator"
+ --build-two-config
+ --build-generator "CodeBlocks - Unix Makefiles"
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-project Simple
+ --test-command Simple)
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Simple_CodeBlocksGenerator")
+ ENDIF ("${cmakeOutput}" MATCHES CodeBlocks)
+ # check for the KDevelop3 generator
+ IF ("${cmakeOutput}" MATCHES KDevelop3)
+ ADD_TEST(Simple_KDevelop3Generator ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/Simple"
+ "${CMake_BINARY_DIR}/Tests/Simple_KDevelop3Generator"
+ --build-two-config
+ --build-generator "KDevelop3 - Unix Makefiles"
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-project Simple
+ --test-command Simple)
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Simple_KDevelop3Generator")
+ ENDIF ("${cmakeOutput}" MATCHES KDevelop3)
+
+ ENDIF(${CMAKE_TEST_GENERATOR} MATCHES "Unix Makefiles" OR ${CMAKE_TEST_GENERATOR} MATCHES "KDevelop")
+
+ # test for correct sub-project generation
+ # not implemented in VS6 or Xcode
+ IF(NOT MSVC60 AND NOT XCODE AND NOT MSVC70)
+ # run cmake and configure all of SubProject
+ # but only build the independent executable car
+ ADD_TEST(SubProject ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/SubProject"
+ "${CMake_BINARY_DIR}/Tests/SubProject"
+ --build-project SubProject
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-target car
+ --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
+ 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 ${CMAKE_TEST_GENERATOR}
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-nocmake
+ --build-project foo
+ --build-target foo
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/SubProject/foo"
+ --test-command foo
+ )
+ SET_TESTS_PROPERTIES ( SubProject-Stage2 PROPERTIES DEPENDS SubProject)
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/SubProject")
+ ENDIF(NOT MSVC60 AND NOT XCODE AND NOT MSVC70)
+
+ IF (CMAKE_STRICT)
+ ADD_TEST_MACRO(DocTest DocTest)
+ ENDIF (CMAKE_STRICT)
+ # 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)
+ SET(_TEST_DIR "${CMake_BINARY_DIR}/Tests/${name}")
+ FILE(MAKE_DIRECTORY "${_TEST_DIR}")
+ 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
+ ")
+ ADD_TEST(${name} /bin/sh ${_TEST_DIR}/nightly-cmake.sh)
+ IF(COMMAND SET_TESTS_PROPERTIES AND COMMAND GET_TEST_PROPERTY)
+ SET_TESTS_PROPERTIES (${name} PROPERTIES TIMEOUT ${CMAKE_LONG_TEST_TIMEOUT})
+ ENDIF(COMMAND SET_TESTS_PROPERTIES AND COMMAND GET_TEST_PROPERTY)
+ ENDMACRO(ADD_NIGHTLY_BUILD_TEST)
+ 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
+ dashmacmini5_release.cmake)
+ ADD_NIGHTLY_BUILD_TEST(CMakeNightlyLinux
+ magrathea_release.cmake)
+ ENDIF(CMAKE_BUILD_NIGHTLY_RELEASES)
+
+ # add tests with more complex invocations
+ ADD_TEST(Framework ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/Framework"
+ "${CMake_BINARY_DIR}/Tests/Framework"
+ --build-two-config
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-project Framework
+ --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")
+
+ ADD_TEST(TargetName ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/TargetName"
+ "${CMake_BINARY_DIR}/Tests/TargetName"
+ --build-two-config
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-project TargetName
+ --test-command ${CMAKE_CMAKE_COMMAND} -E compare_files
+ ${CMake_SOURCE_DIR}/Tests/TargetName/scripts/hello_world
+ ${CMake_BINARY_DIR}/Tests/TargetName/scripts/hello_world)
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/TargetName")
+
+ ADD_TEST(LibName ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/LibName"
+ "${CMake_BINARY_DIR}/Tests/LibName"
+ --build-two-config
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-project LibName
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/LibName/lib"
+ --test-command foobar
+ )
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/LibName")
+
+ ADD_TEST(CustComDepend ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/CustComDepend"
+ "${CMake_BINARY_DIR}/Tests/CustComDepend"
+ --build-two-config
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-project CustComDepend
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/CustComDepend/bin"
+ --test-command foo bar.c
+ )
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/CustComDepend")
+
+ ADD_TEST(ArgumentExpansion ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/ArgumentExpansion"
+ "${CMake_BINARY_DIR}/Tests/ArgumentExpansion"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-project ArgumentExpansion
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/ArgumentExpansion/bin"
+ )
+ SET_TESTS_PROPERTIES(ArgumentExpansion PROPERTIES
+ FAIL_REGULAR_EXPRESSION "Unexpected: ")
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/ArgumentExpansion")
+
+ ADD_TEST(CustomCommand ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/CustomCommand"
+ "${CMake_BINARY_DIR}/Tests/CustomCommand"
+ --build-two-config
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-project CustomCommand
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/CustomCommand/bin"
+ --test-command CustomCommand
+ )
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/CustomCommand")
+
+ ADD_TEST(CustomCommandWorkingDirectory ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/CustomCommandWorkingDirectory"
+ "${CMake_BINARY_DIR}/Tests/CustomCommandWorkingDirectory"
+ --build-two-config
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-project TestWorkingDir
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --test-command working
+ )
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/CustomCommandWorkingDirectory")
+
+ #ADD_TEST(SimpleExclude ${CMAKE_CTEST_COMMAND}
+ # --build-and-test
+ # "${CMake_SOURCE_DIR}/Tests/SimpleExclude"
+ # "${CMake_BINARY_DIR}/Tests/SimpleExclude"
+ # --build-generator ${CMAKE_TEST_GENERATOR}
+ # --build-project SimpleExclude
+ # --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ # --build-two-config
+ # --test-command t4
+ #--test-command "${CMAKE_COMMAND}"
+ #"-DCONFIGURATION=\${CTEST_CONFIGURATION_TYPE}"
+ #-P "${CMake_BINARY_DIR}/Tests/SimpleExclude/run.cmake"
+ #)
+
+# ADD_TEST(SameName ${CMAKE_CTEST_COMMAND}
+# --build-and-test
+# "${CMake_SOURCE_DIR}/Tests/SameName"
+# "${CMake_BINARY_DIR}/Tests/SameName"
+# --build-generator ${CMAKE_TEST_GENERATOR}
+# --build-project SameName
+# --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+# --build-two-config
+# --test-command
+# "${CMake_BINARY_DIR}/Tests/SameName/Exe1/mytest2")
+
+ ADD_TEST(OutOfSource ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/OutOfSource"
+ "${CMake_BINARY_DIR}/Tests/OutOfSource"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-project OutOfSource
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-two-config
+ --test-command
+ "${CMake_BINARY_DIR}/Tests/OutOfSource/SubDir/OutOfSourceSubdir/simple")
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/OutOfSource")
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/OutOfSourceDeep")
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/OutOfBinary")
+
+ ADD_TEST(BuildDepends ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/BuildDepends"
+ "${CMake_BINARY_DIR}/Tests/BuildDepends"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-project BuildDepends
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ )
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/BuildDepends")
+
+ SET(SimpleInstallInstallDir
+ "${CMake_BINARY_DIR}/Tests/SimpleInstall/InstallDirectory")
+ ADD_TEST(SimpleInstall ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/SimpleInstall"
+ "${CMake_BINARY_DIR}/Tests/SimpleInstall"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-project TestSimpleInstall
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-two-config
+ --build-options
+ "-DCMAKE_INSTALL_PREFIX:PATH=${SimpleInstallInstallDir}"
+ "-DCTEST_TEST_CPACK:BOOL=${CTEST_TEST_CPACK}"
+ --test-command ${SimpleInstallInstallDir}/MyTest/bin/SimpleInstExe)
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/SimpleInstall")
+ ADD_TEST(SimpleInstall-Stage2 ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/SimpleInstallS2"
+ "${CMake_BINARY_DIR}/Tests/SimpleInstallS2"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-project TestSimpleInstall
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-two-config
+ --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")
+
+ # 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(CMAKE_SYSTEM_NAME MATCHES "Linux" AND NOT CMAKE_CURRENT_BINARY_DIR MATCHES ".* .*")
+ # Do not try to build RPM
+ if (NOT RPMBUILD)
+ set(CPACK_BINARY_RPM OFF)
+ endif(NOT RPMBUILD)
+
+ find_program(NSIS_MAKENSIS_EXECUTABLE NAMES makensis
+ PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\NSIS]
+ DOC "makensis program location"
+ )
+
+ # But on Windows, only run the CPackComponents test if the NSIS
+ # installer builder is available:
+ #
+ if(WIN32)
+ if(NSIS_MAKENSIS_EXECUTABLE)
+ set(CTEST_RUN_CPackComponents ON)
+ else(NSIS_MAKENSIS_EXECUTABLE)
+ set(CTEST_RUN_CPackComponents OFF)
+ set(CTEST_package_X11_TEST OFF)
+ endif(NSIS_MAKENSIS_EXECUTABLE)
+ endif(WIN32)
+
+ IF(CTEST_RUN_CPackComponents)
+ set(CPackComponents_EXTRA_OPTIONS)
+ if(APPLE)
+ set(CPackComponents_EXTRA_OPTIONS -DCPACK_BINARY_DRAGNDROP:BOOL=ON)
+ endif(APPLE)
+ if(NSIS_MAKENSIS_EXECUTABLE)
+ set(CPackComponents_EXTRA_OPTIONS ${CPackComponents_EXTRA_OPTIONS}
+ -DCPACK_BINARY_NSIS:BOOL=ON)
+ endif(NSIS_MAKENSIS_EXECUTABLE)
+
+ ADD_TEST(CPackComponents ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/CPackComponents"
+ "${CMake_BINARY_DIR}/Tests/CPackComponents"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-project CPackComponents
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-two-config
+ --build-target package
+ --build-options
+ -DCPACK_BINARY_DEB:BOOL=${CPACK_BINARY_DEB}
+ -DCPACK_BINARY_RPM:BOOL=${CPACK_BINARY_RPM}
+ ${CPackComponents_EXTRA_OPTIONS}
+ --graphviz=CPackComponents.dot
+ --test-command ${CMAKE_CMAKE_COMMAND}
+ "-DCPackComponents_BINARY_DIR:PATH=${CMake_BINARY_DIR}/Tests/CPackComponents"
+ -P "${CMake_SOURCE_DIR}/Tests/CPackComponents/VerifyResult.cmake")
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/CPackComponents")
+ ENDIF(CTEST_RUN_CPackComponents)
+
+ IF(CTEST_RUN_CPackComponentsForAll)
+ # Check whether if rpmbuild command is found
+ # before adding RPM tests
+ find_program(RPMBUILD_EXECUTABLE NAMES rpmbuild)
+ if(RPMBUILD_EXECUTABLE)
+ list(APPEND ACTIVE_CPACK_GENERATORS RPM)
+ endif(RPMBUILD_EXECUTABLE)
+ # Check whether if dpkg command is found
+ # before adding DEB tests
+ find_program(DPKG_EXECUTABLE NAMES dpkg)
+ if(DPKG_EXECUTABLE)
+ list(APPEND ACTIVE_CPACK_GENERATORS DEB)
+ endif(DPKG_EXECUTABLE)
+
+ # ACTIVE_CPACK_GENERATORS variable
+ # now contains the list of 'active generators'
+ set(CPackComponentsForAll_EXTRA_OPTIONS)
+ set(CPackRun_CPackCommand "-DCPackCommand=${CMAKE_CPACK_COMMAND}")
+ # set up list of CPack generators
+ list(APPEND GENLST "ZIP")
+ if(APPLE)
+ list(APPEND GENLST "DragNDrop")
+ endif(APPLE)
+ 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(NOT ${RPM_ACTIVE} EQUAL -1)
+ endif(NOT CMAKE_CURRENT_BINARY_DIR MATCHES ".* .*")
+ list(FIND ACTIVE_CPACK_GENERATORS "DEB" DEB_ACTIVE)
+ if (NOT ${DEB_ACTIVE} EQUAL -1)
+ list(APPEND GENLST "DEB")
+ endif(NOT ${DEB_ACTIVE} EQUAL -1)
+
+ # set up list of component packaging ways
+ list(APPEND CWAYLST "default")
+ list(APPEND CWAYLST "OnePackPerGroup")
+ list(APPEND CWAYLST "IgnoreGroup")
+ list(APPEND CWAYLST "AllInOne")
+ foreach(CPackGen ${GENLST})
+ set(CPackRun_CPackGen "-DCPackGen=${CPackGen}")
+ foreach(CPackComponentWay ${CWAYLST})
+ set(CPackRun_CPackComponentWay "-DCPackComponentWay=${CPackComponentWay}")
+ ADD_TEST(CPackComponentsForAll-${CPackGen}-${CPackComponentWay} ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/CPackComponentsForAll"
+ "${CMake_BINARY_DIR}/Tests/CPackComponentsForAll/build${CPackGen}-${CPackComponentWay}"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-project CPackComponentsForAll
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-options
+ -DCPACK_BINARY_${CPackGen}:BOOL=ON
+ ${CPackRun_CPackComponentWay}
+ ${CPackComponentsForAll_EXTRA_OPTIONS}
+ --graphviz=CPackComponentsForAll.dot
+ --test-command ${CMAKE_CMAKE_COMMAND}
+ "-DCPackComponentsForAll_BINARY_DIR:PATH=${CMake_BINARY_DIR}/Tests/CPackComponentsForAll/build${CPackGen}-${CPackComponentWay}"
+ "${CPackRun_CPackCommand}"
+ "${CPackRun_CPackGen}"
+ "${CPackRun_CPackComponentWay}"
+ -P "${CMake_SOURCE_DIR}/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake")
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/CPackComponentsForAll/build${CPackGen}-${CPackComponentWay}")
+ endforeach(CPackComponentWay)
+ endforeach(CPackGen)
+ ENDIF(CTEST_RUN_CPackComponentsForAll)
+
+ # By default, turn this test off (because it takes a long time...)
+ #
+ if(NOT DEFINED CTEST_RUN_CPackTestAllGenerators)
+ set(CTEST_RUN_CPackTestAllGenerators OFF)
+
+ # ...but: if it appears to be a coverage dashboard, or long tests are
+ # on, then set it to the generic CTEST_TEST_CPACK setting.
+ #
+ if(CMAKE_CXX_FLAGS MATCHES "-ftest-coverage" OR
+ NOT "$ENV{COVFILE}" STREQUAL "" OR
+ CMAKE_RUN_LONG_TESTS)
+ set(CTEST_RUN_CPackTestAllGenerators ${CTEST_TEST_CPACK})
+ endif(CMAKE_CXX_FLAGS MATCHES "-ftest-coverage" OR
+ NOT "$ENV{COVFILE}" STREQUAL "" OR
+ CMAKE_RUN_LONG_TESTS)
+ endif(NOT DEFINED CTEST_RUN_CPackTestAllGenerators)
+
+ IF(CTEST_RUN_CPackTestAllGenerators)
+ ADD_TEST(CPackTestAllGenerators ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/CPackTestAllGenerators"
+ "${CMake_BINARY_DIR}/Tests/CPackTestAllGenerators"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-project CPackTestAllGenerators
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --test-command
+ ${CMAKE_CMAKE_COMMAND}
+ -D dir=${CMake_BINARY_DIR}/Tests/CPackTestAllGenerators
+ -D cpack=${CMAKE_CPACK_COMMAND}
+ -P ${CMake_SOURCE_DIR}/Tests/CPackTestAllGenerators/RunCPack.cmake
+ )
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/CPackTestAllGenerators")
+ ENDIF(CTEST_RUN_CPackTestAllGenerators)
+
+ IF(CTEST_package_X11_TEST)
+ SET(X11_build_target_arg --build-target package)
+ ELSE(CTEST_package_X11_TEST)
+ SET(X11_build_target_arg)
+ ENDIF(CTEST_package_X11_TEST)
+
+ ADD_TEST(X11 ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/X11"
+ "${CMake_BINARY_DIR}/Tests/X11"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-project UseX11
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-two-config
+ ${X11_build_target_arg}
+ --test-command UseX11)
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/X11")
+
+ if(NOT DEFINED CTEST_RUN_CMakeTestAllGenerators)
+ set(CTEST_RUN_CMakeTestAllGenerators ON)
+ endif(NOT DEFINED CTEST_RUN_CMakeTestAllGenerators)
+
+ IF(CTEST_RUN_CMakeTestAllGenerators)
+ ADD_TEST(CMakeTestAllGenerators ${CMAKE_CMAKE_COMMAND}
+ -D dir=${CMake_BINARY_DIR}/Tests/CMakeTestAllGenerators
+ -D CMake_SOURCE_DIR=${CMake_SOURCE_DIR}
+ -P ${CMake_SOURCE_DIR}/Tests/CMakeTestAllGenerators/RunCMake.cmake
+ )
+ LIST(APPEND TEST_BUILD_DIRS
+ "${CMake_BINARY_DIR}/Tests/CMakeTestAllGenerators")
+ ENDIF(CTEST_RUN_CMakeTestAllGenerators)
+
+ if(NOT DEFINED CTEST_RUN_CMakeTestBadCommandLines)
+ set(CTEST_RUN_CMakeTestBadCommandLines ON)
+ endif(NOT DEFINED CTEST_RUN_CMakeTestBadCommandLines)
+
+ 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(CTEST_RUN_CMakeTestBadCommandLines)
+
+ if(NOT DEFINED CTEST_RUN_CMakeTestMultipleConfigures)
+ set(CTEST_RUN_CMakeTestMultipleConfigures ON)
+ endif(NOT DEFINED CTEST_RUN_CMakeTestMultipleConfigures)
+
+ IF(CTEST_RUN_CMakeTestMultipleConfigures)
+ ADD_TEST(CMakeTestMultipleConfigures ${CMAKE_CMAKE_COMMAND}
+ -D dir=${CMake_BINARY_DIR}/Tests/CMakeTestMultipleConfigures
+ -D gen=${CMAKE_TEST_GENERATOR}
+ -D CMake_SOURCE_DIR=${CMake_SOURCE_DIR}
+ -P ${CMake_SOURCE_DIR}/Tests/CMakeTestMultipleConfigures/RunCMake.cmake
+ )
+ LIST(APPEND TEST_BUILD_DIRS
+ "${CMake_BINARY_DIR}/Tests/CMakeTestMultipleConfigures")
+ ENDIF(CTEST_RUN_CMakeTestMultipleConfigures)
+
+ ADD_TEST(LoadedCommandOneConfig ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/LoadCommandOneConfig"
+ "${CMake_BINARY_DIR}/Tests/LoadCommandOneConfig"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-project LoadCommand
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --test-command LoadedCommand
+ )
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/LoadCommandOneConfig")
+
+ ADD_TEST(complex ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/Complex"
+ "${CMake_BINARY_DIR}/Tests/Complex"
+ --build-two-config
+ --build-config-sample "${CMAKE_CTEST_COMMAND}"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-project Complex
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/Complex/bin"
+ --build-options
+ -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
+ --test-command complex
+ )
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Complex")
+
+ ADD_TEST(complexOneConfig ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/ComplexOneConfig"
+ "${CMake_BINARY_DIR}/Tests/ComplexOneConfig"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-project Complex
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/ComplexOneConfig/bin"
+ --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 ${CMAKE_TEST_GENERATOR}
+ --build-project HELLO
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --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"
+ "${CMake_BINARY_DIR}/Tests/Environment"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-project EnvironmentProj
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/Environment"
+ --force-new-ctest-process
+ --test-command ${CMAKE_CTEST_COMMAND} -V
+ )
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Environment")
+
+ IF(QT4_WORKS AND QT_QTGUI_FOUND)
+ ADD_TEST(QtAutomoc ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/QtAutomoc"
+ "${CMake_BINARY_DIR}/Tests/QtAutomoc"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-project QtAutomoc
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/QtAutomoc"
+ --force-new-ctest-process
+ --build-options -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}
+ --test-command ${CMAKE_CTEST_COMMAND} -V
+ )
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/QtAutomoc")
+ ENDIF()
+
+ ADD_TEST(ExternalProject ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/ExternalProject"
+ "${CMake_BINARY_DIR}/Tests/ExternalProject"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-project ExternalProjectTest
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/ExternalProject"
+ --force-new-ctest-process
+ --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})
+
+ # do each of the tutorial steps
+ FOREACH(STP RANGE 1 7)
+ ADD_TEST(TutorialStep${STP} ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/Tutorial/Step${STP}"
+ "${CMake_BINARY_DIR}/Tests/Tutorial/Step${STP}"
+ --build-two-config
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-project Tutorial
+ --test-command Tutorial 25.0)
+ ENDFOREACH(STP)
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Tutorial")
+
+ ADD_TEST(testing ${CMAKE_CTEST_COMMAND} -C \${CTEST_CONFIGURATION_TYPE}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/Testing"
+ "${CMake_BINARY_DIR}/Tests/Testing"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-project Testing
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --test-command ${CMAKE_CTEST_COMMAND} -C \${CTEST_CONFIGURATION_TYPE}
+ )
+ SET_TESTS_PROPERTIES(testing PROPERTIES PASS_REGULAR_EXPRESSION "Passed")
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Testing")
+
+ ADD_TEST(wrapping ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/Wrapping"
+ "${CMake_BINARY_DIR}/Tests/Wrapping"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-project Wrapping
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/Wrapping/bin"
+ --test-command wrapping
+ )
+ ADD_TEST(qtwrapping ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/Wrapping"
+ "${CMake_BINARY_DIR}/Tests/Wrapping"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-project Wrapping
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/Wrapping/bin"
+ --test-command qtwrapping
+ )
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Wrapping")
+
+ ADD_TEST(testdriver1 ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/TestDriver"
+ "${CMake_BINARY_DIR}/Tests/TestDriver"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/Wrapping/bin"
+ --build-project TestDriverTest
+ --test-command TestDriverTest test1
+ )
+
+ ADD_TEST(testdriver2 ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/TestDriver"
+ "${CMake_BINARY_DIR}/Tests/TestDriver"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/Wrapping/bin"
+ --build-project TestDriverTest
+ --test-command TestDriverTest test2
+ )
+
+ ADD_TEST(testdriver3 ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/TestDriver"
+ "${CMake_BINARY_DIR}/Tests/TestDriver"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/Wrapping/bin"
+ --build-project TestDriverTest
+ --test-command TestDriverTest subdir/test3
+ )
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/TestDriver")
+
+ ADD_TEST(Dependency ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/Dependency"
+ "${CMake_BINARY_DIR}/Tests/Dependency"
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/Dependency/Exec"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-project Dependency
+ --test-command exec
+ )
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Dependency")
+
+ 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
+# in the tests would have to be adjusted to ${EXECUTABLE_OUTPUT_DIR}/lib .
+# For now we just require on Syllable that the user adjusts the DLL_PATH
+# environment variable, so except the two tests below all other tests will succeed.
+
+ SET(_DLL_PATH "$ENV{DLL_PATH}")
+ IF(NOT "${_DLL_PATH}" MATCHES "^(.*:)?\\@bindir\\@/\\.(:.*)?$")
+ MESSAGE(FATAL_ERROR "In order to successfully run the CMake test suite on Syllable you need to add \"\\@bindir\\@/.\" to the DLL_PATH environment variable")
+ ENDIF(NOT "${_DLL_PATH}" MATCHES "^(.*:)?\\@bindir\\@/\\.(:.*)?$")
+ IF(NOT "${_DLL_PATH}" MATCHES "^(.*:)?\\@bindir\\@/\\.\\./lib(:.*)?$")
+ MESSAGE(FATAL_ERROR "In order to successfully run the CMake test suite on Syllable you need to add \"\\@bindir\\@/../lib\" to the DLL_PATH environment variable")
+ ENDIF(NOT "${_DLL_PATH}" MATCHES "^(.*:)?\\@bindir\\@/\\.\\./lib(:.*)?$")
+
+ ELSE("${CMAKE_SYSTEM_NAME}" MATCHES syllable)
+
+ ADD_TEST(JumpWithLibOut ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/Jump"
+ "${CMake_BINARY_DIR}/Tests/Jump/WithLibOut"
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/Jump/WithLibOut/Executable"
+ --build-project Jump
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-options
+ -DLIBRARY_OUTPUT_PATH:PATH=${CMake_BINARY_DIR}/Tests/Jump/WithLibOut/Lib
+ --test-command jumpExecutable
+ )
+
+ ADD_TEST(JumpNoLibOut ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/Jump"
+ "${CMake_BINARY_DIR}/Tests/Jump/NoLibOut"
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/Jump/NoLibOut/Executable"
+ --build-run-dir "${CMake_BINARY_DIR}/Tests/Jump/NoLibOut/Executable"
+ --build-project Jump
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --test-command jumpExecutable
+ )
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Jump")
+
+ ADD_TEST(Plugin ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/Plugin"
+ "${CMake_BINARY_DIR}/Tests/Plugin"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-project Plugin
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-two-config
+ --test-command bin/example)
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Plugin")
+
+ IF(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG)
+ ADD_TEST_MACRO(RuntimePath RuntimePath)
+ ENDIF(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG)
+ ENDIF("${CMAKE_SYSTEM_NAME}" MATCHES syllable)
+
+ ADD_TEST(linkorder1 ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/LinkLineOrder"
+ "${CMake_BINARY_DIR}/Tests/LinkLineOrder"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-project LinkLineOrder
+ --test-command Exec1
+ )
+
+ ADD_TEST(linkorder2 ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/LinkLineOrder"
+ "${CMake_BINARY_DIR}/Tests/LinkLineOrder"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-project LinkLineOrder
+ --test-command Exec2
+ )
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/LinkLineOrder")
+ SET_TESTS_PROPERTIES ( qtwrapping PROPERTIES DEPENDS wrapping)
+ SET_TESTS_PROPERTIES ( testdriver1 PROPERTIES DEPENDS qtwrapping)
+ SET_TESTS_PROPERTIES ( testdriver2 PROPERTIES DEPENDS testdriver1)
+ SET_TESTS_PROPERTIES ( testdriver3 PROPERTIES DEPENDS testdriver2)
+ SET_TESTS_PROPERTIES ( linkorder2 PROPERTIES DEPENDS linkorder1)
+ SET_TESTS_PROPERTIES ( SimpleInstall-Stage2 PROPERTIES DEPENDS SimpleInstall)
+
+ # Test static linking on toolchains known to support it.
+ IF("${CMAKE_C_COMPILER_ID}" MATCHES "^(GNU)$"
+ AND NOT APPLE AND NOT WIN32 AND NOT CYGWIN
+ AND EXISTS "/usr/lib/libm.a")
+ ADD_TEST(LinkStatic ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/LinkStatic"
+ "${CMake_BINARY_DIR}/Tests/LinkStatic"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-project LinkStatic
+ --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 ${CMAKE_TEST_GENERATOR}
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-project kwsys
+ --test-command kwsysTestsCxx testIOS
+ )
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/kwsys")
+ ENDIF(NOT CMAKE_TEST_DIFFERENT_GENERATOR)
+ SET(MAKE_IS_GNU )
+ IF(${CMAKE_TEST_MAKEPROGRAM} MATCHES make)
+ EXEC_PROGRAM(
+ ${CMAKE_TEST_MAKEPROGRAM} ARGS no_such_target --version
+ RETURN_VALUE res OUTPUT_VARIABLE out
+ )
+ IF("${res}" EQUAL 0)
+ IF("${out}" MATCHES "GNU")
+ SET(MAKE_IS_GNU 1)
+ ENDIF("${out}" MATCHES "GNU")
+ ENDIF("${res}" EQUAL 0)
+ ENDIF(${CMAKE_TEST_MAKEPROGRAM} MATCHES make)
+
+ # only add this test on platforms that support it
+ # 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")
+ ADD_TEST(SubDirSpaces ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/SubDirSpaces"
+ "${CMake_BINARY_DIR}/Tests/SubDirSpaces"
+ --build-exe-dir
+ "${CMake_BINARY_DIR}/Tests/SubDirSpaces/Executable Sources"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-project SUBDIR
+ --test-command test
+ "${CMake_BINARY_DIR}/Tests/SubDirSpaces/ShouldBeHere"
+ "${CMake_BINARY_DIR}/Tests/SubDirSpaces/testfromsubdir.obj"
+ )
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/SubDirSpaces")
+ ENDIF (MAKE_IS_GNU OR
+ "${CMAKE_TEST_MAKEPROGRAM}" MATCHES "nmake|gmake|wmake" OR
+ "${CMAKE_TEST_GENERATOR}" MATCHES "Visual Studio|XCode|Borland")
+
+ IF (WIN32)
+ ADD_TEST(SubDir ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/SubDir"
+ "${CMake_BINARY_DIR}/Tests/SubDir"
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/SubDir/Executable"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-project SUBDIR
+ --test-command test
+ "${CMake_BINARY_DIR}/Tests/SubDir/ShouldBeHere"
+ "${CMake_BINARY_DIR}/Tests/SubDir/testfromsubdir.obj"
+ )
+ ELSE (WIN32)
+ ADD_TEST(SubDir ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/SubDir"
+ "${CMake_BINARY_DIR}/Tests/SubDir"
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/SubDir/Executable"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-project SUBDIR
+ --test-command test
+ "${CMake_BINARY_DIR}/Tests/SubDir/ShouldBeHere"
+ "${CMake_BINARY_DIR}/Tests/SubDir/testfromsubdir.o"
+ )
+ ENDIF (WIN32)
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/SubDir")
+
+ IF(CMAKE_TEST_MSVC)
+ ADD_TEST_MACRO(ForceInclude foo)
+ ADD_TEST_MACRO(PrecompiledHeader foo)
+ ENDIF()
+ IF(CMAKE_TEST_MSVC OR
+ "${CMAKE_TEST_GENERATOR}" MATCHES "(MSYS|MinGW) Makefiles")
+ ADD_TEST_MACRO(ModuleDefinition example_exe)
+ ENDIF()
+
+ ADD_TEST_MACRO(CheckCompilerRelatedVariables CheckCompilerRelatedVariables)
+
+ IF("${CMAKE_TEST_GENERATOR}" MATCHES "Makefile")
+ ADD_TEST(MakeClean ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/MakeClean"
+ "${CMake_BINARY_DIR}/Tests/MakeClean"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-project MakeClean
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-exe-dir "${CMake_BINARY_DIR}/MakeClean"
+ --test-command check_clean
+ )
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/MakeClean")
+ ENDIF("${CMAKE_TEST_GENERATOR}" MATCHES "Makefile")
+
+ if(NOT DEFINED CTEST_RUN_MFC)
+ set(CTEST_RUN_MFC OFF)
+
+ if(MSVC)
+ set(CTEST_RUN_MFC ON)
+
+ # Look for evidence that this is a VCExpress build. If so, avoid
+ # the MFC test by default.
+ string(TOLOWER "${CMAKE_TEST_MAKEPROGRAM}" mkprog)
+ if(mkprog MATCHES "vcexpress")
+ message(STATUS
+ "CMAKE_TEST_MAKEPROGRAM indicates vcexpress, avoiding MFC test")
+ set(CTEST_RUN_MFC OFF)
+ endif()
+
+ # Since MSBuild might also be the "makeprogram" for a VCExpress
+ # build tree, use one more heuristic, too. The string representing
+ # the .vcproj file type contains "VCExpress" on machines where an
+ # express edition of VS was installed last:
+ if(CTEST_RUN_MFC)
+ execute_process(COMMAND cmd /c assoc .vcproj
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ OUTPUT_VARIABLE ov)
+ if(ov MATCHES "VCExpress")
+ message(STATUS
+ ".vcproj file association indicates VCExpress, avoiding MFC test")
+ set(CTEST_RUN_MFC OFF)
+ endif()
+ endif()
+
+ # For the Watcom WMake generator, avoid the MFC test by default.
+ if(CTEST_RUN_MFC)
+ if("${CMAKE_TEST_GENERATOR}" MATCHES "WMake")
+ message(STATUS
+ "using the Watcom WMake generator, avoiding MFC test")
+ set(CTEST_RUN_MFC OFF)
+ endif()
+ endif()
+
+ # Last resort, after quick checks are done. Do a try_compile, and avoid
+ # the MFC test if the simplest possible MFC app cannot be compiled.
+ if(CTEST_RUN_MFC AND NOT DEFINED HAVE_MFC)
+ configure_file(
+ ${CMAKE_CURRENT_SOURCE_DIR}/MFC/try_compile/CMakeLists.txt
+ ${CMAKE_CURRENT_BINARY_DIR}/MFC/try_compile/CMakeLists.txt
+ COPYONLY
+ )
+ configure_file(
+ ${CMAKE_CURRENT_SOURCE_DIR}/MFC/mfc1/stdafx.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/MFC/try_compile/stdafx.cpp
+ COPYONLY
+ )
+ configure_file(
+ ${CMAKE_CURRENT_SOURCE_DIR}/MFC/mfc1/stdafx.h
+ ${CMAKE_CURRENT_BINARY_DIR}/MFC/try_compile/stdafx.h
+ COPYONLY
+ )
+
+ message(STATUS "Looking for MFC")
+
+ try_compile(HAVE_MFC
+ ${CMAKE_CURRENT_BINARY_DIR}/MFC/try_compile/build
+ ${CMAKE_CURRENT_BINARY_DIR}/MFC/try_compile
+ try_compile_mfc
+ OUTPUT_VARIABLE HAVE_MFC_OUTPUT)
+
+ if(HAVE_MFC)
+ message(STATUS "Looking for MFC - found")
+ set(HAVE_MFC 1 CACHE INTERNAL "Have MFC")
+ file(APPEND
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "Determining if MFC exists passed with the following output:\n"
+ "${HAVE_MFC_OUTPUT}\n\n")
+ else()
+ message(STATUS "Looking for MFC - not found")
+ set(HAVE_MFC "" CACHE INTERNAL "Have MFC")
+ file(APPEND
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Determining if MFC exists failed with the following output:\n"
+ "${HAVE_MFC_OUTPUT}\n\n")
+ endif()
+ endif()
+
+ if(CTEST_RUN_MFC AND NOT HAVE_MFC)
+ message(STATUS
+ "cannot compile simplest ever MFC app, avoiding MFC test")
+ set(CTEST_RUN_MFC OFF)
+ endif()
+ endif()
+ endif()
+
+ if(CTEST_RUN_MFC)
+ add_test(MFC ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/MFC"
+ "${CMake_BINARY_DIR}/Tests/MFC"
+ --build-two-config
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-project mfc_driver
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --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(NOT MSVC60)
+ ADD_TEST_MACRO(SBCS SBCS)
+ ENDIF(NOT MSVC60)
+
+ ADD_TEST(VSExternalInclude ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/VSExternalInclude"
+ "${CMake_BINARY_DIR}/Tests/VSExternalInclude"
+ --build-two-config
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-project VSExternalInclude
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --test-command VSExternalInclude)
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/VSExternalInclude")
+
+ ADD_TEST(VSMidl ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/VSMidl"
+ "${CMake_BINARY_DIR}/Tests/VSMidl"
+ --build-two-config
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-project VSMidl
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --test-command VSMidl)
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/VSMidl")
+ ENDIF(${CMAKE_TEST_GENERATOR} MATCHES "Visual Studio")
+
+ IF (APPLE)
+ if (CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
+ SET(BundleTestInstallDir
+ "${CMake_BINARY_DIR}/Tests/BundleTest/InstallDirectory")
+ ADD_TEST(BundleTest ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/BundleTest"
+ "${CMake_BINARY_DIR}/Tests/BundleTest"
+ --build-two-config
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-project BundleTest
+ --build-target install
+# --build-target package
+ --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}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/CFBundleTest"
+ "${CMake_BINARY_DIR}/Tests/CFBundleTest"
+ --build-two-config
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-project CFBundleTest
+ --test-command
+ ${CMAKE_CMAKE_COMMAND} -DCTEST_CONFIGURATION_TYPE=\${CTEST_CONFIGURATION_TYPE}
+ -Ddir=${CMake_BINARY_DIR}/Tests/CFBundleTest
+ -Dgen=${CMAKE_TEST_GENERATOR}
+ -P ${CMake_SOURCE_DIR}/Tests/CFBundleTest/VerifyResult.cmake)
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/CFBundleTest")
+
+ ADD_TEST_MACRO(ObjC++ ObjC++)
+ ENDIF (CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
+ ENDIF (APPLE)
+
+ IF(APPLE AND CTEST_TEST_CPACK)
+ ADD_TEST(BundleGeneratorTest ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/BundleGeneratorTest"
+ "${CMake_BINARY_DIR}/Tests/BundleGeneratorTest"
+ --build-two-config
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-project BundleGeneratorTest
+ --build-target package
+ --build-options "-DCMAKE_INSTALL_PREFIX:PATH=${CMake_BINARY_DIR}/Tests/BundleGeneratorTest/InstallDirectory"
+ )
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/BundleGeneratorTest")
+ ENDIF(APPLE AND CTEST_TEST_CPACK)
+
+ ADD_TEST(WarnUnusedUnusedViaSet ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/VariableUnusedViaSet"
+ "${CMake_BINARY_DIR}/Tests/WarnUnusedUnusedViaSet"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-noclean
+ --build-project WarnUnusedUnusedViaSet
+ --build-options "--warn-unused-vars")
+ SET_TESTS_PROPERTIES(WarnUnusedUnusedViaSet PROPERTIES
+ PASS_REGULAR_EXPRESSION "unused variable \\(changing definition\\) 'UNUSED_VARIABLE'")
+ SET_TESTS_PROPERTIES(WarnUnusedUnusedViaSet PROPERTIES
+ FAIL_REGULAR_EXPRESSION "unused variable \\(unsetting\\) 'UNUSED_VARIABLE'")
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/WarnUnusedUnusedViaSet")
+
+ ADD_TEST(WarnUnusedUnusedViaUnset ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/VariableUnusedViaUnset"
+ "${CMake_BINARY_DIR}/Tests/WarnUnusedUnusedViaUnset"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-noclean
+ --build-project WarnUnusedUnusedViaUnset
+ --build-options "--warn-unused-vars")
+ SET_TESTS_PROPERTIES(WarnUnusedUnusedViaUnset PROPERTIES
+ PASS_REGULAR_EXPRESSION "CMake Warning .*:7 \\(set\\):")
+ SET_TESTS_PROPERTIES(WarnUnusedUnusedViaUnset PROPERTIES
+ FAIL_REGULAR_EXPRESSION "CMake Warning .*:5 \\(set\\):")
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/WarnUnusedUnusedViaUnset")
+
+ ADD_TEST(WarnUnusedCliUnused ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/VariableUsage"
+ "${CMake_BINARY_DIR}/Tests/WarnUnusedCliUnused"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-noclean
+ --build-project WarnUnusedCliUnused
+ --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")
+
+ ADD_TEST(WarnUnusedCliUsed ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/VariableUsage"
+ "${CMake_BINARY_DIR}/Tests/WarnUnusedCliUsed"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-noclean
+ --build-project WarnUnusedCliUsed
+ --build-options "-DUSED_VARIABLE=Usage proven")
+ SET_TESTS_PROPERTIES(WarnUnusedCliUsed PROPERTIES
+ PASS_REGULAR_EXPRESSION "Usage proven")
+ SET_TESTS_PROPERTIES(WarnUnusedCliUsed PROPERTIES
+ FAIL_REGULAR_EXPRESSION "CMake Warning: The variable, 'USED_VARIABLE'")
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/WarnUnusedCliUsed")
+
+ ADD_TEST(WarnUninitialized ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/VariableUsage"
+ "${CMake_BINARY_DIR}/Tests/WarnUninitialized"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-noclean
+ --build-project WarnUninitialized
+ --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}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/TestsWorkingDirectory"
+ "${CMake_BINARY_DIR}/Tests/TestsWorkingDirectory"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-project TestsWorkingDirectoryProj
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/TestsWorkingDirectory"
+ --force-new-ctest-process
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C \${CTEST_CONFIGURATION_TYPE}
+ )
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/TestsWorkingDirectory")
+
+ # Make sure CTest can handle a test with no newline in output.
+ ADD_TEST(CTest.NoNewline
+ ${CMAKE_CMAKE_COMMAND} -E echo_append "This line has no newline!")
+
+ # A simple test for ctest in script mode
+ CONFIGURE_FILE("${CMake_SOURCE_DIR}/Tests/CTestScriptMode/CTestTestScriptMode.cmake.in"
+ "${CMake_BINARY_DIR}/Tests/CTestScriptMode/CTestTestScriptMode.cmake" @ONLY)
+# ADD_TEST(CTest.ScriptMode ${CMAKE_CTEST_COMMAND}
+# -S "${CMake_BINARY_DIR}/Tests/CTestScriptMode/CTestTestScriptMode.cmake"
+# )
+
+ SET(CTEST_TEST_UPDATE 1)
+ IF(CTEST_TEST_UPDATE)
+ # Test CTest Update with Subversion
+ FIND_PACKAGE(Subversion QUIET)
+ IF(Subversion_FOUND)
+ GET_FILENAME_COMPONENT(_Subversion_BIN_DIR
+ ${Subversion_SVN_EXECUTABLE} PATH)
+ FIND_PROGRAM(Subversion_SVNADMIN_EXECUTABLE svnadmin
+ HINTS ${_Subversion_BIN_DIR}
+ )
+ MARK_AS_ADVANCED(Subversion_SVNADMIN_EXECUTABLE)
+ IF(NOT Subversion_SVNADMIN_EXECUTABLE)
+ SET(Subversion_FOUND FALSE)
+ ENDIF(NOT Subversion_SVNADMIN_EXECUTABLE)
+ ENDIF(Subversion_FOUND)
+ IF(Subversion_FOUND)
+ SET(CTestUpdateSVN_DIR "CTest UpdateSVN")
+ CONFIGURE_FILE("${CMake_SOURCE_DIR}/Tests/CTestUpdateSVN.cmake.in"
+ "${CMake_BINARY_DIR}/Tests/CTestUpdateSVN.cmake" @ONLY)
+ ADD_TEST(CTest.UpdateSVN ${CMAKE_CMAKE_COMMAND}
+ -P "${CMake_BINARY_DIR}/Tests/CTestUpdateSVN.cmake"
+ )
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/${CTestUpdateSVN_DIR}")
+ ENDIF(Subversion_FOUND)
+
+ # Test CTest Update with CVS
+ IF(EXISTS ${CMAKE_ROOT}/Modules/FindCVS.cmake)
+ FIND_PACKAGE(CVS QUIET)
+ ELSE(EXISTS ${CMAKE_ROOT}/Modules/FindCVS.cmake)
+ FIND_PROGRAM(CVS_EXECUTABLE NAMES cvs)
+ SET(CVS_FOUND ${CVS_EXECUTABLE})
+ ENDIF(EXISTS ${CMAKE_ROOT}/Modules/FindCVS.cmake)
+ SET(CTEST_TEST_UPDATE_CVS ${CVS_FOUND})
+ IF(CTEST_TEST_UPDATE_CVS AND NOT UNIX)
+ IF("${CVS_EXECUTABLE}" MATCHES "cygwin")
+ MESSAGE(STATUS "No CTest.UpdateCVS test with cygwin cvs.exe outside cygwin!")
+ SET(CTEST_TEST_UPDATE_CVS 0)
+ ENDIF("${CVS_EXECUTABLE}" MATCHES "cygwin")
+ ENDIF(CTEST_TEST_UPDATE_CVS AND NOT UNIX)
+ IF(CTEST_TEST_UPDATE_CVS)
+ SET(CTestUpdateCVS_DIR "CTest UpdateCVS")
+ CONFIGURE_FILE("${CMake_SOURCE_DIR}/Tests/CTestUpdateCVS.cmake.in"
+ "${CMake_BINARY_DIR}/Tests/CTestUpdateCVS.cmake" @ONLY)
+ ADD_TEST(CTest.UpdateCVS ${CMAKE_CMAKE_COMMAND}
+ -P "${CMake_BINARY_DIR}/Tests/CTestUpdateCVS.cmake"
+ )
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/${CTestUpdateCVS_DIR}")
+ ENDIF(CTEST_TEST_UPDATE_CVS)
+
+ # Test CTest Update with BZR
+ FIND_PROGRAM(BZR_EXECUTABLE NAMES bzr)
+ MARK_AS_ADVANCED(BZR_EXECUTABLE)
+ SET(CTEST_TEST_UPDATE_BZR 0)
+ IF(BZR_EXECUTABLE)
+ IF(NOT "${BZR_EXECUTABLE}" MATCHES "cygwin" OR UNIX)
+ SET(CTEST_TEST_UPDATE_BZR 1)
+ ENDIF(NOT "${BZR_EXECUTABLE}" MATCHES "cygwin" OR UNIX)
+ ENDIF(BZR_EXECUTABLE)
+ IF(CTEST_TEST_UPDATE_BZR)
+ # Check if xmloutput plugin is there
+ EXECUTE_PROCESS(COMMAND ${BZR_EXECUTABLE} xmlplugins RESULT_VARIABLE xmlplugres
+ OUTPUT_QUIET ERROR_QUIET)
+ IF( NOT ${xmlplugres} )
+ SET(CTestUpdateBZR_DIR "CTest UpdateBZR")
+ CONFIGURE_FILE("${CMake_SOURCE_DIR}/Tests/CTestUpdateBZR.cmake.in"
+ "${CMake_BINARY_DIR}/Tests/CTestUpdateBZR.cmake" @ONLY)
+ ADD_TEST(CTest.UpdateBZR ${CMAKE_CMAKE_COMMAND}
+ -P "${CMake_BINARY_DIR}/Tests/CTestUpdateBZR.cmake"
+ )
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/${CTestUpdateBZR_DIR}")
+ SET(CTestUpdateBZR_DIR "CTest UpdateBZR_CLocale")
+ CONFIGURE_FILE("${CMake_SOURCE_DIR}/Tests/CTestUpdateBZR.cmake.in"
+ "${CMake_BINARY_DIR}/Tests/CTestUpdateBZR_CLocale.cmake" @ONLY)
+ ADD_TEST(CTest.UpdateBZR.CLocale ${CMAKE_CMAKE_COMMAND}
+ -P "${CMake_BINARY_DIR}/Tests/CTestUpdateBZR_CLocale.cmake"
+ )
+ SET_TESTS_PROPERTIES(CTest.UpdateBZR.CLocale PROPERTIES ENVIRONMENT LC_ALL=C)
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/${CTestUpdateBZR_DIR}")
+ ENDIF( NOT ${xmlplugres} )
+ ENDIF(CTEST_TEST_UPDATE_BZR)
+
+ # Test CTest Update with GIT
+ FIND_PROGRAM(GIT_EXECUTABLE NAMES git)
+ MARK_AS_ADVANCED(GIT_EXECUTABLE)
+ SET(CTEST_TEST_UPDATE_GIT 0)
+ IF(GIT_EXECUTABLE)
+ IF(NOT "${GIT_EXECUTABLE}" MATCHES "cygwin" OR UNIX)
+ SET(CTEST_TEST_UPDATE_GIT 1)
+ ENDIF(NOT "${GIT_EXECUTABLE}" MATCHES "cygwin" OR UNIX)
+ ENDIF(GIT_EXECUTABLE)
+ IF(CTEST_TEST_UPDATE_GIT)
+ SET(CTestUpdateGIT_DIR "CTest UpdateGIT")
+ CONFIGURE_FILE("${CMake_SOURCE_DIR}/Tests/CTestUpdateGIT.cmake.in"
+ "${CMake_BINARY_DIR}/Tests/CTestUpdateGIT.cmake" @ONLY)
+ ADD_TEST(CTest.UpdateGIT ${CMAKE_CMAKE_COMMAND}
+ -P "${CMake_BINARY_DIR}/Tests/CTestUpdateGIT.cmake"
+ )
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/${CTestUpdateGIT_DIR}")
+ ENDIF(CTEST_TEST_UPDATE_GIT)
+
+ # Test CTest Update with HG
+ FIND_PROGRAM(HG_EXECUTABLE NAMES hg)
+ MARK_AS_ADVANCED(HG_EXECUTABLE)
+ SET(CTEST_TEST_UPDATE_HG 0)
+ IF(HG_EXECUTABLE)
+ IF(NOT "${HG_EXECUTABLE}" MATCHES "cygwin" OR UNIX)
+ SET(CTEST_TEST_UPDATE_HG 1)
+ ENDIF(NOT "${HG_EXECUTABLE}" MATCHES "cygwin" OR UNIX)
+ ENDIF(HG_EXECUTABLE)
+ IF(CTEST_TEST_UPDATE_HG)
+ SET(CTestUpdateHG_DIR "CTest UpdateHG")
+ CONFIGURE_FILE("${CMake_SOURCE_DIR}/Tests/CTestUpdateHG.cmake.in"
+ "${CMake_BINARY_DIR}/Tests/CTestUpdateHG.cmake" @ONLY)
+ ADD_TEST(CTest.UpdateHG ${CMAKE_CMAKE_COMMAND}
+ -P "${CMake_BINARY_DIR}/Tests/CTestUpdateHG.cmake"
+ )
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/${CTestUpdateHG_DIR}")
+ ENDIF(CTEST_TEST_UPDATE_HG)
+ ENDIF(CTEST_TEST_UPDATE)
+
+ CONFIGURE_FILE(
+ "${CMake_SOURCE_DIR}/Tests/CTestTestFailure/testNoBuild.cmake.in"
+ "${CMake_BINARY_DIR}/Tests/CTestTestFailure/testNoBuild.cmake"
+ @ONLY ESCAPE_QUOTES)
+ ADD_TEST(CTestTestNoBuild ${CMAKE_CTEST_COMMAND}
+ -S "${CMake_BINARY_DIR}/Tests/CTestTestFailure/testNoBuild.cmake" -V
+ --output-log "${CMake_BINARY_DIR}/Tests/CTestTestFailure/testOut1.log"
+ )
+ SET_TESTS_PROPERTIES(CTestTestNoBuild PROPERTIES
+ FAIL_REGULAR_EXPRESSION "Error" WILL_FAIL true)
+
+ CONFIGURE_FILE(
+ "${CMake_SOURCE_DIR}/Tests/CTestTestFailure/testNoExe.cmake.in"
+ "${CMake_BINARY_DIR}/Tests/CTestTestFailure/testNoExe.cmake"
+ @ONLY ESCAPE_QUOTES)
+ ADD_TEST(CTestTestNoExe ${CMAKE_CTEST_COMMAND}
+ -S "${CMake_BINARY_DIR}/Tests/CTestTestFailure/testNoExe.cmake" -V
+ --output-log "${CMake_BINARY_DIR}/Tests/CTestTestFailure/testOut2.log"
+ )
+ SET_TESTS_PROPERTIES(CTestTestNoExe PROPERTIES DEPENDS CTestTestNoBuild
+ PASS_REGULAR_EXPRESSION "Could not find executable"
+ FAIL_REGULAR_EXPRESSION "SegFault")
+
+ CONFIGURE_FILE(
+ "${CMake_SOURCE_DIR}/Tests/CTestTestUpload/test.cmake.in"
+ "${CMake_BINARY_DIR}/Tests/CTestTestUpload/test.cmake"
+ @ONLY ESCAPE_QUOTES)
+ ADD_TEST(CTestTestUpload ${CMAKE_CTEST_COMMAND}
+ -S "${CMake_BINARY_DIR}/Tests/CTestTestUpload/test.cmake" -V
+ --output-log "${CMake_BINARY_DIR}/Tests/CTestTestUpload/testOut.log"
+ )
+ SET_TESTS_PROPERTIES(CTestTestUpload PROPERTIES
+ PASS_REGULAR_EXPRESSION "Upload\\.xml")
+
+ CONFIGURE_FILE(
+ "${CMake_SOURCE_DIR}/Tests/CTestTestConfigFileInBuildDir/test1.cmake.in"
+ "${CMake_BINARY_DIR}/Tests/CTestTestConfigFileInBuildDir1/test1.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"
+ )
+ REGEX_ESCAPE_STRING(CTEST_TEST_ESCAPED_SOURCE_DIR "${CMake_SOURCE_DIR}")
+ SET_TESTS_PROPERTIES(CTestTestConfigFileInBuildDir1 PROPERTIES DEPENDS CTestTestNoBuild
+ PASS_REGULAR_EXPRESSION
+ "Reading ctest configuration file: ${CTEST_TEST_ESCAPED_SOURCE_DIR}.Tests.CTestTestConfigFileInBuildDir.CTestConfig.cmake")
+
+ CONFIGURE_FILE(
+ "${CMake_SOURCE_DIR}/Tests/CTestTestConfigFileInBuildDir/test2.cmake.in"
+ "${CMake_BINARY_DIR}/Tests/CTestTestConfigFileInBuildDir2/test2.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"
+ )
+ 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")
+
+ # test coverage for mumps
+ # create a MumpsCoverage dir in the binary tree under Testing to
+ # avoid the .NoDartCoverage files in the cmake testing tree
+ configure_file(
+ "${CMake_SOURCE_DIR}/Tests/MumpsCoverage/DartConfiguration.tcl.in"
+ "${CMake_BINARY_DIR}/Testing/MumpsCoverage/DartConfiguration.tcl")
+ configure_file(
+ "${CMake_SOURCE_DIR}/Tests/MumpsCoverage/gtm_coverage.mcov.in"
+ "${CMake_BINARY_DIR}/Testing/MumpsCoverage/gtm_coverage.mcov")
+ file(COPY "${CMake_SOURCE_DIR}/Tests/MumpsCoverage/VistA-FOIA"
+ DESTINATION "${CMake_BINARY_DIR}/Testing/MumpsCoverage")
+ add_test(NAME CTestGTMCoverage
+ COMMAND cmake -E chdir
+ ${CMake_BINARY_DIR}/Testing/MumpsCoverage
+ $<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.*"
+ ENVIRONMENT COVFILE=)
+
+ configure_file(
+ "${CMake_SOURCE_DIR}/Tests/MumpsCoverage/DartConfiguration.cache.tcl.in"
+ "${CMake_BINARY_DIR}/Testing/MumpsCacheCoverage/DartConfiguration.tcl")
+ configure_file(
+ "${CMake_SOURCE_DIR}/Tests/MumpsCoverage/cache_coverage.cmcov.in"
+ "${CMake_BINARY_DIR}/Testing/MumpsCacheCoverage/cache_coverage.cmcov")
+ file(COPY "${CMake_SOURCE_DIR}/Tests/MumpsCoverage/VistA-FOIA"
+ DESTINATION "${CMake_BINARY_DIR}/Testing/MumpsCacheCoverage")
+ add_test(NAME CTestCacheCoverage
+ COMMAND cmake -E chdir
+ ${CMake_BINARY_DIR}/Testing/MumpsCacheCoverage
+ $<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.*"
+ 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}")
+ set(base "${CMake_BINARY_DIR}/Tests/CTestConfig")
+
+ # Test -S script with a -C config arg to ctest:
+ configure_file(
+ "${CMake_SOURCE_DIR}/Tests/CTestConfig/script.cmake.in"
+ "${base}/${cfg}-script.cmake"
+ @ONLY ESCAPE_QUOTES)
+ add_test(CTestConfig.Script.${cfg} ${CMAKE_CTEST_COMMAND}
+ -C ${cfg}
+ -S "${base}/${cfg}-script.cmake" -VV
+ --output-log "${base}/${cfg}-script.log"
+ )
+
+ # Test -D dashboard with a -C config arg to ctest.
+ # (Actual commands inside a cmake -P script because we need to be able to set
+ # the working directory reliably...)
+ configure_file(
+ "${CMake_SOURCE_DIR}/Tests/CTestConfig/dashboard.cmake.in"
+ "${base}/${cfg}-dashboard.cmake"
+ @ONLY ESCAPE_QUOTES)
+ add_test(CTestConfig.Dashboard.${cfg} ${CMAKE_CMAKE_COMMAND}
+ -P "${base}/${cfg}-dashboard.cmake" -VV
+ )
+ endmacro()
+
+ add_config_tests(Debug)
+ add_config_tests(MinSizeRel)
+ add_config_tests(Release)
+ add_config_tests(RelWithDebInfo)
+
+ # Test -S script with some -D variable definition args to ctest:
+ add_test(CTestConfig.ScriptWithArgs ${CMAKE_CTEST_COMMAND}
+ -C "Release"
+ -D arg1=this
+ -D arg2=that
+ -D "arg3=the other"
+ "-Darg4=this is the fourth"
+ -Darg5=the_fifth
+ -Darg6:STRING=value-with-type
+ -S "${CMake_SOURCE_DIR}/Tests/CTestConfig/ScriptWithArgs.cmake" -VV
+ --output-log "${CMake_BINARY_DIR}/Tests/CTestConfig/ScriptWithArgs.log"
+ )
+
+ ADD_TEST_MACRO(CMakeCommands.target_link_libraries target_link_libraries)
+
+ CONFIGURE_FILE(
+ "${CMake_SOURCE_DIR}/Tests/CTestTestCrash/test.cmake.in"
+ "${CMake_BINARY_DIR}/Tests/CTestTestCrash/test.cmake"
+ @ONLY ESCAPE_QUOTES)
+ ADD_TEST(CTestTestCrash ${CMAKE_CTEST_COMMAND}
+ -S "${CMake_BINARY_DIR}/Tests/CTestTestCrash/test.cmake" -V
+ --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")
+ SET_TESTS_PROPERTIES(CTestTestCrash PROPERTIES
+ PASS_REGULAR_EXPRESSION "Failed")
+ ELSE(CMAKE_TEST_GENERATOR MATCHES "Watcom WMake")
+ SET_TESTS_PROPERTIES(CTestTestCrash PROPERTIES
+ PASS_REGULAR_EXPRESSION "(Illegal|SegFault)")
+ ENDIF(CMAKE_TEST_GENERATOR MATCHES "Watcom WMake")
+
+ CONFIGURE_FILE(
+ "${CMake_SOURCE_DIR}/Tests/CTestTestBadExe/test.cmake.in"
+ "${CMake_BINARY_DIR}/Tests/CTestTestBadExe/test.cmake"
+ @ONLY ESCAPE_QUOTES)
+ ADD_TEST(CTestTestBadExe ${CMAKE_CTEST_COMMAND}
+ -S "${CMake_BINARY_DIR}/Tests/CTestTestBadExe/test.cmake" -V
+ --output-log "${CMake_BINARY_DIR}/Tests/CTestTestBadExe/testOutput.log"
+ )
+ SET(CTestTestBadExe_REGEX "BAD_COMMAND")
+ # some cygwin can not be made to produce a BAD_COMMAND error
+ # the best we can get from it is a failed test
+ IF(CYGWIN)
+ SET(CTestTestBadExe_REGEX "(\\*\\*\\*Failed)|BAD_COMMAND")
+ ENDIF()
+ SET_TESTS_PROPERTIES(CTestTestBadExe PROPERTIES
+ PASS_REGULAR_EXPRESSION "${CTestTestBadExe_REGEX}")
+
+ CONFIGURE_FILE(
+ "${CMake_SOURCE_DIR}/Tests/CTestTestParallel/test.cmake.in"
+ "${CMake_BINARY_DIR}/Tests/CTestTestParallel/test.cmake"
+ @ONLY ESCAPE_QUOTES)
+ ADD_TEST(CTestTestParallel ${CMAKE_CTEST_COMMAND}
+ -S "${CMake_BINARY_DIR}/Tests/CTestTestParallel/test.cmake" -V
+ --output-log "${CMake_BINARY_DIR}/Tests/CTestTestParallel/testOutput.log"
+ )
+
+ ADD_TEST(CTestTestPrintLabels ${CMAKE_CTEST_COMMAND} --print-labels)
+ SET_TESTS_PROPERTIES(CTestTestPrintLabels PROPERTIES LABELS "Label1;Label2")
+ SET_TESTS_PROPERTIES(CTestTestPrintLabels PROPERTIES PASS_REGULAR_EXPRESSION
+ "All Labels:.* Label1.* Label2")
+
+ CONFIGURE_FILE(
+ "${CMake_SOURCE_DIR}/Tests/CTestTestResourceLock/test.cmake.in"
+ "${CMake_BINARY_DIR}/Tests/CTestTestResourceLock/test.cmake"
+ @ONLY ESCAPE_QUOTES)
+ ADD_TEST(CTestTestResourceLock ${CMAKE_CTEST_COMMAND}
+ -S "${CMake_BINARY_DIR}/Tests/CTestTestResourceLock/test.cmake" -V
+ --output-log "${CMake_BINARY_DIR}/Tests/CTestTestResourceLock/output.log"
+ )
+
+ CONFIGURE_FILE(
+ "${CMake_SOURCE_DIR}/Tests/CTestTestScheduler/test.cmake.in"
+ "${CMake_BINARY_DIR}/Tests/CTestTestScheduler/test.cmake"
+ @ONLY ESCAPE_QUOTES)
+ ADD_TEST(CTestTestScheduler ${CMAKE_CTEST_COMMAND}
+ -S "${CMake_BINARY_DIR}/Tests/CTestTestScheduler/test.cmake" -V
+ --output-log "${CMake_BINARY_DIR}/Tests/CTestTestScheduler/testOutput.log"
+ )
+ SET_TESTS_PROPERTIES(CTestTestScheduler PROPERTIES
+ PASS_REGULAR_EXPRESSION "Start 1.*Start 2.*Start 3.*Start 4.*Start 4.*Start 3.*Start 2.*Start 1"
+ RESOURCE_LOCK "CostData")
+
+ CONFIGURE_FILE(
+ "${CMake_SOURCE_DIR}/Tests/CTestTestCostSerial/test.cmake.in"
+ "${CMake_BINARY_DIR}/Tests/CTestTestCostSerial/test.cmake"
+ @ONLY ESCAPE_QUOTES)
+ ADD_TEST(CTestTestCostSerial ${CMAKE_CTEST_COMMAND}
+ -S "${CMake_BINARY_DIR}/Tests/CTestTestCostSerial/test.cmake" -V
+ --output-log "${CMake_BINARY_DIR}/Tests/CTestTestCostSerial/testOutput.log"
+ )
+ SET_TESTS_PROPERTIES(CTestTestCostSerial PROPERTIES
+ PASS_REGULAR_EXPRESSION "Start 2.*Start 3.*Start 1.*Start 2.*Start 3.*Start 1"
+ RESOURCE_LOCK "CostData")
+
+ CONFIGURE_FILE(
+ "${CMake_SOURCE_DIR}/Tests/CTestTestStopTime/test.cmake.in"
+ "${CMake_BINARY_DIR}/Tests/CTestTestStopTime/test.cmake"
+ @ONLY ESCAPE_QUOTES)
+ CONFIGURE_FILE(
+ "${CMake_SOURCE_DIR}/Tests/CTestTestStopTime/GetDate.cmake"
+ "${CMake_BINARY_DIR}/Tests/CTestTestStopTime/GetDate.cmake"
+ COPYONLY)
+ ADD_TEST(CTestTestStopTime ${CMAKE_CTEST_COMMAND}
+ -S "${CMake_BINARY_DIR}/Tests/CTestTestStopTime/test.cmake" -V
+ --output-log "${CMake_BINARY_DIR}/Tests/CTestTestStopTime/testOutput.log"
+ )
+ SET_TESTS_PROPERTIES(CTestTestStopTime PROPERTIES
+ PASS_REGULAR_EXPRESSION "The stop time has been passed")
+
+ CONFIGURE_FILE(
+ "${CMake_SOURCE_DIR}/Tests/CTestTestSubdir/test.cmake.in"
+ "${CMake_BINARY_DIR}/Tests/CTestTestSubdir/test.cmake"
+ @ONLY ESCAPE_QUOTES)
+ ADD_TEST(CTestTestSubdir ${CMAKE_CTEST_COMMAND}
+ -S "${CMake_BINARY_DIR}/Tests/CTestTestSubdir/test.cmake" -V
+ --output-log "${CMake_BINARY_DIR}/Tests/CTestTestSubdir/testOutput.log"
+ )
+ #make sure all 3 subdirs were added
+ SET_TESTS_PROPERTIES(CTestTestSubdir PROPERTIES
+ PASS_REGULAR_EXPRESSION "0 tests failed out of 3")
+
+ CONFIGURE_FILE(
+ "${CMake_SOURCE_DIR}/Tests/CTestTestTimeout/test.cmake.in"
+ "${CMake_BINARY_DIR}/Tests/CTestTestTimeout/test.cmake"
+ @ONLY ESCAPE_QUOTES)
+ ADD_TEST(CTestTestTimeout ${CMAKE_CTEST_COMMAND}
+ -C "\${CTestTest_CONFIG}"
+ -S "${CMake_BINARY_DIR}/Tests/CTestTestTimeout/test.cmake" -V
+ --output-log "${CMake_BINARY_DIR}/Tests/CTestTestTimeout/testOutput.log"
+ )
+ SET_TESTS_PROPERTIES(CTestTestTimeout PROPERTIES
+ PASS_REGULAR_EXPRESSION "TestTimeout *\\.+ *\\*\\*\\*Timeout.*CheckChild *\\.+ *Passed")
+
+ CONFIGURE_FILE(
+ "${CMake_SOURCE_DIR}/Tests/CTestTestZeroTimeout/test.cmake.in"
+ "${CMake_BINARY_DIR}/Tests/CTestTestZeroTimeout/test.cmake"
+ @ONLY ESCAPE_QUOTES)
+ ADD_TEST(CTestTestZeroTimeout ${CMAKE_CTEST_COMMAND}
+ -S "${CMake_BINARY_DIR}/Tests/CTestTestZeroTimeout/test.cmake" -V
+ --output-log
+ "${CMake_BINARY_DIR}/Tests/CTestTestZeroTimeout/testOutput.log")
+ SET_TESTS_PROPERTIES(CTestTestZeroTimeout PROPERTIES
+ FAIL_REGULAR_EXPRESSION "\\*\\*\\*Timeout")
+
+ CONFIGURE_FILE(
+ "${CMake_SOURCE_DIR}/Tests/CTestTestDepends/test.cmake.in"
+ "${CMake_BINARY_DIR}/Tests/CTestTestDepends/test.cmake"
+ @ONLY ESCAPE_QUOTES)
+ ADD_TEST(CTestTestDepends ${CMAKE_CTEST_COMMAND}
+ -C "\${CTestTest_CONFIG}"
+ -S "${CMake_BINARY_DIR}/Tests/CTestTestDepends/test.cmake" -V
+ --output-log "${CMake_BINARY_DIR}/Tests/CTestTestDepends/testOutput.log"
+ )
+
+ CONFIGURE_FILE(
+ "${CMake_SOURCE_DIR}/Tests/CTestTestCycle/test.cmake.in"
+ "${CMake_BINARY_DIR}/Tests/CTestTestCycle/test.cmake"
+ @ONLY ESCAPE_QUOTES)
+ ADD_TEST(CTestTestCycle ${CMAKE_CTEST_COMMAND}
+ -C "\${CTestTest_CONFIG}"
+ -S "${CMake_BINARY_DIR}/Tests/CTestTestCycle/test.cmake" -V
+ --output-log "${CMake_BINARY_DIR}/Tests/CTestTestCycle/testOutput.log"
+ )
+ SET_TESTS_PROPERTIES(CTestTestCycle PROPERTIES
+ PASS_REGULAR_EXPRESSION "a cycle exists in the test dependency graph")
+
+ CONFIGURE_FILE(
+ "${CMake_SOURCE_DIR}/Tests/CTestTestRunScript/test.cmake.in"
+ "${CMake_BINARY_DIR}/Tests/CTestTestRunScript/test.cmake"
+ @ONLY ESCAPE_QUOTES)
+ CONFIGURE_FILE(
+ "${CMake_SOURCE_DIR}/Tests/CTestTestRunScript/hello.cmake.in"
+ "${CMake_BINARY_DIR}/Tests/CTestTestRunScript/hello.cmake"
+ @ONLY ESCAPE_QUOTES)
+ ADD_TEST(CTestTestRunScript ${CMAKE_CTEST_COMMAND}
+ -S "${CMake_BINARY_DIR}/Tests/CTestTestRunScript/test.cmake" -V
+ --output-log "${CMake_BINARY_DIR}/Tests/CTestTestRunScript/testOutput.log"
+ )
+
+ ADD_TEST(CTestTestShowOnly ${CMAKE_CTEST_COMMAND} -N)
+
+ ADD_TEST(CTestBatchTest ${CMAKE_CTEST_COMMAND} -B)
+
+ # 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 "^([^:]+)://([^/]+)(/.*)$")
+
+ IF ("${CMAKE_TESTS_CDASH_SERVER}" MATCHES "${regex}")
+ SET(protocol "${CMAKE_MATCH_1}")
+ SET(server "${CMAKE_MATCH_2}")
+ SET(path "${CMAKE_MATCH_3}")
+ ELSE ("${CMAKE_TESTS_CDASH_SERVER}" MATCHES "${regex}")
+ SET(protocol "http")
+ SET(server "www.cdash.org")
+ SET(path "/CDash")
+ MESSAGE("warning: CMAKE_TESTS_CDASH_SERVER does not match expected regex...")
+ MESSAGE(" ...using default url='${protocol}://${server}${path}' for CTestTest[23]")
+ ENDIF ("${CMAKE_TESTS_CDASH_SERVER}" MATCHES "${regex}")
+ ENDIF (CMAKE_TESTS_CDASH_SERVER)
+
+
+ IF (CTEST_TEST_CTEST AND CMAKE_RUN_LONG_TESTS AND CMAKE_TESTS_CDASH_SERVER)
+ CONFIGURE_FILE("${CMake_SOURCE_DIR}/Tests/CTestTest/test.cmake.in"
+ "${CMake_BINARY_DIR}/Tests/CTestTest/test.cmake" @ONLY ESCAPE_QUOTES)
+ ADD_TEST(CTestTest ${CMAKE_CTEST_COMMAND}
+ -S "${CMake_BINARY_DIR}/Tests/CTestTest/test.cmake" -V
+ --output-log "${CMake_BINARY_DIR}/Tests/CTestTest/testOutput.log"
+ )
+
+ CONFIGURE_FILE("${CMake_SOURCE_DIR}/Tests/CTestTest2/test.cmake.in"
+ "${CMake_BINARY_DIR}/Tests/CTestTest2/test.cmake" @ONLY ESCAPE_QUOTES)
+ ADD_TEST(CTestTest2 ${CMAKE_CTEST_COMMAND}
+ -S "${CMake_BINARY_DIR}/Tests/CTestTest2/test.cmake" -V
+ --output-log "${CMake_BINARY_DIR}/Tests/CTestTest2/testOutput.log"
+ )
+
+ CONFIGURE_FILE("${CMake_SOURCE_DIR}/Tests/CTestTestChecksum/test.cmake.in"
+ "${CMake_BINARY_DIR}/Tests/CTestTestChecksum/test.cmake" @ONLY
+ ESCAPE_QUOTES)
+ ADD_TEST(CTestTestChecksum ${CMAKE_CTEST_COMMAND}
+ -S "${CMake_BINARY_DIR}/Tests/CTestTestChecksum/test.cmake" -V
+ --output-log
+ "${CMake_BINARY_DIR}/Tests/CTestTestChecksum/testOutput.log"
+ )
+ SET_TESTS_PROPERTIES(CTestTestChecksum PROPERTIES PASS_REGULAR_EXPRESSION
+ "Submission failed: Checksum failed for file")
+
+ # these tests take a long time, make sure they have it
+ # if timeouts have not already been set
+ GET_TEST_PROPERTY(CTestTest TIMEOUT PREVIOUS_TIMEOUT)
+ IF ("${PREVIOUS_TIMEOUT}" MATCHES NOTFOUND)
+ SET_TESTS_PROPERTIES ( CTestTest
+ PROPERTIES TIMEOUT ${CMAKE_LONG_TEST_TIMEOUT})
+ ENDIF ("${PREVIOUS_TIMEOUT}" MATCHES NOTFOUND)
+
+ GET_TEST_PROPERTY(CTestTest2 TIMEOUT PREVIOUS_TIMEOUT)
+ IF ("${PREVIOUS_TIMEOUT}" MATCHES NOTFOUND)
+ SET_TESTS_PROPERTIES ( CTestTest2
+ PROPERTIES TIMEOUT ${CMAKE_LONG_TEST_TIMEOUT})
+ ENDIF ("${PREVIOUS_TIMEOUT}" MATCHES NOTFOUND)
+ ENDIF (CTEST_TEST_CTEST AND CMAKE_RUN_LONG_TESTS AND CMAKE_TESTS_CDASH_SERVER)
+
+ IF (CMAKE_RUN_LONG_TESTS AND TEST_KDE4_STABLE_BRANCH)
+ IF(UNIX)
+ IF(NOT QT4_FOUND)
+ FIND_PACKAGE(Qt4)
+ ENDIF(NOT QT4_FOUND)
+
+ SET(TRY_BUILD_KDE4 TRUE)
+ IF(QT4_FOUND)
+ # check whether it's Qt 4.5 in a cmake 2.4. compatible way:
+ IF(NOT EXISTS "${QT_QTNETWORK_INCLUDE_DIR}/QAbstractNetworkCache")
+ SET(TRY_BUILD_KDE4 FALSE)
+ ENDIF(NOT EXISTS "${QT_QTNETWORK_INCLUDE_DIR}/QAbstractNetworkCache")
+ ELSE(QT4_FOUND)
+ SET(TRY_BUILD_KDE4 FALSE)
+ ENDIF(QT4_FOUND)
+
+ FIND_PACKAGE(Perl)
+ IF(NOT PERL_FOUND)
+ SET(TRY_BUILD_KDE4 FALSE)
+ ENDIF(NOT PERL_FOUND)
+
+ FIND_PACKAGE(ZLIB)
+ IF(NOT ZLIB_FOUND)
+ SET(TRY_BUILD_KDE4 FALSE)
+ ENDIF(NOT ZLIB_FOUND)
+
+ IF(TRY_BUILD_KDE4)
+ FILE(MAKE_DIRECTORY ${CMake_BINARY_DIR}/Tests/KDE4StableBranchTest)
+ SET(TEST_KDE4_BASE_DIR ${CMake_BINARY_DIR}/Tests/KDE4StableBranchTest)
+ CONFIGURE_FILE(${CMake_SOURCE_DIR}/Tests/KDE4StableBranchTest/test_kde4.sh.in ${CMake_BINARY_DIR}/Tests/KDE4StableBranchTest/test_kde4.sh @ONLY)
+ EXECUTE_PROCESS(COMMAND chmod 755 ${CMake_BINARY_DIR}/Tests/KDE4StableBranchTest/test_kde4.sh )
+ ADD_TEST(KDE4StableBranchTest ${CMake_BINARY_DIR}/Tests/KDE4StableBranchTest/test_kde4.sh)
+ ENDIF(TRY_BUILD_KDE4)
+
+ ENDIF(UNIX)
+ ENDIF (CMAKE_RUN_LONG_TESTS AND TEST_KDE4_STABLE_BRANCH)
+
+ IF("${CMAKE_TEST_GENERATOR}" MATCHES Xcode)
+ SET(CMAKE_SKIP_BOOTSTRAP_TEST 1)
+ ENDIF("${CMAKE_TEST_GENERATOR}" MATCHES Xcode)
+ IF(EXISTS "${CMake_BINARY_DIR}/CMakeLists.txt")
+ # If there is CMakeLists.txt in the binary tree, assume in-source build
+ SET(CMAKE_SKIP_BOOTSTRAP_TEST 1)
+ ENDIF(EXISTS "${CMake_BINARY_DIR}/CMakeLists.txt")
+ SET(bootstrap "")
+ IF(CMAKE_RUN_LONG_TESTS AND NOT CMAKE_SKIP_BOOTSTRAP_TEST)
+ IF(UNIX)
+ SET(bootstrap ${CMake_SOURCE_DIR}/bootstrap)
+ ELSEIF(MSYS)
+ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/bootstrap.bat.in
+ ${CMAKE_CURRENT_BINARY_DIR}/bootstrap.bat @ONLY)
+ SET(bootstrap ${CMAKE_CURRENT_BINARY_DIR}/bootstrap.bat)
+ 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)
+ 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)
+
+ # provide more time for the bootstrap test
+ GET_TEST_PROPERTY(BootstrapTest TIMEOUT PREVIOUS_TIMEOUT)
+ IF ("${PREVIOUS_TIMEOUT}" MATCHES NOTFOUND)
+ SET_TESTS_PROPERTIES ( BootstrapTest
+ PROPERTIES TIMEOUT 5400)
+ ENDIF ("${PREVIOUS_TIMEOUT}" MATCHES NOTFOUND)
+ ENDIF()
+
+ IF(CMAKE_Fortran_COMPILER)
+ ADD_TEST(Fortran ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/Fortran"
+ "${CMake_BINARY_DIR}/Tests/Fortran"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-project testf
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-two-config
+ --test-command testf)
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Fortran")
+
+ # FortranCInterface tests.
+ IF(UNIX)
+ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/FortranC/Flags.cmake.in
+ ${CMAKE_CURRENT_BINARY_DIR}/FortranC/Flags.cmake @ONLY)
+ ADD_TEST(FortranC.Flags ${CMAKE_CMAKE_COMMAND} -P
+ ${CMAKE_CURRENT_BINARY_DIR}/FortranC/Flags.cmake)
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/FortranC/Flags")
+ ELSE()
+ ADD_TEST(FortranC ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FortranC"
+ "${CMake_BINARY_DIR}/Tests/FortranC"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-project FortranC
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-two-config
+ --test-command CMakeFiles/FortranCInterface/FortranCInterface)
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/FortranC")
+ ENDIF()
+ ENDIF()
+
+ 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")
+ GET_FILENAME_COMPONENT(JNIPATH ${JAVA_COMPILE} PATH)
+ FIND_FILE(JNI_H jni.h
+ "${JNIPATH}/../include"
+ "${JNIPATH}/../java/include")
+ 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}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/Java"
+ "${CMake_BINARY_DIR}/Tests/Java"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-project hello
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-two-config
+ --build-run-dir "${CMake_BINARY_DIR}/Tests/Java/"
+ --test-command ${JAVA_RUNTIME} -classpath hello.jar HelloWorld)
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Java")
+ ENDIF("${JNI_FILE}" MATCHES "JDK1_2")
+ 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 sdcc is found, build the SimpleCOnly project with sdcc
+ FIND_PROGRAM(SDCC_EXECUTABLE sdcc)
+ MARK_AS_ADVANCED(SDCC_EXECUTABLE)
+ IF(SDCC_EXECUTABLE)
+ ADD_TEST(SimpleCOnly_sdcc ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/SimpleCOnly"
+ "${CMake_BINARY_DIR}/Tests/SimpleCOnly_sdcc"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-project SimpleC
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-options
+ "-DCMAKE_SYSTEM_NAME=Generic"
+ "-DCMAKE_C_COMPILER=${SDCC_EXECUTABLE}")
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/SimpleCOnly_sdcc")
+ ENDIF(SDCC_EXECUTABLE)
+
+ # If a Linux -> MinGW cross compiler is found then try it
+ FIND_PROGRAM(MINGW_CC_LINUX2WIN_EXECUTABLE i586-mingw32msvc-gcc)
+ FIND_PROGRAM(MINGW_CXX_LINUX2WIN_EXECUTABLE i586-mingw32msvc-g++)
+ FIND_PROGRAM(MINGW_RC_LINUX2WIN_EXECUTABLE i586-mingw32msvc-windres)
+ MARK_AS_ADVANCED(MINGW_CC_LINUX2WIN_EXECUTABLE MINGW_CXX_LINUX2WIN_EXECUTABLE MINGW_RC_LINUX2WIN_EXECUTABLE)
+ IF(MINGW_CC_LINUX2WIN_EXECUTABLE AND MINGW_CXX_LINUX2WIN_EXECUTABLE AND MINGW_RC_LINUX2WIN_EXECUTABLE)
+ ADD_TEST(Simple_Mingw_Linux2Win ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/Simple"
+ "${CMake_BINARY_DIR}/Tests/Simple_Mingw_Linux2Win"
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-project Simple
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --build-options
+ "-DCMAKE_SYSTEM_NAME=Windows"
+ "-DCMAKE_C_COMPILER=${MINGW_CC_LINUX2WIN_EXECUTABLE}"
+ "-DCMAKE_CXX_COMPILER=${MINGW_CXX_LINUX2WIN_EXECUTABLE}"
+ "-DCMAKE_RC_COMPILER=${MINGW_RC_LINUX2WIN_EXECUTABLE}"
+ )
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Simple_Mingw_Linux2Win")
+ ENDIF()
+ ENDIF(CMAKE_TEST_GENERATOR MATCHES "Makefiles" OR CMAKE_TEST_GENERATOR MATCHES "KDevelop")
+
+ 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(PREFIX_IS_FOR_TEST)
+ ENDIF(UNIX)
+
+ IF(CMAKE_TEST_PROJECT_CSE_DIR)
+ SET(script "${CMAKE_TEST_PROJECT_CSE_DIR}/BuildProjectCSE.cmake")
+ IF(NOT EXISTS "${script}")
+ SET(script "${CMAKE_TEST_PROJECT_CSE_DIR}/cse_build.cmake")
+ ENDIF(NOT EXISTS "${script}")
+ IF(NOT EXISTS "${script}")
+ MESSAGE("warning: CMAKE_TEST_PROJECT_CSE_DIR set, but no build script found...")
+ ENDIF(NOT EXISTS "${script}")
+
+ ADD_TEST(BuildCSE ${CMAKE_CTEST_COMMAND} -V -S "${script}")
+ SET_TESTS_PROPERTIES(BuildCSE PROPERTIES TIMEOUT 5400)
+ ENDIF(CMAKE_TEST_PROJECT_CSE_DIR)
+
+ IF(CMAKE_TEST_PLPLOT_DIR)
+ ADD_TEST(plplot ${CMAKE_CTEST_COMMAND} -V -S ${CMAKE_TEST_PLPLOT_DIR}/../../EasyDashboardScripts/plplot.cmake )
+ SET_TESTS_PROPERTIES ( plplot PROPERTIES TIMEOUT 5400)
+ ENDIF(CMAKE_TEST_PLPLOT_DIR)
+
+ IF(CMAKE_TEST_CHICKEN_DIR)
+ ADD_TEST(Chicken ${CMAKE_CTEST_COMMAND} -V -S ${CMAKE_TEST_CHICKEN_DIR}/../../EasyDashboardScripts/Chicken.cmake )
+ SET_TESTS_PROPERTIES ( Chicken PROPERTIES TIMEOUT 5400)
+ ENDIF(CMAKE_TEST_CHICKEN_DIR)
+
+ IF(CMAKE_TEST_KDELIBS_ALPHA_1_DIR)
+ ADD_TEST(KDELibsAlpha1 ${CMAKE_CTEST_COMMAND} -V -S ${CMAKE_TEST_KDELIBS_ALPHA_1_DIR}/../../EasyDashboardScripts/kdelibs.cmake )
+ SET_TESTS_PROPERTIES ( KDELibsAlpha1 PROPERTIES TIMEOUT 5400)
+ ENDIF(CMAKE_TEST_KDELIBS_ALPHA_1_DIR)
+
+ # If this is not an in-source build, provide a target to wipe out
+ # all the test build directories.
+ IF(NOT EXISTS "${CMake_BINARY_DIR}/CMakeLists.txt")
+ CONFIGURE_FILE(${CMake_SOURCE_DIR}/Tests/test_clean.cmake.in
+ ${CMake_BINARY_DIR}/Tests/test_clean.cmake @ONLY)
+ ADD_CUSTOM_TARGET(test_clean
+ COMMAND ${CMAKE_COMMAND} -P ${CMake_BINARY_DIR}/Tests/test_clean.cmake
+ COMMENT "Removing test build directories."
+ )
+ ENDIF(NOT EXISTS "${CMake_BINARY_DIR}/CMakeLists.txt")
+
+ 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)
+ # 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
+ # the vtk542 contract test.
+ # For each Contract test, the project should provide a directory
+ # with at least one CMakeLists.txt file that uses ExternalProject
+ # to download and configure the project. The directory should also
+ # contain a RunTest.cmake file that has a single set of the format:
+ # SET(project_RUN_TEST testToRun)
+ # The testToRun should be a test executable that can be run to
+ # smoke test the build.
+ FOREACH(project ${CMAKE_CONTRACT_PROJECTS})
+ INCLUDE(Contracts/${project}/RunTest.cmake)
+ ADD_TEST_MACRO(Contracts.${project}
+ ${${project}_RUN_TEST})
+ # Contract test timeout in seconds.
+ # Default to 6 hours.
+ IF(DEFINED ${project}_TEST_TIMEOUT)
+ SET(timeout ${${project}_TEST_TIMEOUT})
+ ELSEIF(CMAKE_CONTRACT_TEST_TIMEOUT_DEFAULT)
+ SET(timeout ${CMAKE_CONTRACT_TEST_TIMEOUT_DEFAULT})
+ ELSE()
+ SET(timeout 21600)
+ ENDIF()
+ SET_TESTS_PROPERTIES(Contracts.${project} PROPERTIES TIMEOUT ${timeout})
+ ENDFOREACH()
+
+ IF(TEST_CompileCommandOutput)
+ SET(CompileCommandOutput_EXTRA_OPTIONS
+ --build-options -DMAKE_SUPPORTS_SPACES=${MAKE_IS_GNU})
+ ADD_TEST_MACRO(CompileCommandOutput
+ "${CMake_BINARY_DIR}/Tests/CMakeLib/runcompilecommands")
+ ENDIF()
+
+ ADD_TEST(IncludeDirectories ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/IncludeDirectories"
+ "${CMake_BINARY_DIR}/Tests/IncludeDirectories"
+ --build-two-config
+ --build-generator ${CMAKE_TEST_GENERATOR}
+ --build-project IncludeDirectories
+ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+ --test-command IncludeDirectories)
+ LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/IncludeDirectories")
+
+ IF(CMAKE_USE_KWSTYLE AND KWSTYLE_EXECUTABLE)
+ # The "make StyleCheck" command line as a test. If the test fails, look
+ # for lines like "Error #0 (624) Line length exceed 88 (max=79)" in the
+ # output to find where the style errors are...
+ ADD_TEST(KWStyle ${KWSTYLE_EXECUTABLE}
+ -xml ${CMake_BINARY_DIR}/CMake.kws.xml
+ -o ${CMake_SOURCE_DIR}/Utilities/KWStyle/CMakeOverwrite.txt
+ -v
+ -D ${CMake_BINARY_DIR}/CMakeKWSFiles.txt
+ )
+ SET_TESTS_PROPERTIES(KWStyle PROPERTIES
+ WORKING_DIRECTORY ${CMake_BINARY_DIR}/Utilities/KWStyle)
+ ENDIF()
+ENDIF(BUILD_TESTING)
+
+SUBDIRS(CMakeTests)
diff --git a/Tests/CMakeOnly/AllFindModules/CMakeLists.txt b/Tests/CMakeOnly/AllFindModules/CMakeLists.txt
new file mode 100644
index 000000000..551cee3bc
--- /dev/null
+++ b/Tests/CMakeOnly/AllFindModules/CMakeLists.txt
@@ -0,0 +1,84 @@
+cmake_minimum_required (VERSION 2.8)
+project(AllFindModules)
+
+if (POLICY CMP0017)
+ cmake_policy(SET CMP0017 NEW)
+endif ()
+
+# Avoid ctest truncation of output
+message(STATUS "CTEST_FULL_OUTPUT")
+
+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})
+endmacro(do_find)
+
+# It is only possible to use either Qt3 or Qt4 in one project.
+# Since FindQt will complain if both are found we explicitly request Qt4 here
+# and filter out FindQt3. FindKDE3 also depends on Qt3 and
+# is therefore also blocked
+set(DESIRED_QT_VERSION 4)
+set(NO_QT4_MODULES "Qt3" "KDE3")
+
+# These modules are named Find*.cmake, but are nothing that works in
+# find_package().
+set(NO_FIND_MODULES "PackageHandleStandardArgs" "PackageMessage")
+
+foreach(FIND_MODULE ${FIND_MODULES})
+ string(REGEX REPLACE ".*/Find(.*)\\.cmake$" "\\1" MODULE_NAME "${FIND_MODULE}")
+
+ list(FIND NO_QT4_MODULES ${MODULE_NAME} NO_QT4_INDEX)
+ list(FIND NO_FIND_MODULES ${MODULE_NAME} NO_FIND_INDEX)
+ if (NO_QT4_INDEX EQUAL -1 AND NO_FIND_INDEX EQUAL -1)
+ do_find(${MODULE_NAME})
+ endif ()
+
+endforeach(FIND_MODULE)
+
+# Qt4 is not present, so we can check Qt3
+if (NOT QT4_FOUND)
+ set(DESIRED_QT_VERSION 3)
+ foreach(FIND_MODULE ${NO_QT4_MODULES} "Qt")
+ do_find(${FIND_MODULE})
+ endforeach(FIND_MODULE)
+endif (NOT QT4_FOUND)
+
+macro(check_version_string MODULE_NAME VERSION_VAR)
+ if (${MODULE_NAME}_FOUND)
+ if (DEFINED ${VERSION_VAR})
+ message(STATUS "${VERSION_VAR}='${${VERSION_VAR}}'")
+ if (NOT ${VERSION_VAR} MATCHES "^[0-9]")
+ message(SEND_ERROR "unexpected: ${VERSION_VAR} does not begin with a decimal digit")
+ endif()
+ if ("${${VERSION_VAR}}" STREQUAL "")
+ message(SEND_ERROR "unexpected: ${VERSION_VAR} is empty")
+ endif()
+ if (${VERSION_VAR} VERSION_EQUAL 0)
+ message(SEND_ERROR "unexpected: ${VERSION_VAR} is VERSION_EQUAL 0")
+ endif()
+ if (NOT ${VERSION_VAR} VERSION_GREATER 0)
+ message(SEND_ERROR "unexpected: ${VERSION_VAR} is NOT VERSION_GREATER 0")
+ endif()
+ else()
+ message(SEND_ERROR "${MODULE_NAME}_FOUND is set but version number variable ${VERSION_VAR} is NOT DEFINED")
+ endif()
+ endif ()
+endmacro(check_version_string)
+
+# If any of these modules reported that it was found a version number should have been
+# reported.
+
+foreach(VTEST ALSA ARMADILLO BZIP2 CUPS CURL EXPAT FREETYPE GETTEXT GIT HSPELL
+ JASPER LIBLZMA LIBXML2 LIBXSLT PERL PKG_CONFIG PostgreSQL TIFF ZLIB)
+ check_version_string(${VTEST} ${VTEST}_VERSION_STRING)
+endforeach(VTEST)
+
+foreach(VTEST BISON Boost CUDA DOXYGEN FLEX GIF GTK2 LibArchive OPENSCENEGRAPH
+ RUBY SWIG)
+ check_version_string(${VTEST} ${VTEST}_VERSION)
+endforeach(VTEST)
+
+check_version_string(PYTHONINTERP PYTHON_VERSION_STRING)
+check_version_string(SUBVERSION Subversion_VERSION_SVN)
diff --git a/Tests/CMakeOnly/CMakeLists.txt b/Tests/CMakeOnly/CMakeLists.txt
new file mode 100644
index 000000000..a1551ca03
--- /dev/null
+++ b/Tests/CMakeOnly/CMakeLists.txt
@@ -0,0 +1,30 @@
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Test.cmake.in
+ ${CMAKE_CURRENT_BINARY_DIR}/Test.cmake @ONLY)
+
+macro(add_CMakeOnly_test test)
+ add_test(CMakeOnly.${test} ${CMAKE_CMAKE_COMMAND}
+ -DTEST=${test}
+ -P ${CMAKE_CURRENT_BINARY_DIR}/Test.cmake
+ )
+endmacro()
+
+add_CMakeOnly_test(LinkInterfaceLoop)
+set_property(TEST CMakeOnly.LinkInterfaceLoop PROPERTY TIMEOUT 90)
+
+add_CMakeOnly_test(CheckSymbolExists)
+
+add_CMakeOnly_test(CheckCXXSymbolExists)
+
+add_CMakeOnly_test(CheckCXXCompilerFlag)
+
+add_CMakeOnly_test(CheckLanguage)
+
+add_CMakeOnly_test(AllFindModules)
+
+add_CMakeOnly_test(TargetScope)
+
+add_test(CMakeOnly.ProjectInclude ${CMAKE_CMAKE_COMMAND}
+ -DTEST=ProjectInclude
+ -DCMAKE_ARGS=-DCMAKE_PROJECT_ProjectInclude_INCLUDE=${CMAKE_CURRENT_SOURCE_DIR}/ProjectInclude/include.cmake
+ -P ${CMAKE_CURRENT_BINARY_DIR}/Test.cmake
+ )
diff --git a/Tests/CMakeOnly/CheckCXXCompilerFlag/CMakeLists.txt b/Tests/CMakeOnly/CheckCXXCompilerFlag/CMakeLists.txt
new file mode 100644
index 000000000..e205330b0
--- /dev/null
+++ b/Tests/CMakeOnly/CheckCXXCompilerFlag/CMakeLists.txt
@@ -0,0 +1,58 @@
+cmake_minimum_required(VERSION 2.8)
+project(CheckCXXCompilerFlag)
+
+message(STATUS "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)")
+set(CMAKE_VERBOSE_MAKEFILE 1)
+
+macro(TEST_FAIL value msg)
+ if (${value})
+ message (SEND_ERROR "Test fail:" ${msg} ${Out} )
+ endif ()
+endmacro()
+
+macro(TEST_PASS value msg)
+ if (NOT ${value})
+ message (SEND_ERROR "Test fail:" ${msg} ${Out} )
+ endif ()
+endmacro()
+
+if(CMAKE_COMPILER_IS_GNUCXX)
+ exec_program(${CMAKE_C_COMPILER} ARGS --version OUTPUT_VARIABLE _gcc_version_info)
+ string (REGEX MATCH "[345]\\.[0-9]\\.[0-9]" _gcc_version "${_gcc_version_info}")
+ # gcc on mac just reports: "gcc (GCC) 3.3 20030304 ..." without the
+ # patch level, handle this here:
+ if(NOT _gcc_version)
+ string (REGEX REPLACE ".*\\(GCC\\).* ([34]\\.[0-9]) .*" "\\1.0" _gcc_version "${_gcc_version_info}")
+ endif()
+endif()
+
+if(CMAKE_CXX_COMPILER_ID MATCHES Clang)
+ exec_program(${CMAKE_CXX_COMPILER} ARGS --version OUTPUT_VARIABLE _clang_version_info)
+ string (REGEX REPLACE ".*version ([0-9]\\.[0-9]).*" "\\1" _clang_version "${_clang_version_info}")
+endif()
+
+if(CMAKE_CXX_COMPILER_ID MATCHES Intel)
+ exec_program(${CMAKE_CXX_COMPILER} ARGS -V OUTPUT_VARIABLE _intel_version_info)
+ string (REGEX REPLACE ".*Version ([0-9]+(\\.[0-9]+)+).*" "\\1" _intel_version "${_intel_version_info}")
+endif()
+
+message("Platform:\n WIN32: ${WIN32}\n UNIX: ${UNIX}\n APPLE: ${APPLE}\n MINGW: ${MINGW}\n CYGWIN: ${CYGWIN}\n"
+ " MSVC: ${MSVC}\n MSVC60: ${MSVC60}\n MSVC70: ${MSVC70}\n MSVC71: ${MSVC71}\n MSVC80: ${MSVC80}\n MSVC90: ${MSVC90}\n MSVC10: ${MSVC10}\n"
+ " GCC: ${_gcc_version}\n"
+ " Clang: ${_clang_version}\n"
+ " Intel: ${_intel_version}\n"
+)
+
+include(CheckCXXCompilerFlag)
+
+check_cxx_compiler_flag(-fvisibility=hidden HAS_HIDDEN_VISIBILITY)
+
+message("HAS_HIDDEN_VISIBILITY: ${HAS_HIDDEN_VISIBILITY}\n\nCOMPILE OUTPUT:\n${OUTPUT}")
+
+if(CMAKE_COMPILER_IS_GNUCXX)
+ if(NOT WIN32)
+# test_pass(HAS_HIDDEN_VISIBILITY "GCC should support hidden visibility, but does not.")
+ endif()
+else()
+ message("Unhandled Platform")
+endif()
diff --git a/Tests/CMakeOnly/CheckCXXSymbolExists/CMakeLists.txt b/Tests/CMakeOnly/CheckCXXSymbolExists/CMakeLists.txt
new file mode 100644
index 000000000..1c978c181
--- /dev/null
+++ b/Tests/CMakeOnly/CheckCXXSymbolExists/CMakeLists.txt
@@ -0,0 +1,62 @@
+# This test will verify if CheckCXXSymbolExists only report symbols available
+# for linking that really are. You can find some documentation on this in
+# bug 11333 where we found out that gcc would optimize out the actual
+# reference to the symbol, so symbols that are in fact _not_ available in the
+# given libraries (but seen in header) were reported as present.
+#
+# If you change this test do not forget to change the CheckSymbolExists
+# test, too.
+
+PROJECT(CheckCXXSymbolExists CXX)
+
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
+
+SET(CMAKE_REQUIRED_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/../CheckSymbolExists")
+
+INCLUDE(CheckCXXSymbolExists)
+
+foreach(_config_type Release RelWithDebInfo MinSizeRel Debug)
+ set(CMAKE_TRY_COMPILE_CONFIGURATION ${_config_type})
+ unset(CSE_RESULT_${_config_type} CACHE)
+ MESSAGE(STATUS "Testing configuration ${_config_type}")
+ check_cxx_symbol_exists(non_existent_function_for_symbol_test "cm_cse.h" CSE_RESULT_${_config_type})
+
+ IF (CSE_RESULT_${_config_type})
+ MESSAGE(SEND_ERROR "CheckCXXSymbolExists reported a nonexistent symbol as existing in configuration ${_config_type}")
+ ENDIF (CSE_RESULT_${_config_type})
+endforeach()
+
+set(CMAKE_TRY_COMPILE_CONFIGURATION ${CMAKE_BUILD_TYPE})
+unset(CSE_RESULT_ERRNO_CERRNO CACHE)
+
+MESSAGE(STATUS "Checking <cerrno>")
+
+check_cxx_symbol_exists(errno "cerrno" CSE_RESULT_ERRNO_CERRNO)
+
+IF (NOT CSE_RESULT_ERRNO_CERRNO)
+ unset(CSE_RESULT_ERRNO_ERRNOH CACHE)
+
+ MESSAGE(STATUS "Checking <errno.h>")
+
+ check_cxx_symbol_exists(errno "errno.h" CSE_RESULT_ERRNO_ERRNOH)
+
+ IF (NOT CSE_RESULT_ERRNO_ERRNOH)
+ MESSAGE(SEND_ERROR "CheckCXXSymbolExists did not find errno in <cerrno> and <errno.h>")
+ ELSE (NOT CSE_RESULT_ERRNO_ERRNOH)
+ MESSAGE(STATUS "errno found in <errno.h>")
+ ENDIF (NOT CSE_RESULT_ERRNO_ERRNOH)
+ELSE (NOT CSE_RESULT_ERRNO_CERRNO)
+ MESSAGE(STATUS "errno found in <cerrno>")
+ENDIF (NOT CSE_RESULT_ERRNO_CERRNO)
+
+IF (CMAKE_COMPILER_IS_GNUCXX)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
+ unset(CSE_RESULT_O3 CACHE)
+ MESSAGE(STATUS "Testing with optimization -O3")
+
+ check_cxx_symbol_exists(non_existent_function_for_symbol_test "cm_cse.h" CSE_RESULT_O3)
+
+ IF (CSE_RESULT_O3)
+ MESSAGE(SEND_ERROR "CheckCXXSymbolExists reported a nonexistent symbol as existing with optimization -O3")
+ ENDIF (CSE_RESULT_O3)
+ENDIF (CMAKE_COMPILER_IS_GNUCXX)
diff --git a/Tests/CMakeOnly/CheckLanguage/CMakeLists.txt b/Tests/CMakeOnly/CheckLanguage/CMakeLists.txt
new file mode 100644
index 000000000..f5336dc03
--- /dev/null
+++ b/Tests/CMakeOnly/CheckLanguage/CMakeLists.txt
@@ -0,0 +1,22 @@
+cmake_minimum_required (VERSION 2.8)
+project(CheckLanguage NONE)
+include(CheckLanguage)
+
+set(langs )
+set(expect_C 1)
+set(expect_CXX 1)
+unset(expect_Fortran)
+set(expect_NoSuchLanguage 0)
+foreach(lang C CXX Fortran NoSuchLanguage)
+ check_language(${lang})
+ if(NOT DEFINED CMAKE_${lang}_COMPILER)
+ message(FATAL_ERROR "check_language(${lang}) did not set result")
+ endif()
+ if(DEFINED expect_${lang})
+ if(expect_${lang} AND NOT CMAKE_${lang}_COMPILER)
+ message(FATAL_ERROR "check_language(${lang}) should not fail!")
+ elseif(NOT expect_${lang} AND CMAKE_${lang}_COMPILER)
+ message(FATAL_ERROR "check_language(${lang}) should not succeed!")
+ endif()
+ endif()
+endforeach()
diff --git a/Tests/CMakeOnly/CheckSymbolExists/CMakeLists.txt b/Tests/CMakeOnly/CheckSymbolExists/CMakeLists.txt
new file mode 100644
index 000000000..7c969d3be
--- /dev/null
+++ b/Tests/CMakeOnly/CheckSymbolExists/CMakeLists.txt
@@ -0,0 +1,51 @@
+# This test will verify if CheckSymbolExists only report symbols available
+# for linking that really are. You can find some documentation on this in
+# bug 11333 where we found out that gcc would optimize out the actual
+# reference to the symbol, so symbols that are in fact _not_ available in the
+# given libraries (but seen in header) were reported as present.
+#
+# If you change this test do not forget to change the CheckCXXSymbolExists
+# test, too.
+
+PROJECT(CheckSymbolExists C)
+
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
+
+SET(CMAKE_REQUIRED_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}")
+
+INCLUDE(CheckSymbolExists)
+
+foreach(_config_type Release RelWithDebInfo MinSizeRel Debug)
+ set(CMAKE_TRY_COMPILE_CONFIGURATION ${_config_type})
+ unset(CSE_RESULT_${_config_type} CACHE)
+ MESSAGE(STATUS "Testing configuration ${_config_type}")
+
+ check_symbol_exists(non_existent_function_for_symbol_test "cm_cse.h" CSE_RESULT_${_config_type})
+
+ IF (CSE_RESULT_${_config_type})
+ MESSAGE(SEND_ERROR "CheckSymbolExists reported a nonexistent symbol as existing in configuration ${_config_type}")
+ ENDIF (CSE_RESULT_${_config_type})
+endforeach()
+
+set(CMAKE_TRY_COMPILE_CONFIGURATION ${CMAKE_BUILD_TYPE})
+unset(CSE_RESULT_ERRNO CACHE)
+
+check_symbol_exists(errno "errno.h" CSE_RESULT_ERRNO)
+
+IF (NOT CSE_RESULT_ERRNO)
+ MESSAGE(SEND_ERROR "CheckSymbolExists did not find errno in <errno.h>")
+ELSE (NOT CSE_RESULT_ERRNO)
+ MESSAGE(STATUS "errno found as expected")
+ENDIF (NOT CSE_RESULT_ERRNO)
+
+IF (CMAKE_COMPILER_IS_GNUCC)
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3")
+ unset(CSE_RESULT_O3 CACHE)
+ MESSAGE(STATUS "Testing with optimization -O3")
+
+ check_symbol_exists(non_existent_function_for_symbol_test "cm_cse.h" CSE_RESULT_O3)
+
+ IF (CSE_RESULT_O3)
+ MESSAGE(SEND_ERROR "CheckSymbolExists reported a nonexistent symbol as existing with optimization -O3")
+ ENDIF (CSE_RESULT_O3)
+ENDIF (CMAKE_COMPILER_IS_GNUCC)
diff --git a/Tests/CMakeOnly/CheckSymbolExists/cm_cse.h b/Tests/CMakeOnly/CheckSymbolExists/cm_cse.h
new file mode 100644
index 000000000..4f41c7696
--- /dev/null
+++ b/Tests/CMakeOnly/CheckSymbolExists/cm_cse.h
@@ -0,0 +1,6 @@
+#ifndef _CSE_DUMMY_H
+#define _CSE_DUMMY_H
+
+int non_existent_function_for_symbol_test();
+
+#endif
diff --git a/Tests/CMakeOnly/LinkInterfaceLoop/CMakeLists.txt b/Tests/CMakeOnly/LinkInterfaceLoop/CMakeLists.txt
new file mode 100644
index 000000000..56e449afd
--- /dev/null
+++ b/Tests/CMakeOnly/LinkInterfaceLoop/CMakeLists.txt
@@ -0,0 +1,27 @@
+cmake_minimum_required (VERSION 2.8)
+project(LinkInterfaceLoop C)
+
+# Add a shared library that incorrectly names itself as a
+# dependency, thus forming a cycle.
+add_library(A SHARED IMPORTED)
+set_target_properties(A PROPERTIES
+ IMPORTED_LINK_DEPENDENT_LIBRARIES A
+ IMPORTED_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/dirA/A"
+ )
+
+# Add a shared library that incorrectly names itself in
+# its link interface, thus forming a cycle.
+add_library(B SHARED IMPORTED)
+set_target_properties(B PROPERTIES
+ IMPORTED_LINK_INTERFACE_LIBRARIES B
+ IMPORTED_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/dirB/B"
+ )
+
+# Add a shared library with an empty link interface
+# that depends on two shared libraries.
+add_library(C SHARED lib.c)
+set_property(TARGET C PROPERTY LINK_INTERFACE_LIBRARIES "")
+target_link_libraries(C B A)
+
+add_executable(main main.c)
+target_link_libraries(main C)
diff --git a/Tests/CMakeOnly/LinkInterfaceLoop/lib.c b/Tests/CMakeOnly/LinkInterfaceLoop/lib.c
new file mode 100644
index 000000000..fede1d61f
--- /dev/null
+++ b/Tests/CMakeOnly/LinkInterfaceLoop/lib.c
@@ -0,0 +1 @@
+int lib(void) { return 0; }
diff --git a/Tests/CMakeOnly/LinkInterfaceLoop/main.c b/Tests/CMakeOnly/LinkInterfaceLoop/main.c
new file mode 100644
index 000000000..78f2de106
--- /dev/null
+++ b/Tests/CMakeOnly/LinkInterfaceLoop/main.c
@@ -0,0 +1 @@
+int main(void) { return 0; }
diff --git a/Tests/CMakeOnly/ProjectInclude/CMakeLists.txt b/Tests/CMakeOnly/ProjectInclude/CMakeLists.txt
new file mode 100644
index 000000000..a9abb4ad7
--- /dev/null
+++ b/Tests/CMakeOnly/ProjectInclude/CMakeLists.txt
@@ -0,0 +1,4 @@
+project(ProjectInclude)
+if(NOT AUTO_INCLUDE)
+ message(FATAL_ERROR "include file not found")
+endif()
diff --git a/Tests/CMakeOnly/ProjectInclude/include.cmake b/Tests/CMakeOnly/ProjectInclude/include.cmake
new file mode 100644
index 000000000..527ebe7d0
--- /dev/null
+++ b/Tests/CMakeOnly/ProjectInclude/include.cmake
@@ -0,0 +1 @@
+set(AUTO_INCLUDE TRUE)
diff --git a/Tests/CMakeOnly/TargetScope/CMakeLists.txt b/Tests/CMakeOnly/TargetScope/CMakeLists.txt
new file mode 100644
index 000000000..fa5d8e234
--- /dev/null
+++ b/Tests/CMakeOnly/TargetScope/CMakeLists.txt
@@ -0,0 +1,13 @@
+cmake_minimum_required (VERSION 2.8)
+project(TargetScope NONE)
+
+add_subdirectory(Sub)
+
+if(TARGET SubLibLocal)
+ message(FATAL_ERROR "SubLibLocal visible in top directory")
+endif()
+if(NOT TARGET SubLibGlobal)
+ message(FATAL_ERROR "SubLibGlobal not visible in top directory")
+endif()
+
+add_subdirectory(Sib)
diff --git a/Tests/CMakeOnly/TargetScope/Sib/CMakeLists.txt b/Tests/CMakeOnly/TargetScope/Sib/CMakeLists.txt
new file mode 100644
index 000000000..7f6f4e8fd
--- /dev/null
+++ b/Tests/CMakeOnly/TargetScope/Sib/CMakeLists.txt
@@ -0,0 +1,6 @@
+if(TARGET SubLibLocal)
+ message(FATAL_ERROR "SubLibLocal visible in sibling directory")
+endif()
+if(NOT TARGET SubLibGlobal)
+ message(FATAL_ERROR "SubLibGlobal not visible in sibling directory")
+endif()
diff --git a/Tests/CMakeOnly/TargetScope/Sub/CMakeLists.txt b/Tests/CMakeOnly/TargetScope/Sub/CMakeLists.txt
new file mode 100644
index 000000000..27318f585
--- /dev/null
+++ b/Tests/CMakeOnly/TargetScope/Sub/CMakeLists.txt
@@ -0,0 +1,9 @@
+add_library(SubLibLocal UNKNOWN IMPORTED)
+add_library(SubLibGlobal UNKNOWN IMPORTED GLOBAL)
+add_subdirectory(Sub)
+if(NOT TARGET SubLibLocal)
+ message(FATAL_ERROR "SubLibLocal not visible in own directory")
+endif()
+if(NOT TARGET SubLibGlobal)
+ message(FATAL_ERROR "SubLibGlobal not visible in own directory")
+endif()
diff --git a/Tests/CMakeOnly/TargetScope/Sub/Sub/CMakeLists.txt b/Tests/CMakeOnly/TargetScope/Sub/Sub/CMakeLists.txt
new file mode 100644
index 000000000..a351daadf
--- /dev/null
+++ b/Tests/CMakeOnly/TargetScope/Sub/Sub/CMakeLists.txt
@@ -0,0 +1,6 @@
+if(NOT TARGET SubLibLocal)
+ message(FATAL_ERROR "SubLibLocal not visible in subdirectory")
+endif()
+if(NOT TARGET SubLibGlobal)
+ message(FATAL_ERROR "SubLibGlobal not visible in subdirectory")
+endif()
diff --git a/Tests/CMakeOnly/Test.cmake.in b/Tests/CMakeOnly/Test.cmake.in
new file mode 100644
index 000000000..42af06891
--- /dev/null
+++ b/Tests/CMakeOnly/Test.cmake.in
@@ -0,0 +1,13 @@
+set(source_dir "@CMAKE_CURRENT_SOURCE_DIR@/${TEST}")
+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@"
+ WORKING_DIRECTORY "${binary_dir}"
+ RESULT_VARIABLE result
+ )
+if(result)
+ message(FATAL_ERROR "CMake failed to configure ${TEST}")
+endif()
diff --git a/Tests/CMakeTestAllGenerators/RunCMake.cmake b/Tests/CMakeTestAllGenerators/RunCMake.cmake
new file mode 100644
index 000000000..6d27d3be1
--- /dev/null
+++ b/Tests/CMakeTestAllGenerators/RunCMake.cmake
@@ -0,0 +1,117 @@
+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()
+
+# Analyze 'cmake --help' output for list of available generators:
+#
+execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${dir})
+execute_process(COMMAND ${CMAKE_COMMAND} --help
+ RESULT_VARIABLE result
+ OUTPUT_VARIABLE stdout
+ ERROR_VARIABLE stderr
+ WORKING_DIRECTORY ${dir})
+
+string(REPLACE ";" "\\;" stdout "${stdout}")
+string(REPLACE "\n" "E;" stdout "${stdout}")
+
+set(collecting 0)
+set(generators)
+foreach(eline ${stdout})
+ string(REGEX REPLACE "^(.*)E$" "\\1" line "${eline}")
+ if(collecting AND NOT line STREQUAL "")
+ if(line MATCHES "=")
+ string(REGEX REPLACE "^ (.+)= (.*)$" "\\1" gen "${line}")
+ if(gen MATCHES "[A-Za-z]")
+ string(REGEX REPLACE "^(.*[^ ]) +$" "\\1" gen "${gen}")
+ if(gen)
+ set(generators ${generators} ${gen})
+ endif()
+ endif()
+ else()
+ if(line MATCHES "^ [A-Za-z0-9]")
+ string(REGEX REPLACE "^ (.+)$" "\\1" gen "${line}")
+ string(REGEX REPLACE "^(.*[^ ]) +$" "\\1" gen "${gen}")
+ if(gen)
+ set(generators ${generators} ${gen})
+ endif()
+ endif()
+ endif()
+ endif()
+ if(line STREQUAL "The following generators are available on this platform:")
+ set(collecting 1)
+ endif()
+endforeach()
+
+# Also call with one non-existent generator:
+#
+set(generators ${generators} "BOGUS_CMAKE_GENERATOR")
+
+# Call cmake with -G on each available generator. We do not care if this
+# succeeds or not. We expect it *not* to succeed if the underlying packaging
+# tools are not installed on the system... This test is here simply to add
+# coverage for the various cmake generators, even/especially to test ones
+# where the tools are not installed.
+#
+message(STATUS "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)")
+
+message(STATUS "CMake generators='${generators}'")
+
+# If we'll be testing any of the MinGW Makefiles generators, adjust the
+# ENV{PATH} to make sure libgmp-10.dll can be loaded as needed. But only if
+# the testing machine has a default MinGW install... (If you have a
+# non-default install, append to the PATH before running the test...)
+#
+if(generators MATCHES "MinGW Makefiles")
+ if(EXISTS "C:/MinGW/bin/libgmp-10.dll")
+ string(TOLOWER "$ENV{PATH}" path)
+ if(NOT path MATCHES "/mingw/bin")
+ if(UNIX)
+ set(sep ":")
+ set(mingw_bin "/mingw/bin")
+ else()
+ set(sep ";")
+ set(mingw_bin "C:/MinGW/bin")
+ endif()
+ set(ENV{PATH} "$ENV{PATH}${sep}${mingw_bin}")
+ message(STATUS "info: appending '${sep}${mingw_bin}' to the PATH")
+ endif()
+ endif()
+endif()
+
+# 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
+)
+
+foreach(g ${generators})
+ message(STATUS "cmake -G \"${g}\" ..")
+
+ # Create a binary directory for each generator:
+ #
+ execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory
+ ${dir}/Source/${g}
+ )
+
+ # Run cmake:
+ #
+ execute_process(COMMAND ${CMAKE_COMMAND} -G ${g} ..
+ RESULT_VARIABLE result
+ OUTPUT_VARIABLE stdout
+ ERROR_VARIABLE stderr
+ WORKING_DIRECTORY ${dir}/Source/${g}
+ )
+
+ message(STATUS "result='${result}'")
+ message(STATUS "stdout='${stdout}'")
+ message(STATUS "stderr='${stderr}'")
+ message(STATUS "")
+endforeach()
+
+message(STATUS "CMake generators='${generators}'")
+message(STATUS "CMAKE_COMMAND='${CMAKE_COMMAND}'")
diff --git a/Tests/CMakeTestBadCommandLines/RunCMake.cmake b/Tests/CMakeTestBadCommandLines/RunCMake.cmake
new file mode 100644
index 000000000..08549cc5e
--- /dev/null
+++ b/Tests/CMakeTestBadCommandLines/RunCMake.cmake
@@ -0,0 +1,79 @@
+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/CMakeTestMultipleConfigures/RunCMake.cmake b/Tests/CMakeTestMultipleConfigures/RunCMake.cmake
new file mode 100644
index 000000000..19391d7f1
--- /dev/null
+++ b/Tests/CMakeTestMultipleConfigures/RunCMake.cmake
@@ -0,0 +1,165 @@
+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()
+
+# Call cmake once to get a baseline/reference output build tree: "Build".
+# Then call cmake N more times, each time making a copy of the entire
+# build tree after cmake is done configuring/generating. At the end,
+# analyze the diffs in the generated build trees. Expect no diffs.
+#
+message(STATUS "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)")
+
+set(N 7)
+
+# First setup source and binary trees:
+#
+execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory
+ ${dir}/Source
+)
+
+execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory
+ ${dir}/Build
+)
+
+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
+)
+
+# Patch SmallAndFast to build a .cxx executable too:
+#
+execute_process(COMMAND ${CMAKE_COMMAND} -E copy
+ ${dir}/Source/echoargs.c
+ ${dir}/Source/echoargs.cxx
+)
+file(APPEND "${dir}/Source/CMakeLists.txt" "\nadd_executable(echoargsCXX echoargs.cxx)\n")
+
+# Loop N times, saving a copy of the configured/generated build tree each time:
+#
+foreach(i RANGE 1 ${N})
+ # Equivalent sequence of shell commands:
+ #
+ message(STATUS "${i}: cd Build && cmake -G \"${gen}\" ../Source && cd .. && cp -r Build b${i}")
+
+ # Run cmake:
+ #
+ execute_process(COMMAND ${CMAKE_COMMAND} -G ${gen} ../Source
+ 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 "")
+
+ # Save this iteration of the Build directory:
+ #
+ execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory
+ ${dir}/b${i}
+ )
+ execute_process(COMMAND ${CMAKE_COMMAND} -E copy_directory
+ ${dir}/Build
+ ${dir}/b${i}
+ RESULT_VARIABLE result
+ OUTPUT_VARIABLE stdout
+ ERROR_VARIABLE stderr
+ )
+
+ message(STATUS "result='${result}'")
+ message(STATUS "stdout='${stdout}'")
+ message(STATUS "stderr='${stderr}'")
+ message(STATUS "")
+endforeach()
+
+
+# Function to analyze diffs between two directories.
+# Set DIFF_EXECUTABLE before calling if 'diff' is available.
+#
+function(analyze_directory_diffs d1 d2 diff_count_var)
+ set(diffs 0)
+
+ message(STATUS "Analyzing directory diffs between:")
+ message(STATUS " d1='${d1}'")
+ message(STATUS " d2='${d2}'")
+
+ if(NOT "${d1}" STREQUAL "" AND NOT "${d2}" STREQUAL "")
+ message(STATUS "info: analyzing directories")
+
+ file(GLOB_RECURSE files1 RELATIVE "${d1}" "${d1}/*")
+ file(GLOB_RECURSE files2 RELATIVE "${d2}" "${d2}/*")
+
+ if("${files1}" STREQUAL "${files2}")
+ message(STATUS "info: file lists the same")
+ #message(STATUS " files='${files1}'")
+
+ foreach(f ${files1})
+ execute_process(COMMAND ${CMAKE_COMMAND} -E compare_files
+ ${d1}/${f}
+ ${d2}/${f}
+ RESULT_VARIABLE result
+ OUTPUT_VARIABLE stdout
+ ERROR_VARIABLE stderr
+ )
+ if(result STREQUAL 0)
+ #message(STATUS "info: file '${f}' the same")
+ else()
+ math(EXPR diffs "${diffs} + 1")
+ message(STATUS "warning: file '${f}' differs from d1 to d2")
+ file(READ "${d1}/${f}" f1contents)
+ message(STATUS "contents of file '${d1}/${f}'
+[===[${f1contents}]===]")
+ file(READ "${d2}/${f}" f2contents)
+ message(STATUS "contents of file '${d2}/${f}'
+[===[${f2contents}]===]")
+ if(DIFF_EXECUTABLE)
+ message(STATUS "diff of files '${d1}/${f}' '${d2}/${f}'")
+ message(STATUS "[====[")
+ execute_process(COMMAND ${DIFF_EXECUTABLE} "${d1}/${f}" "${d2}/${f}")
+ message(STATUS "]====]")
+ endif()
+ endif()
+ endforeach()
+ else()
+ math(EXPR diffs "${diffs} + 1")
+ message(STATUS "warning: file *lists* differ - some files exist in d1/not-d2 or not-d1/d2...")
+ message(STATUS " files1='${files1}'")
+ message(STATUS " files2='${files2}'")
+ endif()
+ endif()
+
+ set(${diff_count_var} ${diffs} PARENT_SCOPE)
+endfunction(analyze_directory_diffs)
+
+
+# Analyze diffs between b1:b2, b2:b3, b3:b4, b4:b5 ... bN-1:bN.
+# Expect no diffs.
+#
+find_program(DIFF_EXECUTABLE diff)
+set(total_diffs 0)
+
+foreach(i RANGE 2 ${N})
+ math(EXPR prev "${i} - 1")
+ set(count 0)
+ analyze_directory_diffs(${dir}/b${prev} ${dir}/b${i} count)
+ message(STATUS "diff count='${count}'")
+ message(STATUS "")
+ math(EXPR total_diffs "${total_diffs} + ${count}")
+endforeach()
+
+message(STATUS "CMAKE_COMMAND='${CMAKE_COMMAND}'")
+message(STATUS "total_diffs='${total_diffs}'")
diff --git a/Tests/CMakeTests/.gitattributes b/Tests/CMakeTests/.gitattributes
new file mode 100644
index 000000000..c34e350e5
--- /dev/null
+++ b/Tests/CMakeTests/.gitattributes
@@ -0,0 +1 @@
+File-HASH-Input.txt crlf=input
diff --git a/Tests/CMakeTests/A/include/cmake_i_do_not_exist_in_the_system.h b/Tests/CMakeTests/A/include/cmake_i_do_not_exist_in_the_system.h
new file mode 100644
index 000000000..2392aee71
--- /dev/null
+++ b/Tests/CMakeTests/A/include/cmake_i_do_not_exist_in_the_system.h
@@ -0,0 +1 @@
+/* empty header file */
diff --git a/Tests/CMakeTests/CMakeLists.txt b/Tests/CMakeTests/CMakeLists.txt
new file mode 100644
index 000000000..c42c490b0
--- /dev/null
+++ b/Tests/CMakeTests/CMakeLists.txt
@@ -0,0 +1,69 @@
+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)
+ ADD_TEST(CMake.${TestName} ${CMAKE_EXECUTABLE} ${PreArgs}
+ -P "${CMAKE_CURRENT_BINARY_DIR}/${TestName}Test.cmake" ${ARGN})
+ENDMACRO(AddCMakeTest)
+
+
+AddCMakeTest(List "")
+AddCMakeTest(VariableWatch "")
+AddCMakeTest(Include "")
+AddCMakeTest(FindBase "")
+AddCMakeTest(Toolchain "")
+AddCMakeTest(GetFilenameComponentRealpath "")
+AddCMakeTest(Version "")
+AddCMakeTest(Message "")
+AddCMakeTest(File "")
+AddCMakeTest(ConfigureFile "")
+AddCMakeTest(SeparateArguments "")
+AddCMakeTest(ImplicitLinkInfo "")
+AddCMakeTest(ModuleNotices "")
+AddCMakeTest(GetProperty "")
+AddCMakeTest(If "")
+AddCMakeTest(String "")
+AddCMakeTest(Math "")
+AddCMakeTest(CMakeMinimumRequired "")
+AddCMakeTest(CompilerIdVendor "")
+AddCMakeTest(ProcessorCount "")
+AddCMakeTest(PushCheckState "")
+AddCMakeTest(While "")
+
+AddCMakeTest(FileDownload "")
+set_property(TEST CMake.FileDownload PROPERTY
+ PASS_REGULAR_EXPRESSION "file already exists with expected MD5 sum"
+ )
+
+AddCMakeTest(FileUpload "")
+
+if(HAVE_ELF_H)
+ AddCMakeTest(ELF "")
+endif()
+
+SET(EndStuff_PreArgs
+ "-Ddir:STRING=${CMAKE_CURRENT_BINARY_DIR}/EndStuffTest"
+ )
+AddCMakeTest(EndStuff "${EndStuff_PreArgs}")
+
+SET(GetPrerequisites_PreArgs
+ "-DCTEST_CONFIGURATION_TYPE:STRING=\\\${CTEST_CONFIGURATION_TYPE}"
+ )
+AddCMakeTest(GetPrerequisites "${GetPrerequisites_PreArgs}")
+
+# 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.
+#
+if(GIT_EXECUTABLE)
+ string(REPLACE "\\" "/" ENV_HOME "$ENV{HOME}")
+ set(CheckSourceTree_PreArgs
+ "-DCMake_BINARY_DIR:PATH=${CMake_BINARY_DIR}"
+ "-DCMake_SOURCE_DIR:PATH=${CMake_SOURCE_DIR}"
+ "-DGIT_EXECUTABLE:STRING=${GIT_EXECUTABLE}"
+ "-DHOME:STRING=${ENV_HOME}"
+ )
+ AddCMakeTest(CheckSourceTree "${CheckSourceTree_PreArgs}")
+endif()
diff --git a/Tests/CMakeTests/CMakeMinimumRequiredTest.cmake.in b/Tests/CMakeTests/CMakeMinimumRequiredTest.cmake.in
new file mode 100644
index 000000000..b83a779bb
--- /dev/null
+++ b/Tests/CMakeTests/CMakeMinimumRequiredTest.cmake.in
@@ -0,0 +1,18 @@
+# Execute each test listed in:
+#
+set(scriptname "@CMAKE_CURRENT_SOURCE_DIR@/CMakeMinimumRequiredTestScript.cmake")
+set(number_of_tests_expected 8)
+
+include("@CMAKE_CURRENT_SOURCE_DIR@/ExecuteScriptTests.cmake")
+execute_all_script_tests(${scriptname} number_of_tests_executed)
+
+# And verify that number_of_tests_executed is at least as many as we know
+# about as of this writing...
+#
+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)
+ message(FATAL_ERROR "error: some test cases were skipped")
+endif()
diff --git a/Tests/CMakeTests/CMakeMinimumRequiredTestScript.cmake b/Tests/CMakeTests/CMakeMinimumRequiredTestScript.cmake
new file mode 100644
index 000000000..d434d2901
--- /dev/null
+++ b/Tests/CMakeTests/CMakeMinimumRequiredTestScript.cmake
@@ -0,0 +1,31 @@
+message(STATUS "testname='${testname}'")
+
+if(testname STREQUAL empty) # pass
+ cmake_minimum_required()
+
+elseif(testname STREQUAL bogus) # fail
+ cmake_minimum_required(BOGUS)
+
+elseif(testname STREQUAL no_version) # fail
+ cmake_minimum_required(VERSION)
+
+elseif(testname STREQUAL no_version_before_fatal_error) # fail
+ cmake_minimum_required(VERSION FATAL_ERROR)
+
+elseif(testname STREQUAL bad_version) # fail
+ cmake_minimum_required(VERSION 2.blah.blah)
+
+elseif(testname STREQUAL worse_version) # fail
+ cmake_minimum_required(VERSION blah.blah.blah)
+
+elseif(testname STREQUAL future_version) # fail
+ math(EXPR major "${CMAKE_MAJOR_VERSION} + 1")
+ cmake_minimum_required(VERSION ${major}.2.1)
+
+elseif(testname STREQUAL unknown_arg) # fail
+ cmake_minimum_required(VERSION ${CMAKE_MAJOR_VERSION}.0.0 SILLY)
+
+else() # fail
+ message(FATAL_ERROR "testname='${testname}' - error: no such test in '${CMAKE_CURRENT_LIST_FILE}'")
+
+endif()
diff --git a/Tests/CMakeTests/CheckCMakeTest.cmake b/Tests/CMakeTests/CheckCMakeTest.cmake
new file mode 100644
index 000000000..db9290522
--- /dev/null
+++ b/Tests/CMakeTests/CheckCMakeTest.cmake
@@ -0,0 +1,30 @@
+get_filename_component(CMakeTests_SRC_DIR ${CMAKE_CURRENT_LIST_FILE} PATH)
+function(check_cmake_test prefix)
+ get_filename_component(CMakeTests_BIN_DIR ${CMAKE_CURRENT_LIST_FILE} PATH)
+ foreach(test ${ARGN})
+ message(STATUS "Test ${prefix}-${test}...")
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -P "${CMakeTests_SRC_DIR}/${prefix}-${test}.cmake"
+ WORKING_DIRECTORY "${CMakeTests_BIN_DIR}"
+ OUTPUT_VARIABLE stdout
+ ERROR_VARIABLE stderr
+ RESULT_VARIABLE result
+ )
+ string(REGEX REPLACE "\n" "\n out> " out " out> ${stdout}")
+ string(REGEX 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"
+ "Test ${test} output:\n"
+ "${out}\n"
+ "${err}")
+ endif()
+ if(${test}-STDERR AND NOT "${err}" MATCHES "${${test}-STDERR}")
+ message(FATAL_ERROR
+ "Test ${test} stderr does not match\n ${${test}-STDERR}\n"
+ "Test ${test} output:\n"
+ "${out}\n"
+ "${err}")
+ endif()
+ endforeach()
+endfunction()
diff --git a/Tests/CMakeTests/CheckSourceTreeTest.cmake.in b/Tests/CMakeTests/CheckSourceTreeTest.cmake.in
new file mode 100644
index 000000000..59b28904d
--- /dev/null
+++ b/Tests/CMakeTests/CheckSourceTreeTest.cmake.in
@@ -0,0 +1,357 @@
+# Check the CMake source tree and report anything suspicious...
+#
+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("HOME='${HOME}'")
+message("ENV{DASHBOARD_TEST_FROM_CTEST}='$ENV{DASHBOARD_TEST_FROM_CTEST}'")
+message("")
+string(REPLACE "\\" "\\\\" HOME "${HOME}")
+
+
+# Is the build directory the same as or underneath the source directory?
+# (i.e. - is it an "in source" build?)
+#
+set(in_source_build 0)
+
+if(CMake_SOURCE_DIR STREQUAL "${CMake_BINARY_DIR}")
+ message("build dir *is* source dir")
+ set(in_source_build 1)
+else()
+ string(LENGTH "${CMake_SOURCE_DIR}" src_len)
+ string(LENGTH "${CMake_BINARY_DIR}" bin_len)
+
+ if(bin_len GREATER src_len)
+ math(EXPR substr_len "${src_len}+1")
+ string(SUBSTRING "${CMake_BINARY_DIR}" 0 ${substr_len} bin_dir)
+ if(bin_dir STREQUAL "${CMake_SOURCE_DIR}/")
+ message("build dir is under source dir")
+ set(in_source_build 1)
+ endif()
+ endif()
+endif()
+
+message("src_len='${src_len}'")
+message("bin_len='${bin_len}'")
+message("substr_len='${substr_len}'")
+message("bin_dir='${bin_dir}'")
+message("in_source_build='${in_source_build}'")
+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()
+
+# This test looks for the following types of changes in the source tree:
+#
+set(additions 0)
+set(conflicts 0)
+set(modifications 0)
+set(nonadditions 0)
+
+# ov == output variable... conditionally filled in by either git below:
+#
+set(cmd "")
+set(ov "")
+set(ev "")
+set(rv "")
+
+# 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 status" if there are any local modifications to the
+ # CMake source tree:
+ #
+ message("=============================================================================")
+ message("This is a git checkout, using git to verify source tree....")
+ message("")
+
+ execute_process(COMMAND ${GIT_EXECUTABLE} --version
+ WORKING_DIRECTORY ${CMake_SOURCE_DIR}
+ OUTPUT_VARIABLE version_output
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ message("=== output of 'git --version' ===")
+ message("${version_output}")
+ message("=== end output ===")
+ message("")
+
+ execute_process(COMMAND ${GIT_EXECUTABLE} branch -a
+ WORKING_DIRECTORY ${CMake_SOURCE_DIR}
+ OUTPUT_VARIABLE git_branch_output
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ message("=== output of 'git branch -a' ===")
+ message("${git_branch_output}")
+ message("=== end output ===")
+ message("")
+
+ execute_process(COMMAND ${GIT_EXECUTABLE} log -1
+ WORKING_DIRECTORY ${CMake_SOURCE_DIR}
+ OUTPUT_VARIABLE git_log_output
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ message("=== output of 'git log -1' ===")
+ message("${git_log_output}")
+ message("=== end output ===")
+ message("")
+
+ message("Copy/paste this command to reproduce:")
+ message("cd \"${CMake_SOURCE_DIR}\" && \"${GIT_EXECUTABLE}\" status")
+ message("")
+
+ set(cmd ${GIT_EXECUTABLE} status)
+endif()
+
+
+if(cmd)
+ # Use the HOME value passed in to the script for calling git so it can
+ # find its user/global config settings...
+ #
+ set(original_ENV_HOME "$ENV{HOME}")
+ set(ENV{HOME} "${HOME}")
+
+ execute_process(COMMAND ${cmd}
+ WORKING_DIRECTORY ${CMake_SOURCE_DIR}
+ OUTPUT_VARIABLE ov
+ ERROR_VARIABLE ev
+ RESULT_VARIABLE rv)
+
+ set(ENV{HOME} "${original_ENV_HOME}")
+
+ message("Results of running ${cmd}")
+ message("rv='${rv}'")
+ message("ov='${ov}'")
+ message("ev='${ev}'")
+ message("")
+
+ if(NOT rv STREQUAL 0)
+ if(is_git_checkout AND (rv STREQUAL "1"))
+ # Many builds of git return "1" from a "nothing is changed" git status call...
+ # Do not fail with an error for rv==1 with git...
+ else()
+ message(FATAL_ERROR "error: ${cmd} attempt failed... (see output above)")
+ endif()
+ endif()
+else()
+ message(FATAL_ERROR "error: no COMMAND to run to analyze source tree...")
+endif()
+
+
+# Analyze output:
+#
+if(NOT ov STREQUAL "")
+ string(REPLACE ";" "\\\\;" lines "${ov}")
+ string(REPLACE "\n" "E;" lines "${lines}")
+
+ foreach(line ${lines})
+ message("'${line}'")
+
+ # But do not consider files that exist just because some user poked around
+ # the file system with Windows Explorer or with the Finder from a Mac...
+ # ('Thumbs.db' and '.DS_Store' files...)
+ #
+ set(consider 1)
+ set(ignore_files_regex "^(. |.*(/|\\\\))(\\.DS_Store|Thumbs.db)E$")
+ if(line MATCHES "${ignore_files_regex}")
+ message(" line matches '${ignore_files_regex}' -- not considered")
+ set(consider 0)
+ endif()
+
+ if(consider)
+ if(is_git_checkout)
+ if(line MATCHES "^#[ \t]*modified:")
+ message(" locally modified file detected...")
+ set(modifications 1)
+ endif()
+
+ if(line MATCHES "^# Untracked")
+ message(" locally non-added file/directory detected...")
+ set(nonadditions 1)
+ endif()
+ endif()
+ endif()
+ endforeach()
+endif()
+
+
+message("=============================================================================")
+message("additions='${additions}'")
+message("conflicts='${conflicts}'")
+message("modifications='${modifications}'")
+message("nonadditions='${nonadditions}'")
+message("")
+
+
+# Decide if the test passes or fails:
+#
+message("=============================================================================")
+
+if("$ENV{DASHBOARD_TEST_FROM_CTEST}" STREQUAL "")
+
+ # developers are allowed to have local additions and modifications...
+ set(is_dashboard 0)
+ message("interactive test run")
+ message("")
+
+else()
+
+ set(is_dashboard 1)
+ message("dashboard test run")
+ message("")
+
+ # but dashboard machines are not allowed to have local additions or modifications...
+ if(additions)
+ message(FATAL_ERROR "test fails: local source tree additions")
+ endif()
+
+ if(modifications)
+ message(FATAL_ERROR "test fails: local source tree modifications")
+ endif()
+
+ #
+ # It's a dashboard run if ctest was run with '-D ExperimentalTest' or some
+ # other -D arg on its command line or if ctest is running a -S script to run
+ # a dashboard... Running ctest like that sets the DASHBOARD_TEST_FROM_CTEST
+ # env var.
+ #
+
+endif()
+
+
+# ...and nobody is allowed to have local non-additions or conflicts...
+# Not even developers.
+#
+if(nonadditions)
+ if(in_source_build AND is_dashboard)
+ message("
+warning: test results confounded because this is an 'in-source' build - cannot
+distinguish between non-added files that are in-source build products and
+non-added source files that somebody forgot to 'git add'... - this is only ok
+if this is intentionally an in-source dashboard build... Developers should
+use out-of-source builds to verify a clean source tree with this test...
+
+Allowing test to pass despite the warning message...
+")
+ else()
+ message(FATAL_ERROR "test fails: local source tree non-additions: use git add before committing, or remove the files from the source tree")
+ endif()
+endif()
+
+if(conflicts)
+ message(FATAL_ERROR "test fails: local source tree conflicts: resolve before committing")
+endif()
+
+
+# Still here? Good then...
+#
+message("test passes")
+message("")
diff --git a/Tests/CMakeTests/CompilerIdVendorTest.cmake.in b/Tests/CMakeTests/CompilerIdVendorTest.cmake.in
new file mode 100644
index 000000000..68f646212
--- /dev/null
+++ b/Tests/CMakeTests/CompilerIdVendorTest.cmake.in
@@ -0,0 +1,31 @@
+# This is not supposed to be included by user code, but we need to
+# test it.
+include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake)
+
+set(MY_BINARY_DIR "@CMAKE_CURRENT_BINARY_DIR@/CompilerIdVendor")
+file(REMOVE_RECURSE ${MY_BINARY_DIR})
+file(MAKE_DIRECTORY ${MY_BINARY_DIR})
+
+set(CMAKE_MyLang_COMPILER ${CMAKE_COMMAND})
+set(CMAKE_MyLang_COMPILER_ID_ARG1)
+set(CMAKE_MyLang_COMPILER_ID_FLAGS_LIST)
+set(CMAKE_MyLang_COMPILER_ID_DIR ${MY_BINARY_DIR})
+
+file(WRITE "${MY_BINARY_DIR}/BogusVendor.cmake" "message(\"This is a BogusVendor compiler\")")
+list(APPEND CMAKE_MyLang_COMPILER_ID_VENDORS BogusVendor)
+set(CMAKE_MyLang_COMPILER_ID_VENDOR_FLAGS_BogusVendor -P BogusVendor.cmake)
+set(CMAKE_MyLang_COMPILER_ID_VENDOR_REGEX_BogusVendor ThisDoesNotMatch_BogusVendor)
+
+file(WRITE "${MY_BINARY_DIR}/MyVendor.cmake" "message(\"This is a MyVendor compiler\")")
+list(APPEND CMAKE_MyLang_COMPILER_ID_VENDORS MyVendor)
+set(CMAKE_MyLang_COMPILER_ID_VENDOR_FLAGS_MyVendor -P MyVendor.cmake)
+set(CMAKE_MyLang_COMPILER_ID_VENDOR_REGEX_MyVendor MyVendor)
+
+set(CMAKE_BINARY_DIR ${MY_BINARY_DIR})
+cmake_determine_compiler_id_vendor(MyLang)
+
+if("${CMAKE_MyLang_COMPILER_ID}" STREQUAL "MyVendor")
+ message(STATUS "Found MyVendor compiler id!")
+else()
+ message(FATAL_ERROR "Did not find MyVendor compiler id: [${CMAKE_MyLang_COMPILER_ID}]")
+endif()
diff --git a/Tests/CMakeTests/ConfigureFile-BadArg.cmake b/Tests/CMakeTests/ConfigureFile-BadArg.cmake
new file mode 100644
index 000000000..769fae1ab
--- /dev/null
+++ b/Tests/CMakeTests/ConfigureFile-BadArg.cmake
@@ -0,0 +1 @@
+configure_file(.)
diff --git a/Tests/CMakeTests/ConfigureFile-DirInput.cmake b/Tests/CMakeTests/ConfigureFile-DirInput.cmake
new file mode 100644
index 000000000..920ea280c
--- /dev/null
+++ b/Tests/CMakeTests/ConfigureFile-DirInput.cmake
@@ -0,0 +1 @@
+configure_file(. .)
diff --git a/Tests/CMakeTests/ConfigureFile-DirOutput.cmake b/Tests/CMakeTests/ConfigureFile-DirOutput.cmake
new file mode 100644
index 000000000..d682a2d85
--- /dev/null
+++ b/Tests/CMakeTests/ConfigureFile-DirOutput.cmake
@@ -0,0 +1,5 @@
+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
new file mode 100644
index 000000000..3b09eb0c3
--- /dev/null
+++ b/Tests/CMakeTests/ConfigureFile-NewLineStyle-COPYONLY.cmake
@@ -0,0 +1,3 @@
+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
new file mode 100644
index 000000000..133a67a8a
--- /dev/null
+++ b/Tests/CMakeTests/ConfigureFile-NewLineStyle-NoArg.cmake
@@ -0,0 +1,3 @@
+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
new file mode 100644
index 000000000..b7e619ca2
--- /dev/null
+++ b/Tests/CMakeTests/ConfigureFile-NewLineStyle-ValidArg.cmake
@@ -0,0 +1,17 @@
+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
new file mode 100644
index 000000000..e8887c127
--- /dev/null
+++ b/Tests/CMakeTests/ConfigureFile-NewLineStyle-WrongArg.cmake
@@ -0,0 +1,3 @@
+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
new file mode 100644
index 000000000..532580a21
--- /dev/null
+++ b/Tests/CMakeTests/ConfigureFile-Relative.cmake
@@ -0,0 +1,4 @@
+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
new file mode 100644
index 000000000..6cc61d90c
--- /dev/null
+++ b/Tests/CMakeTests/ConfigureFileTest.cmake.in
@@ -0,0 +1,28 @@
+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/DummyToolchain.cmake b/Tests/CMakeTests/DummyToolchain.cmake
new file mode 100644
index 000000000..6a602015b
--- /dev/null
+++ b/Tests/CMakeTests/DummyToolchain.cmake
@@ -0,0 +1,8 @@
+set(CMAKE_SYSTEM_NAME Dumdidum)
+set(CMAKE_SYSTEM_VERSION "1.0")
+
+set(CMAKE_C_COMPILER /opt/foo/bin/arm-elf-gcc)
+set(CMAKE_C_OUTPUT_EXTENSION ".foo")
+
+set(CMAKE_CXX_COMPILER /opt/bar/bin/cl.exe)
+set(CMAKE_CXX_OUTPUT_EXTENSION ".bar")
diff --git a/Tests/CMakeTests/ELF/elf32lsb.bin b/Tests/CMakeTests/ELF/elf32lsb.bin
new file mode 100644
index 000000000..803ac43f3
--- /dev/null
+++ b/Tests/CMakeTests/ELF/elf32lsb.bin
Binary files differ
diff --git a/Tests/CMakeTests/ELF/elf32msb.bin b/Tests/CMakeTests/ELF/elf32msb.bin
new file mode 100644
index 000000000..d04aaf76c
--- /dev/null
+++ b/Tests/CMakeTests/ELF/elf32msb.bin
Binary files differ
diff --git a/Tests/CMakeTests/ELF/elf64lsb.bin b/Tests/CMakeTests/ELF/elf64lsb.bin
new file mode 100644
index 000000000..a21e3eaa6
--- /dev/null
+++ b/Tests/CMakeTests/ELF/elf64lsb.bin
Binary files differ
diff --git a/Tests/CMakeTests/ELF/elf64msb.bin b/Tests/CMakeTests/ELF/elf64msb.bin
new file mode 100644
index 000000000..bbe255189
--- /dev/null
+++ b/Tests/CMakeTests/ELF/elf64msb.bin
Binary files differ
diff --git a/Tests/CMakeTests/ELFTest.cmake.in b/Tests/CMakeTests/ELFTest.cmake.in
new file mode 100644
index 000000000..0271abb1f
--- /dev/null
+++ b/Tests/CMakeTests/ELFTest.cmake.in
@@ -0,0 +1,48 @@
+set(names
+ elf32lsb.bin
+ elf32msb.bin
+ elf64lsb.bin
+ elf64msb.bin
+ )
+
+# Prepare binaries on which to operate.
+set(in "@CMAKE_CURRENT_SOURCE_DIR@/ELF")
+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})
+ list(APPEND files "${out}/${f}")
+endforeach()
+
+foreach(f ${files})
+ # Check for the initial RPATH.
+ file(RPATH_CHECK FILE "${f}" RPATH "/sample/rpath")
+ if(NOT EXISTS "${f}")
+ message(FATAL_ERROR "RPATH_CHECK removed ${f}")
+ endif()
+
+ # Change the RPATH.
+ file(RPATH_CHANGE FILE "${f}"
+ OLD_RPATH "/sample/rpath"
+ NEW_RPATH "/rpath/sample")
+ set(rpath)
+ file(STRINGS "${f}" rpath REGEX "/rpath/sample" LIMIT_COUNT 1)
+ if(NOT rpath)
+ message(FATAL_ERROR "RPATH not changed in ${f}")
+ endif()
+
+ # Remove the RPATH.
+ file(RPATH_REMOVE FILE "${f}")
+ set(rpath)
+ file(STRINGS "${f}" rpath REGEX "/rpath/sample" LIMIT_COUNT 1)
+ if(rpath)
+ message(FATAL_ERROR "RPATH not removed from ${f}")
+ endif()
+
+ # Check again...this should remove the file.
+ file(RPATH_CHECK FILE "${f}" RPATH "/sample/rpath")
+ if(EXISTS "${f}")
+ message(FATAL_ERROR "RPATH_CHECK did not remove ${f}")
+ endif()
+endforeach()
diff --git a/Tests/CMakeTests/EndStuffTest.cmake.in b/Tests/CMakeTests/EndStuffTest.cmake.in
new file mode 100644
index 000000000..de5dd5073
--- /dev/null
+++ b/Tests/CMakeTests/EndStuffTest.cmake.in
@@ -0,0 +1,18 @@
+# Execute each test listed in:
+#
+set(scriptname "@CMAKE_CURRENT_SOURCE_DIR@/EndStuffTestScript.cmake")
+set(number_of_tests_expected 9)
+
+include("@CMAKE_CURRENT_SOURCE_DIR@/ExecuteScriptTests.cmake")
+execute_all_script_tests(${scriptname} number_of_tests_executed)
+
+# And verify that number_of_tests_executed is at least as many as we know
+# about as of this writing...
+#
+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)
+ message(FATAL_ERROR "error: some test cases were skipped")
+endif()
diff --git a/Tests/CMakeTests/EndStuffTestScript.cmake b/Tests/CMakeTests/EndStuffTestScript.cmake
new file mode 100644
index 000000000..9f4081801
--- /dev/null
+++ b/Tests/CMakeTests/EndStuffTestScript.cmake
@@ -0,0 +1,70 @@
+message(STATUS "testname='${testname}'")
+
+if(testname STREQUAL bad_else) # fail
+ file(WRITE "${dir}/${testname}.cmake"
+"else()
+")
+ execute_process(COMMAND ${CMAKE_COMMAND} -P "${dir}/${testname}.cmake"
+ RESULT_VARIABLE rv)
+ if(NOT rv EQUAL 0)
+ message(FATAL_ERROR "${testname} failed")
+ endif()
+
+elseif(testname STREQUAL bad_elseif) # fail
+ file(WRITE "${dir}/${testname}.cmake"
+"elseif()
+")
+ execute_process(COMMAND ${CMAKE_COMMAND} -P "${dir}/${testname}.cmake"
+ RESULT_VARIABLE rv)
+ if(NOT rv EQUAL 0)
+ message(FATAL_ERROR "${testname} failed")
+ endif()
+
+elseif(testname STREQUAL bad_endforeach) # fail
+ endforeach()
+
+elseif(testname STREQUAL bad_endfunction) # fail
+ endfunction()
+
+elseif(testname STREQUAL bad_endif) # fail
+ file(WRITE "${dir}/${testname}.cmake"
+"cmake_minimum_required(VERSION 2.8)
+endif()
+")
+ execute_process(COMMAND ${CMAKE_COMMAND} -P "${dir}/${testname}.cmake"
+ RESULT_VARIABLE rv)
+ if(NOT rv EQUAL 0)
+ message(FATAL_ERROR "${testname} failed")
+ endif()
+
+elseif(testname STREQUAL endif_low_min_version) # pass
+ file(WRITE "${dir}/${testname}.cmake"
+"cmake_minimum_required(VERSION 1.2)
+endif()
+")
+ execute_process(COMMAND ${CMAKE_COMMAND} -P "${dir}/${testname}.cmake"
+ RESULT_VARIABLE rv)
+ if(NOT rv EQUAL 0)
+ message(FATAL_ERROR "${testname} failed")
+ endif()
+
+elseif(testname STREQUAL endif_no_min_version) # pass
+ file(WRITE "${dir}/${testname}.cmake"
+"endif()
+")
+ execute_process(COMMAND ${CMAKE_COMMAND} -P "${dir}/${testname}.cmake"
+ RESULT_VARIABLE rv)
+ if(NOT rv EQUAL 0)
+ message(FATAL_ERROR "${testname} failed")
+ endif()
+
+elseif(testname STREQUAL bad_endmacro) # fail
+ endmacro()
+
+elseif(testname STREQUAL bad_endwhile) # fail
+ endwhile()
+
+else() # fail
+ message(FATAL_ERROR "testname='${testname}' - error: no such test in '${CMAKE_CURRENT_LIST_FILE}'")
+
+endif()
diff --git a/Tests/CMakeTests/ExecuteScriptTests.cmake b/Tests/CMakeTests/ExecuteScriptTests.cmake
new file mode 100644
index 000000000..c71585a02
--- /dev/null
+++ b/Tests/CMakeTests/ExecuteScriptTests.cmake
@@ -0,0 +1,63 @@
+# This function calls the ${scriptname} file to execute one test case:
+#
+function(execute_one_script_test scriptname testname expected_result)
+ message("execute_one_script_test")
+ message("testname=[${testname}]")
+
+ execute_process(
+ COMMAND ${CMAKE_COMMAND}
+ -D "dir:STRING=${dir}"
+ -D "testname:STRING=${testname}"
+ -P "${scriptname}"
+ OUTPUT_VARIABLE out
+ ERROR_VARIABLE err
+ RESULT_VARIABLE result
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_STRIP_TRAILING_WHITESPACE
+ )
+
+ message("out=[${out}]")
+ message("err=[${err}]")
+
+ if(expected_result STREQUAL "fail")
+ # case expected to fail, result should be non-0...
+ # error if it's 0
+ if("${result}" STREQUAL "0")
+ message(SEND_ERROR "script failed: testname='${testname}' [${result}] actually passed, but expected to fail...")
+ endif()
+ else()
+ # case expected to pass, result should be 0...
+ # error if it's non-0
+ if(NOT "${result}" STREQUAL "0")
+ message(SEND_ERROR "script failed: testname='${testname}' [${result}] actually failed, but expected to pass...")
+ endif()
+ endif()
+
+ message("")
+endfunction()
+
+
+# This function reads the script file and calls execute_one_script_test for
+# each testname case listed in the script. To add new cases, simply edit the
+# script file and add an elseif() clause that matches 'regex' below.
+#
+function(execute_all_script_tests scriptname result)
+ file(READ "${scriptname}" script)
+
+ string(REPLACE ";" "\\\\;" script "${script}")
+ string(REPLACE "\n" "E;" script "${script}")
+
+ set(count 0)
+ set(regex "^ *(if|elseif) *\\( *testname +STREQUAL +\\\"*([^\\\"\\)]+)\\\"* *\\) *# *(fail|pass) *E$")
+
+ foreach(line ${script})
+ if(line MATCHES "${regex}")
+ 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()
+
+ set(${result} ${count} PARENT_SCOPE)
+endfunction()
diff --git a/Tests/CMakeTests/File-Copy-BadArg.cmake b/Tests/CMakeTests/File-Copy-BadArg.cmake
new file mode 100644
index 000000000..91952fc60
--- /dev/null
+++ b/Tests/CMakeTests/File-Copy-BadArg.cmake
@@ -0,0 +1 @@
+file(COPY FileTest.cmake DESTINATION tmp PATTERN * BADARG)
diff --git a/Tests/CMakeTests/File-Copy-BadPerm.cmake b/Tests/CMakeTests/File-Copy-BadPerm.cmake
new file mode 100644
index 000000000..b5cc42f00
--- /dev/null
+++ b/Tests/CMakeTests/File-Copy-BadPerm.cmake
@@ -0,0 +1 @@
+file(COPY FileTest.cmake DESTINATION tmp FILE_PERMISSIONS BADPERM)
diff --git a/Tests/CMakeTests/File-Copy-BadRegex.cmake b/Tests/CMakeTests/File-Copy-BadRegex.cmake
new file mode 100644
index 000000000..41340f623
--- /dev/null
+++ b/Tests/CMakeTests/File-Copy-BadRegex.cmake
@@ -0,0 +1 @@
+file(COPY FileTest.cmake DESTINATION tmp REGEX "(")
diff --git a/Tests/CMakeTests/File-Copy-EarlyArg.cmake b/Tests/CMakeTests/File-Copy-EarlyArg.cmake
new file mode 100644
index 000000000..03993de38
--- /dev/null
+++ b/Tests/CMakeTests/File-Copy-EarlyArg.cmake
@@ -0,0 +1 @@
+file(COPY FileTest.cmake DESTINATION tmp PERMISSIONS)
diff --git a/Tests/CMakeTests/File-Copy-LateArg.cmake b/Tests/CMakeTests/File-Copy-LateArg.cmake
new file mode 100644
index 000000000..43d216874
--- /dev/null
+++ b/Tests/CMakeTests/File-Copy-LateArg.cmake
@@ -0,0 +1 @@
+file(COPY FileTest.cmake DESTINATION tmp PATTERN * FILE_PERMISSIONS)
diff --git a/Tests/CMakeTests/File-Copy-NoDest.cmake b/Tests/CMakeTests/File-Copy-NoDest.cmake
new file mode 100644
index 000000000..f6c6c6d7e
--- /dev/null
+++ b/Tests/CMakeTests/File-Copy-NoDest.cmake
@@ -0,0 +1 @@
+file(COPY FileTest.cmake)
diff --git a/Tests/CMakeTests/File-Copy-NoFile.cmake b/Tests/CMakeTests/File-Copy-NoFile.cmake
new file mode 100644
index 000000000..d5853d396
--- /dev/null
+++ b/Tests/CMakeTests/File-Copy-NoFile.cmake
@@ -0,0 +1 @@
+file(COPY does_not_exist.txt DESTINATION tmp)
diff --git a/Tests/CMakeTests/File-HASH-Input.txt b/Tests/CMakeTests/File-HASH-Input.txt
new file mode 100644
index 000000000..a1d315b2d
--- /dev/null
+++ b/Tests/CMakeTests/File-HASH-Input.txt
@@ -0,0 +1 @@
+sample input string
diff --git a/Tests/CMakeTests/File-MD5-BadArg1.cmake b/Tests/CMakeTests/File-MD5-BadArg1.cmake
new file mode 100644
index 000000000..ac5f67ae2
--- /dev/null
+++ b/Tests/CMakeTests/File-MD5-BadArg1.cmake
@@ -0,0 +1 @@
+file(MD5)
diff --git a/Tests/CMakeTests/File-MD5-BadArg2.cmake b/Tests/CMakeTests/File-MD5-BadArg2.cmake
new file mode 100644
index 000000000..2acc0757e
--- /dev/null
+++ b/Tests/CMakeTests/File-MD5-BadArg2.cmake
@@ -0,0 +1 @@
+file(MD5 ${CMAKE_CURRENT_LIST_DIR}/File-HASH-Input.txt)
diff --git a/Tests/CMakeTests/File-MD5-BadArg4.cmake b/Tests/CMakeTests/File-MD5-BadArg4.cmake
new file mode 100644
index 000000000..79b27558d
--- /dev/null
+++ b/Tests/CMakeTests/File-MD5-BadArg4.cmake
@@ -0,0 +1 @@
+file(MD5 ${CMAKE_CURRENT_LIST_DIR}/File-HASH-Input.txt md5 extra_arg)
diff --git a/Tests/CMakeTests/File-MD5-NoFile.cmake b/Tests/CMakeTests/File-MD5-NoFile.cmake
new file mode 100644
index 000000000..1b91bc8d8
--- /dev/null
+++ b/Tests/CMakeTests/File-MD5-NoFile.cmake
@@ -0,0 +1 @@
+file(MD5 ${CMAKE_CURRENT_LIST_DIR}/DoesNotExist.cmake md5)
diff --git a/Tests/CMakeTests/File-MD5-Works.cmake b/Tests/CMakeTests/File-MD5-Works.cmake
new file mode 100644
index 000000000..0fabe54a4
--- /dev/null
+++ b/Tests/CMakeTests/File-MD5-Works.cmake
@@ -0,0 +1,2 @@
+file(MD5 ${CMAKE_CURRENT_LIST_DIR}/File-HASH-Input.txt md5)
+message("${md5}")
diff --git a/Tests/CMakeTests/File-SHA1-Works.cmake b/Tests/CMakeTests/File-SHA1-Works.cmake
new file mode 100644
index 000000000..f2ab5d747
--- /dev/null
+++ b/Tests/CMakeTests/File-SHA1-Works.cmake
@@ -0,0 +1,2 @@
+file(SHA1 ${CMAKE_CURRENT_LIST_DIR}/File-HASH-Input.txt sha1)
+message("${sha1}")
diff --git a/Tests/CMakeTests/File-SHA224-Works.cmake b/Tests/CMakeTests/File-SHA224-Works.cmake
new file mode 100644
index 000000000..3e86b172f
--- /dev/null
+++ b/Tests/CMakeTests/File-SHA224-Works.cmake
@@ -0,0 +1,2 @@
+file(SHA224 ${CMAKE_CURRENT_LIST_DIR}/File-HASH-Input.txt sha224)
+message("${sha224}")
diff --git a/Tests/CMakeTests/File-SHA256-Works.cmake b/Tests/CMakeTests/File-SHA256-Works.cmake
new file mode 100644
index 000000000..b72d89e95
--- /dev/null
+++ b/Tests/CMakeTests/File-SHA256-Works.cmake
@@ -0,0 +1,2 @@
+file(SHA256 ${CMAKE_CURRENT_LIST_DIR}/File-HASH-Input.txt sha256)
+message("${sha256}")
diff --git a/Tests/CMakeTests/File-SHA384-Works.cmake b/Tests/CMakeTests/File-SHA384-Works.cmake
new file mode 100644
index 000000000..0eeca33cb
--- /dev/null
+++ b/Tests/CMakeTests/File-SHA384-Works.cmake
@@ -0,0 +1,2 @@
+file(SHA384 ${CMAKE_CURRENT_LIST_DIR}/File-HASH-Input.txt sha384)
+message("${sha384}")
diff --git a/Tests/CMakeTests/File-SHA512-Works.cmake b/Tests/CMakeTests/File-SHA512-Works.cmake
new file mode 100644
index 000000000..d74ee4429
--- /dev/null
+++ b/Tests/CMakeTests/File-SHA512-Works.cmake
@@ -0,0 +1,2 @@
+file(SHA512 ${CMAKE_CURRENT_LIST_DIR}/File-HASH-Input.txt sha512)
+message("${sha512}")
diff --git a/Tests/CMakeTests/FileDownloadInput.png b/Tests/CMakeTests/FileDownloadInput.png
new file mode 100644
index 000000000..7bbcee413
--- /dev/null
+++ b/Tests/CMakeTests/FileDownloadInput.png
Binary files differ
diff --git a/Tests/CMakeTests/FileDownloadTest.cmake.in b/Tests/CMakeTests/FileDownloadTest.cmake.in
new file mode 100644
index 000000000..9dc2ebb27
--- /dev/null
+++ b/Tests/CMakeTests/FileDownloadTest.cmake.in
@@ -0,0 +1,43 @@
+set(url "file://@CMAKE_CURRENT_SOURCE_DIR@/FileDownloadInput.png")
+set(dir "@CMAKE_CURRENT_BINARY_DIR@/downloads")
+
+message(STATUS "FileDownload:1")
+file(DOWNLOAD
+ ${url}
+ ${dir}/file1.png
+ TIMEOUT 2
+ )
+
+message(STATUS "FileDownload:2")
+file(DOWNLOAD
+ ${url}
+ ${dir}/file2.png
+ TIMEOUT 2
+ SHOW_PROGRESS
+ )
+
+# Two calls in a row, exactly the same arguments.
+# Since downloaded file should exist already for 2nd call,
+# the 2nd call will short-circuit and return early...
+#
+if(EXISTS ${dir}/file3.png)
+ file(REMOVE ${dir}/file3.png)
+endif()
+
+message(STATUS "FileDownload:3")
+file(DOWNLOAD
+ ${url}
+ ${dir}/file3.png
+ TIMEOUT 2
+ EXPECTED_MD5 d16778650db435bda3a8c3435c3ff5d1
+ )
+
+message(STATUS "FileDownload:4")
+file(DOWNLOAD
+ ${url}
+ ${dir}/file3.png
+ TIMEOUT 2
+ STATUS status
+ EXPECTED_MD5 d16778650db435bda3a8c3435c3ff5d1
+ )
+message(STATUS "${status}")
diff --git a/Tests/CMakeTests/FileTest.cmake.in b/Tests/CMakeTests/FileTest.cmake.in
new file mode 100644
index 000000000..3c3d85ddc
--- /dev/null
+++ b/Tests/CMakeTests/FileTest.cmake.in
@@ -0,0 +1,74 @@
+set(Copy-BadArg-RESULT 1)
+set(Copy-BadArg-STDERR "unknown argument \"BADARG\"")
+set(Copy-BadPerm-RESULT 1)
+set(Copy-BadPerm-STDERR "COPY given invalid permission \"BADPERM\"")
+set(Copy-BadRegex-RESULT 1)
+set(Copy-BadRegex-STDERR "could not compile REGEX")
+set(Copy-EarlyArg-RESULT 1)
+set(Copy-EarlyArg-STDERR "option PERMISSIONS may not appear before")
+set(Copy-LateArg-RESULT 1)
+set(Copy-LateArg-STDERR "option FILE_PERMISSIONS may not appear after")
+set(Copy-NoDest-RESULT 1)
+set(Copy-NoDest-STDERR "given no DESTINATION")
+set(Copy-NoFile-RESULT 1)
+set(Copy-NoFile-STDERR "COPY cannot find.*/does_not_exist\\.txt")
+set(MD5-NoFile-RESULT 1)
+set(MD5-NoFile-STDERR "file MD5 failed to read file")
+set(MD5-BadArg1-RESULT 1)
+set(MD5-BadArg1-STDERR "file must be called with at least two arguments")
+set(MD5-BadArg2-RESULT 1)
+set(MD5-BadArg2-STDERR "file MD5 requires a file name and output variable")
+set(MD5-BadArg4-RESULT 1)
+set(MD5-BadArg4-STDERR "file MD5 requires a file name and output variable")
+set(MD5-Works-RESULT 0)
+set(MD5-Works-STDERR "10d20ddb981a6202b84aa1ce1cb7fce3")
+set(SHA1-Works-RESULT 0)
+set(SHA1-Works-STDERR "83f093e04289b21a9415f408ad50be8b57ad2f34")
+set(SHA224-Works-RESULT 0)
+set(SHA224-Works-STDERR "e995a7789922c4ef9279d94e763c8375934180a51baa7147bc48edf7")
+set(SHA256-Works-RESULT 0)
+set(SHA256-Works-STDERR "d1c5915d8b71150726a1eef75a29ec6bea8fd1bef6b7299ef8048760b0402025")
+set(SHA384-Works-RESULT 0)
+set(SHA384-Works-STDERR "1de9560b4e030e02051ea408200ffc55d70c97ac64ebf822461a5c786f495c36df43259b14483bc8d364f0106f4971ee")
+set(SHA512-Works-RESULT 0)
+set(SHA512-Works-STDERR "3982a1b4e651768bec70ab1fb97045cb7a659f4ba7203d501c52ab2e803071f9d5fd272022df15f27727fc67f8cd022e710e29010b2a9c0b467c111e2f6abf51")
+
+include("@CMAKE_CURRENT_SOURCE_DIR@/CheckCMakeTest.cmake")
+check_cmake_test(File
+ Copy-BadArg
+ Copy-BadPerm
+ Copy-BadRegex
+ Copy-EarlyArg
+ Copy-LateArg
+ Copy-NoDest
+ Copy-NoFile
+ MD5-NoFile
+ MD5-BadArg1
+ MD5-BadArg2
+ MD5-BadArg4
+ MD5-Works
+ SHA1-Works
+ SHA224-Works
+ SHA256-Works
+ SHA384-Works
+ SHA512-Works
+ )
+
+# Also execute each test listed in FileTestScript.cmake:
+#
+set(scriptname "@CMAKE_CURRENT_SOURCE_DIR@/FileTestScript.cmake")
+set(number_of_tests_expected 62)
+
+include("@CMAKE_CURRENT_SOURCE_DIR@/ExecuteScriptTests.cmake")
+execute_all_script_tests(${scriptname} number_of_tests_executed)
+
+# And verify that number_of_tests_executed is at least as many as we know
+# about as of this writing...
+#
+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)
+ message(FATAL_ERROR "error: some test cases were skipped")
+endif()
diff --git a/Tests/CMakeTests/FileTestScript.cmake b/Tests/CMakeTests/FileTestScript.cmake
new file mode 100644
index 000000000..9a4356973
--- /dev/null
+++ b/Tests/CMakeTests/FileTestScript.cmake
@@ -0,0 +1,227 @@
+message(STATUS "testname='${testname}'")
+
+if(testname STREQUAL empty) # fail
+ file()
+
+elseif(testname STREQUAL bogus) # fail
+ file(BOGUS ffff)
+
+elseif(testname STREQUAL different_not_enough_args) # fail
+ file(DIFFERENT ffff)
+
+elseif(testname STREQUAL download_not_enough_args) # fail
+ file(DOWNLOAD ffff)
+
+elseif(testname STREQUAL read_not_enough_args) # fail
+ file(READ ffff)
+
+elseif(testname STREQUAL rpath_check_not_enough_args) # fail
+ file(RPATH_CHECK ffff)
+
+elseif(testname STREQUAL rpath_remove_not_enough_args) # fail
+ file(RPATH_REMOVE ffff)
+
+elseif(testname STREQUAL strings_not_enough_args) # fail
+ file(STRINGS ffff)
+
+elseif(testname STREQUAL to_native_path_not_enough_args) # fail
+ file(TO_NATIVE_PATH ffff)
+
+elseif(testname STREQUAL read_with_offset) # pass
+ file(READ ${CMAKE_CURRENT_LIST_FILE} v OFFSET 42 LIMIT 30)
+ message("v='${v}'")
+
+elseif(testname STREQUAL strings_bad_length_minimum) # fail
+ file(STRINGS ${CMAKE_CURRENT_LIST_FILE} v LENGTH_MINIMUM bogus)
+
+elseif(testname STREQUAL strings_bad_length_maximum) # fail
+ file(STRINGS ${CMAKE_CURRENT_LIST_FILE} v LENGTH_MAXIMUM bogus)
+
+elseif(testname STREQUAL strings_bad_limit_count) # fail
+ file(STRINGS ${CMAKE_CURRENT_LIST_FILE} v LIMIT_COUNT bogus)
+
+elseif(testname STREQUAL strings_bad_limit_input) # fail
+ file(STRINGS ${CMAKE_CURRENT_LIST_FILE} v LIMIT_INPUT bogus)
+
+elseif(testname STREQUAL strings_bad_limit_output) # fail
+ file(STRINGS ${CMAKE_CURRENT_LIST_FILE} v LIMIT_OUTPUT bogus)
+
+elseif(testname STREQUAL strings_bad_regex) # fail
+ file(STRINGS ${CMAKE_CURRENT_LIST_FILE} v REGEX "(")
+
+elseif(testname STREQUAL strings_unknown_arg) # fail
+ file(STRINGS ${CMAKE_CURRENT_LIST_FILE} v BOGUS)
+
+elseif(testname STREQUAL strings_bad_filename) # fail
+ file(STRINGS ffff v LIMIT_COUNT 10)
+
+elseif(testname STREQUAL strings_use_limit_count) # pass
+ file(STRINGS ${CMAKE_CURRENT_LIST_FILE} v LIMIT_COUNT 10)
+ message("v='${v}'")
+
+elseif(testname STREQUAL strings_use_no_hex_conversion) # pass
+ file(STRINGS ${CMAKE_CURRENT_LIST_FILE} v NO_HEX_CONVERSION)
+ message("v='${v}'")
+
+elseif(testname STREQUAL glob_recurse_follow_symlinks_no_expression) # fail
+ file(GLOB_RECURSE v FOLLOW_SYMLINKS)
+
+elseif(testname STREQUAL glob_recurse_relative_no_directory) # fail
+ file(GLOB_RECURSE v RELATIVE)
+
+elseif(testname STREQUAL glob_recurse_relative_no_expression) # fail
+ file(GLOB_RECURSE v RELATIVE dddd)
+
+elseif(testname STREQUAL glob_non_full_path) # pass
+ file(GLOB_RECURSE v ffff*.*)
+ message("v='${v}'")
+
+elseif(testname STREQUAL make_directory_non_full_path) # pass
+ file(MAKE_DIRECTORY FileTestScriptDDDD)
+ if(NOT EXISTS FileTestScriptDDDD)
+ message(FATAL_ERROR "error: non-full-path MAKE_DIRECTORY failed")
+ endif()
+ file(REMOVE_RECURSE FileTestScriptDDDD)
+ if(EXISTS FileTestScriptDDDD)
+ message(FATAL_ERROR "error: non-full-path REMOVE_RECURSE failed")
+ endif()
+
+elseif(testname STREQUAL different_no_variable) # fail
+ file(DIFFERENT FILES)
+
+elseif(testname STREQUAL different_no_files) # fail
+ file(DIFFERENT v FILES)
+
+elseif(testname STREQUAL different_unknown_arg) # fail
+ file(DIFFERENT v FILES ffffLHS ffffRHS BOGUS)
+
+elseif(testname STREQUAL different_different) # pass
+ file(DIFFERENT v FILES ffffLHS ffffRHS)
+ message("v='${v}'")
+
+elseif(testname STREQUAL different_same) # pass
+ file(DIFFERENT v FILES
+ ${CMAKE_CURRENT_LIST_FILE} ${CMAKE_CURRENT_LIST_FILE})
+ message("v='${v}'")
+
+elseif(testname STREQUAL rpath_change_unknown_arg) # fail
+ file(RPATH_CHANGE BOGUS)
+
+elseif(testname STREQUAL rpath_change_bad_file) # fail
+ file(RPATH_CHANGE FILE)
+
+elseif(testname STREQUAL rpath_change_bad_old_rpath) # fail
+ file(RPATH_CHANGE FILE ffff OLD_RPATH)
+
+elseif(testname STREQUAL rpath_change_bad_new_rpath) # fail
+ file(RPATH_CHANGE FILE ffff OLD_RPATH rrrr NEW_RPATH)
+
+elseif(testname STREQUAL rpath_change_file_does_not_exist) # fail
+ file(RPATH_CHANGE FILE ffff OLD_RPATH rrrr NEW_RPATH RRRR)
+
+elseif(testname STREQUAL rpath_change_file_is_not_executable) # fail
+ file(RPATH_CHANGE FILE ${CMAKE_CURRENT_LIST_FILE}
+ OLD_RPATH rrrr NEW_RPATH RRRR)
+
+elseif(testname STREQUAL rpath_remove_unknown_arg) # fail
+ file(RPATH_REMOVE BOGUS)
+
+elseif(testname STREQUAL rpath_remove_bad_file) # fail
+ file(RPATH_REMOVE FILE)
+
+elseif(testname STREQUAL rpath_remove_file_does_not_exist) # fail
+ file(RPATH_REMOVE FILE ffff)
+
+#elseif(testname STREQUAL rpath_remove_file_is_not_executable) # fail
+# file(RPATH_REMOVE FILE ${CMAKE_CURRENT_LIST_FILE})
+
+elseif(testname STREQUAL rpath_check_unknown_arg) # fail
+ file(RPATH_CHECK BOGUS)
+
+elseif(testname STREQUAL rpath_check_bad_file) # fail
+ file(RPATH_CHECK FILE)
+
+elseif(testname STREQUAL rpath_check_bad_rpath) # fail
+ file(RPATH_CHECK FILE ffff RPATH)
+
+elseif(testname STREQUAL rpath_check_file_does_not_exist) # pass
+ file(RPATH_CHECK FILE ffff RPATH rrrr)
+
+elseif(testname STREQUAL rpath_check_file_is_not_executable) # pass
+ file(WRITE ffff_rpath_check "")
+
+ if(NOT EXISTS ffff_rpath_check)
+ message(FATAL_ERROR "error: non-full-path WRITE failed")
+ endif()
+
+ file(RPATH_CHECK FILE ffff_rpath_check RPATH rrrr)
+ # careful: if the file does not have the given RPATH, it is deleted...
+
+ if(EXISTS ffff_rpath_check)
+ message(FATAL_ERROR "error: non-full-path RPATH_CHECK failed")
+ endif()
+
+elseif(testname STREQUAL relative_path_wrong_number_of_args) # fail
+ file(RELATIVE_PATH v dir)
+
+elseif(testname STREQUAL relative_path_non_full_path_dir) # fail
+ file(RELATIVE_PATH v dir file)
+
+elseif(testname STREQUAL relative_path_non_full_path_file) # fail
+ file(RELATIVE_PATH v /dir file)
+
+elseif(testname STREQUAL rename_wrong_number_of_args) # fail
+ file(RENAME ffff)
+
+elseif(testname STREQUAL rename_input_file_does_not_exist) # fail
+ file(RENAME ffff FFFFGGGG)
+
+elseif(testname STREQUAL to_native_path) # pass
+ file(TO_NATIVE_PATH /a/b/c\;/d/e/f:/g/h/i v)
+ message("v='${v}'")
+
+elseif(testname STREQUAL download_wrong_number_of_args) # fail
+ file(DOWNLOAD zzzz://bogus/ffff)
+
+elseif(testname STREQUAL download_file_with_no_path) # fail
+ file(DOWNLOAD zzzz://bogus/ffff ffff)
+
+elseif(testname STREQUAL download_missing_time) # fail
+ file(DOWNLOAD zzzz://bogus/ffff ./ffff TIMEOUT)
+
+elseif(testname STREQUAL download_missing_log_var) # fail
+ file(DOWNLOAD zzzz://bogus/ffff ./ffff TIMEOUT 2 LOG)
+
+elseif(testname STREQUAL download_missing_status_var) # fail
+ file(DOWNLOAD zzzz://bogus/ffff ./ffff TIMEOUT 2 LOG l STATUS)
+
+elseif(testname STREQUAL download_with_bogus_protocol) # pass
+ file(DOWNLOAD zzzz://bogus/ffff ./ffff TIMEOUT 2 LOG l STATUS s)
+ file(REMOVE ./ffff)
+ message("l='${l}'")
+ message("s='${s}'")
+
+elseif(testname STREQUAL upload_wrong_number_of_args) # fail
+ file(UPLOAD ./ffff)
+
+elseif(testname STREQUAL upload_missing_time) # fail
+ file(UPLOAD ./ffff zzzz://bogus/ffff TIMEOUT)
+
+elseif(testname STREQUAL upload_missing_log_var) # fail
+ file(UPLOAD ./ffff zzzz://bogus/ffff TIMEOUT 2 LOG)
+
+elseif(testname STREQUAL upload_missing_status_var) # fail
+ file(UPLOAD ./ffff zzzz://bogus/ffff TIMEOUT 2 LOG l STATUS)
+
+elseif(testname STREQUAL upload_file_that_doesnt_exist) # fail
+ file(UPLOAD ./ffff zzzz://bogus/ffff)
+
+elseif(testname STREQUAL upload_with_bogus_protocol) # pass
+ file(UPLOAD ${CMAKE_CURRENT_LIST_FILE} zzzz://bogus/ffff TIMEOUT 2 LOG l STATUS s)
+ message("l='${l}'")
+ message("s='${s}'")
+
+else() # fail
+ message(FATAL_ERROR "testname='${testname}' - error: no such test in '${CMAKE_CURRENT_LIST_FILE}'")
+
+endif()
diff --git a/Tests/CMakeTests/FileUploadTest.cmake.in b/Tests/CMakeTests/FileUploadTest.cmake.in
new file mode 100644
index 000000000..8577aefd2
--- /dev/null
+++ b/Tests/CMakeTests/FileUploadTest.cmake.in
@@ -0,0 +1,49 @@
+file(REMOVE_RECURSE "@CMAKE_CURRENT_BINARY_DIR@/uploads")
+
+if(EXISTS "@CMAKE_CURRENT_BINARY_DIR@/uploads/file1.png")
+ message(FATAL_ERROR "error: file1.png exists - should have been deleted")
+endif()
+if(EXISTS "@CMAKE_CURRENT_BINARY_DIR@/uploads/file2.png")
+ message(FATAL_ERROR "error: file2.png exists - should have been deleted")
+endif()
+
+file(MAKE_DIRECTORY "@CMAKE_CURRENT_BINARY_DIR@/uploads")
+
+set(filename "@CMAKE_CURRENT_SOURCE_DIR@/FileDownloadInput.png")
+set(urlbase "file://@CMAKE_CURRENT_BINARY_DIR@/uploads")
+
+message(STATUS "FileUpload:1")
+file(UPLOAD
+ ${filename}
+ ${urlbase}/file1.png
+ TIMEOUT 2
+ )
+
+message(STATUS "FileUpload:2")
+file(UPLOAD
+ ${filename}
+ ${urlbase}/file2.png
+ STATUS status
+ LOG log
+ SHOW_PROGRESS
+ )
+
+execute_process(COMMAND ${CMAKE_COMMAND} -E md5sum
+ "@CMAKE_CURRENT_BINARY_DIR@/uploads/file1.png"
+ OUTPUT_VARIABLE sum1
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+if(NOT sum1 MATCHES "^d16778650db435bda3a8c3435c3ff5d1 .*/uploads/file1.png$")
+ message(FATAL_ERROR "file1.png did not upload correctly (sum1='${sum1}')")
+endif()
+
+execute_process(COMMAND ${CMAKE_COMMAND} -E md5sum
+ "@CMAKE_CURRENT_BINARY_DIR@/uploads/file2.png"
+ OUTPUT_VARIABLE sum2
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+if(NOT sum2 MATCHES "^d16778650db435bda3a8c3435c3ff5d1 .*/uploads/file2.png$")
+ message(FATAL_ERROR "file2.png did not upload correctly (sum2='${sum2}')")
+endif()
+
+message(STATUS "log='${log}'")
+message(STATUS "status='${status}'")
+message(STATUS "DONE")
diff --git a/Tests/CMakeTests/FindBaseTest.cmake.in b/Tests/CMakeTests/FindBaseTest.cmake.in
new file mode 100644
index 000000000..47c1692db
--- /dev/null
+++ b/Tests/CMakeTests/FindBaseTest.cmake.in
@@ -0,0 +1,62 @@
+set(MY_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@")
+
+# The find_* commands do path normalization so we should do so too
+# before comparing results.
+get_filename_component(MY_SOURCE_DIR "${MY_SOURCE_DIR}" ABSOLUTE)
+
+set(_HEADER cmake_i_do_not_exist_in_the_system.h)
+set(_HEADER_FULL "${MY_SOURCE_DIR}/include/${_HEADER}")
+set(_HEADER_FULL_A "${MY_SOURCE_DIR}/A/include/${_HEADER}")
+
+# at first check that the header isn't found without special measures
+find_file(FOO_H_1 ${_HEADER})
+if(FOO_H_1)
+ message(FATAL_ERROR "${_HEADER} found: ${FOO_H_1}, it should not exist !")
+endif(FOO_H_1)
+
+# The HINTS option should override the system but the PATHS option
+# should not.
+set(CMAKE_SYSTEM_PREFIX_PATH ${MY_SOURCE_DIR})
+find_file(TEST_H_1 ${_HEADER} HINTS ${MY_SOURCE_DIR}/A/include)
+find_file(TEST_H_2 ${_HEADER} PATHS ${MY_SOURCE_DIR}/A/include)
+if(NOT "${TEST_H_1}" STREQUAL "${_HEADER_FULL_A}")
+ message(FATAL_ERROR "Did not find \"${_HEADER_FULL_A}\"\ngot \"${TEST_H_1}\" instead!")
+endif(NOT "${TEST_H_1}" STREQUAL "${_HEADER_FULL_A}")
+if(NOT "${TEST_H_2}" STREQUAL "${_HEADER_FULL}")
+ message(FATAL_ERROR "Did not find \"${_HEADER_FULL}\"\ngot \"${TEST_H_2}\" instead!")
+endif(NOT "${TEST_H_2}" STREQUAL "${_HEADER_FULL}")
+set(CMAKE_SYSTEM_PREFIX_PATH)
+
+# with this it still should not be found, since the include/ subdir is still missing
+set(CMAKE_INCLUDE_PATH "${MY_SOURCE_DIR}")
+find_file(FOO_H_2 ${_HEADER})
+if(FOO_H_2)
+ message(FATAL_ERROR "${_HEADER} found: ${FOO_H_2}, it should not exist !")
+endif(FOO_H_2)
+
+# now with the PATH_SUFFIX it should be found
+find_file(FOO_H_3 NAMES ${_HEADER} PATH_SUFFIXES include )
+if(NOT "${FOO_H_3}" STREQUAL "${_HEADER_FULL}")
+ message(FATAL_ERROR "Did not find \"${_HEADER_FULL}\"\ngot ${FOO_H_3} instead !")
+endif(NOT "${FOO_H_3}" STREQUAL "${_HEADER_FULL}")
+
+# without PATH_SUFFIX, but with a CMAKE_INCLUDE_PATH it should not be found
+set(CMAKE_INCLUDE_PATH /include)
+find_file(FOO_H_4 ${_HEADER})
+if(FOO_H_4)
+ message(FATAL_ERROR "${_HEADER} found: ${FOO_H_4}, it should not exist !")
+endif(FOO_H_4)
+
+# when setting CMAKE_FIND_ROOT_PATH to the current source dir,
+# together with the CMAKE_INCLUDE_PATH it should be found
+set(CMAKE_FIND_ROOT_PATH blub "${MY_SOURCE_DIR}")
+find_file(FOO_H_5 ${_HEADER})
+if(NOT "${FOO_H_5}" STREQUAL "${_HEADER_FULL}")
+ message(FATAL_ERROR "Did not find \"${_HEADER_FULL}\"\ngot ${FOO_H_5} instead !")
+endif(NOT "${FOO_H_5}" STREQUAL "${_HEADER_FULL}")
+
+# by explicitly disabling CMAKE_FIND_ROOT_PATH again it shouldn't be found
+find_file(FOO_H_6 ${_HEADER} NO_CMAKE_FIND_ROOT_PATH)
+if(FOO_H_6)
+ message(FATAL_ERROR "${_HEADER} found: ${FOO_H_6}, it should not exist !")
+endif(FOO_H_6)
diff --git a/Tests/CMakeTests/GetFilenameComponentRealpathTest.cmake.in b/Tests/CMakeTests/GetFilenameComponentRealpathTest.cmake.in
new file mode 100644
index 000000000..7adc240f0
--- /dev/null
+++ b/Tests/CMakeTests/GetFilenameComponentRealpathTest.cmake.in
@@ -0,0 +1,72 @@
+set(bindir ${CMAKE_CURRENT_BINARY_DIR})
+
+#
+# Test nonexistent REALPATH & ABSOLUTE resolution
+#
+get_filename_component(nonexistent1 ${bindir}/THIS_IS_A_NONEXISTENT_FILE REALPATH)
+get_filename_component(nonexistent2 ${bindir}/THIS_IS_A_NONEXISTENT_FILE ABSOLUTE)
+if(NOT nonexistent1 STREQUAL "${bindir}/THIS_IS_A_NONEXISTENT_FILE")
+ message(FATAL_ERROR "REALPATH is not preserving nonexistent files")
+endif()
+if(NOT nonexistent2 STREQUAL "${bindir}/THIS_IS_A_NONEXISTENT_FILE")
+ message(FATAL_ERROR "ABSOLUTE is not preserving nonexistent files")
+endif()
+
+#
+# Test treatment of relative paths
+#
+foreach(c REALPATH ABSOLUTE)
+ get_filename_component(dir "subdir/THIS_IS_A_NONEXISTENT_FILE" ${c})
+ if(NOT "${dir}" STREQUAL "${bindir}/subdir/THIS_IS_A_NONEXISTENT_FILE")
+ message(FATAL_ERROR
+ "${c} does not handle relative paths. Expected:\n"
+ " ${bindir}/subdir/THIS_IS_A_NONEXISTENT_FILE\n"
+ "but got:\n"
+ " ${nonexistent1}\n"
+ )
+ endif()
+endforeach()
+
+#
+# Test symbolic link resolution
+#
+if(UNIX)
+ # file1 => file2 => file3 (real)
+ file(WRITE ${bindir}/file3 "test file")
+
+ find_program(LN NAMES "ln")
+ if(LN)
+ # Create symlinks using "ln -s"
+ if(NOT EXISTS ${bindir}/file2)
+ execute_process(COMMAND ${LN} "-s" "${bindir}/file3" "${bindir}/file2")
+ endif()
+ if(NOT EXISTS ${bindir}/file1)
+ execute_process(COMMAND ${LN} "-s" "${bindir}/file2" "${bindir}/file1")
+ endif()
+
+ get_filename_component(file1 ${bindir}/file1 REALPATH)
+ get_filename_component(file2 ${bindir}/file2 REALPATH)
+ get_filename_component(file3 ${bindir}/file3 REALPATH)
+
+ if(NOT file3 STREQUAL "${bindir}/file3")
+ message(FATAL_ERROR "CMake fails resolving REALPATH file file3")
+ endif()
+
+ if(NOT file2 STREQUAL "${bindir}/file3")
+ message(FATAL_ERROR "CMake fails resolving simple symlink")
+ endif()
+
+ if(NOT file1 STREQUAL "${bindir}/file3")
+ message(FATAL_ERROR "CMake fails resolving double symlink")
+ endif()
+
+ # cleanup
+ file(REMOVE ${bindir}/file1)
+ file(REMOVE ${bindir}/file2)
+ if(EXISTS file1 OR EXISTS file2)
+ message(FATAL_ERROR "removal of file1 or file2 failed")
+ endif()
+ endif(LN)
+
+ file(REMOVE ${bindir}/file3)
+endif()
diff --git a/Tests/CMakeTests/GetPrerequisitesTest.cmake.in b/Tests/CMakeTests/GetPrerequisitesTest.cmake.in
new file mode 100644
index 000000000..daf467bcc
--- /dev/null
+++ b/Tests/CMakeTests/GetPrerequisitesTest.cmake.in
@@ -0,0 +1,159 @@
+# Test of the functions in the CMake Modules file:
+#
+include(GetPrerequisites)
+
+set(CMAKE_BUILD_TYPE "@CMAKE_BUILD_TYPE@")
+set(CMAKE_CONFIGURATION_TYPES "@CMAKE_CONFIGURATION_TYPES@")
+set(CMAKE_EXECUTABLE_SUFFIX "@CMAKE_EXECUTABLE_SUFFIX@")
+
+
+message(STATUS "=============================================================================")
+message(STATUS "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)")
+message(STATUS "")
+message(STATUS "CMAKE_BUILD_TYPE='${CMAKE_BUILD_TYPE}'")
+message(STATUS "CMAKE_CONFIGURATION_TYPES='${CMAKE_CONFIGURATION_TYPES}'")
+message(STATUS "CMAKE_EXECUTABLE_SUFFIX='${CMAKE_EXECUTABLE_SUFFIX}'")
+message(STATUS "CTEST_CONFIGURATION_TYPE='${CTEST_CONFIGURATION_TYPE}'")
+message(STATUS "")
+
+
+function(stresstest_list_prerequisites file)
+ message(STATUS "=============================================================================")
+ message(STATUS "stresstest_list_prerequisites file='${file}'")
+ message(STATUS "")
+
+ get_filename_component(file_full "${file}" ABSOLUTE)
+
+ message(STATUS "list_prerequisites '${file_full}' 0 0 0")
+ list_prerequisites("${file_full}" 0 0 0)
+ message(STATUS "")
+
+ message(STATUS "list_prerequisites '${file_full}' 0 0 1")
+ list_prerequisites("${file_full}" 0 0 1)
+ message(STATUS "")
+
+ message(STATUS "list_prerequisites '${file_full}' 0 1 0")
+ list_prerequisites("${file_full}" 0 1 0)
+ message(STATUS "")
+
+ message(STATUS "list_prerequisites '${file_full}' 0 1 1")
+ list_prerequisites("${file_full}" 0 1 1)
+ message(STATUS "")
+
+ message(STATUS "list_prerequisites '${file_full}' 1 0 0")
+ list_prerequisites("${file_full}" 1 0 0)
+ message(STATUS "")
+
+ message(STATUS "list_prerequisites '${file_full}' 1 0 1")
+ list_prerequisites("${file_full}" 1 0 1)
+ message(STATUS "")
+
+ message(STATUS "list_prerequisites '${file_full}' 1 1 0")
+ list_prerequisites("${file_full}" 1 1 0)
+ message(STATUS "")
+
+ message(STATUS "list_prerequisites '${file_full}' 1 1 1")
+ list_prerequisites("${file_full}" 1 1 1)
+ message(STATUS "")
+
+ message(STATUS "=============================================================================")
+ message(STATUS "")
+endfunction(stresstest_list_prerequisites)
+
+
+function(test_cmake_executables)
+ message(STATUS "=============================================================================")
+ message(STATUS "Loop over all executable files in the same directory with CMake")
+ message(STATUS "")
+
+ get_filename_component(cmake_bin_dir "${CMAKE_COMMAND}" PATH)
+ list_prerequisites_by_glob(GLOB "${cmake_bin_dir}/*" 0 0 1)
+endfunction(test_cmake_executables)
+
+
+message(STATUS "=============================================================================")
+message(STATUS "Simplest test - list all the direct prerequisites of CMake itself")
+message(STATUS "")
+list_prerequisites("${CMAKE_COMMAND}" 0 0 1)
+message(STATUS "")
+
+message(STATUS "=============================================================================")
+string(LENGTH "$ENV{PATH}" PATH_LENGTH_BEGIN)
+message(STATUS "Begin PATH length is: ${PATH_LENGTH_BEGIN}")
+message(STATUS "")
+
+
+# Leave the code for these tests in here, but turn them off by default... they
+# take longer than they're worth during development...
+#
+set(do_testdefaults 0)
+if(do_testdefaults)
+ message(STATUS "=============================================================================")
+ message(STATUS "Test default argument values to list_prerequisites function...")
+ message(STATUS "")
+ list_prerequisites("${CMAKE_COMMAND}")
+ message(STATUS "")
+endif(do_testdefaults)
+
+
+set(do_stresstest 0)
+if(do_stresstest)
+ message(STATUS "=============================================================================")
+ message(STATUS "stresstest_list_prerequisites with CMake itself...")
+ message(STATUS "")
+ stresstest_list_prerequisites("${CMAKE_COMMAND}")
+ message(STATUS "")
+endif(do_stresstest)
+
+
+test_cmake_executables()
+
+
+message(STATUS "=============================================================================")
+message(STATUS "Test overriding 'gp_tool' with bogus value")
+message(STATUS "")
+set(gp_tool "bogus")
+list_prerequisites("${CMAKE_COMMAND}" 0 0 0)
+set(gp_tool)
+message(STATUS "")
+
+
+message(STATUS "=============================================================================")
+message(STATUS "Test overriding 'gp_tool' with value unlikely to be found")
+message(STATUS "")
+if(APPLE)
+ set(gp_tool "dumpbin")
+else()
+ set(gp_tool "otool")
+endif()
+set(gp_cmd "gp_cmd-NOTFOUND")
+list_prerequisites("${CMAKE_COMMAND}" 0 0 0)
+set(gp_cmd)
+set(gp_tool)
+message(STATUS "")
+
+
+message(STATUS "=============================================================================")
+message(STATUS "All variables: (Make sure functions/macros are not leaving stuff around...")
+message(STATUS " Only variables predefined by CMake and defined in this")
+message(STATUS " test script file should be listed here...)")
+message(STATUS "")
+get_cmake_property(vs VARIABLES)
+foreach(v ${vs})
+ message(STATUS "${v}='${${v}}'")
+endforeach(v)
+message(STATUS "")
+
+message(STATUS "=============================================================================")
+string(LENGTH "$ENV{PATH}" PATH_LENGTH_END)
+message(STATUS "Final PATH length is: ${PATH_LENGTH_END}")
+
+if(PATH_LENGTH_END GREATER ${PATH_LENGTH_BEGIN})
+ message(FATAL_ERROR "list_prerequisties is endlessly appending the path of gp_tool to the PATH.")
+endif()
+message(STATUS "")
+
+
+message(STATUS "=============================================================================")
+message(STATUS "End of test")
+message(STATUS "")
diff --git a/Tests/CMakeTests/GetProperty-Bad-Argument.cmake b/Tests/CMakeTests/GetProperty-Bad-Argument.cmake
new file mode 100644
index 000000000..382dabb50
--- /dev/null
+++ b/Tests/CMakeTests/GetProperty-Bad-Argument.cmake
@@ -0,0 +1 @@
+get_property(FOO GLOBAL PROPERTY FOO FOO)
diff --git a/Tests/CMakeTests/GetProperty-Bad-Directory.cmake b/Tests/CMakeTests/GetProperty-Bad-Directory.cmake
new file mode 100644
index 000000000..cdbfa807c
--- /dev/null
+++ b/Tests/CMakeTests/GetProperty-Bad-Directory.cmake
@@ -0,0 +1 @@
+get_property(FOO DIRECTORY NonExistentSubDir PROPERTY FOO)
diff --git a/Tests/CMakeTests/GetProperty-Bad-Scope.cmake b/Tests/CMakeTests/GetProperty-Bad-Scope.cmake
new file mode 100644
index 000000000..ea8566b50
--- /dev/null
+++ b/Tests/CMakeTests/GetProperty-Bad-Scope.cmake
@@ -0,0 +1 @@
+get_property(FOO FOO FOO)
diff --git a/Tests/CMakeTests/GetProperty-Bad-Target.cmake b/Tests/CMakeTests/GetProperty-Bad-Target.cmake
new file mode 100644
index 000000000..9992dabed
--- /dev/null
+++ b/Tests/CMakeTests/GetProperty-Bad-Target.cmake
@@ -0,0 +1 @@
+get_property(FOO TARGET FOO PROPERTY FOO)
diff --git a/Tests/CMakeTests/GetProperty-Bad-Test.cmake b/Tests/CMakeTests/GetProperty-Bad-Test.cmake
new file mode 100644
index 000000000..44bf3ebc5
--- /dev/null
+++ b/Tests/CMakeTests/GetProperty-Bad-Test.cmake
@@ -0,0 +1 @@
+get_property(FOO TEST FOO PROPERTY FOO)
diff --git a/Tests/CMakeTests/GetProperty-Doc-Properties.cmake b/Tests/CMakeTests/GetProperty-Doc-Properties.cmake
new file mode 100644
index 000000000..6c2c3620e
--- /dev/null
+++ b/Tests/CMakeTests/GetProperty-Doc-Properties.cmake
@@ -0,0 +1,10 @@
+get_property(FOO_BRIEF GLOBAL PROPERTY FOO BRIEF_DOCS)
+get_property(FOO_FULL GLOBAL PROPERTY FOO FULL_DOCS)
+
+if (NOT FOO_BRIEF STREQUAL "NOTFOUND")
+ message(SEND_ERROR "property FOO has BRIEF_DOCS set to '${FOO_BRIEF}'")
+endif ()
+
+if (NOT FOO_FULL STREQUAL "NOTFOUND")
+ message(SEND_ERROR "property FOO has FULL_DOCS set to '${FOO_FULL}'")
+endif ()
diff --git a/Tests/CMakeTests/GetProperty-Global-Name.cmake b/Tests/CMakeTests/GetProperty-Global-Name.cmake
new file mode 100644
index 000000000..497700cb3
--- /dev/null
+++ b/Tests/CMakeTests/GetProperty-Global-Name.cmake
@@ -0,0 +1 @@
+get_property(FOO GLOBAL FOO PROPERTY FOO)
diff --git a/Tests/CMakeTests/GetProperty-Missing-Argument.cmake b/Tests/CMakeTests/GetProperty-Missing-Argument.cmake
new file mode 100644
index 000000000..f0d004dc4
--- /dev/null
+++ b/Tests/CMakeTests/GetProperty-Missing-Argument.cmake
@@ -0,0 +1 @@
+get_property()
diff --git a/Tests/CMakeTests/GetProperty-No-Cache.cmake b/Tests/CMakeTests/GetProperty-No-Cache.cmake
new file mode 100644
index 000000000..9719fe775
--- /dev/null
+++ b/Tests/CMakeTests/GetProperty-No-Cache.cmake
@@ -0,0 +1 @@
+get_property(FOO CACHE PROPERTY FOO)
diff --git a/Tests/CMakeTests/GetProperty-No-Property.cmake b/Tests/CMakeTests/GetProperty-No-Property.cmake
new file mode 100644
index 000000000..bee230d9b
--- /dev/null
+++ b/Tests/CMakeTests/GetProperty-No-Property.cmake
@@ -0,0 +1 @@
+get_property(FOO GLOBAL PROPERTY)
diff --git a/Tests/CMakeTests/GetProperty-No-Source.cmake b/Tests/CMakeTests/GetProperty-No-Source.cmake
new file mode 100644
index 000000000..89773c810
--- /dev/null
+++ b/Tests/CMakeTests/GetProperty-No-Source.cmake
@@ -0,0 +1 @@
+get_property(FOO SOURCE PROPERTY FOO)
diff --git a/Tests/CMakeTests/GetProperty-No-Target.cmake b/Tests/CMakeTests/GetProperty-No-Target.cmake
new file mode 100644
index 000000000..8f1fa23af
--- /dev/null
+++ b/Tests/CMakeTests/GetProperty-No-Target.cmake
@@ -0,0 +1 @@
+get_property(FOO TARGET PROPERTY FOO)
diff --git a/Tests/CMakeTests/GetProperty-No-Test.cmake b/Tests/CMakeTests/GetProperty-No-Test.cmake
new file mode 100644
index 000000000..045bd56ec
--- /dev/null
+++ b/Tests/CMakeTests/GetProperty-No-Test.cmake
@@ -0,0 +1 @@
+get_property(FOO TEST PROPERTY FOO)
diff --git a/Tests/CMakeTests/GetProperty-Variable-Name.cmake b/Tests/CMakeTests/GetProperty-Variable-Name.cmake
new file mode 100644
index 000000000..9190f80ad
--- /dev/null
+++ b/Tests/CMakeTests/GetProperty-Variable-Name.cmake
@@ -0,0 +1 @@
+get_property(FOO VARIABLE FOO PROPERTY FOO)
diff --git a/Tests/CMakeTests/GetPropertyTest.cmake.in b/Tests/CMakeTests/GetPropertyTest.cmake.in
new file mode 100644
index 000000000..ab96e5b52
--- /dev/null
+++ b/Tests/CMakeTests/GetPropertyTest.cmake.in
@@ -0,0 +1,98 @@
+include("@CMAKE_CURRENT_SOURCE_DIR@/CheckCMakeTest.cmake")
+
+set(Missing-Argument-RESULT 1)
+set(Missing-Argument-STDERR ".*CMake Error at (@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 (@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 (@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 (@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(Doc-Properties-RESULT 0)
+
+check_cmake_test(GetProperty
+ Doc-Properties
+)
+
+set(Global-Name-RESULT 1)
+set(Global-Name-STDERR ".*CMake Error at (@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 (@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 (@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 (@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 (@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 (@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 (@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 (@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 (@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/If-Invalid-Argument.cmake b/Tests/CMakeTests/If-Invalid-Argument.cmake
new file mode 100644
index 000000000..b4fb97f41
--- /dev/null
+++ b/Tests/CMakeTests/If-Invalid-Argument.cmake
@@ -0,0 +1,2 @@
+if (NOT foo bar STREQUAL "foo bar")
+endif()
diff --git a/Tests/CMakeTests/IfTest.cmake.in b/Tests/CMakeTests/IfTest.cmake.in
new file mode 100644
index 000000000..639e22672
--- /dev/null
+++ b/Tests/CMakeTests/IfTest.cmake.in
@@ -0,0 +1,166 @@
+# Prepare variable definitions.
+set(VAR_UNDEFINED)
+set(VAR_PATH /some/path/to/a/file.txt)
+set(FALSE_NAMES OFF NO FALSE N FOO-NOTFOUND IGNORE Off No False Ignore off n no false ignore)
+set(TRUE_NAMES ON YES TRUE Y On Yes True on yes true y)
+foreach(_arg "" 0 1 2 ${TRUE_NAMES} ${FALSE_NAMES})
+ set(VAR_${_arg} "${_arg}")
+endforeach()
+
+macro(test_vars _old)
+ # Variables set to false or not set.
+ foreach(_var "" 0 ${FALSE_NAMES} UNDEFINED)
+ if(VAR_${_var})
+ message(FATAL_ERROR "${_old}if(VAR_${_var}) is true!")
+ else()
+ message(STATUS "${_old}if(VAR_${_var}) is false")
+ endif()
+
+ if(NOT VAR_${_var})
+ message(STATUS "${_old}if(NOT VAR_${_var}) is true")
+ else()
+ message(FATAL_ERROR "${_old}if(NOT VAR_${_var}) is false!")
+ endif()
+ endforeach()
+
+ # Variables set to true.
+ foreach(_var 1 2 ${TRUE_NAMES} PATH)
+ if(VAR_${_var})
+ message(STATUS "${_old}if(VAR_${_var}) is true")
+ else()
+ message(FATAL_ERROR "${_old}if(VAR_${_var}) is false!")
+ endif()
+
+ if(NOT VAR_${_var})
+ message(FATAL_ERROR "${_old}if(NOT VAR_${_var}) is true!")
+ else()
+ message(STATUS "${_old}if(NOT VAR_${_var}) is false")
+ endif()
+ endforeach()
+endmacro()
+
+#-----------------------------------------------------------------------------
+# Test the OLD behavior of CMP0012.
+cmake_policy(SET CMP0012 OLD)
+
+# False constants not recognized (still false).
+foreach(_false "" ${FALSE_NAMES})
+ if("${_false}")
+ message(FATAL_ERROR "OLD if(${_false}) is true!")
+ else()
+ message(STATUS "OLD if(${_false}) is false")
+ endif()
+
+ if(NOT "${_false}")
+ message(STATUS "OLD if(NOT ${_false}) is true")
+ else()
+ message(FATAL_ERROR "OLD if(NOT ${_false}) is false!")
+ endif()
+endforeach()
+
+# True constants not recognized.
+foreach(_false ${TRUE_NAMES})
+ if(${_false})
+ message(FATAL_ERROR "OLD if(${_false}) is true!")
+ else()
+ message(STATUS "OLD if(${_false}) is false")
+ endif()
+
+ if(NOT ${_false})
+ message(STATUS "OLD if(NOT ${_false}) is true")
+ else()
+ message(FATAL_ERROR "OLD if(NOT ${_false}) is false!")
+ endif()
+endforeach()
+
+# Numbers not recognized properly.
+foreach(_num 2 -2 2.0 -2.0 2x -2x)
+ if(${_num})
+ message(FATAL_ERROR "OLD if(${_num}) is true!")
+ else()
+ message(STATUS "OLD if(${_num}) is false")
+ endif()
+
+ if(NOT ${_num})
+ message(FATAL_ERROR "OLD if(NOT ${_num}) is true!")
+ else()
+ message(STATUS "OLD if(NOT ${_num}) is false")
+ endif()
+endforeach()
+
+test_vars("OLD ")
+
+#-----------------------------------------------------------------------------
+
+# Test the NEW behavior of CMP0012.
+cmake_policy(SET CMP0012 NEW)
+
+# Test false constants.
+foreach(_false "" 0 ${FALSE_NAMES})
+ if("${_false}")
+ message(FATAL_ERROR "if(${_false}) is true!")
+ else()
+ message(STATUS "if(${_false}) is false")
+ endif()
+
+ if(NOT "${_false}")
+ message(STATUS "if(NOT ${_false}) is true")
+ else()
+ message(FATAL_ERROR "if(NOT ${_false}) is false!")
+ endif()
+endforeach()
+
+# Test true constants.
+foreach(_true 1 ${TRUE_NAMES})
+ if(${_true})
+ message(STATUS "if(${_true}) is true")
+ else()
+ message(FATAL_ERROR "if(${_true}) is false!")
+ endif()
+
+ if(NOT ${_true})
+ message(FATAL_ERROR "if(NOT ${_true}) is true!")
+ else()
+ message(STATUS "if(NOT ${_true}) is false")
+ endif()
+endforeach()
+
+# Numbers recognized properly.
+foreach(_num 2 -2 2.0 -2.0)
+ if(${_num})
+ message(STATUS "if(${_num}) is true")
+ else()
+ message(FATAL_ERROR "if(${_num}) is false!")
+ endif()
+
+ if(NOT ${_num})
+ message(FATAL_ERROR "if(NOT ${_num}) is true!")
+ else()
+ message(STATUS "if(NOT ${_num}) is false")
+ endif()
+endforeach()
+
+# Bad numbers not recognized.
+foreach(_bad 2x -2x)
+ if(${_bad})
+ message(FATAL_ERROR "if(${_bad}) is true!")
+ else()
+ message(STATUS "if(${_bad}) is false")
+ endif()
+
+ if(NOT ${_bad})
+ message(STATUS "if(NOT ${_bad}) is true")
+ else()
+ message(FATAL_ERROR "if(NOT ${_bad}) is false!")
+ endif()
+endforeach()
+
+test_vars("")
+
+set(Invalid-Argument-RESULT 1)
+set(Invalid-Argument-STDERR ".*CMake Error at (@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
new file mode 100644
index 000000000..dbe95005e
--- /dev/null
+++ b/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in
@@ -0,0 +1,420 @@
+# This is not supposed to be included by user code, but we need to
+# test it.
+include(${CMAKE_ROOT}/Modules/CMakeParseImplicitLinkInfo.cmake)
+
+#-----------------------------------------------------------------------------
+# Linux
+
+# gcc dummy.c -v
+set(linux64_gcc_text " /usr/lib/gcc/x86_64-linux-gnu/4.3.3/collect2 --eh-frame-hdr -m elf_x86_64 --hash-style=both -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/gcc/x86_64-linux-gnu/4.3.3/../../../../lib/crt1.o /usr/lib/gcc/x86_64-linux-gnu/4.3.3/../../../../lib/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.3.3/crtbegin.o -L/usr/lib/gcc/x86_64-linux-gnu/4.3.3 -L/usr/lib/gcc/x86_64-linux-gnu/4.3.3 -L/usr/lib/gcc/x86_64-linux-gnu/4.3.3/../../../../lib -L/lib/../lib -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/4.3.3/../../.. -L/usr/lib/x86_64-linux-gnu /tmp/ccEO9iux.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-linux-gnu/4.3.3/crtend.o /usr/lib/gcc/x86_64-linux-gnu/4.3.3/../../../../lib/crtn.o")
+set(linux64_gcc_libs "c")
+set(linux64_gcc_dirs "/usr/lib/gcc/x86_64-linux-gnu/4.3.3;/usr/lib;/lib;/usr/lib/x86_64-linux-gnu")
+list(APPEND platforms linux64_gcc)
+
+# g++ dummy.cxx -v
+set(linux64_g++_text " /usr/lib/gcc/x86_64-linux-gnu/4.3.3/collect2 --eh-frame-hdr -m elf_x86_64 --hash-style=both -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/gcc/x86_64-linux-gnu/4.3.3/../../../../lib/crt1.o /usr/lib/gcc/x86_64-linux-gnu/4.3.3/../../../../lib/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.3.3/crtbegin.o -L/usr/lib/gcc/x86_64-linux-gnu/4.3.3 -L/usr/lib/gcc/x86_64-linux-gnu/4.3.3 -L/usr/lib/gcc/x86_64-linux-gnu/4.3.3/../../../../lib -L/lib/../lib -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/4.3.3/../../.. -L/usr/lib/x86_64-linux-gnu /tmp/ccalRBlq.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/4.3.3/crtend.o /usr/lib/gcc/x86_64-linux-gnu/4.3.3/../../../../lib/crtn.o")
+set(linux64_g++_libs "stdc++;m;c")
+set(linux64_g++_dirs "/usr/lib/gcc/x86_64-linux-gnu/4.3.3;/usr/lib;/lib;/usr/lib/x86_64-linux-gnu")
+list(APPEND platforms linux64_g++)
+
+# f95 dummy.f -v
+set(linux64_f95_text " /usr/lib/gcc/x86_64-linux-gnu/4.3.3/collect2 --eh-frame-hdr -m elf_x86_64 --hash-style=both -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/gcc/x86_64-linux-gnu/4.3.3/../../../../lib/crt1.o /usr/lib/gcc/x86_64-linux-gnu/4.3.3/../../../../lib/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.3.3/crtbegin.o -L/usr/lib/gcc/x86_64-linux-gnu/4.3.3 -L/usr/lib/gcc/x86_64-linux-gnu/4.3.3 -L/usr/lib/gcc/x86_64-linux-gnu/4.3.3/../../../../lib -L/lib/../lib -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/4.3.3/../../.. -L/usr/lib/x86_64-linux-gnu /tmp/ccAVcN7N.o -lgfortranbegin -lgfortran -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/4.3.3/crtend.o /usr/lib/gcc/x86_64-linux-gnu/4.3.3/../../../../lib/crtn.o")
+set(linux64_f95_libs "gfortranbegin;gfortran;m;c")
+set(linux64_f95_dirs "/usr/lib/gcc/x86_64-linux-gnu/4.3.3;/usr/lib;/lib;/usr/lib/x86_64-linux-gnu")
+list(APPEND platforms linux64_f95)
+
+# suncc dummy.c '-#'
+set(linux64_suncc_text "/usr/bin/ld --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 /opt/sun/sunstudio12/prod/lib/amd64/crti.o /opt/sun/sunstudio12/prod/lib/amd64/crt1x.o /opt/sun/sunstudio12/prod/lib/amd64/values-xa.o dummy.o -Y \"/opt/sun/sunstudio12/prod/lib/amd64:/lib64:/usr/lib64\" -Qy -lc /opt/sun/sunstudio12/prod/lib/amd64/libc_supp.a /opt/sun/sunstudio12/prod/lib/amd64/crtn.o")
+set(linux64_suncc_libs "c;/opt/sun/sunstudio12/prod/lib/amd64/libc_supp.a")
+set(linux64_suncc_dirs "/opt/sun/sunstudio12/prod/lib/amd64;/lib64;/usr/lib64")
+list(APPEND platforms linux64_suncc)
+
+# sunCC dummy.cxx -v
+set(linux64_sunCC_text "/opt/sun/sunstudio12/prod/lib/amd64/ld -u __1cH__CimplKcplus_init6F_v_ --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -R/opt/sun/sunstudio12/lib/rw7/amd64:/opt/sun/sunstudio12/lib/amd64:/opt/sun/sunstudio12/rtlibs/amd64:/opt/sun/lib/rtlibs/amd64:/opt/SUNWspro/lib/amd64:/lib64:/usr/lib64 -o a.out /opt/sun/sunstudio12/prod/lib/amd64/crti.o /opt/sun/sunstudio12/prod/lib/amd64/CCrti.o /opt/sun/sunstudio12/prod/lib/amd64/crt1x.o -Y P,/opt/sun/sunstudio12/lib/rw7/amd64:/opt/sun/sunstudio12/lib/amd64:/opt/sun/sunstudio12/rtlibs/amd64:/opt/sun/sunstudio12/prod/lib/rw7/amd64:/opt/sun/sunstudio12/prod/lib/amd64:/lib64:/usr/lib64 dummy.o -lCstd -lCrun -lm -lc /opt/sun/sunstudio12/prod/lib/amd64/libc_supp.a /opt/sun/sunstudio12/prod/lib/amd64/CCrtn.o /opt/sun/sunstudio12/prod/lib/amd64/crtn.o >&/tmp/ld.04973.2.err")
+set(linux64_sunCC_libs "Cstd;Crun;m;c;/opt/sun/sunstudio12/prod/lib/amd64/libc_supp.a")
+set(linux64_sunCC_dirs "/opt/sun/sunstudio12/lib/rw7/amd64;/opt/sun/sunstudio12/lib/amd64;/opt/sun/sunstudio12/rtlibs/amd64;/opt/sun/sunstudio12/prod/lib/rw7/amd64;/opt/sun/sunstudio12/prod/lib/amd64;/lib64;/usr/lib64")
+list(APPEND platforms linux64_sunCC)
+
+# sunf90 dummy.f -v
+set(linux64_sunf90_text "/usr/bin/ld --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -R/opt/sun/sunstudio12/lib/amd64:/opt/sun/sunstudio12/rtlibs/amd64:/opt/sun/lib/rtlibs/amd64 -o a.out /opt/sun/sunstudio12/prod/lib/amd64/crti.o /opt/sun/sunstudio12/prod/lib/amd64/crt1x.o /opt/sun/sunstudio12/prod/lib/amd64/values-xi.o -Y P,/opt/sun/sunstudio12/lib/amd64:/opt/sun/sunstudio12/rtlibs/amd64:/opt/sun/sunstudio12/prod/lib/amd64:/lib64:/usr/lib64 dummy.o -lfui -lfai -lfsu -Bdynamic -lmtsk -lpthread -lm -lc /opt/sun/sunstudio12/prod/lib/amd64/libc_supp.a /opt/sun/sunstudio12/prod/lib/amd64/crtn.o")
+set(linux64_sunf90_libs "fui;fai;fsu;mtsk;pthread;m;c;/opt/sun/sunstudio12/prod/lib/amd64/libc_supp.a")
+set(linux64_sunf90_dirs "/opt/sun/sunstudio12/lib/amd64;/opt/sun/sunstudio12/rtlibs/amd64;/opt/sun/sunstudio12/prod/lib/amd64;/lib64;/usr/lib64")
+list(APPEND platforms linux64_sunf90)
+
+# icc dummy.c -v
+set(linux64_icc_text "ld /usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../lib64/crt1.o /usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../lib64/crti.o /usr/lib64/gcc/x86_64-suse-linux/4.1.2/crtbegin.o --eh-frame-hdr -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o a.out /tmp/iccBP8OfN.o -L/opt/compiler/intel/compiler/11.0/lib/intel64 -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2 -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../x86_64-suse-linux/lib -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../.. -L/lib64 -L/lib -L/usr/lib64 -L/usr/lib -Bstatic -limf -lsvml -Bdynamic -lm -Bstatic -lipgo -ldecimal -lirc -Bdynamic -lgcc_s -lgcc -Bstatic -lirc -Bdynamic -lc -lgcc_s -lgcc -Bstatic -lirc_s -Bdynamic -ldl -lc /usr/lib64/gcc/x86_64-suse-linux/4.1.2/crtend.o /usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../lib64/crtn.o")
+set(linux64_icc_libs "imf;svml;m;ipgo;decimal;irc;irc;c;irc_s;dl;c")
+set(linux64_icc_dirs "/opt/compiler/intel/compiler/11.0/lib/intel64;/usr/lib64/gcc/x86_64-suse-linux/4.1.2;/usr/lib64;/lib64;/usr/x86_64-suse-linux/lib;/lib;/usr/lib")
+list(APPEND platforms linux64_icc)
+
+# icxx dummy.cxx -v
+set(linux64_icxx_text "ld /usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../lib64/crt1.o /usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../lib64/crti.o /usr/lib64/gcc/x86_64-suse-linux/4.1.2/crtbegin.o --eh-frame-hdr -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o a.out /tmp/icpc270GoT.o -L/opt/compiler/intel/compiler/11.0/lib/intel64 -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2 -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../x86_64-suse-linux/lib -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../.. -L/lib64 -L/lib -L/usr/lib64 -L/usr/lib -Bstatic -limf -lsvml -Bdynamic -lm -Bstatic -lipgo -ldecimal -Bdynamic -lstdc++ -Bstatic -lirc -Bdynamic -lgcc_s -lgcc -Bstatic -lirc -Bdynamic -lc -lgcc_s -lgcc -Bstatic -lirc_s -Bdynamic -ldl -lc /usr/lib64/gcc/x86_64-suse-linux/4.1.2/crtend.o /usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../lib64/crtn.o")
+set(linux64_icxx_libs "imf;svml;m;ipgo;decimal;stdc++;irc;irc;c;irc_s;dl;c")
+set(linux64_icxx_dirs "/opt/compiler/intel/compiler/11.0/lib/intel64;/usr/lib64/gcc/x86_64-suse-linux/4.1.2;/usr/lib64;/lib64;/usr/x86_64-suse-linux/lib;/lib;/usr/lib")
+list(APPEND platforms linux64_icxx)
+
+# ifort dummy.f -v
+set(linux64_ifort_text "ld --eh-frame-hdr -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o a.out -L/opt/compiler/intel/compiler/11.0/lib/intel64 -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2 -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../x86_64-suse-linux/lib -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../.. -L/lib64 -L/lib -L/usr/lib64 -L/usr/lib /usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../lib64/crt1.o /usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../lib64/crti.o /usr/lib64/gcc/x86_64-suse-linux/4.1.2/crtbegin.o /opt/compiler/intel/compiler/11.0/lib/intel64/for_main.o dum.cxx -Bstatic -lifport -lifcore -limf -lsvml -Bdynamic -lm -Bstatic -lipgo -lirc -Bdynamic -lpthread -lc -lgcc_s -lgcc -Bstatic -lirc_s -Bdynamic -ldl -lc /usr/lib64/gcc/x86_64-suse-linux/4.1.2/crtend.o /usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../lib64/crtn.o")
+set(linux64_ifort_libs "ifport;ifcore;imf;svml;m;ipgo;irc;pthread;c;irc_s;dl;c")
+set(linux64_ifort_dirs "/opt/compiler/intel/compiler/11.0/lib/intel64;/usr/lib64/gcc/x86_64-suse-linux/4.1.2;/usr/lib64;/lib64;/usr/x86_64-suse-linux/lib;/lib;/usr/lib")
+list(APPEND platforms linux64_ifort)
+
+# pgcc dummy.c -v
+set(linux64_pgcc_text "/usr/bin/ld /usr/lib64/crt1.o /usr/lib64/crti.o /opt/compiler/pgi/linux86-64/8.0-3/lib/trace_init.o /usr/lib64/gcc/x86_64-suse-linux/4.1.2/crtbegin.o -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 /opt/compiler/pgi/linux86-64/8.0-3/lib/pgi.ld -L/opt/compiler/pgi/linux86-64/8.0-3/lib -L/usr/lib64 -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2 /tmp/pgcc7OscXa5ur7Zk.o -rpath /opt/compiler/pgi/linux86-64/8.0-3/lib -lnspgc -lpgc -lm -lgcc -lc -lgcc /usr/lib64/gcc/x86_64-suse-linux/4.1.2/crtend.o /usr/lib64/crtn.o")
+set(linux64_pgcc_libs "nspgc;pgc;m;c")
+set(linux64_pgcc_dirs "/opt/compiler/pgi/linux86-64/8.0-3/lib;/usr/lib64;/usr/lib64/gcc/x86_64-suse-linux/4.1.2")
+list(APPEND platforms linux64_pgcc)
+
+# pgCC dummy.cxx -v
+set(linux64_pgCC_text "/usr/bin/ld /usr/lib64/crt1.o /usr/lib64/crti.o /opt/compiler/pgi/linux86-64/8.0-3/lib/trace_init.o /usr/lib64/gcc/x86_64-suse-linux/4.1.2/crtbegin.o -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 /opt/compiler/pgi/linux86-64/8.0-3/lib/pgi.ld -L/opt/compiler/pgi/linux86-64/8.0-3/lib -L/usr/lib64 -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2 /tmp/pgCCFhjcDt1fs1Ki.o -rpath /opt/compiler/pgi/linux86-64/8.0-3/lib -lstd -lC -lnspgc -lpgc -lm -lgcc -lc -lgcc /usr/lib64/gcc/x86_64-suse-linux/4.1.2/crtend.o /usr/lib64/crtn.o")
+set(linux64_pgCC_libs "std;C;nspgc;pgc;m;c")
+set(linux64_pgCC_dirs "/opt/compiler/pgi/linux86-64/8.0-3/lib;/usr/lib64;/usr/lib64/gcc/x86_64-suse-linux/4.1.2")
+list(APPEND platforms linux64_pgCC)
+
+# pgf90 dummy.f -v
+set(linux64_pgf90_text "/usr/bin/ld /usr/lib64/crt1.o /usr/lib64/crti.o /opt/compiler/pgi/linux86-64/8.0-3/lib/trace_init.o /usr/lib64/gcc/x86_64-suse-linux/4.1.2/crtbegin.o /opt/compiler/pgi/linux86-64/8.0-3/lib/f90main.o -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 /opt/compiler/pgi/linux86-64/8.0-3/lib/pgi.ld -L/opt/compiler/pgi/linux86-64/8.0-3/lib -L/usr/lib64 -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2 /tmp/pgf90QOIc_eB9xY5h.o -rpath /opt/compiler/pgi/linux86-64/8.0-3/lib -lpgf90 -lpgf90_rpm1 -lpgf902 -lpgf90rtl -lpgftnrtl -lnspgc -lpgc -lrt -lpthread -lm -lgcc -lc -lgcc /usr/lib64/gcc/x86_64-suse-linux/4.1.2/crtend.o /usr/lib64/crtn.o")
+set(linux64_pgf90_libs "pgf90;pgf90_rpm1;pgf902;pgf90rtl;pgftnrtl;nspgc;pgc;rt;pthread;m;c")
+set(linux64_pgf90_dirs "/opt/compiler/pgi/linux86-64/8.0-3/lib;/usr/lib64;/usr/lib64/gcc/x86_64-suse-linux/4.1.2")
+list(APPEND platforms linux64_pgf90)
+
+# nagfor dummy.f -Wl,-v
+set(linux64_nagfor_text " /usr/libexec/gcc/x86_64-redhat-linux/4.4.5/collect2 --no-add-needed --eh-frame-hdr --build-id -m elf_x86_64 --hash-style=gnu -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o a.out /usr/lib/gcc/x86_64-redhat-linux/4.4.5/../../../../lib64/crt1.o /usr/lib/gcc/x86_64-redhat-linux/4.4.5/../../../../lib64/crti.o /usr/lib/gcc/x86_64-redhat-linux/4.4.5/crtbegin.o -L/usr/lib/gcc/x86_64-redhat-linux/4.4.5 -L/usr/lib/gcc/x86_64-redhat-linux/4.4.5 -L/usr/lib/gcc/x86_64-redhat-linux/4.4.5/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/4.4.5/../../.. /usr/local/NAG/lib/f90_init.o /usr/local/NAG/lib/quickfit.o dummy.o -rpath /usr/local/NAG/lib /usr/local/NAG/lib/libf53.so /usr/local/NAG/lib/libf53.a -lm -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-redhat-linux/4.4.5/crtend.o /usr/lib/gcc/x86_64-redhat-linux/4.4.5/../../../../lib64/crtn.o")
+set(linux64_nagfor_libs "/usr/local/NAG/lib/f90_init.o;/usr/local/NAG/lib/quickfit.o;/usr/local/NAG/lib/libf53.a;m;c")
+set(linux64_nagfor_dirs "/usr/lib/gcc/x86_64-redhat-linux/4.4.5;/usr/lib64;/lib64;/usr/lib")
+set(linux64_nagfor_obj_regex "^/usr/local/NAG/lib")
+list(APPEND platforms linux64_nagfor)
+
+# absoft dummy.f -X -v
+set(linux64_absoft_text "collect2 version 4.4.5 (x86-64 Linux/ELF)
+/usr/bin/ld --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=both -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib/crt1.o /usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.4.5/crtbegin.o -L/opt/absoft11.1/lib64 -L/usr/lib/gcc/x86_64-linux-gnu/4.4.5 -L/usr/lib/gcc/x86_64-linux-gnu/4.4.5 -L/usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib -L/lib/../lib -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../.. /tmp/E3Bii1/dummy.o -v -laf90math -lafio -lamisc -labsoftmain -laf77math -lm -lmv -lpthread -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-linux-gnu/4.4.5/crtend.o /usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib/crtn.o")
+set(linux64_absoft_libs "af90math;afio;amisc;absoftmain;af77math;m;mv;pthread;c")
+set(linux64_absoft_dirs "/opt/absoft11.1/lib64;/usr/lib/gcc/x86_64-linux-gnu/4.4.5;/usr/lib;/lib")
+list(APPEND platforms linux64_absoft)
+
+# gcc dummy.c -v # in strange path
+set(linux64_test1_text "
+/this/might/match/as/a/linker/ld/but/it/is/not because the ld is not the last path component
+${linux64_gcc_text}")
+set(linux64_test1_libs "${linux64_gcc_libs}")
+set(linux64_test1_dirs "${linux64_gcc_dirs}")
+list(APPEND platforms linux64_test1)
+
+#-----------------------------------------------------------------------------
+# Mac
+
+# gcc -arch i686 dummy.c -v
+set(mac_i686_gcc_text " /usr/libexec/gcc/i686-apple-darwin10/4.2.1/collect2 -dynamic -arch i386 -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.6.o -L/usr/lib/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../../i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../.. /var/tmp//ccnhXAGL.o -lSystem -lgcc -lSystem")
+set(mac_i686_gcc_libs "")
+set(mac_i686_gcc_dirs "/usr/lib/i686-apple-darwin10/4.2.1;/usr/lib/gcc/i686-apple-darwin10/4.2.1;/usr/lib")
+list(APPEND platforms mac_i686_gcc)
+
+# g++ -arch i686 dummy.cxx -v
+set(mac_i686_g++_text " /usr/libexec/gcc/i686-apple-darwin10/4.2.1/collect2 -dynamic -arch i386 -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.6.o -L/usr/lib/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../../i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../.. /var/tmp//ccEXXICh.o -lstdc++ -lSystem -lgcc -lSystem")
+set(mac_i686_g++_libs "stdc++")
+set(mac_i686_g++_dirs "/usr/lib/i686-apple-darwin10/4.2.1;/usr/lib/gcc/i686-apple-darwin10/4.2.1;/usr/lib")
+list(APPEND platforms mac_i686_g++)
+
+# gfortran dummy.f -v
+set(mac_i686_gfortran_text " /usr/libexec/gcc/i386-apple-darwin9.7.0/4.4.1/collect2 -dynamic -arch i386 -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.5.o -L/usr/lib/gcc/i386-apple-darwin9.7.0/4.4.1 -L/usr/lib/gcc -L/usr/lib/gcc/i386-apple-darwin9.7.0/4.4.1/../../.. /var/tmp//ccgqbX5P.o -lgfortranbegin -lgfortran -lgcc_s.10.5 -lgcc -lSystem")
+set(mac_i686_gfortran_libs "gfortranbegin;gfortran")
+set(mac_i686_gfortran_dirs "/usr/lib/gcc/i386-apple-darwin9.7.0/4.4.1;/usr/lib/gcc;/usr/lib")
+list(APPEND platforms mac_i686_gfortran)
+
+# gcc -arch ppc dummy.c -v
+set(mac_ppc_gcc_text " /usr/libexec/gcc/powerpc-apple-darwin10/4.2.1/collect2 -dynamic -arch ppc -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.5.o -L/usr/lib/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1/../../../powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1/../../.. /var/tmp//ccdcolsP.o -lgcc -lSystemStubs -lSystem")
+set(mac_ppc_gcc_libs "")
+set(mac_ppc_gcc_dirs "/usr/lib/powerpc-apple-darwin10/4.2.1;/usr/lib/gcc/powerpc-apple-darwin10/4.2.1;/usr/lib")
+list(APPEND platforms mac_ppc_gcc)
+
+# g++ -arch ppc dummy.cxx -v
+set(mac_ppc_g++_text " /usr/libexec/gcc/powerpc-apple-darwin10/4.2.1/collect2 -dynamic -arch ppc -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.5.o -L/usr/lib/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1/../../../powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1/../../.. /var/tmp//ccbjB6Lj.o -lstdc++ -lgcc -lSystemStubs -lSystem")
+set(mac_ppc_g++_libs "stdc++")
+set(mac_ppc_g++_dirs "/usr/lib/powerpc-apple-darwin10/4.2.1;/usr/lib/gcc/powerpc-apple-darwin10/4.2.1;/usr/lib")
+list(APPEND platforms mac_ppc_g++)
+
+# absoft dummy.f -X -v
+set(mac_absoft_text "collect2 version 4.2.1 (Apple Inc. build 5664) (i686 Darwin)
+/usr/libexec/gcc/i686-apple-darwin10/4.2.1/ld -dynamic -arch i386 -macosx_version_min 10.6.6 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.6.o -L/Applications/Absoft11.1/lib -L/usr/lib/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../../i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../.. /var/folders/04/04+Djjm8GZWBmuEdp2Gsw++++TM/-Tmp-//bTAoJc/dummy.o -v -Y 10 -laf90math -lafio -lamisc -labsoftmain -laf77math -lm -lmv -lSystem -lgcc -lSystem
+")
+set(mac_absoft_libs "af90math;afio;amisc;absoftmain;af77math;m;mv")
+set(mac_absoft_dirs "/Applications/Absoft11.1/lib;/usr/lib/i686-apple-darwin10/4.2.1;/usr/lib/gcc/i686-apple-darwin10/4.2.1;/usr/lib")
+list(APPEND platforms mac_absoft)
+
+#-----------------------------------------------------------------------------
+# Sun
+
+# cc dummy.c '-#'/
+set(sun_cc_text "/usr/ccs/bin/ld /opt/SUNWspro/prod/lib/crti.o /opt/SUNWspro/prod/lib/crt1.o /opt/SUNWspro/prod/lib/misalign.o /opt/SUNWspro/prod/lib/values-xa.o dummy.o -Y \"P,/opt/SUNWspro/prod/lib/v8plus:/opt/SUNWspro/prod/lib:/usr/ccs/lib:/lib:/usr/lib\" -Qy -lc /opt/SUNWspro/prod/lib/crtn.o")
+set(sun_cc_libs "c")
+set(sun_cc_dirs "/opt/SUNWspro/prod/lib/v8plus;/opt/SUNWspro/prod/lib;/usr/ccs/lib;/lib;/usr/lib")
+list(APPEND platforms sun_cc)
+
+# CC dummy.cxx -v
+set(sun_CC_text "/usr/ccs/bin/ld -u __1cH__CimplKcplus_init6F_v_ -zld32=-S/opt/SUNWspro/prod/lib/libldstab_ws.so -zld64=-S/opt/SUNWspro/prod/lib/v9/libldstab_ws.so -zld32=-S/opt/SUNWspro/prod/lib/libCCexcept.so.1 -zld64=-S/opt/SUNWspro/prod/lib/v9/libCCexcept.so.1 -R/opt/SUNWspro/lib/rw7:/opt/SUNWspro/lib/v8plus:/opt/SUNWspro/lib:/usr/ccs/lib:/lib:/usr/lib -o a.out /opt/SUNWspro/prod/lib/crti.o /opt/SUNWspro/prod/lib/CCrti.o /opt/SUNWspro/prod/lib/crt1.o /opt/SUNWspro/prod/lib/misalign.o /opt/SUNWspro/prod/lib/values-xa.o -Y P,/opt/SUNWspro/lib/rw7:/opt/SUNWspro/lib/v8plus:/opt/SUNWspro/prod/lib/rw7:/opt/SUNWspro/prod/lib/v8plus:/opt/SUNWspro/lib:/opt/SUNWspro/prod/lib:/usr/ccs/lib:/lib:/usr/lib dummy.o -lCstd -lCrun -lm -lc /opt/SUNWspro/prod/lib/CCrtn.o /opt/SUNWspro/prod/lib/crtn.o >&/tmp/ld.14846.2.err")
+set(sun_CC_libs "Cstd;Crun;m;c")
+set(sun_CC_dirs "/opt/SUNWspro/lib/rw7;/opt/SUNWspro/lib/v8plus;/opt/SUNWspro/prod/lib/rw7;/opt/SUNWspro/prod/lib/v8plus;/opt/SUNWspro/lib;/opt/SUNWspro/prod/lib;/usr/ccs/lib;/lib;/usr/lib")
+list(APPEND platforms sun_CC)
+
+# f77 dummy.f -v
+set(sun_f77_text "/usr/ccs/bin/ld -t -R/opt/SUNWspro/lib/v8plus:/opt/SUNWspro/lib -o a.out /opt/SUNWspro/prod/lib/crti.o /opt/SUNWspro/prod/lib/crt1.o /opt/SUNWspro/prod/lib/misalign.o /opt/SUNWspro/prod/lib/values-xi.o -Y P,/opt/SUNWspro/lib/v8plus:/opt/SUNWspro/prod/lib/v8plus:/opt/SUNWspro/lib:/opt/SUNWspro/prod/lib:/usr/ccs/lib:/lib:/usr/lib dummy.o -lf77compat -zallextract -lompstubs -zdefaultextract -lfui -lfai -lfai2 -lfsumai -lfprodai -lfminlai -lfmaxlai -lfminvai -lfmaxvai -lfsu -lsunmath -lm -lc /opt/SUNWspro/prod/lib/crtn.o")
+set(sun_f77_libs "f77compat;-zallextract;ompstubs;-zdefaultextract;fui;fai;fai2;fsumai;fprodai;fminlai;fmaxlai;fminvai;fmaxvai;fsu;sunmath;m;c")
+set(sun_f77_dirs "/opt/SUNWspro/lib/v8plus;/opt/SUNWspro/prod/lib/v8plus;/opt/SUNWspro/lib;/opt/SUNWspro/prod/lib;/usr/ccs/lib;/lib;/usr/lib")
+list(APPEND platforms sun_f77)
+
+# f90 dummy.f -v
+set(sun_f90_text "/usr/ccs/bin/ld -t -R/opt/SUNWspro/lib/v8plus:/opt/SUNWspro/lib -o a.out /opt/SUNWspro/prod/lib/crti.o /opt/SUNWspro/prod/lib/crt1.o /opt/SUNWspro/prod/lib/misalign.o /opt/SUNWspro/prod/lib/values-xi.o -Y P,/opt/SUNWspro/lib/v8plus:/opt/SUNWspro/prod/lib/v8plus:/opt/SUNWspro/lib:/opt/SUNWspro/prod/lib:/usr/ccs/lib:/lib:/usr/lib dummy.o -zallextract -lompstubs -zdefaultextract -lfui -lfai -lfai2 -lfsumai -lfprodai -lfminlai -lfmaxlai -lfminvai -lfmaxvai -lfsu -lsunmath -lm -lc /opt/SUNWspro/prod/lib/crtn.o")
+set(sun_f90_libs "-zallextract;ompstubs;-zdefaultextract;fui;fai;fai2;fsumai;fprodai;fminlai;fmaxlai;fminvai;fmaxvai;fsu;sunmath;m;c")
+set(sun_f90_dirs "/opt/SUNWspro/lib/v8plus;/opt/SUNWspro/prod/lib/v8plus;/opt/SUNWspro/lib;/opt/SUNWspro/prod/lib;/usr/ccs/lib;/lib;/usr/lib")
+list(APPEND platforms sun_f90)
+
+#-----------------------------------------------------------------------------
+# AIX
+
+# xlc -q32 dummy.c -V
+set(aix_xlc_32_text "/bin/ld -b32 /lib/crt0.o -bpT:0x10000000 -bpD:0x20000000 dummy.o -L/usr/vac/lib -lxlopt -lxl -lc")
+set(aix_xlc_32_libs "xlopt;xl;c")
+set(aix_xlc_32_dirs "/usr/vac/lib")
+list(APPEND platforms aix_xlc_32)
+
+# xlc -q64 dummy.c -V
+set(aix_xlc_64_text "/bin/ld -b64 /lib/crt0_64.o -bpT:0x100000000 -bpD:0x110000000 dummy.o -L/usr/vac/lib -lxlopt -lxl -lc")
+set(aix_xlc_64_libs "xlopt;xl;c")
+set(aix_xlc_64_dirs "/usr/vac/lib")
+list(APPEND platforms aix_xlc_64)
+
+# xlC -q32 dummy.cxx -V
+set(aix_xlC_32_text "
+/bin/ld -b32 /lib/crt0.o -bpT:0x10000000 -bpD:0x20000000 dummy.o -L/usr/vac/lib -lxlopt -lxl -L/usr/vacpp/lib -lC -lm -lc -bnobind >/tmp/xlcLDW0agyh
+/bin/ld -b32 /lib/crt0.o -bpT:0x10000000 -bpD:0x20000000 dummy.o -L/usr/vac/lib -lxlopt -lxl -L/usr/vacpp/lib -lC -lm -lc |")
+set(aix_xlC_32_libs "xlopt;xl;C;m;c")
+set(aix_xlC_32_dirs "/usr/vac/lib;/usr/vacpp/lib")
+list(APPEND platforms aix_xlC_32)
+
+# xlC -q64 dummy.cxx -V
+set(aix_xlC_64_text "
+/bin/ld -b64 /lib/crt0_64.o -bpT:0x100000000 -bpD:0x110000000 dummy.o -L/usr/vac/lib -lxlopt -lxl -L/usr/vacpp/lib -lC -lm -lc -bnobind >/tmp/xlcLD5nUnah
+/bin/ld -b64 /lib/crt0_64.o -bpT:0x100000000 -bpD:0x110000000 dummy.o -L/usr/vac/lib -lxlopt -lxl -L/usr/vacpp/lib -lC -lm -lc |")
+set(aix_xlC_64_libs "xlopt;xl;C;m;c")
+set(aix_xlC_64_dirs "/usr/vac/lib;/usr/vacpp/lib")
+list(APPEND platforms aix_xlC_64)
+
+# xlf -q32 dummy.f -V
+set(aix_xlf_32_text "/bin/ld -b32 /lib/crt0.o -bpT:0x10000000 -bpD:0x20000000 -bh:4 -bh:4 -bh:4 -bh:4 dummy.o -lxlf90 -L/usr/lpp/xlf/lib -lxlopt -lxlf -lxlomp_ser -lm -lc")
+set(aix_xlf_32_libs "xlf90;xlopt;xlf;xlomp_ser;m;c")
+set(aix_xlf_32_dirs "/usr/lpp/xlf/lib")
+list(APPEND platforms aix_xlf_32)
+
+# xlf -q64 dummy.f -V
+set(aix_xlf_64_text "/bin/ld -b64 /lib/crt0_64.o -bpT:0x100000000 -bpD:0x110000000 -bh:4 -bh:4 -bh:4 -bh:4 dummy.o -lxlf90 -L/usr/lpp/xlf/lib -lxlopt -lxlf -lxlomp_ser -lm -lc")
+set(aix_xlf_64_libs "xlf90;xlopt;xlf;xlomp_ser;m;c")
+set(aix_xlf_64_dirs "/usr/lpp/xlf/lib")
+list(APPEND platforms aix_xlf_64)
+
+# xlf90 -q32 dummy.f -V
+set(aix_xlf90_32_text "/bin/ld -b32 /lib/crt0.o -bpT:0x10000000 -bpD:0x20000000 -bh:4 dummy.o -lxlf90 -L/usr/lpp/xlf/lib -lxlopt -lxlf -lxlomp_ser -lm -lc")
+set(aix_xlf90_32_libs "xlf90;xlopt;xlf;xlomp_ser;m;c")
+set(aix_xlf90_32_dirs "/usr/lpp/xlf/lib")
+list(APPEND platforms aix_xlf90_32)
+
+# xlf90 -q64 dummy.f -V
+set(aix_xlf90_64_text "/bin/ld -b64 /lib/crt0_64.o -bpT:0x100000000 -bpD:0x110000000 -bh:4 dummy.o -lxlf90 -L/usr/lpp/xlf/lib -lxlopt -lxlf -lxlomp_ser -lm -lc")
+set(aix_xlf90_64_libs "xlf90;xlopt;xlf;xlomp_ser;m;c")
+set(aix_xlf90_64_dirs "/usr/lpp/xlf/lib")
+list(APPEND platforms aix_xlf90_64)
+
+#-----------------------------------------------------------------------------
+# HP
+
+# cc dummy.c -v
+set(hp_cc_old_text "cc: LPATH is /usr/lib/pa1.1:/usr/lib:/opt/langtools/lib:
+/usr/ccs/bin/ld /opt/langtools/lib/crt0.o -u main dummy.o -lc")
+set(hp_cc_old_libs "c")
+set(hp_cc_old_dirs "/usr/lib/pa1.1;/usr/lib;/opt/langtools/lib")
+list(APPEND platforms hp_cc_old)
+
+# aCC dummy.cxx -v
+set(hp_aCC_old_text "LPATH=/usr/lib/pa1.1:/usr/lib:/opt/langtools/lib
+ /usr/ccs/bin/ld -o a.out /opt/aCC/lib/crt0.o -u ___exit -u main -L /opt/aCC/lib /opt/aCC/lib/cpprt0.o dummy.o -lstd -lstream -lCsup -lm -lcl -lc /usr/lib/libdld.sl >/var/tmp/AAAa27787 2>&1")
+set(hp_aCC_old_libs "std;stream;Csup;m;cl;c")
+set(hp_aCC_old_dirs "/usr/lib/pa1.1;/usr/lib;/opt/langtools/lib;/opt/aCC/lib")
+list(APPEND platforms hp_aCC_old)
+
+# cc dummy.c -v
+set(hp_cc_32_text "LPATH=/usr/lib/hpux32:/opt/langtools/lib/hpux32
+ /usr/ccs/bin/ld -o a.out -u___exit -umain dummy.o -lc")
+set(hp_cc_32_libs "c")
+set(hp_cc_32_dirs "/usr/lib/hpux32;/opt/langtools/lib/hpux32")
+list(APPEND platforms hp_cc_32)
+
+# cc +DD64 dummy.c -v
+set(hp_cc_64_text "LPATH=/usr/lib/hpux64:/opt/langtools/lib/hpux64
+ /usr/ccs/bin/ld -o a.out -u___exit -umain dummy.o -lc")
+set(hp_cc_64_libs "c")
+set(hp_cc_64_dirs "/usr/lib/hpux64;/opt/langtools/lib/hpux64")
+list(APPEND platforms hp_cc_64)
+
+# aCC dummy.cxx -v
+set(hp_aCC_32_text "LPATH=/usr/lib/hpux32:/opt/langtools/lib/hpux32
+ /usr/ccs/bin/ld -o a.out -u___exit -umain -L/opt/aCC/lib/hpux32 dummy.o -lstd_v2 -lCsup -lm -lunwind -lCsup -lc -ldl >/var/tmp/AAAa03601 2>&1")
+set(hp_aCC_32_libs "std_v2;Csup;m;unwind;Csup;c;dl")
+set(hp_aCC_32_dirs "/usr/lib/hpux32;/opt/langtools/lib/hpux32;/opt/aCC/lib/hpux32")
+list(APPEND platforms hp_aCC_32)
+
+# aCC +DD64 dummy.cxx -v
+set(hp_aCC_64_text "LPATH=/usr/lib/hpux64:/opt/langtools/lib/hpux64
+ /usr/ccs/bin/ld -o a.out -u___exit -umain -L/opt/aCC/lib/hpux64 dummy.o -lstd_v2 -lCsup -lm -lunwind -lCsup -lc -ldl >/var/tmp/AAAa03597 2>&1")
+set(hp_aCC_64_libs "std_v2;Csup;m;unwind;Csup;c;dl")
+set(hp_aCC_64_dirs "/usr/lib/hpux64;/opt/langtools/lib/hpux64;/opt/aCC/lib/hpux64")
+list(APPEND platforms hp_aCC_64)
+
+# f90 dummy.f -v
+set(hp_f90_32_text "LPATH is: /usr/lib/hpux32/:/opt/langtools/lib/hpux32/
+/usr/ccs/bin/ld -u f90\$sgemm -u f90\$sgemv -u f90\$dgemm -u f90\$dgemv dummy.c +vnoshlibunsats -l:libF90.a -l:libIO77.a -lm -lc -lunwind -luca")
+set(hp_f90_32_libs "-l:libF90.a;-l:libIO77.a;m;c;unwind;uca")
+set(hp_f90_32_dirs "/usr/lib/hpux32;/opt/langtools/lib/hpux32")
+list(APPEND platforms hp_f90_32)
+
+# f90 +DD64 dummy.f -v
+set(hp_f90_64_text "LPATH is: /usr/lib/hpux64/:/opt/langtools/lib/hpux64/
+/usr/ccs/bin/ld -u f90\$sgemm -u f90\$sgemv -u f90\$dgemm -u f90\$dgemv dummy.c +vnoshlibunsats -l:libF90.a -l:libIO77.a -lm -lc -lunwind -luca")
+set(hp_f90_64_libs "-l:libF90.a;-l:libIO77.a;m;c;unwind;uca")
+set(hp_f90_64_dirs "/usr/lib/hpux64;/opt/langtools/lib/hpux64")
+list(APPEND platforms hp_f90_64)
+
+#-----------------------------------------------------------------------------
+# IRIX
+
+# cc -o32 dummy.c -v
+set(irix64_cc_o32_text "/usr/lib/ld -elf -_SYSTYPE_SVR4 -require_dynamic_link _rld_new_interface -no_unresolved -Wx,-G 0 -o32 -mips2 -call_shared -g0 -KPIC -L/usr/lib/ -nocount /usr/lib/crt1.o -count dummy.o -nocount -lc /usr/lib/crtn.o")
+set(irix64_cc_o32_libs "c")
+set(irix64_cc_o32_dirs "/usr/lib")
+list(APPEND platforms irix64_cc_o32)
+
+# cc -n32 dummy.c -v
+set(irix64_cc_n32_text "/usr/lib32/cmplrs/ld32 -call_shared -no_unresolved -transitive_link -elf -_SYSTYPE_SVR4 -show -mips4 -n32 -L/usr/lib32/mips4/r10000 -L/usr/lib32/mips4 -L/usr/lib32 /usr/lib32/mips4/crt1.o dummy.o -dont_warn_unused -Bdynamic -lc /usr/lib32/mips4/crtn.o -warn_unused")
+set(irix64_cc_n32_libs "c")
+set(irix64_cc_n32_dirs "/usr/lib32/mips4/r10000;/usr/lib32/mips4;/usr/lib32")
+list(APPEND platforms irix64_cc_n32)
+
+# cc -64 dummy.c -v
+set(irix64_cc_64_text "/usr/lib32/cmplrs/ld64 -call_shared -no_unresolved -transitive_link -elf -_SYSTYPE_SVR4 -show -mips4 -64 -L/usr/lib64/mips4/r10000 -L/usr/lib64/mips4 -L/usr/lib64 /usr/lib64/mips4/crt1.o dummy.o -dont_warn_unused -Bdynamic -lc /usr/lib64/mips4/crtn.o -warn_unused")
+set(irix64_cc_64_libs "c")
+set(irix64_cc_64_dirs "/usr/lib64/mips4/r10000;/usr/lib64/mips4;/usr/lib64")
+list(APPEND platforms irix64_cc_64)
+
+# CC -o32 dummy.cxx -v
+set(irix64_CC_o32_text "/usr/lib/ld -elf -cxx -woff 134 -_SYSTYPE_SVR4 -require_dynamic_link _rld_new_interface -no_unresolved -Wx,-G 0 -o32 -mips2 -call_shared -g0 -KPIC -L/usr/lib/ -nocount /usr/lib/crt1.o /usr/lib/c++init.o -count dummy.o -nocount -dont_warn_unused -lC -warn_unused -lc /usr/lib/crtn.o")
+set(irix64_CC_o32_libs "C;c")
+set(irix64_CC_o32_dirs "/usr/lib")
+list(APPEND platforms irix64_CC_o32)
+
+# CC -n32 dummy.cxx -v
+set(irix64_CC_n32_text "/usr/lib32/cmplrs/ld32 -call_shared -init _main -fini _fini -no_unresolved -transitive_link -demangle -elf -_SYSTYPE_SVR4 -LANG:std -show -mips4 -n32 -L/usr/lib32/mips4/r10000 -L/usr/lib32/mips4 -L/usr/lib32 -cxx -woff 134 /usr/lib32/mips4/crt1.o /usr/lib32/c++init.o dummy.o -dont_warn_unused -lCsup -lC -lCio -Bdynamic -lc /usr/lib32/mips4/crtn.o -warn_unused")
+set(irix64_CC_n32_libs "Csup;C;Cio;c")
+set(irix64_CC_n32_dirs "/usr/lib32/mips4/r10000;/usr/lib32/mips4;/usr/lib32")
+list(APPEND platforms irix64_CC_n32)
+
+# CC -64 dummy.cxx -v
+set(irix64_CC_64_text "/usr/lib32/cmplrs/ld64 -call_shared -init _main -fini _fini -no_unresolved -transitive_link -demangle -elf -_SYSTYPE_SVR4 -LANG:std -show -mips4 -64 -L/usr/lib64/mips4/r10000 -L/usr/lib64/mips4 -L/usr/lib64 -cxx -woff 134 /usr/lib64/mips4/crt1.o /usr/lib64/c++init.o dummy.o -dont_warn_unused -lCsup -lC -lCio -Bdynamic -lc /usr/lib64/mips4/crtn.o -warn_unused")
+set(irix64_CC_64_libs "Csup;C;Cio;c")
+set(irix64_CC_64_dirs "/usr/lib64/mips4/r10000;/usr/lib64/mips4;/usr/lib64")
+list(APPEND platforms irix64_CC_64)
+
+# f77 -o32 dummy.f -v
+set(irix64_f77_o32_text "/usr/lib/ld -elf -_SYSTYPE_SVR4 -require_dynamic_link _rld_new_interface -no_unresolved -Wx,-G 0 -o32 -mips2 -call_shared -g0 -KPIC -L/usr/lib/ -nocount /usr/lib/crt1.o -count dummy.o -nocount -lftn -lm -lc /usr/lib/crtn.o")
+set(irix64_f77_o32_libs "ftn;m;c")
+set(irix64_f77_o32_dirs "/usr/lib")
+list(APPEND platforms irix64_f77_o32)
+
+# f77 -n32 dummy.f -v
+set(irix64_f77_n32_text "/usr/lib32/cmplrs/ld32 -call_shared -no_unresolved -transitive_link -elf -_SYSTYPE_SVR4 -show -mips4 -n32 -L/usr/lib32/mips4/r10000 -L/usr/lib32/mips4 -L/usr/lib32 /usr/lib32/mips4/crt1.o dummy.o -dont_warn_unused -lftn -lm -Bdynamic -lc /usr/lib32/mips4/crtn.o -warn_unused")
+set(irix64_f77_n32_libs "ftn;m;c")
+set(irix64_f77_n32_dirs "/usr/lib32/mips4/r10000;/usr/lib32/mips4;/usr/lib32")
+list(APPEND platforms irix64_f77_n32)
+
+# f77 -64 dummy.f -v
+set(irix64_f77_64_text "/usr/lib32/cmplrs/ld64 -call_shared -no_unresolved -transitive_link -elf -_SYSTYPE_SVR4 -show -mips4 -64 -L/usr/lib64/mips4/r10000 -L/usr/lib64/mips4 -L/usr/lib64 /usr/lib64/mips4/crt1.o dummy.o -dont_warn_unused -lftn -lm -Bdynamic -lc /usr/lib64/mips4/crtn.o -warn_unused")
+set(irix64_f77_64_libs "ftn;m;c")
+set(irix64_f77_64_dirs "/usr/lib64/mips4/r10000;/usr/lib64/mips4;/usr/lib64")
+list(APPEND platforms irix64_f77_64)
+
+# f90 -o32 dummy.f -v
+#f90 ERROR: specified abi -o32 not supported.
+
+# f90 -n32 dummy.f -v
+set(irix64_f90_n32_text "/usr/lib32/cmplrs/ld32 -call_shared -no_unresolved -transitive_link -elf -_SYSTYPE_SVR4 -show -mips4 -n32 -L/usr/lib32/mips4/r10000 -L/usr/lib32/mips4 -L/usr/lib32 /usr/lib32/mips4/crt1.o dummy.o -dont_warn_unused -lfortran -lffio -lftn -lm -Bdynamic -lc /usr/lib32/mips4/crtn.o -warn_unused")
+set(irix64_f90_n32_libs "fortran;ffio;ftn;m;c")
+set(irix64_f90_n32_dirs "/usr/lib32/mips4/r10000;/usr/lib32/mips4;/usr/lib32")
+list(APPEND platforms irix64_f90_n32)
+
+# f90 -64 dummy.f -v
+set(irix64_f90_64_text "/usr/lib32/cmplrs/ld64 -call_shared -no_unresolved -transitive_link -elf -_SYSTYPE_SVR4 -show -mips4 -64 -L/usr/lib64/mips4/r10000 -L/usr/lib64/mips4 -L/usr/lib64 /usr/lib64/mips4/crt1.o dummy.o -dont_warn_unused -lfortran -lffio -lftn -lm -Bdynamic -lc /usr/lib64/mips4/crtn.o -warn_unused")
+set(irix64_f90_64_libs "fortran;ffio;ftn;m;c")
+set(irix64_f90_64_dirs "/usr/lib64/mips4/r10000;/usr/lib64/mips4;/usr/lib64")
+list(APPEND platforms irix64_f90_64)
+
+#-----------------------------------------------------------------------------
+# Cygwin
+
+# gcc dummy.c -v
+set(cygwin_gcc_text " /usr/lib/gcc/i686-pc-cygwin/3.4.4/collect2.exe -Bdynamic --dll-search-prefix=cyg /usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../crt0.o -L/usr/lib/gcc/i686-pc-cygwin/3.4.4 -L/usr/lib/gcc/i686-pc-cygwin/3.4.4 -L/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../.. /home/user/AppData/Local/Temp/cczg1Arh.o -lgcc -lcygwin -luser32 -lkernel32 -ladvapi32 -lshell32 -lgcc")
+set(cygwin_gcc_libs "cygwin;user32;kernel32;advapi32;shell32")
+set(cygwin_gcc_dirs "/usr/lib/gcc/i686-pc-cygwin/3.4.4;/usr/lib")
+list(APPEND platforms cygwin_gcc)
+
+# g++ dummy.cxx -v
+set(cygwin_g++_text " /usr/lib/gcc/i686-pc-cygwin/3.4.4/collect2.exe -Bdynamic --dll-search-prefix=cyg /usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../crt0.o -L/usr/lib/gcc/i686-pc-cygwin/3.4.4 -L/usr/lib/gcc/i686-pc-cygwin/3.4.4 -L/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../.. /home/user/AppData/Local/Temp/ccsvcDO6.o -lstdc++ -lgcc -lcygwin -luser32 -lkernel32 -ladvapi32 -lshell32 -lgcc")
+set(cygwin_g++_libs "stdc++;cygwin;user32;kernel32;advapi32;shell32")
+set(cygwin_g++_dirs "/usr/lib/gcc/i686-pc-cygwin/3.4.4;/usr/lib")
+list(APPEND platforms cygwin_g++)
+
+# gfortran dummy.f -v
+set(cygwin_gfortran_text "Configured with: ... LD=/opt/gcc-tools/bin/ld.exe
+ /usr/lib/gcc/i686-pc-cygwin/4.3.2/collect2.exe -Bdynamic --dll-search-prefix=cyg -u ___register_frame_info -u ___deregister_frame_info /usr/lib/gcc/i686-pc-cygwin/4.3.2/../../../crt0.o /usr/lib/gcc/i686-pc-cygwin/4.3.2/crtbegin.o -L/usr/lib/gcc/i686-pc-cygwin/4.3.2 -L/usr/lib/gcc/i686-pc-cygwin/4.3.2 -L/usr/lib/gcc/i686-pc-cygwin/4.3.2/../../.. /home/user/AppData/Local/Temp/ccqRWKWg.o -lgfortranbegin -lgfortran -lgcc_s -lgcc_s -lgcc -lcygwin -luser32 -lkernel32 -ladvapi32 -lshell32 -lgcc_s -lgcc_s -lgcc /usr/lib/gcc/i686-pc-cygwin/4.3.2/crtend.o
+")
+set(cygwin_gfortran_libs "gfortranbegin;gfortran;cygwin;user32;kernel32;advapi32;shell32")
+set(cygwin_gfortran_dirs "/usr/lib/gcc/i686-pc-cygwin/4.3.2;/usr/lib")
+list(APPEND platforms cygwin_gfortran)
+
+#-----------------------------------------------------------------------------
+# MSYS
+
+# gcc dummy.c -v
+set(msys_gcc_text " C:/some-mingw/bin/../libexec/gcc/mingw32/3.4.5/collect2.exe -Bdynamic /some-mingw/lib/crt2.o C:/some-mingw/bin/../lib/gcc/mingw32/3.4.5/crtbegin.o -LC:/some-mingw/bin/../lib/gcc/mingw32/3.4.5 -LC:/some-mingw/bin/../lib/gcc -L/some-mingw/lib -LC:/some-mingw/bin/../lib/gcc/mingw32/3.4.5/../../.. C:/home/user/AppData/Local/Temp/cckQmvRt.o -lmingw32 -lgcc -lmoldname -lmingwex -lmsvcrt -luser32 -lkernel32 -ladvapi32 -lshell32 -lmingw32 -lgcc -lmoldname -lmingwex -lmsvcrt C:/some-mingw/bin/../lib/gcc/mingw32/3.4.5/crtend.o")
+set(msys_gcc_libs "mingw32;moldname;mingwex;msvcrt;user32;kernel32;advapi32;shell32;mingw32;moldname;mingwex;msvcrt")
+set(msys_gcc_dirs "C:/some-mingw/lib/gcc/mingw32/3.4.5;C:/some-mingw/lib/gcc;/some-mingw/lib;C:/some-mingw/lib")
+list(APPEND platforms msys_gcc)
+
+# g++ dummy.cxx -v
+set(msys_g++_text " C:/some-mingw/bin/../libexec/gcc/mingw32/3.4.5/collect2.exe -Bdynamic /some-mingw/lib/crt2.o C:/some-mingw/bin/../lib/gcc/mingw32/3.4.5/crtbegin.o -LC:/some-mingw/bin/../lib/gcc/mingw32/3.4.5 -LC:/some-mingw/bin/../lib/gcc -L/some-mingw/lib -LC:/some-mingw/bin/../lib/gcc/mingw32/3.4.5/../../.. C:/home/user/AppData/Local/Temp/cci5hYPk.o -lstdc++ -lmingw32 -lgcc -lmoldname -lmingwex -lmsvcrt -luser32 -lkernel32 -ladvapi32 -lshell32 -lmingw32 -lgcc -lmoldname -lmingwex -lmsvcrt C:/some-mingw/bin/../lib/gcc/mingw32/3.4.5/crtend.o")
+set(msys_g++_libs "stdc++;mingw32;moldname;mingwex;msvcrt;user32;kernel32;advapi32;shell32;mingw32;moldname;mingwex;msvcrt")
+set(msys_g++_dirs "C:/some-mingw/lib/gcc/mingw32/3.4.5;C:/some-mingw/lib/gcc;/some-mingw/lib;C:/some-mingw/lib")
+list(APPEND platforms msys_g++)
+
+# g77 dummy.f -v
+set(msys_g77_text " C:/some-mingw/bin/../libexec/gcc/mingw32/3.4.5/collect2.exe -Bdynamic /some-mingw/lib/crt2.o C:/some-mingw/bin/../lib/gcc/mingw32/3.4.5/crtbegin.o -LC:/some-mingw/bin/../lib/gcc/mingw32/3.4.5 -LC:/some-mingw/bin/../lib/gcc -L/some-mingw/lib -LC:/some-mingw/bin/../lib/gcc/mingw32/3.4.5/../../.. C:/home/user/AppData/Local/Temp/ccabRxQ1.o -lfrtbegin -lg2c -lmingw32 -lgcc -lmoldname -lmingwex -lmsvcrt -luser32 -lkernel32 -ladvapi32 -lshell32 -lmingw32 -lgcc -lmoldname -lmingwex -lmsvcrt C:/some-mingw/bin/../lib/gcc/mingw32/3.4.5/crtend.o")
+set(msys_g77_libs "frtbegin;g2c;mingw32;moldname;mingwex;msvcrt;user32;kernel32;advapi32;shell32;mingw32;moldname;mingwex;msvcrt")
+set(msys_g77_dirs "C:/some-mingw/lib/gcc/mingw32/3.4.5;C:/some-mingw/lib/gcc;/some-mingw/lib;C:/some-mingw/lib")
+list(APPEND platforms msys_g77)
+
+
+#-----------------------------------------------------------------------------
+# Test parsing for all above examples.
+
+foreach(p IN LISTS platforms)
+ cmake_parse_implicit_link_info("${${p}_text}" libs dirs log "${${p}_obj_regex}")
+
+ foreach(v libs dirs)
+ if(NOT "${${v}}" STREQUAL "${${p}_${v}}")
+ message(FATAL_ERROR
+ "cmake_parse_implicit_link_info failed\n"
+ "Expected '${p}' implicit ${v}\n"
+ " [${${p}_${v}}]\n"
+ "but got\n"
+ " [${${v}}]\n"
+ "Parse log was:\n"
+ "${log}"
+ )
+ endif()
+ endforeach()
+endforeach()
diff --git a/Tests/CMakeTests/IncludeTest.cmake.in b/Tests/CMakeTests/IncludeTest.cmake.in
new file mode 100644
index 000000000..eca679b4a
--- /dev/null
+++ b/Tests/CMakeTests/IncludeTest.cmake.in
@@ -0,0 +1,41 @@
+# this one must silently fail
+include(I_am_not_here OPTIONAL)
+
+# this one must be found and the result must be put into _includedFile
+include(CMake RESULT_VARIABLE _includedFile)
+
+set(fileOne "${_includedFile}")
+set(fileTwo "${CMAKE_ROOT}/Modules/CMake.cmake")
+if(WIN32)
+ string(TOLOWER "${fileOne}" fileOne)
+ string(TOLOWER "${fileTwo}" fileTwo)
+endif(WIN32)
+
+if(NOT "${fileOne}" STREQUAL "${fileTwo}")
+ message(FATAL_ERROR "Wrong CMake.cmake was included: \"${fileOne}\" expected \"${fileTwo}\"")
+endif(NOT "${fileOne}" STREQUAL "${fileTwo}")
+
+# this one must return NOTFOUND in _includedFile
+include(I_do_not_exist OPTIONAL RESULT_VARIABLE _includedFile)
+
+if(_includedFile)
+ message(FATAL_ERROR "File \"I_do_not_exist\" was included, although it shouldn't exist,\nIncluded file is \"${_includedFile}\"")
+endif(_includedFile)
+
+# and this one must succeed too
+include(CMake OPTIONAL RESULT_VARIABLE _includedFile)
+set(fileOne "${_includedFile}")
+set(fileTwo "${CMAKE_ROOT}/Modules/CMake.cmake")
+if(WIN32)
+ string(TOLOWER "${fileOne}" fileOne)
+ string(TOLOWER "${fileTwo}" fileTwo)
+endif(WIN32)
+
+if(NOT "${fileOne}" STREQUAL "${fileTwo}")
+ message(FATAL_ERROR "Wrong CMake.cmake was included: \"${fileOne}\" expected \"${fileTwo}\"")
+endif(NOT "${fileOne}" STREQUAL "${fileTwo}")
+
+# Check that CMAKE_CURRENT_LIST_DIR is working:
+# Needs to be a file in the build tree, which is correct cmake script
+# but doesn't do a lot, if possible only set() commands:
+include(${CMAKE_CURRENT_LIST_DIR}/../../CTestCustom.cmake)
diff --git a/Tests/CMakeTests/ListTest.cmake.in b/Tests/CMakeTests/ListTest.cmake.in
new file mode 100644
index 000000000..cf6f91a70
--- /dev/null
+++ b/Tests/CMakeTests/ListTest.cmake.in
@@ -0,0 +1,88 @@
+MACRO(TEST command expected)
+ IF("x${result}" STREQUAL "x${expected}")
+ #MESSAGE("TEST \"${command}\" success: \"${result}\" expected: \"${expected}\"")
+ ELSE("x${result}" STREQUAL "x${expected}")
+ MESSAGE(SEND_ERROR "${CMAKE_CURRENT_LIST_LINE}: TEST \"${command}\" failed: \"${result}\" expected: \"${expected}\"")
+ ENDIF("x${result}" STREQUAL "x${expected}")
+ENDMACRO(TEST command expected)
+
+SET(mylist andy bill ken brad)
+
+LIST(LENGTH mylist result)
+TEST("LENGTH mylist result" "4")
+LIST(LENGTH "mylist" result)
+TEST("LENGTH \"mylist\" result" "4")
+
+LIST(LENGTH "nonexiting_list1" result)
+TEST("LENGTH \"nonexiting_list1\" result" "0")
+
+LIST(GET mylist 3 2 1 0 result)
+TEST("GET mylist 3 2 1 0 result" "brad;ken;bill;andy")
+
+LIST(GET mylist 0 item0)
+LIST(GET mylist 1 item1)
+LIST(GET mylist 2 item2)
+LIST(GET mylist 3 item3)
+SET(result "${item3}" "${item0}" "${item1}" "${item2}")
+TEST("GET individual 3 2 1 0 result" "brad;andy;bill;ken")
+
+LIST(GET mylist -1 -2 -3 -4 result)
+TEST("GET mylist -1 -2 -3 -4 result" "brad;ken;bill;andy")
+
+LIST(GET mylist -1 2 -3 0 result)
+TEST("GET mylist -1 2 -3 0 ${result}" "brad;ken;bill;andy")
+
+LIST(GET "nonexiting_list2" 1 result)
+TEST("GET \"nonexiting_list2\" 1 result" "NOTFOUND")
+
+SET(result andy)
+LIST(APPEND result brad)
+TEST("APPEND result brad" "andy;brad")
+
+LIST(APPEND "nonexiting_list3" brad)
+SET(result "${nonexiting_list3}")
+TEST("APPEND \"nonexiting_list3\" brad" "brad")
+
+LIST(INSERT "nonexiting_list4" 0 andy bill brad ken)
+SET(result "${nonexiting_list4}")
+TEST("APPEND \"nonexiting_list4\" andy bill brad ken" "andy;bill;brad;ken")
+
+SET(result andy brad)
+LIST(INSERT result -1 bill ken)
+TEST("INSERT result -1 bill ken" "andy;bill;ken;brad")
+
+SET(result andy bill brad ken bob)
+LIST(REMOVE_ITEM result bob)
+TEST("REMOVE_ITEM result bob" "andy;bill;brad;ken")
+
+SET(result andy bill bob brad ken peter)
+LIST(REMOVE_ITEM result peter bob)
+TEST("REMOVE_ITEM result peter bob" "andy;bill;brad;ken")
+
+SET(result bob andy bill bob brad ken bob)
+LIST(REMOVE_ITEM result bob)
+TEST("REMOVE_ITEM result bob" "andy;bill;brad;ken")
+
+SET(result andy bill bob brad ken peter)
+LIST(REMOVE_AT result 2 -1)
+TEST("REMOVE_AT result 2 -1" "andy;bill;brad;ken")
+
+# ken is at index 2, nobody is not in the list so -1 should be returned
+SET(mylist andy bill ken brad)
+LIST(FIND mylist ken result)
+TEST("FIND mylist ken result" "2")
+
+LIST(FIND mylist nobody result)
+TEST("FIND mylist nobody result" "-1")
+
+SET(result ken bill andy brad)
+LIST(SORT result)
+TEST("SORT result" "andy;bill;brad;ken")
+
+SET(result andy bill brad ken)
+LIST(REVERSE result)
+TEST("REVERSE result" "ken;brad;bill;andy")
+
+SET(result bill andy bill brad ken ken ken)
+LIST(REMOVE_DUPLICATES result)
+TEST("REMOVE_DUPLICATES result" "bill;andy;brad;ken")
diff --git a/Tests/CMakeTests/MathTest.cmake.in b/Tests/CMakeTests/MathTest.cmake.in
new file mode 100644
index 000000000..91cd9220a
--- /dev/null
+++ b/Tests/CMakeTests/MathTest.cmake.in
@@ -0,0 +1,18 @@
+# Execute each test listed in:
+#
+set(scriptname "@CMAKE_CURRENT_SOURCE_DIR@/MathTestScript.cmake")
+set(number_of_tests_expected 4)
+
+include("@CMAKE_CURRENT_SOURCE_DIR@/ExecuteScriptTests.cmake")
+execute_all_script_tests(${scriptname} number_of_tests_executed)
+
+# And verify that number_of_tests_executed is at least as many as we know
+# about as of this writing...
+#
+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)
+ message(FATAL_ERROR "error: some test cases were skipped")
+endif()
diff --git a/Tests/CMakeTests/MathTestScript.cmake b/Tests/CMakeTests/MathTestScript.cmake
new file mode 100644
index 000000000..1b7f8a6f3
--- /dev/null
+++ b/Tests/CMakeTests/MathTestScript.cmake
@@ -0,0 +1,18 @@
+message(STATUS "testname='${testname}'")
+
+if(testname STREQUAL empty) # fail
+ math()
+
+elseif(testname STREQUAL bogus) # fail
+ math(BOGUS)
+
+elseif(testname STREQUAL not_enough_args) # fail
+ math(EXPR x)
+
+elseif(testname STREQUAL cannot_parse) # fail
+ math(EXPR x "1 + 2 +")
+
+else() # fail
+ message(FATAL_ERROR "testname='${testname}' - error: no such test in '${CMAKE_CURRENT_LIST_FILE}'")
+
+endif()
diff --git a/Tests/CMakeTests/MessageTest.cmake.in b/Tests/CMakeTests/MessageTest.cmake.in
new file mode 100644
index 000000000..a9833b99c
--- /dev/null
+++ b/Tests/CMakeTests/MessageTest.cmake.in
@@ -0,0 +1,30 @@
+execute_process(
+ COMMAND ${CMAKE_COMMAND} -P
+ "@CMAKE_CURRENT_SOURCE_DIR@/MessageTestScript.cmake"
+ OUTPUT_VARIABLE out
+ ERROR_VARIABLE err
+ RESULT_VARIABLE result
+ )
+
+message("out=[${out}]")
+message("err=[${err}]")
+
+if(NOT "${result}" STREQUAL "0")
+ message(FATAL_ERROR "message script failed: [${result}]")
+endif()
+
+if(NOT "${out}" MATCHES "message-status")
+ message(FATAL_ERROR "message(STATUS) did not go to stdout")
+endif()
+
+if(NOT "${err}" MATCHES "message-default")
+ message(FATAL_ERROR "message() did not go to stderr by default")
+endif()
+
+if(NOT "${err}" MATCHES "CMake Warning at[^\n]*:\r?\n message-warning")
+ message(FATAL_ERROR "message(WARNING) did not appear properly")
+endif()
+
+if(NOT "${err}" MATCHES "CMake Warning \\(dev\\) at[^\n]*:\r?\n message-author")
+ message(FATAL_ERROR "message(AUTHOR_WARNING) did not appear properly")
+endif()
diff --git a/Tests/CMakeTests/MessageTestScript.cmake b/Tests/CMakeTests/MessageTestScript.cmake
new file mode 100644
index 000000000..c56f88e15
--- /dev/null
+++ b/Tests/CMakeTests/MessageTestScript.cmake
@@ -0,0 +1,4 @@
+message("message-default")
+message(STATUS "message-status")
+message(WARNING "message-warning")
+message(AUTHOR_WARNING "message-author")
diff --git a/Tests/CMakeTests/ModuleNoticesTest.cmake.in b/Tests/CMakeTests/ModuleNoticesTest.cmake.in
new file mode 100644
index 000000000..8ecebd338
--- /dev/null
+++ b/Tests/CMakeTests/ModuleNoticesTest.cmake.in
@@ -0,0 +1,46 @@
+# Regex to match copyright/license notices.
+# We require the Kitware copyright on the first line, but this can
+# match any additional copyright holder notices.
+set(notice_regex "
+#=============================================================================
+# Copyright (20[0-9][0-9]-)?20[0-9][0-9] [^\n]+(
+# Copyright (20[0-9][0-9]-)?20[0-9][0-9] [^\n]+)*
+#
+# Distributed under the OSI-approved BSD License \\(the \"License\"\\);
+# see accompanying file Copyright\\.txt for details\\.
+#
+# This software 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.\\)
+")
+string(REPLACE "\n" "\r?\n" notice_regex "${notice_regex}")
+string(REPLACE "\r\r" "\r" notice_regex "${notice_regex}")
+
+# Modules that do not require our notice.
+set(notice_exceptions
+ FindCUDA.cmake # MIT License, distributed here from upstream project
+ )
+
+# Load the list of modules to check.
+set(dir "@CMake_SOURCE_DIR@/Modules")
+file(GLOB all_modules RELATIVE "${dir}" "${dir}/*.cmake")
+list(REMOVE_ITEM all_modules ${notice_exceptions})
+
+# Check each module.
+set(notice_missing)
+foreach(module ${all_modules})
+ message(STATUS "module: ${module}")
+ file(READ "${dir}/${module}" module_content)
+ if(NOT "${module_content}" MATCHES "${notice_regex}")
+ set(notice_missing "${notice_missing} ${module}\n")
+ endif()
+endforeach()
+
+# Report the list of bad modules.
+if(notice_missing)
+ message(FATAL_ERROR
+ "Some modules do not have a valid copyright notice:\n${notice_missing}")
+endif()
diff --git a/Tests/CMakeTests/ProcessorCountTest.cmake.in b/Tests/CMakeTests/ProcessorCountTest.cmake.in
new file mode 100644
index 000000000..98f6ab16d
--- /dev/null
+++ b/Tests/CMakeTests/ProcessorCountTest.cmake.in
@@ -0,0 +1,72 @@
+include(ProcessorCount)
+
+ProcessorCount(processor_count)
+
+message("### 1. This line should be the first line of text in the test output.")
+message("### 2. If there was output from this test before line #1, then the")
+message("### 3. ProcessorCount(...) function call is emitting output that it shouldn't...")
+
+message("processor_count='${processor_count}'")
+
+execute_process(
+ COMMAND "@CMAKE_BINARY_DIR@/Source/kwsys/$ENV{CMAKE_CONFIG_TYPE}/cmsysTestsCxx"
+ testSystemInformation
+ OUTPUT_VARIABLE tsi_out
+ ERROR_VARIABLE tsi_err)
+string(REGEX REPLACE "(.*)GetNumberOfPhysicalCPU:.([0-9]*)(.*)" "\\2"
+ system_info_processor_count "${tsi_out}")
+
+message("system_info_processor_count='${system_info_processor_count}'")
+
+if(system_info_processor_count EQUAL processor_count)
+ message("processor count matches system information")
+endif()
+
+message("")
+message("CTEST_FULL_OUTPUT (Avoid ctest truncation of output)")
+message("")
+message("tsi_out='${tsi_out}'")
+message("tsi_err='${tsi_err}'")
+message("")
+
+# Evaluate possible error conditions:
+#
+set(err 0)
+set(fatal 0)
+
+if(processor_count EQUAL 0)
+ set(err 1)
+ set(fatal 1)
+ message("err 1")
+ message("could not determine number of processors
+- Additional code for this platform needed in ProcessorCount.cmake?")
+ message("")
+endif()
+
+if(NOT system_info_processor_count EQUAL processor_count)
+ set(err 2)
+ message("err 2")
+ message("SystemInformation and ProcessorCount.cmake disagree:\n"
+ "processor_count='${processor_count}'\n"
+ "SystemInformation processor_count='${system_info_processor_count}'")
+ message("")
+endif()
+
+if(NOT processor_count MATCHES "^[0-9]+$")
+ set(err 3)
+ set(fatal 1)
+ message("err 3")
+ message("ProcessorCount function returned a non-integer")
+ message("")
+endif()
+
+if(NOT system_info_processor_count MATCHES "^[0-9]+$")
+ set(err 4)
+ message("err 4")
+ message("SystemInformation ProcessorCount function returned a non-integer")
+ message("")
+endif()
+
+if(fatal)
+ message(FATAL_ERROR "processor_count='${processor_count}' - see previous test output for more details - it is likely more/different code is needed in ProcessorCount.cmake to fix this test failure - processor_count should be a non-zero positive integer (>=1) for all supported CMake platforms")
+endif()
diff --git a/Tests/CMakeTests/PushCheckStateTest.cmake.in b/Tests/CMakeTests/PushCheckStateTest.cmake.in
new file mode 100644
index 000000000..e707b9a92
--- /dev/null
+++ b/Tests/CMakeTests/PushCheckStateTest.cmake.in
@@ -0,0 +1,30 @@
+include(CMakePushCheckState)
+
+set(CMAKE_REQUIRED_DEFINITIONS defs1 )
+
+cmake_push_check_state()
+
+set(CMAKE_REQUIRED_DEFINITIONS defs2)
+
+cmake_push_check_state()
+
+set(CMAKE_REQUIRED_DEFINITIONS defs3)
+
+cmake_pop_check_state()
+
+if (NOT "${CMAKE_REQUIRED_DEFINITIONS}" STREQUAL "defs2")
+ set(fatal TRUE)
+ message("ERROR: "CMAKE_REQUIRED_DEFINITIONS is \"${CMAKE_REQUIRED_DEFINITIONS}\" (expected \"defs2\")" )
+endif()
+
+cmake_pop_check_state()
+
+if (NOT "${CMAKE_REQUIRED_DEFINITIONS}" STREQUAL "defs1")
+ set(fatal TRUE)
+ message("ERROR: "CMAKE_REQUIRED_DEFINITIONS is \"${CMAKE_REQUIRED_DEFINITIONS}\" (expected \"defs1\")" )
+endif()
+
+
+if(fatal)
+ message(FATAL_ERROR "cmake_push_check_state() test failed")
+endif()
diff --git a/Tests/CMakeTests/SeparateArgumentsTest.cmake.in b/Tests/CMakeTests/SeparateArgumentsTest.cmake.in
new file mode 100644
index 000000000..48964b8cb
--- /dev/null
+++ b/Tests/CMakeTests/SeparateArgumentsTest.cmake.in
@@ -0,0 +1,25 @@
+set(old_out "a b c")
+separate_arguments(old_out)
+set(old_exp "a;b;;c")
+
+set(unix_cmd "a \"b c\" 'd e' \";\" \\ \\'\\\" '\\'' \"\\\"\"")
+set(unix_exp "a;b c;d e;\;; '\";';\"")
+separate_arguments(unix_out UNIX_COMMAND "${unix_cmd}")
+
+set(windows_cmd "a \"b c\" 'd e' \";\" \\ \"c:\\windows\\path\\\\\" \\\"")
+set(windows_exp "a;b c;'d;e';\;;\\;c:\\windows\\path\\;\"")
+separate_arguments(windows_out WINDOWS_COMMAND "${windows_cmd}")
+
+foreach(mode old unix windows)
+ if(NOT "${${mode}_out}" STREQUAL "${${mode}_exp}")
+ message(FATAL_ERROR "separate_arguments ${mode}-style failed. "
+ "Expected\n [${${mode}_exp}]\nbut got\n [${${mode}_out}]\n")
+ endif()
+endforeach()
+
+set(nothing)
+separate_arguments(nothing)
+if(DEFINED nothing)
+ message(FATAL_ERROR "separate_arguments null-case failed: "
+ "nothing=[${nothing}]")
+endif()
diff --git a/Tests/CMakeTests/String-MD5-BadArg1.cmake b/Tests/CMakeTests/String-MD5-BadArg1.cmake
new file mode 100644
index 000000000..89464769b
--- /dev/null
+++ b/Tests/CMakeTests/String-MD5-BadArg1.cmake
@@ -0,0 +1 @@
+string(MD5)
diff --git a/Tests/CMakeTests/String-MD5-BadArg2.cmake b/Tests/CMakeTests/String-MD5-BadArg2.cmake
new file mode 100644
index 000000000..abbbf879a
--- /dev/null
+++ b/Tests/CMakeTests/String-MD5-BadArg2.cmake
@@ -0,0 +1 @@
+string(MD5 md5)
diff --git a/Tests/CMakeTests/String-MD5-BadArg4.cmake b/Tests/CMakeTests/String-MD5-BadArg4.cmake
new file mode 100644
index 000000000..edd442762
--- /dev/null
+++ b/Tests/CMakeTests/String-MD5-BadArg4.cmake
@@ -0,0 +1 @@
+string(MD5 md5 input extra_arg)
diff --git a/Tests/CMakeTests/String-MD5-Works.cmake b/Tests/CMakeTests/String-MD5-Works.cmake
new file mode 100644
index 000000000..4ef7a0754
--- /dev/null
+++ b/Tests/CMakeTests/String-MD5-Works.cmake
@@ -0,0 +1,2 @@
+string(MD5 md5 "sample input string\n")
+message("${md5}")
diff --git a/Tests/CMakeTests/String-SHA1-Works.cmake b/Tests/CMakeTests/String-SHA1-Works.cmake
new file mode 100644
index 000000000..2f3b51b61
--- /dev/null
+++ b/Tests/CMakeTests/String-SHA1-Works.cmake
@@ -0,0 +1,2 @@
+string(SHA1 sha1 "sample input string\n")
+message("${sha1}")
diff --git a/Tests/CMakeTests/String-SHA224-Works.cmake b/Tests/CMakeTests/String-SHA224-Works.cmake
new file mode 100644
index 000000000..5b7f880ee
--- /dev/null
+++ b/Tests/CMakeTests/String-SHA224-Works.cmake
@@ -0,0 +1,2 @@
+string(SHA224 sha224 "sample input string\n")
+message("${sha224}")
diff --git a/Tests/CMakeTests/String-SHA256-Works.cmake b/Tests/CMakeTests/String-SHA256-Works.cmake
new file mode 100644
index 000000000..e3e89ae5d
--- /dev/null
+++ b/Tests/CMakeTests/String-SHA256-Works.cmake
@@ -0,0 +1,2 @@
+string(SHA256 sha256 "sample input string\n")
+message("${sha256}")
diff --git a/Tests/CMakeTests/String-SHA384-Works.cmake b/Tests/CMakeTests/String-SHA384-Works.cmake
new file mode 100644
index 000000000..828a19031
--- /dev/null
+++ b/Tests/CMakeTests/String-SHA384-Works.cmake
@@ -0,0 +1,2 @@
+string(SHA384 sha384 "sample input string\n")
+message("${sha384}")
diff --git a/Tests/CMakeTests/String-SHA512-Works.cmake b/Tests/CMakeTests/String-SHA512-Works.cmake
new file mode 100644
index 000000000..e17db5c6e
--- /dev/null
+++ b/Tests/CMakeTests/String-SHA512-Works.cmake
@@ -0,0 +1,2 @@
+string(SHA512 sha512 "sample input string\n")
+message("${sha512}")
diff --git a/Tests/CMakeTests/StringTest.cmake.in b/Tests/CMakeTests/StringTest.cmake.in
new file mode 100644
index 000000000..49e7dc90c
--- /dev/null
+++ b/Tests/CMakeTests/StringTest.cmake.in
@@ -0,0 +1,50 @@
+set(MD5-BadArg1-RESULT 1)
+set(MD5-BadArg1-STDERR "string MD5 requires an output variable")
+set(MD5-BadArg2-RESULT 1)
+set(MD5-BadArg2-STDERR "string MD5 requires an output variable and an input string")
+set(MD5-BadArg4-RESULT 1)
+set(MD5-BadArg4-STDERR "string MD5 requires an output variable and an input string")
+set(MD5-Works-RESULT 0)
+set(MD5-Works-STDERR "10d20ddb981a6202b84aa1ce1cb7fce3")
+set(SHA1-Works-RESULT 0)
+set(SHA1-Works-STDERR "83f093e04289b21a9415f408ad50be8b57ad2f34")
+set(SHA224-Works-RESULT 0)
+set(SHA224-Works-STDERR "e995a7789922c4ef9279d94e763c8375934180a51baa7147bc48edf7")
+set(SHA256-Works-RESULT 0)
+set(SHA256-Works-STDERR "d1c5915d8b71150726a1eef75a29ec6bea8fd1bef6b7299ef8048760b0402025")
+set(SHA384-Works-RESULT 0)
+set(SHA384-Works-STDERR "1de9560b4e030e02051ea408200ffc55d70c97ac64ebf822461a5c786f495c36df43259b14483bc8d364f0106f4971ee")
+set(SHA512-Works-RESULT 0)
+set(SHA512-Works-STDERR "3982a1b4e651768bec70ab1fb97045cb7a659f4ba7203d501c52ab2e803071f9d5fd272022df15f27727fc67f8cd022e710e29010b2a9c0b467c111e2f6abf51")
+
+include("@CMAKE_CURRENT_SOURCE_DIR@/CheckCMakeTest.cmake")
+check_cmake_test(String
+ MD5-BadArg1
+ MD5-BadArg2
+ MD5-BadArg4
+ MD5-Works
+ SHA1-Works
+ SHA224-Works
+ SHA256-Works
+ SHA384-Works
+ SHA512-Works
+ )
+
+# Execute each test listed in StringTestScript.cmake:
+#
+set(scriptname "@CMAKE_CURRENT_SOURCE_DIR@/StringTestScript.cmake")
+set(number_of_tests_expected 69)
+
+include("@CMAKE_CURRENT_SOURCE_DIR@/ExecuteScriptTests.cmake")
+execute_all_script_tests(${scriptname} number_of_tests_executed)
+
+# And verify that number_of_tests_executed is at least as many as we know
+# about as of this writing...
+#
+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)
+ message(FATAL_ERROR "error: some test cases were skipped")
+endif()
diff --git a/Tests/CMakeTests/StringTestScript.cmake b/Tests/CMakeTests/StringTestScript.cmake
new file mode 100644
index 000000000..7a264a0e2
--- /dev/null
+++ b/Tests/CMakeTests/StringTestScript.cmake
@@ -0,0 +1,279 @@
+message(STATUS "testname='${testname}'")
+
+if(testname STREQUAL empty) # fail
+ string()
+
+elseif(testname STREQUAL bogus) # fail
+ string(BOGUS)
+
+elseif(testname STREQUAL random) # pass
+ string(RANDOM r)
+ message(STATUS "r='${r}'")
+
+elseif(testname STREQUAL toupper_no_variable) # fail
+ string(TOUPPER)
+
+elseif(testname STREQUAL ascii_no_variable) # fail
+ string(ASCII)
+
+elseif(testname STREQUAL ascii_code_too_small) # fail
+ string(ASCII -1 bummer)
+
+elseif(testname STREQUAL ascii_code_too_large) # fail
+ string(ASCII 288 bummer)
+
+elseif(testname STREQUAL configure_no_input) # fail
+ string(CONFIGURE)
+
+elseif(testname STREQUAL configure_no_variable) # fail
+ string(CONFIGURE "this is @testname@")
+
+elseif(testname STREQUAL configure_escape_quotes) # pass
+ string(CONFIGURE "this is @testname@" v ESCAPE_QUOTES)
+ message(STATUS "v='${v}'")
+
+elseif(testname STREQUAL configure_bogus) # fail
+ string(CONFIGURE "this is @testname@" v ESCAPE_QUOTES BOGUS)
+
+elseif(testname STREQUAL regex_no_mode) # fail
+ string(REGEX)
+
+elseif(testname STREQUAL regex_match_not_enough_args) # fail
+ string(REGEX MATCH)
+
+elseif(testname STREQUAL regex_matchall_not_enough_args) # fail
+ string(REGEX MATCHALL)
+
+elseif(testname STREQUAL regex_replace_not_enough_args) # fail
+ string(REGEX REPLACE)
+
+elseif(testname STREQUAL regex_bogus_mode) # fail
+ string(REGEX BOGUS)
+
+elseif(testname STREQUAL regex_match_multiple_inputs) # pass
+ string(REGEX MATCH ".*" v input1 input2 input3 input4)
+ message(STATUS "v='${v}'")
+
+elseif(testname STREQUAL regex_match_bad_regex) # fail
+ string(REGEX MATCH "(.*" v input)
+
+elseif(testname STREQUAL regex_match_empty_string) # fail
+ string(REGEX MATCH "x*" v "")
+
+elseif(testname STREQUAL regex_match_no_match) # pass
+ string(REGEX MATCH "xyz" v "abc")
+ message(STATUS "v='${v}'")
+
+elseif(testname STREQUAL regex_matchall_multiple_inputs) # pass
+ string(REGEX MATCHALL "input" v input1 input2 input3 input4)
+ message(STATUS "v='${v}'")
+
+elseif(testname STREQUAL regex_matchall_bad_regex) # fail
+ string(REGEX MATCHALL "(.*" v input)
+
+elseif(testname STREQUAL regex_matchall_empty_string) # fail
+ string(REGEX MATCHALL "x*" v "")
+
+elseif(testname STREQUAL regex_replace_ends_with_backslash) # fail
+ string(REGEX REPLACE "input" "output\\" v input1 input2 input3 input4)
+
+elseif(testname STREQUAL regex_replace_ends_with_escaped_backslash) # pass
+ string(REGEX REPLACE "input" "output\\\\" v input1 input2 input3 input4)
+ message(STATUS "v='${v}'")
+
+elseif(testname STREQUAL regex_replace_has_linefeed) # pass
+ string(REGEX REPLACE "input" "output\\n" v input1 input2 input3 input4)
+ message(STATUS "v='${v}'")
+
+elseif(testname STREQUAL regex_replace_has_bogus_escape) # fail
+ string(REGEX REPLACE "input" "output\\a" v input1 input2 input3 input4)
+
+elseif(testname STREQUAL regex_replace_bad_regex) # fail
+ string(REGEX REPLACE "this (.*" "with that" v input)
+
+elseif(testname STREQUAL regex_replace_empty_string) # fail
+ string(REGEX REPLACE "x*" "that" v "")
+
+elseif(testname STREQUAL regex_replace_index_too_small) # fail
+ string(REGEX REPLACE "^this (.*)$" "with \\1 \\-1" v "this input")
+
+elseif(testname STREQUAL regex_replace_index_too_large) # fail
+ string(REGEX REPLACE "^this (.*)$" "with \\1 \\2" v "this input")
+
+elseif(testname STREQUAL compare_no_mode) # fail
+ string(COMPARE)
+
+elseif(testname STREQUAL compare_bogus_mode) # fail
+ string(COMPARE BOGUS)
+
+elseif(testname STREQUAL compare_not_enough_args) # fail
+ string(COMPARE EQUAL)
+
+elseif(testname STREQUAL replace_not_enough_args) # fail
+ string(REPLACE)
+
+elseif(testname STREQUAL replace_multiple_inputs) # pass
+ string(REPLACE "input" "output" v input1 input2 input3 input4)
+ message(STATUS "v='${v}'")
+
+elseif(testname STREQUAL substring_not_enough_args) # fail
+ string(SUBSTRING)
+
+elseif(testname STREQUAL substring_begin_too_large) # fail
+ string(SUBSTRING "abcdefg" 25 100 v)
+
+elseif(testname STREQUAL substring_end_too_large) # fail
+ string(SUBSTRING "abcdefg" 1 100 v)
+
+elseif(testname STREQUAL substring_begin_less_than_zero) # fail
+ string(SUBSTRING "abcdefg" -2 4 v)
+
+elseif(testname STREQUAL substring_end_less_than_begin) # fail
+ string(SUBSTRING "abcdefg" 6 3 v)
+
+elseif(testname STREQUAL length_not_enough_args) # fail
+ string(LENGTH)
+
+elseif(testname STREQUAL strip_not_enough_args) # fail
+ string(STRIP)
+
+elseif(testname STREQUAL random_not_enough_args) # fail
+ string(RANDOM)
+
+elseif(testname STREQUAL random_3_args) # fail
+ string(RANDOM LENGTH 9)
+
+elseif(testname STREQUAL random_5_args) # fail
+ string(RANDOM LENGTH 9 ALPHABET "aceimnorsuvwxz")
+
+elseif(testname STREQUAL random_with_length) # pass
+ string(RANDOM LENGTH 9 v)
+ message(STATUS "v='${v}'")
+
+elseif(testname STREQUAL random_with_alphabet) # pass
+ string(RANDOM ALPHABET "aceimnorsuvwxz" v)
+ message(STATUS "v='${v}'")
+
+elseif(testname STREQUAL random_bad_length) # fail
+ string(RANDOM LENGTH 0 v)
+
+elseif(testname STREQUAL random_empty_alphabet) # pass
+ string(RANDOM ALPHABET "" v)
+ message(STATUS "v='${v}'")
+
+elseif(testname STREQUAL random_with_length_and_alphabet) # pass
+ string(RANDOM LENGTH 9 ALPHABET "aceimnorsuvwxz" v)
+ message(STATUS "v='${v}'")
+
+elseif(testname STREQUAL random_with_various_alphabets) # pass
+ # small alphabet
+ string(RANDOM LENGTH 32 ALPHABET "ACGT" v)
+ message(STATUS "v='${v}'")
+
+ # smaller alphabet
+ string(RANDOM LENGTH 32 ALPHABET "AB" v)
+ message(STATUS "v='${v}'")
+
+ # smallest alphabet
+ string(RANDOM LENGTH 32 ALPHABET "Z" v)
+ message(STATUS "v='${v}'")
+
+ # smallest length and alphabet
+ string(RANDOM LENGTH 1 ALPHABET "Q" v)
+ message(STATUS "v='${v}'")
+
+ # seed values -- 2 same, then 1 different
+ string(RANDOM LENGTH 32 ALPHABET "ACGT" RANDOM_SEED 987654 v)
+ message(STATUS "v='${v}'")
+ string(RANDOM LENGTH 32 ALPHABET "ACGT" RANDOM_SEED 987654 v)
+ message(STATUS "v='${v}'")
+ string(RANDOM LENGTH 32 ALPHABET "ACGT" RANDOM_SEED 876543 v)
+ message(STATUS "v='${v}'")
+
+ # alphabet of many colors - use all the crazy keyboard characters
+ string(RANDOM LENGTH 78 ALPHABET "~`!@#$%^&*()_-+={}[]\\|:\\;'\",.<>/?" v)
+ message(STATUS "v='${v}'")
+
+ message(STATUS "CMAKE_SCRIPT_MODE_FILE='${CMAKE_SCRIPT_MODE_FILE}'")
+
+elseif(testname STREQUAL string_find_with_no_parameter) # fail
+ string(FIND)
+
+elseif(testname STREQUAL string_find_with_one_parameter) # fail
+ string(FIND "CMake is great.")
+
+elseif(testname STREQUAL string_find_with_two_parameters) # fail
+ string(FIND "CMake is great." "a")
+
+elseif(testname STREQUAL string_find_with_three_parameters) # pass
+ string(FIND "CMake is great." "a" v)
+ message(STATUS "v='${v}'")
+
+elseif(testname STREQUAL string_find_with_four_parameters) # fail
+ string(FIND "CMake is great." "a" v v2)
+
+elseif(testname STREQUAL string_find_reverse_with_no_parameter) # fail
+ string(FIND REVERSE)
+
+elseif(testname STREQUAL string_find_reverse_with_one_parameter) # fail
+ string(FIND "CMake is great." REVERSE)
+
+elseif(testname STREQUAL string_find_reverse_with_two_parameters) # fail
+ string(FIND "CMake is great." "a" REVERSE)
+
+elseif(testname STREQUAL string_find_reverse_with_three_parameters) # pass
+ string(FIND "CMake is great." "a" v REVERSE)
+ message(STATUS "v='${v}'")
+
+elseif(testname STREQUAL string_find_reverse_with_four_parameters_part1) # fail
+ string(FIND "CMake is great." "a" v v2 REVERSE)
+
+elseif(testname STREQUAL string_find_reverse_with_four_parameters_part2) # fail
+ string(FIND "CMake is great." "a" v REVERSE v2)
+
+elseif(testname STREQUAL string_find_with_no_possible_result) # pass
+ string(FIND "CMake is a great application." "z" v)
+ message(STATUS "v='${v}'")
+ if(NOT(-1 EQUAL ${v}))
+ message(SEND_ERROR "FIND sub-command should return -1 but returned ${v}.")
+ endif(NOT(-1 EQUAL ${v}))
+
+elseif(testname STREQUAL string_find_reverse_with_no_possible_result) # pass
+ string(FIND "CMake is a great application." "z" v REVERSE)
+ message(STATUS "v='${v}'")
+ if(NOT(-1 EQUAL ${v}))
+ message(SEND_ERROR "FIND REVERSE sub-command should return -1 but returned ${v}.")
+ endif(NOT(-1 EQUAL ${v}))
+
+elseif(testname STREQUAL string_find_with_required_result) # pass
+ string(FIND "CMake is a great application." "g" v)
+ message(STATUS "v='${v}'")
+ if(NOT(11 EQUAL ${v}))
+ message(SEND_ERROR "FIND sub-command should return 11 but returned ${v}.")
+ endif(NOT(11 EQUAL ${v}))
+
+elseif(testname STREQUAL string_find_reverse_with_required_result) # pass
+ string(FIND "CMake is a great application." "e" v REVERSE)
+ message(STATUS "v='${v}'")
+ if(NOT(13 EQUAL ${v}))
+ message(SEND_ERROR "FIND REVERSE sub-command should return 13 but returned ${v}.")
+ endif(NOT(13 EQUAL ${v}))
+
+elseif(testname STREQUAL string_find_word_reverse_with_required_result) # pass
+ string(FIND "The command should find REVERSE in this string. Or maybe this REVERSE?!" "REVERSE" v)
+ message(STATUS "v='${v}'")
+ if(NOT(24 EQUAL ${v}))
+ message(SEND_ERROR "FIND sub-command should return 24 but returned ${v}.")
+ endif(NOT(24 EQUAL ${v}))
+
+elseif(testname STREQUAL string_find_reverse_word_reverse_with_required_result) # pass
+ string(FIND "The command should find REVERSE in this string. Or maybe this REVERSE?!" "REVERSE" v REVERSE)
+ message(STATUS "v='${v}'")
+ if(NOT(62 EQUAL ${v}))
+ message(SEND_ERROR "FIND sub-command should return 62 but returned ${v}.")
+ endif(NOT(62 EQUAL ${v}))
+
+else() # fail
+ message(FATAL_ERROR "testname='${testname}' - error: no such test in '${CMAKE_CURRENT_LIST_FILE}'")
+
+endif()
diff --git a/Tests/CMakeTests/ToolchainTest.cmake.in b/Tests/CMakeTests/ToolchainTest.cmake.in
new file mode 100644
index 000000000..e4a2e4813
--- /dev/null
+++ b/Tests/CMakeTests/ToolchainTest.cmake.in
@@ -0,0 +1,139 @@
+############################################################
+# some preparations so that the CMakeDetermineXXX.cmake files will work in scripted mode
+
+# overwrite MARK_AS_ADVANCED(), since this is used in CMakeDetermineCCompiler.cmake
+# which will complain that it can"t be used in script mode
+macro(MARK_AS_ADVANCED)
+endmacro(MARK_AS_ADVANCED)
+# set this to a place where we are allowed to write
+set(CMAKE_PLATFORM_ROOT_BIN "${CMAKE_CURRENT_BINARY_DIR}")
+
+# don't run the compiler detection
+set(CMAKE_C_COMPILER_ID_RUN 1)
+set(CMAKE_CXX_COMPILER_ID_RUN 1)
+
+set(MY_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@")
+
+# at first load CMakeDetermineSystem.cmake without toolchain file
+set(CMAKE_TOOLCHAIN_FILE)
+include(CMakeDetermineSystem)
+
+# check that CMAKE_SYSTEM_XXX and CMAKE_HOST_SYSTEM_xxx are identical
+if(NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "${CMAKE_HOST_SYSTEM_NAME}")
+ message(FATAL_ERROR "CMAKE_SYSTEM_NAME and CMAKE_HOST_SYSTEM_NAME not identical: \"${CMAKE_SYSTEM_NAME}\" vs. \"${CMAKE_HOST_SYSTEM_NAME}\"")
+endif(NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "${CMAKE_HOST_SYSTEM_NAME}")
+
+if(NOT "${CMAKE_SYSTEM}" STREQUAL "${CMAKE_HOST_SYSTEM}")
+ message(FATAL_ERROR "CMAKE_SYSTEM and CMAKE_HOST_SYSTEM not identical: \"${CMAKE_SYSTEM}\" vs. \"${CMAKE_HOST_SYSTEM}\"")
+endif(NOT "${CMAKE_SYSTEM}" STREQUAL "${CMAKE_HOST_SYSTEM}")
+
+if(NOT "${CMAKE_SYSTEM_VERSION}" STREQUAL "${CMAKE_HOST_SYSTEM_VERSION}")
+ message(FATAL_ERROR "CMAKE_SYSTEM_VERSION and CMAKE_HOST_SYSTEM_VERSION not identical: \"${CMAKE_SYSTEM_VERSION}\" vs. \"${CMAKE_HOST_SYSTEM_VERSION}\"")
+endif(NOT "${CMAKE_SYSTEM_VERSION}" STREQUAL "${CMAKE_HOST_SYSTEM_VERSION}")
+
+if(NOT "${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "${CMAKE_HOST_SYSTEM_PROCESSOR}")
+ message(FATAL_ERROR "CMAKE_SYSTEM_PROCESSOR and CMAKE_HOST_SYSTEM_PROCESSOR not identical: \"${CMAKE_SYSTEM_PROCESSOR}\" vs. \"${CMAKE_HOST_SYSTEM_PROCESSOR}\"")
+endif(NOT "${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "${CMAKE_HOST_SYSTEM_PROCESSOR}")
+
+# save the values so we can compare them to CMAKE_HOST_SYSTEM_XXX in the toolchain case
+
+set(NATIVE_SYSTEM "${CMAKE_SYSTEM}")
+set(NATIVE_SYSTEM_NAME "${CMAKE_SYSTEM_NAME}")
+set(NATIVE_SYSTEM_VERSION "${CMAKE_SYSTEM_VERSION}")
+set(NATIVE_SYSTEM_PROCESSOR "${CMAKE_SYSTEM_PROCESSOR}")
+
+# reset them so they will be detected again now
+set(CMAKE_SYSTEM)
+set(CMAKE_SYSTEM_NAME)
+set(CMAKE_SYSTEM_VERSION)
+set(CMAKE_SYSTEM_PROCESSOR)
+set(CMAKE_HOST_SYSTEM)
+set(CMAKE_HOST_SYSTEM_NAME)
+set(CMAKE_HOST_SYSTEM_VERSION)
+set(CMAKE_HOST_SYSTEM_PROCESSOR)
+
+
+############################################################
+
+# now define a toolchain file and check that everything is
+# detected correctly and nothing predefined is overwritten
+
+set(CMAKE_TOOLCHAIN_FILE "${MY_SOURCE_DIR}/DummyToolchain.cmake")
+
+include(CMakeDetermineSystem)
+# make cmake think we are cross compiling for test to work
+set(CMAKE_CROSSCOMPILING TRUE)
+set(CMAKE_C_COMPILER_ID "GNU")
+include(CMakeDetermineCCompiler)
+include(CMakeDetermineCXXCompiler)
+
+#############################################################
+
+# check the results from DetermineSystem
+
+if(NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "Dumdidum")
+ message(FATAL_ERROR "CMAKE_SYSTEM_NAME overwritten: \"${CMAKE_SYSTEM_NAME}\", was: \"Dumdidum\"")
+endif(NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "Dumdidum")
+
+if(NOT "${CMAKE_SYSTEM}" STREQUAL "Dumdidum-1.0")
+ message(FATAL_ERROR "CMAKE_SYSTEM wrong: \"${CMAKE_SYSTEM}\", expected: \"Dumdidum-1.0\"")
+endif(NOT "${CMAKE_SYSTEM}" STREQUAL "Dumdidum-1.0")
+set(fileOne "${_INCLUDED_TOOLCHAIN_FILE}")
+set(fileTwo "${MY_SOURCE_DIR}/DummyToolchain.cmake")
+if(WIN32)
+ string(TOLOWER "${fileOne}" fileOne)
+ string(TOLOWER "${fileTwo}" fileTwo)
+endif(WIN32)
+
+if(NOT "${fileOne}" STREQUAL "${fileTwo}")
+ message(FATAL_ERROR "Wrong toolchain was loaded: \"${fileOne}\" expected \"${fileTwo}\"")
+endif(NOT "${fileOne}" STREQUAL "${fileTwo}")
+
+# check that CMAKE_HOST_SYSTEM_XXX and _SYSTEM_xxx detected above are identical
+if(NOT "${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "${NATIVE_SYSTEM_NAME}")
+ message(FATAL_ERROR "CMAKE_HOST_SYSTEM_NAME and NATIVE_SYSTEM_NAME not identical: \"${CMAKE_HOST_SYSTEM_NAME}\" vs. \"${NATIVE_SYSTEM_NAME}\"")
+endif(NOT "${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "${NATIVE_SYSTEM_NAME}")
+if(NOT "${CMAKE_HOST_SYSTEM}" STREQUAL "${NATIVE_SYSTEM}")
+ message(FATAL_ERROR "CMAKE_HOST_SYSTEM and NATIVE_SYSTEM not identical: \"${CMAKE_HOST_SYSTEM}\" vs. \"${NATIVE_SYSTEM}\"")
+endif(NOT "${CMAKE_HOST_SYSTEM}" STREQUAL "${NATIVE_SYSTEM}")
+if(NOT "${CMAKE_HOST_SYSTEM_VERSION}" STREQUAL "${NATIVE_SYSTEM_VERSION}")
+ message(FATAL_ERROR "CMAKE_HOST_SYSTEM_VERSION and NATIVE_SYSTEM_VERSION not identical: \"${CMAKE_HOST_SYSTEM_VERSION}\" vs. \"${NATIVE_SYSTEM_VERSION}\"")
+endif(NOT "${CMAKE_HOST_SYSTEM_VERSION}" STREQUAL "${NATIVE_SYSTEM_VERSION}")
+if(NOT "${CMAKE_HOST_SYSTEM_PROCESSOR}" STREQUAL "${NATIVE_SYSTEM_PROCESSOR}")
+ message(FATAL_ERROR "CMAKE_HOST_SYSTEM_PROCESSOR and NATIVE_SYSTEM_PROCESSOR not identical: \"${CMAKE_HOST_SYSTEM_PROCESSOR}\" vs. \"${NATIVE_SYSTEM_PROCESSOR}\"")
+endif(NOT "${CMAKE_HOST_SYSTEM_PROCESSOR}" STREQUAL "${NATIVE_SYSTEM_PROCESSOR}")
+
+#############################################################
+
+# check the results from DetermineCCompiler
+
+if(NOT "${_CMAKE_TOOLCHAIN_PREFIX}" STREQUAL "arm-elf-")
+ message(FATAL_ERROR "wrong toolchain prefix detected: \"${_CMAKE_TOOLCHAIN_PREFIX}\", expected: \"arm-elf-\"")
+endif(NOT "${_CMAKE_TOOLCHAIN_PREFIX}" STREQUAL "arm-elf-")
+
+if(NOT "${_CMAKE_USER_C_COMPILER_PATH}" STREQUAL "/opt/foo/bin")
+ message(FATAL_ERROR "wrong C compiler location detected: \"${_CMAKE_USER_C_COMPILER_PATH}\", expected: \"/opt/foo/bin\"")
+endif(NOT "${_CMAKE_USER_C_COMPILER_PATH}" STREQUAL "/opt/foo/bin")
+
+if(NOT "${CMAKE_C_OUTPUT_EXTENSION}" STREQUAL ".foo")
+ message(FATAL_ERROR "C output extension overwritten: \"${CMAKE_C_OUTPUT_EXTENSION}\", was: \".foo\"")
+endif(NOT "${CMAKE_C_OUTPUT_EXTENSION}" STREQUAL ".foo")
+
+#############################################################
+
+# check the results from DetermineCXXCompiler
+
+if(NOT "${_CMAKE_USER_CXX_COMPILER_PATH}" STREQUAL "/opt/bar/bin")
+ message(FATAL_ERROR "wrong CXX compiler location detected: \"${_CMAKE_USER_CXX_COMPILER_PATH}\", expected: \"/opt/bar/bin\"")
+endif(NOT "${_CMAKE_USER_CXX_COMPILER_PATH}" STREQUAL "/opt/bar/bin")
+
+if(NOT "${CMAKE_CXX_OUTPUT_EXTENSION}" STREQUAL ".bar")
+ message(FATAL_ERROR "C output extension overwritten: \"${CMAKE_CXX_OUTPUT_EXTENSION}\", was: \".bar\"")
+endif(NOT "${CMAKE_CXX_OUTPUT_EXTENSION}" STREQUAL ".bar")
+
+message(STATUS "CMAKE_SYSTEM: \"${CMAKE_SYSTEM}\"")
+message(STATUS "_CMAKE_TOOLCHAIN_PREFIX: \"${_CMAKE_TOOLCHAIN_PREFIX}\"")
+message(STATUS "_CMAKE_USER_C_COMPILER_PATH: \"${_CMAKE_USER_C_COMPILER_PATH}\"")
+message(STATUS "_CMAKE_USER_CXX_COMPILER_PATH: \"${_CMAKE_USER_CXX_COMPILER_PATH}\"")
+message(STATUS "CMAKE_C_OUTPUT_EXTENSION: \"${CMAKE_C_OUTPUT_EXTENSION}\"")
+message(STATUS "CMAKE_CXX_OUTPUT_EXTENSION: \"${CMAKE_CXX_OUTPUT_EXTENSION}\"")
diff --git a/Tests/CMakeTests/VariableWatchTest.cmake.in b/Tests/CMakeTests/VariableWatchTest.cmake.in
new file mode 100644
index 000000000..bdb4f7ec4
--- /dev/null
+++ b/Tests/CMakeTests/VariableWatchTest.cmake.in
@@ -0,0 +1,31 @@
+MESSAGE("Start")
+
+VARIABLE_WATCH(TESTVAR MESSAGE)
+VARIABLE_WATCH(TESTVAR1)
+
+macro(testwatch var access file stack)
+ MESSAGE("There was a ${access} access done on the variable: ${var} in file ${file}")
+ MESSAGE("List file stack is: ${stack}")
+ set(${var}_watched 1)
+endmacro(testwatch)
+
+VARIABLE_WATCH(somevar testwatch)
+
+set(TESTVAR1 "1")
+set(TESTVAR "1")
+set(TESTVAR1 "0")
+set(TESTVAR "0")
+
+
+message("Variable: ${somevar}")
+if(NOT somevar_watched)
+ message(SEND_ERROR "'somevar' watch failed!")
+endif()
+set(somevar_watched)
+
+set(somevar "1")
+message("Variable: ${somevar}")
+if(NOT somevar_watched)
+ message(SEND_ERROR "'somevar' watch failed!")
+endif()
+remove(somevar)
diff --git a/Tests/CMakeTests/VersionTest.cmake.in b/Tests/CMakeTests/VersionTest.cmake.in
new file mode 100644
index 000000000..215bb2b96
--- /dev/null
+++ b/Tests/CMakeTests/VersionTest.cmake.in
@@ -0,0 +1,9 @@
+set(min_ver 2.7.20090305)
+cmake_minimum_required(VERSION ${min_ver})
+
+if("${CMAKE_VERSION}" VERSION_LESS "${min_ver}")
+ message(FATAL_ERROR
+ "CMAKE_VERSION=[${CMAKE_VERSION}] is less than [${min_ver}]")
+else()
+ message("CMAKE_VERSION=[${CMAKE_VERSION}] is not less than [${min_ver}]")
+endif()
diff --git a/Tests/CMakeTests/While-Endwhile-Alone-Args.cmake b/Tests/CMakeTests/While-Endwhile-Alone-Args.cmake
new file mode 100644
index 000000000..886d98c7c
--- /dev/null
+++ b/Tests/CMakeTests/While-Endwhile-Alone-Args.cmake
@@ -0,0 +1 @@
+endwhile(a)
diff --git a/Tests/CMakeTests/While-Endwhile-Alone.cmake b/Tests/CMakeTests/While-Endwhile-Alone.cmake
new file mode 100644
index 000000000..82c09a07b
--- /dev/null
+++ b/Tests/CMakeTests/While-Endwhile-Alone.cmake
@@ -0,0 +1 @@
+endwhile()
diff --git a/Tests/CMakeTests/While-Endwhile-Mismatch.cmake b/Tests/CMakeTests/While-Endwhile-Mismatch.cmake
new file mode 100644
index 000000000..5c338d697
--- /dev/null
+++ b/Tests/CMakeTests/While-Endwhile-Mismatch.cmake
@@ -0,0 +1,2 @@
+while(a)
+endwhile(b)
diff --git a/Tests/CMakeTests/While-Missing-Argument.cmake b/Tests/CMakeTests/While-Missing-Argument.cmake
new file mode 100644
index 000000000..32eaa2698
--- /dev/null
+++ b/Tests/CMakeTests/While-Missing-Argument.cmake
@@ -0,0 +1 @@
+while()
diff --git a/Tests/CMakeTests/While-Missing-Endwhile.cmake b/Tests/CMakeTests/While-Missing-Endwhile.cmake
new file mode 100644
index 000000000..1abaaaf2b
--- /dev/null
+++ b/Tests/CMakeTests/While-Missing-Endwhile.cmake
@@ -0,0 +1 @@
+while(a)
diff --git a/Tests/CMakeTests/WhileTest.cmake.in b/Tests/CMakeTests/WhileTest.cmake.in
new file mode 100644
index 000000000..4693f2d8f
--- /dev/null
+++ b/Tests/CMakeTests/WhileTest.cmake.in
@@ -0,0 +1,53 @@
+set(NUMBERS "")
+set(COUNT 0)
+
+while(COUNT LESS 200)
+ set(NUMBERS "${NUMBERS} ${COUNT}")
+ set(COUNT "2${COUNT}")
+
+ set(NCOUNT 3)
+ while(NCOUNT LESS 31)
+ set(NUMBERS "${NUMBERS} ${NCOUNT}")
+ set(NCOUNT "${NCOUNT}0")
+ endwhile()
+endwhile(COUNT LESS 200)
+
+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 (@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 (@CMAKE_CURRENT_SOURCE_DIR@/)?While-Missing-Endwhile.cmake:.*A logical block opening on the line.*(@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 (@CMAKE_CURRENT_SOURCE_DIR@/)?While-Endwhile-Mismatch.cmake:.*A logical block opening on the line.*(@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 (@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 (@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/CMakeTests/include/cmake_i_do_not_exist_in_the_system.h b/Tests/CMakeTests/include/cmake_i_do_not_exist_in_the_system.h
new file mode 100644
index 000000000..2392aee71
--- /dev/null
+++ b/Tests/CMakeTests/include/cmake_i_do_not_exist_in_the_system.h
@@ -0,0 +1 @@
+/* empty header file */
diff --git a/Tests/CMakeWizardTest.cmake b/Tests/CMakeWizardTest.cmake
new file mode 100644
index 000000000..bcae8afeb
--- /dev/null
+++ b/Tests/CMakeWizardTest.cmake
@@ -0,0 +1,52 @@
+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/COnly/CMakeLists.txt b/Tests/COnly/CMakeLists.txt
new file mode 100644
index 000000000..5ef0f1eea
--- /dev/null
+++ b/Tests/COnly/CMakeLists.txt
@@ -0,0 +1,23 @@
+# a simple C only test case
+cmake_minimum_required (VERSION 2.6)
+project (COnly C)
+
+set(CMAKE_DEBUG_POSTFIX "_test_debug_postfix")
+add_library(testc1 STATIC libc1.c)
+add_library(testc2 SHARED libc2.c)
+add_executable (COnly conly.c foo.c foo.h)
+target_link_libraries(COnly testc1 testc2)
+if(MSVC_VERSION)
+ set_target_properties(COnly PROPERTIES
+ LINK_FLAGS " /NODEFAULTLIB:\"libcdg.lib\" /NODEFAULTLIB:\"libcmtg.lib\" /NODEFAULTLIB:\"foomsvcrt.lib\" /NODEFAULTLIB:\"libbar.lib\" /NODEFAULTLIB:\"libfooba.lib\"")
+endif(MSVC_VERSION)
+string(ASCII 35 32 67 77 97 107 101 ASCII_STRING)
+message(STATUS "String: ${ASCII_STRING}")
+get_source_file_property(LANG conly.c LANGUAGE)
+if("${LANG}" STREQUAL "C")
+ message("Language is C")
+else("${LANG}" STREQUAL "C")
+ message(FATAL_ERROR "Bad language for file conly.c")
+endif("${LANG}" STREQUAL "C")
+
+add_library(testCModule MODULE testCModule.c)
diff --git a/Tests/COnly/conly.c b/Tests/COnly/conly.c
new file mode 100644
index 000000000..7214fe1bc
--- /dev/null
+++ b/Tests/COnly/conly.c
@@ -0,0 +1,23 @@
+#include "foo.h"
+
+#include "libc1.h"
+#include "libc2.h"
+
+#include <stdio.h>
+
+int main ()
+{
+ int class = 0;
+ if ( LibC1Func() != 2.0 )
+ {
+ printf("Problem with libc1\n");
+ return 1;
+ }
+ if ( LibC2Func() != 1.0 )
+ {
+ printf("Problem with libc2\n");
+ return 1;
+ }
+ printf("Foo: %s %d\n", foo, class);
+ return 0;
+}
diff --git a/Tests/COnly/foo.c b/Tests/COnly/foo.c
new file mode 100644
index 000000000..e4faf38a3
--- /dev/null
+++ b/Tests/COnly/foo.c
@@ -0,0 +1 @@
+char* foo = "Foo";
diff --git a/Tests/COnly/foo.h b/Tests/COnly/foo.h
new file mode 100644
index 000000000..ad4a9af0f
--- /dev/null
+++ b/Tests/COnly/foo.h
@@ -0,0 +1 @@
+extern char* foo;
diff --git a/Tests/COnly/libc1.c b/Tests/COnly/libc1.c
new file mode 100644
index 000000000..b01e1e1b5
--- /dev/null
+++ b/Tests/COnly/libc1.c
@@ -0,0 +1,4 @@
+float LibC1Func()
+{
+ return 2.0;
+}
diff --git a/Tests/COnly/libc1.h b/Tests/COnly/libc1.h
new file mode 100644
index 000000000..84c94a9cb
--- /dev/null
+++ b/Tests/COnly/libc1.h
@@ -0,0 +1 @@
+extern float LibC1Func();
diff --git a/Tests/COnly/libc2.c b/Tests/COnly/libc2.c
new file mode 100644
index 000000000..0fd895664
--- /dev/null
+++ b/Tests/COnly/libc2.c
@@ -0,0 +1,6 @@
+#include "libc2.h"
+
+float LibC2Func()
+{
+ return 1.0;
+}
diff --git a/Tests/COnly/libc2.h b/Tests/COnly/libc2.h
new file mode 100644
index 000000000..a99d8984e
--- /dev/null
+++ b/Tests/COnly/libc2.h
@@ -0,0 +1,11 @@
+#ifdef _WIN32
+# ifdef testc2_EXPORTS
+# define CM_TEST_LIB_EXPORT __declspec( dllexport )
+# else
+# define CM_TEST_LIB_EXPORT __declspec( dllimport )
+# endif
+#else
+# define CM_TEST_LIB_EXPORT
+#endif
+
+CM_TEST_LIB_EXPORT float LibC2Func();
diff --git a/Tests/COnly/testCModule.c b/Tests/COnly/testCModule.c
new file mode 100644
index 000000000..1a89292b3
--- /dev/null
+++ b/Tests/COnly/testCModule.c
@@ -0,0 +1,6 @@
+#ifdef _WIN32
+# define TEST_EXPORT __declspec(dllexport)
+#else
+# define TEST_EXPORT
+#endif
+TEST_EXPORT int testCModule(void) { return 0; }
diff --git a/Tests/CPackComponents/CMakeLists.txt b/Tests/CPackComponents/CMakeLists.txt
new file mode 100644
index 000000000..58f5bdffe
--- /dev/null
+++ b/Tests/CPackComponents/CMakeLists.txt
@@ -0,0 +1,128 @@
+# 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 that allows
+# users to select which pieces will be installed: the example
+# application, the library binaries, and/or the header file.
+cmake_minimum_required(VERSION 2.6)
+project(CPackComponents)
+
+# Create the mylib library
+add_library(mylib mylib.cpp)
+
+# Create the mylibapp application
+add_executable(mylibapp mylibapp.cpp)
+target_link_libraries(mylibapp mylib)
+
+# On Linux, enable using an absolute install path to verify that
+# CMAKE_INSTALL_PREFIX and CPACK_SET_DESTDIR interact properly.
+#
+# But only use absolute paths if not targeting an NSIS installer
+# as indicated by CPACK_BINARY_NSIS. (If we allow this, the test
+# fails on Linux machines with makensis installed when we are not
+# cross-compiling...)
+#
+if(UNIX AND NOT APPLE)
+ if(NOT CPACK_BINARY_NSIS)
+ set(mylib_install_to_absolute_path ON)
+ endif()
+endif()
+
+if(mylib_install_to_absolute_path)
+ set(CMAKE_INSTALL_PREFIX "/opt/mylib")
+ set(CPACK_SET_DESTDIR ON)
+endif()
+
+# 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 lib
+ COMPONENT libraries)
+install(TARGETS mylibapp
+ RUNTIME
+ DESTINATION bin
+ COMPONENT applications)
+install(FILES mylib.h
+ DESTINATION include
+ COMPONENT headers)
+install(FILES "Issue 7470.html"
+ DESTINATION docs
+ COMPONENT documentation)
+
+if(mylib_install_to_absolute_path)
+ install(FILES mylib.cpp
+ DESTINATION /opt/mylib-source
+ COMPONENT source)
+endif()
+
+# CPack boilerplate for this project
+set(CPACK_PACKAGE_NAME "MyLib")
+set(CPACK_PACKAGE_VENDOR "CMake.org")
+set(CPACK_PACKAGE_CONTACT "somebody@cmake.org")
+set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "MyLib - CPack Component Installation Example")
+set(CPACK_PACKAGE_VERSION "1.0.0")
+set(CPACK_PACKAGE_VERSION_MAJOR "1")
+set(CPACK_PACKAGE_VERSION_MINOR "0")
+set(CPACK_PACKAGE_VERSION_PATCH "0")
+set(CPACK_PACKAGE_INSTALL_DIRECTORY "CPack Component Example")
+
+# Settings used when building NSIS installers
+set(CPACK_NSIS_MENU_LINKS
+ "ftp://ftpserver" "Test Ftp Link"
+ "ftps://ftpsserver" "Test Ftps Link"
+ "http://www.cmake.org" "CMake Web Site"
+ "https://github.com/" "Test Https Link"
+ "mailto:kitware@kitware.com" "Test MailTo Link"
+ "news://newsserver" "Test News Link"
+ )
+
+# Suggested default root for end users of the installer:
+set(CPACK_NSIS_INSTALL_ROOT "C:\\Program Files\\CMake Tests Install Root")
+
+# Include CPack to introduce the appropriate targets
+include(CPack)
+
+# Installation types
+cpack_add_install_type(Full
+ DISPLAY_NAME "Everything")
+cpack_add_install_type(Developer)
+
+# Component groups
+cpack_add_component_group(Runtime)
+cpack_add_component_group(Development
+ EXPANDED
+ DESCRIPTION "All of the tools you'll ever need to develop software")
+
+# Components
+cpack_add_component(applications
+ DISPLAY_NAME "MyLib Application"
+ DESCRIPTION "An 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"
+ GROUP Runtime
+ INSTALL_TYPES Full)
+cpack_add_component(libraries
+ DISPLAY_NAME "Libraries"
+ DESCRIPTION "Static libraries used to build programs with MyLib"
+ GROUP Development
+ INSTALL_TYPES Developer Full)
+cpack_add_component(headers
+ DISPLAY_NAME "C++ Headers"
+ DESCRIPTION "C/C++ header files for use with MyLib"
+ GROUP Development
+ DEPENDS libraries
+ INSTALL_TYPES Developer Full)
+
+if(mylib_install_to_absolute_path)
+ cpack_add_component(source
+ DISPLAY_NAME "C++ Source Files"
+ DESCRIPTION "C/C++ source files to build MyLib"
+ GROUP Development
+ DEPENDS libraries
+ INSTALL_TYPES Developer Full)
+endif()
diff --git a/Tests/CPackComponents/Issue 7470.html b/Tests/CPackComponents/Issue 7470.html
new file mode 100644
index 000000000..12df2c87d
--- /dev/null
+++ b/Tests/CPackComponents/Issue 7470.html
@@ -0,0 +1,9 @@
+<html>
+<body>
+The install rule for this file demonstrates the problem described in<br/>
+CMake issue #7470:<br/>
+<br/>
+<a href="http://public.kitware.com/Bug/view.php?id=7470">
+http://public.kitware.com/Bug/view.php?id=7470</a><br/>
+</body>
+</html>
diff --git a/Tests/CPackComponents/VerifyResult.cmake b/Tests/CPackComponents/VerifyResult.cmake
new file mode 100644
index 000000000..850ec0022
--- /dev/null
+++ b/Tests/CPackComponents/VerifyResult.cmake
@@ -0,0 +1,48 @@
+message(STATUS "=============================================================================")
+message(STATUS "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)")
+message(STATUS "")
+
+if(NOT CPackComponents_BINARY_DIR)
+ message(FATAL_ERROR "CPackComponents_BINARY_DIR not set")
+endif(NOT CPackComponents_BINARY_DIR)
+
+set(expected_file_mask "")
+
+if(WIN32)
+ # Only expect the *.exe installer if it looks like NSIS is
+ # installed on this machine:
+ #
+ find_program(NSIS_MAKENSIS_EXECUTABLE NAMES makensis
+ PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\NSIS]
+ DOC "makensis.exe location"
+ )
+ if(NSIS_MAKENSIS_EXECUTABLE)
+ set(expected_file_mask "${CPackComponents_BINARY_DIR}/MyLib-*.exe")
+ endif(NSIS_MAKENSIS_EXECUTABLE)
+endif(WIN32)
+
+if(APPLE)
+ # Always expect the *.dmg installer - PackageMaker should always
+ # be installed on a development Mac:
+ #
+ set(expected_file_mask "${CPackComponents_BINARY_DIR}/MyLib-*.dmg")
+endif(APPLE)
+
+if(expected_file_mask)
+ set(expected_count 1)
+ file(GLOB expected_file "${expected_file_mask}")
+
+ message(STATUS "expected_count='${expected_count}'")
+ message(STATUS "expected_file='${expected_file}'")
+ message(STATUS "expected_file_mask='${expected_file_mask}'")
+
+ if(NOT expected_file)
+ message(FATAL_ERROR "error: expected_file does not exist: CPackComponents test fails.")
+ endif(NOT expected_file)
+
+ list(LENGTH expected_file actual_count)
+ message(STATUS "actual_count='${actual_count}'")
+ if(NOT actual_count EQUAL expected_count)
+ message(FATAL_ERROR "error: expected_count does not match actual_count: CPackComponents test fails.")
+ endif(NOT actual_count EQUAL expected_count)
+endif(expected_file_mask)
diff --git a/Tests/CPackComponents/mylib.cpp b/Tests/CPackComponents/mylib.cpp
new file mode 100644
index 000000000..8ddac198c
--- /dev/null
+++ b/Tests/CPackComponents/mylib.cpp
@@ -0,0 +1,7 @@
+#include "mylib.h"
+#include "stdio.h"
+
+void mylib_function()
+{
+ printf("This is mylib");
+}
diff --git a/Tests/CPackComponents/mylib.h b/Tests/CPackComponents/mylib.h
new file mode 100644
index 000000000..5d0a822db
--- /dev/null
+++ b/Tests/CPackComponents/mylib.h
@@ -0,0 +1 @@
+void mylib_function();
diff --git a/Tests/CPackComponents/mylibapp.cpp b/Tests/CPackComponents/mylibapp.cpp
new file mode 100644
index 000000000..a438ac77f
--- /dev/null
+++ b/Tests/CPackComponents/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
new file mode 100644
index 000000000..5449d09dc
--- /dev/null
+++ b/Tests/CPackComponentsForAll/CMakeLists.txt
@@ -0,0 +1,123 @@
+# 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.
+#
+# Depending on the CPack generator and on some CPACK_xxx var values
+# the generator may produce a single (NSIS, PackageMaker)
+# or several package files (Archive Generators, RPM, DEB)
+cmake_minimum_required(VERSION 2.8.3.20101130 FATAL_ERROR)
+project(CPackComponentsForAll)
+
+# 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)
+
+# This application does not belong to any component
+# thus (as of cmake 2.8.2) it will be left "uninstalled"
+# by a component-aware installer unless a
+# CPACK_MONOLITHIC_INSTALL=1 is set (at cmake time).
+install(TARGETS mylibapp2
+ RUNTIME
+ DESTINATION bin)
+
+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")
+
+# 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 Unspecified)
+
+# 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")
+
+# Put the components into two different groups: "Runtime" and "Development"
+set(CPACK_COMPONENT_APPLICATIONS_GROUP "Runtime")
+set(CPACK_COMPONENT_LIBRARIES_GROUP "Development")
+set(CPACK_COMPONENT_HEADERS_GROUP "Development")
+
+# Expand the "Development" group by default, since we have so few components.
+# Also, provide this group with a description.
+set(CPACK_COMPONENT_GROUP_DEVELOPMENT_EXPANDED ON)
+set(CPACK_COMPONENT_GROUP_DEVELOPMENT_DESCRIPTION
+ "All of the tools you'll ever need to develop software")
+
+# 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)
+
+# Create two installation types with pre-selected components.
+# The "Developer" installation has just the library and headers,
+# while the "Full" installation has everything.
+set(CPACK_ALL_INSTALL_TYPES Full Developer)
+set(CPACK_INSTALL_TYPE_FULL_DISPLAY_NAME "Everything")
+set(CPACK_COMPONENT_LIBRARIES_INSTALL_TYPES Developer Full)
+set(CPACK_COMPONENT_HEADERS_INSTALL_TYPES Developer Full)
+set(CPACK_COMPONENT_APPLICATIONS_INSTALL_TYPES Full)
+
+# 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 ("${CPackComponentWay}" STREQUAL "default"))
+ # Setup project specific CPack-time CPack Config file.
+ configure_file(${CPackComponentsForAll_SOURCE_DIR}/MyLibCPackConfig-${CPackComponentWay}.cmake.in
+ ${CPackComponentsForAll_BINARY_DIR}/MyLibCPackConfig-${CPackComponentWay}.cmake
+ @ONLY)
+ set(CPACK_PROJECT_CONFIG_FILE ${CPackComponentsForAll_BINARY_DIR}/MyLibCPackConfig-${CPackComponentWay}.cmake)
+endif (NOT ("${CPackComponentWay}" STREQUAL "default"))
+# Include CPack to introduce the appropriate targets
+include(CPack) \ No newline at end of file
diff --git a/Tests/CPackComponentsForAll/MyLibCPackConfig-AllInOne.cmake.in b/Tests/CPackComponentsForAll/MyLibCPackConfig-AllInOne.cmake.in
new file mode 100644
index 000000000..1d203c8d8
--- /dev/null
+++ b/Tests/CPackComponentsForAll/MyLibCPackConfig-AllInOne.cmake.in
@@ -0,0 +1,22 @@
+#
+# Activate component packaging
+#
+if(CPACK_GENERATOR MATCHES "ZIP")
+ set(CPACK_ARCHIVE_COMPONENT_INSTALL "ON")
+endif(CPACK_GENERATOR MATCHES "ZIP")
+
+if(CPACK_GENERATOR MATCHES "RPM")
+ set(CPACK_RPM_COMPONENT_INSTALL "ON")
+endif(CPACK_GENERATOR MATCHES "RPM")
+
+if(CPACK_GENERATOR MATCHES "DEB")
+ set(CPACK_DEB_COMPONENT_INSTALL "ON")
+endif(CPACK_GENERATOR MATCHES "DEB")
+
+#
+# Choose grouping way
+#
+#set(CPACK_COMPONENTS_ALL_GROUPS_IN_ONE_PACKAGE 1)
+#set(CPACK_COMPONENTS_GROUPING)
+#set(CPACK_COMPONENTS_IGNORE_GROUPS 1)
+set(CPACK_COMPONENTS_ALL_IN_ONE_PACKAGE 1)
diff --git a/Tests/CPackComponentsForAll/MyLibCPackConfig-IgnoreGroup.cmake.in b/Tests/CPackComponentsForAll/MyLibCPackConfig-IgnoreGroup.cmake.in
new file mode 100644
index 000000000..9444a1473
--- /dev/null
+++ b/Tests/CPackComponentsForAll/MyLibCPackConfig-IgnoreGroup.cmake.in
@@ -0,0 +1,23 @@
+#
+# Activate component packaging
+#
+if(CPACK_GENERATOR MATCHES "ZIP")
+ set(CPACK_ARCHIVE_COMPONENT_INSTALL "ON")
+endif(CPACK_GENERATOR MATCHES "ZIP")
+
+if(CPACK_GENERATOR MATCHES "RPM")
+ set(CPACK_RPM_COMPONENT_INSTALL "ON")
+ set(CPACK_RPM_applications_PACKAGE_REQUIRES "mylib-libraries")
+endif(CPACK_GENERATOR MATCHES "RPM")
+
+if(CPACK_GENERATOR MATCHES "DEB")
+ set(CPACK_DEB_COMPONENT_INSTALL "ON")
+endif(CPACK_GENERATOR MATCHES "DEB")
+
+#
+# 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) \ No newline at end of file
diff --git a/Tests/CPackComponentsForAll/MyLibCPackConfig-OnePackPerGroup.cmake.in b/Tests/CPackComponentsForAll/MyLibCPackConfig-OnePackPerGroup.cmake.in
new file mode 100644
index 000000000..2d251b363
--- /dev/null
+++ b/Tests/CPackComponentsForAll/MyLibCPackConfig-OnePackPerGroup.cmake.in
@@ -0,0 +1,27 @@
+#
+# Activate component packaging
+#
+if(CPACK_GENERATOR MATCHES "ZIP")
+ set(CPACK_ARCHIVE_COMPONENT_INSTALL "ON")
+endif(CPACK_GENERATOR MATCHES "ZIP")
+
+if(CPACK_GENERATOR MATCHES "RPM")
+ set(CPACK_RPM_COMPONENT_INSTALL "ON")
+ set(CPACK_RPM_Development_PACKAGE_REQUIRES "mylib-Runtime")
+endif(CPACK_GENERATOR MATCHES "RPM")
+
+if(CPACK_GENERATOR MATCHES "DEB")
+ set(CPACK_DEB_COMPONENT_INSTALL "ON")
+endif(CPACK_GENERATOR MATCHES "DEB")
+
+if(CPACK_GENERATOR MATCHES "DragNDrop")
+ set(CPACK_COMPONENTS_GROUPING "ONE_PER_GROUP")
+endif(CPACK_GENERATOR MATCHES "DragNDrop")
+
+#
+# Choose grouping way
+#
+#set(CPACK_COMPONENTS_ALL_GROUPS_IN_ONE_PACKAGE)
+#set(CPACK_COMPONENTS_GROUPING)
+#set(CPACK_COMPONENTS_IGNORE_GROUPS)
+#set(CPACK_COMPONENTS_ALL_IN_ONE_PACKAGE)
diff --git a/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake b/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake
new file mode 100644
index 000000000..e2d343d9f
--- /dev/null
+++ b/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake
@@ -0,0 +1,126 @@
+message(STATUS "=============================================================================")
+message(STATUS "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)")
+message(STATUS "")
+
+if(NOT CPackComponentsForAll_BINARY_DIR)
+ message(FATAL_ERROR "CPackComponentsForAll_BINARY_DIR not set")
+endif(NOT CPackComponentsForAll_BINARY_DIR)
+
+if(NOT CPackGen)
+ message(FATAL_ERROR "CPackGen not set")
+endif(NOT CPackGen)
+get_filename_component(CPACK_LOCATION ${CMAKE_COMMAND} PATH)
+set(CPackCommand "${CPACK_LOCATION}/cpack")
+message("cpack = ${CPackCommand}")
+if(NOT CPackCommand)
+ message(FATAL_ERROR "CPackCommand not set")
+endif(NOT CPackCommand)
+
+if(NOT CPackComponentWay)
+ message(FATAL_ERROR "CPackComponentWay not set")
+endif(NOT CPackComponentWay)
+
+set(expected_file_mask "")
+# The usual default behavior is to expect a single file
+# Then some specific generators (Archive, RPM, ...)
+# May produce several numbers of files depending on
+# CPACK_COMPONENT_xxx values
+set(expected_count 1)
+set(config_type $ENV{CMAKE_CONFIG_TYPE})
+set(config_args )
+if(config_type)
+ set(config_args -C ${config_type})
+endif(config_type)
+set(config_verbose )
+
+if(CPackGen MATCHES "ZIP")
+ set(expected_file_mask "${CPackComponentsForAll_BINARY_DIR}/MyLib-*.zip")
+ if (${CPackComponentWay} STREQUAL "default")
+ set(expected_count 1)
+ elseif (${CPackComponentWay} STREQUAL "OnePackPerGroup")
+ set(expected_count 3)
+ elseif (${CPackComponentWay} STREQUAL "IgnoreGroup")
+ set(expected_count 4)
+ elseif (${CPackComponentWay} STREQUAL "AllInOne")
+ set(expected_count 1)
+ endif ()
+elseif (CPackGen MATCHES "RPM")
+ set(config_verbose -D "CPACK_RPM_PACKAGE_DEBUG=1")
+ set(expected_file_mask "${CPackComponentsForAll_BINARY_DIR}/MyLib-*.rpm")
+ if (${CPackComponentWay} STREQUAL "default")
+ set(expected_count 1)
+ elseif (${CPackComponentWay} STREQUAL "OnePackPerGroup")
+ set(expected_count 3)
+ elseif (${CPackComponentWay} STREQUAL "IgnoreGroup")
+ set(expected_count 4)
+ elseif (${CPackComponentWay} STREQUAL "AllInOne")
+ set(expected_count 1)
+ endif ()
+elseif (CPackGen MATCHES "DEB")
+ set(expected_file_mask "${CPackComponentsForAll_BINARY_DIR}/MyLib-*.deb")
+ if (${CPackComponentWay} STREQUAL "default")
+ set(expected_count 1)
+ elseif (${CPackComponentWay} STREQUAL "OnePackPerGroup")
+ set(expected_count 3)
+ elseif (${CPackComponentWay} STREQUAL "IgnoreGroup")
+ set(expected_count 4)
+ elseif (${CPackComponentWay} STREQUAL "AllInOne")
+ set(expected_count 1)
+ endif ()
+endif()
+
+if(CPackGen MATCHES "DragNDrop")
+ set(expected_file_mask "${CPackComponentsForAll_BINARY_DIR}/MyLib-*.dmg")
+ if (${CPackComponentWay} STREQUAL "default")
+ set(expected_count 1)
+ elseif (${CPackComponentWay} STREQUAL "OnePackPerGroup")
+ set(expected_count 3)
+ elseif (${CPackComponentWay} STREQUAL "IgnoreGroup")
+ set(expected_count 4)
+ elseif (${CPackComponentWay} STREQUAL "AllInOne")
+ set(expected_count 1)
+ endif ()
+endif(CPackGen MATCHES "DragNDrop")
+
+# clean-up previously CPack generated files
+if(expected_file_mask)
+ file(GLOB expected_file "${expected_file_mask}")
+ if (expected_file)
+ file(REMOVE ${expected_file})
+ endif(expected_file)
+endif(expected_file_mask)
+
+message("config_args = ${config_args}")
+message("config_verbose = ${config_verbose}")
+execute_process(COMMAND ${CPackCommand} ${config_verbose} -G ${CPackGen} ${config_args}
+ RESULT_VARIABLE CPack_result
+ OUTPUT_VARIABLE CPack_output
+ ERROR_VARIABLE CPack_error
+ WORKING_DIRECTORY ${CPackComponentsForAll_BINARY_DIR})
+
+if (CPack_result)
+ message(FATAL_ERROR "error: CPack execution went wrong!, CPack_output=${CPack_output}, CPack_error=${CPack_error}")
+else (CPack_result)
+ message(STATUS "CPack_output=${CPack_output}")
+endif(CPack_result)
+
+# Now verify if the number of expected file is OK
+# - using expected_file_mask and
+# - expected_count
+if(expected_file_mask)
+ file(GLOB expected_file "${expected_file_mask}")
+
+ message(STATUS "expected_count='${expected_count}'")
+ message(STATUS "expected_file='${expected_file}'")
+ message(STATUS "expected_file_mask='${expected_file_mask}'")
+
+ if(NOT expected_file)
+ message(FATAL_ERROR "error: expected_file=${expected_file} does not exist: CPackComponentsForAll test fails. (CPack_output=${CPack_output}, CPack_error=${CPack_error}")
+ endif(NOT expected_file)
+
+ list(LENGTH expected_file 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(NOT actual_count EQUAL expected_count)
+endif(expected_file_mask)
diff --git a/Tests/CPackComponentsForAll/mylib.cpp b/Tests/CPackComponentsForAll/mylib.cpp
new file mode 100644
index 000000000..8ddac198c
--- /dev/null
+++ b/Tests/CPackComponentsForAll/mylib.cpp
@@ -0,0 +1,7 @@
+#include "mylib.h"
+#include "stdio.h"
+
+void mylib_function()
+{
+ printf("This is mylib");
+}
diff --git a/Tests/CPackComponentsForAll/mylib.h b/Tests/CPackComponentsForAll/mylib.h
new file mode 100644
index 000000000..5d0a822db
--- /dev/null
+++ b/Tests/CPackComponentsForAll/mylib.h
@@ -0,0 +1 @@
+void mylib_function();
diff --git a/Tests/CPackComponentsForAll/mylibapp.cpp b/Tests/CPackComponentsForAll/mylibapp.cpp
new file mode 100644
index 000000000..a438ac77f
--- /dev/null
+++ b/Tests/CPackComponentsForAll/mylibapp.cpp
@@ -0,0 +1,6 @@
+#include "mylib.h"
+
+int main()
+{
+ mylib_function();
+}
diff --git a/Tests/CPackTestAllGenerators/CMakeLists.txt b/Tests/CPackTestAllGenerators/CMakeLists.txt
new file mode 100644
index 000000000..5eeb7e90b
--- /dev/null
+++ b/Tests/CPackTestAllGenerators/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 2.8)
+project(CPackTestAllGenerators)
+add_subdirectory(../CTestTest/SmallAndFast SmallAndFast)
+install(FILES RunCPack.cmake DESTINATION .)
+include(CPack)
diff --git a/Tests/CPackTestAllGenerators/RunCPack.cmake b/Tests/CPackTestAllGenerators/RunCPack.cmake
new file mode 100644
index 000000000..e0c241ec4
--- /dev/null
+++ b/Tests/CPackTestAllGenerators/RunCPack.cmake
@@ -0,0 +1,55 @@
+if(NOT DEFINED cpack)
+ message(FATAL_ERROR "cpack not defined")
+endif()
+
+if(NOT DEFINED dir)
+ message(FATAL_ERROR "dir not defined")
+endif()
+
+# Analyze 'cpack --help' output for list of available generators:
+#
+execute_process(COMMAND ${cpack} --help
+ RESULT_VARIABLE result
+ OUTPUT_VARIABLE stdout
+ ERROR_VARIABLE stderr
+ WORKING_DIRECTORY ${dir})
+
+string(REPLACE ";" "\\;" stdout "${stdout}")
+string(REPLACE "\n" "E;" stdout "${stdout}")
+
+set(collecting 0)
+set(generators)
+foreach(eline ${stdout})
+ string(REGEX REPLACE "^(.*)E$" "\\1" line "${eline}")
+ if(collecting AND NOT line STREQUAL "")
+ string(REGEX REPLACE "^ ([^ ]+) += (.*)$" "\\1" gen "${line}")
+ string(REGEX REPLACE "^ ([^ ]+) += (.*)$" "\\2" doc "${line}")
+ set(generators ${generators} ${gen})
+ endif()
+ if(line STREQUAL "Generators")
+ set(collecting 1)
+ endif()
+endforeach()
+
+# Call cpack with -G on each available generator. We do not care if this
+# succeeds or not. We expect it *not* to succeed if the underlying packaging
+# tools are not installed on the system... This test is here simply to add
+# coverage for the various cpack generators, even/especially to test ones
+# where the tools are not installed.
+#
+message(STATUS "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)")
+
+message(STATUS "CPack generators='${generators}'")
+
+foreach(g ${generators})
+ message(STATUS "Calling cpack -G ${g}...")
+ execute_process(COMMAND ${cpack} -G ${g}
+ RESULT_VARIABLE result
+ OUTPUT_VARIABLE stdout
+ ERROR_VARIABLE stderr
+ WORKING_DIRECTORY ${dir})
+ message(STATUS "result='${result}'")
+ message(STATUS "stdout='${stdout}'")
+ message(STATUS "stderr='${stderr}'")
+ message(STATUS "")
+endforeach()
diff --git a/Tests/CTestConfig/CMakeLists.txt b/Tests/CTestConfig/CMakeLists.txt
new file mode 100644
index 000000000..f46d89a55
--- /dev/null
+++ b/Tests/CTestConfig/CMakeLists.txt
@@ -0,0 +1,47 @@
+cmake_minimum_required(VERSION 2.8)
+project(CTestConfig)
+
+include(CTest)
+
+
+# We expect this configure to occur through a 'ctest -D Experimental' or a
+# 'ctest -S script.cmake' call.
+#
+# In either case, we expect CMAKE_BUILD_TYPE to be defined for single-configuration
+# build trees and not defined for multi-configuration build trees.
+#
+if(CMAKE_CONFIGURATION_TYPES)
+ # multi-configuration: expect not defined, error if defined
+ if(DEFINED CMAKE_BUILD_TYPE AND NOT CMAKE_BUILD_TYPE STREQUAL "")
+ message(FATAL_ERROR "CMAKE_CONFIGURATION_TYPES='${CMAKE_CONFIGURATION_TYPES}' CMAKE_BUILD_TYPE='${CMAKE_BUILD_TYPE}' is defined and non-empty (but should not be for a multi-configuration generator)")
+ endif()
+else()
+ # single-configuration: expect defined, error if not defined
+ if(NOT DEFINED CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "")
+ message(FATAL_ERROR "CMAKE_BUILD_TYPE is not defined or is empty (but should be defined and non-empty for a single-configuration generator)")
+ endif()
+endif()
+
+
+if(DEFINED CMAKE_BUILD_TYPE AND NOT CMAKE_BUILD_TYPE STREQUAL "")
+ add_definitions(-DCMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE}")
+endif()
+
+add_executable(ctc CTestConfig.cxx)
+
+
+foreach(cfg ${CMAKE_CONFIGURATION_TYPES} ${CMAKE_BUILD_TYPE})
+ add_test(NAME ctc-${cfg} CONFIGURATIONS ${cfg} COMMAND ctc --config $<CONFIGURATION>)
+
+ if(CMAKE_CONFIGURATION_TYPES)
+ set_property(TEST ctc-${cfg}
+ PROPERTY PASS_REGULAR_EXPRESSION "CMAKE_INTDIR is ${cfg}")
+ set_property(TEST ctc-${cfg}
+ PROPERTY FAIL_REGULAR_EXPRESSION "CMAKE_BUILD_TYPE is")
+ else()
+ set_property(TEST ctc-${cfg}
+ PROPERTY PASS_REGULAR_EXPRESSION "CMAKE_BUILD_TYPE is ${cfg}")
+ set_property(TEST ctc-${cfg}
+ PROPERTY FAIL_REGULAR_EXPRESSION "CMAKE_INTDIR is")
+ endif()
+endforeach()
diff --git a/Tests/CTestConfig/CTestConfig.cxx b/Tests/CTestConfig/CTestConfig.cxx
new file mode 100644
index 000000000..49c53241a
--- /dev/null
+++ b/Tests/CTestConfig/CTestConfig.cxx
@@ -0,0 +1,20 @@
+#include <stdio.h>
+
+int main(int argc, const char* argv[])
+{
+ int i = 0;
+ for (; i<argc; ++i)
+ {
+ fprintf(stdout, "%s\n", argv[i]);
+ }
+
+#ifdef CMAKE_BUILD_TYPE
+ fprintf(stdout, "CMAKE_BUILD_TYPE is %s\n", CMAKE_BUILD_TYPE);
+#endif
+
+#ifdef CMAKE_INTDIR
+ fprintf(stdout, "CMAKE_INTDIR is %s\n", CMAKE_INTDIR);
+#endif
+
+ return 0;
+}
diff --git a/Tests/CTestConfig/ScriptWithArgs.cmake b/Tests/CTestConfig/ScriptWithArgs.cmake
new file mode 100644
index 000000000..79896a7fc
--- /dev/null
+++ b/Tests/CTestConfig/ScriptWithArgs.cmake
@@ -0,0 +1,16 @@
+set(CTEST_RUN_CURRENT_SCRIPT 0)
+
+macro(check_arg name expected_value)
+ message("${name}='${${name}}'")
+ if(NOT "${${name}}" STREQUAL "${expected_value}")
+ message(FATAL_ERROR "unexpected ${name} value '${${name}}', expected '${expected_value}'")
+ endif()
+endmacro()
+
+check_arg(arg1 "this")
+check_arg(arg2 "that")
+check_arg(arg3 "the other")
+check_arg(arg4 "this is the fourth")
+check_arg(arg5 "the_fifth")
+check_arg(arg6 "value-with-type")
+check_arg(arg7 "")
diff --git a/Tests/CTestConfig/dashboard.cmake.in b/Tests/CTestConfig/dashboard.cmake.in
new file mode 100644
index 000000000..c7ac21023
--- /dev/null
+++ b/Tests/CTestConfig/dashboard.cmake.in
@@ -0,0 +1,43 @@
+set(CMAKE_CONFIGURATION_TYPES "@CMAKE_CONFIGURATION_TYPES@")
+set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestConfig")
+set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestConfig/@cfg@-dashboard")
+
+file(MAKE_DIRECTORY "${CTEST_BINARY_DIRECTORY}")
+
+get_filename_component(dir "${CMAKE_COMMAND}" PATH)
+set(CMAKE_CTEST_COMMAND "${dir}/ctest")
+
+message("CMAKE_COMMAND='${CMAKE_COMMAND}'")
+message("CMAKE_CTEST_COMMAND='${CMAKE_CTEST_COMMAND}'")
+
+set(arg "")
+if(NOT CMAKE_CONFIGURATION_TYPES)
+ set(arg "-DCMAKE_BUILD_TYPE:STRING=@cfg@")
+endif()
+
+message("cmake initial configure")
+execute_process(COMMAND ${CMAKE_COMMAND}
+ ${arg} -G "@CMAKE_TEST_GENERATOR@" ${CTEST_SOURCE_DIRECTORY}
+ WORKING_DIRECTORY ${CTEST_BINARY_DIRECTORY}
+ RESULT_VARIABLE rv)
+if(NOT rv STREQUAL 0)
+ message(FATAL_ERROR "error calling cmake: rv='${rv}'")
+endif()
+
+
+function(call_ctest arg)
+ message("call_ctest ${arg}")
+ execute_process(COMMAND ${CMAKE_CTEST_COMMAND}
+ -C "@cfg@" -D ${arg} -VV
+ WORKING_DIRECTORY ${CTEST_BINARY_DIRECTORY}
+ RESULT_VARIABLE rv)
+ if(NOT rv STREQUAL 0)
+ message(FATAL_ERROR "error calling ctest: rv='${rv}'")
+ endif()
+endfunction()
+
+
+call_ctest(ExperimentalStart)
+call_ctest(ExperimentalConfigure)
+call_ctest(ExperimentalBuild)
+call_ctest(ExperimentalTest)
diff --git a/Tests/CTestConfig/script.cmake.in b/Tests/CTestConfig/script.cmake.in
new file mode 100644
index 000000000..5ceb7c325
--- /dev/null
+++ b/Tests/CTestConfig/script.cmake.in
@@ -0,0 +1,21 @@
+set(CTEST_CMAKE_GENERATOR "@CMAKE_TEST_GENERATOR@")
+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")
+
+ctest_start(Experimental)
+
+ctest_configure(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE rv)
+if(NOT rv STREQUAL 0)
+ message(FATAL_ERROR "*** error in ctest_configure ***")
+endif()
+
+ctest_build(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE rv)
+if(NOT rv STREQUAL 0)
+ message(FATAL_ERROR "*** error in ctest_build ***")
+endif()
+
+ctest_test(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE rv)
+if(NOT rv STREQUAL 0)
+ message(FATAL_ERROR "*** error in ctest_test ***")
+endif()
diff --git a/Tests/CTestScriptMode/CTestTestScriptMode.cmake.in b/Tests/CTestScriptMode/CTestTestScriptMode.cmake.in
new file mode 100644
index 000000000..0c4394faa
--- /dev/null
+++ b/Tests/CTestScriptMode/CTestTestScriptMode.cmake.in
@@ -0,0 +1,14 @@
+# This script will be executed with ctest -S
+
+# Check that the system name is determined correctly:
+set(CMAKE_CMAKE_SYSTEM_NAME "@CMAKE_SYSTEM_NAME@")
+
+if (NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "${CMAKE_CMAKE_SYSTEM_NAME}")
+ message(FATAL_ERROR "Error: CMAKE_SYSTEM_NAME is \"${CMAKE_SYSTEM_NAME}\", but should be \"@CMAKE_SYSTEM_NAME@\"")
+endif(NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "${CMAKE_CMAKE_SYSTEM_NAME}")
+
+# this seems to be necessary, otherwise ctest complains that these
+# variables are not set:
+set(CTEST_COMMAND "\"@CMAKE_CTEST_COMMAND@\"")
+set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestScriptMode/")
+set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestScriptMode/")
diff --git a/Tests/CTestTest/SmallAndFast/CMakeLists.txt b/Tests/CTestTest/SmallAndFast/CMakeLists.txt
new file mode 100644
index 000000000..85cb30cef
--- /dev/null
+++ b/Tests/CTestTest/SmallAndFast/CMakeLists.txt
@@ -0,0 +1,25 @@
+cmake_minimum_required(VERSION 2.8)
+project(SmallAndFast)
+
+include(CTest)
+
+add_executable(echoargs echoargs.c)
+set_property(SOURCE echoargs.c APPEND PROPERTY LABELS SourceLabel Everything)
+set_property(TARGET echoargs APPEND PROPERTY LABELS TargetLabel Everything)
+
+add_test(test0 echoargs)
+set_property(TEST test0 APPEND PROPERTY LABELS TestLabel 0ArgTest Everything)
+
+add_test(test1 echoargs 1)
+set_property(TEST test1 APPEND PROPERTY LABELS TestLabel 1ArgTest Everything)
+
+add_test(test2 echoargs 1 2)
+set_property(TEST test2 APPEND PROPERTY LABELS TestLabel 2ArgTest Everything)
+
+if(SAF_INTENTIONAL_COMPILE_ERROR)
+ add_executable(ice intentional_compile_error.cxx)
+endif()
+
+if(SAF_INTENTIONAL_COMPILE_WARNING)
+ add_executable(icw intentional_compile_warning.cxx)
+endif()
diff --git a/Tests/CTestTest/SmallAndFast/echoargs.c b/Tests/CTestTest/SmallAndFast/echoargs.c
new file mode 100644
index 000000000..6e17464f7
--- /dev/null
+++ b/Tests/CTestTest/SmallAndFast/echoargs.c
@@ -0,0 +1,11 @@
+#include <stdio.h>
+
+int main(int argc, const char* argv[])
+{
+ int i = 0;
+ for (; i<argc; ++i)
+ {
+ fprintf(stdout, "%s\n", argv[i]);
+ }
+ return 0;
+}
diff --git a/Tests/CTestTest/SmallAndFast/intentional_compile_error.cxx b/Tests/CTestTest/SmallAndFast/intentional_compile_error.cxx
new file mode 100644
index 000000000..a8930cf72
--- /dev/null
+++ b/Tests/CTestTest/SmallAndFast/intentional_compile_error.cxx
@@ -0,0 +1 @@
+garbage - obviously this should not compile as is
diff --git a/Tests/CTestTest/SmallAndFast/intentional_compile_warning.cxx b/Tests/CTestTest/SmallAndFast/intentional_compile_warning.cxx
new file mode 100644
index 000000000..8ea5e404f
--- /dev/null
+++ b/Tests/CTestTest/SmallAndFast/intentional_compile_warning.cxx
@@ -0,0 +1,11 @@
+#include <stdio.h>
+
+int main(int argc, const char* argv[])
+{
+ unsigned int i = 0; // "i<argc" should produce a "signed/unsigned comparison" warning
+ for (; i<argc; ++i)
+ {
+ fprintf(stdout, "%s\n", argv[i]);
+ }
+ return 0;
+}
diff --git a/Tests/CTestTest/test.cmake.in b/Tests/CTestTest/test.cmake.in
new file mode 100644
index 000000000..eac5eab20
--- /dev/null
+++ b/Tests/CTestTest/test.cmake.in
@@ -0,0 +1,68 @@
+# please see common.cmake for more documentation
+###################################################################
+# The values in this section must always be provided
+###################################################################
+
+# 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.
+# They will be appended to DASHBOARD_ROOT
+SET (CTEST_SOURCE_NAME SmallAndFast)
+SET (CTEST_BINARY_NAME SmallAndFastBuild)
+
+# which ctest command to use for running the dashboard
+SET (CTEST_COMMAND
+ "\"${CTEST_EXECUTABLE_NAME}\" --version"
+ "\"${CTEST_EXECUTABLE_NAME}\" -D Experimental -A \"${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}\""
+ )
+
+# what cmake command to use for configuring this dashboard
+GET_FILENAME_COMPONENT(CTEST_EXECUTABLE_PATH "${CTEST_EXECUTABLE_NAME}" PATH)
+SET(CTEST_CMAKE_COMMAND "\"${CTEST_EXECUTABLE_PATH}/cmake\"")
+
+MESSAGE("CTest executable: ${CTEST_EXECUTABLE_NAME}")
+MESSAGE("CMake executable: ${CTEST_CMAKE_COMMAND}")
+
+CTEST_SLEEP(1)
+CTEST_SLEEP(1 1 1)
+
+####################################################################
+# The values in this section are optional you can either
+# have them or leave them commented out
+####################################################################
+
+# should ctest wipe the binary tree before running
+SET (CTEST_START_WITH_EMPTY_BINARY_DIRECTORY TRUE)
+
+# this is the initial cache to use for the binary tree, be careful to escape
+# any quotes inside of this string if you use it
+SET (CTEST_INITIAL_CACHE "
+SITE:STRING=@SITE@
+BUILDNAME:STRING=SmallAndFast-@BUILDNAME@
+CMAKE_GENERATOR:INTERNAL=@CMAKE_GENERATOR@
+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@
+DART_ROOT:PATH=
+MEMORYCHECK_COMMAND:STRING=@MEMORYCHECK_COMMAND@
+MEMORYCHECK_SUPPRESSIONS_FILE:FILEPATH=@MEMORYCHECK_SUPPRESSIONS_FILE@
+MEMORYCHECK_COMMAND_OPTIONS:STRING=@MEMORYCHECK_COMMAND_OPTIONS@
+COVERAGE_COMMAND:FILEPATH=@COVERAGE_COMMAND@
+")
+
+# if you do not want to use the default location for a
+# dashboard then set this variable to the directory
+# the dashboard should be in
+SET (CTEST_DASHBOARD_ROOT "@CMAKE_CURRENT_BINARY_DIR@/Tests/CTestTest")
+
+
+# set any extra envionment varibles here
+SET (CTEST_ENVIRONMENT
+)
+
+SET (CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestTest/SmallAndFast")
+SET (CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestTest/${CTEST_BINARY_NAME}")
diff --git a/Tests/CTestTest2/test.cmake.in b/Tests/CTestTest2/test.cmake.in
new file mode 100644
index 000000000..b58b6397e
--- /dev/null
+++ b/Tests/CTestTest2/test.cmake.in
@@ -0,0 +1,60 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.1)
+
+# Settings:
+SET(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest")
+SET(CTEST_SITE "@SITE@")
+SET(CTEST_BUILD_NAME "KWSys-@BUILDNAME@-CTest2")
+
+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_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
+SET(CTEST_MEMORYCHECK_COMMAND "@MEMORYCHECK_COMMAND@")
+SET(CTEST_MEMORYCHECK_SUPPRESSIONS_FILE "@MEMORYCHECK_SUPPRESSIONS_FILE@")
+SET(CTEST_MEMORYCHECK_COMMAND_OPTIONS "@MEMORYCHECK_COMMAND_OPTIONS@")
+SET(CTEST_COVERAGE_COMMAND "@COVERAGE_COMMAND@")
+SET(CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
+
+# By default, CTESTTEST2_USE_PURIFY is not defined. If you want to run purify
+# on CTestTest2, set CTESTTEST2_USE_PURIFY to ON in CMake's cache.
+SET(CTESTTEST2_USE_PURIFY @CTESTTEST2_USE_PURIFY@)
+IF("${CTEST_MEMORYCHECK_COMMAND}" MATCHES purify AND NOT CTESTTEST2_USE_PURIFY)
+ SET(CTEST_MEMORYCHECK_COMMAND)
+ENDIF()
+
+#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@
+
+# This one is needed for testing advanced ctest features
+CTEST_TEST_KWSYS:BOOL=ON
+")
+
+CTEST_START(Experimental)
+#CTEST_UPDATE(SOURCE "${CTEST_SOURCE_DIRECTORY}" RETURN_VALUE res)
+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 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_MEMCHECK(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res STRIDE 1.5)
+CTEST_COVERAGE(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
+
+set(CTEST_DROP_METHOD "@protocol@")
+set(CTEST_DROP_SITE "@server@")
+set(CTEST_DROP_LOCATION "@path@/submit.php?project=PublicDashboard")
+
+CTEST_SUBMIT(RETURN_VALUE res)
+
+# Test submission of a subset of parts.
+SET(CTEST_EXTRA_SUBMIT_FILES ${CTEST_NOTES_FILES})
+CTEST_SUBMIT(RETURN_VALUE res PARTS ExtraFiles)
+SET(CTEST_EXTRA_SUBMIT_FILES)
diff --git a/Tests/CTestTestBadExe/CMakeLists.txt b/Tests/CTestTestBadExe/CMakeLists.txt
new file mode 100644
index 000000000..8a925b62f
--- /dev/null
+++ b/Tests/CTestTestBadExe/CMakeLists.txt
@@ -0,0 +1,7 @@
+cmake_minimum_required (VERSION 2.6)
+PROJECT(CTestTestBadExe)
+INCLUDE(CTest)
+
+CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/notAnExe.txt" "${CMAKE_CURRENT_BINARY_DIR}/notAnExe.txt" COPYONLY)
+
+ADD_TEST (TestBadExe "${CMAKE_CURRENT_BINARY_DIR}/notAnExe.txt")
diff --git a/Tests/CTestTestBadExe/CTestConfig.cmake b/Tests/CTestTestBadExe/CTestConfig.cmake
new file mode 100644
index 000000000..1d46ea3e7
--- /dev/null
+++ b/Tests/CTestTestBadExe/CTestConfig.cmake
@@ -0,0 +1,7 @@
+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_CDASH TRUE)
diff --git a/Tests/CTestTestBadExe/notAnExe.txt b/Tests/CTestTestBadExe/notAnExe.txt
new file mode 100644
index 000000000..f2a0aa4a3
--- /dev/null
+++ b/Tests/CTestTestBadExe/notAnExe.txt
@@ -0,0 +1 @@
+This is not an executable file.
diff --git a/Tests/CTestTestBadExe/test.cmake.in b/Tests/CTestTestBadExe/test.cmake.in
new file mode 100644
index 000000000..5d22d3587
--- /dev/null
+++ b/Tests/CTestTestBadExe/test.cmake.in
@@ -0,0 +1,21 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.1)
+
+# Settings:
+SET(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest")
+SET(CTEST_SITE "@SITE@")
+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_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/CTestTestChecksum/test.cmake.in b/Tests/CTestTestChecksum/test.cmake.in
new file mode 100644
index 000000000..84135446f
--- /dev/null
+++ b/Tests/CTestTestChecksum/test.cmake.in
@@ -0,0 +1,25 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.1)
+
+# Settings:
+SET(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest")
+SET(CTEST_SITE "@SITE@")
+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_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 PARALLEL_LEVEL 4)
+
+SET(CTEST_DROP_METHOD "@protocol@")
+SET(CTEST_DROP_SITE "@server@")
+SET(CTEST_DROP_LOCATION "@path@/submit.php?project=PublicDashboard")
+
+CTEST_SUBMIT(RETRY_DELAY 3 RETRY_COUNT 2 INTERNAL_TEST_CHECKSUM RETURN_VALUE res)
diff --git a/Tests/CTestTestConfigFileInBuildDir/CMakeLists.txt b/Tests/CTestTestConfigFileInBuildDir/CMakeLists.txt
new file mode 100644
index 000000000..3c53e6623
--- /dev/null
+++ b/Tests/CTestTestConfigFileInBuildDir/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8)
+project(CTestTestConfigFileInBuildDir)
+include(CTest)
diff --git a/Tests/CTestTestConfigFileInBuildDir/CTestConfig.cmake b/Tests/CTestTestConfigFileInBuildDir/CTestConfig.cmake
new file mode 100644
index 000000000..d2c28f98c
--- /dev/null
+++ b/Tests/CTestTestConfigFileInBuildDir/CTestConfig.cmake
@@ -0,0 +1,7 @@
+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
new file mode 100644
index 000000000..498cab280
--- /dev/null
+++ b/Tests/CTestTestConfigFileInBuildDir/test1.cmake.in
@@ -0,0 +1,17 @@
+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_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
new file mode 100644
index 000000000..d359f2d36
--- /dev/null
+++ b/Tests/CTestTestConfigFileInBuildDir/test2.cmake.in
@@ -0,0 +1,17 @@
+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_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/CMakeLists.txt b/Tests/CTestTestCostSerial/CMakeLists.txt
new file mode 100644
index 000000000..a9a5c2594
--- /dev/null
+++ b/Tests/CTestTestCostSerial/CMakeLists.txt
@@ -0,0 +1,13 @@
+CMAKE_MINIMUM_REQUIRED (VERSION 2.6)
+PROJECT (CTestTestCostSerial)
+INCLUDE (CTest)
+
+ADD_EXECUTABLE (Sleep sleep.c)
+
+FOREACH (index RANGE 1 3)
+ ADD_TEST (TestSleep${index} Sleep)
+ENDFOREACH (index RANGE 1 3)
+
+SET_TESTS_PROPERTIES(TestSleep1 PROPERTIES COST -500)
+SET_TESTS_PROPERTIES(TestSleep2 PROPERTIES COST 12)
+SET_TESTS_PROPERTIES(TestSleep3 PROPERTIES COST 0)
diff --git a/Tests/CTestTestCostSerial/CTestConfig.cmake b/Tests/CTestTestCostSerial/CTestConfig.cmake
new file mode 100644
index 000000000..05c20eb4b
--- /dev/null
+++ b/Tests/CTestTestCostSerial/CTestConfig.cmake
@@ -0,0 +1,7 @@
+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_CDASH TRUE)
diff --git a/Tests/CTestTestCostSerial/sleep.c b/Tests/CTestTestCostSerial/sleep.c
new file mode 100644
index 000000000..cb9f87ab2
--- /dev/null
+++ b/Tests/CTestTestCostSerial/sleep.c
@@ -0,0 +1,16 @@
+#if defined(_WIN32)
+# include <windows.h>
+#else
+# include <unistd.h>
+#endif
+
+/* sleeps for 1 second */
+int main(int argc, char** argv)
+{
+#if defined(_WIN32)
+ Sleep(1000);
+#else
+ sleep(1);
+#endif
+ return 0;
+}
diff --git a/Tests/CTestTestCostSerial/test.cmake.in b/Tests/CTestTestCostSerial/test.cmake.in
new file mode 100644
index 000000000..ca216e3fc
--- /dev/null
+++ b/Tests/CTestTestCostSerial/test.cmake.in
@@ -0,0 +1,28 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.1)
+
+# Settings:
+SET(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest")
+SET(CTEST_SITE "@SITE@")
+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_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})
+
+# Remove old cost data file if it exists
+IF(EXISTS "${CTEST_BINARY_DIRECTORY}/Testing/Temporary/CTestCostData.txt")
+ FILE(REMOVE "${CTEST_BINARY_DIRECTORY}/Testing/Temporary/CTestCostData.txt")
+ENDIF(EXISTS "${CTEST_BINARY_DIRECTORY}/Testing/Temporary/CTestCostData.txt")
+
+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)
+# Run test set a second time to make sure they run in same specified order
+CTEST_TEST(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
diff --git a/Tests/CTestTestCrash/CMakeLists.txt b/Tests/CTestTestCrash/CMakeLists.txt
new file mode 100644
index 000000000..0ac6ba03c
--- /dev/null
+++ b/Tests/CTestTestCrash/CMakeLists.txt
@@ -0,0 +1,7 @@
+cmake_minimum_required (VERSION 2.6)
+PROJECT(CTestTestCrash)
+INCLUDE(CTest)
+
+ADD_EXECUTABLE (Crash crash.cxx)
+
+ADD_TEST (TestCrash Crash)
diff --git a/Tests/CTestTestCrash/CTestConfig.cmake b/Tests/CTestTestCrash/CTestConfig.cmake
new file mode 100644
index 000000000..e1c5b1b6f
--- /dev/null
+++ b/Tests/CTestTestCrash/CTestConfig.cmake
@@ -0,0 +1,7 @@
+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_CDASH TRUE)
diff --git a/Tests/CTestTestCrash/crash.cxx b/Tests/CTestTestCrash/crash.cxx
new file mode 100644
index 000000000..bc9e096e4
--- /dev/null
+++ b/Tests/CTestTestCrash/crash.cxx
@@ -0,0 +1,6 @@
+//causes a segfault
+int main()
+{
+ int* ptr = 0;
+ *ptr = 1;
+}
diff --git a/Tests/CTestTestCrash/test.cmake.in b/Tests/CTestTestCrash/test.cmake.in
new file mode 100644
index 000000000..5cec594cd
--- /dev/null
+++ b/Tests/CTestTestCrash/test.cmake.in
@@ -0,0 +1,22 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.1)
+
+# Settings:
+SET(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest")
+SET(CTEST_SITE "@SITE@")
+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_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)
+#CTEST_SUBMIT()
diff --git a/Tests/CTestTestCycle/CMakeLists.txt b/Tests/CTestTestCycle/CMakeLists.txt
new file mode 100644
index 000000000..6ba6b8c95
--- /dev/null
+++ b/Tests/CTestTestCycle/CMakeLists.txt
@@ -0,0 +1,13 @@
+cmake_minimum_required (VERSION 2.6)
+project(CTestTestCycle)
+include(CTest)
+
+add_executable (simple simple.cxx)
+add_test (one simple)
+add_test (two simple)
+add_test (three simple)
+
+# Add cyclical test dependency
+set_tests_properties(one PROPERTIES DEPENDS "two")
+set_tests_properties(two PROPERTIES DEPENDS "three")
+set_tests_properties(three PROPERTIES DEPENDS "one")
diff --git a/Tests/CTestTestCycle/CTestConfig.cmake b/Tests/CTestTestCycle/CTestConfig.cmake
new file mode 100644
index 000000000..43e99863a
--- /dev/null
+++ b/Tests/CTestTestCycle/CTestConfig.cmake
@@ -0,0 +1,7 @@
+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_CDASH TRUE)
diff --git a/Tests/CTestTestCycle/simple.cxx b/Tests/CTestTestCycle/simple.cxx
new file mode 100644
index 000000000..766b7751b
--- /dev/null
+++ b/Tests/CTestTestCycle/simple.cxx
@@ -0,0 +1,5 @@
+
+int main()
+{
+ return 0;
+}
diff --git a/Tests/CTestTestCycle/test.cmake.in b/Tests/CTestTestCycle/test.cmake.in
new file mode 100644
index 000000000..201f6044e
--- /dev/null
+++ b/Tests/CTestTestCycle/test.cmake.in
@@ -0,0 +1,19 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.1)
+
+# Settings:
+SET(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest")
+SET(CTEST_SITE "@SITE@")
+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_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/CTestTestDepends/CMakeLists.txt b/Tests/CTestTestDepends/CMakeLists.txt
new file mode 100644
index 000000000..26367a658
--- /dev/null
+++ b/Tests/CTestTestDepends/CMakeLists.txt
@@ -0,0 +1,12 @@
+cmake_minimum_required (VERSION 2.6)
+project(CTestTestDepends)
+include(CTest)
+
+add_executable (simple simple.cxx)
+add_test (one simple)
+add_test (two simple)
+add_test (three simple)
+
+# Add redundant (but not cyclical) dependencies
+set_tests_properties(two PROPERTIES DEPENDS "one")
+set_tests_properties(three PROPERTIES DEPENDS "one;two")
diff --git a/Tests/CTestTestDepends/CTestConfig.cmake b/Tests/CTestTestDepends/CTestConfig.cmake
new file mode 100644
index 000000000..e3af7dd8d
--- /dev/null
+++ b/Tests/CTestTestDepends/CTestConfig.cmake
@@ -0,0 +1,7 @@
+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_CDASH TRUE)
diff --git a/Tests/CTestTestDepends/simple.cxx b/Tests/CTestTestDepends/simple.cxx
new file mode 100644
index 000000000..766b7751b
--- /dev/null
+++ b/Tests/CTestTestDepends/simple.cxx
@@ -0,0 +1,5 @@
+
+int main()
+{
+ return 0;
+}
diff --git a/Tests/CTestTestDepends/test.cmake.in b/Tests/CTestTestDepends/test.cmake.in
new file mode 100644
index 000000000..36a1ebf87
--- /dev/null
+++ b/Tests/CTestTestDepends/test.cmake.in
@@ -0,0 +1,19 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.1)
+
+# 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/CTestTestDepends")
+SET(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestTestDepends")
+SET(CTEST_CVS_COMMAND "@CVSCOMMAND@")
+SET(CTEST_CMAKE_GENERATOR "@CMAKE_TEST_GENERATOR@")
+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/CTestTestFailedSubmits/test.cmake.in b/Tests/CTestTestFailedSubmits/test.cmake.in
new file mode 100644
index 000000000..b0e16322d
--- /dev/null
+++ b/Tests/CTestTestFailedSubmits/test.cmake.in
@@ -0,0 +1,47 @@
+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_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/CMakeLists.txt b/Tests/CTestTestFailure/CMakeLists.txt
new file mode 100644
index 000000000..690fbfc5c
--- /dev/null
+++ b/Tests/CTestTestFailure/CMakeLists.txt
@@ -0,0 +1,8 @@
+cmake_minimum_required (VERSION 2.6)
+PROJECT(CTestTestFailure)
+INCLUDE(CTest)
+
+ADD_EXECUTABLE (NoBuild badCode.cxx)
+TARGET_LINK_LIBRARIES (NoBuild ${EXTRA_LIBS})
+
+ADD_TEST (TestNoExe NoBuild)
diff --git a/Tests/CTestTestFailure/CTestConfig.cmake b/Tests/CTestTestFailure/CTestConfig.cmake
new file mode 100644
index 000000000..fd8d97acf
--- /dev/null
+++ b/Tests/CTestTestFailure/CTestConfig.cmake
@@ -0,0 +1,7 @@
+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_CDASH TRUE)
diff --git a/Tests/CTestTestFailure/badCode.cxx b/Tests/CTestTestFailure/badCode.cxx
new file mode 100644
index 000000000..b410f0a13
--- /dev/null
+++ b/Tests/CTestTestFailure/badCode.cxx
@@ -0,0 +1,4 @@
+int main()
+{
+this code will not compile
+}
diff --git a/Tests/CTestTestFailure/testNoBuild.cmake.in b/Tests/CTestTestFailure/testNoBuild.cmake.in
new file mode 100644
index 000000000..7bc921a31
--- /dev/null
+++ b/Tests/CTestTestFailure/testNoBuild.cmake.in
@@ -0,0 +1,21 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.1)
+
+# Settings:
+SET(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest")
+SET(CTEST_SITE "@SITE@")
+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_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_UPDATE(SOURCE "${CTEST_SOURCE_DIRECTORY}" RETURN_VALUE res)
+CTEST_CONFIGURE(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
+CTEST_BUILD(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
diff --git a/Tests/CTestTestFailure/testNoExe.cmake.in b/Tests/CTestTestFailure/testNoExe.cmake.in
new file mode 100644
index 000000000..59c18d752
--- /dev/null
+++ b/Tests/CTestTestFailure/testNoExe.cmake.in
@@ -0,0 +1,19 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.1)
+
+# Settings:
+SET(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest")
+SET(CTEST_SITE "@SITE@")
+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_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_TEST(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
diff --git a/Tests/CTestTestParallel/CMakeLists.txt b/Tests/CTestTestParallel/CMakeLists.txt
new file mode 100644
index 000000000..fc53f6874
--- /dev/null
+++ b/Tests/CTestTestParallel/CMakeLists.txt
@@ -0,0 +1,15 @@
+cmake_minimum_required (VERSION 2.6)
+PROJECT(CTestTestParallel)
+INCLUDE(CTest)
+
+ADD_EXECUTABLE (LockFile lockFile.c)
+
+ADD_TEST (TestRunSerial1 LockFile)
+ADD_TEST (TestRunSerial2 LockFile)
+SET_TESTS_PROPERTIES(TestRunSerial1 TestRunSerial2 PROPERTIES RUN_SERIAL true)
+
+ADD_TEST (TestProcessorsGreaterThanMPL1 LockFile)
+ADD_TEST (TestProcessorsGreaterThanMPL2 LockFile)
+SET_TESTS_PROPERTIES(TestProcessorsGreaterThanMPL1 PROPERTIES PROCESSORS 10)
+SET_TESTS_PROPERTIES(TestProcessorsGreaterThanMPL1 PROPERTIES DEPENDS
+ TestProcessorsGreaterThanMPL2)
diff --git a/Tests/CTestTestParallel/CTestConfig.cmake b/Tests/CTestTestParallel/CTestConfig.cmake
new file mode 100644
index 000000000..c3c503881
--- /dev/null
+++ b/Tests/CTestTestParallel/CTestConfig.cmake
@@ -0,0 +1,7 @@
+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_CDASH TRUE)
diff --git a/Tests/CTestTestParallel/lockFile.c b/Tests/CTestTestParallel/lockFile.c
new file mode 100644
index 000000000..6a6a889cc
--- /dev/null
+++ b/Tests/CTestTestParallel/lockFile.c
@@ -0,0 +1,20 @@
+#include <stdio.h>
+
+/*if run serially, works fine.
+ If run in parallel, someone will attempt to delete
+ a locked file, which will fail */
+int main(void)
+{
+ FILE* file;
+ int i;
+ const char* fname = "lockedFile.txt";
+ file = fopen(fname, "w");
+
+ for(i = 0; i < 10000; i++)
+ {
+ fprintf(file, "%s", "x");
+ fflush(file);
+ }
+ fclose(file);
+ return remove(fname);
+}
diff --git a/Tests/CTestTestParallel/test.cmake.in b/Tests/CTestTestParallel/test.cmake.in
new file mode 100644
index 000000000..83845dee4
--- /dev/null
+++ b/Tests/CTestTestParallel/test.cmake.in
@@ -0,0 +1,21 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.1)
+
+# Settings:
+SET(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest")
+SET(CTEST_SITE "@SITE@")
+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_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 PARALLEL_LEVEL 4)
diff --git a/Tests/CTestTestResourceLock/CMakeLists.txt b/Tests/CTestTestResourceLock/CMakeLists.txt
new file mode 100644
index 000000000..1041ef149
--- /dev/null
+++ b/Tests/CTestTestResourceLock/CMakeLists.txt
@@ -0,0 +1,13 @@
+cmake_minimum_required (VERSION 2.6)
+PROJECT(CTestTestResourceLock)
+INCLUDE(CTest)
+
+ADD_EXECUTABLE (LockFile lockFile.c)
+
+ADD_TEST (TestLockedFile1.1 LockFile locked1.txt)
+ADD_TEST (TestLockedFile1.2 LockFile locked1.txt)
+SET_TESTS_PROPERTIES(TestLockedFile1.1 TestLockedFile1.2 PROPERTIES RESOURCE_LOCK "locked1.txt")
+
+ADD_TEST (TestLockedFile2.1 LockFile locked2.txt)
+ADD_TEST (TestLockedFile2.2 LockFile locked2.txt)
+SET_TESTS_PROPERTIES(TestLockedFile2.1 TestLockedFile2.2 PROPERTIES RESOURCE_LOCK "locked2.txt")
diff --git a/Tests/CTestTestResourceLock/CTestConfig.cmake b/Tests/CTestTestResourceLock/CTestConfig.cmake
new file mode 100644
index 000000000..5fb560b87
--- /dev/null
+++ b/Tests/CTestTestResourceLock/CTestConfig.cmake
@@ -0,0 +1,7 @@
+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_CDASH TRUE)
diff --git a/Tests/CTestTestResourceLock/lockFile.c b/Tests/CTestTestResourceLock/lockFile.c
new file mode 100644
index 000000000..a6a4dc0f4
--- /dev/null
+++ b/Tests/CTestTestResourceLock/lockFile.c
@@ -0,0 +1,31 @@
+#include <stdio.h>
+
+/* Disable deprecation warning for fopen */
+#pragma warning(disable: 4996)
+
+/*if run serially, works fine.
+ If run in parallel, someone will attempt to delete
+ a locked file, which will fail */
+int main(int argc, char** argv)
+{
+ FILE* file;
+ int i;
+ const char* fname;
+ if(argc >= 2)
+ {
+ fname = argv[1];
+ }
+ else
+ {
+ fname = "lockedFile.txt";
+ }
+ file = fopen(fname, "w");
+
+ for(i = 0; i < 10000; i++)
+ {
+ fprintf(file, "%s", "x");
+ fflush(file);
+ }
+ fclose(file);
+ return remove(fname);
+}
diff --git a/Tests/CTestTestResourceLock/test.cmake.in b/Tests/CTestTestResourceLock/test.cmake.in
new file mode 100644
index 000000000..98c5901c4
--- /dev/null
+++ b/Tests/CTestTestResourceLock/test.cmake.in
@@ -0,0 +1,19 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.1)
+
+# Settings:
+SET(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest")
+SET(CTEST_SITE "@SITE@")
+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_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 PARALLEL_LEVEL 4)
diff --git a/Tests/CTestTestRunScript/hello.cmake.in b/Tests/CTestTestRunScript/hello.cmake.in
new file mode 100644
index 000000000..140df1e02
--- /dev/null
+++ b/Tests/CTestTestRunScript/hello.cmake.in
@@ -0,0 +1,2 @@
+SET(CTEST_RUN_CURRENT_SCRIPT 0)
+MESSAGE("hello world")
diff --git a/Tests/CTestTestRunScript/test.cmake.in b/Tests/CTestTestRunScript/test.cmake.in
new file mode 100644
index 000000000..8301a56d3
--- /dev/null
+++ b/Tests/CTestTestRunScript/test.cmake.in
@@ -0,0 +1,2 @@
+SET(CTEST_RUN_CURRENT_SCRIPT 0)
+CTEST_RUN_SCRIPT("CTestTestRunScript/hello.cmake" RETURN_VALUE res RETURN_VALUE)
diff --git a/Tests/CTestTestScheduler/CMakeLists.txt b/Tests/CTestTestScheduler/CMakeLists.txt
new file mode 100644
index 000000000..882988fd4
--- /dev/null
+++ b/Tests/CTestTestScheduler/CMakeLists.txt
@@ -0,0 +1,9 @@
+CMAKE_MINIMUM_REQUIRED (VERSION 2.6)
+PROJECT (CTestTestScheduler)
+INCLUDE (CTest)
+
+ADD_EXECUTABLE (Sleep sleep.c)
+
+FOREACH (time RANGE 1 4)
+ ADD_TEST (TestSleep${time} Sleep ${time})
+ENDFOREACH (time RANGE 1 4)
diff --git a/Tests/CTestTestScheduler/CTestConfig.cmake b/Tests/CTestTestScheduler/CTestConfig.cmake
new file mode 100644
index 000000000..7da8f6f53
--- /dev/null
+++ b/Tests/CTestTestScheduler/CTestConfig.cmake
@@ -0,0 +1,7 @@
+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_CDASH TRUE)
diff --git a/Tests/CTestTestScheduler/sleep.c b/Tests/CTestTestScheduler/sleep.c
new file mode 100644
index 000000000..9631a68dc
--- /dev/null
+++ b/Tests/CTestTestScheduler/sleep.c
@@ -0,0 +1,21 @@
+#if defined(_WIN32)
+# include <windows.h>
+#else
+# include <unistd.h>
+#endif
+
+/* sleeps for 4n seconds, where n is the argument to the program */
+int main(int argc, char** argv)
+{
+ int time;
+ if(argc > 1)
+ {
+ time = 4 * atoi(argv[1]);
+ }
+#if defined(_WIN32)
+ Sleep(time * 1000);
+#else
+ sleep(time);
+#endif
+ return 0;
+}
diff --git a/Tests/CTestTestScheduler/test.cmake.in b/Tests/CTestTestScheduler/test.cmake.in
new file mode 100644
index 000000000..505bd7c5b
--- /dev/null
+++ b/Tests/CTestTestScheduler/test.cmake.in
@@ -0,0 +1,28 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.1)
+
+# Settings:
+SET(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest")
+SET(CTEST_SITE "@SITE@")
+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_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})
+
+# Remove old cost data file if it exists
+IF(EXISTS "${CTEST_BINARY_DIRECTORY}/Testing/Temporary/CTestCostData.txt")
+ FILE(REMOVE "${CTEST_BINARY_DIRECTORY}/Testing/Temporary/CTestCostData.txt")
+ENDIF(EXISTS "${CTEST_BINARY_DIRECTORY}/Testing/Temporary/CTestCostData.txt")
+
+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 PARALLEL_LEVEL 5)
+# Run test set a second time to make sure they run in reverse order
+CTEST_TEST(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res PARALLEL_LEVEL 5)
diff --git a/Tests/CTestTestStopTime/CMakeLists.txt b/Tests/CTestTestStopTime/CMakeLists.txt
new file mode 100644
index 000000000..5fe30d352
--- /dev/null
+++ b/Tests/CTestTestStopTime/CMakeLists.txt
@@ -0,0 +1,11 @@
+cmake_minimum_required (VERSION 2.6)
+PROJECT(CTestTestStopTime)
+INCLUDE(CTest)
+
+ADD_EXECUTABLE (Sleep sleep.c)
+
+ADD_TEST (TestSleep Sleep 30)
+ADD_TEST (ShouldNotRun Sleep 30)
+
+SET_TESTS_PROPERTIES(ShouldNotRun PROPERTIES DEPENDS TestSleep)
+SET_TESTS_PROPERTIES(ShouldNotRun PROPERTIES WILL_FAIL ON)
diff --git a/Tests/CTestTestStopTime/CTestConfig.cmake b/Tests/CTestTestStopTime/CTestConfig.cmake
new file mode 100644
index 000000000..129db4dea
--- /dev/null
+++ b/Tests/CTestTestStopTime/CTestConfig.cmake
@@ -0,0 +1,7 @@
+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_CDASH TRUE)
diff --git a/Tests/CTestTestStopTime/GetDate.cmake b/Tests/CTestTestStopTime/GetDate.cmake
new file mode 100644
index 000000000..b79330691
--- /dev/null
+++ b/Tests/CTestTestStopTime/GetDate.cmake
@@ -0,0 +1,233 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.2)
+
+MACRO(GET_DATE)
+ #
+ # All macro arguments are optional.
+ # If there's an ARGV0, use it as GD_PREFIX. Default = 'GD_'
+ # If there's an ARGV1, use it as ${GD_PREFIX}VERBOSE. Default = '0'
+ #
+ # If the date can be retrieved and parsed successfully, this macro
+ # will set the following CMake variables:
+ #
+ # GD_PREFIX
+ # ${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
+ # ${GD_PREFIX}MONTH
+ # ${GD_PREFIX}DAY
+ # ${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...
+ #
+
+ # If there's an ARGV0, use it as GD_PREFIX:
+ #
+ SET(GD_PREFIX "GD_")
+ IF(NOT "${ARGV0}" STREQUAL "")
+ SET(GD_PREFIX "${ARGV0}")
+ ENDIF(NOT "${ARGV0}" STREQUAL "")
+ IF(NOT "${GD_PREFIX}" STREQUAL "GD_")
+ SET(${GD_PREFIX}PREFIX "${GD_PREFIX}")
+ ENDIF(NOT "${GD_PREFIX}" STREQUAL "GD_")
+
+ # If there's an ARGV1, use it as ${GD_PREFIX}VERBOSE:
+ #
+ SET(${GD_PREFIX}VERBOSE "0")
+ IF(NOT "${ARGV1}" STREQUAL "")
+ SET(${GD_PREFIX}VERBOSE "${ARGV1}")
+ ENDIF(NOT "${ARGV1}" STREQUAL "")
+
+ # 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
+ #
+ # 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(WIN32)
+ #
+ # 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(WIN32)
+
+ EXEC_PROGRAM("${${GD_PREFIX}CMD}" "." ARGS "${${GD_PREFIX}ARGS}"
+ OUTPUT_VARIABLE ${GD_PREFIX}OV RETURN_VALUE ${GD_PREFIX}RV
+ )
+
+ IF(${GD_PREFIX}VERBOSE)
+ MESSAGE(STATUS "")
+ MESSAGE(STATUS "<GET_DATE>")
+ MESSAGE(STATUS "")
+ MESSAGE(STATUS "GD_PREFIX='${GD_PREFIX}'")
+ IF(NOT "${GD_PREFIX}" STREQUAL "GD_")
+ MESSAGE(STATUS "${GD_PREFIX}PREFIX='${${GD_PREFIX}PREFIX}'")
+ ENDIF(NOT "${GD_PREFIX}" STREQUAL "GD_")
+ 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(${GD_PREFIX}VERBOSE)
+
+ 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(NOT "${${GD_PREFIX}YEAR}" MATCHES "^[0-9][0-9][0-9][0-9]$")
+
+ # 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(${${GD_PREFIX}MONTH} GREATER 12)
+
+ # 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(${${GD_PREFIX}DAY} GREATER 31)
+
+ # 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(${${GD_PREFIX}HOUR} GREATER 23)
+
+ # 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(${${GD_PREFIX}MINUTE} GREATER 59)
+
+ # 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(${${GD_PREFIX}SECOND} GREATER 59)
+
+ # 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("${${GD_PREFIX}YEAR}" MATCHES "^[0-9]$")
+ IF("${${GD_PREFIX}MONTH}" MATCHES "^[0-9]$")
+ SET(${GD_PREFIX}MONTH "0${${GD_PREFIX}MONTH}")
+ ENDIF("${${GD_PREFIX}MONTH}" MATCHES "^[0-9]$")
+ IF("${${GD_PREFIX}DAY}" MATCHES "^[0-9]$")
+ SET(${GD_PREFIX}DAY "0${${GD_PREFIX}DAY}")
+ ENDIF("${${GD_PREFIX}DAY}" MATCHES "^[0-9]$")
+ IF("${${GD_PREFIX}HOUR}" MATCHES "^[0-9]$")
+ SET(${GD_PREFIX}HOUR "0${${GD_PREFIX}HOUR}")
+ ENDIF("${${GD_PREFIX}HOUR}" MATCHES "^[0-9]$")
+ IF("${${GD_PREFIX}MINUTE}" MATCHES "^[0-9]$")
+ SET(${GD_PREFIX}MINUTE "0${${GD_PREFIX}MINUTE}")
+ ENDIF("${${GD_PREFIX}MINUTE}" MATCHES "^[0-9]$")
+ IF("${${GD_PREFIX}SECOND}" MATCHES "^[0-9]$")
+ SET(${GD_PREFIX}SECOND "0${${GD_PREFIX}SECOND}")
+ ENDIF("${${GD_PREFIX}SECOND}" MATCHES "^[0-9]$")
+
+ 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(${GD_PREFIX}VERBOSE)
+ ELSE("${${GD_PREFIX}RV}" STREQUAL "0")
+ 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}'")
+ ENDIF("${${GD_PREFIX}RV}" STREQUAL "0")
+
+ IF(${GD_PREFIX}VERBOSE)
+ MESSAGE(STATUS "</GET_DATE>")
+ MESSAGE(STATUS "")
+ ENDIF(${GD_PREFIX}VERBOSE)
+ENDMACRO(GET_DATE)
+
+MACRO(ADD_SECONDS sec)
+ set(new_min ${${GD_PREFIX}MINUTE})
+ set(new_hr ${${GD_PREFIX}HOUR})
+ math(EXPR new_sec "${sec} + ${${GD_PREFIX}SECOND}")
+ while(${new_sec} GREATER 60 OR ${new_sec} EQUAL 60)
+ math(EXPR new_sec "${new_sec} - 60")
+ math(EXPR new_min "${${GD_PREFIX}MINUTE} + 1")
+ endwhile()
+ while(${new_min} GREATER 60 OR ${new_min} EQUAL 60)
+ math(EXPR new_min "${new_min} - 60")
+ math(EXPR new_hr "${${GD_PREFIX}HOUR} + 1")
+ endwhile()
+ math(EXPR new_hr "${new_hr} % 24")
+
+ # Pad the H, M, S if needed
+ string(LENGTH ${new_sec} sec_len)
+ string(LENGTH ${new_min} min_len)
+ string(LENGTH ${new_hr} hr_len)
+ if(${sec_len} EQUAL 1)
+ set(new_sec "0${new_sec}")
+ endif()
+ if(${min_len} EQUAL 1)
+ set(new_min "0${new_min}")
+ endif()
+ if(${hr_len} EQUAL 1)
+ set(new_hr "0${new_hr}")
+ endif()
+ENDMACRO(ADD_SECONDS)
diff --git a/Tests/CTestTestStopTime/sleep.c b/Tests/CTestTestStopTime/sleep.c
new file mode 100644
index 000000000..b5896474b
--- /dev/null
+++ b/Tests/CTestTestStopTime/sleep.c
@@ -0,0 +1,21 @@
+#if defined(_WIN32)
+# include <windows.h>
+#else
+# include <unistd.h>
+#endif
+
+/* sleeps for n seconds, where n is the argument to the program */
+int main(int argc, char** argv)
+{
+ int time;
+ if(argc > 1)
+ {
+ time = atoi(argv[1]);
+ }
+#if defined(_WIN32)
+ Sleep(time * 1000);
+#else
+ sleep(time);
+#endif
+ return 0;
+}
diff --git a/Tests/CTestTestStopTime/test.cmake.in b/Tests/CTestTestStopTime/test.cmake.in
new file mode 100644
index 000000000..2d03686e6
--- /dev/null
+++ b/Tests/CTestTestStopTime/test.cmake.in
@@ -0,0 +1,31 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.1)
+
+# Settings:
+SET(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest")
+SET(CTEST_SITE "@SITE@")
+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_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})
+
+INCLUDE("${CTEST_BINARY_DIRECTORY}/GetDate.cmake")
+
+CTEST_START(Experimental)
+CTEST_CONFIGURE(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
+CTEST_BUILD(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
+
+GET_DATE()
+message("curr time: ${${GD_PREFIX}HOUR}:${${GD_PREFIX}MINUTE}:${${GD_PREFIX}SECOND}")
+ADD_SECONDS(15)
+message("stop time: ${new_hr}:${new_min}:${new_sec}")
+
+CTEST_TEST(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res STOP_TIME "${new_hr}:${new_min}:${new_sec}")
+
+#CTEST_SUBMIT()
diff --git a/Tests/CTestTestSubdir/CMakeLists.txt b/Tests/CTestTestSubdir/CMakeLists.txt
new file mode 100644
index 000000000..5400ee8c5
--- /dev/null
+++ b/Tests/CTestTestSubdir/CMakeLists.txt
@@ -0,0 +1,7 @@
+cmake_minimum_required (VERSION 2.6)
+PROJECT(CTestTestSubdir)
+INCLUDE(CTest)
+
+ADD_SUBDIRECTORY(subdir)
+SUBDIRS(subdir2)
+SUBDIRS("${CTestTestSubdir_SOURCE_DIR}/subdir3")
diff --git a/Tests/CTestTestSubdir/CTestConfig.cmake b/Tests/CTestTestSubdir/CTestConfig.cmake
new file mode 100644
index 000000000..4b848aa26
--- /dev/null
+++ b/Tests/CTestTestSubdir/CTestConfig.cmake
@@ -0,0 +1,7 @@
+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_CDASH TRUE)
diff --git a/Tests/CTestTestSubdir/subdir/CMakeLists.txt b/Tests/CTestTestSubdir/subdir/CMakeLists.txt
new file mode 100644
index 000000000..b40d316d6
--- /dev/null
+++ b/Tests/CTestTestSubdir/subdir/CMakeLists.txt
@@ -0,0 +1,2 @@
+ADD_EXECUTABLE (main main.c)
+ADD_TEST (TestMain1 main)
diff --git a/Tests/CTestTestSubdir/subdir/main.c b/Tests/CTestTestSubdir/subdir/main.c
new file mode 100644
index 000000000..8488f4e58
--- /dev/null
+++ b/Tests/CTestTestSubdir/subdir/main.c
@@ -0,0 +1,4 @@
+int main(void)
+{
+ return 0;
+}
diff --git a/Tests/CTestTestSubdir/subdir2/CMakeLists.txt b/Tests/CTestTestSubdir/subdir2/CMakeLists.txt
new file mode 100644
index 000000000..23f8e07c2
--- /dev/null
+++ b/Tests/CTestTestSubdir/subdir2/CMakeLists.txt
@@ -0,0 +1,2 @@
+ADD_EXECUTABLE (main2 main.c)
+ADD_TEST (TestMain2 main2)
diff --git a/Tests/CTestTestSubdir/subdir2/main.c b/Tests/CTestTestSubdir/subdir2/main.c
new file mode 100644
index 000000000..8488f4e58
--- /dev/null
+++ b/Tests/CTestTestSubdir/subdir2/main.c
@@ -0,0 +1,4 @@
+int main(void)
+{
+ return 0;
+}
diff --git a/Tests/CTestTestSubdir/subdir3/CMakeLists.txt b/Tests/CTestTestSubdir/subdir3/CMakeLists.txt
new file mode 100644
index 000000000..9a44b12b8
--- /dev/null
+++ b/Tests/CTestTestSubdir/subdir3/CMakeLists.txt
@@ -0,0 +1,2 @@
+ADD_EXECUTABLE (main3 main.c)
+ADD_TEST (TestMain3 main3)
diff --git a/Tests/CTestTestSubdir/subdir3/main.c b/Tests/CTestTestSubdir/subdir3/main.c
new file mode 100644
index 000000000..8488f4e58
--- /dev/null
+++ b/Tests/CTestTestSubdir/subdir3/main.c
@@ -0,0 +1,4 @@
+int main(void)
+{
+ return 0;
+}
diff --git a/Tests/CTestTestSubdir/test.cmake.in b/Tests/CTestTestSubdir/test.cmake.in
new file mode 100644
index 000000000..f240473ee
--- /dev/null
+++ b/Tests/CTestTestSubdir/test.cmake.in
@@ -0,0 +1,21 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.1)
+
+# Settings:
+SET(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest")
+SET(CTEST_SITE "@SITE@")
+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_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/CTestTestTimeout/CMakeLists.txt b/Tests/CTestTestTimeout/CMakeLists.txt
new file mode 100644
index 000000000..0fd1cebb3
--- /dev/null
+++ b/Tests/CTestTestTimeout/CMakeLists.txt
@@ -0,0 +1,28 @@
+cmake_minimum_required (VERSION 2.8)
+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()
+ENDIF()
+
+ADD_DEFINITIONS(-DTIMEOUT=${TIMEOUT})
+ADD_EXECUTABLE (Timeout timeout.c)
+
+ADD_TEST(NAME TestTimeout
+ COMMAND ${CMAKE_COMMAND} -D Timeout=$<TARGET_FILE:Timeout>
+ -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)
diff --git a/Tests/CTestTestTimeout/CTestConfig.cmake b/Tests/CTestTestTimeout/CTestConfig.cmake
new file mode 100644
index 000000000..76d62ad27
--- /dev/null
+++ b/Tests/CTestTestTimeout/CTestConfig.cmake
@@ -0,0 +1,7 @@
+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_CDASH TRUE)
diff --git a/Tests/CTestTestTimeout/check.cmake b/Tests/CTestTestTimeout/check.cmake
new file mode 100644
index 000000000..b16f2aab9
--- /dev/null
+++ b/Tests/CTestTestTimeout/check.cmake
@@ -0,0 +1,9 @@
+# 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/test.cmake.in b/Tests/CTestTestTimeout/test.cmake.in
new file mode 100644
index 000000000..8a8dc24e5
--- /dev/null
+++ b/Tests/CTestTestTimeout/test.cmake.in
@@ -0,0 +1,25 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.1)
+
+# Settings:
+SET(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest")
+SET(CTEST_SITE "@SITE@")
+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_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})
+
+FILE(WRITE "${CTEST_BINARY_DIRECTORY}/CMakeCache.txt" "
+TIMEOUT:STRING=@CTestTestTimeout_TIME@
+")
+
+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/CTestTestTimeout/timeout.c b/Tests/CTestTestTimeout/timeout.c
new file mode 100644
index 000000000..370ab22ed
--- /dev/null
+++ b/Tests/CTestTestTimeout/timeout.c
@@ -0,0 +1,18 @@
+#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
new file mode 100644
index 000000000..198cc9713
--- /dev/null
+++ b/Tests/CTestTestTimeout/timeout.cmake
@@ -0,0 +1,6 @@
+# Remove the log file.
+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})
diff --git a/Tests/CTestTestUpload/CMakeLists.txt b/Tests/CTestTestUpload/CMakeLists.txt
new file mode 100644
index 000000000..bc164b10c
--- /dev/null
+++ b/Tests/CTestTestUpload/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required (VERSION 2.6)
+PROJECT(CTestTestUpload)
+
+add_executable (Sleep sleep.c)
diff --git a/Tests/CTestTestUpload/CTestConfig.cmake b/Tests/CTestTestUpload/CTestConfig.cmake
new file mode 100644
index 000000000..89c5b9474
--- /dev/null
+++ b/Tests/CTestTestUpload/CTestConfig.cmake
@@ -0,0 +1,7 @@
+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_CDASH TRUE)
diff --git a/Tests/CTestTestUpload/sleep.c b/Tests/CTestTestUpload/sleep.c
new file mode 100644
index 000000000..b5896474b
--- /dev/null
+++ b/Tests/CTestTestUpload/sleep.c
@@ -0,0 +1,21 @@
+#if defined(_WIN32)
+# include <windows.h>
+#else
+# include <unistd.h>
+#endif
+
+/* sleeps for n seconds, where n is the argument to the program */
+int main(int argc, char** argv)
+{
+ int time;
+ if(argc > 1)
+ {
+ time = atoi(argv[1]);
+ }
+#if defined(_WIN32)
+ Sleep(time * 1000);
+#else
+ sleep(time);
+#endif
+ return 0;
+}
diff --git a/Tests/CTestTestUpload/test.cmake.in b/Tests/CTestTestUpload/test.cmake.in
new file mode 100644
index 000000000..acfa233bc
--- /dev/null
+++ b/Tests/CTestTestUpload/test.cmake.in
@@ -0,0 +1,17 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.1)
+
+# Settings:
+SET(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest")
+SET(CTEST_SITE "@SITE@")
+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_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
+
+CTEST_START(Experimental)
+CTEST_CONFIGURE(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
+CTEST_BUILD(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
+CTEST_UPLOAD(FILES "${CTEST_SOURCE_DIRECTORY}/sleep.c" "${CTEST_BINARY_DIRECTORY}/CMakeCache.txt")
+CTEST_SUBMIT()
diff --git a/Tests/CTestTestZeroTimeout/CMakeLists.txt b/Tests/CTestTestZeroTimeout/CMakeLists.txt
new file mode 100644
index 000000000..8a5246db1
--- /dev/null
+++ b/Tests/CTestTestZeroTimeout/CMakeLists.txt
@@ -0,0 +1,8 @@
+CMAKE_MINIMUM_REQUIRED (VERSION 2.6)
+PROJECT (CTestTestZeroTimeout)
+INCLUDE (CTest)
+
+ADD_EXECUTABLE (Sleep sleep.c)
+
+ADD_TEST (TestExplicitZeroTimeout Sleep)
+SET_TESTS_PROPERTIES(TestExplicitZeroTimeout PROPERTIES TIMEOUT 0)
diff --git a/Tests/CTestTestZeroTimeout/CTestConfig.cmake b/Tests/CTestTestZeroTimeout/CTestConfig.cmake
new file mode 100644
index 000000000..f8e06093d
--- /dev/null
+++ b/Tests/CTestTestZeroTimeout/CTestConfig.cmake
@@ -0,0 +1,7 @@
+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_CDASH TRUE)
diff --git a/Tests/CTestTestZeroTimeout/sleep.c b/Tests/CTestTestZeroTimeout/sleep.c
new file mode 100644
index 000000000..d40d59d97
--- /dev/null
+++ b/Tests/CTestTestZeroTimeout/sleep.c
@@ -0,0 +1,16 @@
+#if defined(_WIN32)
+# include <windows.h>
+#else
+# include <unistd.h>
+#endif
+
+/* sleeps for 5 seconds */
+int main(int argc, char** argv)
+{
+#if defined(_WIN32)
+ Sleep(5000);
+#else
+ sleep(5);
+#endif
+ return 0;
+}
diff --git a/Tests/CTestTestZeroTimeout/test.cmake.in b/Tests/CTestTestZeroTimeout/test.cmake.in
new file mode 100644
index 000000000..56bae9d17
--- /dev/null
+++ b/Tests/CTestTestZeroTimeout/test.cmake.in
@@ -0,0 +1,20 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.1)
+
+# Settings:
+SET(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest")
+SET(CTEST_SITE "@SITE@")
+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_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
+SET(CTEST_COVERAGE_COMMAND "@COVERAGE_COMMAND@")
+SET(CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
+SET(CTEST_TEST_TIMEOUT 2)
+
+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/CTestUpdateBZR.cmake.in b/Tests/CTestUpdateBZR.cmake.in
new file mode 100644
index 000000000..c654f477a
--- /dev/null
+++ b/Tests/CTestUpdateBZR.cmake.in
@@ -0,0 +1,153 @@
+# This script drives creation of a bzr 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(TOP "${TOP}/@CTestUpdateBZR_DIR@")
+
+# Include code common to all update tests.
+include("@CMAKE_CURRENT_SOURCE_DIR@/CTestUpdateCommon.cmake")
+
+#-----------------------------------------------------------------------------
+# Report bzr tools in use.
+message("Using BZR tools:")
+set(BZR "@BZR_EXECUTABLE@")
+message(" bzr = ${BZR}")
+
+#-----------------------------------------------------------------------------
+# Initialize the testing directory.
+message("Creating test directory...")
+init_testing()
+
+#-----------------------------------------------------------------------------
+# Create the repository.
+message("Creating repository...")
+file(MAKE_DIRECTORY ${TOP}/repo.bzr)
+run_child(
+ WORKING_DIRECTORY ${TOP}/repo.bzr
+ COMMAND ${BZR} init
+ )
+set(REPO file://${TOP}/repo.bzr)
+
+#-----------------------------------------------------------------------------
+# Import initial content into the repository.
+message("Importing content...")
+create_content(import)
+
+# Import the content into the repository.
+run_child(WORKING_DIRECTORY ${TOP}/import
+ COMMAND ${BZR} init
+ )
+run_child(WORKING_DIRECTORY ${TOP}/import
+ COMMAND ${BZR} whoami --branch "Test Author <testauthor@cmake.org>"
+ )
+
+run_child(WORKING_DIRECTORY ${TOP}/import
+ COMMAND ${BZR} add .
+ )
+run_child(WORKING_DIRECTORY ${TOP}/import
+ COMMAND ${BZR} commit -m "Initial content"
+ )
+run_child(WORKING_DIRECTORY ${TOP}/import
+ COMMAND ${BZR} push --create-prefix "${REPO}"
+ )
+
+#-----------------------------------------------------------------------------
+# Create a working tree.
+message("Checking out revision 1...")
+run_child(
+ WORKING_DIRECTORY ${TOP}
+ COMMAND ${BZR} branch "${REPO}" user-source
+ )
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${BZR} whoami --branch "Test Author <testauthor@cmake.org>"
+ )
+
+#-----------------------------------------------------------------------------
+# Make changes in the working tree.
+message("Changing content...")
+update_content(user-source files_added files_removed dirs_added)
+if(dirs_added)
+ run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${BZR} add ${dirs_added}
+ )
+endif(dirs_added)
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${BZR} add ${files_added}
+ )
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${BZR} rm ${files_removed}
+ )
+
+#-----------------------------------------------------------------------------
+# Commit the changes to the repository.
+message("Committing revision 2...")
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${BZR} commit -m "Changed content"
+ )
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${BZR} push "${REPO}"
+ )
+
+#-----------------------------------------------------------------------------
+# Make changes in the working tree.
+message("Changing content again...")
+change_content(user-source)
+
+#-----------------------------------------------------------------------------
+# Commit the changes to the repository.
+message("Committing revision 3...")
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${BZR} commit -m "Changed content again"
+ )
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${BZR} push "${REPO}"
+ )
+
+#-----------------------------------------------------------------------------
+# 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 ${BZR} pull --overwrite -r1
+ )
+
+# Create a modified file.
+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
+ "# BZR command configuration
+UpdateCommand: ${BZR}
+")
+
+# Run the dashboard command line interface.
+run_dashboard_command_line(user-binary)
+
+#-----------------------------------------------------------------------------
+# Test initial checkout and update with a dashboard script.
+message("Running CTest Dashboard Script...")
+
+create_dashboard_script(dash-binary
+ "# bzr command configuration
+set(CTEST_BZR_COMMAND \"${BZR}\")
+set(CTEST_CHECKOUT_COMMAND
+ \"\\\"\${CTEST_BZR_COMMAND}\\\" branch -r1 \\\"${REPO}\\\" dash-source\")
+")
+
+# Run the dashboard script with CTest.
+run_dashboard_script(dash-binary)
diff --git a/Tests/CTestUpdateCVS.cmake.in b/Tests/CTestUpdateCVS.cmake.in
new file mode 100644
index 000000000..f7f5db65d
--- /dev/null
+++ b/Tests/CTestUpdateCVS.cmake.in
@@ -0,0 +1,172 @@
+# This script drives creation of a CVS 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(TOP "${TOP}/@CTestUpdateCVS_DIR@")
+set(UPDATE_NOT_GLOBAL 1)
+set(UPDATE_MAYBE Updated{CTestConfig.cmake})
+
+# Include code common to all update tests.
+include("@CMAKE_CURRENT_SOURCE_DIR@/CTestUpdateCommon.cmake")
+
+#-----------------------------------------------------------------------------
+# Report CVS tools in use.
+message("Using CVS tools:")
+set(CVS "@CVS_EXECUTABLE@")
+message(" cvs = ${CVS}")
+
+set(REPO ${TOP}/repo)
+
+# The MSYS cvs tool interprets "c:/" as a "machine:" name for SSH.
+# Detect the MSYS cvs and convert the repo path to an MSYS path.
+if(WIN32)
+ if(EXISTS "${CVS}")
+ file(STRINGS "${CVS}" cvs_is_msys LIMIT_COUNT 1 REGEX "[Mm][Ss][Yy][Ss]")
+ if(cvs_is_msys)
+ message(" '${CVS}' is from MSYS (contains '${cvs_is_msys}')")
+ string(REGEX REPLACE "^([A-Za-z]):" "/\\1" REPO "${REPO}")
+ endif()
+ endif()
+endif()
+
+set(CVSCMD ${CVS} -d${REPO})
+
+# CVSNT requires an extra option to 'cvs init'.
+set(CVS_INIT_OPT)
+execute_process(
+ COMMAND ${CVS} --version
+ RESULT_VARIABLE RESULT
+ OUTPUT_VARIABLE OUTPUT
+ ERROR_VARIABLE OUTPUT
+ )
+if("${RESULT}" STREQUAL "0" AND "${OUTPUT}" MATCHES "\\(CVSNT\\)")
+ set(CVS_INIT_OPT -n)
+ message(" cvs init needs -n")
+endif()
+
+#-----------------------------------------------------------------------------
+# Initialize the testing directory.
+message("Creating test directory...")
+init_testing()
+
+#-----------------------------------------------------------------------------
+# Create the repository.
+message("Creating repository...")
+file(MAKE_DIRECTORY ${TOP}/repo)
+run_child(
+ COMMAND ${CVSCMD} init ${CVS_INIT_OPT}
+ )
+
+#-----------------------------------------------------------------------------
+# Import initial content into the repository.
+message("Importing content...")
+create_content(import)
+
+# Import the content into the repository.
+run_child(
+ WORKING_DIRECTORY ${TOP}/import
+ COMMAND ${CVSCMD} import -m "Initial content" Project vendor-tag release-tag
+ )
+
+#-----------------------------------------------------------------------------
+# Create a working tree.
+message("Checking out revision 1...")
+run_child(
+ WORKING_DIRECTORY ${TOP}
+ COMMAND ${CVSCMD} co -d user-source Project
+ )
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${CVSCMD} tag Revision1
+ )
+
+#-----------------------------------------------------------------------------
+# Make changes in the working tree.
+message("Changing content...")
+update_content(user-source files_added files_removed dirs_added)
+if(dirs_added)
+ run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${CVSCMD} add ${dirs_added}
+ )
+endif(dirs_added)
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${CVSCMD} add ${files_added}
+ )
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${CVSCMD} rm ${files_removed}
+ )
+
+#-----------------------------------------------------------------------------
+# Commit the changes to the repository.
+message("Committing revision 2...")
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${CVSCMD} commit -m "Changed content"
+ )
+
+#-----------------------------------------------------------------------------
+# Make changes in the working tree.
+message("Changing content again...")
+change_content(user-source)
+
+#-----------------------------------------------------------------------------
+# Commit the changes to the repository.
+message("Committing revision 3...")
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${CVSCMD} commit -m "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 ${CVSCMD} up -rRevision1
+ )
+
+# Delay 1 second so the modification produces a newer time stamp.
+find_program(SLEEP sleep)
+if(SLEEP)
+ message("Delaying...")
+ execute_process(COMMAND ${SLEEP} 1)
+endif()
+
+# Create a modified file.
+message("Modifying locally...")
+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
+ "# CVS command configuration
+CVSCommand: ${CVS}
+CVSUpdateOptions: -dAP
+")
+
+# Run the dashboard command line interface.
+run_dashboard_command_line(user-binary)
+
+#-----------------------------------------------------------------------------
+# Test initial checkout and update with a dashboard script.
+message("Running CTest Dashboard Script...")
+
+create_dashboard_script(dash-binary
+ "# CVS command configuration
+set(CTEST_CVS_COMMAND \"${CVS}\")
+set(CTEST_CVS_UPDATE_OPTIONS -dAP)
+set(CTEST_CHECKOUT_COMMAND
+ \"\\\"\${CTEST_CVS_COMMAND}\\\" -d \\\"${REPO}\\\" co -rRevision1 -d dash-source Project\")
+")
+
+# Run the dashboard script with CTest.
+run_dashboard_script(dash-binary)
diff --git a/Tests/CTestUpdateCommon.cmake b/Tests/CTestUpdateCommon.cmake
new file mode 100644
index 000000000..335d09e7e
--- /dev/null
+++ b/Tests/CTestUpdateCommon.cmake
@@ -0,0 +1,234 @@
+#-----------------------------------------------------------------------------
+# Function to run a child process and report output only on error.
+function(run_child)
+ execute_process(${ARGN}
+ RESULT_VARIABLE FAILED
+ OUTPUT_VARIABLE OUTPUT
+ ERROR_VARIABLE OUTPUT
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_STRIP_TRAILING_WHITESPACE
+ )
+ if(FAILED)
+ string(REGEX REPLACE "\n" "\n " OUTPUT "${OUTPUT}")
+ message(FATAL_ERROR "Child failed (${FAILED}), output is\n ${OUTPUT}\n"
+ "Command = [${ARGN}]\n")
+ endif(FAILED)
+endfunction(run_child)
+
+#-----------------------------------------------------------------------------
+# Function to find the Update.xml file and check for expected entries.
+function(check_updates build)
+ # Find the Update.xml file for the given build tree
+ set(PATTERN ${TOP}/${build}/Testing/*/Update.xml)
+ file(GLOB UPDATE_XML_FILE RELATIVE ${TOP} ${PATTERN})
+ string(REGEX REPLACE "//Update.xml$" "/Update.xml"
+ UPDATE_XML_FILE "${UPDATE_XML_FILE}"
+ )
+ if(NOT UPDATE_XML_FILE)
+ message(FATAL_ERROR "Cannot find Update.xml with pattern\n ${PATTERN}")
+ endif(NOT UPDATE_XML_FILE)
+ message(" found ${UPDATE_XML_FILE}")
+
+ set(max_update_xml_size 16384)
+
+ # Read entries from the Update.xml file
+ set(types "Updated|Modified|Conflicting")
+ file(STRINGS ${TOP}/${UPDATE_XML_FILE} UPDATE_XML_ENTRIES
+ 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}")
+
+ # 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 UPDATE_NOT_GLOBAL)
+ set(rev_elements Revision PriorRevision ${UPDATE_GLOBAL_ELEMENTS})
+ string(REPLACE ";" "|" rev_regex "${rev_elements}")
+ set(rev_regex "^\t<(${rev_regex})>[^<\n]+</(${rev_regex})>$")
+ file(STRINGS ${TOP}/${UPDATE_XML_FILE} UPDATE_XML_REVISIONS
+ REGEX "${rev_regex}"
+ LIMIT_INPUT ${max_update_xml_size}
+ )
+ foreach(r IN LISTS UPDATE_XML_REVISIONS)
+ string(REGEX REPLACE "${rev_regex}" "\\1" element "${r}")
+ set(element_${element} 1)
+ endforeach()
+ foreach(element ${rev_elements})
+ if(NOT element_${element})
+ list(APPEND MISSING "global <${element}> element")
+ endif()
+ endforeach()
+ endif()
+
+ # Report the result
+ set(MSG "")
+ if(MISSING)
+ # List the missing entries
+ set(MSG "${MSG}Update.xml is missing expected entries:\n")
+ foreach(f ${MISSING})
+ set(MSG "${MSG} ${f}\n")
+ endforeach(f)
+ else(MISSING)
+ # Success
+ message(" no entries missing from Update.xml")
+ endif(MISSING)
+
+ # Report the result
+ if(EXTRA)
+ # List the extra entries
+ set(MSG "${MSG}Update.xml has extra unexpected entries:\n")
+ foreach(f ${EXTRA})
+ set(MSG "${MSG} ${f}\n")
+ endforeach(f)
+ else(EXTRA)
+ # Success
+ message(" no extra entries in Update.xml")
+ endif(EXTRA)
+
+ if(MSG)
+ # Provide the log file
+ file(GLOB UPDATE_LOG_FILE
+ ${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}")
+ set(MSG "${MSG}Update log:\n ${UPDATE_LOG}")
+ else(UPDATE_LOG_FILE)
+ set(MSG "${MSG}No update log found!")
+ endif(UPDATE_LOG_FILE)
+
+ # Display the error message
+ message(FATAL_ERROR "${MSG}")
+ endif(MSG)
+endfunction(check_updates)
+
+#-----------------------------------------------------------------------------
+# Function to create initial content.
+function(create_content dir)
+ file(MAKE_DIRECTORY ${TOP}/${dir})
+
+ # An example CTest project configuration file.
+ file(WRITE ${TOP}/${dir}/CTestConfig.cmake
+ "# CTest Configuration File
+set(CTEST_PROJECT_NAME TestProject)
+set(CTEST_NIGHTLY_START_TIME \"21:00:00 EDT\")
+")
+
+ # Some other files.
+ file(WRITE ${TOP}/${dir}/foo.txt "foo\n")
+ file(WRITE ${TOP}/${dir}/bar.txt "bar\n")
+endfunction(create_content)
+
+#-----------------------------------------------------------------------------
+# Function to update content.
+function(update_content dir added_var removed_var dirs_var)
+ file(APPEND ${TOP}/${dir}/foo.txt "foo line 2\n")
+ file(WRITE ${TOP}/${dir}/zot.txt "zot\n")
+ file(REMOVE ${TOP}/${dir}/bar.txt)
+ file(MAKE_DIRECTORY ${TOP}/${dir}/subdir)
+ file(WRITE ${TOP}/${dir}/subdir/foo.txt "foo\n")
+ file(WRITE ${TOP}/${dir}/subdir/bar.txt "bar\n")
+ set(${dirs_var} subdir PARENT_SCOPE)
+ set(${added_var} zot.txt subdir/foo.txt subdir/bar.txt PARENT_SCOPE)
+ set(${removed_var} bar.txt PARENT_SCOPE)
+endfunction(update_content)
+
+#-----------------------------------------------------------------------------
+# Function to change existing files
+function(change_content dir)
+ file(APPEND ${TOP}/${dir}/foo.txt "foo line 3\n")
+ file(APPEND ${TOP}/${dir}/subdir/foo.txt "foo line 2\n")
+endfunction(change_content)
+
+#-----------------------------------------------------------------------------
+# Function to create local modifications before update
+function(modify_content dir)
+ file(APPEND ${TOP}/${dir}/CTestConfig.cmake "# local modification\n")
+endfunction(modify_content)
+
+#-----------------------------------------------------------------------------
+# Function to write CTestConfiguration.ini content.
+function(create_build_tree src_dir bin_dir)
+ file(MAKE_DIRECTORY ${TOP}/${bin_dir})
+ file(WRITE ${TOP}/${bin_dir}/CTestConfiguration.ini
+ "# CTest Configuration File
+SourceDirectory: ${TOP}/${src_dir}
+BuildDirectory: ${TOP}/${bin_dir}
+Site: test.site
+BuildName: user-test
+")
+endfunction(create_build_tree)
+
+#-----------------------------------------------------------------------------
+# Function to write the dashboard test script.
+function(create_dashboard_script bin_dir custom_text)
+ # Write the dashboard script.
+ file(WRITE ${TOP}/${bin_dir}.cmake
+ "# CTest Dashboard Script
+set(CTEST_DASHBOARD_ROOT \"${TOP}\")
+set(CTEST_SITE test.site)
+set(CTEST_BUILD_NAME dash-test)
+set(CTEST_SOURCE_DIRECTORY \${CTEST_DASHBOARD_ROOT}/dash-source)
+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})
+")
+endfunction(create_dashboard_script)
+
+#-----------------------------------------------------------------------------
+# Function to run the dashboard through the command line
+function(run_dashboard_command_line bin_dir)
+ run_child(
+ WORKING_DIRECTORY ${TOP}/${bin_dir}
+ COMMAND ${CMAKE_CTEST_COMMAND} -M Experimental -T Start -T Update
+ )
+
+ # Verify the updates reported by CTest.
+ list(APPEND UPDATE_MAYBE Updated{subdir})
+ set(_modified Modified{CTestConfig.cmake})
+ if(UPDATE_NO_MODIFIED)
+ set(_modified "")
+ endif()
+ check_updates(${bin_dir}
+ Updated{foo.txt}
+ Updated{bar.txt}
+ Updated{zot.txt}
+ Updated{subdir/foo.txt}
+ Updated{subdir/bar.txt}
+ ${_modified}
+ )
+endfunction(run_dashboard_command_line)
+
+#-----------------------------------------------------------------------------
+# Function to run the dashboard through a script
+function(run_dashboard_script bin_dir)
+ run_child(
+ WORKING_DIRECTORY ${TOP}
+ COMMAND ${CMAKE_CTEST_COMMAND} -S ${bin_dir}.cmake -V
+ )
+
+ # 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}
+ )
+endfunction(run_dashboard_script)
+
+#-----------------------------------------------------------------------------
+# Function to initialize the testing directory.
+function(init_testing)
+ file(REMOVE_RECURSE ${TOP})
+ file(MAKE_DIRECTORY ${TOP})
+endfunction(init_testing)
diff --git a/Tests/CTestUpdateGIT.cmake.in b/Tests/CTestUpdateGIT.cmake.in
new file mode 100644
index 000000000..eb9f987c6
--- /dev/null
+++ b/Tests/CTestUpdateGIT.cmake.in
@@ -0,0 +1,317 @@
+# This script drives creation of a git 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(TOP "${TOP}/@CTestUpdateGIT_DIR@")
+set(UPDATE_EXTRA Updated{module})
+
+# Include code common to all update tests.
+include("@CMAKE_CURRENT_SOURCE_DIR@/CTestUpdateCommon.cmake")
+
+#-----------------------------------------------------------------------------
+# Report git tools in use.
+message("Using GIT tools:")
+set(GIT "@GIT_EXECUTABLE@")
+message(" git = ${GIT}")
+
+set(AUTHOR_CONFIG "[user]
+\tname = Test Author
+\temail = testauthor@cmake.org
+")
+
+#-----------------------------------------------------------------------------
+# Initialize the testing directory.
+message("Creating test directory...")
+init_testing()
+
+if(UNIX)
+ set(src "@CMAKE_CURRENT_SOURCE_DIR@")
+ configure_file(${src}/CTestUpdateGIT.sh.in ${TOP}/git.sh @ONLY)
+ set(GIT ${TOP}/git.sh)
+endif()
+
+#-----------------------------------------------------------------------------
+# Create the repository.
+message("Creating repository...")
+file(MAKE_DIRECTORY ${TOP}/repo.git)
+run_child(
+ WORKING_DIRECTORY ${TOP}/repo.git
+ COMMAND ${GIT} --bare init
+ )
+file(REMOVE_RECURSE ${TOP}/repo.git/hooks)
+set(REPO file://${TOP}/repo.git)
+
+# Create submodule repository.
+message("Creating submodule...")
+file(MAKE_DIRECTORY ${TOP}/module.git)
+run_child(
+ WORKING_DIRECTORY ${TOP}/module.git
+ 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
+ )
+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}")
+run_child(WORKING_DIRECTORY ${TOP}/module
+ COMMAND ${GIT} add .
+ )
+run_child(WORKING_DIRECTORY ${TOP}/module
+ COMMAND ${GIT} commit -m "Initial content"
+ )
+run_child(WORKING_DIRECTORY ${TOP}/module
+ COMMAND ${GIT} push origin master:refs/heads/master
+ )
+
+#-----------------------------------------------------------------------------
+# Import initial content into the repository.
+message("Importing content...")
+create_content(import)
+
+# Import the content into the repository.
+run_child(WORKING_DIRECTORY ${TOP}/import
+ COMMAND ${GIT} init
+ )
+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}")
+run_child(WORKING_DIRECTORY ${TOP}/import
+ COMMAND ${GIT} add .
+ )
+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
+ )
+run_child(WORKING_DIRECTORY ${TOP}/import
+ COMMAND ${GIT} commit -m "Initial content"
+ )
+run_child(WORKING_DIRECTORY ${TOP}/import
+ COMMAND ${GIT} push origin master:refs/heads/master
+ )
+
+#-----------------------------------------------------------------------------
+# Modify the submodule.
+change_content(module)
+run_child(WORKING_DIRECTORY ${TOP}/module
+ COMMAND ${GIT} add -u
+ )
+run_child(WORKING_DIRECTORY ${TOP}/module
+ COMMAND ${GIT} commit -m "Changed content"
+ )
+run_child(WORKING_DIRECTORY ${TOP}/module
+ COMMAND ${GIT} push origin master:refs/heads/master
+ )
+
+#-----------------------------------------------------------------------------
+# Create a working tree.
+message("Checking out revision 1...")
+run_child(
+ WORKING_DIRECTORY ${TOP}
+ COMMAND ${GIT} clone ${REPO} user-source
+ )
+file(REMOVE_RECURSE ${TOP}/user-source/.git/hooks)
+file(APPEND ${TOP}/user-source/.git/config "${AUTHOR_CONFIG}")
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${GIT} submodule init
+ )
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${GIT} submodule update
+ )
+
+# Save the first revision name.
+execute_process(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${GIT} rev-parse HEAD
+ OUTPUT_VARIABLE revision1
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+
+#-----------------------------------------------------------------------------
+# Create an empty commit.
+message("Creating empty commit...")
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${GIT} commit --allow-empty -m "Empty commit"
+ )
+
+#-----------------------------------------------------------------------------
+# Make changes in the working tree.
+message("Changing content...")
+update_content(user-source files_added files_removed dirs_added)
+if(dirs_added)
+ run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${GIT} add ${dirs_added}
+ )
+endif(dirs_added)
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${GIT} add ${files_added}
+ )
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${GIT} rm ${files_removed}
+ )
+run_child(WORKING_DIRECTORY ${TOP}/user-source/module
+ COMMAND ${GIT} checkout master
+ )
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${GIT} add -u
+ )
+
+#-----------------------------------------------------------------------------
+# Commit the changes to the repository.
+message("Committing revision 2...")
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${GIT} commit -m "Changed content"
+ )
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${GIT} push origin
+ )
+
+#-----------------------------------------------------------------------------
+# Make changes in the working tree.
+message("Changing content again...")
+change_content(user-source)
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${GIT} add -u
+ )
+
+#-----------------------------------------------------------------------------
+# Commit the changes to the repository.
+message("Committing revision 3...")
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${GIT} commit -m "Changed content again"
+ )
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${GIT} push origin
+ )
+
+#-----------------------------------------------------------------------------
+# Go back to before the changes so we can test updating.
+macro(rewind_source src_dir)
+ message("Backing up to revision 1...")
+ run_child(
+ WORKING_DIRECTORY ${TOP}/${src_dir}
+ COMMAND ${GIT} reset --hard ${revision1}
+ )
+ run_child(
+ WORKING_DIRECTORY ${TOP}/${src_dir}
+ COMMAND ${GIT} submodule update
+ )
+endmacro(rewind_source)
+rewind_source(user-source)
+
+# Make sure pull does not try to rebase (which does not work with
+# modified files) even if ~/.gitconfig sets "branch.master.rebase".
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${GIT} config branch.master.rebase false
+ )
+
+# Create a modified file.
+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
+ "# GIT command configuration
+UpdateCommand: ${GIT}
+")
+
+# Run the dashboard command line interface.
+set(UPDATE_NO_MODIFIED 1)
+run_dashboard_command_line(user-binary)
+set(UPDATE_NO_MODIFIED 0)
+
+rewind_source(user-source)
+modify_content(user-source)
+
+message("Running CTest Dashboard Command Line (custom update)...")
+
+# Create the user build tree.
+create_build_tree(user-source user-binary-custom)
+file(APPEND ${TOP}/user-binary-custom/CTestConfiguration.ini
+ "# GIT command configuration
+UpdateCommand: ${GIT}
+GITUpdateCustom: ${GIT};pull;origin;master
+")
+
+# Run the dashboard command line interface.
+run_dashboard_command_line(user-binary-custom)
+
+#-----------------------------------------------------------------------------
+# Test initial checkout and update with a dashboard script.
+message("Running CTest Dashboard Script...")
+
+create_dashboard_script(dash-binary
+ "# git command configuration
+set(CTEST_GIT_COMMAND \"${GIT}\")
+set(CTEST_GIT_UPDATE_OPTIONS)
+execute_process(
+ WORKING_DIRECTORY \"${TOP}\"
+ COMMAND \"${GIT}\" clone \"${REPO}\" dash-source
+ )
+
+# Test .git file.
+file(RENAME \"${TOP}/dash-source/.git\" \"${TOP}/dash-source/repo.git\")
+file(WRITE \"${TOP}/dash-source/.git\" \"gitdir: repo.git\n\")
+
+execute_process(
+ WORKING_DIRECTORY \"${TOP}/dash-source\"
+ COMMAND \"${GIT}\" reset --hard ${revision1}
+ )
+execute_process(
+ WORKING_DIRECTORY \"${TOP}/dash-source\"
+ COMMAND \"${GIT}\" submodule init
+ )
+execute_process(
+ WORKING_DIRECTORY \"${TOP}/dash-source\"
+ COMMAND \"${GIT}\" submodule update
+ )
+")
+
+# Run the dashboard script with CTest.
+run_dashboard_script(dash-binary)
+
+rewind_source(dash-source)
+
+#-----------------------------------------------------------------------------
+# Test custom update with a dashboard script.
+message("Running CTest Dashboard Script (custom update)...")
+
+create_dashboard_script(dash-binary-custom
+ "# git command configuration
+set(CTEST_GIT_COMMAND \"${GIT}\")
+set(CTEST_GIT_UPDATE_OPTIONS)
+set(CTEST_GIT_UPDATE_CUSTOM \${CTEST_GIT_COMMAND} pull origin master)
+")
+
+# Run the dashboard script with CTest.
+run_dashboard_script(dash-binary-custom)
diff --git a/Tests/CTestUpdateGIT.sh.in b/Tests/CTestUpdateGIT.sh.in
new file mode 100755
index 000000000..e7586d6bf
--- /dev/null
+++ b/Tests/CTestUpdateGIT.sh.in
@@ -0,0 +1,6 @@
+#!/bin/sh
+if test "x$1" = "xpull" -o "x$1" = "xreset"; then
+ "@GIT@" "$@" && sleep 1 && touch foo.txt
+else
+ exec "@GIT@" "$@"
+fi
diff --git a/Tests/CTestUpdateHG.cmake.in b/Tests/CTestUpdateHG.cmake.in
new file mode 100644
index 000000000..640d2c6f3
--- /dev/null
+++ b/Tests/CTestUpdateHG.cmake.in
@@ -0,0 +1,166 @@
+# This script drives creation of a Mercurial 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(TOP "${TOP}/@CTestUpdateHG_DIR@")
+
+# Include code common to all update tests.
+include("@CMAKE_CURRENT_SOURCE_DIR@/CTestUpdateCommon.cmake")
+
+#-----------------------------------------------------------------------------
+# Report hg tools in use.
+message("Using HG tools:")
+set(HG "@HG_EXECUTABLE@")
+message(" hg = ${HG}")
+
+#-----------------------------------------------------------------------------
+# Initialize the testing directory.
+message("Creating test directory...")
+init_testing()
+
+#-----------------------------------------------------------------------------
+# Create the repository.
+message("Creating repository...")
+file(MAKE_DIRECTORY ${TOP}/repo.hg)
+run_child(
+ WORKING_DIRECTORY ${TOP}/repo.hg
+ COMMAND ${HG} init
+ )
+if(NOT "${TOP}" MATCHES "^/")
+ set(slash /)
+endif()
+set(REPO file://${slash}${TOP}/repo.hg)
+
+#-----------------------------------------------------------------------------
+# Import initial content into the repository.
+message("Importing content...")
+create_content(import)
+
+# Import the content into the repository.
+run_child(WORKING_DIRECTORY ${TOP}/import
+ COMMAND ${HG} init
+ )
+run_child(WORKING_DIRECTORY ${TOP}/import
+ COMMAND ${HG} add .
+ )
+run_child(WORKING_DIRECTORY ${TOP}/import
+ COMMAND ${HG} commit -m "Initial content"
+ -u "Test Author <testauthor@cmake.org>"
+ )
+run_child(WORKING_DIRECTORY ${TOP}/import
+ COMMAND ${HG} push "${REPO}"
+ )
+
+#-----------------------------------------------------------------------------
+# Create a working tree.
+message("Checking out first revision...")
+run_child(
+ WORKING_DIRECTORY ${TOP}
+ COMMAND ${HG} clone ${REPO} user-source
+ )
+
+#-----------------------------------------------------------------------------
+# Make changes in the working tree.
+message("Changing content...")
+update_content(user-source files_added files_removed dirs_added)
+if(dirs_added)
+ run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${HG} add ${dirs_added}
+ )
+endif(dirs_added)
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${HG} add ${files_added}
+ )
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${HG} rm ${files_removed}
+ )
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${HG} add
+ )
+
+#-----------------------------------------------------------------------------
+# Commit the changes to the repository.
+message("Committing revision 2...")
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${HG} commit -m "Changed content"
+ -u "Test Author <testauthor@cmake.org>"
+ )
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${HG} push
+ )
+
+#-----------------------------------------------------------------------------
+# Make changes in the working tree.
+message("Changing content again...")
+change_content(user-source)
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${HG} add
+ )
+
+#-----------------------------------------------------------------------------
+# Commit the changes to the repository.
+message("Committing revision 3...")
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${HG} commit -m "Changed content again"
+ -u "Test Author <testauthor@cmake.org>"
+ )
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${HG} push
+ )
+
+#-----------------------------------------------------------------------------
+# Go back to before the changes so we can test updating.
+message("Backing up to first revision...")
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${HG} update -C -r 0
+ )
+
+# Create a modified file.
+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
+ "# HG command configuration
+UpdateCommand: ${HG}
+")
+
+# Run the dashboard command line interface.
+run_dashboard_command_line(user-binary)
+
+#-----------------------------------------------------------------------------
+# Test initial checkout and update with a dashboard script.
+message("Running CTest Dashboard Script...")
+
+create_dashboard_script(dash-binary
+ "# hg command configuration
+set(CTEST_HG_COMMAND \"${HG}\")
+set(CTEST_HG_UPDATE_OPTIONS)
+execute_process(
+ WORKING_DIRECTORY \"${TOP}\"
+ COMMAND \"${HG}\" clone \"${REPO}\" dash-source
+ )
+execute_process(
+ WORKING_DIRECTORY \"${TOP}/dash-source\"
+ COMMAND \"${HG}\" update -C -r 0
+ )
+")
+
+# Run the dashboard script with CTest.
+run_dashboard_script(dash-binary)
diff --git a/Tests/CTestUpdateSVN.cmake.in b/Tests/CTestUpdateSVN.cmake.in
new file mode 100644
index 000000000..15b833b10
--- /dev/null
+++ b/Tests/CTestUpdateSVN.cmake.in
@@ -0,0 +1,149 @@
+# This script drives creation of a Subversion 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(TOP "${TOP}/@CTestUpdateSVN_DIR@")
+set(UPDATE_GLOBAL_ELEMENTS SVNPath)
+
+# Include code common to all update tests.
+include("@CMAKE_CURRENT_SOURCE_DIR@/CTestUpdateCommon.cmake")
+
+#-----------------------------------------------------------------------------
+# Report subversion tools in use.
+message("Using subversion tools:")
+set(SVN "@Subversion_SVN_EXECUTABLE@")
+set(SVNADMIN "@Subversion_SVNADMIN_EXECUTABLE@")
+message(" svn = ${SVN}")
+message(" svnadmin = ${SVNADMIN}")
+
+# Isolate svn test operations from the user configuration.
+file(MAKE_DIRECTORY ${TOP}/config)
+set(SVNCMD ${SVN} --config-dir ${TOP}/config)
+set(SVNUSER --username "test author" --non-interactive)
+
+# Configure for this svn version.
+execute_process(
+ COMMAND ${SVN} help add OUTPUT_VARIABLE help_add ERROR_VARIABLE help_add
+ )
+if("${help_add}" MATCHES "--depth")
+ set(depth_empty "--depth=empty")
+else()
+ set(depth_empty "")
+endif()
+
+#-----------------------------------------------------------------------------
+# Initialize the testing directory.
+message("Creating test directory...")
+init_testing()
+
+#-----------------------------------------------------------------------------
+# Create the repository.
+message("Creating repository...")
+run_child(
+ COMMAND ${SVNADMIN} create --config-dir ${TOP}/config ${TOP}/repo
+ )
+set(REPO file:///${TOP}/repo/trunk)
+
+#-----------------------------------------------------------------------------
+# Import initial content into the repository.
+message("Importing content...")
+create_content(import)
+
+# Import the content into the repository.
+run_child(
+ WORKING_DIRECTORY ${TOP}/import
+ COMMAND ${SVNCMD} import ${SVNUSER} -m "Initial content" . "${REPO}"
+ )
+
+#-----------------------------------------------------------------------------
+# Create a working tree.
+message("Checking out revision 1...")
+run_child(
+ WORKING_DIRECTORY ${TOP}
+ COMMAND ${SVNCMD} co ${SVNUSER} ${REPO} user-source
+ )
+
+#-----------------------------------------------------------------------------
+# Make changes in the working tree.
+message("Changing content...")
+update_content(user-source files_added files_removed dirs_added)
+if(dirs_added)
+ run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${SVNCMD} add ${depth_empty} ${dirs_added}
+ )
+endif(dirs_added)
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${SVNCMD} add ${files_added}
+ )
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${SVNCMD} rm ${files_removed}
+ )
+
+#-----------------------------------------------------------------------------
+# Commit the changes to the repository.
+message("Committing revision 2...")
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${SVNCMD} commit -m "Changed content"
+ )
+
+#-----------------------------------------------------------------------------
+# Make changes in the working tree.
+message("Changing content again...")
+change_content(user-source)
+
+#-----------------------------------------------------------------------------
+# Commit the changes to the repository.
+message("Committing revision 3...")
+run_child(
+ WORKING_DIRECTORY ${TOP}/user-source
+ COMMAND ${SVNCMD} commit -m "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 ${SVNCMD} up -r1
+ )
+
+# Create a modified file.
+message("Modifying locally...")
+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
+ "# SVN command configuration
+SVNCommand: ${SVN}
+SVNUpdateOptions: --config-dir \"${TOP}/config\"
+")
+
+# Run the dashboard command line interface.
+run_dashboard_command_line(user-binary)
+
+#-----------------------------------------------------------------------------
+# Test initial checkout and update with a dashboard script.
+message("Running CTest Dashboard Script...")
+
+create_dashboard_script(dash-binary
+ "# Subversion command configuration
+set(CTEST_SVN_COMMAND \"${SVN}\")
+set(CTEST_SVN_UPDATE_OPTIONS
+ \"--config-dir \\\"\${CTEST_DASHBOARD_ROOT}/config\\\"\")
+set(CTEST_CHECKOUT_COMMAND
+ \"\\\"\${CTEST_SVN_COMMAND}\\\" co -r1 \\\"${REPO}\\\" dash-source\")
+")
+
+# Run the dashboard script with CTest.
+run_dashboard_script(dash-binary)
diff --git a/Tests/CheckCompilerRelatedVariables/CMakeLists.txt b/Tests/CheckCompilerRelatedVariables/CMakeLists.txt
new file mode 100644
index 000000000..8b279a5c4
--- /dev/null
+++ b/Tests/CheckCompilerRelatedVariables/CMakeLists.txt
@@ -0,0 +1,90 @@
+cmake_minimum_required(VERSION 2.8)
+project(CheckCompilerRelatedVariables)
+
+
+function(echo_var var)
+ if(DEFINED ${var})
+ message("${var}='${${var}}' is defined")
+ else()
+ message("${var}='${${var}}' is NOT defined")
+ endif()
+endfunction()
+
+
+#
+# Check that the correct number of MSVC** variables are defined...
+#
+set(msvc_total 0)
+
+if(DEFINED MSVC60)
+ math(EXPR msvc_total "${msvc_total} + 1")
+endif()
+if(DEFINED MSVC70)
+ math(EXPR msvc_total "${msvc_total} + 1")
+endif()
+if(DEFINED MSVC71)
+ math(EXPR msvc_total "${msvc_total} + 1")
+endif()
+if(DEFINED MSVC80)
+ math(EXPR msvc_total "${msvc_total} + 1")
+endif()
+if(DEFINED MSVC90)
+ math(EXPR msvc_total "${msvc_total} + 1")
+endif()
+if(DEFINED MSVC10)
+ math(EXPR msvc_total "${msvc_total} + 1")
+endif()
+if(DEFINED MSVC11)
+ math(EXPR msvc_total "${msvc_total} + 1")
+endif()
+
+echo_var(MSVC)
+echo_var(MSVC60)
+echo_var(MSVC70)
+echo_var(MSVC71)
+echo_var(MSVC80)
+echo_var(MSVC90)
+echo_var(MSVC10)
+echo_var(MSVC11)
+
+if(MSVC)
+ #
+ # MSVC is set in cl.cmake when cl is the compiler...
+ #
+ # Exactly one of the numbered variables should also be set
+ # indicating which version of the cl compiler / Visual Studio
+ # is in use...
+ #
+ if(msvc_total EQUAL 1)
+ message("test passes: exactly one MSVC** variable is defined...")
+ else()
+ message(FATAL_ERROR "error: ${msvc_total} MSVC** variables are defined -- exactly 1 expected")
+ endif()
+else()
+ #
+ # The compiler is something other than cl... None of the MSVC** variables
+ # should be defined...
+ #
+ if(msvc_total EQUAL 0)
+ message("test passes: no MSVC** variables are defined on non-MSVC build...")
+ else()
+ message(FATAL_ERROR "error: ${msvc_total} MSVC** variables are defined -- exactly 0 expected")
+ endif()
+endif()
+
+
+#
+# This is a no-op executable... If this test is going to fail, it fails during
+# the configure step while cmake is configuring this CMakeLists.txt file...
+#
+
+file(WRITE
+ "${CMAKE_CURRENT_BINARY_DIR}/main.cxx"
+ "int main() { return 0; }
+"
+ )
+
+add_executable(
+ CheckCompilerRelatedVariables
+ "${CMAKE_CURRENT_BINARY_DIR}/main.cxx"
+ )
diff --git a/Tests/CheckFortran.cmake b/Tests/CheckFortran.cmake
new file mode 100644
index 000000000..ebbb426ce
--- /dev/null
+++ b/Tests/CheckFortran.cmake
@@ -0,0 +1,50 @@
+
+#=============================================================================
+# 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.)
+
+if(NOT DEFINED CMAKE_Fortran_COMPILER)
+ set(_desc "Looking for a Fortran compiler")
+ message(STATUS ${_desc})
+ file(REMOVE_RECURSE ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CheckFortran)
+ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CheckFortran/CMakeLists.txt"
+ "cmake_minimum_required(VERSION 2.4)
+project(CheckFortran Fortran)
+file(WRITE \"\${CMAKE_CURRENT_BINARY_DIR}/result.cmake\"
+ \"set(CMAKE_Fortran_COMPILER \\\"\${CMAKE_Fortran_COMPILER}\\\")\\n\"
+ \"set(CMAKE_Fortran_FLAGS \\\"\${CMAKE_Fortran_FLAGS}\\\")\\n\"
+ )
+")
+ execute_process(
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CheckFortran
+ COMMAND ${CMAKE_COMMAND} . -G ${CMAKE_GENERATOR}
+ OUTPUT_VARIABLE output
+ ERROR_VARIABLE output
+ RESULT_VARIABLE result
+ )
+ include(${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CheckFortran/result.cmake OPTIONAL)
+ if(CMAKE_Fortran_COMPILER AND "${result}" STREQUAL "0")
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "${_desc} passed with the following output:\n"
+ "${output}\n")
+ else()
+ set(CMAKE_Fortran_COMPILER NOTFOUND)
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "${_desc} failed with the following output:\n"
+ "${output}\n")
+ endif()
+ message(STATUS "${_desc} - ${CMAKE_Fortran_COMPILER}")
+ set(CMAKE_Fortran_COMPILER "${CMAKE_Fortran_COMPILER}" CACHE FILEPATH "Fortran compiler")
+ mark_as_advanced(CMAKE_Fortran_COMPILER)
+ set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" CACHE STRING "Fortran flags")
+ mark_as_advanced(CMAKE_Fortran_FLAGS)
+endif()
diff --git a/Tests/CommandLineTest/CMakeLists.txt b/Tests/CommandLineTest/CMakeLists.txt
new file mode 100644
index 000000000..0493a0c4b
--- /dev/null
+++ b/Tests/CommandLineTest/CMakeLists.txt
@@ -0,0 +1,79 @@
+cmake_minimum_required (VERSION 2.6)
+PROJECT(CommandLineTest)
+
+GET_FILENAME_COMPONENT(CMAKE_BIN_DIR ${CMAKE_COMMAND} PATH)
+MACRO(EXEC_CMAKE_COMMAND CMAKE_ARGS)
+ EXEC_PROGRAM("${CMAKE_COMMAND}" ARGS "${CMAKE_ARGS}" RETURN_VALUE RET)
+ IF(${RET})
+ MESSAGE(SEND_ERROR "CMake command failed with arguments \"${CMAKE_ARGS}\"")
+ ENDIF(${RET})
+ENDMACRO(EXEC_CMAKE_COMMAND)
+
+EXEC_CMAKE_COMMAND("-E chdir \"${CMAKE_CURRENT_SOURCE_DIR}\" \"${CMAKE_COMMAND}\" -E echo \"Hello World\"")
+EXEC_CMAKE_COMMAND("-E time \"${CMAKE_COMMAND} -N -L ${CommandLineTest_SOURCE_DIR}\"")
+EXEC_CMAKE_COMMAND("-E time \"${CMAKE_COMMAND} -N -LA ${CommandLineTest_SOURCE_DIR}\"")
+EXEC_CMAKE_COMMAND("-E time \"${CMAKE_COMMAND} -N -LH ${CommandLineTest_SOURCE_DIR}\"")
+EXEC_CMAKE_COMMAND("-E time \"${CMAKE_COMMAND} -N -LAH ${CommandLineTest_SOURCE_DIR}\"")
+EXEC_CMAKE_COMMAND("--help")
+EXEC_CMAKE_COMMAND("--help-command-list")
+EXEC_CMAKE_COMMAND("--help add_executable")
+EXEC_CMAKE_COMMAND("--help-command add_executable")
+EXEC_CMAKE_COMMAND("--help-full \"${CMAKE_CURRENT_BINARY_DIR}/cmake.txt\"")
+EXEC_CMAKE_COMMAND("--help-man \"${CMAKE_CURRENT_BINARY_DIR}/cmake.man\"")
+EXEC_CMAKE_COMMAND("--help-html \"${CMAKE_CURRENT_BINARY_DIR}/cmake.html\"")
+EXEC_CMAKE_COMMAND("--copyright \"${CMAKE_CURRENT_BINARY_DIR}/Copyright.txt\"")
+EXEC_CMAKE_COMMAND("--version \"${CMAKE_CURRENT_BINARY_DIR}/version.txt\"")
+
+ADD_EXECUTABLE(CommandLineTest CommandLineTest.cxx)
+
+GET_FILENAME_COMPONENT(CMAKE_COMMAND_PATH "${CMAKE_COMMAND}" PATH)
+SET(CTEST_COMMAND "${CMAKE_COMMAND_PATH}/ctest")
+MACRO(EXEC_CTEST_COMMAND CMAKE_ARGS)
+ EXEC_PROGRAM("${CTEST_COMMAND}" ARGS "${CMAKE_ARGS}" RETURN_VALUE RET)
+ IF(${RET})
+ MESSAGE(SEND_ERROR "CTest command failed with arguments \"${CMAKE_ARGS}\"")
+ ENDIF(${RET})
+ENDMACRO(EXEC_CTEST_COMMAND)
+MACRO(EXEC_CTEST_COMMAND_WITH_DIR DIR CMAKE_ARGS)
+ EXEC_PROGRAM("${CTEST_COMMAND}" "${DIR}" ARGS "${CMAKE_ARGS}" RETURN_VALUE RET)
+ IF(${RET})
+ MESSAGE(SEND_ERROR "CTest command failed with arguments \"${CMAKE_ARGS}\"")
+ ENDIF(${RET})
+ENDMACRO(EXEC_CTEST_COMMAND_WITH_DIR)
+
+EXEC_CTEST_COMMAND_WITH_DIR("${CMAKE_CURRENT_BINARY_DIR}/../.." "-N")
+EXEC_CTEST_COMMAND_WITH_DIR("${CMAKE_CURRENT_BINARY_DIR}/../.." "-R complex -N")
+EXEC_CTEST_COMMAND_WITH_DIR("${CMAKE_CURRENT_BINARY_DIR}/../.." "-E Simple -N")
+EXEC_CTEST_COMMAND_WITH_DIR("${CMAKE_CURRENT_BINARY_DIR}/../.." "-E Simple -N")
+EXEC_CTEST_COMMAND_WITH_DIR("${CMAKE_CURRENT_BINARY_DIR}/../.." "-N -I -10")
+EXEC_CTEST_COMMAND_WITH_DIR("${CMAKE_CURRENT_BINARY_DIR}/../.." "-N -I 10-")
+EXEC_CTEST_COMMAND_WITH_DIR("${CMAKE_CURRENT_BINARY_DIR}/../.." "-N -I 3,4")
+EXEC_CTEST_COMMAND("--help")
+EXEC_CTEST_COMMAND("--copyright")
+EXEC_CTEST_COMMAND("--help-full \"${CMAKE_CURRENT_BINARY_DIR}/ctest.txt\"")
+EXEC_CTEST_COMMAND("--help-man \"${CMAKE_CURRENT_BINARY_DIR}/ctest.man\"")
+EXEC_CTEST_COMMAND("--help-html \"${CMAKE_CURRENT_BINARY_DIR}/ctest.html\"")
+EXEC_CTEST_COMMAND("--version")
+
+IF(THIS_SHOULD_BE_SET)
+ MESSAGE(STATUS "***************************")
+ MESSAGE(STATUS "PreLoad.cmake works fine.")
+ MESSAGE(STATUS "***************************")
+ELSE(THIS_SHOULD_BE_SET)
+ MESSAGE("***************************")
+ MESSAGE(FATAL_ERROR "PreLoad.cmake does not work.")
+ENDIF(THIS_SHOULD_BE_SET)
+
+IF(DEFINED ENV{TEST_ENVIRONMENT_VARIABLE_NOTSET})
+ MESSAGE(SEND_ERROR "Environment variable definition test broken!")
+ENDIF(DEFINED ENV{TEST_ENVIRONMENT_VARIABLE_NOTSET})
+
+SET(ENV{TEST_ENVIRONMENT_VARIABLE} "Environment variable set")
+IF("$ENV{TEST_ENVIRONMENT_VARIABLE}" STREQUAL "Environment variable set")
+ MESSAGE(STATUS "Environment variable set to: $ENV{TEST_ENVIRONMENT_VARIABLE}")
+ IF(NOT DEFINED ENV{TEST_ENVIRONMENT_VARIABLE})
+ MESSAGE(SEND_ERROR "Environment variable definition test failed!")
+ ENDIF(NOT DEFINED ENV{TEST_ENVIRONMENT_VARIABLE})
+ELSE("$ENV{TEST_ENVIRONMENT_VARIABLE}" STREQUAL "Environment variable set")
+ MESSAGE(SEND_ERROR "Environment variable setting is broken")
+ENDIF("$ENV{TEST_ENVIRONMENT_VARIABLE}" STREQUAL "Environment variable set")
diff --git a/Tests/CommandLineTest/CommandLineTest.cxx b/Tests/CommandLineTest/CommandLineTest.cxx
new file mode 100644
index 000000000..f8b643afb
--- /dev/null
+++ b/Tests/CommandLineTest/CommandLineTest.cxx
@@ -0,0 +1,4 @@
+int main()
+{
+ return 0;
+}
diff --git a/Tests/CommandLineTest/PreLoad.cmake b/Tests/CommandLineTest/PreLoad.cmake
new file mode 100644
index 000000000..87284aff0
--- /dev/null
+++ b/Tests/CommandLineTest/PreLoad.cmake
@@ -0,0 +1 @@
+SET(THIS_SHOULD_BE_SET ON CACHE BOOL "Some variable")
diff --git a/Tests/CompileCommandOutput/CMakeLists.txt b/Tests/CompileCommandOutput/CMakeLists.txt
new file mode 100644
index 000000000..bd8e305c2
--- /dev/null
+++ b/Tests/CompileCommandOutput/CMakeLists.txt
@@ -0,0 +1,16 @@
+# a simple C only test case
+cmake_minimum_required (VERSION 2.6)
+project (CompileCommandOutput CXX)
+
+SET(CMAKE_EXPORT_COMPILE_COMMANDS ON)
+set(CMAKE_DEBUG_POSTFIX "_test_debug_postfix")
+IF(MAKE_SUPPORTS_SPACES)
+ SET(test1_srcs "file with spaces.cxx")
+ELSE()
+ SET(test1_srcs "file_with_underscores.cxx")
+ENDIF()
+ADD_LIBRARY(test1 STATIC ${test1_srcs})
+ADD_LIBRARY(test2 SHARED "../CompileCommandOutput/relative.cxx")
+INCLUDE_DIRECTORIES(${CompileCommandOutput_SOURCE_DIR}/../../Source)
+ADD_EXECUTABLE(CompileCommandOutput compile_command_output.cxx)
+TARGET_LINK_LIBRARIES(CompileCommandOutput test1 test2)
diff --git a/Tests/CompileCommandOutput/compile_command_output.cxx b/Tests/CompileCommandOutput/compile_command_output.cxx
new file mode 100644
index 000000000..145a06426
--- /dev/null
+++ b/Tests/CompileCommandOutput/compile_command_output.cxx
@@ -0,0 +1,9 @@
+#include "file_with_underscores.h"
+#include "relative.h"
+
+int main (int argc, char** argv)
+{
+ file_with_underscores();
+ relative();
+ return 0;
+}
diff --git a/Tests/CompileCommandOutput/file with spaces.cxx b/Tests/CompileCommandOutput/file with spaces.cxx
new file mode 100644
index 000000000..554e176e4
--- /dev/null
+++ b/Tests/CompileCommandOutput/file with spaces.cxx
@@ -0,0 +1 @@
+#include "file_with_underscores.cxx"
diff --git a/Tests/CompileCommandOutput/file_with_underscores.cxx b/Tests/CompileCommandOutput/file_with_underscores.cxx
new file mode 100644
index 000000000..4f42ccf56
--- /dev/null
+++ b/Tests/CompileCommandOutput/file_with_underscores.cxx
@@ -0,0 +1,3 @@
+#include "file_with_underscores.h"
+
+void file_with_underscores() {}
diff --git a/Tests/CompileCommandOutput/file_with_underscores.h b/Tests/CompileCommandOutput/file_with_underscores.h
new file mode 100644
index 000000000..0d73e3159
--- /dev/null
+++ b/Tests/CompileCommandOutput/file_with_underscores.h
@@ -0,0 +1 @@
+void file_with_underscores();
diff --git a/Tests/CompileCommandOutput/relative.cxx b/Tests/CompileCommandOutput/relative.cxx
new file mode 100644
index 000000000..eae11e226
--- /dev/null
+++ b/Tests/CompileCommandOutput/relative.cxx
@@ -0,0 +1,3 @@
+#include "relative.h"
+
+void relative() {}
diff --git a/Tests/CompileCommandOutput/relative.h b/Tests/CompileCommandOutput/relative.h
new file mode 100644
index 000000000..ddfe5519b
--- /dev/null
+++ b/Tests/CompileCommandOutput/relative.h
@@ -0,0 +1,11 @@
+#if defined(_WIN32)
+# ifdef test2_EXPORTS
+# define TEST2_EXPORT __declspec(dllexport)
+# else
+# define TEST2_EXPORT __declspec(dllimport)
+# endif
+#else
+# define TEST2_EXPORT
+#endif
+
+TEST2_EXPORT void relative();
diff --git a/Tests/Complex/CMakeLists.txt b/Tests/Complex/CMakeLists.txt
new file mode 100644
index 000000000..ec3ad3985
--- /dev/null
+++ b/Tests/Complex/CMakeLists.txt
@@ -0,0 +1,406 @@
+#
+# A more complex test case
+#
+SET(CMAKE_BACKWARDS_COMPATIBILITY 1.4)
+PROJECT (Complex)
+
+# Try setting a new policy. The IF test is for coverage.
+IF(POLICY CMP0003)
+ CMAKE_POLICY(SET CMP0003 NEW)
+
+ CMAKE_POLICY(GET CMP0003 P3)
+ IF(NOT "${P3}" STREQUAL "NEW")
+ MESSAGE(FATAL_ERROR "CMAKE_POLICY(GET) did not report NEW!")
+ ENDIF(NOT "${P3}" STREQUAL "NEW")
+ENDIF(POLICY CMP0003)
+
+# Test building without per-rule echo lines in Makefiles.
+SET_PROPERTY(GLOBAL PROPERTY RULE_MESSAGES OFF)
+
+SET(CPACK_SOURCE_IGNORE_FILES "~$;\\.cvsignore$;^C:/hoffman/My Builds/testcase.*/CVS/;^C:/hoffman/My Builds/testcase.*/\\.svn/;^C:/hoffman/My Builds/testcase.*/sweigart/;^C:/hoffman/My Builds/testcase/www/eospaper/solution/eos2001/;^C:/hoffman/My Builds/testcase/www/eospaper/solution/opal_tables_new/;^C:/hoffman/My Builds/testcase/COPYING$;^C:/hoffman/My Builds/testcase/INSTALL$;^C:/hoffman/My Builds/testcase/Makefile$;^C:/hoffman/My Builds/testcase/Makefile\\.in$;^C:/hoffman/My Builds/testcase/.*\\.lo$;^C:/hoffman/My Builds/testcase/.*\\.la$;^C:/hoffman/My Builds/testcase/mkinstalldirs$;^C:/hoffman/My Builds/testcase/missing$;^C:/hoffman/My Builds/testcase/ltmain\\.sh$;^C:/hoffman/My Builds/testcase/libtool$;^C:/hoffman/My Builds/testcase/install-sh$;^C:/hoffman/My Builds/testcase/configure$;^C:/hoffman/My Builds/testcase/config\\.sub$;^C:/hoffman/My Builds/testcase/config\\.status$;^C:/hoffman/My Builds/testcase/config\\.log$;^C:/hoffman/My Builds/testcase/config\\.guess$;^C:/hoffman/My Builds/testcase/autom4te\\.cache$;^C:/hoffman/My Builds/testcase/aclocal\\.m4$;^C:/hoffman/My Builds/testcase/depcomp$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/rho-T-loci/0\\.075\\.model_cassisi_eos1_10$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/rho-T-loci/0\\.075\\.model_cassisi_eos1_10_corr$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/rho-T-loci/0\\.1\\.model_cassisi_eos1$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/rho-T-loci/0\\.1\\.model_cassisi_scvh$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/rho-T-loci/0\\.1\\.modelc$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/rho-T-loci/0\\.3\\.modelc$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/rho-T-loci/1\\.0\\.modelc$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/rho-T-loci/1\\.0\\.rgbtip\\.modelc$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/rho-T-loci/1\\.0\\.zahb\\.modelc$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/rho-T-loci/0\\.1\\.model$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/rho-T-loci/1\\.0\\.model$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/rho-T-loci/0\\.3\\.model$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/rho-T-loci/0\\.085\\.model$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/.*\\.ps$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange\\.mem$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange\\.aux$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange\\.log$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange\\.dvi$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange\\.tex\\.bak$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/head\\.tmp$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/body\\.tmp$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/prior-dvi\\.aux$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/j10\\.tex$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/j12\\.tex$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/j16\\.tex$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/j20\\.tex$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/j22\\.tex$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/j26\\.tex$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/j30\\.tex$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/j32\\.tex$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/j36\\.tex$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/k10\\.tex$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/k12\\.tex$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/k20\\.tex$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/k22\\.tex$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/k30\\.tex$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/k32\\.tex$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/1_exchange_dgamma1\\.yplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/1_exchange_dlnp\\.yplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/2_exchange_dgamma1\\.yplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/2_exchange_dlnp\\.yplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/linear_exchange_dgamma1\\.yplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/linear_exchange_dlnp\\.yplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/noexchange_dgamma1\\.yplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/noexchange_dlnp\\.yplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/nr_exchange_dgamma1\\.yplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/nr_exchange_dlnp\\.yplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/series_exchange_dgamma1\\.yplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/series_exchange_dlnp\\.yplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_JNR_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_Jseries_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_KNR_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_Kseries_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check34_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check35_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check36_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check43_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check44_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check45_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check46_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check47_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check48_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/tc_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/.*\\.pyc$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/context\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/make\\.out.*$;^C:/hoffman/My Builds/testcase/www/Makefile$;^C:/hoffman/My Builds/testcase/www/Makefile\\.in$;^C:/hoffman/My Builds/testcase/src/.*\\.flc$;^C:/hoffman/My Builds/testcase/src/Makefile$;^C:/hoffman/My Builds/testcase/src/Makefile\\.in$;^C:/hoffman/My Builds/testcase/src/\\.deps$;^C:/hoffman/My Builds/testcase/src/\\.libs$;^C:/hoffman/My Builds/testcase/src/.*\\.la$;^C:/hoffman/My Builds/testcase/src/.*\\.lo$;^C:/hoffman/My Builds/testcase/src/make\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/statef.*\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/0\\.1\\.model$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/0\\.1\\.model_13$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/0\\.1\\.model_23$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/0\\.3\\.model$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/0\\.3\\.model_13$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/0\\.3\\.model_23$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/1\\.0\\.model$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/1\\.0\\.model_13$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/1\\.0\\.model_15$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/1\\.0\\.model_23$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/1\\.0\\.model_rel$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/hot_post_agb\\.model$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/rgb_tip\\.model$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/rgbtip\\.1\\.0\\.model$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/rgbtip\\.1\\.0\\.model_13$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/rgbtip\\.1\\.0\\.model_23$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/start_shellflash\\.model$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/white_dwarf\\.model$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/zahb\\.1\\.0\\.model$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/zahb\\.1\\.0\\.model_13$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/zahb\\.1\\.0\\.model_23$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/zahb\\.model$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/dh/dgamma1$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/dh/dlnp$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/dh/statef_compare\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/fermi_dirac_approx/15gamma1\\.gnuplot$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/fermi_dirac_approx/15lnp\\.gnuplot$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/fermi_dirac_approx/23gamma1\\.gnuplot$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/fermi_dirac_approx/23lnp\\.gnuplot$;^C:/hoffman/My Builds/testcase/www/eospaper/solution/thermodynamic_consistency/.*\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/solution/thermodynamic_consistency/.*\\.results$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/pteh/dgamma1$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/pteh/dlnp$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/pteh/statef_compare\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/newversion_grid/.*\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/newversion_grid/.*\\.err$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/.*\\.ps$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/.*\\.pyc$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/eff_fit\\.aux$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/eff_fit\\.dvi$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/eff_fit\\.log$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/body\\.tmp$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/head\\.tmp$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/prior-dvi\\.aux$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/3order_data\\.tex$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/5order_data\\.tex$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/8order_data\\.tex$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/eff_check8_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/eff_check1_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/eff_check3_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/eff_check5_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/effo_check3_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/effoo_check3_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/fda15gamma1\\.yplot$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/fda15lnp\\.yplot$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/fda23gamma1\\.yplot$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/fda23lnp\\.yplot$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/tc_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/make\\.out.*$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/thermodynamic_consistency/statef_compare\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/thermodynamic_consistency/tc\\.results$;^C:/hoffman/My Builds/testcase/www/eospaper/solution/opal_solar/opal_compare_model\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/solution/opal_solar/opal_compare_solar\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/solution/opal_solar/opal_solar\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/solution/opal_solar/opal_solar_1995\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/solution/opal_solar/statef_opal_model\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/solution/opal_solar/statef_opal_model_1995\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/purehe_newversion_grid/.*\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/purehe_newversion_grid/.*\\.err$;^C:/hoffman/My Builds/testcase/include/Makefile\\.in$;^C:/hoffman/My Builds/testcase/include/Makefile$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/model-loci/0\\.1\\.model_pteh$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/model-loci/1\\.0\\.model_eos1a-eos1$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/model-loci/1\\.0\\.model_pteh$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/model-loci/statef_model_0\\.1\\.model_pteh\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/model-loci/statef_model_1\\.0\\.model_eos1a-eos1\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/model-loci/statef_model_1\\.0\\.model_pteh\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/context/contour\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/context/eos_grid\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/context/statef_grid\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/thermodynamic_consistency/fort\\.91$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/thermodynamic_consistency/statef_compare\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/nocoulomb/dgamma1$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/nocoulomb/dlnp$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/nocoulomb/statef_compare\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/context$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/oldversion_grid$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/2005Ap&SS\\.298\\.\\.135S\\.pdf$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/2007Ap&SS\\.307\\.\\.263C\\.pdf$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/astro-ph\\.9909168_eprint_submitted_to_High_Press\\.Res\\.16,331\\.pdf$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/.*ps.*$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/.*\\.pyc$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/convergence\\.aux$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/convergence\\.dvi$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/convergence\\.log$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/body\\.tmp$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/head\\.tmp$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/prior-dvi\\.aux$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/statef_grid-newversion$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/context\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/pureh_context\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/purehe_context\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/old$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/make\\.out.*$;^C:/hoffman/My Builds/testcase/utils/.*\\.flc$;^C:/hoffman/My Builds/testcase/utils/Makefile$;^C:/hoffman/My Builds/testcase/utils/Makefile\\.in$;^C:/hoffman/My Builds/testcase/utils/\\.deps$;^C:/hoffman/My Builds/testcase/utils/\\.libs$;^C:/hoffman/My Builds/testcase/utils/.*\\.la$;^C:/hoffman/My Builds/testcase/utils/.*\\.lo$;^C:/hoffman/My Builds/testcase/utils/free_eos_test$;^C:/hoffman/My Builds/testcase/utils/test_rosenbrock$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/eff_check/eff_check1\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/eff_check/eff_check3\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/eff_check/eff_check5\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/eff_check/eff_check8\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/eff_check/eff_checknr\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/eff_check/effo_check3\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/eff_check/effoo_check3\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence_20070613$;^C:/hoffman/My Builds/testcase/www/eospaper/text$;^C:/hoffman/My Builds/testcase/www/eospaper/cassisi_book_fig$;^C:/hoffman/My Builds/testcase/www/eospaper/1\\.1\\.0$;^C:/hoffman/My Builds/testcase/www/eospaper/2\\.0\\.0$;^C:/hoffman/My Builds/testcase/www/eospaper/1\\.2\\.0$;^C:/hoffman/My Builds/testcase/www/eospaper/1\\.3\\.0$;^C:/hoffman/My Builds/testcase/www/eospaper/1\\.4\\.0$;^C:/hoffman/My Builds/testcase/www/eospaper/1\\.5\\.0$;^C:/hoffman/My Builds/testcase/www/eospaper/1\\.6\\.0$;^C:/hoffman/My Builds/testcase/www/eospaper/figures$;^C:/hoffman/My Builds/testcase/www/eospaper/old$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/.*\\.ps.*$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/coulomb\\.aux$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/coulomb\\.dvi$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/coulomb\\.log$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/.*\\.pyc$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/body\\.tmp$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/head\\.tmp$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/prior-dvi\\.aux$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/context\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/dh_dgamma1_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/dh_dlnp_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/dhtau_dgamma1_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/dhtau_dlnp_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/nocoulomb_dgamma1_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/nocoulomb_dlnp_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/pteh_dgamma1_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/pteh_dlnp_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/make\\.out.*$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/exchange_JNR\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/exchange_Jseries\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/exchange_KNR\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/exchange_Kseries\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/exchange_check34\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/exchange_check35\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/exchange_check36\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/exchange_check44\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/exchange_check45\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/exchange_check46\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/statef_compare_1_exchange\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/statef_compare_2_exchange\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/statef_compare_linear_exchange\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/statef_compare_noexchange\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/statef_compare_nr_exchange\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/statef_compare_series_exchange\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/1_exchange_dgamma1\\.gnuplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/noexchange_dlnp\\.gnuplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/nr_exchange_dgamma1\\.gnuplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/series_exchange_dlnp\\.gnuplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/series_exchange_dgamma1\\.gnuplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/linear_exchange_dlnp\\.gnuplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/2_exchange_dgamma1\\.gnuplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/nr_exchange_dlnp\\.gnuplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/linear_exchange_dgamma1\\.gnuplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/noexchange_dgamma1\\.gnuplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/1_exchange_dlnp\\.gnuplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/2_exchange_dlnp\\.gnuplot$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/pureh_newversion_grid/.*\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/pureh_newversion_grid/.*\\.err$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/dhtau/dgamma1$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/dhtau/dlnp$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/dhtau/statef_compare\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/model-loci/statef_model_0\\.1\\.model\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/model-loci/statef_model_0\\.3\\.model\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/model-loci/statef_model_1\\.0\\.model\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/model-loci/statef_model_1\\.0\\.model_linear\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/model-loci/statef_model_1\\.0\\.model_noexchange\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/model-loci/statef_model_1\\.0\\.model_nr\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/model-loci/statef_model_1\\.0\\.rgbtip\\.model\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/model-loci/statef_model_1\\.0\\.zahb\\.model\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/model-loci/1\\.0\\.zahb\\.model$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/model-loci/1\\.0\\.rgbtip\\.model$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/model-loci/1\\.0\\.model_linear$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/model-loci/1\\.0\\.model_noexchange$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/model-loci/1\\.0\\.model_nr$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/model-loci/0\\.1\\.model$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/model-loci/1\\.0\\.model$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/model-loci/0\\.3\\.model$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/context/contour\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/context/eos_grid\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/context/statef_grid\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/rho-T-loci/gong/delta\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/rho-T-loci/gong/m0085eos1gong\\.ascii$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/rho-T-loci/gong/m0085eos2gong\\.ascii$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/coulomb_adjust/coulomb_adjust\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/solution/.*\\.ps$;^C:/hoffman/My Builds/testcase/www/eospaper/solution/.*\\.pyc$;^C:/hoffman/My Builds/testcase/www/eospaper/solution/head\\.tmp$;^C:/hoffman/My Builds/testcase/www/eospaper/solution/body\\.tmp$;^C:/hoffman/My Builds/testcase/www/eospaper/solution/prior-dvi\\.aux$;^C:/hoffman/My Builds/testcase/www/eospaper/solution/solution\\.aux$;^C:/hoffman/My Builds/testcase/www/eospaper/solution/solution\\.log$;^C:/hoffman/My Builds/testcase/www/eospaper/solution/solution\\.dvi$;^C:/hoffman/My Builds/testcase/www/eospaper/solution/rtc_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/solution/tc_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/solution/make\\.out.*$")
+
+#
+# Define a macro
+#
+MACRO(ASSERT value msg)
+ IF (NOT ${value})
+ MESSAGE ("Assertion failure:" ${msg} )
+ ENDIF (NOT ${value})
+ENDMACRO(ASSERT)
+
+# invoke the macro
+ASSERT(Complex_BINARY_DIR "The PROJECT command is broken")
+
+#
+# Define a var args macro, it must take two or four args
+#
+MACRO(TEST_ARGC value1 value2)
+ ADD_DEFINITIONS(${value1} ${value2})
+ IF (${ARGC} MATCHES 4)
+ ADD_DEFINITIONS(${ARGV2} ${ARGV3})
+ ENDIF (${ARGC} MATCHES 4)
+ENDMACRO(TEST_ARGC)
+
+# invoke the macro
+TEST_ARGC(-DCMAKE_ARGV1 -DCMAKE_ARGV2 -DCMAKE_ARGV3 -DCMAKE_ARGV4)
+
+MACRO(TEST_VAR_ARG fa)
+ IF("${ARGV}" MATCHES "^1;2;3$")
+ MESSAGE(STATUS "ARGV works")
+ ELSE("${ARGV}" MATCHES "^1;2;3$")
+ MESSAGE(FATAL_ERROR "ARGV does not work; got \"${ARGV}\" instead of \"1;2;3\"")
+ ENDIF("${ARGV}" MATCHES "^1;2;3$")
+ IF("${ARGN}" MATCHES "^2;3$")
+ MESSAGE(STATUS "ARGN works")
+ ELSE("${ARGN}" MATCHES "^2;3$")
+ MESSAGE(FATAL_ERROR "ARGV does not work; got \"${ARGN}\" instead of \"2;3\"")
+ ENDIF("${ARGN}" MATCHES "^2;3$")
+ENDMACRO(TEST_VAR_ARG)
+
+TEST_VAR_ARG(1 2 3)
+
+# Floating-point comparison test.
+IF(2.4 LESS 2.4)
+ MESSAGE(FATAL_ERROR "Failed: 2.4 LESS 2.4")
+ENDIF(2.4 LESS 2.4)
+IF(2.4 GREATER 2.4)
+ MESSAGE(FATAL_ERROR "Failed: 2.4 GREATER 2.4")
+ENDIF(2.4 GREATER 2.4)
+IF(NOT 2.4 EQUAL 2.4)
+ MESSAGE(FATAL_ERROR "Failed: NOT 2.4 EQUAL 2.4")
+ENDIF(NOT 2.4 EQUAL 2.4)
+
+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(NOT CMAKE_COMPILER_IS_GNUCXX)
+ENDIF(CMAKE_SYSTEM MATCHES "OSF1-V.*")
+
+
+ADD_DEFINITIONS(-DCMAKE_IS_FUN)
+ADD_DEFINITIONS(-DCMAKE_IS_REALLY_FUN)
+SET_PROPERTY(DIRECTORY
+ PROPERTY COMPILE_DEFINITIONS_RELEASE
+ CMAKE_IS_FUN_IN_RELEASE_MODE
+ )
+
+SET(TEST_SEP "a b c")
+SEPARATE_ARGUMENTS(TEST_SEP)
+
+
+#
+# Include vars from a file and from a cache
+#
+IF (EXISTS ${Complex_SOURCE_DIR}/VarTests.cmake)
+ INCLUDE(${Complex_SOURCE_DIR}/VarTests.cmake)
+ENDIF (EXISTS ${Complex_SOURCE_DIR}/VarTests.cmake)
+INCLUDE(fileshouldnotbehere OPTIONAL)
+LOAD_CACHE(${Complex_SOURCE_DIR}/Cache
+ EXCLUDE
+ CACHE_TEST_VAR_EXCLUDED
+ INCLUDE_INTERNALS
+ CACHE_TEST_VAR_INTERNAL)
+
+LOAD_CACHE(${Complex_SOURCE_DIR}/Cache READ_WITH_PREFIX foo CACHE_TEST_VAR2)
+IF(${fooCACHE_TEST_VAR2} MATCHES bar)
+ MESSAGE("Load cache worked: ${fooCACHE_TEST_VAR2}")
+ELSE(${fooCACHE_TEST_VAR2} MATCHES bar)
+ MESSAGE(FATAL_ERROR "Load cache with prefix failed: ${fooCACHE_TEST_VAR2}")
+ENDIF(${fooCACHE_TEST_VAR2} MATCHES bar)
+
+
+
+#
+# Specify include and lib dirs
+# (BEFORE is for coverage)
+#
+INCLUDE_DIRECTORIES(
+ Library
+)
+
+INCLUDE_DIRECTORIES(BEFORE
+ ${Complex_BINARY_DIR}
+)
+INCLUDE_DIRECTORIES(SYSTEM Library/SystemDir)
+
+INCLUDE_REGULAR_EXPRESSION("^(cmTest|file|sharedFile|test).*$" "^cmMissing")
+
+LINK_DIRECTORIES(
+ ${Complex_BINARY_DIR}/Library
+)
+
+#
+# check for SET CACHE FORCE
+#
+SET(FORCE_TEST 1 CACHE STRING "a test")
+SET(FORCE_TEST 0 CACHE STRING "a test" FORCE)
+
+#
+# Lib and exe path
+#
+SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${Complex_BINARY_DIR}/lib/static")
+SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${Complex_BINARY_DIR}/lib")
+SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${Complex_BINARY_DIR}/bin")
+
+MESSAGE (Test " " escape " " semi-colon " " \; \;)
+#
+# Exec program (TODO: test a result)
+# Increase coverage.
+#
+MESSAGE("\nIgnore this message")
+OPTION(NO_EXEC_PROGRAM "Do not test EXEC_PROGRAM" 0)
+IF (NOT NO_EXEC_PROGRAM)
+ EXEC_PROGRAM(${CMAKE_COMMAND} ARGS -E echo NO_EXEC_PROGRAM "${Complex_BINARY_DIR}")
+ELSE (NOT NO_EXEC_PROGRAM)
+ MESSAGE("Set this option ON")
+ENDIF (NOT NO_EXEC_PROGRAM)
+
+MARK_AS_ADVANCED(NO_EXEC_PROGRAM)
+MARK_AS_ADVANCED(CLEAR NO_EXEC_PROGRAM)
+
+# Execute a process. Add coverage for this command.
+EXECUTE_PROCESS(
+ COMMAND ${CMAKE_COMMAND} -E echo "ABCDEFG"
+ OUTPUT_VARIABLE TEST_OUT
+ )
+IF("${TEST_OUT}" MATCHES "^ABCDEFG\n$")
+ELSE("${TEST_OUT}" MATCHES "^ABCDEFG\n$")
+ MESSAGE(SEND_ERROR "EXECUTE_PROCESS output test failed: [${TEST_OUT}]")
+ENDIF("${TEST_OUT}" MATCHES "^ABCDEFG\n$")
+
+# This test has some problems on UNIX systems. Disabling for now.
+#
+# EXECUTE_PROCESS(
+# COMMAND ${CMAKE_COMMAND} -E echo "ABCDEFG"
+# COMMAND /process/does/not/exist
+# OUTPUT_QUIET
+# ERROR_QUIET
+# RESULT_VARIABLE RESULT
+# )
+# IF("${RESULT}" MATCHES "^0$")
+# MESSAGE(SEND_ERROR
+# "EXECUTE_PROCESS result test failed with RESULT=[${RESULT}]")
+# ELSE("${RESULT}" MATCHES "^0$")
+# MESSAGE(STATUS "EXECUTE_PROCESS result test passed with RESULT=[${RESULT}]")
+# ENDIF("${RESULT}" MATCHES "^0$")
+
+#
+# Create directory.
+# The 'complex' executable will then test if this dir exists,
+# sadly it won't be able to remove it.
+#
+MAKE_DIRECTORY("${Complex_BINARY_DIR}/make_dir")
+
+#
+# Test FIND_LIBARY
+# Create a dummy empty lib
+#
+CONFIGURE_FILE(
+ ${Complex_SOURCE_DIR}/Library/dummy
+ ${Complex_BINARY_DIR}/Library/dummylib.lib
+ COPYONLY IMMEDIATE)
+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)
+ENDFOREACH (ext)
+
+FIND_LIBRARY(FIND_DUMMY_LIB
+ dummylib
+ PATHS
+ ${Complex_BINARY_DIR}/Library DOC "find dummy lib")
+
+FIND_LIBRARY(FIND_DUMMY_LIB
+ NAMES dummylib dummylib2
+ PATHS
+ ${Complex_BINARY_DIR}/Library DOC "find dummy lib")
+
+# This doesn't work for platforms that have a shared library and an import
+# library, like Windows with .dll and .lib. Limit is to ".so" now because it's
+# known to work there.
+IF(CMAKE_SHARED_LIBRARY_SUFFIX STREQUAL ".so")
+ FIND_LIBRARY(FIND_DUMMY_SHLIB_VERSIONED
+ NAMES libdummylib${CMAKE_SHARED_LIBRARY_SUFFIX}.2
+ PATHS ${Complex_BINARY_DIR}/Library
+ DOC "find versioned dummy shared lib"
+ NO_DEFAULT_PATH)
+
+ IF(NOT FIND_DUMMY_SHLIB_VERSIONED MATCHES "/libdummylib${CMAKE_SHARED_LIBRARY_SUFFIX}.2")
+ MESSAGE(SEND_ERROR "FIND_DUMMY_SHLIB_VERSIONED is not set correctly: "
+ "${FIND_DUMMY_SHLIB_VERSIONED}")
+ ENDIF()
+ENDIF()
+
+# Static library, should work everywhere
+FIND_LIBRARY(FIND_DUMMY_STLIB_VERSIONED
+ NAMES libdummylib${CMAKE_STATIC_LIBRARY_SUFFIX}.2
+ PATHS ${Complex_BINARY_DIR}/Library
+ DOC "find versioned dummy static lib"
+ NO_DEFAULT_PATH)
+
+IF(NOT FIND_DUMMY_STLIB_VERSIONED MATCHES "/libdummylib${CMAKE_STATIC_LIBRARY_SUFFIX}.2")
+ MESSAGE(SEND_ERROR "FIND_DUMMY_STLIB_VERSIONED is not set correctly: "
+ "${FIND_DUMMY_STLIB_VERSIONED}")
+ENDIF()
+
+#
+# Test SET_SOURCE_FILES_PROPERTIES
+#
+SET_SOURCE_FILES_PROPERTIES(nonexisting_file2
+ GENERATED
+ ABSTRACT
+ WRAP_EXCLUDE
+ COMPILE_FLAGS "-foo -bar")
+
+GET_SOURCE_FILE_PROPERTY(FILE_HAS_ABSTRACT nonexisting_file2 ABSTRACT)
+GET_SOURCE_FILE_PROPERTY(FILE_HAS_WRAP_EXCLUDE nonexisting_file2 WRAP_EXCLUDE)
+GET_SOURCE_FILE_PROPERTY(FILE_COMPILE_FLAGS nonexisting_file2 COMPILE_FLAGS)
+
+SET_SOURCE_FILES_PROPERTIES(nonexisting_file3 PROPERTIES
+ GENERATED 1
+ ABSTRACT 1
+ WRAP_EXCLUDE 1
+ COMPILE_FLAGS "-foo -bar")
+GET_SOURCE_FILE_PROPERTY(FILE_HAS_ABSTRACT nonexisting_file3 ABSTRACT)
+GET_SOURCE_FILE_PROPERTY(FILE_HAS_WRAP_EXCLUDE nonexisting_file3 WRAP_EXCLUDE)
+GET_SOURCE_FILE_PROPERTY(FILE_COMPILE_FLAGS nonexisting_file3 COMPILE_FLAGS)
+
+#
+# Test registry (win32)
+# Create a file, put its path in a registry key, try to find the file in that
+# path using that registry key, then remove the file and the key
+#
+IF (WIN32)
+ IF (NOT UNIX)
+ SET(dir "${Complex_BINARY_DIR}/registry_dir")
+ SET(file "registry_test_dummy")
+ SET(hkey "HKEY_CURRENT_USER\\Software\\Kitware\\CMake\\Tests\\Complex;registry_test")
+ CONFIGURE_FILE(
+ ${Complex_SOURCE_DIR}/Library/dummy
+ "${dir}/${file}"
+ COPYONLY IMMEDIATE)
+ EXEC_PROGRAM(${CMAKE_COMMAND} ARGS "-E write_regv \"${hkey}\" \"${dir}\"")
+ FIND_PATH(REGISTRY_TEST_PATH
+ ${file}
+ "[${hkey}]" DOC "Registry_Test_Path")
+ EXEC_PROGRAM(${CMAKE_COMMAND} ARGS "-E delete_regv \"${hkey}\"")
+ EXEC_PROGRAM(${CMAKE_COMMAND} ARGS "-E remove \"${dir}/${file}\"")
+ ENDIF (NOT UNIX)
+ENDIF (WIN32)
+
+#
+# Test a set and a remove
+#
+SET(REMOVE_STRING a b c d e f)
+SET(removeVar1 c e)
+REMOVE(REMOVE_STRING ${removeVar1} f)
+
+#
+# Test an IF inside a FOREACH.
+#
+FOREACH(x "a")
+ IF(${x} MATCHES "a")
+ # Should always execute.
+ SET(IF_INSIDE_FOREACH_THEN_EXECUTED 1)
+ ELSE(${x} MATCHES "a")
+ # Should never execute.
+ SET(IF_INSIDE_FOREACH_ELSE_EXECUTED 1)
+ ENDIF(${x} MATCHES "a")
+ENDFOREACH(x)
+
+# test WHILE command
+SET (while_var 1)
+WHILE (while_var LESS 1000)
+ SET(while_var ${while_var}0)
+ENDWHILE(while_var LESS 1000)
+
+SET(SHOULD_BE_ZERO )
+SET(SHOULD_BE_ONE 1)
+
+# test elseif functionality, the mess below tries to catch problem
+# of clauses being executed early or late etc
+set (RESULT 3)
+if (RESULT EQUAL 1)
+ if (RESULT EQUAL 2)
+ set (ELSEIF_RESULT 1)
+ elseif (RESULT EQUAL 3)
+ set (ELSEIF_RESULT 1)
+ endif (RESULT EQUAL 2)
+elseif (RESULT EQUAL 2)
+ set (ELSEIF_RESULT 1)
+elseif (RESULT EQUAL 3)
+ if (RESULT EQUAL 2)
+ set (ELSEIF_RESULT 1)
+ elseif (RESULT EQUAL 3)
+ if (NOT ELSEIF_RESULT EQUAL 1)
+ set (ELSEIF_RESULT 2)
+ endif (NOT ELSEIF_RESULT EQUAL 1)
+ endif (RESULT EQUAL 2)
+elseif (RESULT EQUAL 4)
+ if (RESULT EQUAL 2)
+ set (ELSEIF_RESULT 1)
+ elseif (RESULT EQUAL 3)
+ set (ELSEIF_RESULT 1)
+ endif (RESULT EQUAL 2)
+else (RESULT EQUAL 1)
+ if (RESULT EQUAL 2)
+ set (ELSEIF_RESULT 1)
+ elseif (RESULT EQUAL 3)
+ set (ELSEIF_RESULT 1)
+ endif (RESULT EQUAL 2)
+endif (RESULT EQUAL 1)
+
+if (NOT ELSEIF_RESULT EQUAL 2)
+ set (ELSEIF_RESULT 0)
+endif (NOT ELSEIF_RESULT EQUAL 2)
+
+# test handling of parenthetical groups in conditionals
+if (2 GREATER 1 AND (4 LESS 3 OR 5 LESS 6) AND NOT (7 GREATER 8))
+ set(CONDITIONAL_PARENTHESES 1)
+endif()
+
+
+#
+# Configure file
+# (plug vars to #define so that they can be tested)
+#
+CONFIGURE_FILE(
+ ${Complex_SOURCE_DIR}/cmTestConfigure.h.in
+ ${Complex_BINARY_DIR}/cmTestConfigure.h)
+
+SET(STRING_WITH_QUOTES "\"hello world\"")
+# test CONFIGURE_FILE with ESCAPE_QUOTES on
+CONFIGURE_FILE(
+ ${Complex_SOURCE_DIR}/cmTestConfigureEscape.h.in
+ ${Complex_BINARY_DIR}/cmTestConfigureEscape.h ESCAPE_QUOTES)
+
+# Test regular expression commands.
+STRING(REGEX MATCH "b" RESULT "abc")
+IF(NOT RESULT)
+ MESSAGE(SEND_ERROR "STRING(REGEX MATCH ... ) test failed.")
+ENDIF(NOT RESULT)
+STRING(REGEX MATCHALL "b" RESULT "abcb")
+IF(NOT RESULT)
+ MESSAGE(SEND_ERROR "STRING(REGEX MATCHALL ... ) test failed.")
+ENDIF(NOT RESULT)
+STRING(REGEX REPLACE ".([bd])." "[\\1]" RESULT "a(b)c(d)e")
+IF("x${RESULT}" MATCHES "^xa\\[b\\]c\\[d\\]e$")
+ SET(STRING_REGEX_PASSED 1)
+ENDIF("x${RESULT}" MATCHES "^xa\\[b\\]c\\[d\\]e$")
+IF(NOT STRING_REGEX_PASSED)
+ MESSAGE(SEND_ERROR
+ "STRING(REGEX REPLACE ... ) test failed (\"${RESULT}\" v. \"a[b]c[d]e\")")
+ENDIF(NOT STRING_REGEX_PASSED)
+
+
+#
+# Create the libs and the main exe
+#
+ADD_SUBDIRECTORY(Library)
+ADD_SUBDIRECTORY(Executable)
+SUBDIR_DEPENDS(Executable Library)
+EXPORT_LIBRARY_DEPENDENCIES(${Complex_BINARY_DIR}/ComplexLibraryDepends.cmake)
+INCLUDE(${Complex_BINARY_DIR}/ComplexLibraryDepends.cmake OPTIONAL)
diff --git a/Tests/Complex/Cache/CMakeCache.txt b/Tests/Complex/Cache/CMakeCache.txt
new file mode 100644
index 000000000..17c55aa01
--- /dev/null
+++ b/Tests/Complex/Cache/CMakeCache.txt
@@ -0,0 +1,34 @@
+# This is the CMakeCache file.
+# For build in directory: d:/build/kitware/cmake/CMake-nmake/Tests/Complex
+# You can edit this file to change values found and used by cmake.
+# If you do not want to change any of the values, simply exit the editor.
+# If you do want to change a value, simply edit, save, and exit the editor.
+# The syntax for the file is as follows:
+# KEY:TYPE=VALUE
+# KEY is the name of a varible in the cache.
+# TYPE is a hint to GUI's for the type of VALUE, DO NOT EDIT TYPE!.
+# VALUE is the current value for the KEY.
+
+########################
+# EXTERNAL cache entries
+########################
+
+//A var.
+CACHE_TEST_VAR1:STRING=foo
+
+//A var.
+CACHE_TEST_VAR2:FILEPATH=bar
+
+//A var.
+CACHE_TEST_VAR3:BOOL=1
+
+//A var.
+CACHE_TEST_VAR_EXCLUDED:BOOL=1
+
+
+########################
+# INTERNAL cache entries
+########################
+
+//A var.
+CACHE_TEST_VAR_INTERNAL:INTERNAL=bar
diff --git a/Tests/Complex/Executable/A.cxx b/Tests/Complex/Executable/A.cxx
new file mode 100644
index 000000000..fb3eb0819
--- /dev/null
+++ b/Tests/Complex/Executable/A.cxx
@@ -0,0 +1,9 @@
+// Include code from a header that should not be compiled separately.
+#include "A.hh"
+
+#include <stdio.h>
+int main()
+{
+ printf("#define A_VALUE %d\n", A());
+ return 0;
+}
diff --git a/Tests/Complex/Executable/A.h b/Tests/Complex/Executable/A.h
new file mode 100644
index 000000000..25c45fcbf
--- /dev/null
+++ b/Tests/Complex/Executable/A.h
@@ -0,0 +1,4 @@
+// This header should not be compiled directly but through inclusion
+// in A.cxx through A.hh.
+extern int A();
+int A() { return 10; }
diff --git a/Tests/Complex/Executable/A.hh b/Tests/Complex/Executable/A.hh
new file mode 100644
index 000000000..e6bab022e
--- /dev/null
+++ b/Tests/Complex/Executable/A.hh
@@ -0,0 +1,2 @@
+// This header should not be compiled directly but through inclusion in A.cxx
+#include "A.h"
diff --git a/Tests/Complex/Executable/A.txt b/Tests/Complex/Executable/A.txt
new file mode 100644
index 000000000..8ee9462be
--- /dev/null
+++ b/Tests/Complex/Executable/A.txt
@@ -0,0 +1 @@
+This file should not be compiled!
diff --git a/Tests/Complex/Executable/CMakeLists.txt b/Tests/Complex/Executable/CMakeLists.txt
new file mode 100644
index 000000000..345836257
--- /dev/null
+++ b/Tests/Complex/Executable/CMakeLists.txt
@@ -0,0 +1,170 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 1.3)
+#
+# Create exe.
+#
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DTEST_CXX_FLAGS")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DTEST_C_FLAGS")
+
+# Create an imported target for if(TARGET) test below.
+ADD_LIBRARY(ExeImportedTarget UNKNOWN IMPORTED)
+
+# Test if(TARGET) command.
+IF(NOT TARGET CMakeTestLibrary)
+ MESSAGE(FATAL_ERROR "IF(NOT TARGET CMakeTestLibrary) returned true!")
+ENDIF(NOT TARGET CMakeTestLibrary)
+IF(NOT TARGET ExeImportedTarget)
+ MESSAGE(FATAL_ERROR "IF(NOT TARGET ExeImportedTarget) returned true!")
+ENDIF(NOT TARGET ExeImportedTarget)
+IF(TARGET LibImportedTarget)
+ MESSAGE(FATAL_ERROR "IF(TARGET LibImportedTarget) returned true!")
+ENDIF(TARGET LibImportedTarget)
+IF(TARGET NotATarget)
+ MESSAGE(FATAL_ERROR "IF(TARGET NotATarget) returned true!")
+ENDIF(TARGET NotATarget)
+
+ # Use LINK_LIBRARIES instead of TARGET_LINK_LIBRARIES to
+SET(COMPLEX_LIBS CMakeTestLibrary;CMakeTestLibraryShared;CMakeTestCLibraryShared)
+LINK_LIBRARIES(${COMPLEX_LIBS})
+
+# Test forcing a .cxx file to not build.
+SET_SOURCE_FILES_PROPERTIES(complex_nobuild.cxx PROPERTIES
+ HEADER_FILE_ONLY 1)
+
+# Test forcing a .c file to not build.
+# This makes sure a mixed language library is created
+# with header file only sources
+SET_SOURCE_FILES_PROPERTIES(complex_nobuild.c PROPERTIES
+ HEADER_FILE_ONLY 1)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+ADD_EXECUTABLE(A A.cxx A.hh A.h A.txt)
+ADD_CUSTOM_COMMAND(OUTPUT Aout.h COMMAND A > Aout.h VERBATIM)
+ADD_EXECUTABLE(complex complex testcflags.c Aout.h)
+# Sub1/NameConflictTest.c Sub2/NameConflictTest.c)
+ADD_EXECUTABLE(complex.file complex.file.cxx complex_nobuild.cxx
+ complex_nobuild.c)
+
+IF (UNIX)
+ TARGET_LINK_LIBRARIES(complex ${CMAKE_DL_LIBS})
+ELSE(UNIX)
+ IF (NOT BORLAND)
+ IF(NOT MINGW)
+ TARGET_LINK_LIBRARIES(complex rpcrt4.lib)
+ ENDIF(NOT MINGW)
+ ENDIF(NOT BORLAND)
+ENDIF (UNIX)
+
+# Test linking to static lib when a shared lib has the same name.
+IF(CMAKE_EXE_LINK_STATIC_CXX_FLAGS)
+ ADD_DEFINITIONS(-DCOMPLEX_TEST_LINK_STATIC)
+ TARGET_LINK_LIBRARIES(complex CMakeTestLinkStatic)
+ENDIF(CMAKE_EXE_LINK_STATIC_CXX_FLAGS)
+
+# can we get the path to a source file
+GET_SOURCE_FILE_PROPERTY(A_LOCATION A.cxx LOCATION)
+IF ("${A_LOCATION}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}/A.cxx")
+ ADD_DEFINITIONS(-DCMAKE_FOUND_ACXX)
+ENDIF ("${A_LOCATION}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}/A.cxx")
+
+# get the directory parent
+GET_DIRECTORY_PROPERTY(P_VALUE PARENT_DIRECTORY)
+IF ("${P_VALUE}" STREQUAL "${CMAKE_SOURCE_DIR}")
+ ADD_DEFINITIONS(-DCMAKE_FOUND_PARENT)
+ENDIF ("${P_VALUE}" STREQUAL "${CMAKE_SOURCE_DIR}")
+
+# get the stack of listfiles
+INCLUDE(Included.cmake)
+IF ("${LF_VALUE}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt;${CMAKE_CURRENT_SOURCE_DIR}/Included.cmake")
+ ADD_DEFINITIONS(-DCMAKE_FOUND_LISTFILE_STACK)
+ENDIF ("${LF_VALUE}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt;${CMAKE_CURRENT_SOURCE_DIR}/Included.cmake")
+
+# Test add/remove definitions.
+ADD_DEFINITIONS(
+ -DCOMPLEX_DEFINED_PRE
+ -DCOMPLEX_DEFINED
+ -DCOMPLEX_DEFINED_POST
+ -DCOMPLEX_DEFINED
+ )
+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")
+ADD_CUSTOM_COMMAND(TARGET complex PRE_BUILD
+ COMMAND ${CREATE_FILE_EXE}
+ ARGS "${Complex_BINARY_DIR}/Executable/prelink.txt")
+ADD_CUSTOM_COMMAND(TARGET complex POST_BUILD
+ COMMAND ${CREATE_FILE_EXE}
+ ARGS "${Complex_BINARY_DIR}/Executable/postbuild.txt")
+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")
+
+SET_SOURCE_FILES_PROPERTIES(complex
+ COMPILE_FLAGS
+ "-DFILE_HAS_EXTRA_COMPILE_FLAGS"
+ #" -DFILE_DEFINE_STRING=\\\"hello\\\""
+ OBJECT_DEPENDS ${Complex_BINARY_DIR}/cmTestGeneratedHeader.h
+)
+SET_TARGET_PROPERTIES(complex PROPERTIES COMPILE_FLAGS "-DCOMPLEX_TARGET_FLAG")
+ADD_CUSTOM_COMMAND(
+ TARGET complex
+ SOURCE ${Complex_SOURCE_DIR}/cmTestGeneratedHeader.h.in
+ COMMAND ${CMAKE_COMMAND}
+ ARGS -E copy ${Complex_SOURCE_DIR}/cmTestGeneratedHeader.h.in
+ ${Complex_BINARY_DIR}/cmTestGeneratedHeader.h
+ OUTPUTS ${Complex_BINARY_DIR}/cmTestGeneratedHeader.h
+ DEPENDS ${CMAKE_COMMAND}
+)
+
+# Test creating an executable that is not built by default.
+ADD_EXECUTABLE(notInAllExe EXCLUDE_FROM_ALL notInAllExe.cxx)
+TARGET_LINK_LIBRARIES(notInAllExe notInAllLib)
+
+# Test user-value flag mapping for the VS IDE.
+IF(MSVC)
+ SET_TARGET_PROPERTIES(notInAllExe PROPERTIES
+ LINK_FLAGS "/NODEFAULTLIB:LIBC;LIBCMT;MSVCRT")
+ENDIF(MSVC)
+
+# Test creating a custom target that builds not-in-all targets.
+ADD_CUSTOM_TARGET(notInAllCustom)
+ADD_DEPENDENCIES(notInAllCustom notInAllExe)
+
+#
+# Output the files required by 'complex' to a file.
+#
+# This test has been moved to the 'required' subdir so that it
+# has no side-effects on the current Makefile (duplicated source file
+# due to source list expansion done twice).
+#
+ADD_SUBDIRECTORY(Temp)
+
+IF(CMAKE_COMPILER_IS_GNUCXX AND CMAKE_INCLUDE_SYSTEM_FLAG_CXX)
+ ADD_EXECUTABLE(testSystemDir testSystemDir.cxx)
+ SET_TARGET_PROPERTIES(testSystemDir PROPERTIES COMPILE_FLAGS "-Werror")
+ENDIF(CMAKE_COMPILER_IS_GNUCXX AND CMAKE_INCLUDE_SYSTEM_FLAG_CXX)
+
+#
+# Extra coverage.Not used.
+#
+INSTALL_TARGETS(/tmp complex)
+INSTALL_PROGRAMS(/tmp complex)
+
+CONFIGURE_FILE(
+ ${Complex_SOURCE_DIR}/Executable/cmVersion.h.in
+ ${Complex_BINARY_DIR}/cmVersion.h)
+
+SOURCE_GROUP(A_GROUP ".cxx")
+SOURCE_GROUP(B_GROUP REGULAR_EXPRESSION "cxx")
+SOURCE_GROUP(C_GROUP FILES complex.cxx)
+
+FILE(WRITE ${Complex_BINARY_DIR}/A/libA.a "test")
+FILE(WRITE ${Complex_BINARY_DIR}/A/libC.a "test")
+FILE(WRITE ${Complex_BINARY_DIR}/B/libB.a "test")
+FILE(WRITE ${Complex_BINARY_DIR}/B/libA.a "test")
+FILE(WRITE ${Complex_BINARY_DIR}/C/libC.a "test")
+FILE(WRITE ${Complex_BINARY_DIR}/C/libB.a "test")
diff --git a/Tests/Complex/Executable/Included.cmake b/Tests/Complex/Executable/Included.cmake
new file mode 100644
index 000000000..2d1ea3e8c
--- /dev/null
+++ b/Tests/Complex/Executable/Included.cmake
@@ -0,0 +1,2 @@
+GET_DIRECTORY_PROPERTY(LF_VALUE LISTFILE_STACK)
+
diff --git a/Tests/Complex/Executable/Sub1/NameConflictTest.c b/Tests/Complex/Executable/Sub1/NameConflictTest.c
new file mode 100644
index 000000000..87203861f
--- /dev/null
+++ b/Tests/Complex/Executable/Sub1/NameConflictTest.c
@@ -0,0 +1,4 @@
+int NameConflictTest1()
+{
+ return 0;
+}
diff --git a/Tests/Complex/Executable/Sub2/NameConflictTest.c b/Tests/Complex/Executable/Sub2/NameConflictTest.c
new file mode 100644
index 000000000..4a3257255
--- /dev/null
+++ b/Tests/Complex/Executable/Sub2/NameConflictTest.c
@@ -0,0 +1,4 @@
+int NameConflictTest2()
+{
+ return 0;
+}
diff --git a/Tests/Complex/Executable/Temp/CMakeLists.txt b/Tests/Complex/Executable/Temp/CMakeLists.txt
new file mode 100644
index 000000000..f00955029
--- /dev/null
+++ b/Tests/Complex/Executable/Temp/CMakeLists.txt
@@ -0,0 +1,8 @@
+#
+# Output the files required by 'complex' to a file.
+# The 'complex' executable will then test if this file exists and remove it.
+# The contents of this file is not tested (absolute paths).
+#
+OUTPUT_REQUIRED_FILES(
+ ${Complex_SOURCE_DIR}/Executable/complex.cxx
+ ${Complex_BINARY_DIR}/Executable/Temp/complex-required.txt)
diff --git a/Tests/Complex/Executable/cmVersion.h.in b/Tests/Complex/Executable/cmVersion.h.in
new file mode 100644
index 000000000..de7522d1d
--- /dev/null
+++ b/Tests/Complex/Executable/cmVersion.h.in
@@ -0,0 +1 @@
+#define CMAKE_MINIMUM_REQUIRED_VERSION "${CMAKE_MINIMUM_REQUIRED_VERSION}"
diff --git a/Tests/Complex/Executable/complex.cxx b/Tests/Complex/Executable/complex.cxx
new file mode 100644
index 000000000..1901d9914
--- /dev/null
+++ b/Tests/Complex/Executable/complex.cxx
@@ -0,0 +1,1026 @@
+#include "cmTestConfigure.h"
+#include "cmTestConfigureEscape.h"
+#include "cmTestGeneratedHeader.h"
+#include "cmVersion.h"
+#include "ExtraSources/file1.h"
+#include "Aout.h"
+#include "file2.h"
+#include "sharedFile.h"
+extern "C" {
+#include "testConly.h"
+}
+#include <vector>
+#include <string>
+#include <iostream>
+#include <string.h>
+
+#include <stdio.h>
+#include <sys/stat.h>
+#if !defined(S_ISDIR)
+# define S_ISDIR(mode) ((mode) & _S_IFDIR)
+#endif
+
+#ifdef COMPLEX_TEST_LINK_STATIC
+extern "C"
+{
+ int TestLinkGetType();
+}
+#endif
+
+int cm_passed = 0;
+int cm_failed = 0;
+// ======================================================================
+
+void cmFailed(const char* Message, const char* m2= "", const char* m3 = "")
+{
+ std::cout << "FAILED: " << Message << m2 << m3 << "\n";
+ cm_failed++;
+}
+
+// ======================================================================
+
+void cmPassed(const char* Message, const char* m2="")
+{
+ std::cout << "Passed: " << Message << m2 << "\n";
+ cm_passed++;
+}
+
+#ifndef COMPLEX_DEFINED_PRE
+# error "COMPLEX_DEFINED_PRE not defined!"
+#endif
+
+#ifdef COMPLEX_DEFINED
+# error "COMPLEX_DEFINED is defined but it should not!"
+#endif
+
+#ifndef COMPLEX_DEFINED_POST
+# error "COMPLEX_DEFINED_POST not defined!"
+#endif
+
+#ifndef CMAKE_IS_REALLY_FUN
+# error This is a problem. Looks like ADD_DEFINITIONS and REMOVE_DEFINITIONS does not work
+#endif
+
+#if defined(NDEBUG) && !defined(CMAKE_IS_FUN_IN_RELEASE_MODE)
+# error Per-configuration directory-level definition not inherited.
+#endif
+
+// ======================================================================
+
+void TestAndRemoveFile(const char* filename)
+{
+ struct stat st;
+ if(stat(filename, &st) < 0)
+ {
+ cmFailed("Could not find file: ", filename);
+ }
+ else
+ {
+ if (remove(filename) < 0)
+ {
+ cmFailed("Unable to remove file. It does not imply that this test failed, but it *will* be corrupted thereafter if this file is not removed: ", filename);
+ }
+ else
+ {
+ cmPassed("Find and remove file: ", filename);
+ }
+ }
+}
+
+// ======================================================================
+
+void TestDir(const char* filename)
+{
+ struct stat st;
+ if(stat(filename, &st) < 0 || !S_ISDIR(st.st_mode))
+ {
+ cmFailed("Could not find dir: ", filename);
+ }
+ else
+ {
+ cmPassed("Find dir: ", filename);
+ }
+}
+
+// Here is a stupid function that tries to use std::string methods
+// so that the dec cxx compiler will instantiate the stuff that
+// we are using from the CMakeLib library....
+void ForceStringUse()
+{
+ std::vector<std::string> v;
+ std::vector<std::string> v2;
+ v = v2;
+ std::string cachetest = CACHE_TEST_VAR_INTERNAL;
+ v.push_back(cachetest);
+ v2 = v;
+ std::string x(5,'x');
+ char buff[5];
+ x.copy(buff, 1, 0);
+ x[0] = 'a';
+ std::string::size_type pos = 0;
+ x.replace(pos, pos, pos, 'x');
+ std::string copy = cachetest;
+ cachetest.find("bar");
+ cachetest.rfind("bar");
+ copy.append(cachetest);
+ copy = cachetest.substr(0, cachetest.size());
+}
+
+
+// defined in testcflags.c
+extern "C" int TestCFlags(char* m);
+extern "C" int TestTargetCompileFlags(char* m);
+
+#if 0
+// defined in Sub1/NameConflictTest.c
+extern "C" int NameConflictTest1();
+// defined in Sub2/NameConflictTest.c
+extern "C" int NameConflictTest2();
+#endif
+
+// ======================================================================
+
+int main()
+{
+#if 0
+ if(NameConflictTest1() == 0 && NameConflictTest2() == 0)
+ {
+ cmPassed("Sub dir with same named source works");
+ }
+ else
+ {
+ cmFailed("Sub dir with same named source fails");
+ }
+#endif
+ if(file1() != 1)
+ {
+ cmFailed("Call to file1 function from library failed.");
+ }
+ else
+ {
+ cmPassed("Call to file1 function returned 1.");
+ }
+#ifndef COMPLEX_TARGET_FLAG
+ cmFailed("COMPILE_FLAGS did not work with SET_TARGET_PROPERTIES");
+#else
+ cmPassed("COMPILE_FLAGS did work with SET_TARGET_PROPERTIES");
+#endif
+
+#ifdef ELSEIF_RESULT
+ cmPassed("ELSEIF did work");
+#else
+ cmFailed("ELSEIF did not work");
+#endif
+
+#ifdef CONDITIONAL_PARENTHESES
+ cmPassed("CONDITIONAL_PARENTHESES did work");
+#else
+ cmFailed("CONDITIONAL_PARENTHESES did not work");
+#endif
+
+ if(file2() != 1)
+ {
+ cmFailed("Call to file2 function from library failed.");
+ }
+ else
+ {
+ cmPassed("Call to file2 function returned 1.");
+ }
+#ifndef TEST_CXX_FLAGS
+ cmFailed("CMake CMAKE_CXX_FLAGS is not being passed to the compiler!");
+#else
+ cmPassed("CMake CMAKE_CXX_FLAGS is being passed to the compiler.");
+#endif
+ std::string gen = CMAKE_GENERATOR;
+ // visual studio is currently broken for c flags
+ char msg[1024];
+ if(gen.find("Visual") == gen.npos)
+ {
+#ifdef TEST_C_FLAGS
+ cmFailed("CMake CMAKE_C_FLAGS are being passed to c++ files the compiler!");
+#else
+ cmPassed("CMake CMAKE_C_FLAGS are not being passed to c++ files.");
+#endif
+ if(TestCFlags(msg))
+ {
+ cmPassed(
+ "CMake CMAKE_C_FLAGS are being passed to c files and CXX flags are not.");
+ }
+ else
+ {
+ cmFailed(msg);
+ }
+ }
+ if(TestTargetCompileFlags(msg))
+ {
+ cmPassed(msg);
+ }
+ else
+ {
+ cmFailed(msg);
+ }
+
+ // ----------------------------------------------------------------------
+ // Test ADD_DEFINITIONS
+
+#ifndef CMAKE_IS_FUN
+ cmFailed("CMake is not fun, so it is broken and should be fixed.");
+#else
+ cmPassed("CMAKE_IS_FUN is defined.");
+#endif
+
+#if defined(CMAKE_ARGV1) && defined(CMAKE_ARGV2) && defined(CMAKE_ARGV3) && defined(CMAKE_ARGV4)
+ cmPassed("Variable args for MACROs are working.");
+#else
+ cmFailed("Variable args for MACROs are failing.");
+#endif
+
+ // ----------------------------------------------------------------------
+ // Test GET_SOURCE_FILE_PROPERTY for location
+#ifndef CMAKE_FOUND_ACXX
+ cmFailed("CMake did not get the location of A.cxx correctly");
+#else
+ cmPassed("CMake found A.cxx properly");
+#endif
+
+ // ----------------------------------------------------------------------
+ // Test GET_DIRECTORY_PROPERTY for parent
+#ifndef CMAKE_FOUND_PARENT
+ cmFailed("CMake did not get the location of the parent directory properly");
+#else
+ cmPassed("CMake found the parent directory properly");
+#endif
+
+ // ----------------------------------------------------------------------
+ // Test GET_DIRECTORY_PROPERTY for listfiles
+#ifndef CMAKE_FOUND_LISTFILE_STACK
+ cmFailed("CMake did not get the listfile stack properly");
+#else
+ cmPassed("CMake found the listfile stack properly");
+#endif
+
+ // ----------------------------------------------------------------------
+ // Test SET, VARIABLE_REQUIRES
+
+#ifdef SHOULD_NOT_BE_DEFINED
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED is defined.");
+#endif
+
+#ifndef ONE_VAR
+ cmFailed("cmakedefine is broken, ONE_VAR is not defined.");
+#else
+ cmPassed("ONE_VAR is defined.");
+#endif
+
+#ifndef ONE_VAR_IS_DEFINED
+ cmFailed("cmakedefine, SET or VARIABLE_REQUIRES is broken, "
+ "ONE_VAR_IS_DEFINED is not defined.");
+#else
+ cmPassed("ONE_VAR_IS_DEFINED is defined.");
+#endif
+
+#ifdef ZERO_VAR
+ cmFailed("cmakedefine is broken, ZERO_VAR is defined.");
+#else
+ cmPassed("ZERO_VAR is not defined.");
+#endif
+
+#ifndef STRING_VAR
+ cmFailed("the CONFIGURE_FILE command is broken, STRING_VAR is not defined.");
+#else
+ if(strcmp(STRING_VAR, "CMake is great") != 0)
+ {
+ cmFailed("the SET or CONFIGURE_FILE command is broken. STRING_VAR == ",
+ STRING_VAR);
+ }
+ else
+ {
+ cmPassed("STRING_VAR == ", STRING_VAR);
+ }
+#endif
+
+ // ----------------------------------------------------------------------
+ // Test various IF/ELSE combinations
+
+#ifdef SHOULD_NOT_BE_DEFINED_NOT
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_NOT is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_NOT is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_NOT
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_NOT is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_NOT is defined.");
+#endif
+
+#ifdef SHOULD_NOT_BE_DEFINED_NOT2
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_NOT2 is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_NOT2 is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_NOT2
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_NOT2 is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_NOT2 is defined.");
+#endif
+
+#ifdef SHOULD_NOT_BE_DEFINED_AND
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_AND is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_AND is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_AND
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_AND is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_AND is defined.");
+#endif
+
+#ifdef SHOULD_NOT_BE_DEFINED_AND2
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_AND2 is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_AND2 is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_AND2
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_AND2 is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_AND2 is defined.");
+#endif
+
+#ifdef SHOULD_NOT_BE_DEFINED_OR
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_OR is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_OR is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_OR
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_OR is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_OR is defined.");
+#endif
+
+#ifdef SHOULD_NOT_BE_DEFINED_OR2
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_OR2 is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_OR2 is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_OR2
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_OR2 is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_OR2 is defined.");
+#endif
+
+#ifdef SHOULD_NOT_BE_DEFINED_MATCHES
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_MATCHES is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_MATCHES is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_MATCHES
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_MATCHES is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_MATCHES is defined.");
+#endif
+
+#ifdef SHOULD_NOT_BE_DEFINED_MATCHES2
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_MATCHES2 is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_MATCHES2 is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_MATCHES2
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_MATCHES2 is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_MATCHES2 is defined.");
+#endif
+
+#ifdef SHOULD_NOT_BE_DEFINED_COMMAND
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_COMMAND is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_COMMAND is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_COMMAND
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_COMMAND is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_COMMAND is defined.");
+#endif
+
+#ifdef SHOULD_NOT_BE_DEFINED_COMMAND2
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_COMMAND2 is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_COMMAND2 is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_COMMAND2
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_COMMAND2 is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_COMMAND2 is defined.");
+#endif
+
+#ifdef SHOULD_NOT_BE_DEFINED_EXISTS
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_EXISTS is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_EXISTS is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_EXISTS
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_EXISTS is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_EXISTS is defined.");
+#endif
+
+#ifdef SHOULD_NOT_BE_DEFINED_EXISTS2
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_EXISTS2 is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_EXISTS2 is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_EXISTS2
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_EXISTS2 is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_EXISTS2 is defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_IS_DIRECTORY
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_IS_DIRECTORY is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_IS_DIRECTORY is defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_IS_DIRECTORY2
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_IS_DIRECTORY2 is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_IS_DIRECTORY2 is defined.");
+#endif
+
+#ifdef SHOULD_NOT_BE_DEFINED_LESS
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_LESS is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_LESS is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_LESS
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_LESS is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_LESS is defined.");
+#endif
+
+#ifdef SHOULD_NOT_BE_DEFINED_LESS2
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_LESS2 is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_LESS2 is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_LESS2
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_LESS2 is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_LESS2 is defined.");
+#endif
+
+#ifdef SHOULD_NOT_BE_DEFINED_GREATER
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_GREATER is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_GREATER is not defined.");
+#endif
+
+#ifdef SHOULD_NOT_BE_DEFINED_EQUAL
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_EQUAL is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_EQUAL is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_EQUAL
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_EQUAL is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_EQUAL is defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_GREATER
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_GREATER is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_GREATER is defined.");
+#endif
+
+#ifdef SHOULD_NOT_BE_DEFINED_GREATER2
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_GREATER2 is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_GREATER2 is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_GREATER2
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_GREATER2 is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_GREATER2 is defined.");
+#endif
+
+#ifdef SHOULD_NOT_BE_DEFINED_STRLESS
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_STRLESS is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_STRLESS is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_STRLESS
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_STRLESS is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_STRLESS is defined.");
+#endif
+
+#ifdef SHOULD_NOT_BE_DEFINED_STRLESS2
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_STRLESS2 is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_STRLESS2 is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_STRLESS2
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_STRLESS2 is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_STRLESS2 is defined.");
+#endif
+
+#ifdef SHOULD_NOT_BE_DEFINED_STRGREATER
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_STRGREATER is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_STRGREATER is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_STRGREATER
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_STRGREATER is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_STRGREATER is defined.");
+#endif
+
+#ifdef SHOULD_NOT_BE_DEFINED_STRGREATER2
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_STRGREATER2 is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_STRGREATER2 is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_STRGREATER2
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_STRGREATER2 is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_STRGREATER2 is defined.");
+#endif
+
+ // ----------------------------------------------------------------------
+ // Test FOREACH
+
+#ifndef FOREACH_VAR1
+ cmFailed("the FOREACH, SET or CONFIGURE_FILE command is broken, "
+ "FOREACH_VAR1 is not defined.");
+#else
+ if(strcmp(FOREACH_VAR1, "VALUE1") != 0)
+ {
+ cmFailed("the FOREACH, SET or CONFIGURE_FILE command is broken, "
+ "FOREACH_VAR1 == ", FOREACH_VAR1);
+ }
+ else
+ {
+ cmPassed("FOREACH_VAR1 == ", FOREACH_VAR1);
+ }
+#endif
+
+#ifndef FOREACH_VAR2
+ cmFailed("the FOREACH, SET or CONFIGURE_FILE command is broken, "
+ "FOREACH_VAR2 is not defined.");
+#else
+ if(strcmp(FOREACH_VAR2, "VALUE2") != 0)
+ {
+ cmFailed("the FOREACH, SET or CONFIGURE_FILE command is broken, "
+ "FOREACH_VAR2 == ", FOREACH_VAR2);
+ }
+ else
+ {
+ cmPassed("FOREACH_VAR2 == ", FOREACH_VAR2);
+ }
+#endif
+
+#ifndef FOREACH_CONCAT
+ cmFailed("the FOREACH, SET or CONFIGURE_FILE command is broken, "
+ "FOREACH_CONCAT is not defined.");
+#else
+ if(strcmp(FOREACH_CONCAT, "abcdefg") != 0)
+ {
+ cmFailed("the FOREACH, SET or CONFIGURE_FILE command is broken, "
+ "FOREACH_CONCAT == ", FOREACH_CONCAT);
+ }
+ else
+ {
+ cmPassed("FOREACH_CONCAT == ", FOREACH_CONCAT);
+ }
+#endif
+
+ // ----------------------------------------------------------------------
+ // Test WHILE
+
+ if(WHILE_VALUE != 1000)
+ {
+ cmFailed("WHILE command is not working");
+ }
+ else
+ {
+ cmPassed("WHILE command is working");
+ }
+
+ // ----------------------------------------------------------------------
+ // Test FIND_FILE, FIND_PATH and various GET_FILENAME_COMPONENT combinations
+
+#ifndef FILENAME_VAR_PATH_NAME
+ cmFailed("the FIND_FILE or GET_FILENAME_COMPONENT command is broken, "
+ "FILENAME_VAR_PATH_NAME is not defined.");
+#else
+ if((strcmp(FILENAME_VAR_PATH_NAME, "Complex") == 0) ||
+ (strcmp(FILENAME_VAR_PATH_NAME, "ComplexOneConfig") == 0))
+ {
+ cmPassed("FILENAME_VAR_PATH_NAME == ", FILENAME_VAR_PATH_NAME);
+ }
+ else
+ {
+ cmFailed("the FIND_FILE or GET_FILENAME_COMPONENT command is broken, "
+ "FILENAME_VAR_PATH_NAME == ", FILENAME_VAR_PATH_NAME);
+ }
+#endif
+
+#ifndef FILENAME_VAR_NAME
+ cmFailed("the FIND_FILE or GET_FILENAME_COMPONENT command is broken, "
+ "FILENAME_VAR_NAME is not defined.");
+#else
+ if(strcmp(FILENAME_VAR_NAME, "VarTests.cmake") != 0)
+ {
+ cmFailed("the FIND_FILE or GET_FILENAME_COMPONENT command is broken, "
+ "FILENAME_VAR_NAME == ", FILENAME_VAR_NAME);
+ }
+ else
+ {
+ cmPassed("FILENAME_VAR_NAME == ", FILENAME_VAR_NAME);
+ }
+#endif
+
+#ifndef FILENAME_VAR_EXT
+ cmFailed("the FIND_FILE or GET_FILENAME_COMPONENT command is broken, "
+ "FILENAME_VAR_EXT is not defined.");
+#else
+ if(strcmp(FILENAME_VAR_EXT, ".cmake") != 0)
+ {
+ cmFailed("the FIND_FILE or GET_FILENAME_COMPONENT command is broken, "
+ "FILENAME_VAR_EXT == ", FILENAME_VAR_EXT);
+ }
+ else
+ {
+ cmPassed("FILENAME_VAR_EXT == ", FILENAME_VAR_EXT);
+ }
+#endif
+
+#ifndef FILENAME_VAR_NAME_WE
+ cmFailed("the FIND_FILE or GET_FILENAME_COMPONENT command is broken, "
+ "FILENAME_VAR_NAME_WE is not defined.");
+#else
+ if(strcmp(FILENAME_VAR_NAME_WE, "VarTests") != 0)
+ {
+ cmFailed("the FIND_FILE or GET_FILENAME_COMPONENT command is broken, "
+ "FILENAME_VAR_NAME_WE == ", FILENAME_VAR_NAME_WE);
+ }
+ else
+ {
+ cmPassed("FILENAME_VAR_NAME_WE == ", FILENAME_VAR_NAME_WE);
+ }
+#endif
+
+#ifndef PATH_VAR_NAME
+ cmFailed("the FIND_FILE or GET_FILENAME_COMPONENT command is broken, "
+ "PATH_VAR_NAME is not defined.");
+#else
+ if((strcmp(PATH_VAR_NAME, "Complex") == 0) ||
+ (strcmp(PATH_VAR_NAME, "ComplexOneConfig") == 0))
+ {
+ cmPassed("PATH_VAR_NAME == ", PATH_VAR_NAME);
+ }
+ else
+ {
+ cmFailed("the FIND_FILE or GET_FILENAME_COMPONENT command is broken, "
+ "PATH_VAR_NAME == ", PATH_VAR_NAME);
+ }
+#endif
+
+ // ----------------------------------------------------------------------
+ // Test LOAD_CACHE
+
+#ifndef CACHE_TEST_VAR1
+ cmFailed("the LOAD_CACHE or CONFIGURE_FILE command is broken, "
+ "CACHE_TEST_VAR1 is not defined.");
+#else
+ if(strcmp(CACHE_TEST_VAR1, "foo") != 0)
+ {
+ cmFailed("the LOAD_CACHE or CONFIGURE_FILE command is broken, "
+ "CACHE_TEST_VAR1 == ", CACHE_TEST_VAR1);
+ }
+ else
+ {
+ cmPassed("CACHE_TEST_VAR1 == ", CACHE_TEST_VAR1);
+ }
+#endif
+
+#ifndef CACHE_TEST_VAR2
+ cmFailed("the LOAD_CACHE or CONFIGURE_FILE command is broken, "
+ "CACHE_TEST_VAR2 is not defined.");
+#else
+ if(strcmp(CACHE_TEST_VAR2, "bar") != 0)
+ {
+ cmFailed("the LOAD_CACHE or CONFIGURE_FILE command is broken, "
+ "CACHE_TEST_VAR2 == ", CACHE_TEST_VAR2);
+ }
+ else
+ {
+ cmPassed("CACHE_TEST_VAR2 == ", CACHE_TEST_VAR2);
+ }
+#endif
+
+#ifndef CACHE_TEST_VAR3
+ cmFailed("the LOAD_CACHE or CONFIGURE_FILE command is broken, "
+ "CACHE_TEST_VAR3 is not defined.");
+#else
+ if(strcmp(CACHE_TEST_VAR3, "1") != 0)
+ {
+ cmFailed("the LOAD_CACHE or CONFIGURE_FILE command is broken, "
+ "CACHE_TEST_VAR3 == ", CACHE_TEST_VAR3);
+ }
+ else
+ {
+ cmPassed("CACHE_TEST_VAR3 == ", CACHE_TEST_VAR3);
+ }
+#endif
+
+#ifdef CACHE_TEST_VAR_EXCLUDED
+ cmFailed("the LOAD_CACHE or CONFIGURE_FILE command or cmakedefine is broken, "
+ "CACHE_TEST_VAR_EXCLUDED is defined (should not have been loaded).");
+#else
+ cmPassed("CACHE_TEST_VAR_EXCLUDED is not defined.");
+#endif
+
+#ifndef CACHE_TEST_VAR_INTERNAL
+ cmFailed("the LOAD_CACHE or CONFIGURE_FILE command is broken, "
+ "CACHE_TEST_VAR_INTERNAL is not defined.");
+#else
+ std::string cachetest = CACHE_TEST_VAR_INTERNAL;
+ if(cachetest != "bar")
+ {
+ cmFailed("the LOAD_CACHE or CONFIGURE_FILE command is broken, "
+ "CACHE_TEST_VAR_INTERNAL == ", CACHE_TEST_VAR_INTERNAL);
+ }
+ else
+ {
+ cmPassed("CACHE_TEST_VAR_INTERNAL == ", CACHE_TEST_VAR_INTERNAL);
+ }
+#endif
+
+ // ----------------------------------------------------------------------
+ // Some pre-build/pre-link/post-build custom-commands have been
+ // attached to the lib (see Library/).
+ // Each runs ${CREATE_FILE_EXE} which will create a file.
+ // It also copies that file again using cmake -E.
+ // Similar rules have been added to this executable.
+ //
+ // WARNING: if you run 'complex' manually, this *will* fail, because
+ // 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");
+
+ // ----------------------------------------------------------------------
+ // A custom target has been created (see Library/).
+ // It runs ${CREATE_FILE_EXE} which will create a file.
+ //
+ // WARNING: if you run 'complex' manually, this *will* fail, because
+ // 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");
+
+ // ----------------------------------------------------------------------
+ // A directory has been created.
+
+ TestDir(BINARY_DIR "/make_dir");
+
+ // ----------------------------------------------------------------------
+ // Test OUTPUT_REQUIRED_FILES
+ // The files required by 'complex' have been output to a file.
+ // The contents of this file is not tested (absolute paths).
+ //
+ // WARNING: if you run 'complex' manually, this *will* fail, because
+ // 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");
+
+ // ----------------------------------------------------------------------
+ // Test FIND_LIBRARY
+
+#ifndef FIND_DUMMY_LIB
+ cmFailed("the CONFIGURE_FILE command is broken, "
+ "FIND_DUMMY_LIB is not defined.");
+#else
+ if(strstr(FIND_DUMMY_LIB, "dummylib") == NULL)
+ {
+ cmFailed("the FIND_LIBRARY or CONFIGURE_FILE command is broken, "
+ "FIND_DUMMY_LIB == ", FIND_DUMMY_LIB);
+ }
+ else
+ {
+ cmPassed("FIND_DUMMY_LIB == ", FIND_DUMMY_LIB);
+ }
+#endif
+
+ // ----------------------------------------------------------------------
+ // Test SET_SOURCE_FILES_PROPERTIES
+
+#ifndef FILE_HAS_EXTRA_COMPILE_FLAGS
+ cmFailed("SET_SOURCE_FILES_PROPERTIES failed at setting FILE_HAS_EXTRA_COMPILE_FLAGS flag");
+#else
+ cmPassed("SET_SOURCE_FILES_PROPERTIES succeeded in setting FILE_HAS_EXTRA_COMPILE_FLAGS flag");
+#endif
+
+#if 0 // Disable until implemented everywhere.
+#ifndef FILE_DEFINE_STRING
+ cmFailed("SET_SOURCE_FILES_PROPERTIES failed at setting FILE_DEFINE_STRING flag");
+#else
+ if(strcmp(FILE_DEFINE_STRING, "hello") != 0)
+ {
+ cmFailed("SET_SOURCE_FILES_PROPERTIES failed at setting FILE_DEFINE_STRING flag correctly");
+ }
+ else
+ {
+ cmPassed("SET_SOURCE_FILES_PROPERTIES succeeded in setting FILE_DEFINE_STRING flag");
+ }
+#endif
+#endif
+
+#ifndef FILE_HAS_ABSTRACT
+ cmFailed("SET_SOURCE_FILES_PROPERTIES failed at setting ABSTRACT flag");
+#else
+ cmPassed("SET_SOURCE_FILES_PROPERTIES succeeded in setting ABSTRACT flag");
+#endif
+
+#ifndef FILE_HAS_WRAP_EXCLUDE
+ cmFailed("FILE_HAS_WRAP_EXCLUDE failed at setting WRAP_EXCLUDE flag");
+#else
+ cmPassed("FILE_HAS_WRAP_EXCLUDE succeeded in setting WRAP_EXCLUDE flag");
+#endif
+
+#ifndef FILE_COMPILE_FLAGS
+ cmFailed("the CONFIGURE_FILE command is broken, FILE_COMPILE_FLAGS is not defined.");
+#else
+ if(strcmp(FILE_COMPILE_FLAGS, "-foo -bar") != 0)
+ {
+ cmFailed("the SET_SOURCE_FILES_PROPERTIES or CONFIGURE_FILE command is broken. FILE_COMPILE_FLAGS == ",
+ FILE_COMPILE_FLAGS);
+ }
+ else
+ {
+ cmPassed("SET_SOURCE_FILES_PROPERTIES succeeded in setting extra flags == ", FILE_COMPILE_FLAGS);
+ }
+#endif
+
+ // ----------------------------------------------------------------------
+ // Test registry (win32)
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#ifndef REGISTRY_TEST_PATH
+ cmFailed("the CONFIGURE_FILE command is broken, REGISTRY_TEST_PATH is not defined.");
+#else
+ std::cout << "REGISTRY_TEST_PATH == " << REGISTRY_TEST_PATH << "\n";
+ if(stricmp(REGISTRY_TEST_PATH, BINARY_DIR "/registry_dir") != 0)
+ {
+ cmFailed("the 'read registry value' function or CONFIGURE_FILE command is broken. REGISTRY_TEST_PATH == ",
+ REGISTRY_TEST_PATH, " is not " BINARY_DIR "/registry_dir");
+ }
+ else
+ {
+ cmPassed("REGISTRY_TEST_PATH == ", REGISTRY_TEST_PATH);
+ }
+#endif
+#endif // defined(_WIN32) && !defined(__CYGWIN__)
+
+ if(strcmp(CMAKE_MINIMUM_REQUIRED_VERSION, "1.3") == 0)
+ {
+ cmPassed("CMAKE_MINIMUM_REQUIRED_VERSION is set to 1.3");
+ }
+ else
+ {
+ cmFailed("CMAKE_MINIMUM_REQUIRED_VERSION is not set to the expected 1.3");
+ }
+
+ // ----------------------------------------------------------------------
+ // Test REMOVE command
+ if (strcmp("a;b;d",REMOVE_STRING) == 0)
+ {
+ cmPassed("REMOVE is working");
+ }
+ else
+ {
+ cmFailed("REMOVE is not working");
+ }
+
+ // ----------------------------------------------------------------------
+ // Test SEPARATE_ARGUMENTS
+ if(strcmp("a;b;c", TEST_SEP) == 0)
+ {
+ cmPassed("SEPARATE_ARGUMENTS is working");
+ }
+ else
+ {
+ cmFailed("SEPARATE_ARGUMENTS is not working");
+ }
+
+ // ----------------------------------------------------------------------
+ // Test Escape Quotes
+ if(strcmp("\"hello world\"", STRING_WITH_QUOTES) == 0)
+ {
+ cmPassed("ESCAPE_QUOTES is working");
+ }
+ else
+ {
+ cmFailed("ESCAPE_QUOTES is not working");
+ }
+
+
+ // ----------------------------------------------------------------------
+ // Test if IF command inside a FOREACH works.
+#if defined(IF_INSIDE_FOREACH_THEN_EXECUTED) && !defined(IF_INSIDE_FOREACH_ELSE_EXECUTED)
+ cmPassed("IF inside a FOREACH block works");
+#else
+ cmFailed("IF inside a FOREACH block is broken");
+#endif
+
+#if defined(GENERATED_HEADER_INCLUDED)
+ cmPassed("Generated header included by non-generated source works.");
+#else
+ cmFailed("Generated header included by non-generated source failed.");
+#endif
+ if(SHOULD_BE_ZERO == 0)
+ {
+ cmPassed("cmakedefine01 is working for 0");
+ }
+ else
+ {
+ cmFailed("cmakedefine01 is not working for 0");
+ }
+ if(SHOULD_BE_ONE == 1)
+ {
+ cmPassed("cmakedefine01 is working for 1");
+ }
+ else
+ {
+ cmFailed("cmakedefine01 is not working for 1");
+ }
+#ifdef FORCE_TEST
+ cmFailed("CMake SET CACHE FORCE");
+#else
+ cmPassed("CMake SET CACHE FORCE");
+#endif
+
+#ifdef COMPLEX_TEST_LINK_STATIC
+ if(TestLinkGetType())
+ {
+ cmPassed("Link to static over shared worked.");
+ }
+ else
+ {
+ cmFailed("Link to static over shared failed.");
+ }
+#endif
+
+#if defined(A_VALUE) && A_VALUE == 10
+ cmPassed("Single-character executable A worked.");
+#else
+ cmFailed("Single-character executable A failed.");
+#endif
+
+ // ----------------------------------------------------------------------
+ // Summary
+
+ std::cout << "Passed: " << cm_passed << "\n";
+ if(cm_failed)
+ {
+ std::cout << "Failed: " << cm_failed << "\n";
+ return cm_failed;
+ }
+ return 0;
+}
diff --git a/Tests/Complex/Executable/complex.file.cxx b/Tests/Complex/Executable/complex.file.cxx
new file mode 100644
index 000000000..e873fa644
--- /dev/null
+++ b/Tests/Complex/Executable/complex.file.cxx
@@ -0,0 +1,8 @@
+#if 0
+#include "cmMissingHeader.h"
+#endif
+
+int main(int , char**)
+{
+ return 0;
+}
diff --git a/Tests/Complex/Executable/complex_nobuild.c b/Tests/Complex/Executable/complex_nobuild.c
new file mode 100644
index 000000000..6b3c2c1e2
--- /dev/null
+++ b/Tests/Complex/Executable/complex_nobuild.c
@@ -0,0 +1 @@
+#error "This file should not be compiled."
diff --git a/Tests/Complex/Executable/complex_nobuild.cxx b/Tests/Complex/Executable/complex_nobuild.cxx
new file mode 100644
index 000000000..6b3c2c1e2
--- /dev/null
+++ b/Tests/Complex/Executable/complex_nobuild.cxx
@@ -0,0 +1 @@
+#error "This file should not be compiled."
diff --git a/Tests/Complex/Executable/notInAllExe.cxx b/Tests/Complex/Executable/notInAllExe.cxx
new file mode 100644
index 000000000..70275cd51
--- /dev/null
+++ b/Tests/Complex/Executable/notInAllExe.cxx
@@ -0,0 +1,10 @@
+extern int notInAllLibFunc();
+
+int main()
+{
+ return notInAllLibFunc();
+}
+
+#if 1
+# error "This target should not be compiled by ALL."
+#endif
diff --git a/Tests/Complex/Executable/testSystemDir.cxx b/Tests/Complex/Executable/testSystemDir.cxx
new file mode 100644
index 000000000..e4815c679
--- /dev/null
+++ b/Tests/Complex/Executable/testSystemDir.cxx
@@ -0,0 +1,3 @@
+#include <testSystemDir.h>
+
+int main() { return foo(); }
diff --git a/Tests/Complex/Executable/testcflags.c b/Tests/Complex/Executable/testcflags.c
new file mode 100644
index 000000000..f4d584844
--- /dev/null
+++ b/Tests/Complex/Executable/testcflags.c
@@ -0,0 +1,26 @@
+#include <string.h>
+
+int TestTargetCompileFlags(char* m)
+{
+#ifndef COMPLEX_TARGET_FLAG
+ strcpy(m, "CMAKE SET_TARGET_PROPERTIES COMPILE_FLAGS did not work");
+ return 0;
+#endif
+ strcpy(m, "CMAKE SET_TARGET_PROPERTIES COMPILE_FLAGS worked");
+ return 1;
+}
+
+int TestCFlags(char* m)
+{
+ /* TEST_CXX_FLAGS should not be defined in a c file */
+#ifdef TEST_CXX_FLAGS
+ strcpy(m, "CMake CMAKE_CXX_FLAGS (TEST_CXX_FLAGS) found in c file.");
+ return 0;
+#endif
+ /* TEST_C_FLAGS should be defined in a c file */
+#ifndef TEST_C_FLAGS
+ strcpy(m, "CMake CMAKE_C_FLAGS (TEST_C_FLAGS) not found in c file.");
+ return 0;
+#endif
+ return 1;
+}
diff --git a/Tests/Complex/Library/CMakeLists.txt b/Tests/Complex/Library/CMakeLists.txt
new file mode 100644
index 000000000..c8efc3022
--- /dev/null
+++ b/Tests/Complex/Library/CMakeLists.txt
@@ -0,0 +1,140 @@
+REMOVE_DEFINITIONS(-DCMAKE_IS_REALLY_FUN)
+
+#
+# Small utility used to create file
+# UTILITY_SOURCE is used for coverage and for getting the exact name
+# of the executable.
+#
+UTILITY_SOURCE(CREATE_FILE_EXE create_file "." create_file.cxx)
+ADD_EXECUTABLE(create_file create_file.cxx)
+SET_TARGET_PROPERTIES(create_file PROPERTIES RUNTIME_OUTPUT_DIRECTORY ".")
+
+#
+# Create static library
+# SOURCE_FILES_REMOVE is used for Coverage. empty.h is included for coverage
+#
+AUX_SOURCE_DIRECTORY(ExtraSources LibrarySources)
+SET(LibrarySources ${LibrarySources}
+ file2
+ empty
+ create_file.cxx
+ GENERATED
+ nonexisting_file)
+REMOVE(LibrarySources create_file.cxx GENERATED nonexisting_file)
+ADD_LIBRARY(CMakeTestLibrary ${LibrarySources})
+
+IF(WIN32)
+ IF(NOT CYGWIN)
+ IF(NOT BORLAND)
+ IF(NOT MINGW)
+ TARGET_LINK_LIBRARIES(CMakeTestLibrary
+ debug
+ user32.lib)
+ TARGET_LINK_LIBRARIES(CMakeTestLibrary
+ optimized
+ kernel32.lib)
+ ENDIF(NOT MINGW)
+ ENDIF(NOT BORLAND)
+ ENDIF(NOT CYGWIN)
+ENDIF(WIN32)
+
+#
+# Create shared library
+#
+SET(SharedLibrarySources sharedFile)
+ADD_LIBRARY(CMakeTestLibraryShared SHARED ${SharedLibrarySources})
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DTEST_C_FLAGS")
+ADD_LIBRARY(CMakeTestCLibraryShared SHARED testConly.c)
+DEFINE_PROPERTY(
+ TARGET PROPERTY FOO
+ BRIEF_DOCS "a test 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.
+ SET_TARGET_PROPERTIES(CMakeTestCLibraryShared PROPERTIES LINK_FLAGS "-lm")
+ENDIF(NOT BEOS AND NOT WIN32)
+GET_TARGET_PROPERTY(FOO_BAR_VAR CMakeTestCLibraryShared FOO)
+IF(${FOO_BAR_VAR} MATCHES "BAR")
+ELSE(${FOO_BAR_VAR} MATCHES "BAR")
+ MESSAGE(SEND_ERROR "SET_TARGET_PROPERTIES or GET_TARGET_PROPERTY failed, FOO_BAR_VAR should be BAR, but is ${FOO_BAR_VAR}")
+ENDIF(${FOO_BAR_VAR} MATCHES "BAR")
+
+# Create static and shared lib of same name.
+IF(CMAKE_EXE_LINK_STATIC_CXX_FLAGS)
+ ADD_LIBRARY(CMakeTestLinkStatic STATIC TestLink.c)
+ ADD_LIBRARY(CMakeTestLinkShared SHARED TestLink.c)
+ SET_TARGET_PROPERTIES(CMakeTestLinkStatic CMakeTestLinkShared
+ PROPERTIES OUTPUT_NAME CMakeTestLink)
+ENDIF(CMAKE_EXE_LINK_STATIC_CXX_FLAGS)
+
+#
+# Attach pre-build/pre-link/post-build custom-commands to the lib.
+# Each runs ${CREATE_FILE_EXE} which will create a file.
+# The 'complex' executable will then test if this file exists and remove it.
+#
+ADD_DEPENDENCIES(CMakeTestLibraryShared create_file)
+MESSAGE("complex bin dir is ${Complex_BINARY_DIR}")
+ADD_CUSTOM_COMMAND(TARGET CMakeTestLibraryShared PRE_BUILD
+ COMMAND ${CREATE_FILE_EXE}
+ ARGS "${Complex_BINARY_DIR}/Library/prebuild.txt")
+ADD_CUSTOM_COMMAND(TARGET CMakeTestLibraryShared PRE_BUILD
+ COMMAND ${CREATE_FILE_EXE}
+ ARGS "${Complex_BINARY_DIR}/Library/prelink.txt")
+ADD_CUSTOM_COMMAND(TARGET CMakeTestLibraryShared POST_BUILD
+ COMMAND ${CREATE_FILE_EXE}
+ ARGS "${Complex_BINARY_DIR}/Library/postbuild.txt")
+ADD_CUSTOM_COMMAND(TARGET CMakeTestLibraryShared POST_BUILD
+ COMMAND ${CMAKE_COMMAND}
+ ARGS -E copy
+ "${Complex_BINARY_DIR}/Library/postbuild.txt"
+ "${Complex_BINARY_DIR}/Library/postbuild2.txt")
+
+#
+# Add a custom target.
+# It runs ${CREATE_FILE_EXE} which will create a file.
+# The 'complex' executable will then test if this file exists and remove it.
+#
+ADD_CUSTOM_TARGET(custom_target1
+ ALL
+ ${CREATE_FILE_EXE}
+ "${Complex_BINARY_DIR}/Library/custom_target1.txt")
+
+ADD_DEPENDENCIES(custom_target1 create_file)
+
+#
+# Extra coverage
+#
+SET_SOURCE_FILES_PROPERTIES(file2 PROPERTIES ABSTRACT 1)
+
+INSTALL_FILES(/tmp .h ${Complex_BINARY_DIR}/cmTestConfigure.h)
+INSTALL_FILES(/tmp .cxx ${Complex_BINARY_DIR}/cmTestConfigure.h)
+
+# Test creating a library that is not built by default.
+ADD_LIBRARY(notInAllLib EXCLUDE_FROM_ALL notInAllLib.cxx)
+
+# Create an imported target for if(TARGET) test in Executable dir.
+# That test should not see this target.
+ADD_LIBRARY(LibImportedTarget UNKNOWN IMPORTED)
+
+# Test generation of preprocessed sources.
+IF("${CMAKE_GENERATOR}" MATCHES "Makefile" AND CMAKE_MAKE_PROGRAM)
+ IF(CMAKE_CXX_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(ARCH_COUNT GREATER 1)
+
+ # Custom target to try preprocessing invocation.
+ ADD_CUSTOM_TARGET(test_preprocess ${MAYBE_ALL}
+ COMMAND ${CMAKE_COMMAND} -E remove CMakeFiles/create_file.dir/create_file.i
+ COMMAND ${CMAKE_MAKE_PROGRAM} create_file.i
+ COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/test_preprocess.cmake
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ )
+ ENDIF(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE)
+ENDIF("${CMAKE_GENERATOR}" MATCHES "Makefile" AND CMAKE_MAKE_PROGRAM)
diff --git a/Tests/Complex/Library/ExtraSources/file1.cxx b/Tests/Complex/Library/ExtraSources/file1.cxx
new file mode 100644
index 000000000..e22812e51
--- /dev/null
+++ b/Tests/Complex/Library/ExtraSources/file1.cxx
@@ -0,0 +1,4 @@
+int file1()
+{
+ return 1;
+}
diff --git a/Tests/Complex/Library/ExtraSources/file1.h b/Tests/Complex/Library/ExtraSources/file1.h
new file mode 100644
index 000000000..ce0d818a3
--- /dev/null
+++ b/Tests/Complex/Library/ExtraSources/file1.h
@@ -0,0 +1 @@
+int file1();
diff --git a/Tests/Complex/Library/SystemDir/testSystemDir.h b/Tests/Complex/Library/SystemDir/testSystemDir.h
new file mode 100644
index 000000000..73be3538e
--- /dev/null
+++ b/Tests/Complex/Library/SystemDir/testSystemDir.h
@@ -0,0 +1,2 @@
+// Purposely leave off the return type to create a warning.
+foo() { return 0; }
diff --git a/Tests/Complex/Library/TestLink.c b/Tests/Complex/Library/TestLink.c
new file mode 100644
index 000000000..25dee082f
--- /dev/null
+++ b/Tests/Complex/Library/TestLink.c
@@ -0,0 +1,8 @@
+int TestLinkGetType()
+{
+#ifdef CMakeTestLinkShared_EXPORTS
+ return 0;
+#else
+ return 1;
+#endif
+}
diff --git a/Tests/Complex/Library/create_file.cxx b/Tests/Complex/Library/create_file.cxx
new file mode 100644
index 000000000..d41551980
--- /dev/null
+++ b/Tests/Complex/Library/create_file.cxx
@@ -0,0 +1,28 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+int main (int argc, char *argv[])
+{
+ if (argc < 2)
+ {
+ fprintf(stderr, "Missing name of file to create.\n");
+ return EXIT_FAILURE;
+ }
+
+ FILE *stream = fopen(argv[1], "w");
+ if(stream == NULL)
+ {
+ fprintf(stderr, "Unable to open %s for writing!\n", argv[1]);
+ return EXIT_FAILURE;
+ }
+
+ if(fclose(stream))
+ {
+ fprintf(stderr, "Unable to close %s!\n", argv[1]);
+ return EXIT_FAILURE;
+ }
+
+ fprintf(stdout, ">> Creating %s!\n", argv[1]);
+
+ return EXIT_SUCCESS;
+}
diff --git a/Tests/Complex/Library/dummy b/Tests/Complex/Library/dummy
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/Complex/Library/dummy
diff --git a/Tests/Complex/Library/empty.h b/Tests/Complex/Library/empty.h
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/Complex/Library/empty.h
diff --git a/Tests/Complex/Library/file2.cxx b/Tests/Complex/Library/file2.cxx
new file mode 100644
index 000000000..863fcaa51
--- /dev/null
+++ b/Tests/Complex/Library/file2.cxx
@@ -0,0 +1,10 @@
+#include <string.h>
+
+#ifdef CMAKE_IS_REALLY_FUN
+This is a problem. Looks like REMOVE_DEFINITION does not work
+#endif
+
+int file2()
+{
+ return 1;
+}
diff --git a/Tests/Complex/Library/file2.h b/Tests/Complex/Library/file2.h
new file mode 100644
index 000000000..dea4b80b1
--- /dev/null
+++ b/Tests/Complex/Library/file2.h
@@ -0,0 +1 @@
+int file2();
diff --git a/Tests/Complex/Library/notInAllLib.cxx b/Tests/Complex/Library/notInAllLib.cxx
new file mode 100644
index 000000000..5d928f44a
--- /dev/null
+++ b/Tests/Complex/Library/notInAllLib.cxx
@@ -0,0 +1,5 @@
+int notInAllLibFunc() { return 0; }
+
+#if 1
+# error "This target should not be compiled by ALL."
+#endif
diff --git a/Tests/Complex/Library/sharedFile.cxx b/Tests/Complex/Library/sharedFile.cxx
new file mode 100644
index 000000000..cafac68f4
--- /dev/null
+++ b/Tests/Complex/Library/sharedFile.cxx
@@ -0,0 +1,6 @@
+#include "sharedFile.h"
+
+int sharedFunction()
+{
+ return 1;
+}
diff --git a/Tests/Complex/Library/sharedFile.h b/Tests/Complex/Library/sharedFile.h
new file mode 100644
index 000000000..65ac2e2ba
--- /dev/null
+++ b/Tests/Complex/Library/sharedFile.h
@@ -0,0 +1,12 @@
+#if defined(_WIN32) || defined(WIN32) /* Win32 version */
+#ifdef CMakeTestLibraryShared_EXPORTS
+# define CMakeTest_EXPORT __declspec(dllexport)
+#else
+# define CMakeTest_EXPORT __declspec(dllimport)
+#endif
+#else
+/* unix needs nothing */
+#define CMakeTest_EXPORT
+#endif
+
+CMakeTest_EXPORT int sharedFunction();
diff --git a/Tests/Complex/Library/testConly.c b/Tests/Complex/Library/testConly.c
new file mode 100644
index 000000000..2d83f778e
--- /dev/null
+++ b/Tests/Complex/Library/testConly.c
@@ -0,0 +1,13 @@
+#include "testConly.h"
+#include <stdio.h>
+
+int CsharedFunction()
+{
+#ifndef TEST_C_FLAGS
+ printf("TEST_C_FLAGS failed\n");
+ return 0;
+#else
+ printf("Passed: TEST_C_FLAGS passed\n");
+#endif
+ return 1;
+}
diff --git a/Tests/Complex/Library/testConly.h b/Tests/Complex/Library/testConly.h
new file mode 100644
index 000000000..f1470a8d7
--- /dev/null
+++ b/Tests/Complex/Library/testConly.h
@@ -0,0 +1,13 @@
+#if defined(_WIN32) || defined(WIN32) /* Win32 version */
+#ifdef CMakeTestCLibraryShared_EXPORTS
+# define CMakeTest_EXPORT __declspec(dllexport)
+#else
+# define CMakeTest_EXPORT __declspec(dllimport)
+#endif
+#else
+/* unix needs nothing */
+#define CMakeTest_EXPORT
+#endif
+
+CMakeTest_EXPORT int CsharedFunction();
+
diff --git a/Tests/Complex/Library/test_preprocess.cmake b/Tests/Complex/Library/test_preprocess.cmake
new file mode 100644
index 000000000..d2d9fc652
--- /dev/null
+++ b/Tests/Complex/Library/test_preprocess.cmake
@@ -0,0 +1,7 @@
+SET(TEST_FILE CMakeFiles/create_file.dir/create_file.i)
+FILE(READ ${TEST_FILE} CONTENTS)
+IF("${CONTENTS}" MATCHES "Unable to close")
+ MESSAGE(STATUS "${TEST_FILE} created successfully!")
+ELSE("${CONTENTS}" MATCHES "Unable to close")
+ MESSAGE(FATAL_ERROR "${TEST_FILE} creation failed!")
+ENDIF("${CONTENTS}" MATCHES "Unable to close")
diff --git a/Tests/Complex/VarTests.cmake b/Tests/Complex/VarTests.cmake
new file mode 100644
index 000000000..c146d1be0
--- /dev/null
+++ b/Tests/Complex/VarTests.cmake
@@ -0,0 +1,198 @@
+#
+# Test SET
+#
+SET (ZERO_VAR 0)
+SET (ZERO_VAR2 0)
+
+IF(ZERO_VAR)
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED)
+ELSE(ZERO_VAR)
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED)
+ENDIF(ZERO_VAR)
+
+SET(ONE_VAR 1)
+SET(ONE_VAR2 1)
+SET(STRING_VAR "CMake is great" CACHE STRING "test a cache variable")
+
+#
+# Test VARIABLE_REQUIRES
+#
+VARIABLE_REQUIRES(ONE_VAR
+ ONE_VAR_IS_DEFINED ONE_VAR)
+
+#
+# Test various IF/ELSE combinations
+#
+IF(NOT ZERO_VAR)
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_NOT)
+ELSE(NOT ZERO_VAR)
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_NOT)
+ENDIF(NOT ZERO_VAR)
+
+IF(NOT ONE_VAR)
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_NOT2)
+ELSE(NOT ONE_VAR)
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_NOT2)
+ENDIF(NOT ONE_VAR)
+
+IF(ONE_VAR AND ONE_VAR2)
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_AND)
+ELSE(ONE_VAR AND ONE_VAR2)
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_AND)
+ENDIF(ONE_VAR AND ONE_VAR2)
+
+IF(ONE_VAR AND ZERO_VAR)
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_AND2)
+ELSE(ONE_VAR AND ZERO_VAR)
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_AND2)
+ENDIF(ONE_VAR AND ZERO_VAR)
+
+IF(ZERO_VAR OR ONE_VAR2)
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_OR)
+ELSE(ZERO_VAR OR ONE_VAR2)
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_OR)
+ENDIF(ZERO_VAR OR ONE_VAR2)
+
+IF(ZERO_VAR OR ZERO_VAR2)
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_OR2)
+ELSE(ZERO_VAR OR ZERO_VAR2)
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_OR2)
+ENDIF(ZERO_VAR OR ZERO_VAR2)
+
+IF(STRING_VAR MATCHES "^CMake")
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_MATCHES)
+ELSE(STRING_VAR MATCHES "^CMake")
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_MATCHES)
+ENDIF(STRING_VAR MATCHES "^CMake")
+
+IF(STRING_VAR MATCHES "^foo")
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_MATCHES2)
+ELSE(STRING_VAR MATCHES "^foo")
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_MATCHES2)
+ENDIF(STRING_VAR MATCHES "^foo")
+
+IF(COMMAND "IF")
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_COMMAND)
+ELSE(COMMAND "IF")
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_COMMAND)
+ENDIF(COMMAND "IF")
+
+IF(COMMAND "ROQUEFORT")
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_COMMAND2)
+ELSE(COMMAND "ROQUEFORT")
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_COMMAND2)
+ENDIF(COMMAND "ROQUEFORT")
+
+IF (EXISTS ${Complex_SOURCE_DIR}/VarTests.cmake)
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_EXISTS)
+ELSE(EXISTS ${Complex_SOURCE_DIR}/VarTests.cmake)
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_EXISTS)
+ENDIF (EXISTS ${Complex_SOURCE_DIR}/VarTests.cmake)
+
+IF (EXISTS ${Complex_SOURCE_DIR}/roquefort.txt)
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_EXISTS2)
+ELSE(EXISTS ${Complex_SOURCE_DIR}/roquefort.txt)
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_EXISTS2)
+ENDIF (EXISTS ${Complex_SOURCE_DIR}/roquefort.txt)
+
+IF (IS_DIRECTORY ${Complex_SOURCE_DIR})
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_IS_DIRECTORY)
+ENDIF (IS_DIRECTORY ${Complex_SOURCE_DIR})
+
+IF (NOT IS_DIRECTORY ${Complex_SOURCE_DIR}/VarTests.cmake)
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_IS_DIRECTORY2)
+ENDIF (NOT IS_DIRECTORY ${Complex_SOURCE_DIR}/VarTests.cmake)
+
+SET (SNUM1_VAR "1")
+SET (SNUM2_VAR "2")
+SET (SNUM3_VAR "1")
+
+
+IF (SNUM1_VAR LESS SNUM2_VAR)
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_LESS)
+ELSE (SNUM1_VAR LESS SNUM2_VAR)
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_LESS)
+ENDIF (SNUM1_VAR LESS SNUM2_VAR)
+
+IF (SNUM2_VAR LESS SNUM1_VAR)
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_LESS2)
+ELSE (SNUM2_VAR LESS SNUM1_VAR)
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_LESS2)
+ENDIF (SNUM2_VAR LESS SNUM1_VAR)
+
+IF (SNUM2_VAR GREATER SNUM1_VAR)
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_GREATER)
+ELSE (SNUM2_VAR GREATER SNUM1_VAR)
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_GREATER)
+ENDIF (SNUM2_VAR GREATER SNUM1_VAR)
+
+IF (SNUM2_VAR EQUAL SNUM1_VAR)
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_EQUAL)
+ELSE (SNUM2_VAR EQUAL SNUM1_VAR)
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_EQUAL)
+ENDIF (SNUM2_VAR EQUAL SNUM1_VAR)
+
+IF (SNUM3_VAR EQUAL SNUM1_VAR)
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_EQUAL)
+ELSE (SNUM3_VAR EQUAL SNUM1_VAR)
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_EQUAL)
+ENDIF (SNUM3_VAR EQUAL SNUM1_VAR)
+
+IF (SNUM1_VAR GREATER SNUM2_VAR)
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_GREATER2)
+ELSE (SNUM1_VAR GREATER SNUM2_VAR)
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_GREATER2)
+ENDIF (SNUM1_VAR GREATER SNUM2_VAR)
+
+SET (SSTR1_VAR "abc")
+SET (SSTR2_VAR "bcd")
+
+IF (SSTR1_VAR STRLESS SSTR2_VAR)
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_STRLESS)
+ELSE (SSTR1_VAR STRLESS SSTR2_VAR)
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_STRLESS)
+ENDIF (SSTR1_VAR STRLESS SSTR2_VAR)
+
+IF (SSTR2_VAR STRLESS SSTR1_VAR)
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_STRLESS2)
+ELSE (SSTR2_VAR STRLESS SSTR1_VAR)
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_STRLESS2)
+ENDIF (SSTR2_VAR STRLESS SSTR1_VAR)
+
+IF (SSTR2_VAR STRGREATER SSTR1_VAR)
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_STRGREATER)
+ELSE (SSTR2_VAR STRGREATER SSTR1_VAR)
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_STRGREATER)
+ENDIF (SSTR2_VAR STRGREATER SSTR1_VAR)
+
+IF (SSTR1_VAR STRGREATER SSTR2_VAR)
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_STRGREATER2)
+ELSE (SSTR1_VAR STRGREATER SSTR2_VAR)
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_STRGREATER2)
+ENDIF (SSTR1_VAR STRGREATER SSTR2_VAR)
+
+#
+# Test FOREACH
+#
+FOREACH (INDEX 1 2)
+ SET(FOREACH_VAR${INDEX} "VALUE${INDEX}")
+ENDFOREACH(INDEX)
+
+SET(FOREACH_CONCAT "")
+FOREACH (INDEX a;b;c;d;e;f;g)
+ SET(FOREACH_CONCAT "${FOREACH_CONCAT}${INDEX}")
+ENDFOREACH(INDEX)
+
+#
+# Test FIND_FILE, FIND_PATH and various GET_FILENAME_COMPONENT combinations
+#
+FIND_FILE(FILENAME_VAR "VarTests.cmake" ${Complex_SOURCE_DIR})
+
+GET_FILENAME_COMPONENT(FILENAME_VAR_PATH ${FILENAME_VAR} PATH)
+GET_FILENAME_COMPONENT(FILENAME_VAR_PATH_NAME ${FILENAME_VAR_PATH} NAME)
+GET_FILENAME_COMPONENT(FILENAME_VAR_NAME ${FILENAME_VAR} NAME)
+GET_FILENAME_COMPONENT(FILENAME_VAR_EXT ${FILENAME_VAR} EXT)
+GET_FILENAME_COMPONENT(FILENAME_VAR_NAME_WE ${FILENAME_VAR} NAME_WE CACHE)
+
+FIND_PATH(PATH_VAR "cmTestConfigure.h.in" ${Complex_SOURCE_DIR})
+GET_FILENAME_COMPONENT(PATH_VAR_NAME ${PATH_VAR} NAME)
diff --git a/Tests/Complex/cmTestConfigure.h.in b/Tests/Complex/cmTestConfigure.h.in
new file mode 100644
index 000000000..7741b6fd5
--- /dev/null
+++ b/Tests/Complex/cmTestConfigure.h.in
@@ -0,0 +1,85 @@
+// Test SET, VARIABLE_REQUIRES
+
+#cmakedefine ONE_VAR
+#cmakedefine ONE_VAR_IS_DEFINED
+#cmakedefine ZERO_VAR
+
+#define STRING_VAR "${STRING_VAR}"
+
+// Test FOREACH
+
+#define FOREACH_VAR1 "${FOREACH_VAR1}"
+#define FOREACH_VAR2 "${FOREACH_VAR2}"
+#define FOREACH_CONCAT "${FOREACH_CONCAT}"
+
+// Test WHILE
+#define WHILE_VALUE ${while_var}
+
+// Test FIND_FILE, FIND_PATH and various GET_FILENAME_COMPONENT combinations
+
+#define FILENAME_VAR_PATH_NAME "${FILENAME_VAR_PATH_NAME}"
+#define FILENAME_VAR_NAME "${FILENAME_VAR_NAME}"
+#define FILENAME_VAR_EXT "${FILENAME_VAR_EXT}"
+#define FILENAME_VAR_NAME_WE "${FILENAME_VAR_NAME_WE}"
+
+#define PATH_VAR_NAME "${PATH_VAR_NAME}"
+
+// Test LOAD_CACHE
+
+#define CACHE_TEST_VAR1 "${CACHE_TEST_VAR1}"
+#define CACHE_TEST_VAR2 "${CACHE_TEST_VAR2}"
+#define CACHE_TEST_VAR3 "${CACHE_TEST_VAR3}"
+#cmakedefine CACHE_TEST_VAR_EXCLUDED
+#define CACHE_TEST_VAR_INTERNAL "${CACHE_TEST_VAR_INTERNAL}"
+
+// Test internal CMake vars from C++ flags
+
+#cmakedefine CMAKE_NO_STD_NAMESPACE
+#cmakedefine CMAKE_NO_ANSI_STREAM_HEADERS
+#cmakedefine CMAKE_NO_ANSI_STRING_STREAM
+#cmakedefine CMAKE_NO_ANSI_FOR_SCOPE
+
+#cmakedefine01 SHOULD_BE_ZERO
+#cmakedefine01 SHOULD_BE_ONE
+// Needed to check for files
+
+#define BINARY_DIR "${Complex_BINARY_DIR}"
+
+// Test FIND_LIBRARY
+
+#define FIND_DUMMY_LIB "${FIND_DUMMY_LIB}"
+
+// Test SET_SOURCE_FILES_PROPERTIES
+
+#cmakedefine FILE_HAS_ABSTRACT
+#cmakedefine FILE_HAS_WRAP_EXCLUDE
+#define FILE_COMPILE_FLAGS "${FILE_COMPILE_FLAGS}"
+
+#define TEST_SEP "${TEST_SEP}"
+
+// Test registry read
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#define REGISTRY_TEST_PATH "${REGISTRY_TEST_PATH}"
+#endif
+
+// Test Remove command
+#define REMOVE_STRING "${REMOVE_STRING}"
+
+// Test IF inside FOREACH
+#cmakedefine IF_INSIDE_FOREACH_THEN_EXECUTED
+#cmakedefine IF_INSIDE_FOREACH_ELSE_EXECUTED
+
+// Test SET CACHE FORCE
+#cmakedefine FORCE_TEST
+#define CMAKE_GENERATOR "${CMAKE_GENERATOR}"
+
+#define CMAKE_SHARED_MODULE_PREFIX "${CMAKE_SHARED_MODULE_PREFIX}"
+#define CMAKE_SHARED_MODULE_SUFFIX "${CMAKE_SHARED_MODULE_SUFFIX}"
+
+// test elseif
+#cmakedefine ELSEIF_RESULT
+
+// test parenthesis in conditionals
+#cmakedefine CONDITIONAL_PARENTHESES
+
diff --git a/Tests/Complex/cmTestConfigureEscape.h.in b/Tests/Complex/cmTestConfigureEscape.h.in
new file mode 100644
index 000000000..39a8bd627
--- /dev/null
+++ b/Tests/Complex/cmTestConfigureEscape.h.in
@@ -0,0 +1 @@
+#define STRING_WITH_QUOTES "${STRING_WITH_QUOTES}"
diff --git a/Tests/Complex/cmTestGeneratedHeader.h.in b/Tests/Complex/cmTestGeneratedHeader.h.in
new file mode 100644
index 000000000..0e9dd3ff3
--- /dev/null
+++ b/Tests/Complex/cmTestGeneratedHeader.h.in
@@ -0,0 +1 @@
+#define GENERATED_HEADER_INCLUDED
diff --git a/Tests/ComplexOneConfig/CMakeLists.txt b/Tests/ComplexOneConfig/CMakeLists.txt
new file mode 100644
index 000000000..b50501905
--- /dev/null
+++ b/Tests/ComplexOneConfig/CMakeLists.txt
@@ -0,0 +1,376 @@
+#
+# A more complex test case
+#
+SET(CMAKE_BACKWARDS_COMPATIBILITY 1.4)
+PROJECT (Complex)
+
+# Try setting a new policy. The IF test is for coverage.
+IF(POLICY CMP0003)
+ CMAKE_POLICY(SET CMP0003 NEW)
+
+ CMAKE_POLICY(GET CMP0003 P3)
+ IF(NOT "${P3}" STREQUAL "NEW")
+ MESSAGE(FATAL_ERROR "CMAKE_POLICY(GET) did not report NEW!")
+ ENDIF(NOT "${P3}" STREQUAL "NEW")
+ENDIF(POLICY CMP0003)
+
+# Test building without per-rule echo lines in Makefiles.
+SET_PROPERTY(GLOBAL PROPERTY RULE_MESSAGES OFF)
+
+SET(CPACK_SOURCE_IGNORE_FILES "~$;\\.cvsignore$;^C:/hoffman/My Builds/testcase.*/CVS/;^C:/hoffman/My Builds/testcase.*/\\.svn/;^C:/hoffman/My Builds/testcase.*/sweigart/;^C:/hoffman/My Builds/testcase/www/eospaper/solution/eos2001/;^C:/hoffman/My Builds/testcase/www/eospaper/solution/opal_tables_new/;^C:/hoffman/My Builds/testcase/COPYING$;^C:/hoffman/My Builds/testcase/INSTALL$;^C:/hoffman/My Builds/testcase/Makefile$;^C:/hoffman/My Builds/testcase/Makefile\\.in$;^C:/hoffman/My Builds/testcase/.*\\.lo$;^C:/hoffman/My Builds/testcase/.*\\.la$;^C:/hoffman/My Builds/testcase/mkinstalldirs$;^C:/hoffman/My Builds/testcase/missing$;^C:/hoffman/My Builds/testcase/ltmain\\.sh$;^C:/hoffman/My Builds/testcase/libtool$;^C:/hoffman/My Builds/testcase/install-sh$;^C:/hoffman/My Builds/testcase/configure$;^C:/hoffman/My Builds/testcase/config\\.sub$;^C:/hoffman/My Builds/testcase/config\\.status$;^C:/hoffman/My Builds/testcase/config\\.log$;^C:/hoffman/My Builds/testcase/config\\.guess$;^C:/hoffman/My Builds/testcase/autom4te\\.cache$;^C:/hoffman/My Builds/testcase/aclocal\\.m4$;^C:/hoffman/My Builds/testcase/depcomp$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/rho-T-loci/0\\.075\\.model_cassisi_eos1_10$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/rho-T-loci/0\\.075\\.model_cassisi_eos1_10_corr$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/rho-T-loci/0\\.1\\.model_cassisi_eos1$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/rho-T-loci/0\\.1\\.model_cassisi_scvh$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/rho-T-loci/0\\.1\\.modelc$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/rho-T-loci/0\\.3\\.modelc$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/rho-T-loci/1\\.0\\.modelc$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/rho-T-loci/1\\.0\\.rgbtip\\.modelc$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/rho-T-loci/1\\.0\\.zahb\\.modelc$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/rho-T-loci/0\\.1\\.model$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/rho-T-loci/1\\.0\\.model$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/rho-T-loci/0\\.3\\.model$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/rho-T-loci/0\\.085\\.model$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/.*\\.ps$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange\\.mem$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange\\.aux$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange\\.log$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange\\.dvi$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange\\.tex\\.bak$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/head\\.tmp$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/body\\.tmp$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/prior-dvi\\.aux$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/j10\\.tex$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/j12\\.tex$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/j16\\.tex$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/j20\\.tex$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/j22\\.tex$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/j26\\.tex$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/j30\\.tex$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/j32\\.tex$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/j36\\.tex$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/k10\\.tex$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/k12\\.tex$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/k20\\.tex$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/k22\\.tex$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/k30\\.tex$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/k32\\.tex$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/1_exchange_dgamma1\\.yplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/1_exchange_dlnp\\.yplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/2_exchange_dgamma1\\.yplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/2_exchange_dlnp\\.yplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/linear_exchange_dgamma1\\.yplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/linear_exchange_dlnp\\.yplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/noexchange_dgamma1\\.yplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/noexchange_dlnp\\.yplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/nr_exchange_dgamma1\\.yplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/nr_exchange_dlnp\\.yplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/series_exchange_dgamma1\\.yplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/series_exchange_dlnp\\.yplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_JNR_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_Jseries_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_KNR_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_Kseries_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check34_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check35_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check36_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check43_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check44_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check45_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check46_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check47_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check48_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/tc_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/.*\\.pyc$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/context\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/make\\.out.*$;^C:/hoffman/My Builds/testcase/www/Makefile$;^C:/hoffman/My Builds/testcase/www/Makefile\\.in$;^C:/hoffman/My Builds/testcase/src/.*\\.flc$;^C:/hoffman/My Builds/testcase/src/Makefile$;^C:/hoffman/My Builds/testcase/src/Makefile\\.in$;^C:/hoffman/My Builds/testcase/src/\\.deps$;^C:/hoffman/My Builds/testcase/src/\\.libs$;^C:/hoffman/My Builds/testcase/src/.*\\.la$;^C:/hoffman/My Builds/testcase/src/.*\\.lo$;^C:/hoffman/My Builds/testcase/src/make\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/statef.*\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/0\\.1\\.model$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/0\\.1\\.model_13$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/0\\.1\\.model_23$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/0\\.3\\.model$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/0\\.3\\.model_13$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/0\\.3\\.model_23$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/1\\.0\\.model$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/1\\.0\\.model_13$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/1\\.0\\.model_15$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/1\\.0\\.model_23$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/1\\.0\\.model_rel$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/hot_post_agb\\.model$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/rgb_tip\\.model$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/rgbtip\\.1\\.0\\.model$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/rgbtip\\.1\\.0\\.model_13$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/rgbtip\\.1\\.0\\.model_23$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/start_shellflash\\.model$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/white_dwarf\\.model$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/zahb\\.1\\.0\\.model$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/zahb\\.1\\.0\\.model_13$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/zahb\\.1\\.0\\.model_23$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/model-loci/zahb\\.model$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/dh/dgamma1$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/dh/dlnp$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/dh/statef_compare\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/fermi_dirac_approx/15gamma1\\.gnuplot$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/fermi_dirac_approx/15lnp\\.gnuplot$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/fermi_dirac_approx/23gamma1\\.gnuplot$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/fermi_dirac_approx/23lnp\\.gnuplot$;^C:/hoffman/My Builds/testcase/www/eospaper/solution/thermodynamic_consistency/.*\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/solution/thermodynamic_consistency/.*\\.results$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/pteh/dgamma1$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/pteh/dlnp$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/pteh/statef_compare\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/newversion_grid/.*\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/newversion_grid/.*\\.err$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/.*\\.ps$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/.*\\.pyc$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/eff_fit\\.aux$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/eff_fit\\.dvi$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/eff_fit\\.log$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/body\\.tmp$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/head\\.tmp$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/prior-dvi\\.aux$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/3order_data\\.tex$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/5order_data\\.tex$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/8order_data\\.tex$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/eff_check8_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/eff_check1_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/eff_check3_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/eff_check5_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/effo_check3_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/effoo_check3_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/fda15gamma1\\.yplot$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/fda15lnp\\.yplot$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/fda23gamma1\\.yplot$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/fda23lnp\\.yplot$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/tc_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/make\\.out.*$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/thermodynamic_consistency/statef_compare\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/thermodynamic_consistency/tc\\.results$;^C:/hoffman/My Builds/testcase/www/eospaper/solution/opal_solar/opal_compare_model\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/solution/opal_solar/opal_compare_solar\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/solution/opal_solar/opal_solar\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/solution/opal_solar/opal_solar_1995\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/solution/opal_solar/statef_opal_model\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/solution/opal_solar/statef_opal_model_1995\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/purehe_newversion_grid/.*\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/purehe_newversion_grid/.*\\.err$;^C:/hoffman/My Builds/testcase/include/Makefile\\.in$;^C:/hoffman/My Builds/testcase/include/Makefile$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/model-loci/0\\.1\\.model_pteh$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/model-loci/1\\.0\\.model_eos1a-eos1$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/model-loci/1\\.0\\.model_pteh$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/model-loci/statef_model_0\\.1\\.model_pteh\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/model-loci/statef_model_1\\.0\\.model_eos1a-eos1\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/model-loci/statef_model_1\\.0\\.model_pteh\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/context/contour\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/context/eos_grid\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/context/statef_grid\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/thermodynamic_consistency/fort\\.91$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/thermodynamic_consistency/statef_compare\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/nocoulomb/dgamma1$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/nocoulomb/dlnp$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/nocoulomb/statef_compare\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/context$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/oldversion_grid$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/2005Ap&SS\\.298\\.\\.135S\\.pdf$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/2007Ap&SS\\.307\\.\\.263C\\.pdf$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/astro-ph\\.9909168_eprint_submitted_to_High_Press\\.Res\\.16,331\\.pdf$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/.*ps.*$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/.*\\.pyc$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/convergence\\.aux$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/convergence\\.dvi$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/convergence\\.log$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/body\\.tmp$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/head\\.tmp$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/prior-dvi\\.aux$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/statef_grid-newversion$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/context\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/pureh_context\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/purehe_context\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/old$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/make\\.out.*$;^C:/hoffman/My Builds/testcase/utils/.*\\.flc$;^C:/hoffman/My Builds/testcase/utils/Makefile$;^C:/hoffman/My Builds/testcase/utils/Makefile\\.in$;^C:/hoffman/My Builds/testcase/utils/\\.deps$;^C:/hoffman/My Builds/testcase/utils/\\.libs$;^C:/hoffman/My Builds/testcase/utils/.*\\.la$;^C:/hoffman/My Builds/testcase/utils/.*\\.lo$;^C:/hoffman/My Builds/testcase/utils/free_eos_test$;^C:/hoffman/My Builds/testcase/utils/test_rosenbrock$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/eff_check/eff_check1\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/eff_check/eff_check3\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/eff_check/eff_check5\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/eff_check/eff_check8\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/eff_check/eff_checknr\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/eff_check/effo_check3\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/eff_check/effoo_check3\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence_20070613$;^C:/hoffman/My Builds/testcase/www/eospaper/text$;^C:/hoffman/My Builds/testcase/www/eospaper/cassisi_book_fig$;^C:/hoffman/My Builds/testcase/www/eospaper/1\\.1\\.0$;^C:/hoffman/My Builds/testcase/www/eospaper/2\\.0\\.0$;^C:/hoffman/My Builds/testcase/www/eospaper/1\\.2\\.0$;^C:/hoffman/My Builds/testcase/www/eospaper/1\\.3\\.0$;^C:/hoffman/My Builds/testcase/www/eospaper/1\\.4\\.0$;^C:/hoffman/My Builds/testcase/www/eospaper/1\\.5\\.0$;^C:/hoffman/My Builds/testcase/www/eospaper/1\\.6\\.0$;^C:/hoffman/My Builds/testcase/www/eospaper/figures$;^C:/hoffman/My Builds/testcase/www/eospaper/old$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/.*\\.ps.*$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/coulomb\\.aux$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/coulomb\\.dvi$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/coulomb\\.log$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/.*\\.pyc$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/body\\.tmp$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/head\\.tmp$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/prior-dvi\\.aux$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/context\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/dh_dgamma1_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/dh_dlnp_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/dhtau_dgamma1_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/dhtau_dlnp_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/nocoulomb_dgamma1_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/nocoulomb_dlnp_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/pteh_dgamma1_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/pteh_dlnp_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/make\\.out.*$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/exchange_JNR\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/exchange_Jseries\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/exchange_KNR\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/exchange_Kseries\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/exchange_check34\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/exchange_check35\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/exchange_check36\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/exchange_check44\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/exchange_check45\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/exchange_check46\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/statef_compare_1_exchange\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/statef_compare_2_exchange\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/statef_compare_linear_exchange\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/statef_compare_noexchange\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/statef_compare_nr_exchange\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/statef_compare_series_exchange\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/1_exchange_dgamma1\\.gnuplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/noexchange_dlnp\\.gnuplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/nr_exchange_dgamma1\\.gnuplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/series_exchange_dlnp\\.gnuplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/series_exchange_dgamma1\\.gnuplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/linear_exchange_dlnp\\.gnuplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/2_exchange_dgamma1\\.gnuplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/nr_exchange_dlnp\\.gnuplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/linear_exchange_dgamma1\\.gnuplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/noexchange_dgamma1\\.gnuplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/1_exchange_dlnp\\.gnuplot$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/exchange_check/2_exchange_dlnp\\.gnuplot$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/pureh_newversion_grid/.*\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/convergence/pureh_newversion_grid/.*\\.err$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/dhtau/dgamma1$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/dhtau/dlnp$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/dhtau/statef_compare\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/model-loci/statef_model_0\\.1\\.model\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/model-loci/statef_model_0\\.3\\.model\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/model-loci/statef_model_1\\.0\\.model\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/model-loci/statef_model_1\\.0\\.model_linear\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/model-loci/statef_model_1\\.0\\.model_noexchange\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/model-loci/statef_model_1\\.0\\.model_nr\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/model-loci/statef_model_1\\.0\\.rgbtip\\.model\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/model-loci/statef_model_1\\.0\\.zahb\\.model\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/model-loci/1\\.0\\.zahb\\.model$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/model-loci/1\\.0\\.rgbtip\\.model$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/model-loci/1\\.0\\.model_linear$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/model-loci/1\\.0\\.model_noexchange$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/model-loci/1\\.0\\.model_nr$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/model-loci/0\\.1\\.model$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/model-loci/1\\.0\\.model$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/model-loci/0\\.3\\.model$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/context/contour\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/context/eos_grid\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/exchange/context/statef_grid\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/rho-T-loci/gong/delta\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/rho-T-loci/gong/m0085eos1gong\\.ascii$;^C:/hoffman/My Builds/testcase/www/eospaper/eff_fit/rho-T-loci/gong/m0085eos2gong\\.ascii$;^C:/hoffman/My Builds/testcase/www/eospaper/coulomb/coulomb_adjust/coulomb_adjust\\.out$;^C:/hoffman/My Builds/testcase/www/eospaper/solution/.*\\.ps$;^C:/hoffman/My Builds/testcase/www/eospaper/solution/.*\\.pyc$;^C:/hoffman/My Builds/testcase/www/eospaper/solution/head\\.tmp$;^C:/hoffman/My Builds/testcase/www/eospaper/solution/body\\.tmp$;^C:/hoffman/My Builds/testcase/www/eospaper/solution/prior-dvi\\.aux$;^C:/hoffman/My Builds/testcase/www/eospaper/solution/solution\\.aux$;^C:/hoffman/My Builds/testcase/www/eospaper/solution/solution\\.log$;^C:/hoffman/My Builds/testcase/www/eospaper/solution/solution\\.dvi$;^C:/hoffman/My Builds/testcase/www/eospaper/solution/rtc_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/solution/tc_yplot\\.in$;^C:/hoffman/My Builds/testcase/www/eospaper/solution/make\\.out.*$")
+
+#
+# Define a macro
+#
+MACRO(ASSERT value msg)
+ IF (NOT ${value})
+ MESSAGE ("Assertion failure:" ${msg} )
+ ENDIF (NOT ${value})
+ENDMACRO(ASSERT)
+
+# invoke the macro
+ASSERT(Complex_BINARY_DIR "The PROJECT command is broken")
+
+#
+# Define a var args macro, it must take two or four args
+#
+MACRO(TEST_ARGC value1 value2)
+ ADD_DEFINITIONS(${value1} ${value2})
+ IF (${ARGC} MATCHES 4)
+ ADD_DEFINITIONS(${ARGV2} ${ARGV3})
+ ENDIF (${ARGC} MATCHES 4)
+ENDMACRO(TEST_ARGC)
+
+# invoke the macro
+TEST_ARGC(-DCMAKE_ARGV1 -DCMAKE_ARGV2 -DCMAKE_ARGV3 -DCMAKE_ARGV4)
+
+MACRO(TEST_VAR_ARG fa)
+ IF("${ARGV}" MATCHES "^1;2;3$")
+ MESSAGE(STATUS "ARGV works")
+ ELSE("${ARGV}" MATCHES "^1;2;3$")
+ MESSAGE(FATAL_ERROR "ARGV does not work; got \"${ARGV}\" instead of \"1;2;3\"")
+ ENDIF("${ARGV}" MATCHES "^1;2;3$")
+ IF("${ARGN}" MATCHES "^2;3$")
+ MESSAGE(STATUS "ARGN works")
+ ELSE("${ARGN}" MATCHES "^2;3$")
+ MESSAGE(FATAL_ERROR "ARGV does not work; got \"${ARGN}\" instead of \"2;3\"")
+ ENDIF("${ARGN}" MATCHES "^2;3$")
+ENDMACRO(TEST_VAR_ARG)
+
+TEST_VAR_ARG(1 2 3)
+
+# Floating-point comparison test.
+IF(2.4 LESS 2.4)
+ MESSAGE(FATAL_ERROR "Failed: 2.4 LESS 2.4")
+ENDIF(2.4 LESS 2.4)
+IF(2.4 GREATER 2.4)
+ MESSAGE(FATAL_ERROR "Failed: 2.4 GREATER 2.4")
+ENDIF(2.4 GREATER 2.4)
+IF(NOT 2.4 EQUAL 2.4)
+ MESSAGE(FATAL_ERROR "Failed: NOT 2.4 EQUAL 2.4")
+ENDIF(NOT 2.4 EQUAL 2.4)
+
+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(NOT CMAKE_COMPILER_IS_GNUCXX)
+ENDIF(CMAKE_SYSTEM MATCHES "OSF1-V.*")
+
+
+ADD_DEFINITIONS(-DCMAKE_IS_FUN)
+ADD_DEFINITIONS(-DCMAKE_IS_REALLY_FUN)
+SET_PROPERTY(DIRECTORY
+ PROPERTY COMPILE_DEFINITIONS_RELEASE
+ CMAKE_IS_FUN_IN_RELEASE_MODE
+ )
+
+SET(TEST_SEP "a b c")
+SEPARATE_ARGUMENTS(TEST_SEP)
+
+
+#
+# Include vars from a file and from a cache
+#
+IF (EXISTS ${Complex_SOURCE_DIR}/VarTests.cmake)
+ INCLUDE(${Complex_SOURCE_DIR}/VarTests.cmake)
+ENDIF (EXISTS ${Complex_SOURCE_DIR}/VarTests.cmake)
+INCLUDE(fileshouldnotbehere OPTIONAL)
+LOAD_CACHE(${Complex_SOURCE_DIR}/Cache
+ EXCLUDE
+ CACHE_TEST_VAR_EXCLUDED
+ INCLUDE_INTERNALS
+ CACHE_TEST_VAR_INTERNAL)
+
+LOAD_CACHE(${Complex_SOURCE_DIR}/Cache READ_WITH_PREFIX foo CACHE_TEST_VAR2)
+IF(${fooCACHE_TEST_VAR2} MATCHES bar)
+ MESSAGE("Load cache worked: ${fooCACHE_TEST_VAR2}")
+ELSE(${fooCACHE_TEST_VAR2} MATCHES bar)
+ MESSAGE(FATAL_ERROR "Load cache with prefix failed: ${fooCACHE_TEST_VAR2}")
+ENDIF(${fooCACHE_TEST_VAR2} MATCHES bar)
+
+
+
+#
+# Specify include and lib dirs
+# (BEFORE is for coverage)
+#
+INCLUDE_DIRECTORIES(
+ Library
+)
+
+INCLUDE_DIRECTORIES(BEFORE
+ ${Complex_BINARY_DIR}
+)
+INCLUDE_DIRECTORIES(SYSTEM Library/SystemDir)
+
+INCLUDE_REGULAR_EXPRESSION("^(cmTest|file|sharedFile|test).*$" "^cmMissing")
+
+LINK_DIRECTORIES(
+ ${Complex_BINARY_DIR}/Library
+)
+
+#
+# check for SET CACHE FORCE
+#
+SET(FORCE_TEST 1 CACHE STRING "a test")
+SET(FORCE_TEST 0 CACHE STRING "a test" FORCE)
+
+#
+# Lib and exe path
+#
+SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${Complex_BINARY_DIR}/lib/static")
+SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${Complex_BINARY_DIR}/lib")
+SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${Complex_BINARY_DIR}/bin")
+
+MESSAGE (Test " " escape " " semi-colon " " \; \;)
+#
+# Exec program (TODO: test a result)
+# Increase coverage.
+#
+MESSAGE("\nIgnore this message")
+OPTION(NO_EXEC_PROGRAM "Do not test EXEC_PROGRAM" 0)
+IF (NOT NO_EXEC_PROGRAM)
+ EXEC_PROGRAM(${CMAKE_COMMAND} ARGS -E echo NO_EXEC_PROGRAM "${Complex_BINARY_DIR}")
+ELSE (NOT NO_EXEC_PROGRAM)
+ MESSAGE("Set this option ON")
+ENDIF (NOT NO_EXEC_PROGRAM)
+
+MARK_AS_ADVANCED(NO_EXEC_PROGRAM)
+MARK_AS_ADVANCED(CLEAR NO_EXEC_PROGRAM)
+
+# Execute a process. Add coverage for this command.
+EXECUTE_PROCESS(
+ COMMAND ${CMAKE_COMMAND} -E echo "ABCDEFG"
+ OUTPUT_VARIABLE TEST_OUT
+ )
+IF("${TEST_OUT}" MATCHES "^ABCDEFG\n$")
+ELSE("${TEST_OUT}" MATCHES "^ABCDEFG\n$")
+ MESSAGE(SEND_ERROR "EXECUTE_PROCESS output test failed: [${TEST_OUT}]")
+ENDIF("${TEST_OUT}" MATCHES "^ABCDEFG\n$")
+
+# This test has some problems on UNIX systems. Disabling for now.
+#
+# EXECUTE_PROCESS(
+# COMMAND ${CMAKE_COMMAND} -E echo "ABCDEFG"
+# COMMAND /process/does/not/exist
+# OUTPUT_QUIET
+# ERROR_QUIET
+# RESULT_VARIABLE RESULT
+# )
+# IF("${RESULT}" MATCHES "^0$")
+# MESSAGE(SEND_ERROR
+# "EXECUTE_PROCESS result test failed with RESULT=[${RESULT}]")
+# ELSE("${RESULT}" MATCHES "^0$")
+# MESSAGE(STATUS "EXECUTE_PROCESS result test passed with RESULT=[${RESULT}]")
+# ENDIF("${RESULT}" MATCHES "^0$")
+
+#
+# Create directory.
+# The 'complex' executable will then test if this dir exists,
+# sadly it won't be able to remove it.
+#
+MAKE_DIRECTORY("${Complex_BINARY_DIR}/make_dir")
+
+#
+# Test FIND_LIBARY
+# Create a dummy empty lib
+#
+CONFIGURE_FILE(
+ ${Complex_SOURCE_DIR}/Library/dummy
+ ${Complex_BINARY_DIR}/Library/dummylib.lib
+ COPYONLY IMMEDIATE)
+FOREACH (ext ${CMAKE_SHLIB_SUFFIX};.so;.a;.sl)
+ CONFIGURE_FILE(
+ ${Complex_SOURCE_DIR}/Library/dummy
+ ${Complex_BINARY_DIR}/Library/libdummylib${ext}
+ COPYONLY IMMEDIATE)
+ENDFOREACH (ext)
+
+FIND_LIBRARY(FIND_DUMMY_LIB
+ dummylib
+ PATHS
+ ${Complex_BINARY_DIR}/Library DOC "find dummy lib")
+
+FIND_LIBRARY(FIND_DUMMY_LIB
+ NAMES dummylib dummylib2
+ PATHS
+ ${Complex_BINARY_DIR}/Library DOC "find dummy lib")
+
+#
+# Test SET_SOURCE_FILES_PROPERTIES
+#
+SET_SOURCE_FILES_PROPERTIES(nonexisting_file2
+ GENERATED
+ ABSTRACT
+ WRAP_EXCLUDE
+ COMPILE_FLAGS "-foo -bar")
+
+GET_SOURCE_FILE_PROPERTY(FILE_HAS_ABSTRACT nonexisting_file2 ABSTRACT)
+GET_SOURCE_FILE_PROPERTY(FILE_HAS_WRAP_EXCLUDE nonexisting_file2 WRAP_EXCLUDE)
+GET_SOURCE_FILE_PROPERTY(FILE_COMPILE_FLAGS nonexisting_file2 COMPILE_FLAGS)
+
+SET_SOURCE_FILES_PROPERTIES(nonexisting_file3 PROPERTIES
+ GENERATED 1
+ ABSTRACT 1
+ WRAP_EXCLUDE 1
+ COMPILE_FLAGS "-foo -bar")
+GET_SOURCE_FILE_PROPERTY(FILE_HAS_ABSTRACT nonexisting_file3 ABSTRACT)
+GET_SOURCE_FILE_PROPERTY(FILE_HAS_WRAP_EXCLUDE nonexisting_file3 WRAP_EXCLUDE)
+GET_SOURCE_FILE_PROPERTY(FILE_COMPILE_FLAGS nonexisting_file3 COMPILE_FLAGS)
+
+#
+# Test registry (win32)
+# Create a file, put its path in a registry key, try to find the file in that
+# path using that registry key, then remove the file and the key
+#
+IF (WIN32)
+ IF (NOT UNIX)
+ SET(dir "${Complex_BINARY_DIR}/registry_dir")
+ SET(file "registry_test_dummy")
+ SET(hkey "HKEY_CURRENT_USER\\Software\\Kitware\\CMake\\Tests\\Complex;registry_test")
+ CONFIGURE_FILE(
+ ${Complex_SOURCE_DIR}/Library/dummy
+ "${dir}/${file}"
+ COPYONLY IMMEDIATE)
+ EXEC_PROGRAM(${CMAKE_COMMAND} ARGS "-E write_regv \"${hkey}\" \"${dir}\"")
+ FIND_PATH(REGISTRY_TEST_PATH
+ ${file}
+ "[${hkey}]" DOC "Registry_Test_Path")
+ EXEC_PROGRAM(${CMAKE_COMMAND} ARGS "-E delete_regv \"${hkey}\"")
+ EXEC_PROGRAM(${CMAKE_COMMAND} ARGS "-E remove \"${dir}/${file}\"")
+ ENDIF (NOT UNIX)
+ENDIF (WIN32)
+
+#
+# Test a set and a remove
+#
+SET(REMOVE_STRING a b c d e f)
+SET(removeVar1 c e)
+REMOVE(REMOVE_STRING ${removeVar1} f)
+
+#
+# Test an IF inside a FOREACH.
+#
+FOREACH(x "a")
+ IF(${x} MATCHES "a")
+ # Should always execute.
+ SET(IF_INSIDE_FOREACH_THEN_EXECUTED 1)
+ ELSE(${x} MATCHES "a")
+ # Should never execute.
+ SET(IF_INSIDE_FOREACH_ELSE_EXECUTED 1)
+ ENDIF(${x} MATCHES "a")
+ENDFOREACH(x)
+
+# test WHILE command
+SET (while_var 1)
+WHILE (while_var LESS 1000)
+ SET(while_var ${while_var}0)
+ENDWHILE(while_var LESS 1000)
+
+SET(SHOULD_BE_ZERO )
+SET(SHOULD_BE_ONE 1)
+
+# test elseif functionality, the mess below tries to catch problem
+# of clauses being executed early or late etc
+set (RESULT 3)
+if (RESULT EQUAL 1)
+ if (RESULT EQUAL 2)
+ set (ELSEIF_RESULT 1)
+ elseif (RESULT EQUAL 3)
+ set (ELSEIF_RESULT 1)
+ endif (RESULT EQUAL 2)
+elseif (RESULT EQUAL 2)
+ set (ELSEIF_RESULT 1)
+elseif (RESULT EQUAL 3)
+ if (RESULT EQUAL 2)
+ set (ELSEIF_RESULT 1)
+ elseif (RESULT EQUAL 3)
+ if (NOT ELSEIF_RESULT EQUAL 1)
+ set (ELSEIF_RESULT 2)
+ endif (NOT ELSEIF_RESULT EQUAL 1)
+ endif (RESULT EQUAL 2)
+elseif (RESULT EQUAL 4)
+ if (RESULT EQUAL 2)
+ set (ELSEIF_RESULT 1)
+ elseif (RESULT EQUAL 3)
+ set (ELSEIF_RESULT 1)
+ endif (RESULT EQUAL 2)
+else (RESULT EQUAL 1)
+ if (RESULT EQUAL 2)
+ set (ELSEIF_RESULT 1)
+ elseif (RESULT EQUAL 3)
+ set (ELSEIF_RESULT 1)
+ endif (RESULT EQUAL 2)
+endif (RESULT EQUAL 1)
+
+if (NOT ELSEIF_RESULT EQUAL 2)
+ set (ELSEIF_RESULT 0)
+endif (NOT ELSEIF_RESULT EQUAL 2)
+
+# test handling of parenthetical groups in conditionals
+if (2 GREATER 1 AND (4 LESS 3 OR 5 LESS 6) AND NOT (7 GREATER 8))
+ set(CONDITIONAL_PARENTHESES 1)
+endif()
+
+
+#
+# Configure file
+# (plug vars to #define so that they can be tested)
+#
+CONFIGURE_FILE(
+ ${Complex_SOURCE_DIR}/cmTestConfigure.h.in
+ ${Complex_BINARY_DIR}/cmTestConfigure.h)
+
+SET(STRING_WITH_QUOTES "\"hello world\"")
+# test CONFIGURE_FILE with ESCAPE_QUOTES on
+CONFIGURE_FILE(
+ ${Complex_SOURCE_DIR}/cmTestConfigureEscape.h.in
+ ${Complex_BINARY_DIR}/cmTestConfigureEscape.h ESCAPE_QUOTES)
+
+# Test regular expression commands.
+STRING(REGEX MATCH "b" RESULT "abc")
+IF(NOT RESULT)
+ MESSAGE(SEND_ERROR "STRING(REGEX MATCH ... ) test failed.")
+ENDIF(NOT RESULT)
+STRING(REGEX MATCHALL "b" RESULT "abcb")
+IF(NOT RESULT)
+ MESSAGE(SEND_ERROR "STRING(REGEX MATCHALL ... ) test failed.")
+ENDIF(NOT RESULT)
+STRING(REGEX REPLACE ".([bd])." "[\\1]" RESULT "a(b)c(d)e")
+IF("x${RESULT}" MATCHES "^xa\\[b\\]c\\[d\\]e$")
+ SET(STRING_REGEX_PASSED 1)
+ENDIF("x${RESULT}" MATCHES "^xa\\[b\\]c\\[d\\]e$")
+IF(NOT STRING_REGEX_PASSED)
+ MESSAGE(SEND_ERROR
+ "STRING(REGEX REPLACE ... ) test failed (\"${RESULT}\" v. \"a[b]c[d]e\")")
+ENDIF(NOT STRING_REGEX_PASSED)
+
+
+#
+# Create the libs and the main exe
+#
+ADD_SUBDIRECTORY(Library)
+ADD_SUBDIRECTORY(Executable)
+SUBDIR_DEPENDS(Executable Library)
+EXPORT_LIBRARY_DEPENDENCIES(${Complex_BINARY_DIR}/ComplexLibraryDepends.cmake)
+INCLUDE(${Complex_BINARY_DIR}/ComplexLibraryDepends.cmake OPTIONAL)
diff --git a/Tests/ComplexOneConfig/Cache/CMakeCache.txt b/Tests/ComplexOneConfig/Cache/CMakeCache.txt
new file mode 100644
index 000000000..17c55aa01
--- /dev/null
+++ b/Tests/ComplexOneConfig/Cache/CMakeCache.txt
@@ -0,0 +1,34 @@
+# This is the CMakeCache file.
+# For build in directory: d:/build/kitware/cmake/CMake-nmake/Tests/Complex
+# You can edit this file to change values found and used by cmake.
+# If you do not want to change any of the values, simply exit the editor.
+# If you do want to change a value, simply edit, save, and exit the editor.
+# The syntax for the file is as follows:
+# KEY:TYPE=VALUE
+# KEY is the name of a varible in the cache.
+# TYPE is a hint to GUI's for the type of VALUE, DO NOT EDIT TYPE!.
+# VALUE is the current value for the KEY.
+
+########################
+# EXTERNAL cache entries
+########################
+
+//A var.
+CACHE_TEST_VAR1:STRING=foo
+
+//A var.
+CACHE_TEST_VAR2:FILEPATH=bar
+
+//A var.
+CACHE_TEST_VAR3:BOOL=1
+
+//A var.
+CACHE_TEST_VAR_EXCLUDED:BOOL=1
+
+
+########################
+# INTERNAL cache entries
+########################
+
+//A var.
+CACHE_TEST_VAR_INTERNAL:INTERNAL=bar
diff --git a/Tests/ComplexOneConfig/Executable/A.cxx b/Tests/ComplexOneConfig/Executable/A.cxx
new file mode 100644
index 000000000..fb3eb0819
--- /dev/null
+++ b/Tests/ComplexOneConfig/Executable/A.cxx
@@ -0,0 +1,9 @@
+// Include code from a header that should not be compiled separately.
+#include "A.hh"
+
+#include <stdio.h>
+int main()
+{
+ printf("#define A_VALUE %d\n", A());
+ return 0;
+}
diff --git a/Tests/ComplexOneConfig/Executable/A.h b/Tests/ComplexOneConfig/Executable/A.h
new file mode 100644
index 000000000..25c45fcbf
--- /dev/null
+++ b/Tests/ComplexOneConfig/Executable/A.h
@@ -0,0 +1,4 @@
+// This header should not be compiled directly but through inclusion
+// in A.cxx through A.hh.
+extern int A();
+int A() { return 10; }
diff --git a/Tests/ComplexOneConfig/Executable/A.hh b/Tests/ComplexOneConfig/Executable/A.hh
new file mode 100644
index 000000000..e6bab022e
--- /dev/null
+++ b/Tests/ComplexOneConfig/Executable/A.hh
@@ -0,0 +1,2 @@
+// This header should not be compiled directly but through inclusion in A.cxx
+#include "A.h"
diff --git a/Tests/ComplexOneConfig/Executable/A.txt b/Tests/ComplexOneConfig/Executable/A.txt
new file mode 100644
index 000000000..8ee9462be
--- /dev/null
+++ b/Tests/ComplexOneConfig/Executable/A.txt
@@ -0,0 +1 @@
+This file should not be compiled!
diff --git a/Tests/ComplexOneConfig/Executable/CMakeLists.txt b/Tests/ComplexOneConfig/Executable/CMakeLists.txt
new file mode 100644
index 000000000..345836257
--- /dev/null
+++ b/Tests/ComplexOneConfig/Executable/CMakeLists.txt
@@ -0,0 +1,170 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 1.3)
+#
+# Create exe.
+#
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DTEST_CXX_FLAGS")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DTEST_C_FLAGS")
+
+# Create an imported target for if(TARGET) test below.
+ADD_LIBRARY(ExeImportedTarget UNKNOWN IMPORTED)
+
+# Test if(TARGET) command.
+IF(NOT TARGET CMakeTestLibrary)
+ MESSAGE(FATAL_ERROR "IF(NOT TARGET CMakeTestLibrary) returned true!")
+ENDIF(NOT TARGET CMakeTestLibrary)
+IF(NOT TARGET ExeImportedTarget)
+ MESSAGE(FATAL_ERROR "IF(NOT TARGET ExeImportedTarget) returned true!")
+ENDIF(NOT TARGET ExeImportedTarget)
+IF(TARGET LibImportedTarget)
+ MESSAGE(FATAL_ERROR "IF(TARGET LibImportedTarget) returned true!")
+ENDIF(TARGET LibImportedTarget)
+IF(TARGET NotATarget)
+ MESSAGE(FATAL_ERROR "IF(TARGET NotATarget) returned true!")
+ENDIF(TARGET NotATarget)
+
+ # Use LINK_LIBRARIES instead of TARGET_LINK_LIBRARIES to
+SET(COMPLEX_LIBS CMakeTestLibrary;CMakeTestLibraryShared;CMakeTestCLibraryShared)
+LINK_LIBRARIES(${COMPLEX_LIBS})
+
+# Test forcing a .cxx file to not build.
+SET_SOURCE_FILES_PROPERTIES(complex_nobuild.cxx PROPERTIES
+ HEADER_FILE_ONLY 1)
+
+# Test forcing a .c file to not build.
+# This makes sure a mixed language library is created
+# with header file only sources
+SET_SOURCE_FILES_PROPERTIES(complex_nobuild.c PROPERTIES
+ HEADER_FILE_ONLY 1)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+ADD_EXECUTABLE(A A.cxx A.hh A.h A.txt)
+ADD_CUSTOM_COMMAND(OUTPUT Aout.h COMMAND A > Aout.h VERBATIM)
+ADD_EXECUTABLE(complex complex testcflags.c Aout.h)
+# Sub1/NameConflictTest.c Sub2/NameConflictTest.c)
+ADD_EXECUTABLE(complex.file complex.file.cxx complex_nobuild.cxx
+ complex_nobuild.c)
+
+IF (UNIX)
+ TARGET_LINK_LIBRARIES(complex ${CMAKE_DL_LIBS})
+ELSE(UNIX)
+ IF (NOT BORLAND)
+ IF(NOT MINGW)
+ TARGET_LINK_LIBRARIES(complex rpcrt4.lib)
+ ENDIF(NOT MINGW)
+ ENDIF(NOT BORLAND)
+ENDIF (UNIX)
+
+# Test linking to static lib when a shared lib has the same name.
+IF(CMAKE_EXE_LINK_STATIC_CXX_FLAGS)
+ ADD_DEFINITIONS(-DCOMPLEX_TEST_LINK_STATIC)
+ TARGET_LINK_LIBRARIES(complex CMakeTestLinkStatic)
+ENDIF(CMAKE_EXE_LINK_STATIC_CXX_FLAGS)
+
+# can we get the path to a source file
+GET_SOURCE_FILE_PROPERTY(A_LOCATION A.cxx LOCATION)
+IF ("${A_LOCATION}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}/A.cxx")
+ ADD_DEFINITIONS(-DCMAKE_FOUND_ACXX)
+ENDIF ("${A_LOCATION}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}/A.cxx")
+
+# get the directory parent
+GET_DIRECTORY_PROPERTY(P_VALUE PARENT_DIRECTORY)
+IF ("${P_VALUE}" STREQUAL "${CMAKE_SOURCE_DIR}")
+ ADD_DEFINITIONS(-DCMAKE_FOUND_PARENT)
+ENDIF ("${P_VALUE}" STREQUAL "${CMAKE_SOURCE_DIR}")
+
+# get the stack of listfiles
+INCLUDE(Included.cmake)
+IF ("${LF_VALUE}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt;${CMAKE_CURRENT_SOURCE_DIR}/Included.cmake")
+ ADD_DEFINITIONS(-DCMAKE_FOUND_LISTFILE_STACK)
+ENDIF ("${LF_VALUE}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt;${CMAKE_CURRENT_SOURCE_DIR}/Included.cmake")
+
+# Test add/remove definitions.
+ADD_DEFINITIONS(
+ -DCOMPLEX_DEFINED_PRE
+ -DCOMPLEX_DEFINED
+ -DCOMPLEX_DEFINED_POST
+ -DCOMPLEX_DEFINED
+ )
+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")
+ADD_CUSTOM_COMMAND(TARGET complex PRE_BUILD
+ COMMAND ${CREATE_FILE_EXE}
+ ARGS "${Complex_BINARY_DIR}/Executable/prelink.txt")
+ADD_CUSTOM_COMMAND(TARGET complex POST_BUILD
+ COMMAND ${CREATE_FILE_EXE}
+ ARGS "${Complex_BINARY_DIR}/Executable/postbuild.txt")
+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")
+
+SET_SOURCE_FILES_PROPERTIES(complex
+ COMPILE_FLAGS
+ "-DFILE_HAS_EXTRA_COMPILE_FLAGS"
+ #" -DFILE_DEFINE_STRING=\\\"hello\\\""
+ OBJECT_DEPENDS ${Complex_BINARY_DIR}/cmTestGeneratedHeader.h
+)
+SET_TARGET_PROPERTIES(complex PROPERTIES COMPILE_FLAGS "-DCOMPLEX_TARGET_FLAG")
+ADD_CUSTOM_COMMAND(
+ TARGET complex
+ SOURCE ${Complex_SOURCE_DIR}/cmTestGeneratedHeader.h.in
+ COMMAND ${CMAKE_COMMAND}
+ ARGS -E copy ${Complex_SOURCE_DIR}/cmTestGeneratedHeader.h.in
+ ${Complex_BINARY_DIR}/cmTestGeneratedHeader.h
+ OUTPUTS ${Complex_BINARY_DIR}/cmTestGeneratedHeader.h
+ DEPENDS ${CMAKE_COMMAND}
+)
+
+# Test creating an executable that is not built by default.
+ADD_EXECUTABLE(notInAllExe EXCLUDE_FROM_ALL notInAllExe.cxx)
+TARGET_LINK_LIBRARIES(notInAllExe notInAllLib)
+
+# Test user-value flag mapping for the VS IDE.
+IF(MSVC)
+ SET_TARGET_PROPERTIES(notInAllExe PROPERTIES
+ LINK_FLAGS "/NODEFAULTLIB:LIBC;LIBCMT;MSVCRT")
+ENDIF(MSVC)
+
+# Test creating a custom target that builds not-in-all targets.
+ADD_CUSTOM_TARGET(notInAllCustom)
+ADD_DEPENDENCIES(notInAllCustom notInAllExe)
+
+#
+# Output the files required by 'complex' to a file.
+#
+# This test has been moved to the 'required' subdir so that it
+# has no side-effects on the current Makefile (duplicated source file
+# due to source list expansion done twice).
+#
+ADD_SUBDIRECTORY(Temp)
+
+IF(CMAKE_COMPILER_IS_GNUCXX AND CMAKE_INCLUDE_SYSTEM_FLAG_CXX)
+ ADD_EXECUTABLE(testSystemDir testSystemDir.cxx)
+ SET_TARGET_PROPERTIES(testSystemDir PROPERTIES COMPILE_FLAGS "-Werror")
+ENDIF(CMAKE_COMPILER_IS_GNUCXX AND CMAKE_INCLUDE_SYSTEM_FLAG_CXX)
+
+#
+# Extra coverage.Not used.
+#
+INSTALL_TARGETS(/tmp complex)
+INSTALL_PROGRAMS(/tmp complex)
+
+CONFIGURE_FILE(
+ ${Complex_SOURCE_DIR}/Executable/cmVersion.h.in
+ ${Complex_BINARY_DIR}/cmVersion.h)
+
+SOURCE_GROUP(A_GROUP ".cxx")
+SOURCE_GROUP(B_GROUP REGULAR_EXPRESSION "cxx")
+SOURCE_GROUP(C_GROUP FILES complex.cxx)
+
+FILE(WRITE ${Complex_BINARY_DIR}/A/libA.a "test")
+FILE(WRITE ${Complex_BINARY_DIR}/A/libC.a "test")
+FILE(WRITE ${Complex_BINARY_DIR}/B/libB.a "test")
+FILE(WRITE ${Complex_BINARY_DIR}/B/libA.a "test")
+FILE(WRITE ${Complex_BINARY_DIR}/C/libC.a "test")
+FILE(WRITE ${Complex_BINARY_DIR}/C/libB.a "test")
diff --git a/Tests/ComplexOneConfig/Executable/Included.cmake b/Tests/ComplexOneConfig/Executable/Included.cmake
new file mode 100644
index 000000000..2d1ea3e8c
--- /dev/null
+++ b/Tests/ComplexOneConfig/Executable/Included.cmake
@@ -0,0 +1,2 @@
+GET_DIRECTORY_PROPERTY(LF_VALUE LISTFILE_STACK)
+
diff --git a/Tests/ComplexOneConfig/Executable/Sub1/NameConflictTest.c b/Tests/ComplexOneConfig/Executable/Sub1/NameConflictTest.c
new file mode 100644
index 000000000..87203861f
--- /dev/null
+++ b/Tests/ComplexOneConfig/Executable/Sub1/NameConflictTest.c
@@ -0,0 +1,4 @@
+int NameConflictTest1()
+{
+ return 0;
+}
diff --git a/Tests/ComplexOneConfig/Executable/Sub2/NameConflictTest.c b/Tests/ComplexOneConfig/Executable/Sub2/NameConflictTest.c
new file mode 100644
index 000000000..4a3257255
--- /dev/null
+++ b/Tests/ComplexOneConfig/Executable/Sub2/NameConflictTest.c
@@ -0,0 +1,4 @@
+int NameConflictTest2()
+{
+ return 0;
+}
diff --git a/Tests/ComplexOneConfig/Executable/Temp/CMakeLists.txt b/Tests/ComplexOneConfig/Executable/Temp/CMakeLists.txt
new file mode 100644
index 000000000..f00955029
--- /dev/null
+++ b/Tests/ComplexOneConfig/Executable/Temp/CMakeLists.txt
@@ -0,0 +1,8 @@
+#
+# Output the files required by 'complex' to a file.
+# The 'complex' executable will then test if this file exists and remove it.
+# The contents of this file is not tested (absolute paths).
+#
+OUTPUT_REQUIRED_FILES(
+ ${Complex_SOURCE_DIR}/Executable/complex.cxx
+ ${Complex_BINARY_DIR}/Executable/Temp/complex-required.txt)
diff --git a/Tests/ComplexOneConfig/Executable/cmVersion.h.in b/Tests/ComplexOneConfig/Executable/cmVersion.h.in
new file mode 100644
index 000000000..de7522d1d
--- /dev/null
+++ b/Tests/ComplexOneConfig/Executable/cmVersion.h.in
@@ -0,0 +1 @@
+#define CMAKE_MINIMUM_REQUIRED_VERSION "${CMAKE_MINIMUM_REQUIRED_VERSION}"
diff --git a/Tests/ComplexOneConfig/Executable/complex.cxx b/Tests/ComplexOneConfig/Executable/complex.cxx
new file mode 100644
index 000000000..1901d9914
--- /dev/null
+++ b/Tests/ComplexOneConfig/Executable/complex.cxx
@@ -0,0 +1,1026 @@
+#include "cmTestConfigure.h"
+#include "cmTestConfigureEscape.h"
+#include "cmTestGeneratedHeader.h"
+#include "cmVersion.h"
+#include "ExtraSources/file1.h"
+#include "Aout.h"
+#include "file2.h"
+#include "sharedFile.h"
+extern "C" {
+#include "testConly.h"
+}
+#include <vector>
+#include <string>
+#include <iostream>
+#include <string.h>
+
+#include <stdio.h>
+#include <sys/stat.h>
+#if !defined(S_ISDIR)
+# define S_ISDIR(mode) ((mode) & _S_IFDIR)
+#endif
+
+#ifdef COMPLEX_TEST_LINK_STATIC
+extern "C"
+{
+ int TestLinkGetType();
+}
+#endif
+
+int cm_passed = 0;
+int cm_failed = 0;
+// ======================================================================
+
+void cmFailed(const char* Message, const char* m2= "", const char* m3 = "")
+{
+ std::cout << "FAILED: " << Message << m2 << m3 << "\n";
+ cm_failed++;
+}
+
+// ======================================================================
+
+void cmPassed(const char* Message, const char* m2="")
+{
+ std::cout << "Passed: " << Message << m2 << "\n";
+ cm_passed++;
+}
+
+#ifndef COMPLEX_DEFINED_PRE
+# error "COMPLEX_DEFINED_PRE not defined!"
+#endif
+
+#ifdef COMPLEX_DEFINED
+# error "COMPLEX_DEFINED is defined but it should not!"
+#endif
+
+#ifndef COMPLEX_DEFINED_POST
+# error "COMPLEX_DEFINED_POST not defined!"
+#endif
+
+#ifndef CMAKE_IS_REALLY_FUN
+# error This is a problem. Looks like ADD_DEFINITIONS and REMOVE_DEFINITIONS does not work
+#endif
+
+#if defined(NDEBUG) && !defined(CMAKE_IS_FUN_IN_RELEASE_MODE)
+# error Per-configuration directory-level definition not inherited.
+#endif
+
+// ======================================================================
+
+void TestAndRemoveFile(const char* filename)
+{
+ struct stat st;
+ if(stat(filename, &st) < 0)
+ {
+ cmFailed("Could not find file: ", filename);
+ }
+ else
+ {
+ if (remove(filename) < 0)
+ {
+ cmFailed("Unable to remove file. It does not imply that this test failed, but it *will* be corrupted thereafter if this file is not removed: ", filename);
+ }
+ else
+ {
+ cmPassed("Find and remove file: ", filename);
+ }
+ }
+}
+
+// ======================================================================
+
+void TestDir(const char* filename)
+{
+ struct stat st;
+ if(stat(filename, &st) < 0 || !S_ISDIR(st.st_mode))
+ {
+ cmFailed("Could not find dir: ", filename);
+ }
+ else
+ {
+ cmPassed("Find dir: ", filename);
+ }
+}
+
+// Here is a stupid function that tries to use std::string methods
+// so that the dec cxx compiler will instantiate the stuff that
+// we are using from the CMakeLib library....
+void ForceStringUse()
+{
+ std::vector<std::string> v;
+ std::vector<std::string> v2;
+ v = v2;
+ std::string cachetest = CACHE_TEST_VAR_INTERNAL;
+ v.push_back(cachetest);
+ v2 = v;
+ std::string x(5,'x');
+ char buff[5];
+ x.copy(buff, 1, 0);
+ x[0] = 'a';
+ std::string::size_type pos = 0;
+ x.replace(pos, pos, pos, 'x');
+ std::string copy = cachetest;
+ cachetest.find("bar");
+ cachetest.rfind("bar");
+ copy.append(cachetest);
+ copy = cachetest.substr(0, cachetest.size());
+}
+
+
+// defined in testcflags.c
+extern "C" int TestCFlags(char* m);
+extern "C" int TestTargetCompileFlags(char* m);
+
+#if 0
+// defined in Sub1/NameConflictTest.c
+extern "C" int NameConflictTest1();
+// defined in Sub2/NameConflictTest.c
+extern "C" int NameConflictTest2();
+#endif
+
+// ======================================================================
+
+int main()
+{
+#if 0
+ if(NameConflictTest1() == 0 && NameConflictTest2() == 0)
+ {
+ cmPassed("Sub dir with same named source works");
+ }
+ else
+ {
+ cmFailed("Sub dir with same named source fails");
+ }
+#endif
+ if(file1() != 1)
+ {
+ cmFailed("Call to file1 function from library failed.");
+ }
+ else
+ {
+ cmPassed("Call to file1 function returned 1.");
+ }
+#ifndef COMPLEX_TARGET_FLAG
+ cmFailed("COMPILE_FLAGS did not work with SET_TARGET_PROPERTIES");
+#else
+ cmPassed("COMPILE_FLAGS did work with SET_TARGET_PROPERTIES");
+#endif
+
+#ifdef ELSEIF_RESULT
+ cmPassed("ELSEIF did work");
+#else
+ cmFailed("ELSEIF did not work");
+#endif
+
+#ifdef CONDITIONAL_PARENTHESES
+ cmPassed("CONDITIONAL_PARENTHESES did work");
+#else
+ cmFailed("CONDITIONAL_PARENTHESES did not work");
+#endif
+
+ if(file2() != 1)
+ {
+ cmFailed("Call to file2 function from library failed.");
+ }
+ else
+ {
+ cmPassed("Call to file2 function returned 1.");
+ }
+#ifndef TEST_CXX_FLAGS
+ cmFailed("CMake CMAKE_CXX_FLAGS is not being passed to the compiler!");
+#else
+ cmPassed("CMake CMAKE_CXX_FLAGS is being passed to the compiler.");
+#endif
+ std::string gen = CMAKE_GENERATOR;
+ // visual studio is currently broken for c flags
+ char msg[1024];
+ if(gen.find("Visual") == gen.npos)
+ {
+#ifdef TEST_C_FLAGS
+ cmFailed("CMake CMAKE_C_FLAGS are being passed to c++ files the compiler!");
+#else
+ cmPassed("CMake CMAKE_C_FLAGS are not being passed to c++ files.");
+#endif
+ if(TestCFlags(msg))
+ {
+ cmPassed(
+ "CMake CMAKE_C_FLAGS are being passed to c files and CXX flags are not.");
+ }
+ else
+ {
+ cmFailed(msg);
+ }
+ }
+ if(TestTargetCompileFlags(msg))
+ {
+ cmPassed(msg);
+ }
+ else
+ {
+ cmFailed(msg);
+ }
+
+ // ----------------------------------------------------------------------
+ // Test ADD_DEFINITIONS
+
+#ifndef CMAKE_IS_FUN
+ cmFailed("CMake is not fun, so it is broken and should be fixed.");
+#else
+ cmPassed("CMAKE_IS_FUN is defined.");
+#endif
+
+#if defined(CMAKE_ARGV1) && defined(CMAKE_ARGV2) && defined(CMAKE_ARGV3) && defined(CMAKE_ARGV4)
+ cmPassed("Variable args for MACROs are working.");
+#else
+ cmFailed("Variable args for MACROs are failing.");
+#endif
+
+ // ----------------------------------------------------------------------
+ // Test GET_SOURCE_FILE_PROPERTY for location
+#ifndef CMAKE_FOUND_ACXX
+ cmFailed("CMake did not get the location of A.cxx correctly");
+#else
+ cmPassed("CMake found A.cxx properly");
+#endif
+
+ // ----------------------------------------------------------------------
+ // Test GET_DIRECTORY_PROPERTY for parent
+#ifndef CMAKE_FOUND_PARENT
+ cmFailed("CMake did not get the location of the parent directory properly");
+#else
+ cmPassed("CMake found the parent directory properly");
+#endif
+
+ // ----------------------------------------------------------------------
+ // Test GET_DIRECTORY_PROPERTY for listfiles
+#ifndef CMAKE_FOUND_LISTFILE_STACK
+ cmFailed("CMake did not get the listfile stack properly");
+#else
+ cmPassed("CMake found the listfile stack properly");
+#endif
+
+ // ----------------------------------------------------------------------
+ // Test SET, VARIABLE_REQUIRES
+
+#ifdef SHOULD_NOT_BE_DEFINED
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED is defined.");
+#endif
+
+#ifndef ONE_VAR
+ cmFailed("cmakedefine is broken, ONE_VAR is not defined.");
+#else
+ cmPassed("ONE_VAR is defined.");
+#endif
+
+#ifndef ONE_VAR_IS_DEFINED
+ cmFailed("cmakedefine, SET or VARIABLE_REQUIRES is broken, "
+ "ONE_VAR_IS_DEFINED is not defined.");
+#else
+ cmPassed("ONE_VAR_IS_DEFINED is defined.");
+#endif
+
+#ifdef ZERO_VAR
+ cmFailed("cmakedefine is broken, ZERO_VAR is defined.");
+#else
+ cmPassed("ZERO_VAR is not defined.");
+#endif
+
+#ifndef STRING_VAR
+ cmFailed("the CONFIGURE_FILE command is broken, STRING_VAR is not defined.");
+#else
+ if(strcmp(STRING_VAR, "CMake is great") != 0)
+ {
+ cmFailed("the SET or CONFIGURE_FILE command is broken. STRING_VAR == ",
+ STRING_VAR);
+ }
+ else
+ {
+ cmPassed("STRING_VAR == ", STRING_VAR);
+ }
+#endif
+
+ // ----------------------------------------------------------------------
+ // Test various IF/ELSE combinations
+
+#ifdef SHOULD_NOT_BE_DEFINED_NOT
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_NOT is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_NOT is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_NOT
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_NOT is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_NOT is defined.");
+#endif
+
+#ifdef SHOULD_NOT_BE_DEFINED_NOT2
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_NOT2 is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_NOT2 is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_NOT2
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_NOT2 is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_NOT2 is defined.");
+#endif
+
+#ifdef SHOULD_NOT_BE_DEFINED_AND
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_AND is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_AND is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_AND
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_AND is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_AND is defined.");
+#endif
+
+#ifdef SHOULD_NOT_BE_DEFINED_AND2
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_AND2 is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_AND2 is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_AND2
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_AND2 is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_AND2 is defined.");
+#endif
+
+#ifdef SHOULD_NOT_BE_DEFINED_OR
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_OR is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_OR is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_OR
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_OR is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_OR is defined.");
+#endif
+
+#ifdef SHOULD_NOT_BE_DEFINED_OR2
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_OR2 is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_OR2 is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_OR2
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_OR2 is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_OR2 is defined.");
+#endif
+
+#ifdef SHOULD_NOT_BE_DEFINED_MATCHES
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_MATCHES is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_MATCHES is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_MATCHES
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_MATCHES is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_MATCHES is defined.");
+#endif
+
+#ifdef SHOULD_NOT_BE_DEFINED_MATCHES2
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_MATCHES2 is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_MATCHES2 is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_MATCHES2
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_MATCHES2 is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_MATCHES2 is defined.");
+#endif
+
+#ifdef SHOULD_NOT_BE_DEFINED_COMMAND
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_COMMAND is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_COMMAND is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_COMMAND
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_COMMAND is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_COMMAND is defined.");
+#endif
+
+#ifdef SHOULD_NOT_BE_DEFINED_COMMAND2
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_COMMAND2 is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_COMMAND2 is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_COMMAND2
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_COMMAND2 is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_COMMAND2 is defined.");
+#endif
+
+#ifdef SHOULD_NOT_BE_DEFINED_EXISTS
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_EXISTS is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_EXISTS is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_EXISTS
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_EXISTS is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_EXISTS is defined.");
+#endif
+
+#ifdef SHOULD_NOT_BE_DEFINED_EXISTS2
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_EXISTS2 is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_EXISTS2 is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_EXISTS2
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_EXISTS2 is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_EXISTS2 is defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_IS_DIRECTORY
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_IS_DIRECTORY is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_IS_DIRECTORY is defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_IS_DIRECTORY2
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_IS_DIRECTORY2 is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_IS_DIRECTORY2 is defined.");
+#endif
+
+#ifdef SHOULD_NOT_BE_DEFINED_LESS
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_LESS is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_LESS is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_LESS
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_LESS is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_LESS is defined.");
+#endif
+
+#ifdef SHOULD_NOT_BE_DEFINED_LESS2
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_LESS2 is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_LESS2 is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_LESS2
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_LESS2 is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_LESS2 is defined.");
+#endif
+
+#ifdef SHOULD_NOT_BE_DEFINED_GREATER
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_GREATER is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_GREATER is not defined.");
+#endif
+
+#ifdef SHOULD_NOT_BE_DEFINED_EQUAL
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_EQUAL is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_EQUAL is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_EQUAL
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_EQUAL is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_EQUAL is defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_GREATER
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_GREATER is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_GREATER is defined.");
+#endif
+
+#ifdef SHOULD_NOT_BE_DEFINED_GREATER2
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_GREATER2 is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_GREATER2 is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_GREATER2
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_GREATER2 is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_GREATER2 is defined.");
+#endif
+
+#ifdef SHOULD_NOT_BE_DEFINED_STRLESS
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_STRLESS is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_STRLESS is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_STRLESS
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_STRLESS is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_STRLESS is defined.");
+#endif
+
+#ifdef SHOULD_NOT_BE_DEFINED_STRLESS2
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_STRLESS2 is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_STRLESS2 is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_STRLESS2
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_STRLESS2 is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_STRLESS2 is defined.");
+#endif
+
+#ifdef SHOULD_NOT_BE_DEFINED_STRGREATER
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_STRGREATER is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_STRGREATER is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_STRGREATER
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_STRGREATER is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_STRGREATER is defined.");
+#endif
+
+#ifdef SHOULD_NOT_BE_DEFINED_STRGREATER2
+ cmFailed("IF or SET is broken, SHOULD_NOT_BE_DEFINED_STRGREATER2 is defined.");
+#else
+ cmPassed("SHOULD_NOT_BE_DEFINED_STRGREATER2 is not defined.");
+#endif
+
+#ifndef SHOULD_BE_DEFINED_STRGREATER2
+ cmFailed("IF or SET is broken, SHOULD_BE_DEFINED_STRGREATER2 is not defined.\n");
+#else
+ cmPassed("SHOULD_BE_DEFINED_STRGREATER2 is defined.");
+#endif
+
+ // ----------------------------------------------------------------------
+ // Test FOREACH
+
+#ifndef FOREACH_VAR1
+ cmFailed("the FOREACH, SET or CONFIGURE_FILE command is broken, "
+ "FOREACH_VAR1 is not defined.");
+#else
+ if(strcmp(FOREACH_VAR1, "VALUE1") != 0)
+ {
+ cmFailed("the FOREACH, SET or CONFIGURE_FILE command is broken, "
+ "FOREACH_VAR1 == ", FOREACH_VAR1);
+ }
+ else
+ {
+ cmPassed("FOREACH_VAR1 == ", FOREACH_VAR1);
+ }
+#endif
+
+#ifndef FOREACH_VAR2
+ cmFailed("the FOREACH, SET or CONFIGURE_FILE command is broken, "
+ "FOREACH_VAR2 is not defined.");
+#else
+ if(strcmp(FOREACH_VAR2, "VALUE2") != 0)
+ {
+ cmFailed("the FOREACH, SET or CONFIGURE_FILE command is broken, "
+ "FOREACH_VAR2 == ", FOREACH_VAR2);
+ }
+ else
+ {
+ cmPassed("FOREACH_VAR2 == ", FOREACH_VAR2);
+ }
+#endif
+
+#ifndef FOREACH_CONCAT
+ cmFailed("the FOREACH, SET or CONFIGURE_FILE command is broken, "
+ "FOREACH_CONCAT is not defined.");
+#else
+ if(strcmp(FOREACH_CONCAT, "abcdefg") != 0)
+ {
+ cmFailed("the FOREACH, SET or CONFIGURE_FILE command is broken, "
+ "FOREACH_CONCAT == ", FOREACH_CONCAT);
+ }
+ else
+ {
+ cmPassed("FOREACH_CONCAT == ", FOREACH_CONCAT);
+ }
+#endif
+
+ // ----------------------------------------------------------------------
+ // Test WHILE
+
+ if(WHILE_VALUE != 1000)
+ {
+ cmFailed("WHILE command is not working");
+ }
+ else
+ {
+ cmPassed("WHILE command is working");
+ }
+
+ // ----------------------------------------------------------------------
+ // Test FIND_FILE, FIND_PATH and various GET_FILENAME_COMPONENT combinations
+
+#ifndef FILENAME_VAR_PATH_NAME
+ cmFailed("the FIND_FILE or GET_FILENAME_COMPONENT command is broken, "
+ "FILENAME_VAR_PATH_NAME is not defined.");
+#else
+ if((strcmp(FILENAME_VAR_PATH_NAME, "Complex") == 0) ||
+ (strcmp(FILENAME_VAR_PATH_NAME, "ComplexOneConfig") == 0))
+ {
+ cmPassed("FILENAME_VAR_PATH_NAME == ", FILENAME_VAR_PATH_NAME);
+ }
+ else
+ {
+ cmFailed("the FIND_FILE or GET_FILENAME_COMPONENT command is broken, "
+ "FILENAME_VAR_PATH_NAME == ", FILENAME_VAR_PATH_NAME);
+ }
+#endif
+
+#ifndef FILENAME_VAR_NAME
+ cmFailed("the FIND_FILE or GET_FILENAME_COMPONENT command is broken, "
+ "FILENAME_VAR_NAME is not defined.");
+#else
+ if(strcmp(FILENAME_VAR_NAME, "VarTests.cmake") != 0)
+ {
+ cmFailed("the FIND_FILE or GET_FILENAME_COMPONENT command is broken, "
+ "FILENAME_VAR_NAME == ", FILENAME_VAR_NAME);
+ }
+ else
+ {
+ cmPassed("FILENAME_VAR_NAME == ", FILENAME_VAR_NAME);
+ }
+#endif
+
+#ifndef FILENAME_VAR_EXT
+ cmFailed("the FIND_FILE or GET_FILENAME_COMPONENT command is broken, "
+ "FILENAME_VAR_EXT is not defined.");
+#else
+ if(strcmp(FILENAME_VAR_EXT, ".cmake") != 0)
+ {
+ cmFailed("the FIND_FILE or GET_FILENAME_COMPONENT command is broken, "
+ "FILENAME_VAR_EXT == ", FILENAME_VAR_EXT);
+ }
+ else
+ {
+ cmPassed("FILENAME_VAR_EXT == ", FILENAME_VAR_EXT);
+ }
+#endif
+
+#ifndef FILENAME_VAR_NAME_WE
+ cmFailed("the FIND_FILE or GET_FILENAME_COMPONENT command is broken, "
+ "FILENAME_VAR_NAME_WE is not defined.");
+#else
+ if(strcmp(FILENAME_VAR_NAME_WE, "VarTests") != 0)
+ {
+ cmFailed("the FIND_FILE or GET_FILENAME_COMPONENT command is broken, "
+ "FILENAME_VAR_NAME_WE == ", FILENAME_VAR_NAME_WE);
+ }
+ else
+ {
+ cmPassed("FILENAME_VAR_NAME_WE == ", FILENAME_VAR_NAME_WE);
+ }
+#endif
+
+#ifndef PATH_VAR_NAME
+ cmFailed("the FIND_FILE or GET_FILENAME_COMPONENT command is broken, "
+ "PATH_VAR_NAME is not defined.");
+#else
+ if((strcmp(PATH_VAR_NAME, "Complex") == 0) ||
+ (strcmp(PATH_VAR_NAME, "ComplexOneConfig") == 0))
+ {
+ cmPassed("PATH_VAR_NAME == ", PATH_VAR_NAME);
+ }
+ else
+ {
+ cmFailed("the FIND_FILE or GET_FILENAME_COMPONENT command is broken, "
+ "PATH_VAR_NAME == ", PATH_VAR_NAME);
+ }
+#endif
+
+ // ----------------------------------------------------------------------
+ // Test LOAD_CACHE
+
+#ifndef CACHE_TEST_VAR1
+ cmFailed("the LOAD_CACHE or CONFIGURE_FILE command is broken, "
+ "CACHE_TEST_VAR1 is not defined.");
+#else
+ if(strcmp(CACHE_TEST_VAR1, "foo") != 0)
+ {
+ cmFailed("the LOAD_CACHE or CONFIGURE_FILE command is broken, "
+ "CACHE_TEST_VAR1 == ", CACHE_TEST_VAR1);
+ }
+ else
+ {
+ cmPassed("CACHE_TEST_VAR1 == ", CACHE_TEST_VAR1);
+ }
+#endif
+
+#ifndef CACHE_TEST_VAR2
+ cmFailed("the LOAD_CACHE or CONFIGURE_FILE command is broken, "
+ "CACHE_TEST_VAR2 is not defined.");
+#else
+ if(strcmp(CACHE_TEST_VAR2, "bar") != 0)
+ {
+ cmFailed("the LOAD_CACHE or CONFIGURE_FILE command is broken, "
+ "CACHE_TEST_VAR2 == ", CACHE_TEST_VAR2);
+ }
+ else
+ {
+ cmPassed("CACHE_TEST_VAR2 == ", CACHE_TEST_VAR2);
+ }
+#endif
+
+#ifndef CACHE_TEST_VAR3
+ cmFailed("the LOAD_CACHE or CONFIGURE_FILE command is broken, "
+ "CACHE_TEST_VAR3 is not defined.");
+#else
+ if(strcmp(CACHE_TEST_VAR3, "1") != 0)
+ {
+ cmFailed("the LOAD_CACHE or CONFIGURE_FILE command is broken, "
+ "CACHE_TEST_VAR3 == ", CACHE_TEST_VAR3);
+ }
+ else
+ {
+ cmPassed("CACHE_TEST_VAR3 == ", CACHE_TEST_VAR3);
+ }
+#endif
+
+#ifdef CACHE_TEST_VAR_EXCLUDED
+ cmFailed("the LOAD_CACHE or CONFIGURE_FILE command or cmakedefine is broken, "
+ "CACHE_TEST_VAR_EXCLUDED is defined (should not have been loaded).");
+#else
+ cmPassed("CACHE_TEST_VAR_EXCLUDED is not defined.");
+#endif
+
+#ifndef CACHE_TEST_VAR_INTERNAL
+ cmFailed("the LOAD_CACHE or CONFIGURE_FILE command is broken, "
+ "CACHE_TEST_VAR_INTERNAL is not defined.");
+#else
+ std::string cachetest = CACHE_TEST_VAR_INTERNAL;
+ if(cachetest != "bar")
+ {
+ cmFailed("the LOAD_CACHE or CONFIGURE_FILE command is broken, "
+ "CACHE_TEST_VAR_INTERNAL == ", CACHE_TEST_VAR_INTERNAL);
+ }
+ else
+ {
+ cmPassed("CACHE_TEST_VAR_INTERNAL == ", CACHE_TEST_VAR_INTERNAL);
+ }
+#endif
+
+ // ----------------------------------------------------------------------
+ // Some pre-build/pre-link/post-build custom-commands have been
+ // attached to the lib (see Library/).
+ // Each runs ${CREATE_FILE_EXE} which will create a file.
+ // It also copies that file again using cmake -E.
+ // Similar rules have been added to this executable.
+ //
+ // WARNING: if you run 'complex' manually, this *will* fail, because
+ // 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");
+
+ // ----------------------------------------------------------------------
+ // A custom target has been created (see Library/).
+ // It runs ${CREATE_FILE_EXE} which will create a file.
+ //
+ // WARNING: if you run 'complex' manually, this *will* fail, because
+ // 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");
+
+ // ----------------------------------------------------------------------
+ // A directory has been created.
+
+ TestDir(BINARY_DIR "/make_dir");
+
+ // ----------------------------------------------------------------------
+ // Test OUTPUT_REQUIRED_FILES
+ // The files required by 'complex' have been output to a file.
+ // The contents of this file is not tested (absolute paths).
+ //
+ // WARNING: if you run 'complex' manually, this *will* fail, because
+ // 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");
+
+ // ----------------------------------------------------------------------
+ // Test FIND_LIBRARY
+
+#ifndef FIND_DUMMY_LIB
+ cmFailed("the CONFIGURE_FILE command is broken, "
+ "FIND_DUMMY_LIB is not defined.");
+#else
+ if(strstr(FIND_DUMMY_LIB, "dummylib") == NULL)
+ {
+ cmFailed("the FIND_LIBRARY or CONFIGURE_FILE command is broken, "
+ "FIND_DUMMY_LIB == ", FIND_DUMMY_LIB);
+ }
+ else
+ {
+ cmPassed("FIND_DUMMY_LIB == ", FIND_DUMMY_LIB);
+ }
+#endif
+
+ // ----------------------------------------------------------------------
+ // Test SET_SOURCE_FILES_PROPERTIES
+
+#ifndef FILE_HAS_EXTRA_COMPILE_FLAGS
+ cmFailed("SET_SOURCE_FILES_PROPERTIES failed at setting FILE_HAS_EXTRA_COMPILE_FLAGS flag");
+#else
+ cmPassed("SET_SOURCE_FILES_PROPERTIES succeeded in setting FILE_HAS_EXTRA_COMPILE_FLAGS flag");
+#endif
+
+#if 0 // Disable until implemented everywhere.
+#ifndef FILE_DEFINE_STRING
+ cmFailed("SET_SOURCE_FILES_PROPERTIES failed at setting FILE_DEFINE_STRING flag");
+#else
+ if(strcmp(FILE_DEFINE_STRING, "hello") != 0)
+ {
+ cmFailed("SET_SOURCE_FILES_PROPERTIES failed at setting FILE_DEFINE_STRING flag correctly");
+ }
+ else
+ {
+ cmPassed("SET_SOURCE_FILES_PROPERTIES succeeded in setting FILE_DEFINE_STRING flag");
+ }
+#endif
+#endif
+
+#ifndef FILE_HAS_ABSTRACT
+ cmFailed("SET_SOURCE_FILES_PROPERTIES failed at setting ABSTRACT flag");
+#else
+ cmPassed("SET_SOURCE_FILES_PROPERTIES succeeded in setting ABSTRACT flag");
+#endif
+
+#ifndef FILE_HAS_WRAP_EXCLUDE
+ cmFailed("FILE_HAS_WRAP_EXCLUDE failed at setting WRAP_EXCLUDE flag");
+#else
+ cmPassed("FILE_HAS_WRAP_EXCLUDE succeeded in setting WRAP_EXCLUDE flag");
+#endif
+
+#ifndef FILE_COMPILE_FLAGS
+ cmFailed("the CONFIGURE_FILE command is broken, FILE_COMPILE_FLAGS is not defined.");
+#else
+ if(strcmp(FILE_COMPILE_FLAGS, "-foo -bar") != 0)
+ {
+ cmFailed("the SET_SOURCE_FILES_PROPERTIES or CONFIGURE_FILE command is broken. FILE_COMPILE_FLAGS == ",
+ FILE_COMPILE_FLAGS);
+ }
+ else
+ {
+ cmPassed("SET_SOURCE_FILES_PROPERTIES succeeded in setting extra flags == ", FILE_COMPILE_FLAGS);
+ }
+#endif
+
+ // ----------------------------------------------------------------------
+ // Test registry (win32)
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#ifndef REGISTRY_TEST_PATH
+ cmFailed("the CONFIGURE_FILE command is broken, REGISTRY_TEST_PATH is not defined.");
+#else
+ std::cout << "REGISTRY_TEST_PATH == " << REGISTRY_TEST_PATH << "\n";
+ if(stricmp(REGISTRY_TEST_PATH, BINARY_DIR "/registry_dir") != 0)
+ {
+ cmFailed("the 'read registry value' function or CONFIGURE_FILE command is broken. REGISTRY_TEST_PATH == ",
+ REGISTRY_TEST_PATH, " is not " BINARY_DIR "/registry_dir");
+ }
+ else
+ {
+ cmPassed("REGISTRY_TEST_PATH == ", REGISTRY_TEST_PATH);
+ }
+#endif
+#endif // defined(_WIN32) && !defined(__CYGWIN__)
+
+ if(strcmp(CMAKE_MINIMUM_REQUIRED_VERSION, "1.3") == 0)
+ {
+ cmPassed("CMAKE_MINIMUM_REQUIRED_VERSION is set to 1.3");
+ }
+ else
+ {
+ cmFailed("CMAKE_MINIMUM_REQUIRED_VERSION is not set to the expected 1.3");
+ }
+
+ // ----------------------------------------------------------------------
+ // Test REMOVE command
+ if (strcmp("a;b;d",REMOVE_STRING) == 0)
+ {
+ cmPassed("REMOVE is working");
+ }
+ else
+ {
+ cmFailed("REMOVE is not working");
+ }
+
+ // ----------------------------------------------------------------------
+ // Test SEPARATE_ARGUMENTS
+ if(strcmp("a;b;c", TEST_SEP) == 0)
+ {
+ cmPassed("SEPARATE_ARGUMENTS is working");
+ }
+ else
+ {
+ cmFailed("SEPARATE_ARGUMENTS is not working");
+ }
+
+ // ----------------------------------------------------------------------
+ // Test Escape Quotes
+ if(strcmp("\"hello world\"", STRING_WITH_QUOTES) == 0)
+ {
+ cmPassed("ESCAPE_QUOTES is working");
+ }
+ else
+ {
+ cmFailed("ESCAPE_QUOTES is not working");
+ }
+
+
+ // ----------------------------------------------------------------------
+ // Test if IF command inside a FOREACH works.
+#if defined(IF_INSIDE_FOREACH_THEN_EXECUTED) && !defined(IF_INSIDE_FOREACH_ELSE_EXECUTED)
+ cmPassed("IF inside a FOREACH block works");
+#else
+ cmFailed("IF inside a FOREACH block is broken");
+#endif
+
+#if defined(GENERATED_HEADER_INCLUDED)
+ cmPassed("Generated header included by non-generated source works.");
+#else
+ cmFailed("Generated header included by non-generated source failed.");
+#endif
+ if(SHOULD_BE_ZERO == 0)
+ {
+ cmPassed("cmakedefine01 is working for 0");
+ }
+ else
+ {
+ cmFailed("cmakedefine01 is not working for 0");
+ }
+ if(SHOULD_BE_ONE == 1)
+ {
+ cmPassed("cmakedefine01 is working for 1");
+ }
+ else
+ {
+ cmFailed("cmakedefine01 is not working for 1");
+ }
+#ifdef FORCE_TEST
+ cmFailed("CMake SET CACHE FORCE");
+#else
+ cmPassed("CMake SET CACHE FORCE");
+#endif
+
+#ifdef COMPLEX_TEST_LINK_STATIC
+ if(TestLinkGetType())
+ {
+ cmPassed("Link to static over shared worked.");
+ }
+ else
+ {
+ cmFailed("Link to static over shared failed.");
+ }
+#endif
+
+#if defined(A_VALUE) && A_VALUE == 10
+ cmPassed("Single-character executable A worked.");
+#else
+ cmFailed("Single-character executable A failed.");
+#endif
+
+ // ----------------------------------------------------------------------
+ // Summary
+
+ std::cout << "Passed: " << cm_passed << "\n";
+ if(cm_failed)
+ {
+ std::cout << "Failed: " << cm_failed << "\n";
+ return cm_failed;
+ }
+ return 0;
+}
diff --git a/Tests/ComplexOneConfig/Executable/complex.file.cxx b/Tests/ComplexOneConfig/Executable/complex.file.cxx
new file mode 100644
index 000000000..e873fa644
--- /dev/null
+++ b/Tests/ComplexOneConfig/Executable/complex.file.cxx
@@ -0,0 +1,8 @@
+#if 0
+#include "cmMissingHeader.h"
+#endif
+
+int main(int , char**)
+{
+ return 0;
+}
diff --git a/Tests/ComplexOneConfig/Executable/complex_nobuild.c b/Tests/ComplexOneConfig/Executable/complex_nobuild.c
new file mode 100644
index 000000000..6b3c2c1e2
--- /dev/null
+++ b/Tests/ComplexOneConfig/Executable/complex_nobuild.c
@@ -0,0 +1 @@
+#error "This file should not be compiled."
diff --git a/Tests/ComplexOneConfig/Executable/complex_nobuild.cxx b/Tests/ComplexOneConfig/Executable/complex_nobuild.cxx
new file mode 100644
index 000000000..6b3c2c1e2
--- /dev/null
+++ b/Tests/ComplexOneConfig/Executable/complex_nobuild.cxx
@@ -0,0 +1 @@
+#error "This file should not be compiled."
diff --git a/Tests/ComplexOneConfig/Executable/notInAllExe.cxx b/Tests/ComplexOneConfig/Executable/notInAllExe.cxx
new file mode 100644
index 000000000..70275cd51
--- /dev/null
+++ b/Tests/ComplexOneConfig/Executable/notInAllExe.cxx
@@ -0,0 +1,10 @@
+extern int notInAllLibFunc();
+
+int main()
+{
+ return notInAllLibFunc();
+}
+
+#if 1
+# error "This target should not be compiled by ALL."
+#endif
diff --git a/Tests/ComplexOneConfig/Executable/testSystemDir.cxx b/Tests/ComplexOneConfig/Executable/testSystemDir.cxx
new file mode 100644
index 000000000..e4815c679
--- /dev/null
+++ b/Tests/ComplexOneConfig/Executable/testSystemDir.cxx
@@ -0,0 +1,3 @@
+#include <testSystemDir.h>
+
+int main() { return foo(); }
diff --git a/Tests/ComplexOneConfig/Executable/testcflags.c b/Tests/ComplexOneConfig/Executable/testcflags.c
new file mode 100644
index 000000000..f4d584844
--- /dev/null
+++ b/Tests/ComplexOneConfig/Executable/testcflags.c
@@ -0,0 +1,26 @@
+#include <string.h>
+
+int TestTargetCompileFlags(char* m)
+{
+#ifndef COMPLEX_TARGET_FLAG
+ strcpy(m, "CMAKE SET_TARGET_PROPERTIES COMPILE_FLAGS did not work");
+ return 0;
+#endif
+ strcpy(m, "CMAKE SET_TARGET_PROPERTIES COMPILE_FLAGS worked");
+ return 1;
+}
+
+int TestCFlags(char* m)
+{
+ /* TEST_CXX_FLAGS should not be defined in a c file */
+#ifdef TEST_CXX_FLAGS
+ strcpy(m, "CMake CMAKE_CXX_FLAGS (TEST_CXX_FLAGS) found in c file.");
+ return 0;
+#endif
+ /* TEST_C_FLAGS should be defined in a c file */
+#ifndef TEST_C_FLAGS
+ strcpy(m, "CMake CMAKE_C_FLAGS (TEST_C_FLAGS) not found in c file.");
+ return 0;
+#endif
+ return 1;
+}
diff --git a/Tests/ComplexOneConfig/Library/CMakeLists.txt b/Tests/ComplexOneConfig/Library/CMakeLists.txt
new file mode 100644
index 000000000..c8efc3022
--- /dev/null
+++ b/Tests/ComplexOneConfig/Library/CMakeLists.txt
@@ -0,0 +1,140 @@
+REMOVE_DEFINITIONS(-DCMAKE_IS_REALLY_FUN)
+
+#
+# Small utility used to create file
+# UTILITY_SOURCE is used for coverage and for getting the exact name
+# of the executable.
+#
+UTILITY_SOURCE(CREATE_FILE_EXE create_file "." create_file.cxx)
+ADD_EXECUTABLE(create_file create_file.cxx)
+SET_TARGET_PROPERTIES(create_file PROPERTIES RUNTIME_OUTPUT_DIRECTORY ".")
+
+#
+# Create static library
+# SOURCE_FILES_REMOVE is used for Coverage. empty.h is included for coverage
+#
+AUX_SOURCE_DIRECTORY(ExtraSources LibrarySources)
+SET(LibrarySources ${LibrarySources}
+ file2
+ empty
+ create_file.cxx
+ GENERATED
+ nonexisting_file)
+REMOVE(LibrarySources create_file.cxx GENERATED nonexisting_file)
+ADD_LIBRARY(CMakeTestLibrary ${LibrarySources})
+
+IF(WIN32)
+ IF(NOT CYGWIN)
+ IF(NOT BORLAND)
+ IF(NOT MINGW)
+ TARGET_LINK_LIBRARIES(CMakeTestLibrary
+ debug
+ user32.lib)
+ TARGET_LINK_LIBRARIES(CMakeTestLibrary
+ optimized
+ kernel32.lib)
+ ENDIF(NOT MINGW)
+ ENDIF(NOT BORLAND)
+ ENDIF(NOT CYGWIN)
+ENDIF(WIN32)
+
+#
+# Create shared library
+#
+SET(SharedLibrarySources sharedFile)
+ADD_LIBRARY(CMakeTestLibraryShared SHARED ${SharedLibrarySources})
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DTEST_C_FLAGS")
+ADD_LIBRARY(CMakeTestCLibraryShared SHARED testConly.c)
+DEFINE_PROPERTY(
+ TARGET PROPERTY FOO
+ BRIEF_DOCS "a test 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.
+ SET_TARGET_PROPERTIES(CMakeTestCLibraryShared PROPERTIES LINK_FLAGS "-lm")
+ENDIF(NOT BEOS AND NOT WIN32)
+GET_TARGET_PROPERTY(FOO_BAR_VAR CMakeTestCLibraryShared FOO)
+IF(${FOO_BAR_VAR} MATCHES "BAR")
+ELSE(${FOO_BAR_VAR} MATCHES "BAR")
+ MESSAGE(SEND_ERROR "SET_TARGET_PROPERTIES or GET_TARGET_PROPERTY failed, FOO_BAR_VAR should be BAR, but is ${FOO_BAR_VAR}")
+ENDIF(${FOO_BAR_VAR} MATCHES "BAR")
+
+# Create static and shared lib of same name.
+IF(CMAKE_EXE_LINK_STATIC_CXX_FLAGS)
+ ADD_LIBRARY(CMakeTestLinkStatic STATIC TestLink.c)
+ ADD_LIBRARY(CMakeTestLinkShared SHARED TestLink.c)
+ SET_TARGET_PROPERTIES(CMakeTestLinkStatic CMakeTestLinkShared
+ PROPERTIES OUTPUT_NAME CMakeTestLink)
+ENDIF(CMAKE_EXE_LINK_STATIC_CXX_FLAGS)
+
+#
+# Attach pre-build/pre-link/post-build custom-commands to the lib.
+# Each runs ${CREATE_FILE_EXE} which will create a file.
+# The 'complex' executable will then test if this file exists and remove it.
+#
+ADD_DEPENDENCIES(CMakeTestLibraryShared create_file)
+MESSAGE("complex bin dir is ${Complex_BINARY_DIR}")
+ADD_CUSTOM_COMMAND(TARGET CMakeTestLibraryShared PRE_BUILD
+ COMMAND ${CREATE_FILE_EXE}
+ ARGS "${Complex_BINARY_DIR}/Library/prebuild.txt")
+ADD_CUSTOM_COMMAND(TARGET CMakeTestLibraryShared PRE_BUILD
+ COMMAND ${CREATE_FILE_EXE}
+ ARGS "${Complex_BINARY_DIR}/Library/prelink.txt")
+ADD_CUSTOM_COMMAND(TARGET CMakeTestLibraryShared POST_BUILD
+ COMMAND ${CREATE_FILE_EXE}
+ ARGS "${Complex_BINARY_DIR}/Library/postbuild.txt")
+ADD_CUSTOM_COMMAND(TARGET CMakeTestLibraryShared POST_BUILD
+ COMMAND ${CMAKE_COMMAND}
+ ARGS -E copy
+ "${Complex_BINARY_DIR}/Library/postbuild.txt"
+ "${Complex_BINARY_DIR}/Library/postbuild2.txt")
+
+#
+# Add a custom target.
+# It runs ${CREATE_FILE_EXE} which will create a file.
+# The 'complex' executable will then test if this file exists and remove it.
+#
+ADD_CUSTOM_TARGET(custom_target1
+ ALL
+ ${CREATE_FILE_EXE}
+ "${Complex_BINARY_DIR}/Library/custom_target1.txt")
+
+ADD_DEPENDENCIES(custom_target1 create_file)
+
+#
+# Extra coverage
+#
+SET_SOURCE_FILES_PROPERTIES(file2 PROPERTIES ABSTRACT 1)
+
+INSTALL_FILES(/tmp .h ${Complex_BINARY_DIR}/cmTestConfigure.h)
+INSTALL_FILES(/tmp .cxx ${Complex_BINARY_DIR}/cmTestConfigure.h)
+
+# Test creating a library that is not built by default.
+ADD_LIBRARY(notInAllLib EXCLUDE_FROM_ALL notInAllLib.cxx)
+
+# Create an imported target for if(TARGET) test in Executable dir.
+# That test should not see this target.
+ADD_LIBRARY(LibImportedTarget UNKNOWN IMPORTED)
+
+# Test generation of preprocessed sources.
+IF("${CMAKE_GENERATOR}" MATCHES "Makefile" AND CMAKE_MAKE_PROGRAM)
+ IF(CMAKE_CXX_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(ARCH_COUNT GREATER 1)
+
+ # Custom target to try preprocessing invocation.
+ ADD_CUSTOM_TARGET(test_preprocess ${MAYBE_ALL}
+ COMMAND ${CMAKE_COMMAND} -E remove CMakeFiles/create_file.dir/create_file.i
+ COMMAND ${CMAKE_MAKE_PROGRAM} create_file.i
+ COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/test_preprocess.cmake
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ )
+ ENDIF(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE)
+ENDIF("${CMAKE_GENERATOR}" MATCHES "Makefile" AND CMAKE_MAKE_PROGRAM)
diff --git a/Tests/ComplexOneConfig/Library/ExtraSources/file1.cxx b/Tests/ComplexOneConfig/Library/ExtraSources/file1.cxx
new file mode 100644
index 000000000..e22812e51
--- /dev/null
+++ b/Tests/ComplexOneConfig/Library/ExtraSources/file1.cxx
@@ -0,0 +1,4 @@
+int file1()
+{
+ return 1;
+}
diff --git a/Tests/ComplexOneConfig/Library/ExtraSources/file1.h b/Tests/ComplexOneConfig/Library/ExtraSources/file1.h
new file mode 100644
index 000000000..ce0d818a3
--- /dev/null
+++ b/Tests/ComplexOneConfig/Library/ExtraSources/file1.h
@@ -0,0 +1 @@
+int file1();
diff --git a/Tests/ComplexOneConfig/Library/SystemDir/testSystemDir.h b/Tests/ComplexOneConfig/Library/SystemDir/testSystemDir.h
new file mode 100644
index 000000000..73be3538e
--- /dev/null
+++ b/Tests/ComplexOneConfig/Library/SystemDir/testSystemDir.h
@@ -0,0 +1,2 @@
+// Purposely leave off the return type to create a warning.
+foo() { return 0; }
diff --git a/Tests/ComplexOneConfig/Library/TestLink.c b/Tests/ComplexOneConfig/Library/TestLink.c
new file mode 100644
index 000000000..25dee082f
--- /dev/null
+++ b/Tests/ComplexOneConfig/Library/TestLink.c
@@ -0,0 +1,8 @@
+int TestLinkGetType()
+{
+#ifdef CMakeTestLinkShared_EXPORTS
+ return 0;
+#else
+ return 1;
+#endif
+}
diff --git a/Tests/ComplexOneConfig/Library/create_file.cxx b/Tests/ComplexOneConfig/Library/create_file.cxx
new file mode 100644
index 000000000..d41551980
--- /dev/null
+++ b/Tests/ComplexOneConfig/Library/create_file.cxx
@@ -0,0 +1,28 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+int main (int argc, char *argv[])
+{
+ if (argc < 2)
+ {
+ fprintf(stderr, "Missing name of file to create.\n");
+ return EXIT_FAILURE;
+ }
+
+ FILE *stream = fopen(argv[1], "w");
+ if(stream == NULL)
+ {
+ fprintf(stderr, "Unable to open %s for writing!\n", argv[1]);
+ return EXIT_FAILURE;
+ }
+
+ if(fclose(stream))
+ {
+ fprintf(stderr, "Unable to close %s!\n", argv[1]);
+ return EXIT_FAILURE;
+ }
+
+ fprintf(stdout, ">> Creating %s!\n", argv[1]);
+
+ return EXIT_SUCCESS;
+}
diff --git a/Tests/ComplexOneConfig/Library/dummy b/Tests/ComplexOneConfig/Library/dummy
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/ComplexOneConfig/Library/dummy
diff --git a/Tests/ComplexOneConfig/Library/empty.h b/Tests/ComplexOneConfig/Library/empty.h
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/ComplexOneConfig/Library/empty.h
diff --git a/Tests/ComplexOneConfig/Library/file2.cxx b/Tests/ComplexOneConfig/Library/file2.cxx
new file mode 100644
index 000000000..863fcaa51
--- /dev/null
+++ b/Tests/ComplexOneConfig/Library/file2.cxx
@@ -0,0 +1,10 @@
+#include <string.h>
+
+#ifdef CMAKE_IS_REALLY_FUN
+This is a problem. Looks like REMOVE_DEFINITION does not work
+#endif
+
+int file2()
+{
+ return 1;
+}
diff --git a/Tests/ComplexOneConfig/Library/file2.h b/Tests/ComplexOneConfig/Library/file2.h
new file mode 100644
index 000000000..dea4b80b1
--- /dev/null
+++ b/Tests/ComplexOneConfig/Library/file2.h
@@ -0,0 +1 @@
+int file2();
diff --git a/Tests/ComplexOneConfig/Library/notInAllLib.cxx b/Tests/ComplexOneConfig/Library/notInAllLib.cxx
new file mode 100644
index 000000000..5d928f44a
--- /dev/null
+++ b/Tests/ComplexOneConfig/Library/notInAllLib.cxx
@@ -0,0 +1,5 @@
+int notInAllLibFunc() { return 0; }
+
+#if 1
+# error "This target should not be compiled by ALL."
+#endif
diff --git a/Tests/ComplexOneConfig/Library/sharedFile.cxx b/Tests/ComplexOneConfig/Library/sharedFile.cxx
new file mode 100644
index 000000000..cafac68f4
--- /dev/null
+++ b/Tests/ComplexOneConfig/Library/sharedFile.cxx
@@ -0,0 +1,6 @@
+#include "sharedFile.h"
+
+int sharedFunction()
+{
+ return 1;
+}
diff --git a/Tests/ComplexOneConfig/Library/sharedFile.h b/Tests/ComplexOneConfig/Library/sharedFile.h
new file mode 100644
index 000000000..65ac2e2ba
--- /dev/null
+++ b/Tests/ComplexOneConfig/Library/sharedFile.h
@@ -0,0 +1,12 @@
+#if defined(_WIN32) || defined(WIN32) /* Win32 version */
+#ifdef CMakeTestLibraryShared_EXPORTS
+# define CMakeTest_EXPORT __declspec(dllexport)
+#else
+# define CMakeTest_EXPORT __declspec(dllimport)
+#endif
+#else
+/* unix needs nothing */
+#define CMakeTest_EXPORT
+#endif
+
+CMakeTest_EXPORT int sharedFunction();
diff --git a/Tests/ComplexOneConfig/Library/testConly.c b/Tests/ComplexOneConfig/Library/testConly.c
new file mode 100644
index 000000000..2d83f778e
--- /dev/null
+++ b/Tests/ComplexOneConfig/Library/testConly.c
@@ -0,0 +1,13 @@
+#include "testConly.h"
+#include <stdio.h>
+
+int CsharedFunction()
+{
+#ifndef TEST_C_FLAGS
+ printf("TEST_C_FLAGS failed\n");
+ return 0;
+#else
+ printf("Passed: TEST_C_FLAGS passed\n");
+#endif
+ return 1;
+}
diff --git a/Tests/ComplexOneConfig/Library/testConly.h b/Tests/ComplexOneConfig/Library/testConly.h
new file mode 100644
index 000000000..f1470a8d7
--- /dev/null
+++ b/Tests/ComplexOneConfig/Library/testConly.h
@@ -0,0 +1,13 @@
+#if defined(_WIN32) || defined(WIN32) /* Win32 version */
+#ifdef CMakeTestCLibraryShared_EXPORTS
+# define CMakeTest_EXPORT __declspec(dllexport)
+#else
+# define CMakeTest_EXPORT __declspec(dllimport)
+#endif
+#else
+/* unix needs nothing */
+#define CMakeTest_EXPORT
+#endif
+
+CMakeTest_EXPORT int CsharedFunction();
+
diff --git a/Tests/ComplexOneConfig/Library/test_preprocess.cmake b/Tests/ComplexOneConfig/Library/test_preprocess.cmake
new file mode 100644
index 000000000..d2d9fc652
--- /dev/null
+++ b/Tests/ComplexOneConfig/Library/test_preprocess.cmake
@@ -0,0 +1,7 @@
+SET(TEST_FILE CMakeFiles/create_file.dir/create_file.i)
+FILE(READ ${TEST_FILE} CONTENTS)
+IF("${CONTENTS}" MATCHES "Unable to close")
+ MESSAGE(STATUS "${TEST_FILE} created successfully!")
+ELSE("${CONTENTS}" MATCHES "Unable to close")
+ MESSAGE(FATAL_ERROR "${TEST_FILE} creation failed!")
+ENDIF("${CONTENTS}" MATCHES "Unable to close")
diff --git a/Tests/ComplexOneConfig/VarTests.cmake b/Tests/ComplexOneConfig/VarTests.cmake
new file mode 100644
index 000000000..c146d1be0
--- /dev/null
+++ b/Tests/ComplexOneConfig/VarTests.cmake
@@ -0,0 +1,198 @@
+#
+# Test SET
+#
+SET (ZERO_VAR 0)
+SET (ZERO_VAR2 0)
+
+IF(ZERO_VAR)
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED)
+ELSE(ZERO_VAR)
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED)
+ENDIF(ZERO_VAR)
+
+SET(ONE_VAR 1)
+SET(ONE_VAR2 1)
+SET(STRING_VAR "CMake is great" CACHE STRING "test a cache variable")
+
+#
+# Test VARIABLE_REQUIRES
+#
+VARIABLE_REQUIRES(ONE_VAR
+ ONE_VAR_IS_DEFINED ONE_VAR)
+
+#
+# Test various IF/ELSE combinations
+#
+IF(NOT ZERO_VAR)
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_NOT)
+ELSE(NOT ZERO_VAR)
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_NOT)
+ENDIF(NOT ZERO_VAR)
+
+IF(NOT ONE_VAR)
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_NOT2)
+ELSE(NOT ONE_VAR)
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_NOT2)
+ENDIF(NOT ONE_VAR)
+
+IF(ONE_VAR AND ONE_VAR2)
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_AND)
+ELSE(ONE_VAR AND ONE_VAR2)
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_AND)
+ENDIF(ONE_VAR AND ONE_VAR2)
+
+IF(ONE_VAR AND ZERO_VAR)
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_AND2)
+ELSE(ONE_VAR AND ZERO_VAR)
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_AND2)
+ENDIF(ONE_VAR AND ZERO_VAR)
+
+IF(ZERO_VAR OR ONE_VAR2)
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_OR)
+ELSE(ZERO_VAR OR ONE_VAR2)
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_OR)
+ENDIF(ZERO_VAR OR ONE_VAR2)
+
+IF(ZERO_VAR OR ZERO_VAR2)
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_OR2)
+ELSE(ZERO_VAR OR ZERO_VAR2)
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_OR2)
+ENDIF(ZERO_VAR OR ZERO_VAR2)
+
+IF(STRING_VAR MATCHES "^CMake")
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_MATCHES)
+ELSE(STRING_VAR MATCHES "^CMake")
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_MATCHES)
+ENDIF(STRING_VAR MATCHES "^CMake")
+
+IF(STRING_VAR MATCHES "^foo")
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_MATCHES2)
+ELSE(STRING_VAR MATCHES "^foo")
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_MATCHES2)
+ENDIF(STRING_VAR MATCHES "^foo")
+
+IF(COMMAND "IF")
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_COMMAND)
+ELSE(COMMAND "IF")
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_COMMAND)
+ENDIF(COMMAND "IF")
+
+IF(COMMAND "ROQUEFORT")
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_COMMAND2)
+ELSE(COMMAND "ROQUEFORT")
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_COMMAND2)
+ENDIF(COMMAND "ROQUEFORT")
+
+IF (EXISTS ${Complex_SOURCE_DIR}/VarTests.cmake)
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_EXISTS)
+ELSE(EXISTS ${Complex_SOURCE_DIR}/VarTests.cmake)
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_EXISTS)
+ENDIF (EXISTS ${Complex_SOURCE_DIR}/VarTests.cmake)
+
+IF (EXISTS ${Complex_SOURCE_DIR}/roquefort.txt)
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_EXISTS2)
+ELSE(EXISTS ${Complex_SOURCE_DIR}/roquefort.txt)
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_EXISTS2)
+ENDIF (EXISTS ${Complex_SOURCE_DIR}/roquefort.txt)
+
+IF (IS_DIRECTORY ${Complex_SOURCE_DIR})
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_IS_DIRECTORY)
+ENDIF (IS_DIRECTORY ${Complex_SOURCE_DIR})
+
+IF (NOT IS_DIRECTORY ${Complex_SOURCE_DIR}/VarTests.cmake)
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_IS_DIRECTORY2)
+ENDIF (NOT IS_DIRECTORY ${Complex_SOURCE_DIR}/VarTests.cmake)
+
+SET (SNUM1_VAR "1")
+SET (SNUM2_VAR "2")
+SET (SNUM3_VAR "1")
+
+
+IF (SNUM1_VAR LESS SNUM2_VAR)
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_LESS)
+ELSE (SNUM1_VAR LESS SNUM2_VAR)
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_LESS)
+ENDIF (SNUM1_VAR LESS SNUM2_VAR)
+
+IF (SNUM2_VAR LESS SNUM1_VAR)
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_LESS2)
+ELSE (SNUM2_VAR LESS SNUM1_VAR)
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_LESS2)
+ENDIF (SNUM2_VAR LESS SNUM1_VAR)
+
+IF (SNUM2_VAR GREATER SNUM1_VAR)
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_GREATER)
+ELSE (SNUM2_VAR GREATER SNUM1_VAR)
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_GREATER)
+ENDIF (SNUM2_VAR GREATER SNUM1_VAR)
+
+IF (SNUM2_VAR EQUAL SNUM1_VAR)
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_EQUAL)
+ELSE (SNUM2_VAR EQUAL SNUM1_VAR)
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_EQUAL)
+ENDIF (SNUM2_VAR EQUAL SNUM1_VAR)
+
+IF (SNUM3_VAR EQUAL SNUM1_VAR)
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_EQUAL)
+ELSE (SNUM3_VAR EQUAL SNUM1_VAR)
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_EQUAL)
+ENDIF (SNUM3_VAR EQUAL SNUM1_VAR)
+
+IF (SNUM1_VAR GREATER SNUM2_VAR)
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_GREATER2)
+ELSE (SNUM1_VAR GREATER SNUM2_VAR)
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_GREATER2)
+ENDIF (SNUM1_VAR GREATER SNUM2_VAR)
+
+SET (SSTR1_VAR "abc")
+SET (SSTR2_VAR "bcd")
+
+IF (SSTR1_VAR STRLESS SSTR2_VAR)
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_STRLESS)
+ELSE (SSTR1_VAR STRLESS SSTR2_VAR)
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_STRLESS)
+ENDIF (SSTR1_VAR STRLESS SSTR2_VAR)
+
+IF (SSTR2_VAR STRLESS SSTR1_VAR)
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_STRLESS2)
+ELSE (SSTR2_VAR STRLESS SSTR1_VAR)
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_STRLESS2)
+ENDIF (SSTR2_VAR STRLESS SSTR1_VAR)
+
+IF (SSTR2_VAR STRGREATER SSTR1_VAR)
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_STRGREATER)
+ELSE (SSTR2_VAR STRGREATER SSTR1_VAR)
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_STRGREATER)
+ENDIF (SSTR2_VAR STRGREATER SSTR1_VAR)
+
+IF (SSTR1_VAR STRGREATER SSTR2_VAR)
+ ADD_DEFINITIONS(-DSHOULD_NOT_BE_DEFINED_STRGREATER2)
+ELSE (SSTR1_VAR STRGREATER SSTR2_VAR)
+ ADD_DEFINITIONS(-DSHOULD_BE_DEFINED_STRGREATER2)
+ENDIF (SSTR1_VAR STRGREATER SSTR2_VAR)
+
+#
+# Test FOREACH
+#
+FOREACH (INDEX 1 2)
+ SET(FOREACH_VAR${INDEX} "VALUE${INDEX}")
+ENDFOREACH(INDEX)
+
+SET(FOREACH_CONCAT "")
+FOREACH (INDEX a;b;c;d;e;f;g)
+ SET(FOREACH_CONCAT "${FOREACH_CONCAT}${INDEX}")
+ENDFOREACH(INDEX)
+
+#
+# Test FIND_FILE, FIND_PATH and various GET_FILENAME_COMPONENT combinations
+#
+FIND_FILE(FILENAME_VAR "VarTests.cmake" ${Complex_SOURCE_DIR})
+
+GET_FILENAME_COMPONENT(FILENAME_VAR_PATH ${FILENAME_VAR} PATH)
+GET_FILENAME_COMPONENT(FILENAME_VAR_PATH_NAME ${FILENAME_VAR_PATH} NAME)
+GET_FILENAME_COMPONENT(FILENAME_VAR_NAME ${FILENAME_VAR} NAME)
+GET_FILENAME_COMPONENT(FILENAME_VAR_EXT ${FILENAME_VAR} EXT)
+GET_FILENAME_COMPONENT(FILENAME_VAR_NAME_WE ${FILENAME_VAR} NAME_WE CACHE)
+
+FIND_PATH(PATH_VAR "cmTestConfigure.h.in" ${Complex_SOURCE_DIR})
+GET_FILENAME_COMPONENT(PATH_VAR_NAME ${PATH_VAR} NAME)
diff --git a/Tests/ComplexOneConfig/cmTestConfigure.h.in b/Tests/ComplexOneConfig/cmTestConfigure.h.in
new file mode 100644
index 000000000..7741b6fd5
--- /dev/null
+++ b/Tests/ComplexOneConfig/cmTestConfigure.h.in
@@ -0,0 +1,85 @@
+// Test SET, VARIABLE_REQUIRES
+
+#cmakedefine ONE_VAR
+#cmakedefine ONE_VAR_IS_DEFINED
+#cmakedefine ZERO_VAR
+
+#define STRING_VAR "${STRING_VAR}"
+
+// Test FOREACH
+
+#define FOREACH_VAR1 "${FOREACH_VAR1}"
+#define FOREACH_VAR2 "${FOREACH_VAR2}"
+#define FOREACH_CONCAT "${FOREACH_CONCAT}"
+
+// Test WHILE
+#define WHILE_VALUE ${while_var}
+
+// Test FIND_FILE, FIND_PATH and various GET_FILENAME_COMPONENT combinations
+
+#define FILENAME_VAR_PATH_NAME "${FILENAME_VAR_PATH_NAME}"
+#define FILENAME_VAR_NAME "${FILENAME_VAR_NAME}"
+#define FILENAME_VAR_EXT "${FILENAME_VAR_EXT}"
+#define FILENAME_VAR_NAME_WE "${FILENAME_VAR_NAME_WE}"
+
+#define PATH_VAR_NAME "${PATH_VAR_NAME}"
+
+// Test LOAD_CACHE
+
+#define CACHE_TEST_VAR1 "${CACHE_TEST_VAR1}"
+#define CACHE_TEST_VAR2 "${CACHE_TEST_VAR2}"
+#define CACHE_TEST_VAR3 "${CACHE_TEST_VAR3}"
+#cmakedefine CACHE_TEST_VAR_EXCLUDED
+#define CACHE_TEST_VAR_INTERNAL "${CACHE_TEST_VAR_INTERNAL}"
+
+// Test internal CMake vars from C++ flags
+
+#cmakedefine CMAKE_NO_STD_NAMESPACE
+#cmakedefine CMAKE_NO_ANSI_STREAM_HEADERS
+#cmakedefine CMAKE_NO_ANSI_STRING_STREAM
+#cmakedefine CMAKE_NO_ANSI_FOR_SCOPE
+
+#cmakedefine01 SHOULD_BE_ZERO
+#cmakedefine01 SHOULD_BE_ONE
+// Needed to check for files
+
+#define BINARY_DIR "${Complex_BINARY_DIR}"
+
+// Test FIND_LIBRARY
+
+#define FIND_DUMMY_LIB "${FIND_DUMMY_LIB}"
+
+// Test SET_SOURCE_FILES_PROPERTIES
+
+#cmakedefine FILE_HAS_ABSTRACT
+#cmakedefine FILE_HAS_WRAP_EXCLUDE
+#define FILE_COMPILE_FLAGS "${FILE_COMPILE_FLAGS}"
+
+#define TEST_SEP "${TEST_SEP}"
+
+// Test registry read
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#define REGISTRY_TEST_PATH "${REGISTRY_TEST_PATH}"
+#endif
+
+// Test Remove command
+#define REMOVE_STRING "${REMOVE_STRING}"
+
+// Test IF inside FOREACH
+#cmakedefine IF_INSIDE_FOREACH_THEN_EXECUTED
+#cmakedefine IF_INSIDE_FOREACH_ELSE_EXECUTED
+
+// Test SET CACHE FORCE
+#cmakedefine FORCE_TEST
+#define CMAKE_GENERATOR "${CMAKE_GENERATOR}"
+
+#define CMAKE_SHARED_MODULE_PREFIX "${CMAKE_SHARED_MODULE_PREFIX}"
+#define CMAKE_SHARED_MODULE_SUFFIX "${CMAKE_SHARED_MODULE_SUFFIX}"
+
+// test elseif
+#cmakedefine ELSEIF_RESULT
+
+// test parenthesis in conditionals
+#cmakedefine CONDITIONAL_PARENTHESES
+
diff --git a/Tests/ComplexOneConfig/cmTestConfigureEscape.h.in b/Tests/ComplexOneConfig/cmTestConfigureEscape.h.in
new file mode 100644
index 000000000..39a8bd627
--- /dev/null
+++ b/Tests/ComplexOneConfig/cmTestConfigureEscape.h.in
@@ -0,0 +1 @@
+#define STRING_WITH_QUOTES "${STRING_WITH_QUOTES}"
diff --git a/Tests/ComplexOneConfig/cmTestGeneratedHeader.h.in b/Tests/ComplexOneConfig/cmTestGeneratedHeader.h.in
new file mode 100644
index 000000000..0e9dd3ff3
--- /dev/null
+++ b/Tests/ComplexOneConfig/cmTestGeneratedHeader.h.in
@@ -0,0 +1 @@
+#define GENERATED_HEADER_INCLUDED
diff --git a/Tests/Contracts/Trilinos-10-6/CMakeLists.txt b/Tests/Contracts/Trilinos-10-6/CMakeLists.txt
new file mode 100644
index 000000000..79ed669a2
--- /dev/null
+++ b/Tests/Contracts/Trilinos-10-6/CMakeLists.txt
@@ -0,0 +1,103 @@
+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
new file mode 100644
index 000000000..cc2950232
--- /dev/null
+++ b/Tests/Contracts/Trilinos-10-6/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_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/EnvScript.cmake b/Tests/Contracts/Trilinos-10-6/EnvScript.cmake
new file mode 100644
index 000000000..dacb704f7
--- /dev/null
+++ b/Tests/Contracts/Trilinos-10-6/EnvScript.cmake
@@ -0,0 +1,32 @@
+# Site specific settings:
+#
+if(CTEST_SITE MATCHES "faraway")
+ set(CTEST_SITE "faraway.kitware")
+ set(ENV{CTEST_SITE} "${CTEST_SITE}")
+endif()
+
+if(CTEST_SITE STREQUAL "HUT11")
+ set(CTEST_SITE "hut11.kitware")
+ set(ENV{CTEST_SITE} "${CTEST_SITE}")
+
+ set(ENV{CLAPACK_DIR} "C:/T/clapack/b/clapack-prefix/src/clapack-build")
+endif()
+
+if(CTEST_SITE MATCHES "qwghlm")
+ set(CTEST_SITE "qwghlm.kitware")
+ set(ENV{CTEST_SITE} "${CTEST_SITE}")
+
+ set(ENV{PATH} "/opt/local/bin:$ENV{PATH}")
+ set(ENV{CC} "gcc-mp-4.3")
+ set(ENV{CXX} "g++-mp-4.3")
+ set(ENV{FC} "gfortran-mp-4.3")
+endif()
+
+# Submit to alternate CDash server:
+#
+#set(ENV{CTEST_DROP_SITE} "localhost")
+#set(ENV{CTEST_DROP_LOCATION} "/CDash/submit.php?project=Trilinos")
+
+# Limit packages built:
+#
+set(ENV{Trilinos_PACKAGES} "Teuchos;Kokkos")
diff --git a/Tests/Contracts/Trilinos-10-6/Patch.cmake b/Tests/Contracts/Trilinos-10-6/Patch.cmake
new file mode 100644
index 000000000..76051eb98
--- /dev/null
+++ b/Tests/Contracts/Trilinos-10-6/Patch.cmake
@@ -0,0 +1,38 @@
+if(NOT DEFINED source_dir)
+ message(FATAL_ERROR "variable 'source_dir' not defined")
+endif()
+
+
+if(NOT EXISTS "${source_dir}/CMakeLists.txt")
+ message(FATAL_ERROR "error: No CMakeLists.txt file to patch!")
+endif()
+
+set(text "
+
+#
+# Reference variables typically given as experimental_build_test configure
+# options to avoid CMake warnings about unused variables
+#
+
+MESSAGE(\"Trilinos_ALLOW_NO_PACKAGES='\${Trilinos_ALLOW_NO_PACKAGES}'\")
+MESSAGE(\"Trilinos_WARNINGS_AS_ERRORS_FLAGS='\${Trilinos_WARNINGS_AS_ERRORS_FLAGS}'\")
+")
+
+file(APPEND "${source_dir}/CMakeLists.txt" "${text}")
+
+
+if(NOT EXISTS "${source_dir}/CTestConfig.cmake")
+ message(FATAL_ERROR "error: No CTestConfig.cmake file to patch!")
+endif()
+
+set(text "
+
+#
+# Use newer than 10.6.1 CTestConfig settings from the Trilinos project.
+# Send the Trilinos dashboards to the new Trilinos CDash server instance.
+#
+SET(CTEST_NIGHTLY_START_TIME \"04:00:00 UTC\") # 10 PM MDT or 9 PM MST
+SET(CTEST_DROP_SITE \"testing.sandia.gov\")
+")
+
+file(APPEND "${source_dir}/CTestConfig.cmake" "${text}")
diff --git a/Tests/Contracts/Trilinos-10-6/RunTest.cmake b/Tests/Contracts/Trilinos-10-6/RunTest.cmake
new file mode 100644
index 000000000..30124d8e9
--- /dev/null
+++ b/Tests/Contracts/Trilinos-10-6/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-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
new file mode 100644
index 000000000..04bbf214e
--- /dev/null
+++ b/Tests/Contracts/Trilinos-10-6/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}/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/cse-snapshot/CMakeLists.txt b/Tests/Contracts/cse-snapshot/CMakeLists.txt
new file mode 100644
index 000000000..913421010
--- /dev/null
+++ b/Tests/Contracts/cse-snapshot/CMakeLists.txt
@@ -0,0 +1,114 @@
+cmake_minimum_required(VERSION 2.8)
+project(cse-snapshot)
+
+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()
+endif()
+message(STATUS "HOME='${HOME}'")
+
+if(NOT DEFINED repo)
+ set(repo "git://public.kitware.com/cse.git")
+endif()
+message(STATUS "repo='${repo}'")
+
+if(NOT DEFINED tag)
+ set(tag "cc1dcb95439a21ab1d58f444d93481598414196e")
+endif()
+message(STATUS "tag='${tag}'")
+
+string(SUBSTRING "${tag}" 0 8 shorttag)
+
+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}'")
+
+if(NOT DEFINED PROCESSOR_COUNT)
+ # Unknown:
+ set(PROCESSOR_COUNT 0)
+
+ # Linux:
+ set(cpuinfo_file "/proc/cpuinfo")
+ if(EXISTS "${cpuinfo_file}")
+ file(STRINGS "${cpuinfo_file}" procs REGEX "^processor.: [0-9]+$")
+ list(LENGTH procs PROCESSOR_COUNT)
+ endif()
+
+ # Mac:
+ if(APPLE)
+ find_program(cmd_sysctl "sysctl")
+ if(cmd_sysctl)
+ execute_process(COMMAND ${cmd_sysctl} -n hw.ncpu
+ OUTPUT_VARIABLE PROCESSOR_COUNT
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ endif()
+ endif()
+
+ # Windows:
+ if(WIN32)
+ set(PROCESSOR_COUNT "$ENV{NUMBER_OF_PROCESSORS}")
+ endif()
+endif()
+message(STATUS "PROCESSOR_COUNT='${PROCESSOR_COUNT}'")
+
+find_package(Git)
+if(NOT GIT_EXECUTABLE)
+ message(FATAL_ERROR "error: could not find git")
+ # adjust PATH to find git, or set GIT_EXECUTABLE in LocalOverrides.cmake
+endif()
+message(STATUS "GIT_EXECUTABLE='${GIT_EXECUTABLE}'")
+
+configure_file(
+ "${CMAKE_CURRENT_SOURCE_DIR}/Dashboard.cmake.in"
+ "${script_dir}/Dashboard.cmake"
+ @ONLY)
+
+# Source dir for this project exists outside the CMake build tree because it
+# is absolutely huge.
+#
+if(EXISTS "${source_dir}/.git")
+ # 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 clones the git repository:
+ ExternalProject_Add(download-${PROJECT_NAME}
+ SOURCE_DIR "${source_dir}"
+ GIT_REPOSITORY "${repo}"
+ GIT_TAG "${tag}"
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND ""
+ INSTALL_COMMAND ""
+ )
+endif()
+
+ExternalProject_Add(build-${PROJECT_NAME}
+ DOWNLOAD_COMMAND ""
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND ${CMAKE_CTEST_COMMAND} -S "${script_dir}/Dashboard.cmake"
+ INSTALL_COMMAND ""
+ DEPENDS download-${PROJECT_NAME}
+ )
diff --git a/Tests/Contracts/cse-snapshot/Dashboard.cmake.in b/Tests/Contracts/cse-snapshot/Dashboard.cmake.in
new file mode 100644
index 000000000..138eb3f81
--- /dev/null
+++ b/Tests/Contracts/cse-snapshot/Dashboard.cmake.in
@@ -0,0 +1,76 @@
+# This "ctest -S" script may be configured to drive a nightly dashboard on any
+# Linux machine.
+#
+set(CTEST_BINARY_DIRECTORY "@binary_dir@")
+set(CTEST_BUILD_NAME "@BUILDNAME@")
+set(CTEST_SITE "@SITE@")
+set(CTEST_SOURCE_DIRECTORY "@source_dir@")
+set(PROCESSOR_COUNT "@PROCESSOR_COUNT@")
+
+# Assume a Linux build, with a make that supports -j. Modify this script if
+# assumption is ever invalid.
+#
+if(PROCESSOR_COUNT)
+ set(CTEST_BUILD_FLAGS "-j${PROCESSOR_COUNT}")
+endif()
+
+set(CTEST_CMAKE_GENERATOR "Unix Makefiles")
+set(CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
+
+message("Cleaning binary dir '${CTEST_BINARY_DIRECTORY}'")
+ctest_empty_binary_directory("${CTEST_BINARY_DIRECTORY}")
+
+# Intentionally no ctest_update step in this script. This script is run as a
+# "Contract" test on a CMake dashboard submission using the just-built ctest
+# as the driver. The download step in the Contract CMakeLists file takes care
+# of setting up the source tree before calling this ctest -S script. The idea
+# is that the source tree will be the same every day, so there should not be
+# an "update" step for this build.
+
+message("Configuring CSE in binary dir '${CTEST_BINARY_DIRECTORY}'")
+set_property(GLOBAL PROPERTY SubProject "CSE-toplevel")
+set_property(GLOBAL PROPERTY Label "CSE-toplevel")
+
+ctest_start("Experimental")
+
+set(CSE_TOPLEVEL_OPTIONS
+ -DEXTERNAL_PROJECT_DASHBOARD_BUILD:BOOL=ON
+ -DEXTERNAL_PROJECT_TESTS:BOOL=ON
+ -DCSE_INSTALL_PREFIX:PATH=${CTEST_BINARY_DIRECTORY}/built
+ -DCSE_SUBSET:STRING=ALL
+ -DCTEST_SITE:STRING=${CTEST_SITE}
+)
+
+ctest_configure(OPTIONS "${CSE_TOPLEVEL_OPTIONS}")
+
+# The configure step produces a file listing the CSE packages and dependencies.
+# This file also generates Project.xml and stores it in ${PROJECT_XML}.
+#
+set(subprojects "")
+if(EXISTS "${CTEST_BINARY_DIRECTORY}/CSEBuildtimeDepends.cmake")
+ message("Including CSEBuildtimeDepends.cmake")
+ include("${CTEST_BINARY_DIRECTORY}/CSEBuildtimeDepends.cmake")
+ set(subprojects ${CSE_ALL_SORTED})
+ message("Submitting Project.xml")
+ ctest_submit(FILES ${PROJECT_XML})
+endif()
+
+message("Submitting CSE configure results")
+ctest_submit()
+
+if(subprojects)
+ message("Building by looping over subprojects...")
+ foreach(subproject ${subprojects})
+ message("########## ${subproject} ##########")
+ set_property(GLOBAL PROPERTY SubProject "${subproject}")
+ set_property(GLOBAL PROPERTY Label "${subproject}")
+ ctest_build(TARGET "${subproject}" APPEND)
+ message("Submitting ${subproject} build results")
+ ctest_submit(PARTS build)
+ endforeach()
+else()
+ message("Building all...")
+ ctest_build(APPEND)
+ message("Submitting build results")
+ ctest_submit(PARTS build)
+endif()
diff --git a/Tests/Contracts/cse-snapshot/RunTest.cmake b/Tests/Contracts/cse-snapshot/RunTest.cmake
new file mode 100644
index 000000000..7eb630116
--- /dev/null
+++ b/Tests/Contracts/cse-snapshot/RunTest.cmake
@@ -0,0 +1,3 @@
+set(exe "$ENV{HOME}/.cmake/Contracts/cse-snapshot/510345e4/build/built/Release/git-1.6.5.2/bin/git")
+set(args help clone)
+set(cse-snapshot_RUN_TEST ${exe} ${args})
diff --git a/Tests/Contracts/vtk542/CMakeLists.txt b/Tests/Contracts/vtk542/CMakeLists.txt
new file mode 100644
index 000000000..cfb8b1600
--- /dev/null
+++ b/Tests/Contracts/vtk542/CMakeLists.txt
@@ -0,0 +1,30 @@
+# 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
new file mode 100644
index 000000000..4f48e5cd2
--- /dev/null
+++ b/Tests/Contracts/vtk542/RunTest.cmake
@@ -0,0 +1 @@
+SET(vtk542_RUN_TEST VTK-build/bin/CommonCxxTests otherArrays)
diff --git a/Tests/CrossCompile/CMakeLists.txt b/Tests/CrossCompile/CMakeLists.txt
new file mode 100644
index 000000000..96a57a051
--- /dev/null
+++ b/Tests/CrossCompile/CMakeLists.txt
@@ -0,0 +1,13 @@
+cmake_minimum_required (VERSION 2.6)
+PROJECT(CrossCompile)
+
+UNSET(run_result CACHE)
+
+#Simulate the cross compile condition
+SET(CMAKE_CROSSCOMPILING ON)
+
+ADD_EXECUTABLE(CrossCompile main.c)
+
+TRY_RUN(run_result compile_result
+ ${CrossCompile_BINARY_DIR}
+ ${CrossCompile_SOURCE_DIR}/main.c)
diff --git a/Tests/CrossCompile/main.c b/Tests/CrossCompile/main.c
new file mode 100644
index 000000000..8488f4e58
--- /dev/null
+++ b/Tests/CrossCompile/main.c
@@ -0,0 +1,4 @@
+int main(void)
+{
+ return 0;
+}
diff --git a/Tests/CustComDepend/CMakeLists.txt b/Tests/CustComDepend/CMakeLists.txt
new file mode 100644
index 000000000..d5266842d
--- /dev/null
+++ b/Tests/CustComDepend/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required (VERSION 2.6)
+project(CustComDepend)
+include_directories("${CustComDepend_SOURCE_DIR}")
+add_definitions(-D_CRT_SECURE_NO_DEPRECATE=1)
+set(EXECUTABLE_OUTPUT_PATH ${CustComDepend_BINARY_DIR}/bin)
+add_executable(foo foo.cxx)
+add_custom_command(
+ OUTPUT ${CustComDepend_BINARY_DIR}/bar.c
+ COMMAND ${CustComDepend_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/foo
+ ${CustComDepend_BINARY_DIR}/bar.c
+ DEPENDS ${CustComDepend_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/foo
+)
+
+add_library(bar SHARED ${CustComDepend_BINARY_DIR}/bar.c)
diff --git a/Tests/CustComDepend/bar.h b/Tests/CustComDepend/bar.h
new file mode 100644
index 000000000..d462c9b5b
--- /dev/null
+++ b/Tests/CustComDepend/bar.h
@@ -0,0 +1,9 @@
+#ifdef _WIN32
+# ifdef bar_EXPORTS
+# define BAR_EXPORT __declspec( dllexport )
+# else
+# define BAR_EXPORT __declspec( dllimport )
+# endif
+#else
+# define BAR_EXPORT
+#endif
diff --git a/Tests/CustComDepend/foo.cxx b/Tests/CustComDepend/foo.cxx
new file mode 100644
index 000000000..3c204f8a2
--- /dev/null
+++ b/Tests/CustComDepend/foo.cxx
@@ -0,0 +1,15 @@
+#include <stdio.h>
+
+int main(int ac, char** av)
+{
+ FILE* fout = fopen(av[1], "w");
+ printf("create %s\n", av[1]);
+ if(!fout)
+ {
+ return -1;
+ }
+ fprintf(fout, "#include <bar.h>\nBAR_EXPORT int bar(){ return 10;}\n");
+ fclose(fout);
+ return 0;
+}
+
diff --git a/Tests/CustomCommand/CMakeLists.txt b/Tests/CustomCommand/CMakeLists.txt
new file mode 100644
index 000000000..b7c9ea268
--- /dev/null
+++ b/Tests/CustomCommand/CMakeLists.txt
@@ -0,0 +1,438 @@
+#
+# Wrapping
+#
+cmake_minimum_required (VERSION 2.6)
+PROJECT (CustomCommand)
+
+ADD_SUBDIRECTORY(GeneratedHeader)
+
+#
+# Lib and exe path
+#
+IF(NOT DEFINED bin_dir)
+ SET(bin_dir "bin")
+ENDIF()
+
+SET (LIBRARY_OUTPUT_PATH
+ ${PROJECT_BINARY_DIR}/${bin_dir} CACHE INTERNAL
+ "Single output directory for building all libraries.")
+
+SET (EXECUTABLE_OUTPUT_PATH
+ ${PROJECT_BINARY_DIR}/${bin_dir} CACHE INTERNAL
+ "Single output directory for building all executables.")
+
+################################################################
+#
+# First test using a compiled generator to create a .c file
+#
+################################################################
+# 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
+#
+################################################################
+# add the executable that will generate the file
+ADD_EXECUTABLE(wrapper wrapper.cxx)
+
+ADD_CUSTOM_COMMAND(
+ OUTPUT ${PROJECT_BINARY_DIR}/wrapped.c ${PROJECT_BINARY_DIR}/wrapped_help.c
+ DEPENDS wrapper
+ MAIN_DEPENDENCY ${PROJECT_SOURCE_DIR}/wrapped.h
+ COMMAND ${EXECUTABLE_OUTPUT_PATH}/${CMAKE_CFG_INTDIR}/wrapper
+ ${PROJECT_BINARY_DIR}/wrapped.c ${PROJECT_BINARY_DIR}/wrapped_help.c
+ ${CMAKE_CFG_INTDIR} # this argument tests passing of the configuration
+ VERBATIM # passing of configuration should work in this mode
+ )
+
+################################################################
+#
+# Test creating files from a custom target
+#
+################################################################
+ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_BINARY_DIR}//doc1.dvi # test 2 slashes
+ DEPENDS ${PROJECT_SOURCE_DIR}/doc1.tex
+ COMMAND ${CMAKE_COMMAND}
+ ARGS -E copy ${PROJECT_SOURCE_DIR}/doc1.tex
+ ${PROJECT_BINARY_DIR}/doc1.dvi
+ )
+
+ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_BINARY_DIR}/doc1.h
+ COMMAND ${CMAKE_COMMAND} -E echo " Copying doc1.dvi to doc1temp.h."
+ COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/doc1.dvi
+ ${PROJECT_BINARY_DIR}/doc1temp.h
+ )
+ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_BINARY_DIR}/doc1.h APPEND
+ DEPENDS ${PROJECT_BINARY_DIR}/doc1.dvi
+ COMMAND ${CMAKE_COMMAND} -E echo " Copying doc1temp.h to doc1.h."
+ COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/doc1temp.h
+ ${PROJECT_BINARY_DIR}/doc1.h
+ COMMAND ${CMAKE_COMMAND} -E echo " Removing doc1temp.h."
+ COMMAND ${CMAKE_COMMAND} -E remove -f ${PROJECT_BINARY_DIR}/doc1temp.h
+ )
+
+# Add custom command to generate foo.h.
+ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_BINARY_DIR}/foo.h
+ DEPENDS ${PROJECT_SOURCE_DIR}/foo.h.in
+ COMMAND ${CMAKE_COMMAND} -E echo " Copying foo.h.in to foo.h."
+ COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/foo.h.in
+ ${PROJECT_BINARY_DIR}/foo.h
+ )
+
+# Add the location of foo.h to the include path.
+INCLUDE_DIRECTORIES(${PROJECT_BINARY_DIR})
+
+# Test generation of a file to the build tree without full path. As
+# of CMake 2.6 custom command outputs specified by relative path go in
+# the build tree.
+ADD_CUSTOM_COMMAND(
+ OUTPUT doc1.txt
+ COMMAND ${CMAKE_COMMAND} -E echo "Example Document Target" > doc1.txt
+ DEPENDS doc1.tex
+ VERBATIM
+ )
+
+# Add a custom target to drive generation of doc1.h.
+ADD_CUSTOM_TARGET(TDocument ALL
+ COMMAND ${CMAKE_COMMAND} -E echo " Copying doc1.h to doc2.h."
+ COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/doc1.h
+ ${PROJECT_BINARY_DIR}/doc2.h
+ DEPENDS doc1.txt ${PROJECT_BINARY_DIR}//doc1.h # test 2 slashes
+ COMMENT "Running top-level TDocument commands"
+ SOURCES doc1.tex
+ )
+
+# Setup a pre- and post-build pair that will fail if not run in the
+# proper order.
+ADD_CUSTOM_COMMAND(
+ TARGET TDocument PRE_BUILD
+ COMMAND ${CMAKE_COMMAND} -E echo " Writing doc1pre.txt."
+ COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/doc1.tex ${PROJECT_BINARY_DIR}/doc1pre.txt
+ COMMENT "Running TDocument pre-build commands"
+ )
+ADD_CUSTOM_COMMAND(
+ TARGET TDocument POST_BUILD
+ 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
+ COMMENT "Running TDocument post-build commands"
+ )
+
+################################################################
+#
+# Test using a multistep generated file
+#
+################################################################
+ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_BINARY_DIR}/foo.pre
+ DEPENDS ${PROJECT_SOURCE_DIR}/foo.in
+ TDocument # Ensure doc1.h generates before this target
+ COMMAND ${CMAKE_COMMAND}
+ ARGS -E copy ${PROJECT_SOURCE_DIR}/foo.in
+ ${PROJECT_BINARY_DIR}/foo.pre
+ )
+
+ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_BINARY_DIR}/foo.c
+ DEPENDS ${PROJECT_BINARY_DIR}/foo.pre
+ COMMAND ${CMAKE_COMMAND}
+ ARGS -E copy ${PROJECT_BINARY_DIR}/foo.pre
+ ${PROJECT_BINARY_DIR}/foo.c
+ )
+
+# 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
+# get generated even if they are not needed by an object file.
+ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_BINARY_DIR}/not_included.h
+ DEPENDS ${PROJECT_SOURCE_DIR}/foo.h.in
+ COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/foo.h.in
+ ${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
+ ${PROJECT_BINARY_DIR}/foo.c
+ ${PROJECT_BINARY_DIR}/wrapped.c
+ ${PROJECT_BINARY_DIR}/wrapped_help.c
+ ${PROJECT_BINARY_DIR}/generated.c
+ ${PROJECT_BINARY_DIR}/not_included.h
+ gen_redirect.c # default location for custom commands is in build tree
+ )
+
+# Add the rule to create generated.c at build time. This is placed
+# 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}
+ ARGS ${PROJECT_BINARY_DIR}/generated.c
+ )
+
+TARGET_LINK_LIBRARIES(CustomCommand GeneratedHeader)
+
+##############################################################################
+# Test for using just the target name as executable in the COMMAND
+# section. Has to be recognized and replaced by CMake with the output
+# actual location of the executable.
+# Additionally the generator is created in an extra subdir after the
+# ADD_CUSTOM_COMMAND() is used.
+#
+# Test the same for ADD_CUSTOM_TARGET()
+
+ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/generated_extern.cxx
+ COMMAND generator_extern ${CMAKE_CURRENT_BINARY_DIR}/generated_extern.cxx
+ )
+
+ADD_EXECUTABLE(CustomCommandUsingTargetTest main.cxx ${CMAKE_CURRENT_BINARY_DIR}/generated_extern.cxx )
+
+ADD_CUSTOM_TARGET(RunTarget
+ COMMAND generator_extern ${CMAKE_CURRENT_BINARY_DIR}/run_target.cxx
+ )
+
+ADD_CUSTOM_COMMAND(TARGET CustomCommandUsingTargetTest POST_BUILD
+ COMMAND dummy_generator ${CMAKE_CURRENT_BINARY_DIR}/generated_dummy.cxx)
+
+ADD_SUBDIRECTORY(GeneratorInExtraDir)
+
+##############################################################################
+# Test shell operators in custom commands.
+
+ADD_EXECUTABLE(tcat tcat.cxx)
+
+ADD_CUSTOM_COMMAND(OUTPUT gen_redirect.c
+ DEPENDS tcat gen_redirect_in.c
+ COMMAND tcat < ${CMAKE_CURRENT_SOURCE_DIR}/gen_redirect_in.c > gen_redirect.c
+ COMMAND ${CMAKE_COMMAND} -E echo "#endif" >> gen_redirect.c
+ VERBATIM
+ )
+
+##############################################################################
+# Test non-trivial command line arguments in custom commands.
+SET(EXPECTED_ARGUMENTS)
+SET(CHECK_ARGS)
+IF(NOT MSVC71)
+ SET(CHECK_ARGS -DPATH=c:/posix/path)
+ENDIF()
+SET(CHECK_ARGS
+ ${CHECK_ARGS}
+ c:/posix/path
+ c:\\windows\\path
+ 'single-quotes'
+ single'quote
+ \"double-quotes\"
+ "\\;semi-colons\\;"
+ "semi\\;colon"
+ `back-ticks`
+ back`tick
+ "(parens)"
+ "(lparen"
+ "rparen)"
+ {curly}
+ {lcurly}
+ rcurly}
+ <angle>
+ <langle
+ rangle>
+ [square]
+ [lsquare # these have funny behavior due to special cases for
+ rsquare] # windows registry value names in list expansion
+ $dollar-signs$
+ dollar$sign
+ &ampersands&x # Borland make does not like trailing ampersand
+ one&ampersand
+ @two-ats@
+ one@at
+ ~two-tilda~
+ one~tilda
+ ^two-carrots^
+ one^carrot
+ %two-percents%
+ one%percent
+ !two-exclamations!
+ one!exclamation
+ ?two-questions?
+ one?question
+ *two-stars*
+ one*star
+ =two+equals=
+ one=equals
+ _two-underscores_
+ one_underscore
+ ,two-commas,
+ one,comma
+ .two-periods.
+ one.period
+ |two-pipes|
+ one|pipe
+ |nopipe
+ "#two-pounds#"
+ "one#pound"
+ "#nocomment"
+ "c:/posix/path/with space"
+ "c:\\windows\\path\\with space"
+ "'single quotes with space'"
+ "single'quote with space"
+ "\"double-quotes with space\""
+ "\\;semi-colons w s\\;"
+ "semi\\;colon w s"
+ "`back-ticks` w s"
+ "back`tick w s"
+ "(parens) w s"
+ "(lparen w s"
+ "rparen) w s"
+ "{curly} w s"
+ "{lcurly w s"
+ "rcurly} w s"
+ "<angle> w s"
+ "<langle w s"
+ "rangle> w s"
+ "[square] w s"
+ "[lsquare w s" # these have funny behavior due to special cases for
+ "rsquare] w s" # windows registry value names in list expansion
+ "$dollar-signs$ w s"
+ "dollar$sign w s"
+ "&ampersands& w s"
+ "one&ampersand w s"
+ "@two-ats@ w s"
+ "one@at w s"
+ "~two-tilda~ w s"
+ "one~tilda w s"
+ "^two-carrots^ w s"
+ "one^carrot w s"
+ "%two-percents% w s"
+ "one%percent w s"
+ "!two-exclamations! w s"
+ "one!exclamation w s"
+ "*two-stars* w s"
+ "one*star w s"
+ "=two+equals= w s"
+ "one=equals w s"
+ "_two-underscores_ w s"
+ "one_underscore w s"
+ "?two-questions? w s"
+ "one?question w s"
+ ",two-commas, w s"
+ "one,comma w s"
+ ".two-periods. w s"
+ "one.period w s"
+ "|two-pipes| w s"
+ "one|pipe w s"
+ "#two-pounds# w s"
+ "one#pound w s"
+ ~ ` ! @ \# $ % ^ & _ - + = : "\;" \" ' , . ? "(" ")" { } []
+ )
+IF(NOT MINGW)
+ # * # MinGW programs on windows always expands the wildcard!
+ # / # MSys make converts a leading slash to the mingw home directory
+ LIST(APPEND CHECK_ARGS * /)
+ENDIF(NOT MINGW)
+
+# The windows command shell does not support a double quote by itself:
+# double\"quote
+# without messing up quoting of arguments following it.
+
+# Make tools need help with escaping a single backslash
+# \
+# at the end of a command because they think it is a continuation
+# character.
+
+# We now have special cases for shell operators:
+# | < > << >> &> 2>&1 1>&2
+# to allow custom commands to perform redirection.
+
+FOREACH(arg ${CHECK_ARGS} "")
+ SET(ARG "${arg}")
+ STRING(REGEX REPLACE "\\\\" "\\\\\\\\" ARG "${ARG}")
+ STRING(REGEX REPLACE "\"" "\\\\\"" ARG "${ARG}")
+ SET(EXPECTED_ARGUMENTS
+ "${EXPECTED_ARGUMENTS} \"${ARG}\",
+")
+ENDFOREACH(arg)
+CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/check_command_line.c.in
+ ${CMAKE_CURRENT_BINARY_DIR}/check_command_line.c
+ @ONLY IMMEDIATE)
+ADD_EXECUTABLE(check_command_line
+ ${CMAKE_CURRENT_BINARY_DIR}/check_command_line.c)
+SET(output_name "check_command_line")
+SET_PROPERTY(TARGET check_command_line
+ PROPERTY OUTPUT_NAME ${output_name})
+# SET_TARGET_PROPERTIES(check_command_line PROPERTIES
+# COMPILE_FLAGS -DCHECK_COMMAND_LINE_VERBOSE)
+ADD_CUSTOM_COMMAND(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/command_line_check
+ COMMAND ${CMAKE_COMMAND} -DMARK_FILE=${CMAKE_CURRENT_BINARY_DIR}/check_mark.txt
+ -P ${CMAKE_CURRENT_SOURCE_DIR}/check_mark.cmake
+ COMMAND ${EXECUTABLE_OUTPUT_PATH}/${CMAKE_CFG_INTDIR}/${output_name}
+ ${CHECK_ARGS} ""
+ VERBATIM
+ COMMENT "Checking custom command line escapes (single'quote)"
+ )
+SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/command_line_check
+ PROPERTIES SYMBOLIC 1)
+ADD_CUSTOM_TARGET(do_check_command_line ALL
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/command_line_check
+ COMMAND ${CMAKE_COMMAND} -E echo "Checking custom target command escapes"
+ COMMAND ${EXECUTABLE_OUTPUT_PATH}/${CMAKE_CFG_INTDIR}/${output_name}
+ ${CHECK_ARGS} ""
+ VERBATIM
+ COMMENT "Checking custom target command line escapes ($dollar-signs$)"
+ )
+ADD_DEPENDENCIES(do_check_command_line check_command_line)
+
+ADD_CUSTOM_TARGET(pre_check_command_line
+ COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_CURRENT_BINARY_DIR}/check_mark.txt
+ )
+ADD_DEPENDENCIES(do_check_command_line pre_check_command_line)
+
+# <SameNameTest>
+#
+# Add a custom target called "SameName" -- then add a custom command in a
+# different target whose output is a full-path file called "SameName" -- then
+# add a second custom target that depends on the full-path file ".../SameName"
+#
+# At first, this reproduces a bug reported by a customer. After fixing it,
+# having this test here makes sure it stays fixed moving forward.
+#
+ADD_CUSTOM_COMMAND(
+ OUTPUT SameName1.txt
+ COMMAND ${CMAKE_COMMAND} -E touch SameName1.txt
+ )
+ADD_CUSTOM_TARGET(SameName ALL
+ DEPENDS SameName1.txt
+ )
+
+ADD_CUSTOM_COMMAND(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/subdir/SameName
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/subdir
+ COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/subdir/SameName
+ )
+ADD_CUSTOM_TARGET(DifferentName ALL
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/subdir/SameName
+ )
+#
+# </SameNameTest>
+
+# Per-config target name and generator expressions.
+ADD_SUBDIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../PerConfig PerConfig)
+ADD_CUSTOM_COMMAND(
+ OUTPUT perconfig.out
+ COMMAND ${PerConfig_COMMAND}
+ DEPENDS ${PerConfig_DEPENDS}
+ VERBATIM
+ )
+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)
diff --git a/Tests/CustomCommand/GeneratedHeader/CMakeLists.txt b/Tests/CustomCommand/GeneratedHeader/CMakeLists.txt
new file mode 100644
index 000000000..2d47d8749
--- /dev/null
+++ b/Tests/CustomCommand/GeneratedHeader/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Simulate in-source build include-file behavior for out-of-source
+# builds.
+SET(CMAKE_INCLUDE_CURRENT_DIR 1)
+
+ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/generated.h
+ COMMAND
+ ${CMAKE_COMMAND} ARGS -E
+ copy ${CMAKE_CURRENT_SOURCE_DIR}/generated.h.in
+ ${CMAKE_CURRENT_BINARY_DIR}/generated.h
+)
+
+ADD_LIBRARY(GeneratedHeader main.cpp ${CMAKE_CURRENT_BINARY_DIR}/generated.h)
+
diff --git a/Tests/CustomCommand/GeneratedHeader/generated.h.in b/Tests/CustomCommand/GeneratedHeader/generated.h.in
new file mode 100644
index 000000000..ae6f64c1c
--- /dev/null
+++ b/Tests/CustomCommand/GeneratedHeader/generated.h.in
@@ -0,0 +1 @@
+//hello
diff --git a/Tests/CustomCommand/GeneratedHeader/main.cpp b/Tests/CustomCommand/GeneratedHeader/main.cpp
new file mode 100644
index 000000000..0b43ffe83
--- /dev/null
+++ b/Tests/CustomCommand/GeneratedHeader/main.cpp
@@ -0,0 +1,5 @@
+#include "generated.h"
+int mainGeneratedHeader()
+{
+ return 0;
+}
diff --git a/Tests/CustomCommand/GeneratorInExtraDir/CMakeLists.txt b/Tests/CustomCommand/GeneratorInExtraDir/CMakeLists.txt
new file mode 100644
index 000000000..195a47792
--- /dev/null
+++ b/Tests/CustomCommand/GeneratorInExtraDir/CMakeLists.txt
@@ -0,0 +1,8 @@
+ADD_DEFINITIONS(-DGENERATOR_EXTERN)
+
+# add the executable which will be used for generating files
+ADD_EXECUTABLE(generator_extern ../generator.cxx)
+SET_TARGET_PROPERTIES(generator_extern PROPERTIES OUTPUT_NAME the_external_generator)
+
+# add an executable which will be called from ADD_CUSTOM_COMMAND( ... POST_BUILD)
+ADD_EXECUTABLE(dummy_generator ../generator.cxx)
diff --git a/Tests/CustomCommand/check_command_line.c.in b/Tests/CustomCommand/check_command_line.c.in
new file mode 100644
index 000000000..e0e0d2142
--- /dev/null
+++ b/Tests/CustomCommand/check_command_line.c.in
@@ -0,0 +1,36 @@
+#include <stdio.h>
+#include <string.h>
+
+const char* expected_arguments[] =
+{
+@EXPECTED_ARGUMENTS@ 0
+};
+
+int main(int argc, const char* argv[])
+{
+ const char** a = argv+1;
+ const char** e = expected_arguments;
+ (void)argc;
+ for(;*a && *e; ++a, ++e)
+ {
+ if(strcmp(*a, *e) != 0)
+ {
+ fprintf(stderr, "Argument [%s] does not match expected [%s].\n",
+ *a, *e);
+ return 1;
+ }
+ else
+ {
+#if defined(CHECK_COMMAND_LINE_VERBOSE)
+ printf("[%s]\n", *a);
+#endif
+ }
+ }
+ if(*a || *e)
+ {
+ fprintf(stderr, "Number of arguments does not match expected.\n");
+ return 1;
+ }
+ printf("Command line escapes work!\n");
+ return 0;
+}
diff --git a/Tests/CustomCommand/check_mark.cmake b/Tests/CustomCommand/check_mark.cmake
new file mode 100644
index 000000000..8b0551f83
--- /dev/null
+++ b/Tests/CustomCommand/check_mark.cmake
@@ -0,0 +1,5 @@
+IF(EXISTS "${MARK_FILE}")
+ MESSAGE(FATAL_ERROR "Custom command run more than once!")
+ELSE(EXISTS "${MARK_FILE}")
+ FILE(WRITE "${MARK_FILE}" "check for running custom command twice\n")
+ENDIF(EXISTS "${MARK_FILE}")
diff --git a/Tests/CustomCommand/config.h.in b/Tests/CustomCommand/config.h.in
new file mode 100644
index 000000000..86c97bd95
--- /dev/null
+++ b/Tests/CustomCommand/config.h.in
@@ -0,0 +1 @@
+#define PROJECT_BINARY_DIR "@PROJECT_BINARY_DIR@"
diff --git a/Tests/CustomCommand/doc1.tex b/Tests/CustomCommand/doc1.tex
new file mode 100644
index 000000000..e6b6ccbe5
--- /dev/null
+++ b/Tests/CustomCommand/doc1.tex
@@ -0,0 +1 @@
+int doc() { return 7;}
diff --git a/Tests/CustomCommand/foo.h.in b/Tests/CustomCommand/foo.h.in
new file mode 100644
index 000000000..d7721a2a5
--- /dev/null
+++ b/Tests/CustomCommand/foo.h.in
@@ -0,0 +1 @@
+/* Empty header file just used to test header generation. */
diff --git a/Tests/CustomCommand/foo.in b/Tests/CustomCommand/foo.in
new file mode 100644
index 000000000..08c559df4
--- /dev/null
+++ b/Tests/CustomCommand/foo.in
@@ -0,0 +1,28 @@
+#include "doc1.h"
+#include "foo.h"
+#include "config.h"
+
+#include <stdio.h>
+
+int generated();
+int wrapped();
+
+int main ()
+{
+ if (generated()*wrapped()*doc() == 3*5*7)
+ {
+ FILE* fin = fopen(PROJECT_BINARY_DIR "/not_included.h", "r");
+ if(fin)
+ {
+ fclose(fin);
+ return 0;
+ }
+ else
+ {
+ return -2;
+ }
+ }
+
+ return -1;
+}
+
diff --git a/Tests/CustomCommand/gen_redirect_in.c b/Tests/CustomCommand/gen_redirect_in.c
new file mode 100644
index 000000000..8dd8f43f0
--- /dev/null
+++ b/Tests/CustomCommand/gen_redirect_in.c
@@ -0,0 +1,5 @@
+#if 1
+
+int gen_redirect() { return 3; }
+
+/* endif should be concatenated to generated file */
diff --git a/Tests/CustomCommand/generator.cxx b/Tests/CustomCommand/generator.cxx
new file mode 100644
index 000000000..cceac073a
--- /dev/null
+++ b/Tests/CustomCommand/generator.cxx
@@ -0,0 +1,19 @@
+#include <stdio.h>
+
+int main(int argc, char *argv[])
+{
+ if ( argc < 2 )
+ {
+ fprintf(stderr, "Usage: %s <file>\n", argv[0]);
+ return 1;
+ }
+ FILE *fp = fopen(argv[1],"w");
+#ifdef GENERATOR_EXTERN
+ fprintf(fp,"int generated() { return 3; }\n");
+#else
+ fprintf(fp,"extern int gen_redirect(void);\n");
+ fprintf(fp,"int generated() { return gen_redirect(); }\n");
+#endif
+ fclose(fp);
+ return 0;
+}
diff --git a/Tests/CustomCommand/main.cxx b/Tests/CustomCommand/main.cxx
new file mode 100644
index 000000000..600e751dd
--- /dev/null
+++ b/Tests/CustomCommand/main.cxx
@@ -0,0 +1,6 @@
+extern int generated();
+
+int main()
+{
+ return generated();
+}
diff --git a/Tests/CustomCommand/tcat.cxx b/Tests/CustomCommand/tcat.cxx
new file mode 100644
index 000000000..89e3cb0a2
--- /dev/null
+++ b/Tests/CustomCommand/tcat.cxx
@@ -0,0 +1,11 @@
+#include <stdio.h>
+
+int main()
+{
+ int c;
+ while((c = getc(stdin), c != EOF))
+ {
+ putc(c, stdout);
+ }
+ return 0;
+}
diff --git a/Tests/CustomCommand/wrapped.h b/Tests/CustomCommand/wrapped.h
new file mode 100644
index 000000000..fa882cb5b
--- /dev/null
+++ b/Tests/CustomCommand/wrapped.h
@@ -0,0 +1 @@
+/* empty file */
diff --git a/Tests/CustomCommand/wrapper.cxx b/Tests/CustomCommand/wrapper.cxx
new file mode 100644
index 000000000..93cb079fe
--- /dev/null
+++ b/Tests/CustomCommand/wrapper.cxx
@@ -0,0 +1,36 @@
+#include <stdio.h>
+#include <string.h>
+
+int main(int argc, char *argv[])
+{
+ if ( argc < 3 )
+ {
+ fprintf(stderr, "Usage: %s <file1> <file2>\n", argv[0]);
+ return 1;
+ }
+ FILE *fp = fopen(argv[1],"w");
+ fprintf(fp,"extern int wrapped_help();\n");
+ fprintf(fp,"int wrapped() { return wrapped_help(); }\n");
+ fclose(fp);
+ fp = fopen(argv[2],"w");
+ fprintf(fp,"int wrapped_help() { return 5; }\n");
+ fclose(fp);
+#ifdef CMAKE_INTDIR
+ /* The VS6 IDE passes a leading ".\\" in its variable expansion. */
+# if defined(_MSC_VER) && _MSC_VER == 1200
+# define CFG_DIR ".\\" CMAKE_INTDIR
+# else
+# define CFG_DIR CMAKE_INTDIR
+# endif
+ const char* cfg = (argc >= 4)? argv[3] : "";
+ if(strcmp(cfg, CFG_DIR) != 0)
+ {
+ fprintf(stderr,
+ "Did not receive expected configuration argument:\n"
+ " expected [" CFG_DIR "]\n"
+ " received [%s]\n", cfg);
+ return 1;
+ }
+#endif
+ return 0;
+}
diff --git a/Tests/CustomCommandWorkingDirectory/CMakeLists.txt b/Tests/CustomCommandWorkingDirectory/CMakeLists.txt
new file mode 100644
index 000000000..36d32e4a0
--- /dev/null
+++ b/Tests/CustomCommandWorkingDirectory/CMakeLists.txt
@@ -0,0 +1,42 @@
+cmake_minimum_required (VERSION 2.6)
+PROJECT(TestWorkingDir)
+
+ADD_CUSTOM_COMMAND(
+ OUTPUT "${TestWorkingDir_BINARY_DIR}/working.c"
+ COMMAND "${CMAKE_COMMAND}" -E copy ./working.c.in "${TestWorkingDir_BINARY_DIR}/working.c"
+ WORKING_DIRECTORY "${TestWorkingDir_SOURCE_DIR}"
+ COMMENT "custom command"
+)
+
+SET_SOURCE_FILES_PROPERTIES(
+ "${TestWorkingDir_BINARY_DIR}/customTarget.c"
+ "${TestWorkingDir_BINARY_DIR}/customTarget2.c"
+ PROPERTIES GENERATED 1)
+
+ADD_EXECUTABLE(working "${TestWorkingDir_BINARY_DIR}/working.c"
+ "${TestWorkingDir_BINARY_DIR}/customTarget.c")
+
+ADD_CUSTOM_TARGET(
+ Custom ALL
+ COMMAND "${CMAKE_COMMAND}" -E copy_if_different ./customTarget.c "${TestWorkingDir_BINARY_DIR}/customTarget.c"
+ WORKING_DIRECTORY "${TestWorkingDir_SOURCE_DIR}"
+)
+
+ADD_DEPENDENCIES(working Custom)
+
+file(MAKE_DIRECTORY ${TestWorkingDir_BINARY_DIR}/work)
+add_custom_command(
+ OUTPUT working2.c # Relative to build tree
+ COMMAND "${CMAKE_COMMAND}" -E copy ${TestWorkingDir_SOURCE_DIR}/working.c.in ../working2.c
+ DEPENDS ${TestWorkingDir_SOURCE_DIR}/working.c.in/ # trailing slash should be removed
+ WORKING_DIRECTORY work/ # Relative to build tree, trailing slash
+ )
+add_executable(working2 working2.c ${TestWorkingDir_BINARY_DIR}/customTarget2.c)
+
+add_custom_target(
+ Custom2 ALL
+ COMMAND "${CMAKE_COMMAND}" -E copy_if_different ${TestWorkingDir_SOURCE_DIR}/customTarget.c ../customTarget2.c
+ WORKING_DIRECTORY work/ # Relative to build tree, trailing slash
+)
+
+add_dependencies(working2 Custom2)
diff --git a/Tests/CustomCommandWorkingDirectory/customTarget.c b/Tests/CustomCommandWorkingDirectory/customTarget.c
new file mode 100644
index 000000000..8dbf0d478
--- /dev/null
+++ b/Tests/CustomCommandWorkingDirectory/customTarget.c
@@ -0,0 +1,4 @@
+int customTarget()
+{
+ return 0;
+}
diff --git a/Tests/CustomCommandWorkingDirectory/working.c.in b/Tests/CustomCommandWorkingDirectory/working.c.in
new file mode 100644
index 000000000..cf75bd164
--- /dev/null
+++ b/Tests/CustomCommandWorkingDirectory/working.c.in
@@ -0,0 +1,7 @@
+int customTarget();
+
+int main()
+{
+ return customTarget();
+}
+
diff --git a/Tests/CxxOnly/CMakeLists.txt b/Tests/CxxOnly/CMakeLists.txt
new file mode 100644
index 000000000..e62f3c797
--- /dev/null
+++ b/Tests/CxxOnly/CMakeLists.txt
@@ -0,0 +1,13 @@
+# a simple CXX only test case
+project (CxxOnly CXX)
+
+set(CMAKE_DEBUG_POSTFIX "_test_debug_postfix")
+if(WIN32)
+ set(EXTRA_SRCS test.CPP)
+endif()
+add_library(testcxx1.my STATIC libcxx1.cxx ${EXTRA_SRCS})
+add_library(testcxx2 SHARED libcxx2.cxx)
+add_executable (CxxOnly cxxonly.cxx)
+target_link_libraries(CxxOnly testcxx1.my testcxx2)
+
+add_library(testCxxModule MODULE testCxxModule.cxx)
diff --git a/Tests/CxxOnly/cxxonly.cxx b/Tests/CxxOnly/cxxonly.cxx
new file mode 100644
index 000000000..9cf6f2d29
--- /dev/null
+++ b/Tests/CxxOnly/cxxonly.cxx
@@ -0,0 +1,25 @@
+#include "libcxx1.h"
+#include "libcxx2.h"
+#ifdef _MSC_VER
+extern int testCPP;
+#endif
+
+#include <stdio.h>
+
+int main ()
+{
+#ifdef _MSC_VER
+ testCPP = 1;
+#endif
+ if ( LibCxx1Class::Method() != 2.0 )
+ {
+ printf("Problem with libcxx1\n");
+ return 1;
+ }
+ if ( LibCxx2Class::Method() != 1.0 )
+ {
+ printf("Problem with libcxx2\n");
+ return 1;
+ }
+ return 0;
+}
diff --git a/Tests/CxxOnly/libcxx1.cxx b/Tests/CxxOnly/libcxx1.cxx
new file mode 100644
index 000000000..da18019d3
--- /dev/null
+++ b/Tests/CxxOnly/libcxx1.cxx
@@ -0,0 +1,6 @@
+#include "libcxx1.h"
+
+float LibCxx1Class::Method()
+{
+ return 2.0;
+}
diff --git a/Tests/CxxOnly/libcxx1.h b/Tests/CxxOnly/libcxx1.h
new file mode 100644
index 000000000..9452a64b1
--- /dev/null
+++ b/Tests/CxxOnly/libcxx1.h
@@ -0,0 +1,5 @@
+class LibCxx1Class
+{
+public:
+ static float Method();
+};
diff --git a/Tests/CxxOnly/libcxx2.cxx b/Tests/CxxOnly/libcxx2.cxx
new file mode 100644
index 000000000..453039c58
--- /dev/null
+++ b/Tests/CxxOnly/libcxx2.cxx
@@ -0,0 +1,6 @@
+#include "libcxx2.h"
+
+float LibCxx2Class::Method()
+{
+ return 1.0;
+}
diff --git a/Tests/CxxOnly/libcxx2.h b/Tests/CxxOnly/libcxx2.h
new file mode 100644
index 000000000..5dd84f6c2
--- /dev/null
+++ b/Tests/CxxOnly/libcxx2.h
@@ -0,0 +1,15 @@
+#ifdef _WIN32
+# ifdef testcxx2_EXPORTS
+# define CM_TEST_LIB_EXPORT __declspec( dllexport )
+# else
+# define CM_TEST_LIB_EXPORT __declspec( dllimport )
+# endif
+#else
+# define CM_TEST_LIB_EXPORT
+#endif
+
+class CM_TEST_LIB_EXPORT LibCxx2Class
+{
+public:
+ static float Method();
+};
diff --git a/Tests/CxxOnly/test.CPP b/Tests/CxxOnly/test.CPP
new file mode 100644
index 000000000..8a3cde262
--- /dev/null
+++ b/Tests/CxxOnly/test.CPP
@@ -0,0 +1 @@
+int testCPP;
diff --git a/Tests/CxxOnly/testCxxModule.cxx b/Tests/CxxOnly/testCxxModule.cxx
new file mode 100644
index 000000000..dd16d2bfa
--- /dev/null
+++ b/Tests/CxxOnly/testCxxModule.cxx
@@ -0,0 +1,6 @@
+#ifdef _WIN32
+# define TEST_EXPORT __declspec(dllexport)
+#else
+# define TEST_EXPORT
+#endif
+TEST_EXPORT int testCxxModule(void) { return 0; }
diff --git a/Tests/Dependency/1/CMakeLists.txt b/Tests/Dependency/1/CMakeLists.txt
new file mode 100644
index 000000000..b50b2e9c5
--- /dev/null
+++ b/Tests/Dependency/1/CMakeLists.txt
@@ -0,0 +1,3 @@
+ADD_LIBRARY( One OneSrc.c )
+# This library has no dependencies
+TARGET_LINK_LIBRARIES( One "" )
diff --git a/Tests/Dependency/1/OneSrc.c b/Tests/Dependency/1/OneSrc.c
new file mode 100644
index 000000000..9801c2524
--- /dev/null
+++ b/Tests/Dependency/1/OneSrc.c
@@ -0,0 +1,3 @@
+void OneFunction()
+{
+}
diff --git a/Tests/Dependency/CMakeLists.txt b/Tests/Dependency/CMakeLists.txt
new file mode 100644
index 000000000..86e128f58
--- /dev/null
+++ b/Tests/Dependency/CMakeLists.txt
@@ -0,0 +1,53 @@
+cmake_minimum_required (VERSION 2.6)
+PROJECT( Dependency )
+
+# to test directories with only one character One was changed to 1
+# There is one executable that depends on eight libraries. The
+# system has the following dependency graph:
+#
+# NoDepA:
+# NoDepB: NoDepA
+# NoDepC: NoDepA
+# 1:
+# Two: Three
+# Three: 1 Four
+# Four: 1 Two NoDepA
+# Five: Two
+# SixA: Two Five
+# SixB: Four Five
+# Seven: Two
+# Eight: Seven
+#
+# Exec: NoDepB NoDepC SixA SixB
+# Exec2: Eight Five
+# Exec3: Eight Five
+# Exec4: Five Two
+#
+# The libraries One,...,Eight have their dependencies explicitly
+# encoded. The libraries NoDepA,...,NoDepC do not.
+#
+# Although SixB does not depend on Two, there is a dependency listed
+# in the corresponding CMakeLists.txt just because of commands used.
+
+ADD_SUBDIRECTORY(NoDepA)
+ADD_SUBDIRECTORY(NoDepB)
+ADD_SUBDIRECTORY(NoDepC)
+ADD_SUBDIRECTORY(1)
+ADD_SUBDIRECTORY(Two)
+ADD_SUBDIRECTORY(Three)
+ADD_SUBDIRECTORY(Four)
+ADD_SUBDIRECTORY(Five)
+ADD_SUBDIRECTORY(Six)
+ADD_SUBDIRECTORY(Seven)
+ADD_SUBDIRECTORY(Eight)
+ADD_SUBDIRECTORY(Exec)
+ADD_SUBDIRECTORY(Exec2)
+ADD_SUBDIRECTORY(Exec3)
+ADD_SUBDIRECTORY(Exec4)
+
+# Specific cases added to test fixes to problems found in real
+# projects.
+ADD_SUBDIRECTORY(Case1)
+ADD_SUBDIRECTORY(Case2)
+ADD_SUBDIRECTORY(Case3)
+ADD_SUBDIRECTORY(Case4)
diff --git a/Tests/Dependency/Case1/CMakeLists.txt b/Tests/Dependency/Case1/CMakeLists.txt
new file mode 100644
index 000000000..4c5fc2037
--- /dev/null
+++ b/Tests/Dependency/Case1/CMakeLists.txt
@@ -0,0 +1,19 @@
+project(CASE1)
+
+# The old anaylize lib depends stuff in cmTarget gets this case wrong.
+# The cmComputeLinkDepends implementation gets it right.
+
+add_library(case1a STATIC a.c)
+
+add_library(case1b STATIC b.c b2.c)
+target_link_libraries(case1b case1a)
+
+add_library(case1c STATIC c.c c2.c)
+target_link_libraries(case1c case1b)
+
+add_library(case1d STATIC d.c)
+target_link_libraries(case1d case1c)
+
+add_executable(hello main.c)
+target_link_libraries(hello case1c case1b case1d case1c)
+
diff --git a/Tests/Dependency/Case1/a.c b/Tests/Dependency/Case1/a.c
new file mode 100644
index 000000000..d702db1af
--- /dev/null
+++ b/Tests/Dependency/Case1/a.c
@@ -0,0 +1,5 @@
+int a()
+{
+ return 5;
+}
+
diff --git a/Tests/Dependency/Case1/b.c b/Tests/Dependency/Case1/b.c
new file mode 100644
index 000000000..6bdfafafb
--- /dev/null
+++ b/Tests/Dependency/Case1/b.c
@@ -0,0 +1,6 @@
+extern int a();
+
+int b()
+{
+ return a()+17;
+}
diff --git a/Tests/Dependency/Case1/b2.c b/Tests/Dependency/Case1/b2.c
new file mode 100644
index 000000000..f37e1bb75
--- /dev/null
+++ b/Tests/Dependency/Case1/b2.c
@@ -0,0 +1,4 @@
+int b2()
+{
+ return 3;
+}
diff --git a/Tests/Dependency/Case1/c.c b/Tests/Dependency/Case1/c.c
new file mode 100644
index 000000000..c180a59b6
--- /dev/null
+++ b/Tests/Dependency/Case1/c.c
@@ -0,0 +1,6 @@
+extern int b();
+
+int c()
+{
+ return b()+42;
+}
diff --git a/Tests/Dependency/Case1/c2.c b/Tests/Dependency/Case1/c2.c
new file mode 100644
index 000000000..4cf4426e5
--- /dev/null
+++ b/Tests/Dependency/Case1/c2.c
@@ -0,0 +1,6 @@
+extern int b2();
+
+int c2()
+{
+ return b2()+1;
+}
diff --git a/Tests/Dependency/Case1/d.c b/Tests/Dependency/Case1/d.c
new file mode 100644
index 000000000..ea5457d4d
--- /dev/null
+++ b/Tests/Dependency/Case1/d.c
@@ -0,0 +1,7 @@
+extern int c2();
+
+int d()
+{
+ return c2()+2;
+}
+
diff --git a/Tests/Dependency/Case1/main.c b/Tests/Dependency/Case1/main.c
new file mode 100644
index 000000000..1e5f6d4aa
--- /dev/null
+++ b/Tests/Dependency/Case1/main.c
@@ -0,0 +1,10 @@
+extern int b();
+extern int c();
+extern int d();
+
+int main()
+{
+ c();
+ b();
+ d();
+}
diff --git a/Tests/Dependency/Case2/CMakeLists.txt b/Tests/Dependency/Case2/CMakeLists.txt
new file mode 100644
index 000000000..21caaad3e
--- /dev/null
+++ b/Tests/Dependency/Case2/CMakeLists.txt
@@ -0,0 +1,22 @@
+project(CASE2 C)
+
+add_library(case2Foo1 STATIC foo1.c foo1b.c foo1c.c)
+add_library(case2Foo2 STATIC foo2.c foo2b.c foo2c.c)
+add_library(case2Foo3 STATIC foo3.c foo3b.c foo3c.c)
+target_link_libraries(case2Foo1 case2Foo2)
+target_link_libraries(case2Foo2 case2Foo3)
+target_link_libraries(case2Foo3 case2Foo1)
+set_property(TARGET case2Foo1 PROPERTY LINK_INTERFACE_MULTIPLICITY 3)
+
+add_library(case2Bar1 STATIC bar1.c)
+add_library(case2Bar2 STATIC bar2.c)
+add_library(case2Bar3 STATIC bar3.c)
+target_link_libraries(case2Bar1 case2Bar2 case2Foo1)
+target_link_libraries(case2Bar2 case2Bar3)
+target_link_libraries(case2Bar3 case2Bar1)
+
+add_executable(case2Zot zot.c)
+target_link_libraries(case2Zot case2Bar1)
+
+#set_property(GLOBAL PROPERTY GLOBAL_DEPENDS_DEBUG_MODE 1)
+#set(CMAKE_LINK_DEPENDS_DEBUG_MODE 1)
diff --git a/Tests/Dependency/Case2/bar1.c b/Tests/Dependency/Case2/bar1.c
new file mode 100644
index 000000000..6108fba72
--- /dev/null
+++ b/Tests/Dependency/Case2/bar1.c
@@ -0,0 +1,4 @@
+extern int foo1();
+extern int bar2(void);
+int bar1(void) { return bar2(); }
+int bar1_from_bar3(void) { return foo1(); }
diff --git a/Tests/Dependency/Case2/bar2.c b/Tests/Dependency/Case2/bar2.c
new file mode 100644
index 000000000..b9a236090
--- /dev/null
+++ b/Tests/Dependency/Case2/bar2.c
@@ -0,0 +1,2 @@
+extern int bar3(void);
+int bar2(void) { return bar3(); }
diff --git a/Tests/Dependency/Case2/bar3.c b/Tests/Dependency/Case2/bar3.c
new file mode 100644
index 000000000..73e85567a
--- /dev/null
+++ b/Tests/Dependency/Case2/bar3.c
@@ -0,0 +1,2 @@
+extern int bar1_from_bar3(void);
+int bar3(void) { return bar1_from_bar3(); }
diff --git a/Tests/Dependency/Case2/foo1.c b/Tests/Dependency/Case2/foo1.c
new file mode 100644
index 000000000..5f1f8ac84
--- /dev/null
+++ b/Tests/Dependency/Case2/foo1.c
@@ -0,0 +1,2 @@
+extern int foo2(void);
+int foo1(void) { return foo2(); }
diff --git a/Tests/Dependency/Case2/foo1b.c b/Tests/Dependency/Case2/foo1b.c
new file mode 100644
index 000000000..e2b6dc341
--- /dev/null
+++ b/Tests/Dependency/Case2/foo1b.c
@@ -0,0 +1,2 @@
+extern int foo2b(void);
+int foo1b(void) { return foo2b(); }
diff --git a/Tests/Dependency/Case2/foo1c.c b/Tests/Dependency/Case2/foo1c.c
new file mode 100644
index 000000000..1dcca58c6
--- /dev/null
+++ b/Tests/Dependency/Case2/foo1c.c
@@ -0,0 +1,2 @@
+extern int foo2c(void);
+int foo1c(void) { return foo2c(); }
diff --git a/Tests/Dependency/Case2/foo2.c b/Tests/Dependency/Case2/foo2.c
new file mode 100644
index 000000000..601923663
--- /dev/null
+++ b/Tests/Dependency/Case2/foo2.c
@@ -0,0 +1,2 @@
+extern int foo3(void);
+int foo2(void) { return foo3(); }
diff --git a/Tests/Dependency/Case2/foo2b.c b/Tests/Dependency/Case2/foo2b.c
new file mode 100644
index 000000000..34d694411
--- /dev/null
+++ b/Tests/Dependency/Case2/foo2b.c
@@ -0,0 +1,2 @@
+extern int foo3b(void);
+int foo2b(void) { return foo3b(); }
diff --git a/Tests/Dependency/Case2/foo2c.c b/Tests/Dependency/Case2/foo2c.c
new file mode 100644
index 000000000..dbc54de74
--- /dev/null
+++ b/Tests/Dependency/Case2/foo2c.c
@@ -0,0 +1,2 @@
+extern int foo3c(void);
+int foo2c(void) { return foo3c(); }
diff --git a/Tests/Dependency/Case2/foo3.c b/Tests/Dependency/Case2/foo3.c
new file mode 100644
index 000000000..dacef6ae4
--- /dev/null
+++ b/Tests/Dependency/Case2/foo3.c
@@ -0,0 +1,2 @@
+extern int foo1b(void);
+int foo3(void) { return foo1b(); }
diff --git a/Tests/Dependency/Case2/foo3b.c b/Tests/Dependency/Case2/foo3b.c
new file mode 100644
index 000000000..ca25fd8ff
--- /dev/null
+++ b/Tests/Dependency/Case2/foo3b.c
@@ -0,0 +1,2 @@
+extern int foo1c(void);
+int foo3b(void) { return foo1c(); }
diff --git a/Tests/Dependency/Case2/foo3c.c b/Tests/Dependency/Case2/foo3c.c
new file mode 100644
index 000000000..0ad65fe44
--- /dev/null
+++ b/Tests/Dependency/Case2/foo3c.c
@@ -0,0 +1 @@
+int foo3c(void) { return 0; }
diff --git a/Tests/Dependency/Case2/zot.c b/Tests/Dependency/Case2/zot.c
new file mode 100644
index 000000000..f25b49343
--- /dev/null
+++ b/Tests/Dependency/Case2/zot.c
@@ -0,0 +1,5 @@
+extern int bar1(void);
+int main(void)
+{
+ return bar1();
+}
diff --git a/Tests/Dependency/Case3/CMakeLists.txt b/Tests/Dependency/Case3/CMakeLists.txt
new file mode 100644
index 000000000..f01dd057a
--- /dev/null
+++ b/Tests/Dependency/Case3/CMakeLists.txt
@@ -0,0 +1,10 @@
+project(CASE3 C)
+
+add_library(case3Foo1 STATIC foo1.c foo1b.c)
+add_library(case3Foo2 STATIC foo2.c)
+
+add_executable(case3Bar bar.c)
+target_link_libraries(case3Bar case3Foo1 case3Foo2 case3Foo1)
+
+#set_property(GLOBAL PROPERTY GLOBAL_DEPENDS_DEBUG_MODE 1)
+#set(CMAKE_LINK_DEPENDS_DEBUG_MODE 1)
diff --git a/Tests/Dependency/Case3/bar.c b/Tests/Dependency/Case3/bar.c
new file mode 100644
index 000000000..62959c1cb
--- /dev/null
+++ b/Tests/Dependency/Case3/bar.c
@@ -0,0 +1,5 @@
+extern int foo1(void);
+int main(void)
+{
+ return foo1();
+}
diff --git a/Tests/Dependency/Case3/foo1.c b/Tests/Dependency/Case3/foo1.c
new file mode 100644
index 000000000..5f1f8ac84
--- /dev/null
+++ b/Tests/Dependency/Case3/foo1.c
@@ -0,0 +1,2 @@
+extern int foo2(void);
+int foo1(void) { return foo2(); }
diff --git a/Tests/Dependency/Case3/foo1b.c b/Tests/Dependency/Case3/foo1b.c
new file mode 100644
index 000000000..6ae3babdc
--- /dev/null
+++ b/Tests/Dependency/Case3/foo1b.c
@@ -0,0 +1 @@
+int foo1b(void) { return 0; }
diff --git a/Tests/Dependency/Case3/foo2.c b/Tests/Dependency/Case3/foo2.c
new file mode 100644
index 000000000..33dbbfce6
--- /dev/null
+++ b/Tests/Dependency/Case3/foo2.c
@@ -0,0 +1,2 @@
+extern int foo1b(void);
+int foo2(void) { return foo1b(); }
diff --git a/Tests/Dependency/Case4/CMakeLists.txt b/Tests/Dependency/Case4/CMakeLists.txt
new file mode 100644
index 000000000..a71049da3
--- /dev/null
+++ b/Tests/Dependency/Case4/CMakeLists.txt
@@ -0,0 +1,19 @@
+project(CASE4 C)
+
+# This is not really a circular dependency. "case4Bar" refers to a
+# third-party library that happens to match the executable name, which
+# is okay when the executable is not a linkable target (ENABLE_EXPORTS
+# is not set). This tests whether CMake avoids incorrectly reporting
+# a circular dependency. In practice case4Foo may be a shared
+# library, but we skip that here because we do not want it to actually
+# have to find the third-party library.
+add_library(case4Foo STATIC foo.c)
+target_link_libraries(case4Foo case4Bar)
+
+# The executable avoids linking to a library with its own name, which
+# has been a CMake-ism for a long time, so we will not get a link
+# failure. An imported target or executable with an OUTPUT_NAME set
+# may be used if the user really wants to link a third-party library
+# into an executable of the same name.
+add_executable(case4Bar bar.c)
+target_link_libraries(case4Bar case4Foo)
diff --git a/Tests/Dependency/Case4/bar.c b/Tests/Dependency/Case4/bar.c
new file mode 100644
index 000000000..d0bb0c43c
--- /dev/null
+++ b/Tests/Dependency/Case4/bar.c
@@ -0,0 +1,2 @@
+extern int foo();
+int main() { return foo(); }
diff --git a/Tests/Dependency/Case4/foo.c b/Tests/Dependency/Case4/foo.c
new file mode 100644
index 000000000..9fe07f82f
--- /dev/null
+++ b/Tests/Dependency/Case4/foo.c
@@ -0,0 +1 @@
+int foo() { return 0; }
diff --git a/Tests/Dependency/Eight/CMakeLists.txt b/Tests/Dependency/Eight/CMakeLists.txt
new file mode 100644
index 000000000..5d8e7564e
--- /dev/null
+++ b/Tests/Dependency/Eight/CMakeLists.txt
@@ -0,0 +1,3 @@
+ADD_LIBRARY( Eight EightSrc.c )
+TARGET_LINK_LIBRARIES( Eight Seven )
+
diff --git a/Tests/Dependency/Eight/EightSrc.c b/Tests/Dependency/Eight/EightSrc.c
new file mode 100644
index 000000000..7bfa481e2
--- /dev/null
+++ b/Tests/Dependency/Eight/EightSrc.c
@@ -0,0 +1,6 @@
+void SevenFunction();
+
+void EightFunction()
+{
+ SevenFunction();
+}
diff --git a/Tests/Dependency/Exec/CMakeLists.txt b/Tests/Dependency/Exec/CMakeLists.txt
new file mode 100644
index 000000000..97fffe706
--- /dev/null
+++ b/Tests/Dependency/Exec/CMakeLists.txt
@@ -0,0 +1,7 @@
+# This executable directly depends on NoDepB, NoDepC, SixA and SixB. However,
+# since NoDepB and NoDepC do not have explicit dependency information,
+# and they depend on NoDepA, we have to manually specify that dependency.
+LINK_LIBRARIES( NoDepB NoDepC NoDepA SixB SixA )
+
+ADD_EXECUTABLE( exec ExecMain.c )
+
diff --git a/Tests/Dependency/Exec/ExecMain.c b/Tests/Dependency/Exec/ExecMain.c
new file mode 100644
index 000000000..d2f551c7a
--- /dev/null
+++ b/Tests/Dependency/Exec/ExecMain.c
@@ -0,0 +1,18 @@
+#include <stdio.h>
+
+void NoDepBFunction();
+void NoDepCFunction();
+void SixAFunction();
+void SixBFunction();
+
+int main( )
+{
+ SixAFunction();
+ SixBFunction();
+ NoDepBFunction();
+ NoDepCFunction();
+
+ printf("Dependency test executable ran successfully.\n");
+
+ return 0;
+}
diff --git a/Tests/Dependency/Exec2/CMakeLists.txt b/Tests/Dependency/Exec2/CMakeLists.txt
new file mode 100644
index 000000000..ee0c74d13
--- /dev/null
+++ b/Tests/Dependency/Exec2/CMakeLists.txt
@@ -0,0 +1,12 @@
+# Here, Eight depends on Seven, which has the same dependencies as Five.
+# If the dependencies of Five are emitted, and then we attempt to emit the
+# dependencies of Seven, then we find that they have already been done. So:
+# Original line: Eight Five
+# Add deps of Five: Eight Five Two ... NoDepA
+# Now, we must make sure that Seven gets inserted between Five and Two, and
+# not at the end. Unfortunately, if we get it wrong, the test will only
+# fail on a platform where the link order makes a difference.
+LINK_LIBRARIES( Eight Five )
+
+ADD_EXECUTABLE( exec2 ExecMain.c )
+
diff --git a/Tests/Dependency/Exec2/ExecMain.c b/Tests/Dependency/Exec2/ExecMain.c
new file mode 100644
index 000000000..d08a796c3
--- /dev/null
+++ b/Tests/Dependency/Exec2/ExecMain.c
@@ -0,0 +1,14 @@
+#include <stdio.h>
+
+void FiveFunction();
+void EightFunction();
+
+int main( )
+{
+ FiveFunction();
+ EightFunction();
+
+ printf("Dependency test executable ran successfully.\n");
+
+ return 0;
+}
diff --git a/Tests/Dependency/Exec3/CMakeLists.txt b/Tests/Dependency/Exec3/CMakeLists.txt
new file mode 100644
index 000000000..b33e732a2
--- /dev/null
+++ b/Tests/Dependency/Exec3/CMakeLists.txt
@@ -0,0 +1,6 @@
+# Here, Five already has it's immediate dependency, Two satisfied. We must
+# make sure Two gets output anyway, because Eight indirectly depends on it.
+LINK_LIBRARIES( Five Two Eight Five )
+
+ADD_EXECUTABLE( exec3 ExecMain.c )
+
diff --git a/Tests/Dependency/Exec3/ExecMain.c b/Tests/Dependency/Exec3/ExecMain.c
new file mode 100644
index 000000000..d08a796c3
--- /dev/null
+++ b/Tests/Dependency/Exec3/ExecMain.c
@@ -0,0 +1,14 @@
+#include <stdio.h>
+
+void FiveFunction();
+void EightFunction();
+
+int main( )
+{
+ FiveFunction();
+ EightFunction();
+
+ printf("Dependency test executable ran successfully.\n");
+
+ return 0;
+}
diff --git a/Tests/Dependency/Exec4/CMakeLists.txt b/Tests/Dependency/Exec4/CMakeLists.txt
new file mode 100644
index 000000000..6fcb15383
--- /dev/null
+++ b/Tests/Dependency/Exec4/CMakeLists.txt
@@ -0,0 +1,6 @@
+# Even though Five's dependency on Two is explicitly satisfied, Two
+# must be emitted again in order to satisfy a cyclic dependency on Three.
+LINK_LIBRARIES( Five Two Five )
+
+ADD_EXECUTABLE( exec4 ExecMain.c )
+
diff --git a/Tests/Dependency/Exec4/ExecMain.c b/Tests/Dependency/Exec4/ExecMain.c
new file mode 100644
index 000000000..3f53573bf
--- /dev/null
+++ b/Tests/Dependency/Exec4/ExecMain.c
@@ -0,0 +1,14 @@
+#include <stdio.h>
+
+void FiveFunction();
+void TwoFunction();
+
+int main( )
+{
+ FiveFunction();
+ TwoFunction();
+
+ printf("Dependency test executable ran successfully.\n");
+
+ return 0;
+}
diff --git a/Tests/Dependency/Five/CMakeLists.txt b/Tests/Dependency/Five/CMakeLists.txt
new file mode 100644
index 000000000..27f6a1f5b
--- /dev/null
+++ b/Tests/Dependency/Five/CMakeLists.txt
@@ -0,0 +1,3 @@
+ADD_LIBRARY( Five FiveSrc.c )
+TARGET_LINK_LIBRARIES( Five Two )
+
diff --git a/Tests/Dependency/Five/FiveSrc.c b/Tests/Dependency/Five/FiveSrc.c
new file mode 100644
index 000000000..33d8ad7dc
--- /dev/null
+++ b/Tests/Dependency/Five/FiveSrc.c
@@ -0,0 +1,6 @@
+void TwoFunction();
+
+void FiveFunction()
+{
+ TwoFunction();
+}
diff --git a/Tests/Dependency/Four/CMakeLists.txt b/Tests/Dependency/Four/CMakeLists.txt
new file mode 100644
index 000000000..df0f1624e
--- /dev/null
+++ b/Tests/Dependency/Four/CMakeLists.txt
@@ -0,0 +1,6 @@
+INCLUDE_DIRECTORIES(${Dependency_BINARY_DIR}/Two)
+ADD_LIBRARY( Four FourSrc.c )
+TARGET_LINK_LIBRARIES( Four One Two NoDepA )
+
+# TwoCustom must build before Four.
+ADD_DEPENDENCIES(Four TwoCustom)
diff --git a/Tests/Dependency/Four/FourSrc.c b/Tests/Dependency/Four/FourSrc.c
new file mode 100644
index 000000000..23a66a49a
--- /dev/null
+++ b/Tests/Dependency/Four/FourSrc.c
@@ -0,0 +1,15 @@
+#include <two-test.h> /* Requires TwoCustom to be built first. */
+void NoDepAFunction();
+void OneFunction();
+void TwoFunction();
+
+void FourFunction()
+{
+ static int count = 0;
+ if( count == 0 ) {
+ ++count;
+ TwoFunction();
+ }
+ OneFunction();
+ NoDepAFunction();
+}
diff --git a/Tests/Dependency/NoDepA/CMakeLists.txt b/Tests/Dependency/NoDepA/CMakeLists.txt
new file mode 100644
index 000000000..cedf185fa
--- /dev/null
+++ b/Tests/Dependency/NoDepA/CMakeLists.txt
@@ -0,0 +1 @@
+ADD_LIBRARY( NoDepA NoDepASrc.c )
diff --git a/Tests/Dependency/NoDepA/NoDepASrc.c b/Tests/Dependency/NoDepA/NoDepASrc.c
new file mode 100644
index 000000000..8c4072bd1
--- /dev/null
+++ b/Tests/Dependency/NoDepA/NoDepASrc.c
@@ -0,0 +1,3 @@
+void NoDepAFunction()
+{
+}
diff --git a/Tests/Dependency/NoDepB/CMakeLists.txt b/Tests/Dependency/NoDepB/CMakeLists.txt
new file mode 100644
index 000000000..0d69f6841
--- /dev/null
+++ b/Tests/Dependency/NoDepB/CMakeLists.txt
@@ -0,0 +1,3 @@
+ADD_LIBRARY( NoDepB NoDepBSrc.c )
+# This library depends on NoDepA, but the
+# dependency is not explicitly specified.
diff --git a/Tests/Dependency/NoDepB/NoDepBSrc.c b/Tests/Dependency/NoDepB/NoDepBSrc.c
new file mode 100644
index 000000000..ddc71c527
--- /dev/null
+++ b/Tests/Dependency/NoDepB/NoDepBSrc.c
@@ -0,0 +1,6 @@
+void NoDepAFunction();
+
+void NoDepBFunction()
+{
+ NoDepAFunction();
+}
diff --git a/Tests/Dependency/NoDepC/CMakeLists.txt b/Tests/Dependency/NoDepC/CMakeLists.txt
new file mode 100644
index 000000000..88b29ba6f
--- /dev/null
+++ b/Tests/Dependency/NoDepC/CMakeLists.txt
@@ -0,0 +1,3 @@
+ADD_LIBRARY( NoDepC NoDepCSrc.c )
+# This library depends on NoDepA, but the
+# dependency is not explicitly specified.
diff --git a/Tests/Dependency/NoDepC/NoDepCSrc.c b/Tests/Dependency/NoDepC/NoDepCSrc.c
new file mode 100644
index 000000000..b478c596d
--- /dev/null
+++ b/Tests/Dependency/NoDepC/NoDepCSrc.c
@@ -0,0 +1,6 @@
+void NoDepAFunction();
+
+void NoDepCFunction()
+{
+ NoDepAFunction();
+}
diff --git a/Tests/Dependency/Seven/CMakeLists.txt b/Tests/Dependency/Seven/CMakeLists.txt
new file mode 100644
index 000000000..51a38d8ed
--- /dev/null
+++ b/Tests/Dependency/Seven/CMakeLists.txt
@@ -0,0 +1,3 @@
+ADD_LIBRARY( Seven SevenSrc.c )
+TARGET_LINK_LIBRARIES( Seven Two )
+
diff --git a/Tests/Dependency/Seven/SevenSrc.c b/Tests/Dependency/Seven/SevenSrc.c
new file mode 100644
index 000000000..e1f3329e8
--- /dev/null
+++ b/Tests/Dependency/Seven/SevenSrc.c
@@ -0,0 +1,6 @@
+void TwoFunction();
+
+void SevenFunction()
+{
+ TwoFunction();
+}
diff --git a/Tests/Dependency/Six/CMakeLists.txt b/Tests/Dependency/Six/CMakeLists.txt
new file mode 100644
index 000000000..d0abdd695
--- /dev/null
+++ b/Tests/Dependency/Six/CMakeLists.txt
@@ -0,0 +1,12 @@
+# In some projects, people don't use TARGET_LINK_LIBRARIES, but just
+# use an all-encompassing LINK_LIBRARIES. And sometimes they don't
+# specify them in the correct order.
+
+LINK_LIBRARIES( Two )
+LINK_LIBRARIES( Five )
+
+ADD_LIBRARY( SixA SixASrc.c )
+
+ADD_LIBRARY( SixB SixBSrc.c )
+TARGET_LINK_LIBRARIES( SixB Four )
+
diff --git a/Tests/Dependency/Six/SixASrc.c b/Tests/Dependency/Six/SixASrc.c
new file mode 100644
index 000000000..7ea3711f2
--- /dev/null
+++ b/Tests/Dependency/Six/SixASrc.c
@@ -0,0 +1,8 @@
+void FiveFunction();
+void TwoFunction();
+
+void SixAFunction()
+{
+ FiveFunction();
+ TwoFunction();
+}
diff --git a/Tests/Dependency/Six/SixBSrc.c b/Tests/Dependency/Six/SixBSrc.c
new file mode 100644
index 000000000..92f9607f8
--- /dev/null
+++ b/Tests/Dependency/Six/SixBSrc.c
@@ -0,0 +1,10 @@
+void TwoFunction();
+void FiveFunction();
+void FourFunction();
+
+void SixBFunction()
+{
+ TwoFunction();
+ FiveFunction();
+ FourFunction();
+}
diff --git a/Tests/Dependency/Three/CMakeLists.txt b/Tests/Dependency/Three/CMakeLists.txt
new file mode 100644
index 000000000..6b20dcb81
--- /dev/null
+++ b/Tests/Dependency/Three/CMakeLists.txt
@@ -0,0 +1,3 @@
+ADD_LIBRARY( Three ThreeSrc.c )
+TARGET_LINK_LIBRARIES( Three One Four )
+
diff --git a/Tests/Dependency/Three/ThreeSrc.c b/Tests/Dependency/Three/ThreeSrc.c
new file mode 100644
index 000000000..9c77f17a0
--- /dev/null
+++ b/Tests/Dependency/Three/ThreeSrc.c
@@ -0,0 +1,12 @@
+void OneFunction();
+void FourFunction();
+
+void ThreeFunction()
+{
+ static int count = 0;
+ if( count == 0 ) {
+ ++count;
+ FourFunction();
+ }
+ OneFunction();
+}
diff --git a/Tests/Dependency/Two/CMakeLists.txt b/Tests/Dependency/Two/CMakeLists.txt
new file mode 100644
index 000000000..587c848f7
--- /dev/null
+++ b/Tests/Dependency/Two/CMakeLists.txt
@@ -0,0 +1,20 @@
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+ADD_LIBRARY( Two TwoSrc.c )
+TARGET_LINK_LIBRARIES( Two Three )
+
+# Setup a target to cause failure if Two does not depend on it or if
+# Two actually links to it. This will test that a utility dependency
+# on a library target works properly.
+ADD_CUSTOM_COMMAND(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/two-test.h
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ ${CMAKE_CURRENT_SOURCE_DIR}/two-test.h.in
+ ${CMAKE_CURRENT_BINARY_DIR}/two-test.h
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/two-test.h.in
+ )
+ADD_LIBRARY( TwoCustom TwoCustomSrc.c ${CMAKE_CURRENT_BINARY_DIR}/two-test.h)
+SET_TARGET_PROPERTIES(TwoCustom PROPERTIES EXCLUDE_FROM_ALL 1)
+TARGET_LINK_LIBRARIES(TwoCustom Three)
+
+# Add a utility dependency to make sure it works without linking.
+ADD_DEPENDENCIES(Two TwoCustom)
diff --git a/Tests/Dependency/Two/TwoCustomSrc.c b/Tests/Dependency/Two/TwoCustomSrc.c
new file mode 100644
index 000000000..ac31dcf37
--- /dev/null
+++ b/Tests/Dependency/Two/TwoCustomSrc.c
@@ -0,0 +1,10 @@
+extern void NoFunction();
+
+/* Provide a function that is supposed to be found in the Three
+ library. If Two links to TwoCustom then TwoCustom will come before
+ Three and this symbol will be used. Since NoFunction is not
+ defined, that will cause a link failure. */
+void ThreeFunction()
+{
+ NoFunction();
+}
diff --git a/Tests/Dependency/Two/TwoSrc.c b/Tests/Dependency/Two/TwoSrc.c
new file mode 100644
index 000000000..0b3366b2b
--- /dev/null
+++ b/Tests/Dependency/Two/TwoSrc.c
@@ -0,0 +1,10 @@
+#include <two-test.h>
+
+void TwoFunction()
+{
+ static int count = 0;
+ if( count == 0 ) {
+ ++count;
+ ThreeFunction();
+ }
+}
diff --git a/Tests/Dependency/Two/two-test.h.in b/Tests/Dependency/Two/two-test.h.in
new file mode 100644
index 000000000..8c6a7f770
--- /dev/null
+++ b/Tests/Dependency/Two/two-test.h.in
@@ -0,0 +1 @@
+extern void ThreeFunction();
diff --git a/Tests/DocTest/CMakeLists.txt b/Tests/DocTest/CMakeLists.txt
new file mode 100644
index 000000000..837328e81
--- /dev/null
+++ b/Tests/DocTest/CMakeLists.txt
@@ -0,0 +1,7 @@
+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
new file mode 100644
index 000000000..2263cbd73
--- /dev/null
+++ b/Tests/DocTest/DocTest.cxx
@@ -0,0 +1,33 @@
+#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/DoubleProject/CMakeLists.txt b/Tests/DoubleProject/CMakeLists.txt
new file mode 100644
index 000000000..02a627597
--- /dev/null
+++ b/Tests/DoubleProject/CMakeLists.txt
@@ -0,0 +1,3 @@
+project(dumb)
+project(dumber)
+add_executable(just_silly silly.c)
diff --git a/Tests/DoubleProject/silly.c b/Tests/DoubleProject/silly.c
new file mode 100644
index 000000000..f8b643afb
--- /dev/null
+++ b/Tests/DoubleProject/silly.c
@@ -0,0 +1,4 @@
+int main()
+{
+ return 0;
+}
diff --git a/Tests/EmptyLibrary/CMakeLists.txt b/Tests/EmptyLibrary/CMakeLists.txt
new file mode 100644
index 000000000..baddbbf5e
--- /dev/null
+++ b/Tests/EmptyLibrary/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 2.6)
+project(TestEmptyLibrary)
+
+add_subdirectory(subdir)
diff --git a/Tests/EmptyLibrary/subdir/CMakeLists.txt b/Tests/EmptyLibrary/subdir/CMakeLists.txt
new file mode 100644
index 000000000..e273f8db9
--- /dev/null
+++ b/Tests/EmptyLibrary/subdir/CMakeLists.txt
@@ -0,0 +1 @@
+add_library(test test.h)
diff --git a/Tests/EmptyLibrary/subdir/test.h b/Tests/EmptyLibrary/subdir/test.h
new file mode 100644
index 000000000..8511f53d6
--- /dev/null
+++ b/Tests/EmptyLibrary/subdir/test.h
@@ -0,0 +1 @@
+extern int dummy;
diff --git a/Tests/EnforceConfig.cmake.in b/Tests/EnforceConfig.cmake.in
new file mode 100644
index 000000000..c9028a391
--- /dev/null
+++ b/Tests/EnforceConfig.cmake.in
@@ -0,0 +1,26 @@
+# Choose a configuration with which to drive CTest tests.
+IF(CTEST_CONFIGURATION_TYPE)
+ SET(CTestTest_CONFIG "${CTEST_CONFIGURATION_TYPE}")
+ELSE(CTEST_CONFIGURATION_TYPE)
+ SET(CTestTest_CONFIG "@CTestTest_CONFIG@")
+ENDIF(CTEST_CONFIGURATION_TYPE)
+
+# Choose a configuration that was built if none is given.
+IF(NOT CTEST_CONFIGURATION_TYPE)
+ SET(CTEST_CMD "@CMAKE_CTEST_COMMAND@@CMAKE_EXECUTABLE_SUFFIX@")
+ GET_FILENAME_COMPONENT(CTEST_DIR "${CTEST_CMD}" PATH)
+ GET_FILENAME_COMPONENT(CTEST_EXE "${CTEST_CMD}" NAME)
+ FOREACH(cfg Release Debug MinSizeRel RelWithDebInfo)
+ IF(NOT CTEST_CONFIGURATION_TYPE)
+ IF(EXISTS "${CTEST_DIR}/${cfg}/${CTEST_EXE}")
+ SET(CTEST_CONFIGURATION_TYPE ${cfg})
+ ENDIF(EXISTS "${CTEST_DIR}/${cfg}/${CTEST_EXE}")
+ ENDIF(NOT CTEST_CONFIGURATION_TYPE)
+ ENDFOREACH(cfg)
+ IF(NOT CTEST_CONFIGURATION_TYPE)
+ SET(CTEST_CONFIGURATION_TYPE NoConfig)
+ ENDIF(NOT CTEST_CONFIGURATION_TYPE)
+ MESSAGE("Guessing configuration ${CTEST_CONFIGURATION_TYPE}")
+ENDIF(NOT CTEST_CONFIGURATION_TYPE)
+
+@TEST_HOME_ENV_CODE@
diff --git a/Tests/Environment/CMakeLists.txt b/Tests/Environment/CMakeLists.txt
new file mode 100644
index 000000000..2b18d2466
--- /dev/null
+++ b/Tests/Environment/CMakeLists.txt
@@ -0,0 +1,26 @@
+cmake_minimum_required(VERSION 2.6)
+project(EnvironmentProj)
+
+add_executable(Environment main.cxx)
+
+enable_testing()
+
+add_test(Environment1 Environment)
+add_test(Environment2 Environment)
+add_test(EchoEnvironment1 ${CMAKE_COMMAND} -E environment)
+add_test(EchoEnvironment2 ${CMAKE_COMMAND} -E environment)
+
+# Make sure "CMAKE_ENV.*Happy Thanksgiving" is in the output of
+# the "1" tests:
+#
+set_tests_properties(Environment1 EchoEnvironment1 PROPERTIES
+ ENVIRONMENT "CMAKE_ENVIRONMENT_TEST_VAR=Happy Thanksgiving!"
+ PASS_REGULAR_EXPRESSION "CMAKE_ENV.*Happy Thanksgiving"
+)
+
+# Make sure "CMAKE_ENV.*Happy Thanksgiving" is *NOT* in the output of
+# the "2" tests:
+#
+set_tests_properties(Environment2 EchoEnvironment2 PROPERTIES
+ FAIL_REGULAR_EXPRESSION "CMAKE_ENV.*Happy Thanksgiving"
+)
diff --git a/Tests/Environment/main.cxx b/Tests/Environment/main.cxx
new file mode 100644
index 000000000..2e1bf4c28
--- /dev/null
+++ b/Tests/Environment/main.cxx
@@ -0,0 +1,16 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(int argc, char *argv[])
+{
+ char* var = getenv("CMAKE_ENVIRONMENT_TEST_VAR");
+ if (!var)
+ {
+ var = "(null)";
+ }
+
+ fprintf(stdout, "Environment:\n");
+ fprintf(stdout, " CMAKE_ENVIRONMENT_TEST_VAR='%s'\n", var);
+
+ return 0;
+}
diff --git a/Tests/ExportImport/CMakeLists.txt b/Tests/ExportImport/CMakeLists.txt
new file mode 100644
index 000000000..ccfb8940c
--- /dev/null
+++ b/Tests/ExportImport/CMakeLists.txt
@@ -0,0 +1,75 @@
+cmake_minimum_required (VERSION 2.7.20090711)
+project(ExportImport C CXX)
+
+# Wipe out the install tree to make sure the exporter works.
+add_custom_command(
+ OUTPUT ${ExportImport_BINARY_DIR}/CleanupProject
+ COMMAND ${CMAKE_COMMAND} -E remove_directory ${ExportImport_BINARY_DIR}/Root
+ )
+add_custom_target(CleanupTarget ALL DEPENDS ${ExportImport_BINARY_DIR}/CleanupProject)
+set_property(
+ SOURCE ${ExportImport_BINARY_DIR}/CleanupProject
+ PROPERTY SYMBOLIC 1
+ )
+
+if(CMAKE_CONFIGURATION_TYPES)
+ set(NESTED_CONFIG_TYPE -C "${CMAKE_CFG_INTDIR}")
+else(CMAKE_CONFIGURATION_TYPES)
+ if(CMAKE_BUILD_TYPE)
+ set(NESTED_CONFIG_TYPE -C "${CMAKE_BUILD_TYPE}")
+ else(CMAKE_BUILD_TYPE)
+ set(NESTED_CONFIG_TYPE)
+ endif(CMAKE_BUILD_TYPE)
+endif(CMAKE_CONFIGURATION_TYPES)
+
+if(MINGW OR MSYS)
+ # Test CMAKE_GNUtoMS whether we have VS or not.
+ set(ExportImport_GNUtoMS 1)
+endif()
+
+configure_file(${ExportImport_SOURCE_DIR}/InitialCache.cmake.in
+ ${ExportImport_BINARY_DIR}/InitialCache.cmake @ONLY)
+
+# Build and install the exporter.
+add_custom_command(
+ OUTPUT ${ExportImport_BINARY_DIR}/ExportProject
+ COMMAND ${CMAKE_CTEST_COMMAND} ${NESTED_CONFIG_TYPE}
+ --build-and-test
+ ${ExportImport_SOURCE_DIR}/Export
+ ${ExportImport_BINARY_DIR}/Export
+ --build-noclean
+ --build-project Export
+ --build-target install
+ --build-generator ${CMAKE_GENERATOR}
+ --build-makeprogram ${CMAKE_MAKE_PROGRAM}
+ --build-options -C${ExportImport_BINARY_DIR}/InitialCache.cmake
+ )
+add_custom_target(ExportTarget ALL DEPENDS ${ExportImport_BINARY_DIR}/ExportProject)
+add_dependencies(ExportTarget CleanupTarget)
+set_property(
+ SOURCE ${ExportImport_BINARY_DIR}/ExportProject
+ PROPERTY SYMBOLIC 1
+ )
+
+# Build and install the importer.
+add_custom_command(
+ OUTPUT ${ExportImport_BINARY_DIR}/ImportProject
+ COMMAND ${CMAKE_CTEST_COMMAND} ${NESTED_CONFIG_TYPE}
+ --build-and-test
+ ${ExportImport_SOURCE_DIR}/Import
+ ${ExportImport_BINARY_DIR}/Import
+ --build-noclean
+ --build-project Import
+ --build-generator ${CMAKE_GENERATOR}
+ --build-makeprogram ${CMAKE_MAKE_PROGRAM}
+ --build-options -C${ExportImport_BINARY_DIR}/InitialCache.cmake
+ )
+add_custom_target(ImportTarget ALL DEPENDS ${ExportImport_BINARY_DIR}/ImportProject)
+add_dependencies(ImportTarget ExportTarget)
+set_property(
+ SOURCE ${ExportImport_BINARY_DIR}/ImportProject
+ PROPERTY SYMBOLIC 1
+ )
+
+add_executable(ExportImport main.c)
+add_dependencies(ExportImport ImportTarget)
diff --git a/Tests/ExportImport/Export/CMakeLists.txt b/Tests/ExportImport/Export/CMakeLists.txt
new file mode 100644
index 000000000..f06a4659f
--- /dev/null
+++ b/Tests/ExportImport/Export/CMakeLists.txt
@@ -0,0 +1,145 @@
+cmake_minimum_required (VERSION 2.7.20090711)
+project(Export C CXX)
+
+# Pretend that RelWithDebInfo should link to debug libraries to test
+# the DEBUG_CONFIGURATIONS property.
+set_property(GLOBAL PROPERTY DEBUG_CONFIGURATIONS Debug RelWithDebInfo)
+
+add_library(testExe1lib STATIC testExe1lib.c) # not exported
+add_executable(testExe1 testExe1.c)
+target_link_libraries(testExe1 testExe1lib)
+set_property(TARGET testExe1 PROPERTY VERSION 4)
+
+add_library(testExe2libImp SHARED testExe2libImp.c)
+set_property(TARGET testExe2libImp PROPERTY LIBRARY_OUTPUT_DIRECTORY impl)
+add_library(testExe2lib SHARED testExe2lib.c)
+target_link_libraries(testExe2lib testExe2libImp)
+set_property(TARGET testExe2lib PROPERTY LINK_INTERFACE_LIBRARIES "")
+add_executable(testExe2 testExe2.c)
+set_property(TARGET testExe2 PROPERTY ENABLE_EXPORTS 1)
+set_property(TARGET testExe2 PROPERTY LINK_INTERFACE_LIBRARIES testExe2lib)
+
+add_library(testLib1 STATIC testLib1.c)
+add_library(testLib2 STATIC testLib2.c)
+target_link_libraries(testLib2 testLib1)
+
+# Test library with empty link interface. Link it to an implementation
+# dependency that itself links to dependencies publicly.
+add_library(testLib3ImpDep SHARED testLib3ImpDep.c)
+set_property(TARGET testLib3ImpDep PROPERTY LIBRARY_OUTPUT_DIRECTORY impl/dep)
+add_library(testLib3Imp SHARED testLib3Imp.c)
+set_property(TARGET testLib3Imp PROPERTY LIBRARY_OUTPUT_DIRECTORY impl)
+target_link_libraries(testLib3Imp testLib3ImpDep)
+add_library(testLib3 SHARED testLib3.c)
+target_link_libraries(testLib3 testLib3Imp)
+set_property(TARGET testLib3 PROPERTY LINK_INTERFACE_LIBRARIES "")
+set_property(TARGET testLib3 PROPERTY VERSION 1.2)
+set_property(TARGET testLib3 PROPERTY SOVERSION 3)
+
+# Test <ARCHIVE|LIBRARY|RUNTIME>_OUTPUT_NAME[_<CONFIG>] properties.
+set_property(TARGET testLib3 PROPERTY RUNTIME_OUTPUT_NAME_DEBUG testLib3dll-d)
+set_property(TARGET testLib3 PROPERTY RUNTIME_OUTPUT_NAME_RELEASE testLib3dll-r)
+set_property(TARGET testLib3 PROPERTY RUNTIME_OUTPUT_NAME testLib3dll)
+set_property(TARGET testLib3 PROPERTY LIBRARY_OUTPUT_NAME_DEBUG testLib3lib-d)
+set_property(TARGET testLib3 PROPERTY LIBRARY_OUTPUT_NAME_RELEASE testLib3lib-r)
+set_property(TARGET testLib3 PROPERTY LIBRARY_OUTPUT_NAME testLib3lib)
+set_property(TARGET testLib3 PROPERTY ARCHIVE_OUTPUT_NAME testLib3import)
+
+add_library(testLib4 SHARED testLib4.c)
+set_property(TARGET testLib4 PROPERTY FRAMEWORK 1)
+
+add_library(testLib5 SHARED testLib5.c)
+
+add_library(testLib6 STATIC testLib6.cxx testLib6c.c)
+
+# Work-around: Visual Studio 6 does not support per-target object files.
+set(VS6)
+if("${CMAKE_GENERATOR}" MATCHES "Visual Studio 6")
+ set(VS6 1)
+endif("${CMAKE_GENERATOR}" MATCHES "Visual Studio 6")
+
+# Test using the target_link_libraries command to set the
+# LINK_INTERFACE_LIBRARIES* properties. We construct two libraries
+# providing the same two symbols. In each library one of the symbols
+# will work and the other one will fail to link. The import part of
+# this test will try to use the symbol corresponding to the
+# configuration in which it is built. If the proper library is not
+# used via the link interface the import test will fail to link.
+add_library(testLib4lib STATIC testLib4lib.c)
+add_library(testLib4libdbg STATIC testLib4libopt.c testLib4libdbg${VS6}.c)
+add_library(testLib4libopt STATIC testLib4libdbg.c testLib4libopt${VS6}.c)
+set_property(TARGET testLib4libdbg PROPERTY COMPILE_DEFINITIONS LIB_DBG)
+set_property(TARGET testLib4libopt PROPERTY COMPILE_DEFINITIONS LIB_OPT)
+target_link_libraries(testLib4
+ LINK_INTERFACE_LIBRARIES
+ testLib4lib debug testLib4libdbg optimized testLib4libopt
+ )
+
+add_executable(testExe3 testExe3.c)
+set_property(TARGET testExe3 PROPERTY MACOSX_BUNDLE 1)
+
+# Test cyclic dependencies.
+add_library(testLibCycleA STATIC
+ testLibCycleA1.c testLibCycleA2.c testLibCycleA3.c)
+add_library(testLibCycleB STATIC
+ testLibCycleB1.c testLibCycleB2.c testLibCycleB3.c)
+target_link_libraries(testLibCycleA testLibCycleB)
+target_link_libraries(testLibCycleB testLibCycleA)
+set_property(TARGET testLibCycleA PROPERTY LINK_INTERFACE_MULTIPLICITY 3)
+
+# Install and export from install tree.
+install(
+ TARGETS
+ testExe1 testLib1 testLib2 testExe2 testLib3 testLib4 testExe3
+ testExe2lib testLib4lib testLib4libdbg testLib4libopt
+ testLib6
+ testLibCycleA testLibCycleB
+ EXPORT exp
+ RUNTIME DESTINATION bin
+ LIBRARY DESTINATION lib NAMELINK_SKIP
+ ARCHIVE DESTINATION lib
+ FRAMEWORK DESTINATION Frameworks
+ BUNDLE DESTINATION Applications
+ )
+install(
+ TARGETS
+ testExe2libImp testLib3Imp
+ EXPORT exp
+ RUNTIME DESTINATION bin
+ LIBRARY DESTINATION lib/impl
+ ARCHIVE DESTINATION lib/impl
+ )
+install(
+ TARGETS
+ testLib3ImpDep
+ EXPORT exp
+ RUNTIME DESTINATION bin
+ LIBRARY DESTINATION lib/impl/dep
+ ARCHIVE DESTINATION lib/impl/dep
+ )
+install(
+ TARGETS testLib5
+ EXPORT exp
+ # Leave out RUNTIME DESTINATION to test implib-only export.
+ LIBRARY DESTINATION lib
+ ARCHIVE DESTINATION lib
+ )
+install(EXPORT exp NAMESPACE exp_ DESTINATION lib/exp)
+
+# Install testLib5.dll outside the export.
+if(WIN32)
+ install(TARGETS testLib5 RUNTIME DESTINATION bin)
+endif(WIN32)
+
+# Export from build tree.
+export(TARGETS testExe1 testLib1 testLib2 testLib3
+ testExe2libImp testLib3Imp testLib3ImpDep
+ NAMESPACE bld_
+ FILE ExportBuildTree.cmake
+ )
+export(TARGETS testExe2 testLib4 testLib5 testLib6 testExe3 testExe2lib
+ testLib4lib testLib4libdbg testLib4libopt
+ testLibCycleA testLibCycleB
+ NAMESPACE bld_
+ APPEND FILE ExportBuildTree.cmake
+ )
diff --git a/Tests/ExportImport/Export/testExe1.c b/Tests/ExportImport/Export/testExe1.c
new file mode 100644
index 000000000..e00fac74f
--- /dev/null
+++ b/Tests/ExportImport/Export/testExe1.c
@@ -0,0 +1,26 @@
+#include <stdio.h>
+
+extern int testExe1lib(void);
+
+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_testExe1() { return 0; }\n");
+ fclose(f);
+ }
+ else
+ {
+ fprintf(stderr, "Error writing to %s\n", argv[1]);
+ return 1;
+ }
+ }
+ return testExe1lib();
+}
diff --git a/Tests/ExportImport/Export/testExe1lib.c b/Tests/ExportImport/Export/testExe1lib.c
new file mode 100644
index 000000000..7ad48a392
--- /dev/null
+++ b/Tests/ExportImport/Export/testExe1lib.c
@@ -0,0 +1 @@
+int testExe1lib(void) { return 0; }
diff --git a/Tests/ExportImport/Export/testExe2.c b/Tests/ExportImport/Export/testExe2.c
new file mode 100644
index 000000000..f7d93453a
--- /dev/null
+++ b/Tests/ExportImport/Export/testExe2.c
@@ -0,0 +1,12 @@
+#if defined(_WIN32) || defined(__CYGWIN__)
+# define testExe2_EXPORT __declspec(dllexport)
+#else
+# define testExe2_EXPORT
+#endif
+
+testExe2_EXPORT int testExe2Func(void) { return 123; }
+
+int main()
+{
+ return 0;
+}
diff --git a/Tests/ExportImport/Export/testExe2lib.c b/Tests/ExportImport/Export/testExe2lib.c
new file mode 100644
index 000000000..199143900
--- /dev/null
+++ b/Tests/ExportImport/Export/testExe2lib.c
@@ -0,0 +1,10 @@
+#if defined(_WIN32) || defined(__CYGWIN__)
+# define testExe2lib_EXPORT __declspec(dllexport)
+# define testExe2libImp_IMPORT __declspec(dllimport)
+#else
+# define testExe2lib_EXPORT
+# define testExe2libImp_IMPORT
+#endif
+
+testExe2libImp_IMPORT int testExe2libImp(void);
+testExe2lib_EXPORT int testExe2lib(void) { return testExe2libImp(); }
diff --git a/Tests/ExportImport/Export/testExe2libImp.c b/Tests/ExportImport/Export/testExe2libImp.c
new file mode 100644
index 000000000..f5a23af55
--- /dev/null
+++ b/Tests/ExportImport/Export/testExe2libImp.c
@@ -0,0 +1,7 @@
+#if defined(_WIN32) || defined(__CYGWIN__)
+# define testExe2libImp_EXPORT __declspec(dllexport)
+#else
+# define testExe2libImp_EXPORT
+#endif
+
+testExe2libImp_EXPORT int testExe2libImp(void) { return 0; }
diff --git a/Tests/ExportImport/Export/testExe3.c b/Tests/ExportImport/Export/testExe3.c
new file mode 100644
index 000000000..895e2fc2d
--- /dev/null
+++ b/Tests/ExportImport/Export/testExe3.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_testExe3() { 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/testLib1.c b/Tests/ExportImport/Export/testLib1.c
new file mode 100644
index 000000000..35bb1e5db
--- /dev/null
+++ b/Tests/ExportImport/Export/testLib1.c
@@ -0,0 +1 @@
+int testLib1(void) { return 0; }
diff --git a/Tests/ExportImport/Export/testLib2.c b/Tests/ExportImport/Export/testLib2.c
new file mode 100644
index 000000000..aabc0d30f
--- /dev/null
+++ b/Tests/ExportImport/Export/testLib2.c
@@ -0,0 +1,4 @@
+
+extern int testLib1(void);
+
+int testLib2(void) { return testLib1(); }
diff --git a/Tests/ExportImport/Export/testLib3.c b/Tests/ExportImport/Export/testLib3.c
new file mode 100644
index 000000000..31cec9435
--- /dev/null
+++ b/Tests/ExportImport/Export/testLib3.c
@@ -0,0 +1,10 @@
+#if defined(_WIN32) || defined(__CYGWIN__)
+# define testLib3_EXPORT __declspec(dllexport)
+# define testLib3Imp_IMPORT __declspec(dllimport)
+#else
+# define testLib3_EXPORT
+# define testLib3Imp_IMPORT
+#endif
+
+testLib3Imp_IMPORT int testLib3Imp(void);
+testLib3_EXPORT int testLib3(void) { return testLib3Imp(); }
diff --git a/Tests/ExportImport/Export/testLib3Imp.c b/Tests/ExportImport/Export/testLib3Imp.c
new file mode 100644
index 000000000..c27bccd40
--- /dev/null
+++ b/Tests/ExportImport/Export/testLib3Imp.c
@@ -0,0 +1,10 @@
+#if defined(_WIN32) || defined(__CYGWIN__)
+# define testLib3Imp_EXPORT __declspec(dllexport)
+# define testLib3ImpDep_IMPORT __declspec(dllimport)
+#else
+# define testLib3Imp_EXPORT
+# define testLib3ImpDep_IMPORT
+#endif
+
+testLib3ImpDep_IMPORT int testLib3ImpDep(void);
+testLib3Imp_EXPORT int testLib3Imp(void) { return testLib3ImpDep(); }
diff --git a/Tests/ExportImport/Export/testLib3ImpDep.c b/Tests/ExportImport/Export/testLib3ImpDep.c
new file mode 100644
index 000000000..578ac30ef
--- /dev/null
+++ b/Tests/ExportImport/Export/testLib3ImpDep.c
@@ -0,0 +1,7 @@
+#if defined(_WIN32) || defined(__CYGWIN__)
+# define testLib3ImpDep_EXPORT __declspec(dllexport)
+#else
+# define testLib3ImpDep_EXPORT
+#endif
+
+testLib3ImpDep_EXPORT int testLib3ImpDep(void) { return 0; }
diff --git a/Tests/ExportImport/Export/testLib4.c b/Tests/ExportImport/Export/testLib4.c
new file mode 100644
index 000000000..846b4389b
--- /dev/null
+++ b/Tests/ExportImport/Export/testLib4.c
@@ -0,0 +1,7 @@
+#if defined(_WIN32) || defined(__CYGWIN__)
+# define testLib4_EXPORT __declspec(dllexport)
+#else
+# define testLib4_EXPORT
+#endif
+
+testLib4_EXPORT int testLib4(void) { return 0; }
diff --git a/Tests/ExportImport/Export/testLib4lib.c b/Tests/ExportImport/Export/testLib4lib.c
new file mode 100644
index 000000000..bf3c11ec6
--- /dev/null
+++ b/Tests/ExportImport/Export/testLib4lib.c
@@ -0,0 +1,4 @@
+int testLib4lib(void)
+{
+ return 0;
+}
diff --git a/Tests/ExportImport/Export/testLib4libdbg.c b/Tests/ExportImport/Export/testLib4libdbg.c
new file mode 100644
index 000000000..453f26282
--- /dev/null
+++ b/Tests/ExportImport/Export/testLib4libdbg.c
@@ -0,0 +1,14 @@
+#ifdef LIB_DBG
+/* We are building in testLib4libdbg. Provide the correct symbol. */
+int testLib4libdbg(void)
+{
+ return 0;
+}
+#else
+/* We are not building in testLib4libdbg. Poison the symbol. */
+extern int testLib4libdbg_noexist(void);
+int testLib4libdbg(void)
+{
+ return testLib4libdbg_noexist();
+}
+#endif
diff --git a/Tests/ExportImport/Export/testLib4libdbg1.c b/Tests/ExportImport/Export/testLib4libdbg1.c
new file mode 100644
index 000000000..cc56cf933
--- /dev/null
+++ b/Tests/ExportImport/Export/testLib4libdbg1.c
@@ -0,0 +1 @@
+#include "testLib4libdbg.c"
diff --git a/Tests/ExportImport/Export/testLib4libopt.c b/Tests/ExportImport/Export/testLib4libopt.c
new file mode 100644
index 000000000..605edd05b
--- /dev/null
+++ b/Tests/ExportImport/Export/testLib4libopt.c
@@ -0,0 +1,14 @@
+#ifdef LIB_OPT
+/* We are building in testLib4libopt. Provide the correct symbol. */
+int testLib4libopt(void)
+{
+ return 0;
+}
+#else
+/* We are not building in testLib4libopt. Poison the symbol. */
+extern int testLib4libopt_noexist(void);
+int testLib4libopt(void)
+{
+ return testLib4libopt_noexist();
+}
+#endif
diff --git a/Tests/ExportImport/Export/testLib4libopt1.c b/Tests/ExportImport/Export/testLib4libopt1.c
new file mode 100644
index 000000000..d9b55879d
--- /dev/null
+++ b/Tests/ExportImport/Export/testLib4libopt1.c
@@ -0,0 +1 @@
+#include "testLib4libopt.c"
diff --git a/Tests/ExportImport/Export/testLib5.c b/Tests/ExportImport/Export/testLib5.c
new file mode 100644
index 000000000..20a821513
--- /dev/null
+++ b/Tests/ExportImport/Export/testLib5.c
@@ -0,0 +1,7 @@
+#if defined(_WIN32) || defined(__CYGWIN__)
+# define testLib5_EXPORT __declspec(dllexport)
+#else
+# define testLib5_EXPORT
+#endif
+
+testLib5_EXPORT int testLib5(void) { return 0; }
diff --git a/Tests/ExportImport/Export/testLib6.cxx b/Tests/ExportImport/Export/testLib6.cxx
new file mode 100644
index 000000000..338e6399a
--- /dev/null
+++ b/Tests/ExportImport/Export/testLib6.cxx
@@ -0,0 +1,6 @@
+extern "C" int testLib6cxx(void)
+{
+ // Reference C++ standard library symbols.
+ delete new int;
+ return 0;
+}
diff --git a/Tests/ExportImport/Export/testLib6c.c b/Tests/ExportImport/Export/testLib6c.c
new file mode 100644
index 000000000..493ca070e
--- /dev/null
+++ b/Tests/ExportImport/Export/testLib6c.c
@@ -0,0 +1,5 @@
+extern int testLib6cxx(void);
+int testLib6(void)
+{
+ return testLib6cxx();
+}
diff --git a/Tests/ExportImport/Export/testLibCycleA1.c b/Tests/ExportImport/Export/testLibCycleA1.c
new file mode 100644
index 000000000..3db9e5356
--- /dev/null
+++ b/Tests/ExportImport/Export/testLibCycleA1.c
@@ -0,0 +1,2 @@
+extern int testLibCycleB1(void);
+int testLibCycleA1(void) { return testLibCycleB1(); }
diff --git a/Tests/ExportImport/Export/testLibCycleA2.c b/Tests/ExportImport/Export/testLibCycleA2.c
new file mode 100644
index 000000000..29ad46d4e
--- /dev/null
+++ b/Tests/ExportImport/Export/testLibCycleA2.c
@@ -0,0 +1,2 @@
+extern int testLibCycleB2(void);
+int testLibCycleA2(void) { return testLibCycleB2(); }
diff --git a/Tests/ExportImport/Export/testLibCycleA3.c b/Tests/ExportImport/Export/testLibCycleA3.c
new file mode 100644
index 000000000..565447b21
--- /dev/null
+++ b/Tests/ExportImport/Export/testLibCycleA3.c
@@ -0,0 +1,2 @@
+extern int testLibCycleB3(void);
+int testLibCycleA3(void) { return testLibCycleB3(); }
diff --git a/Tests/ExportImport/Export/testLibCycleB1.c b/Tests/ExportImport/Export/testLibCycleB1.c
new file mode 100644
index 000000000..36cb7b0e9
--- /dev/null
+++ b/Tests/ExportImport/Export/testLibCycleB1.c
@@ -0,0 +1,2 @@
+extern int testLibCycleA2(void);
+int testLibCycleB1(void) { return testLibCycleA2(); }
diff --git a/Tests/ExportImport/Export/testLibCycleB2.c b/Tests/ExportImport/Export/testLibCycleB2.c
new file mode 100644
index 000000000..ff1209302
--- /dev/null
+++ b/Tests/ExportImport/Export/testLibCycleB2.c
@@ -0,0 +1,2 @@
+extern int testLibCycleA3(void);
+int testLibCycleB2(void) { return testLibCycleA3(); }
diff --git a/Tests/ExportImport/Export/testLibCycleB3.c b/Tests/ExportImport/Export/testLibCycleB3.c
new file mode 100644
index 000000000..ca8d47005
--- /dev/null
+++ b/Tests/ExportImport/Export/testLibCycleB3.c
@@ -0,0 +1 @@
+int testLibCycleB3(void) { return 0; }
diff --git a/Tests/ExportImport/Import/A/CMakeLists.txt b/Tests/ExportImport/Import/A/CMakeLists.txt
new file mode 100644
index 000000000..a21e1b0f8
--- /dev/null
+++ b/Tests/ExportImport/Import/A/CMakeLists.txt
@@ -0,0 +1,150 @@
+# Import targets from the exported build tree.
+include(${Import_BINARY_DIR}/../Export/ExportBuildTree.cmake)
+
+# Import targets from the exported install tree.
+include(${CMAKE_INSTALL_PREFIX}/lib/exp/exp.cmake)
+
+# Try referencing an executable imported from the install tree.
+add_custom_command(
+ OUTPUT ${Import_BINARY_DIR}/exp_generated.c
+ COMMAND exp_testExe1 ${Import_BINARY_DIR}/exp_generated.c
+ DEPENDS exp_testExe1
+ )
+add_custom_command(
+ OUTPUT ${Import_BINARY_DIR}/exp_generated3.c
+ COMMAND exp_testExe3 ${Import_BINARY_DIR}/exp_generated3.c
+ DEPENDS exp_testExe3
+ )
+
+add_executable(imp_testExe1
+ imp_testExe1.c
+ ${Import_BINARY_DIR}/exp_generated.c
+ ${Import_BINARY_DIR}/exp_generated3.c
+ )
+
+# Try linking to a library imported from the install tree.
+target_link_libraries(imp_testExe1
+ exp_testLib2
+ exp_testLib3
+ exp_testLib4
+ exp_testLib5
+ exp_testLib6
+ exp_testLibCycleA
+ )
+
+# Try building a plugin to an executable imported from the install tree.
+add_library(imp_mod1 MODULE imp_mod1.c)
+target_link_libraries(imp_mod1 exp_testExe2)
+
+# Try referencing an executable imported from the build tree.
+add_custom_command(
+ OUTPUT ${Import_BINARY_DIR}/bld_generated.c
+ COMMAND bld_testExe1 ${Import_BINARY_DIR}/bld_generated.c
+ DEPENDS bld_testExe1
+ )
+add_custom_command(
+ OUTPUT ${Import_BINARY_DIR}/bld_generated3.c
+ COMMAND bld_testExe3 ${Import_BINARY_DIR}/bld_generated3.c
+ DEPENDS bld_testExe3
+ )
+
+add_executable(imp_testExe1b
+ imp_testExe1.c
+ ${Import_BINARY_DIR}/bld_generated.c
+ ${Import_BINARY_DIR}/bld_generated3.c
+ )
+
+# Try linking to a library imported from the build tree.
+target_link_libraries(imp_testExe1b
+ bld_testLib2
+ bld_testLib3
+ bld_testLib4
+ bld_testLib5
+ bld_testLib6
+ bld_testLibCycleA
+ )
+
+# Try building a plugin to an executable imported from the build tree.
+add_library(imp_mod1b MODULE imp_mod1.c)
+target_link_libraries(imp_mod1b bld_testExe2)
+
+# Export/CMakeLists.txt pretends the RelWithDebInfo (as well as Debug)
+# configuration should link to debug libs.
+foreach(c DEBUG RELWITHDEBINFO)
+ set_property(TARGET imp_testExe1 PROPERTY COMPILE_DEFINITIONS_${c} EXE_DBG)
+ set_property(TARGET imp_testExe1b PROPERTY COMPILE_DEFINITIONS_${c} EXE_DBG)
+endforeach(c)
+
+#-----------------------------------------------------------------------------
+# Create a custom target to generate a header for the libraries below.
+# Drive the header generation through an indirect chain of imported
+# target dependencies.
+
+# testLib2tmp1.h
+add_custom_command(
+ OUTPUT testLib2tmp1.h
+ VERBATIM COMMAND
+ ${CMAKE_COMMAND} -E echo "extern int testLib2(void);" > testLib2tmp1.h
+ )
+
+# hdr_testLib2tmp1 needs testLib2tmp1.h
+add_custom_target(hdr_testLib2tmp1 DEPENDS testLib2tmp1.h)
+
+# exp_testExe2 needs hdr_testLib2tmp1
+add_dependencies(exp_testExe2 hdr_testLib2tmp1)
+
+# testLib2tmp.h needs exp_testExe2
+add_custom_command(
+ OUTPUT testLib2tmp.h
+ VERBATIM COMMAND exp_testExe2
+ COMMAND ${CMAKE_COMMAND} -E copy testLib2tmp1.h testLib2tmp.h
+ )
+
+# hdr_testLib2tmp needs testLib2tmp.h
+add_custom_target(hdr_testLib2tmp DEPENDS testLib2tmp.h)
+
+add_library(dep_testLib2tmp UNKNOWN IMPORTED)
+set_property(TARGET dep_testLib2tmp PROPERTY
+ IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/testLib2tmp.h)
+
+# dep_testLib2tmp needs hdr_testLib2tmp
+add_dependencies(dep_testLib2tmp hdr_testLib2tmp)
+
+# testLib2.h needs dep_testLib2tmp
+add_custom_command(
+ OUTPUT testLib2.h
+ VERBATIM COMMAND ${CMAKE_COMMAND} -E copy testLib2tmp.h testLib2.h
+ DEPENDS dep_testLib2tmp
+ )
+
+# hdr_testLib2 needs testLib2.h
+add_custom_target(hdr_testLib2 DEPENDS testLib2.h)
+
+add_library(dep_testLib2 UNKNOWN IMPORTED)
+
+# dep_testLib2 needs hdr_testLib2
+add_dependencies(dep_testLib2 hdr_testLib2)
+
+# exp_testLib2 and bld_testLib2 both need dep_testLib2
+add_dependencies(bld_testLib2 dep_testLib2)
+add_dependencies(exp_testLib2 dep_testLib2)
+
+#-----------------------------------------------------------------------------
+# Create a library to be linked by another directory in this project
+# to test transitive linking to otherwise invisible imported targets.
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+add_library(imp_lib1 STATIC imp_lib1.c)
+target_link_libraries(imp_lib1 exp_testLib2)
+add_library(imp_lib1b STATIC imp_lib1.c)
+target_link_libraries(imp_lib1b bld_testLib2)
+
+#-----------------------------------------------------------------------------
+# Test that handling imported targets, including transitive dependencies,
+# works in CheckFunctionExists (...and hopefully all other try_compile() checks
+include(CheckFunctionExists)
+unset(HAVE_TESTLIB1_FUNCTION CACHE)
+set(CMAKE_REQUIRED_LIBRARIES exp_testLib2)
+check_function_exists(testLib1 HAVE_TESTLIB1_FUNCTION)
+if (NOT HAVE_TESTLIB1_FUNCTION)
+ message(SEND_ERROR "Using imported target testLib2 in check_function_exists() failed !")
+endif()
diff --git a/Tests/ExportImport/Import/A/imp_lib1.c b/Tests/ExportImport/Import/A/imp_lib1.c
new file mode 100644
index 000000000..5b3215e99
--- /dev/null
+++ b/Tests/ExportImport/Import/A/imp_lib1.c
@@ -0,0 +1,6 @@
+#include "testLib2.h"
+
+int imp_lib1(void)
+{
+ return testLib2();
+}
diff --git a/Tests/ExportImport/Import/A/imp_mod1.c b/Tests/ExportImport/Import/A/imp_mod1.c
new file mode 100644
index 000000000..579d949c3
--- /dev/null
+++ b/Tests/ExportImport/Import/A/imp_mod1.c
@@ -0,0 +1,13 @@
+#if defined(_WIN32) || defined(__CYGWIN__)
+# define testExe2_IMPORT __declspec(dllimport)
+#else
+# define testExe2_IMPORT
+#endif
+
+testExe2_IMPORT int testExe2Func(void);
+testExe2_IMPORT int testExe2lib(void);
+
+int imp_mod1()
+{
+ return testExe2Func() + testExe2lib();
+}
diff --git a/Tests/ExportImport/Import/A/imp_testExe1.c b/Tests/ExportImport/Import/A/imp_testExe1.c
new file mode 100644
index 000000000..451998ab7
--- /dev/null
+++ b/Tests/ExportImport/Import/A/imp_testExe1.c
@@ -0,0 +1,25 @@
+extern int generated_by_testExe1();
+extern int generated_by_testExe3();
+extern int testLib2();
+extern int testLib3();
+extern int testLib4();
+extern int testLib4lib();
+extern int testLib5();
+extern int testLib6();
+extern int testLibCycleA1();
+
+/* Switch a symbol between debug and optimized builds to make sure the
+ proper library is found from the testLib4 link interface. */
+#ifdef EXE_DBG
+# define testLib4libcfg testLib4libdbg
+#else
+# define testLib4libcfg testLib4libopt
+#endif
+extern testLib4libcfg(void);
+
+int main()
+{
+ return (testLib2() + generated_by_testExe1() + testLib3() + testLib4()
+ + testLib5() + testLib6() + testLibCycleA1()
+ + generated_by_testExe3() + testLib4lib() + testLib4libcfg());
+}
diff --git a/Tests/ExportImport/Import/CMakeLists.txt b/Tests/ExportImport/Import/CMakeLists.txt
new file mode 100644
index 000000000..3fc78a280
--- /dev/null
+++ b/Tests/ExportImport/Import/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required (VERSION 2.7.20090711)
+project(Import C CXX)
+
+# Import everything in a subdirectory.
+add_subdirectory(A)
+
+# Make sure the imported targets are scoped inside the subdirectory.
+if(TARGET exp_testLib2)
+ message(FATAL_ERROR "Imported target exp_testLib2 is not scoped in subdir!")
+endif()
+if(TARGET bld_testLib2)
+ message(FATAL_ERROR "Imported target bld_testLib2 is not scoped in subdir!")
+endif()
+
+# Test transitive linking to a target imported in the subdirectory.
+add_executable(imp_testTransExe1 imp_testTransExe1.c)
+target_link_libraries(imp_testTransExe1 imp_lib1)
+add_executable(imp_testTransExe1b imp_testTransExe1.c)
+target_link_libraries(imp_testTransExe1b imp_lib1b)
diff --git a/Tests/ExportImport/Import/imp_testTransExe1.c b/Tests/ExportImport/Import/imp_testTransExe1.c
new file mode 100644
index 000000000..360a112ac
--- /dev/null
+++ b/Tests/ExportImport/Import/imp_testTransExe1.c
@@ -0,0 +1,6 @@
+extern int imp_lib1(void);
+
+int main()
+{
+ return imp_lib1();
+}
diff --git a/Tests/ExportImport/InitialCache.cmake.in b/Tests/ExportImport/InitialCache.cmake.in
new file mode 100644
index 000000000..4893f7020
--- /dev/null
+++ b/Tests/ExportImport/InitialCache.cmake.in
@@ -0,0 +1,15 @@
+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")
+SET(CMAKE_C_FLAGS_RELEASE "@CMAKE_C_FLAGS_RELEASE@" CACHE STRING "C Flags")
+SET(CMAKE_C_FLAGS_MINSIZEREL "@CMAKE_C_FLAGS_MINSIZEREL@" CACHE STRING "C Flags")
+SET(CMAKE_C_FLAGS_RELWITHDEBINFO "@CMAKE_C_FLAGS_RELWITHDEBINFO@" CACHE STRING "C Flags")
+SET(CMAKE_CXX_COMPILER "@CMAKE_CXX_COMPILER@" CACHE STRING "C++ Compiler")
+SET(CMAKE_CXX_FLAGS "@CMAKE_CXX_FLAGS@" CACHE STRING "C++ Flags")
+SET(CMAKE_CXX_FLAGS_DEBUG "@CMAKE_CXX_FLAGS_DEBUG@" CACHE STRING "C++ Flags")
+SET(CMAKE_CXX_FLAGS_RELEASE "@CMAKE_CXX_FLAGS_RELEASE@" CACHE STRING "C++ Flags")
+SET(CMAKE_CXX_FLAGS_MINSIZEREL "@CMAKE_CXX_FLAGS_MINSIZEREL@" CACHE STRING "C++ Flags")
+SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "@CMAKE_CXX_FLAGS_RELWITHDEBINFO@" CACHE STRING "C++ Flags")
+SET(CMAKE_INSTALL_PREFIX "@ExportImport_BINARY_DIR@/Root" CACHE STRING "Installation Prefix")
+SET(CMAKE_SKIP_RPATH ON CACHE BOOL "No RPATH")
+SET(CMAKE_GNUtoMS "@ExportImport_GNUtoMS@" CACHE BOOL "CMAKE_GNUtoMS")
diff --git a/Tests/ExportImport/main.c b/Tests/ExportImport/main.c
new file mode 100644
index 000000000..f8b643afb
--- /dev/null
+++ b/Tests/ExportImport/main.c
@@ -0,0 +1,4 @@
+int main()
+{
+ return 0;
+}
diff --git a/Tests/ExternalOBJ/CMakeLists.txt b/Tests/ExternalOBJ/CMakeLists.txt
new file mode 100644
index 000000000..683e7997c
--- /dev/null
+++ b/Tests/ExternalOBJ/CMakeLists.txt
@@ -0,0 +1,63 @@
+cmake_minimum_required (VERSION 2.6)
+PROJECT (ExternalOBJ)
+
+IF(APPLE)
+ # set _CMAKE_OSX_MACHINE to umame -m
+ EXEC_PROGRAM(uname ARGS -m OUTPUT_VARIABLE _CMAKE_OSX_MACHINE)
+ # check for Power PC and change to ppc
+ IF("${_CMAKE_OSX_MACHINE}" MATCHES "Power")
+ SET(_CMAKE_OSX_MACHINE ppc)
+ ENDIF("${_CMAKE_OSX_MACHINE}" MATCHES "Power")
+ SET(CMAKE_OSX_ARCHITECTURES ${_CMAKE_OSX_MACHINE})
+ENDIF(APPLE)
+
+# Build the external object file.
+TRY_COMPILE(EXTERNAL_OBJECT_BUILT
+ ${ExternalOBJ_BINARY_DIR}/Object
+ ${ExternalOBJ_SOURCE_DIR}/Object
+ Object
+ external
+ OUTPUT_VARIABLE OUTPUT
+ )
+IF(EXTERNAL_OBJECT_BUILT)
+ MESSAGE(
+ "Building external_object.cxx succeeded with the following output:\n"
+ "[${OUTPUT}]"
+ )
+ELSE(EXTERNAL_OBJECT_BUILT)
+ MESSAGE(FATAL_ERROR
+ "Building external_object.cxx failed with the following output:\n"
+ "[${OUTPUT}]"
+ )
+ENDIF(EXTERNAL_OBJECT_BUILT)
+
+# Find the external object file.
+SET(DIR ${ExternalOBJ_BINARY_DIR}/Object)
+FILE(GLOB_RECURSE EXTERNAL_OBJECT
+ "${DIR}/external_object*${CMAKE_CXX_OUTPUT_EXTENSION}")
+IF(EXTERNAL_OBJECT)
+ LIST (GET EXTERNAL_OBJECT 0 EXTERNAL_OBJECT)
+ MESSAGE("Found \"${EXTERNAL_OBJECT}\".")
+ELSE(EXTERNAL_OBJECT)
+ MESSAGE(FATAL_ERROR "Could not find external object.")
+ENDIF(EXTERNAL_OBJECT)
+
+# Test creation of external objects by custom commands.
+SET(CUSTOM_OBJECT
+ ${CMAKE_CURRENT_BINARY_DIR}/custom_object${CMAKE_C_OUTPUT_EXTENSION})
+ADD_CUSTOM_COMMAND(
+ OUTPUT ${CUSTOM_OBJECT}
+ COMMAND ${CMAKE_COMMAND} -E copy ${EXTERNAL_OBJECT} ${CUSTOM_OBJECT}
+ DEPENDS ${EXTERNAL_OBJECT}
+ )
+
+message("${EXTERNAL_OBJECT}")
+# Build an executable using the external object file.
+ADD_EXECUTABLE(ExternalOBJ executable.cxx ${CUSTOM_OBJECT})
+# A bug showed up in VS2010 where an object file that was
+# part of a custom commad output worked, but ones that were
+# not didn't work. So, repeat the executable using the object
+# directly and not from the output of the copy.
+ADD_EXECUTABLE(ExternalOBJ2 executable.cxx ${EXTERNAL_OBJECT})
+
+ADD_SUBDIRECTORY(Sub)
diff --git a/Tests/ExternalOBJ/Object/CMakeLists.txt b/Tests/ExternalOBJ/Object/CMakeLists.txt
new file mode 100644
index 000000000..6f1d7e3fb
--- /dev/null
+++ b/Tests/ExternalOBJ/Object/CMakeLists.txt
@@ -0,0 +1,13 @@
+cmake_minimum_required (VERSION 2.6)
+PROJECT(Object)
+IF(APPLE)
+ # set _CMAKE_OSX_MACHINE to umame -m
+ EXEC_PROGRAM(uname ARGS -m OUTPUT_VARIABLE _CMAKE_OSX_MACHINE)
+ # check for Power PC and change to ppc
+ IF("${_CMAKE_OSX_MACHINE}" MATCHES "Power")
+ SET(_CMAKE_OSX_MACHINE ppc)
+ ENDIF("${_CMAKE_OSX_MACHINE}" MATCHES "Power")
+ SET(CMAKE_OSX_ARCHITECTURES ${_CMAKE_OSX_MACHINE})
+ENDIF(APPLE)
+
+ADD_EXECUTABLE(external external_object.cxx external_main.cxx)
diff --git a/Tests/ExternalOBJ/Object/external_main.cxx b/Tests/ExternalOBJ/Object/external_main.cxx
new file mode 100644
index 000000000..f8b643afb
--- /dev/null
+++ b/Tests/ExternalOBJ/Object/external_main.cxx
@@ -0,0 +1,4 @@
+int main()
+{
+ return 0;
+}
diff --git a/Tests/ExternalOBJ/Object/external_object.cxx b/Tests/ExternalOBJ/Object/external_object.cxx
new file mode 100644
index 000000000..5b4adaf0c
--- /dev/null
+++ b/Tests/ExternalOBJ/Object/external_object.cxx
@@ -0,0 +1,4 @@
+int external_object_function()
+{
+ return 0;
+}
diff --git a/Tests/ExternalOBJ/Sub/CMakeLists.txt b/Tests/ExternalOBJ/Sub/CMakeLists.txt
new file mode 100644
index 000000000..35cd30c7d
--- /dev/null
+++ b/Tests/ExternalOBJ/Sub/CMakeLists.txt
@@ -0,0 +1,3 @@
+set_property(SOURCE ${CUSTOM_OBJECT} PROPERTY GENERATED 1)
+add_executable(ExternalOBJSub ../executable.cxx ${CUSTOM_OBJECT})
+add_dependencies(ExternalOBJSub ExternalOBJ) # depend on generating target
diff --git a/Tests/ExternalOBJ/executable.cxx b/Tests/ExternalOBJ/executable.cxx
new file mode 100644
index 000000000..f9ec61df5
--- /dev/null
+++ b/Tests/ExternalOBJ/executable.cxx
@@ -0,0 +1,5 @@
+extern int external_object_function();
+int main()
+{
+ return external_object_function();
+}
diff --git a/Tests/ExternalProject/CMakeLists.txt b/Tests/ExternalProject/CMakeLists.txt
new file mode 100644
index 000000000..7a7626199
--- /dev/null
+++ b/Tests/ExternalProject/CMakeLists.txt
@@ -0,0 +1,585 @@
+cmake_minimum_required(VERSION 2.8)
+project(ExternalProjectTest NONE)
+
+include(ExternalProject)
+
+find_package(CVS)
+find_package(Subversion)
+find_package(Git)
+
+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}/CMakeExternals")
+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()
+
+
+# Empty projects that test all the known ExternalProject_Add argument key words:
+#
+set(proj AAA-TestAlphabetization)
+ExternalProject_Add(${proj}
+ BUILD_COMMAND ""
+ CONFIGURE_COMMAND ""
+ DOWNLOAD_COMMAND ""
+ INSTALL_COMMAND ""
+)
+
+set(proj ZZZ-TestAlphabetization)
+ExternalProject_Add(${proj}
+ BUILD_COMMAND ""
+ CONFIGURE_COMMAND ""
+ DOWNLOAD_COMMAND ""
+ INSTALL_COMMAND ""
+)
+
+set(proj TargetNameSameAsFolder)
+ExternalProject_Add(${proj}
+ BUILD_COMMAND ""
+ CONFIGURE_COMMAND ""
+ DOWNLOAD_COMMAND ""
+ INSTALL_COMMAND ""
+)
+set_property(TARGET ${proj} PROPERTY FOLDER "${proj}")
+
+set(proj MinimalNoOpProject)
+ExternalProject_Add(${proj}
+ BUILD_COMMAND ""
+ CONFIGURE_COMMAND ""
+ DOWNLOAD_COMMAND ""
+ INSTALL_COMMAND ""
+)
+
+set(proj EmptyNoOpProject)
+ExternalProject_Add(${proj}
+ BUILD_COMMAND ""
+ CMAKE_ARGS ""
+ CONFIGURE_COMMAND ""
+ CVS_REPOSITORY ""
+ CVS_MODULE ""
+ CVS_TAG ""
+ DEPENDS "MinimalNoOpProject"
+ DOWNLOAD_COMMAND ""
+ INSTALL_COMMAND ""
+ PATCH_COMMAND ""
+ STEP_TARGETS install update
+ SVN_REPOSITORY ""
+ SVN_REVISION ""
+ SVN_USERNAME ""
+ SVN_PASSWORD ""
+ SVN_TRUST_CERT 1
+ TEST_COMMAND ""
+ TIMEOUT ""
+ URL ""
+ URL_MD5 ""
+ UPDATE_COMMAND ""
+)
+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_MD5 0b8182edcecdf40bf1c9d71d7d259f78
+ 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)
+
+if(CVS_EXECUTABLE)
+ set(do_cvs_tests 1)
+endif()
+
+if(do_cvs_tests AND NOT UNIX)
+ if("${CVS_EXECUTABLE}" MATCHES "cygwin")
+ message(STATUS "No ExternalProject cvs tests with cygwin cvs.exe outside cygwin!")
+ set(do_cvs_tests 0)
+ endif()
+endif()
+
+if(do_cvs_tests)
+ # Unzip/untar the CVS repository in our source folder so that other
+ # projects below may use it to test CVS args of ExternalProject_Add
+ #
+ set(proj SetupLocalCVSRepository)
+ set(local_cvs_repo "${CMAKE_CURRENT_BINARY_DIR}/LocalRepositories/CVS")
+ ExternalProject_Add(${proj}
+ SOURCE_DIR ${local_cvs_repo}
+ URL ${CMAKE_CURRENT_SOURCE_DIR}/cvsrepo.tgz
+ URL_MD5 55fc85825ffdd9ed2597123c68b79f7e
+ BUILD_COMMAND ""
+ CONFIGURE_COMMAND "${CVS_EXECUTABLE}" --version
+ INSTALL_COMMAND ""
+ )
+ set_property(TARGET ${proj}
+ PROPERTY FOLDER "SetupRepos/Local/Deeply/Nested/For/Testing")
+
+ # The MSYS cvs tool interprets "c:/" as a "machine:" name for SSH.
+ # Detect the MSYS cvs and convert the repo path to an MSYS path.
+ if(WIN32)
+ if(EXISTS "${CVS_EXECUTABLE}")
+ file(STRINGS "${CVS_EXECUTABLE}" cvs_is_msys LIMIT_COUNT 1 REGEX "[Mm][Ss][Yy][Ss]")
+ if(cvs_is_msys)
+ message(STATUS "'${CVS_EXECUTABLE}' is from MSYS (contains '${cvs_is_msys}')")
+ string(REGEX REPLACE "^([A-Za-z]):" "/\\1" local_cvs_repo "${local_cvs_repo}")
+ endif()
+ endif()
+ endif()
+
+ # CVS by date stamp:
+ #
+ set(proj TutorialStep1-CVS-20090626)
+ ExternalProject_Add(${proj}
+ CVS_REPOSITORY "${local_cvs_repo}"
+ CVS_MODULE "TutorialStep1"
+ CVS_TAG "-D2009-06-26 16:50:00 UTC"
+ UPDATE_COMMAND ""
+ CMAKE_GENERATOR "${CMAKE_GENERATOR}"
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
+ INSTALL_COMMAND ""
+ DEPENDS "SetupLocalCVSRepository"
+ )
+ set_property(TARGET ${proj} PROPERTY FOLDER "CVS")
+
+ # CVS by tag:
+ #
+ set(proj TutorialStep1-CVS-testtag1)
+ ExternalProject_Add(${proj}
+ CVS_REPOSITORY "${local_cvs_repo}"
+ CVS_MODULE "TutorialStep1"
+ CVS_TAG -rtesttag1
+ UPDATE_COMMAND ""
+ CMAKE_GENERATOR "${CMAKE_GENERATOR}"
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
+ INSTALL_COMMAND ""
+ DEPENDS "SetupLocalCVSRepository"
+ )
+ set_property(TARGET ${proj} PROPERTY FOLDER "CVS")
+
+ # Live CVS / HEAD (no CVS_TAG):
+ #
+ set(proj TutorialStep1-CVS-HEAD)
+ ExternalProject_Add(${proj}
+ CVS_REPOSITORY "${local_cvs_repo}"
+ CVS_MODULE "TutorialStep1"
+ CMAKE_GENERATOR "${CMAKE_GENERATOR}"
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
+ 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"
+ )
+ set_property(TARGET ${proj} PROPERTY FOLDER "CVS")
+endif()
+
+
+# SVN-based tests:
+#
+set(do_svn_tests 0)
+
+if(Subversion_SVN_EXECUTABLE)
+ set(do_svn_tests 1)
+endif()
+
+# Only do svn tests with svn >= version 1.2
+#
+if(do_svn_tests)
+ if(Subversion_VERSION_SVN VERSION_LESS 1.2)
+ message(STATUS "No ExternalProject svn tests with svn client less than version 1.2")
+ set(do_svn_tests 0)
+ endif()
+endif()
+
+# Only do svn tests in cygwin/cygwin or not-cygwin/not-cygwin arrangements:
+#
+if(do_svn_tests)
+ if(CMAKE_CURRENT_BINARY_DIR MATCHES "cygdrive/" AND
+ NOT "${Subversion_SVN_EXECUTABLE}" MATCHES "cygwin")
+ message(STATUS "No ExternalProject svn tests with non-cygwin svn client in a /cygdrive based build")
+ set(do_svn_tests 0)
+ endif()
+endif()
+
+if(do_svn_tests)
+ # Unzip/untar the SVN repository in our source folder so that other
+ # projects below may use it to test SVN args of ExternalProject_Add
+ #
+ set(proj SetupLocalSVNRepository)
+ set(local_svn_repo "${CMAKE_CURRENT_BINARY_DIR}/LocalRepositories/SVN")
+ set(local_svn_repo_url "file:///${local_svn_repo}/TutorialStep1")
+ ExternalProject_Add(${proj}
+ SOURCE_DIR ${local_svn_repo}
+ URL ${CMAKE_CURRENT_SOURCE_DIR}/svnrepo.tgz
+ URL_MD5 2f468be4ed1fa96377fca0cc830819c4
+ BUILD_COMMAND ""
+ CONFIGURE_COMMAND "${Subversion_SVN_EXECUTABLE}" --version
+ INSTALL_COMMAND ""
+ )
+ set_property(TARGET ${proj}
+ PROPERTY FOLDER "SetupRepos/Local/Deeply/Nested/For/Testing")
+
+ # SVN by date stamp:
+ #
+ set(proj TutorialStep1-SVN-20090626)
+ ExternalProject_Add(${proj}
+ SVN_REPOSITORY "${local_svn_repo_url}"
+ SVN_REVISION "-r{2009-06-26 16:50:00 +0000}"
+ UPDATE_COMMAND ""
+ CMAKE_GENERATOR "${CMAKE_GENERATOR}"
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
+ INSTALL_COMMAND ""
+ DEPENDS "SetupLocalSVNRepository"
+ )
+ set_property(TARGET ${proj} PROPERTY FOLDER "SVN")
+
+ # SVN by revision number:
+ #
+ set(proj TutorialStep1-SVN-r2)
+ ExternalProject_Add(${proj}
+ SVN_REPOSITORY "${local_svn_repo_url}"
+ SVN_REVISION "-r2"
+ UPDATE_COMMAND ""
+ CMAKE_GENERATOR "${CMAKE_GENERATOR}"
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
+ INSTALL_COMMAND ""
+ DEPENDS "SetupLocalSVNRepository"
+ )
+ set_property(TARGET ${proj} PROPERTY FOLDER "SVN")
+
+ # Live SVN / trunk (no SVN_REVISION):
+ #
+ set(proj TutorialStep1-SVN-trunk)
+ ExternalProject_Add(${proj}
+ SVN_REPOSITORY "${local_svn_repo_url}"
+ CMAKE_GENERATOR "${CMAKE_GENERATOR}"
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
+ INSTALL_COMMAND ""
+ DEPENDS "SetupLocalSVNRepository"
+ LOG_DOWNLOAD 1
+ )
+ set_property(TARGET ${proj} PROPERTY FOLDER "SVN")
+endif()
+
+
+set(do_git_tests 0)
+
+if(GIT_EXECUTABLE)
+ set(do_git_tests 1)
+
+ execute_process(
+ COMMAND "${GIT_EXECUTABLE}" --version
+ OUTPUT_VARIABLE ov
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+ string(REGEX REPLACE "^git version (.+)$" "\\1" git_version "${ov}")
+ message(STATUS "git_version='${git_version}'")
+
+ if(git_version VERSION_LESS 1.6.5)
+ message(STATUS "No ExternalProject git tests with git client less than version 1.6.5")
+ set(do_git_tests 0)
+ endif()
+endif()
+
+
+if(do_git_tests)
+ set(local_git_repo "../../LocalRepositories/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 SetupLocalGITRepository)
+ ExternalProject_Add(${proj}
+ SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/LocalRepositories/GIT
+ URL ${CMAKE_CURRENT_SOURCE_DIR}/gitrepo.tgz
+ BUILD_COMMAND ""
+ CONFIGURE_COMMAND "${GIT_EXECUTABLE}" --version
+ INSTALL_COMMAND ""
+ )
+ set_property(TARGET ${proj}
+ PROPERTY FOLDER "SetupRepos/Local/Deeply/Nested/For/Testing")
+
+ # git by commit id:
+ #
+ set(proj TutorialStep1-GIT-byhash)
+ ExternalProject_Add(${proj}
+ GIT_REPOSITORY "${local_git_repo}"
+ GIT_TAG d1970730310fe8bc07e73f15dc570071f9f9654a
+ 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")
+
+ # git by explicit branch/tag name:
+ #
+ set(proj TutorialStep1-GIT-bytag)
+ ExternalProject_Add(${proj}
+ GIT_REPOSITORY "${local_git_repo}"
+ GIT_TAG "origin/master"
+ 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")
+
+ # Live git / master (no GIT_TAG):
+ #
+ set(proj TutorialStep1-GIT-master)
+ ExternalProject_Add(${proj}
+ GIT_REPOSITORY "${local_git_repo}"
+ CMAKE_GENERATOR "${CMAKE_GENERATOR}"
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
+ INSTALL_COMMAND ""
+ DEPENDS "SetupLocalGITRepository"
+ LOG_UPDATE 1
+ )
+ set_property(TARGET ${proj} PROPERTY FOLDER "GIT")
+endif()
+
+
+# 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)
+
+if(do_cvs_tests)
+ add_test(TutorialStep1-CVS-20090626-BuildTreeTest
+ "${binary_base}/TutorialStep1-CVS-20090626/Tutorial" 4)
+
+ add_test(TutorialStep1-CVS-testtag1-BuildTreeTest
+ "${binary_base}/TutorialStep1-CVS-testtag1/Tutorial" 64)
+
+ add_test(TutorialStep1-CVS-HEAD-BuildTreeTest
+ "${binary_base}/TutorialStep1-CVS-HEAD/Tutorial" 81)
+endif()
+
+if(do_svn_tests)
+ add_test(TutorialStep1-SVN-20090626-BuildTreeTest
+ "${binary_base}/TutorialStep1-SVN-20090626/Tutorial" 100)
+
+ add_test(TutorialStep1-SVN-r2-BuildTreeTest
+ "${binary_base}/TutorialStep1-SVN-r2/Tutorial" 99)
+
+ add_test(TutorialStep1-SVN-trunk-BuildTreeTest
+ "${binary_base}/TutorialStep1-SVN-trunk/Tutorial" 98)
+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}'")
+message(STATUS "GIT_EXECUTABLE='${GIT_EXECUTABLE}'")
diff --git a/Tests/ExternalProject/Example/CMakeLists.txt b/Tests/ExternalProject/Example/CMakeLists.txt
new file mode 100644
index 000000000..69ebaaf51
--- /dev/null
+++ b/Tests/ExternalProject/Example/CMakeLists.txt
@@ -0,0 +1,11 @@
+# This is the canonical simplest ExternalProject example CMakeLists.txt file:
+cmake_minimum_required(VERSION 2.8)
+project(ExternalProjectExample NONE)
+include(ExternalProject)
+
+ExternalProject_Add(
+ cmake281
+ URL http://www.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/Step1.tar b/Tests/ExternalProject/Step1.tar
new file mode 100644
index 000000000..3711f07fb
--- /dev/null
+++ b/Tests/ExternalProject/Step1.tar
Binary files differ
diff --git a/Tests/ExternalProject/Step1.tar.bz2 b/Tests/ExternalProject/Step1.tar.bz2
new file mode 100644
index 000000000..49b5f23a6
--- /dev/null
+++ b/Tests/ExternalProject/Step1.tar.bz2
Binary files differ
diff --git a/Tests/ExternalProject/Step1.tgz b/Tests/ExternalProject/Step1.tgz
new file mode 100644
index 000000000..d9b4cd259
--- /dev/null
+++ b/Tests/ExternalProject/Step1.tgz
Binary files differ
diff --git a/Tests/ExternalProject/Step1.zip b/Tests/ExternalProject/Step1.zip
new file mode 100644
index 000000000..49dac24ed
--- /dev/null
+++ b/Tests/ExternalProject/Step1.zip
Binary files differ
diff --git a/Tests/ExternalProject/Step1NoDir.tar b/Tests/ExternalProject/Step1NoDir.tar
new file mode 100644
index 000000000..03664b856
--- /dev/null
+++ b/Tests/ExternalProject/Step1NoDir.tar
Binary files differ
diff --git a/Tests/ExternalProject/Step1NoDir.tar.bz2 b/Tests/ExternalProject/Step1NoDir.tar.bz2
new file mode 100644
index 000000000..92eb480d6
--- /dev/null
+++ b/Tests/ExternalProject/Step1NoDir.tar.bz2
Binary files differ
diff --git a/Tests/ExternalProject/Step1NoDir.tgz b/Tests/ExternalProject/Step1NoDir.tgz
new file mode 100644
index 000000000..71a2d8142
--- /dev/null
+++ b/Tests/ExternalProject/Step1NoDir.tgz
Binary files differ
diff --git a/Tests/ExternalProject/Step1NoDir.zip b/Tests/ExternalProject/Step1NoDir.zip
new file mode 100644
index 000000000..b42d31879
--- /dev/null
+++ b/Tests/ExternalProject/Step1NoDir.zip
Binary files differ
diff --git a/Tests/ExternalProject/Step1Patch.cmake b/Tests/ExternalProject/Step1Patch.cmake
new file mode 100644
index 000000000..35e09d948
--- /dev/null
+++ b/Tests/ExternalProject/Step1Patch.cmake
@@ -0,0 +1,25 @@
+# Verify the current working directory.
+if(NOT EXISTS CMakeLists.txt)
+ message(FATAL_ERROR "File does not exist:\n ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt")
+endif()
+if(NOT EXISTS tutorial.cxx)
+ message(FATAL_ERROR "File does not exist:\n ${CMAKE_CURRENT_SOURCE_DIR}/tutorial.cxx")
+endif()
+
+# Check if the patch is already applied.
+file(STRINGS CMakeLists.txt prop_line REGEX "^set_property")
+if(prop_line)
+ message(STATUS "Patch already applied!")
+ return()
+endif()
+
+# Apply the patch.
+file(APPEND CMakeLists.txt "
+# Patch by ExternalProject test:
+set_property(TARGET Tutorial PROPERTY OUTPUT_NAME EP-Tutorial)
+list(LENGTH TEST_LIST len)
+if(NOT len EQUAL 3)
+ message(FATAL_ERROR \"TEST_LIST length is \${len}, not 3\")
+endif()
+")
+message(STATUS "Patched ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt")
diff --git a/Tests/ExternalProject/TryCheckout.cmake b/Tests/ExternalProject/TryCheckout.cmake
new file mode 100644
index 000000000..de069ebe4
--- /dev/null
+++ b/Tests/ExternalProject/TryCheckout.cmake
@@ -0,0 +1,54 @@
+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(try_cvs_checkout)
+
+
+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(try_svn_checkout)
diff --git a/Tests/ExternalProject/cvsrepo.tgz b/Tests/ExternalProject/cvsrepo.tgz
new file mode 100644
index 000000000..baba6d3c2
--- /dev/null
+++ b/Tests/ExternalProject/cvsrepo.tgz
Binary files differ
diff --git a/Tests/ExternalProject/gitrepo.tgz b/Tests/ExternalProject/gitrepo.tgz
new file mode 100644
index 000000000..0a84bda7c
--- /dev/null
+++ b/Tests/ExternalProject/gitrepo.tgz
Binary files differ
diff --git a/Tests/ExternalProject/svnrepo.tgz b/Tests/ExternalProject/svnrepo.tgz
new file mode 100644
index 000000000..b8484165e
--- /dev/null
+++ b/Tests/ExternalProject/svnrepo.tgz
Binary files differ
diff --git a/Tests/FindModulesExecuteAll/CMakeLists.txt b/Tests/FindModulesExecuteAll/CMakeLists.txt
new file mode 100644
index 000000000..df5162652
--- /dev/null
+++ b/Tests/FindModulesExecuteAll/CMakeLists.txt
@@ -0,0 +1,30 @@
+# This file includes all FindXXX.cmake modules, so they are all executed.
+# As it is it doesn't test a lot.
+# It makes sure that the modules don't contain basic syntax errors.
+# It also makes sure that modules don't fail with an error if something
+# wasn't found but REQUIRED was not given.
+#
+# I guess more things could be added, like checking whether variables are
+# defined after running the modules (e.g. FOO_FOUND etc.).
+project(FindModulesExecuteAll)
+cmake_minimum_required(VERSION 2.7)
+
+file(GLOB all_modules "${CMAKE_CURRENT_SOURCE_DIR}/../../Modules/Find*cmake")
+
+foreach(module ${all_modules})
+ message(STATUS "module: ${module}")
+ include("${module}")
+
+ # get the "basename" of the package, so the existence of variables like
+ # FOO_FOUND could be tested later on, Alex
+ string(REGEX REPLACE ".+Find([^\\.]+)\\.cmake" "\\1" packageName "${module}")
+ string(TOUPPER "${packageName}" packageNameUpper)
+
+# disabled for now, since too many modules break:
+# if(NOT DEFINED ${packageNameUpper}_FOUND)
+# message(SEND_ERROR "${packageNameUpper}_FOUND not defined !")
+# endif(NOT DEFINED ${packageNameUpper}_FOUND)
+
+endforeach(module ${all_modules})
+
+add_executable(FindModulesExecuteAll main.c)
diff --git a/Tests/FindModulesExecuteAll/main.c b/Tests/FindModulesExecuteAll/main.c
new file mode 100644
index 000000000..c13815cea
--- /dev/null
+++ b/Tests/FindModulesExecuteAll/main.c
@@ -0,0 +1,4 @@
+int main()
+{
+ return 0;
+}
diff --git a/Tests/FindPackageModeMakefileTest/CMakeLists.txt b/Tests/FindPackageModeMakefileTest/CMakeLists.txt
new file mode 100644
index 000000000..3674f0efe
--- /dev/null
+++ b/Tests/FindPackageModeMakefileTest/CMakeLists.txt
@@ -0,0 +1,31 @@
+
+
+if(UNIX AND "${CMAKE_GENERATOR}" MATCHES "Makefile")
+
+ # Test whether the make is GNU make, and only add the test in this case,
+ # since the configured makefile in this test uses $(shell ...), which
+ # is AFAIK a GNU make extension. Alex
+ execute_process(COMMAND ${CMAKE_MAKE_PROGRAM} -v
+ OUTPUT_VARIABLE makeVersionOutput
+ ERROR_QUIET
+ TIMEOUT 10)
+ string(TOUPPER "${makeVersionOutput}" MAKE_VERSION_OUTPUT)
+ if("${MAKE_VERSION_OUTPUT}" MATCHES ".*GNU MAKE.*")
+
+ # build a library which we can search during the test
+ add_library(foo STATIC foo.cpp)
+
+ # configure a FindFoo.cmake so it knows where the library can be found
+ configure_file(FindFoo.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/FindFoo.cmake @ONLY)
+
+ # now set up the test:
+ get_target_property(cmakeExecutable cmake LOCATION)
+
+ 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)
+
+ add_test(FindPackageModeMakefileTest ${CMAKE_MAKE_PROGRAM} -f ${CMAKE_CURRENT_BINARY_DIR}/ConfMakefile )
+
+ endif()
+
+endif()
diff --git a/Tests/FindPackageModeMakefileTest/FindFoo.cmake.in b/Tests/FindPackageModeMakefileTest/FindFoo.cmake.in
new file mode 100644
index 000000000..dc62bac41
--- /dev/null
+++ b/Tests/FindPackageModeMakefileTest/FindFoo.cmake.in
@@ -0,0 +1,9 @@
+
+find_library(FOO_LIBRARY NAMES foo HINTS "@CMAKE_CURRENT_BINARY_DIR@" )
+find_path(FOO_INCLUDE_DIR NAMES foo.h HINTS "@CMAKE_CURRENT_SOURCE_DIR@" )
+
+set(FOO_LIBRARIES ${FOO_LIBRARY})
+set(FOO_INCLUDE_DIRS "${FOO_INCLUDE_DIR}" "/some/path/with a space/include" )
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Foo DEFAULT_MSG FOO_LIBRARY FOO_INCLUDE_DIR )
diff --git a/Tests/FindPackageModeMakefileTest/Makefile.in b/Tests/FindPackageModeMakefileTest/Makefile.in
new file mode 100644
index 000000000..f647901e7
--- /dev/null
+++ b/Tests/FindPackageModeMakefileTest/Makefile.in
@@ -0,0 +1,29 @@
+CMAKE = "@cmakeExecutable@"
+CMAKE_CURRENT_BINARY_DIR = "@CMAKE_CURRENT_BINARY_DIR@"
+CMAKE_CXX_COMPILER = "@CMAKE_CXX_COMPILER@"
+CMAKE_CXX_COMPILER_ID = "@CMAKE_CXX_COMPILER_ID@"
+
+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
+
+main.o: main.cpp
+ @$(CMAKE_FOO) -DMODE=COMPILE >$(tmp)
+ @foo="`cat $(tmp)`"; \
+ printf '"%s" %s %s -c main.cpp\n' $(CMAKE_CXX_COMPILER) "$(CXXFLAGS)" "$$foo" >$(tmp)
+ @cat $(tmp)
+ @sh $(tmp)
+ @rm -f $(tmp)
+
+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)
+ @cat $(tmp)
+ @sh $(tmp)
+ @rm -f $(tmp)
+
+clean:
+ rm -f $(tmp) *.o pngtest
diff --git a/Tests/FindPackageModeMakefileTest/foo.cpp b/Tests/FindPackageModeMakefileTest/foo.cpp
new file mode 100644
index 000000000..6aea22629
--- /dev/null
+++ b/Tests/FindPackageModeMakefileTest/foo.cpp
@@ -0,0 +1,4 @@
+int foo()
+{
+ return 1477;
+}
diff --git a/Tests/FindPackageModeMakefileTest/foo.h b/Tests/FindPackageModeMakefileTest/foo.h
new file mode 100644
index 000000000..4ec598ad5
--- /dev/null
+++ b/Tests/FindPackageModeMakefileTest/foo.h
@@ -0,0 +1,6 @@
+#ifndef FOO_H
+#define FOO_H
+
+int foo();
+
+#endif
diff --git a/Tests/FindPackageModeMakefileTest/main.cpp b/Tests/FindPackageModeMakefileTest/main.cpp
new file mode 100644
index 000000000..e5f9134ce
--- /dev/null
+++ b/Tests/FindPackageModeMakefileTest/main.cpp
@@ -0,0 +1,8 @@
+#include <stdio.h>
+#include <foo.h>
+
+int main()
+{
+ printf("foo is: %d\n", foo());
+ return 0;
+}
diff --git a/Tests/FindPackageTest/A/wibble-config.cmake b/Tests/FindPackageTest/A/wibble-config.cmake
new file mode 100644
index 000000000..deffa5729
--- /dev/null
+++ b/Tests/FindPackageTest/A/wibble-config.cmake
@@ -0,0 +1 @@
+# Test config file.
diff --git a/Tests/FindPackageTest/B/wibble-config.cmake b/Tests/FindPackageTest/B/wibble-config.cmake
new file mode 100644
index 000000000..deffa5729
--- /dev/null
+++ b/Tests/FindPackageTest/B/wibble-config.cmake
@@ -0,0 +1 @@
+# Test config file.
diff --git a/Tests/FindPackageTest/Baz 1.1/BazConfig.cmake b/Tests/FindPackageTest/Baz 1.1/BazConfig.cmake
new file mode 100644
index 000000000..deffa5729
--- /dev/null
+++ b/Tests/FindPackageTest/Baz 1.1/BazConfig.cmake
@@ -0,0 +1 @@
+# Test config file.
diff --git a/Tests/FindPackageTest/Baz 1.1/BazConfigVersion.cmake b/Tests/FindPackageTest/Baz 1.1/BazConfigVersion.cmake
new file mode 100644
index 000000000..321fa118e
--- /dev/null
+++ b/Tests/FindPackageTest/Baz 1.1/BazConfigVersion.cmake
@@ -0,0 +1,8 @@
+SET(PACKAGE_VERSION 1.1)
+IF("${PACKAGE_FIND_VERSION_MAJOR}" EQUAL 1)
+ SET(PACKAGE_VERSION_COMPATIBLE 1)
+ IF("${PACKAGE_FIND_VERSION_MINOR}" EQUAL 1)
+ SET(PACKAGE_VERSION_EXACT 1)
+ ENDIF("${PACKAGE_FIND_VERSION_MINOR}" EQUAL 1)
+ENDIF("${PACKAGE_FIND_VERSION_MAJOR}" EQUAL 1)
+
diff --git a/Tests/FindPackageTest/Baz 1.2/CMake/BazConfig.cmake b/Tests/FindPackageTest/Baz 1.2/CMake/BazConfig.cmake
new file mode 100644
index 000000000..deffa5729
--- /dev/null
+++ b/Tests/FindPackageTest/Baz 1.2/CMake/BazConfig.cmake
@@ -0,0 +1 @@
+# Test config file.
diff --git a/Tests/FindPackageTest/Baz 1.2/CMake/BazConfigVersion.cmake b/Tests/FindPackageTest/Baz 1.2/CMake/BazConfigVersion.cmake
new file mode 100644
index 000000000..4576809f5
--- /dev/null
+++ b/Tests/FindPackageTest/Baz 1.2/CMake/BazConfigVersion.cmake
@@ -0,0 +1,8 @@
+SET(PACKAGE_VERSION 1.2)
+IF("${PACKAGE_FIND_VERSION_MAJOR}" EQUAL 1)
+ SET(PACKAGE_VERSION_COMPATIBLE 1)
+ IF("${PACKAGE_FIND_VERSION_MINOR}" EQUAL 2)
+ SET(PACKAGE_VERSION_EXACT 1)
+ ENDIF("${PACKAGE_FIND_VERSION_MINOR}" EQUAL 2)
+ENDIF("${PACKAGE_FIND_VERSION_MAJOR}" EQUAL 1)
+
diff --git a/Tests/FindPackageTest/CMakeLists.txt b/Tests/FindPackageTest/CMakeLists.txt
new file mode 100644
index 000000000..e85fb4dd2
--- /dev/null
+++ b/Tests/FindPackageTest/CMakeLists.txt
@@ -0,0 +1,533 @@
+cmake_minimum_required (VERSION 2.6)
+PROJECT(FindPackageTest)
+
+LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR})
+
+# Look for a package which uses FindPackageHandleStandardArgs.cmake with the
+# new (as of cmake 2.8.3) syntax. This works only if CMP0017 is set to NEW,
+# because otherwise FindPackageHandleStandardArgs.cmake from the current
+# directory is included (via CMAKE_MODULE_PATH).
+CMAKE_POLICY(SET CMP0017 NEW)
+FIND_PACKAGE(ZLIB QUIET)
+
+# Look for a package that has a find module and may be found.
+FIND_PACKAGE(OpenGL QUIET)
+
+# Look for a package that has no find module and will not be found.
+FIND_PACKAGE(NotAPackage QUIET)
+
+# Look for a package that has an advanced find module.
+FIND_PACKAGE(VTK QUIET)
+
+ADD_EXECUTABLE(FindPackageTest FindPackageTest.cxx)
+
+# test behaviour of cmFindBase wrt. the CMAKE_PREFIX_PATH variable
+# foo.h should be found in ${CMAKE_CURRENT_SOURCE_DIR}/include:
+
+SET(CMAKE_PREFIX_PATH /blub /blah "${CMAKE_CURRENT_SOURCE_DIR}")
+FIND_PATH(FOO_DIR foo.h)
+
+IF(NOT FOO_DIR)
+ MESSAGE(FATAL_ERROR "Did not find foo.h which is in ${CMAKE_CURRENT_SOURCE_DIR}/include
+ CMAKE_PREFIX_PATH = ${CMAKE_PREFIX_PATH}")
+ENDIF(NOT FOO_DIR)
+
+FIND_PACKAGE(VersionTestA 1)
+FIND_PACKAGE(VersionTestB 1.2)
+FIND_PACKAGE(VersionTestC 1.2.3)
+FIND_PACKAGE(VersionTestD 1.2.3.4)
+
+
+FIND_PACKAGE(LotsOfComponents COMPONENTS AComp OPTIONAL_COMPONENTS BComp CComp)
+IF(NOT LOTSOFCOMPONENTS_FOUND)
+ MESSAGE(SEND_ERROR "LotsOfComponents not found !")
+ENDIF()
+
+#-----------------------------------------------------------------------------
+# Test system package registry if possible.
+SET(CMakeTestSystemPackage "")
+IF(WIN32 AND NOT CYGWIN)
+ # Try writing a value to the system package registry.
+ SET(_data "${FindPackageTest_SOURCE_DIR}/SystemPackage")
+ SET(_key "HKLM\\Software\\Kitware\\CMake\\Packages\\CMakeTestSystemPackage")
+ SET(_file "${FindPackageTest_BINARY_DIR}/CMakeTestSystemPackage.data")
+ FILE(WRITE ${_file} "${_data}\n")
+ EXECUTE_PROCESS(
+ COMMAND ${CMAKE_COMMAND} -E md5sum ${_file}
+ OUTPUT_VARIABLE _output ERROR_VARIABLE _error RESULT_VARIABLE _failed
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+ STRING(REGEX REPLACE " .*" "" _value "${_output}")
+ IF(NOT _failed AND _value)
+ EXECUTE_PROCESS(
+ COMMAND reg add "${_key}" /v "${_value}" /t REG_SZ /d "${_data}" /f
+ OUTPUT_VARIABLE _output ERROR_VARIABLE _output RESULT_VARIABLE _failed
+ )
+ ENDIF()
+ # If the above worked, add the rest of the test and a rule to
+ # cleanup the value.
+ IF(NOT _failed)
+ MESSAGE(STATUS "HKLM is writable: enabling CMakeTestSystemPackage")
+ SET(CMakeTestSystemPackage_CLEANUP reg delete "${_key}" /v "${_value}" /f)
+ SET(CMakeTestSystemPackage CMakeTestSystemPackage)
+ ELSE()
+ MESSAGE(STATUS "HKLM is readonly: disabling CMakeTestSystemPackage")
+ ENDIF()
+ENDIF()
+
+#-----------------------------------------------------------------------------
+
+#SET(CMAKE_FIND_DEBUG_MODE 1)
+
+# For purposes of the test wipe out previous find results.
+SET(PACKAGES
+ foo Foo Bar Blub TFramework Tframework TApp Tapp Special
+ VersionedA VersionedB VersionedC VersionedD VersionedE
+ WrongA WrongB WrongC WrongD
+ wibbleA wibbleB
+ RecursiveA RecursiveB RecursiveC
+ ArchA ArchB ArchC ArchD
+ EnvA EnvB
+ SetFoundTRUE SetFoundFALSE
+ ${CMakeTestSystemPackage}
+ )
+FOREACH(p ${PACKAGES})
+ SET(${p}_DIR "" CACHE FILEPATH "Wipe out find results for testing." FORCE)
+ENDFOREACH(p)
+
+# Enable framework and bundle searching. Make sure bundles are found
+# before unix-syle packages.
+SET(CMAKE_FIND_FRAMEWORK LAST)
+SET(CMAKE_FIND_APPBUNDLE FIRST)
+
+# Set the wrong answer for a find to make sure it re-finds.
+set(VersionedA_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib/cmake/zot-4.0)
+
+# Test that CMAKE_IGNORE_PATH can ignore the purposely bad package
+# files in the lib/cmake/zot-3.1 directory.
+set(CMAKE_IGNORE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/lib/cmake/zot-3.1)
+
+# Look for packages with new-style signatures.
+FIND_PACKAGE(foo NO_MODULE)
+FIND_PACKAGE(Foo CONFIGS FooConfig.cmake)
+FIND_PACKAGE(Bar)
+SET(CMAKE_DISABLE_FIND_PACKAGE_Blub TRUE)
+FIND_PACKAGE(Blub NO_MODULE)
+FIND_PACKAGE(TFramework CONFIGS TFrameworkConfig.cmake)
+FIND_PACKAGE(Tframework)
+FIND_PACKAGE(TApp)
+FIND_PACKAGE(Tapp CONFIGS tapp-config.cmake)
+FIND_PACKAGE(Special NAMES Suffix SuffixTest PATH_SUFFIXES test)
+FIND_PACKAGE(VersionedA 2 NAMES zot)
+FIND_PACKAGE(VersionedB 3.1 EXACT NAMES zot)
+FIND_PACKAGE(VersionedC 4.0 EXACT NAMES zot)
+FIND_PACKAGE(VersionedD 1.1 EXACT NAMES Baz)
+FIND_PACKAGE(VersionedE 1.2 EXACT NAMES Baz)
+
+# Test Config files which set Xyz_FOUND themselves:
+FIND_PACKAGE(SetFoundTRUE NO_MODULE)
+FIND_PACKAGE(SetFoundFALSE NO_MODULE)
+
+# Test wrong initial path when result is present.
+SET(WrongA_DIR "${VersionedD_DIR}")
+FIND_PACKAGE(WrongA 1.2 EXACT NAMES Baz)
+
+# Test wrong initial cache entry of UNINITIALIZED type when result is present.
+SET(WrongB_DIR "${VersionedD_DIR}" CACHE UNINITIALIZED "Wrong Value" FORCE)
+GET_PROPERTY(type CACHE WrongB_DIR PROPERTY TYPE)
+FIND_PACKAGE(WrongB 1.2 EXACT NAMES Baz)
+
+# Test wrong initial path when result is missing.
+SET(WrongC_DIR "${VersionedD_DIR}")
+FIND_PACKAGE(WrongC 1.3 EXACT QUIET NAMES Baz)
+
+# Test wrong initial cache entry of UNINITIALIZED type when result is missing.
+SET(WrongD_DIR "${VersionedD_DIR}" CACHE UNINITIALIZED "Wrong Value" FORCE)
+GET_PROPERTY(type CACHE WrongD_DIR PROPERTY TYPE)
+FIND_PACKAGE(WrongD 1.3 EXACT QUIET NAMES Baz)
+
+# HINTS should override the system but PATHS should not
+LIST(INSERT CMAKE_SYSTEM_PREFIX_PATH 0 "${CMAKE_CURRENT_SOURCE_DIR}/A")
+FIND_PACKAGE(wibbleA NAMES wibble PATHS B)
+FIND_PACKAGE(wibbleB NAMES wibble HINTS B)
+
+# Look for package with recursive find-modules.
+FIND_PACKAGE(RecursiveA COMPONENTS A)
+FIND_PACKAGE(RecursiveB 2)
+FIND_PACKAGE(RecursiveC 3.1 EXACT)
+
+# Test architecture-specific search directories.
+SET(CMAKE_LIBRARY_ARCHITECTURE arch)
+FIND_PACKAGE(ArchA NAMES Bar)
+FIND_PACKAGE(ArchB NAMES Foo CONFIGS FooConfig.cmake)
+FIND_PACKAGE(ArchC 3.1 EXACT NAMES zot)
+FIND_PACKAGE(ArchD 4.0 EXACT NAMES zot)
+UNSET(CMAKE_LIBRARY_ARCHITECTURE)
+
+# Test <Package>_DIR environment variable.
+# We erase the main prefix path to ensure the env var is used.
+SET(CMAKE_PREFIX_PATH)
+SET(ENV{EnvA_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/lib/zot-3.1")
+FIND_PACKAGE(EnvA 3.1 EXACT QUIET NAMES zot) # Should Work
+FIND_PACKAGE(EnvB 3.1 EXACT QUIET NAMES zot) # Should Fail
+
+# Test system package registry if available.
+IF(CMakeTestSystemPackage)
+ FIND_PACKAGE(CMakeTestSystemPackage)
+ EXECUTE_PROCESS(COMMAND ${CMakeTestSystemPackage_CLEANUP}
+ OUTPUT_VARIABLE _output ERROR_VARIABLE _error)
+ENDIF()
+
+# Expected locations at which packages should be found.
+SET(foo_EXPECTED "lib/foo-1.2/foo-config.cmake")
+SET(Foo_EXPECTED "lib/foo-1.2/CMake/FooConfig.cmake")
+SET(Bar_EXPECTED "lib/Bar/BarConfig.cmake")
+SET(Blub_MISSING "")
+SET(Special_EXPECTED "lib/suffix/test/SuffixTestConfig.cmake")
+SET(TFramework_EXPECTED
+ "TFramework.framework/Versions/A/Resources/CMake/TFrameworkConfig.cmake")
+SET(Tframework_EXPECTED
+ "TFramework.framework/Versions/A/Resources/tframework-config.cmake")
+SET(TApp_EXPECTED
+ "TApp.app/Contents/Resources/TAppConfig.cmake")
+SET(Tapp_EXPECTED
+ "TApp.app/Contents/Resources/cmake/tapp-config.cmake")
+SET(VersionedA_EXPECTED "lib/zot-2.0/zot-config.cmake")
+SET(VersionedB_EXPECTED "lib/zot-3.1/zot-config.cmake")
+SET(VersionedC_EXPECTED "lib/cmake/zot-4.0/zot-config.cmake")
+SET(VersionedD_EXPECTED "Baz 1.1/BazConfig.cmake")
+SET(VersionedE_EXPECTED "Baz 1.2/CMake/BazConfig.cmake")
+SET(WrongA_EXPECTED "${VersionedE_EXPECTED}")
+SET(WrongB_EXPECTED "${VersionedE_EXPECTED}")
+SET(WrongC_MISSING "WrongC_DIR-NOTFOUND")
+SET(WrongD_MISSING "WrongD_DIR-NOTFOUND")
+SET(wibbleA_EXPECTED "A/wibble-config.cmake")
+SET(wibbleB_EXPECTED "B/wibble-config.cmake")
+SET(RecursiveA_EXPECTED "lib/RecursiveA/recursivea-config.cmake")
+SET(RecursiveB_EXPECTED "lib/zot-2.0/zot-config.cmake")
+SET(RecursiveC_EXPECTED "lib/zot-3.1/zot-config.cmake")
+SET(ArchA_EXPECTED "lib/arch/Bar/BarConfig.cmake")
+SET(ArchB_EXPECTED "lib/arch/foo-1.2/CMake/FooConfig.cmake")
+SET(ArchC_EXPECTED "lib/arch/zot-3.1/zot-config.cmake")
+SET(ArchD_EXPECTED "lib/arch/cmake/zot-4.0/zot-config.cmake")
+SET(EnvA_EXPECTED "lib/zot-3.1/zot-config.cmake")
+SET(EnvB_MISSING "EnvB_DIR-NOTFOUND")
+SET(SetFoundTRUE_EXPECTED "cmake/SetFoundTRUEConfig.cmake")
+SET(SetFoundFALSE_MISSING "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
+SET(CMakeTestSystemPackage_EXPECTED "SystemPackage/CMakeTestSystemPackageConfig.cmake")
+
+# Check the results.
+FOREACH(p ${PACKAGES})
+ IF(DEFINED ${p}_MISSING)
+ # Check and report failure.
+ IF(NOT "${${p}_DIR}" STREQUAL "${${p}_MISSING}")
+ MESSAGE(SEND_ERROR
+ "Package ${p} should have been [${${p}_MISSING}] but "
+ "was [${${p}_DIR}]")
+ ENDIF()
+ IF(${p}_FOUND)
+ MESSAGE(SEND_ERROR
+ "Package ${p} should not have been found, but ${p}_FOUND is set to "
+ "\"${${p}_FOUND}\"")
+ ENDIF()
+ ELSEIF(${p}_FOUND)
+ # Convert to relative path for comparison to expected location.
+ FILE(RELATIVE_PATH REL_${p}_CONFIG "${CMAKE_CURRENT_SOURCE_DIR}"
+ "${${p}_CONFIG}")
+
+ # Debugging output.
+ IF(CMAKE_FIND_DEBUG_MODE)
+ MESSAGE("Package ${p} found [${REL_${p}_CONFIG}]")
+ ENDIF(CMAKE_FIND_DEBUG_MODE)
+
+ # Check and report failure.
+ IF(NOT "${REL_${p}_CONFIG}" STREQUAL "${${p}_EXPECTED}")
+ MESSAGE(SEND_ERROR
+ "Package ${p} should have been [${${p}_EXPECTED}] but "
+ "was [${REL_${p}_CONFIG}]")
+ ENDIF(NOT "${REL_${p}_CONFIG}" STREQUAL "${${p}_EXPECTED}")
+ ELSE()
+ MESSAGE(SEND_ERROR "Package ${p} not found!")
+ ENDIF()
+ENDFOREACH(p)
+
+# Check that version information was extracted.
+IF(NOT "${VersionedA_VERSION}" STREQUAL "2.0")
+ MESSAGE(SEND_ERROR
+ "Package VersionedA is version [${VersionedA_VERSION}], not [2.0]")
+ENDIF(NOT "${VersionedA_VERSION}" STREQUAL "2.0")
+IF(NOT "${VersionedA_VERSION_MAJOR}" STREQUAL "2")
+ MESSAGE(SEND_ERROR
+ "Package VersionedA is major version [${VersionedA_VERSION_MAJOR}], not [2]")
+ENDIF(NOT "${VersionedA_VERSION_MAJOR}" STREQUAL "2")
+IF(NOT "${VersionedA_VERSION_MINOR}" STREQUAL "0")
+ MESSAGE(SEND_ERROR
+ "Package VersionedA is minor version [${VersionedA_VERSION_MINOR}], not [0]")
+ENDIF(NOT "${VersionedA_VERSION_MINOR}" STREQUAL "0")
+
+IF(NOT "${VersionedB_VERSION}" STREQUAL "3.1")
+ MESSAGE(SEND_ERROR
+ "Package VersionedB is version [${VersionedB_VERSION}], not [3.1]")
+ENDIF(NOT "${VersionedB_VERSION}" STREQUAL "3.1")
+IF(NOT "${VersionedB_VERSION_MAJOR}" STREQUAL "3")
+ MESSAGE(SEND_ERROR
+ "Package VersionedB is major version [${VersionedB_VERSION_MAJOR}], not [3]")
+ENDIF(NOT "${VersionedB_VERSION_MAJOR}" STREQUAL "3")
+IF(NOT "${VersionedB_VERSION_MINOR}" STREQUAL "1")
+ MESSAGE(SEND_ERROR
+ "Package VersionedB is minor version [${VersionedB_VERSION_MINOR}], not [1]")
+ENDIF(NOT "${VersionedB_VERSION_MINOR}" STREQUAL "1")
+
+IF(NOT "${Special_VERSION}" STREQUAL "1.2")
+ MESSAGE(SEND_ERROR
+ "Package Special is version [${Special_VERSION}], not [1.2]")
+ENDIF(NOT "${Special_VERSION}" STREQUAL "1.2")
+IF(NOT "${Special_VERSION_MAJOR}" STREQUAL "1")
+ MESSAGE(SEND_ERROR
+ "Package Special is major version [${Special_VERSION_MAJOR}], not [1]")
+ENDIF(NOT "${Special_VERSION_MAJOR}" STREQUAL "1")
+IF(NOT "${Special_VERSION_MINOR}" STREQUAL "2")
+ MESSAGE(SEND_ERROR
+ "Package Special is minor version [${Special_VERSION_MINOR}], not [2]")
+ENDIF(NOT "${Special_VERSION_MINOR}" STREQUAL "2")
+
+# Test version number comparison.
+IF(NOT "1.2.3.4" VERSION_LESS "1.2.3.5")
+ MESSAGE(SEND_ERROR "1.2.3.4 VERSION_LESS 1.2.3.5 is not true!")
+ENDIF()
+IF(NOT "1.2" VERSION_LESS "1.10")
+ MESSAGE(SEND_ERROR "1.2 VERSION_LESS 1.10 is not true!")
+ENDIF()
+IF(NOT "1.02" VERSION_GREATER "1.1")
+ MESSAGE(SEND_ERROR "1.02 VERSION_GREATER 1.1 is not true!")
+ENDIF()
+IF("1.2.3" VERSION_GREATER "1.2.3.4")
+ MESSAGE(SEND_ERROR "1.2.3 VERSION_GREATER 1.2.3.4 is not false!")
+ENDIF()
+IF(NOT "1.2" VERSION_EQUAL "1.2.0.0")
+ MESSAGE(SEND_ERROR "1.2 VERSION_EQUAL 1.2.0.0 is not true!")
+ENDIF()
+
+#-----------------------------------------------------------------------------
+# Test export(PACKAGE) with find_package.
+MESSAGE(STATUS "Preparing export(PACKAGE) test project")
+TRY_COMPILE(EXPORTER_COMPILED
+ ${FindPackageTest_BINARY_DIR}/Exporter
+ ${FindPackageTest_SOURCE_DIR}/Exporter
+ CMakeTestExportPackage dummy
+ 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)
+
+#-----------------------------------------------------------------------------
+# Test configure_package_config_file().
+
+include(CMakePackageConfigHelpers)
+
+set(INCLUDE_INSTALL_DIR include )
+set(SHARE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/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_INSTALL_PREFIX}"
+ PATH_VARS INCLUDE_INSTALL_DIR SHARE_INSTALL_DIR CURRENT_BUILD_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().
+
+# also test that an empty CMAKE_SIZEOF_VOID_P is accepted:
+set(_CMAKE_SIZEOF_VOID_P ${CMAKE_SIZEOF_VOID_P})
+set(CMAKE_SIZEOF_VOID_P "")
+
+write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/Foo123ConfigVersion.cmake
+ VERSION 1.2.3
+ COMPATIBILITY AnyNewerVersion)
+
+set(CMAKE_SIZEOF_VOID_P ${_CMAKE_SIZEOF_VOID_P})
+
+set(PACKAGE_FIND_VERSION 2.3.4)
+include(${CMAKE_CURRENT_BINARY_DIR}/Foo123ConfigVersion.cmake)
+if(PACKAGE_VERSION_COMPATIBLE)
+ message(SEND_ERROR "Found Foo123 with version 1.2.3, but 2.3.4 was requested !")
+endif()
+
+set(PACKAGE_FIND_VERSION 0.0.1)
+include(${CMAKE_CURRENT_BINARY_DIR}/Foo123ConfigVersion.cmake)
+if(NOT PACKAGE_VERSION_COMPATIBLE)
+ message(SEND_ERROR "Did not find Foo123 with version 1.2.3 (0.0.1 was requested) !")
+endif()
+
+if(PACKAGE_VERSION_UNSUITABLE)
+ message(SEND_ERROR "PACKAGE_VERSION_UNSUITABLE set, but must not be !")
+endif()
+
+set(PACKAGE_FIND_VERSION 1.0.0)
+include(${CMAKE_CURRENT_BINARY_DIR}/Foo123ConfigVersion.cmake)
+if(NOT PACKAGE_VERSION_COMPATIBLE)
+ message(SEND_ERROR "Did not find Foo123 with version 1.2.3 (1.0.0 was requested) !")
+endif()
+if(PACKAGE_VERSION_EXACT)
+ message(SEND_ERROR "PACKAGE_VERSION_EXACT set, although it should not be !")
+endif()
+
+set(PACKAGE_FIND_VERSION 1.2.3)
+include(${CMAKE_CURRENT_BINARY_DIR}/Foo123ConfigVersion.cmake)
+if(NOT PACKAGE_VERSION_COMPATIBLE)
+ message(SEND_ERROR "Did not find Foo123 with version 1.2.3 (1.2.3 was requested) !")
+endif()
+if(NOT PACKAGE_VERSION_EXACT)
+ message(SEND_ERROR "PACKAGE_VERSION_EXACT not set, although it should be !")
+endif()
+
+
+#######################
+include(WriteBasicConfigVersionFile)
+
+write_basic_config_version_file(${CMAKE_CURRENT_BINARY_DIR}/Boo123ConfigVersion.cmake
+ VERSION 1.2.3
+ COMPATIBILITY SameMajorVersion)
+
+unset(PACKAGE_VERSION_UNSUITABLE)
+set(PACKAGE_VERSION_EXACT FALSE)
+set(PACKAGE_FIND_VERSION 2.3.4)
+set(PACKAGE_FIND_VERSION_MAJOR 2)
+include(${CMAKE_CURRENT_BINARY_DIR}/Boo123ConfigVersion.cmake)
+if(PACKAGE_VERSION_COMPATIBLE)
+ message(SEND_ERROR "Found Boo123 with version 1.2.3, but 2.3.4 was requested !")
+endif()
+if(PACKAGE_VERSION_EXACT)
+ message(SEND_ERROR "PACKAGE_VERSION_EXACT set, although it should not be !")
+endif()
+
+set(PACKAGE_FIND_VERSION 0.0.1)
+set(PACKAGE_FIND_VERSION_MAJOR 0)
+include(${CMAKE_CURRENT_BINARY_DIR}/Boo123ConfigVersion.cmake)
+if(PACKAGE_VERSION_COMPATIBLE)
+ message(SEND_ERROR "Found Boo123 with version 1.2.3, but 0.0.1 was requested !")
+endif()
+if(PACKAGE_VERSION_EXACT)
+ message(SEND_ERROR "PACKAGE_VERSION_EXACT set, although it should not be !")
+endif()
+
+set(PACKAGE_FIND_VERSION 1.0.0)
+set(PACKAGE_FIND_VERSION_MAJOR 1)
+include(${CMAKE_CURRENT_BINARY_DIR}/Boo123ConfigVersion.cmake)
+if(NOT PACKAGE_VERSION_COMPATIBLE)
+ message(SEND_ERROR "Did not find Boo123 with version 1.2.3 (1.0.0 was requested) !")
+endif()
+if(PACKAGE_VERSION_EXACT)
+ message(SEND_ERROR "PACKAGE_VERSION_EXACT set, although it should not be !")
+endif()
+
+set(PACKAGE_FIND_VERSION 1.2.3)
+set(PACKAGE_FIND_VERSION_MAJOR 1)
+include(${CMAKE_CURRENT_BINARY_DIR}/Boo123ConfigVersion.cmake)
+if(NOT PACKAGE_VERSION_COMPATIBLE)
+ message(SEND_ERROR "Did not find Boo123 with version 1.2.3 (1.2.3 was requested) !")
+endif()
+if(NOT PACKAGE_VERSION_EXACT)
+ message(SEND_ERROR "PACKAGE_VERSION_EXACT not set, although it should be !")
+endif()
+
+if(PACKAGE_VERSION_UNSUITABLE)
+ message(SEND_ERROR "PACKAGE_VERSION_UNSUITABLE set, but must not be !")
+endif()
+
+#######################
+
+write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/Bar123ConfigVersion.cmake
+ VERSION 1.2.3.17
+ COMPATIBILITY ExactVersion)
+
+unset(PACKAGE_VERSION_UNSUITABLE)
+set(PACKAGE_VERSION_EXACT FALSE)
+set(PACKAGE_FIND_VERSION 2.3.4)
+include(${CMAKE_CURRENT_BINARY_DIR}/Bar123ConfigVersion.cmake)
+if(PACKAGE_VERSION_COMPATIBLE)
+ message(SEND_ERROR "Found Bar123 with version 1.2.3 (2.3.4 was requested) !")
+endif()
+if(PACKAGE_VERSION_EXACT)
+ message(SEND_ERROR "PACKAGE_VERSION_EXACT set, although it should not be !")
+endif()
+
+set(PACKAGE_FIND_VERSION 1.2)
+include(${CMAKE_CURRENT_BINARY_DIR}/Bar123ConfigVersion.cmake)
+if(PACKAGE_VERSION_COMPATIBLE)
+ message(SEND_ERROR "Found Bar123 with version 1.2.3 (1.2 was requested) !")
+endif()
+if(PACKAGE_VERSION_EXACT)
+ message(SEND_ERROR "PACKAGE_VERSION_EXACT set, although it should not be !")
+endif()
+
+set(PACKAGE_FIND_VERSION 1)
+include(${CMAKE_CURRENT_BINARY_DIR}/Bar123ConfigVersion.cmake)
+if(PACKAGE_VERSION_COMPATIBLE)
+ message(SEND_ERROR "Found Bar123 with version 1.2.3 (1 was requested) !")
+endif()
+if(PACKAGE_VERSION_EXACT)
+ message(SEND_ERROR "PACKAGE_VERSION_EXACT set, although it should not be !")
+endif()
+
+set(PACKAGE_FIND_VERSION 1.2.3.4)
+include(${CMAKE_CURRENT_BINARY_DIR}/Bar123ConfigVersion.cmake)
+if(NOT PACKAGE_VERSION_COMPATIBLE)
+ message(SEND_ERROR "Did not find Bar123 with version 1.2.3 (1.2.3.4 was requested) !")
+endif()
+if(PACKAGE_VERSION_EXACT)
+ message(SEND_ERROR "PACKAGE_VERSION_EXACT set, although it should not be !")
+endif()
+
+set(PACKAGE_FIND_VERSION 1.2.3)
+set(PACKAGE_VERSION_EXACT FALSE)
+set(PACKAGE_VERSION_COMPATIBLE FALSE)
+include(${CMAKE_CURRENT_BINARY_DIR}/Bar123ConfigVersion.cmake)
+if(NOT PACKAGE_VERSION_COMPATIBLE)
+ message(SEND_ERROR "Did not find Bar123 with version 1.2.3 (1.2.3 was requested) !")
+endif()
+if(PACKAGE_VERSION_EXACT)
+ message(SEND_ERROR "PACKAGE_VERSION_EXACT set, although it should not be !")
+endif()
+
+
+set(PACKAGE_FIND_VERSION 1.2.3.17)
+set(PACKAGE_VERSION_EXACT FALSE)
+set(PACKAGE_VERSION_COMPATIBLE FALSE)
+include(${CMAKE_CURRENT_BINARY_DIR}/Bar123ConfigVersion.cmake)
+if(NOT PACKAGE_VERSION_COMPATIBLE)
+ message(SEND_ERROR "Did not find Bar123 with version 1.2.3 (1.2.3.17 was requested) !")
+endif()
+if(NOT PACKAGE_VERSION_EXACT)
+ message(SEND_ERROR "PACKAGE_VERSION_EXACT not set, although it should be !")
+endif()
+
+if(PACKAGE_VERSION_UNSUITABLE)
+ message(SEND_ERROR "PACKAGE_VERSION_UNSUITABLE set, but must not be !")
+endif()
diff --git a/Tests/FindPackageTest/Exporter/CMakeLists.txt b/Tests/FindPackageTest/Exporter/CMakeLists.txt
new file mode 100644
index 000000000..d25a2e74c
--- /dev/null
+++ b/Tests/FindPackageTest/Exporter/CMakeLists.txt
@@ -0,0 +1,12 @@
+cmake_minimum_required(VERSION 2.7.20090831)
+project(CMakeTestExportPackage C)
+
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/CMakeTestExportPackageConfig.cmake.in
+ ${CMAKE_CURRENT_BINARY_DIR}/CMakeTestExportPackageConfig.cmake
+ @ONLY)
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/CMakeTestExportPackageConfigVersion.cmake.in
+ ${CMAKE_CURRENT_BINARY_DIR}/CMakeTestExportPackageConfigVersion.cmake
+ @ONLY)
+export(PACKAGE CMakeTestExportPackage)
+
+add_executable(dummy dummy.c)
diff --git a/Tests/FindPackageTest/Exporter/CMakeTestExportPackageConfig.cmake.in b/Tests/FindPackageTest/Exporter/CMakeTestExportPackageConfig.cmake.in
new file mode 100644
index 000000000..deffa5729
--- /dev/null
+++ b/Tests/FindPackageTest/Exporter/CMakeTestExportPackageConfig.cmake.in
@@ -0,0 +1 @@
+# Test config file.
diff --git a/Tests/FindPackageTest/Exporter/CMakeTestExportPackageConfigVersion.cmake.in b/Tests/FindPackageTest/Exporter/CMakeTestExportPackageConfigVersion.cmake.in
new file mode 100644
index 000000000..ff450a145
--- /dev/null
+++ b/Tests/FindPackageTest/Exporter/CMakeTestExportPackageConfigVersion.cmake.in
@@ -0,0 +1,6 @@
+# Test config file.
+SET(PACKAGE_VERSION "1.@CMAKE_VERSION@")
+IF("${PACKAGE_FIND_VERSION}" VERSION_EQUAL "${PACKAGE_VERSION}")
+ SET(PACKAGE_VERSION_COMPATIBLE 1)
+ SET(PACKAGE_VERSION_EXACT 1)
+ENDIF()
diff --git a/Tests/FindPackageTest/Exporter/dummy.c b/Tests/FindPackageTest/Exporter/dummy.c
new file mode 100644
index 000000000..76e819701
--- /dev/null
+++ b/Tests/FindPackageTest/Exporter/dummy.c
@@ -0,0 +1 @@
+int main() { return 0; }
diff --git a/Tests/FindPackageTest/FindLotsOfComponents.cmake b/Tests/FindPackageTest/FindLotsOfComponents.cmake
new file mode 100644
index 000000000..9076d86ed
--- /dev/null
+++ b/Tests/FindPackageTest/FindLotsOfComponents.cmake
@@ -0,0 +1,10 @@
+set(LOC_FOO TRUE)
+
+set(LotsOfComponents_AComp_FOUND TRUE)
+set(LotsOfComponents_BComp_FOUND FALSE)
+set(LotsOfComponents_CComp_FOUND TRUE)
+
+include(FindPackageHandleStandardArgs)
+
+find_package_handle_standard_args(LotsOfComponents REQUIRED_VARS LOC_FOO
+ HANDLE_COMPONENTS)
diff --git a/Tests/FindPackageTest/FindPackageHandleStandardArgs.cmake b/Tests/FindPackageTest/FindPackageHandleStandardArgs.cmake
new file mode 100644
index 000000000..7e41c96c9
--- /dev/null
+++ b/Tests/FindPackageTest/FindPackageHandleStandardArgs.cmake
@@ -0,0 +1 @@
+message(FATAL_ERROR "This file (${CMAKE_CURRENT_LIST_FILE}) must not be included, but FindPackageHandleStandardArgs.cmake from Modules/ instead !")
diff --git a/Tests/FindPackageTest/FindPackageTest.cxx b/Tests/FindPackageTest/FindPackageTest.cxx
new file mode 100644
index 000000000..f8b643afb
--- /dev/null
+++ b/Tests/FindPackageTest/FindPackageTest.cxx
@@ -0,0 +1,4 @@
+int main()
+{
+ return 0;
+}
diff --git a/Tests/FindPackageTest/FindRecursiveA.cmake b/Tests/FindPackageTest/FindRecursiveA.cmake
new file mode 100644
index 000000000..3af7e99a3
--- /dev/null
+++ b/Tests/FindPackageTest/FindRecursiveA.cmake
@@ -0,0 +1 @@
+FIND_PACKAGE(RecursiveA NO_MODULE)
diff --git a/Tests/FindPackageTest/FindRecursiveB.cmake b/Tests/FindPackageTest/FindRecursiveB.cmake
new file mode 100644
index 000000000..c609ab127
--- /dev/null
+++ b/Tests/FindPackageTest/FindRecursiveB.cmake
@@ -0,0 +1 @@
+FIND_PACKAGE(RecursiveB NAMES zot)
diff --git a/Tests/FindPackageTest/FindRecursiveC.cmake b/Tests/FindPackageTest/FindRecursiveC.cmake
new file mode 100644
index 000000000..018cc7302
--- /dev/null
+++ b/Tests/FindPackageTest/FindRecursiveC.cmake
@@ -0,0 +1 @@
+FIND_PACKAGE(RecursiveC NAMES zot)
diff --git a/Tests/FindPackageTest/FindVersionTestA.cmake b/Tests/FindPackageTest/FindVersionTestA.cmake
new file mode 100644
index 000000000..55c67e257
--- /dev/null
+++ b/Tests/FindPackageTest/FindVersionTestA.cmake
@@ -0,0 +1,18 @@
+IF(NOT "${VersionTestA_FIND_VERSION}" STREQUAL "1")
+ MESSAGE(SEND_ERROR "VersionTestA_FIND_VERSION=${VersionTestA_FIND_VERSION} is not 1")
+ENDIF(NOT "${VersionTestA_FIND_VERSION}" STREQUAL "1")
+IF(NOT "${VersionTestA_FIND_VERSION_MAJOR}" STREQUAL "1")
+ MESSAGE(SEND_ERROR "VersionTestA_FIND_VERSION_MAJOR=${VersionTestA_FIND_VERSION_MAJOR} is not 1")
+ENDIF(NOT "${VersionTestA_FIND_VERSION_MAJOR}" STREQUAL "1")
+IF(NOT "${VersionTestA_FIND_VERSION_MINOR}" STREQUAL "0")
+ MESSAGE(SEND_ERROR "VersionTestA_FIND_VERSION_MINOR=${VersionTestA_FIND_VERSION_MINOR} is not 0")
+ENDIF(NOT "${VersionTestA_FIND_VERSION_MINOR}" STREQUAL "0")
+IF(NOT "${VersionTestA_FIND_VERSION_PATCH}" STREQUAL "0")
+ MESSAGE(SEND_ERROR "VersionTestA_FIND_VERSION_PATCH=${VersionTestA_FIND_VERSION_PATCH} is not 0")
+ENDIF(NOT "${VersionTestA_FIND_VERSION_PATCH}" STREQUAL "0")
+IF(NOT "${VersionTestA_FIND_VERSION_TWEAK}" STREQUAL "0")
+ MESSAGE(SEND_ERROR "VersionTestA_FIND_VERSION_TWEAK=${VersionTestA_FIND_VERSION_TWEAK} is not 0")
+ENDIF(NOT "${VersionTestA_FIND_VERSION_TWEAK}" STREQUAL "0")
+IF(NOT "${VersionTestA_FIND_VERSION_COUNT}" STREQUAL "1")
+ MESSAGE(SEND_ERROR "VersionTestA_FIND_VERSION_COUNT=${VersionTestA_FIND_VERSION_COUNT} is not 1")
+ENDIF(NOT "${VersionTestA_FIND_VERSION_COUNT}" STREQUAL "1")
diff --git a/Tests/FindPackageTest/FindVersionTestB.cmake b/Tests/FindPackageTest/FindVersionTestB.cmake
new file mode 100644
index 000000000..03173c65a
--- /dev/null
+++ b/Tests/FindPackageTest/FindVersionTestB.cmake
@@ -0,0 +1,18 @@
+IF(NOT "${VersionTestB_FIND_VERSION}" STREQUAL "1.2")
+ MESSAGE(SEND_ERROR "VersionTestB_FIND_VERSION=${VersionTestB_FIND_VERSION} is not 1.2")
+ENDIF(NOT "${VersionTestB_FIND_VERSION}" STREQUAL "1.2")
+IF(NOT "${VersionTestB_FIND_VERSION_MAJOR}" STREQUAL "1")
+ MESSAGE(SEND_ERROR "VersionTestB_FIND_VERSION_MAJOR=${VersionTestB_FIND_VERSION_MAJOR} is not 1")
+ENDIF(NOT "${VersionTestB_FIND_VERSION_MAJOR}" STREQUAL "1")
+IF(NOT "${VersionTestB_FIND_VERSION_MINOR}" STREQUAL "2")
+ MESSAGE(SEND_ERROR "VersionTestB_FIND_VERSION_MINOR=${VersionTestB_FIND_VERSION_MINOR} is not 2")
+ENDIF(NOT "${VersionTestB_FIND_VERSION_MINOR}" STREQUAL "2")
+IF(NOT "${VersionTestB_FIND_VERSION_PATCH}" STREQUAL "0")
+ MESSAGE(SEND_ERROR "VersionTestB_FIND_VERSION_PATCH=${VersionTestB_FIND_VERSION_PATCH} is not 0")
+ENDIF(NOT "${VersionTestB_FIND_VERSION_PATCH}" STREQUAL "0")
+IF(NOT "${VersionTestB_FIND_VERSION_TWEAK}" STREQUAL "0")
+ MESSAGE(SEND_ERROR "VersionTestB_FIND_VERSION_TWEAK=${VersionTestB_FIND_VERSION_TWEAK} is not 0")
+ENDIF(NOT "${VersionTestB_FIND_VERSION_TWEAK}" STREQUAL "0")
+IF(NOT "${VersionTestB_FIND_VERSION_COUNT}" STREQUAL "2")
+ MESSAGE(SEND_ERROR "VersionTestB_FIND_VERSION_COUNT=${VersionTestB_FIND_VERSION_COUNT} is not 2")
+ENDIF(NOT "${VersionTestB_FIND_VERSION_COUNT}" STREQUAL "2")
diff --git a/Tests/FindPackageTest/FindVersionTestC.cmake b/Tests/FindPackageTest/FindVersionTestC.cmake
new file mode 100644
index 000000000..1344cbc22
--- /dev/null
+++ b/Tests/FindPackageTest/FindVersionTestC.cmake
@@ -0,0 +1,18 @@
+IF(NOT "${VersionTestC_FIND_VERSION}" STREQUAL "1.2.3")
+ MESSAGE(SEND_ERROR "VersionTestC_FIND_VERSION=${VersionTestC_FIND_VERSION} is not 1.2.3")
+ENDIF(NOT "${VersionTestC_FIND_VERSION}" STREQUAL "1.2.3")
+IF(NOT "${VersionTestC_FIND_VERSION_MAJOR}" STREQUAL "1")
+ MESSAGE(SEND_ERROR "VersionTestC_FIND_VERSION_MAJOR=${VersionTestC_FIND_VERSION_MAJOR} is not 1")
+ENDIF(NOT "${VersionTestC_FIND_VERSION_MAJOR}" STREQUAL "1")
+IF(NOT "${VersionTestC_FIND_VERSION_MINOR}" STREQUAL "2")
+ MESSAGE(SEND_ERROR "VersionTestC_FIND_VERSION_MINOR=${VersionTestC_FIND_VERSION_MINOR} is not 2")
+ENDIF(NOT "${VersionTestC_FIND_VERSION_MINOR}" STREQUAL "2")
+IF(NOT "${VersionTestC_FIND_VERSION_PATCH}" STREQUAL "3")
+ MESSAGE(SEND_ERROR "VersionTestC_FIND_VERSION_PATCH=${VersionTestC_FIND_VERSION_PATCH} is not 3")
+ENDIF(NOT "${VersionTestC_FIND_VERSION_PATCH}" STREQUAL "3")
+IF(NOT "${VersionTestC_FIND_VERSION_TWEAK}" STREQUAL "0")
+ MESSAGE(SEND_ERROR "VersionTestC_FIND_VERSION_TWEAK=${VersionTestC_FIND_VERSION_TWEAK} is not 0")
+ENDIF(NOT "${VersionTestC_FIND_VERSION_TWEAK}" STREQUAL "0")
+IF(NOT "${VersionTestC_FIND_VERSION_COUNT}" STREQUAL "3")
+ MESSAGE(SEND_ERROR "VersionTestC_FIND_VERSION_COUNT=${VersionTestC_FIND_VERSION_COUNT} is not 3")
+ENDIF(NOT "${VersionTestC_FIND_VERSION_COUNT}" STREQUAL "3")
diff --git a/Tests/FindPackageTest/FindVersionTestD.cmake b/Tests/FindPackageTest/FindVersionTestD.cmake
new file mode 100644
index 000000000..d3e3f509e
--- /dev/null
+++ b/Tests/FindPackageTest/FindVersionTestD.cmake
@@ -0,0 +1,18 @@
+IF(NOT "${VersionTestD_FIND_VERSION}" STREQUAL "1.2.3.4")
+ MESSAGE(SEND_ERROR "VersionTestD_FIND_VERSION=${VersionTestD_FIND_VERSION} is not 1.2.3.4")
+ENDIF(NOT "${VersionTestD_FIND_VERSION}" STREQUAL "1.2.3.4")
+IF(NOT "${VersionTestD_FIND_VERSION_MAJOR}" STREQUAL "1")
+ MESSAGE(SEND_ERROR "VersionTestD_FIND_VERSION_MAJOR=${VersionTestD_FIND_VERSION_MAJOR} is not 1")
+ENDIF(NOT "${VersionTestD_FIND_VERSION_MAJOR}" STREQUAL "1")
+IF(NOT "${VersionTestD_FIND_VERSION_MINOR}" STREQUAL "2")
+ MESSAGE(SEND_ERROR "VersionTestD_FIND_VERSION_MINOR=${VersionTestD_FIND_VERSION_MINOR} is not 2")
+ENDIF(NOT "${VersionTestD_FIND_VERSION_MINOR}" STREQUAL "2")
+IF(NOT "${VersionTestD_FIND_VERSION_PATCH}" STREQUAL "3")
+ MESSAGE(SEND_ERROR "VersionTestD_FIND_VERSION_PATCH=${VersionTestD_FIND_VERSION_PATCH} is not 3")
+ENDIF(NOT "${VersionTestD_FIND_VERSION_PATCH}" STREQUAL "3")
+IF(NOT "${VersionTestD_FIND_VERSION_TWEAK}" STREQUAL "4")
+ MESSAGE(SEND_ERROR "VersionTestD_FIND_VERSION_TWEAK=${VersionTestD_FIND_VERSION_TWEAK} is not 4")
+ENDIF(NOT "${VersionTestD_FIND_VERSION_TWEAK}" STREQUAL "4")
+IF(NOT "${VersionTestD_FIND_VERSION_COUNT}" STREQUAL "4")
+ MESSAGE(SEND_ERROR "VersionTestD_FIND_VERSION_COUNT=${VersionTestD_FIND_VERSION_COUNT} is not 4")
+ENDIF(NOT "${VersionTestD_FIND_VERSION_COUNT}" STREQUAL "4")
diff --git a/Tests/FindPackageTest/RelocatableConfig.cmake.in b/Tests/FindPackageTest/RelocatableConfig.cmake.in
new file mode 100644
index 000000000..4a4b4e9c6
--- /dev/null
+++ b/Tests/FindPackageTest/RelocatableConfig.cmake.in
@@ -0,0 +1,11 @@
+@PACKAGE_INIT@
+
+set(RELOC_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@")
+set(RELOC_SHARE_DIR "@PACKAGE_SHARE_INSTALL_DIR@")
+set_and_check(RELOC_BUILD_DIR "@PACKAGE_CURRENT_BUILD_DIR@")
+
+set(Relocatable_AComp_FOUND TRUE)
+set(Relocatable_BComp_FOUND FALSE)
+set(Relocatable_CComp_FOUND FALSE)
+
+check_required_components(Relocatable)
diff --git a/Tests/FindPackageTest/SystemPackage/CMakeTestSystemPackageConfig.cmake b/Tests/FindPackageTest/SystemPackage/CMakeTestSystemPackageConfig.cmake
new file mode 100644
index 000000000..deffa5729
--- /dev/null
+++ b/Tests/FindPackageTest/SystemPackage/CMakeTestSystemPackageConfig.cmake
@@ -0,0 +1 @@
+# Test config file.
diff --git a/Tests/FindPackageTest/TApp.app/Contents/Resources/TAppConfig.cmake b/Tests/FindPackageTest/TApp.app/Contents/Resources/TAppConfig.cmake
new file mode 100644
index 000000000..deffa5729
--- /dev/null
+++ b/Tests/FindPackageTest/TApp.app/Contents/Resources/TAppConfig.cmake
@@ -0,0 +1 @@
+# Test config file.
diff --git a/Tests/FindPackageTest/TApp.app/Contents/Resources/cmake/tapp-config.cmake b/Tests/FindPackageTest/TApp.app/Contents/Resources/cmake/tapp-config.cmake
new file mode 100644
index 000000000..deffa5729
--- /dev/null
+++ b/Tests/FindPackageTest/TApp.app/Contents/Resources/cmake/tapp-config.cmake
@@ -0,0 +1 @@
+# Test config file.
diff --git a/Tests/FindPackageTest/TFramework.framework/Versions/A/Resources/CMake/TFrameworkConfig.cmake b/Tests/FindPackageTest/TFramework.framework/Versions/A/Resources/CMake/TFrameworkConfig.cmake
new file mode 100644
index 000000000..deffa5729
--- /dev/null
+++ b/Tests/FindPackageTest/TFramework.framework/Versions/A/Resources/CMake/TFrameworkConfig.cmake
@@ -0,0 +1 @@
+# Test config file.
diff --git a/Tests/FindPackageTest/TFramework.framework/Versions/A/Resources/tframework-config.cmake b/Tests/FindPackageTest/TFramework.framework/Versions/A/Resources/tframework-config.cmake
new file mode 100644
index 000000000..deffa5729
--- /dev/null
+++ b/Tests/FindPackageTest/TFramework.framework/Versions/A/Resources/tframework-config.cmake
@@ -0,0 +1 @@
+# Test config file.
diff --git a/Tests/FindPackageTest/cmake/SetFoundFALSEConfig.cmake b/Tests/FindPackageTest/cmake/SetFoundFALSEConfig.cmake
new file mode 100644
index 000000000..ae6bd1454
--- /dev/null
+++ b/Tests/FindPackageTest/cmake/SetFoundFALSEConfig.cmake
@@ -0,0 +1 @@
+set(SetFoundFALSE_FOUND FALSE)
diff --git a/Tests/FindPackageTest/cmake/SetFoundTRUEConfig.cmake b/Tests/FindPackageTest/cmake/SetFoundTRUEConfig.cmake
new file mode 100644
index 000000000..19d071144
--- /dev/null
+++ b/Tests/FindPackageTest/cmake/SetFoundTRUEConfig.cmake
@@ -0,0 +1 @@
+set(SetFoundTRUE_FOUND TRUE)
diff --git a/Tests/FindPackageTest/include/foo.h b/Tests/FindPackageTest/include/foo.h
new file mode 100644
index 000000000..2392aee71
--- /dev/null
+++ b/Tests/FindPackageTest/include/foo.h
@@ -0,0 +1 @@
+/* empty header file */
diff --git a/Tests/FindPackageTest/lib/Bar/BarConfig.cmake b/Tests/FindPackageTest/lib/Bar/BarConfig.cmake
new file mode 100644
index 000000000..deffa5729
--- /dev/null
+++ b/Tests/FindPackageTest/lib/Bar/BarConfig.cmake
@@ -0,0 +1 @@
+# Test config file.
diff --git a/Tests/FindPackageTest/lib/Bar/cmake/bar-config.cmake b/Tests/FindPackageTest/lib/Bar/cmake/bar-config.cmake
new file mode 100644
index 000000000..deffa5729
--- /dev/null
+++ b/Tests/FindPackageTest/lib/Bar/cmake/bar-config.cmake
@@ -0,0 +1 @@
+# Test config file.
diff --git a/Tests/FindPackageTest/lib/Blub/BlubConfig.cmake b/Tests/FindPackageTest/lib/Blub/BlubConfig.cmake
new file mode 100644
index 000000000..deffa5729
--- /dev/null
+++ b/Tests/FindPackageTest/lib/Blub/BlubConfig.cmake
@@ -0,0 +1 @@
+# Test config file.
diff --git a/Tests/FindPackageTest/lib/RecursiveA/recursivea-config.cmake b/Tests/FindPackageTest/lib/RecursiveA/recursivea-config.cmake
new file mode 100644
index 000000000..eff4d4fd0
--- /dev/null
+++ b/Tests/FindPackageTest/lib/RecursiveA/recursivea-config.cmake
@@ -0,0 +1,4 @@
+# Test config file.
+if(NOT "${RecursiveA_FIND_COMPONENTS}" STREQUAL "A")
+ message(FATAL_ERROR "find_package(RecursiveA NO_MODULE) did not forward components")
+endif()
diff --git a/Tests/FindPackageTest/lib/TApp/TAppConfig.cmake b/Tests/FindPackageTest/lib/TApp/TAppConfig.cmake
new file mode 100644
index 000000000..cbf06036e
--- /dev/null
+++ b/Tests/FindPackageTest/lib/TApp/TAppConfig.cmake
@@ -0,0 +1,2 @@
+# Test config file that should not be found.
+MESSAGE("Package TApp found non-bundle first!")
diff --git a/Tests/FindPackageTest/lib/arch/Bar/BarConfig.cmake b/Tests/FindPackageTest/lib/arch/Bar/BarConfig.cmake
new file mode 100644
index 000000000..deffa5729
--- /dev/null
+++ b/Tests/FindPackageTest/lib/arch/Bar/BarConfig.cmake
@@ -0,0 +1 @@
+# Test config file.
diff --git a/Tests/FindPackageTest/lib/arch/cmake/zot-4.0/zot-config-version.cmake b/Tests/FindPackageTest/lib/arch/cmake/zot-4.0/zot-config-version.cmake
new file mode 100644
index 000000000..2f768e8f5
--- /dev/null
+++ b/Tests/FindPackageTest/lib/arch/cmake/zot-4.0/zot-config-version.cmake
@@ -0,0 +1,7 @@
+SET(PACKAGE_VERSION 4.0)
+IF("${PACKAGE_FIND_VERSION_MAJOR}" EQUAL 4)
+ SET(PACKAGE_VERSION_COMPATIBLE 1)
+ IF("${PACKAGE_FIND_VERSION_MINOR}" EQUAL 0)
+ SET(PACKAGE_VERSION_EXACT 1)
+ ENDIF("${PACKAGE_FIND_VERSION_MINOR}" EQUAL 0)
+ENDIF("${PACKAGE_FIND_VERSION_MAJOR}" EQUAL 4)
diff --git a/Tests/FindPackageTest/lib/arch/cmake/zot-4.0/zot-config.cmake b/Tests/FindPackageTest/lib/arch/cmake/zot-4.0/zot-config.cmake
new file mode 100644
index 000000000..deffa5729
--- /dev/null
+++ b/Tests/FindPackageTest/lib/arch/cmake/zot-4.0/zot-config.cmake
@@ -0,0 +1 @@
+# Test config file.
diff --git a/Tests/FindPackageTest/lib/arch/foo-1.2/CMake/FooConfig.cmake b/Tests/FindPackageTest/lib/arch/foo-1.2/CMake/FooConfig.cmake
new file mode 100644
index 000000000..deffa5729
--- /dev/null
+++ b/Tests/FindPackageTest/lib/arch/foo-1.2/CMake/FooConfig.cmake
@@ -0,0 +1 @@
+# Test config file.
diff --git a/Tests/FindPackageTest/lib/arch/zot-3.1/zot-config-version.cmake b/Tests/FindPackageTest/lib/arch/zot-3.1/zot-config-version.cmake
new file mode 100644
index 000000000..13763adf1
--- /dev/null
+++ b/Tests/FindPackageTest/lib/arch/zot-3.1/zot-config-version.cmake
@@ -0,0 +1,7 @@
+SET(PACKAGE_VERSION 3.1)
+IF("${PACKAGE_FIND_VERSION_MAJOR}" EQUAL 3)
+ SET(PACKAGE_VERSION_COMPATIBLE 1)
+ IF("${PACKAGE_FIND_VERSION_MINOR}" EQUAL 1)
+ SET(PACKAGE_VERSION_EXACT 1)
+ ENDIF("${PACKAGE_FIND_VERSION_MINOR}" EQUAL 1)
+ENDIF("${PACKAGE_FIND_VERSION_MAJOR}" EQUAL 3)
diff --git a/Tests/FindPackageTest/lib/arch/zot-3.1/zot-config.cmake b/Tests/FindPackageTest/lib/arch/zot-3.1/zot-config.cmake
new file mode 100644
index 000000000..deffa5729
--- /dev/null
+++ b/Tests/FindPackageTest/lib/arch/zot-3.1/zot-config.cmake
@@ -0,0 +1 @@
+# Test config file.
diff --git a/Tests/FindPackageTest/lib/cmake/zot-3.1/zot-config-version.cmake b/Tests/FindPackageTest/lib/cmake/zot-3.1/zot-config-version.cmake
new file mode 100644
index 000000000..bee2f0eea
--- /dev/null
+++ b/Tests/FindPackageTest/lib/cmake/zot-3.1/zot-config-version.cmake
@@ -0,0 +1,4 @@
+# Claim to be any version to test that CMAKE_IGNORE_PATH hides us.
+SET(PACKAGE_VERSION 3.1)
+SET(PACKAGE_VERSION_COMPATIBLE 1)
+SET(PACKAGE_VERSION_EXACT 1)
diff --git a/Tests/FindPackageTest/lib/cmake/zot-3.1/zot-config.cmake b/Tests/FindPackageTest/lib/cmake/zot-3.1/zot-config.cmake
new file mode 100644
index 000000000..2fbd525f3
--- /dev/null
+++ b/Tests/FindPackageTest/lib/cmake/zot-3.1/zot-config.cmake
@@ -0,0 +1,2 @@
+# Test config file.
+message(WARNING "CMAKE_IGNORE_PATH failed to ignore this file!")
diff --git a/Tests/FindPackageTest/lib/cmake/zot-4.0/zot-config-version.cmake b/Tests/FindPackageTest/lib/cmake/zot-4.0/zot-config-version.cmake
new file mode 100644
index 000000000..606945f2d
--- /dev/null
+++ b/Tests/FindPackageTest/lib/cmake/zot-4.0/zot-config-version.cmake
@@ -0,0 +1,8 @@
+SET(PACKAGE_VERSION 4.0)
+IF("${PACKAGE_FIND_VERSION_MAJOR}" EQUAL 4)
+ SET(PACKAGE_VERSION_COMPATIBLE 1)
+ IF("${PACKAGE_FIND_VERSION_MINOR}" EQUAL 0)
+ SET(PACKAGE_VERSION_EXACT 1)
+ ENDIF("${PACKAGE_FIND_VERSION_MINOR}" EQUAL 0)
+ENDIF("${PACKAGE_FIND_VERSION_MAJOR}" EQUAL 4)
+
diff --git a/Tests/FindPackageTest/lib/cmake/zot-4.0/zot-config.cmake b/Tests/FindPackageTest/lib/cmake/zot-4.0/zot-config.cmake
new file mode 100644
index 000000000..deffa5729
--- /dev/null
+++ b/Tests/FindPackageTest/lib/cmake/zot-4.0/zot-config.cmake
@@ -0,0 +1 @@
+# Test config file.
diff --git a/Tests/FindPackageTest/lib/foo-1.2/CMake/FooConfig.cmake b/Tests/FindPackageTest/lib/foo-1.2/CMake/FooConfig.cmake
new file mode 100644
index 000000000..deffa5729
--- /dev/null
+++ b/Tests/FindPackageTest/lib/foo-1.2/CMake/FooConfig.cmake
@@ -0,0 +1 @@
+# Test config file.
diff --git a/Tests/FindPackageTest/lib/foo-1.2/foo-config.cmake b/Tests/FindPackageTest/lib/foo-1.2/foo-config.cmake
new file mode 100644
index 000000000..deffa5729
--- /dev/null
+++ b/Tests/FindPackageTest/lib/foo-1.2/foo-config.cmake
@@ -0,0 +1 @@
+# Test config file.
diff --git a/Tests/FindPackageTest/lib/suffix/test/SuffixTestConfig.cmake b/Tests/FindPackageTest/lib/suffix/test/SuffixTestConfig.cmake
new file mode 100644
index 000000000..deffa5729
--- /dev/null
+++ b/Tests/FindPackageTest/lib/suffix/test/SuffixTestConfig.cmake
@@ -0,0 +1 @@
+# Test config file.
diff --git a/Tests/FindPackageTest/lib/suffix/test/SuffixTestConfigVersion.cmake b/Tests/FindPackageTest/lib/suffix/test/SuffixTestConfigVersion.cmake
new file mode 100644
index 000000000..5c3bddece
--- /dev/null
+++ b/Tests/FindPackageTest/lib/suffix/test/SuffixTestConfigVersion.cmake
@@ -0,0 +1,7 @@
+SET(PACKAGE_VERSION 1.2)
+IF("${PACKAGE_FIND_VERSION_MAJOR}" EQUAL 1)
+ SET(PACKAGE_VERSION_COMPATIBLE 1)
+ IF("${PACKAGE_FIND_VERSION_MINOR}" EQUAL 2)
+ SET(PACKAGE_VERSION_EXACT 1)
+ ENDIF("${PACKAGE_FIND_VERSION_MINOR}" EQUAL 2)
+ENDIF("${PACKAGE_FIND_VERSION_MAJOR}" EQUAL 1)
diff --git a/Tests/FindPackageTest/lib/zot-1.0/zot-config.cmake b/Tests/FindPackageTest/lib/zot-1.0/zot-config.cmake
new file mode 100644
index 000000000..deffa5729
--- /dev/null
+++ b/Tests/FindPackageTest/lib/zot-1.0/zot-config.cmake
@@ -0,0 +1 @@
+# Test config file.
diff --git a/Tests/FindPackageTest/lib/zot-2.0/zot-config-version.cmake b/Tests/FindPackageTest/lib/zot-2.0/zot-config-version.cmake
new file mode 100644
index 000000000..10ac53d19
--- /dev/null
+++ b/Tests/FindPackageTest/lib/zot-2.0/zot-config-version.cmake
@@ -0,0 +1,5 @@
+SET(PACKAGE_VERSION 2.0)
+IF("${PACKAGE_FIND_VERSION_MAJOR}" EQUAL 2)
+ SET(PACKAGE_VERSION_COMPATIBLE 1)
+ENDIF("${PACKAGE_FIND_VERSION_MAJOR}" EQUAL 2)
+
diff --git a/Tests/FindPackageTest/lib/zot-2.0/zot-config.cmake b/Tests/FindPackageTest/lib/zot-2.0/zot-config.cmake
new file mode 100644
index 000000000..deffa5729
--- /dev/null
+++ b/Tests/FindPackageTest/lib/zot-2.0/zot-config.cmake
@@ -0,0 +1 @@
+# Test config file.
diff --git a/Tests/FindPackageTest/lib/zot-3.0/zot-config-version.cmake b/Tests/FindPackageTest/lib/zot-3.0/zot-config-version.cmake
new file mode 100644
index 000000000..af57cfa5c
--- /dev/null
+++ b/Tests/FindPackageTest/lib/zot-3.0/zot-config-version.cmake
@@ -0,0 +1,5 @@
+SET(PACKAGE_VERSION 3.0)
+IF("${PACKAGE_FIND_VERSION_MAJOR}" EQUAL 3)
+ SET(PACKAGE_VERSION_COMPATIBLE 1)
+ENDIF("${PACKAGE_FIND_VERSION_MAJOR}" EQUAL 3)
+
diff --git a/Tests/FindPackageTest/lib/zot-3.0/zot-config.cmake b/Tests/FindPackageTest/lib/zot-3.0/zot-config.cmake
new file mode 100644
index 000000000..deffa5729
--- /dev/null
+++ b/Tests/FindPackageTest/lib/zot-3.0/zot-config.cmake
@@ -0,0 +1 @@
+# Test config file.
diff --git a/Tests/FindPackageTest/lib/zot-3.1/zot-config-version.cmake b/Tests/FindPackageTest/lib/zot-3.1/zot-config-version.cmake
new file mode 100644
index 000000000..b54d94ce6
--- /dev/null
+++ b/Tests/FindPackageTest/lib/zot-3.1/zot-config-version.cmake
@@ -0,0 +1,8 @@
+SET(PACKAGE_VERSION 3.1)
+IF("${PACKAGE_FIND_VERSION_MAJOR}" EQUAL 3)
+ SET(PACKAGE_VERSION_COMPATIBLE 1)
+ IF("${PACKAGE_FIND_VERSION_MINOR}" EQUAL 1)
+ SET(PACKAGE_VERSION_EXACT 1)
+ ENDIF("${PACKAGE_FIND_VERSION_MINOR}" EQUAL 1)
+ENDIF("${PACKAGE_FIND_VERSION_MAJOR}" EQUAL 3)
+
diff --git a/Tests/FindPackageTest/lib/zot-3.1/zot-config.cmake b/Tests/FindPackageTest/lib/zot-3.1/zot-config.cmake
new file mode 100644
index 000000000..deffa5729
--- /dev/null
+++ b/Tests/FindPackageTest/lib/zot-3.1/zot-config.cmake
@@ -0,0 +1 @@
+# Test config file.
diff --git a/Tests/FindPackageTest/lib/zot/zot-config-version.cmake b/Tests/FindPackageTest/lib/zot/zot-config-version.cmake
new file mode 100644
index 000000000..2a6be8640
--- /dev/null
+++ b/Tests/FindPackageTest/lib/zot/zot-config-version.cmake
@@ -0,0 +1,10 @@
+# This version should never, ever be used.
+SET(PACKAGE_VERSION_UNSUITABLE 1)
+SET(PACKAGE_VERSION 3.1)
+IF("${PACKAGE_FIND_VERSION_MAJOR}" EQUAL 3)
+ SET(PACKAGE_VERSION_COMPATIBLE 1)
+ IF("${PACKAGE_FIND_VERSION_MINOR}" EQUAL 1)
+ SET(PACKAGE_VERSION_EXACT 1)
+ ENDIF("${PACKAGE_FIND_VERSION_MINOR}" EQUAL 1)
+ENDIF("${PACKAGE_FIND_VERSION_MAJOR}" EQUAL 3)
+
diff --git a/Tests/FindPackageTest/lib/zot/zot-config.cmake b/Tests/FindPackageTest/lib/zot/zot-config.cmake
new file mode 100644
index 000000000..442b8a4ec
--- /dev/null
+++ b/Tests/FindPackageTest/lib/zot/zot-config.cmake
@@ -0,0 +1,2 @@
+# Test config file that is unsuitable.
+MESSAGE(FATAL_ERROR "Unsuitable version of zot was found")
diff --git a/Tests/ForceInclude/CMakeLists.txt b/Tests/ForceInclude/CMakeLists.txt
new file mode 100644
index 000000000..5c02ebbd0
--- /dev/null
+++ b/Tests/ForceInclude/CMakeLists.txt
@@ -0,0 +1,10 @@
+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)$")
+ message(FATAL_ERROR "The ForceInclude test works only with MSVC or Intel")
+endif()
+
+add_executable(foo foo.c)
+set_property(SOURCE foo.c PROPERTY COMPILE_FLAGS "/FIfoo1.h /FIfoo2.h")
diff --git a/Tests/ForceInclude/foo.c b/Tests/ForceInclude/foo.c
new file mode 100644
index 000000000..af898f4aa
--- /dev/null
+++ b/Tests/ForceInclude/foo.c
@@ -0,0 +1,7 @@
+#ifndef FOO_1
+# error "foo1.h not included by /FI"
+#endif
+#ifndef FOO_2
+# error "foo2.h not included by /FI"
+#endif
+int main(void) { return 0; }
diff --git a/Tests/ForceInclude/foo1.h b/Tests/ForceInclude/foo1.h
new file mode 100644
index 000000000..2c1cb7bb3
--- /dev/null
+++ b/Tests/ForceInclude/foo1.h
@@ -0,0 +1 @@
+#define FOO_1
diff --git a/Tests/ForceInclude/foo2.h b/Tests/ForceInclude/foo2.h
new file mode 100644
index 000000000..e47524dfa
--- /dev/null
+++ b/Tests/ForceInclude/foo2.h
@@ -0,0 +1 @@
+#define FOO_2
diff --git a/Tests/Fortran/CMakeLists.txt b/Tests/Fortran/CMakeLists.txt
new file mode 100644
index 000000000..a995f68dd
--- /dev/null
+++ b/Tests/Fortran/CMakeLists.txt
@@ -0,0 +1,220 @@
+cmake_minimum_required (VERSION 2.6)
+project(testf C CXX Fortran)
+message("CTEST_FULL_OUTPUT ")
+set(CMAKE_VERBOSE_MAKEFILE 1)
+message("ENV_FLAGS = $ENV{FFLAGS}")
+message("CMAKE_Fortran_COMPILER_INIT = ${CMAKE_Fortran_COMPILER_INIT}")
+message("CMAKE_Fortran_COMPILER_FULLPATH = ${CMAKE_Fortran_COMPILER_FULLPATH}")
+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)$")
+ # 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")
+ # 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)
+ if("${output}" MATCHES "Red Hat .* 2\\.96")
+ set(_SHARED STATIC)
+ endif()
+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")
+ set(world_def world_gnu.def)
+ elseif("${CMAKE_Fortran_COMPILER_ID}" MATCHES "Intel" OR
+ "${CMAKE_GENERATOR}" MATCHES "Visual Studio") # Intel plugin
+ set(world_def world_icl.def)
+ endif()
+endif()
+
+add_library(hello STATIC hello.f)
+add_library(world ${_SHARED} world.f ${world_def})
+add_executable(testf testf.f)
+target_link_libraries(testf hello world)
+
+function(test_fortran_c_interface_module)
+ message(STATUS "Testing FortranCInterface module")
+ # test the C to Fortran interface module
+ include(FortranCInterface)
+ FortranCInterface_VERIFY()
+ FortranCInterface_VERIFY(CXX)
+ if(CMAKE_Fortran_COMPILER_SUPPORTS_F90)
+ if(NOT CMAKE_Fortran_COMPILER_ID MATCHES "SunPro|MIPSpro|PathScale|Absoft")
+ set(module_expected 1)
+ endif()
+ if(FortranCInterface_MODULE_FOUND OR module_expected)
+ set(srcs foo.f)
+ set(FORTRAN_FUNCTIONS test_mod:sub)
+ set(MYC_DEFS TEST_MOD)
+ else()
+ message("${CMAKE_Fortran_COMPILER_ID} compilers do not support"
+ " linking Fortran module procedures from C")
+ endif()
+ endif()
+ list(APPEND FORTRAN_FUNCTIONS my_sub mysub)
+ FortranCInterface_HEADER(foo.h
+ MACRO_NAMESPACE "FC_"
+ SYMBOL_NAMESPACE "F_"
+ SYMBOLS ${FORTRAN_FUNCTIONS}
+ )
+ include_directories("${testf_BINARY_DIR}")
+
+ # if the name mangling is not found for a F90 compiler
+ # print out some diagnostic stuff for the dashboard
+ if(NOT FortranCInterface_GLOBAL_FOUND OR
+ (NOT FortranCInterface_MODULE_FOUND AND module_expected) )
+ find_program(FortranCInterface_EXE
+ NAMES FortranCInterface
+ PATHS ${FortranCInterface_BINARY_DIR} ${FortranCInterface_BINARY_DIR}/Debug
+ NO_DEFAULT_PATH
+ )
+ find_program(DUMPBIN dumpbin)
+ find_program(NM nm)
+ if(FortranCInterface_EXE)
+ if(DEPENDS)
+ execute_process(COMMAND ${DUMPBIN} /symbols "${FortranCInterface_EXE}"
+ OUTPUT_VARIABLE out)
+ message("symbols in ${FortranCInterface_EXE}:\n${out}")
+ endif()
+ if(NM)
+ execute_process(COMMAND ${NM} "${FortranCInterface_EXE}"
+ OUTPUT_VARIABLE out)
+ message("symbols in ${FortranCInterface_EXE}:\n${out}")
+ endif()
+ endif()
+ endif()
+ message("Fortran = ${CMAKE_Fortran_COMPILER_ID}")
+ message("C = ${CMAKE_C_COMPILER_ID}")
+
+ add_library(myfort mysub.f ${srcs})
+
+ add_library(myc myc.c)
+ target_link_libraries(myc myfort)
+ set_property(TARGET myc PROPERTY COMPILE_DEFINITIONS ${MYC_DEFS})
+
+ add_library(mycxx mycxx.cxx)
+ target_link_libraries(mycxx myc)
+
+ add_executable(mainc mainc.c)
+ target_link_libraries(mainc myc)
+ add_executable(maincxx maincxx.c)
+ target_link_libraries(maincxx mycxx)
+
+ # print out some stuff to help debug on machines via cdash
+ file(READ "${testf_BINARY_DIR}/foo.h" fooh)
+ message("foo.h contents:\n${fooh}")
+endfunction()
+
+# if the id's match or the compilers are compatible, then
+# 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}" ))
+ test_fortran_c_interface_module()
+else()
+ message("Fortran does not match c compiler")
+ message("Fortran = ${CMAKE_Fortran_COMPILER_ID}")
+ message("C = ${CMAKE_C_COMPILER_ID}")
+ # 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")
+ set(CMAKE_CREATE_CONSOLE_EXE )
+ set(CMAKE_LIBRARY_PATH_FLAG "-L")
+ set(CMAKE_LINK_LIBRARY_FLAG "-l")
+ set(CMAKE_LINK_LIBRARY_SUFFIX )
+ endif()
+ # 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"))
+ set(CMAKE_EXE_LINKER_FLAGS "")
+ set(CMAKE_Fortran_FLAGS "")
+ endif()
+
+endif()
+
+
+
+
+set(TEST_MODULE_DEPENDS 0)
+if(CMAKE_Fortran_COMPILER_SUPPORTS_F90)
+ add_executable(test_module
+ test_module_main.f90
+ test_module_implementation.f90
+ test_module_interface.f90)
+
+ add_executable(test_use_in_comment_fixedform
+ test_use_in_comment_fixedform.f)
+ set_property(SOURCE test_use_in_comment_fixedform.f PROPERTY Fortran_FORMAT FIXED)
+ add_executable(test_use_in_comment_freeform
+ test_use_in_comment_freeform.f90)
+ set_property(SOURCE test_use_in_comment_freeform.f90 PROPERTY Fortran_FORMAT FREE)
+
+ add_executable(test_in_interface
+ in_interface/main.f90
+ in_interface/module.f90)
+
+ add_definitions(-DFOO -DBAR=1)
+ include_directories(${testf_SOURCE_DIR}/include)
+ add_executable(test_preprocess test_preprocess.F90)
+
+ set(TEST_MODULE_DEPENDS 1)
+endif(CMAKE_Fortran_COMPILER_SUPPORTS_F90)
+
+if(TEST_MODULE_DEPENDS)
+ # Build the external project separately using a custom target.
+ # Make sure it uses the same build configuration as this test.
+ if(CMAKE_CONFIGURATION_TYPES)
+ set(External_CONFIG_TYPE -C "${CMAKE_CFG_INTDIR}")
+ set(External_BUILD_TYPE)
+ else(CMAKE_CONFIGURATION_TYPES)
+ set(External_CONFIG_TYPE)
+ set(External_BUILD_TYPE -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE})
+ endif(CMAKE_CONFIGURATION_TYPES)
+ set(External_SOURCE_DIR "${testf_SOURCE_DIR}/External")
+ set(External_BINARY_DIR "${testf_BINARY_DIR}/External")
+ if("${testf_BINARY_DIR}" MATCHES " ")
+ # Our build tree has a space, so the build tool supports spaces.
+ # Test using modules from a path with spaces.
+ set(External_BINARY_DIR "${External_BINARY_DIR} Build")
+ endif()
+ add_custom_command(
+ OUTPUT ${testf_BINARY_DIR}/ExternalProject
+ COMMAND ${CMAKE_CTEST_COMMAND}
+ ARGS ${External_CONFIG_TYPE}
+ --build-and-test
+ ${External_SOURCE_DIR}
+ ${External_BINARY_DIR}
+ --build-noclean
+ --build-two-config
+ --build-project ExtFort
+ --build-generator ${CMAKE_GENERATOR}
+ --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}
+ ${External_BUILD_TYPE}
+ )
+ add_custom_target(ExternalTarget ALL DEPENDS ${testf_BINARY_DIR}/ExternalProject)
+
+ # Test module output directory if available.
+ if(CMAKE_Fortran_MODDIR_FLAG)
+ set(Library_MODDIR "${testf_BINARY_DIR}/Library/modules")
+ else(CMAKE_Fortran_MODDIR_FLAG)
+ set(Library_MODDIR "${testf_BINARY_DIR}/Library")
+ endif(CMAKE_Fortran_MODDIR_FLAG)
+
+ add_subdirectory(Library)
+ add_subdirectory(Executable)
+endif(TEST_MODULE_DEPENDS)
diff --git a/Tests/Fortran/Executable/CMakeLists.txt b/Tests/Fortran/Executable/CMakeLists.txt
new file mode 100644
index 000000000..55f21ad46
--- /dev/null
+++ b/Tests/Fortran/Executable/CMakeLists.txt
@@ -0,0 +1,8 @@
+include_directories(${Library_MODDIR})
+include_directories(${External_BINARY_DIR})
+link_directories(${External_BINARY_DIR})
+
+add_executable(subdir_exe2 main.f90)
+target_link_libraries(subdir_exe2 subdir_mods)
+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
new file mode 100644
index 000000000..f21156cda
--- /dev/null
+++ b/Tests/Fortran/Executable/main.f90
@@ -0,0 +1,6 @@
+PROGRAM MAINF90
+ USE libraryModuleA
+ USE libraryModuleB
+ USE externalMod
+ CALL printExtModGreeting
+END PROGRAM MAINF90
diff --git a/Tests/Fortran/External/CMakeLists.txt b/Tests/Fortran/External/CMakeLists.txt
new file mode 100644
index 000000000..0eb1cfeed
--- /dev/null
+++ b/Tests/Fortran/External/CMakeLists.txt
@@ -0,0 +1,4 @@
+project(ExtFort Fortran)
+
+add_library(myext a.f90)
+
diff --git a/Tests/Fortran/External/a.f90 b/Tests/Fortran/External/a.f90
new file mode 100644
index 000000000..2be73c53c
--- /dev/null
+++ b/Tests/Fortran/External/a.f90
@@ -0,0 +1,7 @@
+MODULE externalMod
+!
+CONTAINS
+ SUBROUTINE printExtModGreeting
+ WRITE(*,*) "Greetings from Module externalMod"
+ END SUBROUTINE
+END MODULE
diff --git a/Tests/Fortran/Library/CMakeLists.txt b/Tests/Fortran/Library/CMakeLists.txt
new file mode 100644
index 000000000..fe1368a07
--- /dev/null
+++ b/Tests/Fortran/Library/CMakeLists.txt
@@ -0,0 +1,11 @@
+INCLUDE_DIRECTORIES(${Library_MODDIR})
+ADD_LIBRARY(subdir_mods a.f90 b.f90)
+ADD_EXECUTABLE(subdir_exe main.f90)
+TARGET_LINK_LIBRARIES(subdir_exe subdir_mods)
+
+# Test module output directory if available.
+IF(CMAKE_Fortran_MODDIR_FLAG)
+ SET_TARGET_PROPERTIES(subdir_mods PROPERTIES
+ Fortran_MODULE_DIRECTORY modules
+ )
+ENDIF(CMAKE_Fortran_MODDIR_FLAG)
diff --git a/Tests/Fortran/Library/a.f90 b/Tests/Fortran/Library/a.f90
new file mode 100644
index 000000000..3031c0723
--- /dev/null
+++ b/Tests/Fortran/Library/a.f90
@@ -0,0 +1,3 @@
+MODULE libraryModuleA
+ USE libraryModuleB
+END MODULE
diff --git a/Tests/Fortran/Library/b.f90 b/Tests/Fortran/Library/b.f90
new file mode 100644
index 000000000..ae1edcb20
--- /dev/null
+++ b/Tests/Fortran/Library/b.f90
@@ -0,0 +1,2 @@
+MODULE libraryModuleB
+END MODULE
diff --git a/Tests/Fortran/Library/main.f90 b/Tests/Fortran/Library/main.f90
new file mode 100644
index 000000000..2385408a2
--- /dev/null
+++ b/Tests/Fortran/Library/main.f90
@@ -0,0 +1,3 @@
+PROGRAM MAINF90
+ USE libraryModuleA
+END PROGRAM MAINF90
diff --git a/Tests/Fortran/foo.f b/Tests/Fortran/foo.f
new file mode 100644
index 000000000..dbbb3a4e9
--- /dev/null
+++ b/Tests/Fortran/foo.f
@@ -0,0 +1,9 @@
+ module test_mod
+ interface dummy
+ module procedure sub
+ end interface
+ contains
+ subroutine sub
+ end subroutine
+
+ end module test_mod
diff --git a/Tests/Fortran/hello.f b/Tests/Fortran/hello.f
new file mode 100644
index 000000000..aa0de7715
--- /dev/null
+++ b/Tests/Fortran/hello.f
@@ -0,0 +1,6 @@
+ SUBROUTINE HELLO
+
+ PRINT *, 'Hello'
+
+ END
+
diff --git a/Tests/Fortran/in_interface/main.f90 b/Tests/Fortran/in_interface/main.f90
new file mode 100644
index 000000000..28bcf36d5
--- /dev/null
+++ b/Tests/Fortran/in_interface/main.f90
@@ -0,0 +1,3 @@
+program hello
+ use test_interface
+end program hello
diff --git a/Tests/Fortran/in_interface/module.f90 b/Tests/Fortran/in_interface/module.f90
new file mode 100644
index 000000000..1064d74b0
--- /dev/null
+++ b/Tests/Fortran/in_interface/module.f90
@@ -0,0 +1,12 @@
+module test_interface
+
+ interface dummy
+ module procedure module_function
+ end interface
+
+contains
+
+ subroutine module_function
+ end subroutine
+
+end module test_interface \ No newline at end of file
diff --git a/Tests/Fortran/include/test_preprocess.h b/Tests/Fortran/include/test_preprocess.h
new file mode 100644
index 000000000..29ac4b65f
--- /dev/null
+++ b/Tests/Fortran/include/test_preprocess.h
@@ -0,0 +1,5 @@
+#ifdef BAR
+ PRINT * , 'BAR was defined via ADD_DEFINITIONS'
+#else
+ PRINT *, 'If you can read this something went wrong'
+#endif
diff --git a/Tests/Fortran/mainc.c b/Tests/Fortran/mainc.c
new file mode 100644
index 000000000..9efafc5c0
--- /dev/null
+++ b/Tests/Fortran/mainc.c
@@ -0,0 +1,5 @@
+extern int myc(void);
+int main()
+{
+ return myc();
+}
diff --git a/Tests/Fortran/maincxx.c b/Tests/Fortran/maincxx.c
new file mode 100644
index 000000000..d35ea7e25
--- /dev/null
+++ b/Tests/Fortran/maincxx.c
@@ -0,0 +1,6 @@
+extern int myc(void);
+extern int mycxx(void);
+int main()
+{
+ return myc() + mycxx();
+}
diff --git a/Tests/Fortran/myc.c b/Tests/Fortran/myc.c
new file mode 100644
index 000000000..efd9b68aa
--- /dev/null
+++ b/Tests/Fortran/myc.c
@@ -0,0 +1,12 @@
+#include "foo.h"
+extern F_test_mod_sub(void);
+extern F_mysub(void);
+int myc(void)
+{
+ F_mysub();
+ F_my_sub();
+#ifdef TEST_MOD
+ F_test_mod_sub();
+#endif
+ return 0;
+}
diff --git a/Tests/Fortran/mycxx.cxx b/Tests/Fortran/mycxx.cxx
new file mode 100644
index 000000000..bf04062ed
--- /dev/null
+++ b/Tests/Fortran/mycxx.cxx
@@ -0,0 +1,6 @@
+extern "C" int myc(void);
+extern "C" int mycxx(void)
+{
+ delete new int;
+ return myc();
+}
diff --git a/Tests/Fortran/mysub.f b/Tests/Fortran/mysub.f
new file mode 100644
index 000000000..4b108e333
--- /dev/null
+++ b/Tests/Fortran/mysub.f
@@ -0,0 +1,5 @@
+ subroutine mysub
+ print *, 'Printing this requires fortran language libraries'
+ end subroutine
+ subroutine my_sub
+ end subroutine
diff --git a/Tests/Fortran/test_module_implementation.f90 b/Tests/Fortran/test_module_implementation.f90
new file mode 100644
index 000000000..de3cb574c
--- /dev/null
+++ b/Tests/Fortran/test_module_implementation.f90
@@ -0,0 +1,6 @@
+FUNCTION TEST_MODULE_FUNCTION(A,B)
+ REAL :: TEST_MODULE_FUNCTION
+ REAL, INTENT(IN) :: A
+ REAL, INTENT(IN) :: B
+ TEST_MODULE_FUNCTION = A + B
+END FUNCTION TEST_MODULE_FUNCTION
diff --git a/Tests/Fortran/test_module_interface.f90 b/Tests/Fortran/test_module_interface.f90
new file mode 100644
index 000000000..dd0f35c56
--- /dev/null
+++ b/Tests/Fortran/test_module_interface.f90
@@ -0,0 +1,9 @@
+MODULE TEST_MODULE
+ INTERFACE
+ FUNCTION TEST_MODULE_FUNCTION(A,B)
+ REAL :: TEST_MODULE_FUNCTION
+ REAL, INTENT(IN) :: A
+ REAL, INTENT(IN) :: B
+ END FUNCTION TEST_MODULE_FUNCTION
+ END INTERFACE
+END MODULE TEST_MODULE
diff --git a/Tests/Fortran/test_module_main.f90 b/Tests/Fortran/test_module_main.f90
new file mode 100644
index 000000000..6ac97fa91
--- /dev/null
+++ b/Tests/Fortran/test_module_main.f90
@@ -0,0 +1,4 @@
+PROGRAM MAINF90
+ USE TEST_MODULE
+ PRINT *,'Sum is',TEST_MODULE_FUNCTION(1., 2.)
+END PROGRAM MAINF90
diff --git a/Tests/Fortran/test_preprocess.F90 b/Tests/Fortran/test_preprocess.F90
new file mode 100644
index 000000000..e4f1fbe76
--- /dev/null
+++ b/Tests/Fortran/test_preprocess.F90
@@ -0,0 +1,51 @@
+MODULE Available
+! no conent
+END MODULE
+
+PROGRAM PPTEST
+! value of InPPFalseBranch ; values of SkipToEnd
+! 0 <empty>
+#ifndef FOO
+ ! 1 ; <0>
+ USE NotAvailable
+# ifndef FOO
+ ! 2 ; <0,0>
+ USE NotAvailable
+# else
+ ! 2 ; <0,0>
+ USE NotAvailable
+# endif
+ ! 1 ; <0>
+# ifdef FOO
+ ! 2 ; <0,1>
+ USE NotAvailable
+# else
+ ! 2 ; <0,1>
+ USE NotAvailable
+# endif
+ ! 1 ; <0>
+#else
+ ! 0 ; <0>
+ USE Available
+# ifndef FOO
+ ! 1 ; <0,0>
+ USE NotAvailable
+# else
+ ! 0 ; <0,0>
+ USE Available
+# endif
+ ! 0 ; <0>
+# ifdef FOO
+ ! 0 ; <0,1>
+ USE Available
+# else
+ ! 1 ; <0,1>
+ USE NotAvailable
+# endif
+ ! 0 ; <0>
+#endif
+! 0 ; <empty>
+
+#include "test_preprocess.h"
+
+END PROGRAM
diff --git a/Tests/Fortran/test_use_in_comment_fixedform.f b/Tests/Fortran/test_use_in_comment_fixedform.f
new file mode 100644
index 000000000..39f486bf9
--- /dev/null
+++ b/Tests/Fortran/test_use_in_comment_fixedform.f
@@ -0,0 +1,7 @@
+ PROGRAM foo
+! USE bar
+! use bar
+! Use bar
+
+ WRITE(*,*) 'Hello, Fortran world.'
+ END PROGRAM
diff --git a/Tests/Fortran/test_use_in_comment_freeform.f90 b/Tests/Fortran/test_use_in_comment_freeform.f90
new file mode 100644
index 000000000..c992a041b
--- /dev/null
+++ b/Tests/Fortran/test_use_in_comment_freeform.f90
@@ -0,0 +1,7 @@
+PROGRAM foo
+! USE bar
+! use bar
+! Use bar
+
+ WRITE(*,*) 'Hello, Fortran world.'
+END PROGRAM
diff --git a/Tests/Fortran/testf.f b/Tests/Fortran/testf.f
new file mode 100644
index 000000000..abf6c6df7
--- /dev/null
+++ b/Tests/Fortran/testf.f
@@ -0,0 +1,7 @@
+ PROGRAM TESTF
+
+ CALL HELLO()
+ CALL WORLD()
+
+ END
+
diff --git a/Tests/Fortran/world.f b/Tests/Fortran/world.f
new file mode 100644
index 000000000..0487dffe4
--- /dev/null
+++ b/Tests/Fortran/world.f
@@ -0,0 +1,6 @@
+ SUBROUTINE WORLD
+
+ PRINT *, 'World!'
+
+ END
+
diff --git a/Tests/Fortran/world_gnu.def b/Tests/Fortran/world_gnu.def
new file mode 100644
index 000000000..161779877
--- /dev/null
+++ b/Tests/Fortran/world_gnu.def
@@ -0,0 +1,2 @@
+EXPORTS
+ world_
diff --git a/Tests/Fortran/world_icl.def b/Tests/Fortran/world_icl.def
new file mode 100644
index 000000000..ead7710cd
--- /dev/null
+++ b/Tests/Fortran/world_icl.def
@@ -0,0 +1,2 @@
+EXPORTS
+ WORLD
diff --git a/Tests/FortranC/CMakeLists.txt b/Tests/FortranC/CMakeLists.txt
new file mode 100644
index 000000000..f33558397
--- /dev/null
+++ b/Tests/FortranC/CMakeLists.txt
@@ -0,0 +1,25 @@
+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
+ "${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()
+endif()
+
+# Wipe out all FortranCInterface information to ensure it re-runs.
+file(REMOVE_RECURSE ${CMAKE_BINARY_DIR}/CMakeFiles/FortranCInterface)
+
+if(FortranC_TEST_FLAGS)
+ # Test whether FortranCInterface checks see C flags.
+ set(ENV{TEST_OPT_CC} "--test-opt-cc=1")
+ set(CMAKE_C_FLAGS "$ENV{TEST_OPT_CC} ${CMAKE_C_FLAGS}")
+
+ # Test whether FortranCInterface checks see Fortran flags.
+ set(ENV{TEST_OPT_FC} "--test-opt-fc=1")
+ set(CMAKE_Fortran_FLAGS "$ENV{TEST_OPT_FC} ${CMAKE_Fortran_FLAGS}")
+endif()
+
+include(FortranCInterface)
+FortranCInterface_VERIFY()
diff --git a/Tests/FortranC/Flags.cmake.in b/Tests/FortranC/Flags.cmake.in
new file mode 100644
index 000000000..0b82f0ead
--- /dev/null
+++ b/Tests/FortranC/Flags.cmake.in
@@ -0,0 +1,28 @@
+set(src "@CMAKE_CURRENT_SOURCE_DIR@/FortranC")
+set(bld "@CMAKE_CURRENT_BINARY_DIR@/FortranC/Flags")
+
+# Create wrapper scripts for the compilers that check for expected
+# flags, remove them, and invoke the real compiler.
+set(ID "CC")
+set(COMMAND "@CMAKE_C_COMPILER@")
+configure_file("${src}/test_opt.sh.in" "${bld}/cc.sh" @ONLY)
+set(ID "FC")
+set(COMMAND "@CMAKE_Fortran_COMPILER@")
+configure_file("${src}/test_opt.sh.in" "${bld}/fc.sh" @ONLY)
+set(ID)
+set(COMMAND)
+
+execute_process(
+ WORKING_DIRECTORY "${bld}"
+ COMMAND ${CMAKE_COMMAND} "${src}" -G "@CMAKE_TEST_GENERATOR@"
+ "-DFortranC_TEST_FLAGS=1"
+ "-DCMAKE_C_COMPILER=${bld}/cc.sh"
+ "-DCMAKE_C_FLAGS:STRING=@CMAKE_C_FLAGS@"
+ "-DCMAKE_Fortran_COMPILER=${bld}/fc.sh"
+ "-DCMAKE_Fortran_FLAGS:STRING=@CMAKE_Fortran_FLAGS@"
+ RESULT_VARIABLE result
+ )
+
+if(NOT "${result}" STREQUAL "0")
+ message(FATAL_ERROR "Configuration failed: ${result}")
+endif()
diff --git a/Tests/FortranC/test_opt.sh.in b/Tests/FortranC/test_opt.sh.in
new file mode 100755
index 000000000..f3d93dcf1
--- /dev/null
+++ b/Tests/FortranC/test_opt.sh.in
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+TEST_OPT_@ID@_FOUND=0
+ARGS=""
+for a in "$@"; do
+ if [ "x${TEST_OPT_@ID@}" != "x" -a "x${TEST_OPT_@ID@}" = "x$a" ]; then
+ TEST_OPT_@ID@_FOUND=1
+ else
+ ARGS="$ARGS \"$a\""
+ fi
+done
+
+if [ "x${TEST_OPT_@ID@}" != "x" -a "x${TEST_OPT_@ID@_FOUND}" != "x1" ]; then
+ echo "Not given option '${TEST_OPT_@ID@}' as expected!"
+ exit 1
+fi
+
+eval "\"@COMMAND@\"" "$ARGS"
diff --git a/Tests/FortranOnly/CMakeLists.txt b/Tests/FortranOnly/CMakeLists.txt
new file mode 100644
index 000000000..d57a8b295
--- /dev/null
+++ b/Tests/FortranOnly/CMakeLists.txt
@@ -0,0 +1,45 @@
+cmake_minimum_required (VERSION 2.8)
+project(FortranOnly Fortran)
+message("CTEST_FULL_OUTPUT ")
+
+# create a library with hello and world functions
+add_library(FortranOnlylib hello.f world.f)
+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)
+
+# create a custom command that runs FortranOnly 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
+ > testfhello.txt)
+# create a second executable FortranOnly2 that has
+# testfhello.txt has an source file so that it will
+# run the above custom command.
+add_executable(FortranOnly2 testfhello.txt testf.f)
+target_link_libraries(FortranOnly2 FortranOnlylib)
+# create a custom target to check the content of testfhello.txt
+# by running the cmake script checktestf2.cmake
+add_custom_target(checktestf2 ALL
+ COMMAND ${CMAKE_COMMAND}
+ -P ${FortranOnly_SOURCE_DIR}/checktestf2.cmake)
+
+# create a custom target that runs FortranOnly 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
+)
+# make sure stuff is built in the right order
+add_dependencies(checktestf2 FortranOnly2)
+add_dependencies(sayhello FortranOnly)
+add_dependencies(FortranOnly2 FortranOnly)
+
+# add a custom target that checkes that out.txt has the correct
+# content
+add_custom_target(checksayhello ALL
+ COMMAND ${CMAKE_COMMAND} -P ${FortranOnly_SOURCE_DIR}/checksayhello.cmake
+ )
+add_dependencies(checksayhello sayhello)
diff --git a/Tests/FortranOnly/checksayhello.cmake b/Tests/FortranOnly/checksayhello.cmake
new file mode 100644
index 000000000..5352290ab
--- /dev/null
+++ b/Tests/FortranOnly/checksayhello.cmake
@@ -0,0 +1,7 @@
+file(READ out.txt IN)
+message("${IN}")
+if(IN MATCHES Hello AND IN MATCHES World)
+ message("Passed")
+else()
+ message(FATAL_ERROR "Hello world not found")
+endif()
diff --git a/Tests/FortranOnly/checktestf2.cmake b/Tests/FortranOnly/checktestf2.cmake
new file mode 100644
index 000000000..f0e6be329
--- /dev/null
+++ b/Tests/FortranOnly/checktestf2.cmake
@@ -0,0 +1,8 @@
+file(READ testfhello.txt IN)
+message("${IN}")
+if(IN MATCHES Hello AND IN MATCHES World)
+ message("Passed")
+else()
+ message(FATAL_ERROR "Hello world not found")
+endif()
+file(WRITE testfhello2.txt ${IN})
diff --git a/Tests/FortranOnly/hello.f b/Tests/FortranOnly/hello.f
new file mode 100644
index 000000000..63e64080d
--- /dev/null
+++ b/Tests/FortranOnly/hello.f
@@ -0,0 +1,5 @@
+ SUBROUTINE HELLO
+
+ PRINT *, 'Hello'
+
+ END
diff --git a/Tests/FortranOnly/testf.f b/Tests/FortranOnly/testf.f
new file mode 100644
index 000000000..490918108
--- /dev/null
+++ b/Tests/FortranOnly/testf.f
@@ -0,0 +1,6 @@
+ PROGRAM TESTF
+
+ CALL HELLO()
+ CALL WORLD()
+
+ END
diff --git a/Tests/FortranOnly/world.f b/Tests/FortranOnly/world.f
new file mode 100644
index 000000000..342b24431
--- /dev/null
+++ b/Tests/FortranOnly/world.f
@@ -0,0 +1,4 @@
+! Free-format ".f" file to test Fortran_FORMAT property
+SUBROUTINE WORLD
+ PRINT *, 'World!'
+END
diff --git a/Tests/Framework/CMakeLists.txt b/Tests/Framework/CMakeLists.txt
new file mode 100644
index 000000000..29f983810
--- /dev/null
+++ b/Tests/Framework/CMakeLists.txt
@@ -0,0 +1,80 @@
+cmake_minimum_required (VERSION 2.6)
+project(Framework)
+
+add_library(foo SHARED
+ foo.cxx
+ foo.h
+ foo2.h
+ fooExtensionlessResource
+ fooPublic.h
+ fooPublicExtensionlessHeader
+ fooPrivate.h
+ fooPrivateExtensionlessHeader
+ fooNeither.h
+ fooBoth.h
+ test.lua
+ fooDeepPublic.h
+)
+set_property(SOURCE fooDeepPublic.h
+ PROPERTY MACOSX_PACKAGE_LOCATION Headers/Deep
+ )
+set(foo_ver ver4)
+
+set_target_properties(foo PROPERTIES
+ FRAMEWORK TRUE
+ FRAMEWORK_VERSION ${foo_ver}
+ PRIVATE_HEADER "fooPrivate.h;fooBoth.h;fooPrivateExtensionlessHeader"
+ PUBLIC_HEADER "foo.h;foo2.h;fooPublic.h;fooBoth.h;fooPublicExtensionlessHeader"
+ RESOURCE "fooExtensionlessResource;test.lua"
+ INSTALL_NAME_DIR "@executable_path/../../../Library/Frameworks"
+ DEBUG_POSTFIX -d
+)
+# fooBoth.h is listed as both public and private... (private wins...)
+# fooNeither.h is listed as neither public nor private...
+
+add_executable(bar bar.cxx)
+target_link_libraries(bar foo)
+install(TARGETS foo bar
+ RUNTIME DESTINATION Applications/CMakeTestsFramework/bin
+ FRAMEWORK DESTINATION Library/Frameworks
+ LIBRARY DESTINATION lib
+ ARCHIVE DESTINATION lib
+
+ # These are ignored on the Mac... and things are automatically placed in
+ # their appropriate Framework sub-folder at build time. (And then the built
+ # framework is copied recursively when it is installed.)
+ PRIVATE_HEADER DESTINATION share/foo-${foo_ver}/PrivateHeaders
+ PUBLIC_HEADER DESTINATION include/foo-${foo_ver}
+ RESOURCE DESTINATION share/foo-${foo_ver}/Resources
+ # But they are required to be present so that installing a framework on other
+ # other platforms will install the pieces of the framework without having to
+ # duplicate install rules for the pieces of the framework.
+)
+
+# Make a static library and apply the framework properties to it to verify
+# that everything still builds correctly, but it will not actually produce
+# a framework... The framework properties only apply when the library type
+# is SHARED.
+#
+add_library(fooStatic STATIC
+ foo.cxx
+ foo.h
+ foo2.h
+ fooExtensionlessResource
+ fooPublic.h
+ fooPublicExtensionlessHeader
+ fooPrivate.h
+ fooPrivateExtensionlessHeader
+ fooNeither.h
+ fooBoth.h
+ test.lua
+ fooDeepPublic.h
+)
+set_target_properties(fooStatic PROPERTIES
+ FRAMEWORK TRUE
+ FRAMEWORK_VERSION none
+)
+add_executable(barStatic bar.cxx)
+target_link_libraries(barStatic fooStatic)
+
+include(CPack)
diff --git a/Tests/Framework/bar.cxx b/Tests/Framework/bar.cxx
new file mode 100644
index 000000000..37c132a0f
--- /dev/null
+++ b/Tests/Framework/bar.cxx
@@ -0,0 +1,6 @@
+void foo();
+int main()
+{
+ foo();
+ return 0;
+}
diff --git a/Tests/Framework/foo.cxx b/Tests/Framework/foo.cxx
new file mode 100644
index 000000000..b249ce348
--- /dev/null
+++ b/Tests/Framework/foo.cxx
@@ -0,0 +1,10 @@
+#include <stdio.h>
+#if defined(_WIN32) && defined(foo_EXPORTS)
+# define CM_TEST_LIB_EXPORT __declspec( dllexport )
+#else
+# define CM_TEST_LIB_EXPORT
+#endif
+CM_TEST_LIB_EXPORT void foo()
+{
+ printf("foo\n");
+}
diff --git a/Tests/Framework/foo.h b/Tests/Framework/foo.h
new file mode 100644
index 000000000..d959c813f
--- /dev/null
+++ b/Tests/Framework/foo.h
@@ -0,0 +1 @@
+fooh
diff --git a/Tests/Framework/foo2.h b/Tests/Framework/foo2.h
new file mode 100644
index 000000000..2431d7980
--- /dev/null
+++ b/Tests/Framework/foo2.h
@@ -0,0 +1 @@
+foo2h
diff --git a/Tests/Framework/fooBoth.h b/Tests/Framework/fooBoth.h
new file mode 100644
index 000000000..5a0f33095
--- /dev/null
+++ b/Tests/Framework/fooBoth.h
@@ -0,0 +1 @@
+fooBothh
diff --git a/Tests/Framework/fooDeepPublic.h b/Tests/Framework/fooDeepPublic.h
new file mode 100644
index 000000000..3fc410878
--- /dev/null
+++ b/Tests/Framework/fooDeepPublic.h
@@ -0,0 +1 @@
+fooDeepPublic
diff --git a/Tests/Framework/fooExtensionlessResource b/Tests/Framework/fooExtensionlessResource
new file mode 100644
index 000000000..5122750ee
--- /dev/null
+++ b/Tests/Framework/fooExtensionlessResource
@@ -0,0 +1 @@
+fooExtensionlessResource
diff --git a/Tests/Framework/fooNeither.h b/Tests/Framework/fooNeither.h
new file mode 100644
index 000000000..04736a1b1
--- /dev/null
+++ b/Tests/Framework/fooNeither.h
@@ -0,0 +1 @@
+fooNeitherh
diff --git a/Tests/Framework/fooPrivate.h b/Tests/Framework/fooPrivate.h
new file mode 100644
index 000000000..dc8cb34dc
--- /dev/null
+++ b/Tests/Framework/fooPrivate.h
@@ -0,0 +1 @@
+fooPrivateh
diff --git a/Tests/Framework/fooPrivateExtensionlessHeader b/Tests/Framework/fooPrivateExtensionlessHeader
new file mode 100644
index 000000000..ac97b929e
--- /dev/null
+++ b/Tests/Framework/fooPrivateExtensionlessHeader
@@ -0,0 +1 @@
+fooPrivateExtensionlessHeader
diff --git a/Tests/Framework/fooPublic.h b/Tests/Framework/fooPublic.h
new file mode 100644
index 000000000..f0469de6f
--- /dev/null
+++ b/Tests/Framework/fooPublic.h
@@ -0,0 +1 @@
+fooPublich
diff --git a/Tests/Framework/fooPublicExtensionlessHeader b/Tests/Framework/fooPublicExtensionlessHeader
new file mode 100644
index 000000000..972d9898d
--- /dev/null
+++ b/Tests/Framework/fooPublicExtensionlessHeader
@@ -0,0 +1 @@
+fooPublicExtensionlessHeader
diff --git a/Tests/Framework/test.lua b/Tests/Framework/test.lua
new file mode 100644
index 000000000..ce5c3eb84
--- /dev/null
+++ b/Tests/Framework/test.lua
@@ -0,0 +1 @@
+test.lua
diff --git a/Tests/FunctionTest/CMakeLists.txt b/Tests/FunctionTest/CMakeLists.txt
new file mode 100644
index 000000000..5d4f42d4a
--- /dev/null
+++ b/Tests/FunctionTest/CMakeLists.txt
@@ -0,0 +1,176 @@
+# a simple C only test case
+cmake_minimum_required (VERSION 2.6)
+PROJECT (FunctionTest)
+
+FUNCTION(FAILED testname)
+ MESSAGE(SEND_ERROR "${testname} failed ${ARGN}")
+ENDFUNCTION(FAILED)
+
+FUNCTION(PASS testname)
+ MESSAGE("${testname} passed ${ARGN}")
+ENDFUNCTION(PASS)
+
+
+# test scope
+SET(COUNT 3)
+FUNCTION(scope_test)
+ SET(COUNT 4)
+ENDFUNCTION(scope_test)
+scope_test()
+IF(COUNT EQUAL "3")
+ PASS("scope")
+ELSE(COUNT EQUAL "3")
+ FAILED("COUNT Got: ${COUNT}")
+ENDIF(COUNT EQUAL "3")
+
+# test ARGC
+FUNCTION(weird_name)
+ IF("${ARGC}" EQUAL "3")
+ PASS("ARGC")
+ ELSE("${ARGC}" EQUAL "3")
+ FAILED("ARGC" "Got: ${ARGC}")
+ ENDIF("${ARGC}" EQUAL "3")
+ENDFUNCTION(weird_name)
+WeIrD_nAmE(a1 a2 a3)
+
+# test ARGN
+FUNCTION(test_argn_function argument)
+ IF("${ARGN}" EQUAL "3")
+ PASS("ARGN")
+ ELSE("${ARGN}" EQUAL "3")
+ FAILED("ARGN" "Got: ${ARGN}")
+ ENDIF("${ARGN}" EQUAL "3")
+ENDFUNCTION(test_argn_function)
+Test_Argn_Function(ignored 3)
+
+# test argument naming and raise scope
+function(track_find_variable cache_variable is_changed)
+ set("${is_changed}" changed PARENT_SCOPE)
+endfunction(track_find_variable)
+track_find_variable(testvar is_changed)
+if ("${is_changed}" STREQUAL changed)
+ pass("same argument name test")
+else ("${is_changed}" STREQUAL changed)
+ pass("same argument name test")
+endif ("${is_changed}" STREQUAL changed)
+
+include("Util.cmake")
+tester()
+if (tester_res STREQUAL "${CMAKE_CURRENT_LIST_FILE}")
+ pass("CMAKE_CURRENT_LIST_FILE test")
+else (tester_res STREQUAL "${CMAKE_CURRENT_LIST_FILE}")
+ pass("CMAKE_CURRENT_LIST_FILE test")
+endif (tester_res STREQUAL "${CMAKE_CURRENT_LIST_FILE}")
+
+
+
+# test recursion and return via set(... PARENT_SCOPE)
+function (factorial argument result)
+ if (argument LESS 2)
+ set (lresult 1)
+ else (argument LESS 2)
+ math (EXPR temp "${argument} - 1")
+ factorial (${temp} tresult)
+ math (EXPR lresult "${argument}*${tresult}")
+ endif (argument LESS 2)
+ set ("${result}" "${lresult}" PARENT_SCOPE)
+endfunction (factorial)
+
+factorial (5 fresult)
+if (fresult EQUAL 120)
+ pass("factorial")
+else (fresult EQUAL 120)
+ failed ("factorial, computed ${fresult} instead of 120")
+endif (fresult EQUAL 120)
+
+
+
+# case test
+FUNCTION(strange_function m)
+ SET("${m}" strange_function PARENT_SCOPE)
+ENDFUNCTION(strange_function m)
+
+STRANGE_FUNCTION(var)
+set(second_var "second_var")
+IF("${var}" STREQUAL "strange_function" AND "${second_var}" STREQUAL "second_var")
+ PASS("Case Test" "(${var} ${second_var})")
+ELSE("${var}" STREQUAL "strange_function" AND "${second_var}" STREQUAL "second_var")
+ FAILED("Case test" "(${var} ${second_var})")
+ENDIF("${var}" STREQUAL "strange_function" AND "${second_var}" STREQUAL "second_var")
+
+# test backing up command
+FUNCTION(ADD_EXECUTABLE exec)
+ _ADD_EXECUTABLE(mini${exec} ${ARGN})
+ENDFUNCTION(ADD_EXECUTABLE)
+
+# var undef case
+FUNCTION(undef_var m)
+ SET("${m}" PARENT_SCOPE)
+ENDFUNCTION(undef_var)
+
+SET(FUNCTION_UNDEFINED 1)
+undef_var(FUNCTION_UNDEFINED)
+IF(DEFINED FUNCTION_UNDEFINED)
+ FAILED("Function Undefine Test" "(${FUNCTION_UNDEFINED})")
+ELSE(DEFINED FUNCTION_UNDEFINED)
+ PASS("Function Undefine Test" "(${FUNCTION_UNDEFINED})")
+ENDIF(DEFINED FUNCTION_UNDEFINED)
+
+# Subdirectory scope raise.
+SET(SUBDIR_UNDEFINED 1)
+ADD_SUBDIRECTORY(SubDirScope)
+IF(DEFINED SUBDIR_UNDEFINED)
+ FAILED("Subdir Undefine Test" "(${SUBDIR_UNDEFINED})")
+ELSE(DEFINED SUBDIR_UNDEFINED)
+ PASS("Subdir Undefine Test" "(${SUBDIR_UNDEFINED})")
+ENDIF(DEFINED SUBDIR_UNDEFINED)
+IF(DEFINED SUBDIR_DEFINED)
+ PASS("Subdir Define Test" "(${SUBDIR_DEFINED})")
+ELSE(DEFINED SUBDIR_DEFINED)
+ FAILED("Subdir Define Test" "(${SUBDIR_DEFINED})")
+ENDIF(DEFINED SUBDIR_DEFINED)
+
+# Test function-scoped directory.
+FUNCTION(ADD_SUBDIR2 dir)
+ ADD_SUBDIRECTORY("${dir}" "${dir}2")
+ # The parent scope sets in the subdir should be visible here.
+ IF(DEFINED SUBDIR_UNDEFINED)
+ FAILED("Subdir Function Undefine Test 1" "(${SUBDIR_UNDEFINED})")
+ ELSE(DEFINED SUBDIR_UNDEFINED)
+ PASS("Subdir Function Undefine Test 1" "(${SUBDIR_UNDEFINED})")
+ ENDIF(DEFINED SUBDIR_UNDEFINED)
+ IF(DEFINED SUBDIR_DEFINED)
+ PASS("Subdir Function Define Test 1" "(${SUBDIR_DEFINED})")
+ ELSE(DEFINED SUBDIR_DEFINED)
+ FAILED("Subdir Function Define Test 1" "(${SUBDIR_DEFINED})")
+ ENDIF(DEFINED SUBDIR_DEFINED)
+ENDFUNCTION(ADD_SUBDIR2)
+
+# Reset test variables.
+SET(SUBDIR_UNDEFINED 1)
+SET(SUBDIR_DEFINED)
+
+# Run test function.
+ADD_SUBDIR2(SubDirScope)
+
+# The parent scope sets in the subdir should not be visible here.
+IF(DEFINED SUBDIR_UNDEFINED)
+ PASS("Subdir Function Undefine Test 2" "(${SUBDIR_UNDEFINED})")
+ELSE(DEFINED SUBDIR_UNDEFINED)
+ FAILED("Subdir Function Undefine Test 2" "(${SUBDIR_UNDEFINED})")
+ENDIF(DEFINED SUBDIR_UNDEFINED)
+IF(DEFINED SUBDIR_DEFINED)
+ FAILED("Subdir Function Define Test 2" "(${SUBDIR_DEFINED})")
+ELSE(DEFINED SUBDIR_DEFINED)
+ PASS("Subdir Function Define Test 2" "(${SUBDIR_DEFINED})")
+ENDIF(DEFINED SUBDIR_DEFINED)
+
+ADD_EXECUTABLE(FunctionTest functionTest.c)
+
+# Use the PROJECT_LABEL property: in IDEs, the project label should appear
+# in the UI rather than the target name. If this were a good test of the
+# property rather than just a smoke test, it would verify that the label
+# actually appears in the UI of the IDE... Or at least that the text appears
+# somewhere in the generated project files.
+SET_PROPERTY(TARGET miniFunctionTest
+ PROPERTY PROJECT_LABEL "Test de Fonctionnement")
diff --git a/Tests/FunctionTest/SubDirScope/CMakeLists.txt b/Tests/FunctionTest/SubDirScope/CMakeLists.txt
new file mode 100644
index 000000000..4a53d2c0a
--- /dev/null
+++ b/Tests/FunctionTest/SubDirScope/CMakeLists.txt
@@ -0,0 +1,14 @@
+SET(SUBDIR_DEFINED 1 PARENT_SCOPE)
+SET(SUBDIR_UNDEFINED PARENT_SCOPE)
+
+# The above sets should not affect the current scope.
+IF(DEFINED SUBDIR_UNDEFINED)
+ PASS("SubdirScope Undefine Test" "(${SUBDIR_UNDEFINED})")
+ELSE(DEFINED SUBDIR_UNDEFINED)
+ FAILED("SubdirScope Undefine Test" "(${SUBDIR_UNDEFINED})")
+ENDIF(DEFINED SUBDIR_UNDEFINED)
+IF(DEFINED SUBDIR_DEFINED)
+ FAILED("SubdirScope Define Test" "(${SUBDIR_DEFINED})")
+ELSE(DEFINED SUBDIR_DEFINED)
+ PASS("SubdirScope Define Test" "(${SUBDIR_DEFINED})")
+ENDIF(DEFINED SUBDIR_DEFINED)
diff --git a/Tests/FunctionTest/Util.cmake b/Tests/FunctionTest/Util.cmake
new file mode 100644
index 000000000..f0c73b5da
--- /dev/null
+++ b/Tests/FunctionTest/Util.cmake
@@ -0,0 +1,3 @@
+function(tester)
+ set (tester_res "${CMAKE_CURRENT_LIST_FILE}" PARENT_SCOPE)
+endfunction(tester)
diff --git a/Tests/FunctionTest/functionTest.c b/Tests/FunctionTest/functionTest.c
new file mode 100644
index 000000000..e0ced6afd
--- /dev/null
+++ b/Tests/FunctionTest/functionTest.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main(int argc, char* argv[])
+{
+ printf("Running command: %s with %d arguments\n", argv[0], argc);
+ return 0;
+}
diff --git a/Tests/IPO/CMakeLists.txt b/Tests/IPO/CMakeLists.txt
new file mode 100644
index 000000000..595e4f50d
--- /dev/null
+++ b/Tests/IPO/CMakeLists.txt
@@ -0,0 +1,7 @@
+cmake_minimum_required (VERSION 2.8)
+project(IPO NONE)
+
+SET_PROPERTY(DIRECTORY PROPERTY INTERPROCEDURAL_OPTIMIZATION 1)
+
+add_subdirectory(../COnly COnly)
+add_subdirectory(../CxxOnly CxxOnly)
diff --git a/Tests/IncludeDirectories/CMakeLists.txt b/Tests/IncludeDirectories/CMakeLists.txt
new file mode 100644
index 000000000..60f5e5e6f
--- /dev/null
+++ b/Tests/IncludeDirectories/CMakeLists.txt
@@ -0,0 +1,49 @@
+cmake_minimum_required (VERSION 2.6)
+project(IncludeDirectories)
+
+file(WRITE ${CMAKE_BINARY_DIR}/Flags/Flags.h
+"//Flags.h
+")
+file(WRITE ${CMAKE_BINARY_DIR}/IncDir/IncDir.h
+"//IncDir.h
+")
+file(WRITE ${CMAKE_BINARY_DIR}/SrcProp/SrcProp.h
+"//SrcProp.h
+")
+file(WRITE ${CMAKE_BINARY_DIR}/TarProp/TarProp.h
+"//TarProp.h
+")
+
+# default to testing with full path
+# some compilers can not handle the escape for directories
+# with spaces in them.
+set(USE_FULLPATH TRUE)
+if(WATCOM OR MSVC60)
+ set(USE_FULLPATH FALSE)
+endif()
+if(USE_FULLPATH)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} \"-I${CMAKE_BINARY_DIR}/Flags\"")
+else()
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -IFlags")
+endif()
+
+include_directories(${CMAKE_BINARY_DIR}/IncDir)
+if(USE_FULLPATH)
+ set_source_files_properties(main.cpp PROPERTIES COMPILE_FLAGS
+ "\"-I${CMAKE_BINARY_DIR}/SrcProp\"")
+else()
+ set_source_files_properties(main.cpp PROPERTIES COMPILE_FLAGS
+ "-ISrcProp")
+endif()
+
+add_executable(IncludeDirectories main.cpp)
+
+if(USE_FULLPATH)
+ set_target_properties(IncludeDirectories
+ PROPERTIES COMPILE_FLAGS "\"-I${CMAKE_BINARY_DIR}/TarProp\"")
+else()
+ set_target_properties(IncludeDirectories
+ PROPERTIES COMPILE_FLAGS "-ITarProp")
+endif()
+
+add_subdirectory(TargetIncludeDirectories)
diff --git a/Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt b/Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt
new file mode 100644
index 000000000..334b8be62
--- /dev/null
+++ b/Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt
@@ -0,0 +1,24 @@
+
+cmake_minimum_required(VERSION 2.8)
+
+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")
+endmacro()
+
+create_header(bar)
+create_header(bat)
+create_header(foo)
+create_header(baz)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+include_directories("${CMAKE_CURRENT_BINARY_DIR}/bar")
+
+add_executable(TargetIncludeDirectories main.cpp)
+set_property(TARGET TargetIncludeDirectories APPEND PROPERTY INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/bat")
+set_property(TARGET TargetIncludeDirectories APPEND PROPERTY INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/foo")
+
+include_directories("${CMAKE_CURRENT_BINARY_DIR}/baz")
diff --git a/Tests/IncludeDirectories/TargetIncludeDirectories/main.cpp b/Tests/IncludeDirectories/TargetIncludeDirectories/main.cpp
new file mode 100644
index 000000000..8aa35320f
--- /dev/null
+++ b/Tests/IncludeDirectories/TargetIncludeDirectories/main.cpp
@@ -0,0 +1,10 @@
+
+#include "bar.h"
+#include "bat.h"
+#include "foo.h"
+#include "baz.h"
+
+int main(int, char**)
+{
+ return 0;
+}
diff --git a/Tests/IncludeDirectories/main.cpp b/Tests/IncludeDirectories/main.cpp
new file mode 100644
index 000000000..a59d27c39
--- /dev/null
+++ b/Tests/IncludeDirectories/main.cpp
@@ -0,0 +1,9 @@
+#include "Flags.h"
+#include "IncDir.h"
+#include "SrcProp.h"
+#include "TarProp.h"
+
+int main(int argc, char** argv)
+{
+ return 0;
+}
diff --git a/Tests/JCTest/CMakeLists.txt b/Tests/JCTest/CMakeLists.txt
new file mode 100644
index 000000000..a0f590e57
--- /dev/null
+++ b/Tests/JCTest/CMakeLists.txt
@@ -0,0 +1,9 @@
+cmake_minimum_required(VERSION 2.6)
+project(TestTime)
+enable_testing()
+add_executable(TestTime TestTime.cxx)
+
+foreach(f 1 2 3 4 5 6 7 8 9 10 11 12 12 14 15 16 17 18 19
+20 21 22 23 24 25 26 27 28 29 30)
+ add_test(TestTime${f} TestTime 50000000)
+endforeach(f)
diff --git a/Tests/JCTest/TestTime.cxx b/Tests/JCTest/TestTime.cxx
new file mode 100644
index 000000000..5768ab522
--- /dev/null
+++ b/Tests/JCTest/TestTime.cxx
@@ -0,0 +1,12 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(int ac, char** av)
+{
+ float d = 10.0;
+ for(int i =0; i < atoi(av[1]); i++)
+ {
+ d *= .2;
+ }
+ printf("%f", d);
+}
diff --git a/Tests/Java/A.java b/Tests/Java/A.java
new file mode 100644
index 000000000..e34b7046a
--- /dev/null
+++ b/Tests/Java/A.java
@@ -0,0 +1,11 @@
+class A
+{
+ public A()
+ {
+ }
+
+ public void printName()
+ {
+ System.out.println("A");
+ }
+}
diff --git a/Tests/Java/CMakeLists.txt b/Tests/Java/CMakeLists.txt
new file mode 100644
index 000000000..6a69a2464
--- /dev/null
+++ b/Tests/Java/CMakeLists.txt
@@ -0,0 +1,9 @@
+project(hello Java)
+
+cmake_minimum_required (VERSION 2.6)
+set(CMAKE_VERBOSE_MAKEFILE 1)
+
+find_package(Java COMPONENTS Development)
+include (UseJava)
+
+add_jar(hello A.java HelloWorld.java)
diff --git a/Tests/Java/HelloWorld.java b/Tests/Java/HelloWorld.java
new file mode 100644
index 000000000..54246ec26
--- /dev/null
+++ b/Tests/Java/HelloWorld.java
@@ -0,0 +1,11 @@
+class HelloWorld
+{
+ public static void main(String args[])
+ {
+ A a;
+ a = new A();
+ a.printName();
+ System.out.println("Hello World!");
+ }
+}
+
diff --git a/Tests/Jump/CMakeLists.txt b/Tests/Jump/CMakeLists.txt
new file mode 100644
index 000000000..4bdafd09b
--- /dev/null
+++ b/Tests/Jump/CMakeLists.txt
@@ -0,0 +1,6 @@
+cmake_minimum_required (VERSION 2.6)
+PROJECT(Jump)
+
+SET(CMAKE_IGNORE_DEPENDENCIES_ORDERING 1)
+ADD_SUBDIRECTORY(Executable)
+ADD_SUBDIRECTORY(Library)
diff --git a/Tests/Jump/Executable/CMakeLists.txt b/Tests/Jump/Executable/CMakeLists.txt
new file mode 100644
index 000000000..7658b7e31
--- /dev/null
+++ b/Tests/Jump/Executable/CMakeLists.txt
@@ -0,0 +1,6 @@
+IF(NOT LIBRARY_OUTPUT_PATH)
+ LINK_DIRECTORIES(${Jump_BINARY_DIR}/Library/Static
+ ${Jump_BINARY_DIR}/Library/Shared)
+ENDIF(NOT LIBRARY_OUTPUT_PATH)
+ADD_EXECUTABLE(jumpExecutable jumpExecutable.cxx)
+TARGET_LINK_LIBRARIES(jumpExecutable jumpStatic jumpShared)
diff --git a/Tests/Jump/Executable/jumpExecutable.cxx b/Tests/Jump/Executable/jumpExecutable.cxx
new file mode 100644
index 000000000..7a050c702
--- /dev/null
+++ b/Tests/Jump/Executable/jumpExecutable.cxx
@@ -0,0 +1,12 @@
+#ifdef _WIN32
+# define JUMP_IMPORT __declspec(dllimport)
+#else
+# define JUMP_IMPORT extern
+#endif
+
+extern int jumpStatic();
+JUMP_IMPORT int jumpShared();
+int main()
+{
+ return jumpShared() && jumpShared();
+}
diff --git a/Tests/Jump/Library/CMakeLists.txt b/Tests/Jump/Library/CMakeLists.txt
new file mode 100644
index 000000000..2f78c501c
--- /dev/null
+++ b/Tests/Jump/Library/CMakeLists.txt
@@ -0,0 +1,2 @@
+ADD_SUBDIRECTORY(Static)
+ADD_SUBDIRECTORY(Shared)
diff --git a/Tests/Jump/Library/Shared/CMakeLists.txt b/Tests/Jump/Library/Shared/CMakeLists.txt
new file mode 100644
index 000000000..44405770f
--- /dev/null
+++ b/Tests/Jump/Library/Shared/CMakeLists.txt
@@ -0,0 +1,26 @@
+ADD_LIBRARY(jumpShared SHARED jumpShared.cxx)
+
+IF(WIN32 OR CYGWIN)
+ SET(SHARED_MUST_BE_IN_EXE_DIR 1)
+ENDIF()
+
+IF(APPLE)
+ SET(SHARED_MUST_BE_IN_EXE_DIR 1)
+ENDIF(APPLE)
+
+IF(SHARED_MUST_BE_IN_EXE_DIR)
+ SET(LIB_NAME
+ ${CMAKE_SHARED_LIBRARY_PREFIX}jumpShared${CMAKE_SHARED_LIBRARY_SUFFIX})
+ SET(EXE_DIR ${Jump_BINARY_DIR}/Executable)
+ IF(EXECUTABLE_OUTPUT_PATH)
+ SET(EXE_DIR ${EXECUTABLE_OUTPUT_PATH})
+ ENDIF(EXECUTABLE_OUTPUT_PATH)
+ SET(LIB_DIR ${Jump_BINARY_DIR}/Library/Shared)
+ IF(LIBRARY_OUTPUT_PATH)
+ SET(LIB_DIR ${LIBRARY_OUTPUT_PATH})
+ ENDIF(LIBRARY_OUTPUT_PATH)
+ ADD_CUSTOM_COMMAND(TARGET jumpShared
+ POST_BUILD COMMAND ${CMAKE_COMMAND} ARGS -E copy
+ ${LIB_DIR}/${CMAKE_CFG_INTDIR}/${LIB_NAME}
+ ${EXE_DIR}/${CMAKE_CFG_INTDIR}/${LIB_NAME})
+ENDIF(SHARED_MUST_BE_IN_EXE_DIR)
diff --git a/Tests/Jump/Library/Shared/jumpShared.cxx b/Tests/Jump/Library/Shared/jumpShared.cxx
new file mode 100644
index 000000000..f500058cc
--- /dev/null
+++ b/Tests/Jump/Library/Shared/jumpShared.cxx
@@ -0,0 +1,7 @@
+#ifdef _WIN32
+# define JUMP_EXPORT __declspec(dllexport)
+#else
+# define JUMP_EXPORT
+#endif
+
+JUMP_EXPORT int jumpShared() { return 0; }
diff --git a/Tests/Jump/Library/Static/CMakeLists.txt b/Tests/Jump/Library/Static/CMakeLists.txt
new file mode 100644
index 000000000..23e70c0b1
--- /dev/null
+++ b/Tests/Jump/Library/Static/CMakeLists.txt
@@ -0,0 +1 @@
+ADD_LIBRARY(jumpStatic STATIC jumpStatic.cxx)
diff --git a/Tests/Jump/Library/Static/jumpStatic.cxx b/Tests/Jump/Library/Static/jumpStatic.cxx
new file mode 100644
index 000000000..1f92eb998
--- /dev/null
+++ b/Tests/Jump/Library/Static/jumpStatic.cxx
@@ -0,0 +1 @@
+int jumpStatic() { return 0; }
diff --git a/Tests/KDE4StableBranchTest/test_kde4.sh.in b/Tests/KDE4StableBranchTest/test_kde4.sh.in
new file mode 100755
index 000000000..81badcd79
--- /dev/null
+++ b/Tests/KDE4StableBranchTest/test_kde4.sh.in
@@ -0,0 +1,62 @@
+#!/bin/sh
+
+# This shell script tests whether cmake is able to build the latest
+# stable KDE4 release, or at least some part of it.
+# It downloads automoc from KDE svn, builds and installs it, then it
+# downloads phonon from KDE svn, builds and installs it, and finally
+# it downloads kdelibs (currently from the 4.3 branch), and builds
+# a (small) part of it, i.e. libkdecore and one unit test depending on it.
+#
+# <neundorf AT kde.org>
+
+CMAKE="@CMAKE_CMAKE_COMMAND@"
+BASEDIR="@TEST_KDE4_BASE_DIR@"
+INSTALLDIR="$BASEDIR/install"
+QMAKE="@QT_QMAKE_EXECUTABLE@"
+
+cd "$BASEDIR" || exit -1
+echo "Removing old install dir " $INSTALLDIR
+
+rm -rf install || exit -1
+rm -rf build-automoc || exit -1
+rm -rf build-phonon || exit -1
+rm -rf build-kdelibs || exit -1
+
+
+
+# build and install automoc
+cd "$BASEDIR" || exit -1
+svn co svn://anonsvn.kde.org/home/kde/tags/kdesupport-for-4.3/kdesupport/automoc || exit -1
+
+mkdir -p build-automoc || exit -1
+
+cd build-automoc || exit -1
+"$CMAKE" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DQT_QMAKE_EXECUTABLE:STRING="$QMAKE" ../automoc || exit -1
+"$CMAKE" --build . || exit -1
+"$CMAKE" -P cmake_install.cmake || exit -1
+
+export CMAKE_PREFIX_PATH="$INSTALLDIR:$CMAKE_PREFIX_PATH"
+
+
+# build and install phonon
+cd "$BASEDIR" || exit -1
+svn co svn://anonsvn.kde.org/home/kde/tags/kdesupport-for-4.3/kdesupport/phonon || exit -1
+
+mkdir -p build-phonon || exit -1
+
+cd build-phonon || exit -1
+"$CMAKE" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DQT_QMAKE_EXECUTABLE:STRING="$QMAKE" -DWITH_GLIB2=FALSE -DWITH_GObject=FALSE -DWITH_GStreamer=FALSE -DWITH_GStreamerPlugins=FALSE -DWITH_OpenGL=FALSE -DWITH_XCB=FALSE -DWITH_Xine=FALSE ../phonon || exit -1
+"$CMAKE" --build . || exit -1
+"$CMAKE" -P cmake_install.cmake || exit -1
+
+
+# finally build kdelibs/kdecore
+cd "$BASEDIR" || exit -1
+
+svn co svn://anonsvn.kde.org/home/kde/branches/KDE/4.3/kdelibs/ || exit -1
+mkdir -p build-kdelibs || exit -1
+cd build-kdelibs || exit -1
+# trick cmake into not searching strigi and not searching sharedmimeinfo
+"$CMAKE" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DQT_QMAKE_EXECUTABLE:STRING="$QMAKE" -DSTRIGI_FOUND=TRUE -DSTRIGI_INCLUDE_DIR=/usr/include -DSTRIGI_STREAMANALYZER_LIBRARY=-lc -DSTRIGI_STREAMS_LIBRARY=-lc -DSTRIGI_STRIGIQTDBUSCLIENT_LIBRARY=-lc -DSTRIGI_NEEDS_SIGNED_CHAR=TRUE -DSTRIGI_NEEDS_CHAR=FALSE -DUPDATE_MIME_DATABASE_EXECUTABLE=/bin/sh ../kdelibs || exit -1
+make -C kdecore/tests kurltest || exit -1
+
diff --git a/Tests/LibName/CMakeLists.txt b/Tests/LibName/CMakeLists.txt
new file mode 100644
index 000000000..07499a14d
--- /dev/null
+++ b/Tests/LibName/CMakeLists.txt
@@ -0,0 +1,26 @@
+project(LibName)
+# this is a test to make sure that relative path
+# LIBRARY_OUTPUT_PATH and EXECUTABLE_OUTPUT_PATH work
+set(LIBRARY_OUTPUT_PATH lib)
+set(EXECUTABLE_OUTPUT_PATH lib)
+
+add_library(bar SHARED bar.c)
+
+add_library(foo SHARED foo.c)
+target_link_libraries(foo bar)
+
+add_executable(foobar foobar.c)
+target_link_libraries(foobar foo)
+IF(UNIX)
+ target_link_libraries(foobar -L/usr/local/lib)
+ENDIF(UNIX)
+
+
+# check with lib version
+
+add_library(verFoo SHARED foo.c)
+target_link_libraries(verFoo bar)
+set_target_properties(verFoo PROPERTIES VERSION 3.1.4 SOVERSION 3)
+
+add_executable(verFoobar foobar.c)
+target_link_libraries(verFoobar verFoo)
diff --git a/Tests/LibName/bar.c b/Tests/LibName/bar.c
new file mode 100644
index 000000000..960718038
--- /dev/null
+++ b/Tests/LibName/bar.c
@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+
+extern void foo()
+{
+}
diff --git a/Tests/LibName/foo.c b/Tests/LibName/foo.c
new file mode 100644
index 000000000..a68970405
--- /dev/null
+++ b/Tests/LibName/foo.c
@@ -0,0 +1,11 @@
+#ifdef _WIN32
+__declspec(dllimport)
+#endif
+extern void foo();
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+ void bar()
+{
+ foo();
+}
diff --git a/Tests/LibName/foobar.c b/Tests/LibName/foobar.c
new file mode 100644
index 000000000..73b4b4156
--- /dev/null
+++ b/Tests/LibName/foobar.c
@@ -0,0 +1,10 @@
+#ifdef _WIN32
+__declspec(dllimport)
+#endif
+extern void bar();
+
+int main()
+{
+ bar();
+ return 0;
+}
diff --git a/Tests/LinkDirectory/CMakeLists.txt b/Tests/LinkDirectory/CMakeLists.txt
new file mode 100644
index 000000000..7356b27d2
--- /dev/null
+++ b/Tests/LinkDirectory/CMakeLists.txt
@@ -0,0 +1,47 @@
+cmake_minimum_required(VERSION 2.8)
+project(LinkDirectory C)
+
+# Put the subproject source tree in our build tree so it can refer to
+# link directories relative to its source.
+if(NOT "${LinkDirectory_SOURCE_DIR}" STREQUAL "${LinkDirectory_BINARY_DIR}")
+ file(COPY External/ DESTINATION External PATTERN CVS EXCLUDE)
+endif()
+
+# Build a library into the subproject source tree.
+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)
+ExternalProject_Add(ExternalTarget
+ SOURCE_DIR "${LinkDirectory_BINARY_DIR}/External"
+ BINARY_DIR "${LinkDirectory_BINARY_DIR}/External-build"
+ CMAKE_ARGS "-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=${LinkDirectory_BINARY_DIR}/bin"
+ PREFIX "${LinkDirectory_BINARY_DIR}/External-build/root"
+ DOWNLOAD_COMMAND ""
+ INSTALL_COMMAND ""
+ )
+
+# Add a step to wipe out the subproject executable after our libraries
+# change. This is needed because the subproject cannot depend on them
+# directly because it does not know the full paths to the libraries.
+# (The purpose of this test is to check that link_directories works.)
+ExternalProject_Add_Step(ExternalTarget cleanup
+ COMMAND ${CMAKE_COMMAND} -E remove_directory ${LinkDirectory_BINARY_DIR}/bin
+ DEPENDEES download
+ DEPENDERS configure
+ DEPENDS ${mylibA} ${mylibB}
+ "${LinkDirectory_BINARY_DIR}/External/CMakeLists.txt"
+ "${LinkDirectory_BINARY_DIR}/External/myexe.c"
+ )
+
+# Make the subproject build after our targets.
+add_dependencies(ExternalTarget mylibA mylibB)
diff --git a/Tests/LinkDirectory/External/CMakeLists.txt b/Tests/LinkDirectory/External/CMakeLists.txt
new file mode 100644
index 000000000..f7c840f9a
--- /dev/null
+++ b/Tests/LinkDirectory/External/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 2.8)
+project(LinkDirectoryExternal C)
+
+# Test CMP0015 OLD behavior: -L../lib
+cmake_policy(SET CMP0015 OLD)
+link_directories(../lib)
+
+# Test CMP0015 NEW behavior: -L${CMAKE_CURRENT_SOURCE_DIR}/lib
+cmake_policy(SET CMP0015 NEW)
+link_directories(lib)
+
+add_executable(myexe myexe.c)
+set_property(TARGET myexe PROPERTY OUTPUT_NAME LinkDirectory)
+target_link_libraries(myexe mylibA mylibB)
diff --git a/Tests/LinkDirectory/External/myexe.c b/Tests/LinkDirectory/External/myexe.c
new file mode 100644
index 000000000..6ef1ebe59
--- /dev/null
+++ b/Tests/LinkDirectory/External/myexe.c
@@ -0,0 +1,3 @@
+extern int mylibA(void);
+extern int mylibB(void);
+int main(void) { return mylibA() + mylibB(); }
diff --git a/Tests/LinkDirectory/mylibA.c b/Tests/LinkDirectory/mylibA.c
new file mode 100644
index 000000000..890a0890e
--- /dev/null
+++ b/Tests/LinkDirectory/mylibA.c
@@ -0,0 +1 @@
+int mylibA(void) { return 0; }
diff --git a/Tests/LinkDirectory/mylibB.c b/Tests/LinkDirectory/mylibB.c
new file mode 100644
index 000000000..090cc6ce5
--- /dev/null
+++ b/Tests/LinkDirectory/mylibB.c
@@ -0,0 +1 @@
+int mylibB(void) { return 0; }
diff --git a/Tests/LinkFlags/CMakeLists.txt b/Tests/LinkFlags/CMakeLists.txt
new file mode 100644
index 000000000..e06020c25
--- /dev/null
+++ b/Tests/LinkFlags/CMakeLists.txt
@@ -0,0 +1,28 @@
+cmake_minimum_required(VERSION 2.8)
+project(LinkFlags C)
+
+string(TOUPPER "${TEST_CONFIG}" TEST_CONFIG_UPPER)
+set(obj "${CMAKE_C_OUTPUT_EXTENSION}")
+if(BORLAND)
+ set(pre -)
+endif()
+
+add_library(LinkFlags_lib STATIC LinkFlagsLib.c)
+set_property(TARGET LinkFlags_lib PROPERTY STATIC_LIBRARY_FLAGS ${pre}BADFLAG${obj})
+
+add_library(LinkFlags_dll SHARED LinkFlagsLib.c)
+set_property(TARGET LinkFlags_dll PROPERTY LINK_FLAGS ${pre}BADFLAG${obj})
+
+add_executable(LinkFlags_exe LinkFlagsExe.c)
+set_property(TARGET LinkFlags_exe PROPERTY LINK_FLAGS ${pre}BADFLAG${obj})
+
+add_library(LinkFlags_lib_config STATIC LinkFlagsLib.c)
+set_property(TARGET LinkFlags_lib_config PROPERTY STATIC_LIBRARY_FLAGS_${TEST_CONFIG_UPPER} ${pre}BADFLAG_${TEST_CONFIG}${obj})
+
+add_library(LinkFlags_dll_config SHARED LinkFlagsLib.c)
+set_property(TARGET LinkFlags_dll_config PROPERTY LINK_FLAGS_${TEST_CONFIG_UPPER} ${pre}BADFLAG_${TEST_CONFIG}${obj})
+
+add_executable(LinkFlags_exe_config LinkFlagsExe.c)
+set_property(TARGET LinkFlags_exe_config PROPERTY LINK_FLAGS_${TEST_CONFIG_UPPER} ${pre}BADFLAG_${TEST_CONFIG}${obj})
+
+add_executable(LinkFlags LinkFlags.c)
diff --git a/Tests/LinkFlags/LinkFlags.c b/Tests/LinkFlags/LinkFlags.c
new file mode 100644
index 000000000..78f2de106
--- /dev/null
+++ b/Tests/LinkFlags/LinkFlags.c
@@ -0,0 +1 @@
+int main(void) { return 0; }
diff --git a/Tests/LinkFlags/LinkFlagsExe.c b/Tests/LinkFlags/LinkFlagsExe.c
new file mode 100644
index 000000000..123587a1f
--- /dev/null
+++ b/Tests/LinkFlags/LinkFlagsExe.c
@@ -0,0 +1,6 @@
+int main(void) { return 0; }
+
+/* Intel compiler does not reject bad flags or objects! */
+#if defined(__INTEL_COMPILER)
+# error BADFLAG
+#endif
diff --git a/Tests/LinkFlags/LinkFlagsLib.c b/Tests/LinkFlags/LinkFlagsLib.c
new file mode 100644
index 000000000..9d8d08819
--- /dev/null
+++ b/Tests/LinkFlags/LinkFlagsLib.c
@@ -0,0 +1,6 @@
+int flags_lib(void) { return 0; }
+
+/* Intel compiler does not reject bad flags or objects! */
+#if defined(__INTEL_COMPILER)
+# error BADFLAG
+#endif
diff --git a/Tests/LinkLanguage/CMakeLists.txt b/Tests/LinkLanguage/CMakeLists.txt
new file mode 100644
index 000000000..b4e53925d
--- /dev/null
+++ b/Tests/LinkLanguage/CMakeLists.txt
@@ -0,0 +1,15 @@
+cmake_minimum_required(VERSION 2.7.20090708)
+project(LinkLanguage C CXX)
+
+add_library(foo STATIC foo.cxx)
+add_executable(LinkLanguage LinkLanguage.c)
+
+# Export the target now to compute its link interface and implementation.
+# This tests that the link info is recomputed after the library is linked.
+export(TARGETS LinkLanguage FILE LinkLanguageTargets.cmake)
+
+target_link_libraries(LinkLanguage foo)
+
+# CMake should now automatically choose CXX for linking, so we need
+# not set the property:
+#set_property(TARGET LinkLanguage PROPERTY LINKER_LANGUAGE CXX)
diff --git a/Tests/LinkLanguage/LinkLanguage.c b/Tests/LinkLanguage/LinkLanguage.c
new file mode 100644
index 000000000..cf1557cab
--- /dev/null
+++ b/Tests/LinkLanguage/LinkLanguage.c
@@ -0,0 +1,6 @@
+extern int foo(void);
+int main()
+{
+ return foo();
+}
+
diff --git a/Tests/LinkLanguage/foo.cxx b/Tests/LinkLanguage/foo.cxx
new file mode 100644
index 000000000..5321c2dc0
--- /dev/null
+++ b/Tests/LinkLanguage/foo.cxx
@@ -0,0 +1,6 @@
+extern "C" int foo(void)
+{
+ // Reference C++ standard library symbols.
+ delete new int;
+ return 0;
+}
diff --git a/Tests/LinkLine/CMakeLists.txt b/Tests/LinkLine/CMakeLists.txt
new file mode 100644
index 000000000..c8f0ecf63
--- /dev/null
+++ b/Tests/LinkLine/CMakeLists.txt
@@ -0,0 +1,12 @@
+PROJECT( LinkLine )
+
+# Makes sure that the library order as specified by the user are
+# unchanged by dependency analysis, etc. libOne and libTwo are
+# dependent on each other. The link line should be -lOne -lTwo -lOne.
+
+ADD_LIBRARY( One One.c )
+ADD_LIBRARY( Two Two.c )
+
+LINK_LIBRARIES( One Two )
+ADD_EXECUTABLE( LinkLine Exec.c )
+LINK_LIBRARIES( One )
diff --git a/Tests/LinkLine/Exec.c b/Tests/LinkLine/Exec.c
new file mode 100644
index 000000000..807a7a8cc
--- /dev/null
+++ b/Tests/LinkLine/Exec.c
@@ -0,0 +1,9 @@
+void OneFunc();
+void TwoFunc();
+
+int main()
+{
+ OneFunc();
+ TwoFunc();
+ return 0;
+}
diff --git a/Tests/LinkLine/One.c b/Tests/LinkLine/One.c
new file mode 100644
index 000000000..167f07d0d
--- /dev/null
+++ b/Tests/LinkLine/One.c
@@ -0,0 +1,10 @@
+void TwoFunc();
+
+void OneFunc()
+{
+ static int i = 0;
+ ++i;
+ if( i==1 ) {
+ TwoFunc();
+ }
+}
diff --git a/Tests/LinkLine/Two.c b/Tests/LinkLine/Two.c
new file mode 100644
index 000000000..0db73a882
--- /dev/null
+++ b/Tests/LinkLine/Two.c
@@ -0,0 +1,10 @@
+void OneFunc();
+
+void TwoFunc()
+{
+ static int i = 0;
+ ++i;
+ if( i==1 ) {
+ OneFunc();
+ }
+}
diff --git a/Tests/LinkLineOrder/CMakeLists.txt b/Tests/LinkLineOrder/CMakeLists.txt
new file mode 100644
index 000000000..21a502217
--- /dev/null
+++ b/Tests/LinkLineOrder/CMakeLists.txt
@@ -0,0 +1,36 @@
+PROJECT( LinkLineOrder )
+
+# This tests ensures that the order of libraries are preserved when
+# they don't have dependency information, even if they are deep in the
+# dependency tree.
+
+# NoDepC depends on NoDepA which depends on NoDepB. NoDepE and NoDepF
+# are dependent on each other (recursive dependency). However, CMake
+# has no information about these libraries except for the order they
+# are specified in One. We must make sure we don't lose that.
+
+ADD_LIBRARY( NoDepA NoDepA.c )
+ADD_LIBRARY( NoDepB NoDepB.c )
+ADD_LIBRARY( NoDepC NoDepC.c )
+ADD_LIBRARY( NoDepE NoDepE.c )
+ADD_LIBRARY( NoDepF NoDepF.c )
+
+ADD_LIBRARY( One One.c )
+TARGET_LINK_LIBRARIES( One NoDepC NoDepA NoDepB NoDepE NoDepF NoDepE )
+
+ADD_EXECUTABLE( Exec1 Exec1.c )
+TARGET_LINK_LIBRARIES( Exec1 One )
+
+
+# Similar situation as One, except at a different level of the
+# dependency tree. This makes sure that the order is presevered
+# everywhere in the graph.
+ADD_LIBRARY( NoDepX NoDepX.c )
+ADD_LIBRARY( NoDepY NoDepY.c )
+ADD_LIBRARY( NoDepZ NoDepZ.c )
+
+ADD_LIBRARY( Two Two.c )
+TARGET_LINK_LIBRARIES( Two One NoDepZ NoDepX NoDepY )
+
+ADD_EXECUTABLE( Exec2 Exec2.c )
+TARGET_LINK_LIBRARIES( Exec2 Two )
diff --git a/Tests/LinkLineOrder/Exec1.c b/Tests/LinkLineOrder/Exec1.c
new file mode 100644
index 000000000..9bbf0f68f
--- /dev/null
+++ b/Tests/LinkLineOrder/Exec1.c
@@ -0,0 +1,8 @@
+/* Directly depends on One */
+void OneFunc();
+
+int main()
+{
+ OneFunc();
+ return 0;
+}
diff --git a/Tests/LinkLineOrder/Exec2.c b/Tests/LinkLineOrder/Exec2.c
new file mode 100644
index 000000000..91b85758e
--- /dev/null
+++ b/Tests/LinkLineOrder/Exec2.c
@@ -0,0 +1,8 @@
+/* Directly depends on Two */
+void TwoFunc();
+
+int main()
+{
+ TwoFunc();
+ return 0;
+}
diff --git a/Tests/LinkLineOrder/NoDepA.c b/Tests/LinkLineOrder/NoDepA.c
new file mode 100644
index 000000000..76f97bc8c
--- /dev/null
+++ b/Tests/LinkLineOrder/NoDepA.c
@@ -0,0 +1,7 @@
+/* depends on NoDepB */
+void NoDepB_func();
+
+void NoDepA_func()
+{
+ NoDepB_func();
+}
diff --git a/Tests/LinkLineOrder/NoDepB.c b/Tests/LinkLineOrder/NoDepB.c
new file mode 100644
index 000000000..fa89ae9ee
--- /dev/null
+++ b/Tests/LinkLineOrder/NoDepB.c
@@ -0,0 +1,4 @@
+/* No dependencies */
+void NoDepB_func()
+{
+}
diff --git a/Tests/LinkLineOrder/NoDepC.c b/Tests/LinkLineOrder/NoDepC.c
new file mode 100644
index 000000000..f05d962b7
--- /dev/null
+++ b/Tests/LinkLineOrder/NoDepC.c
@@ -0,0 +1,7 @@
+/* depends on NoDepA */
+void NoDepA_func();
+
+void NoDepC_func()
+{
+ NoDepA_func();
+}
diff --git a/Tests/LinkLineOrder/NoDepE.c b/Tests/LinkLineOrder/NoDepE.c
new file mode 100644
index 000000000..e1ba74996
--- /dev/null
+++ b/Tests/LinkLineOrder/NoDepE.c
@@ -0,0 +1,11 @@
+/* depends on NoDepF */
+void NoDepF_func();
+
+void NoDepE_func()
+{
+ static int firstcall = 1;
+ if( firstcall ) {
+ firstcall = 0;
+ NoDepF_func();
+ }
+}
diff --git a/Tests/LinkLineOrder/NoDepF.c b/Tests/LinkLineOrder/NoDepF.c
new file mode 100644
index 000000000..8311cb868
--- /dev/null
+++ b/Tests/LinkLineOrder/NoDepF.c
@@ -0,0 +1,11 @@
+/* depends on NoDepE */
+void NoDepE_func();
+
+void NoDepF_func()
+{
+ static int firstcall = 1;
+ if( firstcall ) {
+ firstcall = 0;
+ NoDepE_func();
+ }
+}
diff --git a/Tests/LinkLineOrder/NoDepX.c b/Tests/LinkLineOrder/NoDepX.c
new file mode 100644
index 000000000..c895dd11b
--- /dev/null
+++ b/Tests/LinkLineOrder/NoDepX.c
@@ -0,0 +1,7 @@
+/* depends on NoDepY*/
+void NoDepY_func();
+
+void NoDepX_func()
+{
+ NoDepY_func();
+}
diff --git a/Tests/LinkLineOrder/NoDepY.c b/Tests/LinkLineOrder/NoDepY.c
new file mode 100644
index 000000000..1e6a4aec3
--- /dev/null
+++ b/Tests/LinkLineOrder/NoDepY.c
@@ -0,0 +1,4 @@
+/* No dependencies */
+void NoDepY_func()
+{
+}
diff --git a/Tests/LinkLineOrder/NoDepZ.c b/Tests/LinkLineOrder/NoDepZ.c
new file mode 100644
index 000000000..045e5705a
--- /dev/null
+++ b/Tests/LinkLineOrder/NoDepZ.c
@@ -0,0 +1,7 @@
+/* depends on NoDepX */
+void NoDepX_func();
+
+void NoDepZ_func()
+{
+ NoDepX_func();
+}
diff --git a/Tests/LinkLineOrder/One.c b/Tests/LinkLineOrder/One.c
new file mode 100644
index 000000000..b23b1ece9
--- /dev/null
+++ b/Tests/LinkLineOrder/One.c
@@ -0,0 +1,10 @@
+/* depends on NoDepC and NoDepE (and hence on NoDepA, NoDepB and */
+/* NoDepF) */
+void NoDepC_func();
+void NoDepE_func();
+
+void OneFunc()
+{
+ NoDepC_func();
+ NoDepE_func();
+}
diff --git a/Tests/LinkLineOrder/Two.c b/Tests/LinkLineOrder/Two.c
new file mode 100644
index 000000000..6bffaa866
--- /dev/null
+++ b/Tests/LinkLineOrder/Two.c
@@ -0,0 +1,8 @@
+void OneFunc();
+void NoDepZ_func();
+
+void TwoFunc()
+{
+ OneFunc();
+ NoDepZ_func();
+}
diff --git a/Tests/LinkStatic/CMakeLists.txt b/Tests/LinkStatic/CMakeLists.txt
new file mode 100644
index 000000000..2062c4345
--- /dev/null
+++ b/Tests/LinkStatic/CMakeLists.txt
@@ -0,0 +1,27 @@
+cmake_minimum_required(VERSION 2.8.4.20110303 FATAL_ERROR)
+project(LinkStatic C)
+
+if(NOT "${CMAKE_C_COMPILER_ID}" MATCHES "^(GNU)$")
+ message(FATAL_ERROR "This test works only with the GNU compiler!")
+endif()
+
+find_library(MATH_LIBRARY NAMES libm.a)
+if(MATH_LIBRARY)
+ get_filename_component(MATH_LIB_DIR ${MATH_LIBRARY} PATH)
+ link_directories(${MATH_LIB_DIR})
+ # Name the library both with a full path and as "-lm" to
+ # activate the link type switching code for both cases.
+ # If the second one links shared then the link will fail.
+ set(MATH_LIBRARIES ${MATH_LIBRARY} -lm)
+else()
+ message(FATAL_ERROR "Cannot find libm.a needed for this test")
+endif()
+
+add_executable(LinkStatic LinkStatic.c)
+target_link_libraries(LinkStatic ${MATH_LIBRARIES})
+
+# Enable static linking.
+set(LinkStatic_FLAG "-static" CACHE STRING "Flag to link statically")
+set_property(TARGET LinkStatic PROPERTY LINK_FLAGS "${LinkStatic_FLAG}")
+set_property(TARGET LinkStatic PROPERTY LINK_SEARCH_START_STATIC 1)
+#set_property(TARGET LinkStatic PROPERTY LINK_SEARCH_END_STATIC 1) # insufficient
diff --git a/Tests/LinkStatic/LinkStatic.c b/Tests/LinkStatic/LinkStatic.c
new file mode 100644
index 000000000..360097744
--- /dev/null
+++ b/Tests/LinkStatic/LinkStatic.c
@@ -0,0 +1,5 @@
+#include <math.h>
+int main(void)
+{
+ return (int)sin(0);
+}
diff --git a/Tests/LoadCommand/CMakeCommands/CMakeLists.txt b/Tests/LoadCommand/CMakeCommands/CMakeLists.txt
new file mode 100644
index 000000000..5cdbc59bf
--- /dev/null
+++ b/Tests/LoadCommand/CMakeCommands/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required (VERSION 2.6)
+PROJECT(CMAKE_LOADED_COMMANDS)
+
+IF (MUDSLIDE_TYPE MATCHES MUCHO)
+ ADD_DEFINITIONS(-DMUCHO_MUDSLIDE)
+ENDIF (MUDSLIDE_TYPE MATCHES MUCHO)
+
+INCLUDE_DIRECTORIES(${CMAKE_ROOT}/include ${CMAKE_ROOT}/Source)
+
+ADD_LIBRARY(cmCMAKE_TEST_COMMAND MODULE cmTestCommand.c)
+
+IF(WATCOM)
+ TARGET_LINK_LIBRARIES(cmCMAKE_TEST_COMMAND clbsdll.lib)
+ENDIF(WATCOM)
diff --git a/Tests/LoadCommand/CMakeCommands/cmTestCommand.c b/Tests/LoadCommand/CMakeCommands/cmTestCommand.c
new file mode 100644
index 000000000..6b4f48f7b
--- /dev/null
+++ b/Tests/LoadCommand/CMakeCommands/cmTestCommand.c
@@ -0,0 +1,219 @@
+#include "cmCPluginAPI.h"
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+typedef struct
+{
+ char *LibraryName;
+ int Argc;
+ char** Argv;
+} cmVTKWrapTclData;
+
+/* do almost everything in the initial pass */
+static int CCONV InitialPass(void *inf, void *mf, int argc, char *argv[])
+{
+ char* file;
+ char* str;
+ char *srcs;
+ const char* cstr;
+ char buffer[1024];
+ void *source_file;
+ char *args[2];
+ char *ccArgs[4];
+ char *ccDep[1];
+ char *ccOut[1];
+ cmLoadedCommandInfo *info = (cmLoadedCommandInfo *)inf;
+
+ cmVTKWrapTclData *cdata =
+ (cmVTKWrapTclData *)malloc(sizeof(cmVTKWrapTclData));
+ cdata->LibraryName = "BOO";
+ cdata->Argc = argc;
+ cdata->Argv = argv;
+ info->CAPI->SetClientData(info,cdata);
+
+ /* 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 */
+ if(!info->CAPI->IsOn(mf,"TEST_COMMAND_TEST1"))
+ {
+ info->CAPI->AddDefinition(mf, "TEST_DEF", "HOO");
+ return 1;
+ }
+
+ info->CAPI->AddDefinition(mf, "TEST_DEF", "HOO");
+ cdata->LibraryName = "HOO";
+
+ info->CAPI->AddCacheDefinition(mf, "SOME_CACHE_VARIABLE", "ON",
+ "Test cache variable",
+ CM_CACHE_BOOL);
+ info->CAPI->AddCacheDefinition(mf, "SOME_CACHE_VARIABLE1", "",
+ "Test cache variable 1",
+ CM_CACHE_PATH);
+ info->CAPI->AddCacheDefinition(mf, "SOME_CACHE_VARIABLE2", "",
+ "Test cache variable 2",
+ CM_CACHE_FILEPATH);
+ info->CAPI->AddCacheDefinition(mf, "SOME_CACHE_VARIABLE3", "",
+ "Test cache variable 3",
+ CM_CACHE_STRING);
+ info->CAPI->AddCacheDefinition(mf, "SOME_CACHE_VARIABLE4", "",
+ "Test cache variable 4",
+ CM_CACHE_INTERNAL);
+ info->CAPI->AddCacheDefinition(mf, "SOME_CACHE_VARIABLE5", "",
+ "Test cache variable 5",
+ CM_CACHE_STATIC);
+
+
+ file = info->CAPI->ExpandVariablesInString(mf, "${CMAKE_COMMAND}", 0, 0);
+
+ str = info->CAPI->GetFilenameWithoutExtension(file);
+ info->CAPI->DisplaySatus(mf, str);
+ info->CAPI->Free(str);
+ str = info->CAPI->GetFilenamePath(file);
+ info->CAPI->DisplaySatus(mf, str);
+ info->CAPI->Free(str);
+ str = info->CAPI->Capitalized("cmake");
+ info->CAPI->DisplaySatus(mf, str);
+ info->CAPI->Free(str);
+
+ info->CAPI->DisplaySatus(mf, info->CAPI->GetProjectName(mf));
+ info->CAPI->DisplaySatus(mf, info->CAPI->GetHomeDirectory(mf));
+ info->CAPI->DisplaySatus(mf, info->CAPI->GetHomeOutputDirectory(mf));
+ info->CAPI->DisplaySatus(mf, info->CAPI->GetStartDirectory(mf));
+ info->CAPI->DisplaySatus(mf, info->CAPI->GetStartOutputDirectory(mf));
+ info->CAPI->DisplaySatus(mf, info->CAPI->GetCurrentDirectory(mf));
+ info->CAPI->DisplaySatus(mf, info->CAPI->GetCurrentOutputDirectory(mf));
+ sprintf(buffer, "Cache version: %d.%d, CMake version: %d.%d",
+ info->CAPI->GetCacheMajorVersion(mf),
+ info->CAPI->GetCacheMinorVersion(mf),
+ info->CAPI->GetMajorVersion(mf),
+ info->CAPI->GetMinorVersion(mf));
+ info->CAPI->DisplaySatus(mf, buffer);
+ if ( info->CAPI->CommandExists(mf, "SET") )
+ {
+ info->CAPI->DisplaySatus(mf, "Command SET exists");
+ }
+ if ( info->CAPI->CommandExists(mf, "SET_FOO_BAR") )
+ {
+ info->CAPI->SetError(mf, "Command SET_FOO_BAR should not exists");
+ return 0;
+ }
+ info->CAPI->AddDefineFlag(mf, "-DADDED_DEFINITION");
+
+ source_file = info->CAPI->CreateNewSourceFile(mf);
+ cstr = info->CAPI->SourceFileGetSourceName(source_file);
+ sprintf(buffer, "Shold be empty (source file name): [%s]", cstr);
+ info->CAPI->DisplaySatus(mf, buffer);
+ cstr = info->CAPI->SourceFileGetFullPath(source_file);
+ sprintf(buffer, "Should be empty (source file full path): [%s]", cstr);
+ info->CAPI->DisplaySatus(mf, buffer);
+ info->CAPI->DefineSourceFileProperty(mf,"SOME_PROPERTY","unused old prop",
+ "This property is no longer used",
+ 0);
+ if ( info->CAPI->SourceFileGetPropertyAsBool(source_file, "SOME_PROPERTY") )
+ {
+ info->CAPI->SetError(mf, "Property SOME_PROPERTY should not be defined");
+ return 0;
+ }
+ info->CAPI->DefineSourceFileProperty(mf,"SOME_PROPERTY2","nice prop",
+ "This property is for testing.",
+ 0);
+ info->CAPI->SourceFileSetProperty(source_file, "SOME_PROPERTY2", "HERE");
+ cstr = info->CAPI->SourceFileGetProperty(source_file, "ABSTRACT");
+ sprintf(buffer, "Should be 0 (source file abstract property): [%p]", cstr);
+ info->CAPI->DisplaySatus(mf, buffer);
+
+ info->CAPI->DestroySourceFile(source_file);
+
+ srcs = argv[2];
+ info->CAPI->AddExecutable(mf,"LoadedCommand",1, &srcs, 0);
+
+ /* add customs commands to generate the source file */
+ ccArgs[0] = "-E";
+ ccArgs[1] = "copy";
+ ccArgs[2] = argv[0];
+ ccArgs[3] = argv[1];
+ ccDep[0] = ccArgs[2];
+ ccOut[0] = ccArgs[3];
+ info->CAPI->AddCustomCommand(mf, "LoadedCommand.cxx.in",
+ file,
+ 4, ccArgs,
+ 1, ccDep,
+ 1, ccOut,
+ "LoadedCommand");
+
+
+ ccArgs[2] = argv[1];
+ ccArgs[3] = argv[2];
+ ccDep[0] = ccArgs[2];
+ ccOut[0] = ccArgs[3];
+ info->CAPI->AddCustomCommandToOutput(mf, ccOut[0],
+ file,
+ 4, ccArgs,
+ ccDep[0],
+ 0, 0);
+
+
+ ccArgs[1] = "echo";
+ ccArgs[2] = "Build has finished";
+ info->CAPI->AddCustomCommandToTarget(mf, "LoadedCommand",
+ file,
+ 3, ccArgs,
+ CM_POST_BUILD);
+
+ info->CAPI->Free(file);
+
+ args[0] = "TEST_EXEC";
+ args[1] = "TRUE";
+
+ /* code coverage */
+ if (info->CAPI->GetTotalArgumentSize(2,args) != 13)
+ {
+ return 0;
+ }
+ info->CAPI->ExecuteCommand(mf,"SET",2,args);
+
+ /* make sure we can find the source file */
+ if (!info->CAPI->GetSource(mf,argv[1]))
+ {
+ info->CAPI->SetError(mf, "Source file could not be found!");
+ return 0;
+ }
+
+ return 1;
+}
+
+static void CCONV FinalPass(void *inf, void *mf)
+{
+ cmLoadedCommandInfo *info = (cmLoadedCommandInfo *)inf;
+ /* get our client data from initial pass */
+ cmVTKWrapTclData *cdata =
+ (cmVTKWrapTclData *)info->CAPI->GetClientData(info);
+ if (strcmp(info->CAPI->GetDefinition(mf, "TEST_DEF"),"HOO") ||
+ strcmp(cdata->LibraryName,"HOO"))
+ {
+ fprintf(stderr,"*** Failed LOADED COMMAND Final Pass\n");
+ }
+}
+static void CCONV Destructor(void *inf)
+{
+ cmLoadedCommandInfo *info = (cmLoadedCommandInfo *)inf;
+ /* get our client data from initial pass */
+ cmVTKWrapTclData *cdata =
+ (cmVTKWrapTclData *)info->CAPI->GetClientData(info);
+ free(cdata);
+}
+
+#ifdef MUCHO_MUDSLIDE
+void CM_PLUGIN_EXPORT CCONV CMAKE_TEST_COMMANDInit(cmLoadedCommandInfo *info)
+{
+ info->InitialPass = InitialPass;
+ info->FinalPass = FinalPass;
+ info->Destructor = Destructor;
+ info->m_Inherited = 0;
+ info->Name = "CMAKE_TEST_COMMAND";
+}
+#endif
+
+
+
+
diff --git a/Tests/LoadCommand/CMakeLists.txt b/Tests/LoadCommand/CMakeLists.txt
new file mode 100644
index 000000000..846cbb084
--- /dev/null
+++ b/Tests/LoadCommand/CMakeLists.txt
@@ -0,0 +1,63 @@
+cmake_minimum_required (VERSION 2.6)
+PROJECT(LoadCommand)
+
+# set a definition
+SET (TEST_COMMAND_TEST1 1)
+
+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)
+
+INCLUDE_DIRECTORIES(${LoadCommand_BINARY_DIR})
+
+# try to compile the command
+# make sure it is not already loaded
+IF(COMMAND CMAKE_TEST_COMMAND)
+ELSE(COMMAND CMAKE_TEST_COMMAND)
+ TRY_COMPILE(COMPILE_OK
+ ${LoadCommand_BINARY_DIR}/CMakeCommands
+ ${LoadCommand_SOURCE_DIR}/CMakeCommands
+ CMAKE_LOADED_COMMANDS CMAKE_FLAGS -DMUDSLIDE_TYPE:STRING=MUCHO
+ OUTPUT_VARIABLE OUTPUT )
+# do another TRY_COMPILE to get around make
+# problem on hp
+ TRY_COMPILE(COMPILE_OK
+ ${LoadCommand_BINARY_DIR}/CMakeCommands
+ ${LoadCommand_SOURCE_DIR}/CMakeCommands
+ CMAKE_LOADED_COMMANDS CMAKE_FLAGS -DMUDSLIDE_TYPE:STRING=MUCHO
+ OUTPUT_VARIABLE OUTPUT )
+ENDIF(COMMAND CMAKE_TEST_COMMAND)
+
+MESSAGE("Output from try compile: ${OUTPUT}")
+
+# if the compile was OK, try loading the command
+IF (COMPILE_OK)
+ LOAD_COMMAND(CMAKE_TEST_COMMAND
+ ${LoadCommand_BINARY_DIR}/CMakeCommands
+ ${LoadCommand_BINARY_DIR}/CMakeCommands/Debug
+ ${LoadCommand_BINARY_DIR}/CMakeCommands/Development
+ )
+ # if the command loaded, execute the command
+ IF (COMMAND CMAKE_TEST_COMMAND)
+ CMAKE_TEST_COMMAND(
+ "${LoadCommand_SOURCE_DIR}/LoadedCommand.cxx.in"
+ "${LoadCommand_BINARY_DIR}/LoadedCommand2.cxx.in"
+ "${LoadCommand_BINARY_DIR}/LoadedCommand3.cxx"
+ )
+ ENDIF (COMMAND CMAKE_TEST_COMMAND)
+ELSE (COMPILE_OK)
+ MESSAGE("failed to compile CMAKE_LOADED_COMMANDS")
+ENDIF (COMPILE_OK)
+
+# TEST_DEF is set by the loaded command cmTestCommand.c
+IF (TEST_DEF AND SOME_CACHE_VARIABLE AND TEST_EXEC)
+ ADD_DEFINITIONS(-DCMAKE_IS_FUN)
+ENDIF (TEST_DEF AND SOME_CACHE_VARIABLE AND TEST_EXEC)
+
diff --git a/Tests/LoadCommand/LoadedCommand.cxx.in b/Tests/LoadCommand/LoadedCommand.cxx.in
new file mode 100644
index 000000000..c58bcf153
--- /dev/null
+++ b/Tests/LoadCommand/LoadedCommand.cxx.in
@@ -0,0 +1,41 @@
+#include "LoadedCommand.h"
+#include <stdio.h>
+
+int testSizeOf(int s1, int s2)
+{
+ return s1 - 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");
+ ret= 1;
+#endif
+#if !defined(CMAKE_IS_FUN)
+ printf("Loaded Command was not built with CMAKE_IS_FUN: failed.\n");
+ ret = 1;
+#endif
+ if(testSizeOf(SIZEOF_CHAR, sizeof(char)))
+ {
+ printf("Size of char is broken.\n");
+ ret = 1;
+ }
+ if(testSizeOf(SIZEOF_SHORT, sizeof(short)))
+ {
+ printf("Size of short is broken.\n");
+ ret = 1;
+ }
+ return ret;
+}
diff --git a/Tests/LoadCommand/LoadedCommand.h.in b/Tests/LoadCommand/LoadedCommand.h.in
new file mode 100644
index 000000000..7516a66e5
--- /dev/null
+++ b/Tests/LoadCommand/LoadedCommand.h.in
@@ -0,0 +1,7 @@
+/* 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/CMakeCommands/CMakeLists.txt b/Tests/LoadCommandOneConfig/CMakeCommands/CMakeLists.txt
new file mode 100644
index 000000000..953d05c99
--- /dev/null
+++ b/Tests/LoadCommandOneConfig/CMakeCommands/CMakeLists.txt
@@ -0,0 +1,17 @@
+cmake_minimum_required (VERSION 2.6)
+PROJECT(CMAKE_LOADED_COMMANDS)
+
+IF (MUDSLIDE_TYPE MATCHES MUCHO)
+ ADD_DEFINITIONS(-DMUCHO_MUDSLIDE)
+ENDIF (MUDSLIDE_TYPE MATCHES MUCHO)
+
+IF(WATCOM)
+ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
+ENDIF(WATCOM)
+INCLUDE_DIRECTORIES(${CMAKE_ROOT}/include ${CMAKE_ROOT}/Source)
+
+ADD_LIBRARY(cmCMAKE_TEST_COMMAND MODULE cmTestCommand.c)
+
+IF(WATCOM)
+ TARGET_LINK_LIBRARIES(cmCMAKE_TEST_COMMAND clbsdll.lib)
+ENDIF(WATCOM)
diff --git a/Tests/LoadCommandOneConfig/CMakeCommands/cmTestCommand.c b/Tests/LoadCommandOneConfig/CMakeCommands/cmTestCommand.c
new file mode 100644
index 000000000..6b4f48f7b
--- /dev/null
+++ b/Tests/LoadCommandOneConfig/CMakeCommands/cmTestCommand.c
@@ -0,0 +1,219 @@
+#include "cmCPluginAPI.h"
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+typedef struct
+{
+ char *LibraryName;
+ int Argc;
+ char** Argv;
+} cmVTKWrapTclData;
+
+/* do almost everything in the initial pass */
+static int CCONV InitialPass(void *inf, void *mf, int argc, char *argv[])
+{
+ char* file;
+ char* str;
+ char *srcs;
+ const char* cstr;
+ char buffer[1024];
+ void *source_file;
+ char *args[2];
+ char *ccArgs[4];
+ char *ccDep[1];
+ char *ccOut[1];
+ cmLoadedCommandInfo *info = (cmLoadedCommandInfo *)inf;
+
+ cmVTKWrapTclData *cdata =
+ (cmVTKWrapTclData *)malloc(sizeof(cmVTKWrapTclData));
+ cdata->LibraryName = "BOO";
+ cdata->Argc = argc;
+ cdata->Argv = argv;
+ info->CAPI->SetClientData(info,cdata);
+
+ /* 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 */
+ if(!info->CAPI->IsOn(mf,"TEST_COMMAND_TEST1"))
+ {
+ info->CAPI->AddDefinition(mf, "TEST_DEF", "HOO");
+ return 1;
+ }
+
+ info->CAPI->AddDefinition(mf, "TEST_DEF", "HOO");
+ cdata->LibraryName = "HOO";
+
+ info->CAPI->AddCacheDefinition(mf, "SOME_CACHE_VARIABLE", "ON",
+ "Test cache variable",
+ CM_CACHE_BOOL);
+ info->CAPI->AddCacheDefinition(mf, "SOME_CACHE_VARIABLE1", "",
+ "Test cache variable 1",
+ CM_CACHE_PATH);
+ info->CAPI->AddCacheDefinition(mf, "SOME_CACHE_VARIABLE2", "",
+ "Test cache variable 2",
+ CM_CACHE_FILEPATH);
+ info->CAPI->AddCacheDefinition(mf, "SOME_CACHE_VARIABLE3", "",
+ "Test cache variable 3",
+ CM_CACHE_STRING);
+ info->CAPI->AddCacheDefinition(mf, "SOME_CACHE_VARIABLE4", "",
+ "Test cache variable 4",
+ CM_CACHE_INTERNAL);
+ info->CAPI->AddCacheDefinition(mf, "SOME_CACHE_VARIABLE5", "",
+ "Test cache variable 5",
+ CM_CACHE_STATIC);
+
+
+ file = info->CAPI->ExpandVariablesInString(mf, "${CMAKE_COMMAND}", 0, 0);
+
+ str = info->CAPI->GetFilenameWithoutExtension(file);
+ info->CAPI->DisplaySatus(mf, str);
+ info->CAPI->Free(str);
+ str = info->CAPI->GetFilenamePath(file);
+ info->CAPI->DisplaySatus(mf, str);
+ info->CAPI->Free(str);
+ str = info->CAPI->Capitalized("cmake");
+ info->CAPI->DisplaySatus(mf, str);
+ info->CAPI->Free(str);
+
+ info->CAPI->DisplaySatus(mf, info->CAPI->GetProjectName(mf));
+ info->CAPI->DisplaySatus(mf, info->CAPI->GetHomeDirectory(mf));
+ info->CAPI->DisplaySatus(mf, info->CAPI->GetHomeOutputDirectory(mf));
+ info->CAPI->DisplaySatus(mf, info->CAPI->GetStartDirectory(mf));
+ info->CAPI->DisplaySatus(mf, info->CAPI->GetStartOutputDirectory(mf));
+ info->CAPI->DisplaySatus(mf, info->CAPI->GetCurrentDirectory(mf));
+ info->CAPI->DisplaySatus(mf, info->CAPI->GetCurrentOutputDirectory(mf));
+ sprintf(buffer, "Cache version: %d.%d, CMake version: %d.%d",
+ info->CAPI->GetCacheMajorVersion(mf),
+ info->CAPI->GetCacheMinorVersion(mf),
+ info->CAPI->GetMajorVersion(mf),
+ info->CAPI->GetMinorVersion(mf));
+ info->CAPI->DisplaySatus(mf, buffer);
+ if ( info->CAPI->CommandExists(mf, "SET") )
+ {
+ info->CAPI->DisplaySatus(mf, "Command SET exists");
+ }
+ if ( info->CAPI->CommandExists(mf, "SET_FOO_BAR") )
+ {
+ info->CAPI->SetError(mf, "Command SET_FOO_BAR should not exists");
+ return 0;
+ }
+ info->CAPI->AddDefineFlag(mf, "-DADDED_DEFINITION");
+
+ source_file = info->CAPI->CreateNewSourceFile(mf);
+ cstr = info->CAPI->SourceFileGetSourceName(source_file);
+ sprintf(buffer, "Shold be empty (source file name): [%s]", cstr);
+ info->CAPI->DisplaySatus(mf, buffer);
+ cstr = info->CAPI->SourceFileGetFullPath(source_file);
+ sprintf(buffer, "Should be empty (source file full path): [%s]", cstr);
+ info->CAPI->DisplaySatus(mf, buffer);
+ info->CAPI->DefineSourceFileProperty(mf,"SOME_PROPERTY","unused old prop",
+ "This property is no longer used",
+ 0);
+ if ( info->CAPI->SourceFileGetPropertyAsBool(source_file, "SOME_PROPERTY") )
+ {
+ info->CAPI->SetError(mf, "Property SOME_PROPERTY should not be defined");
+ return 0;
+ }
+ info->CAPI->DefineSourceFileProperty(mf,"SOME_PROPERTY2","nice prop",
+ "This property is for testing.",
+ 0);
+ info->CAPI->SourceFileSetProperty(source_file, "SOME_PROPERTY2", "HERE");
+ cstr = info->CAPI->SourceFileGetProperty(source_file, "ABSTRACT");
+ sprintf(buffer, "Should be 0 (source file abstract property): [%p]", cstr);
+ info->CAPI->DisplaySatus(mf, buffer);
+
+ info->CAPI->DestroySourceFile(source_file);
+
+ srcs = argv[2];
+ info->CAPI->AddExecutable(mf,"LoadedCommand",1, &srcs, 0);
+
+ /* add customs commands to generate the source file */
+ ccArgs[0] = "-E";
+ ccArgs[1] = "copy";
+ ccArgs[2] = argv[0];
+ ccArgs[3] = argv[1];
+ ccDep[0] = ccArgs[2];
+ ccOut[0] = ccArgs[3];
+ info->CAPI->AddCustomCommand(mf, "LoadedCommand.cxx.in",
+ file,
+ 4, ccArgs,
+ 1, ccDep,
+ 1, ccOut,
+ "LoadedCommand");
+
+
+ ccArgs[2] = argv[1];
+ ccArgs[3] = argv[2];
+ ccDep[0] = ccArgs[2];
+ ccOut[0] = ccArgs[3];
+ info->CAPI->AddCustomCommandToOutput(mf, ccOut[0],
+ file,
+ 4, ccArgs,
+ ccDep[0],
+ 0, 0);
+
+
+ ccArgs[1] = "echo";
+ ccArgs[2] = "Build has finished";
+ info->CAPI->AddCustomCommandToTarget(mf, "LoadedCommand",
+ file,
+ 3, ccArgs,
+ CM_POST_BUILD);
+
+ info->CAPI->Free(file);
+
+ args[0] = "TEST_EXEC";
+ args[1] = "TRUE";
+
+ /* code coverage */
+ if (info->CAPI->GetTotalArgumentSize(2,args) != 13)
+ {
+ return 0;
+ }
+ info->CAPI->ExecuteCommand(mf,"SET",2,args);
+
+ /* make sure we can find the source file */
+ if (!info->CAPI->GetSource(mf,argv[1]))
+ {
+ info->CAPI->SetError(mf, "Source file could not be found!");
+ return 0;
+ }
+
+ return 1;
+}
+
+static void CCONV FinalPass(void *inf, void *mf)
+{
+ cmLoadedCommandInfo *info = (cmLoadedCommandInfo *)inf;
+ /* get our client data from initial pass */
+ cmVTKWrapTclData *cdata =
+ (cmVTKWrapTclData *)info->CAPI->GetClientData(info);
+ if (strcmp(info->CAPI->GetDefinition(mf, "TEST_DEF"),"HOO") ||
+ strcmp(cdata->LibraryName,"HOO"))
+ {
+ fprintf(stderr,"*** Failed LOADED COMMAND Final Pass\n");
+ }
+}
+static void CCONV Destructor(void *inf)
+{
+ cmLoadedCommandInfo *info = (cmLoadedCommandInfo *)inf;
+ /* get our client data from initial pass */
+ cmVTKWrapTclData *cdata =
+ (cmVTKWrapTclData *)info->CAPI->GetClientData(info);
+ free(cdata);
+}
+
+#ifdef MUCHO_MUDSLIDE
+void CM_PLUGIN_EXPORT CCONV CMAKE_TEST_COMMANDInit(cmLoadedCommandInfo *info)
+{
+ info->InitialPass = InitialPass;
+ info->FinalPass = FinalPass;
+ info->Destructor = Destructor;
+ info->m_Inherited = 0;
+ info->Name = "CMAKE_TEST_COMMAND";
+}
+#endif
+
+
+
+
diff --git a/Tests/LoadCommandOneConfig/CMakeLists.txt b/Tests/LoadCommandOneConfig/CMakeLists.txt
new file mode 100644
index 000000000..e99105a74
--- /dev/null
+++ b/Tests/LoadCommandOneConfig/CMakeLists.txt
@@ -0,0 +1,69 @@
+cmake_minimum_required (VERSION 2.6)
+PROJECT(LoadCommand)
+
+# set a definition
+SET (TEST_COMMAND_TEST1 1)
+
+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)
+
+INCLUDE (${CMAKE_ROOT}/Modules/CheckLibraryExists.cmake)
+CHECK_LIBRARY_EXISTS(m ceil "" HAVE_LIBM)
+
+CONFIGURE_FILE(${LoadCommand_SOURCE_DIR}/LoadedCommand.h.in
+ ${LoadCommand_BINARY_DIR}/LoadedCommand.h)
+
+INCLUDE_DIRECTORIES(${LoadCommand_BINARY_DIR})
+
+# try to compile the command
+# make sure it is not already loaded
+IF(COMMAND CMAKE_TEST_COMMAND)
+ELSE(COMMAND CMAKE_TEST_COMMAND)
+ TRY_COMPILE(COMPILE_OK
+ ${LoadCommand_BINARY_DIR}/CMakeCommands
+ ${LoadCommand_SOURCE_DIR}/CMakeCommands
+ CMAKE_LOADED_COMMANDS CMAKE_FLAGS -DMUDSLIDE_TYPE:STRING=MUCHO
+ OUTPUT_VARIABLE OUTPUT )
+# do another TRY_COMPILE to get around make
+# problem on hp
+ TRY_COMPILE(COMPILE_OK
+ ${LoadCommand_BINARY_DIR}/CMakeCommands
+ ${LoadCommand_SOURCE_DIR}/CMakeCommands
+ CMAKE_LOADED_COMMANDS CMAKE_FLAGS -DMUDSLIDE_TYPE:STRING=MUCHO
+ OUTPUT_VARIABLE OUTPUT )
+ENDIF(COMMAND CMAKE_TEST_COMMAND)
+
+MESSAGE("Output from try compile: ${OUTPUT}")
+
+# if the compile was OK, try loading the command
+IF (COMPILE_OK)
+ LOAD_COMMAND(CMAKE_TEST_COMMAND
+ ${LoadCommand_BINARY_DIR}/CMakeCommands
+ ${LoadCommand_BINARY_DIR}/CMakeCommands/Debug
+ ${LoadCommand_BINARY_DIR}/CMakeCommands/Development
+ )
+ # if the command loaded, execute the command
+ IF (COMMAND CMAKE_TEST_COMMAND)
+ CMAKE_TEST_COMMAND(
+ "${LoadCommand_SOURCE_DIR}/LoadedCommand.cxx.in"
+ "${LoadCommand_BINARY_DIR}/LoadedCommand2.cxx.in"
+ "${LoadCommand_BINARY_DIR}/LoadedCommand3.cxx"
+ )
+ ENDIF (COMMAND CMAKE_TEST_COMMAND)
+ELSE (COMPILE_OK)
+ MESSAGE("failed to compile CMAKE_LOADED_COMMANDS")
+ENDIF (COMPILE_OK)
+
+# TEST_DEF is set by the loaded command cmTestCommand.c
+IF (TEST_DEF AND SOME_CACHE_VARIABLE AND TEST_EXEC)
+ ADD_DEFINITIONS(-DCMAKE_IS_FUN)
+ENDIF (TEST_DEF AND SOME_CACHE_VARIABLE AND TEST_EXEC)
+
diff --git a/Tests/LoadCommandOneConfig/LoadedCommand.cxx.in b/Tests/LoadCommandOneConfig/LoadedCommand.cxx.in
new file mode 100644
index 000000000..c58bcf153
--- /dev/null
+++ b/Tests/LoadCommandOneConfig/LoadedCommand.cxx.in
@@ -0,0 +1,41 @@
+#include "LoadedCommand.h"
+#include <stdio.h>
+
+int testSizeOf(int s1, int s2)
+{
+ return s1 - 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");
+ ret= 1;
+#endif
+#if !defined(CMAKE_IS_FUN)
+ printf("Loaded Command was not built with CMAKE_IS_FUN: failed.\n");
+ ret = 1;
+#endif
+ if(testSizeOf(SIZEOF_CHAR, sizeof(char)))
+ {
+ printf("Size of char is broken.\n");
+ ret = 1;
+ }
+ if(testSizeOf(SIZEOF_SHORT, sizeof(short)))
+ {
+ printf("Size of short is broken.\n");
+ ret = 1;
+ }
+ return ret;
+}
diff --git a/Tests/LoadCommandOneConfig/LoadedCommand.h.in b/Tests/LoadCommandOneConfig/LoadedCommand.h.in
new file mode 100644
index 000000000..7a0a15d4d
--- /dev/null
+++ b/Tests/LoadCommandOneConfig/LoadedCommand.h.in
@@ -0,0 +1,13 @@
+/* Check for size of types */
+#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
+
+/* Check for libraries */
+#cmakedefine HAVE_LIBM
diff --git a/Tests/MFC/CMakeLists.txt b/Tests/MFC/CMakeLists.txt
new file mode 100644
index 000000000..62ff749fe
--- /dev/null
+++ b/Tests/MFC/CMakeLists.txt
@@ -0,0 +1,61 @@
+cmake_minimum_required(VERSION 2.8)
+project(mfc_driver)
+
+include(CTest)
+include(ExternalProject)
+
+
+set(CMAKE_MFC_FLAG_VALUE "2")
+configure_file(
+ ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt.in
+ ${CMAKE_CURRENT_BINARY_DIR}/CMakeLists.SharedMfcDll.txt
+ @ONLY
+ )
+
+ExternalProject_Add(mfcShared
+ URL ${CMAKE_CURRENT_SOURCE_DIR}/mfc1
+ PATCH_COMMAND ${CMAKE_COMMAND} -E copy
+ ${CMAKE_CURRENT_BINARY_DIR}/CMakeLists.SharedMfcDll.txt
+ <SOURCE_DIR>/CMakeLists.txt
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
+ )
+
+
+set(CMAKE_MFC_FLAG_VALUE "1")
+configure_file(
+ ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt.in
+ ${CMAKE_CURRENT_BINARY_DIR}/CMakeLists.StaticMfcLib.txt
+ @ONLY
+ )
+
+ExternalProject_Add(mfcStatic
+ URL ${CMAKE_CURRENT_SOURCE_DIR}/mfc1
+ PATCH_COMMAND ${CMAKE_COMMAND} -E copy
+ ${CMAKE_CURRENT_BINARY_DIR}/CMakeLists.StaticMfcLib.txt
+ <SOURCE_DIR>/CMakeLists.txt
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
+ )
+
+
+set(binary_dir "${CMAKE_CURRENT_BINARY_DIR}")
+configure_file(
+ ${CMAKE_CURRENT_SOURCE_DIR}/ValidateBuild.cmake.in
+ ${CMAKE_CURRENT_BINARY_DIR}/ValidateBuild.cmake
+ @ONLY
+ )
+add_test(
+ NAME validate
+ COMMAND ${CMAKE_COMMAND}
+ -P "${CMAKE_CURRENT_BINARY_DIR}/ValidateBuild.cmake"
+ )
+
+
+add_test(
+ NAME environment
+ COMMAND ${CMAKE_COMMAND} -E environment
+ )
+
+
+message(STATUS "===== environment =====")
+execute_process(COMMAND ${CMAKE_COMMAND} -E environment)
+message(STATUS "===== /environment =====")
diff --git a/Tests/MFC/CMakeLists.txt.in b/Tests/MFC/CMakeLists.txt.in
new file mode 100644
index 000000000..e6bfabd33
--- /dev/null
+++ b/Tests/MFC/CMakeLists.txt.in
@@ -0,0 +1,62 @@
+cmake_minimum_required(VERSION 2.8)
+project(mfc1)
+
+macro(replace_flags var these those)
+ if("${${var}}" MATCHES "${these}")
+ string(REGEX REPLACE "${these}" "${those}" ${var} "${${var}}")
+ #message(STATUS "info: ${var} changed to '${${var}}'")
+ endif()
+ message(STATUS "info: ${var}='${${var}}'")
+endmacro()
+
+macro(msvc_link_to_static_crt)
+ if(MSVC)
+ set(has_correct_flag 0)
+ foreach(lang C CXX)
+ foreach(suffix "" _DEBUG _MINSIZEREL _RELEASE _RELWITHDEBINFO)
+ replace_flags("CMAKE_${lang}_FLAGS${suffix}" "/MD" "/MT")
+ if(CMAKE_${lang}_FLAGS${suffix} MATCHES "/MT")
+ set(has_correct_flag 1)
+ endif()
+ endforeach()
+ endforeach()
+ if(NOT has_correct_flag)
+ message(FATAL_ERROR "no CMAKE_*_FLAGS var contains /MT")
+ endif()
+ endif()
+endmacro()
+
+set(files
+ ChildFrm.cpp
+ ChildFrm.h
+ MainFrm.cpp
+ MainFrm.h
+ mfc1.cpp
+ mfc1.h
+ mfc1.rc
+ mfc1Doc.cpp
+ mfc1Doc.h
+ mfc1View.cpp
+ mfc1View.h
+ Resource.h
+ stdafx.cpp
+ stdafx.h
+)
+
+set(CMAKE_MFC_FLAG "@CMAKE_MFC_FLAG_VALUE@")
+
+if("${CMAKE_MFC_FLAG}" STREQUAL "1")
+ msvc_link_to_static_crt()
+else()
+ # VS generators add this automatically based on the CMAKE_MFC_FLAG value,
+ # but generators matching "Make" require:
+ add_definitions(-D_AFXDLL)
+endif()
+
+add_executable(mfc1 WIN32 ${files})
+install(TARGETS mfc1 DESTINATION bin)
+
+if("${CMAKE_MFC_FLAG}" STREQUAL "2")
+ set(CMAKE_INSTALL_MFC_LIBRARIES ON)
+ include(InstallRequiredSystemLibraries)
+endif()
diff --git a/Tests/MFC/ValidateBuild.cmake.in b/Tests/MFC/ValidateBuild.cmake.in
new file mode 100644
index 000000000..ed923f5e7
--- /dev/null
+++ b/Tests/MFC/ValidateBuild.cmake.in
@@ -0,0 +1,68 @@
+#
+# This code validates that the install trees of the shared and static builds
+# of "mfc1" have the expected contents:
+#
+set(binary_dir "@binary_dir@")
+message("binary_dir='${binary_dir}'")
+
+# There should be exactly one file in the static install tree "bin" directory
+# and it should be named "mfc1.exe"
+#
+message(STATUS "===== mfcStatic install tree =====")
+file(GLOB_RECURSE files "${binary_dir}/mfcStatic-prefix/bin/*.*")
+message(STATUS "mfcStatic files='${files}'")
+list(LENGTH files len)
+if(NOT len EQUAL 1)
+ message(FATAL_ERROR
+ "len='${len}' is not '1' (count of static 'bin' files)")
+endif()
+get_filename_component(name "${files}" NAME)
+string(TOLOWER "${name}" name)
+if(NOT "${name}" STREQUAL "mfc1.exe")
+ message(FATAL_ERROR "unexpected mfcStatic file name '${name}'")
+endif()
+
+# There should be at least 3 files in the shared install tree "bin"
+# directory: mfc1.exe, the main MFC dll and the C runtime dll. With more
+# recent versions of VS, there will also be an MFC language dll and a
+# manifest file.
+#
+message(STATUS "===== mfcShared install tree =====")
+file(GLOB_RECURSE files "${binary_dir}/mfcShared-prefix/bin/*.*")
+message(STATUS "mfcShared files='${files}'")
+list(LENGTH files len)
+
+set(msvc6 "@MSVC60@")
+if("${msvc6}" STREQUAL "1")
+ set(expected_minimum_file_count 1)
+else()
+ set(expected_minimum_file_count 3)
+endif()
+
+if(len LESS ${expected_minimum_file_count})
+ message(FATAL_ERROR
+ "len='${len}' is less than '${expected_minimum_file_count}' (count of shared 'bin' files)")
+endif()
+foreach(f ${files})
+ message(STATUS "file '${f}'")
+ get_filename_component(ext "${f}" EXT)
+ string(TOLOWER "${ext}" ext)
+
+ if("${ext}" MATCHES "\\.exe$")
+ message(STATUS " exe file")
+ get_filename_component(name "${f}" NAME)
+ string(TOLOWER "${name}" name)
+ if(NOT "${name}" STREQUAL "mfc1.exe")
+ message(FATAL_ERROR "unexpected mfcShared .exe file name '${name}'")
+ endif()
+ elseif("${ext}" MATCHES "\\.dll$")
+ message(STATUS " dll file")
+ elseif("${ext}" MATCHES "\\.manifest$")
+ message(STATUS " manifest file")
+ else()
+ message(STATUS " unknown file")
+ message(FATAL_ERROR "unexpected mfcShared ${ext} file name '${f}'")
+ endif()
+endforeach()
+
+message(STATUS "All mfc1 build validation tests pass.")
diff --git a/Tests/MFC/mfc1/.gitattributes b/Tests/MFC/mfc1/.gitattributes
new file mode 100644
index 000000000..59be5dcfb
--- /dev/null
+++ b/Tests/MFC/mfc1/.gitattributes
@@ -0,0 +1,6 @@
+.gitattributes export-ignore
+
+*.sln -crlf
+*.vcproj -crlf
+
+* -whitespace
diff --git a/Tests/MFC/mfc1/ChildFrm.cpp b/Tests/MFC/mfc1/ChildFrm.cpp
new file mode 100644
index 000000000..b04c4f231
--- /dev/null
+++ b/Tests/MFC/mfc1/ChildFrm.cpp
@@ -0,0 +1,59 @@
+// ChildFrm.cpp : implementation of the CChildFrame class
+//
+#include "stdafx.h"
+#include "mfc1.h"
+
+#include "ChildFrm.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// CChildFrame
+
+IMPLEMENT_DYNCREATE(CChildFrame, CMDIChildWnd)
+
+BEGIN_MESSAGE_MAP(CChildFrame, CMDIChildWnd)
+END_MESSAGE_MAP()
+
+
+// CChildFrame construction/destruction
+
+CChildFrame::CChildFrame()
+{
+ // TODO: add member initialization code here
+}
+
+CChildFrame::~CChildFrame()
+{
+}
+
+
+BOOL CChildFrame::PreCreateWindow(CREATESTRUCT& cs)
+{
+ // TODO: Modify the Window class or styles here by modifying the CREATESTRUCT cs
+ if( !CMDIChildWnd::PreCreateWindow(cs) )
+ return FALSE;
+
+ return TRUE;
+}
+
+
+// CChildFrame diagnostics
+
+#ifdef _DEBUG
+void CChildFrame::AssertValid() const
+{
+ CMDIChildWnd::AssertValid();
+}
+
+void CChildFrame::Dump(CDumpContext& dc) const
+{
+ CMDIChildWnd::Dump(dc);
+}
+
+#endif //_DEBUG
+
+
+// CChildFrame message handlers
diff --git a/Tests/MFC/mfc1/ChildFrm.h b/Tests/MFC/mfc1/ChildFrm.h
new file mode 100644
index 000000000..34b80f126
--- /dev/null
+++ b/Tests/MFC/mfc1/ChildFrm.h
@@ -0,0 +1,34 @@
+// ChildFrm.h : interface of the CChildFrame class
+//
+
+
+#pragma once
+
+
+class CChildFrame : public CMDIChildWnd
+{
+ DECLARE_DYNCREATE(CChildFrame)
+public:
+ CChildFrame();
+
+// Attributes
+public:
+
+// Operations
+public:
+
+// Overrides
+ virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
+
+// Implementation
+public:
+ virtual ~CChildFrame();
+#ifdef _DEBUG
+ virtual void AssertValid() const;
+ virtual void Dump(CDumpContext& dc) const;
+#endif
+
+// Generated message map functions
+protected:
+ DECLARE_MESSAGE_MAP()
+};
diff --git a/Tests/MFC/mfc1/MainFrm.cpp b/Tests/MFC/mfc1/MainFrm.cpp
new file mode 100644
index 000000000..44554bf4c
--- /dev/null
+++ b/Tests/MFC/mfc1/MainFrm.cpp
@@ -0,0 +1,98 @@
+// MainFrm.cpp : implementation of the CMainFrame class
+//
+
+#include "stdafx.h"
+#include "mfc1.h"
+
+#include "MainFrm.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// CMainFrame
+
+IMPLEMENT_DYNAMIC(CMainFrame, CMDIFrameWnd)
+
+BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
+ ON_WM_CREATE()
+END_MESSAGE_MAP()
+
+static UINT indicators[] =
+{
+ ID_SEPARATOR, // status line indicator
+ ID_INDICATOR_CAPS,
+ ID_INDICATOR_NUM,
+ ID_INDICATOR_SCRL,
+};
+
+
+// CMainFrame construction/destruction
+
+CMainFrame::CMainFrame()
+{
+ // TODO: add member initialization code here
+}
+
+CMainFrame::~CMainFrame()
+{
+}
+
+
+int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
+{
+ if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
+ return -1;
+
+ if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
+ | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
+ !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
+ {
+ TRACE0("Failed to create toolbar\n");
+ return -1; // fail to create
+ }
+
+ if (!m_wndStatusBar.Create(this) ||
+ !m_wndStatusBar.SetIndicators(indicators,
+ sizeof(indicators)/sizeof(UINT)))
+ {
+ TRACE0("Failed to create status bar\n");
+ return -1; // fail to create
+ }
+ // TODO: Delete these three lines if you don't want the toolbar to be dockable
+ m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
+ EnableDocking(CBRS_ALIGN_ANY);
+ DockControlBar(&m_wndToolBar);
+
+ return 0;
+}
+
+BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
+{
+ if( !CMDIFrameWnd::PreCreateWindow(cs) )
+ return FALSE;
+ // TODO: Modify the Window class or styles here by modifying
+ // the CREATESTRUCT cs
+
+ return TRUE;
+}
+
+
+// CMainFrame diagnostics
+
+#ifdef _DEBUG
+void CMainFrame::AssertValid() const
+{
+ CMDIFrameWnd::AssertValid();
+}
+
+void CMainFrame::Dump(CDumpContext& dc) const
+{
+ CMDIFrameWnd::Dump(dc);
+}
+
+#endif //_DEBUG
+
+
+// CMainFrame message handlers
diff --git a/Tests/MFC/mfc1/MainFrm.h b/Tests/MFC/mfc1/MainFrm.h
new file mode 100644
index 000000000..1039ac5ee
--- /dev/null
+++ b/Tests/MFC/mfc1/MainFrm.h
@@ -0,0 +1,38 @@
+// MainFrm.h : interface of the CMainFrame class
+//
+
+
+#pragma once
+class CMainFrame : public CMDIFrameWnd
+{
+ DECLARE_DYNAMIC(CMainFrame)
+public:
+ CMainFrame();
+
+// Attributes
+public:
+
+// Operations
+public:
+
+// Overrides
+public:
+ virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
+
+// Implementation
+public:
+ virtual ~CMainFrame();
+#ifdef _DEBUG
+ virtual void AssertValid() const;
+ virtual void Dump(CDumpContext& dc) const;
+#endif
+
+protected: // control bar embedded members
+ CStatusBar m_wndStatusBar;
+ CToolBar m_wndToolBar;
+
+// Generated message map functions
+protected:
+ afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
+ DECLARE_MESSAGE_MAP()
+};
diff --git a/Tests/MFC/mfc1/ReadMe.txt b/Tests/MFC/mfc1/ReadMe.txt
new file mode 100644
index 000000000..d84608e71
--- /dev/null
+++ b/Tests/MFC/mfc1/ReadMe.txt
@@ -0,0 +1,135 @@
+================================================================================
+ MICROSOFT FOUNDATION CLASS LIBRARY : mfc1 Project Overview
+===============================================================================
+
+The application wizard has created this mfc1 application for
+you. This application not only demonstrates the basics of using the Microsoft
+Foundation Classes but is also a starting point for writing your application.
+
+This file contains a summary of what you will find in each of the files that
+make up your mfc1 application.
+
+mfc1.vcproj
+ This is the main project file for VC++ projects generated using an application wizard.
+ It contains information about the version of Visual C++ that generated the file, and
+ information about the platforms, configurations, and project features selected with the
+ application wizard.
+
+mfc1.h
+ This is the main header file for the application. It includes other
+ project specific headers (including Resource.h) and declares the
+ Cmfc1App application class.
+
+mfc1.cpp
+ This is the main application source file that contains the application
+ class Cmfc1App.
+
+mfc1.rc
+ This is a listing of all of the Microsoft Windows resources that the
+ program uses. It includes the icons, bitmaps, and cursors that are stored
+ in the RES subdirectory. This file can be directly edited in Microsoft
+ Visual C++. Your project resources are in 1033.
+
+res\mfc1.ico
+ This is an icon file, which is used as the application's icon. This
+ icon is included by the main resource file mfc1.rc.
+
+res\mfc1.rc2
+ This file contains resources that are not edited by Microsoft
+ Visual C++. You should place all resources not editable by
+ the resource editor in this file.
+mfc1.reg
+ This is an example .reg file that shows you the kind of registration
+ settings the framework will set for you. You can use this as a .reg
+ file to go along with your application or just delete it and rely
+ on the default RegisterShellFileTypes registration.
+/////////////////////////////////////////////////////////////////////////////
+
+For the main frame window:
+ The project includes a standard MFC interface.
+MainFrm.h, MainFrm.cpp
+ These files contain the frame class CMainFrame, which is derived from
+ CMDIFrameWnd and controls all MDI frame features.
+res\Toolbar.bmp
+ This bitmap file is used to create tiled images for the toolbar.
+ The initial toolbar and status bar are constructed in the CMainFrame
+ class. Edit this toolbar bitmap using the resource editor, and
+ update the IDR_MAINFRAME TOOLBAR array in mfc1.rc to add
+ toolbar buttons.
+/////////////////////////////////////////////////////////////////////////////
+
+For the child frame window:
+
+ChildFrm.h, ChildFrm.cpp
+ These files define and implement the CChildFrame class, which
+ supports the child windows in an MDI application.
+
+/////////////////////////////////////////////////////////////////////////////
+
+The application wizard creates one document type and one view:
+
+mfc1Doc.h, mfc1Doc.cpp - the document
+ These files contain your Cmfc1Doc class. Edit these files to
+ add your special document data and to implement file saving and loading
+ (via Cmfc1Doc::Serialize).
+ The Document will have the following strings:
+ File extension: mf1
+ File type ID: mfc1.Document
+ Main frame caption: mfc1
+ Doc type name: mfc1
+ Filter name: mfc1 Files (*.mf1)
+ File new short name: mfc1
+ File type long name: mfc1.Document
+mfc1View.h, mfc1View.cpp - the view of the document
+ These files contain your Cmfc1View class.
+ Cmfc1View objects are used to view Cmfc1Doc objects.
+res\mfc1Doc.ico
+ This is an icon file, which is used as the icon for MDI child windows
+ for the Cmfc1Doc class. This icon is included by the main
+ resource file mfc1.rc.
+/////////////////////////////////////////////////////////////////////////////
+
+Other Features:
+
+ActiveX Controls
+ The application includes support to use ActiveX controls.
+
+Printing and Print Preview support
+ The application wizard has generated code to handle the print, print setup, and print preview
+ commands by calling member functions in the CView class from the MFC library.
+/////////////////////////////////////////////////////////////////////////////
+
+Other standard files:
+
+StdAfx.h, StdAfx.cpp
+ These files are used to build a precompiled header (PCH) file
+ named mfc1.pch and a precompiled types file named StdAfx.obj.
+
+Resource.h
+ This is the standard header file, which defines new resource IDs.
+ Microsoft Visual C++ reads and updates this file.
+
+mfc1.manifest
+ Application manifest files are used by Windows XP to describe an applications
+ dependency on specific versions of Side-by-Side assemblies. The loader uses this
+ information to load the appropriate assembly from the assembly cache or private
+ from the application. The Application manifest maybe included for redistribution
+ as an external .manifest file that is installed in the same folder as the application
+ executable or it may be included in the executable in the form of a resource.
+/////////////////////////////////////////////////////////////////////////////
+
+Other notes:
+
+The application wizard uses "TODO:" to indicate parts of the source code you
+should add to or customize.
+
+If your application uses MFC in a shared DLL, and your application is in a
+language other than the operating system's current language, you will need
+to copy the corresponding localized resources MFC70XXX.DLL from the Microsoft
+Visual C++ CD-ROM under the Win\System directory to your computer's system or
+system32 directory, and rename it to be MFCLOC.DLL. ("XXX" stands for the
+language abbreviation. For example, MFC70DEU.DLL contains resources
+translated to German.) If you don't do this, some of the UI elements of
+your application will remain in the language of the operating system.
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/Tests/MFC/mfc1/Resource.h b/Tests/MFC/mfc1/Resource.h
new file mode 100644
index 000000000..0a9c13f57
--- /dev/null
+++ b/Tests/MFC/mfc1/Resource.h
@@ -0,0 +1,20 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by mfc1.rc
+//
+#define IDD_ABOUTBOX 100
+#define IDP_OLE_INIT_FAILED 100
+#define IDR_MAINFRAME 128
+#define IDR_mfc1TYPE 129
+#define IDR_MANIFEST CREATEPROCESS_MANIFEST_RESOURCE_ID
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 130
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 32771
+#endif
+#endif
diff --git a/Tests/MFC/mfc1/mfc1.cpp b/Tests/MFC/mfc1/mfc1.cpp
new file mode 100644
index 000000000..9530cd2b9
--- /dev/null
+++ b/Tests/MFC/mfc1/mfc1.cpp
@@ -0,0 +1,144 @@
+// mfc1.cpp : Defines the class behaviors for the application.
+//
+
+#include "stdafx.h"
+#include "mfc1.h"
+#include "MainFrm.h"
+
+#include "ChildFrm.h"
+#include "mfc1Doc.h"
+#include "mfc1View.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// Cmfc1App
+
+BEGIN_MESSAGE_MAP(Cmfc1App, CWinApp)
+ ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
+ // Standard file based document commands
+ ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
+ ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
+ // Standard print setup command
+ ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)
+END_MESSAGE_MAP()
+
+
+// Cmfc1App construction
+
+Cmfc1App::Cmfc1App()
+{
+ // TODO: add construction code here,
+ // Place all significant initialization in InitInstance
+}
+
+
+// The one and only Cmfc1App object
+
+Cmfc1App theApp;
+
+// Cmfc1App initialization
+
+BOOL Cmfc1App::InitInstance()
+{
+ // InitCommonControls() is required on Windows XP if an application
+ // manifest specifies use of ComCtl32.dll version 6 or later to enable
+ // visual styles. Otherwise, any window creation will fail.
+ InitCommonControls();
+
+ CWinApp::InitInstance();
+
+ // Initialize OLE libraries
+ if (!AfxOleInit())
+ {
+ AfxMessageBox(IDP_OLE_INIT_FAILED);
+ return FALSE;
+ }
+ AfxEnableControlContainer();
+ // Standard initialization
+ // If you are not using these features and wish to reduce the size
+ // of your final executable, you should remove from the following
+ // the specific initialization routines you do not need
+ // Change the registry key under which our settings are stored
+ // TODO: You should modify this string to be something appropriate
+ // such as the name of your company or organization
+ SetRegistryKey(_T("Local AppWizard-Generated Applications"));
+ LoadStdProfileSettings(4); // Load standard INI file options (including MRU)
+ // Register the application's document templates. Document templates
+ // serve as the connection between documents, frame windows and views
+ CMultiDocTemplate* pDocTemplate;
+ pDocTemplate = new CMultiDocTemplate(IDR_mfc1TYPE,
+ RUNTIME_CLASS(Cmfc1Doc),
+ RUNTIME_CLASS(CChildFrame), // custom MDI child frame
+ RUNTIME_CLASS(Cmfc1View));
+ if (!pDocTemplate)
+ return FALSE;
+ AddDocTemplate(pDocTemplate);
+ // create main MDI Frame window
+ CMainFrame* pMainFrame = new CMainFrame;
+ if (!pMainFrame || !pMainFrame->LoadFrame(IDR_MAINFRAME))
+ return FALSE;
+ m_pMainWnd = pMainFrame;
+ // call DragAcceptFiles only if there's a suffix
+ // In an MDI app, this should occur immediately after setting m_pMainWnd
+ // Enable drag/drop open
+ m_pMainWnd->DragAcceptFiles();
+ // Enable DDE Execute open
+ EnableShellOpen();
+ RegisterShellFileTypes(TRUE);
+ // Parse command line for standard shell commands, DDE, file open
+ CCommandLineInfo cmdInfo;
+ ParseCommandLine(cmdInfo);
+ // Dispatch commands specified on the command line. Will return FALSE if
+ // app was launched with /RegServer, /Register, /Unregserver or /Unregister.
+ if (!ProcessShellCommand(cmdInfo))
+ return FALSE;
+ // The main window has been initialized, so show and update it
+ pMainFrame->ShowWindow(m_nCmdShow);
+ pMainFrame->UpdateWindow();
+ return TRUE;
+}
+
+
+
+// CAboutDlg dialog used for App About
+
+class CAboutDlg : public CDialog
+{
+public:
+ CAboutDlg();
+
+// Dialog Data
+ enum { IDD = IDD_ABOUTBOX };
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+
+// Implementation
+protected:
+ DECLARE_MESSAGE_MAP()
+};
+
+CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
+{
+}
+
+void CAboutDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+}
+
+BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
+END_MESSAGE_MAP()
+
+// App command to run the dialog
+void Cmfc1App::OnAppAbout()
+{
+ CAboutDlg aboutDlg;
+ aboutDlg.DoModal();
+}
+
+
+// Cmfc1App message handlers
diff --git a/Tests/MFC/mfc1/mfc1.h b/Tests/MFC/mfc1/mfc1.h
new file mode 100644
index 000000000..c273601f8
--- /dev/null
+++ b/Tests/MFC/mfc1/mfc1.h
@@ -0,0 +1,31 @@
+// mfc1.h : main header file for the mfc1 application
+//
+#pragma once
+
+#ifndef __AFXWIN_H__
+ #error include 'stdafx.h' before including this file for PCH
+#endif
+
+#include "resource.h" // main symbols
+
+
+// Cmfc1App:
+// See mfc1.cpp for the implementation of this class
+//
+
+class Cmfc1App : public CWinApp
+{
+public:
+ Cmfc1App();
+
+
+// Overrides
+public:
+ virtual BOOL InitInstance();
+
+// Implementation
+ afx_msg void OnAppAbout();
+ DECLARE_MESSAGE_MAP()
+};
+
+extern Cmfc1App theApp;
diff --git a/Tests/MFC/mfc1/mfc1.rc b/Tests/MFC/mfc1/mfc1.rc
new file mode 100644
index 000000000..346c5fb77
--- /dev/null
+++ b/Tests/MFC/mfc1/mfc1.rc
@@ -0,0 +1,393 @@
+//Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+#ifdef APSTUDIO_INVOKED
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "#define _AFX_NO_SPLITTER_RESOURCES\r\n"
+ "#define _AFX_NO_OLE_RESOURCES\r\n"
+ "#define _AFX_NO_TRACKER_RESOURCES\r\n"
+ "#define _AFX_NO_PROPERTY_RESOURCES\r\n"
+ "\r\n"
+ "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
+ "LANGUAGE 9, 1\r\n"
+ "#pragma code_page(1252)\r\n"
+ "#include ""res\\mfc1.rc2"" // non-Microsoft Visual C++ edited resources\r\n"
+ "#include ""afxres.rc"" // Standard components\r\n"
+ "#include ""afxprint.rc"" // printing/print preview resources\r\n"
+ "#endif\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+LANGUAGE 9, 1
+#pragma code_page(1252)
+IDR_MAINFRAME ICON "res\\mfc1.ico"
+IDR_mfc1TYPE ICON "res\\mfc1Doc.ico"
+#endif
+/////////////////////////////////////////////////////////////////////////////
+//
+// Bitmap
+//
+
+IDR_MAINFRAME BITMAP "res\\Toolbar.bmp"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Toolbar
+//
+
+IDR_MAINFRAME TOOLBAR 16, 15
+BEGIN
+ BUTTON ID_FILE_NEW
+ BUTTON ID_FILE_OPEN
+ BUTTON ID_FILE_SAVE
+ SEPARATOR
+ BUTTON ID_EDIT_CUT
+ BUTTON ID_EDIT_COPY
+ BUTTON ID_EDIT_PASTE
+ SEPARATOR
+ BUTTON ID_FILE_PRINT
+ BUTTON ID_APP_ABOUT
+END
+
+
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+LANGUAGE 9, 1
+#pragma code_page(1252)
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDR_MAINFRAME MENU
+BEGIN
+ POPUP "&File"
+ BEGIN
+ MENUITEM "&New\tCtrl+N", ID_FILE_NEW
+ MENUITEM "&Open...\tCtrl+O", ID_FILE_OPEN
+ MENUITEM SEPARATOR
+ MENUITEM "P&rint Setup...", ID_FILE_PRINT_SETUP
+ MENUITEM SEPARATOR
+ MENUITEM "Recent File", ID_FILE_MRU_FILE1,GRAYED
+ MENUITEM SEPARATOR
+ MENUITEM "&Close", ID_FILE_CLOSE
+ MENUITEM "E&xit", ID_APP_EXIT
+ END
+ POPUP "&View"
+ BEGIN
+ MENUITEM "&Toolbar", ID_VIEW_TOOLBAR
+ MENUITEM "&Status Bar", ID_VIEW_STATUS_BAR
+ END
+ POPUP "&Help"
+ BEGIN
+ MENUITEM "&About mfc1...", ID_APP_ABOUT
+ END
+END
+IDR_mfc1TYPE MENU
+BEGIN
+ POPUP "&File"
+ BEGIN
+ MENUITEM "&New\tCtrl+N", ID_FILE_NEW
+ MENUITEM "&Open...\tCtrl+O", ID_FILE_OPEN
+ MENUITEM "&Close", ID_FILE_CLOSE
+ MENUITEM "&Save\tCtrl+S", ID_FILE_SAVE
+ MENUITEM "Save &As...", ID_FILE_SAVE_AS
+ MENUITEM SEPARATOR
+ MENUITEM "&Print...\tCtrl+P", ID_FILE_PRINT
+ MENUITEM "Print Pre&view", ID_FILE_PRINT_PREVIEW
+ MENUITEM "P&rint Setup...", ID_FILE_PRINT_SETUP
+ MENUITEM SEPARATOR
+ MENUITEM "Recent File", ID_FILE_MRU_FILE1,GRAYED
+ MENUITEM SEPARATOR
+ MENUITEM "E&xit", ID_APP_EXIT
+ END
+ POPUP "&Edit"
+ BEGIN
+ MENUITEM "&Undo\tCtrl+Z", ID_EDIT_UNDO
+ MENUITEM SEPARATOR
+ MENUITEM "Cu&t\tCtrl+X", ID_EDIT_CUT
+ MENUITEM "&Copy\tCtrl+C", ID_EDIT_COPY
+ MENUITEM "&Paste\tCtrl+V", ID_EDIT_PASTE
+ END
+ POPUP "&View"
+ BEGIN
+ MENUITEM "&Toolbar", ID_VIEW_TOOLBAR
+ MENUITEM "&Status Bar", ID_VIEW_STATUS_BAR
+ END
+ POPUP "&Window"
+ BEGIN
+ MENUITEM "&New Window", ID_WINDOW_NEW
+ MENUITEM "&Cascade", ID_WINDOW_CASCADE
+ MENUITEM "&Tile", ID_WINDOW_TILE_HORZ
+ MENUITEM "&Arrange Icons", ID_WINDOW_ARRANGE
+ END
+ POPUP "&Help"
+ BEGIN
+ MENUITEM "&About mfc1...", ID_APP_ABOUT
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Accelerator
+//
+
+IDR_MAINFRAME ACCELERATORS
+BEGIN
+ "N", ID_FILE_NEW, VIRTKEY,CONTROL
+ "O", ID_FILE_OPEN, VIRTKEY,CONTROL
+ "S", ID_FILE_SAVE, VIRTKEY,CONTROL
+ "P", ID_FILE_PRINT, VIRTKEY,CONTROL
+ "Z", ID_EDIT_UNDO, VIRTKEY,CONTROL
+ "X", ID_EDIT_CUT, VIRTKEY,CONTROL
+ "C", ID_EDIT_COPY, VIRTKEY,CONTROL
+ "V", ID_EDIT_PASTE, VIRTKEY,CONTROL
+ VK_BACK, ID_EDIT_UNDO, VIRTKEY,ALT
+ VK_DELETE, ID_EDIT_CUT, VIRTKEY,SHIFT
+ VK_INSERT, ID_EDIT_COPY, VIRTKEY,CONTROL
+ VK_INSERT, ID_EDIT_PASTE, VIRTKEY,SHIFT
+ VK_F6, ID_NEXT_PANE, VIRTKEY
+ VK_F6, ID_PREV_PANE, VIRTKEY,SHIFT
+END
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+#if _MSC_VER < 1300
+#define DS_SHELLFONT_FLAG 0
+#else
+#define DS_SHELLFONT_FLAG DS_SHELLFONT
+#endif
+
+IDD_ABOUTBOX DIALOGEX 0, 0, 235, 55
+CAPTION "About mfc1"
+STYLE DS_MODALFRAME | DS_SHELLFONT_FLAG | WS_POPUP | WS_CAPTION | WS_SYSMENU
+FONT 8, "MS Shell Dlg"
+BEGIN
+ ICON IDR_MAINFRAME,IDC_STATIC,11,17,20,20
+ LTEXT "mfc1 Version 1.0",IDC_STATIC,40,10,119,8,
+ SS_NOPREFIX
+ LTEXT "Copyright (C) 2011",IDC_STATIC,40,25,119,8
+ DEFPUSHBUTTON "OK",IDOK,178,7,50,16,WS_GROUP
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,1
+ PRODUCTVERSION 1,0,0,1
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904e4"
+ BEGIN
+ VALUE "CompanyName", "TODO: <Company name>"
+ VALUE "FileDescription", "TODO: <File description>"
+ VALUE "FileVersion", "1.0.0.1"
+ VALUE "InternalName", "mfc1.exe"
+ VALUE "LegalCopyright", "TODO: (c) <Company name>. All rights reserved."
+ VALUE "OriginalFilename","mfc1.exe"
+ VALUE "ProductName", "TODO: <Product name>"
+ VALUE "ProductVersion", "1.0.0.1"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0409, 1252
+ END
+END
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_ABOUTBOX, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 228
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 48
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE
+BEGIN
+// Non-mac-targeting apps remove the two extra substrings
+ IDR_MAINFRAME "mfc1"
+ // has a file suffix - shell file type too
+ IDR_mfc1TYPE "\nmfc1\nmfc1\nmfc1 Files (*.mf1)\n.mf1\nmfc1.Document\nmfc1.Document"
+END
+STRINGTABLE
+BEGIN
+ AFX_IDS_APP_TITLE "mfc1"
+ AFX_IDS_IDLEMESSAGE "Ready"
+END
+STRINGTABLE
+BEGIN
+ ID_INDICATOR_EXT "EXT"
+ ID_INDICATOR_CAPS "CAP"
+ ID_INDICATOR_NUM "NUM"
+ ID_INDICATOR_SCRL "SCRL"
+ ID_INDICATOR_OVR "OVR"
+ ID_INDICATOR_REC "REC"
+END
+STRINGTABLE
+BEGIN
+ ID_FILE_NEW "Create a new document\nNew"
+ ID_FILE_OPEN "Open an existing document\nOpen"
+ ID_FILE_CLOSE "Close the active document\nClose"
+ ID_FILE_SAVE "Save the active document\nSave"
+ ID_FILE_SAVE_AS "Save the active document with a new name\nSave As"
+ ID_FILE_PAGE_SETUP "Change the printing options\nPage Setup"
+ ID_FILE_PRINT_SETUP "Change the printer and printing options\nPrint Setup"
+ ID_FILE_PRINT "Print the active document\nPrint"
+ ID_FILE_PRINT_PREVIEW "Display full pages\nPrint Preview"
+ ID_APP_ABOUT "Display program information, version number and copyright\nAbout"
+ ID_APP_EXIT "Quit the application; prompts to save documents\nExit"
+ ID_FILE_MRU_FILE1 "Open this document"
+ ID_FILE_MRU_FILE2 "Open this document"
+ ID_FILE_MRU_FILE3 "Open this document"
+ ID_FILE_MRU_FILE4 "Open this document"
+ ID_FILE_MRU_FILE5 "Open this document"
+ ID_FILE_MRU_FILE6 "Open this document"
+ ID_FILE_MRU_FILE7 "Open this document"
+ ID_FILE_MRU_FILE8 "Open this document"
+ ID_FILE_MRU_FILE9 "Open this document"
+ ID_FILE_MRU_FILE10 "Open this document"
+ ID_FILE_MRU_FILE11 "Open this document"
+ ID_FILE_MRU_FILE12 "Open this document"
+ ID_FILE_MRU_FILE13 "Open this document"
+ ID_FILE_MRU_FILE14 "Open this document"
+ ID_FILE_MRU_FILE15 "Open this document"
+ ID_FILE_MRU_FILE16 "Open this document"
+ ID_NEXT_PANE "Switch to the next window pane\nNext Pane"
+ ID_PREV_PANE "Switch back to the previous window pane\nPrevious Pane"
+ ID_WINDOW_NEW "Open another window for the active document\nNew Window"
+ ID_WINDOW_ARRANGE "Arrange icons at the bottom of the window\nArrange Icons"
+ ID_WINDOW_CASCADE "Arrange windows so they overlap\nCascade Windows"
+ ID_WINDOW_TILE_HORZ "Arrange windows as non-overlapping tiles\nTile Windows"
+ ID_WINDOW_TILE_VERT "Arrange windows as non-overlapping tiles\nTile Windows"
+ ID_WINDOW_SPLIT "Split the active window into panes\nSplit"
+ ID_EDIT_CLEAR "Erase the selection\nErase"
+ ID_EDIT_CLEAR_ALL "Erase everything\nErase All"
+ ID_EDIT_COPY "Copy the selection and put it on the Clipboard\nCopy"
+ ID_EDIT_CUT "Cut the selection and put it on the Clipboard\nCut"
+ ID_EDIT_FIND "Find the specified text\nFind"
+ ID_EDIT_PASTE "Insert Clipboard contents\nPaste"
+ ID_EDIT_REPEAT "Repeat the last action\nRepeat"
+ ID_EDIT_REPLACE "Replace specific text with different text\nReplace"
+ ID_EDIT_SELECT_ALL "Select the entire document\nSelect All"
+ ID_EDIT_UNDO "Undo the last action\nUndo"
+ ID_EDIT_REDO "Redo the previously undone action\nRedo"
+ ID_VIEW_TOOLBAR "Show or hide the toolbar\nToggle ToolBar"
+ ID_VIEW_STATUS_BAR "Show or hide the status bar\nToggle StatusBar"
+END
+
+STRINGTABLE
+BEGIN
+ AFX_IDS_SCSIZE "Change the window size"
+ AFX_IDS_SCMOVE "Change the window position"
+ AFX_IDS_SCMINIMIZE "Reduce the window to an icon"
+ AFX_IDS_SCMAXIMIZE "Enlarge the window to full size"
+ AFX_IDS_SCNEXTWINDOW "Switch to the next document window"
+ AFX_IDS_SCPREVWINDOW "Switch to the previous document window"
+ AFX_IDS_SCCLOSE "Close the active window and prompts to save the documents"
+ AFX_IDS_SCRESTORE "Restore the window to normal size"
+ AFX_IDS_SCTASKLIST "Activate Task List"
+ AFX_IDS_MDICHILD "Activate this window"
+ AFX_IDS_PREVIEW_CLOSE "Close print preview mode\nCancel Preview"
+END
+
+#endif
+
+#ifdef _UNICODE
+IDR_MANIFEST RT_MANIFEST "res\\mfc1.manifest"
+#endif
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+#define _AFX_NO_SPLITTER_RESOURCES
+#define _AFX_NO_OLE_RESOURCES
+#define _AFX_NO_TRACKER_RESOURCES
+#define _AFX_NO_PROPERTY_RESOURCES
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+LANGUAGE 9, 1
+#pragma code_page(1252)
+#include "res\\mfc1.rc2" // non-Microsoft Visual C++ edited resources
+#include "afxres.rc" // Standard components
+#include "afxprint.rc" // printing/print preview resources
+#endif
+#endif // not APSTUDIO_INVOKED
diff --git a/Tests/MFC/mfc1/mfc1.reg b/Tests/MFC/mfc1/mfc1.reg
new file mode 100644
index 000000000..9f3a86ffb
--- /dev/null
+++ b/Tests/MFC/mfc1/mfc1.reg
@@ -0,0 +1,13 @@
+REGEDIT
+; This .REG file may be used by your SETUP program.
+; If a SETUP program is not available, the entries below will be
+; registered in your InitInstance automatically with a call to
+; CWinApp::RegisterShellFileTypes and COleObjectFactory::UpdateRegistryAll.
+
+HKEY_CLASSES_ROOT\.mf1 = mfc1.Document
+HKEY_CLASSES_ROOT\mfc1.Document\shell\open\command = mfc1.EXE %1
+HKEY_CLASSES_ROOT\mfc1.Document\shell\open\ddeexec = [open("%1")]
+HKEY_CLASSES_ROOT\mfc1.Document\shell\open\ddeexec\application = mfc1
+ ; note: the application is optional
+ ; (it defaults to the app name in "command")
+HKEY_CLASSES_ROOT\mfc1.Document = mfc1.Document
diff --git a/Tests/MFC/mfc1/mfc1.sln b/Tests/MFC/mfc1/mfc1.sln
new file mode 100644
index 000000000..78bbe56f2
--- /dev/null
+++ b/Tests/MFC/mfc1/mfc1.sln
@@ -0,0 +1,21 @@
+Microsoft Visual Studio Solution File, Format Version 8.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mfc1", "mfc1.vcproj", "{06C08100-1145-4104-AEC3-6BC8C608B819}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfiguration) = preSolution
+ Debug = Debug
+ Release = Release
+ EndGlobalSection
+ GlobalSection(ProjectConfiguration) = postSolution
+ {06C08100-1145-4104-AEC3-6BC8C608B819}.Debug.ActiveCfg = Debug|Win32
+ {06C08100-1145-4104-AEC3-6BC8C608B819}.Debug.Build.0 = Debug|Win32
+ {06C08100-1145-4104-AEC3-6BC8C608B819}.Release.ActiveCfg = Release|Win32
+ {06C08100-1145-4104-AEC3-6BC8C608B819}.Release.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddIns) = postSolution
+ EndGlobalSection
+EndGlobal
diff --git a/Tests/MFC/mfc1/mfc1.vcproj b/Tests/MFC/mfc1/mfc1.vcproj
new file mode 100644
index 000000000..6df86e564
--- /dev/null
+++ b/Tests/MFC/mfc1/mfc1.vcproj
@@ -0,0 +1,216 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="mfc1"
+ ProjectGUID="{06C08100-1145-4104-AEC3-6BC8C608B819}"
+ Keyword="MFCProj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="1"
+ UseOfMFC="2"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ TreatWChar_tAsBuiltInType="TRUE"
+ UsePrecompiledHeader="3"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="_DEBUG"
+ MkTypLibCompatible="FALSE"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(IntDir)"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="1"
+ UseOfMFC="2"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+ MinimalRebuild="FALSE"
+ RuntimeLibrary="2"
+ TreatWChar_tAsBuiltInType="TRUE"
+ UsePrecompiledHeader="3"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="NDEBUG"
+ MkTypLibCompatible="FALSE"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(IntDir)"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath=".\ChildFrm.cpp">
+ </File>
+ <File
+ RelativePath=".\MainFrm.cpp">
+ </File>
+ <File
+ RelativePath=".\mfc1.cpp">
+ </File>
+ <File
+ RelativePath=".\mfc1Doc.cpp">
+ </File>
+ <File
+ RelativePath=".\mfc1View.cpp">
+ </File>
+ <File
+ RelativePath=".\stdafx.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ <File
+ RelativePath=".\ChildFrm.h">
+ </File>
+ <File
+ RelativePath=".\MainFrm.h">
+ </File>
+ <File
+ RelativePath=".\mfc1.h">
+ </File>
+ <File
+ RelativePath=".\mfc1Doc.h">
+ </File>
+ <File
+ RelativePath=".\mfc1View.h">
+ </File>
+ <File
+ RelativePath=".\Resource.h">
+ </File>
+ <File
+ RelativePath=".\stdafx.h">
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+ <File
+ RelativePath=".\res\mfc1.ico">
+ </File>
+ <File
+ RelativePath=".\mfc1.rc">
+ </File>
+ <File
+ RelativePath=".\res\mfc1.rc2">
+ </File>
+ <File
+ RelativePath=".\res\mfc1Doc.ico">
+ </File>
+ <File
+ RelativePath=".\res\Toolbar.bmp">
+ </File>
+ </Filter>
+ <File
+ RelativePath=".\res\mfc1.manifest">
+ </File>
+ <File
+ RelativePath=".\mfc1.reg">
+ </File>
+ <File
+ RelativePath=".\ReadMe.txt">
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/Tests/MFC/mfc1/mfc1Doc.cpp b/Tests/MFC/mfc1/mfc1Doc.cpp
new file mode 100644
index 000000000..8767052ed
--- /dev/null
+++ b/Tests/MFC/mfc1/mfc1Doc.cpp
@@ -0,0 +1,78 @@
+// mfc1Doc.cpp : implementation of the Cmfc1Doc class
+//
+
+#include "stdafx.h"
+#include "mfc1.h"
+
+#include "mfc1Doc.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// Cmfc1Doc
+
+IMPLEMENT_DYNCREATE(Cmfc1Doc, CDocument)
+
+BEGIN_MESSAGE_MAP(Cmfc1Doc, CDocument)
+END_MESSAGE_MAP()
+
+
+// Cmfc1Doc construction/destruction
+
+Cmfc1Doc::Cmfc1Doc()
+{
+ // TODO: add one-time construction code here
+
+}
+
+Cmfc1Doc::~Cmfc1Doc()
+{
+}
+
+BOOL Cmfc1Doc::OnNewDocument()
+{
+ if (!CDocument::OnNewDocument())
+ return FALSE;
+
+ // TODO: add reinitialization code here
+ // (SDI documents will reuse this document)
+
+ return TRUE;
+}
+
+
+
+
+// Cmfc1Doc serialization
+
+void Cmfc1Doc::Serialize(CArchive& ar)
+{
+ if (ar.IsStoring())
+ {
+ // TODO: add storing code here
+ }
+ else
+ {
+ // TODO: add loading code here
+ }
+}
+
+
+// Cmfc1Doc diagnostics
+
+#ifdef _DEBUG
+void Cmfc1Doc::AssertValid() const
+{
+ CDocument::AssertValid();
+}
+
+void Cmfc1Doc::Dump(CDumpContext& dc) const
+{
+ CDocument::Dump(dc);
+}
+#endif //_DEBUG
+
+
+// Cmfc1Doc commands
diff --git a/Tests/MFC/mfc1/mfc1Doc.h b/Tests/MFC/mfc1/mfc1Doc.h
new file mode 100644
index 000000000..92d8e3541
--- /dev/null
+++ b/Tests/MFC/mfc1/mfc1Doc.h
@@ -0,0 +1,37 @@
+// mfc1Doc.h : interface of the Cmfc1Doc class
+//
+
+
+#pragma once
+
+class Cmfc1Doc : public CDocument
+{
+protected: // create from serialization only
+ Cmfc1Doc();
+ DECLARE_DYNCREATE(Cmfc1Doc)
+
+// Attributes
+public:
+
+// Operations
+public:
+
+// Overrides
+ public:
+ virtual BOOL OnNewDocument();
+ virtual void Serialize(CArchive& ar);
+
+// Implementation
+public:
+ virtual ~Cmfc1Doc();
+#ifdef _DEBUG
+ virtual void AssertValid() const;
+ virtual void Dump(CDumpContext& dc) const;
+#endif
+
+protected:
+
+// Generated message map functions
+protected:
+ DECLARE_MESSAGE_MAP()
+};
diff --git a/Tests/MFC/mfc1/mfc1View.cpp b/Tests/MFC/mfc1/mfc1View.cpp
new file mode 100644
index 000000000..06c765230
--- /dev/null
+++ b/Tests/MFC/mfc1/mfc1View.cpp
@@ -0,0 +1,99 @@
+// mfc1View.cpp : implementation of the Cmfc1View class
+//
+
+#include "stdafx.h"
+#include "mfc1.h"
+
+#include "mfc1Doc.h"
+#include "mfc1View.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// Cmfc1View
+
+IMPLEMENT_DYNCREATE(Cmfc1View, CView)
+
+BEGIN_MESSAGE_MAP(Cmfc1View, CView)
+ // Standard printing commands
+ ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
+ ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
+ ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
+END_MESSAGE_MAP()
+
+// Cmfc1View construction/destruction
+
+Cmfc1View::Cmfc1View()
+{
+ // TODO: add construction code here
+
+}
+
+Cmfc1View::~Cmfc1View()
+{
+}
+
+BOOL Cmfc1View::PreCreateWindow(CREATESTRUCT& cs)
+{
+ // TODO: Modify the Window class or styles here by modifying
+ // the CREATESTRUCT cs
+
+ return CView::PreCreateWindow(cs);
+}
+
+// Cmfc1View drawing
+
+void Cmfc1View::OnDraw(CDC* /*pDC*/)
+{
+ Cmfc1Doc* pDoc = GetDocument();
+ ASSERT_VALID(pDoc);
+ if (!pDoc)
+ return;
+
+ // TODO: add draw code for native data here
+}
+
+
+// Cmfc1View printing
+
+BOOL Cmfc1View::OnPreparePrinting(CPrintInfo* pInfo)
+{
+ // default preparation
+ return DoPreparePrinting(pInfo);
+}
+
+void Cmfc1View::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
+{
+ // TODO: add extra initialization before printing
+}
+
+void Cmfc1View::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
+{
+ // TODO: add cleanup after printing
+}
+
+
+// Cmfc1View diagnostics
+
+#ifdef _DEBUG
+void Cmfc1View::AssertValid() const
+{
+ CView::AssertValid();
+}
+
+void Cmfc1View::Dump(CDumpContext& dc) const
+{
+ CView::Dump(dc);
+}
+
+Cmfc1Doc* Cmfc1View::GetDocument() const // non-debug version is inline
+{
+ ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(Cmfc1Doc)));
+ return (Cmfc1Doc*)m_pDocument;
+}
+#endif //_DEBUG
+
+
+// Cmfc1View message handlers
diff --git a/Tests/MFC/mfc1/mfc1View.h b/Tests/MFC/mfc1/mfc1View.h
new file mode 100644
index 000000000..42446536b
--- /dev/null
+++ b/Tests/MFC/mfc1/mfc1View.h
@@ -0,0 +1,48 @@
+// mfc1View.h : interface of the Cmfc1View class
+//
+
+
+#pragma once
+
+
+class Cmfc1View : public CView
+{
+protected: // create from serialization only
+ Cmfc1View();
+ DECLARE_DYNCREATE(Cmfc1View)
+
+// Attributes
+public:
+ Cmfc1Doc* GetDocument() const;
+
+// Operations
+public:
+
+// Overrides
+ public:
+ virtual void OnDraw(CDC* pDC); // overridden to draw this view
+virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
+protected:
+ virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
+ virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
+ virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
+
+// Implementation
+public:
+ virtual ~Cmfc1View();
+#ifdef _DEBUG
+ virtual void AssertValid() const;
+ virtual void Dump(CDumpContext& dc) const;
+#endif
+
+protected:
+
+// Generated message map functions
+protected:
+ DECLARE_MESSAGE_MAP()
+};
+
+#ifndef _DEBUG // debug version in mfc1View.cpp
+inline Cmfc1Doc* Cmfc1View::GetDocument() const
+ { return reinterpret_cast<Cmfc1Doc*>(m_pDocument); }
+#endif
diff --git a/Tests/MFC/mfc1/res/Toolbar.bmp b/Tests/MFC/mfc1/res/Toolbar.bmp
new file mode 100644
index 000000000..d501723c1
--- /dev/null
+++ b/Tests/MFC/mfc1/res/Toolbar.bmp
Binary files differ
diff --git a/Tests/MFC/mfc1/res/mfc1.ico b/Tests/MFC/mfc1/res/mfc1.ico
new file mode 100644
index 000000000..8a84ca3d3
--- /dev/null
+++ b/Tests/MFC/mfc1/res/mfc1.ico
Binary files differ
diff --git a/Tests/MFC/mfc1/res/mfc1.manifest b/Tests/MFC/mfc1/res/mfc1.manifest
new file mode 100644
index 000000000..b15d2f2f2
--- /dev/null
+++ b/Tests/MFC/mfc1/res/mfc1.manifest
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+<assemblyIdentity
+ version="1.0.0.0"
+ processorArchitecture="X86"
+ name="Microsoft.Windows.mfc1"
+ type="win32"
+/>
+<description>Your app description here</description>
+<dependency>
+ <dependentAssembly>
+ <assemblyIdentity
+ type="win32"
+ name="Microsoft.Windows.Common-Controls"
+ version="6.0.0.0"
+ processorArchitecture="X86"
+ publicKeyToken="6595b64144ccf1df"
+ language="*"
+ />
+ </dependentAssembly>
+</dependency>
+</assembly>
diff --git a/Tests/MFC/mfc1/res/mfc1.rc2 b/Tests/MFC/mfc1/res/mfc1.rc2
new file mode 100644
index 000000000..62a3ab0d6
--- /dev/null
+++ b/Tests/MFC/mfc1/res/mfc1.rc2
@@ -0,0 +1,13 @@
+//
+// mfc1.RC2 - resources Microsoft Visual C++ does not edit directly
+//
+
+#ifdef APSTUDIO_INVOKED
+#error this file is not editable by Microsoft Visual C++
+#endif //APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Add manually edited resources here...
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/Tests/MFC/mfc1/res/mfc1Doc.ico b/Tests/MFC/mfc1/res/mfc1Doc.ico
new file mode 100644
index 000000000..2a1f1ae6e
--- /dev/null
+++ b/Tests/MFC/mfc1/res/mfc1Doc.ico
Binary files differ
diff --git a/Tests/MFC/mfc1/stdafx.cpp b/Tests/MFC/mfc1/stdafx.cpp
new file mode 100644
index 000000000..67fd1b539
--- /dev/null
+++ b/Tests/MFC/mfc1/stdafx.cpp
@@ -0,0 +1,5 @@
+// stdafx.cpp : source file that includes just the standard includes
+// mfc1.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
diff --git a/Tests/MFC/mfc1/stdafx.h b/Tests/MFC/mfc1/stdafx.h
new file mode 100644
index 000000000..35a678dcd
--- /dev/null
+++ b/Tests/MFC/mfc1/stdafx.h
@@ -0,0 +1,56 @@
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently,
+// but are changed infrequently
+
+#pragma once
+
+#ifndef VC_EXTRALEAN
+#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
+#endif
+
+// See http://msdn.microsoft.com/en-us/library/6sehtctf.aspx for more info
+// on WINVER and _WIN32_WINNT
+
+// Modify the following defines if you have to target a platform prior to the ones specified below.
+// Refer to MSDN for the latest info on corresponding values for different platforms.
+#ifndef WINVER // Allow use of features specific to Windows 95 and Windows NT 4 or later.
+#if _MSC_VER < 1600
+#define WINVER 0x0400 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
+#else
+#define WINVER 0x0501 // Target Windows XP and later with VS 10 and later
+#endif
+#endif
+
+#ifndef _WIN32_WINNT // Allow use of features specific to Windows NT 4 or later.
+#if _MSC_VER < 1600
+#define _WIN32_WINNT 0x0400 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
+#else
+#define _WIN32_WINNT 0x0501 // Target Windows XP and later with VS 10 and later
+#endif
+#endif
+
+#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later.
+#if _MSC_VER < 1600
+#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.
+#endif
+#endif
+
+#ifndef _WIN32_IE // Allow use of features specific to IE 4.0 or later.
+#if _MSC_VER < 1600
+#define _WIN32_IE 0x0400 // Change this to the appropriate value to target IE 5.0 or later.
+#endif
+#endif
+
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit
+
+// turns off MFC's hiding of some common and often safely ignored warning messages
+#define _AFX_ALL_WARNINGS
+
+#include <afxwin.h> // MFC core and standard components
+#include <afxext.h> // MFC extensions
+#include <afxdisp.h> // MFC Automation classes
+
+#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
+#ifndef _AFX_NO_AFXCMN_SUPPORT
+#include <afxcmn.h> // MFC support for Windows Common Controls
+#endif // _AFX_NO_AFXCMN_SUPPORT
diff --git a/Tests/MFC/try_compile/CMakeLists.txt b/Tests/MFC/try_compile/CMakeLists.txt
new file mode 100644
index 000000000..8e5d746f6
--- /dev/null
+++ b/Tests/MFC/try_compile/CMakeLists.txt
@@ -0,0 +1,15 @@
+cmake_minimum_required(VERSION 2.8)
+project(try_compile_mfc)
+
+set(files
+ stdafx.cpp
+ stdafx.h
+)
+
+set(CMAKE_MFC_FLAG "2")
+
+# VS generators add this automatically based on the CMAKE_MFC_FLAG value,
+# but generators matching "Make" require:
+add_definitions(-D_AFXDLL)
+
+add_executable(simplest_possible_mfc_exe WIN32 ${files})
diff --git a/Tests/MacroTest/CMakeLists.txt b/Tests/MacroTest/CMakeLists.txt
new file mode 100644
index 000000000..ef673fd85
--- /dev/null
+++ b/Tests/MacroTest/CMakeLists.txt
@@ -0,0 +1,91 @@
+# a simple C only test case
+cmake_minimum_required (VERSION 2.6)
+PROJECT (MacroTest)
+
+MACRO(FAILED testname)
+ MESSAGE(SEND_ERROR "${testname} failed ${ARGN}")
+ENDMACRO(FAILED)
+
+MACRO(PASS testname)
+ MESSAGE("${testname} passed ${ARGN}")
+ENDMACRO(PASS)
+
+# test ARGC
+MACRO(weird_name)
+ IF("${ARGC}" EQUAL "3")
+ PASS("ARGC")
+ ELSE("${ARGC}" EQUAL "3")
+ FAILED("ARGC" "Got: ${ARGC}")
+ ENDIF("${ARGC}" EQUAL "3")
+ENDMACRO(weird_name)
+WeIrD_nAmE(a1 a2 a3)
+
+# test ARGN
+MACRO(test_argn_macro argument)
+ IF("${ARGN}" EQUAL "3")
+ PASS("ARGN")
+ ELSE("${ARGN}" EQUAL "3")
+ FAILED("ARGN" "Got: ${ARGN}")
+ ENDIF("${ARGN}" EQUAL "3")
+ENDMACRO(test_argn_macro)
+Test_Argn_Macro(ignored 3)
+
+# case test
+MACRO(strange_macro m)
+ SET("${m}" strange_macro)
+ENDMACRO(strange_macro m)
+STRANGE_MACRO(var)
+set(second_var "second_var")
+IF("${var}" STREQUAL "strange_macro" AND "${second_var}" STREQUAL "second_var")
+ PASS("Case Test" "(${var} ${second_var})")
+ELSE("${var}" STREQUAL "strange_macro" AND "${second_var}" STREQUAL "second_var")
+ FAILED("Case test" "(${var} ${second_var})")
+ENDIF("${var}" STREQUAL "strange_macro" AND "${second_var}" STREQUAL "second_var")
+
+# test backing up command
+MACRO(ADD_EXECUTABLE exec)
+ _ADD_EXECUTABLE("mini${exec}" ${ARGN})
+ENDMACRO(ADD_EXECUTABLE)
+
+INCLUDE(CheckCSourceCompiles)
+Check_C_Source_Compiles(
+"
+#include <stdio.h>
+#ifdef __CLASSIC_C__
+int main(){
+ int ac;
+ char*av[];
+#else
+int main(int ac, char*av[]){
+#endif
+ if(ac > 1000){return *av[0];}
+ return 0;
+}"
+SOME_CHECK)
+IF(SOME_CHECK)
+ MESSAGE("CheckCSourceCompiles works")
+ELSE(SOME_CHECK)
+ MESSAGE(FATAL_ERROR "CheckCSourceCompiles does not work")
+ENDIF(SOME_CHECK)
+
+INCLUDE(CheckCXXSourceCompiles)
+Check_CXX_Source_Compiles(
+"
+#include <stdio.h>
+int main(int ac, char*av[]){
+ if(ac > 1000){return *av[0];}
+ return 0;
+}"
+SOME_CHECK)
+IF(SOME_CHECK)
+ MESSAGE("CheckCXXSourceCompiles works")
+ELSE(SOME_CHECK)
+ MESSAGE(FATAL_ERROR "CheckCXXSourceCompiles does not work")
+ENDIF(SOME_CHECK)
+
+ADD_EXECUTABLE(MacroTest macroTest.c)
+
+MACRO(GET_CURRENT_FILE var)
+ SET(${var} ${CMAKE_CURRENT_LIST_FILE})
+ENDMACRO(GET_CURRENT_FILE)
+INCLUDE(context.cmake)
diff --git a/Tests/MacroTest/context.cmake b/Tests/MacroTest/context.cmake
new file mode 100644
index 000000000..f4d7035fb
--- /dev/null
+++ b/Tests/MacroTest/context.cmake
@@ -0,0 +1,10 @@
+GET_CURRENT_FILE(current_file)
+IF(NOT "${current_file}" STREQUAL "${CMAKE_CURRENT_LIST_FILE}")
+ MESSAGE(FATAL_ERROR
+ "Macro file context is broken. Expected:\n"
+ " ${CMAKE_CURRENT_LIST_FILE}\n"
+ "but got:\n"
+ " ${current_file}\n"
+ "from the macro."
+ )
+ENDIF(NOT "${current_file}" STREQUAL "${CMAKE_CURRENT_LIST_FILE}")
diff --git a/Tests/MacroTest/macroTest.c b/Tests/MacroTest/macroTest.c
new file mode 100644
index 000000000..e0ced6afd
--- /dev/null
+++ b/Tests/MacroTest/macroTest.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main(int argc, char* argv[])
+{
+ printf("Running command: %s with %d arguments\n", argv[0], argc);
+ return 0;
+}
diff --git a/Tests/MakeClean/CMakeLists.txt b/Tests/MakeClean/CMakeLists.txt
new file mode 100644
index 000000000..97d3554bd
--- /dev/null
+++ b/Tests/MakeClean/CMakeLists.txt
@@ -0,0 +1,57 @@
+cmake_minimum_required (VERSION 2.6)
+PROJECT(MakeClean)
+
+# Build the to-clean project.
+TRY_COMPILE(TOCLEAN_BUILT
+ ${MakeClean_BINARY_DIR}/ToClean
+ ${MakeClean_SOURCE_DIR}/ToClean
+ ToClean
+ OUTPUT_VARIABLE OUTPUT
+ )
+IF(TOCLEAN_BUILT)
+ MESSAGE(
+ "Building ToClean succeeded with the following output:\n"
+ "[${OUTPUT}]"
+ )
+ELSE(TOCLEAN_BUILT)
+ MESSAGE(FATAL_ERROR
+ "Building ToClean failed with the following output:\n"
+ "[${OUTPUT}]"
+ )
+ENDIF(TOCLEAN_BUILT)
+
+# Get the set of files to check from the ToClean project.
+INCLUDE(${MakeClean_BINARY_DIR}/ToClean/ToCleanFiles.cmake)
+
+# Check for the existence of the files.
+FOREACH(f ${TOCLEAN_FILES})
+ IF(EXISTS "${f}")
+ ELSE(EXISTS "${f}")
+ MESSAGE(FATAL_ERROR "File \"${f}\" does not exist!")
+ ENDIF(EXISTS "${f}")
+ENDFOREACH(f)
+
+# Configure an executable to check that all the files are missing.
+SET(CHECK_FILES)
+FOREACH(f ${TOCLEAN_FILES})
+ SET(CHECK_FILES "${CHECK_FILES} \"${f}\",\n")
+ENDFOREACH(f)
+CONFIGURE_FILE(${MakeClean_SOURCE_DIR}/check_clean.c.in
+ ${MakeClean_BINARY_DIR}/check_clean.c @ONLY IMMEDIATE)
+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
+ COMMENT "Clean the ToClean Project"
+ )
diff --git a/Tests/MakeClean/ToClean/CMakeLists.txt b/Tests/MakeClean/ToClean/CMakeLists.txt
new file mode 100644
index 000000000..50facadb7
--- /dev/null
+++ b/Tests/MakeClean/ToClean/CMakeLists.txt
@@ -0,0 +1,31 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(ToClean)
+
+# Build a simple project.
+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}")
+
+# Create a file that must be registered for cleaning.
+FILE(WRITE "${ToClean_BINARY_DIR}/Registered.txt"
+ "File registered for cleaning.\n")
+SET_DIRECTORY_PROPERTIES(PROPERTIES
+ ADDITIONAL_MAKE_CLEAN_FILES "${ToClean_BINARY_DIR}/Registered.txt")
+SET(TOCLEAN_FILES ${TOCLEAN_FILES} "${ToClean_BINARY_DIR}/Registered.txt")
+
+# Create a custom command whose output should be cleaned.
+ADD_CUSTOM_COMMAND(OUTPUT ${ToClean_BINARY_DIR}/generated.txt
+ DEPENDS ${ToClean_SOURCE_DIR}/toclean.cxx
+ COMMAND ${CMAKE_COMMAND}
+ ARGS -E copy ${ToClean_SOURCE_DIR}/toclean.cxx
+ ${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")
+
+# Configure a file listing these build-time-generated files.
+CONFIGURE_FILE(${ToClean_SOURCE_DIR}/ToCleanFiles.cmake.in
+ ${ToClean_BINARY_DIR}/ToCleanFiles.cmake @ONLY IMMEDIATE)
diff --git a/Tests/MakeClean/ToClean/ToCleanFiles.cmake.in b/Tests/MakeClean/ToClean/ToCleanFiles.cmake.in
new file mode 100644
index 000000000..10d11c37a
--- /dev/null
+++ b/Tests/MakeClean/ToClean/ToCleanFiles.cmake.in
@@ -0,0 +1 @@
+SET(TOCLEAN_FILES "@TOCLEAN_FILES@")
diff --git a/Tests/MakeClean/ToClean/toclean.cxx b/Tests/MakeClean/ToClean/toclean.cxx
new file mode 100644
index 000000000..f8b643afb
--- /dev/null
+++ b/Tests/MakeClean/ToClean/toclean.cxx
@@ -0,0 +1,4 @@
+int main()
+{
+ return 0;
+}
diff --git a/Tests/MakeClean/check_clean.c.in b/Tests/MakeClean/check_clean.c.in
new file mode 100644
index 000000000..5bc4ab880
--- /dev/null
+++ b/Tests/MakeClean/check_clean.c.in
@@ -0,0 +1,26 @@
+#include <stdio.h>
+
+int main()
+{
+ /* The list of files to check. */
+ const char* files[] =
+ {
+ @CHECK_FILES@
+ 0
+ };
+
+ /* No file should exist. */
+ const char** f = files;
+ int result = 0;
+ for(; *f; ++f)
+ {
+ FILE* pf = fopen(*f, "rb");
+ if(pf)
+ {
+ fclose(pf);
+ fprintf(stderr, "File \"%s\" exists!", *f);
+ result = 1;
+ }
+ }
+ return result;
+}
diff --git a/Tests/MathTest/CMakeLists.txt b/Tests/MathTest/CMakeLists.txt
new file mode 100644
index 000000000..d1e5b1acd
--- /dev/null
+++ b/Tests/MathTest/CMakeLists.txt
@@ -0,0 +1,29 @@
+cmake_minimum_required (VERSION 2.6)
+PROJECT(MathTest)
+
+
+# Expression test
+
+SET(expressions
+ "5 * ( 3 + 4)"
+ "(1 | 2 | 4 | 8) & 16"
+ "1 +(3*4) + 10 >> 2"
+ "10000 / 20 / 4"
+ "10000 / (20 / 4)"
+ )
+
+SET(FILE_EXPRESSIONS "")
+FOREACH(expression
+ ${expressions})
+ MATH(EXPR expr "${expression}")
+ SET(FILE_EXPRESSIONS "${FILE_EXPRESSIONS}TEST_EXPRESSION(${expression}, ${expr})\n")
+ENDFOREACH(expression)
+
+CONFIGURE_FILE(
+ "${CMAKE_CURRENT_SOURCE_DIR}/MathTestTests.h.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/MathTestTests.h"
+ @ONLY)
+
+INCLUDE_DIRECTORIES("${CMAKE_CURRENT_BINARY_DIR}")
+ADD_EXECUTABLE(MathTest MathTestExec.cxx)
+
diff --git a/Tests/MathTest/MathTestExec.cxx b/Tests/MathTest/MathTestExec.cxx
new file mode 100644
index 000000000..5b94602a6
--- /dev/null
+++ b/Tests/MathTest/MathTestExec.cxx
@@ -0,0 +1,26 @@
+#include <stdio.h>
+
+#define TEST_EXPRESSION(x, y) \
+ if ( (x) != (y) ) \
+ { \
+ printf("Problem with EXPR: Expression: \"%s\" in C returns %d while in CMake returns: %d\n", \
+ #x, (x), (y)); \
+ res ++; \
+ }
+
+int main(int argc, char* argv[])
+{
+ if ( argc > 1 )
+ {
+ printf("Usage: %s\n", argv[0]);
+ return 1;
+ }
+ int res = 0;
+#include "MathTestTests.h"
+ if ( res != 0 )
+ {
+ printf("%s: %d math tests failed\n", argv[0], res);
+ return 1;
+ }
+ return 0;
+}
diff --git a/Tests/MathTest/MathTestTests.h.in b/Tests/MathTest/MathTestTests.h.in
new file mode 100644
index 000000000..39c6861d7
--- /dev/null
+++ b/Tests/MathTest/MathTestTests.h.in
@@ -0,0 +1 @@
+@FILE_EXPRESSIONS@
diff --git a/Tests/MissingSourceFile/CMakeLists.txt b/Tests/MissingSourceFile/CMakeLists.txt
new file mode 100644
index 000000000..a7206c897
--- /dev/null
+++ b/Tests/MissingSourceFile/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8)
+project(MissingSourceFile C)
+add_executable(MissingSourceFile DoesNotExist/MissingSourceFile.c)
diff --git a/Tests/Module/CheckTypeSize/CMakeLists.txt b/Tests/Module/CheckTypeSize/CMakeLists.txt
new file mode 100644
index 000000000..45e9f6757
--- /dev/null
+++ b/Tests/Module/CheckTypeSize/CMakeLists.txt
@@ -0,0 +1,18 @@
+cmake_minimum_required(VERSION 2.8.1 FATAL_ERROR)
+project(CheckTypeSize C)
+
+include(CheckTypeSize)
+check_type_size("void*" SIZEOF_DATA_PTR)
+check_type_size(char SIZEOF_CHAR)
+check_type_size(short SIZEOF_SHORT)
+check_type_size(int SIZEOF_INT)
+check_type_size(long SIZEOF_LONG)
+check_type_size("long long" SIZEOF_LONG_LONG)
+check_type_size(__int64 SIZEOF___INT64)
+check_type_size(size_t SIZEOF_SIZE_T)
+check_type_size(ssize_t SIZEOF_SSIZE_T)
+
+configure_file(config.h.in config.h)
+include_directories(${CheckTypeSize_BINARY_DIR})
+
+add_executable(CheckTypeSize CheckTypeSize.c)
diff --git a/Tests/Module/CheckTypeSize/CheckTypeSize.c b/Tests/Module/CheckTypeSize/CheckTypeSize.c
new file mode 100644
index 000000000..602c83494
--- /dev/null
+++ b/Tests/Module/CheckTypeSize/CheckTypeSize.c
@@ -0,0 +1,122 @@
+#include "config.h"
+
+#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;
+
+ /* 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
+
+ return result;
+}
diff --git a/Tests/Module/CheckTypeSize/config.h.in b/Tests/Module/CheckTypeSize/config.h.in
new file mode 100644
index 000000000..b5bfbf6e5
--- /dev/null
+++ b/Tests/Module/CheckTypeSize/config.h.in
@@ -0,0 +1,39 @@
+#cmakedefine HAVE_SYS_TYPES_H
+#cmakedefine HAVE_STDINT_H
+#cmakedefine HAVE_STDDEF_H
+
+/* void* */
+#cmakedefine HAVE_SIZEOF_DATA_PTR
+@SIZEOF_DATA_PTR_CODE@
+
+/* char */
+#cmakedefine HAVE_SIZEOF_CHAR
+@SIZEOF_CHAR_CODE@
+
+/* short */
+#cmakedefine HAVE_SIZEOF_SHORT
+@SIZEOF_SHORT_CODE@
+
+/* int */
+#cmakedefine HAVE_SIZEOF_INT
+@SIZEOF_INT_CODE@
+
+/* long */
+#cmakedefine HAVE_SIZEOF_LONG
+@SIZEOF_LONG_CODE@
+
+/* long long */
+#cmakedefine HAVE_SIZEOF_LONG_LONG
+@SIZEOF_LONG_LONG_CODE@
+
+/* __int64 */
+#cmakedefine HAVE_SIZEOF___INT64
+@SIZEOF___INT64_CODE@
+
+/* size_t */
+#cmakedefine HAVE_SIZEOF_SIZE_T
+@SIZEOF_SIZE_T_CODE@
+
+/* ssize_t */
+#cmakedefine HAVE_SIZEOF_SSIZE_T
+@SIZEOF_SSIZE_T_CODE@
diff --git a/Tests/Module/GenerateExportHeader/CMakeLists.txt b/Tests/Module/GenerateExportHeader/CMakeLists.txt
new file mode 100644
index 000000000..4a5b1cb5a
--- /dev/null
+++ b/Tests/Module/GenerateExportHeader/CMakeLists.txt
@@ -0,0 +1,184 @@
+cmake_minimum_required(VERSION 2.8.5 FATAL_ERROR)
+
+project(GenerateExportHeader)
+
+# Prevent timeout on Watcom by not running the tests.
+if ("${CMAKE_CXX_COMPILER_ID}" MATCHES Watcom)
+ file(WRITE
+ "${CMAKE_CURRENT_BINARY_DIR}/main.cxx"
+ "int main() { return 0; }
+ "
+ )
+
+ add_executable(
+ GenerateExportHeader
+ "${CMAKE_CURRENT_BINARY_DIR}/main.cxx"
+ )
+ return()
+endif()
+
+include(CheckCXXCompilerFlag)
+
+set( CMAKE_INCLUDE_CURRENT_DIR ON )
+
+macro(TEST_FAIL value msg)
+ if (${value})
+ message (SEND_ERROR "Test fail:" ${msg} ${Out} )
+ endif ()
+endmacro()
+
+macro(TEST_PASS value msg)
+ if (NOT ${value})
+ message (SEND_ERROR "Test fail:" ${msg} ${Out} )
+ endif ()
+endmacro()
+
+check_cxx_compiler_flag(-Werror HAS_WERROR_FLAG)
+
+if(HAS_WERROR_FLAG)
+ set(ERROR_FLAG "-Werror")
+else()
+ # MSVC
+ # And intel on windows?
+ # http://software.intel.com/en-us/articles/how-to-handle-warnings-message-in-compiler/?wapkw=%28compiler+warning+message%29
+ check_cxx_compiler_flag("/WX" HAS_WX_FLAG)
+ if(HAS_WX_FLAG)
+ set(ERROR_FLAG "/WX")
+ else()
+ # Sun CC
+ # http://www.acsu.buffalo.edu/~charngda/sunstudio.html
+ check_cxx_compiler_flag("-errwarn=%all" HAS_ERRWARN_ALL)
+ if (HAS_ERRWARN_ALL)
+ set(ERROR_FLAG "-errwarn=%all")
+ else()
+ endif()
+ 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()
+
+macro(build_fail Include Library LibrarySource Source Message)
+ _do_build(${Include} ${Library} ${LibrarySource} "${Source}")
+ test_fail(Result ${Message})
+endmacro()
+
+macro(build_pass Include Library LibrarySource Source Message)
+ _do_build(${Include} ${Library} ${LibrarySource} "${Source}")
+ test_pass(Result ${Message})
+endmacro()
+
+include(GenerateExportHeader)
+
+add_compiler_export_flags()
+
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
+
+message("#### COMPILER_HAS_DEPRECATED: " ${COMPILER_HAS_DEPRECATED})
+message("#### COMPILER_HAS_HIDDEN_VISIBILITY: " ${COMPILER_HAS_HIDDEN_VISIBILITY})
+message("#### WIN32: " ${WIN32})
+message("#### HAS_WERROR_FLAG: " ${HAS_WERROR_FLAG})
+
+set(link_libraries)
+macro(macro_add_test_library name)
+ add_subdirectory(${name})
+ include_directories(${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 (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()
+
+if(MSVC AND COMPILER_HAS_DEPRECATED)
+ add_definitions(/wd4996)
+endif()
+
+add_executable(GenerateExportHeader exportheader_test.cpp)
+
+target_link_libraries(GenerateExportHeader ${link_libraries})
diff --git a/Tests/Module/GenerateExportHeader/exportheader_test.cpp b/Tests/Module/GenerateExportHeader/exportheader_test.cpp
new file mode 100644
index 000000000..55c3c1ad6
--- /dev/null
+++ b/Tests/Module/GenerateExportHeader/exportheader_test.cpp
@@ -0,0 +1,82 @@
+
+#include "libshared.h"
+
+#include "libstatic.h"
+
+// #define BUILD_FAIL
+
+#ifndef BUILD_FAIL
+#define DOES_NOT_BUILD(function)
+#else
+#define DOES_NOT_BUILD(function) function
+#endif
+
+int main()
+{
+ {
+ Libshared l;
+ l.libshared();
+ l.libshared_exported();
+ l.libshared_deprecated();
+ l.libshared_not_exported();
+
+ DOES_NOT_BUILD(l.libshared_excluded();)
+ }
+
+ {
+ LibsharedNotExported l;
+ DOES_NOT_BUILD(l.libshared();)
+ l.libshared_exported();
+ l.libshared_deprecated();
+ DOES_NOT_BUILD(l.libshared_not_exported();)
+ DOES_NOT_BUILD(l.libshared_excluded();)
+ }
+
+ {
+ LibsharedExcluded l;
+ DOES_NOT_BUILD(l.libshared();)
+ l.libshared_exported();
+ l.libshared_deprecated();
+ DOES_NOT_BUILD(l.libshared_not_exported();)
+ DOES_NOT_BUILD(l.libshared_excluded();)
+ }
+
+ libshared_exported();
+ libshared_deprecated();
+ DOES_NOT_BUILD(libshared_not_exported();)
+ DOES_NOT_BUILD(libshared_excluded();)
+
+ {
+ Libstatic l;
+ l.libstatic();
+ l.libstatic_exported();
+ l.libstatic_deprecated();
+ l.libstatic_not_exported();
+ l.libstatic_excluded();
+ }
+
+ {
+ LibstaticNotExported l;
+ l.libstatic();
+ l.libstatic_exported();
+ l.libstatic_deprecated();
+ l.libstatic_not_exported();
+ l.libstatic_excluded();
+ }
+
+ {
+ LibstaticExcluded l;
+ l.libstatic();
+ l.libstatic_exported();
+ l.libstatic_deprecated();
+ l.libstatic_not_exported();
+ l.libstatic_excluded();
+ }
+
+ libstatic_exported();
+ libstatic_deprecated();
+ libstatic_not_exported();
+ libstatic_excluded();
+
+ return 0;
+}
diff --git a/Tests/Module/GenerateExportHeader/lib_shared_and_static/CMakeLists.txt b/Tests/Module/GenerateExportHeader/lib_shared_and_static/CMakeLists.txt
new file mode 100644
index 000000000..be0387fd5
--- /dev/null
+++ b/Tests/Module/GenerateExportHeader/lib_shared_and_static/CMakeLists.txt
@@ -0,0 +1,23 @@
+
+cmake_minimum_required(VERSION 2.8)
+
+project(lib_shared_and_static)
+
+include(GenerateExportHeader)
+
+add_compiler_export_flags()
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(lib_SRCS
+ libshared_and_static.cpp
+)
+
+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)
+
+export(TARGETS shared_variant static_variant FILE Targets.cmake)
diff --git a/Tests/Module/GenerateExportHeader/lib_shared_and_static/libshared_and_static.cpp b/Tests/Module/GenerateExportHeader/lib_shared_and_static/libshared_and_static.cpp
new file mode 100644
index 000000000..1e0727362
--- /dev/null
+++ b/Tests/Module/GenerateExportHeader/lib_shared_and_static/libshared_and_static.cpp
@@ -0,0 +1,91 @@
+
+#include "libshared_and_static.h"
+
+int LibsharedAndStatic::libshared_and_static() const
+{
+ return 0;
+}
+
+int LibsharedAndStatic::libshared_and_static_exported() const
+{
+ return 0;
+}
+
+int LibsharedAndStatic::libshared_and_static_deprecated() const
+{
+ return 0;
+}
+
+int LibsharedAndStatic::libshared_and_static_not_exported() const {
+ return 0;
+}
+
+int LibsharedAndStatic::libshared_and_static_excluded() const {
+ return 0;
+}
+
+int LibsharedAndStaticNotExported::libshared_and_static() const
+{
+ return 0;
+}
+
+int LibsharedAndStaticNotExported::libshared_and_static_exported() const
+{
+ return 0;
+}
+
+int LibsharedAndStaticNotExported::libshared_and_static_deprecated() const
+{
+ return 0;
+}
+
+int LibsharedAndStaticNotExported::libshared_and_static_not_exported() const {
+ return 0;
+}
+
+int LibsharedAndStaticNotExported::libshared_and_static_excluded() const {
+ return 0;
+}
+
+int LibsharedAndStaticExcluded::libshared_and_static() const
+{
+ return 0;
+}
+
+int LibsharedAndStaticExcluded::libshared_and_static_exported() const
+{
+ return 0;
+}
+
+int LibsharedAndStaticExcluded::libshared_and_static_deprecated() const
+{
+ return 0;
+}
+
+int LibsharedAndStaticExcluded::libshared_and_static_not_exported() const {
+ return 0;
+}
+
+int LibsharedAndStaticExcluded::libshared_and_static_excluded() const {
+ return 0;
+}
+
+int libshared_and_static() {
+ return 0;
+}
+
+int libshared_and_static_exported() {
+ return 0;
+}
+
+int libshared_and_static_deprecated() {
+ return 0;
+}
+
+int libshared_and_static_not_exported() {
+ return 0;
+}
+
+int libshared_and_static_excluded() {
+ return 0;
+}
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
new file mode 100644
index 000000000..049bfe9c4
--- /dev/null
+++ b/Tests/Module/GenerateExportHeader/lib_shared_and_static/libshared_and_static.h
@@ -0,0 +1,54 @@
+
+#ifndef SHARED_AND_STATIC_H
+#define SHARED_AND_STATIC_H
+
+#include "libshared_and_static_export.h"
+
+class 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 libshared_and_static_not_exported() const;
+
+ int 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 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;
+};
+
+class LIBSHARED_AND_STATIC_NO_EXPORT LibsharedAndStaticExcluded {
+public:
+ int libshared_and_static() const;
+
+ int LIBSHARED_AND_STATIC_EXPORT libshared_and_static_exported() const;
+
+ int 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;
+};
+
+LIBSHARED_AND_STATIC_EXPORT int libshared_and_static_exported();
+
+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();
+
+#endif
diff --git a/Tests/Module/GenerateExportHeader/lib_shared_and_statictest/CMakeLists.txt b/Tests/Module/GenerateExportHeader/lib_shared_and_statictest/CMakeLists.txt
new file mode 100644
index 000000000..207534d6e
--- /dev/null
+++ b/Tests/Module/GenerateExportHeader/lib_shared_and_statictest/CMakeLists.txt
@@ -0,0 +1,33 @@
+
+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/libshared/CMakeLists.txt b/Tests/Module/GenerateExportHeader/libshared/CMakeLists.txt
new file mode 100644
index 000000000..e20adb1a7
--- /dev/null
+++ b/Tests/Module/GenerateExportHeader/libshared/CMakeLists.txt
@@ -0,0 +1,16 @@
+
+cmake_minimum_required(VERSION 2.8)
+
+project(libshared)
+
+include(GenerateExportHeader)
+
+add_compiler_export_flags()
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+add_library(libshared SHARED libshared.cpp)
+
+generate_export_header(libshared)
+
+export(TARGETS libshared FILE Targets.cmake)
diff --git a/Tests/Module/GenerateExportHeader/libshared/libshared.cpp b/Tests/Module/GenerateExportHeader/libshared/libshared.cpp
new file mode 100644
index 000000000..d4041b36d
--- /dev/null
+++ b/Tests/Module/GenerateExportHeader/libshared/libshared.cpp
@@ -0,0 +1,91 @@
+
+#include "libshared.h"
+
+int Libshared::libshared() const
+{
+ return 0;
+}
+
+int Libshared::libshared_exported() const
+{
+ return 0;
+}
+
+int Libshared::libshared_deprecated() const
+{
+ return 0;
+}
+
+int Libshared::libshared_not_exported() const {
+ return 0;
+}
+
+int Libshared::libshared_excluded() const {
+ return 0;
+}
+
+int LibsharedNotExported::libshared() const
+{
+ return 0;
+}
+
+int LibsharedNotExported::libshared_exported() const
+{
+ return 0;
+}
+
+int LibsharedNotExported::libshared_deprecated() const
+{
+ return 0;
+}
+
+int LibsharedNotExported::libshared_not_exported() const {
+ return 0;
+}
+
+int LibsharedNotExported::libshared_excluded() const {
+ return 0;
+}
+
+int LibsharedExcluded::libshared() const
+{
+ return 0;
+}
+
+int LibsharedExcluded::libshared_exported() const
+{
+ return 0;
+}
+
+int LibsharedExcluded::libshared_deprecated() const
+{
+ return 0;
+}
+
+int LibsharedExcluded::libshared_not_exported() const {
+ return 0;
+}
+
+int LibsharedExcluded::libshared_excluded() const {
+ return 0;
+}
+
+int libshared() {
+ return 0;
+}
+
+int libshared_exported() {
+ return 0;
+}
+
+int libshared_deprecated() {
+ return 0;
+}
+
+int libshared_not_exported() {
+ return 0;
+}
+
+int libshared_excluded() {
+ return 0;
+}
diff --git a/Tests/Module/GenerateExportHeader/libshared/libshared.h b/Tests/Module/GenerateExportHeader/libshared/libshared.h
new file mode 100644
index 000000000..3d9bbff4f
--- /dev/null
+++ b/Tests/Module/GenerateExportHeader/libshared/libshared.h
@@ -0,0 +1,54 @@
+
+#ifndef LIBSHARED_H
+#define LIBSHARED_H
+
+#include "libshared_export.h"
+
+class LIBSHARED_EXPORT Libshared {
+public:
+ int libshared() const;
+
+ int libshared_exported() const;
+
+ int LIBSHARED_DEPRECATED libshared_deprecated() const;
+
+ int libshared_not_exported() const;
+
+ int LIBSHARED_NO_EXPORT libshared_excluded() const;
+};
+
+class LibsharedNotExported {
+public:
+ int libshared() const;
+
+ int LIBSHARED_EXPORT libshared_exported() const;
+
+ int LIBSHARED_DEPRECATED_EXPORT libshared_deprecated() const;
+
+ int libshared_not_exported() const;
+
+ int LIBSHARED_NO_EXPORT libshared_excluded() const;
+};
+
+class LIBSHARED_NO_EXPORT LibsharedExcluded {
+public:
+ int libshared() const;
+
+ int LIBSHARED_EXPORT libshared_exported() const;
+
+ int LIBSHARED_DEPRECATED_EXPORT libshared_deprecated() const;
+
+ int libshared_not_exported() const;
+
+ int LIBSHARED_NO_EXPORT libshared_excluded() const;
+};
+
+LIBSHARED_EXPORT int libshared_exported();
+
+LIBSHARED_DEPRECATED_EXPORT int libshared_deprecated();
+
+int libshared_not_exported();
+
+int LIBSHARED_NO_EXPORT libshared_excluded();
+
+#endif
diff --git a/Tests/Module/GenerateExportHeader/libsharedtest/CMakeLists.txt b/Tests/Module/GenerateExportHeader/libsharedtest/CMakeLists.txt
new file mode 100644
index 000000000..a5804fcfb
--- /dev/null
+++ b/Tests/Module/GenerateExportHeader/libsharedtest/CMakeLists.txt
@@ -0,0 +1,44 @@
+
+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")
+
+# 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/libstatic/CMakeLists.txt b/Tests/Module/GenerateExportHeader/libstatic/CMakeLists.txt
new file mode 100644
index 000000000..b2db3ea74
--- /dev/null
+++ b/Tests/Module/GenerateExportHeader/libstatic/CMakeLists.txt
@@ -0,0 +1,18 @@
+
+cmake_minimum_required(VERSION 2.8)
+
+project(libstatic)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+include(GenerateExportHeader)
+
+add_compiler_export_flags()
+
+# Show that the export header has no effect on a static library.
+
+add_library(libstatic STATIC libstatic.cpp)
+
+generate_export_header(libstatic)
+
+export(TARGETS libstatic FILE Targets.cmake)
diff --git a/Tests/Module/GenerateExportHeader/libstatic/libstatic.cpp b/Tests/Module/GenerateExportHeader/libstatic/libstatic.cpp
new file mode 100644
index 000000000..0710c3e9e
--- /dev/null
+++ b/Tests/Module/GenerateExportHeader/libstatic/libstatic.cpp
@@ -0,0 +1,87 @@
+
+#include "libstatic.h"
+
+int Libstatic::libstatic() const
+{
+ return 0;
+}
+
+int Libstatic::libstatic_exported() const
+{
+ return 0;
+}
+
+int Libstatic::libstatic_deprecated() const
+{
+ return 0;
+}
+
+int Libstatic::libstatic_not_exported() const {
+ return 0;
+}
+
+int Libstatic::libstatic_excluded() const {
+ return 0;
+}
+
+int LibstaticNotExported::libstatic() const
+{
+ return 0;
+}
+
+int LibstaticNotExported::libstatic_exported() const
+{
+ return 0;
+}
+
+int LibstaticNotExported::libstatic_deprecated() const
+{
+ return 0;
+}
+
+int LibstaticNotExported::libstatic_not_exported() const {
+ return 0;
+}
+
+int LibstaticNotExported::libstatic_excluded() const {
+ return 0;
+}
+
+int LibstaticExcluded::libstatic() const
+{
+ return 0;
+}
+
+int LibstaticExcluded::libstatic_exported() const
+{
+ return 0;
+}
+
+int LibstaticExcluded::libstatic_deprecated() const
+{
+ return 0;
+}
+
+int LibstaticExcluded::libstatic_not_exported() const {
+ return 0;
+}
+
+int LibstaticExcluded::libstatic_excluded() const {
+ return 0;
+}
+
+int libstatic_exported() {
+ return 0;
+}
+
+int libstatic_deprecated() {
+ return 0;
+}
+
+int libstatic_not_exported() {
+ return 0;
+}
+
+int libstatic_excluded() {
+ return 0;
+}
diff --git a/Tests/Module/GenerateExportHeader/libstatic/libstatic.h b/Tests/Module/GenerateExportHeader/libstatic/libstatic.h
new file mode 100644
index 000000000..cc7a35b4e
--- /dev/null
+++ b/Tests/Module/GenerateExportHeader/libstatic/libstatic.h
@@ -0,0 +1,54 @@
+
+#ifndef LIBSTATIC_H
+#define LIBSTATIC_H
+
+#include "libstatic_export.h"
+
+class LIBSTATIC_EXPORT Libstatic {
+public:
+ int libstatic() const;
+
+ int libstatic_exported() const;
+
+ int LIBSTATIC_DEPRECATED libstatic_deprecated() const;
+
+ int libstatic_not_exported() const;
+
+ int LIBSTATIC_NO_EXPORT libstatic_excluded() const;
+};
+
+class LibstaticNotExported {
+public:
+ int libstatic() const;
+
+ int LIBSTATIC_EXPORT libstatic_exported() const;
+
+ int LIBSTATIC_DEPRECATED libstatic_deprecated() const;
+
+ int libstatic_not_exported() const;
+
+ int LIBSTATIC_NO_EXPORT libstatic_excluded() const;
+};
+
+class LIBSTATIC_NO_EXPORT LibstaticExcluded {
+public:
+ int libstatic() const;
+
+ int LIBSTATIC_EXPORT libstatic_exported() const;
+
+ int LIBSTATIC_DEPRECATED libstatic_deprecated() const;
+
+ int libstatic_not_exported() const;
+
+ int LIBSTATIC_NO_EXPORT libstatic_excluded() const;
+};
+
+LIBSTATIC_EXPORT int libstatic_exported();
+
+LIBSTATIC_DEPRECATED_EXPORT int libstatic_deprecated();
+
+int libstatic_not_exported();
+
+int LIBSTATIC_NO_EXPORT libstatic_excluded();
+
+#endif
diff --git a/Tests/Module/GenerateExportHeader/libstatictest/CMakeLists.txt b/Tests/Module/GenerateExportHeader/libstatictest/CMakeLists.txt
new file mode 100644
index 000000000..eb6bb874c
--- /dev/null
+++ b/Tests/Module/GenerateExportHeader/libstatictest/CMakeLists.txt
@@ -0,0 +1,18 @@
+
+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/nodeprecated/CMakeLists.txt b/Tests/Module/GenerateExportHeader/nodeprecated/CMakeLists.txt
new file mode 100644
index 000000000..aeeb13a85
--- /dev/null
+++ b/Tests/Module/GenerateExportHeader/nodeprecated/CMakeLists.txt
@@ -0,0 +1,26 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(nodeprecated)
+
+execute_process(COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_BINARY_DIR}/nodeprecated_defined)
+execute_process(COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_BINARY_DIR}/nodeprecated_not_defined)
+
+configure_file(CMakeLists.txt.in ${CMAKE_CURRENT_BINARY_DIR}/nodeprecated_not_defined/CMakeLists.txt)
+set(DEFINE_NO_DEPRECATED DEFINE_NO_DEPRECATED)
+configure_file(CMakeLists.txt.in ${CMAKE_CURRENT_BINARY_DIR}/nodeprecated_defined/CMakeLists.txt)
+
+try_compile(Result ${CMAKE_CURRENT_BINARY_DIR}/nodeprecated_not_defined_build
+ ${CMAKE_CURRENT_BINARY_DIR}/nodeprecated_not_defined
+ nodeprecated_test
+ OUTPUT_VARIABLE Out
+)
+
+test_pass(Result "Failed to build without no-deprecated define")
+
+try_compile(Result ${CMAKE_CURRENT_BINARY_DIR}/nodeprecated_defined_build
+ ${CMAKE_CURRENT_BINARY_DIR}/nodeprecated_defined
+ nodeprecated_test
+ OUTPUT_VARIABLE Out
+)
+
+test_fail(Result "Built even with no-deprecated define") \ No newline at end of file
diff --git a/Tests/Module/GenerateExportHeader/nodeprecated/CMakeLists.txt.in b/Tests/Module/GenerateExportHeader/nodeprecated/CMakeLists.txt.in
new file mode 100644
index 000000000..d8dc482f3
--- /dev/null
+++ b/Tests/Module/GenerateExportHeader/nodeprecated/CMakeLists.txt.in
@@ -0,0 +1,15 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(nodeprecated_test)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+include(GenerateExportHeader)
+
+add_library(nodeprecatedlib SHARED someclass.cpp)
+
+generate_export_header(nodeprecatedlib @DEFINE_NO_DEPRECATED@)
+
+add_executable(nodeprecatedconsumer main.cpp)
+
+target_link_libraries(nodeprecatedconsumer nodeprecatedlib)
diff --git a/Tests/Module/GenerateExportHeader/nodeprecated/src/main.cpp b/Tests/Module/GenerateExportHeader/nodeprecated/src/main.cpp
new file mode 100644
index 000000000..eec46d3f2
--- /dev/null
+++ b/Tests/Module/GenerateExportHeader/nodeprecated/src/main.cpp
@@ -0,0 +1,9 @@
+
+#include "someclass.h"
+
+int main(int, char**)
+{
+ SomeClass sc;
+ sc.someMethod();
+ return 0;
+}
diff --git a/Tests/Module/GenerateExportHeader/nodeprecated/src/someclass.cpp b/Tests/Module/GenerateExportHeader/nodeprecated/src/someclass.cpp
new file mode 100644
index 000000000..a3f41111c
--- /dev/null
+++ b/Tests/Module/GenerateExportHeader/nodeprecated/src/someclass.cpp
@@ -0,0 +1,9 @@
+
+#include "someclass.h"
+
+#ifndef NODEPRECATEDLIB_NO_DEPRECATED
+void SomeClass::someMethod() const
+{
+
+}
+#endif
diff --git a/Tests/Module/GenerateExportHeader/nodeprecated/src/someclass.h b/Tests/Module/GenerateExportHeader/nodeprecated/src/someclass.h
new file mode 100644
index 000000000..312a177f1
--- /dev/null
+++ b/Tests/Module/GenerateExportHeader/nodeprecated/src/someclass.h
@@ -0,0 +1,10 @@
+
+#include "nodeprecatedlib_export.h"
+
+class NODEPRECATEDLIB_EXPORT SomeClass
+{
+public:
+#ifndef NODEPRECATEDLIB_NO_DEPRECATED
+ void someMethod() const;
+#endif
+};
diff --git a/Tests/Module/GenerateExportHeader/override_symbol/CMakeLists.txt b/Tests/Module/GenerateExportHeader/override_symbol/CMakeLists.txt
new file mode 100644
index 000000000..aeeef20ee
--- /dev/null
+++ b/Tests/Module/GenerateExportHeader/override_symbol/CMakeLists.txt
@@ -0,0 +1,11 @@
+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
new file mode 100644
index 000000000..eec46d3f2
--- /dev/null
+++ b/Tests/Module/GenerateExportHeader/override_symbol/main.cpp
@@ -0,0 +1,9 @@
+
+#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
new file mode 100644
index 000000000..427ec297c
--- /dev/null
+++ b/Tests/Module/GenerateExportHeader/override_symbol/someclass.cpp
@@ -0,0 +1,7 @@
+
+#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
new file mode 100644
index 000000000..ae5e84454
--- /dev/null
+++ b/Tests/Module/GenerateExportHeader/override_symbol/someclass.h
@@ -0,0 +1,8 @@
+
+#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
new file mode 100644
index 000000000..bd64df283
--- /dev/null
+++ b/Tests/Module/GenerateExportHeader/prefix/CMakeLists.txt
@@ -0,0 +1,15 @@
+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
new file mode 100644
index 000000000..507f6fd15
--- /dev/null
+++ b/Tests/Module/GenerateExportHeader/prefix/main.cpp
@@ -0,0 +1,8 @@
+
+#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
new file mode 100644
index 000000000..1fd2cb2b4
--- /dev/null
+++ b/Tests/Module/GenerateExportHeader/prefix/useprefixclass.cpp
@@ -0,0 +1,7 @@
+
+#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
new file mode 100644
index 000000000..f5e31b507
--- /dev/null
+++ b/Tests/Module/GenerateExportHeader/prefix/useprefixclass.h
@@ -0,0 +1,13 @@
+
+#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/ModuleDefinition/CMakeLists.txt b/Tests/ModuleDefinition/CMakeLists.txt
new file mode 100644
index 000000000..a30f64363
--- /dev/null
+++ b/Tests/ModuleDefinition/CMakeLists.txt
@@ -0,0 +1,31 @@
+cmake_minimum_required(VERSION 2.6)
+project(ModuleDefinition C)
+
+# Test .def file source recognition for DLLs.
+add_library(example_dll SHARED example_dll.c example_dll.def)
+
+# Test generated .def file.
+add_custom_command(OUTPUT example_dll_gen.def
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/example_dll_gen.def.in
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/example_dll_gen.def.in
+ ${CMAKE_CURRENT_BINARY_DIR}/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)$")
+ 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")
+ set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS EXAMPLE_DLL_2)
+ set(example_dll_2 example_dll_2)
+endif()
+
+# Test .def file source recognition for EXEs.
+add_executable(example_exe example_exe.c example_exe.def)
+set_property(TARGET example_exe PROPERTY ENABLE_EXPORTS 1)
+target_link_libraries(example_exe example_dll example_dll_gen ${example_dll_2})
+
+# Test linking to the executable.
+add_library(example_mod_1 MODULE example_mod_1.c)
+target_link_libraries(example_mod_1 example_exe example_dll ${example_dll_2})
diff --git a/Tests/ModuleDefinition/example_dll.c b/Tests/ModuleDefinition/example_dll.c
new file mode 100644
index 000000000..88b3904a7
--- /dev/null
+++ b/Tests/ModuleDefinition/example_dll.c
@@ -0,0 +1 @@
+int example_dll_function(void) { return 0; }
diff --git a/Tests/ModuleDefinition/example_dll.def b/Tests/ModuleDefinition/example_dll.def
new file mode 100644
index 000000000..df64fb3c1
--- /dev/null
+++ b/Tests/ModuleDefinition/example_dll.def
@@ -0,0 +1,2 @@
+EXPORTS
+example_dll_function
diff --git a/Tests/ModuleDefinition/example_dll_2.c b/Tests/ModuleDefinition/example_dll_2.c
new file mode 100644
index 000000000..9d79acdd3
--- /dev/null
+++ b/Tests/ModuleDefinition/example_dll_2.c
@@ -0,0 +1 @@
+int example_dll_2_function(void) { return 0; }
diff --git a/Tests/ModuleDefinition/example_dll_2.def b/Tests/ModuleDefinition/example_dll_2.def
new file mode 100644
index 000000000..8eba7f9cd
--- /dev/null
+++ b/Tests/ModuleDefinition/example_dll_2.def
@@ -0,0 +1,2 @@
+EXPORTS
+example_dll_2_function
diff --git a/Tests/ModuleDefinition/example_dll_gen.c b/Tests/ModuleDefinition/example_dll_gen.c
new file mode 100644
index 000000000..be5d1eed7
--- /dev/null
+++ b/Tests/ModuleDefinition/example_dll_gen.c
@@ -0,0 +1 @@
+int example_dll_gen_function(void) { return 0; }
diff --git a/Tests/ModuleDefinition/example_dll_gen.def.in b/Tests/ModuleDefinition/example_dll_gen.def.in
new file mode 100644
index 000000000..c489dbc83
--- /dev/null
+++ b/Tests/ModuleDefinition/example_dll_gen.def.in
@@ -0,0 +1,2 @@
+EXPORTS
+example_dll_gen_function
diff --git a/Tests/ModuleDefinition/example_exe.c b/Tests/ModuleDefinition/example_exe.c
new file mode 100644
index 000000000..253ae8b70
--- /dev/null
+++ b/Tests/ModuleDefinition/example_exe.c
@@ -0,0 +1,16 @@
+extern int __declspec(dllimport) example_dll_function(void);
+extern int __declspec(dllimport) example_dll_gen_function(void);
+#ifdef EXAMPLE_DLL_2
+extern int __declspec(dllimport) example_dll_2_function(void);
+#endif
+int example_exe_function(void) { return 0; }
+int main(void)
+{
+ return
+ example_dll_function() +
+ example_dll_gen_function() +
+#ifdef EXAMPLE_DLL_2
+ example_dll_2_function() +
+#endif
+ example_exe_function();
+}
diff --git a/Tests/ModuleDefinition/example_exe.def b/Tests/ModuleDefinition/example_exe.def
new file mode 100644
index 000000000..2a0df1f84
--- /dev/null
+++ b/Tests/ModuleDefinition/example_exe.def
@@ -0,0 +1,2 @@
+EXPORTS
+example_exe_function
diff --git a/Tests/ModuleDefinition/example_mod_1.c b/Tests/ModuleDefinition/example_mod_1.c
new file mode 100644
index 000000000..4e2f9ba1f
--- /dev/null
+++ b/Tests/ModuleDefinition/example_mod_1.c
@@ -0,0 +1,21 @@
+#ifdef __WATCOMC__
+# define MODULE_CCONV __cdecl
+#else
+# define MODULE_CCONV
+#endif
+
+int __declspec(dllimport) example_exe_function(void);
+int __declspec(dllimport) example_dll_function(void);
+#ifdef EXAMPLE_DLL_2
+int __declspec(dllimport) example_dll_2_function(void);
+#endif
+
+__declspec(dllexport) int MODULE_CCONV example_mod_1_function(int n)
+{
+ return
+ example_dll_function() +
+#ifdef EXAMPLE_DLL_2
+ example_dll_2_function() +
+#endif
+ example_exe_function() + n;
+}
diff --git a/Tests/MumpsCoverage/.gitattributes b/Tests/MumpsCoverage/.gitattributes
new file mode 100644
index 000000000..b6806125d
--- /dev/null
+++ b/Tests/MumpsCoverage/.gitattributes
@@ -0,0 +1,2 @@
+*.cmcov -crlf -whitespace
+*.mcov -crlf -whitespace
diff --git a/Tests/MumpsCoverage/Accounts_ReceivableTest.cmcov b/Tests/MumpsCoverage/Accounts_ReceivableTest.cmcov
new file mode 100644
index 000000000..c3b3342ab
--- /dev/null
+++ b/Tests/MumpsCoverage/Accounts_ReceivableTest.cmcov
@@ -0,0 +1,304 @@
+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
new file mode 100644
index 000000000..3c585f556
--- /dev/null
+++ b/Tests/MumpsCoverage/Accounts_ReceivableTest.mcov
@@ -0,0 +1,1445 @@
+%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/DartConfiguration.cache.tcl.in b/Tests/MumpsCoverage/DartConfiguration.cache.tcl.in
new file mode 100644
index 000000000..a1c6b17f6
--- /dev/null
+++ b/Tests/MumpsCoverage/DartConfiguration.cache.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/MumpsCoverage
+BuildDirectory: ${CMake_BINARY_DIR}/Testing/MumpsCacheCoverage
diff --git a/Tests/MumpsCoverage/DartConfiguration.tcl.in b/Tests/MumpsCoverage/DartConfiguration.tcl.in
new file mode 100644
index 000000000..2d7eaa521
--- /dev/null
+++ b/Tests/MumpsCoverage/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/MumpsCoverage
+BuildDirectory: ${CMake_BINARY_DIR}/Testing/MumpsCoverage
diff --git a/Tests/MumpsCoverage/VistA-FOIA/Packages/Toolkit/Routines/XINDEX.m b/Tests/MumpsCoverage/VistA-FOIA/Packages/Toolkit/Routines/XINDEX.m
new file mode 100644
index 000000000..b04522151
--- /dev/null
+++ b/Tests/MumpsCoverage/VistA-FOIA/Packages/Toolkit/Routines/XINDEX.m
@@ -0,0 +1,144 @@
+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/cache_coverage.cmcov.in b/Tests/MumpsCoverage/cache_coverage.cmcov.in
new file mode 100644
index 000000000..b431dbdc1
--- /dev/null
+++ b/Tests/MumpsCoverage/cache_coverage.cmcov.in
@@ -0,0 +1,2 @@
+packages:${CMake_BINARY_DIR}/Testing/MumpsCoverage/VistA-FOIA/Packages
+coverage_dir:${CMake_SOURCE_DIR}/Tests/MumpsCoverage
diff --git a/Tests/MumpsCoverage/gtm_coverage.mcov.in b/Tests/MumpsCoverage/gtm_coverage.mcov.in
new file mode 100644
index 000000000..b431dbdc1
--- /dev/null
+++ b/Tests/MumpsCoverage/gtm_coverage.mcov.in
@@ -0,0 +1,2 @@
+packages:${CMake_BINARY_DIR}/Testing/MumpsCoverage/VistA-FOIA/Packages
+coverage_dir:${CMake_SOURCE_DIR}/Tests/MumpsCoverage
diff --git a/Tests/NewlineArgs/CMakeLists.txt b/Tests/NewlineArgs/CMakeLists.txt
new file mode 100644
index 000000000..a18230488
--- /dev/null
+++ b/Tests/NewlineArgs/CMakeLists.txt
@@ -0,0 +1,16 @@
+# a simple CXX only test case
+cmake_minimum_required (VERSION 2.6)
+project (NewlineArgs CXX)
+
+add_definitions("-DTEST_FLAG_1
+-DTEST_FLAG_2")
+
+include_directories(" ${NewlineArgs_BINARY_DIR}
+ ${NewlineArgs_SOURCE_DIR} ")
+
+configure_file("${NewlineArgs_SOURCE_DIR}/libcxx2.h.in"
+ "${NewlineArgs_BINARY_DIR}/libcxx2.h")
+
+add_library(testcxx1 libcxx1.cxx)
+add_executable (NewlineArgs cxxonly.cxx)
+target_link_libraries(NewlineArgs testcxx1)
diff --git a/Tests/NewlineArgs/cxxonly.cxx b/Tests/NewlineArgs/cxxonly.cxx
new file mode 100644
index 000000000..05d55e4ef
--- /dev/null
+++ b/Tests/NewlineArgs/cxxonly.cxx
@@ -0,0 +1,19 @@
+#include "libcxx1.h"
+#include "libcxx2.h"
+
+#include <stdio.h>
+
+int main ()
+{
+ if ( LibCxx1Class::Method() != 2.0 )
+ {
+ printf("Problem with libcxx1\n");
+ return 1;
+ }
+#ifdef TEST_FLAG_3
+ return 0;
+#else
+ printf("Problem with libcxx2.h include dir probably!\n");
+ return 1;
+#endif
+}
diff --git a/Tests/NewlineArgs/libcxx1.cxx b/Tests/NewlineArgs/libcxx1.cxx
new file mode 100644
index 000000000..72f171d5c
--- /dev/null
+++ b/Tests/NewlineArgs/libcxx1.cxx
@@ -0,0 +1,10 @@
+#include "libcxx1.h"
+
+#ifdef TEST_FLAG_1
+#ifdef TEST_FLAG_2
+float LibCxx1Class::Method()
+{
+ return 2.0;
+}
+#endif
+#endif
diff --git a/Tests/NewlineArgs/libcxx1.h b/Tests/NewlineArgs/libcxx1.h
new file mode 100644
index 000000000..ea094d758
--- /dev/null
+++ b/Tests/NewlineArgs/libcxx1.h
@@ -0,0 +1,9 @@
+class LibCxx1Class
+{
+public:
+#ifdef TEST_FLAG_1
+#ifdef TEST_FLAG_2
+ static float Method();
+#endif
+#endif
+};
diff --git a/Tests/NewlineArgs/libcxx2.h.in b/Tests/NewlineArgs/libcxx2.h.in
new file mode 100644
index 000000000..bdf9cfa93
--- /dev/null
+++ b/Tests/NewlineArgs/libcxx2.h.in
@@ -0,0 +1,6 @@
+#ifdef TEST_FLAG_1
+#ifdef TEST_FLAG_2
+#define TEST_FLAG_3
+#endif
+#endif
+
diff --git a/Tests/ObjC++/CMakeLists.txt b/Tests/ObjC++/CMakeLists.txt
new file mode 100644
index 000000000..c892bd0a1
--- /dev/null
+++ b/Tests/ObjC++/CMakeLists.txt
@@ -0,0 +1,6 @@
+# a simple objc++ test case that uses Cocoa framework
+PROJECT (ObjC++)
+
+ADD_EXECUTABLE (ObjC++ objc++.mm)
+TARGET_LINK_LIBRARIES(ObjC++ "-framework Cocoa")
+
diff --git a/Tests/ObjC++/objc++.mm b/Tests/ObjC++/objc++.mm
new file mode 100644
index 000000000..f0be25682
--- /dev/null
+++ b/Tests/ObjC++/objc++.mm
@@ -0,0 +1,23 @@
+#import <Cocoa/Cocoa.h>
+#import <iostream>
+using namespace std;
+
+int main()
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+ NSMutableSet *mySet = [NSMutableSet set];
+ cout<<"Adding values to the set."<<endl;
+ [mySet addObject:[NSNumber numberWithInt:356]];
+ [mySet addObject:[NSNumber numberWithInt:550]];
+ [mySet addObject:[NSNumber numberWithInt:914]];
+
+ cout<<"The set contains "<<[mySet count]<<" objects."<<endl;
+ if ([mySet containsObject:[NSNumber numberWithInt:911]])
+ cout<<"It's there!"<<endl;
+ else
+ cout<<"It's not there."<<endl;
+
+ [pool release];
+ return 0;
+}
diff --git a/Tests/ObjectLibrary/A/CMakeLists.txt b/Tests/ObjectLibrary/A/CMakeLists.txt
new file mode 100644
index 000000000..121a8acba
--- /dev/null
+++ b/Tests/ObjectLibrary/A/CMakeLists.txt
@@ -0,0 +1,17 @@
+# 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()
+
+add_definitions(-DA_DEF)
+
+add_custom_command(
+ OUTPUT a1.c
+ DEPENDS a1.c.in
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/a1.c.in
+ ${CMAKE_CURRENT_BINARY_DIR}/a1.c
+ )
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+
+add_library(A OBJECT a1.c a2.c)
diff --git a/Tests/ObjectLibrary/A/a.h b/Tests/ObjectLibrary/A/a.h
new file mode 100644
index 000000000..7259f982e
--- /dev/null
+++ b/Tests/ObjectLibrary/A/a.h
@@ -0,0 +1,6 @@
+#ifndef A_DEF
+# error "A_DEF not defined"
+#endif
+#ifdef B_DEF
+# error "B_DEF must not be defined"
+#endif
diff --git a/Tests/ObjectLibrary/A/a1.c.in b/Tests/ObjectLibrary/A/a1.c.in
new file mode 100644
index 000000000..d1eaf58fd
--- /dev/null
+++ b/Tests/ObjectLibrary/A/a1.c.in
@@ -0,0 +1,2 @@
+#include "a.h"
+int a1(void) { return 0; }
diff --git a/Tests/ObjectLibrary/A/a2.c b/Tests/ObjectLibrary/A/a2.c
new file mode 100644
index 000000000..d8f225eb7
--- /dev/null
+++ b/Tests/ObjectLibrary/A/a2.c
@@ -0,0 +1,2 @@
+#include "a.h"
+int a2(void) { return 0; }
diff --git a/Tests/ObjectLibrary/AB.def b/Tests/ObjectLibrary/AB.def
new file mode 100644
index 000000000..3f2b5c054
--- /dev/null
+++ b/Tests/ObjectLibrary/AB.def
@@ -0,0 +1,5 @@
+EXPORTS
+a1
+a2
+b1
+b2
diff --git a/Tests/ObjectLibrary/B/CMakeLists.txt b/Tests/ObjectLibrary/B/CMakeLists.txt
new file mode 100644
index 000000000..67172d132
--- /dev/null
+++ b/Tests/ObjectLibrary/B/CMakeLists.txt
@@ -0,0 +1,15 @@
+if("${CMAKE_GENERATOR}" MATCHES "Visual Studio 6")
+ # VS 6 generator does not use per-target object locations.
+ set(vs6 _vs6)
+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()
+
+add_definitions(-DB_DEF)
+add_library(B OBJECT b1.c b2.c)
+add_library(Bexport OBJECT b1${vs6}.c b2${vs6}.c)
+set_property(TARGET Bexport PROPERTY COMPILE_DEFINITIONS Bexport)
diff --git a/Tests/ObjectLibrary/B/b.h b/Tests/ObjectLibrary/B/b.h
new file mode 100644
index 000000000..11b22f427
--- /dev/null
+++ b/Tests/ObjectLibrary/B/b.h
@@ -0,0 +1,11 @@
+#ifdef A_DEF
+# error "A_DEF must not be defined"
+#endif
+#ifndef B_DEF
+# error "B_DEF not defined"
+#endif
+#if defined(_WIN32) && defined(Bexport)
+# define EXPORT_B __declspec(dllexport)
+#else
+# define EXPORT_B
+#endif
diff --git a/Tests/ObjectLibrary/B/b1.c b/Tests/ObjectLibrary/B/b1.c
new file mode 100644
index 000000000..fdeffe491
--- /dev/null
+++ b/Tests/ObjectLibrary/B/b1.c
@@ -0,0 +1,2 @@
+#include "b.h"
+EXPORT_B int b1(void) { return 0; }
diff --git a/Tests/ObjectLibrary/B/b1_vs6.c b/Tests/ObjectLibrary/B/b1_vs6.c
new file mode 100644
index 000000000..b606e10e6
--- /dev/null
+++ b/Tests/ObjectLibrary/B/b1_vs6.c
@@ -0,0 +1 @@
+#include "b1.c"
diff --git a/Tests/ObjectLibrary/B/b2.c b/Tests/ObjectLibrary/B/b2.c
new file mode 100644
index 000000000..6e0d17cbe
--- /dev/null
+++ b/Tests/ObjectLibrary/B/b2.c
@@ -0,0 +1,2 @@
+#include "b.h"
+EXPORT_B int b2(void) { return 0; }
diff --git a/Tests/ObjectLibrary/B/b2_vs6.c b/Tests/ObjectLibrary/B/b2_vs6.c
new file mode 100644
index 000000000..d96a43e04
--- /dev/null
+++ b/Tests/ObjectLibrary/B/b2_vs6.c
@@ -0,0 +1 @@
+#include "b2.c"
diff --git a/Tests/ObjectLibrary/CMakeLists.txt b/Tests/ObjectLibrary/CMakeLists.txt
new file mode 100644
index 000000000..87234159f
--- /dev/null
+++ b/Tests/ObjectLibrary/CMakeLists.txt
@@ -0,0 +1,52 @@
+cmake_minimum_required(VERSION 2.8)
+project(ObjectLibrary C)
+
+add_subdirectory(A)
+add_subdirectory(B)
+
+add_library(Cstatic STATIC c.c $<TARGET_OBJECTS:A> $<TARGET_OBJECTS:B>)
+add_executable(UseCstatic main.c)
+target_link_libraries(UseCstatic Cstatic)
+
+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_executable(UseCinternal main.c c.c $<TARGET_OBJECTS:A> $<TARGET_OBJECTS:B>)
+
+if("${CMAKE_GENERATOR}" MATCHES "^Visual Studio (6|7|7 .NET 2003)$")
+ # VS 6 and 7 generators do not add objects as sources so we need a
+ # dummy object to convince the IDE to build the targets below.
+ set(dummy dummy.obj) # In MinGW: gcc -c dummy.c -o dummy.obj
+elseif("${CMAKE_GENERATOR}" MATCHES "Xcode")
+ # Xcode does not seem to support targets without sources.
+ set(dummy dummy.c)
+endif()
+
+# Test static library without its own sources.
+add_library(ABstatic STATIC ${dummy} $<TARGET_OBJECTS:A> $<TARGET_OBJECTS:B>)
+add_executable(UseABstatic mainAB.c)
+target_link_libraries(UseABstatic ABstatic)
+
+# Test module definition file to export object library symbols in the test
+# below if the platform needs and supports it.
+set(ABshared_SRCS $<TARGET_OBJECTS:A>)
+if(CMAKE_LINK_DEF_FILE_FLAG OR NOT WIN32)
+ list(APPEND ABshared_SRCS $<TARGET_OBJECTS:B> AB.def)
+else()
+ set(NO_A NO_A)
+ list(APPEND ABshared_SRCS $<TARGET_OBJECTS:Bexport>)
+endif()
+
+# Test shared library without its own sources.
+add_library(ABshared SHARED ${dummy} ${ABshared_SRCS})
+add_executable(UseABshared mainAB.c)
+set_property(TARGET UseABshared PROPERTY COMPILE_DEFINITIONS SHARED_B ${NO_A})
+target_link_libraries(UseABshared ABshared)
+
+# Test executable without its own sources.
+add_library(ABmain OBJECT mainAB.c)
+add_executable(UseABinternal ${dummy}
+ $<TARGET_OBJECTS:ABmain> $<TARGET_OBJECTS:A> $<TARGET_OBJECTS:B>
+ )
diff --git a/Tests/ObjectLibrary/c.c b/Tests/ObjectLibrary/c.c
new file mode 100644
index 000000000..968095b8b
--- /dev/null
+++ b/Tests/ObjectLibrary/c.c
@@ -0,0 +1,19 @@
+#if defined(_WIN32) && defined(Cshared_EXPORTS)
+# define EXPORT_C __declspec(dllexport)
+#else
+# define EXPORT_C
+#endif
+
+extern int a1(void);
+extern int a2(void);
+extern int b1(void);
+extern int b2(void);
+EXPORT_C int c(void)
+{
+ return 0
+ + a1()
+ + a2()
+ + b1()
+ + b2()
+ ;
+}
diff --git a/Tests/ObjectLibrary/dummy.c b/Tests/ObjectLibrary/dummy.c
new file mode 100644
index 000000000..2b17d816d
--- /dev/null
+++ b/Tests/ObjectLibrary/dummy.c
@@ -0,0 +1 @@
+int dummy(void) {return 0;}
diff --git a/Tests/ObjectLibrary/dummy.obj b/Tests/ObjectLibrary/dummy.obj
new file mode 100644
index 000000000..77f6f2f1b
--- /dev/null
+++ b/Tests/ObjectLibrary/dummy.obj
Binary files differ
diff --git a/Tests/ObjectLibrary/main.c b/Tests/ObjectLibrary/main.c
new file mode 100644
index 000000000..6819f1c6d
--- /dev/null
+++ b/Tests/ObjectLibrary/main.c
@@ -0,0 +1,16 @@
+#if defined(_WIN32) && defined(SHARED_C)
+# define IMPORT_C __declspec(dllimport)
+#else
+# define IMPORT_C
+#endif
+extern IMPORT_C int b1(void);
+extern IMPORT_C int b2(void);
+extern IMPORT_C int c(void);
+int main(void)
+{
+ return 0
+ + c()
+ + b1()
+ + b2()
+ ;
+}
diff --git a/Tests/ObjectLibrary/mainAB.c b/Tests/ObjectLibrary/mainAB.c
new file mode 100644
index 000000000..556898b83
--- /dev/null
+++ b/Tests/ObjectLibrary/mainAB.c
@@ -0,0 +1,22 @@
+#if defined(_WIN32) && defined(SHARED_B)
+# define IMPORT_B __declspec(dllimport)
+#else
+# define IMPORT_B
+#endif
+extern IMPORT_B int b1(void);
+extern IMPORT_B int b2(void);
+#ifndef NO_A
+extern int a1(void);
+extern int a2(void);
+#endif
+int main(void)
+{
+ return 0
+#ifndef NO_A
+ + a1()
+ + a2()
+#endif
+ + b1()
+ + b2()
+ ;
+}
diff --git a/Tests/OutDir/CMakeLists.txt b/Tests/OutDir/CMakeLists.txt
new file mode 100644
index 000000000..88468c3c0
--- /dev/null
+++ b/Tests/OutDir/CMakeLists.txt
@@ -0,0 +1,35 @@
+cmake_minimum_required(VERSION 2.8)
+project(OutDir C)
+
+if(CMAKE_CONFIGURATION_TYPES)
+ foreach(config ${CMAKE_CONFIGURATION_TYPES})
+ string(TOUPPER "${config}" CONFIG)
+ list(APPEND configs "${CONFIG}")
+ endforeach()
+ set(CMAKE_BUILD_TYPE)
+elseif(NOT CMAKE_BUILD_TYPE)
+ set(CMAKE_BUILD_TYPE Debug)
+endif()
+
+if(CMAKE_BUILD_TYPE)
+ string(TOUPPER "${CMAKE_BUILD_TYPE}" configs)
+endif()
+
+set(top "${OutDir_BINARY_DIR}")
+foreach(config ${configs})
+ foreach(type archive runtime library)
+ string(TOUPPER "${type}" TYPE)
+ set(CMAKE_${TYPE}_OUTPUT_DIRECTORY_${config} "${top}/${type}")
+ file(REMOVE_RECURSE "${top}/${type}")
+ endforeach()
+endforeach()
+
+add_subdirectory(../COnly COnly)
+
+add_custom_command(
+ OUTPUT OutDir.h
+ COMMAND ${CMAKE_COMMAND} -Dtop=${top} -P ${OutDir_SOURCE_DIR}/OutDir.cmake
+ DEPENDS COnly ${OutDir_SOURCE_DIR}/OutDir.cmake
+ )
+include_directories(${top})
+add_executable(OutDir OutDir.c OutDir.h)
diff --git a/Tests/OutDir/OutDir.c b/Tests/OutDir/OutDir.c
new file mode 100644
index 000000000..53f925926
--- /dev/null
+++ b/Tests/OutDir/OutDir.c
@@ -0,0 +1,24 @@
+#include <OutDir.h>
+#include <stdio.h>
+
+int main(void)
+{
+ const char* files[] = {TESTC1_LIB, TESTC2_LIB, CONLY_EXE, 0};
+ int result = 0;
+ const char** fname = files;
+ for(;*fname;++fname)
+ {
+ FILE* f = fopen(*fname, "rb");
+ if(f)
+ {
+ printf("found: [%s]\n", *fname);
+ fclose(f);
+ }
+ else
+ {
+ printf("error: [%s]\n", *fname);
+ result = 1;
+ }
+ }
+ return result;
+}
diff --git a/Tests/OutDir/OutDir.cmake b/Tests/OutDir/OutDir.cmake
new file mode 100644
index 000000000..e1e6b7f93
--- /dev/null
+++ b/Tests/OutDir/OutDir.cmake
@@ -0,0 +1,28 @@
+set(CMAKE_FIND_LIBRARY_PREFIXES "lib" "")
+set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib" ".a" ".so" ".sl" ".dylib" ".dll.a")
+
+find_library(TESTC1_LIB
+ NAMES testc1 testc1_test_debug_postfix
+ PATHS ${top}/archive
+ NO_DEFAULT_PATH)
+
+find_library(TESTC2_LIB
+ NAMES testc2 testc2_test_debug_postfix
+ PATHS ${top}/archive ${top}/library
+ NO_DEFAULT_PATH)
+
+find_program(CONLY_EXE
+ NAMES COnly
+ PATHS ${top}/runtime
+ NO_DEFAULT_PATH)
+
+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}\"
+
+#endif
+")
diff --git a/Tests/OutOfBinary/CMakeLists.txt b/Tests/OutOfBinary/CMakeLists.txt
new file mode 100644
index 000000000..fcf90bd0d
--- /dev/null
+++ b/Tests/OutOfBinary/CMakeLists.txt
@@ -0,0 +1,2 @@
+ADD_LIBRARY(outlib outlib.c)
+
diff --git a/Tests/OutOfBinary/outlib.c b/Tests/OutOfBinary/outlib.c
new file mode 100644
index 000000000..9ea579b7a
--- /dev/null
+++ b/Tests/OutOfBinary/outlib.c
@@ -0,0 +1,2 @@
+int outlib() { return 456; }
+
diff --git a/Tests/OutOfSource/CMakeLists.txt b/Tests/OutOfSource/CMakeLists.txt
new file mode 100644
index 000000000..e250f4177
--- /dev/null
+++ b/Tests/OutOfSource/CMakeLists.txt
@@ -0,0 +1,18 @@
+# a simple test cas
+cmake_minimum_required (VERSION 2.6)
+project (OutOfSource)
+
+add_subdirectory(SubDir)
+
+get_directory_property(ANIMAL DIRECTORY OutOfSourceSubdir DEFINITION WEASELS)
+get_directory_property(ANIMALREL DIRECTORY SubDir/../OutOfSourceSubdir DEFINITION WEASELS)
+IF(NOT "${ANIMAL}" STREQUAL "${ANIMALREL}")
+ MESSAGE(FATAL_ERROR "GET_DIRECTORY_PROPERTY does not seem to collapse paths.")
+ENDIF(NOT "${ANIMAL}" STREQUAL "${ANIMALREL}")
+
+configure_file(
+ ${OutOfSource_SOURCE_DIR}/testdp.h.in
+ ${OutOfSource_BINARY_DIR}/SubDir/OutOfSourceSubdir/testdp.h
+ )
+
+set(KEN 1)
diff --git a/Tests/OutOfSource/OutOfSourceSubdir/CMakeLists.txt b/Tests/OutOfSource/OutOfSourceSubdir/CMakeLists.txt
new file mode 100644
index 000000000..c362e79ba
--- /dev/null
+++ b/Tests/OutOfSource/OutOfSourceSubdir/CMakeLists.txt
@@ -0,0 +1,62 @@
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+
+IF ("${PROJECT_SOURCE_DIR}" STREQUAL "${ANOTHER_PROJ_SOURCE_DIR}")
+ SET(BUILD_SHARED_LIBS 1)
+
+ # Construct a source file outside the tree whose full path is close to
+ # the path length limit. This will cause the full path to the object
+ # file in the build tree to exceed the maximum path length which will
+ # test cmLocalGenerator::CreateSafeUniqueObjectFileName.
+ GET_FILENAME_COMPONENT(DEEPDIR
+ ${OutOfSource_BINARY_DIR}/../OutOfSourceDeep/deeper ABSOLUTE)
+
+ # Test giving the generator a custom limit.
+ SET(CMAKE_OBJECT_PATH_MAX 220)
+
+ # Use a separate variable for computation.
+ SET(MAXPATH "${CMAKE_OBJECT_PATH_MAX}")
+
+ # VS8 adds "OutOfSource/SubDir/OutOfSourceSubdir/../../../" to the
+ # path of the source file for no good reason. Reduce the length
+ # limit by 46 characters to account for it. It should still be long
+ # enough to require special object file name conversion.
+ IF(${CMAKE_GENERATOR} MATCHES "Visual Studio (8|10)")
+ MATH(EXPR MAXPATH "${MAXPATH} - 46")
+ ENDIF()
+
+ # Ninja imposes a maximum path component count of 30. Permit more
+ # path components in the source path.
+ IF(${CMAKE_GENERATOR} MATCHES "Ninja")
+ MATH(EXPR MAXPATH "${MAXPATH} - 44")
+ ENDIF()
+
+ # MAXPATH less 25 for last /and/deeper/simple.cxx part and small safety
+ MATH(EXPR MAXPATH "${MAXPATH} - 25")
+ STRING(LENGTH "${DEEPDIR}" DEEPDIR_LEN)
+ WHILE("${DEEPDIR_LEN}" LESS "${MAXPATH}")
+ SET(DEEPDIR ${DEEPDIR}/and/deeper)
+ STRING(LENGTH "${DEEPDIR}" DEEPDIR_LEN)
+ ENDWHILE("${DEEPDIR_LEN}" LESS "${MAXPATH}")
+ SET(DEEPSRC ${DEEPDIR}/simple.cxx)
+ STRING(LENGTH "${DEEPSRC}" DEEPSRC_LEN)
+ CONFIGURE_FILE(simple.cxx.in ${DEEPSRC} COPYONLY)
+
+ # Watcom WMake seems to have problems with long command lines. Just
+ # disable this part of the test until it is resolved.
+ IF(${CMAKE_GENERATOR} MATCHES "Watcom WMake")
+ SET(DEEPSRC "")
+ ADD_DEFINITIONS(-DNO_DEEPSRC)
+ ENDIF(${CMAKE_GENERATOR} MATCHES "Watcom WMake")
+
+ ADD_LIBRARY(testlib testlib.cxx)
+ ADD_EXECUTABLE (simple simple.cxx ../simple.cxx ${DEEPSRC})
+ TARGET_LINK_LIBRARIES(simple testlib outlib)
+ENDIF ("${PROJECT_SOURCE_DIR}" STREQUAL "${ANOTHER_PROJ_SOURCE_DIR}")
+
+# test getting a definition from a subdir
+SET (WEASELS SIZZLING)
+
+GET_DIRECTORY_PROPERTY(incDirs INCLUDE_DIRECTORIES)
+IF(NOT incDirs)
+ MESSAGE(FATAL_ERROR "GET_DIRECTORY_PROPERTY(INCLUDE_DIRECTORIES) returned empty list")
+ENDIF(NOT incDirs)
diff --git a/Tests/OutOfSource/OutOfSourceSubdir/simple.cxx b/Tests/OutOfSource/OutOfSourceSubdir/simple.cxx
new file mode 100644
index 000000000..d88c311f8
--- /dev/null
+++ b/Tests/OutOfSource/OutOfSourceSubdir/simple.cxx
@@ -0,0 +1,39 @@
+#include <stdio.h>
+#include <string.h>
+
+#include "testlib.h"
+#include "testdp.h"
+
+extern int simple();
+#ifndef NO_DEEPSRC
+extern int simple2();
+#endif
+extern "C" int outlib();
+
+int main ()
+{
+ if(simple() != 123)
+ {
+ return -3;
+ }
+ if (strcmp(animal,"SIZZLING"))
+ {
+ fprintf(stderr,"Get definitions from a subdir did not work\n");
+ return -2;
+ }
+ if(TestLib() != 1.0)
+ {
+ return -1;
+ }
+ if(outlib() != 456)
+ {
+ return -4;
+ }
+#ifndef NO_DEEPSRC
+ if(simple2() != 789)
+ {
+ return -5;
+ }
+#endif
+ return 0;
+}
diff --git a/Tests/OutOfSource/OutOfSourceSubdir/simple.cxx.in b/Tests/OutOfSource/OutOfSourceSubdir/simple.cxx.in
new file mode 100644
index 000000000..8339b7c6e
--- /dev/null
+++ b/Tests/OutOfSource/OutOfSourceSubdir/simple.cxx.in
@@ -0,0 +1 @@
+int simple2() { return 789; }
diff --git a/Tests/OutOfSource/OutOfSourceSubdir/testlib.cxx b/Tests/OutOfSource/OutOfSourceSubdir/testlib.cxx
new file mode 100644
index 000000000..1f78bd3e0
--- /dev/null
+++ b/Tests/OutOfSource/OutOfSourceSubdir/testlib.cxx
@@ -0,0 +1,6 @@
+#include "testlib.h"
+
+float TestLib()
+{
+ return 1.0;
+}
diff --git a/Tests/OutOfSource/OutOfSourceSubdir/testlib.h b/Tests/OutOfSource/OutOfSourceSubdir/testlib.h
new file mode 100644
index 000000000..289b67361
--- /dev/null
+++ b/Tests/OutOfSource/OutOfSourceSubdir/testlib.h
@@ -0,0 +1,11 @@
+#ifdef _WIN32
+# ifdef testlib_EXPORTS
+# define CM_TEST_LIB_EXPORT __declspec( dllexport )
+# else
+# define CM_TEST_LIB_EXPORT __declspec( dllimport )
+# endif
+#else
+# define CM_TEST_LIB_EXPORT
+#endif
+
+CM_TEST_LIB_EXPORT float TestLib();
diff --git a/Tests/OutOfSource/SubDir/CMakeLists.txt b/Tests/OutOfSource/SubDir/CMakeLists.txt
new file mode 100644
index 000000000..4fc48e13d
--- /dev/null
+++ b/Tests/OutOfSource/SubDir/CMakeLists.txt
@@ -0,0 +1,8 @@
+PROJECT(ANOTHER_PROJ)
+
+# subdir to an out of source and out of binary directory
+ADD_SUBDIRECTORY(${OutOfSource_SOURCE_DIR}/../OutOfBinary
+ ${OutOfSource_BINARY_DIR}/../OutOfBinary)
+
+# subdir to a sibling dir
+ADD_SUBDIRECTORY(${OutOfSource_SOURCE_DIR}/${KEN}OutOfSourceSubdir OutOfSourceSubdir )
diff --git a/Tests/OutOfSource/simple.cxx b/Tests/OutOfSource/simple.cxx
new file mode 100644
index 000000000..27e79f4ad
--- /dev/null
+++ b/Tests/OutOfSource/simple.cxx
@@ -0,0 +1 @@
+int simple() { return 123; }
diff --git a/Tests/OutOfSource/testdp.h.in b/Tests/OutOfSource/testdp.h.in
new file mode 100644
index 000000000..2ca99d523
--- /dev/null
+++ b/Tests/OutOfSource/testdp.h.in
@@ -0,0 +1 @@
+char *animal = "${ANIMAL}";
diff --git a/Tests/PerConfig/CMakeLists.txt b/Tests/PerConfig/CMakeLists.txt
new file mode 100644
index 000000000..3a473b883
--- /dev/null
+++ b/Tests/PerConfig/CMakeLists.txt
@@ -0,0 +1,34 @@
+project(PerConfig C)
+
+# Targets with per-configuration names.
+ADD_LIBRARY(pcStatic STATIC pcStatic.c)
+SET_PROPERTY(TARGET pcStatic PROPERTY RELEASE_POSTFIX -opt)
+SET_PROPERTY(TARGET pcStatic PROPERTY DEBUG_POSTFIX -dbg)
+ADD_LIBRARY(pcShared SHARED pcShared.c)
+SET_PROPERTY(TARGET pcShared PROPERTY RELEASE_POSTFIX -opt)
+SET_PROPERTY(TARGET pcShared PROPERTY DEBUG_POSTFIX -dbg)
+SET_PROPERTY(TARGET pcShared PROPERTY VERSION 1.2)
+SET_PROPERTY(TARGET pcShared PROPERTY SOVERSION 3)
+IF(UNIX AND NOT CYGWIN)
+ SET(soname_file -DpcShared_soname_file=$<TARGET_SONAME_FILE:pcShared>)
+ENDIF()
+ADD_EXECUTABLE(perconfig perconfig.c)
+TARGET_LINK_LIBRARIES(perconfig pcStatic pcShared)
+SET_PROPERTY(TARGET perconfig PROPERTY RELEASE_POSTFIX -opt)
+SET_PROPERTY(TARGET perconfig PROPERTY DEBUG_POSTFIX -dbg)
+
+SET(PerConfig_COMMAND
+ ${CMAKE_COMMAND}
+ -Dconfiguration=$<CONFIGURATION>
+ -Dperconfig_file_dir=$<TARGET_FILE_DIR:perconfig>
+ -Dperconfig_file_name=$<TARGET_FILE_NAME:perconfig>
+ -Dperconfig_file=$<TARGET_FILE:perconfig>
+ -DpcStatic_file=$<TARGET_FILE:pcStatic>
+ -DpcStatic_linker_file=$<TARGET_LINKER_FILE:pcStatic>
+ -DpcShared_file=$<TARGET_FILE:pcShared>
+ -DpcShared_linker_file=$<TARGET_LINKER_FILE:pcShared>
+ ${soname_file}
+ -P ${PerConfig_SOURCE_DIR}/perconfig.cmake
+ )
+SET(PerConfig_COMMAND "${PerConfig_COMMAND}" PARENT_SCOPE)
+SET(PerConfig_DEPENDS ${PerConfig_SOURCE_DIR}/perconfig.cmake perconfig pcStatic pcShared)
diff --git a/Tests/PerConfig/pcShared.c b/Tests/PerConfig/pcShared.c
new file mode 100644
index 000000000..b08fadc94
--- /dev/null
+++ b/Tests/PerConfig/pcShared.c
@@ -0,0 +1,5 @@
+#include "pcShared.h"
+const char* pcShared(void)
+{
+ return "INFO:symbol[pcShared]";
+}
diff --git a/Tests/PerConfig/pcShared.h b/Tests/PerConfig/pcShared.h
new file mode 100644
index 000000000..59a6ef43b
--- /dev/null
+++ b/Tests/PerConfig/pcShared.h
@@ -0,0 +1,16 @@
+#ifndef pcShared_h
+#define pcShared_h
+
+#ifdef _WIN32
+# ifdef pcShared_EXPORTS
+# define PC_EXPORT __declspec(dllexport)
+# else
+# define PC_EXPORT __declspec(dllimport)
+# endif
+#else
+# define PC_EXPORT
+#endif
+
+PC_EXPORT const char* pcShared(void);
+
+#endif
diff --git a/Tests/PerConfig/pcStatic.c b/Tests/PerConfig/pcStatic.c
new file mode 100644
index 000000000..7e1bf512d
--- /dev/null
+++ b/Tests/PerConfig/pcStatic.c
@@ -0,0 +1,4 @@
+const char* pcStatic(void)
+{
+ return "INFO:symbol[pcStatic]";
+}
diff --git a/Tests/PerConfig/perconfig.c b/Tests/PerConfig/perconfig.c
new file mode 100644
index 000000000..d942d4562
--- /dev/null
+++ b/Tests/PerConfig/perconfig.c
@@ -0,0 +1,8 @@
+#include "pcShared.h"
+extern const char* pcStatic(void);
+int main()
+{
+ pcStatic();
+ pcShared();
+ return 0;
+}
diff --git a/Tests/PerConfig/perconfig.cmake b/Tests/PerConfig/perconfig.cmake
new file mode 100644
index 000000000..6a710ca4b
--- /dev/null
+++ b/Tests/PerConfig/perconfig.cmake
@@ -0,0 +1,40 @@
+# Print values for human reference.
+foreach(v
+ configuration
+ perconfig_file_dir
+ perconfig_file_name
+ perconfig_file
+ pcStatic_file
+ pcStatic_linker_file
+ pcShared_file
+ pcShared_linker_file
+ pcShared_soname_file
+ )
+ message(STATUS "${v}=${${v}}")
+endforeach()
+
+# Verify that file names match as expected.
+set(pc_file_components ${perconfig_file_dir}/${perconfig_file_name})
+if(NOT "${pc_file_components}" STREQUAL "${perconfig_file}")
+ message(SEND_ERROR
+ "File components ${pc_file_components} do not match ${perconfig_file}")
+endif()
+if(NOT "${pcStatic_file}" STREQUAL "${pcStatic_linker_file}")
+ message(SEND_ERROR
+ "pcStatic_file does not match pcStatic_linker_file:\n"
+ " ${pcStatic_file}\n"
+ " ${pcStatic_linker_file}\n"
+ )
+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}\\].*")
+ message(SEND_ERROR "No INFO:symbol[${lib}] found in:\n ${${lib}_file}")
+ endif()
+endforeach()
+execute_process(COMMAND ${perconfig_file} RESULT_VARIABLE result)
+if(result)
+ message(SEND_ERROR "Error running:\n ${perconfig_file}\n(${result})")
+endif()
diff --git a/Tests/Plugin/CMakeLists.txt b/Tests/Plugin/CMakeLists.txt
new file mode 100644
index 000000000..31ca59c13
--- /dev/null
+++ b/Tests/Plugin/CMakeLists.txt
@@ -0,0 +1,88 @@
+cmake_minimum_required (VERSION 2.6)
+PROJECT(Plugin)
+
+# Test per-target output directory properties.
+SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${Plugin_BINARY_DIR}/bin)
+SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${Plugin_BINARY_DIR}/lib/plugin)
+SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${Plugin_BINARY_DIR}/lib/static)
+
+# We need the dynamic loader support from KWSys to load the plugin in
+# the executable.
+SET(KWSYS_NAMESPACE kwsys)
+SET(KWSYS_HEADER_ROOT ${Plugin_BINARY_DIR}/include)
+SET(KWSYS_USE_DynamicLoader 1)
+ADD_SUBDIRECTORY(${Plugin_SOURCE_DIR}/../../Source/kwsys src/kwsys)
+
+# Configure the location of plugins.
+CONFIGURE_FILE(${Plugin_SOURCE_DIR}/src/example_exe.h.in
+ ${Plugin_BINARY_DIR}/include/example_exe.h @ONLY)
+
+# We need to include headers from the source tree and configured
+# headers in the build tree.
+INCLUDE_DIRECTORIES(
+ ${Plugin_BINARY_DIR}/include
+ ${Plugin_SOURCE_DIR}/include
+ )
+
+# 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
+ ENABLE_EXPORTS 1
+ OUTPUT_NAME example
+ # Test placing exe import library in unique directory.
+ ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}/exe
+ )
+TARGET_LINK_LIBRARIES(example_exe kwsys)
+
+# Create a plugin that uses the API provided by the executable.
+# This module "links" to the executable to use the symbols.
+ADD_LIBRARY(example_mod_1 MODULE src/example_mod_1.c)
+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_
+ 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()
+ENDIF()
+
+# TODO:
+# - create a plugin that links to a static lib
+# - create a plugin that links to a shared lib
diff --git a/Tests/Plugin/check_mod_soname.cmake b/Tests/Plugin/check_mod_soname.cmake
new file mode 100644
index 000000000..3737b450d
--- /dev/null
+++ b/Tests/Plugin/check_mod_soname.cmake
@@ -0,0 +1,14 @@
+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}")
+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")
+endif()
diff --git a/Tests/Plugin/include/example.h b/Tests/Plugin/include/example.h
new file mode 100644
index 000000000..1d7e8c015
--- /dev/null
+++ b/Tests/Plugin/include/example.h
@@ -0,0 +1,25 @@
+#ifndef example_h
+#define example_h
+
+#if defined(_WIN32) || defined(__CYGWIN__)
+# if defined(example_exe_EXPORTS)
+# define EXAMPLE_EXPORT __declspec(dllexport)
+# else
+# define EXAMPLE_EXPORT __declspec(dllimport)
+# endif
+#else
+# define EXAMPLE_EXPORT
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+EXAMPLE_EXPORT int example_exe_function(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Tests/Plugin/src/example_exe.cxx b/Tests/Plugin/src/example_exe.cxx
new file mode 100644
index 000000000..d2c52052c
--- /dev/null
+++ b/Tests/Plugin/src/example_exe.cxx
@@ -0,0 +1,60 @@
+#include <example.h>
+
+#include <example_exe.h>
+
+#include <kwsys/DynamicLoader.hxx>
+#include <kwsys/ios/iostream>
+#include <kwsys/stl/string>
+
+#include <stdio.h>
+
+// Implement the ABI used by plugins.
+extern "C" int example_exe_function()
+{
+ kwsys_ios::cout << "hello" << kwsys_ios::endl;
+ return 123;
+}
+
+#ifdef CMAKE_INTDIR
+# define CONFIG_DIR "/" CMAKE_INTDIR
+#else
+# define CONFIG_DIR ""
+#endif
+
+int main()
+{
+ kwsys_stl::string libName = EXAMPLE_EXE_PLUGIN_DIR CONFIG_DIR "/";
+ libName += kwsys::DynamicLoader::LibPrefix();
+ libName += "example_mod_1";
+ libName += kwsys::DynamicLoader::LibExtension();
+ kwsys::DynamicLoader::LibraryHandle handle =
+ kwsys::DynamicLoader::OpenLibrary(libName.c_str());
+ if(!handle)
+ {
+ kwsys_ios::cerr << "Could not open plugin \""
+ << libName << "\"!" << kwsys_ios::endl;
+ return 1;
+ }
+ kwsys::DynamicLoader::SymbolPointer sym =
+ kwsys::DynamicLoader::GetSymbolAddress(handle, "example_mod_1_function");
+ if(!sym)
+ {
+ kwsys_ios::cerr
+ << "Could not get plugin symbol \"example_mod_1_function\"!"
+ << kwsys_ios::endl;
+ return 1;
+ }
+#ifdef __WATCOMC__
+ int(__cdecl *f)(int) = (int(__cdecl *)(int))(sym);
+#else
+ int(*f)(int) = reinterpret_cast<int(*)(int)>(sym);
+#endif
+ if(f(456) != (123+456))
+ {
+ kwsys_ios::cerr << "Incorrect return value from plugin!"
+ << kwsys_ios::endl;
+ return 1;
+ }
+ kwsys::DynamicLoader::CloseLibrary(handle);
+ return 0;
+}
diff --git a/Tests/Plugin/src/example_exe.h.in b/Tests/Plugin/src/example_exe.h.in
new file mode 100644
index 000000000..62f0d9f02
--- /dev/null
+++ b/Tests/Plugin/src/example_exe.h.in
@@ -0,0 +1,6 @@
+#ifndef example_exe_h
+#define example_exe_h
+
+#define EXAMPLE_EXE_PLUGIN_DIR "@CMAKE_LIBRARY_OUTPUT_DIRECTORY@"
+
+#endif
diff --git a/Tests/Plugin/src/example_mod_1.c b/Tests/Plugin/src/example_mod_1.c
new file mode 100644
index 000000000..1fc733845
--- /dev/null
+++ b/Tests/Plugin/src/example_mod_1.c
@@ -0,0 +1,22 @@
+#include <example.h>
+
+#include <stdio.h>
+
+#if defined(_WIN32)
+# define MODULE_EXPORT __declspec(dllexport)
+#else
+# define MODULE_EXPORT
+#endif
+
+#ifdef __WATCOMC__
+# define MODULE_CCONV __cdecl
+#else
+# define MODULE_CCONV
+#endif
+
+MODULE_EXPORT int MODULE_CCONV example_mod_1_function(int n)
+{
+ int result = example_exe_function() + n;
+ printf("world\n");
+ return result;
+}
diff --git a/Tests/Policy0002/A/CMakeLists.txt b/Tests/Policy0002/A/CMakeLists.txt
new file mode 100644
index 000000000..cee6422a9
--- /dev/null
+++ b/Tests/Policy0002/A/CMakeLists.txt
@@ -0,0 +1 @@
+add_executable(Policy0002 ../policy0002.c)
diff --git a/Tests/Policy0002/CMakeLists.txt b/Tests/Policy0002/CMakeLists.txt
new file mode 100644
index 000000000..0f6d3319a
--- /dev/null
+++ b/Tests/Policy0002/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 2.6)
+project(Policy0002 C)
+cmake_policy(SET CMP0002 OLD)
+add_subdirectory(A)
+add_executable(Policy0002 policy0002.c)
diff --git a/Tests/Policy0002/policy0002.c b/Tests/Policy0002/policy0002.c
new file mode 100644
index 000000000..8488f4e58
--- /dev/null
+++ b/Tests/Policy0002/policy0002.c
@@ -0,0 +1,4 @@
+int main(void)
+{
+ return 0;
+}
diff --git a/Tests/PolicyScope/Bar.cmake b/Tests/PolicyScope/Bar.cmake
new file mode 100644
index 000000000..cf1904c48
--- /dev/null
+++ b/Tests/PolicyScope/Bar.cmake
@@ -0,0 +1,8 @@
+cmake_minimum_required(VERSION 2.6.3)
+
+# Make sure a policy set differently by our includer is now correct.
+cmake_policy(GET CMP0003 cmp)
+check(CMP0003 "NEW" "${cmp}")
+
+# Test allowing the top-level file to not have cmake_minimum_required.
+cmake_policy(SET CMP0000 OLD)
diff --git a/Tests/PolicyScope/CMakeLists.txt b/Tests/PolicyScope/CMakeLists.txt
new file mode 100644
index 000000000..e6f2edc07
--- /dev/null
+++ b/Tests/PolicyScope/CMakeLists.txt
@@ -0,0 +1,104 @@
+project(PolicyScope C)
+# No cmake_minimum_required(VERSION), it's in FindFoo.
+
+#-----------------------------------------------------------------------------
+# Helper function to report results.
+function(check msg lhs rhs)
+ if(NOT "${lhs}" STREQUAL "${rhs}")
+ message(FATAL_ERROR "${msg}: expected [${lhs}], got [${rhs}]")
+ endif()
+endfunction(check)
+
+#-----------------------------------------------------------------------------
+# Test using a development framework that sets policies for us.
+
+# Policy CMP0011 should not be set at this point.
+cmake_policy(GET CMP0011 cmp)
+check(CMP0011 "" "${cmp}")
+
+# Put the test modules in the search path.
+list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR})
+
+# The included file should set policies for us.
+find_package(Foo)
+
+# Check policies set by the package.
+cmake_policy(GET CMP0003 cmp)
+check(CMP0003 "OLD" "${cmp}")
+cmake_policy(GET CMP0002 cmp)
+check(CMP0002 "NEW" "${cmp}")
+cmake_policy(GET CMP0011 cmp)
+check(CMP0011 "NEW" "${cmp}")
+
+# Make sure an included file cannot change policies.
+include(Bar)
+cmake_policy(GET CMP0003 cmp)
+check(CMP0003 "OLD" "${cmp}")
+
+# Allow the included file to change policies.
+include(Bar NO_POLICY_SCOPE)
+cmake_policy(GET CMP0003 cmp)
+check(CMP0003 "NEW" "${cmp}")
+
+#-----------------------------------------------------------------------------
+# Test function and macro policy recording.
+
+# Create the functions in an isolated scope in which we change policies.
+cmake_policy(PUSH)
+if(1)
+ # Change CMP0002
+ cmake_policy(SET CMP0002 OLD)
+ function(func1)
+ # CMP0002 should be changed when this function is invoked
+ cmake_policy(GET CMP0002 cmp)
+ check(CMP0002 "OLD" "${cmp}")
+ endfunction(func1)
+
+ # Unset CMP0002
+ cmake_policy(VERSION 2.4)
+ macro(macro1)
+ # CMP0002 should be unset when this macro is invoked
+ cmake_policy(GET CMP0002 cmp)
+ check(CMP0002 "" "${cmp}")
+
+ # Setting the policy should work here and also in the caller.
+ cmake_policy(SET CMP0002 OLD)
+ cmake_policy(GET CMP0002 cmp)
+ check(CMP0002 "OLD" "${cmp}")
+ endmacro(macro1)
+endif(1)
+cmake_policy(POP)
+
+# CMP0002 should still be NEW in this context.
+cmake_policy(GET CMP0002 cmp)
+check(CMP0002 "NEW" "${cmp}")
+
+# Check the recorded policies
+func1()
+macro1()
+
+# The macro should have changed CMP0002.
+cmake_policy(GET CMP0002 cmp)
+check(CMP0002 "OLD" "${cmp}")
+
+#-----------------------------------------------------------------------------
+# Test CMAKE_POLICY_DEFAULT_CMP<NNNN> variable.
+cmake_policy(PUSH)
+ set(CMAKE_POLICY_DEFAULT_CMP0010 OLD) # ignored
+ set(CMAKE_POLICY_DEFAULT_CMP0012 OLD) # honored
+ set(CMAKE_POLICY_DEFAULT_CMP0013 NEW) # honored
+ set(CMAKE_POLICY_DEFAULT_CMP0014 "") # noop
+ cmake_policy(VERSION 2.6.3)
+ cmake_policy(GET CMP0010 cmp)
+ check(CMP0010 "NEW" "${cmp}")
+ cmake_policy(GET CMP0012 cmp)
+ check(CMP0012 "OLD" "${cmp}")
+ cmake_policy(GET CMP0013 cmp)
+ check(CMP0013 "NEW" "${cmp}")
+ cmake_policy(GET CMP0014 cmp)
+ check(CMP0014 "" "${cmp}")
+cmake_policy(POP)
+
+#-----------------------------------------------------------------------------
+# Dummy executable so the project can build and run.
+add_executable(PolicyScope main.c)
diff --git a/Tests/PolicyScope/FindFoo.cmake b/Tests/PolicyScope/FindFoo.cmake
new file mode 100644
index 000000000..5b441e20e
--- /dev/null
+++ b/Tests/PolicyScope/FindFoo.cmake
@@ -0,0 +1,2 @@
+cmake_minimum_required(VERSION 2.6.3)
+cmake_policy(SET CMP0003 OLD)
diff --git a/Tests/PolicyScope/main.c b/Tests/PolicyScope/main.c
new file mode 100644
index 000000000..f8b643afb
--- /dev/null
+++ b/Tests/PolicyScope/main.c
@@ -0,0 +1,4 @@
+int main()
+{
+ return 0;
+}
diff --git a/Tests/PositionIndependentTargets/CMakeLists.txt b/Tests/PositionIndependentTargets/CMakeLists.txt
new file mode 100644
index 000000000..eec893d32
--- /dev/null
+++ b/Tests/PositionIndependentTargets/CMakeLists.txt
@@ -0,0 +1,13 @@
+
+cmake_minimum_required(VERSION 2.8)
+
+project(PositionIndependentTargets)
+
+include(CheckCXXSourceCompiles)
+
+include_directories("${CMAKE_CURRENT_SOURCE_DIR}") # For pic_test.h
+
+add_subdirectory(global)
+add_subdirectory(targets)
+
+add_executable(PositionIndependentTargets main.cpp)
diff --git a/Tests/PositionIndependentTargets/global/CMakeLists.txt b/Tests/PositionIndependentTargets/global/CMakeLists.txt
new file mode 100644
index 000000000..1d662f8ea
--- /dev/null
+++ b/Tests/PositionIndependentTargets/global/CMakeLists.txt
@@ -0,0 +1,37 @@
+
+set(CMAKE_POSITION_INDEPENDENT_CODE True)
+
+add_executable(test_target_executable_global
+ "${CMAKE_CURRENT_SOURCE_DIR}/../pic_main.cpp"
+)
+
+add_library(test_target_shared_library_global
+ SHARED "${CMAKE_CURRENT_SOURCE_DIR}/../pic_lib.cpp"
+)
+set_target_properties(test_target_shared_library_global
+ PROPERTIES DEFINE_SYMBOL PIC_TEST_BUILD_DLL
+)
+
+add_library(test_target_static_library_global
+ STATIC "${CMAKE_CURRENT_SOURCE_DIR}/../pic_lib.cpp"
+)
+set_target_properties(test_target_static_library_global
+ PROPERTIES COMPILE_DEFINITIONS PIC_TEST_STATIC_BUILD
+)
+
+
+file(READ
+ "${CMAKE_CURRENT_SOURCE_DIR}/../pic_test.h"
+ PIC_HEADER_CONTENT
+)
+
+check_cxx_source_compiles(
+ "
+${PIC_HEADER_CONTENT}
+int main(int,char**) { return 0; }\n"
+ PIC_TRY_COMPILE_RESULT
+)
+
+if (NOT PIC_TRY_COMPILE_RESULT)
+ message(SEND_ERROR "TRY_COMPILE with content requiring __PIC__ failed. ${OUTPUT}")
+endif()
diff --git a/Tests/PositionIndependentTargets/main.cpp b/Tests/PositionIndependentTargets/main.cpp
new file mode 100644
index 000000000..e72cef7eb
--- /dev/null
+++ b/Tests/PositionIndependentTargets/main.cpp
@@ -0,0 +1,2 @@
+
+int main(int,char**) { return 0; }
diff --git a/Tests/PositionIndependentTargets/pic_lib.cpp b/Tests/PositionIndependentTargets/pic_lib.cpp
new file mode 100644
index 000000000..b8b25a33e
--- /dev/null
+++ b/Tests/PositionIndependentTargets/pic_lib.cpp
@@ -0,0 +1,12 @@
+
+#include "pic_test.h"
+
+class PIC_TEST_EXPORT Dummy
+{
+ int dummy();
+};
+
+int Dummy::dummy()
+{
+ return 0;
+}
diff --git a/Tests/PositionIndependentTargets/pic_main.cpp b/Tests/PositionIndependentTargets/pic_main.cpp
new file mode 100644
index 000000000..6a41a7a6b
--- /dev/null
+++ b/Tests/PositionIndependentTargets/pic_main.cpp
@@ -0,0 +1,4 @@
+
+#include "pic_test.h"
+
+int main(int,char**) { return 0; }
diff --git a/Tests/PositionIndependentTargets/pic_test.h b/Tests/PositionIndependentTargets/pic_test.h
new file mode 100644
index 000000000..13cf8f79f
--- /dev/null
+++ b/Tests/PositionIndependentTargets/pic_test.h
@@ -0,0 +1,20 @@
+
+#if defined(__ELF__)
+# if !defined(__PIC__) && !defined(__PIE__)
+# error "The POSITION_INDEPENDENT_CODE property should cause __PIC__ or __PIE__ to be defined on ELF platforms."
+# endif
+#endif
+
+#if defined(PIC_TEST_STATIC_BUILD)
+# define PIC_TEST_EXPORT
+#else
+# if defined(_WIN32) || defined(WIN32) /* Win32 version */
+# ifdef PIC_TEST_BUILD_DLL
+# define PIC_TEST_EXPORT __declspec(dllexport)
+# else
+# define PIC_TEST_EXPORT __declspec(dllimport)
+# endif
+# else
+# define PIC_TEST_EXPORT
+# endif
+#endif
diff --git a/Tests/PositionIndependentTargets/targets/CMakeLists.txt b/Tests/PositionIndependentTargets/targets/CMakeLists.txt
new file mode 100644
index 000000000..4724c854a
--- /dev/null
+++ b/Tests/PositionIndependentTargets/targets/CMakeLists.txt
@@ -0,0 +1,20 @@
+
+add_executable(test_target_executable_properties "${CMAKE_CURRENT_SOURCE_DIR}/../pic_main.cpp")
+set_target_properties(test_target_executable_properties
+ PROPERTIES
+ POSITION_INDEPENDENT_CODE True
+)
+
+add_library(test_target_shared_library_properties SHARED "${CMAKE_CURRENT_SOURCE_DIR}/../pic_lib.cpp")
+set_target_properties(test_target_shared_library_properties
+ PROPERTIES
+ POSITION_INDEPENDENT_CODE True
+ DEFINE_SYMBOL PIC_TEST_BUILD_DLL
+)
+
+add_library(test_target_static_library_properties STATIC "${CMAKE_CURRENT_SOURCE_DIR}/../pic_lib.cpp")
+set_target_properties(test_target_static_library_properties
+ PROPERTIES
+ POSITION_INDEPENDENT_CODE True
+ COMPILE_DEFINITIONS PIC_TEST_STATIC_BUILD
+)
diff --git a/Tests/PreOrder/CMakeLists.txt b/Tests/PreOrder/CMakeLists.txt
new file mode 100644
index 000000000..29720e4c1
--- /dev/null
+++ b/Tests/PreOrder/CMakeLists.txt
@@ -0,0 +1,6 @@
+# a simple test case
+PROJECT (PreOrder)
+SET(CMAKE_IGNORE_DEPENDENCIES_ORDERING 1)
+ADD_SUBDIRECTORY(Library)
+ADD_EXECUTABLE (PreOrder simple.cxx)
+TARGET_LINK_LIBRARIES(PreOrder simpleLib)
diff --git a/Tests/PreOrder/Library/CMakeLists.txt b/Tests/PreOrder/Library/CMakeLists.txt
new file mode 100644
index 000000000..6c011eca9
--- /dev/null
+++ b/Tests/PreOrder/Library/CMakeLists.txt
@@ -0,0 +1,2 @@
+ADD_LIBRARY(simpleLib simpleLib.cxx )
+
diff --git a/Tests/PreOrder/Library/simpleLib.cxx b/Tests/PreOrder/Library/simpleLib.cxx
new file mode 100644
index 000000000..281d8885a
--- /dev/null
+++ b/Tests/PreOrder/Library/simpleLib.cxx
@@ -0,0 +1,3 @@
+void simpleLib()
+{
+}
diff --git a/Tests/PreOrder/simple.cxx b/Tests/PreOrder/simple.cxx
new file mode 100644
index 000000000..ef26e7984
--- /dev/null
+++ b/Tests/PreOrder/simple.cxx
@@ -0,0 +1,6 @@
+extern void simpleLib();
+int main ()
+{
+ simpleLib();
+ return 0;
+}
diff --git a/Tests/PrecompiledHeader/CMakeLists.txt b/Tests/PrecompiledHeader/CMakeLists.txt
new file mode 100644
index 000000000..3374e325f
--- /dev/null
+++ b/Tests/PrecompiledHeader/CMakeLists.txt
@@ -0,0 +1,59 @@
+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)$")
+ MESSAGE(FATAL_ERROR "The PrecompiledHeader test works only with MSVC or Intel")
+ENDIF()
+
+# Compute a custom name for the precompiled header.
+IF(CMAKE_CONFIGURATION_TYPES)
+ SET(PCH_DIR "${CMAKE_CURRENT_BINARY_DIR}/PCH/${CMAKE_CFG_INTDIR}")
+ FOREACH(cfg ${CMAKE_CONFIGURATION_TYPES})
+ FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/PCH/${cfg})
+ ENDFOREACH()
+ELSE(CMAKE_CONFIGURATION_TYPES)
+ SET(PCH_DIR "${CMAKE_CURRENT_BINARY_DIR}/PCH")
+ FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/PCH)
+ENDIF(CMAKE_CONFIGURATION_TYPES)
+
+# The VS6 IDE does not support renaming .pch files with /Fp.
+IF("${CMAKE_GENERATOR}" MATCHES "Visual Studio 6")
+ SET(PCH_USE_INCLUDE_DIR 1)
+ SET(PCH_FILE)
+ELSE("${CMAKE_GENERATOR}" MATCHES "Visual Studio 6")
+ SET(PCH_USE_INCLUDE_DIR 0)
+ SET(PCH_FILE "\"/Fp${PCH_DIR}/foo_precompiled.pch\"")
+ENDIF("${CMAKE_GENERATOR}" MATCHES "Visual Studio 6")
+
+# Choose between an explicit include path and using /I during
+# precompilation. The /I form is used to test that the PCH is
+# actually used. In practice the include path form would be used.
+IF(PCH_USE_INCLUDE_DIR)
+ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include)
+ELSE(PCH_USE_INCLUDE_DIR)
+ SET(PCH_INCLUDE_DIR "\"/I${CMAKE_CURRENT_SOURCE_DIR}/include\"")
+ENDIF(PCH_USE_INCLUDE_DIR)
+
+# Create a target that will use a precompiled header.
+SET(foo_SRCS foo1.c foo2.c)
+ADD_EXECUTABLE(foo foo_precompile.c ${foo_SRCS})
+
+# Setup flags on the target to create and use the precompiled header.
+SET_TARGET_PROPERTIES(foo PROPERTIES
+ COMPILE_FLAGS "/Yufoo_precompiled.h /FIfoo_precompiled.h ${PCH_FILE}")
+SET_SOURCE_FILES_PROPERTIES(foo_precompile.c PROPERTIES
+ COMPILE_FLAGS "/Ycfoo_precompiled.h ${PCH_INCLUDE_DIR}")
+
+# Setup dependencies for precompiled header creation and use. The VS
+# IDE takes care of this automatically.
+IF("${CMAKE_GENERATOR}" MATCHES "Makefile" OR
+ "${CMAKE_GENERATOR}" MATCHES "Ninja")
+ # This source file creates the precompiled header as a side-effect.
+ SET_SOURCE_FILES_PROPERTIES(foo_precompile.c PROPERTIES
+ OBJECT_OUTPUTS "${PCH_DIR}/foo_precompiled.pch")
+
+ # These source files use the precompiled header.
+ SET_SOURCE_FILES_PROPERTIES(${foo_SRCS} PROPERTIES
+ OBJECT_DEPENDS "${PCH_DIR}/foo_precompiled.pch")
+ENDIF("${CMAKE_GENERATOR}" MATCHES "Makefile")
diff --git a/Tests/PrecompiledHeader/foo1.c b/Tests/PrecompiledHeader/foo1.c
new file mode 100644
index 000000000..b10eba7e9
--- /dev/null
+++ b/Tests/PrecompiledHeader/foo1.c
@@ -0,0 +1,8 @@
+#ifndef foo_h
+# error "Precompiled header foo_precompiled.h has not been loaded."
+#endif
+
+int main()
+{
+ return foo();
+}
diff --git a/Tests/PrecompiledHeader/foo2.c b/Tests/PrecompiledHeader/foo2.c
new file mode 100644
index 000000000..2845cdb15
--- /dev/null
+++ b/Tests/PrecompiledHeader/foo2.c
@@ -0,0 +1,9 @@
+#ifndef foo_h
+# include "foo.h"
+# error "Precompiled header foo_precompiled.h has not been loaded."
+#endif
+
+int foo()
+{
+ return 0;
+}
diff --git a/Tests/PrecompiledHeader/foo_precompile.c b/Tests/PrecompiledHeader/foo_precompile.c
new file mode 100644
index 000000000..c37d69a1c
--- /dev/null
+++ b/Tests/PrecompiledHeader/foo_precompile.c
@@ -0,0 +1,5 @@
+/* The foo_precompiled.h header is included by a /FI option when this
+ source is used to create a precompiled header. Include it here
+ explicitly to allow dependency scanning to detect the dependency
+ whether or not the include path is known to the scanner. */
+#include "include/foo_precompiled.h"
diff --git a/Tests/PrecompiledHeader/include/foo.h b/Tests/PrecompiledHeader/include/foo.h
new file mode 100644
index 000000000..2210cb41d
--- /dev/null
+++ b/Tests/PrecompiledHeader/include/foo.h
@@ -0,0 +1,4 @@
+#ifndef foo_h
+#define foo_h
+extern int foo();
+#endif
diff --git a/Tests/PrecompiledHeader/include/foo_precompiled.h b/Tests/PrecompiledHeader/include/foo_precompiled.h
new file mode 100644
index 000000000..f4de601ff
--- /dev/null
+++ b/Tests/PrecompiledHeader/include/foo_precompiled.h
@@ -0,0 +1 @@
+#include "foo.h"
diff --git a/Tests/Preprocess/CMakeLists.txt b/Tests/Preprocess/CMakeLists.txt
new file mode 100644
index 000000000..1ed7b83ac
--- /dev/null
+++ b/Tests/Preprocess/CMakeLists.txt
@@ -0,0 +1,269 @@
+cmake_minimum_required(VERSION 2.6)
+project(Preprocess)
+
+# This test is meant both as a test and as a reference for supported
+# syntax on native tool command lines.
+
+# Determine the build tool being used. Not all characters can be
+# escaped for all build tools. This test checks all characters known
+# to work with each tool and documents those known to not work.
+if("${CMAKE_GENERATOR}" MATCHES "Xcode")
+ set(PP_XCODE 1)
+endif("${CMAKE_GENERATOR}" MATCHES "Xcode")
+if("${CMAKE_GENERATOR}" MATCHES "Visual Studio 6")
+ set(PP_VS6 1)
+endif("${CMAKE_GENERATOR}" MATCHES "Visual Studio 6")
+if("${CMAKE_GENERATOR}" MATCHES "Unix Makefiles")
+ set(PP_UMAKE 1)
+endif("${CMAKE_GENERATOR}" MATCHES "Unix Makefiles")
+if("${CMAKE_GENERATOR}" MATCHES "NMake Makefiles")
+ set(PP_NMAKE 1)
+endif("${CMAKE_GENERATOR}" MATCHES "NMake Makefiles")
+if("${CMAKE_GENERATOR}" MATCHES "MinGW Makefiles")
+ set(PP_MINGW 1)
+endif("${CMAKE_GENERATOR}" MATCHES "MinGW Makefiles")
+if("${CMAKE_GENERATOR}" MATCHES "Borland Makefiles")
+ set(PP_BORLAND 1)
+endif("${CMAKE_GENERATOR}" MATCHES "Borland Makefiles")
+if("${CMAKE_GENERATOR}" MATCHES "Watcom WMake")
+ set(PP_WATCOM 1)
+endif("${CMAKE_GENERATOR}" MATCHES "Watcom WMake")
+if("${CMAKE_GENERATOR}" MATCHES "Visual Studio 7$")
+ set(PP_VS70 1)
+endif("${CMAKE_GENERATOR}" MATCHES "Visual Studio 7$")
+if("${CMAKE_GENERATOR}" MATCHES "Visual Studio")
+ set(PP_VS 1)
+endif("${CMAKE_GENERATOR}" MATCHES "Visual Studio")
+if("${CMAKE_GENERATOR}" MATCHES "Visual Studio 10")
+ set(PP_VS100 1)
+endif("${CMAKE_GENERATOR}" MATCHES "Visual Studio 10")
+if("${CMAKE_GENERATOR}" MATCHES "Visual Studio 11")
+ set(PP_VS110 1)
+endif("${CMAKE_GENERATOR}" MATCHES "Visual Studio 11")
+
+# 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
+# check the compiler that will be used when the compiler is at fault
+# (does not work even from a command shell).
+
+#-----------------------------------------------------------------------------
+# Construct a C-string literal to test passing through a definition on
+# the command line. We configure the value into a header so it can be
+# checked in the executable at runtime. The semicolon is handled
+# specially because it needs to be escaped in the COMPILE_DEFINITIONS
+# property value to avoid separating definitions but the string value
+# must not have it escaped inside the configured header.
+set(STRING_EXTRA "")
+
+if(NOT BORLAND AND NOT PP_VS70 AND NOT PP_VS100 AND NOT PP_VS110)
+ # Borland, VS70 IDE: ;
+ # The Borland compiler will simply not accept a non-escaped semicolon
+ # on the command line. If it is escaped \; then the escape character
+ # shows up in the preprocessing output too.
+ #
+ # The VS 7.0 IDE separates definitions on semicolons and commas with
+ # no regard for quotes. Fortunately VS 7.1 and above are okay.
+ # VS 10 seems to also not like semicolons
+ set(SEMICOLON "\;")
+endif()
+
+if(NOT PP_VS6)
+ # VS 6 IDE: spaces and '"', '$', or ';'
+ # The project parser cannot handle spaces if there are quotes.
+ # Since we test passing in a quoted string, we cannot have spaces.
+ set(STRING_EXTRA "${STRING_EXTRA} ")
+
+ if(NOT PP_BORLAND AND NOT PP_WATCOM)
+ # Borland, WMake: multiple spaces
+ # The make tool seems to remove extra whitespace from inside
+ # quoted strings when passing to the compiler. It does not have
+ # trouble passing to other tools, and the compiler may be directly
+ # invoked from the command line.
+ set(STRING_EXTRA "${STRING_EXTRA} ")
+ endif(NOT PP_BORLAND AND NOT PP_WATCOM)
+endif(NOT PP_VS6)
+
+if(NOT PP_VS)
+ # VS: ,
+ # Visual Studio will not accept a comma in the value of a definition.
+ # The comma-separated list of PreprocessorDefinitions in the project
+ # file seems to be parsed before the content of entries is examined.
+ set(STRING_EXTRA "${STRING_EXTRA},")
+endif(NOT PP_VS)
+
+if(NOT PP_MINGW)
+ # MinGW: &
+ # When inside -D"FOO=\"a & b\"" MinGW make wants -D"FOO=\"a "&" b\""
+ # but it does not like quoted ampersand elsewhere.
+ set(STRING_EXTRA "${STRING_EXTRA}&")
+endif(NOT PP_MINGW)
+
+if(NOT PP_MINGW)
+ # MinGW: |
+ # When inside -D"FOO=\"a | b\"" MinGW make wants -D"FOO=\"a "|" b\""
+ # but it does not like quoted pipe elsewhere.
+ set(STRING_EXTRA "${STRING_EXTRA}|")
+endif(NOT PP_MINGW)
+
+if(NOT PP_BORLAND AND NOT PP_MINGW AND NOT PP_NMAKE)
+ # Borland, NMake, MinGW: ^
+ # When inside -D"FOO=\"a ^ b\"" the make tools want -D"FOO=\"a "^" b\""
+ # but do not like quoted carrot elsewhere. In NMake the non-quoted
+ # syntax works when the flags are not in a make variable.
+ set(STRING_EXTRA "${STRING_EXTRA}^")
+endif(NOT PP_BORLAND AND NOT PP_MINGW AND NOT PP_NMAKE)
+
+if(NOT PP_BORLAND AND NOT PP_MINGW AND NOT PP_NMAKE)
+ # Borland, MinGW: < >
+ # Angle-brackets have funny behavior that is hard to escape.
+ set(STRING_EXTRA "${STRING_EXTRA}<>")
+endif(NOT PP_BORLAND AND NOT PP_MINGW AND NOT PP_NMAKE)
+
+set(EXPR_OP1 "/")
+if((NOT MSVC OR PP_NMAKE) AND
+ NOT "${CMAKE_C_COMPILER_ID}" MATCHES "^(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
+ # not seem to accept the syntax when it is invoked from inside a
+ # make tool (nmake, mingw32-make, etc.). Instead the argument must
+ # be placed inside a response file. Then cl accepts it because it
+ # parses the response file as it would the normal windows command
+ # line. Currently only NMake supports running cl with a response
+ # file. Supporting other make tools would require CMake to generate
+ # response files explicitly for each object file.
+ #
+ # When the icl compiler is invoked from the command line then % must
+ # be written just '%'. However nmake requires '%%' except when using
+ # response files. Currently we have no way to affect escaping based
+ # on whether flags go in a response file, so we just have to skip it.
+ set(STRING_EXTRA "${STRING_EXTRA}%")
+ set(EXPR_OP1 "%")
+endif()
+
+# General: \"
+# Make tools do not reliably accept \\\" syntax:
+# - MinGW and MSYS make tools crash with \\\"
+# - Borland make actually wants a mis-matched quote \\"
+# 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)
+ set(STRING_EXTRA "${STRING_EXTRA}\\\"")
+endif(PP_NMAKE OR PP_UMAKE)
+
+# General: #
+# MSVC will not accept a # in the value of a string definition on the
+# command line. The character seems to be simply replaced by an
+# equals =. According to "cl -help" definitions may be specified by
+# -DMACRO#VALUE as well as -DMACRO=VALUE. It must be implemented by a
+# simple search-and-replace.
+#
+# The Borland compiler will parse both # and \# as just # but the make
+# tool seems to want \# sometimes and not others.
+#
+# Unix make does not like # in variable settings without extra
+# escaping. This could probably be fixed but since MSVC does not
+# support it and it is not an operator it is not worthwhile.
+
+# Compose the final test string.
+set(STRING_VALUE "hello`~!@$*)(_+-=}{][:'.?/${STRING_EXTRA}world")
+
+#-----------------------------------------------------------------------------
+# Function-style macro command-line support:
+# - Borland does not support
+# - MSVC does not support
+# - Watcom does not support
+# - GCC supports
+
+# Too few platforms support this to bother implementing.
+# People can just configure headers with the macros.
+
+#-----------------------------------------------------------------------------
+# Construct a sample expression to pass as a macro definition.
+
+set(EXPR "x*y+!(x==(y+1*2))*f(x${EXPR_OP1}2)")
+
+if(NOT WATCOM)
+ # Watcom does not support - or / because it parses them as options.
+ set(EXPR "${EXPR} + y/x-x")
+endif(NOT WATCOM)
+
+#-----------------------------------------------------------------------------
+
+# Inform the test if the debug configuration is getting built.
+# The NDEBUG definition takes care of this for release.
+set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DPREPROCESS_DEBUG")
+set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DPREPROCESS_DEBUG")
+
+# Inform the test if it built from Xcode or VS6 IDE.
+if(PP_XCODE)
+ set(PREPROCESS_XCODE 1)
+endif(PP_XCODE)
+if(PP_VS6)
+ set(PREPROCESS_VS6 1)
+ set(VS6 _vs6)
+endif(PP_VS6)
+
+# Test old-style definitions.
+add_definitions(-DOLD_DEF -DOLD_EXPR=2)
+
+# Make sure old-style definitions are converted to directory property.
+set(OLD_DEFS_EXPECTED "OLD_DEF;OLD_EXPR=2")
+get_property(OLD_DEFS DIRECTORY PROPERTY COMPILE_DEFINITIONS)
+if(NOT "${OLD_DEFS}" STREQUAL "${OLD_DEFS_EXPECTED}")
+ message(SEND_ERROR "add_definitions not converted to directory property!")
+endif(NOT "${OLD_DEFS}" STREQUAL "${OLD_DEFS_EXPECTED}")
+
+add_executable(Preprocess preprocess.c preprocess${VS6}.cxx)
+
+set(FILE_PATH "${Preprocess_SOURCE_DIR}/file_def.h")
+set(TARGET_PATH "${Preprocess_SOURCE_DIR}/target_def.h")
+
+# Set some definition properties.
+foreach(c "" "_DEBUG" "_RELEASE")
+ set_property(
+ DIRECTORY .
+ APPEND PROPERTY COMPILE_DEFINITIONS${c} "DIRECTORY_DEF${c}"
+ )
+ set_property(
+ TARGET Preprocess
+ PROPERTY COMPILE_DEFINITIONS${c} "TARGET_DEF${c}"
+ )
+ set_property(
+ SOURCE preprocess.c preprocess${VS6}.cxx
+ PROPERTY COMPILE_DEFINITIONS${c} "FILE_DEF${c}"
+ )
+endforeach(c)
+
+# Add definitions with values.
+if(NOT PREPROCESS_VS6)
+ # The path might have spaces, which VS6 does not support.
+ set(DEF_TARGET_PATH "TARGET_PATH=\"${TARGET_PATH}\"")
+ set(DEF_FILE_PATH "FILE_PATH=\"${FILE_PATH}\"")
+endif(NOT PREPROCESS_VS6)
+set_property(
+ TARGET Preprocess
+ APPEND PROPERTY COMPILE_DEFINITIONS
+ "TARGET_STRING=\"${STRING_VALUE}${SEMICOLON}\""
+ "TARGET_EXPR=${EXPR}"
+ ${DEF_TARGET_PATH}
+ )
+set_property(
+ SOURCE preprocess.c preprocess${VS6}.cxx
+ APPEND PROPERTY COMPILE_DEFINITIONS
+ "FILE_STRING=\"${STRING_VALUE}${SEMICOLON}\""
+ "FILE_EXPR=${EXPR}"
+ ${DEF_FILE_PATH}
+ )
+
+# Helper target for running test manually in build tree.
+add_custom_target(drive COMMAND Preprocess)
+
+# Configure the header file with the desired string value.
+if(SEMICOLON)
+ set(STRING_VALUE "${STRING_VALUE};")
+endif(SEMICOLON)
+configure_file(${Preprocess_SOURCE_DIR}/preprocess.h.in
+ ${Preprocess_BINARY_DIR}/preprocess.h)
+include_directories(${Preprocess_BINARY_DIR})
diff --git a/Tests/Preprocess/file_def.h b/Tests/Preprocess/file_def.h
new file mode 100644
index 000000000..fbf8986a0
--- /dev/null
+++ b/Tests/Preprocess/file_def.h
@@ -0,0 +1 @@
+#define FILE_PATH_DEF
diff --git a/Tests/Preprocess/preprocess.c b/Tests/Preprocess/preprocess.c
new file mode 100644
index 000000000..16209acf4
--- /dev/null
+++ b/Tests/Preprocess/preprocess.c
@@ -0,0 +1,198 @@
+#include <preprocess.h>
+
+#include FILE_PATH
+#include TARGET_PATH
+
+#include <string.h>
+#include <stdio.h>
+
+int check_defines_C(void)
+{
+ int result = 1;
+ if(strcmp(FILE_STRING, STRING_VALUE) != 0)
+ {
+ fprintf(stderr,
+ "FILE_STRING has wrong value in C [%s]\n", FILE_STRING);
+ result = 0;
+ }
+ if(strcmp(TARGET_STRING, STRING_VALUE) != 0)
+ {
+ fprintf(stderr,
+ "TARGET_STRING has wrong value in C [%s]\n", TARGET_STRING);
+ result = 0;
+ }
+ {
+ int x = 2;
+ int y = 3;
+ if((FILE_EXPR) != (EXPR))
+ {
+ fprintf(stderr, "FILE_EXPR did not work in C [%s]\n",
+ TO_STRING(FILE_EXPR));
+ result = 0;
+ }
+ if((TARGET_EXPR) != (EXPR))
+ {
+ fprintf(stderr, "TARGET_EXPR did not work in C [%s]\n",
+ TO_STRING(FILE_EXPR));
+ result = 0;
+ }
+ }
+#ifdef NDEBUG
+# ifdef FILE_DEF_DEBUG
+ {
+ fprintf(stderr, "FILE_DEF_DEBUG should not be defined in C\n");
+ result = 0;
+ }
+# endif
+# ifdef TARGET_DEF_DEBUG
+ {
+ fprintf(stderr, "TARGET_DEF_DEBUG should not be defined in C\n");
+ result = 0;
+ }
+# endif
+# ifdef DIRECTORY_DEF_DEBUG
+ {
+ fprintf(stderr, "DIRECTORY_DEF_DEBUG should not be defined in C\n");
+ result = 0;
+ }
+# endif
+# ifndef FILE_DEF_RELEASE
+# ifndef PREPROCESS_XCODE
+ {
+ fprintf(stderr, "FILE_DEF_RELEASE should be defined in C\n");
+ result = 0;
+ }
+# endif
+# endif
+# ifndef TARGET_DEF_RELEASE
+ {
+ fprintf(stderr, "TARGET_DEF_RELEASE should be defined in C\n");
+ result = 0;
+ }
+# endif
+# ifndef DIRECTORY_DEF_RELEASE
+ {
+ fprintf(stderr, "DIRECTORY_DEF_RELEASE should be defined in C\n");
+ result = 0;
+ }
+# endif
+#endif
+#ifdef PREPROCESS_DEBUG
+# ifndef FILE_DEF_DEBUG
+# ifndef PREPROCESS_XCODE
+ {
+ fprintf(stderr, "FILE_DEF_DEBUG should be defined in C\n");
+ result = 0;
+ }
+# endif
+# endif
+# ifndef TARGET_DEF_DEBUG
+ {
+ fprintf(stderr, "TARGET_DEF_DEBUG should be defined in C\n");
+ result = 0;
+ }
+# endif
+# ifndef DIRECTORY_DEF_DEBUG
+ {
+ fprintf(stderr, "DIRECTORY_DEF_DEBUG should be defined in C\n");
+ result = 0;
+ }
+# endif
+# ifdef FILE_DEF_RELEASE
+ {
+ fprintf(stderr, "FILE_DEF_RELEASE should not be defined in C\n");
+ result = 0;
+ }
+# endif
+# ifdef TARGET_DEF_RELEASE
+ {
+ fprintf(stderr, "TARGET_DEF_RELEASE should not be defined in C\n");
+ result = 0;
+ }
+# endif
+# ifdef DIRECTORY_DEF_RELEASE
+ {
+ fprintf(stderr, "DIRECTORY_DEF_RELEASE should not be defined in C\n");
+ result = 0;
+ }
+# endif
+#endif
+#if defined(FILE_DEF_DEBUG) || defined(TARGET_DEF_DEBUG)
+# if !defined(FILE_DEF_DEBUG) || !defined(TARGET_DEF_DEBUG)
+# ifndef PREPROCESS_XCODE
+ {
+ fprintf(stderr,
+ "FILE_DEF_DEBUG and TARGET_DEF_DEBUG inconsistent in C\n");
+ result = 0;
+ }
+# endif
+# endif
+# if defined(FILE_DEF_RELEASE) || defined(TARGET_DEF_RELEASE)
+ {
+ fprintf(stderr, "DEBUG and RELEASE definitions inconsistent in C\n");
+ result = 0;
+ }
+# endif
+#endif
+#if defined(FILE_DEF_RELEASE) || defined(TARGET_DEF_RELEASE)
+# if !defined(FILE_DEF_RELEASE) || !defined(TARGET_DEF_RELEASE)
+# ifndef PREPROCESS_XCODE
+ {
+ fprintf(stderr,
+ "FILE_DEF_RELEASE and TARGET_DEF_RELEASE inconsistent in C\n");
+ result = 0;
+ }
+# endif
+# endif
+# if defined(FILE_DEF_DEBUG) || defined(TARGET_DEF_DEBUG)
+ {
+ fprintf(stderr, "RELEASE and DEBUG definitions inconsistent in C\n");
+ result = 0;
+ }
+# endif
+#endif
+#ifndef FILE_PATH_DEF
+ {
+ fprintf(stderr, "FILE_PATH_DEF not defined in C\n");
+ result = 0;
+ }
+#endif
+#ifndef TARGET_PATH_DEF
+ {
+ fprintf(stderr, "TARGET_PATH_DEF not defined in C\n");
+ result = 0;
+ }
+#endif
+#ifndef FILE_DEF
+ {
+ fprintf(stderr, "FILE_DEF not defined in C\n");
+ result = 0;
+ }
+#endif
+#ifndef TARGET_DEF
+ {
+ fprintf(stderr, "TARGET_DEF not defined in C\n");
+ result = 0;
+ }
+#endif
+#ifndef DIRECTORY_DEF
+ {
+ fprintf(stderr, "DIRECTORY_DEF not defined in C\n");
+ result = 0;
+ }
+#endif
+#ifndef OLD_DEF
+ {
+ fprintf(stderr, "OLD_DEF not defined in C\n");
+ result = 0;
+ }
+#endif
+#if !defined(OLD_EXPR) || OLD_EXPR != 2
+ {
+ fprintf(stderr, "OLD_EXPR id not work in C [%s]\n",
+ TO_STRING(OLD_EXPR));
+ result = 0;
+ }
+#endif
+ return result;
+}
diff --git a/Tests/Preprocess/preprocess.cxx b/Tests/Preprocess/preprocess.cxx
new file mode 100644
index 000000000..27b6ac89a
--- /dev/null
+++ b/Tests/Preprocess/preprocess.cxx
@@ -0,0 +1,225 @@
+#include <preprocess.h>
+
+#include FILE_PATH
+#include TARGET_PATH
+
+#include <string.h>
+#include <stdio.h>
+
+extern "C" int check_defines_C(void);
+
+int check_defines_CXX()
+{
+ int result = 1;
+ if(strcmp(FILE_STRING, STRING_VALUE) != 0)
+ {
+ fprintf(stderr,
+ "FILE_STRING has wrong value in CXX [%s]\n", FILE_STRING);
+ result = 0;
+ }
+ if(strcmp(TARGET_STRING, STRING_VALUE) != 0)
+ {
+ fprintf(stderr,
+ "TARGET_STRING has wrong value in CXX [%s]\n", TARGET_STRING);
+ result = 0;
+ }
+ {
+ int x = 2;
+ int y = 3;
+ if((FILE_EXPR) != (EXPR))
+ {
+ fprintf(stderr, "FILE_EXPR did not work in CXX [%s]\n",
+ TO_STRING(FILE_EXPR));
+ result = 0;
+ }
+ if((TARGET_EXPR) != (EXPR))
+ {
+ fprintf(stderr, "TARGET_EXPR did not work in CXX [%s]\n",
+ TO_STRING(FILE_EXPR));
+ result = 0;
+ }
+ }
+#ifdef NDEBUG
+# ifdef FILE_DEF_DEBUG
+ {
+ fprintf(stderr, "FILE_DEF_DEBUG should not be defined in CXX\n");
+ result = 0;
+ }
+# endif
+# ifdef TARGET_DEF_DEBUG
+ {
+ fprintf(stderr, "TARGET_DEF_DEBUG should not be defined in CXX\n");
+ result = 0;
+ }
+# endif
+# ifdef DIRECTORY_DEF_DEBUG
+ {
+ fprintf(stderr, "DIRECTORY_DEF_DEBUG should not be defined in CXX\n");
+ result = 0;
+ }
+# endif
+# ifndef FILE_DEF_RELEASE
+# ifndef PREPROCESS_XCODE
+ {
+ fprintf(stderr, "FILE_DEF_RELEASE should be defined in CXX\n");
+ result = 0;
+ }
+# endif
+# endif
+# ifndef TARGET_DEF_RELEASE
+ {
+ fprintf(stderr, "TARGET_DEF_RELEASE should be defined in CXX\n");
+ result = 0;
+ }
+# endif
+# ifndef DIRECTORY_DEF_RELEASE
+ {
+ fprintf(stderr, "DIRECTORY_DEF_RELEASE should be defined in CXX\n");
+ result = 0;
+ }
+# endif
+#endif
+#ifdef PREPROCESS_DEBUG
+# ifndef FILE_DEF_DEBUG
+# ifndef PREPROCESS_XCODE
+ {
+ fprintf(stderr, "FILE_DEF_DEBUG should be defined in CXX\n");
+ result = 0;
+ }
+# endif
+# endif
+# ifndef TARGET_DEF_DEBUG
+ {
+ fprintf(stderr, "TARGET_DEF_DEBUG should be defined in CXX\n");
+ result = 0;
+ }
+# endif
+# ifndef DIRECTORY_DEF_DEBUG
+ {
+ fprintf(stderr, "DIRECTORY_DEF_DEBUG should be defined in CXX\n");
+ result = 0;
+ }
+# endif
+# ifdef FILE_DEF_RELEASE
+ {
+ fprintf(stderr, "FILE_DEF_RELEASE should not be defined in CXX\n");
+ result = 0;
+ }
+# endif
+# ifdef TARGET_DEF_RELEASE
+ {
+ fprintf(stderr, "TARGET_DEF_RELEASE should not be defined in CXX\n");
+ result = 0;
+ }
+# endif
+# ifdef DIRECTORY_DEF_RELEASE
+ {
+ fprintf(stderr, "DIRECTORY_DEF_RELEASE should not be defined in CXX\n");
+ result = 0;
+ }
+# endif
+#endif
+#if defined(FILE_DEF_DEBUG) || defined(TARGET_DEF_DEBUG)
+# if !defined(FILE_DEF_DEBUG) || !defined(TARGET_DEF_DEBUG)
+# ifndef PREPROCESS_XCODE
+ {
+ fprintf(stderr,
+ "FILE_DEF_DEBUG and TARGET_DEF_DEBUG inconsistent in CXX\n");
+ result = 0;
+ }
+# endif
+# endif
+# if defined(FILE_DEF_RELEASE) || defined(TARGET_DEF_RELEASE)
+ {
+ fprintf(stderr, "DEBUG and RELEASE definitions inconsistent in CXX\n");
+ result = 0;
+ }
+# endif
+#endif
+#if defined(FILE_DEF_RELEASE) || defined(TARGET_DEF_RELEASE)
+# if !defined(FILE_DEF_RELEASE) || !defined(TARGET_DEF_RELEASE)
+# ifndef PREPROCESS_XCODE
+ {
+ fprintf(stderr,
+ "FILE_DEF_RELEASE and TARGET_DEF_RELEASE inconsistent in CXX\n");
+ result = 0;
+ }
+# endif
+# endif
+# if defined(FILE_DEF_DEBUG) || defined(TARGET_DEF_DEBUG)
+ {
+ fprintf(stderr, "RELEASE and DEBUG definitions inconsistent in CXX\n");
+ result = 0;
+ }
+# endif
+#endif
+#ifndef FILE_PATH_DEF
+ {
+ fprintf(stderr, "FILE_PATH_DEF not defined in CXX\n");
+ result = 0;
+ }
+#endif
+#ifndef TARGET_PATH_DEF
+ {
+ fprintf(stderr, "TARGET_PATH_DEF not defined in CXX\n");
+ result = 0;
+ }
+#endif
+#ifndef FILE_DEF
+ {
+ fprintf(stderr, "FILE_DEF not defined in CXX\n");
+ result = 0;
+ }
+#endif
+#ifndef TARGET_DEF
+ {
+ fprintf(stderr, "TARGET_DEF not defined in CXX\n");
+ result = 0;
+ }
+#endif
+#ifndef DIRECTORY_DEF
+ {
+ fprintf(stderr, "DIRECTORY_DEF not defined in CXX\n");
+ result = 0;
+ }
+#endif
+#ifndef OLD_DEF
+ {
+ fprintf(stderr, "OLD_DEF not defined in CXX\n");
+ result = 0;
+ }
+#endif
+#if !defined(OLD_EXPR) || OLD_EXPR != 2
+ {
+ fprintf(stderr, "OLD_EXPR id not work in C [%s]\n",
+ TO_STRING(OLD_EXPR));
+ result = 0;
+ }
+#endif
+ return result;
+}
+
+int main()
+{
+ int result = 1;
+
+ if(!check_defines_C())
+ {
+ result = 0;
+ }
+
+ if(!check_defines_CXX())
+ {
+ result = 0;
+ }
+
+ if(result)
+ {
+ printf("All preprocessor definitions are correct.\n");
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
+}
diff --git a/Tests/Preprocess/preprocess.h.in b/Tests/Preprocess/preprocess.h.in
new file mode 100644
index 000000000..3e1c7a07a
--- /dev/null
+++ b/Tests/Preprocess/preprocess.h.in
@@ -0,0 +1,16 @@
+/* Define configured macros. */
+#define STRING_VALUE "@STRING_VALUE@"
+#define EXPR @EXPR@
+#cmakedefine PREPROCESS_XCODE
+#cmakedefine PREPROCESS_VS6
+
+#ifdef PREPROCESS_VS6
+# define FILE_PATH "@FILE_PATH@"
+# define TARGET_PATH "@TARGET_PATH@"
+#endif
+
+/* Declarations and macros shared by all sources. */
+#define TO_STRING(x) TO_STRING0(x)
+#define TO_STRING0(x) #x
+
+static int f(int i) { return i*3; }
diff --git a/Tests/Preprocess/preprocess_vs6.cxx b/Tests/Preprocess/preprocess_vs6.cxx
new file mode 100644
index 000000000..9df89f6a0
--- /dev/null
+++ b/Tests/Preprocess/preprocess_vs6.cxx
@@ -0,0 +1,3 @@
+// The VS6 IDE does not support object name configuration so we need a
+// source file with a different name. Include the real source file.
+#include "preprocess.cxx"
diff --git a/Tests/Preprocess/target_def.h b/Tests/Preprocess/target_def.h
new file mode 100644
index 000000000..f016d5cd2
--- /dev/null
+++ b/Tests/Preprocess/target_def.h
@@ -0,0 +1 @@
+#define TARGET_PATH_DEF
diff --git a/Tests/Properties/CMakeLists.txt b/Tests/Properties/CMakeLists.txt
new file mode 100644
index 000000000..c1bc3b9e3
--- /dev/null
+++ b/Tests/Properties/CMakeLists.txt
@@ -0,0 +1,147 @@
+# a simple CXX only test case
+cmake_minimum_required (VERSION 2.6)
+project (Properties)
+
+# these first three tests really test both properties and the management of
+# cmSourceFile objects by CMake.
+
+# test properties on a build tree file that is relative (yuck)
+configure_file(properties.h.in "${Properties_BINARY_DIR}/properties.h")
+set_source_files_properties(properties.h PROPERTIES TEST1 1)
+get_source_file_property(RESULT1 properties.h TEST1)
+
+# test properties on a headerfile in the source tree
+# accessed without an extenion (also yuck)
+set_source_files_properties(properties2 PROPERTIES TEST2 1)
+get_source_file_property(RESULT2 properties2 TEST2)
+
+# test properties on a relative source that is not generated
+set_source_files_properties(SubDir/properties3.cxx PROPERTIES TEST3 1)
+get_source_file_property(RESULT3 SubDir/properties3.cxx TEST3)
+
+include_directories("${Properties_SOURCE_DIR}" "${Properties_BINARY_DIR}")
+
+
+# test generic property interfaces
+get_property(GLOBALRESULT GLOBAL PROPERTY GLOBALTEST DEFINED)
+if (GLOBALRESULT)
+ message(SEND_ERROR "Error: global prop defined when it should not be, "
+ "result is GLOBALRESULT=${GLOBALRESULT}")
+endif (GLOBALRESULT)
+
+define_property(GLOBAL PROPERTY GLOBALTEST
+ BRIEF_DOCS "A test property"
+ FULL_DOCS "A long description of this test property"
+ )
+
+get_property(GLOBALRESULT GLOBAL PROPERTY GLOBALTEST DEFINED)
+if (NOT GLOBALRESULT)
+ message(SEND_ERROR "Error: global prop not defined "
+ "result is GLOBALRESULT=${GLOBALRESULT}")
+endif (NOT GLOBALRESULT)
+
+set_property(GLOBAL PROPERTY GLOBALTEST 1)
+set_property(DIRECTORY PROPERTY DIRECTORYTEST 1)
+set_property(SOURCE SubDir/properties3.cxx PROPERTY SOURCETEST 1)
+get_property(GLOBALRESULT GLOBAL PROPERTY GLOBALTEST)
+get_property(DIRECTORYRESULT DIRECTORY PROPERTY DIRECTORYTEST)
+get_property(SOURCERESULT
+ SOURCE SubDir/properties3.cxx
+ PROPERTY SOURCETEST
+ )
+
+if (RESULT1 AND RESULT2 AND RESULT3 AND GLOBALRESULT AND
+ DIRECTORYRESULT AND SOURCERESULT)
+ add_executable (Properties SubDir/properties3.cxx properties)
+else (RESULT1 AND RESULT2 AND RESULT3 AND GLOBALRESULT AND
+ DIRECTORYRESULT AND SOURCERESULT)
+ message(SEND_ERROR
+ "Error: test results are RESULT1=${RESULT1} RESULT2=${RESULT2} "
+ "RESULT3=${RESULT3} GLOBALRESULT=${GLOBALRESULT} "
+ "DIRECTORYRESULT=${DIRECTORYRESULT} "
+ "SOURCERESULT=${SOURCERESULT}")
+endif (RESULT1 AND RESULT2 AND RESULT3 AND GLOBALRESULT AND
+ DIRECTORYRESULT AND SOURCERESULT)
+
+# test the target property
+set_property(TARGET Properties PROPERTY TARGETTEST 1)
+get_property(TARGETRESULT TARGET Properties PROPERTY TARGETTEST)
+if (NOT TARGETRESULT)
+ message(SEND_ERROR
+ "Error: target result is TARGETRESULT=${TARGETRESULT}")
+endif (NOT TARGETRESULT)
+
+# test APPEND and APPEND_STRING set_property()
+set_property(TARGET Properties PROPERTY FOO foo)
+set_property(TARGET Properties PROPERTY BAR bar)
+set_property(TARGET Properties APPEND PROPERTY FOO 123)
+set_property(TARGET Properties APPEND_STRING PROPERTY BAR 456)
+
+get_property(APPEND_RESULT TARGET Properties PROPERTY FOO)
+if (NOT "${APPEND_RESULT}" STREQUAL "foo;123")
+ message(SEND_ERROR
+ "Error: target result is APPEND_RESULT=${APPEND_RESULT}")
+endif ()
+
+get_property(APPEND_STRING_RESULT TARGET Properties PROPERTY BAR)
+if (NOT "${APPEND_STRING_RESULT}" STREQUAL "bar456")
+ message(SEND_ERROR
+ "Error: target result is APPEND_STRING_RESULT=${APPEND_STRING_RESULT}")
+endif ()
+
+# test get_property SET
+get_property(TARGETRESULT TARGET Properties PROPERTY TARGETTEST SET)
+if (NOT TARGETRESULT)
+ message(SEND_ERROR
+ "Error: target prop not set, result is TARGETRESULT=${TARGETRESULT}")
+endif (NOT TARGETRESULT)
+
+# test unsetting a property
+set_property(TARGET Properties PROPERTY TARGETTEST)
+get_property(TARGETRESULT TARGET Properties PROPERTY TARGETTEST SET)
+if (TARGETRESULT)
+ message(SEND_ERROR "Error: target prop not unset, "
+ "result is TARGETRESULT=${TARGETRESULT}")
+endif (TARGETRESULT)
+
+
+
+# test the target SOURCES property
+get_property(Properties_SOURCES TARGET Properties PROPERTY SOURCES)
+set_source_files_properties(${Properties_SOURCES} PROPERTIES TEST4 1)
+get_source_file_property(RESULT4 properties.h TEST4)
+if(NOT RESULT4)
+ message(SEND_ERROR "Error: target result is"
+ " RESULT4=${RESULT4}"
+ " Properties_SOURCES=[${Properties_SOURCES}]")
+endif(NOT RESULT4)
+
+# test CACHE properties
+macro(check_cache_props)
+ foreach(prop VALUE TYPE HELPSTRING ADVANCED STRINGS)
+ get_property(result CACHE SOME_ENTRY PROPERTY ${prop})
+ if(NOT "x${result}" STREQUAL "x${expect_${prop}}")
+ message(SEND_ERROR "CACHE property ${prop} is [${result}], not [${expect_${prop}}]")
+ endif()
+ endforeach(prop)
+endmacro(check_cache_props)
+set(expect_VALUE "ON")
+set(expect_TYPE "BOOL")
+set(expect_HELPSTRING "sample cache entry")
+set(expect_ADVANCED 0)
+set(expect_STRINGS "")
+set(SOME_ENTRY "${expect_VALUE}" CACHE ${expect_TYPE} "${expect_HELPSTRING}" FORCE)
+mark_as_advanced(CLEAR SOME_ENTRY)
+set_property(CACHE SOME_ENTRY PROPERTY STRINGS "")
+check_cache_props()
+set(expect_VALUE "Some string")
+set(expect_TYPE "STRING")
+set(expect_HELPSTRING "sample cache entry help")
+set(expect_ADVANCED 1)
+set(expect_STRINGS "Some string;Some other string;Some third string")
+set_property(CACHE SOME_ENTRY PROPERTY TYPE "${expect_TYPE}")
+set_property(CACHE SOME_ENTRY PROPERTY HELPSTRING "${expect_HELPSTRING}")
+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()
diff --git a/Tests/Properties/SubDir/properties3.cxx b/Tests/Properties/SubDir/properties3.cxx
new file mode 100644
index 000000000..1a27a04d4
--- /dev/null
+++ b/Tests/Properties/SubDir/properties3.cxx
@@ -0,0 +1,9 @@
+#include "properties.h"
+#include "properties2.h"
+
+#if defined HAVE_PROPERTIES_H && defined HAVE_PROPERTIES2_H
+int main ()
+{
+ return 0;
+}
+#endif
diff --git a/Tests/Properties/properties.h.in b/Tests/Properties/properties.h.in
new file mode 100644
index 000000000..5e9283168
--- /dev/null
+++ b/Tests/Properties/properties.h.in
@@ -0,0 +1 @@
+#define HAVE_PROPERTIES_H
diff --git a/Tests/Properties/properties2.h b/Tests/Properties/properties2.h
new file mode 100644
index 000000000..898fd9e6a
--- /dev/null
+++ b/Tests/Properties/properties2.h
@@ -0,0 +1 @@
+#define HAVE_PROPERTIES2_H
diff --git a/Tests/Qt4Deploy/CMakeLists.txt b/Tests/Qt4Deploy/CMakeLists.txt
new file mode 100644
index 000000000..646ea9f3b
--- /dev/null
+++ b/Tests/Qt4Deploy/CMakeLists.txt
@@ -0,0 +1,70 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(Qt4Deploy)
+set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/install)
+
+find_package(Qt4 REQUIRED QtMain QtCore QtSql)
+include(${QT_USE_FILE})
+
+add_executable(testdeploy MACOSX_BUNDLE testdeploy.cpp)
+target_link_libraries(testdeploy ${QT_LIBRARIES})
+set_target_properties(testdeploy PROPERTIES INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}")
+
+if(CMAKE_CONFIGURATION_TYPES AND QT_QTCORE_LIBRARY_RELEASE AND QT_QTCORE_LIBRARY_DEBUG)
+ # note: installing debug Qt libraries from a Qt installation configured with
+ # -debug-and-release not yet supported (very low priority).
+ install(CODE "
+ if(\"\${CMAKE_INSTALL_CONFIG_NAME}\" MATCHES \"^([Dd][Ee][Bb][Uu][Gg])$\")
+ return()
+ endif()
+ ")
+endif()
+
+# install the Qt4 app with qsqlite plugin
+install(CODE "file(REMOVE_RECURSE \"${CMAKE_INSTALL_PREFIX}\")")
+install(TARGETS testdeploy DESTINATION .)
+include(../../Modules/DeployQt4.cmake)
+if(APPLE)
+ install_qt4_executable(testdeploy.app "qsqlite")
+elseif(WIN32)
+ install_qt4_executable(testdeploy.exe "qsqlite")
+else()
+ install_qt4_executable(testdeploy "qsqlite")
+endif()
+
+
+# test depends on standard qsqlite plugin
+if(QT_QSQLITE_PLUGIN_DEBUG OR QT_QSQLITE_PLUGIN_RELEASE)
+
+ # test the deployed Qt application
+ if(APPLE)
+ install(CODE "
+ message(STATUS \"executing: ${CMAKE_INSTALL_PREFIX}/testdeploy.app/Contents/MacOS/testdeploy\")
+ execute_process(COMMAND \"${CMAKE_INSTALL_PREFIX}/testdeploy.app/Contents/MacOS/testdeploy\"
+ RESULT_VARIABLE result)
+ if(NOT result STREQUAL \"0\")
+ message(FATAL_ERROR \"error running testdeploy app\")
+ endif()
+ ")
+ else()
+ install(CODE "
+ message(STATUS \"executing: ${CMAKE_INSTALL_PREFIX}/testdeploy\")
+ execute_process(COMMAND \"${CMAKE_INSTALL_PREFIX}/testdeploy\"
+ RESULT_VARIABLE result)
+ if(NOT result STREQUAL \"0\")
+ message(FATAL_ERROR \"error running testdeploy app\")
+ endif()
+ ")
+ endif()
+
+ # custom target to install and test the installation at build time
+ if(CMAKE_CONFIGURATION_TYPES)
+ set(install_config "-DCMAKE_INSTALL_CONFIG_NAME=${CMAKE_CFG_INTDIR}")
+ endif()
+
+ add_custom_target(testdeploy_test ALL
+ COMMAND ${CMAKE_COMMAND} ${install_config} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_install.cmake
+ COMMENT "${CMAKE_COMMAND} ${install_config} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_install.cmake"
+ DEPENDS testdeploy)
+
+endif()
diff --git a/Tests/Qt4Deploy/testdeploy.cpp b/Tests/Qt4Deploy/testdeploy.cpp
new file mode 100644
index 000000000..8b9c8d6fa
--- /dev/null
+++ b/Tests/Qt4Deploy/testdeploy.cpp
@@ -0,0 +1,29 @@
+#include <QCoreApplication>
+#include <QSqlDatabase>
+#include <QLibraryInfo>
+#include <QDebug>
+#include <QStringList>
+
+int main(int argc, char** argv)
+{
+ QCoreApplication app(argc, argv);
+
+ qDebug() << "App path:" << app.applicationDirPath();
+ qDebug() << "Plugin path:" << QLibraryInfo::location(QLibraryInfo::PluginsPath);
+
+ bool foundSqlite = false;
+
+ qDebug() << "Supported Database Drivers:";
+ foreach(const QString &sqlDriver, QSqlDatabase::drivers())
+ {
+ qDebug() << " " << sqlDriver;
+ if(sqlDriver == "QSQLITE")
+ foundSqlite = true;
+ }
+
+ if(foundSqlite)
+ qDebug() << "Found sqlite support from plugin.";
+ else
+ qDebug() << "Could not find sqlite support from plugin.";
+ return foundSqlite ? 0 : 1;
+}
diff --git a/Tests/QtAutomoc/CMakeLists.txt b/Tests/QtAutomoc/CMakeLists.txt
new file mode 100644
index 000000000..5e3686dbc
--- /dev/null
+++ b/Tests/QtAutomoc/CMakeLists.txt
@@ -0,0 +1,23 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(QtAutomoc)
+
+find_package(Qt4 REQUIRED)
+
+include(UseQt4)
+
+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 a library target, both requiring automoc:
+add_library(codeeditorLib STATIC codeeditor.cpp)
+
+add_executable(foo main.cpp calwidget.cpp foo.cpp blub.cpp bar.cpp abc.cpp xyz.cpp yaf.cpp private_slot.cpp)
+
+set_target_properties(foo codeeditorLib PROPERTIES AUTOMOC TRUE)
+
+target_link_libraries(foo codeeditorLib ${QT_LIBRARIES} )
diff --git a/Tests/QtAutomoc/abc.cpp b/Tests/QtAutomoc/abc.cpp
new file mode 100644
index 000000000..4bbc76905
--- /dev/null
+++ b/Tests/QtAutomoc/abc.cpp
@@ -0,0 +1,49 @@
+/*============================================================================
+ 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 "abc.h"
+#include "abc_p.h"
+
+#include <stdio.h>
+
+class PrintAbc : public QObject
+{
+ Q_OBJECT
+ public:
+ PrintAbc():QObject() {}
+ public slots:
+ void print() const { printf("abc\n"); }
+};
+
+Abc::Abc()
+:QObject()
+{
+}
+
+
+void Abc::doAbc()
+{
+ PrintAbc pa;
+ pa.print();
+ AbcP abcP;
+ abcP.doAbcP();
+}
+
+// check that including the moc file for the cpp file and the header works:
+#include "abc.moc"
+#include "moc_abc.cpp"
+#include "moc_abc_p.cpp"
+
+// check that including a moc file from another header works:
+#include "moc_xyz.cpp"
diff --git a/Tests/QtAutomoc/abc.h b/Tests/QtAutomoc/abc.h
new file mode 100644
index 000000000..d1924b0da
--- /dev/null
+++ b/Tests/QtAutomoc/abc.h
@@ -0,0 +1,28 @@
+/*============================================================================
+ 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 ABC_H
+#define ABC_H
+
+#include <QObject>
+
+class Abc : public QObject
+{
+ Q_OBJECT
+ public:
+ Abc();
+ public slots:
+ void doAbc();
+};
+
+#endif
diff --git a/Tests/QtAutomoc/abc_p.h b/Tests/QtAutomoc/abc_p.h
new file mode 100644
index 000000000..952fff315
--- /dev/null
+++ b/Tests/QtAutomoc/abc_p.h
@@ -0,0 +1,30 @@
+/*============================================================================
+ 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 ABC_P_H
+#define ABC_P_H
+
+#include <QObject>
+
+#include <stdio.h>
+
+class AbcP : public QObject
+{
+ Q_OBJECT
+ public:
+ AbcP() {}
+ public slots:
+ void doAbcP() { printf("I am private abc !\n"); }
+};
+
+#endif
diff --git a/Tests/QtAutomoc/bar.cpp b/Tests/QtAutomoc/bar.cpp
new file mode 100644
index 000000000..8be48159d
--- /dev/null
+++ b/Tests/QtAutomoc/bar.cpp
@@ -0,0 +1,28 @@
+/*============================================================================
+ 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 "sub/bar.h"
+
+#include <stdio.h>
+
+Bar::Bar()
+:QObject()
+{
+}
+
+void Bar::doBar()
+{
+ printf("Hello bar !\n");
+}
+
+#include "sub/moc_bar.cpp"
diff --git a/Tests/QtAutomoc/blub.cpp b/Tests/QtAutomoc/blub.cpp
new file mode 100644
index 000000000..bd53972ac
--- /dev/null
+++ b/Tests/QtAutomoc/blub.cpp
@@ -0,0 +1,40 @@
+/*============================================================================
+ 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 "blub.h"
+
+#include <stdio.h>
+
+class BlubBlub : public QObject
+{
+ Q_OBJECT
+ public:
+ BlubBlub():QObject() {}
+ public slots:
+ int getValue() const { return 13; }
+};
+
+Blub::Blub()
+{
+}
+
+
+void Blub::blubber()
+{
+ BlubBlub bb;
+ printf("Blub blub %d ! \n", bb.getValue());
+}
+
+// test the case that the wrong moc-file is included, it should
+// actually be "blub.moc"
+#include "moc_blub.cpp"
diff --git a/Tests/QtAutomoc/blub.h b/Tests/QtAutomoc/blub.h
new file mode 100644
index 000000000..1967bc1ea
--- /dev/null
+++ b/Tests/QtAutomoc/blub.h
@@ -0,0 +1,26 @@
+/*============================================================================
+ 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 BLUB_H
+#define BLUB_H
+
+#include <QObject>
+
+class Blub
+{
+ public:
+ Blub();
+ void blubber();
+};
+
+#endif
diff --git a/Tests/QtAutomoc/calwidget.cpp b/Tests/QtAutomoc/calwidget.cpp
new file mode 100644
index 000000000..24f3b4efe
--- /dev/null
+++ b/Tests/QtAutomoc/calwidget.cpp
@@ -0,0 +1,424 @@
+/****************************************************************************
+ **
+ ** 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 <QtGui>
+
+ #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"), Qt::red);
+ comboBox->addItem(tr("Blue"), Qt::blue);
+ comboBox->addItem(tr("Black"), Qt::black);
+ comboBox->addItem(tr("Magenta"), Qt::magenta);
+ return comboBox;
+ }
+
+//#include "moc_calwidget.cpp"
diff --git a/Tests/QtAutomoc/calwidget.h b/Tests/QtAutomoc/calwidget.h
new file mode 100644
index 000000000..844738937
--- /dev/null
+++ b/Tests/QtAutomoc/calwidget.h
@@ -0,0 +1,121 @@
+ /****************************************************************************
+ **
+ ** 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/codeeditor.cpp b/Tests/QtAutomoc/codeeditor.cpp
new file mode 100644
index 000000000..01da06276
--- /dev/null
+++ b/Tests/QtAutomoc/codeeditor.cpp
@@ -0,0 +1,153 @@
+/****************************************************************************
+ **
+ ** 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 <QtGui>
+
+ #include "codeeditor.h"
+
+
+ CodeEditor::CodeEditor(QWidget *parent) : QPlainTextEdit(parent)
+ {
+ lineNumberArea = new LineNumberArea(this);
+
+ connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth(int)));
+ connect(this, SIGNAL(updateRequest(QRect,int)), this, SLOT(updateLineNumberArea(QRect,int)));
+ connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(highlightCurrentLine()));
+
+ updateLineNumberAreaWidth(0);
+ highlightCurrentLine();
+ }
+
+
+
+ int CodeEditor::lineNumberAreaWidth()
+ {
+ int digits = 1;
+ int max = qMax(1, blockCount());
+ while (max >= 10) {
+ max /= 10;
+ ++digits;
+ }
+
+ int space = 3 + fontMetrics().width(QLatin1Char('9')) * digits;
+
+ return space;
+ }
+
+
+
+ void CodeEditor::updateLineNumberAreaWidth(int /* newBlockCount */)
+ {
+ setViewportMargins(lineNumberAreaWidth(), 0, 0, 0);
+ }
+
+
+
+ void CodeEditor::updateLineNumberArea(const QRect &rect, int dy)
+ {
+ if (dy)
+ lineNumberArea->scroll(0, dy);
+ else
+ lineNumberArea->update(0, rect.y(), lineNumberArea->width(), rect.height());
+
+ if (rect.contains(viewport()->rect()))
+ updateLineNumberAreaWidth(0);
+ }
+
+
+
+ void CodeEditor::resizeEvent(QResizeEvent *e)
+ {
+ QPlainTextEdit::resizeEvent(e);
+
+ QRect cr = contentsRect();
+ lineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height()));
+ }
+
+
+
+ void CodeEditor::highlightCurrentLine()
+ {
+ QList<QTextEdit::ExtraSelection> extraSelections;
+
+ if (!isReadOnly()) {
+ QTextEdit::ExtraSelection selection;
+
+ QColor lineColor = QColor(Qt::yellow).lighter(160);
+
+ selection.format.setBackground(lineColor);
+ selection.format.setProperty(QTextFormat::FullWidthSelection, true);
+ selection.cursor = textCursor();
+ selection.cursor.clearSelection();
+ extraSelections.append(selection);
+ }
+
+ setExtraSelections(extraSelections);
+ }
+
+
+
+ void CodeEditor::lineNumberAreaPaintEvent(QPaintEvent *event)
+ {
+ QPainter painter(lineNumberArea);
+ painter.fillRect(event->rect(), Qt::lightGray);
+
+
+ QTextBlock block = firstVisibleBlock();
+ int blockNumber = block.blockNumber();
+ int top = (int) blockBoundingGeometry(block).translated(contentOffset()).top();
+ int bottom = top + (int) blockBoundingRect(block).height();
+
+ while (block.isValid() && top <= event->rect().bottom()) {
+ if (block.isVisible() && bottom >= event->rect().top()) {
+ QString number = QString::number(blockNumber + 1);
+ painter.setPen(Qt::black);
+ painter.drawText(0, top, lineNumberArea->width(), fontMetrics().height(),
+ Qt::AlignRight, number);
+ }
+
+ block = block.next();
+ top = bottom;
+ bottom = top + (int) blockBoundingRect(block).height();
+ ++blockNumber;
+ }
+ }
+
+#include "codeeditor.moc"
diff --git a/Tests/QtAutomoc/codeeditor.h b/Tests/QtAutomoc/codeeditor.h
new file mode 100644
index 000000000..56e9e7923
--- /dev/null
+++ b/Tests/QtAutomoc/codeeditor.h
@@ -0,0 +1,99 @@
+ /****************************************************************************
+ **
+ ** 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 CODEEDITOR_H
+ #define CODEEDITOR_H
+
+ #include <QPlainTextEdit>
+ #include <QObject>
+
+ class QPaintEvent;
+ class QResizeEvent;
+ class QSize;
+ class QWidget;
+
+ class LineNumberArea;
+
+
+ class CodeEditor : public QPlainTextEdit
+ {
+ Q_OBJECT
+
+ public:
+ CodeEditor(QWidget *parent = 0);
+
+ void lineNumberAreaPaintEvent(QPaintEvent *event);
+ int lineNumberAreaWidth();
+
+ protected:
+ void resizeEvent(QResizeEvent *event);
+
+ private slots:
+ void updateLineNumberAreaWidth(int newBlockCount);
+ void highlightCurrentLine();
+ void updateLineNumberArea(const QRect &, int);
+
+ private:
+ QWidget *lineNumberArea;
+ };
+
+
+ class LineNumberArea : public QWidget
+ {
+ public:
+ LineNumberArea(CodeEditor *editor) : QWidget(editor) {
+ codeEditor = editor;
+ }
+
+ QSize sizeHint() const {
+ return QSize(codeEditor->lineNumberAreaWidth(), 0);
+ }
+
+ protected:
+ void paintEvent(QPaintEvent *event) {
+ codeEditor->lineNumberAreaPaintEvent(event);
+ }
+
+ private:
+ CodeEditor *codeEditor;
+ };
+
+
+ #endif
diff --git a/Tests/QtAutomoc/foo.cpp b/Tests/QtAutomoc/foo.cpp
new file mode 100644
index 000000000..699ba094b
--- /dev/null
+++ b/Tests/QtAutomoc/foo.cpp
@@ -0,0 +1,39 @@
+/*============================================================================
+ 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 "foo.h"
+
+#include <stdio.h>
+
+class FooFoo : public QObject
+{
+ Q_OBJECT
+ public:
+ FooFoo():QObject() {}
+ public slots:
+ int getValue() const { return 12; }
+};
+
+Foo::Foo()
+:QObject()
+{
+}
+
+
+void Foo::doFoo()
+{
+ FooFoo ff;
+ printf("Hello automoc: %d\n", ff.getValue());
+}
+
+#include "foo.moc"
diff --git a/Tests/QtAutomoc/foo.h b/Tests/QtAutomoc/foo.h
new file mode 100644
index 000000000..32d4c8d8f
--- /dev/null
+++ b/Tests/QtAutomoc/foo.h
@@ -0,0 +1,28 @@
+/*============================================================================
+ 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 FOO_H
+#define FOO_H
+
+#include <QObject>
+
+class Foo : public QObject
+{
+ Q_OBJECT
+ public:
+ Foo();
+ public slots:
+ void doFoo();
+};
+
+#endif
diff --git a/Tests/QtAutomoc/main.cpp b/Tests/QtAutomoc/main.cpp
new file mode 100644
index 000000000..738f67720
--- /dev/null
+++ b/Tests/QtAutomoc/main.cpp
@@ -0,0 +1,82 @@
+/****************************************************************************
+ **
+ ** 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 <QtGui>
+
+#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"
+
+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();
+
+ return app.exec();
+}
diff --git a/Tests/QtAutomoc/private_slot.cpp b/Tests/QtAutomoc/private_slot.cpp
new file mode 100644
index 000000000..1387a70cf
--- /dev/null
+++ b/Tests/QtAutomoc/private_slot.cpp
@@ -0,0 +1,21 @@
+
+#include "private_slot.h"
+
+class PrivateSlotPrivate
+{
+public:
+
+ void privateSlot()
+ {
+
+ }
+};
+
+PrivateSlot::PrivateSlot(QObject *parent)
+ : QObject(parent),
+ d(new PrivateSlotPrivate)
+{
+
+}
+
+#include "private_slot.moc"
diff --git a/Tests/QtAutomoc/private_slot.h b/Tests/QtAutomoc/private_slot.h
new file mode 100644
index 000000000..28e54482a
--- /dev/null
+++ b/Tests/QtAutomoc/private_slot.h
@@ -0,0 +1,20 @@
+
+#ifndef PRIVATE_SLOT_H
+#define PRIVATE_SLOT_H
+
+#include <QObject>
+
+class PrivateSlotPrivate;
+
+class PrivateSlot : public QObject
+{
+ Q_OBJECT
+public:
+ PrivateSlot(QObject *parent = 0);
+
+private:
+ PrivateSlotPrivate * const d;
+ Q_PRIVATE_SLOT(d, void privateSlot())
+};
+
+#endif
diff --git a/Tests/QtAutomoc/sub/bar.h b/Tests/QtAutomoc/sub/bar.h
new file mode 100644
index 000000000..db56b8ed5
--- /dev/null
+++ b/Tests/QtAutomoc/sub/bar.h
@@ -0,0 +1,28 @@
+/*============================================================================
+ 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 BAR_H
+#define BAR_H
+
+#include <QObject>
+
+class Bar : public QObject
+{
+ Q_OBJECT
+ public:
+ Bar();
+ public slots:
+ void doBar();
+};
+
+#endif
diff --git a/Tests/QtAutomoc/xyz.cpp b/Tests/QtAutomoc/xyz.cpp
new file mode 100644
index 000000000..a3562a337
--- /dev/null
+++ b/Tests/QtAutomoc/xyz.cpp
@@ -0,0 +1,28 @@
+/*============================================================================
+ 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 "xyz.h"
+
+#include <stdio.h>
+
+Xyz::Xyz()
+:QObject()
+{
+}
+
+
+void Xyz::doXyz()
+{
+ printf("This is xyz !\n");
+}
diff --git a/Tests/QtAutomoc/xyz.h b/Tests/QtAutomoc/xyz.h
new file mode 100644
index 000000000..8175d3792
--- /dev/null
+++ b/Tests/QtAutomoc/xyz.h
@@ -0,0 +1,28 @@
+/*============================================================================
+ 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 XYZ_H
+#define XYZ_H
+
+#include <QObject>
+
+class Xyz : public QObject
+{
+ Q_OBJECT
+ public:
+ Xyz();
+ public slots:
+ void doXyz();
+};
+
+#endif
diff --git a/Tests/QtAutomoc/yaf.cpp b/Tests/QtAutomoc/yaf.cpp
new file mode 100644
index 000000000..d278ab422
--- /dev/null
+++ b/Tests/QtAutomoc/yaf.cpp
@@ -0,0 +1,32 @@
+/*============================================================================
+ 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 "yaf.h"
+#include "yaf_p.h"
+
+#include <stdio.h>
+
+Yaf::Yaf()
+{
+}
+
+
+void Yaf::doYaf()
+{
+ YafP yafP;
+ yafP.doYafP();
+}
+
+// check that including a moc file from a private header the wrong way works:
+#include "yaf_p.moc"
diff --git a/Tests/QtAutomoc/yaf.h b/Tests/QtAutomoc/yaf.h
new file mode 100644
index 000000000..8689f8308
--- /dev/null
+++ b/Tests/QtAutomoc/yaf.h
@@ -0,0 +1,25 @@
+/*============================================================================
+ 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 YAF_H
+#define YAF_H
+
+class Yaf
+{
+ public:
+ Yaf();
+ public:
+ void doYaf();
+};
+
+#endif
diff --git a/Tests/QtAutomoc/yaf_p.h b/Tests/QtAutomoc/yaf_p.h
new file mode 100644
index 000000000..f0368ade1
--- /dev/null
+++ b/Tests/QtAutomoc/yaf_p.h
@@ -0,0 +1,30 @@
+/*============================================================================
+ 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 YAF_P_H
+#define YAF_P_H
+
+#include <QObject>
+
+#include <stdio.h>
+
+class YafP : public QObject
+{
+ Q_OBJECT
+ public:
+ YafP() {}
+ public slots:
+ void doYafP() { printf("I am yet another file !\n"); }
+};
+
+#endif
diff --git a/Tests/README b/Tests/README
new file mode 100644
index 000000000..8b2fda845
--- /dev/null
+++ b/Tests/README
@@ -0,0 +1,39 @@
+If you think about adding a new testcase then here is a small checklist you
+can run through to find a proper place for it. Go through the list from the
+beginning and stop once you find something that matches your tests needs,
+i.e. if you will test a module and only need the configure mode use the
+instructions from section 2, not 3.
+
+1. Your testcase can run in CMake script mode, i.e. "cmake -P something"
+
+Put your test in Tests/CMakeTests/ directory as a .cmake.in file. It will be
+put into the test binary directory by configure_file(... @ONLY) and run from
+there. Use the AddCMakeTest() macro in Tests/CMakeTests/CMakeLists.txt to add
+your test to the test runs.
+
+2. Your test needs CMake to run in configure mode, but will not build anything
+
+This includes tests that will build something using try_compile() and friends,
+but nothing that expects add_executable(), add_library(), or add_test() to run.
+
+If the test configures the project only once and it must succeed then put it
+into the Tests/CMakeOnly/ directory. Create a subdirectory named like your
+test and write the CMakeLists.txt you need into that subdirectory. Use the
+add_CMakeOnly_test() macro from Tests/CMakeOnly/CMakeLists.txt to add your
+test to the test runs.
+
+If the test configures the project with multiple variations and verifies
+success or failure each time then put it into the Tests/RunCMake/ directory.
+Read the instructions in Tests/RunCMake/CMakeLists.txt to add a test.
+
+3. If you are testing something from the Modules directory
+
+Put your test in the Tests/Modules/ directory. Create a subdirectory there
+named after your test. Use the ADD_TEST_MACRO macro from Tests/CMakeLists.txt
+to add your test to the test run. If you have put your stuff in
+Tests/Modules/Foo then you call it using ADD_TEST_MACRO(Module.Foo Foo).
+
+4. You are doing other stuff.
+
+Find a good place ;) In doubt mail to cmake-developers@cmake.org and ask for
+advise.
diff --git a/Tests/ReturnTest/CMakeLists.txt b/Tests/ReturnTest/CMakeLists.txt
new file mode 100644
index 000000000..a08855ec1
--- /dev/null
+++ b/Tests/ReturnTest/CMakeLists.txt
@@ -0,0 +1,147 @@
+# a simple C only test case
+cmake_minimum_required (VERSION 2.6)
+project (ReturnTest)
+
+function (FAILED testname)
+ message (SEND_ERROR "${testname} failed ${ARGN}")
+endfunction (FAILED)
+
+function (PASS testname)
+ message ("${testname} passed ${ARGN}")
+endfunction (PASS)
+
+# test simple return
+function (simple)
+ set(simpleResult 1 PARENT_SCOPE)
+ return()
+ set(simpleResult 0 PARENT_SCOPE)
+endfunction (simple)
+simple()
+if ("${simpleResult}")
+ pass ("simple")
+else ("${simpleResult}")
+ failed ("simple got: ${simpleResult}")
+endif ("${simpleResult}")
+
+#test return in an if statement
+set (simple2IF 1)
+function (simple2)
+ set(simple2Result 1 PARENT_SCOPE)
+ if (simple2IF)
+ return()
+ endif (simple2IF)
+ set(simple2Result 0 PARENT_SCOPE)
+endfunction (simple2)
+simple2()
+if ("${simple2Result}")
+ pass ("simple2")
+else ("${simple2Result}")
+ failed ("simple2 got: ${simple2Result}")
+endif ("${simple2Result}")
+
+#test return in a foreach loop
+function (looptest)
+ foreach (iter RANGE 1 5)
+ set (looptestResult "${iter}" PARENT_SCOPE)
+ if ("${iter}" EQUAL 3)
+ return ()
+ endif ("${iter}" EQUAL 3)
+ endforeach (iter)
+endfunction (looptest)
+looptest()
+if ("${looptestResult}" EQUAL 3)
+ pass ("looptest")
+else ("${looptestResult}" EQUAL 3)
+ failed ("looptest got: ${looptestResult}")
+endif ("${looptestResult}" EQUAL 3)
+
+#test return in a while loop
+function (whiletest)
+ set (iter "a")
+ while(NOT "${iter}" STREQUAL "aaaaa")
+ set (whiletestResult "${iter}" PARENT_SCOPE)
+ if ("${iter}" STREQUAL "aaa")
+ return ()
+ endif ("${iter}" STREQUAL "aaa")
+ set (iter "${iter}a")
+ endwhile(NOT "${iter}" STREQUAL "aaaaa")
+endfunction (whiletest)
+whiletest()
+if ("${whiletestResult}" STREQUAL "aaa")
+ pass ("whiletest")
+else ("${whiletestResult}" STREQUAL "aaa")
+ failed ("whiletest got: ${whiletestResult}")
+endif ("${whiletestResult}" STREQUAL "aaa")
+
+# check subdir return
+add_subdirectory(subdir)
+get_directory_property(subdirResult DIRECTORY subdir DEFINITION subdirreturn)
+if ("${subdirResult}" EQUAL 1)
+ pass ("subdir")
+else ("${subdirResult}" EQUAL 1)
+ failed ("subdir got: ${subdirResult}")
+endif ("${subdirResult}" EQUAL 1)
+
+# check return from a file
+include(include_return.cmake)
+if ("${include_returnResult}" EQUAL 1)
+ pass ("include_return")
+else ("${include_returnResult}" EQUAL 1)
+ failed ("include_return got: ${include_returnResult}")
+endif ("${include_returnResult}" EQUAL 1)
+
+# check return from within a macro
+macro (mymacro)
+ set (foo 1)
+ if (foo)
+ return()
+ endif (foo)
+endmacro(mymacro)
+
+# test simple return
+function (simple3)
+ set (bar 0)
+ set(simple3Result 1 PARENT_SCOPE)
+ if (bar)
+ else (bar)
+ mymacro()
+ endif(bar)
+ set(simple3Result 0 PARENT_SCOPE)
+endfunction (simple3)
+simple3()
+if ("${simple3Result}")
+ pass ("macrotest")
+else ("${simple3Result}")
+ failed ("macrotest got: ${simple3Result}")
+endif ("${simple3Result}")
+
+
+# test break command now in a foreach
+foreach (iter RANGE 1 5)
+ set (break1 "${iter}")
+ if ("${iter}" EQUAL 3)
+ break ()
+ endif ("${iter}" EQUAL 3)
+endforeach (iter)
+if ("${break1}" EQUAL 3)
+ pass ("break in foreach")
+else ("${break1}" EQUAL 3)
+ failed ("break in foreach got: ${break1}")
+endif ("${break1}" EQUAL 3)
+
+# test break in a while loop
+set (iter "a")
+while(NOT "${iter}" STREQUAL "aaaaa")
+ if ("${iter}" STREQUAL "aaa")
+ break ()
+ endif ("${iter}" STREQUAL "aaa")
+ set (iter "${iter}a")
+endwhile(NOT "${iter}" STREQUAL "aaaaa")
+if ("${iter}" STREQUAL "aaa")
+ pass ("break in a while")
+else ("${iter}" STREQUAL "aaa")
+ failed ("break in a whi;e got: ${whiletestResult}")
+endif ("${iter}" STREQUAL "aaa")
+
+
+add_executable (ReturnTest returnTest.c)
diff --git a/Tests/ReturnTest/include_return.cmake b/Tests/ReturnTest/include_return.cmake
new file mode 100644
index 000000000..7cea1fb2d
--- /dev/null
+++ b/Tests/ReturnTest/include_return.cmake
@@ -0,0 +1,3 @@
+set(include_returnResult 1)
+return()
+set(include_returnResult 0)
diff --git a/Tests/ReturnTest/returnTest.c b/Tests/ReturnTest/returnTest.c
new file mode 100644
index 000000000..e0ced6afd
--- /dev/null
+++ b/Tests/ReturnTest/returnTest.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main(int argc, char* argv[])
+{
+ printf("Running command: %s with %d arguments\n", argv[0], argc);
+ return 0;
+}
diff --git a/Tests/ReturnTest/subdir/CMakeLists.txt b/Tests/ReturnTest/subdir/CMakeLists.txt
new file mode 100644
index 000000000..b9510924f
--- /dev/null
+++ b/Tests/ReturnTest/subdir/CMakeLists.txt
@@ -0,0 +1,3 @@
+set (subdirreturn 1)
+return()
+set (subdirreturn 0)
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
new file mode 100644
index 000000000..eca96f907
--- /dev/null
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -0,0 +1,58 @@
+# 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 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.
+
+macro(add_RunCMake_test test)
+ add_test(RunCMake.${test} ${CMAKE_CMAKE_COMMAND}
+ -DCMAKE_MODULE_PATH=${CMAKE_CURRENT_SOURCE_DIR}
+ -DRunCMake_GENERATOR=${CMAKE_TEST_GENERATOR}
+ -DRunCMake_SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}/${test}
+ -DRunCMake_BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}/${test}
+ -P "${CMAKE_CURRENT_SOURCE_DIR}/${test}/RunCMakeTest.cmake"
+ )
+endmacro()
+
+add_RunCMake_test(Languages)
+add_RunCMake_test(ObjectLibrary)
+
+add_RunCMake_test(build_command)
+add_RunCMake_test(find_package)
+add_RunCMake_test(include)
+add_RunCMake_test(list)
+
+if("${CMAKE_TEST_GENERATOR}" MATCHES "Visual Studio [^6]")
+ add_RunCMake_test(include_external_msproject)
+endif()
diff --git a/Tests/RunCMake/Languages/CMakeLists.txt b/Tests/RunCMake/Languages/CMakeLists.txt
new file mode 100644
index 000000000..e8db6b05b
--- /dev/null
+++ b/Tests/RunCMake/Languages/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/Languages/NoLangSHARED-result.txt b/Tests/RunCMake/Languages/NoLangSHARED-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/Languages/NoLangSHARED-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Languages/NoLangSHARED-stderr.txt b/Tests/RunCMake/Languages/NoLangSHARED-stderr.txt
new file mode 100644
index 000000000..3f93cf86c
--- /dev/null
+++ b/Tests/RunCMake/Languages/NoLangSHARED-stderr.txt
@@ -0,0 +1 @@
+CMake Error: CMake can not determine linker language for target:NoLang
diff --git a/Tests/RunCMake/Languages/NoLangSHARED.cmake b/Tests/RunCMake/Languages/NoLangSHARED.cmake
new file mode 100644
index 000000000..de6adf7cb
--- /dev/null
+++ b/Tests/RunCMake/Languages/NoLangSHARED.cmake
@@ -0,0 +1 @@
+add_library(NoLang SHARED foo.nolang)
diff --git a/Tests/RunCMake/Languages/RunCMakeTest.cmake b/Tests/RunCMake/Languages/RunCMakeTest.cmake
new file mode 100644
index 000000000..a99548f05
--- /dev/null
+++ b/Tests/RunCMake/Languages/RunCMakeTest.cmake
@@ -0,0 +1,3 @@
+include(RunCMake)
+
+run_cmake(NoLangSHARED)
diff --git a/Tests/RunCMake/Languages/foo.nolang b/Tests/RunCMake/Languages/foo.nolang
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/Languages/foo.nolang
diff --git a/Tests/RunCMake/ObjectLibrary/BadObjSource1-result.txt b/Tests/RunCMake/ObjectLibrary/BadObjSource1-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/BadObjSource1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ObjectLibrary/BadObjSource1-stderr.txt b/Tests/RunCMake/ObjectLibrary/BadObjSource1-stderr.txt
new file mode 100644
index 000000000..b31225b48
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/BadObjSource1-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at BadObjSource1.cmake:1 \(add_library\):
+ OBJECT library "A" contains:
+
+ bad.def
+
+ but may contain only headers and sources that compile.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObjectLibrary/BadObjSource1.cmake b/Tests/RunCMake/ObjectLibrary/BadObjSource1.cmake
new file mode 100644
index 000000000..aa3514d90
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/BadObjSource1.cmake
@@ -0,0 +1 @@
+add_library(A OBJECT a.c bad.def)
diff --git a/Tests/RunCMake/ObjectLibrary/BadObjSource2-result.txt b/Tests/RunCMake/ObjectLibrary/BadObjSource2-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/BadObjSource2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ObjectLibrary/BadObjSource2-stderr.txt b/Tests/RunCMake/ObjectLibrary/BadObjSource2-stderr.txt
new file mode 100644
index 000000000..906cf0b64
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/BadObjSource2-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at BadObjSource2.cmake:1 \(add_library\):
+ OBJECT library "A" contains:
+
+ bad.obj
+
+ but may contain only headers and sources that compile.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObjectLibrary/BadObjSource2.cmake b/Tests/RunCMake/ObjectLibrary/BadObjSource2.cmake
new file mode 100644
index 000000000..7957c99f2
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/BadObjSource2.cmake
@@ -0,0 +1 @@
+add_library(A OBJECT a.c bad.obj)
diff --git a/Tests/RunCMake/ObjectLibrary/BadSourceExpression1-result.txt b/Tests/RunCMake/ObjectLibrary/BadSourceExpression1-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/BadSourceExpression1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ObjectLibrary/BadSourceExpression1-stderr.txt b/Tests/RunCMake/ObjectLibrary/BadSourceExpression1-stderr.txt
new file mode 100644
index 000000000..a1cac36fa
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/BadSourceExpression1-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error at BadSourceExpression1.cmake:1 \(add_library\):
+ Unrecognized generator expression:
+
+ \$<BAD_EXPRESSION>
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObjectLibrary/BadSourceExpression1.cmake b/Tests/RunCMake/ObjectLibrary/BadSourceExpression1.cmake
new file mode 100644
index 000000000..020c9a00f
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/BadSourceExpression1.cmake
@@ -0,0 +1 @@
+add_library(A STATIC a.c $<BAD_EXPRESSION>)
diff --git a/Tests/RunCMake/ObjectLibrary/BadSourceExpression2-result.txt b/Tests/RunCMake/ObjectLibrary/BadSourceExpression2-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/BadSourceExpression2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ObjectLibrary/BadSourceExpression2-stderr.txt b/Tests/RunCMake/ObjectLibrary/BadSourceExpression2-stderr.txt
new file mode 100644
index 000000000..f1fcbe85f
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/BadSourceExpression2-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at BadSourceExpression2.cmake:1 \(add_library\):
+ 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/BadSourceExpression2.cmake b/Tests/RunCMake/ObjectLibrary/BadSourceExpression2.cmake
new file mode 100644
index 000000000..ed5dc4335
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/BadSourceExpression2.cmake
@@ -0,0 +1 @@
+add_library(A STATIC a.c $<TARGET_OBJECTS:DoesNotExist>)
diff --git a/Tests/RunCMake/ObjectLibrary/BadSourceExpression3-result.txt b/Tests/RunCMake/ObjectLibrary/BadSourceExpression3-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/BadSourceExpression3-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ObjectLibrary/BadSourceExpression3-stderr.txt b/Tests/RunCMake/ObjectLibrary/BadSourceExpression3-stderr.txt
new file mode 100644
index 000000000..ad14a3513
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/BadSourceExpression3-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at BadSourceExpression3.cmake:2 \(add_library\):
+ 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/BadSourceExpression3.cmake b/Tests/RunCMake/ObjectLibrary/BadSourceExpression3.cmake
new file mode 100644
index 000000000..c3d9a622d
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/BadSourceExpression3.cmake
@@ -0,0 +1,2 @@
+add_library(NotObjLib STATIC a.c)
+add_library(A STATIC a.c $<TARGET_OBJECTS:NotObjLib>)
diff --git a/Tests/RunCMake/ObjectLibrary/CMakeLists.txt b/Tests/RunCMake/ObjectLibrary/CMakeLists.txt
new file mode 100644
index 000000000..a7f077912
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8)
+project(${RunCMake_TEST} C)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/ObjectLibrary/Export-result.txt b/Tests/RunCMake/ObjectLibrary/Export-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/Export-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ObjectLibrary/Export-stderr.txt b/Tests/RunCMake/ObjectLibrary/Export-stderr.txt
new file mode 100644
index 000000000..bdadca488
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/Export-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at Export.cmake:2 \(export\):
+ export given OBJECT library "A" which may not be exported.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObjectLibrary/Export.cmake b/Tests/RunCMake/ObjectLibrary/Export.cmake
new file mode 100644
index 000000000..a3f104e29
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/Export.cmake
@@ -0,0 +1,2 @@
+add_library(A OBJECT a.c)
+export(TARGETS A FILE AExport.cmake)
diff --git a/Tests/RunCMake/ObjectLibrary/ExportLanguages.cmake b/Tests/RunCMake/ObjectLibrary/ExportLanguages.cmake
new file mode 100644
index 000000000..0796c21ba
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/ExportLanguages.cmake
@@ -0,0 +1,15 @@
+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/Import-result.txt b/Tests/RunCMake/ObjectLibrary/Import-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/Import-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ObjectLibrary/Import-stderr.txt b/Tests/RunCMake/ObjectLibrary/Import-stderr.txt
new file mode 100644
index 000000000..74b496ab8
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/Import-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at Import.cmake:1 \(add_library\):
+ The OBJECT library type may not be used for IMPORTED libraries.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObjectLibrary/Import.cmake b/Tests/RunCMake/ObjectLibrary/Import.cmake
new file mode 100644
index 000000000..806b44a25
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/Import.cmake
@@ -0,0 +1 @@
+add_library(A OBJECT IMPORTED)
diff --git a/Tests/RunCMake/ObjectLibrary/Install-result.txt b/Tests/RunCMake/ObjectLibrary/Install-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/Install-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ObjectLibrary/Install-stderr.txt b/Tests/RunCMake/ObjectLibrary/Install-stderr.txt
new file mode 100644
index 000000000..d2f9f4a37
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/Install-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at Install.cmake:2 \(install\):
+ install TARGETS given OBJECT library "A" which may not be installed.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObjectLibrary/Install.cmake b/Tests/RunCMake/ObjectLibrary/Install.cmake
new file mode 100644
index 000000000..c1d214bd4
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/Install.cmake
@@ -0,0 +1,2 @@
+add_library(A OBJECT a.c)
+install(TARGETS A DESTINATION lib)
diff --git a/Tests/RunCMake/ObjectLibrary/LinkObjLHS-result.txt b/Tests/RunCMake/ObjectLibrary/LinkObjLHS-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/LinkObjLHS-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ObjectLibrary/LinkObjLHS-stderr.txt b/Tests/RunCMake/ObjectLibrary/LinkObjLHS-stderr.txt
new file mode 100644
index 000000000..90e828bdb
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/LinkObjLHS-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at LinkObjLHS.cmake:2 \(target_link_libraries\):
+ Object library target "AnObjLib" may not link to anything.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObjectLibrary/LinkObjLHS.cmake b/Tests/RunCMake/ObjectLibrary/LinkObjLHS.cmake
new file mode 100644
index 000000000..5d7831a23
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/LinkObjLHS.cmake
@@ -0,0 +1,2 @@
+add_library(AnObjLib OBJECT a.c)
+target_link_libraries(AnObjLib OtherLib)
diff --git a/Tests/RunCMake/ObjectLibrary/LinkObjRHS1-result.txt b/Tests/RunCMake/ObjectLibrary/LinkObjRHS1-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/LinkObjRHS1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ObjectLibrary/LinkObjRHS1-stderr.txt b/Tests/RunCMake/ObjectLibrary/LinkObjRHS1-stderr.txt
new file mode 100644
index 000000000..8809f8933
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/LinkObjRHS1-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error at LinkObjRHS1.cmake:3 \(target_link_libraries\):
+ Target "AnObjLib" of type OBJECT_LIBRARY 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.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObjectLibrary/LinkObjRHS1.cmake b/Tests/RunCMake/ObjectLibrary/LinkObjRHS1.cmake
new file mode 100644
index 000000000..113d6a841
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/LinkObjRHS1.cmake
@@ -0,0 +1,3 @@
+add_library(A STATIC a.c)
+add_library(AnObjLib OBJECT a.c)
+target_link_libraries(A AnObjLib)
diff --git a/Tests/RunCMake/ObjectLibrary/LinkObjRHS2-result.txt b/Tests/RunCMake/ObjectLibrary/LinkObjRHS2-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/LinkObjRHS2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ObjectLibrary/LinkObjRHS2-stderr.txt b/Tests/RunCMake/ObjectLibrary/LinkObjRHS2-stderr.txt
new file mode 100644
index 000000000..3295fcac3
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/LinkObjRHS2-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error at LinkObjRHS2.cmake:1 \(add_library\):
+ Target "A" links to OBJECT library "AnObjLib" but this is not allowed. One
+ may link only to STATIC or SHARED libraries, or to executables with the
+ ENABLE_EXPORTS property set.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObjectLibrary/LinkObjRHS2.cmake b/Tests/RunCMake/ObjectLibrary/LinkObjRHS2.cmake
new file mode 100644
index 000000000..616372949
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/LinkObjRHS2.cmake
@@ -0,0 +1,3 @@
+add_library(A SHARED a.c)
+target_link_libraries(A AnObjLib)
+add_library(AnObjLib OBJECT a.c)
diff --git a/Tests/RunCMake/ObjectLibrary/ObjWithObj-result.txt b/Tests/RunCMake/ObjectLibrary/ObjWithObj-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/ObjWithObj-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ObjectLibrary/ObjWithObj-stderr.txt b/Tests/RunCMake/ObjectLibrary/ObjWithObj-stderr.txt
new file mode 100644
index 000000000..d67b4ae32
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/ObjWithObj-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at ObjWithObj.cmake:2 \(add_library\):
+ Only executables and non-OBJECT libraries may reference target objects.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObjectLibrary/ObjWithObj.cmake b/Tests/RunCMake/ObjectLibrary/ObjWithObj.cmake
new file mode 100644
index 000000000..d0ef34bfe
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/ObjWithObj.cmake
@@ -0,0 +1,2 @@
+add_library(A OBJECT a.c)
+add_library(B OBJECT $<TARGET_OBJECTS:A>)
diff --git a/Tests/RunCMake/ObjectLibrary/PostBuild-result.txt b/Tests/RunCMake/ObjectLibrary/PostBuild-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/PostBuild-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ObjectLibrary/PostBuild-stderr.txt b/Tests/RunCMake/ObjectLibrary/PostBuild-stderr.txt
new file mode 100644
index 000000000..4b067bbc3
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/PostBuild-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at PostBuild.cmake:2 \(add_custom_command\):
+ Target "A" is an OBJECT 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/ObjectLibrary/PostBuild.cmake b/Tests/RunCMake/ObjectLibrary/PostBuild.cmake
new file mode 100644
index 000000000..dea9a099e
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/PostBuild.cmake
@@ -0,0 +1,4 @@
+add_library(A OBJECT a.c)
+add_custom_command(TARGET A POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E echo "A post-build"
+ )
diff --git a/Tests/RunCMake/ObjectLibrary/PreBuild-result.txt b/Tests/RunCMake/ObjectLibrary/PreBuild-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/PreBuild-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ObjectLibrary/PreBuild-stderr.txt b/Tests/RunCMake/ObjectLibrary/PreBuild-stderr.txt
new file mode 100644
index 000000000..3b27a6da5
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/PreBuild-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at PreBuild.cmake:2 \(add_custom_command\):
+ Target "A" is an OBJECT 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/ObjectLibrary/PreBuild.cmake b/Tests/RunCMake/ObjectLibrary/PreBuild.cmake
new file mode 100644
index 000000000..e4424c100
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/PreBuild.cmake
@@ -0,0 +1,4 @@
+add_library(A OBJECT a.c)
+add_custom_command(TARGET A PRE_BUILD
+ COMMAND ${CMAKE_COMMAND} -E echo "A pre-build"
+ )
diff --git a/Tests/RunCMake/ObjectLibrary/PreLink-result.txt b/Tests/RunCMake/ObjectLibrary/PreLink-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/PreLink-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/ObjectLibrary/PreLink-stderr.txt b/Tests/RunCMake/ObjectLibrary/PreLink-stderr.txt
new file mode 100644
index 000000000..947b9f177
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/PreLink-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at PreLink.cmake:2 \(add_custom_command\):
+ Target "A" is an OBJECT 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/ObjectLibrary/PreLink.cmake b/Tests/RunCMake/ObjectLibrary/PreLink.cmake
new file mode 100644
index 000000000..b88905511
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/PreLink.cmake
@@ -0,0 +1,4 @@
+add_library(A OBJECT a.c)
+add_custom_command(TARGET A PRE_LINK
+ COMMAND ${CMAKE_COMMAND} -E echo "A pre-link"
+ )
diff --git a/Tests/RunCMake/ObjectLibrary/RunCMakeTest.cmake b/Tests/RunCMake/ObjectLibrary/RunCMakeTest.cmake
new file mode 100644
index 000000000..55db14dfd
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/RunCMakeTest.cmake
@@ -0,0 +1,18 @@
+include(RunCMake)
+
+run_cmake(BadSourceExpression1)
+run_cmake(BadSourceExpression2)
+run_cmake(BadSourceExpression3)
+run_cmake(BadObjSource1)
+run_cmake(BadObjSource2)
+run_cmake(Export)
+run_cmake(ExportLanguages)
+run_cmake(Import)
+run_cmake(Install)
+run_cmake(LinkObjLHS)
+run_cmake(LinkObjRHS1)
+run_cmake(LinkObjRHS2)
+run_cmake(ObjWithObj)
+run_cmake(PostBuild)
+run_cmake(PreBuild)
+run_cmake(PreLink)
diff --git a/Tests/RunCMake/ObjectLibrary/a.c b/Tests/RunCMake/ObjectLibrary/a.c
new file mode 100644
index 000000000..af20d3ff6
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/a.c
@@ -0,0 +1 @@
+int a(void) { return 0; }
diff --git a/Tests/RunCMake/ObjectLibrary/a.cxx b/Tests/RunCMake/ObjectLibrary/a.cxx
new file mode 100644
index 000000000..ae9c87c49
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/a.cxx
@@ -0,0 +1 @@
+extern "C" int acxx(void) { return 0; }
diff --git a/Tests/RunCMake/ObjectLibrary/bad.def b/Tests/RunCMake/ObjectLibrary/bad.def
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/bad.def
diff --git a/Tests/RunCMake/ObjectLibrary/bad.obj b/Tests/RunCMake/ObjectLibrary/bad.obj
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/RunCMake/ObjectLibrary/bad.obj
diff --git a/Tests/RunCMake/RunCMake.cmake b/Tests/RunCMake/RunCMake.cmake
new file mode 100644
index 000000000..c3c161abe
--- /dev/null
+++ b/Tests/RunCMake/RunCMake.cmake
@@ -0,0 +1,74 @@
+foreach(arg
+ RunCMake_GENERATOR
+ RunCMake_SOURCE_DIR
+ RunCMake_BINARY_DIR
+ )
+ if(NOT DEFINED ${arg})
+ message(FATAL_ERROR "${arg} not given!")
+ endif()
+endforeach()
+
+function(run_cmake test)
+ set(top_src "${RunCMake_SOURCE_DIR}")
+ set(top_bin "${RunCMake_BINARY_DIR}")
+ if(EXISTS ${top_src}/${test}-result.txt)
+ file(READ ${top_src}/${test}-result.txt expect_result)
+ string(REGEX REPLACE "\n+$" "" expect_result "${expect_result}")
+ else()
+ set(expect_result 0)
+ endif()
+ foreach(o out err)
+ if(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}")
+ set(RunCMake_TEST_BINARY_DIR "${top_bin}/${test}-build")
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} "${RunCMake_TEST_SOURCE_DIR}"
+ -G "${RunCMake_GENERATOR}" -DRunCMake_TEST=${test}
+ WORKING_DIRECTORY "${RunCMake_TEST_BINARY_DIR}"
+ OUTPUT_VARIABLE actual_stdout
+ ERROR_VARIABLE actual_stderr
+ RESULT_VARIABLE actual_result
+ )
+ set(msg "")
+ if(NOT "${actual_result}" STREQUAL "${expect_result}")
+ set(msg "${msg}Result is [${actual_result}], not [${expect_result}].\n")
+ endif()
+ foreach(o out err)
+ string(REGEX REPLACE "\n+$" "" actual_std${o} "${actual_std${o}}")
+ set(expect_${o} "")
+ if(DEFINED expect_std${o})
+ if(NOT "${actual_std${o}}" MATCHES "${expect_std${o}}")
+ string(REGEX REPLACE "\n" "\n expect-${o}> " expect_${o}
+ " expect-${o}> ${expect_std${o}}")
+ set(expect_${o} "Expected std${o} to match:\n${expect_${o}}\n")
+ set(msg "${msg}std${o} does not match that expected.\n")
+ endif()
+ endif()
+ endforeach()
+ unset(RunCMake_TEST_FAILED)
+ include(${top_src}/${test}-check.cmake OPTIONAL)
+ if(RunCMake_TEST_FAILED)
+ set(msg "${RunCMake_TEST_FAILED}\n${msg}")
+ 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}")
+ message(SEND_ERROR "${test} - FAILED:\n"
+ "${msg}"
+ "${expect_out}"
+ "Actual stdout:\n${actual_out}\n"
+ "${expect_err}"
+ "Actual stderr:\n${actual_err}\n"
+ )
+ else()
+ message(STATUS "${test} - PASSED")
+ endif()
+endfunction()
diff --git a/Tests/RunCMake/build_command/CMakeLists.txt b/Tests/RunCMake/build_command/CMakeLists.txt
new file mode 100644
index 000000000..0fbb94803
--- /dev/null
+++ b/Tests/RunCMake/build_command/CMakeLists.txt
@@ -0,0 +1,59 @@
+cmake_minimum_required(VERSION 2.8)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
+
+# This CMakeLists file is *sometimes expected* to result in a configure error.
+#
+# expect this to succeed:
+# ../bin/Release/cmake -G Xcode
+# ../../CMake/Tests/CMakeCommands/build_command
+#
+# expect this to fail:
+# ../bin/Release/cmake -DTEST_ERROR_CONDITIONS:BOOL=ON -G Xcode
+# ../../CMake/Tests/CMakeCommands/build_command
+#
+# This project exists merely to test the CMake command 'build_command'...
+# ...even purposefully calling it with known-bad argument lists to cover
+# error handling code.
+#
+
+set(cmd "initial")
+
+message("0. begin")
+
+if(TEST_ERROR_CONDITIONS)
+ # Test with no arguments (an error):
+ build_command()
+ message("1. cmd='${cmd}'")
+
+ # Test with unknown arguments (also an error):
+ build_command(cmd BOGUS STUFF)
+ message("2. cmd='${cmd}'")
+
+ build_command(cmd STUFF BOGUS)
+ message("3. cmd='${cmd}'")
+else()
+ message("(skipping cases 1, 2 and 3 because TEST_ERROR_CONDITIONS is OFF)")
+endif()
+
+# Test the one arg signature with none of the optional KEYWORD arguments:
+build_command(cmd)
+message("4. cmd='${cmd}'")
+
+# Test the two-arg legacy signature:
+build_command(legacy_cmd ${CMAKE_BUILD_TOOL})
+message("5. legacy_cmd='${legacy_cmd}'")
+message(" CMAKE_BUILD_TOOL='${CMAKE_BUILD_TOOL}'")
+
+# Test the optional KEYWORDs:
+build_command(cmd CONFIGURATION hoohaaConfig)
+message("6. cmd='${cmd}'")
+
+build_command(cmd PROJECT_NAME hoohaaProject)
+message("7. cmd='${cmd}'")
+
+build_command(cmd TARGET hoohaaTarget)
+message("8. cmd='${cmd}'")
+
+set(cmd "final")
+message("9. cmd='${cmd}'")
diff --git a/Tests/RunCMake/build_command/ErrorsOFF-stderr.txt b/Tests/RunCMake/build_command/ErrorsOFF-stderr.txt
new file mode 100644
index 000000000..331885b94
--- /dev/null
+++ b/Tests/RunCMake/build_command/ErrorsOFF-stderr.txt
@@ -0,0 +1 @@
+skipping cases 1, 2 and 3 because TEST_ERROR_CONDITIONS is OFF
diff --git a/Tests/RunCMake/build_command/ErrorsOFF-stdout.txt b/Tests/RunCMake/build_command/ErrorsOFF-stdout.txt
new file mode 100644
index 000000000..cf66a9d7a
--- /dev/null
+++ b/Tests/RunCMake/build_command/ErrorsOFF-stdout.txt
@@ -0,0 +1 @@
+Build files have been written to:
diff --git a/Tests/RunCMake/build_command/ErrorsOFF.cmake b/Tests/RunCMake/build_command/ErrorsOFF.cmake
new file mode 100644
index 000000000..a243fab01
--- /dev/null
+++ b/Tests/RunCMake/build_command/ErrorsOFF.cmake
@@ -0,0 +1 @@
+set(TEST_ERROR_CONDITIONS OFF)
diff --git a/Tests/RunCMake/build_command/ErrorsON-result.txt b/Tests/RunCMake/build_command/ErrorsON-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/build_command/ErrorsON-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/build_command/ErrorsON-stderr.txt b/Tests/RunCMake/build_command/ErrorsON-stderr.txt
new file mode 100644
index 000000000..0be7475d7
--- /dev/null
+++ b/Tests/RunCMake/build_command/ErrorsON-stderr.txt
@@ -0,0 +1,12 @@
+CMake Error at CMakeLists.txt:[0-9]+ \(build_command\):
+ build_command requires at least one argument naming a CMake variable
+
++
+1. cmd='initial'
+CMake Error at CMakeLists.txt:[0-9]+ \(build_command\):
+ build_command unknown argument "BOGUS"
+
++
+2. cmd='initial'
+CMake Error at CMakeLists.txt:[0-9]+ \(build_command\):
+ build_command unknown argument "STUFF"
diff --git a/Tests/RunCMake/build_command/ErrorsON-stdout.txt b/Tests/RunCMake/build_command/ErrorsON-stdout.txt
new file mode 100644
index 000000000..841dd0d88
--- /dev/null
+++ b/Tests/RunCMake/build_command/ErrorsON-stdout.txt
@@ -0,0 +1 @@
+Configuring incomplete, errors occurred!
diff --git a/Tests/RunCMake/build_command/ErrorsON.cmake b/Tests/RunCMake/build_command/ErrorsON.cmake
new file mode 100644
index 000000000..27814bf64
--- /dev/null
+++ b/Tests/RunCMake/build_command/ErrorsON.cmake
@@ -0,0 +1 @@
+set(TEST_ERROR_CONDITIONS ON)
diff --git a/Tests/RunCMake/build_command/RunCMakeTest.cmake b/Tests/RunCMake/build_command/RunCMakeTest.cmake
new file mode 100644
index 000000000..4525c5725
--- /dev/null
+++ b/Tests/RunCMake/build_command/RunCMakeTest.cmake
@@ -0,0 +1,4 @@
+include(RunCMake)
+
+run_cmake(ErrorsOFF)
+run_cmake(ErrorsON)
diff --git a/Tests/RunCMake/find_package/CMakeLists.txt b/Tests/RunCMake/find_package/CMakeLists.txt
new file mode 100644
index 000000000..e8db6b05b
--- /dev/null
+++ b/Tests/RunCMake/find_package/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/find_package/ComponentRequiredAndOptional-result.txt b/Tests/RunCMake/find_package/ComponentRequiredAndOptional-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/find_package/ComponentRequiredAndOptional-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/find_package/ComponentRequiredAndOptional-stderr.txt b/Tests/RunCMake/find_package/ComponentRequiredAndOptional-stderr.txt
new file mode 100644
index 000000000..db8f51222
--- /dev/null
+++ b/Tests/RunCMake/find_package/ComponentRequiredAndOptional-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at ComponentRequiredAndOptional.cmake:1 \(find_package\):
+ find_package called with components that are both required and optional:
+
+ CompA
+ CompB
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/find_package/ComponentRequiredAndOptional.cmake b/Tests/RunCMake/find_package/ComponentRequiredAndOptional.cmake
new file mode 100644
index 000000000..0355f5af3
--- /dev/null
+++ b/Tests/RunCMake/find_package/ComponentRequiredAndOptional.cmake
@@ -0,0 +1 @@
+find_package(NotHere REQUIRED CompA CompB CompC OPTIONAL_COMPONENTS CompA CompB CompD)
diff --git a/Tests/RunCMake/find_package/MissingConfig-stderr.txt b/Tests/RunCMake/find_package/MissingConfig-stderr.txt
new file mode 100644
index 000000000..1eae0bb0b
--- /dev/null
+++ b/Tests/RunCMake/find_package/MissingConfig-stderr.txt
@@ -0,0 +1,19 @@
+CMake Warning at MissingConfig.cmake:1 \(find_package\):
+ Could not find a package configuration file provided by "NotHere" with any
+ of the following names:
+
+ NotHereConfig.cmake
+ nothere-config.cmake
+
+ Add the installation prefix of "NotHere" to CMAKE_PREFIX_PATH or set
+ "NotHere_DIR" to a directory containing one of the above files. If
+ "NotHere" provides a separate development package or SDK, be sure it has
+ been installed.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+
+
+CMake Warning at MissingConfig.cmake:2 \(message\):
+ This warning must be reachable.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/find_package/MissingConfig.cmake b/Tests/RunCMake/find_package/MissingConfig.cmake
new file mode 100644
index 000000000..238e7e498
--- /dev/null
+++ b/Tests/RunCMake/find_package/MissingConfig.cmake
@@ -0,0 +1,2 @@
+find_package(NotHere CONFIG)
+message(WARNING "This warning must be reachable.")
diff --git a/Tests/RunCMake/find_package/MissingConfigOneName-stderr.txt b/Tests/RunCMake/find_package/MissingConfigOneName-stderr.txt
new file mode 100644
index 000000000..10e71faa3
--- /dev/null
+++ b/Tests/RunCMake/find_package/MissingConfigOneName-stderr.txt
@@ -0,0 +1,10 @@
+CMake Warning at MissingConfigOneName.cmake:1 \(find_package\):
+ Could not find a package configuration file named "NotHereConfig.cmake"
+ provided by package "NotHere".
+
+ Add the installation prefix of "NotHere" to CMAKE_PREFIX_PATH or set
+ "NotHere_DIR" to a directory containing one of the above files. If
+ "NotHere" provides a separate development package or SDK, be sure it has
+ been installed.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/find_package/MissingConfigOneName.cmake b/Tests/RunCMake/find_package/MissingConfigOneName.cmake
new file mode 100644
index 000000000..11676a9ab
--- /dev/null
+++ b/Tests/RunCMake/find_package/MissingConfigOneName.cmake
@@ -0,0 +1 @@
+find_package(NotHere CONFIGS NotHereConfig.cmake)
diff --git a/Tests/RunCMake/find_package/MissingConfigRequired-result.txt b/Tests/RunCMake/find_package/MissingConfigRequired-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/find_package/MissingConfigRequired-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/find_package/MissingConfigRequired-stderr.txt b/Tests/RunCMake/find_package/MissingConfigRequired-stderr.txt
new file mode 100644
index 000000000..2ba774aa2
--- /dev/null
+++ b/Tests/RunCMake/find_package/MissingConfigRequired-stderr.txt
@@ -0,0 +1,13 @@
+CMake Error at MissingConfigRequired.cmake:1 \(find_package\):
+ Could not find a package configuration file provided by "NotHere" with any
+ of the following names:
+
+ NotHereConfig.cmake
+ nothere-config.cmake
+
+ Add the installation prefix of "NotHere" to CMAKE_PREFIX_PATH or set
+ "NotHere_DIR" to a directory containing one of the above files. If
+ "NotHere" provides a separate development package or SDK, be sure it has
+ been installed.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/find_package/MissingConfigRequired.cmake b/Tests/RunCMake/find_package/MissingConfigRequired.cmake
new file mode 100644
index 000000000..0ae67023a
--- /dev/null
+++ b/Tests/RunCMake/find_package/MissingConfigRequired.cmake
@@ -0,0 +1,2 @@
+find_package(NotHere CONFIG REQUIRED)
+message(FATAL_ERROR "This error must not be reachable.")
diff --git a/Tests/RunCMake/find_package/MissingConfigVersion-stderr.txt b/Tests/RunCMake/find_package/MissingConfigVersion-stderr.txt
new file mode 100644
index 000000000..2f5086ea8
--- /dev/null
+++ b/Tests/RunCMake/find_package/MissingConfigVersion-stderr.txt
@@ -0,0 +1,13 @@
+CMake Warning at MissingConfigVersion.cmake:1 \(find_package\):
+ Could not find a package configuration file provided by "NotHere"
+ \(requested version 1\.2\) with any of the following names:
+
+ NotHereConfig.cmake
+ nothere-config.cmake
+
+ Add the installation prefix of "NotHere" to CMAKE_PREFIX_PATH or set
+ "NotHere_DIR" to a directory containing one of the above files. If
+ "NotHere" provides a separate development package or SDK, be sure it has
+ been installed.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/find_package/MissingConfigVersion.cmake b/Tests/RunCMake/find_package/MissingConfigVersion.cmake
new file mode 100644
index 000000000..ac35a79e4
--- /dev/null
+++ b/Tests/RunCMake/find_package/MissingConfigVersion.cmake
@@ -0,0 +1 @@
+find_package(NotHere 1.2 CONFIG)
diff --git a/Tests/RunCMake/find_package/MissingModule-stderr.txt b/Tests/RunCMake/find_package/MissingModule-stderr.txt
new file mode 100644
index 000000000..2ad460f58
--- /dev/null
+++ b/Tests/RunCMake/find_package/MissingModule-stderr.txt
@@ -0,0 +1,26 @@
+CMake Warning at MissingModule.cmake:1 \(find_package\):
+ No "FindNotHere.cmake" found in CMAKE_MODULE_PATH.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+
+
+CMake Warning \(dev\) at MissingModule.cmake:1 \(find_package\):
+ FindNotHere.cmake must either be part of this project itself, in this case
+ adjust CMAKE_MODULE_PATH so that it points to the correct location inside
+ its source tree.
+
+ Or it must be installed by a package which has already been found via
+ find_package\(\). In this case make sure that package has indeed been found
+ and adjust CMAKE_MODULE_PATH to contain the location where that package has
+ installed FindNotHere.cmake. This must be a location provided by that
+ package. This error in general means that the buildsystem of this project
+ is relying on a Find-module without ensuring that it is actually available.
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning at MissingModule.cmake:2 \(message\):
+ This warning must be reachable.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/find_package/MissingModule.cmake b/Tests/RunCMake/find_package/MissingModule.cmake
new file mode 100644
index 000000000..76bcef293
--- /dev/null
+++ b/Tests/RunCMake/find_package/MissingModule.cmake
@@ -0,0 +1,2 @@
+find_package(NotHere MODULE)
+message(WARNING "This warning must be reachable.")
diff --git a/Tests/RunCMake/find_package/MissingModuleRequired-result.txt b/Tests/RunCMake/find_package/MissingModuleRequired-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/find_package/MissingModuleRequired-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/find_package/MissingModuleRequired-stderr.txt b/Tests/RunCMake/find_package/MissingModuleRequired-stderr.txt
new file mode 100644
index 000000000..fec05f183
--- /dev/null
+++ b/Tests/RunCMake/find_package/MissingModuleRequired-stderr.txt
@@ -0,0 +1,21 @@
+CMake Error at MissingModuleRequired.cmake:1 \(find_package\):
+ No "FindNotHere.cmake" found in CMAKE_MODULE_PATH.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+
+
+CMake Warning \(dev\) at MissingModuleRequired.cmake:1 \(find_package\):
+ FindNotHere.cmake must either be part of this project itself, in this case
+ adjust CMAKE_MODULE_PATH so that it points to the correct location inside
+ its source tree.
+
+ Or it must be installed by a package which has already been found via
+ find_package\(\). In this case make sure that package has indeed been found
+ and adjust CMAKE_MODULE_PATH to contain the location where that package has
+ installed FindNotHere.cmake. This must be a location provided by that
+ package. This error in general means that the buildsystem of this project
+ is relying on a Find-module without ensuring that it is actually available.
+
+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/find_package/MissingModuleRequired.cmake b/Tests/RunCMake/find_package/MissingModuleRequired.cmake
new file mode 100644
index 000000000..897eda688
--- /dev/null
+++ b/Tests/RunCMake/find_package/MissingModuleRequired.cmake
@@ -0,0 +1,2 @@
+find_package(NotHere MODULE REQUIRED)
+message(FATAL_ERROR "This error must not be reachable.")
diff --git a/Tests/RunCMake/find_package/MissingNormal-stderr.txt b/Tests/RunCMake/find_package/MissingNormal-stderr.txt
new file mode 100644
index 000000000..f4c6fbafd
--- /dev/null
+++ b/Tests/RunCMake/find_package/MissingNormal-stderr.txt
@@ -0,0 +1,23 @@
+CMake Warning at MissingNormal.cmake:1 \(find_package\):
+ By not providing "FindNotHere.cmake" in CMAKE_MODULE_PATH this project has
+ asked CMake to find a package configuration file provided by "NotHere", but
+ CMake did not find one.
+
+ Could not find a package configuration file provided by "NotHere" with any
+ of the following names:
+
+ NotHereConfig.cmake
+ nothere-config.cmake
+
+ Add the installation prefix of "NotHere" to CMAKE_PREFIX_PATH or set
+ "NotHere_DIR" to a directory containing one of the above files. If
+ "NotHere" provides a separate development package or SDK, be sure it has
+ been installed.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+
+
+CMake Warning at MissingNormal.cmake:2 \(message\):
+ This warning must be reachable.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/find_package/MissingNormal.cmake b/Tests/RunCMake/find_package/MissingNormal.cmake
new file mode 100644
index 000000000..fb90e0128
--- /dev/null
+++ b/Tests/RunCMake/find_package/MissingNormal.cmake
@@ -0,0 +1,2 @@
+find_package(NotHere)
+message(WARNING "This warning must be reachable.")
diff --git a/Tests/RunCMake/find_package/MissingNormalRequired-result.txt b/Tests/RunCMake/find_package/MissingNormalRequired-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/find_package/MissingNormalRequired-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/find_package/MissingNormalRequired-stderr.txt b/Tests/RunCMake/find_package/MissingNormalRequired-stderr.txt
new file mode 100644
index 000000000..7bb7902b6
--- /dev/null
+++ b/Tests/RunCMake/find_package/MissingNormalRequired-stderr.txt
@@ -0,0 +1,17 @@
+CMake Error at MissingNormalRequired.cmake:1 \(find_package\):
+ By not providing "FindNotHere.cmake" in CMAKE_MODULE_PATH this project has
+ asked CMake to find a package configuration file provided by "NotHere", but
+ CMake did not find one.
+
+ Could not find a package configuration file provided by "NotHere" with any
+ of the following names:
+
+ NotHereConfig.cmake
+ nothere-config.cmake
+
+ Add the installation prefix of "NotHere" to CMAKE_PREFIX_PATH or set
+ "NotHere_DIR" to a directory containing one of the above files. If
+ "NotHere" provides a separate development package or SDK, be sure it has
+ been installed.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/find_package/MissingNormalRequired.cmake b/Tests/RunCMake/find_package/MissingNormalRequired.cmake
new file mode 100644
index 000000000..33353d8cd
--- /dev/null
+++ b/Tests/RunCMake/find_package/MissingNormalRequired.cmake
@@ -0,0 +1,2 @@
+find_package(NotHere REQUIRED)
+message(FATAL_ERROR "This error must not be reachable.")
diff --git a/Tests/RunCMake/find_package/MissingNormalVersion-stderr.txt b/Tests/RunCMake/find_package/MissingNormalVersion-stderr.txt
new file mode 100644
index 000000000..36de8009e
--- /dev/null
+++ b/Tests/RunCMake/find_package/MissingNormalVersion-stderr.txt
@@ -0,0 +1,17 @@
+CMake Warning at MissingNormalVersion.cmake:1 \(find_package\):
+ By not providing "FindNotHere.cmake" in CMAKE_MODULE_PATH this project has
+ asked CMake to find a package configuration file provided by "NotHere", but
+ CMake did not find one.
+
+ Could not find a package configuration file provided by "NotHere"
+ \(requested version 1\.2\) with any of the following names:
+
+ NotHereConfig.cmake
+ nothere-config.cmake
+
+ Add the installation prefix of "NotHere" to CMAKE_PREFIX_PATH or set
+ "NotHere_DIR" to a directory containing one of the above files. If
+ "NotHere" provides a separate development package or SDK, be sure it has
+ been installed.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/find_package/MissingNormalVersion.cmake b/Tests/RunCMake/find_package/MissingNormalVersion.cmake
new file mode 100644
index 000000000..2d9ce4ea5
--- /dev/null
+++ b/Tests/RunCMake/find_package/MissingNormalVersion.cmake
@@ -0,0 +1 @@
+find_package(NotHere 1.2)
diff --git a/Tests/RunCMake/find_package/MissingNormalWarnNoModuleNew-stderr.txt b/Tests/RunCMake/find_package/MissingNormalWarnNoModuleNew-stderr.txt
new file mode 100644
index 000000000..d34f23c8f
--- /dev/null
+++ b/Tests/RunCMake/find_package/MissingNormalWarnNoModuleNew-stderr.txt
@@ -0,0 +1,30 @@
+CMake Warning \(dev\) at MissingNormalWarnNoModuleNew.cmake:3 \(find_package\):
+ find_package called without either MODULE or CONFIG option and no
+ FindNotHere.cmake module is in CMAKE_MODULE_PATH. Add MODULE to
+ exclusively request Module mode and fail if FindNotHere.cmake is missing.
+ Add CONFIG to exclusively request Config mode and search for a package
+ configuration file provided by NotHere \(NotHereConfig.cmake or
+ nothere-config.cmake\).
+
+ \(Variable CMAKE_FIND_PACKAGE_WARN_NO_MODULE enabled 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 Warning at MissingNormalWarnNoModuleNew.cmake:3 \(find_package\):
+ By not providing "FindNotHere.cmake" in CMAKE_MODULE_PATH this project has
+ asked CMake to find a package configuration file provided by "NotHere", but
+ CMake did not find one.
+
+ Could not find a package configuration file provided by "NotHere" with any
+ of the following names:
+
+ NotHereConfig.cmake
+ nothere-config.cmake
+
+ Add the installation prefix of "NotHere" to CMAKE_PREFIX_PATH or set
+ "NotHere_DIR" to a directory containing one of the above files. If
+ "NotHere" provides a separate development package or SDK, be sure it has
+ been installed.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/find_package/MissingNormalWarnNoModuleNew.cmake b/Tests/RunCMake/find_package/MissingNormalWarnNoModuleNew.cmake
new file mode 100644
index 000000000..0211249c6
--- /dev/null
+++ b/Tests/RunCMake/find_package/MissingNormalWarnNoModuleNew.cmake
@@ -0,0 +1,3 @@
+set(CMAKE_FIND_PACKAGE_WARN_NO_MODULE 1)
+set(CMAKE_MINIMUM_REQUIRED_VERSION 2.8.8)
+find_package(NotHere)
diff --git a/Tests/RunCMake/find_package/MissingNormalWarnNoModuleOld-stderr.txt b/Tests/RunCMake/find_package/MissingNormalWarnNoModuleOld-stderr.txt
new file mode 100644
index 000000000..b336b5621
--- /dev/null
+++ b/Tests/RunCMake/find_package/MissingNormalWarnNoModuleOld-stderr.txt
@@ -0,0 +1,29 @@
+CMake Warning \(dev\) at MissingNormalWarnNoModuleOld.cmake:2 \(find_package\):
+ find_package called without NO_MODULE option and no FindNotHere.cmake
+ module is in CMAKE_MODULE_PATH. Add NO_MODULE to exclusively request
+ Config mode and search for a package configuration file provided by NotHere
+ \(NotHereConfig.cmake or nothere-config.cmake\). Otherwise make
+ FindNotHere.cmake available in CMAKE_MODULE_PATH.
+
+ \(Variable CMAKE_FIND_PACKAGE_WARN_NO_MODULE enabled 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 Warning at MissingNormalWarnNoModuleOld.cmake:2 \(find_package\):
+ By not providing "FindNotHere.cmake" in CMAKE_MODULE_PATH this project has
+ asked CMake to find a package configuration file provided by "NotHere", but
+ CMake did not find one.
+
+ Could not find a package configuration file provided by "NotHere" with any
+ of the following names:
+
+ NotHereConfig.cmake
+ nothere-config.cmake
+
+ Add the installation prefix of "NotHere" to CMAKE_PREFIX_PATH or set
+ "NotHere_DIR" to a directory containing one of the above files. If
+ "NotHere" provides a separate development package or SDK, be sure it has
+ been installed.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/find_package/MissingNormalWarnNoModuleOld.cmake b/Tests/RunCMake/find_package/MissingNormalWarnNoModuleOld.cmake
new file mode 100644
index 000000000..1c4a77599
--- /dev/null
+++ b/Tests/RunCMake/find_package/MissingNormalWarnNoModuleOld.cmake
@@ -0,0 +1,2 @@
+set(CMAKE_FIND_PACKAGE_WARN_NO_MODULE 1)
+find_package(NotHere)
diff --git a/Tests/RunCMake/find_package/MixedModeOptions-result.txt b/Tests/RunCMake/find_package/MixedModeOptions-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/find_package/MixedModeOptions-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/find_package/MixedModeOptions-stderr.txt b/Tests/RunCMake/find_package/MixedModeOptions-stderr.txt
new file mode 100644
index 000000000..b8670221b
--- /dev/null
+++ b/Tests/RunCMake/find_package/MixedModeOptions-stderr.txt
@@ -0,0 +1,14 @@
+CMake Error at MixedModeOptions.cmake:1 \(find_package\):
+ find_package given options exclusive to Module mode:
+
+ MODULE
+
+ and options exclusive to Config mode:
+
+ CONFIG
+ CONFIGS
+ NO_DEFAULT_PATH
+
+ The options are incompatible.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/find_package/MixedModeOptions.cmake b/Tests/RunCMake/find_package/MixedModeOptions.cmake
new file mode 100644
index 000000000..7f78ee05f
--- /dev/null
+++ b/Tests/RunCMake/find_package/MixedModeOptions.cmake
@@ -0,0 +1 @@
+find_package(NotHere MODULE CONFIG CONFIGS NotHereConfig.cmake NO_DEFAULT_PATH)
diff --git a/Tests/RunCMake/find_package/RunCMakeTest.cmake b/Tests/RunCMake/find_package/RunCMakeTest.cmake
new file mode 100644
index 000000000..42705b77a
--- /dev/null
+++ b/Tests/RunCMake/find_package/RunCMakeTest.cmake
@@ -0,0 +1,16 @@
+include(RunCMake)
+
+run_cmake(ComponentRequiredAndOptional)
+run_cmake(MissingNormal)
+run_cmake(MissingNormalRequired)
+run_cmake(MissingNormalVersion)
+run_cmake(MissingNormalWarnNoModuleOld)
+run_cmake(MissingNormalWarnNoModuleNew)
+run_cmake(MissingModule)
+run_cmake(MissingModuleRequired)
+run_cmake(MissingConfig)
+run_cmake(MissingConfigOneName)
+run_cmake(MissingConfigRequired)
+run_cmake(MissingConfigVersion)
+run_cmake(MixedModeOptions)
+run_cmake(SetFoundFALSE)
diff --git a/Tests/RunCMake/find_package/SetFoundFALSE-stderr.txt b/Tests/RunCMake/find_package/SetFoundFALSE-stderr.txt
new file mode 100644
index 000000000..695f6450d
--- /dev/null
+++ b/Tests/RunCMake/find_package/SetFoundFALSE-stderr.txt
@@ -0,0 +1,9 @@
+CMake Warning at SetFoundFALSE.cmake:2 \(find_package\):
+ Found package configuration file:
+
+ .*/Tests/RunCMake/find_package/SetFoundFALSEConfig.cmake
+
+ but it set SetFoundFALSE_FOUND to FALSE so package "SetFoundFALSE" is
+ considered to be NOT FOUND.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/find_package/SetFoundFALSE.cmake b/Tests/RunCMake/find_package/SetFoundFALSE.cmake
new file mode 100644
index 000000000..fbcec3c56
--- /dev/null
+++ b/Tests/RunCMake/find_package/SetFoundFALSE.cmake
@@ -0,0 +1,2 @@
+set(SetFoundFALSE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
+find_package(SetFoundFALSE CONFIG)
diff --git a/Tests/RunCMake/find_package/SetFoundFALSEConfig.cmake b/Tests/RunCMake/find_package/SetFoundFALSEConfig.cmake
new file mode 100644
index 000000000..ae6bd1454
--- /dev/null
+++ b/Tests/RunCMake/find_package/SetFoundFALSEConfig.cmake
@@ -0,0 +1 @@
+set(SetFoundFALSE_FOUND FALSE)
diff --git a/Tests/RunCMake/include/CMakeLists.txt b/Tests/RunCMake/include/CMakeLists.txt
new file mode 100644
index 000000000..e8db6b05b
--- /dev/null
+++ b/Tests/RunCMake/include/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/include/EmptyString-stderr.txt b/Tests/RunCMake/include/EmptyString-stderr.txt
new file mode 100644
index 000000000..006c647c6
--- /dev/null
+++ b/Tests/RunCMake/include/EmptyString-stderr.txt
@@ -0,0 +1,5 @@
+CMake Warning \(dev\) at EmptyString.cmake:1 \(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/include/EmptyString.cmake b/Tests/RunCMake/include/EmptyString.cmake
new file mode 100644
index 000000000..4285cb3d5
--- /dev/null
+++ b/Tests/RunCMake/include/EmptyString.cmake
@@ -0,0 +1 @@
+include("")
diff --git a/Tests/RunCMake/include/EmptyStringOptional-stderr.txt b/Tests/RunCMake/include/EmptyStringOptional-stderr.txt
new file mode 100644
index 000000000..b61c67912
--- /dev/null
+++ b/Tests/RunCMake/include/EmptyStringOptional-stderr.txt
@@ -0,0 +1,5 @@
+CMake Warning \(dev\) at EmptyStringOptional.cmake:1 \(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/include/EmptyStringOptional.cmake b/Tests/RunCMake/include/EmptyStringOptional.cmake
new file mode 100644
index 000000000..549d46b3d
--- /dev/null
+++ b/Tests/RunCMake/include/EmptyStringOptional.cmake
@@ -0,0 +1 @@
+include("" OPTIONAL)
diff --git a/Tests/RunCMake/include/RunCMakeTest.cmake b/Tests/RunCMake/include/RunCMakeTest.cmake
new file mode 100644
index 000000000..59b87ca75
--- /dev/null
+++ b/Tests/RunCMake/include/RunCMakeTest.cmake
@@ -0,0 +1,4 @@
+include(RunCMake)
+
+run_cmake(EmptyString)
+run_cmake(EmptyStringOptional)
diff --git a/Tests/RunCMake/include_external_msproject/CMakeLists.txt b/Tests/RunCMake/include_external_msproject/CMakeLists.txt
new file mode 100644
index 000000000..e8db6b05b
--- /dev/null
+++ b/Tests/RunCMake/include_external_msproject/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/include_external_msproject/CustomGuid-check.cmake b/Tests/RunCMake/include_external_msproject/CustomGuid-check.cmake
new file mode 100644
index 000000000..68dec4c08
--- /dev/null
+++ b/Tests/RunCMake/include_external_msproject/CustomGuid-check.cmake
@@ -0,0 +1 @@
+check_project(CustomGuid external "aaa-bbb-ccc-000" "" "")
diff --git a/Tests/RunCMake/include_external_msproject/CustomGuid.cmake b/Tests/RunCMake/include_external_msproject/CustomGuid.cmake
new file mode 100644
index 000000000..1dbe7da05
--- /dev/null
+++ b/Tests/RunCMake/include_external_msproject/CustomGuid.cmake
@@ -0,0 +1,2 @@
+include_external_msproject(external external.project
+ GUID aaa-bbb-ccc-000)
diff --git a/Tests/RunCMake/include_external_msproject/CustomGuidTypePlatform-check.cmake b/Tests/RunCMake/include_external_msproject/CustomGuidTypePlatform-check.cmake
new file mode 100644
index 000000000..614712ee6
--- /dev/null
+++ b/Tests/RunCMake/include_external_msproject/CustomGuidTypePlatform-check.cmake
@@ -0,0 +1 @@
+check_project(CustomGuidTypePlatform external "aaa-bbb-ccc-111" "aaa-bbb-ccc-ddd-eee" "Custom Platform")
diff --git a/Tests/RunCMake/include_external_msproject/CustomGuidTypePlatform.cmake b/Tests/RunCMake/include_external_msproject/CustomGuidTypePlatform.cmake
new file mode 100644
index 000000000..ee4db655f
--- /dev/null
+++ b/Tests/RunCMake/include_external_msproject/CustomGuidTypePlatform.cmake
@@ -0,0 +1,5 @@
+# Test all optional parameters are set.
+include_external_msproject(external external.project
+ GUID aaa-bbb-ccc-111
+ TYPE aaa-bbb-ccc-ddd-eee
+ PLATFORM "Custom Platform")
diff --git a/Tests/RunCMake/include_external_msproject/CustomTypePlatform-check.cmake b/Tests/RunCMake/include_external_msproject/CustomTypePlatform-check.cmake
new file mode 100644
index 000000000..054eeb037
--- /dev/null
+++ b/Tests/RunCMake/include_external_msproject/CustomTypePlatform-check.cmake
@@ -0,0 +1 @@
+check_project(CustomTypePlatform external "" "aaa-bbb-ccc-ddd-eee" "Custom Platform")
diff --git a/Tests/RunCMake/include_external_msproject/CustomTypePlatform.cmake b/Tests/RunCMake/include_external_msproject/CustomTypePlatform.cmake
new file mode 100644
index 000000000..8c76adbc8
--- /dev/null
+++ b/Tests/RunCMake/include_external_msproject/CustomTypePlatform.cmake
@@ -0,0 +1,3 @@
+include_external_msproject(external external.project
+ TYPE aaa-bbb-ccc-ddd-eee
+ PLATFORM "Custom Platform")
diff --git a/Tests/RunCMake/include_external_msproject/RunCMakeTest.cmake b/Tests/RunCMake/include_external_msproject/RunCMakeTest.cmake
new file mode 100644
index 000000000..90710f9bf
--- /dev/null
+++ b/Tests/RunCMake/include_external_msproject/RunCMakeTest.cmake
@@ -0,0 +1,6 @@
+include(RunCMake)
+include(${CMAKE_CURRENT_LIST_DIR}/check_utils.cmake)
+
+run_cmake(CustomGuid)
+run_cmake(CustomTypePlatform)
+run_cmake(CustomGuidTypePlatform)
diff --git a/Tests/RunCMake/include_external_msproject/check_utils.cmake b/Tests/RunCMake/include_external_msproject/check_utils.cmake
new file mode 100644
index 000000000..7d6b8f8ea
--- /dev/null
+++ b/Tests/RunCMake/include_external_msproject/check_utils.cmake
@@ -0,0 +1,109 @@
+# Check that file contains line that matches regular expression.
+# Sets IS_FOUND variable to TRUE if found and to FALSE otherwise.
+macro(check_line_exists TARGET_FILE REG_EXP_REF)
+ set(IS_FOUND "FALSE")
+
+ file(STRINGS ${TARGET_FILE} FOUND_LINE LIMIT_COUNT 1 REGEX "${${REG_EXP_REF}}")
+ list(LENGTH FOUND_LINE _VAR_LEN)
+
+ if(_VAR_LEN GREATER 0)
+ set(IS_FOUND "TRUE")
+ endif(_VAR_LEN GREATER 0)
+endmacro(check_line_exists TARGET_FILE REG_EXP_REF)
+
+# Search and parse project section line by project name.
+# If search was successful stores found type and guid into FOUND_TYPE and FOUND_GUID variables respectively.
+# Sets IS_FOUND variable to TRUE if found and to FALSE otherwise.
+macro(parse_project_section TARGET_FILE PROJECT_NAME)
+ set(REG_EXP "^Project\\(\\\"{(.+)}\\\"\\) = \\\"${PROJECT_NAME}\\\", \\\".+\\..+\\\", \\\"{(.+)}\\\"$")
+
+ check_line_exists(${TARGET_FILE} REG_EXP)
+ if(NOT IS_FOUND)
+ return()
+ endif(NOT IS_FOUND)
+
+ string(REGEX REPLACE "${REG_EXP}" "\\1;\\2" _GUIDS "${FOUND_LINE}")
+
+ list(GET _GUIDS 0 FOUND_TYPE)
+ list(GET _GUIDS 1 FOUND_GUID)
+endmacro(parse_project_section TARGET_FILE PROJECT_NAME)
+
+# Search project section line by project name and type.
+# Returns TRUE if found and FALSE otherwise
+function(check_project_type TARGET_FILE PROJECT_NAME PROJECT_TYPE RESULT)
+ set(${RESULT} "FALSE" PARENT_SCOPE)
+
+ parse_project_section(${TARGET_FILE} ${PROJECT_NAME})
+ if(IS_FOUND AND FOUND_TYPE STREQUAL PROJECT_TYPE)
+ set(${RESULT} "TRUE" PARENT_SCOPE)
+ endif(IS_FOUND AND FOUND_TYPE STREQUAL PROJECT_TYPE)
+endfunction(check_project_type TARGET_FILE PROJECT_NAME PROJECT_TYPE RESULT)
+
+
+# Search project section line by project name and id.
+# Returns TRUE if found and FALSE otherwise
+function(check_project_guid TARGET_FILE PROJECT_NAME PROJECT_GUID RESULT)
+ set(${RESULT} "FALSE" PARENT_SCOPE)
+
+ parse_project_section(${TARGET_FILE} ${PROJECT_NAME})
+ if(IS_FOUND AND FOUND_GUID STREQUAL PROJECT_GUID)
+ set(${RESULT} "TRUE" PARENT_SCOPE)
+ endif(IS_FOUND AND FOUND_GUID STREQUAL PROJECT_GUID)
+endfunction(check_project_guid TARGET_FILE PROJECT_NAME PROJECT_GUID RESULT)
+
+
+# Search project's build configuration line by project name and target platform name.
+# Returns TRUE if found and FALSE otherwise
+function(check_custom_platform TARGET_FILE PROJECT_NAME PLATFORM_NAME RESULT)
+ set(${RESULT} "FALSE" PARENT_SCOPE)
+
+ # extract project guid
+ parse_project_section(${TARGET_FILE} ${PROJECT_NAME})
+ if(NOT IS_FOUND)
+ return()
+ endif(NOT IS_FOUND)
+
+ # probably whould be better to use configuration name
+ # extracted from CMAKE_CONFIGURATION_TYPES than just hardcoded "Debug" instead
+ set(REG_EXP "^(\t)*\\{${FOUND_GUID}\\}\\.Debug[^ ]*\\.ActiveCfg = Debug\\|${PLATFORM_NAME}$")
+ check_line_exists(${TARGET_FILE} REG_EXP)
+
+ set(${RESULT} ${IS_FOUND} PARENT_SCOPE)
+endfunction(check_custom_platform TARGET_FILE PLATFORM_NAME RESULT)
+
+# RunCMake test check helper
+function(check_project test name guid type platform)
+ set(sln "${RunCMake_TEST_BINARY_DIR}/${test}.sln")
+ set(sep "")
+ set(failed "")
+ if(NOT type)
+ set(type 8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942)
+ endif()
+ if(NOT platform)
+ if("${RunCMake_GENERATOR}" MATCHES "Win64")
+ set(platform "x64")
+ else()
+ set(platform "Win32")
+ endif()
+ endif()
+ if(guid)
+ check_project_guid("${sln}" "${name}" "${guid}" passed_guid)
+ if(NOT passed_guid)
+ set(failed "${failed}${sep}${name} solution has no project with expected GUID=${guid}")
+ set(sep "\n")
+ endif()
+ else()
+ set(passed_guid 1)
+ endif()
+ check_project_type("${sln}" "${name}" "${type}" passed_type)
+ if(NOT passed_type)
+ set(failed "${failed}${sep}${name} solution has no project with expected TYPE=${type}")
+ set(sep "\n")
+ endif()
+ check_custom_platform("${sln}" "${name}" "${platform}" passed_platform)
+ if(NOT passed_platform)
+ set(failed "${failed}${sep}${name} solution has no project with expected PLATFORM=${platform}")
+ set(sep "\n")
+ endif()
+ set(RunCMake_TEST_FAILED "${failed}" PARENT_SCOPE)
+endfunction()
diff --git a/Tests/RunCMake/include_external_msproject/main.cpp b/Tests/RunCMake/include_external_msproject/main.cpp
new file mode 100644
index 000000000..919810306
--- /dev/null
+++ b/Tests/RunCMake/include_external_msproject/main.cpp
@@ -0,0 +1,3 @@
+void main()
+{
+}
diff --git a/Tests/RunCMake/list/CMakeLists.txt b/Tests/RunCMake/list/CMakeLists.txt
new file mode 100644
index 000000000..e8db6b05b
--- /dev/null
+++ b/Tests/RunCMake/list/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/list/EmptyGet0-result.txt b/Tests/RunCMake/list/EmptyGet0-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/list/EmptyGet0-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/EmptyGet0-stderr.txt b/Tests/RunCMake/list/EmptyGet0-stderr.txt
new file mode 100644
index 000000000..0c61b011f
--- /dev/null
+++ b/Tests/RunCMake/list/EmptyGet0-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at EmptyGet0.cmake:2 \(list\):
+ list GET given empty list
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/EmptyGet0.cmake b/Tests/RunCMake/list/EmptyGet0.cmake
new file mode 100644
index 000000000..494710825
--- /dev/null
+++ b/Tests/RunCMake/list/EmptyGet0.cmake
@@ -0,0 +1,2 @@
+set(mylist "")
+list(GET mylist 0 result)
diff --git a/Tests/RunCMake/list/EmptyInsert-1-result.txt b/Tests/RunCMake/list/EmptyInsert-1-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/list/EmptyInsert-1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/EmptyInsert-1-stderr.txt b/Tests/RunCMake/list/EmptyInsert-1-stderr.txt
new file mode 100644
index 000000000..0900ff941
--- /dev/null
+++ b/Tests/RunCMake/list/EmptyInsert-1-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at EmptyInsert-1.cmake:2 \(list\):
+ list index: -1 out of range \(0, 0\)
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/EmptyInsert-1.cmake b/Tests/RunCMake/list/EmptyInsert-1.cmake
new file mode 100644
index 000000000..140da5d07
--- /dev/null
+++ b/Tests/RunCMake/list/EmptyInsert-1.cmake
@@ -0,0 +1,2 @@
+set(mylist "")
+list(INSERT mylist -1 x)
diff --git a/Tests/RunCMake/list/EmptyRemoveAt0-result.txt b/Tests/RunCMake/list/EmptyRemoveAt0-result.txt
new file mode 100644
index 000000000..d00491fd7
--- /dev/null
+++ b/Tests/RunCMake/list/EmptyRemoveAt0-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/list/EmptyRemoveAt0-stderr.txt b/Tests/RunCMake/list/EmptyRemoveAt0-stderr.txt
new file mode 100644
index 000000000..b24a0ed0b
--- /dev/null
+++ b/Tests/RunCMake/list/EmptyRemoveAt0-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at EmptyRemoveAt0.cmake:2 \(list\):
+ list REMOVE_AT given empty list
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/EmptyRemoveAt0.cmake b/Tests/RunCMake/list/EmptyRemoveAt0.cmake
new file mode 100644
index 000000000..d6a3e85c6
--- /dev/null
+++ b/Tests/RunCMake/list/EmptyRemoveAt0.cmake
@@ -0,0 +1,2 @@
+set(mylist "")
+list(REMOVE_AT mylist 0)
diff --git a/Tests/RunCMake/list/RunCMakeTest.cmake b/Tests/RunCMake/list/RunCMakeTest.cmake
new file mode 100644
index 000000000..555051de0
--- /dev/null
+++ b/Tests/RunCMake/list/RunCMakeTest.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+run_cmake(EmptyGet0)
+run_cmake(EmptyRemoveAt0)
+run_cmake(EmptyInsert-1)
diff --git a/Tests/RuntimePath/CMakeLists.txt b/Tests/RuntimePath/CMakeLists.txt
new file mode 100644
index 000000000..2164cdb8d
--- /dev/null
+++ b/Tests/RuntimePath/CMakeLists.txt
@@ -0,0 +1,33 @@
+cmake_minimum_required (VERSION 2.6)
+project(RuntimePath C)
+
+# Add a simple chain of shared libraries that must be found.
+add_library(foo1 SHARED foo1.c)
+set_property(TARGET foo1 PROPERTY OUTPUT_NAME foo)
+set_property(TARGET foo1 PROPERTY LIBRARY_OUTPUT_DIRECTORY A)
+
+add_library(bar1 SHARED bar1.c)
+set_property(TARGET bar1 PROPERTY OUTPUT_NAME bar)
+set_property(TARGET bar1 PROPERTY VERSION 1)
+set_property(TARGET bar1 PROPERTY LIBRARY_OUTPUT_DIRECTORY B)
+target_link_libraries(bar1 foo1)
+
+add_executable(RuntimePath main.c)
+target_link_libraries(RuntimePath bar1)
+
+# Add a library that provides a conflicting location to make sure
+# rpath ordering works.
+add_library(foo2 SHARED foo2.c)
+set_property(TARGET foo2 PROPERTY OUTPUT_NAME foo)
+set_property(TARGET foo2 PROPERTY LIBRARY_OUTPUT_DIRECTORY B)
+
+# Add a library that would provide a conflicting location if not for
+# soname analysis in rpath ordering. This will also break the old
+# link directory ordering to make sure files are linked with full
+# paths.
+if(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG)
+ add_library(bar2 SHARED bar2.c)
+ set_property(TARGET bar2 PROPERTY OUTPUT_NAME bar)
+ set_property(TARGET bar2 PROPERTY LIBRARY_OUTPUT_DIRECTORY A)
+ target_link_libraries(bar2 foo2)
+endif(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG)
diff --git a/Tests/RuntimePath/bar1.c b/Tests/RuntimePath/bar1.c
new file mode 100644
index 000000000..ebad8d20c
--- /dev/null
+++ b/Tests/RuntimePath/bar1.c
@@ -0,0 +1,2 @@
+extern int foo1();
+int bar1() { return foo1(); }
diff --git a/Tests/RuntimePath/bar2.c b/Tests/RuntimePath/bar2.c
new file mode 100644
index 000000000..60d5e686a
--- /dev/null
+++ b/Tests/RuntimePath/bar2.c
@@ -0,0 +1,2 @@
+extern int foo2();
+int bar2() { return foo2(); }
diff --git a/Tests/RuntimePath/foo1.c b/Tests/RuntimePath/foo1.c
new file mode 100644
index 000000000..27cd9125b
--- /dev/null
+++ b/Tests/RuntimePath/foo1.c
@@ -0,0 +1 @@
+int foo1() { return 0; }
diff --git a/Tests/RuntimePath/foo2.c b/Tests/RuntimePath/foo2.c
new file mode 100644
index 000000000..40b4f56a9
--- /dev/null
+++ b/Tests/RuntimePath/foo2.c
@@ -0,0 +1 @@
+int foo2() { return 0; }
diff --git a/Tests/RuntimePath/main.c b/Tests/RuntimePath/main.c
new file mode 100644
index 000000000..c71ee0639
--- /dev/null
+++ b/Tests/RuntimePath/main.c
@@ -0,0 +1,5 @@
+extern int bar1();
+int main()
+{
+ return bar1();
+}
diff --git a/Tests/SBCS/CMakeLists.txt b/Tests/SBCS/CMakeLists.txt
new file mode 100644
index 000000000..b3c3c2cfc
--- /dev/null
+++ b/Tests/SBCS/CMakeLists.txt
@@ -0,0 +1,6 @@
+# a SBCS test case
+project (SBCS)
+
+add_definitions(-D_SBCS)
+
+add_executable (SBCS SBCS.cxx)
diff --git a/Tests/SBCS/SBCS.cxx b/Tests/SBCS/SBCS.cxx
new file mode 100644
index 000000000..6ce2c9f25
--- /dev/null
+++ b/Tests/SBCS/SBCS.cxx
@@ -0,0 +1,22 @@
+// Test to verify that _SBCS being defined causes CharacterSet to be set to 0 (Single Byte Character Set)
+
+int main ()
+{
+#ifdef _UNICODE
+ bool UnicodeSet=true;
+#else
+ bool UnicodeSet=false;
+#endif
+
+#ifdef _MBCS
+ bool MBCSSet=true;
+#else
+ bool MBCSSet=false;
+#endif
+
+ // if neither _UNICODE nor _MBCS is set, CharacterSet must be set to SBCS.
+ bool SBCSSet=(!UnicodeSet && !MBCSSet);
+
+ // Reverse boolean to indicate error case correctly
+ return !SBCSSet;
+}
diff --git a/Tests/SameName/CMakeLists.txt b/Tests/SameName/CMakeLists.txt
new file mode 100644
index 000000000..a4b993cfd
--- /dev/null
+++ b/Tests/SameName/CMakeLists.txt
@@ -0,0 +1,7 @@
+cmake_minimum_required (VERSION 2.6)
+PROJECT(SameName C)
+
+ADD_SUBDIRECTORY(Lib1)
+
+INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/Lib1)
+ADD_SUBDIRECTORY(Exe1)
diff --git a/Tests/SameName/Exe1/CMakeLists.txt b/Tests/SameName/Exe1/CMakeLists.txt
new file mode 100644
index 000000000..3917a2f6b
--- /dev/null
+++ b/Tests/SameName/Exe1/CMakeLists.txt
@@ -0,0 +1,11 @@
+# a target with the same name as a target in a different dir
+ADD_EXECUTABLE(mytest_exe conly.c)
+SET_TARGET_PROPERTIES(mytest_exe PROPERTIES OUTPUT_NAME mytest)
+TARGET_LINK_LIBRARIES(mytest_exe mytest)
+
+# and two targets in the same dir with the same name
+ADD_LIBRARY(mytest2 ../Lib1/libc1.c)
+
+ADD_EXECUTABLE(mytest2_exe conly.c)
+SET_TARGET_PROPERTIES(mytest2_exe PROPERTIES OUTPUT_NAME mytest2)
+TARGET_LINK_LIBRARIES(mytest2_exe mytest2)
diff --git a/Tests/SameName/Exe1/conly.c b/Tests/SameName/Exe1/conly.c
new file mode 100644
index 000000000..eb62c301a
--- /dev/null
+++ b/Tests/SameName/Exe1/conly.c
@@ -0,0 +1,12 @@
+#include "libc1.h"
+#include <stdio.h>
+
+int main ()
+{
+ if ( LibC1Func() != 2.0 )
+ {
+ printf("Problem with libc1\n");
+ return 1;
+ }
+ return 0;
+}
diff --git a/Tests/SameName/Lib1/CMakeLists.txt b/Tests/SameName/Lib1/CMakeLists.txt
new file mode 100644
index 000000000..67e7f6843
--- /dev/null
+++ b/Tests/SameName/Lib1/CMakeLists.txt
@@ -0,0 +1 @@
+ADD_LIBRARY(mytest libc1.c)
diff --git a/Tests/SameName/Lib1/libc1.c b/Tests/SameName/Lib1/libc1.c
new file mode 100644
index 000000000..b01e1e1b5
--- /dev/null
+++ b/Tests/SameName/Lib1/libc1.c
@@ -0,0 +1,4 @@
+float LibC1Func()
+{
+ return 2.0;
+}
diff --git a/Tests/SameName/Lib1/libc1.h b/Tests/SameName/Lib1/libc1.h
new file mode 100644
index 000000000..84c94a9cb
--- /dev/null
+++ b/Tests/SameName/Lib1/libc1.h
@@ -0,0 +1 @@
+extern float LibC1Func();
diff --git a/Tests/SetLang/CMakeLists.txt b/Tests/SetLang/CMakeLists.txt
new file mode 100644
index 000000000..ab6570c33
--- /dev/null
+++ b/Tests/SetLang/CMakeLists.txt
@@ -0,0 +1,10 @@
+# test forcing a source file language to c++ from c
+cmake_minimum_required (VERSION 2.6)
+project(SetLang)
+# force this to be verbose so I can debug a dashboard entry
+SET(CMAKE_VERBOSE_MAKEFILE 1)
+add_library(foo foo.c)
+add_executable(SetLang bar.c)
+set_source_files_properties(foo.c bar.c PROPERTIES LANGUAGE CXX)
+target_link_libraries(SetLang foo)
+set_target_properties(SetLang PROPERTIES LINKER_LANGUAGE CXX)
diff --git a/Tests/SetLang/bar.c b/Tests/SetLang/bar.c
new file mode 100644
index 000000000..f59c318b1
--- /dev/null
+++ b/Tests/SetLang/bar.c
@@ -0,0 +1,21 @@
+#include <stdio.h>
+
+int foo();
+class A
+{
+public:
+ A() {this->i = foo();}
+ int i;
+};
+
+int main()
+{
+ A a;
+ if(a.i == 21)
+ {
+ printf("passed foo is 21\n");
+ return 0;
+ }
+ printf("Failed foo is not 21\n");
+ return -1;
+}
diff --git a/Tests/SetLang/foo.c b/Tests/SetLang/foo.c
new file mode 100644
index 000000000..e7918af58
--- /dev/null
+++ b/Tests/SetLang/foo.c
@@ -0,0 +1,7 @@
+int foo()
+{
+ int r = 10;
+ r++;
+ int ret = r+10;
+ return ret;
+}
diff --git a/Tests/Simple/CMakeLists.txt b/Tests/Simple/CMakeLists.txt
new file mode 100644
index 000000000..dc965a733
--- /dev/null
+++ b/Tests/Simple/CMakeLists.txt
@@ -0,0 +1,17 @@
+# a simple test case
+project (Simple)
+
+add_executable (Simple simple.cxx)
+
+add_library (simpleLib STATIC
+ simpleLib.cxx
+ simpleCLib.c
+ simpleWe.cpp
+ )
+
+target_link_libraries (Simple simpleLib)
+
+# make sure optimized libs are not used by debug builds
+if(CMAKE_BUILD_TYPE MATCHES Debug)
+ target_link_libraries(Simple optimized c:/not/here.lib )
+endif(CMAKE_BUILD_TYPE MATCHES Debug)
diff --git a/Tests/Simple/simple.cxx b/Tests/Simple/simple.cxx
new file mode 100644
index 000000000..7bee7c074
--- /dev/null
+++ b/Tests/Simple/simple.cxx
@@ -0,0 +1,11 @@
+extern void simpleLib();
+extern "C" int FooBar();
+extern int bar();
+extern int bar1();
+int main ()
+{
+ FooBar();
+ bar();
+ simpleLib();
+ return 0;
+}
diff --git a/Tests/Simple/simpleCLib.c b/Tests/Simple/simpleCLib.c
new file mode 100644
index 000000000..88fc33efc
--- /dev/null
+++ b/Tests/Simple/simpleCLib.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+
+int FooBar()
+{
+ int class;
+ int private = 10;
+ for ( class = 0; class < private; class ++ )
+ {
+ printf("Count: %d/%d\n", class, private);
+ }
+ return 0;
+}
diff --git a/Tests/Simple/simpleLib.cxx b/Tests/Simple/simpleLib.cxx
new file mode 100644
index 000000000..281d8885a
--- /dev/null
+++ b/Tests/Simple/simpleLib.cxx
@@ -0,0 +1,3 @@
+void simpleLib()
+{
+}
diff --git a/Tests/Simple/simpleWe.cpp b/Tests/Simple/simpleWe.cpp
new file mode 100644
index 000000000..859e07c06
--- /dev/null
+++ b/Tests/Simple/simpleWe.cpp
@@ -0,0 +1,17 @@
+#include <stdio.h>
+
+class Foo
+{
+public:
+ Foo()
+ {
+ printf("This one has nonstandard extension\n");
+ }
+ int getnum() { return 0; }
+};
+
+int bar()
+{
+ Foo f;
+ return f.getnum();
+}
diff --git a/Tests/SimpleCOnly/CMakeLists.txt b/Tests/SimpleCOnly/CMakeLists.txt
new file mode 100644
index 000000000..d0ed651b1
--- /dev/null
+++ b/Tests/SimpleCOnly/CMakeLists.txt
@@ -0,0 +1,17 @@
+# this enables only C, i.e. disables C++
+project(SimpleCOnly C)
+
+add_library(SimpleCLib STATIC bar.c foo.c)
+
+add_executable(SimpleC main.c)
+target_link_libraries(SimpleC SimpleCLib)
+
+# and some check, just to make sure it works:
+include(CheckTypeSize)
+check_type_size(float SIZE_FLOAT)
+message(STATUS "sizeof(float): ${SIZE_FLOAT}")
+
+# make sure optimized libs are not used by debug builds
+if(CMAKE_BUILD_TYPE MATCHES Debug)
+ target_link_libraries(Simple optimized c:/not/here.lib )
+endif(CMAKE_BUILD_TYPE MATCHES Debug)
diff --git a/Tests/SimpleCOnly/bar.c b/Tests/SimpleCOnly/bar.c
new file mode 100644
index 000000000..5d8eac09f
--- /dev/null
+++ b/Tests/SimpleCOnly/bar.c
@@ -0,0 +1 @@
+int bar() {return 5;}
diff --git a/Tests/SimpleCOnly/foo.c b/Tests/SimpleCOnly/foo.c
new file mode 100644
index 000000000..b8cdea427
--- /dev/null
+++ b/Tests/SimpleCOnly/foo.c
@@ -0,0 +1 @@
+int foo() { return 12;}
diff --git a/Tests/SimpleCOnly/main.c b/Tests/SimpleCOnly/main.c
new file mode 100644
index 000000000..e4df685cb
--- /dev/null
+++ b/Tests/SimpleCOnly/main.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+
+extern int foo();
+extern int bar();
+
+int main()
+{
+ int i=foo();
+ int k=bar();
+ i=i*k;
+ return i;
+}
diff --git a/Tests/SimpleExclude/CMakeLists.txt b/Tests/SimpleExclude/CMakeLists.txt
new file mode 100644
index 000000000..baca23e39
--- /dev/null
+++ b/Tests/SimpleExclude/CMakeLists.txt
@@ -0,0 +1,11 @@
+cmake_minimum_required (VERSION 2.6)
+project(SimpleExclude C)
+
+set(EXECUTABLE_OUTPUT_PATH "${SimpleExclude_BINARY_DIR}" CACHE INTERNAL "" FORCE)
+set(LIBRARY_OUTPUT_PATH "${SimpleExclude_BINARY_DIR}" CACHE INTERNAL "" FORCE)
+
+add_subdirectory(dirC EXCLUDE_FROM_ALL)
+add_subdirectory(dirD)
+
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/run.cmake.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/run.cmake" @ONLY)
diff --git a/Tests/SimpleExclude/dirC/CMakeLists.txt b/Tests/SimpleExclude/dirC/CMakeLists.txt
new file mode 100644
index 000000000..9b59fdaff
--- /dev/null
+++ b/Tests/SimpleExclude/dirC/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_subdirectory(dirA EXCLUDE_FROM_ALL)
+add_subdirectory(dirB)
+
diff --git a/Tests/SimpleExclude/dirC/dirA/CMakeLists.txt b/Tests/SimpleExclude/dirC/dirA/CMakeLists.txt
new file mode 100644
index 000000000..52fac8183
--- /dev/null
+++ b/Tests/SimpleExclude/dirC/dirA/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_library(t1 STATIC t1.c)
+
+add_library(t2 STATIC t2.c)
+
+add_executable(t3 t3.c)
+
+add_executable(t4 t4.c)
+
+add_executable(t5 t5.c)
+target_link_libraries(t5 t1)
diff --git a/Tests/SimpleExclude/dirC/dirA/t1.c b/Tests/SimpleExclude/dirC/dirA/t1.c
new file mode 100644
index 000000000..67fe06fee
--- /dev/null
+++ b/Tests/SimpleExclude/dirC/dirA/t1.c
@@ -0,0 +1,8 @@
+#include <stdio.h>
+
+int tlib1func()
+{
+ Should not be build unless target directory A, B, or C are build;
+ printf("This is T1\n");
+ return 5;
+}
diff --git a/Tests/SimpleExclude/dirC/dirA/t2.c b/Tests/SimpleExclude/dirC/dirA/t2.c
new file mode 100644
index 000000000..6aaf40675
--- /dev/null
+++ b/Tests/SimpleExclude/dirC/dirA/t2.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int tlib2func()
+{
+ printf("This is T2\n");
+ return 2;
+}
diff --git a/Tests/SimpleExclude/dirC/dirA/t3.c b/Tests/SimpleExclude/dirC/dirA/t3.c
new file mode 100644
index 000000000..1366dc0a6
--- /dev/null
+++ b/Tests/SimpleExclude/dirC/dirA/t3.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main(int argc, char* argv[])
+{
+ Should not be build unless target directory A, B, or C are build;
+ return 0;
+}
diff --git a/Tests/SimpleExclude/dirC/dirA/t4.c b/Tests/SimpleExclude/dirC/dirA/t4.c
new file mode 100644
index 000000000..7c36ca927
--- /dev/null
+++ b/Tests/SimpleExclude/dirC/dirA/t4.c
@@ -0,0 +1,17 @@
+#include <stdio.h>
+
+#ifdef __CLASSIC_C__
+int main()
+{
+ int ac;
+ char*av[];
+#else
+ int main(int ac, char*av[])
+ {
+#endif
+ if(ac > 1000){return *av[0];}
+ printf("This is T4. This one should work.\n");
+ return 0;
+ }
+
+
diff --git a/Tests/SimpleExclude/dirC/dirA/t5.c b/Tests/SimpleExclude/dirC/dirA/t5.c
new file mode 100644
index 000000000..1fba2127c
--- /dev/null
+++ b/Tests/SimpleExclude/dirC/dirA/t5.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main(int argc, char* argv[])
+{
+ Should not be build unless target directory A, B, or C are build;
+ return 5;
+}
diff --git a/Tests/SimpleExclude/dirC/dirB/CMakeLists.txt b/Tests/SimpleExclude/dirC/dirB/CMakeLists.txt
new file mode 100644
index 000000000..ea4650c4a
--- /dev/null
+++ b/Tests/SimpleExclude/dirC/dirB/CMakeLists.txt
@@ -0,0 +1,5 @@
+add_library(t6 STATIC t6.c)
+
+add_library(t7 STATIC t7.c)
+target_link_libraries(t7 t2)
+
diff --git a/Tests/SimpleExclude/dirC/dirB/t6.c b/Tests/SimpleExclude/dirC/dirB/t6.c
new file mode 100644
index 000000000..e8877df60
--- /dev/null
+++ b/Tests/SimpleExclude/dirC/dirB/t6.c
@@ -0,0 +1,8 @@
+#include <stdio.h>
+
+int tlib6func()
+{
+ Should not be build unless target directory B, or C are build;
+ printf("This is T6\n");
+ return 6;
+}
diff --git a/Tests/SimpleExclude/dirC/dirB/t7.c b/Tests/SimpleExclude/dirC/dirB/t7.c
new file mode 100644
index 000000000..b95d3ec43
--- /dev/null
+++ b/Tests/SimpleExclude/dirC/dirB/t7.c
@@ -0,0 +1,16 @@
+#include <stdio.h>
+
+extern int tlib2func();
+
+int tlib7func()
+{
+ printf("This is T7\n");
+
+ if ( tlib2func() != 2 )
+ {
+ fprintf(stderr, "Something wrong with T2\n");
+ return 1;
+ }
+
+ return 7;
+}
diff --git a/Tests/SimpleExclude/dirD/CMakeLists.txt b/Tests/SimpleExclude/dirD/CMakeLists.txt
new file mode 100644
index 000000000..44b8c27b6
--- /dev/null
+++ b/Tests/SimpleExclude/dirD/CMakeLists.txt
@@ -0,0 +1,7 @@
+add_library(t8 STATIC t8.c)
+
+add_executable(t9 t9.c)
+target_link_libraries(t9 t7)
+
+add_custom_target(t4_custom ALL)
+add_dependencies(t4_custom t4)
diff --git a/Tests/SimpleExclude/dirD/t8.c b/Tests/SimpleExclude/dirD/t8.c
new file mode 100644
index 000000000..bddec6f7e
--- /dev/null
+++ b/Tests/SimpleExclude/dirD/t8.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int tlib8func()
+{
+ printf("This is T8\n");
+ return 8;
+}
diff --git a/Tests/SimpleExclude/dirD/t9.c b/Tests/SimpleExclude/dirD/t9.c
new file mode 100644
index 000000000..321014b17
--- /dev/null
+++ b/Tests/SimpleExclude/dirD/t9.c
@@ -0,0 +1,24 @@
+#include <stdio.h>
+
+extern int tlib7func();
+
+#ifdef __CLASSIC_C__
+int main()
+{
+ int ac;
+ char*av[];
+#else
+ int main(int ac, char*av[])
+ {
+#endif
+ if(ac > 1000){return *av[0];}
+ printf("This is T9. This one should work.\n");
+
+ if ( tlib7func() != 7 )
+ {
+ fprintf(stderr, "Something wrong with T7\n");
+ return 1;
+ }
+ return 0;
+ }
+
diff --git a/Tests/SimpleExclude/run.cmake.in b/Tests/SimpleExclude/run.cmake.in
new file mode 100644
index 000000000..8f83380c8
--- /dev/null
+++ b/Tests/SimpleExclude/run.cmake.in
@@ -0,0 +1,13 @@
+set(t4_name "\"@CMAKE_CURRENT_BINARY_DIR@${CFG_DIR}/t4\"")
+exec_program("${t4_name}" RETURN_VALUE "t4_var")
+message("T4 ${t4_name} resulted ${t4_var}")
+
+set(t9_name "\"@CMAKE_CURRENT_BINARY_DIR@${CFG_DIR}/t9\"")
+exec_program("${t9_name}" RETURN_VALUE "t9_var")
+message("T9 ${t9_name} resulted ${t9_var}")
+
+if ( "${t4_var}" EQUAL "0" AND "${t9_var}" EQUAL "0" )
+ message("Everything is good, Yoshimi won...")
+else ( "${t4_var}" EQUAL "0" AND "${t9_var}" EQUAL "0" )
+ message(FATAL_ERROR "Yoshimi lost... The evil pink robots will take over the world")
+endif ( "${t4_var}" EQUAL "0" AND "${t9_var}" EQUAL "0" )
diff --git a/Tests/SimpleInstall/CMakeLists.txt b/Tests/SimpleInstall/CMakeLists.txt
new file mode 100644
index 000000000..378b5292b
--- /dev/null
+++ b/Tests/SimpleInstall/CMakeLists.txt
@@ -0,0 +1,398 @@
+cmake_minimum_required (VERSION 2.6)
+PROJECT (TestSimpleInstall)
+SET(CMAKE_VERBOSE_MAKEFILE 1)
+SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY
+ "${TestSimpleInstall_BINARY_DIR}/bin")
+SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY
+ "${TestSimpleInstall_BINARY_DIR}/lib/static")
+SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY
+ "${TestSimpleInstall_BINARY_DIR}/lib")
+
+# Skip generating the rpath pointing at the build tree to make sure
+# the executable is installed with the proper rpath in the install
+# tree.
+SET(CMAKE_SKIP_BUILD_RPATH 1)
+
+# Make sure the executable can run from the install tree.
+SET(CMAKE_INSTALL_NAME_DIR ${CMAKE_INSTALL_PREFIX}/MyTest/lib)
+
+# 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)
+
+SET(CMAKE_DEBUG_POSTFIX "_test_debug_postfix")
+
+SET(EXTRA_INSTALL_FLAGS)
+MESSAGE("Extra install: ${EXTRA_INSTALL_FLAGS}")
+
+IF(STAGE2)
+ SET(LIBPATHS
+ ${CMAKE_INSTALL_PREFIX}/MyTest/lib/static
+ ${CMAKE_INSTALL_PREFIX}/MyTest/lib
+ )
+ SET(t1NAMES test1 test1${CMAKE_DEBUG_POSTFIX} test1rel)
+ SET(t2NAMES test2 test2${CMAKE_DEBUG_POSTFIX})
+ SET(t4NAMES test4out test4out${CMAKE_DEBUG_POSTFIX})
+
+ # Make sure the install script ran.
+ SET(CMAKE_INSTALL_SCRIPT_DID_RUN 0)
+ INCLUDE(${CMAKE_INSTALL_PREFIX}/MyTest/InstallScriptOut.cmake OPTIONAL)
+ IF(CMAKE_INSTALL_SCRIPT_DID_RUN)
+ MESSAGE(STATUS "Stage 1 did run install script 2.")
+ ELSE(CMAKE_INSTALL_SCRIPT_DID_RUN)
+ MESSAGE(SEND_ERROR "Stage 1 did not run install script 2.")
+ ENDIF(CMAKE_INSTALL_SCRIPT_DID_RUN)
+
+ IF(CYGWIN OR MINGW)
+ SET(LIBPATHS ${LIBPATHS} "${CMAKE_INSTALL_PREFIX}/MyTest/bin")
+ ENDIF(CYGWIN OR MINGW)
+ MESSAGE("Search for library in: ${LIBPATHS}")
+
+ SET(TEST1_LIBRARY "TEST1_LIBRARY-NOTFOUND" CACHE FILEPATH "Force find." FORCE)
+ SET(TEST2_LIBRARY "TEST2_LIBRARY-NOTFOUND" CACHE FILEPATH "Force find." FORCE)
+ SET(TEST4_LIBRARY "TEST4_LIBRARY-NOTFOUND" CACHE FILEPATH "Force find." FORCE)
+
+ FIND_LIBRARY(TEST1_LIBRARY
+ NAMES ${t1NAMES}
+ PATHS ${LIBPATHS}
+ DOC "First library")
+ FIND_LIBRARY(TEST2_LIBRARY
+ NAMES ${t2NAMES}
+ PATHS ${LIBPATHS}
+ DOC "Second library")
+ FIND_LIBRARY(TEST4_LIBRARY
+ NAMES ${t4NAMES}
+ PATHS ${LIBPATHS}
+ DOC "Fourth library")
+
+ # Test importing a library found on disk.
+ ADD_LIBRARY(lib_test4 UNKNOWN IMPORTED)
+ SET_PROPERTY(TARGET lib_test4 PROPERTY IMPORTED_LOCATION ${TEST4_LIBRARY})
+
+ INCLUDE_DIRECTORIES(${CMAKE_INSTALL_PREFIX}/MyTest/include)
+ ADD_EXECUTABLE (SimpleInstExeS2 inst2.cxx foo.c foo.h)
+ TARGET_LINK_LIBRARIES(SimpleInstExeS2 ${TEST1_LIBRARY} ${TEST2_LIBRARY} lib_test4)
+ SET(install_target SimpleInstExeS2)
+
+ IF("${TEST1_LIBRARY}" MATCHES "static")
+ MESSAGE(STATUS "test1 correctly found in lib/static")
+ ELSE("${TEST1_LIBRARY}" MATCHES "static")
+ MESSAGE(SEND_ERROR "test1 not found in lib/static!")
+ ENDIF("${TEST1_LIBRARY}" MATCHES "static")
+
+ # Check for failure of configuration-specific installation.
+ IF(EXISTS "${CMAKE_INSTALL_PREFIX}/MyTest/include/Release/lib1debug.h")
+ MESSAGE(FATAL_ERROR "Debug-configuration file installed for Release!")
+ ENDIF(EXISTS "${CMAKE_INSTALL_PREFIX}/MyTest/include/Release/lib1debug.h")
+ IF(EXISTS "${CMAKE_INSTALL_PREFIX}/MyTest/include/Debug/lib1release.h")
+ MESSAGE(FATAL_ERROR "Release-configuration file installed for Debug!")
+ ENDIF(EXISTS "${CMAKE_INSTALL_PREFIX}/MyTest/include/Debug/lib1release.h")
+
+ # Check for failure of directory installation.
+ IF(NOT EXISTS "${CMAKE_INSTALL_PREFIX}/MyTest/share/TestSubDir/TSD.h")
+ MESSAGE(FATAL_ERROR "Directory installation did not install TSD.h")
+ ENDIF(NOT EXISTS "${CMAKE_INSTALL_PREFIX}/MyTest/share/TestSubDir/TSD.h")
+ IF(EXISTS "${CMAKE_INSTALL_PREFIX}/MyTest/share/TestSubDir/CVS")
+ MESSAGE(FATAL_ERROR "Directory installation installed CVS directory.")
+ ENDIF(EXISTS "${CMAKE_INSTALL_PREFIX}/MyTest/share/TestSubDir/CVS")
+ IF(EXISTS "${CMAKE_INSTALL_PREFIX}/MyTest/share/CVS")
+ MESSAGE(FATAL_ERROR "Directory installation installed CVS directory.")
+ ENDIF(EXISTS "${CMAKE_INSTALL_PREFIX}/MyTest/share/CVS")
+ IF(EXISTS "${CMAKE_INSTALL_PREFIX}/MyTest/share/CMakeLists.txt")
+ MESSAGE(FATAL_ERROR "Directory installation installed CMakeLists.txt.")
+ ENDIF(EXISTS "${CMAKE_INSTALL_PREFIX}/MyTest/share/CMakeLists.txt")
+ IF(NOT EXISTS "${CMAKE_INSTALL_PREFIX}/MyTest/share/alt/TestSubDir/TSD.h")
+ MESSAGE(FATAL_ERROR "Directory installation did not install alternate TSD.h")
+ ENDIF(NOT EXISTS "${CMAKE_INSTALL_PREFIX}/MyTest/share/alt/TestSubDir/TSD.h")
+ IF(EXISTS "${CMAKE_INSTALL_PREFIX}/MyTest/share/alt/TestSubDir/TSD.cxx")
+ MESSAGE(FATAL_ERROR "Directory installation installed alternate TSD.cxx")
+ ENDIF(EXISTS "${CMAKE_INSTALL_PREFIX}/MyTest/share/alt/TestSubDir/TSD.cxx")
+
+ # Check that scripts properly installed.
+ IF(WIN32 AND NOT CYGWIN)
+ SET(BAT .bat)
+ ELSE(WIN32 AND NOT CYGWIN)
+ SET(BAT)
+ ENDIF(WIN32 AND NOT CYGWIN)
+ FOREACH(loc share share/old1 share/old2 share/old3 share/alt)
+ SET(CUR_SCRIPT "${CMAKE_INSTALL_PREFIX}/MyTest/${loc}/sample_script${BAT}")
+ EXECUTE_PROCESS(
+ COMMAND ${CUR_SCRIPT}
+ RESULT_VARIABLE SAMPLE_SCRIPT_RESULT
+ OUTPUT_VARIABLE SAMPLE_SCRIPT_OUTPUT
+ )
+ IF(NOT "${SAMPLE_SCRIPT_RESULT}" MATCHES "^0$")
+ MESSAGE(FATAL_ERROR
+ "Sample script [${CUR_SCRIPT}] failed: [${SAMPLE_SCRIPT_RESULT}]")
+ ENDIF(NOT "${SAMPLE_SCRIPT_RESULT}" MATCHES "^0$")
+ IF(NOT "${SAMPLE_SCRIPT_OUTPUT}" MATCHES "Sample Script Output")
+ MESSAGE(FATAL_ERROR
+ "Bad sample script [${CUR_SCRIPT}] output: [${SAMPLE_SCRIPT_OUTPUT}]")
+ ENDIF(NOT "${SAMPLE_SCRIPT_OUTPUT}" MATCHES "Sample Script Output")
+ ENDFOREACH(loc)
+
+ # Check for failure of empty directory installation.
+ IF(NOT EXISTS "${CMAKE_INSTALL_PREFIX}/MyTest/share/empty")
+ MESSAGE(FATAL_ERROR "Empty directory installation did not install.")
+ ENDIF(NOT EXISTS "${CMAKE_INSTALL_PREFIX}/MyTest/share/empty")
+ FILE(GLOB EMPTY_FILES "${CMAKE_INSTALL_PREFIX}/MyTest/share/empty/*")
+ IF(EMPTY_FILES)
+ MESSAGE(FATAL_ERROR "Empty directory installed [${EMPTY_FILES}].")
+ ENDIF(EMPTY_FILES)
+
+ # Make sure the test executable can run from the install tree.
+ SET_TARGET_PROPERTIES(SimpleInstExeS2 PROPERTIES
+ INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/MyTest/lib)
+
+ INSTALL_TARGETS(/MyTest/bin SimpleInstExeS2)
+
+# try to import the exported targets again
+ SET(SimpleInstallS1_DIR ${CMAKE_INSTALL_PREFIX}/MyTest/lib)
+ FIND_PACKAGE(SimpleInstallS1 REQUIRED)
+ GET_TARGET_PROPERTY(simpleInstallImported S1_SimpleInstall IMPORTED)
+ IF(NOT simpleInstallImported)
+ MESSAGE(FATAL_ERROR "Target S1_SimpleInstall could not be imported")
+ ENDIF(NOT simpleInstallImported)
+
+ELSE(STAGE2)
+ # Wipe out the install directory to do a fresh test.
+ FILE(REMOVE_RECURSE ${CMAKE_INSTALL_PREFIX}/MyTest)
+
+ # this is stage 1, so create libraries and modules and install everything
+ ADD_LIBRARY(test1 STATIC lib1.cxx)
+ ADD_LIBRARY(test2 SHARED lib2.cxx)
+ ADD_LIBRARY(test3 MODULE lib3.cxx)
+ ADD_LIBRARY(test4 SHARED lib4.cxx)
+
+ # Test <ARCHIVE|LIBRARY|RUNTIME>_OUTPUT_NAME properties.
+ SET_PROPERTY(TARGET test4 PROPERTY ARCHIVE_OUTPUT_NAME test4out)
+ SET_PROPERTY(TARGET test4 PROPERTY LIBRARY_OUTPUT_NAME test4out)
+
+ ADD_EXECUTABLE (SimpleInstall inst.cxx foo.c foo.h)
+ TARGET_LINK_LIBRARIES(SimpleInstall test1 test2 test4)
+ SET(install_target SimpleInstall)
+
+ SET_TARGET_PROPERTIES(SimpleInstall PROPERTIES OUTPUT_NAME SimpleInstExe)
+ # Disable VERSION test until it is implemented in the Xcode generator.
+ IF(NOT XCODE)
+ SET_TARGET_PROPERTIES(SimpleInstall PROPERTIES VERSION 1.2)
+ ENDIF(NOT XCODE)
+
+ # Make sure the test executable can run from the install tree.
+ SET_TARGET_PROPERTIES(SimpleInstall PROPERTIES
+ INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/MyTest/lib)
+
+ # Test per-configuration output name.
+ SET_TARGET_PROPERTIES(test1 PROPERTIES RELEASE_OUTPUT_NAME test1rel)
+ SET_TARGET_PROPERTIES(test2 PROPERTIES PUBLIC_HEADER foo.h)
+
+ IF(CMAKE_GENERATOR MATCHES "Makefiles")
+ ADD_SUBDIRECTORY(TestSubDir)
+ ADD_DEPENDENCIES(SimpleInstall TSD)
+ ENDIF(CMAKE_GENERATOR MATCHES "Makefiles")
+
+ ADD_DEPENDENCIES(SimpleInstall test3)
+ ADD_DEPENDENCIES(test2 test3)
+ ADD_DEPENDENCIES(test4 test2)
+
+ INSTALL(TARGETS SimpleInstall test1 test2 test3 EXPORT SimpleInstallS1
+ RUNTIME DESTINATION MyTest/bin COMPONENT Runtime # .exe, .dll
+ LIBRARY DESTINATION MyTest/lib COMPONENT Runtime # .so, mod.dll
+ ARCHIVE DESTINATION MyTest/lib/static COMPONENT Development # .a, .lib
+ PUBLIC_HEADER DESTINATION MyTest/include COMPONENT Development
+ )
+
+ INSTALL(TARGETS test4 PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
+ RUNTIME DESTINATION MyTest/bin
+ LIBRARY DESTINATION MyTest/lib
+ ARCHIVE DESTINATION MyTest/lib/static
+ OPTIONAL # for coverage...target should always exist
+ )
+ INSTALL(FILES lib1.h DESTINATION MyTest/include/foo)
+ INSTALL(FILES lib2.h
+ DESTINATION MyTest/include/foo
+ COMPONENT Development
+ PERMISSIONS OWNER_READ OWNER_WRITE
+ RENAME lib2renamed.h
+ )
+
+ # Test old-style install commands.
+ INSTALL_FILES(/MyTest/include FILES lib3.h)
+ INSTALL_FILES(/MyTest/include/old .h lib3)
+ INSTALL_FILES(/MyTest/include/old "^lib2.h$")
+ INSTALL_PROGRAMS(/MyTest/share/old1 FILES
+ scripts/sample_script scripts/sample_script.bat)
+ INSTALL_PROGRAMS(/MyTest/share/old2
+ scripts/sample_script scripts/sample_script.bat)
+
+# "export" the targets collected in "SimpleInstallS1"
+ INSTALL(EXPORT SimpleInstallS1 FILE SimpleInstallS1Config.cmake
+ DESTINATION MyTest/lib
+ NAMESPACE S1_ )
+
+ EXPORT(TARGETS SimpleInstall test1 test2 test3
+ FILE "${CMAKE_CURRENT_BINARY_DIR}/SimpleInstallS1Config.cmake"
+ NAMESPACE S2_ )
+
+ ADD_SUBDIRECTORY(scripts)
+
+ # Test optional installation.
+ INSTALL(FILES does_not_exist.h DESTINATION MyTest/include/foo OPTIONAL)
+
+ # Test configuration-specific installation.
+ INSTALL(FILES lib1.h RENAME lib1release.h CONFIGURATIONS Release
+ DESTINATION MyTest/include/Release
+ )
+ INSTALL(FILES lib1.h RENAME lib1debug.h CONFIGURATIONS Debug
+ DESTINATION MyTest/include/Debug
+ )
+
+ # Test directory installation.
+ 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
+ FILE_PERMISSIONS OWNER_READ OWNER_WRITE
+ DIRECTORY_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
+ GROUP_READ GROUP_EXECUTE
+ PATTERN "CVS" EXCLUDE
+ REGEX "\\.txt$" EXCLUDE
+ PATTERN "scripts/*" PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ
+ )
+
+ # Alternate directory installation for coverage.
+ INSTALL(
+ DIRECTORY scripts/ DESTINATION MyTest/share/alt
+ COMPONENT Development
+ USE_SOURCE_PERMISSIONS
+ PATTERN "CVS" EXCLUDE
+ REGEX "\\.txt$" EXCLUDE
+ )
+ INSTALL(
+ DIRECTORY TestSubDir DESTINATION MyTest/share/alt
+ FILE_PERMISSIONS OWNER_READ OWNER_WRITE
+ DIRECTORY_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
+ GROUP_READ GROUP_EXECUTE
+ FILES_MATCHING PATTERN "*.h"
+ )
+
+ # Test empty directory installation.
+ INSTALL(DIRECTORY DESTINATION MyTest/share/empty)
+
+ # Test optional directory installation.
+ INSTALL(DIRECTORY does-not-exist DESTINATION MyTest/share OPTIONAL)
+
+ # Test user-specified install scripts, with and without COMPONENT.
+ INSTALL(
+ SCRIPT InstallScript1.cmake
+ CODE "SET(INSTALL_CODE_DID_RUN 1)"
+ SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/InstallScript2.cmake
+ )
+ INSTALL(
+ SCRIPT InstallScript3.cmake
+ CODE "SET(INSTALL_CODE_WITH_COMPONENT_DID_RUN 1)"
+ SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/InstallScript4.cmake
+ COMPONENT Development
+ )
+ SET_DIRECTORY_PROPERTIES(PROPERTIES
+ ADDITIONAL_MAKE_CLEAN_FILES
+ "${CMAKE_INSTALL_PREFIX}/InstallScriptOut.cmake;${CMAKE_INSTALL_PREFIX}/InstallScript4Out.cmake")
+
+ SET_TARGET_PROPERTIES(SimpleInstall PROPERTIES PRE_INSTALL_SCRIPT
+ ${CMAKE_CURRENT_SOURCE_DIR}/PreInstall.cmake)
+ SET_TARGET_PROPERTIES(SimpleInstall PROPERTIES POST_INSTALL_SCRIPT
+ ${CMAKE_CURRENT_SOURCE_DIR}/PostInstall.cmake)
+ SET_TARGET_PROPERTIES(test4 PROPERTIES VERSION 1.2 SOVERSION 3
+ INSTALL_NAME_DIR @executable_path/../lib)
+ENDIF(STAGE2)
+
+IF(CMAKE_CONFIGURATION_TYPES)
+ SET(SI_CONFIG -C ${CMAKE_CFG_INTDIR})
+ELSE(CMAKE_CONFIGURATION_TYPES)
+ SET(SI_CONFIG)
+ENDIF(CMAKE_CONFIGURATION_TYPES)
+
+# Dummy test of CPack
+SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Test of packaging with cpack")
+SET(CPACK_PACKAGE_VENDOR "Kitware")
+SET(CPACK_INSTALL_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/PackageScript.cmake")
+
+IF(WIN32 AND NOT UNIX)
+ FIND_PROGRAM(NSIS_MAKENSIS NAMES makensis
+ PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\NSIS]
+ DOC "Where is makensis.exe located"
+ )
+ IF(NOT NSIS_MAKENSIS)
+ SET(CPACK_GENERATOR TGZ)
+ ENDIF(NOT NSIS_MAKENSIS)
+ENDIF(WIN32 AND NOT UNIX)
+IF(UNIX AND NOT APPLE)
+ SET(CPACK_GENERATOR "TGZ;STGZ;TZ")
+ # FIND_PROGRAM(found_compress
+ # NAMES compress)
+ # IF(found_compress)
+ # FIND_PROGRAM(file_command NAMES file)
+ # IF(NOT file_command)
+ # set(file_command file)
+ # ENDIF(NOT file_command)
+ # EXECUTE_PROCESS(COMMAND ${file_command} ${found_compress}
+ # OUTPUT_VARIABLE output)
+ # set(SKIP_TZ FALSE)
+ # if("${output}" MATCHES "script")
+ # set(SKIP_TZ TRUE)
+ # endif("${output}" MATCHES "script")
+ # if("${output}" MATCHES "dummy.sh")
+ # set(SKIP_TZ TRUE)
+ # endif("${output}" MATCHES "dummy.sh")
+ # if(NOT SKIP_TZ)
+ # message("compress found and it was not a script")
+ # message("output from file command: [${output}]")
+ # SET(CPACK_GENERATOR "${CPACK_GENERATOR};TZ")
+ # else(NOT SKIP_TZ)
+ # message("compress found, but it was a script so dont use it")
+ # message("output from file command: [${output}]")
+ # endif(NOT SKIP_TZ)
+ # ENDIF(found_compress)
+ FIND_PROGRAM(found_bz2
+ NAMES bzip2)
+ IF(found_bz2)
+ SET(CPACK_GENERATOR "${CPACK_GENERATOR};TBZ2")
+ ENDIF(found_bz2)
+ENDIF(UNIX AND NOT APPLE)
+
+SET(CPACK_PACKAGE_EXECUTABLES "SimpleInstall" "Simple Install")
+SET(CMAKE_INSTALL_MFC_LIBRARIES 1)
+SET(CMAKE_INSTALL_DEBUG_LIBRARIES 1)
+INCLUDE(InstallRequiredSystemLibraries)
+
+IF(CTEST_TEST_CPACK)
+ SET(PACKAGE_TARGET --build-target package)
+
+ # Avoid settings that require the .zip file command line tools...
+ # (just build an NSIS installer without component support)
+ #
+ SET(CPACK_BINARY_ZIP OFF)
+ SET(CPACK_MONOLITHIC_INSTALL ON)
+ELSE(CTEST_TEST_CPACK)
+ SET(PACKAGE_TARGET)
+ENDIF(CTEST_TEST_CPACK)
+
+INCLUDE(CPack)
+
+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}
+ COMMENT "Install Project"
+ )
diff --git a/Tests/SimpleInstall/InstallScript1.cmake b/Tests/SimpleInstall/InstallScript1.cmake
new file mode 100644
index 000000000..27b7725f8
--- /dev/null
+++ b/Tests/SimpleInstall/InstallScript1.cmake
@@ -0,0 +1,5 @@
+MESSAGE("This is install script 1.")
+SET(INSTALL_SCRIPT_1_DID_RUN 1)
+IF(INSTALL_CODE_DID_RUN)
+ MESSAGE(FATAL_ERROR "Install script 1 did not run before install code.")
+ENDIF(INSTALL_CODE_DID_RUN)
diff --git a/Tests/SimpleInstall/InstallScript2.cmake b/Tests/SimpleInstall/InstallScript2.cmake
new file mode 100644
index 000000000..927cae8b6
--- /dev/null
+++ b/Tests/SimpleInstall/InstallScript2.cmake
@@ -0,0 +1,14 @@
+MESSAGE("This is install script 2.")
+IF(INSTALL_SCRIPT_1_DID_RUN)
+ MESSAGE("Install script ordering works.")
+ELSE(INSTALL_SCRIPT_1_DID_RUN)
+ MESSAGE(FATAL_ERROR "Install script 1 did not run before install script 2.")
+ENDIF(INSTALL_SCRIPT_1_DID_RUN)
+IF(INSTALL_CODE_DID_RUN)
+ MESSAGE("Install code ordering works.")
+ELSE(INSTALL_CODE_DID_RUN)
+ MESSAGE(FATAL_ERROR "Install script 2 did not run after install code.")
+ENDIF(INSTALL_CODE_DID_RUN)
+FILE(WRITE "${CMAKE_INSTALL_PREFIX}/MyTest/InstallScriptOut.cmake"
+ "SET(CMAKE_INSTALL_SCRIPT_DID_RUN 1)\n"
+ )
diff --git a/Tests/SimpleInstall/InstallScript3.cmake b/Tests/SimpleInstall/InstallScript3.cmake
new file mode 100644
index 000000000..b1aecd4c2
--- /dev/null
+++ b/Tests/SimpleInstall/InstallScript3.cmake
@@ -0,0 +1,12 @@
+MESSAGE("This is install script 3.")
+SET(INSTALL_SCRIPT_3_DID_RUN 1)
+IF(INSTALL_CODE_WITH_COMPONENT_DID_RUN)
+ MESSAGE(FATAL_ERROR "Install script 3 did not run before install code with component.")
+ENDIF(INSTALL_CODE_WITH_COMPONENT_DID_RUN)
+
+IF(CMAKE_INSTALL_COMPONENT)
+IF(NOT "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Development")
+ MESSAGE("CMAKE_INSTALL_COMPONENT=\"${CMAKE_INSTALL_COMPONENT}\"")
+ MESSAGE(FATAL_ERROR "Install script 3 should only run for \"Development\" INSTALL COMPONENT.")
+ENDIF(NOT "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Development")
+ENDIF(CMAKE_INSTALL_COMPONENT)
diff --git a/Tests/SimpleInstall/InstallScript4.cmake b/Tests/SimpleInstall/InstallScript4.cmake
new file mode 100644
index 000000000..0ffea4bc8
--- /dev/null
+++ b/Tests/SimpleInstall/InstallScript4.cmake
@@ -0,0 +1,22 @@
+MESSAGE("This is install script 4.")
+IF(INSTALL_SCRIPT_3_DID_RUN)
+ MESSAGE("Install script ordering works.")
+ELSE(INSTALL_SCRIPT_3_DID_RUN)
+ MESSAGE(FATAL_ERROR "Install script 3 did not run before install script 4.")
+ENDIF(INSTALL_SCRIPT_3_DID_RUN)
+IF(INSTALL_CODE_WITH_COMPONENT_DID_RUN)
+ MESSAGE("Install code ordering works.")
+ELSE(INSTALL_CODE_WITH_COMPONENT_DID_RUN)
+ MESSAGE(FATAL_ERROR "Install script 4 did not run after install with component code.")
+ENDIF(INSTALL_CODE_WITH_COMPONENT_DID_RUN)
+
+IF(CMAKE_INSTALL_COMPONENT)
+IF(NOT "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Development")
+ MESSAGE("CMAKE_INSTALL_COMPONENT=\"${CMAKE_INSTALL_COMPONENT}\"")
+ MESSAGE(FATAL_ERROR "Install script 4 should only run for \"Development\" INSTALL COMPONENT.")
+ENDIF(NOT "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Development")
+ENDIF(CMAKE_INSTALL_COMPONENT)
+
+FILE(WRITE "${CMAKE_INSTALL_PREFIX}/MyTest/InstallScript4Out.cmake"
+ "SET(CMAKE_INSTALL_SCRIPT_4_DID_RUN 1)\n"
+ )
diff --git a/Tests/SimpleInstall/PackageScript.cmake b/Tests/SimpleInstall/PackageScript.cmake
new file mode 100644
index 000000000..3567a2f43
--- /dev/null
+++ b/Tests/SimpleInstall/PackageScript.cmake
@@ -0,0 +1,10 @@
+MESSAGE("This is packaging script")
+MESSAGE("It writes a file with all variables available in ${CMAKE_INSTALL_PREFIX}/AllVariables.txt")
+
+FILE(WRITE ${CMAKE_INSTALL_PREFIX}/AllVariables.txt "")
+GET_CMAKE_PROPERTY(res VARIABLES)
+FOREACH(var ${res})
+ FILE(APPEND ${CMAKE_INSTALL_PREFIX}/AllVariables.txt
+ "${var} \"${${var}}\"\n")
+ENDFOREACH(var ${res})
+
diff --git a/Tests/SimpleInstall/PostInstall.cmake b/Tests/SimpleInstall/PostInstall.cmake
new file mode 100644
index 000000000..52ea140a5
--- /dev/null
+++ b/Tests/SimpleInstall/PostInstall.cmake
@@ -0,0 +1,6 @@
+MESSAGE("In post install")
+IF(PRE_INSTALL_DID_RUN)
+ MESSAGE("Pre and post install work fine")
+ELSE(PRE_INSTALL_DID_RUN)
+ MESSAGE(FATAL_ERROR "Pre install did not run before post install")
+ENDIF(PRE_INSTALL_DID_RUN)
diff --git a/Tests/SimpleInstall/PreInstall.cmake b/Tests/SimpleInstall/PreInstall.cmake
new file mode 100644
index 000000000..2ea2f7716
--- /dev/null
+++ b/Tests/SimpleInstall/PreInstall.cmake
@@ -0,0 +1,2 @@
+MESSAGE("This is in pre install")
+SET(PRE_INSTALL_DID_RUN 1)
diff --git a/Tests/SimpleInstall/TestSubDir/CMakeLists.txt b/Tests/SimpleInstall/TestSubDir/CMakeLists.txt
new file mode 100644
index 000000000..4f6295300
--- /dev/null
+++ b/Tests/SimpleInstall/TestSubDir/CMakeLists.txt
@@ -0,0 +1,3 @@
+ADD_EXECUTABLE(TSD TSD.cxx TSD_utils.cxx)
+INSTALL_FILES(/MyTest/include FILES TSD.h)
+INSTALL_TARGETS(/MyTest/bin TSD)
diff --git a/Tests/SimpleInstall/TestSubDir/TSD.cxx b/Tests/SimpleInstall/TestSubDir/TSD.cxx
new file mode 100644
index 000000000..8fc38787a
--- /dev/null
+++ b/Tests/SimpleInstall/TestSubDir/TSD.cxx
@@ -0,0 +1,10 @@
+#include <stdio.h>
+
+#include "TSD.h"
+
+int main()
+{
+ int res = TSD("TEST");
+ printf("Hello from TSD\n");
+ return res;
+}
diff --git a/Tests/SimpleInstall/TestSubDir/TSD.h b/Tests/SimpleInstall/TestSubDir/TSD.h
new file mode 100644
index 000000000..6a3c1affa
--- /dev/null
+++ b/Tests/SimpleInstall/TestSubDir/TSD.h
@@ -0,0 +1 @@
+int TSD(const char*);
diff --git a/Tests/SimpleInstall/TestSubDir/TSD_utils.cxx b/Tests/SimpleInstall/TestSubDir/TSD_utils.cxx
new file mode 100644
index 000000000..0277f05ae
--- /dev/null
+++ b/Tests/SimpleInstall/TestSubDir/TSD_utils.cxx
@@ -0,0 +1,10 @@
+#include <string.h>
+
+int TSD(const char* foo)
+{
+ if ( strcmp(foo, "TEST") == 0 )
+ {
+ return 0;
+ }
+ return 1;
+}
diff --git a/Tests/SimpleInstall/foo.c b/Tests/SimpleInstall/foo.c
new file mode 100644
index 000000000..45d5b2bf2
--- /dev/null
+++ b/Tests/SimpleInstall/foo.c
@@ -0,0 +1,6 @@
+char* foo = "Foo";
+
+int SomeFunctionInFoo()
+{
+ return 5;
+}
diff --git a/Tests/SimpleInstall/foo.h b/Tests/SimpleInstall/foo.h
new file mode 100644
index 000000000..2708baffe
--- /dev/null
+++ b/Tests/SimpleInstall/foo.h
@@ -0,0 +1,11 @@
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern char* foo;
+extern int SomeFunctionInFoo();
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/Tests/SimpleInstall/inst.cxx b/Tests/SimpleInstall/inst.cxx
new file mode 100644
index 000000000..7f2962d00
--- /dev/null
+++ b/Tests/SimpleInstall/inst.cxx
@@ -0,0 +1,37 @@
+#include "foo.h"
+
+#ifdef STAGE_2
+# include <foo/lib1.h>
+# include <foo/lib2renamed.h>
+# include <lib3.h>
+# include <old/lib2.h>
+# include <old/lib3.h>
+#else
+# include "lib1.h"
+# include "lib2.h"
+#endif
+
+#include "lib4.h"
+
+#include <stdio.h>
+
+int main ()
+{
+ if ( Lib1Func() != 2.0 )
+ {
+ printf("Problem with lib1\n");
+ return 1;
+ }
+ if ( Lib2Func() != 1.0 )
+ {
+ printf("Problem with lib2\n");
+ return 1;
+ }
+ if ( Lib4Func() != 4.0 )
+ {
+ printf("Problem with lib4\n");
+ return 1;
+ }
+ printf("The value of Foo: %s\n", foo);
+ return SomeFunctionInFoo()-5;
+}
diff --git a/Tests/SimpleInstall/inst2.cxx b/Tests/SimpleInstall/inst2.cxx
new file mode 100644
index 000000000..c70b93af1
--- /dev/null
+++ b/Tests/SimpleInstall/inst2.cxx
@@ -0,0 +1,2 @@
+#define STAGE_2
+#include "inst.cxx"
diff --git a/Tests/SimpleInstall/lib1.cxx b/Tests/SimpleInstall/lib1.cxx
new file mode 100644
index 000000000..7aa905205
--- /dev/null
+++ b/Tests/SimpleInstall/lib1.cxx
@@ -0,0 +1,6 @@
+#include "lib1.h"
+
+float Lib1Func()
+{
+ return 2.0;
+}
diff --git a/Tests/SimpleInstall/lib1.h b/Tests/SimpleInstall/lib1.h
new file mode 100644
index 000000000..0d64e76bc
--- /dev/null
+++ b/Tests/SimpleInstall/lib1.h
@@ -0,0 +1 @@
+extern float Lib1Func();
diff --git a/Tests/SimpleInstall/lib2.cxx b/Tests/SimpleInstall/lib2.cxx
new file mode 100644
index 000000000..dccc48b78
--- /dev/null
+++ b/Tests/SimpleInstall/lib2.cxx
@@ -0,0 +1,6 @@
+#include "lib2.h"
+
+float Lib2Func()
+{
+ return 1.0;
+}
diff --git a/Tests/SimpleInstall/lib2.h b/Tests/SimpleInstall/lib2.h
new file mode 100644
index 000000000..ea5a6f7ea
--- /dev/null
+++ b/Tests/SimpleInstall/lib2.h
@@ -0,0 +1,11 @@
+#ifdef _WIN32
+# ifdef test2_EXPORTS
+# define CM_TEST_LIB_EXPORT __declspec( dllexport )
+# else
+# define CM_TEST_LIB_EXPORT __declspec( dllimport )
+# endif
+#else
+# define CM_TEST_LIB_EXPORT
+#endif
+
+CM_TEST_LIB_EXPORT float Lib2Func();
diff --git a/Tests/SimpleInstall/lib3.cxx b/Tests/SimpleInstall/lib3.cxx
new file mode 100644
index 000000000..da8dbf942
--- /dev/null
+++ b/Tests/SimpleInstall/lib3.cxx
@@ -0,0 +1,6 @@
+#include "lib3.h"
+
+float Lib3Func()
+{
+ return 2.0;
+}
diff --git a/Tests/SimpleInstall/lib3.h b/Tests/SimpleInstall/lib3.h
new file mode 100644
index 000000000..c250ed769
--- /dev/null
+++ b/Tests/SimpleInstall/lib3.h
@@ -0,0 +1,11 @@
+#ifdef _WIN32
+# ifdef test3_EXPORTS
+# define CM_TEST_LIB_EXPORT __declspec( dllexport )
+# else
+# define CM_TEST_LIB_EXPORT __declspec( dllimport )
+# endif
+#else
+# define CM_TEST_LIB_EXPORT
+#endif
+
+CM_TEST_LIB_EXPORT float Lib3Func();
diff --git a/Tests/SimpleInstall/lib4.cxx b/Tests/SimpleInstall/lib4.cxx
new file mode 100644
index 000000000..fbfa23aa4
--- /dev/null
+++ b/Tests/SimpleInstall/lib4.cxx
@@ -0,0 +1,7 @@
+#include "lib4.h"
+
+float Lib4Func()
+{
+ return 4.0;
+}
+
diff --git a/Tests/SimpleInstall/lib4.h b/Tests/SimpleInstall/lib4.h
new file mode 100644
index 000000000..4b94ea207
--- /dev/null
+++ b/Tests/SimpleInstall/lib4.h
@@ -0,0 +1,12 @@
+#ifdef _WIN32
+# ifdef test4_EXPORTS
+# define CM_TEST_LIB_EXPORT __declspec( dllexport )
+# else
+# define CM_TEST_LIB_EXPORT __declspec( dllimport )
+# endif
+#else
+# define CM_TEST_LIB_EXPORT
+#endif
+
+CM_TEST_LIB_EXPORT float Lib4Func();
+
diff --git a/Tests/SimpleInstall/scripts/.gitattributes b/Tests/SimpleInstall/scripts/.gitattributes
new file mode 100644
index 000000000..5e3db2fb3
--- /dev/null
+++ b/Tests/SimpleInstall/scripts/.gitattributes
@@ -0,0 +1 @@
+sample_script crlf=input
diff --git a/Tests/SimpleInstall/scripts/CMakeLists.txt b/Tests/SimpleInstall/scripts/CMakeLists.txt
new file mode 100644
index 000000000..d46c1652e
--- /dev/null
+++ b/Tests/SimpleInstall/scripts/CMakeLists.txt
@@ -0,0 +1 @@
+INSTALL_PROGRAMS(/MyTest/share/old3 "^sample_script(\\.bat)?$")
diff --git a/Tests/SimpleInstall/scripts/sample_script b/Tests/SimpleInstall/scripts/sample_script
new file mode 100755
index 000000000..81f9f5315
--- /dev/null
+++ b/Tests/SimpleInstall/scripts/sample_script
@@ -0,0 +1,2 @@
+#!/bin/sh
+echo "Sample Script Output"
diff --git a/Tests/SimpleInstall/scripts/sample_script.bat b/Tests/SimpleInstall/scripts/sample_script.bat
new file mode 100755
index 000000000..64a77b5b0
--- /dev/null
+++ b/Tests/SimpleInstall/scripts/sample_script.bat
@@ -0,0 +1 @@
+@echo Sample Script Output
diff --git a/Tests/SimpleInstallS2/CMakeLists.txt b/Tests/SimpleInstallS2/CMakeLists.txt
new file mode 100644
index 000000000..378b5292b
--- /dev/null
+++ b/Tests/SimpleInstallS2/CMakeLists.txt
@@ -0,0 +1,398 @@
+cmake_minimum_required (VERSION 2.6)
+PROJECT (TestSimpleInstall)
+SET(CMAKE_VERBOSE_MAKEFILE 1)
+SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY
+ "${TestSimpleInstall_BINARY_DIR}/bin")
+SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY
+ "${TestSimpleInstall_BINARY_DIR}/lib/static")
+SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY
+ "${TestSimpleInstall_BINARY_DIR}/lib")
+
+# Skip generating the rpath pointing at the build tree to make sure
+# the executable is installed with the proper rpath in the install
+# tree.
+SET(CMAKE_SKIP_BUILD_RPATH 1)
+
+# Make sure the executable can run from the install tree.
+SET(CMAKE_INSTALL_NAME_DIR ${CMAKE_INSTALL_PREFIX}/MyTest/lib)
+
+# 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)
+
+SET(CMAKE_DEBUG_POSTFIX "_test_debug_postfix")
+
+SET(EXTRA_INSTALL_FLAGS)
+MESSAGE("Extra install: ${EXTRA_INSTALL_FLAGS}")
+
+IF(STAGE2)
+ SET(LIBPATHS
+ ${CMAKE_INSTALL_PREFIX}/MyTest/lib/static
+ ${CMAKE_INSTALL_PREFIX}/MyTest/lib
+ )
+ SET(t1NAMES test1 test1${CMAKE_DEBUG_POSTFIX} test1rel)
+ SET(t2NAMES test2 test2${CMAKE_DEBUG_POSTFIX})
+ SET(t4NAMES test4out test4out${CMAKE_DEBUG_POSTFIX})
+
+ # Make sure the install script ran.
+ SET(CMAKE_INSTALL_SCRIPT_DID_RUN 0)
+ INCLUDE(${CMAKE_INSTALL_PREFIX}/MyTest/InstallScriptOut.cmake OPTIONAL)
+ IF(CMAKE_INSTALL_SCRIPT_DID_RUN)
+ MESSAGE(STATUS "Stage 1 did run install script 2.")
+ ELSE(CMAKE_INSTALL_SCRIPT_DID_RUN)
+ MESSAGE(SEND_ERROR "Stage 1 did not run install script 2.")
+ ENDIF(CMAKE_INSTALL_SCRIPT_DID_RUN)
+
+ IF(CYGWIN OR MINGW)
+ SET(LIBPATHS ${LIBPATHS} "${CMAKE_INSTALL_PREFIX}/MyTest/bin")
+ ENDIF(CYGWIN OR MINGW)
+ MESSAGE("Search for library in: ${LIBPATHS}")
+
+ SET(TEST1_LIBRARY "TEST1_LIBRARY-NOTFOUND" CACHE FILEPATH "Force find." FORCE)
+ SET(TEST2_LIBRARY "TEST2_LIBRARY-NOTFOUND" CACHE FILEPATH "Force find." FORCE)
+ SET(TEST4_LIBRARY "TEST4_LIBRARY-NOTFOUND" CACHE FILEPATH "Force find." FORCE)
+
+ FIND_LIBRARY(TEST1_LIBRARY
+ NAMES ${t1NAMES}
+ PATHS ${LIBPATHS}
+ DOC "First library")
+ FIND_LIBRARY(TEST2_LIBRARY
+ NAMES ${t2NAMES}
+ PATHS ${LIBPATHS}
+ DOC "Second library")
+ FIND_LIBRARY(TEST4_LIBRARY
+ NAMES ${t4NAMES}
+ PATHS ${LIBPATHS}
+ DOC "Fourth library")
+
+ # Test importing a library found on disk.
+ ADD_LIBRARY(lib_test4 UNKNOWN IMPORTED)
+ SET_PROPERTY(TARGET lib_test4 PROPERTY IMPORTED_LOCATION ${TEST4_LIBRARY})
+
+ INCLUDE_DIRECTORIES(${CMAKE_INSTALL_PREFIX}/MyTest/include)
+ ADD_EXECUTABLE (SimpleInstExeS2 inst2.cxx foo.c foo.h)
+ TARGET_LINK_LIBRARIES(SimpleInstExeS2 ${TEST1_LIBRARY} ${TEST2_LIBRARY} lib_test4)
+ SET(install_target SimpleInstExeS2)
+
+ IF("${TEST1_LIBRARY}" MATCHES "static")
+ MESSAGE(STATUS "test1 correctly found in lib/static")
+ ELSE("${TEST1_LIBRARY}" MATCHES "static")
+ MESSAGE(SEND_ERROR "test1 not found in lib/static!")
+ ENDIF("${TEST1_LIBRARY}" MATCHES "static")
+
+ # Check for failure of configuration-specific installation.
+ IF(EXISTS "${CMAKE_INSTALL_PREFIX}/MyTest/include/Release/lib1debug.h")
+ MESSAGE(FATAL_ERROR "Debug-configuration file installed for Release!")
+ ENDIF(EXISTS "${CMAKE_INSTALL_PREFIX}/MyTest/include/Release/lib1debug.h")
+ IF(EXISTS "${CMAKE_INSTALL_PREFIX}/MyTest/include/Debug/lib1release.h")
+ MESSAGE(FATAL_ERROR "Release-configuration file installed for Debug!")
+ ENDIF(EXISTS "${CMAKE_INSTALL_PREFIX}/MyTest/include/Debug/lib1release.h")
+
+ # Check for failure of directory installation.
+ IF(NOT EXISTS "${CMAKE_INSTALL_PREFIX}/MyTest/share/TestSubDir/TSD.h")
+ MESSAGE(FATAL_ERROR "Directory installation did not install TSD.h")
+ ENDIF(NOT EXISTS "${CMAKE_INSTALL_PREFIX}/MyTest/share/TestSubDir/TSD.h")
+ IF(EXISTS "${CMAKE_INSTALL_PREFIX}/MyTest/share/TestSubDir/CVS")
+ MESSAGE(FATAL_ERROR "Directory installation installed CVS directory.")
+ ENDIF(EXISTS "${CMAKE_INSTALL_PREFIX}/MyTest/share/TestSubDir/CVS")
+ IF(EXISTS "${CMAKE_INSTALL_PREFIX}/MyTest/share/CVS")
+ MESSAGE(FATAL_ERROR "Directory installation installed CVS directory.")
+ ENDIF(EXISTS "${CMAKE_INSTALL_PREFIX}/MyTest/share/CVS")
+ IF(EXISTS "${CMAKE_INSTALL_PREFIX}/MyTest/share/CMakeLists.txt")
+ MESSAGE(FATAL_ERROR "Directory installation installed CMakeLists.txt.")
+ ENDIF(EXISTS "${CMAKE_INSTALL_PREFIX}/MyTest/share/CMakeLists.txt")
+ IF(NOT EXISTS "${CMAKE_INSTALL_PREFIX}/MyTest/share/alt/TestSubDir/TSD.h")
+ MESSAGE(FATAL_ERROR "Directory installation did not install alternate TSD.h")
+ ENDIF(NOT EXISTS "${CMAKE_INSTALL_PREFIX}/MyTest/share/alt/TestSubDir/TSD.h")
+ IF(EXISTS "${CMAKE_INSTALL_PREFIX}/MyTest/share/alt/TestSubDir/TSD.cxx")
+ MESSAGE(FATAL_ERROR "Directory installation installed alternate TSD.cxx")
+ ENDIF(EXISTS "${CMAKE_INSTALL_PREFIX}/MyTest/share/alt/TestSubDir/TSD.cxx")
+
+ # Check that scripts properly installed.
+ IF(WIN32 AND NOT CYGWIN)
+ SET(BAT .bat)
+ ELSE(WIN32 AND NOT CYGWIN)
+ SET(BAT)
+ ENDIF(WIN32 AND NOT CYGWIN)
+ FOREACH(loc share share/old1 share/old2 share/old3 share/alt)
+ SET(CUR_SCRIPT "${CMAKE_INSTALL_PREFIX}/MyTest/${loc}/sample_script${BAT}")
+ EXECUTE_PROCESS(
+ COMMAND ${CUR_SCRIPT}
+ RESULT_VARIABLE SAMPLE_SCRIPT_RESULT
+ OUTPUT_VARIABLE SAMPLE_SCRIPT_OUTPUT
+ )
+ IF(NOT "${SAMPLE_SCRIPT_RESULT}" MATCHES "^0$")
+ MESSAGE(FATAL_ERROR
+ "Sample script [${CUR_SCRIPT}] failed: [${SAMPLE_SCRIPT_RESULT}]")
+ ENDIF(NOT "${SAMPLE_SCRIPT_RESULT}" MATCHES "^0$")
+ IF(NOT "${SAMPLE_SCRIPT_OUTPUT}" MATCHES "Sample Script Output")
+ MESSAGE(FATAL_ERROR
+ "Bad sample script [${CUR_SCRIPT}] output: [${SAMPLE_SCRIPT_OUTPUT}]")
+ ENDIF(NOT "${SAMPLE_SCRIPT_OUTPUT}" MATCHES "Sample Script Output")
+ ENDFOREACH(loc)
+
+ # Check for failure of empty directory installation.
+ IF(NOT EXISTS "${CMAKE_INSTALL_PREFIX}/MyTest/share/empty")
+ MESSAGE(FATAL_ERROR "Empty directory installation did not install.")
+ ENDIF(NOT EXISTS "${CMAKE_INSTALL_PREFIX}/MyTest/share/empty")
+ FILE(GLOB EMPTY_FILES "${CMAKE_INSTALL_PREFIX}/MyTest/share/empty/*")
+ IF(EMPTY_FILES)
+ MESSAGE(FATAL_ERROR "Empty directory installed [${EMPTY_FILES}].")
+ ENDIF(EMPTY_FILES)
+
+ # Make sure the test executable can run from the install tree.
+ SET_TARGET_PROPERTIES(SimpleInstExeS2 PROPERTIES
+ INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/MyTest/lib)
+
+ INSTALL_TARGETS(/MyTest/bin SimpleInstExeS2)
+
+# try to import the exported targets again
+ SET(SimpleInstallS1_DIR ${CMAKE_INSTALL_PREFIX}/MyTest/lib)
+ FIND_PACKAGE(SimpleInstallS1 REQUIRED)
+ GET_TARGET_PROPERTY(simpleInstallImported S1_SimpleInstall IMPORTED)
+ IF(NOT simpleInstallImported)
+ MESSAGE(FATAL_ERROR "Target S1_SimpleInstall could not be imported")
+ ENDIF(NOT simpleInstallImported)
+
+ELSE(STAGE2)
+ # Wipe out the install directory to do a fresh test.
+ FILE(REMOVE_RECURSE ${CMAKE_INSTALL_PREFIX}/MyTest)
+
+ # this is stage 1, so create libraries and modules and install everything
+ ADD_LIBRARY(test1 STATIC lib1.cxx)
+ ADD_LIBRARY(test2 SHARED lib2.cxx)
+ ADD_LIBRARY(test3 MODULE lib3.cxx)
+ ADD_LIBRARY(test4 SHARED lib4.cxx)
+
+ # Test <ARCHIVE|LIBRARY|RUNTIME>_OUTPUT_NAME properties.
+ SET_PROPERTY(TARGET test4 PROPERTY ARCHIVE_OUTPUT_NAME test4out)
+ SET_PROPERTY(TARGET test4 PROPERTY LIBRARY_OUTPUT_NAME test4out)
+
+ ADD_EXECUTABLE (SimpleInstall inst.cxx foo.c foo.h)
+ TARGET_LINK_LIBRARIES(SimpleInstall test1 test2 test4)
+ SET(install_target SimpleInstall)
+
+ SET_TARGET_PROPERTIES(SimpleInstall PROPERTIES OUTPUT_NAME SimpleInstExe)
+ # Disable VERSION test until it is implemented in the Xcode generator.
+ IF(NOT XCODE)
+ SET_TARGET_PROPERTIES(SimpleInstall PROPERTIES VERSION 1.2)
+ ENDIF(NOT XCODE)
+
+ # Make sure the test executable can run from the install tree.
+ SET_TARGET_PROPERTIES(SimpleInstall PROPERTIES
+ INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/MyTest/lib)
+
+ # Test per-configuration output name.
+ SET_TARGET_PROPERTIES(test1 PROPERTIES RELEASE_OUTPUT_NAME test1rel)
+ SET_TARGET_PROPERTIES(test2 PROPERTIES PUBLIC_HEADER foo.h)
+
+ IF(CMAKE_GENERATOR MATCHES "Makefiles")
+ ADD_SUBDIRECTORY(TestSubDir)
+ ADD_DEPENDENCIES(SimpleInstall TSD)
+ ENDIF(CMAKE_GENERATOR MATCHES "Makefiles")
+
+ ADD_DEPENDENCIES(SimpleInstall test3)
+ ADD_DEPENDENCIES(test2 test3)
+ ADD_DEPENDENCIES(test4 test2)
+
+ INSTALL(TARGETS SimpleInstall test1 test2 test3 EXPORT SimpleInstallS1
+ RUNTIME DESTINATION MyTest/bin COMPONENT Runtime # .exe, .dll
+ LIBRARY DESTINATION MyTest/lib COMPONENT Runtime # .so, mod.dll
+ ARCHIVE DESTINATION MyTest/lib/static COMPONENT Development # .a, .lib
+ PUBLIC_HEADER DESTINATION MyTest/include COMPONENT Development
+ )
+
+ INSTALL(TARGETS test4 PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
+ RUNTIME DESTINATION MyTest/bin
+ LIBRARY DESTINATION MyTest/lib
+ ARCHIVE DESTINATION MyTest/lib/static
+ OPTIONAL # for coverage...target should always exist
+ )
+ INSTALL(FILES lib1.h DESTINATION MyTest/include/foo)
+ INSTALL(FILES lib2.h
+ DESTINATION MyTest/include/foo
+ COMPONENT Development
+ PERMISSIONS OWNER_READ OWNER_WRITE
+ RENAME lib2renamed.h
+ )
+
+ # Test old-style install commands.
+ INSTALL_FILES(/MyTest/include FILES lib3.h)
+ INSTALL_FILES(/MyTest/include/old .h lib3)
+ INSTALL_FILES(/MyTest/include/old "^lib2.h$")
+ INSTALL_PROGRAMS(/MyTest/share/old1 FILES
+ scripts/sample_script scripts/sample_script.bat)
+ INSTALL_PROGRAMS(/MyTest/share/old2
+ scripts/sample_script scripts/sample_script.bat)
+
+# "export" the targets collected in "SimpleInstallS1"
+ INSTALL(EXPORT SimpleInstallS1 FILE SimpleInstallS1Config.cmake
+ DESTINATION MyTest/lib
+ NAMESPACE S1_ )
+
+ EXPORT(TARGETS SimpleInstall test1 test2 test3
+ FILE "${CMAKE_CURRENT_BINARY_DIR}/SimpleInstallS1Config.cmake"
+ NAMESPACE S2_ )
+
+ ADD_SUBDIRECTORY(scripts)
+
+ # Test optional installation.
+ INSTALL(FILES does_not_exist.h DESTINATION MyTest/include/foo OPTIONAL)
+
+ # Test configuration-specific installation.
+ INSTALL(FILES lib1.h RENAME lib1release.h CONFIGURATIONS Release
+ DESTINATION MyTest/include/Release
+ )
+ INSTALL(FILES lib1.h RENAME lib1debug.h CONFIGURATIONS Debug
+ DESTINATION MyTest/include/Debug
+ )
+
+ # Test directory installation.
+ 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
+ FILE_PERMISSIONS OWNER_READ OWNER_WRITE
+ DIRECTORY_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
+ GROUP_READ GROUP_EXECUTE
+ PATTERN "CVS" EXCLUDE
+ REGEX "\\.txt$" EXCLUDE
+ PATTERN "scripts/*" PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ
+ )
+
+ # Alternate directory installation for coverage.
+ INSTALL(
+ DIRECTORY scripts/ DESTINATION MyTest/share/alt
+ COMPONENT Development
+ USE_SOURCE_PERMISSIONS
+ PATTERN "CVS" EXCLUDE
+ REGEX "\\.txt$" EXCLUDE
+ )
+ INSTALL(
+ DIRECTORY TestSubDir DESTINATION MyTest/share/alt
+ FILE_PERMISSIONS OWNER_READ OWNER_WRITE
+ DIRECTORY_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
+ GROUP_READ GROUP_EXECUTE
+ FILES_MATCHING PATTERN "*.h"
+ )
+
+ # Test empty directory installation.
+ INSTALL(DIRECTORY DESTINATION MyTest/share/empty)
+
+ # Test optional directory installation.
+ INSTALL(DIRECTORY does-not-exist DESTINATION MyTest/share OPTIONAL)
+
+ # Test user-specified install scripts, with and without COMPONENT.
+ INSTALL(
+ SCRIPT InstallScript1.cmake
+ CODE "SET(INSTALL_CODE_DID_RUN 1)"
+ SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/InstallScript2.cmake
+ )
+ INSTALL(
+ SCRIPT InstallScript3.cmake
+ CODE "SET(INSTALL_CODE_WITH_COMPONENT_DID_RUN 1)"
+ SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/InstallScript4.cmake
+ COMPONENT Development
+ )
+ SET_DIRECTORY_PROPERTIES(PROPERTIES
+ ADDITIONAL_MAKE_CLEAN_FILES
+ "${CMAKE_INSTALL_PREFIX}/InstallScriptOut.cmake;${CMAKE_INSTALL_PREFIX}/InstallScript4Out.cmake")
+
+ SET_TARGET_PROPERTIES(SimpleInstall PROPERTIES PRE_INSTALL_SCRIPT
+ ${CMAKE_CURRENT_SOURCE_DIR}/PreInstall.cmake)
+ SET_TARGET_PROPERTIES(SimpleInstall PROPERTIES POST_INSTALL_SCRIPT
+ ${CMAKE_CURRENT_SOURCE_DIR}/PostInstall.cmake)
+ SET_TARGET_PROPERTIES(test4 PROPERTIES VERSION 1.2 SOVERSION 3
+ INSTALL_NAME_DIR @executable_path/../lib)
+ENDIF(STAGE2)
+
+IF(CMAKE_CONFIGURATION_TYPES)
+ SET(SI_CONFIG -C ${CMAKE_CFG_INTDIR})
+ELSE(CMAKE_CONFIGURATION_TYPES)
+ SET(SI_CONFIG)
+ENDIF(CMAKE_CONFIGURATION_TYPES)
+
+# Dummy test of CPack
+SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Test of packaging with cpack")
+SET(CPACK_PACKAGE_VENDOR "Kitware")
+SET(CPACK_INSTALL_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/PackageScript.cmake")
+
+IF(WIN32 AND NOT UNIX)
+ FIND_PROGRAM(NSIS_MAKENSIS NAMES makensis
+ PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\NSIS]
+ DOC "Where is makensis.exe located"
+ )
+ IF(NOT NSIS_MAKENSIS)
+ SET(CPACK_GENERATOR TGZ)
+ ENDIF(NOT NSIS_MAKENSIS)
+ENDIF(WIN32 AND NOT UNIX)
+IF(UNIX AND NOT APPLE)
+ SET(CPACK_GENERATOR "TGZ;STGZ;TZ")
+ # FIND_PROGRAM(found_compress
+ # NAMES compress)
+ # IF(found_compress)
+ # FIND_PROGRAM(file_command NAMES file)
+ # IF(NOT file_command)
+ # set(file_command file)
+ # ENDIF(NOT file_command)
+ # EXECUTE_PROCESS(COMMAND ${file_command} ${found_compress}
+ # OUTPUT_VARIABLE output)
+ # set(SKIP_TZ FALSE)
+ # if("${output}" MATCHES "script")
+ # set(SKIP_TZ TRUE)
+ # endif("${output}" MATCHES "script")
+ # if("${output}" MATCHES "dummy.sh")
+ # set(SKIP_TZ TRUE)
+ # endif("${output}" MATCHES "dummy.sh")
+ # if(NOT SKIP_TZ)
+ # message("compress found and it was not a script")
+ # message("output from file command: [${output}]")
+ # SET(CPACK_GENERATOR "${CPACK_GENERATOR};TZ")
+ # else(NOT SKIP_TZ)
+ # message("compress found, but it was a script so dont use it")
+ # message("output from file command: [${output}]")
+ # endif(NOT SKIP_TZ)
+ # ENDIF(found_compress)
+ FIND_PROGRAM(found_bz2
+ NAMES bzip2)
+ IF(found_bz2)
+ SET(CPACK_GENERATOR "${CPACK_GENERATOR};TBZ2")
+ ENDIF(found_bz2)
+ENDIF(UNIX AND NOT APPLE)
+
+SET(CPACK_PACKAGE_EXECUTABLES "SimpleInstall" "Simple Install")
+SET(CMAKE_INSTALL_MFC_LIBRARIES 1)
+SET(CMAKE_INSTALL_DEBUG_LIBRARIES 1)
+INCLUDE(InstallRequiredSystemLibraries)
+
+IF(CTEST_TEST_CPACK)
+ SET(PACKAGE_TARGET --build-target package)
+
+ # Avoid settings that require the .zip file command line tools...
+ # (just build an NSIS installer without component support)
+ #
+ SET(CPACK_BINARY_ZIP OFF)
+ SET(CPACK_MONOLITHIC_INSTALL ON)
+ELSE(CTEST_TEST_CPACK)
+ SET(PACKAGE_TARGET)
+ENDIF(CTEST_TEST_CPACK)
+
+INCLUDE(CPack)
+
+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}
+ COMMENT "Install Project"
+ )
diff --git a/Tests/SimpleInstallS2/InstallScript1.cmake b/Tests/SimpleInstallS2/InstallScript1.cmake
new file mode 100644
index 000000000..27b7725f8
--- /dev/null
+++ b/Tests/SimpleInstallS2/InstallScript1.cmake
@@ -0,0 +1,5 @@
+MESSAGE("This is install script 1.")
+SET(INSTALL_SCRIPT_1_DID_RUN 1)
+IF(INSTALL_CODE_DID_RUN)
+ MESSAGE(FATAL_ERROR "Install script 1 did not run before install code.")
+ENDIF(INSTALL_CODE_DID_RUN)
diff --git a/Tests/SimpleInstallS2/InstallScript2.cmake b/Tests/SimpleInstallS2/InstallScript2.cmake
new file mode 100644
index 000000000..927cae8b6
--- /dev/null
+++ b/Tests/SimpleInstallS2/InstallScript2.cmake
@@ -0,0 +1,14 @@
+MESSAGE("This is install script 2.")
+IF(INSTALL_SCRIPT_1_DID_RUN)
+ MESSAGE("Install script ordering works.")
+ELSE(INSTALL_SCRIPT_1_DID_RUN)
+ MESSAGE(FATAL_ERROR "Install script 1 did not run before install script 2.")
+ENDIF(INSTALL_SCRIPT_1_DID_RUN)
+IF(INSTALL_CODE_DID_RUN)
+ MESSAGE("Install code ordering works.")
+ELSE(INSTALL_CODE_DID_RUN)
+ MESSAGE(FATAL_ERROR "Install script 2 did not run after install code.")
+ENDIF(INSTALL_CODE_DID_RUN)
+FILE(WRITE "${CMAKE_INSTALL_PREFIX}/MyTest/InstallScriptOut.cmake"
+ "SET(CMAKE_INSTALL_SCRIPT_DID_RUN 1)\n"
+ )
diff --git a/Tests/SimpleInstallS2/InstallScript3.cmake b/Tests/SimpleInstallS2/InstallScript3.cmake
new file mode 100644
index 000000000..b1aecd4c2
--- /dev/null
+++ b/Tests/SimpleInstallS2/InstallScript3.cmake
@@ -0,0 +1,12 @@
+MESSAGE("This is install script 3.")
+SET(INSTALL_SCRIPT_3_DID_RUN 1)
+IF(INSTALL_CODE_WITH_COMPONENT_DID_RUN)
+ MESSAGE(FATAL_ERROR "Install script 3 did not run before install code with component.")
+ENDIF(INSTALL_CODE_WITH_COMPONENT_DID_RUN)
+
+IF(CMAKE_INSTALL_COMPONENT)
+IF(NOT "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Development")
+ MESSAGE("CMAKE_INSTALL_COMPONENT=\"${CMAKE_INSTALL_COMPONENT}\"")
+ MESSAGE(FATAL_ERROR "Install script 3 should only run for \"Development\" INSTALL COMPONENT.")
+ENDIF(NOT "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Development")
+ENDIF(CMAKE_INSTALL_COMPONENT)
diff --git a/Tests/SimpleInstallS2/InstallScript4.cmake b/Tests/SimpleInstallS2/InstallScript4.cmake
new file mode 100644
index 000000000..0ffea4bc8
--- /dev/null
+++ b/Tests/SimpleInstallS2/InstallScript4.cmake
@@ -0,0 +1,22 @@
+MESSAGE("This is install script 4.")
+IF(INSTALL_SCRIPT_3_DID_RUN)
+ MESSAGE("Install script ordering works.")
+ELSE(INSTALL_SCRIPT_3_DID_RUN)
+ MESSAGE(FATAL_ERROR "Install script 3 did not run before install script 4.")
+ENDIF(INSTALL_SCRIPT_3_DID_RUN)
+IF(INSTALL_CODE_WITH_COMPONENT_DID_RUN)
+ MESSAGE("Install code ordering works.")
+ELSE(INSTALL_CODE_WITH_COMPONENT_DID_RUN)
+ MESSAGE(FATAL_ERROR "Install script 4 did not run after install with component code.")
+ENDIF(INSTALL_CODE_WITH_COMPONENT_DID_RUN)
+
+IF(CMAKE_INSTALL_COMPONENT)
+IF(NOT "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Development")
+ MESSAGE("CMAKE_INSTALL_COMPONENT=\"${CMAKE_INSTALL_COMPONENT}\"")
+ MESSAGE(FATAL_ERROR "Install script 4 should only run for \"Development\" INSTALL COMPONENT.")
+ENDIF(NOT "${CMAKE_INSTALL_COMPONENT}" STREQUAL "Development")
+ENDIF(CMAKE_INSTALL_COMPONENT)
+
+FILE(WRITE "${CMAKE_INSTALL_PREFIX}/MyTest/InstallScript4Out.cmake"
+ "SET(CMAKE_INSTALL_SCRIPT_4_DID_RUN 1)\n"
+ )
diff --git a/Tests/SimpleInstallS2/PackageScript.cmake b/Tests/SimpleInstallS2/PackageScript.cmake
new file mode 100644
index 000000000..3567a2f43
--- /dev/null
+++ b/Tests/SimpleInstallS2/PackageScript.cmake
@@ -0,0 +1,10 @@
+MESSAGE("This is packaging script")
+MESSAGE("It writes a file with all variables available in ${CMAKE_INSTALL_PREFIX}/AllVariables.txt")
+
+FILE(WRITE ${CMAKE_INSTALL_PREFIX}/AllVariables.txt "")
+GET_CMAKE_PROPERTY(res VARIABLES)
+FOREACH(var ${res})
+ FILE(APPEND ${CMAKE_INSTALL_PREFIX}/AllVariables.txt
+ "${var} \"${${var}}\"\n")
+ENDFOREACH(var ${res})
+
diff --git a/Tests/SimpleInstallS2/PostInstall.cmake b/Tests/SimpleInstallS2/PostInstall.cmake
new file mode 100644
index 000000000..52ea140a5
--- /dev/null
+++ b/Tests/SimpleInstallS2/PostInstall.cmake
@@ -0,0 +1,6 @@
+MESSAGE("In post install")
+IF(PRE_INSTALL_DID_RUN)
+ MESSAGE("Pre and post install work fine")
+ELSE(PRE_INSTALL_DID_RUN)
+ MESSAGE(FATAL_ERROR "Pre install did not run before post install")
+ENDIF(PRE_INSTALL_DID_RUN)
diff --git a/Tests/SimpleInstallS2/PreInstall.cmake b/Tests/SimpleInstallS2/PreInstall.cmake
new file mode 100644
index 000000000..2ea2f7716
--- /dev/null
+++ b/Tests/SimpleInstallS2/PreInstall.cmake
@@ -0,0 +1,2 @@
+MESSAGE("This is in pre install")
+SET(PRE_INSTALL_DID_RUN 1)
diff --git a/Tests/SimpleInstallS2/TestSubDir/CMakeLists.txt b/Tests/SimpleInstallS2/TestSubDir/CMakeLists.txt
new file mode 100644
index 000000000..4f6295300
--- /dev/null
+++ b/Tests/SimpleInstallS2/TestSubDir/CMakeLists.txt
@@ -0,0 +1,3 @@
+ADD_EXECUTABLE(TSD TSD.cxx TSD_utils.cxx)
+INSTALL_FILES(/MyTest/include FILES TSD.h)
+INSTALL_TARGETS(/MyTest/bin TSD)
diff --git a/Tests/SimpleInstallS2/TestSubDir/TSD.cxx b/Tests/SimpleInstallS2/TestSubDir/TSD.cxx
new file mode 100644
index 000000000..8fc38787a
--- /dev/null
+++ b/Tests/SimpleInstallS2/TestSubDir/TSD.cxx
@@ -0,0 +1,10 @@
+#include <stdio.h>
+
+#include "TSD.h"
+
+int main()
+{
+ int res = TSD("TEST");
+ printf("Hello from TSD\n");
+ return res;
+}
diff --git a/Tests/SimpleInstallS2/TestSubDir/TSD.h b/Tests/SimpleInstallS2/TestSubDir/TSD.h
new file mode 100644
index 000000000..6a3c1affa
--- /dev/null
+++ b/Tests/SimpleInstallS2/TestSubDir/TSD.h
@@ -0,0 +1 @@
+int TSD(const char*);
diff --git a/Tests/SimpleInstallS2/TestSubDir/TSD_utils.cxx b/Tests/SimpleInstallS2/TestSubDir/TSD_utils.cxx
new file mode 100644
index 000000000..0277f05ae
--- /dev/null
+++ b/Tests/SimpleInstallS2/TestSubDir/TSD_utils.cxx
@@ -0,0 +1,10 @@
+#include <string.h>
+
+int TSD(const char* foo)
+{
+ if ( strcmp(foo, "TEST") == 0 )
+ {
+ return 0;
+ }
+ return 1;
+}
diff --git a/Tests/SimpleInstallS2/foo.c b/Tests/SimpleInstallS2/foo.c
new file mode 100644
index 000000000..45d5b2bf2
--- /dev/null
+++ b/Tests/SimpleInstallS2/foo.c
@@ -0,0 +1,6 @@
+char* foo = "Foo";
+
+int SomeFunctionInFoo()
+{
+ return 5;
+}
diff --git a/Tests/SimpleInstallS2/foo.h b/Tests/SimpleInstallS2/foo.h
new file mode 100644
index 000000000..2708baffe
--- /dev/null
+++ b/Tests/SimpleInstallS2/foo.h
@@ -0,0 +1,11 @@
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern char* foo;
+extern int SomeFunctionInFoo();
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/Tests/SimpleInstallS2/inst.cxx b/Tests/SimpleInstallS2/inst.cxx
new file mode 100644
index 000000000..7f2962d00
--- /dev/null
+++ b/Tests/SimpleInstallS2/inst.cxx
@@ -0,0 +1,37 @@
+#include "foo.h"
+
+#ifdef STAGE_2
+# include <foo/lib1.h>
+# include <foo/lib2renamed.h>
+# include <lib3.h>
+# include <old/lib2.h>
+# include <old/lib3.h>
+#else
+# include "lib1.h"
+# include "lib2.h"
+#endif
+
+#include "lib4.h"
+
+#include <stdio.h>
+
+int main ()
+{
+ if ( Lib1Func() != 2.0 )
+ {
+ printf("Problem with lib1\n");
+ return 1;
+ }
+ if ( Lib2Func() != 1.0 )
+ {
+ printf("Problem with lib2\n");
+ return 1;
+ }
+ if ( Lib4Func() != 4.0 )
+ {
+ printf("Problem with lib4\n");
+ return 1;
+ }
+ printf("The value of Foo: %s\n", foo);
+ return SomeFunctionInFoo()-5;
+}
diff --git a/Tests/SimpleInstallS2/inst2.cxx b/Tests/SimpleInstallS2/inst2.cxx
new file mode 100644
index 000000000..c70b93af1
--- /dev/null
+++ b/Tests/SimpleInstallS2/inst2.cxx
@@ -0,0 +1,2 @@
+#define STAGE_2
+#include "inst.cxx"
diff --git a/Tests/SimpleInstallS2/lib1.cxx b/Tests/SimpleInstallS2/lib1.cxx
new file mode 100644
index 000000000..7aa905205
--- /dev/null
+++ b/Tests/SimpleInstallS2/lib1.cxx
@@ -0,0 +1,6 @@
+#include "lib1.h"
+
+float Lib1Func()
+{
+ return 2.0;
+}
diff --git a/Tests/SimpleInstallS2/lib1.h b/Tests/SimpleInstallS2/lib1.h
new file mode 100644
index 000000000..0d64e76bc
--- /dev/null
+++ b/Tests/SimpleInstallS2/lib1.h
@@ -0,0 +1 @@
+extern float Lib1Func();
diff --git a/Tests/SimpleInstallS2/lib2.cxx b/Tests/SimpleInstallS2/lib2.cxx
new file mode 100644
index 000000000..dccc48b78
--- /dev/null
+++ b/Tests/SimpleInstallS2/lib2.cxx
@@ -0,0 +1,6 @@
+#include "lib2.h"
+
+float Lib2Func()
+{
+ return 1.0;
+}
diff --git a/Tests/SimpleInstallS2/lib2.h b/Tests/SimpleInstallS2/lib2.h
new file mode 100644
index 000000000..ea5a6f7ea
--- /dev/null
+++ b/Tests/SimpleInstallS2/lib2.h
@@ -0,0 +1,11 @@
+#ifdef _WIN32
+# ifdef test2_EXPORTS
+# define CM_TEST_LIB_EXPORT __declspec( dllexport )
+# else
+# define CM_TEST_LIB_EXPORT __declspec( dllimport )
+# endif
+#else
+# define CM_TEST_LIB_EXPORT
+#endif
+
+CM_TEST_LIB_EXPORT float Lib2Func();
diff --git a/Tests/SimpleInstallS2/lib3.cxx b/Tests/SimpleInstallS2/lib3.cxx
new file mode 100644
index 000000000..da8dbf942
--- /dev/null
+++ b/Tests/SimpleInstallS2/lib3.cxx
@@ -0,0 +1,6 @@
+#include "lib3.h"
+
+float Lib3Func()
+{
+ return 2.0;
+}
diff --git a/Tests/SimpleInstallS2/lib3.h b/Tests/SimpleInstallS2/lib3.h
new file mode 100644
index 000000000..c250ed769
--- /dev/null
+++ b/Tests/SimpleInstallS2/lib3.h
@@ -0,0 +1,11 @@
+#ifdef _WIN32
+# ifdef test3_EXPORTS
+# define CM_TEST_LIB_EXPORT __declspec( dllexport )
+# else
+# define CM_TEST_LIB_EXPORT __declspec( dllimport )
+# endif
+#else
+# define CM_TEST_LIB_EXPORT
+#endif
+
+CM_TEST_LIB_EXPORT float Lib3Func();
diff --git a/Tests/SimpleInstallS2/lib4.cxx b/Tests/SimpleInstallS2/lib4.cxx
new file mode 100644
index 000000000..fbfa23aa4
--- /dev/null
+++ b/Tests/SimpleInstallS2/lib4.cxx
@@ -0,0 +1,7 @@
+#include "lib4.h"
+
+float Lib4Func()
+{
+ return 4.0;
+}
+
diff --git a/Tests/SimpleInstallS2/lib4.h b/Tests/SimpleInstallS2/lib4.h
new file mode 100644
index 000000000..4b94ea207
--- /dev/null
+++ b/Tests/SimpleInstallS2/lib4.h
@@ -0,0 +1,12 @@
+#ifdef _WIN32
+# ifdef test4_EXPORTS
+# define CM_TEST_LIB_EXPORT __declspec( dllexport )
+# else
+# define CM_TEST_LIB_EXPORT __declspec( dllimport )
+# endif
+#else
+# define CM_TEST_LIB_EXPORT
+#endif
+
+CM_TEST_LIB_EXPORT float Lib4Func();
+
diff --git a/Tests/SimpleInstallS2/scripts/.gitattributes b/Tests/SimpleInstallS2/scripts/.gitattributes
new file mode 100644
index 000000000..5e3db2fb3
--- /dev/null
+++ b/Tests/SimpleInstallS2/scripts/.gitattributes
@@ -0,0 +1 @@
+sample_script crlf=input
diff --git a/Tests/SimpleInstallS2/scripts/CMakeLists.txt b/Tests/SimpleInstallS2/scripts/CMakeLists.txt
new file mode 100644
index 000000000..d46c1652e
--- /dev/null
+++ b/Tests/SimpleInstallS2/scripts/CMakeLists.txt
@@ -0,0 +1 @@
+INSTALL_PROGRAMS(/MyTest/share/old3 "^sample_script(\\.bat)?$")
diff --git a/Tests/SimpleInstallS2/scripts/sample_script b/Tests/SimpleInstallS2/scripts/sample_script
new file mode 100755
index 000000000..81f9f5315
--- /dev/null
+++ b/Tests/SimpleInstallS2/scripts/sample_script
@@ -0,0 +1,2 @@
+#!/bin/sh
+echo "Sample Script Output"
diff --git a/Tests/SimpleInstallS2/scripts/sample_script.bat b/Tests/SimpleInstallS2/scripts/sample_script.bat
new file mode 100755
index 000000000..64a77b5b0
--- /dev/null
+++ b/Tests/SimpleInstallS2/scripts/sample_script.bat
@@ -0,0 +1 @@
+@echo Sample Script Output
diff --git a/Tests/SourceGroups/CMakeLists.txt b/Tests/SourceGroups/CMakeLists.txt
new file mode 100644
index 000000000..c3cf38c7a
--- /dev/null
+++ b/Tests/SourceGroups/CMakeLists.txt
@@ -0,0 +1,35 @@
+cmake_minimum_required (VERSION 2.6)
+project(SourceGroups)
+
+# this is not really a test which can fail
+# it is more an example with several source_group()
+# commands.
+# The created projects have to be loaded manually
+# in Visual Studio/Xcode/Eclipse/...
+# to see whether the correct groups have been created.
+
+source_group(Base FILES main.c)
+
+# a sub group
+source_group(Base\\Sub1 FILES sub1/foo.c)
+
+# a sub sub group
+source_group(Base\\Sub1\\Sub2 FILES sub1/foobar.c)
+
+# a group with empty name
+source_group("" FILES foo.c)
+
+# a group, whose name consists only of the delimiter
+#should be handled the same way as an empty name
+source_group("\\" FILES baz.c)
+
+# a sub sub group whose last component has the same name
+# as an already existing group
+source_group(Base\\Sub1\\Base FILES bar.c)
+
+# a group without files, is currently not created
+source_group(EmptyGroup)
+
+
+add_executable(SourceGroups main.c bar.c foo.c sub1/foo.c sub1/foobar.c baz.c README.txt)
+
diff --git a/Tests/SourceGroups/README.txt b/Tests/SourceGroups/README.txt
new file mode 100644
index 000000000..1a4baf536
--- /dev/null
+++ b/Tests/SourceGroups/README.txt
@@ -0,0 +1 @@
+
diff --git a/Tests/SourceGroups/bar.c b/Tests/SourceGroups/bar.c
new file mode 100644
index 000000000..a2fcad5e9
--- /dev/null
+++ b/Tests/SourceGroups/bar.c
@@ -0,0 +1,4 @@
+int barbar(void)
+{
+ return 2;
+}
diff --git a/Tests/SourceGroups/baz.c b/Tests/SourceGroups/baz.c
new file mode 100644
index 000000000..477f4fa6e
--- /dev/null
+++ b/Tests/SourceGroups/baz.c
@@ -0,0 +1,4 @@
+int baz(void)
+{
+ return 13;
+}
diff --git a/Tests/SourceGroups/foo.c b/Tests/SourceGroups/foo.c
new file mode 100644
index 000000000..3bebc4d22
--- /dev/null
+++ b/Tests/SourceGroups/foo.c
@@ -0,0 +1,4 @@
+int bar(void)
+{
+ return 42;
+}
diff --git a/Tests/SourceGroups/main.c b/Tests/SourceGroups/main.c
new file mode 100644
index 000000000..212e64baa
--- /dev/null
+++ b/Tests/SourceGroups/main.c
@@ -0,0 +1,13 @@
+#include <stdio.h>
+
+extern int foo(void);
+extern int bar(void);
+extern int foobar(void);
+extern int barbar(void);
+extern int baz(void);
+
+int main()
+{
+ printf("foo: %d bar: %d foobar: %d barbar: %d baz: %d\n", foo(), bar(), foobar(), barbar(), baz());
+ return 0;
+}
diff --git a/Tests/SourceGroups/sub1/foo.c b/Tests/SourceGroups/sub1/foo.c
new file mode 100644
index 000000000..39912a748
--- /dev/null
+++ b/Tests/SourceGroups/sub1/foo.c
@@ -0,0 +1,4 @@
+int foo(void)
+{
+ return 17;
+}
diff --git a/Tests/SourceGroups/sub1/foobar.c b/Tests/SourceGroups/sub1/foobar.c
new file mode 100644
index 000000000..32588b5e1
--- /dev/null
+++ b/Tests/SourceGroups/sub1/foobar.c
@@ -0,0 +1,4 @@
+int foobar(void)
+{
+ return 1477;
+}
diff --git a/Tests/StringFileTest/CMakeLists.txt b/Tests/StringFileTest/CMakeLists.txt
new file mode 100644
index 000000000..7792a353d
--- /dev/null
+++ b/Tests/StringFileTest/CMakeLists.txt
@@ -0,0 +1,282 @@
+cmake_minimum_required (VERSION 2.6)
+PROJECT(StringFileTest)
+INCLUDE_DIRECTORIES(${StringFileTest_BINARY_DIR})
+
+# Read file test
+FILE(READ "${CMAKE_CURRENT_SOURCE_DIR}/InputFile.h.in" infile)
+
+# Test reading a binary file into hex representation
+FILE(READ "${CMAKE_CURRENT_SOURCE_DIR}/test.bin" hexContents HEX)
+
+IF("${hexContents}" STREQUAL "0001027700")
+ MESSAGE("FILE(READ HEX) correctly read [${hexContents}]")
+ELSE("${hexContents}" STREQUAL "0001027700")
+ MESSAGE(SEND_ERROR "FILE(READ HEX) incorrectly read [${hexContents}], but expected was [0001027700]")
+ENDIF("${hexContents}" STREQUAL "0001027700")
+
+# FILE(STRINGS) test
+FILE(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/InputFile.h.in" infile_strings
+ LIMIT_COUNT 1 LIMIT_INPUT 1024 LIMIT_OUTPUT 1024
+ LENGTH_MINIMUM 10 LENGTH_MAXIMUM 23 REGEX include NEWLINE_CONSUME)
+SET(infile_strings_goal "#include \"includefile\"\n")
+IF("${infile_strings}" STREQUAL "${infile_strings_goal}")
+ MESSAGE("FILE(STRINGS) correctly read [${infile_strings}]")
+ELSE("${infile_strings}" STREQUAL "${infile_strings_goal}")
+ MESSAGE(SEND_ERROR
+ "FILE(STRINGS) incorrectly read [${infile_strings}]")
+ENDIF("${infile_strings}" STREQUAL "${infile_strings_goal}")
+
+# test reading a file and getting its binary data as hex string
+FILE(READ "${CMAKE_CURRENT_SOURCE_DIR}/main.srec" infilehex LIMIT 4 HEX)
+IF(NOT "${infilehex}" STREQUAL "53313036")
+ MESSAGE(SEND_ERROR
+ "FILE(READ ... HEX) error, read: \"${infilehex}\", expected \"53313036\"")
+ENDIF(NOT "${infilehex}" STREQUAL "53313036")
+
+
+# test that FILE(STRINGS) also work with Intel hex and Motorola S-record files
+# this file has been created with "sdcc main.c"
+FILE(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/main.ihx" infile_strings REGEX INFO)
+SET(infile_strings_goal "INFO:compiler\\[SDCC-HEX\\]")
+IF("${infile_strings}" MATCHES "${infile_strings_goal}")
+ MESSAGE("FILE(STRINGS) correctly read from hex file [${infile_strings}]")
+ELSE("${infile_strings}" MATCHES "${infile_strings_goal}")
+ MESSAGE(SEND_ERROR
+ "FILE(STRINGS) incorrectly read from hex file [${infile_strings}]")
+ENDIF("${infile_strings}" MATCHES "${infile_strings_goal}")
+
+# this file has been created with "sdcc main.c --out-fmt-s19"
+FILE(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/main.srec" infile_strings REGEX INFO)
+SET(infile_strings_goal "INFO:compiler\\[SDCC-SREC\\]")
+IF("${infile_strings}" MATCHES "${infile_strings_goal}")
+ MESSAGE("FILE(STRINGS) correctly read from srec file [${infile_strings}]")
+ELSE("${infile_strings}" MATCHES "${infile_strings_goal}")
+ MESSAGE(SEND_ERROR
+ "FILE(STRINGS) incorrectly read from srec file [${infile_strings}]")
+ENDIF("${infile_strings}" MATCHES "${infile_strings_goal}")
+
+# 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")
+STRING(REGEX REPLACE "[Aa][uU][tT][oO]([cC][oO][nN][fF]|[mM][aA][kK][eE])"
+ "CMake" rrepvar "People should use Autoconf and Automake")
+STRING(COMPARE EQUAL "CMake" "Autoconf" nceqvar)
+STRING(COMPARE EQUAL "CMake" "CMake" ceqvar)
+STRING(COMPARE NOTEQUAL "CMake" "Autoconf" cneqvar)
+STRING(COMPARE NOTEQUAL "CMake" "CMake" ncneqvar)
+STRING(COMPARE LESS "before" "after" nclvar)
+STRING(COMPARE LESS "max" "min" clvar)
+STRING(COMPARE GREATER "before" "after" cgvar)
+STRING(COMPARE GREATER "max" "min" ncgvar)
+STRING(ASCII 67 109 97 107 101 savar)
+STRING(TOUPPER "CMake" tuvar)
+STRING(TOLOWER "CMake" tlvar)
+STRING(REPLACE "Autoconf" "CMake" repvar "People should use Autoconf")
+
+IF("abc" STREQUAL "xyz")
+ MESSAGE(SEND_ERROR "Problem with the IF(STREQUAL), \"abc\" and \"xyz\" considered equal")
+ENDIF("abc" STREQUAL "xyz")
+
+IF("CMake is cool" MATCHES "(CMake) (is).+")
+ IF(NOT "${CMAKE_MATCH_0}" STREQUAL "CMake is cool")
+ MESSAGE(SEND_ERROR "CMAKE_MATCH_0 wrong: \"${CMAKE_MATCH_0}\", expected \"CMake is cool\"")
+ ENDIF(NOT "${CMAKE_MATCH_0}" STREQUAL "CMake is cool")
+ IF(NOT "${CMAKE_MATCH_1}" STREQUAL "CMake")
+ MESSAGE(SEND_ERROR "CMAKE_MATCH_1 wrong: \"${CMAKE_MATCH_1}\", expected \"CMake\"")
+ ENDIF(NOT "${CMAKE_MATCH_1}" STREQUAL "CMake")
+ IF(NOT "${CMAKE_MATCH_2}" STREQUAL "is")
+ MESSAGE(SEND_ERROR "CMAKE_MATCH_2 wrong: \"${CMAKE_MATCH_2}\", expected \"is\"")
+ ENDIF(NOT "${CMAKE_MATCH_2}" STREQUAL "is")
+ELSE("CMake is cool" MATCHES "(CMake) (is).+")
+ MESSAGE(SEND_ERROR "Problem with the IF(MATCHES), no match found")
+ENDIF("CMake is cool" MATCHES "(CMake) (is).+")
+
+STRING(REGEX MATCH "(People).+CMake" matchResultVar "People should use CMake")
+IF(NOT "${matchResultVar}" STREQUAL "People should use CMake")
+ MESSAGE(SEND_ERROR "STRING(REGEX MATCH) problem: \"${matchResultVar}\", expected \"People should use CMake\"")
+ENDIF(NOT "${matchResultVar}" STREQUAL "People should use CMake")
+IF(NOT "${CMAKE_MATCH_0}" STREQUAL "People should use CMake")
+ MESSAGE(SEND_ERROR "CMAKE_MATCH_0 wrong: \"${CMAKE_MATCH_0}\", expected \"People should use CMake\"")
+ENDIF(NOT "${CMAKE_MATCH_0}" STREQUAL "People should use CMake")
+IF(NOT "${CMAKE_MATCH_1}" STREQUAL "People")
+ MESSAGE(SEND_ERROR "CMAKE_MATCH_1 wrong: \"${CMAKE_MATCH_1}\", expected \"People\"")
+ENDIF(NOT "${CMAKE_MATCH_1}" STREQUAL "People")
+IF(NOT "${CMAKE_MATCH_2}" STREQUAL "")
+ MESSAGE(SEND_ERROR "CMAKE_MATCH_2 wrong: \"${CMAKE_MATCH_2}\", expected empty string")
+ENDIF(NOT "${CMAKE_MATCH_2}" STREQUAL "")
+
+
+STRING(STRIP "
+ ST1
+ " ST1)
+STRING(STRIP "ST2 " ST2)
+STRING(STRIP " ST3" ST3)
+
+FOREACH(var ST1 ST2 ST3)
+ IF("${var}" STREQUAL "${${var}}")
+ MESSAGE("[${var}] == [${${var}}]")
+ ELSE("${var}" STREQUAL "${${var}}")
+ MESSAGE(SEND_ERROR "Problem with the STRIP command for ${var}: [${${var}}]")
+ ENDIF("${var}" STREQUAL "${${var}}")
+ENDFOREACH(var)
+
+STRING(SUBSTRING "People should use Autoconf" 7 10 substringres)
+SET(substringres "Everybody ${substringres} CMake")
+
+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}]")
+STRING(COMPARE EQUAL "${var}" "$(VAR1)$(VAR2)/$(VAR3)" result)
+IF(NOT result)
+ MESSAGE(SEND_ERROR "Unquoted $(VAR) syntax is broken.")
+ENDIF(NOT result)
+
+# 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"
+ "${CMAKE_CURRENT_BINARY_DIR}/Directory1"
+ "${CMAKE_CURRENT_BINARY_DIR}/Directory2"
+ )
+
+# Write results to the file (test write file)
+SET(file "${CMAKE_CURRENT_BINARY_DIR}/Includes/Values.h")
+FILE(WRITE "${file}" "/* this file is generated */\n")
+FOREACH(var
+ rmvar
+ rmallvar
+ rrepvar
+ repvar
+ relpath
+ substringres
+ lengthres
+ nceqvar
+ ceqvar
+ cneqvar
+ ncneqvar
+ nclvar
+ clvar
+ cgvar
+ ncgvar
+ savar
+ tuvar
+ tlvar)
+ FILE(APPEND "${file}" "#define ${var} \"${${var}}\"\n")
+ENDFOREACH(var)
+
+# Verify that the file was created recently.
+IF(NOT "${file}" IS_NEWER_THAN "${CMAKE_CURRENT_SOURCE_DIR}/InputFile.h.in")
+ MESSAGE(FATAL_ERROR "IF(FILE_IS_NEWER) does not seem to work.")
+ENDIF(NOT "${file}" IS_NEWER_THAN "${CMAKE_CURRENT_SOURCE_DIR}/InputFile.h.in")
+
+# Test configuration of the string
+SET(TEST_DEFINED 123)
+SET(TEST_NOT_DEFINED)
+STRING(CONFIGURE "${infile}" infile+-/out @ONLY)
+SET(infile "${infile+-/out}")
+
+# Write include file to a file
+STRING(REGEX REPLACE "includefile" "${file}" 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")
+
+# Test file copy with relative paths
+FILE(COPY .
+ DESTINATION src
+ FILE_PERMISSIONS OWNER_READ # test no OWNER_WRITE
+ DIRECTORY_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
+ FILES_MATCHING PATTERN *.cxx # Only copy the main source file
+ REGEX /src$ EXCLUDE # Block recursion for in-source build
+ )
+
+# Test file glob
+FILE(GLOB_RECURSE src_files "${CMAKE_CURRENT_SOURCE_DIR}/*")
+MESSAGE("Files in ${CMAKE_CURRENT_SOURCE_DIR} are ${src_files}")
+SET(expr "${CMAKE_CURRENT_BINARY_DIR}/src/[sS][!a-su-zA-Z0-9][^a-qs-zA-Z0-9]ing?ile*.cxx")
+MESSAGE("Glob expression is [${expr}].")
+FILE(GLOB src_files "${expr}")
+MESSAGE("Globbed files [${src_files}].")
+ADD_EXECUTABLE(StringFileTest ${src_files})
+
+SET(expr "${CMAKE_CURRENT_SOURCE_DIR}/../*.cxx")
+FILE(GLOB_RECURSE rel_src_files RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/.." "${expr}")
+MESSAGE("Globbed files [${rel_src_files}].")
+
+# Test FOREACH range
+MESSAGE("Cheack if FOREACH with RANGE works")
+MACRO(TEST_RANGE ARGS CHECK)
+ SET(r)
+ FOREACH(a RANGE ${ARGS})
+ SET(r ${r} ${a})
+ ENDFOREACH(a)
+ MESSAGE("FOREACH with RANGE ${ARGS} produces ${r}")
+ IF("x${r}x" MATCHES "^x${CHECK}x$")
+ ELSE("x${r}x" MATCHES "^x${CHECK}x$")
+ MESSAGE(SEND_ERROR "The range resulted in: ${r} should be ${CHECK}")
+ ENDIF("x${r}x" MATCHES "^x${CHECK}x$")
+ENDMACRO(TEST_RANGE)
+TEST_RANGE("5" "0;1;2;3;4;5")
+TEST_RANGE("3;5" "3;4;5")
+TEST_RANGE("5;3" "5;4;3")
+TEST_RANGE("3;10;2" "3;5;7;9")
+TEST_RANGE("10;0;-3" "10;7;4;1")
+
+# Test FOREACH IN signature
+set(list1 "" a "")
+set(list2 a "" b)
+set(var_)
+set(var_a)
+set(var_b)
+foreach(item IN LISTS list1 list2 ITEMS "" a "")
+ set(var_${item} "${var_${item}}x")
+endforeach(item)
+if(NOT "${var_}" STREQUAL "xxxxx")
+ message(FATAL_ERROR "count incorrect for \"\": [${var_}]")
+endif()
+if(NOT "${var_a}" STREQUAL "xxx")
+ message(FATAL_ERROR "count incorrect for \"a\": [${var_a}]")
+endif()
+if(NOT "${var_b}" STREQUAL "x")
+ message(FATAL_ERROR "count incorrect \"b\": [${var_b}]")
+endif()
+
+# Test SUBSTRING command
+SET(ST_INPUTSTRING "0123456789")
+STRING(SUBSTRING ${ST_INPUTSTRING} 3 0 ST_EMPTY)
+STRING(SUBSTRING ${ST_INPUTSTRING} 1 1 ST_ONE)
+STRING(SUBSTRING ${ST_INPUTSTRING} 0 10 ST_ALL)
+STRING(SUBSTRING ${ST_INPUTSTRING} 0 -1 ST_ALL_MINUS)
+STRING(SUBSTRING ${ST_INPUTSTRING} 9 -1 ST_NINE)
+
+IF(ST_EMPTY)
+ MESSAGE(SEND_ERROR "SUBSTRING with length 0 does not return an empty string")
+ENDIF(ST_EMPTY)
+IF(NOT ST_ONE STREQUAL "1")
+ MESSAGE(SEND_ERROR "SUBSTING command does not cut the correct selected character, was \"" ${ST_ONE} "\", should be \"1\"")
+ENDIF(NOT ST_ONE STREQUAL "1")
+IF(NOT ST_INPUTSTRING STREQUAL ST_ALL)
+ MESSAGE(SEND_ERROR "SUBSTRING does not return the whole string when selected with length")
+ENDIF(NOT ST_INPUTSTRING STREQUAL ST_ALL)
+IF(NOT ST_INPUTSTRING STREQUAL ST_ALL_MINUS)
+ MESSAGE(SEND_ERROR "SUBSTRING does not return the whole string when selected with -1")
+ENDIF(NOT ST_INPUTSTRING STREQUAL ST_ALL_MINUS)
+IF(NOT ST_NINE STREQUAL "9")
+ MESSAGE(SEND_ERROR "SUBSTRING does not return the tail when selected with -1")
+ENDIF(NOT ST_NINE STREQUAL "9")
diff --git a/Tests/StringFileTest/InputFile.h.in b/Tests/StringFileTest/InputFile.h.in
new file mode 100644
index 000000000..3e70a36e8
--- /dev/null
+++ b/Tests/StringFileTest/InputFile.h.in
@@ -0,0 +1,38 @@
+#include "includefile"
+
+/* This should be configured to a define. */
+#cmakedefine TEST_DEFINED @TEST_DEFINED@
+/* This should be configured to a commented undef with the curlies in place */
+#cmakedefine TEST_NOT_DEFINED ${TEST_NOT_DEFINED}
+
+/* This complicated line should be configured unchanged: */
+static const char* configvar =
+"@$@$junk =~ s/#$xyz#/$foo_bar{$wibble}->{$xyz}/;@@";
+
+int CheckMethod(const char* var, const char* val )
+{
+ if ( !var )
+ {
+ printf("Var not specified\n");
+ return 1;
+ }
+ if ( !val )
+ {
+ printf("Val not specified\n");
+ return 1;
+ }
+ if ( strcmp(var, val) != 0)
+ {
+ printf("Var (%s) and Val (%s) are not the same...\n", var, val);
+ return 1;
+ }
+#if !defined(TEST_DEFINED) || TEST_DEFINED != 123
+ printf("TEST_DEFINED is not defined to 123\n");
+ return 1;
+#elif defined(TEST_NOT_DEFINED)
+ printf("TEST_NOT_DEFINED is defined\n");
+ return 1;
+#else
+ return 0;
+#endif
+}
diff --git a/Tests/StringFileTest/StringFile.cxx b/Tests/StringFileTest/StringFile.cxx
new file mode 100644
index 000000000..609ebaf20
--- /dev/null
+++ b/Tests/StringFileTest/StringFile.cxx
@@ -0,0 +1,31 @@
+#include <stdio.h>
+#include <string.h>
+#include "OutputFile.h"
+
+int main(int, char*[])
+{
+ int res = 0;
+
+ res += CheckMethod(rmvar, "CMake");
+ res += CheckMethod(rmallvar, "CMake;cmake;CMake");
+ res += CheckMethod(rrepvar, "People should use CMake and CMake");
+ res += CheckMethod(repvar, "People should use CMake");
+ res += CheckMethod(substringres, "Everybody should use CMake");
+ res += CheckMethod(nceqvar, "0");
+ res += CheckMethod(lengthres, "26");
+ res += CheckMethod(ceqvar, "1");
+ res += CheckMethod(cneqvar, "1");
+ res += CheckMethod(ncneqvar, "0");
+ res += CheckMethod(nclvar, "0");
+ res += CheckMethod(clvar, "1");
+ res += CheckMethod(cgvar, "1");
+ res += CheckMethod(ncgvar, "0");
+ res += CheckMethod(savar, "Cmake");
+ res += CheckMethod(tuvar, "CMAKE");
+ res += CheckMethod(tlvar, "cmake");
+ res += CheckMethod(relpath, "../../X11R6/bin/xnest");
+ res += CheckMethod(configvar,
+ "@$@$junk =~ s/#$xyz#/$foo_bar{$wibble}->{$xyz}/;@@");
+
+ return res;
+}
diff --git a/Tests/StringFileTest/main.ihx b/Tests/StringFileTest/main.ihx
new file mode 100644
index 000000000..c1d1dd2b3
--- /dev/null
+++ b/Tests/StringFileTest/main.ihx
@@ -0,0 +1,21 @@
+:03000000020003F8
+:03005C0002005F40
+:05005F0012006480FEA8
+:010064002279
+:0E006900494E464F3A636F6D70696C65725B6D
+:0A007700534443432D4845585D00F3
+:06003200E478FFF6D8FDA2
+:080010007900E94400601B7A4D
+:0500180000900081785A
+:03001D000075A0CB
+:0A00200000E493F2A308B800020503
+:08002A00A0D9F4DAF275A0FF81
+:080038007800E84400600A7939
+:030040000075A0A8
+:0600430000E4F309D8FC03
+:080049007800E84400600C7926
+:0B00510000900000E4F0A3D8FCD9FAF6
+:03000300758107FD
+:0A000600120065E582600302005F4E
+:04006500758200227E
+:00000001FF
diff --git a/Tests/StringFileTest/main.srec b/Tests/StringFileTest/main.srec
new file mode 100644
index 000000000..bd47c29cc
--- /dev/null
+++ b/Tests/StringFileTest/main.srec
@@ -0,0 +1,21 @@
+S1060000020003F4
+S106005C02005F3C
+S108005F12006480FEA4
+S10400642275
+S1110069494E464F3A636F6D70696C65725B69
+S10E0077534443432D535245435D00A6
+S1090032E478FFF6D8FD9E
+S10B00107900E94400601B7A49
+S1080018009000827855
+S106001D0075A0C7
+S10D002000E493F2A308B8000205FF
+S10B002AA0D9F4DAF275A0FF7D
+S10B00387800E84400600A7935
+S10600400075A0A4
+S109004300E4F309D8FCFF
+S10B00497800E84400600C7922
+S10E005100900000E4F0A3D8FCD9FAF2
+S1060003758107F9
+S10D0006120065E582600302005F4A
+S1070065758200227A
+S9030000FC
diff --git a/Tests/StringFileTest/test.bin b/Tests/StringFileTest/test.bin
new file mode 100644
index 000000000..18d62a144
--- /dev/null
+++ b/Tests/StringFileTest/test.bin
Binary files differ
diff --git a/Tests/SubDir/AnotherSubdir/pair+int.int.c b/Tests/SubDir/AnotherSubdir/pair+int.int.c
new file mode 100644
index 000000000..b7a623781
--- /dev/null
+++ b/Tests/SubDir/AnotherSubdir/pair+int.int.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+void pair_stuff()
+{
+ printf("Placeholder for a strange file in subdirectory\n");
+}
diff --git a/Tests/SubDir/AnotherSubdir/pair_int.int.c b/Tests/SubDir/AnotherSubdir/pair_int.int.c
new file mode 100644
index 000000000..b7a623781
--- /dev/null
+++ b/Tests/SubDir/AnotherSubdir/pair_int.int.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+void pair_stuff()
+{
+ printf("Placeholder for a strange file in subdirectory\n");
+}
diff --git a/Tests/SubDir/AnotherSubdir/secondone.c b/Tests/SubDir/AnotherSubdir/secondone.c
new file mode 100644
index 000000000..3e9e5afe6
--- /dev/null
+++ b/Tests/SubDir/AnotherSubdir/secondone.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+void secondone()
+{
+ printf("Hello again\n");
+}
diff --git a/Tests/SubDir/AnotherSubdir/testfromsubdir.c b/Tests/SubDir/AnotherSubdir/testfromsubdir.c
new file mode 100644
index 000000000..34b6e7a88
--- /dev/null
+++ b/Tests/SubDir/AnotherSubdir/testfromsubdir.c
@@ -0,0 +1,14 @@
+#include <stdio.h>
+
+void secondone();
+void pair_stuff();
+void vcl_stuff();
+
+int main()
+{
+ printf("Hello from subdirectory\n");
+ secondone();
+ pair_stuff();
+ vcl_stuff();
+ return 0;
+}
diff --git a/Tests/SubDir/CMakeLists.txt b/Tests/SubDir/CMakeLists.txt
new file mode 100644
index 000000000..9cfbe25ce
--- /dev/null
+++ b/Tests/SubDir/CMakeLists.txt
@@ -0,0 +1,46 @@
+cmake_minimum_required (VERSION 2.6)
+PROJECT(SUBDIR)
+SUBDIRS(Executable EXCLUDE_FROM_ALL Examples)
+WRITE_FILE(${SUBDIR_BINARY_DIR}/ShouldBeHere "This file should exist.")
+#WATCOM WMAKE does not support + in the name of a file!
+IF(WATCOM)
+ SET(PLUS_NAME_FILES
+ AnotherSubdir/pair_int.int.c
+ vcl_algorithm_vcl_pair_double.foo.c)
+ELSE(WATCOM)
+ SET(PLUS_NAME_FILES
+ AnotherSubdir/pair+int.int.c
+ vcl_algorithm+vcl_pair+double.foo.c)
+ENDIF(WATCOM)
+
+ADD_EXECUTABLE(TestFromSubdir
+ AnotherSubdir/testfromsubdir.c
+ AnotherSubdir/secondone
+ ${PLUS_NAME_FILES}
+ )
+
+AUX_SOURCE_DIRECTORY(ThirdSubDir SOURCES)
+IF(WATCOM)
+ FOREACH(f ${SOURCES})
+ IF("${f}" STREQUAL "ThirdSubDir/pair+int.int1.c")
+ ELSE("${f}" STREQUAL "ThirdSubDir/pair+int.int1.c")
+ SET(SOURCES2 ${f} ${SOURCES2})
+ ENDIF("${f}" STREQUAL "ThirdSubDir/pair+int.int1.c")
+ ENDFOREACH(f)
+ SET(SOURCES ${SOURCES2})
+ SET(SOURCES ${SOURCES}
+ vcl_algorithm_vcl_pair_double.foo.c)
+ELSE(WATCOM)
+ FOREACH(f ${SOURCES})
+ IF("${f}" STREQUAL "ThirdSubDir/pair_int.int1.c")
+ ELSE("${f}" STREQUAL "ThirdSubDir/pair_int.int1.c")
+ SET(SOURCES2 ${f} ${SOURCES2})
+ MESSAGE("${f}")
+ ENDIF("${f}" STREQUAL "ThirdSubDir/pair_int.int1.c")
+ ENDFOREACH(f)
+ SET(SOURCES ${SOURCES2})
+ SET(SOURCES ${SOURCES}
+ vcl_algorithm+vcl_pair+double.foo.c)
+ENDIF(WATCOM)
+MESSAGE("Sources: ${SOURCES}")
+ADD_EXECUTABLE(TestWithAuxSourceDir ${SOURCES})
diff --git a/Tests/SubDir/Examples/CMakeLists.txt b/Tests/SubDir/Examples/CMakeLists.txt
new file mode 100644
index 000000000..b0f1e896c
--- /dev/null
+++ b/Tests/SubDir/Examples/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required (VERSION 2.6)
+PROJECT(Examples)
+SUBDIRS(example1 example2)
diff --git a/Tests/SubDir/Examples/example1/CMakeLists.txt b/Tests/SubDir/Examples/example1/CMakeLists.txt
new file mode 100644
index 000000000..303618321
--- /dev/null
+++ b/Tests/SubDir/Examples/example1/CMakeLists.txt
@@ -0,0 +1,7 @@
+cmake_minimum_required (VERSION 2.6)
+PROJECT(example1)
+ADD_EXECUTABLE(example1 example1.cxx)
+
+ADD_CUSTOM_COMMAND(TARGET example1 POST_BUILD
+ COMMAND "${CMAKE_COMMAND}" ARGS -E remove ${SUBDIR_BINARY_DIR}/ShouldBeHere
+ COMMENT "Remove marker file that should exist because this should not be run")
diff --git a/Tests/SubDir/Examples/example1/example1.cxx b/Tests/SubDir/Examples/example1/example1.cxx
new file mode 100644
index 000000000..3c4819415
--- /dev/null
+++ b/Tests/SubDir/Examples/example1/example1.cxx
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main()
+{
+ printf("example1\n");
+ return 0;
+}
diff --git a/Tests/SubDir/Examples/example2/CMakeLists.txt b/Tests/SubDir/Examples/example2/CMakeLists.txt
new file mode 100644
index 000000000..19a537686
--- /dev/null
+++ b/Tests/SubDir/Examples/example2/CMakeLists.txt
@@ -0,0 +1,2 @@
+PROJECT(example2)
+ADD_EXECUTABLE(example2 example2.cxx)
diff --git a/Tests/SubDir/Examples/example2/example2.cxx b/Tests/SubDir/Examples/example2/example2.cxx
new file mode 100644
index 000000000..60ef3c940
--- /dev/null
+++ b/Tests/SubDir/Examples/example2/example2.cxx
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main()
+{
+ printf("example2\n");
+ return 0;
+}
diff --git a/Tests/SubDir/Executable/CMakeLists.txt b/Tests/SubDir/Executable/CMakeLists.txt
new file mode 100644
index 000000000..d679168d8
--- /dev/null
+++ b/Tests/SubDir/Executable/CMakeLists.txt
@@ -0,0 +1 @@
+ADD_EXECUTABLE(test test.cxx)
diff --git a/Tests/SubDir/Executable/test.cxx b/Tests/SubDir/Executable/test.cxx
new file mode 100644
index 000000000..c528fb166
--- /dev/null
+++ b/Tests/SubDir/Executable/test.cxx
@@ -0,0 +1,49 @@
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef _WIN32
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
+
+// return true if the file exists
+int FileExists(const char* filename)
+{
+#ifdef _MSC_VER
+# define access _access
+#endif
+#ifndef F_OK
+#define F_OK 0
+#endif
+ if ( access(filename, F_OK) != 0 )
+ {
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+}
+
+
+int main(int ac, char** av)
+{
+ if(ac <= 1)
+ {
+ printf("Usage: %s <file>\n", av[0]);
+ return 1;
+ }
+ if(!FileExists(av[1]))
+ {
+ printf("Missing file %s\n", av[1]);
+ return 1;
+ }
+ if(FileExists(av[2]))
+ {
+ printf("File %s should be in subdirectory\n", av[2]);
+ return 1;
+ }
+ printf("%s is not there! Good.", av[2]);
+ printf("%s is there! Good.", av[1]);
+ return 0;
+}
diff --git a/Tests/SubDir/ThirdSubDir/pair+int.int1.c b/Tests/SubDir/ThirdSubDir/pair+int.int1.c
new file mode 100644
index 000000000..b7a623781
--- /dev/null
+++ b/Tests/SubDir/ThirdSubDir/pair+int.int1.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+void pair_stuff()
+{
+ printf("Placeholder for a strange file in subdirectory\n");
+}
diff --git a/Tests/SubDir/ThirdSubDir/pair_int.int1.c b/Tests/SubDir/ThirdSubDir/pair_int.int1.c
new file mode 100644
index 000000000..b7a623781
--- /dev/null
+++ b/Tests/SubDir/ThirdSubDir/pair_int.int1.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+void pair_stuff()
+{
+ printf("Placeholder for a strange file in subdirectory\n");
+}
diff --git a/Tests/SubDir/ThirdSubDir/pair_p_int.int1.c b/Tests/SubDir/ThirdSubDir/pair_p_int.int1.c
new file mode 100644
index 000000000..95a66eee6
--- /dev/null
+++ b/Tests/SubDir/ThirdSubDir/pair_p_int.int1.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+void pair_p_stuff()
+{
+ printf("Placeholder for another strange file in subdirectory\n");
+}
diff --git a/Tests/SubDir/ThirdSubDir/testfromauxsubdir.c b/Tests/SubDir/ThirdSubDir/testfromauxsubdir.c
new file mode 100644
index 000000000..d1620845f
--- /dev/null
+++ b/Tests/SubDir/ThirdSubDir/testfromauxsubdir.c
@@ -0,0 +1,16 @@
+#include <stdio.h>
+
+void secondone();
+void pair_stuff();
+void pair_p_stuff();
+void vcl_stuff();
+
+int main()
+{
+ printf("Hello from subdirectory\n");
+ secondone();
+ pair_stuff();
+ pair_p_stuff();
+ vcl_stuff();
+ return 0;
+}
diff --git a/Tests/SubDir/ThirdSubDir/thirdone.c b/Tests/SubDir/ThirdSubDir/thirdone.c
new file mode 100644
index 000000000..3e9e5afe6
--- /dev/null
+++ b/Tests/SubDir/ThirdSubDir/thirdone.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+void secondone()
+{
+ printf("Hello again\n");
+}
diff --git a/Tests/SubDir/vcl_algorithm+vcl_pair+double.foo.c b/Tests/SubDir/vcl_algorithm+vcl_pair+double.foo.c
new file mode 100644
index 000000000..a0c60f75a
--- /dev/null
+++ b/Tests/SubDir/vcl_algorithm+vcl_pair+double.foo.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+void vcl_stuff()
+{
+ printf("Placeholder for a file with strange name\n");
+}
diff --git a/Tests/SubDir/vcl_algorithm_vcl_pair_double.foo.c b/Tests/SubDir/vcl_algorithm_vcl_pair_double.foo.c
new file mode 100644
index 000000000..a0c60f75a
--- /dev/null
+++ b/Tests/SubDir/vcl_algorithm_vcl_pair_double.foo.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+void vcl_stuff()
+{
+ printf("Placeholder for a file with strange name\n");
+}
diff --git a/Tests/SubDirSpaces/Another Subdir/pair+int.int.c b/Tests/SubDirSpaces/Another Subdir/pair+int.int.c
new file mode 100644
index 000000000..b7a623781
--- /dev/null
+++ b/Tests/SubDirSpaces/Another Subdir/pair+int.int.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+void pair_stuff()
+{
+ printf("Placeholder for a strange file in subdirectory\n");
+}
diff --git a/Tests/SubDirSpaces/Another Subdir/pair_int.int.c b/Tests/SubDirSpaces/Another Subdir/pair_int.int.c
new file mode 100644
index 000000000..b7a623781
--- /dev/null
+++ b/Tests/SubDirSpaces/Another Subdir/pair_int.int.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+void pair_stuff()
+{
+ printf("Placeholder for a strange file in subdirectory\n");
+}
diff --git a/Tests/SubDirSpaces/Another Subdir/secondone.c b/Tests/SubDirSpaces/Another Subdir/secondone.c
new file mode 100644
index 000000000..3e9e5afe6
--- /dev/null
+++ b/Tests/SubDirSpaces/Another Subdir/secondone.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+void secondone()
+{
+ printf("Hello again\n");
+}
diff --git a/Tests/SubDirSpaces/Another Subdir/testfromsubdir.c b/Tests/SubDirSpaces/Another Subdir/testfromsubdir.c
new file mode 100644
index 000000000..34b6e7a88
--- /dev/null
+++ b/Tests/SubDirSpaces/Another Subdir/testfromsubdir.c
@@ -0,0 +1,14 @@
+#include <stdio.h>
+
+void secondone();
+void pair_stuff();
+void vcl_stuff();
+
+int main()
+{
+ printf("Hello from subdirectory\n");
+ secondone();
+ pair_stuff();
+ vcl_stuff();
+ return 0;
+}
diff --git a/Tests/SubDirSpaces/CMakeLists.txt b/Tests/SubDirSpaces/CMakeLists.txt
new file mode 100644
index 000000000..879530b56
--- /dev/null
+++ b/Tests/SubDirSpaces/CMakeLists.txt
@@ -0,0 +1,77 @@
+cmake_minimum_required (VERSION 2.6)
+PROJECT(SUBDIR)
+
+# Some systems do not seem to support rpath with spaces.
+IF("${CMAKE_SYSTEM}" MATCHES "IRIX|QNX")
+ SET(CMAKE_SKIP_BUILD_RPATH 1)
+ENDIF("${CMAKE_SYSTEM}" MATCHES "IRIX|QNX")
+
+# be able to see output from make on dashboards
+SET(CMAKE_VERBOSE_MAKEFILE 1)
+message("${CMAKE_MAKE_PROGRAM}")
+set(CMAKE_PAREN TRUE)
+IF("${CMAKE_MAKE_PROGRAM}" MATCHES "wmake")
+ message("wmake does not support () in path")
+ set(CMAKE_PAREN FALSE)
+elseif("${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("${out}" MATCHES "GNU Make 3.82")
+ # GNU Make 3.82 fails on parens: http://savannah.gnu.org/bugs/?30612
+ message(STATUS "GNU Make 3.82 sometimes fails on () in path")
+ set(CMAKE_PAREN FALSE)
+ endif()
+endif()
+
+IF(CMAKE_PAREN)
+ ADD_DEFINITIONS(-DCMAKE_PAREN=1)
+ SUBDIRS("Executable Sources" "Some(x86) Sources" EXCLUDE_FROM_ALL "Some Examples")
+ELSE(CMAKE_PAREN)
+ SUBDIRS("Executable Sources" EXCLUDE_FROM_ALL "Some Examples")
+ENDIF(CMAKE_PAREN)
+
+WRITE_FILE(${SUBDIR_BINARY_DIR}/ShouldBeHere "This file should exist.")
+#WATCOM WMAKE does not support + in the name of a file!
+IF(WATCOM)
+ SET(PLUS_NAME_FILES
+ "Another Subdir/pair_int.int.c"
+ vcl_algorithm_vcl_pair_double.foo.c)
+ELSE(WATCOM)
+ SET(PLUS_NAME_FILES
+ "Another Subdir/pair+int.int.c"
+ vcl_algorithm+vcl_pair+double.foo.c)
+ENDIF(WATCOM)
+
+ADD_EXECUTABLE(TestFromSubdir
+ "Another Subdir/testfromsubdir.c"
+ "Another Subdir/secondone"
+ ${PLUS_NAME_FILES}
+ )
+
+AUX_SOURCE_DIRECTORY(ThirdSubDir SOURCES)
+IF(WATCOM)
+ FOREACH(f ${SOURCES})
+ IF("${f}" STREQUAL "ThirdSubDir/pair+int.int1.c")
+ ELSE("${f}" STREQUAL "ThirdSubDir/pair+int.int1.c")
+ SET(SOURCES2 ${f} ${SOURCES2})
+ ENDIF("${f}" STREQUAL "ThirdSubDir/pair+int.int1.c")
+ ENDFOREACH(f)
+ SET(SOURCES ${SOURCES2})
+ SET(SOURCES ${SOURCES}
+ vcl_algorithm_vcl_pair_double.foo.c)
+ELSE(WATCOM)
+ FOREACH(f ${SOURCES})
+ IF("${f}" STREQUAL "ThirdSubDir/pair_int.int1.c")
+ ELSE("${f}" STREQUAL "ThirdSubDir/pair_int.int1.c")
+ SET(SOURCES2 ${f} ${SOURCES2})
+ ENDIF("${f}" STREQUAL "ThirdSubDir/pair_int.int1.c")
+ ENDFOREACH(f)
+ SET(SOURCES ${SOURCES2})
+ SET(SOURCES ${SOURCES}
+ vcl_algorithm+vcl_pair+double.foo.c)
+ENDIF(WATCOM)
+ADD_EXECUTABLE(TestWithAuxSourceDir ${SOURCES})
+IF(CMAKE_PAREN)
+ target_link_libraries(TestWithAuxSourceDir testOddPath)
+ENDIF(CMAKE_PAREN)
+
diff --git a/Tests/SubDirSpaces/Executable Sources/CMakeLists.txt b/Tests/SubDirSpaces/Executable Sources/CMakeLists.txt
new file mode 100644
index 000000000..d679168d8
--- /dev/null
+++ b/Tests/SubDirSpaces/Executable Sources/CMakeLists.txt
@@ -0,0 +1 @@
+ADD_EXECUTABLE(test test.cxx)
diff --git a/Tests/SubDirSpaces/Executable Sources/test.cxx b/Tests/SubDirSpaces/Executable Sources/test.cxx
new file mode 100644
index 000000000..c528fb166
--- /dev/null
+++ b/Tests/SubDirSpaces/Executable Sources/test.cxx
@@ -0,0 +1,49 @@
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef _WIN32
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
+
+// return true if the file exists
+int FileExists(const char* filename)
+{
+#ifdef _MSC_VER
+# define access _access
+#endif
+#ifndef F_OK
+#define F_OK 0
+#endif
+ if ( access(filename, F_OK) != 0 )
+ {
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+}
+
+
+int main(int ac, char** av)
+{
+ if(ac <= 1)
+ {
+ printf("Usage: %s <file>\n", av[0]);
+ return 1;
+ }
+ if(!FileExists(av[1]))
+ {
+ printf("Missing file %s\n", av[1]);
+ return 1;
+ }
+ if(FileExists(av[2]))
+ {
+ printf("File %s should be in subdirectory\n", av[2]);
+ return 1;
+ }
+ printf("%s is not there! Good.", av[2]);
+ printf("%s is there! Good.", av[1]);
+ return 0;
+}
diff --git a/Tests/SubDirSpaces/Executable/CMakeLists.txt b/Tests/SubDirSpaces/Executable/CMakeLists.txt
new file mode 100644
index 000000000..d679168d8
--- /dev/null
+++ b/Tests/SubDirSpaces/Executable/CMakeLists.txt
@@ -0,0 +1 @@
+ADD_EXECUTABLE(test test.cxx)
diff --git a/Tests/SubDirSpaces/Executable/test.cxx b/Tests/SubDirSpaces/Executable/test.cxx
new file mode 100644
index 000000000..c528fb166
--- /dev/null
+++ b/Tests/SubDirSpaces/Executable/test.cxx
@@ -0,0 +1,49 @@
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef _WIN32
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
+
+// return true if the file exists
+int FileExists(const char* filename)
+{
+#ifdef _MSC_VER
+# define access _access
+#endif
+#ifndef F_OK
+#define F_OK 0
+#endif
+ if ( access(filename, F_OK) != 0 )
+ {
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+}
+
+
+int main(int ac, char** av)
+{
+ if(ac <= 1)
+ {
+ printf("Usage: %s <file>\n", av[0]);
+ return 1;
+ }
+ if(!FileExists(av[1]))
+ {
+ printf("Missing file %s\n", av[1]);
+ return 1;
+ }
+ if(FileExists(av[2]))
+ {
+ printf("File %s should be in subdirectory\n", av[2]);
+ return 1;
+ }
+ printf("%s is not there! Good.", av[2]);
+ printf("%s is there! Good.", av[1]);
+ return 0;
+}
diff --git a/Tests/SubDirSpaces/Some Examples/CMakeLists.txt b/Tests/SubDirSpaces/Some Examples/CMakeLists.txt
new file mode 100644
index 000000000..b0f1e896c
--- /dev/null
+++ b/Tests/SubDirSpaces/Some Examples/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required (VERSION 2.6)
+PROJECT(Examples)
+SUBDIRS(example1 example2)
diff --git a/Tests/SubDirSpaces/Some Examples/example1/CMakeLists.txt b/Tests/SubDirSpaces/Some Examples/example1/CMakeLists.txt
new file mode 100644
index 000000000..303618321
--- /dev/null
+++ b/Tests/SubDirSpaces/Some Examples/example1/CMakeLists.txt
@@ -0,0 +1,7 @@
+cmake_minimum_required (VERSION 2.6)
+PROJECT(example1)
+ADD_EXECUTABLE(example1 example1.cxx)
+
+ADD_CUSTOM_COMMAND(TARGET example1 POST_BUILD
+ COMMAND "${CMAKE_COMMAND}" ARGS -E remove ${SUBDIR_BINARY_DIR}/ShouldBeHere
+ COMMENT "Remove marker file that should exist because this should not be run")
diff --git a/Tests/SubDirSpaces/Some Examples/example1/example1.cxx b/Tests/SubDirSpaces/Some Examples/example1/example1.cxx
new file mode 100644
index 000000000..3c4819415
--- /dev/null
+++ b/Tests/SubDirSpaces/Some Examples/example1/example1.cxx
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main()
+{
+ printf("example1\n");
+ return 0;
+}
diff --git a/Tests/SubDirSpaces/Some Examples/example2/CMakeLists.txt b/Tests/SubDirSpaces/Some Examples/example2/CMakeLists.txt
new file mode 100644
index 000000000..19a537686
--- /dev/null
+++ b/Tests/SubDirSpaces/Some Examples/example2/CMakeLists.txt
@@ -0,0 +1,2 @@
+PROJECT(example2)
+ADD_EXECUTABLE(example2 example2.cxx)
diff --git a/Tests/SubDirSpaces/Some Examples/example2/example2.cxx b/Tests/SubDirSpaces/Some Examples/example2/example2.cxx
new file mode 100644
index 000000000..60ef3c940
--- /dev/null
+++ b/Tests/SubDirSpaces/Some Examples/example2/example2.cxx
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main()
+{
+ printf("example2\n");
+ return 0;
+}
diff --git a/Tests/SubDirSpaces/Some(x86) Sources/CMakeLists.txt b/Tests/SubDirSpaces/Some(x86) Sources/CMakeLists.txt
new file mode 100644
index 000000000..cfba9169c
--- /dev/null
+++ b/Tests/SubDirSpaces/Some(x86) Sources/CMakeLists.txt
@@ -0,0 +1 @@
+add_library(testOddPath test.c)
diff --git a/Tests/SubDirSpaces/Some(x86) Sources/test.c b/Tests/SubDirSpaces/Some(x86) Sources/test.c
new file mode 100644
index 000000000..66568d4c2
--- /dev/null
+++ b/Tests/SubDirSpaces/Some(x86) Sources/test.c
@@ -0,0 +1,3 @@
+void testOdd()
+{
+}
diff --git a/Tests/SubDirSpaces/ThirdSubDir/pair+int.int1.c b/Tests/SubDirSpaces/ThirdSubDir/pair+int.int1.c
new file mode 100644
index 000000000..b7a623781
--- /dev/null
+++ b/Tests/SubDirSpaces/ThirdSubDir/pair+int.int1.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+void pair_stuff()
+{
+ printf("Placeholder for a strange file in subdirectory\n");
+}
diff --git a/Tests/SubDirSpaces/ThirdSubDir/pair_int.int1.c b/Tests/SubDirSpaces/ThirdSubDir/pair_int.int1.c
new file mode 100644
index 000000000..b7a623781
--- /dev/null
+++ b/Tests/SubDirSpaces/ThirdSubDir/pair_int.int1.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+void pair_stuff()
+{
+ printf("Placeholder for a strange file in subdirectory\n");
+}
diff --git a/Tests/SubDirSpaces/ThirdSubDir/pair_p_int.int1.c b/Tests/SubDirSpaces/ThirdSubDir/pair_p_int.int1.c
new file mode 100644
index 000000000..95a66eee6
--- /dev/null
+++ b/Tests/SubDirSpaces/ThirdSubDir/pair_p_int.int1.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+void pair_p_stuff()
+{
+ printf("Placeholder for another strange file in subdirectory\n");
+}
diff --git a/Tests/SubDirSpaces/ThirdSubDir/testfromauxsubdir.c b/Tests/SubDirSpaces/ThirdSubDir/testfromauxsubdir.c
new file mode 100644
index 000000000..fa6c33ced
--- /dev/null
+++ b/Tests/SubDirSpaces/ThirdSubDir/testfromauxsubdir.c
@@ -0,0 +1,21 @@
+#include <stdio.h>
+
+void secondone();
+void pair_stuff();
+void pair_p_stuff();
+void vcl_stuff();
+#ifdef CMAKE_PAREN
+void testOdd();
+#endif
+int main()
+{
+ printf("Hello from subdirectory\n");
+ secondone();
+#ifdef CMAKE_PAREN
+ testOdd();
+#endif
+ pair_stuff();
+ pair_p_stuff();
+ vcl_stuff();
+ return 0;
+}
diff --git a/Tests/SubDirSpaces/ThirdSubDir/thirdone.c b/Tests/SubDirSpaces/ThirdSubDir/thirdone.c
new file mode 100644
index 000000000..3e9e5afe6
--- /dev/null
+++ b/Tests/SubDirSpaces/ThirdSubDir/thirdone.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+void secondone()
+{
+ printf("Hello again\n");
+}
diff --git a/Tests/SubDirSpaces/vcl_algorithm+vcl_pair+double.foo.c b/Tests/SubDirSpaces/vcl_algorithm+vcl_pair+double.foo.c
new file mode 100644
index 000000000..a0c60f75a
--- /dev/null
+++ b/Tests/SubDirSpaces/vcl_algorithm+vcl_pair+double.foo.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+void vcl_stuff()
+{
+ printf("Placeholder for a file with strange name\n");
+}
diff --git a/Tests/SubDirSpaces/vcl_algorithm_vcl_pair_double.foo.c b/Tests/SubDirSpaces/vcl_algorithm_vcl_pair_double.foo.c
new file mode 100644
index 000000000..a0c60f75a
--- /dev/null
+++ b/Tests/SubDirSpaces/vcl_algorithm_vcl_pair_double.foo.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+void vcl_stuff()
+{
+ printf("Placeholder for a file with strange name\n");
+}
diff --git a/Tests/SubProject/CMakeLists.txt b/Tests/SubProject/CMakeLists.txt
new file mode 100644
index 000000000..b669621df
--- /dev/null
+++ b/Tests/SubProject/CMakeLists.txt
@@ -0,0 +1,6 @@
+cmake_minimum_required (VERSION 2.6)
+project(SubProject)
+message("${CMAKE_IMPORT_LIBRARY_SUFFIX}")
+add_library(bar bar.cxx)
+add_executable(car car.cxx)
+add_subdirectory(foo)
diff --git a/Tests/SubProject/bar.cxx b/Tests/SubProject/bar.cxx
new file mode 100644
index 000000000..c3f6a181a
--- /dev/null
+++ b/Tests/SubProject/bar.cxx
@@ -0,0 +1,4 @@
+int bar()
+{
+ return 10;
+}
diff --git a/Tests/SubProject/car.cxx b/Tests/SubProject/car.cxx
new file mode 100644
index 000000000..95de4a327
--- /dev/null
+++ b/Tests/SubProject/car.cxx
@@ -0,0 +1,6 @@
+int main(int ac, char** av)
+{
+ (void) ac;
+ (void) av;
+ return 0;
+}
diff --git a/Tests/SubProject/foo/CMakeLists.txt b/Tests/SubProject/foo/CMakeLists.txt
new file mode 100644
index 000000000..011178b26
--- /dev/null
+++ b/Tests/SubProject/foo/CMakeLists.txt
@@ -0,0 +1,3 @@
+project(foo)
+add_executable(foo foo.cxx)
+target_link_libraries(foo bar)
diff --git a/Tests/SubProject/foo/foo.cxx b/Tests/SubProject/foo/foo.cxx
new file mode 100644
index 000000000..68fa36376
--- /dev/null
+++ b/Tests/SubProject/foo/foo.cxx
@@ -0,0 +1,15 @@
+int bar();
+#include <stdio.h>
+
+int main(int ac, char** av)
+{
+ (void)ac;
+ (void)av;
+ int ret = bar();
+ printf("bar = %d\n", ret);
+ if(ret == 10)
+ {
+ return 0;
+ }
+ return -1;
+}
diff --git a/Tests/SwigTest/CMakeLists.txt b/Tests/SwigTest/CMakeLists.txt
new file mode 100644
index 000000000..5a8e61922
--- /dev/null
+++ b/Tests/SwigTest/CMakeLists.txt
@@ -0,0 +1,50 @@
+SET(language "python")
+
+cmake_minimum_required (VERSION 2.6)
+
+PROJECT(example_${language}_class)
+
+FIND_PACKAGE(SWIG REQUIRED)
+INCLUDE(${SWIG_USE_FILE})
+
+IF(${language} MATCHES python)
+ FIND_PACKAGE(PythonLibs)
+ INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH})
+ SET(SWIG_LANG_LIBRARIES ${PYTHON_LIBRARIES})
+ENDIF(${language} MATCHES python)
+IF(${language} MATCHES perl)
+ FIND_PACKAGE(PerlLibs)
+ INCLUDE_DIRECTORIES(${PERL_INCLUDE_PATH})
+ ADD_DEFINITIONS(${PERL_EXTRA_C_FLAGS})
+ SET(SWIG_LANG_LIBRARIES ${PERL_LIBRARY})
+ENDIF(${language} MATCHES perl)
+IF(${language} MATCHES tcl)
+ FIND_PACKAGE(TCL)
+ INCLUDE_DIRECTORIES(${TCL_INCLUDE_PATH})
+ SET(SWIG_LANG_LIBRARIES ${TCL_LIBRARY})
+ENDIF(${language} MATCHES tcl)
+IF(${language} MATCHES ruby)
+ FIND_PACKAGE(Ruby)
+ INCLUDE_DIRECTORIES(${RUBY_INCLUDE_PATH})
+ SET(SWIG_LANG_LIBRARIES ${RUBY_LIBRARY})
+ENDIF(${language} MATCHES ruby)
+IF(${language} MATCHES php4)
+ FIND_PACKAGE(PHP4)
+ INCLUDE_DIRECTORIES(${PHP4_INCLUDE_PATH})
+ SET(SWIG_LANG_LIBRARIES ${PHP4_LIBRARY})
+ENDIF(${language} MATCHES php4)
+IF(${language} MATCHES pike)
+ FIND_PACKAGE(Pike)
+ INCLUDE_DIRECTORIES(${PIKE_INCLUDE_PATH})
+ SET(SWIG_LANG_LIBRARIES ${PIKE_LIBRARY})
+ENDIF(${language} MATCHES pike)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+
+SET(CMAKE_SWIG_FLAGS "")
+
+SET_SOURCE_FILES_PROPERTIES(example.i PROPERTIES CPLUSPLUS ON)
+SET_SOURCE_FILES_PROPERTIES(example.i PROPERTIES SWIG_FLAGS "-includeall")
+SWIG_ADD_MODULE(example "${language}"
+ example.i example.cxx)
+SWIG_LINK_LIBRARIES(example ${SWIG_LANG_LIBRARIES})
diff --git a/Tests/SwigTest/example.cxx b/Tests/SwigTest/example.cxx
new file mode 100644
index 000000000..1e8e203dd
--- /dev/null
+++ b/Tests/SwigTest/example.cxx
@@ -0,0 +1,28 @@
+/* File : example.c */
+
+#include "example.h"
+#define M_PI 3.14159265358979323846
+
+/* Move the shape to a new location */
+void Shape::move(double dx, double dy) {
+ x += dx;
+ y += dy;
+}
+
+int Shape::nshapes = 0;
+
+double Circle::area(void) {
+ return M_PI*radius*radius;
+}
+
+double Circle::perimeter(void) {
+ return 2*M_PI*radius;
+}
+
+double Square::area(void) {
+ return width*width;
+}
+
+double Square::perimeter(void) {
+ return 4*width;
+}
diff --git a/Tests/SwigTest/example.h b/Tests/SwigTest/example.h
new file mode 100644
index 000000000..46d901361
--- /dev/null
+++ b/Tests/SwigTest/example.h
@@ -0,0 +1,39 @@
+/* File : example.h */
+
+class Shape {
+public:
+ Shape() {
+ nshapes++;
+ }
+ virtual ~Shape() {
+ nshapes--;
+ };
+ double x, y;
+ void move(double dx, double dy);
+ virtual double area(void) = 0;
+ virtual double perimeter(void) = 0;
+ static int nshapes;
+};
+
+class Circle : public Shape {
+private:
+ double radius;
+public:
+ Circle(double r) : radius(r) { };
+ virtual double area(void);
+ virtual double perimeter(void);
+};
+
+class Square : public Shape {
+private:
+ double width;
+public:
+ Square(double w) : width(w) { };
+ virtual double area(void);
+ virtual double perimeter(void);
+};
+
+
+
+
+
diff --git a/Tests/SwigTest/example.i b/Tests/SwigTest/example.i
new file mode 100644
index 000000000..75700b305
--- /dev/null
+++ b/Tests/SwigTest/example.i
@@ -0,0 +1,10 @@
+/* File : example.i */
+%module example
+
+%{
+#include "example.h"
+%}
+
+/* Let's just grab the original header file here */
+%include "example.h"
+
diff --git a/Tests/SwigTest/runme.php4 b/Tests/SwigTest/runme.php4
new file mode 100644
index 000000000..653ced256
--- /dev/null
+++ b/Tests/SwigTest/runme.php4
@@ -0,0 +1,58 @@
+<?php
+
+# This file illustrates the low-level C++ interface
+# created by SWIG. In this case, all of our C++ classes
+# get converted into function calls.
+
+require("example.php");
+
+# ----- Object creation -----
+
+print "Creating some objects:\n";
+$c = new_Circle(10);
+print " Created circle $c\n";
+$s = new_Square(10);
+print " Created square $s\n";
+
+# ----- Access a static member -----
+
+print "\nA total of " . nshapes() . " shapes were created\n";
+
+# ----- Member data access -----
+
+# Set the location of the object.
+# Note: methods in the base class Shape are used since
+# x and y are defined there.
+
+Shape_x_set($c, 20);
+Shape_y_set($c, 30);
+Shape_x_set($s,-10);
+Shape_y_set($s,5);
+
+print "\nHere is their current position:\n";
+print " Circle = (" . Shape_x_get($c) . "," . Shape_y_get($c) . ")\n";
+print " Square = (" . Shape_x_get($s) . "," . Shape_y_get($s) . ")\n";
+
+# ----- Call some methods -----
+
+print "\nHere are some properties of the shapes:\n";
+foreach (array($c,$s) as $o) {
+ print " $o\n";
+ print " area = " . Shape_area($o) . "\n";
+ print " perimeter = " . Shape_perimeter($o) . "\n";
+ }
+# Notice how the Shape_area() and Shape_perimeter() functions really
+# invoke the appropriate virtual method on each object.
+
+# ----- Delete everything -----
+
+print "\nGuess I'll clean up now\n";
+
+# Note: this invokes the virtual destructor
+delete_Shape($c);
+delete_Shape($s);
+
+print nshapes() . " shapes remain\n";
+print "Goodbye\n";
+
+?>
diff --git a/Tests/SwigTest/runme.pike b/Tests/SwigTest/runme.pike
new file mode 100755
index 000000000..a6377600e
--- /dev/null
+++ b/Tests/SwigTest/runme.pike
@@ -0,0 +1,53 @@
+import .example;
+
+int main()
+{
+ // ----- Object creation -----
+
+ write("Creating some objects:\n");
+ Circle c = Circle(10.0);
+ write(" Created circle.\n");
+ Square s = Square(10.0);
+ write(" Created square.\n");
+
+ // ----- Access a static member -----
+
+ write("\nA total of " + Shape_nshapes_get() + " shapes were created\n");
+
+ // ----- Member data access -----
+
+ // Set the location of the object
+
+ c->x_set(20.0);
+ c->y_set(30.0);
+
+ s->x_set(-10.0);
+ s->y_set(5.0);
+
+ write("\nHere is their current position:\n");
+ write(" Circle = (%f, %f)\n", c->x_get(), c->y_get());
+ write(" Square = (%f, %f)\n", s->x_get(), s->y_get());
+
+ // ----- Call some methods -----
+
+ write("\nHere are some properties of the shapes:\n");
+ write(" The circle:\n");
+ write(" area = %f.\n", c->area());
+ write(" perimeter = %f.\n", c->perimeter());
+ write(" The square:\n");
+ write(" area = %f.\n", s->area());
+ write(" perimeter = %f.\n", s->perimeter());
+
+ write("\nGuess I'll clean up now\n");
+
+ /* See if we can force 's' to be garbage-collected */
+ s = 0;
+
+ /* Now we should be down to only 1 shape */
+ write("%d shapes remain\n", Shape_nshapes_get());
+
+ /* Done */
+ write("Goodbye\n");
+
+ return 0;
+}
diff --git a/Tests/SwigTest/runme.pl b/Tests/SwigTest/runme.pl
new file mode 100644
index 000000000..5bfb3d83a
--- /dev/null
+++ b/Tests/SwigTest/runme.pl
@@ -0,0 +1,57 @@
+# file: runme.pl
+
+# This file illustrates the low-level C++ interface
+# created by SWIG. In this case, all of our C++ classes
+# get converted into function calls.
+
+use example;
+
+# ----- Object creation -----
+
+print "Creating some objects:\n";
+$c = examplec::new_Circle(10);
+print " Created circle $c\n";
+$s = examplec::new_Square(10);
+print " Created square $s\n";
+
+# ----- Access a static member -----
+
+print "\nA total of $examplec::Shape_nshapes shapes were created\n";
+
+# ----- Member data access -----
+
+# Set the location of the object.
+# Note: methods in the base class Shape are used since
+# x and y are defined there.
+
+examplec::Shape_x_set($c, 20);
+examplec::Shape_y_set($c, 30);
+examplec::Shape_x_set($s,-10);
+examplec::Shape_y_set($s,5);
+
+print "\nHere is their current position:\n";
+print " Circle = (",examplec::Shape_x_get($c),",", examplec::Shape_y_get($c),")\n";
+print " Square = (",examplec::Shape_x_get($s),",", examplec::Shape_y_get($s),")\n";
+
+# ----- Call some methods -----
+
+print "\nHere are some properties of the shapes:\n";
+foreach $o ($c,$s) {
+ print " $o\n";
+ print " area = ", examplec::Shape_area($o), "\n";
+ print " perimeter = ", examplec::Shape_perimeter($o), "\n";
+ }
+# Notice how the Shape_area() and Shape_perimeter() functions really
+# invoke the appropriate virtual method on each object.
+
+# ----- Delete everything -----
+
+print "\nGuess I'll clean up now\n";
+
+# Note: this invokes the virtual destructor
+examplec::delete_Shape($c);
+examplec::delete_Shape($s);
+
+print $examplec::Shape_nshapes," shapes remain\n";
+print "Goodbye\n";
+
diff --git a/Tests/SwigTest/runme.py b/Tests/SwigTest/runme.py
new file mode 100644
index 000000000..42a5aa363
--- /dev/null
+++ b/Tests/SwigTest/runme.py
@@ -0,0 +1,51 @@
+# file: runme.py
+
+# This file illustrates the shadow-class C++ interface generated
+# by SWIG.
+
+import example
+
+# ----- Object creation -----
+
+print "Creating some objects:"
+c = example.Circle(10)
+print " Created circle", c
+s = example.Square(10)
+print " Created square", s
+
+# ----- Access a static member -----
+
+print "\nA total of", example.cvar.Shape_nshapes,"shapes were created"
+
+# ----- Member data access -----
+
+# Set the location of the object
+
+c.x = 20
+c.y = 30
+
+s.x = -10
+s.y = 5
+
+print "\nHere is their current position:"
+print " Circle = (%f, %f)" % (c.x,c.y)
+print " Square = (%f, %f)" % (s.x,s.y)
+
+# ----- Call some methods -----
+
+print "\nHere are some properties of the shapes:"
+for o in [c,s]:
+ print " ", o
+ print " area = ", o.area()
+ print " perimeter = ", o.perimeter()
+
+print "\nGuess I'll clean up now"
+
+# Note: this invokes the virtual destructor
+del c
+del s
+
+s = 3
+print example.cvar.Shape_nshapes,"shapes remain"
+print "Goodbye"
+
diff --git a/Tests/SwigTest/runme.rb b/Tests/SwigTest/runme.rb
new file mode 100644
index 000000000..de73bcd46
--- /dev/null
+++ b/Tests/SwigTest/runme.rb
@@ -0,0 +1,49 @@
+# file: runme.rb
+
+# This file illustrates the C++ interface created by SWIG.
+# All of our C++ classes get converted into Ruby classes.
+
+require 'example'
+
+# ----- Object creation -----
+
+print "Creating some objects:\n"
+c = Example::Circle.new(10)
+print " Created circle #{c}\n"
+s = Example::Square.new(10)
+print " Created square #{s}\n"
+
+# ----- Access a static member -----
+
+print "\nA total of #{Example::Shape.nshapes} shapes were created\n"
+
+# ----- Member data access -----
+
+# Set the location of the object
+
+# Notice how we can do this using functions specific to
+# the 'Circle' class.
+c.x = 20
+c.y = 30
+
+# Now use the same functions in the base class
+s.x = -10
+s.y = 5
+
+print "\nHere is their current position:\n"
+print " Circle = (", c.x, ",", c.y, ")\n"
+print " Square = (", s.x, ",", s.y, ")\n"
+
+# ----- Call some methods -----
+
+print "\nHere are some properties of the shapes:\n"
+for o in [c, s]
+ print " #{o}\n"
+ print " area = ", o.area, "\n"
+ print " perimeter = ", o.perimeter, "\n"
+end
+# Notice how the Shape#area() and Shape#perimeter() functions really
+# invoke the appropriate virtual method on each object.
+
+print "\n", Example::Shape.nshapes," shapes remain\n"
+print "Goodbye\n"
diff --git a/Tests/SwigTest/runme.tcl b/Tests/SwigTest/runme.tcl
new file mode 100644
index 000000000..c7f472560
--- /dev/null
+++ b/Tests/SwigTest/runme.tcl
@@ -0,0 +1,50 @@
+# file: runme.tcl
+
+# This file illustrates the high level C++ interface.
+# In this case C++ classes work kind of like Tk widgets
+
+catch { load ./example[info sharedlibextension] example}
+
+# ----- Object creation -----
+
+puts "Creating some objects:"
+Circle c 10
+puts " Created circle [c cget -this]"
+Square s 10
+puts " Created square [s cget -this]"
+
+# ----- Access a static member -----
+
+puts "\nA total of $Shape_nshapes shapes were created"
+
+# ----- Member data access -----
+
+# Set the location of the object
+
+c configure -x 20 -y 30
+s configure -x -10 -y 5
+
+puts "\nHere is their current position:"
+puts " Circle = ([c cget -x], [c cget -y])"
+puts " Square = ([s cget -x], [s cget -y])"
+
+# ----- Call some methods -----
+
+puts "\nHere are some properties of the shapes:"
+foreach o "c s" {
+ puts " [$o cget -this]"
+ puts " area = [$o area]"
+ puts " perimeter = [$o perimeter]"
+}
+
+# ----- Delete everything -----
+
+puts "\nGuess I'll clean up now"
+
+# Note: this invokes the virtual destructor
+rename c ""
+rename s ""
+
+puts "$Shape_nshapes shapes remain"
+puts "Goodbye"
+
diff --git a/Tests/SwigTest/runme2.tcl b/Tests/SwigTest/runme2.tcl
new file mode 100644
index 000000000..88ec2f678
--- /dev/null
+++ b/Tests/SwigTest/runme2.tcl
@@ -0,0 +1,70 @@
+# file: runme2.tcl
+
+# This file illustrates the low-level C++ interface
+# created by SWIG. In this case, all of our C++ classes
+# get converted into function calls.
+
+catch { load ./example[info sharedlibextension] example}
+
+# ----- Object creation -----
+
+puts "Creating some objects:"
+set c [new_Circle 10]
+puts " Created circle $c"
+set s [new_Square 10]
+puts " Created square $s"
+
+# ----- Access a static member -----
+
+puts "\nA total of $Shape_nshapes shapes were created"
+
+# ----- Member data access -----
+
+# Set the location of the object
+# Note: the base class must be used since that's where x and y
+# were declared.
+
+Shape_x_set $c 20
+Shape_y_set $c 30
+Shape_x_set $s -10
+Shape_y_set $s 5
+
+puts "\nHere is their current position:"
+puts " Circle = ([Shape_x_get $c], [Shape_y_get $c])"
+puts " Square = ([Shape_x_get $s], [Shape_y_get $s])"
+
+# ----- Call some methods -----
+
+puts "\nHere are some properties of the shapes:"
+foreach o "$c $s" {
+ puts " $o"
+ puts " area = [Shape_area $o]"
+ puts " perimeter = [Shape_perimeter $o]"
+}
+# Notice how the Shape_area() and Shape_perimeter() functions really
+# invoke the appropriate virtual method on each object.
+
+# ----- Try to cause a type error -----
+
+puts "\nI'm going to try and break the type system"
+
+if { [catch {
+ # Bad script!
+ Square_area $c # Try to invoke Square method on a Circle
+ puts " Bad bad SWIG!"
+
+}]} {
+ puts " Well, it didn't work. Good SWIG."
+}
+
+# ----- Delete everything -----
+
+puts "\nGuess I'll clean up now"
+
+# Note: this invokes the virtual destructor
+delete_Shape $c
+delete_Shape $s
+
+puts "$Shape_nshapes shapes remain"
+puts "Goodbye"
+
diff --git a/Tests/SystemInformation/CMakeLists.txt b/Tests/SystemInformation/CMakeLists.txt
new file mode 100644
index 000000000..c4285758e
--- /dev/null
+++ b/Tests/SystemInformation/CMakeLists.txt
@@ -0,0 +1,61 @@
+cmake_minimum_required (VERSION 2.6)
+PROJECT(SystemInformation)
+
+INCLUDE_DIRECTORIES("This does not exists")
+GET_DIRECTORY_PROPERTY(incl INCLUDE_DIRECTORIES)
+SET_DIRECTORY_PROPERTIES(PROPERTIES INCLUDE_DIRECTORIES "${SystemInformation_BINARY_DIR};${SystemInformation_SOURCE_DIR}")
+
+MESSAGE("To prevent CTest from stripping output, you have to display: CTEST_FULL_OUTPUT")
+
+
+CONFIGURE_FILE(${SystemInformation_SOURCE_DIR}/SystemInformation.in
+${SystemInformation_BINARY_DIR}/SystemInformation.out)
+CONFIGURE_FILE(${SystemInformation_SOURCE_DIR}/DumpInformation.h.in
+${SystemInformation_BINARY_DIR}/DumpInformation.h)
+ADD_EXECUTABLE(SystemInformation DumpInformation.cxx)
+
+MACRO(FOO args)
+ MESSAGE("Test macro")
+ENDMACRO(FOO)
+
+FOO(lala)
+
+FILE(WRITE ${CMAKE_CURRENT_BINARY_DIR}/AllVariables.txt "")
+GET_CMAKE_PROPERTY(res VARIABLES)
+FOREACH(var ${res})
+ FILE(APPEND ${CMAKE_CURRENT_BINARY_DIR}/AllVariables.txt
+ "${var} \"${${var}}\"\n")
+ENDFOREACH(var ${res})
+
+FILE(WRITE ${CMAKE_CURRENT_BINARY_DIR}/AllCommands.txt "")
+GET_CMAKE_PROPERTY(res COMMANDS)
+FOREACH(var ${res})
+ FILE(APPEND ${CMAKE_CURRENT_BINARY_DIR}/AllCommands.txt
+ "${var}\n")
+ENDFOREACH(var ${res})
+
+FILE(WRITE ${CMAKE_CURRENT_BINARY_DIR}/AllMacros.txt "")
+GET_CMAKE_PROPERTY(res MACROS)
+FOREACH(var ${res})
+ FILE(APPEND ${CMAKE_CURRENT_BINARY_DIR}/AllMacros.txt
+ "${var}\n")
+ENDFOREACH(var ${res})
+
+FILE(WRITE ${CMAKE_CURRENT_BINARY_DIR}/OtherProperties.txt "")
+GET_DIRECTORY_PROPERTY(res INCLUDE_DIRECTORIES)
+FOREACH(var ${res})
+ FILE(APPEND ${CMAKE_CURRENT_BINARY_DIR}/OtherProperties.txt
+ "INCLUDE_DIRECTORY: ${var}\n")
+ENDFOREACH(var)
+
+GET_DIRECTORY_PROPERTY(res LINK_DIRECTORIES)
+FOREACH(var ${res})
+ FILE(APPEND ${CMAKE_CURRENT_BINARY_DIR}/OtherProperties.txt
+ "LINK_DIRECTORIES: ${var}\n")
+ENDFOREACH(var)
+
+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/DumpInformation.cxx b/Tests/SystemInformation/DumpInformation.cxx
new file mode 100644
index 000000000..579dcbcf2
--- /dev/null
+++ b/Tests/SystemInformation/DumpInformation.cxx
@@ -0,0 +1,80 @@
+#include "DumpInformation.h"
+#include <stdio.h>
+#include <sys/stat.h>
+
+void cmDumpInformationPrintFile(const char* name, FILE* fout)
+{
+ fprintf(fout,
+ "Avoid ctest truncation of output: CTEST_FULL_OUTPUT\n");
+ fprintf(fout,
+ "================================================================\n");
+ struct stat fs;
+ if(stat(name, &fs) != 0)
+ {
+ fprintf(fout, "The file \"%s\" does not exist.\n", name);
+ fflush(fout);
+ return;
+ }
+
+ FILE* fin = fopen(name, "r");
+ if(fin)
+ {
+ fprintf(fout,
+ "Contents of \"%s\":\n"
+ "----------------------------------------------------------------\n",
+ name);
+ const int bufferSize = 4096;
+ char buffer[bufferSize];
+ int n;
+ while((n = fread(buffer, 1, bufferSize, fin)) > 0)
+ {
+ for(char* c = buffer; c < buffer+n; ++c)
+ {
+ switch(*c)
+ {
+ case '<': fprintf(fout, "&lt;"); break;
+ case '>': fprintf(fout, "&gt;"); break;
+ case '&': fprintf(fout, "&amp;"); break;
+ default: putc(*c, fout); break;
+ }
+ }
+ fflush(fout);
+ }
+ fclose(fin);
+ }
+ else
+ {
+ fprintf(fout, "Error opening \"%s\" for reading.\n", name);
+ fflush(fout);
+ }
+}
+
+int main(int,char *[])
+{
+ const char* files[] =
+ {
+ DumpInformation_BINARY_DIR "/SystemInformation.out",
+ DumpInformation_BINARY_DIR "/AllVariables.txt",
+ DumpInformation_BINARY_DIR "/AllCommands.txt",
+ DumpInformation_BINARY_DIR "/AllMacros.txt",
+ DumpInformation_BINARY_DIR "/OtherProperties.txt",
+ DumpInformation_BINARY_DIR "/../../Source/cmConfigure.h",
+ DumpInformation_BINARY_DIR "/../../CMakeCache.txt",
+ DumpInformation_BINARY_DIR "/../../CMakeFiles/CMakeOutput.log",
+ DumpInformation_BINARY_DIR "/../../CMakeFiles/CMakeError.log",
+ DumpInformation_BINARY_DIR "/../../Bootstrap.cmk/cmake_bootstrap.log",
+ DumpInformation_BINARY_DIR "/../../Source/cmsys/Configure.hxx",
+ DumpInformation_BINARY_DIR "/../../Source/cmsys/Configure.h",
+ DumpInformation_BINARY_DIR "/CMakeFiles/CMakeOutput.log",
+ DumpInformation_BINARY_DIR "/CMakeFiles/CMakeError.log",
+ 0
+ };
+
+ const char** f;
+ for(f = files; *f; ++f)
+ {
+ cmDumpInformationPrintFile(*f, stdout);
+ }
+
+ return 0;
+}
diff --git a/Tests/SystemInformation/DumpInformation.h.in b/Tests/SystemInformation/DumpInformation.h.in
new file mode 100644
index 000000000..72d5cd179
--- /dev/null
+++ b/Tests/SystemInformation/DumpInformation.h.in
@@ -0,0 +1,6 @@
+#ifndef _DumpInformation_h
+#define _DumpInformation_h
+
+#define DumpInformation_BINARY_DIR "@SystemInformation_BINARY_DIR@"
+
+#endif
diff --git a/Tests/SystemInformation/SystemInformation.in b/Tests/SystemInformation/SystemInformation.in
new file mode 100644
index 000000000..ecbc05408
--- /dev/null
+++ b/Tests/SystemInformation/SystemInformation.in
@@ -0,0 +1,102 @@
+CMAKE_STATIC_LIBRARY_PREFIX == "${CMAKE_STATIC_LIBRARY_PREFIX}"
+CMAKE_STATIC_LIBRARY_SUFFIX == "${CMAKE_STATIC_LIBRARY_SUFFIX}"
+CMAKE_SHARED_LIBRARY_PREFIX == "${CMAKE_SHARED_LIBRARY_PREFIX}"
+CMAKE_SHARED_LIBRARY_SUFFIX == "${CMAKE_SHARED_LIBRARY_SUFFIX}"
+CMAKE_SHARED_MODULE_PREFIX == "${CMAKE_SHARED_MODULE_PREFIX}"
+CMAKE_SHARED_MODULE_SUFFIX == "${CMAKE_SHARED_MODULE_SUFFIX}"
+
+
+CMAKE_DL_LIBS == "${CMAKE_DL_LIBS}"
+CMAKE_LIBRARY_PATH_FLAG == "${CMAKE_LIBRARY_PATH_FLAG}"
+CMAKE_LINK_LIBRARY_FLAG == "${CMAKE_LINK_LIBRARY_FLAG}"
+CMAKE_SKIP_RPATH == "${CMAKE_SKIP_RPATH}"
+CMAKE_SYSTEM_INFO_FILE == "${CMAKE_SYSTEM_INFO_FILE}"
+CMAKE_SYSTEM_NAME == "${CMAKE_SYSTEM_NAME}"
+CMAKE_SYSTEM == "${CMAKE_SYSTEM}"
+CMAKE_CXX_COMPILER == "${CMAKE_CXX_COMPILER}"
+CMAKE_C_COMPILER == "${CMAKE_C_COMPILER}"
+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_CXX_COMPILER_ID == "${CMAKE_CXX_COMPILER_ID}"
+CMAKE_CXX_COMPILER_VERSION == "${CMAKE_CXX_COMPILER_VERSION}"
+
+// C shared library flag
+CMAKE_SHARED_LIBRARY_C_FLAGS == "${CMAKE_SHARED_LIBRARY_C_FLAGS}"
+CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS == "${CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS}"
+CMAKE_SHARED_LIBRARY_LINK_FLAGS == "${CMAKE_SHARED_LIBRARY_LINK_FLAGS}"
+CMAKE_SHARED_LIBRARY_RUNTIME_FLAG == "${CMAKE_SHARED_LIBRARY_RUNTIME_FLAG}"
+CMAKE_SHARED_LIBRARY_RUNTIME_FLAG_SEP == "${CMAKE_SHARED_LIBRARY_RUNTIME_FLAG_SEP}"
+CMAKE_SHARED_LIBRARY_LINK_STATIC_C_FLAGS == "${CMAKE_SHARED_LIBRARY_LINK_STATIC_C_FLAGS}"
+CMAKE_SHARED_LIBRARY_LINK_DYNAMIC_C_FLAGS == "${CMAKE_SHARED_LIBRARY_LINK_DYNAMIC_C_FLAGS}"
+CMAKE_C_COMPILE_OPTIONS_PIC == "${CMAKE_C_COMPILE_OPTIONS_PIC}"
+CMAKE_C_COMPILE_OPTIONS_PIE == "${CMAKE_C_COMPILE_OPTIONS_PIE}"
+CMAKE_C_COMPILE_OPTIONS_DLL == "${CMAKE_C_COMPILE_OPTIONS_DLL}"
+
+// C shared module flags
+CMAKE_SHARED_MODULE_C_FLAGS == "${CMAKE_SHARED_MODULE_C_FLAGS}"
+CMAKE_SHARED_MODULE_CREATE_C_FLAGS == "${CMAKE_SHARED_MODULE_CREATE_C_FLAGS}"
+CMAKE_SHARED_MODULE_LINK_STATIC_C_FLAGS == "${CMAKE_SHARED_MODULE_LINK_STATIC_C_FLAGS}"
+CMAKE_SHARED_MODULE_LINK_DYNAMIC_C_FLAGS == "${CMAKE_SHARED_MODULE_LINK_DYNAMIC_C_FLAGS}"
+
+// C exe flags
+CMAKE_EXE_LINK_STATIC_C_FLAGS == "${CMAKE_EXE_LINK_STATIC_C_FLAGS}"
+CMAKE_EXE_LINK_DYNAMIC_C_FLAGS == "${CMAKE_EXE_LINK_DYNAMIC_C_FLAGS}"
+
+// CXX shared library flags
+CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS == "${CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS}"
+CMAKE_SHARED_LIBRARY_CXX_FLAGS == "${CMAKE_SHARED_LIBRARY_CXX_FLAGS}"
+CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS == "${CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS}"
+CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG == "${CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG}"
+CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG_SEP == "${CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG_SEP}"
+CMAKE_SHARED_LIBRARY_LINK_STATIC_CXX_FLAGS == "${CMAKE_SHARED_LIBRARY_LINK_STATIC_CXX_FLAGS}"
+CMAKE_SHARED_LIBRARY_LINK_DYNAMIC_CXX_FLAGS == "${CMAKE_SHARED_LIBRARY_LINK_DYNAMIC_CXX_FLAGS}"
+CMAKE_CXX_COMPILE_OPTIONS_PIC == "${CMAKE_CXX_COMPILE_OPTIONS_PIC}"
+CMAKE_CXX_COMPILE_OPTIONS_PIE == "${CMAKE_CXX_COMPILE_OPTIONS_PIE}"
+CMAKE_CXX_COMPILE_OPTIONS_DLL == "${CMAKE_CXX_COMPILE_OPTIONS_DLL}"
+
+// CXX shared module flags
+CMAKE_SHARED_MODULE_CREATE_CXX_FLAGS == "${CMAKE_SHARED_MODULE_CREATE_CXX_FLAGS}"
+CMAKE_SHARED_MODULE_CXX_FLAGS == "${CMAKE_SHARED_MODULE_CXX_FLAGS}"
+CMAKE_SHARED_MODULE_LINK_STATIC_CXX_FLAGS == "${CMAKE_SHARED_MODULE_LINK_STATIC_CXX_FLAGS}"
+CMAKE_SHARED_MODULE_LINK_DYNAMIC_CXX_FLAGS == "${CMAKE_SHARED_MODULE_LINK_DYNAMIC_CXX_FLAGS}"
+
+// CXX exe flags
+CMAKE_EXE_LINK_STATIC_CXX_FLAGS == "${CMAKE_EXE_LINK_STATIC_CXX_FLAGS}"
+CMAKE_EXE_LINK_DYNAMIC_CXX_FLAGS == "${CMAKE_EXE_LINK_DYNAMIC_CXX_FLAGS}"
+
+CMAKE_USER_MAKE_RULES_OVERRIDE == "${CMAKE_USER_MAKE_RULES_OVERRIDE}"
+CMAKE_VERBOSE_MAKEFILE == "${CMAKE_VERBOSE_MAKEFILE}"
+CMAKE_BUILD_TYPE == "${CMAKE_BUILD_TYPE}"
+CMAKE_CXX_FLAGS == "${CMAKE_CXX_FLAGS}"
+CMAKE_CXX_FLAGS_DEBUG == "${CMAKE_CXX_FLAGS_DEBUG}"
+CMAKE_CXX_FLAGS_MINSIZEREL == "${CMAKE_CXX_FLAGS_MINSIZEREL}"
+CMAKE_CXX_FLAGS_RELEASE == "${CMAKE_CXX_FLAGS_RELEASE}"
+CMAKE_CXX_FLAGS_RELWITHDEBINFO == "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}"
+
+CMAKE_C_FLAGS == "${CMAKE_C_FLAGS}"
+CMAKE_C_FLAGS_DEBUG == "${CMAKE_C_FLAGS_DEBUG}"
+CMAKE_C_FLAGS_MINSIZEREL == "${CMAKE_C_FLAGS_MINSIZEREL}"
+CMAKE_C_FLAGS_RELEASE == "${CMAKE_C_FLAGS_RELEASE}"
+CMAKE_C_FLAGS_RELWITHDEBINFO == "${CMAKE_C_FLAGS_RELWITHDEBINFO}"
+
+// build rules
+CMAKE_CXX_CREATE_SHARED_LIBRARY == "${CMAKE_CXX_CREATE_SHARED_LIBRARY}"
+CMAKE_CXX_CREATE_SHARED_MODULE == "${CMAKE_CXX_CREATE_SHARED_MODULE}"
+CMAKE_C_CREATE_SHARED_LIBRARY == "${CMAKE_C_CREATE_SHARED_LIBRARY}"
+CMAKE_C_CREATE_SHARED_MODULE == "${CMAKE_C_CREATE_SHARED_MODULE}"
+CMAKE_CXX_CREATE_STATIC_LIBRARY == "${CMAKE_CXX_CREATE_STATIC_LIBRARY}"
+CMAKE_C_CREATE_STATIC_LIBRARY == "${CMAKE_C_CREATE_STATIC_LIBRARY}"
+CMAKE_CXX_COMPILE_OBJECT == "${CMAKE_CXX_COMPILE_OBJECT}"
+CMAKE_C_COMPILE_OBJECT == "${CMAKE_C_COMPILE_OBJECT}"
+CMAKE_C_LINK_EXECUTABLE == "${CMAKE_C_LINK_EXECUTABLE}"
+CMAKE_CXX_LINK_EXECUTABLE == "${CMAKE_CXX_LINK_EXECUTABLE}"
+
+// implicit link info
+CMAKE_C_IMPLICIT_LINK_LIBRARIES == "${CMAKE_C_IMPLICIT_LINK_LIBRARIES}"
+CMAKE_C_IMPLICIT_LINK_DIRECTORIES == "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}"
+CMAKE_CXX_IMPLICIT_LINK_LIBRARIES == "${CMAKE_CXX_IMPLICIT_LINK_LIBRARIES}"
+CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES == "${CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES}"
+
+XCODE_VERSION == "${XCODE_VERSION}"
diff --git a/Tests/TarTest/CMakeLists.txt b/Tests/TarTest/CMakeLists.txt
new file mode 100644
index 000000000..a3c5b31ff
--- /dev/null
+++ b/Tests/TarTest/CMakeLists.txt
@@ -0,0 +1,69 @@
+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(${RET})
+ENDMACRO(EXEC_TAR_COMMAND)
+
+# 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)
+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(UNIX)
+
+# 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(NOT EXISTS "${sfile}")
+ EXEC_PROGRAM("${CMAKE_COMMAND}" ARGS "-E compare_files \"${sfile}\" \"${rfile}\"" RETURN_VALUE ret)
+ IF(${ret})
+ MESSAGE(SEND_ERROR "Files \"${sfile}\" \"${rfile}\" are different")
+ ENDIF(${ret})
+ ENDIF(NOT EXISTS "${sfile}")
+ ENDFOREACH(file)
+ENDMACRO(CHECK_DIR_STRUCTURE)
+
+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
new file mode 100644
index 000000000..86f2cd170
--- /dev/null
+++ b/Tests/TarTest/TestTarExec.cxx
@@ -0,0 +1,5 @@
+int main()
+{
+ return 0;
+}
+
diff --git a/Tests/TargetName/CMakeLists.txt b/Tests/TargetName/CMakeLists.txt
new file mode 100644
index 000000000..9729d21ff
--- /dev/null
+++ b/Tests/TargetName/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required (VERSION 2.6)
+project(TargetName)
+
+add_subdirectory(executables)
+add_subdirectory(scripts)
diff --git a/Tests/TargetName/executables/CMakeLists.txt b/Tests/TargetName/executables/CMakeLists.txt
new file mode 100644
index 000000000..2671e3e90
--- /dev/null
+++ b/Tests/TargetName/executables/CMakeLists.txt
@@ -0,0 +1 @@
+add_executable(hello_world hello_world.c)
diff --git a/Tests/TargetName/executables/hello_world.c b/Tests/TargetName/executables/hello_world.c
new file mode 100644
index 000000000..539d867e0
--- /dev/null
+++ b/Tests/TargetName/executables/hello_world.c
@@ -0,0 +1,5 @@
+#include <stdio.h>
+main()
+{
+ printf("hello, world\n");
+}
diff --git a/Tests/TargetName/scripts/.gitattributes b/Tests/TargetName/scripts/.gitattributes
new file mode 100644
index 000000000..51b8ce901
--- /dev/null
+++ b/Tests/TargetName/scripts/.gitattributes
@@ -0,0 +1 @@
+hello_world crlf=input
diff --git a/Tests/TargetName/scripts/CMakeLists.txt b/Tests/TargetName/scripts/CMakeLists.txt
new file mode 100644
index 000000000..40d4e2fb0
--- /dev/null
+++ b/Tests/TargetName/scripts/CMakeLists.txt
@@ -0,0 +1,13 @@
+if(NOT CMAKE_BINARY_DIR STREQUAL "${CMAKE_SOURCE_DIR}")
+ add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/hello_world
+ COMMAND ${CMAKE_COMMAND} -E copy
+ ${CMAKE_CURRENT_SOURCE_DIR}/hello_world ${CMAKE_CURRENT_BINARY_DIR}
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/hello_world
+ )
+ add_custom_target(
+ hello_world_copy ALL
+ DEPENDS #hello_world
+ ${CMAKE_CURRENT_BINARY_DIR}/hello_world
+ )
+endif(NOT CMAKE_BINARY_DIR STREQUAL "${CMAKE_SOURCE_DIR}")
diff --git a/Tests/TargetName/scripts/hello_world b/Tests/TargetName/scripts/hello_world
new file mode 100755
index 000000000..ea3a72c1c
--- /dev/null
+++ b/Tests/TargetName/scripts/hello_world
@@ -0,0 +1,2 @@
+#!/bin/sh
+echo "hello, world"
diff --git a/Tests/TestDriver/CMakeLists.txt b/Tests/TestDriver/CMakeLists.txt
new file mode 100644
index 000000000..bd5e97414
--- /dev/null
+++ b/Tests/TestDriver/CMakeLists.txt
@@ -0,0 +1,15 @@
+cmake_minimum_required (VERSION 2.6)
+PROJECT(TestDriverTest)
+
+SET(Extra_SRCS testExtraStuff.cxx testExtraStuff2.cxx )
+SET(Extra_SRCS ${Extra_SRCS};testExtraStuff3.cxx )
+INCLUDE_DIRECTORIES(${TestDriverTest_SOURCE_DIR})
+CREATE_TEST_SOURCELIST(testSrcs
+ TestDriverTest.cxx
+ test1.cxx
+ test2.cxx
+ subdir/test3.cxx
+ EXTRA_INCLUDE testArgs.h FUNCTION testProccessArgs)
+
+ADD_EXECUTABLE(TestDriverTest ${testSrcs} ${Extra_SRCS})
+
diff --git a/Tests/TestDriver/subdir/test3.cxx b/Tests/TestDriver/subdir/test3.cxx
new file mode 100644
index 000000000..976d6ebaa
--- /dev/null
+++ b/Tests/TestDriver/subdir/test3.cxx
@@ -0,0 +1,8 @@
+#include <stdio.h>
+int subdir_test3(int ac, char*av[])
+{
+ printf("test3\n");
+ for(int i =0; i < ac; i++)
+ printf("arg %d is %s\n", ac, av[i]);
+ return 0;
+}
diff --git a/Tests/TestDriver/test1.cxx b/Tests/TestDriver/test1.cxx
new file mode 100644
index 000000000..ac82f8ae9
--- /dev/null
+++ b/Tests/TestDriver/test1.cxx
@@ -0,0 +1,25 @@
+#include <stdio.h>
+int testExtraStuff3();
+int testExtraStuff();
+int testExtraStuff2();
+
+int test1(int ac, char* av[])
+{
+ if(!testExtraStuff2())
+ {
+ return -1;
+ }
+ if(!testExtraStuff())
+ {
+ return -1;
+ }
+ if(!testExtraStuff3())
+ {
+ return -1;
+ }
+
+ printf("test1\n");
+ for(int i =0; i < ac; i++)
+ printf("arg %d is %s\n", ac, av[i]);
+ return 0;
+}
diff --git a/Tests/TestDriver/test2.cxx b/Tests/TestDriver/test2.cxx
new file mode 100644
index 000000000..69f0fff17
--- /dev/null
+++ b/Tests/TestDriver/test2.cxx
@@ -0,0 +1,8 @@
+#include <stdio.h>
+int test2(int ac, char*av[])
+{
+ printf("test2\n");
+ for(int i =0; i < ac; i++)
+ printf("arg %d is %s\n", ac, av[i]);
+ return 0;
+}
diff --git a/Tests/TestDriver/testArgs.h b/Tests/TestDriver/testArgs.h
new file mode 100644
index 000000000..04893660b
--- /dev/null
+++ b/Tests/TestDriver/testArgs.h
@@ -0,0 +1,20 @@
+void testProccessArgs(int* ac, char***av)
+{
+ char** argv = *av;
+ if(*ac < 2)
+ {
+ return;
+ }
+ if(strcmp(argv[1], "--with-threads") == 0)
+ {
+ printf("number of threads is %s\n", argv[2]);
+ *av +=2;
+ *ac -=2;
+ }
+ else if (strcmp(argv[1], "--without-threads") == 0)
+ {
+ printf("no threads\n");
+ *av += 1;
+ *ac -= 1;
+ }
+}
diff --git a/Tests/TestDriver/testExtraStuff.cxx b/Tests/TestDriver/testExtraStuff.cxx
new file mode 100644
index 000000000..bfd073c9a
--- /dev/null
+++ b/Tests/TestDriver/testExtraStuff.cxx
@@ -0,0 +1,4 @@
+int testExtraStuff()
+{
+ return 1;
+}
diff --git a/Tests/TestDriver/testExtraStuff2.cxx b/Tests/TestDriver/testExtraStuff2.cxx
new file mode 100644
index 000000000..e755dbe02
--- /dev/null
+++ b/Tests/TestDriver/testExtraStuff2.cxx
@@ -0,0 +1,4 @@
+int testExtraStuff2()
+{
+ return 1;
+}
diff --git a/Tests/TestDriver/testExtraStuff3.cxx b/Tests/TestDriver/testExtraStuff3.cxx
new file mode 100644
index 000000000..9c239d42a
--- /dev/null
+++ b/Tests/TestDriver/testExtraStuff3.cxx
@@ -0,0 +1,4 @@
+int testExtraStuff3()
+{
+ return 1;
+}
diff --git a/Tests/TestInstall.sh.in b/Tests/TestInstall.sh.in
new file mode 100755
index 000000000..953578050
--- /dev/null
+++ b/Tests/TestInstall.sh.in
@@ -0,0 +1,63 @@
+#!/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/Testing/CMakeLists.txt b/Tests/Testing/CMakeLists.txt
new file mode 100644
index 000000000..815b52b58
--- /dev/null
+++ b/Tests/Testing/CMakeLists.txt
@@ -0,0 +1,59 @@
+#
+# Testing
+#
+cmake_minimum_required (VERSION 2.7)
+PROJECT (Testing)
+
+#
+# Lib and exe path
+#
+SET (LIBRARY_OUTPUT_PATH
+ ${Testing_BINARY_DIR}/bin/ CACHE PATH
+ "Single output directory for building all libraries.")
+
+SET (EXECUTABLE_OUTPUT_PATH
+ ${Testing_BINARY_DIR}/bin/ CACHE PATH
+ "Single output directory for building all executables.")
+
+#
+# Where will executable tests be written ?
+#
+IF (EXECUTABLE_OUTPUT_PATH)
+ SET (CXX_TEST_PATH ${EXECUTABLE_OUTPUT_PATH})
+ELSE (EXECUTABLE_OUTPUT_PATH)
+ SET (CXX_TEST_PATH .)
+ENDIF (EXECUTABLE_OUTPUT_PATH)
+
+#
+# Include Dart
+# (will also set NSLOOKUP, HOSTNAME, etc.)
+#
+INCLUDE (${CMAKE_ROOT}/Modules/Dart.cmake)
+
+#
+# Extra coverage
+#
+BUILD_COMMAND(BUILD_COMMAND_VAR ${CMAKE_MAKE_PROGRAM})
+BUILD_NAME(BUILD_NAME_VAR)
+SITE_NAME(SITE_NAME_VAR)
+
+#
+# Enable testing
+#
+ENABLE_TESTING()
+
+#
+# Add test
+#
+ADD_EXECUTABLE(testing testing.cxx)
+ADD_TEST(testing.1 ${Testing_BINARY_DIR}/bin/testing)
+
+#
+# skip level test
+#
+ADD_SUBDIRECTORY(Sub/Sub2)
+
+# Per-config target name and generator expressions.
+ADD_SUBDIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../PerConfig PerConfig)
+ADD_TEST(NAME testing.perconfig COMMAND perconfig)
+ADD_TEST(NAME testing.driver COMMAND ${PerConfig_COMMAND})
diff --git a/Tests/Testing/DartConfig.cmake b/Tests/Testing/DartConfig.cmake
new file mode 100644
index 000000000..26af720ac
--- /dev/null
+++ b/Tests/Testing/DartConfig.cmake
@@ -0,0 +1,24 @@
+# Dashboard is opened for submissions for a 24 hour period starting at
+# the specified NIGHLY_START_TIME. Time is specified in 24 hour format.
+SET (NIGHTLY_START_TIME "23:00:00 EST")
+
+# Dart server to submit results (used by client)
+SET (DROP_SITE "")
+SET (DROP_LOCATION "")
+SET (DROP_SITE_USER "")
+SET (DROP_SITE_PASSWORD "")
+SET (TRIGGER_SITE "")
+
+# Dart server configuration
+# SET (CVS_WEB_URL "")
+# SET (CVS_WEB_CVSROOT "")
+# SET (USE_DOXYGEN "Off")
+# SET (DOXYGEN_URL "")
+# SET (GNATS_WEB_URL "")
+
+# Continuous email delivery variables
+# SET (CONTINUOUS_FROM "")
+# SET (SMTP_MAILHOST "")
+# SET (CONTINUOUS_MONITOR_LIST "")
+# SET (CONTINUOUS_BASE_URL "")
+
diff --git a/Tests/Testing/Sub/Sub2/CMakeLists.txt b/Tests/Testing/Sub/Sub2/CMakeLists.txt
new file mode 100644
index 000000000..fb9e8619e
--- /dev/null
+++ b/Tests/Testing/Sub/Sub2/CMakeLists.txt
@@ -0,0 +1,17 @@
+#
+# Add test
+#
+ADD_EXECUTABLE(testing2 testing2.cxx)
+ADD_TEST(testing.2 ${Testing_BINARY_DIR}/bin/testing2)
+
+add_test(NotCycle.a ${CMAKE_COMMAND} -E echo a)
+add_test(NotCycle.test1 ${CMAKE_COMMAND} -E echo test1)
+set_property(TEST NotCycle.test1 PROPERTY DEPENDS NotCycle.a)
+
+add_test(NotCycle.b ${CMAKE_COMMAND} -E echo b)
+add_test(NotCycle.test2 ${CMAKE_COMMAND} -E echo test2)
+set_property(TEST NotCycle.test2 PROPERTY DEPENDS NotCycle.b NotCycle.test1)
+
+add_test(NotCycle.c ${CMAKE_COMMAND} -E echo c)
+add_test(NotCycle.test3 ${CMAKE_COMMAND} -E echo test3)
+set_property(TEST NotCycle.test3 PROPERTY DEPENDS NotCycle.c NotCycle.test1 NotCycle.test2)
diff --git a/Tests/Testing/Sub/Sub2/testing2.cxx b/Tests/Testing/Sub/Sub2/testing2.cxx
new file mode 100644
index 000000000..1482f27e5
--- /dev/null
+++ b/Tests/Testing/Sub/Sub2/testing2.cxx
@@ -0,0 +1,4 @@
+int main ()
+{
+ return 0;
+}
diff --git a/Tests/Testing/testing.cxx b/Tests/Testing/testing.cxx
new file mode 100644
index 000000000..1482f27e5
--- /dev/null
+++ b/Tests/Testing/testing.cxx
@@ -0,0 +1,4 @@
+int main ()
+{
+ return 0;
+}
diff --git a/Tests/TestsWorkingDirectory/CMakeLists.txt b/Tests/TestsWorkingDirectory/CMakeLists.txt
new file mode 100644
index 000000000..6a6e9b6c7
--- /dev/null
+++ b/Tests/TestsWorkingDirectory/CMakeLists.txt
@@ -0,0 +1,42 @@
+cmake_minimum_required(VERSION 2.6)
+project(TestsWorkingDirectoryProj)
+
+add_executable(WorkingDirectory main.c)
+
+enable_testing()
+
+set(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}/bin")
+
+add_test(NAME WorkingDirectory0 COMMAND WorkingDirectory "${CMAKE_BINARY_DIR}")
+
+add_test(NAME WorkingDirectory1 COMMAND WorkingDirectory "${CMAKE_BINARY_DIR}")
+set_tests_properties(WorkingDirectory1 PROPERTIES
+ WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
+)
+
+string(REGEX REPLACE "/[^/]*$" "" _parent_dir "${CMAKE_BINARY_DIR}")
+
+add_test(NAME WorkingDirectory2 COMMAND WorkingDirectory "${_parent_dir}")
+set_tests_properties(WorkingDirectory2 PROPERTIES
+ WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/.."
+)
+
+set(_default_cwd "${CMAKE_BINARY_DIR}")
+
+# FIXME: How to deal with /debug, /release, etc. with VS or Xcode?
+if(${CMAKE_GENERATOR} MATCHES "Makefiles")
+add_test(WorkingDirectory3 ${EXECUTABLE_OUTPUT_PATH}/WorkingDirectory ${_default_cwd})
+endif()
+
+add_test(NAME WorkingDirectory4 WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMAND WorkingDirectory ${CMAKE_BINARY_DIR})
+
+string(REGEX REPLACE "/[^/]*$" "" _parent_dir "${CMAKE_BINARY_DIR}")
+
+add_test(NAME WorkingDirectory5 WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/.. COMMAND WorkingDirectory ${_parent_dir})
+
+# FIXME: How to deal with /debug, /release, etc. with VS or Xcode?
+if(${CMAKE_GENERATOR} MATCHES "Makefiles")
+add_test(WorkingDirectory6 ${EXECUTABLE_OUTPUT_PATH}/WorkingDirectory ${_default_cwd} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/..)
+endif()
+
+add_subdirectory(subdir)
diff --git a/Tests/TestsWorkingDirectory/main.c b/Tests/TestsWorkingDirectory/main.c
new file mode 100644
index 000000000..19f2f14af
--- /dev/null
+++ b/Tests/TestsWorkingDirectory/main.c
@@ -0,0 +1,64 @@
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if defined(_WIN32) && (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__) || defined(__MINGW32__))
+
+#include <io.h>
+#include <direct.h>
+
+#if defined(__WATCOMC__)
+#include <direct.h>
+#define _getcwd getcwd
+#endif
+
+static const char* Getcwd(char* buf, unsigned int len)
+{
+ const char* ret = _getcwd(buf, len);
+ char* p = NULL;
+ if(!ret)
+ {
+ fprintf(stderr, "No current working directory.\n");
+ abort();
+ }
+ // make sure the drive letter is capital
+ if(strlen(buf) > 1 && buf[1] == ':')
+ {
+ buf[0] = toupper(buf[0]);
+ }
+ for(p = buf; *p; ++p)
+ {
+ if(*p == '\\')
+ {
+ *p = '/';
+ }
+ }
+ return ret;
+}
+
+#else
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+static const char* Getcwd(char* buf, unsigned int len)
+{
+ const char* ret = getcwd(buf, len);
+ if(!ret)
+ {
+ fprintf(stderr, "No current working directory\n");
+ abort();
+ }
+ return ret;
+}
+
+#endif
+
+int main(int argc, char *argv[])
+{
+ char buf[2048];
+ const char *cwd = Getcwd(buf, sizeof(buf));
+
+ return strcmp(cwd, argv[1]);
+}
diff --git a/Tests/TestsWorkingDirectory/subdir/CMakeLists.txt b/Tests/TestsWorkingDirectory/subdir/CMakeLists.txt
new file mode 100644
index 000000000..c16b1db43
--- /dev/null
+++ b/Tests/TestsWorkingDirectory/subdir/CMakeLists.txt
@@ -0,0 +1,31 @@
+add_test(NAME WorkingDirectory-Subdir0 COMMAND WorkingDirectory "${CMAKE_CURRENT_BINARY_DIR}")
+
+add_test(NAME WorkingDirectory-Subdir1 COMMAND WorkingDirectory "${CMAKE_CURRENT_BINARY_DIR}")
+set_tests_properties(WorkingDirectory-Subdir1 PROPERTIES
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
+)
+
+string(REGEX REPLACE "/[^/]*$" "" _parent_dir "${CMAKE_CURRENT_BINARY_DIR}")
+
+add_test(NAME WorkingDirectory-Subdir2 COMMAND WorkingDirectory "${_parent_dir}")
+set_tests_properties(WorkingDirectory-Subdir2 PROPERTIES
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/.."
+)
+
+set(_default_cwd "${CMAKE_CURRENT_BINARY_DIR}")
+
+# FIXME: How to deal with /debug, /release, etc. with VS or Xcode?
+if(${CMAKE_GENERATOR} MATCHES "Makefiles")
+add_test(WorkingDirectory-Subdir3 ${EXECUTABLE_OUTPUT_PATH}/WorkingDirectory ${_default_cwd})
+endif()
+
+add_test(NAME WorkingDirectory-Subdir4 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND WorkingDirectory ${CMAKE_CURRENT_BINARY_DIR})
+
+string(REGEX REPLACE "/[^/]*$" "" _parent_dir "${CMAKE_CURRENT_BINARY_DIR}")
+
+add_test(NAME WorkingDirectory-Subdir5 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/.. COMMAND WorkingDirectory ${_parent_dir})
+
+# FIXME: How to deal with /debug, /release, etc. with VS or Xcode?
+if(${CMAKE_GENERATOR} MATCHES "Makefiles")
+add_test(WorkingDirectory-Subdir6 ${EXECUTABLE_OUTPUT_PATH}/WorkingDirectory ${_default_cwd} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/..)
+endif()
diff --git a/Tests/TryCompile/CMakeLists.txt b/Tests/TryCompile/CMakeLists.txt
new file mode 100644
index 000000000..938c092c0
--- /dev/null
+++ b/Tests/TryCompile/CMakeLists.txt
@@ -0,0 +1,247 @@
+cmake_minimum_required (VERSION 2.6)
+PROJECT(TryCompile)
+
+MACRO(TEST_ASSERT value msg)
+ IF (NOT ${value})
+ MESSAGE (SEND_ERROR "Assertion failure:" ${msg} )
+ ENDIF (NOT ${value})
+ENDMACRO(TEST_ASSERT)
+
+MACRO(TEST_FAIL value msg)
+ IF (${value})
+ MESSAGE (SEND_ERROR "Failing test succeeded:" ${msg} )
+ ENDIF (${value})
+ENDMACRO(TEST_FAIL)
+
+MACRO(TEST_EXPECT_EXACT command expected)
+ IF(NOT "x${result}" STREQUAL "x${expected}")
+ MESSAGE(SEND_ERROR "${CMAKE_CURRENT_LIST_LINE}: TEST \"${command}\" failed: \"${result}\" expected: \"${expected}\"")
+ ENDIF(NOT "x${result}" STREQUAL "x${expected}")
+ENDMACRO(TEST_EXPECT_EXACT command expected)
+
+MACRO(TEST_EXPECT_CONTAINS command expected)
+ IF(NOT "${result}" MATCHES "${expected}")
+ MESSAGE(SEND_ERROR "${CMAKE_CURRENT_LIST_LINE}: TEST \"${command}\" failed: \"${result}\" expected: \"${expected}\"")
+ ENDIF(NOT "${result}" MATCHES "${expected}")
+ENDMACRO(TEST_EXPECT_CONTAINS command expected)
+
+
+# try to compile a file that should compile
+# also check that COPY_FILE works
+TRY_COMPILE(SHOULD_PASS
+ ${TryCompile_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp
+ ${TryCompile_SOURCE_DIR}/pass.c
+ OUTPUT_VARIABLE TRY_OUT
+ COPY_FILE ${TryCompile_BINARY_DIR}/CopyOfPass
+ )
+
+IF(NOT SHOULD_PASS)
+ MESSAGE(SEND_ERROR "should pass failed ${TRY_OUT}")
+ENDIF(NOT SHOULD_PASS)
+IF(NOT EXISTS "${TryCompile_BINARY_DIR}/CopyOfPass")
+ MESSAGE(SEND_ERROR "COPY_FILE to \"${TryCompile_BINARY_DIR}/CopyOfPass\" failed")
+ELSE(NOT EXISTS "${TryCompile_BINARY_DIR}/CopyOfPass")
+ FILE(REMOVE "${TryCompile_BINARY_DIR}/CopyOfPass")
+ENDIF(NOT EXISTS "${TryCompile_BINARY_DIR}/CopyOfPass")
+
+# try to compile a file that should not compile
+TRY_COMPILE(SHOULD_FAIL
+ ${TryCompile_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp
+ ${TryCompile_SOURCE_DIR}/fail.c
+ OUTPUT_VARIABLE TRY_OUT)
+IF(SHOULD_FAIL)
+ MESSAGE(SEND_ERROR "Should fail passed ${TRY_OUT}")
+ENDIF(SHOULD_FAIL)
+
+# try to compile a file that should compile
+TRY_COMPILE(SHOULD_PASS
+ ${TryCompile_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp
+ ${TryCompile_SOURCE_DIR}/pass.c
+ OUTPUT_VARIABLE TRY_OUT)
+IF(NOT SHOULD_PASS)
+ MESSAGE(SEND_ERROR "should pass failed ${TRY_OUT}")
+ENDIF(NOT SHOULD_PASS)
+
+# try to compile a file that should not compile
+TRY_COMPILE(SHOULD_FAIL
+ ${TryCompile_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp
+ ${TryCompile_SOURCE_DIR}/fail.c
+ OUTPUT_VARIABLE TRY_OUT)
+IF(SHOULD_FAIL)
+ MESSAGE(SEND_ERROR "Should fail passed ${TRY_OUT}")
+ENDIF(SHOULD_FAIL)
+
+IF(NOT SHOULD_FAIL)
+ IF(SHOULD_PASS)
+ MESSAGE("All Tests passed, ignore all previous output.")
+ ELSE(SHOULD_PASS)
+ MESSAGE("Test failed")
+ ENDIF(SHOULD_PASS)
+ELSE(NOT SHOULD_FAIL)
+ MESSAGE("Test failed")
+ENDIF(NOT SHOULD_FAIL)
+TRY_COMPILE(CMAKE_ANSI_FOR_SCOPE
+ ${TryCompile_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp
+ ${CMAKE_ROOT}/Modules/TestForAnsiForScope.cxx OUTPUT_VARIABLE OUT)
+IF (CMAKE_ANSI_FOR_SCOPE)
+ MESSAGE("Compiler supports ansi for")
+ELSE(CMAKE_ANSI_FOR_SCOPE)
+ MESSAGE("Compiler does not support ansi for scope")
+ENDIF(CMAKE_ANSI_FOR_SCOPE)
+
+TRY_COMPILE(CMAKE_ANSI_FOR_SCOPE
+ ${TryCompile_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp
+ ${CMAKE_ROOT}/Modules/TestForAnsiForScope.cxx OUTPUT_VARIABLE OUT)
+IF (CMAKE_ANSI_FOR_SCOPE)
+ MESSAGE("Compiler supports ansi for")
+ELSE(CMAKE_ANSI_FOR_SCOPE)
+ MESSAGE("Compiler does not support ansi for scope")
+ENDIF(CMAKE_ANSI_FOR_SCOPE)
+
+MESSAGE("use the module now")
+INCLUDE(${CMAKE_ROOT}/Modules/TestForANSIForScope.cmake)
+IF (CMAKE_ANSI_FOR_SCOPE)
+ MESSAGE("Compiler supports ansi for")
+ELSE(CMAKE_ANSI_FOR_SCOPE)
+ MESSAGE("Compiler does not support ansi for scope")
+ENDIF(CMAKE_ANSI_FOR_SCOPE)
+
+MESSAGE("Testing try_compile project mode")
+TRY_COMPILE(TEST_INNER
+ ${TryCompile_BINARY_DIR}/CMakeFiles/Inner
+ ${TryCompile_SOURCE_DIR}/Inner
+ TryCompileInner innerexe
+ OUTPUT_VARIABLE output)
+TEST_ASSERT(TEST_INNER "try_compile project mode failed:\n${output}")
+
+ADD_EXECUTABLE(TryCompile pass.c)
+
+######################################
+
+# now two tests for TRY_RUN
+
+# try to run a file that should compile and run without error
+# also check that OUTPUT_VARIABLE contains both the compile output
+# and the run output
+TRY_RUN(SHOULD_RUN SHOULD_COMPILE
+ ${TryCompile_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp
+ ${TryCompile_SOURCE_DIR}/exit_success.c
+ OUTPUT_VARIABLE TRY_OUT)
+IF(NOT SHOULD_COMPILE)
+ MESSAGE(SEND_ERROR "exit_success failed compiling: ${TRY_OUT}")
+ENDIF(NOT SHOULD_COMPILE)
+IF(NOT "${SHOULD_RUN}" STREQUAL "0")
+ MESSAGE(SEND_ERROR "exit_success failed running with exit code ${SHOULD_RUN}")
+ENDIF(NOT "${SHOULD_RUN}" STREQUAL "0")
+# check the compile output for the filename
+IF(NOT "${TRY_OUT}" MATCHES "exit_success")
+ MESSAGE(SEND_ERROR " TRY_OUT didn't contain \"exit_success\": \"${TRY_OUT}\"")
+ENDIF(NOT "${TRY_OUT}" MATCHES "exit_success")
+# check the run output
+IF(NOT "${TRY_OUT}" MATCHES "hello world")
+ MESSAGE(SEND_ERROR " TRY_OUT didn't contain \"hello world\": \"${TRY_OUT}\"")
+ENDIF(NOT "${TRY_OUT}" MATCHES "hello world")
+
+TRY_RUN(ARG_TEST_RUN ARG_TEST_COMPILE
+ ${TryCompile_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp
+ ${TryCompile_SOURCE_DIR}/expect_arg.c
+ OUTPUT_VARIABLE TRY_OUT
+ ARGS arg1 arg2)
+IF(NOT ARG_TEST_COMPILE)
+ MESSAGE(SEND_ERROR "expect_arg failed compiling: ${TRY_OUT}")
+ENDIF(NOT ARG_TEST_COMPILE)
+IF(NOT "${ARG_TEST_RUN}" STREQUAL "0")
+ MESSAGE(SEND_ERROR "expect_arg failed running with exit code ${ARG_TEST_RUN} ${TRY_OUT}")
+ENDIF(NOT "${ARG_TEST_RUN}" STREQUAL "0")
+
+# try to run a file that should compile and run, but return an error
+TRY_RUN(SHOULD_EXIT_WITH_ERROR SHOULD_COMPILE
+ ${TryCompile_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp
+ ${TryCompile_SOURCE_DIR}/exit_with_error.c
+ COMPILE_OUTPUT_VARIABLE COMPILE_OUTPUT
+ RUN_OUTPUT_VARIABLE RUN_OUTPUT)
+
+IF(NOT SHOULD_COMPILE)
+ MESSAGE(STATUS " exit_with_error failed compiling: ${COMPILE_OUTPUT}")
+ENDIF(NOT SHOULD_COMPILE)
+IF("${SHOULD_EXIT_WITH_ERROR}" STREQUAL "0")
+ MESSAGE(SEND_ERROR " exit_with_error passed with exit code ${SHOULD_EXIT_WITH_ERROR}")
+ENDIF("${SHOULD_EXIT_WITH_ERROR}" STREQUAL "0")
+
+# check the compile output, it should contain the filename
+IF(NOT "${COMPILE_OUTPUT}" MATCHES "exit_with_error")
+ MESSAGE(SEND_ERROR " COMPILE_OUT didn't contain \"exit_with_error\": \"${COMPILE_OUTPUT}\"")
+ENDIF(NOT "${COMPILE_OUTPUT}" MATCHES "exit_with_error")
+#... but not the run time output
+IF("${COMPILE_OUTPUT}" MATCHES "hello world")
+ MESSAGE(SEND_ERROR " COMPILE_OUT contains the run output: \"${COMPILE_OUTPUT}\"")
+ENDIF("${COMPILE_OUTPUT}" MATCHES "hello world")
+# check the run output, it should stdout
+IF(NOT "${RUN_OUTPUT}" MATCHES "hello world")
+ MESSAGE(SEND_ERROR " RUN_OUTPUT didn't contain \"hello world\": \"${RUN_OUTPUT}\"")
+ENDIF(NOT "${RUN_OUTPUT}" MATCHES "hello world")
+
+#######################################################################
+#
+# also test that the CHECK_C_SOURCE_COMPILES, CHECK_CXX_SOURCE_COMPILES
+# CHECK_C_SOURCE_RUNS and CHECK_CXX_SOURCE_RUNS macros work
+
+INCLUDE(CheckCSourceCompiles)
+INCLUDE(CheckCXXSourceCompiles)
+INCLUDE(CheckCSourceRuns)
+INCLUDE(CheckCXXSourceRuns)
+
+CHECK_C_SOURCE_COMPILES("I dont build" C_BUILD_SHOULD_FAIL)
+CHECK_C_SOURCE_COMPILES("int main() {return 0;}" C_BUILD_SHOULD_WORK)
+CHECK_C_SOURCE_RUNS("int main() {return 1;}" C_RUN_SHOULD_FAIL)
+CHECK_C_SOURCE_RUNS("int main() {return 0;}" C_RUN_SHOULD_WORK)
+
+TEST_FAIL(C_BUILD_SHOULD_FAIL "CHECK_C_SOURCE_COMPILES() succeeded, but should have failed")
+TEST_ASSERT(C_BUILD_SHOULD_WORK "CHECK_C_SOURCE_COMPILES() failed")
+TEST_FAIL(C_RUN_SHOULD_FAIL "CHECK_C_SOURCE_RUNS() succeeded, but should have failed")
+TEST_ASSERT(C_RUN_SHOULD_WORK "CHECK_C_SOURCE_RUNS() failed")
+
+CHECK_CXX_SOURCE_COMPILES("I dont build" CXX_BUILD_SHOULD_FAIL)
+CHECK_CXX_SOURCE_COMPILES("int main() {return 0;}" CXX_BUILD_SHOULD_WORK)
+CHECK_CXX_SOURCE_RUNS("int main() {return 2;}" CXX_RUN_SHOULD_FAIL)
+CHECK_CXX_SOURCE_RUNS("int main() {return 0;}" CXX_RUN_SHOULD_WORK)
+
+TEST_FAIL(CXX_BUILD_SHOULD_FAIL "CHECK_CXX_SOURCE_COMPILES() succeeded, but should have failed")
+TEST_ASSERT(CXX_BUILD_SHOULD_WORK "CHECK_CXX_SOURCE_COMPILES() failed")
+TEST_FAIL(CXX_RUN_SHOULD_FAIL "CHECK_CXX_SOURCE_RUNS() succeeded, but should have failed")
+TEST_ASSERT(CXX_RUN_SHOULD_WORK "CHECK_CXX_SOURCE_RUNS() failed")
+
+FOREACH(lang C CXX)
+ IF(NOT "${CMAKE_${lang}_COMPILER_ID}" MATCHES "^(PathScale)$")
+ SET(${lang}_DD --)
+ ENDIF()
+ENDFOREACH()
+
+UNSET(C_BOGUS_FLAG CACHE)
+INCLUDE(CheckCCompilerFlag)
+CHECK_C_COMPILER_FLAG(${C_DD}-_this_is_not_a_flag_ C_BOGUS_FLAG)
+TEST_FAIL(C_BOGUS_FLAG "CHECK_C_COMPILER_FLAG() succeeded, but should have failed")
+
+UNSET(CXX_BOGUS_FLAG CACHE)
+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")
+ 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")
+ENDIF()
+
+#######################################################################
+#
+# also test that the check_prototype_definition macro works
+
+include(CheckPrototypeDefinition)
+
+check_prototype_definition(remove
+ "int remove(const char *pathname)"
+ "0"
+ "stdio.h"
+ TEST_REMOVE_PROTO)
+test_assert(TEST_REMOVE_PROTO "check_prototype_definition for remove() failed")
diff --git a/Tests/TryCompile/Inner/CMakeLists.txt b/Tests/TryCompile/Inner/CMakeLists.txt
new file mode 100644
index 000000000..d62bcc4dd
--- /dev/null
+++ b/Tests/TryCompile/Inner/CMakeLists.txt
@@ -0,0 +1,15 @@
+cmake_minimum_required(VERSION 2.6)
+project(TryCompileInner C)
+
+try_compile(SHOULD_PASS
+ ${TryCompileInner_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp
+ ${TryCompileInner_SOURCE_DIR}/../pass.c
+ OUTPUT_VARIABLE TRY_OUT
+ )
+if(NOT SHOULD_PASS)
+ message(FATAL_ERROR "Inner try-compile SHOULD_PASS failed!")
+endif()
+
+add_library(innerlib innerlib.c)
+add_executable(innerexe innerexe.c)
+target_link_libraries(innerexe innerlib)
diff --git a/Tests/TryCompile/Inner/innerexe.c b/Tests/TryCompile/Inner/innerexe.c
new file mode 100644
index 000000000..9b121a17d
--- /dev/null
+++ b/Tests/TryCompile/Inner/innerexe.c
@@ -0,0 +1,2 @@
+extern int innerlib(void);
+int main() { return innerlib(); }
diff --git a/Tests/TryCompile/Inner/innerlib.c b/Tests/TryCompile/Inner/innerlib.c
new file mode 100644
index 000000000..0ce11799b
--- /dev/null
+++ b/Tests/TryCompile/Inner/innerlib.c
@@ -0,0 +1 @@
+int innerlib(void) { return 0; }
diff --git a/Tests/TryCompile/exit_success.c b/Tests/TryCompile/exit_success.c
new file mode 100644
index 000000000..82f5b5f82
--- /dev/null
+++ b/Tests/TryCompile/exit_success.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main()
+{
+ printf("hello world\n");
+ return 0;
+}
diff --git a/Tests/TryCompile/exit_with_error.c b/Tests/TryCompile/exit_with_error.c
new file mode 100644
index 000000000..f3c523d37
--- /dev/null
+++ b/Tests/TryCompile/exit_with_error.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main()
+{
+ printf("hello world\n");
+ return -1;
+}
diff --git a/Tests/TryCompile/expect_arg.c b/Tests/TryCompile/expect_arg.c
new file mode 100644
index 000000000..7ca49aa43
--- /dev/null
+++ b/Tests/TryCompile/expect_arg.c
@@ -0,0 +1,22 @@
+#include <stdio.h>
+#include <string.h>
+int main(int ac, char*av[])
+{
+ int i;
+ printf("ac = [%d]\n", ac);
+ for(i =0; i < ac; i++)
+ {
+ printf("arg[%d] = %s\n", i, av[i]);
+ }
+ if(ac == 3)
+ {
+ if(strcmp(av[1], "arg1") ==0
+ && strcmp(av[2], "arg2") ==0)
+ {
+ printf("arg1 and arg2 present and accounted for!\n");
+ return 0;
+ }
+ }
+ printf("arg1 and arg2 missing!\n");
+ return -1;
+}
diff --git a/Tests/TryCompile/fail.c b/Tests/TryCompile/fail.c
new file mode 100644
index 000000000..b915ebe4c
--- /dev/null
+++ b/Tests/TryCompile/fail.c
@@ -0,0 +1 @@
+asdflkjasdlj
diff --git a/Tests/TryCompile/pass.c b/Tests/TryCompile/pass.c
new file mode 100644
index 000000000..40bc5e2dd
--- /dev/null
+++ b/Tests/TryCompile/pass.c
@@ -0,0 +1,6 @@
+int main()
+{
+ return 0;
+}
+
+
diff --git a/Tests/Tutorial/Step1/CMakeLists.txt b/Tests/Tutorial/Step1/CMakeLists.txt
new file mode 100644
index 000000000..e461d3c8b
--- /dev/null
+++ b/Tests/Tutorial/Step1/CMakeLists.txt
@@ -0,0 +1,20 @@
+cmake_minimum_required (VERSION 2.6)
+project (Tutorial)
+
+# The version number.
+set (Tutorial_VERSION_MAJOR 1)
+set (Tutorial_VERSION_MINOR 0)
+
+# configure a header file to pass some of the CMake settings
+# to the source code
+configure_file (
+ "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in"
+ "${PROJECT_BINARY_DIR}/TutorialConfig.h"
+ )
+
+# add the binary tree to the search path for include files
+# so that we will find TutorialConfig.h
+include_directories("${PROJECT_BINARY_DIR}")
+
+# add the executable
+add_executable(Tutorial tutorial.cxx)
diff --git a/Tests/Tutorial/Step1/TutorialConfig.h.in b/Tests/Tutorial/Step1/TutorialConfig.h.in
new file mode 100644
index 000000000..5395a0671
--- /dev/null
+++ b/Tests/Tutorial/Step1/TutorialConfig.h.in
@@ -0,0 +1,4 @@
+// the configured options and settings for Tutorial
+#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
+#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
+
diff --git a/Tests/Tutorial/Step1/tutorial.cxx b/Tests/Tutorial/Step1/tutorial.cxx
new file mode 100644
index 000000000..8ab6dc306
--- /dev/null
+++ b/Tests/Tutorial/Step1/tutorial.cxx
@@ -0,0 +1,23 @@
+// A simple program that computes the square root of a number
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include "TutorialConfig.h"
+
+int main (int argc, char *argv[])
+{
+ if (argc < 2)
+ {
+ fprintf(stdout,"%s Version %d.%d\n",
+ argv[0],
+ Tutorial_VERSION_MAJOR,
+ Tutorial_VERSION_MINOR);
+ fprintf(stdout,"Usage: %s number\n",argv[0]);
+ return 1;
+ }
+ double inputValue = atof(argv[1]);
+ double outputValue = sqrt(inputValue);
+ fprintf(stdout,"The square root of %g is %g\n",
+ inputValue, outputValue);
+ return 0;
+}
diff --git a/Tests/Tutorial/Step2/CMakeLists.txt b/Tests/Tutorial/Step2/CMakeLists.txt
new file mode 100644
index 000000000..c82b7df98
--- /dev/null
+++ b/Tests/Tutorial/Step2/CMakeLists.txt
@@ -0,0 +1,31 @@
+cmake_minimum_required (VERSION 2.6)
+project (Tutorial)
+
+# The version number.
+set (Tutorial_VERSION_MAJOR 1)
+set (Tutorial_VERSION_MINOR 0)
+
+# should we use our own math functions
+option(USE_MYMATH "Use tutorial provided math implementation" ON)
+
+# configure a header file to pass some of the CMake settings
+# to the source code
+configure_file (
+ "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in"
+ "${PROJECT_BINARY_DIR}/TutorialConfig.h"
+ )
+
+# add the binary tree to the search path for include files
+# so that we will find TutorialConfig.h
+include_directories ("${PROJECT_BINARY_DIR}")
+
+# add the MathFunctions library?
+if (USE_MYMATH)
+ include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions")
+ add_subdirectory (MathFunctions)
+ set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)
+endif (USE_MYMATH)
+
+# add the executable
+add_executable (Tutorial tutorial.cxx)
+target_link_libraries (Tutorial ${EXTRA_LIBS})
diff --git a/Tests/Tutorial/Step2/MathFunctions/CMakeLists.txt b/Tests/Tutorial/Step2/MathFunctions/CMakeLists.txt
new file mode 100644
index 000000000..8b443a659
--- /dev/null
+++ b/Tests/Tutorial/Step2/MathFunctions/CMakeLists.txt
@@ -0,0 +1 @@
+add_library(MathFunctions mysqrt.cxx)
diff --git a/Tests/Tutorial/Step2/MathFunctions/MathFunctions.h b/Tests/Tutorial/Step2/MathFunctions/MathFunctions.h
new file mode 100644
index 000000000..cd36bccff
--- /dev/null
+++ b/Tests/Tutorial/Step2/MathFunctions/MathFunctions.h
@@ -0,0 +1 @@
+double mysqrt(double x);
diff --git a/Tests/Tutorial/Step2/MathFunctions/mysqrt.cxx b/Tests/Tutorial/Step2/MathFunctions/mysqrt.cxx
new file mode 100644
index 000000000..76b8e2d9d
--- /dev/null
+++ b/Tests/Tutorial/Step2/MathFunctions/mysqrt.cxx
@@ -0,0 +1,29 @@
+#include <stdio.h>
+#include "MathFunctions.h"
+
+// a hack square root calculation using simple operations
+double mysqrt(double x)
+{
+ if (x <= 0)
+ {
+ return 0;
+ }
+
+ double result;
+ double delta;
+ result = x;
+
+ // do ten iterations
+ int i;
+ for (i = 0; i < 10; ++i)
+ {
+ if (result <= 0)
+ {
+ result = 0.1;
+ }
+ delta = x - (result*result);
+ result = result + 0.5*delta/result;
+ fprintf(stdout,"Computing sqrt of %g to be %g\n",x,result);
+ }
+ return result;
+}
diff --git a/Tests/Tutorial/Step2/TutorialConfig.h.in b/Tests/Tutorial/Step2/TutorialConfig.h.in
new file mode 100644
index 000000000..25a06020a
--- /dev/null
+++ b/Tests/Tutorial/Step2/TutorialConfig.h.in
@@ -0,0 +1,5 @@
+// the configured options and settings for Tutorial
+#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
+#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
+#cmakedefine USE_MYMATH
+
diff --git a/Tests/Tutorial/Step2/tutorial.cxx b/Tests/Tutorial/Step2/tutorial.cxx
new file mode 100644
index 000000000..82b416f11
--- /dev/null
+++ b/Tests/Tutorial/Step2/tutorial.cxx
@@ -0,0 +1,34 @@
+// A simple program that computes the square root of a number
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include "TutorialConfig.h"
+
+#ifdef USE_MYMATH
+#include "MathFunctions.h"
+#endif
+
+int main (int argc, char *argv[])
+{
+ if (argc < 2)
+ {
+ fprintf(stdout,"%s Version %d.%d\n",
+ argv[0],
+ Tutorial_VERSION_MAJOR,
+ Tutorial_VERSION_MINOR);
+ fprintf(stdout,"Usage: %s number\n",argv[0]);
+ return 1;
+ }
+
+ double inputValue = atof(argv[1]);
+
+#ifdef USE_MYMATH
+ double outputValue = mysqrt(inputValue);
+#else
+ double outputValue = sqrt(inputValue);
+#endif
+
+ fprintf(stdout,"The square root of %g is %g\n",
+ inputValue, outputValue);
+ return 0;
+}
diff --git a/Tests/Tutorial/Step3/CMakeLists.txt b/Tests/Tutorial/Step3/CMakeLists.txt
new file mode 100644
index 000000000..0b05fd737
--- /dev/null
+++ b/Tests/Tutorial/Step3/CMakeLists.txt
@@ -0,0 +1,68 @@
+cmake_minimum_required (VERSION 2.6)
+project (Tutorial)
+
+# The version number.
+set (Tutorial_VERSION_MAJOR 1)
+set (Tutorial_VERSION_MINOR 0)
+
+# should we use our own math functions
+option(USE_MYMATH "Use tutorial provided math implementation" ON)
+
+# configure a header file to pass some of the CMake settings
+# to the source code
+configure_file (
+ "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in"
+ "${PROJECT_BINARY_DIR}/TutorialConfig.h"
+ )
+
+# add the binary tree to the search path for include files
+# so that we will find TutorialConfig.h
+include_directories ("${PROJECT_BINARY_DIR}")
+
+# add the MathFunctions library?
+if (USE_MYMATH)
+ include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions")
+ add_subdirectory (MathFunctions)
+ set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)
+endif (USE_MYMATH)
+
+# add the executable
+add_executable (Tutorial tutorial.cxx)
+target_link_libraries (Tutorial ${EXTRA_LIBS})
+
+# add the install targets
+install (TARGETS Tutorial DESTINATION bin)
+install (FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h"
+ DESTINATION include)
+
+
+# enable testing
+enable_testing ()
+
+# does the application run
+add_test (TutorialRuns Tutorial 25)
+
+# does it sqrt of 25
+add_test (TutorialComp25 Tutorial 25)
+set_tests_properties (TutorialComp25
+ PROPERTIES PASS_REGULAR_EXPRESSION "25 is 5"
+ )
+
+# does it handle negative numbers
+add_test (TutorialNegative Tutorial -25)
+set_tests_properties (TutorialNegative
+ PROPERTIES PASS_REGULAR_EXPRESSION "-25 is 0"
+ )
+
+# does it handle small numbers
+add_test (TutorialSmall Tutorial 0.0001)
+set_tests_properties (TutorialSmall
+ PROPERTIES PASS_REGULAR_EXPRESSION "0.0001 is 0.01"
+ )
+
+# does the usage message work?
+add_test (TutorialUsage Tutorial)
+set_tests_properties (TutorialUsage
+ PROPERTIES
+ PASS_REGULAR_EXPRESSION "Usage:.*number"
+ )
diff --git a/Tests/Tutorial/Step3/MathFunctions/CMakeLists.txt b/Tests/Tutorial/Step3/MathFunctions/CMakeLists.txt
new file mode 100644
index 000000000..f386036c3
--- /dev/null
+++ b/Tests/Tutorial/Step3/MathFunctions/CMakeLists.txt
@@ -0,0 +1,4 @@
+add_library(MathFunctions mysqrt.cxx)
+
+install (TARGETS MathFunctions DESTINATION bin)
+install (FILES MathFunctions.h DESTINATION include)
diff --git a/Tests/Tutorial/Step3/MathFunctions/MathFunctions.h b/Tests/Tutorial/Step3/MathFunctions/MathFunctions.h
new file mode 100644
index 000000000..cd36bccff
--- /dev/null
+++ b/Tests/Tutorial/Step3/MathFunctions/MathFunctions.h
@@ -0,0 +1 @@
+double mysqrt(double x);
diff --git a/Tests/Tutorial/Step3/MathFunctions/mysqrt.cxx b/Tests/Tutorial/Step3/MathFunctions/mysqrt.cxx
new file mode 100644
index 000000000..76b8e2d9d
--- /dev/null
+++ b/Tests/Tutorial/Step3/MathFunctions/mysqrt.cxx
@@ -0,0 +1,29 @@
+#include <stdio.h>
+#include "MathFunctions.h"
+
+// a hack square root calculation using simple operations
+double mysqrt(double x)
+{
+ if (x <= 0)
+ {
+ return 0;
+ }
+
+ double result;
+ double delta;
+ result = x;
+
+ // do ten iterations
+ int i;
+ for (i = 0; i < 10; ++i)
+ {
+ if (result <= 0)
+ {
+ result = 0.1;
+ }
+ delta = x - (result*result);
+ result = result + 0.5*delta/result;
+ fprintf(stdout,"Computing sqrt of %g to be %g\n",x,result);
+ }
+ return result;
+}
diff --git a/Tests/Tutorial/Step3/TutorialConfig.h.in b/Tests/Tutorial/Step3/TutorialConfig.h.in
new file mode 100644
index 000000000..25a06020a
--- /dev/null
+++ b/Tests/Tutorial/Step3/TutorialConfig.h.in
@@ -0,0 +1,5 @@
+// the configured options and settings for Tutorial
+#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
+#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
+#cmakedefine USE_MYMATH
+
diff --git a/Tests/Tutorial/Step3/tutorial.cxx b/Tests/Tutorial/Step3/tutorial.cxx
new file mode 100644
index 000000000..82b416f11
--- /dev/null
+++ b/Tests/Tutorial/Step3/tutorial.cxx
@@ -0,0 +1,34 @@
+// A simple program that computes the square root of a number
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include "TutorialConfig.h"
+
+#ifdef USE_MYMATH
+#include "MathFunctions.h"
+#endif
+
+int main (int argc, char *argv[])
+{
+ if (argc < 2)
+ {
+ fprintf(stdout,"%s Version %d.%d\n",
+ argv[0],
+ Tutorial_VERSION_MAJOR,
+ Tutorial_VERSION_MINOR);
+ fprintf(stdout,"Usage: %s number\n",argv[0]);
+ return 1;
+ }
+
+ double inputValue = atof(argv[1]);
+
+#ifdef USE_MYMATH
+ double outputValue = mysqrt(inputValue);
+#else
+ double outputValue = sqrt(inputValue);
+#endif
+
+ fprintf(stdout,"The square root of %g is %g\n",
+ inputValue, outputValue);
+ return 0;
+}
diff --git a/Tests/Tutorial/Step4/CMakeLists.txt b/Tests/Tutorial/Step4/CMakeLists.txt
new file mode 100644
index 000000000..3b24b4416
--- /dev/null
+++ b/Tests/Tutorial/Step4/CMakeLists.txt
@@ -0,0 +1,68 @@
+cmake_minimum_required (VERSION 2.6)
+project (Tutorial)
+
+# The version number.
+set (Tutorial_VERSION_MAJOR 1)
+set (Tutorial_VERSION_MINOR 0)
+
+# does this system provide the log and exp functions?
+include (${CMAKE_ROOT}/Modules/CheckFunctionExists.cmake)
+check_function_exists (log HAVE_LOG)
+check_function_exists (exp HAVE_EXP)
+
+# should we use our own math functions
+option(USE_MYMATH "Use tutorial provided math implementation" ON)
+
+# configure a header file to pass some of the CMake settings
+# to the source code
+configure_file (
+ "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in"
+ "${PROJECT_BINARY_DIR}/TutorialConfig.h"
+ )
+
+# add the binary tree to the search path for include files
+# so that we will find TutorialConfig.h
+include_directories ("${PROJECT_BINARY_DIR}")
+
+# add the MathFunctions library?
+if (USE_MYMATH)
+ include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions")
+ add_subdirectory (MathFunctions)
+ set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)
+endif (USE_MYMATH)
+
+# add the executable
+add_executable (Tutorial tutorial.cxx)
+target_link_libraries (Tutorial ${EXTRA_LIBS})
+
+# add the install targets
+install (TARGETS Tutorial DESTINATION bin)
+install (FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h"
+ DESTINATION include)
+
+# enable testing
+enable_testing ()
+
+# does the application run
+add_test (TutorialRuns Tutorial 25)
+
+# does the usage message work?
+add_test (TutorialUsage Tutorial)
+set_tests_properties (TutorialUsage
+ PROPERTIES
+ PASS_REGULAR_EXPRESSION "Usage:.*number"
+ )
+
+#define a macro to simplify adding tests
+macro (do_test arg result)
+ add_test (TutorialComp${arg} Tutorial ${arg})
+ set_tests_properties (TutorialComp${arg}
+ PROPERTIES PASS_REGULAR_EXPRESSION ${result}
+ )
+endmacro (do_test)
+
+# do a bunch of result based tests
+do_test (25 "25 is 5")
+do_test (-25 "-25 is 0")
+do_test (0.0001 "0.0001 is 0.01")
+
diff --git a/Tests/Tutorial/Step4/MathFunctions/CMakeLists.txt b/Tests/Tutorial/Step4/MathFunctions/CMakeLists.txt
new file mode 100644
index 000000000..f386036c3
--- /dev/null
+++ b/Tests/Tutorial/Step4/MathFunctions/CMakeLists.txt
@@ -0,0 +1,4 @@
+add_library(MathFunctions mysqrt.cxx)
+
+install (TARGETS MathFunctions DESTINATION bin)
+install (FILES MathFunctions.h DESTINATION include)
diff --git a/Tests/Tutorial/Step4/MathFunctions/MathFunctions.h b/Tests/Tutorial/Step4/MathFunctions/MathFunctions.h
new file mode 100644
index 000000000..cd36bccff
--- /dev/null
+++ b/Tests/Tutorial/Step4/MathFunctions/MathFunctions.h
@@ -0,0 +1 @@
+double mysqrt(double x);
diff --git a/Tests/Tutorial/Step4/MathFunctions/mysqrt.cxx b/Tests/Tutorial/Step4/MathFunctions/mysqrt.cxx
new file mode 100644
index 000000000..0cf7db480
--- /dev/null
+++ b/Tests/Tutorial/Step4/MathFunctions/mysqrt.cxx
@@ -0,0 +1,39 @@
+#include <stdio.h>
+#include "MathFunctions.h"
+#include "TutorialConfig.h"
+
+#include <math.h>
+
+// a hack square root calculation using simple operations
+double mysqrt(double x)
+{
+ if (x <= 0)
+ {
+ return 0;
+ }
+
+ double result;
+
+ // if we have both log and exp then use them
+#if defined(HAVE_LOG) && defined (HAVE_EXP)
+ result = exp(log(x)*0.5);
+ fprintf(stdout,"Computing sqrt of %g to be %g using log\n",x,result);
+#else
+ double delta;
+ result = x;
+
+ // do ten iterations
+ int i;
+ for (i = 0; i < 10; ++i)
+ {
+ if (result <= 0)
+ {
+ result = 0.1;
+ }
+ delta = x - (result*result);
+ result = result + 0.5*delta/result;
+ fprintf(stdout,"Computing sqrt of %g to be %g\n",x,result);
+ }
+#endif
+ return result;
+}
diff --git a/Tests/Tutorial/Step4/TutorialConfig.h.in b/Tests/Tutorial/Step4/TutorialConfig.h.in
new file mode 100644
index 000000000..a0912656a
--- /dev/null
+++ b/Tests/Tutorial/Step4/TutorialConfig.h.in
@@ -0,0 +1,9 @@
+// the configured options and settings for Tutorial
+#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
+#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
+#cmakedefine USE_MYMATH
+
+// does the platform provide exp and log functions?
+#cmakedefine HAVE_LOG
+#cmakedefine HAVE_EXP
+
diff --git a/Tests/Tutorial/Step4/tutorial.cxx b/Tests/Tutorial/Step4/tutorial.cxx
new file mode 100644
index 000000000..82b416f11
--- /dev/null
+++ b/Tests/Tutorial/Step4/tutorial.cxx
@@ -0,0 +1,34 @@
+// A simple program that computes the square root of a number
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include "TutorialConfig.h"
+
+#ifdef USE_MYMATH
+#include "MathFunctions.h"
+#endif
+
+int main (int argc, char *argv[])
+{
+ if (argc < 2)
+ {
+ fprintf(stdout,"%s Version %d.%d\n",
+ argv[0],
+ Tutorial_VERSION_MAJOR,
+ Tutorial_VERSION_MINOR);
+ fprintf(stdout,"Usage: %s number\n",argv[0]);
+ return 1;
+ }
+
+ double inputValue = atof(argv[1]);
+
+#ifdef USE_MYMATH
+ double outputValue = mysqrt(inputValue);
+#else
+ double outputValue = sqrt(inputValue);
+#endif
+
+ fprintf(stdout,"The square root of %g is %g\n",
+ inputValue, outputValue);
+ return 0;
+}
diff --git a/Tests/Tutorial/Step5/CMakeLists.txt b/Tests/Tutorial/Step5/CMakeLists.txt
new file mode 100644
index 000000000..3002ea084
--- /dev/null
+++ b/Tests/Tutorial/Step5/CMakeLists.txt
@@ -0,0 +1,72 @@
+cmake_minimum_required (VERSION 2.6)
+project (Tutorial)
+
+# The version number.
+set (Tutorial_VERSION_MAJOR 1)
+set (Tutorial_VERSION_MINOR 0)
+
+# does this system provide the log and exp functions?
+include (${CMAKE_ROOT}/Modules/CheckFunctionExists.cmake)
+check_function_exists (log HAVE_LOG)
+check_function_exists (exp HAVE_EXP)
+
+# should we use our own math functions
+option(USE_MYMATH "Use tutorial provided math implementation" ON)
+
+# configure a header file to pass some of the CMake settings
+# to the source code
+configure_file (
+ "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in"
+ "${PROJECT_BINARY_DIR}/TutorialConfig.h"
+ )
+
+# add the binary tree to the search path for include files
+# so that we will find TutorialConfig.h
+include_directories ("${PROJECT_BINARY_DIR}")
+
+# add the MathFunctions library?
+if (USE_MYMATH)
+ include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions")
+ add_subdirectory (MathFunctions)
+ set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)
+endif (USE_MYMATH)
+
+# add the executable
+add_executable (Tutorial tutorial.cxx)
+target_link_libraries (Tutorial ${EXTRA_LIBS})
+
+# add the install targets
+install (TARGETS Tutorial DESTINATION bin)
+install (FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h"
+ DESTINATION include)
+
+# enable testing
+enable_testing ()
+
+# does the application run
+add_test (TutorialRuns Tutorial 25)
+
+# does the usage message work?
+add_test (TutorialUsage Tutorial)
+set_tests_properties (TutorialUsage
+ PROPERTIES
+ PASS_REGULAR_EXPRESSION "Usage:.*number"
+ )
+
+#define a macro to simplify adding tests
+macro (do_test arg result)
+ add_test (TutorialComp${arg} Tutorial ${arg})
+ set_tests_properties (TutorialComp${arg}
+ PROPERTIES PASS_REGULAR_EXPRESSION ${result}
+ )
+endmacro (do_test)
+
+# do a bunch of result based tests
+do_test (4 "4 is 2")
+do_test (9 "9 is 3")
+do_test (5 "5 is 2.236")
+do_test (7 "7 is 2.645")
+do_test (25 "25 is 5")
+do_test (-25 "-25 is 0")
+do_test (0.0001 "0.0001 is 0.01")
+
diff --git a/Tests/Tutorial/Step5/MathFunctions/CMakeLists.txt b/Tests/Tutorial/Step5/MathFunctions/CMakeLists.txt
new file mode 100644
index 000000000..453a46332
--- /dev/null
+++ b/Tests/Tutorial/Step5/MathFunctions/CMakeLists.txt
@@ -0,0 +1,17 @@
+# first we add the executable that generates the table
+# add the binary tree directory to the search path for include files
+include_directories( ${CMAKE_CURRENT_BINARY_DIR} )
+
+add_executable(MakeTable MakeTable.cxx )
+# add the command to generate the source code
+add_custom_command (
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
+ COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
+ DEPENDS MakeTable
+ )
+
+# add the main library
+add_library(MathFunctions mysqrt.cxx ${CMAKE_CURRENT_BINARY_DIR}/Table.h )
+
+install (TARGETS MathFunctions DESTINATION bin)
+install (FILES MathFunctions.h DESTINATION include)
diff --git a/Tests/Tutorial/Step5/MathFunctions/MakeTable.cxx b/Tests/Tutorial/Step5/MathFunctions/MakeTable.cxx
new file mode 100644
index 000000000..540254271
--- /dev/null
+++ b/Tests/Tutorial/Step5/MathFunctions/MakeTable.cxx
@@ -0,0 +1,35 @@
+// A simple program that builds a sqrt table
+#include <stdio.h>
+#include <math.h>
+
+int main (int argc, char *argv[])
+{
+ int i;
+ double result;
+
+ // make sure we have enough arguments
+ if (argc < 2)
+ {
+ return 1;
+ }
+
+ // open the output file
+ FILE *fout = fopen(argv[1],"w");
+ if (!fout)
+ {
+ return 1;
+ }
+
+ // create a source file with a table of square roots
+ fprintf(fout,"double sqrtTable[] = {\n");
+ for (i = 0; i < 10; ++i)
+ {
+ result = sqrt(static_cast<double>(i));
+ fprintf(fout,"%g,\n",result);
+ }
+
+ // close the table with a zero
+ fprintf(fout,"0};\n");
+ fclose(fout);
+ return 0;
+}
diff --git a/Tests/Tutorial/Step5/MathFunctions/MathFunctions.h b/Tests/Tutorial/Step5/MathFunctions/MathFunctions.h
new file mode 100644
index 000000000..cd36bccff
--- /dev/null
+++ b/Tests/Tutorial/Step5/MathFunctions/MathFunctions.h
@@ -0,0 +1 @@
+double mysqrt(double x);
diff --git a/Tests/Tutorial/Step5/MathFunctions/mysqrt.cxx b/Tests/Tutorial/Step5/MathFunctions/mysqrt.cxx
new file mode 100644
index 000000000..33659b740
--- /dev/null
+++ b/Tests/Tutorial/Step5/MathFunctions/mysqrt.cxx
@@ -0,0 +1,44 @@
+#include <stdio.h>
+#include "MathFunctions.h"
+#include "TutorialConfig.h"
+
+// include the generated table
+#include "Table.h"
+
+#include <math.h>
+
+// a hack square root calculation using simple operations
+double mysqrt(double x)
+{
+ if (x <= 0)
+ {
+ return 0;
+ }
+
+ double result;
+
+ // if we have both log and exp then use them
+ double delta;
+
+ // use the table to help find an initial value
+ result = x;
+ if (x >= 1 && x < 10)
+ {
+ result = sqrtTable[static_cast<int>(x)];
+ }
+
+ // do ten iterations
+ int i;
+ for (i = 0; i < 10; ++i)
+ {
+ if (result <= 0)
+ {
+ result = 0.1;
+ }
+ delta = x - (result*result);
+ result = result + 0.5*delta/result;
+ fprintf(stdout,"Computing sqrt of %g to be %g\n",x,result);
+ }
+
+ return result;
+}
diff --git a/Tests/Tutorial/Step5/TutorialConfig.h.in b/Tests/Tutorial/Step5/TutorialConfig.h.in
new file mode 100644
index 000000000..a0912656a
--- /dev/null
+++ b/Tests/Tutorial/Step5/TutorialConfig.h.in
@@ -0,0 +1,9 @@
+// the configured options and settings for Tutorial
+#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
+#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
+#cmakedefine USE_MYMATH
+
+// does the platform provide exp and log functions?
+#cmakedefine HAVE_LOG
+#cmakedefine HAVE_EXP
+
diff --git a/Tests/Tutorial/Step5/tutorial.cxx b/Tests/Tutorial/Step5/tutorial.cxx
new file mode 100644
index 000000000..82b416f11
--- /dev/null
+++ b/Tests/Tutorial/Step5/tutorial.cxx
@@ -0,0 +1,34 @@
+// A simple program that computes the square root of a number
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include "TutorialConfig.h"
+
+#ifdef USE_MYMATH
+#include "MathFunctions.h"
+#endif
+
+int main (int argc, char *argv[])
+{
+ if (argc < 2)
+ {
+ fprintf(stdout,"%s Version %d.%d\n",
+ argv[0],
+ Tutorial_VERSION_MAJOR,
+ Tutorial_VERSION_MINOR);
+ fprintf(stdout,"Usage: %s number\n",argv[0]);
+ return 1;
+ }
+
+ double inputValue = atof(argv[1]);
+
+#ifdef USE_MYMATH
+ double outputValue = mysqrt(inputValue);
+#else
+ double outputValue = sqrt(inputValue);
+#endif
+
+ fprintf(stdout,"The square root of %g is %g\n",
+ inputValue, outputValue);
+ return 0;
+}
diff --git a/Tests/Tutorial/Step6/CMakeLists.txt b/Tests/Tutorial/Step6/CMakeLists.txt
new file mode 100644
index 000000000..4f70f4fc4
--- /dev/null
+++ b/Tests/Tutorial/Step6/CMakeLists.txt
@@ -0,0 +1,78 @@
+cmake_minimum_required (VERSION 2.6)
+project (Tutorial)
+
+# The version number.
+set (Tutorial_VERSION_MAJOR 1)
+set (Tutorial_VERSION_MINOR 0)
+
+# does this system provide the log and exp functions?
+include (${CMAKE_ROOT}/Modules/CheckFunctionExists.cmake)
+check_function_exists (log HAVE_LOG)
+check_function_exists (exp HAVE_EXP)
+
+# should we use our own math functions
+option(USE_MYMATH "Use tutorial provided math implementation" ON)
+
+# configure a header file to pass some of the CMake settings
+# to the source code
+configure_file (
+ "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in"
+ "${PROJECT_BINARY_DIR}/TutorialConfig.h"
+ )
+
+# add the binary tree to the search path for include files
+# so that we will find TutorialConfig.h
+include_directories ("${PROJECT_BINARY_DIR}")
+
+# add the MathFunctions library?
+if (USE_MYMATH)
+ include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions")
+ add_subdirectory (MathFunctions)
+ set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)
+endif (USE_MYMATH)
+
+# add the executable
+add_executable (Tutorial tutorial.cxx)
+target_link_libraries (Tutorial ${EXTRA_LIBS})
+
+# add the install targets
+install (TARGETS Tutorial DESTINATION bin)
+install (FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h"
+ DESTINATION include)
+
+# enable testing
+enable_testing ()
+
+# does the application run
+add_test (TutorialRuns Tutorial 25)
+
+# does the usage message work?
+add_test (TutorialUsage Tutorial)
+set_tests_properties (TutorialUsage
+ PROPERTIES
+ PASS_REGULAR_EXPRESSION "Usage:.*number"
+ )
+
+#define a macro to simplify adding tests
+macro (do_test arg result)
+ add_test (TutorialComp${arg} Tutorial ${arg})
+ set_tests_properties (TutorialComp${arg}
+ PROPERTIES PASS_REGULAR_EXPRESSION ${result}
+ )
+endmacro (do_test)
+
+# do a bunch of result based tests
+do_test (4 "4 is 2")
+do_test (9 "9 is 3")
+do_test (5 "5 is 2.236")
+do_test (7 "7 is 2.645")
+do_test (25 "25 is 5")
+do_test (-25 "-25 is 0")
+do_test (0.0001 "0.0001 is 0.01")
+
+# build a CPack driven installer package
+include (InstallRequiredSystemLibraries)
+set (CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt")
+set (CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}")
+set (CPACK_PACKAGE_VERSION_MINOR "${Tutorial_VERSION_MINOR}")
+include (CPack)
diff --git a/Tests/Tutorial/Step6/License.txt b/Tests/Tutorial/Step6/License.txt
new file mode 100644
index 000000000..673d72453
--- /dev/null
+++ b/Tests/Tutorial/Step6/License.txt
@@ -0,0 +1,2 @@
+This is the open source License.txt file introduced in
+CMake/Tests/Tutorial/Step6...
diff --git a/Tests/Tutorial/Step6/MathFunctions/CMakeLists.txt b/Tests/Tutorial/Step6/MathFunctions/CMakeLists.txt
new file mode 100644
index 000000000..d606ac03e
--- /dev/null
+++ b/Tests/Tutorial/Step6/MathFunctions/CMakeLists.txt
@@ -0,0 +1,26 @@
+# 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}
+ ARGS ${CMAKE_CURRENT_BINARY_DIR}/Table.h
+ )
+
+set_source_files_properties (
+ mysqrt.cxx PROPERTIES
+ OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/Table.h
+ )
+
+# add the binary tree directory to the search path for include files
+include_directories( ${CMAKE_CURRENT_BINARY_DIR} )
+
+# add the main library
+add_library(MathFunctions mysqrt.cxx)
+
+install (TARGETS MathFunctions DESTINATION bin)
+install (FILES MathFunctions.h DESTINATION include)
diff --git a/Tests/Tutorial/Step6/MathFunctions/MakeTable.cxx b/Tests/Tutorial/Step6/MathFunctions/MakeTable.cxx
new file mode 100644
index 000000000..540254271
--- /dev/null
+++ b/Tests/Tutorial/Step6/MathFunctions/MakeTable.cxx
@@ -0,0 +1,35 @@
+// A simple program that builds a sqrt table
+#include <stdio.h>
+#include <math.h>
+
+int main (int argc, char *argv[])
+{
+ int i;
+ double result;
+
+ // make sure we have enough arguments
+ if (argc < 2)
+ {
+ return 1;
+ }
+
+ // open the output file
+ FILE *fout = fopen(argv[1],"w");
+ if (!fout)
+ {
+ return 1;
+ }
+
+ // create a source file with a table of square roots
+ fprintf(fout,"double sqrtTable[] = {\n");
+ for (i = 0; i < 10; ++i)
+ {
+ result = sqrt(static_cast<double>(i));
+ fprintf(fout,"%g,\n",result);
+ }
+
+ // close the table with a zero
+ fprintf(fout,"0};\n");
+ fclose(fout);
+ return 0;
+}
diff --git a/Tests/Tutorial/Step6/MathFunctions/MathFunctions.h b/Tests/Tutorial/Step6/MathFunctions/MathFunctions.h
new file mode 100644
index 000000000..cd36bccff
--- /dev/null
+++ b/Tests/Tutorial/Step6/MathFunctions/MathFunctions.h
@@ -0,0 +1 @@
+double mysqrt(double x);
diff --git a/Tests/Tutorial/Step6/MathFunctions/mysqrt.cxx b/Tests/Tutorial/Step6/MathFunctions/mysqrt.cxx
new file mode 100644
index 000000000..33659b740
--- /dev/null
+++ b/Tests/Tutorial/Step6/MathFunctions/mysqrt.cxx
@@ -0,0 +1,44 @@
+#include <stdio.h>
+#include "MathFunctions.h"
+#include "TutorialConfig.h"
+
+// include the generated table
+#include "Table.h"
+
+#include <math.h>
+
+// a hack square root calculation using simple operations
+double mysqrt(double x)
+{
+ if (x <= 0)
+ {
+ return 0;
+ }
+
+ double result;
+
+ // if we have both log and exp then use them
+ double delta;
+
+ // use the table to help find an initial value
+ result = x;
+ if (x >= 1 && x < 10)
+ {
+ result = sqrtTable[static_cast<int>(x)];
+ }
+
+ // do ten iterations
+ int i;
+ for (i = 0; i < 10; ++i)
+ {
+ if (result <= 0)
+ {
+ result = 0.1;
+ }
+ delta = x - (result*result);
+ result = result + 0.5*delta/result;
+ fprintf(stdout,"Computing sqrt of %g to be %g\n",x,result);
+ }
+
+ return result;
+}
diff --git a/Tests/Tutorial/Step6/TutorialConfig.h.in b/Tests/Tutorial/Step6/TutorialConfig.h.in
new file mode 100644
index 000000000..a0912656a
--- /dev/null
+++ b/Tests/Tutorial/Step6/TutorialConfig.h.in
@@ -0,0 +1,9 @@
+// the configured options and settings for Tutorial
+#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
+#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
+#cmakedefine USE_MYMATH
+
+// does the platform provide exp and log functions?
+#cmakedefine HAVE_LOG
+#cmakedefine HAVE_EXP
+
diff --git a/Tests/Tutorial/Step6/tutorial.cxx b/Tests/Tutorial/Step6/tutorial.cxx
new file mode 100644
index 000000000..82b416f11
--- /dev/null
+++ b/Tests/Tutorial/Step6/tutorial.cxx
@@ -0,0 +1,34 @@
+// A simple program that computes the square root of a number
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include "TutorialConfig.h"
+
+#ifdef USE_MYMATH
+#include "MathFunctions.h"
+#endif
+
+int main (int argc, char *argv[])
+{
+ if (argc < 2)
+ {
+ fprintf(stdout,"%s Version %d.%d\n",
+ argv[0],
+ Tutorial_VERSION_MAJOR,
+ Tutorial_VERSION_MINOR);
+ fprintf(stdout,"Usage: %s number\n",argv[0]);
+ return 1;
+ }
+
+ double inputValue = atof(argv[1]);
+
+#ifdef USE_MYMATH
+ double outputValue = mysqrt(inputValue);
+#else
+ double outputValue = sqrt(inputValue);
+#endif
+
+ fprintf(stdout,"The square root of %g is %g\n",
+ inputValue, outputValue);
+ return 0;
+}
diff --git a/Tests/Tutorial/Step7/CMakeLists.txt b/Tests/Tutorial/Step7/CMakeLists.txt
new file mode 100644
index 000000000..42f73f221
--- /dev/null
+++ b/Tests/Tutorial/Step7/CMakeLists.txt
@@ -0,0 +1,82 @@
+cmake_minimum_required (VERSION 2.6)
+project (Tutorial)
+
+# The version number.
+set (Tutorial_VERSION_MAJOR 1)
+set (Tutorial_VERSION_MINOR 0)
+
+# does this system provide the log and exp functions?
+include (${CMAKE_ROOT}/Modules/CheckFunctionExists.cmake)
+check_function_exists (log HAVE_LOG)
+check_function_exists (exp HAVE_EXP)
+
+# should we use our own math functions
+option(USE_MYMATH "Use tutorial provided math implementation" ON)
+
+# configure a header file to pass some of the CMake settings
+# to the source code
+configure_file (
+ "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in"
+ "${PROJECT_BINARY_DIR}/TutorialConfig.h"
+ )
+
+# add the binary tree to the search path for include files
+# so that we will find TutorialConfig.h
+include_directories ("${PROJECT_BINARY_DIR}")
+
+# add the MathFunctions library?
+if (USE_MYMATH)
+ include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions")
+ add_subdirectory (MathFunctions)
+ set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)
+endif (USE_MYMATH)
+
+# add the executable
+add_executable (Tutorial tutorial.cxx)
+target_link_libraries (Tutorial ${EXTRA_LIBS})
+
+# add the install targets
+install (TARGETS Tutorial DESTINATION bin)
+install (FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h"
+ DESTINATION include)
+
+# enable testing
+enable_testing ()
+
+# does the application run
+add_test (TutorialRuns Tutorial 25)
+
+# does the usage message work?
+add_test (TutorialUsage Tutorial)
+set_tests_properties (TutorialUsage
+ PROPERTIES
+ PASS_REGULAR_EXPRESSION "Usage:.*number"
+ )
+
+#define a macro to simplify adding tests
+macro (do_test arg result)
+ add_test (TutorialComp${arg} Tutorial ${arg})
+ set_tests_properties (TutorialComp${arg}
+ PROPERTIES PASS_REGULAR_EXPRESSION ${result}
+ )
+endmacro (do_test)
+
+# do a bunch of result based tests
+do_test (4 "4 is 2")
+do_test (9 "9 is 3")
+do_test (5 "5 is 2.236")
+do_test (7 "7 is 2.645")
+do_test (25 "25 is 5")
+do_test (-25 "-25 is 0")
+do_test (0.0001 "0.0001 is 0.01")
+
+# build a CPack driven installer package
+include (InstallRequiredSystemLibraries)
+set (CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt")
+set (CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}")
+set (CPACK_PACKAGE_VERSION_MINOR "${Tutorial_VERSION_MINOR}")
+set (CPACK_PACKAGE_CONTACT "foo@bar.org")
+include (CPack)
+
+# enable dashboard scripting
+include (CTest)
diff --git a/Tests/Tutorial/Step7/CTestConfig.cmake b/Tests/Tutorial/Step7/CTestConfig.cmake
new file mode 100644
index 000000000..d8f5c4491
--- /dev/null
+++ b/Tests/Tutorial/Step7/CTestConfig.cmake
@@ -0,0 +1 @@
+set (CTEST_PROJECT_NAME "Tutorial")
diff --git a/Tests/Tutorial/Step7/License.txt b/Tests/Tutorial/Step7/License.txt
new file mode 100644
index 000000000..673d72453
--- /dev/null
+++ b/Tests/Tutorial/Step7/License.txt
@@ -0,0 +1,2 @@
+This is the open source License.txt file introduced in
+CMake/Tests/Tutorial/Step6...
diff --git a/Tests/Tutorial/Step7/MathFunctions/CMakeLists.txt b/Tests/Tutorial/Step7/MathFunctions/CMakeLists.txt
new file mode 100644
index 000000000..d606ac03e
--- /dev/null
+++ b/Tests/Tutorial/Step7/MathFunctions/CMakeLists.txt
@@ -0,0 +1,26 @@
+# 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}
+ ARGS ${CMAKE_CURRENT_BINARY_DIR}/Table.h
+ )
+
+set_source_files_properties (
+ mysqrt.cxx PROPERTIES
+ OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/Table.h
+ )
+
+# add the binary tree directory to the search path for include files
+include_directories( ${CMAKE_CURRENT_BINARY_DIR} )
+
+# add the main library
+add_library(MathFunctions mysqrt.cxx)
+
+install (TARGETS MathFunctions DESTINATION bin)
+install (FILES MathFunctions.h DESTINATION include)
diff --git a/Tests/Tutorial/Step7/MathFunctions/MakeTable.cxx b/Tests/Tutorial/Step7/MathFunctions/MakeTable.cxx
new file mode 100644
index 000000000..540254271
--- /dev/null
+++ b/Tests/Tutorial/Step7/MathFunctions/MakeTable.cxx
@@ -0,0 +1,35 @@
+// A simple program that builds a sqrt table
+#include <stdio.h>
+#include <math.h>
+
+int main (int argc, char *argv[])
+{
+ int i;
+ double result;
+
+ // make sure we have enough arguments
+ if (argc < 2)
+ {
+ return 1;
+ }
+
+ // open the output file
+ FILE *fout = fopen(argv[1],"w");
+ if (!fout)
+ {
+ return 1;
+ }
+
+ // create a source file with a table of square roots
+ fprintf(fout,"double sqrtTable[] = {\n");
+ for (i = 0; i < 10; ++i)
+ {
+ result = sqrt(static_cast<double>(i));
+ fprintf(fout,"%g,\n",result);
+ }
+
+ // close the table with a zero
+ fprintf(fout,"0};\n");
+ fclose(fout);
+ return 0;
+}
diff --git a/Tests/Tutorial/Step7/MathFunctions/MathFunctions.h b/Tests/Tutorial/Step7/MathFunctions/MathFunctions.h
new file mode 100644
index 000000000..cd36bccff
--- /dev/null
+++ b/Tests/Tutorial/Step7/MathFunctions/MathFunctions.h
@@ -0,0 +1 @@
+double mysqrt(double x);
diff --git a/Tests/Tutorial/Step7/MathFunctions/mysqrt.cxx b/Tests/Tutorial/Step7/MathFunctions/mysqrt.cxx
new file mode 100644
index 000000000..33659b740
--- /dev/null
+++ b/Tests/Tutorial/Step7/MathFunctions/mysqrt.cxx
@@ -0,0 +1,44 @@
+#include <stdio.h>
+#include "MathFunctions.h"
+#include "TutorialConfig.h"
+
+// include the generated table
+#include "Table.h"
+
+#include <math.h>
+
+// a hack square root calculation using simple operations
+double mysqrt(double x)
+{
+ if (x <= 0)
+ {
+ return 0;
+ }
+
+ double result;
+
+ // if we have both log and exp then use them
+ double delta;
+
+ // use the table to help find an initial value
+ result = x;
+ if (x >= 1 && x < 10)
+ {
+ result = sqrtTable[static_cast<int>(x)];
+ }
+
+ // do ten iterations
+ int i;
+ for (i = 0; i < 10; ++i)
+ {
+ if (result <= 0)
+ {
+ result = 0.1;
+ }
+ delta = x - (result*result);
+ result = result + 0.5*delta/result;
+ fprintf(stdout,"Computing sqrt of %g to be %g\n",x,result);
+ }
+
+ return result;
+}
diff --git a/Tests/Tutorial/Step7/TutorialConfig.h.in b/Tests/Tutorial/Step7/TutorialConfig.h.in
new file mode 100644
index 000000000..a0912656a
--- /dev/null
+++ b/Tests/Tutorial/Step7/TutorialConfig.h.in
@@ -0,0 +1,9 @@
+// the configured options and settings for Tutorial
+#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
+#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
+#cmakedefine USE_MYMATH
+
+// does the platform provide exp and log functions?
+#cmakedefine HAVE_LOG
+#cmakedefine HAVE_EXP
+
diff --git a/Tests/Tutorial/Step7/build1.cmake b/Tests/Tutorial/Step7/build1.cmake
new file mode 100644
index 000000000..039d5569b
--- /dev/null
+++ b/Tests/Tutorial/Step7/build1.cmake
@@ -0,0 +1,5 @@
+SET(CTEST_SOURCE_DIRECTORY "$ENV{HOME}/Dashboards/My Tests/CMake/Tests/Tutorial/Step7")
+SET(CTEST_BINARY_DIRECTORY "${CTEST_SOURCE_DIRECTORY}-build1")
+
+SET(CTEST_CMAKE_COMMAND "cmake")
+SET(CTEST_COMMAND "ctest -D Experimental")
diff --git a/Tests/Tutorial/Step7/build2.cmake b/Tests/Tutorial/Step7/build2.cmake
new file mode 100644
index 000000000..5112355b2
--- /dev/null
+++ b/Tests/Tutorial/Step7/build2.cmake
@@ -0,0 +1,9 @@
+SET(CTEST_SOURCE_DIRECTORY "$ENV{HOME}/Dashboards/My Tests/CMake/Tests/Tutorial/Step7")
+SET(CTEST_BINARY_DIRECTORY "${CTEST_SOURCE_DIRECTORY}-build2")
+SET(CTEST_CMAKE_GENERATOR "Visual Studio 8 2005")
+
+CTEST_START("Experimental")
+CTEST_CONFIGURE(BUILD "${CTEST_BINARY_DIRECTORY}")
+CTEST_BUILD(BUILD "${CTEST_BINARY_DIRECTORY}")
+CTEST_TEST(BUILD "${CTEST_BINARY_DIRECTORY}")
+CTEST_SUBMIT()
diff --git a/Tests/Tutorial/Step7/tutorial.cxx b/Tests/Tutorial/Step7/tutorial.cxx
new file mode 100644
index 000000000..82b416f11
--- /dev/null
+++ b/Tests/Tutorial/Step7/tutorial.cxx
@@ -0,0 +1,34 @@
+// A simple program that computes the square root of a number
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include "TutorialConfig.h"
+
+#ifdef USE_MYMATH
+#include "MathFunctions.h"
+#endif
+
+int main (int argc, char *argv[])
+{
+ if (argc < 2)
+ {
+ fprintf(stdout,"%s Version %d.%d\n",
+ argv[0],
+ Tutorial_VERSION_MAJOR,
+ Tutorial_VERSION_MINOR);
+ fprintf(stdout,"Usage: %s number\n",argv[0]);
+ return 1;
+ }
+
+ double inputValue = atof(argv[1]);
+
+#ifdef USE_MYMATH
+ double outputValue = mysqrt(inputValue);
+#else
+ double outputValue = sqrt(inputValue);
+#endif
+
+ fprintf(stdout,"The square root of %g is %g\n",
+ inputValue, outputValue);
+ return 0;
+}
diff --git a/Tests/Unset/CMakeLists.txt b/Tests/Unset/CMakeLists.txt
new file mode 100644
index 000000000..bacb6d21f
--- /dev/null
+++ b/Tests/Unset/CMakeLists.txt
@@ -0,0 +1,55 @@
+cmake_minimum_required(VERSION 2.6)
+project(Unset C)
+
+# Local variable
+set(x 42)
+if(NOT x EQUAL 42)
+ message(FATAL_ERROR "x!=42")
+endif(NOT x EQUAL 42)
+
+if(NOT DEFINED x)
+ message(FATAL_ERROR "x should be defined!")
+endif(NOT DEFINED x)
+
+unset(x)
+if(DEFINED x)
+ message(FATAL_ERROR "x should be undefined now!")
+endif(DEFINED x)
+
+# Local variable test unset via set()
+set(x 43)
+if(NOT x EQUAL 43)
+ message(FATAL_ERROR "x!=43")
+endif(NOT x EQUAL 43)
+set(x)
+if(DEFINED x)
+ message(FATAL_ERROR "x should be undefined now!")
+endif(DEFINED x)
+
+# Cache variable
+set(BAR "test" CACHE STRING "documentation")
+if(NOT DEFINED BAR)
+ message(FATAL_ERROR "BAR not defined")
+endif(NOT DEFINED BAR)
+
+# Test interaction of cache entries with variables.
+set(BAR "test-var")
+if(NOT "$CACHE{BAR}" STREQUAL "test")
+ message(FATAL_ERROR "\$CACHE{BAR} changed by variable BAR")
+endif(NOT "$CACHE{BAR}" STREQUAL "test")
+if(NOT "${BAR}" STREQUAL "test-var")
+ message(FATAL_ERROR "\${BAR} not separate from \$CACHE{BAR}")
+endif(NOT "${BAR}" STREQUAL "test-var")
+unset(BAR)
+if(NOT "${BAR}" STREQUAL "test")
+ message(FATAL_ERROR "\${BAR} does not fall through to \$CACHE{BAR}")
+endif(NOT "${BAR}" STREQUAL "test")
+
+# Test unsetting of CACHE entry.
+unset(BAR CACHE)
+if(DEFINED BAR)
+ message(FATAL_ERROR "BAR still defined")
+endif(DEFINED BAR)
+
+
+add_executable(Unset unset.c)
diff --git a/Tests/Unset/unset.c b/Tests/Unset/unset.c
new file mode 100644
index 000000000..f8b643afb
--- /dev/null
+++ b/Tests/Unset/unset.c
@@ -0,0 +1,4 @@
+int main()
+{
+ return 0;
+}
diff --git a/Tests/VSExternalInclude/CMakeLists.txt b/Tests/VSExternalInclude/CMakeLists.txt
new file mode 100644
index 000000000..a2fd61973
--- /dev/null
+++ b/Tests/VSExternalInclude/CMakeLists.txt
@@ -0,0 +1,60 @@
+cmake_minimum_required (VERSION 2.6)
+PROJECT(VSExternalInclude)
+
+IF(${CMAKE_GENERATOR} MATCHES "Visual Studio 6")
+ SET(PROJECT_EXT dsp)
+ELSE(${CMAKE_GENERATOR} MATCHES "Visual Studio 6")
+ SET(PROJECT_EXT vcproj)
+ENDIF(${CMAKE_GENERATOR} MATCHES "Visual Studio 6")
+IF(${CMAKE_GENERATOR} MATCHES "Visual Studio 1[01]")
+ SET(PROJECT_EXT vcxproj)
+ENDIF()
+
+# make sure directories exists
+SET(LIB1_BINARY_DIR ${VSExternalInclude_BINARY_DIR}/Lib1)
+MAKE_DIRECTORY("${LIB1_BINARY_DIR}")
+
+SET(LIB2_BINARY_DIR ${VSExternalInclude_BINARY_DIR}/Lib2)
+MAKE_DIRECTORY("${LIB2_BINARY_DIR}")
+
+# generate lib1
+EXEC_PROGRAM("${CMAKE_COMMAND}" "${LIB1_BINARY_DIR}" ARGS -G\"${CMAKE_GENERATOR}\"
+ \"${VSExternalInclude_SOURCE_DIR}/Lib1\" OUTPUT_VARIABLE OUT)
+MESSAGE("CMAKE Ran with the following output:\n\"${OUT}\"")
+
+# generate lib2
+EXEC_PROGRAM("${CMAKE_COMMAND}" "${LIB2_BINARY_DIR}" ARGS -G\"${CMAKE_GENERATOR}\"
+ \"${VSExternalInclude_SOURCE_DIR}/Lib2\" OUTPUT_VARIABLE OUT)
+MESSAGE("CMAKE Ran with the following output:\n\"${OUT}\"")
+
+
+INCLUDE_EXTERNAL_MSPROJECT(lib1 ${VSExternalInclude_BINARY_DIR}/Lib1/LIB1.${PROJECT_EXT})
+# lib2 depends on lib1
+INCLUDE_EXTERNAL_MSPROJECT(lib2 ${VSExternalInclude_BINARY_DIR}/Lib2/LIB2.${PROJECT_EXT} lib1)
+
+INCLUDE_DIRECTORIES(${VSExternalInclude_SOURCE_DIR}/Lib2 ${VSExternalInclude_SOURCE_DIR}/Lib1)
+
+SET(SOURCES main.cpp)
+
+ADD_EXECUTABLE(VSExternalInclude ${SOURCES})
+
+# target depends on lib2
+ADD_DEPENDENCIES(VSExternalInclude lib2)
+# VS 10 vcxproj files have depends in them
+# Since lib1 and lib2 do not depend on each other
+# then the vcxproj files do not depend on each other
+# 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(MSVC10 OR MSVC11)
+ ADD_DEPENDENCIES(VSExternalInclude lib1)
+ENDIF()
+
+# Interaction testing between the FOLDER target property and
+# INCLUDE_EXTERNAL_MSPROJECT targets:
+set_target_properties(VSExternalInclude PROPERTIES FOLDER folder1/folder2)
+set_target_properties(lib1 PROPERTIES FOLDER folder1/folder2)
+set_target_properties(lib2 PROPERTIES FOLDER folder1/folder2)
+add_custom_target(EmptyCustomTarget)
+set_target_properties(EmptyCustomTarget PROPERTIES FOLDER folder1/folder2)
+set_property(GLOBAL PROPERTY USE_FOLDERS ON)
diff --git a/Tests/VSExternalInclude/Lib1/CMakeLists.txt b/Tests/VSExternalInclude/Lib1/CMakeLists.txt
new file mode 100644
index 000000000..72ffcedc1
--- /dev/null
+++ b/Tests/VSExternalInclude/Lib1/CMakeLists.txt
@@ -0,0 +1,5 @@
+PROJECT(LIB1)
+
+SET(SOURCES lib1.cpp)
+
+ADD_LIBRARY(lib1 ${SOURCES})
diff --git a/Tests/VSExternalInclude/Lib1/lib1.cpp b/Tests/VSExternalInclude/Lib1/lib1.cpp
new file mode 100644
index 000000000..690eb740f
--- /dev/null
+++ b/Tests/VSExternalInclude/Lib1/lib1.cpp
@@ -0,0 +1,7 @@
+
+#include "lib1.h"
+
+int add1(int num)
+{
+ return num + 1;
+}
diff --git a/Tests/VSExternalInclude/Lib1/lib1.h b/Tests/VSExternalInclude/Lib1/lib1.h
new file mode 100644
index 000000000..543e71e02
--- /dev/null
+++ b/Tests/VSExternalInclude/Lib1/lib1.h
@@ -0,0 +1,8 @@
+
+#ifndef LIB1_HPP
+#define LIB1_HPP
+
+int add1(int num);
+
+
+#endif
diff --git a/Tests/VSExternalInclude/Lib2/CMakeLists.txt b/Tests/VSExternalInclude/Lib2/CMakeLists.txt
new file mode 100644
index 000000000..31e40e4e1
--- /dev/null
+++ b/Tests/VSExternalInclude/Lib2/CMakeLists.txt
@@ -0,0 +1,7 @@
+PROJECT(VSEXTERNAL_LIB2)
+
+INCLUDE_DIRECTORIES(${VSEXTERNAL_LIB2_SOURCE_DIR}/../Lib1)
+
+SET(SOURCES lib2.cpp)
+
+ADD_LIBRARY(lib2 ${SOURCES})
diff --git a/Tests/VSExternalInclude/Lib2/lib2.cpp b/Tests/VSExternalInclude/Lib2/lib2.cpp
new file mode 100644
index 000000000..adc2d29af
--- /dev/null
+++ b/Tests/VSExternalInclude/Lib2/lib2.cpp
@@ -0,0 +1,9 @@
+
+#include "lib2.h"
+#include "lib1.h"
+
+int add1_and_mult2(int num)
+{
+ int tmp = add1(num);
+ return tmp * 2;
+}
diff --git a/Tests/VSExternalInclude/Lib2/lib2.h b/Tests/VSExternalInclude/Lib2/lib2.h
new file mode 100644
index 000000000..48bda468d
--- /dev/null
+++ b/Tests/VSExternalInclude/Lib2/lib2.h
@@ -0,0 +1,10 @@
+
+
+#ifndef LIB2_HPP
+#define LIB2_HPP
+
+#include "lib1.h"
+
+int add1_and_mult2(int num);
+
+#endif
diff --git a/Tests/VSExternalInclude/main.cpp b/Tests/VSExternalInclude/main.cpp
new file mode 100644
index 000000000..ea1047cb6
--- /dev/null
+++ b/Tests/VSExternalInclude/main.cpp
@@ -0,0 +1,9 @@
+
+#include "lib2.h"
+
+int main(int argc, char** argv)
+{
+ int num = add1_and_mult2(4);
+
+ return 0;
+}
diff --git a/Tests/VSGNUFortran/CMakeLists.txt b/Tests/VSGNUFortran/CMakeLists.txt
new file mode 100644
index 000000000..229c3156c
--- /dev/null
+++ b/Tests/VSGNUFortran/CMakeLists.txt
@@ -0,0 +1,26 @@
+cmake_minimum_required(VERSION 2.8)
+project(VSGNUFortran)
+
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin")
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
+
+# force the executable to be put out of Debug/Release dir
+# because gmake build of fortran will not be in a config
+# directory, and for easier testing we want the exe and .dll
+# to be in the same directory.
+if(CMAKE_CONFIGURATION_TYPES)
+ foreach(config ${CMAKE_CONFIGURATION_TYPES})
+ string(TOUPPER "${config}" config)
+ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${config}
+ ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
+ endforeach()
+endif()
+
+add_subdirectory(subdir)
+include_directories(${VSGNUFortran_BINARY_DIR}/subdir/fortran)
+add_subdirectory(c_code)
+# use a cmake script to run the executable so that PATH
+# can be set with the MinGW/bin in it, and the fortran
+# runtime libraries can be found.
+configure_file(runtest.cmake.in runtest.cmake @ONLY)
diff --git a/Tests/VSGNUFortran/c_code/CMakeLists.txt b/Tests/VSGNUFortran/c_code/CMakeLists.txt
new file mode 100644
index 000000000..27d22fd35
--- /dev/null
+++ b/Tests/VSGNUFortran/c_code/CMakeLists.txt
@@ -0,0 +1,2 @@
+add_executable(c_using_fortran main.c)
+target_link_libraries(c_using_fortran hello)
diff --git a/Tests/VSGNUFortran/c_code/main.c b/Tests/VSGNUFortran/c_code/main.c
new file mode 100644
index 000000000..9157cc5f3
--- /dev/null
+++ b/Tests/VSGNUFortran/c_code/main.c
@@ -0,0 +1,7 @@
+#include <HelloWorldFCMangle.h> /* created by FortranCInterface */
+extern void FC_hello(void);
+int main()
+{
+ FC_hello();
+ return 0;
+}
diff --git a/Tests/VSGNUFortran/runtest.cmake.in b/Tests/VSGNUFortran/runtest.cmake.in
new file mode 100644
index 000000000..987207bc4
--- /dev/null
+++ b/Tests/VSGNUFortran/runtest.cmake.in
@@ -0,0 +1,23 @@
+get_filename_component(MINGW_PATH "@MINGW_GFORTRAN@" PATH)
+if(NOT EXISTS "${MINGW_PATH}")
+ set(test_exe
+ "@VSGNUFortran_BINARY_DIR@/bin/c_using_fortran@CMAKE_EXECUTABLE_SUFFIX@")
+ message("run: ${test_exe}")
+ execute_process(COMMAND "${test_exe}"
+ RESULT_VARIABLE res)
+ if(NOT "${res}" EQUAL 0)
+ message(FATAL_ERROR "${test_exe} returned a non 0 value")
+ endif()
+ return()
+endif()
+file(TO_NATIVE_PATH "${MINGW_PATH}" MINGW_PATH)
+string(REPLACE "\\" "\\\\" MINGW_PATH "${MINGW_PATH}")
+message("${MINGW_PATH}")
+set(test_exe "@VSGNUFortran_BINARY_DIR@/bin/c_using_fortran.exe")
+set(ENV{PATH} "${MINGW_PATH}";$ENV{PATH})
+message("run ${test_exe}")
+execute_process(COMMAND "${test_exe}"
+ RESULT_VARIABLE res)
+if(NOT "${res}" EQUAL 0)
+ message(FATAL_ERROR "${test_exe} returned a non 0 value")
+endif()
diff --git a/Tests/VSGNUFortran/subdir/CMakeLists.txt b/Tests/VSGNUFortran/subdir/CMakeLists.txt
new file mode 100644
index 000000000..0b9919953
--- /dev/null
+++ b/Tests/VSGNUFortran/subdir/CMakeLists.txt
@@ -0,0 +1,16 @@
+include(CMakeAddFortranSubdirectory)
+# add the fortran subdirectory as a fortran project
+# the subdir is fortran, the project is FortranHello
+cmake_add_fortran_subdirectory(fortran
+ PROJECT FortranHello # project name in toplevel CMakeLists.txt
+ ARCHIVE_DIR ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}
+ RUNTIME_DIR bin # ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
+ LIBRARIES hello world # target libraries created
+ CMAKE_COMMAND_LINE
+ -DCMAKE_RUNTIME_OUTPUT_DIRECTORY=${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
+ -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY=${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}
+ -DCMAKE_LIBRARY_OUTPUT_DIRECTORY=${CMAKE_LIBRARY_OUTPUT_DIRECTORY}
+ LINK_LIBRARIES # link interface libraries
+ LINK_LIBS hello world # hello needs world to link
+ NO_EXTERNAL_INSTALL
+ )
diff --git a/Tests/VSGNUFortran/subdir/fortran/CMakeLists.txt b/Tests/VSGNUFortran/subdir/fortran/CMakeLists.txt
new file mode 100644
index 000000000..3ee1855c3
--- /dev/null
+++ b/Tests/VSGNUFortran/subdir/fortran/CMakeLists.txt
@@ -0,0 +1,46 @@
+cmake_minimum_required(VERSION 2.8)
+project(FortranHello Fortran C)
+
+# add a function to test for -lsunquad on sunpro sun systems.
+function(test_sunquad result)
+ set( TEST_DIR "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/sunq")
+ file(WRITE "${TEST_DIR}/testsunq.f" "
+ PROGRAM TEST
+ END
+ ")
+ file(WRITE ${TEST_DIR}/CMakeLists.txt "
+project(sunq Fortran)
+add_library(sunq SHARED testsunq.f)
+target_link_libraries(sunq sunquad)
+")
+ message(STATUS "looking for -lsunquad")
+ try_compile(RESULT "${TEST_DIR}" "${TEST_DIR}" sunq OUTPUT_VARIABLE OUT)
+ if("${RESULT}")
+ message(STATUS "-lsunquad found")
+ else()
+ message(STATUS "-lsunquad not found")
+ endif()
+ message(STATUS
+ "looking for sunquad:\nRESULT=[${RESULT}]\nOUTPUT=[\n${OUT}\n]")
+ set(${result} "${RESULT}" PARENT_SCOPE)
+endfunction()
+
+# check for the fortran c interface mangling
+include(FortranCInterface)
+FortranCInterface_HEADER(HelloWorldFCMangle.h
+ MACRO_NAMESPACE "FC_"
+ SYMBOL_NAMESPACE "FC_"
+ SYMBOLS hello world)
+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)
+ if(CMAKE_Fortran_PLATFORM_ID MATCHES SunOS)
+ target_link_libraries(hello sunmath m)
+ test_sunquad(CMAKE_HAS_SUNQUAD)
+ if(CMAKE_HAS_SUNQUAD)
+ target_link_libraries(hello sunquad)
+ endif()
+ endif()
+endif()
diff --git a/Tests/VSGNUFortran/subdir/fortran/hello.f b/Tests/VSGNUFortran/subdir/fortran/hello.f
new file mode 100644
index 000000000..e52119add
--- /dev/null
+++ b/Tests/VSGNUFortran/subdir/fortran/hello.f
@@ -0,0 +1,7 @@
+!DEC$ ATTRIBUTES DLLEXPORT :: HELLO
+ SUBROUTINE HELLO
+
+ PRINT *, 'Hello'
+ CALL WORLD
+
+ END
diff --git a/Tests/VSGNUFortran/subdir/fortran/world.f b/Tests/VSGNUFortran/subdir/fortran/world.f
new file mode 100644
index 000000000..0598eeea6
--- /dev/null
+++ b/Tests/VSGNUFortran/subdir/fortran/world.f
@@ -0,0 +1,6 @@
+!DEC$ ATTRIBUTES DLLEXPORT :: WORLD
+ SUBROUTINE WORLD
+
+ PRINT *, 'World!'
+
+ END
diff --git a/Tests/VSMidl/CMakeLists.txt b/Tests/VSMidl/CMakeLists.txt
new file mode 100644
index 000000000..432506c3b
--- /dev/null
+++ b/Tests/VSMidl/CMakeLists.txt
@@ -0,0 +1,81 @@
+# This CMakeLists.txt file exists solely to drive the one found in the "src"
+# subdir as an ExternalProject build. The project in "src" cannot build when
+# there is a space in the directory name, so we copy that directory to a place
+# guaranteed not to have a space in the name, build it there, and then copy the
+# resulting output directory back up here into this CMake test's build tree.
+#
+if(NOT DEFINED CMAKE_BUILDNAME)
+ string(REGEX REPLACE "^.*/([^/]+)/[^/]+/([^/]+)$" "\\1" CMAKE_BUILDNAME "${CMAKE_CURRENT_BINARY_DIR}")
+ string(REGEX REPLACE "^.*/([^/]+)/[^/]+/([^/]+)$" "\\2" THIS_TESTNAME "${CMAKE_CURRENT_BINARY_DIR}")
+ string(REPLACE " " "_" CMAKE_BUILDNAME "${CMAKE_BUILDNAME}")
+endif()
+message(STATUS "CMAKE_BUILDNAME='${CMAKE_BUILDNAME}'")
+message(STATUS "THIS_TESTNAME='${THIS_TESTNAME}'")
+
+cmake_minimum_required(VERSION 2.8)
+project(${THIS_TESTNAME})
+
+include(ExternalProject)
+
+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}")
+ endif()
+
+ # But just use root of SystemDrive if HOME contains any spaces:
+ # (Default on XP and earlier...)
+ if(HOME MATCHES " " AND WIN32)
+ string(REPLACE "\\" "/" HOME "$ENV{SystemDrive}")
+ endif()
+ if(HOME MATCHES " ")
+ set(HOME "")
+ endif()
+endif()
+message(STATUS "HOME='${HOME}'")
+
+if(NOT DEFINED url)
+ set(url "${CMAKE_CURRENT_SOURCE_DIR}/src")
+endif()
+message(STATUS "url='${url}'")
+
+set(base_dir "${HOME}/.cmake/Dashboards/${CMAKE_BUILDNAME}/${THIS_TESTNAME}")
+set(binary_dir "${base_dir}/build")
+set(source_dir "${base_dir}/src")
+
+# Source dir for this project exists in the CMake source tree, but we cannot
+# use it in-place since there might be a space in its directory name.
+# Source dir is therefore copied under a '.cmake/Dashboards'
+# dir in your HOME directory to give it a name with no spaces.
+#
+ExternalProject_Add(clean-${PROJECT_NAME}
+ DOWNLOAD_COMMAND ""
+ CONFIGURE_COMMAND ${CMAKE_COMMAND} -E remove_directory "${source_dir}"
+ BUILD_COMMAND ${CMAKE_COMMAND} -E remove_directory "${binary_dir}"
+ INSTALL_COMMAND ""
+ )
+
+ExternalProject_Add(download-${PROJECT_NAME}
+ URL "${url}"
+ SOURCE_DIR "${source_dir}"
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND ""
+ INSTALL_COMMAND ""
+ DEPENDS clean-${PROJECT_NAME}
+ )
+
+ExternalProject_Add(build-${PROJECT_NAME}
+ DOWNLOAD_COMMAND ""
+ SOURCE_DIR "${source_dir}"
+ BINARY_DIR "${binary_dir}"
+ INSTALL_COMMAND ${CMAKE_COMMAND} -E copy_directory
+ "${binary_dir}/${CMAKE_CFG_INTDIR}"
+ "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}"
+ DEPENDS download-${PROJECT_NAME}
+ )
diff --git a/Tests/VSMidl/src/CMakeLists.txt b/Tests/VSMidl/src/CMakeLists.txt
new file mode 100644
index 000000000..86c04ed98
--- /dev/null
+++ b/Tests/VSMidl/src/CMakeLists.txt
@@ -0,0 +1,12 @@
+cmake_minimum_required(VERSION 2.8)
+project(VSMidl)
+
+if(MSVC_VERSION GREATER 1200)
+ include_directories("${CMAKE_CURRENT_BINARY_DIR}/\$(IntDir)")
+else()
+ # midl generated headers end up directly in CMAKE_CURRENT_BINARY_DIR with
+ # VS6 builds.
+ include_directories("${CMAKE_CURRENT_BINARY_DIR}")
+endif()
+
+add_executable(VSMidl main.cpp test.idl)
diff --git a/Tests/VSMidl/src/main.cpp b/Tests/VSMidl/src/main.cpp
new file mode 100644
index 000000000..6b78fcc7f
--- /dev/null
+++ b/Tests/VSMidl/src/main.cpp
@@ -0,0 +1,17 @@
+#include <stdio.h>
+#include <test.h>
+#include <test_i.c>
+
+int main(int argc, char** argv)
+{
+ IID libid = LIBID_CMakeMidlTestLib;
+ CLSID clsid = CLSID_CMakeMidlTest;
+ IID iid = IID_ICMakeMidlTest;
+
+ printf("Running '%s'\n", argv[0]);
+ printf(" libid starts with '0x%08lx'\n", (long) libid.Data1);
+ printf(" clsid starts with '0x%08lx'\n", (long) clsid.Data1);
+ printf(" iid starts with '0x%08lx'\n", (long) iid.Data1);
+
+ return 0;
+}
diff --git a/Tests/VSMidl/src/test.idl b/Tests/VSMidl/src/test.idl
new file mode 100644
index 000000000..fd755c789
--- /dev/null
+++ b/Tests/VSMidl/src/test.idl
@@ -0,0 +1,30 @@
+import "oaidl.idl";
+import "ocidl.idl";
+
+[
+ object,
+ uuid(258CCEBE-8EE4-4A48-B78C-AC53BCD59E28),
+ dual,
+ nonextensible,
+ helpstring("ICMakeTest Interface"),
+ pointer_default(unique)
+]
+interface ICMakeMidlTest : IUnknown
+{
+ [id(1), helpstring("method Method")] HRESULT Method();
+}
+
+[
+ uuid(0537BA59-7EEC-48F8-BD4B-369BC7D9807E),
+]
+library CMakeMidlTestLib
+{
+ [
+ uuid(D2A90807-019A-46E5-BF47-FF4FA4352D2A),
+ helpstring("CMakeMidlTest Class")
+ ]
+ coclass CMakeMidlTest
+ {
+ [default] interface ICMakeMidlTest;
+ };
+}
diff --git a/Tests/VSResource/CMakeLists.txt b/Tests/VSResource/CMakeLists.txt
new file mode 100644
index 000000000..c5cb336ae
--- /dev/null
+++ b/Tests/VSResource/CMakeLists.txt
@@ -0,0 +1,40 @@
+cmake_minimum_required(VERSION 2.8.4)
+project(VSResource)
+
+string(REPLACE "/INCREMENTAL:YES" ""
+ CMAKE_EXE_LINKER_FLAGS_DEBUG
+ "${CMAKE_EXE_LINKER_FLAGS_DEBUG}")
+
+message(STATUS "CMAKE_RC_COMPILER='${CMAKE_RC_COMPILER}'")
+
+# Because of the following avoidance techniques required for windres and VS6,
+# we recommend using a configured header file, and defining preprocessor
+# symbols via #define code and including that header in the rc file. Using
+# add_definitions is fine for simple definitions (with no spaces and no
+# quoting), but requires avoidance or work-arounds beyond that...
+
+if(CMAKE_RC_COMPILER MATCHES windres)
+ # windres rc compiler does not properly define quoted /D values as strings
+ message(STATUS "CMAKE_RC_COMPILER MATCHES windres")
+ add_definitions(/DCMAKE_RCDEFINE=test.txt)
+ add_definitions(/DCMAKE_RCDEFINE_NO_QUOTED_STRINGS)
+elseif(MSVC60)
+ # VS6 rc compiler does not deal well with spaces in a "/D" value, but it can
+ # handle the quoting
+ message(STATUS "MSVC60")
+ add_definitions(/DCMAKE_RCDEFINE="test.txt")
+else()
+ # expected case -- rc compiler is "capable enough"
+ message(STATUS
+ "rc compiler handles quoted strings with spaces in values via /D")
+ 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()
+
+add_executable(VSResource main.cpp test.rc)
+
+set_property(TARGET VSResource
+ PROPERTY VS_GLOBAL_CMakeTestVsGlobalVariable "test val")
diff --git a/Tests/VSResource/main.cpp b/Tests/VSResource/main.cpp
new file mode 100644
index 000000000..7ee0c74fa
--- /dev/null
+++ b/Tests/VSResource/main.cpp
@@ -0,0 +1,80 @@
+#include <windows.h>
+#include <stdio.h>
+
+struct x
+{
+ const char *txt;
+};
+
+int main(int argc, char** argv)
+{
+ int ret = 1;
+
+ fprintf(stdout, "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)\n");
+
+#ifdef CMAKE_RCDEFINE
+ fprintf(stdout, "CMAKE_RCDEFINE defined\n");
+#endif
+
+#ifdef CMAKE_RCDEFINE_NO_QUOTED_STRINGS
+ // Expect CMAKE_RCDEFINE to preprocess to exactly test.txt
+ x test;
+ test.txt = "*exactly* test.txt";
+ fprintf(stdout, "CMAKE_RCDEFINE_NO_QUOTED_STRINGS defined\n");
+ fprintf(stdout, "CMAKE_RCDEFINE is %s, and is *not* a string constant\n",
+ CMAKE_RCDEFINE);
+#else
+ // Expect CMAKE_RCDEFINE to be a string:
+ fprintf(stdout, "CMAKE_RCDEFINE='%s', and is a string constant\n",
+ CMAKE_RCDEFINE);
+#endif
+
+ HRSRC hello = ::FindResource(NULL, MAKEINTRESOURCE(1025), "TEXTFILE");
+ if(hello)
+ {
+ fprintf(stdout, "FindResource worked\n");
+ HGLOBAL hgbl = ::LoadResource(NULL, hello);
+ int datasize = (int) ::SizeofResource(NULL, hello);
+ if(hgbl && datasize>0)
+ {
+ fprintf(stdout, "LoadResource worked\n");
+ fprintf(stdout, "SizeofResource returned datasize='%d'\n", datasize);
+ void *data = ::LockResource(hgbl);
+ if (data)
+ {
+ fprintf(stdout, "LockResource worked\n");
+ char *str = (char *) malloc(datasize+4);
+ if (str)
+ {
+ memcpy(str, data, datasize);
+ str[datasize] = 'E';
+ str[datasize+1] = 'O';
+ str[datasize+2] = 'R';
+ str[datasize+3] = 0;
+ fprintf(stdout, "str='%s'\n", str);
+ free(str);
+
+ ret = 0;
+
+#ifdef CMAKE_RCDEFINE_NO_QUOTED_STRINGS
+ fprintf(stdout, "LoadString skipped\n");
+#else
+ char buf[256];
+ if (::LoadString(NULL, 1026, buf, sizeof(buf)) > 0)
+ {
+ fprintf(stdout, "LoadString worked\n");
+ fprintf(stdout, "buf='%s'\n", buf);
+ }
+ else
+ {
+ fprintf(stdout, "LoadString failed\n");
+ ret = 1;
+ }
+#endif
+ }
+ }
+ }
+ }
+
+ return ret;
+}
diff --git a/Tests/VSResource/test.rc b/Tests/VSResource/test.rc
new file mode 100644
index 000000000..4ce4b5312
--- /dev/null
+++ b/Tests/VSResource/test.rc
@@ -0,0 +1,17 @@
+#ifdef CMAKE_RCDEFINE
+
+// This line can compile with either an unquoted or a quoted string
+1025 TEXTFILE CMAKE_RCDEFINE
+
+#ifndef CMAKE_RCDEFINE_NO_QUOTED_STRINGS
+// This block can only be compiled if CMAKE_RCDEFINE preprocesses
+// to a double quoted string
+STRINGTABLE
+BEGIN
+ 1026 CMAKE_RCDEFINE
+END
+#endif
+
+#else
+#error "resource compiler did not get defines from command line!"
+#endif
diff --git a/Tests/VSResource/test.txt b/Tests/VSResource/test.txt
new file mode 100644
index 000000000..c27c68d1a
--- /dev/null
+++ b/Tests/VSResource/test.txt
@@ -0,0 +1 @@
+Hello World! (@TEXTFILE_FROM_SOURCE_DIR@)
diff --git a/Tests/VariableUnusedViaSet/CMakeLists.txt b/Tests/VariableUnusedViaSet/CMakeLists.txt
new file mode 100644
index 000000000..0123ab221
--- /dev/null
+++ b/Tests/VariableUnusedViaSet/CMakeLists.txt
@@ -0,0 +1,4 @@
+set(UNUSED_VARIABLE)
+# Warning should occur here
+set(UNUSED_VARIABLE "Usage")
+message(STATUS "${UNUSED_VARIABLE}")
diff --git a/Tests/VariableUnusedViaUnset/CMakeLists.txt b/Tests/VariableUnusedViaUnset/CMakeLists.txt
new file mode 100644
index 000000000..4b4031da3
--- /dev/null
+++ b/Tests/VariableUnusedViaUnset/CMakeLists.txt
@@ -0,0 +1,8 @@
+# NOTE: Changing lines in here changes the test results since the first
+# instance shouldn't warn, but the second should and they have the same message
+
+# A warning should NOT be issued for this line:
+set(UNUSED_VARIABLE)
+# Warning should occur here:
+set(UNUSED_VARIABLE)
+message(STATUS "${UNUSED_VARIABLE}")
diff --git a/Tests/VariableUsage/CMakeLists.txt b/Tests/VariableUsage/CMakeLists.txt
new file mode 100644
index 000000000..4da1f56c7
--- /dev/null
+++ b/Tests/VariableUsage/CMakeLists.txt
@@ -0,0 +1 @@
+message(STATUS "${USED_VARIABLE}")
diff --git a/Tests/Wrapping/CMakeLists.txt b/Tests/Wrapping/CMakeLists.txt
new file mode 100644
index 000000000..c84dedc47
--- /dev/null
+++ b/Tests/Wrapping/CMakeLists.txt
@@ -0,0 +1,107 @@
+#
+# Wrapping
+#
+cmake_minimum_required (VERSION 2.6)
+PROJECT (Wrapping)
+
+# Disable cleaning of custom command outputs to preserve the hacks
+# used to generate the files using CONFIGURE_FILE.
+SET_DIRECTORY_PROPERTIES(PROPERTIES CLEAN_NO_CUSTOM 1)
+
+#
+# Lib and exe path
+#
+SET (LIBRARY_OUTPUT_PATH
+ ${Wrapping_BINARY_DIR}/bin/ CACHE INTERNAL
+ "Single output directory for building all libraries.")
+
+SET (EXECUTABLE_OUTPUT_PATH
+ ${Wrapping_BINARY_DIR}/bin/ CACHE INTERNAL
+ "Single output directory for building all executables.")
+
+#
+# Where will executable tests be written ?
+#
+IF (EXECUTABLE_OUTPUT_PATH)
+ SET (CXX_TEST_PATH ${EXECUTABLE_OUTPUT_PATH})
+ELSE (EXECUTABLE_OUTPUT_PATH)
+ SET (CXX_TEST_PATH .)
+ENDIF (EXECUTABLE_OUTPUT_PATH)
+
+#
+# Add exe
+#
+ADD_EXECUTABLE (wrapping wrapping.cxx)
+
+ADD_EXECUTABLE (Wrap Wrap.c)
+IF(WIN32)
+ SET(EXE_EXT ".exe")
+ENDIF(WIN32)
+SET(WRAP ${EXECUTABLE_OUTPUT_PATH}/${CMAKE_CFG_INTDIR}/Wrap${EXE_EXT})
+
+#
+# QT Wrappers
+#
+
+SET (QT_WRAP_CPP "On")
+SET (QT_MOC_EXE "echo")
+INCLUDE( FindQt3 )
+
+IF (QT_FOUND AND QT_WRAP_UI)
+ message("found qt 3 test it...")
+ INCLUDE_DIRECTORIES( ${QT_INCLUDE_DIR} )
+ INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_BINARY_DIR} )
+
+
+ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/foo.ui.in
+ ${CMAKE_CURRENT_BINARY_DIR}/foo.ui IMMEDIATE)
+
+ SET (QT_WRAP_UI "On")
+ SET (QT_UIC_EXE "${QT_UIC_EXECUTABLE}")
+
+
+ SET (QTUI_SRCS
+ qtwrapping.ui
+ ${CMAKE_CURRENT_BINARY_DIR}/foo.ui
+ )
+ QT_WRAP_UI (myqtlib QTUI_H_SRCS QTUI_S_SRCS ${QTUI_SRCS})
+ QT_WRAP_CPP (myqtlib QT_MOC_SRCS ${SRCS} vtkTestMoc.h)
+
+ MESSAGE("QT files are ${QTUI_S_SRCS}")
+ MESSAGE("QT other files are ${QTUI_H_SRCS}")
+ ADD_DEFINITIONS(${QT_DEFINITIONS})
+ ADD_LIBRARY(myqtlib ${QTUI_S_SRCS} ${QT_MOC_SRCS})
+ ADD_EXECUTABLE (qtwrapping qtwrappingmain.cxx)
+ TARGET_LINK_LIBRARIES(qtwrapping myqtlib)
+
+ TARGET_LINK_LIBRARIES( qtwrapping ${QT_LIBRARIES} )
+ELSE (QT_FOUND AND QT_WRAP_UI)
+ ADD_EXECUTABLE (qtwrapping qtnoqtmain.cxx)
+ENDIF (QT_FOUND AND QT_WRAP_UI)
+
+#
+# FLTK Wrappers
+#
+# 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})
+ADD_LIBRARY(wraplibFLTK ${wraplibFLTK_FLTK_UI_SRCS})
+ADD_DEPENDENCIES(wraplibFLTK fakefluid)
+ADD_DEPENDENCIES(fakefluid Wrap)
+#
+# Mangled Mesa
+#
+CONFIGURE_FILE(
+ ${Wrapping_SOURCE_DIR}/dummy
+ ${Wrapping_BINARY_DIR}/gl.h
+ COPYONLY IMMEDIATE)
+USE_MANGLED_MESA (${Wrapping_BINARY_DIR} ${Wrapping_BINARY_DIR}/mangled_mesa)
+
diff --git a/Tests/Wrapping/Wrap.c b/Tests/Wrapping/Wrap.c
new file mode 100644
index 000000000..0a1ff501e
--- /dev/null
+++ b/Tests/Wrapping/Wrap.c
@@ -0,0 +1,23 @@
+#include <stdio.h>
+
+#ifdef __CLASSIC_C__
+int main(argc, argv)
+ int argc;
+ char ** argv;
+#else
+int main(int argc, const char* argv[])
+#endif
+{
+ FILE* fout = fopen(argv[argc-1], "w");
+ printf("Wrap creating \"%s\"\n", argv[argc-1]);
+ if(fout)
+ {
+ fprintf(fout, "int foo() { return 0; }\n");
+ fclose(fout);
+ }
+ else
+ {
+ return -1;
+ }
+ return 0;
+}
diff --git a/Tests/Wrapping/dummy b/Tests/Wrapping/dummy
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/Wrapping/dummy
diff --git a/Tests/Wrapping/fakefluid.cxx b/Tests/Wrapping/fakefluid.cxx
new file mode 100644
index 000000000..af4467997
--- /dev/null
+++ b/Tests/Wrapping/fakefluid.cxx
@@ -0,0 +1,17 @@
+#include <stdio.h>
+#include <string.h>
+int main(int ac, char** av)
+{
+ for(int i =0; i < ac; ++i)
+ {
+ if(strcmp(av[i], "-o") == 0 ||
+ strcmp(av[i], "-h") == 0)
+ {
+ fprintf(stdout, "fakefluid is creating file \"%s\"\n", av[i+1]);
+ FILE* file = fopen(av[i+1], "w");
+ fprintf(file, "// hello\n");
+ fclose(file);
+ }
+ }
+ return 0;
+}
diff --git a/Tests/Wrapping/fltk1.fl b/Tests/Wrapping/fltk1.fl
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/Wrapping/fltk1.fl
diff --git a/Tests/Wrapping/foo.ui.in b/Tests/Wrapping/foo.ui.in
new file mode 100644
index 000000000..4f57b5db1
--- /dev/null
+++ b/Tests/Wrapping/foo.ui.in
@@ -0,0 +1,44 @@
+<!DOCTYPE UI><UI>
+<class>foo</class>
+<widget>
+ <class>QDialog</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>qtwrapping</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>229</width>
+ <height>38</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>QTWrapUI Test program</string>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>11</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel1</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>This is a test for QTWrapUI.</string>
+ </property>
+ </widget>
+ </vbox>
+</widget>
+</UI>
diff --git a/Tests/Wrapping/hints b/Tests/Wrapping/hints
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/Wrapping/hints
diff --git a/Tests/Wrapping/itkWrapperConfig.cxx b/Tests/Wrapping/itkWrapperConfig.cxx
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/Wrapping/itkWrapperConfig.cxx
diff --git a/Tests/Wrapping/qtnoqtmain.cxx b/Tests/Wrapping/qtnoqtmain.cxx
new file mode 100644
index 000000000..8b7334a18
--- /dev/null
+++ b/Tests/Wrapping/qtnoqtmain.cxx
@@ -0,0 +1,5 @@
+int main(int ac, char** av)
+{
+ return 0;
+}
+
diff --git a/Tests/Wrapping/qtwrapping.ui b/Tests/Wrapping/qtwrapping.ui
new file mode 100644
index 000000000..67dcb9fbc
--- /dev/null
+++ b/Tests/Wrapping/qtwrapping.ui
@@ -0,0 +1,44 @@
+<!DOCTYPE UI><UI>
+<class>qtwrapping</class>
+<widget>
+ <class>QDialog</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>qtwrapping</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>229</width>
+ <height>38</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>QTWrapUI Test program</string>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>11</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel1</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>This is a test for QTWrapUI.</string>
+ </property>
+ </widget>
+ </vbox>
+</widget>
+</UI>
diff --git a/Tests/Wrapping/qtwrappingmain.cxx b/Tests/Wrapping/qtwrappingmain.cxx
new file mode 100644
index 000000000..fabecfc72
--- /dev/null
+++ b/Tests/Wrapping/qtwrappingmain.cxx
@@ -0,0 +1,29 @@
+#include <qapplication.h>
+#include "qtwrapping.h"
+
+#ifndef _WIN32
+# include <stdlib.h>
+# include <stdio.h>
+#endif
+
+int main(int argc, char *argv[])
+{
+#ifndef _WIN32
+ const char* display = getenv("DISPLAY");
+ if ( display && strlen(display)>0 )
+ {
+#endif
+ QApplication app(argc,argv);
+
+ qtwrapping qtw;
+ app.setMainWidget(&qtw);
+#ifndef _WIN32
+ }
+ else
+ {
+ printf("Environment variable DISPLAY is not set. I will pretend like the test passed, but you should really set it.\n");
+ }
+#endif
+
+ return 0;
+}
diff --git a/Tests/Wrapping/vtkExcluded.cxx b/Tests/Wrapping/vtkExcluded.cxx
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/Wrapping/vtkExcluded.cxx
diff --git a/Tests/Wrapping/vtkExcluded.h b/Tests/Wrapping/vtkExcluded.h
new file mode 100644
index 000000000..835f61a3e
--- /dev/null
+++ b/Tests/Wrapping/vtkExcluded.h
@@ -0,0 +1,2 @@
+// A comment
+// Another comment
diff --git a/Tests/Wrapping/vtkIncluded.cxx b/Tests/Wrapping/vtkIncluded.cxx
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Tests/Wrapping/vtkIncluded.cxx
diff --git a/Tests/Wrapping/vtkIncluded.h b/Tests/Wrapping/vtkIncluded.h
new file mode 100644
index 000000000..a1c4aba26
--- /dev/null
+++ b/Tests/Wrapping/vtkIncluded.h
@@ -0,0 +1,2 @@
+// A comment
+// Another comment (force coverage)
diff --git a/Tests/Wrapping/vtkTestMoc.h b/Tests/Wrapping/vtkTestMoc.h
new file mode 100644
index 000000000..f11a927f0
--- /dev/null
+++ b/Tests/Wrapping/vtkTestMoc.h
@@ -0,0 +1,8 @@
+#include <qapplication.h>
+
+class Foo : public QApplication
+{
+ Q_OBJECT
+public:
+ Foo();
+};
diff --git a/Tests/Wrapping/wrapping.cxx b/Tests/Wrapping/wrapping.cxx
new file mode 100644
index 000000000..1482f27e5
--- /dev/null
+++ b/Tests/Wrapping/wrapping.cxx
@@ -0,0 +1,4 @@
+int main ()
+{
+ return 0;
+}
diff --git a/Tests/X11/CMakeLists.txt b/Tests/X11/CMakeLists.txt
new file mode 100644
index 000000000..03aa09578
--- /dev/null
+++ b/Tests/X11/CMakeLists.txt
@@ -0,0 +1,40 @@
+# a simple C only test case
+cmake_minimum_required (VERSION 2.6)
+PROJECT (UseX11 CXX C)
+
+INCLUDE (${CMAKE_ROOT}/Modules/FindX11.cmake)
+MESSAGE("X11_FOUND: ${X11_FOUND}")
+
+ADD_EXECUTABLE (UseX11 X11.c)
+install(TARGETS UseX11 DESTINATION bin)
+
+# so for universal binaries this test will fail if
+#
+IF(APPLE)
+ LIST(LENGTH CMAKE_OSX_ARCHITECTURES NUMARCH)
+ IF(NUMARCH GREATER 1)
+ IF(NOT EXISTS /usr/X11R6/lib//libSM.6.dylib)
+ SET(X11_FOUND FALSE)
+ MESSAGE("disable X11, because of universal binary and sysroot")
+ ENDIF(NOT EXISTS /usr/X11R6/lib//libSM.6.dylib)
+ ENDIF(NUMARCH GREATER 1)
+ENDIF(APPLE)
+
+IF(X11_FOUND)
+ ADD_DEFINITIONS(-DCMAKE_HAS_X)
+ INCLUDE_DIRECTORIES(${X11_INCLUDE_DIR})
+ TARGET_LINK_LIBRARIES(UseX11 ${X11_LIBRARIES})
+ IF(APPLE)
+ ADD_EXECUTABLE(HelloWorldX11 HelloWorldX11.cxx)
+ TARGET_LINK_LIBRARIES(HelloWorldX11 ${X11_LIBRARIES})
+ install(TARGETS HelloWorldX11 DESTINATION bin)
+
+ set(CPACK_BINARY_OSXX11 ON CACHE BOOL "" FORCE)
+ set(CPACK_BINARY_PACKAGEMAKER OFF CACHE BOOL "" FORCE )
+ set(CPACK_PACKAGE_NAME HelloWorldX11Package)
+ set(CPACK_PACKAGE_EXECUTABLES HelloWorldX11 HelloWorldX11)
+ ENDIF(APPLE)
+ENDIF(X11_FOUND)
+
+# build a CPack driven installer package
+include(CPack)
diff --git a/Tests/X11/HelloWorldX11.cxx b/Tests/X11/HelloWorldX11.cxx
new file mode 100644
index 000000000..e3c9dd9cf
--- /dev/null
+++ b/Tests/X11/HelloWorldX11.cxx
@@ -0,0 +1,146 @@
+
+/*** START MAIN.H ***/
+/* http://www.geocities.com/jeff_louie/x11/helloworld.htm* */
+/*
+ * main.h
+ * TestX
+ *
+ * Created by Jeff Louie on Tue Feb 03 2004.
+ * Copyright (c) 2004 __MyCompanyName__. All rights reserved.
+ *
+ */
+
+
+#ifndef MAIN_H
+#define MAIN_H 1
+
+#include <iostream>
+#include <stdlib.h>
+
+/* include the X library headers */
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xos.h>
+
+class Main {
+
+public:
+ // constructor
+ Main(int argc, char * const argv[]);
+ //virtual ~Main();
+
+
+private:
+
+
+ /* here are our X variables */
+ Display *dis;
+ int screen;
+ Window win;
+ GC gc;
+
+ /* here are our X routines declared! */
+ void init_x();
+ void close_x();
+ void redraw();
+ int delay(int i);
+
+};
+
+#endif
+
+/*** END MAIN.H ***/
+
+/*** START MAIN.CPP ***/
+
+// modified from Brian Hammond's Howdy program at
+// http://www.insanityengine.com/doc/x11/xintro.html
+// jeff louie 02.05.2004
+
+
+
+int main (int argc, char * const argv[]) {
+ Main m(argc, argv);
+ return 0;
+}
+
+//Main::~Main() {;};
+Main::Main (int argc, char * const argv[]) {
+ XEvent event; // XEvent declaration
+ KeySym key; // KeyPress Events
+ char text[255]; // char buffer for KeyPress Events
+
+ init_x();
+
+ // event loop
+ while(1) {
+ // get the next event and stuff it into our event variable.
+ // Note: only events we set the mask for are detected!
+ XNextEvent(dis, &event);
+
+
+ switch (event.type) {
+ int x;
+ int y;
+ case Expose:
+ if (event.xexpose.count==0) {
+ redraw();
+ }
+ break;
+ case KeyPress:
+ if (XLookupString(&event.xkey,text,255,&key,0)==1) {
+ // use the XLookupString routine to convert the invent
+ // KeyPress data into regular text. Weird but necessary...
+ if ((text[0]=='q') || (text[0]=='Q')) {
+ close_x();
+ }
+ else {
+ // echo key press
+ printf("You pressed the %c key!\n",text[0]);
+ }
+ }
+ break;
+ case ButtonPress:
+ // get cursor position
+ x= event.xbutton.x;
+ y= event.xbutton.y;
+ strcpy(text,"X is FUN!");
+ XSetForeground(dis,gc,rand()%event.xbutton.x%255);
+ // draw text at cursor
+ XDrawString(dis,win,gc,x,y, text, strlen(text));
+ break;
+ default:
+ printf("Unhandled event.\n");
+ }
+ }
+}
+
+void Main::init_x() {
+ unsigned long black,white;
+
+ dis=XOpenDisplay(NULL);
+ screen=DefaultScreen(dis);
+ black=BlackPixel(dis,screen),
+ white=WhitePixel(dis, screen);
+ win=XCreateSimpleWindow(dis,DefaultRootWindow(dis),0,0,
+ 300, 300, 5,black, white);
+ XSetStandardProperties(dis,win,"Hello World","Hi",None,NULL,0,NULL);
+ XSelectInput(dis, win, ExposureMask|ButtonPressMask|KeyPressMask);
+ // get Graphics Context
+ gc=XCreateGC(dis, win, 0,0);
+ XSetBackground(dis,gc,white);
+ XSetForeground(dis,gc,black);
+ XClearWindow(dis, win);
+ XMapRaised(dis, win);
+};
+
+void Main::close_x() {
+ XFreeGC(dis, gc);
+ XDestroyWindow(dis,win);
+ XCloseDisplay(dis);
+ exit(1);
+};
+
+void Main::redraw() {
+ XClearWindow(dis, win);
+};
diff --git a/Tests/X11/X11.c b/Tests/X11/X11.c
new file mode 100644
index 000000000..b802ed8b9
--- /dev/null
+++ b/Tests/X11/X11.c
@@ -0,0 +1,21 @@
+#include "stdio.h"
+#ifdef CMAKE_HAS_X
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+int main()
+{
+ printf("There is X on this computer\n");
+ return 0;
+}
+
+#else
+
+int main()
+{
+ printf("No X on this computer\n");
+ return 0;
+}
+
+#endif
diff --git a/Tests/bootstrap.bat.in b/Tests/bootstrap.bat.in
new file mode 100644
index 000000000..aeb24b1ca
--- /dev/null
+++ b/Tests/bootstrap.bat.in
@@ -0,0 +1,2 @@
+@echo off
+sh "@CMake_SOURCE_DIR@/bootstrap" %*
diff --git a/Tests/iOSNavApp/CMakeLists.txt b/Tests/iOSNavApp/CMakeLists.txt
new file mode 100644
index 000000000..12c3ada35
--- /dev/null
+++ b/Tests/iOSNavApp/CMakeLists.txt
@@ -0,0 +1,38 @@
+cmake_minimum_required(VERSION 2.8.5)
+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}
+ ${CMAKE_CURRENT_SOURCE_DIR}/Classes
+ )
+
+add_library(Functions STATIC TotalFunction.c TotalFunction.h)
+
+set(M_SRCS main.m Classes/NavApp3AppDelegate.m Classes/RootViewController.m)
+set(HEADERS Classes/NavApp3AppDelegate.h Classes/RootViewController.h)
+set(RESOURCES MainWindow.xib RootViewController.xib)
+
+add_executable(NavApp3 MACOSX_BUNDLE ${M_SRCS} ${HEADERS} ${RESOURCES})
+
+target_link_libraries(NavApp3
+ Functions
+ "-framework CoreGraphics"
+ "-framework Foundation"
+ "-framework UIKit"
+ )
+
+set_target_properties(NavApp3 PROPERTIES
+ MACOSX_BUNDLE_GUI_IDENTIFIER "com.yourcompany.NavApp3"
+ MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist.in
+ RESOURCE "${RESOURCES}"
+ XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "iPhone Developer"
+ XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "dwarf-with-dsym"
+ XCODE_ATTRIBUTE_GCC_PRECOMPILE_PREFIX_HEADER YES
+ XCODE_ATTRIBUTE_GCC_PREFIX_HEADER ${CMAKE_CURRENT_LIST_DIR}/NavApp3_Prefix.pch
+ XCODE_ATTRIBUTE_INFOPLIST_PREPROCESS YES
+ XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET 3.0
+ )
diff --git a/Tests/iOSNavApp/Classes/NavApp3AppDelegate.h b/Tests/iOSNavApp/Classes/NavApp3AppDelegate.h
new file mode 100644
index 000000000..f1234fe8b
--- /dev/null
+++ b/Tests/iOSNavApp/Classes/NavApp3AppDelegate.h
@@ -0,0 +1,20 @@
+//
+// NavApp3AppDelegate.h
+// NavApp3
+//
+// Created by David Cole on 6/23/11.
+// Copyright 2011 Kitware, Inc. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface NavApp3AppDelegate : NSObject <UIApplicationDelegate> {
+
+ UIWindow *window;
+ UINavigationController *navigationController;
+}
+
+@property (nonatomic, retain) IBOutlet UIWindow *window;
+@property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
+
+@end
diff --git a/Tests/iOSNavApp/Classes/NavApp3AppDelegate.m b/Tests/iOSNavApp/Classes/NavApp3AppDelegate.m
new file mode 100644
index 000000000..c82204c11
--- /dev/null
+++ b/Tests/iOSNavApp/Classes/NavApp3AppDelegate.m
@@ -0,0 +1,88 @@
+//
+// NavApp3AppDelegate.m
+// NavApp3
+//
+// Created by David Cole on 6/23/11.
+// Copyright 2011 Kitware, Inc. All rights reserved.
+//
+
+#import "NavApp3AppDelegate.h"
+#import "RootViewController.h"
+
+
+@implementation NavApp3AppDelegate
+
+@synthesize window;
+@synthesize navigationController;
+
+
+#pragma mark -
+#pragma mark Application lifecycle
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+
+ // Override point for customization after application launch.
+ // Add the navigation controller's view to the window and display.
+ [self.window addSubview:navigationController.view];
+ [self.window makeKeyAndVisible];
+
+ return YES;
+}
+
+
+- (void)applicationWillResignActive:(UIApplication *)application {
+ /*
+ Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
+ Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
+ */
+}
+
+
+- (void)applicationDidEnterBackground:(UIApplication *)application {
+ /*
+ Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
+ If your application supports background execution, called instead of applicationWillTerminate: when the user quits.
+ */
+}
+
+
+- (void)applicationWillEnterForeground:(UIApplication *)application {
+ /*
+ Called as part of transition from the background to the inactive state: here you can undo many of the changes made on entering the background.
+ */
+}
+
+
+- (void)applicationDidBecomeActive:(UIApplication *)application {
+ /*
+ Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
+ */
+}
+
+
+- (void)applicationWillTerminate:(UIApplication *)application {
+ /*
+ Called when the application is about to terminate.
+ See also applicationDidEnterBackground:.
+ */
+}
+
+
+#pragma mark -
+#pragma mark Memory management
+
+- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
+ /*
+ Free up as much memory as possible by purging cached data objects that can be recreated (or reloaded from disk) later.
+ */
+}
+
+
+- (void)dealloc {
+ [navigationController release];
+ [window release];
+ [super dealloc];
+}
+
+
+@end
diff --git a/Tests/iOSNavApp/Classes/RootViewController.h b/Tests/iOSNavApp/Classes/RootViewController.h
new file mode 100644
index 000000000..c5e9c1148
--- /dev/null
+++ b/Tests/iOSNavApp/Classes/RootViewController.h
@@ -0,0 +1,14 @@
+//
+// RootViewController.h
+// NavApp3
+//
+// Created by David Cole on 6/23/11.
+// Copyright 2011 Kitware, Inc. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface RootViewController : UITableViewController {
+}
+
+@end
diff --git a/Tests/iOSNavApp/Classes/RootViewController.m b/Tests/iOSNavApp/Classes/RootViewController.m
new file mode 100644
index 000000000..8a20d89db
--- /dev/null
+++ b/Tests/iOSNavApp/Classes/RootViewController.m
@@ -0,0 +1,168 @@
+//
+// RootViewController.m
+// NavApp3
+//
+// Created by David Cole on 6/23/11.
+// Copyright 2011 Kitware, Inc. All rights reserved.
+//
+
+#import "RootViewController.h"
+
+#include "TotalFunction.h"
+
+
+@implementation RootViewController
+
+
+#pragma mark -
+#pragma mark View lifecycle
+
+/*
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
+ // self.navigationItem.rightBarButtonItem = self.editButtonItem;
+}
+*/
+
+/*
+- (void)viewWillAppear:(BOOL)animated {
+ [super viewWillAppear:animated];
+}
+*/
+/*
+- (void)viewDidAppear:(BOOL)animated {
+ [super viewDidAppear:animated];
+}
+*/
+/*
+- (void)viewWillDisappear:(BOOL)animated {
+ [super viewWillDisappear:animated];
+}
+*/
+/*
+- (void)viewDidDisappear:(BOOL)animated {
+ [super viewDidDisappear:animated];
+}
+*/
+
+/*
+ // Override to allow orientations other than the default portrait orientation.
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
+ // Return YES for supported orientations.
+ return (interfaceOrientation == UIInterfaceOrientationPortrait);
+}
+ */
+
+
+#pragma mark -
+#pragma mark Table view data source
+
+// Customize the number of sections in the table view.
+- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
+ return 1;
+}
+
+
+// Customize the number of rows in the table view.
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+ int n = Total("numberOfRows");
+ return n;
+}
+
+
+// Customize the appearance of table view cells.
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+
+ static NSString *CellIdentifier = @"Cell";
+
+ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
+ if (cell == nil) {
+ cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
+ }
+
+ // Configure the cell.
+ cell.textLabel.text = [NSString stringWithFormat:@"%d", [indexPath row]];
+
+ return cell;
+}
+
+
+/*
+// Override to support conditional editing of the table view.
+- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
+ // Return NO if you do not want the specified item to be editable.
+ return YES;
+}
+*/
+
+
+/*
+// Override to support editing the table view.
+- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
+
+ if (editingStyle == UITableViewCellEditingStyleDelete) {
+ // Delete the row from the data source.
+ [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
+ }
+ else if (editingStyle == UITableViewCellEditingStyleInsert) {
+ // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
+ }
+}
+*/
+
+
+/*
+// Override to support rearranging the table view.
+- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
+}
+*/
+
+
+/*
+// Override to support conditional rearranging of the table view.
+- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
+ // Return NO if you do not want the item to be re-orderable.
+ return YES;
+}
+*/
+
+
+#pragma mark -
+#pragma mark Table view delegate
+
+- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+
+ /*
+ <#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:@"<#Nib name#>" bundle:nil];
+ // ...
+ // Pass the selected object to the new view controller.
+ [self.navigationController pushViewController:detailViewController animated:YES];
+ [detailViewController release];
+ */
+}
+
+
+#pragma mark -
+#pragma mark Memory management
+
+- (void)didReceiveMemoryWarning {
+ // Releases the view if it doesn't have a superview.
+ [super didReceiveMemoryWarning];
+
+ // Relinquish ownership any cached data, images, etc that aren't in use.
+}
+
+- (void)viewDidUnload {
+ // Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
+ // For example: self.myOutlet = nil;
+}
+
+
+- (void)dealloc {
+ [super dealloc];
+}
+
+
+@end
diff --git a/Tests/iOSNavApp/Info.plist.in b/Tests/iOSNavApp/Info.plist.in
new file mode 100644
index 000000000..6ea0f00ee
--- /dev/null
+++ b/Tests/iOSNavApp/Info.plist.in
@@ -0,0 +1,32 @@
+<?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>English</string>
+ <key>CFBundleDisplayName</key>
+ <string>NavApp3</string>
+ <key>CFBundleExecutable</key>
+ <string>NavApp3</string>
+ <key>CFBundleIconFile</key>
+ <string></string>
+ <key>CFBundleIdentifier</key>
+ <string>com.yourcompany.NavApp3</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>NavApp3</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1.0</string>
+ <key>LSRequiresIPhoneOS</key>
+ <true/>
+ <key>NSMainNibFile</key>
+ <string>MainWindow</string>
+ <key>UISupportedInterfaceOrientations</key>
+ <array/>
+</dict>
+</plist>
diff --git a/Tests/iOSNavApp/MainWindow.xib b/Tests/iOSNavApp/MainWindow.xib
new file mode 100644
index 000000000..1ff5f67fc
--- /dev/null
+++ b/Tests/iOSNavApp/MainWindow.xib
@@ -0,0 +1,542 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.10">
+ <data>
+ <int key="IBDocument.SystemTarget">1024</int>
+ <string key="IBDocument.SystemVersion">10D571</string>
+ <string key="IBDocument.InterfaceBuilderVersion">786</string>
+ <string key="IBDocument.AppKitVersion">1038.29</string>
+ <string key="IBDocument.HIToolboxVersion">460.00</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="NS.object.0">112</string>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <integer value="13"/>
+ </object>
+ <object class="NSArray" key="IBDocument.PluginDependencies">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.Metadata">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys" id="0">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBProxyObject" id="841351856">
+ <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ <object class="IBProxyObject" id="302016328">
+ <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ <object class="IBUICustomObject" id="664661524">
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ <object class="IBUIWindow" id="380026005">
+ <nil key="NSNextResponder"/>
+ <int key="NSvFlags">1316</int>
+ <object class="NSPSMatrix" key="NSFrameMatrix"/>
+ <string key="NSFrameSize">{320, 480}</string>
+ <object class="NSColor" key="IBUIBackgroundColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MSAxIDEAA</bytes>
+ </object>
+ <bool key="IBUIOpaque">NO</bool>
+ <bool key="IBUIClearsContextBeforeDrawing">NO</bool>
+ <object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <bool key="IBUIResizesToFullScreen">YES</bool>
+ </object>
+ <object class="IBUINavigationController" id="701001926">
+ <object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
+ <object class="IBUISimulatedOrientationMetrics" key="IBUISimulatedOrientationMetrics">
+ <int key="interfaceOrientation">1</int>
+ </object>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <bool key="IBUIHorizontal">NO</bool>
+ <object class="IBUINavigationBar" key="IBUINavigationBar" id="207850653">
+ <nil key="NSNextResponder"/>
+ <int key="NSvFlags">256</int>
+ <string key="NSFrameSize">{0, 0}</string>
+ <bool key="IBUIOpaque">NO</bool>
+ <bool key="IBUIClipsSubviews">YES</bool>
+ <bool key="IBUIMultipleTouchEnabled">YES</bool>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ <object class="NSMutableArray" key="IBUIViewControllers">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBUIViewController" id="619226028">
+ <object class="IBUINavigationItem" key="IBUINavigationItem" id="394667715">
+ <reference key="IBUINavigationBar"/>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ <reference key="IBUIParentViewController" ref="701001926"/>
+ <string key="IBUINibName">RootViewController</string>
+ <object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
+ <object class="IBUISimulatedOrientationMetrics" key="IBUISimulatedOrientationMetrics">
+ <int key="interfaceOrientation">1</int>
+ </object>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <bool key="IBUIHorizontal">NO</bool>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="IBObjectContainer" key="IBDocument.Objects">
+ <object class="NSMutableArray" key="connectionRecords">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">delegate</string>
+ <reference key="source" ref="841351856"/>
+ <reference key="destination" ref="664661524"/>
+ </object>
+ <int key="connectionID">4</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">window</string>
+ <reference key="source" ref="664661524"/>
+ <reference key="destination" ref="380026005"/>
+ </object>
+ <int key="connectionID">5</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">navigationController</string>
+ <reference key="source" ref="664661524"/>
+ <reference key="destination" ref="701001926"/>
+ </object>
+ <int key="connectionID">15</int>
+ </object>
+ </object>
+ <object class="IBMutableOrderedSet" key="objectRecords">
+ <object class="NSArray" key="orderedObjects">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBObjectRecord">
+ <int key="objectID">0</int>
+ <reference key="object" ref="0"/>
+ <reference key="children" ref="1000"/>
+ <nil key="parent"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">2</int>
+ <reference key="object" ref="380026005"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-1</int>
+ <reference key="object" ref="841351856"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">File's Owner</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">3</int>
+ <reference key="object" ref="664661524"/>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-2</int>
+ <reference key="object" ref="302016328"/>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">9</int>
+ <reference key="object" ref="701001926"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="207850653"/>
+ <reference ref="619226028"/>
+ </object>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">11</int>
+ <reference key="object" ref="207850653"/>
+ <reference key="parent" ref="701001926"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">13</int>
+ <reference key="object" ref="619226028"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="394667715"/>
+ </object>
+ <reference key="parent" ref="701001926"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">14</int>
+ <reference key="object" ref="394667715"/>
+ <reference key="parent" ref="619226028"/>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="flattenedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>-1.CustomClassName</string>
+ <string>-2.CustomClassName</string>
+ <string>11.IBPluginDependency</string>
+ <string>13.CustomClassName</string>
+ <string>13.IBPluginDependency</string>
+ <string>2.IBAttributePlaceholdersKey</string>
+ <string>2.IBEditorWindowLastContentRect</string>
+ <string>2.IBPluginDependency</string>
+ <string>3.CustomClassName</string>
+ <string>3.IBPluginDependency</string>
+ <string>9.IBEditorWindowLastContentRect</string>
+ <string>9.IBPluginDependency</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>UIApplication</string>
+ <string>UIResponder</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>RootViewController</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSMutableDictionary">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference key="dict.sortedKeys" ref="0"/>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <string>{{673, 376}, {320, 480}}</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>NavApp3AppDelegate</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>{{186, 376}, {320, 480}}</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="unlocalizedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference key="dict.sortedKeys" ref="0"/>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="activeLocalization"/>
+ <object class="NSMutableDictionary" key="localizations">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference key="dict.sortedKeys" ref="0"/>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="sourceID"/>
+ <int key="maxID">16</int>
+ </object>
+ <object class="IBClassDescriber" key="IBDocument.Classes">
+ <object class="NSMutableArray" key="referencedPartialClassDescriptions">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">RootViewController</string>
+ <string key="superclassName">UITableViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/RootViewController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIWindow</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBUserSource</string>
+ <string key="minorKey"/>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NavApp3AppDelegate</string>
+ <string key="superclassName">NSObject</string>
+ <object class="NSMutableDictionary" key="outlets">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>navigationController</string>
+ <string>window</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>UINavigationController</string>
+ <string>UIWindow</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="toOneOutletInfosByName">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>navigationController</string>
+ <string>window</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBToOneOutletInfo">
+ <string key="name">navigationController</string>
+ <string key="candidateClassName">UINavigationController</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">window</string>
+ <string key="candidateClassName">UIWindow</string>
+ </object>
+ </object>
+ </object>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/NavApp3AppDelegate.h</string>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableArray" key="referencedPartialClassDescriptionsV3.2+">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSError.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSFileManager.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyValueCoding.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyValueObserving.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyedArchiver.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSObject.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSRunLoop.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSThread.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSURL.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSURLConnection.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIAccessibility.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UINibLoading.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier" id="48103097">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIResponder.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIApplication</string>
+ <string key="superclassName">UIResponder</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIApplication.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIBarButtonItem</string>
+ <string key="superclassName">UIBarItem</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIBarButtonItem.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIBarItem</string>
+ <string key="superclassName">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIBarItem.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UINavigationBar</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier" id="193736137">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UINavigationBar.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UINavigationController</string>
+ <string key="superclassName">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier" id="720195805">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UINavigationController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UINavigationItem</string>
+ <string key="superclassName">NSObject</string>
+ <reference key="sourceIdentifier" ref="193736137"/>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIResponder</string>
+ <string key="superclassName">NSObject</string>
+ <reference key="sourceIdentifier" ref="48103097"/>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UISearchBar</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISearchBar.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UISearchDisplayController</string>
+ <string key="superclassName">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISearchDisplayController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UITableViewController</string>
+ <string key="superclassName">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITableViewController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITextField.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <string key="superclassName">UIResponder</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <reference key="sourceIdentifier" ref="720195805"/>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIPopoverController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISplitViewController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITabBarController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <string key="superclassName">UIResponder</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIViewController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIWindow</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIWindow.h</string>
+ </object>
+ </object>
+ </object>
+ </object>
+ <int key="IBDocument.localizationMode">0</int>
+ <string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
+ <integer value="1024" key="NS.object.0"/>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
+ <integer value="3100" key="NS.object.0"/>
+ </object>
+ <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+ <string key="IBDocument.LastKnownRelativeProjectPath">NavApp3.xcodeproj</string>
+ <int key="IBDocument.defaultPropertyAccessControl">3</int>
+ <string key="IBCocoaTouchPluginVersion">112</string>
+ </data>
+</archive>
diff --git a/Tests/iOSNavApp/NavApp3_Prefix.pch b/Tests/iOSNavApp/NavApp3_Prefix.pch
new file mode 100644
index 000000000..9919f3076
--- /dev/null
+++ b/Tests/iOSNavApp/NavApp3_Prefix.pch
@@ -0,0 +1,14 @@
+//
+// Prefix header for all source files of the 'NavApp3' target in the 'NavApp3' project
+//
+#import <Availability.h>
+
+#ifndef __IPHONE_3_0
+#warning "This project uses features only available in iPhone SDK 3.0 and later."
+#endif
+
+
+#ifdef __OBJC__
+ #import <Foundation/Foundation.h>
+ #import <UIKit/UIKit.h>
+#endif
diff --git a/Tests/iOSNavApp/RootViewController.xib b/Tests/iOSNavApp/RootViewController.xib
new file mode 100644
index 000000000..12a4831f2
--- /dev/null
+++ b/Tests/iOSNavApp/RootViewController.xib
@@ -0,0 +1,384 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.10">
+ <data>
+ <int key="IBDocument.SystemTarget">784</int>
+ <string key="IBDocument.SystemVersion">10D541</string>
+ <string key="IBDocument.InterfaceBuilderVersion">760</string>
+ <string key="IBDocument.AppKitVersion">1038.29</string>
+ <string key="IBDocument.HIToolboxVersion">460.00</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="NS.object.0">81</string>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <integer value="2"/>
+ </object>
+ <object class="NSArray" key="IBDocument.PluginDependencies">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.Metadata">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys" id="0">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBProxyObject" id="841351856">
+ <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ <object class="IBProxyObject" id="371349661">
+ <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ <object class="IBUITableView" id="709618507">
+ <reference key="NSNextResponder"/>
+ <int key="NSvFlags">274</int>
+ <string key="NSFrameSize">{320, 247}</string>
+ <reference key="NSSuperview"/>
+ <object class="NSColor" key="IBUIBackgroundColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MQA</bytes>
+ </object>
+ <bool key="IBUIOpaque">NO</bool>
+ <bool key="IBUIClipsSubviews">YES</bool>
+ <bool key="IBUIClearsContextBeforeDrawing">NO</bool>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <bool key="IBUIBouncesZoom">NO</bool>
+ <int key="IBUISeparatorStyle">1</int>
+ <int key="IBUISectionIndexMinimumDisplayRowCount">0</int>
+ <bool key="IBUIShowsSelectionImmediatelyOnTouchBegin">YES</bool>
+ <float key="IBUIRowHeight">44</float>
+ <float key="IBUISectionHeaderHeight">22</float>
+ <float key="IBUISectionFooterHeight">22</float>
+ </object>
+ </object>
+ <object class="IBObjectContainer" key="IBDocument.Objects">
+ <object class="NSMutableArray" key="connectionRecords">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">view</string>
+ <reference key="source" ref="841351856"/>
+ <reference key="destination" ref="709618507"/>
+ </object>
+ <int key="connectionID">3</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">dataSource</string>
+ <reference key="source" ref="709618507"/>
+ <reference key="destination" ref="841351856"/>
+ </object>
+ <int key="connectionID">4</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">delegate</string>
+ <reference key="source" ref="709618507"/>
+ <reference key="destination" ref="841351856"/>
+ </object>
+ <int key="connectionID">5</int>
+ </object>
+ </object>
+ <object class="IBMutableOrderedSet" key="objectRecords">
+ <object class="NSArray" key="orderedObjects">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBObjectRecord">
+ <int key="objectID">0</int>
+ <reference key="object" ref="0"/>
+ <reference key="children" ref="1000"/>
+ <nil key="parent"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-1</int>
+ <reference key="object" ref="841351856"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">File's Owner</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-2</int>
+ <reference key="object" ref="371349661"/>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">2</int>
+ <reference key="object" ref="709618507"/>
+ <reference key="parent" ref="0"/>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="flattenedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>-1.CustomClassName</string>
+ <string>-2.CustomClassName</string>
+ <string>2.IBEditorWindowLastContentRect</string>
+ <string>2.IBPluginDependency</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>RootViewController</string>
+ <string>UIResponder</string>
+ <string>{{144, 609}, {320, 247}}</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="unlocalizedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference key="dict.sortedKeys" ref="0"/>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="activeLocalization"/>
+ <object class="NSMutableDictionary" key="localizations">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference key="dict.sortedKeys" ref="0"/>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="sourceID"/>
+ <int key="maxID">5</int>
+ </object>
+ <object class="IBClassDescriber" key="IBDocument.Classes">
+ <object class="NSMutableArray" key="referencedPartialClassDescriptions">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">RootViewController</string>
+ <string key="superclassName">UITableViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/RootViewController.h</string>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableArray" key="referencedPartialClassDescriptionsV3.2+">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSError.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSFileManager.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyValueCoding.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyValueObserving.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyedArchiver.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSNetServices.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSObject.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSPort.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSRunLoop.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSStream.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSThread.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSURL.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSURLConnection.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSXMLParser.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIAccessibility.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UINibLoading.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier" id="654420027">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIResponder.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIResponder</string>
+ <string key="superclassName">NSObject</string>
+ <reference key="sourceIdentifier" ref="654420027"/>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIScrollView</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIScrollView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UISearchBar</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISearchBar.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UISearchDisplayController</string>
+ <string key="superclassName">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISearchDisplayController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UITableView</string>
+ <string key="superclassName">UIScrollView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITableView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UITableViewController</string>
+ <string key="superclassName">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITableViewController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITextField.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <string key="superclassName">UIResponder</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UINavigationController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITabBarController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <string key="superclassName">UIResponder</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIViewController.h</string>
+ </object>
+ </object>
+ </object>
+ </object>
+ <int key="IBDocument.localizationMode">0</int>
+ <string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
+ <integer value="784" key="NS.object.0"/>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
+ <integer value="3100" key="NS.object.0"/>
+ </object>
+ <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+ <string key="IBDocument.LastKnownRelativeProjectPath">NavApp3.xcodeproj</string>
+ <int key="IBDocument.defaultPropertyAccessControl">3</int>
+ <string key="IBCocoaTouchPluginVersion">81</string>
+ </data>
+</archive>
diff --git a/Tests/iOSNavApp/TotalFunction.c b/Tests/iOSNavApp/TotalFunction.c
new file mode 100644
index 000000000..0965a88ac
--- /dev/null
+++ b/Tests/iOSNavApp/TotalFunction.c
@@ -0,0 +1,14 @@
+//
+// TotalFunction.c
+// NavApp3
+//
+// Created by David Cole on 8/10/11.
+// Copyright 2011 Kitware, Inc. All rights reserved.
+//
+
+#include "TotalFunction.h"
+
+int Total(const char *context)
+{
+ return 22;
+}
diff --git a/Tests/iOSNavApp/TotalFunction.h b/Tests/iOSNavApp/TotalFunction.h
new file mode 100644
index 000000000..1301c3d64
--- /dev/null
+++ b/Tests/iOSNavApp/TotalFunction.h
@@ -0,0 +1,14 @@
+//
+// TotalFunction.h
+// NavApp3
+//
+// Created by David Cole on 8/10/11.
+// Copyright 2011 Kitware, Inc. All rights reserved.
+//
+
+#ifndef NavApp3_TotalFunction_h
+#define NavApp3_TotalFunction_h
+
+int Total(const char *context);
+
+#endif
diff --git a/Tests/iOSNavApp/main.m b/Tests/iOSNavApp/main.m
new file mode 100644
index 000000000..8070c4727
--- /dev/null
+++ b/Tests/iOSNavApp/main.m
@@ -0,0 +1,17 @@
+//
+// main.m
+// NavApp3
+//
+// Created by David Cole on 6/23/11.
+// Copyright 2011 Kitware, Inc. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+int main(int argc, char *argv[]) {
+
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+ int retVal = UIApplicationMain(argc, argv, nil, nil);
+ [pool release];
+ return retVal;
+}
diff --git a/Tests/test_clean.cmake.in b/Tests/test_clean.cmake.in
new file mode 100644
index 000000000..ce5e62b79
--- /dev/null
+++ b/Tests/test_clean.cmake.in
@@ -0,0 +1,2 @@
+SET(TEST_BUILD_DIRS "@TEST_BUILD_DIRS@")
+FILE(REMOVE_RECURSE ${TEST_BUILD_DIRS})
diff --git a/Utilities/.NoDartCoverage b/Utilities/.NoDartCoverage
new file mode 100644
index 000000000..3c9972938
--- /dev/null
+++ b/Utilities/.NoDartCoverage
@@ -0,0 +1 @@
+# do not do coverage in this directory
diff --git a/Utilities/.gitattributes b/Utilities/.gitattributes
new file mode 100644
index 000000000..e3a9e6105
--- /dev/null
+++ b/Utilities/.gitattributes
@@ -0,0 +1,2 @@
+/Git export-ignore
+SetupForDevelopment.sh export-ignore
diff --git a/Utilities/CMakeLists.txt b/Utilities/CMakeLists.txt
new file mode 100644
index 000000000..798c16397
--- /dev/null
+++ b/Utilities/CMakeLists.txt
@@ -0,0 +1,158 @@
+#=============================================================================
+# 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.
+#=============================================================================
+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.docbook
+ ${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
+ )
+
+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
+ ${CMake_BINARY_DIR}/Docs/${target}.docbook
+ )
+ LIST(APPEND HTML_FILES ${CMake_BINARY_DIR}/Docs/${target}.html)
+ ENDIF(CMD)
+ENDMACRO(ADD_DOCS target dependency)
+
+# Help cmake-gui find the Qt DLLs on Windows.
+SET(WIN_SHELL_GENS "Visual Studio|NMake|MinGW|Watcom|Borland")
+IF(BUILD_QtDialog AND "${CMAKE_GENERATOR}" MATCHES "${WIN_SHELL_GENS}"
+ AND EXISTS "${QT_QMAKE_EXECUTABLE}" AND NOT CMAKE_NO_AUTO_QT_ENV)
+ GET_FILENAME_COMPONENT(Qt_BIN_DIR "${QT_QMAKE_EXECUTABLE}" PATH)
+ IF(EXISTS "${Qt_BIN_DIR}/QtCore4.dll")
+ # 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}")
+ ENDIF(EXISTS "${Qt_BIN_DIR}/QtCore4.dll")
+ENDIF(BUILD_QtDialog AND "${CMAKE_GENERATOR}" MATCHES "${WIN_SHELL_GENS}"
+ AND EXISTS "${QT_QMAKE_EXECUTABLE}" AND NOT CMAKE_NO_AUTO_QT_ENV)
+
+# 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(${CMAKE_MAN_DIR}/man1 FILES ${MAN_FILES})
+INSTALL_FILES(${CMAKE_DOC_DIR} FILES ${HTML_FILES} ${TEXT_FILES})
+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 the XHTML DTD and its dependencies in the 'xml'
+ # directory so that xmllint can run without network access.
+ # However, it's --path option accepts a space-separated list of
+ # paths so it cannot handle spaces in the path to the source tree.
+ # Therefore we run the tool with the current work directory set to
+ # the 'xml' directory and use '.' as the path.
+ add_test(CMake.HTML
+ ${CMAKE_CMAKE_COMMAND} -E chdir ${CMAKE_CURRENT_SOURCE_DIR}/xml
+ ${LIBXML2_XMLLINT_EXECUTABLE} --valid --noout --nonet --path .
+ ${HTML_FILES}
+ )
+ endif()
+ endif()
+endif()
diff --git a/Utilities/Doxygen/CMakeLists.txt b/Utilities/Doxygen/CMakeLists.txt
new file mode 100644
index 000000000..2430391fd
--- /dev/null
+++ b/Utilities/Doxygen/CMakeLists.txt
@@ -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.
+#=============================================================================
+
+#
+# Build the documentation
+#
+INCLUDE (${CMAKE_ROOT}/Modules/Documentation.cmake OPTIONAL)
+
+IF (BUILD_DOCUMENTATION)
+
+ #
+ # Configure the script and the doxyfile, then add target
+ #
+ IF(NOT DOT_PATH)
+ GET_FILENAME_COMPONENT(DOT_PATH ${DOT} PATH)
+ ENDIF(NOT DOT_PATH)
+
+ CONFIGURE_FILE(
+ ${CMake_SOURCE_DIR}/Utilities/Doxygen/doxyfile.in
+ ${CMake_BINARY_DIR}/Utilities/Doxygen/doxyfile)
+
+ CONFIGURE_FILE(
+ ${CMake_SOURCE_DIR}/Utilities/Doxygen/doc_makeall.sh.in
+ ${CMake_BINARY_DIR}/Utilities/Doxygen/doc_makeall.sh)
+
+ ADD_CUSTOM_TARGET(DoxygenDoc
+ ${BASH}
+ ${CMake_BINARY_DIR}/Utilities/Doxygen/doc_makeall.sh)
+
+ENDIF (BUILD_DOCUMENTATION)
diff --git a/Utilities/Doxygen/authors.txt b/Utilities/Doxygen/authors.txt
new file mode 100644
index 000000000..9ba6ccac4
--- /dev/null
+++ b/Utilities/Doxygen/authors.txt
@@ -0,0 +1,17 @@
+andy: Cedilnik, Andy (andy.cedilnik@kitware.com)
+barre: Barre, Sebastien (sebastien.barre@kitware.com)
+berk: Geveci, Berk (berk.geveci@kitware.com)
+bettingf: Bettinger, Franck (bettingf@cs.man.ac.uk)
+biddi: Biddiscombe, John (jbiddiscombe@skippingmouse.co.uk)
+blezek: Blezek, Dan (blezek@crd.ge.com)
+geoff: Cross, Geoffrey (geoff@robots.ox.ac.uk)
+hoffman: Hoffman, Bill (bill.hoffman@kitware.com)
+ibanez: Ibanez, Luis (luis.ibanez@kitware.com)
+iscott: Scott, Ian (ian.m.scott@stud.man.ac.uk)
+king: King, Brad (brad.king@kitware.com)
+lorensen: Lorensen, Bill (lorensen@crd.ge.com)
+martink, lymbdemo: Martin, Ken (ken.martin@kitware.com)
+millerjv: Miller, Jim (millerjv@crd.ge.com)
+perera: Perera, Amitha (perera@cs.rpi.edu)
+starreveld: Starreveld, Yves (ystarrev@julian.uwo.ca)
+will, schroede: Schroeder, Will (will.schroeder@kitware.com)
diff --git a/Utilities/Doxygen/doc_makeall.sh.in b/Utilities/Doxygen/doc_makeall.sh.in
new file mode 100755
index 000000000..a1b00e7d0
--- /dev/null
+++ b/Utilities/Doxygen/doc_makeall.sh.in
@@ -0,0 +1,248 @@
+# -------------------------------------------------------------------------
+# Doxygen documentation batch
+# modified by S. Barre (Time-stamp: <2003-01-16 14:04:41 barre>
+# -------------------------------------------------------------------------
+
+# Path to several tools (_PROG to avoid the typical GZIP env var pb)
+# Example:
+# DOXYGEN_PROG=@DOXYGEN@ (INCLUDE(${CMAKE_ROOT}/Modules/FindDoxygen.cmake))
+# GZIP_PROG=@GZIP@ (INCLUDE(${CMAKE_ROOT}/Modules/FindCygwin.cmake))
+# HHC_PROG=@HHC@ (INCLUDE(${CMAKE_ROOT}/Modules/FindHhc.cmake))
+# MV_PROG=@MV@ (INCLUDE(${CMAKE_ROOT}/Modules/FindCygwin.cmake))
+# PERL_PROG=@PERL@ (INCLUDE(${CMAKE_ROOT}/Modules/FindPerl.cmake))
+# RM_PROG=@RM@ (INCLUDE(${CMAKE_ROOT}/Modules/FindCygwin.cmake))
+# TAR_PROG=@TAR@ (INCLUDE(${CMAKE_ROOT}/Modules/FindCygwin.cmake))
+# WGET_PROG=@WGET@ (INCLUDE(${CMAKE_ROOT}/Modules/FindWget.cmake))
+#
+export DOXYGEN_PROG="@DOXYGEN@" # Doxygen
+export GZIP_PROG="@GZIP@" # gzip (Unix-like 'gzip compressor')
+export GNUPLOT_PROG="@GNUPLOT@" # gnuplot (data plotting program)
+export HHC_PROG="@HTML_HELP_COMPILER@" # HTML Help Compiler
+export MV_PROG="@MV@" # mv (Unix-like 'move/rename files')
+export PERL_PROG="@PERL@" # Perl
+export RM_PROG="@RM@" # rm (Unix-like 'remove files')
+export TAR_PROG="@TAR@" # tar (Unix-like 'archiver')
+export WGET_PROG="@WGET@" # wget (remote file retrieval)
+
+# PROJECT_NAME:
+# Documentation/project name. Used in some of the resulting file names and
+# xrefs to uniquify two or more projects linked together through their
+# Doxygen's tag files. Mandatory for each documentation set.
+# Note: might be the same as the doxyfile's PROJECT_NAME
+# Example:
+# PROJECT_NAME=VTK
+#
+export PROJECT_NAME=CMake
+
+# PATH_TO_VTK_DOX_SCRIPTS:
+# Path to the directory holding the Perl scripts used to produce the VTK doc
+# in Doxygen format. You need the VTK source files or a local copy of
+# these scripts.
+# Example:
+# PATH_TO_VTK_DOX_SCRIPTS=@VTK_SOURCE_DIR@/Utilities/Doxygen
+#
+export PATH_TO_VTK_DOX_SCRIPTS="@VTK_SOURCE_DIR@/Utilities/Doxygen"
+
+# SOURCE_DIR:
+# Source directory. The top directory of the source files.
+# Example:
+# SOURCE_DIR=@VTK_SOURCE_DIR@
+#
+export SOURCE_DIR="@CMake_SOURCE_DIR@"
+
+# REL_PATH_TO_TOP:
+# Relative path from the top directory of the source files to the directory
+# (or top directory) holding the files to document. Useful if several parts
+# of the same source directory should be documented separately.
+# Example:
+# REL_PATH_TO_TOP=.
+# REL_PATH_TO_TOP=framework/src
+#
+# export REL_PATH_TO_TOP=Source
+export REL_PATH_TO_TOP=.
+
+# INTERMEDIATE_DOX_DIR:
+# Directory where the intermediate Doxygen files should be stored (mainly
+# these headers files converted from the VTK format to the Doxygen format).
+# This directory is erased at the end of this script, unless you comment
+# the corresponding line.
+# DOXTEMP might be used to simplify the syntax.
+# Example:
+# DOXTEMP=DOXTEMP=@VTK_BINARY_DIR@/Utilities/Doxygen
+# INTERMEDIATE_DOX_DIR=$DOXTEMP/dox
+#
+export DOXTEMP="@CMake_BINARY_DIR@/Utilities/Doxygen"
+export INTERMEDIATE_DOX_DIR="$DOXTEMP/dox"
+
+# DOXYFILE:
+# Path to the Doxygen configuration file (i.e. doxyfile).
+# Example:
+# DOXYFILE=$DOXTEMP/doxyfile
+#
+export DOXYFILE="$DOXTEMP/doxyfile"
+
+# OUTPUT_DIRECTORY ALLOW_ERASE_OUTPUT_DIRECTORY:
+# Path to the Doxygen output directory (where the resulting doc is stored).
+# Note: should be the same as your doxyfile's OUTPUT_DIRECTORY
+# If ON, allows the output directory to be erased when some advanced output
+# file have been produced (HTML Help, or TAR archive for example).
+# Example:
+# OUTPUT_DIRECTORY=$DOXTEMP/doc
+# ALLOW_ERASE_OUTPUT_DIRECTORY=ON
+#
+export OUTPUT_DIRECTORY="$DOXTEMP/doc"
+export ALLOW_ERASE_OUTPUT_DIRECTORY=ON
+
+# COMPILE_HTML_HELP RESULTING_HTML_HELP_FILE:
+# Compile the CHM (Compressed HTML) HTML Help file, name of the resulting
+# file. If set to ON and name is non-empty these options will actually
+# trigger the HTML-Help compiler to create the CHM. The resulting
+# file (usually index.chm) will be renamed to this name.
+# Note: if ON, the whole $OUTPUT_DIRECTORY will be erased at the end of
+# this script, since this file is considered to be one of the
+# advanced final output, unless ALLOW_ERASE_OUTPUT_DIRECTORY is OFF
+# Note: your doxyfile should be configured to enable HTML Help creation
+# (using GENERATE_HTML = YES, GENERATE_HTMLHELP = YES)
+# Example:
+# COMPILE_HTML_HELP=ON
+# COMPILE_HTML_HELP=@DOCUMENTATION_HTML_HELP@
+# RESULTING_HTML_HELP_FILE=$DOXTEMP/vtk4.chm
+#
+export COMPILE_HTML_HELP=@DOCUMENTATION_HTML_HELP@
+export RESULTING_HTML_HELP_FILE="$DOXTEMP/$PROJECT_NAME.chm"
+
+# CREATE_HTML_TARZ_ARCHIVE RESULTING_HTML_TARZ_ARCHIVE_FILE:
+# Create a compressed (gzip) tar archive of the html directory (located
+# under the OUTPUT_DIRECTORY), and name of the resulting archive file.
+# Note: your doxyfile should be configured to enable HTML creation
+# (using GENERATE_HTML = YES)
+# Example:
+# CREATE_HTML_TARZ_ARCHIVE=ON
+# CREATE_HTML_TARZ_ARCHIVE=@DOCUMENTATION_HTML_TARZ@
+# RESULTING_HTML_TARZ_ARCHIVE_FILE=$DOXTEMP/vtk4-html.tar.gz
+# RESULTING_HTML_TARZ_ARCHIVE_FILE=$DOXTEMP/$PROJECT_NAME-html.tar.gz
+#
+export CREATE_HTML_TARZ_ARCHIVE=@DOCUMENTATION_HTML_TARZ@
+export RESULTING_HTML_TARZ_ARCHIVE_FILE="$DOXTEMP/$PROJECT_NAME-html.tar.gz"
+
+# ----------------------------------------------------------------------------
+# Build the contributors list.
+
+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" \
+ --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)$' \
+ --files_in '(?:^hints|dummy|README|^Makefile\.borland|\.(?:c|cmake|cpp|cxx|h|html|in|java|fl|pl|py|tcl|txt))$' \
+ --files_out '(?:^ChangeLog\.txt)$' \
+ --gnuplot_file "$DOXTEMP/contrib/history.plt" \
+ --history_img "|lines|$DOXTEMP/contrib/history.png" \
+ --history_img "365|lines|$DOXTEMP/contrib/history2y.png" \
+ --history_img "180|linespoints|$DOXTEMP/contrib/history6m.png" \
+ --history_dir "$DOXTEMP/contrib" \
+ --history_max_nb 10 \
+ --lines_add 1.0 \
+ --lines_rem 0.5 \
+ --massive 50 \
+ --max_class_nb 10 \
+ --max_file_nb 5 \
+ --min_class 0.02 \
+ --min_file 0.01 \
+ --min_contrib 0.05 \
+ --min_gcontrib 0.0001 \
+ --store "doc_""$PROJECT_NAME""_contributors.dox" \
+ --relativeto "$SOURCE_DIR/$REL_PATH_TO_TOP" \
+ --to "$INTERMEDIATE_DOX_DIR" \
+ "$SOURCE_DIR/$REL_PATH_TO_TOP"
+ fi
+
+ if test "x$GNUPLOT_PROG" != "xNOTFOUND" ; then
+ $GNUPLOT_PROG "$DOXTEMP/contrib/history.plt"
+ fi
+fi
+
+# ----------------------------------------------------------------------------
+# Create the Doxygen doc.
+
+if test "x$DOXYGEN_PROG" != "xNOTFOUND" ; then
+
+ if test "x$RM_PROG" != "xNOTFOUND" ; then
+ $RM_PROG -fr "$OUTPUT_DIRECTORY"
+ fi
+
+ "$DOXYGEN_PROG" "$DOXYFILE"
+
+ # yes, a second time, to get the contrib, I don't know why
+ "$DOXYGEN_PROG" "$DOXYFILE"
+fi
+
+# ----------------------------------------------------------------------------
+# Clean the HTML pages to remove the path to the intermediate Doxygen dir.
+
+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" \
+ --verbose \
+ --to "$INTERMEDIATE_DOX_DIR" \
+ --html "$OUTPUT_DIRECTORY/html"
+ fi
+fi
+
+# ----------------------------------------------------------------------------
+# Create the CHM HTML HELP doc.
+
+if test "x$COMPILE_HTML_HELP" == "xON" ; then
+ if test "x$RESULTING_HTML_HELP_FILE" != "x" ; then
+ cd $OUTPUT_DIRECTORY/html
+ 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"
+ fi
+ fi
+ fi
+fi
+
+# ----------------------------------------------------------------------------
+# Create the compressed tar archive.
+
+if test "x$CREATE_HTML_TARZ_ARCHIVE" == "xON" ; then
+ if test "x$RESULTING_HTML_TARZ_ARCHIVE_FILE" != "x" ; then
+ cd "$OUTPUT_DIRECTORY"
+ if test "x$TAR_PROG" != "xNOTFOUND" ; then
+ if test "x$RM_PROG" != "xNOTFOUND" ; then
+ $RM_PROG -f html.tar
+ fi
+ $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
+ fi
+ $GZIP_PROG html.tar
+ $MV_PROG -f html.tar.gz "$RESULTING_HTML_TARZ_ARCHIVE_FILE"
+ fi
+ fi
+ fi
+fi
+
+# ----------------------------------------------------------------------------
+# Clean-up.
+
+if test "x$RM_PROG" != "xNOTFOUND" ; then
+ $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"
+ 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"
+ fi
+ fi
+ fi
+fi
diff --git a/Utilities/Doxygen/doxyfile.in b/Utilities/Doxygen/doxyfile.in
new file mode 100644
index 000000000..9743af721
--- /dev/null
+++ b/Utilities/Doxygen/doxyfile.in
@@ -0,0 +1,79 @@
+# -------------------------------------------------------------------------
+# doxyfile for CMake
+# modified by S. Barre (Time-stamp: <2002-02-13 18:24:35 barre>
+# -------------------------------------------------------------------------
+
+PROJECT_NAME = CMake
+
+FULL_PATH_NAMES = YES
+WARN_IF_UNDOCUMENTED = NO
+
+GENERATE_TREEVIEW = NO
+GENERATE_TODOLIST = YES
+GENERATE_BUGLIST = YES
+GENERATE_HTML = YES
+GENERATE_HTMLHELP = YES
+GENERATE_LATEX = NO
+GENERATE_MAN = NO
+GENERATE_RTF = NO
+
+HAVE_DOT = YES
+#HAVE_DOT = NO
+DOT_PATH = "@DOT_PATH@"
+CLASS_GRAPH = YES
+COLLABORATION_GRAPH = YES
+TEMPLATE_RELATIONS = YES
+INCLUDE_GRAPH = YES
+INCLUDED_BY_GRAPH = YES
+CLASS_DIAGRAMS = YES
+GENERATE_LEGEND = YES
+GRAPHICAL_HIERARCHY = YES
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION = YES
+
+ALLEXTERNALS = NO
+
+IMAGE_PATH = "@CMake_BINARY_DIR@/Utilities/Doxygen/contrib"
+
+OUTPUT_DIRECTORY = "@CMake_BINARY_DIR@/Utilities/Doxygen/doc"
+
+INPUT = \
+ "@CMake_SOURCE_DIR@/Source" \
+ "@CMake_SOURCE_DIR@/Source/CPack" \
+ "@CMake_SOURCE_DIR@/Source/CTest" \
+ "@CMake_SOURCE_DIR@/Source/CursesDialog" \
+ "@CMake_SOURCE_DIR@/Source/MFCDialog" \
+ "@CMake_BINARY_DIR@/Source/kwsys" \
+ "@CMake_BINARY_DIR@/Source/cmsys" \
+ "@CMake_BINARY_DIR@/Utilities/Doxygen/dox/doc_CMake_contributors.dox" \
+
+EXTRACT_ALL = YES
+EXTRACT_PRIVATE = NO
+EXTRACT_STATIC = YES
+HIDE_UNDOC_MEMBERS = NO
+HIDE_UNDOC_CLASSES = YES
+ALWAYS_DETAILED_SEC = NO
+SOURCE_BROWSER = YES
+INLINE_SOURCES = NO
+CASE_SENSE_NAMES = YES
+VERBATIM_HEADERS = NO
+SHOW_INCLUDE_FILES = YES
+JAVADOC_AUTOBRIEF = YES
+SORT_MEMBER_DOCS = NO
+DISTRIBUTE_GROUP_DOC = YES
+TAB_SIZE = 3
+
+FILE_PATTERNS = *.h *.hxx *.cxx
+RECURSIVE = NO
+EXCLUDE_PATTERNS =
+
+HTML_ALIGN_MEMBERS = YES
+ALPHABETICAL_INDEX = YES
+COLS_IN_ALPHA_INDEX = 3
+IGNORE_PREFIX = cm
+
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = YES
+SEARCH_INCLUDES = YES
+INCLUDE_PATH =
+EXPAND_ONLY_PREDEF = YES
diff --git a/Utilities/Git/commit-msg b/Utilities/Git/commit-msg
new file mode 100755
index 000000000..9a5d1c1b3
--- /dev/null
+++ b/Utilities/Git/commit-msg
@@ -0,0 +1,23 @@
+#!/usr/bin/env bash
+#=============================================================================
+# 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.
+#=============================================================================
+
+die() {
+ echo 'commit-msg hook failure' 1>&2
+ echo '-----------------------' 1>&2
+ echo '' 1>&2
+ echo "$@" 1>&2
+ exit 1
+}
+
+# This is a placeholder for future commit-msg checks.
+exit 0
diff --git a/Utilities/Git/pre-commit b/Utilities/Git/pre-commit
new file mode 100755
index 000000000..d308a81b5
--- /dev/null
+++ b/Utilities/Git/pre-commit
@@ -0,0 +1,67 @@
+#!/usr/bin/env bash
+#=============================================================================
+# 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.
+#=============================================================================
+
+die() {
+ echo 'pre-commit hook failure' 1>&2
+ echo '-----------------------' 1>&2
+ echo '' 1>&2
+ echo "$@" 1>&2
+ exit 1
+}
+
+#-------------------------------------------------------------------------------
+line_too_long=80
+bad=$(regex=".{$line_too_long}" &&
+git diff-index --cached HEAD --name-only --diff-filter=AM \
+ --pickaxe-regex -S"$regex" -- 'Source/*.h' 'Source/*.cxx' |
+while read file; do
+ lines_too_long=$(git diff-index -p --cached HEAD \
+ --pickaxe-regex -S"$regex" -- "$file")
+ if echo "$lines_too_long" | egrep -q '^\+'"$regex"; then
+ echo "$lines_too_long"
+ fi
+done)
+test -z "$bad" ||
+die 'The following changes add lines too long for our C++ style:
+
+'"$bad"'
+
+Use lines strictly less than '"$line_too_long"' characters in C++ code.'
+
+#-------------------------------------------------------------------------------
+if test -z "$HOOKS_ALLOW_KWSYS"; then
+ # Disallow changes to KWSys
+ files=$(git diff-index --name-only --cached HEAD -- Source/kwsys) &&
+ if test -n "$files"; then
+ die 'Changes to KWSys files
+
+'"$(echo "$files" | sed 's/^/ /')"'
+
+cannot be committed through Git. KWSys is kept in a CVS repository
+shared by several projects. A robot replays changes committed there
+into the Source/kwsys directory in CMake. Please send changes to
+this directory separately. Run
+
+ git reset HEAD -- Source/kwsys
+
+to unstage these changes and then
+
+ git diff -- Source/kwsys > kwsys.patch
+
+to construct the patch. Alternatively, set environment variable
+
+ HOOKS_ALLOW_KWSYS=1
+
+to disable this check and commit the changes locally.'
+ fi
+fi
diff --git a/Utilities/Git/prepare-commit-msg b/Utilities/Git/prepare-commit-msg
new file mode 100755
index 000000000..1517bb2db
--- /dev/null
+++ b/Utilities/Git/prepare-commit-msg
@@ -0,0 +1,15 @@
+#!/usr/bin/env bash
+#=============================================================================
+# 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.
+#=============================================================================
+
+# This is a placeholder for future prepare-commit-msg hooks.
+exit 0
diff --git a/Utilities/GitSetup/.gitattributes b/Utilities/GitSetup/.gitattributes
new file mode 100644
index 000000000..facbbb21c
--- /dev/null
+++ b/Utilities/GitSetup/.gitattributes
@@ -0,0 +1,7 @@
+.git* export-ignore
+
+# Exclude from source archives files specific to Git work tree.
+* export-ignore
+
+tips eol=lf whitespace=indent-with-non-tab
+setup-* eol=lf whitespace=indent-with-non-tab
diff --git a/Utilities/GitSetup/LICENSE b/Utilities/GitSetup/LICENSE
new file mode 100644
index 000000000..d64569567
--- /dev/null
+++ b/Utilities/GitSetup/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/Utilities/GitSetup/NOTICE b/Utilities/GitSetup/NOTICE
new file mode 100644
index 000000000..0d32c02eb
--- /dev/null
+++ b/Utilities/GitSetup/NOTICE
@@ -0,0 +1,5 @@
+Kitware Local Git Setup Scripts
+Copyright 2010-2012 Kitware, Inc.
+
+This product includes software developed at Kitware, Inc.
+(http://www.kitware.com/).
diff --git a/Utilities/GitSetup/README b/Utilities/GitSetup/README
new file mode 100644
index 000000000..cf468fb68
--- /dev/null
+++ b/Utilities/GitSetup/README
@@ -0,0 +1,80 @@
+Kitware Local Git Setup Scripts
+
+
+Introduction
+------------
+
+This is a collection of local Git development setup scripts meant for
+inclusion in project source trees to aid their development workflow.
+Project-specific information needed by the scripts may be configured
+in a "config" file added next to them in the project.
+
+
+Import
+------
+
+A project may import these scripts into their source tree by
+initializing a subtree merge. Bring up a Git prompt and set the
+current working directory inside a clone of the target project.
+Fetch the "setup" branch from the GitSetup repository:
+
+ $ git fetch ../GitSetup setup:setup
+
+Prepare to merge the branch but place the content in a subdirectory.
+Any prefix (with trailing '/') may be chosen so long as it is used
+consistently within a project through the rest of these instructions:
+
+ $ git merge -s ours --no-commit setup
+ $ git read-tree -u --prefix=Utilities/GitSetup/ setup
+
+Commit the merge with an informative message:
+
+ $ git commit
+ ------------------------------------------------------------------------
+ Merge branch 'setup'
+
+ Add Utilities/GitSetup/ directory using subtree merge from
+ the general GitSetup repository "setup" branch.
+ ------------------------------------------------------------------------
+
+
+Configuration
+-------------
+
+Read the "Project configuration instructions" comment in each script.
+Add a "config" file next to the scripts with desired configuration
+(optionally copy and modify "config.sample"). For example, to
+configure the "setup-hooks" script:
+
+ $ git config -f Utilities/GitSetup/config hooks.url "$url"
+
+where "$url" is the project repository publishing the "hooks" branch.
+When finished, add and commit the configuration file:
+
+ $ git add Utilities/GitSetup/config
+ $ git commit
+
+
+Update
+------
+
+A project may update these scripts from the GitSetup repository.
+Bring up a Git prompt and set the current working directory inside a
+clone of the target project. Fetch the "setup" branch from the
+GitSetup repository:
+
+ $ git fetch ../GitSetup setup:setup
+
+Merge the "setup" branch into the subtree:
+
+ $ git merge -X subtree=Utilities/GitSetup setup
+
+where "Utilities/GitSetup" is the same prefix used during the import
+setup, but without a trailing '/'.
+
+
+License
+-------
+
+Distributed under the Apache License 2.0.
+See LICENSE and NOTICE for details.
diff --git a/Utilities/GitSetup/config b/Utilities/GitSetup/config
new file mode 100644
index 000000000..b7d54235c
--- /dev/null
+++ b/Utilities/GitSetup/config
@@ -0,0 +1,9 @@
+[hooks]
+ url = http://cmake.org/cmake.git
+[ssh]
+ host = cmake.org
+ key = id_git_cmake
+ request-url = https://www.kitware.com/Admin/SendPassword.cgi
+[stage]
+ url = git://cmake.org/stage/cmake.git
+ pushurl = git@cmake.org:stage/cmake.git
diff --git a/Utilities/GitSetup/config.sample b/Utilities/GitSetup/config.sample
new file mode 100644
index 000000000..bba2382c3
--- /dev/null
+++ b/Utilities/GitSetup/config.sample
@@ -0,0 +1,22 @@
+# Kitware Local Git Setup Scripts - Sample Project Configuration
+#
+# Copy to "config" and edit as necessary.
+
+[hooks]
+ url = http://public.kitware.com/GitSetup.git
+ #branch = hooks
+
+[ssh]
+ host = public.kitware.com
+ key = id_git_public
+ request-url = https://www.kitware.com/Admin/SendPassword.cgi
+
+[stage]
+ #url = git://public.kitware.com/stage/Project.git
+ #pushurl = git@public.kitware.com:stage/Project.git
+
+[gerrit]
+ #project = Project
+ site = http://review.source.kitware.com
+ # pushurl placeholder "$username" is literal
+ pushurl = $username@review.source.kitware.com:Project
diff --git a/Utilities/GitSetup/setup-gerrit b/Utilities/GitSetup/setup-gerrit
new file mode 100755
index 000000000..9e8fa6237
--- /dev/null
+++ b/Utilities/GitSetup/setup-gerrit
@@ -0,0 +1,142 @@
+#!/usr/bin/env bash
+#=============================================================================
+# Copyright 2010-2012 Kitware, Inc.
+#
+# 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.
+#=============================================================================
+
+# Run this script to set up the local Git repository to push to
+# a Gerrit Code Review instance for this project.
+
+# Project configuration instructions:
+#
+# - Run a Gerrit Code Review server
+#
+# - Populate adjacent "config" file with:
+# gerrit.site = Top Gerrit URL (not project-specific)
+# gerrit.project = Name of project in Gerrit
+# gerrit.pushurl = Review site push URL with "$username" placeholder
+# gerrit.remote = Gerrit remote name, if not "gerrit"
+# gerrit.url = Gerrit project URL, if not "$site/p/$project"
+
+die() {
+ echo 1>&2 "$@" ; exit 1
+}
+
+# Make sure we are inside the repository.
+cd "${BASH_SOURCE%/*}" &&
+
+# Load the project configuration.
+site=$(git config -f config --get gerrit.site) &&
+project=$(git config -f config --get gerrit.project) &&
+pushurl_=$(git config -f config --get gerrit.pushurl) &&
+remote=$(git config -f config --get gerrit.remote ||
+ echo "gerrit") &&
+fetchurl=$(git config -f config --get gerrit.url ||
+ echo "$site/p/$project") ||
+die 'This project is not configured to use Gerrit.'
+
+# Get current gerrit push URL.
+pushurl=$(git config --get remote."$remote".pushurl ||
+ git config --get remote."$remote".url || echo '') &&
+
+# Tell user about current configuration.
+if test -n "$pushurl"; then
+ echo 'Remote "'"$remote"'" is currently configured to push to
+
+ '"$pushurl"'
+' &&
+ read -ep 'Reconfigure Gerrit? [y/N]: ' ans &&
+ if [ "$ans" == "y" ] || [ "$ans" == "Y" ]; then
+ setup=1
+ else
+ setup=''
+ fi
+else
+ echo 'Remote "'"$remote"'" is not yet configured.
+
+'"$project"' changes must be pushed to our Gerrit Code Review site:
+
+ '"$fetchurl"'
+
+Register a Gerrit account and select a username (used below).
+You will need an OpenID:
+
+ http://openid.net/get-an-openid/
+' &&
+ read -ep 'Configure Gerrit? [Y/n]: ' ans &&
+ if [ "$ans" == "n" ] || [ "$ans" == "N" ]; then
+ exit 0
+ else
+ setup=1
+ fi
+fi &&
+
+# Perform setup if necessary.
+if test -n "$setup"; then
+ echo 'Sign-in to Gerrit to get/set your username at
+
+ '"$site"'/#/settings
+
+Add your SSH public keys at
+
+ '"$site"'/#/settings/ssh-keys
+' &&
+ read -ep "Gerrit username? [$USER]: " gu &&
+ if test -z "$gu"; then
+ gu="$USER"
+ fi &&
+ if test -z "$pushurl"; then
+ git remote add "$remote" "$fetchurl"
+ else
+ git config remote."$remote".url "$fetchurl"
+ fi &&
+ pushurl="${pushurl_/\$username/$gu}" &&
+ git config remote."$remote".pushurl "$pushurl" &&
+ echo 'Remote "'"$remote"'" is now configured to push to
+
+ '"$pushurl"'
+'
+fi &&
+
+# Optionally test Gerrit access.
+if test -n "$pushurl"; then
+ read -ep 'Test access to Gerrit (SSH)? [y/N]: ' ans &&
+ if [ "$ans" == "y" ] || [ "$ans" == "Y" ]; then
+ echo -n 'Testing Gerrit access by SSH...'
+ if git ls-remote --heads "$pushurl" >/dev/null; then
+ echo 'passed.'
+ else
+ echo 'failed.' &&
+ die 'Could not access Gerrit. Add your SSH public keys at
+
+ '"$site"'/#/settings/ssh-keys
+'
+ fi
+ fi
+fi &&
+
+# Set up GerritId hook.
+hook=$(git config --get hooks.GerritId || echo '') &&
+if test -z "$hook"; then
+ echo '
+Enabling GerritId hook to add a "Change-Id" footer to commit
+messages for interaction with Gerrit. Run
+
+ git config hooks.GerritId false
+
+to disable this feature (but you will be on your own).' &&
+ git config hooks.GerritId true
+else
+ echo 'GerritId hook already configured to "'"$hook"'".'
+fi
diff --git a/Utilities/GitSetup/setup-hooks b/Utilities/GitSetup/setup-hooks
new file mode 100755
index 000000000..c07985ae5
--- /dev/null
+++ b/Utilities/GitSetup/setup-hooks
@@ -0,0 +1,63 @@
+#!/usr/bin/env bash
+#=============================================================================
+# Copyright 2010-2012 Kitware, Inc.
+#
+# 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.
+#=============================================================================
+
+# Run this script to set up local Git hooks for this project.
+
+# Project configuration instructions:
+#
+# - Publish a "hooks" branch in the project repository such that
+# clones will have "refs/remotes/origin/hooks".
+#
+# - Populate adjacent "config" file with:
+# hooks.url = Repository URL publishing "hooks" branch
+# hooks.branch = Repository branch instead of "hooks"
+
+egrep-q() {
+ egrep "$@" >/dev/null 2>/dev/null
+}
+
+die() {
+ echo 1>&2 "$@" ; exit 1
+}
+
+# Make sure we are inside the repository.
+cd "${BASH_SOURCE%/*}" &&
+
+# Select a hooks branch.
+if url=$(git config --get hooks.url); then
+ # Fetch hooks from locally configured repository.
+ branch=$(git config hooks.branch || echo hooks)
+elif git for-each-ref refs/remotes/origin/hooks 2>/dev/null |
+ egrep-q 'refs/remotes/origin/hooks$'; then
+ # Use hooks cloned from origin.
+ url=.. && branch=remotes/origin/hooks
+elif url=$(git config -f config --get hooks.url); then
+ # Fetch hooks from project-configured repository.
+ branch=$(git config -f config hooks.branch || echo hooks)
+else
+ die 'This project is not configured to install local hooks.'
+fi &&
+
+# Populate ".git/hooks".
+echo 'Setting up git hooks...' &&
+git_dir=$(git rev-parse --git-dir) &&
+cd "$git_dir/hooks" &&
+if ! test -e .git; then
+ git init -q || die 'Could not run git init for hooks.'
+fi &&
+git fetch -q "$url" "$branch" &&
+git reset -q --hard FETCH_HEAD || die 'Failed to install hooks'
diff --git a/Utilities/GitSetup/setup-ssh b/Utilities/GitSetup/setup-ssh
new file mode 100755
index 000000000..8920a5bd3
--- /dev/null
+++ b/Utilities/GitSetup/setup-ssh
@@ -0,0 +1,111 @@
+#!/usr/bin/env bash
+#=============================================================================
+# Copyright 2010-2012 Kitware, Inc.
+#
+# 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.
+#=============================================================================
+
+# Run this script to set up ssh push access to the repository host.
+
+# Project configuration instructions:
+#
+# - Populate adjacent "config" file with:
+# ssh.host = Repository host name
+# ssh.user = Username on host, if not "git"
+# ssh.key = Local ssh key name
+# ssh.request-url = Web page URL to request ssh access
+
+egrep-q() {
+ egrep "$@" >/dev/null 2>/dev/null
+}
+
+die() {
+ echo 1>&2 "$@" ; exit 1
+}
+
+# Make sure we are inside the repository.
+cd "${BASH_SOURCE%/*}" &&
+
+# Load the project configuration.
+host=$(git config -f config --get ssh.host) &&
+user=$(git config -f config --get ssh.user || echo git) &&
+key=$(git config -f config --get ssh.key) &&
+request_url=$(git config -f config --get ssh.request-url) ||
+die 'This project is not configured for ssh push access.'
+
+# Check for existing configuration.
+if test -r ~/.ssh/config &&
+ egrep-q 'Host[= ]'"${host//\./\\.}" ~/.ssh/config; then
+ echo 'Host "'"$host"'" is already in ~/.ssh/config' &&
+ setup= &&
+ question='Test'
+else
+ echo 'Host "'"$host"'" not found in ~/.ssh/config' &&
+ setup=1 &&
+ question='Setup and test'
+fi &&
+
+# Ask the user whether to make changes.
+echo '' &&
+read -ep "${question} push access by ssh to $user@$host? [y/N]: " access &&
+if test "$access" != "y" -a "$access" != "Y"; then
+ exit 0
+fi &&
+
+# Setup host configuration if necessary.
+if test -n "$setup"; then
+ if ! test -d ~/.ssh; then
+ mkdir -p ~/.ssh &&
+ chmod 700 ~/.ssh
+ fi &&
+ if ! test -f ~/.ssh/config; then
+ touch ~/.ssh/config &&
+ chmod 600 ~/.ssh/config
+ fi &&
+ ssh_config='Host='"$host"'
+ IdentityFile ~/.ssh/'"$key" &&
+ echo "Adding to ~/.ssh/config:
+
+$ssh_config
+" &&
+ echo "$ssh_config" >> ~/.ssh/config &&
+ if ! test -e ~/.ssh/"$key"; then
+ if test -f ~/.ssh/id_rsa; then
+ # Take care of the common case.
+ ln -s id_rsa ~/.ssh/"$key"
+ echo '
+Assuming ~/.ssh/id_rsa is the private key corresponding to the public key for
+
+ '"$user@$host"'
+
+If this is incorrect place private key at "~/.ssh/'"$key"'".'
+ else
+ echo '
+Place the private key corresponding to the public key registered for
+
+ '"$user@$host"'
+
+at "~/.ssh/'"$key"'".'
+ fi
+ read -e -n 1 -p 'Press any key to continue...'
+ fi
+fi || exit 1
+
+# Test access configuration.
+echo 'Testing ssh push access to "'"$user@$host"'"...' &&
+if ! ssh "$user@$host" info; then
+ die 'No ssh push access to "'"$user@$host"'". You may need to request access at
+
+ '"$request_url"'
+'
+fi
diff --git a/Utilities/GitSetup/setup-stage b/Utilities/GitSetup/setup-stage
new file mode 100755
index 000000000..323e47aea
--- /dev/null
+++ b/Utilities/GitSetup/setup-stage
@@ -0,0 +1,79 @@
+#!/usr/bin/env bash
+#=============================================================================
+# Copyright 2010-2012 Kitware, Inc.
+#
+# 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.
+#=============================================================================
+
+# Run this script to set up the topic stage for pushing changes.
+
+# Project configuration instructions:
+#
+# - Run a Topic Stage repository next to the main project repository.
+#
+# - Populate adjacent "config" file with:
+# stage.url = Topic Stage repository URL
+# stage.pushurl = Topic Stage push URL if not "$url"
+
+egrep-q() {
+ egrep "$@" >/dev/null 2>/dev/null
+}
+
+die() {
+ echo 1>&2 "$@" ; exit 1
+}
+
+# Make sure we are inside the repository.
+cd "${BASH_SOURCE%/*}" &&
+
+# Load the project configuration.
+fetchurl=$(git config -f config --get stage.url) &&
+pushurl_=$(git config -f config --get stage.pushurl || echo '') &&
+remote=$(git config -f config --get stage.remote || echo 'stage') ||
+die 'This project is not configured to use a topic stage.'
+
+# Get current stage push URL.
+pushurl=$(git config --get remote."$remote".pushurl ||
+ git config --get remote."$remote".url || echo '') &&
+
+# Tell user about current configuration.
+if test -n "$pushurl"; then
+ echo 'Remote "'"$remote"'" is currently configured to push to
+
+ '"$pushurl"'
+' &&
+ read -ep 'Reconfigure Topic Stage? [y/N]: ' ans &&
+ if [ "$ans" == "y" ] || [ "$ans" == "Y" ]; then
+ setup=1
+ else
+ setup=''
+ fi
+else
+ setup=1
+fi
+
+# Perform setup if necessary.
+if test -n "$setup"; then
+ echo 'Setting up the topic stage...' &&
+ if test -z "$pushurl"; then
+ git remote add "$remote" "$fetchurl"
+ else
+ git config remote."$remote".url "$fetchurl"
+ fi &&
+ pushurl="${pushurl_}" &&
+ git config remote."$remote".pushurl "$pushurl" &&
+ echo 'Remote "'"$remote"'" is now configured to push to
+
+ '"$pushurl"'
+'
+fi || die 'Could not configure the topic stage remote.'
diff --git a/Utilities/GitSetup/setup-user b/Utilities/GitSetup/setup-user
new file mode 100755
index 000000000..1af439c45
--- /dev/null
+++ b/Utilities/GitSetup/setup-user
@@ -0,0 +1,39 @@
+#!/usr/bin/env bash
+#=============================================================================
+# Copyright 2010-2012 Kitware, Inc.
+#
+# 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.
+#=============================================================================
+
+# Run this script to configure Git user info in this repository.
+
+# Project configuration instructions: NONE
+
+for (( ; ; )); do
+ user_name=$(git config user.name || echo '') &&
+ user_email=$(git config user.email || echo '') &&
+ if test -n "$user_name" -a -n "$user_email"; then
+ echo 'Your commits will record as Author:
+
+ '"$user_name <$user_email>"'
+' &&
+ read -ep 'Is the author name and email address above correct? [Y/n] ' correct &&
+ if test "$correct" != "n" -a "$correct" != "N"; then
+ break
+ fi
+ fi &&
+ read -ep 'Enter your full name e.g. "John Doe": ' name &&
+ read -ep 'Enter your email address e.g. "john@gmail.com": ' email &&
+ git config user.name "$name" &&
+ git config user.email "$email"
+done
diff --git a/Utilities/GitSetup/tips b/Utilities/GitSetup/tips
new file mode 100755
index 000000000..784e1ed89
--- /dev/null
+++ b/Utilities/GitSetup/tips
@@ -0,0 +1,55 @@
+#!/usr/bin/env bash
+#=============================================================================
+# Copyright 2010-2012 Kitware, Inc.
+#
+# 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.
+#=============================================================================
+
+# This script makes optional suggestions for working with Git.
+
+# Project configuration instructions: NONE
+
+egrep-q() {
+ egrep "$@" >/dev/null 2>/dev/null
+}
+
+# Suggest color configuration.
+if test -z "$(git config --get color.ui)"; then
+ echo '
+One may enable color output from Git commands with
+
+ git config --global color.ui auto
+'
+fi
+
+# Suggest bash completion.
+if ! bash -i -c 'echo $PS1' | egrep-q '__git_ps1'; then
+ echo '
+A dynamic, informative Git shell prompt can be obtained by sourcing
+the git bash-completion script in your "~/.bashrc". Set the PS1
+environmental variable as suggested in the comments at the top of the
+bash-completion script. You may need to install the bash-completion
+package from your distribution to obtain it.
+'
+fi
+
+# Suggest merge tool.
+if test -z "$(git config --get merge.tool)"; then
+ echo '
+One may configure Git to load a merge tool with
+
+ git config merge.tool <toolname>
+
+See "git help mergetool" for more information.
+'
+fi
diff --git a/Utilities/KWIML/ABI.h.in b/Utilities/KWIML/ABI.h.in
new file mode 100644
index 000000000..060a520db
--- /dev/null
+++ b/Utilities/KWIML/ABI.h.in
@@ -0,0 +1,478 @@
+/*============================================================================
+ 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(__hpux) && !defined(__GNUC__) /* Old HP: no __HP_cc/__HP_aCC 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
+
+/* 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
new file mode 100644
index 000000000..6a8641adc
--- /dev/null
+++ b/Utilities/KWIML/CMakeLists.txt
@@ -0,0 +1,79 @@
+#=============================================================================
+# 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.
+#=============================================================================
+
+# 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)
+ project(KWIML)
+ include(CTest)
+ mark_as_advanced(BUILD_TESTING)
+endif()
+
+#-----------------------------------------------------------------------------
+get_property(KWIML_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
+foreach(lang ${KWIML_LANGUAGES})
+ set(KWIML_LANGUAGE_${lang} 1)
+endforeach()
+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}")
+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)
+ add_subdirectory(test)
+endif()
diff --git a/Utilities/KWIML/Copyright.txt b/Utilities/KWIML/Copyright.txt
new file mode 100644
index 000000000..c1e5ebc3f
--- /dev/null
+++ b/Utilities/KWIML/Copyright.txt
@@ -0,0 +1,30 @@
+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.
diff --git a/Utilities/KWIML/INT.h.in b/Utilities/KWIML/INT.h.in
new file mode 100644
index 000000000..d2eda6387
--- /dev/null
+++ b/Utilities/KWIML/INT.h.in
@@ -0,0 +1,861 @@
+/*============================================================================
+ 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.txt b/Utilities/KWIML/README.txt
new file mode 100644
index 000000000..6bdf859d9
--- /dev/null
+++ b/Utilities/KWIML/README.txt
@@ -0,0 +1,29 @@
+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/test/CMakeLists.txt b/Utilities/KWIML/test/CMakeLists.txt
new file mode 100644
index 000000000..a2359cce1
--- /dev/null
+++ b/Utilities/KWIML/test/CMakeLists.txt
@@ -0,0 +1,70 @@
+#=============================================================================
+# 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.
+#=============================================================================
+
+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}/%>"
+ )
+
+# 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)
+ set(CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS} -Wno-format")
+ endif()
+endforeach()
+
+if(KWIML_LANGUAGE_C)
+ set(test_srcs test.c)
+else()
+ set(test_srcs test.cxx)
+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_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_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
+ 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})
+
+# 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
+ 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
new file mode 100644
index 000000000..131c81f92
--- /dev/null
+++ b/Utilities/KWIML/test/test.c
@@ -0,0 +1,39 @@
+/*============================================================================
+ 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.
+============================================================================*/
+#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_include_C(void);
+extern int test_include_CXX(void);
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+int main(void)
+{
+ int result = 1;
+#ifdef KWIML_LANGUAGE_C
+ 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_include_CXX() && result;
+#endif
+ return result? 0 : 1;
+}
diff --git a/Utilities/KWIML/test/test.cxx b/Utilities/KWIML/test/test.cxx
new file mode 100644
index 000000000..bf614218a
--- /dev/null
+++ b/Utilities/KWIML/test/test.cxx
@@ -0,0 +1,12 @@
+/*============================================================================
+ 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.c"
diff --git a/Utilities/KWIML/test/test.h b/Utilities/KWIML/test/test.h
new file mode 100644
index 000000000..b87a0e7e9
--- /dev/null
+++ b/Utilities/KWIML/test/test.h
@@ -0,0 +1,37 @@
+/*============================================================================
+ 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)
+*/
+#define KWIML_HEADER(x) KWIML_HEADER0(KWIML_NAMESPACE/x)
+#define KWIML_HEADER0(x) KWIML_HEADER1(x)
+#define KWIML_HEADER1(x) <x>
+
+/* Quiet MS standard library deprecation warnings. */
+#ifndef _CRT_SECURE_NO_DEPRECATE
+# define _CRT_SECURE_NO_DEPRECATE
+#endif
+
+#else
+# error "test.h included multiple times."
+#endif
diff --git a/Utilities/KWIML/test/test_ABI_C.c b/Utilities/KWIML/test/test_ABI_C.c
new file mode 100644
index 000000000..3ca4ad390
--- /dev/null
+++ b/Utilities/KWIML/test/test_ABI_C.c
@@ -0,0 +1,22 @@
+/*============================================================================
+ 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
new file mode 100644
index 000000000..7ede20e09
--- /dev/null
+++ b/Utilities/KWIML/test/test_ABI_CXX.cxx
@@ -0,0 +1,22 @@
+/*============================================================================
+ 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
new file mode 100644
index 000000000..992baeaeb
--- /dev/null
+++ b/Utilities/KWIML/test/test_ABI_endian.h.in
@@ -0,0 +1,47 @@
+/*============================================================================
+ 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
new file mode 100644
index 000000000..5513a0bd8
--- /dev/null
+++ b/Utilities/KWIML/test/test_INT_C.c
@@ -0,0 +1,22 @@
+/*============================================================================
+ 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
new file mode 100644
index 000000000..9f74e9680
--- /dev/null
+++ b/Utilities/KWIML/test/test_INT_CXX.cxx
@@ -0,0 +1,22 @@
+/*============================================================================
+ 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
new file mode 100644
index 000000000..71b443d6e
--- /dev/null
+++ b/Utilities/KWIML/test/test_INT_format.h.in
@@ -0,0 +1,200 @@
+/*============================================================================
+ 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_include_C.c b/Utilities/KWIML/test/test_include_C.c
new file mode 100644
index 000000000..fb3e4cf7f
--- /dev/null
+++ b/Utilities/KWIML/test/test_include_C.c
@@ -0,0 +1,22 @@
+/*============================================================================
+ 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>
+
+/* Test KWIML header inclusion after above system headers. */
+#include "test.h"
+#include KWIML_HEADER(ABI.h)
+#include KWIML_HEADER(INT.h)
+
+int test_include_C(void)
+{
+ return 1;
+}
diff --git a/Utilities/KWIML/test/test_include_CXX.cxx b/Utilities/KWIML/test/test_include_CXX.cxx
new file mode 100644
index 000000000..111311a84
--- /dev/null
+++ b/Utilities/KWIML/test/test_include_CXX.cxx
@@ -0,0 +1,28 @@
+/*============================================================================
+ 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 <string>
+
+#if defined(_MSC_VER) && defined(NDEBUG)
+// Use C++ runtime to avoid linker warning:
+// warning LNK4089: all references to 'MSVCP71.dll' discarded by /OPT:REF
+std::string test_include_CXX_use_stl_string;
+#endif
+
+/* Test KWIML header inclusion after above system headers. */
+#include "test.h"
+#include KWIML_HEADER(ABI.h)
+#include KWIML_HEADER(INT.h)
+
+extern "C" int test_include_CXX(void)
+{
+ return 1;
+}
diff --git a/Utilities/KWStyle/CMake.kws.xml.in b/Utilities/KWStyle/CMake.kws.xml.in
new file mode 100644
index 000000000..c2b442940
--- /dev/null
+++ b/Utilities/KWStyle/CMake.kws.xml.in
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<Description>
+<LineLength>79</LineLength>
+<!--
+<Header>"@CMake_SOURCE_DIR@/Utilities/KWStyle/Headers",false,true</Header>
+<Functions>
+<regex>[A-Z]</regex>
+<length>100</length>
+</Functions>
+-->
+</Description>
diff --git a/Utilities/KWStyle/CMakeFiles.txt.in b/Utilities/KWStyle/CMakeFiles.txt.in
new file mode 100644
index 000000000..a95aac655
--- /dev/null
+++ b/Utilities/KWStyle/CMakeFiles.txt.in
@@ -0,0 +1,15 @@
+"@CMake_SOURCE_DIR@/Source/*.txx"
+"@CMake_SOURCE_DIR@/Source/*.cxx"
+"@CMake_SOURCE_DIR@/Source/*.h*"
+"@CMake_SOURCE_DIR@/Source/CPack/*.txx"
+"@CMake_SOURCE_DIR@/Source/CPack/*.cxx"
+"@CMake_SOURCE_DIR@/Source/CPack/*.h*"
+"@CMake_SOURCE_DIR@/Source/CTest/*.txx"
+"@CMake_SOURCE_DIR@/Source/CTest/*.cxx"
+"@CMake_SOURCE_DIR@/Source/CTest/*.h*"
+"@CMake_SOURCE_DIR@/Source/CurseDialog/*.h*"
+"@CMake_SOURCE_DIR@/Source/CurseDialog/*.cxx"
+"@CMake_SOURCE_DIR@/Source/CurseDialog/*.txx"
+-f (Lexer\.h)
+-f (Lexer\.cxx)
+-f (Parser\.cxx)
diff --git a/Utilities/KWStyle/CMakeLists.txt b/Utilities/KWStyle/CMakeLists.txt
new file mode 100644
index 000000000..5b0c84e8b
--- /dev/null
+++ b/Utilities/KWStyle/CMakeLists.txt
@@ -0,0 +1,78 @@
+#=============================================================================
+# 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 uses KWStyle for checking the coding style
+
+# Search for a built-from-source KWStyle under Dashboards/Support on a typical
+# dashboard machines:
+#
+SET(home "$ENV{HOME}")
+IF(NOT home)
+ STRING(REPLACE "\\" "/" home "$ENV{USERPROFILE}")
+ENDIF()
+
+FIND_PROGRAM(KWSTYLE_EXECUTABLE
+ NAMES KWStyle
+ PATHS
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Kitware Inc.\\KWStyle 1.0.0]/bin"
+ "${home}/Dashboards/Support/KWStyle/bin"
+ )
+MARK_AS_ADVANCED(KWSTYLE_EXECUTABLE)
+
+SET(CMAKE_USE_KWSTYLE_DEFAULT OFF)
+IF(KWSTYLE_EXECUTABLE)
+ SET(CMAKE_USE_KWSTYLE_DEFAULT ON)
+ENDIF()
+
+OPTION(CMAKE_USE_KWSTYLE
+ "Add StyleCheck target and KWStyle test: run KWStyle to check for coding standard violations."
+ ${CMAKE_USE_KWSTYLE_DEFAULT})
+MARK_AS_ADVANCED(CMAKE_USE_KWSTYLE)
+
+IF(CMAKE_USE_KWSTYLE)
+ OPTION(KWSTYLE_USE_VIM_FORMAT "Set KWStyle to generate errors with a VIM-compatible format." OFF)
+ OPTION(KWSTYLE_USE_MSVC_FORMAT "Set KWStyle to generate errors with a VisualStudio-compatible format." OFF)
+ MARK_AS_ADVANCED(KWSTYLE_USE_VIM_FORMAT)
+ MARK_AS_ADVANCED(KWSTYLE_USE_MSVC_FORMAT)
+
+ IF(KWSTYLE_USE_VIM_FORMAT)
+ SET(KWSTYLE_ARGUMENTS -vim ${KWSTYLE_ARGUMENTS})
+ ENDIF(KWSTYLE_USE_VIM_FORMAT)
+
+ IF(KWSTYLE_USE_MSVC_FORMAT)
+ SET(KWSTYLE_ARGUMENTS -msvc ${KWSTYLE_ARGUMENTS})
+ ENDIF(KWSTYLE_USE_MSVC_FORMAT)
+
+ CONFIGURE_FILE(${CMake_SOURCE_DIR}/Utilities/KWStyle/CMake.kws.xml.in
+ ${CMake_BINARY_DIR}/CMake.kws.xml)
+ CONFIGURE_FILE(${CMake_SOURCE_DIR}/Utilities/KWStyle/CMakeMoreChecks.kws.xml.in
+ ${CMake_BINARY_DIR}/CMakeMoreChecks.kws.xml)
+
+ CONFIGURE_FILE(${CMake_SOURCE_DIR}/Utilities/KWStyle/CMakeFiles.txt.in
+ ${CMake_BINARY_DIR}/CMakeKWSFiles.txt)
+
+ ADD_CUSTOM_COMMAND(
+ OUTPUT ${CMake_BINARY_DIR}/KWStyleReport.txt
+ COMMAND ${KWSTYLE_EXECUTABLE}
+ ARGS -xml ${CMake_BINARY_DIR}/CMake.kws.xml -o ${CMake_SOURCE_DIR}/Utilities/KWStyle/CMakeOverwrite.txt -v ${KWSTYLE_ARGUMENTS} -D ${CMake_BINARY_DIR}/CMakeKWSFiles.txt
+ COMMENT "Coding Style Checker"
+ )
+
+ ADD_CUSTOM_TARGET(MoreStyleChecks
+ COMMAND ${KWSTYLE_EXECUTABLE}
+ -xml ${CMake_BINARY_DIR}/CMakeMoreChecks.kws.xml -html ${CMake_BINARY_DIR}/html -o ${CMake_SOURCE_DIR}/Utilities/KWStyle/CMakeOverwrite.txt -v ${KWSTYLE_ARGUMENTS} -D ${CMake_BINARY_DIR}/CMakeKWSFiles.txt
+ COMMENT "Coding Style Checker, more checks enabled"
+ )
+
+ ADD_CUSTOM_TARGET(StyleCheck DEPENDS ${CMake_BINARY_DIR}/KWStyleReport.txt)
+ENDIF(CMAKE_USE_KWSTYLE)
diff --git a/Utilities/KWStyle/CMakeMoreChecks.kws.xml.in b/Utilities/KWStyle/CMakeMoreChecks.kws.xml.in
new file mode 100644
index 000000000..b7078e0cf
--- /dev/null
+++ b/Utilities/KWStyle/CMakeMoreChecks.kws.xml.in
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<Description>
+ <ErrorThreshold>10</ErrorThreshold>
+ <LineLength>79</LineLength>
+ <Header>"@CMake_SOURCE_DIR@/Utilities/KWStyle/Headers",false,true</Header>
+ <Functions>
+ <regex>^(cm)?[A-Z]</regex>
+ <length>200</length>
+ </Functions>
+ <InternalVariables>
+ <regex>^[A-Z]</regex>
+ <alignment>0</alignment>
+ </InternalVariables>
+ <SemicolonSpace>0</SemicolonSpace>
+ <DeclarationOrder>
+ <public>0</public>
+ <protected>1</protected>
+ <private>2</private>
+ </DeclarationOrder>
+ <Tabs>1</Tabs>
+ <EmptyLines>4</EmptyLines>
+ <StatementPerLine>
+ <maxNumber>1</maxNumber>
+ <checkInline>0</checkInline>
+ </StatementPerLine>
+ <VariablePerLine>
+ <maxNumber>1</maxNumber>
+ </VariablePerLine>
+ <BadCharacters>true</BadCharacters>
+</Description>
diff --git a/Utilities/KWStyle/CMakeOverwrite.txt b/Utilities/KWStyle/CMakeOverwrite.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Utilities/KWStyle/CMakeOverwrite.txt
diff --git a/Utilities/KWStyle/Headers/CMakeHeader.h b/Utilities/KWStyle/Headers/CMakeHeader.h
new file mode 100644
index 000000000..3d7702e1a
--- /dev/null
+++ b/Utilities/KWStyle/Headers/CMakeHeader.h
@@ -0,0 +1,11 @@
+/*============================================================================
+ 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.
+============================================================================*/
diff --git a/Utilities/Release/CMakeInstall.bmp b/Utilities/Release/CMakeInstall.bmp
new file mode 100644
index 000000000..0d4c1a5e7
--- /dev/null
+++ b/Utilities/Release/CMakeInstall.bmp
Binary files differ
diff --git a/Utilities/Release/CMakeLogo.ico b/Utilities/Release/CMakeLogo.ico
new file mode 100644
index 000000000..e13bb156f
--- /dev/null
+++ b/Utilities/Release/CMakeLogo.ico
Binary files differ
diff --git a/Utilities/Release/Cygwin/CMakeLists.txt b/Utilities/Release/Cygwin/CMakeLists.txt
new file mode 100644
index 000000000..2420c97d9
--- /dev/null
+++ b/Utilities/Release/Cygwin/CMakeLists.txt
@@ -0,0 +1,25 @@
+FILE(GLOB INSTALLED_CURSES /usr/bin/cygncurses-*.dll)
+SET(MAX 0)
+FOREACH(f ${INSTALLED_CURSES})
+ IF(NOT "${f}" MATCHES "\\+")
+ STRING(REGEX REPLACE ".*-([0-9]*).dll" "\\1" NUMBER "${f}")
+ IF(NUMBER GREATER MAX)
+ SET(MAX ${NUMBER})
+ ENDIF(NUMBER GREATER MAX)
+ ENDIF(NOT "${f}" MATCHES "\\+")
+ENDFOREACH(f)
+STRING(REGEX REPLACE "/usr/bin/" "\\1" NUMBER "${f}")
+SET(CMAKE_NCURSES_VERSION "libncurses${MAX}")
+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")
+INSTALL_FILES(/share/doc/Cygwin FILES
+ ${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})
+CONFIGURE_FILE("${CMake_SOURCE_DIR}/Utilities/Release/Cygwin/cygwin-patch.diff.in"
+ ${CPACK_CYGWIN_PATCH_FILE})
+
diff --git a/Utilities/Release/Cygwin/README.cygwin.in b/Utilities/Release/Cygwin/README.cygwin.in
new file mode 100644
index 000000000..6c42a4c20
--- /dev/null
+++ b/Utilities/Release/Cygwin/README.cygwin.in
@@ -0,0 +1,42 @@
+cmake
+--------------------------------------
+Runtime requirements:
+ cygwin-1.5.21(0.156/4/2) or newer
+
+Build requirements
+ cygwin-1.5.21(0.156/4/2) or newer
+ make
+
+Canonical homepage:
+ http://www.cmake.org
+
+Canonical download:
+ ftp://www.cmake.org/pub/cmake/
+
+------------------------------------
+
+Build instructions:
+ unpack @CPACK_PACKAGE_FILE_NAME@-@CPACK_CYGWIN_PATCH_NUMBER@-src.tar.bz2
+ if you use setup to install this src package, it will be
+ unpacked under /usr/src automatically
+ cd /usr/src
+ ./@CPACK_PACKAGE_FILE_NAME@-@CPACK_CYGWIN_PATCH_NUMBER@.sh all
+
+This will create:
+ /usr/src/@CPACK_PACKAGE_FILE_NAME@.tar.bz2
+ /usr/src/@CPACK_PACKAGE_FILE_NAME@-@CPACK_CYGWIN_PATCH_NUMBER@-src.tar.bz2
+
+-------------------------------------------
+
+Port Notes:
+
+The directory /usr/share/@CPACK_PACKAGE_FILE_NAME@/include is purposely not
+located at /usr/include/@CPACK_PACKAGE_FILE_NAME@ or /usr/include/cmake. The
+files it contains are not meant for inclusion in any C or C++ program.
+They are used for compiling dynamically loadable CMake commands inside
+projects that provide them. CMake will automatically provide the
+proper include path when the files are needed.
+
+------------------
+
+Cygwin port maintained by: CMake Developers <cmake@www.cmake.org>
diff --git a/Utilities/Release/Cygwin/cygwin-package.sh.in b/Utilities/Release/Cygwin/cygwin-package.sh.in
new file mode 100755
index 000000000..9730b3332
--- /dev/null
+++ b/Utilities/Release/Cygwin/cygwin-package.sh.in
@@ -0,0 +1,90 @@
+TOP_DIR=`cd \`echo "$0" | sed -n '/\//{s/\/[^\/]*$//;p;}'\`;pwd`
+
+# create build directory
+mkdirs()
+{
+ (
+ mkdir -p "$TOP_DIR/@CPACK_PACKAGE_FILE_NAME@/.build"
+ )
+}
+
+# cd into
+# untar source tree and apply patch
+prep()
+{
+ (
+ cd "$TOP_DIR" &&
+ tar xvfj @CPACK_PACKAGE_FILE_NAME@.tar.bz2
+ patch -p0 < "@CPACK_PACKAGE_FILE_NAME@-@CPACK_CYGWIN_PATCH_NUMBER@.patch" &&
+ mkdirs
+ )
+}
+
+conf()
+{
+ (
+ cd "$TOP_DIR/@CPACK_PACKAGE_FILE_NAME@/.build" &&
+ ../bootstrap --parallel=2
+ )
+}
+
+build()
+{
+ (
+ cd "$TOP_DIR/@CPACK_PACKAGE_FILE_NAME@/.build" &&
+ make -j2 &&
+ make test
+ )
+}
+
+clean()
+{
+ (
+ cd "$TOP_DIR/@CPACK_PACKAGE_FILE_NAME@/.build" &&
+ make clean
+ )
+}
+
+pkg()
+{
+ (
+ cd "$TOP_DIR/@CPACK_PACKAGE_FILE_NAME@/.build" &&
+ ./bin/cpack &&
+ mv @CPACK_PACKAGE_FILE_NAME@-@CPACK_CYGWIN_PATCH_NUMBER@.tar.bz2 "$TOP_DIR"
+ )
+}
+
+spkg()
+{
+ (
+ cd "$TOP_DIR/@CPACK_PACKAGE_FILE_NAME@/.build" &&
+ ./bin/cpack --config CPackSourceConfig.cmake &&
+ mv @CPACK_PACKAGE_FILE_NAME@-@CPACK_CYGWIN_PATCH_NUMBER@-src.tar.bz2 "$TOP_DIR"
+ )
+}
+
+finish()
+{
+ (
+ rm -rf "@CPACK_PACKAGE_FILE_NAME@"
+ )
+}
+
+case $1 in
+ prep) prep ; STATUS=$? ;;
+ mkdirs) mkdirs ; STATUS=$? ;;
+ conf) conf ; STATUS=$? ;;
+ build) build ; STATUS=$? ;;
+ clean) clean ; STATUS=$? ;;
+ package) pkg ; STATUS=$? ;;
+ pkg) pkg ; STATUS=$? ;;
+ src-package) spkg ; STATUS=$? ;;
+ spkg) spkg ; STATUS=$? ;;
+ finish) finish ; STATUS=$? ;;
+ all) (
+ prep && conf && build && pkg && spkg && finish ;
+ STATUS=$?
+ ) ;;
+ *) echo "Error: bad argument (all or one of these: prep mkdirs conf build clean package pkg src-package spkg finish)" ; exit 1 ;;
+esac
+exit ${STATUS}
diff --git a/Utilities/Release/Cygwin/cygwin-patch.diff.in b/Utilities/Release/Cygwin/cygwin-patch.diff.in
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Utilities/Release/Cygwin/cygwin-patch.diff.in
diff --git a/Utilities/Release/Cygwin/cygwin-setup.hint.in b/Utilities/Release/Cygwin/cygwin-setup.hint.in
new file mode 100644
index 000000000..a2532fc68
--- /dev/null
+++ b/Utilities/Release/Cygwin/cygwin-setup.hint.in
@@ -0,0 +1,5 @@
+# CMake setup.hint file for cygwin setup.exe program
+category: Devel
+requires: libgcc1 libidn11 @CMAKE_NCURSES_VERSION@ libstdc++6
+sdesc: "A cross platform build manager"
+ldesc: "CMake is a cross platform build manager. It allows you to specify build parameters for C and C++ programs in a cross platform manner. For cygwin Makefiles will be generated. CMake is also capable of generating microsoft project files, nmake, and borland makefiles. CMake can also perform system inspection operations like finding installed libraries and header files."
diff --git a/Utilities/Release/README b/Utilities/Release/README
new file mode 100644
index 000000000..12eafe18f
--- /dev/null
+++ b/Utilities/Release/README
@@ -0,0 +1,21 @@
+To create a cmake release, make sure the "release" tag is pointing to the
+expected git commit:
+
+http://cmake.org/gitweb?p=cmake.git;a=shortlog;h=refs/heads/release
+
+Then as kitware@hythloth, using an up-to-date CMake:
+
+ cd ~/CMakeReleases/cmake/Utilities/Release
+ mkdir 283rc1
+ cd 283rc1
+ ~/CMakeReleases/build/bin/cmake -DCMAKE_CREATE_VERSION=release -P ../create-cmake-release.cmake
+ ./create-release.sh
+
+
+create-cmake-release.cmake: script to run to create release sh scripts
+Add or remove machines in create-cmake-release.cmake.
+
+Cygwin -> directory that contains cpack cygwin package files used in
+ CMakeCPack.cmake
+
+machine_release.cmake : config files for each machine
diff --git a/Utilities/Release/create-cmake-release.cmake b/Utilities/Release/create-cmake-release.cmake
new file mode 100644
index 000000000..c304e6777
--- /dev/null
+++ b/Utilities/Release/create-cmake-release.cmake
@@ -0,0 +1,42 @@
+if(NOT DEFINED CMAKE_CREATE_VERSION)
+ set(CMAKE_CREATE_VERSION "release")
+ message("Using default value of 'release' for CMAKE_CREATE_VERSION")
+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
+ magrathea_release.cmake # Linux
+ v20n250_aix_release.cmake # AIX 5.3
+ ferrari_sgi64_release.cmake # IRIX 64
+ ferrari_sgi_release.cmake # IRIX
+)
+
+set(RELEASE_SCRIPTS_BATCH_2
+ dash2win64_cygwin.cmake # Cygwin
+)
+
+function(write_batch_shell_script filename)
+ set(scripts ${ARGN})
+ set(i 0)
+ file(WRITE ${filename} "#!/bin/bash")
+ foreach(f ${scripts})
+ math(EXPR x "420*(${i}/4)")
+ 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&
+")
+ math(EXPR i "${i}+1")
+ endforeach(f)
+ execute_process(COMMAND chmod a+x ${filename})
+endfunction()
+
+write_batch_shell_script("create-${CMAKE_CREATE_VERSION}-batch1.sh" ${RELEASE_SCRIPTS_BATCH_1})
+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")
diff --git a/Utilities/Release/dash2win64_cygwin.cmake b/Utilities/Release/dash2win64_cygwin.cmake
new file mode 100644
index 000000000..78e8df0af
--- /dev/null
+++ b/Utilities/Release/dash2win64_cygwin.cmake
@@ -0,0 +1,19 @@
+set(CMAKE_RELEASE_DIRECTORY "c:/cygwin/home/dashboard/CMakeReleaseCygwin")
+set(PROCESSORS 9)
+set(MAKE_PROGRAM "make")
+set(MAKE "${MAKE_PROGRAM} -j8")
+set(HOST dash2win64)
+set(CPACK_BINARY_GENERATORS "CygwinBinary")
+set(CPACK_SOURCE_GENERATORS "CygwinSource")
+set(MAKE_PROGRAM "make")
+set(INITIAL_CACHE "CMAKE_BUILD_TYPE:STRING=Release
+CMAKE_Fortran_COMPILER_FULLPATH:FILEPATH=FALSE
+CTEST_TEST_TIMEOUT:STRING=7200
+DART_TESTING_TIMEOUT:STRING=7200
+")
+set(CXX g++)
+set(CC gcc)
+set(SCRIPT_NAME dash2win64cygwin)
+set(GIT_EXTRA "git config core.autocrlf true")
+get_filename_component(path "${CMAKE_CURRENT_LIST_FILE}" PATH)
+include(${path}/release_cmake.cmake)
diff --git a/Utilities/Release/dash2win64_release.cmake b/Utilities/Release/dash2win64_release.cmake
new file mode 100644
index 000000000..fb82de0d0
--- /dev/null
+++ b/Utilities/Release/dash2win64_release.cmake
@@ -0,0 +1,19 @@
+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_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/dashmacmini2_release.cmake b/Utilities/Release/dashmacmini2_release.cmake
new file mode 100644
index 000000000..3e6b04973
--- /dev/null
+++ b/Utilities/Release/dashmacmini2_release.cmake
@@ -0,0 +1,18 @@
+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_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
new file mode 100644
index 000000000..bd93a8733
--- /dev/null
+++ b/Utilities/Release/dashmacmini5_release.cmake
@@ -0,0 +1,20 @@
+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(HOST dashmacmini5)
+set(MAKE_PROGRAM "make")
+set(MAKE "${MAKE_PROGRAM} -j5")
+set(CPACK_BINARY_GENERATORS "PackageMaker TGZ TZ")
+set(CPACK_SOURCE_GENERATORS "TGZ TZ")
+set(INITIAL_CACHE "
+CMAKE_BUILD_TYPE:STRING=Release
+CMAKE_OSX_ARCHITECTURES:STRING=x86_64;i386
+CMAKE_OSX_DEPLOYMENT_TARGET:STRING=10.5
+CMAKE_SKIP_BOOTSTRAP_TEST:STRING=TRUE
+CPACK_SYSTEM_NAME:STRING=Darwin64-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/ferrari_sgi64_release.cmake b/Utilities/Release/ferrari_sgi64_release.cmake
new file mode 100644
index 000000000..4425f0557
--- /dev/null
+++ b/Utilities/Release/ferrari_sgi64_release.cmake
@@ -0,0 +1,16 @@
+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
new file mode 100644
index 000000000..ee5121a9b
--- /dev/null
+++ b/Utilities/Release/ferrari_sgi_release.cmake
@@ -0,0 +1,11 @@
+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/hythloth_release.cmake b/Utilities/Release/hythloth_release.cmake
new file mode 100644
index 000000000..d2f4ba58c
--- /dev/null
+++ b/Utilities/Release/hythloth_release.cmake
@@ -0,0 +1,10 @@
+set(PROCESSORS 2)
+set(HOST hythloth)
+set(MAKE_PROGRAM "make")
+set(MAKE "${MAKE_PROGRAM} -j2")
+set(INITIAL_CACHE "
+CMAKE_BUILD_TYPE:STRING=Release
+CMAKE_SKIP_BOOTSTRAP_TEST:STRING=TRUE
+")
+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
new file mode 100644
index 000000000..1b2ae02c7
--- /dev/null
+++ b/Utilities/Release/magrathea_release.cmake
@@ -0,0 +1,16 @@
+set(PROCESSORS 1)
+set(HOST magrathea)
+set(MAKE_PROGRAM "make")
+set(CC gcc332s)
+set(CXX c++332s)
+set(INITIAL_CACHE "
+CMAKE_BUILD_TYPE:STRING=Release
+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
+CPACK_SYSTEM_NAME:STRING=Linux-i386
+BUILD_QtDialog:BOOL:=TRUE
+QT_QMAKE_EXECUTABLE:FILEPATH=/home/kitware/qt-4.43-install/bin/qmake
+")
+get_filename_component(path "${CMAKE_CURRENT_LIST_FILE}" PATH)
+include(${path}/release_cmake.cmake)
diff --git a/Utilities/Release/release_cmake.cmake b/Utilities/Release/release_cmake.cmake
new file mode 100644
index 000000000..0c9b3f9c5
--- /dev/null
+++ b/Utilities/Release/release_cmake.cmake
@@ -0,0 +1,136 @@
+get_filename_component(SCRIPT_PATH "${CMAKE_CURRENT_LIST_FILE}" PATH)
+
+# default to self extracting tgz, tgz, and tar.Z
+if(NOT DEFINED CPACK_BINARY_GENERATORS)
+ set(CPACK_BINARY_GENERATORS "STGZ TGZ TZ")
+endif(NOT DEFINED CPACK_BINARY_GENERATORS)
+if(DEFINED EXTRA_COPY)
+ set(HAS_EXTRA_COPY 1)
+endif(DEFINED EXTRA_COPY)
+if(NOT DEFINED CMAKE_RELEASE_DIRECTORY)
+ set(CMAKE_RELEASE_DIRECTORY "~/CMakeReleaseDirectory")
+endif(NOT DEFINED CMAKE_RELEASE_DIRECTORY)
+if(NOT DEFINED SCRIPT_NAME)
+ set(SCRIPT_NAME "${HOST}")
+endif(NOT DEFINED SCRIPT_NAME)
+if(NOT DEFINED MAKE_PROGRAM)
+ message(FATAL_ERROR "MAKE_PROGRAM must be set")
+endif(NOT DEFINED MAKE_PROGRAM)
+if(NOT DEFINED MAKE)
+ set(MAKE "${MAKE_PROGRAM}")
+endif(NOT DEFINED MAKE)
+if(NOT DEFINED RUN_SHELL)
+ set(RUN_SHELL "/bin/sh")
+endif(NOT DEFINED RUN_SHELL)
+if(NOT DEFINED PROCESSORS)
+ set(PROCESSORS 1)
+endif(NOT DEFINED PROCESSORS)
+if(NOT DEFINED CMAKE_CREATE_VERSION)
+ message(FATAL_ERROR "CMAKE_CREATE_VERSION not defined")
+endif(NOT DEFINED CMAKE_CREATE_VERSION)
+if(NOT DEFINED GIT_COMMAND)
+ set(GIT_COMMAND git)
+endif()
+
+if(${CMAKE_CREATE_VERSION} MATCHES "^(release|maint|next|nightly)$")
+ set(GIT_BRANCH origin/${CMAKE_CREATE_VERSION})
+else()
+ set(GIT_BRANCH ${CMAKE_CREATE_VERSION})
+endif()
+
+if(NOT DEFINED FINAL_PATH )
+ set(FINAL_PATH ${CMAKE_RELEASE_DIRECTORY}/${CMAKE_CREATE_VERSION}-build)
+endif(NOT DEFINED FINAL_PATH )
+
+if(NOT HOST)
+ message(FATAL_ERROR "HOST must be specified with -DHOST=host")
+endif(NOT HOST)
+if(NOT DEFINED MAKE)
+ message(FATAL_ERROR "MAKE must be specified with -DMAKE=\"make -j2\"")
+endif(NOT DEFINED MAKE)
+
+message("Creating CMake release ${CMAKE_CREATE_VERSION} on ${HOST} with parallel = ${PROCESSORS}")
+
+# define a macro to run a remote command
+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})
+ else(${ARGC} GREATER 2)
+ message("ssh ${HOST} ${EXTRA_HOP} ${command}")
+ execute_process(COMMAND ssh ${HOST} ${EXTRA_HOP} ${command} RESULT_VARIABLE result)
+ endif(${ARGC} GREATER 2)
+ if(${result} GREATER 0)
+ message(FATAL_ERROR "Error running command: ${command}, return value = ${result}")
+ endif(${result} GREATER 0)
+endmacro(remote_command)
+
+# 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)
+configure_file(${SCRIPT_PATH}/release_cmake.sh.in ${SCRIPT_FILE} @ONLY)
+
+# run the script by starting a shell on the remote machine
+# then using the script file as input to the shell
+IF(RUN_LOCAL)
+ message(FATAL_ERROR "run this command: ${RUN_SHELL} ${SCRIPT_FILE}")
+ELSE(RUN_LOCAL)
+ remote_command("run release_cmake-${HOST}.sh on server"
+ "${RUN_SHELL}" ${SCRIPT_FILE})
+ENDIF(RUN_LOCAL)
+
+# now figure out which types of packages were created
+set(generators ${CPACK_BINARY_GENERATORS} ${CPACK_SOURCE_GENERATORS})
+separate_arguments(generators)
+foreach(gen ${generators})
+ if("${gen}" STREQUAL "TGZ")
+ set(SUFFIXES ${SUFFIXES} "*.tar.gz")
+ endif("${gen}" STREQUAL "TGZ")
+ if("${gen}" STREQUAL "STGZ")
+ set(SUFFIXES ${SUFFIXES} "*.sh")
+ endif("${gen}" STREQUAL "STGZ")
+ if("${gen}" STREQUAL "PackageMaker")
+ set(SUFFIXES ${SUFFIXES} "*.dmg")
+ endif("${gen}" STREQUAL "PackageMaker")
+ if("${gen}" STREQUAL "TBZ2")
+ set(SUFFIXES ${SUFFIXES} "*.tar.bz2")
+ endif("${gen}" STREQUAL "TBZ2")
+ if("${gen}" MATCHES "Cygwin")
+ set(SUFFIXES ${SUFFIXES} "*.tar.bz2")
+ set(extra_files setup.hint)
+ endif("${gen}" MATCHES "Cygwin")
+ if("${gen}" STREQUAL "TZ")
+ set(SUFFIXES ${SUFFIXES} "*.tar.Z")
+ endif("${gen}" STREQUAL "TZ")
+ if("${gen}" STREQUAL "ZIP")
+ set(SUFFIXES ${SUFFIXES} "*.zip")
+ endif("${gen}" STREQUAL "ZIP")
+ if("${gen}" STREQUAL "NSIS")
+ set(SUFFIXES ${SUFFIXES} "*.exe")
+ endif("${gen}" STREQUAL "NSIS")
+endforeach(gen)
+# copy all the files over from the remote machine
+set(PROJECT_PREFIX cmake-)
+foreach(suffix ${SUFFIXES})
+ message("scp ${HOST}:${FINAL_PATH}/${PROJECT_PREFIX}${suffix} .")
+ execute_process(COMMAND
+ scp ${HOST}:${FINAL_PATH}/${PROJECT_PREFIX}${suffix} .
+ RESULT_VARIABLE result)
+ if(${result} GREATER 0)
+ message("error getting file back scp ${HOST}:${FINAL_PATH}/${PROJECT_PREFIX}${suffix} .")
+ endif(${result} GREATER 0)
+endforeach(suffix)
+
+# if there are extra files to copy get them as well
+if(extra_files)
+ foreach(f ${extra_files})
+ message("scp ${HOST}:${FINAL_PATH}/${f} .")
+ execute_process(COMMAND
+ scp ${HOST}:${FINAL_PATH}/${f} .
+ RESULT_VARIABLE result)
+ if(${result} GREATER 0)
+ message("error getting file back scp ${HOST}:${FINAL_PATH}/${f} .")
+ endif(${result} GREATER 0)
+ endforeach(f)
+endif(extra_files)
diff --git a/Utilities/Release/release_cmake.sh.in b/Utilities/Release/release_cmake.sh.in
new file mode 100755
index 000000000..50882c5de
--- /dev/null
+++ b/Utilities/Release/release_cmake.sh.in
@@ -0,0 +1,154 @@
+#!/bin/sh
+echo "Start release"
+date
+echo ""
+echo "remove and create working directory @CMAKE_RELEASE_DIRECTORY@"
+rm -rf @CMAKE_RELEASE_DIRECTORY@
+mkdir @CMAKE_RELEASE_DIRECTORY@
+
+check_exit_value()
+{
+ VALUE="$1"
+ if [ "$VALUE" != "0" ]; then
+ echo "error in $2"
+ exit 1
+ fi
+}
+
+if [ ! -z "@CC@" ]; then
+ export CC="@CC@"
+ check_exit_value $? "set CC compiler env var" || exit 1
+fi
+
+if [ ! -z "@FC@" ]; then
+ export FC="@FC@"
+ check_exit_value $? "set FC compiler env var" || exit 1
+fi
+
+if [ ! -z "@CXX@" ]; then
+ export CXX="@CXX@"
+ check_exit_value $? "set CC compiler env var" || exit 1
+fi
+
+if [ ! -z "@LDFLAGS@" ]; then
+ export LDFLAGS="@LDFLAGS@"
+ check_exit_value $? "set LDFLAGS env var" || exit 1
+fi
+
+if [ ! -z "@FFLAGS@" ]; then
+ export FFLAGS="@FFLAGS@"
+ check_exit_value $? "set FFLAGS env var" || exit 1
+fi
+
+if [ ! -z "@CFLAGS@" ]; then
+ export CFLAGS="@CFLAGS@"
+ check_exit_value $? "set CFLAGS env var" || exit 1
+fi
+
+if [ ! -z "@CXXFLAGS@" ]; then
+ export CXXFLAGS="@CXXFLAGS@"
+ check_exit_value $? "setCXXFLAGS env var" || exit 1
+fi
+
+if [ ! -z "@USER_MAKE_RULE_FILE_CONTENTS@" ]; then
+ echo "@USER_MAKE_RULE_FILE_CONTENTS@" > "@USER_MAKE_RULE_FILE@"
+ check_exit_value $? "Create User Rule file" || exit 1
+fi
+echo "Create a directory to build in"
+rm -rf @CMAKE_RELEASE_DIRECTORY@/@CMAKE_CREATE_VERSION@-build
+check_exit_value $? "Remove build tree" || exit 1
+mkdir @CMAKE_RELEASE_DIRECTORY@/@CMAKE_CREATE_VERSION@-build
+check_exit_value $? "Create build directory" || exit 1
+# make sure directory was created
+if [ ! -d @CMAKE_RELEASE_DIRECTORY@/@CMAKE_CREATE_VERSION@-build ]; then
+ echo "Could not create @CMAKE_RELEASE_DIRECTORY@/@CMAKE_CREATE_VERSION@-build"
+ exit -1
+fi
+
+echo "Create initial cache"
+echo "@INITIAL_CACHE@" > @CMAKE_RELEASE_DIRECTORY@/@CMAKE_CREATE_VERSION@-build/CMakeCache.txt
+check_exit_value $? "Create initial cache" || exit 1
+
+# create a user override file user.txt if USER_OVERRIDE is set,
+# and append the cache variable to the cache
+if [ ! -z "@USER_OVERRIDE@" ]; then
+ echo "@USER_OVERRIDE@" > @CMAKE_RELEASE_DIRECTORY@/@CMAKE_CREATE_VERSION@-build/user.txt
+ 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
+
+echo "Checkout the source for @CMAKE_CREATE_VERSION@"
+cd @CMAKE_RELEASE_DIRECTORY@
+if [ ! -z "@GIT_COMMAND@" ]; then
+ # clone the repo without creating any source files in the directory
+ # matching the branch being built (i.e. master CMake-2-8, etc)
+ @GIT_COMMAND@ clone -n git://cmake.org/cmake.git @CMAKE_CREATE_VERSION@
+ check_exit_value $? "Checkout git cmake source" || exit 1
+ # go into the git directory
+ cd @CMAKE_CREATE_VERSION@
+ # run any extra commands if they exist
+ @GIT_EXTRA@
+ check_exit_value $? "git extra cmake source" || exit 1
+ # now checkout a copy on the local branch working
+ @GIT_COMMAND@ checkout -b working @GIT_BRANCH@
+ check_exit_value $? "git checkout" || exit 1
+ cd ..
+else
+ echo GIT_COMMAND does not exist
+ exit 1
+fi
+
+cd @CMAKE_RELEASE_DIRECTORY@/@CMAKE_CREATE_VERSION@-build
+
+if [ ! -z "@CONFIGURE_WITH_CMAKE@" ]; then
+ echo "Run cmake to configure cmake"
+ @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
+fi
+
+echo "Build cmake with @MAKE@"
+@MAKE@
+check_exit_value $? "Build cmake" || exit 1
+
+if [ -z "@SKIP_TESTS@" ]; then
+ echo "Run cmake tests"
+ ./bin/ctest --output-on-failure -j @PROCESSORS@ test
+ check_exit_value $? "Test cmake" || exit 1
+fi
+
+# loop over binary generators
+generators="@CPACK_BINARY_GENERATORS@"
+for GEN in $generators; do
+ echo "Create $GEN package"
+ ./bin/cpack -D CMAKE_MAKE_PROGRAM=@MAKE_PROGRAM@ -G $GEN
+ check_exit_value $? "Create $GEN package" || exit 1
+done
+
+# loop over source generators
+generators="@CPACK_SOURCE_GENERATORS@"
+for GEN in $generators; do
+ echo "Create $GEN package"
+ ./bin/cpack -D CMAKE_MAKE_PROGRAM=@MAKE_PROGRAM@ -G $GEN --config CPackSourceConfig.cmake
+ check_exit_value $? "Create $GEN package" || exit 1
+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 ""
+exit 0
diff --git a/Utilities/Release/upload_release.cmake b/Utilities/Release/upload_release.cmake
new file mode 100644
index 000000000..dc6c78f38
--- /dev/null
+++ b/Utilities/Release/upload_release.cmake
@@ -0,0 +1,30 @@
+set(PROJECT_PREFIX cmake-)
+if(NOT VERSION)
+ set(VERSION 2.8)
+endif()
+set(dir "v${VERSION}")
+if("${VERSION}" MATCHES "master")
+ set(dir "dev")
+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}")
+set(count 0)
+foreach(file ${FILES})
+ if(NOT IS_DIRECTORY ${file})
+ message("upload ${file} ${UPLOAD_LOC}")
+ execute_process(COMMAND
+ scp ${file} ${UPLOAD_LOC}
+ RESULT_VARIABLE result)
+ math(EXPR count "${count} + 1")
+ if("${result}" GREATER 0)
+ message(FATAL_ERROR "failed to upload file to ${UPLOAD_LOC}")
+ endif()
+ endif()
+endforeach(file)
+if(${count} EQUAL 0)
+ message(FATAL_ERROR "Error no files uploaded.")
+endif()
diff --git a/Utilities/Release/v20n250_aix_release.cmake b/Utilities/Release/v20n250_aix_release.cmake
new file mode 100644
index 000000000..53c34d7ce
--- /dev/null
+++ b/Utilities/Release/v20n250_aix_release.cmake
@@ -0,0 +1,21 @@
+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(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/SetupForDevelopment.sh b/Utilities/SetupForDevelopment.sh
new file mode 100755
index 000000000..0a9df7e83
--- /dev/null
+++ b/Utilities/SetupForDevelopment.sh
@@ -0,0 +1,13 @@
+#!/usr/bin/env bash
+
+cd "${BASH_SOURCE%/*}/.." &&
+Utilities/GitSetup/setup-user && echo &&
+Utilities/GitSetup/setup-hooks && echo &&
+Utilities/GitSetup/setup-stage && echo &&
+(Utilities/GitSetup/setup-ssh ||
+ echo 'Failed to setup SSH. Run this again to retry.') && echo &&
+Utilities/GitSetup/tips
+
+# Rebase master by default
+git config rebase.stat true
+git config branch.master.rebase true
diff --git a/Utilities/cmThirdParty.h.in b/Utilities/cmThirdParty.h.in
new file mode 100644
index 000000000..c8240850e
--- /dev/null
+++ b/Utilities/cmThirdParty.h.in
@@ -0,0 +1,23 @@
+/*============================================================================
+ 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 __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_ZLIB
+#cmakedefine CMAKE_USE_SYSTEM_BZIP2
+#cmakedefine CMAKE_USE_SYSTEM_LIBARCHIVE
+#cmakedefine CTEST_USE_XMLRPC
+
+#endif
diff --git a/Utilities/cm_bzlib.h b/Utilities/cm_bzlib.h
new file mode 100644
index 000000000..d1fffa1aa
--- /dev/null
+++ b/Utilities/cm_bzlib.h
@@ -0,0 +1,23 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2012 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_bzlib_h
+#define __cm_bzlib_h
+
+/* Use the bzip2 library configured for CMake. */
+#include "cmThirdParty.h"
+#ifdef CMAKE_USE_SYSTEM_BZIP2
+# include <bzlib.h>
+#else
+# include <cmbzip2/bzlib.h>
+#endif
+
+#endif
diff --git a/Utilities/cm_curl.h b/Utilities/cm_curl.h
new file mode 100644
index 000000000..43944a3f4
--- /dev/null
+++ b/Utilities/cm_curl.h
@@ -0,0 +1,23 @@
+/*============================================================================
+ 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 __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>
+#endif
+
+#endif
diff --git a/Utilities/cm_expat.h b/Utilities/cm_expat.h
new file mode 100644
index 000000000..91f4a7b52
--- /dev/null
+++ b/Utilities/cm_expat.h
@@ -0,0 +1,23 @@
+/*============================================================================
+ 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 __cm_expat_h
+#define __cm_expat_h
+
+/* Use the expat library configured for CMake. */
+#include "cmThirdParty.h"
+#ifdef CMAKE_USE_SYSTEM_EXPAT
+# include <expat.h>
+#else
+# include <cmexpat/expat.h>
+#endif
+
+#endif
diff --git a/Utilities/cm_libarchive.h b/Utilities/cm_libarchive.h
new file mode 100644
index 000000000..1469baeb4
--- /dev/null
+++ b/Utilities/cm_libarchive.h
@@ -0,0 +1,25 @@
+/*============================================================================
+ 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 __cm_libarchive_h
+#define __cm_libarchive_h
+
+/* Use the libarchive configured for CMake. */
+#include "cmThirdParty.h"
+#ifdef CMAKE_USE_SYSTEM_LIBARCHIVE
+# include <archive.h>
+# include <archive_entry.h>
+#else
+# include <cmlibarchive/libarchive/archive.h>
+# include <cmlibarchive/libarchive/archive_entry.h>
+#endif
+
+#endif
diff --git a/Utilities/cm_xmlrpc.h b/Utilities/cm_xmlrpc.h
new file mode 100644
index 000000000..a6b375da8
--- /dev/null
+++ b/Utilities/cm_xmlrpc.h
@@ -0,0 +1,22 @@
+/*============================================================================
+ 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 __cm_xmlrpc_h
+#define __cm_xmlrpc_h
+
+/* Use the xmlrpc library configured for CMake. */
+#include "cmThirdParty.h"
+#ifdef CTEST_USE_XMLRPC
+# include <xmlrpc.h>
+# include <xmlrpc_client.h>
+#endif
+
+#endif
diff --git a/Utilities/cm_zlib.h b/Utilities/cm_zlib.h
new file mode 100644
index 000000000..fb5832e35
--- /dev/null
+++ b/Utilities/cm_zlib.h
@@ -0,0 +1,23 @@
+/*============================================================================
+ 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 __cm_zlib_h
+#define __cm_zlib_h
+
+/* Use the zlib library configured for CMake. */
+#include "cmThirdParty.h"
+#ifdef CMAKE_USE_SYSTEM_ZLIB
+# include <zlib.h>
+#else
+# include <cmzlib/zlib.h>
+#endif
+
+#endif
diff --git a/Utilities/cmake.m4 b/Utilities/cmake.m4
new file mode 100644
index 000000000..a374a3bfb
--- /dev/null
+++ b/Utilities/cmake.m4
@@ -0,0 +1,53 @@
+dnl ============================================================================
+dnl CMake - Cross Platform Makefile Generator
+dnl Copyright 2011 Matthias Kretz, kretz@kde.org
+dnl
+dnl Distributed under the OSI-approved BSD License (the "License");
+dnl see accompanying file Copyright.txt for details.
+dnl
+dnl This software is distributed WITHOUT ANY WARRANTY; without even the
+dnl implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+dnl See the License for more information.
+dnl ============================================================================
+
+AC_DEFUN([CMAKE_FIND_BINARY],
+[AC_ARG_VAR([CMAKE_BINARY], [path to the cmake binary])dnl
+
+if test "x$ac_cv_env_CMAKE_BINARY_set" != "xset"; then
+ AC_PATH_TOOL([CMAKE_BINARY], [cmake])dnl
+fi
+])dnl
+
+# $1: package name
+# $2: language (e.g. C/CXX/Fortran)
+# $3: The compiler ID, defaults to GNU.
+# Possible values are: GNU, Intel, Clang, SunPro, HP, XL, VisualAge, PGI,
+# PathScale, Cray, SCO, MIPSpro, MSVC
+# $4: optional extra arguments to cmake, e.g. "-DCMAKE_SIZEOF_VOID_P=8"
+# $5: optional path to cmake binary
+AC_DEFUN([CMAKE_FIND_PACKAGE], [
+AC_REQUIRE([CMAKE_FIND_BINARY])dnl
+
+AC_ARG_VAR([$1][_][$2][FLAGS], [$2 compiler flags for $1. This overrides the cmake output])dnl
+AC_ARG_VAR([$1][_LIBS], [linker flags for $1. This overrides the cmake output])dnl
+
+failed=false
+AC_MSG_CHECKING([for $1])
+if test -n "$1[]_$2[]FLAGS"; then
+ $1[]_$2[]FLAGS=`$CMAKE_BINARY --find-package "-DNAME=$1" "-DCOMPILER_ID=m4_default([$3], [GNU])" "-DLANGUAGE=$2" -DMODE=COMPILE $4` || failed=true
+fi
+if test -n "$1[]_LIBS"; then
+ $1[]_LIBS=`$CMAKE_BINARY --find-package "-DNAME=$1" "-DCOMPILER_ID=m4_default([$3], [GNU])" "-DLANGUAGE=$2" -DMODE=LINK $4` || failed=true
+fi
+
+if $failed; then
+ unset $1[]_$2[]FLAGS
+ unset $1[]_LIBS
+
+ AC_MSG_RESULT([no])
+ $6
+else
+ AC_MSG_RESULT([yes])
+ $5
+fi[]dnl
+])
diff --git a/Utilities/cmbzip2/CHANGES b/Utilities/cmbzip2/CHANGES
new file mode 100644
index 000000000..6e4f65e2e
--- /dev/null
+++ b/Utilities/cmbzip2/CHANGES
@@ -0,0 +1,319 @@
+ ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
+
+ bzip2/libbzip2 version 1.0.5 of 10 December 2007
+ Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
+
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------
+
+
+0.9.0
+~~~~~
+First version.
+
+
+0.9.0a
+~~~~~~
+Removed 'ranlib' from Makefile, since most modern Unix-es
+don't need it, or even know about it.
+
+
+0.9.0b
+~~~~~~
+Fixed a problem with error reporting in bzip2.c. This does not effect
+the library in any way. Problem is: versions 0.9.0 and 0.9.0a (of the
+program proper) compress and decompress correctly, but give misleading
+error messages (internal panics) when an I/O error occurs, instead of
+reporting the problem correctly. This shouldn't give any data loss
+(as far as I can see), but is confusing.
+
+Made the inline declarations disappear for non-GCC compilers.
+
+
+0.9.0c
+~~~~~~
+Fixed some problems in the library pertaining to some boundary cases.
+This makes the library behave more correctly in those situations. The
+fixes apply only to features (calls and parameters) not used by
+bzip2.c, so the non-fixedness of them in previous versions has no
+effect on reliability of bzip2.c.
+
+In bzlib.c:
+ * made zero-length BZ_FLUSH work correctly in bzCompress().
+ * fixed bzWrite/bzRead to ignore zero-length requests.
+ * fixed bzread to correctly handle read requests after EOF.
+ * wrong parameter order in call to bzDecompressInit in
+ bzBuffToBuffDecompress. Fixed.
+
+In compress.c:
+ * changed setting of nGroups in sendMTFValues() so as to
+ do a bit better on small files. This _does_ effect
+ bzip2.c.
+
+
+0.9.5a
+~~~~~~
+Major change: add a fallback sorting algorithm (blocksort.c)
+to give reasonable behaviour even for very repetitive inputs.
+Nuked --repetitive-best and --repetitive-fast since they are
+no longer useful.
+
+Minor changes: mostly a whole bunch of small changes/
+bugfixes in the driver (bzip2.c). Changes pertaining to the
+user interface are:
+
+ allow decompression of symlink'd files to stdout
+ decompress/test files even without .bz2 extension
+ give more accurate error messages for I/O errors
+ when compressing/decompressing to stdout, don't catch control-C
+ read flags from BZIP2 and BZIP environment variables
+ decline to break hard links to a file unless forced with -f
+ allow -c flag even with no filenames
+ preserve file ownerships as far as possible
+ make -s -1 give the expected block size (100k)
+ add a flag -q --quiet to suppress nonessential warnings
+ stop decoding flags after --, so files beginning in - can be handled
+ resolved inconsistent naming: bzcat or bz2cat ?
+ bzip2 --help now returns 0
+
+Programming-level changes are:
+
+ fixed syntax error in GET_LL4 for Borland C++ 5.02
+ let bzBuffToBuffDecompress return BZ_DATA_ERROR{_MAGIC}
+ fix overshoot of mode-string end in bzopen_or_bzdopen
+ wrapped bzlib.h in #ifdef __cplusplus ... extern "C" { ... }
+ close file handles under all error conditions
+ added minor mods so it compiles with DJGPP out of the box
+ fixed Makefile so it doesn't give problems with BSD make
+ fix uninitialised memory reads in dlltest.c
+
+0.9.5b
+~~~~~~
+Open stdin/stdout in binary mode for DJGPP.
+
+0.9.5c
+~~~~~~
+Changed BZ_N_OVERSHOOT to be ... + 2 instead of ... + 1. The + 1
+version could cause the sorted order to be wrong in some extremely
+obscure cases. Also changed setting of quadrant in blocksort.c.
+
+0.9.5d
+~~~~~~
+The only functional change is to make bzlibVersion() in the library
+return the correct string. This has no effect whatsoever on the
+functioning of the bzip2 program or library. Added a couple of casts
+so the library compiles without warnings at level 3 in MS Visual
+Studio 6.0. Included a Y2K statement in the file Y2K_INFO. All other
+changes are minor documentation changes.
+
+1.0
+~~~
+Several minor bugfixes and enhancements:
+
+* Large file support. The library uses 64-bit counters to
+ count the volume of data passing through it. bzip2.c
+ is now compiled with -D_FILE_OFFSET_BITS=64 to get large
+ file support from the C library. -v correctly prints out
+ file sizes greater than 4 gigabytes. All these changes have
+ been made without assuming a 64-bit platform or a C compiler
+ which supports 64-bit ints, so, except for the C library
+ aspect, they are fully portable.
+
+* Decompression robustness. The library/program should be
+ robust to any corruption of compressed data, detecting and
+ handling _all_ corruption, instead of merely relying on
+ the CRCs. What this means is that the program should
+ never crash, given corrupted data, and the library should
+ always return BZ_DATA_ERROR.
+
+* Fixed an obscure race-condition bug only ever observed on
+ Solaris, in which, if you were very unlucky and issued
+ control-C at exactly the wrong time, both input and output
+ files would be deleted.
+
+* Don't run out of file handles on test/decompression when
+ large numbers of files have invalid magic numbers.
+
+* Avoid library namespace pollution. Prefix all exported
+ symbols with BZ2_.
+
+* Minor sorting enhancements from my DCC2000 paper.
+
+* Advance the version number to 1.0, so as to counteract the
+ (false-in-this-case) impression some people have that programs
+ with version numbers less than 1.0 are in some way, experimental,
+ pre-release versions.
+
+* Create an initial Makefile-libbz2_so to build a shared library.
+ Yes, I know I should really use libtool et al ...
+
+* Make the program exit with 2 instead of 0 when decompression
+ fails due to a bad magic number (ie, an invalid bzip2 header).
+ Also exit with 1 (as the manual claims :-) whenever a diagnostic
+ message would have been printed AND the corresponding operation
+ is aborted, for example
+ bzip2: Output file xx already exists.
+ When a diagnostic message is printed but the operation is not
+ aborted, for example
+ bzip2: Can't guess original name for wurble -- using wurble.out
+ then the exit value 0 is returned, unless some other problem is
+ also detected.
+
+ I think it corresponds more closely to what the manual claims now.
+
+
+1.0.1
+~~~~~
+* Modified dlltest.c so it uses the new BZ2_ naming scheme.
+* Modified makefile-msc to fix minor build probs on Win2k.
+* Updated README.COMPILATION.PROBLEMS.
+
+There are no functionality changes or bug fixes relative to version
+1.0.0. This is just a documentation update + a fix for minor Win32
+build problems. For almost everyone, upgrading from 1.0.0 to 1.0.1 is
+utterly pointless. Don't bother.
+
+
+1.0.2
+~~~~~
+A bug fix release, addressing various minor issues which have appeared
+in the 18 or so months since 1.0.1 was released. Most of the fixes
+are to do with file-handling or documentation bugs. To the best of my
+knowledge, there have been no data-loss-causing bugs reported in the
+compression/decompression engine of 1.0.0 or 1.0.1.
+
+Note that this release does not improve the rather crude build system
+for Unix platforms. The general plan here is to autoconfiscate/
+libtoolise 1.0.2 soon after release, and release the result as 1.1.0
+or perhaps 1.2.0. That, however, is still just a plan at this point.
+
+Here are the changes in 1.0.2. Bug-reporters and/or patch-senders in
+parentheses.
+
+* Fix an infinite segfault loop in 1.0.1 when a directory is
+ encountered in -f (force) mode.
+ (Trond Eivind Glomsrod, Nicholas Nethercote, Volker Schmidt)
+
+* Avoid double fclose() of output file on certain I/O error paths.
+ (Solar Designer)
+
+* Don't fail with internal error 1007 when fed a long stream (> 48MB)
+ of byte 251. Also print useful message suggesting that 1007s may be
+ caused by bad memory.
+ (noticed by Juan Pedro Vallejo, fixed by me)
+
+* Fix uninitialised variable silly bug in demo prog dlltest.c.
+ (Jorj Bauer)
+
+* Remove 512-MB limitation on recovered file size for bzip2recover
+ on selected platforms which support 64-bit ints. At the moment
+ all GCC supported platforms, and Win32.
+ (me, Alson van der Meulen)
+
+* Hard-code header byte values, to give correct operation on platforms
+ using EBCDIC as their native character set (IBM's OS/390).
+ (Leland Lucius)
+
+* Copy file access times correctly.
+ (Marty Leisner)
+
+* Add distclean and check targets to Makefile.
+ (Michael Carmack)
+
+* Parameterise use of ar and ranlib in Makefile. Also add $(LDFLAGS).
+ (Rich Ireland, Bo Thorsen)
+
+* Pass -p (create parent dirs as needed) to mkdir during make install.
+ (Jeremy Fusco)
+
+* Dereference symlinks when copying file permissions in -f mode.
+ (Volker Schmidt)
+
+* Majorly simplify implementation of uInt64_qrm10.
+ (Bo Lindbergh)
+
+* Check the input file still exists before deleting the output one,
+ when aborting in cleanUpAndFail().
+ (Joerg Prante, Robert Linden, Matthias Krings)
+
+Also a bunch of patches courtesy of Philippe Troin, the Debian maintainer
+of bzip2:
+
+* Wrapper scripts (with manpages): bzdiff, bzgrep, bzmore.
+
+* Spelling changes and minor enhancements in bzip2.1.
+
+* Avoid race condition between creating the output file and setting its
+ interim permissions safely, by using fopen_output_safely().
+ No changes to bzip2recover since there is no issue with file
+ permissions there.
+
+* do not print senseless report with -v when compressing an empty
+ file.
+
+* bzcat -f works on non-bzip2 files.
+
+* do not try to escape shell meta-characters on unix (the shell takes
+ care of these).
+
+* added --fast and --best aliases for -1 -9 for gzip compatibility.
+
+
+1.0.3 (15 Feb 05)
+~~~~~~~~~~~~~~~~~
+Fixes some minor bugs since the last version, 1.0.2.
+
+* Further robustification against corrupted compressed data.
+ There are currently no known bitstreams which can cause the
+ decompressor to crash, loop or access memory which does not
+ belong to it. If you are using bzip2 or the library to
+ decompress bitstreams from untrusted sources, an upgrade
+ to 1.0.3 is recommended. This fixes CAN-2005-1260.
+
+* The documentation has been converted to XML, from which html
+ and pdf can be derived.
+
+* Various minor bugs in the documentation have been fixed.
+
+* Fixes for various compilation warnings with newer versions of
+ gcc, and on 64-bit platforms.
+
+* The BZ_NO_STDIO cpp symbol was not properly observed in 1.0.2.
+ This has been fixed.
+
+
+1.0.4 (20 Dec 06)
+~~~~~~~~~~~~~~~~~
+Fixes some minor bugs since the last version, 1.0.3.
+
+* Fix file permissions race problem (CAN-2005-0953).
+
+* Avoid possible segfault in BZ2_bzclose. From Coverity's NetBSD
+ scan.
+
+* 'const'/prototype cleanups in the C code.
+
+* Change default install location to /usr/local, and handle multiple
+ 'make install's without error.
+
+* Sanitise file names more carefully in bzgrep. Fixes CAN-2005-0758
+ to the extent that applies to bzgrep.
+
+* Use 'mktemp' rather than 'tempfile' in bzdiff.
+
+* Tighten up a couple of assertions in blocksort.c following automated
+ analysis.
+
+* Fix minor doc/comment bugs.
+
+
+1.0.5 (10 Dec 07)
+~~~~~~~~~~~~~~~~~
+Security fix only. Fixes CERT-FI 20469 as it applies to bzip2.
+
diff --git a/Utilities/cmbzip2/CMakeLists.txt b/Utilities/cmbzip2/CMakeLists.txt
new file mode 100644
index 000000000..2aff69c08
--- /dev/null
+++ b/Utilities/cmbzip2/CMakeLists.txt
@@ -0,0 +1,4 @@
+project(bzip2)
+add_definitions(-D_FILE_OFFSET_BITS=64)
+add_library(cmbzip2
+ blocksort.c huffman.c crctable.c randtable.c compress.c decompress.c bzlib.c)
diff --git a/Utilities/cmbzip2/LICENSE b/Utilities/cmbzip2/LICENSE
new file mode 100644
index 000000000..f420cffb6
--- /dev/null
+++ b/Utilities/cmbzip2/LICENSE
@@ -0,0 +1,42 @@
+
+--------------------------------------------------------------------------
+
+This program, "bzip2", the associated library "libbzip2", and all
+documentation, are copyright (C) 1996-2007 Julian R Seward. 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. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+
+3. Altered source versions must be plainly marked as such, and must
+ not be misrepresented as being the original software.
+
+4. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
+
+Julian Seward, jseward@bzip.org
+bzip2/libbzip2 version 1.0.5 of 10 December 2007
+
+--------------------------------------------------------------------------
diff --git a/Utilities/cmbzip2/Makefile-libbz2_so b/Utilities/cmbzip2/Makefile-libbz2_so
new file mode 100644
index 000000000..83708871c
--- /dev/null
+++ b/Utilities/cmbzip2/Makefile-libbz2_so
@@ -0,0 +1,59 @@
+
+# This Makefile builds a shared version of the library,
+# libbz2.so.1.0.4, with soname libbz2.so.1.0,
+# at least on x86-Linux (RedHat 7.2),
+# with gcc-2.96 20000731 (Red Hat Linux 7.1 2.96-98).
+# Please see the README file for some important info
+# about building the library like this.
+
+# ------------------------------------------------------------------
+# This file is part of bzip2/libbzip2, a program and library for
+# lossless, block-sorting data compression.
+#
+# bzip2/libbzip2 version 1.0.5 of 10 December 2007
+# Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+#
+# Please read the WARNING, DISCLAIMER and PATENTS sections in the
+# README file.
+#
+# This program is released under the terms of the license contained
+# in the file LICENSE.
+# ------------------------------------------------------------------
+
+
+SHELL=/bin/sh
+CC=gcc
+BIGFILES=-D_FILE_OFFSET_BITS=64
+CFLAGS=-fpic -fPIC -Wall -Winline -O2 -g $(BIGFILES)
+
+OBJS= blocksort.o \
+ huffman.o \
+ crctable.o \
+ randtable.o \
+ compress.o \
+ decompress.o \
+ bzlib.o
+
+all: $(OBJS)
+ $(CC) -shared -Wl,-soname -Wl,libbz2.so.1.0 -o libbz2.so.1.0.4 $(OBJS)
+ $(CC) $(CFLAGS) -o bzip2-shared bzip2.c libbz2.so.1.0.4
+ rm -f libbz2.so.1.0
+ ln -s libbz2.so.1.0.4 libbz2.so.1.0
+
+clean:
+ rm -f $(OBJS) bzip2.o libbz2.so.1.0.4 libbz2.so.1.0 bzip2-shared
+
+blocksort.o: blocksort.c
+ $(CC) $(CFLAGS) -c blocksort.c
+huffman.o: huffman.c
+ $(CC) $(CFLAGS) -c huffman.c
+crctable.o: crctable.c
+ $(CC) $(CFLAGS) -c crctable.c
+randtable.o: randtable.c
+ $(CC) $(CFLAGS) -c randtable.c
+compress.o: compress.c
+ $(CC) $(CFLAGS) -c compress.c
+decompress.o: decompress.c
+ $(CC) $(CFLAGS) -c decompress.c
+bzlib.o: bzlib.c
+ $(CC) $(CFLAGS) -c bzlib.c
diff --git a/Utilities/cmbzip2/README b/Utilities/cmbzip2/README
new file mode 100644
index 000000000..e17a84e04
--- /dev/null
+++ b/Utilities/cmbzip2/README
@@ -0,0 +1,210 @@
+
+This is the README for bzip2/libzip2.
+This version is fully compatible with the previous public releases.
+
+------------------------------------------------------------------
+This file is part of bzip2/libbzip2, a program and library for
+lossless, block-sorting data compression.
+
+bzip2/libbzip2 version 1.0.5 of 10 December 2007
+Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+
+Please read the WARNING, DISCLAIMER and PATENTS sections in this file.
+
+This program is released under the terms of the license contained
+in the file LICENSE.
+------------------------------------------------------------------
+
+Complete documentation is available in Postscript form (manual.ps),
+PDF (manual.pdf) or html (manual.html). A plain-text version of the
+manual page is available as bzip2.txt.
+
+
+HOW TO BUILD -- UNIX
+
+Type 'make'. This builds the library libbz2.a and then the programs
+bzip2 and bzip2recover. Six self-tests are run. If the self-tests
+complete ok, carry on to installation:
+
+To install in /usr/local/bin, /usr/local/lib, /usr/local/man and
+/usr/local/include, type
+
+ make install
+
+To install somewhere else, eg, /xxx/yyy/{bin,lib,man,include}, type
+
+ make install PREFIX=/xxx/yyy
+
+If you are (justifiably) paranoid and want to see what 'make install'
+is going to do, you can first do
+
+ make -n install or
+ make -n install PREFIX=/xxx/yyy respectively.
+
+The -n instructs make to show the commands it would execute, but not
+actually execute them.
+
+
+HOW TO BUILD -- UNIX, shared library libbz2.so.
+
+Do 'make -f Makefile-libbz2_so'. This Makefile seems to work for
+Linux-ELF (RedHat 7.2 on an x86 box), with gcc. I make no claims
+that it works for any other platform, though I suspect it probably
+will work for most platforms employing both ELF and gcc.
+
+bzip2-shared, a client of the shared library, is also built, but not
+self-tested. So I suggest you also build using the normal Makefile,
+since that conducts a self-test. A second reason to prefer the
+version statically linked to the library is that, on x86 platforms,
+building shared objects makes a valuable register (%ebx) unavailable
+to gcc, resulting in a slowdown of 10%-20%, at least for bzip2.
+
+Important note for people upgrading .so's from 0.9.0/0.9.5 to version
+1.0.X. All the functions in the library have been renamed, from (eg)
+bzCompress to BZ2_bzCompress, to avoid namespace pollution.
+Unfortunately this means that the libbz2.so created by
+Makefile-libbz2_so will not work with any program which used an older
+version of the library. I do encourage library clients to make the
+effort to upgrade to use version 1.0, since it is both faster and more
+robust than previous versions.
+
+
+HOW TO BUILD -- Windows 95, NT, DOS, Mac, etc.
+
+It's difficult for me to support compilation on all these platforms.
+My approach is to collect binaries for these platforms, and put them
+on the master web site (http://www.bzip.org). Look there. However
+(FWIW), bzip2-1.0.X is very standard ANSI C and should compile
+unmodified with MS Visual C. If you have difficulties building, you
+might want to read README.COMPILATION.PROBLEMS.
+
+At least using MS Visual C++ 6, you can build from the unmodified
+sources by issuing, in a command shell:
+
+ nmake -f makefile.msc
+
+(you may need to first run the MSVC-provided script VCVARS32.BAT
+ so as to set up paths to the MSVC tools correctly).
+
+
+VALIDATION
+
+Correct operation, in the sense that a compressed file can always be
+decompressed to reproduce the original, is obviously of paramount
+importance. To validate bzip2, I used a modified version of Mark
+Nelson's churn program. Churn is an automated test driver which
+recursively traverses a directory structure, using bzip2 to compress
+and then decompress each file it encounters, and checking that the
+decompressed data is the same as the original.
+
+
+
+Please read and be aware of the following:
+
+WARNING:
+
+ This program and library (attempts to) compress data by
+ performing several non-trivial transformations on it.
+ Unless you are 100% familiar with *all* the algorithms
+ contained herein, and with the consequences of modifying them,
+ you should NOT meddle with the compression or decompression
+ machinery. Incorrect changes can and very likely *will*
+ lead to disastrous loss of data.
+
+
+DISCLAIMER:
+
+ I TAKE NO RESPONSIBILITY FOR ANY LOSS OF DATA ARISING FROM THE
+ USE OF THIS PROGRAM/LIBRARY, HOWSOEVER CAUSED.
+
+ Every compression of a file implies an assumption that the
+ compressed file can be decompressed to reproduce the original.
+ Great efforts in design, coding and testing have been made to
+ ensure that this program works correctly. However, the complexity
+ of the algorithms, and, in particular, the presence of various
+ special cases in the code which occur with very low but non-zero
+ probability make it impossible to rule out the possibility of bugs
+ remaining in the program. DO NOT COMPRESS ANY DATA WITH THIS
+ PROGRAM UNLESS YOU ARE PREPARED TO ACCEPT THE POSSIBILITY, HOWEVER
+ SMALL, THAT THE DATA WILL NOT BE RECOVERABLE.
+
+ That is not to say this program is inherently unreliable.
+ Indeed, I very much hope the opposite is true. bzip2/libbzip2
+ has been carefully constructed and extensively tested.
+
+
+PATENTS:
+
+ To the best of my knowledge, bzip2/libbzip2 does not use any
+ patented algorithms. However, I do not have the resources
+ to carry out a patent search. Therefore I cannot give any
+ guarantee of the above statement.
+
+
+
+WHAT'S NEW IN 0.9.0 (as compared to 0.1pl2) ?
+
+ * Approx 10% faster compression, 30% faster decompression
+ * -t (test mode) is a lot quicker
+ * Can decompress concatenated compressed files
+ * Programming interface, so programs can directly read/write .bz2 files
+ * Less restrictive (BSD-style) licensing
+ * Flag handling more compatible with GNU gzip
+ * Much more documentation, i.e., a proper user manual
+ * Hopefully, improved portability (at least of the library)
+
+WHAT'S NEW IN 0.9.5 ?
+
+ * Compression speed is much less sensitive to the input
+ data than in previous versions. Specifically, the very
+ slow performance caused by repetitive data is fixed.
+ * Many small improvements in file and flag handling.
+ * A Y2K statement.
+
+WHAT'S NEW IN 1.0.0 ?
+
+ See the CHANGES file.
+
+WHAT'S NEW IN 1.0.2 ?
+
+ See the CHANGES file.
+
+WHAT'S NEW IN 1.0.3 ?
+
+ See the CHANGES file.
+
+WHAT'S NEW IN 1.0.4 ?
+
+ See the CHANGES file.
+
+WHAT'S NEW IN 1.0.5 ?
+
+ See the CHANGES file.
+
+
+I hope you find bzip2 useful. Feel free to contact me at
+ jseward@bzip.org
+if you have any suggestions or queries. Many people mailed me with
+comments, suggestions and patches after the releases of bzip-0.15,
+bzip-0.21, and bzip2 versions 0.1pl2, 0.9.0, 0.9.5, 1.0.0, 1.0.1,
+1.0.2 and 1.0.3, and the changes in bzip2 are largely a result of this
+feedback. I thank you for your comments.
+
+bzip2's "home" is http://www.bzip.org/
+
+Julian Seward
+jseward@bzip.org
+Cambridge, UK.
+
+18 July 1996 (version 0.15)
+25 August 1996 (version 0.21)
+ 7 August 1997 (bzip2, version 0.1)
+29 August 1997 (bzip2, version 0.1pl2)
+23 August 1998 (bzip2, version 0.9.0)
+ 8 June 1999 (bzip2, version 0.9.5)
+ 4 Sept 1999 (bzip2, version 0.9.5d)
+ 5 May 2000 (bzip2, version 1.0pre8)
+30 December 2001 (bzip2, version 1.0.2pre1)
+15 February 2005 (bzip2, version 1.0.3)
+20 December 2006 (bzip2, version 1.0.4)
+10 December 2007 (bzip2, version 1.0.5)
diff --git a/Utilities/cmbzip2/README.COMPILATION.PROBLEMS b/Utilities/cmbzip2/README.COMPILATION.PROBLEMS
new file mode 100644
index 000000000..22b95c6cb
--- /dev/null
+++ b/Utilities/cmbzip2/README.COMPILATION.PROBLEMS
@@ -0,0 +1,58 @@
+------------------------------------------------------------------
+This file is part of bzip2/libbzip2, a program and library for
+lossless, block-sorting data compression.
+
+bzip2/libbzip2 version 1.0.5 of 10 December 2007
+Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+
+Please read the WARNING, DISCLAIMER and PATENTS sections in the
+README file.
+
+This program is released under the terms of the license contained
+in the file LICENSE.
+------------------------------------------------------------------
+
+bzip2-1.0.5 should compile without problems on the vast majority of
+platforms. Using the supplied Makefile, I've built and tested it
+myself for x86-linux and amd64-linux. With makefile.msc, Visual C++
+6.0 and nmake, you can build a native Win32 version too. Large file
+support seems to work correctly on at least on amd64-linux.
+
+When I say "large file" I mean a file of size 2,147,483,648 (2^31)
+bytes or above. Many older OSs can't handle files above this size,
+but many newer ones can. Large files are pretty huge -- most files
+you'll encounter are not Large Files.
+
+Early versions of bzip2 (0.1, 0.9.0, 0.9.5) compiled on a wide variety
+of platforms without difficulty, and I hope this version will continue
+in that tradition. However, in order to support large files, I've had
+to include the define -D_FILE_OFFSET_BITS=64 in the Makefile. This
+can cause problems.
+
+The technique of adding -D_FILE_OFFSET_BITS=64 to get large file
+support is, as far as I know, the Recommended Way to get correct large
+file support. For more details, see the Large File Support
+Specification, published by the Large File Summit, at
+
+ http://ftp.sas.com/standards/large.file
+
+As a general comment, if you get compilation errors which you think
+are related to large file support, try removing the above define from
+the Makefile, ie, delete the line
+
+ BIGFILES=-D_FILE_OFFSET_BITS=64
+
+from the Makefile, and do 'make clean ; make'. This will give you a
+version of bzip2 without large file support, which, for most
+applications, is probably not a problem.
+
+Alternatively, try some of the platform-specific hints listed below.
+
+You can use the spewG.c program to generate huge files to test bzip2's
+large file support, if you are feeling paranoid. Be aware though that
+any compilation problems which affect bzip2 will also affect spewG.c,
+alas.
+
+AIX: I have reports that for large file support, you need to specify
+-D_LARGE_FILES rather than -D_FILE_OFFSET_BITS=64. I have not tested
+this myself.
diff --git a/Utilities/cmbzip2/README.XML.STUFF b/Utilities/cmbzip2/README.XML.STUFF
new file mode 100644
index 000000000..1a5b4c55a
--- /dev/null
+++ b/Utilities/cmbzip2/README.XML.STUFF
@@ -0,0 +1,45 @@
+ ----------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
+
+ bzip2/libbzip2 version 1.0.5 of 10 December 2007
+ Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
+
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ----------------------------------------------------------------
+
+The script xmlproc.sh takes an xml file as input,
+and processes it to create .pdf, .html or .ps output.
+It uses format.pl, a perl script to format <pre> blocks nicely,
+ and add CDATA tags so writers do not have to use eg. &lt;
+
+The file "entities.xml" must be edited to reflect current
+version, year, etc.
+
+
+Usage:
+
+ ./xmlproc.sh -v manual.xml
+ Validates an xml file to ensure no dtd-compliance errors
+
+ ./xmlproc.sh -html manual.xml
+ Output: manual.html
+
+ ./xmlproc.sh -pdf manual.xml
+ Output: manual.pdf
+
+ ./xmlproc.sh -ps manual.xml
+ Output: manual.ps
+
+
+Notum bene:
+- pdfxmltex barfs if given a filename with an underscore in it
+
+- xmltex won't work yet - there's a bug in passivetex
+ which we are all waiting for Sebastian to fix.
+ So we are going the xml -> pdf -> ps route for the time being,
+ using pdfxmltex.
diff --git a/Utilities/cmbzip2/blocksort.c b/Utilities/cmbzip2/blocksort.c
new file mode 100644
index 000000000..95adb5ef3
--- /dev/null
+++ b/Utilities/cmbzip2/blocksort.c
@@ -0,0 +1,1094 @@
+
+/*-------------------------------------------------------------*/
+/*--- Block sorting machinery ---*/
+/*--- blocksort.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
+
+ bzip2/libbzip2 version 1.0.5 of 10 December 2007
+ Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
+
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------ */
+
+
+#include "bzlib_private.h"
+
+/*---------------------------------------------*/
+/*--- Fallback O(N log(N)^2) sorting ---*/
+/*--- algorithm, for repetitive blocks ---*/
+/*---------------------------------------------*/
+
+/*---------------------------------------------*/
+static
+__inline__
+void fallbackSimpleSort ( UInt32* fmap,
+ UInt32* eclass,
+ Int32 lo,
+ Int32 hi )
+{
+ Int32 i, j, tmp;
+ UInt32 ec_tmp;
+
+ if (lo == hi) return;
+
+ if (hi - lo > 3) {
+ for ( i = hi-4; i >= lo; i-- ) {
+ tmp = fmap[i];
+ ec_tmp = eclass[tmp];
+ for ( j = i+4; j <= hi && ec_tmp > eclass[fmap[j]]; j += 4 )
+ fmap[j-4] = fmap[j];
+ fmap[j-4] = tmp;
+ }
+ }
+
+ for ( i = hi-1; i >= lo; i-- ) {
+ tmp = fmap[i];
+ ec_tmp = eclass[tmp];
+ for ( j = i+1; j <= hi && ec_tmp > eclass[fmap[j]]; j++ )
+ fmap[j-1] = fmap[j];
+ fmap[j-1] = tmp;
+ }
+}
+
+
+/*---------------------------------------------*/
+#define fswap(zz1, zz2) \
+ { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
+
+#define fvswap(zzp1, zzp2, zzn) \
+{ \
+ Int32 yyp1 = (zzp1); \
+ Int32 yyp2 = (zzp2); \
+ Int32 yyn = (zzn); \
+ while (yyn > 0) { \
+ fswap(fmap[yyp1], fmap[yyp2]); \
+ yyp1++; yyp2++; yyn--; \
+ } \
+}
+
+
+#define fmin(a,b) ((a) < (b)) ? (a) : (b)
+
+#define fpush(lz,hz) { stackLo[sp] = lz; \
+ stackHi[sp] = hz; \
+ sp++; }
+
+#define fpop(lz,hz) { sp--; \
+ lz = stackLo[sp]; \
+ hz = stackHi[sp]; }
+
+#define FALLBACK_QSORT_SMALL_THRESH 10
+#define FALLBACK_QSORT_STACK_SIZE 100
+
+
+static
+void fallbackQSort3 ( UInt32* fmap,
+ UInt32* eclass,
+ Int32 loSt,
+ Int32 hiSt )
+{
+ Int32 unLo, unHi, ltLo, gtHi, n, m;
+ Int32 sp, lo, hi;
+ UInt32 med, r, r3;
+ Int32 stackLo[FALLBACK_QSORT_STACK_SIZE];
+ Int32 stackHi[FALLBACK_QSORT_STACK_SIZE];
+
+ r = 0;
+
+ sp = 0;
+ fpush ( loSt, hiSt );
+
+ while (sp > 0) {
+
+ AssertH ( sp < FALLBACK_QSORT_STACK_SIZE - 1, 1004 );
+
+ fpop ( lo, hi );
+ if (hi - lo < FALLBACK_QSORT_SMALL_THRESH) {
+ fallbackSimpleSort ( fmap, eclass, lo, hi );
+ continue;
+ }
+
+ /* Random partitioning. Median of 3 sometimes fails to
+ avoid bad cases. Median of 9 seems to help but
+ looks rather expensive. This too seems to work but
+ is cheaper. Guidance for the magic constants
+ 7621 and 32768 is taken from Sedgewick's algorithms
+ book, chapter 35.
+ */
+ r = ((r * 7621) + 1) % 32768;
+ r3 = r % 3;
+ if (r3 == 0) med = eclass[fmap[lo]]; else
+ if (r3 == 1) med = eclass[fmap[(lo+hi)>>1]]; else
+ med = eclass[fmap[hi]];
+
+ unLo = ltLo = lo;
+ unHi = gtHi = hi;
+
+ while (1) {
+ while (1) {
+ if (unLo > unHi) break;
+ n = (Int32)eclass[fmap[unLo]] - (Int32)med;
+ if (n == 0) {
+ fswap(fmap[unLo], fmap[ltLo]);
+ ltLo++; unLo++;
+ continue;
+ };
+ if (n > 0) break;
+ unLo++;
+ }
+ while (1) {
+ if (unLo > unHi) break;
+ n = (Int32)eclass[fmap[unHi]] - (Int32)med;
+ if (n == 0) {
+ fswap(fmap[unHi], fmap[gtHi]);
+ gtHi--; unHi--;
+ continue;
+ };
+ if (n < 0) break;
+ unHi--;
+ }
+ if (unLo > unHi) break;
+ fswap(fmap[unLo], fmap[unHi]); unLo++; unHi--;
+ }
+
+ AssertD ( unHi == unLo-1, "fallbackQSort3(2)" );
+
+ if (gtHi < ltLo) continue;
+
+ n = fmin(ltLo-lo, unLo-ltLo); fvswap(lo, unLo-n, n);
+ m = fmin(hi-gtHi, gtHi-unHi); fvswap(unLo, hi-m+1, m);
+
+ n = lo + unLo - ltLo - 1;
+ m = hi - (gtHi - unHi) + 1;
+
+ if (n - lo > hi - m) {
+ fpush ( lo, n );
+ fpush ( m, hi );
+ } else {
+ fpush ( m, hi );
+ fpush ( lo, n );
+ }
+ }
+}
+
+#undef fmin
+#undef fpush
+#undef fpop
+#undef fswap
+#undef fvswap
+#undef FALLBACK_QSORT_SMALL_THRESH
+#undef FALLBACK_QSORT_STACK_SIZE
+
+
+/*---------------------------------------------*/
+/* Pre:
+ nblock > 0
+ eclass exists for [0 .. nblock-1]
+ ((UChar*)eclass) [0 .. nblock-1] holds block
+ ptr exists for [0 .. nblock-1]
+
+ Post:
+ ((UChar*)eclass) [0 .. nblock-1] holds block
+ All other areas of eclass destroyed
+ fmap [0 .. nblock-1] holds sorted order
+ bhtab [ 0 .. 2+(nblock/32) ] destroyed
+*/
+
+#define SET_BH(zz) bhtab[(zz) >> 5] |= (1 << ((zz) & 31))
+#define CLEAR_BH(zz) bhtab[(zz) >> 5] &= ~(1 << ((zz) & 31))
+#define ISSET_BH(zz) (bhtab[(zz) >> 5] & (1 << ((zz) & 31)))
+#define WORD_BH(zz) bhtab[(zz) >> 5]
+#define UNALIGNED_BH(zz) ((zz) & 0x01f)
+
+static
+void fallbackSort ( UInt32* fmap,
+ UInt32* eclass,
+ UInt32* bhtab,
+ Int32 nblock,
+ Int32 verb )
+{
+ Int32 ftab[257];
+ Int32 ftabCopy[256];
+ Int32 H, i, j, k, l, r, cc, cc1;
+ Int32 nNotDone;
+ Int32 nBhtab;
+ UChar* eclass8 = (UChar*)eclass;
+
+ /*--
+ Initial 1-char radix sort to generate
+ initial fmap and initial BH bits.
+ --*/
+ if (verb >= 4)
+ VPrintf0 ( " bucket sorting ...\n" );
+ for (i = 0; i < 257; i++) ftab[i] = 0;
+ for (i = 0; i < nblock; i++) ftab[eclass8[i]]++;
+ for (i = 0; i < 256; i++) ftabCopy[i] = ftab[i];
+ for (i = 1; i < 257; i++) ftab[i] += ftab[i-1];
+
+ for (i = 0; i < nblock; i++) {
+ j = eclass8[i];
+ k = ftab[j] - 1;
+ ftab[j] = k;
+ fmap[k] = i;
+ }
+
+ nBhtab = 2 + (nblock / 32);
+ for (i = 0; i < nBhtab; i++) bhtab[i] = 0;
+ for (i = 0; i < 256; i++) SET_BH(ftab[i]);
+
+ /*--
+ Inductively refine the buckets. Kind-of an
+ "exponential radix sort" (!), inspired by the
+ Manber-Myers suffix array construction algorithm.
+ --*/
+
+ /*-- set sentinel bits for block-end detection --*/
+ for (i = 0; i < 32; i++) {
+ SET_BH(nblock + 2*i);
+ CLEAR_BH(nblock + 2*i + 1);
+ }
+
+ /*-- the log(N) loop --*/
+ H = 1;
+ while (1) {
+
+ if (verb >= 4)
+ VPrintf1 ( " depth %6d has ", H );
+
+ j = 0;
+ for (i = 0; i < nblock; i++) {
+ if (ISSET_BH(i)) j = i;
+ k = fmap[i] - H; if (k < 0) k += nblock;
+ eclass[k] = j;
+ }
+
+ nNotDone = 0;
+ r = -1;
+ while (1) {
+
+ /*-- find the next non-singleton bucket --*/
+ k = r + 1;
+ while (ISSET_BH(k) && UNALIGNED_BH(k)) k++;
+ if (ISSET_BH(k)) {
+ while (WORD_BH(k) == 0xffffffff) k += 32;
+ while (ISSET_BH(k)) k++;
+ }
+ l = k - 1;
+ if (l >= nblock) break;
+ while (!ISSET_BH(k) && UNALIGNED_BH(k)) k++;
+ if (!ISSET_BH(k)) {
+ while (WORD_BH(k) == 0x00000000) k += 32;
+ while (!ISSET_BH(k)) k++;
+ }
+ r = k - 1;
+ if (r >= nblock) break;
+
+ /*-- now [l, r] bracket current bucket --*/
+ if (r > l) {
+ nNotDone += (r - l + 1);
+ fallbackQSort3 ( fmap, eclass, l, r );
+
+ /*-- scan bucket and generate header bits-- */
+ cc = -1;
+ for (i = l; i <= r; i++) {
+ cc1 = eclass[fmap[i]];
+ if (cc != cc1) { SET_BH(i); cc = cc1; };
+ }
+ }
+ }
+
+ if (verb >= 4)
+ VPrintf1 ( "%6d unresolved strings\n", nNotDone );
+
+ H *= 2;
+ if (H > nblock || nNotDone == 0) break;
+ }
+
+ /*--
+ Reconstruct the original block in
+ eclass8 [0 .. nblock-1], since the
+ previous phase destroyed it.
+ --*/
+ if (verb >= 4)
+ VPrintf0 ( " reconstructing block ...\n" );
+ j = 0;
+ for (i = 0; i < nblock; i++) {
+ while (ftabCopy[j] == 0) j++;
+ ftabCopy[j]--;
+ eclass8[fmap[i]] = (UChar)j;
+ }
+ AssertH ( j < 256, 1005 );
+}
+
+#undef SET_BH
+#undef CLEAR_BH
+#undef ISSET_BH
+#undef WORD_BH
+#undef UNALIGNED_BH
+
+
+/*---------------------------------------------*/
+/*--- The main, O(N^2 log(N)) sorting ---*/
+/*--- algorithm. Faster for "normal" ---*/
+/*--- non-repetitive blocks. ---*/
+/*---------------------------------------------*/
+
+/*---------------------------------------------*/
+static
+__inline__
+Bool mainGtU ( UInt32 i1,
+ UInt32 i2,
+ UChar* block,
+ UInt16* quadrant,
+ UInt32 nblock,
+ Int32* budget )
+{
+ Int32 k;
+ UChar c1, c2;
+ UInt16 s1, s2;
+
+ AssertD ( i1 != i2, "mainGtU" );
+ /* 1 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ i1++; i2++;
+ /* 2 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ i1++; i2++;
+ /* 3 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ i1++; i2++;
+ /* 4 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ i1++; i2++;
+ /* 5 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ i1++; i2++;
+ /* 6 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ i1++; i2++;
+ /* 7 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ i1++; i2++;
+ /* 8 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ i1++; i2++;
+ /* 9 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ i1++; i2++;
+ /* 10 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ i1++; i2++;
+ /* 11 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ i1++; i2++;
+ /* 12 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ i1++; i2++;
+
+ k = nblock + 8;
+
+ do {
+ /* 1 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ s1 = quadrant[i1]; s2 = quadrant[i2];
+ if (s1 != s2) return (s1 > s2);
+ i1++; i2++;
+ /* 2 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ s1 = quadrant[i1]; s2 = quadrant[i2];
+ if (s1 != s2) return (s1 > s2);
+ i1++; i2++;
+ /* 3 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ s1 = quadrant[i1]; s2 = quadrant[i2];
+ if (s1 != s2) return (s1 > s2);
+ i1++; i2++;
+ /* 4 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ s1 = quadrant[i1]; s2 = quadrant[i2];
+ if (s1 != s2) return (s1 > s2);
+ i1++; i2++;
+ /* 5 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ s1 = quadrant[i1]; s2 = quadrant[i2];
+ if (s1 != s2) return (s1 > s2);
+ i1++; i2++;
+ /* 6 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ s1 = quadrant[i1]; s2 = quadrant[i2];
+ if (s1 != s2) return (s1 > s2);
+ i1++; i2++;
+ /* 7 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ s1 = quadrant[i1]; s2 = quadrant[i2];
+ if (s1 != s2) return (s1 > s2);
+ i1++; i2++;
+ /* 8 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ s1 = quadrant[i1]; s2 = quadrant[i2];
+ if (s1 != s2) return (s1 > s2);
+ i1++; i2++;
+
+ if (i1 >= nblock) i1 -= nblock;
+ if (i2 >= nblock) i2 -= nblock;
+
+ k -= 8;
+ (*budget)--;
+ }
+ while (k >= 0);
+
+ return False;
+}
+
+
+/*---------------------------------------------*/
+/*--
+ Knuth's increments seem to work better
+ than Incerpi-Sedgewick here. Possibly
+ because the number of elems to sort is
+ usually small, typically <= 20.
+--*/
+static
+Int32 incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280,
+ 9841, 29524, 88573, 265720,
+ 797161, 2391484 };
+
+static
+void mainSimpleSort ( UInt32* ptr,
+ UChar* block,
+ UInt16* quadrant,
+ Int32 nblock,
+ Int32 lo,
+ Int32 hi,
+ Int32 d,
+ Int32* budget )
+{
+ Int32 i, j, h, bigN, hp;
+ UInt32 v;
+
+ bigN = hi - lo + 1;
+ if (bigN < 2) return;
+
+ hp = 0;
+ while (incs[hp] < bigN) hp++;
+ hp--;
+
+ for (; hp >= 0; hp--) {
+ h = incs[hp];
+
+ i = lo + h;
+ while (True) {
+
+ /*-- copy 1 --*/
+ if (i > hi) break;
+ v = ptr[i];
+ j = i;
+ while ( mainGtU (
+ ptr[j-h]+d, v+d, block, quadrant, nblock, budget
+ ) ) {
+ ptr[j] = ptr[j-h];
+ j = j - h;
+ if (j <= (lo + h - 1)) break;
+ }
+ ptr[j] = v;
+ i++;
+
+ /*-- copy 2 --*/
+ if (i > hi) break;
+ v = ptr[i];
+ j = i;
+ while ( mainGtU (
+ ptr[j-h]+d, v+d, block, quadrant, nblock, budget
+ ) ) {
+ ptr[j] = ptr[j-h];
+ j = j - h;
+ if (j <= (lo + h - 1)) break;
+ }
+ ptr[j] = v;
+ i++;
+
+ /*-- copy 3 --*/
+ if (i > hi) break;
+ v = ptr[i];
+ j = i;
+ while ( mainGtU (
+ ptr[j-h]+d, v+d, block, quadrant, nblock, budget
+ ) ) {
+ ptr[j] = ptr[j-h];
+ j = j - h;
+ if (j <= (lo + h - 1)) break;
+ }
+ ptr[j] = v;
+ i++;
+
+ if (*budget < 0) return;
+ }
+ }
+}
+
+
+/*---------------------------------------------*/
+/*--
+ The following is an implementation of
+ an elegant 3-way quicksort for strings,
+ described in a paper "Fast Algorithms for
+ Sorting and Searching Strings", by Robert
+ Sedgewick and Jon L. Bentley.
+--*/
+
+#define mswap(zz1, zz2) \
+ { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
+
+#define mvswap(zzp1, zzp2, zzn) \
+{ \
+ Int32 yyp1 = (zzp1); \
+ Int32 yyp2 = (zzp2); \
+ Int32 yyn = (zzn); \
+ while (yyn > 0) { \
+ mswap(ptr[yyp1], ptr[yyp2]); \
+ yyp1++; yyp2++; yyn--; \
+ } \
+}
+
+static
+__inline__
+UChar mmed3 ( UChar a, UChar b, UChar c )
+{
+ UChar t;
+ if (a > b) { t = a; a = b; b = t; };
+ if (b > c) {
+ b = c;
+ if (a > b) b = a;
+ }
+ return b;
+}
+
+#define mmin(a,b) ((a) < (b)) ? (a) : (b)
+
+#define mpush(lz,hz,dz) { stackLo[sp] = lz; \
+ stackHi[sp] = hz; \
+ stackD [sp] = dz; \
+ sp++; }
+
+#define mpop(lz,hz,dz) { sp--; \
+ lz = stackLo[sp]; \
+ hz = stackHi[sp]; \
+ dz = stackD [sp]; }
+
+
+#define mnextsize(az) (nextHi[az]-nextLo[az])
+
+#define mnextswap(az,bz) \
+ { Int32 tz; \
+ tz = nextLo[az]; nextLo[az] = nextLo[bz]; nextLo[bz] = tz; \
+ tz = nextHi[az]; nextHi[az] = nextHi[bz]; nextHi[bz] = tz; \
+ tz = nextD [az]; nextD [az] = nextD [bz]; nextD [bz] = tz; }
+
+
+#define MAIN_QSORT_SMALL_THRESH 20
+#define MAIN_QSORT_DEPTH_THRESH (BZ_N_RADIX + BZ_N_QSORT)
+#define MAIN_QSORT_STACK_SIZE 100
+
+static
+void mainQSort3 ( UInt32* ptr,
+ UChar* block,
+ UInt16* quadrant,
+ Int32 nblock,
+ Int32 loSt,
+ Int32 hiSt,
+ Int32 dSt,
+ Int32* budget )
+{
+ Int32 unLo, unHi, ltLo, gtHi, n, m, med;
+ Int32 sp, lo, hi, d;
+
+ Int32 stackLo[MAIN_QSORT_STACK_SIZE];
+ Int32 stackHi[MAIN_QSORT_STACK_SIZE];
+ Int32 stackD [MAIN_QSORT_STACK_SIZE];
+
+ Int32 nextLo[3];
+ Int32 nextHi[3];
+ Int32 nextD [3];
+
+ sp = 0;
+ mpush ( loSt, hiSt, dSt );
+
+ while (sp > 0) {
+
+ AssertH ( sp < MAIN_QSORT_STACK_SIZE - 2, 1001 );
+
+ mpop ( lo, hi, d );
+ if (hi - lo < MAIN_QSORT_SMALL_THRESH ||
+ d > MAIN_QSORT_DEPTH_THRESH) {
+ mainSimpleSort ( ptr, block, quadrant, nblock, lo, hi, d, budget );
+ if (*budget < 0) return;
+ continue;
+ }
+
+ med = (Int32)
+ mmed3 ( block[ptr[ lo ]+d],
+ block[ptr[ hi ]+d],
+ block[ptr[ (lo+hi)>>1 ]+d] );
+
+ unLo = ltLo = lo;
+ unHi = gtHi = hi;
+
+ while (True) {
+ while (True) {
+ if (unLo > unHi) break;
+ n = ((Int32)block[ptr[unLo]+d]) - med;
+ if (n == 0) {
+ mswap(ptr[unLo], ptr[ltLo]);
+ ltLo++; unLo++; continue;
+ };
+ if (n > 0) break;
+ unLo++;
+ }
+ while (True) {
+ if (unLo > unHi) break;
+ n = ((Int32)block[ptr[unHi]+d]) - med;
+ if (n == 0) {
+ mswap(ptr[unHi], ptr[gtHi]);
+ gtHi--; unHi--; continue;
+ };
+ if (n < 0) break;
+ unHi--;
+ }
+ if (unLo > unHi) break;
+ mswap(ptr[unLo], ptr[unHi]); unLo++; unHi--;
+ }
+
+ AssertD ( unHi == unLo-1, "mainQSort3(2)" );
+
+ if (gtHi < ltLo) {
+ mpush(lo, hi, d+1 );
+ continue;
+ }
+
+ n = mmin(ltLo-lo, unLo-ltLo); mvswap(lo, unLo-n, n);
+ m = mmin(hi-gtHi, gtHi-unHi); mvswap(unLo, hi-m+1, m);
+
+ n = lo + unLo - ltLo - 1;
+ m = hi - (gtHi - unHi) + 1;
+
+ nextLo[0] = lo; nextHi[0] = n; nextD[0] = d;
+ nextLo[1] = m; nextHi[1] = hi; nextD[1] = d;
+ nextLo[2] = n+1; nextHi[2] = m-1; nextD[2] = d+1;
+
+ if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
+ if (mnextsize(1) < mnextsize(2)) mnextswap(1,2);
+ if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
+
+ AssertD (mnextsize(0) >= mnextsize(1), "mainQSort3(8)" );
+ AssertD (mnextsize(1) >= mnextsize(2), "mainQSort3(9)" );
+
+ mpush (nextLo[0], nextHi[0], nextD[0]);
+ mpush (nextLo[1], nextHi[1], nextD[1]);
+ mpush (nextLo[2], nextHi[2], nextD[2]);
+ }
+}
+
+#undef mswap
+#undef mvswap
+#undef mpush
+#undef mpop
+#undef mmin
+#undef mnextsize
+#undef mnextswap
+#undef MAIN_QSORT_SMALL_THRESH
+#undef MAIN_QSORT_DEPTH_THRESH
+#undef MAIN_QSORT_STACK_SIZE
+
+
+/*---------------------------------------------*/
+/* Pre:
+ nblock > N_OVERSHOOT
+ block32 exists for [0 .. nblock-1 +N_OVERSHOOT]
+ ((UChar*)block32) [0 .. nblock-1] holds block
+ ptr exists for [0 .. nblock-1]
+
+ Post:
+ ((UChar*)block32) [0 .. nblock-1] holds block
+ All other areas of block32 destroyed
+ ftab [0 .. 65536 ] destroyed
+ ptr [0 .. nblock-1] holds sorted order
+ if (*budget < 0), sorting was abandoned
+*/
+
+#define BIGFREQ(b) (ftab[((b)+1) << 8] - ftab[(b) << 8])
+#define SETMASK (1 << 21)
+#define CLEARMASK (~(SETMASK))
+
+static
+void mainSort ( UInt32* ptr,
+ UChar* block,
+ UInt16* quadrant,
+ UInt32* ftab,
+ Int32 nblock,
+ Int32 verb,
+ Int32* budget )
+{
+ Int32 i, j, k, ss, sb;
+ Int32 runningOrder[256];
+ Bool bigDone[256];
+ Int32 copyStart[256];
+ Int32 copyEnd [256];
+ UChar c1;
+ Int32 numQSorted;
+ UInt16 s;
+ if (verb >= 4) VPrintf0 ( " main sort initialise ...\n" );
+
+ /*-- set up the 2-byte frequency table --*/
+ for (i = 65536; i >= 0; i--) ftab[i] = 0;
+
+ j = block[0] << 8;
+ i = nblock-1;
+ for (; i >= 3; i -= 4) {
+ quadrant[i] = 0;
+ j = (j >> 8) | ( ((UInt16)block[i]) << 8);
+ ftab[j]++;
+ quadrant[i-1] = 0;
+ j = (j >> 8) | ( ((UInt16)block[i-1]) << 8);
+ ftab[j]++;
+ quadrant[i-2] = 0;
+ j = (j >> 8) | ( ((UInt16)block[i-2]) << 8);
+ ftab[j]++;
+ quadrant[i-3] = 0;
+ j = (j >> 8) | ( ((UInt16)block[i-3]) << 8);
+ ftab[j]++;
+ }
+ for (; i >= 0; i--) {
+ quadrant[i] = 0;
+ j = (j >> 8) | ( ((UInt16)block[i]) << 8);
+ ftab[j]++;
+ }
+
+ /*-- (emphasises close relationship of block & quadrant) --*/
+ for (i = 0; i < BZ_N_OVERSHOOT; i++) {
+ block [nblock+i] = block[i];
+ quadrant[nblock+i] = 0;
+ }
+
+ if (verb >= 4) VPrintf0 ( " bucket sorting ...\n" );
+
+ /*-- Complete the initial radix sort --*/
+ for (i = 1; i <= 65536; i++) ftab[i] += ftab[i-1];
+
+ s = block[0] << 8;
+ i = nblock-1;
+ for (; i >= 3; i -= 4) {
+ s = (s >> 8) | (block[i] << 8);
+ j = ftab[s] -1;
+ ftab[s] = j;
+ ptr[j] = i;
+ s = (s >> 8) | (block[i-1] << 8);
+ j = ftab[s] -1;
+ ftab[s] = j;
+ ptr[j] = i-1;
+ s = (s >> 8) | (block[i-2] << 8);
+ j = ftab[s] -1;
+ ftab[s] = j;
+ ptr[j] = i-2;
+ s = (s >> 8) | (block[i-3] << 8);
+ j = ftab[s] -1;
+ ftab[s] = j;
+ ptr[j] = i-3;
+ }
+ for (; i >= 0; i--) {
+ s = (s >> 8) | (block[i] << 8);
+ j = ftab[s] -1;
+ ftab[s] = j;
+ ptr[j] = i;
+ }
+
+ /*--
+ Now ftab contains the first loc of every small bucket.
+ Calculate the running order, from smallest to largest
+ big bucket.
+ --*/
+ for (i = 0; i <= 255; i++) {
+ bigDone [i] = False;
+ runningOrder[i] = i;
+ }
+
+ {
+ Int32 vv;
+ Int32 h = 1;
+ do h = 3 * h + 1; while (h <= 256);
+ do {
+ h = h / 3;
+ for (i = h; i <= 255; i++) {
+ vv = runningOrder[i];
+ j = i;
+ while ( BIGFREQ(runningOrder[j-h]) > BIGFREQ(vv) ) {
+ runningOrder[j] = runningOrder[j-h];
+ j = j - h;
+ if (j <= (h - 1)) goto zero;
+ }
+ zero:
+ runningOrder[j] = vv;
+ }
+ } while (h != 1);
+ }
+
+ /*--
+ The main sorting loop.
+ --*/
+
+ numQSorted = 0;
+
+ for (i = 0; i <= 255; i++) {
+
+ /*--
+ Process big buckets, starting with the least full.
+ Basically this is a 3-step process in which we call
+ mainQSort3 to sort the small buckets [ss, j], but
+ also make a big effort to avoid the calls if we can.
+ --*/
+ ss = runningOrder[i];
+
+ /*--
+ Step 1:
+ Complete the big bucket [ss] by quicksorting
+ any unsorted small buckets [ss, j], for j != ss.
+ Hopefully previous pointer-scanning phases have already
+ completed many of the small buckets [ss, j], so
+ we don't have to sort them at all.
+ --*/
+ for (j = 0; j <= 255; j++) {
+ if (j != ss) {
+ sb = (ss << 8) + j;
+ if ( ! (ftab[sb] & SETMASK) ) {
+ Int32 lo = ftab[sb] & CLEARMASK;
+ Int32 hi = (ftab[sb+1] & CLEARMASK) - 1;
+ if (hi > lo) {
+ if (verb >= 4)
+ VPrintf4 ( " qsort [0x%x, 0x%x] "
+ "done %d this %d\n",
+ ss, j, numQSorted, hi - lo + 1 );
+ mainQSort3 (
+ ptr, block, quadrant, nblock,
+ lo, hi, BZ_N_RADIX, budget
+ );
+ numQSorted += (hi - lo + 1);
+ if (*budget < 0) return;
+ }
+ }
+ ftab[sb] |= SETMASK;
+ }
+ }
+
+ AssertH ( !bigDone[ss], 1006 );
+
+ /*--
+ Step 2:
+ Now scan this big bucket [ss] so as to synthesise the
+ sorted order for small buckets [t, ss] for all t,
+ including, magically, the bucket [ss,ss] too.
+ This will avoid doing Real Work in subsequent Step 1's.
+ --*/
+ {
+ for (j = 0; j <= 255; j++) {
+ copyStart[j] = ftab[(j << 8) + ss] & CLEARMASK;
+ copyEnd [j] = (ftab[(j << 8) + ss + 1] & CLEARMASK) - 1;
+ }
+ for (j = ftab[ss << 8] & CLEARMASK; j < copyStart[ss]; j++) {
+ k = ptr[j]-1; if (k < 0) k += nblock;
+ c1 = block[k];
+ if (!bigDone[c1])
+ ptr[ copyStart[c1]++ ] = k;
+ }
+ for (j = (ftab[(ss+1) << 8] & CLEARMASK) - 1; j > copyEnd[ss]; j--) {
+ k = ptr[j]-1; if (k < 0) k += nblock;
+ c1 = block[k];
+ if (!bigDone[c1])
+ ptr[ copyEnd[c1]-- ] = k;
+ }
+ }
+
+ AssertH ( (copyStart[ss]-1 == copyEnd[ss])
+ ||
+ /* Extremely rare case missing in bzip2-1.0.0 and 1.0.1.
+ Necessity for this case is demonstrated by compressing
+ a sequence of approximately 48.5 million of character
+ 251; 1.0.0/1.0.1 will then die here. */
+ (copyStart[ss] == 0 && copyEnd[ss] == nblock-1),
+ 1007 )
+
+ for (j = 0; j <= 255; j++) ftab[(j << 8) + ss] |= SETMASK;
+
+ /*--
+ Step 3:
+ The [ss] big bucket is now done. Record this fact,
+ and update the quadrant descriptors. Remember to
+ update quadrants in the overshoot area too, if
+ necessary. The "if (i < 255)" test merely skips
+ this updating for the last bucket processed, since
+ updating for the last bucket is pointless.
+
+ The quadrant array provides a way to incrementally
+ cache sort orderings, as they appear, so as to
+ make subsequent comparisons in fullGtU() complete
+ faster. For repetitive blocks this makes a big
+ difference (but not big enough to be able to avoid
+ the fallback sorting mechanism, exponential radix sort).
+
+ The precise meaning is: at all times:
+
+ for 0 <= i < nblock and 0 <= j <= nblock
+
+ if block[i] != block[j],
+
+ then the relative values of quadrant[i] and
+ quadrant[j] are meaningless.
+
+ else {
+ if quadrant[i] < quadrant[j]
+ then the string starting at i lexicographically
+ precedes the string starting at j
+
+ else if quadrant[i] > quadrant[j]
+ then the string starting at j lexicographically
+ precedes the string starting at i
+
+ else
+ the relative ordering of the strings starting
+ at i and j has not yet been determined.
+ }
+ --*/
+ bigDone[ss] = True;
+
+ if (i < 255) {
+ Int32 bbStart = ftab[ss << 8] & CLEARMASK;
+ Int32 bbSize = (ftab[(ss+1) << 8] & CLEARMASK) - bbStart;
+ Int32 shifts = 0;
+
+ while ((bbSize >> shifts) > 65534) shifts++;
+
+ for (j = bbSize-1; j >= 0; j--) {
+ Int32 a2update = ptr[bbStart + j];
+ UInt16 qVal = (UInt16)(j >> shifts);
+ quadrant[a2update] = qVal;
+ if (a2update < BZ_N_OVERSHOOT)
+ quadrant[a2update + nblock] = qVal;
+ }
+ AssertH ( ((bbSize-1) >> shifts) <= 65535, 1002 );
+ }
+
+ }
+
+ if (verb >= 4)
+ VPrintf3 ( " %d pointers, %d sorted, %d scanned\n",
+ nblock, numQSorted, nblock - numQSorted );
+}
+
+#undef BIGFREQ
+#undef SETMASK
+#undef CLEARMASK
+
+
+/*---------------------------------------------*/
+/* Pre:
+ nblock > 0
+ arr2 exists for [0 .. nblock-1 +N_OVERSHOOT]
+ ((UChar*)arr2) [0 .. nblock-1] holds block
+ arr1 exists for [0 .. nblock-1]
+
+ Post:
+ ((UChar*)arr2) [0 .. nblock-1] holds block
+ All other areas of block destroyed
+ ftab [ 0 .. 65536 ] destroyed
+ arr1 [0 .. nblock-1] holds sorted order
+*/
+void BZ2_blockSort ( EState* s )
+{
+ UInt32* ptr = s->ptr;
+ UChar* block = s->block;
+ UInt32* ftab = s->ftab;
+ Int32 nblock = s->nblock;
+ Int32 verb = s->verbosity;
+ Int32 wfact = s->workFactor;
+ UInt16* quadrant;
+ Int32 budget;
+ Int32 budgetInit;
+ Int32 i;
+
+ if (nblock < 10000) {
+ fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
+ } else {
+ /* Calculate the location for quadrant, remembering to get
+ the alignment right. Assumes that &(block[0]) is at least
+ 2-byte aligned -- this should be ok since block is really
+ the first section of arr2.
+ */
+ i = nblock+BZ_N_OVERSHOOT;
+ if (i & 1) i++;
+ quadrant = (UInt16*)(&(block[i]));
+
+ /* (wfact-1) / 3 puts the default-factor-30
+ transition point at very roughly the same place as
+ with v0.1 and v0.9.0.
+ Not that it particularly matters any more, since the
+ resulting compressed stream is now the same regardless
+ of whether or not we use the main sort or fallback sort.
+ */
+ if (wfact < 1 ) wfact = 1;
+ if (wfact > 100) wfact = 100;
+ budgetInit = nblock * ((wfact-1) / 3);
+ budget = budgetInit;
+
+ mainSort ( ptr, block, quadrant, ftab, nblock, verb, &budget );
+ if (verb >= 3)
+ VPrintf3 ( " %d work, %d block, ratio %5.2f\n",
+ budgetInit - budget,
+ nblock,
+ (float)(budgetInit - budget) /
+ (float)(nblock==0 ? 1 : nblock) );
+ if (budget < 0) {
+ if (verb >= 2)
+ VPrintf0 ( " too repetitive; using fallback"
+ " sorting algorithm\n" );
+ fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
+ }
+ }
+
+ s->origPtr = -1;
+ for (i = 0; i < s->nblock; i++)
+ if (ptr[i] == 0)
+ { s->origPtr = i; break; };
+
+ AssertH( s->origPtr != -1, 1003 );
+}
+
+
+/*-------------------------------------------------------------*/
+/*--- end blocksort.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/Utilities/cmbzip2/bz-common.xsl b/Utilities/cmbzip2/bz-common.xsl
new file mode 100644
index 000000000..66fcd6fe0
--- /dev/null
+++ b/Utilities/cmbzip2/bz-common.xsl
@@ -0,0 +1,39 @@
+<?xml version="1.0"?> <!-- -*- sgml -*- -->
+<xsl:stylesheet
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+<!-- we like '1.2 Title' -->
+<xsl:param name="section.autolabel" select="'1'"/>
+<xsl:param name="section.label.includes.component.label" select="'1'"/>
+
+<!-- Do not put 'Chapter' at the start of eg 'Chapter 1. Doing This' -->
+<xsl:param name="local.l10n.xml" select="document('')"/>
+<l:i18n xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0">
+ <l:l10n language="en">
+ <l:context name="title-numbered">
+ <l:template name="chapter" text="%n.&#160;%t"/>
+ </l:context>
+ </l:l10n>
+</l:i18n>
+
+<!-- don't generate sub-tocs for qanda sets -->
+<xsl:param name="generate.toc">
+set toc,title
+book toc,title,figure,table,example,equation
+chapter toc,title
+section toc
+sect1 toc
+sect2 toc
+sect3 toc
+sect4 nop
+sect5 nop
+qandaset toc
+qandadiv nop
+appendix toc,title
+article/appendix nop
+article toc,title
+preface toc,title
+reference toc,title
+</xsl:param>
+
+</xsl:stylesheet>
diff --git a/Utilities/cmbzip2/bz-fo.xsl b/Utilities/cmbzip2/bz-fo.xsl
new file mode 100644
index 000000000..ba3e30123
--- /dev/null
+++ b/Utilities/cmbzip2/bz-fo.xsl
@@ -0,0 +1,276 @@
+<?xml version="1.0" encoding="UTF-8"?> <!-- -*- sgml -*- -->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:fo="http://www.w3.org/1999/XSL/Format" version="1.0">
+
+<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/fo/docbook.xsl"/>
+<xsl:import href="bz-common.xsl"/>
+
+<!-- set indent = yes while debugging, then change to NO -->
+<xsl:output method="xml" indent="yes"/>
+
+<!-- ensure only passivetex extensions are on -->
+<xsl:param name="stylesheet.result.type" select="'fo'"/>
+<!-- fo extensions: PDF bookmarks and index terms -->
+<xsl:param name="use.extensions" select="'1'"/>
+<xsl:param name="xep.extensions" select="0"/>
+<xsl:param name="fop.extensions" select="0"/>
+<xsl:param name="saxon.extensions" select="0"/>
+<xsl:param name="passivetex.extensions" select="1"/>
+<xsl:param name="tablecolumns.extension" select="'1'"/>
+
+<!-- ensure we are using single sided -->
+<xsl:param name="double.sided" select="'0'"/>
+
+<!-- insert cross references to page numbers -->
+<xsl:param name="insert.xref.page.number" select="1"/>
+
+<!-- <?custom-pagebreak?> inserts a page break at this point -->
+<xsl:template match="processing-instruction('custom-pagebreak')">
+ <fo:block break-before='page'/>
+</xsl:template>
+
+<!-- show links in color -->
+<xsl:attribute-set name="xref.properties">
+ <xsl:attribute name="color">blue</xsl:attribute>
+</xsl:attribute-set>
+
+<!-- make pre listings indented a bit + a bg colour -->
+<xsl:template match="programlisting | screen">
+ <fo:block start-indent="0.25in" wrap-option="no-wrap"
+ white-space-collapse="false" text-align="start"
+ font-family="monospace" background-color="#f2f2f9"
+ linefeed-treatment="preserve"
+ xsl:use-attribute-sets="normal.para.spacing">
+ <xsl:apply-templates/>
+ </fo:block>
+</xsl:template>
+<!-- make verbatim output prettier -->
+<xsl:template match="literallayout">
+ <fo:block start-indent="0.25in" wrap-option="no-wrap"
+ white-space-collapse="false" text-align="start"
+ font-family="monospace" background-color="#edf7f4"
+ linefeed-treatment="preserve"
+ space-before="0em" space-after="0em">
+ <xsl:apply-templates/>
+ </fo:block>
+</xsl:template>
+
+<!-- workaround bug in passivetex fo output for itemizedlist -->
+<xsl:template match="itemizedlist/listitem">
+ <xsl:variable name="id">
+ <xsl:call-template name="object.id"/></xsl:variable>
+ <xsl:variable name="itemsymbol">
+ <xsl:call-template name="list.itemsymbol">
+ <xsl:with-param name="node" select="parent::itemizedlist"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="item.contents">
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block>
+ <xsl:choose>
+ <xsl:when test="$itemsymbol='disc'">&#x2022;</xsl:when>
+ <xsl:when test="$itemsymbol='bullet'">&#x2022;</xsl:when>
+ <xsl:otherwise>&#x2022;</xsl:otherwise>
+ </xsl:choose>
+ </fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <xsl:apply-templates/> <!-- removed extra block wrapper -->
+ </fo:list-item-body>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="parent::*/@spacing = 'compact'">
+ <fo:list-item id="{$id}"
+ xsl:use-attribute-sets="compact.list.item.spacing">
+ <xsl:copy-of select="$item.contents"/>
+ </fo:list-item>
+ </xsl:when>
+ <xsl:otherwise>
+ <fo:list-item id="{$id}" xsl:use-attribute-sets="list.item.spacing">
+ <xsl:copy-of select="$item.contents"/>
+ </fo:list-item>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<!-- workaround bug in passivetex fo output for orderedlist -->
+<xsl:template match="orderedlist/listitem">
+ <xsl:variable name="id">
+ <xsl:call-template name="object.id"/></xsl:variable>
+ <xsl:variable name="item.contents">
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block>
+ <xsl:apply-templates select="." mode="item-number"/>
+ </fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <xsl:apply-templates/> <!-- removed extra block wrapper -->
+ </fo:list-item-body>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="parent::*/@spacing = 'compact'">
+ <fo:list-item id="{$id}"
+ xsl:use-attribute-sets="compact.list.item.spacing">
+ <xsl:copy-of select="$item.contents"/>
+ </fo:list-item>
+ </xsl:when>
+ <xsl:otherwise>
+ <fo:list-item id="{$id}" xsl:use-attribute-sets="list.item.spacing">
+ <xsl:copy-of select="$item.contents"/>
+ </fo:list-item>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<!-- workaround bug in passivetex fo output for variablelist -->
+<xsl:param name="variablelist.as.blocks" select="1"/>
+<xsl:template match="varlistentry" mode="vl.as.blocks">
+ <xsl:variable name="id">
+ <xsl:call-template name="object.id"/></xsl:variable>
+ <fo:block id="{$id}" xsl:use-attribute-sets="list.item.spacing"
+ keep-together.within-column="always"
+ keep-with-next.within-column="always">
+ <xsl:apply-templates select="term"/>
+ </fo:block>
+ <fo:block start-indent="0.5in" end-indent="0in"
+ space-after.minimum="0.2em"
+ space-after.optimum="0.4em"
+ space-after.maximum="0.6em">
+ <fo:block>
+ <xsl:apply-templates select="listitem"/>
+ </fo:block>
+ </fo:block>
+</xsl:template>
+
+
+<!-- workaround bug in footers: force right-align w/two 80|30 cols -->
+<xsl:template name="footer.table">
+ <xsl:param name="pageclass" select="''"/>
+ <xsl:param name="sequence" select="''"/>
+ <xsl:param name="gentext-key" select="''"/>
+ <xsl:choose>
+ <xsl:when test="$pageclass = 'index'">
+ <xsl:attribute name="margin-left">0pt</xsl:attribute>
+ </xsl:when>
+ </xsl:choose>
+ <xsl:variable name="candidate">
+ <fo:table table-layout="fixed" width="100%">
+ <fo:table-column column-number="1" column-width="80%"/>
+ <fo:table-column column-number="2" column-width="20%"/>
+ <fo:table-body>
+ <fo:table-row height="14pt">
+ <fo:table-cell text-align="left" display-align="after">
+ <xsl:attribute name="relative-align">baseline</xsl:attribute>
+ <fo:block>
+ <fo:block> </fo:block><!-- empty cell -->
+ </fo:block>
+ </fo:table-cell>
+ <fo:table-cell text-align="center" display-align="after">
+ <xsl:attribute name="relative-align">baseline</xsl:attribute>
+ <fo:block>
+ <xsl:call-template name="footer.content">
+ <xsl:with-param name="pageclass" select="$pageclass"/>
+ <xsl:with-param name="sequence" select="$sequence"/>
+ <xsl:with-param name="position" select="'center'"/>
+ <xsl:with-param name="gentext-key" select="$gentext-key"/>
+ </xsl:call-template>
+ </fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-body>
+ </fo:table>
+ </xsl:variable>
+ <!-- Really output a footer? -->
+ <xsl:choose>
+ <xsl:when test="$pageclass='titlepage' and $gentext-key='book'
+ and $sequence='first'">
+ <!-- no, book titlepages have no footers at all -->
+ </xsl:when>
+ <xsl:when test="$sequence = 'blank' and $footers.on.blank.pages = 0">
+ <!-- no output -->
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy-of select="$candidate"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+
+<!-- fix bug in headers: force right-align w/two 40|60 cols -->
+<xsl:template name="header.table">
+ <xsl:param name="pageclass" select="''"/>
+ <xsl:param name="sequence" select="''"/>
+ <xsl:param name="gentext-key" select="''"/>
+ <xsl:choose>
+ <xsl:when test="$pageclass = 'index'">
+ <xsl:attribute name="margin-left">0pt</xsl:attribute>
+ </xsl:when>
+ </xsl:choose>
+ <xsl:variable name="candidate">
+ <fo:table table-layout="fixed" width="100%">
+ <xsl:call-template name="head.sep.rule">
+ <xsl:with-param name="pageclass" select="$pageclass"/>
+ <xsl:with-param name="sequence" select="$sequence"/>
+ <xsl:with-param name="gentext-key" select="$gentext-key"/>
+ </xsl:call-template>
+ <fo:table-column column-number="1" column-width="40%"/>
+ <fo:table-column column-number="2" column-width="60%"/>
+ <fo:table-body>
+ <fo:table-row height="14pt">
+ <fo:table-cell text-align="left" display-align="before">
+ <xsl:attribute name="relative-align">baseline</xsl:attribute>
+ <fo:block>
+ <fo:block> </fo:block><!-- empty cell -->
+ </fo:block>
+ </fo:table-cell>
+ <fo:table-cell text-align="center" display-align="before">
+ <xsl:attribute name="relative-align">baseline</xsl:attribute>
+ <fo:block>
+ <xsl:call-template name="header.content">
+ <xsl:with-param name="pageclass" select="$pageclass"/>
+ <xsl:with-param name="sequence" select="$sequence"/>
+ <xsl:with-param name="position" select="'center'"/>
+ <xsl:with-param name="gentext-key" select="$gentext-key"/>
+ </xsl:call-template>
+ </fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-body>
+ </fo:table>
+ </xsl:variable>
+ <!-- Really output a header? -->
+ <xsl:choose>
+ <xsl:when test="$pageclass = 'titlepage' and $gentext-key = 'book'
+ and $sequence='first'">
+ <!-- no, book titlepages have no headers at all -->
+ </xsl:when>
+ <xsl:when test="$sequence = 'blank' and $headers.on.blank.pages = 0">
+ <!-- no output -->
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy-of select="$candidate"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+
+<!-- Bug-fix for Suse 10 PassiveTex version -->
+<!-- Precompute attribute values 'cos PassiveTex is too stupid: -->
+<xsl:attribute-set name="component.title.properties">
+ <xsl:attribute name="keep-with-next.within-column">always</xsl:attribute>
+ <xsl:attribute name="space-before.optimum">
+ <xsl:value-of select="concat($body.font.master, 'pt')"/>
+ </xsl:attribute>
+ <xsl:attribute name="space-before.minimum">
+ <xsl:value-of select="$body.font.master * 0.8"/>
+ <xsl:text>pt</xsl:text>
+ </xsl:attribute>
+ <xsl:attribute name="space-before.maximum">
+ <xsl:value-of select="$body.font.master * 1.2"/>
+ <xsl:text>pt</xsl:text>
+ </xsl:attribute>
+ <xsl:attribute name="hyphenate">false</xsl:attribute>
+</xsl:attribute-set>
+
+
+</xsl:stylesheet>
diff --git a/Utilities/cmbzip2/bz-html.xsl b/Utilities/cmbzip2/bz-html.xsl
new file mode 100644
index 000000000..1785fffbc
--- /dev/null
+++ b/Utilities/cmbzip2/bz-html.xsl
@@ -0,0 +1,20 @@
+<?xml version="1.0"?> <!-- -*- sgml -*- -->
+<!DOCTYPE xsl:stylesheet [ <!ENTITY bz-css SYSTEM "./bzip.css"> ]>
+
+<xsl:stylesheet
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl"/>
+<xsl:import href="bz-common.xsl"/>
+
+<!-- use 8859-1 encoding -->
+<xsl:output method="html" encoding="ISO-8859-1" indent="yes"/>
+
+<!-- we include the css directly when generating one large file -->
+<xsl:template name="user.head.content">
+ <style type="text/css" media="screen">
+ <xsl:text>&bz-css;</xsl:text>
+ </style>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/Utilities/cmbzip2/bzdiff b/Utilities/cmbzip2/bzdiff
new file mode 100644
index 000000000..c4c996490
--- /dev/null
+++ b/Utilities/cmbzip2/bzdiff
@@ -0,0 +1,76 @@
+#!/bin/sh
+# sh is buggy on RS/6000 AIX 3.2. Replace above line with #!/bin/ksh
+
+# Bzcmp/diff wrapped for bzip2,
+# adapted from zdiff by Philippe Troin <phil@fifi.org> for Debian GNU/Linux.
+
+# Bzcmp and bzdiff are used to invoke the cmp or the diff pro-
+# gram on compressed files. All options specified are passed
+# directly to cmp or diff. If only 1 file is specified, then
+# the files compared are file1 and an uncompressed file1.gz.
+# If two files are specified, then they are uncompressed (if
+# necessary) and fed to cmp or diff. The exit status from cmp
+# or diff is preserved.
+
+PATH="/usr/bin:/bin:$PATH"; export PATH
+prog=`echo $0 | sed 's|.*/||'`
+case "$prog" in
+ *cmp) comp=${CMP-cmp} ;;
+ *) comp=${DIFF-diff} ;;
+esac
+
+OPTIONS=
+FILES=
+for ARG
+do
+ case "$ARG" in
+ -*) OPTIONS="$OPTIONS $ARG";;
+ *) if test -f "$ARG"; then
+ FILES="$FILES $ARG"
+ else
+ echo "${prog}: $ARG not found or not a regular file"
+ exit 1
+ fi ;;
+ esac
+done
+if test -z "$FILES"; then
+ echo "Usage: $prog [${comp}_options] file [file]"
+ exit 1
+fi
+tmp=`mktemp ${TMPDIR:-/tmp}/bzdiff.XXXXXXXXXX` || {
+ echo 'cannot create a temporary file' >&2
+ exit 1
+}
+set $FILES
+if test $# -eq 1; then
+ FILE=`echo "$1" | sed 's/.bz2$//'`
+ bzip2 -cd "$FILE.bz2" | $comp $OPTIONS - "$FILE"
+ STAT="$?"
+
+elif test $# -eq 2; then
+ case "$1" in
+ *.bz2)
+ case "$2" in
+ *.bz2)
+ F=`echo "$2" | sed 's|.*/||;s|.bz2$||'`
+ bzip2 -cdfq "$2" > $tmp
+ bzip2 -cdfq "$1" | $comp $OPTIONS - $tmp
+ STAT="$?"
+ /bin/rm -f $tmp;;
+
+ *) bzip2 -cdfq "$1" | $comp $OPTIONS - "$2"
+ STAT="$?";;
+ esac;;
+ *) case "$2" in
+ *.bz2)
+ bzip2 -cdfq "$2" | $comp $OPTIONS "$1" -
+ STAT="$?";;
+ *) $comp $OPTIONS "$1" "$2"
+ STAT="$?";;
+ esac;;
+ esac
+ exit "$STAT"
+else
+ echo "Usage: $prog [${comp}_options] file [file]"
+ exit 1
+fi
diff --git a/Utilities/cmbzip2/bzdiff.1 b/Utilities/cmbzip2/bzdiff.1
new file mode 100644
index 000000000..adb7a8e72
--- /dev/null
+++ b/Utilities/cmbzip2/bzdiff.1
@@ -0,0 +1,47 @@
+\"Shamelessly copied from zmore.1 by Philippe Troin <phil@fifi.org>
+\"for Debian GNU/Linux
+.TH BZDIFF 1
+.SH NAME
+bzcmp, bzdiff \- compare bzip2 compressed files
+.SH SYNOPSIS
+.B bzcmp
+[ cmp_options ] file1
+[ file2 ]
+.br
+.B bzdiff
+[ diff_options ] file1
+[ file2 ]
+.SH DESCRIPTION
+.I Bzcmp
+and
+.I bzdiff
+are used to invoke the
+.I cmp
+or the
+.I diff
+program on bzip2 compressed files. All options specified are passed
+directly to
+.I cmp
+or
+.IR diff "."
+If only 1 file is specified, then the files compared are
+.I file1
+and an uncompressed
+.IR file1 ".bz2."
+If two files are specified, then they are uncompressed if necessary and fed to
+.I cmp
+or
+.IR diff "."
+The exit status from
+.I cmp
+or
+.I diff
+is preserved.
+.SH "SEE ALSO"
+cmp(1), diff(1), bzmore(1), bzless(1), bzgrep(1), bzip2(1)
+.SH BUGS
+Messages from the
+.I cmp
+or
+.I diff
+programs refer to temporary filenames instead of those specified.
diff --git a/Utilities/cmbzip2/bzgrep b/Utilities/cmbzip2/bzgrep
new file mode 100644
index 000000000..8ccf919ac
--- /dev/null
+++ b/Utilities/cmbzip2/bzgrep
@@ -0,0 +1,75 @@
+#!/bin/sh
+
+# Bzgrep wrapped for bzip2,
+# adapted from zgrep by Philippe Troin <phil@fifi.org> for Debian GNU/Linux.
+## zgrep notice:
+## zgrep -- a wrapper around a grep program that decompresses files as needed
+## Adapted from a version sent by Charles Levert <charles@comm.polymtl.ca>
+
+PATH="/usr/bin:$PATH"; export PATH
+
+prog=`echo $0 | sed 's|.*/||'`
+case "$prog" in
+ *egrep) grep=${EGREP-egrep} ;;
+ *fgrep) grep=${FGREP-fgrep} ;;
+ *) grep=${GREP-grep} ;;
+esac
+pat=""
+while test $# -ne 0; do
+ case "$1" in
+ -e | -f) opt="$opt $1"; shift; pat="$1"
+ if test "$grep" = grep; then # grep is buggy with -e on SVR4
+ grep=egrep
+ fi;;
+ -A | -B) opt="$opt $1 $2"; shift;;
+ -*) opt="$opt $1";;
+ *) if test -z "$pat"; then
+ pat="$1"
+ else
+ break;
+ fi;;
+ esac
+ shift
+done
+
+if test -z "$pat"; then
+ echo "grep through bzip2 files"
+ echo "usage: $prog [grep_options] pattern [files]"
+ exit 1
+fi
+
+list=0
+silent=0
+op=`echo "$opt" | sed -e 's/ //g' -e 's/-//g'`
+case "$op" in
+ *l*) list=1
+esac
+case "$op" in
+ *h*) silent=1
+esac
+
+if test $# -eq 0; then
+ bzip2 -cdfq | $grep $opt "$pat"
+ exit $?
+fi
+
+res=0
+for i do
+ if test -f "$i"; then :; else if test -f "$i.bz2"; then i="$i.bz2"; fi; fi
+ if test $list -eq 1; then
+ bzip2 -cdfq "$i" | $grep $opt "$pat" 2>&1 > /dev/null && echo $i
+ r=$?
+ elif test $# -eq 1 -o $silent -eq 1; then
+ bzip2 -cdfq "$i" | $grep $opt "$pat"
+ r=$?
+ else
+ j=${i//\\/\\\\}
+ j=${j//|/\\|}
+ j=${j//&/\\&}
+ j=`printf "%s" "$j" | tr '\n' ' '`
+ bzip2 -cdfq "$i" | $grep $opt "$pat" | sed "s|^|${j}:|"
+ r=$?
+ fi
+ test "$r" -ne 0 && res="$r"
+done
+exit $res
diff --git a/Utilities/cmbzip2/bzgrep.1 b/Utilities/cmbzip2/bzgrep.1
new file mode 100644
index 000000000..930af8c7f
--- /dev/null
+++ b/Utilities/cmbzip2/bzgrep.1
@@ -0,0 +1,56 @@
+\"Shamelessly copied from zmore.1 by Philippe Troin <phil@fifi.org>
+\"for Debian GNU/Linux
+.TH BZGREP 1
+.SH NAME
+bzgrep, bzfgrep, bzegrep \- search possibly bzip2 compressed files for a regular expression
+.SH SYNOPSIS
+.B bzgrep
+[ grep_options ]
+.BI [\ -e\ ] " pattern"
+.IR filename ".\|.\|."
+.br
+.B bzegrep
+[ egrep_options ]
+.BI [\ -e\ ] " pattern"
+.IR filename ".\|.\|."
+.br
+.B bzfgrep
+[ fgrep_options ]
+.BI [\ -e\ ] " pattern"
+.IR filename ".\|.\|."
+.SH DESCRIPTION
+.IR Bzgrep
+is used to invoke the
+.I grep
+on bzip2-compressed files. All options specified are passed directly to
+.I grep.
+If no file is specified, then the standard input is decompressed
+if necessary and fed to grep.
+Otherwise the given files are uncompressed if necessary and fed to
+.I grep.
+.PP
+If
+.I bzgrep
+is invoked as
+.I bzegrep
+or
+.I bzfgrep
+then
+.I egrep
+or
+.I fgrep
+is used instead of
+.I grep.
+If the GREP environment variable is set,
+.I bzgrep
+uses it as the
+.I grep
+program to be invoked. For example:
+
+ for sh: GREP=fgrep bzgrep string files
+ for csh: (setenv GREP fgrep; bzgrep string files)
+.SH AUTHOR
+Charles Levert (charles@comm.polymtl.ca). Adapted to bzip2 by Philippe
+Troin <phil@fifi.org> for Debian GNU/Linux.
+.SH "SEE ALSO"
+grep(1), egrep(1), fgrep(1), bzdiff(1), bzmore(1), bzless(1), bzip2(1)
diff --git a/Utilities/cmbzip2/bzip.css b/Utilities/cmbzip2/bzip.css
new file mode 100644
index 000000000..4feb40165
--- /dev/null
+++ b/Utilities/cmbzip2/bzip.css
@@ -0,0 +1,74 @@
+/* Colours:
+#74240f dark brown h1, h2, h3, h4
+#336699 medium blue links
+#339999 turquoise link hover colour
+#202020 almost black general text
+#761596 purple md5sum text
+#626262 dark gray pre border
+#eeeeee very light gray pre background
+#f2f2f9 very light blue nav table background
+#3366cc medium blue nav table border
+*/
+
+a, a:link, a:visited, a:active { color: #336699; }
+a:hover { color: #339999; }
+
+body { font: 80%/126% sans-serif; }
+h1, h2, h3, h4 { color: #74240f; }
+
+dt { color: #336699; font-weight: bold }
+dd {
+ margin-left: 1.5em;
+ padding-bottom: 0.8em;
+}
+
+/* -- ruler -- */
+div.hr_blue {
+ height: 3px;
+ background:#ffffff url("/images/hr_blue.png") repeat-x; }
+div.hr_blue hr { display:none; }
+
+/* release styles */
+#release p { margin-top: 0.4em; }
+#release .md5sum { color: #761596; }
+
+
+/* ------ styles for docs|manuals|howto ------ */
+/* -- lists -- */
+ul {
+ margin: 0px 4px 16px 16px;
+ padding: 0px;
+ list-style: url("/images/li-blue.png");
+}
+ul li {
+ margin-bottom: 10px;
+}
+ul ul {
+ list-style-type: none;
+ list-style-image: none;
+ margin-left: 0px;
+}
+
+/* header / footer nav tables */
+table.nav {
+ border: solid 1px #3366cc;
+ background: #f2f2f9;
+ background-color: #f2f2f9;
+ margin-bottom: 0.5em;
+}
+/* don't have underlined links in chunked nav menus */
+table.nav a { text-decoration: none; }
+table.nav a:hover { text-decoration: underline; }
+table.nav td { font-size: 85%; }
+
+code, tt, pre { font-size: 120%; }
+code, tt { color: #761596; }
+
+div.literallayout, pre.programlisting, pre.screen {
+ color: #000000;
+ padding: 0.5em;
+ background: #eeeeee;
+ border: 1px solid #626262;
+ background-color: #eeeeee;
+ margin: 4px 0px 4px 0px;
+}
diff --git a/Utilities/cmbzip2/bzip2.1 b/Utilities/cmbzip2/bzip2.1
new file mode 100644
index 000000000..a313f2d5b
--- /dev/null
+++ b/Utilities/cmbzip2/bzip2.1
@@ -0,0 +1,454 @@
+.PU
+.TH bzip2 1
+.SH NAME
+bzip2, bunzip2 \- a block-sorting file compressor, v1.0.4
+.br
+bzcat \- decompresses files to stdout
+.br
+bzip2recover \- recovers data from damaged bzip2 files
+
+.SH SYNOPSIS
+.ll +8
+.B bzip2
+.RB [ " \-cdfkqstvzVL123456789 " ]
+[
+.I "filenames \&..."
+]
+.ll -8
+.br
+.B bunzip2
+.RB [ " \-fkvsVL " ]
+[
+.I "filenames \&..."
+]
+.br
+.B bzcat
+.RB [ " \-s " ]
+[
+.I "filenames \&..."
+]
+.br
+.B bzip2recover
+.I "filename"
+
+.SH DESCRIPTION
+.I bzip2
+compresses files using the Burrows-Wheeler block sorting
+text compression algorithm, and Huffman coding. Compression is
+generally considerably better than that achieved by more conventional
+LZ77/LZ78-based compressors, and approaches the performance of the PPM
+family of statistical compressors.
+
+The command-line options are deliberately very similar to
+those of
+.I GNU gzip,
+but they are not identical.
+
+.I bzip2
+expects a list of file names to accompany the
+command-line flags. Each file is replaced by a compressed version of
+itself, with the name "original_name.bz2".
+Each compressed file
+has the same modification date, permissions, and, when possible,
+ownership as the corresponding original, so that these properties can
+be correctly restored at decompression time. File name handling is
+naive in the sense that there is no mechanism for preserving original
+file names, permissions, ownerships or dates in filesystems which lack
+these concepts, or have serious file name length restrictions, such as
+MS-DOS.
+
+.I bzip2
+and
+.I bunzip2
+will by default not overwrite existing
+files. If you want this to happen, specify the \-f flag.
+
+If no file names are specified,
+.I bzip2
+compresses from standard
+input to standard output. In this case,
+.I bzip2
+will decline to
+write compressed output to a terminal, as this would be entirely
+incomprehensible and therefore pointless.
+
+.I bunzip2
+(or
+.I bzip2 \-d)
+decompresses all
+specified files. Files which were not created by
+.I bzip2
+will be detected and ignored, and a warning issued.
+.I bzip2
+attempts to guess the filename for the decompressed file
+from that of the compressed file as follows:
+
+ filename.bz2 becomes filename
+ filename.bz becomes filename
+ filename.tbz2 becomes filename.tar
+ filename.tbz becomes filename.tar
+ anyothername becomes anyothername.out
+
+If the file does not end in one of the recognised endings,
+.I .bz2,
+.I .bz,
+.I .tbz2
+or
+.I .tbz,
+.I bzip2
+complains that it cannot
+guess the name of the original file, and uses the original name
+with
+.I .out
+appended.
+
+As with compression, supplying no
+filenames causes decompression from
+standard input to standard output.
+
+.I bunzip2
+will correctly decompress a file which is the
+concatenation of two or more compressed files. The result is the
+concatenation of the corresponding uncompressed files. Integrity
+testing (\-t)
+of concatenated
+compressed files is also supported.
+
+You can also compress or decompress files to the standard output by
+giving the \-c flag. Multiple files may be compressed and
+decompressed like this. The resulting outputs are fed sequentially to
+stdout. Compression of multiple files
+in this manner generates a stream
+containing multiple compressed file representations. Such a stream
+can be decompressed correctly only by
+.I bzip2
+version 0.9.0 or
+later. Earlier versions of
+.I bzip2
+will stop after decompressing
+the first file in the stream.
+
+.I bzcat
+(or
+.I bzip2 -dc)
+decompresses all specified files to
+the standard output.
+
+.I bzip2
+will read arguments from the environment variables
+.I BZIP2
+and
+.I BZIP,
+in that order, and will process them
+before any arguments read from the command line. This gives a
+convenient way to supply default arguments.
+
+Compression is always performed, even if the compressed
+file is slightly
+larger than the original. Files of less than about one hundred bytes
+tend to get larger, since the compression mechanism has a constant
+overhead in the region of 50 bytes. Random data (including the output
+of most file compressors) is coded at about 8.05 bits per byte, giving
+an expansion of around 0.5%.
+
+As a self-check for your protection,
+.I
+bzip2
+uses 32-bit CRCs to
+make sure that the decompressed version of a file is identical to the
+original. This guards against corruption of the compressed data, and
+against undetected bugs in
+.I bzip2
+(hopefully very unlikely). The
+chances of data corruption going undetected is microscopic, about one
+chance in four billion for each file processed. Be aware, though, that
+the check occurs upon decompression, so it can only tell you that
+something is wrong. It can't help you
+recover the original uncompressed
+data. You can use
+.I bzip2recover
+to try to recover data from
+damaged files.
+
+Return values: 0 for a normal exit, 1 for environmental problems (file
+not found, invalid flags, I/O errors, &c), 2 to indicate a corrupt
+compressed file, 3 for an internal consistency error (eg, bug) which
+caused
+.I bzip2
+to panic.
+
+.SH OPTIONS
+.TP
+.B \-c --stdout
+Compress or decompress to standard output.
+.TP
+.B \-d --decompress
+Force decompression.
+.I bzip2,
+.I bunzip2
+and
+.I bzcat
+are
+really the same program, and the decision about what actions to take is
+done on the basis of which name is used. This flag overrides that
+mechanism, and forces
+.I bzip2
+to decompress.
+.TP
+.B \-z --compress
+The complement to \-d: forces compression, regardless of the
+invocation name.
+.TP
+.B \-t --test
+Check integrity of the specified file(s), but don't decompress them.
+This really performs a trial decompression and throws away the result.
+.TP
+.B \-f --force
+Force overwrite of output files. Normally,
+.I bzip2
+will not overwrite
+existing output files. Also forces
+.I bzip2
+to break hard links
+to files, which it otherwise wouldn't do.
+
+bzip2 normally declines to decompress files which don't have the
+correct magic header bytes. If forced (-f), however, it will pass
+such files through unmodified. This is how GNU gzip behaves.
+.TP
+.B \-k --keep
+Keep (don't delete) input files during compression
+or decompression.
+.TP
+.B \-s --small
+Reduce memory usage, for compression, decompression and testing. Files
+are decompressed and tested using a modified algorithm which only
+requires 2.5 bytes per block byte. This means any file can be
+decompressed in 2300k of memory, albeit at about half the normal speed.
+
+During compression, \-s selects a block size of 200k, which limits
+memory use to around the same figure, at the expense of your compression
+ratio. In short, if your machine is low on memory (8 megabytes or
+less), use \-s for everything. See MEMORY MANAGEMENT below.
+.TP
+.B \-q --quiet
+Suppress non-essential warning messages. Messages pertaining to
+I/O errors and other critical events will not be suppressed.
+.TP
+.B \-v --verbose
+Verbose mode -- show the compression ratio for each file processed.
+Further \-v's increase the verbosity level, spewing out lots of
+information which is primarily of interest for diagnostic purposes.
+.TP
+.B \-L --license -V --version
+Display the software version, license terms and conditions.
+.TP
+.B \-1 (or \-\-fast) to \-9 (or \-\-best)
+Set the block size to 100 k, 200 k .. 900 k when compressing. Has no
+effect when decompressing. See MEMORY MANAGEMENT below.
+The \-\-fast and \-\-best aliases are primarily for GNU gzip
+compatibility. In particular, \-\-fast doesn't make things
+significantly faster.
+And \-\-best merely selects the default behaviour.
+.TP
+.B \--
+Treats all subsequent arguments as file names, even if they start
+with a dash. This is so you can handle files with names beginning
+with a dash, for example: bzip2 \-- \-myfilename.
+.TP
+.B \--repetitive-fast --repetitive-best
+These flags are redundant in versions 0.9.5 and above. They provided
+some coarse control over the behaviour of the sorting algorithm in
+earlier versions, which was sometimes useful. 0.9.5 and above have an
+improved algorithm which renders these flags irrelevant.
+
+.SH MEMORY MANAGEMENT
+.I bzip2
+compresses large files in blocks. The block size affects
+both the compression ratio achieved, and the amount of memory needed for
+compression and decompression. The flags \-1 through \-9
+specify the block size to be 100,000 bytes through 900,000 bytes (the
+default) respectively. At decompression time, the block size used for
+compression is read from the header of the compressed file, and
+.I bunzip2
+then allocates itself just enough memory to decompress
+the file. Since block sizes are stored in compressed files, it follows
+that the flags \-1 to \-9 are irrelevant to and so ignored
+during decompression.
+
+Compression and decompression requirements,
+in bytes, can be estimated as:
+
+ Compression: 400k + ( 8 x block size )
+
+ Decompression: 100k + ( 4 x block size ), or
+ 100k + ( 2.5 x block size )
+
+Larger block sizes give rapidly diminishing marginal returns. Most of
+the compression comes from the first two or three hundred k of block
+size, a fact worth bearing in mind when using
+.I bzip2
+on small machines.
+It is also important to appreciate that the decompression memory
+requirement is set at compression time by the choice of block size.
+
+For files compressed with the default 900k block size,
+.I bunzip2
+will require about 3700 kbytes to decompress. To support decompression
+of any file on a 4 megabyte machine,
+.I bunzip2
+has an option to
+decompress using approximately half this amount of memory, about 2300
+kbytes. Decompression speed is also halved, so you should use this
+option only where necessary. The relevant flag is -s.
+
+In general, try and use the largest block size memory constraints allow,
+since that maximises the compression achieved. Compression and
+decompression speed are virtually unaffected by block size.
+
+Another significant point applies to files which fit in a single block
+-- that means most files you'd encounter using a large block size. The
+amount of real memory touched is proportional to the size of the file,
+since the file is smaller than a block. For example, compressing a file
+20,000 bytes long with the flag -9 will cause the compressor to
+allocate around 7600k of memory, but only touch 400k + 20000 * 8 = 560
+kbytes of it. Similarly, the decompressor will allocate 3700k but only
+touch 100k + 20000 * 4 = 180 kbytes.
+
+Here is a table which summarises the maximum memory usage for different
+block sizes. Also recorded is the total compressed size for 14 files of
+the Calgary Text Compression Corpus totalling 3,141,622 bytes. This
+column gives some feel for how compression varies with block size.
+These figures tend to understate the advantage of larger block sizes for
+larger files, since the Corpus is dominated by smaller files.
+
+ Compress Decompress Decompress Corpus
+ Flag usage usage -s usage Size
+
+ -1 1200k 500k 350k 914704
+ -2 2000k 900k 600k 877703
+ -3 2800k 1300k 850k 860338
+ -4 3600k 1700k 1100k 846899
+ -5 4400k 2100k 1350k 845160
+ -6 5200k 2500k 1600k 838626
+ -7 6100k 2900k 1850k 834096
+ -8 6800k 3300k 2100k 828642
+ -9 7600k 3700k 2350k 828642
+
+.SH RECOVERING DATA FROM DAMAGED FILES
+.I bzip2
+compresses files in blocks, usually 900kbytes long. Each
+block is handled independently. If a media or transmission error causes
+a multi-block .bz2
+file to become damaged, it may be possible to
+recover data from the undamaged blocks in the file.
+
+The compressed representation of each block is delimited by a 48-bit
+pattern, which makes it possible to find the block boundaries with
+reasonable certainty. Each block also carries its own 32-bit CRC, so
+damaged blocks can be distinguished from undamaged ones.
+
+.I bzip2recover
+is a simple program whose purpose is to search for
+blocks in .bz2 files, and write each block out into its own .bz2
+file. You can then use
+.I bzip2
+\-t
+to test the
+integrity of the resulting files, and decompress those which are
+undamaged.
+
+.I bzip2recover
+takes a single argument, the name of the damaged file,
+and writes a number of files "rec00001file.bz2",
+"rec00002file.bz2", etc, containing the extracted blocks.
+The output filenames are designed so that the use of
+wildcards in subsequent processing -- for example,
+"bzip2 -dc rec*file.bz2 > recovered_data" -- processes the files in
+the correct order.
+
+.I bzip2recover
+should be of most use dealing with large .bz2
+files, as these will contain many blocks. It is clearly
+futile to use it on damaged single-block files, since a
+damaged block cannot be recovered. If you wish to minimise
+any potential data loss through media or transmission errors,
+you might consider compressing with a smaller
+block size.
+
+.SH PERFORMANCE NOTES
+The sorting phase of compression gathers together similar strings in the
+file. Because of this, files containing very long runs of repeated
+symbols, like "aabaabaabaab ..." (repeated several hundred times) may
+compress more slowly than normal. Versions 0.9.5 and above fare much
+better than previous versions in this respect. The ratio between
+worst-case and average-case compression time is in the region of 10:1.
+For previous versions, this figure was more like 100:1. You can use the
+\-vvvv option to monitor progress in great detail, if you want.
+
+Decompression speed is unaffected by these phenomena.
+
+.I bzip2
+usually allocates several megabytes of memory to operate
+in, and then charges all over it in a fairly random fashion. This means
+that performance, both for compressing and decompressing, is largely
+determined by the speed at which your machine can service cache misses.
+Because of this, small changes to the code to reduce the miss rate have
+been observed to give disproportionately large performance improvements.
+I imagine
+.I bzip2
+will perform best on machines with very large caches.
+
+.SH CAVEATS
+I/O error messages are not as helpful as they could be.
+.I bzip2
+tries hard to detect I/O errors and exit cleanly, but the details of
+what the problem is sometimes seem rather misleading.
+
+This manual page pertains to version 1.0.4 of
+.I bzip2.
+Compressed data created by this version is entirely forwards and
+backwards compatible with the previous public releases, versions
+0.1pl2, 0.9.0, 0.9.5, 1.0.0, 1.0.1, 1.0.2 and 1.0.3, but with the following
+exception: 0.9.0 and above can correctly decompress multiple
+concatenated compressed files. 0.1pl2 cannot do this; it will stop
+after decompressing just the first file in the stream.
+
+.I bzip2recover
+versions prior to 1.0.2 used 32-bit integers to represent
+bit positions in compressed files, so they could not handle compressed
+files more than 512 megabytes long. Versions 1.0.2 and above use
+64-bit ints on some platforms which support them (GNU supported
+targets, and Windows). To establish whether or not bzip2recover was
+built with such a limitation, run it without arguments. In any event
+you can build yourself an unlimited version if you can recompile it
+with MaybeUInt64 set to be an unsigned 64-bit integer.
+
+
+
+.SH AUTHOR
+Julian Seward, jsewardbzip.org.
+
+http://www.bzip.org
+
+The ideas embodied in
+.I bzip2
+are due to (at least) the following
+people: Michael Burrows and David Wheeler (for the block sorting
+transformation), David Wheeler (again, for the Huffman coder), Peter
+Fenwick (for the structured coding model in the original
+.I bzip,
+and many refinements), and Alistair Moffat, Radford Neal and Ian Witten
+(for the arithmetic coder in the original
+.I bzip).
+I am much
+indebted for their help, support and advice. See the manual in the
+source distribution for pointers to sources of documentation. Christian
+von Roques encouraged me to look for faster sorting algorithms, so as to
+speed up compression. Bela Lubkin encouraged me to improve the
+worst-case compression performance.
+Donna Robinson XMLised the documentation.
+The bz* scripts are derived from those of GNU gzip.
+Many people sent patches, helped
+with portability problems, lent machines, gave advice and were generally
+helpful.
diff --git a/Utilities/cmbzip2/bzip2.1.preformatted b/Utilities/cmbzip2/bzip2.1.preformatted
new file mode 100644
index 000000000..15e16e50a
--- /dev/null
+++ b/Utilities/cmbzip2/bzip2.1.preformatted
@@ -0,0 +1,399 @@
+bzip2(1) bzip2(1)
+
+
+
+NNAAMMEE
+ bzip2, bunzip2 − a blockâ€sorting file compressor, v1.0.4
+ bzcat − decompresses files to stdout
+ bzip2recover − recovers data from damaged bzip2 files
+
+
+SSYYNNOOPPSSIISS
+ bbzziipp22 [ −−ccddffkkqqssttvvzzVVLL112233445566778899 ] [ _f_i_l_e_n_a_m_e_s _._._. ]
+ bbuunnzziipp22 [ −−ffkkvvssVVLL ] [ _f_i_l_e_n_a_m_e_s _._._. ]
+ bbzzccaatt [ −−ss ] [ _f_i_l_e_n_a_m_e_s _._._. ]
+ bbzziipp22rreeccoovveerr _f_i_l_e_n_a_m_e
+
+
+DDEESSCCRRIIPPTTIIOONN
+ _b_z_i_p_2 compresses files using the Burrowsâ€Wheeler block
+ sorting text compression algorithm, and Huffman coding.
+ Compression is generally considerably better than that
+ achieved by more conventional LZ77/LZ78â€based compressors,
+ and approaches the performance of the PPM family of sta­
+ tistical compressors.
+
+ The commandâ€line options are deliberately very similar to
+ those of _G_N_U _g_z_i_p_, but they are not identical.
+
+ _b_z_i_p_2 expects a list of file names to accompany the com­
+ mandâ€line flags. Each file is replaced by a compressed
+ version of itself, with the name "original_name.bz2".
+ Each compressed file has the same modification date, per­
+ missions, and, when possible, ownership as the correspond­
+ ing original, so that these properties can be correctly
+ restored at decompression time. File name handling is
+ naive in the sense that there is no mechanism for preserv­
+ ing original file names, permissions, ownerships or dates
+ in filesystems which lack these concepts, or have serious
+ file name length restrictions, such as MSâ€DOS.
+
+ _b_z_i_p_2 and _b_u_n_z_i_p_2 will by default not overwrite existing
+ files. If you want this to happen, specify the −f flag.
+
+ If no file names are specified, _b_z_i_p_2 compresses from
+ standard input to standard output. In this case, _b_z_i_p_2
+ will decline to write compressed output to a terminal, as
+ this would be entirely incomprehensible and therefore
+ pointless.
+
+ _b_u_n_z_i_p_2 (or _b_z_i_p_2 _−_d_) decompresses all specified files.
+ Files which were not created by _b_z_i_p_2 will be detected and
+ ignored, and a warning issued. _b_z_i_p_2 attempts to guess
+ the filename for the decompressed file from that of the
+ compressed file as follows:
+
+ filename.bz2 becomes filename
+ filename.bz becomes filename
+ filename.tbz2 becomes filename.tar
+ filename.tbz becomes filename.tar
+ anyothername becomes anyothername.out
+
+ If the file does not end in one of the recognised endings,
+ _._b_z_2_, _._b_z_, _._t_b_z_2 or _._t_b_z_, _b_z_i_p_2 complains that it cannot
+ guess the name of the original file, and uses the original
+ name with _._o_u_t appended.
+
+ As with compression, supplying no filenames causes decom­
+ pression from standard input to standard output.
+
+ _b_u_n_z_i_p_2 will correctly decompress a file which is the con­
+ catenation of two or more compressed files. The result is
+ the concatenation of the corresponding uncompressed files.
+ Integrity testing (−t) of concatenated compressed files is
+ also supported.
+
+ You can also compress or decompress files to the standard
+ output by giving the −c flag. Multiple files may be com­
+ pressed and decompressed like this. The resulting outputs
+ are fed sequentially to stdout. Compression of multiple
+ files in this manner generates a stream containing multi­
+ ple compressed file representations. Such a stream can be
+ decompressed correctly only by _b_z_i_p_2 version 0.9.0 or
+ later. Earlier versions of _b_z_i_p_2 will stop after decom­
+ pressing the first file in the stream.
+
+ _b_z_c_a_t (or _b_z_i_p_2 _â€_d_c_) decompresses all specified files to
+ the standard output.
+
+ _b_z_i_p_2 will read arguments from the environment variables
+ _B_Z_I_P_2 and _B_Z_I_P_, in that order, and will process them
+ before any arguments read from the command line. This
+ gives a convenient way to supply default arguments.
+
+ Compression is always performed, even if the compressed
+ file is slightly larger than the original. Files of less
+ than about one hundred bytes tend to get larger, since the
+ compression mechanism has a constant overhead in the
+ region of 50 bytes. Random data (including the output of
+ most file compressors) is coded at about 8.05 bits per
+ byte, giving an expansion of around 0.5%.
+
+ As a selfâ€check for your protection, _b_z_i_p_2 uses 32â€bit
+ CRCs to make sure that the decompressed version of a file
+ is identical to the original. This guards against corrup­
+ tion of the compressed data, and against undetected bugs
+ in _b_z_i_p_2 (hopefully very unlikely). The chances of data
+ corruption going undetected is microscopic, about one
+ chance in four billion for each file processed. Be aware,
+ though, that the check occurs upon decompression, so it
+ can only tell you that something is wrong. It can’t help
+ you recover the original uncompressed data. You can use
+ _b_z_i_p_2_r_e_c_o_v_e_r to try to recover data from damaged files.
+
+ Return values: 0 for a normal exit, 1 for environmental
+ problems (file not found, invalid flags, I/O errors, &c),
+ 2 to indicate a corrupt compressed file, 3 for an internal
+ consistency error (eg, bug) which caused _b_z_i_p_2 to panic.
+
+
+OOPPTTIIOONNSS
+ −−cc â€â€â€â€ssttddoouutt
+ Compress or decompress to standard output.
+
+ −−dd â€â€â€â€ddeeccoommpprreessss
+ Force decompression. _b_z_i_p_2_, _b_u_n_z_i_p_2 and _b_z_c_a_t are
+ really the same program, and the decision about
+ what actions to take is done on the basis of which
+ name is used. This flag overrides that mechanism,
+ and forces _b_z_i_p_2 to decompress.
+
+ −−zz â€â€â€â€ccoommpprreessss
+ The complement to −d: forces compression,
+ regardless of the invocation name.
+
+ −−tt â€â€â€â€tteesstt
+ Check integrity of the specified file(s), but don’t
+ decompress them. This really performs a trial
+ decompression and throws away the result.
+
+ −−ff â€â€â€â€ffoorrccee
+ Force overwrite of output files. Normally, _b_z_i_p_2
+ will not overwrite existing output files. Also
+ forces _b_z_i_p_2 to break hard links to files, which it
+ otherwise wouldn’t do.
+
+ bzip2 normally declines to decompress files which
+ don’t have the correct magic header bytes. If
+ forced (â€f), however, it will pass such files
+ through unmodified. This is how GNU gzip behaves.
+
+ −−kk â€â€â€â€kkeeeepp
+ Keep (don’t delete) input files during compression
+ or decompression.
+
+ −−ss â€â€â€â€ssmmaallll
+ Reduce memory usage, for compression, decompression
+ and testing. Files are decompressed and tested
+ using a modified algorithm which only requires 2.5
+ bytes per block byte. This means any file can be
+ decompressed in 2300k of memory, albeit at about
+ half the normal speed.
+
+ During compression, −s selects a block size of
+ 200k, which limits memory use to around the same
+ figure, at the expense of your compression ratio.
+ In short, if your machine is low on memory (8
+ megabytes or less), use −s for everything. See
+ MEMORY MANAGEMENT below.
+
+ −−qq â€â€â€â€qquuiieett
+ Suppress nonâ€essential warning messages. Messages
+ pertaining to I/O errors and other critical events
+ will not be suppressed.
+
+ −−vv â€â€â€â€vveerrbboossee
+ Verbose mode â€â€ show the compression ratio for each
+ file processed. Further −v’s increase the ver­
+ bosity level, spewing out lots of information which
+ is primarily of interest for diagnostic purposes.
+
+ −−LL â€â€â€â€lliicceennssee â€â€VV â€â€â€â€vveerrssiioonn
+ Display the software version, license terms and
+ conditions.
+
+ −−11 ((oorr −−−−ffaasstt)) ttoo −−99 ((oorr −−−−bbeesstt))
+ Set the block size to 100 k, 200 k .. 900 k when
+ compressing. Has no effect when decompressing.
+ See MEMORY MANAGEMENT below. The −−fast and −−best
+ aliases are primarily for GNU gzip compatibility.
+ In particular, −−fast doesn’t make things signifi­
+ cantly faster. And −−best merely selects the
+ default behaviour.
+
+ −− Treats all subsequent arguments as file names, even
+ if they start with a dash. This is so you can han­
+ dle files with names beginning with a dash, for
+ example: bzip2 −†−myfilename.
+
+ −−â€â€rreeppeettiittiivveeâ€â€ffaasstt â€â€â€â€rreeppeettiittiivveeâ€â€bbeesstt
+ These flags are redundant in versions 0.9.5 and
+ above. They provided some coarse control over the
+ behaviour of the sorting algorithm in earlier ver­
+ sions, which was sometimes useful. 0.9.5 and above
+ have an improved algorithm which renders these
+ flags irrelevant.
+
+
+MMEEMMOORRYY MMAANNAAGGEEMMEENNTT
+ _b_z_i_p_2 compresses large files in blocks. The block size
+ affects both the compression ratio achieved, and the
+ amount of memory needed for compression and decompression.
+ The flags −1 through −9 specify the block size to be
+ 100,000 bytes through 900,000 bytes (the default) respec­
+ tively. At decompression time, the block size used for
+ compression is read from the header of the compressed
+ file, and _b_u_n_z_i_p_2 then allocates itself just enough memory
+ to decompress the file. Since block sizes are stored in
+ compressed files, it follows that the flags −1 to −9 are
+ irrelevant to and so ignored during decompression.
+
+ Compression and decompression requirements, in bytes, can
+ be estimated as:
+
+ Compression: 400k + ( 8 x block size )
+
+ Decompression: 100k + ( 4 x block size ), or
+ 100k + ( 2.5 x block size )
+
+ Larger block sizes give rapidly diminishing marginal
+ returns. Most of the compression comes from the first two
+ or three hundred k of block size, a fact worth bearing in
+ mind when using _b_z_i_p_2 on small machines. It is also
+ important to appreciate that the decompression memory
+ requirement is set at compression time by the choice of
+ block size.
+
+ For files compressed with the default 900k block size,
+ _b_u_n_z_i_p_2 will require about 3700 kbytes to decompress. To
+ support decompression of any file on a 4 megabyte machine,
+ _b_u_n_z_i_p_2 has an option to decompress using approximately
+ half this amount of memory, about 2300 kbytes. Decompres­
+ sion speed is also halved, so you should use this option
+ only where necessary. The relevant flag is â€s.
+
+ In general, try and use the largest block size memory con­
+ straints allow, since that maximises the compression
+ achieved. Compression and decompression speed are virtu­
+ ally unaffected by block size.
+
+ Another significant point applies to files which fit in a
+ single block â€â€ that means most files you’d encounter
+ using a large block size. The amount of real memory
+ touched is proportional to the size of the file, since the
+ file is smaller than a block. For example, compressing a
+ file 20,000 bytes long with the flag â€9 will cause the
+ compressor to allocate around 7600k of memory, but only
+ touch 400k + 20000 * 8 = 560 kbytes of it. Similarly, the
+ decompressor will allocate 3700k but only touch 100k +
+ 20000 * 4 = 180 kbytes.
+
+ Here is a table which summarises the maximum memory usage
+ for different block sizes. Also recorded is the total
+ compressed size for 14 files of the Calgary Text Compres­
+ sion Corpus totalling 3,141,622 bytes. This column gives
+ some feel for how compression varies with block size.
+ These figures tend to understate the advantage of larger
+ block sizes for larger files, since the Corpus is domi­
+ nated by smaller files.
+
+ Compress Decompress Decompress Corpus
+ Flag usage usage â€s usage Size
+
+ â€1 1200k 500k 350k 914704
+ â€2 2000k 900k 600k 877703
+ â€3 2800k 1300k 850k 860338
+ â€4 3600k 1700k 1100k 846899
+ â€5 4400k 2100k 1350k 845160
+ â€6 5200k 2500k 1600k 838626
+ â€7 6100k 2900k 1850k 834096
+ â€8 6800k 3300k 2100k 828642
+ â€9 7600k 3700k 2350k 828642
+
+
+RREECCOOVVEERRIINNGG DDAATTAA FFRROOMM DDAAMMAAGGEEDD FFIILLEESS
+ _b_z_i_p_2 compresses files in blocks, usually 900kbytes long.
+ Each block is handled independently. If a media or trans­
+ mission error causes a multiâ€block .bz2 file to become
+ damaged, it may be possible to recover data from the
+ undamaged blocks in the file.
+
+ The compressed representation of each block is delimited
+ by a 48â€bit pattern, which makes it possible to find the
+ block boundaries with reasonable certainty. Each block
+ also carries its own 32â€bit CRC, so damaged blocks can be
+ distinguished from undamaged ones.
+
+ _b_z_i_p_2_r_e_c_o_v_e_r is a simple program whose purpose is to
+ search for blocks in .bz2 files, and write each block out
+ into its own .bz2 file. You can then use _b_z_i_p_2 −t to test
+ the integrity of the resulting files, and decompress those
+ which are undamaged.
+
+ _b_z_i_p_2_r_e_c_o_v_e_r takes a single argument, the name of the dam­
+ aged file, and writes a number of files
+ "rec00001file.bz2", "rec00002file.bz2", etc, containing
+ the extracted blocks. The output filenames are
+ designed so that the use of wildcards in subsequent pro­
+ cessing â€â€ for example, "bzip2 â€dc rec*file.bz2 > recov­
+ ered_data" â€â€ processes the files in the correct order.
+
+ _b_z_i_p_2_r_e_c_o_v_e_r should be of most use dealing with large .bz2
+ files, as these will contain many blocks. It is clearly
+ futile to use it on damaged singleâ€block files, since a
+ damaged block cannot be recovered. If you wish to min­
+ imise any potential data loss through media or transmis­
+ sion errors, you might consider compressing with a smaller
+ block size.
+
+
+PPEERRFFOORRMMAANNCCEE NNOOTTEESS
+ The sorting phase of compression gathers together similar
+ strings in the file. Because of this, files containing
+ very long runs of repeated symbols, like "aabaabaabaab
+ ..." (repeated several hundred times) may compress more
+ slowly than normal. Versions 0.9.5 and above fare much
+ better than previous versions in this respect. The ratio
+ between worstâ€case and averageâ€case compression time is in
+ the region of 10:1. For previous versions, this figure
+ was more like 100:1. You can use the −vvvv option to mon­
+ itor progress in great detail, if you want.
+
+ Decompression speed is unaffected by these phenomena.
+
+ _b_z_i_p_2 usually allocates several megabytes of memory to
+ operate in, and then charges all over it in a fairly ran­
+ dom fashion. This means that performance, both for com­
+ pressing and decompressing, is largely determined by the
+ speed at which your machine can service cache misses.
+ Because of this, small changes to the code to reduce the
+ miss rate have been observed to give disproportionately
+ large performance improvements. I imagine _b_z_i_p_2 will per­
+ form best on machines with very large caches.
+
+
+CCAAVVEEAATTSS
+ I/O error messages are not as helpful as they could be.
+ _b_z_i_p_2 tries hard to detect I/O errors and exit cleanly,
+ but the details of what the problem is sometimes seem
+ rather misleading.
+
+ This manual page pertains to version 1.0.4 of _b_z_i_p_2_. Com­
+ pressed data created by this version is entirely forwards
+ and backwards compatible with the previous public
+ releases, versions 0.1pl2, 0.9.0, 0.9.5, 1.0.0, 1.0.1,
+ 1.0.2 and 1.0.3, but with the following exception: 0.9.0
+ and above can correctly decompress multiple concatenated
+ compressed files. 0.1pl2 cannot do this; it will stop
+ after decompressing just the first file in the stream.
+
+ _b_z_i_p_2_r_e_c_o_v_e_r versions prior to 1.0.2 used 32â€bit integers
+ to represent bit positions in compressed files, so they
+ could not handle compressed files more than 512 megabytes
+ long. Versions 1.0.2 and above use 64â€bit ints on some
+ platforms which support them (GNU supported targets, and
+ Windows). To establish whether or not bzip2recover was
+ built with such a limitation, run it without arguments.
+ In any event you can build yourself an unlimited version
+ if you can recompile it with MaybeUInt64 set to be an
+ unsigned 64â€bit integer.
+
+
+
+
+AAUUTTHHOORR
+ Julian Seward, jsewardbzip.org.
+
+ http://www.bzip.org
+
+ The ideas embodied in _b_z_i_p_2 are due to (at least) the fol­
+ lowing people: Michael Burrows and David Wheeler (for the
+ block sorting transformation), David Wheeler (again, for
+ the Huffman coder), Peter Fenwick (for the structured cod­
+ ing model in the original _b_z_i_p_, and many refinements), and
+ Alistair Moffat, Radford Neal and Ian Witten (for the
+ arithmetic coder in the original _b_z_i_p_)_. I am much
+ indebted for their help, support and advice. See the man­
+ ual in the source distribution for pointers to sources of
+ documentation. Christian von Roques encouraged me to look
+ for faster sorting algorithms, so as to speed up compres­
+ sion. Bela Lubkin encouraged me to improve the worstâ€case
+ compression performance. Donna Robinson XMLised the docu­
+ mentation. The bz* scripts are derived from those of GNU
+ gzip. Many people sent patches, helped with portability
+ problems, lent machines, gave advice and were generally
+ helpful.
+
+
+
+ bzip2(1)
diff --git a/Utilities/cmbzip2/bzip2.c b/Utilities/cmbzip2/bzip2.c
new file mode 100644
index 000000000..88e5f0936
--- /dev/null
+++ b/Utilities/cmbzip2/bzip2.c
@@ -0,0 +1,2034 @@
+
+/*-----------------------------------------------------------*/
+/*--- A block-sorting, lossless compressor bzip2.c ---*/
+/*-----------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
+
+ bzip2/libbzip2 version 1.0.5 of 10 December 2007
+ Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
+
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------ */
+
+
+/* Place a 1 beside your platform, and 0 elsewhere.
+ Generic 32-bit Unix.
+ Also works on 64-bit Unix boxes.
+ This is the default.
+*/
+#define BZ_UNIX 1
+
+/*--
+ Win32, as seen by Jacob Navia's excellent
+ port of (Chris Fraser & David Hanson)'s excellent
+ lcc compiler. Or with MS Visual C.
+ This is selected automatically if compiled by a compiler which
+ defines _WIN32, not including the Cygwin GCC.
+--*/
+#define BZ_LCCWIN32 0
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#undef BZ_LCCWIN32
+#define BZ_LCCWIN32 1
+#undef BZ_UNIX
+#define BZ_UNIX 0
+#endif
+
+
+/*---------------------------------------------*/
+/*--
+ Some stuff for all platforms.
+--*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <math.h>
+#include <errno.h>
+#include <ctype.h>
+#include "bzlib.h"
+
+#define ERROR_IF_EOF(i) { if ((i) == EOF) ioError(); }
+#define ERROR_IF_NOT_ZERO(i) { if ((i) != 0) ioError(); }
+#define ERROR_IF_MINUS_ONE(i) { if ((i) == (-1)) ioError(); }
+
+
+/*---------------------------------------------*/
+/*--
+ Platform-specific stuff.
+--*/
+
+#if BZ_UNIX
+# include <fcntl.h>
+# include <sys/types.h>
+# include <utime.h>
+# include <unistd.h>
+# include <sys/stat.h>
+# include <sys/times.h>
+
+# define PATH_SEP '/'
+# define MY_LSTAT lstat
+# define MY_STAT stat
+# define MY_S_ISREG S_ISREG
+# define MY_S_ISDIR S_ISDIR
+
+# define APPEND_FILESPEC(root, name) \
+ root=snocString((root), (name))
+
+# define APPEND_FLAG(root, name) \
+ root=snocString((root), (name))
+
+# define SET_BINARY_MODE(fd) /**/
+
+# ifdef __GNUC__
+# define NORETURN __attribute__ ((noreturn))
+# else
+# define NORETURN /**/
+# endif
+
+# ifdef __DJGPP__
+# include <io.h>
+# include <fcntl.h>
+# undef MY_LSTAT
+# undef MY_STAT
+# define MY_LSTAT stat
+# define MY_STAT stat
+# undef SET_BINARY_MODE
+# define SET_BINARY_MODE(fd) \
+ do { \
+ int retVal = setmode ( fileno ( fd ), \
+ O_BINARY ); \
+ ERROR_IF_MINUS_ONE ( retVal ); \
+ } while ( 0 )
+# endif
+
+# ifdef __CYGWIN__
+# include <io.h>
+# include <fcntl.h>
+# undef SET_BINARY_MODE
+# define SET_BINARY_MODE(fd) \
+ do { \
+ int retVal = setmode ( fileno ( fd ), \
+ O_BINARY ); \
+ ERROR_IF_MINUS_ONE ( retVal ); \
+ } while ( 0 )
+# endif
+#endif /* BZ_UNIX */
+
+
+
+#if BZ_LCCWIN32
+# include <io.h>
+# include <fcntl.h>
+# include <sys\stat.h>
+
+# define NORETURN /**/
+# define PATH_SEP '\\'
+# define MY_LSTAT _stat
+# define MY_STAT _stat
+# define MY_S_ISREG(x) ((x) & _S_IFREG)
+# define MY_S_ISDIR(x) ((x) & _S_IFDIR)
+
+# define APPEND_FLAG(root, name) \
+ root=snocString((root), (name))
+
+# define APPEND_FILESPEC(root, name) \
+ root = snocString ((root), (name))
+
+# define SET_BINARY_MODE(fd) \
+ do { \
+ int retVal = setmode ( fileno ( fd ), \
+ O_BINARY ); \
+ ERROR_IF_MINUS_ONE ( retVal ); \
+ } while ( 0 )
+
+#endif /* BZ_LCCWIN32 */
+
+
+/*---------------------------------------------*/
+/*--
+ Some more stuff for all platforms :-)
+--*/
+
+typedef char Char;
+typedef unsigned char Bool;
+typedef unsigned char UChar;
+typedef int Int32;
+typedef unsigned int UInt32;
+typedef short Int16;
+typedef unsigned short UInt16;
+
+#define True ((Bool)1)
+#define False ((Bool)0)
+
+/*--
+ IntNative is your platform's `native' int size.
+ Only here to avoid probs with 64-bit platforms.
+--*/
+typedef int IntNative;
+
+
+/*---------------------------------------------------*/
+/*--- Misc (file handling) data decls ---*/
+/*---------------------------------------------------*/
+
+Int32 verbosity;
+Bool keepInputFiles, smallMode, deleteOutputOnInterrupt;
+Bool forceOverwrite, testFailsExist, unzFailsExist, noisy;
+Int32 numFileNames, numFilesProcessed, blockSize100k;
+Int32 exitValue;
+
+/*-- source modes; F==file, I==stdin, O==stdout --*/
+#define SM_I2O 1
+#define SM_F2O 2
+#define SM_F2F 3
+
+/*-- operation modes --*/
+#define OM_Z 1
+#define OM_UNZ 2
+#define OM_TEST 3
+
+Int32 opMode;
+Int32 srcMode;
+
+#define FILE_NAME_LEN 1034
+
+Int32 longestFileName;
+Char inName [FILE_NAME_LEN];
+Char outName[FILE_NAME_LEN];
+Char tmpName[FILE_NAME_LEN];
+Char *progName;
+Char progNameReally[FILE_NAME_LEN];
+FILE *outputHandleJustInCase;
+Int32 workFactor;
+
+static void panic ( const Char* ) NORETURN;
+static void ioError ( void ) NORETURN;
+static void outOfMemory ( void ) NORETURN;
+static void configError ( void ) NORETURN;
+static void crcError ( void ) NORETURN;
+static void cleanUpAndFail ( Int32 ) NORETURN;
+static void compressedStreamEOF ( void ) NORETURN;
+
+static void copyFileName ( Char*, Char* );
+static void* myMalloc ( Int32 );
+static void applySavedFileAttrToOutputFile ( IntNative fd );
+
+
+
+/*---------------------------------------------------*/
+/*--- An implementation of 64-bit ints. Sigh. ---*/
+/*--- Roll on widespread deployment of ANSI C9X ! ---*/
+/*---------------------------------------------------*/
+
+typedef
+ struct { UChar b[8]; }
+ UInt64;
+
+
+static
+void uInt64_from_UInt32s ( UInt64* n, UInt32 lo32, UInt32 hi32 )
+{
+ n->b[7] = (UChar)((hi32 >> 24) & 0xFF);
+ n->b[6] = (UChar)((hi32 >> 16) & 0xFF);
+ n->b[5] = (UChar)((hi32 >> 8) & 0xFF);
+ n->b[4] = (UChar) (hi32 & 0xFF);
+ n->b[3] = (UChar)((lo32 >> 24) & 0xFF);
+ n->b[2] = (UChar)((lo32 >> 16) & 0xFF);
+ n->b[1] = (UChar)((lo32 >> 8) & 0xFF);
+ n->b[0] = (UChar) (lo32 & 0xFF);
+}
+
+
+static
+double uInt64_to_double ( UInt64* n )
+{
+ Int32 i;
+ double base = 1.0;
+ double sum = 0.0;
+ for (i = 0; i < 8; i++) {
+ sum += base * (double)(n->b[i]);
+ base *= 256.0;
+ }
+ return sum;
+}
+
+
+static
+Bool uInt64_isZero ( UInt64* n )
+{
+ Int32 i;
+ for (i = 0; i < 8; i++)
+ if (n->b[i] != 0) return 0;
+ return 1;
+}
+
+
+/* Divide *n by 10, and return the remainder. */
+static
+Int32 uInt64_qrm10 ( UInt64* n )
+{
+ UInt32 rem, tmp;
+ Int32 i;
+ rem = 0;
+ for (i = 7; i >= 0; i--) {
+ tmp = rem * 256 + n->b[i];
+ n->b[i] = tmp / 10;
+ rem = tmp % 10;
+ }
+ return rem;
+}
+
+
+/* ... and the Whole Entire Point of all this UInt64 stuff is
+ so that we can supply the following function.
+*/
+static
+void uInt64_toAscii ( char* outbuf, UInt64* n )
+{
+ Int32 i, q;
+ UChar buf[32];
+ Int32 nBuf = 0;
+ UInt64 n_copy = *n;
+ do {
+ q = uInt64_qrm10 ( &n_copy );
+ buf[nBuf] = q + '0';
+ nBuf++;
+ } while (!uInt64_isZero(&n_copy));
+ outbuf[nBuf] = 0;
+ for (i = 0; i < nBuf; i++)
+ outbuf[i] = buf[nBuf-i-1];
+}
+
+
+/*---------------------------------------------------*/
+/*--- Processing of complete files and streams ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------*/
+static
+Bool myfeof ( FILE* f )
+{
+ Int32 c = fgetc ( f );
+ if (c == EOF) return True;
+ ungetc ( c, f );
+ return False;
+}
+
+
+/*---------------------------------------------*/
+static
+void compressStream ( FILE *stream, FILE *zStream )
+{
+ BZFILE* bzf = NULL;
+ UChar ibuf[5000];
+ Int32 nIbuf;
+ UInt32 nbytes_in_lo32, nbytes_in_hi32;
+ UInt32 nbytes_out_lo32, nbytes_out_hi32;
+ Int32 bzerr, bzerr_dummy, ret;
+
+ SET_BINARY_MODE(stream);
+ SET_BINARY_MODE(zStream);
+
+ if (ferror(stream)) goto errhandler_io;
+ if (ferror(zStream)) goto errhandler_io;
+
+ bzf = BZ2_bzWriteOpen ( &bzerr, zStream,
+ blockSize100k, verbosity, workFactor );
+ if (bzerr != BZ_OK) goto errhandler;
+
+ if (verbosity >= 2) fprintf ( stderr, "\n" );
+
+ while (True) {
+
+ if (myfeof(stream)) break;
+ nIbuf = fread ( ibuf, sizeof(UChar), 5000, stream );
+ if (ferror(stream)) goto errhandler_io;
+ if (nIbuf > 0) BZ2_bzWrite ( &bzerr, bzf, (void*)ibuf, nIbuf );
+ if (bzerr != BZ_OK) goto errhandler;
+
+ }
+
+ BZ2_bzWriteClose64 ( &bzerr, bzf, 0,
+ &nbytes_in_lo32, &nbytes_in_hi32,
+ &nbytes_out_lo32, &nbytes_out_hi32 );
+ if (bzerr != BZ_OK) goto errhandler;
+
+ if (ferror(zStream)) goto errhandler_io;
+ ret = fflush ( zStream );
+ if (ret == EOF) goto errhandler_io;
+ if (zStream != stdout) {
+ Int32 fd = fileno ( zStream );
+ if (fd < 0) goto errhandler_io;
+ applySavedFileAttrToOutputFile ( fd );
+ ret = fclose ( zStream );
+ outputHandleJustInCase = NULL;
+ if (ret == EOF) goto errhandler_io;
+ }
+ outputHandleJustInCase = NULL;
+ if (ferror(stream)) goto errhandler_io;
+ ret = fclose ( stream );
+ if (ret == EOF) goto errhandler_io;
+
+ if (verbosity >= 1) {
+ if (nbytes_in_lo32 == 0 && nbytes_in_hi32 == 0) {
+ fprintf ( stderr, " no data compressed.\n");
+ } else {
+ Char buf_nin[32], buf_nout[32];
+ UInt64 nbytes_in, nbytes_out;
+ double nbytes_in_d, nbytes_out_d;
+ uInt64_from_UInt32s ( &nbytes_in,
+ nbytes_in_lo32, nbytes_in_hi32 );
+ uInt64_from_UInt32s ( &nbytes_out,
+ nbytes_out_lo32, nbytes_out_hi32 );
+ nbytes_in_d = uInt64_to_double ( &nbytes_in );
+ nbytes_out_d = uInt64_to_double ( &nbytes_out );
+ uInt64_toAscii ( buf_nin, &nbytes_in );
+ uInt64_toAscii ( buf_nout, &nbytes_out );
+ fprintf ( stderr, "%6.3f:1, %6.3f bits/byte, "
+ "%5.2f%% saved, %s in, %s out.\n",
+ nbytes_in_d / nbytes_out_d,
+ (8.0 * nbytes_out_d) / nbytes_in_d,
+ 100.0 * (1.0 - nbytes_out_d / nbytes_in_d),
+ buf_nin,
+ buf_nout
+ );
+ }
+ }
+
+ return;
+
+ errhandler:
+ BZ2_bzWriteClose64 ( &bzerr_dummy, bzf, 1,
+ &nbytes_in_lo32, &nbytes_in_hi32,
+ &nbytes_out_lo32, &nbytes_out_hi32 );
+ switch (bzerr) {
+ case BZ_CONFIG_ERROR:
+ configError(); break;
+ case BZ_MEM_ERROR:
+ outOfMemory (); break;
+ case BZ_IO_ERROR:
+ errhandler_io:
+ ioError(); break;
+ default:
+ panic ( "compress:unexpected error" );
+ }
+
+ panic ( "compress:end" );
+ /*notreached*/
+}
+
+
+
+/*---------------------------------------------*/
+static
+Bool uncompressStream ( FILE *zStream, FILE *stream )
+{
+ BZFILE* bzf = NULL;
+ Int32 bzerr, bzerr_dummy, ret, nread, streamNo, i;
+ UChar obuf[5000];
+ UChar unused[BZ_MAX_UNUSED];
+ Int32 nUnused;
+ void* unusedTmpV;
+ UChar* unusedTmp;
+
+ nUnused = 0;
+ streamNo = 0;
+
+ SET_BINARY_MODE(stream);
+ SET_BINARY_MODE(zStream);
+
+ if (ferror(stream)) goto errhandler_io;
+ if (ferror(zStream)) goto errhandler_io;
+
+ while (True) {
+
+ bzf = BZ2_bzReadOpen (
+ &bzerr, zStream, verbosity,
+ (int)smallMode, unused, nUnused
+ );
+ if (bzf == NULL || bzerr != BZ_OK) goto errhandler;
+ streamNo++;
+
+ while (bzerr == BZ_OK) {
+ nread = BZ2_bzRead ( &bzerr, bzf, obuf, 5000 );
+ if (bzerr == BZ_DATA_ERROR_MAGIC) goto trycat;
+ if ((bzerr == BZ_OK || bzerr == BZ_STREAM_END) && nread > 0)
+ fwrite ( obuf, sizeof(UChar), nread, stream );
+ if (ferror(stream)) goto errhandler_io;
+ }
+ if (bzerr != BZ_STREAM_END) goto errhandler;
+
+ BZ2_bzReadGetUnused ( &bzerr, bzf, &unusedTmpV, &nUnused );
+ if (bzerr != BZ_OK) panic ( "decompress:bzReadGetUnused" );
+
+ unusedTmp = (UChar*)unusedTmpV;
+ for (i = 0; i < nUnused; i++) unused[i] = unusedTmp[i];
+
+ BZ2_bzReadClose ( &bzerr, bzf );
+ if (bzerr != BZ_OK) panic ( "decompress:bzReadGetUnused" );
+
+ if (nUnused == 0 && myfeof(zStream)) break;
+ }
+
+ closeok:
+ if (ferror(zStream)) goto errhandler_io;
+ if (stream != stdout) {
+ Int32 fd = fileno ( stream );
+ if (fd < 0) goto errhandler_io;
+ applySavedFileAttrToOutputFile ( fd );
+ }
+ ret = fclose ( zStream );
+ if (ret == EOF) goto errhandler_io;
+
+ if (ferror(stream)) goto errhandler_io;
+ ret = fflush ( stream );
+ if (ret != 0) goto errhandler_io;
+ if (stream != stdout) {
+ ret = fclose ( stream );
+ outputHandleJustInCase = NULL;
+ if (ret == EOF) goto errhandler_io;
+ }
+ outputHandleJustInCase = NULL;
+ if (verbosity >= 2) fprintf ( stderr, "\n " );
+ return True;
+
+ trycat:
+ if (forceOverwrite) {
+ rewind(zStream);
+ while (True) {
+ if (myfeof(zStream)) break;
+ nread = fread ( obuf, sizeof(UChar), 5000, zStream );
+ if (ferror(zStream)) goto errhandler_io;
+ if (nread > 0) fwrite ( obuf, sizeof(UChar), nread, stream );
+ if (ferror(stream)) goto errhandler_io;
+ }
+ goto closeok;
+ }
+
+ errhandler:
+ BZ2_bzReadClose ( &bzerr_dummy, bzf );
+ switch (bzerr) {
+ case BZ_CONFIG_ERROR:
+ configError(); break;
+ case BZ_IO_ERROR:
+ errhandler_io:
+ ioError(); break;
+ case BZ_DATA_ERROR:
+ crcError();
+ case BZ_MEM_ERROR:
+ outOfMemory();
+ case BZ_UNEXPECTED_EOF:
+ compressedStreamEOF();
+ case BZ_DATA_ERROR_MAGIC:
+ if (zStream != stdin) fclose(zStream);
+ if (stream != stdout) fclose(stream);
+ if (streamNo == 1) {
+ return False;
+ } else {
+ if (noisy)
+ fprintf ( stderr,
+ "\n%s: %s: trailing garbage after EOF ignored\n",
+ progName, inName );
+ return True;
+ }
+ default:
+ panic ( "decompress:unexpected error" );
+ }
+
+ panic ( "decompress:end" );
+ return True; /*notreached*/
+}
+
+
+/*---------------------------------------------*/
+static
+Bool testStream ( FILE *zStream )
+{
+ BZFILE* bzf = NULL;
+ Int32 bzerr, bzerr_dummy, ret, nread, streamNo, i;
+ UChar obuf[5000];
+ UChar unused[BZ_MAX_UNUSED];
+ Int32 nUnused;
+ void* unusedTmpV;
+ UChar* unusedTmp;
+
+ nUnused = 0;
+ streamNo = 0;
+
+ SET_BINARY_MODE(zStream);
+ if (ferror(zStream)) goto errhandler_io;
+
+ while (True) {
+
+ bzf = BZ2_bzReadOpen (
+ &bzerr, zStream, verbosity,
+ (int)smallMode, unused, nUnused
+ );
+ if (bzf == NULL || bzerr != BZ_OK) goto errhandler;
+ streamNo++;
+
+ while (bzerr == BZ_OK) {
+ nread = BZ2_bzRead ( &bzerr, bzf, obuf, 5000 );
+ if (bzerr == BZ_DATA_ERROR_MAGIC) goto errhandler;
+ }
+ if (bzerr != BZ_STREAM_END) goto errhandler;
+
+ BZ2_bzReadGetUnused ( &bzerr, bzf, &unusedTmpV, &nUnused );
+ if (bzerr != BZ_OK) panic ( "test:bzReadGetUnused" );
+
+ unusedTmp = (UChar*)unusedTmpV;
+ for (i = 0; i < nUnused; i++) unused[i] = unusedTmp[i];
+
+ BZ2_bzReadClose ( &bzerr, bzf );
+ if (bzerr != BZ_OK) panic ( "test:bzReadGetUnused" );
+ if (nUnused == 0 && myfeof(zStream)) break;
+
+ }
+
+ if (ferror(zStream)) goto errhandler_io;
+ ret = fclose ( zStream );
+ if (ret == EOF) goto errhandler_io;
+
+ if (verbosity >= 2) fprintf ( stderr, "\n " );
+ return True;
+
+ errhandler:
+ BZ2_bzReadClose ( &bzerr_dummy, bzf );
+ if (verbosity == 0)
+ fprintf ( stderr, "%s: %s: ", progName, inName );
+ switch (bzerr) {
+ case BZ_CONFIG_ERROR:
+ configError(); break;
+ case BZ_IO_ERROR:
+ errhandler_io:
+ ioError(); break;
+ case BZ_DATA_ERROR:
+ fprintf ( stderr,
+ "data integrity (CRC) error in data\n" );
+ return False;
+ case BZ_MEM_ERROR:
+ outOfMemory();
+ case BZ_UNEXPECTED_EOF:
+ fprintf ( stderr,
+ "file ends unexpectedly\n" );
+ return False;
+ case BZ_DATA_ERROR_MAGIC:
+ if (zStream != stdin) fclose(zStream);
+ if (streamNo == 1) {
+ fprintf ( stderr,
+ "bad magic number (file not created by bzip2)\n" );
+ return False;
+ } else {
+ if (noisy)
+ fprintf ( stderr,
+ "trailing garbage after EOF ignored\n" );
+ return True;
+ }
+ default:
+ panic ( "test:unexpected error" );
+ }
+
+ panic ( "test:end" );
+ return True; /*notreached*/
+}
+
+
+/*---------------------------------------------------*/
+/*--- Error [non-] handling grunge ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------*/
+static
+void setExit ( Int32 v )
+{
+ if (v > exitValue) exitValue = v;
+}
+
+
+/*---------------------------------------------*/
+static
+void cadvise ( void )
+{
+ if (noisy)
+ fprintf (
+ stderr,
+ "\nIt is possible that the compressed file(s) have become corrupted.\n"
+ "You can use the -tvv option to test integrity of such files.\n\n"
+ "You can use the `bzip2recover' program to attempt to recover\n"
+ "data from undamaged sections of corrupted files.\n\n"
+ );
+}
+
+
+/*---------------------------------------------*/
+static
+void showFileNames ( void )
+{
+ if (noisy)
+ fprintf (
+ stderr,
+ "\tInput file = %s, output file = %s\n",
+ inName, outName
+ );
+}
+
+
+/*---------------------------------------------*/
+static
+void cleanUpAndFail ( Int32 ec )
+{
+ IntNative retVal;
+ struct MY_STAT statBuf;
+
+ if ( srcMode == SM_F2F
+ && opMode != OM_TEST
+ && deleteOutputOnInterrupt ) {
+
+ /* Check whether input file still exists. Delete output file
+ only if input exists to avoid loss of data. Joerg Prante, 5
+ January 2002. (JRS 06-Jan-2002: other changes in 1.0.2 mean
+ this is less likely to happen. But to be ultra-paranoid, we
+ do the check anyway.) */
+ retVal = MY_STAT ( inName, &statBuf );
+ if (retVal == 0) {
+ if (noisy)
+ fprintf ( stderr,
+ "%s: Deleting output file %s, if it exists.\n",
+ progName, outName );
+ if (outputHandleJustInCase != NULL)
+ fclose ( outputHandleJustInCase );
+ retVal = remove ( outName );
+ if (retVal != 0)
+ fprintf ( stderr,
+ "%s: WARNING: deletion of output file "
+ "(apparently) failed.\n",
+ progName );
+ } else {
+ fprintf ( stderr,
+ "%s: WARNING: deletion of output file suppressed\n",
+ progName );
+ fprintf ( stderr,
+ "%s: since input file no longer exists. Output file\n",
+ progName );
+ fprintf ( stderr,
+ "%s: `%s' may be incomplete.\n",
+ progName, outName );
+ fprintf ( stderr,
+ "%s: I suggest doing an integrity test (bzip2 -tv)"
+ " of it.\n",
+ progName );
+ }
+ }
+
+ if (noisy && numFileNames > 0 && numFilesProcessed < numFileNames) {
+ fprintf ( stderr,
+ "%s: WARNING: some files have not been processed:\n"
+ "%s: %d specified on command line, %d not processed yet.\n\n",
+ progName, progName,
+ numFileNames, numFileNames - numFilesProcessed );
+ }
+ setExit(ec);
+ exit(exitValue);
+}
+
+
+/*---------------------------------------------*/
+static
+void panic ( const Char* s )
+{
+ fprintf ( stderr,
+ "\n%s: PANIC -- internal consistency error:\n"
+ "\t%s\n"
+ "\tThis is a BUG. Please report it to me at:\n"
+ "\tjseward@bzip.org\n",
+ progName, s );
+ showFileNames();
+ cleanUpAndFail( 3 );
+}
+
+
+/*---------------------------------------------*/
+static
+void crcError ( void )
+{
+ fprintf ( stderr,
+ "\n%s: Data integrity error when decompressing.\n",
+ progName );
+ showFileNames();
+ cadvise();
+ cleanUpAndFail( 2 );
+}
+
+
+/*---------------------------------------------*/
+static
+void compressedStreamEOF ( void )
+{
+ if (noisy) {
+ fprintf ( stderr,
+ "\n%s: Compressed file ends unexpectedly;\n\t"
+ "perhaps it is corrupted? *Possible* reason follows.\n",
+ progName );
+ perror ( progName );
+ showFileNames();
+ cadvise();
+ }
+ cleanUpAndFail( 2 );
+}
+
+
+/*---------------------------------------------*/
+static
+void ioError ( void )
+{
+ fprintf ( stderr,
+ "\n%s: I/O or other error, bailing out. "
+ "Possible reason follows.\n",
+ progName );
+ perror ( progName );
+ showFileNames();
+ cleanUpAndFail( 1 );
+}
+
+
+/*---------------------------------------------*/
+static
+void mySignalCatcher ( IntNative n )
+{
+ fprintf ( stderr,
+ "\n%s: Control-C or similar caught, quitting.\n",
+ progName );
+ cleanUpAndFail(1);
+}
+
+
+/*---------------------------------------------*/
+static
+void mySIGSEGVorSIGBUScatcher ( IntNative n )
+{
+ if (opMode == OM_Z)
+ fprintf (
+ stderr,
+ "\n%s: Caught a SIGSEGV or SIGBUS whilst compressing.\n"
+ "\n"
+ " Possible causes are (most likely first):\n"
+ " (1) This computer has unreliable memory or cache hardware\n"
+ " (a surprisingly common problem; try a different machine.)\n"
+ " (2) A bug in the compiler used to create this executable\n"
+ " (unlikely, if you didn't compile bzip2 yourself.)\n"
+ " (3) A real bug in bzip2 -- I hope this should never be the case.\n"
+ " The user's manual, Section 4.3, has more info on (1) and (2).\n"
+ " \n"
+ " If you suspect this is a bug in bzip2, or are unsure about (1)\n"
+ " or (2), feel free to report it to me at: jseward@bzip.org.\n"
+ " Section 4.3 of the user's manual describes the info a useful\n"
+ " bug report should have. If the manual is available on your\n"
+ " system, please try and read it before mailing me. If you don't\n"
+ " have the manual or can't be bothered to read it, mail me anyway.\n"
+ "\n",
+ progName );
+ else
+ fprintf (
+ stderr,
+ "\n%s: Caught a SIGSEGV or SIGBUS whilst decompressing.\n"
+ "\n"
+ " Possible causes are (most likely first):\n"
+ " (1) The compressed data is corrupted, and bzip2's usual checks\n"
+ " failed to detect this. Try bzip2 -tvv my_file.bz2.\n"
+ " (2) This computer has unreliable memory or cache hardware\n"
+ " (a surprisingly common problem; try a different machine.)\n"
+ " (3) A bug in the compiler used to create this executable\n"
+ " (unlikely, if you didn't compile bzip2 yourself.)\n"
+ " (4) A real bug in bzip2 -- I hope this should never be the case.\n"
+ " The user's manual, Section 4.3, has more info on (2) and (3).\n"
+ " \n"
+ " If you suspect this is a bug in bzip2, or are unsure about (2)\n"
+ " or (3), feel free to report it to me at: jseward@bzip.org.\n"
+ " Section 4.3 of the user's manual describes the info a useful\n"
+ " bug report should have. If the manual is available on your\n"
+ " system, please try and read it before mailing me. If you don't\n"
+ " have the manual or can't be bothered to read it, mail me anyway.\n"
+ "\n",
+ progName );
+
+ showFileNames();
+ if (opMode == OM_Z)
+ cleanUpAndFail( 3 ); else
+ { cadvise(); cleanUpAndFail( 2 ); }
+}
+
+
+/*---------------------------------------------*/
+static
+void outOfMemory ( void )
+{
+ fprintf ( stderr,
+ "\n%s: couldn't allocate enough memory\n",
+ progName );
+ showFileNames();
+ cleanUpAndFail(1);
+}
+
+
+/*---------------------------------------------*/
+static
+void configError ( void )
+{
+ fprintf ( stderr,
+ "bzip2: I'm not configured correctly for this platform!\n"
+ "\tI require Int32, Int16 and Char to have sizes\n"
+ "\tof 4, 2 and 1 bytes to run properly, and they don't.\n"
+ "\tProbably you can fix this by defining them correctly,\n"
+ "\tand recompiling. Bye!\n" );
+ setExit(3);
+ exit(exitValue);
+}
+
+
+/*---------------------------------------------------*/
+/*--- The main driver machinery ---*/
+/*---------------------------------------------------*/
+
+/* All rather crufty. The main problem is that input files
+ are stat()d multiple times before use. This should be
+ cleaned up.
+*/
+
+/*---------------------------------------------*/
+static
+void pad ( Char *s )
+{
+ Int32 i;
+ if ( (Int32)strlen(s) >= longestFileName ) return;
+ for (i = 1; i <= longestFileName - (Int32)strlen(s); i++)
+ fprintf ( stderr, " " );
+}
+
+
+/*---------------------------------------------*/
+static
+void copyFileName ( Char* to, Char* from )
+{
+ if ( strlen(from) > FILE_NAME_LEN-10 ) {
+ fprintf (
+ stderr,
+ "bzip2: file name\n`%s'\n"
+ "is suspiciously (more than %d chars) long.\n"
+ "Try using a reasonable file name instead. Sorry! :-)\n",
+ from, FILE_NAME_LEN-10
+ );
+ setExit(1);
+ exit(exitValue);
+ }
+
+ strncpy(to,from,FILE_NAME_LEN-10);
+ to[FILE_NAME_LEN-10]='\0';
+}
+
+
+/*---------------------------------------------*/
+static
+Bool fileExists ( Char* name )
+{
+ FILE *tmp = fopen ( name, "rb" );
+ Bool exists = (tmp != NULL);
+ if (tmp != NULL) fclose ( tmp );
+ return exists;
+}
+
+
+/*---------------------------------------------*/
+/* Open an output file safely with O_EXCL and good permissions.
+ This avoids a race condition in versions < 1.0.2, in which
+ the file was first opened and then had its interim permissions
+ set safely. We instead use open() to create the file with
+ the interim permissions required. (--- --- rw-).
+
+ For non-Unix platforms, if we are not worrying about
+ security issues, simple this simply behaves like fopen.
+*/
+static
+FILE* fopen_output_safely ( Char* name, const char* mode )
+{
+# if BZ_UNIX
+ FILE* fp;
+ IntNative fh;
+ fh = open(name, O_WRONLY|O_CREAT|O_EXCL, S_IWUSR|S_IRUSR);
+ if (fh == -1) return NULL;
+ fp = fdopen(fh, mode);
+ if (fp == NULL) close(fh);
+ return fp;
+# else
+ return fopen(name, mode);
+# endif
+}
+
+
+/*---------------------------------------------*/
+/*--
+ if in doubt, return True
+--*/
+static
+Bool notAStandardFile ( Char* name )
+{
+ IntNative i;
+ struct MY_STAT statBuf;
+
+ i = MY_LSTAT ( name, &statBuf );
+ if (i != 0) return True;
+ if (MY_S_ISREG(statBuf.st_mode)) return False;
+ return True;
+}
+
+
+/*---------------------------------------------*/
+/*--
+ rac 11/21/98 see if file has hard links to it
+--*/
+static
+Int32 countHardLinks ( Char* name )
+{
+ IntNative i;
+ struct MY_STAT statBuf;
+
+ i = MY_LSTAT ( name, &statBuf );
+ if (i != 0) return 0;
+ return (statBuf.st_nlink - 1);
+}
+
+
+/*---------------------------------------------*/
+/* Copy modification date, access date, permissions and owner from the
+ source to destination file. We have to copy this meta-info off
+ into fileMetaInfo before starting to compress / decompress it,
+ because doing it afterwards means we get the wrong access time.
+
+ To complicate matters, in compress() and decompress() below, the
+ sequence of tests preceding the call to saveInputFileMetaInfo()
+ involves calling fileExists(), which in turn establishes its result
+ by attempting to fopen() the file, and if successful, immediately
+ fclose()ing it again. So we have to assume that the fopen() call
+ does not cause the access time field to be updated.
+
+ Reading of the man page for stat() (man 2 stat) on RedHat 7.2 seems
+ to imply that merely doing open() will not affect the access time.
+ Therefore we merely need to hope that the C library only does
+ open() as a result of fopen(), and not any kind of read()-ahead
+ cleverness.
+
+ It sounds pretty fragile to me. Whether this carries across
+ robustly to arbitrary Unix-like platforms (or even works robustly
+ on this one, RedHat 7.2) is unknown to me. Nevertheless ...
+*/
+#if BZ_UNIX
+static
+struct MY_STAT fileMetaInfo;
+#endif
+
+static
+void saveInputFileMetaInfo ( Char *srcName )
+{
+# if BZ_UNIX
+ IntNative retVal;
+ /* Note use of stat here, not lstat. */
+ retVal = MY_STAT( srcName, &fileMetaInfo );
+ ERROR_IF_NOT_ZERO ( retVal );
+# endif
+}
+
+
+static
+void applySavedTimeInfoToOutputFile ( Char *dstName )
+{
+# if BZ_UNIX
+ IntNative retVal;
+ struct utimbuf uTimBuf;
+
+ uTimBuf.actime = fileMetaInfo.st_atime;
+ uTimBuf.modtime = fileMetaInfo.st_mtime;
+
+ retVal = utime ( dstName, &uTimBuf );
+ ERROR_IF_NOT_ZERO ( retVal );
+# endif
+}
+
+static
+void applySavedFileAttrToOutputFile ( IntNative fd )
+{
+# if BZ_UNIX
+ IntNative retVal;
+
+ retVal = fchmod ( fd, fileMetaInfo.st_mode );
+ ERROR_IF_NOT_ZERO ( retVal );
+
+ (void) fchown ( fd, fileMetaInfo.st_uid, fileMetaInfo.st_gid );
+ /* chown() will in many cases return with EPERM, which can
+ be safely ignored.
+ */
+# endif
+}
+
+
+/*---------------------------------------------*/
+static
+Bool containsDubiousChars ( Char* name )
+{
+# if BZ_UNIX
+ /* On unix, files can contain any characters and the file expansion
+ * is performed by the shell.
+ */
+ return False;
+# else /* ! BZ_UNIX */
+ /* On non-unix (Win* platforms), wildcard characters are not allowed in
+ * filenames.
+ */
+ for (; *name != '\0'; name++)
+ if (*name == '?' || *name == '*') return True;
+ return False;
+# endif /* BZ_UNIX */
+}
+
+
+/*---------------------------------------------*/
+#define BZ_N_SUFFIX_PAIRS 4
+
+const Char* zSuffix[BZ_N_SUFFIX_PAIRS]
+ = { ".bz2", ".bz", ".tbz2", ".tbz" };
+const Char* unzSuffix[BZ_N_SUFFIX_PAIRS]
+ = { "", "", ".tar", ".tar" };
+
+static
+Bool hasSuffix ( Char* s, const Char* suffix )
+{
+ Int32 ns = strlen(s);
+ Int32 nx = strlen(suffix);
+ if (ns < nx) return False;
+ if (strcmp(s + ns - nx, suffix) == 0) return True;
+ return False;
+}
+
+static
+Bool mapSuffix ( Char* name,
+ const Char* oldSuffix,
+ const Char* newSuffix )
+{
+ if (!hasSuffix(name,oldSuffix)) return False;
+ name[strlen(name)-strlen(oldSuffix)] = 0;
+ strcat ( name, newSuffix );
+ return True;
+}
+
+
+/*---------------------------------------------*/
+static
+void compress ( Char *name )
+{
+ FILE *inStr;
+ FILE *outStr;
+ Int32 n, i;
+ struct MY_STAT statBuf;
+
+ deleteOutputOnInterrupt = False;
+
+ if (name == NULL && srcMode != SM_I2O)
+ panic ( "compress: bad modes\n" );
+
+ switch (srcMode) {
+ case SM_I2O:
+ copyFileName ( inName, (Char*)"(stdin)" );
+ copyFileName ( outName, (Char*)"(stdout)" );
+ break;
+ case SM_F2F:
+ copyFileName ( inName, name );
+ copyFileName ( outName, name );
+ strcat ( outName, ".bz2" );
+ break;
+ case SM_F2O:
+ copyFileName ( inName, name );
+ copyFileName ( outName, (Char*)"(stdout)" );
+ break;
+ }
+
+ if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) {
+ if (noisy)
+ fprintf ( stderr, "%s: There are no files matching `%s'.\n",
+ progName, inName );
+ setExit(1);
+ return;
+ }
+ if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
+ fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
+ progName, inName, strerror(errno) );
+ setExit(1);
+ return;
+ }
+ for (i = 0; i < BZ_N_SUFFIX_PAIRS; i++) {
+ if (hasSuffix(inName, zSuffix[i])) {
+ if (noisy)
+ fprintf ( stderr,
+ "%s: Input file %s already has %s suffix.\n",
+ progName, inName, zSuffix[i] );
+ setExit(1);
+ return;
+ }
+ }
+ if ( srcMode == SM_F2F || srcMode == SM_F2O ) {
+ MY_STAT(inName, &statBuf);
+ if ( MY_S_ISDIR(statBuf.st_mode) ) {
+ fprintf( stderr,
+ "%s: Input file %s is a directory.\n",
+ progName,inName);
+ setExit(1);
+ return;
+ }
+ }
+ if ( srcMode == SM_F2F && !forceOverwrite && notAStandardFile ( inName )) {
+ if (noisy)
+ fprintf ( stderr, "%s: Input file %s is not a normal file.\n",
+ progName, inName );
+ setExit(1);
+ return;
+ }
+ if ( srcMode == SM_F2F && fileExists ( outName ) ) {
+ if (forceOverwrite) {
+ remove(outName);
+ } else {
+ fprintf ( stderr, "%s: Output file %s already exists.\n",
+ progName, outName );
+ setExit(1);
+ return;
+ }
+ }
+ if ( srcMode == SM_F2F && !forceOverwrite &&
+ (n=countHardLinks ( inName )) > 0) {
+ fprintf ( stderr, "%s: Input file %s has %d other link%s.\n",
+ progName, inName, n, n > 1 ? "s" : "" );
+ setExit(1);
+ return;
+ }
+
+ if ( srcMode == SM_F2F ) {
+ /* Save the file's meta-info before we open it. Doing it later
+ means we mess up the access times. */
+ saveInputFileMetaInfo ( inName );
+ }
+
+ switch ( srcMode ) {
+
+ case SM_I2O:
+ inStr = stdin;
+ outStr = stdout;
+ if ( isatty ( fileno ( stdout ) ) ) {
+ fprintf ( stderr,
+ "%s: I won't write compressed data to a terminal.\n",
+ progName );
+ fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
+ progName, progName );
+ setExit(1);
+ return;
+ };
+ break;
+
+ case SM_F2O:
+ inStr = fopen ( inName, "rb" );
+ outStr = stdout;
+ if ( isatty ( fileno ( stdout ) ) ) {
+ fprintf ( stderr,
+ "%s: I won't write compressed data to a terminal.\n",
+ progName );
+ fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
+ progName, progName );
+ if ( inStr != NULL ) fclose ( inStr );
+ setExit(1);
+ return;
+ };
+ if ( inStr == NULL ) {
+ fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
+ progName, inName, strerror(errno) );
+ setExit(1);
+ return;
+ };
+ break;
+
+ case SM_F2F:
+ inStr = fopen ( inName, "rb" );
+ outStr = fopen_output_safely ( outName, "wb" );
+ if ( outStr == NULL) {
+ fprintf ( stderr, "%s: Can't create output file %s: %s.\n",
+ progName, outName, strerror(errno) );
+ if ( inStr != NULL ) fclose ( inStr );
+ setExit(1);
+ return;
+ }
+ if ( inStr == NULL ) {
+ fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
+ progName, inName, strerror(errno) );
+ if ( outStr != NULL ) fclose ( outStr );
+ setExit(1);
+ return;
+ };
+ break;
+
+ default:
+ panic ( "compress: bad srcMode" );
+ break;
+ }
+
+ if (verbosity >= 1) {
+ fprintf ( stderr, " %s: ", inName );
+ pad ( inName );
+ fflush ( stderr );
+ }
+
+ /*--- Now the input and output handles are sane. Do the Biz. ---*/
+ outputHandleJustInCase = outStr;
+ deleteOutputOnInterrupt = True;
+ compressStream ( inStr, outStr );
+ outputHandleJustInCase = NULL;
+
+ /*--- If there was an I/O error, we won't get here. ---*/
+ if ( srcMode == SM_F2F ) {
+ applySavedTimeInfoToOutputFile ( outName );
+ deleteOutputOnInterrupt = False;
+ if ( !keepInputFiles ) {
+ IntNative retVal = remove ( inName );
+ ERROR_IF_NOT_ZERO ( retVal );
+ }
+ }
+
+ deleteOutputOnInterrupt = False;
+}
+
+
+/*---------------------------------------------*/
+static
+void uncompress ( Char *name )
+{
+ FILE *inStr;
+ FILE *outStr;
+ Int32 n, i;
+ Bool magicNumberOK;
+ Bool cantGuess;
+ struct MY_STAT statBuf;
+
+ deleteOutputOnInterrupt = False;
+
+ if (name == NULL && srcMode != SM_I2O)
+ panic ( "uncompress: bad modes\n" );
+
+ cantGuess = False;
+ switch (srcMode) {
+ case SM_I2O:
+ copyFileName ( inName, (Char*)"(stdin)" );
+ copyFileName ( outName, (Char*)"(stdout)" );
+ break;
+ case SM_F2F:
+ copyFileName ( inName, name );
+ copyFileName ( outName, name );
+ for (i = 0; i < BZ_N_SUFFIX_PAIRS; i++)
+ if (mapSuffix(outName,zSuffix[i],unzSuffix[i]))
+ goto zzz;
+ cantGuess = True;
+ strcat ( outName, ".out" );
+ break;
+ case SM_F2O:
+ copyFileName ( inName, name );
+ copyFileName ( outName, (Char*)"(stdout)" );
+ break;
+ }
+
+ zzz:
+ if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) {
+ if (noisy)
+ fprintf ( stderr, "%s: There are no files matching `%s'.\n",
+ progName, inName );
+ setExit(1);
+ return;
+ }
+ if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
+ fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
+ progName, inName, strerror(errno) );
+ setExit(1);
+ return;
+ }
+ if ( srcMode == SM_F2F || srcMode == SM_F2O ) {
+ MY_STAT(inName, &statBuf);
+ if ( MY_S_ISDIR(statBuf.st_mode) ) {
+ fprintf( stderr,
+ "%s: Input file %s is a directory.\n",
+ progName,inName);
+ setExit(1);
+ return;
+ }
+ }
+ if ( srcMode == SM_F2F && !forceOverwrite && notAStandardFile ( inName )) {
+ if (noisy)
+ fprintf ( stderr, "%s: Input file %s is not a normal file.\n",
+ progName, inName );
+ setExit(1);
+ return;
+ }
+ if ( /* srcMode == SM_F2F implied && */ cantGuess ) {
+ if (noisy)
+ fprintf ( stderr,
+ "%s: Can't guess original name for %s -- using %s\n",
+ progName, inName, outName );
+ /* just a warning, no return */
+ }
+ if ( srcMode == SM_F2F && fileExists ( outName ) ) {
+ if (forceOverwrite) {
+ remove(outName);
+ } else {
+ fprintf ( stderr, "%s: Output file %s already exists.\n",
+ progName, outName );
+ setExit(1);
+ return;
+ }
+ }
+ if ( srcMode == SM_F2F && !forceOverwrite &&
+ (n=countHardLinks ( inName ) ) > 0) {
+ fprintf ( stderr, "%s: Input file %s has %d other link%s.\n",
+ progName, inName, n, n > 1 ? "s" : "" );
+ setExit(1);
+ return;
+ }
+
+ if ( srcMode == SM_F2F ) {
+ /* Save the file's meta-info before we open it. Doing it later
+ means we mess up the access times. */
+ saveInputFileMetaInfo ( inName );
+ }
+
+ switch ( srcMode ) {
+
+ case SM_I2O:
+ inStr = stdin;
+ outStr = stdout;
+ if ( isatty ( fileno ( stdin ) ) ) {
+ fprintf ( stderr,
+ "%s: I won't read compressed data from a terminal.\n",
+ progName );
+ fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
+ progName, progName );
+ setExit(1);
+ return;
+ };
+ break;
+
+ case SM_F2O:
+ inStr = fopen ( inName, "rb" );
+ outStr = stdout;
+ if ( inStr == NULL ) {
+ fprintf ( stderr, "%s: Can't open input file %s:%s.\n",
+ progName, inName, strerror(errno) );
+ if ( inStr != NULL ) fclose ( inStr );
+ setExit(1);
+ return;
+ };
+ break;
+
+ case SM_F2F:
+ inStr = fopen ( inName, "rb" );
+ outStr = fopen_output_safely ( outName, "wb" );
+ if ( outStr == NULL) {
+ fprintf ( stderr, "%s: Can't create output file %s: %s.\n",
+ progName, outName, strerror(errno) );
+ if ( inStr != NULL ) fclose ( inStr );
+ setExit(1);
+ return;
+ }
+ if ( inStr == NULL ) {
+ fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
+ progName, inName, strerror(errno) );
+ if ( outStr != NULL ) fclose ( outStr );
+ setExit(1);
+ return;
+ };
+ break;
+
+ default:
+ panic ( "uncompress: bad srcMode" );
+ break;
+ }
+
+ if (verbosity >= 1) {
+ fprintf ( stderr, " %s: ", inName );
+ pad ( inName );
+ fflush ( stderr );
+ }
+
+ /*--- Now the input and output handles are sane. Do the Biz. ---*/
+ outputHandleJustInCase = outStr;
+ deleteOutputOnInterrupt = True;
+ magicNumberOK = uncompressStream ( inStr, outStr );
+ outputHandleJustInCase = NULL;
+
+ /*--- If there was an I/O error, we won't get here. ---*/
+ if ( magicNumberOK ) {
+ if ( srcMode == SM_F2F ) {
+ applySavedTimeInfoToOutputFile ( outName );
+ deleteOutputOnInterrupt = False;
+ if ( !keepInputFiles ) {
+ IntNative retVal = remove ( inName );
+ ERROR_IF_NOT_ZERO ( retVal );
+ }
+ }
+ } else {
+ unzFailsExist = True;
+ deleteOutputOnInterrupt = False;
+ if ( srcMode == SM_F2F ) {
+ IntNative retVal = remove ( outName );
+ ERROR_IF_NOT_ZERO ( retVal );
+ }
+ }
+ deleteOutputOnInterrupt = False;
+
+ if ( magicNumberOK ) {
+ if (verbosity >= 1)
+ fprintf ( stderr, "done\n" );
+ } else {
+ setExit(2);
+ if (verbosity >= 1)
+ fprintf ( stderr, "not a bzip2 file.\n" ); else
+ fprintf ( stderr,
+ "%s: %s is not a bzip2 file.\n",
+ progName, inName );
+ }
+
+}
+
+
+/*---------------------------------------------*/
+static
+void testf ( Char *name )
+{
+ FILE *inStr;
+ Bool allOK;
+ struct MY_STAT statBuf;
+
+ deleteOutputOnInterrupt = False;
+
+ if (name == NULL && srcMode != SM_I2O)
+ panic ( "testf: bad modes\n" );
+
+ copyFileName ( outName, (Char*)"(none)" );
+ switch (srcMode) {
+ case SM_I2O: copyFileName ( inName, (Char*)"(stdin)" ); break;
+ case SM_F2F: copyFileName ( inName, name ); break;
+ case SM_F2O: copyFileName ( inName, name ); break;
+ }
+
+ if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) {
+ if (noisy)
+ fprintf ( stderr, "%s: There are no files matching `%s'.\n",
+ progName, inName );
+ setExit(1);
+ return;
+ }
+ if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
+ fprintf ( stderr, "%s: Can't open input %s: %s.\n",
+ progName, inName, strerror(errno) );
+ setExit(1);
+ return;
+ }
+ if ( srcMode != SM_I2O ) {
+ MY_STAT(inName, &statBuf);
+ if ( MY_S_ISDIR(statBuf.st_mode) ) {
+ fprintf( stderr,
+ "%s: Input file %s is a directory.\n",
+ progName,inName);
+ setExit(1);
+ return;
+ }
+ }
+
+ switch ( srcMode ) {
+
+ case SM_I2O:
+ if ( isatty ( fileno ( stdin ) ) ) {
+ fprintf ( stderr,
+ "%s: I won't read compressed data from a terminal.\n",
+ progName );
+ fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
+ progName, progName );
+ setExit(1);
+ return;
+ };
+ inStr = stdin;
+ break;
+
+ case SM_F2O: case SM_F2F:
+ inStr = fopen ( inName, "rb" );
+ if ( inStr == NULL ) {
+ fprintf ( stderr, "%s: Can't open input file %s:%s.\n",
+ progName, inName, strerror(errno) );
+ setExit(1);
+ return;
+ };
+ break;
+
+ default:
+ panic ( "testf: bad srcMode" );
+ break;
+ }
+
+ if (verbosity >= 1) {
+ fprintf ( stderr, " %s: ", inName );
+ pad ( inName );
+ fflush ( stderr );
+ }
+
+ /*--- Now the input handle is sane. Do the Biz. ---*/
+ outputHandleJustInCase = NULL;
+ allOK = testStream ( inStr );
+
+ if (allOK && verbosity >= 1) fprintf ( stderr, "ok\n" );
+ if (!allOK) testFailsExist = True;
+}
+
+
+/*---------------------------------------------*/
+static
+void license ( void )
+{
+ fprintf ( stderr,
+
+ "bzip2, a block-sorting file compressor. "
+ "Version %s.\n"
+ " \n"
+ " Copyright (C) 1996-2007 by Julian Seward.\n"
+ " \n"
+ " This program is free software; you can redistribute it and/or modify\n"
+ " it under the terms set out in the LICENSE file, which is included\n"
+ " in the bzip2-1.0.5 source distribution.\n"
+ " \n"
+ " This program is distributed in the hope that it will be useful,\n"
+ " but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ " LICENSE file for more details.\n"
+ " \n",
+ BZ2_bzlibVersion()
+ );
+}
+
+
+/*---------------------------------------------*/
+static
+void usage ( Char *fullProgName )
+{
+ fprintf (
+ stderr,
+ "bzip2, a block-sorting file compressor. "
+ "Version %s.\n"
+ "\n usage: %s [flags and input files in any order]\n"
+ "\n"
+ " -h --help print this message\n"
+ " -d --decompress force decompression\n"
+ " -z --compress force compression\n"
+ " -k --keep keep (don't delete) input files\n"
+ " -f --force overwrite existing output files\n"
+ " -t --test test compressed file integrity\n"
+ " -c --stdout output to standard out\n"
+ " -q --quiet suppress noncritical error messages\n"
+ " -v --verbose be verbose (a 2nd -v gives more)\n"
+ " -L --license display software version & license\n"
+ " -V --version display software version & license\n"
+ " -s --small use less memory (at most 2500k)\n"
+ " -1 .. -9 set block size to 100k .. 900k\n"
+ " --fast alias for -1\n"
+ " --best alias for -9\n"
+ "\n"
+ " If invoked as `bzip2', default action is to compress.\n"
+ " as `bunzip2', default action is to decompress.\n"
+ " as `bzcat', default action is to decompress to stdout.\n"
+ "\n"
+ " If no file names are given, bzip2 compresses or decompresses\n"
+ " from standard input to standard output. You can combine\n"
+ " short flags, so `-v -4' means the same as -v4 or -4v, &c.\n"
+# if BZ_UNIX
+ "\n"
+# endif
+ ,
+
+ BZ2_bzlibVersion(),
+ fullProgName
+ );
+}
+
+
+/*---------------------------------------------*/
+static
+void redundant ( Char* flag )
+{
+ fprintf (
+ stderr,
+ "%s: %s is redundant in versions 0.9.5 and above\n",
+ progName, flag );
+}
+
+
+/*---------------------------------------------*/
+/*--
+ All the garbage from here to main() is purely to
+ implement a linked list of command-line arguments,
+ into which main() copies argv[1 .. argc-1].
+
+ The purpose of this exercise is to facilitate
+ the expansion of wildcard characters * and ? in
+ filenames for OSs which don't know how to do it
+ themselves, like MSDOS, Windows 95 and NT.
+
+ The actual Dirty Work is done by the platform-
+ specific macro APPEND_FILESPEC.
+--*/
+
+typedef
+ struct zzzz {
+ Char *name;
+ struct zzzz *link;
+ }
+ Cell;
+
+
+/*---------------------------------------------*/
+static
+void *myMalloc ( Int32 n )
+{
+ void* p;
+
+ p = malloc ( (size_t)n );
+ if (p == NULL) outOfMemory ();
+ return p;
+}
+
+
+/*---------------------------------------------*/
+static
+Cell *mkCell ( void )
+{
+ Cell *c;
+
+ c = (Cell*) myMalloc ( sizeof ( Cell ) );
+ c->name = NULL;
+ c->link = NULL;
+ return c;
+}
+
+
+/*---------------------------------------------*/
+static
+Cell *snocString ( Cell *root, Char *name )
+{
+ if (root == NULL) {
+ Cell *tmp = mkCell();
+ tmp->name = (Char*) myMalloc ( 5 + strlen(name) );
+ strcpy ( tmp->name, name );
+ return tmp;
+ } else {
+ Cell *tmp = root;
+ while (tmp->link != NULL) tmp = tmp->link;
+ tmp->link = snocString ( tmp->link, name );
+ return root;
+ }
+}
+
+
+/*---------------------------------------------*/
+static
+void addFlagsFromEnvVar ( Cell** argList, Char* varName )
+{
+ Int32 i, j, k;
+ Char *envbase, *p;
+
+ envbase = getenv(varName);
+ if (envbase != NULL) {
+ p = envbase;
+ i = 0;
+ while (True) {
+ if (p[i] == 0) break;
+ p += i;
+ i = 0;
+ while (isspace((Int32)(p[0]))) p++;
+ while (p[i] != 0 && !isspace((Int32)(p[i]))) i++;
+ if (i > 0) {
+ k = i; if (k > FILE_NAME_LEN-10) k = FILE_NAME_LEN-10;
+ for (j = 0; j < k; j++) tmpName[j] = p[j];
+ tmpName[k] = 0;
+ APPEND_FLAG(*argList, tmpName);
+ }
+ }
+ }
+}
+
+
+/*---------------------------------------------*/
+#define ISFLAG(s) (strcmp(aa->name, (s))==0)
+
+IntNative main ( IntNative argc, Char *argv[] )
+{
+ Int32 i, j;
+ Char *tmp;
+ Cell *argList;
+ Cell *aa;
+ Bool decode;
+
+ /*-- Be really really really paranoid :-) --*/
+ if (sizeof(Int32) != 4 || sizeof(UInt32) != 4 ||
+ sizeof(Int16) != 2 || sizeof(UInt16) != 2 ||
+ sizeof(Char) != 1 || sizeof(UChar) != 1)
+ configError();
+
+ /*-- Initialise --*/
+ outputHandleJustInCase = NULL;
+ smallMode = False;
+ keepInputFiles = False;
+ forceOverwrite = False;
+ noisy = True;
+ verbosity = 0;
+ blockSize100k = 9;
+ testFailsExist = False;
+ unzFailsExist = False;
+ numFileNames = 0;
+ numFilesProcessed = 0;
+ workFactor = 30;
+ deleteOutputOnInterrupt = False;
+ exitValue = 0;
+ i = j = 0; /* avoid bogus warning from egcs-1.1.X */
+
+ /*-- Set up signal handlers for mem access errors --*/
+ signal (SIGSEGV, mySIGSEGVorSIGBUScatcher);
+# if BZ_UNIX
+# ifndef __DJGPP__
+ signal (SIGBUS, mySIGSEGVorSIGBUScatcher);
+# endif
+# endif
+
+ copyFileName ( inName, (Char*)"(none)" );
+ copyFileName ( outName, (Char*)"(none)" );
+
+ copyFileName ( progNameReally, argv[0] );
+ progName = &progNameReally[0];
+ for (tmp = &progNameReally[0]; *tmp != '\0'; tmp++)
+ if (*tmp == PATH_SEP) progName = tmp + 1;
+
+
+ /*-- Copy flags from env var BZIP2, and
+ expand filename wildcards in arg list.
+ --*/
+ argList = NULL;
+ addFlagsFromEnvVar ( &argList, (Char*)"BZIP2" );
+ addFlagsFromEnvVar ( &argList, (Char*)"BZIP" );
+ for (i = 1; i <= argc-1; i++)
+ APPEND_FILESPEC(argList, argv[i]);
+
+
+ /*-- Find the length of the longest filename --*/
+ longestFileName = 7;
+ numFileNames = 0;
+ decode = True;
+ for (aa = argList; aa != NULL; aa = aa->link) {
+ if (ISFLAG("--")) { decode = False; continue; }
+ if (aa->name[0] == '-' && decode) continue;
+ numFileNames++;
+ if (longestFileName < (Int32)strlen(aa->name) )
+ longestFileName = (Int32)strlen(aa->name);
+ }
+
+
+ /*-- Determine source modes; flag handling may change this too. --*/
+ if (numFileNames == 0)
+ srcMode = SM_I2O; else srcMode = SM_F2F;
+
+
+ /*-- Determine what to do (compress/uncompress/test/cat). --*/
+ /*-- Note that subsequent flag handling may change this. --*/
+ opMode = OM_Z;
+
+ if ( (strstr ( progName, "unzip" ) != 0) ||
+ (strstr ( progName, "UNZIP" ) != 0) )
+ opMode = OM_UNZ;
+
+ if ( (strstr ( progName, "z2cat" ) != 0) ||
+ (strstr ( progName, "Z2CAT" ) != 0) ||
+ (strstr ( progName, "zcat" ) != 0) ||
+ (strstr ( progName, "ZCAT" ) != 0) ) {
+ opMode = OM_UNZ;
+ srcMode = (numFileNames == 0) ? SM_I2O : SM_F2O;
+ }
+
+
+ /*-- Look at the flags. --*/
+ for (aa = argList; aa != NULL; aa = aa->link) {
+ if (ISFLAG("--")) break;
+ if (aa->name[0] == '-' && aa->name[1] != '-') {
+ for (j = 1; aa->name[j] != '\0'; j++) {
+ switch (aa->name[j]) {
+ case 'c': srcMode = SM_F2O; break;
+ case 'd': opMode = OM_UNZ; break;
+ case 'z': opMode = OM_Z; break;
+ case 'f': forceOverwrite = True; break;
+ case 't': opMode = OM_TEST; break;
+ case 'k': keepInputFiles = True; break;
+ case 's': smallMode = True; break;
+ case 'q': noisy = False; break;
+ case '1': blockSize100k = 1; break;
+ case '2': blockSize100k = 2; break;
+ case '3': blockSize100k = 3; break;
+ case '4': blockSize100k = 4; break;
+ case '5': blockSize100k = 5; break;
+ case '6': blockSize100k = 6; break;
+ case '7': blockSize100k = 7; break;
+ case '8': blockSize100k = 8; break;
+ case '9': blockSize100k = 9; break;
+ case 'V':
+ case 'L': license(); break;
+ case 'v': verbosity++; break;
+ case 'h': usage ( progName );
+ exit ( 0 );
+ break;
+ default: fprintf ( stderr, "%s: Bad flag `%s'\n",
+ progName, aa->name );
+ usage ( progName );
+ exit ( 1 );
+ break;
+ }
+ }
+ }
+ }
+
+ /*-- And again ... --*/
+ for (aa = argList; aa != NULL; aa = aa->link) {
+ if (ISFLAG("--")) break;
+ if (ISFLAG("--stdout")) srcMode = SM_F2O; else
+ if (ISFLAG("--decompress")) opMode = OM_UNZ; else
+ if (ISFLAG("--compress")) opMode = OM_Z; else
+ if (ISFLAG("--force")) forceOverwrite = True; else
+ if (ISFLAG("--test")) opMode = OM_TEST; else
+ if (ISFLAG("--keep")) keepInputFiles = True; else
+ if (ISFLAG("--small")) smallMode = True; else
+ if (ISFLAG("--quiet")) noisy = False; else
+ if (ISFLAG("--version")) license(); else
+ if (ISFLAG("--license")) license(); else
+ if (ISFLAG("--exponential")) workFactor = 1; else
+ if (ISFLAG("--repetitive-best")) redundant(aa->name); else
+ if (ISFLAG("--repetitive-fast")) redundant(aa->name); else
+ if (ISFLAG("--fast")) blockSize100k = 1; else
+ if (ISFLAG("--best")) blockSize100k = 9; else
+ if (ISFLAG("--verbose")) verbosity++; else
+ if (ISFLAG("--help")) { usage ( progName ); exit ( 0 ); }
+ else
+ if (strncmp ( aa->name, "--", 2) == 0) {
+ fprintf ( stderr, "%s: Bad flag `%s'\n", progName, aa->name );
+ usage ( progName );
+ exit ( 1 );
+ }
+ }
+
+ if (verbosity > 4) verbosity = 4;
+ if (opMode == OM_Z && smallMode && blockSize100k > 2)
+ blockSize100k = 2;
+
+ if (opMode == OM_TEST && srcMode == SM_F2O) {
+ fprintf ( stderr, "%s: -c and -t cannot be used together.\n",
+ progName );
+ exit ( 1 );
+ }
+
+ if (srcMode == SM_F2O && numFileNames == 0)
+ srcMode = SM_I2O;
+
+ if (opMode != OM_Z) blockSize100k = 0;
+
+ if (srcMode == SM_F2F) {
+ signal (SIGINT, mySignalCatcher);
+ signal (SIGTERM, mySignalCatcher);
+# if BZ_UNIX
+ signal (SIGHUP, mySignalCatcher);
+# endif
+ }
+
+ if (opMode == OM_Z) {
+ if (srcMode == SM_I2O) {
+ compress ( NULL );
+ } else {
+ decode = True;
+ for (aa = argList; aa != NULL; aa = aa->link) {
+ if (ISFLAG("--")) { decode = False; continue; }
+ if (aa->name[0] == '-' && decode) continue;
+ numFilesProcessed++;
+ compress ( aa->name );
+ }
+ }
+ }
+ else
+
+ if (opMode == OM_UNZ) {
+ unzFailsExist = False;
+ if (srcMode == SM_I2O) {
+ uncompress ( NULL );
+ } else {
+ decode = True;
+ for (aa = argList; aa != NULL; aa = aa->link) {
+ if (ISFLAG("--")) { decode = False; continue; }
+ if (aa->name[0] == '-' && decode) continue;
+ numFilesProcessed++;
+ uncompress ( aa->name );
+ }
+ }
+ if (unzFailsExist) {
+ setExit(2);
+ exit(exitValue);
+ }
+ }
+
+ else {
+ testFailsExist = False;
+ if (srcMode == SM_I2O) {
+ testf ( NULL );
+ } else {
+ decode = True;
+ for (aa = argList; aa != NULL; aa = aa->link) {
+ if (ISFLAG("--")) { decode = False; continue; }
+ if (aa->name[0] == '-' && decode) continue;
+ numFilesProcessed++;
+ testf ( aa->name );
+ }
+ }
+ if (testFailsExist && noisy) {
+ fprintf ( stderr,
+ "\n"
+ "You can use the `bzip2recover' program to attempt to recover\n"
+ "data from undamaged sections of corrupted files.\n\n"
+ );
+ setExit(2);
+ exit(exitValue);
+ }
+ }
+
+ /* Free the argument list memory to mollify leak detectors
+ (eg) Purify, Checker. Serves no other useful purpose.
+ */
+ aa = argList;
+ while (aa != NULL) {
+ Cell* aa2 = aa->link;
+ if (aa->name != NULL) free(aa->name);
+ free(aa);
+ aa = aa2;
+ }
+
+ return exitValue;
+}
+
+
+/*-----------------------------------------------------------*/
+/*--- end bzip2.c ---*/
+/*-----------------------------------------------------------*/
diff --git a/Utilities/cmbzip2/bzip2.txt b/Utilities/cmbzip2/bzip2.txt
new file mode 100644
index 000000000..4fb9c7435
--- /dev/null
+++ b/Utilities/cmbzip2/bzip2.txt
@@ -0,0 +1,391 @@
+
+NAME
+ bzip2, bunzip2 - a block-sorting file compressor, v1.0.4
+ bzcat - decompresses files to stdout
+ bzip2recover - recovers data from damaged bzip2 files
+
+
+SYNOPSIS
+ bzip2 [ -cdfkqstvzVL123456789 ] [ filenames ... ]
+ bunzip2 [ -fkvsVL ] [ filenames ... ]
+ bzcat [ -s ] [ filenames ... ]
+ bzip2recover filename
+
+
+DESCRIPTION
+ bzip2 compresses files using the Burrows-Wheeler block
+ sorting text compression algorithm, and Huffman coding.
+ Compression is generally considerably better than that
+ achieved by more conventional LZ77/LZ78-based compressors,
+ and approaches the performance of the PPM family of sta-
+ tistical compressors.
+
+ The command-line options are deliberately very similar to
+ those of GNU gzip, but they are not identical.
+
+ bzip2 expects a list of file names to accompany the com-
+ mand-line flags. Each file is replaced by a compressed
+ version of itself, with the name "original_name.bz2".
+ Each compressed file has the same modification date, per-
+ missions, and, when possible, ownership as the correspond-
+ ing original, so that these properties can be correctly
+ restored at decompression time. File name handling is
+ naive in the sense that there is no mechanism for preserv-
+ ing original file names, permissions, ownerships or dates
+ in filesystems which lack these concepts, or have serious
+ file name length restrictions, such as MS-DOS.
+
+ bzip2 and bunzip2 will by default not overwrite existing
+ files. If you want this to happen, specify the -f flag.
+
+ If no file names are specified, bzip2 compresses from
+ standard input to standard output. In this case, bzip2
+ will decline to write compressed output to a terminal, as
+ this would be entirely incomprehensible and therefore
+ pointless.
+
+ bunzip2 (or bzip2 -d) decompresses all specified files.
+ Files which were not created by bzip2 will be detected and
+ ignored, and a warning issued. bzip2 attempts to guess
+ the filename for the decompressed file from that of the
+ compressed file as follows:
+
+ filename.bz2 becomes filename
+ filename.bz becomes filename
+ filename.tbz2 becomes filename.tar
+ filename.tbz becomes filename.tar
+ anyothername becomes anyothername.out
+
+ If the file does not end in one of the recognised endings,
+ .bz2, .bz, .tbz2 or .tbz, bzip2 complains that it cannot
+ guess the name of the original file, and uses the original
+ name with .out appended.
+
+ As with compression, supplying no filenames causes decom-
+ pression from standard input to standard output.
+
+ bunzip2 will correctly decompress a file which is the con-
+ catenation of two or more compressed files. The result is
+ the concatenation of the corresponding uncompressed files.
+ Integrity testing (-t) of concatenated compressed files is
+ also supported.
+
+ You can also compress or decompress files to the standard
+ output by giving the -c flag. Multiple files may be com-
+ pressed and decompressed like this. The resulting outputs
+ are fed sequentially to stdout. Compression of multiple
+ files in this manner generates a stream containing multi-
+ ple compressed file representations. Such a stream can be
+ decompressed correctly only by bzip2 version 0.9.0 or
+ later. Earlier versions of bzip2 will stop after decom-
+ pressing the first file in the stream.
+
+ bzcat (or bzip2 -dc) decompresses all specified files to
+ the standard output.
+
+ bzip2 will read arguments from the environment variables
+ BZIP2 and BZIP, in that order, and will process them
+ before any arguments read from the command line. This
+ gives a convenient way to supply default arguments.
+
+ Compression is always performed, even if the compressed
+ file is slightly larger than the original. Files of less
+ than about one hundred bytes tend to get larger, since the
+ compression mechanism has a constant overhead in the
+ region of 50 bytes. Random data (including the output of
+ most file compressors) is coded at about 8.05 bits per
+ byte, giving an expansion of around 0.5%.
+
+ As a self-check for your protection, bzip2 uses 32-bit
+ CRCs to make sure that the decompressed version of a file
+ is identical to the original. This guards against corrup-
+ tion of the compressed data, and against undetected bugs
+ in bzip2 (hopefully very unlikely). The chances of data
+ corruption going undetected is microscopic, about one
+ chance in four billion for each file processed. Be aware,
+ though, that the check occurs upon decompression, so it
+ can only tell you that something is wrong. It can't help
+ you recover the original uncompressed data. You can use
+ bzip2recover to try to recover data from damaged files.
+
+ Return values: 0 for a normal exit, 1 for environmental
+ problems (file not found, invalid flags, I/O errors, &c),
+ 2 to indicate a corrupt compressed file, 3 for an internal
+ consistency error (eg, bug) which caused bzip2 to panic.
+
+
+OPTIONS
+ -c --stdout
+ Compress or decompress to standard output.
+
+ -d --decompress
+ Force decompression. bzip2, bunzip2 and bzcat are
+ really the same program, and the decision about
+ what actions to take is done on the basis of which
+ name is used. This flag overrides that mechanism,
+ and forces bzip2 to decompress.
+
+ -z --compress
+ The complement to -d: forces compression,
+ regardless of the invocation name.
+
+ -t --test
+ Check integrity of the specified file(s), but don't
+ decompress them. This really performs a trial
+ decompression and throws away the result.
+
+ -f --force
+ Force overwrite of output files. Normally, bzip2
+ will not overwrite existing output files. Also
+ forces bzip2 to break hard links to files, which it
+ otherwise wouldn't do.
+
+ bzip2 normally declines to decompress files which
+ don't have the correct magic header bytes. If
+ forced (-f), however, it will pass such files
+ through unmodified. This is how GNU gzip behaves.
+
+ -k --keep
+ Keep (don't delete) input files during compression
+ or decompression.
+
+ -s --small
+ Reduce memory usage, for compression, decompression
+ and testing. Files are decompressed and tested
+ using a modified algorithm which only requires 2.5
+ bytes per block byte. This means any file can be
+ decompressed in 2300k of memory, albeit at about
+ half the normal speed.
+
+ During compression, -s selects a block size of
+ 200k, which limits memory use to around the same
+ figure, at the expense of your compression ratio.
+ In short, if your machine is low on memory (8
+ megabytes or less), use -s for everything. See
+ MEMORY MANAGEMENT below.
+
+ -q --quiet
+ Suppress non-essential warning messages. Messages
+ pertaining to I/O errors and other critical events
+ will not be suppressed.
+
+ -v --verbose
+ Verbose mode -- show the compression ratio for each
+ file processed. Further -v's increase the ver-
+ bosity level, spewing out lots of information which
+ is primarily of interest for diagnostic purposes.
+
+ -L --license -V --version
+ Display the software version, license terms and
+ conditions.
+
+ -1 (or --fast) to -9 (or --best)
+ Set the block size to 100 k, 200 k .. 900 k when
+ compressing. Has no effect when decompressing.
+ See MEMORY MANAGEMENT below. The --fast and --best
+ aliases are primarily for GNU gzip compatibility.
+ In particular, --fast doesn't make things signifi-
+ cantly faster. And --best merely selects the
+ default behaviour.
+
+ -- Treats all subsequent arguments as file names, even
+ if they start with a dash. This is so you can han-
+ dle files with names beginning with a dash, for
+ example: bzip2 -- -myfilename.
+
+ --repetitive-fast --repetitive-best
+ These flags are redundant in versions 0.9.5 and
+ above. They provided some coarse control over the
+ behaviour of the sorting algorithm in earlier ver-
+ sions, which was sometimes useful. 0.9.5 and above
+ have an improved algorithm which renders these
+ flags irrelevant.
+
+
+MEMORY MANAGEMENT
+ bzip2 compresses large files in blocks. The block size
+ affects both the compression ratio achieved, and the
+ amount of memory needed for compression and decompression.
+ The flags -1 through -9 specify the block size to be
+ 100,000 bytes through 900,000 bytes (the default) respec-
+ tively. At decompression time, the block size used for
+ compression is read from the header of the compressed
+ file, and bunzip2 then allocates itself just enough memory
+ to decompress the file. Since block sizes are stored in
+ compressed files, it follows that the flags -1 to -9 are
+ irrelevant to and so ignored during decompression.
+
+ Compression and decompression requirements, in bytes, can
+ be estimated as:
+
+ Compression: 400k + ( 8 x block size )
+
+ Decompression: 100k + ( 4 x block size ), or
+ 100k + ( 2.5 x block size )
+
+ Larger block sizes give rapidly diminishing marginal
+ returns. Most of the compression comes from the first two
+ or three hundred k of block size, a fact worth bearing in
+ mind when using bzip2 on small machines. It is also
+ important to appreciate that the decompression memory
+ requirement is set at compression time by the choice of
+ block size.
+
+ For files compressed with the default 900k block size,
+ bunzip2 will require about 3700 kbytes to decompress. To
+ support decompression of any file on a 4 megabyte machine,
+ bunzip2 has an option to decompress using approximately
+ half this amount of memory, about 2300 kbytes. Decompres-
+ sion speed is also halved, so you should use this option
+ only where necessary. The relevant flag is -s.
+
+ In general, try and use the largest block size memory con-
+ straints allow, since that maximises the compression
+ achieved. Compression and decompression speed are virtu-
+ ally unaffected by block size.
+
+ Another significant point applies to files which fit in a
+ single block -- that means most files you'd encounter
+ using a large block size. The amount of real memory
+ touched is proportional to the size of the file, since the
+ file is smaller than a block. For example, compressing a
+ file 20,000 bytes long with the flag -9 will cause the
+ compressor to allocate around 7600k of memory, but only
+ touch 400k + 20000 * 8 = 560 kbytes of it. Similarly, the
+ decompressor will allocate 3700k but only touch 100k +
+ 20000 * 4 = 180 kbytes.
+
+ Here is a table which summarises the maximum memory usage
+ for different block sizes. Also recorded is the total
+ compressed size for 14 files of the Calgary Text Compres-
+ sion Corpus totalling 3,141,622 bytes. This column gives
+ some feel for how compression varies with block size.
+ These figures tend to understate the advantage of larger
+ block sizes for larger files, since the Corpus is domi-
+ nated by smaller files.
+
+ Compress Decompress Decompress Corpus
+ Flag usage usage -s usage Size
+
+ -1 1200k 500k 350k 914704
+ -2 2000k 900k 600k 877703
+ -3 2800k 1300k 850k 860338
+ -4 3600k 1700k 1100k 846899
+ -5 4400k 2100k 1350k 845160
+ -6 5200k 2500k 1600k 838626
+ -7 6100k 2900k 1850k 834096
+ -8 6800k 3300k 2100k 828642
+ -9 7600k 3700k 2350k 828642
+
+
+RECOVERING DATA FROM DAMAGED FILES
+ bzip2 compresses files in blocks, usually 900kbytes long.
+ Each block is handled independently. If a media or trans-
+ mission error causes a multi-block .bz2 file to become
+ damaged, it may be possible to recover data from the
+ undamaged blocks in the file.
+
+ The compressed representation of each block is delimited
+ by a 48-bit pattern, which makes it possible to find the
+ block boundaries with reasonable certainty. Each block
+ also carries its own 32-bit CRC, so damaged blocks can be
+ distinguished from undamaged ones.
+
+ bzip2recover is a simple program whose purpose is to
+ search for blocks in .bz2 files, and write each block out
+ into its own .bz2 file. You can then use bzip2 -t to test
+ the integrity of the resulting files, and decompress those
+ which are undamaged.
+
+ bzip2recover takes a single argument, the name of the dam-
+ aged file, and writes a number of files
+ "rec00001file.bz2", "rec00002file.bz2", etc, containing
+ the extracted blocks. The output filenames are
+ designed so that the use of wildcards in subsequent pro-
+ cessing -- for example, "bzip2 -dc rec*file.bz2 > recov-
+ ered_data" -- processes the files in the correct order.
+
+ bzip2recover should be of most use dealing with large .bz2
+ files, as these will contain many blocks. It is clearly
+ futile to use it on damaged single-block files, since a
+ damaged block cannot be recovered. If you wish to min-
+ imise any potential data loss through media or transmis-
+ sion errors, you might consider compressing with a smaller
+ block size.
+
+
+PERFORMANCE NOTES
+ The sorting phase of compression gathers together similar
+ strings in the file. Because of this, files containing
+ very long runs of repeated symbols, like "aabaabaabaab
+ ..." (repeated several hundred times) may compress more
+ slowly than normal. Versions 0.9.5 and above fare much
+ better than previous versions in this respect. The ratio
+ between worst-case and average-case compression time is in
+ the region of 10:1. For previous versions, this figure
+ was more like 100:1. You can use the -vvvv option to mon-
+ itor progress in great detail, if you want.
+
+ Decompression speed is unaffected by these phenomena.
+
+ bzip2 usually allocates several megabytes of memory to
+ operate in, and then charges all over it in a fairly ran-
+ dom fashion. This means that performance, both for com-
+ pressing and decompressing, is largely determined by the
+ speed at which your machine can service cache misses.
+ Because of this, small changes to the code to reduce the
+ miss rate have been observed to give disproportionately
+ large performance improvements. I imagine bzip2 will per-
+ form best on machines with very large caches.
+
+
+CAVEATS
+ I/O error messages are not as helpful as they could be.
+ bzip2 tries hard to detect I/O errors and exit cleanly,
+ but the details of what the problem is sometimes seem
+ rather misleading.
+
+ This manual page pertains to version 1.0.4 of bzip2. Com-
+ pressed data created by this version is entirely forwards
+ and backwards compatible with the previous public
+ releases, versions 0.1pl2, 0.9.0, 0.9.5, 1.0.0, 1.0.1,
+ 1.0.2 and 1.0.3, but with the following exception: 0.9.0
+ and above can correctly decompress multiple concatenated
+ compressed files. 0.1pl2 cannot do this; it will stop
+ after decompressing just the first file in the stream.
+
+ bzip2recover versions prior to 1.0.2 used 32-bit integers
+ to represent bit positions in compressed files, so they
+ could not handle compressed files more than 512 megabytes
+ long. Versions 1.0.2 and above use 64-bit ints on some
+ platforms which support them (GNU supported targets, and
+ Windows). To establish whether or not bzip2recover was
+ built with such a limitation, run it without arguments.
+ In any event you can build yourself an unlimited version
+ if you can recompile it with MaybeUInt64 set to be an
+ unsigned 64-bit integer.
+
+
+AUTHOR
+ Julian Seward, jsewardbzip.org.
+
+ http://www.bzip.org
+
+ The ideas embodied in bzip2 are due to (at least) the fol-
+ lowing people: Michael Burrows and David Wheeler (for the
+ block sorting transformation), David Wheeler (again, for
+ the Huffman coder), Peter Fenwick (for the structured cod-
+ ing model in the original bzip, and many refinements), and
+ Alistair Moffat, Radford Neal and Ian Witten (for the
+ arithmetic coder in the original bzip). I am much
+ indebted for their help, support and advice. See the man-
+ ual in the source distribution for pointers to sources of
+ documentation. Christian von Roques encouraged me to look
+ for faster sorting algorithms, so as to speed up compres-
+ sion. Bela Lubkin encouraged me to improve the worst-case
+ compression performance. Donna Robinson XMLised the docu-
+ mentation. The bz* scripts are derived from those of GNU
+ gzip. Many people sent patches, helped with portability
+ problems, lent machines, gave advice and were generally
+ helpful.
+
diff --git a/Utilities/cmbzip2/bzip2recover.c b/Utilities/cmbzip2/bzip2recover.c
new file mode 100644
index 000000000..6e47b603b
--- /dev/null
+++ b/Utilities/cmbzip2/bzip2recover.c
@@ -0,0 +1,514 @@
+/*-----------------------------------------------------------*/
+/*--- Block recoverer program for bzip2 ---*/
+/*--- bzip2recover.c ---*/
+/*-----------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
+
+ bzip2/libbzip2 version 1.0.5 of 10 December 2007
+ Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
+
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------ */
+
+/* This program is a complete hack and should be rewritten properly.
+ It isn't very complicated. */
+
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+/* This program records bit locations in the file to be recovered.
+ That means that if 64-bit ints are not supported, we will not
+ be able to recover .bz2 files over 512MB (2^32 bits) long.
+ On GNU supported platforms, we take advantage of the 64-bit
+ int support to circumvent this problem. Ditto MSVC.
+
+ This change occurred in version 1.0.2; all prior versions have
+ the 512MB limitation.
+*/
+#ifdef __GNUC__
+ typedef unsigned long long int MaybeUInt64;
+# define MaybeUInt64_FMT "%Lu"
+#else
+#ifdef _MSC_VER
+ typedef unsigned __int64 MaybeUInt64;
+# define MaybeUInt64_FMT "%I64u"
+#else
+ typedef unsigned int MaybeUInt64;
+# define MaybeUInt64_FMT "%u"
+#endif
+#endif
+
+typedef unsigned int UInt32;
+typedef int Int32;
+typedef unsigned char UChar;
+typedef char Char;
+typedef unsigned char Bool;
+#define True ((Bool)1)
+#define False ((Bool)0)
+
+
+#define BZ_MAX_FILENAME 2000
+
+Char inFileName[BZ_MAX_FILENAME];
+Char outFileName[BZ_MAX_FILENAME];
+Char progName[BZ_MAX_FILENAME];
+
+MaybeUInt64 bytesOut = 0;
+MaybeUInt64 bytesIn = 0;
+
+
+/*---------------------------------------------------*/
+/*--- Header bytes ---*/
+/*---------------------------------------------------*/
+
+#define BZ_HDR_B 0x42 /* 'B' */
+#define BZ_HDR_Z 0x5a /* 'Z' */
+#define BZ_HDR_h 0x68 /* 'h' */
+#define BZ_HDR_0 0x30 /* '0' */
+
+
+/*---------------------------------------------------*/
+/*--- I/O errors ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------*/
+static void readError ( void )
+{
+ fprintf ( stderr,
+ "%s: I/O error reading `%s', possible reason follows.\n",
+ progName, inFileName );
+ perror ( progName );
+ fprintf ( stderr, "%s: warning: output file(s) may be incomplete.\n",
+ progName );
+ exit ( 1 );
+}
+
+
+/*---------------------------------------------*/
+static void writeError ( void )
+{
+ fprintf ( stderr,
+ "%s: I/O error reading `%s', possible reason follows.\n",
+ progName, inFileName );
+ perror ( progName );
+ fprintf ( stderr, "%s: warning: output file(s) may be incomplete.\n",
+ progName );
+ exit ( 1 );
+}
+
+
+/*---------------------------------------------*/
+static void mallocFail ( Int32 n )
+{
+ fprintf ( stderr,
+ "%s: malloc failed on request for %d bytes.\n",
+ progName, n );
+ fprintf ( stderr, "%s: warning: output file(s) may be incomplete.\n",
+ progName );
+ exit ( 1 );
+}
+
+
+/*---------------------------------------------*/
+static void tooManyBlocks ( Int32 max_handled_blocks )
+{
+ fprintf ( stderr,
+ "%s: `%s' appears to contain more than %d blocks\n",
+ progName, inFileName, max_handled_blocks );
+ fprintf ( stderr,
+ "%s: and cannot be handled. To fix, increase\n",
+ progName );
+ fprintf ( stderr,
+ "%s: BZ_MAX_HANDLED_BLOCKS in bzip2recover.c, and recompile.\n",
+ progName );
+ exit ( 1 );
+}
+
+
+
+/*---------------------------------------------------*/
+/*--- Bit stream I/O ---*/
+/*---------------------------------------------------*/
+
+typedef
+ struct {
+ FILE* handle;
+ Int32 buffer;
+ Int32 buffLive;
+ Char mode;
+ }
+ BitStream;
+
+
+/*---------------------------------------------*/
+static BitStream* bsOpenReadStream ( FILE* stream )
+{
+ BitStream *bs = malloc ( sizeof(BitStream) );
+ if (bs == NULL) mallocFail ( sizeof(BitStream) );
+ bs->handle = stream;
+ bs->buffer = 0;
+ bs->buffLive = 0;
+ bs->mode = 'r';
+ return bs;
+}
+
+
+/*---------------------------------------------*/
+static BitStream* bsOpenWriteStream ( FILE* stream )
+{
+ BitStream *bs = malloc ( sizeof(BitStream) );
+ if (bs == NULL) mallocFail ( sizeof(BitStream) );
+ bs->handle = stream;
+ bs->buffer = 0;
+ bs->buffLive = 0;
+ bs->mode = 'w';
+ return bs;
+}
+
+
+/*---------------------------------------------*/
+static void bsPutBit ( BitStream* bs, Int32 bit )
+{
+ if (bs->buffLive == 8) {
+ Int32 retVal = putc ( (UChar) bs->buffer, bs->handle );
+ if (retVal == EOF) writeError();
+ bytesOut++;
+ bs->buffLive = 1;
+ bs->buffer = bit & 0x1;
+ } else {
+ bs->buffer = ( (bs->buffer << 1) | (bit & 0x1) );
+ bs->buffLive++;
+ };
+}
+
+
+/*---------------------------------------------*/
+/*--
+ Returns 0 or 1, or 2 to indicate EOF.
+--*/
+static Int32 bsGetBit ( BitStream* bs )
+{
+ if (bs->buffLive > 0) {
+ bs->buffLive --;
+ return ( ((bs->buffer) >> (bs->buffLive)) & 0x1 );
+ } else {
+ Int32 retVal = getc ( bs->handle );
+ if ( retVal == EOF ) {
+ if (errno != 0) readError();
+ return 2;
+ }
+ bs->buffLive = 7;
+ bs->buffer = retVal;
+ return ( ((bs->buffer) >> 7) & 0x1 );
+ }
+}
+
+
+/*---------------------------------------------*/
+static void bsClose ( BitStream* bs )
+{
+ Int32 retVal;
+
+ if ( bs->mode == 'w' ) {
+ while ( bs->buffLive < 8 ) {
+ bs->buffLive++;
+ bs->buffer <<= 1;
+ };
+ retVal = putc ( (UChar) (bs->buffer), bs->handle );
+ if (retVal == EOF) writeError();
+ bytesOut++;
+ retVal = fflush ( bs->handle );
+ if (retVal == EOF) writeError();
+ }
+ retVal = fclose ( bs->handle );
+ if (retVal == EOF) {
+ if (bs->mode == 'w') writeError(); else readError();
+ }
+ free ( bs );
+}
+
+
+/*---------------------------------------------*/
+static void bsPutUChar ( BitStream* bs, UChar c )
+{
+ Int32 i;
+ for (i = 7; i >= 0; i--)
+ bsPutBit ( bs, (((UInt32) c) >> i) & 0x1 );
+}
+
+
+/*---------------------------------------------*/
+static void bsPutUInt32 ( BitStream* bs, UInt32 c )
+{
+ Int32 i;
+
+ for (i = 31; i >= 0; i--)
+ bsPutBit ( bs, (c >> i) & 0x1 );
+}
+
+
+/*---------------------------------------------*/
+static Bool endsInBz2 ( Char* name )
+{
+ Int32 n = strlen ( name );
+ if (n <= 4) return False;
+ return
+ (name[n-4] == '.' &&
+ name[n-3] == 'b' &&
+ name[n-2] == 'z' &&
+ name[n-1] == '2');
+}
+
+
+/*---------------------------------------------------*/
+/*--- ---*/
+/*---------------------------------------------------*/
+
+/* This logic isn't really right when it comes to Cygwin. */
+#ifdef _WIN32
+# define BZ_SPLIT_SYM '\\' /* path splitter on Windows platform */
+#else
+# define BZ_SPLIT_SYM '/' /* path splitter on Unix platform */
+#endif
+
+#define BLOCK_HEADER_HI 0x00003141UL
+#define BLOCK_HEADER_LO 0x59265359UL
+
+#define BLOCK_ENDMARK_HI 0x00001772UL
+#define BLOCK_ENDMARK_LO 0x45385090UL
+
+/* Increase if necessary. However, a .bz2 file with > 50000 blocks
+ would have an uncompressed size of at least 40GB, so the chances
+ are low you'll need to up this.
+*/
+#define BZ_MAX_HANDLED_BLOCKS 50000
+
+MaybeUInt64 bStart [BZ_MAX_HANDLED_BLOCKS];
+MaybeUInt64 bEnd [BZ_MAX_HANDLED_BLOCKS];
+MaybeUInt64 rbStart[BZ_MAX_HANDLED_BLOCKS];
+MaybeUInt64 rbEnd [BZ_MAX_HANDLED_BLOCKS];
+
+Int32 main ( Int32 argc, Char** argv )
+{
+ FILE* inFile;
+ FILE* outFile;
+ BitStream* bsIn, *bsWr;
+ Int32 b, wrBlock, currBlock, rbCtr;
+ MaybeUInt64 bitsRead;
+
+ UInt32 buffHi, buffLo, blockCRC;
+ Char* p;
+
+ strcpy ( progName, argv[0] );
+ inFileName[0] = outFileName[0] = 0;
+
+ fprintf ( stderr,
+ "bzip2recover 1.0.5: extracts blocks from damaged .bz2 files.\n" );
+
+ if (argc != 2) {
+ fprintf ( stderr, "%s: usage is `%s damaged_file_name'.\n",
+ progName, progName );
+ switch (sizeof(MaybeUInt64)) {
+ case 8:
+ fprintf(stderr,
+ "\trestrictions on size of recovered file: None\n");
+ break;
+ case 4:
+ fprintf(stderr,
+ "\trestrictions on size of recovered file: 512 MB\n");
+ fprintf(stderr,
+ "\tto circumvent, recompile with MaybeUInt64 as an\n"
+ "\tunsigned 64-bit int.\n");
+ break;
+ default:
+ fprintf(stderr,
+ "\tsizeof(MaybeUInt64) is not 4 or 8 -- "
+ "configuration error.\n");
+ break;
+ }
+ exit(1);
+ }
+
+ if (strlen(argv[1]) >= BZ_MAX_FILENAME-20) {
+ fprintf ( stderr,
+ "%s: supplied filename is suspiciously (>= %d chars) long. Bye!\n",
+ progName, (int)strlen(argv[1]) );
+ exit(1);
+ }
+
+ strcpy ( inFileName, argv[1] );
+
+ inFile = fopen ( inFileName, "rb" );
+ if (inFile == NULL) {
+ fprintf ( stderr, "%s: can't read `%s'\n", progName, inFileName );
+ exit(1);
+ }
+
+ bsIn = bsOpenReadStream ( inFile );
+ fprintf ( stderr, "%s: searching for block boundaries ...\n", progName );
+
+ bitsRead = 0;
+ buffHi = buffLo = 0;
+ currBlock = 0;
+ bStart[currBlock] = 0;
+
+ rbCtr = 0;
+
+ while (True) {
+ b = bsGetBit ( bsIn );
+ bitsRead++;
+ if (b == 2) {
+ if (bitsRead >= bStart[currBlock] &&
+ (bitsRead - bStart[currBlock]) >= 40) {
+ bEnd[currBlock] = bitsRead-1;
+ if (currBlock > 0)
+ fprintf ( stderr, " block %d runs from " MaybeUInt64_FMT
+ " to " MaybeUInt64_FMT " (incomplete)\n",
+ currBlock, bStart[currBlock], bEnd[currBlock] );
+ } else
+ currBlock--;
+ break;
+ }
+ buffHi = (buffHi << 1) | (buffLo >> 31);
+ buffLo = (buffLo << 1) | (b & 1);
+ if ( ( (buffHi & 0x0000ffff) == BLOCK_HEADER_HI
+ && buffLo == BLOCK_HEADER_LO)
+ ||
+ ( (buffHi & 0x0000ffff) == BLOCK_ENDMARK_HI
+ && buffLo == BLOCK_ENDMARK_LO)
+ ) {
+ if (bitsRead > 49) {
+ bEnd[currBlock] = bitsRead-49;
+ } else {
+ bEnd[currBlock] = 0;
+ }
+ if (currBlock > 0 &&
+ (bEnd[currBlock] - bStart[currBlock]) >= 130) {
+ fprintf ( stderr, " block %d runs from " MaybeUInt64_FMT
+ " to " MaybeUInt64_FMT "\n",
+ rbCtr+1, bStart[currBlock], bEnd[currBlock] );
+ rbStart[rbCtr] = bStart[currBlock];
+ rbEnd[rbCtr] = bEnd[currBlock];
+ rbCtr++;
+ }
+ if (currBlock >= BZ_MAX_HANDLED_BLOCKS)
+ tooManyBlocks(BZ_MAX_HANDLED_BLOCKS);
+ currBlock++;
+
+ bStart[currBlock] = bitsRead;
+ }
+ }
+
+ bsClose ( bsIn );
+
+ /*-- identified blocks run from 1 to rbCtr inclusive. --*/
+
+ if (rbCtr < 1) {
+ fprintf ( stderr,
+ "%s: sorry, I couldn't find any block boundaries.\n",
+ progName );
+ exit(1);
+ };
+
+ fprintf ( stderr, "%s: splitting into blocks\n", progName );
+
+ inFile = fopen ( inFileName, "rb" );
+ if (inFile == NULL) {
+ fprintf ( stderr, "%s: can't open `%s'\n", progName, inFileName );
+ exit(1);
+ }
+ bsIn = bsOpenReadStream ( inFile );
+
+ /*-- placate gcc's dataflow analyser --*/
+ blockCRC = 0; bsWr = 0;
+
+ bitsRead = 0;
+ outFile = NULL;
+ wrBlock = 0;
+ while (True) {
+ b = bsGetBit(bsIn);
+ if (b == 2) break;
+ buffHi = (buffHi << 1) | (buffLo >> 31);
+ buffLo = (buffLo << 1) | (b & 1);
+ if (bitsRead == 47+rbStart[wrBlock])
+ blockCRC = (buffHi << 16) | (buffLo >> 16);
+
+ if (outFile != NULL && bitsRead >= rbStart[wrBlock]
+ && bitsRead <= rbEnd[wrBlock]) {
+ bsPutBit ( bsWr, b );
+ }
+
+ bitsRead++;
+
+ if (bitsRead == rbEnd[wrBlock]+1) {
+ if (outFile != NULL) {
+ bsPutUChar ( bsWr, 0x17 ); bsPutUChar ( bsWr, 0x72 );
+ bsPutUChar ( bsWr, 0x45 ); bsPutUChar ( bsWr, 0x38 );
+ bsPutUChar ( bsWr, 0x50 ); bsPutUChar ( bsWr, 0x90 );
+ bsPutUInt32 ( bsWr, blockCRC );
+ bsClose ( bsWr );
+ }
+ if (wrBlock >= rbCtr) break;
+ wrBlock++;
+ } else
+ if (bitsRead == rbStart[wrBlock]) {
+ /* Create the output file name, correctly handling leading paths.
+ (31.10.2001 by Sergey E. Kusikov) */
+ Char* split;
+ Int32 ofs, k;
+ for (k = 0; k < BZ_MAX_FILENAME; k++)
+ outFileName[k] = 0;
+ strcpy (outFileName, inFileName);
+ split = strrchr (outFileName, BZ_SPLIT_SYM);
+ if (split == NULL) {
+ split = outFileName;
+ } else {
+ ++split;
+ }
+ /* Now split points to the start of the basename. */
+ ofs = split - outFileName;
+ sprintf (split, "rec%5d", wrBlock+1);
+ for (p = split; *p != 0; p++) if (*p == ' ') *p = '0';
+ strcat (outFileName, inFileName + ofs);
+
+ if ( !endsInBz2(outFileName)) strcat ( outFileName, ".bz2" );
+
+ fprintf ( stderr, " writing block %d to `%s' ...\n",
+ wrBlock+1, outFileName );
+
+ outFile = fopen ( outFileName, "wb" );
+ if (outFile == NULL) {
+ fprintf ( stderr, "%s: can't write `%s'\n",
+ progName, outFileName );
+ exit(1);
+ }
+ bsWr = bsOpenWriteStream ( outFile );
+ bsPutUChar ( bsWr, BZ_HDR_B );
+ bsPutUChar ( bsWr, BZ_HDR_Z );
+ bsPutUChar ( bsWr, BZ_HDR_h );
+ bsPutUChar ( bsWr, BZ_HDR_0 + 9 );
+ bsPutUChar ( bsWr, 0x31 ); bsPutUChar ( bsWr, 0x41 );
+ bsPutUChar ( bsWr, 0x59 ); bsPutUChar ( bsWr, 0x26 );
+ bsPutUChar ( bsWr, 0x53 ); bsPutUChar ( bsWr, 0x59 );
+ }
+ }
+
+ fprintf ( stderr, "%s: finished\n", progName );
+ return 0;
+}
+
+
+
+/*-----------------------------------------------------------*/
+/*--- end bzip2recover.c ---*/
+/*-----------------------------------------------------------*/
diff --git a/Utilities/cmbzip2/bzlib.c b/Utilities/cmbzip2/bzlib.c
new file mode 100644
index 000000000..aeecef10f
--- /dev/null
+++ b/Utilities/cmbzip2/bzlib.c
@@ -0,0 +1,1575 @@
+
+/*-------------------------------------------------------------*/
+/*--- Library top-level functions. ---*/
+/*--- bzlib.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
+
+ bzip2/libbzip2 version 1.0.5 of 10 December 2007
+ Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
+
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------ */
+
+/* CHANGES
+ 0.9.0 -- original version.
+ 0.9.0a/b -- no changes in this file.
+ 0.9.0c -- made zero-length BZ_FLUSH work correctly in bzCompress().
+ fixed bzWrite/bzRead to ignore zero-length requests.
+ fixed bzread to correctly handle read requests after EOF.
+ wrong parameter order in call to bzDecompressInit in
+ bzBuffToBuffDecompress. Fixed.
+*/
+
+#include "bzlib_private.h"
+
+
+/*---------------------------------------------------*/
+/*--- Compression stuff ---*/
+/*---------------------------------------------------*/
+
+
+/*---------------------------------------------------*/
+#ifndef BZ_NO_STDIO
+void BZ2_bz__AssertH__fail ( int errcode )
+{
+ fprintf(stderr,
+ "\n\nbzip2/libbzip2: internal error number %d.\n"
+ "This is a bug in bzip2/libbzip2, %s.\n"
+ "Please report it to me at: jseward@bzip.org. If this happened\n"
+ "when you were using some program which uses libbzip2 as a\n"
+ "component, you should also report this bug to the author(s)\n"
+ "of that program. Please make an effort to report this bug;\n"
+ "timely and accurate bug reports eventually lead to higher\n"
+ "quality software. Thanks. Julian Seward, 10 December 2007.\n\n",
+ errcode,
+ BZ2_bzlibVersion()
+ );
+
+ if (errcode == 1007) {
+ fprintf(stderr,
+ "\n*** A special note about internal error number 1007 ***\n"
+ "\n"
+ "Experience suggests that a common cause of i.e. 1007\n"
+ "is unreliable memory or other hardware. The 1007 assertion\n"
+ "just happens to cross-check the results of huge numbers of\n"
+ "memory reads/writes, and so acts (unintendedly) as a stress\n"
+ "test of your memory system.\n"
+ "\n"
+ "I suggest the following: try compressing the file again,\n"
+ "possibly monitoring progress in detail with the -vv flag.\n"
+ "\n"
+ "* If the error cannot be reproduced, and/or happens at different\n"
+ " points in compression, you may have a flaky memory system.\n"
+ " Try a memory-test program. I have used Memtest86\n"
+ " (www.memtest86.com). At the time of writing it is free (GPLd).\n"
+ " Memtest86 tests memory much more thorougly than your BIOSs\n"
+ " power-on test, and may find failures that the BIOS doesn't.\n"
+ "\n"
+ "* If the error can be repeatably reproduced, this is a bug in\n"
+ " bzip2, and I would very much like to hear about it. Please\n"
+ " let me know, and, ideally, save a copy of the file causing the\n"
+ " problem -- without which I will be unable to investigate it.\n"
+ "\n"
+ );
+ }
+
+ exit(3);
+}
+#endif
+
+
+/*---------------------------------------------------*/
+static
+int bz_config_ok ( void )
+{
+ if (sizeof(int) != 4) return 0;
+ if (sizeof(short) != 2) return 0;
+ if (sizeof(char) != 1) return 0;
+ return 1;
+}
+
+
+/*---------------------------------------------------*/
+static
+void* default_bzalloc ( void* opaque, Int32 items, Int32 size )
+{
+ void* v = malloc ( items * size );
+ (void)opaque;
+ return v;
+}
+
+static
+void default_bzfree ( void* opaque, void* addr )
+{
+ if (addr != NULL) free ( addr );
+ (void)opaque;
+}
+
+
+/*---------------------------------------------------*/
+static
+void prepare_new_block ( EState* s )
+{
+ Int32 i;
+ s->nblock = 0;
+ s->numZ = 0;
+ s->state_out_pos = 0;
+ BZ_INITIALISE_CRC ( s->blockCRC );
+ for (i = 0; i < 256; i++) s->inUse[i] = False;
+ s->blockNo++;
+}
+
+
+/*---------------------------------------------------*/
+static
+void init_RL ( EState* s )
+{
+ s->state_in_ch = 256;
+ s->state_in_len = 0;
+}
+
+
+static
+Bool isempty_RL ( EState* s )
+{
+ if (s->state_in_ch < 256 && s->state_in_len > 0)
+ return False; else
+ return True;
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzCompressInit)
+ ( bz_stream* strm,
+ int blockSize100k,
+ int verbosity,
+ int workFactor )
+{
+ Int32 n;
+ EState* s;
+
+ if (!bz_config_ok()) return BZ_CONFIG_ERROR;
+
+ if (strm == NULL ||
+ blockSize100k < 1 || blockSize100k > 9 ||
+ workFactor < 0 || workFactor > 250)
+ return BZ_PARAM_ERROR;
+
+ if (workFactor == 0) workFactor = 30;
+ if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
+ if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
+
+ s = BZALLOC( sizeof(EState) );
+ if (s == NULL) return BZ_MEM_ERROR;
+ s->strm = strm;
+
+ s->arr1 = NULL;
+ s->arr2 = NULL;
+ s->ftab = NULL;
+
+ n = 100000 * blockSize100k;
+ s->arr1 = BZALLOC( n * sizeof(UInt32) );
+ s->arr2 = BZALLOC( (n+BZ_N_OVERSHOOT) * sizeof(UInt32) );
+ s->ftab = BZALLOC( 65537 * sizeof(UInt32) );
+
+ if (s->arr1 == NULL || s->arr2 == NULL || s->ftab == NULL) {
+ if (s->arr1 != NULL) BZFREE(s->arr1);
+ if (s->arr2 != NULL) BZFREE(s->arr2);
+ if (s->ftab != NULL) BZFREE(s->ftab);
+ if (s != NULL) BZFREE(s);
+ return BZ_MEM_ERROR;
+ }
+
+ s->blockNo = 0;
+ s->state = BZ_S_INPUT;
+ s->mode = BZ_M_RUNNING;
+ s->combinedCRC = 0;
+ s->blockSize100k = blockSize100k;
+ s->nblockMAX = 100000 * blockSize100k - 19;
+ s->verbosity = verbosity;
+ s->workFactor = workFactor;
+
+ s->block = (UChar*)s->arr2;
+ s->mtfv = (UInt16*)s->arr1;
+ s->zbits = NULL;
+ s->ptr = (UInt32*)s->arr1;
+
+ strm->state = s;
+ strm->total_in_lo32 = 0;
+ strm->total_in_hi32 = 0;
+ strm->total_out_lo32 = 0;
+ strm->total_out_hi32 = 0;
+ init_RL ( s );
+ prepare_new_block ( s );
+ return BZ_OK;
+}
+
+
+/*---------------------------------------------------*/
+static
+void add_pair_to_block ( EState* s )
+{
+ Int32 i;
+ UChar ch = (UChar)(s->state_in_ch);
+ for (i = 0; i < s->state_in_len; i++) {
+ BZ_UPDATE_CRC( s->blockCRC, ch );
+ }
+ s->inUse[s->state_in_ch] = True;
+ switch (s->state_in_len) {
+ case 1:
+ s->block[s->nblock] = (UChar)ch; s->nblock++;
+ break;
+ case 2:
+ s->block[s->nblock] = (UChar)ch; s->nblock++;
+ s->block[s->nblock] = (UChar)ch; s->nblock++;
+ break;
+ case 3:
+ s->block[s->nblock] = (UChar)ch; s->nblock++;
+ s->block[s->nblock] = (UChar)ch; s->nblock++;
+ s->block[s->nblock] = (UChar)ch; s->nblock++;
+ break;
+ default:
+ s->inUse[s->state_in_len-4] = True;
+ s->block[s->nblock] = (UChar)ch; s->nblock++;
+ s->block[s->nblock] = (UChar)ch; s->nblock++;
+ s->block[s->nblock] = (UChar)ch; s->nblock++;
+ s->block[s->nblock] = (UChar)ch; s->nblock++;
+ s->block[s->nblock] = ((UChar)(s->state_in_len-4));
+ s->nblock++;
+ break;
+ }
+}
+
+
+/*---------------------------------------------------*/
+static
+void flush_RL ( EState* s )
+{
+ if (s->state_in_ch < 256) add_pair_to_block ( s );
+ init_RL ( s );
+}
+
+
+/*---------------------------------------------------*/
+#define ADD_CHAR_TO_BLOCK(zs,zchh0) \
+{ \
+ UInt32 zchh = (UInt32)(zchh0); \
+ /*-- fast track the common case --*/ \
+ if (zchh != zs->state_in_ch && \
+ zs->state_in_len == 1) { \
+ UChar ch = (UChar)(zs->state_in_ch); \
+ BZ_UPDATE_CRC( zs->blockCRC, ch ); \
+ zs->inUse[zs->state_in_ch] = True; \
+ zs->block[zs->nblock] = (UChar)ch; \
+ zs->nblock++; \
+ zs->state_in_ch = zchh; \
+ } \
+ else \
+ /*-- general, uncommon cases --*/ \
+ if (zchh != zs->state_in_ch || \
+ zs->state_in_len == 255) { \
+ if (zs->state_in_ch < 256) \
+ add_pair_to_block ( zs ); \
+ zs->state_in_ch = zchh; \
+ zs->state_in_len = 1; \
+ } else { \
+ zs->state_in_len++; \
+ } \
+}
+
+
+/*---------------------------------------------------*/
+static
+Bool copy_input_until_stop ( EState* s )
+{
+ Bool progress_in = False;
+
+ if (s->mode == BZ_M_RUNNING) {
+
+ /*-- fast track the common case --*/
+ while (True) {
+ /*-- block full? --*/
+ if (s->nblock >= s->nblockMAX) break;
+ /*-- no input? --*/
+ if (s->strm->avail_in == 0) break;
+ progress_in = True;
+ ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
+ s->strm->next_in++;
+ s->strm->avail_in--;
+ s->strm->total_in_lo32++;
+ if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
+ }
+
+ } else {
+
+ /*-- general, uncommon case --*/
+ while (True) {
+ /*-- block full? --*/
+ if (s->nblock >= s->nblockMAX) break;
+ /*-- no input? --*/
+ if (s->strm->avail_in == 0) break;
+ /*-- flush/finish end? --*/
+ if (s->avail_in_expect == 0) break;
+ progress_in = True;
+ ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
+ s->strm->next_in++;
+ s->strm->avail_in--;
+ s->strm->total_in_lo32++;
+ if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
+ s->avail_in_expect--;
+ }
+ }
+ return progress_in;
+}
+
+
+/*---------------------------------------------------*/
+static
+Bool copy_output_until_stop ( EState* s )
+{
+ Bool progress_out = False;
+
+ while (True) {
+
+ /*-- no output space? --*/
+ if (s->strm->avail_out == 0) break;
+
+ /*-- block done? --*/
+ if (s->state_out_pos >= s->numZ) break;
+
+ progress_out = True;
+ *(s->strm->next_out) = s->zbits[s->state_out_pos];
+ s->state_out_pos++;
+ s->strm->avail_out--;
+ s->strm->next_out++;
+ s->strm->total_out_lo32++;
+ if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
+ }
+
+ return progress_out;
+}
+
+
+/*---------------------------------------------------*/
+static
+Bool handle_compress ( bz_stream* strm )
+{
+ Bool progress_in = False;
+ Bool progress_out = False;
+ EState* s = strm->state;
+
+ while (True) {
+
+ if (s->state == BZ_S_OUTPUT) {
+ progress_out |= copy_output_until_stop ( s );
+ if (s->state_out_pos < s->numZ) break;
+ if (s->mode == BZ_M_FINISHING &&
+ s->avail_in_expect == 0 &&
+ isempty_RL(s)) break;
+ prepare_new_block ( s );
+ s->state = BZ_S_INPUT;
+ if (s->mode == BZ_M_FLUSHING &&
+ s->avail_in_expect == 0 &&
+ isempty_RL(s)) break;
+ }
+
+ if (s->state == BZ_S_INPUT) {
+ progress_in |= copy_input_until_stop ( s );
+ if (s->mode != BZ_M_RUNNING && s->avail_in_expect == 0) {
+ flush_RL ( s );
+ BZ2_compressBlock ( s, (Bool)(s->mode == BZ_M_FINISHING) );
+ s->state = BZ_S_OUTPUT;
+ }
+ else
+ if (s->nblock >= s->nblockMAX) {
+ BZ2_compressBlock ( s, False );
+ s->state = BZ_S_OUTPUT;
+ }
+ else
+ if (s->strm->avail_in == 0) {
+ break;
+ }
+ }
+
+ }
+
+ return progress_in || progress_out;
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action )
+{
+ Bool progress;
+ EState* s;
+ if (strm == NULL) return BZ_PARAM_ERROR;
+ s = strm->state;
+ if (s == NULL) return BZ_PARAM_ERROR;
+ if (s->strm != strm) return BZ_PARAM_ERROR;
+
+ preswitch:
+ switch (s->mode) {
+
+ case BZ_M_IDLE:
+ return BZ_SEQUENCE_ERROR;
+
+ case BZ_M_RUNNING:
+ if (action == BZ_RUN) {
+ progress = handle_compress ( strm );
+ return progress ? BZ_RUN_OK : BZ_PARAM_ERROR;
+ }
+ else
+ if (action == BZ_FLUSH) {
+ s->avail_in_expect = strm->avail_in;
+ s->mode = BZ_M_FLUSHING;
+ goto preswitch;
+ }
+ else
+ if (action == BZ_FINISH) {
+ s->avail_in_expect = strm->avail_in;
+ s->mode = BZ_M_FINISHING;
+ goto preswitch;
+ }
+ else
+ return BZ_PARAM_ERROR;
+
+ case BZ_M_FLUSHING:
+ if (action != BZ_FLUSH) return BZ_SEQUENCE_ERROR;
+ if (s->avail_in_expect != s->strm->avail_in)
+ return BZ_SEQUENCE_ERROR;
+ progress = handle_compress ( strm );
+ if (s->avail_in_expect > 0 || !isempty_RL(s) ||
+ s->state_out_pos < s->numZ) return BZ_FLUSH_OK;
+ s->mode = BZ_M_RUNNING;
+ return BZ_RUN_OK;
+
+ case BZ_M_FINISHING:
+ if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR;
+ if (s->avail_in_expect != s->strm->avail_in)
+ return BZ_SEQUENCE_ERROR;
+ progress = handle_compress ( strm );
+ if (!progress) return BZ_SEQUENCE_ERROR;
+ if (s->avail_in_expect > 0 || !isempty_RL(s) ||
+ s->state_out_pos < s->numZ) return BZ_FINISH_OK;
+ s->mode = BZ_M_IDLE;
+ return BZ_STREAM_END;
+ }
+ return BZ_OK; /*--not reached--*/
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzCompressEnd) ( bz_stream *strm )
+{
+ EState* s;
+ if (strm == NULL) return BZ_PARAM_ERROR;
+ s = strm->state;
+ if (s == NULL) return BZ_PARAM_ERROR;
+ if (s->strm != strm) return BZ_PARAM_ERROR;
+
+ if (s->arr1 != NULL) BZFREE(s->arr1);
+ if (s->arr2 != NULL) BZFREE(s->arr2);
+ if (s->ftab != NULL) BZFREE(s->ftab);
+ BZFREE(strm->state);
+
+ strm->state = NULL;
+
+ return BZ_OK;
+}
+
+
+/*---------------------------------------------------*/
+/*--- Decompression stuff ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzDecompressInit)
+ ( bz_stream* strm,
+ int verbosity,
+ int small )
+{
+ DState* s;
+
+ if (!bz_config_ok()) return BZ_CONFIG_ERROR;
+
+ if (strm == NULL) return BZ_PARAM_ERROR;
+ if (small != 0 && small != 1) return BZ_PARAM_ERROR;
+ if (verbosity < 0 || verbosity > 4) return BZ_PARAM_ERROR;
+
+ if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
+ if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
+
+ s = BZALLOC( sizeof(DState) );
+ if (s == NULL) return BZ_MEM_ERROR;
+ s->strm = strm;
+ strm->state = s;
+ s->state = BZ_X_MAGIC_1;
+ s->bsLive = 0;
+ s->bsBuff = 0;
+ s->calculatedCombinedCRC = 0;
+ strm->total_in_lo32 = 0;
+ strm->total_in_hi32 = 0;
+ strm->total_out_lo32 = 0;
+ strm->total_out_hi32 = 0;
+ s->smallDecompress = (Bool)small;
+ s->ll4 = NULL;
+ s->ll16 = NULL;
+ s->tt = NULL;
+ s->currBlockNo = 0;
+ s->verbosity = verbosity;
+
+ return BZ_OK;
+}
+
+
+/*---------------------------------------------------*/
+/* Return True iff data corruption is discovered.
+ Returns False if there is no problem.
+*/
+static
+Bool unRLE_obuf_to_output_FAST ( DState* s )
+{
+ UChar k1;
+
+ if (s->blockRandomised) {
+
+ while (True) {
+ /* try to finish existing run */
+ while (True) {
+ if (s->strm->avail_out == 0) return False;
+ if (s->state_out_len == 0) break;
+ *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
+ BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
+ s->state_out_len--;
+ s->strm->next_out++;
+ s->strm->avail_out--;
+ s->strm->total_out_lo32++;
+ if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
+ }
+
+ /* can a new run be started? */
+ if (s->nblock_used == s->save_nblock+1) return False;
+
+ /* Only caused by corrupt data stream? */
+ if (s->nblock_used > s->save_nblock+1)
+ return True;
+
+ s->state_out_len = 1;
+ s->state_out_ch = s->k0;
+ BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
+ k1 ^= BZ_RAND_MASK; s->nblock_used++;
+ if (s->nblock_used == s->save_nblock+1) continue;
+ if (k1 != s->k0) { s->k0 = k1; continue; };
+
+ s->state_out_len = 2;
+ BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
+ k1 ^= BZ_RAND_MASK; s->nblock_used++;
+ if (s->nblock_used == s->save_nblock+1) continue;
+ if (k1 != s->k0) { s->k0 = k1; continue; };
+
+ s->state_out_len = 3;
+ BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
+ k1 ^= BZ_RAND_MASK; s->nblock_used++;
+ if (s->nblock_used == s->save_nblock+1) continue;
+ if (k1 != s->k0) { s->k0 = k1; continue; };
+
+ BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
+ k1 ^= BZ_RAND_MASK; s->nblock_used++;
+ s->state_out_len = ((Int32)k1) + 4;
+ BZ_GET_FAST(s->k0); BZ_RAND_UPD_MASK;
+ s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
+ }
+
+ } else {
+
+ /* restore */
+ UInt32 c_calculatedBlockCRC = s->calculatedBlockCRC;
+ UChar c_state_out_ch = s->state_out_ch;
+ Int32 c_state_out_len = s->state_out_len;
+ Int32 c_nblock_used = s->nblock_used;
+ Int32 c_k0 = s->k0;
+ UInt32* c_tt = s->tt;
+ UInt32 c_tPos = s->tPos;
+ char* cs_next_out = s->strm->next_out;
+ unsigned int cs_avail_out = s->strm->avail_out;
+ Int32 ro_blockSize100k = s->blockSize100k;
+ /* end restore */
+
+ UInt32 avail_out_INIT = cs_avail_out;
+ Int32 s_save_nblockPP = s->save_nblock+1;
+ unsigned int total_out_lo32_old;
+
+ while (True) {
+
+ /* try to finish existing run */
+ if (c_state_out_len > 0) {
+ while (True) {
+ if (cs_avail_out == 0) goto return_notr;
+ if (c_state_out_len == 1) break;
+ *( (UChar*)(cs_next_out) ) = c_state_out_ch;
+ BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
+ c_state_out_len--;
+ cs_next_out++;
+ cs_avail_out--;
+ }
+ s_state_out_len_eq_one:
+ {
+ if (cs_avail_out == 0) {
+ c_state_out_len = 1; goto return_notr;
+ };
+ *( (UChar*)(cs_next_out) ) = c_state_out_ch;
+ BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
+ cs_next_out++;
+ cs_avail_out--;
+ }
+ }
+ /* Only caused by corrupt data stream? */
+ if (c_nblock_used > s_save_nblockPP)
+ return True;
+
+ /* can a new run be started? */
+ if (c_nblock_used == s_save_nblockPP) {
+ c_state_out_len = 0; goto return_notr;
+ };
+ c_state_out_ch = c_k0;
+ BZ_GET_FAST_C(k1); c_nblock_used++;
+ if (k1 != c_k0) {
+ c_k0 = k1; goto s_state_out_len_eq_one;
+ };
+ if (c_nblock_used == s_save_nblockPP)
+ goto s_state_out_len_eq_one;
+
+ c_state_out_len = 2;
+ BZ_GET_FAST_C(k1); c_nblock_used++;
+ if (c_nblock_used == s_save_nblockPP) continue;
+ if (k1 != c_k0) { c_k0 = k1; continue; };
+
+ c_state_out_len = 3;
+ BZ_GET_FAST_C(k1); c_nblock_used++;
+ if (c_nblock_used == s_save_nblockPP) continue;
+ if (k1 != c_k0) { c_k0 = k1; continue; };
+
+ BZ_GET_FAST_C(k1); c_nblock_used++;
+ c_state_out_len = ((Int32)k1) + 4;
+ BZ_GET_FAST_C(c_k0); c_nblock_used++;
+ }
+
+ return_notr:
+ total_out_lo32_old = s->strm->total_out_lo32;
+ s->strm->total_out_lo32 += (avail_out_INIT - cs_avail_out);
+ if (s->strm->total_out_lo32 < total_out_lo32_old)
+ s->strm->total_out_hi32++;
+
+ /* save */
+ s->calculatedBlockCRC = c_calculatedBlockCRC;
+ s->state_out_ch = c_state_out_ch;
+ s->state_out_len = c_state_out_len;
+ s->nblock_used = c_nblock_used;
+ s->k0 = c_k0;
+ s->tt = c_tt;
+ s->tPos = c_tPos;
+ s->strm->next_out = cs_next_out;
+ s->strm->avail_out = cs_avail_out;
+ /* end save */
+ }
+ return False;
+}
+
+
+
+/*---------------------------------------------------*/
+__inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab )
+{
+ Int32 nb, na, mid;
+ nb = 0;
+ na = 256;
+ do {
+ mid = (nb + na) >> 1;
+ if (indx >= cftab[mid]) nb = mid; else na = mid;
+ }
+ while (na - nb != 1);
+ return nb;
+}
+
+
+/*---------------------------------------------------*/
+/* Return True iff data corruption is discovered.
+ Returns False if there is no problem.
+*/
+static
+Bool unRLE_obuf_to_output_SMALL ( DState* s )
+{
+ UChar k1;
+
+ if (s->blockRandomised) {
+
+ while (True) {
+ /* try to finish existing run */
+ while (True) {
+ if (s->strm->avail_out == 0) return False;
+ if (s->state_out_len == 0) break;
+ *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
+ BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
+ s->state_out_len--;
+ s->strm->next_out++;
+ s->strm->avail_out--;
+ s->strm->total_out_lo32++;
+ if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
+ }
+
+ /* can a new run be started? */
+ if (s->nblock_used == s->save_nblock+1) return False;
+
+ /* Only caused by corrupt data stream? */
+ if (s->nblock_used > s->save_nblock+1)
+ return True;
+
+ s->state_out_len = 1;
+ s->state_out_ch = s->k0;
+ BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
+ k1 ^= BZ_RAND_MASK; s->nblock_used++;
+ if (s->nblock_used == s->save_nblock+1) continue;
+ if (k1 != s->k0) { s->k0 = k1; continue; };
+
+ s->state_out_len = 2;
+ BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
+ k1 ^= BZ_RAND_MASK; s->nblock_used++;
+ if (s->nblock_used == s->save_nblock+1) continue;
+ if (k1 != s->k0) { s->k0 = k1; continue; };
+
+ s->state_out_len = 3;
+ BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
+ k1 ^= BZ_RAND_MASK; s->nblock_used++;
+ if (s->nblock_used == s->save_nblock+1) continue;
+ if (k1 != s->k0) { s->k0 = k1; continue; };
+
+ BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
+ k1 ^= BZ_RAND_MASK; s->nblock_used++;
+ s->state_out_len = ((Int32)k1) + 4;
+ BZ_GET_SMALL(s->k0); BZ_RAND_UPD_MASK;
+ s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
+ }
+
+ } else {
+
+ while (True) {
+ /* try to finish existing run */
+ while (True) {
+ if (s->strm->avail_out == 0) return False;
+ if (s->state_out_len == 0) break;
+ *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
+ BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
+ s->state_out_len--;
+ s->strm->next_out++;
+ s->strm->avail_out--;
+ s->strm->total_out_lo32++;
+ if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
+ }
+
+ /* can a new run be started? */
+ if (s->nblock_used == s->save_nblock+1) return False;
+
+ /* Only caused by corrupt data stream? */
+ if (s->nblock_used > s->save_nblock+1)
+ return True;
+
+ s->state_out_len = 1;
+ s->state_out_ch = s->k0;
+ BZ_GET_SMALL(k1); s->nblock_used++;
+ if (s->nblock_used == s->save_nblock+1) continue;
+ if (k1 != s->k0) { s->k0 = k1; continue; };
+
+ s->state_out_len = 2;
+ BZ_GET_SMALL(k1); s->nblock_used++;
+ if (s->nblock_used == s->save_nblock+1) continue;
+ if (k1 != s->k0) { s->k0 = k1; continue; };
+
+ s->state_out_len = 3;
+ BZ_GET_SMALL(k1); s->nblock_used++;
+ if (s->nblock_used == s->save_nblock+1) continue;
+ if (k1 != s->k0) { s->k0 = k1; continue; };
+
+ BZ_GET_SMALL(k1); s->nblock_used++;
+ s->state_out_len = ((Int32)k1) + 4;
+ BZ_GET_SMALL(s->k0); s->nblock_used++;
+ }
+
+ }
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzDecompress) ( bz_stream *strm )
+{
+ Bool corrupt;
+ DState* s;
+ if (strm == NULL) return BZ_PARAM_ERROR;
+ s = strm->state;
+ if (s == NULL) return BZ_PARAM_ERROR;
+ if (s->strm != strm) return BZ_PARAM_ERROR;
+
+ while (True) {
+ if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR;
+ if (s->state == BZ_X_OUTPUT) {
+ if (s->smallDecompress)
+ corrupt = unRLE_obuf_to_output_SMALL ( s ); else
+ corrupt = unRLE_obuf_to_output_FAST ( s );
+ if (corrupt) return BZ_DATA_ERROR;
+ if (s->nblock_used == s->save_nblock+1 && s->state_out_len == 0) {
+ BZ_FINALISE_CRC ( s->calculatedBlockCRC );
+ if (s->verbosity >= 3)
+ VPrintf2 ( " {0x%08x, 0x%08x}", s->storedBlockCRC,
+ s->calculatedBlockCRC );
+ if (s->verbosity >= 2) VPrintf0 ( "]" );
+ if (s->calculatedBlockCRC != s->storedBlockCRC)
+ return BZ_DATA_ERROR;
+ s->calculatedCombinedCRC
+ = (s->calculatedCombinedCRC << 1) |
+ (s->calculatedCombinedCRC >> 31);
+ s->calculatedCombinedCRC ^= s->calculatedBlockCRC;
+ s->state = BZ_X_BLKHDR_1;
+ } else {
+ return BZ_OK;
+ }
+ }
+ if (s->state >= BZ_X_MAGIC_1) {
+ Int32 r = BZ2_decompress ( s );
+ if (r == BZ_STREAM_END) {
+ if (s->verbosity >= 3)
+ VPrintf2 ( "\n combined CRCs: stored = 0x%08x, computed = 0x%08x",
+ s->storedCombinedCRC, s->calculatedCombinedCRC );
+ if (s->calculatedCombinedCRC != s->storedCombinedCRC)
+ return BZ_DATA_ERROR;
+ return r;
+ }
+ if (s->state != BZ_X_OUTPUT) return r;
+ }
+ }
+
+ AssertH ( 0, 6001 );
+
+ return 0; /*NOTREACHED*/
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzDecompressEnd) ( bz_stream *strm )
+{
+ DState* s;
+ if (strm == NULL) return BZ_PARAM_ERROR;
+ s = strm->state;
+ if (s == NULL) return BZ_PARAM_ERROR;
+ if (s->strm != strm) return BZ_PARAM_ERROR;
+
+ if (s->tt != NULL) BZFREE(s->tt);
+ if (s->ll16 != NULL) BZFREE(s->ll16);
+ if (s->ll4 != NULL) BZFREE(s->ll4);
+
+ BZFREE(strm->state);
+ strm->state = NULL;
+
+ return BZ_OK;
+}
+
+
+#ifndef BZ_NO_STDIO
+/*---------------------------------------------------*/
+/*--- File I/O stuff ---*/
+/*---------------------------------------------------*/
+
+#define BZ_SETERR(eee) \
+{ \
+ if (bzerror != NULL) *bzerror = eee; \
+ if (bzf != NULL) bzf->lastErr = eee; \
+}
+
+typedef
+ struct {
+ FILE* handle;
+ Char buf[BZ_MAX_UNUSED];
+ Int32 bufN;
+ Bool writing;
+ bz_stream strm;
+ Int32 lastErr;
+ Bool initialisedOk;
+ }
+ bzFile;
+
+
+/*---------------------------------------------*/
+static Bool myfeof ( FILE* f )
+{
+ Int32 c = fgetc ( f );
+ if (c == EOF) return True;
+ ungetc ( c, f );
+ return False;
+}
+
+
+/*---------------------------------------------------*/
+BZFILE* BZ_API(BZ2_bzWriteOpen)
+ ( int* bzerror,
+ FILE* f,
+ int blockSize100k,
+ int verbosity,
+ int workFactor )
+{
+ Int32 ret;
+ bzFile* bzf = NULL;
+
+ BZ_SETERR(BZ_OK);
+
+ if (f == NULL ||
+ (blockSize100k < 1 || blockSize100k > 9) ||
+ (workFactor < 0 || workFactor > 250) ||
+ (verbosity < 0 || verbosity > 4))
+ { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
+
+ if (ferror(f))
+ { BZ_SETERR(BZ_IO_ERROR); return NULL; };
+
+ bzf = malloc ( sizeof(bzFile) );
+ if (bzf == NULL)
+ { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
+
+ BZ_SETERR(BZ_OK);
+ bzf->initialisedOk = False;
+ bzf->bufN = 0;
+ bzf->handle = f;
+ bzf->writing = True;
+ bzf->strm.bzalloc = NULL;
+ bzf->strm.bzfree = NULL;
+ bzf->strm.opaque = NULL;
+
+ if (workFactor == 0) workFactor = 30;
+ ret = BZ2_bzCompressInit ( &(bzf->strm), blockSize100k,
+ verbosity, workFactor );
+ if (ret != BZ_OK)
+ { BZ_SETERR(ret); free(bzf); return NULL; };
+
+ bzf->strm.avail_in = 0;
+ bzf->initialisedOk = True;
+ return bzf;
+}
+
+
+
+/*---------------------------------------------------*/
+void BZ_API(BZ2_bzWrite)
+ ( int* bzerror,
+ BZFILE* b,
+ void* buf,
+ int len )
+{
+ Int32 n, n2, ret;
+ bzFile* bzf = (bzFile*)b;
+
+ BZ_SETERR(BZ_OK);
+ if (bzf == NULL || buf == NULL || len < 0)
+ { BZ_SETERR(BZ_PARAM_ERROR); return; };
+ if (!(bzf->writing))
+ { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
+ if (ferror(bzf->handle))
+ { BZ_SETERR(BZ_IO_ERROR); return; };
+
+ if (len == 0)
+ { BZ_SETERR(BZ_OK); return; };
+
+ bzf->strm.avail_in = len;
+ bzf->strm.next_in = buf;
+
+ while (True) {
+ bzf->strm.avail_out = BZ_MAX_UNUSED;
+ bzf->strm.next_out = bzf->buf;
+ ret = BZ2_bzCompress ( &(bzf->strm), BZ_RUN );
+ if (ret != BZ_RUN_OK)
+ { BZ_SETERR(ret); return; };
+
+ if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
+ n = BZ_MAX_UNUSED - bzf->strm.avail_out;
+ n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar),
+ n, bzf->handle );
+ if (n != n2 || ferror(bzf->handle))
+ { BZ_SETERR(BZ_IO_ERROR); return; };
+ }
+
+ if (bzf->strm.avail_in == 0)
+ { BZ_SETERR(BZ_OK); return; };
+ }
+}
+
+
+/*---------------------------------------------------*/
+void BZ_API(BZ2_bzWriteClose)
+ ( int* bzerror,
+ BZFILE* b,
+ int abandon,
+ unsigned int* nbytes_in,
+ unsigned int* nbytes_out )
+{
+ BZ2_bzWriteClose64 ( bzerror, b, abandon,
+ nbytes_in, NULL, nbytes_out, NULL );
+}
+
+
+void BZ_API(BZ2_bzWriteClose64)
+ ( int* bzerror,
+ BZFILE* b,
+ int abandon,
+ unsigned int* nbytes_in_lo32,
+ unsigned int* nbytes_in_hi32,
+ unsigned int* nbytes_out_lo32,
+ unsigned int* nbytes_out_hi32 )
+{
+ Int32 n, n2, ret;
+ bzFile* bzf = (bzFile*)b;
+
+ if (bzf == NULL)
+ { BZ_SETERR(BZ_OK); return; };
+ if (!(bzf->writing))
+ { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
+ if (ferror(bzf->handle))
+ { BZ_SETERR(BZ_IO_ERROR); return; };
+
+ if (nbytes_in_lo32 != NULL) *nbytes_in_lo32 = 0;
+ if (nbytes_in_hi32 != NULL) *nbytes_in_hi32 = 0;
+ if (nbytes_out_lo32 != NULL) *nbytes_out_lo32 = 0;
+ if (nbytes_out_hi32 != NULL) *nbytes_out_hi32 = 0;
+
+ if ((!abandon) && bzf->lastErr == BZ_OK) {
+ while (True) {
+ bzf->strm.avail_out = BZ_MAX_UNUSED;
+ bzf->strm.next_out = bzf->buf;
+ ret = BZ2_bzCompress ( &(bzf->strm), BZ_FINISH );
+ if (ret != BZ_FINISH_OK && ret != BZ_STREAM_END)
+ { BZ_SETERR(ret); return; };
+
+ if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
+ n = BZ_MAX_UNUSED - bzf->strm.avail_out;
+ n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar),
+ n, bzf->handle );
+ if (n != n2 || ferror(bzf->handle))
+ { BZ_SETERR(BZ_IO_ERROR); return; };
+ }
+
+ if (ret == BZ_STREAM_END) break;
+ }
+ }
+
+ if ( !abandon && !ferror ( bzf->handle ) ) {
+ fflush ( bzf->handle );
+ if (ferror(bzf->handle))
+ { BZ_SETERR(BZ_IO_ERROR); return; };
+ }
+
+ if (nbytes_in_lo32 != NULL)
+ *nbytes_in_lo32 = bzf->strm.total_in_lo32;
+ if (nbytes_in_hi32 != NULL)
+ *nbytes_in_hi32 = bzf->strm.total_in_hi32;
+ if (nbytes_out_lo32 != NULL)
+ *nbytes_out_lo32 = bzf->strm.total_out_lo32;
+ if (nbytes_out_hi32 != NULL)
+ *nbytes_out_hi32 = bzf->strm.total_out_hi32;
+
+ BZ_SETERR(BZ_OK);
+ BZ2_bzCompressEnd ( &(bzf->strm) );
+ free ( bzf );
+}
+
+
+/*---------------------------------------------------*/
+BZFILE* BZ_API(BZ2_bzReadOpen)
+ ( int* bzerror,
+ FILE* f,
+ int verbosity,
+ int small,
+ void* unused,
+ int nUnused )
+{
+ bzFile* bzf = NULL;
+ int ret;
+
+ BZ_SETERR(BZ_OK);
+
+ if (f == NULL ||
+ (small != 0 && small != 1) ||
+ (verbosity < 0 || verbosity > 4) ||
+ (unused == NULL && nUnused != 0) ||
+ (unused != NULL && (nUnused < 0 || nUnused > BZ_MAX_UNUSED)))
+ { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
+
+ if (ferror(f))
+ { BZ_SETERR(BZ_IO_ERROR); return NULL; };
+
+ bzf = malloc ( sizeof(bzFile) );
+ if (bzf == NULL)
+ { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
+
+ BZ_SETERR(BZ_OK);
+
+ bzf->initialisedOk = False;
+ bzf->handle = f;
+ bzf->bufN = 0;
+ bzf->writing = False;
+ bzf->strm.bzalloc = NULL;
+ bzf->strm.bzfree = NULL;
+ bzf->strm.opaque = NULL;
+
+ while (nUnused > 0) {
+ bzf->buf[bzf->bufN] = *((UChar*)(unused)); bzf->bufN++;
+ unused = ((void*)( 1 + ((UChar*)(unused)) ));
+ nUnused--;
+ }
+
+ ret = BZ2_bzDecompressInit ( &(bzf->strm), verbosity, small );
+ if (ret != BZ_OK)
+ { BZ_SETERR(ret); free(bzf); return NULL; };
+
+ bzf->strm.avail_in = bzf->bufN;
+ bzf->strm.next_in = bzf->buf;
+
+ bzf->initialisedOk = True;
+ return bzf;
+}
+
+
+/*---------------------------------------------------*/
+void BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b )
+{
+ bzFile* bzf = (bzFile*)b;
+
+ BZ_SETERR(BZ_OK);
+ if (bzf == NULL)
+ { BZ_SETERR(BZ_OK); return; };
+
+ if (bzf->writing)
+ { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
+
+ if (bzf->initialisedOk)
+ (void)BZ2_bzDecompressEnd ( &(bzf->strm) );
+ free ( bzf );
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzRead)
+ ( int* bzerror,
+ BZFILE* b,
+ void* buf,
+ int len )
+{
+ Int32 n, ret;
+ bzFile* bzf = (bzFile*)b;
+
+ BZ_SETERR(BZ_OK);
+
+ if (bzf == NULL || buf == NULL || len < 0)
+ { BZ_SETERR(BZ_PARAM_ERROR); return 0; };
+
+ if (bzf->writing)
+ { BZ_SETERR(BZ_SEQUENCE_ERROR); return 0; };
+
+ if (len == 0)
+ { BZ_SETERR(BZ_OK); return 0; };
+
+ bzf->strm.avail_out = len;
+ bzf->strm.next_out = buf;
+
+ while (True) {
+
+ if (ferror(bzf->handle))
+ { BZ_SETERR(BZ_IO_ERROR); return 0; };
+
+ if (bzf->strm.avail_in == 0 && !myfeof(bzf->handle)) {
+ n = fread ( bzf->buf, sizeof(UChar),
+ BZ_MAX_UNUSED, bzf->handle );
+ if (ferror(bzf->handle))
+ { BZ_SETERR(BZ_IO_ERROR); return 0; };
+ bzf->bufN = n;
+ bzf->strm.avail_in = bzf->bufN;
+ bzf->strm.next_in = bzf->buf;
+ }
+
+ ret = BZ2_bzDecompress ( &(bzf->strm) );
+
+ if (ret != BZ_OK && ret != BZ_STREAM_END)
+ { BZ_SETERR(ret); return 0; };
+
+ if (ret == BZ_OK && myfeof(bzf->handle) &&
+ bzf->strm.avail_in == 0 && bzf->strm.avail_out > 0)
+ { BZ_SETERR(BZ_UNEXPECTED_EOF); return 0; };
+
+ if (ret == BZ_STREAM_END)
+ { BZ_SETERR(BZ_STREAM_END);
+ return len - bzf->strm.avail_out; };
+ if (bzf->strm.avail_out == 0)
+ { BZ_SETERR(BZ_OK); return len; };
+
+ }
+
+ return 0; /*not reached*/
+}
+
+
+/*---------------------------------------------------*/
+void BZ_API(BZ2_bzReadGetUnused)
+ ( int* bzerror,
+ BZFILE* b,
+ void** unused,
+ int* nUnused )
+{
+ bzFile* bzf = (bzFile*)b;
+ if (bzf == NULL)
+ { BZ_SETERR(BZ_PARAM_ERROR); return; };
+ if (bzf->lastErr != BZ_STREAM_END)
+ { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
+ if (unused == NULL || nUnused == NULL)
+ { BZ_SETERR(BZ_PARAM_ERROR); return; };
+
+ BZ_SETERR(BZ_OK);
+ *nUnused = bzf->strm.avail_in;
+ *unused = bzf->strm.next_in;
+}
+#endif
+
+
+/*---------------------------------------------------*/
+/*--- Misc convenience stuff ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzBuffToBuffCompress)
+ ( char* dest,
+ unsigned int* destLen,
+ char* source,
+ unsigned int sourceLen,
+ int blockSize100k,
+ int verbosity,
+ int workFactor )
+{
+ bz_stream strm;
+ int ret;
+
+ if (dest == NULL || destLen == NULL ||
+ source == NULL ||
+ blockSize100k < 1 || blockSize100k > 9 ||
+ verbosity < 0 || verbosity > 4 ||
+ workFactor < 0 || workFactor > 250)
+ return BZ_PARAM_ERROR;
+
+ if (workFactor == 0) workFactor = 30;
+ strm.bzalloc = NULL;
+ strm.bzfree = NULL;
+ strm.opaque = NULL;
+ ret = BZ2_bzCompressInit ( &strm, blockSize100k,
+ verbosity, workFactor );
+ if (ret != BZ_OK) return ret;
+
+ strm.next_in = source;
+ strm.next_out = dest;
+ strm.avail_in = sourceLen;
+ strm.avail_out = *destLen;
+
+ ret = BZ2_bzCompress ( &strm, BZ_FINISH );
+ if (ret == BZ_FINISH_OK) goto output_overflow;
+ if (ret != BZ_STREAM_END) goto errhandler;
+
+ /* normal termination */
+ *destLen -= strm.avail_out;
+ BZ2_bzCompressEnd ( &strm );
+ return BZ_OK;
+
+ output_overflow:
+ BZ2_bzCompressEnd ( &strm );
+ return BZ_OUTBUFF_FULL;
+
+ errhandler:
+ BZ2_bzCompressEnd ( &strm );
+ return ret;
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzBuffToBuffDecompress)
+ ( char* dest,
+ unsigned int* destLen,
+ char* source,
+ unsigned int sourceLen,
+ int small,
+ int verbosity )
+{
+ bz_stream strm;
+ int ret;
+
+ if (dest == NULL || destLen == NULL ||
+ source == NULL ||
+ (small != 0 && small != 1) ||
+ verbosity < 0 || verbosity > 4)
+ return BZ_PARAM_ERROR;
+
+ strm.bzalloc = NULL;
+ strm.bzfree = NULL;
+ strm.opaque = NULL;
+ ret = BZ2_bzDecompressInit ( &strm, verbosity, small );
+ if (ret != BZ_OK) return ret;
+
+ strm.next_in = source;
+ strm.next_out = dest;
+ strm.avail_in = sourceLen;
+ strm.avail_out = *destLen;
+
+ ret = BZ2_bzDecompress ( &strm );
+ if (ret == BZ_OK) goto output_overflow_or_eof;
+ if (ret != BZ_STREAM_END) goto errhandler;
+
+ /* normal termination */
+ *destLen -= strm.avail_out;
+ BZ2_bzDecompressEnd ( &strm );
+ return BZ_OK;
+
+ output_overflow_or_eof:
+ if (strm.avail_out > 0) {
+ BZ2_bzDecompressEnd ( &strm );
+ return BZ_UNEXPECTED_EOF;
+ } else {
+ BZ2_bzDecompressEnd ( &strm );
+ return BZ_OUTBUFF_FULL;
+ };
+
+ errhandler:
+ BZ2_bzDecompressEnd ( &strm );
+ return ret;
+}
+
+
+/*---------------------------------------------------*/
+/*--
+ Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
+ to support better zlib compatibility.
+ This code is not _officially_ part of libbzip2 (yet);
+ I haven't tested it, documented it, or considered the
+ threading-safeness of it.
+ If this code breaks, please contact both Yoshioka and me.
+--*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+/*--
+ return version like "0.9.5d, 4-Sept-1999".
+--*/
+const char * BZ_API(BZ2_bzlibVersion)(void)
+{
+ return BZ_VERSION;
+}
+
+
+#ifndef BZ_NO_STDIO
+/*---------------------------------------------------*/
+
+#if defined(_WIN32) || defined(OS2) || defined(MSDOS)
+# include <fcntl.h>
+# include <io.h>
+# define SET_BINARY_MODE(file) setmode(fileno(file),O_BINARY)
+#else
+# define SET_BINARY_MODE(file)
+#endif
+static
+BZFILE * bzopen_or_bzdopen
+ ( const char *path, /* no use when bzdopen */
+ int fd, /* no use when bzdopen */
+ const char *mode,
+ int open_mode) /* bzopen: 0, bzdopen:1 */
+{
+ int bzerr;
+ char unused[BZ_MAX_UNUSED];
+ int blockSize100k = 9;
+ int writing = 0;
+ char mode2[10] = "";
+ FILE *fp = NULL;
+ BZFILE *bzfp = NULL;
+ int verbosity = 0;
+ int workFactor = 30;
+ int smallMode = 0;
+ int nUnused = 0;
+
+ if (mode == NULL) return NULL;
+ while (*mode) {
+ switch (*mode) {
+ case 'r':
+ writing = 0; break;
+ case 'w':
+ writing = 1; break;
+ case 's':
+ smallMode = 1; break;
+ default:
+ if (isdigit((int)(*mode))) {
+ blockSize100k = *mode-BZ_HDR_0;
+ }
+ }
+ mode++;
+ }
+ strcat(mode2, writing ? "w" : "r" );
+ strcat(mode2,"b"); /* binary mode */
+
+ if (open_mode==0) {
+ if (path==NULL || strcmp(path,"")==0) {
+ fp = (writing ? stdout : stdin);
+ SET_BINARY_MODE(fp);
+ } else {
+ fp = fopen(path,mode2);
+ }
+ } else {
+#ifdef BZ_STRICT_ANSI
+ fp = NULL;
+#else
+ fp = fdopen(fd,mode2);
+#endif
+ }
+ if (fp == NULL) return NULL;
+
+ if (writing) {
+ /* Guard against total chaos and anarchy -- JRS */
+ if (blockSize100k < 1) blockSize100k = 1;
+ if (blockSize100k > 9) blockSize100k = 9;
+ bzfp = BZ2_bzWriteOpen(&bzerr,fp,blockSize100k,
+ verbosity,workFactor);
+ } else {
+ bzfp = BZ2_bzReadOpen(&bzerr,fp,verbosity,smallMode,
+ unused,nUnused);
+ }
+ if (bzfp == NULL) {
+ if (fp != stdin && fp != stdout) fclose(fp);
+ return NULL;
+ }
+ return bzfp;
+}
+
+
+/*---------------------------------------------------*/
+/*--
+ open file for read or write.
+ ex) bzopen("file","w9")
+ case path="" or NULL => use stdin or stdout.
+--*/
+BZFILE * BZ_API(BZ2_bzopen)
+ ( const char *path,
+ const char *mode )
+{
+ return bzopen_or_bzdopen(path,-1,mode,/*bzopen*/0);
+}
+
+
+/*---------------------------------------------------*/
+BZFILE * BZ_API(BZ2_bzdopen)
+ ( int fd,
+ const char *mode )
+{
+ return bzopen_or_bzdopen(NULL,fd,mode,/*bzdopen*/1);
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzread) (BZFILE* b, void* buf, int len )
+{
+ int bzerr, nread;
+ if (((bzFile*)b)->lastErr == BZ_STREAM_END) return 0;
+ nread = BZ2_bzRead(&bzerr,b,buf,len);
+ if (bzerr == BZ_OK || bzerr == BZ_STREAM_END) {
+ return nread;
+ } else {
+ return -1;
+ }
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzwrite) (BZFILE* b, void* buf, int len )
+{
+ int bzerr;
+
+ BZ2_bzWrite(&bzerr,b,buf,len);
+ if(bzerr == BZ_OK){
+ return len;
+ }else{
+ return -1;
+ }
+}
+
+
+/*---------------------------------------------------*/
+int BZ_API(BZ2_bzflush) (BZFILE *b)
+{
+ (void) b;
+ /* do nothing now... */
+ return 0;
+}
+
+
+/*---------------------------------------------------*/
+void BZ_API(BZ2_bzclose) (BZFILE* b)
+{
+ int bzerr;
+ FILE *fp;
+
+ if (b==NULL) {return;}
+ fp = ((bzFile *)b)->handle;
+ if(((bzFile*)b)->writing){
+ BZ2_bzWriteClose(&bzerr,b,0,NULL,NULL);
+ if(bzerr != BZ_OK){
+ BZ2_bzWriteClose(NULL,b,1,NULL,NULL);
+ }
+ }else{
+ BZ2_bzReadClose(&bzerr,b);
+ }
+ if(fp!=stdin && fp!=stdout){
+ fclose(fp);
+ }
+}
+
+
+/*---------------------------------------------------*/
+/*--
+ return last error code
+--*/
+static const char *bzerrorstrings[] = {
+ "OK"
+ ,"SEQUENCE_ERROR"
+ ,"PARAM_ERROR"
+ ,"MEM_ERROR"
+ ,"DATA_ERROR"
+ ,"DATA_ERROR_MAGIC"
+ ,"IO_ERROR"
+ ,"UNEXPECTED_EOF"
+ ,"OUTBUFF_FULL"
+ ,"CONFIG_ERROR"
+ ,"???" /* for future */
+ ,"???" /* for future */
+ ,"???" /* for future */
+ ,"???" /* for future */
+ ,"???" /* for future */
+ ,"???" /* for future */
+};
+
+
+const char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum)
+{
+ int err = ((bzFile *)b)->lastErr;
+
+ if(err>0) err = 0;
+ *errnum = err;
+ return bzerrorstrings[err*-1];
+}
+#endif
+
+
+/*-------------------------------------------------------------*/
+/*--- end bzlib.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/Utilities/cmbzip2/bzlib.h b/Utilities/cmbzip2/bzlib.h
new file mode 100644
index 000000000..c5b75d6d8
--- /dev/null
+++ b/Utilities/cmbzip2/bzlib.h
@@ -0,0 +1,282 @@
+
+/*-------------------------------------------------------------*/
+/*--- Public header file for the library. ---*/
+/*--- bzlib.h ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
+
+ bzip2/libbzip2 version 1.0.5 of 10 December 2007
+ Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
+
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------ */
+
+
+#ifndef _BZLIB_H
+#define _BZLIB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define BZ_RUN 0
+#define BZ_FLUSH 1
+#define BZ_FINISH 2
+
+#define BZ_OK 0
+#define BZ_RUN_OK 1
+#define BZ_FLUSH_OK 2
+#define BZ_FINISH_OK 3
+#define BZ_STREAM_END 4
+#define BZ_SEQUENCE_ERROR (-1)
+#define BZ_PARAM_ERROR (-2)
+#define BZ_MEM_ERROR (-3)
+#define BZ_DATA_ERROR (-4)
+#define BZ_DATA_ERROR_MAGIC (-5)
+#define BZ_IO_ERROR (-6)
+#define BZ_UNEXPECTED_EOF (-7)
+#define BZ_OUTBUFF_FULL (-8)
+#define BZ_CONFIG_ERROR (-9)
+
+typedef
+ struct {
+ char *next_in;
+ unsigned int avail_in;
+ unsigned int total_in_lo32;
+ unsigned int total_in_hi32;
+
+ char *next_out;
+ unsigned int avail_out;
+ unsigned int total_out_lo32;
+ unsigned int total_out_hi32;
+
+ void *state;
+
+ void *(*bzalloc)(void *,int,int);
+ void (*bzfree)(void *,void *);
+ void *opaque;
+ }
+ bz_stream;
+
+
+#ifndef BZ_IMPORT
+#define BZ_EXPORT
+#endif
+
+#ifndef BZ_NO_STDIO
+/* Need a definitition for FILE */
+#include <stdio.h>
+#endif
+
+#ifdef _WIN32
+# include <windows.h>
+# ifdef small
+ /* windows.h define small to char */
+# undef small
+# endif
+# ifdef BZ_EXPORT
+# define BZ_API(func) WINAPI func
+# define BZ_EXTERN extern
+# else
+ /* import windows dll dynamically */
+# define BZ_API(func) (WINAPI * func)
+# define BZ_EXTERN
+# endif
+#else
+# define BZ_API(func) func
+# define BZ_EXTERN extern
+#endif
+
+
+/*-- Core (low-level) library functions --*/
+
+BZ_EXTERN int BZ_API(BZ2_bzCompressInit) (
+ bz_stream* strm,
+ int blockSize100k,
+ int verbosity,
+ int workFactor
+ );
+
+BZ_EXTERN int BZ_API(BZ2_bzCompress) (
+ bz_stream* strm,
+ int action
+ );
+
+BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) (
+ bz_stream* strm
+ );
+
+BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) (
+ bz_stream *strm,
+ int verbosity,
+ int small
+ );
+
+BZ_EXTERN int BZ_API(BZ2_bzDecompress) (
+ bz_stream* strm
+ );
+
+BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) (
+ bz_stream *strm
+ );
+
+
+
+/*-- High(er) level library functions --*/
+
+#ifndef BZ_NO_STDIO
+#define BZ_MAX_UNUSED 5000
+
+typedef void BZFILE;
+
+BZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) (
+ int* bzerror,
+ FILE* f,
+ int verbosity,
+ int small,
+ void* unused,
+ int nUnused
+ );
+
+BZ_EXTERN void BZ_API(BZ2_bzReadClose) (
+ int* bzerror,
+ BZFILE* b
+ );
+
+BZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) (
+ int* bzerror,
+ BZFILE* b,
+ void** unused,
+ int* nUnused
+ );
+
+BZ_EXTERN int BZ_API(BZ2_bzRead) (
+ int* bzerror,
+ BZFILE* b,
+ void* buf,
+ int len
+ );
+
+BZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) (
+ int* bzerror,
+ FILE* f,
+ int blockSize100k,
+ int verbosity,
+ int workFactor
+ );
+
+BZ_EXTERN void BZ_API(BZ2_bzWrite) (
+ int* bzerror,
+ BZFILE* b,
+ void* buf,
+ int len
+ );
+
+BZ_EXTERN void BZ_API(BZ2_bzWriteClose) (
+ int* bzerror,
+ BZFILE* b,
+ int abandon,
+ unsigned int* nbytes_in,
+ unsigned int* nbytes_out
+ );
+
+BZ_EXTERN void BZ_API(BZ2_bzWriteClose64) (
+ int* bzerror,
+ BZFILE* b,
+ int abandon,
+ unsigned int* nbytes_in_lo32,
+ unsigned int* nbytes_in_hi32,
+ unsigned int* nbytes_out_lo32,
+ unsigned int* nbytes_out_hi32
+ );
+#endif
+
+
+/*-- Utility functions --*/
+
+BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) (
+ char* dest,
+ unsigned int* destLen,
+ char* source,
+ unsigned int sourceLen,
+ int blockSize100k,
+ int verbosity,
+ int workFactor
+ );
+
+BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) (
+ char* dest,
+ unsigned int* destLen,
+ char* source,
+ unsigned int sourceLen,
+ int small,
+ int verbosity
+ );
+
+
+/*--
+ Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
+ to support better zlib compatibility.
+ This code is not _officially_ part of libbzip2 (yet);
+ I haven't tested it, documented it, or considered the
+ threading-safeness of it.
+ If this code breaks, please contact both Yoshioka and me.
+--*/
+
+BZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) (
+ void
+ );
+
+#ifndef BZ_NO_STDIO
+BZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) (
+ const char *path,
+ const char *mode
+ );
+
+BZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) (
+ int fd,
+ const char *mode
+ );
+
+BZ_EXTERN int BZ_API(BZ2_bzread) (
+ BZFILE* b,
+ void* buf,
+ int len
+ );
+
+BZ_EXTERN int BZ_API(BZ2_bzwrite) (
+ BZFILE* b,
+ void* buf,
+ int len
+ );
+
+BZ_EXTERN int BZ_API(BZ2_bzflush) (
+ BZFILE* b
+ );
+
+BZ_EXTERN void BZ_API(BZ2_bzclose) (
+ BZFILE* b
+ );
+
+BZ_EXTERN const char * BZ_API(BZ2_bzerror) (
+ BZFILE *b,
+ int *errnum
+ );
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/*-------------------------------------------------------------*/
+/*--- end bzlib.h ---*/
+/*-------------------------------------------------------------*/
diff --git a/Utilities/cmbzip2/bzlib_private.h b/Utilities/cmbzip2/bzlib_private.h
new file mode 100644
index 000000000..02a667f49
--- /dev/null
+++ b/Utilities/cmbzip2/bzlib_private.h
@@ -0,0 +1,526 @@
+
+/*-------------------------------------------------------------*/
+/*--- Private header file for the library. ---*/
+/*--- bzlib_private.h ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
+
+ bzip2/libbzip2 version 1.0.5 of 10 December 2007
+ Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
+
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------ */
+
+
+#ifndef _BZLIB_PRIVATE_H
+#define _BZLIB_PRIVATE_H
+
+#include <stdlib.h>
+
+#ifndef BZ_NO_STDIO
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#endif
+
+#include "bzlib.h"
+
+
+#if defined(__BORLANDC__)
+# pragma warn -8004 /* Assigned value never used. */
+# pragma warn -8008 /* Condition is always true/false. */
+# pragma warn -8066 /* Unreachable code. */
+# pragma warn -8057 /* Unused parameter. */
+#endif
+#if defined(_MSC_VER)
+/* 'integral size mismatch in argument; conversion supplied */
+# pragma warning(disable:4244)
+/* conversion from 'size_t' to 'off_t', possible loss of data */
+# pragma warning(disable:4267)
+/* warning C4127: conditional expression is constant*/
+# pragma warning(disable:4127)
+#endif
+#if defined(__clang__)
+# pragma clang diagnostic ignored "-Wcast-align"
+#endif
+
+/*-- General stuff. --*/
+
+#define BZ_VERSION "1.0.5, 10-Dec-2007"
+
+typedef char Char;
+typedef unsigned char Bool;
+typedef unsigned char UChar;
+typedef int Int32;
+typedef unsigned int UInt32;
+typedef short Int16;
+typedef unsigned short UInt16;
+
+#define True ((Bool)1)
+#define False ((Bool)0)
+
+#ifndef __GNUC__
+#define __inline__ /* */
+#endif
+
+#ifndef BZ_NO_STDIO
+
+extern void BZ2_bz__AssertH__fail ( int errcode );
+#define AssertH(cond,errcode) \
+ { if (!(cond)) BZ2_bz__AssertH__fail ( errcode ); }
+
+#if BZ_DEBUG
+#define AssertD(cond,msg) \
+ { if (!(cond)) { \
+ fprintf ( stderr, \
+ "\n\nlibbzip2(debug build): internal error\n\t%s\n", msg );\
+ exit(1); \
+ }}
+#else
+#define AssertD(cond,msg) /* */
+#endif
+
+#define VPrintf0(zf) \
+ fprintf(stderr,zf)
+#define VPrintf1(zf,za1) \
+ fprintf(stderr,zf,za1)
+#define VPrintf2(zf,za1,za2) \
+ fprintf(stderr,zf,za1,za2)
+#define VPrintf3(zf,za1,za2,za3) \
+ fprintf(stderr,zf,za1,za2,za3)
+#define VPrintf4(zf,za1,za2,za3,za4) \
+ fprintf(stderr,zf,za1,za2,za3,za4)
+#define VPrintf5(zf,za1,za2,za3,za4,za5) \
+ fprintf(stderr,zf,za1,za2,za3,za4,za5)
+
+#else
+
+extern void bz_internal_error ( int errcode );
+#define AssertH(cond,errcode) \
+ { if (!(cond)) bz_internal_error ( errcode ); }
+#define AssertD(cond,msg) do { } while (0)
+#define VPrintf0(zf) do { } while (0)
+#define VPrintf1(zf,za1) do { } while (0)
+#define VPrintf2(zf,za1,za2) do { } while (0)
+#define VPrintf3(zf,za1,za2,za3) do { } while (0)
+#define VPrintf4(zf,za1,za2,za3,za4) do { } while (0)
+#define VPrintf5(zf,za1,za2,za3,za4,za5) do { } while (0)
+
+#endif
+
+
+#define BZALLOC(nnn) (strm->bzalloc)(strm->opaque,(nnn),1)
+#define BZFREE(ppp) (strm->bzfree)(strm->opaque,(ppp))
+
+
+/*-- Header bytes. --*/
+
+#define BZ_HDR_B 0x42 /* 'B' */
+#define BZ_HDR_Z 0x5a /* 'Z' */
+#define BZ_HDR_h 0x68 /* 'h' */
+#define BZ_HDR_0 0x30 /* '0' */
+
+/*-- Constants for the back end. --*/
+
+#define BZ_MAX_ALPHA_SIZE 258
+#define BZ_MAX_CODE_LEN 23
+
+#define BZ_RUNA 0
+#define BZ_RUNB 1
+
+#define BZ_N_GROUPS 6
+#define BZ_G_SIZE 50
+#define BZ_N_ITERS 4
+
+#define BZ_MAX_SELECTORS (2 + (900000 / BZ_G_SIZE))
+
+
+
+/*-- Stuff for randomising repetitive blocks. --*/
+
+extern Int32 BZ2_rNums[512];
+
+#define BZ_RAND_DECLS \
+ Int32 rNToGo; \
+ Int32 rTPos \
+
+#define BZ_RAND_INIT_MASK \
+ s->rNToGo = 0; \
+ s->rTPos = 0 \
+
+#define BZ_RAND_MASK ((s->rNToGo == 1) ? 1 : 0)
+
+#define BZ_RAND_UPD_MASK \
+ if (s->rNToGo == 0) { \
+ s->rNToGo = BZ2_rNums[s->rTPos]; \
+ s->rTPos++; \
+ if (s->rTPos == 512) s->rTPos = 0; \
+ } \
+ s->rNToGo--;
+
+
+
+/*-- Stuff for doing CRCs. --*/
+
+extern UInt32 BZ2_crc32Table[256];
+
+#define BZ_INITIALISE_CRC(crcVar) \
+{ \
+ crcVar = 0xffffffffL; \
+}
+
+#define BZ_FINALISE_CRC(crcVar) \
+{ \
+ crcVar = ~(crcVar); \
+}
+
+#define BZ_UPDATE_CRC(crcVar,cha) \
+{ \
+ crcVar = (crcVar << 8) ^ \
+ BZ2_crc32Table[(crcVar >> 24) ^ \
+ ((UChar)cha)]; \
+}
+
+
+
+/*-- States and modes for compression. --*/
+
+#define BZ_M_IDLE 1
+#define BZ_M_RUNNING 2
+#define BZ_M_FLUSHING 3
+#define BZ_M_FINISHING 4
+
+#define BZ_S_OUTPUT 1
+#define BZ_S_INPUT 2
+
+#define BZ_N_RADIX 2
+#define BZ_N_QSORT 12
+#define BZ_N_SHELL 18
+#define BZ_N_OVERSHOOT (BZ_N_RADIX + BZ_N_QSORT + BZ_N_SHELL + 2)
+
+
+
+
+/*-- Structure holding all the compression-side stuff. --*/
+
+typedef
+ struct {
+ /* pointer back to the struct bz_stream */
+ bz_stream* strm;
+
+ /* mode this stream is in, and whether inputting */
+ /* or outputting data */
+ Int32 mode;
+ Int32 state;
+
+ /* remembers avail_in when flush/finish requested */
+ UInt32 avail_in_expect;
+
+ /* for doing the block sorting */
+ UInt32* arr1;
+ UInt32* arr2;
+ UInt32* ftab;
+ Int32 origPtr;
+
+ /* aliases for arr1 and arr2 */
+ UInt32* ptr;
+ UChar* block;
+ UInt16* mtfv;
+ UChar* zbits;
+
+ /* for deciding when to use the fallback sorting algorithm */
+ Int32 workFactor;
+
+ /* run-length-encoding of the input */
+ UInt32 state_in_ch;
+ Int32 state_in_len;
+ BZ_RAND_DECLS;
+
+ /* input and output limits and current posns */
+ Int32 nblock;
+ Int32 nblockMAX;
+ Int32 numZ;
+ Int32 state_out_pos;
+
+ /* map of bytes used in block */
+ Int32 nInUse;
+ Bool inUse[256];
+ UChar unseqToSeq[256];
+
+ /* the buffer for bit stream creation */
+ UInt32 bsBuff;
+ Int32 bsLive;
+
+ /* block and combined CRCs */
+ UInt32 blockCRC;
+ UInt32 combinedCRC;
+
+ /* misc administratium */
+ Int32 verbosity;
+ Int32 blockNo;
+ Int32 blockSize100k;
+
+ /* stuff for coding the MTF values */
+ Int32 nMTF;
+ Int32 mtfFreq [BZ_MAX_ALPHA_SIZE];
+ UChar selector [BZ_MAX_SELECTORS];
+ UChar selectorMtf[BZ_MAX_SELECTORS];
+
+ UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+ Int32 code [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+ Int32 rfreq [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+ /* second dimension: only 3 needed; 4 makes index calculations faster */
+ UInt32 len_pack[BZ_MAX_ALPHA_SIZE][4];
+
+ }
+ EState;
+
+
+
+/*-- externs for compression. --*/
+
+extern void
+BZ2_blockSort ( EState* );
+
+extern void
+BZ2_compressBlock ( EState*, Bool );
+
+extern void
+BZ2_bsInitWrite ( EState* );
+
+extern void
+BZ2_hbAssignCodes ( Int32*, UChar*, Int32, Int32, Int32 );
+
+extern void
+BZ2_hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 );
+
+
+
+/*-- states for decompression. --*/
+
+#define BZ_X_IDLE 1
+#define BZ_X_OUTPUT 2
+
+#define BZ_X_MAGIC_1 10
+#define BZ_X_MAGIC_2 11
+#define BZ_X_MAGIC_3 12
+#define BZ_X_MAGIC_4 13
+#define BZ_X_BLKHDR_1 14
+#define BZ_X_BLKHDR_2 15
+#define BZ_X_BLKHDR_3 16
+#define BZ_X_BLKHDR_4 17
+#define BZ_X_BLKHDR_5 18
+#define BZ_X_BLKHDR_6 19
+#define BZ_X_BCRC_1 20
+#define BZ_X_BCRC_2 21
+#define BZ_X_BCRC_3 22
+#define BZ_X_BCRC_4 23
+#define BZ_X_RANDBIT 24
+#define BZ_X_ORIGPTR_1 25
+#define BZ_X_ORIGPTR_2 26
+#define BZ_X_ORIGPTR_3 27
+#define BZ_X_MAPPING_1 28
+#define BZ_X_MAPPING_2 29
+#define BZ_X_SELECTOR_1 30
+#define BZ_X_SELECTOR_2 31
+#define BZ_X_SELECTOR_3 32
+#define BZ_X_CODING_1 33
+#define BZ_X_CODING_2 34
+#define BZ_X_CODING_3 35
+#define BZ_X_MTF_1 36
+#define BZ_X_MTF_2 37
+#define BZ_X_MTF_3 38
+#define BZ_X_MTF_4 39
+#define BZ_X_MTF_5 40
+#define BZ_X_MTF_6 41
+#define BZ_X_ENDHDR_2 42
+#define BZ_X_ENDHDR_3 43
+#define BZ_X_ENDHDR_4 44
+#define BZ_X_ENDHDR_5 45
+#define BZ_X_ENDHDR_6 46
+#define BZ_X_CCRC_1 47
+#define BZ_X_CCRC_2 48
+#define BZ_X_CCRC_3 49
+#define BZ_X_CCRC_4 50
+
+
+
+/*-- Constants for the fast MTF decoder. --*/
+
+#define MTFA_SIZE 4096
+#define MTFL_SIZE 16
+
+
+
+/*-- Structure holding all the decompression-side stuff. --*/
+
+typedef
+ struct {
+ /* pointer back to the struct bz_stream */
+ bz_stream* strm;
+
+ /* state indicator for this stream */
+ Int32 state;
+
+ /* for doing the final run-length decoding */
+ UChar state_out_ch;
+ Int32 state_out_len;
+ Bool blockRandomised;
+ BZ_RAND_DECLS;
+
+ /* the buffer for bit stream reading */
+ UInt32 bsBuff;
+ Int32 bsLive;
+
+ /* misc administratium */
+ Int32 blockSize100k;
+ Bool smallDecompress;
+ Int32 currBlockNo;
+ Int32 verbosity;
+
+ /* for undoing the Burrows-Wheeler transform */
+ Int32 origPtr;
+ UInt32 tPos;
+ Int32 k0;
+ Int32 unzftab[256];
+ Int32 nblock_used;
+ Int32 cftab[257];
+ Int32 cftabCopy[257];
+
+ /* for undoing the Burrows-Wheeler transform (FAST) */
+ UInt32 *tt;
+
+ /* for undoing the Burrows-Wheeler transform (SMALL) */
+ UInt16 *ll16;
+ UChar *ll4;
+
+ /* stored and calculated CRCs */
+ UInt32 storedBlockCRC;
+ UInt32 storedCombinedCRC;
+ UInt32 calculatedBlockCRC;
+ UInt32 calculatedCombinedCRC;
+
+ /* map of bytes used in block */
+ Int32 nInUse;
+ Bool inUse[256];
+ Bool inUse16[16];
+ UChar seqToUnseq[256];
+
+ /* for decoding the MTF values */
+ UChar mtfa [MTFA_SIZE];
+ Int32 mtfbase[256 / MTFL_SIZE];
+ UChar selector [BZ_MAX_SELECTORS];
+ UChar selectorMtf[BZ_MAX_SELECTORS];
+ UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+
+ Int32 limit [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+ Int32 base [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+ Int32 perm [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+ Int32 minLens[BZ_N_GROUPS];
+
+ /* save area for scalars in the main decompress code */
+ Int32 save_i;
+ Int32 save_j;
+ Int32 save_t;
+ Int32 save_alphaSize;
+ Int32 save_nGroups;
+ Int32 save_nSelectors;
+ Int32 save_EOB;
+ Int32 save_groupNo;
+ Int32 save_groupPos;
+ Int32 save_nextSym;
+ Int32 save_nblockMAX;
+ Int32 save_nblock;
+ Int32 save_es;
+ Int32 save_N;
+ Int32 save_curr;
+ Int32 save_zt;
+ Int32 save_zn;
+ Int32 save_zvec;
+ Int32 save_zj;
+ Int32 save_gSel;
+ Int32 save_gMinlen;
+ Int32* save_gLimit;
+ Int32* save_gBase;
+ Int32* save_gPerm;
+
+ }
+ DState;
+
+
+
+/*-- Macros for decompression. --*/
+
+#define BZ_GET_FAST(cccc) \
+ /* c_tPos is unsigned, hence test < 0 is pointless. */ \
+ if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \
+ s->tPos = s->tt[s->tPos]; \
+ cccc = (UChar)(s->tPos & 0xff); \
+ s->tPos >>= 8;
+
+#define BZ_GET_FAST_C(cccc) \
+ /* c_tPos is unsigned, hence test < 0 is pointless. */ \
+ if (c_tPos >= (UInt32)100000 * (UInt32)ro_blockSize100k) return True; \
+ c_tPos = c_tt[c_tPos]; \
+ cccc = (UChar)(c_tPos & 0xff); \
+ c_tPos >>= 8;
+
+#define SET_LL4(i,n) \
+ { if (((i) & 0x1) == 0) \
+ s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0xf0) | (n); else \
+ s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0x0f) | ((n) << 4); \
+ }
+
+#define GET_LL4(i) \
+ ((((UInt32)(s->ll4[(i) >> 1])) >> (((i) << 2) & 0x4)) & 0xF)
+
+#define SET_LL(i,n) \
+ { s->ll16[i] = (UInt16)(n & 0x0000ffff); \
+ SET_LL4(i, n >> 16); \
+ }
+
+#define GET_LL(i) \
+ (((UInt32)s->ll16[i]) | (GET_LL4(i) << 16))
+
+#define BZ_GET_SMALL(cccc) \
+ /* c_tPos is unsigned, hence test < 0 is pointless. */ \
+ if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \
+ cccc = BZ2_indexIntoF ( s->tPos, s->cftab ); \
+ s->tPos = GET_LL(s->tPos);
+
+
+/*-- externs for decompression. --*/
+
+extern Int32
+BZ2_indexIntoF ( Int32, Int32* );
+
+extern Int32
+BZ2_decompress ( DState* );
+
+extern void
+BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*,
+ Int32, Int32, Int32 );
+
+
+#endif
+
+
+/*-- BZ_NO_STDIO seems to make NULL disappear on some platforms. --*/
+
+#ifdef BZ_NO_STDIO
+#ifndef NULL
+#define NULL 0
+#endif
+#endif
+
+
+/*-------------------------------------------------------------*/
+/*--- end bzlib_private.h ---*/
+/*-------------------------------------------------------------*/
diff --git a/Utilities/cmbzip2/bzmore b/Utilities/cmbzip2/bzmore
new file mode 100644
index 000000000..21b1de61c
--- /dev/null
+++ b/Utilities/cmbzip2/bzmore
@@ -0,0 +1,61 @@
+#!/bin/sh
+
+# Bzmore wrapped for bzip2,
+# adapted from zmore by Philippe Troin <phil@fifi.org> for Debian GNU/Linux.
+
+PATH="/usr/bin:$PATH"; export PATH
+
+prog=`echo $0 | sed 's|.*/||'`
+case "$prog" in
+ *less) more=less ;;
+ *) more=more ;;
+esac
+
+if test "`echo -n a`" = "-n a"; then
+ # looks like a SysV system:
+ n1=''; n2='\c'
+else
+ n1='-n'; n2=''
+fi
+oldtty=`stty -g 2>/dev/null`
+if stty -cbreak 2>/dev/null; then
+ cb='cbreak'; ncb='-cbreak'
+else
+ # 'stty min 1' resets eof to ^a on both SunOS and SysV!
+ cb='min 1 -icanon'; ncb='icanon eof ^d'
+fi
+if test $? -eq 0 -a -n "$oldtty"; then
+ trap 'stty $oldtty 2>/dev/null; exit' 0 2 3 5 10 13 15
+else
+ trap 'stty $ncb echo 2>/dev/null; exit' 0 2 3 5 10 13 15
+fi
+
+if test $# = 0; then
+ if test -t 0; then
+ echo usage: $prog files...
+ else
+ bzip2 -cdfq | eval $more
+ fi
+else
+ FIRST=1
+ for FILE
+ do
+ if test $FIRST -eq 0; then
+ echo $n1 "--More--(Next file: $FILE)$n2"
+ stty $cb -echo 2>/dev/null
+ ANS=`dd bs=1 count=1 2>/dev/null`
+ stty $ncb echo 2>/dev/null
+ echo " "
+ if test "$ANS" = 'e' -o "$ANS" = 'q'; then
+ exit
+ fi
+ fi
+ if test "$ANS" != 's'; then
+ echo "------> $FILE <------"
+ bzip2 -cdfq "$FILE" | eval $more
+ fi
+ if test -t; then
+ FIRST=0
+ fi
+ done
+fi
diff --git a/Utilities/cmbzip2/bzmore.1 b/Utilities/cmbzip2/bzmore.1
new file mode 100644
index 000000000..c6868ed5c
--- /dev/null
+++ b/Utilities/cmbzip2/bzmore.1
@@ -0,0 +1,152 @@
+.\"Shamelessly copied from zmore.1 by Philippe Troin <phil@fifi.org>
+.\"for Debian GNU/Linux
+.TH BZMORE 1
+.SH NAME
+bzmore, bzless \- file perusal filter for crt viewing of bzip2 compressed text
+.SH SYNOPSIS
+.B bzmore
+[ name ... ]
+.br
+.B bzless
+[ name ... ]
+.SH NOTE
+In the following description,
+.I bzless
+and
+.I less
+can be used interchangeably with
+.I bzmore
+and
+.I more.
+.SH DESCRIPTION
+.I Bzmore
+is a filter which allows examination of compressed or plain text files
+one screenful at a time on a soft-copy terminal.
+.I bzmore
+works on files compressed with
+.I bzip2
+and also on uncompressed files.
+If a file does not exist,
+.I bzmore
+looks for a file of the same name with the addition of a .bz2 suffix.
+.PP
+.I Bzmore
+normally pauses after each screenful, printing --More--
+at the bottom of the screen.
+If the user then types a carriage return, one more line is displayed.
+If the user hits a space,
+another screenful is displayed. Other possibilities are enumerated later.
+.PP
+.I Bzmore
+looks in the file
+.I /etc/termcap
+to determine terminal characteristics,
+and to determine the default window size.
+On a terminal capable of displaying 24 lines,
+the default window size is 22 lines.
+Other sequences which may be typed when
+.I bzmore
+pauses, and their effects, are as follows (\fIi\fP is an optional integer
+argument, defaulting to 1) :
+.PP
+.IP \fIi\|\fP<space>
+display
+.I i
+more lines, (or another screenful if no argument is given)
+.PP
+.IP ^D
+display 11 more lines (a ``scroll'').
+If
+.I i
+is given, then the scroll size is set to \fIi\|\fP.
+.PP
+.IP d
+same as ^D (control-D)
+.PP
+.IP \fIi\|\fPz
+same as typing a space except that \fIi\|\fP, if present, becomes the new
+window size. Note that the window size reverts back to the default at the
+end of the current file.
+.PP
+.IP \fIi\|\fPs
+skip \fIi\|\fP lines and print a screenful of lines
+.PP
+.IP \fIi\|\fPf
+skip \fIi\fP screenfuls and print a screenful of lines
+.PP
+.IP "q or Q"
+quit reading the current file; go on to the next (if any)
+.PP
+.IP "e or q"
+When the prompt --More--(Next file:
+.IR file )
+is printed, this command causes bzmore to exit.
+.PP
+.IP s
+When the prompt --More--(Next file:
+.IR file )
+is printed, this command causes bzmore to skip the next file and continue.
+.PP
+.IP =
+Display the current line number.
+.PP
+.IP \fIi\|\fP/expr
+search for the \fIi\|\fP-th occurrence of the regular expression \fIexpr.\fP
+If the pattern is not found,
+.I bzmore
+goes on to the next file (if any).
+Otherwise, a screenful is displayed, starting two lines before the place
+where the expression was found.
+The user's erase and kill characters may be used to edit the regular
+expression.
+Erasing back past the first column cancels the search command.
+.PP
+.IP \fIi\|\fPn
+search for the \fIi\|\fP-th occurrence of the last regular expression entered.
+.PP
+.IP !command
+invoke a shell with \fIcommand\|\fP.
+The character `!' in "command" are replaced with the
+previous shell command. The sequence "\\!" is replaced by "!".
+.PP
+.IP ":q or :Q"
+quit reading the current file; go on to the next (if any)
+(same as q or Q).
+.PP
+.IP .
+(dot) repeat the previous command.
+.PP
+The commands take effect immediately, i.e., it is not necessary to
+type a carriage return.
+Up to the time when the command character itself is given,
+the user may hit the line kill character to cancel the numerical
+argument being formed.
+In addition, the user may hit the erase character to redisplay the
+--More-- message.
+.PP
+At any time when output is being sent to the terminal, the user can
+hit the quit key (normally control\-\\).
+.I Bzmore
+will stop sending output, and will display the usual --More--
+prompt.
+The user may then enter one of the above commands in the normal manner.
+Unfortunately, some output is lost when this is done, due to the
+fact that any characters waiting in the terminal's output queue
+are flushed when the quit signal occurs.
+.PP
+The terminal is set to
+.I noecho
+mode by this program so that the output can be continuous.
+What you type will thus not show on your terminal, except for the / and !
+commands.
+.PP
+If the standard output is not a teletype, then
+.I bzmore
+acts just like
+.I bzcat,
+except that a header is printed before each file.
+.SH FILES
+.DT
+/etc/termcap Terminal data base
+.SH "SEE ALSO"
+more(1), less(1), bzip2(1), bzdiff(1), bzgrep(1)
diff --git a/Utilities/cmbzip2/compress.c b/Utilities/cmbzip2/compress.c
new file mode 100644
index 000000000..7d9b3da75
--- /dev/null
+++ b/Utilities/cmbzip2/compress.c
@@ -0,0 +1,672 @@
+
+/*-------------------------------------------------------------*/
+/*--- Compression machinery (not incl block sorting) ---*/
+/*--- compress.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
+
+ bzip2/libbzip2 version 1.0.5 of 10 December 2007
+ Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
+
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------ */
+
+
+/* CHANGES
+ 0.9.0 -- original version.
+ 0.9.0a/b -- no changes in this file.
+ 0.9.0c -- changed setting of nGroups in sendMTFValues()
+ so as to do a bit better on small files
+*/
+
+#include "bzlib_private.h"
+
+
+/*---------------------------------------------------*/
+/*--- Bit stream I/O ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+void BZ2_bsInitWrite ( EState* s )
+{
+ s->bsLive = 0;
+ s->bsBuff = 0;
+}
+
+
+/*---------------------------------------------------*/
+static
+void bsFinishWrite ( EState* s )
+{
+ while (s->bsLive > 0) {
+ s->zbits[s->numZ] = (UChar)(s->bsBuff >> 24);
+ s->numZ++;
+ s->bsBuff <<= 8;
+ s->bsLive -= 8;
+ }
+}
+
+
+/*---------------------------------------------------*/
+#define bsNEEDW(nz) \
+{ \
+ while (s->bsLive >= 8) { \
+ s->zbits[s->numZ] \
+ = (UChar)(s->bsBuff >> 24); \
+ s->numZ++; \
+ s->bsBuff <<= 8; \
+ s->bsLive -= 8; \
+ } \
+}
+
+
+/*---------------------------------------------------*/
+static
+__inline__
+void bsW ( EState* s, Int32 n, UInt32 v )
+{
+ bsNEEDW ( n );
+ s->bsBuff |= (v << (32 - s->bsLive - n));
+ s->bsLive += n;
+}
+
+
+/*---------------------------------------------------*/
+static
+void bsPutUInt32 ( EState* s, UInt32 u )
+{
+ bsW ( s, 8, (u >> 24) & 0xffL );
+ bsW ( s, 8, (u >> 16) & 0xffL );
+ bsW ( s, 8, (u >> 8) & 0xffL );
+ bsW ( s, 8, u & 0xffL );
+}
+
+
+/*---------------------------------------------------*/
+static
+void bsPutUChar ( EState* s, UChar c )
+{
+ bsW( s, 8, (UInt32)c );
+}
+
+
+/*---------------------------------------------------*/
+/*--- The back end proper ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+static
+void makeMaps_e ( EState* s )
+{
+ Int32 i;
+ s->nInUse = 0;
+ for (i = 0; i < 256; i++)
+ if (s->inUse[i]) {
+ s->unseqToSeq[i] = s->nInUse;
+ s->nInUse++;
+ }
+}
+
+
+/*---------------------------------------------------*/
+static
+void generateMTFValues ( EState* s )
+{
+ UChar yy[256];
+ Int32 i, j;
+ Int32 zPend;
+ Int32 wr;
+ Int32 EOB;
+
+ /*
+ After sorting (eg, here),
+ s->arr1 [ 0 .. s->nblock-1 ] holds sorted order,
+ and
+ ((UChar*)s->arr2) [ 0 .. s->nblock-1 ]
+ holds the original block data.
+
+ The first thing to do is generate the MTF values,
+ and put them in
+ ((UInt16*)s->arr1) [ 0 .. s->nblock-1 ].
+ Because there are strictly fewer or equal MTF values
+ than block values, ptr values in this area are overwritten
+ with MTF values only when they are no longer needed.
+
+ The final compressed bitstream is generated into the
+ area starting at
+ (UChar*) (&((UChar*)s->arr2)[s->nblock])
+
+ These storage aliases are set up in bzCompressInit(),
+ except for the last one, which is arranged in
+ compressBlock().
+ */
+ UInt32* ptr = s->ptr;
+ UChar* block = s->block;
+ UInt16* mtfv = s->mtfv;
+
+ makeMaps_e ( s );
+ EOB = s->nInUse+1;
+
+ for (i = 0; i <= EOB; i++) s->mtfFreq[i] = 0;
+
+ wr = 0;
+ zPend = 0;
+ for (i = 0; i < s->nInUse; i++) yy[i] = (UChar) i;
+
+ for (i = 0; i < s->nblock; i++) {
+ UChar ll_i;
+ AssertD ( wr <= i, "generateMTFValues(1)" );
+ j = ptr[i]-1; if (j < 0) j += s->nblock;
+ ll_i = s->unseqToSeq[block[j]];
+ AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" );
+
+ if (yy[0] == ll_i) {
+ zPend++;
+ } else {
+
+ if (zPend > 0) {
+ zPend--;
+ while (True) {
+ if (zPend & 1) {
+ mtfv[wr] = BZ_RUNB; wr++;
+ s->mtfFreq[BZ_RUNB]++;
+ } else {
+ mtfv[wr] = BZ_RUNA; wr++;
+ s->mtfFreq[BZ_RUNA]++;
+ }
+ if (zPend < 2) break;
+ zPend = (zPend - 2) / 2;
+ };
+ zPend = 0;
+ }
+ {
+ register UChar rtmp;
+ register UChar* ryy_j;
+ register UChar rll_i;
+ rtmp = yy[1];
+ yy[1] = yy[0];
+ ryy_j = &(yy[1]);
+ rll_i = ll_i;
+ while ( rll_i != rtmp ) {
+ register UChar rtmp2;
+ ryy_j++;
+ rtmp2 = rtmp;
+ rtmp = *ryy_j;
+ *ryy_j = rtmp2;
+ };
+ yy[0] = rtmp;
+ j = ryy_j - &(yy[0]);
+ mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++;
+ }
+
+ }
+ }
+
+ if (zPend > 0) {
+ zPend--;
+ while (True) {
+ if (zPend & 1) {
+ mtfv[wr] = BZ_RUNB; wr++;
+ s->mtfFreq[BZ_RUNB]++;
+ } else {
+ mtfv[wr] = BZ_RUNA; wr++;
+ s->mtfFreq[BZ_RUNA]++;
+ }
+ if (zPend < 2) break;
+ zPend = (zPend - 2) / 2;
+ };
+ zPend = 0;
+ }
+
+ mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++;
+
+ s->nMTF = wr;
+}
+
+
+/*---------------------------------------------------*/
+#define BZ_LESSER_ICOST 0
+#define BZ_GREATER_ICOST 15
+
+static
+void sendMTFValues ( EState* s )
+{
+ Int32 v, t, i, j, gs, ge, totc, bt, bc, iter;
+ Int32 nSelectors, alphaSize, minLen, maxLen, selCtr;
+ Int32 nGroups, nBytes;
+
+ /*--
+ UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+ is a global since the decoder also needs it.
+
+ Int32 code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+ Int32 rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+ are also globals only used in this proc.
+ Made global to keep stack frame size small.
+ --*/
+
+
+ UInt16 cost[BZ_N_GROUPS];
+ Int32 fave[BZ_N_GROUPS];
+
+ UInt16* mtfv = s->mtfv;
+
+ if (s->verbosity >= 3)
+ VPrintf3( " %d in block, %d after MTF & 1-2 coding, "
+ "%d+2 syms in use\n",
+ s->nblock, s->nMTF, s->nInUse );
+
+ alphaSize = s->nInUse+2;
+ for (t = 0; t < BZ_N_GROUPS; t++)
+ for (v = 0; v < alphaSize; v++)
+ s->len[t][v] = BZ_GREATER_ICOST;
+
+ /*--- Decide how many coding tables to use ---*/
+ AssertH ( s->nMTF > 0, 3001 );
+ if (s->nMTF < 200) nGroups = 2; else
+ if (s->nMTF < 600) nGroups = 3; else
+ if (s->nMTF < 1200) nGroups = 4; else
+ if (s->nMTF < 2400) nGroups = 5; else
+ nGroups = 6;
+
+ /*--- Generate an initial set of coding tables ---*/
+ {
+ Int32 nPart, remF, tFreq, aFreq;
+
+ nPart = nGroups;
+ remF = s->nMTF;
+ gs = 0;
+ while (nPart > 0) {
+ tFreq = remF / nPart;
+ ge = gs-1;
+ aFreq = 0;
+ while (aFreq < tFreq && ge < alphaSize-1) {
+ ge++;
+ aFreq += s->mtfFreq[ge];
+ }
+
+ if (ge > gs
+ && nPart != nGroups && nPart != 1
+ && ((nGroups-nPart) % 2 == 1)) {
+ aFreq -= s->mtfFreq[ge];
+ ge--;
+ }
+
+ if (s->verbosity >= 3)
+ VPrintf5( " initial group %d, [%d .. %d], "
+ "has %d syms (%4.1f%%)\n",
+ nPart, gs, ge, aFreq,
+ (100.0 * (float)aFreq) / (float)(s->nMTF) );
+
+ for (v = 0; v < alphaSize; v++)
+ if (v >= gs && v <= ge)
+ s->len[nPart-1][v] = BZ_LESSER_ICOST; else
+ s->len[nPart-1][v] = BZ_GREATER_ICOST;
+
+ nPart--;
+ gs = ge+1;
+ remF -= aFreq;
+ }
+ }
+
+ /*---
+ Iterate up to BZ_N_ITERS times to improve the tables.
+ ---*/
+ for (iter = 0; iter < BZ_N_ITERS; iter++) {
+
+ for (t = 0; t < nGroups; t++) fave[t] = 0;
+
+ for (t = 0; t < nGroups; t++)
+ for (v = 0; v < alphaSize; v++)
+ s->rfreq[t][v] = 0;
+
+ /*---
+ Set up an auxiliary length table which is used to fast-track
+ the common case (nGroups == 6).
+ ---*/
+ if (nGroups == 6) {
+ for (v = 0; v < alphaSize; v++) {
+ s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v];
+ s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v];
+ s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v];
+ }
+ }
+
+ nSelectors = 0;
+ totc = 0;
+ gs = 0;
+ while (True) {
+
+ /*--- Set group start & end marks. --*/
+ if (gs >= s->nMTF) break;
+ ge = gs + BZ_G_SIZE - 1;
+ if (ge >= s->nMTF) ge = s->nMTF-1;
+
+ /*--
+ Calculate the cost of this group as coded
+ by each of the coding tables.
+ --*/
+ for (t = 0; t < nGroups; t++) cost[t] = 0;
+
+ if (nGroups == 6 && 50 == ge-gs+1) {
+ /*--- fast track the common case ---*/
+ register UInt32 cost01, cost23, cost45;
+ register UInt16 icv;
+ cost01 = cost23 = cost45 = 0;
+
+# define BZ_ITER(nn) \
+ icv = mtfv[gs+(nn)]; \
+ cost01 += s->len_pack[icv][0]; \
+ cost23 += s->len_pack[icv][1]; \
+ cost45 += s->len_pack[icv][2]; \
+
+ BZ_ITER(0); BZ_ITER(1); BZ_ITER(2); BZ_ITER(3); BZ_ITER(4);
+ BZ_ITER(5); BZ_ITER(6); BZ_ITER(7); BZ_ITER(8); BZ_ITER(9);
+ BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14);
+ BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19);
+ BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24);
+ BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29);
+ BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34);
+ BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39);
+ BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44);
+ BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49);
+
+# undef BZ_ITER
+
+ cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16;
+ cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16;
+ cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16;
+
+ } else {
+ /*--- slow version which correctly handles all situations ---*/
+ for (i = gs; i <= ge; i++) {
+ UInt16 icv = mtfv[i];
+ for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv];
+ }
+ }
+
+ /*--
+ Find the coding table which is best for this group,
+ and record its identity in the selector table.
+ --*/
+ bc = 999999999; bt = -1;
+ for (t = 0; t < nGroups; t++)
+ if (cost[t] < bc) { bc = cost[t]; bt = t; };
+ totc += bc;
+ fave[bt]++;
+ s->selector[nSelectors] = bt;
+ nSelectors++;
+
+ /*--
+ Increment the symbol frequencies for the selected table.
+ --*/
+ if (nGroups == 6 && 50 == ge-gs+1) {
+ /*--- fast track the common case ---*/
+
+# define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++
+
+ BZ_ITUR(0); BZ_ITUR(1); BZ_ITUR(2); BZ_ITUR(3); BZ_ITUR(4);
+ BZ_ITUR(5); BZ_ITUR(6); BZ_ITUR(7); BZ_ITUR(8); BZ_ITUR(9);
+ BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14);
+ BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19);
+ BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24);
+ BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29);
+ BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34);
+ BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39);
+ BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44);
+ BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49);
+
+# undef BZ_ITUR
+
+ } else {
+ /*--- slow version which correctly handles all situations ---*/
+ for (i = gs; i <= ge; i++)
+ s->rfreq[bt][ mtfv[i] ]++;
+ }
+
+ gs = ge+1;
+ }
+ if (s->verbosity >= 3) {
+ VPrintf2 ( " pass %d: size is %d, grp uses are ",
+ iter+1, totc/8 );
+ for (t = 0; t < nGroups; t++)
+ VPrintf1 ( "%d ", fave[t] );
+ VPrintf0 ( "\n" );
+ }
+
+ /*--
+ Recompute the tables based on the accumulated frequencies.
+ --*/
+ /* maxLen was changed from 20 to 17 in bzip2-1.0.3. See
+ comment in huffman.c for details. */
+ for (t = 0; t < nGroups; t++)
+ BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]),
+ alphaSize, 17 /*20*/ );
+ }
+
+
+ AssertH( nGroups < 8, 3002 );
+ AssertH( nSelectors < 32768 &&
+ nSelectors <= (2 + (900000 / BZ_G_SIZE)),
+ 3003 );
+
+
+ /*--- Compute MTF values for the selectors. ---*/
+ {
+ UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp;
+ for (i = 0; i < nGroups; i++) pos[i] = i;
+ for (i = 0; i < nSelectors; i++) {
+ ll_i = s->selector[i];
+ j = 0;
+ tmp = pos[j];
+ while ( ll_i != tmp ) {
+ j++;
+ tmp2 = tmp;
+ tmp = pos[j];
+ pos[j] = tmp2;
+ };
+ pos[0] = tmp;
+ s->selectorMtf[i] = j;
+ }
+ };
+
+ /*--- Assign actual codes for the tables. --*/
+ for (t = 0; t < nGroups; t++) {
+ minLen = 32;
+ maxLen = 0;
+ for (i = 0; i < alphaSize; i++) {
+ if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
+ if (s->len[t][i] < minLen) minLen = s->len[t][i];
+ }
+ AssertH ( !(maxLen > 17 /*20*/ ), 3004 );
+ AssertH ( !(minLen < 1), 3005 );
+ BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]),
+ minLen, maxLen, alphaSize );
+ }
+
+ /*--- Transmit the mapping table. ---*/
+ {
+ Bool inUse16[16];
+ for (i = 0; i < 16; i++) {
+ inUse16[i] = False;
+ for (j = 0; j < 16; j++)
+ if (s->inUse[i * 16 + j]) inUse16[i] = True;
+ }
+
+ nBytes = s->numZ;
+ for (i = 0; i < 16; i++)
+ if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0);
+
+ for (i = 0; i < 16; i++)
+ if (inUse16[i])
+ for (j = 0; j < 16; j++) {
+ if (s->inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0);
+ }
+
+ if (s->verbosity >= 3)
+ VPrintf1( " bytes: mapping %d, ", s->numZ-nBytes );
+ }
+
+ /*--- Now the selectors. ---*/
+ nBytes = s->numZ;
+ bsW ( s, 3, nGroups );
+ bsW ( s, 15, nSelectors );
+ for (i = 0; i < nSelectors; i++) {
+ for (j = 0; j < s->selectorMtf[i]; j++) bsW(s,1,1);
+ bsW(s,1,0);
+ }
+ if (s->verbosity >= 3)
+ VPrintf1( "selectors %d, ", s->numZ-nBytes );
+
+ /*--- Now the coding tables. ---*/
+ nBytes = s->numZ;
+
+ for (t = 0; t < nGroups; t++) {
+ Int32 curr = s->len[t][0];
+ bsW ( s, 5, curr );
+ for (i = 0; i < alphaSize; i++) {
+ while (curr < s->len[t][i]) { bsW(s,2,2); curr++; /* 10 */ };
+ while (curr > s->len[t][i]) { bsW(s,2,3); curr--; /* 11 */ };
+ bsW ( s, 1, 0 );
+ }
+ }
+
+ if (s->verbosity >= 3)
+ VPrintf1 ( "code lengths %d, ", s->numZ-nBytes );
+
+ /*--- And finally, the block data proper ---*/
+ nBytes = s->numZ;
+ selCtr = 0;
+ gs = 0;
+ while (True) {
+ if (gs >= s->nMTF) break;
+ ge = gs + BZ_G_SIZE - 1;
+ if (ge >= s->nMTF) ge = s->nMTF-1;
+ AssertH ( s->selector[selCtr] < nGroups, 3006 );
+
+ if (nGroups == 6 && 50 == ge-gs+1) {
+ /*--- fast track the common case ---*/
+ UInt16 mtfv_i;
+ UChar* s_len_sel_selCtr
+ = &(s->len[s->selector[selCtr]][0]);
+ Int32* s_code_sel_selCtr
+ = &(s->code[s->selector[selCtr]][0]);
+
+# define BZ_ITAH(nn) \
+ mtfv_i = mtfv[gs+(nn)]; \
+ bsW ( s, \
+ s_len_sel_selCtr[mtfv_i], \
+ s_code_sel_selCtr[mtfv_i] )
+
+ BZ_ITAH(0); BZ_ITAH(1); BZ_ITAH(2); BZ_ITAH(3); BZ_ITAH(4);
+ BZ_ITAH(5); BZ_ITAH(6); BZ_ITAH(7); BZ_ITAH(8); BZ_ITAH(9);
+ BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14);
+ BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19);
+ BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24);
+ BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29);
+ BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34);
+ BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39);
+ BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44);
+ BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49);
+
+# undef BZ_ITAH
+
+ } else {
+ /*--- slow version which correctly handles all situations ---*/
+ for (i = gs; i <= ge; i++) {
+ bsW ( s,
+ s->len [s->selector[selCtr]] [mtfv[i]],
+ s->code [s->selector[selCtr]] [mtfv[i]] );
+ }
+ }
+
+
+ gs = ge+1;
+ selCtr++;
+ }
+ AssertH( selCtr == nSelectors, 3007 );
+
+ if (s->verbosity >= 3)
+ VPrintf1( "codes %d\n", s->numZ-nBytes );
+}
+
+
+/*---------------------------------------------------*/
+void BZ2_compressBlock ( EState* s, Bool is_last_block )
+{
+ if (s->nblock > 0) {
+
+ BZ_FINALISE_CRC ( s->blockCRC );
+ s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31);
+ s->combinedCRC ^= s->blockCRC;
+ if (s->blockNo > 1) s->numZ = 0;
+
+ if (s->verbosity >= 2)
+ VPrintf4( " block %d: crc = 0x%08x, "
+ "combined CRC = 0x%08x, size = %d\n",
+ s->blockNo, s->blockCRC, s->combinedCRC, s->nblock );
+
+ BZ2_blockSort ( s );
+ }
+
+ s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]);
+
+ /*-- If this is the first block, create the stream header. --*/
+ if (s->blockNo == 1) {
+ BZ2_bsInitWrite ( s );
+ bsPutUChar ( s, BZ_HDR_B );
+ bsPutUChar ( s, BZ_HDR_Z );
+ bsPutUChar ( s, BZ_HDR_h );
+ bsPutUChar ( s, (UChar)(BZ_HDR_0 + s->blockSize100k) );
+ }
+
+ if (s->nblock > 0) {
+
+ bsPutUChar ( s, 0x31 ); bsPutUChar ( s, 0x41 );
+ bsPutUChar ( s, 0x59 ); bsPutUChar ( s, 0x26 );
+ bsPutUChar ( s, 0x53 ); bsPutUChar ( s, 0x59 );
+
+ /*-- Now the block's CRC, so it is in a known place. --*/
+ bsPutUInt32 ( s, s->blockCRC );
+
+ /*--
+ Now a single bit indicating (non-)randomisation.
+ As of version 0.9.5, we use a better sorting algorithm
+ which makes randomisation unnecessary. So always set
+ the randomised bit to 'no'. Of course, the decoder
+ still needs to be able to handle randomised blocks
+ so as to maintain backwards compatibility with
+ older versions of bzip2.
+ --*/
+ bsW(s,1,0);
+
+ bsW ( s, 24, s->origPtr );
+ generateMTFValues ( s );
+ sendMTFValues ( s );
+ }
+
+
+ /*-- If this is the last block, add the stream trailer. --*/
+ if (is_last_block) {
+
+ bsPutUChar ( s, 0x17 ); bsPutUChar ( s, 0x72 );
+ bsPutUChar ( s, 0x45 ); bsPutUChar ( s, 0x38 );
+ bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 );
+ bsPutUInt32 ( s, s->combinedCRC );
+ if (s->verbosity >= 2)
+ VPrintf1( " final combined CRC = 0x%08x\n ", s->combinedCRC );
+ bsFinishWrite ( s );
+ }
+}
+
+
+/*-------------------------------------------------------------*/
+/*--- end compress.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/Utilities/cmbzip2/crctable.c b/Utilities/cmbzip2/crctable.c
new file mode 100644
index 000000000..215687b2c
--- /dev/null
+++ b/Utilities/cmbzip2/crctable.c
@@ -0,0 +1,104 @@
+
+/*-------------------------------------------------------------*/
+/*--- Table for doing CRCs ---*/
+/*--- crctable.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
+
+ bzip2/libbzip2 version 1.0.5 of 10 December 2007
+ Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
+
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------ */
+
+
+#include "bzlib_private.h"
+
+/*--
+ I think this is an implementation of the AUTODIN-II,
+ Ethernet & FDDI 32-bit CRC standard. Vaguely derived
+ from code by Rob Warnock, in Section 51 of the
+ comp.compression FAQ.
+--*/
+
+UInt32 BZ2_crc32Table[256] = {
+
+ /*-- Ugly, innit? --*/
+
+ 0x00000000L, 0x04c11db7L, 0x09823b6eL, 0x0d4326d9L,
+ 0x130476dcL, 0x17c56b6bL, 0x1a864db2L, 0x1e475005L,
+ 0x2608edb8L, 0x22c9f00fL, 0x2f8ad6d6L, 0x2b4bcb61L,
+ 0x350c9b64L, 0x31cd86d3L, 0x3c8ea00aL, 0x384fbdbdL,
+ 0x4c11db70L, 0x48d0c6c7L, 0x4593e01eL, 0x4152fda9L,
+ 0x5f15adacL, 0x5bd4b01bL, 0x569796c2L, 0x52568b75L,
+ 0x6a1936c8L, 0x6ed82b7fL, 0x639b0da6L, 0x675a1011L,
+ 0x791d4014L, 0x7ddc5da3L, 0x709f7b7aL, 0x745e66cdL,
+ 0x9823b6e0L, 0x9ce2ab57L, 0x91a18d8eL, 0x95609039L,
+ 0x8b27c03cL, 0x8fe6dd8bL, 0x82a5fb52L, 0x8664e6e5L,
+ 0xbe2b5b58L, 0xbaea46efL, 0xb7a96036L, 0xb3687d81L,
+ 0xad2f2d84L, 0xa9ee3033L, 0xa4ad16eaL, 0xa06c0b5dL,
+ 0xd4326d90L, 0xd0f37027L, 0xddb056feL, 0xd9714b49L,
+ 0xc7361b4cL, 0xc3f706fbL, 0xceb42022L, 0xca753d95L,
+ 0xf23a8028L, 0xf6fb9d9fL, 0xfbb8bb46L, 0xff79a6f1L,
+ 0xe13ef6f4L, 0xe5ffeb43L, 0xe8bccd9aL, 0xec7dd02dL,
+ 0x34867077L, 0x30476dc0L, 0x3d044b19L, 0x39c556aeL,
+ 0x278206abL, 0x23431b1cL, 0x2e003dc5L, 0x2ac12072L,
+ 0x128e9dcfL, 0x164f8078L, 0x1b0ca6a1L, 0x1fcdbb16L,
+ 0x018aeb13L, 0x054bf6a4L, 0x0808d07dL, 0x0cc9cdcaL,
+ 0x7897ab07L, 0x7c56b6b0L, 0x71159069L, 0x75d48ddeL,
+ 0x6b93dddbL, 0x6f52c06cL, 0x6211e6b5L, 0x66d0fb02L,
+ 0x5e9f46bfL, 0x5a5e5b08L, 0x571d7dd1L, 0x53dc6066L,
+ 0x4d9b3063L, 0x495a2dd4L, 0x44190b0dL, 0x40d816baL,
+ 0xaca5c697L, 0xa864db20L, 0xa527fdf9L, 0xa1e6e04eL,
+ 0xbfa1b04bL, 0xbb60adfcL, 0xb6238b25L, 0xb2e29692L,
+ 0x8aad2b2fL, 0x8e6c3698L, 0x832f1041L, 0x87ee0df6L,
+ 0x99a95df3L, 0x9d684044L, 0x902b669dL, 0x94ea7b2aL,
+ 0xe0b41de7L, 0xe4750050L, 0xe9362689L, 0xedf73b3eL,
+ 0xf3b06b3bL, 0xf771768cL, 0xfa325055L, 0xfef34de2L,
+ 0xc6bcf05fL, 0xc27dede8L, 0xcf3ecb31L, 0xcbffd686L,
+ 0xd5b88683L, 0xd1799b34L, 0xdc3abdedL, 0xd8fba05aL,
+ 0x690ce0eeL, 0x6dcdfd59L, 0x608edb80L, 0x644fc637L,
+ 0x7a089632L, 0x7ec98b85L, 0x738aad5cL, 0x774bb0ebL,
+ 0x4f040d56L, 0x4bc510e1L, 0x46863638L, 0x42472b8fL,
+ 0x5c007b8aL, 0x58c1663dL, 0x558240e4L, 0x51435d53L,
+ 0x251d3b9eL, 0x21dc2629L, 0x2c9f00f0L, 0x285e1d47L,
+ 0x36194d42L, 0x32d850f5L, 0x3f9b762cL, 0x3b5a6b9bL,
+ 0x0315d626L, 0x07d4cb91L, 0x0a97ed48L, 0x0e56f0ffL,
+ 0x1011a0faL, 0x14d0bd4dL, 0x19939b94L, 0x1d528623L,
+ 0xf12f560eL, 0xf5ee4bb9L, 0xf8ad6d60L, 0xfc6c70d7L,
+ 0xe22b20d2L, 0xe6ea3d65L, 0xeba91bbcL, 0xef68060bL,
+ 0xd727bbb6L, 0xd3e6a601L, 0xdea580d8L, 0xda649d6fL,
+ 0xc423cd6aL, 0xc0e2d0ddL, 0xcda1f604L, 0xc960ebb3L,
+ 0xbd3e8d7eL, 0xb9ff90c9L, 0xb4bcb610L, 0xb07daba7L,
+ 0xae3afba2L, 0xaafbe615L, 0xa7b8c0ccL, 0xa379dd7bL,
+ 0x9b3660c6L, 0x9ff77d71L, 0x92b45ba8L, 0x9675461fL,
+ 0x8832161aL, 0x8cf30badL, 0x81b02d74L, 0x857130c3L,
+ 0x5d8a9099L, 0x594b8d2eL, 0x5408abf7L, 0x50c9b640L,
+ 0x4e8ee645L, 0x4a4ffbf2L, 0x470cdd2bL, 0x43cdc09cL,
+ 0x7b827d21L, 0x7f436096L, 0x7200464fL, 0x76c15bf8L,
+ 0x68860bfdL, 0x6c47164aL, 0x61043093L, 0x65c52d24L,
+ 0x119b4be9L, 0x155a565eL, 0x18197087L, 0x1cd86d30L,
+ 0x029f3d35L, 0x065e2082L, 0x0b1d065bL, 0x0fdc1becL,
+ 0x3793a651L, 0x3352bbe6L, 0x3e119d3fL, 0x3ad08088L,
+ 0x2497d08dL, 0x2056cd3aL, 0x2d15ebe3L, 0x29d4f654L,
+ 0xc5a92679L, 0xc1683bceL, 0xcc2b1d17L, 0xc8ea00a0L,
+ 0xd6ad50a5L, 0xd26c4d12L, 0xdf2f6bcbL, 0xdbee767cL,
+ 0xe3a1cbc1L, 0xe760d676L, 0xea23f0afL, 0xeee2ed18L,
+ 0xf0a5bd1dL, 0xf464a0aaL, 0xf9278673L, 0xfde69bc4L,
+ 0x89b8fd09L, 0x8d79e0beL, 0x803ac667L, 0x84fbdbd0L,
+ 0x9abc8bd5L, 0x9e7d9662L, 0x933eb0bbL, 0x97ffad0cL,
+ 0xafb010b1L, 0xab710d06L, 0xa6322bdfL, 0xa2f33668L,
+ 0xbcb4666dL, 0xb8757bdaL, 0xb5365d03L, 0xb1f740b4L
+};
+
+
+/*-------------------------------------------------------------*/
+/*--- end crctable.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/Utilities/cmbzip2/decompress.c b/Utilities/cmbzip2/decompress.c
new file mode 100644
index 000000000..bba5e0fa3
--- /dev/null
+++ b/Utilities/cmbzip2/decompress.c
@@ -0,0 +1,626 @@
+
+/*-------------------------------------------------------------*/
+/*--- Decompression machinery ---*/
+/*--- decompress.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
+
+ bzip2/libbzip2 version 1.0.5 of 10 December 2007
+ Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
+
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------ */
+
+
+#include "bzlib_private.h"
+
+
+/*---------------------------------------------------*/
+static
+void makeMaps_d ( DState* s )
+{
+ Int32 i;
+ s->nInUse = 0;
+ for (i = 0; i < 256; i++)
+ if (s->inUse[i]) {
+ s->seqToUnseq[s->nInUse] = i;
+ s->nInUse++;
+ }
+}
+
+
+/*---------------------------------------------------*/
+#define RETURN(rrr) \
+ { retVal = rrr; goto save_state_and_return; };
+
+#define GET_BITS(lll,vvv,nnn) \
+ case lll: s->state = lll; \
+ while (True) { \
+ if (s->bsLive >= nnn) { \
+ UInt32 v; \
+ v = (s->bsBuff >> \
+ (s->bsLive-nnn)) & ((1 << nnn)-1); \
+ s->bsLive -= nnn; \
+ vvv = v; \
+ break; \
+ } \
+ if (s->strm->avail_in == 0) RETURN(BZ_OK); \
+ s->bsBuff \
+ = (s->bsBuff << 8) | \
+ ((UInt32) \
+ (*((UChar*)(s->strm->next_in)))); \
+ s->bsLive += 8; \
+ s->strm->next_in++; \
+ s->strm->avail_in--; \
+ s->strm->total_in_lo32++; \
+ if (s->strm->total_in_lo32 == 0) \
+ s->strm->total_in_hi32++; \
+ }
+
+#define GET_UCHAR(lll,uuu) \
+ GET_BITS(lll,uuu,8)
+
+#define GET_BIT(lll,uuu) \
+ GET_BITS(lll,uuu,1)
+
+/*---------------------------------------------------*/
+#define GET_MTF_VAL(label1,label2,lval) \
+{ \
+ if (groupPos == 0) { \
+ groupNo++; \
+ if (groupNo >= nSelectors) \
+ RETURN(BZ_DATA_ERROR); \
+ groupPos = BZ_G_SIZE; \
+ gSel = s->selector[groupNo]; \
+ gMinlen = s->minLens[gSel]; \
+ gLimit = &(s->limit[gSel][0]); \
+ gPerm = &(s->perm[gSel][0]); \
+ gBase = &(s->base[gSel][0]); \
+ } \
+ groupPos--; \
+ zn = gMinlen; \
+ GET_BITS(label1, zvec, zn); \
+ while (1) { \
+ if (zn > 20 /* the longest code */) \
+ RETURN(BZ_DATA_ERROR); \
+ if (zvec <= gLimit[zn]) break; \
+ zn++; \
+ GET_BIT(label2, zj); \
+ zvec = (zvec << 1) | zj; \
+ }; \
+ if (zvec - gBase[zn] < 0 \
+ || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE) \
+ RETURN(BZ_DATA_ERROR); \
+ lval = gPerm[zvec - gBase[zn]]; \
+}
+
+
+/*---------------------------------------------------*/
+Int32 BZ2_decompress ( DState* s )
+{
+ UChar uc;
+ Int32 retVal;
+ Int32 minLen, maxLen;
+ bz_stream* strm = s->strm;
+
+ /* stuff that needs to be saved/restored */
+ Int32 i;
+ Int32 j;
+ Int32 t;
+ Int32 alphaSize;
+ Int32 nGroups;
+ Int32 nSelectors;
+ Int32 EOB;
+ Int32 groupNo;
+ Int32 groupPos;
+ Int32 nextSym;
+ Int32 nblockMAX;
+ Int32 nblock;
+ Int32 es;
+ Int32 N;
+ Int32 curr;
+ Int32 zt;
+ Int32 zn;
+ Int32 zvec;
+ Int32 zj;
+ Int32 gSel;
+ Int32 gMinlen;
+ Int32* gLimit;
+ Int32* gBase;
+ Int32* gPerm;
+
+ if (s->state == BZ_X_MAGIC_1) {
+ /*initialise the save area*/
+ s->save_i = 0;
+ s->save_j = 0;
+ s->save_t = 0;
+ s->save_alphaSize = 0;
+ s->save_nGroups = 0;
+ s->save_nSelectors = 0;
+ s->save_EOB = 0;
+ s->save_groupNo = 0;
+ s->save_groupPos = 0;
+ s->save_nextSym = 0;
+ s->save_nblockMAX = 0;
+ s->save_nblock = 0;
+ s->save_es = 0;
+ s->save_N = 0;
+ s->save_curr = 0;
+ s->save_zt = 0;
+ s->save_zn = 0;
+ s->save_zvec = 0;
+ s->save_zj = 0;
+ s->save_gSel = 0;
+ s->save_gMinlen = 0;
+ s->save_gLimit = NULL;
+ s->save_gBase = NULL;
+ s->save_gPerm = NULL;
+ }
+
+ /*restore from the save area*/
+ i = s->save_i;
+ j = s->save_j;
+ t = s->save_t;
+ alphaSize = s->save_alphaSize;
+ nGroups = s->save_nGroups;
+ nSelectors = s->save_nSelectors;
+ EOB = s->save_EOB;
+ groupNo = s->save_groupNo;
+ groupPos = s->save_groupPos;
+ nextSym = s->save_nextSym;
+ nblockMAX = s->save_nblockMAX;
+ nblock = s->save_nblock;
+ es = s->save_es;
+ N = s->save_N;
+ curr = s->save_curr;
+ zt = s->save_zt;
+ zn = s->save_zn;
+ zvec = s->save_zvec;
+ zj = s->save_zj;
+ gSel = s->save_gSel;
+ gMinlen = s->save_gMinlen;
+ gLimit = s->save_gLimit;
+ gBase = s->save_gBase;
+ gPerm = s->save_gPerm;
+
+ retVal = BZ_OK;
+
+ switch (s->state) {
+
+ GET_UCHAR(BZ_X_MAGIC_1, uc);
+ if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC);
+
+ GET_UCHAR(BZ_X_MAGIC_2, uc);
+ if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC);
+
+ GET_UCHAR(BZ_X_MAGIC_3, uc)
+ if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC);
+
+ GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8)
+ if (s->blockSize100k < (BZ_HDR_0 + 1) ||
+ s->blockSize100k > (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC);
+ s->blockSize100k -= BZ_HDR_0;
+
+ if (s->smallDecompress) {
+ s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) );
+ s->ll4 = BZALLOC(
+ ((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar)
+ );
+ if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR);
+ } else {
+ s->tt = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) );
+ if (s->tt == NULL) RETURN(BZ_MEM_ERROR);
+ }
+
+ GET_UCHAR(BZ_X_BLKHDR_1, uc);
+
+ if (uc == 0x17) goto endhdr_2;
+ if (uc != 0x31) RETURN(BZ_DATA_ERROR);
+ GET_UCHAR(BZ_X_BLKHDR_2, uc);
+ if (uc != 0x41) RETURN(BZ_DATA_ERROR);
+ GET_UCHAR(BZ_X_BLKHDR_3, uc);
+ if (uc != 0x59) RETURN(BZ_DATA_ERROR);
+ GET_UCHAR(BZ_X_BLKHDR_4, uc);
+ if (uc != 0x26) RETURN(BZ_DATA_ERROR);
+ GET_UCHAR(BZ_X_BLKHDR_5, uc);
+ if (uc != 0x53) RETURN(BZ_DATA_ERROR);
+ GET_UCHAR(BZ_X_BLKHDR_6, uc);
+ if (uc != 0x59) RETURN(BZ_DATA_ERROR);
+
+ s->currBlockNo++;
+ if (s->verbosity >= 2)
+ VPrintf1 ( "\n [%d: huff+mtf ", s->currBlockNo );
+
+ s->storedBlockCRC = 0;
+ GET_UCHAR(BZ_X_BCRC_1, uc);
+ s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
+ GET_UCHAR(BZ_X_BCRC_2, uc);
+ s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
+ GET_UCHAR(BZ_X_BCRC_3, uc);
+ s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
+ GET_UCHAR(BZ_X_BCRC_4, uc);
+ s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
+
+ GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1);
+
+ s->origPtr = 0;
+ GET_UCHAR(BZ_X_ORIGPTR_1, uc);
+ s->origPtr = (s->origPtr << 8) | ((Int32)uc);
+ GET_UCHAR(BZ_X_ORIGPTR_2, uc);
+ s->origPtr = (s->origPtr << 8) | ((Int32)uc);
+ GET_UCHAR(BZ_X_ORIGPTR_3, uc);
+ s->origPtr = (s->origPtr << 8) | ((Int32)uc);
+
+ if (s->origPtr < 0)
+ RETURN(BZ_DATA_ERROR);
+ if (s->origPtr > 10 + 100000*s->blockSize100k)
+ RETURN(BZ_DATA_ERROR);
+
+ /*--- Receive the mapping table ---*/
+ for (i = 0; i < 16; i++) {
+ GET_BIT(BZ_X_MAPPING_1, uc);
+ if (uc == 1)
+ s->inUse16[i] = True; else
+ s->inUse16[i] = False;
+ }
+
+ for (i = 0; i < 256; i++) s->inUse[i] = False;
+
+ for (i = 0; i < 16; i++)
+ if (s->inUse16[i])
+ for (j = 0; j < 16; j++) {
+ GET_BIT(BZ_X_MAPPING_2, uc);
+ if (uc == 1) s->inUse[i * 16 + j] = True;
+ }
+ makeMaps_d ( s );
+ if (s->nInUse == 0) RETURN(BZ_DATA_ERROR);
+ alphaSize = s->nInUse+2;
+
+ /*--- Now the selectors ---*/
+ GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
+ if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR);
+ GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
+ if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
+ for (i = 0; i < nSelectors; i++) {
+ j = 0;
+ while (True) {
+ GET_BIT(BZ_X_SELECTOR_3, uc);
+ if (uc == 0) break;
+ j++;
+ if (j >= nGroups) RETURN(BZ_DATA_ERROR);
+ }
+ s->selectorMtf[i] = j;
+ }
+
+ /*--- Undo the MTF values for the selectors. ---*/
+ {
+ UChar pos[BZ_N_GROUPS], tmp, v;
+ for (v = 0; v < nGroups; v++) pos[v] = v;
+
+ for (i = 0; i < nSelectors; i++) {
+ v = s->selectorMtf[i];
+ tmp = pos[v];
+ while (v > 0) { pos[v] = pos[v-1]; v--; }
+ pos[0] = tmp;
+ s->selector[i] = tmp;
+ }
+ }
+
+ /*--- Now the coding tables ---*/
+ for (t = 0; t < nGroups; t++) {
+ GET_BITS(BZ_X_CODING_1, curr, 5);
+ for (i = 0; i < alphaSize; i++) {
+ while (True) {
+ if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR);
+ GET_BIT(BZ_X_CODING_2, uc);
+ if (uc == 0) break;
+ GET_BIT(BZ_X_CODING_3, uc);
+ if (uc == 0) curr++; else curr--;
+ }
+ s->len[t][i] = curr;
+ }
+ }
+
+ /*--- Create the Huffman decoding tables ---*/
+ for (t = 0; t < nGroups; t++) {
+ minLen = 32;
+ maxLen = 0;
+ for (i = 0; i < alphaSize; i++) {
+ if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
+ if (s->len[t][i] < minLen) minLen = s->len[t][i];
+ }
+ BZ2_hbCreateDecodeTables (
+ &(s->limit[t][0]),
+ &(s->base[t][0]),
+ &(s->perm[t][0]),
+ &(s->len[t][0]),
+ minLen, maxLen, alphaSize
+ );
+ s->minLens[t] = minLen;
+ }
+
+ /*--- Now the MTF values ---*/
+
+ EOB = s->nInUse+1;
+ nblockMAX = 100000 * s->blockSize100k;
+ groupNo = -1;
+ groupPos = 0;
+
+ for (i = 0; i <= 255; i++) s->unzftab[i] = 0;
+
+ /*-- MTF init --*/
+ {
+ Int32 ii, jj, kk;
+ kk = MTFA_SIZE-1;
+ for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) {
+ for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
+ s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj);
+ kk--;
+ }
+ s->mtfbase[ii] = kk + 1;
+ }
+ }
+ /*-- end MTF init --*/
+
+ nblock = 0;
+ GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
+
+ while (True) {
+
+ if (nextSym == EOB) break;
+
+ if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
+
+ es = -1;
+ N = 1;
+ do {
+ if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
+ if (nextSym == BZ_RUNB) es = es + (1+1) * N;
+ N = N * 2;
+ GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
+ }
+ while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
+
+ es++;
+ uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ];
+ s->unzftab[uc] += es;
+
+ if (s->smallDecompress)
+ while (es > 0) {
+ if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
+ s->ll16[nblock] = (UInt16)uc;
+ nblock++;
+ es--;
+ }
+ else
+ while (es > 0) {
+ if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
+ s->tt[nblock] = (UInt32)uc;
+ nblock++;
+ es--;
+ };
+
+ continue;
+
+ } else {
+
+ if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
+
+ /*-- uc = MTF ( nextSym-1 ) --*/
+ {
+ Int32 ii, jj, kk, pp, lno, off;
+ UInt32 nn;
+ nn = (UInt32)(nextSym - 1);
+
+ if (nn < MTFL_SIZE) {
+ /* avoid general-case expense */
+ pp = s->mtfbase[0];
+ uc = s->mtfa[pp+nn];
+ while (nn > 3) {
+ Int32 z = pp+nn;
+ s->mtfa[(z) ] = s->mtfa[(z)-1];
+ s->mtfa[(z)-1] = s->mtfa[(z)-2];
+ s->mtfa[(z)-2] = s->mtfa[(z)-3];
+ s->mtfa[(z)-3] = s->mtfa[(z)-4];
+ nn -= 4;
+ }
+ while (nn > 0) {
+ s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--;
+ };
+ s->mtfa[pp] = uc;
+ } else {
+ /* general case */
+ lno = nn / MTFL_SIZE;
+ off = nn % MTFL_SIZE;
+ pp = s->mtfbase[lno] + off;
+ uc = s->mtfa[pp];
+ while (pp > s->mtfbase[lno]) {
+ s->mtfa[pp] = s->mtfa[pp-1]; pp--;
+ };
+ s->mtfbase[lno]++;
+ while (lno > 0) {
+ s->mtfbase[lno]--;
+ s->mtfa[s->mtfbase[lno]]
+ = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1];
+ lno--;
+ }
+ s->mtfbase[0]--;
+ s->mtfa[s->mtfbase[0]] = uc;
+ if (s->mtfbase[0] == 0) {
+ kk = MTFA_SIZE-1;
+ for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) {
+ for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
+ s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj];
+ kk--;
+ }
+ s->mtfbase[ii] = kk + 1;
+ }
+ }
+ }
+ }
+ /*-- end uc = MTF ( nextSym-1 ) --*/
+
+ s->unzftab[s->seqToUnseq[uc]]++;
+ if (s->smallDecompress)
+ s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else
+ s->tt[nblock] = (UInt32)(s->seqToUnseq[uc]);
+ nblock++;
+
+ GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
+ continue;
+ }
+ }
+
+ /* Now we know what nblock is, we can do a better sanity
+ check on s->origPtr.
+ */
+ if (s->origPtr < 0 || s->origPtr >= nblock)
+ RETURN(BZ_DATA_ERROR);
+
+ /*-- Set up cftab to facilitate generation of T^(-1) --*/
+ s->cftab[0] = 0;
+ for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
+ for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
+ for (i = 0; i <= 256; i++) {
+ if (s->cftab[i] < 0 || s->cftab[i] > nblock) {
+ /* s->cftab[i] can legitimately be == nblock */
+ RETURN(BZ_DATA_ERROR);
+ }
+ }
+
+ s->state_out_len = 0;
+ s->state_out_ch = 0;
+ BZ_INITIALISE_CRC ( s->calculatedBlockCRC );
+ s->state = BZ_X_OUTPUT;
+ if (s->verbosity >= 2) VPrintf0 ( "rt+rld" );
+
+ if (s->smallDecompress) {
+
+ /*-- Make a copy of cftab, used in generation of T --*/
+ for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i];
+
+ /*-- compute the T vector --*/
+ for (i = 0; i < nblock; i++) {
+ uc = (UChar)(s->ll16[i]);
+ SET_LL(i, s->cftabCopy[uc]);
+ s->cftabCopy[uc]++;
+ }
+
+ /*-- Compute T^(-1) by pointer reversal on T --*/
+ i = s->origPtr;
+ j = GET_LL(i);
+ do {
+ Int32 tmp = GET_LL(j);
+ SET_LL(j, i);
+ i = j;
+ j = tmp;
+ }
+ while (i != s->origPtr);
+
+ s->tPos = s->origPtr;
+ s->nblock_used = 0;
+ if (s->blockRandomised) {
+ BZ_RAND_INIT_MASK;
+ BZ_GET_SMALL(s->k0); s->nblock_used++;
+ BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
+ } else {
+ BZ_GET_SMALL(s->k0); s->nblock_used++;
+ }
+
+ } else {
+
+ /*-- compute the T^(-1) vector --*/
+ for (i = 0; i < nblock; i++) {
+ uc = (UChar)(s->tt[i] & 0xff);
+ s->tt[s->cftab[uc]] |= (i << 8);
+ s->cftab[uc]++;
+ }
+
+ s->tPos = s->tt[s->origPtr] >> 8;
+ s->nblock_used = 0;
+ if (s->blockRandomised) {
+ BZ_RAND_INIT_MASK;
+ BZ_GET_FAST(s->k0); s->nblock_used++;
+ BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
+ } else {
+ BZ_GET_FAST(s->k0); s->nblock_used++;
+ }
+
+ }
+
+ RETURN(BZ_OK);
+
+
+
+ endhdr_2:
+
+ GET_UCHAR(BZ_X_ENDHDR_2, uc);
+ if (uc != 0x72) RETURN(BZ_DATA_ERROR);
+ GET_UCHAR(BZ_X_ENDHDR_3, uc);
+ if (uc != 0x45) RETURN(BZ_DATA_ERROR);
+ GET_UCHAR(BZ_X_ENDHDR_4, uc);
+ if (uc != 0x38) RETURN(BZ_DATA_ERROR);
+ GET_UCHAR(BZ_X_ENDHDR_5, uc);
+ if (uc != 0x50) RETURN(BZ_DATA_ERROR);
+ GET_UCHAR(BZ_X_ENDHDR_6, uc);
+ if (uc != 0x90) RETURN(BZ_DATA_ERROR);
+
+ s->storedCombinedCRC = 0;
+ GET_UCHAR(BZ_X_CCRC_1, uc);
+ s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
+ GET_UCHAR(BZ_X_CCRC_2, uc);
+ s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
+ GET_UCHAR(BZ_X_CCRC_3, uc);
+ s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
+ GET_UCHAR(BZ_X_CCRC_4, uc);
+ s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
+
+ s->state = BZ_X_IDLE;
+ RETURN(BZ_STREAM_END);
+
+ default: AssertH ( False, 4001 );
+ }
+
+ AssertH ( False, 4002 );
+
+ save_state_and_return:
+
+ s->save_i = i;
+ s->save_j = j;
+ s->save_t = t;
+ s->save_alphaSize = alphaSize;
+ s->save_nGroups = nGroups;
+ s->save_nSelectors = nSelectors;
+ s->save_EOB = EOB;
+ s->save_groupNo = groupNo;
+ s->save_groupPos = groupPos;
+ s->save_nextSym = nextSym;
+ s->save_nblockMAX = nblockMAX;
+ s->save_nblock = nblock;
+ s->save_es = es;
+ s->save_N = N;
+ s->save_curr = curr;
+ s->save_zt = zt;
+ s->save_zn = zn;
+ s->save_zvec = zvec;
+ s->save_zj = zj;
+ s->save_gSel = gSel;
+ s->save_gMinlen = gMinlen;
+ s->save_gLimit = gLimit;
+ s->save_gBase = gBase;
+ s->save_gPerm = gPerm;
+
+ return retVal;
+}
+
+
+/*-------------------------------------------------------------*/
+/*--- end decompress.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/Utilities/cmbzip2/dlltest.c b/Utilities/cmbzip2/dlltest.c
new file mode 100644
index 000000000..4e27da280
--- /dev/null
+++ b/Utilities/cmbzip2/dlltest.c
@@ -0,0 +1,175 @@
+/*
+ minibz2
+ libbz2.dll test program.
+ by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
+ This file is Public Domain. Welcome any email to me.
+
+ usage: minibz2 [-d] [-{1,2,..9}] [[srcfilename] destfilename]
+*/
+
+#define BZ_IMPORT
+#include <stdio.h>
+#include <stdlib.h>
+#include "bzlib.h"
+#ifdef _WIN32
+#include <io.h>
+#endif
+
+
+#ifdef _WIN32
+
+#define BZ2_LIBNAME "libbz2-1.0.2.DLL"
+
+#include <windows.h>
+static int BZ2DLLLoaded = 0;
+static HINSTANCE BZ2DLLhLib;
+int BZ2DLLLoadLibrary(void)
+{
+ HINSTANCE hLib;
+
+ if(BZ2DLLLoaded==1){return 0;}
+ hLib=LoadLibrary(BZ2_LIBNAME);
+ if(hLib == NULL){
+ fprintf(stderr,"Can't load %s\n",BZ2_LIBNAME);
+ return -1;
+ }
+ BZ2_bzlibVersion=GetProcAddress(hLib,"BZ2_bzlibVersion");
+ BZ2_bzopen=GetProcAddress(hLib,"BZ2_bzopen");
+ BZ2_bzdopen=GetProcAddress(hLib,"BZ2_bzdopen");
+ BZ2_bzread=GetProcAddress(hLib,"BZ2_bzread");
+ BZ2_bzwrite=GetProcAddress(hLib,"BZ2_bzwrite");
+ BZ2_bzflush=GetProcAddress(hLib,"BZ2_bzflush");
+ BZ2_bzclose=GetProcAddress(hLib,"BZ2_bzclose");
+ BZ2_bzerror=GetProcAddress(hLib,"BZ2_bzerror");
+
+ if (!BZ2_bzlibVersion || !BZ2_bzopen || !BZ2_bzdopen
+ || !BZ2_bzread || !BZ2_bzwrite || !BZ2_bzflush
+ || !BZ2_bzclose || !BZ2_bzerror) {
+ fprintf(stderr,"GetProcAddress failed.\n");
+ return -1;
+ }
+ BZ2DLLLoaded=1;
+ BZ2DLLhLib=hLib;
+ return 0;
+
+}
+int BZ2DLLFreeLibrary(void)
+{
+ if(BZ2DLLLoaded==0){return 0;}
+ FreeLibrary(BZ2DLLhLib);
+ BZ2DLLLoaded=0;
+}
+#endif /* WIN32 */
+
+void usage(void)
+{
+ puts("usage: minibz2 [-d] [-{1,2,..9}] [[srcfilename] destfilename]");
+}
+
+int main(int argc,char *argv[])
+{
+ int decompress = 0;
+ int level = 9;
+ char *fn_r = NULL;
+ char *fn_w = NULL;
+
+#ifdef _WIN32
+ if(BZ2DLLLoadLibrary()<0){
+ fprintf(stderr,"Loading of %s failed. Giving up.\n", BZ2_LIBNAME);
+ exit(1);
+ }
+ printf("Loading of %s succeeded. Library version is %s.\n",
+ BZ2_LIBNAME, BZ2_bzlibVersion() );
+#endif
+ while(++argv,--argc){
+ if(**argv =='-' || **argv=='/'){
+ char *p;
+
+ for(p=*argv+1;*p;p++){
+ if(*p=='d'){
+ decompress = 1;
+ }else if('1'<=*p && *p<='9'){
+ level = *p - '0';
+ }else{
+ usage();
+ exit(1);
+ }
+ }
+ }else{
+ break;
+ }
+ }
+ if(argc>=1){
+ fn_r = *argv;
+ argc--;argv++;
+ }else{
+ fn_r = NULL;
+ }
+ if(argc>=1){
+ fn_w = *argv;
+ argc--;argv++;
+ }else{
+ fn_w = NULL;
+ }
+ {
+ int len;
+ char buff[0x1000];
+ char mode[10];
+
+ if(decompress){
+ BZFILE *BZ2fp_r = NULL;
+ FILE *fp_w = NULL;
+
+ if(fn_w){
+ if((fp_w = fopen(fn_w,"wb"))==NULL){
+ printf("can't open [%s]\n",fn_w);
+ perror("reason:");
+ exit(1);
+ }
+ }else{
+ fp_w = stdout;
+ }
+ if((fn_r == NULL && (BZ2fp_r = BZ2_bzdopen(fileno(stdin),"rb"))==NULL)
+ || (fn_r != NULL && (BZ2fp_r = BZ2_bzopen(fn_r,"rb"))==NULL)){
+ printf("can't bz2openstream\n");
+ exit(1);
+ }
+ while((len=BZ2_bzread(BZ2fp_r,buff,0x1000))>0){
+ fwrite(buff,1,len,fp_w);
+ }
+ BZ2_bzclose(BZ2fp_r);
+ if(fp_w != stdout) fclose(fp_w);
+ }else{
+ BZFILE *BZ2fp_w = NULL;
+ FILE *fp_r = NULL;
+
+ if(fn_r){
+ if((fp_r = fopen(fn_r,"rb"))==NULL){
+ printf("can't open [%s]\n",fn_r);
+ perror("reason:");
+ exit(1);
+ }
+ }else{
+ fp_r = stdin;
+ }
+ mode[0]='w';
+ mode[1] = '0' + level;
+ mode[2] = '\0';
+
+ if((fn_w == NULL && (BZ2fp_w = BZ2_bzdopen(fileno(stdout),mode))==NULL)
+ || (fn_w !=NULL && (BZ2fp_w = BZ2_bzopen(fn_w,mode))==NULL)){
+ printf("can't bz2openstream\n");
+ exit(1);
+ }
+ while((len=fread(buff,1,0x1000,fp_r))>0){
+ BZ2_bzwrite(BZ2fp_w,buff,len);
+ }
+ BZ2_bzclose(BZ2fp_w);
+ if(fp_r!=stdin)fclose(fp_r);
+ }
+ }
+#ifdef _WIN32
+ BZ2DLLFreeLibrary();
+#endif
+ return 0;
+}
diff --git a/Utilities/cmbzip2/dlltest.dsp b/Utilities/cmbzip2/dlltest.dsp
new file mode 100644
index 000000000..4b1615edc
--- /dev/null
+++ b/Utilities/cmbzip2/dlltest.dsp
@@ -0,0 +1,93 @@
+# Microsoft Developer Studio Project File - Name="dlltest" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** •ÒW‚µ‚È‚¢‚Å‚­‚¾‚³‚¢ **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=dlltest - Win32 Debug
+!MESSAGE ‚±‚ê‚Í—LŒø‚ÈÒ²¸Ì§²Ù‚Å‚Í‚ ‚è‚Ü‚¹‚ñB ‚±‚ÌÌßÛ¼Þª¸Ä‚ðËÞÙÄÞ‚·‚邽‚ß‚É‚Í NMAKE ‚ðŽg—p‚µ‚Ä‚­‚¾‚³‚¢B
+!MESSAGE [Ò²¸Ì§²Ù‚Ì´¸½Îß°Ä] ºÏÝÄÞ‚ðŽg—p‚µ‚ÄŽÀs‚µ‚Ä‚­‚¾‚³‚¢
+!MESSAGE
+!MESSAGE NMAKE /f "dlltest.mak".
+!MESSAGE
+!MESSAGE NMAKE ‚ÌŽÀsŽž‚É\¬‚ðŽw’è‚Å‚«‚Ü‚·
+!MESSAGE ºÏÝÄÞ ×²Ýã‚ÅϸۂÌÝ’è‚ð’è‹`‚µ‚Ü‚·B—á:
+!MESSAGE
+!MESSAGE NMAKE /f "dlltest.mak" CFG="dlltest - Win32 Debug"
+!MESSAGE
+!MESSAGE ‘I‘ð‰Â”\‚ÈËÞÙÄÞ Ó°ÄÞ:
+!MESSAGE
+!MESSAGE "dlltest - Win32 Release" ("Win32 (x86) Console Application" —p)
+!MESSAGE "dlltest - Win32 Debug" ("Win32 (x86) Console Application" —p)
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "dlltest - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x411 /d "NDEBUG"
+# ADD RSC /l 0x411 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"minibz2.exe"
+
+!ELSEIF "$(CFG)" == "dlltest - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "dlltest_"
+# PROP BASE Intermediate_Dir "dlltest_"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "dlltest_"
+# PROP Intermediate_Dir "dlltest_"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x411 /d "_DEBUG"
+# ADD RSC /l 0x411 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"minibz2.exe" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "dlltest - Win32 Release"
+# Name "dlltest - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\bzlib.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\dlltest.c
+# End Source File
+# End Target
+# End Project
diff --git a/Utilities/cmbzip2/entities.xml b/Utilities/cmbzip2/entities.xml
new file mode 100644
index 000000000..e9e0553b7
--- /dev/null
+++ b/Utilities/cmbzip2/entities.xml
@@ -0,0 +1,9 @@
+<!-- misc. strings -->
+<!ENTITY bz-url "http://www.bzip.org">
+<!ENTITY bz-email "jseward@bzip.org">
+<!ENTITY bz-lifespan "1996-2007">
+
+<!ENTITY bz-version "1.0.5">
+<!ENTITY bz-date "10 December 2007">
+
+<!ENTITY manual-title "bzip2 Manual">
diff --git a/Utilities/cmbzip2/format.pl b/Utilities/cmbzip2/format.pl
new file mode 100755
index 000000000..2b391dad6
--- /dev/null
+++ b/Utilities/cmbzip2/format.pl
@@ -0,0 +1,68 @@
+#!/usr/bin/perl -w
+#
+# ------------------------------------------------------------------
+# This file is part of bzip2/libbzip2, a program and library for
+# lossless, block-sorting data compression.
+#
+# bzip2/libbzip2 version 1.0.5 of 10 December 2007
+# Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+#
+# Please read the WARNING, DISCLAIMER and PATENTS sections in the
+# README file.
+#
+# This program is released under the terms of the license contained
+# in the file LICENSE.
+# ------------------------------------------------------------------
+#
+use strict;
+
+# get command line values:
+if ( $#ARGV !=1 ) {
+ die "Usage: $0 xml_infile xml_outfile\n";
+}
+
+my $infile = shift;
+# check infile exists
+die "Can't find file \"$infile\""
+ unless -f $infile;
+# check we can read infile
+if (! -r $infile) {
+ die "Can't read input $infile\n";
+}
+# check we can open infile
+open( INFILE,"<$infile" ) or
+ die "Can't input $infile $!";
+
+#my $outfile = 'fmt-manual.xml';
+my $outfile = shift;
+#print "Infile: $infile, Outfile: $outfile\n";
+# check we can write to outfile
+open( OUTFILE,">$outfile" ) or
+ die "Can't output $outfile $! for writing";
+
+my ($prev, $curr, $str);
+$prev = ''; $curr = '';
+while ( <INFILE> ) {
+
+ print OUTFILE $prev;
+ $prev = $curr;
+ $curr = $_;
+ $str = '';
+
+ if ( $prev =~ /<programlisting>$|<screen>$/ ) {
+ chomp $prev;
+ $curr = join( '', $prev, "<![CDATA[", $curr );
+ $prev = '';
+ next;
+ }
+ elsif ( $curr =~ /<\/programlisting>|<\/screen>/ ) {
+ chomp $prev;
+ $curr = join( '', $prev, "]]>", $curr );
+ $prev = '';
+ next;
+ }
+}
+print OUTFILE $curr;
+close INFILE;
+close OUTFILE;
+exit;
diff --git a/Utilities/cmbzip2/huffman.c b/Utilities/cmbzip2/huffman.c
new file mode 100644
index 000000000..87e79e38a
--- /dev/null
+++ b/Utilities/cmbzip2/huffman.c
@@ -0,0 +1,205 @@
+
+/*-------------------------------------------------------------*/
+/*--- Huffman coding low-level stuff ---*/
+/*--- huffman.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
+
+ bzip2/libbzip2 version 1.0.5 of 10 December 2007
+ Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
+
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------ */
+
+
+#include "bzlib_private.h"
+
+/*---------------------------------------------------*/
+#define WEIGHTOF(zz0) ((zz0) & 0xffffff00)
+#define DEPTHOF(zz1) ((zz1) & 0x000000ff)
+#define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3))
+
+#define ADDWEIGHTS(zw1,zw2) \
+ (WEIGHTOF(zw1)+WEIGHTOF(zw2)) | \
+ (1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2)))
+
+#define UPHEAP(z) \
+{ \
+ Int32 zz, tmp; \
+ zz = z; tmp = heap[zz]; \
+ while (weight[tmp] < weight[heap[zz >> 1]]) { \
+ heap[zz] = heap[zz >> 1]; \
+ zz >>= 1; \
+ } \
+ heap[zz] = tmp; \
+}
+
+#define DOWNHEAP(z) \
+{ \
+ Int32 zz, yy, tmp; \
+ zz = z; tmp = heap[zz]; \
+ while (True) { \
+ yy = zz << 1; \
+ if (yy > nHeap) break; \
+ if (yy < nHeap && \
+ weight[heap[yy+1]] < weight[heap[yy]]) \
+ yy++; \
+ if (weight[tmp] < weight[heap[yy]]) break; \
+ heap[zz] = heap[yy]; \
+ zz = yy; \
+ } \
+ heap[zz] = tmp; \
+}
+
+
+/*---------------------------------------------------*/
+void BZ2_hbMakeCodeLengths ( UChar *len,
+ Int32 *freq,
+ Int32 alphaSize,
+ Int32 maxLen )
+{
+ /*--
+ Nodes and heap entries run from 1. Entry 0
+ for both the heap and nodes is a sentinel.
+ --*/
+ Int32 nNodes, nHeap, n1, n2, i, j, k;
+ Bool tooLong;
+
+ Int32 heap [ BZ_MAX_ALPHA_SIZE + 2 ];
+ Int32 weight [ BZ_MAX_ALPHA_SIZE * 2 ];
+ Int32 parent [ BZ_MAX_ALPHA_SIZE * 2 ];
+
+ for (i = 0; i < alphaSize; i++)
+ weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8;
+
+ while (True) {
+
+ nNodes = alphaSize;
+ nHeap = 0;
+
+ heap[0] = 0;
+ weight[0] = 0;
+ parent[0] = -2;
+
+ for (i = 1; i <= alphaSize; i++) {
+ parent[i] = -1;
+ nHeap++;
+ heap[nHeap] = i;
+ UPHEAP(nHeap);
+ }
+
+ AssertH( nHeap < (BZ_MAX_ALPHA_SIZE+2), 2001 );
+
+ while (nHeap > 1) {
+ n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
+ n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
+ nNodes++;
+ parent[n1] = parent[n2] = nNodes;
+ weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]);
+ parent[nNodes] = -1;
+ nHeap++;
+ heap[nHeap] = nNodes;
+ UPHEAP(nHeap);
+ }
+
+ AssertH( nNodes < (BZ_MAX_ALPHA_SIZE * 2), 2002 );
+
+ tooLong = False;
+ for (i = 1; i <= alphaSize; i++) {
+ j = 0;
+ k = i;
+ while (parent[k] >= 0) { k = parent[k]; j++; }
+ len[i-1] = j;
+ if (j > maxLen) tooLong = True;
+ }
+
+ if (! tooLong) break;
+
+ /* 17 Oct 04: keep-going condition for the following loop used
+ to be 'i < alphaSize', which missed the last element,
+ theoretically leading to the possibility of the compressor
+ looping. However, this count-scaling step is only needed if
+ one of the generated Huffman code words is longer than
+ maxLen, which up to and including version 1.0.2 was 20 bits,
+ which is extremely unlikely. In version 1.0.3 maxLen was
+ changed to 17 bits, which has minimal effect on compression
+ ratio, but does mean this scaling step is used from time to
+ time, enough to verify that it works.
+
+ This means that bzip2-1.0.3 and later will only produce
+ Huffman codes with a maximum length of 17 bits. However, in
+ order to preserve backwards compatibility with bitstreams
+ produced by versions pre-1.0.3, the decompressor must still
+ handle lengths of up to 20. */
+
+ for (i = 1; i <= alphaSize; i++) {
+ j = weight[i] >> 8;
+ j = 1 + (j / 2);
+ weight[i] = j << 8;
+ }
+ }
+}
+
+
+/*---------------------------------------------------*/
+void BZ2_hbAssignCodes ( Int32 *code,
+ UChar *length,
+ Int32 minLen,
+ Int32 maxLen,
+ Int32 alphaSize )
+{
+ Int32 n, vec, i;
+
+ vec = 0;
+ for (n = minLen; n <= maxLen; n++) {
+ for (i = 0; i < alphaSize; i++)
+ if (length[i] == n) { code[i] = vec; vec++; };
+ vec <<= 1;
+ }
+}
+
+
+/*---------------------------------------------------*/
+void BZ2_hbCreateDecodeTables ( Int32 *limit,
+ Int32 *base,
+ Int32 *perm,
+ UChar *length,
+ Int32 minLen,
+ Int32 maxLen,
+ Int32 alphaSize )
+{
+ Int32 pp, i, j, vec;
+
+ pp = 0;
+ for (i = minLen; i <= maxLen; i++)
+ for (j = 0; j < alphaSize; j++)
+ if (length[j] == i) { perm[pp] = j; pp++; };
+
+ for (i = 0; i < BZ_MAX_CODE_LEN; i++) base[i] = 0;
+ for (i = 0; i < alphaSize; i++) base[length[i]+1]++;
+
+ for (i = 1; i < BZ_MAX_CODE_LEN; i++) base[i] += base[i-1];
+
+ for (i = 0; i < BZ_MAX_CODE_LEN; i++) limit[i] = 0;
+ vec = 0;
+
+ for (i = minLen; i <= maxLen; i++) {
+ vec += (base[i+1] - base[i]);
+ limit[i] = vec-1;
+ vec <<= 1;
+ }
+ for (i = minLen + 1; i <= maxLen; i++)
+ base[i] = ((limit[i-1] + 1) << 1) - base[i];
+}
+
+
+/*-------------------------------------------------------------*/
+/*--- end huffman.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/Utilities/cmbzip2/libbz2.def b/Utilities/cmbzip2/libbz2.def
new file mode 100644
index 000000000..69fef54bc
--- /dev/null
+++ b/Utilities/cmbzip2/libbz2.def
@@ -0,0 +1,27 @@
+LIBRARY LIBBZ2
+DESCRIPTION "libbzip2: library for data compression"
+EXPORTS
+ BZ2_bzCompressInit
+ BZ2_bzCompress
+ BZ2_bzCompressEnd
+ BZ2_bzDecompressInit
+ BZ2_bzDecompress
+ BZ2_bzDecompressEnd
+ BZ2_bzReadOpen
+ BZ2_bzReadClose
+ BZ2_bzReadGetUnused
+ BZ2_bzRead
+ BZ2_bzWriteOpen
+ BZ2_bzWrite
+ BZ2_bzWriteClose
+ BZ2_bzWriteClose64
+ BZ2_bzBuffToBuffCompress
+ BZ2_bzBuffToBuffDecompress
+ BZ2_bzlibVersion
+ BZ2_bzopen
+ BZ2_bzdopen
+ BZ2_bzread
+ BZ2_bzwrite
+ BZ2_bzflush
+ BZ2_bzclose
+ BZ2_bzerror
diff --git a/Utilities/cmbzip2/libbz2.dsp b/Utilities/cmbzip2/libbz2.dsp
new file mode 100644
index 000000000..a21a20f75
--- /dev/null
+++ b/Utilities/cmbzip2/libbz2.dsp
@@ -0,0 +1,130 @@
+# Microsoft Developer Studio Project File - Name="libbz2" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** •ÒW‚µ‚È‚¢‚Å‚­‚¾‚³‚¢ **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=libbz2 - Win32 Debug
+!MESSAGE ‚±‚ê‚Í—LŒø‚ÈÒ²¸Ì§²Ù‚Å‚Í‚ ‚è‚Ü‚¹‚ñB ‚±‚ÌÌßÛ¼Þª¸Ä‚ðËÞÙÄÞ‚·‚邽‚ß‚É‚Í NMAKE ‚ðŽg—p‚µ‚Ä‚­‚¾‚³‚¢B
+!MESSAGE [Ò²¸Ì§²Ù‚Ì´¸½Îß°Ä] ºÏÝÄÞ‚ðŽg—p‚µ‚ÄŽÀs‚µ‚Ä‚­‚¾‚³‚¢
+!MESSAGE
+!MESSAGE NMAKE /f "libbz2.mak".
+!MESSAGE
+!MESSAGE NMAKE ‚ÌŽÀsŽž‚É\¬‚ðŽw’è‚Å‚«‚Ü‚·
+!MESSAGE ºÏÝÄÞ ×²Ýã‚ÅϸۂÌÝ’è‚ð’è‹`‚µ‚Ü‚·B—á:
+!MESSAGE
+!MESSAGE NMAKE /f "libbz2.mak" CFG="libbz2 - Win32 Debug"
+!MESSAGE
+!MESSAGE ‘I‘ð‰Â”\‚ÈËÞÙÄÞ Ó°ÄÞ:
+!MESSAGE
+!MESSAGE "libbz2 - Win32 Release" ("Win32 (x86) Dynamic-Link Library" —p)
+!MESSAGE "libbz2 - Win32 Debug" ("Win32 (x86) Dynamic-Link Library" —p)
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "libbz2 - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x411 /d "NDEBUG"
+# ADD RSC /l 0x411 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"libbz2.dll"
+
+!ELSEIF "$(CFG)" == "libbz2 - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
+# ADD BASE RSC /l 0x411 /d "_DEBUG"
+# ADD RSC /l 0x411 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:"libbz2.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "libbz2 - Win32 Release"
+# Name "libbz2 - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\blocksort.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bzlib.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\bzlib.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\bzlib_private.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\compress.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\crctable.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\decompress.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\huffman.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\libbz2.def
+# End Source File
+# Begin Source File
+
+SOURCE=.\randtable.c
+# End Source File
+# End Target
+# End Project
diff --git a/Utilities/cmbzip2/libbz2.lib b/Utilities/cmbzip2/libbz2.lib
new file mode 100644
index 000000000..9a97a75e2
--- /dev/null
+++ b/Utilities/cmbzip2/libbz2.lib
Binary files differ
diff --git a/Utilities/cmbzip2/makefile.msc b/Utilities/cmbzip2/makefile.msc
new file mode 100644
index 000000000..d5f2e5930
--- /dev/null
+++ b/Utilities/cmbzip2/makefile.msc
@@ -0,0 +1,63 @@
+# Makefile for Microsoft Visual C++ 6.0
+# usage: nmake -f makefile.msc
+# K.M. Syring (syring@gsf.de)
+# Fixed up by JRS for bzip2-0.9.5d release.
+
+CC=cl
+CFLAGS= -DWIN32 -MD -Ox -D_FILE_OFFSET_BITS=64 -nologo
+
+OBJS= blocksort.obj \
+ huffman.obj \
+ crctable.obj \
+ randtable.obj \
+ compress.obj \
+ decompress.obj \
+ bzlib.obj
+
+all: lib bzip2 test
+
+bzip2: lib
+ $(CC) $(CFLAGS) -o bzip2 bzip2.c libbz2.lib setargv.obj
+ $(CC) $(CFLAGS) -o bzip2recover bzip2recover.c
+
+lib: $(OBJS)
+ lib /out:libbz2.lib $(OBJS)
+
+test: bzip2
+ type words1
+ .\\bzip2 -1 < sample1.ref > sample1.rb2
+ .\\bzip2 -2 < sample2.ref > sample2.rb2
+ .\\bzip2 -3 < sample3.ref > sample3.rb2
+ .\\bzip2 -d < sample1.bz2 > sample1.tst
+ .\\bzip2 -d < sample2.bz2 > sample2.tst
+ .\\bzip2 -ds < sample3.bz2 > sample3.tst
+ @echo All six of the fc's should find no differences.
+ @echo If fc finds an error on sample3.bz2, this could be
+ @echo because WinZip's 'TAR file smart CR/LF conversion'
+ @echo is too clever for its own good. Disable this option.
+ @echo The correct size for sample3.ref is 120,244. If it
+ @echo is 150,251, WinZip has messed it up.
+ fc sample1.bz2 sample1.rb2
+ fc sample2.bz2 sample2.rb2
+ fc sample3.bz2 sample3.rb2
+ fc sample1.tst sample1.ref
+ fc sample2.tst sample2.ref
+ fc sample3.tst sample3.ref
+
+
+
+clean:
+ del *.obj
+ del libbz2.lib
+ del bzip2.exe
+ del bzip2recover.exe
+ del sample1.rb2
+ del sample2.rb2
+ del sample3.rb2
+ del sample1.tst
+ del sample2.tst
+ del sample3.tst
+
+.c.obj:
+ $(CC) $(CFLAGS) -c $*.c -o $*.obj
+
diff --git a/Utilities/cmbzip2/manual.html b/Utilities/cmbzip2/manual.html
new file mode 100644
index 000000000..bb4495385
--- /dev/null
+++ b/Utilities/cmbzip2/manual.html
@@ -0,0 +1,2540 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>bzip2 and libbzip2, version 1.0.5</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.69.1">
+<style type="text/css" media="screen">/* Colours:
+#74240f dark brown h1, h2, h3, h4
+#336699 medium blue links
+#339999 turquoise link hover colour
+#202020 almost black general text
+#761596 purple md5sum text
+#626262 dark gray pre border
+#eeeeee very light gray pre background
+#f2f2f9 very light blue nav table background
+#3366cc medium blue nav table border
+*/
+
+a, a:link, a:visited, a:active { color: #336699; }
+a:hover { color: #339999; }
+
+body { font: 80%/126% sans-serif; }
+h1, h2, h3, h4 { color: #74240f; }
+
+dt { color: #336699; font-weight: bold }
+dd {
+ margin-left: 1.5em;
+ padding-bottom: 0.8em;
+}
+
+/* -- ruler -- */
+div.hr_blue {
+ height: 3px;
+ background:#ffffff url("/images/hr_blue.png") repeat-x; }
+div.hr_blue hr { display:none; }
+
+/* release styles */
+#release p { margin-top: 0.4em; }
+#release .md5sum { color: #761596; }
+
+
+/* ------ styles for docs|manuals|howto ------ */
+/* -- lists -- */
+ul {
+ margin: 0px 4px 16px 16px;
+ padding: 0px;
+ list-style: url("/images/li-blue.png");
+}
+ul li {
+ margin-bottom: 10px;
+}
+ul ul {
+ list-style-type: none;
+ list-style-image: none;
+ margin-left: 0px;
+}
+
+/* header / footer nav tables */
+table.nav {
+ border: solid 1px #3366cc;
+ background: #f2f2f9;
+ background-color: #f2f2f9;
+ margin-bottom: 0.5em;
+}
+/* don't have underlined links in chunked nav menus */
+table.nav a { text-decoration: none; }
+table.nav a:hover { text-decoration: underline; }
+table.nav td { font-size: 85%; }
+
+code, tt, pre { font-size: 120%; }
+code, tt { color: #761596; }
+
+div.literallayout, pre.programlisting, pre.screen {
+ color: #000000;
+ padding: 0.5em;
+ background: #eeeeee;
+ border: 1px solid #626262;
+ background-color: #eeeeee;
+ margin: 4px 0px 4px 0px;
+}
+</style>
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="book" lang="en">
+<div class="titlepage">
+<div>
+<div><h1 class="title">
+<a name="userman"></a>bzip2 and libbzip2, version 1.0.5</h1></div>
+<div><h2 class="subtitle">A program and library for data compression</h2></div>
+<div><div class="authorgroup"><div class="author">
+<h3 class="author">
+<span class="firstname">Julian</span> <span class="surname">Seward</span>
+</h3>
+<div class="affiliation"><span class="orgname">http://www.bzip.org<br></span></div>
+</div></div></div>
+<div><p class="releaseinfo">Version 1.0.5 of 10 December 2007</p></div>
+<div><p class="copyright">Copyright © 1996-2007 Julian Seward</p></div>
+<div><div class="legalnotice">
+<a name="id2499833"></a><p>This program, <code class="computeroutput">bzip2</code>, the
+ associated library <code class="computeroutput">libbzip2</code>, and
+ all documentation, are copyright © 1996-2007 Julian Seward.
+ All rights reserved.</p>
+<p>Redistribution and use in source and binary forms, with
+ or without modification, are permitted provided that the
+ following conditions are met:</p>
+<div class="itemizedlist"><ul type="bullet">
+<li style="list-style-type: disc"><p>Redistributions of source code must retain the
+ above copyright notice, this list of conditions and the
+ following disclaimer.</p></li>
+<li style="list-style-type: disc"><p>The origin of this software must not be
+ misrepresented; you must not claim that you wrote the original
+ software. If you use this software in a product, an
+ acknowledgment in the product documentation would be
+ appreciated but is not required.</p></li>
+<li style="list-style-type: disc"><p>Altered source versions must be plainly marked
+ as such, and must not be misrepresented as being the original
+ software.</p></li>
+<li style="list-style-type: disc"><p>The name of the author may not be used to
+ endorse or promote products derived from this software without
+ specific prior written permission.</p></li>
+</ul></div>
+<p>THIS SOFTWARE IS PROVIDED BY THE AUTHOR "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 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.</p>
+<p>PATENTS: To the best of my knowledge,
+ <code class="computeroutput">bzip2</code> and
+ <code class="computeroutput">libbzip2</code> do not use any patented
+ algorithms. However, I do not have the resources to carry
+ out a patent search. Therefore I cannot give any guarantee of
+ the above statement.
+ </p>
+</div></div>
+</div>
+<hr>
+</div>
+<div class="toc">
+<p><b>Table of Contents</b></p>
+<dl>
+<dt><span class="chapter"><a href="#intro">1. Introduction</a></span></dt>
+<dt><span class="chapter"><a href="#using">2. How to use bzip2</a></span></dt>
+<dd><dl>
+<dt><span class="sect1"><a href="#name">2.1. NAME</a></span></dt>
+<dt><span class="sect1"><a href="#synopsis">2.2. SYNOPSIS</a></span></dt>
+<dt><span class="sect1"><a href="#description">2.3. DESCRIPTION</a></span></dt>
+<dt><span class="sect1"><a href="#options">2.4. OPTIONS</a></span></dt>
+<dt><span class="sect1"><a href="#memory-management">2.5. MEMORY MANAGEMENT</a></span></dt>
+<dt><span class="sect1"><a href="#recovering">2.6. RECOVERING DATA FROM DAMAGED FILES</a></span></dt>
+<dt><span class="sect1"><a href="#performance">2.7. PERFORMANCE NOTES</a></span></dt>
+<dt><span class="sect1"><a href="#caveats">2.8. CAVEATS</a></span></dt>
+<dt><span class="sect1"><a href="#author">2.9. AUTHOR</a></span></dt>
+</dl></dd>
+<dt><span class="chapter"><a href="#libprog">3.
+Programming with <code class="computeroutput">libbzip2</code>
+</a></span></dt>
+<dd><dl>
+<dt><span class="sect1"><a href="#top-level">3.1. Top-level structure</a></span></dt>
+<dd><dl>
+<dt><span class="sect2"><a href="#ll-summary">3.1.1. Low-level summary</a></span></dt>
+<dt><span class="sect2"><a href="#hl-summary">3.1.2. High-level summary</a></span></dt>
+<dt><span class="sect2"><a href="#util-fns-summary">3.1.3. Utility functions summary</a></span></dt>
+</dl></dd>
+<dt><span class="sect1"><a href="#err-handling">3.2. Error handling</a></span></dt>
+<dt><span class="sect1"><a href="#low-level">3.3. Low-level interface</a></span></dt>
+<dd><dl>
+<dt><span class="sect2"><a href="#bzcompress-init">3.3.1. <code class="computeroutput">BZ2_bzCompressInit</code></a></span></dt>
+<dt><span class="sect2"><a href="#bzCompress">3.3.2. <code class="computeroutput">BZ2_bzCompress</code></a></span></dt>
+<dt><span class="sect2"><a href="#bzCompress-end">3.3.3. <code class="computeroutput">BZ2_bzCompressEnd</code></a></span></dt>
+<dt><span class="sect2"><a href="#bzDecompress-init">3.3.4. <code class="computeroutput">BZ2_bzDecompressInit</code></a></span></dt>
+<dt><span class="sect2"><a href="#bzDecompress">3.3.5. <code class="computeroutput">BZ2_bzDecompress</code></a></span></dt>
+<dt><span class="sect2"><a href="#bzDecompress-end">3.3.6. <code class="computeroutput">BZ2_bzDecompressEnd</code></a></span></dt>
+</dl></dd>
+<dt><span class="sect1"><a href="#hl-interface">3.4. High-level interface</a></span></dt>
+<dd><dl>
+<dt><span class="sect2"><a href="#bzreadopen">3.4.1. <code class="computeroutput">BZ2_bzReadOpen</code></a></span></dt>
+<dt><span class="sect2"><a href="#bzread">3.4.2. <code class="computeroutput">BZ2_bzRead</code></a></span></dt>
+<dt><span class="sect2"><a href="#bzreadgetunused">3.4.3. <code class="computeroutput">BZ2_bzReadGetUnused</code></a></span></dt>
+<dt><span class="sect2"><a href="#bzreadclose">3.4.4. <code class="computeroutput">BZ2_bzReadClose</code></a></span></dt>
+<dt><span class="sect2"><a href="#bzwriteopen">3.4.5. <code class="computeroutput">BZ2_bzWriteOpen</code></a></span></dt>
+<dt><span class="sect2"><a href="#bzwrite">3.4.6. <code class="computeroutput">BZ2_bzWrite</code></a></span></dt>
+<dt><span class="sect2"><a href="#bzwriteclose">3.4.7. <code class="computeroutput">BZ2_bzWriteClose</code></a></span></dt>
+<dt><span class="sect2"><a href="#embed">3.4.8. Handling embedded compressed data streams</a></span></dt>
+<dt><span class="sect2"><a href="#std-rdwr">3.4.9. Standard file-reading/writing code</a></span></dt>
+</dl></dd>
+<dt><span class="sect1"><a href="#util-fns">3.5. Utility functions</a></span></dt>
+<dd><dl>
+<dt><span class="sect2"><a href="#bzbufftobuffcompress">3.5.1. <code class="computeroutput">BZ2_bzBuffToBuffCompress</code></a></span></dt>
+<dt><span class="sect2"><a href="#bzbufftobuffdecompress">3.5.2. <code class="computeroutput">BZ2_bzBuffToBuffDecompress</code></a></span></dt>
+</dl></dd>
+<dt><span class="sect1"><a href="#zlib-compat">3.6. <code class="computeroutput">zlib</code> compatibility functions</a></span></dt>
+<dt><span class="sect1"><a href="#stdio-free">3.7. Using the library in a <code class="computeroutput">stdio</code>-free environment</a></span></dt>
+<dd><dl>
+<dt><span class="sect2"><a href="#stdio-bye">3.7.1. Getting rid of <code class="computeroutput">stdio</code></a></span></dt>
+<dt><span class="sect2"><a href="#critical-error">3.7.2. Critical error handling</a></span></dt>
+</dl></dd>
+<dt><span class="sect1"><a href="#win-dll">3.8. Making a Windows DLL</a></span></dt>
+</dl></dd>
+<dt><span class="chapter"><a href="#misc">4. Miscellanea</a></span></dt>
+<dd><dl>
+<dt><span class="sect1"><a href="#limits">4.1. Limitations of the compressed file format</a></span></dt>
+<dt><span class="sect1"><a href="#port-issues">4.2. Portability issues</a></span></dt>
+<dt><span class="sect1"><a href="#bugs">4.3. Reporting bugs</a></span></dt>
+<dt><span class="sect1"><a href="#package">4.4. Did you get the right package?</a></span></dt>
+<dt><span class="sect1"><a href="#reading">4.5. Further Reading</a></span></dt>
+</dl></dd>
+</dl>
+</div>
+<div class="chapter" lang="en">
+<div class="titlepage"><div><div><h2 class="title">
+<a name="intro"></a>1. Introduction</h2></div></div></div>
+<p><code class="computeroutput">bzip2</code> compresses files
+using the Burrows-Wheeler block-sorting text compression
+algorithm, and Huffman coding. Compression is generally
+considerably better than that achieved by more conventional
+LZ77/LZ78-based compressors, and approaches the performance of
+the PPM family of statistical compressors.</p>
+<p><code class="computeroutput">bzip2</code> is built on top of
+<code class="computeroutput">libbzip2</code>, a flexible library for
+handling compressed data in the
+<code class="computeroutput">bzip2</code> format. This manual
+describes both how to use the program and how to work with the
+library interface. Most of the manual is devoted to this
+library, not the program, which is good news if your interest is
+only in the program.</p>
+<div class="itemizedlist"><ul type="bullet">
+<li style="list-style-type: disc"><p><a href="#using">How to use bzip2</a> describes how to use
+ <code class="computeroutput">bzip2</code>; this is the only part
+ you need to read if you just want to know how to operate the
+ program.</p></li>
+<li style="list-style-type: disc"><p><a href="#libprog">Programming with libbzip2</a> describes the
+ programming interfaces in detail, and</p></li>
+<li style="list-style-type: disc"><p><a href="#misc">Miscellanea</a> records some
+ miscellaneous notes which I thought ought to be recorded
+ somewhere.</p></li>
+</ul></div>
+</div>
+<div class="chapter" lang="en">
+<div class="titlepage"><div><div><h2 class="title">
+<a name="using"></a>2. How to use bzip2</h2></div></div></div>
+<div class="toc">
+<p><b>Table of Contents</b></p>
+<dl>
+<dt><span class="sect1"><a href="#name">2.1. NAME</a></span></dt>
+<dt><span class="sect1"><a href="#synopsis">2.2. SYNOPSIS</a></span></dt>
+<dt><span class="sect1"><a href="#description">2.3. DESCRIPTION</a></span></dt>
+<dt><span class="sect1"><a href="#options">2.4. OPTIONS</a></span></dt>
+<dt><span class="sect1"><a href="#memory-management">2.5. MEMORY MANAGEMENT</a></span></dt>
+<dt><span class="sect1"><a href="#recovering">2.6. RECOVERING DATA FROM DAMAGED FILES</a></span></dt>
+<dt><span class="sect1"><a href="#performance">2.7. PERFORMANCE NOTES</a></span></dt>
+<dt><span class="sect1"><a href="#caveats">2.8. CAVEATS</a></span></dt>
+<dt><span class="sect1"><a href="#author">2.9. AUTHOR</a></span></dt>
+</dl>
+</div>
+<p>This chapter contains a copy of the
+<code class="computeroutput">bzip2</code> man page, and nothing
+else.</p>
+<div class="sect1" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="name"></a>2.1. NAME</h2></div></div></div>
+<div class="itemizedlist"><ul type="bullet">
+<li style="list-style-type: disc"><p><code class="computeroutput">bzip2</code>,
+ <code class="computeroutput">bunzip2</code> - a block-sorting file
+ compressor, v1.0.4</p></li>
+<li style="list-style-type: disc"><p><code class="computeroutput">bzcat</code> -
+ decompresses files to stdout</p></li>
+<li style="list-style-type: disc"><p><code class="computeroutput">bzip2recover</code> -
+ recovers data from damaged bzip2 files</p></li>
+</ul></div>
+</div>
+<div class="sect1" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="synopsis"></a>2.2. SYNOPSIS</h2></div></div></div>
+<div class="itemizedlist"><ul type="bullet">
+<li style="list-style-type: disc"><p><code class="computeroutput">bzip2</code> [
+ -cdfkqstvzVL123456789 ] [ filenames ... ]</p></li>
+<li style="list-style-type: disc"><p><code class="computeroutput">bunzip2</code> [
+ -fkvsVL ] [ filenames ... ]</p></li>
+<li style="list-style-type: disc"><p><code class="computeroutput">bzcat</code> [ -s ] [
+ filenames ... ]</p></li>
+<li style="list-style-type: disc"><p><code class="computeroutput">bzip2recover</code>
+ filename</p></li>
+</ul></div>
+</div>
+<div class="sect1" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="description"></a>2.3. DESCRIPTION</h2></div></div></div>
+<p><code class="computeroutput">bzip2</code> compresses files
+using the Burrows-Wheeler block sorting text compression
+algorithm, and Huffman coding. Compression is generally
+considerably better than that achieved by more conventional
+LZ77/LZ78-based compressors, and approaches the performance of
+the PPM family of statistical compressors.</p>
+<p>The command-line options are deliberately very similar to
+those of GNU <code class="computeroutput">gzip</code>, but they are
+not identical.</p>
+<p><code class="computeroutput">bzip2</code> expects a list of
+file names to accompany the command-line flags. Each file is
+replaced by a compressed version of itself, with the name
+<code class="computeroutput">original_name.bz2</code>. Each
+compressed file has the same modification date, permissions, and,
+when possible, ownership as the corresponding original, so that
+these properties can be correctly restored at decompression time.
+File name handling is naive in the sense that there is no
+mechanism for preserving original file names, permissions,
+ownerships or dates in filesystems which lack these concepts, or
+have serious file name length restrictions, such as
+MS-DOS.</p>
+<p><code class="computeroutput">bzip2</code> and
+<code class="computeroutput">bunzip2</code> will by default not
+overwrite existing files. If you want this to happen, specify
+the <code class="computeroutput">-f</code> flag.</p>
+<p>If no file names are specified,
+<code class="computeroutput">bzip2</code> compresses from standard
+input to standard output. In this case,
+<code class="computeroutput">bzip2</code> will decline to write
+compressed output to a terminal, as this would be entirely
+incomprehensible and therefore pointless.</p>
+<p><code class="computeroutput">bunzip2</code> (or
+<code class="computeroutput">bzip2 -d</code>) decompresses all
+specified files. Files which were not created by
+<code class="computeroutput">bzip2</code> will be detected and
+ignored, and a warning issued.
+<code class="computeroutput">bzip2</code> attempts to guess the
+filename for the decompressed file from that of the compressed
+file as follows:</p>
+<div class="itemizedlist"><ul type="bullet">
+<li style="list-style-type: disc"><p><code class="computeroutput">filename.bz2 </code>
+ becomes
+ <code class="computeroutput">filename</code></p></li>
+<li style="list-style-type: disc"><p><code class="computeroutput">filename.bz </code>
+ becomes
+ <code class="computeroutput">filename</code></p></li>
+<li style="list-style-type: disc"><p><code class="computeroutput">filename.tbz2</code>
+ becomes
+ <code class="computeroutput">filename.tar</code></p></li>
+<li style="list-style-type: disc"><p><code class="computeroutput">filename.tbz </code>
+ becomes
+ <code class="computeroutput">filename.tar</code></p></li>
+<li style="list-style-type: disc"><p><code class="computeroutput">anyothername </code>
+ becomes
+ <code class="computeroutput">anyothername.out</code></p></li>
+</ul></div>
+<p>If the file does not end in one of the recognised endings,
+<code class="computeroutput">.bz2</code>,
+<code class="computeroutput">.bz</code>,
+<code class="computeroutput">.tbz2</code> or
+<code class="computeroutput">.tbz</code>,
+<code class="computeroutput">bzip2</code> complains that it cannot
+guess the name of the original file, and uses the original name
+with <code class="computeroutput">.out</code> appended.</p>
+<p>As with compression, supplying no filenames causes
+decompression from standard input to standard output.</p>
+<p><code class="computeroutput">bunzip2</code> will correctly
+decompress a file which is the concatenation of two or more
+compressed files. The result is the concatenation of the
+corresponding uncompressed files. Integrity testing
+(<code class="computeroutput">-t</code>) of concatenated compressed
+files is also supported.</p>
+<p>You can also compress or decompress files to the standard
+output by giving the <code class="computeroutput">-c</code> flag.
+Multiple files may be compressed and decompressed like this. The
+resulting outputs are fed sequentially to stdout. Compression of
+multiple files in this manner generates a stream containing
+multiple compressed file representations. Such a stream can be
+decompressed correctly only by
+<code class="computeroutput">bzip2</code> version 0.9.0 or later.
+Earlier versions of <code class="computeroutput">bzip2</code> will
+stop after decompressing the first file in the stream.</p>
+<p><code class="computeroutput">bzcat</code> (or
+<code class="computeroutput">bzip2 -dc</code>) decompresses all
+specified files to the standard output.</p>
+<p><code class="computeroutput">bzip2</code> will read arguments
+from the environment variables
+<code class="computeroutput">BZIP2</code> and
+<code class="computeroutput">BZIP</code>, in that order, and will
+process them before any arguments read from the command line.
+This gives a convenient way to supply default arguments.</p>
+<p>Compression is always performed, even if the compressed
+file is slightly larger than the original. Files of less than
+about one hundred bytes tend to get larger, since the compression
+mechanism has a constant overhead in the region of 50 bytes.
+Random data (including the output of most file compressors) is
+coded at about 8.05 bits per byte, giving an expansion of around
+0.5%.</p>
+<p>As a self-check for your protection,
+<code class="computeroutput">bzip2</code> uses 32-bit CRCs to make
+sure that the decompressed version of a file is identical to the
+original. This guards against corruption of the compressed data,
+and against undetected bugs in
+<code class="computeroutput">bzip2</code> (hopefully very unlikely).
+The chances of data corruption going undetected is microscopic,
+about one chance in four billion for each file processed. Be
+aware, though, that the check occurs upon decompression, so it
+can only tell you that something is wrong. It can't help you
+recover the original uncompressed data. You can use
+<code class="computeroutput">bzip2recover</code> to try to recover
+data from damaged files.</p>
+<p>Return values: 0 for a normal exit, 1 for environmental
+problems (file not found, invalid flags, I/O errors, etc.), 2
+to indicate a corrupt compressed file, 3 for an internal
+consistency error (eg, bug) which caused
+<code class="computeroutput">bzip2</code> to panic.</p>
+</div>
+<div class="sect1" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="options"></a>2.4. OPTIONS</h2></div></div></div>
+<div class="variablelist"><dl>
+<dt><span class="term"><code class="computeroutput">-c --stdout</code></span></dt>
+<dd><p>Compress or decompress to standard
+ output.</p></dd>
+<dt><span class="term"><code class="computeroutput">-d --decompress</code></span></dt>
+<dd><p>Force decompression.
+ <code class="computeroutput">bzip2</code>,
+ <code class="computeroutput">bunzip2</code> and
+ <code class="computeroutput">bzcat</code> are really the same
+ program, and the decision about what actions to take is done on
+ the basis of which name is used. This flag overrides that
+ mechanism, and forces bzip2 to decompress.</p></dd>
+<dt><span class="term"><code class="computeroutput">-z --compress</code></span></dt>
+<dd><p>The complement to
+ <code class="computeroutput">-d</code>: forces compression,
+ regardless of the invokation name.</p></dd>
+<dt><span class="term"><code class="computeroutput">-t --test</code></span></dt>
+<dd><p>Check integrity of the specified file(s), but
+ don't decompress them. This really performs a trial
+ decompression and throws away the result.</p></dd>
+<dt><span class="term"><code class="computeroutput">-f --force</code></span></dt>
+<dd>
+<p>Force overwrite of output files. Normally,
+ <code class="computeroutput">bzip2</code> will not overwrite
+ existing output files. Also forces
+ <code class="computeroutput">bzip2</code> to break hard links to
+ files, which it otherwise wouldn't do.</p>
+<p><code class="computeroutput">bzip2</code> normally declines
+ to decompress files which don't have the correct magic header
+ bytes. If forced (<code class="computeroutput">-f</code>),
+ however, it will pass such files through unmodified. This is
+ how GNU <code class="computeroutput">gzip</code> behaves.</p>
+</dd>
+<dt><span class="term"><code class="computeroutput">-k --keep</code></span></dt>
+<dd><p>Keep (don't delete) input files during
+ compression or decompression.</p></dd>
+<dt><span class="term"><code class="computeroutput">-s --small</code></span></dt>
+<dd>
+<p>Reduce memory usage, for compression,
+ decompression and testing. Files are decompressed and tested
+ using a modified algorithm which only requires 2.5 bytes per
+ block byte. This means any file can be decompressed in 2300k
+ of memory, albeit at about half the normal speed.</p>
+<p>During compression, <code class="computeroutput">-s</code>
+ selects a block size of 200k, which limits memory use to around
+ the same figure, at the expense of your compression ratio. In
+ short, if your machine is low on memory (8 megabytes or less),
+ use <code class="computeroutput">-s</code> for everything. See
+ <a href="#memory-management">MEMORY MANAGEMENT</a> below.</p>
+</dd>
+<dt><span class="term"><code class="computeroutput">-q --quiet</code></span></dt>
+<dd><p>Suppress non-essential warning messages.
+ Messages pertaining to I/O errors and other critical events
+ will not be suppressed.</p></dd>
+<dt><span class="term"><code class="computeroutput">-v --verbose</code></span></dt>
+<dd><p>Verbose mode -- show the compression ratio for
+ each file processed. Further
+ <code class="computeroutput">-v</code>'s increase the verbosity
+ level, spewing out lots of information which is primarily of
+ interest for diagnostic purposes.</p></dd>
+<dt><span class="term"><code class="computeroutput">-L --license -V --version</code></span></dt>
+<dd><p>Display the software version, license terms and
+ conditions.</p></dd>
+<dt><span class="term"><code class="computeroutput">-1</code> (or
+ <code class="computeroutput">--fast</code>) to
+ <code class="computeroutput">-9</code> (or
+ <code class="computeroutput">-best</code>)</span></dt>
+<dd><p>Set the block size to 100 k, 200 k ... 900 k
+ when compressing. Has no effect when decompressing. See <a href="#memory-management">MEMORY MANAGEMENT</a> below. The
+ <code class="computeroutput">--fast</code> and
+ <code class="computeroutput">--best</code> aliases are primarily
+ for GNU <code class="computeroutput">gzip</code> compatibility.
+ In particular, <code class="computeroutput">--fast</code> doesn't
+ make things significantly faster. And
+ <code class="computeroutput">--best</code> merely selects the
+ default behaviour.</p></dd>
+<dt><span class="term"><code class="computeroutput">--</code></span></dt>
+<dd><p>Treats all subsequent arguments as file names,
+ even if they start with a dash. This is so you can handle
+ files with names beginning with a dash, for example:
+ <code class="computeroutput">bzip2 --
+ -myfilename</code>.</p></dd>
+<dt>
+<span class="term"><code class="computeroutput">--repetitive-fast</code>, </span><span class="term"><code class="computeroutput">--repetitive-best</code></span>
+</dt>
+<dd><p>These flags are redundant in versions 0.9.5 and
+ above. They provided some coarse control over the behaviour of
+ the sorting algorithm in earlier versions, which was sometimes
+ useful. 0.9.5 and above have an improved algorithm which
+ renders these flags irrelevant.</p></dd>
+</dl></div>
+</div>
+<div class="sect1" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="memory-management"></a>2.5. MEMORY MANAGEMENT</h2></div></div></div>
+<p><code class="computeroutput">bzip2</code> compresses large
+files in blocks. The block size affects both the compression
+ratio achieved, and the amount of memory needed for compression
+and decompression. The flags <code class="computeroutput">-1</code>
+through <code class="computeroutput">-9</code> specify the block
+size to be 100,000 bytes through 900,000 bytes (the default)
+respectively. At decompression time, the block size used for
+compression is read from the header of the compressed file, and
+<code class="computeroutput">bunzip2</code> then allocates itself
+just enough memory to decompress the file. Since block sizes are
+stored in compressed files, it follows that the flags
+<code class="computeroutput">-1</code> to
+<code class="computeroutput">-9</code> are irrelevant to and so
+ignored during decompression.</p>
+<p>Compression and decompression requirements, in bytes, can be
+estimated as:</p>
+<pre class="programlisting">Compression: 400k + ( 8 x block size )
+
+Decompression: 100k + ( 4 x block size ), or
+ 100k + ( 2.5 x block size )</pre>
+<p>Larger block sizes give rapidly diminishing marginal
+returns. Most of the compression comes from the first two or
+three hundred k of block size, a fact worth bearing in mind when
+using <code class="computeroutput">bzip2</code> on small machines.
+It is also important to appreciate that the decompression memory
+requirement is set at compression time by the choice of block
+size.</p>
+<p>For files compressed with the default 900k block size,
+<code class="computeroutput">bunzip2</code> will require about 3700
+kbytes to decompress. To support decompression of any file on a
+4 megabyte machine, <code class="computeroutput">bunzip2</code> has
+an option to decompress using approximately half this amount of
+memory, about 2300 kbytes. Decompression speed is also halved,
+so you should use this option only where necessary. The relevant
+flag is <code class="computeroutput">-s</code>.</p>
+<p>In general, try and use the largest block size memory
+constraints allow, since that maximises the compression achieved.
+Compression and decompression speed are virtually unaffected by
+block size.</p>
+<p>Another significant point applies to files which fit in a
+single block -- that means most files you'd encounter using a
+large block size. The amount of real memory touched is
+proportional to the size of the file, since the file is smaller
+than a block. For example, compressing a file 20,000 bytes long
+with the flag <code class="computeroutput">-9</code> will cause the
+compressor to allocate around 7600k of memory, but only touch
+400k + 20000 * 8 = 560 kbytes of it. Similarly, the decompressor
+will allocate 3700k but only touch 100k + 20000 * 4 = 180
+kbytes.</p>
+<p>Here is a table which summarises the maximum memory usage
+for different block sizes. Also recorded is the total compressed
+size for 14 files of the Calgary Text Compression Corpus
+totalling 3,141,622 bytes. This column gives some feel for how
+compression varies with block size. These figures tend to
+understate the advantage of larger block sizes for larger files,
+since the Corpus is dominated by smaller files.</p>
+<pre class="programlisting"> Compress Decompress Decompress Corpus
+Flag usage usage -s usage Size
+
+ -1 1200k 500k 350k 914704
+ -2 2000k 900k 600k 877703
+ -3 2800k 1300k 850k 860338
+ -4 3600k 1700k 1100k 846899
+ -5 4400k 2100k 1350k 845160
+ -6 5200k 2500k 1600k 838626
+ -7 6100k 2900k 1850k 834096
+ -8 6800k 3300k 2100k 828642
+ -9 7600k 3700k 2350k 828642</pre>
+</div>
+<div class="sect1" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="recovering"></a>2.6. RECOVERING DATA FROM DAMAGED FILES</h2></div></div></div>
+<p><code class="computeroutput">bzip2</code> compresses files in
+blocks, usually 900kbytes long. Each block is handled
+independently. If a media or transmission error causes a
+multi-block <code class="computeroutput">.bz2</code> file to become
+damaged, it may be possible to recover data from the undamaged
+blocks in the file.</p>
+<p>The compressed representation of each block is delimited by
+a 48-bit pattern, which makes it possible to find the block
+boundaries with reasonable certainty. Each block also carries
+its own 32-bit CRC, so damaged blocks can be distinguished from
+undamaged ones.</p>
+<p><code class="computeroutput">bzip2recover</code> is a simple
+program whose purpose is to search for blocks in
+<code class="computeroutput">.bz2</code> files, and write each block
+out into its own <code class="computeroutput">.bz2</code> file. You
+can then use <code class="computeroutput">bzip2 -t</code> to test
+the integrity of the resulting files, and decompress those which
+are undamaged.</p>
+<p><code class="computeroutput">bzip2recover</code> takes a
+single argument, the name of the damaged file, and writes a
+number of files <code class="computeroutput">rec0001file.bz2</code>,
+<code class="computeroutput">rec0002file.bz2</code>, etc, containing
+the extracted blocks. The output filenames are designed so that
+the use of wildcards in subsequent processing -- for example,
+<code class="computeroutput">bzip2 -dc rec*file.bz2 &gt;
+recovered_data</code> -- lists the files in the correct
+order.</p>
+<p><code class="computeroutput">bzip2recover</code> should be of
+most use dealing with large <code class="computeroutput">.bz2</code>
+files, as these will contain many blocks. It is clearly futile
+to use it on damaged single-block files, since a damaged block
+cannot be recovered. If you wish to minimise any potential data
+loss through media or transmission errors, you might consider
+compressing with a smaller block size.</p>
+</div>
+<div class="sect1" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="performance"></a>2.7. PERFORMANCE NOTES</h2></div></div></div>
+<p>The sorting phase of compression gathers together similar
+strings in the file. Because of this, files containing very long
+runs of repeated symbols, like "aabaabaabaab ..." (repeated
+several hundred times) may compress more slowly than normal.
+Versions 0.9.5 and above fare much better than previous versions
+in this respect. The ratio between worst-case and average-case
+compression time is in the region of 10:1. For previous
+versions, this figure was more like 100:1. You can use the
+<code class="computeroutput">-vvvv</code> option to monitor progress
+in great detail, if you want.</p>
+<p>Decompression speed is unaffected by these
+phenomena.</p>
+<p><code class="computeroutput">bzip2</code> usually allocates
+several megabytes of memory to operate in, and then charges all
+over it in a fairly random fashion. This means that performance,
+both for compressing and decompressing, is largely determined by
+the speed at which your machine can service cache misses.
+Because of this, small changes to the code to reduce the miss
+rate have been observed to give disproportionately large
+performance improvements. I imagine
+<code class="computeroutput">bzip2</code> will perform best on
+machines with very large caches.</p>
+</div>
+<div class="sect1" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="caveats"></a>2.8. CAVEATS</h2></div></div></div>
+<p>I/O error messages are not as helpful as they could be.
+<code class="computeroutput">bzip2</code> tries hard to detect I/O
+errors and exit cleanly, but the details of what the problem is
+sometimes seem rather misleading.</p>
+<p>This manual page pertains to version 1.0.5 of
+<code class="computeroutput">bzip2</code>. Compressed data created by
+this version is entirely forwards and backwards compatible with the
+previous public releases, versions 0.1pl2, 0.9.0 and 0.9.5, 1.0.0,
+1.0.1, 1.0.2 and 1.0.3, but with the following exception: 0.9.0 and
+above can correctly decompress multiple concatenated compressed files.
+0.1pl2 cannot do this; it will stop after decompressing just the first
+file in the stream.</p>
+<p><code class="computeroutput">bzip2recover</code> versions
+prior to 1.0.2 used 32-bit integers to represent bit positions in
+compressed files, so it could not handle compressed files more
+than 512 megabytes long. Versions 1.0.2 and above use 64-bit ints
+on some platforms which support them (GNU supported targets, and
+Windows). To establish whether or not
+<code class="computeroutput">bzip2recover</code> was built with such
+a limitation, run it without arguments. In any event you can
+build yourself an unlimited version if you can recompile it with
+<code class="computeroutput">MaybeUInt64</code> set to be an
+unsigned 64-bit integer.</p>
+</div>
+<div class="sect1" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="author"></a>2.9. AUTHOR</h2></div></div></div>
+<p>Julian Seward,
+<code class="computeroutput">jseward@bzip.org</code></p>
+<p>The ideas embodied in
+<code class="computeroutput">bzip2</code> are due to (at least) the
+following people: Michael Burrows and David Wheeler (for the
+block sorting transformation), David Wheeler (again, for the
+Huffman coder), Peter Fenwick (for the structured coding model in
+the original <code class="computeroutput">bzip</code>, and many
+refinements), and Alistair Moffat, Radford Neal and Ian Witten
+(for the arithmetic coder in the original
+<code class="computeroutput">bzip</code>). I am much indebted for
+their help, support and advice. See the manual in the source
+distribution for pointers to sources of documentation. Christian
+von Roques encouraged me to look for faster sorting algorithms,
+so as to speed up compression. Bela Lubkin encouraged me to
+improve the worst-case compression performance.
+Donna Robinson XMLised the documentation.
+Many people sent
+patches, helped with portability problems, lent machines, gave
+advice and were generally helpful.</p>
+</div>
+</div>
+<div class="chapter" lang="en">
+<div class="titlepage"><div><div><h2 class="title">
+<a name="libprog"></a>3. 
+Programming with <code class="computeroutput">libbzip2</code>
+</h2></div></div></div>
+<div class="toc">
+<p><b>Table of Contents</b></p>
+<dl>
+<dt><span class="sect1"><a href="#top-level">3.1. Top-level structure</a></span></dt>
+<dd><dl>
+<dt><span class="sect2"><a href="#ll-summary">3.1.1. Low-level summary</a></span></dt>
+<dt><span class="sect2"><a href="#hl-summary">3.1.2. High-level summary</a></span></dt>
+<dt><span class="sect2"><a href="#util-fns-summary">3.1.3. Utility functions summary</a></span></dt>
+</dl></dd>
+<dt><span class="sect1"><a href="#err-handling">3.2. Error handling</a></span></dt>
+<dt><span class="sect1"><a href="#low-level">3.3. Low-level interface</a></span></dt>
+<dd><dl>
+<dt><span class="sect2"><a href="#bzcompress-init">3.3.1. <code class="computeroutput">BZ2_bzCompressInit</code></a></span></dt>
+<dt><span class="sect2"><a href="#bzCompress">3.3.2. <code class="computeroutput">BZ2_bzCompress</code></a></span></dt>
+<dt><span class="sect2"><a href="#bzCompress-end">3.3.3. <code class="computeroutput">BZ2_bzCompressEnd</code></a></span></dt>
+<dt><span class="sect2"><a href="#bzDecompress-init">3.3.4. <code class="computeroutput">BZ2_bzDecompressInit</code></a></span></dt>
+<dt><span class="sect2"><a href="#bzDecompress">3.3.5. <code class="computeroutput">BZ2_bzDecompress</code></a></span></dt>
+<dt><span class="sect2"><a href="#bzDecompress-end">3.3.6. <code class="computeroutput">BZ2_bzDecompressEnd</code></a></span></dt>
+</dl></dd>
+<dt><span class="sect1"><a href="#hl-interface">3.4. High-level interface</a></span></dt>
+<dd><dl>
+<dt><span class="sect2"><a href="#bzreadopen">3.4.1. <code class="computeroutput">BZ2_bzReadOpen</code></a></span></dt>
+<dt><span class="sect2"><a href="#bzread">3.4.2. <code class="computeroutput">BZ2_bzRead</code></a></span></dt>
+<dt><span class="sect2"><a href="#bzreadgetunused">3.4.3. <code class="computeroutput">BZ2_bzReadGetUnused</code></a></span></dt>
+<dt><span class="sect2"><a href="#bzreadclose">3.4.4. <code class="computeroutput">BZ2_bzReadClose</code></a></span></dt>
+<dt><span class="sect2"><a href="#bzwriteopen">3.4.5. <code class="computeroutput">BZ2_bzWriteOpen</code></a></span></dt>
+<dt><span class="sect2"><a href="#bzwrite">3.4.6. <code class="computeroutput">BZ2_bzWrite</code></a></span></dt>
+<dt><span class="sect2"><a href="#bzwriteclose">3.4.7. <code class="computeroutput">BZ2_bzWriteClose</code></a></span></dt>
+<dt><span class="sect2"><a href="#embed">3.4.8. Handling embedded compressed data streams</a></span></dt>
+<dt><span class="sect2"><a href="#std-rdwr">3.4.9. Standard file-reading/writing code</a></span></dt>
+</dl></dd>
+<dt><span class="sect1"><a href="#util-fns">3.5. Utility functions</a></span></dt>
+<dd><dl>
+<dt><span class="sect2"><a href="#bzbufftobuffcompress">3.5.1. <code class="computeroutput">BZ2_bzBuffToBuffCompress</code></a></span></dt>
+<dt><span class="sect2"><a href="#bzbufftobuffdecompress">3.5.2. <code class="computeroutput">BZ2_bzBuffToBuffDecompress</code></a></span></dt>
+</dl></dd>
+<dt><span class="sect1"><a href="#zlib-compat">3.6. <code class="computeroutput">zlib</code> compatibility functions</a></span></dt>
+<dt><span class="sect1"><a href="#stdio-free">3.7. Using the library in a <code class="computeroutput">stdio</code>-free environment</a></span></dt>
+<dd><dl>
+<dt><span class="sect2"><a href="#stdio-bye">3.7.1. Getting rid of <code class="computeroutput">stdio</code></a></span></dt>
+<dt><span class="sect2"><a href="#critical-error">3.7.2. Critical error handling</a></span></dt>
+</dl></dd>
+<dt><span class="sect1"><a href="#win-dll">3.8. Making a Windows DLL</a></span></dt>
+</dl>
+</div>
+<p>This chapter describes the programming interface to
+<code class="computeroutput">libbzip2</code>.</p>
+<p>For general background information, particularly about
+memory use and performance aspects, you'd be well advised to read
+<a href="#using">How to use bzip2</a> as well.</p>
+<div class="sect1" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="top-level"></a>3.1. Top-level structure</h2></div></div></div>
+<p><code class="computeroutput">libbzip2</code> is a flexible
+library for compressing and decompressing data in the
+<code class="computeroutput">bzip2</code> data format. Although
+packaged as a single entity, it helps to regard the library as
+three separate parts: the low level interface, and the high level
+interface, and some utility functions.</p>
+<p>The structure of
+<code class="computeroutput">libbzip2</code>'s interfaces is similar
+to that of Jean-loup Gailly's and Mark Adler's excellent
+<code class="computeroutput">zlib</code> library.</p>
+<p>All externally visible symbols have names beginning
+<code class="computeroutput">BZ2_</code>. This is new in version
+1.0. The intention is to minimise pollution of the namespaces of
+library clients.</p>
+<p>To use any part of the library, you need to
+<code class="computeroutput">#include &lt;bzlib.h&gt;</code>
+into your sources.</p>
+<div class="sect2" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="ll-summary"></a>3.1.1. Low-level summary</h3></div></div></div>
+<p>This interface provides services for compressing and
+decompressing data in memory. There's no provision for dealing
+with files, streams or any other I/O mechanisms, just straight
+memory-to-memory work. In fact, this part of the library can be
+compiled without inclusion of
+<code class="computeroutput">stdio.h</code>, which may be helpful
+for embedded applications.</p>
+<p>The low-level part of the library has no global variables
+and is therefore thread-safe.</p>
+<p>Six routines make up the low level interface:
+<code class="computeroutput">BZ2_bzCompressInit</code>,
+<code class="computeroutput">BZ2_bzCompress</code>, and
+<code class="computeroutput">BZ2_bzCompressEnd</code> for
+compression, and a corresponding trio
+<code class="computeroutput">BZ2_bzDecompressInit</code>,
+<code class="computeroutput">BZ2_bzDecompress</code> and
+<code class="computeroutput">BZ2_bzDecompressEnd</code> for
+decompression. The <code class="computeroutput">*Init</code>
+functions allocate memory for compression/decompression and do
+other initialisations, whilst the
+<code class="computeroutput">*End</code> functions close down
+operations and release memory.</p>
+<p>The real work is done by
+<code class="computeroutput">BZ2_bzCompress</code> and
+<code class="computeroutput">BZ2_bzDecompress</code>. These
+compress and decompress data from a user-supplied input buffer to
+a user-supplied output buffer. These buffers can be any size;
+arbitrary quantities of data are handled by making repeated calls
+to these functions. This is a flexible mechanism allowing a
+consumer-pull style of activity, or producer-push, or a mixture
+of both.</p>
+</div>
+<div class="sect2" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="hl-summary"></a>3.1.2. High-level summary</h3></div></div></div>
+<p>This interface provides some handy wrappers around the
+low-level interface to facilitate reading and writing
+<code class="computeroutput">bzip2</code> format files
+(<code class="computeroutput">.bz2</code> files). The routines
+provide hooks to facilitate reading files in which the
+<code class="computeroutput">bzip2</code> data stream is embedded
+within some larger-scale file structure, or where there are
+multiple <code class="computeroutput">bzip2</code> data streams
+concatenated end-to-end.</p>
+<p>For reading files,
+<code class="computeroutput">BZ2_bzReadOpen</code>,
+<code class="computeroutput">BZ2_bzRead</code>,
+<code class="computeroutput">BZ2_bzReadClose</code> and
+<code class="computeroutput">BZ2_bzReadGetUnused</code> are
+supplied. For writing files,
+<code class="computeroutput">BZ2_bzWriteOpen</code>,
+<code class="computeroutput">BZ2_bzWrite</code> and
+<code class="computeroutput">BZ2_bzWriteFinish</code> are
+available.</p>
+<p>As with the low-level library, no global variables are used
+so the library is per se thread-safe. However, if I/O errors
+occur whilst reading or writing the underlying compressed files,
+you may have to consult <code class="computeroutput">errno</code> to
+determine the cause of the error. In that case, you'd need a C
+library which correctly supports
+<code class="computeroutput">errno</code> in a multithreaded
+environment.</p>
+<p>To make the library a little simpler and more portable,
+<code class="computeroutput">BZ2_bzReadOpen</code> and
+<code class="computeroutput">BZ2_bzWriteOpen</code> require you to
+pass them file handles (<code class="computeroutput">FILE*</code>s)
+which have previously been opened for reading or writing
+respectively. That avoids portability problems associated with
+file operations and file attributes, whilst not being much of an
+imposition on the programmer.</p>
+</div>
+<div class="sect2" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="util-fns-summary"></a>3.1.3. Utility functions summary</h3></div></div></div>
+<p>For very simple needs,
+<code class="computeroutput">BZ2_bzBuffToBuffCompress</code> and
+<code class="computeroutput">BZ2_bzBuffToBuffDecompress</code> are
+provided. These compress data in memory from one buffer to
+another buffer in a single function call. You should assess
+whether these functions fulfill your memory-to-memory
+compression/decompression requirements before investing effort in
+understanding the more general but more complex low-level
+interface.</p>
+<p>Yoshioka Tsuneo
+(<code class="computeroutput">tsuneo@rr.iij4u.or.jp</code>) has
+contributed some functions to give better
+<code class="computeroutput">zlib</code> compatibility. These
+functions are <code class="computeroutput">BZ2_bzopen</code>,
+<code class="computeroutput">BZ2_bzread</code>,
+<code class="computeroutput">BZ2_bzwrite</code>,
+<code class="computeroutput">BZ2_bzflush</code>,
+<code class="computeroutput">BZ2_bzclose</code>,
+<code class="computeroutput">BZ2_bzerror</code> and
+<code class="computeroutput">BZ2_bzlibVersion</code>. You may find
+these functions more convenient for simple file reading and
+writing, than those in the high-level interface. These functions
+are not (yet) officially part of the library, and are minimally
+documented here. If they break, you get to keep all the pieces.
+I hope to document them properly when time permits.</p>
+<p>Yoshioka also contributed modifications to allow the
+library to be built as a Windows DLL.</p>
+</div>
+</div>
+<div class="sect1" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="err-handling"></a>3.2. Error handling</h2></div></div></div>
+<p>The library is designed to recover cleanly in all
+situations, including the worst-case situation of decompressing
+random data. I'm not 100% sure that it can always do this, so
+you might want to add a signal handler to catch segmentation
+violations during decompression if you are feeling especially
+paranoid. I would be interested in hearing more about the
+robustness of the library to corrupted compressed data.</p>
+<p>Version 1.0.3 more robust in this respect than any
+previous version. Investigations with Valgrind (a tool for detecting
+problems with memory management) indicate
+that, at least for the few files I tested, all single-bit errors
+in the decompressed data are caught properly, with no
+segmentation faults, no uses of uninitialised data, no out of
+range reads or writes, and no infinite looping in the decompressor.
+So it's certainly pretty robust, although
+I wouldn't claim it to be totally bombproof.</p>
+<p>The file <code class="computeroutput">bzlib.h</code> contains
+all definitions needed to use the library. In particular, you
+should definitely not include
+<code class="computeroutput">bzlib_private.h</code>.</p>
+<p>In <code class="computeroutput">bzlib.h</code>, the various
+return values are defined. The following list is not intended as
+an exhaustive description of the circumstances in which a given
+value may be returned -- those descriptions are given later.
+Rather, it is intended to convey the rough meaning of each return
+value. The first five actions are normal and not intended to
+denote an error situation.</p>
+<div class="variablelist"><dl>
+<dt><span class="term"><code class="computeroutput">BZ_OK</code></span></dt>
+<dd><p>The requested action was completed
+ successfully.</p></dd>
+<dt><span class="term"><code class="computeroutput">BZ_RUN_OK, BZ_FLUSH_OK,
+ BZ_FINISH_OK</code></span></dt>
+<dd><p>In
+ <code class="computeroutput">BZ2_bzCompress</code>, the requested
+ flush/finish/nothing-special action was completed
+ successfully.</p></dd>
+<dt><span class="term"><code class="computeroutput">BZ_STREAM_END</code></span></dt>
+<dd><p>Compression of data was completed, or the
+ logical stream end was detected during
+ decompression.</p></dd>
+</dl></div>
+<p>The following return values indicate an error of some
+kind.</p>
+<div class="variablelist"><dl>
+<dt><span class="term"><code class="computeroutput">BZ_CONFIG_ERROR</code></span></dt>
+<dd><p>Indicates that the library has been improperly
+ compiled on your platform -- a major configuration error.
+ Specifically, it means that
+ <code class="computeroutput">sizeof(char)</code>,
+ <code class="computeroutput">sizeof(short)</code> and
+ <code class="computeroutput">sizeof(int)</code> are not 1, 2 and
+ 4 respectively, as they should be. Note that the library
+ should still work properly on 64-bit platforms which follow
+ the LP64 programming model -- that is, where
+ <code class="computeroutput">sizeof(long)</code> and
+ <code class="computeroutput">sizeof(void*)</code> are 8. Under
+ LP64, <code class="computeroutput">sizeof(int)</code> is still 4,
+ so <code class="computeroutput">libbzip2</code>, which doesn't
+ use the <code class="computeroutput">long</code> type, is
+ OK.</p></dd>
+<dt><span class="term"><code class="computeroutput">BZ_SEQUENCE_ERROR</code></span></dt>
+<dd><p>When using the library, it is important to call
+ the functions in the correct sequence and with data structures
+ (buffers etc) in the correct states.
+ <code class="computeroutput">libbzip2</code> checks as much as it
+ can to ensure this is happening, and returns
+ <code class="computeroutput">BZ_SEQUENCE_ERROR</code> if not.
+ Code which complies precisely with the function semantics, as
+ detailed below, should never receive this value; such an event
+ denotes buggy code which you should
+ investigate.</p></dd>
+<dt><span class="term"><code class="computeroutput">BZ_PARAM_ERROR</code></span></dt>
+<dd><p>Returned when a parameter to a function call is
+ out of range or otherwise manifestly incorrect. As with
+ <code class="computeroutput">BZ_SEQUENCE_ERROR</code>, this
+ denotes a bug in the client code. The distinction between
+ <code class="computeroutput">BZ_PARAM_ERROR</code> and
+ <code class="computeroutput">BZ_SEQUENCE_ERROR</code> is a bit
+ hazy, but still worth making.</p></dd>
+<dt><span class="term"><code class="computeroutput">BZ_MEM_ERROR</code></span></dt>
+<dd><p>Returned when a request to allocate memory
+ failed. Note that the quantity of memory needed to decompress
+ a stream cannot be determined until the stream's header has
+ been read. So
+ <code class="computeroutput">BZ2_bzDecompress</code> and
+ <code class="computeroutput">BZ2_bzRead</code> may return
+ <code class="computeroutput">BZ_MEM_ERROR</code> even though some
+ of the compressed data has been read. The same is not true
+ for compression; once
+ <code class="computeroutput">BZ2_bzCompressInit</code> or
+ <code class="computeroutput">BZ2_bzWriteOpen</code> have
+ successfully completed,
+ <code class="computeroutput">BZ_MEM_ERROR</code> cannot
+ occur.</p></dd>
+<dt><span class="term"><code class="computeroutput">BZ_DATA_ERROR</code></span></dt>
+<dd><p>Returned when a data integrity error is
+ detected during decompression. Most importantly, this means
+ when stored and computed CRCs for the data do not match. This
+ value is also returned upon detection of any other anomaly in
+ the compressed data.</p></dd>
+<dt><span class="term"><code class="computeroutput">BZ_DATA_ERROR_MAGIC</code></span></dt>
+<dd><p>As a special case of
+ <code class="computeroutput">BZ_DATA_ERROR</code>, it is
+ sometimes useful to know when the compressed stream does not
+ start with the correct magic bytes (<code class="computeroutput">'B' 'Z'
+ 'h'</code>).</p></dd>
+<dt><span class="term"><code class="computeroutput">BZ_IO_ERROR</code></span></dt>
+<dd><p>Returned by
+ <code class="computeroutput">BZ2_bzRead</code> and
+ <code class="computeroutput">BZ2_bzWrite</code> when there is an
+ error reading or writing in the compressed file, and by
+ <code class="computeroutput">BZ2_bzReadOpen</code> and
+ <code class="computeroutput">BZ2_bzWriteOpen</code> for attempts
+ to use a file for which the error indicator (viz,
+ <code class="computeroutput">ferror(f)</code>) is set. On
+ receipt of <code class="computeroutput">BZ_IO_ERROR</code>, the
+ caller should consult <code class="computeroutput">errno</code>
+ and/or <code class="computeroutput">perror</code> to acquire
+ operating-system specific information about the
+ problem.</p></dd>
+<dt><span class="term"><code class="computeroutput">BZ_UNEXPECTED_EOF</code></span></dt>
+<dd><p>Returned by
+ <code class="computeroutput">BZ2_bzRead</code> when the
+ compressed file finishes before the logical end of stream is
+ detected.</p></dd>
+<dt><span class="term"><code class="computeroutput">BZ_OUTBUFF_FULL</code></span></dt>
+<dd><p>Returned by
+ <code class="computeroutput">BZ2_bzBuffToBuffCompress</code> and
+ <code class="computeroutput">BZ2_bzBuffToBuffDecompress</code> to
+ indicate that the output data will not fit into the output
+ buffer provided.</p></dd>
+</dl></div>
+</div>
+<div class="sect1" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="low-level"></a>3.3. Low-level interface</h2></div></div></div>
+<div class="sect2" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="bzcompress-init"></a>3.3.1. <code class="computeroutput">BZ2_bzCompressInit</code></h3></div></div></div>
+<pre class="programlisting">typedef struct {
+ char *next_in;
+ unsigned int avail_in;
+ unsigned int total_in_lo32;
+ unsigned int total_in_hi32;
+
+ char *next_out;
+ unsigned int avail_out;
+ unsigned int total_out_lo32;
+ unsigned int total_out_hi32;
+
+ void *state;
+
+ void *(*bzalloc)(void *,int,int);
+ void (*bzfree)(void *,void *);
+ void *opaque;
+} bz_stream;
+
+int BZ2_bzCompressInit ( bz_stream *strm,
+ int blockSize100k,
+ int verbosity,
+ int workFactor );</pre>
+<p>Prepares for compression. The
+<code class="computeroutput">bz_stream</code> structure holds all
+data pertaining to the compression activity. A
+<code class="computeroutput">bz_stream</code> structure should be
+allocated and initialised prior to the call. The fields of
+<code class="computeroutput">bz_stream</code> comprise the entirety
+of the user-visible data. <code class="computeroutput">state</code>
+is a pointer to the private data structures required for
+compression.</p>
+<p>Custom memory allocators are supported, via fields
+<code class="computeroutput">bzalloc</code>,
+<code class="computeroutput">bzfree</code>, and
+<code class="computeroutput">opaque</code>. The value
+<code class="computeroutput">opaque</code> is passed to as the first
+argument to all calls to <code class="computeroutput">bzalloc</code>
+and <code class="computeroutput">bzfree</code>, but is otherwise
+ignored by the library. The call <code class="computeroutput">bzalloc (
+opaque, n, m )</code> is expected to return a pointer
+<code class="computeroutput">p</code> to <code class="computeroutput">n *
+m</code> bytes of memory, and <code class="computeroutput">bzfree (
+opaque, p )</code> should free that memory.</p>
+<p>If you don't want to use a custom memory allocator, set
+<code class="computeroutput">bzalloc</code>,
+<code class="computeroutput">bzfree</code> and
+<code class="computeroutput">opaque</code> to
+<code class="computeroutput">NULL</code>, and the library will then
+use the standard <code class="computeroutput">malloc</code> /
+<code class="computeroutput">free</code> routines.</p>
+<p>Before calling
+<code class="computeroutput">BZ2_bzCompressInit</code>, fields
+<code class="computeroutput">bzalloc</code>,
+<code class="computeroutput">bzfree</code> and
+<code class="computeroutput">opaque</code> should be filled
+appropriately, as just described. Upon return, the internal
+state will have been allocated and initialised, and
+<code class="computeroutput">total_in_lo32</code>,
+<code class="computeroutput">total_in_hi32</code>,
+<code class="computeroutput">total_out_lo32</code> and
+<code class="computeroutput">total_out_hi32</code> will have been
+set to zero. These four fields are used by the library to inform
+the caller of the total amount of data passed into and out of the
+library, respectively. You should not try to change them. As of
+version 1.0, 64-bit counts are maintained, even on 32-bit
+platforms, using the <code class="computeroutput">_hi32</code>
+fields to store the upper 32 bits of the count. So, for example,
+the total amount of data in is <code class="computeroutput">(total_in_hi32
+&lt;&lt; 32) + total_in_lo32</code>.</p>
+<p>Parameter <code class="computeroutput">blockSize100k</code>
+specifies the block size to be used for compression. It should
+be a value between 1 and 9 inclusive, and the actual block size
+used is 100000 x this figure. 9 gives the best compression but
+takes most memory.</p>
+<p>Parameter <code class="computeroutput">verbosity</code> should
+be set to a number between 0 and 4 inclusive. 0 is silent, and
+greater numbers give increasingly verbose monitoring/debugging
+output. If the library has been compiled with
+<code class="computeroutput">-DBZ_NO_STDIO</code>, no such output
+will appear for any verbosity setting.</p>
+<p>Parameter <code class="computeroutput">workFactor</code>
+controls how the compression phase behaves when presented with
+worst case, highly repetitive, input data. If compression runs
+into difficulties caused by repetitive data, the library switches
+from the standard sorting algorithm to a fallback algorithm. The
+fallback is slower than the standard algorithm by perhaps a
+factor of three, but always behaves reasonably, no matter how bad
+the input.</p>
+<p>Lower values of <code class="computeroutput">workFactor</code>
+reduce the amount of effort the standard algorithm will expend
+before resorting to the fallback. You should set this parameter
+carefully; too low, and many inputs will be handled by the
+fallback algorithm and so compress rather slowly, too high, and
+your average-to-worst case compression times can become very
+large. The default value of 30 gives reasonable behaviour over a
+wide range of circumstances.</p>
+<p>Allowable values range from 0 to 250 inclusive. 0 is a
+special case, equivalent to using the default value of 30.</p>
+<p>Note that the compressed output generated is the same
+regardless of whether or not the fallback algorithm is
+used.</p>
+<p>Be aware also that this parameter may disappear entirely in
+future versions of the library. In principle it should be
+possible to devise a good way to automatically choose which
+algorithm to use. Such a mechanism would render the parameter
+obsolete.</p>
+<p>Possible return values:</p>
+<pre class="programlisting">BZ_CONFIG_ERROR
+ if the library has been mis-compiled
+BZ_PARAM_ERROR
+ if strm is NULL
+ or blockSize &lt; 1 or blockSize &gt; 9
+ or verbosity &lt; 0 or verbosity &gt; 4
+ or workFactor &lt; 0 or workFactor &gt; 250
+BZ_MEM_ERROR
+ if not enough memory is available
+BZ_OK
+ otherwise</pre>
+<p>Allowable next actions:</p>
+<pre class="programlisting">BZ2_bzCompress
+ if BZ_OK is returned
+ no specific action needed in case of error</pre>
+</div>
+<div class="sect2" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="bzCompress"></a>3.3.2. <code class="computeroutput">BZ2_bzCompress</code></h3></div></div></div>
+<pre class="programlisting">int BZ2_bzCompress ( bz_stream *strm, int action );</pre>
+<p>Provides more input and/or output buffer space for the
+library. The caller maintains input and output buffers, and
+calls <code class="computeroutput">BZ2_bzCompress</code> to transfer
+data between them.</p>
+<p>Before each call to
+<code class="computeroutput">BZ2_bzCompress</code>,
+<code class="computeroutput">next_in</code> should point at the data
+to be compressed, and <code class="computeroutput">avail_in</code>
+should indicate how many bytes the library may read.
+<code class="computeroutput">BZ2_bzCompress</code> updates
+<code class="computeroutput">next_in</code>,
+<code class="computeroutput">avail_in</code> and
+<code class="computeroutput">total_in</code> to reflect the number
+of bytes it has read.</p>
+<p>Similarly, <code class="computeroutput">next_out</code> should
+point to a buffer in which the compressed data is to be placed,
+with <code class="computeroutput">avail_out</code> indicating how
+much output space is available.
+<code class="computeroutput">BZ2_bzCompress</code> updates
+<code class="computeroutput">next_out</code>,
+<code class="computeroutput">avail_out</code> and
+<code class="computeroutput">total_out</code> to reflect the number
+of bytes output.</p>
+<p>You may provide and remove as little or as much data as you
+like on each call of
+<code class="computeroutput">BZ2_bzCompress</code>. In the limit,
+it is acceptable to supply and remove data one byte at a time,
+although this would be terribly inefficient. You should always
+ensure that at least one byte of output space is available at
+each call.</p>
+<p>A second purpose of
+<code class="computeroutput">BZ2_bzCompress</code> is to request a
+change of mode of the compressed stream.</p>
+<p>Conceptually, a compressed stream can be in one of four
+states: IDLE, RUNNING, FLUSHING and FINISHING. Before
+initialisation
+(<code class="computeroutput">BZ2_bzCompressInit</code>) and after
+termination (<code class="computeroutput">BZ2_bzCompressEnd</code>),
+a stream is regarded as IDLE.</p>
+<p>Upon initialisation
+(<code class="computeroutput">BZ2_bzCompressInit</code>), the stream
+is placed in the RUNNING state. Subsequent calls to
+<code class="computeroutput">BZ2_bzCompress</code> should pass
+<code class="computeroutput">BZ_RUN</code> as the requested action;
+other actions are illegal and will result in
+<code class="computeroutput">BZ_SEQUENCE_ERROR</code>.</p>
+<p>At some point, the calling program will have provided all
+the input data it wants to. It will then want to finish up -- in
+effect, asking the library to process any data it might have
+buffered internally. In this state,
+<code class="computeroutput">BZ2_bzCompress</code> will no longer
+attempt to read data from
+<code class="computeroutput">next_in</code>, but it will want to
+write data to <code class="computeroutput">next_out</code>. Because
+the output buffer supplied by the user can be arbitrarily small,
+the finishing-up operation cannot necessarily be done with a
+single call of
+<code class="computeroutput">BZ2_bzCompress</code>.</p>
+<p>Instead, the calling program passes
+<code class="computeroutput">BZ_FINISH</code> as an action to
+<code class="computeroutput">BZ2_bzCompress</code>. This changes
+the stream's state to FINISHING. Any remaining input (ie,
+<code class="computeroutput">next_in[0 .. avail_in-1]</code>) is
+compressed and transferred to the output buffer. To do this,
+<code class="computeroutput">BZ2_bzCompress</code> must be called
+repeatedly until all the output has been consumed. At that
+point, <code class="computeroutput">BZ2_bzCompress</code> returns
+<code class="computeroutput">BZ_STREAM_END</code>, and the stream's
+state is set back to IDLE.
+<code class="computeroutput">BZ2_bzCompressEnd</code> should then be
+called.</p>
+<p>Just to make sure the calling program does not cheat, the
+library makes a note of <code class="computeroutput">avail_in</code>
+at the time of the first call to
+<code class="computeroutput">BZ2_bzCompress</code> which has
+<code class="computeroutput">BZ_FINISH</code> as an action (ie, at
+the time the program has announced its intention to not supply
+any more input). By comparing this value with that of
+<code class="computeroutput">avail_in</code> over subsequent calls
+to <code class="computeroutput">BZ2_bzCompress</code>, the library
+can detect any attempts to slip in more data to compress. Any
+calls for which this is detected will return
+<code class="computeroutput">BZ_SEQUENCE_ERROR</code>. This
+indicates a programming mistake which should be corrected.</p>
+<p>Instead of asking to finish, the calling program may ask
+<code class="computeroutput">BZ2_bzCompress</code> to take all the
+remaining input, compress it and terminate the current
+(Burrows-Wheeler) compression block. This could be useful for
+error control purposes. The mechanism is analogous to that for
+finishing: call <code class="computeroutput">BZ2_bzCompress</code>
+with an action of <code class="computeroutput">BZ_FLUSH</code>,
+remove output data, and persist with the
+<code class="computeroutput">BZ_FLUSH</code> action until the value
+<code class="computeroutput">BZ_RUN</code> is returned. As with
+finishing, <code class="computeroutput">BZ2_bzCompress</code>
+detects any attempt to provide more input data once the flush has
+begun.</p>
+<p>Once the flush is complete, the stream returns to the
+normal RUNNING state.</p>
+<p>This all sounds pretty complex, but isn't really. Here's a
+table which shows which actions are allowable in each state, what
+action will be taken, what the next state is, and what the
+non-error return values are. Note that you can't explicitly ask
+what state the stream is in, but nor do you need to -- it can be
+inferred from the values returned by
+<code class="computeroutput">BZ2_bzCompress</code>.</p>
+<pre class="programlisting">IDLE/any
+ Illegal. IDLE state only exists after BZ2_bzCompressEnd or
+ before BZ2_bzCompressInit.
+ Return value = BZ_SEQUENCE_ERROR
+
+RUNNING/BZ_RUN
+ Compress from next_in to next_out as much as possible.
+ Next state = RUNNING
+ Return value = BZ_RUN_OK
+
+RUNNING/BZ_FLUSH
+ Remember current value of next_in. Compress from next_in
+ to next_out as much as possible, but do not accept any more input.
+ Next state = FLUSHING
+ Return value = BZ_FLUSH_OK
+
+RUNNING/BZ_FINISH
+ Remember current value of next_in. Compress from next_in
+ to next_out as much as possible, but do not accept any more input.
+ Next state = FINISHING
+ Return value = BZ_FINISH_OK
+
+FLUSHING/BZ_FLUSH
+ Compress from next_in to next_out as much as possible,
+ but do not accept any more input.
+ If all the existing input has been used up and all compressed
+ output has been removed
+ Next state = RUNNING; Return value = BZ_RUN_OK
+ else
+ Next state = FLUSHING; Return value = BZ_FLUSH_OK
+
+FLUSHING/other
+ Illegal.
+ Return value = BZ_SEQUENCE_ERROR
+
+FINISHING/BZ_FINISH
+ Compress from next_in to next_out as much as possible,
+ but to not accept any more input.
+ If all the existing input has been used up and all compressed
+ output has been removed
+ Next state = IDLE; Return value = BZ_STREAM_END
+ else
+ Next state = FINISHING; Return value = BZ_FINISH_OK
+
+FINISHING/other
+ Illegal.
+ Return value = BZ_SEQUENCE_ERROR</pre>
+<p>That still looks complicated? Well, fair enough. The
+usual sequence of calls for compressing a load of data is:</p>
+<div class="orderedlist"><ol type="1">
+<li><p>Get started with
+ <code class="computeroutput">BZ2_bzCompressInit</code>.</p></li>
+<li><p>Shovel data in and shlurp out its compressed form
+ using zero or more calls of
+ <code class="computeroutput">BZ2_bzCompress</code> with action =
+ <code class="computeroutput">BZ_RUN</code>.</p></li>
+<li><p>Finish up. Repeatedly call
+ <code class="computeroutput">BZ2_bzCompress</code> with action =
+ <code class="computeroutput">BZ_FINISH</code>, copying out the
+ compressed output, until
+ <code class="computeroutput">BZ_STREAM_END</code> is
+ returned.</p></li>
+<li><p>Close up and go home. Call
+ <code class="computeroutput">BZ2_bzCompressEnd</code>.</p></li>
+</ol></div>
+<p>If the data you want to compress fits into your input
+buffer all at once, you can skip the calls of
+<code class="computeroutput">BZ2_bzCompress ( ..., BZ_RUN )</code>
+and just do the <code class="computeroutput">BZ2_bzCompress ( ..., BZ_FINISH
+)</code> calls.</p>
+<p>All required memory is allocated by
+<code class="computeroutput">BZ2_bzCompressInit</code>. The
+compression library can accept any data at all (obviously). So
+you shouldn't get any error return values from the
+<code class="computeroutput">BZ2_bzCompress</code> calls. If you
+do, they will be
+<code class="computeroutput">BZ_SEQUENCE_ERROR</code>, and indicate
+a bug in your programming.</p>
+<p>Trivial other possible return values:</p>
+<pre class="programlisting">BZ_PARAM_ERROR
+ if strm is NULL, or strm-&gt;s is NULL</pre>
+</div>
+<div class="sect2" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="bzCompress-end"></a>3.3.3. <code class="computeroutput">BZ2_bzCompressEnd</code></h3></div></div></div>
+<pre class="programlisting">int BZ2_bzCompressEnd ( bz_stream *strm );</pre>
+<p>Releases all memory associated with a compression
+stream.</p>
+<p>Possible return values:</p>
+<pre class="programlisting">BZ_PARAM_ERROR if strm is NULL or strm-&gt;s is NULL
+BZ_OK otherwise</pre>
+</div>
+<div class="sect2" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="bzDecompress-init"></a>3.3.4. <code class="computeroutput">BZ2_bzDecompressInit</code></h3></div></div></div>
+<pre class="programlisting">int BZ2_bzDecompressInit ( bz_stream *strm, int verbosity, int small );</pre>
+<p>Prepares for decompression. As with
+<code class="computeroutput">BZ2_bzCompressInit</code>, a
+<code class="computeroutput">bz_stream</code> record should be
+allocated and initialised before the call. Fields
+<code class="computeroutput">bzalloc</code>,
+<code class="computeroutput">bzfree</code> and
+<code class="computeroutput">opaque</code> should be set if a custom
+memory allocator is required, or made
+<code class="computeroutput">NULL</code> for the normal
+<code class="computeroutput">malloc</code> /
+<code class="computeroutput">free</code> routines. Upon return, the
+internal state will have been initialised, and
+<code class="computeroutput">total_in</code> and
+<code class="computeroutput">total_out</code> will be zero.</p>
+<p>For the meaning of parameter
+<code class="computeroutput">verbosity</code>, see
+<code class="computeroutput">BZ2_bzCompressInit</code>.</p>
+<p>If <code class="computeroutput">small</code> is nonzero, the
+library will use an alternative decompression algorithm which
+uses less memory but at the cost of decompressing more slowly
+(roughly speaking, half the speed, but the maximum memory
+requirement drops to around 2300k). See <a href="#using">How to use bzip2</a>
+for more information on memory management.</p>
+<p>Note that the amount of memory needed to decompress a
+stream cannot be determined until the stream's header has been
+read, so even if
+<code class="computeroutput">BZ2_bzDecompressInit</code> succeeds, a
+subsequent <code class="computeroutput">BZ2_bzDecompress</code>
+could fail with
+<code class="computeroutput">BZ_MEM_ERROR</code>.</p>
+<p>Possible return values:</p>
+<pre class="programlisting">BZ_CONFIG_ERROR
+ if the library has been mis-compiled
+BZ_PARAM_ERROR
+ if ( small != 0 &amp;&amp; small != 1 )
+ or (verbosity &lt;; 0 || verbosity &gt; 4)
+BZ_MEM_ERROR
+ if insufficient memory is available</pre>
+<p>Allowable next actions:</p>
+<pre class="programlisting">BZ2_bzDecompress
+ if BZ_OK was returned
+ no specific action required in case of error</pre>
+</div>
+<div class="sect2" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="bzDecompress"></a>3.3.5. <code class="computeroutput">BZ2_bzDecompress</code></h3></div></div></div>
+<pre class="programlisting">int BZ2_bzDecompress ( bz_stream *strm );</pre>
+<p>Provides more input and/out output buffer space for the
+library. The caller maintains input and output buffers, and uses
+<code class="computeroutput">BZ2_bzDecompress</code> to transfer
+data between them.</p>
+<p>Before each call to
+<code class="computeroutput">BZ2_bzDecompress</code>,
+<code class="computeroutput">next_in</code> should point at the
+compressed data, and <code class="computeroutput">avail_in</code>
+should indicate how many bytes the library may read.
+<code class="computeroutput">BZ2_bzDecompress</code> updates
+<code class="computeroutput">next_in</code>,
+<code class="computeroutput">avail_in</code> and
+<code class="computeroutput">total_in</code> to reflect the number
+of bytes it has read.</p>
+<p>Similarly, <code class="computeroutput">next_out</code> should
+point to a buffer in which the uncompressed output is to be
+placed, with <code class="computeroutput">avail_out</code>
+indicating how much output space is available.
+<code class="computeroutput">BZ2_bzCompress</code> updates
+<code class="computeroutput">next_out</code>,
+<code class="computeroutput">avail_out</code> and
+<code class="computeroutput">total_out</code> to reflect the number
+of bytes output.</p>
+<p>You may provide and remove as little or as much data as you
+like on each call of
+<code class="computeroutput">BZ2_bzDecompress</code>. In the limit,
+it is acceptable to supply and remove data one byte at a time,
+although this would be terribly inefficient. You should always
+ensure that at least one byte of output space is available at
+each call.</p>
+<p>Use of <code class="computeroutput">BZ2_bzDecompress</code> is
+simpler than
+<code class="computeroutput">BZ2_bzCompress</code>.</p>
+<p>You should provide input and remove output as described
+above, and repeatedly call
+<code class="computeroutput">BZ2_bzDecompress</code> until
+<code class="computeroutput">BZ_STREAM_END</code> is returned.
+Appearance of <code class="computeroutput">BZ_STREAM_END</code>
+denotes that <code class="computeroutput">BZ2_bzDecompress</code>
+has detected the logical end of the compressed stream.
+<code class="computeroutput">BZ2_bzDecompress</code> will not
+produce <code class="computeroutput">BZ_STREAM_END</code> until all
+output data has been placed into the output buffer, so once
+<code class="computeroutput">BZ_STREAM_END</code> appears, you are
+guaranteed to have available all the decompressed output, and
+<code class="computeroutput">BZ2_bzDecompressEnd</code> can safely
+be called.</p>
+<p>If case of an error return value, you should call
+<code class="computeroutput">BZ2_bzDecompressEnd</code> to clean up
+and release memory.</p>
+<p>Possible return values:</p>
+<pre class="programlisting">BZ_PARAM_ERROR
+ if strm is NULL or strm-&gt;s is NULL
+ or strm-&gt;avail_out &lt; 1
+BZ_DATA_ERROR
+ if a data integrity error is detected in the compressed stream
+BZ_DATA_ERROR_MAGIC
+ if the compressed stream doesn't begin with the right magic bytes
+BZ_MEM_ERROR
+ if there wasn't enough memory available
+BZ_STREAM_END
+ if the logical end of the data stream was detected and all
+ output in has been consumed, eg s--&gt;avail_out &gt; 0
+BZ_OK
+ otherwise</pre>
+<p>Allowable next actions:</p>
+<pre class="programlisting">BZ2_bzDecompress
+ if BZ_OK was returned
+BZ2_bzDecompressEnd
+ otherwise</pre>
+</div>
+<div class="sect2" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="bzDecompress-end"></a>3.3.6. <code class="computeroutput">BZ2_bzDecompressEnd</code></h3></div></div></div>
+<pre class="programlisting">int BZ2_bzDecompressEnd ( bz_stream *strm );</pre>
+<p>Releases all memory associated with a decompression
+stream.</p>
+<p>Possible return values:</p>
+<pre class="programlisting">BZ_PARAM_ERROR
+ if strm is NULL or strm-&gt;s is NULL
+BZ_OK
+ otherwise</pre>
+<p>Allowable next actions:</p>
+<pre class="programlisting"> None.</pre>
+</div>
+</div>
+<div class="sect1" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="hl-interface"></a>3.4. High-level interface</h2></div></div></div>
+<p>This interface provides functions for reading and writing
+<code class="computeroutput">bzip2</code> format files. First, some
+general points.</p>
+<div class="itemizedlist"><ul type="bullet">
+<li style="list-style-type: disc"><p>All of the functions take an
+ <code class="computeroutput">int*</code> first argument,
+ <code class="computeroutput">bzerror</code>. After each call,
+ <code class="computeroutput">bzerror</code> should be consulted
+ first to determine the outcome of the call. If
+ <code class="computeroutput">bzerror</code> is
+ <code class="computeroutput">BZ_OK</code>, the call completed
+ successfully, and only then should the return value of the
+ function (if any) be consulted. If
+ <code class="computeroutput">bzerror</code> is
+ <code class="computeroutput">BZ_IO_ERROR</code>, there was an
+ error reading/writing the underlying compressed file, and you
+ should then consult <code class="computeroutput">errno</code> /
+ <code class="computeroutput">perror</code> to determine the cause
+ of the difficulty. <code class="computeroutput">bzerror</code>
+ may also be set to various other values; precise details are
+ given on a per-function basis below.</p></li>
+<li style="list-style-type: disc"><p>If <code class="computeroutput">bzerror</code> indicates
+ an error (ie, anything except
+ <code class="computeroutput">BZ_OK</code> and
+ <code class="computeroutput">BZ_STREAM_END</code>), you should
+ immediately call
+ <code class="computeroutput">BZ2_bzReadClose</code> (or
+ <code class="computeroutput">BZ2_bzWriteClose</code>, depending on
+ whether you are attempting to read or to write) to free up all
+ resources associated with the stream. Once an error has been
+ indicated, behaviour of all calls except
+ <code class="computeroutput">BZ2_bzReadClose</code>
+ (<code class="computeroutput">BZ2_bzWriteClose</code>) is
+ undefined. The implication is that (1)
+ <code class="computeroutput">bzerror</code> should be checked
+ after each call, and (2) if
+ <code class="computeroutput">bzerror</code> indicates an error,
+ <code class="computeroutput">BZ2_bzReadClose</code>
+ (<code class="computeroutput">BZ2_bzWriteClose</code>) should then
+ be called to clean up.</p></li>
+<li style="list-style-type: disc"><p>The <code class="computeroutput">FILE*</code> arguments
+ passed to <code class="computeroutput">BZ2_bzReadOpen</code> /
+ <code class="computeroutput">BZ2_bzWriteOpen</code> should be set
+ to binary mode. Most Unix systems will do this by default, but
+ other platforms, including Windows and Mac, will not. If you
+ omit this, you may encounter problems when moving code to new
+ platforms.</p></li>
+<li style="list-style-type: disc"><p>Memory allocation requests are handled by
+ <code class="computeroutput">malloc</code> /
+ <code class="computeroutput">free</code>. At present there is no
+ facility for user-defined memory allocators in the file I/O
+ functions (could easily be added, though).</p></li>
+</ul></div>
+<div class="sect2" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="bzreadopen"></a>3.4.1. <code class="computeroutput">BZ2_bzReadOpen</code></h3></div></div></div>
+<pre class="programlisting">typedef void BZFILE;
+
+BZFILE *BZ2_bzReadOpen( int *bzerror, FILE *f,
+ int verbosity, int small,
+ void *unused, int nUnused );</pre>
+<p>Prepare to read compressed data from file handle
+<code class="computeroutput">f</code>.
+<code class="computeroutput">f</code> should refer to a file which
+has been opened for reading, and for which the error indicator
+(<code class="computeroutput">ferror(f)</code>)is not set. If
+<code class="computeroutput">small</code> is 1, the library will try
+to decompress using less memory, at the expense of speed.</p>
+<p>For reasons explained below,
+<code class="computeroutput">BZ2_bzRead</code> will decompress the
+<code class="computeroutput">nUnused</code> bytes starting at
+<code class="computeroutput">unused</code>, before starting to read
+from the file <code class="computeroutput">f</code>. At most
+<code class="computeroutput">BZ_MAX_UNUSED</code> bytes may be
+supplied like this. If this facility is not required, you should
+pass <code class="computeroutput">NULL</code> and
+<code class="computeroutput">0</code> for
+<code class="computeroutput">unused</code> and
+n<code class="computeroutput">Unused</code> respectively.</p>
+<p>For the meaning of parameters
+<code class="computeroutput">small</code> and
+<code class="computeroutput">verbosity</code>, see
+<code class="computeroutput">BZ2_bzDecompressInit</code>.</p>
+<p>The amount of memory needed to decompress a file cannot be
+determined until the file's header has been read. So it is
+possible that <code class="computeroutput">BZ2_bzReadOpen</code>
+returns <code class="computeroutput">BZ_OK</code> but a subsequent
+call of <code class="computeroutput">BZ2_bzRead</code> will return
+<code class="computeroutput">BZ_MEM_ERROR</code>.</p>
+<p>Possible assignments to
+<code class="computeroutput">bzerror</code>:</p>
+<pre class="programlisting">BZ_CONFIG_ERROR
+ if the library has been mis-compiled
+BZ_PARAM_ERROR
+ if f is NULL
+ or small is neither 0 nor 1
+ or ( unused == NULL &amp;&amp; nUnused != 0 )
+ or ( unused != NULL &amp;&amp; !(0 &lt;= nUnused &lt;= BZ_MAX_UNUSED) )
+BZ_IO_ERROR
+ if ferror(f) is nonzero
+BZ_MEM_ERROR
+ if insufficient memory is available
+BZ_OK
+ otherwise.</pre>
+<p>Possible return values:</p>
+<pre class="programlisting">Pointer to an abstract BZFILE
+ if bzerror is BZ_OK
+NULL
+ otherwise</pre>
+<p>Allowable next actions:</p>
+<pre class="programlisting">BZ2_bzRead
+ if bzerror is BZ_OK
+BZ2_bzClose
+ otherwise</pre>
+</div>
+<div class="sect2" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="bzread"></a>3.4.2. <code class="computeroutput">BZ2_bzRead</code></h3></div></div></div>
+<pre class="programlisting">int BZ2_bzRead ( int *bzerror, BZFILE *b, void *buf, int len );</pre>
+<p>Reads up to <code class="computeroutput">len</code>
+(uncompressed) bytes from the compressed file
+<code class="computeroutput">b</code> into the buffer
+<code class="computeroutput">buf</code>. If the read was
+successful, <code class="computeroutput">bzerror</code> is set to
+<code class="computeroutput">BZ_OK</code> and the number of bytes
+read is returned. If the logical end-of-stream was detected,
+<code class="computeroutput">bzerror</code> will be set to
+<code class="computeroutput">BZ_STREAM_END</code>, and the number of
+bytes read is returned. All other
+<code class="computeroutput">bzerror</code> values denote an
+error.</p>
+<p><code class="computeroutput">BZ2_bzRead</code> will supply
+<code class="computeroutput">len</code> bytes, unless the logical
+stream end is detected or an error occurs. Because of this, it
+is possible to detect the stream end by observing when the number
+of bytes returned is less than the number requested.
+Nevertheless, this is regarded as inadvisable; you should instead
+check <code class="computeroutput">bzerror</code> after every call
+and watch out for
+<code class="computeroutput">BZ_STREAM_END</code>.</p>
+<p>Internally, <code class="computeroutput">BZ2_bzRead</code>
+copies data from the compressed file in chunks of size
+<code class="computeroutput">BZ_MAX_UNUSED</code> bytes before
+decompressing it. If the file contains more bytes than strictly
+needed to reach the logical end-of-stream,
+<code class="computeroutput">BZ2_bzRead</code> will almost certainly
+read some of the trailing data before signalling
+<code class="computeroutput">BZ_SEQUENCE_END</code>. To collect the
+read but unused data once
+<code class="computeroutput">BZ_SEQUENCE_END</code> has appeared,
+call <code class="computeroutput">BZ2_bzReadGetUnused</code>
+immediately before
+<code class="computeroutput">BZ2_bzReadClose</code>.</p>
+<p>Possible assignments to
+<code class="computeroutput">bzerror</code>:</p>
+<pre class="programlisting">BZ_PARAM_ERROR
+ if b is NULL or buf is NULL or len &lt; 0
+BZ_SEQUENCE_ERROR
+ if b was opened with BZ2_bzWriteOpen
+BZ_IO_ERROR
+ if there is an error reading from the compressed file
+BZ_UNEXPECTED_EOF
+ if the compressed file ended before
+ the logical end-of-stream was detected
+BZ_DATA_ERROR
+ if a data integrity error was detected in the compressed stream
+BZ_DATA_ERROR_MAGIC
+ if the stream does not begin with the requisite header bytes
+ (ie, is not a bzip2 data file). This is really
+ a special case of BZ_DATA_ERROR.
+BZ_MEM_ERROR
+ if insufficient memory was available
+BZ_STREAM_END
+ if the logical end of stream was detected.
+BZ_OK
+ otherwise.</pre>
+<p>Possible return values:</p>
+<pre class="programlisting">number of bytes read
+ if bzerror is BZ_OK or BZ_STREAM_END
+undefined
+ otherwise</pre>
+<p>Allowable next actions:</p>
+<pre class="programlisting">collect data from buf, then BZ2_bzRead or BZ2_bzReadClose
+ if bzerror is BZ_OK
+collect data from buf, then BZ2_bzReadClose or BZ2_bzReadGetUnused
+ if bzerror is BZ_SEQUENCE_END
+BZ2_bzReadClose
+ otherwise</pre>
+</div>
+<div class="sect2" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="bzreadgetunused"></a>3.4.3. <code class="computeroutput">BZ2_bzReadGetUnused</code></h3></div></div></div>
+<pre class="programlisting">void BZ2_bzReadGetUnused( int* bzerror, BZFILE *b,
+ void** unused, int* nUnused );</pre>
+<p>Returns data which was read from the compressed file but
+was not needed to get to the logical end-of-stream.
+<code class="computeroutput">*unused</code> is set to the address of
+the data, and <code class="computeroutput">*nUnused</code> to the
+number of bytes. <code class="computeroutput">*nUnused</code> will
+be set to a value between <code class="computeroutput">0</code> and
+<code class="computeroutput">BZ_MAX_UNUSED</code> inclusive.</p>
+<p>This function may only be called once
+<code class="computeroutput">BZ2_bzRead</code> has signalled
+<code class="computeroutput">BZ_STREAM_END</code> but before
+<code class="computeroutput">BZ2_bzReadClose</code>.</p>
+<p>Possible assignments to
+<code class="computeroutput">bzerror</code>:</p>
+<pre class="programlisting">BZ_PARAM_ERROR
+ if b is NULL
+ or unused is NULL or nUnused is NULL
+BZ_SEQUENCE_ERROR
+ if BZ_STREAM_END has not been signalled
+ or if b was opened with BZ2_bzWriteOpen
+BZ_OK
+ otherwise</pre>
+<p>Allowable next actions:</p>
+<pre class="programlisting">BZ2_bzReadClose</pre>
+</div>
+<div class="sect2" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="bzreadclose"></a>3.4.4. <code class="computeroutput">BZ2_bzReadClose</code></h3></div></div></div>
+<pre class="programlisting">void BZ2_bzReadClose ( int *bzerror, BZFILE *b );</pre>
+<p>Releases all memory pertaining to the compressed file
+<code class="computeroutput">b</code>.
+<code class="computeroutput">BZ2_bzReadClose</code> does not call
+<code class="computeroutput">fclose</code> on the underlying file
+handle, so you should do that yourself if appropriate.
+<code class="computeroutput">BZ2_bzReadClose</code> should be called
+to clean up after all error situations.</p>
+<p>Possible assignments to
+<code class="computeroutput">bzerror</code>:</p>
+<pre class="programlisting">BZ_SEQUENCE_ERROR
+ if b was opened with BZ2_bzOpenWrite
+BZ_OK
+ otherwise</pre>
+<p>Allowable next actions:</p>
+<pre class="programlisting">none</pre>
+</div>
+<div class="sect2" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="bzwriteopen"></a>3.4.5. <code class="computeroutput">BZ2_bzWriteOpen</code></h3></div></div></div>
+<pre class="programlisting">BZFILE *BZ2_bzWriteOpen( int *bzerror, FILE *f,
+ int blockSize100k, int verbosity,
+ int workFactor );</pre>
+<p>Prepare to write compressed data to file handle
+<code class="computeroutput">f</code>.
+<code class="computeroutput">f</code> should refer to a file which
+has been opened for writing, and for which the error indicator
+(<code class="computeroutput">ferror(f)</code>)is not set.</p>
+<p>For the meaning of parameters
+<code class="computeroutput">blockSize100k</code>,
+<code class="computeroutput">verbosity</code> and
+<code class="computeroutput">workFactor</code>, see
+<code class="computeroutput">BZ2_bzCompressInit</code>.</p>
+<p>All required memory is allocated at this stage, so if the
+call completes successfully,
+<code class="computeroutput">BZ_MEM_ERROR</code> cannot be signalled
+by a subsequent call to
+<code class="computeroutput">BZ2_bzWrite</code>.</p>
+<p>Possible assignments to
+<code class="computeroutput">bzerror</code>:</p>
+<pre class="programlisting">BZ_CONFIG_ERROR
+ if the library has been mis-compiled
+BZ_PARAM_ERROR
+ if f is NULL
+ or blockSize100k &lt; 1 or blockSize100k &gt; 9
+BZ_IO_ERROR
+ if ferror(f) is nonzero
+BZ_MEM_ERROR
+ if insufficient memory is available
+BZ_OK
+ otherwise</pre>
+<p>Possible return values:</p>
+<pre class="programlisting">Pointer to an abstract BZFILE
+ if bzerror is BZ_OK
+NULL
+ otherwise</pre>
+<p>Allowable next actions:</p>
+<pre class="programlisting">BZ2_bzWrite
+ if bzerror is BZ_OK
+ (you could go directly to BZ2_bzWriteClose, but this would be pretty pointless)
+BZ2_bzWriteClose
+ otherwise</pre>
+</div>
+<div class="sect2" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="bzwrite"></a>3.4.6. <code class="computeroutput">BZ2_bzWrite</code></h3></div></div></div>
+<pre class="programlisting">void BZ2_bzWrite ( int *bzerror, BZFILE *b, void *buf, int len );</pre>
+<p>Absorbs <code class="computeroutput">len</code> bytes from the
+buffer <code class="computeroutput">buf</code>, eventually to be
+compressed and written to the file.</p>
+<p>Possible assignments to
+<code class="computeroutput">bzerror</code>:</p>
+<pre class="programlisting">BZ_PARAM_ERROR
+ if b is NULL or buf is NULL or len &lt; 0
+BZ_SEQUENCE_ERROR
+ if b was opened with BZ2_bzReadOpen
+BZ_IO_ERROR
+ if there is an error writing the compressed file.
+BZ_OK
+ otherwise</pre>
+</div>
+<div class="sect2" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="bzwriteclose"></a>3.4.7. <code class="computeroutput">BZ2_bzWriteClose</code></h3></div></div></div>
+<pre class="programlisting">void BZ2_bzWriteClose( int *bzerror, BZFILE* f,
+ int abandon,
+ unsigned int* nbytes_in,
+ unsigned int* nbytes_out );
+
+void BZ2_bzWriteClose64( int *bzerror, BZFILE* f,
+ int abandon,
+ unsigned int* nbytes_in_lo32,
+ unsigned int* nbytes_in_hi32,
+ unsigned int* nbytes_out_lo32,
+ unsigned int* nbytes_out_hi32 );</pre>
+<p>Compresses and flushes to the compressed file all data so
+far supplied by <code class="computeroutput">BZ2_bzWrite</code>.
+The logical end-of-stream markers are also written, so subsequent
+calls to <code class="computeroutput">BZ2_bzWrite</code> are
+illegal. All memory associated with the compressed file
+<code class="computeroutput">b</code> is released.
+<code class="computeroutput">fflush</code> is called on the
+compressed file, but it is not
+<code class="computeroutput">fclose</code>'d.</p>
+<p>If <code class="computeroutput">BZ2_bzWriteClose</code> is
+called to clean up after an error, the only action is to release
+the memory. The library records the error codes issued by
+previous calls, so this situation will be detected automatically.
+There is no attempt to complete the compression operation, nor to
+<code class="computeroutput">fflush</code> the compressed file. You
+can force this behaviour to happen even in the case of no error,
+by passing a nonzero value to
+<code class="computeroutput">abandon</code>.</p>
+<p>If <code class="computeroutput">nbytes_in</code> is non-null,
+<code class="computeroutput">*nbytes_in</code> will be set to be the
+total volume of uncompressed data handled. Similarly,
+<code class="computeroutput">nbytes_out</code> will be set to the
+total volume of compressed data written. For compatibility with
+older versions of the library,
+<code class="computeroutput">BZ2_bzWriteClose</code> only yields the
+lower 32 bits of these counts. Use
+<code class="computeroutput">BZ2_bzWriteClose64</code> if you want
+the full 64 bit counts. These two functions are otherwise
+absolutely identical.</p>
+<p>Possible assignments to
+<code class="computeroutput">bzerror</code>:</p>
+<pre class="programlisting">BZ_SEQUENCE_ERROR
+ if b was opened with BZ2_bzReadOpen
+BZ_IO_ERROR
+ if there is an error writing the compressed file
+BZ_OK
+ otherwise</pre>
+</div>
+<div class="sect2" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="embed"></a>3.4.8. Handling embedded compressed data streams</h3></div></div></div>
+<p>The high-level library facilitates use of
+<code class="computeroutput">bzip2</code> data streams which form
+some part of a surrounding, larger data stream.</p>
+<div class="itemizedlist"><ul type="bullet">
+<li style="list-style-type: disc"><p>For writing, the library takes an open file handle,
+ writes compressed data to it,
+ <code class="computeroutput">fflush</code>es it but does not
+ <code class="computeroutput">fclose</code> it. The calling
+ application can write its own data before and after the
+ compressed data stream, using that same file handle.</p></li>
+<li style="list-style-type: disc"><p>Reading is more complex, and the facilities are not as
+ general as they could be since generality is hard to reconcile
+ with efficiency. <code class="computeroutput">BZ2_bzRead</code>
+ reads from the compressed file in blocks of size
+ <code class="computeroutput">BZ_MAX_UNUSED</code> bytes, and in
+ doing so probably will overshoot the logical end of compressed
+ stream. To recover this data once decompression has ended,
+ call <code class="computeroutput">BZ2_bzReadGetUnused</code> after
+ the last call of <code class="computeroutput">BZ2_bzRead</code>
+ (the one returning
+ <code class="computeroutput">BZ_STREAM_END</code>) but before
+ calling
+ <code class="computeroutput">BZ2_bzReadClose</code>.</p></li>
+</ul></div>
+<p>This mechanism makes it easy to decompress multiple
+<code class="computeroutput">bzip2</code> streams placed end-to-end.
+As the end of one stream, when
+<code class="computeroutput">BZ2_bzRead</code> returns
+<code class="computeroutput">BZ_STREAM_END</code>, call
+<code class="computeroutput">BZ2_bzReadGetUnused</code> to collect
+the unused data (copy it into your own buffer somewhere). That
+data forms the start of the next compressed stream. To start
+uncompressing that next stream, call
+<code class="computeroutput">BZ2_bzReadOpen</code> again, feeding in
+the unused data via the <code class="computeroutput">unused</code> /
+<code class="computeroutput">nUnused</code> parameters. Keep doing
+this until <code class="computeroutput">BZ_STREAM_END</code> return
+coincides with the physical end of file
+(<code class="computeroutput">feof(f)</code>). In this situation
+<code class="computeroutput">BZ2_bzReadGetUnused</code> will of
+course return no data.</p>
+<p>This should give some feel for how the high-level interface
+can be used. If you require extra flexibility, you'll have to
+bite the bullet and get to grips with the low-level
+interface.</p>
+</div>
+<div class="sect2" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="std-rdwr"></a>3.4.9. Standard file-reading/writing code</h3></div></div></div>
+<p>Here's how you'd write data to a compressed file:</p>
+<pre class="programlisting">FILE* f;
+BZFILE* b;
+int nBuf;
+char buf[ /* whatever size you like */ ];
+int bzerror;
+int nWritten;
+
+f = fopen ( "myfile.bz2", "w" );
+if ( !f ) {
+ /* handle error */
+}
+b = BZ2_bzWriteOpen( &amp;bzerror, f, 9 );
+if (bzerror != BZ_OK) {
+ BZ2_bzWriteClose ( b );
+ /* handle error */
+}
+
+while ( /* condition */ ) {
+ /* get data to write into buf, and set nBuf appropriately */
+ nWritten = BZ2_bzWrite ( &amp;bzerror, b, buf, nBuf );
+ if (bzerror == BZ_IO_ERROR) {
+ BZ2_bzWriteClose ( &amp;bzerror, b );
+ /* handle error */
+ }
+}
+
+BZ2_bzWriteClose( &amp;bzerror, b );
+if (bzerror == BZ_IO_ERROR) {
+ /* handle error */
+}</pre>
+<p>And to read from a compressed file:</p>
+<pre class="programlisting">FILE* f;
+BZFILE* b;
+int nBuf;
+char buf[ /* whatever size you like */ ];
+int bzerror;
+int nWritten;
+
+f = fopen ( "myfile.bz2", "r" );
+if ( !f ) {
+ /* handle error */
+}
+b = BZ2_bzReadOpen ( &amp;bzerror, f, 0, NULL, 0 );
+if ( bzerror != BZ_OK ) {
+ BZ2_bzReadClose ( &amp;bzerror, b );
+ /* handle error */
+}
+
+bzerror = BZ_OK;
+while ( bzerror == BZ_OK &amp;&amp; /* arbitrary other conditions */) {
+ nBuf = BZ2_bzRead ( &amp;bzerror, b, buf, /* size of buf */ );
+ if ( bzerror == BZ_OK ) {
+ /* do something with buf[0 .. nBuf-1] */
+ }
+}
+if ( bzerror != BZ_STREAM_END ) {
+ BZ2_bzReadClose ( &amp;bzerror, b );
+ /* handle error */
+} else {
+ BZ2_bzReadClose ( &amp;bzerror, b );
+}</pre>
+</div>
+</div>
+<div class="sect1" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="util-fns"></a>3.5. Utility functions</h2></div></div></div>
+<div class="sect2" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="bzbufftobuffcompress"></a>3.5.1. <code class="computeroutput">BZ2_bzBuffToBuffCompress</code></h3></div></div></div>
+<pre class="programlisting">int BZ2_bzBuffToBuffCompress( char* dest,
+ unsigned int* destLen,
+ char* source,
+ unsigned int sourceLen,
+ int blockSize100k,
+ int verbosity,
+ int workFactor );</pre>
+<p>Attempts to compress the data in <code class="computeroutput">source[0
+.. sourceLen-1]</code> into the destination buffer,
+<code class="computeroutput">dest[0 .. *destLen-1]</code>. If the
+destination buffer is big enough,
+<code class="computeroutput">*destLen</code> is set to the size of
+the compressed data, and <code class="computeroutput">BZ_OK</code>
+is returned. If the compressed data won't fit,
+<code class="computeroutput">*destLen</code> is unchanged, and
+<code class="computeroutput">BZ_OUTBUFF_FULL</code> is
+returned.</p>
+<p>Compression in this manner is a one-shot event, done with a
+single call to this function. The resulting compressed data is a
+complete <code class="computeroutput">bzip2</code> format data
+stream. There is no mechanism for making additional calls to
+provide extra input data. If you want that kind of mechanism,
+use the low-level interface.</p>
+<p>For the meaning of parameters
+<code class="computeroutput">blockSize100k</code>,
+<code class="computeroutput">verbosity</code> and
+<code class="computeroutput">workFactor</code>, see
+<code class="computeroutput">BZ2_bzCompressInit</code>.</p>
+<p>To guarantee that the compressed data will fit in its
+buffer, allocate an output buffer of size 1% larger than the
+uncompressed data, plus six hundred extra bytes.</p>
+<p><code class="computeroutput">BZ2_bzBuffToBuffDecompress</code>
+will not write data at or beyond
+<code class="computeroutput">dest[*destLen]</code>, even in case of
+buffer overflow.</p>
+<p>Possible return values:</p>
+<pre class="programlisting">BZ_CONFIG_ERROR
+ if the library has been mis-compiled
+BZ_PARAM_ERROR
+ if dest is NULL or destLen is NULL
+ or blockSize100k &lt; 1 or blockSize100k &gt; 9
+ or verbosity &lt; 0 or verbosity &gt; 4
+ or workFactor &lt; 0 or workFactor &gt; 250
+BZ_MEM_ERROR
+ if insufficient memory is available
+BZ_OUTBUFF_FULL
+ if the size of the compressed data exceeds *destLen
+BZ_OK
+ otherwise</pre>
+</div>
+<div class="sect2" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="bzbufftobuffdecompress"></a>3.5.2. <code class="computeroutput">BZ2_bzBuffToBuffDecompress</code></h3></div></div></div>
+<pre class="programlisting">int BZ2_bzBuffToBuffDecompress( char* dest,
+ unsigned int* destLen,
+ char* source,
+ unsigned int sourceLen,
+ int small,
+ int verbosity );</pre>
+<p>Attempts to decompress the data in <code class="computeroutput">source[0
+.. sourceLen-1]</code> into the destination buffer,
+<code class="computeroutput">dest[0 .. *destLen-1]</code>. If the
+destination buffer is big enough,
+<code class="computeroutput">*destLen</code> is set to the size of
+the uncompressed data, and <code class="computeroutput">BZ_OK</code>
+is returned. If the compressed data won't fit,
+<code class="computeroutput">*destLen</code> is unchanged, and
+<code class="computeroutput">BZ_OUTBUFF_FULL</code> is
+returned.</p>
+<p><code class="computeroutput">source</code> is assumed to hold
+a complete <code class="computeroutput">bzip2</code> format data
+stream.
+<code class="computeroutput">BZ2_bzBuffToBuffDecompress</code> tries
+to decompress the entirety of the stream into the output
+buffer.</p>
+<p>For the meaning of parameters
+<code class="computeroutput">small</code> and
+<code class="computeroutput">verbosity</code>, see
+<code class="computeroutput">BZ2_bzDecompressInit</code>.</p>
+<p>Because the compression ratio of the compressed data cannot
+be known in advance, there is no easy way to guarantee that the
+output buffer will be big enough. You may of course make
+arrangements in your code to record the size of the uncompressed
+data, but such a mechanism is beyond the scope of this
+library.</p>
+<p><code class="computeroutput">BZ2_bzBuffToBuffDecompress</code>
+will not write data at or beyond
+<code class="computeroutput">dest[*destLen]</code>, even in case of
+buffer overflow.</p>
+<p>Possible return values:</p>
+<pre class="programlisting">BZ_CONFIG_ERROR
+ if the library has been mis-compiled
+BZ_PARAM_ERROR
+ if dest is NULL or destLen is NULL
+ or small != 0 &amp;&amp; small != 1
+ or verbosity &lt; 0 or verbosity &gt; 4
+BZ_MEM_ERROR
+ if insufficient memory is available
+BZ_OUTBUFF_FULL
+ if the size of the compressed data exceeds *destLen
+BZ_DATA_ERROR
+ if a data integrity error was detected in the compressed data
+BZ_DATA_ERROR_MAGIC
+ if the compressed data doesn't begin with the right magic bytes
+BZ_UNEXPECTED_EOF
+ if the compressed data ends unexpectedly
+BZ_OK
+ otherwise</pre>
+</div>
+</div>
+<div class="sect1" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="zlib-compat"></a>3.6. <code class="computeroutput">zlib</code> compatibility functions</h2></div></div></div>
+<p>Yoshioka Tsuneo has contributed some functions to give
+better <code class="computeroutput">zlib</code> compatibility.
+These functions are <code class="computeroutput">BZ2_bzopen</code>,
+<code class="computeroutput">BZ2_bzread</code>,
+<code class="computeroutput">BZ2_bzwrite</code>,
+<code class="computeroutput">BZ2_bzflush</code>,
+<code class="computeroutput">BZ2_bzclose</code>,
+<code class="computeroutput">BZ2_bzerror</code> and
+<code class="computeroutput">BZ2_bzlibVersion</code>. These
+functions are not (yet) officially part of the library. If they
+break, you get to keep all the pieces. Nevertheless, I think
+they work ok.</p>
+<pre class="programlisting">typedef void BZFILE;
+
+const char * BZ2_bzlibVersion ( void );</pre>
+<p>Returns a string indicating the library version.</p>
+<pre class="programlisting">BZFILE * BZ2_bzopen ( const char *path, const char *mode );
+BZFILE * BZ2_bzdopen ( int fd, const char *mode );</pre>
+<p>Opens a <code class="computeroutput">.bz2</code> file for
+reading or writing, using either its name or a pre-existing file
+descriptor. Analogous to <code class="computeroutput">fopen</code>
+and <code class="computeroutput">fdopen</code>.</p>
+<pre class="programlisting">int BZ2_bzread ( BZFILE* b, void* buf, int len );
+int BZ2_bzwrite ( BZFILE* b, void* buf, int len );</pre>
+<p>Reads/writes data from/to a previously opened
+<code class="computeroutput">BZFILE</code>. Analogous to
+<code class="computeroutput">fread</code> and
+<code class="computeroutput">fwrite</code>.</p>
+<pre class="programlisting">int BZ2_bzflush ( BZFILE* b );
+void BZ2_bzclose ( BZFILE* b );</pre>
+<p>Flushes/closes a <code class="computeroutput">BZFILE</code>.
+<code class="computeroutput">BZ2_bzflush</code> doesn't actually do
+anything. Analogous to <code class="computeroutput">fflush</code>
+and <code class="computeroutput">fclose</code>.</p>
+<pre class="programlisting">const char * BZ2_bzerror ( BZFILE *b, int *errnum )</pre>
+<p>Returns a string describing the more recent error status of
+<code class="computeroutput">b</code>, and also sets
+<code class="computeroutput">*errnum</code> to its numerical
+value.</p>
+</div>
+<div class="sect1" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="stdio-free"></a>3.7. Using the library in a <code class="computeroutput">stdio</code>-free environment</h2></div></div></div>
+<div class="sect2" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="stdio-bye"></a>3.7.1. Getting rid of <code class="computeroutput">stdio</code></h3></div></div></div>
+<p>In a deeply embedded application, you might want to use
+just the memory-to-memory functions. You can do this
+conveniently by compiling the library with preprocessor symbol
+<code class="computeroutput">BZ_NO_STDIO</code> defined. Doing this
+gives you a library containing only the following eight
+functions:</p>
+<p><code class="computeroutput">BZ2_bzCompressInit</code>,
+<code class="computeroutput">BZ2_bzCompress</code>,
+<code class="computeroutput">BZ2_bzCompressEnd</code>
+<code class="computeroutput">BZ2_bzDecompressInit</code>,
+<code class="computeroutput">BZ2_bzDecompress</code>,
+<code class="computeroutput">BZ2_bzDecompressEnd</code>
+<code class="computeroutput">BZ2_bzBuffToBuffCompress</code>,
+<code class="computeroutput">BZ2_bzBuffToBuffDecompress</code></p>
+<p>When compiled like this, all functions will ignore
+<code class="computeroutput">verbosity</code> settings.</p>
+</div>
+<div class="sect2" lang="en">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="critical-error"></a>3.7.2. Critical error handling</h3></div></div></div>
+<p><code class="computeroutput">libbzip2</code> contains a number
+of internal assertion checks which should, needless to say, never
+be activated. Nevertheless, if an assertion should fail,
+behaviour depends on whether or not the library was compiled with
+<code class="computeroutput">BZ_NO_STDIO</code> set.</p>
+<p>For a normal compile, an assertion failure yields the
+message:</p>
+<div class="blockquote"><blockquote class="blockquote">
+<p>bzip2/libbzip2: internal error number N.</p>
+<p>This is a bug in bzip2/libbzip2, 1.0.5 of 10 December 2007.
+Please report it to me at: jseward@bzip.org. If this happened
+when you were using some program which uses libbzip2 as a
+component, you should also report this bug to the author(s)
+of that program. Please make an effort to report this bug;
+timely and accurate bug reports eventually lead to higher
+quality software. Thanks. Julian Seward, 10 December 2007.
+</p>
+</blockquote></div>
+<p>where <code class="computeroutput">N</code> is some error code
+number. If <code class="computeroutput">N == 1007</code>, it also
+prints some extra text advising the reader that unreliable memory
+is often associated with internal error 1007. (This is a
+frequently-observed-phenomenon with versions 1.0.0/1.0.1).</p>
+<p><code class="computeroutput">exit(3)</code> is then
+called.</p>
+<p>For a <code class="computeroutput">stdio</code>-free library,
+assertion failures result in a call to a function declared
+as:</p>
+<pre class="programlisting">extern void bz_internal_error ( int errcode );</pre>
+<p>The relevant code is passed as a parameter. You should
+supply such a function.</p>
+<p>In either case, once an assertion failure has occurred, any
+<code class="computeroutput">bz_stream</code> records involved can
+be regarded as invalid. You should not attempt to resume normal
+operation with them.</p>
+<p>You may, of course, change critical error handling to suit
+your needs. As I said above, critical errors indicate bugs in
+the library and should not occur. All "normal" error situations
+are indicated via error return codes from functions, and can be
+recovered from.</p>
+</div>
+</div>
+<div class="sect1" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="win-dll"></a>3.8. Making a Windows DLL</h2></div></div></div>
+<p>Everything related to Windows has been contributed by
+Yoshioka Tsuneo
+(<code class="computeroutput">tsuneo@rr.iij4u.or.jp</code>), so
+you should send your queries to him (but perhaps Cc: me,
+<code class="computeroutput">jseward@bzip.org</code>).</p>
+<p>My vague understanding of what to do is: using Visual C++
+5.0, open the project file
+<code class="computeroutput">libbz2.dsp</code>, and build. That's
+all.</p>
+<p>If you can't open the project file for some reason, make a
+new one, naming these files:
+<code class="computeroutput">blocksort.c</code>,
+<code class="computeroutput">bzlib.c</code>,
+<code class="computeroutput">compress.c</code>,
+<code class="computeroutput">crctable.c</code>,
+<code class="computeroutput">decompress.c</code>,
+<code class="computeroutput">huffman.c</code>,
+<code class="computeroutput">randtable.c</code> and
+<code class="computeroutput">libbz2.def</code>. You will also need
+to name the header files <code class="computeroutput">bzlib.h</code>
+and <code class="computeroutput">bzlib_private.h</code>.</p>
+<p>If you don't use VC++, you may need to define the
+proprocessor symbol
+<code class="computeroutput">_WIN32</code>.</p>
+<p>Finally, <code class="computeroutput">dlltest.c</code> is a
+sample program using the DLL. It has a project file,
+<code class="computeroutput">dlltest.dsp</code>.</p>
+<p>If you just want a makefile for Visual C, have a look at
+<code class="computeroutput">makefile.msc</code>.</p>
+<p>Be aware that if you compile
+<code class="computeroutput">bzip2</code> itself on Win32, you must
+set <code class="computeroutput">BZ_UNIX</code> to 0 and
+<code class="computeroutput">BZ_LCCWIN32</code> to 1, in the file
+<code class="computeroutput">bzip2.c</code>, before compiling.
+Otherwise the resulting binary won't work correctly.</p>
+<p>I haven't tried any of this stuff myself, but it all looks
+plausible.</p>
+</div>
+</div>
+<div class="chapter" lang="en">
+<div class="titlepage"><div><div><h2 class="title">
+<a name="misc"></a>4. Miscellanea</h2></div></div></div>
+<div class="toc">
+<p><b>Table of Contents</b></p>
+<dl>
+<dt><span class="sect1"><a href="#limits">4.1. Limitations of the compressed file format</a></span></dt>
+<dt><span class="sect1"><a href="#port-issues">4.2. Portability issues</a></span></dt>
+<dt><span class="sect1"><a href="#bugs">4.3. Reporting bugs</a></span></dt>
+<dt><span class="sect1"><a href="#package">4.4. Did you get the right package?</a></span></dt>
+<dt><span class="sect1"><a href="#reading">4.5. Further Reading</a></span></dt>
+</dl>
+</div>
+<p>These are just some random thoughts of mine. Your mileage
+may vary.</p>
+<div class="sect1" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="limits"></a>4.1. Limitations of the compressed file format</h2></div></div></div>
+<p><code class="computeroutput">bzip2-1.0.X</code>,
+<code class="computeroutput">0.9.5</code> and
+<code class="computeroutput">0.9.0</code> use exactly the same file
+format as the original version,
+<code class="computeroutput">bzip2-0.1</code>. This decision was
+made in the interests of stability. Creating yet another
+incompatible compressed file format would create further
+confusion and disruption for users.</p>
+<p>Nevertheless, this is not a painless decision. Development
+work since the release of
+<code class="computeroutput">bzip2-0.1</code> in August 1997 has
+shown complexities in the file format which slow down
+decompression and, in retrospect, are unnecessary. These
+are:</p>
+<div class="itemizedlist"><ul type="bullet">
+<li style="list-style-type: disc"><p>The run-length encoder, which is the first of the
+ compression transformations, is entirely irrelevant. The
+ original purpose was to protect the sorting algorithm from the
+ very worst case input: a string of repeated symbols. But
+ algorithm steps Q6a and Q6b in the original Burrows-Wheeler
+ technical report (SRC-124) show how repeats can be handled
+ without difficulty in block sorting.</p></li>
+<li style="list-style-type: disc">
+<p>The randomisation mechanism doesn't really need to be
+ there. Udi Manber and Gene Myers published a suffix array
+ construction algorithm a few years back, which can be employed
+ to sort any block, no matter how repetitive, in O(N log N)
+ time. Subsequent work by Kunihiko Sadakane has produced a
+ derivative O(N (log N)^2) algorithm which usually outperforms
+ the Manber-Myers algorithm.</p>
+<p>I could have changed to Sadakane's algorithm, but I find
+ it to be slower than <code class="computeroutput">bzip2</code>'s
+ existing algorithm for most inputs, and the randomisation
+ mechanism protects adequately against bad cases. I didn't
+ think it was a good tradeoff to make. Partly this is due to
+ the fact that I was not flooded with email complaints about
+ <code class="computeroutput">bzip2-0.1</code>'s performance on
+ repetitive data, so perhaps it isn't a problem for real
+ inputs.</p>
+<p>Probably the best long-term solution, and the one I have
+ incorporated into 0.9.5 and above, is to use the existing
+ sorting algorithm initially, and fall back to a O(N (log N)^2)
+ algorithm if the standard algorithm gets into
+ difficulties.</p>
+</li>
+<li style="list-style-type: disc"><p>The compressed file format was never designed to be
+ handled by a library, and I have had to jump though some hoops
+ to produce an efficient implementation of decompression. It's
+ a bit hairy. Try passing
+ <code class="computeroutput">decompress.c</code> through the C
+ preprocessor and you'll see what I mean. Much of this
+ complexity could have been avoided if the compressed size of
+ each block of data was recorded in the data stream.</p></li>
+<li style="list-style-type: disc"><p>An Adler-32 checksum, rather than a CRC32 checksum,
+ would be faster to compute.</p></li>
+</ul></div>
+<p>It would be fair to say that the
+<code class="computeroutput">bzip2</code> format was frozen before I
+properly and fully understood the performance consequences of
+doing so.</p>
+<p>Improvements which I was able to incorporate into 0.9.0,
+despite using the same file format, are:</p>
+<div class="itemizedlist"><ul type="bullet">
+<li style="list-style-type: disc"><p>Single array implementation of the inverse BWT. This
+ significantly speeds up decompression, presumably because it
+ reduces the number of cache misses.</p></li>
+<li style="list-style-type: disc"><p>Faster inverse MTF transform for large MTF values.
+ The new implementation is based on the notion of sliding blocks
+ of values.</p></li>
+<li style="list-style-type: disc"><p><code class="computeroutput">bzip2-0.9.0</code> now reads
+ and writes files with <code class="computeroutput">fread</code>
+ and <code class="computeroutput">fwrite</code>; version 0.1 used
+ <code class="computeroutput">putc</code> and
+ <code class="computeroutput">getc</code>. Duh! Well, you live
+ and learn.</p></li>
+</ul></div>
+<p>Further ahead, it would be nice to be able to do random
+access into files. This will require some careful design of
+compressed file formats.</p>
+</div>
+<div class="sect1" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="port-issues"></a>4.2. Portability issues</h2></div></div></div>
+<p>After some consideration, I have decided not to use GNU
+<code class="computeroutput">autoconf</code> to configure 0.9.5 or
+1.0.</p>
+<p><code class="computeroutput">autoconf</code>, admirable and
+wonderful though it is, mainly assists with portability problems
+between Unix-like platforms. But
+<code class="computeroutput">bzip2</code> doesn't have much in the
+way of portability problems on Unix; most of the difficulties
+appear when porting to the Mac, or to Microsoft's operating
+systems. <code class="computeroutput">autoconf</code> doesn't help
+in those cases, and brings in a whole load of new
+complexity.</p>
+<p>Most people should be able to compile the library and
+program under Unix straight out-of-the-box, so to speak,
+especially if you have a version of GNU C available.</p>
+<p>There are a couple of
+<code class="computeroutput">__inline__</code> directives in the
+code. GNU C (<code class="computeroutput">gcc</code>) should be
+able to handle them. If you're not using GNU C, your C compiler
+shouldn't see them at all. If your compiler does, for some
+reason, see them and doesn't like them, just
+<code class="computeroutput">#define</code>
+<code class="computeroutput">__inline__</code> to be
+<code class="computeroutput">/* */</code>. One easy way to do this
+is to compile with the flag
+<code class="computeroutput">-D__inline__=</code>, which should be
+understood by most Unix compilers.</p>
+<p>If you still have difficulties, try compiling with the
+macro <code class="computeroutput">BZ_STRICT_ANSI</code> defined.
+This should enable you to build the library in a strictly ANSI
+compliant environment. Building the program itself like this is
+dangerous and not supported, since you remove
+<code class="computeroutput">bzip2</code>'s checks against
+compressing directories, symbolic links, devices, and other
+not-really-a-file entities. This could cause filesystem
+corruption!</p>
+<p>One other thing: if you create a
+<code class="computeroutput">bzip2</code> binary for public distribution,
+please consider linking it statically (<code class="computeroutput">gcc
+-static</code>). This avoids all sorts of library-version
+issues that others may encounter later on.</p>
+<p>If you build <code class="computeroutput">bzip2</code> on
+Win32, you must set <code class="computeroutput">BZ_UNIX</code> to 0
+and <code class="computeroutput">BZ_LCCWIN32</code> to 1, in the
+file <code class="computeroutput">bzip2.c</code>, before compiling.
+Otherwise the resulting binary won't work correctly.</p>
+</div>
+<div class="sect1" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="bugs"></a>4.3. Reporting bugs</h2></div></div></div>
+<p>I tried pretty hard to make sure
+<code class="computeroutput">bzip2</code> is bug free, both by
+design and by testing. Hopefully you'll never need to read this
+section for real.</p>
+<p>Nevertheless, if <code class="computeroutput">bzip2</code> dies
+with a segmentation fault, a bus error or an internal assertion
+failure, it will ask you to email me a bug report. Experience from
+years of feedback of bzip2 users indicates that almost all these
+problems can be traced to either compiler bugs or hardware
+problems.</p>
+<div class="itemizedlist"><ul type="bullet">
+<li style="list-style-type: disc">
+<p>Recompile the program with no optimisation, and
+ see if it works. And/or try a different compiler. I heard all
+ sorts of stories about various flavours of GNU C (and other
+ compilers) generating bad code for
+ <code class="computeroutput">bzip2</code>, and I've run across two
+ such examples myself.</p>
+<p>2.7.X versions of GNU C are known to generate bad code
+ from time to time, at high optimisation levels. If you get
+ problems, try using the flags
+ <code class="computeroutput">-O2</code>
+ <code class="computeroutput">-fomit-frame-pointer</code>
+ <code class="computeroutput">-fno-strength-reduce</code>. You
+ should specifically <span class="emphasis"><em>not</em></span> use
+ <code class="computeroutput">-funroll-loops</code>.</p>
+<p>You may notice that the Makefile runs six tests as part
+ of the build process. If the program passes all of these, it's
+ a pretty good (but not 100%) indication that the compiler has
+ done its job correctly.</p>
+</li>
+<li style="list-style-type: disc">
+<p>If <code class="computeroutput">bzip2</code>
+ crashes randomly, and the crashes are not repeatable, you may
+ have a flaky memory subsystem.
+ <code class="computeroutput">bzip2</code> really hammers your
+ memory hierarchy, and if it's a bit marginal, you may get these
+ problems. Ditto if your disk or I/O subsystem is slowly
+ failing. Yup, this really does happen.</p>
+<p>Try using a different machine of the same type, and see
+ if you can repeat the problem.</p>
+</li>
+<li style="list-style-type: disc"><p>This isn't really a bug, but ... If
+ <code class="computeroutput">bzip2</code> tells you your file is
+ corrupted on decompression, and you obtained the file via FTP,
+ there is a possibility that you forgot to tell FTP to do a
+ binary mode transfer. That absolutely will cause the file to
+ be non-decompressible. You'll have to transfer it
+ again.</p></li>
+</ul></div>
+<p>If you've incorporated
+<code class="computeroutput">libbzip2</code> into your own program
+and are getting problems, please, please, please, check that the
+parameters you are passing in calls to the library, are correct,
+and in accordance with what the documentation says is allowable.
+I have tried to make the library robust against such problems,
+but I'm sure I haven't succeeded.</p>
+<p>Finally, if the above comments don't help, you'll have to
+send me a bug report. Now, it's just amazing how many people
+will send me a bug report saying something like:</p>
+<pre class="programlisting">bzip2 crashed with segmentation fault on my machine</pre>
+<p>and absolutely nothing else. Needless to say, a such a
+report is <span class="emphasis"><em>totally, utterly, completely and
+comprehensively 100% useless; a waste of your time, my time, and
+net bandwidth</em></span>. With no details at all, there's no way
+I can possibly begin to figure out what the problem is.</p>
+<p>The rules of the game are: facts, facts, facts. Don't omit
+them because "oh, they won't be relevant". At the bare
+minimum:</p>
+<pre class="programlisting">Machine type. Operating system version.
+Exact version of bzip2 (do bzip2 -V).
+Exact version of the compiler used.
+Flags passed to the compiler.</pre>
+<p>However, the most important single thing that will help me
+is the file that you were trying to compress or decompress at the
+time the problem happened. Without that, my ability to do
+anything more than speculate about the cause, is limited.</p>
+</div>
+<div class="sect1" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="package"></a>4.4. Did you get the right package?</h2></div></div></div>
+<p><code class="computeroutput">bzip2</code> is a resource hog.
+It soaks up large amounts of CPU cycles and memory. Also, it
+gives very large latencies. In the worst case, you can feed many
+megabytes of uncompressed data into the library before getting
+any compressed output, so this probably rules out applications
+requiring interactive behaviour.</p>
+<p>These aren't faults of my implementation, I hope, but more
+an intrinsic property of the Burrows-Wheeler transform
+(unfortunately). Maybe this isn't what you want.</p>
+<p>If you want a compressor and/or library which is faster,
+uses less memory but gets pretty good compression, and has
+minimal latency, consider Jean-loup Gailly's and Mark Adler's
+work, <code class="computeroutput">zlib-1.2.1</code> and
+<code class="computeroutput">gzip-1.2.4</code>. Look for them at
+<a href="http://www.zlib.org" target="_top">http://www.zlib.org</a> and
+<a href="http://www.gzip.org" target="_top">http://www.gzip.org</a>
+respectively.</p>
+<p>For something faster and lighter still, you might try Markus F
+X J Oberhumer's <code class="computeroutput">LZO</code> real-time
+compression/decompression library, at
+<a href="http://www.oberhumer.com/opensource" target="_top">http://www.oberhumer.com/opensource</a>.</p>
+</div>
+<div class="sect1" lang="en">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="reading"></a>4.5. Further Reading</h2></div></div></div>
+<p><code class="computeroutput">bzip2</code> is not research
+work, in the sense that it doesn't present any new ideas.
+Rather, it's an engineering exercise based on existing
+ideas.</p>
+<p>Four documents describe essentially all the ideas behind
+<code class="computeroutput">bzip2</code>:</p>
+<div class="literallayout"><p>Michael Burrows and D. J. Wheeler:<br>
+  "A block-sorting lossless data compression algorithm"<br>
+   10th May 1994. <br>
+   Digital SRC Research Report 124.<br>
+   ftp://ftp.digital.com/pub/DEC/SRC/research-reports/SRC-124.ps.gz<br>
+   If you have trouble finding it, try searching at the<br>
+   New Zealand Digital Library, http://www.nzdl.org.<br>
+<br>
+Daniel S. Hirschberg and Debra A. LeLewer<br>
+  "Efficient Decoding of Prefix Codes"<br>
+   Communications of the ACM, April 1990, Vol 33, Number 4.<br>
+   You might be able to get an electronic copy of this<br>
+   from the ACM Digital Library.<br>
+<br>
+David J. Wheeler<br>
+   Program bred3.c and accompanying document bred3.ps.<br>
+   This contains the idea behind the multi-table Huffman coding scheme.<br>
+   ftp://ftp.cl.cam.ac.uk/users/djw3/<br>
+<br>
+Jon L. Bentley and Robert Sedgewick<br>
+  "Fast Algorithms for Sorting and Searching Strings"<br>
+   Available from Sedgewick's web page,<br>
+   www.cs.princeton.edu/~rs<br>
+</p></div>
+<p>The following paper gives valuable additional insights into
+the algorithm, but is not immediately the basis of any code used
+in bzip2.</p>
+<div class="literallayout"><p>Peter Fenwick:<br>
+   Block Sorting Text Compression<br>
+   Proceedings of the 19th Australasian Computer Science Conference,<br>
+     Melbourne, Australia.  Jan 31 - Feb 2, 1996.<br>
+   ftp://ftp.cs.auckland.ac.nz/pub/peter-f/ACSC96paper.ps</p></div>
+<p>Kunihiko Sadakane's sorting algorithm, mentioned above, is
+available from:</p>
+<div class="literallayout"><p>http://naomi.is.s.u-tokyo.ac.jp/~sada/papers/Sada98b.ps.gz<br>
+</p></div>
+<p>The Manber-Myers suffix array construction algorithm is
+described in a paper available from:</p>
+<div class="literallayout"><p>http://www.cs.arizona.edu/people/gene/PAPERS/suffix.ps<br>
+</p></div>
+<p>Finally, the following papers document some
+investigations I made into the performance of sorting
+and decompression algorithms:</p>
+<div class="literallayout"><p>Julian Seward<br>
+   On the Performance of BWT Sorting Algorithms<br>
+   Proceedings of the IEEE Data Compression Conference 2000<br>
+     Snowbird, Utah.  28-30 March 2000.<br>
+<br>
+Julian Seward<br>
+   Space-time Tradeoffs in the Inverse B-W Transform<br>
+   Proceedings of the IEEE Data Compression Conference 2001<br>
+     Snowbird, Utah.  27-29 March 2001.<br>
+</p></div>
+</div>
+</div>
+</div></body>
+</html>
diff --git a/Utilities/cmbzip2/manual.pdf b/Utilities/cmbzip2/manual.pdf
new file mode 100644
index 000000000..10c10de7a
--- /dev/null
+++ b/Utilities/cmbzip2/manual.pdf
Binary files differ
diff --git a/Utilities/cmbzip2/manual.ps b/Utilities/cmbzip2/manual.ps
new file mode 100644
index 000000000..b8b610c81
--- /dev/null
+++ b/Utilities/cmbzip2/manual.ps
@@ -0,0 +1,82900 @@
+%!PS-Adobe-3.0
+%%Creator: xpdf/pdftops 3.01
+%%LanguageLevel: 2
+%%DocumentSuppliedResources: (atend)
+%%DocumentMedia: plain 612 792 0 () ()
+%%BoundingBox: 0 0 612 792
+%%Pages: 38
+%%EndComments
+%%BeginDefaults
+%%PageMedia: plain
+%%EndDefaults
+%%BeginProlog
+%%BeginResource: procset xpdf 3.01 0
+/xpdf 75 dict def xpdf begin
+% PDF special state
+/pdfDictSize 15 def
+/pdfSetup {
+ 3 1 roll 2 array astore
+ /setpagedevice where {
+ pop 3 dict begin
+ /PageSize exch def
+ /ImagingBBox null def
+ /Policies 1 dict dup begin /PageSize 3 def end def
+ { /Duplex true def } if
+ currentdict end setpagedevice
+ } {
+ pop pop
+ } ifelse
+} def
+/pdfStartPage {
+ pdfDictSize dict begin
+ /pdfFillCS [] def
+ /pdfFillXform {} def
+ /pdfStrokeCS [] def
+ /pdfStrokeXform {} def
+ /pdfFill [0] def
+ /pdfStroke [0] def
+ /pdfFillOP false def
+ /pdfStrokeOP false def
+ /pdfLastFill false def
+ /pdfLastStroke false def
+ /pdfTextMat [1 0 0 1 0 0] def
+ /pdfFontSize 0 def
+ /pdfCharSpacing 0 def
+ /pdfTextRender 0 def
+ /pdfTextRise 0 def
+ /pdfWordSpacing 0 def
+ /pdfHorizScaling 1 def
+ /pdfTextClipPath [] def
+} def
+/pdfEndPage { end } def
+% PDF color state
+/cs { /pdfFillXform exch def dup /pdfFillCS exch def
+ setcolorspace } def
+/CS { /pdfStrokeXform exch def dup /pdfStrokeCS exch def
+ setcolorspace } def
+/sc { pdfLastFill not { pdfFillCS setcolorspace } if
+ dup /pdfFill exch def aload pop pdfFillXform setcolor
+ /pdfLastFill true def /pdfLastStroke false def } def
+/SC { pdfLastStroke not { pdfStrokeCS setcolorspace } if
+ dup /pdfStroke exch def aload pop pdfStrokeXform setcolor
+ /pdfLastStroke true def /pdfLastFill false def } def
+/op { /pdfFillOP exch def
+ pdfLastFill { pdfFillOP setoverprint } if } def
+/OP { /pdfStrokeOP exch def
+ pdfLastStroke { pdfStrokeOP setoverprint } if } def
+/fCol {
+ pdfLastFill not {
+ pdfFillCS setcolorspace
+ pdfFill aload pop pdfFillXform setcolor
+ pdfFillOP setoverprint
+ /pdfLastFill true def /pdfLastStroke false def
+ } if
+} def
+/sCol {
+ pdfLastStroke not {
+ pdfStrokeCS setcolorspace
+ pdfStroke aload pop pdfStrokeXform setcolor
+ pdfStrokeOP setoverprint
+ /pdfLastStroke true def /pdfLastFill false def
+ } if
+} def
+% build a font
+/pdfMakeFont {
+ 4 3 roll findfont
+ 4 2 roll matrix scale makefont
+ dup length dict begin
+ { 1 index /FID ne { def } { pop pop } ifelse } forall
+ /Encoding exch def
+ currentdict
+ end
+ definefont pop
+} def
+/pdfMakeFont16 {
+ exch findfont
+ dup length dict begin
+ { 1 index /FID ne { def } { pop pop } ifelse } forall
+ /WMode exch def
+ currentdict
+ end
+ definefont pop
+} def
+% graphics state operators
+/q { gsave pdfDictSize dict begin } def
+/Q {
+ end grestore
+ /pdfLastFill where {
+ pop
+ pdfLastFill {
+ pdfFillOP setoverprint
+ } {
+ pdfStrokeOP setoverprint
+ } ifelse
+ } if
+} def
+/cm { concat } def
+/d { setdash } def
+/i { setflat } def
+/j { setlinejoin } def
+/J { setlinecap } def
+/M { setmiterlimit } def
+/w { setlinewidth } def
+% path segment operators
+/m { moveto } def
+/l { lineto } def
+/c { curveto } def
+/re { 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto
+ neg 0 rlineto closepath } def
+/h { closepath } def
+% path painting operators
+/S { sCol stroke } def
+/Sf { fCol stroke } def
+/f { fCol fill } def
+/f* { fCol eofill } def
+% clipping operators
+/W { clip newpath } def
+/W* { eoclip newpath } def
+% text state operators
+/Tc { /pdfCharSpacing exch def } def
+/Tf { dup /pdfFontSize exch def
+ dup pdfHorizScaling mul exch matrix scale
+ pdfTextMat matrix concatmatrix dup 4 0 put dup 5 0 put
+ exch findfont exch makefont setfont } def
+/Tr { /pdfTextRender exch def } def
+/Ts { /pdfTextRise exch def } def
+/Tw { /pdfWordSpacing exch def } def
+/Tz { /pdfHorizScaling exch def } def
+% text positioning operators
+/Td { pdfTextMat transform moveto } def
+/Tm { /pdfTextMat exch def } def
+% text string operators
+/cshow where {
+ pop
+ /cshow2 {
+ dup {
+ pop pop
+ 1 string dup 0 3 index put 3 index exec
+ } exch cshow
+ pop pop
+ } def
+}{
+ /cshow2 {
+ currentfont /FontType get 0 eq {
+ 0 2 2 index length 1 sub {
+ 2 copy get exch 1 add 2 index exch get
+ 2 copy exch 256 mul add
+ 2 string dup 0 6 5 roll put dup 1 5 4 roll put
+ 3 index exec
+ } for
+ } {
+ dup {
+ 1 string dup 0 3 index put 3 index exec
+ } forall
+ } ifelse
+ pop pop
+ } def
+} ifelse
+/awcp {
+ exch {
+ false charpath
+ 5 index 5 index rmoveto
+ 6 index eq { 7 index 7 index rmoveto } if
+ } exch cshow2
+ 6 {pop} repeat
+} def
+/Tj {
+ fCol
+ 1 index stringwidth pdfTextMat idtransform pop
+ sub 1 index length dup 0 ne { div } { pop pop 0 } ifelse
+ pdfWordSpacing pdfHorizScaling mul 0 pdfTextMat dtransform 32
+ 4 3 roll pdfCharSpacing pdfHorizScaling mul add 0
+ pdfTextMat dtransform
+ 6 5 roll Tj1
+} def
+/Tj16 {
+ fCol
+ 2 index stringwidth pdfTextMat idtransform pop
+ sub exch div
+ pdfWordSpacing pdfHorizScaling mul 0 pdfTextMat dtransform 32
+ 4 3 roll pdfCharSpacing pdfHorizScaling mul add 0
+ pdfTextMat dtransform
+ 6 5 roll Tj1
+} def
+/Tj16V {
+ fCol
+ 2 index stringwidth pdfTextMat idtransform exch pop
+ sub exch div
+ 0 pdfWordSpacing pdfTextMat dtransform 32
+ 4 3 roll pdfCharSpacing add 0 exch
+ pdfTextMat dtransform
+ 6 5 roll Tj1
+} def
+/Tj1 {
+ 0 pdfTextRise pdfTextMat dtransform rmoveto
+ currentpoint 8 2 roll
+ pdfTextRender 1 and 0 eq {
+ 6 copy awidthshow
+ } if
+ pdfTextRender 3 and dup 1 eq exch 2 eq or {
+ 7 index 7 index moveto
+ 6 copy
+ currentfont /FontType get 3 eq { fCol } { sCol } ifelse
+ false awcp currentpoint stroke moveto
+ } if
+ pdfTextRender 4 and 0 ne {
+ 8 6 roll moveto
+ false awcp
+ /pdfTextClipPath [ pdfTextClipPath aload pop
+ {/moveto cvx}
+ {/lineto cvx}
+ {/curveto cvx}
+ {/closepath cvx}
+ pathforall ] def
+ currentpoint newpath moveto
+ } {
+ 8 {pop} repeat
+ } ifelse
+ 0 pdfTextRise neg pdfTextMat dtransform rmoveto
+} def
+/TJm { pdfFontSize 0.001 mul mul neg 0
+ pdfTextMat dtransform rmoveto } def
+/TJmV { pdfFontSize 0.001 mul mul neg 0 exch
+ pdfTextMat dtransform rmoveto } def
+/Tclip { pdfTextClipPath cvx exec clip newpath
+ /pdfTextClipPath [] def } def
+% Level 2 image operators
+/pdfImBuf 100 string def
+/pdfIm {
+ image
+ { currentfile pdfImBuf readline
+ not { pop exit } if
+ (%-EOD-) eq { exit } if } loop
+} def
+/pdfImM {
+ fCol imagemask
+ { currentfile pdfImBuf readline
+ not { pop exit } if
+ (%-EOD-) eq { exit } if } loop
+} def
+/pdfImClip {
+ gsave
+ 0 2 4 index length 1 sub {
+ dup 4 index exch 2 copy
+ get 5 index div put
+ 1 add 3 index exch 2 copy
+ get 3 index div put
+ } for
+ pop pop rectclip
+} def
+/pdfImClipEnd { grestore } def
+% shading operators
+/colordelta {
+ false 0 1 3 index length 1 sub {
+ dup 4 index exch get 3 index 3 2 roll get sub abs 0.004 gt {
+ pop true
+ } if
+ } for
+ exch pop exch pop
+} def
+/funcCol { func n array astore } def
+/funcSH {
+ dup 0 eq {
+ true
+ } {
+ dup 6 eq {
+ false
+ } {
+ 4 index 4 index funcCol dup
+ 6 index 4 index funcCol dup
+ 3 1 roll colordelta 3 1 roll
+ 5 index 5 index funcCol dup
+ 3 1 roll colordelta 3 1 roll
+ 6 index 8 index funcCol dup
+ 3 1 roll colordelta 3 1 roll
+ colordelta or or or
+ } ifelse
+ } ifelse
+ {
+ 1 add
+ 4 index 3 index add 0.5 mul exch 4 index 3 index add 0.5 mul exch
+ 6 index 6 index 4 index 4 index 4 index funcSH
+ 2 index 6 index 6 index 4 index 4 index funcSH
+ 6 index 2 index 4 index 6 index 4 index funcSH
+ 5 3 roll 3 2 roll funcSH pop pop
+ } {
+ pop 3 index 2 index add 0.5 mul 3 index 2 index add 0.5 mul
+ funcCol sc
+ dup 4 index exch mat transform m
+ 3 index 3 index mat transform l
+ 1 index 3 index mat transform l
+ mat transform l pop pop h f*
+ } ifelse
+} def
+/axialCol {
+ dup 0 lt {
+ pop t0
+ } {
+ dup 1 gt {
+ pop t1
+ } {
+ dt mul t0 add
+ } ifelse
+ } ifelse
+ func n array astore
+} def
+/axialSH {
+ dup 0 eq {
+ true
+ } {
+ dup 8 eq {
+ false
+ } {
+ 2 index axialCol 2 index axialCol colordelta
+ } ifelse
+ } ifelse
+ {
+ 1 add 3 1 roll 2 copy add 0.5 mul
+ dup 4 3 roll exch 4 index axialSH
+ exch 3 2 roll axialSH
+ } {
+ pop 2 copy add 0.5 mul axialCol sc
+ exch dup dx mul x0 add exch dy mul y0 add
+ 3 2 roll dup dx mul x0 add exch dy mul y0 add
+ dx abs dy abs ge {
+ 2 copy yMin sub dy mul dx div add yMin m
+ yMax sub dy mul dx div add yMax l
+ 2 copy yMax sub dy mul dx div add yMax l
+ yMin sub dy mul dx div add yMin l
+ h f*
+ } {
+ exch 2 copy xMin sub dx mul dy div add xMin exch m
+ xMax sub dx mul dy div add xMax exch l
+ exch 2 copy xMax sub dx mul dy div add xMax exch l
+ xMin sub dx mul dy div add xMin exch l
+ h f*
+ } ifelse
+ } ifelse
+} def
+/radialCol {
+ dup t0 lt {
+ pop t0
+ } {
+ dup t1 gt {
+ pop t1
+ } if
+ } ifelse
+ func n array astore
+} def
+/radialSH {
+ dup 0 eq {
+ true
+ } {
+ dup 8 eq {
+ false
+ } {
+ 2 index dt mul t0 add radialCol
+ 2 index dt mul t0 add radialCol colordelta
+ } ifelse
+ } ifelse
+ {
+ 1 add 3 1 roll 2 copy add 0.5 mul
+ dup 4 3 roll exch 4 index radialSH
+ exch 3 2 roll radialSH
+ } {
+ pop 2 copy add 0.5 mul dt mul t0 add axialCol sc
+ exch dup dx mul x0 add exch dup dy mul y0 add exch dr mul r0 add
+ 0 360 arc h
+ dup dx mul x0 add exch dup dy mul y0 add exch dr mul r0 add
+ 0 360 arc h f*
+ } ifelse
+} def
+end
+%%EndResource
+%%EndProlog
+%%BeginSetup
+xpdf begin
+%%BeginResource: font DTUUHP+NimbusSanL-Bold
+%!PS-AdobeFont-1.0: NimbusSanL-Bold 1.05
+%%CreationDate: Wed Dec 22 1999
+% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development
+% (URW)++,Copyright 1999 by (URW)++ Design & Development
+% See the file COPYING (GNU General Public License) for license conditions.
+% As a special exception, permission is granted to include this font
+% program in a Postscript or PDF file that consists of a document that
+% contains text to be displayed or printed using this font, regardless
+% of the conditions or license applying to the document itself.
+12 dict begin
+/FontInfo 10 dict dup begin
+/version (1.05) readonly def
+/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file COPYING (GNU General Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def
+/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def
+/FullName (Nimbus Sans L Bold) readonly def
+/FamilyName (Nimbus Sans L) readonly def
+/Weight (Bold) readonly def
+/ItalicAngle 0.0 def
+/isFixedPitch false def
+/UnderlinePosition -155 def
+/UnderlineThickness 69 def
+end readonly def
+/FontName /DTUUHP+NimbusSanL-Bold def
+/PaintType 0 def
+/WMode 0 def
+/FontBBox {-173 -307 1003 949} readonly def
+/FontType 1 def
+/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def
+/Encoding StandardEncoding def
+currentdict end
+currentfile eexec
+d9d66f633b846a989b9974b0179fc6cc445bc2c03103c68570a7b354a4a280ae
+6fbf7f9888e039ab60fcaf852eb4ce3afeb979d5ea70fde44a2ae5c8c0166c27
+bf9665eea11c7d2329c1a211dd26bb372be5822f5ea70d99eb578c7befd44cdf
+045a363056e5e1cc51525ea6fc061dcebb337208eff729802376a2801424f670
+0e7e6397b28f15bc10b40012b0a3eaeb2693e8f7f627c4c9c7c6c5bff105c1e4
+1b2b9e8f09253b76040d268b80719e1b3f5a55ab7b8d62a63193c4ae94c086c1
+552833ddd8f116b5df33205ae709b3aa63da7bebb165b67281827b48fb5edbed
+02a1a5c0784fc57d3487daa59520bada1be3fb9795669924321ce4f466cd8e3f
+7e8ec2494aee80e2dd7a48a6861af5b9f0ccaa4a2fe2b03498eacacd6b9c39c6
+a8f2e39e06bbb061cf2ec380a32efad0b790974bb5cc3daf0992471456967362
+77de34813f27abe99302f86bb4d293a37f84667e7f3dfee4cfe9d1a676a5728c
+aeb5222ff50da97e74b2cdebf725fbca7015a188891c8a376b9dd8a642c4b184
+b1bbf3f376a6d6e31ef1c8354ddf8039cb20faabcb34d4749b3c8c8d6972ceb1
+06b8a5aae3ae40a91f1f2b1155681a9cc933f87528c99a2b0268b43a3e829e7f
+3bd863cb52950773bd9b0731dc4992541d7de7a055ca65ddd2317f1705c20d1f
+93291bcc254cbaba425c032b3b15050d41da14ffe1b3d684eea428095a01e931
+98d4f849b239ad9d79f4502f0271affb0c297f2f347bfb9c137782646f648f77
+0076b85f5a929fcdea2703333f6918b8f125627f8b505c688e30f258ded1aecf
+2c86edcd88c29249a8081731737195fab7adbb54743bd66511194dee2516959b
+a20701e2d97342248297425491f6c9471ec9a98e630d734dac19721f0b324432
+c8d7a0b751453f89f7008ba37bc48e0831ee3ecbd8a0a292d63cfc890b28f695
+9e29ac3b4ddb78a6883b9272ce34a012a82adec0b6b641e3940a438a098ccfbf
+c50544b94facfd9d7ae09ad0632015f81d2f77fc6d80a42ec11d67d8a91c376c
+13c8e3444cdfde4d2a1ed021410f4d6a4e97804ae949bd913094d23108c9d384
+56f11025e2d24939114b6bcf579a0315c52f3ca1bcc2860fc1a0b9fb8a37ae2f
+c20c0fd44d215fc2af737fd0339b070d54e664021240071c665de4170dfa182d
+4e385685fb41a2d85888b1149e9a766cb4f309b4e2baa28cf1f8cc12c4b19e33
+f046ce97b53deb549fea96cf6ce66357c4904b7932f5b1ce03cfe3a10c976b9c
+c9ad11d7a02816f8e11666ca8b3ee1411df2ca94172659bad929e3e3e5248f48
+0690cec6d8f7061608cf2672f65abdc96b4fca84d5c847440cf9523d3bf23f6b
+d4365582e4b187b6a1a0282ed323bf221edd0a4ce11ce7eda738d1af48b2e19f
+eb3da1664de99c447c35dfd45069fded1fcd70b4a6855e91ffbd7146efe88012
+0bff1d6d1acb53d5e07fb5795f561a4a3e953bba7c03a9762adae18e58dce6b3
+b1a703122ef3b16963ac7cb9682ce60e17947e7e675d19901c7e8272ce4c9fdf
+536abdffa429b820a82aee9a73d7dcf77dde4d8e251cb3b3a5b0a91c0fcd7fbb
+ead7a812ff194fd049f28b82f4c2d73e41cc73c1c9f668931a2c7eba5400a1b9
+0902efe6792f207136e1e16b41794e6cbf7316889a602d35c37ef36dec95af26
+e9bb0900456f2ebf2705ecce7b2ed90343d23e006ecb282d4b3629bb0c3892f3
+ff9c17fe6c5fab68358e1cd44aff021948ac9fb8410a3de22e0a01e367c52470
+2a8cfd284cf9e8f505d5dbd7bbe242fe071fea0094a55ed1cd7c9be6b7c56c98
+16ad1985fb7624f5e48cf6c0c2ed85b466f64c52f017b20cdabb85d24452e086
+3942362e764a2bda0f6c1b24426e302ddc4403a087efb2850cf3275c7b24275a
+ae270f212831f4c4a5d95deab61923ca126e587e8f5ed4f2d5738f06e8c4f911
+b346b8ecdac481dedd2f546305a7cd63cb67d40093c618fbbdf498c8d7ead8c7
+1f5f022d0bbcfaa8670e3b3b999a1697c947af38d7e1a360e3f0825a9aa77840
+d7a9dfd575ce2f04d308f7c553ebf569ac84f2c12aa0869ce107c713a3cce624
+5059bfb3f5aa27d10e337086144ab09286be3825a3482c5422454c6a9cbbf205
+833316780eb88302796fc427a0fb9e53a7bf24577feb3fa5d85cb6344f908007
+183522d3c760c11fc7da8d14bb5dd800576a6b4d1b991c1bf3db0f9ca2ac5d22
+91079a199f2f6e6dc68213d33ea893b74f6aff30ed1b51f8b53a015ffd4d2076
+b71f73225b151cfcf11e2a2917cf1b3f60e2b4d442307c394e1625f7e60eb12a
+f2eb9ca7b17b082f1664d09cb7a3f38aea99a13f659089426126f47fad5b6dc7
+64101cd437da3c22bc43e7a8de07253eb371470ee1e4e42a5d1fa2c4db5565ad
+79d6271ae28e8fde5d4cb24064c145de44ed486a1e7df2df921f2b1be5fdb120
+d8b781c3655ea72dc22a2a2d37579f0af60b42320ab25c8d769124352448a154
+7a381b388a4d9a54e82f199ba35f1a3981823ab698e3f87d38d32addd4f13832
+77fcc9acee7fbd3285f689a85b76d0feb9e70f09bad0ce144770a6cc203ce40e
+15912de0e3465dbc7918e3ea49ade57ee8c48c75937f5d25498c45170693067e
+6902937c9b43ab6080111663d5dc6d88f72a39c5e7bad677229498323a3e7a22
+2fe2552b00cb91ce2848a1a53538b7af2503a3671903e10df0e9641dbb70577a
+e828dd3cae98fa9e1a74f4377f908d3cd79461408ed29832bc4c9865550ccb00
+45359282255057a4bd4859915cf1e45ecdb7329f90bbf63e0a22a54b05c5acd1
+9c7c4dfc25482a27a20c7ab908546c3577e87ade93ea46436314a0a7c524b892
+4b012239e77cd65ae2949bbf7e46a5a2269b7ffb1cf8a5bc7eea1944d2b0bf37
+bfc36adad9a599fa133f77935f24ef518819d054345df144731dd2332b0f7f5e
+84c46af486941cf1293e86ee719c9bab6263470c7009c3933f1857b0a863e36c
+288d37e6ac85e6a1b4e6e91c0a9fe367bec427ea3713e8d1f0523ecff6067717
+244ca21c177968583815f023420a660f7aa4cdc8bf25ac3b3e429942b9f5123d
+84234c186d9226487c76dfef5d26165771c0e75f0ace7e3882e49de831b46c12
+e30dc37395241d7619c05abc40f5a36f8042b461fb6c3a5181f77b14e9e6d978
+37356b4b31fac3850df1869063724316104c799b6a2f42c361a375e4d29eba7f
+850fe29efbc2cef627a25db549a4d4c48f9fc9a2f32fa50c1ce6b5a545a95f7e
+bf2e9ed710ae91ace1281a44e49aee4133ccc04926a6dba24b721c21188c89a5
+2a49745501cfaa4364cf49e3ec2a59d9ee46f33362634f9758827b199fd07dba
+939bd7387124656831862f70a97c5a05959572c74865f5902e95093fecdbea3b
+bba9b47dace807262de0c7ef04843259f58a323471237cd573298c5d0a0650ad
+2acabd71cb44c63675192845e3d01b3b28af871f347d4a460cc28d9e94409443
+30e893d27b06132063ab727a38f447a2a4633d29adac01bdccc7634e64dfdc55
+9141f69e1202c4a0fd48479b0ed95a7605c94901373e1100a6cbfc113fcce445
+e0317cc94a8507dd637c37676954b9d34c6727aacf17285876db16dd0e11384c
+2b996e85e82fd8fd2b8f9b83bccb398b997364f0ddb71e60ccc50cdd5d122eec
+c36b86a89fbbb5bfb227fba3a7b7de7c907e58780fc276c24ff066982691a97a
+50d14362d27d790375a47162decc53c5c11e8a7499788dfd86aefffe7e674aed
+26706e2d079e9a571c6a32accc8c0dcf23508f58477d05f9a1fc679c0da64254
+27ae33293d02c9eca01daf2d0a1b07e5515d36e18caa3ab1b6c5736dfdefe384
+dbcd244f0c11087a873c4501c6de2a5a57e346fd3f92a0451e63fff6b99c6dfc
+64ed8673dc54ef6509d0d043925bce39072fc64ddf2c49b8602d1a51ee822f19
+d7b2135aa84626bfe3ff321a6bec3a003ad97e7699cfa34bf41f9c2b38df4794
+cb5ae36c95f42b44212de67a96ca9d047587998636673a031c4eb03cf1a55326
+f5d94dde75086b44f095ede0068fb6b9d256759041cda04ecacbd8d7784159af
+ae31a9c637d9a5c0c6840dd9e30eacc66d4d6fd6f12a603aa2db3e9866693070
+0d69cddc416d4b76cf6b835c7bebf914816b87edcd5a24e346eba2dded30f5a0
+dc033e93b040a6ee7f8ab3c44c61017c758c11c2e2fe3c4f18996287a48fa9f8
+fd068c42d0d3384ff27c5a88ef630125562663ee95a66b7b588b417b20d3ae84
+6ecf2693940d4733f9e70b0455b6097e73553eed34df8da712c29d76326670b7
+13f19d4b5ada1833d46fd6cfb92b85eb946cc74252718cc5e605cd6c3c5a46e8
+51536cddcc3cb244c78e629fab784fd76372ca9417fa67f292a7e780b78186d7
+f391cd91b6222e88c0bcff66208814965511967b2ed0d075c77b57701608b647
+b4e462d3e56e06c0403f858582a754dcbf8841fe81d39359d8c5a77c8ae6b795
+c11b84f702de09f22498a189a4c69d726a63260784066562a50544e5d07aebb5
+8265c1c6607bfc6008f2edfc9d0de71646548e59bb374996a4412ac22ab47dc8
+357153c7c9061e95952a729a80fb45f3650fb0c84a07c1956dcc0856d7b0fa71
+3f09c1b995b0c48c57c9367c0601a46cdaefd0460735682d5aafe8545cba587b
+ca6e8144ff14a25b2fce9b23d8ebf715c5a544bd646d5460d2f8cbd44b6d8203
+54e4b7377db351ff26b7b9336a7dca3a610d3a92541054c544064447ac6d1a15
+cf1d1a3797cfe85fb55b56ac01fbb6f47e9c8e5c2929bdc7ee14f6d868464493
+df4759cc80405ef270a816607f248c5c1d5c56035a8ffc1fc1b5f69aabe2f964
+cba4c0ed5416a20f102c82bdfe59ddb4a16140c85d55af2aa52c92ee85c37881
+9c95865704b3cc39da6270dfaca8c3611edbb6da767bb50a03d6a06ed9890104
+da2a575ea45e16da2e1fdcd603c91af6beb934ea33023152c25c27c3c771b553
+1a9aa1ae684e1539e549972c97321fa0710759b6d4b9e55ef1b41bda01d77786
+87c22cb79310a9000bade74a8ac97b3eb2ff024bfd60c0ad7fdedb23c805f64e
+fd139e015e0d1d3591be5930c356e6b8c1a4f0ad9af94eded4ee9aaa436d4cf9
+58c5897d06b7c97cdec22745c46e7b37695a8c66140f7f8421138892f4851c3f
+d355b1de1d32145d39243d0590a90f1c4ec2c246d3f3779b319c38d4221576be
+fd17d8bc8819cf8ec30075305f8637d1ddf0f7255ad456cc290f10ec39ddc2f5
+290092718e7d268531aaeb377701dafa933b94ce763c1954ef0cce19d77c9208
+157c38b279c578c56b7e523afccc91fe6819483de18ceebbe74b81844ddb84c6
+22d4f29661e89e5417ce43c28028e9e1c54063afd716088b6e8fe0cd1702c2c3
+31273573f5c3d760c8a2c7cbb362ed650ea8ff54f19e097f14af9739885af15b
+46ed31cdef73db671b22efd41ff3f6bbd29625fae7571f9542fc06c77e28d2f6
+3ba2c9cf89da564de3a6fb3f0ff981c5c482a1e1de730041b7f1c890c4528bf1
+8e79f2fa4ed8a738f09a68a5b53edf6cbcf8861003917a89989146af7ab2e5a2
+836279643900c27a90463679a22f0ca5077728f6ae8a28324f9adcc19fa493b5
+e2465c6d98cb608f8dc52cdd6c52bad1a1502779b638df9336e12f035b3c310c
+b92b3add047365f2d25b0ec7e05cc46f31c0575eaf4ebea0b660aa20d9e7edf9
+0aa077e3000e25176038ccc92d4f9fdbae6b05aa2e17ad004e13308464a20cdd
+0271ed0f964e73cb11f18c2b795dba31c3ffd5648c63dab395238ba7c0cc7db6
+b206e6179c6ad7c2534c46a2b9c1d7fe6bc693df35118b708933677ab3a76cee
+9ac0303c2c0967d718a1691f6a922abb6b37625fc01908c10242731b79a1a82c
+fce9efbd1c6bd483fd867bc2938609ee52c0271a7ed1fde1b8667b98e22fd450
+86f515fd2ac2c11c50fce95f3e506ac6518dd4e532ddb100d87a9240bdcdafc2
+0c8bec467d76261165e9d8bdac9197ec798c81cfe80e3619f432674cadf44ff4
+3f61089abeb13d665e7901f4a1ba84115333210009d55e051b692aebee9d9bf3
+d0219c290191c17f7317aaf402b88ba353c25f126e2d32bef73d528c65af0840
+3ed4086daff574762531794fdbf637b765273911297b75338691e9ef4d2ad452
+22454c6a9cbbf205039d6d35c09a0ce284e9a776773a98e09e6a816dd71d80c3
+d80abcb006353b4b7c48c76bd9c1ed9db78bf62e9ad2222e5bee9fde0281f0e6
+11fd6f899938cee729a184be7cbdb0b84fc9c380d6c69cdd6e0f3f6780af684b
+cec6361673853b400f47e00177ff1ee7f9eb8c285a49e137e08d5d7663df71ab
+71ca71adc0857055686a04777a2e1408ce629e018c97524af5588991be92e4fa
+4a27745aa950a72d479c48d6f8c30d4258a882f199b4359f92a963fc650230c5
+79edf743f2cfe86a197296dd675bf05f25ed969de77bfdd0b518cbb5c30b4e42
+27c5117f235b34f7fc32413a980a38968ff9b8151280a0259214790e421d0f39
+eeebe98adba820401c2d47d4132cc68cae0f59b049d7489f62259bfc55091c81
+89e2480dcb77f689965151b7f6706af675a871370d2195b07457af8809f7abfe
+7d3672d76a74f55ec749ef40f755a3eed96cce000644ca0c497afaab7294afdc
+13c3239f54f3eeee809bcd936ff447277d2f3613936e7b39e683f25b60505f2b
+f4343ed0902badeb62495cef53789b9e74baf866be33efe66c1c5faa95f60ac9
+156a26bb9f72cb73e891ee4b905f72845b3ae05e025879f07a7b91fd06204148
+60832d64b6bd5abe0472aa7aff07fa05d23a01238b6f624ae8db25bb71ddd893
+1fc6003f23292a428a5a99df5861e0ae858c398d66d027a32a71d6e62d62b6a1
+a1db86b1ea3005a201618f22899cb1e7d70f65fdcfbf7962ee0d0d15412d006c
+cfebd0e0892888f26238bd1f7f090de03c41ee4ba53548f469fda2d94f6b3da8
+a606fcc3554e3f261b8490a3b8cde3ee846542668ce3b371318f9864c45a4223
+fa2a86e12034bba867c4abeb461c609c8d47e184703bd6c891f39076ee06bfd3
+bffa679de07d8c8eed9b4b24ff74c6db2cf84108f28e4f0fdb78e0e726a9bd3f
+2a1b94daee18fd20f2c902cbeba13c1b281d0a11a96b20800e4cf939dd32bda8
+25aa63d9f86f380af4dd379d80441dc4fbc0719a69ebc16e1617940a19eb0b44
+96581982d45b08e512000e3915490a1a79b908e1e63ae129750fa45dd33c0e9e
+2e767a89c6f11e33f193da18dc6c820dbed8d370492c19ad9d6407e50cb62446
+d3ab009d9e8f3c51eac2139ab64ffa19b70405813652fbbe33fbe5bc95d40b5f
+9ef833a4b1b51e56065abfef1036eeab8e04f096aac0d2813c2e721e0db97368
+c17f0cc971c9ca18a2db11745f67d42ce5148e2e8b2c0e13e4bb16a2789f0c4c
+e7b65be454ea623212bb2ce5afc6b5b3ad5bfed65063354becbc1531389977e4
+6599896d9ddbdf3ad6fdd8a44b14ec8cc9f131d73cba91e28cb54b37655e4b44
+db0457ae7bfd3c6b73bacf09861a7fe4b664928230fa03cb99ebb763703ff8d2
+68877c3a3b1cf915891578aec60c1f7d1e447fc777d8eb3573ba2a9ce47c99ca
+a9d52f2f12b101fe48658edc7543ef85dfe01b72dc4dda597951ea4298fd444a
+ee33b14ff2f91b7297922daa7e346493080868f56aaa2176c9f2c1284e4b2672
+a3b75face39df1c8b7a825a3a5c25871d190e48574e1d03a5fb094d418c47ac1
+687e8347036cc44fed3d84fe5d4b84a61fac9968b8d004c28539a3681476ac45
+56538901ff2764c1c46f5ffe048cd3a7eafc6a9fe98ff9b3cfdf3ac035a9d3f6
+8d75440d43a1842cc1e8b6b9b6d49a9bd093620735c9c7c11c21652a5262a86f
+c10413a373a9e02a488bd9a16a51fb51b027b2c5cde35cb1aed91ce58703e1e9
+ebdc1a161d754ee437412182f7d532426841e2455add22c031a2171426881bbe
+4090d1cbfc498ef46749308b73ebf4dc5a06adde6f83bfb368388bf7c2d900cf
+57932ba4c9db0f15faff7cbd701050a1db98bdc9a5f9f428980ecfb1e999f460
+231e59b5c62c7879278f10f6a61f79cc9da24d35a2d26996d8a4a106e081b8c8
+3fcc015b775acb00f78953a834018c146c65cd715bfb5f90c03feac01839c6ba
+156e327c97350d2851dd77e8263b967742472dc1e3b8f0e980de9f1815007cea
+51619d84375b777d5cf32a144affd8ef0f4fee2df1f839b2a5d900ec8e76363d
+c829f1d03d211175ab982226616b19c51800e4b5d4b28aba82980eaac6131940
+026e3c2297e197fb8f130fb15d2c4098b97c84074d4e50b5c6606bb0f3230931
+52b39a58964b4ca44caf45f63af49b330ab3dd863f5ebfa8ab0db6cc37838a64
+72c601c215037e94ac89420fea13d52174ed5c933e8c8525f88e6ce482661861
+58b904ba7fdb864cfe04bd7ce6070fc5ef576b1de985a8c4eeca7fe32b90d320
+9091d8931bc21c6f969288b1cab44bc53755d8d8f257466803dfd5725dbb5830
+4be6c784fb6f8c5e66802028759c0597246fc103eb63b58f361b144668713570
+8c6be071b51fde425a0aa5724986ca67e87eacb8f517fb3103e52595ba002e02
+82e54cb82b04c993d991d70b5eaac7a639213ec0f82a1d7750f3f6e94d8ac7a0
+8a586b816a9fbe78ff96bf1e3cd52798089f279a0a0d93e0314883988bba0f78
+7ce5745f8b07eb3b750c1d0a13fa4b0338346220ff9ff10cfe04f29e2c24aef0
+f77f6748b63b0c6d53461536034450820c73116cc66feb9c7f7d08e0a47d4c92
+ec61c5342099c27d93a79d9c9f278142ba03b51d6e1e03944abe063baac32629
+1b5dc30de8512f0cb3a973cc43afc2be532ed012c3eb58266cbeebf611f91aa1
+489d0174e713b976f3a0b36c575df597a3d8b12d4c5441e3a478f0933eb129ea
+e44484e084bdde7d2d9ba23a6bf1bbdd51d96ba4a5207af1044e917186b7e66d
+accde1295b615f37f1395827e29e3a1711fb2b6c50374df468be421cc531eae4
+b3cd2473c979d11c11beaf14aa9b6cce4acc8208f22f9fbb6713bb8306e5b5a4
+d46d11e604114d9a5a4be0615a843d10de54ad62d582302fffcfab7f785b11c4
+83081286cfa04302f7b92f64dbb42f3f97cde0c047662be6a3e58986c54b7c3e
+2ac1b0d19bc1490311150931aed3497abaa74303d3f0a3f3af8667c4b0b91385
+cdc9bd2ae98ac32a2d943e0583a0f3c74fcb803559fea211098b48385d3d8d32
+9e2cda61d7589e5383fa32abfcac50355549f1e819eb31531dadc47f5e759790
+d355444f1efa6b1dfc7713d446008225808fffbdc81a3b1b374c7f2901e27e2c
+41c477de0e52e9005288b7175117b32c326b3ad2b9f9342865d0bdd0ba6044ac
+395c2c69bf82a7aa9b77842a3bc7b4a675b0c32a4e4504d2a9fe8762170f54c3
+4dc3620cdea9d1877f274559ac6d37aa83f90346130472775858c18746db4558
+4f2fa7698926c4fb2eef0951579dae63c2d3c7b9e1fc811ee5dda4dc5b5e61fd
+c0ed21724902532087dbef11b1fd0d71eca9f271a3d1bf8ded5df19db6761547
+97d0a12f94147d64bade52704f880d0fcb89f4958547c6839c9e111892797f29
+4e65f7a54e14ea3d3f50712979f84852e57b9c1d70474a3593d53f21603e00e0
+e79ff355914f9a3d4ab1e14410eac9926928e714248535b178d6fe9e0e84ce99
+59f66fb52f37a4e3dfa5488b76d9ae2f62d4495bca11cc148dc20e29a694fabd
+e65c7629ebc40ff0c0fa109631655d3ef9848e16aa7c73cfd4aed02f8f125ab5
+0d628ce52fcae577c7ef0ab688a2f4fa9a0e2a9b10b93130f0b357f4679c1f7c
+9bd270f34f0bfd86459b402c74224a621dfad6ed316d05e15d31707fae7a9b62
+f8f75537326742f1e9d0c7483489f4f4fa38e0f327f24fbfb26307ead2720bd9
+678f45875eb05036341ba38660630b7d005304d4388ff7eb3be9c2635c21af0a
+02d12fd19a4e52181a9c7f2356b2a16eae4e8ed5b1ea0c01565c26856787fdfc
+2aaaf11958ff3414ab62ca19e947db6b78030e2c528f3d1c0215cadbb0c34f72
+6751da03c604bae7b97f379864bb54be9799bd387e88d6c7053f83dbae1cfb04
+f2ac87d12dcbe17a5183780fab4589e8b0d70934e856f11629a91e6d13da7704
+73cc80e0b80bdd42a71eee5f43a4dab994ee7cfeff83d08169aa298c98a85477
+dfc729ed6db098b4ae47a25b8ae7587b8cb2d59cc0989c06129fc201e7c9b763
+f8b3f651a5c735edc975cec4ce461e81ac9d5e3b08a708fc536b46b9566a58c3
+0402aafd2b6018dd063877b880f85e09895dd4c9d89b5f264ad72cbea438c153
+054e1a5ece2091e1d4105f46b047b75ff3be86491e694c1e2e03bff36812d148
+d9923f5d89a28fbc4f45fbc3db74cc37bf3cf41b070d72a4cd571524fa6df788
+3153e77818641287ae22b1c72331fbff019ccecbc1709615ad749dc77cb6b331
+30ca3d0fa05cc47447c17d96cf6ded782ff6b505193915aebe31f1f7b95dc9fd
+91a124f9551224117174ae1e05754dedcec813a8aa4934b73de1b20d7c10a20d
+83a8b085cc2d431b87397e5f8286c0a80704101475ec9845b2bf7ecb9ae457fd
+abad09e4e8ee411d4a20518597b08d5dd66afebba03f632ff2ed520270893f00
+35cf0716f4a092faf8a0c2a3f73ca46afd2a825eee041bbc2b649330fe821807
+707a06ed91847b434d34742844947d54e80422f5b5b56f6dbda934089c32ad12
+375b31af9aa91329c253fafd3cff4858c39ae5efbed4d590819d2f5963b7e08a
+99e157ca1c18b20c62a8f7bd278f560e871b6126d9cdcec52c6839417bc70dd2
+49fa373ca6dd557540906729f2fc5476c38595d958ab2b6c14629f9e16a2a9ce
+9f6e2dd760e55a38a3432e74126135364cec00a7b6dbf0cd48555df9f31e71aa
+9d573bb077085030aa3146d0693fe683884ab380f052c38b31b0e3483d122c4d
+d15a6a93eafec3523f4b2744935de9d1660fb4d8a76d82045862b59ea2183961
+f9868bf03e4a71db61e03fae93bea1092ac5ec83d71dad123d5663149d4bd0be
+e643435aabc919942bbc60d4ab56ecdecad30d270589775a3ff718cef0e2ea46
+b8c75fa911752ef13410185e5cea25aee6fae74489355d3328e0cbe8d4c55d46
+4114b4a4c85309dff4f2a5c2b14fc4f4779f4e3a8bd29076baec35cd59ecadca
+09e93d8dd4786052d970484ea3cb45b37c4a6f74249e9f5eb7583b018dcdabfe
+67259769ae1a904f20b3ef352cd191bbed998f4b2c06465d7355e82ffa718e08
+9dfa5c8fdaac95d8e05cf8b5a899b8484c5ea104eef3e5b21436ed396662222c
+8cfd00b5a854ba9338da205f16e5c0f451bc1c6cf34f0da069af5ccfb460cccb
+b6f393a99f6138e0ece299e0c0f7f1d0c83e0b936cac2dc38f08292245e7afdc
+6538c4fecc7d712ef83997088f73ae6ff0ab83d0ae76a7811cc07b41a57d1d34
+04681526d327b489094dd961f2f60a0c6c275f09f0a171e88056f58735d2f502
+65a167d12ff3395df58c3b901a68f0d96f8ef54ac5548086229adac495fbc256
+afe832991f1839aeddf1a87abc217835e58af4199823165fb9899fc831b47bfe
+4c3c1f5a2696e9a5f310afb8138eea06fda0688e0d0d7cd1ceff93a72c57289d
+332525c3bc60e51ab25526a4876affb2c64657caf14b34fca46a78e41b0c1955
+01fa1a0c0d77d5f7026234af489b316872e64b4d449efc540fb0da553063a71b
+d8ee44b0f9a20adb9f60b99803f1760c0cde357784e87042133aa085e9a37a5b
+b5685e73354ca0e9a48d886fd12841674bc0713d43301883f1c2f6190b47a4b9
+996c0e528b6572c96232ecbc57c57073463ae36b5b2974163cff75828a20c47f
+926e99faab51f19fdbe0f89bb71ffba9eb95a82b3a712b54578f665a89edf193
+d575ed95bb883f9d6797029ff0cc8a75459fac0cca4530e17d93c9834a8d9c9b
+376d3e40f3e44e6e895f25c90a803cf8b0f3056037809e3ed618475c199f43cb
+a7eeff84d38f49aafa4e469aa78cddb87ea76a87da1b888c38e225499d1bb089
+32d599918227c97b1e4de521460f1a175ff2fc500bb95574d9eac64cd00896f6
+27589fe5351f46a46d1fe8ae16fdc945decb08c0b7d841c5516535ab65b84724
+04796bd7b7083a606977316dffaeec0e8681c10df4deef6335403e5b08889558
+48bfb1b8708a5c41c5147fbed3942ac26ce66357c4904b79147dca55f039b648
+ae18d0d6d330a621301e3c1d6e478fc6fcee4c3382d463491a167596ff51f17d
+1afdd4ee7ab8f1b27b4ef2b665cb6818637b5e982447f6d7ab2806f769d254f9
+f5981812a9458a39f51366773a8980c7c6dced448d878af3bc088237815d2727
+40093cb7c3a4e6e86ec6cd61fa8ad13b20e270f97ee5be1799f2966a0ca2a7c9
+32de08bb021adf9466f1b88ffef315b818954057877d3d59f173c1b1874fffdd
+e3749a0dba7d62d70483b1a7c7720c1e95c59faeed0c8be1913177c6dbaa6905
+a6bd1a153906aa1b6919ebd1befb9a54d9b84cd9d548b1abe83933670ea719b8
+6337d01283b95306db92fe059da52d107ec47819bd163b3830c989df4052614a
+9866b057aeaed455fc9864df1960e97806cf95011394e2052861152024969836
+77be8008c246f14aea1c26e620fb331f96cd32a23b1c87d534d678181a198758
+4bffe069fb5a0c6b63ca8a9cfb6c3fd6ecf07c5bc59712ec7d02a5b988c3fbbf
+695fc7068a644d8885ccd88987532539e5cefc64fb97ec1376ef0a97970db510
+4c19b7a64a1b4f7eedfec2515996238dadbbfa8afd8004f12867de20912c2774
+1ceca6f2956b340ccb5e30f2b1f5f6376e6d3a272be05c29125f6d74bbee7879
+8836ee673971ab724dc89867d5a939da0cb41678fbb8d8ed35efa28de86728f7
+953c9c5896b867e4b7df3322563aff8a31cca8901b5542af2c7254547c7c09d0
+15baa7cbdc7352960ac650a543f05e290341d245ddd331a556ac7fc0ee7eb246
+718b71073b9a32776f6215fd8fa2297a2e9be23728cbb24c53ea10a4544ddfb5
+7d6292640840c77bf03728c3e5d2665ed7db7410c9ecb32c249a45664f72f8f4
+2e81a2e086b535f6473b1a3319d134317edbd1864cba7b79f89ef99d16c8871a
+28fbc4cb45f982bac6de81ef637a7e1022a5579f73867e40e31ec8903632e33f
+b24abe53b1f3a3097779b977bbeb41c21857909d3e25f7bc88e6d3fe6f183da0
+0133a99ae39080012df8498b9ce322ea9b76343c2e8be3676f08602470da2761
+ed9de407fba38be82de624e1552be40a0e10b55ad74367b91c80b8bc5cf59f64
+b79072369d9e492ee6b9f9df0b91ae608a44020ed6874038974ccc9afa88d6b7
+8114af4de09e77e4b0a1a1fb27e226a62385b969bbebb657ea927fd86e050ff1
+3ebd001a022333f8caca13c54f9b345cd5b6553c90b4f7fb949d7d65d9bf9fd9
+46a3c7c531f6a6479aab0d5a7015b56959777892feea7990edbd2b423f6e9ce4
+583caac124c268628a9cb703dd96aacd35b1031e08a741d02adfd579267df790
+5ef26af14b2bbdc22a1eb33b58719a1e8463f28784f4c15cb3c25cfb2e20a508
+7854a53f4ab398b02177de500a049d6c9faa13fd40c19178e878f1cc26221c59
+b40545f5f4442abba06656ead5afd938adeb3ea50c699862d48e767c223c1f22
+246e58c5694d1e23511710817a9fd18a1620cc651345e6d3302d85139f7a5734
+7e423be145e165baf46019fe831f97602ec87b3cdfb8fea12869c98f115d1b66
+5aa588fa82484acded7ca2c13a17bda305f63ee226ee1f37cf247f1aea9ff92e
+2fa4c1e0448a5dde45294699a9490a5ea94cf81c53491fc19e2ade5af005c300
+a5fc99b893ed1d469788e94de823006f8848dc9d021f19b934278d44e8c73da9
+3728f389563e10ae6017c5caf3b4b340be1d7d2b7f24a8cfcc1ed1eb920cd366
+6fa12f35e45673fb12b45a6ed7e84937576e5327c82d7f27f6c0255f75ef4b02
+cd492b23ec1f346bdf8e007042a82ab730ab2805569d7b978a4b114577514548
+0d426dc4a8ad86de85b23ab5aa8a50a30bbdd8ef5e9ff8e7954a69987fb5401e
+a9d039d5e05ef245e3c70a85236969f32bd1e5d29d71a2013493945e803838dc
+7241a73c4c1f14548eaadcba64aebc29fd2253fa59b6b039bb2edc9e4a7c8e83
+317ec39a07b8c8297e4b08d4e6f01a53e3d690f1d1db49f19640c16441be6ae8
+d1cbdf853394cf665f741938733fbc700e8d82c4cf1d72456008a0fe55c8b677
+a4f3e197aac9b976343923dd4c5a181454319fc509d499bf14740ef1387f354d
+d71c3bc5b9d4d2d9e0e7a3bc60c79c8e6d344bebeb3b2dc2c3605fdf1002f061
+d52f718b57d1f6c1406b1fdf2ce37ee45693ba72284c5652b2d88b29ad55d9bd
+78032a76ae6427c19749ca1503fdfa6eda4861f0b0c72684589efe6c01d9c964
+1201b79c5ce03520510e13bc5461fa3d2897e2b7c65ebb571e2d0ce319248d4a
+fcde6d70c38d25f6bbf0c09b64553c3fdadc64c293deda6e2ed8c191d7f432ac
+5bcc1ac3183c92d545abbd4da7e768140b9f5a5077b08dc8eae64727eade3e5c
+05e07036b08c31ba5ae366c642f816b5fa60e148795d3d4ce050f09c443d6fe0
+d44f8859d43da39643d4fb8c5e2e34f1b32142ddef07b1c02c09f4cc9509eabe
+99350ccd3a9d2d6fb809016dbe0c1a29fd1d25cc83125ba7d0143e09203f9e34
+99c6d07cc78bfdb82f72c577aff1045cd2ce2e3de0300283ae5ac540d498e467
+0e3718e3dac6dcdf1c7ab2d5f75c5b6e56bc32d8ddace4ce7f9272aae188f3b7
+d6d31b380592cfc0de45eabdd87cfaa15143cce738ede40bd9a06db0b3d5f570
+be5b21b328b3ac4ff46abb190ec17e73d31af389dc8e887280f84caf7b317c27
+38593005aa586b3c4918fa95a9435e45db40bb52d2f6034686463c87280b8085
+877297a871dd11fa1d782568fe813cbdab6daba828c1c264c3db809cb9da6635
+640c3e991dc41cb1841ea1556b7560d47526bdc012a8f1dacb30f38ed0f4721b
+b98b107526258d66804fb0dd4c52d827850d8f0a764a53cd81f66269a8cc114c
+06482a5b2b752416707d28e88291bca02b7746161794437f61e7e3353ecc92c4
+151af9a2f0b0e0e7b8be3106fa8b455e60d1b8e7a30a45922fe00f7ac9031be3
+b9e1dcae83017ffa27f196e1b8da6cff1bc25c0d776dbf675838c24c57a3078c
+d2f6dad8722aa8997078f22bfab7e8f995538174d577c28d1660e5484270e63b
+90ff29111a71bcfdda204034ad6df026ba9fe61c02bc99e0553cae82fc1f84a6
+f8c744cf34a92b3fa239b23fa2aa469c5765c02abeea272fc928d24714c14ea1
+2dc6871a82973f1b57a2063379dc471f0dd0684ab5ce9ab8088512b548c0e96c
+59f314ee81f9ba0a793072325d5b2a478eca04739746
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndResource
+/F122_0 /DTUUHP+NimbusSanL-Bold 1 1
+[ /.notdef/dotaccent/fi/fl/fraction/hungarumlaut/Lslash/lslash
+ /ogonek/ring/.notdef/breve/minus/.notdef/Zcaron/zcaron
+ /caron/dotlessi/dotlessj/ff/ffi/ffl/notequal/infinity
+ /lessequal/greaterequal/partialdiff/summation/product/pi/grave/quotesingle
+ /space/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright
+ /parenleft/parenright/asterisk/plus/comma/hyphen/period/slash
+ /zero/one/two/three/four/five/six/seven
+ /eight/nine/colon/semicolon/less/equal/greater/question
+ /at/A/B/C/D/E/F/G
+ /H/I/J/K/L/M/N/O
+ /P/Q/R/S/T/U/V/W
+ /X/Y/Z/bracketleft/backslash/bracketright/asciicircum/underscore
+ /quoteleft/a/b/c/d/e/f/g
+ /h/i/j/k/l/m/n/o
+ /p/q/r/s/t/u/v/w
+ /x/y/z/braceleft/bar/braceright/asciitilde/.notdef
+ /Euro/integral/quotesinglbase/florin/quotedblbase/ellipsis/dagger/daggerdbl
+ /circumflex/perthousand/Scaron/guilsinglleft/OE/Omega/radical/approxequal
+ /.notdef/.notdef/.notdef/quotedblleft/quotedblright/bullet/endash/emdash
+ /tilde/trademark/scaron/guilsinglright/oe/Delta/lozenge/Ydieresis
+ /.notdef/exclamdown/cent/sterling/currency/yen/brokenbar/section
+ /dieresis/copyright/ordfeminine/guillemotleft/logicalnot/hyphen/registered/macron
+ /degree/plusminus/twosuperior/threesuperior/acute/mu/paragraph/periodcentered
+ /cedilla/onesuperior/ordmasculine/guillemotright/onequarter/onehalf/threequarters/questiondown
+ /Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla
+ /Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex/Idieresis
+ /Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis/multiply
+ /Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls
+ /agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla
+ /egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis
+ /eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis/divide
+ /oslash/ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis]
+pdfMakeFont
+%%BeginResource: font VXAMRV+NimbusRomNo9L-Regu
+%!PS-AdobeFont-1.0: NimbusRomNo9L-Regu 1.05
+%%CreationDate: Wed Dec 22 1999
+% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development
+% (URW)++,Copyright 1999 by (URW)++ Design & Development
+% See the file COPYING (GNU General Public License) for license conditions.
+% As a special exception, permission is granted to include this font
+% program in a Postscript or PDF file that consists of a document that
+% contains text to be displayed or printed using this font, regardless
+% of the conditions or license applying to the document itself.
+12 dict begin
+/FontInfo 10 dict dup begin
+/version (1.05) readonly def
+/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file COPYING (GNU General Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def
+/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def
+/FullName (Nimbus Roman No9 L Regular) readonly def
+/FamilyName (Nimbus Roman No9 L) readonly def
+/Weight (Regular) readonly def
+/ItalicAngle 0.0 def
+/isFixedPitch false def
+/UnderlinePosition -100 def
+/UnderlineThickness 50 def
+end readonly def
+/FontName /VXAMRV+NimbusRomNo9L-Regu def
+/PaintType 0 def
+/WMode 0 def
+/FontBBox {-168 -281 1000 924} readonly def
+/FontType 1 def
+/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def
+/Encoding StandardEncoding def
+currentdict end
+currentfile eexec
+d9d66f633b846a989b9974b0179fc6cc445bc2c03103c68570a7b354a4a280ae
+6fbf7f9888e039ab60fcaf852eb4ce3afeb979d5ea70fde44a2ae5c8c0166c27
+bf9665eea11c7d2329c1a211dd26bb372be5822f5ea70d99eb578c7befd44cdf
+045a363056e5e1cc51525ea6fc061dcebb337208eff729802376a2801424f670
+0e7e6397b28f15bc10b40012b0a3eaeb2693e8f7f627c4c9c7c6c5bff105c1e4
+1b2b9e8f09253b76040d268b80719e1b3f5a55ab7b8e152a40e590419249f2e4
+c36159f8e54b532468e36965a38646781ab0b7f6a3e851fd10caa49adfc1e546
+2fd2ec6150dc6e19523050f6148348a561ad8d2e2721eff8a570cb33460a745b
+926c889304c09753c2d78fb0ca95dc6de5b8c524752c83601e7e9f73df660674
+f05ad83a166da9be89f22feabd4b2665960f6fb5bc32928e1230c212e5d69cee
+0b3311a1738a11747ae263106916d8e95f25b25b4bc6afb03b79abb95dda518b
+41a49458111d2a1433c043627ef9460d324ffe22935f4f6da88b8b91ae95b34e
+08408a34ec8eac3f65b6ae3e3e2524867ee9d29068f81e4372f4470beeb4d6be
+ee4df956becc0cb77f8490117b22b2fb75c938ed0a5e208d88bc38b2ab8b9cfb
+f1d53084b6f43df336481eca0aa2d5317bc83fc0e1d4db01d0b7707eef217e94
+a7f985102ded27d8e8b009f7ef6db91b91e78bfae7bd688e10b3dc9ac77cdee8
+47aa4dc8ec78241e593d26ec7a60696151a2ae5325d736e99e01bdcbde69579f
+92eeec224b6757eedc64a75455bb665df42a0e4ce7b99bf3e7d66f8ffc8c13f9
+d7a1ff7a9d5ff7ac43396779f11c9b008c33a2043d48b61b88b03104b1425f09
+675b559ca4302c001ee80d2b739cc0fd1023bf4f1ff9c01e892e59cca7c26011
+b8e0b6d29cc29fc72792fda5e7d5d88ef98f9dba960c96534c399c54865eab86
+0fa2e0d6c7c44b553eac1574d55e7970744d4792fffbdce6fb4365bdbc2965bb
+2e9edad9e0ebf0b620db415ad98297f5ae83d9c710436657e74d26e83957c745
+89834337035a7501803947f6880b70e56a3a404c62d57b849d28804cbe0f5884
+435a0e12dcc9ba414abb732bfbae237001f557dea5e972ba0838a3c7c9eb75aa
+4a050da0a529bdffbf9011c360564fd17a02c18860af6b86efd4e2c125686c9a
+5e114e95c71fc89a5de9c589bfe5ac0480cff716345265d2435edae67cfc4801
+5bc08e7a48d683acdb91e05f469c0c8919d73a5d07a1ccb173e30e76680acb09
+02a40a3e11916198bd69f1a26e88330f50692d0d5917e99e7a01b327413e24aa
+e98ea484e45897e6ae4d6997b6e8bbf61c9406e916d56985cb2bd297e8acfc6e
+cf2d2281ad84696b7c6cb584bd85cc20ba14add3bc3e25db91124c0acf22e902
+3cfbf04cc40de331991e9075d22ab5ee0e849b340050e6c417c664a782d05549
+db2ef572f193b1c12b4635c2b358747046de5858ec32b3b2e79d42750657977f
+acdd2ee5a7c9320d907438dba63aa05ed410fc7000f53549091be71be45da4ab
+a315f95b724a60f17c70833e889cfe7ea206a7abc4393cb6ef47be3700ba5638
+6831391809ef8384aea8c22735e8062a9f9101add125a321fb65399cbcd9c9e6
+0f46fbf271b2b1ec80832cc054bab5ca80d4561da0a380d56d5cb3d90ae89a19
+48cd824eb1e7ac6127a6dba3e8ea40f00add89749d77ec0eebe26fd6ea5d8cce
+f7239681b3d94898236ae92ff3912e0afe84b6c7e08134c158b640b4aecab5f2
+a90028e67d33df31b461a2846f83d90979bb22618e2a17c5d159fb59d5177e12
+edf1320f596e7a4c379329adb367f92bf2869a9a97398e0c20f5f017ca9db7ba
+b3bab72b87a7b6bf4febd03132f9075c271f2054078396df8403dc91461325f6
+12cf1421f3099ccd799c2c099492c4f071336d985c0c360b2f5a5877fd00b6f9
+2e5911dddfb31d17a60124ee8da6cbda94196d7ed42804610e4f730daf2f2d5a
+b767c320c62543e26534314facae006ba2064623902c8ac479eeebb609e8c3e4
+1516ce412cb410bd026231e22a9cd0f664d769e4e45cbb75b7341f06d8e37285
+beaa9ab71aabe3cbfe5a348681aa246047ca29ca6b442feade254c7582d32d3c
+71b5e645c82e92f057eb5f859bee23daa95c575edaaf9896d6c10980a09db34e
+084c8a754e31b618c6991baa856cb86877044e10c2f189b284e3195a2db6b910
+2574e2461d2fae65b7321c0093a2a34996c0b77123503e9edc623dd02c44fb76
+3c550840bdf969582d226510ebf89944e59684eb2e2c463e69702266fbcf8d1d
+4c0be400495e227b9cb21c8086f328782ca7294dcf3ecdc1a62714143a4c1b98
+e5de1dd554fba60571188a58f0354a6b9ef580689b78a0c8515ca05a35832616
+7e0a90f68f3c306ab60aab20872fb167673f41e8e87ff0111f579cbd0da68b56
+3e35d2ebf9f28b104082e36187373efc7a33f62d3fe4a390b63a76e9b2531871
+6bd59861f51b561dcc115192a6fc22d15a5af03ba09cdfa66b660cf4288e9d79
+26e797256659b0ff64bb5d900990c3cb588e1e18810bcb009a91e5f4f8d9db1a
+f2a063bdabd9c3332f4bdb701bb94b4fd24570b440ae74b8d924e48e7c2defb0
+53a19e5b4df39abf4f6fc6160b5fcca00608422a3091cd03e726b1ea1d203b3f
+c44173460b490498eda3121881ebd21cb5b571d21a6228cc0a1b035ebe97f26b
+0b58179bd22ac950ec3a98458051a874297cd6bfe731c5b413819503111f1f6e
+ebfb5628c955f5fcaed76f2402ce351f77e471d1c9821dad627ff25131590577
+5ff9335dd28d85a11bf155765632b34a3aa1df9c01134bd8fe927e0064319951
+e2c1d374c9acfc30932712a5c3e0fe3c7e355e3356e9135a143f1b4e2738e208
+8f44633dd9300bafc770625a64b2bd20d4f672701310e5d1d5b2dd502802539a
+65344601924c473b7618f9b87bf6eb49474fe62891097b9b381dfc9dd22f6ceb
+340efd950b74e614a2908eea7b0d395e15943d0a9072e2c0e6c91d9141c84281
+6a59f02111333723db78c2c287675d73152ee3c63397f5ea6203c707568137e0
+12438b86ead16d71a0a56d00e6ace9d80aff646b05d829dcf08dce2fed1a17d3
+83a7c9e7c2a5caeb38bda802e6696bab17a5d1e5d6c51b6371c642d5588a2945
+1f3c8b0cd56806531579f7c0d10a9fbe254ea910522d955c86ddd693b8660bbd
+17b2b23fea57af15b1720e42c6de537074c071c50c114ac54c45ba2fee00d13a
+2573bb9243648a1be2569cf68ff78e4cacacdb34dad918a30005c31f17781633
+6b74af8b9931bec0c1892780020c1a92470e3ad7f1bb6ef26c835f13a9c56ded
+51df4a7847c993b88b9fda9a8955d8bdbf6ba773d06645e292ce26d9df4bbd4f
+3d20f52161853827837c837f33425990818b958adcc3ae79b5791ff04daa32fe
+54050aa9d34606f16c7763de770cc33c9acb60e5354d5a27a687ca6e0fd74a4b
+5cffeadf6ad0ba87b906c09201ff65ce6c3f620bbfaaccbe54da884b87e906b5
+f5285d3841ecf78f0a1ee4a80724da3a4fd49ffbaa66be3402a2480a6f8fc164
+343a369e2b8947fd5f58a4697234c742685421ce3d57398c5ed6f6b049fdf39f
+6870236751d9ef2210e680b4d8a6daab758bd7fa7da9680604e5bf85d1826611
+2ca08e8922a1d46ac853f4bdca37f7fe80d2d27854012e4a8f70bd854ea4c189
+ea6939096b56168aeb971aaafe1bca667137a76761cba2fbffceafe3e98d5590
+db3dbc44b3f9d4ef0419cae23086898bb25a222eea19c1a760389672933ea7c2
+8b31025619bd108b79d51d54e23f401f42165f0d513bb2409ce66ba3e83fc000
+4372873eb8b4405a8f5bd88cc2f21d2d60fa4024707869c5fd40d94028ed13b2
+5762cc7924d100d3ce0dd32cfca124ec1fce4cce8c137070a18f05cd73809449
+bcdeb0ac24dcf63679d46aa8b3a4a5d0dbfa9342716619cd3683dfa7a9d6683e
+5a7a03ddb47833fdff8935f2f004f58ede6447adce4fda1b734c75c52d16c406
+9428cdf68855946014584f7fe49b03f896e0054cffff5da4728bf4ce1d892052
+701b48b81f58f5ea344e8ebfe13baa70cb43ce4a979d8225ed78417648672e61
+07eb7b31f81cf52b4136288200e640654e83534eadf05301faf2f3a859772c3a
+545fc20429119ff00c259aa582af4e3cde1c99769f4e433d9b178edcecf142ad
+ffaa6da004a90f53e70048aa8d15a26bfcf7b02ed70bc262d165e99f87ca7424
+0eb98f3d7fc0d4926ae43c8d322bb9eca24a4c45f7dbb0feaa9a900e3521d6b3
+87b52a30acb29c914b06793f19a1efbe3be7d0b8e20cad99d292c315b12376d5
+655121189a833132715762ca7118685814f71aaa08b89e466c7468bca01bd98b
+63ec7cc3ac41dd06c5bbda86227afcc1f7796b5f878946c135bfa75a98db1b57
+0f38c49770ae23986ffaedbf6644df58a252c29ac821f4584b96b5ddafa9b3a1
+aa0ef6d17fc1e75916753bc8c799497e1279ec783ea86df307cd54b58c2b3ebb
+fd722006d127834b089670e5f1e7ba8bc4a0f6181bb4efbb8f99e4475181449f
+2fcb255da4233f7ab097ef0108ba3fc12cda0618870eacb9fe4195dfab182242
+bae0956d09e388d10da2f940186e25c9926886e9806c70105dc75259fb1e5da2
+675e4e114f84862e6b822a10a9d364b1cd13dca3d385b83499c715ecd7598766
+b215910f002358d592fc36d0bd482ee9cc338378ea1566839526a5783f250818
+078b97d73b1d62a1aad3d5a9753bfef23f7b3e6d5bd318c463aa04490b9063a0
+e83e3e68109b182720d2b1c13b498f8f495661c0f4e6455b96a6a92ff806f1cb
+3b1c6eac82d9a687b83c572c42df22beae31d1239719186f14ef637fe4e7c7b1
+fe8f4f1bd8367d76d467be95c394a818198d922bcaeeee371fe17e396b27cec5
+f0554778587fc7d78acdf317a8efdfc82c2f57b6411b3ab68f96e3e7cd321a6d
+4783435056ab5a0095726435be6885bf2784fb2cbeffc0f8248dcd594d34b21c
+98e67de50b6876c3d6d4d4ca7ce0b9013ebe754b104dcfc0719a10cdd9985e19
+2cdf4e88876c2dd4e79e23afa70ab5b4758af32ee87b8415b881ac15c5c3e1bc
+d17a5b961efb3a8dc987deded6f28a240d66f004ad05ce1c551e29b45668db2b
+305c9b1af5cd5388a0802d80f18e0f4bc8065baf393ffab9a4d674312c2033d2
+7c78b5e9461fb09b9b2caaab70ceb3afa574c89bc620328211c85656f63a8ddd
+97c827297327b7980c2fe0acb1c34866aa3c5d7408e257eba3c53de8338bdf96
+cb7ba55fe31bddbf7807148c0a132bdbbe8a2c21a23e11889da13e429914f7f5
+7132936359a0cc65e5993caf52902f76f75d6cb46dd20a3c0be80d45f2c746bf
+236733462080fbdc8c5c1dbe9781f45aba74af8033a6ef2bdb16f7b0930d6b6e
+7ca7fac8cfb2dfab8c063d961077585d24e8fbb5e0b0bee9c4509b23361dd06a
+dd25767833b9a770780b311f608cae7adde000297a2672211f0de8cf7f5fbc62
+78faba25d035fe3a7cc3a4743c0efe1c4a5e9cadf1e05bc7982648d5c9fb2992
+4a9ee1570ba2ab068cce168552299361d62a2bc2c0da48ee94d1cedf1e2d29bb
+43864ab5b770a14c98a432ab76c17998904f052a50ef845100533ba5cfb24c84
+da53581ec4f2201ca9fdae76ef365515188ace4cfc939ad6d193413ca7ee225b
+0137f4637f09952213be725cc7aec579b2fe85f7c6af18d70c4fda0557567e64
+d430f09aca7bf28984977ba0f5849a5a86729d5640bbe4c30b17ab03262a02bd
+8ee077ead7fdaefd37af16007d83714aca07fcf882adc4792583aabb279579df
+6741f637cdf8598fb5827528771444b0aa82dd5e00e70edefa7405a1d8a7797b
+ef021a53ba68c7ff6780c94f1393d1745ab1fd7c728c6112766a3c2e21dff002
+9e45a5c5668f8b084f22cd6a6cfb056cf0f402a73b2c02118259352eff6d680b
+877ce3024c37d532c186f3d4a97603704cc0ddb25cac00aeb4cf601f6fb45655
+8939ab962cb9e16a2400938d226056535ebe5707cf0a8678b54e6e3a103b2eff
+0bb7306d7c7c3f523b2aec267a5f1e3f99208d8ec9ab27d658c26f635c2984ab
+5a4d214768c6dc775bcc616838159aa10d5bd93cfc8b2d836eae5ed480fb6ddb
+24253a62a1b798bfa51b068b6888b76d2233b6fb11794f166254cb3ac8cfb650
+429866dbeb8d09e6d03889899a4e8bfc9a855ea4660f928d0aae8247eec1668c
+8e798398d53e52a5684caa59c47cb38c8f1009a8aa12a269a587593874c2dc78
+0ba989078910f3d70211147751e9f7264d6e64f1b05410ed3427bb7d0704443e
+f2baeb0fb9e3f1c1c14b178e716feb4644240447a3f02211350e36e1a586a042
+9ab336c6b44c0d2977294e704e8695b6daf079bca033b6bd3485eb7a78582fb9
+373716136c63eadbab3a2577738f553f81135829f9118f4bfe20cd51190bd7c5
+17035ebe97f26b0b58973ea9b5e0d111d9eacf2fa54b223c4f40c139ab891a41
+c7d5ba5338bfd58090ea727c3fd9d0c0217c05798787881d07cefe019518ccdd
+a7ad72305f06a98717cda80c5daaafc50e3c6d78d2b5d851beec46731a6c29ed
+ddcb9089de5cc2ddb696d3b7de3b67f066527ae22cc1ae6285dd1ad42e0809ee
+65812268d28e7105859262e9368a3aa7fd0207d47de5ea5591927f5e568386d3
+a61fcbe872945a272c75384be1e85b26aa094704715f1957de37a2fde2577ba3
+85000d0708fc918d52360cda828cedd17cb7d625155ceb6931a29025b44ec8fc
+3678fa08027b20fb9649d07f01484f2fd2e1746f290e32434fcd4d15acf0708b
+ee3fe9948d3ae141749b47810558d71d592735c1c86ee375be7413b2cf462660
+0b115cd043ede5612ab895cee0909da8d165408cd5c4c34114ee4d7fab4c37b6
+a31cb829c4bab2dd04b1a7097dec24c6429c13482667116522f94edc99de551c
+a693362be4d277e12829bc466e13d09841b5d9af504be4ea59e9c2459eea5ac2
+c678e3fa30cdfc5ab855d56c1ad8374f9769a6b575a1dee5aaaab4f716dcebe0
+0fab8b0b5522294ce3164f8446679fcc7aff5bf49062cea58f5c661a895ae753
+8891536066f8416ff5e357fc34cc34d6b68abe2fb2c540a7123bbf90d2671f65
+90515b96cdd1bd2c1396bc15503caa4ccd3ce28e0361801bdc5da98887b2c39d
+b84a0a4de7859c7da394acc497641ece12ad8a7d62ac5f8e6bda0577fe64d581
+35390a37a1570cb25b23b747b236f3f2606a3ff6e487a78069a068e7af13a8e9
+315016ebb2552f644065408a69f1bb6fed50486b2a05d403cd56ec5d3671c9ce
+091995d384491b65eeaf33078529238342c32a4b81788c31e62ba0614bafcf9c
+3c1cd422c605740a8939487e26bb9233d4cde68afe7a0cadc3aecd739c9c425d
+09cb50b4b4be28115ba7fc59b541513cd6fd08039cf40a1f5b90a8bd1263806f
+ec35aaa4100ecc05416ece2f061cfdbc321cf3324f1eda91976cabb8d2d9acc9
+b93c575c363fa691e18215311431841de8187a20d6664348c7a8adb06e867d02
+07bd48fe8067168c4412fc80cdba62f8b9209f5407670a26db1f7f5d67c4d227
+90bcd0f1e8640e5f9288c410487290808b88f9421d506386ac95cd959fd1ed07
+778de2f62958ff409d37332aa4ba88c735f2a56e4e746ee98b9667072874b21a
+5f98225aeecabf5cc818f3fa54edde178b40a1b1d6e2f900365e2b503346b213
+ddb43a269c5a973d303dbf615ac3caabfc39fe2144681e7cd633056bc77d95a9
+16f54291575aff7a3a4c13eca61a8d261b3a74307aac38b50c0e55222626e717
+db6e122547b3b8a766fb877deeea52ece2e74ba02ca7676f0e037cffaf287340
+c19bbfd9378d8e898225eda3fbf814ad51f976241a7285dbcc62610fe998ebc9
+7dc5961af9d70a6786e8922e7932a539f1606101440c6855f2284eb34a895cae
+44637b6a0b1c6386c21f11f2e7ee2adf012ea6ff35314981226505bd4b0ea25d
+371be9fb6fc0425d8f374cc51fcb15600ff7a49a4104bc29a369c8336438bd4a
+45b7c8fd52577a49acdb394cbbc16c844ad99f85b5af1e8018900d50862d7c7b
+045ee4bf7972eb05aa5696a004f3ec9be95c4c14180c7c8098a3a0443c0dfaad
+91e9c3a37509b29066af112db77107b9daf2e45e72dcd78660d5d56018cdf1e4
+ca787593c31a2d6ef925e37e4ee77e687e149bf506664975ccbf5fdc20b5c306
+984208ffb9ec2f79e76a7a029cf5981fd2d07176083d7fa0d9fa7b1e6c6da9fe
+423bf29011478ba39fbdc7e77ba230ee7b89728c9312602dda359f1ee65ba362
+d1f36657943255d62f0c84fe8a630204a8e64d8f940e9ddaf3c2ddc16fd131c7
+f302a2f9fb65ecccad4616977b2ec724fc6a4c39417962e0de1dcfa69aec8a02
+07179266935b655d20af3d45228ac3796fd2b7b6e0580904a27fe0c8023f4fa0
+fd70e469e5f309690c6ab737e9e0dd1db57fb312362b64ff1955401395b42086
+07e7f9449a8953149f324b4d5785c2a0a4c28eb487fd0bfd65462a1a4a741be1
+b1876330912edefcace1dfacea7628d16a4716d3989e1b31830cbc2bf9fce144
+9f0e80bdcbcfcf477a2c30a72ec227b20a0af16fcb8356bc205f18c6088c1d6d
+c579f1dcd23ffa147d72821b7a63fc011d5718fed41b16ea1d83ecd8d2ade289
+54eaa105f82f777b6635c160d0e3d67fbff2080db2a99d489a070d865c39ac9d
+2a88ab5fbce010919edc0ab213a09038fac6d3c81a4972e3c5683f49480fa5fe
+b8cd3279398028dab63ef7e8e1df85a63f93273f187f8f8619c14ab824c97c3c
+70d06fbc0a1b4be1b2b7f11ef469adef71617b304b51c462ab3c6c0e831c9ad3
+cb80c5e0d0fafd079d7f4f245d542ea892c6fe3c3d6d1ac2c92371b7a33aab5a
+ab8375b4cae9661c9d314999093b2a04ea1cb671c9f07ecefba615e023cb0f72
+b6eed231ad31b1f4d03e807e56c1e1663986eed65e3ee47a2dd11c1211236973
+4b4607a6570f534debc72ac06dbb2149f9efb793a917b3b604271fb764fab871
+f7aa5a5fcc54533951454fe7afa29cddef96e951aaa9b8eeb3f9b418bd132974
+c601b6fa29471dc34814fc81a1e1a5155951c12022aadce5826302220b18dfc3
+d30b2277d08e7cc7a87bf1b8ec4507b43cefb117119d86de3be51bf870390ea3
+d8daa3f74ccd3712d1c00261e853dc3078dd411189872a50d85d58cee8fffb1f
+0288029490412f3e58f83dada08fa695b18efd0a4f289705385a411fcb2d7a47
+ffe38977fce18188c0043c448d27e160ee752be0d44d0f83b6bf642c694aa530
+e223aefa3fdb17ee7aeaba75b9a86d7cb0f50ad4d5ce68d4ed48cb0c188f9dc4
+34548b48403078f63079bce8529f910ab280ebcae7df9f824dca756f9d647dc4
+d42da412230a6231307e7495424f98c9f129cc4a326a3dd8e476e18d666f94fe
+53edc87e47f6d84abb643ff3b4084437da26b4a298f819f4b6823eddac11bc85
+b9f5c5d0aa1e7b0ddca82c8e01944b3ea48978c1b8f4ff47779a5523f600d33b
+896b659c31f4f6f7decbae0fe1f83dde18f77f53db140a36b0f6f4b883ebcbb2
+b6d353bf2ca6102173b6dfba0f452d011f6cf7d661a470c3c5dd189c1e83fc4b
+9372ed67ef4ed9a5b98f85c8d73d490133b7362ab976a385cec705a2eb89d7f3
+2fbd60c08b86a30219aa2988f79e6386062be839c1f9d30affde82cade3494ee
+13041755e76cc07ccb3a4a701461290b5b79728eddfc63b2ed5cd4bbe0c4c365
+75488d590258ce2084f898d7c58b3f65b09dea2f8d4f71e80b2a2f8f31d5fcef
+7a7744b64d7baa701e473b85c65814b0a93e3ffbd7b2af85e00ffbfab9bb7766
+f444709a47902c919bd2a4becdce07b64053aea1058e26024b46153d6bb92c0b
+59861b2ddaf3d38dbea5bfedcc49938eb98188a3c4dceefa1f308559f7712ccf
+288219c6a3d4eefb81a2c5f154990fd8f09713a0531017d74b47e1f97aa6f0f3
+92ce5bb7475c676247d57bb14ff676f11a4b5b564ac26bfa9d85c9cb0414fafb
+c35b46eacf74dd964fbddab28fd7bb304b9bf4e12cd15b3bbb163dd66e89f24e
+6485c6ea63365d29907f6ba96d313f9b2ab7d175d549f4235653ef979a5c63cb
+6ee50cc333387a0ed88d30d9fd2197d31a0894ed0a47b15d92dca463a8c84b3a
+986d396e6530b2e9ba127bb5662ca948a8f0c563b9c868644b8d01064db6aa72
+090dda0521e6d778192a8c6d4d4639e80e309194cb76fc5d4615f396dd85b06f
+71dfc7f39a259e322c5e7d28646310eac92e5f6afdd6071b21e6664e1cdd3848
+c864ce0e380fdc48b251d52b5094ead64d380b6818e2c8b1a4eb8f9c18adde6d
+6e4ce1def2ae8f2649f1e5aaa05720a358a74e181568a10b536f68b7a0292787
+12c34acfa5bbafc4aa3eaa4d8ebb26e20bb00d228b4eac4a163e0b72899874a3
+f85e82c396d9e2891d8e0d6e5571d4ef116879cd2f5485dde4b9d40f638a3a95
+de5ddd14adbe72f5bbadf0d9950a195f64fd3209c6d47b46b7708f855da96cb5
+e9e1260f6699d945a611a7ea348db3c86be4b32fc2687f15c4c86957018d428d
+f6244a1fb6a99122bf89d7add01c80f2b2bb2c7168b02c400bfc98d65394948d
+c736741f9e0244fe096571f087c5d6d7d022c726a4cecf37cf2ddeb1e9d77098
+60c5d43121bc2e4b72a2d895a5ad2f449196aefe8c01784323de3804363b88c9
+1c86124f431e6dd0744c3d073fff4bbc2b98bdef713bdefc2da4e0e22eda76d0
+34424ce13529bc04c078dfbf8b3efd96cf662c4e151f15d4f8ea52641689d4a0
+5f7c9ec4efa5119db9e3a61e4a669c29348a1e71382c093499cd35d7d1227a5f
+5bc3db96823c167100074c70040a55142148196567c20c7eecbb25ed6e31f563
+9add24d52aceea4b88114eb6dba9461c2e5262fb9529e9f6f0bde20d3e209a8f
+0c9fd81b99b00d268f764593baa894f7ae50634766c922f751ed183aacaec03d
+b7d96d012cd0d111904245be9537edb0f8769ad1a8abbd8d1cbbe5e79c53c00d
+983c69d8865e93b6495a2f15ad9ab1da7503bd5b85ebe27aba01f71e56482be9
+d4342ac2562d8e6d1e4146447561ef5068d17306d66a52fa41644897a9b161c8
+5dd4161aa3d956e7961aa8020467e76a833e01c974e32aa2b8cf27d62fc81ee4
+d74649bf9530306481f430a539a95dcc2502f712947f6a68dda00589ef404132
+1dbc8b94afd827bbd5f77820353fddec5d98fdd256e858581054789781ab090a
+816e65ad3dc4a68b4ef2356e7cd2f906a859dad680d649457bae159f91805d52
+fb6dcfa5d0ac6373fa8325a817563bc9ed89a17d8cdee9b7516f38908e426f05
+1517eec7941cbadb22390e3e2e17d62ca67f37d01377c5a1e09bef5b795b4446
+54b383193351e05ed8bbd8b0b138cf62a428c78744582eec90a41c3bd44a4e73
+c9b32ea4936c211269ba5f883d45b16681f8afa0646a4031ef69cf4936305336
+5758f50534e6974342f4d232b5024dba0eb297e3aa3e9ef0935bd47998370420
+ead844c7e336288356715ceb8cb8492ecdc8fd8f1183360fa32850051442f4d7
+c0250d658c633de21048f4676a1875df6a8a61f0fc7c25dd5acd0220798ca70e
+f09a72b19595172afb9085b9a5971ad1b9a3a2508884a3bce88c984f58389620
+95584866c59f89120c7f491cde35b9d179f11db0d3c30370138852050cf14b18
+c06dadc218335bb465dd88304f1c1cd11062ca72649491fdc62d571c082cc816
+261444906d399760159f6b1e6df4b42a7a84750aa61c034b11a6e7eddcdeb54d
+e1f5151042a8e9f6a23a81a235fbc3908a85a6b05d8162bbdf3a672715b6fcce
+554e98df1f4583e03e456469890f07f83bc0a8954fc5edc7898f21f6917d30fa
+36faee98f622ef313cc8431931d83d271cef880dba07b832a01384994e964233
+f2e29de305c3863191f877dfba44214da68bdbfbde1e3b8b9659d7800df5bd19
+28bb1425a51abc317efdda09d29e04ec8b17bd3b78085595120b58fb421916c6
+af4b92776ef8a8211cc376a37566422bf2e2a840be57a357ab9b9adaa20600d5
+c49f228d2f7bb606fcfa867342884fcd426a72ca4c5d09612bbe26a2d9d3c8fe
+15a55e095b6705f2a2f2a00c9f1cbae16b91e13798b96d5ae66b5a8d1cd751cc
+9747bd951a55ec3fcc11f58f8afb40913166ab60a01b697507fe0753d085e5a8
+8153cfcbb70e29b7073ab33f7be2b6bd070ed974d0cfe4d41f7f57f05cef38c4
+251aa826e4a1d37459212c1b411b6b51faa564da0ff48ee6402b3c9fb77d502f
+61feeb32602da2b5fa880c537f60e1394571392c3fba4d110ff47a42d923c153
+f7a83bc1ffe67cd11ff1a763950f2d7b6d9575f45562c3a9de6d4ebf59482d7a
+716f39eca97fd68be71aa73987d570ce2ddf953c6ec97cbb76b147ceb8973564
+7ee159434e3af6588f47ff9722b7e90f4d9fd0c5b9e9f3a14f9bfba60ca6556b
+0473dc073a961731d322161500e15ada373d503552c0b76fc6576088e630cf29
+b9b0c82cb348259edd482520a84965a53cd673138aa57c32e41fcf50fe24a447
+4ed23401f43f5206de7fb3b6d1750223115919d85b54eae8298a19212e5c66e0
+c05c6dd7d7f8dd877123205b7e391a189e11fc30fdc6532fca87770985b357a4
+fbf9c5d261a4c998e2fe8eb96e27dac9daf1d3f0ec7422a85d9c7b241857209c
+f372c03c1100d8ebf3ce4ab3c0efc1f979c5999bac6d4abb6abab1d059c53f7e
+34f972f56df329bdb8485e39cc98cbf20ccb70a2a3cfdad4deb3267578b02f0b
+0340f42bac749465951198d2ea2bf7995852a50b5876597e55e1a1977b9e2f0b
+8a8fb0f03839dcf6bd5542827208d443ed4b9c0145e4522274a02e4420f738e7
+962c6d9fee17520ecf6d6772e5e77d6ed395304699dd65d7a610d793e38ce3dc
+e461843d5af1e27bed5652bb84d5e85622b48bec72e1622ab11506ade702cb2e
+8ca3ffb8add5c2470207bed74f2b34faf8cb61dd5e0bf54f2b8e1c7ea1fee81e
+0e0a16747443630b04990ee1be9db5764a580222b27332072e74a60ab7b789da
+aee741eb538e3ac7e38b333c7f6dadcad5b9383ab433359862dcb30ba53a413b
+5e9947eb637e78eedc4b8b17cec6b82f4cb8d2d71a37921e69d428723823ec95
+0f683a6bfb55d22dfb161e1d6b6db49dacece6e43ad2c51a70e6342a85169fde
+f8060d7da7e20b4db176bb862c29749077d7104bcb313e5c886a01cb16f11f62
+984c5f853516c1419df929d29eaf4490a3aebd24358eac006a594afcb839778f
+d0925e2daabe74c7ddcce9a4f454633b52b445fea99105fb0699485956fc737f
+25625d53dcf0b9e2386bbf0900e0e011e8adfe162d5876a850a6507512690d2d
+d1f00992f4dbbca2c63cd70b16dce15d1c128b9d6881f3f7ffeb68d7174ae769
+3b6f5e02523c7f046de294e18255b689d2ef529e6dfe489956afc909284a4d43
+b0ca1d9f8b9be4e4da535522cd9b6e64841c81138ee358ef6768e7f78af8033a
+6885457da6ba42cb4bdd4f35233b8e5ac02b7d8fbf2092bb8ce890decb6e99ca
+152d2aa56c5ab4179ba7936c74dd6c342a392131fb96c14c3b24d9f0e4d8b1cb
+862ea5e7b13e204c914bf95f55ff32e4308fe5b2949fa454560e8dec474ef52b
+65bbbed017d5eaed0d89a3c86fc63bf01d3a6a10a5fe389b1af013ebcbff2a17
+7f6e854dfec5dbf19d4e977a07a42287a2dbd42a78e589a002cca47eb865bd5e
+601a98bb3a8572f20ef1c0a2b3500f615b1b8f9b04215f91acec454312ec1dce
+08f413b9e2ddddcfd2bd85125dc5a043a45c0b9d3c86ac30b21f34cae2d347a1
+e93586eb95fdd3d1db7157b21b7ed1702d31876a1cfce58d619a66df8ccc3116
+319854a57965fe23d2d2d7e02f4d95d810e8a13d29872274fa6f48b7333b743c
+7af418c1fdaf467acd5483a47c5e99a7bd81e18ef98763ecc08820176a109145
+af183870faf171a3c24f603654896e2d1b0ac6224cfc765bf747e194cd18c740
+6c61fd10b6b7dce9c0a6577a87ae840e88f99cbf1c1d6cc83623d2fe80bd710c
+ec79256f89f26b45f75281d3de9636a134f63e244df4a623c63a895fe66e1464
+1959655f235bd056d65e3a50f55a041447594422eeffacce6af7cc9768f72158
+18ed408e47358ad45fce20e4848cc38f70943755e9233ac711e663f2c7d77b46
+c878e70669ad30ed18b6f832e4d7f54a23c837ed440ae97883348a0b5fe95232
+779187e429b6f855ed7cffccc8d6784d8bcd92548e3257ac87231c36f119ddfb
+f28ab8dc8b253a1fa09f016887fc29b6659b40bf3dd9db6ead8c8c3e504b10f8
+37dac82a816e06722397867df32fa25da0713e92ede9e4d41577ef58ac70b402
+a4427a7c86f7c1d7f378b62db43ca4bc3a8669f6e924d719f18799d1a9e5969d
+76bde4fc976074f2d623721d38e3f5c73428d6824049dea9416a450be02dcb55
+908e37faf4a56a36519311ddb3d1cb66837c2964a2dd0d34a23dde43eb30c88d
+b6ea541956b904db911d009f0b209bfdc139f48878c811ec38a21692f9b866c0
+a59d9d736d429de0db4b0526463d0348157019a262b2c3e0bf54095d06110593
+3646fcd24134d6b3a2a906a891187692967e93f69a54ff3ab8050418585ed1f5
+9822b134f8841589fe146d05ab00c8e22651c43723216c053851a5d1f9bdfaf8
+59c55523acf1e394d27500a1cdd551c773c9a6d7b3882f31f29c281fb6c6250d
+8a1c3c8dd110c1910014da6fd1d57b8ae102b261fb65a3019bd75e81ccebde3f
+3e23764e9a5dbe640ca98585da2a4af9de5a5045598a905ee7b82bbaabdd0d92
+bb5351d3a0b3071e8666fce45202af6000790c1c1d0a5bf0c4623b9815b8d3b7
+7c39970a509db6a4a0fface38a60e2dccab7f5b7ad1c0f42a74da16147589a2d
+3dadde9bb1a63a4047ea20dde1109f8856bb81184f4256994b5005d654e49086
+7bb8396fc8d807ebdefbb74e9894bf0ec793699f0e68263885581a17c87d7082
+371d3d4884b50e1295c517fc56b91ebb6b4c23b150d542cd0768924232a5ac00
+8a98f5ce9adc8dd3e65f085b35640919767237d0f9703cbd691a987a0aa0444a
+5ea0d887837482a7248865cd78b6f665301cb67cceb1f689198821227c1acd81
+3d0a50674832bd33b2672756d5186c89528180e190d1525c3e806caddc1e4157
+46055910cee4f60f40b1065f435be8a39eb454d88f5bc45ba818e5b006e5a38d
+29974f68ee1962448f7a9fd83c7f107c7788eb8975dedee759a2bbca40c811b9
+d857cf8e510376d48abd60567f307d6ec471f99b03cc7b5e8140dc0450af3832
+242a353515b5b347774f32b8b6c033adc43b2bf7185480e47c868308f3906bee
+e44131b11b2b14e77f33686307842337cd1f9695491bbbdf271b5345c44d6a75
+58c59d6d5bf8b24af38248368644e331a88cf73d0eba9dfa6f80f11af0293bb8
+40d9755540afd18fb03e0b26b6432277434166123d80044808f6f1115ca55b87
+60f82520eb81166f8363b150bac7f45983d1f4ea0b503fa8d041261e2fd14caa
+c7db8e5b1bdb04a65cbb660526d8b21eeff68105486474803acc96e7b882bc9f
+5a1d5f1e333b2b2aacf4272a05a41aea04b2c18a82b1c66a40753a3690aef089
+b9fe83dd0d86fb7b7045f041b690928b7b2b67162a1f5564117652fa7899a444
+bccc231189c60ceb72abb4038d7d0ab5a027bea7ee75542416b12a16ee00900c
+db94b2c89b2345d209cd68307e101cd06dbb79e76c725dc7180becca0eab9f8c
+ae1714c57bee7e7f54c84e7a2ab9a2b1ddd4d160cb4825b69c1bf5ee26b18391
+acd6fab3f890d8cbff5ba3666b8d7853652da2bd5db79ad8de358e55a5e02270
+e1a2d09adfed75088a71593ff0f54d5c527518cc767584e4380b8fce58b04ca2
+05a69ee280da655169029a16a3df3b86fc4ab635300397767c7d9ec3b3fbd60a
+bbf51ad4a3cb348539fb9b7eb072ece9afb2b3c00e2b91bb40a82d2ddfa58e9d
+f40699038c9a7bf930a83996afe9580c5338405108ac04fd713bb22ca2024475
+f540fe14290ab1818d9bb19483aba2f39a958ea417ec73792233ab538cb70e0a
+455c6b7e0bc86eab1df73eec1e16a6f95cd23b8f695fd2b919dd282bd1129baa
+93fb68080d90c29776bf27fa42dc0721e380ecf88286484417664e41c5b257ca
+bd4835c1d64318507de5dc2f1060644b2b125f17aff1b95a37b9b667906d48c0
+9fa7d875d59cb6f7fef2e37ec418540f8f13c2d70cbe9566299dfb80c06df99e
+b045dd3baefd87b24316700fa1c9f72157b927052cda3fd2b480df750298d645
+7c412ca39f6325d66c77be38bd8e491d8f710c5f91f432e13f89056940029532
+db065329782579b79d9f6ba60552dbd6a302e628f75e0d3582d25eb03e7deb33
+54790b02521553eb0c286cb415cde225b5d65cb79db060d13afe862d5885b567
+2430481620475f50546ac782370e3ea1c95600a524d288b5d4028be7cfbea855
+528953e607721b7488f7d7f9dd5ad14332b32bbef72240036a3e1646fe5418a7
+1fd206ad3fc75b7dcd9813caf5d29ddbb12d7ff94e37bccd72ba1086dc431b5b
+713ed14ab7e9f1bff7dddfa9bf22624e4caf3cc0d4194f0b6a36b1c67e43f117
+4bb23054ed01209d28bc55224028648a4a3073d56835afa9e004fb999372f29a
+d76db663c2a29b5638567058904a4933be88e75ca1f365739a65c27bdc195e7e
+09cfb2426fa829ca3859306b556d1bfadb5d9493c66e34dd7f63583e4532a075
+532cee2d8976f785d7909093787e8aa5fc7912ca8fa89d346634ef71f98c9fa3
+cdfd931ccc699caa314c402ebcd6bbcfcd3ef7ede19e6c8b5ea9bbe73ae35b72
+e214974b2bbb26a115750327d20732b6f6795c25e4c0b1a63b5054383d428d2b
+85ac1f719ce35a18de6f4753cb615aec6212a272d89b3750863536fcf5f791db
+3b7b39a66ebbe9fb1876bb089ec2cba092d291aac88f09c720aac4dd8fdc22d6
+4367c4c5330d4e0ed7d454728af2b4801618edada4fa3e5357fb91458dc13288
+7650401bbca16d73bea8cd5127797f92c8b5314663e02cefabd1edd89e4486ba
+4d371138ea6a07ce358d31bc9ecae64f409546e9101fff7ec710b45f910510aa
+b51eb2374992009a28262a370d42109a0aa5ebbc16d2ec5d58e0a5e7e6f80a02
+5cf8a581f3bbf98752edf64feba585fbeb56b27a79384a22c868693c05084423
+f7cd396cb48e68f76bab6512f76da2772f3d137881ebaf1d3ca6e1c98d54732a
+fc24bfe29efcd703c489dd8dcc69da4b86b5650788bfeab8bf66c5c1df7697af
+ab33d0c14caf16b9810ea74c32ccb5bbac2613c6a3d946436ccf934a20b81cfe
+5e712765d1983bd77cc45612a31c893a5583238c944f91f2d6d1069386621108
+108b0e65b4f6d76bfd0e1158005e8ba53ab48e865e9f6d07835d4e9e124b01b6
+41baaa6cff413e7ef8eed73f1cccaef55a87d71afb309ba162d3e15dda6f04da
+2de8db583beabac1e5680df43bc063095de043b2ad4c8600ef63a8090b64785e
+5288892b63a87d8c805d1000b6524109a41e05e517e07f0a76466125650b3d97
+008057de3d3380b0c352e70ac04fcc21108e619a707fbf7f59869cc9a2d571c9
+f77114250c1c41dcd527323edb2fb883dabf371dccf42389a260fbf53464bd24
+d5ae5be48163f142733b205e110d77de5cc07117d7d6d347cc8b035fa387b249
+fde3beeeac843c89bbb871114f5313437a784c051e021da4f80adb2d5e392f0e
+46068df67f46afeca052378d97597f21c39db6a2ca7c10c57421499da8d5bdec
+128109432f86a0ce63ca2be7fd64e29e8392bdd0013d4990884f7cf49e7b88ad
+846af39a3aa1ec3c85f21db07952d1b45cfc20d6848536b63d2572f44ff718ad
+c2cfacaf395cc64b34290bf19a19d756b38142c6a7471ab436c6b81abed86fbf
+8553dd8d5a052f4d53d6124ea4ddf235f4a792f8aa485fb068d39c682eda37c3
+2fcc58da51f74c24bac8db5cf825407f88daba78f41d8ba078fceb0236c2deff
+e61cc0abbdbec3bfa099b49cd1218dbff85cc705730ea545cdff4421ee5a5355
+9ccea2cf6257b757e4c6b853a476f0c97ece80a41fee4994b05eec575f87bba6
+9066eceb28ac92e1f4483f8744ede06a05ea038565096458785453b2462d103f
+300aff3783f7a2ee1a27cb223e7145b6b74fb5a95a5445b5800d0b7e4451be83
+8a7679e3a29c9bd79be0ce900f8cede4f5fbfcf46b6354268087bb020914f246
+fe06d18cc7e9cb1003bc96fb5961043d919c9298e61dc5c7cb39886e65939fc9
+037e0484b62d1ee35842b3ddb879a7fe175f07451c4456361bb646e5dd87ad6d
+ded8388fa78806f8c993bf16f539a4526503d8baf83d1f0a594db7fb1a11e7da
+d2f9db98c5d8206ea4a44ed134d784b05ac0ca245b2a5adbd93efa4a566e93c4
+84fac7ef0ad46254101b308dc4e39c549942af85c96a5dd31e5d9a99149f49ff
+99cfc5783d2cf9c320640a5029bbd61c86d4a6ae9fee690c5ac5e92d6b07aea0
+31c6110df41e63bd7039d6ba8ea9ef33beb3cdb415f4497245606963da60194a
+8383663ba3f3be2d6e0b4865ddddb484f625beb57eadfc694125ee35480efadd
+70248037bf40187f54cb53a51fd0a916d0b1a54311f43cb39856b5e4e17ddf0e
+54466ad34cdbed8fee17c87f00bfe4832eea2acaf9e93aa5091b62febfba9b01
+5960618d7135ad546cf4d00c8c725c6da697406891b75361c81cfc2d13a03836
+8f2bc045495a1d24628606990f351b6f6f197ec7b52169495bc0047335c4a3d6
+1a7aaa63fba1aca730ba1fa90ca04a0fab27b145b2dd0b4c03f01c79bb77758b
+fa630d02a5200c48499964fdac705d1f6b0aaddc58b47a35077f5ee2fbcab957
+919e5bf614a1468207592bfc36bdd62ea9389142350d0835243f485c99a49ee0
+b6fce33e9f1ca586f704d27c59621206abe70ac31608ca67a512dd60f07510cc
+e0ab7715f3a662f824a011ec47e60f84664e474a255712aad0bbb1c7c1488a49
+0a75447e9feaba451fcd1106d7da535ad82757494620a195b2f0b1622c62351d
+89b62f4f9bb812fed256952928d864147176ff0e03bdd2ba75977cbd0b5ec371
+4478c47d97601280566d937243a0c8b0b33450773897ed5535bea6d7eafd5413
+5c4a4976ee0153f4eb913aed8a1497b743e5e1ace625936b3da74119b49bb536
+1a6fefc0eb959394bd745cea919b1e62c8cac77754c59b725a26c606a7c5b3c1
+45fa3e24e5fd96e230497a0178f21cdd53c733a6bf29605879f61cd4b7ad1117
+1412b03ef42e4f8261df1544138958b3e96ac45e3a45c1bbd0a6d3f1fc4df057
+d0013bd3dea861453e54eb4721124ee277fa0eed1bdb6ca37e30dff04e91b88f
+308edd43cb7dd7e9722e57dcc7f3633209505409a1f98a133874895e00b32c01
+85baefdb0b4e97f75488ea0f76424d9196a2437fc9f67fe2933ff34232768eac
+722a84a7fc52fdf3ad248c69fd7d4c45fc33ffc6a04b562ce367d96b03c0ff8d
+75174dbdc09bdb35a9f4840a6adc555f42d20bf5e2d3da34a991f63648ebe86f
+3e155514afb82c1b3e37fcdcf8c594acf65fdfcf5965f42cb35543ffb1a1e40f
+622e6ed20b4979a37835cf08e40b8bcb015db8eb1a044dced8f6bf6360d0fa20
+e656d90efbf461da451852f58439db9281f60edf5de4af016f8715eee83eb666
+d48784d39764e33008e5d9195ef62439f3af1b989bd952fe0a0d30a85708bb1b
+a353efd6594a3ca201115b3659dc1a80619f155c6649f944dfa3e543971f8dd2
+b0a30afe77658ab82e630bcd4fcc33af8810da1360730055255aacc77fbe09dd
+9b13d44a41e0a1d3789d94bd78494a33ae60b9ad7290e4d1ed6924820140e2a8
+ae5137fe7c2570af124263b99d11ece45cf80a6e11f56dc6d77e50fab50608fa
+09eb1520f22ec16571e92a193f1699f81e352bcd9e0c838a8c1d5bfe80d76957
+7129c9c46fda7235dcc34f604171a75f069f9e00adf56e84ab1f74f093bb6995
+743f9e027fc4d9e6bcd647b2ec7f0d7af2e2efd2dbbb68c83ceb1c760fa71ed5
+0394d38963fdcbf3891934a4cbdab80107778a63f1101017becd233ba0c2e602
+e9075c5e509f2ace7b7d5c346dfb58d0ba3e005e38ea7428dfd0100b7e1fddb2
+7fe8cca96b04f9b349693acba904d44e143e03e82d16158beb36dfa21f57a039
+d6bb9bdd1a787fb9df968004388f8655e9d8b6f435117836bc910697aa1737d0
+55c73fcf23f8b56b58b09195b7cbff574a2418b1ab9f74dc607066fcb798b880
+5fb0d761cd5cca51f9ff0d2e67cabdb026f2a9b292fa472b97ab89af60cba974
+71fdef1417b14e6ff5440867aced2ff9837c1cd1e1aea23bc3cf3444e35f7cb5
+97c2f8d5576ffeaa83e06a9e6383e9225ffe0db4b1575e1f87f28b373716b668
+4f3e9e694d6d56495d21673d165cfae5c6ca112d16a40247216da4debabb7e8d
+34fcb858707d82cb8868dcd8e956d1ddf8bbf6cd57c293f8e3427f14c99e910d
+a7bef26c09e31ca66550496574c0c8f70e7efc9f74bb45fb1ff13b31d8982b44
+038c1218b874ac95ab907d01bca78f00fdec53773064be453a82efa3ce336c46
+69345e172763413f021d75570ddb0a16c806e444d8b9895af997ee7425d2ae29
+1d57d9aa91a5d9e992a7275381ac332a2396900e4d821f69a349d48a5197f98f
+3534ab2a47926edacfc5281c09ea8ddff7ccbdec5b95857c9b2d82829376bec9
+79a6ed53c42f6be0c80a9fe6b90c06624a29adc0e268241e145b18dea609cf8e
+e79720d031691f5912c7b4c1fd4358a6ed07abe23973f5b296ea3e36d8081d64
+50835e84fe95a56764117785baf8b08ac40dcf7453f4c67100445ea6a77ab755
+e3b4882dd0a9d74332f72322d36ab9dbf2199028eb6c6d0f43e79065e0fa47a7
+68bfe8609fe6ad82e7a1fadbe827d86ab6f3db8d0650c31e80c7b5ae24c703da
+104ebb4cbf0d63b0248ac1c47a8ef14a095d902bb390c48760ba7da6fe56fb44
+df02ee166b522a550efab2006e814f4053d0f21f3ee790ca6d17e8ea5ae31083
+5889c2ca6b3fcd267131d33f3f71bbaa5d414479fd6c9e84ae481defa4eacf99
+93a6fe4ff57f5e09fb99b8fce71b958080971e61bf0ccbdd2a86448782aa9871
+0cb686013548fb3f691436501545d2ddb46a3424b643590da9b3069d76eefeda
+946b6ae4a531f7d8b3bf98ab35d37ca5b36729548c06d230b597ab2cfd12dd01
+7fd2398830db4b4f2dd298e945659a564470b22656e28a2defb63714b5dcec1a
+5cca4f9f3a07077c87c06bcc145edea8424d9f44ef8e73fa98fd216cf3fd8408
+52ec5988a7749f0d6923f6c0ef50e9b2a7a61c006316b49c51a0127004566d81
+066e7f1ed02f5f570cef07df070ee98d836ad6048fa77c8888dadea64b72d4ef
+1404634b59cb590e5113d384e43ddcea459dec60c3f1cbec10e33100bc7eb8bc
+7e339177105ad6a478ed9e096477601347e97c3916a3981920b16bf4d64d8fb8
+694341db499b9ca3cf34e140d7db4d6c5c291f100c2d419752e89ba7fac3e8f7
+5b4a63616197bcacae3e0170b7467670f67acd1acab2e0502f02f416b851a5cf
+6f83c3cd9992dc925b388cf75b423edf1d5d234a341adf12cff88bec1da95ad5
+dcff92b3cca7418cc86ab1f1969ea85824d243bc5cf4fafd8f426556dd9017ee
+0242046f909acaed3ff2a91564303d13c8df20ff52e25e60cb7168902daac679
+b794ef58e0ec9a5b5a97a1143b09157c97f9946d98077de28e8908b84f73a018
+e0c3bc6f4a6ee088edde6f1e0f568799d86765d843965381467a99c8b91632e5
+eed53fdeb8673bd6c9b3757773febbf86ee428d4b386985e810db8124f5bf974
+df99afad632f03e338642c9312787ac47a9d2f4a10fc5399b6ae9029a0336d89
+2aabb090e581b749473ff20815277881f985146a028f6dfb0acd19954a0bdbb8
+b4ed1a65d3b9866dac29c6aa8aed39d956433ba649f283aaea848f6cf8f96268
+cc669613981e4705d9220970608e67028de79d0b3668b4a3db70f61c9fc01078
+37ec51eab70d92a017d96cd8893eccbe23081dafeaf81ca2c9d45d38cf554c84
+99a6b479ebfbd96be8f7f4599b10dd45b4ac860ea6aa410f161df2b33c08586d
+87218a790509800164b41e3cd0a7d30d9584813c42fe3935ee56c6f22cde9fd4
+05615ab2abac9dfcac550140c4540d6dff9ed67f530570744d0be3e56041e1d8
+ceb5a6925b3bc52c206f6dd87f2c4de70ec19487d2ddaf20ef6b26fcd60631ba
+b1677d0ab695dd68b2a3b27a70b0b48fcc872991bd0b9688a966e72239b58d3b
+2e58862eb4db390e169100e539c238299449bda356a0968c866ba0e0bf3b88f7
+6cfd39fe10ae30eb6ca7149b41e412cf556969b4c816a1945c0878e2a79e7ece
+7e52754c8dfa755d79fb15e5576a8846307527460b6d9182154e23b84ea9d443
+7fcbb470e9833d2f3f90aa88d0e44b175a9358ad0d846ae6744c4b69a5e24692
+eb37b5b9678729be88cb9f84d2773ba99b29ad2056420328116840ccb475ab76
+27bc7efd2dbe6dcdf596e94c09aa959f2d43d48a80ce2faa7c30be324d18b8f8
+70f77be72199e931d5d5f3acf48ff8060e168b48d066b2354fea58713c1a5367
+330c9491fdb6fe9654a8fd66803fdb1990bcf5bf2d8665980d162f1be17663f6
+857563371b1056144cf54ad30f1fae5707f7bbe87fae41d2c683e8a02931de24
+29e66f35188ff3594f37f7ec5021e8ccf00248be459f80ef9a46d0344e153789
+69729194731a49135ae771aac663c0037db67200c9677bf1f39abbbc54802741
+23d36a35f128c1c35dfac1a29a9c1a488f6d7df23933488c858667bfe24948db
+86bd0087f94b0c6325a403de4a434bf767c137f248c85257a72e39b51351d401
+8b530913ea8be8bfbeb039233bc3432db0b61aa281a0ce2f01b0399b066fde7e
+abcafdd46c4d6bcf2924de2ed3972c01ae0213dc1553928895c2b541b1b254e7
+a1ae46069a110c55de12f66358815cfb07cf0de59865be85f1a8f2b61d0ebae2
+7d341bdc37eab342af148a05d0fa415b86cda706746c75e0fb71a610e455a64a
+d8515705ec8d265f3e4ed9c0203744c86a1fe55ff52b6c8f4ba71e0a26651cd5
+fc38d93b2370b1e38c29343c96dd9b3d4a39b78f7bc7f2eed735f46bb46f96b1
+becbcaa7cd99ef23d16bcb3f38a605dbb908b28b1039d2ea1fc5d7afc11f1aa3
+798b407ec236421ccca18fc1f27a12d7e0b253039827104461c51ccb2283c9e2
+6fcb819b656a1aaf1b29821bcecc50b911d1a05330c43a0c6025ec90dc134042
+77ad9424c2d2e642a1223dc74ff16f70b54c0ff578157f0c701279facaeb2563
+cb3855872d3933c0a7be7b633e7e3ef053e1213e4cd7e1c57804eccd8026e581
+beb4c2fc59cacb4c1e7696d165316d7f3391ede443873c7ac48277e47eebc64e
+3023d06ffccb05a1a71b64b7da4ce1b6256c4970b179c91e1b5d6ade81c151d4
+dc3cccff1d6ebd118285d56ff7631f2c7e2b89cd70b2ef7a3894366fd177c06a
+39e3971747f671898a0109008e3190b0aef909597ffe91d7c7c2069b5680298e
+eee7c04e58cd328c1bafac2a8bcb63f6d9a6a56f29f3551ce1d2512b5885d1b7
+8397e464b5f81f4803eebfc0cc632fb653f52fc7ebe2f64ab5ce16e840bd0577
+cdfa24a928e2888ef6171e43aedaf88616344cd64b3a2c0873dbbf8eb1fdc08c
+cd86f324775672bc550241d139bdeca9e6ee36d49fbb117eb5eb456d99258067
+94ba27cc50585d2544b2f1f16c19ba41b0cb308c4f50039a843e66b20e04db1e
+b0e99faa3556d8e95f4526f0a105d4b761df415148051c604077ce2025732152
+e6db72d810bb8d81c733ba78c0deb8799abaa20d3d77152b2dd109d70efb2bdd
+7f17c1b79bcecf6b30cf0f852ac61197e0f601d2602205bc37708fb4306a782b
+1f2a39bb03554a1d10100221f99ccb45b538bf2a94ddf8c4e0b10c62f4af712c
+a44387b0038bf2474dbd2242c735db0d79246d73a43137d535eee525502ee440
+9021ae2414e9f443740cdacdaabcfaa0084a60ac34303dd559269eb088e2925c
+632bdaae44dae0ae57f3080be448c56aa549b620d1729b6cc2974e571a5697b0
+4ff3e6f6542c4fcb2abc9261d97d6e6e60538d69b36c8189491a978a7d00b9b6
+3e62a1f51d6002e12d0604d53af0188e565ceec8ba572bfde122249dacc9d9d7
+75047c69ef0485adf9f0dcec0f0c926ab91b551ebd9b8f4aa03817c25ca92395
+518304be94b5d56bbdb833cee92c32b792c6a31f37448b319880e4cac35d2edf
+dff530d0f7773e5148d41ae56e02633781cb2abb15ec2d94ae52d3c8fcfd3097
+45d95f67b560165f57393a42fc7474b5284c7cc0b893f84f8733768264ffa8dd
+0bed83d99c035bd1a83597f0d614797c583ec8c5b96b9739f304edfe1e00ab42
+38f353a82e7c71d74877d8519add9b8c78f611174599512f11c22c10cb360307
+b262f1f78c7f9a85f1fd21e94d72abd413650ea6a69b057e021ada9787d06185
+c57c0947f9a2a81822054e855f802160649e25ddc82969d94c052c289f35bb57
+c77de5dfc63716c5b0a87bc7ed859663c457f080089e3d729b9bb1299050788a
+79ada19db21011b01a47b278615be5359e71ecec7c06a67c4943e6106e152824
+ccb1fd39c485e90efebb1b2192d93c8bc52e356e51e5fc805cd7e43543e9c500
+d0ac85b7230350f9f403340a16bbdbbc3bdf0f7a571aaec4d6fdbecb288c210f
+b7c244f1908305a0b1632a8123001175e36124b543ff92c16576d373b9bdece7
+67889128ffa3497ff846f8befaf5de3b7c339f049adc9116c9a7bb8bae435798
+08dca2d9c151d9329c345919930e8437054501bba38c2bd5102a20e4291203f6
+eece2f70bff3df08aeb8ddf1806e9657ee4a5e3fd5a8fd979d90d45734f14f71
+5d339ac91b7fa18a17be81583c08544a8a32729c17975014d629b139c0b3c236
+bc9a99231ffb339b7761a2586eac564be734ef37992cec6c06c2c93de2b340fb
+3a27a52dabe69d9178d9a544430cff229335edd6f817bc52c690917fbf322852
+d4a7a709a593704568cf142b45eff164d817880cc93782c223247c65fa99aca3
+5c66a26093f9ffbc25ca9b3cf6b8ba478695c68212e80e3868a0db1a1c84bcdc
+df05fe054733a1b794ed1cc483a57b97ca2e97fcb1ceb9cc2ae7d5e0e064cc8e
+01cc628180359749622ac1cfbb57d51b25974ecb15dc83f99dbfba2d779adaf9
+6a9307bf3faef5d2ba5135a15d13c4215570e772376a4a4a3a5ec4028ef11004
+b93acaf38128de94531c23f114fec41cb2e2027e8ee138aef6ad017f5d97a600
+1063be706b65da0eda2234e7e9a9c27c084c4564b362ffa93ec9127cbc9366ce
+7b74805943c9961be5a5b5ec87675b02f756af1b70074d03374ae931cff31757
+4145af416a9098bba84ed2d3ed44019257c0f34e7f94dbd10fd04fd15ffd1b64
+f65b2c02e581175436150a074de43f8e11fbc56e806486665cedbcf387504d6f
+0687a13d668c69dddbc37adf91ad0091a770ee23850ae2fcbd6b9de9d8a8c8b8
+eccde66b7122c7b9602dbd0f6b7f7e4890933451c7a3904382d7801bcd992f76
+4cd41d74bc8723eba2647db7f813b465d11052e0f4ef593049942915c614ede3
+4f8f2b77bedec635eb3461d66cbfd4be1689a839b1feaa41c0f0fa23669806bb
+52fea1fa5ab524a447ef3cfea4583a7790baa418ff8917388daadc5a3d1a9fcc
+7f4a826c912eba5d4b82d4c29b639d56532b37ee9aed6bf06137a3af899c70a1
+ce4c9940e6ea87b6e274696c4a15d6aa3c17f9334aa84fcf1edb48e306640e57
+892b25e67c6f87e4e4cdf1a9cf12f69c0028b5fb768e839e1b8f75f3ab2d9763
+6e1be8c5a73bfa8675853695ee32887dd6df5f03f88e637d45f752d22f6c76b3
+71b9a514078c3200ddd2e998f33f1ae5c0a5fdc932f7c4727512caec232a681f
+bbdec1a919bddaebf5efbd06869bcfe0637b72cefaac13f915f25cd3a926c0a5
+4875435ee6a413e2554fe4ecfcb96c1b5d8719e84dd34939dfd7795eedecbceb
+786df32b6360bffed553a74b444a35e0ab0517cf7aa9c4e420e5bea4a5aac950
+54cfb55d1a1e57b58b8fb382e8ea2acbfb9b43d1ab67e0c1450ed3091758c1b3
+8155fd6996500a55fa5d134f17e55978d930425e0c03748364c46d3bef68a390
+649e09e48c2fab92108eef8603c70a977a388d4d24971296aaabcb932bc96033
+f648a6ada265aca938a6512f456fdc194f7186808deb3c16769d3faa850f78fb
+58610c776c2ef3f208404def2940e484a801cdc45aeac88fa9852d1319159340
+3478b1b7f204ff297b67bddf1d38e256f864d3a83d6919ca7db1bbb1f5b8f6e7
+8ba272d1fb28d760618dac6f5633b9481645c9b8eb3a3384518103cc68aceb05
+5a91dd8def04b49d363b0c6daf63aef5d85b1e79504c23b3bb50a4b7194838d6
+b417b0ccbcd95a46834f9bbb2ac30fb2d9b9c31cf4b608e1379399a95f8dfa94
+53998a743c5a5bf33ed1e10177dc4a2a347f5fa4d09470cb5d71b07bf459c800
+0119a2164b143f03fce36c19384a01cec5b9080491b82b9ff115f795d969f480
+b7232d0375a9d46faff31fecc9351b42923e9ab6207d2723915d7843db279505
+280d70d9c80a1821a257aec764b7e85a1e8da7c40d42a0f77385ea66a7643435
+e20af708470f645046bbeac12d840fe3260ce75e20563014d9e2ebdaa57ef06c
+0ddb55fdf6ec3e064312d13e25299b153169788e8a4decc095eb37eaf8e8ce2c
+cd7174f44ee8f3875c5a3de3c7ce22296e99c44628f52cd3d18eb9215c34e563
+0ba85b5fcf3a211021a19945510c7e39ab56d977f74fd50ba8a70def82fa6777
+6930390700b4636330a998b535126d610e8a1cb63f618d69896fb47576857f5f
+8926ddb4833966695a26402aecc48bbcadc04c2833afcedeee14254a9e77603a
+5bb7b9de3c97007901143a7901c00b77a13e72940a6507a76164989e71d91eb2
+3080c585be2f8734909fa1efa7fc6a2464d95e4c5051fb8d6065a7d9a453cbdd
+033626544b72108e4c4c087b4e4dd972893371ba7b8e8291ea4f98d03c61ce6d
+d56734f17a66697f2260af9b3f8b9a36717b490e1ce649d839a66133da7742d2
+dbcaa22ff915fcadffa0383cf34c2290fa42fe23128e29e7bb1c59e55b7ac347
+fe66481f485d7bd09f55cb51d208d0765a510d5f6958fcd3ff5a5ed27d06a02a
+f7ecadce4b4ac5f1d0210c5637f07382193d77945e249d2c4973aa43dea41dc0
+51cd72643bda4f749dd5846a9d3a7346d39f78eaad738d2d255df0f0cab5fb10
+96a0ac86bb013980dedfc84ddfef081700fc3c66b6d5a125c9e83df17d92658c
+10d79a8aaa222004c20aaae6128132c64f96a7a7c869489a63860c15d53f958b
+d6fb81cd165bf253d996c15295f7c2fc52c13b51aded1c774cb35a0ab258bca3
+ab438786ff7e648f42ab568fdd9cd598c52b5748b0c44458d4e0b8080ad19cbc
+55d8aa1a78cafed7bd41a864488d8ab0bc12f6689027c65c70a2b26bd2590026
+3e80ba6189672adfe377e9fb516cc6bbb0f2e341dc9e2f34a8bb00b4079ea28f
+7c8138c415306e00bdd8e71176faf06fac92e38e8e15dc6ec6cdb389d1a15310
+ca67408a9686f21bf6fbbfa7ce032974e2b860a3a72561508bcf22ede4122185
+b83532444134af2bac5ced1932c9cc06b70160d0cefc8f76ed1108b629e81060
+ce6c30e0bc9ac232fef7ab1c99e21792921bddc20f2afd3b083dba29641458a1
+1ba80613610b01543d336ebc45ae15c276c9ff18fecdc0cde3be18e044497217
+b9a812d926538fc42871f439282c1717833170bdbffbd7e2034d794eee9177ed
+28045b2dc45959426e35d30fde
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndResource
+/F130_0 /VXAMRV+NimbusRomNo9L-Regu 1 1
+[ /.notdef/dotaccent/fi/fl/fraction/hungarumlaut/Lslash/lslash
+ /ogonek/ring/.notdef/breve/minus/.notdef/Zcaron/zcaron
+ /caron/dotlessi/dotlessj/ff/ffi/ffl/notequal/infinity
+ /lessequal/greaterequal/partialdiff/summation/product/pi/grave/quotesingle
+ /space/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright
+ /parenleft/parenright/asterisk/plus/comma/hyphen/period/slash
+ /zero/one/two/three/four/five/six/seven
+ /eight/nine/colon/semicolon/less/equal/greater/question
+ /at/A/B/C/D/E/F/G
+ /H/I/J/K/L/M/N/O
+ /P/Q/R/S/T/U/V/W
+ /X/Y/Z/bracketleft/backslash/bracketright/asciicircum/underscore
+ /quoteleft/a/b/c/d/e/f/g
+ /h/i/j/k/l/m/n/o
+ /p/q/r/s/t/u/v/w
+ /x/y/z/braceleft/bar/braceright/asciitilde/.notdef
+ /Euro/integral/quotesinglbase/florin/quotedblbase/ellipsis/dagger/daggerdbl
+ /circumflex/perthousand/Scaron/guilsinglleft/OE/Omega/radical/approxequal
+ /.notdef/.notdef/.notdef/quotedblleft/quotedblright/bullet/endash/emdash
+ /tilde/trademark/scaron/guilsinglright/oe/Delta/lozenge/Ydieresis
+ /.notdef/exclamdown/cent/sterling/currency/yen/brokenbar/section
+ /dieresis/copyright/ordfeminine/guillemotleft/logicalnot/hyphen/registered/macron
+ /degree/plusminus/twosuperior/threesuperior/acute/mu/paragraph/periodcentered
+ /cedilla/onesuperior/ordmasculine/guillemotright/onequarter/onehalf/threequarters/questiondown
+ /Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla
+ /Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex/Idieresis
+ /Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis/multiply
+ /Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls
+ /agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla
+ /egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis
+ /eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis/divide
+ /oslash/ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis]
+pdfMakeFont
+%%BeginResource: font MFECUR+NimbusMonL-Regu
+%!PS-AdobeFont-1.0: NimbusMonL-Regu 1.05
+%%CreationDate: Wed Dec 22 1999
+% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development
+% (URW)++,Copyright 1999 by (URW)++ Design & Development
+% See the file COPYING (GNU General Public License) for license conditions.
+% As a special exception, permission is granted to include this font
+% program in a Postscript or PDF file that consists of a document that
+% contains text to be displayed or printed using this font, regardless
+% of the conditions or license applying to the document itself.
+12 dict begin
+/FontInfo 10 dict dup begin
+/version (1.05) readonly def
+/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file COPYING (GNU General Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def
+/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def
+/FullName (Nimbus Mono L Regular) readonly def
+/FamilyName (Nimbus Mono L) readonly def
+/Weight (Regular) readonly def
+/ItalicAngle 0.0 def
+/isFixedPitch false def
+/UnderlinePosition -100 def
+/UnderlineThickness 50 def
+end readonly def
+/FontName /MFECUR+NimbusMonL-Regu def
+/PaintType 0 def
+/WMode 0 def
+/FontBBox {-12 -237 650 811} readonly def
+/FontType 1 def
+/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def
+/Encoding StandardEncoding def
+currentdict end
+currentfile eexec
+d9d66f633b846a989b9974b0179fc6cc445bc2c03103c68570a7b354a4a280ae
+6fbf7f9888e039ab60fcaf852eb4ce3afeb979d5ea70fde44a2ae5c8c0166c27
+bf9665eea11c7d2329c1a211dd26bb372be5822f5ea70d99eb578c7befd44cdf
+045a363056e5e1cc51525ea6fc061dcebb337208eff729802376a2801424f670
+0e7e6397b28f15bc10b40012b0a3eaeb2693e8f7f627c4c9c7c6c5bff105c1e4
+1b2b9e8f09253b76040d268b80719e1b3f5a55ab7b89290699b50c1bf1baeffe
+1f57be7b5ea025241a248a6d4cfa5067a1da6eba4cfc940599ba3f3c934d7248
+b8e4ac5816f0d2ce8b3c4193ce39d19fffdb75254573173cb51ccd83c2f2d06b
+2483cf9b07b21ec6f502f028c273887bb06dae2afac10e9fd3c7cf51bca7b277
+b706e425302dc78975ac0e43b87073257a5cd7424b6865fca89d886e8f95c4f6
+d457623dbbc0d16bafeb4c649f5d72b09b18502eeab687e915e9b536a361b4f1
+44c3cd4cc683b5f05a4ecb4823a5eb5179bb7eee8b76c21b2491a97808f6318b
+585b0bad98f42fb4a755bcb74cd354f794c8bea5b90fb9681bd5849d45247e39
+930c882490230e1662d39cca875bffeac3e79a78de6e1298abe9817ae98675c4
+16220ad0d3a36580ee2f2a17aaa1246c416d58a4c52fbb26aaf3b6f75833af8e
+3aa996218dafa571fbc7cad90ece9c883c813d8f168c5e86bbfa0f0a5cb36e35
+2de4caa0f8d3227f72c5056bfb5bca6bf9c60e037a0e44670a8d3cbc9a19f379
+ca8db30b711f518a8c7569211ac70c46eed2af62a37f238bd0bd12d60332e673
+c6e784b3eba3f2e71e9993b97e8a38f85048937e958f1cd8fc6e661048546135
+56b810fa1ff611b96495081c04542df7fef085dec619dc8c84cc57683d212813
+9d14728aa32723e1d15f2af8f03422cfafd8ea4c92dabfe00e6110bca39fc555
+bc066ef848e437b50688daf26d001aed7e74605ddf9c0ed36be45455aef92689
+8cf32baf2418e02118593f54fe1857807bfa0b93b5cdccd81d28bede22cda6ee
+2e32422c1e8da8866e526300f9059e85ca54122ecbffdc011460913e0d28f7f5
+fbc9d7f9f6934b3d8efc1a91cba4128f6bbc5eb55e5e7b73647bff70662bafbb
+145cfa65df3db858bc3fc577b1bd8bc74fb8a61bfa71b8304aeeb36d8efe12fa
+6f5eee0eae0830e5177dc745250fc362f78231fc3ac9864559dba92dda2feb96
+2629293435bf4a89f913fd15702cf325981ca3a08b327f7ee35794a9e88326e0
+24559b547fc6da61b7a3b9357f72c767baa9c79c4e7b77f70ec01ac0b8596425
+5f7346dc8cedc702d3d57b09ef89cdd33756619af59acb9d17a3abeaa6c65218
+6d6855348a1095746b34af15df313091c59e5bf9e79b156cd7903c1c42e115e9
+c5203037c808bd295195e074fc4a46fbb1ff01c814878f0c177f552bdc9bb698
+349d73aec17997374ec90b69293a064442141a44c6fe8e3c283c02a4655c579b
+f21b53d1fd37996c682745600785c7b52c4eeb47fa5fd640739e1f09d5c5dd2b
+b7515a4cce0a21281d315563895972bee88bbc7401be9e20cb160b6bc81ed469
+6d66169bdc648aaae8a9495b072911cc814c19d53b95de0071e3a439d3c09c3c
+1cd422c605740a8939487e26bb9233d4cdefcca49bbeb1b913570a51b2f96d30
+2ef8913c6bb60b54f7ea4b8ca16ad3b4194dcba28439eb31a9443caf061c4d88
+c22cec8d9d8d85d7aa225fd64bfae7376abd40f822ba1ecc9339e09403195752
+fc03a5c4742ad93064d975906ed63acb495aae324403d3bca118179e10256543
+1bc84d47e0c016234eec0c52255ae783417941cc884efadb63f8269876f00a8e
+1e1f19eafffa00453203a0752750f8c876aaf87826baf77b81d336ffc29249c9
+a6a44f40381294447840632ee59a3c4530391f35da45c16a001f793782be488b
+5e01d7f75dbd53fb31f956f16202d3d94a300866814ba44c79764cc25acb57f2
+333dfcf3d97a98fca949b1da71ab27885183d8baafc9bc743143f2f1002ad752
+1e55d207de23e97d1760cd918a55148e37e05f6347e8cc299eed28d7319abcdf
+a4a279d5f64cc2151f91a0be9e8382a35b535a6b5f41f3708169881c243391c6
+67d9121ba21f6bb22be1ec9933d9af1dde9693d7704c1141ce2b977ff5181299
+6a57f7806814440a28b1dfb62c4dedb82f0ebaabef3367bebcd43246d54d8eb6
+7af07b164374998f06a0b7e271ad6ea974698a806002374d270c6dd5c9dfd5db
+e056fe1b3d58482a0cc98d4d5603c59ec2e13b446023692b9ac2dd7cf767d2dc
+a7c62bb3578847085cab79f139bd312cb07ce13e38c3fb8f695bcf4021c282b0
+9b20ba67f378cbb8832751b8f3eed370a572139431b9187893b592529fb1b6c5
+19f51798bce9e56ca50185d42fbd85819c3a1153d65997511b19acf87e69c07d
+2ca1a7401c2b23f99c19f95da0df136472f9fb574b21aebbf0c2f892b9260001
+9a9173f108e72c3eb4a93719293e8be026b833cd709c7c05c1a2e7250cad2586
+ca70fb7d927e36a2e4a6f34e754c8dd8ea2571cd82054700d386cdf3420f37bc
+b6a70b9a92e46cebee13f6641c67bc40979f9b86e052164612d3dce7be67fa71
+b26ee9f425b54b3577cb4acf3dad02f2e55d2986dea88a5a1955b78c0cd5decd
+213c55c9c57183a7dd5832d49ee81724a19abb7da0779f1aa6a77d5d31434a09
+c6f53b7e27123dac042f58dc27653d940358bb8100b416b920aee20672559f62
+8b20c687d77ff83cca449e94fcf4f06614fc539802340619e3a791a18581ffb6
+9bb5961d1e70e55615cce5c9e1466d77435e486f15175cf87fff65e58127b5c3
+024b93c1c296aab24f29483aeba00736ed30be5bb5284d7afc43294b927bec1b
+86814a5ac25a3b9cd1f25c813cae791f937375e013159624a360955a58e8fa94
+e49593a97150702c71dd8dbfc3774094df930414ffc68cbd4b4a25041cb3b657
+a54c9bf780142d2586eb5dd9ecc1eb5ea69245d5d9c2af868974ae5d46e3a544
+74e96780ae66023778659d9a45853c24da18dd5ca0489ccceff253b009c06cf5
+826adbd0e8fcf23edd75c3d3de8a4c789a895e06d20606e4f8e3c1bd77976e71
+de409203ef1342bdbf2c11bbab4af5a709f0462aa8fa3a02cbed6f23fb4d5e3d
+1751acbd41eecd8571518a9e13889c221ba5568cadf730f9da026fb38e30a25e
+87ef6a13484d6ee31c174bfa4b80cc38134d7b18c85c83b4f14d3c7b0a0b7069
+7baa1a397252ac47b67306e45d64061535d05540c86b9599df909e105bb55100
+3a0271c25bc5d596da2a446e35c019b5dead7b289614bd5085d49ecd0464b494
+cd1ab564a93ac9cbf438fa558bbef71c2fe003573a03979a10fe8bd54a053724
+a529f46ffe55cec8d6bbaf1f57d16185595c82a1ef42e3c81cbc55bf50587630
+404b2090df6d9d25468c1eb7a4b2b3da7f5b718157ef8b5f23af088301e46411
+b51e6e0d464096ce22bbc2028488d9af49792b4a17cbbba8ace8fc51e1de01b0
+97e6db05466bf66978305642b6790c08e59a7055f9442cc2cfc23095df2c27ea
+decc1ba54d6b81ecc873a9c71796a1ece75765b878d12e4da9e19d026ac44dfa
+2dc7e540506546aac70e7b82ae7fa98bf36549f4d540fffd53abaf7ed9044ca5
+6b4e9044a2b23c3e7c70152e96f4e64f6b1918946789d4f703675f3dd6e8e5a8
+f0add5f7e442c35cc782c92db2007596ec1a76d2d22ca5b00f7f9aa9819327a4
+db8d0b03369a05de96b8c4eaec254cba0f39ef6ca005c53afd0ec32f1c092367
+efd9f773bd00b95a60523bc0392b050b15ad70f7cb42f6d36587144cae2447ab
+aa4b4d9377a7e86ac489685833e1c14c3e17638b00884a46c1efa2b158f6239b
+1bbed6fc68ff606278fd4216c2a6d7888f0f0e5dfc9950962d4964901a47d6cc
+2e3243e1dde9ce7f435a7dfb19349a3017ce44b87dc6baec18354a2042c87ed6
+c1e3a1a505cc679e32789f75780f84082cc653a010d14dba84da0191a510359c
+1d24d700c58e54718f1d85396e7c5d3a365637085b6f79c061df17bfcd260ea0
+6b8416c9042c2831eb041346a22bc54f9d7ba43f8c4487fc240baec20ad4aaa8
+c03f180b614c59db6e5ec1531aefc908c46b93419b9f5b2d4eba0a67ba43d685
+1ad44d4b43b7796de5c9a11f726a90fb1a389a342143f98f49237fb451c43eb5
+981562d923d684923dcaee71b52ab4ce6269169a35f545e74584fa440c41eb82
+41ab194c78a5b980d021b3eb7994846d963b78eb6e149cca7713c12f77023002
+b8a797c9ccd0c2bd70dbe44f81f9d274a5ff3824ee34cb4317fa4971d67d90a2
+f3d1b1b84960f0fbee40e6341c5271b5b945b9098f3095986ab7db2e0714cca0
+301f6b8378559d86f0b0d95c2dfe94ac8e10df0c8c16dba12505a0d467dccb84
+16bfeb18784bdc10624f15da1a880ffbcbafbed0e1c7360962478006db59c78b
+ddcee524b6f9b15a8849ee19aa00fa3f71a3c2c96e68dd0248a94ecc43a60ac3
+88e49e005250706880485df109ce1506c0a4edc40f5ae5fe347d52ff63b26c7c
+185a698e171244aa1095620494949d526276175a7e120340d3247cbca4e3df53
+641d6d392abc61c85a22e06cdbc89cf37bffdf8a79361c6dd69e6774772f699b
+92f7a7184a00fdd7f36fb8a08ccde5bbcab3731366c3b74072044d3ef2ebc1cb
+33118b8c09c04174baef8df1bb4a1e1f848c1a5178ec58ea621f6f8a63d0fcf3
+13db79f885ac659c881ab7e40798a4339e6a78ba27cd9e6803c3d4df196c462b
+d08555bed51d7cf5821204728356cf813f554517ac5e28e6c4047c0100610635
+7d25c33330758f71bd1043365bda5d1d9214c8b159d0f8fb69e40e6fb4ef4668
+a228938436dd209dda5925597151f8633297862799152b0317bf21f9572f503b
+b10826aa7f8d15f5d780ea27f1b8ca0ba3dd732d3e3effcfad6e6ad8769db6c1
+df22ace8467481d16e8af6f56032c90c8f2500ce66afb94d378d893e84208048
+ec0cf900507f02e40da3e99386f939e05d9737b0b11b7dfae473496d056be5e0
+7f1cd25454f4b290cc43d936450c3d675ceef5da533db25ec07addc7e8355d8b
+8abb095ddd61c91da2dbeac0574e9ec9d316ed13df03c997d7a4a9c7a6a3a165
+ec1ce316e820e13291132ae91660d5d1812146abfa137726e8700395b4274502
+7d53b1e5cba817beb577bddcb956e89aa2d1ab24128b9ae8e06d9f0a6dab93bd
+f7ee8e2ff918255c3722a8b0e8520dd02ba7c92aba13ebad9ce0ad0f16f728d0
+ad49bcb12b429811d8ca1b5ae29b7d5393401eb5802db4d4497cad43ead218ec
+c674f42143bc174c525bd736b77dc28bfc7e107366eb9091eeda60664a771782
+cb41506406dfd29c974c5a18da88b473ae58a2f1fbe5680a40138a9d2fb7955b
+3fdda23b2cbe7e27c1dc4aea3069b1e7e25068c9051672b8c9a3a37d6e6fdb24
+3bc20d303198f9b8ad8154b3f4a4f2acb17c31a0489c1366eb8a13012c6b8cca
+4d416b911de781563e26c08538e038dd8ef92435a054348add815687ddb99dda
+88f1e2c5887707cd4be47f71ab81a3d6cc3e039bd09697734840f8bd0b88aac6
+191c6db089943f99ee4174e5fab3baf3a8429e273c4d1a5140e0073f86105402
+3f60df69e65809b7a1a5a8aee4d25bdde9fd6d05a3fcf4be5f253e41fc49e121
+df89f259ba981d2617209b53ebd92e430a69668995961177b159933501771905
+08f625b26b5085c04b325e7fb6bb45eebe3bc9f5c5114eb37f19937635d71a72
+39a0039003764d10cb403b58c61bf411aa8f5d717bcff23fb338da58d13ca81f
+acb3316d2b5b675e86a95cfb525199a21af248a1245c92ee37688c6e76a95187
+3b411697a1ea6694e6ccaddef3d57114cfde70609de67972edd1db95d923e077
+4bce7cc77605f9ba5226fb792829b1b8eaa15361ff78f190a0563fd61aac4452
+ee1b0d293e695416c667735dd886d10e4467b613dd9bb899f2bd75f2f13193f0
+481fcd3b4e2aaec6cf2829b1521dd4b6471ba31aa0aa4d63a6456203896a111b
+89c106f1ea85bfe0c0104b1292a1f8d49334578375b55deae2d7381f5cfcc023
+5ddfb3d8546054a0e6d5d81e4254383385ba593a7d3a8e0beb34285dd95d97ca
+3eb598b643834644b611e6db4b8b4360c847120038768e218031e097ba0bdea7
+732f7e460155a496b91b3241c74f9ee0c99ec7adf6a87b701a0ceb07fef5fa44
+44e127de3e777c23a8d938f9879df1dabb7adb31247a53174f919a2a5a4f920c
+9415f3976a8f4b739e114b2c49d67bcedc1852686cb041e3ee94ef94d9f2096e
+76f1c558f40812444c6f0f4dac3a4bd22b82e32d8bbf1504f8232ef00dd2f3ff
+5c4b8349a9d1becb8c59a9f4763f2566a7a513a6c11f54d1fdc1867ab741f3c6
+e2b44aa95479e4e9813350473bc7897b9ec592f01f97697a17967d344a4bc9a5
+62786f28f87e3639d091922f4994671b22efd41ff3f6b8a651117d0a2a97ccfc
+80a69c974fb2ccb36dd6a4897bf88ebc67bfd892e35e6940e94893e1cdfd2799
+8cfcf2b3737a6232e4783eb4a8ae56b83ed7661377b30225a75a1b90b73079e2
+6aa33fd37b81f7d60de62931b6be9d16367a5fab1d14d281d3e8d09dc525f549
+ed03a449df4655802bc3265010f286df86602740d8a86aaa228b9c47e3e78c0b
+22d2600d5cd55a3116058daa7e34174144f78a8f72e0dcb8cc64addcc52df0df
+3f8c21d9cc04e187be53f8fed4f33633ba03afa178fa5ce769a7eb0e1b9bf5bd
+de0ea74dc99598a66696bf6d5071da995a30b8144acdea116cfc447255a99cce
+4ec01bc8a0b355c0881f6e9eb48725d61ee0b245e0f7cc35b9e76fe11f681017
+f794ed8d4c4c7a02e17bd16a02347f28318ccaafe0575734058121e3ad8064ec
+a0086a58f216020a2dca29376981a2595bfac2a0394d448949b52ffb47e5c5e0
+d6371cb4a417ac834d6c9fa0018c5efb16e39e32c85088b266d74af5630b2544
+d4cf403482c490f86d35f81cc44b34200400c10c6dff035423e725d41d2b5ee0
+c3f03a603a161713216af97036ed38ff8d9b09f189ad191a0d03369c3fcd5a3a
+f88a57338971d7bcb5f3fbf8735ad8459524d93a92eac1c2bf5f0e6e1cf675f1
+6d72b35ceaf34d8fac178a1dd823ca0448ee1fa2f616b803c38b89238aaa1ae7
+cb057ecdbad28147da46a34b8a1f1d389e082cc3e8eb1a7e5c0c932341824c21
+570e003d8c11c87d7082371d3d4804da32fde118c6c5b5b08828e5783200c6ea
+0a7ab73343f5fd681a3116fd818c7054a5199212eb0f3a9a0d87bc364670ee2f
+7a5081a1e48a58748d297e014dd5db7faaf7a27459f115741bf4facfa1b395e3
+e97452bdaff906af9c52c5908748f1e13cc85d165bc893c1eba728458b708f8a
+9e8990a6f258bda0989aad0959e7326d1d6bccb50c4fab15a6ea3cbe94724fc2
+8f174df93fbff41adbb9d4fac0124d33151d06753d4d879ac4f15aec5d1cc0b7
+a9e861f790a16eb0821b2a7b7b42d6f3e389c51a1d7c652859ffbe66646d4199
+a62ed28a30c8932dc4d2855e7e6311d79cedba8beefe2cd529f4b45382f3e6e6
+a7659da9b786fe7bc2e431ee3f11873ab2709200b715343cc25c5365d06be9ac
+829458ff77f4d509d9c3917237d759da6775e09c2eaf4ce966a14157ea2780bc
+e3249446573c82b33ec5ca150022a83301f00f41eea3694059b14b2a9abcea30
+65cfd06b9dce3823477bf80938d355427666a8287a65e231a2357aed80d27a61
+58140c2cdb1f44caefd6b629fa661440c361dde7817154052436a36bbc1bf382
+e30285979c4568b180417740a17150952e3eb4091f583083d75a05a2d91009de
+46da396794dbb5288e2a2e6191d3f22e335f0275f33e9af2154cddbcc99b149c
+6d7aad7fdedb23c805f09725b60b5ec77e8ac9953a3578b23c6023a196f35333
+a36fab2ca195e397fc82318434e9f2844d17bbdc177989fd8af61ddb46512d2c
+f5d7821941b18b7c1f1be16df6e6bed4a1655edcaf6300fa8765e903b03a95a7
+0a7e6d55457f451a8177e0e9c9f3aec8d174843e3a99ed698689019e96cb4683
+bb24c71e22f4895656acc67ecd671963abeffef53724a645b98e5d2680297fe5
+2d43ddfdfd5536f7c239a5092076512a2a9821f12338e388bd5115ff4f4d2c01
+d741f821874380838988c17bd975fc388a253c8c006c67963ce3c4404baa0750
+c56760e367b566ed129911eb056bee42f12bec9980177f1b3713068073cf34c3
+70d6ee202c49b42809afd1f8786e14a6c63794eb2ddf49d5a06f34de23356260
+96ea26d57b94a928e5312147ecc40bbc6a204c4b3ee9d4f4361f8df9e1c1ae68
+ef60fbeb99339842e652479362b19d33de080f9625b5c167bf2b11775929b12c
+fa9e9a89cf84f249a1078f5584425e2ad8ac82adc298867ebea1ec6c0428fdc5
+01dccde39e5fc147959ea254217153c0b550ef96c229664c22286a7827ebbf15
+c7fcdc57dbb5914bb0460b6e0c0f58c98b264925d9996d9e0d31fb70e66eb9e4
+d928015f2c12acdb7d77a66408f2767c05f93292fae45492e5dcea337cbab346
+da82c905ddb016bba5d31e740b813c3d709d78d7ac50326f90d2e4af4c1dd893
+e26f9767db437b52a758d6237e52c4a2a71624d2b1f79dbe83b6b7839deb413b
+f34b91b3dfbc88b7b0b78ab579594ac3d57471074f78e59a64d75b4e6ed3cf22
+33f6ebc86e289402dea3907b0a2406188246e8e44054f81854dae0fedaef8952
+c05c8f5c4591673102a0f24f7deea7e19e27863a27c00b510690b331413df839
+5ae5a37f8c6b25082073bcede7c8ecdbbba2c09467afcebb48f4a4e25cb069c2
+b7acc265f988955a79ba95b3f4d8c6cf94164941723601923409e9d81ba8aeea
+64e8f1f09794779a1262020bc301b1966a789fa2f37d7521db536c0c8da36b7d
+906398a8a41230cda975088fa5a6070d88882dd8dee7af696ef5ba2c5a525d61
+d35a6834907c4846cfc69b17edf77c58e501a0600a04ab4b36d9007ac54ccfb5
+14a47193ed01d4fd5e3c8cf04b3e38c4895de3eee14dfbe6351bbbea6530046f
+89e913d022c0cafe528a33c4e84d465fe6fb031b48d904c5120d452a6c1fdfb9
+08e242a05d015a9ab2536dbadf0ffd0190d355edcd3174cfdda0974e2a33cbfb
+2a3d557ed2f6f284cb3c990c3071b7efc678a5d27518ec1912cbaa890dd6bbc8
+824eb1e7ac6127a67e68428ffd67e650fd44c9ec448a309056ce45e4a4a2b769
+8183ac418981f617dc469a566e713aedce2bbc7cdddf1f7affc6d11e94757130
+c4ec7b55dba7356b21e5267c5ed99f427a19daf476e48993e856c852d35ca1bb
+b32d59ce688ed184fa9ea1622c306cd788d6372c5b4a94b001f198e33209bb59
+46af1ef7b066d049825bb78318a38ca23ec9a93bc4b4b12806c1a0e5be179e3d
+0c0e5bda654e506e74e0ef1a8b12c18bc3f041d5e61a8f03436f146e4daae3b9
+6b8c7ae139f42e8dcf772cb5742104aaf776f3dd19bad920df77b42aac654d32
+2de3779c42639b50059d13b81c3904df76a0ab47046a0132378f9201359f71c8
+12eb4837bcbf3f1498bf8c7b2298e6b2e528f9898ddfaf75b5358a73a67e6307
+707fb13b2360ffdc5659ed8e70ecbab711d89f8c6558622d67737b1108ad5139
+b126a6c7be8b25709fa7cc2a625a0796b7d08b11f098edb80f8aa08a5668ae91
+4ff1c470dbcc7775a73fbd857cdb9a5d0c122d4765caa8d9d35514390c9b339a
+c04a78342e186e5c49dba4cd9ab165b4c139e76b88c807cc4b5db7b5063c2f81
+16721670497a0183c643c5a70ab2405d5d8b6773a4a2d39b3cd0d763c12ec296
+9b3c3ab916656fcca5d715e7dac796937b2b6d4adb251fb79b183e6eab23796a
+0bd0bf5bcab03529467a265781716b0186573b862b2a2057c427d85d7b547c7a
+9e7fdf7a674587df709ffd0a63d0852ea0d02c13e8038762de82362739de9ede
+0db4296421d462d8286e2152aa67298c9ff511e8de1a26089d383bdbbf27066b
+f322738cd2cf198bdefe566ced1808dafc015c8ae972117776594e9c506a3223
+d4ced495d6229c9bec17c47071415f80482f9ecaaeba6a135d2173254dde6be3
+f0ce9a7a81ec2e9af4add855b08309d34e780adf0f7c9029d2ce0d5f807ef0ee
+531217450c82b7f3643456772549acc2ba6a5938c517fd775114ed44ec69a45f
+d9110c969edd9e6f8b4bfb953aed79a1daf47c7238871e4d537100c4d8981d82
+a2344eb7df5baebad28e34870d52d97a66dfc75740cda6b403c1964c0feb034d
+d3e5c8b4a37acb9f5718f7b6a3d267694df8baaabd38154d16c162ebe43b473f
+ec1f060846ee8402d67942ee080dac9b18eb8b09d384ac24f85d287ea3e2c59a
+0f2c1d6bad36e262e031acd399a2b9a7940908d65f142fb209416e891a6abeeb
+389e2df002436d43fa1161b71382d1842788af1a9e6f39ed56e8bf63991fa790
+a52ce312aaede90df1be57e3c1151dd0350ffe7e476cac5f34cf8505bcbd25f3
+29aeed3a52bfe1f10366dfc4a15fe212b1cc9da76c8272d7ce85c2930d797b82
+4a67de55c50d45cb3640db2a79ecb647a2fd2d948114eea9bad6312319f8db5a
+a29d60b22439d45760751904f5de5d8c5c9d0211ac9d30b9459dd05eeea240f0
+97f0c239068c514b8213609014e6bc50633d0ecf774c210aee7c75a5bac24e62
+813181e4d040ad1bd4bd4ec7b99b8a37abd694cb67483d1c5dd5c17f54ea7f20
+50d0ea8ce1cbfa5395e62e10c5d17a423ac76bfba25a38fd474b5b4117ccfccd
+30a2ffa484af429168b1b5679b67542755e989b39387fcd9b1d8f8ba313a758c
+58641f34ccbc8f2556ad1b17c33f601ea76ac75ee6b681aef12c0712a14e7b8e
+a8a5bd316223d5142e8b53a6f81a8a608a3dc32f20c5e417a6aff0f725dd7867
+429fdcdc16a22ef6112fdfc5282c61a1aa9b134c1b420de7b359be8373cf3716
+d7b3ae832ec15e305ff6c8e9d4197f8b0150b30e1b9e7f15275b4b7a65dfc611
+97c0e5f91561f3e6203950edfd6cea20d0649071442b2916ebce5f4d3da73914
+5a2bfe6d055580af134b7dddbb9baf9477454eee8abc7b33eea500102e395212
+78d08c08ae455bc0fc5bf5a0a577e5f5fc71490add5a623ccca134b62c19d3a6
+4019415ecee0168621be2b4856ef3b3944c0db9aef7d3e933a034184934bfd4e
+3fe21d4d2625e6464e9ff9cc25e793eb7b8701d3fa07ff9a3020f76d668d083f
+59c6f6751179d60eb17b9c4e35f3815aa5ed3793a2030d317f1610215fa920a5
+5ff29a67e8e6f186f00b5ce164677eb1961eeee35b5a7891d4296967a9d096bc
+76b0d072eabab7ea758da89fbdc25b8261d9fa08099b6e84494fe034c3edd5f0
+c45e67ffe588b2532efb3dd1c34be9ce299712eac0e4c4cbee6f30e958c9dea0
+15c5c4fef7cd440ea982f91c07928463807fe07f27ef61a5deefa47879847835
+d4e50aa1dd0ad2b3d01069cc7b4741b3f680131f7d5cafc6b3978c3c1d608ac9
+d24342092746628cb71fa01e3c675f14463f9edd4c339ada41ba4b6a0faa5117
+204463bc7b94d01edc1b3d5781898c85516617f29b4dce2d32c2686ddbfdb838
+f67b097be600f6aeefb6eca5f729b45be307232f92731c10c3330672c9584141
+7192e62a0ebae828fadd77bfc2ecdc1e562daf5660354e0edd5b7177bd8e9d24
+f77e526e649044cfd49633d48cea64de714e59438ad980e0b1ffd51ee19692ed
+665e2ff332bb54bdbf75316c4b1a39c538312fd649e8c462994dc8f14bf056ff
+0804de76474d0ee084e363c8b7081b1c08e252e05e49679e6c7ac81f42e9372d
+e5af64f59c4fb62f3e2e7b16ff53bbbc006e3d9b0f29434db5a63210944053da
+ab56b1075a0c3832220752d104fa1770d3acfbc31704a1b7852c077058f616e0
+a4373c1c92c7b60566691573502e9a92d583a3163bf31fc100c92e6405ee4d54
+09d23a83225bf6d1de2c7bead011ad64547d6835ac9a7378033c85592a0c3497
+a03c16190ebdabb792ca0bf803dcbc3bdf0f7a571aae00f596ee01eb476bad97
+3a27a219aafcc0fa245c6731a2e8e561c63b7bc3147b9433a8203fddb7138b0c
+1611c7e62375f2a114f7bfab36cb1a94b9e10ca63833ab245af595217779bc7f
+d12e68a65919eca4fae72f755669580ab0009452bf086ea835f91a0d5b384b40
+82bd515f006865bbee2c50db43b4457a793693806b86f68a2b2419fc3e937a72
+c6f414de148d2a62a71ee9fcab710d6dc08ad6c4ac443365e7a78843f80cd769
+c56efecc2d63487b5fcead1aaaf9481a7361723388f5b51c2d9cea90486cb9f9
+79f6f5ee718d4a49ed91cb091adcbd0e7b3ad963368c9cde877666a742cf5073
+aaf79428b3095f989fc1fa6f5ab1d724d92c33c1325c05a39423b8a83bba9359
+97793fda280740aeb6be3193be5f4feeca2a8f28efa9c8e016f0fc87c8f3392d
+5715b9b9a7aa3c61ac84461e2c3220372568aaed851f1cc40481e326197ecab1
+f3cd792fbeb27a58a5f889a5f6321473148c6d311ca89be96039ac9423700d87
+ab0d7e8b89717d1a62ca14e01f51bd77832bb6dbf76b201a04d222852050cc5c
+c6a4996789a0bfd6ce364592300282f102e66f4ae9e50d60d886cacb099df960
+c42e2213017c567f27326e677bbd04a239631950b566eb39e4f675d2e989f56f
+74da3a0469d988ea0122ecc3670d458ad82bcf7ad04bf3ca9b00d76ee569f98b
+a375285a1abbff253b8f179f71f496286330e364049c72ecad4d82a933af0189
+03de5e4abcfc637803167e56911f826735a7c41e7936f4bea148397bcfb18cda
+fb03182ed7c511aa9de0c6e6c80b24cb535f03ee16bbcb514d65ca9ac2ef15c1
+aa1825759fc4ecafc7c0d9401f139b3f20ee915955268578a933b184a86f2017
+03cbf4db79be18c09c8cb07d85739b8653ad37b8c0b647161e5cac746b3c0b94
+2ae2a0540f38dbee122cad0cf739ef1b49b6dbbd5d08c97c04dca33030f18718
+583337a015395e1fa932df0328c7ddd9546b7812ba06d82a35f8110d55fa377d
+fa6880f52645890d58478e4ee3b72f08b2d7113b2453729b37e4fffad13c5f62
+06b3c767a45c80bd479d1e24df660e46c83c48166fccec13b9cc4e62a6aaa813
+7c424885f83d7647b80849c0a77bed562f134034cda9fd6e8d7dec9e43f0c018
+9287de759676f20005556cedc67c31509a8bf56a5c972b5d247f21d8b6a58953
+7d92101841166d7781d4d80cdc35ca382d8c2dac3ea3a34f93dce0ff8c76ef12
+390d5d57d88f3bc00d46513f0358c43a22c413d9a6ba6b3e13913474b9e53bf5
+31136a5edf9192965aca98e06316c05fd3d6e88fe09cc08e327ed027b81eb146
+63e3073ea5d1d59b74149c5f5242d3cb253c36a84cc837d76b2ba36104aef0d8
+f9f4404d63c42f3d635dc9195ea582b589cb5b54ab01af9ae53f3ec95992c09f
+a5bfe86e6ef6948bc387730a9cff0cdd365650aeaa5e1d52d8f88dd49d36e6f0
+786c7f4ef8c2a5a242e84cfd4dc50adfea0c2ac27839699b92fa8feb6436f2aa
+d02710777083723ca7e481f83b637f19ffb7511de223a0a261324189edb38d88
+6ff5cb1356e8d567afe76f96cb72f88016e39e99af6aad499ac60c8a3205f253
+82c0312e1f2b6ee7b37d178bd4e67550276a7421b4f514fd293ad32bb1121234
+bff93d2297dd32dfdd7e7ba91c0544f79dfea965f4f67494f3ddd97d7881fcfb
+20ed71f6b5cd27b12d04098a9293e273148590fbb65f6fba63e7bcf14dfe6f0b
+51f870be20174f991329a5ef3d3c9fce206799a01ca102ee7999c2a97a19e796
+bb5f88922b76f922d302dd833ec532022b13ec573b375cf75e49718b2278f2b2
+4ce9865f20902d6358440efc9eab6e0e069ac7c193c88a044cf33f6a39388f6a
+296f42c637533cc503adfc71c5f898c408a7e5479868ebd29c9ed02939ffd49a
+2812baa355be429858e0c6aac60817d684778b71fb9a73e7ac4fcb078bb1a75a
+b425ea09ad8585ab3fad79429321a8f96e2e1f02ad70e2fdbeee625bb434b0be
+f8eb957f817c5699c7293e47daa4ead6d47f00fbb6c8674ef1f7729cdb19749a
+ca9cd399a4abcf28ff71edececb2a955ffbe9ebf4bdab56256e7cd66304ed4ab
+1b3fddf6431296aa641a8795a4006a049fd3b35074a865c901636b70619ec26d
+aaaa8c8c9060938337144209f3e3de01e92293ca89583cbb4c2edec074bb4c05
+15130c3ebfd78dc687f0ad0981c0d27fcaeb28f470193ca13d98277dbfcfbf38
+f8353dbd04380abef7176b0b4199d7319ebfd88ece219ba6edec59fd158987e8
+9adc035b8fb2141be0e0f25d56e077e5992e4f95640abca7aeac3d929be02d40
+9a86dbcc043637c5e0f1a5a12579e57b042b386be96c9a8b3c4e79c8dd28a52b
+a1159728785a75f2e579b8669a36a9f9e7807ff9d5aa0d8652609a47264a2003
+fd202bc8fe9cf80e2ef05ea5e5fbae676a77bbdc4308ab92eb0dd9a960f4865b
+8305eef47abc2353287f52c766ea1c1b86fdacf0986e56a87462ac820e61051e
+7f22cd8ea7dcc7838a45a08ea3fec105d80fe5ee5e87732bfc2e9d664a7ab43b
+05321557d69ceed6b679797a67a0c38b9d101bbe870d746568325c52d4ca255b
+b23f9672ce2b4e3fe944f5dbc388e575abd897d969ac2a81915e3fec3d7409ed
+14de1e4cf7737b6e46f6c71142db06a799a7208539c649244ce73a58f2247e81
+4f241aba74d6ae593d47c227137ccddcf1f523a730a234c91ac3ae8a456cad1e
+91a9480c438b047be40bb2e4038f8ebc34ecc3a8037454b7342c317871fc1d97
+42f26e3d956da7679a072cab96b27fb2ddf480d2f40ed88b2e5b0b82892c8314
+cec9bdc12433159714891b8591a051cf2cce7580af74d5096f53a65347488bcb
+948fb028f310575d3429123ebecd9b09d83f30ab8c8ab65d49d691fac27e3612
+66ea08634f4c7d3a648ec068c2cf31f116951934864dca2755daacb6d22803f0
+9488117ef66e9b12663da9d00a3eb0280ba412e4b6f6397ee7800f250fbfa023
+3162addcca4dc23190a52397cda3285291842a2b269c4e07f17a0035fcbe785b
+6a570e4b75692658ed47b6dbf297adf1b3b164740d1e851f08deca9c05a263a8
+3364c544cece706e77a32f6d5d10f8d4170d5246d92c2c9fae457e0f5e4ecd4d
+08b4edfd42a1791cca41078d5e520807817206193d8a649eb39b64c80e126feb
+240e1784da3c66378196828104c49e5fb86475a80c21de71e0aa36ac5e529ade
+427c03c2236db0deca99c7c486ff463a72723efb519263916e73c25da625d0fb
+e45258ad2abf3445b72cbf3e7e64d507198f666edec002e233cc0af6a8c1095c
+3cd232e2ec50b2ede3e09b61e25996b4a64c0eec9d55025b1f47e53e0b128bef
+a34646b4e2c13699d112c958590058e6b606cbd978cbb0ef69eee350bbf71ff1
+8213a42d135e77e2c53a8121aa3dd1e903dc0e961810d103bd70a2b448f29ec5
+c3d907d7243d76c6ae04c22a8fbc6c1a05f9b9ec97cbb0e76928f4aa26c913e0
+3f8c371efb61f370751eea6af25a3df4ab3da3e4aa263c2477343e4b19915219
+c4c52cf43dbf373c316b80619f479d9b531e62f26ef9fc6da13e9cf0bce74d13
+c2832f1c9d9432437d253dccf73cd699342521a3cfe8f85ccdcd23e9b240c961
+fce15ef77fad8438674b55da638df2492b29fc1a003859f382a776260ae5067f
+93dd176181c10c4a45e8f237c5c9781e01d2e1e0890e1a6e75e2bbfda4d29613
+efdcdfb21317d770fa6c1ac3800f328bdb82b48b7320ddcf64add23374971af1
+50470fd002c01ef412c5bb4984737840da5c9e0e4d4b2b7747056a3865af6db4
+f4b9cd84d27dd2e45aa0d9f32d0cf58a5f1baa374359223cfdd07c18017660a2
+9227404eef0abbd0e29bd8698752e85448a5c3cf596dc805a87ff903ff890e48
+b7971764fcd8f921eefcc55b2d20cd5908a6fa35d56bea96a39ab521d985c50c
+4e0213b30325d295a00d32d97e95646867122dbef37a3c866fd72e2f29ed8758
+a362a4f17875cba8be23d04a35714d4c27c4417039fc8bcd25365c8a4bb41815
+ce1f74949d6b6aa58fef0c4cbb8d54ce92d65d0a65f13ac6063de4a55ba5561d
+509f2fec155b2181a169ecf14f1fab587569f260c0cacded8021ed8d7cae5ad1
+332f1061e166686b41277495597c16e728d6a8ff49f824df503a63322b442182
+665a12900dd48d1361342575fdd5c9d9ddd7bc73a937b2ac6257255414029a65
+9001199e9e1f16cf3cf876bee000302935493ae997e3f112420d7d3f06739b79
+eddc1bf7ecfc5316549d2ff228a4e28b522d6cfaae3148bea2755a45bc27dfc5
+128a9a38777cd3b07f91edacedba2565b55218d7891da863243cf68e7800b82f
+0341740a1f5dc6dcf0125cda844867fe4945326f13a954430753a28ea8491bdd
+c545e71e4d52cabc3f05dce434101d36a62328c5fe6b5df3864f9f5aec22f399
+43f72fed081d3724306477a06eb9b6fcc9faeb77e62ee4e20cc51600b1bb081a
+1c5a00e064d5755838b251807ae57c85675cf04b69a66bef0c19c364969d3547
+55efcf31f8ae346582462e986e3a1d653c205e5d58d21de4553832c885e543bd
+11eea2d3c08f883000966c99281251fbc2920917700037278d4934f3441dd535
+bdd3c52111ed0b282ca23cfa97ab25c8726acb13d50599245e532432572c35ac
+b9391685d9e1deed1f95fcb151594cd63e79691b5972ba2c3a0c0a2ffaf3c9fa
+5ac47d9177a691742e4634db6631c8696d0a30bce1d86a4fb737ab85296ea479
+fe90c51cce54d64087bfc80ae56abb5d04f5516bffb681e6b39f480767f2120e
+97d1e8488f1f540e2ebf63eb74596670f5892f4c327971f697c7530778c3676f
+2792289cb12486935c447d4eaf4afec65fe6c6962306449e33fb19fb9806f87a
+8b91874ddf3e3138481fdc711f0954d73f11fba39efdeb55ed13b16b932525e9
+9f3c86ae60f9096efd4968759def8d629ff2838decbe4c68833ba0d64d1d3330
+b84cfe8ceb23f4b5d55aa5a9b51ee595aee0cd668b20c687d77ff83c803ab994
+c743b43d9882837c42a58cf704490fddcb5646d48cfd2e30464d710c1440513f
+4417dfd66d39e0fa6c596e17d07964ebf2caecd0a9fd78e003541ba53468e719
+b7dac2685ccb9b7d857aff1d4432a72f61829010924781f5d15ffcf8d504e361
+6f86c6638469db4ad281d8ec365848b6f7ae1047114a2cd3cf3d1e46e0b4f40e
+1a8d3e1df1c1b677702d7fbd5a5924f91c726de2e37b436250eb71610dd82cd5
+5c049fd044b4407784fd83387eb6a788103430fab4f682294b287dac43f3061e
+d99c74309ae973bb998bbb2a691402843a1a28ee62ae8e8baf4d645d156b94ab
+34680095425ad8b4dc27289e3c6818d6032f91535459d7595b2b9bfc2f44e782
+30f0af49c0a2223e1cee9e1289f682ed5e8ea7db99663a234719667bcffa8077
+e0118b0b9702538421dfada01d97d7a8f232464b9fc209cf278bd5fef80c14be
+011a9f6fc78dd20ab012a30780db2507f4d5e1e493f30814ab1c70cda75ce959
+b5d515b2ee8640dd4bcda6710703a9e5670abadae856b86ef8e4143a5f03fc16
+a6c57ac7c3a96c50e45191b0b1c4f6acd622c400cd0f2ae9e9d51236f1b945d3
+71adc5feab8aa8422a28755b63978aaff787158a68c26fd29ab6e849b076b852
+2190caef1a86663f4e12cdf25ba7bf882ef2e0e21c77c14fdf940792d7bb28f8
+892a9ca0bbabe1c70c152f30f366bc86b5bb1eb3b54425617682a5463238c999
+aba3a7bf788a297d2a555dbb218b19ce501aac43d94a0bb6ae290628821efb0c
+84ceecb30c140917a458db6fd011f3cbfb4a1cb5ea019db628c106e2a55f1c13
+448edd4a9a159ebb369d509da296da724f729fc7560c00c41f4309e32ea6fb71
+16f62325a5af317f106a8d8c2c01ecce6775d45fdbefdf6925e9a44604dda13b
+27cc9a960a21eea2af9bdf6b3cd357d6097ad40df7403005746a30833e814eac
+8db72c383fa42ba9fd007a263ce3b74c1356bd522d2611e4e960c9ff5204d46f
+ee332f9f134e75c791a6d20923ece8d4dfedcf96ab45dfd751739dbd47b4863a
+f0fda172848cd279afd9fac3cc5744c1fa8a5fb4955c6c1c952f56da06430aee
+084507664f93c71d881b63041cdec58306100a0e8c77421d75679ce33e2a0a63
+ac2f813006cea69e00352ffd5f5914b63dbad5905a590ce0903ed9b9679779e2
+d9da62f478768776a173832a8f3cd66b6b62484d190baf2d834241000b0eec79
+f1e53b42a74b159bf781ee4415ab6acff86c5b0593cf463bf95d8fa82293a548
+84bb226f40f24591e5ad463ae4b672905e7a4222edf976e8ad889e71986b3818
+bd3eeb6a0c96787c6fdf3a4faed94f0ba0269fd082ac451531e3b0c01f996090
+3f821dcd64642868f07aa0feada34088a85e6644ef07f4402b4b293073e9d308
+bb298b0e44be36bdda218259b4f48f1b638f5007d3aa8ece802b485e7e9075d2
+6ec881fbdecb3cf58c8a3afe0d9835e7b468c648e52b2eddb81dcba4e9678bf4
+b173541dbec382423e80877ba2df94a605bbc2cdca2b76f74d2eb425d8191958
+804617f21172f397bb762aa7dfd0485cd020397a5d3e9fc9405ec7edccbcbdf4
+295a0057b7684a701bb7ea01e8978fb3367ecd089be19aab2828f6825d275d3f
+60662c1e2ec5e98ecb99a96d6fe379e2fd158a7106b2190902f0ed71969b6daf
+3f9e460f16f1b40cc2aa08330b9fc2e24802bed034b71de445a14bb33f642989
+4f76319eddee328319ee9577740fc803b81714a99bf0a5722981427ba0858546
+c0f77f3919070060704c3bd991d94909d2012146b88c0d35fba7c2de864e35b7
+caf0099c4630443625be3769b01526f3f0c8c821da9d546bc258c004a4d2b46b
+886f1ef916f50d3f5fd139e0570b4151dd41f1f1b5dab0db7787105c77b86901
+73c562d3eef6ef741078659467f333450d7d80c67c91a26ba8c77adcee6f4c56
+c7f248dd92520db35768e703f7bd171f9e663b9daebeb9611cf48425b6b35c1e
+8bc7a0b45441ad3854ac9b37061839f578256a8e41766d1a6b29a99a0195620f
+a090d0ef4120667902b0587946206f294b78775d60ebec668f6e4fb9ca897e85
+76151b245aff8232a90f97a5a93e935c88579dc0f2e9da7cbd02426b3b15ed50
+30acf50107f7b4d4e2c32dd75d6d8c4539176a2244e761ebf1ffbf97d336fdd6
+ef9cf138326e10bdb57638235348eef8ffd33c84b426ec1c81fd8d4a3907d52d
+1ba7e9b64dd56b8fbc2362e30f2451b69b0d7cbea1f3101afcd44242d3ff5b66
+89a7c05449b281035e983c6b8c68859734b232a73996a19d116ac4a94f7b482e
+1f984371e7e9919c312250c35f6f7fee25ec23e562dcc25cb29ea79dff0e7c8c
+fa19280288c26dd5c32f4aeb98c85afda533191809267f0555498da5688b7c20
+219a058efaa597125535871922ff9b20cfbf4c4b35bdfa4bde73ca8ce6abf14c
+510ed2072a01c8adfada0064777509d4f97bd2baf66e7151ade76e407066efdd
+2e08a15790c81d545b340019bd350c7b90b36adc8658c1848020a77f918e1527
+b3974710af503a79d7947dce93bd81161cd7e0b1125d2fe0edaeb91baf1279e7
+312fbed646472b352310fdfbefdcc4c20ccfed0d6626083b0261d7c47d966984
+8dca4298b9ddb58fe21bb391c7d45d9b562d38c4dc23acb5aa87e3ddf59ee238
+c91318db2491a24110af90539a16940141d1efdf4a13d202f9b9401bc89d7297
+5269cd5515f9a6186a6ef866cfa03730f726d7a4075e0bc6f094e9584a84cf1e
+78489bb68dc09ee3f1356f4e45b8621e06078a6727eb72c36fca805213c1675d
+4365255d90164f33ce6b2231113f64fdcf5a789cd61002b2a38d2ca5bf1f5361
+c9ae0f4efb51337e344fb7ce15f8edbdc9ec82a9435175f59b6c19ae2dd0b10a
+944565e4b14bd1dcda02d42be27fb9f0330636091228e3b89709c8148932a5f8
+c5ba5bfecfef6de83eb414adc613d8534c4e4528d934c37e768d08e103b8ed2a
+e1e49bb1b3e6cbcdc3ff63dac7994b8c09203d82a99710449277c20a34e01538
+67c5d5e6abebba650c441d3fe56de997e928193682e5f1faa93a5bc800862132
+ed3b6c005cc0e604231e3e61d17214ca38148c875c268a861a14b54e659dd932
+cbe6ea7109b273975d6ceed351f0b0876a0b647946d29097dd98b5f6bda7b43a
+e6481f17743fda503b34a120c8c06f4798c1fcd4e521a30d76f2340df562b63d
+dd4b27da8b583547d285f3848bb9fddb60d0ed22a4cb27a2784e8d7662e84ffa
+eea50afc03b0815b72bbe9558c8959d0ccc00a8c8c9f740f95b671a66dfdfc68
+77fac12c1995d977495c9ccacd924e45a66f8739de156ee6962c7930f8aac374
+894f8bc396ff69f2249392c7c4248f9cf9ffff9eaf635e66a34511f39a066b88
+4866e776b8d6eca0319f23ca604ead742bb6f6f3b046454a1c0fc242551112b5
+c745e9b8f12723867b2b895c0f93c99df1d542b86c1c9db47390f2d6c3b57ecc
+66b1a6ab514a47fd9aa6240b46c54a92fdf80fc44eeed4b8a136fb88b1fa5b9c
+a2fe682cca4d0c5a3e994cfebdc270f48e3af91ae6bc9172bd9c73053a761364
+6ef9e68ef58c718a478e7d81e57f34a791c26269819c78574d7cc12632684219
+a1f8e1c5ce8b358d6fbf23984e59d9533ad310d158ab5baa9feda08717a7f5e0
+57684c455a7e3d833f82b4e13e9a92b0b8fba5cdd72a7e46709074ddc82e449a
+c906474441066fdd9cb7f341f3a2ee9f2fbf5e4e1a350a45fcad6b2e05825b6c
+89077d742619cf1f8434a3b5cc44998176667cfd5c5f4ee51326d1ee3e449915
+00bdaf57c88a107ac49c14cebf18d010c5b3206ec88fd06e3c5114581ee5a5e8
+c4ee5a5c3d48653fb23d28f26862c433ed083af01ed3df8e147548f9cdd882f8
+ca3088106b9c73b9e28786ffa643c343a940bf850f312666e635b8db95c6f70b
+83d645fd947f6df322d26f8f9081cae71ba8b9d0de67d535b61146c956801d6b
+ff9a69365bda9bc97d8d93142d4c367d5255587ada25e4fb061f8e430f73d2a9
+7142d9e4c17435b78805946e4fde624ea5d9b5c511c9afe2cfaf447cf08235b8
+575ddab8af93588e0c8206f08f883170ed4463da31a53cef67f01aab8f645acc
+c2c764f24bf831dcf005833ccd1296025368b3d51a04efd095fd1355e93de563
+e71dd047ef49f5bf8c17b01b2884872257d743ac6fdd8f54e27a241d7c75b387
+a8841d8cede676e35d4f01acba2acebd8b22113bfbef80d5eab1e8cf56f649a4
+516ec097872a597e83519fc1397c7d4a4f6db7daf044835b17d085578f5a3776
+fd5ed9235c018354e801fac338aa7ee581e97d91df0196ea4bcb09f0e6f2e2bf
+b5470827f1b6bb0b7133c19bf43bbe824ebdaf9526ab15ff8ae8848bf0decb3f
+cfa7d3f5ed71191894c705a27cd9aa30fd384ce6a5f0bc51c5651dd2510a3481
+d086aa87595f885c4c0afcb02b1837cedf85c5e64d440e36581874a117043b75
+78da94a069cf2bd57ae70c230e8d1a0d4637223d14a9868835d8923feb404323
+43c22d0f0e8201c20247c78abf9267915069d6471862c2a0c51ee3ce3153e305
+4a4ec6ea52dcb55df358d1a0d8aafa79fe08ebe4d22e9ecb9d2e50a7f367cded
+7169f84285c482fc1effbde6feea424ecdda2494127c7b896dd05f5e62f5fd1c
+031de960d6ec59954e8405081601df741edd97f227fd426e0998ca7b9b498beb
+4cda9a16715cb699c46d1386469958079ddf5ff174d70338206208f0b9ade386
+03e8dcf31e09f44976c1ad762896a615d9bfe54978b7c3914458c8af4d33dc62
+9f9af5171df3b9e548b24011ec5f02e31dc379582e16f3c999f047b82e7f27f0
+4bfdd827c9a1d19e4230695d4ec499afdb6147146cb6f5a8a26efbd6d0c5f205
+34cb9c37fa4c4b6122f55bacb756173282abd6a2e5219c25b86a5181021f0bac
+6f17f89f3b8f74c281aeea7c1d4ffac602c2364c9e1ec8b0a623bd3541765cf7
+aa5febbb6e857810a564850259ac4ce6d641f7b765dd46584c43c8113c8583f9
+e7763d3f4f83649e12e15557f48dcb0a637140b2f7479f78f1f64bcf8a07acc0
+43b9d9ac1f8b2c3b00c36b46d8e514c998fcd47354b364e8c2434e774ac7098b
+24c3bfadbaab5bdb8ab0a6b9773aea4175615241249a2a58222df8c53c32d01d
+6adc5fb4a933605fff98c7d011266380b305403a79867936156240a5c555105b
+95cec3873530fa6d37e8cfc286118a9618c60d6282412d0ccc5a8e3af47a42ec
+29cee0176d1c4802144619a5bf1cdf9ec5b8d6f87c379c476ab941da24420a86
+04a0b1ad7884b5e05136139afccf0b7101cae4b8f0bfdbe276aad1b95e2c0d57
+3902bfdee651a202b99189cada176a22facd053bbc73af1c90cbda10635798e9
+8de05c338e90b3dc4afb8d29010590b641db4a9ab707294e55e44c97e275b52f
+b88f52a6c7e545cdc73de46da699c8c3d895880368aa035a137fa8686ef4f64e
+09167b9e523312b175a166de5e1297c60db361d9505c12b48c1780a00be2a9a1
+43bc6362c731eb26a61097c62c28d2cc8d75ba3c63e31a49b9cb5b8b7fe1fbbb
+6153bc87b4538ef5cd4919811329ae933d86ef556883323ed5a6db5c98c11b2c
+cc04c4f937289590e5f7ee8d57940f21373a81b8b92eb7ca978c1a07af7b1065
+3e6498a6e2fa734269d61cf0dedd647eddbbe395e1e8190552f9a4332082bee0
+87f28fd6bb19e48de8ad662f41b4a5de657511f2329fe6b541f50ec43be24d5e
+e7336712535ece6a590426e10422d130f4fd8b0fe314c9fe068c6a45835994ae
+7bfda8ae49fab23905e4d8b374fc654f336b36b2080df61abc288b26b9ca7b42
+68e46f120b82cdcb74715e6d09aac096fd117ace3383beaca52aa248cfe307ca
+8930a34b7062fb153d968c93169dd223449ca68765480cfdc5df39be45055d37
+8ba14daa5a4745a9f7b76ab664ef3d5b2fba29c60a06d1a088c05eec6d95c080
+1974ec344b24dfd892db7874e3e9df0fd61ef8f59b525f92f2b374999f923f34
+668e55cc90ff2890107a7528853f44177fa52a071f0ce997ae94b590289411e4
+c0669c936d4b885de8427b60b2f8820bc9d6781bf275a95921d8cf4f55cc8cc7
+73ff7d001f4fc5c41ea1c755ee48c5550677755aee061a3ac85bc0d9c1e5b410
+f38ddb877fef4ad4142c87c42b6fead87f1daa99ee0fbe7e7eee948672373a3f
+7ace2444607921c61cefa7360f3194685acf836165e19395c2b2c9cb5778d9a2
+6f35f91d61e5e4838aa23909b46a899a1e02e27ebfb5368f1080272f6ae9adc5
+44f512191bf17dba3eb22d98b9b934f359fc86c9e451d2d4194632a7db5b1270
+6a58cea47392fa8cc24f6b4ec5d172e9e5601617d8e22e837c0b35b4281364e5
+81757e2fccb98fa88879d7ccc568fa9b183504b491329320c968b5611eb1f337
+a6e50d6faac591da994aa47761865ab84651c328bf259be59bd752f110f89081
+7553823cc67e36721e95f1c4e2e372e020f2b2ffb045aa70ca4dd6d55d88e32d
+c8a17492ef28a44d4a536fca8bd75b3dc392fc296377b2c4743897c32eb65283
+e776e8f8fd97c661c67c3f0d97343af141bf6b77499a13af4605e36d3f4c3fab
+12bc5daa5db1d12dfe5915acf14409e9302b1bbc8c5861948eae329ea31132df
+8494560e564bc16073c7a777fefb30cac6f4b8943c70195289946a60f06d4306
+4536c2740995b7247451c9e1619f7e277af4bcbfff6b68553ae23eef7b179c16
+cab6aae7b6f5fc72e0d7cac34611d1353716580948ba69dc534a3fa592984244
+c1bbd0a6d3f1fc4d9c8ff48e770f5c65be3b5a961e2ab8931e73c8222e6eb481
+86e92906bf2b44fef5a59b460bc88ad1837730515d82c337c349cd087329ffff
+0718e22bd3f09fede7042992a191575008890c5966f1230ab186f019f1794671
+8e619ce8706fd94bf0fb1d6ec22513150c1b9496742a94e048df079bde5d7bf3
+9db82668e5f5453962990f4e3e0245cd2e767c5cf3754c1371bb37bb7e14db75
+a90fcd5de1a7d75748289177ebe65a397762b5b1dbd468e7cbb3fec66a6b3f2e
+8e9a1802bb2cc4506b3ad1632d674f1d54a0c1c08787f274b48d60e9111d8035
+be3af44a3a12e16175ebbafdee5cfce2a9a26cb9826c86207f8ea895e5c2fd66
+216be83f81fa47f39dbaff3789865b1bef63bae463b7d166dfba5e3e9967697d
+f6c91c7dbb765bdb91f4ee5920567a94199416484e75cb6b1c0d1bdd62e831f2
+4b6d7b1009bea14c78ca6b8f1020cb05c9bfd13076d5f335d0b8ae417fa26c75
+d04a28a778d8858e64736fa0a5ba789b58b4d05540ecdf28ee044ea18704076f
+c3c92090d119bc67594021aaa4e89a063ac0e64f2198c5cdb3951c7681ababbf
+6e96666f467a0fdc729efcd2f1d94e193d8fd56802063840696f3eca394c2841
+6b7e6bd4759aaceebdf82bb473d49256e653943469db71794ae96b3d130bf97d
+752a9b3bc4449bb756039609a4f9fcc63c637d8672f2f24dbd49a5f9f5139c54
+23c4a1cba345784f28b7933dd3d2c9938b35e63678b045ec314fd9e9188f1b18
+ca034a26f5d7e2e779cfe4d16560ed2e4f3ac2bf1b5324c6b342e29b5ba3c9e0
+7bf1bff519f91bd9cbd4c198f0b98431d83d7309d0a4b62bcd450d62649e5b41
+335d87c297d288942a637999c2dbdaaaeda4f68d166265a37df001b1a4a5f561
+64a9a7af810851d98af3e01b0e4bbcdf33d3035b98118b48c6452da0caecca10
+228a308a0a3844d57628b2dfd7189f1fd252ea1ce3cbbab7e71329b886cc36ef
+b40f642aa54698e87f4ce8b310f0ee29968ae04de003fbaff84d866e4220b607
+3b3c5fdfef88354a54d4318dd852ffeb9be81630c673e425fd3bb6ddec9f298f
+a9982f8a5859b983bcc09b989f4a71ee4a54d38a220c3ce7491e7d996d8b0e11
+b085acb8f217be35f3eb7fa08bd8ea8c66df8ad00e329ae732ce12801aa8b1a9
+40db1a7b303967c185b90229a1188eeda3a1565dad1c08181fb35ba03667d513
+9f2b6a71dd27e11c7db9a7eced6404cb09250fa0ae2f0fe7fa61147039cb8685
+e7a1566e25b40b1f23ffda5515c107e3487ede0a148f2d8500f102b4f517c956
+87b2e0399387f4a9067ecc725bcb327ba5e98d5c68fb54ac99834146bbd7e91c
+b04d9576bb16e39608c14c25aae446d250b388610b2714757631c18feb700057
+c0022456c9ea28140a150dc6fea0333ecf9c291d95505de3c053c1f957f76a06
+a5e96f792200eb5f1811e86d70c9bf1e0d28da28b8c6042555a27ddd0aa168b0
+0f3c113217d990f6ead0a6ecc4ff4c92c577121d2b1dcbff547c03184360a6b6
+3788919d20302f0c35541b48cb6e926be087b1f7308041dc8cb8f161d8a8bd32
+ecc861efd6ebe16568dd47b82fd1a02200733fef4176a7477185d79e44c128fd
+c54f4f28cee76dcded7399bcfebbfa620a6f5e4df5350fe6005f84541a6e77cd
+97ddcf704455f96435edb3666d9cb57521f35e258eeb2163944c90cbdb3d4a70
+c94b9d3905fff429f16560c6bc44aa27bb481e24d03f29f135eef38d973d12e9
+c251de1d9b976d4d7bb7b4f62dc7a6093d186d240db797432dfb5e71f8fa09d1
+b9b6cbde7b4674bb3f38967091b8b375c0e7dfddc0a206b0d8908707521254a3
+35be48528674c8597822a0a9e9ca84f0b3d2a44ec9deca0db51fa2ef3db16851
+7939ebef52b5af799ff6fe86b0cc459be94187af479e95651233f2515e01ccc9
+57130b01e6e97df375396f8499535a1fcc0dae920db25db41477263a847b578e
+8ac94e59fcb69b97a1ebf8d84e2fab6925bd16077d5a58403539acb40adbb89a
+55623d7e09a8481e71b47416751f01881ece4d94ea9cff6dabb3546ff2cde4cf
+1ba77ecadcd4499637e26c5064a342d71cf50d725c40286ad352bf97e0da521d
+58055ff97c68768b4435db372f0b3d23845d7709ac47b2a965327f62573a8fe9
+e9c5c435ddf12478bcdfde41c0e4303b03949446ec9291c553eebd9add6bfb9a
+45165ce3820af4264dd3b54ac41e4b2df6ede1286973660e37281c7540beb69d
+16a86ae03b8c5ce7ac142585f72a0cba8cfa3c71a54db60d1305790ffbaeee1f
+f31774926a1da96a37574c9a5b66daad0a68adf9f104123941ac4d3342c13bac
+b9b124ec9db917032e3f495107f3cab93d57751e88a5369e27358ecf4f9348ea
+543fb55c0492862ce28cfb1f28e0e5ffaa32df8fdca241db555619583fad76d5
+04ef599f233c424359768f6e8f0cea95774901577277dfd8f90418598e
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndResource
+/F134_0 /MFECUR+NimbusMonL-Regu 1 1
+[ /.notdef/dotaccent/fi/fl/fraction/hungarumlaut/Lslash/lslash
+ /ogonek/ring/.notdef/breve/minus/.notdef/Zcaron/zcaron
+ /caron/dotlessi/dotlessj/ff/ffi/ffl/notequal/infinity
+ /lessequal/greaterequal/partialdiff/summation/product/pi/grave/quotesingle
+ /space/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright
+ /parenleft/parenright/asterisk/plus/comma/hyphen/period/slash
+ /zero/one/two/three/four/five/six/seven
+ /eight/nine/colon/semicolon/less/equal/greater/question
+ /at/A/B/C/D/E/F/G
+ /H/I/J/K/L/M/N/O
+ /P/Q/R/S/T/U/V/W
+ /X/Y/Z/bracketleft/backslash/bracketright/asciicircum/underscore
+ /quoteleft/a/b/c/d/e/f/g
+ /h/i/j/k/l/m/n/o
+ /p/q/r/s/t/u/v/w
+ /x/y/z/braceleft/bar/braceright/asciitilde/.notdef
+ /Euro/integral/quotesinglbase/florin/quotedblbase/ellipsis/dagger/daggerdbl
+ /circumflex/perthousand/Scaron/guilsinglleft/OE/Omega/radical/approxequal
+ /.notdef/.notdef/.notdef/quotedblleft/quotedblright/bullet/endash/emdash
+ /tilde/trademark/scaron/guilsinglright/oe/Delta/lozenge/Ydieresis
+ /.notdef/exclamdown/cent/sterling/currency/yen/brokenbar/section
+ /dieresis/copyright/ordfeminine/guillemotleft/logicalnot/hyphen/registered/macron
+ /degree/plusminus/twosuperior/threesuperior/acute/mu/paragraph/periodcentered
+ /cedilla/onesuperior/ordmasculine/guillemotright/onequarter/onehalf/threequarters/questiondown
+ /Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla
+ /Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex/Idieresis
+ /Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis/multiply
+ /Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls
+ /agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla
+ /egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis
+ /eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis/divide
+ /oslash/ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis]
+pdfMakeFont
+%%BeginResource: font ZOVMRD+CMMI10
+%!PS-AdobeFont-1.1: CMMI10 1.100
+%%CreationDate: 1996 Jul 23 07:53:57
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.100) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMMI10) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle -14.04 def
+/isFixedPitch false def
+end readonly def
+/FontName /ZOVMRD+CMMI10 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 45 /arrowhookright put
+dup 58 /period put
+readonly def
+/FontBBox{-32 -250 1048 750}readonly def
+currentdict end
+currentfile eexec
+d9d66f633b846a97b686a97e45a3d0aa0529731c99a784ccbe85b4993b2eebde
+3b12d472b7cf54651ef21185116a69ab1096ed4bad2f646635e019b6417cc77b
+532f85d811c70d1429a19a5307ef63eb5c5e02c89fc6c20f6d9d89e7d91fe470
+b72befda23f5df76be05af4ce93137a219ed8a04a9d7d6fdf37e6b7fcde0d90b
+986423e5960a5d9fbb4c956556e8df90cbfaec476fa36fd9a5c8175c9af513fe
+d919c2ddd26bdc0d99398b9f4d03d5993dfc0930297866e1cd0a319b6b1fd958
+9e394a533a081c36d456a09920001a3d2199583eb9b84b4dee08e3d12939e321
+990cd249827d9648574955f61baaa11263a91b6c3d47a5190165b0c25abf6d3e
+6ec187e4b05182126bb0d0323d943170b795255260f9fd25f2248d04f45dfbfb
+def7ff8b19bfef637b210018ae02572b389b3f76282beb29cc301905d388c721
+59616893e774413f48de0b408bc66dce3fe17cb9f84d205839d58014d6a88823
+d9320ae93af96d97a02c4d5a2bb2b8c7925c4578003959c46e3ce1a2f0eac4bf
+8b9b325e46435bde60bc54d72bc8acb5c0a34413ac87045dc7b84646a324b808
+6fd8e34217213e131c3b1510415ce45420688ed9c1d27890ec68bd7c1235faf9
+1dab3a369dd2fc3be5cf9655c7b7eda7361d7e05e5831b6b8e2eec542a7b38ee
+03be4bac6079d038acb3c7c916279764547c2d51976baba94ba9866d79f13909
+95aa39b0f03103a07cbdf441b8c5669f729020af284b7ff52a29c6255fcaacf1
+74109050fba2602e72593fbcbfc26e726ee4aef97b7632bc4f5f353b5c67fed2
+3ea752a4a57b8f7feff1d7341d895f0a3a0be1d8e3391970457a967eff84f6d8
+47750b1145b8cc5bd96ee7aa99ddc9e06939e383bda41175233d58ad263ebf19
+afc0e2f840512d321166547b306c592b8a01e1fa2564b9a26dac14256414e4c8
+42616728d918c74d13c349f4186ec7b9708b86467425a6fdb3a396562f7ee4d8
+40b43621744cf8a23a6e532649b66c2a0002dd04f8f39618e4f572819dd34837
+b5a08e643fdca1505af6a1fa3ddfd1fa758013caed8acddbbb334d664dff5b53
+95601766777978d01677b8d19e1b10a078432d2884bb42d1f224976325883657
+05acb022d1e9cb556e37af91917c78e98229e3a4dbf03ae741998542977ad6df
+1760fc1f1a479464922afda2cba7961e9da696b71205e19c542c97f25419c43c
+fa1a042ba0cf5622ffbd3e775d0d564135d99b9ffba011eebc4066b003ce2f88
+825936d7393d05d3804601cee9d123120fdf73624a9d4e361a28e998acec53f8
+7a62a0aee33be2e96542534a8af24497d1c377cd7f723767b44857d94c6cda7a
+c3d6f0087fa36655dd2b81eaecb31fe4f4a2fb1ea9fbe8b83d35826ac93fbb4f
+2bee014f41f8f276510cf5ce35c3954e8cafc521d0c3ab80ea8c7fc29427a1d4
+42d6f6c1800919e58de9ae12304d718ad80febbb412da54153469cd51a288628
+ad109baa77981525b3d9b0efe593537fcbb8520d38cccbd5db171a0385a432c1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndResource
+/F147_0 /ZOVMRD+CMMI10 1 1
+[ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/arrowhookright/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/period/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef]
+pdfMakeFont
+%%BeginResource: font ERVBFT+NimbusMonL-Bold
+%!PS-AdobeFont-1.0: NimbusMonL-Bold 1.05
+%%CreationDate: Wed Dec 22 1999
+% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development
+% (URW)++,Copyright 1999 by (URW)++ Design & Development
+% See the file COPYING (GNU General Public License) for license conditions.
+% As a special exception, permission is granted to include this font
+% program in a Postscript or PDF file that consists of a document that
+% contains text to be displayed or printed using this font, regardless
+% of the conditions or license applying to the document itself.
+12 dict begin
+/FontInfo 10 dict dup begin
+/version (1.05) readonly def
+/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file COPYING (GNU General Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def
+/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def
+/FullName (Nimbus Mono L Bold) readonly def
+/FamilyName (Nimbus Mono L) readonly def
+/Weight (Bold) readonly def
+/ItalicAngle 0.0 def
+/isFixedPitch false def
+/UnderlinePosition -100 def
+/UnderlineThickness 50 def
+end readonly def
+/FontName /ERVBFT+NimbusMonL-Bold def
+/PaintType 0 def
+/WMode 0 def
+/FontBBox {-43 -278 681 871} readonly def
+/FontType 1 def
+/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def
+/Encoding StandardEncoding def
+currentdict end
+currentfile eexec
+d9d66f633b846a989b9974b0179fc6cc445bc2c03103c68570a7b354a4a280ae
+6fbf7f9888e039ab60fcaf852eb4ce3afeb979d5ea70fde44a2ae5c8c0166c27
+bf9665eea11c7d2329c1a211dd26bb372be5822f5ea70d99eb578c7befd44cdf
+045a363056e5e1cc51525ea6fc061dcebb337208eff729802376a2801424f670
+0e7e6397b28f15bc10b40012b0a3eaeb2693e8f7f627c4c9c7c6c5bff105c1e4
+1b2b9e8f09253b76040d268b80719e1b3f5a55ab7b892ad5e69acacc6c1640eb
+3067bfc64938f41636db8831883bddabc6777dee17f2e84f1d530bc76f51c621
+75ec6b727a82c193d1c0801ac492bbe281b46626bd21f2adbbfd144793ef754a
+ea5f1cda3310e83d78a098160c66d6b0c68d4976898d9dc1a08d01740ac3e7f6
+8d3ce0a7e109104248cb86318400bd82ef894efd9c9456e97055286c144d3efc
+d2625110f1ae76241079bec19939ac962e0ba813359c15b07c74d5e9868e2167
+ea1199d21ca8827cddf1be8357261bd32e79fea6bc475577c5f6848345bce58d
+f5435281572ae6b33b53607ebee6f862d4c752aee43c00cdbfd258c7765b1358
+5d6165ee034e5815de79cc26c4a720607bafa6049710ee3782bc2cd84fe2473f
+1335d20a3b6e9e8355af36673cdbe63c27d4f0e183fedab10031b1ee33b9573a
+2e1961b7c6baa41f7c3ee707fe86071ede5756a00d7b3bf0a21b7c3cf41093cd
+66eccccc22f4534912cb900b08e69574b07f246305dcbc238780278aeb8c9e55
+3d096a944ec7aa9f697f354aa137df90a9547efec1cbd568cb999979f5aec6af
+a84edaee1564d178541cf4631081781608fd38964257cf89b1c8e0120b3f6af0
+793597ad553cee5cccd5c4f09cb0b4e998e6e76243191af7e93833d067833f0e
+53670d7e996ed67cfe6699a6e3815932ad272af4829c2ee08a30d3938c928d1c
+e89af71192ec1247ca233093aafa54ffa58f4aaf3fe9c62302e598f4ff8cc32c
+4d318391f7a36d0d8b416dd36d776b301425cbaf82d520141238781111a14cce
+7927e2af21ef837558002539aaeb170fa7e7e37efd447c37db455d2f08533155
+53f3c5c3be4817680efd0ba3a114db6aaba6c4d0d57b09ef8baad463996718c1
+9d155a62d7ae82eae4c82760c594a6ba3c7ee4290f0d898bb3e404ccaa91fea4
+eaa2146ac6a23f6c5a8aae834a0587d990024bbe8de485c71b916ad96dd66792
+a732a188e6a57c459ebbd7756cfd54770e2a8d81bd4618d916a30ec7084b2492
+5f77ab14169547eedfefb6f03c7d5365cef512df194628d5fbea6cf56d0f5346
+b6b6c1da1dd8d8321b88807b579bb6a0c8f69cd919e311b6ade903b470f4e0a3
+dd5015c6432452ecec048dcd14814e47def4a53c5ca6fa9e91d8a28c719f9348
+509c0e17d632f8cb3f7468bb0e7f7f6525c086dc7efb997a60e059d3d4938489
+23e60f7c67fa6aa8062594f122a48c54aa7c049859928a3dfc72752acad074aa
+416c667fcd176da4d7d31a9f6be6f146d4a9dc78f419fab7c9e6c74d40ea659c
+24098088bea26bf5a725fe56025d1fcf8465ed7103702aef74973f6fb697e645
+e902d65354a44bb3489007c555a6a08bb057eca27c93bfcee9de42e2782fed4d
+664ad7f2d238b7eda1ca4ad473bb9559e11a9f214e258ce1a2a60512975b112b
+336864238a36732c3adacbfd52c85a0dc809ff955f9c81401f72107f3d263999
+a69836d76d228ab4f954b00da07bc4a4e165f2dc5ecd8138cc408ac22217b15d
+8baf04408d4b47e55129b0e596c93d10cd42372292e1ff483868e8510076f7f1
+ed8ead1bdee2b49533f87ddbef2abdcbca432307f7ad0b3c3d4721f3e67e609b
+b06f8b7e66af7c843aa1f71bdadf0f4fb6baac84815c8154a0023cfb68282b4c
+8e24e478f81f8d26ef82d6d0e1da4a65478f4a1f65a7dfb4d1700207850c33f8
+148158a784b452ac6874080039e2259431c05c4522f1d67522e273b443ae9820
+adb5303cd0d839ffd17eb1fc6957159a569f64873b4b3bf99349c486a3af2b20
+b6b9c41263300ab0844d24daf780b4f324eda854d4e210daedc0e34f4b67fca2
+1265ea3764f8f755007b62e9e18e80bd30f3b96124065198c0a5985ba2172550
+8c8eabe77b26df4451f5068956fce111041a7d23f681ff2c1b93344fe688708b
+61a47674c318d078fc4bf79217659987dcd1bda1e1b74068960036c472906152
+cafe4a8a702d271a02c790ea3e440e4f415556ec703a23b7aaf7bc50c5a32f7f
+fee6426433e945c28be038cbe5ee0e7933945f052757d480c58d4d7dc4ab924f
+985e054fd553d1c037beaba29b14e823a4091b08ed602a69d1c3eb0fd63faa93
+36db22e6588d3d2fa727916163030958cc89b3ce99ddeda6190f97e039f9821d
+ab4e4d9a15cb5094041790b995d8950412bbf049bd1d8afeb8bddafc6aef748a
+f2523b8313e13f90f966c134e39d52e10b63e30aadca42bbac5962e4e3f71337
+bc2fd40679beb44e111250352f04cb0404158bad9f74416c94003bd12c88d9e9
+5cac3a3eb575733eb44a3c32946dacdb3405f5b4a2513fdf9e6bb2e6e21c5385
+6c527ccc120eaf95d400847dfc9e6a40806330442e1895b53a6188e57c65b466
+da203785fc322efd64f2e6f66f996bf7ca035bb2117648a8857f1b10469aee10
+dd22d785de27f01f1d725b56b380917004a06afc0046335f97a2ff20ea44f794
+c1dfd6b107549e39247a5cb3f9c37af849e9c5f06214a570113d91ad4e14d9cb
+aadf8ef93a933795c0cbfb7204dc605b4b3b95b9fed0372d8df634f7293298a3
+6aa4abd1f212ecd5d4ac49d467567385f80e163b9464f6554e48ff78d45aa402
+b5ee093a8f96da45504e41bfb1a72f579031efa801690a32f4e248a5f773027d
+da3f3721d4fb481fd1b8e81054aa4a700e9964a87871e01f03fe80ac4215cdf2
+7a4944cf89a893638730631261114f8aab967fe29e280124fa8d51fc94b1c552
+db58e038097172d5f634ceafb877d7caca03436cf6bf40afe4dc99ce08d3605a
+78e2c90ffe766fd3ac0e8b2ab247c3f689a55e350cbe80a9a452bf8666d5710a
+6fbbc45e4690afc625bb7a8a29bc17aa582b6e200bd5123e26b2d445992a3a5f
+7aa128c3f6230588c41c6c456655961b823e65d7471ad16f9aea07c2b3d39c45
+726f023ea4780719a3656ae18670daa3bc084e60fdf2ba1ff0204f285d72d9a8
+269430e406cd36741bb227a1aa28cedf9484689a78dd5495337bde66b5a790fe
+4af761c0b505ff974e4c7f67348eb1887b5b9315a7b3455d3677bc77b61d48ec
+f5ebdc73b25eeaf12a6c896a54b499ba5f2897b7da9465c34561b23e0e740eec
+fc7adf944329e003f5266b94a425f3864b167a34d0b9d259fcd8d741c9dc0fb5
+bffb8c8cef470f923d7962cb5806c67763358a9f6ccf78220f28e45a84b0ff35
+c585c18b19c61b51cbe58007fb852e0a92ed6d704f15ff0f863528db72ea3dd4
+3ea0af466fa5b60ac4490aa5db18a649c442a60b4f824e914915376a127dbe30
+85a3c56ef4233579b756eb62e04fea0a55503f88bfdf011436d9d5088e027c26
+daa8165842a4ddd43fc3ab8dadbb4d53c5ba9a5b51f33d505fe3ed168109f1f3
+9ac5c3357e48cd9e3adccf2daaad831000e27307d6cb2aa6ecf5f92cff39b266
+73b1d3587e029313101a9075ab35de260f23f3d3bab5f7a6134fd07c076dcd99
+7bf2e7c40ff0c0fa1096312b791d638b0038138ed5c578e51309444691c1b182
+8b346fe0286e13e3907beda13044177c788b4948a4dd398aa9fc317665b250a1
+3570a783821db58159b825b14c2a639f62995a049eeeb8904226a8f8e14a7959
+731a74dc4b215d7ec095ebe86a3bf07080cdb0dce6d06fcc2e3a57bb04944f90
+8f395bd65117984c1596303c2781e3997bbfb6ab9f354ebcea7404785d8dfb04
+b19a3a6792807fe5debd6eeec1ba9ba9a37473d6c435bdefd5b2ea9c21d9ec79
+0043b5ad1b0a50f9a24594d00f8fd155681c33df8f0c0b3cd5a4fc275da65dfc
+6c65ed8713956bb94b6281a4f39c8ef72b932adf3f6ecfa697ff7d84f93e7a29
+8fab7b48172e32ba7b3135f4a2501961f4a1c50403fc38c715743b55095ecc1a
+38f11f1475521fa00f950776279e8a377fb4ca4870c8daa4fc67efe4db8e37c0
+d56ad93cd334ebe18dd6d92a3ea48b29e7e76eec5e8aa0db20ad690869053422
+8567c4b72be2093426677988f8ac9f7fcde0dac8bae175066a485f3b1d0c2129
+9e38a93996a0eb7a3357ee43bcdf8749bcfd7e7e0a23c7d9e118c4da7fff5661
+07454fc1ab28a875af7e512b2432256c401ea462d9aeb0a2f97270cf2aa8ec53
+1e5248ad52b1b74a376faaf7772e948f433cea2f0ed4dabec00855a394fedb83
+1daff1d977e9b816ebd27801505dcaa51f9ab531e6c1358b275d3a6ba38f4f4c
+528f2dceea3a404a6362e3cfef9d904b573571a4e634d4852f3b922495af19c3
+c63c736d1e8a5b15cfc4da58f26f22be233b4579377227110f8fe5b0df57b495
+2c14d2011b6215b855c36d901f001e24261089f5edd39f7e5bbb2bf90c6f5c5e
+7ba8928434f52689365ed48123414ead2e00f8860e60afb5f59d2715c4ee2b3b
+2b10399ca1c3f70259c63762f64a5a1cb6b1995030a7d775a04cd77a95436e4b
+c3b1f3d1959ded9f35fdd7fcde9b051245446dcac11fb3d0228ce4c012a2f201
+81ec3dd2aa1bd66ec02c93e4784268f754c9f0eba42d27b755bc58ad00e09e04
+e05fd21ed0c160353d2f5467b5903b4e1d1b8666acce06ada99c063c684d8738
+3d338c579595d1e2ab301c4236183cf2c3be0320ee83cde4ea050160b58787f2
+bad8154825c9b29cc14682e15db5f53aba109799c10f25fa2e54560fdafe6c91
+c246ae56edebe0aa30e152b61fa64e517f6cc41ac7b3c25ecada33e3f6d6ee5f
+562542e0e66d9c07aa9889505d51452cc2ee73e3683e3fabe26f003b87d9fbdc
+a376e85ad9547c23e463fa073429d32ca0e58326385a89106d5b72cde3c00c11
+c5f40d1e8b61e6cb1cc6416e28afa6caa469682ec8365081a21d77a8b1df7167
+6344226bb9a7533c0fdfe153878a3af3088e520b94933d0099c2ff89974bf795
+d871b9e5d40cd7aac72a99f351d824f86d33cc89bd70dd41f1a866657bac3a58
+a4eedf997eb49f8d967e148f381e753d5e67080d2843d44a3585e078615bea47
+6c882773d995f4154fdb773a7d9e29fe46e464e602cd206063c96fc51c30ffed
+cecdfa28a951dd5211acd684ed3efd9feaa5aa98b091aece8681999d7c8ce708
+1c64f09e18e64198b841d7824e03de11101493975ecb1b7d556714725a14bdb4
+5d9237ecf693202198964c1554a04ab3485bbf9ff863441da3511d8fe6363e32
+a38a11f4dc6a1ee18bfa3a1c2c93a90675b0c21959054b17b1af4d533c87ac69
+08d0c344fe817d6817a74fdb46f35d3b48b9128784f43a68d809425c6570c600
+9a76199111e88a1c9802de558332000dbb9d1211929d509af5915b7ae8ea1c3d
+d2598f5007de8e7383f7453fc6a9c0b91c80e9b1742bf6418dca69450785fb73
+12dd228889cfbc3f6711a26022b29f9295ee1ca8459305fbf2b93cb3fff5b6e7
+2b5c1d2c4d453f0b9a53b6f361136b1048b30e7c90e0de8edda423e55ccb2e2e
+ee7b502af2baf30a92af542869b8f26ee28509dc01492095e0c27ccaa30e0db6
+3f02f11dc0ce8a94b8a8a7ef735e4fab04830ef077a8d788b224c184339274fd
+5f7b547b77f81bad985c73b05a79d3c8661a9c2b71c7313d8b9cb50ae03aee95
+2dbf1afc9ddfc00d59e6f99021dffbb66acddaedf48df5462fc528dfdafa5e5b
+a039d6bb9bdd1a78e47684a3c53ca307abd566093c2a4f6b9f0be52d4f1f2758
+ec48370eab4e1e6ab393a23358bae52fed3b270124639dd0a56ca6afce77494b
+34f46433cac90eb63e7e0d25de6c8a0670b14e83d08a531cf2148002f9a6df19
+7f87c989b831c509df23057b3ec569eb5f5f530edd047a53b5b59f483703bdcf
+b578fdc44ca7487e3d39479ca4760457e7018af01116b29bbdf7c3e0f5c07a8f
+7f502c15059d9635b7ce630194962e4183c3838d9401260a743d8ebae1665ce8
+73bcfe5d090a8984e98030fe6b21dbcb49398b6905ec04ed310e37cd069a85d3
+7cd9e3a02dd8e036b2a79192ec036cf7e10653e08928cb8bf4911122d27e195f
+48d3dfaa34122ef2df8e023c9ea1f246af2879f5df632719bf7a91f266d823aa
+caefce067bf74ee0d625cf128c3930ab83521380e0ceb5daa2384da4ab23c34d
+0db8a4acce1a33b6deea3581efe521279147ac1b36e4f6b2c08df2b2dbab051d
+264a250a06ed06aa906c2682ad2ecdccbfd880941bd824d021f086560bfbb359
+e2519a2708a4976f42913465e18872a93cda809a85730a4930ef1e3e733292c8
+06c80c8865645c6a69b128b1333c3ac8c616d3e3a0163aba54c7a51a063fbce1
+4018cabe1b1ebdafaefc27d2b22afc96449cd515cced671baa88d51c5c778bfe
+00208127f1fc35db9c6afe4fc91dd0bb1277181508d7b9868a055025c65394e9
+ab7a95494118d20fbdd7ce0b5f11492df5e8c54c1ce1ecd2e7279e07fe6a62d5
+63d7ffd38f04ba75057cf190319634f57aa246f03f5f904ff952d7b1006d43bc
+ce88d89ade52e861aefad538b644942b6b97e778000de2f2ac2b2280d85a823a
+176d8387ca420a441980d3e866604325917f78572ec9ba14a0944e37480ad3ff
+9c10590c0705840d09c8bb076a5aae81b5e315ca901e262b773143a554360fda
+3dc799fd07482666f47c17d8a5bad6efa53f20707869c5fd40d940a885310cd6
+d5ca9c351731fa69fdf0bfb148e17ac26ff43bfbb38c101867ed95d789ed2b0f
+61820249b398fac0c5eee32032984302eb1804b82bad515d721213732ad43b95
+d4a02e17b22159ca29e300042804b75807782b9bda49255cccf4e35c461ff59b
+65e36f6c6345dbb2e8c2f5445031999c2d8f0444cf4198ac17db48199c3b3fec
+02a130d230aba456406e1070178bdaafc422343ed9edbf471c965d2b891586db
+a34bb2d66f98f716e605799f3800c68000941a52d691640583cce11b94cb5599
+29fd0d5e8a9307831fe15fcd232eb361721d0da9e7ce111ff1ebc256a407372a
+253180e51f1800ffb0313c2c3f3c4fcddd59f824dcd0eaa1e59837487288b558
+7f8e6d27954208fb815ed1d54a36476a95c660751a2ce7d475c72ff1784c363f
+a641595eb92e65d9e7bfe18eeffeddfe82d9f6f0cee37e6a9e60b44939263272
+4816df40ed24551f0d07d813aba49a80bd3560188e5d0170385fd15c34b45465
+3d5d59bf7624ab116452ac28dc9217b11c75a08d68e55b10e9567a9d3d8d5da8
+89116318aff25efab611da69e132ba2ff888d68c84c056544c0fe9137faa8344
+4008487c34ff2c2376558ce20108f76582965fb06c2129e607a0e60889d97fac
+2c71a026299b071ea7f9995a542b7e31efede8a4d341210a37f7b4bb96aa7c31
+c873cc0c3edff7b23d8a22e7e601ffbbab0f671b02ba487cf6b588ebecd26f9b
+b7e8de0cbda870662bcca90716c0ff768a9c7c69c1dcb4086f1e881c6dd5b3f5
+0ac517ca096f28b1c7ac9195f99e44d444017a3bd54a68f4588f0a7562553053
+8bfaf7788a7243c30446213bc987e3383913f24b36b33e4b082e507cae63358c
+9675599f6d746305a417fe8848f37bf85f4535e28ddbc5868dd6dbd3148cdc1f
+2c2d224f00c3af4c1ddbfd88bf79eec76e45ef546cae548825a0bca6bf93b0b1
+373af60a7b24a75079d6645d0908a9f55ed0fe7397100a730a6f4e55678714bd
+90c887e46a2c7703b13b1dda74a819b97abfe6275a24e73901540168737a8b32
+ca1902b7577b8761b3c4a6b60dfad490e35d71c5f35d8ef382fe66433336951d
+e4ee981f980168853438755f135c333b8723d5778e2e3067dc73b7fd99aafbe1
+d5a2d1cf443905fb45730ce8fff14674abded9f94b45756a646b4cb1f789c7e8
+0748f3641a22c01b10adbdc77760c0e2a0b9055c4f9107d935f5c2fb2fdd2845
+6d6d2d2096e4baf14bcc8d716adf053bfe40845f02c0d18fccc453f3f8e45458
+69f802f506ca21d0fab24d7f3d6d6c219637a2dcbc58614c1456a9c6b0b0f57d
+09cce675fff4f626b1b68c0a63fb9a16145d58176cf27ff5d3513dbec6014f3a
+2b5de7ce69c8ac2fc184bad23950b28cf0414801764967ff97022cd4865d994e
+585ff2c992d480de31f549f26a18e4721133f3d88316976bdae41431d44ec8d7
+4eacb29aeb132ff49e3c646ef025eb541dcc54f38b8aeb562887ed6cdd07ffa6
+cf3b2f89e4b0fbb5226702068b8043b6e2f284e4350c97a7498e6440bc3c8d2d
+27d8aa1eac980e960613180ae4224624b2c6f92ed4666e391ae5e159c0ce207a
+7433e462cd92aeb67eb89fdcd20e46f17f3d15ee679c064176a2db0ad5c38eed
+7595cf6ab9750fca76e8e5ea2443b9d13da375ca2a2dc87fbd3d81ed58e366ef
+94952cbd918134ea08f90516854207a2fd92799c410ed1fb6a9c36877d0b777e
+ef59b03f19bc6b8fda91ab8ae21c89d117825a1595466da10f20b86d6d223cdb
+6976312c7fb7bffb58feadfcd019bacedce96ec239b5a799005e94bdefb9ec40
+e717a597326b5330f38fbf708d002c9eb8d8ea0834241a35e3a07a58a030e678
+5812bb5de1cb511426cf49ff39647db65d8a7f2f87ca5e903eb1478984abcc17
+c7ee0b1f7d1e9e3b81c663abcce77a90f1cff1b01f116d2995e65cba0b3f1a3e
+80079ece2fc25e0f5cf24507c99e5b6e87a417cdf29a1a8c58aa747afa962c25
+14671fbe467e22931a723a236aedff5676acde6ee71dc9eec11301af96927274
+a732813a49a473edb7e9886b6c45605681a563f32745d60cb4a26a7064406756
+c9add724e9b400097377258e81cfe085b1abdb3a00354353b50c9bd11a6e655a
+d264a203708f739a46e4322a1a8204e32ae385d4f7694d6ad63f975986ffd869
+355b7ea9c0feef8f6d7bcce3128a0e45853de0a5f442bb805166c7906c9f1023
+df70bca683907a0bbc11249670f81c522441aa6fc4e7889a38d15ead8cad4ccf
+e95ff5438d0edc450e6399f0228ea318dc2979e7e5a36eb76f9d81061ec8c615
+217d9dc7a1d0924dd953ad2b741e48357953d43186da75f340c58b7d2a6c7eaa
+3038fa4b66b0ccea51af9610e5558d82bf79a301d73d57b6feaef32d6f19e801
+e37a3c1ea341bee088e322faf9ab5ab1934b70f894853984abd5f34c4d3fea05
+5ab4fc70179cc9f1379f98b3d1f529f3c2aa4ae63b8d2bfd46afdbcda8ea11be
+f32c93eb4d435fc37486a1cbaadc3c98de581ebad18f35175d7b3e67c9194d5b
+bb3cd1918e86daacb86055a548fab07ce7c933bd984eb713405d2b3f48124432
+a88e10b97f7be3a270405594d3e06c17b47719e2678f0f069ff1abfe7d3672d7
+6a748a9e277ffdd25f5477d0c9d60d7e8da9e0ef30e5fd6c70d47d31637bc0cd
+4d67f5ed2b103889a61fd11075aabce9f2517ec9b53d7db5b27790d9bb1e19c3
+d7c3a7e1b95516ee38062d4ea759151e4de0449e6aae79500c42b4efe4936d0d
+000fb3391330c035d9d6b9e25671f9ac599a40c37b2439c06fdfd988abcbaf77
+0e42d324e8ca78613f35ea64aa88c3c43e51cebe8ed1067cad94ea0387783e03
+e76af474f739b9249d1e95eef85ab528e8cd2da99e33c7ef0ee9df694db43f3d
+fe467e6fd1b5291ecbf6b1ac7a25c002dee8be0727ec5439715bfd8f854843ea
+1d080677f64889d70165f1bad110a8baf3885629f8ddbc3d3b09c57dea28b4f6
+7a3c042ce64d636d0bdef920ab5ef9544f52ad533837867c4930fd4dd3213e18
+ae2ca622e0e218b1bd54bd60e01d4cddfc2e9b64c6c99e79ab2c3e52cbefa598
+434213d475b6292190b89be95b3c6660133e1b498bd7ff2fd14aab2aca0dffaf
+62d9df30c19ca0e949007dcf8453e70e60a519674d305523d33bfc3119037236
+19cc4ab1707db2c4984c6d4fb4310932e9ede7808cfc7d343a7fda08068966d4
+7877d7de7c0f5ffbfaae5666be3bdb48de31c5ab6bcfa7d35816e5862bc4a13c
+ecf2355935040fac37141f7bef7e58f7b025e187df3950edfd6cea20d0649071
+442b2916ebce5f4d3ce055efdabf1c2dc348ac0ae6777f679e2f62a0a3ee9124
+7fc855bfc6f0c337a74c44ea1f5dd32ce6183a4c80a6b967861f6101c28b72da
+d6aa1128f196627e24179c18f384e27cf7f81f43138381d177f93f8082cc9d56
+1b3c99f1bea073a1a81f8bcea131e3587b397937c4029d486fe6842a709558f7
+43cd16c8f0a5e4fbb3e522663b82e2544a6fecefd3d8a2b222301fd4988c0136
+859e86087fad63292bc4187412731a966710ca9ccb86329560d64be31ca4b526
+82245c1a487046ad21dd9a270e3fae72fecdcf9608784f649a25474034ac744d
+44e14e72d02ff17b2252aa5273de3ba3cd71a95070a9fed0dff80653b3d346c7
+56119529e5bcb6011d341e368827cddf22d4f99f1781829df808507e2b4ceb13
+211b08f55444e75a005639a20c33706f8985f3308c08f77e72dbfbe049ae8177
+c2da2e62eb58f0fbb369f5bab0fff49f9d4765f931fe66f8aa107d8116becdfb
+466d282527bab6fa29721678837cb46d60148a7fd9cae63d6aa634d23ee21161
+ef9e834520f367903a65bef7996ab77d37ba97aeb2a7a8c3502aac988e7a0430
+9d67a06db4a90714fd1a933402df0830026920bf1f71cb0379bda8714415c9bc
+e7795fa4ebc37e819b3d8ee65375bfdd6b36bda41b7791864389e9b589919ee6
+2872bac2e221b28150d3024a984033899e5372ab474b9b4494f7bb4331b6213e
+7953565f35d2ea6da212956dab01571cbeeef86293c58a259860e294f69730e6
+f141680cf75d40e829f9679e98341fd1e0817cb8e40cd6c4fa691ac691fb59df
+b78e87add951eac41ad1b4f4fa45d2e346e0fa73157a7d2b2df89ea56a80e885
+9e0d0331d216db4f1b95d662bad40e472f21bbe05576ce4a2d27af01880f438a
+30c17bc65fb460ac1b3e01aa43aa3677ba05a437fcca3ce4c2864d99c701d79e
+3a199dbc7e2f00be8d4347f96b61ba0f88e90b49d412d0ed162e82715ea04c27
+af3feb0a7b3e4dd17c875a51e9bbed3c9e10eaabeec0f029d94fa90d60605b52
+2dcff539fbc323e7f0e1cbfc1a192a44345efc070bd5d5939d9f4383897704f0
+e785126abd9f582f1afe88a727784afdac3dca49892c6beb52cb1adee18034e8
+e88a441890175575951fd87594b63751e69165496d566bd23c8db4b9239bbaa9
+ef5058f5b51c74cf70632f88f1a05e1b40078c183ea8433427f63a5f68a1b81c
+bd46625b8ba2cf713c001cca4c74a186f93aaa3869a517dd64f1e81c71823239
+1934faea604cf4d9ddf974fb09c5786bde05978bb25209b5c7648602dd62c32c
+61ec4b5ce1177185354dd5cdf15540121b6d82457ff3111db1aab1889fb0e3c8
+38cbc7a671ba16a4bc567d9cdd427205e8f4de7edc64c00bb6080071130b43d3
+6e7919a5b7c29c68ac505ff107d1e2ab66a3417612ba2f461548f1e72c702a19
+7a6311dae649e46768d85d759281429b97a35379b84c763d35cfd434a4e3bbb8
+4c6e5ee8dff3a7449bec14c785bce1d4c617217ee6315fda000f0c54d1054e80
+c8f9f452daaa465f633ffc3eeda9c76e7a77024eaf39bd5bc9562fa44f3da9ae
+7e665a33bd22aae6dbc1d9efab63741e30775eeffb819ff933342c8e6b978f8a
+2aa20c2f2810072c4f2437e7cc13861002ab6d5ee84a6f80549683a34da3cec9
+e3471d112332ea260153836fa24e22eec0cdb0a5b3b0773cfd237daa67c55aa4
+cbf1cc30f43183a93bf7d7068ead32ac8064bb1f0a8bb61cf5472bcab360cf71
+b61c3443eae4f1ec7fc0d883559f8a2ff2522dcd7dad5f395e9ab2454cca6dad
+07bb58bdeb1e54f75816dabea8d170974909b2fad53f9a69d97eb11ff20c6aef
+eb6d76e9fa93c317115602db90359be638da383d9e01f6bdacb5ac5bd7c77d42
+d80646ace9f2384774610f63f97d70c4e81a2871be0a5b028c88afd82a3b6376
+5d5064a6786a829a6e6320120395b1541bfd6e3ec182d50982d7bec4140f146a
+06890a79b85a6f20f9bf616f5f56e02752c5d177a48aa2f8ecb67e42e2314850
+d2109c0965a55d1e0f470371443991f9b8859ac70bd6f049dbf57ccc8e2e3c67
+eb8d1b4f36c660746008460ebc0f7284c802925206b968477a503dfa6879794e
+7ed82fcc58443fa1d95fd561bc9d3a2ccb2bfa19916d8a88e6f7eff0ce0a7d4d
+90c77f63bc75f3368f7a97dea9d9392e3f499ae4b8e53602636cd53ebdb42213
+c2668a3c618a76f6f5a96fc33c0e41ef620a63e3c52512c66b59f810c6b85923
+d81ff8618f42ee19b10d4d088bd6b784e4f9bd6bffe083161181b2f79b374fd4
+b846650d4b95b6c3e58449d8f0a201aec72d87588c54fbb3112045040109a3d2
+d98c778ed3fe07f54010773b628baf29ad3b91072fbdef7cde0b969d0b695bf2
+5d386c6b8647bfd55c169374c57d5bd8fb29af5c5a6718d7cee318a06ad35d96
+fbf879929e28bd43b583aff2769688e087b00ea95b28629a71c6ea847f988357
+da9e23422fe2ebc4c33f183679233e0d1d8150ec58ca6ca0bda2a529e6f6d146
+92010b1eda6360aac940ed23410455209383b68c3a1fd68a0ef92d16cd4deda9
+9dbedb1ce18a79817fb3d043f919f1b98c62ecc70dc27886b258428ae2d1075e
+ef8c1225f96be5ee3c1b4e127d26bc2abc6d457333a0d5cce99dff00f3f41e0b
+a9fd7bac9e96691cd316abe913a6edf95c6c5d37086cf3cb960b82684ce473ed
+574fd8c6ca059bd679441c22e6c39376d3a33c8011361c834bbd7b87c345a9f0
+c6cc1328b5af926f763bebc13be92238da171124de119a097d65e5d623cbf157
+a4e93e250a6bc34bc54feb2889da3f5993eff0bf38ef6e440d0bdb405746aa70
+4e5de570b0347d52b25ae9e0ffd758b8d6da1a57e47289a26d0ed30e31474273
+c2315c74a39e6b26f558dec140d384cd3bbd7246bf46a0f7becce45fe0c343ce
+78016204e814dccc58061d48ffc808423452985b12d28c94eaba89eda793f7b2
+8d9fde11f30434bdf73c48484a814ebe541f4e6eb817de43146ae4e04fa7129a
+ec0e4b92ae22a1d2344375f68314d839aade59c4ac1d556538fd7a9f7ee9a139
+f3620952c6c45f7181a6448a807a1bf62cb59f440199297cbc8a360d0168c153
+7c6b3ba56dd0f7f104271138846a6f305f2c8a7536512c54a1c46232606a6649
+81a8083d59a4b5e8ca2cd0b70dd0b44bef1c2ae9ebcbaeecbc7c4bfb2ce309f7
+830ba06f3c8e79fddf737451a67d8c4425c51e11f832d99198c16dee864b4c9a
+e48863f5a3cd0e6f3c5b31a6bff527bce260aefbc40b1d8065d2f88f97dd9ff4
+8b21d069ae8cebaa511f0d00c1da76207821859bb191d5f9261adff3e6417788
+5b493db49420f472496a8207d3f2d64fa3304de0e78d6259a626d8fdf81c51d0
+f81ef8c619507f0544ebd3aa8d1f200a5ce240a1171441438d6bbb19c0850bdf
+4a0147baf4787513752e4e052a09d6b94bec96107e64f6b2692bedf2a38863e1
+15ac2564c0eb10fb923ef3d505f750bfb6407856406cc92e9b2a3a810fb49ef8
+e8f445c2e32b30d352fba6fe345c8af241307e76c13ed376554b857b23f2b10e
+9f4f1d6b25ee850d744332fb73349790426bc3adf811998f84f4721247ed9dc2
+cb33d343ed9fcbdd001d97708408a4885ef05908333546167859788124f50eaf
+7f9cd5b7a9f4a77b2337f51569fe3fb45e41dc50394ec963851fef76ed67592c
+bac68e378043d77137974cb61772228d63d46d92821662203dcc0dd1db375bd6
+95c9153c7226202ee545aa36b0bfba49bba59e918e3bcad377cb461d52442b9c
+d159764090efaa0a887a12b0c9884d4eb0cbae8b2b5fe1d68b8b13abcde73223
+234063907a8012134dc42337f131ce012a98e582fcc50c9507c1f87b83d62dfc
+bb951dd48c3fb078aaebfa25ae1908f87d97915d86bea53e23c2c4fd426210cb
+a517ee3681183d327a5ab42c02977c3221213e76ed5f986ad6bcc14f50651367
+f142a4dc6379213974fb90a7be
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndResource
+/F392_0 /ERVBFT+NimbusMonL-Bold 1 1
+[ /.notdef/dotaccent/fi/fl/fraction/hungarumlaut/Lslash/lslash
+ /ogonek/ring/.notdef/breve/minus/.notdef/Zcaron/zcaron
+ /caron/dotlessi/dotlessj/ff/ffi/ffl/notequal/infinity
+ /lessequal/greaterequal/partialdiff/summation/product/pi/grave/quotesingle
+ /space/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright
+ /parenleft/parenright/asterisk/plus/comma/hyphen/period/slash
+ /zero/one/two/three/four/five/six/seven
+ /eight/nine/colon/semicolon/less/equal/greater/question
+ /at/A/B/C/D/E/F/G
+ /H/I/J/K/L/M/N/O
+ /P/Q/R/S/T/U/V/W
+ /X/Y/Z/bracketleft/backslash/bracketright/asciicircum/underscore
+ /quoteleft/a/b/c/d/e/f/g
+ /h/i/j/k/l/m/n/o
+ /p/q/r/s/t/u/v/w
+ /x/y/z/braceleft/bar/braceright/asciitilde/.notdef
+ /Euro/integral/quotesinglbase/florin/quotedblbase/ellipsis/dagger/daggerdbl
+ /circumflex/perthousand/Scaron/guilsinglleft/OE/Omega/radical/approxequal
+ /.notdef/.notdef/.notdef/quotedblleft/quotedblright/bullet/endash/emdash
+ /tilde/trademark/scaron/guilsinglright/oe/Delta/lozenge/Ydieresis
+ /.notdef/exclamdown/cent/sterling/currency/yen/brokenbar/section
+ /dieresis/copyright/ordfeminine/guillemotleft/logicalnot/hyphen/registered/macron
+ /degree/plusminus/twosuperior/threesuperior/acute/mu/paragraph/periodcentered
+ /cedilla/onesuperior/ordmasculine/guillemotright/onequarter/onehalf/threequarters/questiondown
+ /Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla
+ /Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex/Idieresis
+ /Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis/multiply
+ /Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls
+ /agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla
+ /egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis
+ /eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis/divide
+ /oslash/ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis]
+pdfMakeFont
+%%BeginResource: font BZXIEB+CMSY10
+%!PS-AdobeFont-1.1: CMSY10 1.0
+%%CreationDate: 1991 Aug 15 07:20:57
+% Copyright (C) 1997 American Mathematical Society. All Rights Reserved.
+11 dict begin
+/FontInfo 7 dict dup begin
+/version (1.0) readonly def
+/Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def
+/FullName (CMSY10) readonly def
+/FamilyName (Computer Modern) readonly def
+/Weight (Medium) readonly def
+/ItalicAngle -14.035 def
+/isFixedPitch false def
+end readonly def
+/FontName /BZXIEB+CMSY10 def
+/PaintType 0 def
+/FontType 1 def
+/FontMatrix [0.001 0 0 0.001 0 0] readonly def
+/Encoding 256 array
+0 1 255 {1 index exch /.notdef put} for
+dup 32 /arrowleft put
+readonly def
+/FontBBox{-29 -960 1116 775}readonly def
+currentdict end
+currentfile eexec
+d9d66f633b846a97b686a97e45a3d0aa052f09f9c8ade9d907c058b87e9b6964
+7d53359e51216774a4eaa1e2b58ec3176bd1184a633b951372b4198d4e8c5ef4
+a213acb58aa0a658908035bf2ed8531779838a960dfe2b27ea49c37156989c85
+e21b3abf72e39a89232cd9f4237fc80c9e64e8425aa3bef7ded60b122a52922a
+221a37d9a807dd01161779dde7d31ff2b87f97c73d63eecdda4c49501773468a
+27d1663e0b62f461f6e40a5d6676d1d12b51e641c1d4e8e2771864fc104f8cbf
+5b78ec1d88228725f1c453a678f58a7e1b7bd7ca700717d288eb8da1f57c4f09
+0abf1d42c5ddd0c384c7e22f8f8047be1d4c1cc8e33368fb1ac82b4e96146730
+de3302b2e6b819cb6ae455b1af3187ffe8071aa57ef8a6616b9cb7941d44ec7a
+71a7bb3df755178d7d2e4bb69859efa4bbc30bd6bb1531133fd4d9438ff99f09
+4ecc068a324d75b5f696b8688eeb2f17e5ed34ccd6d047a4e3806d000c199d7c
+515db70a8d4f6146fe068dc1e5de8bc5703711da090312ba3fc00a08c453c609
+c627a8bd98d9e826f964721e92bbdc978e88eea0a9c14802ebcc41f810428fa8
+b9972032a01769a7c72d1a65276f414deedaf1d22be23f4705bf5ef31b6a3b69
+0c896320f09e9875b50220a5bdbbd57c041b5ea97f421685a7256b0d9755edbe
+d05190dabf1c3dbf558258163c8231d89167a816bba55fb1f14ad04320ae381d
+f783a9eacee8ae5c1838775fe2380bdd1f3afcccc96d2a2dfc999b52a6689c51
+af82b8d63205b339103134dac7e3c45e6693940276041bb07ebdb9b729e8ef0d
+ee8bf450fa42551be65217fea902e28decc09580b504f0f52f1e8fc5ce7ac28d
+c4e47f908fdaeba23827a97a0aa741aa7708f7bbfec6fa69cc4f7c3bd4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndResource
+/F564_0 /BZXIEB+CMSY10 1 1
+[ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /arrowleft/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+ /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef]
+pdfMakeFont
+%%BeginResource: font WWWUTU+NimbusRomNo9L-ReguItal
+%!PS-AdobeFont-1.0: NimbusRomNo9L-ReguItal 1.05
+%%CreationDate: Wed Dec 22 1999
+% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development
+% (URW)++,Copyright 1999 by (URW)++ Design & Development
+% See the file COPYING (GNU General Public License) for license conditions.
+% As a special exception, permission is granted to include this font
+% program in a Postscript or PDF file that consists of a document that
+% contains text to be displayed or printed using this font, regardless
+% of the conditions or license applying to the document itself.
+12 dict begin
+/FontInfo 10 dict dup begin
+/version (1.05) readonly def
+/Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file COPYING (GNU General Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def
+/Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def
+/FullName (Nimbus Roman No9 L Regular Italic) readonly def
+/FamilyName (Nimbus Roman No9 L) readonly def
+/Weight (Regular) readonly def
+/ItalicAngle -15.5 def
+/isFixedPitch false def
+/UnderlinePosition -100 def
+/UnderlineThickness 50 def
+end readonly def
+/FontName /WWWUTU+NimbusRomNo9L-ReguItal def
+/PaintType 0 def
+/WMode 0 def
+/FontBBox {-169 -270 1010 924} readonly def
+/FontType 1 def
+/FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def
+/Encoding StandardEncoding def
+currentdict end
+currentfile eexec
+d9d66f633b846a989b9974b0179fc6cc445bc2c03103c68570a7b354a4a280ae
+6fbf7f9888e039ab60fcaf852eb4ce3afeb979d5ea70fde44a2ae5c8c0166c27
+bf9665eea11c7d2329c1a211dd26bb372be5822f5ea70d99eb578c7befd44cdf
+045a363056e5e1cc51525ea6fc061dcebb337208eff729802376a2801424f670
+0e7e6397b28f15bc10b40012b0a3eaeb2693e8f7f627c4c9c7c6c5bff105c1e4
+1b2b9e8f09253b76040d268b80719e1b3f5a55ab7b8e134d4cb5abced39ac635
+da001e9934c198a7f9b9ed0028a85e9ae00421dfd8eaa3bb3b4b4ce45d209303
+237bd51809fe4d880900b1eeb236aca87b9ff6ebe6b994a60af5d67ccc42bd56
+77295c346eb4c62bdc1ef22ee07daad928dfb73455f091f32408ed6430b97417
+683af27a03718a156e3f6e7b6e4f2e8177503cd82ddbf4557a3ccff4c858ae7a
+f7efed6cc521a28342436b953e4650b5792be85ea2f989eb6d986905a61fa38b
+96e1bbc830b74469150fb0b598a794fd80d10870084a877273a9502c3456e5ef
+74350e6e3be5863e8ba185eb59fb87b36566af71200b6ed389d1287d4e925e33
+b2383ed05d87d48586e698fbc5d562ed9d8a09ec3eaa1b1f300224af20c23f26
+a2eadc74562571da84b3914d1d80b127c6ff4706c7046bbb372a0013e0ab94f0
+c27946583871d272bf4f20fa84e89d745de7bba885cc09ba72e0f530ed4ef7d1
+864b3c67007ed98800284235372f0a70c912e21e851afbf812165b8df912cd1a
+013e271f0b347967876c68ae4c4107ef8ad1f170916210034c66394a9d971b68
+fbfc1131e37fc178eb97c1b2a0f573add9d7c0bf944e6529734df8a7ef54485b
+a3375cc30e9e328943733cbd352bc15b06c85bfb4a96994291c72a0eae84fb01
+0f1b24d0125fb8c16d60561df8bb7aa7ddfe9549afb70c1e89424214609fde41
+9a142892e30f02754fd234ceb3c59a2a04c06bab7ae40e8fdec50559b8347684
+391c750987802d5452c47c1e0b5f222de9a0eeafee19d796ff375a1e1ef0aeed
+1bcac4f485fcaee18aec585d1a9d80f41871dda45fef1eae82c5893118987beb
+4d9e345c27c7419fe65e4853b40537d822e34ff1e0bd2819d21ef607981259e8
+9f1040a2d708d7463858aa5381759ac49df4dddeb209a278fe60bd2508aca0f4
+6a249a05b652e4c7bf1b676943cdc4602910fa3ea7636985a10f637832a5abab
+9c7a580d605929d6d7154506217252a755beb8462d30a798ffa9b26e500eab24
+7e9fd612c776ae60423995dc1852686cb041e66357a9acd4b6a4e9846b1dc803
+23dab6b7765205d82b50cc6394e725c19df00f7db427341d514047e4bc594efb
+a262eb2c414e43d8acc9cb195d12f3b2a9748f38edb3ac3447d27d20d1e62bbe
+22f6378e508f0cd6f17ef1c500407f6d442e92ef2e00b8de78660d87fd1c7209
+ea67cdb37076e1eaaed128814a948e27e1f2fa81fe54be6c57ef8c2b2e460f08
+6ff1bb529c9100b1d878dc9a077d21805e89d8b0fbc2a074e4b55a869c96fca7
+8117347b9cfa480ff4a37b34b040a99fba99942bd86ce4b46ff5c69babca7a3a
+f5018da05556bff71ecc844b2b718598f0825cda3d19d714fb66472621113ad7
+bb240de7dfbd1f17ffd8f2ef4b85a8eb6e1bfdf26c7f98168197c02c4aa535c2
+0f9ef9b7cb7f1d174b2e94953f541c3b84d43366e0e00a028b98f990b4d01515
+3ccc2e1853473bb9b25857e4b8f9d6695ef332bd3baa9ee551a4b142defb7f03
+97cd075ef9cd41082ccbf63e849c48835e105923e725d41d2b5ee0c3f03a603a
+161713216af97bd21aa87e3a80d75383603152011530b8abd2294d041e90a040
+f61baf86be97f8daa8326eb1a2b4511425785f35f75835683515af6cd0e73194
+2b25d5fa8c7e12ccde33aa193d61a35eba7f7e101843e35dfdf3e07a1442b0eb
+f2a9084634736a21128843df49c84b1061d0826777a754076c4c3d0a68b32dba
+ed4b5c0746ddecdd79fbcc7a4425eddaa7f49257148f05ff52ff6bac71cb65ca
+8ad5869cc9fd7c4c194ae8d5d20a730a035234d8f9a6363e7a49fc22bbd34d08
+eb7fd43a678be52b95eccf029a6b18a512d30ceb0b6adf80ff1232dfda1a5752
+b5222edd9012b45cf0df0644b2e713afef21255a08232efbd5d5f7506bfd050a
+f0daf55b5db595d29361f8253c26c37e09b4f87056edd8c90e0df4fc74072541
+8ad8ccea562e4ce72acc8e9f39284fca274c572ffec24ba30ef9db07054965bd
+2205d717c9b3b0723061cd74ec688b915ab6689904d5762629c891f2fc0cdfb1
+8d8a4d2260dc93d7ac1107b197d7e8418bbacfc660d888697296b7cc6581024c
+e583b0114ffe3b3a960d601ff23c0f633e2b85300042f717c4718c0547fd9b19
+e74d0e18f6908e4528065888c136dc8767b74025ef5faf470a272f57f548d738
+c5d2ff6def4366c1c08e0b09855e04ec3bbd8cb6b770f638ac7d852b7b2250f6
+cfbb5669c9112fbf73546a9c1e968a1e1a06128efee6422e41df1519c7346635
+31fea419bba8067c6d0e964143a0906762197b8de95502ae9bb54ced17de5ce8
+9d628716bf1e306aad09bd7f8cb2b7dae5bfa9ef53e716d5aa2ca014eae837c6
+c0f2d5f535ae93682e855b1bdd6ce955627284a4712f67c1d6de9f80d4dda43a
+9fe34fe4fab544459a1dfa0d1383c50bb3e6c3df078acb88db37ecb38aaabbb3
+cc59d3fbe6a84f1f9521b6e05d0a0b2e0fceae8eeea4f41976945501f32bb383
+455467d21777796688e57ae9b7b392d167b63bfdc1102565649b53694f1eb3e8
+5ec2f094ab06d427b5e1e7412b3369336c766a7fc778190dd5aeebef9b6a034e
+133314cb512667f1a4eef90a1251ca9e8aaf7966ec96004c09c4dfacbb0d4c45
+60d8df4183d3598fb9584a4433c9131f8602474f27e4916b43de80ed1d02f6e4
+d208b014c0a44d94ef709930eca646b2f07d8358d48d0a768b6f13492e3cb877
+fe38c58a7f5468af52ffc11b8c02bd91484cdc022abe678a7f2e298a7fad967a
+2ea7dc427e6ac154766ca4ae15fd414a76064823f3145724184e30ec4f1494c8
+78f7f63edea60daf2448de8a79801ecfd86a06ef122451dd2380bb1a4256a7ea
+806d131e66d5a6e3079f7c2d7c143e2879f5316ffebb1bfa166a088b8fa9cb7f
+4a5f0875a8ff5d378e9e8205c6155ea85756475ca5149eb72643b4ae1f907c0c
+fc8f63150cdc6209b1951af23ff68188360939501770eac39ed55dadc4dfb1c5
+b2ef39c93d0326a804f62e8f187a224444098835ff670ad55b49f3cd0aba2901
+293ae04427916ee14c81f4044a05d9c8ad14ad4b5567e8e0147780a0bd294c5a
+10a50a5cc7656f901588419108d2570e804a5e590004008776c8cf20b56d5ef1
+fa32538c480bcc1955321f954008871ba180177dea952fefec536f6522582647
+bc205dd139a18d2a41956baa4b002169cf042ab2ebf91ff203dc2e2559171910
+2119e94673a275d73f3909d0834b170e2b62beedcca27afb44a35ac51dcb5719
+82706f101b216b4af3523974378a05c327702b132335ff288adf62578f30cdcc
+cf826898361bd49238f368ae2182fbb631e375e903ed9efb911a047119b40830
+a39909494e86aee21694223df1a57ac8e5b4f0465d0868939ac77ccb448d3f58
+36631cebdc06bf2865c58437568cd734efbfa870214853232ccb48cc57c8c32e
+97cdeb89cf5e0c032e81de377b368f7d57187f0828675a52382d41de6cd9fb52
+2a1ccfde3192c650fcd7d1f86db03c401e6eebd0d40bf23c10e021ed66bc5b7c
+ae57d0905bd24925c8573f069139883bbde13df3ae05bec1771eddb9b003555f
+9d69657ac718c065a32ef7ca8a1ff5880fc66196e8123050a47ebe4dd5c1a4a7
+40ce1cf340bf08021fceef8172d9cdeb063f4e4c2205ae4503c71aec1836f9bf
+96ccd0a712e33407446ceab96221d7b3f4342fc74aafa802481acecee7243807
+390b2d12c844193560738e576d27b0f5a90b25e1b5a27de8a2c74b3303526191
+5ee0251065475f26bf0bbca5549f13e1357797a5728b46ba9570c095d938112c
+b3ba212c26cd6bb569ea276e1d8397569f8d4c78528490187a172d2e30dd0228
+d69fdaa25fbdb477c88d52f0ba137280d68656036c17b8852b03c21621d0b21c
+6c016f18cacfa9a998e972f40eda07278da54fe5119babf0145d6824f051cd63
+91bc93472f780f00e261dc74d6673da37d8d9291e25af279829f8d47bb524c19
+8b598ce1c576ac8542b5ead99b039ac2996a6d791a22a5d5bb0fa3eb65d1fa01
+401d5c7d44a9cfe082e9314ada6f4ac8ecea5be8e5a1cb6a1dba1c615e69ec9b
+0f231b64ac31c545859f0195bb9b403121df7be1ea1488b413825d8e1d7afbfc
+e5a8e1e52d9c3ea6de3ce75d013cb7396e825bac3a50d0bffd2d30c6f1c5dc0d
+83c1b68dd8b6042382285812093db4c5d7f6eaa8a4acbeba794f63610456a641
+42fdfd0c4c5f0c4486a6170b7701ca64cd1408f686fbd2afb56ba307722b2bba
+c542123f766171b43aae5ac053094a04ac4faa3cbdadcec81ab5aaac58d3a7b7
+1dbedcfe63d062b11dbcacefea89c6f8916389d3f7d93da89ebd8c37414c7db6
+d6512a4e8c76145ac170faf136a023b3c31cbae9775e436d6cb2835b77b56458
+6905d558a3cfab0f1f3426557a66bf775292df056cfaaca8c087b4c0bcc2aae1
+fa49f346602384f743be6b1aa26134ba2872366c17f1dd356221838a40be3a4d
+0b8502a964d360ea9bc58e4ffbf283c8294679197faf5d23aad1c89c3da84902
+c95619fa0ab76ca0c7ae725a1c5d9c40e84cc84eba8fc95361f3a738ddbcb593
+b3110db2f69ecf9da21d788d36a1bf986e2dd78c9e62f643e6677f80991f90a0
+8bd35484fc4aef3243bc3b460f57bf6f0a503b57f84723738e1b94c3029520c1
+f8d787f99305ef87fe64293b5fbf0a378306459c022f4127f2e2207ba818aac4
+1c860b70833b92cb7228ab2c8f68d03b6ecb67d4f83cb160c170298e1bff339f
+306505ea4fe86929f115b3c55c7fbdb7f09eb38f7c8ca86c9c89d9b92dae37a9
+5839a181e6e55835da3e81c8846980ec5c16646a31bbffe54a8505e005c9200c
+cb2b476083d7e55e63648146e8e615d349ed779b787232605beb38346e3578bf
+d043797edc00f6df91c9a02958ea01f55f00d576c8a8d236e81b59eaf96bdfe3
+4de4125a3893acea97aa8d6373b736d4cc0166095bbb75b7341f06d8e3fb732a
+5539fa8a27abc1d82f1a86a76870450fdebbe889dd048cbf2f184dcca5377649
+9ca0053aa9a88ab4d6f279f8a3ba704ed057dc2a361d07e5af6c9c8ce4b08c05
+d06635afce1cd7fb1288df9ca1f9a556d1a120691297d8134214da14db45cdbf
+5545abb75134d45257b1e373eaf23fb600370cf8e7de02e7211639b11f8fa0d5
+6627c5718f554ca3351ac95c04dbe894e20692065af2c7a9e239449df4a65917
+2e0fa2bd3ebffbffd9093569851a31db46c8c30c1fb8339a7f742a2c89212831
+15459844298972b8b06e2c699d6acaaf331a023047e5b2041fc39d830b0851a5
+8ef1e329b688034f9c91927cbaae2ec2c84f8502127055ade448d6dd7eea3aae
+392dce03347141b3b85f3018b3396b9fb1e4a59c50d9e8b82610088575eec663
+5686e7234e72e4690ce386fcf9d16b54c9c692e9324427dee7e096b6d4c45501
+da2d0eda66a1f29e90c00fd2c62ae43a97f611794c4704d179ce0bd63ffc4f50
+ab3ca7086bf942283fb0d175888a13e5278aaaa25a26e3df4fbf13e64519ad94
+44af171207f3f89b369ccd6162c0ba1320d30d3a596d9f58976f94434c1fb773
+e70be87528a9bd5fb7e494e6cdba0a3cabab8dc2073ea7f5b956bf5d5ca1b258
+25a73e0824ce8d00f4c945c0afdc4b57f7c0162a14b30154b61ab030a73679af
+d43e322a04fc7b3c814f3b2d07585eae6a5254b43bc836c6000bf23a56fbfbfe
+8478f1cd00150ee39f0aad2c7ae3313b8d619b84ddd8cd3878a4b306950873da
+9a592f520b7d7e0cf9b9c97d35139eef9c329763869e64d89a52fed016e1cd40
+4497359d9d4d6bb70222418282cd9ed7f12c16cc1aa6b3eea9c812b7c3910209
+2831b0f05e644f58e878c1eaa3d587c89b26db8b9952e0bead12c7db6aa5a042
+9e33012db0551fe6a589baa800905a7cb35d220efbb675a96444edd18ad89dbc
+ebc4087162e977b4cc680a0e3490bfaf28a556c3bb9299935097e3e048679849
+a85ce906f55bdf564f3cca2b0a70b404d02520b77614e577231cb2310dde1ba5
+cea1ef926ad191c98a21ed76ebb8f407ea2ae2ff56014216abb118c0218590f5
+f3284f9a187a85b3f5091f05b21d747f6fe7384a27ae6a8ddb923df4f61900e9
+adb8be5d338613e1486d710e892b5b733061951d164ae233023a69e02457e90d
+dfb6d8a53ea0a57f3c9e27614633ace3c6cf57dc8c81d0c079642c4a0745d281
+2bc6ac4587a56e65d6955e50f4380d94f9628c130102e2a3325d694865a0dd90
+01ab118f393fd86d01aedb5612fcb49e8b81fa6fadf7b69650fcef45a0a724d9
+ecf8ced5cf56913fb68a39c71350acd855433cc25b25ade198cda46bfccf1fac
+f1c841a1e6058a73e26e580cb46384885c417799d92822689c2f58bc1e0a040a
+9d7d3d73de3c18688d62581d54a0eadf9deffb3db34a9f052bce33d5fe8e8ae9
+78e4b0bdcc2a8ffdcaa5b4c0f4a0256d94364e70e1749dbc2b147d69ec539b47
+ef868ac4807f7ac1f01c93b3361942915581efc754453f221f4a70bb903ec310
+62cca7ac392f6f70b61f49822cfd65c668070babc1102322e4cf224902f0cc6e
+26bb2c119c3c66434f4a85164c49ed51084a1f0795eb631f6d38123619cc5ced
+c8c6908f380a4a3f7939d0b03187e448fa44333ed8d8c2504c3fce0235795d86
+f7a7bb423d1a7ca81b27b4f81c93ac95ba336a0d8e6bb90c96ae775ee34c07da
+5cd019a73b7944424d242dd7d96ea0349307ed426fe0c7fb8b5cbe3d295a3069
+b975fafbe78109cab35ac2fa5154f66af9b9ea522cd4847408d1ce24cf7fc770
+4f222fedc962ff21d09aa2ae6cc1b14cfbcab5d0016607362d3c8f6347f7a54e
+821327ddd475396b465b1bf5894703c6de1e9947e64867e68efb2620c7f46367
+c0c345f294b781943f0c96500688a08347b0272c60e5d6a7810a44c4e5654d09
+05931a57e1fe6ff7edd1e77a1e1c39070b49e4d72a62f06340f9a76d0553905b
+35e5711434d25cc3b14557bbaf66a82a6ef543bbfd14c314ddee0ee99090482f
+c1dd06eecf203ec9511a3ad6ccecdd1139ccf31dc72e407853d159c1622131df
+f560bd84c30c58439b06aef79bf53ffaa90ab3727e59f164271a69c5bf36f0d8
+3f9c0099933b6bdfc2f613d4f3565dfbd0c85e8723491ead13697f8945f63a6a
+612990613b54bb7a19c1d3a13c14f19694e3b1293293a51c64ebe436738eb61e
+2ccef09ca77eeb35c7bf10db2a9b1eabbe4fb88ccefeae6359bf5e136ee974ea
+a1a5c7152d54de8dfab89422943ad50e5884f330ad4078763ea071c6265e555d
+a610d246133435db11c37e786302e3e8889ece1d9ec3670d82babfed7be2fb7e
+fdb78e1b6e1c682b930f48bf0a28301b463a5ca77c368f7d57187f0828675a52
+382d41de6cd9fb522cf52d8792796fccac48d9528d6ba65cca775eea0d9e272c
+084f8017bb4ff779b615a46518b256b2c43b27e28b988bf6b60d783d56905a5d
+7794904c0cb95e2aa83512f47d2c393b778b7611053d31bbc4670c6ffe45ff25
+2b7064e4740e8895169607d57c89956b526a664b28a2a9f7c42d6a40c4a95aa6
+6be98967f52a855db02c498f141fd6afffc0a69b14bbd009a0c0f023d4d6706c
+cc05401aa96d550b6ce0190281ba4cebf16acfa4fd94730cd977d6c120c124ba
+ef8489e22a13c30552196e99046201ccff11cb3aff92a63e47a10a3a6433bfc0
+e77047453b71527f209c939d8516182ca5f0966ccbf971fede25e3fefd92cf8b
+fd11ac59dff36c25aaa8c771a83d9cbb7dccb37f4f7572f11f702bc27ea9510b
+a2d4baa94f5953beb927aaf2426421f0093c603bd63827e28f17d57cef476577
+c1f13eb8beeada42a1eb221cac3dccd5d84a6f74fa2b289c3cab6e2fc94dd92b
+d96a015b218ca7facbe18f9c7a580610905847a649e4477773b87686f7f28b33
+24148f4213ccaac483b43be2a9763fdbbdbbd50a0f9d59fc31f5b7b2ac0f915a
+89abd64d84faa62a4c3167fbbf651a6236ead6ad931c11435921cbdc4ed66f67
+fe83bc059fa0c625001ad5b3bf638293646d33076f3afafa8b8fd7307da5c53b
+5845999c1624e9ed30cd48483403f9afdabbcbe80fa5025bea2cbc081e2b32c7
+42685421ce3d574a414b340075cb02e80d7427d4cc503ee02f5b33e509d76e0b
+21b5d5a252757c4b7893dd9870f9371eca57ae78ac688ee28c31d597bc018496
+3fa54a8e160a77dc8b0627d7319885fb2ae0e2e2c9fbcde4b5a7acb04bf1e611
+b73b0dee3ac8f44c4ca15dbeca20c35a7a8805f3c22e6fba8e9b22722dd25ae3
+ba2dec2a0c9a13509f4c9fd3dba03ef6e49a632bf7de5ec45b64a1f4e3a36976
+1b7a9c7b95bd29b09b930b0d82f2c39f9bc3c24d99c58a664d4adedf7b74e13e
+6d85e03e615a60a2aee9f790c6d0a2e6e82e6840e51b38c4579fb95337423fba
+437d97ab42bafb1097b2e2952e86c88e94ba7020e83163b5d810de8f57625819
+d86d7ae834d7135e30f2e21dd061ff15f22de6c9243d2caaa5abf67abee3a6f5
+306273037adcd10e8f00818ee88ad2ea98d6b7f1ee7e3d1db49a57fa350664d6
+021078ee1ebfbdbe5aee9efab2acd9809ccfb180f8017a84ba6bfc1ba5940eca
+3076c863f8d9df3e4afb32361acab13bacd3e465d094b64bece987be66fa501d
+5deba893368ea3fdd3b3a4201d3bd68b3464ead10c6f0ddf513a630e0133fec8
+08630e4b3c8b0aad1bbeed508e7e03d41b3d060a92b1958407843e4cabd78d79
+ff72fc0e92f4903cfd05856f457dd15b1aab99c1d29804d2f3134c9817f45fd2
+efebb92545f056f4ca76ea74ad464cd041b7cbb8892f2dba833118b83e20c039
+99939ffc6cc50503bb871565797ec537e26eb622fd30303273748af2afd97e07
+a9c2a96f4ef8754dc3ea8f3348cb30d76bdaa84d2e933c94c99d13e74f19970f
+5d2bd19712926e230dd02aeae6461edd83ac935ec2f420649f82d4160a072700
+10141602c3a6572740d8e97fd08e56b987062bb57237bbb3056a36e97e399a7a
+cf9653743a9984ef36254d60772a0eedca800923461a3e4443a5ef469aefceec
+aa1831e56b0d8ea6ccb76bb9dbb6ab7584ee268bdd0f5f0d57eddba9b97d74a2
+910f178f388a50fa32aad7b87b3235efcabd4b5009190d12e8c770f6e70dbe10
+e747e1984a1c41d701e6220b001fe25b9a677c996f8fd91bd40fa7e07f57e8bd
+5d2381442b337924e56de4d18cdc352314caebf065f610b00b50302bae3ad612
+dad9059a3d7f3bd63827e28f17d57cef4a8cb8af1f080a993c3c74871e4b7bdb
+2602d07587aed02aa783d80234b6eecc77d163847e63d3c9aa412d10acea7a5c
+5ece5b893bb3031facee72701acd225d6b6a752cb2f84de3ceab2b97b606a0bf
+c6874869a86e3a55a4e1d7abd94719f604ea68b1108ebb5bebc3ef465bdd2cdb
+864ecfe0d6959d5114eaaf1612c970caa2c94729178e6af130a1df211a3795a9
+b5fb934e47f6c48155a19acce788036b4867f90d40c1e4ff7460399f1f08f98a
+0aa3e0d8e354195a2563759dfe0183c8d67b449516ed8f5cf3288f7298d62092
+922f07027352bc7c9612cfca46f1cf2ed1417ab863c2615f2d26ee13d7a04a18
+8336ec9961e76af2f506e3db3d67a2a4fb2dbbb0ca34be6db9789a1cda607d9b
+35f0eac47f488bbe74f8f04b49dc492ec8f096e6710ad59d248a0c98497541d8
+5f9134d5215b0a05fc29db1aa71e432a2c0b00106bf3124df0b72c144375a280
+9cc5ed8335b3e970eaad9178f43011b55d7f3e11d89be1058361893016254440
+353b88162a4e7913721092e05573497ed693f3120176dc08253d2356559041d8
+741a6b9c41f8eb695369633632ffc35a1e2e4ed6258f0a8eef0bf6bb028efed8
+a679be4bc197cc868255f748ca953312eef556d8fdae4e9706c3116e76140587
+db18492730a14e96c211fcd0aeb0d4324b1b4abd0150637c6c135fcca1823fde
+20482dbbab536f87e1d3f0ac4b5154e33bfaade3ac4af8b8d2082658d35a251e
+a0d718f702ed8d957555331c9593abbf64b2194dac9f098773ef4313cd8a48e7
+4d60513d6ee1c132e59ebf5dce2359b61efd16fb4cce810172abb3939e874792
+a862462c72895461ed4dd265abbf52c11c50e607fd3bebeff0397398f656066c
+5f64fc4e67cf5f984fe818c9500cb10beadc1ac513c0c8e60701144b949ce67d
+08cec1adeb70fb01f48abfea22412f4b07b710a8d774228ae156bfdd556c0f49
+bda072c0926a08150f77ee338b3b4303bd2186da21b89df804cd531c499ef953
+9b1ed325e5ef952af05cf67a9fe64b1af975c18348809161ad382debfde45495
+5b32472edf5098b6d1f8fc8807f81ee5be3659bd0f47542ee81e20cbaef168dd
+4b991069cda2f850b1faa40e74fad79ed5f74a0fde1c060996a2280e9c9d21f5
+d23174d3ef4d9eb6e337d443cfccaeab8b0015e6427f9439c8473a1364faf782
+f58bd8bd775899092844ba570c427dff47b8cc4859fd9042ce78aa27ffea8b5a
+c52be0d97cd01c7250a6eda489b5a17e23167239e0d7fd8f3429529ef02548e9
+b7bc1dcfc729600ff98d9f9b33ecdd10ff78baa313b7e35c51dfe8c6a17568fd
+bfbd434860a8ef3821b336783fa328279c05b05aba37f8d26da43391c9cfbd71
+6b240148995a005448afbe45ef2c2853aa3c1cf3ba6434ec79e8dbacef443569
+8e6ef17bdf960e9a37f0b34f4aa39641492bcce95afe55d168e510f934288da7
+c61eb3e1a42f18abc608995cd8c9afcc591751bcd9759387d3924751b1a2c79a
+0cf18b53d3ed8096e2c559dd001e8bf6824b3eedafedd8b89fa23f4aeed14435
+a7d05da7b0607edf2aab0816e866f6791e834bff5f5c6699edb97df199549d54
+3d039671a481d094352ec76d2f7e5119887ee3ad1117f749a85b3b6f37e3d25f
+25397d1d019da9c5c6fbbfbaeb4fdf0a423f6394968f2eabc560f76e75b07b54
+a6d87328604fc86be37a1e8e5790eb845cca88bbc2e01eab28a6d6615229658b
+7554a85064aacf698949e4f56f2bd61bd5af31bd6012ef0c1bb627cbeec71b52
+e99af95f699617a8462e14e144424a64e4c1cda80a13cf7b20929041b2df6686
+15c2f77a73f9cdbca33cd11188a9a608b240b27e7cfc5234fdad6db5d6565787
+d99f45709674690ee704de4ce6accc37343eaac02dd8ca368221d607c4ea24dc
+05aaa5162120301a8fb4c3166ef0e813aab536200a8d54d3e0679cbad59cae0d
+d9c251016336c63243b42f4a439af0f1b4d4cc3ee9c24dae5ec87c10b4b046eb
+3877eae636101c3231319957690cf7cd562fb48e44abd46bfd8640de5348a01d
+8389dbe26165729c3ea1023b354cc6b6928922cffb2df9ea60d853a74067b442
+a7d4938296e2ffdeee8b33dae2ecf5be2451fbe3829f9c1d45820c9849176a43
+22694f059367670d68ad12080a84603821f867ca37dc727c3c5254103af21cd9
+034f679aea5d4bc81366245725fa46cd671ac9251817e8abbe9f06f182b738e9
+05769b0d6a504170334d09bb7b809c249ca9678658b36fef98a0f8936cc9167f
+31837fb2e92319b8e4df5168494fe90a12a88b93bae098fac2f3af2c087759cf
+0fdc3d901e921222a19e53c654d13e52a6f272bd65e3deee14e3e59c6dd9b794
+dbd476ccd4deb50e94d207123a5bb6276e40177c13adee9227e283b51bdc8e50
+2af8d9f3d4cdf61a9bffdb5047aa305f7c61fbb49440b70993c9620020fadf15
+4b5248e8e2a6fd5638a447a593b320039eb53a709e992a481c0de5f19640c17f
+cdcfacfbf7b5252c0274c53f6de78a11db640076e01a11be6a63c3a8be0e3fb0
+f0c1f40b379b80399771b0b23aa0fb934ee3184f0c18d5cb40285510a4eb92f1
+6f089ce3cf32b52add23b0f6a436637a17a71f90e8c91adeaff7eb97220a17b7
+354ea80c678e158c1ecd586f0e2e6d7ab5a179500d404e19a65db6c9568b0799
+330d69b254d29e704196964553817ab428be257c5d51aac61ee9cffcd3ec4615
+1d6e9992ad91a791d1c2465df24757dcbc64f3788b15868b905e53ccd04625c7
+f04fa267d68a6aeb59443ead9bc171f845b2b0d7ac7e788c21411a1d4b3935d6
+ef2093333ce092da5d06fcf6c1f1afc68db00cc1d0090f21046b54694f5162cc
+cb07ac6e81a3b657871db0692cd70edcfb645c335167e08eb15caa6cbf6419b0
+1cb28d3beb8c5ab6c8f77663a2c258177a1feb9abb560e903b45a1d14644a08d
+778a0db918b36ed5a2d6d409adf41a21b13211679094cf290c4652633d861e1e
+2cf20b69ccdcf17ac7d4bc15febe037998b98c176369d225995e578f62f6e548
+049da929686caf8b58bf1baf99bfd7196c8084419d381078ad0bc6bffbe163de
+15a4d0e6fb53208aff06f08967882b17c0696f060218ae037682036cb39365b7
+33d8c2b0f2414f3c919473a6abc8d419f70b541a62082602990c3c35a55217d5
+96fea82048181950779a3fc5f67bdad8df84e5433fa67bccd05ec886d857b789
+18ffbf083fa0b9f98cf5cfc9ae29d607d2ed11fa02131fd7c258431b20f7b113
+c316b7163644fdef029d33366200e9c4b5727940490a81aa139dddf9493f6b32
+0ee84950a6a549460032d0ba7fb3b2ded2e4028bd3ef456005bfc1456c681f25
+82dad6da15127a1ef14550d9557b86c2bc37440d538ee5146f320c9db07aed68
+70f6fa748a5b87fde0e3ef4cf1567e743eea26076ba668b46f3f7ad99f4df367
+fd40d87cca35267a09a3a33f8212655b747323e9d5f184cde766906f6f85ef2b
+3ad0dc0edcd150e589dae9c0e19d464ad618c32e14a5dbcaa6ecbcd990cc49ad
+c6de19129debd2de99b506adf4dbdea4ff1364e300447c9c0deda2cdf1d3648b
+1a83bd4be46e1797fb5b6216077a54f12c7ace9c28320026a19492e58193d082
+c0b5473a5a603ce22ea377511b725ad9c23b1a1b906b465fa02d0fb620e23074
+66c9d077730916850cd2abcc2412a364f4a0efde3fb741dea91fbba138e74dcb
+809627282be317d8f1dbb22220c9696bf39a27fc38aff90eaf458151a00a8a88
+9d4f5d933b1eee63054c65798ad32079ce573d53c620b6a0f81fd931b5a24707
+ebb30cf01b0c63b55ee8c08b805a9a45aea8aacf49982ce6d3e8726c6a122437
+1b9b116a56de605482449dabbb83d353ebdf355fcb8cde5658c699b8a55718a8
+6e051b42221dda48257e9f56d09f31a77630930abb0fce0d49ec9cb27c6ce480
+4c3b36d45ec195e7f78dc930370ed66cd4b6763085ec4c626693e69b39e993b1
+70b2289f29dcf94d5d2763a8211a92c40442371aa2f4297c9958c833421ee693
+a74b256e425979afe86b286bbda0983e14194250d9fecd03a8ba1fe615e93ae1
+d60d43f6858ea9cd47ddf88a1bfb5e90b60a28cdb269d9e1e43b0cf470a95b48
+aa5299e7159e7ccb18200914b93c3b0df79f181789fdfd6693613d0d42778883
+88847927f59d40f0cb5334f62eafe4f380076cfb7720174eceab1eb5050ea12c
+e4293db115c4f9bd4d21910a69d566a706f5c0e1bcb344203503855e6643b125
+17b6db03c41f13a347ad39e47a46d626f8a31a163bda6d23264657b412bdec99
+c87a103d26
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+cleartomark
+%%EndResource
+/F637_0 /WWWUTU+NimbusRomNo9L-ReguItal 1 1
+[ /.notdef/dotaccent/fi/fl/fraction/hungarumlaut/Lslash/lslash
+ /ogonek/ring/.notdef/breve/minus/.notdef/Zcaron/zcaron
+ /caron/dotlessi/dotlessj/ff/ffi/ffl/notequal/infinity
+ /lessequal/greaterequal/partialdiff/summation/product/pi/grave/quotesingle
+ /space/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright
+ /parenleft/parenright/asterisk/plus/comma/hyphen/period/slash
+ /zero/one/two/three/four/five/six/seven
+ /eight/nine/colon/semicolon/less/equal/greater/question
+ /at/A/B/C/D/E/F/G
+ /H/I/J/K/L/M/N/O
+ /P/Q/R/S/T/U/V/W
+ /X/Y/Z/bracketleft/backslash/bracketright/asciicircum/underscore
+ /quoteleft/a/b/c/d/e/f/g
+ /h/i/j/k/l/m/n/o
+ /p/q/r/s/t/u/v/w
+ /x/y/z/braceleft/bar/braceright/asciitilde/.notdef
+ /Euro/integral/quotesinglbase/florin/quotedblbase/ellipsis/dagger/daggerdbl
+ /circumflex/perthousand/Scaron/guilsinglleft/OE/Omega/radical/approxequal
+ /.notdef/.notdef/.notdef/quotedblleft/quotedblright/bullet/endash/emdash
+ /tilde/trademark/scaron/guilsinglright/oe/Delta/lozenge/Ydieresis
+ /.notdef/exclamdown/cent/sterling/currency/yen/brokenbar/section
+ /dieresis/copyright/ordfeminine/guillemotleft/logicalnot/hyphen/registered/macron
+ /degree/plusminus/twosuperior/threesuperior/acute/mu/paragraph/periodcentered
+ /cedilla/onesuperior/ordmasculine/guillemotright/onequarter/onehalf/threequarters/questiondown
+ /Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla
+ /Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex/Idieresis
+ /Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis/multiply
+ /Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls
+ /agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla
+ /egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis
+ /eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis/divide
+ /oslash/ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis]
+pdfMakeFont
+612 792 false pdfSetup
+%%EndSetup
+%%Page: 1 1
+%%BeginPageSetup
+%%PageOrientation: Portrait
+pdfStartPage
+0 0 612 792 re W
+%%EndPageSetup
+[] 0 d
+1 i
+0 j
+0 J
+10 M
+1 w
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+false op
+false OP
+0 0 612 792 re
+W
+q
+[1 0 0 1 72 756] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 463.019 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -36] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -720] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+117.436 701.916 Td
+/F122_0 24.7902 Tf
+(bzip2) 63.3638 Tj
+-278 TJm
+(and) 44.077 Tj
+-278 TJm
+(libbzip2,) 99.1856 Tj
+-278 TJm
+(ver) 37.2101 Tj
+15 TJm
+(sion) 50.9687 Tj
+-278 TJm
+(1.0.5) 55.1334 Tj
+[1 0 0 1 72 696.784] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -15.4939] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -681.29] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90.4929 661.631 Td
+/F122_0 20.6585 Tf
+(A) 14.9154 Tj
+-278 TJm
+(pr) 20.6585 Tj
+20 TJm
+(ogram) 63.1324 Tj
+-278 TJm
+(and) 36.7308 Tj
+-278 TJm
+(librar) 51.6669 Tj
+-10 TJm
+(y) 11.4861 Tj
+-278 TJm
+(f) 6.87928 Tj
+20 TJm
+(or) 20.6585 Tj
+-278 TJm
+(data) 42.4739 Tj
+-278 TJm
+(compression) 128.579 Tj
+[1 0 0 1 72 657.035] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -144] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -513.035] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+207.676 503.285 Td
+/F122_0 11.9552 Tf
+(J) 6.64709 Tj
+20 TJm
+(ulian) 27.9034 Tj
+-278 TJm
+(Se) 14.6212 Tj
+15 TJm
+(war) 20.5988 Tj
+20 TJm
+(d,) 10.6282 Tj
+-278 TJm
+(http://www) 61.103 Tj
+40 TJm
+(.bzip.or) 42.5127 Tj
+15 TJm
+(g) 7.30463 Tj
+[1 0 0 1 72 500.625] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -435.826] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 463.019 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+Q
+showpage
+%%PageTrailer
+pdfEndPage
+%%Page: 2 2
+%%BeginPageSetup
+%%PageOrientation: Portrait
+pdfStartPage
+0 0 612 792 re W
+%%EndPageSetup
+[] 0 d
+1 i
+0 j
+0 J
+10 M
+1 w
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+false op
+false OP
+0 0 612 792 re
+W
+q
+[1 0 0 1 72 741.554] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 14.4459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 187.197 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 140.398 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -140.398 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 280.796 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -472.974 -13.9477] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -0.4981] cm
+q
+[] 0 d
+0 J
+0.4981 w
+0 0.2491 m
+475.465 0.2491 l
+S
+Q
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 479.251 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -21.5542] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -720] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 709.534 Td
+/F122_0 14.3462 Tf
+(bzip2) 36.6689 Tj
+-489 TJm
+(and) 25.5075 Tj
+-488 TJm
+(libbzip2,) 57.3991 Tj
+-542 TJm
+(ver) 21.5336 Tj
+15 TJm
+(sion) 29.4958 Tj
+-488 TJm
+(1.0.5:) 36.6832 Tj
+-766 TJm
+(A) 10.358 Tj
+-488 TJm
+(pr) 14.3462 Tj
+20 TJm
+(ogram) 43.842 Tj
+-489 TJm
+(and) 25.5075 Tj
+-489 TJm
+(librar) 35.8798 Tj
+-10 TJm
+(y) 7.97649 Tj
+-488 TJm
+(f) 4.77728 Tj
+20 TJm
+(or) 14.3462 Tj
+-489 TJm
+(data) 29.4958 Tj
+72 692.319 Td
+(compression) 89.2907 Tj
+[1 0 0 1 72 689.349] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -689.349] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 680.364 Td
+/F130_0 9.9626 Tf
+(by) 9.9626 Tj
+-250 TJm
+(Julian) 23.8007 Tj
+-250 TJm
+(Se) 9.9626 Tj
+25 TJm
+(w) 7.193 Tj
+10 TJm
+(ard) 12.7222 Tj
+[1 0 0 1 72 678.207] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -678.207] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 668.409 Td
+/F130_0 9.9626 Tf
+(Cop) 16.6077 Tj
+10 TJm
+(yright) 23.8007 Tj
+[1 0 0 1 114.799 668.409] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -114.799 -668.409] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+114.799 668.409 Td
+/F130_0 9.9626 Tf
+(\251) 7.57158 Tj
+[1 0 0 1 122.371 668.409] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -122.371 -668.409] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+124.861 668.409 Td
+/F130_0 9.9626 Tf
+(1996-2007) 43.1679 Tj
+-250 TJm
+(Julian) 23.8007 Tj
+-250 TJm
+(Se) 9.9626 Tj
+25 TJm
+(w) 7.193 Tj
+10 TJm
+(ard) 12.7222 Tj
+[1 0 0 1 72 666.252] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -7.9701] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -658.282] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 650.875 Td
+/F130_0 7.9701 Tf
+(This) 14.1708 Tj
+-250 TJm
+(program,) 28.9952 Tj
+[1 0 0 1 119.151 650.875] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -119.151 -650.875] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+119.151 650.875 Td
+/F134_0 7.9701 Tf
+(bzip2) 23.9103 Tj
+[1 0 0 1 143.061 650.875] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -143.061 -650.875] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+143.061 650.875 Td
+/F130_0 7.9701 Tf
+(,) 1.99253 Tj
+-250 TJm
+(the) 9.73946 Tj
+-250 TJm
+(associated) 32.7571 Tj
+-250 TJm
+(library) 21.2483 Tj
+[1 0 0 1 216.768 650.875] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -216.768 -650.875] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+216.768 650.875 Td
+/F134_0 7.9701 Tf
+(libbzip2) 38.2565 Tj
+[1 0 0 1 255.024 650.875] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -255.024 -650.875] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+255.024 650.875 Td
+/F130_0 7.9701 Tf
+(,) 1.99253 Tj
+-250 TJm
+(and) 11.5088 Tj
+-250 TJm
+(all) 7.9701 Tj
+-250 TJm
+(documentation,) 49.3668 Tj
+-250 TJm
+(are) 9.73149 Tj
+-250 TJm
+(cop) 11.5088 Tj
+10 TJm
+(yright) 19.0406 Tj
+-250 TJm
+(\251) 6.05728 Tj
+-250 TJm
+(1996-2007) 34.5344 Tj
+-250 TJm
+(Julian) 19.0406 Tj
+-250 TJm
+(Se) 7.9701 Tj
+25 TJm
+(w) 5.75441 Tj
+10 TJm
+(ard.) 12.1703 Tj
+-310 TJm
+(All) 10.1858 Tj
+-250 TJm
+(rights) 18.1559 Tj
+-250 TJm
+(reserv) 19.471 Tj
+15 TJm
+(ed.) 9.5163 Tj
+[1 0 0 1 72 649.149] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -7.9701] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -641.179] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 633.34 Td
+/F130_0 7.9701 Tf
+(Redistrib) 29.2264 Tj
+20 TJm
+(ution) 16.3865 Tj
+-250 TJm
+(and) 11.5088 Tj
+-250 TJm
+(use) 10.6241 Tj
+-250 TJm
+(in) 6.20074 Tj
+-250 TJm
+(source) 20.802 Tj
+-250 TJm
+(and) 11.5088 Tj
+-250 TJm
+(binary) 20.3636 Tj
+-250 TJm
+(forms,) 20.5868 Tj
+-250 TJm
+(with) 14.1708 Tj
+-250 TJm
+(or) 6.63909 Tj
+-250 TJm
+(without) 24.3566 Tj
+-250 TJm
+(modi\002cation,) 42.2894 Tj
+-250 TJm
+(are) 9.73149 Tj
+-250 TJm
+(permitted) 30.5494 Tj
+-250 TJm
+(pro) 10.6241 Tj
+15 TJm
+(vided) 17.7096 Tj
+-250 TJm
+(that) 11.9551 Tj
+-250 TJm
+(the) 9.73946 Tj
+-250 TJm
+(follo) 15.0555 Tj
+25 TJm
+(wing) 15.9402 Tj
+-250 TJm
+(conditions) 33.2114 Tj
+-250 TJm
+(are) 9.73149 Tj
+-250 TJm
+(met:) 14.1708 Tj
+[1 0 0 1 72 631.615] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -23.7789] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 5.5791 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -77.5791 -607.836] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+77.5791 607.836 Td
+/F130_0 7.9701 Tf
+(\225) 2.78954 Tj
+[1 0 0 1 80.3686 607.836] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 1.9926 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 1.594 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -83.9552 -607.836] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+83.9552 607.836 Td
+/F130_0 7.9701 Tf
+(Redistrib) 29.2264 Tj
+20 TJm
+(utions) 19.4869 Tj
+-250 TJm
+(of) 6.63909 Tj
+-250 TJm
+(source) 20.802 Tj
+-250 TJm
+(code) 15.0475 Tj
+-250 TJm
+(must) 15.5018 Tj
+-250 TJm
+(retain) 18.1479 Tj
+-250 TJm
+(the) 9.73946 Tj
+-250 TJm
+(abo) 11.5088 Tj
+15 TJm
+(v) 3.98505 Tj
+15 TJm
+(e) 3.53872 Tj
+-250 TJm
+(cop) 11.5088 Tj
+10 TJm
+(yright) 19.0406 Tj
+-250 TJm
+(notice,) 21.4714 Tj
+-250 TJm
+(this) 11.5168 Tj
+-250 TJm
+(list) 9.74743 Tj
+-250 TJm
+(of) 6.63909 Tj
+-250 TJm
+(conditions) 33.2114 Tj
+-250 TJm
+(and) 11.5088 Tj
+-250 TJm
+(the) 9.73946 Tj
+-250 TJm
+(follo) 15.0555 Tj
+25 TJm
+(wing) 15.9402 Tj
+-250 TJm
+(disclaimer) 33.2034 Tj
+55 TJm
+(.) 1.99253 Tj
+[1 0 0 1 470.908 607.836] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -398.908 -17.5343] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 5.5791 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -77.5791 -590.302] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+77.5791 590.302 Td
+/F130_0 7.9701 Tf
+(\225) 2.78954 Tj
+[1 0 0 1 80.3686 590.302] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 1.9926 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 1.594 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -83.9552 -590.302] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+83.9552 590.302 Td
+/F130_0 7.9701 Tf
+(The) 12.3935 Tj
+-270 TJm
+(origin) 19.0406 Tj
+-270 TJm
+(of) 6.63909 Tj
+-270 TJm
+(this) 11.5168 Tj
+-270 TJm
+(softw) 17.7096 Tj
+10 TJm
+(are) 9.73149 Tj
+-270 TJm
+(must) 15.5018 Tj
+-270 TJm
+(not) 10.1858 Tj
+-270 TJm
+(be) 7.52377 Tj
+-270 TJm
+(misrepresented;) 50.4667 Tj
+-279 TJm
+(you) 11.9551 Tj
+-270 TJm
+(must) 15.5018 Tj
+-270 TJm
+(not) 10.1858 Tj
+-270 TJm
+(claim) 17.7096 Tj
+-270 TJm
+(that) 11.9551 Tj
+-270 TJm
+(you) 11.9551 Tj
+-270 TJm
+(wrote) 18.1479 Tj
+-270 TJm
+(the) 9.73946 Tj
+-270 TJm
+(original) 24.795 Tj
+-270 TJm
+(softw) 17.7096 Tj
+10 TJm
+(are.) 11.724 Tj
+-740 TJm
+(If) 5.30809 Tj
+-270 TJm
+(you) 11.9551 Tj
+-270 TJm
+(use) 10.6241 Tj
+-270 TJm
+(this) 11.5168 Tj
+-270 TJm
+(softw) 17.7096 Tj
+10 TJm
+(are) 9.73149 Tj
+-270 TJm
+(in) 6.20074 Tj
+-269 TJm
+(a) 3.53872 Tj
+83.9552 580.737 Td
+(product,) 26.3412 Tj
+-250 TJm
+(an) 7.52377 Tj
+-250 TJm
+(ackno) 19.0326 Tj
+25 TJm
+(wledgment) 35.4191 Tj
+-250 TJm
+(in) 6.20074 Tj
+-250 TJm
+(the) 9.73946 Tj
+-250 TJm
+(product) 24.3487 Tj
+-250 TJm
+(documentation) 47.3743 Tj
+-250 TJm
+(w) 5.75441 Tj
+10 TJm
+(ould) 14.1708 Tj
+-250 TJm
+(be) 7.52377 Tj
+-250 TJm
+(appreciated) 36.7342 Tj
+-250 TJm
+(b) 3.98505 Tj
+20 TJm
+(ut) 6.20074 Tj
+-250 TJm
+(is) 5.31606 Tj
+-250 TJm
+(not) 10.1858 Tj
+-250 TJm
+(required.) 28.5489 Tj
+[1 0 0 1 403.817 580.737] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -331.817 -17.5342] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 5.5791 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -77.5791 -563.203] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+77.5791 563.203 Td
+/F130_0 7.9701 Tf
+(\225) 2.78954 Tj
+[1 0 0 1 80.3686 563.203] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 1.9926 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 1.594 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -83.9552 -563.203] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+83.9552 563.203 Td
+/F130_0 7.9701 Tf
+(Altered) 23.9023 Tj
+-250 TJm
+(source) 20.802 Tj
+-250 TJm
+(v) 3.98505 Tj
+15 TJm
+(ersions) 22.5793 Tj
+-250 TJm
+(must) 15.5018 Tj
+-250 TJm
+(be) 7.52377 Tj
+-250 TJm
+(plainly) 22.1409 Tj
+-250 TJm
+(mark) 16.3786 Tj
+10 TJm
+(ed) 7.52377 Tj
+-250 TJm
+(as) 6.63909 Tj
+-250 TJm
+(such,) 16.6017 Tj
+-250 TJm
+(and) 11.5088 Tj
+-250 TJm
+(must) 15.5018 Tj
+-250 TJm
+(not) 10.1858 Tj
+-250 TJm
+(be) 7.52377 Tj
+-250 TJm
+(misrepresented) 48.251 Tj
+-250 TJm
+(as) 6.63909 Tj
+-250 TJm
+(being) 17.7096 Tj
+-250 TJm
+(the) 9.73946 Tj
+-250 TJm
+(original) 24.795 Tj
+-250 TJm
+(softw) 17.7096 Tj
+10 TJm
+(are.) 11.724 Tj
+[1 0 0 1 464.405 563.203] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -392.405 -17.5343] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 5.5791 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -77.5791 -545.669] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+77.5791 545.669 Td
+/F130_0 7.9701 Tf
+(\225) 2.78954 Tj
+[1 0 0 1 80.3686 545.669] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 1.9926 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 1.594 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -83.9552 -545.669] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+83.9552 545.669 Td
+/F130_0 7.9701 Tf
+(The) 12.3935 Tj
+-250 TJm
+(name) 17.2632 Tj
+-250 TJm
+(of) 6.63909 Tj
+-250 TJm
+(the) 9.73946 Tj
+-250 TJm
+(author) 20.3636 Tj
+-250 TJm
+(may) 13.7245 Tj
+-250 TJm
+(not) 10.1858 Tj
+-250 TJm
+(be) 7.52377 Tj
+-250 TJm
+(used) 14.6092 Tj
+-250 TJm
+(to) 6.20074 Tj
+-250 TJm
+(endorse) 24.787 Tj
+-250 TJm
+(or) 6.63909 Tj
+-250 TJm
+(promote) 26.5643 Tj
+-250 TJm
+(products) 27.449 Tj
+-250 TJm
+(deri) 12.3935 Tj
+25 TJm
+(v) 3.98505 Tj
+15 TJm
+(ed) 7.52377 Tj
+-250 TJm
+(from) 15.4939 Tj
+-250 TJm
+(this) 11.5168 Tj
+-250 TJm
+(softw) 17.7096 Tj
+10 TJm
+(are) 9.73149 Tj
+-250 TJm
+(without) 24.3566 Tj
+-250 TJm
+(speci\002c) 24.3487 Tj
+-250 TJm
+(prior) 15.4939 Tj
+-250 TJm
+(written) 22.5793 Tj
+-250 TJm
+(permission.) 36.9733 Tj
+[1 0 0 1 533.577 545.669] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -461.577 -9.6956] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -535.973] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 528.135 Td
+/F130_0 7.9701 Tf
+(THIS) 17.7096 Tj
+-401 TJm
+(SOFTW) 27.0107 Tj
+120 TJm
+(ARE) 15.9402 Tj
+-401 TJm
+(IS) 7.08542 Tj
+-400 TJm
+(PR) 9.74743 Tj
+40 TJm
+(O) 5.75441 Tj
+50 TJm
+(VIDED) 24.787 Tj
+-401 TJm
+(BY) 11.0705 Tj
+-401 TJm
+(THE) 15.4939 Tj
+-401 TJm
+(A) 5.75441 Tj
+55 TJm
+(UTHOR) 27.449 Tj
+-401 TJm
+("AS) 13.4376 Tj
+-401 TJm
+(IS") 10.3372 Tj
+-401 TJm
+(AND) 17.2632 Tj
+-400 TJm
+(ANY) 17.2632 Tj
+-401 TJm
+(EXPRESS) 34.1041 Tj
+-401 TJm
+(OR) 11.0705 Tj
+-401 TJm
+(IMPLIED) 32.3188 Tj
+-401 TJm
+(W) 7.52377 Tj
+120 TJm
+(ARRANTIES,) 46.7128 Tj
+-401 TJm
+(INCLUDING,) 46.2585 Tj
+-400 TJm
+(B) 5.31606 Tj
+10 TJm
+(UT) 10.6241 Tj
+72 518.571 Td
+(NO) 11.5088 Tj
+40 TJm
+(T) 4.86973 Tj
+-304 TJm
+(LIMITED) 32.7571 Tj
+-304 TJm
+(T) 4.86973 Tj
+18 TJm
+(O,) 7.74694 Tj
+-305 TJm
+(THE) 15.4939 Tj
+-304 TJm
+(IMPLIED) 32.3188 Tj
+-304 TJm
+(W) 7.52377 Tj
+120 TJm
+(ARRANTIES) 44.7202 Tj
+-304 TJm
+(OF) 10.1858 Tj
+-304 TJm
+(MERCHANT) 44.7202 Tj
+93 TJm
+(ABILITY) 31.8724 Tj
+-304 TJm
+(AND) 17.2632 Tj
+-305 TJm
+(FITNESS) 31.442 Tj
+-304 TJm
+(FOR) 15.5018 Tj
+-304 TJm
+(A) 5.75441 Tj
+-304 TJm
+(P) 4.43138 Tj
+92 TJm
+(AR) 11.0705 Tj
+60 TJm
+(TICULAR) 34.5344 Tj
+-304 TJm
+(PURPOSE) 34.9887 Tj
+-304 TJm
+(ARE) 15.9402 Tj
+-305 TJm
+(DI) 8.40846 Tj
+1 TJm
+(S-) 7.08542 Tj
+72 509.006 Td
+(CLAIMED.) 38.2963 Tj
+-576 TJm
+(IN) 8.40846 Tj
+-287 TJm
+(NO) 11.5088 Tj
+-288 TJm
+(EVENT) 26.118 Tj
+-288 TJm
+(SHALL) 25.6797 Tj
+-288 TJm
+(THE) 15.4939 Tj
+-287 TJm
+(A) 5.75441 Tj
+55 TJm
+(UTHOR) 27.449 Tj
+-288 TJm
+(BE) 10.1858 Tj
+-288 TJm
+(LIABLE) 28.3337 Tj
+-288 TJm
+(FOR) 15.5018 Tj
+-288 TJm
+(ANY) 17.2632 Tj
+-287 TJm
+(DIRECT) 28.78 Tj
+74 TJm
+(,) 1.99253 Tj
+-288 TJm
+(INDIRECT) 37.1885 Tj
+74 TJm
+(,) 1.99253 Tj
+-288 TJm
+(INCIDENT) 37.6268 Tj
+93 TJm
+(AL,) 12.6167 Tj
+-288 TJm
+(SPECIAL,) 34.3193 Tj
+-288 TJm
+(EXEMPLAR) 42.9509 Tj
+65 TJm
+(Y) 5.75441 Tj
+129 TJm
+(,) 1.99253 Tj
+72 499.442 Td
+(OR) 11.0705 Tj
+-299 TJm
+(CONSEQ) 31.8804 Tj
+10 TJm
+(UENTIAL) 34.5265 Tj
+-300 TJm
+(D) 5.75441 Tj
+40 TJm
+(AMA) 18.5942 Tj
+40 TJm
+(GES) 15.0555 Tj
+-299 TJm
+(\(INCLUDING,) 48.9125 Tj
+-299 TJm
+(B) 5.31606 Tj
+10 TJm
+(UT) 10.6241 Tj
+-299 TJm
+(NO) 11.5088 Tj
+40 TJm
+(T) 4.86973 Tj
+-300 TJm
+(LIMITED) 32.7571 Tj
+-299 TJm
+(T) 4.86973 Tj
+18 TJm
+(O,) 7.74694 Tj
+-299 TJm
+(PR) 9.74743 Tj
+40 TJm
+(OCUREMENT) 49.59 Tj
+-299 TJm
+(OF) 10.1858 Tj
+-300 TJm
+(SUBSTITUTE) 47.8206 Tj
+-299 TJm
+(GOODS) 27.449 Tj
+-299 TJm
+(OR) 11.0705 Tj
+-300 TJm
+(SER) 14.6172 Tj
+80 TJm
+(VICES) 23.0256 Tj
+1 TJm
+(;) 2.21569 Tj
+72 489.878 Td
+(LOSS) 19.4869 Tj
+-360 TJm
+(OF) 10.1858 Tj
+-360 TJm
+(USE,) 17.048 Tj
+-360 TJm
+(D) 5.75441 Tj
+40 TJm
+(A) 5.75441 Tj
+111 TJm
+(T) 4.86973 Tj
+93 TJm
+(A,) 7.74694 Tj
+-360 TJm
+(OR) 11.0705 Tj
+-359 TJm
+(PR) 9.74743 Tj
+40 TJm
+(OFITS;) 24.3566 Tj
+-360 TJm
+(OR) 11.0705 Tj
+-360 TJm
+(B) 5.31606 Tj
+10 TJm
+(USINESS) 32.3267 Tj
+-360 TJm
+(INTERR) 28.78 Tj
+40 TJm
+(UPTION\)) 31.8724 Tj
+-360 TJm
+(HO) 11.5088 Tj
+35 TJm
+(WEVER) 28.3337 Tj
+-360 TJm
+(CA) 11.0705 Tj
+55 TJm
+(USED) 20.8099 Tj
+-359 TJm
+(AND) 17.2632 Tj
+-360 TJm
+(ON) 11.5088 Tj
+-360 TJm
+(ANY) 17.2632 Tj
+-360 TJm
+(THEOR) 26.5643 Tj
+65 TJm
+(Y) 5.75441 Tj
+-360 TJm
+(OF) 10.1858 Tj
+-360 TJm
+(LIAB) 18.5942 Tj
+1 TJm
+(ILITY) 20.802 Tj
+128 TJm
+(,) 1.99253 Tj
+72 480.314 Td
+(WHETHER) 38.9578 Tj
+-247 TJm
+(IN) 8.40846 Tj
+-247 TJm
+(CONTRA) 32.7651 Tj
+40 TJm
+(CT) 10.1858 Tj
+74 TJm
+(,) 1.99253 Tj
+-247 TJm
+(STRICT) 27.457 Tj
+-247 TJm
+(LIABILITY) 39.3962 Tj
+129 TJm
+(,) 1.99253 Tj
+-246 TJm
+(OR) 11.0705 Tj
+-247 TJm
+(T) 4.86973 Tj
+18 TJm
+(OR) 11.0705 Tj
+60 TJm
+(T) 4.86973 Tj
+-247 TJm
+(\(INCLUDING) 46.92 Tj
+-247 TJm
+(NEGLIGENCE) 50.4667 Tj
+-247 TJm
+(OR) 11.0705 Tj
+-247 TJm
+(O) 5.75441 Tj
+40 TJm
+(THER) 20.8099 Tj
+55 TJm
+(WISE\)) 22.133 Tj
+-247 TJm
+(ARISING) 32.3188 Tj
+-247 TJm
+(IN) 8.40846 Tj
+-247 TJm
+(ANY) 17.2632 Tj
+-247 TJm
+(W) 7.52377 Tj
+120 TJm
+(A) 5.75441 Tj
+105 TJm
+(Y) 5.75441 Tj
+-247 TJm
+(OUT) 16.3786 Tj
+72 470.75 Td
+(OF) 10.1858 Tj
+-250 TJm
+(THE) 15.4939 Tj
+-250 TJm
+(USE) 15.0555 Tj
+-250 TJm
+(OF) 10.1858 Tj
+-250 TJm
+(THIS) 17.7096 Tj
+-250 TJm
+(SOFTW) 27.0107 Tj
+120 TJm
+(ARE,) 17.9327 Tj
+-250 TJm
+(EVEN) 21.2483 Tj
+-250 TJm
+(IF) 7.08542 Tj
+-250 TJm
+(AD) 11.5088 Tj
+40 TJm
+(VISED) 23.464 Tj
+-250 TJm
+(OF) 10.1858 Tj
+-250 TJm
+(THE) 15.4939 Tj
+-250 TJm
+(POSSIBILITY) 47.8206 Tj
+-250 TJm
+(OF) 10.1858 Tj
+-250 TJm
+(SUCH) 21.2563 Tj
+-250 TJm
+(D) 5.75441 Tj
+40 TJm
+(AMA) 18.5942 Tj
+40 TJm
+(GE.) 12.6167 Tj
+[1 0 0 1 72 469.598] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -7.9701] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -461.628] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 453.216 Td
+/F130_0 7.9701 Tf
+(P) 4.43138 Tj
+92 TJm
+(A) 5.75441 Tj
+111 TJm
+(TENTS:) 27.0107 Tj
+-296 TJm
+(T) 4.86973 Tj
+80 TJm
+(o) 3.98505 Tj
+-295 TJm
+(the) 9.73946 Tj
+-296 TJm
+(best) 12.8398 Tj
+-295 TJm
+(of) 6.63909 Tj
+-296 TJm
+(my) 10.1858 Tj
+-295 TJm
+(kno) 11.9551 Tj
+25 TJm
+(wledge,) 25.0102 Tj
+[1 0 0 1 208.544 453.216] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -208.544 -453.216] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+208.544 453.216 Td
+/F134_0 7.9701 Tf
+(bzip2) 23.9103 Tj
+[1 0 0 1 232.454 453.216] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -232.454 -453.216] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+234.81 453.216 Td
+/F130_0 7.9701 Tf
+(and) 11.5088 Tj
+[1 0 0 1 248.674 453.216] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -248.674 -453.216] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+248.674 453.216 Td
+/F134_0 7.9701 Tf
+(libbzip2) 38.2565 Tj
+[1 0 0 1 286.931 453.216] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -286.931 -453.216] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+289.286 453.216 Td
+/F130_0 7.9701 Tf
+(do) 7.9701 Tj
+-296 TJm
+(not) 10.1858 Tj
+-295 TJm
+(use) 10.6241 Tj
+-296 TJm
+(an) 7.52377 Tj
+15 TJm
+(y) 3.98505 Tj
+-295 TJm
+(patented) 27.0027 Tj
+-296 TJm
+(algorithms.) 36.0886 Tj
+-893 TJm
+(Ho) 9.73946 Tj
+25 TJm
+(we) 9.29314 Tj
+25 TJm
+(v) 3.98505 Tj
+15 TJm
+(er) 6.19277 Tj
+40 TJm
+(,) 1.99253 Tj
+-307 TJm
+(I) 2.65404 Tj
+-295 TJm
+(do) 7.9701 Tj
+-296 TJm
+(not) 10.1858 Tj
+-295 TJm
+(ha) 7.52377 Tj
+20 TJm
+(v) 3.98505 Tj
+15 TJm
+(e) 3.53872 Tj
+-296 TJm
+(the) 9.73946 Tj
+-295 TJm
+(resources) 30.0951 Tj
+-296 TJm
+(to) 6.20074 Tj
+72 443.652 Td
+(carry) 16.3706 Tj
+-250 TJm
+(out) 10.1858 Tj
+-250 TJm
+(a) 3.53872 Tj
+-250 TJm
+(patent) 19.4789 Tj
+-250 TJm
+(search.) 22.3482 Tj
+-620 TJm
+(Therefore) 31.4181 Tj
+-250 TJm
+(I) 2.65404 Tj
+-250 TJm
+(cannot) 21.2483 Tj
+-250 TJm
+(gi) 6.20074 Tj
+25 TJm
+(v) 3.98505 Tj
+15 TJm
+(e) 3.53872 Tj
+-250 TJm
+(an) 7.52377 Tj
+15 TJm
+(y) 3.98505 Tj
+-250 TJm
+(guarantee) 30.9798 Tj
+-250 TJm
+(of) 6.63909 Tj
+-250 TJm
+(the) 9.73946 Tj
+-250 TJm
+(abo) 11.5088 Tj
+15 TJm
+(v) 3.98505 Tj
+15 TJm
+(e) 3.53872 Tj
+-250 TJm
+(statement.) 32.5419 Tj
+[1 0 0 1 72 441.926] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -391.074] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 374.394 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 46.7993 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -46.7993 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 93.5986 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.2765 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+Q
+showpage
+%%PageTrailer
+pdfEndPage
+%%Page: 3 3
+%%BeginPageSetup
+%%PageOrientation: Portrait
+pdfStartPage
+0 0 612 792 re W
+%%EndPageSetup
+[] 0 d
+1 i
+0 j
+0 J
+10 M
+1 w
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+false op
+false OP
+0 0 612 792 re
+W
+q
+[1 0 0 1 72 741.554] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 14.4459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 187.197 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 140.398 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -140.398 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 280.796 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -472.974 -13.9477] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -0.4981] cm
+q
+[] 0 d
+0 J
+0.4981 w
+0 0.2491 m
+475.465 0.2491 l
+S
+Q
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 479.251 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -468 -21.5542] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -720] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 707.441 Td
+/F122_0 17.2154 Tf
+(T) 10.5186 Tj
+80 TJm
+(ab) 20.0904 Tj
+10 TJm
+(le) 14.3576 Tj
+-278 TJm
+(of) 16.2513 Tj
+-278 TJm
+(Contents) 74.5943 Tj
+[1 0 0 1 72 698.619] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -11.7401] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -686.879] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 686.879 Td
+/F130_0 9.9626 Tf
+(1.) 7.47195 Tj
+-310 TJm
+(Introduction) 49.2551 Tj
+[1 0 0 1 131.815 686.879] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -136.796 -686.879] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+145.733 686.879 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 511.108 686.879] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -511.108 -686.879] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+511.108 686.879 Td
+/F130_0 9.9626 Tf
+(1) 4.9813 Tj
+[1 0 0 1 516.09 686.879] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -0.0996] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -11.8556] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -674.923] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 674.923 Td
+/F130_0 9.9626 Tf
+(2.) 7.47195 Tj
+-310 TJm
+(Ho) 12.1743 Tj
+25 TJm
+(w) 7.193 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(use) 13.2801 Tj
+-250 TJm
+(bzip2) 22.1369 Tj
+[1 0 0 1 152.318 674.923] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -157.3 -674.923] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+167.054 674.923 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 511.108 674.923] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -511.108 -674.923] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+511.108 674.923 Td
+/F130_0 9.9626 Tf
+(2) 4.9813 Tj
+[1 0 0 1 516.09 674.923] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7984] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -662.968] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 662.968 Td
+/F130_0 9.9626 Tf
+(2.1.) 14.9439 Tj
+-310 TJm
+(N) 7.193 Tj
+35 TJm
+(AME) 22.1369 Tj
+[1 0 0 1 119.014 662.968] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -123.995 -662.968] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+132.691 662.968 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 511.108 662.968] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -511.108 -662.968] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+511.108 662.968 Td
+/F130_0 9.9626 Tf
+(2) 4.9813 Tj
+[1 0 0 1 516.09 662.968] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -0.0995] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -11.8556] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -651.013] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 651.013 Td
+/F130_0 9.9626 Tf
+(2.2.) 14.9439 Tj
+-310 TJm
+(SYNOPSIS) 47.0534 Tj
+[1 0 0 1 137.085 651.013] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -142.067 -651.013] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+150.582 651.013 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 511.108 651.013] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -511.108 -651.013] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+511.108 651.013 Td
+/F130_0 9.9626 Tf
+(2) 4.9813 Tj
+[1 0 0 1 516.09 651.013] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -0.0996] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -11.8556] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -639.058] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 639.058 Td
+/F130_0 9.9626 Tf
+(2.3.) 14.9439 Tj
+-310 TJm
+(DESCRIPTION) 64.7569 Tj
+[1 0 0 1 154.789 639.058] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -159.77 -639.058] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+168.29 639.058 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 511.108 639.058] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -511.108 -639.058] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+511.108 639.058 Td
+/F130_0 9.9626 Tf
+(3) 4.9813 Tj
+[1 0 0 1 516.09 639.058] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -0.0995] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -11.8557] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -627.103] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 627.103 Td
+/F130_0 9.9626 Tf
+(2.4.) 14.9439 Tj
+-310 TJm
+(OPTIONS) 42.0621 Tj
+[1 0 0 1 132.094 627.103] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -137.076 -627.103] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+145.873 627.103 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 511.108 627.103] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -511.108 -627.103] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+511.108 627.103 Td
+/F130_0 9.9626 Tf
+(4) 4.9813 Tj
+[1 0 0 1 516.09 627.103] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -0.0995] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -11.8556] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -615.147] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 615.147 Td
+/F130_0 9.9626 Tf
+(2.5.) 14.9439 Tj
+-310 TJm
+(MEMOR) 37.6387 Tj
+65 TJm
+(Y) 7.193 Tj
+-250 TJm
+(MAN) 23.2427 Tj
+35 TJm
+(A) 7.193 Tj
+40 TJm
+(GEMENT) 41.5042 Tj
+[1 0 0 1 207.9 615.147] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -212.881 -615.147] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+221.412 615.147 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 511.108 615.147] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -511.108 -615.147] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+511.108 615.147 Td
+/F130_0 9.9626 Tf
+(5) 4.9813 Tj
+[1 0 0 1 516.09 615.147] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -0.0996] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -11.8556] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -603.192] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 603.192 Td
+/F130_0 9.9626 Tf
+(2.6.) 14.9439 Tj
+-310 TJm
+(RECO) 26.5703 Tj
+50 TJm
+(VERING) 37.6287 Tj
+-250 TJm
+(D) 7.193 Tj
+40 TJm
+(A) 7.193 Tj
+111 TJm
+(T) 6.08715 Tj
+93 TJm
+(A) 7.193 Tj
+-250 TJm
+(FR) 12.1843 Tj
+40 TJm
+(OM) 16.0497 Tj
+-250 TJm
+(D) 7.193 Tj
+40 TJm
+(AMA) 23.2427 Tj
+40 TJm
+(GED) 20.4731 Tj
+-250 TJm
+(FILES) 26.5703 Tj
+[1 0 0 1 293.449 603.192] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -298.43 -603.192] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+308.464 603.192 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 511.108 603.192] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -511.108 -603.192] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+511.108 603.192 Td
+/F130_0 9.9626 Tf
+(6) 4.9813 Tj
+[1 0 0 1 516.09 603.192] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -0.0995] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -11.8557] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -591.237] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 591.237 Td
+/F130_0 9.9626 Tf
+(2.7.) 14.9439 Tj
+-310 TJm
+(PERFORMANCE) 73.6236 Tj
+-250 TJm
+(NO) 14.386 Tj
+40 TJm
+(TES) 17.7135 Tj
+[1 0 0 1 197.847 591.237] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -202.829 -591.237] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+211.958 591.237 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 511.108 591.237] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -511.108 -591.237] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+511.108 591.237 Td
+/F130_0 9.9626 Tf
+(6) 4.9813 Tj
+[1 0 0 1 516.09 591.237] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -0.0995] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -11.8557] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -579.282] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 579.282 Td
+/F130_0 9.9626 Tf
+(2.8.) 14.9439 Tj
+-310 TJm
+(CA) 13.8381 Tj
+135 TJm
+(VEA) 20.4731 Tj
+111 TJm
+(TS) 11.6264 Tj
+[1 0 0 1 133.519 579.282] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -138.5 -579.282] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+148.799 579.282 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 511.108 579.282] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -511.108 -579.282] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+511.108 579.282 Td
+/F130_0 9.9626 Tf
+(7) 4.9813 Tj
+[1 0 0 1 516.09 579.282] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -0.0995] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -11.8556] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -567.327] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 567.327 Td
+/F130_0 9.9626 Tf
+(2.9.) 14.9439 Tj
+-310 TJm
+(A) 7.193 Tj
+55 TJm
+(UTHOR) 34.3112 Tj
+[1 0 0 1 130.989 567.327] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -135.97 -567.327] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+145.32 567.327 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 511.108 567.327] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -511.108 -567.327] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+511.108 567.327 Td
+/F130_0 9.9626 Tf
+(7) 4.9813 Tj
+[1 0 0 1 516.09 567.327] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -0.2192] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -11.736] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -555.372] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 555.372 Td
+/F130_0 9.9626 Tf
+(3.) 7.47195 Tj
+-310 TJm
+(Programming) 54.7943 Tj
+-250 TJm
+(with) 17.7135 Tj
+[1 0 0 1 160.049 555.372] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -160.049 -555.372] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+160.049 555.372 Td
+/F134_0 9.9626 Tf
+(libbzip2) 47.8205 Tj
+[1 0 0 1 207.87 555.372] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -215.342 -555.372] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+224.856 555.372 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 511.108 555.372] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -511.108 -555.372] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+511.108 555.372 Td
+/F130_0 9.9626 Tf
+(8) 4.9813 Tj
+[1 0 0 1 516.09 555.372] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7984] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -543.416] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 543.416 Td
+/F130_0 9.9626 Tf
+(3.1.) 14.9439 Tj
+-310 TJm
+(T) 6.08715 Tj
+80 TJm
+(op-le) 20.4731 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(el) 7.193 Tj
+-250 TJm
+(structure) 34.8591 Tj
+[1 0 0 1 164.921 543.416] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -169.902 -543.416] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+179.997 543.416 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 511.108 543.416] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -511.108 -543.416] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+511.108 543.416 Td
+/F130_0 9.9626 Tf
+(8) 4.9813 Tj
+[1 0 0 1 516.09 543.416] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7983] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -531.461] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 531.461 Td
+/F130_0 9.9626 Tf
+(3.1.1.) 22.4159 Tj
+-310 TJm
+(Lo) 11.0684 Tj
+25 TJm
+(w-le) 17.7035 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(el) 7.193 Tj
+-250 TJm
+(summary) 37.0808 Tj
+[1 0 0 1 177.374 531.461] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -182.355 -531.461] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+192.866 531.461 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 511.108 531.461] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -511.108 -531.461] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+511.108 531.461 Td
+/F130_0 9.9626 Tf
+(9) 4.9813 Tj
+[1 0 0 1 516.09 531.461] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7984] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -519.506] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 519.506 Td
+/F130_0 9.9626 Tf
+(3.1.2.) 22.4159 Tj
+-310 TJm
+(High-le) 30.4357 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(el) 7.193 Tj
+-250 TJm
+(summary) 37.0808 Tj
+[1 0 0 1 179.287 519.506] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -184.268 -519.506] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+193.822 519.506 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 511.108 519.506] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -511.108 -519.506] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+511.108 519.506 Td
+/F130_0 9.9626 Tf
+(9) 4.9813 Tj
+[1 0 0 1 516.09 519.506] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7984] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -507.551] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 507.551 Td
+/F130_0 9.9626 Tf
+(3.1.3.) 22.4159 Tj
+-310 TJm
+(Utility) 26.0223 Tj
+-250 TJm
+(functions) 37.0808 Tj
+-250 TJm
+(summary) 37.0808 Tj
+[1 0 0 1 202.669 507.551] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -207.65 -507.551] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+216.582 507.551 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 511.108 507.551] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -511.108 -507.551] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+511.108 507.551 Td
+/F130_0 9.9626 Tf
+(9) 4.9813 Tj
+[1 0 0 1 516.09 507.551] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7983] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -495.596] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 495.596 Td
+/F130_0 9.9626 Tf
+(3.2.) 14.9439 Tj
+-310 TJm
+(Error) 21.0211 Tj
+-250 TJm
+(handling) 34.8691 Tj
+[1 0 0 1 148.413 495.596] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -153.394 -495.596] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+162.611 495.596 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 495.596] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -495.596] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 495.596 Td
+/F130_0 9.9626 Tf
+(10) 9.9626 Tj
+[1 0 0 1 516.09 495.596] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7984] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -483.641] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 483.641 Td
+/F130_0 9.9626 Tf
+(3.3.) 14.9439 Tj
+-310 TJm
+(Lo) 11.0684 Tj
+25 TJm
+(w-le) 17.7035 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(el) 7.193 Tj
+-250 TJm
+(interf) 21.579 Tj
+10 TJm
+(ace) 13.2702 Tj
+[1 0 0 1 167.571 483.641] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -172.552 -483.641] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+181.045 483.641 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 483.641] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -483.641] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 483.641 Td
+/F130_0 9.9626 Tf
+(11) 9.9626 Tj
+[1 0 0 1 516.09 483.641] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -0.0995] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -11.8557] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -471.685] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 471.685 Td
+/F130_0 9.9626 Tf
+(3.3.1.) 22.4159 Tj
+[1 0 0 1 97.5043 471.685] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -97.5043 -471.685] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+97.5043 471.685 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompressInit) 107.596 Tj
+[1 0 0 1 205.101 471.685] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -210.082 -471.685] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+219.736 471.685 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 471.685] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -471.685] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 471.685 Td
+/F130_0 9.9626 Tf
+(11) 9.9626 Tj
+[1 0 0 1 516.09 471.685] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -1.5341] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -10.421] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -459.73] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 459.73 Td
+/F130_0 9.9626 Tf
+(3.3.2.) 22.4159 Tj
+[1 0 0 1 97.5043 459.73] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -97.5043 -459.73] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+97.5043 459.73 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompress) 83.6858 Tj
+[1 0 0 1 181.19 459.73] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -186.172 -459.73] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+194.497 459.73 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 459.73] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -459.73] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 459.73 Td
+/F130_0 9.9626 Tf
+(13) 9.9626 Tj
+[1 0 0 1 516.09 459.73] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -1.5342] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -10.421] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -447.775] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 447.775 Td
+/F130_0 9.9626 Tf
+(3.3.3.) 22.4159 Tj
+[1 0 0 1 97.5043 447.775] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -97.5043 -447.775] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+97.5043 447.775 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompressEnd) 101.619 Tj
+[1 0 0 1 199.123 447.775] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -204.105 -447.775] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+214.533 447.775 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 447.775] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -447.775] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 447.775 Td
+/F130_0 9.9626 Tf
+(16) 9.9626 Tj
+[1 0 0 1 516.09 447.775] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -1.5342] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -10.421] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -435.82] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 435.82 Td
+/F130_0 9.9626 Tf
+(3.3.4.) 22.4159 Tj
+[1 0 0 1 97.5043 435.82] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -97.5043 -435.82] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+97.5043 435.82 Td
+/F134_0 9.9626 Tf
+(BZ2_bzDecompressInit) 119.551 Tj
+[1 0 0 1 217.056 435.82] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -222.037 -435.82] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+232.355 435.82 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 435.82] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -435.82] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 435.82 Td
+/F130_0 9.9626 Tf
+(16) 9.9626 Tj
+[1 0 0 1 516.09 435.82] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -1.5341] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -10.421] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -423.865] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 423.865 Td
+/F130_0 9.9626 Tf
+(3.3.5.) 22.4159 Tj
+[1 0 0 1 97.5043 423.865] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -97.5043 -423.865] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+97.5043 423.865 Td
+/F134_0 9.9626 Tf
+(BZ2_bzDecompress) 95.641 Tj
+[1 0 0 1 193.146 423.865] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -198.127 -423.865] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+207.116 423.865 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 423.865] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -423.865] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 423.865 Td
+/F130_0 9.9626 Tf
+(17) 9.9626 Tj
+[1 0 0 1 516.09 423.865] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -1.5342] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -10.421] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -411.91] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 411.91 Td
+/F130_0 9.9626 Tf
+(3.3.6.) 22.4159 Tj
+[1 0 0 1 97.5043 411.91] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -97.5043 -411.91] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+97.5043 411.91 Td
+/F134_0 9.9626 Tf
+(BZ2_bzDecompressEnd) 113.574 Tj
+[1 0 0 1 211.078 411.91] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -216.06 -411.91] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+224.938 411.91 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 411.91] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -411.91] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 411.91 Td
+/F130_0 9.9626 Tf
+(18) 9.9626 Tj
+[1 0 0 1 516.09 411.91] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -1.5342] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -10.421] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -399.954] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 399.954 Td
+/F130_0 9.9626 Tf
+(3.4.) 14.9439 Tj
+-310 TJm
+(High-le) 30.4357 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(el) 7.193 Tj
+-250 TJm
+(interf) 21.579 Tj
+10 TJm
+(ace) 13.2702 Tj
+[1 0 0 1 169.483 399.954] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -174.465 -399.954] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+184.216 399.954 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 399.954] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -399.954] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 399.954 Td
+/F130_0 9.9626 Tf
+(18) 9.9626 Tj
+[1 0 0 1 516.09 399.954] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7983] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -387.999] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 387.999 Td
+/F130_0 9.9626 Tf
+(3.4.1.) 22.4159 Tj
+[1 0 0 1 97.5043 387.999] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -97.5043 -387.999] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+97.5043 387.999 Td
+/F134_0 9.9626 Tf
+(BZ2_bzReadOpen) 83.6858 Tj
+[1 0 0 1 181.19 387.999] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -186.172 -387.999] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+194.497 387.999 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 387.999] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -387.999] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 387.999 Td
+/F130_0 9.9626 Tf
+(19) 9.9626 Tj
+[1 0 0 1 516.09 387.999] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -1.5342] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -10.421] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -376.044] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 376.044 Td
+/F130_0 9.9626 Tf
+(3.4.2.) 22.4159 Tj
+[1 0 0 1 97.5043 376.044] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -97.5043 -376.044] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+97.5043 376.044 Td
+/F134_0 9.9626 Tf
+(BZ2_bzRead) 59.7756 Tj
+[1 0 0 1 157.28 376.044] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -162.261 -376.044] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+171.472 376.044 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 376.044] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -376.044] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 376.044 Td
+/F130_0 9.9626 Tf
+(20) 9.9626 Tj
+[1 0 0 1 516.09 376.044] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -1.31] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -10.6452] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -364.089] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 364.089 Td
+/F130_0 9.9626 Tf
+(3.4.3.) 22.4159 Tj
+[1 0 0 1 97.5043 364.089] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -97.5043 -364.089] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+97.5043 364.089 Td
+/F134_0 9.9626 Tf
+(BZ2_bzReadGetUnused) 113.574 Tj
+[1 0 0 1 211.078 364.089] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -216.06 -364.089] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+224.938 364.089 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 364.089] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -364.089] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 364.089 Td
+/F130_0 9.9626 Tf
+(21) 9.9626 Tj
+[1 0 0 1 516.09 364.089] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -1.31] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -10.6452] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -352.134] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 352.134 Td
+/F130_0 9.9626 Tf
+(3.4.4.) 22.4159 Tj
+[1 0 0 1 97.5043 352.134] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -97.5043 -352.134] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+97.5043 352.134 Td
+/F134_0 9.9626 Tf
+(BZ2_bzReadClose) 89.6634 Tj
+[1 0 0 1 187.168 352.134] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -192.149 -352.134] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+201.914 352.134 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 352.134] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -352.134] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 352.134 Td
+/F130_0 9.9626 Tf
+(22) 9.9626 Tj
+[1 0 0 1 516.09 352.134] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -1.31] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -10.6451] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -340.179] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 340.179 Td
+/F130_0 9.9626 Tf
+(3.4.5.) 22.4159 Tj
+[1 0 0 1 97.5043 340.179] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -97.5043 -340.179] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+97.5043 340.179 Td
+/F134_0 9.9626 Tf
+(BZ2_bzWriteOpen) 89.6634 Tj
+[1 0 0 1 187.168 340.179] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -192.149 -340.179] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+201.914 340.179 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 340.179] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -340.179] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 340.179 Td
+/F130_0 9.9626 Tf
+(22) 9.9626 Tj
+[1 0 0 1 516.09 340.179] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -1.5342] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -10.421] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -328.223] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 328.223 Td
+/F130_0 9.9626 Tf
+(3.4.6.) 22.4159 Tj
+[1 0 0 1 97.5043 328.223] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -97.5043 -328.223] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+97.5043 328.223 Td
+/F134_0 9.9626 Tf
+(BZ2_bzWrite) 65.7532 Tj
+[1 0 0 1 163.258 328.223] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -168.239 -328.223] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+176.675 328.223 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 328.223] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -328.223] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 328.223 Td
+/F130_0 9.9626 Tf
+(23) 9.9626 Tj
+[1 0 0 1 516.09 328.223] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -1.31] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -10.6452] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -316.268] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 316.268 Td
+/F130_0 9.9626 Tf
+(3.4.7.) 22.4159 Tj
+[1 0 0 1 97.5043 316.268] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -97.5043 -316.268] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+97.5043 316.268 Td
+/F134_0 9.9626 Tf
+(BZ2_bzWriteClose) 95.641 Tj
+[1 0 0 1 193.146 316.268] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -198.127 -316.268] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+207.116 316.268 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 316.268] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -316.268] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 316.268 Td
+/F130_0 9.9626 Tf
+(23) 9.9626 Tj
+[1 0 0 1 516.09 316.268] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -1.31] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -10.6451] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -304.313] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 304.313 Td
+/F130_0 9.9626 Tf
+(3.4.8.) 22.4159 Tj
+-310 TJm
+(Handling) 37.0808 Tj
+-250 TJm
+(embedded) 40.9463 Tj
+-250 TJm
+(compressed) 47.0334 Tj
+-250 TJm
+(data) 16.5977 Tj
+-250 TJm
+(streams) 30.4357 Tj
+[1 0 0 1 279.56 304.313] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -284.541 -304.313] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+294.601 304.313 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 304.313] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -304.313] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 304.313 Td
+/F130_0 9.9626 Tf
+(24) 9.9626 Tj
+[1 0 0 1 516.09 304.313] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7984] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -292.358] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 292.358 Td
+/F130_0 9.9626 Tf
+(3.4.9.) 22.4159 Tj
+-310 TJm
+(Standard) 35.417 Tj
+-250 TJm
+(\002le-reading/writing) 77.4791 Tj
+-250 TJm
+(code) 18.8094 Tj
+[1 0 0 1 234.19 292.358] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -239.172 -292.358] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+247.564 292.358 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 292.358] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -292.358] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 292.358 Td
+/F130_0 9.9626 Tf
+(25) 9.9626 Tj
+[1 0 0 1 516.09 292.358] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7984] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -280.403] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 280.403 Td
+/F130_0 9.9626 Tf
+(3.5.) 14.9439 Tj
+-310 TJm
+(Utility) 26.0223 Tj
+-250 TJm
+(functions) 37.0808 Tj
+[1 0 0 1 155.625 280.403] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -160.607 -280.403] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+170.645 280.403 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 280.403] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -280.403] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 280.403 Td
+/F130_0 9.9626 Tf
+(26) 9.9626 Tj
+[1 0 0 1 516.09 280.403] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7983] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -268.448] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 268.448 Td
+/F130_0 9.9626 Tf
+(3.5.1.) 22.4159 Tj
+[1 0 0 1 97.5043 268.448] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -97.5043 -268.448] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+97.5043 268.448 Td
+/F134_0 9.9626 Tf
+(BZ2_bzBuffToBuffCompress) 143.461 Tj
+[1 0 0 1 240.966 268.448] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -245.948 -268.448] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+255.38 268.448 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 268.448] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -268.448] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 268.448 Td
+/F130_0 9.9626 Tf
+(26) 9.9626 Tj
+[1 0 0 1 516.09 268.448] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -1.5342] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -10.421] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -256.492] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 256.492 Td
+/F130_0 9.9626 Tf
+(3.5.2.) 22.4159 Tj
+[1 0 0 1 97.5043 256.492] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -97.5043 -256.492] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+97.5043 256.492 Td
+/F134_0 9.9626 Tf
+(BZ2_bzBuffToBuffDecompress) 155.417 Tj
+[1 0 0 1 252.922 256.492] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -257.903 -256.492] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+267.999 256.492 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 256.492] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -256.492] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 256.492 Td
+/F130_0 9.9626 Tf
+(27) 9.9626 Tj
+[1 0 0 1 516.09 256.492] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -1.5342] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -10.421] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -244.537] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 244.537 Td
+/F130_0 9.9626 Tf
+(3.6.) 14.9439 Tj
+[1 0 0 1 90.0324 244.537] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90.0324 -244.537] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90.0324 244.537 Td
+/F134_0 9.9626 Tf
+(zlib) 23.9102 Tj
+[1 0 0 1 113.943 244.537] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -113.943 -244.537] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+116.433 244.537 Td
+/F130_0 9.9626 Tf
+(compatibility) 53.1405 Tj
+-250 TJm
+(functions) 37.0808 Tj
+[1 0 0 1 209.144 244.537] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -214.126 -244.537] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+223.971 244.537 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 244.537] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -244.537] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 244.537 Td
+/F130_0 9.9626 Tf
+(28) 9.9626 Tj
+[1 0 0 1 516.09 244.537] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7983] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -232.582] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 232.582 Td
+/F130_0 9.9626 Tf
+(3.7.) 14.9439 Tj
+-310 TJm
+(Using) 23.8007 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(library) 26.5603 Tj
+-250 TJm
+(in) 7.7509 Tj
+-250 TJm
+(a) 4.42339 Tj
+[1 0 0 1 177.195 232.582] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -177.195 -232.582] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+177.195 232.582 Td
+/F134_0 9.9626 Tf
+(stdio) 29.8878 Tj
+[1 0 0 1 207.083 232.582] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -207.083 -232.582] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+207.083 232.582 Td
+/F130_0 9.9626 Tf
+(-free) 18.7994 Tj
+-250 TJm
+(en) 9.40469 Tj
+40 TJm
+(vironment) 40.9562 Tj
+[1 0 0 1 278.335 232.582] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -283.316 -232.582] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+291.775 232.582 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 232.582] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -232.582] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 232.582 Td
+/F130_0 9.9626 Tf
+(28) 9.9626 Tj
+[1 0 0 1 516.09 232.582] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7984] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -220.627] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 220.627 Td
+/F130_0 9.9626 Tf
+(3.7.1.) 22.4159 Tj
+-310 TJm
+(Getting) 29.8878 Tj
+-250 TJm
+(rid) 11.0684 Tj
+-250 TJm
+(of) 8.29885 Tj
+[1 0 0 1 154.231 220.627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -154.231 -220.627] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+154.231 220.627 Td
+/F134_0 9.9626 Tf
+(stdio) 29.8878 Tj
+[1 0 0 1 184.119 220.627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -189.1 -220.627] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+198.175 220.627 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 220.627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -220.627] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 220.627 Td
+/F130_0 9.9626 Tf
+(29) 9.9626 Tj
+[1 0 0 1 516.09 220.627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7984] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -208.672] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 208.672 Td
+/F130_0 9.9626 Tf
+(3.7.2.) 22.4159 Tj
+-310 TJm
+(Critical) 29.8878 Tj
+-250 TJm
+(error) 19.3573 Tj
+-250 TJm
+(handling) 34.8691 Tj
+[1 0 0 1 186.599 208.672] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -191.58 -208.672] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+201.629 208.672 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 208.672] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -208.672] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 208.672 Td
+/F130_0 9.9626 Tf
+(29) 9.9626 Tj
+[1 0 0 1 516.09 208.672] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7983] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -196.717] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 196.717 Td
+/F130_0 9.9626 Tf
+(3.8.) 14.9439 Tj
+-310 TJm
+(Making) 30.9936 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(W) 9.40469 Tj
+40 TJm
+(indo) 17.7135 Tj
+25 TJm
+(ws) 11.0684 Tj
+-250 TJm
+(DLL) 19.3673 Tj
+[1 0 0 1 189.828 196.717] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -194.809 -196.717] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+203.243 196.717 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 196.717] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -196.717] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 196.717 Td
+/F130_0 9.9626 Tf
+(29) 9.9626 Tj
+[1 0 0 1 516.09 196.717] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -2.1569] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7983] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -184.761] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 184.761 Td
+/F130_0 9.9626 Tf
+(4.) 7.47195 Tj
+-310 TJm
+(Miscellanea) 48.1393 Tj
+[1 0 0 1 130.699 184.761] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -135.68 -184.761] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+144.898 184.761 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 184.761] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -184.761] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 184.761 Td
+/F130_0 9.9626 Tf
+(31) 9.9626 Tj
+[1 0 0 1 516.09 184.761] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -0.0995] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -11.8557] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -172.806] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 172.806 Td
+/F130_0 9.9626 Tf
+(4.1.) 14.9439 Tj
+-310 TJm
+(Limitations) 45.9475 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(compressed) 47.0334 Tj
+-250 TJm
+(\002le) 12.7322 Tj
+-250 TJm
+(format) 26.5603 Tj
+[1 0 0 1 255.231 172.806] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -260.212 -172.806] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+269.154 172.806 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 172.806] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -172.806] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 172.806 Td
+/F130_0 9.9626 Tf
+(31) 9.9626 Tj
+[1 0 0 1 516.09 172.806] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7983] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -160.851] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 160.851 Td
+/F130_0 9.9626 Tf
+(4.2.) 14.9439 Tj
+-310 TJm
+(Portability) 42.0721 Tj
+-250 TJm
+(issues) 23.8007 Tj
+[1 0 0 1 158.395 160.851] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -163.376 -160.851] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+172.03 160.851 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 160.851] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -160.851] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 160.851 Td
+/F130_0 9.9626 Tf
+(32) 9.9626 Tj
+[1 0 0 1 516.09 160.851] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -2.1569] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7983] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -148.896] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 148.896 Td
+/F130_0 9.9626 Tf
+(4.3.) 14.9439 Tj
+-310 TJm
+(Reporting) 39.8504 Tj
+-250 TJm
+(b) 4.9813 Tj
+20 TJm
+(ugs) 13.8381 Tj
+[1 0 0 1 150.993 148.896] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -155.975 -148.896] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+166.115 148.896 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 148.896] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -148.896] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 148.896 Td
+/F130_0 9.9626 Tf
+(32) 9.9626 Tj
+[1 0 0 1 516.09 148.896] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7984] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -136.941] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 136.941 Td
+/F130_0 9.9626 Tf
+(4.4.) 14.9439 Tj
+-310 TJm
+(Did) 14.9439 Tj
+-250 TJm
+(you) 14.9439 Tj
+-250 TJm
+(get) 12.1743 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(right) 18.8194 Tj
+-250 TJm
+(package?) 37.0609 Tj
+[1 0 0 1 212.602 136.941] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 3.0884 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 3.0884 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -218.778 -136.941] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+229.109 136.941 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 136.941] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -136.941] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 136.941 Td
+/F130_0 9.9626 Tf
+(33) 9.9626 Tj
+[1 0 0 1 516.09 136.941] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7983] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -124.986] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 124.986 Td
+/F130_0 9.9626 Tf
+(4.5.) 14.9439 Tj
+-310 TJm
+(Further) 29.3299 Tj
+-250 TJm
+(Reading) 33.2053 Tj
+[1 0 0 1 155.058 124.986] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -160.039 -124.986] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+170.361 124.986 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 124.986] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -124.986] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 124.986 Td
+/F130_0 9.9626 Tf
+(34) 9.9626 Tj
+[1 0 0 1 516.09 124.986] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -2.1569] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 0 -62.0143] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 374.394 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 41.3997 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -494.668 -50.8518] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+536.068 50.8518 Td
+/F130_0 9.9626 Tf
+(iii) 8.30881 Tj
+[1 0 0 1 453.269 50.8518] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 93.5985 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.2765 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+Q
+showpage
+%%PageTrailer
+pdfEndPage
+%%Page: 4 4
+%%BeginPageSetup
+%%PageOrientation: Portrait
+pdfStartPage
+0 0 612 792 re W
+%%EndPageSetup
+[] 0 d
+1 i
+0 j
+0 J
+10 M
+1 w
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+false op
+false OP
+0 0 612 792 re
+W
+q
+[1 0 0 1 72 741.554] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 14.4459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 187.197 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 140.398 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -140.398 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 280.796 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -472.974 -13.9477] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -0.4981] cm
+q
+[] 0 d
+0 J
+0.4981 w
+0 0.2491 m
+475.465 0.2491 l
+S
+Q
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 479.251 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -468 -21.5542] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -720] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 701.916 Td
+/F122_0 24.7902 Tf
+(1.) 20.675 Tj
+-278 TJm
+(Intr) 39.937 Tj
+20 TJm
+(oduction) 104.664 Tj
+[1 0 0 1 72 701.606] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -691.643] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 679.998 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 101.888 679.998] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -101.888 -679.998] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+104.507 679.998 Td
+/F130_0 9.9626 Tf
+(compresses) 45.9276 Tj
+-263 TJm
+(\002les) 16.6077 Tj
+-263 TJm
+(using) 21.589 Tj
+-263 TJm
+(the) 12.1743 Tj
+-262 TJm
+(Burro) 23.2427 Tj
+25 TJm
+(ws-Wheeler) 48.1293 Tj
+-263 TJm
+(block-sorting) 53.1305 Tj
+-263 TJm
+(te) 7.193 Tj
+15 TJm
+(xt) 7.7509 Tj
+-263 TJm
+(compression) 50.3609 Tj
+-263 TJm
+(algorithm,) 41.2352 Tj
+-266 TJm
+(and) 14.386 Tj
+-263 TJm
+(Huf) 15.4918 Tj
+25 TJm
+(fman) 20.4731 Tj
+-263 TJm
+(coding.) 29.6088 Tj
+72 668.043 Td
+(Compression) 52.5826 Tj
+-203 TJm
+(is) 6.64505 Tj
+-204 TJm
+(generally) 37.0708 Tj
+-203 TJm
+(considerably) 50.9089 Tj
+-203 TJm
+(better) 22.6848 Tj
+-204 TJm
+(t) 2.7696 Tj
+1 TJm
+(han) 14.386 Tj
+-204 TJm
+(that) 14.9439 Tj
+-203 TJm
+(achie) 21.0211 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(ed) 9.40469 Tj
+-203 TJm
+(by) 9.9626 Tj
+-204 TJm
+(more) 20.4731 Tj
+-203 TJm
+(con) 14.386 Tj
+40 TJm
+(v) 4.9813 Tj
+15 TJm
+(entional) 32.0995 Tj
+-203 TJm
+(LZ77/LZ78-based) 73.0458 Tj
+-204 TJm
+(compressors,) 52.2937 Tj
+72 656.087 Td
+(and) 14.386 Tj
+-250 TJm
+(approaches) 44.8118 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(performance) 50.341 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(PPM) 19.9352 Tj
+-250 TJm
+(f) 3.31755 Tj
+10 TJm
+(amily) 22.6948 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(statistical) 37.6387 Tj
+-250 TJm
+(compressors.) 52.2937 Tj
+[1 0 0 1 72 653.931] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -643.968] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 634.17 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 101.888 634.17] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -101.888 -634.17] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+105.073 634.17 Td
+/F130_0 9.9626 Tf
+(is) 6.64505 Tj
+-320 TJm
+(b) 4.9813 Tj
+20 TJm
+(uilt) 13.2901 Tj
+-319 TJm
+(on) 9.9626 Tj
+-320 TJm
+(top) 12.7322 Tj
+-320 TJm
+(of) 8.29885 Tj
+[1 0 0 1 176.712 634.17] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -176.712 -634.17] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+176.712 634.17 Td
+/F134_0 9.9626 Tf
+(libbzip2) 47.8205 Tj
+[1 0 0 1 224.533 634.17] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -224.533 -634.17] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+224.533 634.17 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-337 TJm
+(a) 4.42339 Tj
+-320 TJm
+(\003e) 9.9626 Tj
+15 TJm
+(xible) 19.9252 Tj
+-320 TJm
+(library) 26.5603 Tj
+-319 TJm
+(for) 11.6164 Tj
+-320 TJm
+(handling) 34.8691 Tj
+-320 TJm
+(compressed) 47.0334 Tj
+-320 TJm
+(data) 16.5977 Tj
+-319 TJm
+(in) 7.7509 Tj
+-320 TJm
+(the) 12.1743 Tj
+[1 0 0 1 449.816 634.17] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -449.816 -634.17] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+449.816 634.17 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 479.704 634.17] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -479.704 -634.17] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+482.889 634.17 Td
+/F130_0 9.9626 Tf
+(format.) 29.0509 Tj
+-1039 TJm
+(This) 17.7135 Tj
+72 622.214 Td
+(manual) 29.3299 Tj
+-316 TJm
+(describes) 37.0708 Tj
+-316 TJm
+(both) 17.7135 Tj
+-317 TJm
+(ho) 9.9626 Tj
+25 TJm
+(w) 7.193 Tj
+-316 TJm
+(to) 7.7509 Tj
+-316 TJm
+(use) 13.2801 Tj
+-316 TJm
+(the) 12.1743 Tj
+-316 TJm
+(program) 33.7533 Tj
+-316 TJm
+(and) 14.386 Tj
+-317 TJm
+(ho) 9.9626 Tj
+25 TJm
+(w) 7.193 Tj
+-316 TJm
+(to) 7.7509 Tj
+-316 TJm
+(w) 7.193 Tj
+10 TJm
+(ork) 13.2801 Tj
+-316 TJm
+(with) 17.7135 Tj
+-316 TJm
+(the) 12.1743 Tj
+-317 TJm
+(library) 26.5603 Tj
+-316 TJm
+(interf) 21.579 Tj
+10 TJm
+(ace.) 15.7608 Tj
+-1017 TJm
+(Most) 20.4831 Tj
+-316 TJm
+(of) 8.29885 Tj
+-316 TJm
+(the) 12.1743 Tj
+-317 TJm
+(manual) 29.3299 Tj
+-316 TJm
+(is) 6.64505 Tj
+72 610.259 Td
+(de) 9.40469 Tj
+25 TJm
+(v) 4.9813 Tj
+20 TJm
+(oted) 17.1556 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(this) 14.396 Tj
+-250 TJm
+(library) 26.5603 Tj
+65 TJm
+(,) 2.49065 Tj
+-250 TJm
+(not) 12.7322 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(program,) 36.2439 Tj
+-250 TJm
+(which) 24.3486 Tj
+-250 TJm
+(is) 6.64505 Tj
+-250 TJm
+(good) 19.9252 Tj
+-250 TJm
+(ne) 9.40469 Tj
+25 TJm
+(ws) 11.0684 Tj
+-250 TJm
+(if) 6.08715 Tj
+-250 TJm
+(your) 18.2614 Tj
+-250 TJm
+(interest) 29.3299 Tj
+-250 TJm
+(is) 6.64505 Tj
+-250 TJm
+(only) 17.7135 Tj
+-250 TJm
+(in) 7.7509 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(program.) 36.2439 Tj
+[1 0 0 1 72 608.102] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 0 -29.7236] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 6.9739 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -78.9739 -578.379] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+78.9739 578.379 Td
+/F130_0 9.9626 Tf
+(\225) 3.48691 Tj
+[1 0 0 1 82.4608 578.379] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.9925 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 1] sc
+/DeviceRGB {} CS
+[0 0 1] SC
+[1 0 0 1 -86.944 -578.379] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 578.379 Td
+/F130_0 9.9626 Tf
+(Ho) 12.1743 Tj
+25 TJm
+(w) 7.193 Tj
+-259 TJm
+(to) 7.7509 Tj
+-260 TJm
+(use) 13.2801 Tj
+-259 TJm
+(bzip2) 22.1369 Tj
+[1 0 0 1 156.985 578.379] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 1] sc
+/DeviceRGB {} CS
+[0 0 1] SC
+/DeviceRGB {} cs
+[0 0 1] sc
+/DeviceRGB {} CS
+[0 0 1] SC
+[1 0 0 1 -156.985 -578.379] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+159.57 578.379 Td
+/F130_0 9.9626 Tf
+([2]) 11.6164 Tj
+[1 0 0 1 171.186 578.379] cm
+/DeviceRGB {} cs
+[0 0 1] sc
+/DeviceRGB {} CS
+[0 0 1] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -171.186 -578.379] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+173.771 578.379 Td
+/F130_0 9.9626 Tf
+(describes) 37.0708 Tj
+-259 TJm
+(ho) 9.9626 Tj
+25 TJm
+(w) 7.193 Tj
+-260 TJm
+(to) 7.7509 Tj
+-259 TJm
+(use) 13.2801 Tj
+[1 0 0 1 259.119 578.379] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -259.119 -578.379] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+259.119 578.379 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 289.007 578.379] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -289.007 -578.379] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+289.007 578.379 Td
+/F130_0 9.9626 Tf
+(;) 2.7696 Tj
+-264 TJm
+(this) 14.396 Tj
+-260 TJm
+(is) 6.64505 Tj
+-259 TJm
+(the) 12.1743 Tj
+-260 TJm
+(only) 17.7135 Tj
+-259 TJm
+(part) 15.4918 Tj
+-259 TJm
+(you) 14.9439 Tj
+-260 TJm
+(need) 18.8094 Tj
+-259 TJm
+(to) 7.7509 Tj
+-260 TJm
+(read) 17.1456 Tj
+-259 TJm
+(if) 6.08715 Tj
+-260 TJm
+(you) 14.9439 Tj
+-259 TJm
+(just) 14.396 Tj
+-260 TJm
+(w) 7.193 Tj
+10 TJm
+(ant) 12.1743 Tj
+-259 TJm
+(to) 7.7509 Tj
+-260 TJm
+(kno) 14.9439 Tj
+25 TJm
+(w) 7.193 Tj
+86.944 566.424 Td
+(ho) 9.9626 Tj
+25 TJm
+(w) 7.193 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(operate) 29.3199 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(program.) 36.2439 Tj
+[1 0 0 1 199.302 566.424] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -127.302 -21.9178] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 6.9739 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -78.9739 -544.506] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+78.9739 544.506 Td
+/F130_0 9.9626 Tf
+(\225) 3.48691 Tj
+[1 0 0 1 82.4608 544.506] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.9925 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 1] sc
+/DeviceRGB {} CS
+[0 0 1] SC
+[1 0 0 1 -86.944 -544.506] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 544.506 Td
+/F130_0 9.9626 Tf
+(Programming) 54.7943 Tj
+-250 TJm
+(with) 17.7135 Tj
+-250 TJm
+(libbzip2) 32.6574 Tj
+[1 0 0 1 197.09 544.506] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 1] sc
+/DeviceRGB {} CS
+[0 0 1] SC
+/DeviceRGB {} cs
+[0 0 1] sc
+/DeviceRGB {} CS
+[0 0 1] SC
+[1 0 0 1 -197.09 -544.506] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+199.58 544.506 Td
+/F130_0 9.9626 Tf
+([8]) 11.6164 Tj
+[1 0 0 1 211.197 544.506] cm
+/DeviceRGB {} cs
+[0 0 1] sc
+/DeviceRGB {} CS
+[0 0 1] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -211.197 -544.506] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+213.687 544.506 Td
+/F130_0 9.9626 Tf
+(describes) 37.0708 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(programming) 54.2364 Tj
+-250 TJm
+(interf) 21.579 Tj
+10 TJm
+(aces) 17.1456 Tj
+-250 TJm
+(in) 7.7509 Tj
+-250 TJm
+(detail,) 24.6275 Tj
+-250 TJm
+(and) 14.386 Tj
+[1 0 0 1 417.501 544.506] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -345.501 -21.9178] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 6.9739 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -78.9739 -522.588] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+78.9739 522.588 Td
+/F130_0 9.9626 Tf
+(\225) 3.48691 Tj
+[1 0 0 1 82.4608 522.588] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.9925 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 1] sc
+/DeviceRGB {} CS
+[0 0 1] SC
+[1 0 0 1 -86.944 -522.588] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 522.588 Td
+/F130_0 9.9626 Tf
+(Miscellanea) 48.1393 Tj
+[1 0 0 1 135.083 522.588] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 1] sc
+/DeviceRGB {} CS
+[0 0 1] SC
+/DeviceRGB {} cs
+[0 0 1] sc
+/DeviceRGB {} CS
+[0 0 1] SC
+[1 0 0 1 -135.083 -522.588] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+137.573 522.588 Td
+/F130_0 9.9626 Tf
+([31]) 16.5977 Tj
+[1 0 0 1 154.171 522.588] cm
+/DeviceRGB {} cs
+[0 0 1] sc
+/DeviceRGB {} CS
+[0 0 1] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -154.171 -522.588] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+156.662 522.588 Td
+/F130_0 9.9626 Tf
+(records) 29.3199 Tj
+-250 TJm
+(some) 21.031 Tj
+-250 TJm
+(miscellaneous) 56.4481 Tj
+-250 TJm
+(notes) 21.031 Tj
+-250 TJm
+(which) 24.3486 Tj
+-250 TJm
+(I) 3.31755 Tj
+-250 TJm
+(thought) 30.4457 Tj
+-250 TJm
+(ought) 22.6948 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(be) 9.40469 Tj
+-250 TJm
+(recorded) 34.8492 Tj
+-250 TJm
+(some) 21.031 Tj
+25 TJm
+(where.) 26.8293 Tj
+[1 0 0 1 492.31 522.588] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -420.31 -471.736] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 374.394 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 43.0633 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -496.332 -50.8518] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+539.395 50.8518 Td
+/F130_0 9.9626 Tf
+(1) 4.9813 Tj
+[1 0 0 1 453.269 50.8518] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 93.5985 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.2765 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+Q
+showpage
+%%PageTrailer
+pdfEndPage
+%%Page: 5 5
+%%BeginPageSetup
+%%PageOrientation: Portrait
+pdfStartPage
+0 0 612 792 re W
+%%EndPageSetup
+[] 0 d
+1 i
+0 j
+0 J
+10 M
+1 w
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+false op
+false OP
+0 0 612 792 re
+W
+q
+[1 0 0 1 72 741.554] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 14.4459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 187.197 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 140.398 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -140.398 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 280.796 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -472.974 -13.9477] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -0.4981] cm
+q
+[] 0 d
+0 J
+0.4981 w
+0 0.2491 m
+475.465 0.2491 l
+S
+Q
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 479.251 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -21.5542] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -720] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 701.916 Td
+/F122_0 24.7902 Tf
+(2.) 20.675 Tj
+-278 TJm
+(Ho) 33.0453 Tj
+15 TJm
+(w) 19.2868 Tj
+-278 TJm
+(to) 23.4019 Tj
+-278 TJm
+(use) 42.7135 Tj
+-278 TJm
+(bzip2) 63.3638 Tj
+[1 0 0 1 72 696.784] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -14.944] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -671.877] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 656.35 Td
+/F122_0 17.2154 Tf
+(T) 10.5186 Tj
+80 TJm
+(ab) 20.0904 Tj
+10 TJm
+(le) 14.3576 Tj
+-278 TJm
+(of) 16.2513 Tj
+-278 TJm
+(Contents) 74.5943 Tj
+[1 0 0 1 72 647.528] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -11.7401] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -635.788] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 635.788 Td
+/F130_0 9.9626 Tf
+(2.1.) 14.9439 Tj
+-310 TJm
+(N) 7.193 Tj
+35 TJm
+(AME) 22.1369 Tj
+[1 0 0 1 119.014 635.788] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -123.995 -635.788] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+132.691 635.788 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 511.108 635.788] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -511.108 -635.788] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+511.108 635.788 Td
+/F130_0 9.9626 Tf
+(2) 4.9813 Tj
+[1 0 0 1 516.09 635.788] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -0.0995] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -11.8556] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -623.832] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 623.832 Td
+/F130_0 9.9626 Tf
+(2.2.) 14.9439 Tj
+-310 TJm
+(SYNOPSIS) 47.0534 Tj
+[1 0 0 1 137.085 623.832] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -142.067 -623.832] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+150.582 623.832 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 511.108 623.832] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -511.108 -623.832] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+511.108 623.832 Td
+/F130_0 9.9626 Tf
+(2) 4.9813 Tj
+[1 0 0 1 516.09 623.832] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -0.0996] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -11.8556] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -611.877] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 611.877 Td
+/F130_0 9.9626 Tf
+(2.3.) 14.9439 Tj
+-310 TJm
+(DESCRIPTION) 64.7569 Tj
+[1 0 0 1 154.789 611.877] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -159.77 -611.877] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+168.29 611.877 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 511.108 611.877] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -511.108 -611.877] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+511.108 611.877 Td
+/F130_0 9.9626 Tf
+(3) 4.9813 Tj
+[1 0 0 1 516.09 611.877] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -0.0995] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -11.8557] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -599.922] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 599.922 Td
+/F130_0 9.9626 Tf
+(2.4.) 14.9439 Tj
+-310 TJm
+(OPTIONS) 42.0621 Tj
+[1 0 0 1 132.094 599.922] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -137.076 -599.922] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+145.873 599.922 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 511.108 599.922] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -511.108 -599.922] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+511.108 599.922 Td
+/F130_0 9.9626 Tf
+(4) 4.9813 Tj
+[1 0 0 1 516.09 599.922] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -0.0995] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -11.8556] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -587.967] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 587.967 Td
+/F130_0 9.9626 Tf
+(2.5.) 14.9439 Tj
+-310 TJm
+(MEMOR) 37.6387 Tj
+65 TJm
+(Y) 7.193 Tj
+-250 TJm
+(MAN) 23.2427 Tj
+35 TJm
+(A) 7.193 Tj
+40 TJm
+(GEMENT) 41.5042 Tj
+[1 0 0 1 207.9 587.967] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -212.881 -587.967] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+221.412 587.967 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 511.108 587.967] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -511.108 -587.967] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+511.108 587.967 Td
+/F130_0 9.9626 Tf
+(5) 4.9813 Tj
+[1 0 0 1 516.09 587.967] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -0.0996] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -11.8556] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -576.012] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 576.012 Td
+/F130_0 9.9626 Tf
+(2.6.) 14.9439 Tj
+-310 TJm
+(RECO) 26.5703 Tj
+50 TJm
+(VERING) 37.6287 Tj
+-250 TJm
+(D) 7.193 Tj
+40 TJm
+(A) 7.193 Tj
+111 TJm
+(T) 6.08715 Tj
+93 TJm
+(A) 7.193 Tj
+-250 TJm
+(FR) 12.1843 Tj
+40 TJm
+(OM) 16.0497 Tj
+-250 TJm
+(D) 7.193 Tj
+40 TJm
+(AMA) 23.2427 Tj
+40 TJm
+(GED) 20.4731 Tj
+-250 TJm
+(FILES) 26.5703 Tj
+[1 0 0 1 293.449 576.012] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -298.43 -576.012] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+308.464 576.012 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 511.108 576.012] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -511.108 -576.012] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+511.108 576.012 Td
+/F130_0 9.9626 Tf
+(6) 4.9813 Tj
+[1 0 0 1 516.09 576.012] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -0.0995] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -11.8557] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -564.056] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 564.056 Td
+/F130_0 9.9626 Tf
+(2.7.) 14.9439 Tj
+-310 TJm
+(PERFORMANCE) 73.6236 Tj
+-250 TJm
+(NO) 14.386 Tj
+40 TJm
+(TES) 17.7135 Tj
+[1 0 0 1 197.847 564.056] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -202.829 -564.056] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+211.958 564.056 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 511.108 564.056] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -511.108 -564.056] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+511.108 564.056 Td
+/F130_0 9.9626 Tf
+(6) 4.9813 Tj
+[1 0 0 1 516.09 564.056] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -0.0995] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -11.8556] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -552.101] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 552.101 Td
+/F130_0 9.9626 Tf
+(2.8.) 14.9439 Tj
+-310 TJm
+(CA) 13.8381 Tj
+135 TJm
+(VEA) 20.4731 Tj
+111 TJm
+(TS) 11.6264 Tj
+[1 0 0 1 133.519 552.101] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -138.5 -552.101] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+148.799 552.101 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 511.108 552.101] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -511.108 -552.101] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+511.108 552.101 Td
+/F130_0 9.9626 Tf
+(7) 4.9813 Tj
+[1 0 0 1 516.09 552.101] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -0.0996] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -11.8556] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -540.146] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 540.146 Td
+/F130_0 9.9626 Tf
+(2.9.) 14.9439 Tj
+-310 TJm
+(A) 7.193 Tj
+55 TJm
+(UTHOR) 34.3112 Tj
+[1 0 0 1 130.989 540.146] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -135.97 -540.146] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+145.32 540.146 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 511.108 540.146] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -511.108 -540.146] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+511.108 540.146 Td
+/F130_0 9.9626 Tf
+(7) 4.9813 Tj
+[1 0 0 1 516.09 540.146] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -0.2191] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -520.002] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 508.266 Td
+/F130_0 9.9626 Tf
+(This) 17.7135 Tj
+-250 TJm
+(chapter) 29.3199 Tj
+-250 TJm
+(contains) 33.2053 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(cop) 14.386 Tj
+10 TJm
+(y) 4.9813 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(the) 12.1743 Tj
+[1 0 0 1 213.837 508.266] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -213.837 -508.266] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+213.837 508.266 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 243.725 508.266] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -243.725 -508.266] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+246.215 508.266 Td
+/F130_0 9.9626 Tf
+(man) 17.1556 Tj
+-250 TJm
+(page,) 21.3 Tj
+-250 TJm
+(and) 14.386 Tj
+-250 TJm
+(nothing) 30.4457 Tj
+-250 TJm
+(else.) 17.9825 Tj
+[1 0 0 1 72 506.109] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -496.146] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 473.513 Td
+/F122_0 20.6585 Tf
+(2.1.) 34.4584 Tj
+-278 TJm
+(NAME) 60.8186 Tj
+[1 0 0 1 72 473.513] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -31.8804] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.9739 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -78.9739 -441.632] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+78.9739 441.632 Td
+/F130_0 9.9626 Tf
+(\225) 3.48691 Tj
+[1 0 0 1 82.4608 441.632] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 1.9925 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -86.944 -441.632] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 441.632 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 116.832 441.632] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -116.832 -441.632] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+116.832 441.632 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 121.813 441.632] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -121.813 -441.632] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+121.813 441.632 Td
+/F134_0 9.9626 Tf
+(bunzip2) 41.8429 Tj
+[1 0 0 1 163.656 441.632] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -163.656 -441.632] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+166.147 441.632 Td
+/F130_0 9.9626 Tf
+(-) 3.31755 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(block-sorting) 53.1305 Tj
+-250 TJm
+(\002le) 12.7322 Tj
+-250 TJm
+(compressor) 45.9276 Tj
+40 TJm
+(,) 2.49065 Tj
+-250 TJm
+(v1.0.4) 24.9065 Tj
+[1 0 0 1 325.129 441.632] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -253.129 -21.9179] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.9739 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -78.9739 -419.715] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+78.9739 419.715 Td
+/F130_0 9.9626 Tf
+(\225) 3.48691 Tj
+[1 0 0 1 82.4608 419.715] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 1.9925 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -86.944 -419.715] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 419.715 Td
+/F134_0 9.9626 Tf
+(bzcat) 29.8878 Tj
+[1 0 0 1 116.832 419.715] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -116.832 -419.715] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+119.322 419.715 Td
+/F130_0 9.9626 Tf
+(-) 3.31755 Tj
+-250 TJm
+(decompresses) 55.3323 Tj
+-250 TJm
+(\002les) 16.6077 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(stdout) 24.3586 Tj
+[1 0 0 1 236.651 419.715] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -164.651 -21.9178] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.9739 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -78.9739 -397.797] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+78.9739 397.797 Td
+/F130_0 9.9626 Tf
+(\225) 3.48691 Tj
+[1 0 0 1 82.4608 397.797] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 1.9925 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -86.944 -397.797] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 397.797 Td
+/F134_0 9.9626 Tf
+(bzip2recover) 71.7307 Tj
+[1 0 0 1 158.675 397.797] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -158.675 -397.797] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+161.166 397.797 Td
+/F130_0 9.9626 Tf
+(-) 3.31755 Tj
+-250 TJm
+(reco) 17.1456 Tj
+15 TJm
+(v) 4.9813 Tj
+15 TJm
+(ers) 11.6164 Tj
+-250 TJm
+(data) 16.5977 Tj
+-250 TJm
+(from) 19.3673 Tj
+-250 TJm
+(damaged) 35.965 Tj
+-250 TJm
+(bzip2) 22.1369 Tj
+-250 TJm
+(\002les) 16.6077 Tj
+[1 0 0 1 323.545 397.797] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -251.545 -12.1195] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -375.715] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 353.081 Td
+/F122_0 20.6585 Tf
+(2.2.) 34.4584 Tj
+-278 TJm
+(SYNOPSIS) 105.627 Tj
+[1 0 0 1 72 352.823] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -31.6223] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.9739 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -78.9739 -321.201] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+78.9739 321.201 Td
+/F130_0 9.9626 Tf
+(\225) 3.48691 Tj
+[1 0 0 1 82.4608 321.201] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 1.9925 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -86.944 -321.201] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 321.201 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 116.832 321.201] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -116.832 -321.201] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+119.322 321.201 Td
+/F130_0 9.9626 Tf
+([) 3.31755 Tj
+-250 TJm
+(-cdfkqstvzVL123456789) 100.164 Tj
+-250 TJm
+(]) 3.31755 Tj
+-250 TJm
+([) 3.31755 Tj
+-250 TJm
+(\002lenames) 38.1866 Tj
+-250 TJm
+(...) 7.47195 Tj
+-620 TJm
+(]) 3.31755 Tj
+[1 0 0 1 297.045 321.201] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -225.045 -21.9178] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.9739 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -78.9739 -299.283] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+78.9739 299.283 Td
+/F130_0 9.9626 Tf
+(\225) 3.48691 Tj
+[1 0 0 1 82.4608 299.283] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 1.9925 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -86.944 -299.283] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 299.283 Td
+/F134_0 9.9626 Tf
+(bunzip2) 41.8429 Tj
+[1 0 0 1 128.787 299.283] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -128.787 -299.283] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+131.278 299.283 Td
+/F130_0 9.9626 Tf
+([) 3.31755 Tj
+-250 TJm
+(-fkvsVL) 33.7533 Tj
+-250 TJm
+(]) 3.31755 Tj
+-250 TJm
+([) 3.31755 Tj
+-250 TJm
+(\002lenames) 38.1866 Tj
+-250 TJm
+(...) 7.47195 Tj
+-620 TJm
+(]) 3.31755 Tj
+[1 0 0 1 242.589 299.283] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -170.589 -21.9178] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.9739 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -78.9739 -277.365] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+78.9739 277.365 Td
+/F130_0 9.9626 Tf
+(\225) 3.48691 Tj
+[1 0 0 1 82.4608 277.365] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 1.9925 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -86.944 -277.365] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 277.365 Td
+/F134_0 9.9626 Tf
+(bzcat) 29.8878 Tj
+[1 0 0 1 116.832 277.365] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -116.832 -277.365] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+119.322 277.365 Td
+/F130_0 9.9626 Tf
+([) 3.31755 Tj
+-250 TJm
+(-s) 7.193 Tj
+-250 TJm
+(]) 3.31755 Tj
+-250 TJm
+([) 3.31755 Tj
+-250 TJm
+(\002lenames) 38.1866 Tj
+-250 TJm
+(...) 7.47195 Tj
+-620 TJm
+(]) 3.31755 Tj
+[1 0 0 1 204.074 277.365] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -132.074 -21.9178] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.9739 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -78.9739 -255.447] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+78.9739 255.447 Td
+/F130_0 9.9626 Tf
+(\225) 3.48691 Tj
+[1 0 0 1 82.4608 255.447] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 1.9925 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -86.944 -255.447] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 255.447 Td
+/F134_0 9.9626 Tf
+(bzip2recover) 71.7307 Tj
+[1 0 0 1 158.675 255.447] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -158.675 -255.447] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+161.166 255.447 Td
+/F130_0 9.9626 Tf
+(\002lename) 34.3112 Tj
+[1 0 0 1 195.476 255.447] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -123.477 -204.596] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 374.394 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 6.7545] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 43.0633 -6.7545] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -496.332 -50.8519] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+539.395 50.8519 Td
+/F130_0 9.9626 Tf
+(2) 4.9813 Tj
+[1 0 0 1 453.269 50.8519] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 93.5985 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.2765 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+Q
+showpage
+%%PageTrailer
+pdfEndPage
+%%Page: 6 6
+%%BeginPageSetup
+%%PageOrientation: Portrait
+pdfStartPage
+0 0 612 792 re W
+%%EndPageSetup
+[] 0 d
+1 i
+0 j
+0 J
+10 M
+1 w
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+false op
+false OP
+0 0 612 792 re
+W
+q
+[1 0 0 1 72 741.554] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 14.4459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 187.197 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 -8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 105.519 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -371.59 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+477.109 749.245 Td
+/F130_0 9.9626 Tf
+(Ho) 12.1743 Tj
+25 TJm
+(w) 7.193 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(use) 13.2801 Tj
+-250 TJm
+(bzip2) 22.1369 Tj
+[1 0 0 1 266.071 747.089] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 280.796 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -472.974 -5.0363] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -0.4981] cm
+q
+[] 0 d
+0 J
+0.4981 w
+0 0.2491 m
+475.465 0.2491 l
+S
+Q
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 479.251 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -21.5542] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -720] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 704.93 Td
+/F122_0 20.6585 Tf
+(2.3.) 34.4584 Tj
+-278 TJm
+(DESCRIPTION) 141.18 Tj
+[1 0 0 1 72 704.672] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -694.709] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 683.012 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 101.888 683.012] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -101.888 -683.012] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+104.56 683.012 Td
+/F130_0 9.9626 Tf
+(compresses) 45.9276 Tj
+-268 TJm
+(\002les) 16.6077 Tj
+-268 TJm
+(using) 21.589 Tj
+-268 TJm
+(the) 12.1743 Tj
+-269 TJm
+(Burro) 23.2427 Tj
+25 TJm
+(ws-Wheeler) 48.1293 Tj
+-268 TJm
+(block) 22.1369 Tj
+-268 TJm
+(sorting) 27.6761 Tj
+-268 TJm
+(te) 7.193 Tj
+15 TJm
+(xt) 7.7509 Tj
+-268 TJm
+(compression) 50.3609 Tj
+-268 TJm
+(algorithm,) 41.2352 Tj
+-273 TJm
+(and) 14.386 Tj
+-268 TJm
+(Huf) 15.4918 Tj
+25 TJm
+(fman) 20.4731 Tj
+-269 TJm
+(c) 4.42339 Tj
+1 TJm
+(od) 9.9626 Tj
+-1 TJm
+(i) 2.7696 Tj
+1 TJm
+(ng.) 12.4533 Tj
+72 671.057 Td
+(Compression) 52.5826 Tj
+-203 TJm
+(is) 6.64505 Tj
+-204 TJm
+(generally) 37.0708 Tj
+-203 TJm
+(considerably) 50.9089 Tj
+-203 TJm
+(better) 22.6848 Tj
+-204 TJm
+(t) 2.7696 Tj
+1 TJm
+(han) 14.386 Tj
+-204 TJm
+(that) 14.9439 Tj
+-203 TJm
+(achie) 21.0211 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(ed) 9.40469 Tj
+-203 TJm
+(by) 9.9626 Tj
+-204 TJm
+(more) 20.4731 Tj
+-203 TJm
+(con) 14.386 Tj
+40 TJm
+(v) 4.9813 Tj
+15 TJm
+(entional) 32.0995 Tj
+-203 TJm
+(LZ77/LZ78-based) 73.0458 Tj
+-204 TJm
+(compressors,) 52.2937 Tj
+72 659.101 Td
+(and) 14.386 Tj
+-250 TJm
+(approaches) 44.8118 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(performance) 50.341 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(PPM) 19.9352 Tj
+-250 TJm
+(f) 3.31755 Tj
+10 TJm
+(amily) 22.6948 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(statistical) 37.6387 Tj
+-250 TJm
+(compressors.) 52.2937 Tj
+[1 0 0 1 72 656.945] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -646.982] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 637.184 Td
+/F130_0 9.9626 Tf
+(The) 15.4918 Tj
+-250 TJm
+(command-line) 57.5539 Tj
+-250 TJm
+(options) 29.3399 Tj
+-250 TJm
+(are) 12.1643 Tj
+-250 TJm
+(deliberately) 47.0334 Tj
+-250 TJm
+(v) 4.9813 Tj
+15 TJm
+(ery) 12.7222 Tj
+-250 TJm
+(similar) 27.6761 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(those) 21.031 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(GNU) 21.579 Tj
+[1 0 0 1 364.869 637.184] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -364.869 -637.184] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+364.869 637.184 Td
+/F134_0 9.9626 Tf
+(gzip) 23.9102 Tj
+[1 0 0 1 388.779 637.184] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -388.779 -637.184] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+388.779 637.184 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-250 TJm
+(b) 4.9813 Tj
+20 TJm
+(ut) 7.7509 Tj
+-250 TJm
+(the) 12.1743 Tj
+15 TJm
+(y) 4.9813 Tj
+-250 TJm
+(are) 12.1643 Tj
+-250 TJm
+(not) 12.7322 Tj
+-250 TJm
+(identical.) 36.8018 Tj
+[1 0 0 1 72 635.027] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -625.064] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 615.266 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 101.888 615.266] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -101.888 -615.266] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+105.175 615.266 Td
+/F130_0 9.9626 Tf
+(e) 4.42339 Tj
+15 TJm
+(xpects) 25.4544 Tj
+-330 TJm
+(a) 4.42339 Tj
+-330 TJm
+(list) 12.1843 Tj
+-330 TJm
+(of) 8.29885 Tj
+-330 TJm
+(\002le) 12.7322 Tj
+-329 TJm
+(names) 25.4544 Tj
+-330 TJm
+(to) 7.7509 Tj
+-330 TJm
+(accompan) 40.3884 Tj
+15 TJm
+(y) 4.9813 Tj
+-330 TJm
+(the) 12.1743 Tj
+-330 TJm
+(command-line) 57.5539 Tj
+-330 TJm
+(\003ags.) 21.31 Tj
+-1099 TJm
+(Each) 19.9152 Tj
+-330 TJm
+(\002le) 12.7322 Tj
+-330 TJm
+(is) 6.64505 Tj
+-330 TJm
+(replaced) 33.7433 Tj
+-330 TJm
+(by) 9.9626 Tj
+-330 TJm
+(a) 4.42339 Tj
+-330 TJm
+(compressed) 47.0334 Tj
+72 603.311 Td
+(v) 4.9813 Tj
+15 TJm
+(ersion) 24.3486 Tj
+-349 TJm
+(of) 8.29885 Tj
+-348 TJm
+(itself,) 22.4159 Tj
+-373 TJm
+(with) 17.7135 Tj
+-349 TJm
+(the) 12.1743 Tj
+-349 TJm
+(name) 21.579 Tj
+[1 0 0 1 204.444 603.311] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -204.444 -603.311] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+204.444 603.311 Td
+/F134_0 9.9626 Tf
+(original_name.bz2) 101.619 Tj
+[1 0 0 1 306.063 603.311] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -306.063 -603.311] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+306.063 603.311 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+-1212 TJm
+(Each) 19.9152 Tj
+-348 TJm
+(compressed) 47.0334 Tj
+-349 TJm
+(\002le) 12.7322 Tj
+-348 TJm
+(has) 13.2801 Tj
+-349 TJm
+(the) 12.1743 Tj
+-348 TJm
+(same) 20.4731 Tj
+-349 TJm
+(modi\002cation) 50.3709 Tj
+-349 TJm
+(date,) 19.0883 Tj
+72 591.356 Td
+(permissions,) 50.092 Tj
+-344 TJm
+(and,) 16.8766 Tj
+-344 TJm
+(when) 21.579 Tj
+-325 TJm
+(possible,) 35.1481 Tj
+-344 TJm
+(o) 4.9813 Tj
+25 TJm
+(wnership) 36.5229 Tj
+-325 TJm
+(as) 8.29885 Tj
+-325 TJm
+(the) 12.1743 Tj
+-326 TJm
+(corresponding) 56.996 Tj
+-325 TJm
+(original,) 33.4843 Tj
+-344 TJm
+(so) 8.85675 Tj
+-325 TJm
+(that) 14.9439 Tj
+-325 TJm
+(these) 20.4731 Tj
+-325 TJm
+(properties) 39.8404 Tj
+-325 TJm
+(can) 13.8281 Tj
+-326 TJm
+(be) 9.40469 Tj
+-325 TJm
+(correctly) 35.4071 Tj
+72 579.4 Td
+(restored) 32.0895 Tj
+-308 TJm
+(at) 7.193 Tj
+-308 TJm
+(decompression) 59.7656 Tj
+-307 TJm
+(time.) 20.2042 Tj
+-484 TJm
+(File) 15.5018 Tj
+-308 TJm
+(name) 21.579 Tj
+-308 TJm
+(handling) 34.8691 Tj
+-308 TJm
+(is) 6.64505 Tj
+-307 TJm
+(nai) 12.1743 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-308 TJm
+(in) 7.7509 Tj
+-308 TJm
+(the) 12.1743 Tj
+-308 TJm
+(sense) 21.579 Tj
+-308 TJm
+(that) 14.9439 Tj
+-308 TJm
+(there) 19.9152 Tj
+-307 TJm
+(is) 6.64505 Tj
+-308 TJm
+(no) 9.9626 Tj
+-308 TJm
+(mechanism) 45.3796 Tj
+-308 TJm
+(for) 11.6164 Tj
+-308 TJm
+(preserving) 42.0521 Tj
+72 567.445 Td
+(original) 30.9936 Tj
+-334 TJm
+(\002le) 12.7322 Tj
+-333 TJm
+(names,) 27.9451 Tj
+-355 TJm
+(permissions,) 50.092 Tj
+-355 TJm
+(o) 4.9813 Tj
+25 TJm
+(wnerships) 40.3983 Tj
+-333 TJm
+(or) 8.29885 Tj
+-334 TJm
+(dates) 20.4731 Tj
+-334 TJm
+(in) 7.7509 Tj
+-333 TJm
+(\002lesystems) 44.2838 Tj
+-334 TJm
+(which) 24.3486 Tj
+-334 TJm
+(lack) 16.5977 Tj
+-333 TJm
+(these) 20.4731 Tj
+-334 TJm
+(concepts,) 37.3498 Tj
+-355 TJm
+(or) 8.29885 Tj
+-333 TJm
+(ha) 9.40469 Tj
+20 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-334 TJm
+(serious) 28.224 Tj
+-334 TJm
+(\002le) 12.7322 Tj
+72 555.49 Td
+(name) 21.579 Tj
+-250 TJm
+(length) 24.9065 Tj
+-250 TJm
+(restrictions,) 46.7644 Tj
+-250 TJm
+(such) 18.2614 Tj
+-250 TJm
+(as) 8.29885 Tj
+-250 TJm
+(MS-DOS.) 40.1294 Tj
+[1 0 0 1 72 553.333] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -543.371] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 533.572 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 101.888 533.572] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -101.888 -533.572] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+104.379 533.572 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 121.255 533.572] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -121.255 -533.572] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+121.255 533.572 Td
+/F134_0 9.9626 Tf
+(bunzip2) 41.8429 Tj
+[1 0 0 1 163.098 533.572] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -163.098 -533.572] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+165.589 533.572 Td
+/F130_0 9.9626 Tf
+(will) 15.5018 Tj
+-250 TJm
+(by) 9.9626 Tj
+-250 TJm
+(def) 12.7222 Tj
+10 TJm
+(ault) 14.9439 Tj
+-250 TJm
+(not) 12.7322 Tj
+-250 TJm
+(o) 4.9813 Tj
+15 TJm
+(v) 4.9813 Tj
+15 TJm
+(erwrite) 28.2141 Tj
+-250 TJm
+(e) 4.42339 Tj
+15 TJm
+(xisting) 27.1282 Tj
+-250 TJm
+(\002les.) 19.0983 Tj
+-620 TJm
+(If) 6.63509 Tj
+-250 TJm
+(you) 14.9439 Tj
+-250 TJm
+(w) 7.193 Tj
+10 TJm
+(ant) 12.1743 Tj
+-250 TJm
+(this) 14.396 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(happen,) 31.2626 Tj
+-250 TJm
+(specify) 28.772 Tj
+-250 TJm
+(the) 12.1743 Tj
+[1 0 0 1 495.977 533.572] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -495.977 -533.572] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+495.977 533.572 Td
+/F134_0 9.9626 Tf
+(-f) 11.9551 Tj
+[1 0 0 1 507.932 533.572] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -507.932 -533.572] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+510.423 533.572 Td
+/F130_0 9.9626 Tf
+(\003ag.) 17.4346 Tj
+[1 0 0 1 72 531.415] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -521.453] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 511.654 Td
+/F130_0 9.9626 Tf
+(If) 6.63509 Tj
+-284 TJm
+(no) 9.9626 Tj
+-285 TJm
+(\002le) 12.7322 Tj
+-284 TJm
+(names) 25.4544 Tj
+-284 TJm
+(are) 12.1643 Tj
+-284 TJm
+(speci\002ed,) 37.9077 Tj
+[1 0 0 1 193.935 511.654] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -193.935 -511.654] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+193.935 511.654 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 223.823 511.654] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -223.823 -511.654] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+226.655 511.654 Td
+/F130_0 9.9626 Tf
+(compresses) 45.9276 Tj
+-284 TJm
+(from) 19.3673 Tj
+-285 TJm
+(standard) 33.7533 Tj
+-284 TJm
+(input) 20.4831 Tj
+-284 TJm
+(to) 7.7509 Tj
+-284 TJm
+(standard) 33.7533 Tj
+-285 TJm
+(output.) 27.9551 Tj
+-825 TJm
+(In) 8.29885 Tj
+-285 TJm
+(this) 14.396 Tj
+-284 TJm
+(case,) 19.6363 Tj
+[1 0 0 1 491.778 511.654] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -491.778 -511.654] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+491.778 511.654 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 521.666 511.654] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -521.666 -511.654] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+524.499 511.654 Td
+/F130_0 9.9626 Tf
+(will) 15.5018 Tj
+72 499.699 Td
+(decline) 28.772 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(write) 20.4731 Tj
+-250 TJm
+(compressed) 47.0334 Tj
+-250 TJm
+(output) 25.4644 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(terminal,) 35.696 Tj
+-250 TJm
+(as) 8.29885 Tj
+-250 TJm
+(this) 14.396 Tj
+-250 TJm
+(w) 7.193 Tj
+10 TJm
+(ould) 17.7135 Tj
+-250 TJm
+(be) 9.40469 Tj
+-250 TJm
+(entirely) 30.4357 Tj
+-250 TJm
+(incomprehensible) 70.8341 Tj
+-250 TJm
+(and) 14.386 Tj
+-250 TJm
+(therefore) 35.955 Tj
+-250 TJm
+(pointless.) 37.9177 Tj
+[1 0 0 1 72 497.542] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -487.58] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 477.781 Td
+/F134_0 9.9626 Tf
+(bunzip2) 41.8429 Tj
+[1 0 0 1 113.843 477.781] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -113.843 -477.781] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+116.176 477.781 Td
+/F130_0 9.9626 Tf
+(\(or) 11.6164 Tj
+[1 0 0 1 130.125 477.781] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -130.125 -477.781] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+130.125 477.781 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+-600 TJm
+(-d) 11.9551 Tj
+[1 0 0 1 177.946 477.781] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -177.946 -477.781] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+177.946 477.781 Td
+/F130_0 9.9626 Tf
+(\)) 3.31755 Tj
+-234 TJm
+(decompresses) 55.3323 Tj
+-234 TJm
+(all) 9.9626 Tj
+-234 TJm
+(speci\002ed) 35.417 Tj
+-235 TJm
+(\002les.) 19.0983 Tj
+-609 TJm
+(Files) 19.3773 Tj
+-234 TJm
+(which) 24.3486 Tj
+-234 TJm
+(were) 19.3573 Tj
+-234 TJm
+(not) 12.7322 Tj
+-235 TJm
+(created) 28.762 Tj
+-234 TJm
+(by) 9.9626 Tj
+[1 0 0 1 445.012 477.781] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -445.012 -477.781] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+445.012 477.781 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 474.9 477.781] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -474.9 -477.781] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+477.233 477.781 Td
+/F130_0 9.9626 Tf
+(will) 15.5018 Tj
+-234 TJm
+(be) 9.40469 Tj
+-234 TJm
+(detected) 33.1954 Tj
+72 465.826 Td
+(and) 14.386 Tj
+-280 TJm
+(i) 2.7696 Tj
+1 TJm
+(gnored,) 30.1568 Tj
+-287 TJm
+(and) 14.386 Tj
+-280 TJm
+(a) 4.42339 Tj
+-279 TJm
+(w) 7.193 Tj
+10 TJm
+(arning) 25.4544 Tj
+-280 TJm
+(issued.) 27.3972 Tj
+[1 0 0 1 216.033 465.826] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -216.033 -465.826] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+216.033 465.826 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 245.921 465.826] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -245.921 -465.826] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+248.705 465.826 Td
+/F130_0 9.9626 Tf
+(attempts) 33.7633 Tj
+-279 TJm
+(to) 7.7509 Tj
+-280 TJm
+(guess) 22.1369 Tj
+-279 TJm
+(the) 12.1743 Tj
+-280 TJm
+(\002lename) 34.3112 Tj
+-279 TJm
+(for) 11.6164 Tj
+-280 TJm
+(the) 12.1743 Tj
+-279 TJm
+(decompressed) 56.4381 Tj
+-280 TJm
+(\002le) 12.7322 Tj
+-279 TJm
+(from) 19.3673 Tj
+-280 TJm
+(that) 14.9439 Tj
+-279 TJm
+(of) 8.29885 Tj
+-280 TJm
+(the) 12.1743 Tj
+72 453.871 Td
+(compressed) 47.0334 Tj
+-250 TJm
+(\002le) 12.7322 Tj
+-250 TJm
+(as) 8.29885 Tj
+-250 TJm
+(follo) 18.8194 Tj
+25 TJm
+(ws:) 13.8381 Tj
+[1 0 0 1 72 451.714] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -29.7236] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.9739 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -78.9739 -421.991] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+78.9739 421.991 Td
+/F130_0 9.9626 Tf
+(\225) 3.48691 Tj
+[1 0 0 1 82.4608 421.991] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 1.9925 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -86.944 -421.991] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 421.991 Td
+/F134_0 9.9626 Tf
+(filename.bz2) 71.7307 Tj
+[1 0 0 1 164.653 421.991] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -164.653 -421.991] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+167.143 421.991 Td
+/F130_0 9.9626 Tf
+(becomes) 34.8591 Tj
+[1 0 0 1 204.493 421.991] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -204.493 -421.991] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+204.493 421.991 Td
+/F134_0 9.9626 Tf
+(filename) 47.8205 Tj
+[1 0 0 1 252.313 421.991] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -180.313 -21.9178] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.9739 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -78.9739 -400.073] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+78.9739 400.073 Td
+/F130_0 9.9626 Tf
+(\225) 3.48691 Tj
+[1 0 0 1 82.4608 400.073] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 1.9925 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -86.944 -400.073] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 400.073 Td
+/F134_0 9.9626 Tf
+(filename.bz) 65.7532 Tj
+[1 0 0 1 158.675 400.073] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -158.675 -400.073] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+161.166 400.073 Td
+/F130_0 9.9626 Tf
+(becomes) 34.8591 Tj
+[1 0 0 1 198.515 400.073] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -198.515 -400.073] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+198.515 400.073 Td
+/F134_0 9.9626 Tf
+(filename) 47.8205 Tj
+[1 0 0 1 246.336 400.073] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -174.336 -21.9178] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.9739 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -78.9739 -378.155] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+78.9739 378.155 Td
+/F130_0 9.9626 Tf
+(\225) 3.48691 Tj
+[1 0 0 1 82.4608 378.155] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 1.9925 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -86.944 -378.155] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 378.155 Td
+/F134_0 9.9626 Tf
+(filename.tbz2) 77.7083 Tj
+[1 0 0 1 164.653 378.155] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -164.653 -378.155] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+167.143 378.155 Td
+/F130_0 9.9626 Tf
+(becomes) 34.8591 Tj
+[1 0 0 1 204.493 378.155] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -204.493 -378.155] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+204.493 378.155 Td
+/F134_0 9.9626 Tf
+(filename.tar) 71.7307 Tj
+[1 0 0 1 276.224 378.155] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -204.224 -21.9178] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.9739 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -78.9739 -356.237] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+78.9739 356.237 Td
+/F130_0 9.9626 Tf
+(\225) 3.48691 Tj
+[1 0 0 1 82.4608 356.237] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 1.9925 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -86.944 -356.237] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 356.237 Td
+/F134_0 9.9626 Tf
+(filename.tbz) 71.7307 Tj
+[1 0 0 1 164.653 356.237] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -164.653 -356.237] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+167.143 356.237 Td
+/F130_0 9.9626 Tf
+(becomes) 34.8591 Tj
+[1 0 0 1 204.493 356.237] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -204.493 -356.237] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+204.493 356.237 Td
+/F134_0 9.9626 Tf
+(filename.tar) 71.7307 Tj
+[1 0 0 1 276.224 356.237] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -204.224 -21.9178] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.9739 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -78.9739 -334.319] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+78.9739 334.319 Td
+/F130_0 9.9626 Tf
+(\225) 3.48691 Tj
+[1 0 0 1 82.4608 334.319] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 1.9925 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -86.944 -334.319] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 334.319 Td
+/F134_0 9.9626 Tf
+(anyothername) 71.7307 Tj
+[1 0 0 1 164.653 334.319] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -164.653 -334.319] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+167.143 334.319 Td
+/F130_0 9.9626 Tf
+(becomes) 34.8591 Tj
+[1 0 0 1 204.493 334.319] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -204.493 -334.319] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+204.493 334.319 Td
+/F134_0 9.9626 Tf
+(anyothername.out) 95.641 Tj
+[1 0 0 1 300.134 334.319] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -228.134 -11.4968] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -322.823] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 312.402 Td
+/F130_0 9.9626 Tf
+(If) 6.63509 Tj
+-342 TJm
+(the) 12.1743 Tj
+-342 TJm
+(\002le) 12.7322 Tj
+-342 TJm
+(does) 18.2614 Tj
+-342 TJm
+(not) 12.7322 Tj
+-343 TJm
+(end) 14.386 Tj
+-342 TJm
+(in) 7.7509 Tj
+-342 TJm
+(one) 14.386 Tj
+-342 TJm
+(of) 8.29885 Tj
+-342 TJm
+(the) 12.1743 Tj
+-342 TJm
+(recognised) 43.158 Tj
+-342 TJm
+(endings,) 33.4843 Tj
+[1 0 0 1 309.305 312.402] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -309.305 -312.402] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+309.305 312.402 Td
+/F134_0 9.9626 Tf
+(.bz2) 23.9102 Tj
+[1 0 0 1 333.215 312.402] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -333.215 -312.402] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+333.215 312.402 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 339.344 312.402] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -339.344 -312.402] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+339.344 312.402 Td
+/F134_0 9.9626 Tf
+(.bz) 17.9327 Tj
+[1 0 0 1 357.276 312.402] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -357.276 -312.402] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+357.276 312.402 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 363.405 312.402] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -363.405 -312.402] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+363.405 312.402 Td
+/F134_0 9.9626 Tf
+(.tbz2) 29.8878 Tj
+[1 0 0 1 393.293 312.402] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -393.293 -312.402] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+396.701 312.402 Td
+/F130_0 9.9626 Tf
+(or) 8.29885 Tj
+[1 0 0 1 408.409 312.402] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -408.409 -312.402] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+408.409 312.402 Td
+/F134_0 9.9626 Tf
+(.tbz) 23.9102 Tj
+[1 0 0 1 432.319 312.402] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -432.319 -312.402] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+432.319 312.402 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 438.448 312.402] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -438.448 -312.402] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+438.448 312.402 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 468.336 312.402] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468.336 -312.402] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+471.744 312.402 Td
+/F130_0 9.9626 Tf
+(complains) 40.9562 Tj
+-342 TJm
+(that) 14.9439 Tj
+-342 TJm
+(it) 5.53921 Tj
+72 300.446 Td
+(cannot) 26.5603 Tj
+-250 TJm
+(guess) 22.1369 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(name) 21.579 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(original) 30.9936 Tj
+-250 TJm
+(\002le,) 15.2229 Tj
+-250 TJm
+(and) 14.386 Tj
+-250 TJm
+(uses) 17.1556 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(original) 30.9936 Tj
+-250 TJm
+(name) 21.579 Tj
+-250 TJm
+(with) 17.7135 Tj
+[1 0 0 1 370.009 300.446] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -370.009 -300.446] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+370.009 300.446 Td
+/F134_0 9.9626 Tf
+(.out) 23.9102 Tj
+[1 0 0 1 393.92 300.446] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -393.92 -300.446] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+396.41 300.446 Td
+/F130_0 9.9626 Tf
+(appended.) 40.6673 Tj
+[1 0 0 1 72 298.29] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -288.327] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 278.529 Td
+/F130_0 9.9626 Tf
+(As) 11.0684 Tj
+-250 TJm
+(with) 17.7135 Tj
+-250 TJm
+(compression,) 52.8516 Tj
+-250 TJm
+(supplying) 39.3025 Tj
+-250 TJm
+(no) 9.9626 Tj
+-250 TJm
+(\002lenames) 38.1866 Tj
+-250 TJm
+(causes) 26.0024 Tj
+-250 TJm
+(decompression) 59.7656 Tj
+-250 TJm
+(from) 19.3673 Tj
+-250 TJm
+(standard) 33.7533 Tj
+-250 TJm
+(input) 20.4831 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(standard) 33.7533 Tj
+-250 TJm
+(output.) 27.9551 Tj
+[1 0 0 1 72 276.372] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -266.409] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 256.611 Td
+/F134_0 9.9626 Tf
+(bunzip2) 41.8429 Tj
+[1 0 0 1 113.843 256.611] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -113.843 -256.611] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+116.409 256.611 Td
+/F130_0 9.9626 Tf
+(will) 15.5018 Tj
+-257 TJm
+(correctly) 35.4071 Tj
+-258 TJm
+(decompress) 47.0334 Tj
+-257 TJm
+(a) 4.42339 Tj
+-258 TJm
+(\002le) 12.7322 Tj
+-257 TJm
+(which) 24.3486 Tj
+-258 TJm
+(is) 6.64505 Tj
+-258 TJm
+(the) 12.1743 Tj
+-257 TJm
+(concatenation) 55.3323 Tj
+-258 TJm
+(of) 8.29885 Tj
+-257 TJm
+(tw) 9.9626 Tj
+10 TJm
+(o) 4.9813 Tj
+-258 TJm
+(or) 8.29885 Tj
+-257 TJm
+(more) 20.4731 Tj
+-258 TJm
+(compressed) 47.0334 Tj
+-257 TJm
+(\002les.) 19.0983 Tj
+-665 TJm
+(The) 15.4918 Tj
+-258 TJm
+(result) 22.1369 Tj
+-257 TJm
+(is) 6.64505 Tj
+72 244.656 Td
+(the) 12.1743 Tj
+-239 TJm
+(concatenation) 55.3323 Tj
+-238 TJm
+(of) 8.29885 Tj
+-239 TJm
+(the) 12.1743 Tj
+-239 TJm
+(corresponding) 56.996 Tj
+-239 TJm
+(uncompressed) 56.996 Tj
+-238 TJm
+(\002les.) 19.0983 Tj
+-613 TJm
+(Inte) 15.4918 Tj
+15 TJm
+(grity) 18.8194 Tj
+-238 TJm
+(testing) 26.5703 Tj
+-239 TJm
+(\() 3.31755 Tj
+[1 0 0 1 382.247 244.656] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -382.247 -244.656] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+382.247 244.656 Td
+/F134_0 9.9626 Tf
+(-t) 11.9551 Tj
+[1 0 0 1 394.202 244.656] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -394.202 -244.656] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+394.202 244.656 Td
+/F130_0 9.9626 Tf
+(\)) 3.31755 Tj
+-239 TJm
+(of) 8.29885 Tj
+-238 TJm
+(concatenated) 52.0048 Tj
+-239 TJm
+(compressed) 47.0334 Tj
+-239 TJm
+(\002les) 16.6077 Tj
+-239 TJm
+(is) 6.64505 Tj
+72 232.7 Td
+(also) 16.0497 Tj
+-250 TJm
+(supported.) 41.7831 Tj
+[1 0 0 1 72 230.544] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -220.581] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 210.783 Td
+/F130_0 9.9626 Tf
+(Y) 7.193 Tj
+110 TJm
+(ou) 9.9626 Tj
+-399 TJm
+(can) 13.8281 Tj
+-399 TJm
+(also) 16.0497 Tj
+-399 TJm
+(compress) 37.6287 Tj
+-400 TJm
+(or) 8.29885 Tj
+-399 TJm
+(decompress) 47.0334 Tj
+-399 TJm
+(\002les) 16.6077 Tj
+-399 TJm
+(to) 7.7509 Tj
+-399 TJm
+(the) 12.1743 Tj
+-399 TJm
+(standard) 33.7533 Tj
+-399 TJm
+(output) 25.4644 Tj
+-399 TJm
+(by) 9.9626 Tj
+-400 TJm
+(gi) 7.7509 Tj
+25 TJm
+(ving) 17.7135 Tj
+-399 TJm
+(the) 12.1743 Tj
+[1 0 0 1 409.67 210.783] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -409.67 -210.783] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+409.67 210.783 Td
+/F134_0 9.9626 Tf
+(-c) 11.9551 Tj
+[1 0 0 1 421.625 210.783] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -421.625 -210.783] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+425.602 210.783 Td
+/F130_0 9.9626 Tf
+(\003ag.) 17.4346 Tj
+-757 TJm
+(Multiple) 34.3212 Tj
+-400 TJm
+(\002l) 8.30881 Tj
+1 TJm
+(es) 8.29885 Tj
+-400 TJm
+(may) 17.1556 Tj
+-399 TJm
+(be) 9.40469 Tj
+72 198.828 Td
+(compressed) 47.0334 Tj
+-367 TJm
+(and) 14.386 Tj
+-367 TJm
+(decompressed) 56.4381 Tj
+-367 TJm
+(lik) 10.5205 Tj
+10 TJm
+(e) 4.42339 Tj
+-367 TJm
+(this.) 16.8866 Tj
+-1321 TJm
+(The) 15.4918 Tj
+-367 TJm
+(resulting) 34.8691 Tj
+-367 TJm
+(outputs) 29.3399 Tj
+-367 TJm
+(are) 12.1643 Tj
+-367 TJm
+(fed) 12.7222 Tj
+-367 TJm
+(sequentially) 48.1492 Tj
+-366 TJm
+(to) 7.7509 Tj
+-367 TJm
+(stdout.) 26.8492 Tj
+-1322 TJm
+(Compression) 52.5826 Tj
+-367 TJm
+(of) 8.29885 Tj
+72 186.872 Td
+(multiple) 33.2153 Tj
+-289 TJm
+(\002les) 16.6077 Tj
+-289 TJm
+(in) 7.7509 Tj
+-289 TJm
+(this) 14.396 Tj
+-289 TJm
+(manner) 29.8778 Tj
+-288 TJm
+(generates) 37.6188 Tj
+-289 TJm
+(a) 4.42339 Tj
+-289 TJm
+(stream) 26.5603 Tj
+-289 TJm
+(containing) 42.0621 Tj
+-289 TJm
+(multiple) 33.2153 Tj
+-289 TJm
+(compressed) 47.0334 Tj
+-289 TJm
+(\002le) 12.7322 Tj
+-289 TJm
+(representations.) 62.8042 Tj
+-853 TJm
+(Such) 19.9252 Tj
+-289 TJm
+(a) 4.42339 Tj
+-289 TJm
+(stream) 26.5603 Tj
+72 174.917 Td
+(can) 13.8281 Tj
+-391 TJm
+(be) 9.40469 Tj
+-391 TJm
+(decompressed) 56.4381 Tj
+-390 TJm
+(correctly) 35.4071 Tj
+-391 TJm
+(only) 17.7135 Tj
+-391 TJm
+(by) 9.9626 Tj
+[1 0 0 1 238.116 174.917] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -238.116 -174.917] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+238.116 174.917 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 268.004 174.917] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -268.004 -174.917] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+271.897 174.917 Td
+/F130_0 9.9626 Tf
+(v) 4.9813 Tj
+15 TJm
+(ersion) 24.3486 Tj
+-391 TJm
+(0.9.0) 19.9252 Tj
+-391 TJm
+(or) 8.29885 Tj
+-391 TJm
+(l) 2.7696 Tj
+1 TJm
+(ater) 14.9339 Tj
+55 TJm
+(.) 2.49065 Tj
+-733 TJm
+(Earlier) 27.1082 Tj
+-391 TJm
+(v) 4.9813 Tj
+15 TJm
+(ersions) 28.224 Tj
+-391 TJm
+(of) 8.29885 Tj
+[1 0 0 1 448.071 174.917] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -448.071 -174.917] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+448.071 174.917 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 477.958 174.917] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -477.958 -174.917] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+481.852 174.917 Td
+/F130_0 9.9626 Tf
+(will) 15.5018 Tj
+-391 TJm
+(stop) 16.6077 Tj
+-391 TJm
+(after) 18.2515 Tj
+72 162.962 Td
+(decompressing) 59.7656 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(\002rst) 15.5018 Tj
+-250 TJm
+(\002le) 12.7322 Tj
+-250 TJm
+(in) 7.7509 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(stream.) 29.0509 Tj
+[1 0 0 1 72 160.805] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -150.843] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 141.044 Td
+/F134_0 9.9626 Tf
+(bzcat) 29.8878 Tj
+[1 0 0 1 101.888 141.044] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -101.888 -141.044] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+104.379 141.044 Td
+/F130_0 9.9626 Tf
+(\(or) 11.6164 Tj
+[1 0 0 1 118.486 141.044] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -118.486 -141.044] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+118.486 141.044 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+-600 TJm
+(-dc) 17.9327 Tj
+[1 0 0 1 172.284 141.044] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -172.284 -141.044] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+172.284 141.044 Td
+/F130_0 9.9626 Tf
+(\)) 3.31755 Tj
+-250 TJm
+(decompresses) 55.3323 Tj
+-250 TJm
+(all) 9.9626 Tj
+-250 TJm
+(speci\002ed) 35.417 Tj
+-250 TJm
+(\002les) 16.6077 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(standard) 33.7533 Tj
+-250 TJm
+(output.) 27.9551 Tj
+[1 0 0 1 72 138.887] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -128.925] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 119.126 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 101.888 119.126] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -101.888 -119.126] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+104.866 119.126 Td
+/F130_0 9.9626 Tf
+(will) 15.5018 Tj
+-299 TJm
+(read) 17.1456 Tj
+-299 TJm
+(ar) 7.74094 Tj
+18 TJm
+(guments) 33.7633 Tj
+-299 TJm
+(from) 19.3673 Tj
+-299 TJm
+(the) 12.1743 Tj
+-299 TJm
+(en) 9.40469 Tj
+40 TJm
+(vironment) 40.9562 Tj
+-298 TJm
+(v) 4.9813 Tj
+25 TJm
+(ariables) 30.9837 Tj
+[1 0 0 1 316.903 119.126] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -316.903 -119.126] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+316.903 119.126 Td
+/F134_0 9.9626 Tf
+(BZIP2) 29.8878 Tj
+[1 0 0 1 346.791 119.126] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -346.791 -119.126] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+349.769 119.126 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 367.133 119.126] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -367.133 -119.126] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+367.133 119.126 Td
+/F134_0 9.9626 Tf
+(BZIP) 23.9102 Tj
+[1 0 0 1 391.043 119.126] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -391.043 -119.126] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+391.043 119.126 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-299 TJm
+(in) 7.7509 Tj
+-299 TJm
+(that) 14.9439 Tj
+-299 TJm
+(order) 21.0211 Tj
+40 TJm
+(,) 2.49065 Tj
+-311 TJm
+(and) 14.386 Tj
+-299 TJm
+(will) 15.5018 Tj
+-299 TJm
+(process) 29.8778 Tj
+-299 TJm
+(them) 19.9252 Tj
+72 107.171 Td
+(before) 25.4445 Tj
+-250 TJm
+(an) 9.40469 Tj
+15 TJm
+(y) 4.9813 Tj
+-250 TJm
+(ar) 7.74094 Tj
+18 TJm
+(guments) 33.7633 Tj
+-250 TJm
+(read) 17.1456 Tj
+-250 TJm
+(from) 19.3673 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(command) 39.2925 Tj
+-250 TJm
+(line.) 17.4346 Tj
+-310 TJm
+(This) 17.7135 Tj
+-250 TJm
+(gi) 7.7509 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(es) 8.29885 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(con) 14.386 Tj
+40 TJm
+(v) 4.9813 Tj
+15 TJm
+(enient) 24.3486 Tj
+-250 TJm
+(w) 7.193 Tj
+10 TJm
+(ay) 9.40469 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(supply) 26.5703 Tj
+-250 TJm
+(def) 12.7222 Tj
+10 TJm
+(ault) 14.9439 Tj
+-250 TJm
+(ar) 7.74094 Tj
+18 TJm
+(guments.) 36.2539 Tj
+[1 0 0 1 72 105.014] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -95.0517] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 85.2534 Td
+/F130_0 9.9626 Tf
+(Compression) 52.5826 Tj
+-294 TJm
+(is) 6.64505 Tj
+-294 TJm
+(al) 7.193 Tj
+10 TJm
+(w) 7.193 Tj
+10 TJm
+(ays) 13.2801 Tj
+-294 TJm
+(performed,) 43.9849 Tj
+-305 TJm
+(e) 4.42339 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(en) 9.40469 Tj
+-294 TJm
+(if) 6.08715 Tj
+-294 TJm
+(the) 12.1743 Tj
+-294 TJm
+(compressed) 47.0334 Tj
+-294 TJm
+(\002le) 12.7322 Tj
+-293 TJm
+(is) 6.64505 Tj
+-294 TJm
+(slightly) 29.8978 Tj
+-294 TJm
+(lar) 10.5105 Tj
+18 TJm
+(ger) 12.7222 Tj
+-294 TJm
+(than) 17.1556 Tj
+-294 TJm
+(the) 12.1743 Tj
+-294 TJm
+(original.) 33.4843 Tj
+-884 TJm
+(Files) 19.3773 Tj
+-294 TJm
+(of) 8.29885 Tj
+-294 TJm
+(less) 14.9439 Tj
+-294 TJm
+(than) 17.1556 Tj
+72 73.2982 Td
+(about) 22.1369 Tj
+-246 TJm
+(one) 14.386 Tj
+-246 TJm
+(hundred) 32.6474 Tj
+-245 TJm
+(bytes) 21.031 Tj
+-246 TJm
+(tend) 17.1556 Tj
+-246 TJm
+(to) 7.7509 Tj
+-246 TJm
+(get) 12.1743 Tj
+-246 TJm
+(l) 2.7696 Tj
+1 TJm
+(ar) 7.74094 Tj
+18 TJm
+(ger) 12.7222 Tj
+40 TJm
+(,) 2.49065 Tj
+-247 TJm
+(since) 20.4731 Tj
+-246 TJm
+(the) 12.1743 Tj
+-246 TJm
+(compression) 50.3609 Tj
+-245 TJm
+(mechanism) 45.3796 Tj
+-246 TJm
+(has) 13.2801 Tj
+-246 TJm
+(a) 4.42339 Tj
+-246 TJm
+(constant) 33.2053 Tj
+-246 TJm
+(o) 4.9813 Tj
+15 TJm
+(v) 4.9813 Tj
+15 TJm
+(erhead) 26.5503 Tj
+-245 TJm
+(in) 7.7509 Tj
+-246 TJm
+(the) 12.1743 Tj
+-246 TJm
+(re) 7.74094 Tj
+15 TJm
+(gion) 17.7135 Tj
+-246 TJm
+(of) 8.29885 Tj
+[1 0 0 1 72 50.8518] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 374.394 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 6.8541] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 43.0633 -6.7545] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -496.332 -50.9514] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+539.395 50.9514 Td
+/F130_0 9.9626 Tf
+(3) 4.9813 Tj
+[1 0 0 1 453.269 50.8518] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 93.5985 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.2765 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+Q
+showpage
+%%PageTrailer
+pdfEndPage
+%%Page: 7 7
+%%BeginPageSetup
+%%PageOrientation: Portrait
+pdfStartPage
+0 0 612 792 re W
+%%EndPageSetup
+[] 0 d
+1 i
+0 j
+0 J
+10 M
+1 w
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+false op
+false OP
+0 0 612 792 re
+W
+q
+[1 0 0 1 72 741.554] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 14.4459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 187.197 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 -8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 105.519 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -371.59 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+477.109 749.245 Td
+/F130_0 9.9626 Tf
+(Ho) 12.1743 Tj
+25 TJm
+(w) 7.193 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(use) 13.2801 Tj
+-250 TJm
+(bzip2) 22.1369 Tj
+[1 0 0 1 266.071 747.089] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 280.796 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -472.974 -5.0363] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -0.4981] cm
+q
+[] 0 d
+0 J
+0.4981 w
+0 0.2491 m
+475.465 0.2491 l
+S
+Q
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 479.251 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -540 -741.554] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 710.037 Td
+/F130_0 9.9626 Tf
+(50) 9.9626 Tj
+-264 TJm
+(bytes.) 23.5217 Tj
+-351 TJm
+(Random) 33.7633 Tj
+-264 TJm
+(dat) 12.1743 Tj
+1 TJm
+(a) 4.42339 Tj
+-264 TJm
+(\(including) 40.9562 Tj
+-264 TJm
+(the) 12.1743 Tj
+-264 TJm
+(output) 25.4644 Tj
+-263 TJm
+(of) 8.29885 Tj
+-264 TJm
+(most) 19.3773 Tj
+-264 TJm
+(\002le) 12.7322 Tj
+-263 TJm
+(compressors\)) 53.1206 Tj
+-264 TJm
+(is) 6.64505 Tj
+-264 TJm
+(coded) 23.7907 Tj
+-263 TJm
+(at) 7.193 Tj
+-264 TJm
+(about) 22.1369 Tj
+-264 TJm
+(8.05) 17.4346 Tj
+-263 TJm
+(bits) 14.396 Tj
+-264 TJm
+(per) 12.7222 Tj
+-264 TJm
+(byte,) 19.6462 Tj
+-267 TJm
+(gi) 7.7509 Tj
+25 TJm
+(ving) 17.7135 Tj
+-264 TJm
+(an) 9.40469 Tj
+72 698.082 Td
+(e) 4.42339 Tj
+15 TJm
+(xpansion) 35.9749 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(around) 27.6661 Tj
+-250 TJm
+(0.5%.) 23.2427 Tj
+[1 0 0 1 72 695.925] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.8441] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -686.081] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 676.283 Td
+/F130_0 9.9626 Tf
+(As) 11.0684 Tj
+-268 TJm
+(a) 4.42339 Tj
+-268 TJm
+(self-check) 40.9363 Tj
+-269 TJm
+(for) 11.6164 Tj
+-268 TJm
+(your) 18.2614 Tj
+-268 TJm
+(protection,) 42.889 Tj
+[1 0 0 1 217.273 676.283] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -217.273 -676.283] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+217.273 676.283 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 247.161 676.283] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -247.161 -676.283] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+249.833 676.283 Td
+/F130_0 9.9626 Tf
+(uses) 17.1556 Tj
+-268 TJm
+(32-bit) 23.8007 Tj
+-268 TJm
+(CRCs) 23.8106 Tj
+-269 TJm
+(to) 7.7509 Tj
+-268 TJm
+(mak) 17.1556 Tj
+10 TJm
+(e) 4.42339 Tj
+-268 TJm
+(sure) 16.5977 Tj
+-268 TJm
+(that) 14.9439 Tj
+-268 TJm
+(the) 12.1743 Tj
+-269 TJm
+(decompressed) 56.4381 Tj
+-268 TJm
+(v) 4.9813 Tj
+15 TJm
+(ersion) 24.3486 Tj
+-268 TJm
+(of) 8.29885 Tj
+-268 TJm
+(a) 4.42339 Tj
+-268 TJm
+(\002le) 12.7322 Tj
+-269 TJm
+(is) 6.64505 Tj
+72 664.328 Td
+(identical) 34.3112 Tj
+-200 TJm
+(to) 7.7509 Tj
+-199 TJm
+(the) 12.1743 Tj
+-200 TJm
+(original.) 33.4843 Tj
+-586 TJm
+(This) 17.7135 Tj
+-200 TJm
+(guards) 26.5603 Tj
+-199 TJm
+(ag) 9.40469 Tj
+5 TJm
+(ainst) 18.8194 Tj
+-200 TJm
+(corruption) 41.5042 Tj
+-199 TJm
+(of) 8.29885 Tj
+-200 TJm
+(the) 12.1743 Tj
+-200 TJm
+(compressed) 47.0334 Tj
+-199 TJm
+(data,) 19.0883 Tj
+-210 TJm
+(and) 14.386 Tj
+-199 TJm
+(ag) 9.40469 Tj
+5 TJm
+(ainst) 18.8194 Tj
+-200 TJm
+(undetected) 43.158 Tj
+-200 TJm
+(b) 4.9813 Tj
+20 TJm
+(ugs) 13.8381 Tj
+-199 TJm
+(in) 7.7509 Tj
+[1 0 0 1 510.112 664.328] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -510.112 -664.328] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+510.112 664.328 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 540 664.328] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -540 -664.328] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 652.373 Td
+/F130_0 9.9626 Tf
+(\(hopefully) 41.5042 Tj
+-275 TJm
+(v) 4.9813 Tj
+15 TJm
+(ery) 12.7222 Tj
+-274 TJm
+(unlik) 20.4831 Tj
+10 TJm
+(ely\).) 17.9825 Tj
+-384 TJm
+(The) 15.4918 Tj
+-275 TJm
+(chances) 31.5316 Tj
+-275 TJm
+(of) 8.29885 Tj
+-275 TJm
+(data) 16.5977 Tj
+-274 TJm
+(corruption) 41.5042 Tj
+-275 TJm
+(going) 22.6948 Tj
+-275 TJm
+(undetected) 43.158 Tj
+-274 TJm
+(is) 6.64505 Tj
+-275 TJm
+(microscopic,) 51.1878 Tj
+-281 TJm
+(about) 22.1369 Tj
+-275 TJm
+(one) 14.386 Tj
+-274 TJm
+(chance) 27.6562 Tj
+-275 TJm
+(in) 7.7509 Tj
+-275 TJm
+(four) 16.5977 Tj
+72 640.417 Td
+(billion) 26.0223 Tj
+-279 TJm
+(for) 11.6164 Tj
+-279 TJm
+(each) 18.2515 Tj
+-279 TJm
+(\002le) 12.7322 Tj
+-280 TJm
+(processed.) 41.7732 Tj
+-795 TJm
+(Be) 11.0684 Tj
+-279 TJm
+(a) 4.42339 Tj
+15 TJm
+(w) 7.193 Tj
+10 TJm
+(are,) 14.655 Tj
+-286 TJm
+(though,) 30.1668 Tj
+-287 TJm
+(that) 14.9439 Tj
+-279 TJm
+(the) 12.1743 Tj
+-279 TJm
+(check) 23.2328 Tj
+-279 TJm
+(occurs) 26.0024 Tj
+-279 TJm
+(upon) 19.9252 Tj
+-279 TJm
+(decompression,) 62.2563 Tj
+-287 TJm
+(so) 8.85675 Tj
+-279 TJm
+(it) 5.53921 Tj
+-279 TJm
+(can) 13.8281 Tj
+-279 TJm
+(only) 17.7135 Tj
+-280 TJm
+(tell) 12.7322 Tj
+-279 TJm
+(you) 14.9439 Tj
+72 628.462 Td
+(that) 14.9439 Tj
+-237 TJm
+(something) 41.5142 Tj
+-236 TJm
+(is) 6.64505 Tj
+-237 TJm
+(wrong.) 27.9451 Tj
+-611 TJm
+(It) 6.08715 Tj
+-237 TJm
+(can') 17.1456 Tj
+18 TJm
+(t) 2.7696 Tj
+-237 TJm
+(help) 17.1556 Tj
+-237 TJm
+(you) 14.9439 Tj
+-236 TJm
+(reco) 17.1456 Tj
+15 TJm
+(v) 4.9813 Tj
+15 TJm
+(er) 7.74094 Tj
+-237 TJm
+(the) 12.1743 Tj
+-237 TJm
+(original) 30.9936 Tj
+-237 TJm
+(uncompressed) 56.996 Tj
+-236 TJm
+(data.) 19.0883 Tj
+-612 TJm
+(Y) 7.193 Tj
+110 TJm
+(ou) 9.9626 Tj
+-236 TJm
+(can) 13.8281 Tj
+-237 TJm
+(use) 13.2801 Tj
+[1 0 0 1 458.159 628.462] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -458.159 -628.462] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+458.159 628.462 Td
+/F134_0 9.9626 Tf
+(bzip2recover) 71.7307 Tj
+[1 0 0 1 529.89 628.462] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -529.89 -628.462] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+532.249 628.462 Td
+/F130_0 9.9626 Tf
+(to) 7.7509 Tj
+72 616.507 Td
+(try) 11.0684 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(reco) 17.1456 Tj
+15 TJm
+(v) 4.9813 Tj
+15 TJm
+(er) 7.74094 Tj
+-250 TJm
+(data) 16.5977 Tj
+-250 TJm
+(from) 19.3673 Tj
+-250 TJm
+(damaged) 35.965 Tj
+-250 TJm
+(\002les.) 19.0983 Tj
+[1 0 0 1 72 614.35] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.8441] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -604.506] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 594.708 Td
+/F130_0 9.9626 Tf
+(Return) 27.1182 Tj
+-298 TJm
+(v) 4.9813 Tj
+25 TJm
+(alues:) 23.2427 Tj
+-406 TJm
+(0) 4.9813 Tj
+-298 TJm
+(for) 11.6164 Tj
+-298 TJm
+(a) 4.42339 Tj
+-298 TJm
+(normal) 28.224 Tj
+-298 TJm
+(e) 4.42339 Tj
+15 TJm
+(xit,) 13.0112 Tj
+-310 TJm
+(1) 4.9813 Tj
+-298 TJm
+(for) 11.6164 Tj
+-297 TJm
+(en) 9.40469 Tj
+40 TJm
+(vironmental) 48.1492 Tj
+-298 TJm
+(problems) 37.0808 Tj
+-298 TJm
+(\(\002le) 16.0497 Tj
+-298 TJm
+(not) 12.7322 Tj
+-298 TJm
+(found,) 25.7334 Tj
+-310 TJm
+(in) 7.7509 Tj
+40 TJm
+(v) 4.9813 Tj
+25 TJm
+(alid) 14.9439 Tj
+-298 TJm
+(\003ags,) 21.31 Tj
+-310 TJm
+(I/O) 13.2801 Tj
+-298 TJm
+(errors,) 25.7234 Tj
+-310 TJm
+(etc.\),) 19.9152 Tj
+-310 TJm
+(2) 4.9813 Tj
+-298 TJm
+(to) 7.7509 Tj
+72 582.753 Td
+(indicate) 31.5416 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(corrupt) 28.772 Tj
+-250 TJm
+(compressed) 47.0334 Tj
+-250 TJm
+(\002le,) 15.2229 Tj
+-250 TJm
+(3) 4.9813 Tj
+-250 TJm
+(for) 11.6164 Tj
+-250 TJm
+(an) 9.40469 Tj
+-250 TJm
+(internal) 30.4357 Tj
+-250 TJm
+(consistenc) 41.5042 Tj
+15 TJm
+(y) 4.9813 Tj
+-250 TJm
+(error) 19.3573 Tj
+-250 TJm
+(\(e) 7.74094 Tj
+15 TJm
+(g,) 7.47195 Tj
+-250 TJm
+(b) 4.9813 Tj
+20 TJm
+(ug\)) 13.2801 Tj
+-250 TJm
+(which) 24.3486 Tj
+-250 TJm
+(caused) 27.1082 Tj
+[1 0 0 1 443.065 582.753] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -443.065 -582.753] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+443.065 582.753 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 472.953 582.753] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -472.953 -582.753] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+475.444 582.753 Td
+/F130_0 9.9626 Tf
+(to) 7.7509 Tj
+-250 TJm
+(panic.) 24.0696 Tj
+[1 0 0 1 72 580.596] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.8441] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -570.752] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 548.118 Td
+/F122_0 20.6585 Tf
+(2.4.) 34.4584 Tj
+-278 TJm
+(OPTIONS) 92.9839 Tj
+[1 0 0 1 72 547.86] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.8441] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.8441] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -528.172] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 516.475 Td
+/F134_0 9.9626 Tf
+(-c) 11.9551 Tj
+-600 TJm
+(--stdout) 47.8205 Tj
+[1 0 0 1 137.753 516.475] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -68.2441 -0.1544] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -516.32] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+108 504.52 Td
+/F130_0 9.9626 Tf
+(Compress) 39.8504 Tj
+-250 TJm
+(or) 8.29885 Tj
+-250 TJm
+(decompress) 47.0334 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(standard) 33.7533 Tj
+-250 TJm
+(output.) 27.9551 Tj
+[1 0 0 1 72 502.363] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -3.8664] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.8441] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -488.652] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 478.854 Td
+/F134_0 9.9626 Tf
+(-d) 11.9551 Tj
+-600 TJm
+(--decompress) 71.7307 Tj
+[1 0 0 1 161.664 478.854] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -92.1544 -1.5341] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -477.32] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+108 466.899 Td
+/F130_0 9.9626 Tf
+(F) 5.53921 Tj
+15 TJm
+(orce) 17.1456 Tj
+-296 TJm
+(decompression.) 62.2563 Tj
+[1 0 0 1 200.214 466.899] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -200.214 -466.899] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+200.214 466.899 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 230.102 466.899] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -230.102 -466.899] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+230.102 466.899 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 235.659 466.899] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -235.659 -466.899] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+235.659 466.899 Td
+/F134_0 9.9626 Tf
+(bunzip2) 41.8429 Tj
+[1 0 0 1 277.502 466.899] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -277.502 -466.899] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+280.454 466.899 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 297.791 466.899] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -297.791 -466.899] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+297.791 466.899 Td
+/F134_0 9.9626 Tf
+(bzcat) 29.8878 Tj
+[1 0 0 1 327.679 466.899] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -327.679 -466.899] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+330.631 466.899 Td
+/F130_0 9.9626 Tf
+(are) 12.1643 Tj
+-296 TJm
+(really) 22.6848 Tj
+-296 TJm
+(the) 12.1743 Tj
+-297 TJm
+(same) 20.4731 Tj
+-296 TJm
+(program,) 36.2439 Tj
+-308 TJm
+(and) 14.386 Tj
+-296 TJm
+(the) 12.1743 Tj
+-296 TJm
+(decision) 33.2053 Tj
+-297 TJm
+(about) 22.1369 Tj
+108 454.944 Td
+(what) 19.3673 Tj
+-303 TJm
+(actions) 28.224 Tj
+-303 TJm
+(to) 7.7509 Tj
+-303 TJm
+(tak) 12.1743 Tj
+10 TJm
+(e) 4.42339 Tj
+-303 TJm
+(is) 6.64505 Tj
+-303 TJm
+(done) 19.3673 Tj
+-303 TJm
+(on) 9.9626 Tj
+-304 TJm
+(the) 12.1743 Tj
+-303 TJm
+(basis) 19.9252 Tj
+-303 TJm
+(of) 8.29885 Tj
+-303 TJm
+(which) 24.3486 Tj
+-303 TJm
+(name) 21.579 Tj
+-303 TJm
+(is) 6.64505 Tj
+-303 TJm
+(used.) 20.7521 Tj
+-939 TJm
+(This) 17.7135 Tj
+-303 TJm
+(\003ag) 14.9439 Tj
+-303 TJm
+(o) 4.9813 Tj
+15 TJm
+(v) 4.9813 Tj
+15 TJm
+(errides) 27.1082 Tj
+-303 TJm
+(that) 14.9439 Tj
+-303 TJm
+(mechanism,) 47.8703 Tj
+-316 TJm
+(and) 14.386 Tj
+108 442.988 Td
+(forces) 24.3386 Tj
+-250 TJm
+(bzip2) 22.1369 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(decompress.) 49.5241 Tj
+[1 0 0 1 72 440.832] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -3.8665] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.8441] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -427.121] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 417.323 Td
+/F134_0 9.9626 Tf
+(-z) 11.9551 Tj
+-600 TJm
+(--compress) 59.7756 Tj
+[1 0 0 1 149.709 417.323] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -80.1993 -1.5342] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -415.789] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+108 405.368 Td
+/F130_0 9.9626 Tf
+(The) 15.4918 Tj
+-250 TJm
+(complement) 49.2551 Tj
+-250 TJm
+(to) 7.7509 Tj
+[1 0 0 1 187.969 405.368] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -187.969 -405.368] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+187.969 405.368 Td
+/F134_0 9.9626 Tf
+(-d) 11.9551 Tj
+[1 0 0 1 199.924 405.368] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -199.924 -405.368] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+199.924 405.368 Td
+/F130_0 9.9626 Tf
+(:) 2.7696 Tj
+-310 TJm
+(forces) 24.3386 Tj
+-250 TJm
+(compression,) 52.8516 Tj
+-250 TJm
+(re) 7.74094 Tj
+15 TJm
+(g) 4.9813 Tj
+5 TJm
+(ardless) 27.6661 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(in) 7.7509 Tj
+40 TJm
+(v) 4.9813 Tj
+20 TJm
+(okation) 29.8878 Tj
+-250 TJm
+(name.) 24.0696 Tj
+[1 0 0 1 72 403.211] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -3.8665] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.8441] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -389.5] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 379.702 Td
+/F134_0 9.9626 Tf
+(-t) 11.9551 Tj
+-600 TJm
+(--test) 35.8654 Tj
+[1 0 0 1 125.798 379.702] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -56.2889 -0.1544] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -379.548] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+108 367.747 Td
+/F130_0 9.9626 Tf
+(Check) 25.4544 Tj
+-270 TJm
+(inte) 14.9439 Tj
+15 TJm
+(grity) 18.8194 Tj
+-271 TJm
+(of) 8.29885 Tj
+-270 TJm
+(the) 12.1743 Tj
+-271 TJm
+(speci\002ed) 35.417 Tj
+-270 TJm
+(\002le\(s\),) 25.7334 Tj
+-276 TJm
+(b) 4.9813 Tj
+20 TJm
+(ut) 7.7509 Tj
+-270 TJm
+(don') 18.2614 Tj
+18 TJm
+(t) 2.7696 Tj
+-270 TJm
+(decompress) 47.0334 Tj
+-271 TJm
+(them.) 22.4159 Tj
+-742 TJm
+(This) 17.7135 Tj
+-271 TJm
+(really) 22.6848 Tj
+-270 TJm
+(performs) 35.965 Tj
+-270 TJm
+(a) 4.42339 Tj
+-271 TJm
+(trial) 16.0497 Tj
+-270 TJm
+(decompres-) 46.4755 Tj
+108 355.791 Td
+(sion) 16.6077 Tj
+-250 TJm
+(and) 14.386 Tj
+-250 TJm
+(thro) 16.0497 Tj
+25 TJm
+(ws) 11.0684 Tj
+-250 TJm
+(a) 4.42339 Tj
+15 TJm
+(w) 7.193 Tj
+10 TJm
+(ay) 9.40469 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(result.) 24.6275 Tj
+[1 0 0 1 72 353.635] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -3.8664] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.8441] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -339.924] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 330.126 Td
+/F134_0 9.9626 Tf
+(-f) 11.9551 Tj
+-600 TJm
+(--force) 41.8429 Tj
+[1 0 0 1 131.776 330.126] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -62.2665 -0.1544] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -329.971] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+108 318.171 Td
+/F130_0 9.9626 Tf
+(F) 5.53921 Tj
+15 TJm
+(orce) 17.1456 Tj
+-338 TJm
+(o) 4.9813 Tj
+15 TJm
+(v) 4.9813 Tj
+15 TJm
+(erwrite) 28.2141 Tj
+-339 TJm
+(of) 8.29885 Tj
+-338 TJm
+(output) 25.4644 Tj
+-338 TJm
+(\002les.) 19.0983 Tj
+-1150 TJm
+(Normally) 38.1866 Tj
+65 TJm
+(,) 2.49065 Tj
+[1 0 0 1 289.831 318.171] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -289.831 -318.171] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+289.831 318.171 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 319.719 318.171] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -319.719 -318.171] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+323.089 318.171 Td
+/F130_0 9.9626 Tf
+(will) 15.5018 Tj
+-338 TJm
+(not) 12.7322 Tj
+-339 TJm
+(o) 4.9813 Tj
+15 TJm
+(v) 4.9813 Tj
+15 TJm
+(erwrite) 28.2141 Tj
+-338 TJm
+(e) 4.42339 Tj
+15 TJm
+(xisting) 27.1282 Tj
+-338 TJm
+(output) 25.4644 Tj
+-338 TJm
+(\002les.) 19.0983 Tj
+-1150 TJm
+(Also) 18.8194 Tj
+-339 TJm
+(forces) 24.3386 Tj
+[1 0 0 1 108 306.215] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -108 -306.215] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+108 306.215 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 137.888 306.215] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -137.888 -306.215] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+140.379 306.215 Td
+/F130_0 9.9626 Tf
+(to) 7.7509 Tj
+-250 TJm
+(break) 22.1269 Tj
+-250 TJm
+(hard) 17.7035 Tj
+-250 TJm
+(links) 19.3773 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(\002les,) 19.0983 Tj
+-250 TJm
+(which) 24.3486 Tj
+-250 TJm
+(it) 5.53921 Tj
+-250 TJm
+(otherwise) 38.7346 Tj
+-250 TJm
+(w) 7.193 Tj
+10 TJm
+(ouldn') 26.0123 Tj
+18 TJm
+(t) 2.7696 Tj
+-250 TJm
+(do.) 12.4533 Tj
+[1 0 0 1 72 304.681] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.8441] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -294.837] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+108 284.416 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 137.888 284.416] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -137.888 -284.416] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+141.211 284.416 Td
+/F130_0 9.9626 Tf
+(normally) 35.9749 Tj
+-334 TJm
+(declines) 32.6474 Tj
+-333 TJm
+(to) 7.7509 Tj
+-334 TJm
+(decompress) 47.0334 Tj
+-333 TJm
+(\002les) 16.6077 Tj
+-334 TJm
+(which) 24.3486 Tj
+-333 TJm
+(don') 18.2614 Tj
+18 TJm
+(t) 2.7696 Tj
+-334 TJm
+(ha) 9.40469 Tj
+20 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-333 TJm
+(the) 12.1743 Tj
+-334 TJm
+(correct) 27.6562 Tj
+-333 TJm
+(magic) 24.3486 Tj
+-334 TJm
+(header) 26.5503 Tj
+-333 TJm
+(bytes.) 23.5217 Tj
+-561 TJm
+(If) 6.63509 Tj
+-334 TJm
+(forced) 25.4445 Tj
+108 272.461 Td
+(\() 3.31755 Tj
+[1 0 0 1 111.318 272.461] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -111.318 -272.461] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+111.318 272.461 Td
+/F134_0 9.9626 Tf
+(-f) 11.9551 Tj
+[1 0 0 1 123.273 272.461] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -123.273 -272.461] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+123.273 272.461 Td
+/F130_0 9.9626 Tf
+(\),) 5.8082 Tj
+-250 TJm
+(ho) 9.9626 Tj
+25 TJm
+(we) 11.6164 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(er) 7.74094 Tj
+40 TJm
+(,) 2.49065 Tj
+-250 TJm
+(it) 5.53921 Tj
+-250 TJm
+(will) 15.5018 Tj
+-250 TJm
+(pass) 17.1556 Tj
+-250 TJm
+(such) 18.2614 Tj
+-250 TJm
+(\002les) 16.6077 Tj
+-250 TJm
+(through) 30.9936 Tj
+-250 TJm
+(unmodi\002ed.) 47.8803 Tj
+-310 TJm
+(This) 17.7135 Tj
+-250 TJm
+(is) 6.64505 Tj
+-250 TJm
+(ho) 9.9626 Tj
+25 TJm
+(w) 7.193 Tj
+-250 TJm
+(GNU) 21.579 Tj
+[1 0 0 1 412.585 272.461] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -412.585 -272.461] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+412.585 272.461 Td
+/F134_0 9.9626 Tf
+(gzip) 23.9102 Tj
+[1 0 0 1 436.496 272.461] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -436.496 -272.461] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+438.986 272.461 Td
+/F130_0 9.9626 Tf
+(beha) 18.8094 Tj
+20 TJm
+(v) 4.9813 Tj
+15 TJm
+(es.) 10.7895 Tj
+[1 0 0 1 72 270.304] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -3.8665] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.8441] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -256.594] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 246.795 Td
+/F134_0 9.9626 Tf
+(-k) 11.9551 Tj
+-600 TJm
+(--keep) 35.8654 Tj
+[1 0 0 1 125.798 246.795] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -56.2889 -1.5342] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -245.261] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+108 234.84 Td
+/F130_0 9.9626 Tf
+(K) 7.193 Tj
+25 TJm
+(eep) 13.8281 Tj
+-250 TJm
+(\(don') 21.579 Tj
+18 TJm
+(t) 2.7696 Tj
+-250 TJm
+(delete\)) 27.1082 Tj
+-250 TJm
+(input) 20.4831 Tj
+-250 TJm
+(\002les) 16.6077 Tj
+-250 TJm
+(during) 26.0123 Tj
+-250 TJm
+(compression) 50.3609 Tj
+-250 TJm
+(or) 8.29885 Tj
+-250 TJm
+(decompression.) 62.2563 Tj
+[1 0 0 1 72 232.683] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -3.8665] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.8441] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -218.973] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 209.174 Td
+/F134_0 9.9626 Tf
+(-s) 11.9551 Tj
+-600 TJm
+(--small) 41.8429 Tj
+[1 0 0 1 131.776 209.174] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -62.2665 -0.1544] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -209.02] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+108 197.219 Td
+/F130_0 9.9626 Tf
+(Reduce) 29.8778 Tj
+-347 TJm
+(memory) 33.2053 Tj
+-347 TJm
+(usage,) 25.1755 Tj
+-371 TJm
+(for) 11.6164 Tj
+-346 TJm
+(compression,) 52.8516 Tj
+-371 TJm
+(decompression) 59.7656 Tj
+-347 TJm
+(and) 14.386 Tj
+-347 TJm
+(testing.) 29.0609 Tj
+-1201 TJm
+(Files) 19.3773 Tj
+-347 TJm
+(are) 12.1643 Tj
+-347 TJm
+(decompressed) 56.4381 Tj
+-346 TJm
+(and) 14.386 Tj
+-347 TJm
+(tested) 23.2427 Tj
+108 185.264 Td
+(using) 21.589 Tj
+-388 TJm
+(a) 4.42339 Tj
+-388 TJm
+(modi\002ed) 35.427 Tj
+-388 TJm
+(algorithm) 38.7446 Tj
+-389 TJm
+(which) 24.3486 Tj
+-388 TJm
+(only) 17.7135 Tj
+-388 TJm
+(requires) 32.0895 Tj
+-388 TJm
+(2.5) 12.4533 Tj
+-388 TJm
+(bytes) 21.031 Tj
+-388 TJm
+(per) 12.7222 Tj
+-388 TJm
+(block) 22.1369 Tj
+-389 TJm
+(byte.) 19.6462 Tj
+-1448 TJm
+(This) 17.7135 Tj
+-389 TJm
+(means) 25.4544 Tj
+-388 TJm
+(an) 9.40469 Tj
+15 TJm
+(y) 4.9813 Tj
+-388 TJm
+(\002le) 12.7322 Tj
+-388 TJm
+(can) 13.8281 Tj
+-388 TJm
+(be) 9.40469 Tj
+108 173.309 Td
+(decompressed) 56.4381 Tj
+-250 TJm
+(in) 7.7509 Tj
+-250 TJm
+(2300k) 24.9065 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(memory) 33.2053 Tj
+65 TJm
+(,) 2.49065 Tj
+-250 TJm
+(albeit) 22.1369 Tj
+-250 TJm
+(at) 7.193 Tj
+-250 TJm
+(about) 22.1369 Tj
+-250 TJm
+(half) 15.4918 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(normal) 28.224 Tj
+-250 TJm
+(speed.) 25.1755 Tj
+[1 0 0 1 72 171.152] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.8441] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -161.308] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+108 151.51 Td
+/F130_0 9.9626 Tf
+(During) 28.224 Tj
+-252 TJm
+(compr) 25.4544 Tj
+1 TJm
+(ession,) 27.3972 Tj
+[1 0 0 1 194.09 151.51] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -194.09 -151.51] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+194.09 151.51 Td
+/F134_0 9.9626 Tf
+(-s) 11.9551 Tj
+[1 0 0 1 206.046 151.51] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -206.046 -151.51] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+208.551 151.51 Td
+/F130_0 9.9626 Tf
+(selects) 26.5603 Tj
+-251 TJm
+(a) 4.42339 Tj
+-252 TJm
+(block) 22.1369 Tj
+-251 TJm
+(size) 15.4918 Tj
+-252 TJm
+(of) 8.29885 Tj
+-252 TJm
+(200k,) 22.4159 Tj
+-251 TJm
+(which) 24.3486 Tj
+-252 TJm
+(limits) 22.7048 Tj
+-251 TJm
+(memory) 33.2053 Tj
+-252 TJm
+(use) 13.2801 Tj
+-251 TJm
+(to) 7.7509 Tj
+-252 TJm
+(around) 27.6661 Tj
+-251 TJm
+(the) 12.1743 Tj
+-252 TJm
+(same) 20.4731 Tj
+-251 TJm
+(\002gure,) 25.7334 Tj
+-252 TJm
+(at) 7.193 Tj
+108 139.554 Td
+(the) 12.1743 Tj
+-287 TJm
+(e) 4.42339 Tj
+15 TJm
+(xpense) 27.6661 Tj
+-287 TJm
+(of) 8.29885 Tj
+-288 TJm
+(your) 18.2614 Tj
+-287 TJm
+(compression) 50.3609 Tj
+-287 TJm
+(ratio.) 20.7521 Tj
+-843 TJm
+(In) 8.29885 Tj
+-287 TJm
+(short,) 22.4159 Tj
+-297 TJm
+(if) 6.08715 Tj
+-287 TJm
+(your) 18.2614 Tj
+-287 TJm
+(machine) 33.7533 Tj
+-287 TJm
+(is) 6.64505 Tj
+-287 TJm
+(lo) 7.7509 Tj
+25 TJm
+(w) 7.193 Tj
+-287 TJm
+(on) 9.9626 Tj
+-288 TJm
+(memory) 33.2053 Tj
+-287 TJm
+(\(8) 8.29885 Tj
+-287 TJm
+(me) 12.1743 Tj
+15 TJm
+(g) 4.9813 Tj
+5 TJm
+(abytes) 25.4544 Tj
+-287 TJm
+(or) 8.29885 Tj
+-287 TJm
+(less\),) 20.7521 Tj
+108 127.599 Td
+(use) 13.2801 Tj
+[1 0 0 1 123.771 127.599] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -123.771 -127.599] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+123.771 127.599 Td
+/F134_0 9.9626 Tf
+(-s) 11.9551 Tj
+[1 0 0 1 135.726 127.599] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -135.726 -127.599] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+138.216 127.599 Td
+/F130_0 9.9626 Tf
+(for) 11.6164 Tj
+-250 TJm
+(e) 4.42339 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(erything.) 35.696 Tj
+-620 TJm
+(See) 14.386 Tj
+[1 0 0 1 220.079 127.599] cm
+/DeviceRGB {} cs
+[0 0 1] sc
+/DeviceRGB {} CS
+[0 0 1] SC
+[1 0 0 1 -220.079 -127.599] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+220.079 127.599 Td
+/F130_0 9.9626 Tf
+(MEMOR) 37.6387 Tj
+65 TJm
+(Y) 7.193 Tj
+-250 TJm
+(MAN) 23.2427 Tj
+35 TJm
+(A) 7.193 Tj
+40 TJm
+(GEMENT) 41.5042 Tj
+[1 0 0 1 337.946 127.599] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 1] sc
+/DeviceRGB {} CS
+[0 0 1] SC
+/DeviceRGB {} cs
+[0 0 1] sc
+/DeviceRGB {} CS
+[0 0 1] SC
+[1 0 0 1 -337.946 -127.599] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+340.437 127.599 Td
+/F130_0 9.9626 Tf
+([5]) 11.6164 Tj
+[1 0 0 1 352.053 127.599] cm
+/DeviceRGB {} cs
+[0 0 1] sc
+/DeviceRGB {} CS
+[0 0 1] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -352.053 -127.599] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+354.544 127.599 Td
+/F130_0 9.9626 Tf
+(belo) 17.1556 Tj
+25 TJm
+(w) 7.193 Tj
+65 TJm
+(.) 2.49065 Tj
+[1 0 0 1 72 125.443] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -3.8665] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.8441] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -111.732] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 101.934 Td
+/F134_0 9.9626 Tf
+(-q) 11.9551 Tj
+-600 TJm
+(--quiet) 41.8429 Tj
+[1 0 0 1 131.776 101.934] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -62.2665 -1.5342] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -100.399] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+108 89.9784 Td
+/F130_0 9.9626 Tf
+(Suppress) 35.9749 Tj
+-221 TJm
+(non-essential) 52.5726 Tj
+-220 TJm
+(w) 7.193 Tj
+10 TJm
+(arning) 25.4544 Tj
+-221 TJm
+(messages.) 40.1194 Tj
+-300 TJm
+(Messages) 38.7346 Tj
+-221 TJm
+(pertaining) 40.3983 Tj
+-221 TJm
+(to) 7.7509 Tj
+-220 TJm
+(I/O) 13.2801 Tj
+-221 TJm
+(errors) 23.2328 Tj
+-221 TJm
+(and) 14.386 Tj
+-220 TJm
+(other) 20.4731 Tj
+-221 TJm
+(critical) 27.6661 Tj
+-221 TJm
+(e) 4.42339 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(ents) 16.0497 Tj
+-221 TJm
+(wi) 9.9626 Tj
+1 TJm
+(ll) 5.53921 Tj
+-221 TJm
+(not) 12.7322 Tj
+108 78.0232 Td
+(be) 9.40469 Tj
+-250 TJm
+(suppressed.) 46.2065 Tj
+[1 0 0 1 72 75.8664] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -3.8664] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -21.1482] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 374.394 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 43.0633 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -496.332 -50.8518] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+539.395 50.8518 Td
+/F130_0 9.9626 Tf
+(4) 4.9813 Tj
+[1 0 0 1 453.269 50.8518] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 93.5985 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.2765 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+Q
+showpage
+%%PageTrailer
+pdfEndPage
+%%Page: 8 8
+%%BeginPageSetup
+%%PageOrientation: Portrait
+pdfStartPage
+0 0 612 792 re W
+%%EndPageSetup
+[] 0 d
+1 i
+0 j
+0 J
+10 M
+1 w
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+false op
+false OP
+0 0 612 792 re
+W
+q
+[1 0 0 1 72 741.554] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 14.4459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 187.197 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 -8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 105.519 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -371.59 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+477.109 749.245 Td
+/F130_0 9.9626 Tf
+(Ho) 12.1743 Tj
+25 TJm
+(w) 7.193 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(use) 13.2801 Tj
+-250 TJm
+(bzip2) 22.1369 Tj
+[1 0 0 1 266.071 747.089] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 280.796 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -472.974 -5.0363] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -0.4981] cm
+q
+[] 0 d
+0 J
+0.4981 w
+0 0.2491 m
+475.465 0.2491 l
+S
+Q
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 479.251 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -21.5542] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -720] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 710.037 Td
+/F134_0 9.9626 Tf
+(-v) 11.9551 Tj
+-600 TJm
+(--verbose) 53.798 Tj
+[1 0 0 1 143.731 710.037] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -74.2217 -0.1544] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -709.883] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+108 698.082 Td
+/F130_0 9.9626 Tf
+(V) 7.193 Tj
+111 TJm
+(erbose) 26.0024 Tj
+-323 TJm
+(mode) 22.1369 Tj
+-322 TJm
+(--) 6.63509 Tj
+-323 TJm
+(sho) 13.8381 Tj
+25 TJm
+(w) 7.193 Tj
+-322 TJm
+(the) 12.1743 Tj
+-323 TJm
+(compression) 50.3609 Tj
+-323 TJm
+(ratio) 18.2614 Tj
+-322 TJm
+(for) 11.6164 Tj
+-323 TJm
+(each) 18.2515 Tj
+-322 TJm
+(\002le) 12.7322 Tj
+-323 TJm
+(processed.) 41.7732 Tj
+-1056 TJm
+(Further) 29.3299 Tj
+[1 0 0 1 430.015 698.082] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -430.015 -698.082] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+430.015 698.082 Td
+/F134_0 9.9626 Tf
+(-v) 11.9551 Tj
+[1 0 0 1 441.97 698.082] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -441.97 -698.082] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+441.97 698.082 Td
+/F130_0 9.9626 Tf
+(') 3.31755 Tj
+55 TJm
+(s) 3.87545 Tj
+-323 TJm
+(increase) 32.6375 Tj
+-322 TJm
+(the) 12.1743 Tj
+-323 TJm
+(v) 4.9813 Tj
+15 TJm
+(erbosity) 32.0995 Tj
+108 686.127 Td
+(le) 7.193 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(el,) 9.68365 Tj
+-250 TJm
+(spe) 13.2801 Tj
+25 TJm
+(wing) 19.9252 Tj
+-250 TJm
+(out) 12.7322 Tj
+-250 TJm
+(lots) 14.396 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(information) 47.0434 Tj
+-250 TJm
+(which) 24.3486 Tj
+-250 TJm
+(is) 6.64505 Tj
+-250 TJm
+(primarily) 37.0808 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(interest) 29.3299 Tj
+-250 TJm
+(for) 11.6164 Tj
+-250 TJm
+(diagnostic) 40.9562 Tj
+-250 TJm
+(purposes.) 37.9077 Tj
+[1 0 0 1 72 683.97] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -3.985] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -670.023] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 660.224 Td
+/F134_0 9.9626 Tf
+(-L) 11.9551 Tj
+-600 TJm
+(--license) 53.798 Tj
+-600 TJm
+(-V) 11.9551 Tj
+-600 TJm
+(--version) 53.798 Tj
+[1 0 0 1 221.44 660.224] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -151.93 -0.1544] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -660.07] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+108 648.269 Td
+/F130_0 9.9626 Tf
+(Display) 30.9936 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(softw) 22.1369 Tj
+10 TJm
+(are) 12.1643 Tj
+-250 TJm
+(v) 4.9813 Tj
+15 TJm
+(ersion,) 26.8392 Tj
+-250 TJm
+(license) 27.6661 Tj
+-250 TJm
+(terms) 22.1369 Tj
+-250 TJm
+(and) 14.386 Tj
+-250 TJm
+(conditions.) 44.0048 Tj
+[1 0 0 1 72 646.112] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -3.985] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -632.165] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 622.366 Td
+/F134_0 9.9626 Tf
+(-1) 11.9551 Tj
+[1 0 0 1 83.9552 622.366] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -83.9552 -622.366] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.4458 622.366 Td
+/F130_0 9.9626 Tf
+(\(or) 11.6164 Tj
+[1 0 0 1 100.553 622.366] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -100.553 -622.366] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+100.553 622.366 Td
+/F134_0 9.9626 Tf
+(--fast) 35.8654 Tj
+[1 0 0 1 136.418 622.366] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -136.418 -622.366] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+136.418 622.366 Td
+/F130_0 9.9626 Tf
+(\)) 3.31755 Tj
+-250 TJm
+(to) 7.7509 Tj
+[1 0 0 1 152.468 622.366] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -152.468 -622.366] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+152.468 622.366 Td
+/F134_0 9.9626 Tf
+(-9) 11.9551 Tj
+[1 0 0 1 164.423 622.366] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -164.423 -622.366] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+166.914 622.366 Td
+/F130_0 9.9626 Tf
+(\(or) 11.6164 Tj
+[1 0 0 1 181.021 622.366] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -181.021 -622.366] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+181.021 622.366 Td
+/F134_0 9.9626 Tf
+(-best) 29.8878 Tj
+[1 0 0 1 210.909 622.366] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -210.909 -622.366] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+210.909 622.366 Td
+/F130_0 9.9626 Tf
+(\)) 3.31755 Tj
+[1 0 0 1 214.226 622.366] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -142.226 -1.7832] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -620.583] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+108 610.411 Td
+/F130_0 9.9626 Tf
+(Set) 12.7322 Tj
+-288 TJm
+(the) 12.1743 Tj
+-289 TJm
+(block) 22.1369 Tj
+-288 TJm
+(size) 15.4918 Tj
+-288 TJm
+(to) 7.7509 Tj
+-288 TJm
+(100) 14.9439 Tj
+-289 TJm
+(k,) 7.47195 Tj
+-298 TJm
+(200) 14.9439 Tj
+-288 TJm
+(k) 4.9813 Tj
+-288 TJm
+(...) 7.47195 Tj
+-850 TJm
+(900) 14.9439 Tj
+-288 TJm
+(k) 4.9813 Tj
+-288 TJm
+(when) 21.579 Tj
+-289 TJm
+(compressing.) 52.8516 Tj
+-849 TJm
+(Has) 15.4918 Tj
+-289 TJm
+(no) 9.9626 Tj
+-288 TJm
+(ef) 7.74094 Tj
+25 TJm
+(fect) 14.9339 Tj
+-288 TJm
+(when) 21.579 Tj
+-288 TJm
+(decompressing.) 62.2563 Tj
+-850 TJm
+(See) 14.386 Tj
+[1 0 0 1 108 598.456] cm
+/DeviceRGB {} cs
+[0 0 1] sc
+/DeviceRGB {} CS
+[0 0 1] SC
+[1 0 0 1 -108 -598.456] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+108 598.456 Td
+/F130_0 9.9626 Tf
+(MEMOR) 37.6387 Tj
+65 TJm
+(Y) 7.193 Tj
+-297 TJm
+(MAN) 23.2427 Tj
+35 TJm
+(A) 7.193 Tj
+40 TJm
+(GEMENT) 41.5042 Tj
+[1 0 0 1 226.338 598.456] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 1] sc
+/DeviceRGB {} CS
+[0 0 1] SC
+/DeviceRGB {} cs
+[0 0 1] sc
+/DeviceRGB {} CS
+[0 0 1] SC
+[1 0 0 1 -226.338 -598.456] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+229.3 598.456 Td
+/F130_0 9.9626 Tf
+([5]) 11.6164 Tj
+[1 0 0 1 240.916 598.456] cm
+/DeviceRGB {} cs
+[0 0 1] sc
+/DeviceRGB {} CS
+[0 0 1] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -240.916 -598.456] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+243.878 598.456 Td
+/F130_0 9.9626 Tf
+(belo) 17.1556 Tj
+25 TJm
+(w) 7.193 Tj
+65 TJm
+(.) 2.49065 Tj
+-904 TJm
+(The) 15.4918 Tj
+[1 0 0 1 297.278 598.456] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -297.278 -598.456] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+297.278 598.456 Td
+/F134_0 9.9626 Tf
+(--fast) 35.8654 Tj
+[1 0 0 1 333.144 598.456] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -333.144 -598.456] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+336.106 598.456 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 353.454 598.456] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -353.454 -598.456] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+353.454 598.456 Td
+/F134_0 9.9626 Tf
+(--best) 35.8654 Tj
+[1 0 0 1 389.319 598.456] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -389.319 -598.456] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+392.281 598.456 Td
+/F130_0 9.9626 Tf
+(aliases) 26.5603 Tj
+-297 TJm
+(are) 12.1643 Tj
+-298 TJm
+(primarily) 37.0808 Tj
+-297 TJm
+(for) 11.6164 Tj
+-297 TJm
+(GNU) 21.579 Tj
+[1 0 0 1 516.09 598.456] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -516.09 -598.456] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+516.09 598.456 Td
+/F134_0 9.9626 Tf
+(gzip) 23.9102 Tj
+[1 0 0 1 540 598.456] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -540 -598.456] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+108 586.501 Td
+/F130_0 9.9626 Tf
+(compatibility) 53.1405 Tj
+65 TJm
+(.) 2.49065 Tj
+-356 TJm
+(In) 8.29885 Tj
+-265 TJm
+(particular) 38.1767 Tj
+40 TJm
+(,) 2.49065 Tj
+[1 0 0 1 220.423 586.501] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -220.423 -586.501] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+220.423 586.501 Td
+/F134_0 9.9626 Tf
+(--fast) 35.8654 Tj
+[1 0 0 1 256.288 586.501] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -256.288 -586.501] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+258.932 586.501 Td
+/F130_0 9.9626 Tf
+(doesn') 26.5603 Tj
+18 TJm
+(t) 2.7696 Tj
+-265 TJm
+(mak) 17.1556 Tj
+10 TJm
+(e) 4.42339 Tj
+-266 TJm
+(things) 24.3586 Tj
+-265 TJm
+(signi\002cantly) 49.2651 Tj
+-265 TJm
+(f) 3.31755 Tj
+10 TJm
+(aster) 18.8094 Tj
+55 TJm
+(.) 2.49065 Tj
+-712 TJm
+(And) 17.1556 Tj
+[1 0 0 1 444.622 586.501] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.622 -586.501] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+444.622 586.501 Td
+/F134_0 9.9626 Tf
+(--best) 35.8654 Tj
+[1 0 0 1 480.487 586.501] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -480.487 -586.501] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+483.131 586.501 Td
+/F130_0 9.9626 Tf
+(merely) 27.6661 Tj
+-265 TJm
+(selects) 26.5603 Tj
+108 574.546 Td
+(the) 12.1743 Tj
+-250 TJm
+(def) 12.7222 Tj
+10 TJm
+(ault) 14.9439 Tj
+-250 TJm
+(beha) 18.8094 Tj
+20 TJm
+(viour) 21.031 Tj
+55 TJm
+(.) 2.49065 Tj
+[1 0 0 1 72 574.446] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -3.985] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -560.498] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 548.643 Td
+/F134_0 9.9626 Tf
+(--) 11.9551 Tj
+[1 0 0 1 83.9552 548.643] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -14.4458 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -548.643] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+108 536.688 Td
+/F130_0 9.9626 Tf
+(T) 6.08715 Tj
+35 TJm
+(reats) 18.8094 Tj
+-261 TJm
+(all) 9.9626 Tj
+-261 TJm
+(subsequent) 44.2738 Tj
+-260 TJm
+(ar) 7.74094 Tj
+18 TJm
+(guments) 33.7633 Tj
+-261 TJm
+(as) 8.29885 Tj
+-261 TJm
+(\002le) 12.7322 Tj
+-261 TJm
+(names,) 27.9451 Tj
+-263 TJm
+(e) 4.42339 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(en) 9.40469 Tj
+-261 TJm
+(if) 6.08715 Tj
+-261 TJm
+(the) 12.1743 Tj
+15 TJm
+(y) 4.9813 Tj
+-260 TJm
+(start) 17.1556 Tj
+-261 TJm
+(with) 17.7135 Tj
+-261 TJm
+(a) 4.42339 Tj
+-261 TJm
+(dash.) 20.7521 Tj
+-685 TJm
+(This) 17.7135 Tj
+-260 TJm
+(is) 6.64505 Tj
+-261 TJm
+(so) 8.85675 Tj
+-261 TJm
+(you) 14.9439 Tj
+-261 TJm
+(can) 13.8281 Tj
+-260 TJm
+(handle) 26.5603 Tj
+-261 TJm
+(\002les) 16.6077 Tj
+108 524.732 Td
+(with) 17.7135 Tj
+-250 TJm
+(names) 25.4544 Tj
+-250 TJm
+(be) 9.40469 Tj
+15 TJm
+(ginning) 30.4457 Tj
+-250 TJm
+(with) 17.7135 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(dash,) 20.7521 Tj
+-250 TJm
+(for) 11.6164 Tj
+-250 TJm
+(e) 4.42339 Tj
+15 TJm
+(xample:) 32.0995 Tj
+[1 0 0 1 302.27 524.732] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -302.27 -524.732] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+302.27 524.732 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+-600 TJm
+(--) 11.9551 Tj
+-600 TJm
+(-myfilename) 65.7532 Tj
+[1 0 0 1 421.821 524.732] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -421.821 -524.732] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+421.821 524.732 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+[1 0 0 1 72 522.576] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -3.985] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -508.628] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 498.83 Td
+/F134_0 9.9626 Tf
+(--repetitive-fast) 101.619 Tj
+[1 0 0 1 173.619 498.83] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -173.619 -498.83] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+173.619 498.83 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 178.6 498.83] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -183.582 -498.83] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+183.582 498.83 Td
+/F134_0 9.9626 Tf
+(--repetitive-best) 101.619 Tj
+[1 0 0 1 285.2 498.83] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -215.691 -1.5342] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -497.295] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+108 486.874 Td
+/F130_0 9.9626 Tf
+(These) 23.7907 Tj
+-207 TJm
+(\003ags) 18.8194 Tj
+-206 TJm
+(are) 12.1643 Tj
+-207 TJm
+(redundant) 39.8404 Tj
+-207 TJm
+(in) 7.7509 Tj
+-206 TJm
+(v) 4.9813 Tj
+15 TJm
+(ersions) 28.224 Tj
+-207 TJm
+(0.9.5) 19.9252 Tj
+-207 TJm
+(and) 14.386 Tj
+-206 TJm
+(abo) 14.386 Tj
+15 TJm
+(v) 4.9813 Tj
+15 TJm
+(e.) 6.91404 Tj
+-591 TJm
+(The) 15.4918 Tj
+15 TJm
+(y) 4.9813 Tj
+-207 TJm
+(pro) 13.2801 Tj
+15 TJm
+(vided) 22.1369 Tj
+-207 TJm
+(some) 21.031 Tj
+-207 TJm
+(c) 4.42339 Tj
+1 TJm
+(o) 4.9813 Tj
+-1 TJm
+(a) 4.42339 Tj
+1 TJm
+(rse) 11.6164 Tj
+-207 TJm
+(control) 28.224 Tj
+-207 TJm
+(o) 4.9813 Tj
+15 TJm
+(v) 4.9813 Tj
+15 TJm
+(er) 7.74094 Tj
+-207 TJm
+(the) 12.1743 Tj
+-206 TJm
+(beha) 18.8094 Tj
+20 TJm
+(viour) 21.031 Tj
+108 474.919 Td
+(of) 8.29885 Tj
+-250 TJm
+(the) 12.1743 Tj
+-251 TJm
+(sorting) 27.6761 Tj
+-250 TJm
+(algorithm) 38.7446 Tj
+-250 TJm
+(in) 7.7509 Tj
+-251 TJm
+(earlier) 25.4445 Tj
+-250 TJm
+(v) 4.9813 Tj
+15 TJm
+(ersions,) 30.7147 Tj
+-250 TJm
+(which) 24.3486 Tj
+-251 TJm
+(w) 7.193 Tj
+10 TJm
+(as) 8.29885 Tj
+-250 TJm
+(sometimes) 42.62 Tj
+-250 TJm
+(useful.) 26.8392 Tj
+-622 TJm
+(0.9.5) 19.9252 Tj
+-251 TJm
+(and) 14.386 Tj
+-250 TJm
+(abo) 14.386 Tj
+15 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-250 TJm
+(ha) 9.40469 Tj
+20 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-251 TJm
+(an) 9.40469 Tj
+-250 TJm
+(impro) 23.8007 Tj
+15 TJm
+(v) 4.9813 Tj
+15 TJm
+(ed) 9.40469 Tj
+108 462.964 Td
+(algorithm) 38.7446 Tj
+-250 TJm
+(which) 24.3486 Tj
+-250 TJm
+(renders) 29.3199 Tj
+-250 TJm
+(these) 20.4731 Tj
+-250 TJm
+(\003ags) 18.8194 Tj
+-250 TJm
+(irrele) 21.0211 Tj
+25 TJm
+(v) 4.9813 Tj
+25 TJm
+(ant.) 14.6649 Tj
+[1 0 0 1 72 460.807] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -3.985] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -436.897] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 414.264 Td
+/F122_0 20.6585 Tf
+(2.5.) 34.4584 Tj
+-278 TJm
+(MEMOR) 79.184 Tj
+50 TJm
+(Y) 13.7792 Tj
+-278 TJm
+(MANA) 61.9548 Tj
+50 TJm
+(GEMENT) 88.3771 Tj
+[1 0 0 1 72 414.005] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -404.043] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 392.346 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 101.888 392.346] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -101.888 -392.346] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+104.454 392.346 Td
+/F130_0 9.9626 Tf
+(compresses) 45.9276 Tj
+-258 TJm
+(lar) 10.5105 Tj
+18 TJm
+(ge) 9.40469 Tj
+-257 TJm
+(\002les) 16.6077 Tj
+-258 TJm
+(in) 7.7509 Tj
+-257 TJm
+(blocks.) 28.503 Tj
+-666 TJm
+(The) 15.4918 Tj
+-257 TJm
+(block) 22.1369 Tj
+-258 TJm
+(size) 15.4918 Tj
+-258 TJm
+(af) 7.74094 Tj
+25 TJm
+(fects) 18.8094 Tj
+-257 TJm
+(both) 17.7135 Tj
+-258 TJm
+(the) 12.1743 Tj
+-257 TJm
+(compression) 50.3609 Tj
+-258 TJm
+(ratio) 18.2614 Tj
+-257 TJm
+(achie) 21.0211 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(ed,) 11.8953 Tj
+-260 TJm
+(and) 14.386 Tj
+-258 TJm
+(the) 12.1743 Tj
+-257 TJm
+(amount) 29.8878 Tj
+72 380.391 Td
+(of) 8.29885 Tj
+-215 TJm
+(memory) 33.2053 Tj
+-215 TJm
+(needed) 28.2141 Tj
+-215 TJm
+(for) 11.6164 Tj
+-215 TJm
+(compression) 50.3609 Tj
+-214 TJm
+(and) 14.386 Tj
+-215 TJm
+(decompression.) 62.2563 Tj
+-597 TJm
+(The) 15.4918 Tj
+-215 TJm
+(\003ags) 18.8194 Tj
+[1 0 0 1 337.719 380.391] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -337.719 -380.391] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+337.719 380.391 Td
+/F134_0 9.9626 Tf
+(-1) 11.9551 Tj
+[1 0 0 1 349.674 380.391] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -349.674 -380.391] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+351.815 380.391 Td
+/F130_0 9.9626 Tf
+(through) 30.9936 Tj
+[1 0 0 1 384.95 380.391] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -384.95 -380.391] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+384.95 380.391 Td
+/F134_0 9.9626 Tf
+(-9) 11.9551 Tj
+[1 0 0 1 396.905 380.391] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -396.905 -380.391] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+399.046 380.391 Td
+/F130_0 9.9626 Tf
+(specify) 28.772 Tj
+-215 TJm
+(the) 12.1743 Tj
+-215 TJm
+(block) 22.1369 Tj
+-215 TJm
+(size) 15.4918 Tj
+-215 TJm
+(to) 7.7509 Tj
+-214 TJm
+(be) 9.40469 Tj
+-215 TJm
+(100,000) 32.3785 Tj
+72 368.435 Td
+(bytes) 21.031 Tj
+-278 TJm
+(through) 30.9936 Tj
+-277 TJm
+(900,000) 32.3785 Tj
+-278 TJm
+(bytes) 21.031 Tj
+-278 TJm
+(\(the) 15.4918 Tj
+-277 TJm
+(def) 12.7222 Tj
+10 TJm
+(ault\)) 18.2614 Tj
+-278 TJm
+(respecti) 30.9837 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(ely) 12.1743 Tj
+65 TJm
+(.) 2.49065 Tj
+-786 TJm
+(At) 9.9626 Tj
+-278 TJm
+(decompression) 59.7656 Tj
+-278 TJm
+(time,) 20.2042 Tj
+-284 TJm
+(the) 12.1743 Tj
+-278 TJm
+(block) 22.1369 Tj
+-278 TJm
+(size) 15.4918 Tj
+-277 TJm
+(used) 18.2614 Tj
+-278 TJm
+(for) 11.6164 Tj
+-278 TJm
+(compression) 50.3609 Tj
+72 356.48 Td
+(is) 6.64505 Tj
+-243 TJm
+(read) 17.1456 Tj
+-242 TJm
+(from) 19.3673 Tj
+-243 TJm
+(the) 12.1743 Tj
+-242 TJm
+(header) 26.5503 Tj
+-243 TJm
+(of) 8.29885 Tj
+-242 TJm
+(the) 12.1743 Tj
+-243 TJm
+(compressed) 47.0334 Tj
+-242 TJm
+(\002le,) 15.2229 Tj
+-244 TJm
+(and) 14.386 Tj
+[1 0 0 1 275.174 356.48] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -275.174 -356.48] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+275.174 356.48 Td
+/F134_0 9.9626 Tf
+(bunzip2) 41.8429 Tj
+[1 0 0 1 317.017 356.48] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -317.017 -356.48] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+319.433 356.48 Td
+/F130_0 9.9626 Tf
+(then) 17.1556 Tj
+-243 TJm
+(all) 9.9626 Tj
+1 TJm
+(o) 4.9813 Tj
+-1 TJm
+(c) 4.42339 Tj
+1 TJm
+(ates) 15.4918 Tj
+-243 TJm
+(itself) 19.9252 Tj
+-242 TJm
+(just) 14.396 Tj
+-243 TJm
+(enough) 29.3299 Tj
+-243 TJm
+(memory) 33.2053 Tj
+-242 TJm
+(to) 7.7509 Tj
+-243 TJm
+(decompress) 47.0334 Tj
+72 344.525 Td
+(the) 12.1743 Tj
+-303 TJm
+(\002le.) 15.2229 Tj
+-940 TJm
+(Since) 22.1369 Tj
+-304 TJm
+(block) 22.1369 Tj
+-303 TJm
+(sizes) 19.3673 Tj
+-303 TJm
+(are) 12.1643 Tj
+-303 TJm
+(stored) 24.3486 Tj
+-304 TJm
+(in) 7.7509 Tj
+-303 TJm
+(compressed) 47.0334 Tj
+-303 TJm
+(\002les,) 19.0983 Tj
+-317 TJm
+(it) 5.53921 Tj
+-303 TJm
+(follo) 18.8194 Tj
+25 TJm
+(ws) 11.0684 Tj
+-304 TJm
+(that) 14.9439 Tj
+-303 TJm
+(the) 12.1743 Tj
+-303 TJm
+(\003ags) 18.8194 Tj
+[1 0 0 1 406.35 344.525] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -406.35 -344.525] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+406.35 344.525 Td
+/F134_0 9.9626 Tf
+(-1) 11.9551 Tj
+[1 0 0 1 418.305 344.525] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -418.305 -344.525] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+421.327 344.525 Td
+/F130_0 9.9626 Tf
+(to) 7.7509 Tj
+[1 0 0 1 432.1 344.525] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -432.1 -344.525] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+432.1 344.525 Td
+/F134_0 9.9626 Tf
+(-9) 11.9551 Tj
+[1 0 0 1 444.055 344.525] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.055 -344.525] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+447.077 344.525 Td
+/F130_0 9.9626 Tf
+(are) 12.1643 Tj
+-303 TJm
+(irrele) 21.0211 Tj
+25 TJm
+(v) 4.9813 Tj
+25 TJm
+(ant) 12.1743 Tj
+-304 TJm
+(to) 7.7509 Tj
+-303 TJm
+(and) 14.386 Tj
+-303 TJm
+(so) 8.85675 Tj
+72 332.57 Td
+(ignored) 30.4357 Tj
+-250 TJm
+(during) 26.0123 Tj
+-250 TJm
+(decompression.) 62.2563 Tj
+[1 0 0 1 72 330.413] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -320.45] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 310.652 Td
+/F130_0 9.9626 Tf
+(Compression) 52.5826 Tj
+-250 TJm
+(and) 14.386 Tj
+-250 TJm
+(decompression) 59.7656 Tj
+-250 TJm
+(requirements,) 54.5054 Tj
+-250 TJm
+(in) 7.7509 Tj
+-250 TJm
+(bytes,) 23.5217 Tj
+-250 TJm
+(can) 13.8281 Tj
+-250 TJm
+(be) 9.40469 Tj
+-250 TJm
+(estimated) 38.1866 Tj
+-250 TJm
+(as:) 11.0684 Tj
+[1 0 0 1 72 308.495] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -60.7721] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 59.7758 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 56.1893] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -299.13] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 299.13 Td
+/F134_0 9.9626 Tf
+(Compression:) 71.7307 Tj
+-1278 TJm
+(400k) 23.9102 Tj
+-426 TJm
+(+) 5.97756 Tj
+-426 TJm
+(\() 5.97756 Tj
+-426 TJm
+(8) 5.97756 Tj
+-426 TJm
+(x) 5.97756 Tj
+-426 TJm
+(block) 29.8878 Tj
+-426 TJm
+(size) 23.9102 Tj
+-426 TJm
+(\)) 5.97756 Tj
+90 275.22 Td
+(Decompression:) 83.6858 Tj
+-426 TJm
+(100k) 23.9102 Tj
+-426 TJm
+(+) 5.97756 Tj
+-426 TJm
+(\() 5.97756 Tj
+-426 TJm
+(4) 5.97756 Tj
+-426 TJm
+(x) 5.97756 Tj
+-426 TJm
+(block) 29.8878 Tj
+-426 TJm
+(size) 23.9102 Tj
+-426 TJm
+(\),) 11.9551 Tj
+-426 TJm
+(or) 11.9551 Tj
+153.66 263.265 Td
+(100k) 23.9102 Tj
+-426 TJm
+(+) 5.97756 Tj
+-426 TJm
+(\() 5.97756 Tj
+-426 TJm
+(2.5) 17.9327 Tj
+-426 TJm
+(x) 5.97756 Tj
+-426 TJm
+(block) 29.8878 Tj
+-426 TJm
+(size) 23.9102 Tj
+-426 TJm
+(\)) 5.97756 Tj
+[1 0 0 1 72 247.723] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.5492] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -237.761] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 225.805 Td
+/F130_0 9.9626 Tf
+(Lar) 13.8281 Tj
+18 TJm
+(ger) 12.7222 Tj
+-292 TJm
+(block) 22.1369 Tj
+-292 TJm
+(sizes) 19.3673 Tj
+-291 TJm
+(gi) 7.7509 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-292 TJm
+(rapidly) 28.224 Tj
+-292 TJm
+(diminishing) 47.6113 Tj
+-292 TJm
+(mar) 15.4918 Tj
+18 TJm
+(ginal) 19.9252 Tj
+-291 TJm
+(returns.) 30.1568 Tj
+-871 TJm
+(Most) 20.4831 Tj
+-292 TJm
+(of) 8.29885 Tj
+-291 TJm
+(the) 12.1743 Tj
+-292 TJm
+(compression) 50.3609 Tj
+-292 TJm
+(comes) 25.4544 Tj
+-292 TJm
+(from) 19.3673 Tj
+-291 TJm
+(the) 12.1743 Tj
+-292 TJm
+(\002rst) 15.5018 Tj
+-292 TJm
+(tw) 9.9626 Tj
+10 TJm
+(o) 4.9813 Tj
+-292 TJm
+(or) 8.29885 Tj
+72 213.85 Td
+(three) 19.9152 Tj
+-232 TJm
+(hundred) 32.6474 Tj
+-232 TJm
+(k) 4.9813 Tj
+-232 TJm
+(of) 8.29885 Tj
+-232 TJm
+(block) 22.1369 Tj
+-232 TJm
+(size,) 17.9825 Tj
+-235 TJm
+(a) 4.42339 Tj
+-232 TJm
+(f) 3.31755 Tj
+10 TJm
+(act) 11.6164 Tj
+-232 TJm
+(w) 7.193 Tj
+10 TJm
+(orth) 16.0497 Tj
+-232 TJm
+(bearing) 29.8778 Tj
+-232 TJm
+(in) 7.7509 Tj
+-232 TJm
+(mind) 20.4831 Tj
+-232 TJm
+(when) 21.579 Tj
+-231 TJm
+(using) 21.589 Tj
+[1 0 0 1 354.025 213.85] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -354.025 -213.85] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+354.025 213.85 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 383.913 213.85] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -383.913 -213.85] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+386.223 213.85 Td
+/F130_0 9.9626 Tf
+(on) 9.9626 Tj
+-232 TJm
+(small) 21.589 Tj
+-232 TJm
+(machines.) 40.1194 Tj
+-304 TJm
+(It) 6.08715 Tj
+-232 TJm
+(is) 6.64505 Tj
+-232 TJm
+(also) 16.0497 Tj
+-231 TJm
+(important) 38.7446 Tj
+72 201.895 Td
+(to) 7.7509 Tj
+-250 TJm
+(appreciate) 40.9363 Tj
+-250 TJm
+(that) 14.9439 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(decompression) 59.7656 Tj
+-250 TJm
+(memory) 33.2053 Tj
+-250 TJm
+(requirement) 48.1393 Tj
+-250 TJm
+(is) 6.64505 Tj
+-250 TJm
+(set) 11.0684 Tj
+-250 TJm
+(at) 7.193 Tj
+-250 TJm
+(compression) 50.3609 Tj
+-250 TJm
+(time) 17.7135 Tj
+-250 TJm
+(by) 9.9626 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(choice) 26.0024 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(block) 22.1369 Tj
+-250 TJm
+(size.) 17.9825 Tj
+[1 0 0 1 72 199.738] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -189.776] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 179.977 Td
+/F130_0 9.9626 Tf
+(F) 5.53921 Tj
+15 TJm
+(or) 8.29885 Tj
+-388 TJm
+(\002les) 16.6077 Tj
+-389 TJm
+(compressed) 47.0334 Tj
+-388 TJm
+(with) 17.7135 Tj
+-389 TJm
+(the) 12.1743 Tj
+-388 TJm
+(def) 12.7222 Tj
+10 TJm
+(ault) 14.9439 Tj
+-389 TJm
+(900k) 19.9252 Tj
+-388 TJm
+(block) 22.1369 Tj
+-389 TJm
+(size,) 17.9825 Tj
+[1 0 0 1 302.002 179.977] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -302.002 -179.977] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+302.002 179.977 Td
+/F134_0 9.9626 Tf
+(bunzip2) 41.8429 Tj
+[1 0 0 1 343.846 179.977] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -343.846 -179.977] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+347.715 179.977 Td
+/F130_0 9.9626 Tf
+(will) 15.5018 Tj
+-388 TJm
+(require) 28.2141 Tj
+-389 TJm
+(about) 22.1369 Tj
+-388 TJm
+(3700) 19.9252 Tj
+-389 TJm
+(kbytes) 26.0123 Tj
+-388 TJm
+(to) 7.7509 Tj
+-389 TJm
+(decompress.) 49.5241 Tj
+72 168.022 Td
+(T) 6.08715 Tj
+80 TJm
+(o) 4.9813 Tj
+-424 TJm
+(support) 29.8878 Tj
+-425 TJm
+(decompression) 59.7656 Tj
+-424 TJm
+(of) 8.29885 Tj
+-424 TJm
+(an) 9.40469 Tj
+15 TJm
+(y) 4.9813 Tj
+-425 TJm
+(\002l) 8.30881 Tj
+1 TJm
+(e) 4.42339 Tj
+-425 TJm
+(on) 9.9626 Tj
+-424 TJm
+(a) 4.42339 Tj
+-424 TJm
+(4) 4.9813 Tj
+-425 TJm
+(me) 12.1743 Tj
+15 TJm
+(g) 4.9813 Tj
+5 TJm
+(abyte) 21.579 Tj
+-424 TJm
+(machine,) 36.2439 Tj
+[1 0 0 1 348.272 168.022] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -348.272 -168.022] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+348.272 168.022 Td
+/F134_0 9.9626 Tf
+(bunzip2) 41.8429 Tj
+[1 0 0 1 390.115 168.022] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -390.115 -168.022] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+394.342 168.022 Td
+/F130_0 9.9626 Tf
+(has) 13.2801 Tj
+-424 TJm
+(an) 9.40469 Tj
+-425 TJm
+(option) 25.4644 Tj
+-424 TJm
+(to) 7.7509 Tj
+-424 TJm
+(decompress) 47.0334 Tj
+-424 TJm
+(using) 21.589 Tj
+72 156.067 Td
+(approximately) 57.5539 Tj
+-281 TJm
+(half) 15.4918 Tj
+-281 TJm
+(this) 14.396 Tj
+-280 TJm
+(amount) 29.8878 Tj
+-281 TJm
+(of) 8.29885 Tj
+-281 TJm
+(memory) 33.2053 Tj
+65 TJm
+(,) 2.49065 Tj
+-288 TJm
+(about) 22.1369 Tj
+-281 TJm
+(2300) 19.9252 Tj
+-281 TJm
+(kbytes.) 28.503 Tj
+-805 TJm
+(Decompression) 61.9773 Tj
+-280 TJm
+(speed) 22.6848 Tj
+-281 TJm
+(is) 6.64505 Tj
+-281 TJm
+(also) 16.0497 Tj
+-281 TJm
+(halv) 17.1556 Tj
+15 TJm
+(ed,) 11.8953 Tj
+-288 TJm
+(so) 8.85675 Tj
+-281 TJm
+(you) 14.9439 Tj
+-281 TJm
+(should) 26.5703 Tj
+72 144.112 Td
+(use) 13.2801 Tj
+-250 TJm
+(this) 14.396 Tj
+-250 TJm
+(option) 25.4644 Tj
+-250 TJm
+(only) 17.7135 Tj
+-250 TJm
+(where) 24.3386 Tj
+-250 TJm
+(necessary) 38.7246 Tj
+65 TJm
+(.) 2.49065 Tj
+-620 TJm
+(The) 15.4918 Tj
+-250 TJm
+(rele) 14.9339 Tj
+25 TJm
+(v) 4.9813 Tj
+25 TJm
+(ant) 12.1743 Tj
+-250 TJm
+(\003ag) 14.9439 Tj
+-250 TJm
+(is) 6.64505 Tj
+[1 0 0 1 305.024 144.112] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -305.024 -144.112] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+305.024 144.112 Td
+/F134_0 9.9626 Tf
+(-s) 11.9551 Tj
+[1 0 0 1 316.979 144.112] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -316.979 -144.112] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+316.979 144.112 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+[1 0 0 1 72 141.955] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -131.992] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 122.194 Td
+/F130_0 9.9626 Tf
+(In) 8.29885 Tj
+-204 TJm
+(general,) 31.8106 Tj
+-214 TJm
+(try) 11.0684 Tj
+-204 TJm
+(and) 14.386 Tj
+-205 TJm
+(use) 13.2801 Tj
+-204 TJm
+(the) 12.1743 Tj
+-204 TJm
+(lar) 10.5105 Tj
+18 TJm
+(gest) 16.0497 Tj
+-205 TJm
+(block) 22.1369 Tj
+-204 TJm
+(size) 15.4918 Tj
+-205 TJm
+(memory) 33.2053 Tj
+-204 TJm
+(constraints) 43.1679 Tj
+-204 TJm
+(allo) 14.9439 Tj
+25 TJm
+(w) 7.193 Tj
+65 TJm
+(,) 2.49065 Tj
+-214 TJm
+(since) 20.4731 Tj
+-204 TJm
+(that) 14.9439 Tj
+-205 TJm
+(maximises) 42.62 Tj
+-204 TJm
+(the) 12.1743 Tj
+-204 TJm
+(compression) 50.3609 Tj
+-205 TJm
+(achie) 21.0211 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(ed.) 11.8953 Tj
+72 110.239 Td
+(Compression) 52.5826 Tj
+-250 TJm
+(and) 14.386 Tj
+-250 TJm
+(decompression) 59.7656 Tj
+-250 TJm
+(speed) 22.6848 Tj
+-250 TJm
+(are) 12.1643 Tj
+-250 TJm
+(virtually) 33.7633 Tj
+-250 TJm
+(unaf) 17.7035 Tj
+25 TJm
+(fected) 24.3386 Tj
+-250 TJm
+(by) 9.9626 Tj
+-250 TJm
+(block) 22.1369 Tj
+-250 TJm
+(size.) 17.9825 Tj
+[1 0 0 1 72 108.082] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -98.1193] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 88.321 Td
+/F130_0 9.9626 Tf
+(Another) 32.6474 Tj
+-296 TJm
+(signi\002cant) 41.5142 Tj
+-296 TJm
+(point) 20.4831 Tj
+-295 TJm
+(applies) 28.224 Tj
+-296 TJm
+(to) 7.7509 Tj
+-296 TJm
+(\002les) 16.6077 Tj
+-296 TJm
+(which) 24.3486 Tj
+-296 TJm
+(\002t) 8.30881 Tj
+-296 TJm
+(in) 7.7509 Tj
+-296 TJm
+(a) 4.42339 Tj
+-295 TJm
+(single) 23.8007 Tj
+-296 TJm
+(block) 22.1369 Tj
+-296 TJm
+(--) 6.63509 Tj
+-296 TJm
+(that) 14.9439 Tj
+-296 TJm
+(means) 25.4544 Tj
+-296 TJm
+(most) 19.3773 Tj
+-295 TJm
+(\002les) 16.6077 Tj
+-296 TJm
+(you') 18.2614 Tj
+50 TJm
+(d) 4.9813 Tj
+-296 TJm
+(encounter) 39.2825 Tj
+-296 TJm
+(using) 21.589 Tj
+-296 TJm
+(a) 4.42339 Tj
+72 76.3658 Td
+(lar) 10.5105 Tj
+18 TJm
+(ge) 9.40469 Tj
+-290 TJm
+(block) 22.1369 Tj
+-290 TJm
+(size.) 17.9825 Tj
+-859 TJm
+(The) 15.4918 Tj
+-290 TJm
+(amount) 29.8878 Tj
+-290 TJm
+(of) 8.29885 Tj
+-290 TJm
+(real) 14.9339 Tj
+-290 TJm
+(memory) 33.2053 Tj
+-289 TJm
+(touched) 31.5416 Tj
+-290 TJm
+(is) 6.64505 Tj
+-290 TJm
+(proportional) 49.2551 Tj
+-290 TJm
+(to) 7.7509 Tj
+-290 TJm
+(the) 12.1743 Tj
+-290 TJm
+(size) 15.4918 Tj
+-290 TJm
+(of) 8.29885 Tj
+-290 TJm
+(the) 12.1743 Tj
+-289 TJm
+(\002le,) 15.2229 Tj
+-300 TJm
+(since) 20.4731 Tj
+-290 TJm
+(the) 12.1743 Tj
+-290 TJm
+(\002le) 12.7322 Tj
+-290 TJm
+(is) 6.64505 Tj
+-290 TJm
+(smaller) 29.3299 Tj
+[1 0 0 1 72 50.8518] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 374.394 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 6.8541] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 43.0633 -6.7545] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -496.332 -50.9514] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+539.395 50.9514 Td
+/F130_0 9.9626 Tf
+(5) 4.9813 Tj
+[1 0 0 1 453.269 50.8518] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 93.5985 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.2765 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+Q
+showpage
+%%PageTrailer
+pdfEndPage
+%%Page: 9 9
+%%BeginPageSetup
+%%PageOrientation: Portrait
+pdfStartPage
+0 0 612 792 re W
+%%EndPageSetup
+[] 0 d
+1 i
+0 j
+0 J
+10 M
+1 w
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+false op
+false OP
+0 0 612 792 re
+W
+q
+[1 0 0 1 72 741.554] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 14.4459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 187.197 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 -8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 105.519 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -371.59 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+477.109 749.245 Td
+/F130_0 9.9626 Tf
+(Ho) 12.1743 Tj
+25 TJm
+(w) 7.193 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(use) 13.2801 Tj
+-250 TJm
+(bzip2) 22.1369 Tj
+[1 0 0 1 266.071 747.089] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 280.796 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -472.974 -5.0363] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -0.4981] cm
+q
+[] 0 d
+0 J
+0.4981 w
+0 0.2491 m
+475.465 0.2491 l
+S
+Q
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 479.251 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -540 -741.554] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 710.037 Td
+/F130_0 9.9626 Tf
+(than) 17.1556 Tj
+-362 TJm
+(a) 4.42339 Tj
+-362 TJm
+(block.) 24.6275 Tj
+-1293 TJm
+(F) 5.53921 Tj
+15 TJm
+(or) 8.29885 Tj
+-362 TJm
+(e) 4.42339 Tj
+15 TJm
+(xample,) 31.8205 Tj
+-390 TJm
+(compressing) 50.3609 Tj
+-362 TJm
+(a) 4.42339 Tj
+-362 TJm
+(\002le) 12.7322 Tj
+-362 TJm
+(20,000) 27.3972 Tj
+-362 TJm
+(bytes) 21.031 Tj
+-362 TJm
+(long) 17.7135 Tj
+-362 TJm
+(with) 17.7135 Tj
+-362 TJm
+(the) 12.1743 Tj
+-362 TJm
+(\003ag) 14.9439 Tj
+[1 0 0 1 406.528 710.037] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -406.528 -710.037] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+406.528 710.037 Td
+/F134_0 9.9626 Tf
+(-9) 11.9551 Tj
+[1 0 0 1 418.483 710.037] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -418.483 -710.037] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+422.09 710.037 Td
+/F130_0 9.9626 Tf
+(will) 15.5018 Tj
+-362 TJm
+(cause) 22.1269 Tj
+-362 TJm
+(the) 12.1743 Tj
+-362 TJm
+(compressor) 45.9276 Tj
+-362 TJm
+(to) 7.7509 Tj
+72 698.082 Td
+(allocate) 30.9837 Tj
+-271 TJm
+(around) 27.6661 Tj
+-272 TJm
+(7600k) 24.9065 Tj
+-271 TJm
+(of) 8.29885 Tj
+-272 TJm
+(memory) 33.2053 Tj
+65 TJm
+(,) 2.49065 Tj
+-277 TJm
+(b) 4.9813 Tj
+20 TJm
+(ut) 7.7509 Tj
+-271 TJm
+(only) 17.7135 Tj
+-272 TJm
+(touch) 22.1369 Tj
+-271 TJm
+(400k) 19.9252 Tj
+-272 TJm
+(+) 5.61891 Tj
+-271 TJm
+(20000) 24.9065 Tj
+-272 TJm
+(*) 4.9813 Tj
+-271 TJm
+(8) 4.9813 Tj
+-272 TJm
+(=) 5.61891 Tj
+-271 TJm
+(560) 14.9439 Tj
+-272 TJm
+(kbytes) 26.0123 Tj
+-271 TJm
+(of) 8.29885 Tj
+-272 TJm
+(it.) 8.02986 Tj
+-748 TJm
+(Similarly) 37.0908 Tj
+65 TJm
+(,) 2.49065 Tj
+-277 TJm
+(the) 12.1743 Tj
+-272 TJm
+(decompressor) 55.3323 Tj
+72 686.127 Td
+(will) 15.5018 Tj
+-250 TJm
+(allocate) 30.9837 Tj
+-250 TJm
+(3700k) 24.9065 Tj
+-250 TJm
+(b) 4.9813 Tj
+20 TJm
+(ut) 7.7509 Tj
+-250 TJm
+(only) 17.7135 Tj
+-250 TJm
+(touch) 22.1369 Tj
+-250 TJm
+(100k) 19.9252 Tj
+-250 TJm
+(+) 5.61891 Tj
+-250 TJm
+(20000) 24.9065 Tj
+-250 TJm
+(*) 4.9813 Tj
+-250 TJm
+(4) 4.9813 Tj
+-250 TJm
+(=) 5.61891 Tj
+-250 TJm
+(180) 14.9439 Tj
+-250 TJm
+(kbytes.) 28.503 Tj
+[1 0 0 1 72 683.97] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -674.008] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 664.209 Td
+/F130_0 9.9626 Tf
+(Here) 19.3573 Tj
+-293 TJm
+(is) 6.64505 Tj
+-294 TJm
+(a) 4.42339 Tj
+-293 TJm
+(table) 19.3673 Tj
+-294 TJm
+(which) 24.3486 Tj
+-293 TJm
+(summarises) 47.0434 Tj
+-294 TJm
+(the) 12.1743 Tj
+-293 TJm
+(maximum) 40.4083 Tj
+-294 TJm
+(memory) 33.2053 Tj
+-293 TJm
+(usage) 22.6848 Tj
+-294 TJm
+(for) 11.6164 Tj
+-293 TJm
+(dif) 11.0684 Tj
+25 TJm
+(ferent) 23.2328 Tj
+-294 TJm
+(block) 22.1369 Tj
+-293 TJm
+(sizes.) 21.8579 Tj
+-881 TJm
+(Also) 18.8194 Tj
+-293 TJm
+(recorded) 34.8492 Tj
+-294 TJm
+(is) 6.64505 Tj
+-293 TJm
+(the) 12.1743 Tj
+-294 TJm
+(total) 17.7135 Tj
+72 652.254 Td
+(compressed) 47.0334 Tj
+-289 TJm
+(size) 15.4918 Tj
+-289 TJm
+(for) 11.6164 Tj
+-289 TJm
+(14) 9.9626 Tj
+-289 TJm
+(\002les) 16.6077 Tj
+-290 TJm
+(of) 8.29885 Tj
+-289 TJm
+(the) 12.1743 Tj
+-289 TJm
+(Calg) 18.8194 Tj
+5 TJm
+(ary) 12.7222 Tj
+-289 TJm
+(T) 6.08715 Tj
+70 TJm
+(e) 4.42339 Tj
+15 TJm
+(xt) 7.7509 Tj
+-289 TJm
+(Compression) 52.5826 Tj
+-289 TJm
+(Corpus) 28.782 Tj
+-289 TJm
+(totalling) 33.2153 Tj
+-289 TJm
+(3,141,622) 39.8504 Tj
+-290 TJm
+(bytes.) 23.5217 Tj
+-854 TJm
+(This) 17.7135 Tj
+-290 TJm
+(column) 29.8878 Tj
+-289 TJm
+(gi) 7.7509 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(es) 8.29885 Tj
+72 640.299 Td
+(some) 21.031 Tj
+-253 TJm
+(feel) 14.9339 Tj
+-253 TJm
+(for) 11.6164 Tj
+-253 TJm
+(ho) 9.9626 Tj
+25 TJm
+(w) 7.193 Tj
+-253 TJm
+(compression) 50.3609 Tj
+-253 TJm
+(v) 4.9813 Tj
+25 TJm
+(aries) 18.8094 Tj
+-253 TJm
+(with) 17.7135 Tj
+-253 TJm
+(block) 22.1369 Tj
+-253 TJm
+(size.) 17.9825 Tj
+-638 TJm
+(These) 23.7907 Tj
+-253 TJm
+(\002gures) 27.1182 Tj
+-253 TJm
+(tend) 17.1556 Tj
+-254 TJm
+(to) 7.7509 Tj
+-253 TJm
+(understate) 40.9463 Tj
+-253 TJm
+(the) 12.1743 Tj
+-253 TJm
+(adv) 14.386 Tj
+25 TJm
+(antage) 26.0024 Tj
+-253 TJm
+(of) 8.29885 Tj
+-253 TJm
+(lar) 10.5105 Tj
+18 TJm
+(ger) 12.7222 Tj
+-253 TJm
+(block) 22.1369 Tj
+72 628.344 Td
+(sizes) 19.3673 Tj
+-250 TJm
+(for) 11.6164 Tj
+-250 TJm
+(lar) 10.5105 Tj
+18 TJm
+(ger) 12.7222 Tj
+-250 TJm
+(\002les,) 19.0983 Tj
+-250 TJm
+(since) 20.4731 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(Corpus) 28.782 Tj
+-250 TJm
+(is) 6.64505 Tj
+-250 TJm
+(dominated) 42.0621 Tj
+-250 TJm
+(by) 9.9626 Tj
+-250 TJm
+(smaller) 29.3299 Tj
+-250 TJm
+(\002les.) 19.0983 Tj
+[1 0 0 1 72 626.187] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -156.413] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 155.417 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5865] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 151.831] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -616.822] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+123.952 616.822 Td
+/F134_0 9.9626 Tf
+(Compress) 47.8205 Tj
+-1278 TJm
+(Decompress) 59.7756 Tj
+-1278 TJm
+(Decompress) 59.7756 Tj
+-1278 TJm
+(Corpus) 35.8654 Tj
+90 604.867 Td
+(Flag) 23.9102 Tj
+-2130 TJm
+(usage) 29.8878 Tj
+-2556 TJm
+(usage) 29.8878 Tj
+-2982 TJm
+(-s) 11.9551 Tj
+-426 TJm
+(usage) 29.8878 Tj
+-2130 TJm
+(Size) 23.9102 Tj
+94.244 580.956 Td
+(-1) 11.9551 Tj
+-2556 TJm
+(1200k) 29.8878 Tj
+-2982 TJm
+(500k) 23.9102 Tj
+-3834 TJm
+(350k) 23.9102 Tj
+-2556 TJm
+(914704) 35.8654 Tj
+94.244 569.001 Td
+(-2) 11.9551 Tj
+-2556 TJm
+(2000k) 29.8878 Tj
+-2982 TJm
+(900k) 23.9102 Tj
+-3834 TJm
+(600k) 23.9102 Tj
+-2556 TJm
+(877703) 35.8654 Tj
+94.244 557.046 Td
+(-3) 11.9551 Tj
+-2556 TJm
+(2800k) 29.8878 Tj
+-2556 TJm
+(1300k) 29.8878 Tj
+-3834 TJm
+(850k) 23.9102 Tj
+-2556 TJm
+(860338) 35.8654 Tj
+94.244 545.091 Td
+(-4) 11.9551 Tj
+-2556 TJm
+(3600k) 29.8878 Tj
+-2556 TJm
+(1700k) 29.8878 Tj
+-3408 TJm
+(1100k) 29.8878 Tj
+-2556 TJm
+(846899) 35.8654 Tj
+94.244 533.136 Td
+(-5) 11.9551 Tj
+-2556 TJm
+(4400k) 29.8878 Tj
+-2556 TJm
+(2100k) 29.8878 Tj
+-3408 TJm
+(1350k) 29.8878 Tj
+-2556 TJm
+(845160) 35.8654 Tj
+94.244 521.181 Td
+(-6) 11.9551 Tj
+-2556 TJm
+(5200k) 29.8878 Tj
+-2556 TJm
+(2500k) 29.8878 Tj
+-3408 TJm
+(1600k) 29.8878 Tj
+-2556 TJm
+(838626) 35.8654 Tj
+94.244 509.225 Td
+(-7) 11.9551 Tj
+-2556 TJm
+(6100k) 29.8878 Tj
+-2556 TJm
+(2900k) 29.8878 Tj
+-3408 TJm
+(1850k) 29.8878 Tj
+-2556 TJm
+(834096) 35.8654 Tj
+94.244 497.27 Td
+(-8) 11.9551 Tj
+-2556 TJm
+(6800k) 29.8878 Tj
+-2556 TJm
+(3300k) 29.8878 Tj
+-3408 TJm
+(2100k) 29.8878 Tj
+-2556 TJm
+(828642) 35.8654 Tj
+94.244 485.315 Td
+(-9) 11.9551 Tj
+-2556 TJm
+(7600k) 29.8878 Tj
+-2556 TJm
+(3700k) 29.8878 Tj
+-3408 TJm
+(2350k) 29.8878 Tj
+-2556 TJm
+(828642) 35.8654 Tj
+[1 0 0 1 72 469.773] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -3.5866] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -459.811] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 435.021 Td
+/F122_0 20.6585 Tf
+(2.6.) 34.4584 Tj
+-278 TJm
+(RECO) 59.6824 Tj
+50 TJm
+(VERING) 79.2047 Tj
+-278 TJm
+(D) 14.9154 Tj
+40 TJm
+(A) 14.9154 Tj
+90 TJm
+(T) 12.6223 Tj
+90 TJm
+(A) 14.9154 Tj
+-278 TJm
+(FR) 27.5378 Tj
+20 TJm
+(OM) 33.2808 Tj
+-278 TJm
+(D) 14.9154 Tj
+40 TJm
+(AMA) 47.0394 Tj
+50 TJm
+(GED) 44.767 Tj
+72 410.23 Td
+(FILES) 58.5462 Tj
+[1 0 0 1 72 409.972] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -400.01] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 388.312 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 101.888 388.312] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -101.888 -388.312] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+105.138 388.312 Td
+/F130_0 9.9626 Tf
+(compresses) 45.9276 Tj
+-326 TJm
+(\002les) 16.6077 Tj
+-326 TJm
+(in) 7.7509 Tj
+-326 TJm
+(blocks,) 28.503 Tj
+-346 TJm
+(usually) 28.782 Tj
+-326 TJm
+(900kbytes) 40.9562 Tj
+-326 TJm
+(long.) 20.2042 Tj
+-1077 TJm
+(Each) 19.9152 Tj
+-326 TJm
+(block) 22.1369 Tj
+-327 TJm
+(is) 6.64505 Tj
+-326 TJm
+(handled) 31.5416 Tj
+-326 TJm
+(independently) 56.4481 Tj
+65 TJm
+(.) 2.49065 Tj
+-1077 TJm
+(If) 6.63509 Tj
+-326 TJm
+(a) 4.42339 Tj
+-326 TJm
+(media) 24.3486 Tj
+-326 TJm
+(or) 8.29885 Tj
+72 376.357 Td
+(transmission) 50.3709 Tj
+-319 TJm
+(error) 19.3573 Tj
+-318 TJm
+(causes) 26.0024 Tj
+-319 TJm
+(a) 4.42339 Tj
+-318 TJm
+(multi-block) 46.4955 Tj
+[1 0 0 1 234.518 376.357] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -234.518 -376.357] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+234.518 376.357 Td
+/F134_0 9.9626 Tf
+(.bz2) 23.9102 Tj
+[1 0 0 1 258.429 376.357] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -258.429 -376.357] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+261.603 376.357 Td
+/F130_0 9.9626 Tf
+(\002le) 12.7322 Tj
+-319 TJm
+(to) 7.7509 Tj
+-318 TJm
+(become) 30.9837 Tj
+-319 TJm
+(damaged,) 38.4556 Tj
+-336 TJm
+(it) 5.53921 Tj
+-318 TJm
+(may) 17.1556 Tj
+-319 TJm
+(be) 9.40469 Tj
+-318 TJm
+(possible) 32.6574 Tj
+-319 TJm
+(to) 7.7509 Tj
+-318 TJm
+(reco) 17.1456 Tj
+15 TJm
+(v) 4.9813 Tj
+15 TJm
+(er) 7.74094 Tj
+-319 TJm
+(data) 16.5977 Tj
+-319 TJm
+(from) 19.3673 Tj
+-318 TJm
+(the) 12.1743 Tj
+72 364.402 Td
+(undamaged) 45.9276 Tj
+-250 TJm
+(blocks) 26.0123 Tj
+-250 TJm
+(in) 7.7509 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(\002le.) 15.2229 Tj
+[1 0 0 1 72 362.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -352.283] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 342.484 Td
+/F130_0 9.9626 Tf
+(The) 15.4918 Tj
+-358 TJm
+(compressed) 47.0334 Tj
+-357 TJm
+(representation) 56.4381 Tj
+-358 TJm
+(of) 8.29885 Tj
+-357 TJm
+(each) 18.2515 Tj
+-358 TJm
+(block) 22.1369 Tj
+-358 TJm
+(is) 6.64505 Tj
+-357 TJm
+(delimited) 37.6387 Tj
+-358 TJm
+(by) 9.9626 Tj
+-357 TJm
+(a) 4.42339 Tj
+-358 TJm
+(48-bit) 23.8007 Tj
+-358 TJm
+(pattern,) 30.1568 Tj
+-384 TJm
+(which) 24.3486 Tj
+-358 TJm
+(mak) 17.1556 Tj
+10 TJm
+(es) 8.29885 Tj
+-357 TJm
+(it) 5.53921 Tj
+-358 TJm
+(possible) 32.6574 Tj
+-357 TJm
+(to) 7.7509 Tj
+-358 TJm
+(\002nd) 15.5018 Tj
+-358 TJm
+(the) 12.1743 Tj
+72 330.529 Td
+(block) 22.1369 Tj
+-286 TJm
+(boundaries) 43.7159 Tj
+-286 TJm
+(wit) 12.7322 Tj
+1 TJm
+(h) 4.9813 Tj
+-286 TJm
+(reasonable) 42.6001 Tj
+-286 TJm
+(certainty) 34.8591 Tj
+65 TJm
+(.) 2.49065 Tj
+-835 TJm
+(Each) 19.9152 Tj
+-285 TJm
+(block) 22.1369 Tj
+-286 TJm
+(also) 16.0497 Tj
+-286 TJm
+(carries) 26.5503 Tj
+-286 TJm
+(its) 9.41466 Tj
+-285 TJm
+(o) 4.9813 Tj
+25 TJm
+(wn) 12.1743 Tj
+-286 TJm
+(32-bit) 23.8007 Tj
+-286 TJm
+(CRC,) 22.4258 Tj
+-286 TJm
+(so) 8.85675 Tj
+-285 TJm
+(damaged) 35.965 Tj
+-286 TJm
+(blocks) 26.0123 Tj
+-286 TJm
+(can) 13.8281 Tj
+-286 TJm
+(be) 9.40469 Tj
+72 318.574 Td
+(distinguished) 53.1405 Tj
+-250 TJm
+(from) 19.3673 Tj
+-250 TJm
+(undamaged) 45.9276 Tj
+-250 TJm
+(ones.) 20.7521 Tj
+[1 0 0 1 72 316.417] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -306.455] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 296.656 Td
+/F134_0 9.9626 Tf
+(bzip2recover) 71.7307 Tj
+[1 0 0 1 143.731 296.656] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -143.731 -296.656] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+146.448 296.656 Td
+/F130_0 9.9626 Tf
+(is) 6.64505 Tj
+-273 TJm
+(a) 4.42339 Tj
+-272 TJm
+(simple) 26.5703 Tj
+-273 TJm
+(program) 33.7533 Tj
+-273 TJm
+(whose) 25.4544 Tj
+-272 TJm
+(purpose) 31.5416 Tj
+-273 TJm
+(is) 6.64505 Tj
+-273 TJm
+(to) 7.7509 Tj
+-272 TJm
+(search) 25.4445 Tj
+-273 TJm
+(for) 11.6164 Tj
+-273 TJm
+(blocks) 26.0123 Tj
+-272 TJm
+(in) 7.7509 Tj
+[1 0 0 1 392.655 296.656] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -392.655 -296.656] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+392.655 296.656 Td
+/F134_0 9.9626 Tf
+(.bz2) 23.9102 Tj
+[1 0 0 1 416.566 296.656] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -416.566 -296.656] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+419.282 296.656 Td
+/F130_0 9.9626 Tf
+(\002les,) 19.0983 Tj
+-278 TJm
+(and) 14.386 Tj
+-273 TJm
+(write) 20.4731 Tj
+-273 TJm
+(each) 18.2515 Tj
+-272 TJm
+(block) 22.1369 Tj
+-273 TJm
+(out) 12.7322 Tj
+72 284.701 Td
+(into) 15.5018 Tj
+-254 TJm
+(its) 9.41466 Tj
+-255 TJm
+(o) 4.9813 Tj
+25 TJm
+(wn) 12.1743 Tj
+[1 0 0 1 121.43 284.701] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -121.43 -284.701] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+121.43 284.701 Td
+/F134_0 9.9626 Tf
+(.bz2) 23.9102 Tj
+[1 0 0 1 145.34 284.701] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -145.34 -284.701] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+147.875 284.701 Td
+/F130_0 9.9626 Tf
+(\002le.) 15.2229 Tj
+-647 TJm
+(Y) 7.193 Tj
+110 TJm
+(ou) 9.9626 Tj
+-255 TJm
+(can) 13.8281 Tj
+-254 TJm
+(then) 17.1556 Tj
+-255 TJm
+(use) 13.2801 Tj
+[1 0 0 1 240.01 284.701] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -240.01 -284.701] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+240.01 284.701 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+-600 TJm
+(-t) 11.9551 Tj
+[1 0 0 1 287.831 284.701] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -287.831 -284.701] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+290.367 284.701 Td
+/F130_0 9.9626 Tf
+(to) 7.7509 Tj
+-255 TJm
+(t) 2.7696 Tj
+1 TJm
+(est) 11.0684 Tj
+-255 TJm
+(the) 12.1743 Tj
+-254 TJm
+(inte) 14.9439 Tj
+15 TJm
+(grity) 18.8194 Tj
+-255 TJm
+(of) 8.29885 Tj
+-254 TJm
+(the) 12.1743 Tj
+-255 TJm
+(resulting) 34.8691 Tj
+-254 TJm
+(\002les,) 19.0983 Tj
+-256 TJm
+(and) 14.386 Tj
+-255 TJm
+(decompress) 47.0334 Tj
+-254 TJm
+(those) 21.031 Tj
+72 272.746 Td
+(which) 24.3486 Tj
+-250 TJm
+(are) 12.1643 Tj
+-250 TJm
+(undamaged.) 48.4182 Tj
+[1 0 0 1 72 270.589] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -260.626] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 250.828 Td
+/F134_0 9.9626 Tf
+(bzip2recover) 71.7307 Tj
+[1 0 0 1 143.731 250.828] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -143.731 -250.828] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+150.099 250.828 Td
+/F130_0 9.9626 Tf
+(tak) 12.1743 Tj
+10 TJm
+(es) 8.29885 Tj
+-639 TJm
+(a) 4.42339 Tj
+-639 TJm
+(single) 23.8007 Tj
+-639 TJm
+(ar) 7.74094 Tj
+18 TJm
+(gument,) 32.3785 Tj
+-737 TJm
+(the) 12.1743 Tj
+-639 TJm
+(name) 21.579 Tj
+-639 TJm
+(of) 8.29885 Tj
+-639 TJm
+(the) 12.1743 Tj
+-639 TJm
+(damaged) 35.965 Tj
+-639 TJm
+(\002le,) 15.2229 Tj
+-737 TJm
+(and) 14.386 Tj
+-639 TJm
+(writes) 24.3486 Tj
+-639 TJm
+(a) 4.42339 Tj
+-639 TJm
+(number) 30.4357 Tj
+-639 TJm
+(of) 8.29885 Tj
+-640 TJm
+(\002les) 16.6077 Tj
+[1 0 0 1 72 238.873] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -238.873] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 238.873 Td
+/F134_0 9.9626 Tf
+(rec0001file.bz2) 89.6634 Tj
+[1 0 0 1 161.664 238.873] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -161.664 -238.873] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+161.664 238.873 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 169.072 238.873] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -169.072 -238.873] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+169.072 238.873 Td
+/F134_0 9.9626 Tf
+(rec0002file.bz2) 89.6634 Tj
+[1 0 0 1 258.736 238.873] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -258.736 -238.873] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+258.736 238.873 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-494 TJm
+(etc,) 14.107 Tj
+-493 TJm
+(containing) 42.0621 Tj
+-445 TJm
+(the) 12.1743 Tj
+-445 TJm
+(e) 4.42339 Tj
+15 TJm
+(xtracted) 32.0895 Tj
+-445 TJm
+(blocks.) 28.503 Tj
+-1789 TJm
+(The) 15.4918 Tj
+-445 TJm
+(output) 25.4644 Tj
+-445 TJm
+(\002lenames) 38.1866 Tj
+-445 TJm
+(are) 12.1643 Tj
+72 226.918 Td
+(designed) 35.417 Tj
+-337 TJm
+(so) 8.85675 Tj
+-337 TJm
+(that) 14.9439 Tj
+-337 TJm
+(the) 12.1743 Tj
+-337 TJm
+(use) 13.2801 Tj
+-337 TJm
+(of) 8.29885 Tj
+-337 TJm
+(wildc) 22.1369 Tj
+1 TJm
+(ards) 16.5977 Tj
+-337 TJm
+(in) 7.7509 Tj
+-337 TJm
+(subsequent) 44.2738 Tj
+-337 TJm
+(processing) 42.61 Tj
+-337 TJm
+(--) 6.63509 Tj
+-337 TJm
+(for) 11.6164 Tj
+-337 TJm
+(e) 4.42339 Tj
+15 TJm
+(xample,) 31.8205 Tj
+[1 0 0 1 396.538 226.918] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -396.538 -226.918] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+396.538 226.918 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+-600 TJm
+(-dc) 17.9327 Tj
+-600 TJm
+(rec) 17.9327 Tj
+474.247 225.174 Td
+(*) 5.97756 Tj
+480.224 226.918 Td
+(file.bz2) 47.8205 Tj
+-600 TJm
+(>) 5.97756 Tj
+72 214.963 Td
+(recovered_data) 83.6858 Tj
+[1 0 0 1 155.686 214.963] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -155.686 -214.963] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+158.177 214.963 Td
+/F130_0 9.9626 Tf
+(--) 6.63509 Tj
+-250 TJm
+(lists) 16.0597 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(\002les) 16.6077 Tj
+-250 TJm
+(in) 7.7509 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(correct) 27.6562 Tj
+-250 TJm
+(order) 21.0211 Tj
+55 TJm
+(.) 2.49065 Tj
+[1 0 0 1 72 213.653] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -203.69] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 193.045 Td
+/F134_0 9.9626 Tf
+(bzip2recover) 71.7307 Tj
+[1 0 0 1 143.731 193.045] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -143.731 -193.045] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+145.93 193.045 Td
+/F130_0 9.9626 Tf
+(should) 26.5703 Tj
+-221 TJm
+(be) 9.40469 Tj
+-220 TJm
+(of) 8.29885 Tj
+-221 TJm
+(most) 19.3773 Tj
+-221 TJm
+(use) 13.2801 Tj
+-220 TJm
+(dealing) 29.3299 Tj
+-221 TJm
+(with) 17.7135 Tj
+-221 TJm
+(lar) 10.5105 Tj
+18 TJm
+(ge) 9.40469 Tj
+[1 0 0 1 307.229 193.045] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -307.229 -193.045] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+307.229 193.045 Td
+/F134_0 9.9626 Tf
+(.bz2) 23.9102 Tj
+[1 0 0 1 331.14 193.045] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -331.14 -193.045] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+333.338 193.045 Td
+/F130_0 9.9626 Tf
+(\002les,) 19.0983 Tj
+-227 TJm
+(as) 8.29885 Tj
+-220 TJm
+(these) 20.4731 Tj
+-221 TJm
+(will) 15.5018 Tj
+-221 TJm
+(contain) 29.3299 Tj
+-220 TJm
+(man) 17.1556 Tj
+15 TJm
+(y) 4.9813 Tj
+-221 TJm
+(blocks.) 28.503 Tj
+-600 TJm
+(It) 6.08715 Tj
+-221 TJm
+(is) 6.64505 Tj
+-221 TJm
+(clearly) 27.1082 Tj
+72 181.09 Td
+(futile) 21.031 Tj
+-289 TJm
+(to) 7.7509 Tj
+-289 TJm
+(use) 13.2801 Tj
+-289 TJm
+(it) 5.53921 Tj
+-289 TJm
+(on) 9.9626 Tj
+-289 TJm
+(damaged) 35.965 Tj
+-289 TJm
+(single-block) 49.2551 Tj
+-290 TJm
+(\002les) 16.6077 Tj
+1 TJm
+(,) 2.49065 Tj
+-299 TJm
+(since) 20.4731 Tj
+-289 TJm
+(a) 4.42339 Tj
+-290 TJm
+(damaged) 35.965 Tj
+-289 TJm
+(block) 22.1369 Tj
+-289 TJm
+(cannot) 26.5603 Tj
+-289 TJm
+(be) 9.40469 Tj
+-289 TJm
+(reco) 17.1456 Tj
+15 TJm
+(v) 4.9813 Tj
+15 TJm
+(ered.) 19.6363 Tj
+-854 TJm
+(If) 6.63509 Tj
+-289 TJm
+(you) 14.9439 Tj
+-290 TJm
+(wish) 18.8194 Tj
+-289 TJm
+(to) 7.7509 Tj
+-289 TJm
+(minimise) 37.0908 Tj
+72 169.135 Td
+(an) 9.40469 Tj
+15 TJm
+(y) 4.9813 Tj
+-320 TJm
+(potential) 34.8691 Tj
+-320 TJm
+(data) 16.5977 Tj
+-319 TJm
+(loss) 15.5018 Tj
+-320 TJm
+(through) 30.9936 Tj
+-320 TJm
+(media) 24.3486 Tj
+-320 TJm
+(or) 8.29885 Tj
+-319 TJm
+(transmission) 50.3709 Tj
+-320 TJm
+(errors,) 25.7234 Tj
+-337 TJm
+(you) 14.9439 Tj
+-320 TJm
+(might) 23.2527 Tj
+-320 TJm
+(consider) 33.7533 Tj
+-320 TJm
+(compressing) 50.3609 Tj
+-319 TJm
+(with) 17.7135 Tj
+-320 TJm
+(a) 4.42339 Tj
+-320 TJm
+(smaller) 29.3299 Tj
+-320 TJm
+(block) 22.1369 Tj
+72 157.179 Td
+(size.) 17.9825 Tj
+[1 0 0 1 72 157.08] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -147.117] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 122.426 Td
+/F122_0 20.6585 Tf
+(2.7.) 34.4584 Tj
+-278 TJm
+(PERFORMANCE) 161.818 Tj
+-278 TJm
+(NO) 30.9877 Tj
+40 TJm
+(TES) 40.1808 Tj
+[1 0 0 1 72 122.168] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -112.206] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 100.509 Td
+/F130_0 9.9626 Tf
+(The) 15.4918 Tj
+-305 TJm
+(sorting) 27.6761 Tj
+-304 TJm
+(phase) 22.6848 Tj
+-305 TJm
+(of) 8.29885 Tj
+-304 TJm
+(compression) 50.3609 Tj
+-305 TJm
+(g) 4.9813 Tj
+5 TJm
+(athers) 23.7907 Tj
+-304 TJm
+(together) 32.6474 Tj
+-305 TJm
+(similar) 27.6761 Tj
+-304 TJm
+(strings) 26.5703 Tj
+-305 TJm
+(in) 7.7509 Tj
+-304 TJm
+(the) 12.1743 Tj
+-305 TJm
+(\002le.) 15.2229 Tj
+-947 TJm
+(Because) 33.1954 Tj
+-305 TJm
+(of) 8.29885 Tj
+-304 TJm
+(this,) 16.8866 Tj
+-319 TJm
+(\002les) 16.6077 Tj
+-304 TJm
+(containing) 42.0621 Tj
+-305 TJm
+(v) 4.9813 Tj
+15 TJm
+(ery) 12.7222 Tj
+72 88.5534 Td
+(long) 17.7135 Tj
+-286 TJm
+(runs) 17.1556 Tj
+-285 TJm
+(of) 8.29885 Tj
+-286 TJm
+(repeated) 33.7433 Tj
+-285 TJm
+(symbols,) 35.706 Tj
+-295 TJm
+(lik) 10.5205 Tj
+10 TJm
+(e) 4.42339 Tj
+-286 TJm
+("aabaabaabaab) 59.3771 Tj
+-285 TJm
+(...") 11.5367 Tj
+-571 TJm
+(\(repeated) 37.0609 Tj
+-286 TJm
+(se) 8.29885 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(eral) 14.9339 Tj
+-286 TJm
+(hundred) 32.6474 Tj
+-285 TJm
+(times\)) 24.9065 Tj
+-286 TJm
+(may) 17.1556 Tj
+-286 TJm
+(com) 17.1556 Tj
+1 TJm
+(press) 20.4731 Tj
+-286 TJm
+(more) 20.4731 Tj
+-286 TJm
+(slo) 11.6264 Tj
+25 TJm
+(wly) 14.9439 Tj
+72 76.5983 Td
+(than) 17.1556 Tj
+-322 TJm
+(normal.) 30.7147 Tj
+-524 TJm
+(V) 7.193 Tj
+111 TJm
+(ersions) 28.224 Tj
+-322 TJm
+(0.9.5) 19.9252 Tj
+-321 TJm
+(and) 14.386 Tj
+-322 TJm
+(abo) 14.386 Tj
+15 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-322 TJm
+(f) 3.31755 Tj
+10 TJm
+(are) 12.1643 Tj
+-321 TJm
+(much) 22.1369 Tj
+-322 TJm
+(better) 22.6848 Tj
+-321 TJm
+(than) 17.1556 Tj
+-322 TJm
+(pre) 12.7222 Tj
+25 TJm
+(vious) 21.589 Tj
+-321 TJm
+(v) 4.9813 Tj
+15 TJm
+(ersions) 28.224 Tj
+-322 TJm
+(in) 7.7509 Tj
+-322 TJm
+(this) 14.396 Tj
+-321 TJm
+(respect.) 30.7047 Tj
+-1050 TJm
+(The) 15.4918 Tj
+-321 TJm
+(ratio) 18.2614 Tj
+-322 TJm
+(between) 33.1954 Tj
+[1 0 0 1 72 50.8518] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 374.394 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 6.8541] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 43.0633 -6.7545] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -496.332 -50.9514] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+539.395 50.9514 Td
+/F130_0 9.9626 Tf
+(6) 4.9813 Tj
+[1 0 0 1 453.269 50.8518] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 93.5985 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.2765 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+Q
+showpage
+%%PageTrailer
+pdfEndPage
+%%Page: 10 10
+%%BeginPageSetup
+%%PageOrientation: Portrait
+pdfStartPage
+0 0 612 792 re W
+%%EndPageSetup
+[] 0 d
+1 i
+0 j
+0 J
+10 M
+1 w
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+false op
+false OP
+0 0 612 792 re
+W
+q
+[1 0 0 1 72 741.554] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 14.4459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 187.197 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 -8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 105.519 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -371.59 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+477.109 749.245 Td
+/F130_0 9.9626 Tf
+(Ho) 12.1743 Tj
+25 TJm
+(w) 7.193 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(use) 13.2801 Tj
+-250 TJm
+(bzip2) 22.1369 Tj
+[1 0 0 1 266.071 747.089] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 280.796 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -472.974 -5.0363] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -0.4981] cm
+q
+[] 0 d
+0 J
+0.4981 w
+0 0.2491 m
+475.465 0.2491 l
+S
+Q
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 479.251 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -540 -741.554] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 710.037 Td
+/F130_0 9.9626 Tf
+(w) 7.193 Tj
+10 TJm
+(orst-case) 35.4071 Tj
+-289 TJm
+(and) 14.386 Tj
+-290 TJm
+(a) 4.42339 Tj
+20 TJm
+(v) 4.9813 Tj
+15 TJm
+(erage-case) 42.0322 Tj
+-289 TJm
+(compression) 50.3609 Tj
+-290 TJm
+(time) 17.7135 Tj
+-289 TJm
+(is) 6.64505 Tj
+-290 TJm
+(in) 7.7509 Tj
+-289 TJm
+(the) 12.1743 Tj
+-290 TJm
+(re) 7.74094 Tj
+15 TJm
+(gion) 17.7135 Tj
+-289 TJm
+(of) 8.29885 Tj
+-289 TJm
+(10:1.) 20.2042 Tj
+-857 TJm
+(F) 5.53921 Tj
+15 TJm
+(or) 8.29885 Tj
+-290 TJm
+(pre) 12.7222 Tj
+25 TJm
+(vious) 21.589 Tj
+-289 TJm
+(v) 4.9813 Tj
+15 TJm
+(ersions,) 30.7147 Tj
+-299 TJm
+(this) 14.396 Tj
+-290 TJm
+(\002gure) 23.2427 Tj
+-289 TJm
+(w) 7.193 Tj
+10 TJm
+(as) 8.29885 Tj
+-290 TJm
+(more) 20.4731 Tj
+72 698.082 Td
+(lik) 10.5205 Tj
+10 TJm
+(e) 4.42339 Tj
+-250 TJm
+(100:1.) 25.1855 Tj
+-620 TJm
+(Y) 7.193 Tj
+110 TJm
+(ou) 9.9626 Tj
+-250 TJm
+(can) 13.8281 Tj
+-250 TJm
+(use) 13.2801 Tj
+-250 TJm
+(the) 12.1743 Tj
+[1 0 0 1 186.002 698.082] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -186.002 -698.082] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+186.002 698.082 Td
+/F134_0 9.9626 Tf
+(-vvvv) 29.8878 Tj
+[1 0 0 1 215.889 698.082] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -215.889 -698.082] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+218.38 698.082 Td
+/F130_0 9.9626 Tf
+(option) 25.4644 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(monitor) 31.5516 Tj
+-250 TJm
+(progress) 33.7533 Tj
+-250 TJm
+(in) 7.7509 Tj
+-250 TJm
+(great) 19.9152 Tj
+-250 TJm
+(detail,) 24.6275 Tj
+-250 TJm
+(if) 6.08715 Tj
+-250 TJm
+(you) 14.9439 Tj
+-250 TJm
+(w) 7.193 Tj
+10 TJm
+(ant.) 14.6649 Tj
+[1 0 0 1 72 695.925] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -685.963] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 676.164 Td
+/F130_0 9.9626 Tf
+(Decompression) 61.9773 Tj
+-250 TJm
+(speed) 22.6848 Tj
+-250 TJm
+(is) 6.64505 Tj
+-250 TJm
+(unaf) 17.7035 Tj
+25 TJm
+(fected) 24.3386 Tj
+-250 TJm
+(by) 9.9626 Tj
+-250 TJm
+(these) 20.4731 Tj
+-250 TJm
+(phenomena.) 48.4182 Tj
+[1 0 0 1 72 674.007] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -664.045] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 654.247 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 101.888 654.247] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -101.888 -654.247] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+104.863 654.247 Td
+/F130_0 9.9626 Tf
+(usually) 28.782 Tj
+-299 TJm
+(allocates) 34.8591 Tj
+-298 TJm
+(se) 8.29885 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(eral) 14.9339 Tj
+-299 TJm
+(me) 12.1743 Tj
+15 TJm
+(g) 4.9813 Tj
+5 TJm
+(abytes) 25.4544 Tj
+-298 TJm
+(of) 8.29885 Tj
+-299 TJm
+(memory) 33.2053 Tj
+-299 TJm
+(to) 7.7509 Tj
+-298 TJm
+(operate) 29.3199 Tj
+-299 TJm
+(in,) 10.2416 Tj
+-311 TJm
+(and) 14.386 Tj
+-298 TJm
+(then) 17.1556 Tj
+-299 TJm
+(char) 17.1456 Tj
+18 TJm
+(ges) 13.2801 Tj
+-298 TJm
+(all) 9.9626 Tj
+-299 TJm
+(o) 4.9813 Tj
+15 TJm
+(v) 4.9813 Tj
+15 TJm
+(er) 7.74094 Tj
+-299 TJm
+(it) 5.53921 Tj
+-298 TJm
+(in) 7.7509 Tj
+-299 TJm
+(a) 4.42339 Tj
+-298 TJm
+(f) 3.31755 Tj
+10 TJm
+(airly) 18.2614 Tj
+-299 TJm
+(random) 30.4357 Tj
+72 642.291 Td
+(f) 3.31755 Tj
+10 TJm
+(ashion.) 28.503 Tj
+-743 TJm
+(This) 17.7135 Tj
+-270 TJm
+(means) 25.4544 Tj
+-271 TJm
+(that) 14.9439 Tj
+-270 TJm
+(performance,) 52.8317 Tj
+-276 TJm
+(both) 17.7135 Tj
+-270 TJm
+(for) 11.6164 Tj
+-271 TJm
+(compressing) 50.3609 Tj
+-270 TJm
+(and) 14.386 Tj
+-271 TJm
+(decompressing,) 62.2563 Tj
+-275 TJm
+(is) 6.64505 Tj
+-271 TJm
+(lar) 10.5105 Tj
+18 TJm
+(gely) 17.1556 Tj
+-270 TJm
+(determined) 44.8217 Tj
+-271 TJm
+(by) 9.9626 Tj
+-270 TJm
+(the) 12.1743 Tj
+-271 TJm
+(speed) 22.6848 Tj
+72 630.336 Td
+(at) 7.193 Tj
+-294 TJm
+(which) 24.3486 Tj
+-294 TJm
+(your) 18.2614 Tj
+-294 TJm
+(machine) 33.7533 Tj
+-295 TJm
+(ca) 8.84679 Tj
+1 TJm
+(n) 4.9813 Tj
+-295 TJm
+(service) 28.2141 Tj
+-294 TJm
+(cache) 22.6749 Tj
+-294 TJm
+(misses.) 29.0609 Tj
+-442 TJm
+(Because) 33.1954 Tj
+-294 TJm
+(of) 8.29885 Tj
+-294 TJm
+(this,) 16.8866 Tj
+-306 TJm
+(small) 21.589 Tj
+-294 TJm
+(changes) 32.0895 Tj
+-294 TJm
+(to) 7.7509 Tj
+-294 TJm
+(the) 12.1743 Tj
+-294 TJm
+(code) 18.8094 Tj
+-294 TJm
+(to) 7.7509 Tj
+-294 TJm
+(reduce) 26.5503 Tj
+-294 TJm
+(the) 12.1743 Tj
+-295 TJm
+(miss) 18.2714 Tj
+-294 TJm
+(rate) 14.9339 Tj
+72 618.381 Td
+(ha) 9.40469 Tj
+20 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-253 TJm
+(been) 18.8094 Tj
+-253 TJm
+(observ) 26.5603 Tj
+15 TJm
+(ed) 9.40469 Tj
+-253 TJm
+(to) 7.7509 Tj
+-253 TJm
+(gi) 7.7509 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-253 TJm
+(disproportionately) 73.0557 Tj
+-253 TJm
+(lar) 10.5105 Tj
+18 TJm
+(ge) 9.40469 Tj
+-253 TJm
+(performance) 50.341 Tj
+-253 TJm
+(impro) 23.8007 Tj
+15 TJm
+(v) 4.9813 Tj
+15 TJm
+(ements.) 30.7147 Tj
+-639 TJm
+(I) 3.31755 Tj
+-253 TJm
+(imagine) 32.0995 Tj
+[1 0 0 1 438.909 618.381] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -438.909 -618.381] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+438.909 618.381 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 468.796 618.381] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468.796 -618.381] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+471.318 618.381 Td
+/F130_0 9.9626 Tf
+(will) 15.5018 Tj
+-253 TJm
+(perform) 32.0895 Tj
+-253 TJm
+(best) 16.0497 Tj
+72 606.426 Td
+(on) 9.9626 Tj
+-250 TJm
+(machines) 37.6287 Tj
+-250 TJm
+(with) 17.7135 Tj
+-250 TJm
+(v) 4.9813 Tj
+15 TJm
+(ery) 12.7222 Tj
+-250 TJm
+(lar) 10.5105 Tj
+18 TJm
+(ge) 9.40469 Tj
+-250 TJm
+(caches.) 29.041 Tj
+[1 0 0 1 72 604.269] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -594.306] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 571.673 Td
+/F122_0 20.6585 Tf
+(2.8.) 34.4584 Tj
+-278 TJm
+(CA) 29.8309 Tj
+80 TJm
+(VEA) 42.4739 Tj
+90 TJm
+(TS) 26.4016 Tj
+[1 0 0 1 72 571.415] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -561.452] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 549.755 Td
+/F130_0 9.9626 Tf
+(I/O) 13.2801 Tj
+-268 TJm
+(error) 19.3573 Tj
+-267 TJm
+(messages) 37.6287 Tj
+-268 TJm
+(are) 12.1643 Tj
+-268 TJm
+(not) 12.7322 Tj
+-268 TJm
+(as) 8.29885 Tj
+-267 TJm
+(helpful) 28.224 Tj
+-268 TJm
+(as) 8.29885 Tj
+-268 TJm
+(the) 12.1743 Tj
+15 TJm
+(y) 4.9813 Tj
+-267 TJm
+(could) 22.1369 Tj
+-268 TJm
+(be.) 11.8953 Tj
+[1 0 0 1 293.313 549.755] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -293.313 -549.755] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+293.313 549.755 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 323.201 549.755] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -323.201 -549.755] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+325.868 549.755 Td
+/F130_0 9.9626 Tf
+(tries) 17.1556 Tj
+-268 TJm
+(hard) 17.7035 Tj
+-267 TJm
+(to) 7.7509 Tj
+-268 TJm
+(detect) 23.7907 Tj
+-268 TJm
+(I/O) 13.2801 Tj
+-268 TJm
+(errors) 23.2328 Tj
+-267 TJm
+(and) 14.386 Tj
+-268 TJm
+(e) 4.42339 Tj
+15 TJm
+(xit) 10.5205 Tj
+-268 TJm
+(cleanly) 28.772 Tj
+65 TJm
+(,) 2.49065 Tj
+-272 TJm
+(b) 4.9813 Tj
+20 TJm
+(ut) 7.7509 Tj
+-268 TJm
+(the) 12.1743 Tj
+72 537.8 Td
+(details) 26.0123 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(what) 19.3673 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(problem) 33.2053 Tj
+-250 TJm
+(is) 6.64505 Tj
+-250 TJm
+(sometimes) 42.62 Tj
+-250 TJm
+(seem) 20.4731 Tj
+-250 TJm
+(rather) 23.2328 Tj
+-250 TJm
+(misleading.) 46.2165 Tj
+[1 0 0 1 72 535.643] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -525.681] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 515.882 Td
+/F130_0 9.9626 Tf
+(This) 17.7135 Tj
+-280 TJm
+(manual) 29.3299 Tj
+-279 TJm
+(page) 18.8094 Tj
+-280 TJm
+(pertains) 31.5416 Tj
+-280 TJm
+(to) 7.7509 Tj
+-279 TJm
+(v) 4.9813 Tj
+15 TJm
+(ersion) 24.3486 Tj
+-280 TJm
+(1.0.5) 19.9252 Tj
+-280 TJm
+(of) 8.29885 Tj
+[1 0 0 1 256.84 515.882] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -256.84 -515.882] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+256.84 515.882 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 286.728 515.882] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -286.728 -515.882] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+286.728 515.882 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+-798 TJm
+(Compressed) 49.2551 Tj
+-280 TJm
+(data) 16.5977 Tj
+-279 TJm
+(created) 28.762 Tj
+-280 TJm
+(by) 9.9626 Tj
+-280 TJm
+(this) 14.396 Tj
+-279 TJm
+(v) 4.9813 Tj
+15 TJm
+(ersion) 24.3486 Tj
+-280 TJm
+(is) 6.64505 Tj
+-280 TJm
+(entirely) 30.4357 Tj
+-279 TJm
+(forw) 18.8094 Tj
+10 TJm
+(ards) 16.5977 Tj
+72 503.927 Td
+(and) 14.386 Tj
+-294 TJm
+(backw) 26.0024 Tj
+10 TJm
+(ards) 16.5977 Tj
+-293 TJm
+(compatible) 44.2738 Tj
+-294 TJm
+(with) 17.7135 Tj
+-294 TJm
+(the) 12.1743 Tj
+-293 TJm
+(pre) 12.7222 Tj
+25 TJm
+(vious) 21.589 Tj
+-294 TJm
+(public) 24.9065 Tj
+-294 TJm
+(releases,) 34.0223 Tj
+-304 TJm
+(v) 4.9813 Tj
+15 TJm
+(ersions) 28.224 Tj
+-294 TJm
+(0.1pl2,) 27.6761 Tj
+-305 TJm
+(0.9.0) 19.9252 Tj
+-293 TJm
+(and) 14.386 Tj
+-294 TJm
+(0.9.5,) 22.4159 Tj
+-305 TJm
+(1.0.0,) 22.4159 Tj
+-304 TJm
+(1.0.1,) 22.4159 Tj
+-305 TJm
+(1.0.2) 19.9252 Tj
+-294 TJm
+(and) 14.386 Tj
+72 491.972 Td
+(1.0.3,) 22.4159 Tj
+-263 TJm
+(b) 4.9813 Tj
+20 TJm
+(ut) 7.7509 Tj
+-260 TJm
+(with) 17.7135 Tj
+-260 TJm
+(the) 12.1743 Tj
+-260 TJm
+(follo) 18.8194 Tj
+25 TJm
+(wing) 19.9252 Tj
+-260 TJm
+(e) 4.42339 Tj
+15 TJm
+(xception:) 37.0808 Tj
+-330 TJm
+(0.9.0) 19.9252 Tj
+-260 TJm
+(and) 14.386 Tj
+-260 TJm
+(abo) 14.386 Tj
+15 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-260 TJm
+(can) 13.8281 Tj
+-260 TJm
+(correctly) 35.4071 Tj
+-260 TJm
+(decompress) 47.0334 Tj
+-260 TJm
+(multiple) 33.2153 Tj
+-260 TJm
+(concatenated) 52.0048 Tj
+-260 TJm
+(compressed) 47.0334 Tj
+72 480.017 Td
+(\002les.) 19.0983 Tj
+-310 TJm
+(0.1pl2) 25.1855 Tj
+-250 TJm
+(cannot) 26.5603 Tj
+-250 TJm
+(do) 9.9626 Tj
+-250 TJm
+(this;) 17.1656 Tj
+-250 TJm
+(it) 5.53921 Tj
+-250 TJm
+(will) 15.5018 Tj
+-250 TJm
+(stop) 16.6077 Tj
+-250 TJm
+(after) 18.2515 Tj
+-250 TJm
+(decompressing) 59.7656 Tj
+-250 TJm
+(just) 14.396 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(\002rst) 15.5018 Tj
+-250 TJm
+(\002le) 12.7322 Tj
+-250 TJm
+(in) 7.7509 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(stream.) 29.0509 Tj
+[1 0 0 1 72 477.86] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -467.897] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 458.099 Td
+/F134_0 9.9626 Tf
+(bzip2recover) 71.7307 Tj
+[1 0 0 1 143.731 458.099] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -143.731 -458.099] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+146.174 458.099 Td
+/F130_0 9.9626 Tf
+(v) 4.9813 Tj
+15 TJm
+(ersions) 28.224 Tj
+-245 TJm
+(prior) 19.3673 Tj
+-245 TJm
+(to) 7.7509 Tj
+-245 TJm
+(1.0.2) 19.9252 Tj
+-246 TJm
+(used) 18.2614 Tj
+-245 TJm
+(32-bit) 23.8007 Tj
+-245 TJm
+(inte) 14.9439 Tj
+15 TJm
+(gers) 16.5977 Tj
+-245 TJm
+(to) 7.7509 Tj
+-245 TJm
+(represent) 36.5129 Tj
+-245 TJm
+(bit) 10.5205 Tj
+-246 TJm
+(positions) 35.9849 Tj
+-245 TJm
+(in) 7.7509 Tj
+-245 TJm
+(compressed) 47.0334 Tj
+-245 TJm
+(\002les,) 19.0983 Tj
+-246 TJm
+(so) 8.85675 Tj
+-245 TJm
+(it) 5.53921 Tj
+-245 TJm
+(could) 22.1369 Tj
+72 446.144 Td
+(not) 12.7322 Tj
+-384 TJm
+(handle) 26.5603 Tj
+-383 TJm
+(compressed) 47.0334 Tj
+-384 TJm
+(\002les) 16.6077 Tj
+-383 TJm
+(more) 20.4731 Tj
+-384 TJm
+(than) 17.1556 Tj
+-383 TJm
+(512) 14.9439 Tj
+-384 TJm
+(me) 12.1743 Tj
+15 TJm
+(g) 4.9813 Tj
+5 TJm
+(abytes) 25.4544 Tj
+-383 TJm
+(long.) 20.2042 Tj
+-1421 TJm
+(V) 7.193 Tj
+111 TJm
+(ersions) 28.224 Tj
+-384 TJm
+(1.0.2) 19.9252 Tj
+-383 TJm
+(and) 14.386 Tj
+-384 TJm
+(abo) 14.386 Tj
+15 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-384 TJm
+(use) 13.2801 Tj
+-383 TJm
+(64-bit) 23.8007 Tj
+-384 TJm
+(ints) 14.396 Tj
+-383 TJm
+(on) 9.9626 Tj
+-384 TJm
+(some) 21.031 Tj
+72 434.189 Td
+(platforms) 38.1866 Tj
+-245 TJm
+(which) 24.3486 Tj
+-246 TJm
+(support) 29.8878 Tj
+-245 TJm
+(them) 19.9252 Tj
+-246 TJm
+(\(GNU) 24.8965 Tj
+-245 TJm
+(supported) 39.2925 Tj
+-245 TJm
+(tar) 10.5105 Tj
+18 TJm
+(gets,) 18.5404 Tj
+-247 TJm
+(and) 14.386 Tj
+-245 TJm
+(W) 9.40469 Tj
+40 TJm
+(indo) 17.7135 Tj
+25 TJm
+(ws\).) 16.8766 Tj
+-309 TJm
+(T) 6.08715 Tj
+80 TJm
+(o) 4.9813 Tj
+-245 TJm
+(establish) 34.8691 Tj
+-245 TJm
+(whether) 32.0895 Tj
+-246 TJm
+(or) 8.29885 Tj
+-245 TJm
+(not) 12.7322 Tj
+[1 0 0 1 468.269 434.189] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468.269 -434.189] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+468.269 434.189 Td
+/F134_0 9.9626 Tf
+(bzip2recover) 71.7307 Tj
+[1 0 0 1 540 434.189] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -540 -434.189] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 422.233 Td
+/F130_0 9.9626 Tf
+(w) 7.193 Tj
+10 TJm
+(as) 8.29885 Tj
+-255 TJm
+(b) 4.9813 Tj
+20 TJm
+(uilt) 13.2901 Tj
+-255 TJm
+(with) 17.7135 Tj
+-255 TJm
+(such) 18.2614 Tj
+-255 TJm
+(a) 4.42339 Tj
+-255 TJm
+(limitation,) 41.2452 Tj
+-256 TJm
+(run) 13.2801 Tj
+-255 TJm
+(it) 5.53921 Tj
+-255 TJm
+(without) 30.4457 Tj
+-255 TJm
+(ar) 7.74094 Tj
+18 TJm
+(guments.) 36.2539 Tj
+-325 TJm
+(In) 8.29885 Tj
+-255 TJm
+(an) 9.40469 Tj
+15 TJm
+(y) 4.9813 Tj
+-256 TJm
+(e) 4.42339 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(ent) 12.1743 Tj
+-255 TJm
+(you) 14.9439 Tj
+-255 TJm
+(can) 13.8281 Tj
+-255 TJm
+(b) 4.9813 Tj
+20 TJm
+(uild) 15.5018 Tj
+-255 TJm
+(yourself) 32.6474 Tj
+-255 TJm
+(an) 9.40469 Tj
+-255 TJm
+(unlimited) 38.1966 Tj
+-255 TJm
+(v) 4.9813 Tj
+15 TJm
+(ersion) 24.3486 Tj
+-255 TJm
+(if) 6.08715 Tj
+72 410.278 Td
+(you) 14.9439 Tj
+-250 TJm
+(can) 13.8281 Tj
+-250 TJm
+(recompile) 39.8404 Tj
+-250 TJm
+(it) 5.53921 Tj
+-250 TJm
+(with) 17.7135 Tj
+[1 0 0 1 176.318 410.278] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -176.318 -410.278] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+176.318 410.278 Td
+/F134_0 9.9626 Tf
+(MaybeUInt64) 65.7532 Tj
+[1 0 0 1 242.071 410.278] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -242.071 -410.278] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+244.562 410.278 Td
+/F130_0 9.9626 Tf
+(set) 11.0684 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(be) 9.40469 Tj
+-250 TJm
+(an) 9.40469 Tj
+-250 TJm
+(unsigned) 35.9749 Tj
+-250 TJm
+(64-bit) 23.8007 Tj
+-250 TJm
+(inte) 14.9439 Tj
+15 TJm
+(ger) 12.7222 Tj
+55 TJm
+(.) 2.49065 Tj
+[1 0 0 1 72 408.121] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -398.159] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 375.525 Td
+/F122_0 20.6585 Tf
+(2.9.) 34.4584 Tj
+-278 TJm
+(A) 14.9154 Tj
+50 TJm
+(UTHOR) 73.441 Tj
+[1 0 0 1 72 375.267] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -365.305] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 353.608 Td
+/F130_0 9.9626 Tf
+(Julian) 23.8007 Tj
+-250 TJm
+(Se) 9.9626 Tj
+25 TJm
+(w) 7.193 Tj
+10 TJm
+(ard,) 15.2129 Tj
+[1 0 0 1 132.801 353.608] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -132.801 -353.608] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+132.801 353.608 Td
+/F134_0 9.9626 Tf
+(jseward@bzip.org) 95.641 Tj
+[1 0 0 1 228.443 353.608] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -156.443 -1.5342] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -342.111] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 331.69 Td
+/F130_0 9.9626 Tf
+(The) 15.4918 Tj
+-299 TJm
+(ideas) 20.4731 Tj
+-300 TJm
+(embodied) 39.2925 Tj
+-299 TJm
+(in) 7.7509 Tj
+[1 0 0 1 166.942 331.69] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -166.942 -331.69] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+166.942 331.69 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 196.83 331.69] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -196.83 -331.69] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+199.813 331.69 Td
+/F130_0 9.9626 Tf
+(are) 12.1643 Tj
+-299 TJm
+(due) 14.386 Tj
+-300 TJm
+(to) 7.7509 Tj
+-299 TJm
+(\(at) 10.5105 Tj
+-300 TJm
+(least\)) 21.579 Tj
+-299 TJm
+(the) 12.1743 Tj
+-300 TJm
+(follo) 18.8194 Tj
+25 TJm
+(wing) 19.9252 Tj
+-299 TJm
+(people:) 29.3299 Tj
+-409 TJm
+(Michael) 32.6474 Tj
+-300 TJm
+(Burro) 23.2427 Tj
+25 TJm
+(ws) 11.0684 Tj
+-299 TJm
+(and) 14.386 Tj
+-299 TJm
+(Da) 11.6164 Tj
+20 TJm
+(vid) 12.7322 Tj
+-300 TJm
+(Wheeler) 33.7433 Tj
+-299 TJm
+(\(for) 14.9339 Tj
+72 319.735 Td
+(the) 12.1743 Tj
+-312 TJm
+(block) 22.1369 Tj
+-313 TJm
+(sorting) 27.6761 Tj
+-312 TJm
+(transformation\),) 64.468 Tj
+-328 TJm
+(Da) 11.6164 Tj
+20 TJm
+(vid) 12.7322 Tj
+-312 TJm
+(Wheeler) 33.7433 Tj
+-313 TJm
+(\(ag) 12.7222 Tj
+5 TJm
+(ain,) 14.6649 Tj
+-327 TJm
+(for) 11.6164 Tj
+-313 TJm
+(the) 12.1743 Tj
+-312 TJm
+(Huf) 15.4918 Tj
+25 TJm
+(fman) 20.4731 Tj
+-312 TJm
+(coder\),) 27.9351 Tj
+-328 TJm
+(Peter) 20.4731 Tj
+-313 TJm
+(Fenwick) 34.3112 Tj
+-312 TJm
+(\(for) 14.9339 Tj
+-312 TJm
+(the) 12.1743 Tj
+-313 TJm
+(structured) 39.8404 Tj
+72 307.78 Td
+(coding) 27.1182 Tj
+-325 TJm
+(model) 24.9065 Tj
+-326 TJm
+(in) 7.7509 Tj
+-325 TJm
+(the) 12.1743 Tj
+-326 TJm
+(original) 30.9936 Tj
+[1 0 0 1 191.156 307.779] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -191.156 -307.779] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+191.156 307.779 Td
+/F134_0 9.9626 Tf
+(bzip) 23.9102 Tj
+[1 0 0 1 215.067 307.779] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -215.067 -307.779] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+215.067 307.779 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-344 TJm
+(and) 14.386 Tj
+-326 TJm
+(man) 17.1556 Tj
+15 TJm
+(y) 4.9813 Tj
+-325 TJm
+(re\002nements\),) 52.2937 Tj
+-345 TJm
+(and) 14.386 Tj
+-325 TJm
+(Alistair) 29.8878 Tj
+-326 TJm
+(Mof) 17.1556 Tj
+25 TJm
+(f) 3.31755 Tj
+10 TJm
+(at,) 9.68365 Tj
+-344 TJm
+(Radford) 32.6474 Tj
+-325 TJm
+(Neal) 18.8094 Tj
+-326 TJm
+(and) 14.386 Tj
+-325 TJm
+(Ian) 12.7222 Tj
+-326 TJm
+(W) 9.40469 Tj
+40 TJm
+(itten) 17.7135 Tj
+-325 TJm
+(\(for) 14.9339 Tj
+72 295.824 Td
+(the) 12.1743 Tj
+-277 TJm
+(arithmetic) 40.3983 Tj
+-277 TJm
+(coder) 22.1269 Tj
+-277 TJm
+(in) 7.7509 Tj
+-277 TJm
+(the) 12.1743 Tj
+-277 TJm
+(original) 30.9936 Tj
+[1 0 0 1 214.171 295.824] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -214.171 -295.824] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+214.171 295.824 Td
+/F134_0 9.9626 Tf
+(bzip) 23.9102 Tj
+[1 0 0 1 238.082 295.824] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -238.082 -295.824] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+238.082 295.824 Td
+/F130_0 9.9626 Tf
+(\).) 5.8082 Tj
+-782 TJm
+(I) 3.31755 Tj
+-277 TJm
+(am) 12.1743 Tj
+-276 TJm
+(much) 22.1369 Tj
+-277 TJm
+(indebted) 34.3112 Tj
+-277 TJm
+(for) 11.6164 Tj
+-277 TJm
+(their) 18.2614 Tj
+-277 TJm
+(help,) 19.6462 Tj
+-284 TJm
+(support) 29.8878 Tj
+-277 TJm
+(and) 14.386 Tj
+-277 TJm
+(advice.) 28.493 Tj
+-781 TJm
+(See) 14.386 Tj
+-277 TJm
+(the) 12.1743 Tj
+-277 TJm
+(manual) 29.3299 Tj
+72 283.869 Td
+(in) 7.7509 Tj
+-330 TJm
+(the) 12.1743 Tj
+-330 TJm
+(source) 26.0024 Tj
+-330 TJm
+(distrib) 25.4644 Tj
+20 TJm
+(ution) 20.4831 Tj
+-330 TJm
+(for) 11.6164 Tj
+-329 TJm
+(pointers) 32.0995 Tj
+-330 TJm
+(to) 7.7509 Tj
+-330 TJm
+(sources) 29.8778 Tj
+-330 TJm
+(of) 8.29885 Tj
+-330 TJm
+(documentation.) 61.7083 Tj
+-1099 TJm
+(Christian) 36.5329 Tj
+-330 TJm
+(v) 4.9813 Tj
+20 TJm
+(on) 9.9626 Tj
+-330 TJm
+(Roques) 29.8878 Tj
+-330 TJm
+(encouraged) 45.9176 Tj
+-330 TJm
+(me) 12.1743 Tj
+-330 TJm
+(to) 7.7509 Tj
+-330 TJm
+(look) 17.7135 Tj
+72 271.914 Td
+(for) 11.6164 Tj
+-271 TJm
+(f) 3.31755 Tj
+10 TJm
+(aster) 18.8094 Tj
+-271 TJm
+(sorting) 27.6761 Tj
+-271 TJm
+(algorithms,) 45.1107 Tj
+-276 TJm
+(so) 8.85675 Tj
+-272 TJm
+(as) 8.29885 Tj
+-271 TJm
+(to) 7.7509 Tj
+-271 TJm
+(speed) 22.6848 Tj
+-271 TJm
+(up) 9.9626 Tj
+-271 TJm
+(compression.) 52.8516 Tj
+-746 TJm
+(Bela) 18.2614 Tj
+-271 TJm
+(Lubkin) 28.782 Tj
+-271 TJm
+(encouraged) 45.9176 Tj
+-271 TJm
+(me) 12.1743 Tj
+-272 TJm
+(to) 7.7509 Tj
+-271 TJm
+(impro) 23.8007 Tj
+15 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-271 TJm
+(the) 12.1743 Tj
+-271 TJm
+(w) 7.193 Tj
+10 TJm
+(orst-case) 35.4071 Tj
+72 259.959 Td
+(compression) 50.3609 Tj
+-340 TJm
+(performance.) 52.8317 Tj
+-580 TJm
+(Donna) 26.5603 Tj
+-339 TJm
+(Robinson) 38.1966 Tj
+-340 TJm
+(XMLised) 38.1866 Tj
+-340 TJm
+(the) 12.1743 Tj
+-340 TJm
+(documentation.) 61.7083 Tj
+-580 TJm
+(Man) 18.2614 Tj
+15 TJm
+(y) 4.9813 Tj
+-340 TJm
+(people) 26.5603 Tj
+-340 TJm
+(sent) 16.0497 Tj
+-339 TJm
+(patches,) 32.3685 Tj
+-363 TJm
+(helped) 26.5603 Tj
+-340 TJm
+(with) 17.7135 Tj
+72 248.004 Td
+(portability) 41.5142 Tj
+-250 TJm
+(problems,) 39.5714 Tj
+-250 TJm
+(lent) 14.9439 Tj
+-250 TJm
+(machines,) 40.1194 Tj
+-250 TJm
+(g) 4.9813 Tj
+5 TJm
+(a) 4.42339 Tj
+20 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-250 TJm
+(advice) 26.0024 Tj
+-250 TJm
+(and) 14.386 Tj
+-250 TJm
+(were) 19.3573 Tj
+-250 TJm
+(generally) 37.0708 Tj
+-250 TJm
+(helpful.) 30.7147 Tj
+[1 0 0 1 72 245.847] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 0 -194.995] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 374.394 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 6.5851] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 43.0633 -6.4855] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -496.332 -50.9514] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+539.395 50.9514 Td
+/F130_0 9.9626 Tf
+(7) 4.9813 Tj
+[1 0 0 1 453.269 50.8518] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 93.5985 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.2765 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+Q
+showpage
+%%PageTrailer
+pdfEndPage
+%%Page: 11 11
+%%BeginPageSetup
+%%PageOrientation: Portrait
+pdfStartPage
+0 0 612 792 re W
+%%EndPageSetup
+[] 0 d
+1 i
+0 j
+0 J
+10 M
+1 w
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+false op
+false OP
+0 0 612 792 re
+W
+q
+[1 0 0 1 72 741.554] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 4.3836 14.4459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 187.197 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 141.643 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -141.643 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 280.796 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -472.974 -13.9477] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -0.4981] cm
+q
+[] 0 d
+0 J
+0.4981 w
+0 0.2491 m
+475.465 0.2491 l
+S
+Q
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 479.251 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -15.0365 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -21.5542] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -720] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 701.916 Td
+/F122_0 24.7902 Tf
+(3.) 20.675 Tj
+-556 TJm
+(Pr) 26.1785 Tj
+20 TJm
+(ogramming) 134.983 Tj
+-278 TJm
+(with) 49.5804 Tj
+[1 0 0 1 330.484 701.916] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -330.484 -701.916] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+330.484 701.916 Td
+/F392_0 24.7902 Tf
+(libbzip2) 118.993 Tj
+[1 0 0 1 449.477 701.916] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -377.477 -5.5156] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -14.9439] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -671.493] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 656.35 Td
+/F122_0 17.2154 Tf
+(T) 10.5186 Tj
+80 TJm
+(ab) 20.0904 Tj
+10 TJm
+(le) 14.3576 Tj
+-278 TJm
+(of) 16.2513 Tj
+-278 TJm
+(Contents) 74.5943 Tj
+[1 0 0 1 72 647.528] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -11.7401] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -635.788] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 635.788 Td
+/F130_0 9.9626 Tf
+(3.1.) 14.9439 Tj
+-310 TJm
+(T) 6.08715 Tj
+80 TJm
+(op-le) 20.4731 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(el) 7.193 Tj
+-250 TJm
+(structure) 34.8591 Tj
+[1 0 0 1 164.921 635.788] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -169.902 -635.788] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+179.997 635.788 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 511.108 635.788] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -511.108 -635.788] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+511.108 635.788 Td
+/F130_0 9.9626 Tf
+(8) 4.9813 Tj
+[1 0 0 1 516.09 635.788] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7983] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -623.832] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 623.832 Td
+/F130_0 9.9626 Tf
+(3.1.1.) 22.4159 Tj
+-310 TJm
+(Lo) 11.0684 Tj
+25 TJm
+(w-le) 17.7035 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(el) 7.193 Tj
+-250 TJm
+(summary) 37.0808 Tj
+[1 0 0 1 177.374 623.832] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -182.355 -623.832] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+192.866 623.832 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 511.108 623.832] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -511.108 -623.832] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+511.108 623.832 Td
+/F130_0 9.9626 Tf
+(9) 4.9813 Tj
+[1 0 0 1 516.09 623.832] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -2.1569] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7983] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -611.877] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 611.877 Td
+/F130_0 9.9626 Tf
+(3.1.2.) 22.4159 Tj
+-310 TJm
+(High-le) 30.4357 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(el) 7.193 Tj
+-250 TJm
+(summary) 37.0808 Tj
+[1 0 0 1 179.287 611.877] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -184.268 -611.877] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+193.822 611.877 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 511.108 611.877] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -511.108 -611.877] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+511.108 611.877 Td
+/F130_0 9.9626 Tf
+(9) 4.9813 Tj
+[1 0 0 1 516.09 611.877] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7984] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -599.922] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 599.922 Td
+/F130_0 9.9626 Tf
+(3.1.3.) 22.4159 Tj
+-310 TJm
+(Utility) 26.0223 Tj
+-250 TJm
+(functions) 37.0808 Tj
+-250 TJm
+(summary) 37.0808 Tj
+[1 0 0 1 202.669 599.922] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -207.65 -599.922] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+216.582 599.922 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 511.108 599.922] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -511.108 -599.922] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+511.108 599.922 Td
+/F130_0 9.9626 Tf
+(9) 4.9813 Tj
+[1 0 0 1 516.09 599.922] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7983] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -587.967] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 587.967 Td
+/F130_0 9.9626 Tf
+(3.2.) 14.9439 Tj
+-310 TJm
+(Error) 21.0211 Tj
+-250 TJm
+(handling) 34.8691 Tj
+[1 0 0 1 148.413 587.967] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -153.394 -587.967] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+162.611 587.967 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 587.967] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -587.967] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 587.967 Td
+/F130_0 9.9626 Tf
+(10) 9.9626 Tj
+[1 0 0 1 516.09 587.967] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -2.1569] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7983] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -576.012] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 576.012 Td
+/F130_0 9.9626 Tf
+(3.3.) 14.9439 Tj
+-310 TJm
+(Lo) 11.0684 Tj
+25 TJm
+(w-le) 17.7035 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(el) 7.193 Tj
+-250 TJm
+(interf) 21.579 Tj
+10 TJm
+(ace) 13.2702 Tj
+[1 0 0 1 167.571 576.012] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -172.552 -576.012] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+181.045 576.012 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 576.012] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -576.012] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 576.012 Td
+/F130_0 9.9626 Tf
+(11) 9.9626 Tj
+[1 0 0 1 516.09 576.012] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -0.0995] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -11.8557] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -564.056] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 564.056 Td
+/F130_0 9.9626 Tf
+(3.3.1.) 22.4159 Tj
+[1 0 0 1 97.5043 564.056] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -97.5043 -564.056] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+97.5043 564.056 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompressInit) 107.596 Tj
+[1 0 0 1 205.101 564.056] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -210.082 -564.056] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+219.736 564.056 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 564.056] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -564.056] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 564.056 Td
+/F130_0 9.9626 Tf
+(11) 9.9626 Tj
+[1 0 0 1 516.09 564.056] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -1.5341] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -10.421] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -552.101] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 552.101 Td
+/F130_0 9.9626 Tf
+(3.3.2.) 22.4159 Tj
+[1 0 0 1 97.5043 552.101] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -97.5043 -552.101] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+97.5043 552.101 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompress) 83.6858 Tj
+[1 0 0 1 181.19 552.101] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -186.172 -552.101] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+194.497 552.101 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 552.101] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -552.101] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 552.101 Td
+/F130_0 9.9626 Tf
+(13) 9.9626 Tj
+[1 0 0 1 516.09 552.101] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -1.5342] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -10.421] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -540.146] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 540.146 Td
+/F130_0 9.9626 Tf
+(3.3.3.) 22.4159 Tj
+[1 0 0 1 97.5043 540.146] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -97.5043 -540.146] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+97.5043 540.146 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompressEnd) 101.619 Tj
+[1 0 0 1 199.123 540.146] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -204.105 -540.146] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+214.533 540.146 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 540.146] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -540.146] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 540.146 Td
+/F130_0 9.9626 Tf
+(16) 9.9626 Tj
+[1 0 0 1 516.09 540.146] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -1.5342] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -10.421] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -528.191] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 528.191 Td
+/F130_0 9.9626 Tf
+(3.3.4.) 22.4159 Tj
+[1 0 0 1 97.5043 528.191] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -97.5043 -528.191] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+97.5043 528.191 Td
+/F134_0 9.9626 Tf
+(BZ2_bzDecompressInit) 119.551 Tj
+[1 0 0 1 217.056 528.191] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -222.037 -528.191] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+232.355 528.191 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 528.191] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -528.191] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 528.191 Td
+/F130_0 9.9626 Tf
+(16) 9.9626 Tj
+[1 0 0 1 516.09 528.191] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -1.5341] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -10.421] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -516.236] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 516.236 Td
+/F130_0 9.9626 Tf
+(3.3.5.) 22.4159 Tj
+[1 0 0 1 97.5043 516.236] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -97.5043 -516.236] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+97.5043 516.236 Td
+/F134_0 9.9626 Tf
+(BZ2_bzDecompress) 95.641 Tj
+[1 0 0 1 193.146 516.236] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -198.127 -516.236] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+207.116 516.236 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 516.236] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -516.236] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 516.236 Td
+/F130_0 9.9626 Tf
+(17) 9.9626 Tj
+[1 0 0 1 516.09 516.236] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -1.5342] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -10.421] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -504.281] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 504.281 Td
+/F130_0 9.9626 Tf
+(3.3.6.) 22.4159 Tj
+[1 0 0 1 97.5043 504.281] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -97.5043 -504.281] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+97.5043 504.281 Td
+/F134_0 9.9626 Tf
+(BZ2_bzDecompressEnd) 113.574 Tj
+[1 0 0 1 211.078 504.281] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -216.06 -504.281] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+224.938 504.281 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 504.281] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -504.281] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 504.281 Td
+/F130_0 9.9626 Tf
+(18) 9.9626 Tj
+[1 0 0 1 516.09 504.281] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -1.5342] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -10.421] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -492.325] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 492.325 Td
+/F130_0 9.9626 Tf
+(3.4.) 14.9439 Tj
+-310 TJm
+(High-le) 30.4357 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(el) 7.193 Tj
+-250 TJm
+(interf) 21.579 Tj
+10 TJm
+(ace) 13.2702 Tj
+[1 0 0 1 169.483 492.325] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -174.465 -492.325] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+184.216 492.325 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 492.325] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -492.325] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 492.325 Td
+/F130_0 9.9626 Tf
+(18) 9.9626 Tj
+[1 0 0 1 516.09 492.325] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7983] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -480.37] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 480.37 Td
+/F130_0 9.9626 Tf
+(3.4.1.) 22.4159 Tj
+[1 0 0 1 97.5043 480.37] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -97.5043 -480.37] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+97.5043 480.37 Td
+/F134_0 9.9626 Tf
+(BZ2_bzReadOpen) 83.6858 Tj
+[1 0 0 1 181.19 480.37] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -186.172 -480.37] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+194.497 480.37 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 480.37] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -480.37] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 480.37 Td
+/F130_0 9.9626 Tf
+(19) 9.9626 Tj
+[1 0 0 1 516.09 480.37] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -1.5342] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -10.421] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -468.415] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 468.415 Td
+/F130_0 9.9626 Tf
+(3.4.2.) 22.4159 Tj
+[1 0 0 1 97.5043 468.415] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -97.5043 -468.415] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+97.5043 468.415 Td
+/F134_0 9.9626 Tf
+(BZ2_bzRead) 59.7756 Tj
+[1 0 0 1 157.28 468.415] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -162.261 -468.415] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+171.472 468.415 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 468.415] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -468.415] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 468.415 Td
+/F130_0 9.9626 Tf
+(20) 9.9626 Tj
+[1 0 0 1 516.09 468.415] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -1.31] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -10.6452] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -456.46] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 456.46 Td
+/F130_0 9.9626 Tf
+(3.4.3.) 22.4159 Tj
+[1 0 0 1 97.5043 456.46] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -97.5043 -456.46] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+97.5043 456.46 Td
+/F134_0 9.9626 Tf
+(BZ2_bzReadGetUnused) 113.574 Tj
+[1 0 0 1 211.078 456.46] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -216.06 -456.46] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+224.938 456.46 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 456.46] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -456.46] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 456.46 Td
+/F130_0 9.9626 Tf
+(21) 9.9626 Tj
+[1 0 0 1 516.09 456.46] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -1.31] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -10.6452] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -444.505] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 444.505 Td
+/F130_0 9.9626 Tf
+(3.4.4.) 22.4159 Tj
+[1 0 0 1 97.5043 444.505] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -97.5043 -444.505] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+97.5043 444.505 Td
+/F134_0 9.9626 Tf
+(BZ2_bzReadClose) 89.6634 Tj
+[1 0 0 1 187.168 444.505] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -192.149 -444.505] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+201.914 444.505 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 444.505] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -444.505] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 444.505 Td
+/F130_0 9.9626 Tf
+(22) 9.9626 Tj
+[1 0 0 1 516.09 444.505] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -1.31] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -10.6451] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -432.55] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 432.55 Td
+/F130_0 9.9626 Tf
+(3.4.5.) 22.4159 Tj
+[1 0 0 1 97.5043 432.55] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -97.5043 -432.55] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+97.5043 432.55 Td
+/F134_0 9.9626 Tf
+(BZ2_bzWriteOpen) 89.6634 Tj
+[1 0 0 1 187.168 432.55] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -192.149 -432.55] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+201.914 432.55 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 432.55] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -432.55] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 432.55 Td
+/F130_0 9.9626 Tf
+(22) 9.9626 Tj
+[1 0 0 1 516.09 432.55] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -1.5342] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -10.421] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -420.594] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 420.594 Td
+/F130_0 9.9626 Tf
+(3.4.6.) 22.4159 Tj
+[1 0 0 1 97.5043 420.594] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -97.5043 -420.594] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+97.5043 420.594 Td
+/F134_0 9.9626 Tf
+(BZ2_bzWrite) 65.7532 Tj
+[1 0 0 1 163.258 420.594] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -168.239 -420.594] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+176.675 420.594 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 420.594] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -420.594] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 420.594 Td
+/F130_0 9.9626 Tf
+(23) 9.9626 Tj
+[1 0 0 1 516.09 420.594] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -1.31] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -10.6452] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -408.639] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 408.639 Td
+/F130_0 9.9626 Tf
+(3.4.7.) 22.4159 Tj
+[1 0 0 1 97.5043 408.639] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -97.5043 -408.639] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+97.5043 408.639 Td
+/F134_0 9.9626 Tf
+(BZ2_bzWriteClose) 95.641 Tj
+[1 0 0 1 193.146 408.639] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -198.127 -408.639] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+207.116 408.639 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 408.639] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -408.639] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 408.639 Td
+/F130_0 9.9626 Tf
+(23) 9.9626 Tj
+[1 0 0 1 516.09 408.639] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -1.31] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -10.6451] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -396.684] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 396.684 Td
+/F130_0 9.9626 Tf
+(3.4.8.) 22.4159 Tj
+-310 TJm
+(Handling) 37.0808 Tj
+-250 TJm
+(embedded) 40.9463 Tj
+-250 TJm
+(compressed) 47.0334 Tj
+-250 TJm
+(data) 16.5977 Tj
+-250 TJm
+(streams) 30.4357 Tj
+[1 0 0 1 279.56 396.684] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -284.541 -396.684] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+294.601 396.684 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 396.684] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -396.684] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 396.684 Td
+/F130_0 9.9626 Tf
+(24) 9.9626 Tj
+[1 0 0 1 516.09 396.684] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7984] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -384.729] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 384.729 Td
+/F130_0 9.9626 Tf
+(3.4.9.) 22.4159 Tj
+-310 TJm
+(Standard) 35.417 Tj
+-250 TJm
+(\002le-reading/writing) 77.4791 Tj
+-250 TJm
+(code) 18.8094 Tj
+[1 0 0 1 234.19 384.729] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -239.172 -384.729] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+247.564 384.729 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 384.729] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -384.729] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 384.729 Td
+/F130_0 9.9626 Tf
+(25) 9.9626 Tj
+[1 0 0 1 516.09 384.729] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7984] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -372.774] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 372.774 Td
+/F130_0 9.9626 Tf
+(3.5.) 14.9439 Tj
+-310 TJm
+(Utility) 26.0223 Tj
+-250 TJm
+(functions) 37.0808 Tj
+[1 0 0 1 155.625 372.774] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -160.607 -372.774] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+170.645 372.774 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 372.774] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -372.774] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 372.774 Td
+/F130_0 9.9626 Tf
+(26) 9.9626 Tj
+[1 0 0 1 516.09 372.774] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7983] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -360.819] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 360.819 Td
+/F130_0 9.9626 Tf
+(3.5.1.) 22.4159 Tj
+[1 0 0 1 97.5043 360.819] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -97.5043 -360.819] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+97.5043 360.819 Td
+/F134_0 9.9626 Tf
+(BZ2_bzBuffToBuffCompress) 143.461 Tj
+[1 0 0 1 240.966 360.819] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -245.948 -360.819] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+255.38 360.819 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 360.819] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -360.819] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 360.819 Td
+/F130_0 9.9626 Tf
+(26) 9.9626 Tj
+[1 0 0 1 516.09 360.819] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -1.5342] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -10.421] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -348.863] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 348.863 Td
+/F130_0 9.9626 Tf
+(3.5.2.) 22.4159 Tj
+[1 0 0 1 97.5043 348.863] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -97.5043 -348.863] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+97.5043 348.863 Td
+/F134_0 9.9626 Tf
+(BZ2_bzBuffToBuffDecompress) 155.417 Tj
+[1 0 0 1 252.922 348.863] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -257.903 -348.863] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+267.999 348.863 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 348.863] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -348.863] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 348.863 Td
+/F130_0 9.9626 Tf
+(27) 9.9626 Tj
+[1 0 0 1 516.09 348.863] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -1.5342] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -10.421] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -336.908] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 336.908 Td
+/F130_0 9.9626 Tf
+(3.6.) 14.9439 Tj
+[1 0 0 1 90.0324 336.908] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90.0324 -336.908] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90.0324 336.908 Td
+/F134_0 9.9626 Tf
+(zlib) 23.9102 Tj
+[1 0 0 1 113.943 336.908] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -113.943 -336.908] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+116.433 336.908 Td
+/F130_0 9.9626 Tf
+(compatibility) 53.1405 Tj
+-250 TJm
+(functions) 37.0808 Tj
+[1 0 0 1 209.144 336.908] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -214.126 -336.908] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+223.971 336.908 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 336.908] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -336.908] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 336.908 Td
+/F130_0 9.9626 Tf
+(28) 9.9626 Tj
+[1 0 0 1 516.09 336.908] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7983] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -324.953] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 324.953 Td
+/F130_0 9.9626 Tf
+(3.7.) 14.9439 Tj
+-310 TJm
+(Using) 23.8007 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(library) 26.5603 Tj
+-250 TJm
+(in) 7.7509 Tj
+-250 TJm
+(a) 4.42339 Tj
+[1 0 0 1 177.195 324.953] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -177.195 -324.953] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+177.195 324.953 Td
+/F134_0 9.9626 Tf
+(stdio) 29.8878 Tj
+[1 0 0 1 207.083 324.953] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -207.083 -324.953] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+207.083 324.953 Td
+/F130_0 9.9626 Tf
+(-free) 18.7994 Tj
+-250 TJm
+(en) 9.40469 Tj
+40 TJm
+(vironment) 40.9562 Tj
+[1 0 0 1 278.335 324.953] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -283.316 -324.953] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+291.775 324.953 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 324.953] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -324.953] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 324.953 Td
+/F130_0 9.9626 Tf
+(28) 9.9626 Tj
+[1 0 0 1 516.09 324.953] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -2.1569] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7983] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -312.998] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 312.998 Td
+/F130_0 9.9626 Tf
+(3.7.1.) 22.4159 Tj
+-310 TJm
+(Getting) 29.8878 Tj
+-250 TJm
+(rid) 11.0684 Tj
+-250 TJm
+(of) 8.29885 Tj
+[1 0 0 1 154.231 312.998] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -154.231 -312.998] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+154.231 312.998 Td
+/F134_0 9.9626 Tf
+(stdio) 29.8878 Tj
+[1 0 0 1 184.119 312.998] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -189.1 -312.998] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+198.175 312.998 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 312.998] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -312.998] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 312.998 Td
+/F130_0 9.9626 Tf
+(29) 9.9626 Tj
+[1 0 0 1 516.09 312.998] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7984] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -301.043] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 301.043 Td
+/F130_0 9.9626 Tf
+(3.7.2.) 22.4159 Tj
+-310 TJm
+(Critical) 29.8878 Tj
+-250 TJm
+(error) 19.3573 Tj
+-250 TJm
+(handling) 34.8691 Tj
+[1 0 0 1 186.599 301.043] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -191.58 -301.043] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+201.629 301.043 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 301.043] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -301.043] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 301.043 Td
+/F130_0 9.9626 Tf
+(29) 9.9626 Tj
+[1 0 0 1 516.09 301.043] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7983] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -289.088] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 289.088 Td
+/F130_0 9.9626 Tf
+(3.8.) 14.9439 Tj
+-310 TJm
+(Making) 30.9936 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(W) 9.40469 Tj
+40 TJm
+(indo) 17.7135 Tj
+25 TJm
+(ws) 11.0684 Tj
+-250 TJm
+(DLL) 19.3673 Tj
+[1 0 0 1 189.828 289.088] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -194.809 -289.088] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+203.243 289.088 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 289.088] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -289.088] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 289.088 Td
+/F130_0 9.9626 Tf
+(29) 9.9626 Tj
+[1 0 0 1 516.09 289.088] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -2.1569] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -267.006] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 257.207 Td
+/F130_0 9.9626 Tf
+(This) 17.7135 Tj
+-250 TJm
+(chapter) 29.3199 Tj
+-250 TJm
+(describes) 37.0708 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(programming) 54.2364 Tj
+-250 TJm
+(interf) 21.579 Tj
+10 TJm
+(ace) 13.2702 Tj
+-250 TJm
+(to) 7.7509 Tj
+[1 0 0 1 282.448 257.207] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -282.448 -257.207] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+282.448 257.207 Td
+/F134_0 9.9626 Tf
+(libbzip2) 47.8205 Tj
+[1 0 0 1 330.269 257.207] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -330.269 -257.207] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+330.269 257.207 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+[1 0 0 1 72 255.05] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -245.088] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 235.289 Td
+/F130_0 9.9626 Tf
+(F) 5.53921 Tj
+15 TJm
+(or) 8.29885 Tj
+-273 TJm
+(general) 29.3199 Tj
+-272 TJm
+(background) 47.0334 Tj
+-273 TJm
+(information,) 49.534 Tj
+-278 TJm
+(particularly) 45.9276 Tj
+-273 TJm
+(about) 22.1369 Tj
+-273 TJm
+(memory) 33.2053 Tj
+-272 TJm
+(use) 13.2801 Tj
+-273 TJm
+(and) 14.386 Tj
+-273 TJm
+(performance) 50.341 Tj
+-272 TJm
+(aspects,) 31.2626 Tj
+-279 TJm
+(you') 18.2614 Tj
+50 TJm
+(d) 4.9813 Tj
+-272 TJm
+(be) 9.40469 Tj
+-273 TJm
+(well) 17.1556 Tj
+-273 TJm
+(advised) 30.4357 Tj
+72 223.334 Td
+(to) 7.7509 Tj
+-250 TJm
+(read) 17.1456 Tj
+[1 0 0 1 101.878 223.334] cm
+/DeviceRGB {} cs
+[0 0 1] sc
+/DeviceRGB {} CS
+[0 0 1] SC
+[1 0 0 1 -101.878 -223.334] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+101.878 223.334 Td
+/F130_0 9.9626 Tf
+(Ho) 12.1743 Tj
+25 TJm
+(w) 7.193 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(use) 13.2801 Tj
+-250 TJm
+(bzip2) 22.1369 Tj
+[1 0 0 1 171.636 223.334] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 1] sc
+/DeviceRGB {} CS
+[0 0 1] SC
+/DeviceRGB {} cs
+[0 0 1] sc
+/DeviceRGB {} CS
+[0 0 1] SC
+[1 0 0 1 -171.636 -223.334] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+174.126 223.334 Td
+/F130_0 9.9626 Tf
+([2]) 11.6164 Tj
+[1 0 0 1 185.743 223.334] cm
+/DeviceRGB {} cs
+[0 0 1] sc
+/DeviceRGB {} CS
+[0 0 1] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -185.743 -223.334] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+188.233 223.334 Td
+/F130_0 9.9626 Tf
+(as) 8.29885 Tj
+-250 TJm
+(well.) 19.6462 Tj
+[1 0 0 1 72 221.177] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -211.215] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 188.581 Td
+/F122_0 20.6585 Tf
+(3.1.) 34.4584 Tj
+-278 TJm
+(T) 12.6223 Tj
+80 TJm
+(op-le) 49.3532 Tj
+15 TJm
+(vel) 28.7153 Tj
+-278 TJm
+(structure) 89.5339 Tj
+[1 0 0 1 72 184.305] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -174.343] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 166.664 Td
+/F134_0 9.9626 Tf
+(libbzip2) 47.8205 Tj
+[1 0 0 1 119.821 166.664] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -119.821 -166.664] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+123.608 166.664 Td
+/F130_0 9.9626 Tf
+(is) 6.64505 Tj
+-380 TJm
+(a) 4.42339 Tj
+-380 TJm
+(\003e) 9.9626 Tj
+15 TJm
+(xible) 19.9252 Tj
+-381 TJm
+(library) 26.5603 Tj
+-380 TJm
+(for) 11.6164 Tj
+-380 TJm
+(compressing) 50.3609 Tj
+-380 TJm
+(and) 14.386 Tj
+-380 TJm
+(decompressing) 59.7656 Tj
+-380 TJm
+(data) 16.5977 Tj
+-381 TJm
+(in) 7.7509 Tj
+-380 TJm
+(the) 12.1743 Tj
+[1 0 0 1 405.291 166.664] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -405.291 -166.664] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+405.291 166.664 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 435.178 166.664] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -435.178 -166.664] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+438.966 166.664 Td
+/F130_0 9.9626 Tf
+(data) 16.5977 Tj
+-380 TJm
+(format.) 29.0509 Tj
+-1401 TJm
+(Although) 37.6387 Tj
+72 154.708 Td
+(packaged) 37.6188 Tj
+-285 TJm
+(as) 8.29885 Tj
+-284 TJm
+(a) 4.42339 Tj
+-285 TJm
+(single) 23.8007 Tj
+-285 TJm
+(entity) 22.6948 Tj
+65 TJm
+(,) 2.49065 Tj
+-293 TJm
+(it) 5.53921 Tj
+-285 TJm
+(helps) 21.031 Tj
+-285 TJm
+(to) 7.7509 Tj
+-284 TJm
+(re) 7.74094 Tj
+15 TJm
+(g) 4.9813 Tj
+5 TJm
+(ard) 12.7222 Tj
+-285 TJm
+(the) 12.1743 Tj
+-285 TJm
+(library) 26.5603 Tj
+-284 TJm
+(as) 8.29885 Tj
+-285 TJm
+(three) 19.9152 Tj
+-285 TJm
+(separate) 32.6375 Tj
+-284 TJm
+(parts:) 22.1369 Tj
+-380 TJm
+(the) 12.1743 Tj
+-285 TJm
+(lo) 7.7509 Tj
+25 TJm
+(w) 7.193 Tj
+-284 TJm
+(le) 7.193 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(el) 7.193 Tj
+-285 TJm
+(interf) 21.579 Tj
+10 TJm
+(ace,) 15.7608 Tj
+-293 TJm
+(and) 14.386 Tj
+-285 TJm
+(the) 12.1743 Tj
+-285 TJm
+(high) 17.7135 Tj
+72 142.753 Td
+(le) 7.193 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(el) 7.193 Tj
+-250 TJm
+(interf) 21.579 Tj
+10 TJm
+(ace,) 15.7608 Tj
+-250 TJm
+(and) 14.386 Tj
+-250 TJm
+(some) 21.031 Tj
+-250 TJm
+(utility) 23.8106 Tj
+-250 TJm
+(functions.) 39.5714 Tj
+[1 0 0 1 72 140.596] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -130.634] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 120.835 Td
+/F130_0 9.9626 Tf
+(The) 15.4918 Tj
+-349 TJm
+(structure) 34.8591 Tj
+-349 TJm
+(of) 8.29885 Tj
+[1 0 0 1 141.082 120.835] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -141.082 -120.835] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+141.082 120.835 Td
+/F134_0 9.9626 Tf
+(libbzip2) 47.8205 Tj
+[1 0 0 1 188.903 120.835] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -188.903 -120.835] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+188.903 120.835 Td
+/F130_0 9.9626 Tf
+(') 3.31755 Tj
+55 TJm
+(s) 3.87545 Tj
+-349 TJm
+(interf) 21.579 Tj
+10 TJm
+(aces) 17.1456 Tj
+-349 TJm
+(is) 6.64505 Tj
+-349 TJm
+(similar) 27.6761 Tj
+-349 TJm
+(to) 7.7509 Tj
+-349 TJm
+(that) 14.9439 Tj
+-349 TJm
+(of) 8.29885 Tj
+-349 TJm
+(Jean-loup) 38.7346 Tj
+-349 TJm
+(Gailly') 28.224 Tj
+55 TJm
+(s) 3.87545 Tj
+-349 TJm
+(and) 14.386 Tj
+-349 TJm
+(Mark) 21.579 Tj
+-349 TJm
+(Adler') 26.0024 Tj
+55 TJm
+(s) 3.87545 Tj
+-349 TJm
+(e) 4.42339 Tj
+15 TJm
+(xcellent) 31.5416 Tj
+[1 0 0 1 516.09 120.835] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -516.09 -120.835] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+516.09 120.835 Td
+/F134_0 9.9626 Tf
+(zlib) 23.9102 Tj
+[1 0 0 1 540 120.835] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -540 -120.835] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 108.88 Td
+/F130_0 9.9626 Tf
+(library) 26.5603 Tj
+65 TJm
+(.) 2.49065 Tj
+[1 0 0 1 72 106.723] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -96.7608] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 86.9624 Td
+/F130_0 9.9626 Tf
+(All) 12.7322 Tj
+-242 TJm
+(e) 4.42339 Tj
+15 TJm
+(xternally) 35.417 Tj
+-242 TJm
+(visible) 26.5703 Tj
+-241 TJm
+(symbols) 33.2153 Tj
+-242 TJm
+(ha) 9.40469 Tj
+20 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-242 TJm
+(names) 25.4544 Tj
+-242 TJm
+(be) 9.40469 Tj
+15 TJm
+(ginning) 30.4457 Tj
+[1 0 0 1 284.687 86.9624] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -284.687 -86.9624] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+284.687 86.9624 Td
+/F134_0 9.9626 Tf
+(BZ2_) 23.9102 Tj
+[1 0 0 1 308.597 86.9624] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -308.597 -86.9624] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+308.597 86.9624 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+-615 TJm
+(This) 17.7135 Tj
+-241 TJm
+(is) 6.64505 Tj
+-242 TJm
+(ne) 9.40469 Tj
+25 TJm
+(w) 7.193 Tj
+-242 TJm
+(in) 7.7509 Tj
+-242 TJm
+(v) 4.9813 Tj
+15 TJm
+(ersion) 24.3486 Tj
+-242 TJm
+(1.0.) 14.9439 Tj
+-614 TJm
+(The) 15.4918 Tj
+-242 TJm
+(intention) 35.427 Tj
+-242 TJm
+(is) 6.64505 Tj
+-241 TJm
+(to) 7.7509 Tj
+-242 TJm
+(minimise) 37.0908 Tj
+72 75.0073 Td
+(pollution) 35.9849 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(namespaces) 47.5814 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(library) 26.5603 Tj
+-250 TJm
+(clients.) 28.503 Tj
+[1 0 0 1 72 72.8505] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -21.9987] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 4.3836 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 374.394 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 6.8541] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 43.0633 -6.7545] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -498.225 -50.9514] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+541.288 50.9514 Td
+/F130_0 9.9626 Tf
+(8) 4.9813 Tj
+[1 0 0 1 455.161 50.8518] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 93.5986 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.2765 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -15.0366 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+Q
+showpage
+%%PageTrailer
+pdfEndPage
+%%Page: 12 12
+%%BeginPageSetup
+%%PageOrientation: Portrait
+pdfStartPage
+0 0 612 792 re W
+%%EndPageSetup
+[] 0 d
+1 i
+0 j
+0 J
+10 M
+1 w
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+false op
+false OP
+0 0 612 792 re
+W
+q
+[1 0 0 1 72 741.554] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 4.3836 14.4459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 187.197 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 -8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 76.4979 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -344.462 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+420.96 749.245 Td
+/F130_0 9.9626 Tf
+(Programming) 54.7943 Tj
+-250 TJm
+(with) 17.7135 Tj
+[1 0 0 1 498.449 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -498.449 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+498.449 749.245 Td
+/F134_0 9.9626 Tf
+(libbzip2) 47.8205 Tj
+[1 0 0 1 546.269 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -278.305 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 280.796 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -472.974 -5.0363] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -0.4981] cm
+q
+[] 0 d
+0 J
+0.4981 w
+0 0.2491 m
+475.465 0.2491 l
+S
+Q
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 479.251 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -15.0365 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -21.5542] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -720] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 710.037 Td
+/F130_0 9.9626 Tf
+(T) 6.08715 Tj
+80 TJm
+(o) 4.9813 Tj
+-250 TJm
+(use) 13.2801 Tj
+-250 TJm
+(an) 9.40469 Tj
+15 TJm
+(y) 4.9813 Tj
+-250 TJm
+(part) 15.4918 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(library) 26.5603 Tj
+65 TJm
+(,) 2.49065 Tj
+-250 TJm
+(you) 14.9439 Tj
+-250 TJm
+(need) 18.8094 Tj
+-250 TJm
+(to) 7.7509 Tj
+[1 0 0 1 240.567 710.037] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -240.567 -710.037] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+240.567 710.037 Td
+/F134_0 9.9626 Tf
+(#include) 47.8205 Tj
+-600 TJm
+(<bzlib.h>) 53.798 Tj
+[1 0 0 1 348.163 710.037] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -348.163 -710.037] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+350.654 710.037 Td
+/F130_0 9.9626 Tf
+(into) 15.5018 Tj
+-250 TJm
+(your) 18.2614 Tj
+-250 TJm
+(sources.) 32.3685 Tj
+[1 0 0 1 72 707.88] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -697.918] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 679.416 Td
+/F122_0 17.2154 Tf
+(3.1.1.) 43.0729 Tj
+-278 TJm
+(Lo) 21.0372 Tj
+15 TJm
+(w-le) 33.484 Tj
+15 TJm
+(vel) 23.9294 Tj
+-278 TJm
+(summar) 66.9679 Tj
+-10 TJm
+(y) 9.57176 Tj
+[1 0 0 1 72 675.853] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -665.89] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 657.498 Td
+/F130_0 9.9626 Tf
+(This) 17.7135 Tj
+-212 TJm
+(interf) 21.579 Tj
+10 TJm
+(ace) 13.2702 Tj
+-212 TJm
+(pro) 13.2801 Tj
+15 TJm
+(vides) 21.031 Tj
+-212 TJm
+(services) 32.0895 Tj
+-212 TJm
+(for) 11.6164 Tj
+-212 TJm
+(compressing) 50.3609 Tj
+-212 TJm
+(and) 14.386 Tj
+-212 TJm
+(decompress) 47.0334 Tj
+1 TJm
+(ing) 12.7322 Tj
+-212 TJm
+(data) 16.5977 Tj
+-212 TJm
+(in) 7.7509 Tj
+-212 TJm
+(memory) 33.2053 Tj
+65 TJm
+(.) 2.49065 Tj
+-595 TJm
+(There') 26.5503 Tj
+55 TJm
+(s) 3.87545 Tj
+-212 TJm
+(no) 9.9626 Tj
+-212 TJm
+(pro) 13.2801 Tj
+15 TJm
+(vision) 24.3586 Tj
+-212 TJm
+(for) 11.6164 Tj
+-212 TJm
+(dealing) 29.3299 Tj
+72 645.543 Td
+(with) 17.7135 Tj
+-213 TJm
+(\002les,) 19.0983 Tj
+-220 TJm
+(streams) 30.4357 Tj
+-213 TJm
+(or) 8.29885 Tj
+-213 TJm
+(an) 9.40469 Tj
+15 TJm
+(y) 4.9813 Tj
+-213 TJm
+(other) 20.4731 Tj
+-213 TJm
+(I/O) 13.2801 Tj
+-213 TJm
+(mechanisms,) 51.7457 Tj
+-221 TJm
+(just) 14.396 Tj
+-213 TJm
+(straight) 29.8878 Tj
+-213 TJm
+(memory-to-memory) 80.7967 Tj
+-213 TJm
+(w) 7.193 Tj
+10 TJm
+(ork.) 15.7708 Tj
+-595 TJm
+(In) 8.29885 Tj
+-213 TJm
+(f) 3.31755 Tj
+10 TJm
+(act,) 14.107 Tj
+-221 TJm
+(this) 14.396 Tj
+-213 TJm
+(part) 15.4918 Tj
+-213 TJm
+(of) 8.29885 Tj
+-213 TJm
+(the) 12.1743 Tj
+-213 TJm
+(library) 26.5603 Tj
+72 633.588 Td
+(can) 13.8281 Tj
+-250 TJm
+(be) 9.40469 Tj
+-250 TJm
+(compiled) 37.0808 Tj
+-250 TJm
+(without) 30.4457 Tj
+-250 TJm
+(inclusion) 36.5329 Tj
+-250 TJm
+(of) 8.29885 Tj
+[1 0 0 1 222.534 633.588] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -222.534 -633.588] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+222.534 633.588 Td
+/F134_0 9.9626 Tf
+(stdio.h) 41.8429 Tj
+[1 0 0 1 264.377 633.588] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -264.377 -633.588] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+264.377 633.588 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-250 TJm
+(which) 24.3486 Tj
+-250 TJm
+(may) 17.1556 Tj
+-250 TJm
+(be) 9.40469 Tj
+-250 TJm
+(helpful) 28.224 Tj
+-250 TJm
+(for) 11.6164 Tj
+-250 TJm
+(embedded) 40.9463 Tj
+-250 TJm
+(applications.) 50.6399 Tj
+[1 0 0 1 72 631.431] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -621.469] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 611.67 Td
+/F130_0 9.9626 Tf
+(The) 15.4918 Tj
+-250 TJm
+(lo) 7.7509 Tj
+25 TJm
+(w-le) 17.7035 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(el) 7.193 Tj
+-250 TJm
+(part) 15.4918 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(library) 26.5603 Tj
+-250 TJm
+(has) 13.2801 Tj
+-250 TJm
+(no) 9.9626 Tj
+-250 TJm
+(global) 24.9065 Tj
+-250 TJm
+(v) 4.9813 Tj
+25 TJm
+(ariables) 30.9837 Tj
+-250 TJm
+(and) 14.386 Tj
+-250 TJm
+(is) 6.64505 Tj
+-250 TJm
+(therefore) 35.955 Tj
+-250 TJm
+(thread-safe.) 46.7445 Tj
+[1 0 0 1 72 609.513] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -599.551] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 589.752 Td
+/F130_0 9.9626 Tf
+(Six) 13.2901 Tj
+-875 TJm
+(routines) 32.0995 Tj
+-876 TJm
+(mak) 17.1556 Tj
+10 TJm
+(e) 4.42339 Tj
+-875 TJm
+(up) 9.9626 Tj
+-876 TJm
+(the) 12.1743 Tj
+-875 TJm
+(lo) 7.7509 Tj
+25 TJm
+(w) 7.193 Tj
+-876 TJm
+(le) 7.193 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(el) 7.193 Tj
+-875 TJm
+(interf) 21.579 Tj
+10 TJm
+(ace:) 16.0398 Tj
+[1 0 0 1 308.791 589.752] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -308.791 -589.752] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+308.791 589.752 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompressInit) 107.596 Tj
+[1 0 0 1 416.387 589.752] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -416.387 -589.752] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+416.387 589.752 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 429.158 589.752] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -429.158 -589.752] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+429.158 589.752 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompress) 83.6858 Tj
+[1 0 0 1 512.844 589.752] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -512.844 -589.752] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+512.844 589.752 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-1032 TJm
+(and) 14.386 Tj
+[1 0 0 1 72 577.797] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -577.797] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 577.797 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompressEnd) 101.619 Tj
+[1 0 0 1 173.619 577.797] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -173.619 -577.797] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+186.15 577.797 Td
+/F130_0 9.9626 Tf
+(for) 11.6164 Tj
+-1258 TJm
+(compression,) 52.8516 Tj
+-1510 TJm
+(and) 14.386 Tj
+-1257 TJm
+(a) 4.42339 Tj
+-1258 TJm
+(corresponding) 56.996 Tj
+-1258 TJm
+(trio) 13.8381 Tj
+[1 0 0 1 417.958 577.797] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -417.958 -577.797] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+417.958 577.797 Td
+/F134_0 9.9626 Tf
+(BZ2_bzDecompressInit) 119.551 Tj
+[1 0 0 1 537.509 577.797] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -537.509 -577.797] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+537.509 577.797 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 72 565.842] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -565.842] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 565.842 Td
+/F134_0 9.9626 Tf
+(BZ2_bzDecompress) 95.641 Tj
+[1 0 0 1 167.641 565.842] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -167.641 -565.842] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+172.707 565.842 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 192.158 565.842] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -192.158 -565.842] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+192.158 565.842 Td
+/F134_0 9.9626 Tf
+(BZ2_bzDecompressEnd) 113.574 Tj
+[1 0 0 1 305.732 565.842] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -305.732 -565.842] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+310.798 565.842 Td
+/F130_0 9.9626 Tf
+(for) 11.6164 Tj
+-508 TJm
+(decompression.) 62.2563 Tj
+-2171 TJm
+(The) 15.4918 Tj
+[1 0 0 1 431.918 565.842] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -431.918 -565.842] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+431.918 564.099 Td
+/F134_0 9.9626 Tf
+(*) 5.97756 Tj
+437.895 565.842 Td
+(Init) 23.9102 Tj
+[1 0 0 1 461.805 565.842] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -461.805 -565.842] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+466.871 565.842 Td
+/F130_0 9.9626 Tf
+(functions) 37.0808 Tj
+-508 TJm
+(allocate) 30.9837 Tj
+72 553.887 Td
+(memory) 33.2053 Tj
+-574 TJm
+(for) 11.6164 Tj
+-573 TJm
+(compression/decompression) 112.896 Tj
+-574 TJm
+(and) 14.386 Tj
+-574 TJm
+(do) 9.9626 Tj
+-573 TJm
+(other) 20.4731 Tj
+-574 TJm
+(initialisations,) 56.1891 Tj
+-654 TJm
+(whilst) 24.3586 Tj
+-574 TJm
+(the) 12.1743 Tj
+[1 0 0 1 419.502 553.887] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -419.502 -553.887] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+419.502 552.144 Td
+/F134_0 9.9626 Tf
+(*) 5.97756 Tj
+425.48 553.887 Td
+(End) 17.9327 Tj
+[1 0 0 1 443.413 553.887] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -443.413 -553.887] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+449.128 553.887 Td
+/F130_0 9.9626 Tf
+(functions) 37.0808 Tj
+-574 TJm
+(close) 20.4731 Tj
+-573 TJm
+(do) 9.9626 Tj
+25 TJm
+(wn) 12.1743 Tj
+72 541.932 Td
+(operations) 41.5042 Tj
+-250 TJm
+(and) 14.386 Tj
+-250 TJm
+(release) 27.6562 Tj
+-250 TJm
+(memory) 33.2053 Tj
+65 TJm
+(.) 2.49065 Tj
+[1 0 0 1 72 539.775] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -529.812] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 520.014 Td
+/F130_0 9.9626 Tf
+(The) 15.4918 Tj
+-303 TJm
+(real) 14.9339 Tj
+-303 TJm
+(w) 7.193 Tj
+10 TJm
+(ork) 13.2801 Tj
+-303 TJm
+(is) 6.64505 Tj
+-303 TJm
+(done) 19.3673 Tj
+-303 TJm
+(by) 9.9626 Tj
+[1 0 0 1 176.892 520.014] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -176.892 -520.014] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+176.892 520.014 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompress) 83.6858 Tj
+[1 0 0 1 260.578 520.014] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -260.578 -520.014] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+263.598 520.014 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 281.003 520.014] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -281.003 -520.014] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+281.003 520.014 Td
+/F134_0 9.9626 Tf
+(BZ2_bzDecompress) 95.641 Tj
+[1 0 0 1 376.645 520.014] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -376.645 -520.014] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+376.645 520.014 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+-939 TJm
+(These) 23.7907 Tj
+-303 TJm
+(compress) 37.6287 Tj
+-303 TJm
+(and) 14.386 Tj
+-303 TJm
+(decompress) 47.0334 Tj
+-303 TJm
+(data) 16.5977 Tj
+72 508.059 Td
+(from) 19.3673 Tj
+-205 TJm
+(a) 4.42339 Tj
+-205 TJm
+(user) 16.5977 Tj
+20 TJm
+(-supplied) 37.0808 Tj
+-205 TJm
+(input) 20.4831 Tj
+-206 TJm
+(b) 4.9813 Tj
+20 TJm
+(uf) 8.29885 Tj
+25 TJm
+(fer) 11.0585 Tj
+-205 TJm
+(to) 7.7509 Tj
+-205 TJm
+(a) 4.42339 Tj
+-205 TJm
+(user) 16.5977 Tj
+20 TJm
+(-supplied) 37.0808 Tj
+-205 TJm
+(output) 25.4644 Tj
+-205 TJm
+(b) 4.9813 Tj
+20 TJm
+(uf) 8.29885 Tj
+25 TJm
+(fer) 11.0585 Tj
+55 TJm
+(.) 2.49065 Tj
+-591 TJm
+(These) 23.7907 Tj
+-205 TJm
+(b) 4.9813 Tj
+20 TJm
+(uf) 8.29885 Tj
+25 TJm
+(fers) 14.9339 Tj
+-205 TJm
+(can) 13.8281 Tj
+-205 TJm
+(be) 9.40469 Tj
+-205 TJm
+(an) 9.40469 Tj
+15 TJm
+(y) 4.9813 Tj
+-205 TJm
+(size;) 18.2614 Tj
+-220 TJm
+(arbitrary) 34.3012 Tj
+-206 TJm
+(quantities) 38.7446 Tj
+-205 TJm
+(of) 8.29885 Tj
+72 496.104 Td
+(data) 16.5977 Tj
+-258 TJm
+(are) 12.1643 Tj
+-258 TJm
+(handled) 31.5416 Tj
+-258 TJm
+(by) 9.9626 Tj
+-257 TJm
+(making) 29.8878 Tj
+-258 TJm
+(repeated) 33.7433 Tj
+-258 TJm
+(calls) 18.2614 Tj
+-258 TJm
+(to) 7.7509 Tj
+-258 TJm
+(these) 20.4731 Tj
+-258 TJm
+(functions.) 39.5714 Tj
+-667 TJm
+(This) 17.7135 Tj
+-258 TJm
+(is) 6.64505 Tj
+-258 TJm
+(a) 4.42339 Tj
+-257 TJm
+(\003e) 9.9626 Tj
+15 TJm
+(xible) 19.9252 Tj
+-258 TJm
+(mechanism) 45.3796 Tj
+-258 TJm
+(allo) 14.9439 Tj
+25 TJm
+(wing) 19.9252 Tj
+-258 TJm
+(a) 4.42339 Tj
+-258 TJm
+(consumer) 38.7346 Tj
+20 TJm
+(-pull) 18.8194 Tj
+72 484.148 Td
+(style) 18.8194 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(acti) 14.386 Tj
+25 TJm
+(vity) 15.5018 Tj
+65 TJm
+(,) 2.49065 Tj
+-250 TJm
+(or) 8.29885 Tj
+-250 TJm
+(producer) 35.4071 Tj
+20 TJm
+(-push,) 24.6275 Tj
+-250 TJm
+(or) 8.29885 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(mixture) 30.9936 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(both.) 20.2042 Tj
+[1 0 0 1 72 481.992] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -472.029] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 453.527 Td
+/F122_0 17.2154 Tf
+(3.1.2.) 43.0729 Tj
+-278 TJm
+(High-le) 58.343 Tj
+15 TJm
+(vel) 23.9294 Tj
+-278 TJm
+(summar) 66.9679 Tj
+-10 TJm
+(y) 9.57176 Tj
+[1 0 0 1 72 449.697] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -439.734] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 431.61 Td
+/F130_0 9.9626 Tf
+(This) 17.7135 Tj
+-284 TJm
+(interf) 21.579 Tj
+10 TJm
+(ace) 13.2702 Tj
+-284 TJm
+(pro) 13.2801 Tj
+15 TJm
+(vides) 21.031 Tj
+-285 TJm
+(some) 21.031 Tj
+-284 TJm
+(handy) 24.3486 Tj
+-284 TJm
+(wrappers) 36.5129 Tj
+-284 TJm
+(around) 27.6661 Tj
+-284 TJm
+(the) 12.1743 Tj
+-284 TJm
+(lo) 7.7509 Tj
+25 TJm
+(w-le) 17.7035 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(el) 7.193 Tj
+-285 TJm
+(interf) 21.579 Tj
+10 TJm
+(ace) 13.2702 Tj
+-284 TJm
+(to) 7.7509 Tj
+-284 TJm
+(f) 3.31755 Tj
+10 TJm
+(acilitate) 31.5416 Tj
+-284 TJm
+(reading) 29.8778 Tj
+-284 TJm
+(and) 14.386 Tj
+-285 TJm
+(writ) 16.0497 Tj
+1 TJm
+(ing) 12.7322 Tj
+[1 0 0 1 510.112 431.61] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -510.112 -431.61] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+510.112 431.61 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 540 431.61] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -540 -431.61] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 419.654 Td
+/F130_0 9.9626 Tf
+(format) 26.5603 Tj
+-347 TJm
+(\002les) 16.6077 Tj
+-346 TJm
+(\() 3.31755 Tj
+[1 0 0 1 125.391 419.654] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -125.391 -419.654] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+125.391 419.654 Td
+/F134_0 9.9626 Tf
+(.bz2) 23.9102 Tj
+[1 0 0 1 149.301 419.654] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -149.301 -419.654] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+152.754 419.654 Td
+/F130_0 9.9626 Tf
+(\002les\).) 22.4159 Tj
+-1200 TJm
+(The) 15.4918 Tj
+-346 TJm
+(routines) 32.0995 Tj
+-347 TJm
+(pro) 13.2801 Tj
+15 TJm
+(vide) 17.1556 Tj
+-346 TJm
+(hooks) 23.8007 Tj
+-347 TJm
+(to) 7.7509 Tj
+-346 TJm
+(f) 3.31755 Tj
+10 TJm
+(acilitate) 31.5416 Tj
+-347 TJm
+(reading) 29.8778 Tj
+-347 TJm
+(\002les) 16.6077 Tj
+-346 TJm
+(in) 7.7509 Tj
+-347 TJm
+(which) 24.3486 Tj
+-346 TJm
+(the) 12.1743 Tj
+[1 0 0 1 460.049 419.654] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -460.049 -419.654] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+460.049 419.654 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 489.937 419.654] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -489.937 -419.654] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+493.39 419.654 Td
+/F130_0 9.9626 Tf
+(data) 16.5977 Tj
+-347 TJm
+(stream) 26.5603 Tj
+72 407.699 Td
+(is) 6.64505 Tj
+-339 TJm
+(embedded) 40.9463 Tj
+-339 TJm
+(within) 25.4644 Tj
+-339 TJm
+(some) 21.031 Tj
+-339 TJm
+(lar) 10.5105 Tj
+18 TJm
+(ger) 12.7222 Tj
+20 TJm
+(-scale) 23.2328 Tj
+-339 TJm
+(\002le) 12.7322 Tj
+-339 TJm
+(structure,) 37.3498 Tj
+-361 TJm
+(or) 8.29885 Tj
+-339 TJm
+(wh) 12.1743 Tj
+-1 TJm
+(e) 4.42339 Tj
+1 TJm
+(re) 7.74094 Tj
+-340 TJm
+(there) 19.9152 Tj
+-339 TJm
+(are) 12.1643 Tj
+-339 TJm
+(multiple) 33.2153 Tj
+[1 0 0 1 400.941 407.699] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -400.941 -407.699] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+400.941 407.699 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 430.829 407.699] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -430.829 -407.699] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+434.207 407.699 Td
+/F130_0 9.9626 Tf
+(data) 16.5977 Tj
+-339 TJm
+(streams) 30.4357 Tj
+-339 TJm
+(concatenated) 52.0048 Tj
+72 395.744 Td
+(end-to-end.) 45.6486 Tj
+[1 0 0 1 72 395.644] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -385.682] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 373.826 Td
+/F130_0 9.9626 Tf
+(F) 5.53921 Tj
+15 TJm
+(or) 8.29885 Tj
+-332 TJm
+(reading) 29.8778 Tj
+-333 TJm
+(\002les,) 19.0983 Tj
+[1 0 0 1 144.803 373.826] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -144.803 -373.826] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+144.803 373.826 Td
+/F134_0 9.9626 Tf
+(BZ2_bzReadOpen) 83.6858 Tj
+[1 0 0 1 228.489 373.826] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -228.489 -373.826] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+228.489 373.826 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 234.496 373.826] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -234.496 -373.826] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+234.496 373.826 Td
+/F134_0 9.9626 Tf
+(BZ2_bzRead) 59.7756 Tj
+[1 0 0 1 294.272 373.826] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -294.272 -373.826] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+294.272 373.826 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 300.279 373.826] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -300.279 -373.826] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+300.279 373.826 Td
+/F134_0 9.9626 Tf
+(BZ2_bzReadClose) 89.6634 Tj
+[1 0 0 1 389.942 373.826] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -389.942 -373.826] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+393.253 373.826 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 410.951 373.826] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -410.951 -373.826] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+410.951 373.826 Td
+/F134_0 9.9626 Tf
+(BZ2_bzReadGetUnused) 113.574 Tj
+[1 0 0 1 524.525 373.826] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -524.525 -373.826] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+527.836 373.826 Td
+/F130_0 9.9626 Tf
+(are) 12.1643 Tj
+72 361.871 Td
+(supplied.) 36.2539 Tj
+-620 TJm
+(F) 5.53921 Tj
+15 TJm
+(or) 8.29885 Tj
+-250 TJm
+(writing) 28.782 Tj
+-250 TJm
+(\002les,) 19.0983 Tj
+[1 0 0 1 183.471 361.871] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -183.471 -361.871] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+183.471 361.871 Td
+/F134_0 9.9626 Tf
+(BZ2_bzWriteOpen) 89.6634 Tj
+[1 0 0 1 273.135 361.871] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -273.135 -361.871] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+273.135 361.871 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 278.116 361.871] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -278.116 -361.871] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+278.116 361.871 Td
+/F134_0 9.9626 Tf
+(BZ2_bzWrite) 65.7532 Tj
+[1 0 0 1 343.869 361.871] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -343.869 -361.871] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+346.36 361.871 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 363.237 361.871] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -363.237 -361.871] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+363.237 361.871 Td
+/F134_0 9.9626 Tf
+(BZ2_bzWriteFinish) 101.619 Tj
+[1 0 0 1 464.856 361.871] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -464.856 -361.871] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+467.346 361.871 Td
+/F130_0 9.9626 Tf
+(are) 12.1643 Tj
+-250 TJm
+(a) 4.42339 Tj
+20 TJm
+(v) 4.9813 Tj
+25 TJm
+(ailable.) 29.0509 Tj
+[1 0 0 1 72 359.714] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -349.751] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 339.953 Td
+/F130_0 9.9626 Tf
+(As) 11.0684 Tj
+-374 TJm
+(with) 17.7135 Tj
+-374 TJm
+(the) 12.1743 Tj
+-375 TJm
+(lo) 7.7509 Tj
+25 TJm
+(w-le) 17.7035 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(el) 7.193 Tj
+-374 TJm
+(library) 26.5603 Tj
+65 TJm
+(,) 2.49065 Tj
+-405 TJm
+(no) 9.9626 Tj
+-374 TJm
+(global) 24.9065 Tj
+-374 TJm
+(v) 4.9813 Tj
+25 TJm
+(ariables) 30.9837 Tj
+-375 TJm
+(are) 12.1643 Tj
+-374 TJm
+(used) 18.2614 Tj
+-374 TJm
+(so) 8.85675 Tj
+-374 TJm
+(the) 12.1743 Tj
+-374 TJm
+(library) 26.5603 Tj
+-375 TJm
+(is) 6.64505 Tj
+-374 TJm
+(per) 12.7222 Tj
+-374 TJm
+(se) 8.29885 Tj
+-374 TJm
+(thread-safe.) 46.7445 Tj
+-1365 TJm
+(Ho) 12.1743 Tj
+25 TJm
+(we) 11.6164 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(er) 7.74094 Tj
+40 TJm
+(,) 2.49065 Tj
+-406 TJm
+(if) 6.08715 Tj
+-374 TJm
+(I/O) 13.2801 Tj
+72 327.998 Td
+(errors) 23.2328 Tj
+-267 TJm
+(occur) 22.1269 Tj
+-267 TJm
+(whilst) 24.3586 Tj
+-267 TJm
+(reading) 29.8778 Tj
+-267 TJm
+(or) 8.29885 Tj
+-267 TJm
+(writing) 28.782 Tj
+-267 TJm
+(the) 12.1743 Tj
+-268 TJm
+(underlying) 43.1679 Tj
+-267 TJm
+(compressed) 47.0334 Tj
+-267 TJm
+(\002les,) 19.0983 Tj
+-271 TJm
+(you) 14.9439 Tj
+-267 TJm
+(may) 17.1556 Tj
+-267 TJm
+(ha) 9.40469 Tj
+20 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-267 TJm
+(to) 7.7509 Tj
+-267 TJm
+(consult) 28.782 Tj
+[1 0 0 1 457.199 327.998] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -457.199 -327.998] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+457.199 327.998 Td
+/F134_0 9.9626 Tf
+(errno) 29.8878 Tj
+[1 0 0 1 487.087 327.998] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -487.087 -327.998] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+489.748 327.998 Td
+/F130_0 9.9626 Tf
+(to) 7.7509 Tj
+-267 TJm
+(determine) 39.8404 Tj
+72 316.043 Td
+(the) 12.1743 Tj
+-366 TJm
+(cause) 22.1269 Tj
+-365 TJm
+(of) 8.29885 Tj
+-366 TJm
+(the) 12.1743 Tj
+-365 TJm
+(error) 19.3573 Tj
+55 TJm
+(.) 2.49065 Tj
+-1314 TJm
+(In) 8.29885 Tj
+-366 TJm
+(that) 14.9439 Tj
+-365 TJm
+(case,) 19.6363 Tj
+-395 TJm
+(you') 18.2614 Tj
+50 TJm
+(d) 4.9813 Tj
+-366 TJm
+(need) 18.8094 Tj
+-365 TJm
+(a) 4.42339 Tj
+-366 TJm
+(C) 6.64505 Tj
+-365 TJm
+(library) 26.5603 Tj
+-366 TJm
+(which) 24.3486 Tj
+-366 TJm
+(correctly) 35.4071 Tj
+-365 TJm
+(supports) 33.7633 Tj
+[1 0 0 1 431.668 316.043] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -431.668 -316.043] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+431.668 316.043 Td
+/F134_0 9.9626 Tf
+(errno) 29.8878 Tj
+[1 0 0 1 461.556 316.043] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -461.556 -316.043] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+465.199 316.043 Td
+/F130_0 9.9626 Tf
+(in) 7.7509 Tj
+-366 TJm
+(a) 4.42339 Tj
+-365 TJm
+(multithreaded) 55.3422 Tj
+72 304.088 Td
+(en) 9.40469 Tj
+40 TJm
+(vironment.) 43.4469 Tj
+[1 0 0 1 72 303.988] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -294.025] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 282.17 Td
+/F130_0 9.9626 Tf
+(T) 6.08715 Tj
+80 TJm
+(o) 4.9813 Tj
+-243 TJm
+(mak) 17.1556 Tj
+10 TJm
+(e) 4.42339 Tj
+-243 TJm
+(the) 12.1743 Tj
+-242 TJm
+(library) 26.5603 Tj
+-243 TJm
+(a) 4.42339 Tj
+-243 TJm
+(little) 18.2714 Tj
+-242 TJm
+(simpler) 29.8878 Tj
+-243 TJm
+(and) 14.386 Tj
+-243 TJm
+(more) 20.4731 Tj
+-243 TJm
+(portable,) 35.1381 Tj
+[1 0 0 1 289.263 282.17] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -289.263 -282.17] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+289.263 282.17 Td
+/F134_0 9.9626 Tf
+(BZ2_bzReadOpen) 83.6858 Tj
+[1 0 0 1 372.949 282.17] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -372.949 -282.17] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+375.368 282.17 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 392.172 282.17] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -392.172 -282.17] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+392.172 282.17 Td
+/F134_0 9.9626 Tf
+(BZ2_bzWriteOpen) 89.6634 Tj
+[1 0 0 1 481.836 282.17] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -481.836 -282.17] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+484.254 282.17 Td
+/F130_0 9.9626 Tf
+(require) 28.2141 Tj
+-243 TJm
+(you) 14.9439 Tj
+-242 TJm
+(to) 7.7509 Tj
+72 270.215 Td
+(pass) 17.1556 Tj
+-247 TJm
+(them) 19.9252 Tj
+-248 TJm
+(\002le) 12.7322 Tj
+-247 TJm
+(handles) 30.4357 Tj
+-247 TJm
+(\() 3.31755 Tj
+[1 0 0 1 165.421 270.215] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -165.421 -270.215] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+165.421 270.215 Td
+/F134_0 9.9626 Tf
+(FILE) 23.9102 Tj
+189.331 268.471 Td
+(*) 5.97756 Tj
+[1 0 0 1 195.309 270.215] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -195.309 -270.215] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+195.309 270.215 Td
+/F130_0 9.9626 Tf
+(s\)) 7.193 Tj
+-247 TJm
+(which) 24.3486 Tj
+-248 TJm
+(ha) 9.40469 Tj
+20 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-247 TJm
+(pre) 12.7222 Tj
+25 TJm
+(viously) 29.3399 Tj
+-247 TJm
+(been) 18.8094 Tj
+-248 TJm
+(opened) 28.772 Tj
+-247 TJm
+(for) 11.6164 Tj
+-247 TJm
+(reading) 29.8778 Tj
+-247 TJm
+(or) 8.29885 Tj
+-248 TJm
+(writing) 28.782 Tj
+-247 TJm
+(respecti) 30.9837 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(ely) 12.1743 Tj
+65 TJm
+(.) 2.49065 Tj
+-618 TJm
+(That) 18.2614 Tj
+-248 TJm
+(a) 4.42339 Tj
+20 TJm
+(v) 4.9813 Tj
+20 TJm
+(oids) 16.6077 Tj
+72 258.26 Td
+(portability) 41.5142 Tj
+-272 TJm
+(problems) 37.0808 Tj
+-273 TJm
+(associated) 40.9463 Tj
+-272 TJm
+(with) 17.7135 Tj
+-272 TJm
+(\002le) 12.7322 Tj
+-273 TJm
+(operations) 41.5042 Tj
+-272 TJm
+(and) 14.386 Tj
+-272 TJm
+(\002le) 12.7322 Tj
+-273 TJm
+(attrib) 21.031 Tj
+20 TJm
+(utes,) 18.5404 Tj
+-278 TJm
+(whilst) 24.3586 Tj
+-272 TJm
+(not) 12.7322 Tj
+-272 TJm
+(being) 22.1369 Tj
+-273 TJm
+(much) 22.1369 Tj
+-272 TJm
+(of) 8.29885 Tj
+-273 TJm
+(an) 9.40469 Tj
+-272 TJm
+(imposition) 42.63 Tj
+-272 TJm
+(on) 9.9626 Tj
+-273 TJm
+(the) 12.1743 Tj
+72 246.304 Td
+(programmer) 49.2451 Tj
+55 TJm
+(.) 2.49065 Tj
+[1 0 0 1 72 244.147] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -234.185] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 215.683 Td
+/F122_0 17.2154 Tf
+(3.1.3.) 43.0729 Tj
+-278 TJm
+(Utility) 47.8244 Tj
+-278 TJm
+(functions) 77.4693 Tj
+-278 TJm
+(summar) 66.9679 Tj
+-10 TJm
+(y) 9.57176 Tj
+[1 0 0 1 72 212.12] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -202.157] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 193.765 Td
+/F130_0 9.9626 Tf
+(F) 5.53921 Tj
+15 TJm
+(or) 8.29885 Tj
+-273 TJm
+(v) 4.9813 Tj
+15 TJm
+(ery) 12.7222 Tj
+-273 TJm
+(simple) 26.5703 Tj
+-273 TJm
+(needs,) 25.1755 Tj
+[1 0 0 1 165.929 193.765] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -165.929 -193.765] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+165.929 193.765 Td
+/F134_0 9.9626 Tf
+(BZ2_bzBuffToBuffCompress) 143.461 Tj
+[1 0 0 1 309.391 193.765] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -309.391 -193.765] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+312.112 193.765 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 329.219 193.765] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -329.219 -193.765] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+329.219 193.765 Td
+/F134_0 9.9626 Tf
+(BZ2_bzBuffToBuffDecompress) 155.417 Tj
+[1 0 0 1 484.636 193.765] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -484.636 -193.765] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+487.357 193.765 Td
+/F130_0 9.9626 Tf
+(are) 12.1643 Tj
+-273 TJm
+(pro) 13.2801 Tj
+15 TJm
+(vided.) 24.6275 Tj
+72 181.81 Td
+(These) 23.7907 Tj
+-374 TJm
+(compress) 37.6287 Tj
+-373 TJm
+(data) 16.5977 Tj
+-374 TJm
+(in) 7.7509 Tj
+-373 TJm
+(memory) 33.2053 Tj
+-374 TJm
+(from) 19.3673 Tj
+-373 TJm
+(one) 14.386 Tj
+-374 TJm
+(b) 4.9813 Tj
+20 TJm
+(uf) 8.29885 Tj
+25 TJm
+(fer) 11.0585 Tj
+-373 TJm
+(to) 7.7509 Tj
+-374 TJm
+(another) 29.8778 Tj
+-374 TJm
+(b) 4.9813 Tj
+20 TJm
+(uf) 8.29885 Tj
+25 TJm
+(fer) 11.0585 Tj
+-373 TJm
+(in) 7.7509 Tj
+-374 TJm
+(a) 4.42339 Tj
+-373 TJm
+(single) 23.8007 Tj
+-374 TJm
+(function) 33.2053 Tj
+-373 TJm
+(call.) 16.8766 Tj
+-1362 TJm
+(Y) 7.193 Tj
+110 TJm
+(ou) 9.9626 Tj
+-373 TJm
+(should) 26.5703 Tj
+-374 TJm
+(assess) 24.3486 Tj
+72 169.855 Td
+(whether) 32.0895 Tj
+-344 TJm
+(these) 20.4731 Tj
+-343 TJm
+(functions) 37.0808 Tj
+-344 TJm
+(ful\002ll) 22.1469 Tj
+-344 TJm
+(your) 18.2614 Tj
+-343 TJm
+(memory-to-memory) 80.7967 Tj
+-344 TJm
+(compression/decompression) 112.896 Tj
+-343 TJm
+(requirements) 52.0147 Tj
+-344 TJm
+(before) 25.4445 Tj
+-344 TJm
+(in) 7.7509 Tj
+40 TJm
+(v) 4.9813 Tj
+15 TJm
+(esting) 23.8007 Tj
+72 157.9 Td
+(ef) 7.74094 Tj
+25 TJm
+(fort) 14.386 Tj
+-250 TJm
+(in) 7.7509 Tj
+-250 TJm
+(understanding) 56.4481 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(more) 20.4731 Tj
+-250 TJm
+(general) 29.3199 Tj
+-250 TJm
+(b) 4.9813 Tj
+20 TJm
+(ut) 7.7509 Tj
+-250 TJm
+(more) 20.4731 Tj
+-250 TJm
+(comple) 29.3299 Tj
+15 TJm
+(x) 4.9813 Tj
+-250 TJm
+(lo) 7.7509 Tj
+25 TJm
+(w-le) 17.7035 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(el) 7.193 Tj
+-250 TJm
+(interf) 21.579 Tj
+10 TJm
+(ace.) 15.7608 Tj
+[1 0 0 1 72 155.743] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -145.78] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 135.982 Td
+/F130_0 9.9626 Tf
+(Y) 7.193 Tj
+110 TJm
+(oshioka) 30.9936 Tj
+-423 TJm
+(Tsuneo) 29.3299 Tj
+-422 TJm
+(\() 3.31755 Tj
+[1 0 0 1 150.16 135.982] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -150.16 -135.982] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+150.16 135.982 Td
+/F134_0 9.9626 Tf
+(tsuneo@rr.iij4u.or.jp) 125.529 Tj
+[1 0 0 1 275.69 135.982] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -275.69 -135.982] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+275.69 135.982 Td
+/F130_0 9.9626 Tf
+(\)) 3.31755 Tj
+-423 TJm
+(has) 13.2801 Tj
+-422 TJm
+(contrib) 28.224 Tj
+20 TJm
+(uted) 17.1556 Tj
+-423 TJm
+(some) 21.031 Tj
+-423 TJm
+(functions) 37.0808 Tj
+-422 TJm
+(to) 7.7509 Tj
+-423 TJm
+(gi) 7.7509 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-423 TJm
+(better) 22.6848 Tj
+[1 0 0 1 476.462 135.982] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -476.462 -135.982] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+476.462 135.982 Td
+/F134_0 9.9626 Tf
+(zlib) 23.9102 Tj
+[1 0 0 1 500.372 135.982] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -500.372 -135.982] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+504.583 135.982 Td
+/F130_0 9.9626 Tf
+(compati-) 35.417 Tj
+72 124.027 Td
+(bility) 21.041 Tj
+65 TJm
+(.) 2.49065 Tj
+-1446 TJm
+(These) 23.7907 Tj
+-388 TJm
+(functions) 37.0808 Tj
+-387 TJm
+(are) 12.1643 Tj
+[1 0 0 1 193.913 124.027] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -193.913 -124.027] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+193.913 124.027 Td
+/F134_0 9.9626 Tf
+(BZ2_bzopen) 59.7756 Tj
+[1 0 0 1 253.689 124.027] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -253.689 -124.027] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+253.689 124.027 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 260.385 124.027] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -260.385 -124.027] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+260.385 124.027 Td
+/F134_0 9.9626 Tf
+(BZ2_bzread) 59.7756 Tj
+[1 0 0 1 320.161 124.027] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -320.161 -124.027] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+320.161 124.027 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 326.857 124.027] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -326.857 -124.027] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+326.857 124.027 Td
+/F134_0 9.9626 Tf
+(BZ2_bzwrite) 65.7532 Tj
+[1 0 0 1 392.611 124.027] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -392.611 -124.027] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+392.611 124.027 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 399.306 124.027] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -399.306 -124.027] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+399.306 124.027 Td
+/F134_0 9.9626 Tf
+(BZ2_bzflush) 65.7532 Tj
+[1 0 0 1 465.06 124.027] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -465.06 -124.027] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+465.06 124.027 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 471.756 124.027] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -471.756 -124.027] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+471.756 124.027 Td
+/F134_0 9.9626 Tf
+(BZ2_bzclose) 65.7532 Tj
+[1 0 0 1 537.509 124.027] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -537.509 -124.027] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+537.509 124.027 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 72 112.072] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -112.072] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 112.072 Td
+/F134_0 9.9626 Tf
+(BZ2_bzerror) 65.7532 Tj
+[1 0 0 1 137.753 112.072] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -137.753 -112.072] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+140.408 112.072 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 157.449 112.072] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -157.449 -112.072] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+157.449 112.072 Td
+/F134_0 9.9626 Tf
+(BZ2_bzlibVersion) 95.641 Tj
+[1 0 0 1 253.091 112.072] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -253.091 -112.072] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+253.091 112.072 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+-719 TJm
+(Y) 7.193 Tj
+110 TJm
+(ou) 9.9626 Tj
+-266 TJm
+(may) 17.1556 Tj
+-267 TJm
+(\002nd) 15.5018 Tj
+-266 TJm
+(these) 20.4731 Tj
+-267 TJm
+(functions) 37.0808 Tj
+-266 TJm
+(more) 20.4731 Tj
+-267 TJm
+(con) 14.386 Tj
+40 TJm
+(v) 4.9813 Tj
+15 TJm
+(enient) 24.3486 Tj
+-266 TJm
+(for) 11.6164 Tj
+-267 TJm
+(simple) 26.5703 Tj
+-266 TJm
+(\002le) 12.7322 Tj
+-267 TJm
+(reading) 29.8778 Tj
+72 100.117 Td
+(and) 14.386 Tj
+-270 TJm
+(wri) 13.2801 Tj
+1 TJm
+(ting,) 17.9925 Tj
+-275 TJm
+(than) 17.1556 Tj
+-269 TJm
+(those) 21.031 Tj
+-270 TJm
+(in) 7.7509 Tj
+-269 TJm
+(the) 12.1743 Tj
+-270 TJm
+(high-le) 28.224 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(el) 7.193 Tj
+-269 TJm
+(interf) 21.579 Tj
+10 TJm
+(ace.) 15.7608 Tj
+-737 TJm
+(These) 23.7907 Tj
+-270 TJm
+(functions) 37.0808 Tj
+-269 TJm
+(are) 12.1643 Tj
+-270 TJm
+(not) 12.7322 Tj
+-269 TJm
+(\(yet\)) 18.8094 Tj
+-270 TJm
+(of) 8.29885 Tj
+25 TJm
+(\002cially) 27.6761 Tj
+-269 TJm
+(part) 15.4918 Tj
+-270 TJm
+(of) 8.29885 Tj
+-269 TJm
+(the) 12.1743 Tj
+-270 TJm
+(library) 26.5603 Tj
+65 TJm
+(,) 2.49065 Tj
+-274 TJm
+(and) 14.386 Tj
+-270 TJm
+(are) 12.1643 Tj
+72 88.1614 Td
+(minimally) 40.9662 Tj
+-291 TJm
+(documented) 48.6972 Tj
+-291 TJm
+(here.) 19.6363 Tj
+-867 TJm
+(If) 6.63509 Tj
+-291 TJm
+(the) 12.1743 Tj
+15 TJm
+(y) 4.9813 Tj
+-291 TJm
+(break,) 24.6176 Tj
+-301 TJm
+(you) 14.9439 Tj
+-291 TJm
+(get) 12.1743 Tj
+-292 TJm
+(to) 7.7509 Tj
+-291 TJm
+(k) 4.9813 Tj
+10 TJm
+(eep) 13.8281 Tj
+-291 TJm
+(all) 9.9626 Tj
+-291 TJm
+(the) 12.1743 Tj
+-291 TJm
+(pieces.) 27.3872 Tj
+-433 TJm
+(I) 3.31755 Tj
+-291 TJm
+(hope) 19.3673 Tj
+-291 TJm
+(to) 7.7509 Tj
+-291 TJm
+(document) 39.2925 Tj
+-292 TJm
+(them) 19.9252 Tj
+-291 TJm
+(properly) 33.7533 Tj
+-291 TJm
+(when) 21.579 Tj
+72 76.2062 Td
+(time) 17.7135 Tj
+-250 TJm
+(permits.) 32.3785 Tj
+[1 0 0 1 72 74.0494] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -23.1976] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 4.3836 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 374.394 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 6.9737] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 43.0633 -6.7545] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -498.225 -51.071] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+541.288 51.071 Td
+/F130_0 9.9626 Tf
+(9) 4.9813 Tj
+[1 0 0 1 455.161 50.8518] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 93.5986 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.2765 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -15.0366 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+Q
+showpage
+%%PageTrailer
+pdfEndPage
+%%Page: 13 13
+%%BeginPageSetup
+%%PageOrientation: Portrait
+pdfStartPage
+0 0 612 792 re W
+%%EndPageSetup
+[] 0 d
+1 i
+0 j
+0 J
+10 M
+1 w
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+false op
+false OP
+0 0 612 792 re
+W
+q
+[1 0 0 1 72 741.554] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 14.4459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 187.197 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 -8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 76.4979 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -342.569 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+419.067 749.245 Td
+/F130_0 9.9626 Tf
+(Programming) 54.7943 Tj
+-250 TJm
+(with) 17.7135 Tj
+[1 0 0 1 496.556 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -496.556 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+496.556 749.245 Td
+/F134_0 9.9626 Tf
+(libbzip2) 47.8205 Tj
+[1 0 0 1 544.376 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -278.305 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 280.796 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -472.974 -5.0363] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -0.4981] cm
+q
+[] 0 d
+0 J
+0.4981 w
+0 0.2491 m
+475.465 0.2491 l
+S
+Q
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 479.251 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -21.5542] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -720] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 710.037 Td
+/F130_0 9.9626 Tf
+(Y) 7.193 Tj
+110 TJm
+(oshioka) 30.9936 Tj
+-250 TJm
+(also) 16.0497 Tj
+-250 TJm
+(contrib) 28.224 Tj
+20 TJm
+(uted) 17.1556 Tj
+-250 TJm
+(modi\002cations) 54.2464 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(allo) 14.9439 Tj
+25 TJm
+(w) 7.193 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(library) 26.5603 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(be) 9.40469 Tj
+-250 TJm
+(b) 4.9813 Tj
+20 TJm
+(uilt) 13.2901 Tj
+-250 TJm
+(as) 8.29885 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(W) 9.40469 Tj
+40 TJm
+(indo) 17.7135 Tj
+25 TJm
+(ws) 11.0684 Tj
+-250 TJm
+(DLL.) 21.8579 Tj
+[1 0 0 1 72 707.88] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7436] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -698.137] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 675.504 Td
+/F122_0 20.6585 Tf
+(3.2.) 34.4584 Tj
+-278 TJm
+(Err) 29.8515 Tj
+20 TJm
+(or) 20.6585 Tj
+-278 TJm
+(handling) 86.084 Tj
+[1 0 0 1 72 670.907] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7436] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -661.164] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 653.805 Td
+/F130_0 9.9626 Tf
+(The) 15.4918 Tj
+-214 TJm
+(library) 26.5603 Tj
+-215 TJm
+(is) 6.64505 Tj
+-214 TJm
+(designed) 35.417 Tj
+-215 TJm
+(to) 7.7509 Tj
+-214 TJm
+(reco) 17.1456 Tj
+15 TJm
+(v) 4.9813 Tj
+15 TJm
+(er) 7.74094 Tj
+-215 TJm
+(cleanly) 28.772 Tj
+-214 TJm
+(in) 7.7509 Tj
+-215 TJm
+(all) 9.9626 Tj
+-214 TJm
+(situations,) 40.6873 Tj
+-222 TJm
+(including) 37.6387 Tj
+-214 TJm
+(the) 12.1743 Tj
+-215 TJm
+(w) 7.193 Tj
+10 TJm
+(orst-case) 35.4071 Tj
+-214 TJm
+(situation) 34.3212 Tj
+-215 TJm
+(of) 8.29885 Tj
+-214 TJm
+(decompressing) 59.7656 Tj
+-215 TJm
+(random) 30.4357 Tj
+72 641.85 Td
+(data.) 19.0883 Tj
+-764 TJm
+(I'm) 14.386 Tj
+-274 TJm
+(not) 12.7322 Tj
+-275 TJm
+(100%) 23.2427 Tj
+-274 TJm
+(sure) 16.5977 Tj
+-274 TJm
+(that) 14.9439 Tj
+-274 TJm
+(it) 5.53921 Tj
+-274 TJm
+(can) 13.8281 Tj
+-274 TJm
+(al) 7.193 Tj
+10 TJm
+(w) 7.193 Tj
+10 TJm
+(ays) 13.2801 Tj
+-274 TJm
+(do) 9.9626 Tj
+-274 TJm
+(this,) 16.8866 Tj
+-280 TJm
+(so) 8.85675 Tj
+-274 TJm
+(you) 14.9439 Tj
+-274 TJm
+(might) 23.2527 Tj
+-274 TJm
+(w) 7.193 Tj
+10 TJm
+(ant) 12.1743 Tj
+-274 TJm
+(to) 7.7509 Tj
+-274 TJm
+(add) 14.386 Tj
+-274 TJm
+(a) 4.42339 Tj
+-275 TJm
+(s) 3.87545 Tj
+1 TJm
+(ignal) 19.9252 Tj
+-275 TJm
+(handler) 29.8778 Tj
+-274 TJm
+(to) 7.7509 Tj
+-274 TJm
+(catch) 21.0211 Tj
+-274 TJm
+(se) 8.29885 Tj
+15 TJm
+(gmentation) 44.8317 Tj
+72 629.894 Td
+(violations) 39.3025 Tj
+-273 TJm
+(during) 26.0123 Tj
+-273 TJm
+(decompression) 59.7656 Tj
+-273 TJm
+(if) 6.08715 Tj
+-273 TJm
+(you) 14.9439 Tj
+-273 TJm
+(are) 12.1643 Tj
+-273 TJm
+(feeling) 27.6661 Tj
+-274 TJm
+(especiall) 34.8591 Tj
+1 TJm
+(y) 4.9813 Tj
+-274 TJm
+(paranoid.) 37.3498 Tj
+-758 TJm
+(I) 3.31755 Tj
+-273 TJm
+(w) 7.193 Tj
+10 TJm
+(ould) 17.7135 Tj
+-273 TJm
+(be) 9.40469 Tj
+-273 TJm
+(interested) 38.7346 Tj
+-273 TJm
+(in) 7.7509 Tj
+-274 TJm
+(hearing) 29.8778 Tj
+-273 TJm
+(more) 20.4731 Tj
+-273 TJm
+(about) 22.1369 Tj
+72 617.939 Td
+(the) 12.1743 Tj
+-250 TJm
+(rob) 13.2801 Tj
+20 TJm
+(ustness) 28.782 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(library) 26.5603 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(corrupted) 38.1767 Tj
+-250 TJm
+(compressed) 47.0334 Tj
+-250 TJm
+(data.) 19.0883 Tj
+[1 0 0 1 72 615.783] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7436] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -606.039] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 596.241 Td
+/F130_0 9.9626 Tf
+(V) 7.193 Tj
+111 TJm
+(ersion) 24.3486 Tj
+-251 TJm
+(1.0.3) 19.9252 Tj
+-251 TJm
+(more) 20.4731 Tj
+-251 TJm
+(rob) 13.2801 Tj
+20 TJm
+(ust) 11.6264 Tj
+-251 TJm
+(in) 7.7509 Tj
+-251 TJm
+(this) 14.396 Tj
+-251 TJm
+(respect) 28.2141 Tj
+-252 TJm
+(than) 17.1556 Tj
+-251 TJm
+(an) 9.40469 Tj
+15 TJm
+(y) 4.9813 Tj
+-251 TJm
+(pre) 12.7222 Tj
+25 TJm
+(vious) 21.589 Tj
+-251 TJm
+(v) 4.9813 Tj
+15 TJm
+(ersion.) 26.8392 Tj
+-626 TJm
+(In) 8.29885 Tj
+40 TJm
+(v) 4.9813 Tj
+15 TJm
+(estig) 18.8194 Tj
+5 TJm
+(ations) 23.8007 Tj
+-251 TJm
+(with) 17.7135 Tj
+-251 TJm
+(V) 7.193 Tj
+111 TJm
+(algrind) 28.224 Tj
+-251 TJm
+(\(a) 7.74094 Tj
+-252 TJm
+(tool) 15.5018 Tj
+-251 TJm
+(for) 11.6164 Tj
+-251 TJm
+(detecting) 36.5229 Tj
+72 584.285 Td
+(problems) 37.0808 Tj
+-422 TJm
+(with) 17.7135 Tj
+-421 TJm
+(memory) 33.2053 Tj
+-422 TJm
+(management\)) 54.2264 Tj
+-421 TJm
+(indicate) 31.5416 Tj
+-422 TJm
+(that,) 17.4346 Tj
+-464 TJm
+(at) 7.193 Tj
+-422 TJm
+(least) 18.2614 Tj
+-421 TJm
+(for) 11.6164 Tj
+-422 TJm
+(the) 12.1743 Tj
+-422 TJm
+(f) 3.31755 Tj
+1 TJm
+(e) 4.42339 Tj
+25 TJm
+(w) 7.193 Tj
+-422 TJm
+(\002les) 16.6077 Tj
+-422 TJm
+(I) 3.31755 Tj
+-421 TJm
+(tested,) 25.7334 Tj
+-464 TJm
+(all) 9.9626 Tj
+-422 TJm
+(single-bit) 37.6387 Tj
+-422 TJm
+(errors) 23.2328 Tj
+-421 TJm
+(in) 7.7509 Tj
+-422 TJm
+(the) 12.1743 Tj
+72 572.33 Td
+(decompressed) 56.4381 Tj
+-342 TJm
+(data) 16.5977 Tj
+-341 TJm
+(are) 12.1643 Tj
+-342 TJm
+(caught) 26.5603 Tj
+-342 TJm
+(properly) 33.7533 Tj
+65 TJm
+(,) 2.49065 Tj
+-365 TJm
+(with) 17.7135 Tj
+-341 TJm
+(no) 9.9626 Tj
+-342 TJm
+(se) 8.29885 Tj
+15 TJm
+(gmentation) 44.8317 Tj
+-342 TJm
+(f) 3.31755 Tj
+10 TJm
+(aults,) 21.31 Tj
+-365 TJm
+(no) 9.9626 Tj
+-341 TJm
+(uses) 17.1556 Tj
+-342 TJm
+(of) 8.29885 Tj
+-342 TJm
+(uninitialised) 49.2651 Tj
+-342 TJm
+(data,) 19.0883 Tj
+-364 TJm
+(no) 9.9626 Tj
+-342 TJm
+(out) 12.7322 Tj
+-342 TJm
+(of) 8.29885 Tj
+-342 TJm
+(range) 22.1269 Tj
+72 560.375 Td
+(reads) 21.0211 Tj
+-261 TJm
+(or) 8.29885 Tj
+-260 TJm
+(writes,) 26.8392 Tj
+-263 TJm
+(and) 14.386 Tj
+-261 TJm
+(no) 9.9626 Tj
+-261 TJm
+(in\002nit) 23.8106 Tj
+1 TJm
+(e) 4.42339 Tj
+-261 TJm
+(looping) 30.4457 Tj
+-261 TJm
+(in) 7.7509 Tj
+-260 TJm
+(the) 12.1743 Tj
+-261 TJm
+(decompressor) 55.3323 Tj
+55 TJm
+(.) 2.49065 Tj
+-342 TJm
+(So) 10.5205 Tj
+-260 TJm
+(it') 8.85675 Tj
+55 TJm
+(s) 3.87545 Tj
+-261 TJm
+(certainly) 34.8591 Tj
+-260 TJm
+(pretty) 23.2427 Tj
+-261 TJm
+(rob) 13.2801 Tj
+20 TJm
+(ust,) 14.117 Tj
+-263 TJm
+(although) 34.8691 Tj
+-261 TJm
+(I) 3.31755 Tj
+-260 TJm
+(w) 7.193 Tj
+10 TJm
+(ouldn') 26.0123 Tj
+18 TJm
+(t) 2.7696 Tj
+-261 TJm
+(claim) 22.1369 Tj
+72 548.42 Td
+(it) 5.53921 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(be) 9.40469 Tj
+-250 TJm
+(totally) 25.4644 Tj
+-250 TJm
+(bombproof.) 46.7644 Tj
+[1 0 0 1 72 546.263] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7436] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -536.519] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 526.721 Td
+/F130_0 9.9626 Tf
+(The) 15.4918 Tj
+-282 TJm
+(\002le) 12.7322 Tj
+[1 0 0 1 105.84 526.721] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -105.84 -526.721] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+105.84 526.721 Td
+/F134_0 9.9626 Tf
+(bzlib.h) 41.8429 Tj
+[1 0 0 1 147.683 526.721] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -147.683 -526.721] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+150.491 526.721 Td
+/F130_0 9.9626 Tf
+(contains) 33.2053 Tj
+-282 TJm
+(all) 9.9626 Tj
+-282 TJm
+(de\002nitions) 42.0721 Tj
+-282 TJm
+(nee) 13.8281 Tj
+1 TJm
+(ded) 14.386 Tj
+-282 TJm
+(to) 7.7509 Tj
+-282 TJm
+(use) 13.2801 Tj
+-282 TJm
+(the) 12.1743 Tj
+-282 TJm
+(library) 26.5603 Tj
+65 TJm
+(.) 2.49065 Tj
+-811 TJm
+(In) 8.29885 Tj
+-282 TJm
+(particular) 38.1767 Tj
+40 TJm
+(,) 2.49065 Tj
+-290 TJm
+(you) 14.9439 Tj
+-282 TJm
+(should) 26.5703 Tj
+-281 TJm
+(de\002nitely) 37.6387 Tj
+-282 TJm
+(not) 12.7322 Tj
+-282 TJm
+(include) 29.3299 Tj
+[1 0 0 1 72 514.766] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -514.766] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 514.766 Td
+/F134_0 9.9626 Tf
+(bzlib_private.h) 89.6634 Tj
+[1 0 0 1 161.664 514.766] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -161.664 -514.766] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+161.664 514.766 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+[1 0 0 1 72 513.232] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7436] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -503.488] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 493.067 Td
+/F130_0 9.9626 Tf
+(In) 8.29885 Tj
+[1 0 0 1 82.8075 493.067] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -82.8075 -493.067] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+82.8075 493.067 Td
+/F134_0 9.9626 Tf
+(bzlib.h) 41.8429 Tj
+[1 0 0 1 124.651 493.067] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -124.651 -493.067] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+124.651 493.067 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-252 TJm
+(the) 12.1743 Tj
+-252 TJm
+(v) 4.9813 Tj
+25 TJm
+(arious) 24.3486 Tj
+-252 TJm
+(return) 23.7907 Tj
+-252 TJm
+(v) 4.9813 Tj
+25 TJm
+(alues) 20.4731 Tj
+-251 TJm
+(are) 12.1643 Tj
+-252 TJm
+(de\002ned.) 31.8205 Tj
+-631 TJm
+(The) 15.4918 Tj
+-252 TJm
+(follo) 18.8194 Tj
+25 TJm
+(wing) 19.9252 Tj
+-252 TJm
+(list) 12.1843 Tj
+-251 TJm
+(is) 6.64505 Tj
+-252 TJm
+(not) 12.7322 Tj
+-252 TJm
+(intended) 34.3112 Tj
+-252 TJm
+(as) 8.29885 Tj
+-252 TJm
+(an) 9.40469 Tj
+-251 TJm
+(e) 4.42339 Tj
+15 TJm
+(xhausti) 28.782 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-252 TJm
+(description) 44.2738 Tj
+-252 TJm
+(of) 8.29885 Tj
+72 481.112 Td
+(the) 12.1743 Tj
+-236 TJm
+(circumstances) 56.4381 Tj
+-236 TJm
+(in) 7.7509 Tj
+-237 TJm
+(which) 24.3486 Tj
+-236 TJm
+(a) 4.42339 Tj
+-236 TJm
+(gi) 7.7509 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(en) 9.40469 Tj
+-236 TJm
+(v) 4.9813 Tj
+25 TJm
+(alue) 16.5977 Tj
+-236 TJm
+(may) 17.1556 Tj
+-237 TJm
+(be) 9.40469 Tj
+-236 TJm
+(returned) 33.1954 Tj
+-236 TJm
+(--) 6.63509 Tj
+-236 TJm
+(those) 21.031 Tj
+-236 TJm
+(descriptions) 48.1492 Tj
+-236 TJm
+(are) 12.1643 Tj
+-237 TJm
+(gi) 7.7509 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(en) 9.40469 Tj
+-236 TJm
+(later) 17.7035 Tj
+55 TJm
+(.) 2.49065 Tj
+-305 TJm
+(Rather) 26.5603 Tj
+40 TJm
+(,) 2.49065 Tj
+-239 TJm
+(it) 5.53921 Tj
+-236 TJm
+(is) 6.64505 Tj
+-237 TJm
+(intended) 34.3112 Tj
+-236 TJm
+(to) 7.7509 Tj
+72 469.157 Td
+(con) 14.386 Tj
+40 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+15 TJm
+(y) 4.9813 Tj
+-266 TJm
+(the) 12.1743 Tj
+-265 TJm
+(rough) 23.2427 Tj
+-266 TJm
+(meaning) 34.3112 Tj
+-265 TJm
+(of) 8.29885 Tj
+-266 TJm
+(each) 18.2515 Tj
+-266 TJm
+(return) 23.7907 Tj
+-265 TJm
+(v) 4.9813 Tj
+25 TJm
+(alue.) 19.0883 Tj
+-714 TJm
+(The) 15.4918 Tj
+-265 TJm
+(\002rst) 15.5018 Tj
+-266 TJm
+(\002) 5.53921 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-265 TJm
+(actions) 28.224 Tj
+-266 TJm
+(are) 12.1643 Tj
+-266 TJm
+(normal) 28.224 Tj
+-265 TJm
+(and) 14.386 Tj
+-266 TJm
+(not) 12.7322 Tj
+-265 TJm
+(intended) 34.3112 Tj
+-266 TJm
+(to) 7.7509 Tj
+-266 TJm
+(denote) 26.5603 Tj
+-265 TJm
+(an) 9.40469 Tj
+-266 TJm
+(error) 19.3573 Tj
+72 457.202 Td
+(situation.) 36.8118 Tj
+[1 0 0 1 72 457.102] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7436] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7435] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -437.615] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 425.76 Td
+/F134_0 9.9626 Tf
+(BZ_OK) 29.8878 Tj
+[1 0 0 1 101.888 425.76] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -32.3786 -1.3101] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -424.449] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+108 413.804 Td
+/F130_0 9.9626 Tf
+(The) 15.4918 Tj
+-250 TJm
+(requested) 38.1767 Tj
+-250 TJm
+(action) 24.3486 Tj
+-250 TJm
+(w) 7.193 Tj
+10 TJm
+(as) 8.29885 Tj
+-250 TJm
+(completed) 41.5042 Tj
+-250 TJm
+(successfully) 48.6972 Tj
+65 TJm
+(.) 2.49065 Tj
+[1 0 0 1 72 411.648] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -3.766] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7436] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -398.138] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 388.34 Td
+/F134_0 9.9626 Tf
+(BZ_RUN_OK,) 59.7756 Tj
+-600 TJm
+(BZ_FLUSH_OK,) 71.7307 Tj
+-600 TJm
+(BZ_FINISH_OK) 71.7307 Tj
+[1 0 0 1 287.193 388.34] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -217.684 -1.31] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -387.03] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+108 376.384 Td
+/F130_0 9.9626 Tf
+(In) 8.29885 Tj
+[1 0 0 1 118.79 376.384] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -118.79 -376.384] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+118.79 376.384 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompress) 83.6858 Tj
+[1 0 0 1 202.476 376.384] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -202.476 -376.384] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+202.476 376.384 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(requested) 38.1767 Tj
+-250 TJm
+(\003ush/\002nish/nothing-special) 108.493 Tj
+-250 TJm
+(action) 24.3486 Tj
+-250 TJm
+(w) 7.193 Tj
+10 TJm
+(as) 8.29885 Tj
+-250 TJm
+(completed) 41.5042 Tj
+-250 TJm
+(successfully) 48.6972 Tj
+65 TJm
+(.) 2.49065 Tj
+[1 0 0 1 72 374.228] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -3.7659] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7436] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -360.718] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 350.92 Td
+/F134_0 9.9626 Tf
+(BZ_STREAM_END) 77.7083 Tj
+[1 0 0 1 149.709 350.92] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -80.1993 -1.31] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -349.61] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+108 338.965 Td
+/F130_0 9.9626 Tf
+(Compression) 52.5826 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(data) 16.5977 Tj
+-250 TJm
+(w) 7.193 Tj
+10 TJm
+(as) 8.29885 Tj
+-250 TJm
+(completed,) 43.9948 Tj
+-250 TJm
+(or) 8.29885 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(logical) 27.1182 Tj
+-250 TJm
+(stream) 26.5603 Tj
+-250 TJm
+(end) 14.386 Tj
+-250 TJm
+(w) 7.193 Tj
+10 TJm
+(as) 8.29885 Tj
+-250 TJm
+(detected) 33.1954 Tj
+-250 TJm
+(during) 26.0123 Tj
+-250 TJm
+(decompression.) 62.2563 Tj
+[1 0 0 1 72 336.808] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -3.7659] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7436] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7436] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -313.555] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 303.756 Td
+/F130_0 9.9626 Tf
+(The) 15.4918 Tj
+-250 TJm
+(follo) 18.8194 Tj
+25 TJm
+(wing) 19.9252 Tj
+-250 TJm
+(return) 23.7907 Tj
+-250 TJm
+(v) 4.9813 Tj
+25 TJm
+(alues) 20.4731 Tj
+-250 TJm
+(indicate) 31.5416 Tj
+-250 TJm
+(an) 9.40469 Tj
+-250 TJm
+(error) 19.3573 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(some) 21.031 Tj
+-250 TJm
+(kind.) 20.2042 Tj
+[1 0 0 1 72 301.6] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7436] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7436] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -282.112] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 272.314 Td
+/F134_0 9.9626 Tf
+(BZ_CONFIG_ERROR) 89.6634 Tj
+[1 0 0 1 161.664 272.314] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -92.1544 -1.31] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -271.004] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+108 260.359 Td
+/F130_0 9.9626 Tf
+(Indicates) 35.965 Tj
+-386 TJm
+(that) 14.9439 Tj
+-385 TJm
+(the) 12.1743 Tj
+-386 TJm
+(library) 26.5603 Tj
+-386 TJm
+(has) 13.2801 Tj
+-386 TJm
+(been) 18.8094 Tj
+-385 TJm
+(improperly) 44.2738 Tj
+-386 TJm
+(compiled) 37.0808 Tj
+-386 TJm
+(on) 9.9626 Tj
+-386 TJm
+(your) 18.2614 Tj
+-385 TJm
+(platform) 34.3112 Tj
+-386 TJm
+(--) 6.63509 Tj
+-386 TJm
+(a) 4.42339 Tj
+-386 TJm
+(major) 23.2427 Tj
+-385 TJm
+(con\002guration) 53.1305 Tj
+-386 TJm
+(error) 19.3573 Tj
+55 TJm
+(.) 2.49065 Tj
+108 248.404 Td
+(Speci\002cally) 47.0434 Tj
+65 TJm
+(,) 2.49065 Tj
+-481 TJm
+(it) 5.53921 Tj
+-435 TJm
+(means) 25.4544 Tj
+-435 TJm
+(that) 14.9439 Tj
+[1 0 0 1 220.614 248.404] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -220.614 -248.404] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+220.614 248.404 Td
+/F134_0 9.9626 Tf
+(sizeof\(char\)) 71.7307 Tj
+[1 0 0 1 292.345 248.404] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -292.345 -248.404] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+292.345 248.404 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 299.628 248.404] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -299.628 -248.404] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+299.628 248.404 Td
+/F134_0 9.9626 Tf
+(sizeof\(short\)) 77.7083 Tj
+[1 0 0 1 377.337 248.404] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -377.337 -248.404] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+381.669 248.404 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 400.388 248.404] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -400.388 -248.404] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+400.388 248.404 Td
+/F134_0 9.9626 Tf
+(sizeof\(int\)) 65.7532 Tj
+[1 0 0 1 466.141 248.404] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -466.141 -248.404] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+470.474 248.404 Td
+/F130_0 9.9626 Tf
+(are) 12.1643 Tj
+-435 TJm
+(not) 12.7322 Tj
+-435 TJm
+(1,) 7.47195 Tj
+-481 TJm
+(2) 4.9813 Tj
+-435 TJm
+(and) 14.386 Tj
+108 236.449 Td
+(4) 4.9813 Tj
+-389 TJm
+(respecti) 30.9837 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(ely) 12.1743 Tj
+65 TJm
+(,) 2.49065 Tj
+-424 TJm
+(as) 8.29885 Tj
+-390 TJm
+(the) 12.1743 Tj
+15 TJm
+(y) 4.9813 Tj
+-389 TJm
+(should) 26.5703 Tj
+-389 TJm
+(be.) 11.8953 Tj
+-1456 TJm
+(Note) 19.3673 Tj
+-389 TJm
+(that) 14.9439 Tj
+-389 TJm
+(the) 12.1743 Tj
+-389 TJm
+(library) 26.5603 Tj
+-390 TJm
+(should) 26.5703 Tj
+-389 TJm
+(still) 14.9539 Tj
+-389 TJm
+(w) 7.193 Tj
+10 TJm
+(ork) 13.2801 Tj
+-389 TJm
+(properly) 33.7533 Tj
+-390 TJm
+(on) 9.9626 Tj
+-389 TJm
+(64-bit) 23.8007 Tj
+-389 TJm
+(platforms) 38.1866 Tj
+108 224.493 Td
+(which) 24.3486 Tj
+-292 TJm
+(follo) 18.8194 Tj
+25 TJm
+(w) 7.193 Tj
+-292 TJm
+(the) 12.1743 Tj
+-292 TJm
+(LP64) 21.589 Tj
+-292 TJm
+(programming) 54.2364 Tj
+-293 TJm
+(model) 24.9065 Tj
+-292 TJm
+(--) 6.63509 Tj
+-292 TJm
+(that) 14.9439 Tj
+-292 TJm
+(is,) 9.1357 Tj
+-303 TJm
+(where) 24.3386 Tj
+[1 0 0 1 355.279 224.493] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -355.279 -224.493] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+355.279 224.493 Td
+/F134_0 9.9626 Tf
+(sizeof\(long\)) 71.7307 Tj
+[1 0 0 1 427.01 224.493] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -427.01 -224.493] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+429.92 224.493 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 447.217 224.493] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -447.217 -224.493] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+447.217 224.493 Td
+/F134_0 9.9626 Tf
+(sizeof\(void) 65.7532 Tj
+512.97 222.75 Td
+(*) 5.97756 Tj
+518.948 224.493 Td
+(\)) 5.97756 Tj
+[1 0 0 1 524.925 224.493] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -524.925 -224.493] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+527.836 224.493 Td
+/F130_0 9.9626 Tf
+(are) 12.1643 Tj
+108 212.538 Td
+(8.) 7.47195 Tj
+-620 TJm
+(Under) 24.8965 Tj
+-250 TJm
+(LP64,) 24.0796 Tj
+[1 0 0 1 175.606 212.538] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -175.606 -212.538] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+175.606 212.538 Td
+/F134_0 9.9626 Tf
+(sizeof\(int\)) 65.7532 Tj
+[1 0 0 1 241.36 212.538] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -241.36 -212.538] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+243.85 212.538 Td
+/F130_0 9.9626 Tf
+(is) 6.64505 Tj
+-250 TJm
+(still) 14.9539 Tj
+-250 TJm
+(4,) 7.47195 Tj
+-250 TJm
+(so) 8.85675 Tj
+[1 0 0 1 291.74 212.538] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -291.74 -212.538] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+291.74 212.538 Td
+/F134_0 9.9626 Tf
+(libbzip2) 47.8205 Tj
+[1 0 0 1 339.56 212.538] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -339.56 -212.538] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+339.56 212.538 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-250 TJm
+(which) 24.3486 Tj
+-250 TJm
+(doesn') 26.5603 Tj
+18 TJm
+(t) 2.7696 Tj
+-250 TJm
+(use) 13.2801 Tj
+-250 TJm
+(the) 12.1743 Tj
+[1 0 0 1 433.458 212.538] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -433.458 -212.538] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+433.458 212.538 Td
+/F134_0 9.9626 Tf
+(long) 23.9102 Tj
+[1 0 0 1 457.368 212.538] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -457.368 -212.538] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+459.859 212.538 Td
+/F130_0 9.9626 Tf
+(type,) 19.6462 Tj
+-250 TJm
+(is) 6.64505 Tj
+-250 TJm
+(OK.) 16.8766 Tj
+[1 0 0 1 72 210.381] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -3.7659] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7436] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -196.872] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 187.074 Td
+/F134_0 9.9626 Tf
+(BZ_SEQUENCE_ERROR) 101.619 Tj
+[1 0 0 1 173.619 187.074] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -104.11 -1.31] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -185.764] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+108 175.118 Td
+/F130_0 9.9626 Tf
+(When) 23.7907 Tj
+-291 TJm
+(using) 21.589 Tj
+-290 TJm
+(the) 12.1743 Tj
+-291 TJm
+(library) 26.5603 Tj
+65 TJm
+(,) 2.49065 Tj
+-300 TJm
+(it) 5.53921 Tj
+-291 TJm
+(is) 6.64505 Tj
+-290 TJm
+(important) 38.7446 Tj
+-291 TJm
+(to) 7.7509 Tj
+-290 TJm
+(call) 14.386 Tj
+-291 TJm
+(the) 12.1743 Tj
+-290 TJm
+(functions) 37.0808 Tj
+-291 TJm
+(in) 7.7509 Tj
+-290 TJm
+(the) 12.1743 Tj
+-291 TJm
+(correct) 27.6562 Tj
+-290 TJm
+(sequence) 36.5129 Tj
+-291 TJm
+(and) 14.386 Tj
+-290 TJm
+(with) 17.7135 Tj
+-291 TJm
+(data) 16.5977 Tj
+-290 TJm
+(structures) 38.7346 Tj
+108 163.163 Td
+(\(b) 8.29885 Tj
+20 TJm
+(uf) 8.29885 Tj
+25 TJm
+(fers) 14.9339 Tj
+-206 TJm
+(etc\)) 14.9339 Tj
+-205 TJm
+(in) 7.7509 Tj
+-206 TJm
+(the) 12.1743 Tj
+-205 TJm
+(correct) 27.6562 Tj
+-206 TJm
+(states.) 24.6275 Tj
+[1 0 0 1 239.409 163.163] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -239.409 -163.163] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+239.409 163.163 Td
+/F134_0 9.9626 Tf
+(libbzip2) 47.8205 Tj
+[1 0 0 1 287.23 163.163] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -287.23 -163.163] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+289.278 163.163 Td
+/F130_0 9.9626 Tf
+(checks) 27.1082 Tj
+-206 TJm
+(as) 8.29885 Tj
+-205 TJm
+(much) 22.1369 Tj
+-206 TJm
+(as) 8.29885 Tj
+-205 TJm
+(it) 5.53921 Tj
+-206 TJm
+(can) 13.8281 Tj
+-206 TJm
+(to) 7.7509 Tj
+-205 TJm
+(ensure) 26.0024 Tj
+-206 TJm
+(this) 14.396 Tj
+-206 TJm
+(is) 6.64505 Tj
+-205 TJm
+(happening,) 43.9948 Tj
+-215 TJm
+(and) 14.386 Tj
+-205 TJm
+(returns) 27.6661 Tj
+[1 0 0 1 108 151.208] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -108 -151.208] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+108 151.208 Td
+/F134_0 9.9626 Tf
+(BZ_SEQUENCE_ERROR) 101.619 Tj
+[1 0 0 1 209.619 151.208] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -209.619 -151.208] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+213.27 151.208 Td
+/F130_0 9.9626 Tf
+(if) 6.08715 Tj
+-367 TJm
+(not.) 15.2229 Tj
+-659 TJm
+(Code) 21.031 Tj
+-367 TJm
+(which) 24.3486 Tj
+-367 TJm
+(complies) 35.9749 Tj
+-366 TJm
+(precisely) 35.965 Tj
+-367 TJm
+(with) 17.7135 Tj
+-366 TJm
+(the) 12.1743 Tj
+-367 TJm
+(function) 33.2053 Tj
+-366 TJm
+(semantics,) 41.7831 Tj
+-396 TJm
+(as) 8.29885 Tj
+-367 TJm
+(detailed) 31.5416 Tj
+108 139.253 Td
+(belo) 17.1556 Tj
+25 TJm
+(w) 7.193 Tj
+65 TJm
+(,) 2.49065 Tj
+-250 TJm
+(should) 26.5703 Tj
+-250 TJm
+(ne) 9.40469 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(er) 7.74094 Tj
+-250 TJm
+(recei) 19.3573 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-250 TJm
+(this) 14.396 Tj
+-250 TJm
+(v) 4.9813 Tj
+25 TJm
+(alue;) 19.3673 Tj
+-250 TJm
+(such) 18.2614 Tj
+-250 TJm
+(an) 9.40469 Tj
+-250 TJm
+(e) 4.42339 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(ent) 12.1743 Tj
+-250 TJm
+(denotes) 30.4357 Tj
+-250 TJm
+(b) 4.9813 Tj
+20 TJm
+(uggy) 19.9252 Tj
+-250 TJm
+(code) 18.8094 Tj
+-250 TJm
+(which) 24.3486 Tj
+-250 TJm
+(you) 14.9439 Tj
+-250 TJm
+(should) 26.5703 Tj
+-250 TJm
+(in) 7.7509 Tj
+40 TJm
+(v) 4.9813 Tj
+15 TJm
+(estig) 18.8194 Tj
+5 TJm
+(ate.) 14.107 Tj
+[1 0 0 1 72 137.096] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -3.7659] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7436] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -123.587] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 113.788 Td
+/F134_0 9.9626 Tf
+(BZ_PARAM_ERROR) 83.6858 Tj
+[1 0 0 1 155.686 113.788] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -86.1768 -1.31] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -112.478] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+108 101.833 Td
+/F130_0 9.9626 Tf
+(Returned) 36.5229 Tj
+-434 TJm
+(when) 21.579 Tj
+-434 TJm
+(a) 4.42339 Tj
+-434 TJm
+(parameter) 39.8305 Tj
+-434 TJm
+(to) 7.7509 Tj
+-434 TJm
+(a) 4.42339 Tj
+-433 TJm
+(function) 33.2053 Tj
+-434 TJm
+(call) 14.386 Tj
+-434 TJm
+(is) 6.64505 Tj
+-434 TJm
+(out) 12.7322 Tj
+-434 TJm
+(of) 8.29885 Tj
+-434 TJm
+(range) 22.1269 Tj
+-434 TJm
+(or) 8.29885 Tj
+-434 TJm
+(otherwise) 38.7346 Tj
+-434 TJm
+(manifestly) 42.0621 Tj
+-434 TJm
+(incorrect.) 37.8977 Tj
+-1723 TJm
+(As) 11.0684 Tj
+108 89.8778 Td
+(with) 17.7135 Tj
+[1 0 0 1 131.644 89.8778] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -131.644 -89.8778] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+131.644 89.8778 Td
+/F134_0 9.9626 Tf
+(BZ_SEQUENCE_ERROR) 101.619 Tj
+[1 0 0 1 233.263 89.8778] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -233.263 -89.8778] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+233.263 89.8778 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-595 TJm
+(this) 14.396 Tj
+-596 TJm
+(denotes) 30.4357 Tj
+-595 TJm
+(a) 4.42339 Tj
+-595 TJm
+(b) 4.9813 Tj
+20 TJm
+(ug) 9.9626 Tj
+-596 TJm
+(in) 7.7509 Tj
+-595 TJm
+(the) 12.1743 Tj
+-595 TJm
+(client) 22.1369 Tj
+-595 TJm
+(code.) 21.3 Tj
+-2692 TJm
+(The) 15.4918 Tj
+-596 TJm
+(distinction) 42.0721 Tj
+-595 TJm
+(between) 33.1954 Tj
+[1 0 0 1 108 77.9227] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -108 -77.9227] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+108 77.9227 Td
+/F134_0 9.9626 Tf
+(BZ_PARAM_ERROR) 83.6858 Tj
+[1 0 0 1 191.686 77.9227] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -191.686 -77.9227] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+194.177 77.9227 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 211.053 77.9227] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -211.053 -77.9227] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+211.053 77.9227 Td
+/F134_0 9.9626 Tf
+(BZ_SEQUENCE_ERROR) 101.619 Tj
+[1 0 0 1 312.672 77.9227] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -312.672 -77.9227] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+315.163 77.9227 Td
+/F130_0 9.9626 Tf
+(is) 6.64505 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(bit) 10.5205 Tj
+-250 TJm
+(hazy) 18.8094 Tj
+65 TJm
+(,) 2.49065 Tj
+-250 TJm
+(b) 4.9813 Tj
+20 TJm
+(ut) 7.7509 Tj
+-250 TJm
+(still) 14.9539 Tj
+-250 TJm
+(w) 7.193 Tj
+10 TJm
+(orth) 16.0497 Tj
+-250 TJm
+(making.) 32.3785 Tj
+[1 0 0 1 72 75.7659] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -3.7659] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -21.1482] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 374.394 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 6.8541] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 40.5726 -6.7545] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -493.841 -50.9514] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+534.414 50.9514 Td
+/F130_0 9.9626 Tf
+(10) 9.9626 Tj
+[1 0 0 1 453.269 50.8518] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 93.5985 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.2765 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+Q
+showpage
+%%PageTrailer
+pdfEndPage
+%%Page: 14 14
+%%BeginPageSetup
+%%PageOrientation: Portrait
+pdfStartPage
+0 0 612 792 re W
+%%EndPageSetup
+[] 0 d
+1 i
+0 j
+0 J
+10 M
+1 w
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+false op
+false OP
+0 0 612 792 re
+W
+q
+[1 0 0 1 72 741.554] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 14.4459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 187.197 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 -8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 76.4979 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -342.569 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+419.067 749.245 Td
+/F130_0 9.9626 Tf
+(Programming) 54.7943 Tj
+-250 TJm
+(with) 17.7135 Tj
+[1 0 0 1 496.556 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -496.556 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+496.556 749.245 Td
+/F134_0 9.9626 Tf
+(libbzip2) 47.8205 Tj
+[1 0 0 1 544.376 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -278.305 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 280.796 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -472.974 -5.0363] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -0.4981] cm
+q
+[] 0 d
+0 J
+0.4981 w
+0 0.2491 m
+475.465 0.2491 l
+S
+Q
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 479.251 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -21.5542] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -720] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 710.037 Td
+/F134_0 9.9626 Tf
+(BZ_MEM_ERROR) 71.7307 Tj
+[1 0 0 1 143.731 710.037] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -74.2217 -1.31] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -708.727] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+108 698.082 Td
+/F130_0 9.9626 Tf
+(Returned) 36.5229 Tj
+-228 TJm
+(when) 21.579 Tj
+-227 TJm
+(a) 4.42339 Tj
+-228 TJm
+(request) 28.772 Tj
+-227 TJm
+(to) 7.7509 Tj
+-228 TJm
+(allocate) 30.9837 Tj
+-228 TJm
+(memory) 33.2053 Tj
+-227 TJm
+(f) 3.31755 Tj
+10 TJm
+(ailed.) 21.8579 Tj
+-605 TJm
+(Note) 19.3673 Tj
+-228 TJm
+(that) 14.9439 Tj
+-228 TJm
+(the) 12.1743 Tj
+-227 TJm
+(quantity) 32.6574 Tj
+-228 TJm
+(of) 8.29885 Tj
+-227 TJm
+(memory) 33.2053 Tj
+-228 TJm
+(needed) 28.2141 Tj
+-228 TJm
+(to) 7.7509 Tj
+-227 TJm
+(decompress) 47.0334 Tj
+108 686.127 Td
+(a) 4.42339 Tj
+-351 TJm
+(stream) 26.5603 Tj
+-352 TJm
+(cannot) 26.5603 Tj
+-351 TJm
+(be) 9.40469 Tj
+-352 TJm
+(determined) 44.8217 Tj
+-351 TJm
+(until) 18.2714 Tj
+-352 TJm
+(the) 12.1743 Tj
+-351 TJm
+(stream') 29.8778 Tj
+55 TJm
+(s) 3.87545 Tj
+-351 TJm
+(header) 26.5503 Tj
+-352 TJm
+(has) 13.2801 Tj
+-351 TJm
+(been) 18.8094 Tj
+-352 TJm
+(read.) 19.6363 Tj
+-1228 TJm
+(So) 10.5205 Tj
+[1 0 0 1 426.471 686.127] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -426.471 -686.127] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+426.471 686.127 Td
+/F134_0 9.9626 Tf
+(BZ2_bzDecompress) 95.641 Tj
+[1 0 0 1 522.113 686.127] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -522.113 -686.127] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+525.614 686.127 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 108 674.172] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -108 -674.172] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+108 674.172 Td
+/F134_0 9.9626 Tf
+(BZ2_bzRead) 59.7756 Tj
+[1 0 0 1 167.776 674.172] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -167.776 -674.172] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+172.13 674.172 Td
+/F130_0 9.9626 Tf
+(may) 17.1556 Tj
+-437 TJm
+(return) 23.7907 Tj
+[1 0 0 1 221.784 674.172] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -221.784 -674.172] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+221.784 674.172 Td
+/F134_0 9.9626 Tf
+(BZ_MEM_ERROR) 71.7307 Tj
+[1 0 0 1 293.515 674.172] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -293.515 -674.172] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+297.867 674.172 Td
+/F130_0 9.9626 Tf
+(e) 4.42339 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(en) 9.40469 Tj
+-437 TJm
+(though) 27.6761 Tj
+-437 TJm
+(some) 21.031 Tj
+-437 TJm
+(of) 8.29885 Tj
+-437 TJm
+(the) 12.1743 Tj
+-437 TJm
+(compressed) 47.0334 Tj
+-437 TJm
+(data) 16.5977 Tj
+-437 TJm
+(has) 13.2801 Tj
+-437 TJm
+(been) 18.8094 Tj
+-437 TJm
+(read.) 19.6363 Tj
+108 662.217 Td
+(The) 15.4918 Tj
+-479 TJm
+(same) 20.4731 Tj
+-478 TJm
+(is) 6.64505 Tj
+-479 TJm
+(not) 12.7322 Tj
+-478 TJm
+(true) 15.4918 Tj
+-479 TJm
+(for) 11.6164 Tj
+-479 TJm
+(compression;) 53.1305 Tj
+-593 TJm
+(once) 18.8094 Tj
+[1 0 0 1 301.675 662.217] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -301.675 -662.217] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+301.675 662.217 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompressInit) 107.596 Tj
+[1 0 0 1 409.271 662.217] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -409.271 -662.217] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+414.04 662.217 Td
+/F130_0 9.9626 Tf
+(or) 8.29885 Tj
+[1 0 0 1 427.107 662.217] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -427.107 -662.217] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+427.107 662.217 Td
+/F134_0 9.9626 Tf
+(BZ2_bzWriteOpen) 89.6634 Tj
+[1 0 0 1 516.771 662.217] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -516.771 -662.217] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+521.539 662.217 Td
+/F130_0 9.9626 Tf
+(ha) 9.40469 Tj
+20 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+108 650.262 Td
+(successfully) 48.6972 Tj
+-250 TJm
+(completed,) 43.9948 Tj
+[1 0 0 1 205.672 650.261] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -205.672 -650.261] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+205.672 650.261 Td
+/F134_0 9.9626 Tf
+(BZ_MEM_ERROR) 71.7307 Tj
+[1 0 0 1 277.403 650.261] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -277.403 -650.261] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+279.894 650.261 Td
+/F130_0 9.9626 Tf
+(cannot) 26.5603 Tj
+-250 TJm
+(occur) 22.1269 Tj
+55 TJm
+(.) 2.49065 Tj
+[1 0 0 1 72 648.105] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -3.985] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -634.157] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 624.359 Td
+/F134_0 9.9626 Tf
+(BZ_DATA_ERROR) 77.7083 Tj
+[1 0 0 1 149.709 624.359] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -80.1993 -1.31] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -623.049] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+108 612.404 Td
+/F130_0 9.9626 Tf
+(Returned) 36.5229 Tj
+-266 TJm
+(when) 21.579 Tj
+-265 TJm
+(a) 4.42339 Tj
+-266 TJm
+(data) 16.5977 Tj
+-265 TJm
+(inte) 14.9439 Tj
+15 TJm
+(grity) 18.8194 Tj
+-266 TJm
+(error) 19.3573 Tj
+-266 TJm
+(is) 6.64505 Tj
+-265 TJm
+(detected) 33.1954 Tj
+-266 TJm
+(during) 26.0123 Tj
+-265 TJm
+(decompression.) 62.2563 Tj
+-714 TJm
+(Most) 20.4831 Tj
+-266 TJm
+(importantl) 41.5142 Tj
+1 TJm
+(y) 4.9813 Tj
+64 TJm
+(,) 2.49065 Tj
+-269 TJm
+(this) 14.396 Tj
+-266 TJm
+(means) 25.4544 Tj
+-265 TJm
+(when) 21.579 Tj
+108 600.448 Td
+(stored) 24.3486 Tj
+-222 TJm
+(and) 14.386 Tj
+-223 TJm
+(computed) 39.2925 Tj
+-222 TJm
+(CRCs) 23.8106 Tj
+-222 TJm
+(for) 11.6164 Tj
+-222 TJm
+(the) 12.1743 Tj
+-223 TJm
+(data) 16.5977 Tj
+-222 TJm
+(do) 9.9626 Tj
+-222 TJm
+(not) 12.7322 Tj
+-222 TJm
+(match.) 26.8392 Tj
+-602 TJm
+(This) 17.7135 Tj
+-222 TJm
+(v) 4.9813 Tj
+25 TJm
+(alue) 16.5977 Tj
+-222 TJm
+(is) 6.64505 Tj
+-223 TJm
+(also) 16.0497 Tj
+-222 TJm
+(returned) 33.1954 Tj
+-222 TJm
+(upon) 19.9252 Tj
+-222 TJm
+(detection) 36.5229 Tj
+-223 TJm
+(of) 8.29885 Tj
+-222 TJm
+(an) 9.40469 Tj
+15 TJm
+(y) 4.9813 Tj
+-222 TJm
+(other) 20.4731 Tj
+108 588.493 Td
+(anomaly) 34.3112 Tj
+-250 TJm
+(in) 7.7509 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(compressed) 47.0334 Tj
+-250 TJm
+(data.) 19.0883 Tj
+[1 0 0 1 72 586.336] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -3.985] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -572.389] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 562.59 Td
+/F134_0 9.9626 Tf
+(BZ_DATA_ERROR_MAGIC) 113.574 Tj
+[1 0 0 1 185.574 562.59] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -116.065 -1.31] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -561.28] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+108 550.635 Td
+/F130_0 9.9626 Tf
+(As) 11.0684 Tj
+-306 TJm
+(a) 4.42339 Tj
+-306 TJm
+(special) 27.6661 Tj
+-306 TJm
+(case) 17.1456 Tj
+-307 TJm
+(of) 8.29885 Tj
+[1 0 0 1 191.852 550.635] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -191.852 -550.635] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+191.852 550.635 Td
+/F134_0 9.9626 Tf
+(BZ_DATA_ERROR) 77.7083 Tj
+[1 0 0 1 269.561 550.635] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -269.561 -550.635] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+269.561 550.635 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-306 TJm
+(it) 5.53921 Tj
+-306 TJm
+(is) 6.64505 Tj
+-306 TJm
+(sometimes) 42.62 Tj
+-307 TJm
+(usef) 16.5977 Tj
+1 TJm
+(ul) 7.7509 Tj
+-307 TJm
+(to) 7.7509 Tj
+-306 TJm
+(kno) 14.9439 Tj
+25 TJm
+(w) 7.193 Tj
+-306 TJm
+(when) 21.579 Tj
+-306 TJm
+(the) 12.1743 Tj
+-306 TJm
+(compressed) 47.0334 Tj
+-306 TJm
+(stream) 26.5603 Tj
+-306 TJm
+(does) 18.2614 Tj
+108 538.68 Td
+(not) 12.7322 Tj
+-250 TJm
+(start) 17.1556 Tj
+-250 TJm
+(with) 17.7135 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(correct) 27.6562 Tj
+-250 TJm
+(magic) 24.3486 Tj
+-250 TJm
+(bytes) 21.031 Tj
+-250 TJm
+(\() 3.31755 Tj
+[1 0 0 1 261.562 538.68] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -261.562 -538.68] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+261.562 538.68 Td
+/F134_0 9.9626 Tf
+('B') 17.9327 Tj
+-600 TJm
+('Z') 17.9327 Tj
+-600 TJm
+('h') 17.9327 Tj
+[1 0 0 1 327.316 538.68] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -327.316 -538.68] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+327.316 538.68 Td
+/F130_0 9.9626 Tf
+(\).) 5.8082 Tj
+[1 0 0 1 72 536.523] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -3.985] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -522.576] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 512.777 Td
+/F134_0 9.9626 Tf
+(BZ_IO_ERROR) 65.7532 Tj
+[1 0 0 1 137.753 512.777] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -68.2441 -1.3101] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -511.467] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+108 500.822 Td
+/F130_0 9.9626 Tf
+(Returned) 36.5229 Tj
+-233 TJm
+(by) 9.9626 Tj
+[1 0 0 1 159.123 500.822] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -159.123 -500.822] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+159.123 500.822 Td
+/F134_0 9.9626 Tf
+(BZ2_bzRead) 59.7756 Tj
+[1 0 0 1 218.899 500.822] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -218.899 -500.822] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+221.218 500.822 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 237.923 500.822] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -237.923 -500.822] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+237.923 500.822 Td
+/F134_0 9.9626 Tf
+(BZ2_bzWrite) 65.7532 Tj
+[1 0 0 1 303.676 500.822] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -303.676 -500.822] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+305.995 500.822 Td
+/F130_0 9.9626 Tf
+(when) 21.579 Tj
+-233 TJm
+(there) 19.9152 Tj
+-232 TJm
+(is) 6.64505 Tj
+-233 TJm
+(an) 9.40469 Tj
+-233 TJm
+(error) 19.3573 Tj
+-233 TJm
+(reading) 29.8778 Tj
+-232 TJm
+(or) 8.29885 Tj
+-233 TJm
+(writing) 28.782 Tj
+-233 TJm
+(in) 7.7509 Tj
+-233 TJm
+(the) 12.1743 Tj
+-232 TJm
+(compressed) 47.0334 Tj
+108 488.867 Td
+(\002le,) 15.2229 Tj
+-384 TJm
+(and) 14.386 Tj
+-357 TJm
+(by) 9.9626 Tj
+[1 0 0 1 158.511 488.867] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -158.511 -488.867] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+158.511 488.867 Td
+/F134_0 9.9626 Tf
+(BZ2_bzReadOpen) 83.6858 Tj
+[1 0 0 1 242.197 488.867] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -242.197 -488.867] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+245.755 488.867 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 263.698 488.867] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -263.698 -488.867] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+263.698 488.867 Td
+/F134_0 9.9626 Tf
+(BZ2_bzWriteOpen) 89.6634 Tj
+[1 0 0 1 353.362 488.867] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -353.362 -488.867] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+356.92 488.867 Td
+/F130_0 9.9626 Tf
+(for) 11.6164 Tj
+-357 TJm
+(attempts) 33.7633 Tj
+-357 TJm
+(to) 7.7509 Tj
+-357 TJm
+(use) 13.2801 Tj
+-357 TJm
+(a) 4.42339 Tj
+-357 TJm
+(\002le) 12.7322 Tj
+-357 TJm
+(for) 11.6164 Tj
+-358 TJm
+(which) 24.3486 Tj
+-357 TJm
+(the) 12.1743 Tj
+-357 TJm
+(error) 19.3573 Tj
+108 476.912 Td
+(indicator) 35.417 Tj
+-260 TJm
+(\(viz,) 17.9825 Tj
+[1 0 0 1 166.603 476.912] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -166.603 -476.912] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+166.603 476.912 Td
+/F134_0 9.9626 Tf
+(ferror\(f\)) 53.798 Tj
+[1 0 0 1 220.401 476.912] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -220.401 -476.912] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+220.401 476.912 Td
+/F130_0 9.9626 Tf
+(\)) 3.31755 Tj
+-260 TJm
+(is) 6.64505 Tj
+-260 TJm
+(set.) 13.5591 Tj
+-679 TJm
+(On) 12.1743 Tj
+-260 TJm
+(receipt) 27.1082 Tj
+-260 TJm
+(of) 8.29885 Tj
+[1 0 0 1 311.223 476.912] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -311.223 -476.912] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+311.223 476.912 Td
+/F134_0 9.9626 Tf
+(BZ_IO_ERROR) 65.7532 Tj
+[1 0 0 1 376.976 476.912] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -376.976 -476.912] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+376.976 476.912 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-260 TJm
+(the) 12.1743 Tj
+-260 TJm
+(caller) 22.1269 Tj
+-260 TJm
+(should) 26.5703 Tj
+-260 TJm
+(consult) 28.782 Tj
+[1 0 0 1 482.068 476.912] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -482.068 -476.912] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+482.068 476.912 Td
+/F134_0 9.9626 Tf
+(errno) 29.8878 Tj
+[1 0 0 1 511.956 476.912] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -511.956 -476.912] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+514.546 476.912 Td
+/F130_0 9.9626 Tf
+(and/or) 25.4544 Tj
+[1 0 0 1 108 464.957] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -108 -464.957] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+108 464.957 Td
+/F134_0 9.9626 Tf
+(perror) 35.8654 Tj
+[1 0 0 1 143.865 464.957] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -143.865 -464.957] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+146.356 464.957 Td
+/F130_0 9.9626 Tf
+(to) 7.7509 Tj
+-250 TJm
+(acquire) 29.3199 Tj
+-250 TJm
+(operating-system) 68.6224 Tj
+-250 TJm
+(speci\002c) 30.4357 Tj
+-250 TJm
+(information) 47.0434 Tj
+-250 TJm
+(about) 22.1369 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(problem.) 35.696 Tj
+[1 0 0 1 72 462.8] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -3.9849] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -448.852] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 439.054 Td
+/F134_0 9.9626 Tf
+(BZ_UNEXPECTED_EOF) 101.619 Tj
+[1 0 0 1 173.619 439.054] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -104.11 -1.31] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -437.744] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+108 427.099 Td
+/F130_0 9.9626 Tf
+(Returned) 36.5229 Tj
+-250 TJm
+(by) 9.9626 Tj
+[1 0 0 1 159.467 427.099] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -159.467 -427.099] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+159.467 427.099 Td
+/F134_0 9.9626 Tf
+(BZ2_bzRead) 59.7756 Tj
+[1 0 0 1 219.242 427.099] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -219.242 -427.099] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+221.733 427.099 Td
+/F130_0 9.9626 Tf
+(when) 21.579 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(compressed) 47.0334 Tj
+-250 TJm
+(\002le) 12.7322 Tj
+-250 TJm
+(\002nishes) 30.4457 Tj
+-250 TJm
+(before) 25.4445 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(logical) 27.1182 Tj
+-250 TJm
+(end) 14.386 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(stream) 26.5603 Tj
+-250 TJm
+(is) 6.64505 Tj
+-250 TJm
+(detected.) 35.686 Tj
+[1 0 0 1 72 424.942] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -3.985] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -410.994] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 401.196 Td
+/F134_0 9.9626 Tf
+(BZ_OUTBUFF_FULL) 89.6634 Tj
+[1 0 0 1 161.664 401.196] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -92.1544 -1.31] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -399.886] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+108 389.241 Td
+/F130_0 9.9626 Tf
+(Returned) 36.5229 Tj
+-258 TJm
+(by) 9.9626 Tj
+[1 0 0 1 159.632 389.241] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -159.632 -389.241] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+159.632 389.241 Td
+/F134_0 9.9626 Tf
+(BZ2_bzBuffToBuffCompress) 143.461 Tj
+[1 0 0 1 303.094 389.241] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -303.094 -389.241] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+305.668 389.241 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 322.627 389.241] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -322.627 -389.241] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+322.627 389.241 Td
+/F134_0 9.9626 Tf
+(BZ2_bzBuffToBuffDecompress) 155.417 Tj
+[1 0 0 1 478.044 389.241] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -478.044 -389.241] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+480.618 389.241 Td
+/F130_0 9.9626 Tf
+(to) 7.7509 Tj
+-258 TJm
+(indicate) 31.5416 Tj
+-259 TJm
+(that) 14.9439 Tj
+108 377.286 Td
+(the) 12.1743 Tj
+-250 TJm
+(output) 25.4644 Tj
+-250 TJm
+(data) 16.5977 Tj
+-250 TJm
+(will) 15.5018 Tj
+-250 TJm
+(not) 12.7322 Tj
+-250 TJm
+(\002t) 8.30881 Tj
+-250 TJm
+(into) 15.5018 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(output) 25.4644 Tj
+-250 TJm
+(b) 4.9813 Tj
+20 TJm
+(uf) 8.29885 Tj
+25 TJm
+(fer) 11.0585 Tj
+-250 TJm
+(pro) 13.2801 Tj
+15 TJm
+(vided.) 24.6275 Tj
+[1 0 0 1 72 375.129] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -3.985] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -351.218] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 328.585 Td
+/F122_0 20.6585 Tf
+(3.3.) 34.4584 Tj
+-278 TJm
+(Lo) 25.2447 Tj
+15 TJm
+(w-le) 40.1808 Tj
+15 TJm
+(vel) 28.7153 Tj
+-278 TJm
+(interface) 86.1046 Tj
+[1 0 0 1 72 328.327] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -318.364] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 297.964 Td
+/F122_0 17.2154 Tf
+(3.3.1.) 43.0729 Tj
+[1 0 0 1 119.858 297.964] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -119.858 -297.964] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+119.858 297.964 Td
+/F392_0 17.2154 Tf
+(BZ2_bzCompressInit) 185.926 Tj
+[1 0 0 1 305.785 297.964] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -233.785 -2.3327] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -244.779] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 374.394 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 40.5726 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -493.841 -50.8518] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+534.414 50.8518 Td
+/F130_0 9.9626 Tf
+(11) 9.9626 Tj
+[1 0 0 1 453.269 50.8518] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 93.5985 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.2765 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+Q
+showpage
+%%PageTrailer
+pdfEndPage
+%%Page: 15 15
+%%BeginPageSetup
+%%PageOrientation: Portrait
+pdfStartPage
+0 0 612 792 re W
+%%EndPageSetup
+[] 0 d
+1 i
+0 j
+0 J
+10 M
+1 w
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+false op
+false OP
+0 0 612 792 re
+W
+q
+[1 0 0 1 72 741.554] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 14.4459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 187.197 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 -8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 76.4979 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -342.569 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+419.067 749.245 Td
+/F130_0 9.9626 Tf
+(Programming) 54.7943 Tj
+-250 TJm
+(with) 17.7135 Tj
+[1 0 0 1 496.556 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -496.556 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+496.556 749.245 Td
+/F134_0 9.9626 Tf
+(libbzip2) 47.8205 Tj
+[1 0 0 1 544.376 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -278.305 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 280.796 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -472.974 -5.0363] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -0.4981] cm
+q
+[] 0 d
+0 J
+0.4981 w
+0 0.2491 m
+475.465 0.2491 l
+S
+Q
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 479.251 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -296.523] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 274.969 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 271.382] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -711.631] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 711.631 Td
+/F134_0 9.9626 Tf
+(typedef) 41.8429 Tj
+-426 TJm
+(struct) 35.8654 Tj
+-426 TJm
+({) 5.97756 Tj
+98.4879 699.676 Td
+(char) 23.9102 Tj
+126.642 697.933 Td
+(*) 5.97756 Tj
+132.62 699.676 Td
+(next_in;) 47.8205 Tj
+98.4879 687.721 Td
+(unsigned) 47.8205 Tj
+-426 TJm
+(int) 17.9327 Tj
+-426 TJm
+(avail_in;) 53.798 Tj
+98.4879 675.766 Td
+(unsigned) 47.8205 Tj
+-426 TJm
+(int) 17.9327 Tj
+-426 TJm
+(total_in_lo32;) 83.6858 Tj
+98.4879 663.811 Td
+(unsigned) 47.8205 Tj
+-426 TJm
+(int) 17.9327 Tj
+-426 TJm
+(total_in_hi32;) 83.6858 Tj
+98.4879 639.9 Td
+(char) 23.9102 Tj
+126.642 638.157 Td
+(*) 5.97756 Tj
+132.62 639.9 Td
+(next_out;) 53.798 Tj
+98.4879 627.945 Td
+(unsigned) 47.8205 Tj
+-426 TJm
+(int) 17.9327 Tj
+-426 TJm
+(avail_out;) 59.7756 Tj
+98.4879 615.99 Td
+(unsigned) 47.8205 Tj
+-426 TJm
+(int) 17.9327 Tj
+-426 TJm
+(total_out_lo32;) 89.6634 Tj
+98.4879 604.035 Td
+(unsigned) 47.8205 Tj
+-426 TJm
+(int) 17.9327 Tj
+-426 TJm
+(total_out_hi32;) 89.6634 Tj
+98.4879 580.125 Td
+(void) 23.9102 Tj
+126.642 578.381 Td
+(*) 5.97756 Tj
+132.62 580.125 Td
+(state;) 35.8654 Tj
+98.4879 556.214 Td
+(void) 23.9102 Tj
+126.642 554.471 Td
+(*) 5.97756 Tj
+132.62 556.214 Td
+(\() 5.97756 Tj
+138.597 554.471 Td
+(*) 5.97756 Tj
+144.575 556.214 Td
+(bzalloc\)\(void) 77.7083 Tj
+226.527 554.471 Td
+(*) 5.97756 Tj
+232.505 556.214 Td
+(,int,int\);) 59.7756 Tj
+98.4879 544.259 Td
+(void) 23.9102 Tj
+-426 TJm
+(\() 5.97756 Tj
+132.62 542.516 Td
+(*) 5.97756 Tj
+138.597 544.259 Td
+(bzfree\)\(void) 71.7307 Tj
+214.572 542.516 Td
+(*) 5.97756 Tj
+220.55 544.259 Td
+(,void) 29.8878 Tj
+254.682 542.516 Td
+(*) 5.97756 Tj
+260.659 544.259 Td
+(\);) 11.9551 Tj
+98.4879 532.304 Td
+(void) 23.9102 Tj
+126.642 530.56 Td
+(*) 5.97756 Tj
+132.62 532.304 Td
+(opaque;) 41.8429 Tj
+89.9999 520.349 Td
+(}) 5.97756 Tj
+-426 TJm
+(bz_stream;) 59.7756 Tj
+89.9999 496.438 Td
+(int) 17.9327 Tj
+-426 TJm
+(BZ2_bzCompressInit) 107.596 Tj
+-426 TJm
+(\() 5.97756 Tj
+-426 TJm
+(bz_stream) 53.798 Tj
+292.281 494.695 Td
+(*) 5.97756 Tj
+298.258 496.438 Td
+(strm,) 29.8878 Tj
+196.099 484.483 Td
+(int) 17.9327 Tj
+-426 TJm
+(blockSize100k,) 83.6858 Tj
+196.099 472.528 Td
+(int) 17.9327 Tj
+-426 TJm
+(verbosity,) 59.7756 Tj
+196.099 460.573 Td
+(int) 17.9327 Tj
+-426 TJm
+(workFactor) 59.7756 Tj
+-426 TJm
+(\);) 11.9551 Tj
+[1 0 0 1 72 445.031] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.5492] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -435.068] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 423.113 Td
+/F130_0 9.9626 Tf
+(Prepares) 34.3012 Tj
+-356 TJm
+(for) 11.6164 Tj
+-356 TJm
+(compression.) 52.8516 Tj
+-1256 TJm
+(The) 15.4918 Tj
+[1 0 0 1 209.409 423.113] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -209.409 -423.113] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+209.409 423.113 Td
+/F134_0 9.9626 Tf
+(bz_stream) 53.798 Tj
+[1 0 0 1 263.208 423.113] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -263.208 -423.113] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+266.754 423.113 Td
+/F130_0 9.9626 Tf
+(structure) 34.8591 Tj
+-356 TJm
+(holds) 21.589 Tj
+-356 TJm
+(all) 9.9626 Tj
+-356 TJm
+(data) 16.5977 Tj
+-356 TJm
+(pertaining) 40.3983 Tj
+-356 TJm
+(to) 7.7509 Tj
+-356 TJm
+(the) 12.1743 Tj
+-356 TJm
+(compression) 50.3609 Tj
+-355 TJm
+(acti) 14.386 Tj
+25 TJm
+(vity) 15.5018 Tj
+65 TJm
+(.) 2.49065 Tj
+-1256 TJm
+(A) 7.193 Tj
+[1 0 0 1 72 411.158] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -411.158] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 411.158 Td
+/F134_0 9.9626 Tf
+(bz_stream) 53.798 Tj
+[1 0 0 1 125.798 411.158] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -125.798 -411.158] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+128.581 411.158 Td
+/F130_0 9.9626 Tf
+(structure) 34.8591 Tj
+-279 TJm
+(should) 26.5703 Tj
+-280 TJm
+(be) 9.40469 Tj
+-279 TJm
+(allocated) 35.965 Tj
+-279 TJm
+(and) 14.386 Tj
+-280 TJm
+(initialised) 39.3025 Tj
+-279 TJm
+(prior) 19.3673 Tj
+-279 TJm
+(to) 7.7509 Tj
+-279 TJm
+(the) 12.1743 Tj
+-280 TJm
+(call.) 16.8766 Tj
+-796 TJm
+(The) 15.4918 Tj
+-279 TJm
+(\002elds) 21.589 Tj
+-279 TJm
+(of) 8.29885 Tj
+[1 0 0 1 431.939 411.158] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -431.939 -411.158] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+431.939 411.158 Td
+/F134_0 9.9626 Tf
+(bz_stream) 53.798 Tj
+[1 0 0 1 485.738 411.158] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -485.738 -411.158] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+488.52 411.158 Td
+/F130_0 9.9626 Tf
+(comprise) 36.5229 Tj
+-279 TJm
+(the) 12.1743 Tj
+72 399.203 Td
+(entirety) 30.4357 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(user) 16.5977 Tj
+20 TJm
+(-visible) 29.8878 Tj
+-250 TJm
+(data.) 19.0883 Tj
+[1 0 0 1 204.422 399.203] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -204.422 -399.203] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+204.422 399.203 Td
+/F134_0 9.9626 Tf
+(state) 29.8878 Tj
+[1 0 0 1 234.31 399.203] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -234.31 -399.203] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+236.8 399.203 Td
+/F130_0 9.9626 Tf
+(is) 6.64505 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(pointer) 28.224 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(pri) 11.0684 Tj
+25 TJm
+(v) 4.9813 Tj
+25 TJm
+(ate) 11.6164 Tj
+-250 TJm
+(data) 16.5977 Tj
+-250 TJm
+(structures) 38.7346 Tj
+-250 TJm
+(required) 33.1954 Tj
+-250 TJm
+(for) 11.6164 Tj
+-250 TJm
+(compression.) 52.8516 Tj
+[1 0 0 1 72 397.046] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -387.083] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 377.285 Td
+/F130_0 9.9626 Tf
+(Custom) 31.0036 Tj
+-372 TJm
+(memory) 33.2053 Tj
+-372 TJm
+(allocators) 38.7346 Tj
+-372 TJm
+(are) 12.1643 Tj
+-372 TJm
+(supported,) 41.7831 Tj
+-403 TJm
+(via) 12.1743 Tj
+-372 TJm
+(\002elds) 21.589 Tj
+[1 0 0 1 288.908 377.285] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -288.908 -377.285] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+288.908 377.285 Td
+/F134_0 9.9626 Tf
+(bzalloc) 41.8429 Tj
+[1 0 0 1 330.751 377.285] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -330.751 -377.285] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+330.751 377.285 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 337.253 377.285] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -337.253 -377.285] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+337.253 377.285 Td
+/F134_0 9.9626 Tf
+(bzfree) 35.8654 Tj
+[1 0 0 1 373.118 377.285] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -373.118 -377.285] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+373.118 377.285 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-403 TJm
+(and) 14.386 Tj
+[1 0 0 1 397.714 377.285] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -397.714 -377.285] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+397.714 377.285 Td
+/F134_0 9.9626 Tf
+(opaque) 35.8654 Tj
+[1 0 0 1 433.579 377.285] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -433.579 -377.285] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+433.579 377.285 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+-1353 TJm
+(The) 15.4918 Tj
+-372 TJm
+(v) 4.9813 Tj
+25 TJm
+(alue) 16.5977 Tj
+[1 0 0 1 493.782 377.285] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -493.782 -377.285] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+493.782 377.285 Td
+/F134_0 9.9626 Tf
+(opaque) 35.8654 Tj
+[1 0 0 1 529.648 377.285] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -529.648 -377.285] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+533.355 377.285 Td
+/F130_0 9.9626 Tf
+(is) 6.64505 Tj
+72 365.33 Td
+(passed) 26.5603 Tj
+-306 TJm
+(to) 7.7509 Tj
+-306 TJm
+(as) 8.29885 Tj
+-306 TJm
+(the) 12.1743 Tj
+-306 TJm
+(\002rst) 15.5018 Tj
+-306 TJm
+(ar) 7.74094 Tj
+18 TJm
+(gument) 29.8878 Tj
+-306 TJm
+(to) 7.7509 Tj
+-306 TJm
+(all) 9.9626 Tj
+-306 TJm
+(calls) 18.2614 Tj
+-305 TJm
+(to) 7.7509 Tj
+[1 0 0 1 253.941 365.33] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -253.941 -365.33] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+253.941 365.33 Td
+/F134_0 9.9626 Tf
+(bzalloc) 41.8429 Tj
+[1 0 0 1 295.784 365.33] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -295.784 -365.33] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+298.832 365.33 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 316.266 365.33] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -316.266 -365.33] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+316.266 365.33 Td
+/F134_0 9.9626 Tf
+(bzfree) 35.8654 Tj
+[1 0 0 1 352.132 365.33] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -352.132 -365.33] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+352.132 365.33 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-320 TJm
+(b) 4.9813 Tj
+20 TJm
+(ut) 7.7509 Tj
+-306 TJm
+(is) 6.64505 Tj
+-306 TJm
+(otherwise) 38.7346 Tj
+-306 TJm
+(ignored) 30.4357 Tj
+-306 TJm
+(by) 9.9626 Tj
+-306 TJm
+(the) 12.1743 Tj
+-306 TJm
+(library) 26.5603 Tj
+65 TJm
+(.) 2.49065 Tj
+-955 TJm
+(The) 15.4918 Tj
+72 353.375 Td
+(call) 14.386 Tj
+[1 0 0 1 89.4309 353.375] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -89.4309 -353.375] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+89.4309 353.375 Td
+/F134_0 9.9626 Tf
+(bzalloc) 41.8429 Tj
+-600 TJm
+(\() 5.97756 Tj
+-600 TJm
+(opaque,) 41.8429 Tj
+-600 TJm
+(n,) 11.9551 Tj
+-600 TJm
+(m) 5.97756 Tj
+-600 TJm
+(\)) 5.97756 Tj
+[1 0 0 1 232.893 353.375] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -232.893 -353.375] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+235.938 353.375 Td
+/F130_0 9.9626 Tf
+(is) 6.64505 Tj
+-306 TJm
+(e) 4.42339 Tj
+15 TJm
+(xpected) 30.9837 Tj
+-305 TJm
+(to) 7.7509 Tj
+-306 TJm
+(return) 23.7907 Tj
+-306 TJm
+(a) 4.42339 Tj
+-305 TJm
+(pointer) 28.224 Tj
+[1 0 0 1 360.3 353.375] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -360.3 -353.375] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+360.3 353.375 Td
+/F134_0 9.9626 Tf
+(p) 5.97756 Tj
+[1 0 0 1 366.277 353.375] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -366.277 -353.375] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+369.322 353.375 Td
+/F130_0 9.9626 Tf
+(to) 7.7509 Tj
+[1 0 0 1 380.118 353.375] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -380.118 -353.375] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+380.118 353.375 Td
+/F134_0 9.9626 Tf
+(n) 5.97756 Tj
+392.073 351.631 Td
+(*) 5.97756 Tj
+404.029 353.375 Td
+(m) 5.97756 Tj
+[1 0 0 1 410.006 353.375] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -410.006 -353.375] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+413.051 353.375 Td
+/F130_0 9.9626 Tf
+(bytes) 21.031 Tj
+-306 TJm
+(of) 8.29885 Tj
+-305 TJm
+(memory) 33.2053 Tj
+65 TJm
+(,) 2.49065 Tj
+-320 TJm
+(and) 14.386 Tj
+[1 0 0 1 504.135 353.375] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -504.135 -353.375] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+504.135 353.375 Td
+/F134_0 9.9626 Tf
+(bzfree) 35.8654 Tj
+72 341.42 Td
+(\() 5.97756 Tj
+-600 TJm
+(opaque,) 41.8429 Tj
+-600 TJm
+(p) 5.97756 Tj
+-600 TJm
+(\)) 5.97756 Tj
+[1 0 0 1 149.709 341.42] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -149.709 -341.42] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+152.199 341.42 Td
+/F130_0 9.9626 Tf
+(should) 26.5703 Tj
+-250 TJm
+(free) 15.4819 Tj
+-250 TJm
+(that) 14.9439 Tj
+-250 TJm
+(memory) 33.2053 Tj
+65 TJm
+(.) 2.49065 Tj
+[1 0 0 1 72 339.263] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -329.3] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 319.502 Td
+/F130_0 9.9626 Tf
+(If) 6.63509 Tj
+-280 TJm
+(you) 14.9439 Tj
+-280 TJm
+(don') 18.2614 Tj
+18 TJm
+(t) 2.7696 Tj
+-280 TJm
+(w) 7.193 Tj
+10 TJm
+(ant) 12.1743 Tj
+-279 TJm
+(to) 7.7509 Tj
+-280 TJm
+(use) 13.2801 Tj
+-280 TJm
+(a) 4.42339 Tj
+-280 TJm
+(custom) 28.782 Tj
+-280 TJm
+(memory) 33.2053 Tj
+-279 TJm
+(allocator) 34.8591 Tj
+40 TJm
+(,) 2.49065 Tj
+-288 TJm
+(set) 11.0684 Tj
+[1 0 0 1 299.9 319.502] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -299.9 -319.502] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+299.9 319.502 Td
+/F134_0 9.9626 Tf
+(bzalloc) 41.8429 Tj
+[1 0 0 1 341.743 319.502] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -341.743 -319.502] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+341.743 319.502 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 347.096 319.502] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -347.096 -319.502] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+347.096 319.502 Td
+/F134_0 9.9626 Tf
+(bzfree) 35.8654 Tj
+[1 0 0 1 382.961 319.502] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -382.961 -319.502] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+385.749 319.502 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 402.923 319.502] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -402.923 -319.502] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+402.923 319.502 Td
+/F134_0 9.9626 Tf
+(opaque) 35.8654 Tj
+[1 0 0 1 438.788 319.502] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -438.788 -319.502] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+441.576 319.502 Td
+/F130_0 9.9626 Tf
+(to) 7.7509 Tj
+[1 0 0 1 452.115 319.502] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -452.115 -319.502] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+452.115 319.502 Td
+/F134_0 9.9626 Tf
+(NULL) 23.9102 Tj
+[1 0 0 1 476.025 319.502] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -476.025 -319.502] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+476.025 319.502 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-280 TJm
+(and) 14.386 Tj
+-280 TJm
+(the) 12.1743 Tj
+-279 TJm
+(library) 26.5603 Tj
+72 307.547 Td
+(will) 15.5018 Tj
+-250 TJm
+(then) 17.1556 Tj
+-250 TJm
+(use) 13.2801 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(standard) 33.7533 Tj
+[1 0 0 1 176.318 307.547] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -176.318 -307.547] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+176.318 307.547 Td
+/F134_0 9.9626 Tf
+(malloc) 35.8654 Tj
+[1 0 0 1 212.183 307.547] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -212.183 -307.547] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+214.674 307.547 Td
+/F130_0 9.9626 Tf
+(/) 2.7696 Tj
+[1 0 0 1 219.934 307.547] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -219.934 -307.547] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+219.934 307.547 Td
+/F134_0 9.9626 Tf
+(free) 23.9102 Tj
+[1 0 0 1 243.844 307.547] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -243.844 -307.547] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+246.335 307.547 Td
+/F130_0 9.9626 Tf
+(routines.) 34.5901 Tj
+[1 0 0 1 72 307.392] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -297.43] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 285.629 Td
+/F130_0 9.9626 Tf
+(Before) 27.1082 Tj
+-362 TJm
+(calling) 27.1182 Tj
+[1 0 0 1 133.438 285.629] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -133.438 -285.629] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+133.438 285.629 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompressInit) 107.596 Tj
+[1 0 0 1 241.035 285.629] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -241.035 -285.629] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+241.035 285.629 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-390 TJm
+(\002elds) 21.589 Tj
+[1 0 0 1 272.606 285.629] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -272.606 -285.629] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+272.606 285.629 Td
+/F134_0 9.9626 Tf
+(bzalloc) 41.8429 Tj
+[1 0 0 1 314.449 285.629] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -314.449 -285.629] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+314.449 285.629 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 320.825 285.629] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -320.825 -285.629] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+320.825 285.629 Td
+/F134_0 9.9626 Tf
+(bzfree) 35.8654 Tj
+[1 0 0 1 356.69 285.629] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -356.69 -285.629] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+360.296 285.629 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 378.288 285.629] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -378.288 -285.629] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+378.288 285.629 Td
+/F134_0 9.9626 Tf
+(opaque) 35.8654 Tj
+[1 0 0 1 414.154 285.629] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -414.154 -285.629] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+417.76 285.629 Td
+/F130_0 9.9626 Tf
+(should) 26.5703 Tj
+-362 TJm
+(be) 9.40469 Tj
+-362 TJm
+(\002lled) 20.4831 Tj
+-362 TJm
+(appropriately) 53.1206 Tj
+65 TJm
+(,) 2.49065 Tj
+72 273.674 Td
+(as) 8.29885 Tj
+-322 TJm
+(just) 14.396 Tj
+-323 TJm
+(described.) 40.6673 Tj
+-1055 TJm
+(Upon) 22.1369 Tj
+-322 TJm
+(return,) 26.2813 Tj
+-341 TJm
+(the) 12.1743 Tj
+-322 TJm
+(internal) 30.4357 Tj
+-323 TJm
+(state) 18.2614 Tj
+-322 TJm
+(will) 15.5018 Tj
+-323 TJm
+(ha) 9.40469 Tj
+20 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-322 TJm
+(been) 18.8094 Tj
+-323 TJm
+(allocated) 35.965 Tj
+-322 TJm
+(and) 14.386 Tj
+-323 TJm
+(initialised,) 41.7931 Tj
+-340 TJm
+(and) 14.386 Tj
+[1 0 0 1 459.801 273.674] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -459.801 -273.674] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+459.801 273.674 Td
+/F134_0 9.9626 Tf
+(total_in_lo32) 77.7083 Tj
+[1 0 0 1 537.509 273.674] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -537.509 -273.674] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+537.509 273.674 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 72 261.718] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -261.718] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 261.718 Td
+/F134_0 9.9626 Tf
+(total_in_hi32) 77.7083 Tj
+[1 0 0 1 149.709 261.718] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -149.709 -261.718] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+149.709 261.718 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 155.006 261.718] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -155.006 -261.718] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+155.006 261.718 Td
+/F134_0 9.9626 Tf
+(total_out_lo32) 83.6858 Tj
+[1 0 0 1 238.692 261.718] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -238.692 -261.718] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+241.435 261.718 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 258.564 261.718] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -258.564 -261.718] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+258.564 261.718 Td
+/F134_0 9.9626 Tf
+(total_out_hi32) 83.6858 Tj
+[1 0 0 1 342.25 261.718] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -342.25 -261.718] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+344.994 261.718 Td
+/F130_0 9.9626 Tf
+(will) 15.5018 Tj
+-275 TJm
+(ha) 9.40469 Tj
+20 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-276 TJm
+(been) 18.8094 Tj
+-275 TJm
+(set) 11.0684 Tj
+-275 TJm
+(to) 7.7509 Tj
+-276 TJm
+(zero.) 19.6363 Tj
+-772 TJm
+(These) 23.7907 Tj
+-275 TJm
+(four) 16.5977 Tj
+-276 TJm
+(\002elds) 21.589 Tj
+-275 TJm
+(are) 12.1643 Tj
+72 249.763 Td
+(used) 18.2614 Tj
+-340 TJm
+(by) 9.9626 Tj
+-339 TJm
+(the) 12.1743 Tj
+-340 TJm
+(library) 26.5603 Tj
+-339 TJm
+(to) 7.7509 Tj
+-340 TJm
+(inform) 27.1182 Tj
+-339 TJm
+(the) 12.1743 Tj
+-340 TJm
+(caller) 22.1269 Tj
+-339 TJm
+(of) 8.29885 Tj
+-340 TJm
+(the) 12.1743 Tj
+-339 TJm
+(total) 17.7135 Tj
+-340 TJm
+(amount) 29.8878 Tj
+-339 TJm
+(of) 8.29885 Tj
+-340 TJm
+(data) 16.5977 Tj
+-340 TJm
+(passed) 26.5603 Tj
+-339 TJm
+(into) 15.5018 Tj
+-340 TJm
+(and) 14.386 Tj
+-339 TJm
+(out) 12.7322 Tj
+-340 TJm
+(of) 8.29885 Tj
+-339 TJm
+(the) 12.1743 Tj
+-340 TJm
+(library) 26.5603 Tj
+65 TJm
+(,) 2.49065 Tj
+-362 TJm
+(respecti) 30.9837 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(ely) 12.1743 Tj
+65 TJm
+(.) 2.49065 Tj
+72 237.808 Td
+(Y) 7.193 Tj
+110 TJm
+(ou) 9.9626 Tj
+-376 TJm
+(should) 26.5703 Tj
+-377 TJm
+(not) 12.7322 Tj
+-376 TJm
+(try) 11.0684 Tj
+-376 TJm
+(to) 7.7509 Tj
+-377 TJm
+(change) 28.2141 Tj
+-376 TJm
+(them.) 22.4159 Tj
+-1378 TJm
+(As) 11.0684 Tj
+-377 TJm
+(of) 8.29885 Tj
+-376 TJm
+(v) 4.9813 Tj
+15 TJm
+(ersion) 24.3486 Tj
+-377 TJm
+(1.0,) 14.9439 Tj
+-408 TJm
+(64-bit) 23.8007 Tj
+-376 TJm
+(counts) 26.0123 Tj
+-376 TJm
+(are) 12.1643 Tj
+-377 TJm
+(maintained,) 46.7644 Tj
+-408 TJm
+(e) 4.42339 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(en) 9.40469 Tj
+-376 TJm
+(on) 9.9626 Tj
+-376 TJm
+(32-bit) 23.8007 Tj
+-377 TJm
+(platforms,) 40.6773 Tj
+72 225.853 Td
+(using) 21.589 Tj
+-371 TJm
+(the) 12.1743 Tj
+[1 0 0 1 113.148 225.853] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -113.148 -225.853] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+113.148 225.853 Td
+/F134_0 9.9626 Tf
+(_hi32) 29.8878 Tj
+[1 0 0 1 143.036 225.853] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -143.036 -225.853] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+146.729 225.853 Td
+/F130_0 9.9626 Tf
+(\002elds) 21.589 Tj
+-371 TJm
+(to) 7.7509 Tj
+-370 TJm
+(store) 19.3673 Tj
+-371 TJm
+(the) 12.1743 Tj
+-371 TJm
+(upper) 22.6848 Tj
+-370 TJm
+(32) 9.9626 Tj
+-371 TJm
+(bits) 14.396 Tj
+-370 TJm
+(of) 8.29885 Tj
+-371 TJm
+(the) 12.1743 Tj
+-371 TJm
+(count.) 24.6275 Tj
+-1344 TJm
+(So,) 13.0112 Tj
+-400 TJm
+(for) 11.6164 Tj
+-371 TJm
+(e) 4.42339 Tj
+15 TJm
+(xample,) 31.8205 Tj
+-401 TJm
+(the) 12.1743 Tj
+-371 TJm
+(total) 17.7135 Tj
+-370 TJm
+(amount) 29.8878 Tj
+-371 TJm
+(of) 8.29885 Tj
+-370 TJm
+(data) 16.5977 Tj
+-371 TJm
+(in) 7.7509 Tj
+-371 TJm
+(is) 6.64505 Tj
+[1 0 0 1 72 213.898] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -213.898] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 213.898 Td
+/F134_0 9.9626 Tf
+(\(total_in_hi32) 83.6858 Tj
+-600 TJm
+(<<) 11.9551 Tj
+-600 TJm
+(32\)) 17.9327 Tj
+-600 TJm
+(+) 5.97756 Tj
+-600 TJm
+(total_in_lo32) 77.7083 Tj
+[1 0 0 1 293.171 213.898] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -293.171 -213.898] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+293.171 213.898 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+[1 0 0 1 72 212.588] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -202.625] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 191.98 Td
+/F130_0 9.9626 Tf
+(P) 5.53921 Tj
+15 TJm
+(arameter) 34.8492 Tj
+[1 0 0 1 115.367 191.98] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -115.367 -191.98] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+115.367 191.98 Td
+/F134_0 9.9626 Tf
+(blockSize100k) 77.7083 Tj
+[1 0 0 1 193.076 191.98] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -193.076 -191.98] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+196.204 191.98 Td
+/F130_0 9.9626 Tf
+(speci\002es) 34.3112 Tj
+-314 TJm
+(the) 12.1743 Tj
+-314 TJm
+(block) 22.1369 Tj
+-314 TJm
+(size) 15.4918 Tj
+-314 TJm
+(to) 7.7509 Tj
+-314 TJm
+(be) 9.40469 Tj
+-314 TJm
+(used) 18.2614 Tj
+-314 TJm
+(for) 11.6164 Tj
+-314 TJm
+(compression.) 52.8516 Tj
+-1004 TJm
+(It) 6.08715 Tj
+-314 TJm
+(should) 26.5703 Tj
+-314 TJm
+(be) 9.40469 Tj
+-315 TJm
+(a) 4.42339 Tj
+-314 TJm
+(v) 4.9813 Tj
+25 TJm
+(alue) 16.5977 Tj
+-314 TJm
+(between) 33.1954 Tj
+-314 TJm
+(1) 4.9813 Tj
+72 180.025 Td
+(and) 14.386 Tj
+-289 TJm
+(9) 4.9813 Tj
+-289 TJm
+(inclusi) 26.5703 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(e,) 6.91404 Tj
+-299 TJm
+(and) 14.386 Tj
+-289 TJm
+(the) 12.1743 Tj
+-289 TJm
+(actual) 23.7907 Tj
+-289 TJm
+(block) 22.1369 Tj
+-289 TJm
+(size) 15.4918 Tj
+-289 TJm
+(used) 18.2614 Tj
+-289 TJm
+(is) 6.64505 Tj
+-289 TJm
+(100000) 29.8878 Tj
+-289 TJm
+(x) 4.9813 Tj
+-289 TJm
+(this) 14.396 Tj
+-289 TJm
+(\002gure.) 25.7334 Tj
+-854 TJm
+(9) 4.9813 Tj
+-290 TJm
+(gi) 7.7509 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(es) 8.29885 Tj
+-289 TJm
+(the) 12.1743 Tj
+-289 TJm
+(best) 16.0497 Tj
+-289 TJm
+(compression) 50.3609 Tj
+-289 TJm
+(b) 4.9813 Tj
+20 TJm
+(ut) 7.7509 Tj
+-289 TJm
+(tak) 12.1743 Tj
+10 TJm
+(es) 8.29885 Tj
+-289 TJm
+(most) 19.3773 Tj
+72 168.07 Td
+(memory) 33.2053 Tj
+65 TJm
+(.) 2.49065 Tj
+[1 0 0 1 72 165.913] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -155.95] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 146.152 Td
+/F130_0 9.9626 Tf
+(P) 5.53921 Tj
+15 TJm
+(arameter) 34.8492 Tj
+[1 0 0 1 115.095 146.152] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -115.095 -146.152] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+115.095 146.152 Td
+/F134_0 9.9626 Tf
+(verbosity) 53.798 Tj
+[1 0 0 1 168.893 146.152] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -168.893 -146.152] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+171.75 146.152 Td
+/F130_0 9.9626 Tf
+(should) 26.5703 Tj
+-287 TJm
+(be) 9.40469 Tj
+-286 TJm
+(set) 11.0684 Tj
+-287 TJm
+(to) 7.7509 Tj
+-287 TJm
+(a) 4.42339 Tj
+-287 TJm
+(number) 30.4357 Tj
+-286 TJm
+(between) 33.1954 Tj
+-287 TJm
+(0) 4.9813 Tj
+-287 TJm
+(and) 14.386 Tj
+-287 TJm
+(4) 4.9813 Tj
+-286 TJm
+(inclusi) 26.5703 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(e.) 6.91404 Tj
+-841 TJm
+(0) 4.9813 Tj
+-286 TJm
+(is) 6.64505 Tj
+-287 TJm
+(silent,) 24.0796 Tj
+-296 TJm
+(and) 14.386 Tj
+-287 TJm
+(greater) 27.6562 Tj
+-287 TJm
+(numbers) 34.3112 Tj
+-286 TJm
+(gi) 7.7509 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+72 134.197 Td
+(increasingly) 48.6972 Tj
+-342 TJm
+(v) 4.9813 Tj
+15 TJm
+(erbose) 26.0024 Tj
+-342 TJm
+(monitoring/deb) 61.4394 Tj
+20 TJm
+(ugging) 27.6761 Tj
+-342 TJm
+(output.) 27.9551 Tj
+-1173 TJm
+(If) 6.63509 Tj
+-343 TJm
+(the) 12.1743 Tj
+-342 TJm
+(library) 26.5603 Tj
+-342 TJm
+(has) 13.2801 Tj
+-342 TJm
+(been) 18.8094 Tj
+-342 TJm
+(compiled) 37.0808 Tj
+-342 TJm
+(with) 17.7135 Tj
+[1 0 0 1 446.429 134.197] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -446.429 -134.197] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+446.429 134.197 Td
+/F134_0 9.9626 Tf
+(-DBZ_NO_STDIO) 77.7083 Tj
+[1 0 0 1 524.138 134.197] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -524.138 -134.197] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+524.138 134.197 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-342 TJm
+(no) 9.9626 Tj
+72 122.242 Td
+(such) 18.2614 Tj
+-250 TJm
+(output) 25.4644 Tj
+-250 TJm
+(will) 15.5018 Tj
+-250 TJm
+(appear) 26.5503 Tj
+-250 TJm
+(for) 11.6164 Tj
+-250 TJm
+(an) 9.40469 Tj
+15 TJm
+(y) 4.9813 Tj
+-250 TJm
+(v) 4.9813 Tj
+15 TJm
+(erbosity) 32.0995 Tj
+-250 TJm
+(setting.) 29.0609 Tj
+[1 0 0 1 72 120.085] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -110.122] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 100.324 Td
+/F130_0 9.9626 Tf
+(P) 5.53921 Tj
+15 TJm
+(arameter) 34.8492 Tj
+[1 0 0 1 116.619 100.324] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -116.619 -100.324] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+116.619 100.324 Td
+/F134_0 9.9626 Tf
+(workFactor) 59.7756 Tj
+[1 0 0 1 176.394 100.324] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -176.394 -100.324] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+180.775 100.324 Td
+/F130_0 9.9626 Tf
+(controls) 32.0995 Tj
+-440 TJm
+(ho) 9.9626 Tj
+25 TJm
+(w) 7.193 Tj
+-439 TJm
+(the) 12.1743 Tj
+-440 TJm
+(compression) 50.3609 Tj
+-440 TJm
+(phase) 22.6848 Tj
+-439 TJm
+(beha) 18.8094 Tj
+20 TJm
+(v) 4.9813 Tj
+15 TJm
+(es) 8.29885 Tj
+-440 TJm
+(when) 21.579 Tj
+-439 TJm
+(presented) 38.1767 Tj
+-440 TJm
+(with) 17.7135 Tj
+-440 TJm
+(w) 7.193 Tj
+10 TJm
+(orst) 14.9439 Tj
+-439 TJm
+(case,) 19.6363 Tj
+-487 TJm
+(highly) 25.4644 Tj
+72 88.3686 Td
+(repetiti) 28.224 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(e,) 6.91404 Tj
+-433 TJm
+(input) 20.4831 Tj
+-396 TJm
+(data.) 19.0883 Tj
+-1496 TJm
+(If) 6.63509 Tj
+-396 TJm
+(compression) 50.3609 Tj
+-396 TJm
+(runs) 17.1556 Tj
+-397 TJm
+(i) 2.7696 Tj
+1 TJm
+(nto) 12.7322 Tj
+-397 TJm
+(dif) 11.0684 Tj
+25 TJm
+(\002culties) 31.5516 Tj
+-396 TJm
+(caused) 27.1082 Tj
+-396 TJm
+(by) 9.9626 Tj
+-396 TJm
+(repetiti) 28.224 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-396 TJm
+(data,) 19.0883 Tj
+-432 TJm
+(the) 12.1743 Tj
+-397 TJm
+(library) 26.5603 Tj
+-396 TJm
+(switches) 34.3112 Tj
+-396 TJm
+(from) 19.3673 Tj
+[1 0 0 1 72 50.8518] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 374.394 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 40.5726 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -493.841 -50.8518] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+534.414 50.8518 Td
+/F130_0 9.9626 Tf
+(12) 9.9626 Tj
+[1 0 0 1 453.269 50.8518] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 93.5985 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.2765 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+Q
+showpage
+%%PageTrailer
+pdfEndPage
+%%Page: 16 16
+%%BeginPageSetup
+%%PageOrientation: Portrait
+pdfStartPage
+0 0 612 792 re W
+%%EndPageSetup
+[] 0 d
+1 i
+0 j
+0 J
+10 M
+1 w
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+false op
+false OP
+0 0 612 792 re
+W
+q
+[1 0 0 1 72 741.554] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 14.4459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 187.197 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 -8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 76.4979 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -342.569 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+419.067 749.245 Td
+/F130_0 9.9626 Tf
+(Programming) 54.7943 Tj
+-250 TJm
+(with) 17.7135 Tj
+[1 0 0 1 496.556 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -496.556 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+496.556 749.245 Td
+/F134_0 9.9626 Tf
+(libbzip2) 47.8205 Tj
+[1 0 0 1 544.376 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -278.305 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 280.796 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -472.974 -5.0363] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -0.4981] cm
+q
+[] 0 d
+0 J
+0.4981 w
+0 0.2491 m
+475.465 0.2491 l
+S
+Q
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 479.251 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -540 -741.554] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 710.037 Td
+/F130_0 9.9626 Tf
+(the) 12.1743 Tj
+-255 TJm
+(standard) 33.7533 Tj
+-254 TJm
+(sorting) 27.6761 Tj
+-255 TJm
+(algorithm) 38.7446 Tj
+-254 TJm
+(to) 7.7509 Tj
+-255 TJm
+(a) 4.42339 Tj
+-255 TJm
+(f) 3.31755 Tj
+10 TJm
+(allback) 28.772 Tj
+-254 TJm
+(algorithm.) 41.2352 Tj
+-648 TJm
+(The) 15.4918 Tj
+-255 TJm
+(f) 3.31755 Tj
+10 TJm
+(allback) 28.772 Tj
+-254 TJm
+(is) 6.64505 Tj
+-255 TJm
+(slo) 11.6264 Tj
+25 TJm
+(wer) 14.9339 Tj
+-255 TJm
+(than) 17.1556 Tj
+-254 TJm
+(the) 12.1743 Tj
+-255 TJm
+(standard) 33.7533 Tj
+-254 TJm
+(algorithm) 38.7446 Tj
+-255 TJm
+(by) 9.9626 Tj
+-255 TJm
+(perhaps) 30.9837 Tj
+72 698.082 Td
+(a) 4.42339 Tj
+-250 TJm
+(f) 3.31755 Tj
+10 TJm
+(actor) 19.9152 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(three,) 22.4059 Tj
+-250 TJm
+(b) 4.9813 Tj
+20 TJm
+(ut) 7.7509 Tj
+-250 TJm
+(al) 7.193 Tj
+10 TJm
+(w) 7.193 Tj
+10 TJm
+(ays) 13.2801 Tj
+-250 TJm
+(beha) 18.8094 Tj
+20 TJm
+(v) 4.9813 Tj
+15 TJm
+(es) 8.29885 Tj
+-250 TJm
+(reasonably) 43.158 Tj
+65 TJm
+(,) 2.49065 Tj
+-250 TJm
+(no) 9.9626 Tj
+-250 TJm
+(matter) 25.4544 Tj
+-250 TJm
+(ho) 9.9626 Tj
+25 TJm
+(w) 7.193 Tj
+-250 TJm
+(bad) 14.386 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(input.) 22.9738 Tj
+[1 0 0 1 72 695.925] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9617] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -685.964] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 676.165 Td
+/F130_0 9.9626 Tf
+(Lo) 11.0684 Tj
+25 TJm
+(wer) 14.9339 Tj
+-240 TJm
+(v) 4.9813 Tj
+25 TJm
+(alues) 20.4731 Tj
+-239 TJm
+(of) 8.29885 Tj
+[1 0 0 1 138.421 676.165] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -138.421 -676.165] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+138.421 676.165 Td
+/F134_0 9.9626 Tf
+(workFactor) 59.7756 Tj
+[1 0 0 1 198.197 676.165] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -198.197 -676.165] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+200.585 676.165 Td
+/F130_0 9.9626 Tf
+(reduce) 26.5503 Tj
+-240 TJm
+(the) 12.1743 Tj
+-239 TJm
+(amount) 29.8878 Tj
+-240 TJm
+(of) 8.29885 Tj
+-240 TJm
+(ef) 7.74094 Tj
+25 TJm
+(fort) 14.386 Tj
+-239 TJm
+(the) 12.1743 Tj
+-240 TJm
+(standard) 33.7533 Tj
+-240 TJm
+(algorithm) 38.7446 Tj
+-239 TJm
+(will) 15.5018 Tj
+-240 TJm
+(e) 4.42339 Tj
+15 TJm
+(xpend) 24.3486 Tj
+-240 TJm
+(before) 25.4445 Tj
+-240 TJm
+(resorting) 35.417 Tj
+-239 TJm
+(to) 7.7509 Tj
+-240 TJm
+(the) 12.1743 Tj
+72 664.21 Td
+(f) 3.31755 Tj
+10 TJm
+(allback.) 31.2626 Tj
+-618 TJm
+(Y) 7.193 Tj
+110 TJm
+(ou) 9.9626 Tj
+-248 TJm
+(should) 26.5703 Tj
+-247 TJm
+(set) 11.0684 Tj
+-248 TJm
+(this) 14.396 Tj
+-247 TJm
+(parameter) 39.8305 Tj
+-248 TJm
+(carefully;) 38.1767 Tj
+-248 TJm
+(too) 12.7322 Tj
+-248 TJm
+(lo) 7.7509 Tj
+25 TJm
+(w) 7.193 Tj
+65 TJm
+(,) 2.49065 Tj
+-248 TJm
+(and) 14.386 Tj
+-247 TJm
+(man) 17.1556 Tj
+15 TJm
+(y) 4.9813 Tj
+-248 TJm
+(inputs) 24.3586 Tj
+-248 TJm
+(will) 15.5018 Tj
+-247 TJm
+(be) 9.40469 Tj
+-248 TJm
+(handled) 31.5416 Tj
+-247 TJm
+(by) 9.9626 Tj
+-248 TJm
+(the) 12.1743 Tj
+-247 TJm
+(f) 3.31755 Tj
+10 TJm
+(allback) 28.772 Tj
+-248 TJm
+(algorithm) 38.7446 Tj
+72 652.255 Td
+(and) 14.386 Tj
+-308 TJm
+(so) 8.85675 Tj
+-308 TJm
+(compress) 37.6287 Tj
+-308 TJm
+(rather) 23.2328 Tj
+-309 TJm
+(slo) 11.6264 Tj
+25 TJm
+(wly) 14.9439 Tj
+65 TJm
+(,) 2.49065 Tj
+-322 TJm
+(too) 12.7322 Tj
+-309 TJm
+(high,) 20.2042 Tj
+-322 TJm
+(and) 14.386 Tj
+-308 TJm
+(your) 18.2614 Tj
+-309 TJm
+(a) 4.42339 Tj
+20 TJm
+(v) 4.9813 Tj
+15 TJm
+(erage-to-w) 43.148 Tj
+10 TJm
+(orst) 14.9439 Tj
+-308 TJm
+(case) 17.1456 Tj
+-308 TJm
+(compression) 50.3609 Tj
+-308 TJm
+(times) 21.589 Tj
+-308 TJm
+(can) 13.8281 Tj
+-308 TJm
+(become) 30.9837 Tj
+-309 TJm
+(v) 4.9813 Tj
+15 TJm
+(ery) 12.7222 Tj
+-308 TJm
+(lar) 10.5105 Tj
+18 TJm
+(ge.) 11.8953 Tj
+72 640.3 Td
+(The) 15.4918 Tj
+-250 TJm
+(def) 12.7222 Tj
+10 TJm
+(ault) 14.9439 Tj
+-250 TJm
+(v) 4.9813 Tj
+25 TJm
+(alue) 16.5977 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(30) 9.9626 Tj
+-250 TJm
+(gi) 7.7509 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(es) 8.29885 Tj
+-250 TJm
+(reasonable) 42.6001 Tj
+-250 TJm
+(beha) 18.8094 Tj
+20 TJm
+(viour) 21.031 Tj
+-250 TJm
+(o) 4.9813 Tj
+15 TJm
+(v) 4.9813 Tj
+15 TJm
+(er) 7.74094 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(wide) 19.3673 Tj
+-250 TJm
+(range) 22.1269 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(circumstances.) 58.9288 Tj
+[1 0 0 1 72 638.143] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9617] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -628.181] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 618.383 Td
+/F130_0 9.9626 Tf
+(Allo) 17.7135 Tj
+25 TJm
+(w) 7.193 Tj
+10 TJm
+(able) 16.5977 Tj
+-250 TJm
+(v) 4.9813 Tj
+25 TJm
+(alues) 20.4731 Tj
+-250 TJm
+(range) 22.1269 Tj
+-250 TJm
+(from) 19.3673 Tj
+-250 TJm
+(0) 4.9813 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(250) 14.9439 Tj
+-250 TJm
+(inclusi) 26.5703 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(e.) 6.91404 Tj
+-620 TJm
+(0) 4.9813 Tj
+-250 TJm
+(is) 6.64505 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(special) 27.6661 Tj
+-250 TJm
+(case,) 19.6363 Tj
+-250 TJm
+(equi) 17.1556 Tj
+25 TJm
+(v) 4.9813 Tj
+25 TJm
+(alent) 19.3673 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(using) 21.589 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(def) 12.7222 Tj
+10 TJm
+(ault) 14.9439 Tj
+-250 TJm
+(v) 4.9813 Tj
+25 TJm
+(alue) 16.5977 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(30.) 12.4533 Tj
+[1 0 0 1 72 616.226] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9617] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -606.265] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 596.466 Td
+/F130_0 9.9626 Tf
+(Note) 19.3673 Tj
+-250 TJm
+(that) 14.9439 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(compressed) 47.0334 Tj
+-250 TJm
+(output) 25.4644 Tj
+-250 TJm
+(generated) 38.7246 Tj
+-250 TJm
+(is) 6.64505 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(same) 20.4731 Tj
+-250 TJm
+(re) 7.74094 Tj
+15 TJm
+(g) 4.9813 Tj
+5 TJm
+(ardless) 27.6661 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(whether) 32.0895 Tj
+-250 TJm
+(or) 8.29885 Tj
+-250 TJm
+(not) 12.7322 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(f) 3.31755 Tj
+10 TJm
+(allback) 28.772 Tj
+-250 TJm
+(algorithm) 38.7446 Tj
+-250 TJm
+(is) 6.64505 Tj
+-250 TJm
+(used.) 20.7521 Tj
+[1 0 0 1 72 594.309] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9617] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -584.348] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 574.549 Td
+/F130_0 9.9626 Tf
+(Be) 11.0684 Tj
+-303 TJm
+(a) 4.42339 Tj
+15 TJm
+(w) 7.193 Tj
+10 TJm
+(are) 12.1643 Tj
+-303 TJm
+(also) 16.0497 Tj
+-303 TJm
+(that) 14.9439 Tj
+-303 TJm
+(this) 14.396 Tj
+-304 TJm
+(parameter) 39.8305 Tj
+-303 TJm
+(may) 17.1556 Tj
+-303 TJm
+(disappear) 38.1767 Tj
+-303 TJm
+(entirely) 30.4357 Tj
+-303 TJm
+(in) 7.7509 Tj
+-303 TJm
+(future) 23.7907 Tj
+-303 TJm
+(v) 4.9813 Tj
+15 TJm
+(ersions) 28.224 Tj
+-303 TJm
+(of) 8.29885 Tj
+-303 TJm
+(the) 12.1743 Tj
+-304 TJm
+(library) 26.5603 Tj
+65 TJm
+(.) 2.49065 Tj
+-938 TJm
+(In) 8.29885 Tj
+-303 TJm
+(principle) 35.417 Tj
+-303 TJm
+(it) 5.53921 Tj
+-304 TJm
+(should) 26.5703 Tj
+-303 TJm
+(be) 9.40469 Tj
+72 562.594 Td
+(possible) 32.6574 Tj
+-270 TJm
+(to) 7.7509 Tj
+-270 TJm
+(de) 9.40469 Tj
+25 TJm
+(vise) 16.0497 Tj
+-270 TJm
+(a) 4.42339 Tj
+-270 TJm
+(good) 19.9252 Tj
+-270 TJm
+(w) 7.193 Tj
+10 TJm
+(ay) 9.40469 Tj
+-270 TJm
+(to) 7.7509 Tj
+-271 TJm
+(automat) 32.0995 Tj
+1 TJm
+(ically) 22.1369 Tj
+-271 TJm
+(choose) 27.6661 Tj
+-270 TJm
+(which) 24.3486 Tj
+-270 TJm
+(algorithm) 38.7446 Tj
+-270 TJm
+(to) 7.7509 Tj
+-270 TJm
+(use.) 15.7708 Tj
+-740 TJm
+(Such) 19.9252 Tj
+-270 TJm
+(a) 4.42339 Tj
+-271 TJm
+(m) 7.7509 Tj
+1 TJm
+(echanism) 37.6287 Tj
+-271 TJm
+(w) 7.193 Tj
+10 TJm
+(ould) 17.7135 Tj
+-270 TJm
+(render) 25.4445 Tj
+-270 TJm
+(the) 12.1743 Tj
+72 550.639 Td
+(parameter) 39.8305 Tj
+-250 TJm
+(obsolete.) 35.696 Tj
+[1 0 0 1 72 548.482] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9616] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -538.521] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 528.722 Td
+/F130_0 9.9626 Tf
+(Possible) 33.2153 Tj
+-250 TJm
+(return) 23.7907 Tj
+-250 TJm
+(v) 4.9813 Tj
+25 TJm
+(alues:) 23.2427 Tj
+[1 0 0 1 72 528.623] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -144.458] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 143.462 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 139.875] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -519.258] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 519.258 Td
+/F134_0 9.9626 Tf
+(BZ_CONFIG_ERROR) 89.6634 Tj
+98.4879 507.303 Td
+(if) 11.9551 Tj
+-426 TJm
+(the) 17.9327 Tj
+-426 TJm
+(library) 41.8429 Tj
+-426 TJm
+(has) 17.9327 Tj
+-426 TJm
+(been) 23.9102 Tj
+-426 TJm
+(mis-compiled) 71.7307 Tj
+90 495.348 Td
+(BZ_PARAM_ERROR) 83.6858 Tj
+98.4879 483.392 Td
+(if) 11.9551 Tj
+-426 TJm
+(strm) 23.9102 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(NULL) 23.9102 Tj
+98.4879 471.437 Td
+(or) 11.9551 Tj
+-426 TJm
+(blockSize) 53.798 Tj
+-426 TJm
+(<) 5.97756 Tj
+-426 TJm
+(1) 5.97756 Tj
+-426 TJm
+(or) 11.9551 Tj
+-426 TJm
+(blockSize) 53.798 Tj
+-426 TJm
+(>) 5.97756 Tj
+-426 TJm
+(9) 5.97756 Tj
+98.4879 459.482 Td
+(or) 11.9551 Tj
+-426 TJm
+(verbosity) 53.798 Tj
+-426 TJm
+(<) 5.97756 Tj
+-426 TJm
+(0) 5.97756 Tj
+-426 TJm
+(or) 11.9551 Tj
+-426 TJm
+(verbosity) 53.798 Tj
+-426 TJm
+(>) 5.97756 Tj
+-426 TJm
+(4) 5.97756 Tj
+98.4879 447.527 Td
+(or) 11.9551 Tj
+-426 TJm
+(workFactor) 59.7756 Tj
+-426 TJm
+(<) 5.97756 Tj
+-426 TJm
+(0) 5.97756 Tj
+-426 TJm
+(or) 11.9551 Tj
+-426 TJm
+(workFactor) 59.7756 Tj
+-426 TJm
+(>) 5.97756 Tj
+-426 TJm
+(250) 17.9327 Tj
+90 435.572 Td
+(BZ_MEM_ERROR) 71.7307 Tj
+98.4879 423.617 Td
+(if) 11.9551 Tj
+-426 TJm
+(not) 17.9327 Tj
+-426 TJm
+(enough) 35.8654 Tj
+-426 TJm
+(memory) 35.8654 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(available) 53.798 Tj
+90 411.661 Td
+(BZ_OK) 29.8878 Tj
+98.4879 399.706 Td
+(otherwise) 53.798 Tj
+[1 0 0 1 72 384.165] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.5482] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -374.203] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 362.248 Td
+/F130_0 9.9626 Tf
+(Allo) 17.7135 Tj
+25 TJm
+(w) 7.193 Tj
+10 TJm
+(able) 16.5977 Tj
+-250 TJm
+(ne) 9.40469 Tj
+15 TJm
+(xt) 7.7509 Tj
+-250 TJm
+(actions:) 30.9936 Tj
+[1 0 0 1 72 362.148] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -48.8169] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 47.8207 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 44.2341] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -352.783] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 352.783 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompress) 83.6858 Tj
+98.4879 340.828 Td
+(if) 11.9551 Tj
+-426 TJm
+(BZ_OK) 29.8878 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(returned) 47.8205 Tj
+98.4879 328.873 Td
+(no) 11.9551 Tj
+-426 TJm
+(specific) 47.8205 Tj
+-426 TJm
+(action) 35.8654 Tj
+-426 TJm
+(needed) 35.8654 Tj
+-426 TJm
+(in) 11.9551 Tj
+-426 TJm
+(case) 23.9102 Tj
+-426 TJm
+(of) 11.9551 Tj
+-426 TJm
+(error) 29.8878 Tj
+[1 0 0 1 72 313.331] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9616] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -303.37] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 282.711 Td
+/F122_0 17.2154 Tf
+(3.3.2.) 43.0729 Tj
+[1 0 0 1 119.858 282.711] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -119.858 -282.711] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+119.858 282.711 Td
+/F392_0 17.2154 Tf
+(BZ2_bzCompress) 144.609 Tj
+[1 0 0 1 264.468 282.711] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -192.468 -2.3327] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -24.9066] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 23.9103 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 20.3237] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3685] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -271.014] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 271.014 Td
+/F134_0 9.9626 Tf
+(int) 17.9327 Tj
+-426 TJm
+(BZ2_bzCompress) 83.6858 Tj
+-426 TJm
+(\() 5.97756 Tj
+-426 TJm
+(bz_stream) 53.798 Tj
+268.371 269.27 Td
+(*) 5.97756 Tj
+274.348 271.014 Td
+(strm,) 29.8878 Tj
+-426 TJm
+(int) 17.9327 Tj
+-426 TJm
+(action) 35.8654 Tj
+-426 TJm
+(\);) 11.9551 Tj
+[1 0 0 1 72 255.472] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.5482] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -245.51] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 233.555 Td
+/F130_0 9.9626 Tf
+(Pro) 13.8381 Tj
+15 TJm
+(vides) 21.031 Tj
+-222 TJm
+(more) 20.4731 Tj
+-221 TJm
+(input) 20.4831 Tj
+-222 TJm
+(and/or) 25.4544 Tj
+-222 TJm
+(output) 25.4644 Tj
+-222 TJm
+(b) 4.9813 Tj
+20 TJm
+(uf) 8.29885 Tj
+25 TJm
+(fer) 11.0585 Tj
+-221 TJm
+(space) 22.1269 Tj
+-222 TJm
+(for) 11.6164 Tj
+-222 TJm
+(the) 12.1743 Tj
+-221 TJm
+(library) 26.5603 Tj
+65 TJm
+(.) 2.49065 Tj
+-601 TJm
+(The) 15.4918 Tj
+-222 TJm
+(caller) 22.1269 Tj
+-222 TJm
+(maintains) 38.7446 Tj
+-222 TJm
+(input) 20.4831 Tj
+-221 TJm
+(and) 14.386 Tj
+-222 TJm
+(output) 25.4644 Tj
+-222 TJm
+(b) 4.9813 Tj
+20 TJm
+(uf) 8.29885 Tj
+25 TJm
+(fers,) 17.4246 Tj
+-227 TJm
+(and) 14.386 Tj
+-222 TJm
+(calls) 18.2614 Tj
+[1 0 0 1 72 221.6] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -221.6] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 221.6 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompress) 83.6858 Tj
+[1 0 0 1 155.686 221.6] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -155.686 -221.6] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+158.177 221.6 Td
+/F130_0 9.9626 Tf
+(to) 7.7509 Tj
+-250 TJm
+(transfer) 30.4258 Tj
+-250 TJm
+(data) 16.5977 Tj
+-250 TJm
+(between) 33.1954 Tj
+-250 TJm
+(them.) 22.4159 Tj
+[1 0 0 1 72 220.066] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9617] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -210.104] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 199.683 Td
+/F130_0 9.9626 Tf
+(Before) 27.1082 Tj
+-212 TJm
+(each) 18.2515 Tj
+-213 TJm
+(call) 14.386 Tj
+-212 TJm
+(to) 7.7509 Tj
+[1 0 0 1 147.961 199.683] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -147.961 -199.683] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+147.961 199.683 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompress) 83.6858 Tj
+[1 0 0 1 231.647 199.683] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -231.647 -199.683] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+231.647 199.683 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 236.329 199.683] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -236.329 -199.683] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+236.329 199.683 Td
+/F134_0 9.9626 Tf
+(next_in) 41.8429 Tj
+[1 0 0 1 278.172 199.683] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -278.172 -199.683] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+280.288 199.683 Td
+/F130_0 9.9626 Tf
+(should) 26.5703 Tj
+-212 TJm
+(point) 20.4831 Tj
+-213 TJm
+(at) 7.193 Tj
+-212 TJm
+(the) 12.1743 Tj
+-213 TJm
+(data) 16.5977 Tj
+-212 TJm
+(to) 7.7509 Tj
+-212 TJm
+(be) 9.40469 Tj
+-213 TJm
+(compressed,) 49.5241 Tj
+-220 TJm
+(and) 14.386 Tj
+[1 0 0 1 463.493 199.683] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -463.493 -199.683] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+463.493 199.683 Td
+/F134_0 9.9626 Tf
+(avail_in) 47.8205 Tj
+[1 0 0 1 511.314 199.683] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -511.314 -199.683] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+513.43 199.683 Td
+/F130_0 9.9626 Tf
+(should) 26.5703 Tj
+72 187.728 Td
+(indicate) 31.5416 Tj
+-246 TJm
+(ho) 9.9626 Tj
+25 TJm
+(w) 7.193 Tj
+-247 TJm
+(m) 7.7509 Tj
+1 TJm
+(an) 9.40469 Tj
+14 TJm
+(y) 4.9813 Tj
+-246 TJm
+(bytes) 21.031 Tj
+-246 TJm
+(the) 12.1743 Tj
+-246 TJm
+(library) 26.5603 Tj
+-247 TJm
+(may) 17.1556 Tj
+-246 TJm
+(read.) 19.6363 Tj
+[1 0 0 1 259.242 187.728] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -259.242 -187.728] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+259.242 187.728 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompress) 83.6858 Tj
+[1 0 0 1 342.929 187.728] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -342.929 -187.728] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+345.382 187.728 Td
+/F130_0 9.9626 Tf
+(updates) 30.4357 Tj
+[1 0 0 1 378.271 187.728] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -378.271 -187.728] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+378.271 187.728 Td
+/F134_0 9.9626 Tf
+(next_in) 41.8429 Tj
+[1 0 0 1 420.114 187.728] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -420.114 -187.728] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+420.114 187.728 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 425.066 187.728] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -425.066 -187.728] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+425.066 187.728 Td
+/F134_0 9.9626 Tf
+(avail_in) 47.8205 Tj
+[1 0 0 1 472.886 187.728] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -472.886 -187.728] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+475.34 187.728 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 492.179 187.728] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -492.179 -187.728] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+492.179 187.728 Td
+/F134_0 9.9626 Tf
+(total_in) 47.8205 Tj
+[1 0 0 1 540 187.728] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -540 -187.728] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 175.773 Td
+/F130_0 9.9626 Tf
+(to) 7.7509 Tj
+-250 TJm
+(re\003ect) 24.8965 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(number) 30.4357 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(bytes) 21.031 Tj
+-250 TJm
+(it) 5.53921 Tj
+-250 TJm
+(has) 13.2801 Tj
+-250 TJm
+(read.) 19.6363 Tj
+[1 0 0 1 72 173.616] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9616] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -163.654] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 153.856 Td
+/F130_0 9.9626 Tf
+(Similarly) 37.0908 Tj
+65 TJm
+(,) 2.49065 Tj
+[1 0 0 1 113.611 153.856] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -113.611 -153.856] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+113.611 153.856 Td
+/F134_0 9.9626 Tf
+(next_out) 47.8205 Tj
+[1 0 0 1 161.432 153.856] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -161.432 -153.856] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+164.072 153.856 Td
+/F130_0 9.9626 Tf
+(should) 26.5703 Tj
+-265 TJm
+(point) 20.4831 Tj
+-265 TJm
+(to) 7.7509 Tj
+-265 TJm
+(a) 4.42339 Tj
+-265 TJm
+(b) 4.9813 Tj
+20 TJm
+(uf) 8.29885 Tj
+25 TJm
+(fer) 11.0585 Tj
+-265 TJm
+(in) 7.7509 Tj
+-265 TJm
+(which) 24.3486 Tj
+-265 TJm
+(the) 12.1743 Tj
+-265 TJm
+(compressed) 47.0334 Tj
+-265 TJm
+(data) 16.5977 Tj
+-265 TJm
+(is) 6.64505 Tj
+-265 TJm
+(to) 7.7509 Tj
+-265 TJm
+(be) 9.40469 Tj
+-265 TJm
+(placed,) 28.493 Tj
+-269 TJm
+(with) 17.7135 Tj
+[1 0 0 1 464.742 153.856] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -464.742 -153.856] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+464.742 153.856 Td
+/F134_0 9.9626 Tf
+(avail_out) 53.798 Tj
+[1 0 0 1 518.54 153.856] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -518.54 -153.856] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+521.181 153.856 Td
+/F130_0 9.9626 Tf
+(indi-) 18.8194 Tj
+72 141.901 Td
+(cating) 24.3486 Tj
+-209 TJm
+(ho) 9.9626 Tj
+25 TJm
+(w) 7.193 Tj
+-209 TJm
+(much) 22.1369 Tj
+-209 TJm
+(output) 25.4644 Tj
+-209 TJm
+(space) 22.1269 Tj
+-209 TJm
+(is) 6.64505 Tj
+-210 TJm
+(a) 4.42339 Tj
+20 TJm
+(v) 4.9813 Tj
+25 TJm
+(ailable.) 29.0509 Tj
+[1 0 0 1 243.087 141.901] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -243.087 -141.901] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+243.087 141.901 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompress) 83.6858 Tj
+[1 0 0 1 326.773 141.901] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -326.773 -141.901] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+328.856 141.901 Td
+/F130_0 9.9626 Tf
+(updates) 30.4357 Tj
+[1 0 0 1 361.375 141.901] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -361.375 -141.901] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+361.375 141.901 Td
+/F134_0 9.9626 Tf
+(next_out) 47.8205 Tj
+[1 0 0 1 409.196 141.901] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -409.196 -141.901] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+409.196 141.901 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 413.851 141.901] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -413.851 -141.901] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+413.851 141.901 Td
+/F134_0 9.9626 Tf
+(avail_out) 53.798 Tj
+[1 0 0 1 467.649 141.901] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -467.649 -141.901] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+469.732 141.901 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 486.202 141.901] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -486.202 -141.901] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+486.202 141.901 Td
+/F134_0 9.9626 Tf
+(total_out) 53.798 Tj
+[1 0 0 1 540 141.901] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -540 -141.901] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 129.946 Td
+/F130_0 9.9626 Tf
+(to) 7.7509 Tj
+-250 TJm
+(re\003ect) 24.8965 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(number) 30.4357 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(bytes) 21.031 Tj
+-250 TJm
+(output.) 27.9551 Tj
+[1 0 0 1 72 127.789] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9617] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -117.827] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 108.029 Td
+/F130_0 9.9626 Tf
+(Y) 7.193 Tj
+110 TJm
+(ou) 9.9626 Tj
+-272 TJm
+(may) 17.1556 Tj
+-272 TJm
+(pro) 13.2801 Tj
+15 TJm
+(vide) 17.1556 Tj
+-272 TJm
+(and) 14.386 Tj
+-272 TJm
+(remo) 20.4731 Tj
+15 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-272 TJm
+(as) 8.29885 Tj
+-272 TJm
+(little) 18.2714 Tj
+-272 TJm
+(or) 8.29885 Tj
+-272 TJm
+(as) 8.29885 Tj
+-272 TJm
+(much) 22.1369 Tj
+-271 TJm
+(data) 16.5977 Tj
+-272 TJm
+(as) 8.29885 Tj
+-272 TJm
+(you) 14.9439 Tj
+-272 TJm
+(lik) 10.5205 Tj
+10 TJm
+(e) 4.42339 Tj
+-272 TJm
+(on) 9.9626 Tj
+-272 TJm
+(each) 18.2515 Tj
+-272 TJm
+(call) 14.386 Tj
+-272 TJm
+(of) 8.29885 Tj
+[1 0 0 1 399.123 108.029] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -399.123 -108.029] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+399.123 108.029 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompress) 83.6858 Tj
+[1 0 0 1 482.809 108.029] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -482.809 -108.029] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+482.809 108.029 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+-752 TJm
+(In) 8.29885 Tj
+-272 TJm
+(the) 12.1743 Tj
+-272 TJm
+(limit,) 21.32 Tj
+72 96.0736 Td
+(it) 5.53921 Tj
+-266 TJm
+(is) 6.64505 Tj
+-265 TJm
+(acceptable) 42.0422 Tj
+-266 TJm
+(to) 7.7509 Tj
+-266 TJm
+(supply) 26.5703 Tj
+-266 TJm
+(and) 14.386 Tj
+-265 TJm
+(remo) 20.4731 Tj
+15 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-266 TJm
+(data) 16.5977 Tj
+-266 TJm
+(one) 14.386 Tj
+-265 TJm
+(byte) 17.1556 Tj
+-266 TJm
+(at) 7.193 Tj
+-266 TJm
+(a) 4.42339 Tj
+-266 TJm
+(time,) 20.2042 Tj
+-269 TJm
+(although) 34.8691 Tj
+-266 TJm
+(this) 14.396 Tj
+-266 TJm
+(w) 7.193 Tj
+10 TJm
+(ould) 17.7135 Tj
+-265 TJm
+(be) 9.40469 Tj
+-266 TJm
+(terribly) 29.3299 Tj
+-266 TJm
+(inef) 15.4918 Tj
+25 TJm
+(\002cient.) 27.3972 Tj
+-714 TJm
+(Y) 7.193 Tj
+110 TJm
+(ou) 9.9626 Tj
+-266 TJm
+(should) 26.5703 Tj
+72 84.1184 Td
+(al) 7.193 Tj
+10 TJm
+(w) 7.193 Tj
+10 TJm
+(ays) 13.2801 Tj
+-250 TJm
+(ensure) 26.0024 Tj
+-250 TJm
+(that) 14.9439 Tj
+-250 TJm
+(at) 7.193 Tj
+-250 TJm
+(least) 18.2614 Tj
+-250 TJm
+(one) 14.386 Tj
+-250 TJm
+(byte) 17.1556 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(output) 25.4644 Tj
+-250 TJm
+(space) 22.1269 Tj
+-250 TJm
+(is) 6.64505 Tj
+-250 TJm
+(a) 4.42339 Tj
+20 TJm
+(v) 4.9813 Tj
+25 TJm
+(ailable) 26.5603 Tj
+-250 TJm
+(at) 7.193 Tj
+-250 TJm
+(each) 18.2515 Tj
+-250 TJm
+(call.) 16.8766 Tj
+[1 0 0 1 72 81.9616] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9616] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -21.1482] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 374.394 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 6.8541] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 40.5726 -6.7545] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -493.841 -50.9514] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+534.414 50.9514 Td
+/F130_0 9.9626 Tf
+(13) 9.9626 Tj
+[1 0 0 1 453.269 50.8518] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 93.5985 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.2765 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+Q
+showpage
+%%PageTrailer
+pdfEndPage
+%%Page: 17 17
+%%BeginPageSetup
+%%PageOrientation: Portrait
+pdfStartPage
+0 0 612 792 re W
+%%EndPageSetup
+[] 0 d
+1 i
+0 j
+0 J
+10 M
+1 w
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+false op
+false OP
+0 0 612 792 re
+W
+q
+[1 0 0 1 72 741.554] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 14.4459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 187.197 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 -8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 76.4979 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -342.569 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+419.067 749.245 Td
+/F130_0 9.9626 Tf
+(Programming) 54.7943 Tj
+-250 TJm
+(with) 17.7135 Tj
+[1 0 0 1 496.556 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -496.556 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+496.556 749.245 Td
+/F134_0 9.9626 Tf
+(libbzip2) 47.8205 Tj
+[1 0 0 1 544.376 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -278.305 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 280.796 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -472.974 -5.0363] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -0.4981] cm
+q
+[] 0 d
+0 J
+0.4981 w
+0 0.2491 m
+475.465 0.2491 l
+S
+Q
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 479.251 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -540 -741.554] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 710.037 Td
+/F130_0 9.9626 Tf
+(A) 7.193 Tj
+-250 TJm
+(second) 27.6661 Tj
+-250 TJm
+(purpose) 31.5416 Tj
+-250 TJm
+(of) 8.29885 Tj
+[1 0 0 1 156.662 710.037] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -156.662 -710.037] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+156.662 710.037 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompress) 83.6858 Tj
+[1 0 0 1 240.348 710.037] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -240.348 -710.037] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+242.839 710.037 Td
+/F130_0 9.9626 Tf
+(is) 6.64505 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(request) 28.772 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(change) 28.2141 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(mode) 22.1369 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(compressed) 47.0334 Tj
+-250 TJm
+(stream.) 29.0509 Tj
+[1 0 0 1 72 707.88] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -697.918] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 688.12 Td
+/F130_0 9.9626 Tf
+(Conceptually) 53.1305 Tj
+65 TJm
+(,) 2.49065 Tj
+-217 TJm
+(a) 4.42339 Tj
+-210 TJm
+(compressed) 47.0334 Tj
+-209 TJm
+(stream) 26.5603 Tj
+-209 TJm
+(can) 13.8281 Tj
+-209 TJm
+(be) 9.40469 Tj
+-210 TJm
+(in) 7.7509 Tj
+-209 TJm
+(one) 14.386 Tj
+-209 TJm
+(of) 8.29885 Tj
+-209 TJm
+(four) 16.5977 Tj
+-210 TJm
+(states:) 24.9065 Tj
+-289 TJm
+(IDLE,) 25.1755 Tj
+-209 TJm
+(R) 6.64505 Tj
+40 TJm
+(UNNING,) 41.7732 Tj
+-210 TJm
+(FLUSHING) 49.2551 Tj
+-209 TJm
+(and) 14.386 Tj
+-209 TJm
+(FINISHING.) 52.2937 Tj
+-419 TJm
+(Be-) 14.386 Tj
+72 676.164 Td
+(fore) 16.0398 Tj
+-264 TJm
+(initialisation) 49.823 Tj
+-263 TJm
+(\() 3.31755 Tj
+[1 0 0 1 146.434 676.164] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -146.434 -676.164] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+146.434 676.164 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompressInit) 107.596 Tj
+[1 0 0 1 254.031 676.164] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -254.031 -676.164] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+254.031 676.164 Td
+/F130_0 9.9626 Tf
+(\)) 3.31755 Tj
+-264 TJm
+(and) 14.386 Tj
+-263 TJm
+(after) 18.2515 Tj
+-264 TJm
+(termination) 45.9375 Tj
+-264 TJm
+(\() 3.31755 Tj
+[1 0 0 1 349.75 676.164] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -349.75 -676.164] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+349.75 676.164 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompressEnd) 101.619 Tj
+[1 0 0 1 451.369 676.164] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -451.369 -676.164] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+451.369 676.164 Td
+/F130_0 9.9626 Tf
+(\),) 5.8082 Tj
+-267 TJm
+(a) 4.42339 Tj
+-264 TJm
+(stream) 26.5603 Tj
+-264 TJm
+(is) 6.64505 Tj
+-263 TJm
+(re) 7.74094 Tj
+15 TJm
+(g) 4.9813 Tj
+5 TJm
+(arded) 22.1269 Tj
+72 664.209 Td
+(as) 8.29885 Tj
+-250 TJm
+(IDLE.) 25.1755 Tj
+[1 0 0 1 72 664.11] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -654.147] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 642.291 Td
+/F130_0 9.9626 Tf
+(Upon) 22.1369 Tj
+-389 TJm
+(initialisation) 49.823 Tj
+-390 TJm
+(\() 3.31755 Tj
+[1 0 0 1 155.036 642.291] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -155.036 -642.291] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+155.036 642.291 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompressInit) 107.596 Tj
+[1 0 0 1 262.632 642.291] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -262.632 -642.291] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+262.632 642.291 Td
+/F130_0 9.9626 Tf
+(\),) 5.8082 Tj
+-424 TJm
+(the) 12.1743 Tj
+-390 TJm
+(stream) 26.5603 Tj
+-389 TJm
+(is) 6.64505 Tj
+-389 TJm
+(placed) 26.0024 Tj
+-390 TJm
+(in) 7.7509 Tj
+-389 TJm
+(the) 12.1743 Tj
+-390 TJm
+(R) 6.64505 Tj
+40 TJm
+(UNNING) 39.2825 Tj
+-389 TJm
+(state.) 20.7521 Tj
+-1457 TJm
+(Subsequent) 45.9375 Tj
+-389 TJm
+(calls) 18.2614 Tj
+72 630.336 Td
+(to) 7.7509 Tj
+[1 0 0 1 83.818 630.336] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -83.818 -630.336] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+83.818 630.336 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompress) 83.6858 Tj
+[1 0 0 1 167.504 630.336] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -167.504 -630.336] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+171.571 630.336 Td
+/F130_0 9.9626 Tf
+(should) 26.5703 Tj
+-408 TJm
+(pass) 17.1556 Tj
+[1 0 0 1 223.431 630.336] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -223.431 -630.336] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+223.431 630.336 Td
+/F134_0 9.9626 Tf
+(BZ_RUN) 35.8654 Tj
+[1 0 0 1 259.297 630.336] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -259.297 -630.336] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+263.363 630.336 Td
+/F130_0 9.9626 Tf
+(as) 8.29885 Tj
+-408 TJm
+(the) 12.1743 Tj
+-408 TJm
+(requested) 38.1767 Tj
+-409 TJm
+(action;) 27.1182 Tj
+-487 TJm
+(other) 20.4731 Tj
+-408 TJm
+(actions) 28.224 Tj
+-408 TJm
+(are) 12.1643 Tj
+-409 TJm
+(ille) 12.7322 Tj
+15 TJm
+(g) 4.9813 Tj
+5 TJm
+(al) 7.193 Tj
+-408 TJm
+(and) 14.386 Tj
+-408 TJm
+(will) 15.5018 Tj
+-408 TJm
+(result) 22.1369 Tj
+-409 TJm
+(in) 7.7509 Tj
+[1 0 0 1 72 618.381] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -618.381] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 618.381 Td
+/F134_0 9.9626 Tf
+(BZ_SEQUENCE_ERROR) 101.619 Tj
+[1 0 0 1 173.619 618.381] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -173.619 -618.381] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+173.619 618.381 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+[1 0 0 1 72 617.071] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -607.108] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 596.463 Td
+/F130_0 9.9626 Tf
+(At) 9.9626 Tj
+-279 TJm
+(some) 21.031 Tj
+-279 TJm
+(point,) 22.9738 Tj
+-286 TJm
+(the) 12.1743 Tj
+-279 TJm
+(calling) 27.1182 Tj
+-279 TJm
+(program) 33.7533 Tj
+-279 TJm
+(will) 15.5018 Tj
+-279 TJm
+(ha) 9.40469 Tj
+20 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-278 TJm
+(pro) 13.2801 Tj
+14 TJm
+(vi) 7.7509 Tj
+1 TJm
+(ded) 14.386 Tj
+-279 TJm
+(all) 9.9626 Tj
+-279 TJm
+(the) 12.1743 Tj
+-279 TJm
+(input) 20.4831 Tj
+-279 TJm
+(data) 16.5977 Tj
+-279 TJm
+(it) 5.53921 Tj
+-279 TJm
+(w) 7.193 Tj
+10 TJm
+(ants) 16.0497 Tj
+-279 TJm
+(to.) 10.2416 Tj
+-793 TJm
+(It) 6.08715 Tj
+-279 TJm
+(will) 15.5018 Tj
+-279 TJm
+(then) 17.1556 Tj
+-279 TJm
+(w) 7.193 Tj
+10 TJm
+(ant) 12.1743 Tj
+-279 TJm
+(to) 7.7509 Tj
+-279 TJm
+(\002nish) 22.1469 Tj
+-279 TJm
+(up) 9.9626 Tj
+-279 TJm
+(--) 6.63509 Tj
+72 584.508 Td
+(in) 7.7509 Tj
+-287 TJm
+(ef) 7.74094 Tj
+25 TJm
+(fect,) 17.4246 Tj
+-297 TJm
+(asking) 26.0123 Tj
+-288 TJm
+(the) 12.1743 Tj
+-287 TJm
+(library) 26.5603 Tj
+-287 TJm
+(to) 7.7509 Tj
+-288 TJm
+(process) 29.8778 Tj
+-287 TJm
+(an) 9.40469 Tj
+15 TJm
+(y) 4.9813 Tj
+-288 TJm
+(data) 16.5977 Tj
+-287 TJm
+(it) 5.53921 Tj
+-287 TJm
+(might) 23.2527 Tj
+-288 TJm
+(ha) 9.40469 Tj
+20 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-287 TJm
+(b) 4.9813 Tj
+20 TJm
+(uf) 8.29885 Tj
+25 TJm
+(fered) 20.4632 Tj
+-288 TJm
+(internally) 38.1866 Tj
+65 TJm
+(.) 2.49065 Tj
+-844 TJm
+(In) 8.29885 Tj
+-288 TJm
+(this) 14.396 Tj
+-287 TJm
+(state,) 20.7521 Tj
+[1 0 0 1 456.314 584.508] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -456.314 -584.508] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+456.314 584.508 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompress) 83.6858 Tj
+[1 0 0 1 540 584.508] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -540 -584.508] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 572.553 Td
+/F130_0 9.9626 Tf
+(will) 15.5018 Tj
+-258 TJm
+(no) 9.9626 Tj
+-257 TJm
+(longer) 25.4544 Tj
+-258 TJm
+(attempt) 29.8878 Tj
+-258 TJm
+(to) 7.7509 Tj
+-258 TJm
+(read) 17.1456 Tj
+-257 TJm
+(data) 16.5977 Tj
+-258 TJm
+(from) 19.3673 Tj
+[1 0 0 1 234.207 572.553] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -234.207 -572.553] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+234.207 572.553 Td
+/F134_0 9.9626 Tf
+(next_in) 41.8429 Tj
+[1 0 0 1 276.051 572.553] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -276.051 -572.553] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+276.051 572.553 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-260 TJm
+(b) 4.9813 Tj
+20 TJm
+(ut) 7.7509 Tj
+-257 TJm
+(it) 5.53921 Tj
+-258 TJm
+(will) 15.5018 Tj
+-258 TJm
+(w) 7.193 Tj
+10 TJm
+(ant) 12.1743 Tj
+-257 TJm
+(to) 7.7509 Tj
+-258 TJm
+(write) 20.4731 Tj
+-258 TJm
+(data) 16.5977 Tj
+-258 TJm
+(to) 7.7509 Tj
+[1 0 0 1 407.082 572.553] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -407.082 -572.553] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+407.082 572.553 Td
+/F134_0 9.9626 Tf
+(next_out) 47.8205 Tj
+[1 0 0 1 454.902 572.553] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -454.902 -572.553] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+454.902 572.553 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+-666 TJm
+(Because) 33.1954 Tj
+-258 TJm
+(the) 12.1743 Tj
+-258 TJm
+(output) 25.4644 Tj
+72 560.598 Td
+(b) 4.9813 Tj
+20 TJm
+(uf) 8.29885 Tj
+25 TJm
+(fer) 11.0585 Tj
+-228 TJm
+(supplied) 33.7633 Tj
+-228 TJm
+(by) 9.9626 Tj
+-229 TJm
+(the) 12.1743 Tj
+-228 TJm
+(user) 16.5977 Tj
+-228 TJm
+(can) 13.8281 Tj
+-228 TJm
+(be) 9.40469 Tj
+-228 TJm
+(arbitrarily) 39.8404 Tj
+-229 TJm
+(sma) 16.0497 Tj
+1 TJm
+(ll,) 8.02986 Tj
+-233 TJm
+(the) 12.1743 Tj
+-228 TJm
+(\002nishing-up) 48.1592 Tj
+-228 TJm
+(operation) 37.6287 Tj
+-229 TJm
+(cannot) 26.5603 Tj
+-228 TJm
+(necessarily) 44.2638 Tj
+-228 TJm
+(be) 9.40469 Tj
+-228 TJm
+(done) 19.3673 Tj
+-228 TJm
+(with) 17.7135 Tj
+-229 TJm
+(a) 4.42339 Tj
+-228 TJm
+(single) 23.8007 Tj
+72 548.643 Td
+(call) 14.386 Tj
+-250 TJm
+(of) 8.29885 Tj
+[1 0 0 1 99.6659 548.643] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -99.6659 -548.643] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+99.6659 548.643 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompress) 83.6858 Tj
+[1 0 0 1 183.352 548.643] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -183.352 -548.643] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+183.352 548.643 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+[1 0 0 1 72 547.108] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -537.146] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 526.725 Td
+/F130_0 9.9626 Tf
+(Instead,) 31.2626 Tj
+-346 TJm
+(the) 12.1743 Tj
+-327 TJm
+(calling) 27.1182 Tj
+-326 TJm
+(program) 33.7533 Tj
+-327 TJm
+(passes) 25.4544 Tj
+[1 0 0 1 218.231 526.725] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -218.231 -526.725] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+218.231 526.725 Td
+/F134_0 9.9626 Tf
+(BZ_FINISH) 53.798 Tj
+[1 0 0 1 272.029 526.725] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -272.029 -526.725] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+275.284 526.725 Td
+/F130_0 9.9626 Tf
+(as) 8.29885 Tj
+-327 TJm
+(an) 9.40469 Tj
+-327 TJm
+(action) 24.3486 Tj
+-326 TJm
+(to) 7.7509 Tj
+[1 0 0 1 338.108 526.725] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -338.108 -526.725] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+338.108 526.725 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompress) 83.6858 Tj
+[1 0 0 1 421.795 526.725] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -421.795 -526.725] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+421.795 526.725 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+-1081 TJm
+(This) 17.7135 Tj
+-326 TJm
+(changes) 32.0895 Tj
+-327 TJm
+(the) 12.1743 Tj
+-327 TJm
+(stream') 29.8778 Tj
+55 TJm
+(s) 3.87545 Tj
+72 514.77 Td
+(state) 18.2614 Tj
+-291 TJm
+(to) 7.7509 Tj
+-290 TJm
+(FINISHING.) 52.2937 Tj
+-581 TJm
+(An) 12.1743 Tj
+15 TJm
+(y) 4.9813 Tj
+-291 TJm
+(remaining) 40.3983 Tj
+-290 TJm
+(input) 20.4831 Tj
+-291 TJm
+(\(ie,) 13.0012 Tj
+[1 0 0 1 264.452 514.77] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -264.452 -514.77] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+264.452 514.77 Td
+/F134_0 9.9626 Tf
+(next_in[0) 53.798 Tj
+-600 TJm
+(..) 11.9551 Tj
+-1200 TJm
+(avail_in-1]) 65.7532 Tj
+[1 0 0 1 413.892 514.77] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -413.892 -514.77] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+413.892 514.77 Td
+/F130_0 9.9626 Tf
+(\)) 3.31755 Tj
+-291 TJm
+(is) 6.64505 Tj
+-290 TJm
+(compressed) 47.0334 Tj
+-291 TJm
+(and) 14.386 Tj
+-290 TJm
+(transferred) 43.148 Tj
+72 502.814 Td
+(to) 7.7509 Tj
+-421 TJm
+(the) 12.1743 Tj
+-421 TJm
+(output) 25.4644 Tj
+-421 TJm
+(b) 4.9813 Tj
+20 TJm
+(uf) 8.29885 Tj
+25 TJm
+(fer) 11.0585 Tj
+55 TJm
+(.) 2.49065 Tj
+-1646 TJm
+(T) 6.08715 Tj
+80 TJm
+(o) 4.9813 Tj
+-421 TJm
+(do) 9.9626 Tj
+-422 TJm
+(this) 14.396 Tj
+1 TJm
+(,) 2.49065 Tj
+[1 0 0 1 222.339 502.814] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -222.339 -502.814] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+222.339 502.814 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompress) 83.6858 Tj
+[1 0 0 1 306.025 502.814] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -306.025 -502.814] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+310.22 502.814 Td
+/F130_0 9.9626 Tf
+(must) 19.3773 Tj
+-421 TJm
+(be) 9.40469 Tj
+-421 TJm
+(called) 23.7907 Tj
+-421 TJm
+(repeatedly) 41.4942 Tj
+-421 TJm
+(until) 18.2714 Tj
+-421 TJm
+(all) 9.9626 Tj
+-421 TJm
+(the) 12.1743 Tj
+-421 TJm
+(output) 25.4644 Tj
+-421 TJm
+(has) 13.2801 Tj
+-421 TJm
+(been) 18.8094 Tj
+72 490.859 Td
+(consumed.) 42.889 Tj
+-1397 TJm
+(At) 9.9626 Tj
+-379 TJm
+(that) 14.9439 Tj
+-380 TJm
+(point,) 22.9738 Tj
+[1 0 0 1 188.346 490.859] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -188.346 -490.859] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+188.346 490.859 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompress) 83.6858 Tj
+[1 0 0 1 272.033 490.859] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -272.033 -490.859] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+275.813 490.859 Td
+/F130_0 9.9626 Tf
+(returns) 27.6661 Tj
+[1 0 0 1 307.259 490.859] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -307.259 -490.859] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+307.259 490.859 Td
+/F134_0 9.9626 Tf
+(BZ_STREAM_END) 77.7083 Tj
+[1 0 0 1 384.968 490.859] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -384.968 -490.859] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+384.968 490.859 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-379 TJm
+(and) 14.386 Tj
+-380 TJm
+(the) 12.1743 Tj
+-379 TJm
+(stream') 29.8778 Tj
+55 TJm
+(s) 3.87545 Tj
+-380 TJm
+(state) 18.2614 Tj
+-379 TJm
+(is) 6.64505 Tj
+-380 TJm
+(set) 11.0684 Tj
+-379 TJm
+(back) 18.8094 Tj
+-379 TJm
+(to) 7.7509 Tj
+72 478.904 Td
+(IDLE.) 25.1755 Tj
+[1 0 0 1 99.6662 478.904] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -99.6662 -478.904] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+99.6662 478.904 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompressEnd) 101.619 Tj
+[1 0 0 1 201.285 478.904] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -201.285 -478.904] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+203.776 478.904 Td
+/F130_0 9.9626 Tf
+(should) 26.5703 Tj
+-250 TJm
+(then) 17.1556 Tj
+-250 TJm
+(be) 9.40469 Tj
+-250 TJm
+(called.) 26.2813 Tj
+[1 0 0 1 72 477.37] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -467.407] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 456.986 Td
+/F130_0 9.9626 Tf
+(Just) 15.5018 Tj
+-380 TJm
+(to) 7.7509 Tj
+-380 TJm
+(mak) 17.1556 Tj
+10 TJm
+(e) 4.42339 Tj
+-379 TJm
+(sure) 16.5977 Tj
+-380 TJm
+(the) 12.1743 Tj
+-380 TJm
+(calling) 27.1182 Tj
+-380 TJm
+(program) 33.7533 Tj
+-379 TJm
+(does) 18.2614 Tj
+-380 TJm
+(not) 12.7322 Tj
+-380 TJm
+(cheat,) 23.5117 Tj
+-412 TJm
+(the) 12.1743 Tj
+-380 TJm
+(library) 26.5603 Tj
+-380 TJm
+(mak) 17.1556 Tj
+10 TJm
+(es) 8.29885 Tj
+-379 TJm
+(a) 4.42339 Tj
+-380 TJm
+(note) 17.1556 Tj
+-380 TJm
+(of) 8.29885 Tj
+[1 0 0 1 415.708 456.986] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -415.708 -456.986] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+415.708 456.986 Td
+/F134_0 9.9626 Tf
+(avail_in) 47.8205 Tj
+[1 0 0 1 463.528 456.986] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -463.528 -456.986] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+467.312 456.986 Td
+/F130_0 9.9626 Tf
+(at) 7.193 Tj
+-380 TJm
+(the) 12.1743 Tj
+-380 TJm
+(time) 17.7135 Tj
+-379 TJm
+(of) 8.29885 Tj
+-380 TJm
+(the) 12.1743 Tj
+72 445.031 Td
+(\002rst) 15.5018 Tj
+-286 TJm
+(call) 14.386 Tj
+-286 TJm
+(t) 2.7696 Tj
+1 TJm
+(o) 4.9813 Tj
+[1 0 0 1 118.179 445.031] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -118.179 -445.031] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+118.179 445.031 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompress) 83.6858 Tj
+[1 0 0 1 201.865 445.031] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -201.865 -445.031] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+204.713 445.031 Td
+/F130_0 9.9626 Tf
+(which) 24.3486 Tj
+-286 TJm
+(has) 13.2801 Tj
+[1 0 0 1 248.035 445.031] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -248.035 -445.031] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+248.035 445.031 Td
+/F134_0 9.9626 Tf
+(BZ_FINISH) 53.798 Tj
+[1 0 0 1 301.833 445.031] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -301.833 -445.031] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+304.68 445.031 Td
+/F130_0 9.9626 Tf
+(as) 8.29885 Tj
+-286 TJm
+(an) 9.40469 Tj
+-286 TJm
+(action) 24.3486 Tj
+-285 TJm
+(\(ie,) 13.0012 Tj
+-295 TJm
+(at) 7.193 Tj
+-286 TJm
+(the) 12.1743 Tj
+-286 TJm
+(time) 17.7135 Tj
+-285 TJm
+(the) 12.1743 Tj
+-286 TJm
+(program) 33.7533 Tj
+-286 TJm
+(has) 13.2801 Tj
+-286 TJm
+(announced) 43.158 Tj
+-285 TJm
+(its) 9.41466 Tj
+72 433.076 Td
+(intention) 35.427 Tj
+-292 TJm
+(to) 7.7509 Tj
+-292 TJm
+(not) 12.7322 Tj
+-291 TJm
+(supply) 26.5703 Tj
+-292 TJm
+(an) 9.40469 Tj
+15 TJm
+(y) 4.9813 Tj
+-292 TJm
+(more) 20.4731 Tj
+-292 TJm
+(input\).) 26.2913 Tj
+-870 TJm
+(By) 11.6264 Tj
+-292 TJm
+(comparing) 42.61 Tj
+-292 TJm
+(this) 14.396 Tj
+-292 TJm
+(v) 4.9813 Tj
+25 TJm
+(alue) 16.5977 Tj
+-291 TJm
+(with) 17.7135 Tj
+-292 TJm
+(that) 14.9439 Tj
+-292 TJm
+(of) 8.29885 Tj
+[1 0 0 1 392.862 433.076] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -392.862 -433.076] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+392.862 433.076 Td
+/F134_0 9.9626 Tf
+(avail_in) 47.8205 Tj
+[1 0 0 1 440.682 433.076] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -440.682 -433.076] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+443.589 433.076 Td
+/F130_0 9.9626 Tf
+(o) 4.9813 Tj
+15 TJm
+(v) 4.9813 Tj
+15 TJm
+(er) 7.74094 Tj
+-292 TJm
+(subsequent) 44.2738 Tj
+-292 TJm
+(calls) 18.2614 Tj
+-291 TJm
+(to) 7.7509 Tj
+[1 0 0 1 72 421.121] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -421.121] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 421.121 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompress) 83.6858 Tj
+[1 0 0 1 155.686 421.121] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -155.686 -421.121] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+155.686 421.121 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-247 TJm
+(the) 12.1743 Tj
+-247 TJm
+(library) 26.5603 Tj
+-246 TJm
+(can) 13.8281 Tj
+-247 TJm
+(detect) 23.7907 Tj
+-246 TJm
+(an) 9.40469 Tj
+15 TJm
+(y) 4.9813 Tj
+-247 TJm
+(att) 9.9626 Tj
+1 TJm
+(empts) 23.8007 Tj
+-247 TJm
+(to) 7.7509 Tj
+-246 TJm
+(slip) 14.396 Tj
+-247 TJm
+(in) 7.7509 Tj
+-246 TJm
+(more) 20.4731 Tj
+-247 TJm
+(data) 16.5977 Tj
+-246 TJm
+(to) 7.7509 Tj
+-247 TJm
+(compress.) 40.1194 Tj
+-617 TJm
+(An) 12.1743 Tj
+15 TJm
+(y) 4.9813 Tj
+-247 TJm
+(calls) 18.2614 Tj
+-246 TJm
+(for) 11.6164 Tj
+-247 TJm
+(which) 24.3486 Tj
+-246 TJm
+(this) 14.396 Tj
+-247 TJm
+(is) 6.64505 Tj
+72 409.166 Td
+(detected) 33.1954 Tj
+-250 TJm
+(will) 15.5018 Tj
+-250 TJm
+(return) 23.7907 Tj
+[1 0 0 1 151.959 409.166] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -151.959 -409.166] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+151.959 409.166 Td
+/F134_0 9.9626 Tf
+(BZ_SEQUENCE_ERROR) 101.619 Tj
+[1 0 0 1 253.578 409.166] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -253.578 -409.166] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+253.578 409.166 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+-500 TJm
+(This) 17.7135 Tj
+-250 TJm
+(indicates) 35.417 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(programming) 54.2364 Tj
+-250 TJm
+(mistak) 26.5703 Tj
+10 TJm
+(e) 4.42339 Tj
+-250 TJm
+(which) 24.3486 Tj
+-250 TJm
+(should) 26.5703 Tj
+-250 TJm
+(be) 9.40469 Tj
+-250 TJm
+(corrected.) 39.5515 Tj
+[1 0 0 1 72 407.009] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -397.046] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 387.248 Td
+/F130_0 9.9626 Tf
+(Instead) 28.772 Tj
+-224 TJm
+(of) 8.29885 Tj
+-223 TJm
+(asking) 26.0123 Tj
+-224 TJm
+(to) 7.7509 Tj
+-223 TJm
+(\002nish,) 24.6375 Tj
+-229 TJm
+(the) 12.1743 Tj
+-224 TJm
+(calling) 27.1182 Tj
+-223 TJm
+(program) 33.7533 Tj
+-224 TJm
+(may) 17.1556 Tj
+-224 TJm
+(ask) 13.2801 Tj
+[1 0 0 1 293.282 387.248] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -293.282 -387.248] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+293.282 387.248 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompress) 83.6858 Tj
+[1 0 0 1 376.968 387.248] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -376.968 -387.248] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+379.196 387.248 Td
+/F130_0 9.9626 Tf
+(to) 7.7509 Tj
+-224 TJm
+(tak) 12.1743 Tj
+10 TJm
+(e) 4.42339 Tj
+-223 TJm
+(all) 9.9626 Tj
+-224 TJm
+(the) 12.1743 Tj
+-223 TJm
+(remaining) 40.3983 Tj
+-224 TJm
+(input,) 22.9738 Tj
+-229 TJm
+(compress) 37.6287 Tj
+72 375.293 Td
+(it) 5.53921 Tj
+-278 TJm
+(and) 14.386 Tj
+-278 TJm
+(terminate) 37.6287 Tj
+-278 TJm
+(the) 12.1743 Tj
+-278 TJm
+(current) 28.2141 Tj
+-277 TJm
+(\(Burro) 26.5603 Tj
+25 TJm
+(ws-Wheeler\)) 51.4469 Tj
+-278 TJm
+(compression) 50.3609 Tj
+-278 TJm
+(block.) 24.6275 Tj
+-787 TJm
+(Th) 11.0684 Tj
+-1 TJm
+(i) 2.7696 Tj
+1 TJm
+(s) 3.87545 Tj
+-278 TJm
+(could) 22.1369 Tj
+-278 TJm
+(be) 9.40469 Tj
+-278 TJm
+(useful) 24.3486 Tj
+-278 TJm
+(for) 11.6164 Tj
+-278 TJm
+(error) 19.3573 Tj
+-278 TJm
+(control) 28.224 Tj
+-278 TJm
+(purposes.) 37.9077 Tj
+72 363.338 Td
+(The) 15.4918 Tj
+-328 TJm
+(mechanism) 45.3796 Tj
+-328 TJm
+(is) 6.64505 Tj
+-328 TJm
+(analogous) 40.3983 Tj
+-328 TJm
+(to) 7.7509 Tj
+-328 TJm
+(that) 14.9439 Tj
+-328 TJm
+(for) 11.6164 Tj
+-328 TJm
+(\002nishing:) 37.6487 Tj
+-466 TJm
+(call) 14.386 Tj
+[1 0 0 1 297.049 363.337] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -297.049 -363.337] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+297.049 363.337 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompress) 83.6858 Tj
+[1 0 0 1 380.735 363.337] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -380.735 -363.337] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+384.003 363.337 Td
+/F130_0 9.9626 Tf
+(with) 17.7135 Tj
+-328 TJm
+(an) 9.40469 Tj
+-328 TJm
+(action) 24.3486 Tj
+-328 TJm
+(of) 8.29885 Tj
+[1 0 0 1 456.841 363.337] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -456.841 -363.337] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+456.841 363.337 Td
+/F134_0 9.9626 Tf
+(BZ_FLUSH) 47.8205 Tj
+[1 0 0 1 504.662 363.337] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -504.662 -363.337] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+504.662 363.337 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-328 TJm
+(remo) 20.4731 Tj
+15 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+72 351.382 Td
+(output) 25.4644 Tj
+-445 TJm
+(data,) 19.0883 Tj
+-494 TJm
+(and) 14.386 Tj
+-446 TJm
+(persist) 26.0123 Tj
+-445 TJm
+(with) 17.7135 Tj
+-445 TJm
+(the) 12.1743 Tj
+[1 0 0 1 213.94 351.382] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -213.94 -351.382] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+213.94 351.382 Td
+/F134_0 9.9626 Tf
+(BZ_FLUSH) 47.8205 Tj
+[1 0 0 1 261.761 351.382] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -261.761 -351.382] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+266.195 351.382 Td
+/F130_0 9.9626 Tf
+(action) 24.3486 Tj
+-445 TJm
+(until) 18.2714 Tj
+-445 TJm
+(the) 12.1743 Tj
+-446 TJm
+(v) 4.9813 Tj
+25 TJm
+(alue) 16.5977 Tj
+[1 0 0 1 360.062 351.382] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -360.062 -351.382] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+360.062 351.382 Td
+/F134_0 9.9626 Tf
+(BZ_RUN) 35.8654 Tj
+[1 0 0 1 395.928 351.382] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -395.928 -351.382] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+400.362 351.382 Td
+/F130_0 9.9626 Tf
+(is) 6.64505 Tj
+-445 TJm
+(returned.) 35.686 Tj
+-1792 TJm
+(As) 11.0684 Tj
+-445 TJm
+(with) 17.7135 Tj
+-445 TJm
+(\002nishing,) 37.3697 Tj
+[1 0 0 1 72 339.427] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -339.427] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 339.427 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompress) 83.6858 Tj
+[1 0 0 1 155.686 339.427] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -155.686 -339.427] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+158.177 339.427 Td
+/F130_0 9.9626 Tf
+(detects) 27.6661 Tj
+-250 TJm
+(an) 9.40469 Tj
+15 TJm
+(y) 4.9813 Tj
+-250 TJm
+(attempt) 29.8878 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(pro) 13.2801 Tj
+15 TJm
+(vide) 17.1556 Tj
+-250 TJm
+(more) 20.4731 Tj
+-250 TJm
+(input) 20.4831 Tj
+-250 TJm
+(data) 16.5977 Tj
+-250 TJm
+(once) 18.8094 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(\003ush) 19.3773 Tj
+-250 TJm
+(has) 13.2801 Tj
+-250 TJm
+(be) 9.40469 Tj
+15 TJm
+(gun.) 17.4346 Tj
+[1 0 0 1 72 337.27] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -327.308] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 317.509 Td
+/F130_0 9.9626 Tf
+(Once) 21.0211 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(\003ush) 19.3773 Tj
+-250 TJm
+(is) 6.64505 Tj
+-250 TJm
+(complete,) 39.0135 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(stream) 26.5603 Tj
+-250 TJm
+(returns) 27.6661 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(normal) 28.224 Tj
+-250 TJm
+(R) 6.64505 Tj
+40 TJm
+(UNNING) 39.2825 Tj
+-250 TJm
+(state.) 20.7521 Tj
+[1 0 0 1 72 315.353] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -305.39] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 295.591 Td
+/F130_0 9.9626 Tf
+(This) 17.7135 Tj
+-344 TJm
+(all) 9.9626 Tj
+-343 TJm
+(sounds) 27.6761 Tj
+-344 TJm
+(pretty) 23.2427 Tj
+-344 TJm
+(comple) 29.3299 Tj
+15 TJm
+(x,) 7.47195 Tj
+-367 TJm
+(b) 4.9813 Tj
+20 TJm
+(ut) 7.7509 Tj
+-344 TJm
+(isn') 14.9439 Tj
+18 TJm
+(t) 2.7696 Tj
+-344 TJm
+(really) 22.6848 Tj
+65 TJm
+(.) 2.49065 Tj
+-1182 TJm
+(Here') 22.6749 Tj
+55 TJm
+(s) 3.87545 Tj
+-344 TJm
+(a) 4.42339 Tj
+-344 TJm
+(table) 19.3673 Tj
+-343 TJm
+(which) 24.3486 Tj
+-344 TJm
+(sho) 13.8381 Tj
+25 TJm
+(ws) 11.0684 Tj
+-344 TJm
+(which) 24.3486 Tj
+-344 TJm
+(actions) 28.224 Tj
+-343 TJm
+(are) 12.1643 Tj
+-344 TJm
+(allo) 14.9439 Tj
+25 TJm
+(w) 7.193 Tj
+10 TJm
+(able) 16.5977 Tj
+-344 TJm
+(in) 7.7509 Tj
+-344 TJm
+(each) 18.2515 Tj
+72 283.636 Td
+(state,) 20.7521 Tj
+-281 TJm
+(what) 19.3673 Tj
+-274 TJm
+(action) 24.3486 Tj
+-275 TJm
+(will) 15.5018 Tj
+-274 TJm
+(be) 9.40469 Tj
+-275 TJm
+(tak) 12.1743 Tj
+10 TJm
+(en,) 11.8953 Tj
+-280 TJm
+(what) 19.3673 Tj
+-275 TJm
+(the) 12.1743 Tj
+-274 TJm
+(ne) 9.40469 Tj
+15 TJm
+(xt) 7.7509 Tj
+-275 TJm
+(state) 18.2614 Tj
+-274 TJm
+(is,) 9.1357 Tj
+-281 TJm
+(and) 14.386 Tj
+-274 TJm
+(what) 19.3673 Tj
+-275 TJm
+(the) 12.1743 Tj
+-275 TJm
+(non-error) 37.6188 Tj
+-274 TJm
+(return) 23.7907 Tj
+-275 TJm
+(v) 4.9813 Tj
+25 TJm
+(alues) 20.4731 Tj
+-274 TJm
+(are.) 14.655 Tj
+-767 TJm
+(Note) 19.3673 Tj
+-275 TJm
+(that) 14.9439 Tj
+-274 TJm
+(you) 14.9439 Tj
+-275 TJm
+(can') 17.1456 Tj
+18 TJm
+(t) 2.7696 Tj
+72 271.681 Td
+(e) 4.42339 Tj
+15 TJm
+(xplicitly) 33.2153 Tj
+-347 TJm
+(ask) 13.2801 Tj
+-348 TJm
+(what) 19.3673 Tj
+-347 TJm
+(state) 18.2614 Tj
+-348 TJm
+(the) 12.1743 Tj
+-347 TJm
+(stream) 26.5603 Tj
+-348 TJm
+(is) 6.64505 Tj
+-347 TJm
+(in,) 10.2416 Tj
+-372 TJm
+(b) 4.9813 Tj
+20 TJm
+(ut) 7.7509 Tj
+-347 TJm
+(nor) 13.2801 Tj
+-348 TJm
+(do) 9.9626 Tj
+-347 TJm
+(you) 14.9439 Tj
+-348 TJm
+(need) 18.8094 Tj
+-347 TJm
+(to) 7.7509 Tj
+-348 TJm
+(--) 6.63509 Tj
+-347 TJm
+(it) 5.53921 Tj
+-348 TJm
+(can) 13.8281 Tj
+-347 TJm
+(be) 9.40469 Tj
+-347 TJm
+(inferred) 31.5316 Tj
+-348 TJm
+(from) 19.3673 Tj
+-347 TJm
+(the) 12.1743 Tj
+-348 TJm
+(v) 4.9813 Tj
+25 TJm
+(alues) 20.4731 Tj
+-347 TJm
+(returned) 33.1954 Tj
+-348 TJm
+(by) 9.9626 Tj
+[1 0 0 1 72 259.726] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -259.726] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 259.726 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompress) 83.6858 Tj
+[1 0 0 1 155.686 259.726] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -155.686 -259.726] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+155.686 259.726 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+[1 0 0 1 72 258.192] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -207.34] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 374.394 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 40.5726 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -493.841 -50.8518] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+534.414 50.8518 Td
+/F130_0 9.9626 Tf
+(14) 9.9626 Tj
+[1 0 0 1 453.269 50.8518] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 93.5985 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.2765 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+Q
+showpage
+%%PageTrailer
+pdfEndPage
+%%Page: 18 18
+%%BeginPageSetup
+%%PageOrientation: Portrait
+pdfStartPage
+0 0 612 792 re W
+%%EndPageSetup
+[] 0 d
+1 i
+0 j
+0 J
+10 M
+1 w
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+false op
+false OP
+0 0 612 792 re
+W
+q
+[1 0 0 1 72 741.554] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 14.4459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 187.197 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 -8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 76.4979 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -342.569 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+419.067 749.245 Td
+/F130_0 9.9626 Tf
+(Programming) 54.7943 Tj
+-250 TJm
+(with) 17.7135 Tj
+[1 0 0 1 496.556 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -496.556 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+496.556 749.245 Td
+/F134_0 9.9626 Tf
+(libbzip2) 47.8205 Tj
+[1 0 0 1 544.376 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -278.305 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 280.796 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -472.974 -5.0363] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -0.4981] cm
+q
+[] 0 d
+0 J
+0.4981 w
+0 0.2491 m
+475.465 0.2491 l
+S
+Q
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 479.251 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -595.402] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 573.848 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 570.261] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -711.631] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 711.631 Td
+/F134_0 9.9626 Tf
+(IDLE/any) 47.8205 Tj
+98.4879 699.676 Td
+(Illegal.) 47.8205 Tj
+-852 TJm
+(IDLE) 23.9102 Tj
+-426 TJm
+(state) 29.8878 Tj
+-426 TJm
+(only) 23.9102 Tj
+-426 TJm
+(exists) 35.8654 Tj
+-426 TJm
+(after) 29.8878 Tj
+-426 TJm
+(BZ2_bzCompressEnd) 101.619 Tj
+-426 TJm
+(or) 11.9551 Tj
+98.4879 687.721 Td
+(before) 35.8654 Tj
+-426 TJm
+(BZ2_bzCompressInit.) 113.574 Tj
+98.4879 675.766 Td
+(Return) 35.8654 Tj
+-426 TJm
+(value) 29.8878 Tj
+-426 TJm
+(=) 5.97756 Tj
+-426 TJm
+(BZ_SEQUENCE_ERROR) 101.619 Tj
+90 651.856 Td
+(RUNNING/BZ_RUN) 83.6858 Tj
+98.4879 639.9 Td
+(Compress) 47.8205 Tj
+-426 TJm
+(from) 23.9102 Tj
+-426 TJm
+(next_in) 41.8429 Tj
+-426 TJm
+(to) 11.9551 Tj
+-426 TJm
+(next_out) 47.8205 Tj
+-426 TJm
+(as) 11.9551 Tj
+-426 TJm
+(much) 23.9102 Tj
+-426 TJm
+(as) 11.9551 Tj
+-426 TJm
+(possible.) 53.798 Tj
+98.4879 627.945 Td
+(Next) 23.9102 Tj
+-426 TJm
+(state) 29.8878 Tj
+-426 TJm
+(=) 5.97756 Tj
+-426 TJm
+(RUNNING) 41.8429 Tj
+98.4879 615.99 Td
+(Return) 35.8654 Tj
+-426 TJm
+(value) 29.8878 Tj
+-426 TJm
+(=) 5.97756 Tj
+-426 TJm
+(BZ_RUN_OK) 53.798 Tj
+90 592.08 Td
+(RUNNING/BZ_FLUSH) 95.641 Tj
+98.4879 580.125 Td
+(Remember) 47.8205 Tj
+-426 TJm
+(current) 41.8429 Tj
+-426 TJm
+(value) 29.8878 Tj
+-426 TJm
+(of) 11.9551 Tj
+-426 TJm
+(next_in.) 47.8205 Tj
+-426 TJm
+(Compress) 47.8205 Tj
+-426 TJm
+(from) 23.9102 Tj
+-426 TJm
+(next_in) 41.8429 Tj
+98.4879 568.169 Td
+(to) 11.9551 Tj
+-426 TJm
+(next_out) 47.8205 Tj
+-426 TJm
+(as) 11.9551 Tj
+-426 TJm
+(much) 23.9102 Tj
+-426 TJm
+(as) 11.9551 Tj
+-426 TJm
+(possible,) 53.798 Tj
+-426 TJm
+(but) 17.9327 Tj
+-426 TJm
+(do) 11.9551 Tj
+-426 TJm
+(not) 17.9327 Tj
+-426 TJm
+(accept) 35.8654 Tj
+-426 TJm
+(any) 17.9327 Tj
+-426 TJm
+(more) 23.9102 Tj
+-426 TJm
+(input.) 35.8654 Tj
+98.4879 556.214 Td
+(Next) 23.9102 Tj
+-426 TJm
+(state) 29.8878 Tj
+-426 TJm
+(=) 5.97756 Tj
+-426 TJm
+(FLUSHING) 47.8205 Tj
+98.4879 544.259 Td
+(Return) 35.8654 Tj
+-426 TJm
+(value) 29.8878 Tj
+-426 TJm
+(=) 5.97756 Tj
+-426 TJm
+(BZ_FLUSH_OK) 65.7532 Tj
+90 520.349 Td
+(RUNNING/BZ_FINISH) 101.619 Tj
+98.4879 508.394 Td
+(Remember) 47.8205 Tj
+-426 TJm
+(current) 41.8429 Tj
+-426 TJm
+(value) 29.8878 Tj
+-426 TJm
+(of) 11.9551 Tj
+-426 TJm
+(next_in.) 47.8205 Tj
+-426 TJm
+(Compress) 47.8205 Tj
+-426 TJm
+(from) 23.9102 Tj
+-426 TJm
+(next_in) 41.8429 Tj
+98.4879 496.438 Td
+(to) 11.9551 Tj
+-426 TJm
+(next_out) 47.8205 Tj
+-426 TJm
+(as) 11.9551 Tj
+-426 TJm
+(much) 23.9102 Tj
+-426 TJm
+(as) 11.9551 Tj
+-426 TJm
+(possible,) 53.798 Tj
+-426 TJm
+(but) 17.9327 Tj
+-426 TJm
+(do) 11.9551 Tj
+-426 TJm
+(not) 17.9327 Tj
+-426 TJm
+(accept) 35.8654 Tj
+-426 TJm
+(any) 17.9327 Tj
+-426 TJm
+(more) 23.9102 Tj
+-426 TJm
+(input.) 35.8654 Tj
+98.4879 484.483 Td
+(Next) 23.9102 Tj
+-426 TJm
+(state) 29.8878 Tj
+-426 TJm
+(=) 5.97756 Tj
+-426 TJm
+(FINISHING) 53.798 Tj
+98.4879 472.528 Td
+(Return) 35.8654 Tj
+-426 TJm
+(value) 29.8878 Tj
+-426 TJm
+(=) 5.97756 Tj
+-426 TJm
+(BZ_FINISH_OK) 71.7307 Tj
+90 448.618 Td
+(FLUSHING/BZ_FLUSH) 101.619 Tj
+98.4879 436.663 Td
+(Compress) 47.8205 Tj
+-426 TJm
+(from) 23.9102 Tj
+-426 TJm
+(next_in) 41.8429 Tj
+-426 TJm
+(to) 11.9551 Tj
+-426 TJm
+(next_out) 47.8205 Tj
+-426 TJm
+(as) 11.9551 Tj
+-426 TJm
+(much) 23.9102 Tj
+-426 TJm
+(as) 11.9551 Tj
+-426 TJm
+(possible,) 53.798 Tj
+98.4879 424.707 Td
+(but) 17.9327 Tj
+-426 TJm
+(do) 11.9551 Tj
+-426 TJm
+(not) 17.9327 Tj
+-426 TJm
+(accept) 35.8654 Tj
+-426 TJm
+(any) 17.9327 Tj
+-426 TJm
+(more) 23.9102 Tj
+-426 TJm
+(input.) 35.8654 Tj
+98.4879 412.752 Td
+(If) 11.9551 Tj
+-426 TJm
+(all) 17.9327 Tj
+-426 TJm
+(the) 17.9327 Tj
+-426 TJm
+(existing) 47.8205 Tj
+-426 TJm
+(input) 29.8878 Tj
+-426 TJm
+(has) 17.9327 Tj
+-426 TJm
+(been) 23.9102 Tj
+-426 TJm
+(used) 23.9102 Tj
+-426 TJm
+(up) 11.9551 Tj
+-426 TJm
+(and) 17.9327 Tj
+-426 TJm
+(all) 17.9327 Tj
+-426 TJm
+(compressed) 59.7756 Tj
+98.4879 400.797 Td
+(output) 35.8654 Tj
+-426 TJm
+(has) 17.9327 Tj
+-426 TJm
+(been) 23.9102 Tj
+-426 TJm
+(removed) 41.8429 Tj
+106.976 388.842 Td
+(Next) 23.9102 Tj
+-426 TJm
+(state) 29.8878 Tj
+-426 TJm
+(=) 5.97756 Tj
+-426 TJm
+(RUNNING;) 47.8205 Tj
+-426 TJm
+(Return) 35.8654 Tj
+-426 TJm
+(value) 29.8878 Tj
+-426 TJm
+(=) 5.97756 Tj
+-426 TJm
+(BZ_RUN_OK) 53.798 Tj
+98.4879 376.887 Td
+(else) 23.9102 Tj
+106.976 364.932 Td
+(Next) 23.9102 Tj
+-426 TJm
+(state) 29.8878 Tj
+-426 TJm
+(=) 5.97756 Tj
+-426 TJm
+(FLUSHING;) 53.798 Tj
+-426 TJm
+(Return) 35.8654 Tj
+-426 TJm
+(value) 29.8878 Tj
+-426 TJm
+(=) 5.97756 Tj
+-426 TJm
+(BZ_FLUSH_OK) 65.7532 Tj
+90 341.021 Td
+(FLUSHING/other) 83.6858 Tj
+98.4879 329.066 Td
+(Illegal.) 47.8205 Tj
+98.4879 317.111 Td
+(Return) 35.8654 Tj
+-426 TJm
+(value) 29.8878 Tj
+-426 TJm
+(=) 5.97756 Tj
+-426 TJm
+(BZ_SEQUENCE_ERROR) 101.619 Tj
+90 293.201 Td
+(FINISHING/BZ_FINISH) 113.574 Tj
+98.4879 281.245 Td
+(Compress) 47.8205 Tj
+-426 TJm
+(from) 23.9102 Tj
+-426 TJm
+(next_in) 41.8429 Tj
+-426 TJm
+(to) 11.9551 Tj
+-426 TJm
+(next_out) 47.8205 Tj
+-426 TJm
+(as) 11.9551 Tj
+-426 TJm
+(much) 23.9102 Tj
+-426 TJm
+(as) 11.9551 Tj
+-426 TJm
+(possible,) 53.798 Tj
+98.4879 269.29 Td
+(but) 17.9327 Tj
+-426 TJm
+(to) 11.9551 Tj
+-426 TJm
+(not) 17.9327 Tj
+-426 TJm
+(accept) 35.8654 Tj
+-426 TJm
+(any) 17.9327 Tj
+-426 TJm
+(more) 23.9102 Tj
+-426 TJm
+(input.) 35.8654 Tj
+98.4879 257.335 Td
+(If) 11.9551 Tj
+-426 TJm
+(all) 17.9327 Tj
+-426 TJm
+(the) 17.9327 Tj
+-426 TJm
+(existing) 47.8205 Tj
+-426 TJm
+(input) 29.8878 Tj
+-426 TJm
+(has) 17.9327 Tj
+-426 TJm
+(been) 23.9102 Tj
+-426 TJm
+(used) 23.9102 Tj
+-426 TJm
+(up) 11.9551 Tj
+-426 TJm
+(and) 17.9327 Tj
+-426 TJm
+(all) 17.9327 Tj
+-426 TJm
+(compressed) 59.7756 Tj
+98.4879 245.38 Td
+(output) 35.8654 Tj
+-426 TJm
+(has) 17.9327 Tj
+-426 TJm
+(been) 23.9102 Tj
+-426 TJm
+(removed) 41.8429 Tj
+106.976 233.425 Td
+(Next) 23.9102 Tj
+-426 TJm
+(state) 29.8878 Tj
+-426 TJm
+(=) 5.97756 Tj
+-426 TJm
+(IDLE;) 29.8878 Tj
+-426 TJm
+(Return) 35.8654 Tj
+-426 TJm
+(value) 29.8878 Tj
+-426 TJm
+(=) 5.97756 Tj
+-426 TJm
+(BZ_STREAM_END) 77.7083 Tj
+98.4879 221.47 Td
+(else) 23.9102 Tj
+106.976 209.514 Td
+(Next) 23.9102 Tj
+-426 TJm
+(state) 29.8878 Tj
+-426 TJm
+(=) 5.97756 Tj
+-426 TJm
+(FINISHING;) 59.7756 Tj
+-426 TJm
+(Return) 35.8654 Tj
+-426 TJm
+(value) 29.8878 Tj
+-426 TJm
+(=) 5.97756 Tj
+-426 TJm
+(BZ_FINISH_OK) 71.7307 Tj
+90 185.604 Td
+(FINISHING/other) 89.6634 Tj
+98.4879 173.649 Td
+(Illegal.) 47.8205 Tj
+98.4879 161.694 Td
+(Return) 35.8654 Tj
+-426 TJm
+(value) 29.8878 Tj
+-426 TJm
+(=) 5.97756 Tj
+-426 TJm
+(BZ_SEQUENCE_ERROR) 101.619 Tj
+[1 0 0 1 72 146.152] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.5492] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -136.189] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 124.234 Td
+/F130_0 9.9626 Tf
+(That) 18.2614 Tj
+-250 TJm
+(still) 14.9539 Tj
+-250 TJm
+(looks) 21.589 Tj
+-250 TJm
+(complicated?) 53.1206 Tj
+-620 TJm
+(W) 9.40469 Tj
+80 TJm
+(ell,) 12.4533 Tj
+-250 TJm
+(f) 3.31755 Tj
+10 TJm
+(air) 10.5105 Tj
+-250 TJm
+(enough.) 31.8205 Tj
+-620 TJm
+(The) 15.4918 Tj
+-250 TJm
+(usual) 21.031 Tj
+-250 TJm
+(sequence) 36.5129 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(calls) 18.2614 Tj
+-250 TJm
+(for) 11.6164 Tj
+-250 TJm
+(compressing) 50.3609 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(load) 17.1556 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(data) 16.5977 Tj
+-250 TJm
+(is:) 9.41466 Tj
+[1 0 0 1 72 122.077] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -29.7236] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 7.3724 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -79.3724 -92.3537] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+79.3724 92.3537 Td
+/F130_0 9.9626 Tf
+(1.) 7.47195 Tj
+[1 0 0 1 86.8444 92.3537] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 3.0884 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 1.9925 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -91.9253 -92.3537] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+91.9253 92.3537 Td
+/F130_0 9.9626 Tf
+(Get) 14.386 Tj
+-250 TJm
+(started) 26.5603 Tj
+-250 TJm
+(with) 17.7135 Tj
+[1 0 0 1 158.056 92.3537] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -158.056 -92.3537] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+158.056 92.3537 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompressInit) 107.596 Tj
+[1 0 0 1 265.653 92.3537] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -265.653 -92.3537] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+265.653 92.3537 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+[1 0 0 1 268.144 92.3537] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -196.144 -41.5019] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.893 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 374.394 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 6.8542] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 40.5726 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -493.841 -50.9514] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+534.414 50.9514 Td
+/F130_0 9.9626 Tf
+(15) 9.9626 Tj
+[1 0 0 1 453.269 50.8518] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 93.5985 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.2765 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+Q
+showpage
+%%PageTrailer
+pdfEndPage
+%%Page: 19 19
+%%BeginPageSetup
+%%PageOrientation: Portrait
+pdfStartPage
+0 0 612 792 re W
+%%EndPageSetup
+[] 0 d
+1 i
+0 j
+0 J
+10 M
+1 w
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+false op
+false OP
+0 0 612 792 re
+W
+q
+[1 0 0 1 72 741.554] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 14.4459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 187.197 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 -8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 76.4979 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -342.569 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+419.067 749.245 Td
+/F130_0 9.9626 Tf
+(Programming) 54.7943 Tj
+-250 TJm
+(with) 17.7135 Tj
+[1 0 0 1 496.556 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -496.556 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+496.556 749.245 Td
+/F134_0 9.9626 Tf
+(libbzip2) 47.8205 Tj
+[1 0 0 1 544.376 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -278.305 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 280.796 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -472.974 -5.0363] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -0.4981] cm
+q
+[] 0 d
+0 J
+0.4981 w
+0 0.2491 m
+475.465 0.2491 l
+S
+Q
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 479.251 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -31.5168] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 7.3724 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -79.3724 -710.037] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+79.3724 710.037 Td
+/F130_0 9.9626 Tf
+(2.) 7.47195 Tj
+[1 0 0 1 86.8444 710.037] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 3.0884 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 1.9925 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -91.9253 -710.037] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+91.9253 710.037 Td
+/F130_0 9.9626 Tf
+(Sho) 15.5018 Tj
+15 TJm
+(v) 4.9813 Tj
+15 TJm
+(el) 7.193 Tj
+-240 TJm
+(data) 16.5977 Tj
+-240 TJm
+(in) 7.7509 Tj
+-241 TJm
+(and) 14.386 Tj
+-240 TJm
+(shlurp) 24.9065 Tj
+-240 TJm
+(out) 12.7322 Tj
+-240 TJm
+(its) 9.41466 Tj
+-240 TJm
+(compressed) 47.0334 Tj
+-241 TJm
+(form) 19.3673 Tj
+-240 TJm
+(using) 21.589 Tj
+-240 TJm
+(zero) 17.1456 Tj
+-240 TJm
+(or) 8.29885 Tj
+-240 TJm
+(more) 20.4731 Tj
+-241 TJm
+(calls) 18.2614 Tj
+-240 TJm
+(of) 8.29885 Tj
+[1 0 0 1 401.454 710.037] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -401.454 -710.037] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+401.454 710.037 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompress) 83.6858 Tj
+[1 0 0 1 485.14 710.037] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -485.14 -710.037] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+487.533 710.037 Td
+/F130_0 9.9626 Tf
+(with) 17.7135 Tj
+-240 TJm
+(action) 24.3486 Tj
+-240 TJm
+(=) 5.61891 Tj
+[1 0 0 1 91.9253 698.082] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -91.9253 -698.082] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+91.9253 698.082 Td
+/F134_0 9.9626 Tf
+(BZ_RUN) 35.8654 Tj
+[1 0 0 1 127.791 698.082] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -127.791 -698.082] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+127.791 698.082 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+[1 0 0 1 130.281 698.082] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -58.2814 -21.9178] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 7.3724 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -79.3724 -676.164] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+79.3724 676.164 Td
+/F130_0 9.9626 Tf
+(3.) 7.47195 Tj
+[1 0 0 1 86.8444 676.164] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 3.0884 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 1.9925 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -91.9253 -676.164] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+91.9253 676.164 Td
+/F130_0 9.9626 Tf
+(Finish) 24.9165 Tj
+-242 TJm
+(up.) 12.4533 Tj
+-307 TJm
+(Repeatedly) 44.8217 Tj
+-241 TJm
+(call) 14.386 Tj
+[1 0 0 1 198.784 676.164] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -198.784 -676.164] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+198.784 676.164 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompress) 83.6858 Tj
+[1 0 0 1 282.471 676.164] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -282.471 -676.164] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+284.878 676.164 Td
+/F130_0 9.9626 Tf
+(with) 17.7135 Tj
+-242 TJm
+(action) 24.3486 Tj
+-241 TJm
+(=) 5.61891 Tj
+[1 0 0 1 339.78 676.164] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -339.78 -676.164] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+339.78 676.164 Td
+/F134_0 9.9626 Tf
+(BZ_FINISH) 53.798 Tj
+[1 0 0 1 393.579 676.164] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -393.579 -676.164] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+393.579 676.164 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-242 TJm
+(cop) 14.386 Tj
+10 TJm
+(ying) 17.7135 Tj
+-241 TJm
+(out) 12.7322 Tj
+-242 TJm
+(the) 12.1743 Tj
+-242 TJm
+(compres) 33.7533 Tj
+1 TJm
+(sed) 13.2801 Tj
+-242 TJm
+(output,) 27.9551 Tj
+91.9253 664.209 Td
+(until) 18.2714 Tj
+[1 0 0 1 112.687 664.209] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -112.687 -664.209] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+112.687 664.209 Td
+/F134_0 9.9626 Tf
+(BZ_STREAM_END) 77.7083 Tj
+[1 0 0 1 190.396 664.209] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -190.396 -664.209] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+192.886 664.209 Td
+/F130_0 9.9626 Tf
+(is) 6.64505 Tj
+-250 TJm
+(returned.) 35.686 Tj
+[1 0 0 1 237.708 664.209] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -165.708 -21.9178] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 7.3724 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -79.3724 -642.291] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+79.3724 642.291 Td
+/F130_0 9.9626 Tf
+(4.) 7.47195 Tj
+[1 0 0 1 86.8444 642.291] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 3.0884 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 1.9925 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -91.9253 -642.291] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+91.9253 642.291 Td
+/F130_0 9.9626 Tf
+(Close) 22.6948 Tj
+-250 TJm
+(up) 9.9626 Tj
+-250 TJm
+(and) 14.386 Tj
+-250 TJm
+(go) 9.9626 Tj
+-250 TJm
+(home.) 24.6275 Tj
+-620 TJm
+(Call) 16.6077 Tj
+[1 0 0 1 208.796 642.291] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -208.796 -642.291] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+208.796 642.291 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompressEnd) 101.619 Tj
+[1 0 0 1 310.415 642.291] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -310.415 -642.291] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+310.415 642.291 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+[1 0 0 1 312.906 642.291] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -240.906 -12.1195] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -630.172] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 620.374 Td
+/F130_0 9.9626 Tf
+(If) 6.63509 Tj
+-269 TJm
+(the) 12.1743 Tj
+-270 TJm
+(data) 16.5977 Tj
+-269 TJm
+(you) 14.9439 Tj
+-270 TJm
+(w) 7.193 Tj
+10 TJm
+(ant) 12.1743 Tj
+-269 TJm
+(to) 7.7509 Tj
+-270 TJm
+(compress) 37.6287 Tj
+-269 TJm
+(\002ts) 12.1843 Tj
+-270 TJm
+(into) 15.5018 Tj
+-269 TJm
+(your) 18.2614 Tj
+-270 TJm
+(input) 20.4831 Tj
+-269 TJm
+(b) 4.9813 Tj
+20 TJm
+(uf) 8.29885 Tj
+25 TJm
+(fer) 11.0585 Tj
+-270 TJm
+(all) 9.9626 Tj
+-269 TJm
+(at) 7.193 Tj
+-270 TJm
+(once,) 21.3 Tj
+-274 TJm
+(you) 14.9439 Tj
+-269 TJm
+(can) 13.8281 Tj
+-270 TJm
+(skip) 16.6077 Tj
+-269 TJm
+(the) 12.1743 Tj
+-270 TJm
+(calls) 18.2614 Tj
+-269 TJm
+(of) 8.29885 Tj
+[1 0 0 1 456.314 620.374] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -456.314 -620.374] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+456.314 620.374 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompress) 83.6858 Tj
+72 608.418 Td
+(\() 5.97756 Tj
+-600 TJm
+(...,) 23.9102 Tj
+-600 TJm
+(BZ_RUN) 35.8654 Tj
+-600 TJm
+(\)) 5.97756 Tj
+[1 0 0 1 161.664 608.418] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -161.664 -608.418] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+164.154 608.418 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+-250 TJm
+(just) 14.396 Tj
+-250 TJm
+(do) 9.9626 Tj
+-250 TJm
+(the) 12.1743 Tj
+[1 0 0 1 225.036 608.418] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -225.036 -608.418] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+225.036 608.418 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompress) 83.6858 Tj
+-600 TJm
+(\() 5.97756 Tj
+-600 TJm
+(...,) 23.9102 Tj
+-600 TJm
+(BZ_FINISH) 53.798 Tj
+-600 TJm
+(\)) 5.97756 Tj
+[1 0 0 1 422.296 608.418] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -422.296 -608.418] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+424.786 608.418 Td
+/F130_0 9.9626 Tf
+(calls.) 20.7521 Tj
+[1 0 0 1 72 606.262] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -596.299] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 586.501 Td
+/F130_0 9.9626 Tf
+(All) 12.7322 Tj
+-278 TJm
+(required) 33.1954 Tj
+-277 TJm
+(memory) 33.2053 Tj
+-278 TJm
+(is) 6.64505 Tj
+-277 TJm
+(allocated) 35.965 Tj
+-278 TJm
+(by) 9.9626 Tj
+[1 0 0 1 220.295 586.501] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -220.295 -586.501] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+220.295 586.501 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompressInit) 107.596 Tj
+[1 0 0 1 327.891 586.501] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -327.891 -586.501] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+327.891 586.501 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+-785 TJm
+(The) 15.4918 Tj
+-278 TJm
+(compression) 50.3609 Tj
+-277 TJm
+(library) 26.5603 Tj
+-278 TJm
+(can) 13.8281 Tj
+-277 TJm
+(accept) 25.4445 Tj
+-278 TJm
+(an) 9.40469 Tj
+15 TJm
+(y) 4.9813 Tj
+-277 TJm
+(data) 16.5977 Tj
+-278 TJm
+(at) 7.193 Tj
+-278 TJm
+(all) 9.9626 Tj
+72 574.545 Td
+(\(ob) 13.2801 Tj
+15 TJm
+(viously\).) 35.1481 Tj
+-612 TJm
+(So) 10.5205 Tj
+-238 TJm
+(you) 14.9439 Tj
+-237 TJm
+(shouldn') 34.8691 Tj
+18 TJm
+(t) 2.7696 Tj
+-238 TJm
+(get) 12.1743 Tj
+-238 TJm
+(an) 9.40469 Tj
+15 TJm
+(y) 4.9813 Tj
+-237 TJm
+(error) 19.3573 Tj
+-238 TJm
+(return) 23.7907 Tj
+-238 TJm
+(v) 4.9813 Tj
+25 TJm
+(alues) 20.4731 Tj
+-238 TJm
+(from) 19.3673 Tj
+-237 TJm
+(the) 12.1743 Tj
+[1 0 0 1 339.287 574.545] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -339.287 -574.545] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+339.287 574.545 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompress) 83.6858 Tj
+[1 0 0 1 422.973 574.545] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -422.973 -574.545] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+425.342 574.545 Td
+/F130_0 9.9626 Tf
+(calls.) 20.7521 Tj
+-612 TJm
+(If) 6.63509 Tj
+-238 TJm
+(you) 14.9439 Tj
+-237 TJm
+(do,) 12.4533 Tj
+-240 TJm
+(the) 12.1743 Tj
+15 TJm
+(y) 4.9813 Tj
+-238 TJm
+(will) 15.5018 Tj
+-238 TJm
+(be) 9.40469 Tj
+[1 0 0 1 72 562.59] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -562.59] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 562.59 Td
+/F134_0 9.9626 Tf
+(BZ_SEQUENCE_ERROR) 101.619 Tj
+[1 0 0 1 173.619 562.59] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -173.619 -562.59] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+173.619 562.59 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-250 TJm
+(and) 14.386 Tj
+-250 TJm
+(indicate) 31.5416 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(b) 4.9813 Tj
+20 TJm
+(ug) 9.9626 Tj
+-250 TJm
+(in) 7.7509 Tj
+-250 TJm
+(your) 18.2614 Tj
+-250 TJm
+(programming.) 56.727 Tj
+[1 0 0 1 72 560.433] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -550.471] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 540.673 Td
+/F130_0 9.9626 Tf
+(T) 6.08715 Tj
+35 TJm
+(ri) 6.08715 Tj
+25 TJm
+(vial) 14.9439 Tj
+-250 TJm
+(other) 20.4731 Tj
+-250 TJm
+(possible) 32.6574 Tj
+-250 TJm
+(return) 23.7907 Tj
+-250 TJm
+(v) 4.9813 Tj
+25 TJm
+(alues:) 23.2427 Tj
+[1 0 0 1 72 538.516] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -36.8617] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 35.8655 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 32.2789] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -529.151] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 529.151 Td
+/F134_0 9.9626 Tf
+(BZ_PARAM_ERROR) 83.6858 Tj
+98.4879 517.196 Td
+(if) 11.9551 Tj
+-426 TJm
+(strm) 23.9102 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(NULL,) 29.8878 Tj
+-426 TJm
+(or) 11.9551 Tj
+-426 TJm
+(strm->s) 41.8429 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(NULL) 23.9102 Tj
+[1 0 0 1 72 501.654] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -491.691] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 471.033 Td
+/F122_0 17.2154 Tf
+(3.3.3.) 43.0729 Tj
+[1 0 0 1 119.858 471.033] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -119.858 -471.033] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+119.858 471.033 Td
+/F392_0 17.2154 Tf
+(BZ2_bzCompressEnd) 175.597 Tj
+[1 0 0 1 295.455 471.033] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -223.455 -2.3326] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -24.9066] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 23.9103 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 20.3237] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -459.335] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 459.335 Td
+/F134_0 9.9626 Tf
+(int) 17.9327 Tj
+-426 TJm
+(BZ2_bzCompressEnd) 101.619 Tj
+-426 TJm
+(\() 5.97756 Tj
+-426 TJm
+(bz_stream) 53.798 Tj
+286.303 457.592 Td
+(*) 5.97756 Tj
+292.281 459.335 Td
+(strm) 23.9102 Tj
+-426 TJm
+(\);) 11.9551 Tj
+[1 0 0 1 72 443.793] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.5493] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -433.831] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 421.876 Td
+/F130_0 9.9626 Tf
+(Releases) 34.8591 Tj
+-250 TJm
+(all) 9.9626 Tj
+-250 TJm
+(memory) 33.2053 Tj
+-250 TJm
+(associated) 40.9463 Tj
+-250 TJm
+(with) 17.7135 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(compression) 50.3609 Tj
+-250 TJm
+(stream.) 29.0509 Tj
+[1 0 0 1 72 419.719] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -409.756] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 399.958 Td
+/F130_0 9.9626 Tf
+(Possible) 33.2153 Tj
+-250 TJm
+(return) 23.7907 Tj
+-250 TJm
+(v) 4.9813 Tj
+25 TJm
+(alues:) 23.2427 Tj
+[1 0 0 1 72 399.858] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -36.8618] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 35.8655 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 32.2789] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -390.493] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 390.493 Td
+/F134_0 9.9626 Tf
+(BZ_PARAM_ERROR) 83.6858 Tj
+-852 TJm
+(if) 11.9551 Tj
+-426 TJm
+(strm) 23.9102 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(NULL) 23.9102 Tj
+-426 TJm
+(or) 11.9551 Tj
+-426 TJm
+(strm->s) 41.8429 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(NULL) 23.9102 Tj
+90 378.538 Td
+(BZ_OK) 29.8878 Tj
+-4686 TJm
+(otherwise) 53.798 Tj
+[1 0 0 1 72 362.996] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -353.034] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 332.375 Td
+/F122_0 17.2154 Tf
+(3.3.4.) 43.0729 Tj
+[1 0 0 1 119.858 332.375] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -119.858 -332.375] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+119.858 332.375 Td
+/F392_0 17.2154 Tf
+(BZ2_bzDecompressInit) 206.585 Tj
+[1 0 0 1 326.443 332.375] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -254.443 -2.3327] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -24.9066] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 23.9103 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 20.3237] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3685] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -320.678] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 320.678 Td
+/F134_0 9.9626 Tf
+(int) 17.9327 Tj
+-426 TJm
+(BZ2_bzDecompressInit) 119.551 Tj
+-426 TJm
+(\() 5.97756 Tj
+-426 TJm
+(bz_stream) 53.798 Tj
+304.236 318.934 Td
+(*) 5.97756 Tj
+310.214 320.678 Td
+(strm,) 29.8878 Tj
+-426 TJm
+(int) 17.9327 Tj
+-426 TJm
+(verbosity,) 59.7756 Tj
+-426 TJm
+(int) 17.9327 Tj
+-426 TJm
+(small) 29.8878 Tj
+-426 TJm
+(\);) 11.9551 Tj
+[1 0 0 1 72 305.136] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.5492] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -295.173] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 283.218 Td
+/F130_0 9.9626 Tf
+(Prepares) 34.3012 Tj
+-351 TJm
+(for) 11.6164 Tj
+-351 TJm
+(decompression.) 62.2563 Tj
+-1228 TJm
+(As) 11.0684 Tj
+-351 TJm
+(with) 17.7135 Tj
+[1 0 0 1 235.177 283.218] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -235.177 -283.218] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+235.177 283.218 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompressInit) 107.596 Tj
+[1 0 0 1 342.773 283.218] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -342.773 -283.218] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+342.773 283.218 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-377 TJm
+(a) 4.42339 Tj
+[1 0 0 1 356.937 283.218] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -356.937 -283.218] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+356.937 283.218 Td
+/F134_0 9.9626 Tf
+(bz_stream) 53.798 Tj
+[1 0 0 1 410.736 283.218] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -410.736 -283.218] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+414.235 283.218 Td
+/F130_0 9.9626 Tf
+(record) 25.4445 Tj
+-351 TJm
+(should) 26.5703 Tj
+-351 TJm
+(be) 9.40469 Tj
+-352 TJm
+(allocated) 35.965 Tj
+-351 TJm
+(and) 14.386 Tj
+72 271.263 Td
+(initialised) 39.3025 Tj
+-306 TJm
+(before) 25.4445 Tj
+-305 TJm
+(the) 12.1743 Tj
+-306 TJm
+(call.) 16.8766 Tj
+-953 TJm
+(Fields) 24.3586 Tj
+[1 0 0 1 211.833 271.263] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -211.833 -271.263] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+211.833 271.263 Td
+/F134_0 9.9626 Tf
+(bzalloc) 41.8429 Tj
+[1 0 0 1 253.676 271.263] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -253.676 -271.263] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+253.676 271.263 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 259.35 271.263] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -259.35 -271.263] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+259.35 271.263 Td
+/F134_0 9.9626 Tf
+(bzfree) 35.8654 Tj
+[1 0 0 1 295.215 271.263] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -295.215 -271.263] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+298.26 271.263 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 315.69 271.263] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -315.69 -271.263] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+315.69 271.263 Td
+/F134_0 9.9626 Tf
+(opaque) 35.8654 Tj
+[1 0 0 1 351.556 271.263] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -351.556 -271.263] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+354.6 271.263 Td
+/F130_0 9.9626 Tf
+(should) 26.5703 Tj
+-306 TJm
+(be) 9.40469 Tj
+-305 TJm
+(set) 11.0684 Tj
+-306 TJm
+(if) 6.08715 Tj
+-305 TJm
+(a) 4.42339 Tj
+-306 TJm
+(custom) 28.782 Tj
+-305 TJm
+(memory) 33.2053 Tj
+-306 TJm
+(allocator) 34.8591 Tj
+-306 TJm
+(is) 6.64505 Tj
+72 259.308 Td
+(required,) 35.686 Tj
+-350 TJm
+(or) 8.29885 Tj
+-331 TJm
+(made) 21.579 Tj
+[1 0 0 1 147.635 259.308] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -147.635 -259.308] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+147.635 259.308 Td
+/F134_0 9.9626 Tf
+(NULL) 23.9102 Tj
+[1 0 0 1 171.546 259.308] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -171.546 -259.308] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+174.835 259.308 Td
+/F130_0 9.9626 Tf
+(for) 11.6164 Tj
+-330 TJm
+(the) 12.1743 Tj
+-331 TJm
+(normal) 28.224 Tj
+[1 0 0 1 236.722 259.308] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -236.722 -259.308] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+236.722 259.308 Td
+/F134_0 9.9626 Tf
+(malloc) 35.8654 Tj
+[1 0 0 1 272.587 259.308] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -272.587 -259.308] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+275.878 259.308 Td
+/F130_0 9.9626 Tf
+(/) 2.7696 Tj
+[1 0 0 1 281.938 259.308] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -281.938 -259.308] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+281.938 259.308 Td
+/F134_0 9.9626 Tf
+(free) 23.9102 Tj
+[1 0 0 1 305.848 259.308] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -305.848 -259.308] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+309.139 259.308 Td
+/F130_0 9.9626 Tf
+(routines.) 34.5901 Tj
+-1102 TJm
+(Upon) 22.1369 Tj
+-330 TJm
+(return,) 26.2813 Tj
+-350 TJm
+(the) 12.1743 Tj
+-331 TJm
+(internal) 30.4357 Tj
+-330 TJm
+(state) 18.2614 Tj
+-330 TJm
+(will) 15.5018 Tj
+-330 TJm
+(ha) 9.40469 Tj
+20 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-331 TJm
+(been) 18.8094 Tj
+72 247.353 Td
+(initialised,) 41.7931 Tj
+-250 TJm
+(and) 14.386 Tj
+[1 0 0 1 133.16 247.353] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -133.16 -247.353] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+133.16 247.353 Td
+/F134_0 9.9626 Tf
+(total_in) 47.8205 Tj
+[1 0 0 1 180.98 247.353] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -180.98 -247.353] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+183.471 247.353 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 200.348 247.353] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -200.348 -247.353] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+200.348 247.353 Td
+/F134_0 9.9626 Tf
+(total_out) 53.798 Tj
+[1 0 0 1 254.146 247.353] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -254.146 -247.353] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+256.637 247.353 Td
+/F130_0 9.9626 Tf
+(will) 15.5018 Tj
+-250 TJm
+(be) 9.40469 Tj
+-250 TJm
+(zero.) 19.6363 Tj
+[1 0 0 1 72 245.913] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -235.951] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 225.435 Td
+/F130_0 9.9626 Tf
+(F) 5.53921 Tj
+15 TJm
+(or) 8.29885 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(meaning) 34.3112 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(parameter) 39.8305 Tj
+[1 0 0 1 192.756 225.435] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -192.756 -225.435] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+192.756 225.435 Td
+/F134_0 9.9626 Tf
+(verbosity) 53.798 Tj
+[1 0 0 1 246.554 225.435] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -246.554 -225.435] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+246.554 225.435 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-250 TJm
+(see) 12.7222 Tj
+[1 0 0 1 266.748 225.435] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -266.748 -225.435] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+266.748 225.435 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompressInit) 107.596 Tj
+[1 0 0 1 374.345 225.435] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -374.345 -225.435] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+374.345 225.435 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+[1 0 0 1 72 223.278] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -213.315] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 203.517 Td
+/F130_0 9.9626 Tf
+(If) 6.63509 Tj
+[1 0 0 1 81.4975 203.517] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -81.4975 -203.517] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+81.4975 203.517 Td
+/F134_0 9.9626 Tf
+(small) 29.8878 Tj
+[1 0 0 1 111.385 203.517] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -111.385 -203.517] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+114.248 203.517 Td
+/F130_0 9.9626 Tf
+(is) 6.64505 Tj
+-287 TJm
+(nonzero,) 34.5802 Tj
+-297 TJm
+(the) 12.1743 Tj
+-287 TJm
+(library) 26.5603 Tj
+-288 TJm
+(will) 15.5018 Tj
+-287 TJm
+(use) 13.2801 Tj
+-287 TJm
+(an) 9.40469 Tj
+-287 TJm
+(alternati) 32.6474 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-288 TJm
+(decompression) 59.7656 Tj
+-287 TJm
+(algorithm) 38.7446 Tj
+-287 TJm
+(which) 24.3486 Tj
+-288 TJm
+(uses) 17.1556 Tj
+-287 TJm
+(less) 14.9439 Tj
+-287 TJm
+(memory) 33.2053 Tj
+-287 TJm
+(b) 4.9813 Tj
+20 TJm
+(ut) 7.7509 Tj
+-288 TJm
+(at) 7.193 Tj
+-287 TJm
+(the) 12.1743 Tj
+72 191.562 Td
+(cost) 16.0497 Tj
+-289 TJm
+(of) 8.29885 Tj
+-290 TJm
+(decompressing) 59.7656 Tj
+-289 TJm
+(more) 20.4731 Tj
+-289 TJm
+(slo) 11.6264 Tj
+25 TJm
+(wly) 14.9439 Tj
+-290 TJm
+(\(roughly) 34.3112 Tj
+-289 TJm
+(speaking,) 37.9077 Tj
+-299 TJm
+(half) 15.4918 Tj
+-290 TJm
+(the) 12.1743 Tj
+-289 TJm
+(speed,) 25.1755 Tj
+-299 TJm
+(b) 4.9813 Tj
+20 TJm
+(ut) 7.7509 Tj
+-289 TJm
+(the) 12.1743 Tj
+-290 TJm
+(maximum) 40.4083 Tj
+-289 TJm
+(memory) 33.2053 Tj
+-289 TJm
+(requirement) 48.1393 Tj
+-290 TJm
+(drops) 22.1369 Tj
+72 179.607 Td
+(to) 7.7509 Tj
+-250 TJm
+(around) 27.6661 Tj
+-250 TJm
+(2300k\).) 30.7147 Tj
+-620 TJm
+(See) 14.386 Tj
+[1 0 0 1 166.166 179.607] cm
+/DeviceRGB {} cs
+[0 0 1] sc
+/DeviceRGB {} CS
+[0 0 1] SC
+[1 0 0 1 -166.166 -179.607] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+166.166 179.607 Td
+/F130_0 9.9626 Tf
+(Ho) 12.1743 Tj
+25 TJm
+(w) 7.193 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(use) 13.2801 Tj
+-250 TJm
+(bzip2) 22.1369 Tj
+[1 0 0 1 235.924 179.607] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 1] sc
+/DeviceRGB {} CS
+[0 0 1] SC
+/DeviceRGB {} cs
+[0 0 1] sc
+/DeviceRGB {} CS
+[0 0 1] SC
+[1 0 0 1 -235.924 -179.607] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+238.415 179.607 Td
+/F130_0 9.9626 Tf
+([2]) 11.6164 Tj
+[1 0 0 1 250.031 179.607] cm
+/DeviceRGB {} cs
+[0 0 1] sc
+/DeviceRGB {} CS
+[0 0 1] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -250.031 -179.607] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+252.522 179.607 Td
+/F130_0 9.9626 Tf
+(for) 11.6164 Tj
+-250 TJm
+(more) 20.4731 Tj
+-250 TJm
+(information) 47.0434 Tj
+-250 TJm
+(on) 9.9626 Tj
+-250 TJm
+(memory) 33.2053 Tj
+-250 TJm
+(management.) 53.3995 Tj
+[1 0 0 1 72 177.45] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -167.487] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 157.689 Td
+/F130_0 9.9626 Tf
+(Note) 19.3673 Tj
+-289 TJm
+(that) 14.9439 Tj
+-290 TJm
+(the) 12.1743 Tj
+-289 TJm
+(amount) 29.8878 Tj
+-289 TJm
+(of) 8.29885 Tj
+-289 TJm
+(memory) 33.2053 Tj
+-290 TJm
+(needed) 28.2141 Tj
+-289 TJm
+(to) 7.7509 Tj
+-289 TJm
+(decompress) 47.0334 Tj
+-289 TJm
+(a) 4.42339 Tj
+-290 TJm
+(stream) 26.5603 Tj
+-289 TJm
+(cannot) 26.5603 Tj
+-289 TJm
+(be) 9.40469 Tj
+-289 TJm
+(determined) 44.8217 Tj
+-290 TJm
+(until) 18.2714 Tj
+-289 TJm
+(the) 12.1743 Tj
+-289 TJm
+(stream') 29.8778 Tj
+55 TJm
+(s) 3.87545 Tj
+-289 TJm
+(header) 26.5503 Tj
+-290 TJm
+(has) 13.2801 Tj
+72 145.734 Td
+(been) 18.8094 Tj
+-342 TJm
+(read,) 19.6363 Tj
+-366 TJm
+(so) 8.85675 Tj
+-342 TJm
+(e) 4.42339 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(en) 9.40469 Tj
+-342 TJm
+(if) 6.08715 Tj
+[1 0 0 1 161.081 145.734] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -161.081 -145.734] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+161.081 145.734 Td
+/F134_0 9.9626 Tf
+(BZ2_bzDecompressInit) 119.551 Tj
+[1 0 0 1 280.633 145.734] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -280.633 -145.734] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+284.043 145.734 Td
+/F130_0 9.9626 Tf
+(succeeds,) 37.8977 Tj
+-365 TJm
+(a) 4.42339 Tj
+-343 TJm
+(subsequent) 44.2738 Tj
+[1 0 0 1 381.098 145.734] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -381.098 -145.734] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+381.098 145.734 Td
+/F134_0 9.9626 Tf
+(BZ2_bzDecompress) 95.641 Tj
+[1 0 0 1 476.739 145.734] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -476.739 -145.734] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+480.149 145.734 Td
+/F130_0 9.9626 Tf
+(could) 22.1369 Tj
+-342 TJm
+(f) 3.31755 Tj
+10 TJm
+(ail) 9.9626 Tj
+-343 TJm
+(with) 17.7135 Tj
+[1 0 0 1 72 133.779] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -133.779] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 133.779 Td
+/F134_0 9.9626 Tf
+(BZ_MEM_ERROR) 71.7307 Tj
+[1 0 0 1 143.731 133.779] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -143.731 -133.779] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+143.731 133.779 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+[1 0 0 1 72 132.469] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -122.506] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 111.861 Td
+/F130_0 9.9626 Tf
+(Possible) 33.2153 Tj
+-250 TJm
+(return) 23.7907 Tj
+-250 TJm
+(v) 4.9813 Tj
+25 TJm
+(alues:) 23.2427 Tj
+[1 0 0 1 72 111.761] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -60.9095] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 374.394 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 6.8541] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 40.5726 -6.7545] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -493.841 -50.9514] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+534.414 50.9514 Td
+/F130_0 9.9626 Tf
+(16) 9.9626 Tj
+[1 0 0 1 453.269 50.8518] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 93.5985 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.2765 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+Q
+showpage
+%%PageTrailer
+pdfEndPage
+%%Page: 20 20
+%%BeginPageSetup
+%%PageOrientation: Portrait
+pdfStartPage
+0 0 612 792 re W
+%%EndPageSetup
+[] 0 d
+1 i
+0 j
+0 J
+10 M
+1 w
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+false op
+false OP
+0 0 612 792 re
+W
+q
+[1 0 0 1 72 741.554] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 14.4459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 187.197 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 -8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 76.4979 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -342.569 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+419.067 749.245 Td
+/F130_0 9.9626 Tf
+(Programming) 54.7943 Tj
+-250 TJm
+(with) 17.7135 Tj
+[1 0 0 1 496.556 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -496.556 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+496.556 749.245 Td
+/F134_0 9.9626 Tf
+(libbzip2) 47.8205 Tj
+[1 0 0 1 544.376 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -278.305 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 280.796 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -472.974 -5.0363] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -0.4981] cm
+q
+[] 0 d
+0 J
+0.4981 w
+0 0.2491 m
+475.465 0.2491 l
+S
+Q
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 479.251 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -117.195] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 95.6413 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 92.0547] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -711.631] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 711.631 Td
+/F134_0 9.9626 Tf
+(BZ_CONFIG_ERROR) 89.6634 Tj
+98.4879 699.676 Td
+(if) 11.9551 Tj
+-426 TJm
+(the) 17.9327 Tj
+-426 TJm
+(library) 41.8429 Tj
+-426 TJm
+(has) 17.9327 Tj
+-426 TJm
+(been) 23.9102 Tj
+-426 TJm
+(mis-compiled) 71.7307 Tj
+90 687.721 Td
+(BZ_PARAM_ERROR) 83.6858 Tj
+98.4879 675.766 Td
+(if) 11.9551 Tj
+-426 TJm
+(\() 5.97756 Tj
+-426 TJm
+(small) 29.8878 Tj
+-426 TJm
+(!=) 11.9551 Tj
+-426 TJm
+(0) 5.97756 Tj
+-426 TJm
+(&&) 11.9551 Tj
+-426 TJm
+(small) 29.8878 Tj
+-426 TJm
+(!=) 11.9551 Tj
+-426 TJm
+(1) 5.97756 Tj
+-426 TJm
+(\)) 5.97756 Tj
+98.4879 663.811 Td
+(or) 11.9551 Tj
+-426 TJm
+(\(verbosity) 59.7756 Tj
+-426 TJm
+(<;) 11.9551 Tj
+-426 TJm
+(0) 5.97756 Tj
+-426 TJm
+(||) 11.9551 Tj
+-426 TJm
+(verbosity) 53.798 Tj
+-426 TJm
+(>) 5.97756 Tj
+-426 TJm
+(4\)) 11.9551 Tj
+90 651.856 Td
+(BZ_MEM_ERROR) 71.7307 Tj
+98.4879 639.9 Td
+(if) 11.9551 Tj
+-426 TJm
+(insufficient) 71.7307 Tj
+-426 TJm
+(memory) 35.8654 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(available) 53.798 Tj
+[1 0 0 1 72 624.359] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5865] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.5492] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -614.396] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 602.441 Td
+/F130_0 9.9626 Tf
+(Allo) 17.7135 Tj
+25 TJm
+(w) 7.193 Tj
+10 TJm
+(able) 16.5977 Tj
+-250 TJm
+(ne) 9.40469 Tj
+15 TJm
+(xt) 7.7509 Tj
+-250 TJm
+(actions:) 30.9936 Tj
+[1 0 0 1 72 602.341] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -48.8169] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 47.8207 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 44.2341] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -592.976] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 592.976 Td
+/F134_0 9.9626 Tf
+(BZ2_bzDecompress) 95.641 Tj
+98.4879 581.021 Td
+(if) 11.9551 Tj
+-426 TJm
+(BZ_OK) 29.8878 Tj
+-426 TJm
+(was) 17.9327 Tj
+-426 TJm
+(returned) 47.8205 Tj
+98.4879 569.066 Td
+(no) 11.9551 Tj
+-426 TJm
+(specific) 47.8205 Tj
+-426 TJm
+(action) 35.8654 Tj
+-426 TJm
+(required) 47.8205 Tj
+-426 TJm
+(in) 11.9551 Tj
+-426 TJm
+(case) 23.9102 Tj
+-426 TJm
+(of) 11.9551 Tj
+-426 TJm
+(error) 29.8878 Tj
+[1 0 0 1 72 553.524] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -543.562] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 522.903 Td
+/F122_0 17.2154 Tf
+(3.3.5.) 43.0729 Tj
+[1 0 0 1 119.858 522.903] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -119.858 -522.903] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+119.858 522.903 Td
+/F392_0 17.2154 Tf
+(BZ2_bzDecompress) 165.268 Tj
+[1 0 0 1 285.126 522.903] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -213.126 -2.3327] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -24.9066] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 23.9103 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 20.3237] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3685] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -511.206] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 511.206 Td
+/F134_0 9.9626 Tf
+(int) 17.9327 Tj
+-426 TJm
+(BZ2_bzDecompress) 95.641 Tj
+-426 TJm
+(\() 5.97756 Tj
+-426 TJm
+(bz_stream) 53.798 Tj
+280.326 509.462 Td
+(*) 5.97756 Tj
+286.303 511.206 Td
+(strm) 23.9102 Tj
+-426 TJm
+(\);) 11.9551 Tj
+[1 0 0 1 72 495.664] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.5492] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -485.701] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 473.746 Td
+/F130_0 9.9626 Tf
+(Pro) 13.8381 Tj
+15 TJm
+(vides) 21.031 Tj
+-301 TJm
+(more) 20.4731 Tj
+-302 TJm
+(input) 20.4831 Tj
+-301 TJm
+(and/out) 29.8878 Tj
+-302 TJm
+(output) 25.4644 Tj
+-301 TJm
+(b) 4.9813 Tj
+20 TJm
+(uf) 8.29885 Tj
+25 TJm
+(fer) 11.0585 Tj
+-301 TJm
+(space) 22.1269 Tj
+-302 TJm
+(for) 11.6164 Tj
+-301 TJm
+(the) 12.1743 Tj
+-302 TJm
+(library) 26.5603 Tj
+65 TJm
+(.) 2.49065 Tj
+-928 TJm
+(The) 15.4918 Tj
+-301 TJm
+(caller) 22.1269 Tj
+-302 TJm
+(maintains) 38.7446 Tj
+-301 TJm
+(input) 20.4831 Tj
+-302 TJm
+(and) 14.386 Tj
+-301 TJm
+(output) 25.4644 Tj
+-301 TJm
+(b) 4.9813 Tj
+20 TJm
+(uf) 8.29885 Tj
+25 TJm
+(fers,) 17.4246 Tj
+-315 TJm
+(and) 14.386 Tj
+72 461.791 Td
+(uses) 17.1556 Tj
+[1 0 0 1 91.6461 461.791] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -91.6461 -461.791] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+91.6461 461.791 Td
+/F134_0 9.9626 Tf
+(BZ2_bzDecompress) 95.641 Tj
+[1 0 0 1 187.287 461.791] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -187.287 -461.791] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+189.778 461.791 Td
+/F130_0 9.9626 Tf
+(to) 7.7509 Tj
+-250 TJm
+(transfer) 30.4258 Tj
+-250 TJm
+(data) 16.5977 Tj
+-250 TJm
+(between) 33.1954 Tj
+-250 TJm
+(them.) 22.4159 Tj
+[1 0 0 1 72 460.257] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -450.294] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 439.873 Td
+/F130_0 9.9626 Tf
+(Before) 27.1082 Tj
+-498 TJm
+(each) 18.2515 Tj
+-499 TJm
+(call) 14.386 Tj
+-498 TJm
+(to) 7.7509 Tj
+[1 0 0 1 159.356 439.873] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -159.356 -439.873] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+159.356 439.873 Td
+/F134_0 9.9626 Tf
+(BZ2_bzDecompress) 95.641 Tj
+[1 0 0 1 254.997 439.873] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -254.997 -439.873] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+254.997 439.873 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 263.071 439.873] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -263.071 -439.873] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+263.071 439.873 Td
+/F134_0 9.9626 Tf
+(next_in) 41.8429 Tj
+[1 0 0 1 304.914 439.873] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -304.914 -439.873] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+309.879 439.873 Td
+/F130_0 9.9626 Tf
+(should) 26.5703 Tj
+-498 TJm
+(point) 20.4831 Tj
+-499 TJm
+(at) 7.193 Tj
+-498 TJm
+(the) 12.1743 Tj
+-498 TJm
+(compressed) 47.0334 Tj
+-499 TJm
+(data,) 19.0883 Tj
+-560 TJm
+(and) 14.386 Tj
+[1 0 0 1 492.179 439.873] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -492.179 -439.873] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+492.179 439.873 Td
+/F134_0 9.9626 Tf
+(avail_in) 47.8205 Tj
+[1 0 0 1 540 439.873] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -540 -439.873] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 427.918 Td
+/F130_0 9.9626 Tf
+(should) 26.5703 Tj
+-308 TJm
+(indicate) 31.5416 Tj
+-308 TJm
+(ho) 9.9626 Tj
+25 TJm
+(w) 7.193 Tj
+-309 TJm
+(man) 17.1556 Tj
+15 TJm
+(y) 4.9813 Tj
+-308 TJm
+(bytes) 21.031 Tj
+-308 TJm
+(the) 12.1743 Tj
+-308 TJm
+(library) 26.5603 Tj
+-308 TJm
+(may) 17.1556 Tj
+-309 TJm
+(read.) 19.6363 Tj
+[1 0 0 1 294.955 427.918] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -294.955 -427.918] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+294.955 427.918 Td
+/F134_0 9.9626 Tf
+(BZ2_bzDecompress) 95.641 Tj
+[1 0 0 1 390.597 427.918] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -390.597 -427.918] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+393.667 427.918 Td
+/F130_0 9.9626 Tf
+(updates) 30.4357 Tj
+[1 0 0 1 427.173 427.918] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -427.173 -427.918] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+427.173 427.918 Td
+/F134_0 9.9626 Tf
+(next_in) 41.8429 Tj
+[1 0 0 1 469.016 427.918] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -469.016 -427.918] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+469.016 427.918 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 474.723 427.918] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -474.723 -427.918] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+474.723 427.918 Td
+/F134_0 9.9626 Tf
+(avail_in) 47.8205 Tj
+[1 0 0 1 522.543 427.918] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -522.543 -427.918] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+525.614 427.918 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 72 415.963] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -415.963] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 415.963 Td
+/F134_0 9.9626 Tf
+(total_in) 47.8205 Tj
+[1 0 0 1 119.821 415.963] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -119.821 -415.963] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+122.311 415.963 Td
+/F130_0 9.9626 Tf
+(to) 7.7509 Tj
+-250 TJm
+(re\003ect) 24.8965 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(number) 30.4357 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(bytes) 21.031 Tj
+-250 TJm
+(it) 5.53921 Tj
+-250 TJm
+(has) 13.2801 Tj
+-250 TJm
+(read.) 19.6363 Tj
+[1 0 0 1 72 413.806] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -403.843] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 394.045 Td
+/F130_0 9.9626 Tf
+(Similarly) 37.0908 Tj
+65 TJm
+(,) 2.49065 Tj
+[1 0 0 1 113.799 394.045] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -113.799 -394.045] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+113.799 394.045 Td
+/F134_0 9.9626 Tf
+(next_out) 47.8205 Tj
+[1 0 0 1 161.62 394.045] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -161.62 -394.045] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+164.41 394.045 Td
+/F130_0 9.9626 Tf
+(should) 26.5703 Tj
+-280 TJm
+(point) 20.4831 Tj
+-280 TJm
+(to) 7.7509 Tj
+-280 TJm
+(a) 4.42339 Tj
+-280 TJm
+(b) 4.9813 Tj
+20 TJm
+(uf) 8.29885 Tj
+25 TJm
+(fer) 11.0585 Tj
+-280 TJm
+(in) 7.7509 Tj
+-281 TJm
+(which) 24.3486 Tj
+-280 TJm
+(the) 12.1743 Tj
+-280 TJm
+(uncompressed) 56.996 Tj
+-280 TJm
+(output) 25.4644 Tj
+-280 TJm
+(is) 6.64505 Tj
+-280 TJm
+(to) 7.7509 Tj
+-280 TJm
+(be) 9.40469 Tj
+-280 TJm
+(placed,) 28.493 Tj
+-288 TJm
+(with) 17.7135 Tj
+[1 0 0 1 486.202 394.045] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -486.202 -394.045] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+486.202 394.045 Td
+/F134_0 9.9626 Tf
+(avail_out) 53.798 Tj
+[1 0 0 1 540 394.045] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -540 -394.045] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 382.09 Td
+/F130_0 9.9626 Tf
+(indicating) 39.8504 Tj
+-525 TJm
+(ho) 9.9626 Tj
+25 TJm
+(w) 7.193 Tj
+-524 TJm
+(much) 22.1369 Tj
+-525 TJm
+(output) 25.4644 Tj
+-524 TJm
+(space) 22.1269 Tj
+-525 TJm
+(is) 6.64505 Tj
+-525 TJm
+(a) 4.42339 Tj
+20 TJm
+(v) 4.9813 Tj
+25 TJm
+(ailable.) 29.0509 Tj
+[1 0 0 1 285.792 382.09] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -285.792 -382.09] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+285.792 382.09 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompress) 83.6858 Tj
+[1 0 0 1 369.478 382.09] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -369.478 -382.09] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+374.705 382.09 Td
+/F130_0 9.9626 Tf
+(updates) 30.4357 Tj
+[1 0 0 1 410.367 382.09] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -410.367 -382.09] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+410.367 382.09 Td
+/F134_0 9.9626 Tf
+(next_out) 47.8205 Tj
+[1 0 0 1 458.188 382.09] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -458.188 -382.09] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+458.188 382.09 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 466.589 382.09] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -466.589 -382.09] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+466.589 382.09 Td
+/F134_0 9.9626 Tf
+(avail_out) 53.798 Tj
+[1 0 0 1 520.387 382.09] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -520.387 -382.09] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+525.614 382.09 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 72 370.135] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -370.135] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 370.135 Td
+/F134_0 9.9626 Tf
+(total_out) 53.798 Tj
+[1 0 0 1 125.798 370.135] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -125.798 -370.135] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+128.289 370.135 Td
+/F130_0 9.9626 Tf
+(to) 7.7509 Tj
+-250 TJm
+(re\003ect) 24.8965 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(number) 30.4357 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(bytes) 21.031 Tj
+-250 TJm
+(output.) 27.9551 Tj
+[1 0 0 1 72 367.978] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -358.015] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 348.217 Td
+/F130_0 9.9626 Tf
+(Y) 7.193 Tj
+110 TJm
+(ou) 9.9626 Tj
+-320 TJm
+(may) 17.1556 Tj
+-321 TJm
+(pro) 13.2801 Tj
+15 TJm
+(vide) 17.1556 Tj
+-320 TJm
+(and) 14.386 Tj
+-321 TJm
+(remo) 20.4731 Tj
+15 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-320 TJm
+(as) 8.29885 Tj
+-321 TJm
+(little) 18.2714 Tj
+-320 TJm
+(or) 8.29885 Tj
+-320 TJm
+(as) 8.29885 Tj
+-321 TJm
+(much) 22.1369 Tj
+-320 TJm
+(data) 16.5977 Tj
+-321 TJm
+(as) 8.29885 Tj
+-320 TJm
+(you) 14.9439 Tj
+-321 TJm
+(lik) 10.5205 Tj
+10 TJm
+(e) 4.42339 Tj
+-320 TJm
+(on) 9.9626 Tj
+-320 TJm
+(each) 18.2515 Tj
+-321 TJm
+(call) 14.386 Tj
+-320 TJm
+(of) 8.29885 Tj
+[1 0 0 1 407.816 348.217] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -407.816 -348.217] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+407.816 348.217 Td
+/F134_0 9.9626 Tf
+(BZ2_bzDecompress) 95.641 Tj
+[1 0 0 1 503.457 348.217] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -503.457 -348.217] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+503.457 348.217 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+-1043 TJm
+(In) 8.29885 Tj
+-320 TJm
+(the) 12.1743 Tj
+72 336.262 Td
+(limit,) 21.32 Tj
+-295 TJm
+(it) 5.53921 Tj
+-286 TJm
+(is) 6.64505 Tj
+-287 TJm
+(acceptable) 42.0422 Tj
+-286 TJm
+(to) 7.7509 Tj
+-286 TJm
+(supply) 26.5703 Tj
+-286 TJm
+(and) 14.386 Tj
+-287 TJm
+(remo) 20.4731 Tj
+15 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-286 TJm
+(data) 16.5977 Tj
+-286 TJm
+(one) 14.386 Tj
+-286 TJm
+(byte) 17.1556 Tj
+-287 TJm
+(at) 7.193 Tj
+-286 TJm
+(a) 4.42339 Tj
+-286 TJm
+(time,) 20.2042 Tj
+-295 TJm
+(although) 34.8691 Tj
+-286 TJm
+(this) 14.396 Tj
+-287 TJm
+(w) 7.193 Tj
+10 TJm
+(ould) 17.7135 Tj
+-286 TJm
+(be) 9.40469 Tj
+-286 TJm
+(terribly) 29.3299 Tj
+-286 TJm
+(inef) 15.4918 Tj
+25 TJm
+(\002cient.) 27.3972 Tj
+-838 TJm
+(Y) 7.193 Tj
+110 TJm
+(ou) 9.9626 Tj
+72 324.306 Td
+(should) 26.5703 Tj
+-250 TJm
+(al) 7.193 Tj
+10 TJm
+(w) 7.193 Tj
+10 TJm
+(ays) 13.2801 Tj
+-250 TJm
+(ensure) 26.0024 Tj
+-250 TJm
+(that) 14.9439 Tj
+-250 TJm
+(at) 7.193 Tj
+-250 TJm
+(least) 18.2614 Tj
+-250 TJm
+(one) 14.386 Tj
+-250 TJm
+(byte) 17.1556 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(output) 25.4644 Tj
+-250 TJm
+(space) 22.1269 Tj
+-250 TJm
+(is) 6.64505 Tj
+-250 TJm
+(a) 4.42339 Tj
+20 TJm
+(v) 4.9813 Tj
+25 TJm
+(ailable) 26.5603 Tj
+-250 TJm
+(at) 7.193 Tj
+-250 TJm
+(each) 18.2515 Tj
+-250 TJm
+(call.) 16.8766 Tj
+[1 0 0 1 72 322.15] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -312.187] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 302.389 Td
+/F130_0 9.9626 Tf
+(Use) 15.4918 Tj
+-250 TJm
+(of) 8.29885 Tj
+[1 0 0 1 100.772 302.389] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -100.772 -302.389] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+100.772 302.389 Td
+/F134_0 9.9626 Tf
+(BZ2_bzDecompress) 95.641 Tj
+[1 0 0 1 196.413 302.389] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -196.413 -302.389] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+198.904 302.389 Td
+/F130_0 9.9626 Tf
+(is) 6.64505 Tj
+-250 TJm
+(simpler) 29.8878 Tj
+-250 TJm
+(than) 17.1556 Tj
+[1 0 0 1 260.064 302.389] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -260.064 -302.389] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+260.064 302.389 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompress) 83.6858 Tj
+[1 0 0 1 343.75 302.389] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -343.75 -302.389] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+343.75 302.389 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+[1 0 0 1 72 300.232] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -290.269] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 280.471 Td
+/F130_0 9.9626 Tf
+(Y) 7.193 Tj
+110 TJm
+(ou) 9.9626 Tj
+-346 TJm
+(should) 26.5703 Tj
+-347 TJm
+(pro) 13.2801 Tj
+15 TJm
+(vide) 17.1556 Tj
+-346 TJm
+(input) 20.4831 Tj
+-346 TJm
+(and) 14.386 Tj
+-346 TJm
+(remo) 20.4731 Tj
+15 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-347 TJm
+(output) 25.4644 Tj
+-346 TJm
+(as) 8.29885 Tj
+-346 TJm
+(described) 38.1767 Tj
+-346 TJm
+(abo) 14.386 Tj
+15 TJm
+(v) 4.9813 Tj
+15 TJm
+(e,) 6.91404 Tj
+-371 TJm
+(and) 14.386 Tj
+-346 TJm
+(repeatedly) 41.4942 Tj
+-346 TJm
+(call) 14.386 Tj
+[1 0 0 1 422.638 280.471] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -422.638 -280.471] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+422.638 280.471 Td
+/F134_0 9.9626 Tf
+(BZ2_bzDecompress) 95.641 Tj
+[1 0 0 1 518.279 280.471] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -518.279 -280.471] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+521.729 280.471 Td
+/F130_0 9.9626 Tf
+(until) 18.2714 Tj
+[1 0 0 1 72 268.516] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -268.516] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 268.516 Td
+/F134_0 9.9626 Tf
+(BZ_STREAM_END) 77.7083 Tj
+[1 0 0 1 149.709 268.516] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -149.709 -268.516] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+152.314 268.516 Td
+/F130_0 9.9626 Tf
+(is) 6.64505 Tj
+-262 TJm
+(returned.) 35.686 Tj
+-344 TJm
+(Appearance) 47.5714 Tj
+-262 TJm
+(of) 8.29885 Tj
+[1 0 0 1 261.767 268.516] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -261.767 -268.516] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+261.767 268.516 Td
+/F134_0 9.9626 Tf
+(BZ_STREAM_END) 77.7083 Tj
+[1 0 0 1 339.475 268.516] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -339.475 -268.516] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+342.081 268.516 Td
+/F130_0 9.9626 Tf
+(denotes) 30.4357 Tj
+-262 TJm
+(that) 14.9439 Tj
+[1 0 0 1 392.672 268.516] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -392.672 -268.516] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+392.672 268.516 Td
+/F134_0 9.9626 Tf
+(BZ2_bzDecompress) 95.641 Tj
+[1 0 0 1 488.313 268.516] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -488.313 -268.516] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+490.919 268.516 Td
+/F130_0 9.9626 Tf
+(has) 13.2801 Tj
+-262 TJm
+(detected) 33.1954 Tj
+72 256.561 Td
+(the) 12.1743 Tj
+-212 TJm
+(logical) 27.1182 Tj
+-212 TJm
+(end) 14.386 Tj
+-211 TJm
+(of) 8.29885 Tj
+-212 TJm
+(the) 12.1743 Tj
+-212 TJm
+(compressed) 47.0334 Tj
+-212 TJm
+(stream.) 29.0509 Tj
+[1 0 0 1 237.858 256.561] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -237.858 -256.561] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+237.858 256.561 Td
+/F134_0 9.9626 Tf
+(BZ2_bzDecompress) 95.641 Tj
+[1 0 0 1 333.499 256.561] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -333.499 -256.561] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+335.609 256.561 Td
+/F130_0 9.9626 Tf
+(will) 15.5018 Tj
+-212 TJm
+(not) 12.7322 Tj
+-212 TJm
+(produce) 32.0895 Tj
+[1 0 0 1 402.263 256.561] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -402.263 -256.561] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+402.263 256.561 Td
+/F134_0 9.9626 Tf
+(BZ_STREAM_END) 77.7083 Tj
+[1 0 0 1 479.972 256.561] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -479.972 -256.561] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+482.082 256.561 Td
+/F130_0 9.9626 Tf
+(until) 18.2714 Tj
+-212 TJm
+(all) 9.9626 Tj
+-212 TJm
+(output) 25.4644 Tj
+72 244.605 Td
+(data) 16.5977 Tj
+-256 TJm
+(has) 13.2801 Tj
+-256 TJm
+(been) 18.8094 Tj
+-255 TJm
+(placed) 26.0024 Tj
+-256 TJm
+(into) 15.5018 Tj
+-256 TJm
+(the) 12.1743 Tj
+-256 TJm
+(output) 25.4644 Tj
+-256 TJm
+(b) 4.9813 Tj
+20 TJm
+(uf) 8.29885 Tj
+25 TJm
+(fer) 11.0585 Tj
+40 TJm
+(,) 2.49065 Tj
+-257 TJm
+(so) 8.85675 Tj
+-256 TJm
+(once) 18.8094 Tj
+[1 0 0 1 278.978 244.605] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -278.978 -244.605] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+278.978 244.605 Td
+/F134_0 9.9626 Tf
+(BZ_STREAM_END) 77.7083 Tj
+[1 0 0 1 356.687 244.605] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -356.687 -244.605] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+359.236 244.605 Td
+/F130_0 9.9626 Tf
+(appears,) 32.9164 Tj
+-257 TJm
+(you) 14.9439 Tj
+-256 TJm
+(are) 12.1643 Tj
+-256 TJm
+(guaranteed) 43.7059 Tj
+-256 TJm
+(to) 7.7509 Tj
+-256 TJm
+(ha) 9.40469 Tj
+20 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-255 TJm
+(a) 4.42339 Tj
+20 TJm
+(v) 4.9813 Tj
+25 TJm
+(ailable) 26.5603 Tj
+72 232.65 Td
+(all) 9.9626 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(decompressed) 56.4381 Tj
+-250 TJm
+(output,) 27.9551 Tj
+-250 TJm
+(and) 14.386 Tj
+[1 0 0 1 205.369 232.65] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -205.369 -232.65] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+205.369 232.65 Td
+/F134_0 9.9626 Tf
+(BZ2_bzDecompressEnd) 113.574 Tj
+[1 0 0 1 318.943 232.65] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -318.943 -232.65] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+321.433 232.65 Td
+/F130_0 9.9626 Tf
+(can) 13.8281 Tj
+-250 TJm
+(safely) 23.7907 Tj
+-250 TJm
+(be) 9.40469 Tj
+-250 TJm
+(called.) 26.2813 Tj
+[1 0 0 1 72 230.493] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -220.531] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 210.732 Td
+/F130_0 9.9626 Tf
+(If) 6.63509 Tj
+-250 TJm
+(case) 17.1456 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(an) 9.40469 Tj
+-250 TJm
+(error) 19.3573 Tj
+-250 TJm
+(return) 23.7907 Tj
+-250 TJm
+(v) 4.9813 Tj
+25 TJm
+(alue,) 19.0883 Tj
+-250 TJm
+(you) 14.9439 Tj
+-250 TJm
+(should) 26.5703 Tj
+-250 TJm
+(call) 14.386 Tj
+[1 0 0 1 261.259 210.732] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -261.259 -210.732] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+261.259 210.732 Td
+/F134_0 9.9626 Tf
+(BZ2_bzDecompressEnd) 113.574 Tj
+[1 0 0 1 374.833 210.732] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -374.833 -210.732] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+377.323 210.732 Td
+/F130_0 9.9626 Tf
+(to) 7.7509 Tj
+-250 TJm
+(clean) 21.0211 Tj
+-250 TJm
+(up) 9.9626 Tj
+-250 TJm
+(and) 14.386 Tj
+-250 TJm
+(release) 27.6562 Tj
+-250 TJm
+(memory) 33.2053 Tj
+65 TJm
+(.) 2.49065 Tj
+[1 0 0 1 72 208.576] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -198.613] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 188.815 Td
+/F130_0 9.9626 Tf
+(Possible) 33.2153 Tj
+-250 TJm
+(return) 23.7907 Tj
+-250 TJm
+(v) 4.9813 Tj
+25 TJm
+(alues:) 23.2427 Tj
+[1 0 0 1 72 188.715] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -137.863] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 374.394 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 6.8541] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 40.5726 -6.7545] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -493.841 -50.9514] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+534.414 50.9514 Td
+/F130_0 9.9626 Tf
+(17) 9.9626 Tj
+[1 0 0 1 453.269 50.8518] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 93.5985 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.2765 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+Q
+showpage
+%%PageTrailer
+pdfEndPage
+%%Page: 21 21
+%%BeginPageSetup
+%%PageOrientation: Portrait
+pdfStartPage
+0 0 612 792 re W
+%%EndPageSetup
+[] 0 d
+1 i
+0 j
+0 J
+10 M
+1 w
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+false op
+false OP
+0 0 612 792 re
+W
+q
+[1 0 0 1 72 741.554] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 14.4459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 187.197 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 -8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 76.4979 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -342.569 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+419.067 749.245 Td
+/F130_0 9.9626 Tf
+(Programming) 54.7943 Tj
+-250 TJm
+(with) 17.7135 Tj
+[1 0 0 1 496.556 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -496.556 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+496.556 749.245 Td
+/F134_0 9.9626 Tf
+(libbzip2) 47.8205 Tj
+[1 0 0 1 544.376 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -278.305 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 280.796 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -472.974 -5.0363] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -0.4981] cm
+q
+[] 0 d
+0 J
+0.4981 w
+0 0.2491 m
+475.465 0.2491 l
+S
+Q
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 479.251 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -200.882] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 179.328 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 175.741] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -711.631] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 711.631 Td
+/F134_0 9.9626 Tf
+(BZ_PARAM_ERROR) 83.6858 Tj
+98.4879 699.676 Td
+(if) 11.9551 Tj
+-426 TJm
+(strm) 23.9102 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(NULL) 23.9102 Tj
+-426 TJm
+(or) 11.9551 Tj
+-426 TJm
+(strm->s) 41.8429 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(NULL) 23.9102 Tj
+98.4879 687.721 Td
+(or) 11.9551 Tj
+-426 TJm
+(strm->avail_out) 89.6634 Tj
+-426 TJm
+(<) 5.97756 Tj
+-426 TJm
+(1) 5.97756 Tj
+90 675.766 Td
+(BZ_DATA_ERROR) 77.7083 Tj
+98.4879 663.811 Td
+(if) 11.9551 Tj
+-426 TJm
+(a) 5.97756 Tj
+-426 TJm
+(data) 23.9102 Tj
+-426 TJm
+(integrity) 53.798 Tj
+-426 TJm
+(error) 29.8878 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(detected) 47.8205 Tj
+-426 TJm
+(in) 11.9551 Tj
+-426 TJm
+(the) 17.9327 Tj
+-426 TJm
+(compressed) 59.7756 Tj
+-426 TJm
+(stream) 35.8654 Tj
+90 651.856 Td
+(BZ_DATA_ERROR_MAGIC) 113.574 Tj
+98.4879 639.9 Td
+(if) 11.9551 Tj
+-426 TJm
+(the) 17.9327 Tj
+-426 TJm
+(compressed) 59.7756 Tj
+-426 TJm
+(stream) 35.8654 Tj
+-426 TJm
+(doesn't) 41.8429 Tj
+-426 TJm
+(begin) 29.8878 Tj
+-426 TJm
+(with) 23.9102 Tj
+-426 TJm
+(the) 17.9327 Tj
+-426 TJm
+(right) 29.8878 Tj
+-426 TJm
+(magic) 29.8878 Tj
+-426 TJm
+(bytes) 29.8878 Tj
+90 627.945 Td
+(BZ_MEM_ERROR) 71.7307 Tj
+98.4879 615.99 Td
+(if) 11.9551 Tj
+-426 TJm
+(there) 29.8878 Tj
+-426 TJm
+(wasn't) 35.8654 Tj
+-426 TJm
+(enough) 35.8654 Tj
+-426 TJm
+(memory) 35.8654 Tj
+-426 TJm
+(available) 53.798 Tj
+90 604.035 Td
+(BZ_STREAM_END) 77.7083 Tj
+98.4879 592.08 Td
+(if) 11.9551 Tj
+-426 TJm
+(the) 17.9327 Tj
+-426 TJm
+(logical) 41.8429 Tj
+-426 TJm
+(end) 17.9327 Tj
+-426 TJm
+(of) 11.9551 Tj
+-426 TJm
+(the) 17.9327 Tj
+-426 TJm
+(data) 23.9102 Tj
+-426 TJm
+(stream) 35.8654 Tj
+-426 TJm
+(was) 17.9327 Tj
+-426 TJm
+(detected) 47.8205 Tj
+-426 TJm
+(and) 17.9327 Tj
+-426 TJm
+(all) 17.9327 Tj
+98.4879 580.125 Td
+(output) 35.8654 Tj
+-426 TJm
+(in) 11.9551 Tj
+-426 TJm
+(has) 17.9327 Tj
+-426 TJm
+(been) 23.9102 Tj
+-426 TJm
+(consumed,) 53.798 Tj
+-426 TJm
+(eg) 11.9551 Tj
+-426 TJm
+(s-->avail_out) 77.7083 Tj
+-426 TJm
+(>) 5.97756 Tj
+-426 TJm
+(0) 5.97756 Tj
+90 568.169 Td
+(BZ_OK) 29.8878 Tj
+98.4879 556.214 Td
+(otherwise) 53.798 Tj
+[1 0 0 1 72 540.673] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.5492] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -530.71] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 518.755 Td
+/F130_0 9.9626 Tf
+(Allo) 17.7135 Tj
+25 TJm
+(w) 7.193 Tj
+10 TJm
+(able) 16.5977 Tj
+-250 TJm
+(ne) 9.40469 Tj
+15 TJm
+(xt) 7.7509 Tj
+-250 TJm
+(actions:) 30.9936 Tj
+[1 0 0 1 72 518.655] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -60.7721] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 59.7758 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 56.1892] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -509.29] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 509.29 Td
+/F134_0 9.9626 Tf
+(BZ2_bzDecompress) 95.641 Tj
+98.4879 497.335 Td
+(if) 11.9551 Tj
+-426 TJm
+(BZ_OK) 29.8878 Tj
+-426 TJm
+(was) 17.9327 Tj
+-426 TJm
+(returned) 47.8205 Tj
+90 485.38 Td
+(BZ2_bzDecompressEnd) 113.574 Tj
+98.4879 473.425 Td
+(otherwise) 53.798 Tj
+[1 0 0 1 72 457.883] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -447.92] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 427.262 Td
+/F122_0 17.2154 Tf
+(3.3.6.) 43.0729 Tj
+[1 0 0 1 119.858 427.262] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -119.858 -427.262] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+119.858 427.262 Td
+/F392_0 17.2154 Tf
+(BZ2_bzDecompressEnd) 196.256 Tj
+[1 0 0 1 316.114 427.262] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -244.114 -2.3326] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -24.9066] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 23.9103 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 20.3237] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -415.564] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 415.564 Td
+/F134_0 9.9626 Tf
+(int) 17.9327 Tj
+-426 TJm
+(BZ2_bzDecompressEnd) 113.574 Tj
+-426 TJm
+(\() 5.97756 Tj
+-426 TJm
+(bz_stream) 53.798 Tj
+298.259 413.821 Td
+(*) 5.97756 Tj
+304.236 415.564 Td
+(strm) 23.9102 Tj
+-426 TJm
+(\);) 11.9551 Tj
+[1 0 0 1 72 400.023] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.5492] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -390.06] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 378.105 Td
+/F130_0 9.9626 Tf
+(Releases) 34.8591 Tj
+-250 TJm
+(all) 9.9626 Tj
+-250 TJm
+(memory) 33.2053 Tj
+-250 TJm
+(associated) 40.9463 Tj
+-250 TJm
+(with) 17.7135 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(decompression) 59.7656 Tj
+-250 TJm
+(stream.) 29.0509 Tj
+[1 0 0 1 72 375.948] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -365.985] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 356.187 Td
+/F130_0 9.9626 Tf
+(Possible) 33.2153 Tj
+-250 TJm
+(return) 23.7907 Tj
+-250 TJm
+(v) 4.9813 Tj
+25 TJm
+(alues:) 23.2427 Tj
+[1 0 0 1 72 356.087] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -60.7721] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 59.7758 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 56.1893] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -346.723] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 346.723 Td
+/F134_0 9.9626 Tf
+(BZ_PARAM_ERROR) 83.6858 Tj
+98.4879 334.767 Td
+(if) 11.9551 Tj
+-426 TJm
+(strm) 23.9102 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(NULL) 23.9102 Tj
+-426 TJm
+(or) 11.9551 Tj
+-426 TJm
+(strm->s) 41.8429 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(NULL) 23.9102 Tj
+90 322.812 Td
+(BZ_OK) 29.8878 Tj
+98.4879 310.857 Td
+(otherwise) 53.798 Tj
+[1 0 0 1 72 295.315] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.5492] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -285.353] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 273.397 Td
+/F130_0 9.9626 Tf
+(Allo) 17.7135 Tj
+25 TJm
+(w) 7.193 Tj
+10 TJm
+(able) 16.5977 Tj
+-250 TJm
+(ne) 9.40469 Tj
+15 TJm
+(xt) 7.7509 Tj
+-250 TJm
+(actions:) 30.9936 Tj
+[1 0 0 1 72 273.298] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -24.9066] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 23.9103 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 20.3237] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -263.933] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+98.4879 263.933 Td
+/F134_0 9.9626 Tf
+(None.) 29.8878 Tj
+[1 0 0 1 72 248.391] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -238.429] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 213.639 Td
+/F122_0 20.6585 Tf
+(3.4.) 34.4584 Tj
+-278 TJm
+(High-le) 70.0117 Tj
+15 TJm
+(vel) 28.7153 Tj
+-278 TJm
+(interface) 86.1046 Tj
+[1 0 0 1 72 209.042] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -199.08] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 191.721 Td
+/F130_0 9.9626 Tf
+(This) 17.7135 Tj
+-250 TJm
+(interf) 21.579 Tj
+10 TJm
+(ace) 13.2702 Tj
+-250 TJm
+(pro) 13.2801 Tj
+15 TJm
+(vides) 21.031 Tj
+-250 TJm
+(functions) 37.0808 Tj
+-250 TJm
+(for) 11.6164 Tj
+-250 TJm
+(reading) 29.8778 Tj
+-250 TJm
+(and) 14.386 Tj
+-250 TJm
+(writing) 28.782 Tj
+[1 0 0 1 300.292 191.721] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -300.292 -191.721] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+300.292 191.721 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 330.18 191.721] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -330.18 -191.721] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+332.67 191.721 Td
+/F130_0 9.9626 Tf
+(format) 26.5603 Tj
+-250 TJm
+(\002les.) 19.0983 Tj
+-620 TJm
+(First,) 20.7621 Tj
+-250 TJm
+(some) 21.031 Tj
+-250 TJm
+(general) 29.3199 Tj
+-250 TJm
+(points.) 26.8492 Tj
+[1 0 0 1 72 189.564] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -29.7236] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.9739 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -78.9739 -159.84] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+78.9739 159.84 Td
+/F130_0 9.9626 Tf
+(\225) 3.48691 Tj
+[1 0 0 1 82.4608 159.84] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 1.9925 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -86.944 -159.84] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 159.84 Td
+/F130_0 9.9626 Tf
+(All) 12.7322 Tj
+-332 TJm
+(of) 8.29885 Tj
+-331 TJm
+(the) 12.1743 Tj
+-332 TJm
+(functions) 37.0808 Tj
+-332 TJm
+(tak) 12.1743 Tj
+10 TJm
+(e) 4.42339 Tj
+-331 TJm
+(an) 9.40469 Tj
+[1 0 0 1 202.958 159.84] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -202.958 -159.84] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+202.958 159.84 Td
+/F134_0 9.9626 Tf
+(int) 17.9327 Tj
+220.891 158.097 Td
+(*) 5.97756 Tj
+[1 0 0 1 226.868 159.84] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -226.868 -159.84] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+230.172 159.84 Td
+/F130_0 9.9626 Tf
+(\002rst) 15.5018 Tj
+-332 TJm
+(ar) 7.74094 Tj
+18 TJm
+(gument,) 32.3785 Tj
+[1 0 0 1 292.426 159.84] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -292.426 -159.84] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+292.426 159.84 Td
+/F134_0 9.9626 Tf
+(bzerror) 41.8429 Tj
+[1 0 0 1 334.269 159.84] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -334.269 -159.84] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+334.269 159.84 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+-1110 TJm
+(After) 21.0211 Tj
+-332 TJm
+(each) 18.2515 Tj
+-331 TJm
+(call,) 16.8766 Tj
+[1 0 0 1 414.083 159.84] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -414.083 -159.84] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+414.083 159.84 Td
+/F134_0 9.9626 Tf
+(bzerror) 41.8429 Tj
+[1 0 0 1 455.926 159.84] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -455.926 -159.84] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+459.23 159.84 Td
+/F130_0 9.9626 Tf
+(should) 26.5703 Tj
+-332 TJm
+(be) 9.40469 Tj
+-331 TJm
+(consulted) 38.1866 Tj
+86.944 147.885 Td
+(\002rst) 15.5018 Tj
+-349 TJm
+(to) 7.7509 Tj
+-349 TJm
+(determine) 39.8404 Tj
+-348 TJm
+(the) 12.1743 Tj
+-349 TJm
+(outcome) 34.3112 Tj
+-349 TJm
+(of) 8.29885 Tj
+-349 TJm
+(the) 12.1743 Tj
+-348 TJm
+(call.) 16.8766 Tj
+-1213 TJm
+(If) 6.63509 Tj
+[1 0 0 1 280.386 147.885] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -280.386 -147.885] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+280.386 147.885 Td
+/F134_0 9.9626 Tf
+(bzerror) 41.8429 Tj
+[1 0 0 1 322.229 147.885] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -322.229 -147.885] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+325.704 147.885 Td
+/F130_0 9.9626 Tf
+(is) 6.64505 Tj
+[1 0 0 1 335.824 147.885] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -335.824 -147.885] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+335.824 147.885 Td
+/F134_0 9.9626 Tf
+(BZ_OK) 29.8878 Tj
+[1 0 0 1 365.711 147.885] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -365.711 -147.885] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+365.711 147.885 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-349 TJm
+(the) 12.1743 Tj
+-349 TJm
+(call) 14.386 Tj
+-348 TJm
+(completed) 41.5042 Tj
+-349 TJm
+(successfully) 48.6972 Tj
+65 TJm
+(,) 2.49065 Tj
+-374 TJm
+(and) 14.386 Tj
+-348 TJm
+(only) 17.7135 Tj
+86.944 135.93 Td
+(then) 17.1556 Tj
+-271 TJm
+(should) 26.5703 Tj
+-270 TJm
+(the) 12.1743 Tj
+-271 TJm
+(return) 23.7907 Tj
+-270 TJm
+(v) 4.9813 Tj
+25 TJm
+(alue) 16.5977 Tj
+-271 TJm
+(of) 8.29885 Tj
+-271 TJm
+(the) 12.1743 Tj
+-270 TJm
+(function) 33.2053 Tj
+-271 TJm
+(\(if) 9.40469 Tj
+-270 TJm
+(an) 9.40469 Tj
+15 TJm
+(y\)) 8.29885 Tj
+-271 TJm
+(be) 9.40469 Tj
+-271 TJm
+(cons) 18.2614 Tj
+1 TJm
+(u) 4.9813 Tj
+-1 TJm
+(l) 2.7696 Tj
+1 TJm
+(ted.) 14.6649 Tj
+-744 TJm
+(If) 6.63509 Tj
+[1 0 0 1 365.077 135.93] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -365.077 -135.93] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+365.077 135.93 Td
+/F134_0 9.9626 Tf
+(bzerror) 41.8429 Tj
+[1 0 0 1 406.92 135.93] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -406.92 -135.93] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+409.616 135.93 Td
+/F130_0 9.9626 Tf
+(is) 6.64505 Tj
+[1 0 0 1 418.956 135.93] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -418.956 -135.93] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+418.956 135.93 Td
+/F134_0 9.9626 Tf
+(BZ_IO_ERROR) 65.7532 Tj
+[1 0 0 1 484.71 135.93] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -484.71 -135.93] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+484.71 135.93 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-271 TJm
+(there) 19.9152 Tj
+-270 TJm
+(w) 7.193 Tj
+10 TJm
+(as) 8.29885 Tj
+-271 TJm
+(an) 9.40469 Tj
+86.944 123.975 Td
+(error) 19.3573 Tj
+-246 TJm
+(reading/writing) 61.4294 Tj
+-245 TJm
+(the) 12.1743 Tj
+-246 TJm
+(underlying) 43.1679 Tj
+-246 TJm
+(compressed) 47.0334 Tj
+-245 TJm
+(\002le,) 15.2229 Tj
+-247 TJm
+(and) 14.386 Tj
+-245 TJm
+(you) 14.9439 Tj
+-246 TJm
+(should) 26.5703 Tj
+-246 TJm
+(then) 17.1556 Tj
+-245 TJm
+(consult) 28.782 Tj
+[1 0 0 1 414.096 123.975] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -414.096 -123.975] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+414.096 123.975 Td
+/F134_0 9.9626 Tf
+(errno) 29.8878 Tj
+[1 0 0 1 443.984 123.975] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -443.984 -123.975] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+446.432 123.975 Td
+/F130_0 9.9626 Tf
+(/) 2.7696 Tj
+[1 0 0 1 451.649 123.975] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -451.649 -123.975] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+451.649 123.975 Td
+/F134_0 9.9626 Tf
+(perror) 35.8654 Tj
+[1 0 0 1 487.514 123.975] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -487.514 -123.975] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+489.962 123.975 Td
+/F130_0 9.9626 Tf
+(to) 7.7509 Tj
+-246 TJm
+(determine) 39.8404 Tj
+86.944 112.02 Td
+(the) 12.1743 Tj
+-356 TJm
+(cause) 22.1269 Tj
+-356 TJm
+(of) 8.29885 Tj
+-355 TJm
+(the) 12.1743 Tj
+-356 TJm
+(dif) 11.0684 Tj
+25 TJm
+(\002culty) 25.4644 Tj
+65 TJm
+(.) 2.49065 Tj
+[1 0 0 1 206.528 112.02] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -206.528 -112.02] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+206.528 112.02 Td
+/F134_0 9.9626 Tf
+(bzerror) 41.8429 Tj
+[1 0 0 1 248.371 112.02] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -248.371 -112.02] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+251.916 112.02 Td
+/F130_0 9.9626 Tf
+(may) 17.1556 Tj
+-356 TJm
+(also) 16.0497 Tj
+-356 TJm
+(be) 9.40469 Tj
+-355 TJm
+(set) 11.0684 Tj
+-356 TJm
+(to) 7.7509 Tj
+-356 TJm
+(v) 4.9813 Tj
+25 TJm
+(arious) 24.3486 Tj
+-356 TJm
+(other) 20.4731 Tj
+-356 TJm
+(v) 4.9813 Tj
+25 TJm
+(alues;) 23.2427 Tj
+-408 TJm
+(precise) 28.2141 Tj
+-356 TJm
+(details) 26.0123 Tj
+-356 TJm
+(are) 12.1643 Tj
+-356 TJm
+(gi) 7.7509 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(en) 9.40469 Tj
+-356 TJm
+(on) 9.9626 Tj
+-356 TJm
+(a) 4.42339 Tj
+86.944 100.064 Td
+(per) 12.7222 Tj
+20 TJm
+(-function) 36.5229 Tj
+-250 TJm
+(basis) 19.9252 Tj
+-250 TJm
+(belo) 17.1556 Tj
+25 TJm
+(w) 7.193 Tj
+65 TJm
+(.) 2.49065 Tj
+[1 0 0 1 186.839 100.064] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -114.838 -49.2126] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 374.394 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 6.8541] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 40.5726 -6.7545] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -493.841 -50.9514] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+534.414 50.9514 Td
+/F130_0 9.9626 Tf
+(18) 9.9626 Tj
+[1 0 0 1 453.269 50.8518] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 93.5985 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.2765 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+Q
+showpage
+%%PageTrailer
+pdfEndPage
+%%Page: 22 22
+%%BeginPageSetup
+%%PageOrientation: Portrait
+pdfStartPage
+0 0 612 792 re W
+%%EndPageSetup
+[] 0 d
+1 i
+0 j
+0 J
+10 M
+1 w
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+false op
+false OP
+0 0 612 792 re
+W
+q
+[1 0 0 1 72 741.554] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 14.4459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 187.197 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 -8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 76.4979 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -342.569 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+419.067 749.245 Td
+/F130_0 9.9626 Tf
+(Programming) 54.7943 Tj
+-250 TJm
+(with) 17.7135 Tj
+[1 0 0 1 496.556 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -496.556 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+496.556 749.245 Td
+/F134_0 9.9626 Tf
+(libbzip2) 47.8205 Tj
+[1 0 0 1 544.376 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -278.305 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 280.796 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -472.974 -5.0363] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -0.4981] cm
+q
+[] 0 d
+0 J
+0.4981 w
+0 0.2491 m
+475.465 0.2491 l
+S
+Q
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 479.251 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -31.5168] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.9739 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -78.9739 -710.037] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+78.9739 710.037 Td
+/F130_0 9.9626 Tf
+(\225) 3.48691 Tj
+[1 0 0 1 82.4608 710.037] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 1.9925 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -86.944 -710.037] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 710.037 Td
+/F130_0 9.9626 Tf
+(If) 6.63509 Tj
+[1 0 0 1 95.9576 710.037] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -95.9576 -710.037] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+95.9576 710.037 Td
+/F134_0 9.9626 Tf
+(bzerror) 41.8429 Tj
+[1 0 0 1 137.801 710.037] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -137.801 -710.037] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+140.179 710.037 Td
+/F130_0 9.9626 Tf
+(indicates) 35.417 Tj
+-239 TJm
+(an) 9.40469 Tj
+-238 TJm
+(error) 19.3573 Tj
+-239 TJm
+(\(ie,) 13.0012 Tj
+-241 TJm
+(an) 9.40469 Tj
+15 TJm
+(ything) 25.4644 Tj
+-239 TJm
+(e) 4.42339 Tj
+15 TJm
+(xcept) 21.579 Tj
+[1 0 0 1 292.225 710.037] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -292.225 -710.037] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+292.225 710.037 Td
+/F134_0 9.9626 Tf
+(BZ_OK) 29.8878 Tj
+[1 0 0 1 322.113 710.037] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -322.113 -710.037] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+324.492 710.037 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 341.256 710.037] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -341.256 -710.037] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+341.256 710.037 Td
+/F134_0 9.9626 Tf
+(BZ_STREAM_END) 77.7083 Tj
+[1 0 0 1 418.965 710.037] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -418.965 -710.037] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+418.965 710.037 Td
+/F130_0 9.9626 Tf
+(\),) 5.8082 Tj
+-239 TJm
+(you) 14.9439 Tj
+-239 TJm
+(should) 26.5703 Tj
+-238 TJm
+(immediately) 49.813 Tj
+-239 TJm
+(call) 14.386 Tj
+[1 0 0 1 86.944 698.082] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -86.944 -698.082] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 698.082 Td
+/F134_0 9.9626 Tf
+(BZ2_bzReadClose) 89.6634 Tj
+[1 0 0 1 176.608 698.082] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -176.608 -698.082] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+179.343 698.082 Td
+/F130_0 9.9626 Tf
+(\(or) 11.6164 Tj
+[1 0 0 1 193.695 698.082] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -193.695 -698.082] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+193.695 698.082 Td
+/F134_0 9.9626 Tf
+(BZ2_bzWriteClose) 95.641 Tj
+[1 0 0 1 289.337 698.082] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -289.337 -698.082] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+289.337 698.082 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-281 TJm
+(depending) 41.5042 Tj
+-274 TJm
+(on) 9.9626 Tj
+-275 TJm
+(whether) 32.0895 Tj
+-274 TJm
+(you) 14.9439 Tj
+-275 TJm
+(are) 12.1643 Tj
+-275 TJm
+(attempting) 42.62 Tj
+-274 TJm
+(to) 7.7509 Tj
+-275 TJm
+(read) 17.1456 Tj
+-274 TJm
+(or) 8.29885 Tj
+-275 TJm
+(to) 7.7509 Tj
+-274 TJm
+(write\)) 23.7907 Tj
+86.944 686.127 Td
+(to) 7.7509 Tj
+-242 TJm
+(free) 15.4819 Tj
+-242 TJm
+(up) 9.9626 Tj
+-241 TJm
+(all) 9.9626 Tj
+-242 TJm
+(resources) 37.6188 Tj
+-242 TJm
+(associated) 40.9463 Tj
+-242 TJm
+(wi) 9.9626 Tj
+1 TJm
+(th) 7.7509 Tj
+-242 TJm
+(the) 12.1743 Tj
+-242 TJm
+(stream.) 29.0509 Tj
+-614 TJm
+(Once) 21.0211 Tj
+-242 TJm
+(an) 9.40469 Tj
+-242 TJm
+(error) 19.3573 Tj
+-242 TJm
+(has) 13.2801 Tj
+-242 TJm
+(been) 18.8094 Tj
+-241 TJm
+(indicated,) 39.0135 Tj
+-244 TJm
+(beha) 18.8094 Tj
+20 TJm
+(viour) 21.031 Tj
+-241 TJm
+(of) 8.29885 Tj
+-242 TJm
+(all) 9.9626 Tj
+-242 TJm
+(calls) 18.2614 Tj
+-242 TJm
+(e) 4.42339 Tj
+15 TJm
+(xcept) 21.579 Tj
+[1 0 0 1 86.944 674.172] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -86.944 -674.172] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 674.172 Td
+/F134_0 9.9626 Tf
+(BZ2_bzReadClose) 89.6634 Tj
+[1 0 0 1 176.608 674.172] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -176.608 -674.172] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+179.705 674.172 Td
+/F130_0 9.9626 Tf
+(\() 3.31755 Tj
+[1 0 0 1 183.022 674.172] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -183.022 -674.172] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+183.022 674.172 Td
+/F134_0 9.9626 Tf
+(BZ2_bzWriteClose) 95.641 Tj
+[1 0 0 1 278.664 674.172] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -278.664 -674.172] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+278.664 674.172 Td
+/F130_0 9.9626 Tf
+(\)) 3.31755 Tj
+-311 TJm
+(is) 6.64505 Tj
+-311 TJm
+(unde\002ned.) 41.7831 Tj
+-985 TJm
+(The) 15.4918 Tj
+-311 TJm
+(implication) 45.3896 Tj
+-310 TJm
+(is) 6.64505 Tj
+-311 TJm
+(that) 14.9439 Tj
+-311 TJm
+(\(1\)) 11.6164 Tj
+[1 0 0 1 455.988 674.172] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -455.988 -674.172] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+455.988 674.172 Td
+/F134_0 9.9626 Tf
+(bzerror) 41.8429 Tj
+[1 0 0 1 497.831 674.172] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -497.831 -674.172] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+500.928 674.172 Td
+/F130_0 9.9626 Tf
+(should) 26.5703 Tj
+-311 TJm
+(be) 9.40469 Tj
+86.944 662.217 Td
+(check) 23.2328 Tj
+10 TJm
+(ed) 9.40469 Tj
+-291 TJm
+(after) 18.2515 Tj
+-291 TJm
+(each) 18.2515 Tj
+-291 TJm
+(call,) 16.8766 Tj
+-301 TJm
+(and) 14.386 Tj
+-291 TJm
+(\(2\)) 11.6164 Tj
+-291 TJm
+(if) 6.08715 Tj
+[1 0 0 1 225.347 662.217] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -225.347 -662.217] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+225.347 662.217 Td
+/F134_0 9.9626 Tf
+(bzerror) 41.8429 Tj
+[1 0 0 1 267.19 662.217] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -267.19 -662.217] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+270.09 662.217 Td
+/F130_0 9.9626 Tf
+(indicates) 35.417 Tj
+-291 TJm
+(an) 9.40469 Tj
+-291 TJm
+(error) 19.3573 Tj
+40 TJm
+(,) 2.49065 Tj
+[1 0 0 1 345.161 662.217] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -345.161 -662.217] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+345.161 662.217 Td
+/F134_0 9.9626 Tf
+(BZ2_bzReadClose) 89.6634 Tj
+[1 0 0 1 434.824 662.217] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -434.824 -662.217] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+437.724 662.217 Td
+/F130_0 9.9626 Tf
+(\() 3.31755 Tj
+[1 0 0 1 441.041 662.217] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -441.041 -662.217] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+441.041 662.217 Td
+/F134_0 9.9626 Tf
+(BZ2_bzWriteClose) 95.641 Tj
+[1 0 0 1 536.683 662.217] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -536.683 -662.217] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+536.683 662.217 Td
+/F130_0 9.9626 Tf
+(\)) 3.31755 Tj
+86.944 650.262 Td
+(should) 26.5703 Tj
+-250 TJm
+(then) 17.1556 Tj
+-250 TJm
+(be) 9.40469 Tj
+-250 TJm
+(called) 23.7907 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(clean) 21.0211 Tj
+-250 TJm
+(up.) 12.4533 Tj
+[1 0 0 1 220.034 650.261] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -148.034 -21.9178] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.9739 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -78.9739 -628.344] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+78.9739 628.344 Td
+/F130_0 9.9626 Tf
+(\225) 3.48691 Tj
+[1 0 0 1 82.4608 628.344] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 1.9925 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -86.944 -628.344] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 628.344 Td
+/F130_0 9.9626 Tf
+(The) 15.4918 Tj
+[1 0 0 1 106.362 628.344] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -106.362 -628.344] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+106.362 628.344 Td
+/F134_0 9.9626 Tf
+(FILE) 23.9102 Tj
+130.273 626.6 Td
+(*) 5.97756 Tj
+[1 0 0 1 136.25 628.344] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -136.25 -628.344] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+140.177 628.344 Td
+/F130_0 9.9626 Tf
+(ar) 7.74094 Tj
+18 TJm
+(guments) 33.7633 Tj
+-394 TJm
+(passed) 26.5603 Tj
+-394 TJm
+(to) 7.7509 Tj
+[1 0 0 1 227.592 628.344] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -227.592 -628.344] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+227.592 628.344 Td
+/F134_0 9.9626 Tf
+(BZ2_bzReadOpen) 83.6858 Tj
+[1 0 0 1 311.278 628.344] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -311.278 -628.344] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+315.205 628.344 Td
+/F130_0 9.9626 Tf
+(/) 2.7696 Tj
+[1 0 0 1 321.901 628.344] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -321.901 -628.344] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+321.901 628.344 Td
+/F134_0 9.9626 Tf
+(BZ2_bzWriteOpen) 89.6634 Tj
+[1 0 0 1 411.565 628.344] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -411.565 -628.344] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+415.491 628.344 Td
+/F130_0 9.9626 Tf
+(should) 26.5703 Tj
+-394 TJm
+(be) 9.40469 Tj
+-394 TJm
+(set) 11.0684 Tj
+-394 TJm
+(to) 7.7509 Tj
+-394 TJm
+(binary) 25.4544 Tj
+-395 TJm
+(mode.) 24.6275 Tj
+86.944 616.389 Td
+(Most) 20.4831 Tj
+-229 TJm
+(Unix) 19.9252 Tj
+-229 TJm
+(systems) 31.5516 Tj
+-228 TJm
+(will) 15.5018 Tj
+-229 TJm
+(do) 9.9626 Tj
+-229 TJm
+(this) 14.396 Tj
+-229 TJm
+(by) 9.9626 Tj
+-229 TJm
+(def) 12.7222 Tj
+10 TJm
+(ault,) 17.4346 Tj
+-233 TJm
+(b) 4.9813 Tj
+20 TJm
+(ut) 7.7509 Tj
+-229 TJm
+(other) 20.4731 Tj
+-229 TJm
+(platforms,) 40.6773 Tj
+-233 TJm
+(including) 37.6387 Tj
+-229 TJm
+(W) 9.40469 Tj
+40 TJm
+(indo) 17.7135 Tj
+25 TJm
+(ws) 11.0684 Tj
+-228 TJm
+(and) 14.386 Tj
+-229 TJm
+(Mac,) 20.1942 Tj
+-233 TJm
+(will) 15.5018 Tj
+-229 TJm
+(not.) 15.2229 Tj
+-606 TJm
+(If) 6.63509 Tj
+-229 TJm
+(you) 14.9439 Tj
+-229 TJm
+(omit) 18.2714 Tj
+86.944 604.433 Td
+(this,) 16.8866 Tj
+-250 TJm
+(you) 14.9439 Tj
+-250 TJm
+(may) 17.1556 Tj
+-250 TJm
+(encounter) 39.2825 Tj
+-250 TJm
+(problems) 37.0808 Tj
+-250 TJm
+(when) 21.579 Tj
+-250 TJm
+(mo) 12.7322 Tj
+15 TJm
+(ving) 17.7135 Tj
+-250 TJm
+(code) 18.8094 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(ne) 9.40469 Tj
+25 TJm
+(w) 7.193 Tj
+-250 TJm
+(platforms.) 40.6773 Tj
+[1 0 0 1 372.66 604.433] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -300.66 -21.9178] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.9739 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -78.9739 -582.516] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+78.9739 582.516 Td
+/F130_0 9.9626 Tf
+(\225) 3.48691 Tj
+[1 0 0 1 82.4608 582.516] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 1.9925 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -86.944 -582.516] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 582.516 Td
+/F130_0 9.9626 Tf
+(Memory) 34.3112 Tj
+-348 TJm
+(allocation) 39.2925 Tj
+-348 TJm
+(requests) 32.6474 Tj
+-348 TJm
+(are) 12.1643 Tj
+-348 TJm
+(handled) 31.5416 Tj
+-348 TJm
+(by) 9.9626 Tj
+[1 0 0 1 267.67 582.516] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -267.67 -582.516] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+267.67 582.516 Td
+/F134_0 9.9626 Tf
+(malloc) 35.8654 Tj
+[1 0 0 1 303.535 582.516] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -303.535 -582.516] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+307.003 582.516 Td
+/F130_0 9.9626 Tf
+(/) 2.7696 Tj
+[1 0 0 1 313.241 582.516] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -313.241 -582.516] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+313.241 582.516 Td
+/F134_0 9.9626 Tf
+(free) 23.9102 Tj
+[1 0 0 1 337.151 582.516] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -337.151 -582.516] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+337.151 582.516 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+-1209 TJm
+(At) 9.9626 Tj
+-348 TJm
+(present) 28.772 Tj
+-348 TJm
+(there) 19.9152 Tj
+-348 TJm
+(is) 6.64505 Tj
+-348 TJm
+(no) 9.9626 Tj
+-348 TJm
+(f) 3.31755 Tj
+10 TJm
+(acility) 24.9065 Tj
+-348 TJm
+(for) 11.6164 Tj
+-348 TJm
+(user) 16.5977 Tj
+20 TJm
+(-de\002ned) 32.6474 Tj
+86.944 570.56 Td
+(memory) 33.2053 Tj
+-250 TJm
+(allocators) 38.7346 Tj
+-250 TJm
+(in) 7.7509 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(\002le) 12.7322 Tj
+-250 TJm
+(I/O) 13.2801 Tj
+-250 TJm
+(functions) 37.0808 Tj
+-250 TJm
+(\(could) 25.4544 Tj
+-250 TJm
+(easily) 23.2427 Tj
+-250 TJm
+(be) 9.40469 Tj
+-250 TJm
+(added,) 26.2813 Tj
+-250 TJm
+(though\).) 33.4843 Tj
+[1 0 0 1 387.165 570.56] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -315.165 -12.1195] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -548.478] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 529.977 Td
+/F122_0 17.2154 Tf
+(3.4.1.) 43.0729 Tj
+[1 0 0 1 119.858 529.977] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -119.858 -529.977] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+119.858 529.977 Td
+/F392_0 17.2154 Tf
+(BZ2_bzReadOpen) 144.609 Tj
+[1 0 0 1 264.468 529.977] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -192.468 -2.3327] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -72.7272] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 71.731 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 68.1444] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -518.279] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 518.279 Td
+/F134_0 9.9626 Tf
+(typedef) 41.8429 Tj
+-426 TJm
+(void) 23.9102 Tj
+-426 TJm
+(BZFILE;) 41.8429 Tj
+90 494.369 Td
+(BZFILE) 35.8654 Tj
+130.109 492.625 Td
+(*) 5.97756 Tj
+136.087 494.369 Td
+(BZ2_bzReadOpen\() 89.6634 Tj
+-426 TJm
+(int) 17.9327 Tj
+252.171 492.625 Td
+(*) 5.97756 Tj
+258.149 494.369 Td
+(bzerror,) 47.8205 Tj
+-426 TJm
+(FILE) 23.9102 Tj
+338.368 492.625 Td
+(*) 5.97756 Tj
+344.346 494.369 Td
+(f,) 11.9551 Tj
+191.855 482.414 Td
+(int) 17.9327 Tj
+-426 TJm
+(verbosity,) 59.7756 Tj
+-426 TJm
+(int) 17.9327 Tj
+-426 TJm
+(small,) 35.8654 Tj
+191.855 470.458 Td
+(void) 23.9102 Tj
+220.01 468.715 Td
+(*) 5.97756 Tj
+225.987 470.458 Td
+(unused,) 41.8429 Tj
+-426 TJm
+(int) 17.9327 Tj
+-426 TJm
+(nUnused) 41.8429 Tj
+-426 TJm
+(\);) 11.9551 Tj
+[1 0 0 1 72 454.917] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.5492] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -444.954] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 432.999 Td
+/F130_0 9.9626 Tf
+(Prepare) 30.4258 Tj
+-290 TJm
+(to) 7.7509 Tj
+-289 TJm
+(read) 17.1456 Tj
+-290 TJm
+(compressed) 47.0334 Tj
+-290 TJm
+(data) 16.5977 Tj
+-289 TJm
+(from) 19.3673 Tj
+-290 TJm
+(\002le) 12.7322 Tj
+-289 TJm
+(handle) 26.5603 Tj
+[1 0 0 1 272.697 432.999] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -272.697 -432.999] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+272.697 432.999 Td
+/F134_0 9.9626 Tf
+(f) 5.97756 Tj
+[1 0 0 1 278.675 432.999] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -278.675 -432.999] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+278.675 432.999 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+[1 0 0 1 285.439 432.999] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -285.439 -432.999] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+285.439 432.999 Td
+/F134_0 9.9626 Tf
+(f) 5.97756 Tj
+[1 0 0 1 291.417 432.999] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -291.417 -432.999] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+294.303 432.999 Td
+/F130_0 9.9626 Tf
+(should) 26.5703 Tj
+-290 TJm
+(refer) 18.7994 Tj
+-289 TJm
+(to) 7.7509 Tj
+-290 TJm
+(a) 4.42339 Tj
+-290 TJm
+(\002le) 12.7322 Tj
+-289 TJm
+(which) 24.3486 Tj
+-290 TJm
+(has) 13.2801 Tj
+-289 TJm
+(been) 18.8094 Tj
+-290 TJm
+(opened) 28.772 Tj
+-290 TJm
+(for) 11.6164 Tj
+-289 TJm
+(reading,) 32.3685 Tj
+-300 TJm
+(and) 14.386 Tj
+72 421.044 Td
+(for) 11.6164 Tj
+-306 TJm
+(which) 24.3486 Tj
+-305 TJm
+(the) 12.1743 Tj
+-306 TJm
+(error) 19.3573 Tj
+-306 TJm
+(indicator) 35.417 Tj
+-305 TJm
+(\() 3.31755 Tj
+[1 0 0 1 193.457 421.044] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -193.457 -421.044] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+193.457 421.044 Td
+/F134_0 9.9626 Tf
+(ferror\(f\)) 53.798 Tj
+[1 0 0 1 247.255 421.044] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -247.255 -421.044] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+247.255 421.044 Td
+/F130_0 9.9626 Tf
+(\)is) 9.9626 Tj
+-306 TJm
+(not) 12.7322 Tj
+-305 TJm
+(set.) 13.5591 Tj
+-954 TJm
+(If) 6.63509 Tj
+[1 0 0 1 308.784 421.044] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -308.784 -421.044] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+308.784 421.044 Td
+/F134_0 9.9626 Tf
+(small) 29.8878 Tj
+[1 0 0 1 338.671 421.044] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -338.671 -421.044] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+341.717 421.044 Td
+/F130_0 9.9626 Tf
+(is) 6.64505 Tj
+-306 TJm
+(1,) 7.47195 Tj
+-319 TJm
+(the) 12.1743 Tj
+-306 TJm
+(library) 26.5603 Tj
+-306 TJm
+(will) 15.5018 Tj
+-305 TJm
+(try) 11.0684 Tj
+-306 TJm
+(to) 7.7509 Tj
+-306 TJm
+(dec) 13.8281 Tj
+1 TJm
+(ompress) 33.2053 Tj
+-306 TJm
+(using) 21.589 Tj
+-306 TJm
+(less) 14.9439 Tj
+72 409.089 Td
+(memory) 33.2053 Tj
+65 TJm
+(,) 2.49065 Tj
+-250 TJm
+(at) 7.193 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(e) 4.42339 Tj
+15 TJm
+(xpense) 27.6661 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(speed.) 25.1755 Tj
+[1 0 0 1 72 406.932] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -396.969] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 387.171 Td
+/F130_0 9.9626 Tf
+(F) 5.53921 Tj
+15 TJm
+(or) 8.29885 Tj
+-227 TJm
+(reasons) 29.8778 Tj
+-227 TJm
+(e) 4.42339 Tj
+15 TJm
+(xplained) 34.3112 Tj
+-228 TJm
+(belo) 17.1556 Tj
+25 TJm
+(w) 7.193 Tj
+65 TJm
+(,) 2.49065 Tj
+[1 0 0 1 189.193 387.171] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -189.193 -387.171] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+189.193 387.171 Td
+/F134_0 9.9626 Tf
+(BZ2_bzRead) 59.7756 Tj
+[1 0 0 1 248.969 387.171] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -248.969 -387.171] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+251.232 387.171 Td
+/F130_0 9.9626 Tf
+(will) 15.5018 Tj
+-227 TJm
+(decompress) 47.0334 Tj
+-227 TJm
+(the) 12.1743 Tj
+[1 0 0 1 332.732 387.171] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -332.732 -387.171] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+332.732 387.171 Td
+/F134_0 9.9626 Tf
+(nUnused) 41.8429 Tj
+[1 0 0 1 374.575 387.171] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -374.575 -387.171] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+376.838 387.171 Td
+/F130_0 9.9626 Tf
+(bytes) 21.031 Tj
+-227 TJm
+(starting) 29.8878 Tj
+-227 TJm
+(at) 7.193 Tj
+[1 0 0 1 441.74 387.171] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -441.74 -387.171] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+441.74 387.171 Td
+/F134_0 9.9626 Tf
+(unused) 35.8654 Tj
+[1 0 0 1 477.605 387.171] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -477.605 -387.171] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+477.605 387.171 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-232 TJm
+(before) 25.4445 Tj
+-227 TJm
+(starting) 29.8878 Tj
+72 375.216 Td
+(to) 7.7509 Tj
+-280 TJm
+(read) 17.1456 Tj
+-279 TJm
+(from) 19.3673 Tj
+-280 TJm
+(the) 12.1743 Tj
+-279 TJm
+(\002le) 12.7322 Tj
+[1 0 0 1 155.094 375.215] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -155.094 -375.215] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+155.094 375.215 Td
+/F134_0 9.9626 Tf
+(f) 5.97756 Tj
+[1 0 0 1 161.072 375.215] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -161.072 -375.215] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+161.072 375.215 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+-797 TJm
+(At) 9.9626 Tj
+-280 TJm
+(most) 19.3773 Tj
+[1 0 0 1 206.414 375.215] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -206.414 -375.215] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+206.414 375.215 Td
+/F134_0 9.9626 Tf
+(BZ_MAX_UNUSED) 77.7083 Tj
+[1 0 0 1 284.122 375.215] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -284.122 -375.215] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+286.907 375.215 Td
+/F130_0 9.9626 Tf
+(bytes) 21.031 Tj
+-280 TJm
+(may) 17.1556 Tj
+-279 TJm
+(be) 9.40469 Tj
+-280 TJm
+(supplied) 33.7633 Tj
+-279 TJm
+(lik) 10.5205 Tj
+10 TJm
+(e) 4.42339 Tj
+-280 TJm
+(this.) 16.8866 Tj
+-797 TJm
+(If) 6.63509 Tj
+-279 TJm
+(this) 14.396 Tj
+-280 TJm
+(f) 3.31755 Tj
+10 TJm
+(acility) 24.9065 Tj
+-279 TJm
+(is) 6.64505 Tj
+-280 TJm
+(not) 12.7322 Tj
+-279 TJm
+(required,) 35.686 Tj
+72 363.26 Td
+(you) 14.9439 Tj
+-250 TJm
+(should) 26.5703 Tj
+-250 TJm
+(pass) 17.1556 Tj
+[1 0 0 1 138.141 363.26] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -138.141 -363.26] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+138.141 363.26 Td
+/F134_0 9.9626 Tf
+(NULL) 23.9102 Tj
+[1 0 0 1 162.052 363.26] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -162.052 -363.26] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+164.542 363.26 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 181.419 363.26] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -181.419 -363.26] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+181.419 363.26 Td
+/F134_0 9.9626 Tf
+(0) 5.97756 Tj
+[1 0 0 1 187.397 363.26] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -187.397 -363.26] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+189.887 363.26 Td
+/F130_0 9.9626 Tf
+(for) 11.6164 Tj
+[1 0 0 1 203.994 363.26] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -203.994 -363.26] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+203.994 363.26 Td
+/F134_0 9.9626 Tf
+(unused) 35.8654 Tj
+[1 0 0 1 239.86 363.26] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -239.86 -363.26] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+242.351 363.26 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+-250 TJm
+(n) 4.9813 Tj
+[1 0 0 1 264.208 363.26] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -264.208 -363.26] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+264.208 363.26 Td
+/F134_0 9.9626 Tf
+(Unused) 35.8654 Tj
+[1 0 0 1 300.074 363.26] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -300.074 -363.26] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+302.565 363.26 Td
+/F130_0 9.9626 Tf
+(respecti) 30.9837 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(ely) 12.1743 Tj
+65 TJm
+(.) 2.49065 Tj
+[1 0 0 1 72 361.103] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -351.141] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 341.343 Td
+/F130_0 9.9626 Tf
+(F) 5.53921 Tj
+15 TJm
+(or) 8.29885 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(meaning) 34.3112 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(parameters) 43.7059 Tj
+[1 0 0 1 196.631 341.343] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -196.631 -341.343] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+196.631 341.343 Td
+/F134_0 9.9626 Tf
+(small) 29.8878 Tj
+[1 0 0 1 226.519 341.343] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -226.519 -341.343] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+229.01 341.343 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 245.887 341.343] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -245.887 -341.343] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+245.887 341.343 Td
+/F134_0 9.9626 Tf
+(verbosity) 53.798 Tj
+[1 0 0 1 299.685 341.343] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -299.685 -341.343] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+299.685 341.343 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-250 TJm
+(see) 12.7222 Tj
+[1 0 0 1 319.879 341.343] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -319.879 -341.343] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+319.879 341.343 Td
+/F134_0 9.9626 Tf
+(BZ2_bzDecompressInit) 119.551 Tj
+[1 0 0 1 439.431 341.343] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -439.431 -341.343] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+439.431 341.343 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+[1 0 0 1 72 339.186] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -329.223] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 319.425 Td
+/F130_0 9.9626 Tf
+(The) 15.4918 Tj
+-402 TJm
+(amount) 29.8878 Tj
+-402 TJm
+(of) 8.29885 Tj
+-402 TJm
+(memory) 33.2053 Tj
+-402 TJm
+(needed) 28.2141 Tj
+-402 TJm
+(to) 7.7509 Tj
+-402 TJm
+(decompress) 47.0334 Tj
+-402 TJm
+(a) 4.42339 Tj
+-401 TJm
+(\002le) 12.7322 Tj
+-402 TJm
+(cannot) 26.5603 Tj
+-402 TJm
+(be) 9.40469 Tj
+-402 TJm
+(determined) 44.8217 Tj
+-402 TJm
+(until) 18.2714 Tj
+-402 TJm
+(the) 12.1743 Tj
+-402 TJm
+(\002le') 16.0497 Tj
+55 TJm
+(s) 3.87545 Tj
+-402 TJm
+(header) 26.5503 Tj
+-402 TJm
+(has) 13.2801 Tj
+-402 TJm
+(been) 18.8094 Tj
+-402 TJm
+(read.) 19.6363 Tj
+72 307.47 Td
+(So) 10.5205 Tj
+-492 TJm
+(it) 5.53921 Tj
+-491 TJm
+(is) 6.64505 Tj
+-492 TJm
+(possible) 32.6574 Tj
+-492 TJm
+(that) 14.9439 Tj
+[1 0 0 1 166.797 307.47] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -166.797 -307.47] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+166.797 307.47 Td
+/F134_0 9.9626 Tf
+(BZ2_bzReadOpen) 83.6858 Tj
+[1 0 0 1 250.483 307.47] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -250.483 -307.47] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+255.381 307.47 Td
+/F130_0 9.9626 Tf
+(returns) 27.6661 Tj
+[1 0 0 1 287.945 307.47] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -287.945 -307.47] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+287.945 307.47 Td
+/F134_0 9.9626 Tf
+(BZ_OK) 29.8878 Tj
+[1 0 0 1 317.833 307.47] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -317.833 -307.47] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+322.729 307.47 Td
+/F130_0 9.9626 Tf
+(b) 4.9813 Tj
+20 TJm
+(ut) 7.7509 Tj
+-492 TJm
+(a) 4.42339 Tj
+-491 TJm
+(subsequent) 44.2738 Tj
+-492 TJm
+(call) 14.386 Tj
+-492 TJm
+(of) 8.29885 Tj
+[1 0 0 1 431.135 307.47] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -431.135 -307.47] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+431.135 307.47 Td
+/F134_0 9.9626 Tf
+(BZ2_bzRead) 59.7756 Tj
+[1 0 0 1 490.911 307.47] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -490.911 -307.47] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+495.81 307.47 Td
+/F130_0 9.9626 Tf
+(will) 15.5018 Tj
+-492 TJm
+(return) 23.7907 Tj
+[1 0 0 1 72 295.514] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -295.514] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 295.514 Td
+/F134_0 9.9626 Tf
+(BZ_MEM_ERROR) 71.7307 Tj
+[1 0 0 1 143.731 295.514] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -143.731 -295.514] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+143.731 295.514 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+[1 0 0 1 72 294.204] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -284.242] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 273.597 Td
+/F130_0 9.9626 Tf
+(Possible) 33.2153 Tj
+-250 TJm
+(assignments) 48.7072 Tj
+-250 TJm
+(to) 7.7509 Tj
+[1 0 0 1 169.144 273.597] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -169.144 -273.597] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+169.144 273.597 Td
+/F134_0 9.9626 Tf
+(bzerror) 41.8429 Tj
+[1 0 0 1 210.987 273.597] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -210.987 -273.597] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+210.987 273.597 Td
+/F130_0 9.9626 Tf
+(:) 2.7696 Tj
+[1 0 0 1 72 271.44] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -168.369] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 167.372 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 163.786] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -262.075] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 262.075 Td
+/F134_0 9.9626 Tf
+(BZ_CONFIG_ERROR) 89.6634 Tj
+98.4879 250.12 Td
+(if) 11.9551 Tj
+-426 TJm
+(the) 17.9327 Tj
+-426 TJm
+(library) 41.8429 Tj
+-426 TJm
+(has) 17.9327 Tj
+-426 TJm
+(been) 23.9102 Tj
+-426 TJm
+(mis-compiled) 71.7307 Tj
+90 238.165 Td
+(BZ_PARAM_ERROR) 83.6858 Tj
+98.4879 226.209 Td
+(if) 11.9551 Tj
+-426 TJm
+(f) 5.97756 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(NULL) 23.9102 Tj
+98.4879 214.254 Td
+(or) 11.9551 Tj
+-426 TJm
+(small) 29.8878 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(neither) 41.8429 Tj
+-426 TJm
+(0) 5.97756 Tj
+-426 TJm
+(nor) 17.9327 Tj
+-426 TJm
+(1) 5.97756 Tj
+98.4879 202.299 Td
+(or) 11.9551 Tj
+-426 TJm
+(\() 5.97756 Tj
+-426 TJm
+(unused) 35.8654 Tj
+-426 TJm
+(==) 11.9551 Tj
+-426 TJm
+(NULL) 23.9102 Tj
+-426 TJm
+(&&) 11.9551 Tj
+-426 TJm
+(nUnused) 41.8429 Tj
+-426 TJm
+(!=) 11.9551 Tj
+-426 TJm
+(0) 5.97756 Tj
+-426 TJm
+(\)) 5.97756 Tj
+98.4879 190.344 Td
+(or) 11.9551 Tj
+-426 TJm
+(\() 5.97756 Tj
+-426 TJm
+(unused) 35.8654 Tj
+-426 TJm
+(!=) 11.9551 Tj
+-426 TJm
+(NULL) 23.9102 Tj
+-426 TJm
+(&&) 11.9551 Tj
+-426 TJm
+(!\(0) 17.9327 Tj
+-426 TJm
+(<=) 11.9551 Tj
+-426 TJm
+(nUnused) 41.8429 Tj
+-426 TJm
+(<=) 11.9551 Tj
+-426 TJm
+(BZ_MAX_UNUSED\)) 83.6858 Tj
+-426 TJm
+(\)) 5.97756 Tj
+90 178.389 Td
+(BZ_IO_ERROR) 65.7532 Tj
+98.4879 166.434 Td
+(if) 11.9551 Tj
+-426 TJm
+(ferror\(f\)) 53.798 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(nonzero) 41.8429 Tj
+90 154.478 Td
+(BZ_MEM_ERROR) 71.7307 Tj
+98.4879 142.523 Td
+(if) 11.9551 Tj
+-426 TJm
+(insufficient) 71.7307 Tj
+-426 TJm
+(memory) 35.8654 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(available) 53.798 Tj
+90 130.568 Td
+(BZ_OK) 29.8878 Tj
+98.4879 118.613 Td
+(otherwise.) 59.7756 Tj
+[1 0 0 1 72 103.071] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.5492] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -93.1085] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 81.1533 Td
+/F130_0 9.9626 Tf
+(Possible) 33.2153 Tj
+-250 TJm
+(return) 23.7907 Tj
+-250 TJm
+(v) 4.9813 Tj
+25 TJm
+(alues:) 23.2427 Tj
+[1 0 0 1 72 81.0538] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -30.202] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 374.394 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 6.9737] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 40.5726 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -493.841 -51.071] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+534.414 51.071 Td
+/F130_0 9.9626 Tf
+(19) 9.9626 Tj
+[1 0 0 1 453.269 50.8519] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 93.5985 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.2765 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+Q
+showpage
+%%PageTrailer
+pdfEndPage
+%%Page: 23 23
+%%BeginPageSetup
+%%PageOrientation: Portrait
+pdfStartPage
+0 0 612 792 re W
+%%EndPageSetup
+[] 0 d
+1 i
+0 j
+0 J
+10 M
+1 w
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+false op
+false OP
+0 0 612 792 re
+W
+q
+[1 0 0 1 72 741.554] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 14.4459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 187.197 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 -8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 76.4979 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -342.569 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+419.067 749.245 Td
+/F130_0 9.9626 Tf
+(Programming) 54.7943 Tj
+-250 TJm
+(with) 17.7135 Tj
+[1 0 0 1 496.556 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -496.556 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+496.556 749.245 Td
+/F134_0 9.9626 Tf
+(libbzip2) 47.8205 Tj
+[1 0 0 1 544.376 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -278.305 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 280.796 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -472.974 -5.0363] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -0.4981] cm
+q
+[] 0 d
+0 J
+0.4981 w
+0 0.2491 m
+475.465 0.2491 l
+S
+Q
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 479.251 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -81.33] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 59.7758 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 56.1892] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -711.631] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 711.631 Td
+/F134_0 9.9626 Tf
+(Pointer) 41.8429 Tj
+-426 TJm
+(to) 11.9551 Tj
+-426 TJm
+(an) 11.9551 Tj
+-426 TJm
+(abstract) 47.8205 Tj
+-426 TJm
+(BZFILE) 35.8654 Tj
+98.4879 699.676 Td
+(if) 11.9551 Tj
+-426 TJm
+(bzerror) 41.8429 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(BZ_OK) 29.8878 Tj
+90 687.721 Td
+(NULL) 23.9102 Tj
+98.4879 675.766 Td
+(otherwise) 53.798 Tj
+[1 0 0 1 72 660.224] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.5493] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -650.261] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 638.306 Td
+/F130_0 9.9626 Tf
+(Allo) 17.7135 Tj
+25 TJm
+(w) 7.193 Tj
+10 TJm
+(able) 16.5977 Tj
+-250 TJm
+(ne) 9.40469 Tj
+15 TJm
+(xt) 7.7509 Tj
+-250 TJm
+(actions:) 30.9936 Tj
+[1 0 0 1 72 638.207] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -60.7721] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 59.7758 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 56.1893] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -628.842] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 628.842 Td
+/F134_0 9.9626 Tf
+(BZ2_bzRead) 59.7756 Tj
+98.4879 616.887 Td
+(if) 11.9551 Tj
+-426 TJm
+(bzerror) 41.8429 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(BZ_OK) 29.8878 Tj
+90 604.932 Td
+(BZ2_bzClose) 65.7532 Tj
+98.4879 592.976 Td
+(otherwise) 53.798 Tj
+[1 0 0 1 72 577.435] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -567.472] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 546.813 Td
+/F122_0 17.2154 Tf
+(3.4.2.) 43.0729 Tj
+[1 0 0 1 119.858 546.813] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -119.858 -546.813] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+119.858 546.813 Td
+/F392_0 17.2154 Tf
+(BZ2_bzRead) 103.292 Tj
+[1 0 0 1 223.15 546.813] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -151.15 -2.3326] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -24.9066] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 23.9103 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 20.3237] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -535.116] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 535.116 Td
+/F134_0 9.9626 Tf
+(int) 17.9327 Tj
+-426 TJm
+(BZ2_bzRead) 59.7756 Tj
+-426 TJm
+(\() 5.97756 Tj
+-426 TJm
+(int) 17.9327 Tj
+208.595 533.373 Td
+(*) 5.97756 Tj
+214.572 535.116 Td
+(bzerror,) 47.8205 Tj
+-426 TJm
+(BZFILE) 35.8654 Tj
+306.747 533.373 Td
+(*) 5.97756 Tj
+312.724 535.116 Td
+(b,) 11.9551 Tj
+-426 TJm
+(void) 23.9102 Tj
+357.077 533.373 Td
+(*) 5.97756 Tj
+363.055 535.116 Td
+(buf,) 23.9102 Tj
+-426 TJm
+(int) 17.9327 Tj
+-426 TJm
+(len) 17.9327 Tj
+-426 TJm
+(\);) 11.9551 Tj
+[1 0 0 1 72 519.574] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.5492] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -509.612] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 497.656 Td
+/F130_0 9.9626 Tf
+(Reads) 24.3486 Tj
+-285 TJm
+(up) 9.9626 Tj
+-284 TJm
+(to) 7.7509 Tj
+[1 0 0 1 122.569 497.656] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -122.569 -497.656] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+122.569 497.656 Td
+/F134_0 9.9626 Tf
+(len) 17.9327 Tj
+[1 0 0 1 140.501 497.656] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -140.501 -497.656] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+143.337 497.656 Td
+/F130_0 9.9626 Tf
+(\(uncompressed\)) 63.6311 Tj
+-285 TJm
+(bytes) 21.031 Tj
+-284 TJm
+(from) 19.3673 Tj
+-285 TJm
+(the) 12.1743 Tj
+-284 TJm
+(compressed) 47.0334 Tj
+-285 TJm
+(\002le) 12.7322 Tj
+[1 0 0 1 336.319 497.656] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -336.319 -497.656] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+336.319 497.656 Td
+/F134_0 9.9626 Tf
+(b) 5.97756 Tj
+[1 0 0 1 342.296 497.656] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -342.296 -497.656] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+345.132 497.656 Td
+/F130_0 9.9626 Tf
+(into) 15.5018 Tj
+-285 TJm
+(the) 12.1743 Tj
+-284 TJm
+(b) 4.9813 Tj
+20 TJm
+(uf) 8.29885 Tj
+25 TJm
+(fer) 11.0585 Tj
+[1 0 0 1 405.205 497.656] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -405.205 -497.656] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+405.205 497.656 Td
+/F134_0 9.9626 Tf
+(buf) 17.9327 Tj
+[1 0 0 1 423.137 497.656] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -423.137 -497.656] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+423.137 497.656 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+-828 TJm
+(If) 6.63509 Tj
+-284 TJm
+(the) 12.1743 Tj
+-285 TJm
+(read) 17.1456 Tj
+-285 TJm
+(w) 7.193 Tj
+10 TJm
+(as) 8.29885 Tj
+-284 TJm
+(successful,) 43.4369 Tj
+[1 0 0 1 72 485.701] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -485.701] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 485.701 Td
+/F134_0 9.9626 Tf
+(bzerror) 41.8429 Tj
+[1 0 0 1 113.843 485.701] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -113.843 -485.701] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+117.36 485.701 Td
+/F130_0 9.9626 Tf
+(is) 6.64505 Tj
+-353 TJm
+(set) 11.0684 Tj
+-353 TJm
+(to) 7.7509 Tj
+[1 0 0 1 153.374 485.701] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -153.374 -485.701] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+153.374 485.701 Td
+/F134_0 9.9626 Tf
+(BZ_OK) 29.8878 Tj
+[1 0 0 1 183.262 485.701] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -183.262 -485.701] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+186.778 485.701 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+-353 TJm
+(the) 12.1743 Tj
+-353 TJm
+(number) 30.4357 Tj
+-353 TJm
+(of) 8.29885 Tj
+-353 TJm
+(bytes) 21.031 Tj
+-353 TJm
+(read) 17.1456 Tj
+-353 TJm
+(is) 6.64505 Tj
+-353 TJm
+(returned.) 35.686 Tj
+-1238 TJm
+(If) 6.63509 Tj
+-353 TJm
+(the) 12.1743 Tj
+-353 TJm
+(logical) 27.1182 Tj
+-353 TJm
+(end-of-stream) 55.8802 Tj
+-353 TJm
+(w) 7.193 Tj
+10 TJm
+(as) 8.29885 Tj
+-353 TJm
+(detected,) 35.686 Tj
+[1 0 0 1 72 473.746] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -473.746] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 473.746 Td
+/F134_0 9.9626 Tf
+(bzerror) 41.8429 Tj
+[1 0 0 1 113.843 473.746] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -113.843 -473.746] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+116.795 473.746 Td
+/F130_0 9.9626 Tf
+(will) 15.5018 Tj
+-296 TJm
+(be) 9.40469 Tj
+-297 TJm
+(set) 11.0684 Tj
+-296 TJm
+(to) 7.7509 Tj
+[1 0 0 1 172.329 473.746] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -172.329 -473.746] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+172.329 473.746 Td
+/F134_0 9.9626 Tf
+(BZ_STREAM_END) 77.7083 Tj
+[1 0 0 1 250.037 473.746] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -250.037 -473.746] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+250.037 473.746 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-296 TJm
+(and) 14.386 Tj
+-297 TJm
+(the) 12.1743 Tj
+-296 TJm
+(number) 30.4357 Tj
+-296 TJm
+(of) 8.29885 Tj
+-297 TJm
+(bytes) 21.031 Tj
+-296 TJm
+(read) 17.1456 Tj
+-296 TJm
+(is) 6.64505 Tj
+-296 TJm
+(returned.) 35.686 Tj
+-898 TJm
+(All) 12.7322 Tj
+-297 TJm
+(other) 20.4731 Tj
+[1 0 0 1 470 473.746] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -470 -473.746] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+470 473.746 Td
+/F134_0 9.9626 Tf
+(bzerror) 41.8429 Tj
+[1 0 0 1 511.843 473.746] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -511.843 -473.746] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+514.795 473.746 Td
+/F130_0 9.9626 Tf
+(v) 4.9813 Tj
+25 TJm
+(alues) 20.4731 Tj
+72 461.791 Td
+(denote) 26.5603 Tj
+-250 TJm
+(an) 9.40469 Tj
+-250 TJm
+(error) 19.3573 Tj
+55 TJm
+(.) 2.49065 Tj
+[1 0 0 1 72 461.691] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -451.729] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 439.873 Td
+/F134_0 9.9626 Tf
+(BZ2_bzRead) 59.7756 Tj
+[1 0 0 1 131.776 439.873] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -131.776 -439.873] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+134.224 439.873 Td
+/F130_0 9.9626 Tf
+(will) 15.5018 Tj
+-246 TJm
+(supply) 26.5703 Tj
+[1 0 0 1 181.193 439.873] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -181.193 -439.873] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+181.193 439.873 Td
+/F134_0 9.9626 Tf
+(len) 17.9327 Tj
+[1 0 0 1 199.126 439.873] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -199.126 -439.873] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+201.575 439.873 Td
+/F130_0 9.9626 Tf
+(bytes,) 23.5217 Tj
+-247 TJm
+(unless) 24.9065 Tj
+-245 TJm
+(the) 12.1743 Tj
+-246 TJm
+(logical) 27.1182 Tj
+-246 TJm
+(stream) 26.5603 Tj
+-246 TJm
+(end) 14.386 Tj
+-245 TJm
+(is) 6.64505 Tj
+-246 TJm
+(detected) 33.1954 Tj
+-246 TJm
+(or) 8.29885 Tj
+-246 TJm
+(an) 9.40469 Tj
+-246 TJm
+(error) 19.3573 Tj
+-245 TJm
+(occurs.) 28.493 Tj
+-617 TJm
+(Because) 33.1954 Tj
+-246 TJm
+(of) 8.29885 Tj
+-246 TJm
+(this,) 16.8866 Tj
+-247 TJm
+(it) 5.53921 Tj
+72 427.918 Td
+(is) 6.64505 Tj
+-231 TJm
+(possible) 32.6574 Tj
+-231 TJm
+(to) 7.7509 Tj
+-231 TJm
+(detect) 23.7907 Tj
+-231 TJm
+(the) 12.1743 Tj
+-231 TJm
+(stream) 26.5603 Tj
+-231 TJm
+(end) 14.386 Tj
+-232 TJm
+(by) 9.9626 Tj
+-231 TJm
+(observing) 39.2925 Tj
+-231 TJm
+(when) 21.579 Tj
+-231 TJm
+(the) 12.1743 Tj
+-231 TJm
+(number) 30.4357 Tj
+-231 TJm
+(of) 8.29885 Tj
+-231 TJm
+(bytes) 21.031 Tj
+-231 TJm
+(returned) 33.1954 Tj
+-231 TJm
+(is) 6.64505 Tj
+-231 TJm
+(less) 14.9439 Tj
+-231 TJm
+(than) 17.1556 Tj
+-232 TJm
+(the) 12.1743 Tj
+-231 TJm
+(number) 30.4357 Tj
+-231 TJm
+(requested.) 40.6673 Tj
+72 415.963 Td
+(Ne) 11.6164 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(ertheless,) 37.3498 Tj
+-309 TJm
+(this) 14.396 Tj
+-297 TJm
+(is) 6.64505 Tj
+-298 TJm
+(re) 7.74094 Tj
+15 TJm
+(g) 4.9813 Tj
+5 TJm
+(arded) 22.1269 Tj
+-297 TJm
+(as) 8.29885 Tj
+-297 TJm
+(inadvisable;) 48.1492 Tj
+-321 TJm
+(you) 14.9439 Tj
+-298 TJm
+(should) 26.5703 Tj
+-297 TJm
+(instead) 28.224 Tj
+-297 TJm
+(check) 23.2328 Tj
+[1 0 0 1 360.631 415.963] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -360.631 -415.963] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+360.631 415.963 Td
+/F134_0 9.9626 Tf
+(bzerror) 41.8429 Tj
+[1 0 0 1 402.475 415.963] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -402.475 -415.963] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+405.437 415.963 Td
+/F130_0 9.9626 Tf
+(after) 18.2515 Tj
+-297 TJm
+(e) 4.42339 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(ery) 12.7222 Tj
+-298 TJm
+(call) 14.386 Tj
+-297 TJm
+(and) 14.386 Tj
+-297 TJm
+(w) 7.193 Tj
+10 TJm
+(atch) 16.5977 Tj
+-298 TJm
+(out) 12.7322 Tj
+-297 TJm
+(for) 11.6164 Tj
+[1 0 0 1 72 404.008] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -404.008] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 404.008 Td
+/F134_0 9.9626 Tf
+(BZ_STREAM_END) 77.7083 Tj
+[1 0 0 1 149.709 404.008] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -149.709 -404.008] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+149.709 404.008 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+[1 0 0 1 72 402.698] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -392.735] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 382.09 Td
+/F130_0 9.9626 Tf
+(Internally) 38.7346 Tj
+65 TJm
+(,) 2.49065 Tj
+[1 0 0 1 117.541 382.09] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -117.541 -382.09] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+117.541 382.09 Td
+/F134_0 9.9626 Tf
+(BZ2_bzRead) 59.7756 Tj
+[1 0 0 1 177.317 382.09] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -177.317 -382.09] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+181.786 382.09 Td
+/F130_0 9.9626 Tf
+(copies) 25.4544 Tj
+-449 TJm
+(data) 16.5977 Tj
+-448 TJm
+(from) 19.3673 Tj
+-449 TJm
+(the) 12.1743 Tj
+-448 TJm
+(compressed) 47.0334 Tj
+-449 TJm
+(\002le) 12.7322 Tj
+-448 TJm
+(in) 7.7509 Tj
+-449 TJm
+(chunks) 28.224 Tj
+-449 TJm
+(of) 8.29885 Tj
+-448 TJm
+(size) 15.4918 Tj
+[1 0 0 1 419.602 382.09] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -419.602 -382.09] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+419.602 382.09 Td
+/F134_0 9.9626 Tf
+(BZ_MAX_UNUSED) 77.7083 Tj
+[1 0 0 1 497.31 382.09] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -497.31 -382.09] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+501.778 382.09 Td
+/F130_0 9.9626 Tf
+(bytes) 21.031 Tj
+-449 TJm
+(be-) 12.7222 Tj
+72 370.135 Td
+(fore) 16.0398 Tj
+-414 TJm
+(decompressing) 59.7656 Tj
+-414 TJm
+(it.) 8.02986 Tj
+-1605 TJm
+(If) 6.63509 Tj
+-415 TJm
+(the) 12.1743 Tj
+-414 TJm
+(\002le) 12.7322 Tj
+-414 TJm
+(contains) 33.2053 Tj
+-414 TJm
+(more) 20.4731 Tj
+-414 TJm
+(bytes) 21.031 Tj
+-415 TJm
+(than) 17.1556 Tj
+-414 TJm
+(strictly) 27.6761 Tj
+-414 TJm
+(needed) 28.2141 Tj
+-414 TJm
+(to) 7.7509 Tj
+-414 TJm
+(reach) 21.569 Tj
+-414 TJm
+(the) 12.1743 Tj
+-415 TJm
+(logical) 27.1182 Tj
+-414 TJm
+(end-of-stream,) 58.3709 Tj
+[1 0 0 1 72 358.18] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -358.18] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 358.18 Td
+/F134_0 9.9626 Tf
+(BZ2_bzRead) 59.7756 Tj
+[1 0 0 1 131.776 358.18] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -131.776 -358.18] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+134.749 358.18 Td
+/F130_0 9.9626 Tf
+(will) 15.5018 Tj
+-298 TJm
+(almost) 26.5703 Tj
+-299 TJm
+(certainly) 34.8591 Tj
+-298 TJm
+(read) 17.1456 Tj
+-299 TJm
+(some) 21.031 Tj
+-298 TJm
+(of) 8.29885 Tj
+-299 TJm
+(the) 12.1743 Tj
+-298 TJm
+(trailing) 28.782 Tj
+-298 TJm
+(data) 16.5977 Tj
+-299 TJm
+(before) 25.4445 Tj
+-298 TJm
+(signalling) 39.3025 Tj
+[1 0 0 1 413.162 358.18] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -413.162 -358.18] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+413.162 358.18 Td
+/F134_0 9.9626 Tf
+(BZ_SEQUENCE_END) 89.6634 Tj
+[1 0 0 1 502.826 358.18] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -502.826 -358.18] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+502.826 358.18 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+-597 TJm
+(T) 6.08715 Tj
+80 TJm
+(o) 4.9813 Tj
+-298 TJm
+(col-) 15.4918 Tj
+72 346.224 Td
+(lect) 14.386 Tj
+-242 TJm
+(the) 12.1743 Tj
+-242 TJm
+(read) 17.1456 Tj
+-243 TJm
+(b) 4.9813 Tj
+20 TJm
+(ut) 7.7509 Tj
+-242 TJm
+(unused) 28.224 Tj
+-242 TJm
+(data) 16.5977 Tj
+-242 TJm
+(once) 18.8094 Tj
+[1 0 0 1 208.759 346.224] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -208.759 -346.224] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+208.759 346.224 Td
+/F134_0 9.9626 Tf
+(BZ_SEQUENCE_END) 89.6634 Tj
+[1 0 0 1 298.423 346.224] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -298.423 -346.224] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+300.835 346.224 Td
+/F130_0 9.9626 Tf
+(has) 13.2801 Tj
+-242 TJm
+(appeared,) 38.4457 Tj
+-244 TJm
+(call) 14.386 Tj
+[1 0 0 1 374.201 346.224] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -374.201 -346.224] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+374.201 346.224 Td
+/F134_0 9.9626 Tf
+(BZ2_bzReadGetUnused) 113.574 Tj
+[1 0 0 1 487.775 346.224] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -487.775 -346.224] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+490.188 346.224 Td
+/F130_0 9.9626 Tf
+(immediately) 49.813 Tj
+72 334.269 Td
+(before) 25.4445 Tj
+[1 0 0 1 99.935 334.269] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -99.935 -334.269] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+99.935 334.269 Td
+/F134_0 9.9626 Tf
+(BZ2_bzReadClose) 89.6634 Tj
+[1 0 0 1 189.599 334.269] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -189.599 -334.269] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+189.599 334.269 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+[1 0 0 1 72 332.959] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -322.996] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 312.351 Td
+/F130_0 9.9626 Tf
+(Possible) 33.2153 Tj
+-250 TJm
+(assignments) 48.7072 Tj
+-250 TJm
+(to) 7.7509 Tj
+[1 0 0 1 169.144 312.351] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -169.144 -312.351] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+169.144 312.351 Td
+/F134_0 9.9626 Tf
+(bzerror) 41.8429 Tj
+[1 0 0 1 210.987 312.351] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -210.987 -312.351] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+210.987 312.351 Td
+/F130_0 9.9626 Tf
+(:) 2.7696 Tj
+[1 0 0 1 72 310.195] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -259.343] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 374.394 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 6.8541] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 40.5726 -6.7545] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -493.841 -50.9514] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+534.414 50.9514 Td
+/F130_0 9.9626 Tf
+(20) 9.9626 Tj
+[1 0 0 1 453.269 50.8518] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 93.5985 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.2765 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+Q
+showpage
+%%PageTrailer
+pdfEndPage
+%%Page: 24 24
+%%BeginPageSetup
+%%PageOrientation: Portrait
+pdfStartPage
+0 0 612 792 re W
+%%EndPageSetup
+[] 0 d
+1 i
+0 j
+0 J
+10 M
+1 w
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+false op
+false OP
+0 0 612 792 re
+W
+q
+[1 0 0 1 72 741.554] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 14.4459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 187.197 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 -8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 76.4979 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -342.569 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+419.067 749.245 Td
+/F130_0 9.9626 Tf
+(Programming) 54.7943 Tj
+-250 TJm
+(with) 17.7135 Tj
+[1 0 0 1 496.556 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -496.556 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+496.556 749.245 Td
+/F134_0 9.9626 Tf
+(libbzip2) 47.8205 Tj
+[1 0 0 1 544.376 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -278.305 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 280.796 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -472.974 -5.0363] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -0.4981] cm
+q
+[] 0 d
+0 J
+0.4981 w
+0 0.2491 m
+475.465 0.2491 l
+S
+Q
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 479.251 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -284.568] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 263.014 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 259.427] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -711.631] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 711.631 Td
+/F134_0 9.9626 Tf
+(BZ_PARAM_ERROR) 83.6858 Tj
+98.4879 699.676 Td
+(if) 11.9551 Tj
+-426 TJm
+(b) 5.97756 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(NULL) 23.9102 Tj
+-426 TJm
+(or) 11.9551 Tj
+-426 TJm
+(buf) 17.9327 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(NULL) 23.9102 Tj
+-426 TJm
+(or) 11.9551 Tj
+-426 TJm
+(len) 17.9327 Tj
+-426 TJm
+(<) 5.97756 Tj
+-426 TJm
+(0) 5.97756 Tj
+90 687.721 Td
+(BZ_SEQUENCE_ERROR) 101.619 Tj
+98.4879 675.766 Td
+(if) 11.9551 Tj
+-426 TJm
+(b) 5.97756 Tj
+-426 TJm
+(was) 17.9327 Tj
+-426 TJm
+(opened) 35.8654 Tj
+-426 TJm
+(with) 23.9102 Tj
+-426 TJm
+(BZ2_bzWriteOpen) 89.6634 Tj
+90 663.811 Td
+(BZ_IO_ERROR) 65.7532 Tj
+98.4879 651.856 Td
+(if) 11.9551 Tj
+-426 TJm
+(there) 29.8878 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(an) 11.9551 Tj
+-426 TJm
+(error) 29.8878 Tj
+-426 TJm
+(reading) 41.8429 Tj
+-426 TJm
+(from) 23.9102 Tj
+-426 TJm
+(the) 17.9327 Tj
+-426 TJm
+(compressed) 59.7756 Tj
+-426 TJm
+(file) 23.9102 Tj
+90 639.9 Td
+(BZ_UNEXPECTED_EOF) 101.619 Tj
+98.4879 627.945 Td
+(if) 11.9551 Tj
+-426 TJm
+(the) 17.9327 Tj
+-426 TJm
+(compressed) 59.7756 Tj
+-426 TJm
+(file) 23.9102 Tj
+-426 TJm
+(ended) 29.8878 Tj
+-426 TJm
+(before) 35.8654 Tj
+98.4879 615.99 Td
+(the) 17.9327 Tj
+-426 TJm
+(logical) 41.8429 Tj
+-426 TJm
+(end-of-stream) 77.7083 Tj
+-426 TJm
+(was) 17.9327 Tj
+-426 TJm
+(detected) 47.8205 Tj
+90 604.035 Td
+(BZ_DATA_ERROR) 77.7083 Tj
+98.4879 592.08 Td
+(if) 11.9551 Tj
+-426 TJm
+(a) 5.97756 Tj
+-426 TJm
+(data) 23.9102 Tj
+-426 TJm
+(integrity) 53.798 Tj
+-426 TJm
+(error) 29.8878 Tj
+-426 TJm
+(was) 17.9327 Tj
+-426 TJm
+(detected) 47.8205 Tj
+-426 TJm
+(in) 11.9551 Tj
+-426 TJm
+(the) 17.9327 Tj
+-426 TJm
+(compressed) 59.7756 Tj
+-426 TJm
+(stream) 35.8654 Tj
+90 580.125 Td
+(BZ_DATA_ERROR_MAGIC) 113.574 Tj
+98.4879 568.169 Td
+(if) 11.9551 Tj
+-426 TJm
+(the) 17.9327 Tj
+-426 TJm
+(stream) 35.8654 Tj
+-426 TJm
+(does) 23.9102 Tj
+-426 TJm
+(not) 17.9327 Tj
+-426 TJm
+(begin) 29.8878 Tj
+-426 TJm
+(with) 23.9102 Tj
+-426 TJm
+(the) 17.9327 Tj
+-426 TJm
+(requisite) 53.798 Tj
+-426 TJm
+(header) 35.8654 Tj
+-426 TJm
+(bytes) 29.8878 Tj
+98.4879 556.214 Td
+(\(ie,) 23.9102 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(not) 17.9327 Tj
+-426 TJm
+(a) 5.97756 Tj
+-426 TJm
+(bzip2) 29.8878 Tj
+-426 TJm
+(data) 23.9102 Tj
+-426 TJm
+(file\).) 35.8654 Tj
+-852 TJm
+(This) 23.9102 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(really) 35.8654 Tj
+98.4879 544.259 Td
+(a) 5.97756 Tj
+-426 TJm
+(special) 41.8429 Tj
+-426 TJm
+(case) 23.9102 Tj
+-426 TJm
+(of) 11.9551 Tj
+-426 TJm
+(BZ_DATA_ERROR.) 83.6858 Tj
+90 532.304 Td
+(BZ_MEM_ERROR) 71.7307 Tj
+98.4879 520.349 Td
+(if) 11.9551 Tj
+-426 TJm
+(insufficient) 71.7307 Tj
+-426 TJm
+(memory) 35.8654 Tj
+-426 TJm
+(was) 17.9327 Tj
+-426 TJm
+(available) 53.798 Tj
+90 508.394 Td
+(BZ_STREAM_END) 77.7083 Tj
+98.4879 496.438 Td
+(if) 11.9551 Tj
+-426 TJm
+(the) 17.9327 Tj
+-426 TJm
+(logical) 41.8429 Tj
+-426 TJm
+(end) 17.9327 Tj
+-426 TJm
+(of) 11.9551 Tj
+-426 TJm
+(stream) 35.8654 Tj
+-426 TJm
+(was) 17.9327 Tj
+-426 TJm
+(detected.) 53.798 Tj
+90 484.483 Td
+(BZ_OK) 29.8878 Tj
+98.4879 472.528 Td
+(otherwise.) 59.7756 Tj
+[1 0 0 1 72 456.986] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.5492] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -447.024] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 435.068 Td
+/F130_0 9.9626 Tf
+(Possible) 33.2153 Tj
+-250 TJm
+(return) 23.7907 Tj
+-250 TJm
+(v) 4.9813 Tj
+25 TJm
+(alues:) 23.2427 Tj
+[1 0 0 1 72 434.969] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -60.7721] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 59.7758 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 56.1893] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -425.604] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 425.604 Td
+/F134_0 9.9626 Tf
+(number) 35.8654 Tj
+-426 TJm
+(of) 11.9551 Tj
+-426 TJm
+(bytes) 29.8878 Tj
+-426 TJm
+(read) 23.9102 Tj
+98.4879 413.649 Td
+(if) 11.9551 Tj
+-426 TJm
+(bzerror) 41.8429 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(BZ_OK) 29.8878 Tj
+-426 TJm
+(or) 11.9551 Tj
+-426 TJm
+(BZ_STREAM_END) 77.7083 Tj
+90 401.694 Td
+(undefined) 53.798 Tj
+98.4879 389.739 Td
+(otherwise) 53.798 Tj
+[1 0 0 1 72 374.197] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.5492] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -364.234] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 352.279 Td
+/F130_0 9.9626 Tf
+(Allo) 17.7135 Tj
+25 TJm
+(w) 7.193 Tj
+10 TJm
+(able) 16.5977 Tj
+-250 TJm
+(ne) 9.40469 Tj
+15 TJm
+(xt) 7.7509 Tj
+-250 TJm
+(actions:) 30.9936 Tj
+[1 0 0 1 72 352.18] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -84.6825] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 83.6862 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 80.0996] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -342.815] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 342.815 Td
+/F134_0 9.9626 Tf
+(collect) 41.8429 Tj
+-426 TJm
+(data) 23.9102 Tj
+-426 TJm
+(from) 23.9102 Tj
+-426 TJm
+(buf,) 23.9102 Tj
+-426 TJm
+(then) 23.9102 Tj
+-426 TJm
+(BZ2_bzRead) 59.7756 Tj
+-426 TJm
+(or) 11.9551 Tj
+-426 TJm
+(BZ2_bzReadClose) 89.6634 Tj
+98.4879 330.859 Td
+(if) 11.9551 Tj
+-426 TJm
+(bzerror) 41.8429 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(BZ_OK) 29.8878 Tj
+90 318.904 Td
+(collect) 41.8429 Tj
+-426 TJm
+(data) 23.9102 Tj
+-426 TJm
+(from) 23.9102 Tj
+-426 TJm
+(buf,) 23.9102 Tj
+-426 TJm
+(then) 23.9102 Tj
+-426 TJm
+(BZ2_bzReadClose) 89.6634 Tj
+-426 TJm
+(or) 11.9551 Tj
+-426 TJm
+(BZ2_bzReadGetUnused) 113.574 Tj
+98.4879 306.949 Td
+(if) 11.9551 Tj
+-426 TJm
+(bzerror) 41.8429 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(BZ_SEQUENCE_END) 89.6634 Tj
+90 294.994 Td
+(BZ2_bzReadClose) 89.6634 Tj
+98.4879 283.039 Td
+(otherwise) 53.798 Tj
+[1 0 0 1 72 267.497] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -257.534] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 236.876 Td
+/F122_0 17.2154 Tf
+(3.4.3.) 43.0729 Tj
+[1 0 0 1 119.858 236.876] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -119.858 -236.876] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+119.858 236.876 Td
+/F392_0 17.2154 Tf
+(BZ2_bzReadGetUnused) 196.256 Tj
+[1 0 0 1 316.114 236.876] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -244.114 -2.3327] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -36.8617] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 35.8655 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 32.2789] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -225.178] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 225.178 Td
+/F134_0 9.9626 Tf
+(void) 23.9102 Tj
+-426 TJm
+(BZ2_bzReadGetUnused\() 119.551 Tj
+-426 TJm
+(int) 17.9327 Tj
+259.883 223.435 Td
+(*) 5.97756 Tj
+270.104 225.178 Td
+(bzerror,) 47.8205 Tj
+-426 TJm
+(BZFILE) 35.8654 Tj
+362.278 223.435 Td
+(*) 5.97756 Tj
+368.256 225.178 Td
+(b,) 11.9551 Tj
+200.343 213.223 Td
+(void) 23.9102 Tj
+224.254 211.48 Td
+(**) 11.9551 Tj
+240.453 213.223 Td
+(unused,) 41.8429 Tj
+-426 TJm
+(int) 17.9327 Tj
+304.473 211.48 Td
+(*) 5.97756 Tj
+314.694 213.223 Td
+(nUnused) 41.8429 Tj
+-426 TJm
+(\);) 11.9551 Tj
+[1 0 0 1 72 197.681] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.5492] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -187.719] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 175.764 Td
+/F130_0 9.9626 Tf
+(Returns) 30.9936 Tj
+-435 TJm
+(data) 16.5977 Tj
+-435 TJm
+(which) 24.3486 Tj
+-435 TJm
+(w) 7.193 Tj
+10 TJm
+(as) 8.29885 Tj
+-435 TJm
+(read) 17.1456 Tj
+-435 TJm
+(from) 19.3673 Tj
+-435 TJm
+(the) 12.1743 Tj
+-435 TJm
+(compressed) 47.0334 Tj
+-435 TJm
+(\002le) 12.7322 Tj
+-435 TJm
+(b) 4.9813 Tj
+20 TJm
+(ut) 7.7509 Tj
+-435 TJm
+(w) 7.193 Tj
+10 TJm
+(as) 8.29885 Tj
+-435 TJm
+(not) 12.7322 Tj
+-435 TJm
+(needed) 28.2141 Tj
+-435 TJm
+(to) 7.7509 Tj
+-435 TJm
+(get) 12.1743 Tj
+-435 TJm
+(to) 7.7509 Tj
+-435 TJm
+(the) 12.1743 Tj
+-435 TJm
+(logical) 27.1182 Tj
+-435 TJm
+(end-of-stream.) 58.3709 Tj
+[1 0 0 1 72 163.809] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -163.809] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 162.065 Td
+/F134_0 9.9626 Tf
+(*) 5.97756 Tj
+77.9776 163.809 Td
+(unused) 35.8654 Tj
+[1 0 0 1 113.843 163.809] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -113.843 -163.809] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+117.2 163.809 Td
+/F130_0 9.9626 Tf
+(is) 6.64505 Tj
+-337 TJm
+(set) 11.0684 Tj
+-337 TJm
+(to) 7.7509 Tj
+-337 TJm
+(the) 12.1743 Tj
+-337 TJm
+(address) 29.8778 Tj
+-337 TJm
+(of) 8.29885 Tj
+-336 TJm
+(the) 12.1743 Tj
+-337 TJm
+(data,) 19.0883 Tj
+-359 TJm
+(and) 14.386 Tj
+[1 0 0 1 269.089 163.809] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -269.089 -163.809] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+269.089 162.065 Td
+/F134_0 9.9626 Tf
+(*) 5.97756 Tj
+275.067 163.809 Td
+(nUnused) 41.8429 Tj
+[1 0 0 1 316.91 163.809] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -316.91 -163.809] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+320.267 163.809 Td
+/F130_0 9.9626 Tf
+(to) 7.7509 Tj
+-337 TJm
+(the) 12.1743 Tj
+-337 TJm
+(number) 30.4357 Tj
+-337 TJm
+(of) 8.29885 Tj
+-337 TJm
+(bytes.) 23.5217 Tj
+[1 0 0 1 427.247 163.809] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -427.247 -163.809] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+427.247 162.065 Td
+/F134_0 9.9626 Tf
+(*) 5.97756 Tj
+433.225 163.809 Td
+(nUnused) 41.8429 Tj
+[1 0 0 1 475.068 163.809] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -475.068 -163.809] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+478.425 163.809 Td
+/F130_0 9.9626 Tf
+(will) 15.5018 Tj
+-337 TJm
+(be) 9.40469 Tj
+-337 TJm
+(set) 11.0684 Tj
+-337 TJm
+(to) 7.7509 Tj
+-337 TJm
+(a) 4.42339 Tj
+72 151.853 Td
+(v) 4.9813 Tj
+25 TJm
+(alue) 16.5977 Tj
+-250 TJm
+(between) 33.1954 Tj
+[1 0 0 1 131.506 151.853] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -131.506 -151.853] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+131.506 151.853 Td
+/F134_0 9.9626 Tf
+(0) 5.97756 Tj
+[1 0 0 1 137.484 151.853] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -137.484 -151.853] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+139.975 151.853 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 156.851 151.853] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -156.851 -151.853] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+156.851 151.853 Td
+/F134_0 9.9626 Tf
+(BZ_MAX_UNUSED) 77.7083 Tj
+[1 0 0 1 234.56 151.853] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -234.56 -151.853] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+237.05 151.853 Td
+/F130_0 9.9626 Tf
+(inclusi) 26.5703 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(e.) 6.91404 Tj
+[1 0 0 1 72 150.543] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -140.581] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 129.935 Td
+/F130_0 9.9626 Tf
+(This) 17.7135 Tj
+-882 TJm
+(function) 33.2053 Tj
+-883 TJm
+(may) 17.1556 Tj
+-882 TJm
+(only) 17.7135 Tj
+-883 TJm
+(be) 9.40469 Tj
+-882 TJm
+(called) 23.7907 Tj
+-883 TJm
+(once) 18.8094 Tj
+[1 0 0 1 271.332 129.935] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -271.332 -129.935] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+271.332 129.935 Td
+/F134_0 9.9626 Tf
+(BZ2_bzRead) 59.7756 Tj
+[1 0 0 1 331.108 129.935] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -331.108 -129.935] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+339.9 129.935 Td
+/F130_0 9.9626 Tf
+(has) 13.2801 Tj
+-882 TJm
+(signalled) 35.9749 Tj
+[1 0 0 1 406.737 129.935] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -406.737 -129.935] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+406.737 129.935 Td
+/F134_0 9.9626 Tf
+(BZ_STREAM_END) 77.7083 Tj
+[1 0 0 1 484.446 129.935] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -484.446 -129.935] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+493.231 129.935 Td
+/F130_0 9.9626 Tf
+(b) 4.9813 Tj
+20 TJm
+(ut) 7.7509 Tj
+-882 TJm
+(before) 25.4445 Tj
+[1 0 0 1 72 117.98] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -117.98] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 117.98 Td
+/F134_0 9.9626 Tf
+(BZ2_bzReadClose) 89.6634 Tj
+[1 0 0 1 161.664 117.98] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -161.664 -117.98] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+161.664 117.98 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+[1 0 0 1 72 116.67] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -106.708] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 96.0625 Td
+/F130_0 9.9626 Tf
+(Possible) 33.2153 Tj
+-250 TJm
+(assignments) 48.7072 Tj
+-250 TJm
+(to) 7.7509 Tj
+[1 0 0 1 169.144 96.0625] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -169.144 -96.0625] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+169.144 96.0625 Td
+/F134_0 9.9626 Tf
+(bzerror) 41.8429 Tj
+[1 0 0 1 210.987 96.0625] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -210.987 -96.0625] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+210.987 96.0625 Td
+/F130_0 9.9626 Tf
+(:) 2.7696 Tj
+[1 0 0 1 72 93.9057] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -43.0539] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 374.394 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 40.5726 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -493.841 -50.8518] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+534.414 50.8518 Td
+/F130_0 9.9626 Tf
+(21) 9.9626 Tj
+[1 0 0 1 453.269 50.8518] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 93.5985 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.2765 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+Q
+showpage
+%%PageTrailer
+pdfEndPage
+%%Page: 25 25
+%%BeginPageSetup
+%%PageOrientation: Portrait
+pdfStartPage
+0 0 612 792 re W
+%%EndPageSetup
+[] 0 d
+1 i
+0 j
+0 J
+10 M
+1 w
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+false op
+false OP
+0 0 612 792 re
+W
+q
+[1 0 0 1 72 741.554] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 14.4459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 187.197 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 -8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 76.4979 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -342.569 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+419.067 749.245 Td
+/F130_0 9.9626 Tf
+(Programming) 54.7943 Tj
+-250 TJm
+(with) 17.7135 Tj
+[1 0 0 1 496.556 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -496.556 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+496.556 749.245 Td
+/F134_0 9.9626 Tf
+(libbzip2) 47.8205 Tj
+[1 0 0 1 544.376 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -278.305 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 280.796 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -472.974 -5.0363] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -0.4981] cm
+q
+[] 0 d
+0 J
+0.4981 w
+0 0.2491 m
+475.465 0.2491 l
+S
+Q
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 479.251 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -129.151] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 107.597 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 104.01] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -711.631] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 711.631 Td
+/F134_0 9.9626 Tf
+(BZ_PARAM_ERROR) 83.6858 Tj
+98.4879 699.676 Td
+(if) 11.9551 Tj
+-426 TJm
+(b) 5.97756 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(NULL) 23.9102 Tj
+98.4879 687.721 Td
+(or) 11.9551 Tj
+-426 TJm
+(unused) 35.8654 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(NULL) 23.9102 Tj
+-426 TJm
+(or) 11.9551 Tj
+-426 TJm
+(nUnused) 41.8429 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(NULL) 23.9102 Tj
+90 675.766 Td
+(BZ_SEQUENCE_ERROR) 101.619 Tj
+98.4879 663.811 Td
+(if) 11.9551 Tj
+-426 TJm
+(BZ_STREAM_END) 77.7083 Tj
+-426 TJm
+(has) 17.9327 Tj
+-426 TJm
+(not) 17.9327 Tj
+-426 TJm
+(been) 23.9102 Tj
+-426 TJm
+(signalled) 53.798 Tj
+98.4879 651.856 Td
+(or) 11.9551 Tj
+-426 TJm
+(if) 11.9551 Tj
+-426 TJm
+(b) 5.97756 Tj
+-426 TJm
+(was) 17.9327 Tj
+-426 TJm
+(opened) 35.8654 Tj
+-426 TJm
+(with) 23.9102 Tj
+-426 TJm
+(BZ2_bzWriteOpen) 89.6634 Tj
+90 639.9 Td
+(BZ_OK) 29.8878 Tj
+98.4879 627.945 Td
+(otherwise) 53.798 Tj
+[1 0 0 1 72 612.404] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.5492] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -602.441] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 590.486 Td
+/F130_0 9.9626 Tf
+(Allo) 17.7135 Tj
+25 TJm
+(w) 7.193 Tj
+10 TJm
+(able) 16.5977 Tj
+-250 TJm
+(ne) 9.40469 Tj
+15 TJm
+(xt) 7.7509 Tj
+-250 TJm
+(actions:) 30.9936 Tj
+[1 0 0 1 72 590.386] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -24.9066] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 23.9103 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 20.3238] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -581.021] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 581.021 Td
+/F134_0 9.9626 Tf
+(BZ2_bzReadClose) 89.6634 Tj
+[1 0 0 1 72 565.48] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -555.517] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 534.858 Td
+/F122_0 17.2154 Tf
+(3.4.4.) 43.0729 Tj
+[1 0 0 1 119.858 534.858] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -119.858 -534.858] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+119.858 534.858 Td
+/F392_0 17.2154 Tf
+(BZ2_bzReadClose) 154.939 Tj
+[1 0 0 1 274.797 534.858] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -202.797 -2.3327] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -24.9066] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 23.9103 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 20.3237] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3685] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -523.161] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 523.161 Td
+/F134_0 9.9626 Tf
+(void) 23.9102 Tj
+-426 TJm
+(BZ2_bzReadClose) 89.6634 Tj
+-426 TJm
+(\() 5.97756 Tj
+-426 TJm
+(int) 17.9327 Tj
+244.46 521.417 Td
+(*) 5.97756 Tj
+250.438 523.161 Td
+(bzerror,) 47.8205 Tj
+-426 TJm
+(BZFILE) 35.8654 Tj
+342.612 521.417 Td
+(*) 5.97756 Tj
+348.59 523.161 Td
+(b) 5.97756 Tj
+-426 TJm
+(\);) 11.9551 Tj
+[1 0 0 1 72 507.619] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.5492] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -497.656] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 485.701 Td
+/F130_0 9.9626 Tf
+(Releases) 34.8591 Tj
+-430 TJm
+(all) 9.9626 Tj
+-429 TJm
+(memory) 33.2053 Tj
+-430 TJm
+(pertaining) 40.3983 Tj
+-429 TJm
+(to) 7.7509 Tj
+-430 TJm
+(the) 12.1743 Tj
+-429 TJm
+(compressed) 47.0334 Tj
+-430 TJm
+(\002le) 12.7322 Tj
+[1 0 0 1 304.352 485.701] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -304.352 -485.701] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+304.352 485.701 Td
+/F134_0 9.9626 Tf
+(b) 5.97756 Tj
+[1 0 0 1 310.33 485.701] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -310.33 -485.701] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+310.33 485.701 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+[1 0 0 1 321.276 485.701] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -321.276 -485.701] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+321.276 485.701 Td
+/F134_0 9.9626 Tf
+(BZ2_bzReadClose) 89.6634 Tj
+[1 0 0 1 410.94 485.701] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -410.94 -485.701] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+415.22 485.701 Td
+/F130_0 9.9626 Tf
+(does) 18.2614 Tj
+-430 TJm
+(not) 12.7322 Tj
+-429 TJm
+(call) 14.386 Tj
+[1 0 0 1 473.438 485.701] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -473.438 -485.701] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+473.438 485.701 Td
+/F134_0 9.9626 Tf
+(fclose) 35.8654 Tj
+[1 0 0 1 509.304 485.701] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -509.304 -485.701] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+513.584 485.701 Td
+/F130_0 9.9626 Tf
+(on) 9.9626 Tj
+-430 TJm
+(the) 12.1743 Tj
+72 473.746 Td
+(underlying) 43.1679 Tj
+-264 TJm
+(\002le) 12.7322 Tj
+-264 TJm
+(handle,) 29.0509 Tj
+-267 TJm
+(so) 8.85675 Tj
+-264 TJm
+(you) 14.9439 Tj
+-264 TJm
+(should) 26.5703 Tj
+-264 TJm
+(do) 9.9626 Tj
+-264 TJm
+(that) 14.9439 Tj
+-264 TJm
+(yourself) 32.6474 Tj
+-264 TJm
+(if) 6.08715 Tj
+-263 TJm
+(appropriate.) 47.8603 Tj
+[1 0 0 1 348.653 473.746] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -348.653 -473.746] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+348.653 473.746 Td
+/F134_0 9.9626 Tf
+(BZ2_bzReadClose) 89.6634 Tj
+[1 0 0 1 438.317 473.746] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -438.317 -473.746] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+440.946 473.746 Td
+/F130_0 9.9626 Tf
+(should) 26.5703 Tj
+-264 TJm
+(be) 9.40469 Tj
+-264 TJm
+(called) 23.7907 Tj
+-264 TJm
+(to) 7.7509 Tj
+-264 TJm
+(clean) 21.0211 Tj
+72 461.791 Td
+(up) 9.9626 Tj
+-250 TJm
+(after) 18.2515 Tj
+-250 TJm
+(all) 9.9626 Tj
+-250 TJm
+(error) 19.3573 Tj
+-250 TJm
+(situations.) 40.6873 Tj
+[1 0 0 1 72 459.634] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -449.671] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 439.873 Td
+/F130_0 9.9626 Tf
+(Possible) 33.2153 Tj
+-250 TJm
+(assignments) 48.7072 Tj
+-250 TJm
+(to) 7.7509 Tj
+[1 0 0 1 169.144 439.873] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -169.144 -439.873] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+169.144 439.873 Td
+/F134_0 9.9626 Tf
+(bzerror) 41.8429 Tj
+[1 0 0 1 210.987 439.873] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -210.987 -439.873] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+210.987 439.873 Td
+/F130_0 9.9626 Tf
+(:) 2.7696 Tj
+[1 0 0 1 72 437.716] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -60.7721] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 59.7758 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 56.1893] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -428.351] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 428.351 Td
+/F134_0 9.9626 Tf
+(BZ_SEQUENCE_ERROR) 101.619 Tj
+98.4879 416.396 Td
+(if) 11.9551 Tj
+-426 TJm
+(b) 5.97756 Tj
+-426 TJm
+(was) 17.9327 Tj
+-426 TJm
+(opened) 35.8654 Tj
+-426 TJm
+(with) 23.9102 Tj
+-426 TJm
+(BZ2_bzOpenWrite) 89.6634 Tj
+90 404.441 Td
+(BZ_OK) 29.8878 Tj
+98.4879 392.486 Td
+(otherwise) 53.798 Tj
+[1 0 0 1 72 376.944] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.5492] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -366.982] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 355.026 Td
+/F130_0 9.9626 Tf
+(Allo) 17.7135 Tj
+25 TJm
+(w) 7.193 Tj
+10 TJm
+(able) 16.5977 Tj
+-250 TJm
+(ne) 9.40469 Tj
+15 TJm
+(xt) 7.7509 Tj
+-250 TJm
+(actions:) 30.9936 Tj
+[1 0 0 1 72 354.927] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -24.9066] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 23.9103 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 20.3237] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -345.562] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 345.562 Td
+/F134_0 9.9626 Tf
+(none) 23.9102 Tj
+[1 0 0 1 72 330.02] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -320.058] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 299.399 Td
+/F122_0 17.2154 Tf
+(3.4.5.) 43.0729 Tj
+[1 0 0 1 119.858 299.399] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -119.858 -299.399] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+119.858 299.399 Td
+/F392_0 17.2154 Tf
+(BZ2_bzWriteOpen) 154.939 Tj
+[1 0 0 1 274.797 299.399] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -202.797 -2.3327] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -48.8169] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 47.8207 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 44.2341] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -287.702] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 287.702 Td
+/F134_0 9.9626 Tf
+(BZFILE) 35.8654 Tj
+130.109 285.958 Td
+(*) 5.97756 Tj
+136.087 287.702 Td
+(BZ2_bzWriteOpen\() 95.641 Tj
+-426 TJm
+(int) 17.9327 Tj
+258.149 285.958 Td
+(*) 5.97756 Tj
+264.127 287.702 Td
+(bzerror,) 47.8205 Tj
+-426 TJm
+(FILE) 23.9102 Tj
+344.346 285.958 Td
+(*) 5.97756 Tj
+350.323 287.702 Td
+(f,) 11.9551 Tj
+196.099 275.746 Td
+(int) 17.9327 Tj
+-426 TJm
+(blockSize100k,) 83.6858 Tj
+-426 TJm
+(int) 17.9327 Tj
+-426 TJm
+(verbosity,) 59.7756 Tj
+196.099 263.791 Td
+(int) 17.9327 Tj
+-426 TJm
+(workFactor) 59.7756 Tj
+-426 TJm
+(\);) 11.9551 Tj
+[1 0 0 1 72 248.249] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.5492] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -238.287] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 226.332 Td
+/F130_0 9.9626 Tf
+(Prepare) 30.4258 Tj
+-268 TJm
+(to) 7.7509 Tj
+-269 TJm
+(write) 20.4731 Tj
+-268 TJm
+(compressed) 47.0334 Tj
+-269 TJm
+(data) 16.5977 Tj
+-268 TJm
+(to) 7.7509 Tj
+-269 TJm
+(\002le) 12.7322 Tj
+-268 TJm
+(handle) 26.5603 Tj
+[1 0 0 1 262.72 226.332] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -262.72 -226.332] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+262.72 226.332 Td
+/F134_0 9.9626 Tf
+(f) 5.97756 Tj
+[1 0 0 1 268.698 226.332] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -268.698 -226.332] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+268.698 226.332 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+[1 0 0 1 274.829 226.332] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -274.829 -226.332] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+274.829 226.332 Td
+/F134_0 9.9626 Tf
+(f) 5.97756 Tj
+[1 0 0 1 280.807 226.332] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -280.807 -226.332] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+283.481 226.332 Td
+/F130_0 9.9626 Tf
+(should) 26.5703 Tj
+-268 TJm
+(refer) 18.7994 Tj
+-269 TJm
+(to) 7.7509 Tj
+-268 TJm
+(a) 4.42339 Tj
+-269 TJm
+(\002le) 12.7322 Tj
+-268 TJm
+(which) 24.3486 Tj
+-269 TJm
+(has) 13.2801 Tj
+-268 TJm
+(been) 18.8094 Tj
+-269 TJm
+(opened) 28.772 Tj
+-268 TJm
+(for) 11.6164 Tj
+-269 TJm
+(writing,) 31.2726 Tj
+-273 TJm
+(and) 14.386 Tj
+-268 TJm
+(for) 11.6164 Tj
+72 214.377 Td
+(which) 24.3486 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(error) 19.3573 Tj
+-250 TJm
+(indicator) 35.417 Tj
+-250 TJm
+(\() 3.31755 Tj
+[1 0 0 1 176.577 214.376] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -176.577 -214.376] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+176.577 214.376 Td
+/F134_0 9.9626 Tf
+(ferror\(f\)) 53.798 Tj
+[1 0 0 1 230.375 214.376] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -230.375 -214.376] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+230.375 214.376 Td
+/F130_0 9.9626 Tf
+(\)is) 9.9626 Tj
+-250 TJm
+(not) 12.7322 Tj
+-250 TJm
+(set.) 13.5591 Tj
+[1 0 0 1 72 212.593] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -202.631] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 192.459 Td
+/F130_0 9.9626 Tf
+(F) 5.53921 Tj
+15 TJm
+(or) 8.29885 Tj
+-223 TJm
+(the) 12.1743 Tj
+-224 TJm
+(meaning) 34.3112 Tj
+-223 TJm
+(of) 8.29885 Tj
+-224 TJm
+(parameters) 43.7059 Tj
+[1 0 0 1 195.306 192.459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -195.306 -192.459] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+195.306 192.459 Td
+/F134_0 9.9626 Tf
+(blockSize100k) 77.7083 Tj
+[1 0 0 1 273.015 192.459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -273.015 -192.459] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+273.015 192.459 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 277.784 192.459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -277.784 -192.459] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+277.784 192.459 Td
+/F134_0 9.9626 Tf
+(verbosity) 53.798 Tj
+[1 0 0 1 331.583 192.459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -331.583 -192.459] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+333.808 192.459 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 350.42 192.459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -350.42 -192.459] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+350.42 192.459 Td
+/F134_0 9.9626 Tf
+(workFactor) 59.7756 Tj
+[1 0 0 1 410.196 192.459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -410.196 -192.459] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+410.196 192.459 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-229 TJm
+(see) 12.7222 Tj
+[1 0 0 1 429.913 192.459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -429.913 -192.459] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+429.913 192.459 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompressInit) 107.596 Tj
+[1 0 0 1 537.509 192.459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -537.509 -192.459] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+537.509 192.459 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+[1 0 0 1 72 190.302] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -180.339] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 170.541 Td
+/F130_0 9.9626 Tf
+(All) 12.7322 Tj
+-382 TJm
+(required) 33.1954 Tj
+-382 TJm
+(memory) 33.2053 Tj
+-382 TJm
+(is) 6.64505 Tj
+-382 TJm
+(allocated) 35.965 Tj
+-383 TJm
+(at) 7.193 Tj
+-382 TJm
+(this) 14.396 Tj
+-382 TJm
+(stage,) 22.9638 Tj
+-415 TJm
+(so) 8.85675 Tj
+-382 TJm
+(if) 6.08715 Tj
+-382 TJm
+(the) 12.1743 Tj
+-382 TJm
+(call) 14.386 Tj
+-382 TJm
+(completes) 40.3983 Tj
+-382 TJm
+(successfully) 48.6972 Tj
+65 TJm
+(,) 2.49065 Tj
+[1 0 0 1 424.691 170.541] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -424.691 -170.541] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+424.691 170.541 Td
+/F134_0 9.9626 Tf
+(BZ_MEM_ERROR) 71.7307 Tj
+[1 0 0 1 496.422 170.541] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -496.422 -170.541] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+500.228 170.541 Td
+/F130_0 9.9626 Tf
+(cannot) 26.5603 Tj
+-382 TJm
+(be) 9.40469 Tj
+72 158.586 Td
+(signalled) 35.9749 Tj
+-250 TJm
+(by) 9.9626 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(subsequent) 44.2738 Tj
+-250 TJm
+(call) 14.386 Tj
+-250 TJm
+(to) 7.7509 Tj
+[1 0 0 1 203.715 158.586] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -203.715 -158.586] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+203.715 158.586 Td
+/F134_0 9.9626 Tf
+(BZ2_bzWrite) 65.7532 Tj
+[1 0 0 1 269.468 158.586] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -269.468 -158.586] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+269.468 158.586 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+[1 0 0 1 72 156.429] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -146.466] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 136.668 Td
+/F130_0 9.9626 Tf
+(Possible) 33.2153 Tj
+-250 TJm
+(assignments) 48.7072 Tj
+-250 TJm
+(to) 7.7509 Tj
+[1 0 0 1 169.144 136.668] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -169.144 -136.668] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+169.144 136.668 Td
+/F134_0 9.9626 Tf
+(bzerror) 41.8429 Tj
+[1 0 0 1 210.987 136.668] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -210.987 -136.668] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+210.987 136.668 Td
+/F130_0 9.9626 Tf
+(:) 2.7696 Tj
+[1 0 0 1 72 134.511] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -83.6593] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 374.394 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 40.5726 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -493.841 -50.8518] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+534.414 50.8518 Td
+/F130_0 9.9626 Tf
+(22) 9.9626 Tj
+[1 0 0 1 453.269 50.8518] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 93.5985 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.2765 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+Q
+showpage
+%%PageTrailer
+pdfEndPage
+%%Page: 26 26
+%%BeginPageSetup
+%%PageOrientation: Portrait
+pdfStartPage
+0 0 612 792 re W
+%%EndPageSetup
+[] 0 d
+1 i
+0 j
+0 J
+10 M
+1 w
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+false op
+false OP
+0 0 612 792 re
+W
+q
+[1 0 0 1 72 741.554] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 14.4459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 187.197 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 -8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 76.4979 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -342.569 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+419.067 749.245 Td
+/F130_0 9.9626 Tf
+(Programming) 54.7943 Tj
+-250 TJm
+(with) 17.7135 Tj
+[1 0 0 1 496.556 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -496.556 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+496.556 749.245 Td
+/F134_0 9.9626 Tf
+(libbzip2) 47.8205 Tj
+[1 0 0 1 544.376 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -278.305 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 280.796 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -472.974 -5.0363] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -0.4981] cm
+q
+[] 0 d
+0 J
+0.4981 w
+0 0.2491 m
+475.465 0.2491 l
+S
+Q
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 479.251 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -165.016] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 143.462 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 139.875] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -711.631] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 711.631 Td
+/F134_0 9.9626 Tf
+(BZ_CONFIG_ERROR) 89.6634 Tj
+98.4879 699.676 Td
+(if) 11.9551 Tj
+-426 TJm
+(the) 17.9327 Tj
+-426 TJm
+(library) 41.8429 Tj
+-426 TJm
+(has) 17.9327 Tj
+-426 TJm
+(been) 23.9102 Tj
+-426 TJm
+(mis-compiled) 71.7307 Tj
+90 687.721 Td
+(BZ_PARAM_ERROR) 83.6858 Tj
+98.4879 675.766 Td
+(if) 11.9551 Tj
+-426 TJm
+(f) 5.97756 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(NULL) 23.9102 Tj
+98.4879 663.811 Td
+(or) 11.9551 Tj
+-426 TJm
+(blockSize100k) 77.7083 Tj
+-426 TJm
+(<) 5.97756 Tj
+-426 TJm
+(1) 5.97756 Tj
+-426 TJm
+(or) 11.9551 Tj
+-426 TJm
+(blockSize100k) 77.7083 Tj
+-426 TJm
+(>) 5.97756 Tj
+-426 TJm
+(9) 5.97756 Tj
+90 651.856 Td
+(BZ_IO_ERROR) 65.7532 Tj
+98.4879 639.9 Td
+(if) 11.9551 Tj
+-426 TJm
+(ferror\(f\)) 53.798 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(nonzero) 41.8429 Tj
+90 627.945 Td
+(BZ_MEM_ERROR) 71.7307 Tj
+98.4879 615.99 Td
+(if) 11.9551 Tj
+-426 TJm
+(insufficient) 71.7307 Tj
+-426 TJm
+(memory) 35.8654 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(available) 53.798 Tj
+90 604.035 Td
+(BZ_OK) 29.8878 Tj
+98.4879 592.08 Td
+(otherwise) 53.798 Tj
+[1 0 0 1 72 576.538] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.5492] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -566.575] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 554.62 Td
+/F130_0 9.9626 Tf
+(Possible) 33.2153 Tj
+-250 TJm
+(return) 23.7907 Tj
+-250 TJm
+(v) 4.9813 Tj
+25 TJm
+(alues:) 23.2427 Tj
+[1 0 0 1 72 554.521] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -60.7721] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 59.7758 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 56.1892] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -545.156] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 545.156 Td
+/F134_0 9.9626 Tf
+(Pointer) 41.8429 Tj
+-426 TJm
+(to) 11.9551 Tj
+-426 TJm
+(an) 11.9551 Tj
+-426 TJm
+(abstract) 47.8205 Tj
+-426 TJm
+(BZFILE) 35.8654 Tj
+98.4879 533.201 Td
+(if) 11.9551 Tj
+-426 TJm
+(bzerror) 41.8429 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(BZ_OK) 29.8878 Tj
+90 521.245 Td
+(NULL) 23.9102 Tj
+98.4879 509.29 Td
+(otherwise) 53.798 Tj
+[1 0 0 1 72 493.748] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.5492] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -483.786] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 471.831 Td
+/F130_0 9.9626 Tf
+(Allo) 17.7135 Tj
+25 TJm
+(w) 7.193 Tj
+10 TJm
+(able) 16.5977 Tj
+-250 TJm
+(ne) 9.40469 Tj
+15 TJm
+(xt) 7.7509 Tj
+-250 TJm
+(actions:) 30.9936 Tj
+[1 0 0 1 72 471.731] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -84.6825] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 83.6862 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 80.0996] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -462.366] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 462.366 Td
+/F134_0 9.9626 Tf
+(BZ2_bzWrite) 65.7532 Tj
+98.4879 450.411 Td
+(if) 11.9551 Tj
+-426 TJm
+(bzerror) 41.8429 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(BZ_OK) 29.8878 Tj
+98.4879 438.456 Td
+(\(you) 23.9102 Tj
+-426 TJm
+(could) 29.8878 Tj
+-426 TJm
+(go) 11.9551 Tj
+-426 TJm
+(directly) 47.8205 Tj
+-426 TJm
+(to) 11.9551 Tj
+-426 TJm
+(BZ2_bzWriteClose,) 101.619 Tj
+-426 TJm
+(but) 17.9327 Tj
+-426 TJm
+(this) 23.9102 Tj
+-426 TJm
+(would) 29.8878 Tj
+-426 TJm
+(be) 11.9551 Tj
+-426 TJm
+(pretty) 35.8654 Tj
+485.505 434.212 Td
+/F564_0 9.9626 Tf
+( ) 9.9626 Tj
+493.808 434.212 Td
+/F147_0 9.9626 Tf
+(-) 2.7696 Tj
+90 426.501 Td
+/F134_0 9.9626 Tf
+(pointless\)) 59.7756 Tj
+90 414.546 Td
+(BZ2_bzWriteClose) 95.641 Tj
+98.4879 402.59 Td
+(otherwise) 53.798 Tj
+[1 0 0 1 72 387.049] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -377.086] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 356.428 Td
+/F122_0 17.2154 Tf
+(3.4.6.) 43.0729 Tj
+[1 0 0 1 119.858 356.428] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -119.858 -356.428] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+119.858 356.428 Td
+/F392_0 17.2154 Tf
+(BZ2_bzWrite) 113.622 Tj
+[1 0 0 1 233.48 356.428] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -161.48 -2.3327] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -24.9066] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 23.9103 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 20.3237] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3685] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -344.73] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 344.73 Td
+/F134_0 9.9626 Tf
+(void) 23.9102 Tj
+-426 TJm
+(BZ2_bzWrite) 65.7532 Tj
+-426 TJm
+(\() 5.97756 Tj
+-426 TJm
+(int) 17.9327 Tj
+220.55 342.987 Td
+(*) 5.97756 Tj
+226.528 344.73 Td
+(bzerror,) 47.8205 Tj
+-426 TJm
+(BZFILE) 35.8654 Tj
+318.702 342.987 Td
+(*) 5.97756 Tj
+324.679 344.73 Td
+(b,) 11.9551 Tj
+-426 TJm
+(void) 23.9102 Tj
+369.033 342.987 Td
+(*) 5.97756 Tj
+375.01 344.73 Td
+(buf,) 23.9102 Tj
+-426 TJm
+(int) 17.9327 Tj
+-426 TJm
+(len) 17.9327 Tj
+-426 TJm
+(\);) 11.9551 Tj
+[1 0 0 1 72 329.188] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.5492] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -319.226] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 307.27 Td
+/F130_0 9.9626 Tf
+(Absorbs) 33.2053 Tj
+[1 0 0 1 107.696 307.27] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -107.696 -307.27] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+107.696 307.27 Td
+/F134_0 9.9626 Tf
+(len) 17.9327 Tj
+[1 0 0 1 125.629 307.27] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -125.629 -307.27] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+128.119 307.27 Td
+/F130_0 9.9626 Tf
+(bytes) 21.031 Tj
+-250 TJm
+(from) 19.3673 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(b) 4.9813 Tj
+20 TJm
+(uf) 8.29885 Tj
+25 TJm
+(fer) 11.0585 Tj
+[1 0 0 1 214.544 307.27] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -214.544 -307.27] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+214.544 307.27 Td
+/F134_0 9.9626 Tf
+(buf) 17.9327 Tj
+[1 0 0 1 232.477 307.27] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -232.477 -307.27] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+232.477 307.27 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-250 TJm
+(e) 4.42339 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(entually) 32.0995 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(be) 9.40469 Tj
+-250 TJm
+(compressed) 47.0334 Tj
+-250 TJm
+(and) 14.386 Tj
+-250 TJm
+(written) 28.224 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(\002le.) 15.2229 Tj
+[1 0 0 1 72 305.114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -295.151] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 285.353 Td
+/F130_0 9.9626 Tf
+(Possible) 33.2153 Tj
+-250 TJm
+(assignments) 48.7072 Tj
+-250 TJm
+(to) 7.7509 Tj
+[1 0 0 1 169.144 285.353] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -169.144 -285.353] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+169.144 285.353 Td
+/F134_0 9.9626 Tf
+(bzerror) 41.8429 Tj
+[1 0 0 1 210.987 285.353] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -210.987 -285.353] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+210.987 285.353 Td
+/F130_0 9.9626 Tf
+(:) 2.7696 Tj
+[1 0 0 1 72 283.196] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -108.593] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 107.597 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 104.01] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -273.831] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 273.831 Td
+/F134_0 9.9626 Tf
+(BZ_PARAM_ERROR) 83.6858 Tj
+98.4879 261.876 Td
+(if) 11.9551 Tj
+-426 TJm
+(b) 5.97756 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(NULL) 23.9102 Tj
+-426 TJm
+(or) 11.9551 Tj
+-426 TJm
+(buf) 17.9327 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(NULL) 23.9102 Tj
+-426 TJm
+(or) 11.9551 Tj
+-426 TJm
+(len) 17.9327 Tj
+-426 TJm
+(<) 5.97756 Tj
+-426 TJm
+(0) 5.97756 Tj
+90 249.921 Td
+(BZ_SEQUENCE_ERROR) 101.619 Tj
+98.4879 237.965 Td
+(if) 11.9551 Tj
+-426 TJm
+(b) 5.97756 Tj
+-426 TJm
+(was) 17.9327 Tj
+-426 TJm
+(opened) 35.8654 Tj
+-426 TJm
+(with) 23.9102 Tj
+-426 TJm
+(BZ2_bzReadOpen) 83.6858 Tj
+90 226.01 Td
+(BZ_IO_ERROR) 65.7532 Tj
+98.4879 214.055 Td
+(if) 11.9551 Tj
+-426 TJm
+(there) 29.8878 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(an) 11.9551 Tj
+-426 TJm
+(error) 29.8878 Tj
+-426 TJm
+(writing) 41.8429 Tj
+-426 TJm
+(the) 17.9327 Tj
+-426 TJm
+(compressed) 59.7756 Tj
+-426 TJm
+(file.) 29.8878 Tj
+90 202.1 Td
+(BZ_OK) 29.8878 Tj
+98.4879 190.145 Td
+(otherwise) 53.798 Tj
+[1 0 0 1 72 174.603] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -164.64] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 143.982 Td
+/F122_0 17.2154 Tf
+(3.4.7.) 43.0729 Tj
+[1 0 0 1 119.858 143.982] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -119.858 -143.982] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+119.858 143.982 Td
+/F392_0 17.2154 Tf
+(BZ2_bzWriteClose) 165.268 Tj
+[1 0 0 1 285.126 143.982] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -213.126 -2.3326] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -90.7975] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 374.394 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 6.8541] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 40.5726 -6.7545] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -493.841 -50.9514] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+534.414 50.9514 Td
+/F130_0 9.9626 Tf
+(23) 9.9626 Tj
+[1 0 0 1 453.269 50.8518] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 93.5985 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.2765 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+Q
+showpage
+%%PageTrailer
+pdfEndPage
+%%Page: 27 27
+%%BeginPageSetup
+%%PageOrientation: Portrait
+pdfStartPage
+0 0 612 792 re W
+%%EndPageSetup
+[] 0 d
+1 i
+0 j
+0 J
+10 M
+1 w
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+false op
+false OP
+0 0 612 792 re
+W
+q
+[1 0 0 1 72 741.554] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 14.4459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 187.197 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 -8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 76.4979 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -342.569 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+419.067 749.245 Td
+/F130_0 9.9626 Tf
+(Programming) 54.7943 Tj
+-250 TJm
+(with) 17.7135 Tj
+[1 0 0 1 496.556 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -496.556 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+496.556 749.245 Td
+/F134_0 9.9626 Tf
+(libbzip2) 47.8205 Tj
+[1 0 0 1 544.376 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -278.305 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 280.796 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -472.974 -5.0363] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -0.4981] cm
+q
+[] 0 d
+0 J
+0.4981 w
+0 0.2491 m
+475.465 0.2491 l
+S
+Q
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 479.251 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -165.016] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 143.462 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 139.875] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -711.631] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 711.631 Td
+/F134_0 9.9626 Tf
+(void) 23.9102 Tj
+-426 TJm
+(BZ2_bzWriteClose\() 101.619 Tj
+-426 TJm
+(int) 17.9327 Tj
+246.194 709.888 Td
+(*) 5.97756 Tj
+252.171 711.631 Td
+(bzerror,) 47.8205 Tj
+-426 TJm
+(BZFILE) 35.8654 Tj
+340.102 709.888 Td
+(*) 5.97756 Tj
+350.323 711.631 Td
+(f,) 11.9551 Tj
+187.611 699.676 Td
+(int) 17.9327 Tj
+-426 TJm
+(abandon,) 47.8205 Tj
+187.611 687.721 Td
+(unsigned) 47.8205 Tj
+-426 TJm
+(int) 17.9327 Tj
+257.609 685.978 Td
+(*) 5.97756 Tj
+267.83 687.721 Td
+(nbytes_in,) 59.7756 Tj
+187.611 675.766 Td
+(unsigned) 47.8205 Tj
+-426 TJm
+(int) 17.9327 Tj
+257.609 674.023 Td
+(*) 5.97756 Tj
+267.83 675.766 Td
+(nbytes_out) 59.7756 Tj
+-426 TJm
+(\);) 11.9551 Tj
+90 651.856 Td
+(void) 23.9102 Tj
+-426 TJm
+(BZ2_bzWriteClose64\() 113.574 Tj
+-426 TJm
+(int) 17.9327 Tj
+258.149 650.112 Td
+(*) 5.97756 Tj
+264.127 651.856 Td
+(bzerror,) 47.8205 Tj
+-426 TJm
+(BZFILE) 35.8654 Tj
+352.057 650.112 Td
+(*) 5.97756 Tj
+362.278 651.856 Td
+(f,) 11.9551 Tj
+196.099 639.9 Td
+(int) 17.9327 Tj
+-426 TJm
+(abandon,) 47.8205 Tj
+196.099 627.945 Td
+(unsigned) 47.8205 Tj
+-426 TJm
+(int) 17.9327 Tj
+266.097 626.202 Td
+(*) 5.97756 Tj
+276.318 627.945 Td
+(nbytes_in_lo32,) 89.6634 Tj
+196.099 615.99 Td
+(unsigned) 47.8205 Tj
+-426 TJm
+(int) 17.9327 Tj
+266.097 614.247 Td
+(*) 5.97756 Tj
+276.318 615.99 Td
+(nbytes_in_hi32,) 89.6634 Tj
+196.099 604.035 Td
+(unsigned) 47.8205 Tj
+-426 TJm
+(int) 17.9327 Tj
+266.097 602.292 Td
+(*) 5.97756 Tj
+276.318 604.035 Td
+(nbytes_out_lo32,) 95.641 Tj
+196.099 592.08 Td
+(unsigned) 47.8205 Tj
+-426 TJm
+(int) 17.9327 Tj
+266.097 590.336 Td
+(*) 5.97756 Tj
+276.318 592.08 Td
+(nbytes_out_hi32) 89.6634 Tj
+-426 TJm
+(\);) 11.9551 Tj
+[1 0 0 1 72 576.538] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.5492] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -566.575] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 554.62 Td
+/F130_0 9.9626 Tf
+(Compresses) 48.1492 Tj
+-403 TJm
+(and) 14.386 Tj
+-402 TJm
+(\003ushes) 27.6761 Tj
+-403 TJm
+(to) 7.7509 Tj
+-403 TJm
+(the) 12.1743 Tj
+-402 TJm
+(compressed) 47.0334 Tj
+-403 TJm
+(\002le) 12.7322 Tj
+-403 TJm
+(a) 4.42339 Tj
+1 TJm
+(ll) 5.53921 Tj
+-403 TJm
+(data) 16.5977 Tj
+-403 TJm
+(so) 8.85675 Tj
+-402 TJm
+(f) 3.31755 Tj
+10 TJm
+(ar) 7.74094 Tj
+-403 TJm
+(supplied) 33.7633 Tj
+-403 TJm
+(by) 9.9626 Tj
+[1 0 0 1 384.152 554.62] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -384.152 -554.62] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+384.152 554.62 Td
+/F134_0 9.9626 Tf
+(BZ2_bzWrite) 65.7532 Tj
+[1 0 0 1 449.906 554.62] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -449.906 -554.62] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+449.906 554.62 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+-768 TJm
+(The) 15.4918 Tj
+-403 TJm
+(logical) 27.1182 Tj
+-402 TJm
+(end-of-) 29.3199 Tj
+72 542.665 Td
+(stream) 26.5603 Tj
+-352 TJm
+(mark) 20.4731 Tj
+10 TJm
+(ers) 11.6164 Tj
+-352 TJm
+(are) 12.1643 Tj
+-353 TJm
+(also) 16.0497 Tj
+-352 TJm
+(written,) 30.7147 Tj
+-378 TJm
+(so) 8.85675 Tj
+-352 TJm
+(subsequent) 44.2738 Tj
+-352 TJm
+(calls) 18.2614 Tj
+-352 TJm
+(to) 7.7509 Tj
+[1 0 0 1 300.456 542.665] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -300.456 -542.665] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+300.456 542.665 Td
+/F134_0 9.9626 Tf
+(BZ2_bzWrite) 65.7532 Tj
+[1 0 0 1 366.209 542.665] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -366.209 -542.665] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+369.718 542.665 Td
+/F130_0 9.9626 Tf
+(are) 12.1643 Tj
+-352 TJm
+(ille) 12.7322 Tj
+15 TJm
+(g) 4.9813 Tj
+5 TJm
+(al.) 9.68365 Tj
+-1234 TJm
+(All) 12.7322 Tj
+-352 TJm
+(memory) 33.2053 Tj
+-352 TJm
+(associated) 40.9463 Tj
+-352 TJm
+(with) 17.7135 Tj
+72 530.71 Td
+(the) 12.1743 Tj
+-250 TJm
+(compressed) 47.0334 Tj
+-250 TJm
+(\002le) 12.7322 Tj
+[1 0 0 1 151.411 530.71] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -151.411 -530.71] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+151.411 530.71 Td
+/F134_0 9.9626 Tf
+(b) 5.97756 Tj
+[1 0 0 1 157.389 530.71] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -157.389 -530.71] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+159.879 530.71 Td
+/F130_0 9.9626 Tf
+(is) 6.64505 Tj
+-250 TJm
+(released.) 35.1281 Tj
+[1 0 0 1 207.231 530.71] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -207.231 -530.71] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+207.231 530.71 Td
+/F134_0 9.9626 Tf
+(fflush) 35.8654 Tj
+[1 0 0 1 243.097 530.71] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -243.097 -530.71] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+245.587 530.71 Td
+/F130_0 9.9626 Tf
+(is) 6.64505 Tj
+-250 TJm
+(called) 23.7907 Tj
+-250 TJm
+(on) 9.9626 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(compressed) 47.0334 Tj
+-250 TJm
+(\002le,) 15.2229 Tj
+-250 TJm
+(b) 4.9813 Tj
+20 TJm
+(ut) 7.7509 Tj
+-250 TJm
+(it) 5.53921 Tj
+-250 TJm
+(is) 6.64505 Tj
+-250 TJm
+(not) 12.7322 Tj
+[1 0 0 1 422.771 530.71] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -422.771 -530.71] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+422.771 530.71 Td
+/F134_0 9.9626 Tf
+(fclose) 35.8654 Tj
+[1 0 0 1 458.636 530.71] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -458.636 -530.71] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+458.636 530.71 Td
+/F130_0 9.9626 Tf
+(') 3.31755 Tj
+50 TJm
+(d.) 7.47195 Tj
+[1 0 0 1 72 528.553] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -518.59] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 508.792 Td
+/F130_0 9.9626 Tf
+(If) 6.63509 Tj
+[1 0 0 1 81.5743 508.792] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -81.5743 -508.792] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+81.5743 508.792 Td
+/F134_0 9.9626 Tf
+(BZ2_bzWriteClose) 95.641 Tj
+[1 0 0 1 177.216 508.792] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -177.216 -508.792] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+180.155 508.792 Td
+/F130_0 9.9626 Tf
+(is) 6.64505 Tj
+-295 TJm
+(called) 23.7907 Tj
+-295 TJm
+(to) 7.7509 Tj
+-295 TJm
+(clean) 21.0211 Tj
+-295 TJm
+(up) 9.9626 Tj
+-295 TJm
+(after) 18.2515 Tj
+-295 TJm
+(an) 9.40469 Tj
+-295 TJm
+(error) 19.3573 Tj
+40 TJm
+(,) 2.49065 Tj
+-306 TJm
+(the) 12.1743 Tj
+-295 TJm
+(only) 17.7135 Tj
+-295 TJm
+(action) 24.3486 Tj
+-295 TJm
+(is) 6.64505 Tj
+-295 TJm
+(to) 7.7509 Tj
+-295 TJm
+(release) 27.6562 Tj
+-295 TJm
+(the) 12.1743 Tj
+-295 TJm
+(memory) 33.2053 Tj
+65 TJm
+(.) 2.49065 Tj
+-891 TJm
+(The) 15.4918 Tj
+-295 TJm
+(library) 26.5603 Tj
+72 496.837 Td
+(records) 29.3199 Tj
+-289 TJm
+(the) 12.1743 Tj
+-289 TJm
+(error) 19.3573 Tj
+-289 TJm
+(codes) 22.6848 Tj
+-289 TJm
+(issued) 24.9065 Tj
+-289 TJm
+(by) 9.9626 Tj
+-289 TJm
+(pre) 12.7222 Tj
+25 TJm
+(vious) 21.589 Tj
+-289 TJm
+(calls,) 20.7521 Tj
+-299 TJm
+(so) 8.85675 Tj
+-289 TJm
+(this) 14.396 Tj
+-289 TJm
+(situation) 34.3212 Tj
+-289 TJm
+(will) 15.5018 Tj
+-289 TJm
+(be) 9.40469 Tj
+-289 TJm
+(detected) 33.1954 Tj
+-289 TJm
+(automatically) 54.2364 Tj
+65 TJm
+(.) 2.49065 Tj
+-427 TJm
+(There) 23.2328 Tj
+-289 TJm
+(is) 6.64505 Tj
+-289 TJm
+(no) 9.9626 Tj
+-289 TJm
+(attempt) 29.8878 Tj
+72 484.882 Td
+(to) 7.7509 Tj
+-263 TJm
+(complete) 36.5229 Tj
+-262 TJm
+(the) 12.1743 Tj
+-263 TJm
+(compression) 50.3609 Tj
+-263 TJm
+(operation,) 40.1194 Tj
+-265 TJm
+(nor) 13.2801 Tj
+-263 TJm
+(to) 7.7509 Tj
+[1 0 0 1 258.308 484.882] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -258.308 -484.882] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+258.308 484.882 Td
+/F134_0 9.9626 Tf
+(fflush) 35.8654 Tj
+[1 0 0 1 294.173 484.882] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -294.173 -484.882] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+296.79 484.882 Td
+/F130_0 9.9626 Tf
+(the) 12.1743 Tj
+-263 TJm
+(compressed) 47.0334 Tj
+-262 TJm
+(\002le.) 15.2229 Tj
+-696 TJm
+(Y) 7.193 Tj
+110 TJm
+(ou) 9.9626 Tj
+-263 TJm
+(can) 13.8281 Tj
+-263 TJm
+(force) 20.4632 Tj
+-262 TJm
+(this) 14.396 Tj
+-263 TJm
+(beha) 18.8094 Tj
+20 TJm
+(viour) 21.031 Tj
+-263 TJm
+(to) 7.7509 Tj
+-262 TJm
+(happen) 28.772 Tj
+72 472.926 Td
+(e) 4.42339 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(en) 9.40469 Tj
+-250 TJm
+(in) 7.7509 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(case) 17.1456 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(no) 9.9626 Tj
+-250 TJm
+(error) 19.3573 Tj
+40 TJm
+(,) 2.49065 Tj
+-250 TJm
+(by) 9.9626 Tj
+-250 TJm
+(passing) 29.8878 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(nonzero) 32.0895 Tj
+-250 TJm
+(v) 4.9813 Tj
+25 TJm
+(alue) 16.5977 Tj
+-250 TJm
+(to) 7.7509 Tj
+[1 0 0 1 305.014 472.926] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -305.014 -472.926] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+305.014 472.926 Td
+/F134_0 9.9626 Tf
+(abandon) 41.8429 Tj
+[1 0 0 1 346.858 472.926] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -346.858 -472.926] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+346.858 472.926 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+[1 0 0 1 72 470.77] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -460.807] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 451.009 Td
+/F130_0 9.9626 Tf
+(If) 6.63509 Tj
+[1 0 0 1 80.5974 451.009] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -80.5974 -451.009] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+80.5974 451.009 Td
+/F134_0 9.9626 Tf
+(nbytes_in) 53.798 Tj
+[1 0 0 1 134.396 451.009] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -134.396 -451.009] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+136.358 451.009 Td
+/F130_0 9.9626 Tf
+(is) 6.64505 Tj
+-197 TJm
+(non-null,) 36.2539 Tj
+[1 0 0 1 183.287 451.009] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -183.287 -451.009] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+183.287 449.265 Td
+/F134_0 9.9626 Tf
+(*) 5.97756 Tj
+189.265 451.009 Td
+(nbytes_in) 53.798 Tj
+[1 0 0 1 243.063 451.009] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -243.063 -451.009] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+245.025 451.009 Td
+/F130_0 9.9626 Tf
+(will) 15.5018 Tj
+-197 TJm
+(be) 9.40469 Tj
+-197 TJm
+(set) 11.0684 Tj
+-197 TJm
+(to) 7.7509 Tj
+-197 TJm
+(be) 9.40469 Tj
+-197 TJm
+(the) 12.1743 Tj
+-197 TJm
+(total) 17.7135 Tj
+-197 TJm
+(v) 4.9813 Tj
+20 TJm
+(olume) 24.9065 Tj
+-197 TJm
+(of) 8.29885 Tj
+-197 TJm
+(uncompressed) 56.996 Tj
+-197 TJm
+(data) 16.5977 Tj
+-197 TJm
+(handled.) 34.0322 Tj
+-584 TJm
+(Similarly) 37.0908 Tj
+65 TJm
+(,) 2.49065 Tj
+[1 0 0 1 72 439.053] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -439.053] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 439.053 Td
+/F134_0 9.9626 Tf
+(nbytes_out) 59.7756 Tj
+[1 0 0 1 131.776 439.053] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -131.776 -439.053] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+134.716 439.053 Td
+/F130_0 9.9626 Tf
+(will) 15.5018 Tj
+-295 TJm
+(be) 9.40469 Tj
+-295 TJm
+(set) 11.0684 Tj
+-295 TJm
+(to) 7.7509 Tj
+-295 TJm
+(the) 12.1743 Tj
+-295 TJm
+(total) 17.7135 Tj
+-295 TJm
+(v) 4.9813 Tj
+20 TJm
+(olume) 24.9065 Tj
+-296 TJm
+(of) 8.29885 Tj
+-295 TJm
+(compressed) 47.0334 Tj
+-295 TJm
+(data) 16.5977 Tj
+-295 TJm
+(written.) 30.7147 Tj
+-890 TJm
+(F) 5.53921 Tj
+15 TJm
+(or) 8.29885 Tj
+-295 TJm
+(compatibility) 53.1405 Tj
+-295 TJm
+(with) 17.7135 Tj
+-295 TJm
+(older) 20.4731 Tj
+-296 TJm
+(v) 4.9813 Tj
+15 TJm
+(ersions) 28.224 Tj
+-295 TJm
+(of) 8.29885 Tj
+72 427.098 Td
+(the) 12.1743 Tj
+-283 TJm
+(library) 26.5603 Tj
+65 TJm
+(,) 2.49065 Tj
+[1 0 0 1 118.294 427.098] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -118.294 -427.098] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+118.294 427.098 Td
+/F134_0 9.9626 Tf
+(BZ2_bzWriteClose) 95.641 Tj
+[1 0 0 1 213.936 427.098] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -213.936 -427.098] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+216.753 427.098 Td
+/F130_0 9.9626 Tf
+(only) 17.7135 Tj
+-283 TJm
+(yields) 23.8007 Tj
+-283 TJm
+(the) 12.1743 Tj
+-282 TJm
+(lo) 7.7509 Tj
+25 TJm
+(wer) 14.9339 Tj
+-283 TJm
+(32) 9.9626 Tj
+-283 TJm
+(bits) 14.396 Tj
+-283 TJm
+(of) 8.29885 Tj
+-283 TJm
+(these) 20.4731 Tj
+-282 TJm
+(counts.) 28.503 Tj
+-817 TJm
+(Use) 15.4918 Tj
+[1 0 0 1 423.499 427.098] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -423.499 -427.098] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+423.499 427.098 Td
+/F134_0 9.9626 Tf
+(BZ2_bzWriteClose64) 107.596 Tj
+[1 0 0 1 531.095 427.098] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -531.095 -427.098] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+533.913 427.098 Td
+/F130_0 9.9626 Tf
+(if) 6.08715 Tj
+72 415.143 Td
+(you) 14.9439 Tj
+-250 TJm
+(w) 7.193 Tj
+10 TJm
+(ant) 12.1743 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(full) 13.8381 Tj
+-250 TJm
+(64) 9.9626 Tj
+-250 TJm
+(bit) 10.5205 Tj
+-250 TJm
+(counts.) 28.503 Tj
+-620 TJm
+(These) 23.7907 Tj
+-250 TJm
+(tw) 9.9626 Tj
+10 TJm
+(o) 4.9813 Tj
+-250 TJm
+(functions) 37.0808 Tj
+-250 TJm
+(are) 12.1643 Tj
+-250 TJm
+(otherwise) 38.7346 Tj
+-250 TJm
+(absolutely) 40.9562 Tj
+-250 TJm
+(identical.) 36.8018 Tj
+[1 0 0 1 72 412.986] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -403.024] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 393.225 Td
+/F130_0 9.9626 Tf
+(Possible) 33.2153 Tj
+-250 TJm
+(assignments) 48.7072 Tj
+-250 TJm
+(to) 7.7509 Tj
+[1 0 0 1 169.144 393.225] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -169.144 -393.225] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+169.144 393.225 Td
+/F134_0 9.9626 Tf
+(bzerror) 41.8429 Tj
+[1 0 0 1 210.987 393.225] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -210.987 -393.225] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+210.987 393.225 Td
+/F130_0 9.9626 Tf
+(:) 2.7696 Tj
+[1 0 0 1 72 391.069] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -84.6825] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 83.6862 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 80.0996] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -381.704] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 381.704 Td
+/F134_0 9.9626 Tf
+(BZ_SEQUENCE_ERROR) 101.619 Tj
+98.4879 369.748 Td
+(if) 11.9551 Tj
+-426 TJm
+(b) 5.97756 Tj
+-426 TJm
+(was) 17.9327 Tj
+-426 TJm
+(opened) 35.8654 Tj
+-426 TJm
+(with) 23.9102 Tj
+-426 TJm
+(BZ2_bzReadOpen) 83.6858 Tj
+90 357.793 Td
+(BZ_IO_ERROR) 65.7532 Tj
+98.4879 345.838 Td
+(if) 11.9551 Tj
+-426 TJm
+(there) 29.8878 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(an) 11.9551 Tj
+-426 TJm
+(error) 29.8878 Tj
+-426 TJm
+(writing) 41.8429 Tj
+-426 TJm
+(the) 17.9327 Tj
+-426 TJm
+(compressed) 59.7756 Tj
+-426 TJm
+(file) 23.9102 Tj
+90 333.883 Td
+(BZ_OK) 29.8878 Tj
+98.4879 321.928 Td
+(otherwise) 53.798 Tj
+[1 0 0 1 72 306.386] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -296.423] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 275.765 Td
+/F122_0 17.2154 Tf
+(3.4.8.) 43.0729 Tj
+-278 TJm
+(Handling) 73.6475 Tj
+-278 TJm
+(embed) 55.4852 Tj
+10 TJm
+(ded) 30.609 Tj
+-278 TJm
+(compressed) 101.416 Tj
+-278 TJm
+(data) 35.3949 Tj
+-278 TJm
+(streams) 66.0211 Tj
+[1 0 0 1 72 271.935] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -261.972] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 253.847 Td
+/F130_0 9.9626 Tf
+(The) 15.4918 Tj
+-203 TJm
+(high-le) 28.224 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(el) 7.193 Tj
+-203 TJm
+(library) 26.5603 Tj
+-203 TJm
+(f) 3.31755 Tj
+10 TJm
+(acilitates) 35.417 Tj
+-203 TJm
+(use) 13.2801 Tj
+-203 TJm
+(of) 8.29885 Tj
+[1 0 0 1 226.404 253.847] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -226.404 -253.847] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+226.404 253.847 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 256.292 253.847] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -256.292 -253.847] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+258.316 253.847 Td
+/F130_0 9.9626 Tf
+(data) 16.5977 Tj
+-203 TJm
+(streams) 30.4357 Tj
+-203 TJm
+(which) 24.3486 Tj
+-203 TJm
+(form) 19.3673 Tj
+-203 TJm
+(some) 21.031 Tj
+-203 TJm
+(part) 15.4918 Tj
+-203 TJm
+(of) 8.29885 Tj
+-204 TJm
+(a) 4.42339 Tj
+-203 TJm
+(surrounding,) 50.6399 Tj
+-212 TJm
+(lar) 10.5105 Tj
+18 TJm
+(ger) 12.7222 Tj
+-203 TJm
+(data) 16.5977 Tj
+-203 TJm
+(stream.) 29.0509 Tj
+[1 0 0 1 72 251.69] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -29.7236] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.9739 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -78.9739 -221.967] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+78.9739 221.967 Td
+/F130_0 9.9626 Tf
+(\225) 3.48691 Tj
+[1 0 0 1 82.4608 221.967] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 1.9925 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -86.944 -221.967] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 221.967 Td
+/F130_0 9.9626 Tf
+(F) 5.53921 Tj
+15 TJm
+(or) 8.29885 Tj
+-240 TJm
+(writing,) 31.2726 Tj
+-243 TJm
+(the) 12.1743 Tj
+-240 TJm
+(library) 26.5603 Tj
+-241 TJm
+(tak) 12.1743 Tj
+10 TJm
+(es) 8.29885 Tj
+-240 TJm
+(an) 9.40469 Tj
+-241 TJm
+(open) 19.3673 Tj
+-240 TJm
+(\002le) 12.7322 Tj
+-241 TJm
+(handle,) 29.0509 Tj
+-242 TJm
+(writes) 24.3486 Tj
+-241 TJm
+(compres) 33.7533 Tj
+1 TJm
+(sed) 13.2801 Tj
+-241 TJm
+(data) 16.5977 Tj
+-240 TJm
+(to) 7.7509 Tj
+-241 TJm
+(it,) 8.02986 Tj
+[1 0 0 1 398.926 221.967] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -398.926 -221.967] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+398.926 221.967 Td
+/F134_0 9.9626 Tf
+(fflush) 35.8654 Tj
+[1 0 0 1 434.791 221.967] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -434.791 -221.967] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+434.791 221.967 Td
+/F130_0 9.9626 Tf
+(es) 8.29885 Tj
+-240 TJm
+(it) 5.53921 Tj
+-241 TJm
+(b) 4.9813 Tj
+20 TJm
+(ut) 7.7509 Tj
+-240 TJm
+(does) 18.2614 Tj
+-241 TJm
+(not) 12.7322 Tj
+[1 0 0 1 504.135 221.967] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -504.135 -221.967] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+504.135 221.967 Td
+/F134_0 9.9626 Tf
+(fclose) 35.8654 Tj
+[1 0 0 1 540 221.967] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -540 -221.967] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 210.011 Td
+/F130_0 9.9626 Tf
+(it.) 8.02986 Tj
+-610 TJm
+(The) 15.4918 Tj
+-235 TJm
+(calling) 27.1182 Tj
+-235 TJm
+(application) 44.2738 Tj
+-235 TJm
+(can) 13.8281 Tj
+-235 TJm
+(write) 20.4731 Tj
+-235 TJm
+(its) 9.41466 Tj
+-235 TJm
+(o) 4.9813 Tj
+25 TJm
+(wn) 12.1743 Tj
+-235 TJm
+(data) 16.5977 Tj
+-235 TJm
+(before) 25.4445 Tj
+-235 TJm
+(and) 14.386 Tj
+-235 TJm
+(after) 18.2515 Tj
+-235 TJm
+(the) 12.1743 Tj
+-235 TJm
+(compressed) 47.0334 Tj
+-235 TJm
+(data) 16.5977 Tj
+-235 TJm
+(stream,) 29.0509 Tj
+-238 TJm
+(using) 21.589 Tj
+-235 TJm
+(that) 14.9439 Tj
+-235 TJm
+(same) 20.4731 Tj
+-235 TJm
+(\002le) 12.7322 Tj
+86.944 198.056 Td
+(handle.) 29.0509 Tj
+[1 0 0 1 115.995 198.056] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -43.9948 -21.9178] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.9739 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -78.9739 -176.139] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+78.9739 176.139 Td
+/F130_0 9.9626 Tf
+(\225) 3.48691 Tj
+[1 0 0 1 82.4608 176.139] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 1.9925 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -86.944 -176.139] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 176.139 Td
+/F130_0 9.9626 Tf
+(Reading) 33.2053 Tj
+-236 TJm
+(is) 6.64505 Tj
+-236 TJm
+(more) 20.4731 Tj
+-236 TJm
+(comple) 29.3299 Tj
+15 TJm
+(x,) 7.47195 Tj
+-238 TJm
+(and) 14.386 Tj
+-236 TJm
+(the) 12.1743 Tj
+-236 TJm
+(f) 3.31755 Tj
+10 TJm
+(acilities) 30.9936 Tj
+-236 TJm
+(are) 12.1643 Tj
+-236 TJm
+(not) 12.7322 Tj
+-235 TJm
+(as) 8.29885 Tj
+-236 TJm
+(general) 29.3199 Tj
+-236 TJm
+(as) 8.29885 Tj
+-236 TJm
+(the) 12.1743 Tj
+15 TJm
+(y) 4.9813 Tj
+-236 TJm
+(could) 22.1369 Tj
+-236 TJm
+(be) 9.40469 Tj
+-236 TJm
+(since) 20.4731 Tj
+-235 TJm
+(generality) 39.8404 Tj
+-236 TJm
+(is) 6.64505 Tj
+-236 TJm
+(hard) 17.7035 Tj
+-236 TJm
+(to) 7.7509 Tj
+-236 TJm
+(reconcile) 36.5129 Tj
+86.944 164.183 Td
+(with) 17.7135 Tj
+-404 TJm
+(ef) 7.74094 Tj
+25 TJm
+(\002cienc) 26.5603 Tj
+15 TJm
+(y) 4.9813 Tj
+65 TJm
+(.) 2.49065 Tj
+[1 0 0 1 164.811 164.183] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -164.811 -164.183] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+164.811 164.183 Td
+/F134_0 9.9626 Tf
+(BZ2_bzRead) 59.7756 Tj
+[1 0 0 1 224.587 164.183] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -224.587 -164.183] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+228.614 164.183 Td
+/F130_0 9.9626 Tf
+(reads) 21.0211 Tj
+-404 TJm
+(from) 19.3673 Tj
+-405 TJm
+(the) 12.1743 Tj
+-404 TJm
+(compressed) 47.0334 Tj
+-404 TJm
+(\002le) 12.7322 Tj
+-404 TJm
+(in) 7.7509 Tj
+-405 TJm
+(blocks) 26.0123 Tj
+-404 TJm
+(of) 8.29885 Tj
+-404 TJm
+(size) 15.4918 Tj
+[1 0 0 1 434.744 164.183] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -434.744 -164.183] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+434.744 164.183 Td
+/F134_0 9.9626 Tf
+(BZ_MAX_UNUSED) 77.7083 Tj
+[1 0 0 1 512.452 164.183] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -512.452 -164.183] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+516.479 164.183 Td
+/F130_0 9.9626 Tf
+(bytes,) 23.5217 Tj
+86.944 152.228 Td
+(and) 14.386 Tj
+-413 TJm
+(in) 7.7509 Tj
+-413 TJm
+(doing) 22.6948 Tj
+-413 TJm
+(so) 8.85675 Tj
+-413 TJm
+(probably) 35.417 Tj
+-413 TJm
+(will) 15.5018 Tj
+-413 TJm
+(o) 4.9813 Tj
+15 TJm
+(v) 4.9813 Tj
+15 TJm
+(ershoot) 29.3299 Tj
+-413 TJm
+(the) 12.1743 Tj
+-413 TJm
+(logical) 27.1182 Tj
+-413 TJm
+(end) 14.386 Tj
+-413 TJm
+(of) 8.29885 Tj
+-413 TJm
+(compressed) 47.0334 Tj
+-413 TJm
+(stream.) 29.0509 Tj
+-1598 TJm
+(T) 6.08715 Tj
+80 TJm
+(o) 4.9813 Tj
+-413 TJm
+(reco) 17.1456 Tj
+15 TJm
+(v) 4.9813 Tj
+15 TJm
+(er) 7.74094 Tj
+-413 TJm
+(this) 14.396 Tj
+-413 TJm
+(data) 16.5977 Tj
+-413 TJm
+(once) 18.8094 Tj
+86.944 140.273 Td
+(decompression) 59.7656 Tj
+-252 TJm
+(has) 13.2801 Tj
+-252 TJm
+(ended,) 26.2813 Tj
+-253 TJm
+(call) 14.386 Tj
+[1 0 0 1 210.705 140.273] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -210.705 -140.273] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+210.705 140.273 Td
+/F134_0 9.9626 Tf
+(BZ2_bzReadGetUnused) 113.574 Tj
+[1 0 0 1 324.279 140.273] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -324.279 -140.273] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+326.789 140.273 Td
+/F130_0 9.9626 Tf
+(after) 18.2515 Tj
+-252 TJm
+(the) 12.1743 Tj
+-252 TJm
+(last) 13.8381 Tj
+-252 TJm
+(call) 14.386 Tj
+-252 TJm
+(of) 8.29885 Tj
+[1 0 0 1 406.291 140.273] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -406.291 -140.273] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+406.291 140.273 Td
+/F134_0 9.9626 Tf
+(BZ2_bzRead) 59.7756 Tj
+[1 0 0 1 466.067 140.273] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -466.067 -140.273] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+468.578 140.273 Td
+/F130_0 9.9626 Tf
+(\(the) 15.4918 Tj
+-252 TJm
+(one) 14.386 Tj
+-252 TJm
+(returning) 36.5229 Tj
+[1 0 0 1 86.944 128.318] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -86.944 -128.318] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 128.318 Td
+/F134_0 9.9626 Tf
+(BZ_STREAM_END) 77.7083 Tj
+[1 0 0 1 164.653 128.318] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -164.653 -128.318] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+164.653 128.318 Td
+/F130_0 9.9626 Tf
+(\)) 3.31755 Tj
+-250 TJm
+(b) 4.9813 Tj
+20 TJm
+(ut) 7.7509 Tj
+-250 TJm
+(before) 25.4445 Tj
+-250 TJm
+(calling) 27.1182 Tj
+[1 0 0 1 243.028 128.318] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -243.028 -128.318] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+243.028 128.318 Td
+/F134_0 9.9626 Tf
+(BZ2_bzReadClose) 89.6634 Tj
+[1 0 0 1 332.692 128.318] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -332.692 -128.318] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+332.692 128.318 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+[1 0 0 1 335.182 128.318] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -263.182 -77.466] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 374.394 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 6.7545] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 40.5726 -6.7545] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -493.841 -50.8519] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+534.414 50.8518 Td
+/F130_0 9.9626 Tf
+(24) 9.9626 Tj
+[1 0 0 1 453.269 50.8518] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 93.5985 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.2765 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+Q
+showpage
+%%PageTrailer
+pdfEndPage
+%%Page: 28 28
+%%BeginPageSetup
+%%PageOrientation: Portrait
+pdfStartPage
+0 0 612 792 re W
+%%EndPageSetup
+[] 0 d
+1 i
+0 j
+0 J
+10 M
+1 w
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+false op
+false OP
+0 0 612 792 re
+W
+q
+[1 0 0 1 72 741.554] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 14.4459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 187.197 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 -8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 76.4979 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -342.569 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+419.067 749.245 Td
+/F130_0 9.9626 Tf
+(Programming) 54.7943 Tj
+-250 TJm
+(with) 17.7135 Tj
+[1 0 0 1 496.556 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -496.556 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+496.556 749.245 Td
+/F134_0 9.9626 Tf
+(libbzip2) 47.8205 Tj
+[1 0 0 1 544.376 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -278.305 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 280.796 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -472.974 -5.0363] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -0.4981] cm
+q
+[] 0 d
+0 J
+0.4981 w
+0 0.2491 m
+475.465 0.2491 l
+S
+Q
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 479.251 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -21.5542] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -720] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 710.037 Td
+/F130_0 9.9626 Tf
+(This) 17.7135 Tj
+-271 TJm
+(mechanism) 45.3796 Tj
+-272 TJm
+(mak) 17.1556 Tj
+10 TJm
+(es) 8.29885 Tj
+-271 TJm
+(it) 5.53921 Tj
+-271 TJm
+(easy) 17.7035 Tj
+-271 TJm
+(to) 7.7509 Tj
+-272 TJm
+(decompress) 47.0334 Tj
+-271 TJm
+(multiple) 33.2153 Tj
+[1 0 0 1 293.312 710.037] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -293.312 -710.037] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+293.312 710.037 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 323.2 710.037] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -323.2 -710.037] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+325.903 710.037 Td
+/F130_0 9.9626 Tf
+(streams) 30.4357 Tj
+-271 TJm
+(placed) 26.0024 Tj
+-272 TJm
+(end-to-end.) 45.6486 Tj
+-374 TJm
+(As) 11.0684 Tj
+-271 TJm
+(the) 12.1743 Tj
+-271 TJm
+(end) 14.386 Tj
+-271 TJm
+(of) 8.29885 Tj
+-272 TJm
+(one) 14.386 Tj
+-271 TJm
+(stream,) 29.0509 Tj
+72 698.082 Td
+(when) 21.579 Tj
+[1 0 0 1 96.1948 698.082] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -96.1948 -698.082] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+96.1948 698.082 Td
+/F134_0 9.9626 Tf
+(BZ2_bzRead) 59.7756 Tj
+[1 0 0 1 155.971 698.082] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -155.971 -698.082] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+158.586 698.082 Td
+/F130_0 9.9626 Tf
+(returns) 27.6661 Tj
+[1 0 0 1 188.868 698.082] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -188.868 -698.082] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+188.868 698.082 Td
+/F134_0 9.9626 Tf
+(BZ_STREAM_END) 77.7083 Tj
+[1 0 0 1 266.577 698.082] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -266.577 -698.082] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+266.577 698.082 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-263 TJm
+(call) 14.386 Tj
+[1 0 0 1 288.685 698.082] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -288.685 -698.082] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+288.685 698.082 Td
+/F134_0 9.9626 Tf
+(BZ2_bzReadGetUnused) 113.574 Tj
+[1 0 0 1 402.259 698.082] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -402.259 -698.082] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+404.875 698.082 Td
+/F130_0 9.9626 Tf
+(to) 7.7509 Tj
+-263 TJm
+(collect) 26.5603 Tj
+-262 TJm
+(the) 12.1743 Tj
+-263 TJm
+(unused) 28.224 Tj
+-262 TJm
+(data) 16.5977 Tj
+-263 TJm
+(\(cop) 17.7035 Tj
+10 TJm
+(y) 4.9813 Tj
+-262 TJm
+(it) 5.53921 Tj
+72 686.127 Td
+(into) 15.5018 Tj
+-265 TJm
+(your) 18.2614 Tj
+-265 TJm
+(o) 4.9813 Tj
+25 TJm
+(wn) 12.1743 Tj
+-265 TJm
+(b) 4.9813 Tj
+20 TJm
+(uf) 8.29885 Tj
+25 TJm
+(fer) 11.0585 Tj
+-265 TJm
+(some) 21.031 Tj
+25 TJm
+(where\).) 30.1468 Tj
+-711 TJm
+(That) 18.2614 Tj
+-265 TJm
+(data) 16.5977 Tj
+-265 TJm
+(forms) 23.2427 Tj
+-265 TJm
+(the) 12.1743 Tj
+-265 TJm
+(start) 17.1556 Tj
+-265 TJm
+(of) 8.29885 Tj
+-265 TJm
+(the) 12.1743 Tj
+-265 TJm
+(ne) 9.40469 Tj
+15 TJm
+(xt) 7.7509 Tj
+-265 TJm
+(compressed) 47.0334 Tj
+-265 TJm
+(stream.) 29.0509 Tj
+-711 TJm
+(T) 6.08715 Tj
+80 TJm
+(o) 4.9813 Tj
+-265 TJm
+(start) 17.1556 Tj
+-265 TJm
+(uncompressing) 60.3235 Tj
+72 674.172 Td
+(that) 14.9439 Tj
+-246 TJm
+(ne) 9.40469 Tj
+15 TJm
+(xt) 7.7509 Tj
+-246 TJm
+(stream,) 29.0509 Tj
+-247 TJm
+(call) 14.386 Tj
+[1 0 0 1 157.205 674.172] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -157.205 -674.172] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+157.205 674.172 Td
+/F134_0 9.9626 Tf
+(BZ2_bzReadOpen) 83.6858 Tj
+[1 0 0 1 240.891 674.172] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -240.891 -674.172] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+243.344 674.172 Td
+/F130_0 9.9626 Tf
+(ag) 9.40469 Tj
+5 TJm
+(ain,) 14.6649 Tj
+-247 TJm
+(feeding) 29.8778 Tj
+-246 TJm
+(in) 7.7509 Tj
+-246 TJm
+(the) 12.1743 Tj
+-247 TJm
+(unused) 28.224 Tj
+-246 TJm
+(data) 16.5977 Tj
+-246 TJm
+(via) 12.1743 Tj
+-246 TJm
+(the) 12.1743 Tj
+[1 0 0 1 405.967 674.172] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -405.967 -674.172] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+405.967 674.172 Td
+/F134_0 9.9626 Tf
+(unused) 35.8654 Tj
+[1 0 0 1 441.833 674.172] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -441.833 -674.172] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+444.286 674.172 Td
+/F130_0 9.9626 Tf
+(/) 2.7696 Tj
+[1 0 0 1 449.508 674.172] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -449.508 -674.172] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+449.508 674.172 Td
+/F134_0 9.9626 Tf
+(nUnused) 41.8429 Tj
+[1 0 0 1 491.351 674.172] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -491.351 -674.172] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+493.804 674.172 Td
+/F130_0 9.9626 Tf
+(parameters.) 46.1966 Tj
+72 662.217 Td
+(K) 7.193 Tj
+25 TJm
+(eep) 13.8281 Tj
+-263 TJm
+(doing) 22.6948 Tj
+-263 TJm
+(this) 14.396 Tj
+-264 TJm
+(until) 18.2714 Tj
+[1 0 0 1 158.622 662.217] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -158.622 -662.217] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+158.622 662.217 Td
+/F134_0 9.9626 Tf
+(BZ_STREAM_END) 77.7083 Tj
+[1 0 0 1 236.33 662.217] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -236.33 -662.217] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+238.952 662.217 Td
+/F130_0 9.9626 Tf
+(return) 23.7907 Tj
+-263 TJm
+(coincides) 37.6287 Tj
+-263 TJm
+(with) 17.7135 Tj
+-263 TJm
+(the) 12.1743 Tj
+-264 TJm
+(ph) 9.9626 Tj
+5 TJm
+(ysical) 23.2427 Tj
+-263 TJm
+(end) 14.386 Tj
+-263 TJm
+(of) 8.29885 Tj
+-263 TJm
+(\002le) 12.7322 Tj
+-263 TJm
+(\() 3.31755 Tj
+[1 0 0 1 423.125 662.217] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -423.125 -662.217] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+423.125 662.217 Td
+/F134_0 9.9626 Tf
+(feof\(f\)) 41.8429 Tj
+[1 0 0 1 464.968 662.217] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -464.968 -662.217] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+464.968 662.217 Td
+/F130_0 9.9626 Tf
+(\).) 5.8082 Tj
+-699 TJm
+(In) 8.29885 Tj
+-263 TJm
+(this) 14.396 Tj
+-263 TJm
+(situation) 34.3212 Tj
+[1 0 0 1 72 650.261] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -650.261] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 650.261 Td
+/F134_0 9.9626 Tf
+(BZ2_bzReadGetUnused) 113.574 Tj
+[1 0 0 1 185.574 650.261] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -185.574 -650.261] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+188.065 650.261 Td
+/F130_0 9.9626 Tf
+(will) 15.5018 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(course) 26.0024 Tj
+-250 TJm
+(return) 23.7907 Tj
+-250 TJm
+(no) 9.9626 Tj
+-250 TJm
+(data.) 19.0883 Tj
+[1 0 0 1 72 648.951] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -638.989] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 628.344 Td
+/F130_0 9.9626 Tf
+(This) 17.7135 Tj
+-240 TJm
+(should) 26.5703 Tj
+-241 TJm
+(gi) 7.7509 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-240 TJm
+(some) 21.031 Tj
+-241 TJm
+(feel) 14.9339 Tj
+-240 TJm
+(for) 11.6164 Tj
+-241 TJm
+(ho) 9.9626 Tj
+25 TJm
+(w) 7.193 Tj
+-240 TJm
+(the) 12.1743 Tj
+-240 TJm
+(high-le) 28.224 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(el) 7.193 Tj
+-241 TJm
+(interf) 21.579 Tj
+10 TJm
+(ace) 13.2702 Tj
+-240 TJm
+(can) 13.8281 Tj
+-241 TJm
+(be) 9.40469 Tj
+-240 TJm
+(used.) 20.7521 Tj
+-614 TJm
+(If) 6.63509 Tj
+-240 TJm
+(you) 14.9439 Tj
+-241 TJm
+(require) 28.2141 Tj
+-240 TJm
+(e) 4.42339 Tj
+15 TJm
+(xtra) 15.4918 Tj
+-241 TJm
+(\003e) 9.9626 Tj
+15 TJm
+(xibi) 15.5018 Tj
+1 TJm
+(lity) 13.2901 Tj
+65 TJm
+(,) 2.49065 Tj
+-243 TJm
+(you') 18.2614 Tj
+10 TJm
+(ll) 5.53921 Tj
+-240 TJm
+(ha) 9.40469 Tj
+20 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-241 TJm
+(to) 7.7509 Tj
+72 616.389 Td
+(bite) 14.9439 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(b) 4.9813 Tj
+20 TJm
+(ullet) 17.7135 Tj
+-250 TJm
+(and) 14.386 Tj
+-250 TJm
+(get) 12.1743 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(grips) 19.9252 Tj
+-250 TJm
+(with) 17.7135 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(lo) 7.7509 Tj
+25 TJm
+(w-le) 17.7035 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(el) 7.193 Tj
+-250 TJm
+(interf) 21.579 Tj
+10 TJm
+(ace.) 15.7608 Tj
+[1 0 0 1 72 614.232] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -604.269] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 585.767 Td
+/F122_0 17.2154 Tf
+(3.4.9.) 43.0729 Tj
+-278 TJm
+(Standar) 64.0929 Tj
+20 TJm
+(d) 10.5186 Tj
+-278 TJm
+(\002le-reading/writing) 154.009 Tj
+-278 TJm
+(code) 40.1807 Tj
+[1 0 0 1 72 581.937] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -571.975] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 563.85 Td
+/F130_0 9.9626 Tf
+(Here') 22.6749 Tj
+55 TJm
+(s) 3.87545 Tj
+-250 TJm
+(ho) 9.9626 Tj
+25 TJm
+(w) 7.193 Tj
+-250 TJm
+(you') 18.2614 Tj
+50 TJm
+(d) 4.9813 Tj
+-250 TJm
+(write) 20.4731 Tj
+-250 TJm
+(data) 16.5977 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(compressed) 47.0334 Tj
+-250 TJm
+(\002le:) 15.5018 Tj
+[1 0 0 1 72 561.693] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -371.606] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 370.61 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 367.024] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -552.328] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 552.328 Td
+/F134_0 9.9626 Tf
+(FILE) 23.9102 Tj
+113.91 550.584 Td
+(*) 5.97756 Tj
+132.62 552.328 Td
+(f;) 11.9551 Tj
+90 540.373 Td
+(BZFILE) 35.8654 Tj
+125.865 538.629 Td
+(*) 5.97756 Tj
+136.087 540.373 Td
+(b;) 11.9551 Tj
+90 528.418 Td
+(int) 17.9327 Tj
+-2130 TJm
+(nBuf;) 29.8878 Tj
+90 516.462 Td
+(char) 23.9102 Tj
+-1704 TJm
+(buf[) 23.9102 Tj
+-426 TJm
+(/) 5.97756 Tj
+165.018 514.719 Td
+(*) 5.97756 Tj
+175.24 516.462 Td
+(whatever) 47.8205 Tj
+-426 TJm
+(size) 23.9102 Tj
+-426 TJm
+(you) 17.9327 Tj
+-426 TJm
+(like) 23.9102 Tj
+305.79 514.719 Td
+(*) 5.97756 Tj
+311.767 516.462 Td
+(/) 5.97756 Tj
+-426 TJm
+(];) 11.9551 Tj
+90 504.507 Td
+(int) 17.9327 Tj
+-2130 TJm
+(bzerror;) 47.8205 Tj
+90 492.552 Td
+(int) 17.9327 Tj
+-2130 TJm
+(nWritten;) 53.798 Tj
+90 468.642 Td
+(f) 5.97756 Tj
+-426 TJm
+(=) 5.97756 Tj
+-426 TJm
+(fopen) 29.8878 Tj
+-426 TJm
+(\() 5.97756 Tj
+-426 TJm
+("myfile.bz2",) 77.7083 Tj
+-426 TJm
+("w") 17.9327 Tj
+-426 TJm
+(\);) 11.9551 Tj
+90 456.687 Td
+(if) 11.9551 Tj
+-426 TJm
+(\() 5.97756 Tj
+-426 TJm
+(!f) 11.9551 Tj
+-426 TJm
+(\)) 5.97756 Tj
+-426 TJm
+({) 5.97756 Tj
+94.244 444.731 Td
+(/) 5.97756 Tj
+100.222 442.988 Td
+(*) 5.97756 Tj
+110.443 444.731 Td
+(handle) 35.8654 Tj
+-426 TJm
+(error) 29.8878 Tj
+184.685 442.988 Td
+(*) 5.97756 Tj
+190.662 444.731 Td
+(/) 5.97756 Tj
+90 432.776 Td
+(}) 5.97756 Tj
+90 420.821 Td
+(b) 5.97756 Tj
+-426 TJm
+(=) 5.97756 Tj
+-426 TJm
+(BZ2_bzWriteOpen\() 95.641 Tj
+-426 TJm
+(&bzerror,) 53.798 Tj
+-426 TJm
+(f,) 11.9551 Tj
+-426 TJm
+(9) 5.97756 Tj
+-426 TJm
+(\);) 11.9551 Tj
+90 408.866 Td
+(if) 11.9551 Tj
+-426 TJm
+(\(bzerror) 47.8205 Tj
+-426 TJm
+(!=) 11.9551 Tj
+-426 TJm
+(BZ_OK\)) 35.8654 Tj
+-426 TJm
+({) 5.97756 Tj
+94.244 396.911 Td
+(BZ2_bzWriteClose) 95.641 Tj
+-426 TJm
+(\() 5.97756 Tj
+-426 TJm
+(b) 5.97756 Tj
+-426 TJm
+(\);) 11.9551 Tj
+94.244 384.956 Td
+(/) 5.97756 Tj
+100.222 383.212 Td
+(*) 5.97756 Tj
+110.443 384.956 Td
+(handle) 35.8654 Tj
+-426 TJm
+(error) 29.8878 Tj
+184.685 383.212 Td
+(*) 5.97756 Tj
+190.662 384.956 Td
+(/) 5.97756 Tj
+90 373 Td
+(}) 5.97756 Tj
+90 349.09 Td
+(while) 29.8878 Tj
+-426 TJm
+(\() 5.97756 Tj
+-426 TJm
+(/) 5.97756 Tj
+140.331 347.347 Td
+(*) 5.97756 Tj
+150.553 349.09 Td
+(condition) 53.798 Tj
+208.595 347.347 Td
+(*) 5.97756 Tj
+214.572 349.09 Td
+(/) 5.97756 Tj
+-426 TJm
+(\)) 5.97756 Tj
+-426 TJm
+({) 5.97756 Tj
+94.244 337.135 Td
+(/) 5.97756 Tj
+100.222 335.391 Td
+(*) 5.97756 Tj
+110.443 337.135 Td
+(get) 17.9327 Tj
+-426 TJm
+(data) 23.9102 Tj
+-426 TJm
+(to) 11.9551 Tj
+-426 TJm
+(write) 29.8878 Tj
+-426 TJm
+(into) 23.9102 Tj
+-426 TJm
+(buf,) 23.9102 Tj
+-426 TJm
+(and) 17.9327 Tj
+-426 TJm
+(set) 17.9327 Tj
+-426 TJm
+(nBuf) 23.9102 Tj
+-426 TJm
+(appropriately) 77.7083 Tj
+421.874 335.391 Td
+(*) 5.97756 Tj
+427.852 337.135 Td
+(/) 5.97756 Tj
+94.2439 325.18 Td
+(nWritten) 47.8205 Tj
+-426 TJm
+(=) 5.97756 Tj
+-426 TJm
+(BZ2_bzWrite) 65.7532 Tj
+-426 TJm
+(\() 5.97756 Tj
+-426 TJm
+(&bzerror,) 53.798 Tj
+-426 TJm
+(b,) 11.9551 Tj
+-426 TJm
+(buf,) 23.9102 Tj
+-426 TJm
+(nBuf) 23.9102 Tj
+-426 TJm
+(\);) 11.9551 Tj
+94.2439 313.225 Td
+(if) 11.9551 Tj
+-426 TJm
+(\(bzerror) 47.8205 Tj
+-426 TJm
+(==) 11.9551 Tj
+-426 TJm
+(BZ_IO_ERROR\)) 71.7307 Tj
+-426 TJm
+({) 5.97756 Tj
+102.732 301.269 Td
+(BZ2_bzWriteClose) 95.641 Tj
+-426 TJm
+(\() 5.97756 Tj
+-426 TJm
+(&bzerror,) 53.798 Tj
+-426 TJm
+(b) 5.97756 Tj
+-426 TJm
+(\);) 11.9551 Tj
+102.732 289.314 Td
+(/) 5.97756 Tj
+108.709 287.571 Td
+(*) 5.97756 Tj
+118.931 289.314 Td
+(handle) 35.8654 Tj
+-426 TJm
+(error) 29.8878 Tj
+193.172 287.571 Td
+(*) 5.97756 Tj
+199.15 289.314 Td
+(/) 5.97756 Tj
+94.2439 277.359 Td
+(}) 5.97756 Tj
+90 265.404 Td
+(}) 5.97756 Tj
+90 241.494 Td
+(BZ2_bzWriteClose\() 101.619 Tj
+-426 TJm
+(&bzerror,) 53.798 Tj
+-426 TJm
+(b) 5.97756 Tj
+-426 TJm
+(\);) 11.9551 Tj
+90 229.538 Td
+(if) 11.9551 Tj
+-426 TJm
+(\(bzerror) 47.8205 Tj
+-426 TJm
+(==) 11.9551 Tj
+-426 TJm
+(BZ_IO_ERROR\)) 71.7307 Tj
+-426 TJm
+({) 5.97756 Tj
+94.2439 217.583 Td
+(/) 5.97756 Tj
+100.221 215.84 Td
+(*) 5.97756 Tj
+110.443 217.583 Td
+(handle) 35.8654 Tj
+-426 TJm
+(error) 29.8878 Tj
+184.684 215.84 Td
+(*) 5.97756 Tj
+190.662 217.583 Td
+(/) 5.97756 Tj
+89.9999 205.628 Td
+(}) 5.97756 Tj
+[1 0 0 1 72 190.086] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.5492] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -180.124] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 168.168 Td
+/F130_0 9.9626 Tf
+(And) 17.1556 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(read) 17.1456 Tj
+-250 TJm
+(from) 19.3673 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(compressed) 47.0334 Tj
+-250 TJm
+(\002le:) 15.5018 Tj
+[1 0 0 1 72 166.012] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -115.16] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 374.394 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 6.8541] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 40.5726 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -493.841 -50.9513] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+534.414 50.9513 Td
+/F130_0 9.9626 Tf
+(25) 9.9626 Tj
+[1 0 0 1 453.269 50.8518] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 93.5985 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.2765 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+Q
+showpage
+%%PageTrailer
+pdfEndPage
+%%Page: 29 29
+%%BeginPageSetup
+%%PageOrientation: Portrait
+pdfStartPage
+0 0 612 792 re W
+%%EndPageSetup
+[] 0 d
+1 i
+0 j
+0 J
+10 M
+1 w
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+false op
+false OP
+0 0 612 792 re
+W
+q
+[1 0 0 1 72 741.554] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 14.4459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 187.197 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 -8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 76.4979 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -342.569 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+419.067 749.245 Td
+/F130_0 9.9626 Tf
+(Programming) 54.7943 Tj
+-250 TJm
+(with) 17.7135 Tj
+[1 0 0 1 496.556 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -496.556 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+496.556 749.245 Td
+/F134_0 9.9626 Tf
+(libbzip2) 47.8205 Tj
+[1 0 0 1 544.376 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -278.305 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 280.796 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -472.974 -5.0363] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -0.4981] cm
+q
+[] 0 d
+0 J
+0.4981 w
+0 0.2491 m
+475.465 0.2491 l
+S
+Q
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 479.251 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -392.164] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 370.61 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 367.024] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -711.631] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 711.631 Td
+/F134_0 9.9626 Tf
+(FILE) 23.9102 Tj
+113.91 709.888 Td
+(*) 5.97756 Tj
+132.62 711.631 Td
+(f;) 11.9551 Tj
+90 699.676 Td
+(BZFILE) 35.8654 Tj
+125.865 697.933 Td
+(*) 5.97756 Tj
+136.087 699.676 Td
+(b;) 11.9551 Tj
+90 687.721 Td
+(int) 17.9327 Tj
+-2130 TJm
+(nBuf;) 29.8878 Tj
+90 675.766 Td
+(char) 23.9102 Tj
+-1704 TJm
+(buf[) 23.9102 Tj
+-426 TJm
+(/) 5.97756 Tj
+165.018 674.023 Td
+(*) 5.97756 Tj
+175.24 675.766 Td
+(whatever) 47.8205 Tj
+-426 TJm
+(size) 23.9102 Tj
+-426 TJm
+(you) 17.9327 Tj
+-426 TJm
+(like) 23.9102 Tj
+305.79 674.023 Td
+(*) 5.97756 Tj
+311.767 675.766 Td
+(/) 5.97756 Tj
+-426 TJm
+(];) 11.9551 Tj
+90 663.811 Td
+(int) 17.9327 Tj
+-2130 TJm
+(bzerror;) 47.8205 Tj
+90 651.856 Td
+(int) 17.9327 Tj
+-2130 TJm
+(nWritten;) 53.798 Tj
+90 627.945 Td
+(f) 5.97756 Tj
+-426 TJm
+(=) 5.97756 Tj
+-426 TJm
+(fopen) 29.8878 Tj
+-426 TJm
+(\() 5.97756 Tj
+-426 TJm
+("myfile.bz2",) 77.7083 Tj
+-426 TJm
+("r") 17.9327 Tj
+-426 TJm
+(\);) 11.9551 Tj
+90 615.99 Td
+(if) 11.9551 Tj
+-426 TJm
+(\() 5.97756 Tj
+-426 TJm
+(!f) 11.9551 Tj
+-426 TJm
+(\)) 5.97756 Tj
+-426 TJm
+({) 5.97756 Tj
+98.488 604.035 Td
+(/) 5.97756 Tj
+104.466 602.292 Td
+(*) 5.97756 Tj
+114.687 604.035 Td
+(handle) 35.8654 Tj
+-426 TJm
+(error) 29.8878 Tj
+188.929 602.292 Td
+(*) 5.97756 Tj
+194.906 604.035 Td
+(/) 5.97756 Tj
+90 592.08 Td
+(}) 5.97756 Tj
+90 580.125 Td
+(b) 5.97756 Tj
+-426 TJm
+(=) 5.97756 Tj
+-426 TJm
+(BZ2_bzReadOpen) 83.6858 Tj
+-426 TJm
+(\() 5.97756 Tj
+-426 TJm
+(&bzerror,) 53.798 Tj
+-426 TJm
+(f,) 11.9551 Tj
+-426 TJm
+(0,) 11.9551 Tj
+-426 TJm
+(NULL,) 29.8878 Tj
+-426 TJm
+(0) 5.97756 Tj
+-426 TJm
+(\);) 11.9551 Tj
+90 568.169 Td
+(if) 11.9551 Tj
+-426 TJm
+(\() 5.97756 Tj
+-426 TJm
+(bzerror) 41.8429 Tj
+-426 TJm
+(!=) 11.9551 Tj
+-426 TJm
+(BZ_OK) 29.8878 Tj
+-426 TJm
+(\)) 5.97756 Tj
+-426 TJm
+({) 5.97756 Tj
+98.488 556.214 Td
+(BZ2_bzReadClose) 89.6634 Tj
+-426 TJm
+(\() 5.97756 Tj
+-426 TJm
+(&bzerror,) 53.798 Tj
+-426 TJm
+(b) 5.97756 Tj
+-426 TJm
+(\);) 11.9551 Tj
+98.488 544.259 Td
+(/) 5.97756 Tj
+104.466 542.516 Td
+(*) 5.97756 Tj
+114.687 544.259 Td
+(handle) 35.8654 Tj
+-426 TJm
+(error) 29.8878 Tj
+188.929 542.516 Td
+(*) 5.97756 Tj
+194.906 544.259 Td
+(/) 5.97756 Tj
+90 532.304 Td
+(}) 5.97756 Tj
+90 508.394 Td
+(bzerror) 41.8429 Tj
+-426 TJm
+(=) 5.97756 Tj
+-426 TJm
+(BZ_OK;) 35.8654 Tj
+90 496.438 Td
+(while) 29.8878 Tj
+-426 TJm
+(\() 5.97756 Tj
+-426 TJm
+(bzerror) 41.8429 Tj
+-426 TJm
+(==) 11.9551 Tj
+-426 TJm
+(BZ_OK) 29.8878 Tj
+-426 TJm
+(&&) 11.9551 Tj
+-426 TJm
+(/) 5.97756 Tj
+252.948 494.695 Td
+(*) 5.97756 Tj
+263.17 496.438 Td
+(arbitrary) 53.798 Tj
+-426 TJm
+(other) 29.8878 Tj
+-426 TJm
+(conditions) 59.7756 Tj
+419.364 494.695 Td
+(*) 5.97756 Tj
+425.341 496.438 Td
+(/\)) 11.9551 Tj
+-426 TJm
+({) 5.97756 Tj
+98.488 484.483 Td
+(nBuf) 23.9102 Tj
+-426 TJm
+(=) 5.97756 Tj
+-426 TJm
+(BZ2_bzRead) 59.7756 Tj
+-426 TJm
+(\() 5.97756 Tj
+-426 TJm
+(&bzerror,) 53.798 Tj
+-426 TJm
+(b,) 11.9551 Tj
+-426 TJm
+(buf,) 23.9102 Tj
+-426 TJm
+(/) 5.97756 Tj
+319.478 482.74 Td
+(*) 5.97756 Tj
+329.7 484.483 Td
+(size) 23.9102 Tj
+-426 TJm
+(of) 11.9551 Tj
+-426 TJm
+(buf) 17.9327 Tj
+396.23 482.74 Td
+(*) 5.97756 Tj
+402.208 484.483 Td
+(/) 5.97756 Tj
+-426 TJm
+(\);) 11.9551 Tj
+98.488 472.528 Td
+(if) 11.9551 Tj
+-426 TJm
+(\() 5.97756 Tj
+-426 TJm
+(bzerror) 41.8429 Tj
+-426 TJm
+(==) 11.9551 Tj
+-426 TJm
+(BZ_OK) 29.8878 Tj
+-426 TJm
+(\)) 5.97756 Tj
+-426 TJm
+({) 5.97756 Tj
+106.976 460.573 Td
+(/) 5.97756 Tj
+112.953 458.829 Td
+(*) 5.97756 Tj
+123.175 460.573 Td
+(do) 11.9551 Tj
+-426 TJm
+(something) 53.798 Tj
+-426 TJm
+(with) 23.9102 Tj
+-426 TJm
+(buf[0) 29.8878 Tj
+-426 TJm
+(..) 11.9551 Tj
+-426 TJm
+(nBuf-1]) 41.8429 Tj
+321.989 458.829 Td
+(*) 5.97756 Tj
+327.966 460.573 Td
+(/) 5.97756 Tj
+98.4879 448.618 Td
+(}) 5.97756 Tj
+90 436.663 Td
+(}) 5.97756 Tj
+90 424.707 Td
+(if) 11.9551 Tj
+-426 TJm
+(\() 5.97756 Tj
+-426 TJm
+(bzerror) 41.8429 Tj
+-426 TJm
+(!=) 11.9551 Tj
+-426 TJm
+(BZ_STREAM_END) 77.7083 Tj
+-426 TJm
+(\)) 5.97756 Tj
+-426 TJm
+({) 5.97756 Tj
+102.732 412.752 Td
+(BZ2_bzReadClose) 89.6634 Tj
+-426 TJm
+(\() 5.97756 Tj
+-426 TJm
+(&bzerror,) 53.798 Tj
+-426 TJm
+(b) 5.97756 Tj
+-426 TJm
+(\);) 11.9551 Tj
+102.732 400.797 Td
+(/) 5.97756 Tj
+108.709 399.054 Td
+(*) 5.97756 Tj
+118.931 400.797 Td
+(handle) 35.8654 Tj
+-426 TJm
+(error) 29.8878 Tj
+193.172 399.054 Td
+(*) 5.97756 Tj
+199.15 400.797 Td
+(/) 5.97756 Tj
+90 388.842 Td
+(}) 5.97756 Tj
+-426 TJm
+(else) 23.9102 Tj
+-426 TJm
+({) 5.97756 Tj
+102.732 376.887 Td
+(BZ2_bzReadClose) 89.6634 Tj
+-426 TJm
+(\() 5.97756 Tj
+-426 TJm
+(&bzerror,) 53.798 Tj
+-426 TJm
+(b) 5.97756 Tj
+-426 TJm
+(\);) 11.9551 Tj
+90 364.932 Td
+(}) 5.97756 Tj
+[1 0 0 1 72 349.39] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -339.427] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 314.637 Td
+/F122_0 20.6585 Tf
+(3.5.) 34.4584 Tj
+-278 TJm
+(Utility) 57.3893 Tj
+-278 TJm
+(functions) 92.9633 Tj
+[1 0 0 1 72 310.361] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -300.398] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 284.016 Td
+/F122_0 17.2154 Tf
+(3.5.1.) 43.0729 Tj
+[1 0 0 1 119.858 284.016] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -119.858 -284.016] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+119.858 284.016 Td
+/F392_0 17.2154 Tf
+(BZ2_bzBuffToBuffCompress) 247.902 Tj
+[1 0 0 1 367.76 284.016] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -295.76 -2.3327] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -96.6376] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 95.6413 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 92.0548] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -272.318] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 272.318 Td
+/F134_0 9.9626 Tf
+(int) 17.9327 Tj
+-426 TJm
+(BZ2_bzBuffToBuffCompress\() 149.439 Tj
+-426 TJm
+(char) 23.9102 Tj
+289.771 270.575 Td
+(*) 5.97756 Tj
+333.944 272.318 Td
+(dest,) 29.8878 Tj
+217.319 260.363 Td
+(unsigned) 47.8205 Tj
+-426 TJm
+(int) 17.9327 Tj
+287.317 258.62 Td
+(*) 5.97756 Tj
+297.538 260.363 Td
+(destLen,) 47.8205 Tj
+217.319 248.408 Td
+(char) 23.9102 Tj
+241.23 246.664 Td
+(*) 5.97756 Tj
+285.403 248.408 Td
+(source,) 41.8429 Tj
+217.319 236.453 Td
+(unsigned) 47.8205 Tj
+-426 TJm
+(int) 17.9327 Tj
+-852 TJm
+(sourceLen,) 59.7756 Tj
+217.319 224.498 Td
+(int) 17.9327 Tj
+-4686 TJm
+(blockSize100k,) 83.6858 Tj
+217.319 212.542 Td
+(int) 17.9327 Tj
+-4686 TJm
+(verbosity,) 59.7756 Tj
+217.319 200.587 Td
+(int) 17.9327 Tj
+-4686 TJm
+(workFactor) 59.7756 Tj
+-426 TJm
+(\);) 11.9551 Tj
+[1 0 0 1 72 185.045] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.5492] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -175.083] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 163.128 Td
+/F130_0 9.9626 Tf
+(Attempts) 36.5329 Tj
+-442 TJm
+(to) 7.7509 Tj
+-442 TJm
+(compress) 37.6287 Tj
+-443 TJm
+(the) 12.1743 Tj
+-442 TJm
+(data) 16.5977 Tj
+-442 TJm
+(in) 7.7509 Tj
+[1 0 0 1 216.87 163.128] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -216.87 -163.128] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+216.87 163.128 Td
+/F134_0 9.9626 Tf
+(source[0) 47.8205 Tj
+-600 TJm
+(..) 11.9551 Tj
+-1200 TJm
+(sourceLen-1]) 71.7307 Tj
+[1 0 0 1 366.31 163.128] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -366.31 -163.128] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+370.715 163.128 Td
+/F130_0 9.9626 Tf
+(into) 15.5018 Tj
+-442 TJm
+(the) 12.1743 Tj
+-442 TJm
+(destination) 43.7259 Tj
+-443 TJm
+(b) 4.9813 Tj
+20 TJm
+(uf) 8.29885 Tj
+25 TJm
+(fer) 11.0585 Tj
+40 TJm
+(,) 2.49065 Tj
+[1 0 0 1 486.202 163.128] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -486.202 -163.128] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+486.202 163.128 Td
+/F134_0 9.9626 Tf
+(dest[0) 35.8654 Tj
+-600 TJm
+(..) 11.9551 Tj
+72 149.429 Td
+(*) 5.97756 Tj
+77.9776 151.173 Td
+(destLen-1]) 59.7756 Tj
+[1 0 0 1 137.753 151.172] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -137.753 -151.172] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+137.753 151.172 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+-1393 TJm
+(If) 6.63509 Tj
+-379 TJm
+(the) 12.1743 Tj
+-379 TJm
+(destination) 43.7259 Tj
+-379 TJm
+(b) 4.9813 Tj
+20 TJm
+(uf) 8.29885 Tj
+25 TJm
+(fer) 11.0585 Tj
+-378 TJm
+(is) 6.64505 Tj
+-379 TJm
+(big) 12.7322 Tj
+-379 TJm
+(enough,) 31.8205 Tj
+[1 0 0 1 318.486 151.172] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -318.486 -151.172] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+318.486 149.429 Td
+/F134_0 9.9626 Tf
+(*) 5.97756 Tj
+324.464 151.173 Td
+(destLen) 41.8429 Tj
+[1 0 0 1 366.307 151.172] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -366.307 -151.172] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+370.081 151.172 Td
+/F130_0 9.9626 Tf
+(is) 6.64505 Tj
+-379 TJm
+(set) 11.0684 Tj
+-379 TJm
+(to) 7.7509 Tj
+-378 TJm
+(the) 12.1743 Tj
+-379 TJm
+(size) 15.4918 Tj
+-379 TJm
+(of) 8.29885 Tj
+-379 TJm
+(the) 12.1743 Tj
+-379 TJm
+(compressed) 47.0334 Tj
+-379 TJm
+(data,) 19.0883 Tj
+72 139.217 Td
+(and) 14.386 Tj
+[1 0 0 1 89.5273 139.217] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -89.5273 -139.217] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+89.5273 139.217 Td
+/F134_0 9.9626 Tf
+(BZ_OK) 29.8878 Tj
+[1 0 0 1 119.415 139.217] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -119.415 -139.217] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+122.556 139.217 Td
+/F130_0 9.9626 Tf
+(is) 6.64505 Tj
+-315 TJm
+(returned.) 35.686 Tj
+-1012 TJm
+(If) 6.63509 Tj
+-315 TJm
+(the) 12.1743 Tj
+-316 TJm
+(compressed) 47.0334 Tj
+-315 TJm
+(data) 16.5977 Tj
+-315 TJm
+(w) 7.193 Tj
+10 TJm
+(on') 13.2801 Tj
+18 TJm
+(t) 2.7696 Tj
+-316 TJm
+(\002t,) 10.7995 Tj
+[1 0 0 1 313.322 139.217] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -313.322 -139.217] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+313.322 137.474 Td
+/F134_0 9.9626 Tf
+(*) 5.97756 Tj
+319.3 139.217 Td
+(destLen) 41.8429 Tj
+[1 0 0 1 361.143 139.217] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -361.143 -139.217] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+364.284 139.217 Td
+/F130_0 9.9626 Tf
+(is) 6.64505 Tj
+-315 TJm
+(unchanged,) 45.6486 Tj
+-332 TJm
+(and) 14.386 Tj
+[1 0 0 1 440.551 139.217] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -440.551 -139.217] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+440.551 139.217 Td
+/F134_0 9.9626 Tf
+(BZ_OUTBUFF_FULL) 89.6634 Tj
+[1 0 0 1 530.215 139.217] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -530.215 -139.217] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+533.355 139.217 Td
+/F130_0 9.9626 Tf
+(is) 6.64505 Tj
+72 127.262 Td
+(returned.) 35.686 Tj
+[1 0 0 1 72 127.163] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -117.2] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 105.344 Td
+/F130_0 9.9626 Tf
+(Compression) 52.5826 Tj
+-297 TJm
+(in) 7.7509 Tj
+-297 TJm
+(this) 14.396 Tj
+-297 TJm
+(manner) 29.8778 Tj
+-297 TJm
+(is) 6.64505 Tj
+-297 TJm
+(a) 4.42339 Tj
+-297 TJm
+(one-shot) 34.3112 Tj
+-297 TJm
+(e) 4.42339 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(ent,) 14.6649 Tj
+-309 TJm
+(done) 19.3673 Tj
+-297 TJm
+(with) 17.7135 Tj
+-297 TJm
+(a) 4.42339 Tj
+-297 TJm
+(single) 23.8007 Tj
+-297 TJm
+(call) 14.386 Tj
+-297 TJm
+(to) 7.7509 Tj
+-297 TJm
+(this) 14.396 Tj
+-297 TJm
+(function.) 35.696 Tj
+-903 TJm
+(The) 15.4918 Tj
+-297 TJm
+(resulting) 34.8691 Tj
+-297 TJm
+(compressed) 47.0334 Tj
+72 93.3892 Td
+(data) 16.5977 Tj
+-296 TJm
+(is) 6.64505 Tj
+-296 TJm
+(a) 4.42339 Tj
+-296 TJm
+(complete) 36.5229 Tj
+[1 0 0 1 147.988 93.3892] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -147.988 -93.3892] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+147.988 93.3892 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 177.875 93.3892] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -177.875 -93.3892] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+180.825 93.3892 Td
+/F130_0 9.9626 Tf
+(format) 26.5603 Tj
+-296 TJm
+(data) 16.5977 Tj
+-296 TJm
+(stream.) 29.0509 Tj
+-897 TJm
+(There) 23.2328 Tj
+-296 TJm
+(is) 6.64505 Tj
+-296 TJm
+(no) 9.9626 Tj
+-296 TJm
+(mechanism) 45.3796 Tj
+-296 TJm
+(for) 11.6164 Tj
+-296 TJm
+(making) 29.8878 Tj
+-296 TJm
+(additional) 39.8504 Tj
+-296 TJm
+(calls) 18.2614 Tj
+-296 TJm
+(to) 7.7509 Tj
+-296 TJm
+(pro) 13.2801 Tj
+15 TJm
+(vide) 17.1556 Tj
+-296 TJm
+(e) 4.42339 Tj
+15 TJm
+(xtra) 15.4918 Tj
+72 81.434 Td
+(input) 20.4831 Tj
+-250 TJm
+(data.) 19.0883 Tj
+-620 TJm
+(If) 6.63509 Tj
+-250 TJm
+(you) 14.9439 Tj
+-250 TJm
+(w) 7.193 Tj
+10 TJm
+(ant) 12.1743 Tj
+-250 TJm
+(that) 14.9439 Tj
+-250 TJm
+(kind) 17.7135 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(mechanism,) 47.8703 Tj
+-250 TJm
+(use) 13.2801 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(lo) 7.7509 Tj
+25 TJm
+(w-le) 17.7035 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(el) 7.193 Tj
+-250 TJm
+(interf) 21.579 Tj
+10 TJm
+(ace.) 15.7608 Tj
+[1 0 0 1 72 79.2772] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -28.4254] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 374.394 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 6.8541] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 40.5726 -6.7545] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -493.841 -50.9514] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+534.414 50.9514 Td
+/F130_0 9.9626 Tf
+(26) 9.9626 Tj
+[1 0 0 1 453.269 50.8518] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 93.5985 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.2765 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+Q
+showpage
+%%PageTrailer
+pdfEndPage
+%%Page: 30 30
+%%BeginPageSetup
+%%PageOrientation: Portrait
+pdfStartPage
+0 0 612 792 re W
+%%EndPageSetup
+[] 0 d
+1 i
+0 j
+0 J
+10 M
+1 w
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+false op
+false OP
+0 0 612 792 re
+W
+q
+[1 0 0 1 72 741.554] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 14.4459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 187.197 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 -8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 76.4979 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -342.569 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+419.067 749.245 Td
+/F130_0 9.9626 Tf
+(Programming) 54.7943 Tj
+-250 TJm
+(with) 17.7135 Tj
+[1 0 0 1 496.556 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -496.556 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+496.556 749.245 Td
+/F134_0 9.9626 Tf
+(libbzip2) 47.8205 Tj
+[1 0 0 1 544.376 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -278.305 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 280.796 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -472.974 -5.0363] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -0.4981] cm
+q
+[] 0 d
+0 J
+0.4981 w
+0 0.2491 m
+475.465 0.2491 l
+S
+Q
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 479.251 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -21.5542] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -720] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 710.037 Td
+/F130_0 9.9626 Tf
+(F) 5.53921 Tj
+15 TJm
+(or) 8.29885 Tj
+-223 TJm
+(the) 12.1743 Tj
+-224 TJm
+(meaning) 34.3112 Tj
+-223 TJm
+(of) 8.29885 Tj
+-224 TJm
+(parameters) 43.7059 Tj
+[1 0 0 1 195.306 710.037] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -195.306 -710.037] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+195.306 710.037 Td
+/F134_0 9.9626 Tf
+(blockSize100k) 77.7083 Tj
+[1 0 0 1 273.015 710.037] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -273.015 -710.037] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+273.015 710.037 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 277.784 710.037] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -277.784 -710.037] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+277.784 710.037 Td
+/F134_0 9.9626 Tf
+(verbosity) 53.798 Tj
+[1 0 0 1 331.583 710.037] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -331.583 -710.037] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+333.808 710.037 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 350.42 710.037] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -350.42 -710.037] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+350.42 710.037 Td
+/F134_0 9.9626 Tf
+(workFactor) 59.7756 Tj
+[1 0 0 1 410.196 710.037] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -410.196 -710.037] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+410.196 710.037 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-229 TJm
+(see) 12.7222 Tj
+[1 0 0 1 429.913 710.037] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -429.913 -710.037] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+429.913 710.037 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompressInit) 107.596 Tj
+[1 0 0 1 537.509 710.037] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -537.509 -710.037] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+537.509 710.037 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+[1 0 0 1 72 707.88] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -697.918] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 688.12 Td
+/F130_0 9.9626 Tf
+(T) 6.08715 Tj
+80 TJm
+(o) 4.9813 Tj
+-410 TJm
+(guarantee) 38.7246 Tj
+-410 TJm
+(that) 14.9439 Tj
+-410 TJm
+(the) 12.1743 Tj
+-410 TJm
+(compressed) 47.0334 Tj
+-410 TJm
+(data) 16.5977 Tj
+-410 TJm
+(will) 15.5018 Tj
+-410 TJm
+(\002t) 8.30881 Tj
+-410 TJm
+(in) 7.7509 Tj
+-410 TJm
+(its) 9.41466 Tj
+-410 TJm
+(b) 4.9813 Tj
+20 TJm
+(uf) 8.29885 Tj
+25 TJm
+(fer) 11.0585 Tj
+40 TJm
+(,) 2.49065 Tj
+-450 TJm
+(allocate) 30.9837 Tj
+-410 TJm
+(an) 9.40469 Tj
+-410 TJm
+(output) 25.4644 Tj
+-410 TJm
+(b) 4.9813 Tj
+20 TJm
+(uf) 8.29885 Tj
+25 TJm
+(fer) 11.0585 Tj
+-411 TJm
+(of) 8.29885 Tj
+-410 TJm
+(size) 15.4918 Tj
+-410 TJm
+(1%) 13.2801 Tj
+-410 TJm
+(lar) 10.5105 Tj
+18 TJm
+(ger) 12.7222 Tj
+-410 TJm
+(than) 17.1556 Tj
+-410 TJm
+(the) 12.1743 Tj
+72 676.164 Td
+(uncompressed) 56.996 Tj
+-250 TJm
+(data,) 19.0883 Tj
+-250 TJm
+(plus) 16.6077 Tj
+-250 TJm
+(six) 11.6264 Tj
+-250 TJm
+(hundred) 32.6474 Tj
+-250 TJm
+(e) 4.42339 Tj
+15 TJm
+(xtra) 15.4918 Tj
+-250 TJm
+(bytes.) 23.5217 Tj
+[1 0 0 1 72 674.007] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -664.045] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 654.247 Td
+/F134_0 9.9626 Tf
+(BZ2_bzBuffToBuffDecompress) 155.417 Tj
+[1 0 0 1 227.417 654.247] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -227.417 -654.247] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+230.553 654.247 Td
+/F130_0 9.9626 Tf
+(will) 15.5018 Tj
+-315 TJm
+(not) 12.7322 Tj
+-315 TJm
+(write) 20.4731 Tj
+-314 TJm
+(data) 16.5977 Tj
+-315 TJm
+(at) 7.193 Tj
+-315 TJm
+(or) 8.29885 Tj
+-315 TJm
+(be) 9.40469 Tj
+15 TJm
+(yond) 19.9252 Tj
+[1 0 0 1 362.484 654.247] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -362.484 -654.247] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+362.484 654.247 Td
+/F134_0 9.9626 Tf
+(dest[) 29.8878 Tj
+392.372 652.503 Td
+(*) 5.97756 Tj
+398.349 654.247 Td
+(destLen]) 47.8205 Tj
+[1 0 0 1 446.17 654.247] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -446.17 -654.247] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+446.17 654.247 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-331 TJm
+(e) 4.42339 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(en) 9.40469 Tj
+-315 TJm
+(in) 7.7509 Tj
+-315 TJm
+(case) 17.1456 Tj
+-314 TJm
+(of) 8.29885 Tj
+-315 TJm
+(b) 4.9813 Tj
+20 TJm
+(uf) 8.29885 Tj
+25 TJm
+(fer) 11.0585 Tj
+72 642.291 Td
+(o) 4.9813 Tj
+15 TJm
+(v) 4.9813 Tj
+15 TJm
+(er\003o) 18.2614 Tj
+25 TJm
+(w) 7.193 Tj
+65 TJm
+(.) 2.49065 Tj
+[1 0 0 1 72 642.192] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -632.229] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 620.374 Td
+/F130_0 9.9626 Tf
+(Possible) 33.2153 Tj
+-250 TJm
+(return) 23.7907 Tj
+-250 TJm
+(v) 4.9813 Tj
+25 TJm
+(alues:) 23.2427 Tj
+[1 0 0 1 72 620.274] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -168.369] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 167.372 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 163.786] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -610.909] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 610.909 Td
+/F134_0 9.9626 Tf
+(BZ_CONFIG_ERROR) 89.6634 Tj
+98.4879 598.954 Td
+(if) 11.9551 Tj
+-426 TJm
+(the) 17.9327 Tj
+-426 TJm
+(library) 41.8429 Tj
+-426 TJm
+(has) 17.9327 Tj
+-426 TJm
+(been) 23.9102 Tj
+-426 TJm
+(mis-compiled) 71.7307 Tj
+90 586.999 Td
+(BZ_PARAM_ERROR) 83.6858 Tj
+98.4879 575.044 Td
+(if) 11.9551 Tj
+-426 TJm
+(dest) 23.9102 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(NULL) 23.9102 Tj
+-426 TJm
+(or) 11.9551 Tj
+-426 TJm
+(destLen) 41.8429 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(NULL) 23.9102 Tj
+98.4879 563.088 Td
+(or) 11.9551 Tj
+-426 TJm
+(blockSize100k) 77.7083 Tj
+-426 TJm
+(<) 5.97756 Tj
+-426 TJm
+(1) 5.97756 Tj
+-426 TJm
+(or) 11.9551 Tj
+-426 TJm
+(blockSize100k) 77.7083 Tj
+-426 TJm
+(>) 5.97756 Tj
+-426 TJm
+(9) 5.97756 Tj
+98.4879 551.133 Td
+(or) 11.9551 Tj
+-426 TJm
+(verbosity) 53.798 Tj
+-426 TJm
+(<) 5.97756 Tj
+-426 TJm
+(0) 5.97756 Tj
+-426 TJm
+(or) 11.9551 Tj
+-426 TJm
+(verbosity) 53.798 Tj
+-426 TJm
+(>) 5.97756 Tj
+-426 TJm
+(4) 5.97756 Tj
+98.4879 539.178 Td
+(or) 11.9551 Tj
+-426 TJm
+(workFactor) 59.7756 Tj
+-426 TJm
+(<) 5.97756 Tj
+-426 TJm
+(0) 5.97756 Tj
+-426 TJm
+(or) 11.9551 Tj
+-426 TJm
+(workFactor) 59.7756 Tj
+-426 TJm
+(>) 5.97756 Tj
+-426 TJm
+(250) 17.9327 Tj
+90 527.223 Td
+(BZ_MEM_ERROR) 71.7307 Tj
+98.4879 515.268 Td
+(if) 11.9551 Tj
+-426 TJm
+(insufficient) 71.7307 Tj
+-426 TJm
+(memory) 35.8654 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(available) 53.798 Tj
+90 503.313 Td
+(BZ_OUTBUFF_FULL) 89.6634 Tj
+98.4879 491.357 Td
+(if) 11.9551 Tj
+-426 TJm
+(the) 17.9327 Tj
+-426 TJm
+(size) 23.9102 Tj
+-426 TJm
+(of) 11.9551 Tj
+-426 TJm
+(the) 17.9327 Tj
+-426 TJm
+(compressed) 59.7756 Tj
+-426 TJm
+(data) 23.9102 Tj
+-426 TJm
+(exceeds) 41.8429 Tj
+341.655 489.614 Td
+(*) 5.97756 Tj
+347.633 491.357 Td
+(destLen) 41.8429 Tj
+90 479.402 Td
+(BZ_OK) 29.8878 Tj
+98.4879 467.447 Td
+(otherwise) 53.798 Tj
+[1 0 0 1 72 451.905] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -441.943] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 421.284 Td
+/F122_0 17.2154 Tf
+(3.5.2.) 43.0729 Tj
+[1 0 0 1 119.858 421.284] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -119.858 -421.284] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+119.858 421.284 Td
+/F392_0 17.2154 Tf
+(BZ2_bzBuffToBuffDecompress) 268.56 Tj
+[1 0 0 1 388.419 421.284] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -316.419 -2.3327] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -84.6824] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 83.6862 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 80.0996] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -409.587] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 409.587 Td
+/F134_0 9.9626 Tf
+(int) 17.9327 Tj
+-426 TJm
+(BZ2_bzBuffToBuffDecompress\() 161.394 Tj
+-426 TJm
+(char) 23.9102 Tj
+301.726 407.843 Td
+(*) 5.97756 Tj
+345.899 409.587 Td
+(dest,) 29.8878 Tj
+225.807 397.632 Td
+(unsigned) 47.8205 Tj
+-426 TJm
+(int) 17.9327 Tj
+295.805 395.888 Td
+(*) 5.97756 Tj
+306.026 397.632 Td
+(destLen,) 47.8205 Tj
+225.807 385.676 Td
+(char) 23.9102 Tj
+249.718 383.933 Td
+(*) 5.97756 Tj
+293.891 385.676 Td
+(source,) 41.8429 Tj
+225.807 373.721 Td
+(unsigned) 47.8205 Tj
+-426 TJm
+(int) 17.9327 Tj
+-852 TJm
+(sourceLen,) 59.7756 Tj
+225.807 361.766 Td
+(int) 17.9327 Tj
+-4686 TJm
+(small,) 35.8654 Tj
+225.807 349.811 Td
+(int) 17.9327 Tj
+-4686 TJm
+(verbosity) 53.798 Tj
+-426 TJm
+(\);) 11.9551 Tj
+[1 0 0 1 72 334.269] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.5492] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -324.306] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 312.351 Td
+/F130_0 9.9626 Tf
+(Attempts) 36.5329 Tj
+-358 TJm
+(to) 7.7509 Tj
+-359 TJm
+(decompress) 47.0334 Tj
+-358 TJm
+(the) 12.1743 Tj
+-358 TJm
+(data) 16.5977 Tj
+-359 TJm
+(in) 7.7509 Tj
+[1 0 0 1 221.259 312.351] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -221.259 -312.351] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+221.259 312.351 Td
+/F134_0 9.9626 Tf
+(source[0) 47.8205 Tj
+-600 TJm
+(..) 11.9551 Tj
+-1200 TJm
+(sourceLen-1]) 71.7307 Tj
+[1 0 0 1 370.698 312.351] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -370.698 -312.351] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+374.268 312.351 Td
+/F130_0 9.9626 Tf
+(into) 15.5018 Tj
+-358 TJm
+(the) 12.1743 Tj
+-359 TJm
+(destination) 43.7259 Tj
+-358 TJm
+(b) 4.9813 Tj
+20 TJm
+(uf) 8.29885 Tj
+25 TJm
+(fer) 11.0585 Tj
+40 TJm
+(,) 2.49065 Tj
+[1 0 0 1 486.202 312.351] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -486.202 -312.351] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+486.202 312.351 Td
+/F134_0 9.9626 Tf
+(dest[0) 35.8654 Tj
+-600 TJm
+(..) 11.9551 Tj
+72 298.653 Td
+(*) 5.97756 Tj
+77.9776 300.396 Td
+(destLen-1]) 59.7756 Tj
+[1 0 0 1 137.753 300.396] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -137.753 -300.396] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+137.753 300.396 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+-1123 TJm
+(If) 6.63509 Tj
+-334 TJm
+(the) 12.1743 Tj
+-334 TJm
+(destination) 43.7259 Tj
+-334 TJm
+(b) 4.9813 Tj
+20 TJm
+(uf) 8.29885 Tj
+25 TJm
+(fer) 11.0585 Tj
+-334 TJm
+(is) 6.64505 Tj
+-334 TJm
+(big) 12.7322 Tj
+-334 TJm
+(enough,) 31.8205 Tj
+[1 0 0 1 312.554 300.396] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -312.554 -300.396] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+312.554 298.653 Td
+/F134_0 9.9626 Tf
+(*) 5.97756 Tj
+318.531 300.396 Td
+(destLen) 41.8429 Tj
+[1 0 0 1 360.374 300.396] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -360.374 -300.396] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+363.701 300.396 Td
+/F130_0 9.9626 Tf
+(is) 6.64505 Tj
+-334 TJm
+(set) 11.0684 Tj
+-334 TJm
+(to) 7.7509 Tj
+-334 TJm
+(the) 12.1743 Tj
+-334 TJm
+(size) 15.4918 Tj
+-333 TJm
+(of) 8.29885 Tj
+-334 TJm
+(the) 12.1743 Tj
+-334 TJm
+(uncompressed) 56.996 Tj
+-334 TJm
+(data,) 19.0883 Tj
+72 288.441 Td
+(and) 14.386 Tj
+[1 0 0 1 89.5273 288.441] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -89.5273 -288.441] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+89.5273 288.441 Td
+/F134_0 9.9626 Tf
+(BZ_OK) 29.8878 Tj
+[1 0 0 1 119.415 288.441] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -119.415 -288.441] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+122.556 288.441 Td
+/F130_0 9.9626 Tf
+(is) 6.64505 Tj
+-315 TJm
+(returned.) 35.686 Tj
+-1012 TJm
+(If) 6.63509 Tj
+-315 TJm
+(the) 12.1743 Tj
+-316 TJm
+(compressed) 47.0334 Tj
+-315 TJm
+(data) 16.5977 Tj
+-315 TJm
+(w) 7.193 Tj
+10 TJm
+(on') 13.2801 Tj
+18 TJm
+(t) 2.7696 Tj
+-316 TJm
+(\002t,) 10.7995 Tj
+[1 0 0 1 313.322 288.441] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -313.322 -288.441] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+313.322 286.698 Td
+/F134_0 9.9626 Tf
+(*) 5.97756 Tj
+319.3 288.441 Td
+(destLen) 41.8429 Tj
+[1 0 0 1 361.143 288.441] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -361.143 -288.441] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+364.284 288.441 Td
+/F130_0 9.9626 Tf
+(is) 6.64505 Tj
+-315 TJm
+(unchanged,) 45.6486 Tj
+-332 TJm
+(and) 14.386 Tj
+[1 0 0 1 440.551 288.441] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -440.551 -288.441] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+440.551 288.441 Td
+/F134_0 9.9626 Tf
+(BZ_OUTBUFF_FULL) 89.6634 Tj
+[1 0 0 1 530.215 288.441] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -530.215 -288.441] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+533.355 288.441 Td
+/F130_0 9.9626 Tf
+(is) 6.64505 Tj
+72 276.486 Td
+(returned.) 35.686 Tj
+[1 0 0 1 72 276.386] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -266.424] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 254.568 Td
+/F134_0 9.9626 Tf
+(source) 35.8654 Tj
+[1 0 0 1 107.865 254.568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -107.865 -254.568] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+110.981 254.568 Td
+/F130_0 9.9626 Tf
+(is) 6.64505 Tj
+-313 TJm
+(assumed) 34.3112 Tj
+-312 TJm
+(to) 7.7509 Tj
+-313 TJm
+(hold) 17.7135 Tj
+-313 TJm
+(a) 4.42339 Tj
+-313 TJm
+(complete) 36.5229 Tj
+[1 0 0 1 237.04 254.568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -237.04 -254.568] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+237.04 254.568 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 266.928 254.568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -266.928 -254.568] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+270.044 254.568 Td
+/F130_0 9.9626 Tf
+(format) 26.5603 Tj
+-313 TJm
+(data) 16.5977 Tj
+-312 TJm
+(stream.) 29.0509 Tj
+[1 0 0 1 353.446 254.568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -353.446 -254.568] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+353.446 254.568 Td
+/F134_0 9.9626 Tf
+(BZ2_bzBuffToBuffDecompress) 155.417 Tj
+[1 0 0 1 508.863 254.568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -508.863 -254.568] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+511.978 254.568 Td
+/F130_0 9.9626 Tf
+(tries) 17.1556 Tj
+-313 TJm
+(to) 7.7509 Tj
+72 242.613 Td
+(decompress) 47.0334 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(entirety) 30.4357 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(stream) 26.5603 Tj
+-250 TJm
+(into) 15.5018 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(output) 25.4644 Tj
+-250 TJm
+(b) 4.9813 Tj
+20 TJm
+(uf) 8.29885 Tj
+25 TJm
+(fer) 11.0585 Tj
+55 TJm
+(.) 2.49065 Tj
+[1 0 0 1 72 240.456] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -230.493] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 220.695 Td
+/F130_0 9.9626 Tf
+(F) 5.53921 Tj
+15 TJm
+(or) 8.29885 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(meaning) 34.3112 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(parameters) 43.7059 Tj
+[1 0 0 1 196.631 220.695] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -196.631 -220.695] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+196.631 220.695 Td
+/F134_0 9.9626 Tf
+(small) 29.8878 Tj
+[1 0 0 1 226.519 220.695] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -226.519 -220.695] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+229.01 220.695 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 245.887 220.695] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -245.887 -220.695] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+245.887 220.695 Td
+/F134_0 9.9626 Tf
+(verbosity) 53.798 Tj
+[1 0 0 1 299.685 220.695] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -299.685 -220.695] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+299.685 220.695 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-250 TJm
+(see) 12.7222 Tj
+[1 0 0 1 319.879 220.695] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -319.879 -220.695] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+319.879 220.695 Td
+/F134_0 9.9626 Tf
+(BZ2_bzDecompressInit) 119.551 Tj
+[1 0 0 1 439.431 220.695] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -439.431 -220.695] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+439.431 220.695 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+[1 0 0 1 72 218.538] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -208.576] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 198.777 Td
+/F130_0 9.9626 Tf
+(Because) 33.1954 Tj
+-250 TJm
+(the) 12.1743 Tj
+-249 TJm
+(compression) 50.3609 Tj
+-250 TJm
+(ratio) 18.2614 Tj
+-249 TJm
+(of) 8.29885 Tj
+-250 TJm
+(the) 12.1743 Tj
+-249 TJm
+(compressed) 47.0334 Tj
+-250 TJm
+(data) 16.5977 Tj
+-249 TJm
+(cannot) 26.5603 Tj
+-250 TJm
+(be) 9.40469 Tj
+-250 TJm
+(kno) 14.9439 Tj
+25 TJm
+(wn) 12.1743 Tj
+-249 TJm
+(in) 7.7509 Tj
+-250 TJm
+(adv) 14.386 Tj
+25 TJm
+(ance,) 20.7421 Tj
+-249 TJm
+(there) 19.9152 Tj
+-250 TJm
+(is) 6.64505 Tj
+-249 TJm
+(no) 9.9626 Tj
+-250 TJm
+(easy) 17.7035 Tj
+-250 TJm
+(w) 7.193 Tj
+10 TJm
+(ay) 9.40469 Tj
+-249 TJm
+(to) 7.7509 Tj
+-250 TJm
+(guarantee) 38.7246 Tj
+72 186.822 Td
+(that) 14.9439 Tj
+-286 TJm
+(the) 12.1743 Tj
+-287 TJm
+(output) 25.4644 Tj
+-286 TJm
+(b) 4.9813 Tj
+20 TJm
+(uf) 8.29885 Tj
+25 TJm
+(fer) 11.0585 Tj
+-287 TJm
+(will) 15.5018 Tj
+-286 TJm
+(be) 9.40469 Tj
+-286 TJm
+(big) 12.7322 Tj
+-287 TJm
+(enough.) 31.8205 Tj
+-838 TJm
+(Y) 7.193 Tj
+110 TJm
+(ou) 9.9626 Tj
+-287 TJm
+(may) 17.1556 Tj
+-286 TJm
+(of) 8.29885 Tj
+-287 TJm
+(course) 26.0024 Tj
+-286 TJm
+(mak) 17.1556 Tj
+10 TJm
+(e) 4.42339 Tj
+-286 TJm
+(arrangements) 53.6685 Tj
+-287 TJm
+(in) 7.7509 Tj
+-286 TJm
+(your) 18.2614 Tj
+-287 TJm
+(code) 18.8094 Tj
+-286 TJm
+(to) 7.7509 Tj
+-286 TJm
+(record) 25.4445 Tj
+-287 TJm
+(the) 12.1743 Tj
+-286 TJm
+(size) 15.4918 Tj
+-287 TJm
+(of) 8.29885 Tj
+72 174.867 Td
+(the) 12.1743 Tj
+-250 TJm
+(uncompressed) 56.996 Tj
+-250 TJm
+(data,) 19.0883 Tj
+-250 TJm
+(b) 4.9813 Tj
+20 TJm
+(ut) 7.7509 Tj
+-250 TJm
+(such) 18.2614 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(mechanism) 45.3796 Tj
+-250 TJm
+(is) 6.64505 Tj
+-250 TJm
+(be) 9.40469 Tj
+15 TJm
+(yond) 19.9252 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(scope) 22.6848 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(this) 14.396 Tj
+-250 TJm
+(library) 26.5603 Tj
+65 TJm
+(.) 2.49065 Tj
+[1 0 0 1 72 172.71] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -162.747] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 152.949 Td
+/F134_0 9.9626 Tf
+(BZ2_bzBuffToBuffDecompress) 155.417 Tj
+[1 0 0 1 227.417 152.949] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -227.417 -152.949] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+230.553 152.949 Td
+/F130_0 9.9626 Tf
+(will) 15.5018 Tj
+-315 TJm
+(not) 12.7322 Tj
+-315 TJm
+(write) 20.4731 Tj
+-314 TJm
+(data) 16.5977 Tj
+-315 TJm
+(at) 7.193 Tj
+-315 TJm
+(or) 8.29885 Tj
+-315 TJm
+(be) 9.40469 Tj
+15 TJm
+(yond) 19.9252 Tj
+[1 0 0 1 362.484 152.949] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -362.484 -152.949] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+362.484 152.949 Td
+/F134_0 9.9626 Tf
+(dest[) 29.8878 Tj
+392.372 151.206 Td
+(*) 5.97756 Tj
+398.349 152.949 Td
+(destLen]) 47.8205 Tj
+[1 0 0 1 446.17 152.949] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -446.17 -152.949] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+446.17 152.949 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-331 TJm
+(e) 4.42339 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(en) 9.40469 Tj
+-315 TJm
+(in) 7.7509 Tj
+-315 TJm
+(case) 17.1456 Tj
+-314 TJm
+(of) 8.29885 Tj
+-315 TJm
+(b) 4.9813 Tj
+20 TJm
+(uf) 8.29885 Tj
+25 TJm
+(fer) 11.0585 Tj
+72 140.994 Td
+(o) 4.9813 Tj
+15 TJm
+(v) 4.9813 Tj
+15 TJm
+(er\003o) 18.2614 Tj
+25 TJm
+(w) 7.193 Tj
+65 TJm
+(.) 2.49065 Tj
+[1 0 0 1 72 140.894] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -130.932] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 119.076 Td
+/F130_0 9.9626 Tf
+(Possible) 33.2153 Tj
+-250 TJm
+(return) 23.7907 Tj
+-250 TJm
+(v) 4.9813 Tj
+25 TJm
+(alues:) 23.2427 Tj
+[1 0 0 1 72 118.977] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -68.1248] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 374.394 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 6.8541] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 40.5726 -6.7545] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -493.841 -50.9514] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+534.414 50.9514 Td
+/F130_0 9.9626 Tf
+(27) 9.9626 Tj
+[1 0 0 1 453.269 50.8518] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 93.5985 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.2765 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+Q
+showpage
+%%PageTrailer
+pdfEndPage
+%%Page: 31 31
+%%BeginPageSetup
+%%PageOrientation: Portrait
+pdfStartPage
+0 0 612 792 re W
+%%EndPageSetup
+[] 0 d
+1 i
+0 j
+0 J
+10 M
+1 w
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+false op
+false OP
+0 0 612 792 re
+W
+q
+[1 0 0 1 72 741.554] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 4.3836 14.4459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 187.197 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 -8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 76.4979 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -344.462 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+420.96 749.245 Td
+/F130_0 9.9626 Tf
+(Programming) 54.7943 Tj
+-250 TJm
+(with) 17.7135 Tj
+[1 0 0 1 498.449 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -498.449 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+498.449 749.245 Td
+/F134_0 9.9626 Tf
+(libbzip2) 47.8205 Tj
+[1 0 0 1 546.269 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -278.305 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 280.796 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -472.974 -5.0363] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -0.4981] cm
+q
+[] 0 d
+0 J
+0.4981 w
+0 0.2491 m
+475.465 0.2491 l
+S
+Q
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 479.251 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -15.0365 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -248.702] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 227.148 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 223.562] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -711.631] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 711.631 Td
+/F134_0 9.9626 Tf
+(BZ_CONFIG_ERROR) 89.6634 Tj
+98.4879 699.676 Td
+(if) 11.9551 Tj
+-426 TJm
+(the) 17.9327 Tj
+-426 TJm
+(library) 41.8429 Tj
+-426 TJm
+(has) 17.9327 Tj
+-426 TJm
+(been) 23.9102 Tj
+-426 TJm
+(mis-compiled) 71.7307 Tj
+90 687.721 Td
+(BZ_PARAM_ERROR) 83.6858 Tj
+98.4879 675.766 Td
+(if) 11.9551 Tj
+-426 TJm
+(dest) 23.9102 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(NULL) 23.9102 Tj
+-426 TJm
+(or) 11.9551 Tj
+-426 TJm
+(destLen) 41.8429 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(NULL) 23.9102 Tj
+98.4879 663.811 Td
+(or) 11.9551 Tj
+-426 TJm
+(small) 29.8878 Tj
+-426 TJm
+(!=) 11.9551 Tj
+-426 TJm
+(0) 5.97756 Tj
+-426 TJm
+(&&) 11.9551 Tj
+-426 TJm
+(small) 29.8878 Tj
+-426 TJm
+(!=) 11.9551 Tj
+-426 TJm
+(1) 5.97756 Tj
+98.4879 651.856 Td
+(or) 11.9551 Tj
+-426 TJm
+(verbosity) 53.798 Tj
+-426 TJm
+(<) 5.97756 Tj
+-426 TJm
+(0) 5.97756 Tj
+-426 TJm
+(or) 11.9551 Tj
+-426 TJm
+(verbosity) 53.798 Tj
+-426 TJm
+(>) 5.97756 Tj
+-426 TJm
+(4) 5.97756 Tj
+90 639.9 Td
+(BZ_MEM_ERROR) 71.7307 Tj
+98.4879 627.945 Td
+(if) 11.9551 Tj
+-426 TJm
+(insufficient) 71.7307 Tj
+-426 TJm
+(memory) 35.8654 Tj
+-426 TJm
+(is) 11.9551 Tj
+-426 TJm
+(available) 53.798 Tj
+90 615.99 Td
+(BZ_OUTBUFF_FULL) 89.6634 Tj
+98.4879 604.035 Td
+(if) 11.9551 Tj
+-426 TJm
+(the) 17.9327 Tj
+-426 TJm
+(size) 23.9102 Tj
+-426 TJm
+(of) 11.9551 Tj
+-426 TJm
+(the) 17.9327 Tj
+-426 TJm
+(compressed) 59.7756 Tj
+-426 TJm
+(data) 23.9102 Tj
+-426 TJm
+(exceeds) 41.8429 Tj
+341.655 602.291 Td
+(*) 5.97756 Tj
+347.633 604.035 Td
+(destLen) 41.8429 Tj
+90 592.08 Td
+(BZ_DATA_ERROR) 77.7083 Tj
+98.4879 580.125 Td
+(if) 11.9551 Tj
+-426 TJm
+(a) 5.97756 Tj
+-426 TJm
+(data) 23.9102 Tj
+-426 TJm
+(integrity) 53.798 Tj
+-426 TJm
+(error) 29.8878 Tj
+-426 TJm
+(was) 17.9327 Tj
+-426 TJm
+(detected) 47.8205 Tj
+-426 TJm
+(in) 11.9551 Tj
+-426 TJm
+(the) 17.9327 Tj
+-426 TJm
+(compressed) 59.7756 Tj
+-426 TJm
+(data) 23.9102 Tj
+90 568.169 Td
+(BZ_DATA_ERROR_MAGIC) 113.574 Tj
+98.4879 556.214 Td
+(if) 11.9551 Tj
+-426 TJm
+(the) 17.9327 Tj
+-426 TJm
+(compressed) 59.7756 Tj
+-426 TJm
+(data) 23.9102 Tj
+-426 TJm
+(doesn't) 41.8429 Tj
+-426 TJm
+(begin) 29.8878 Tj
+-426 TJm
+(with) 23.9102 Tj
+-426 TJm
+(the) 17.9327 Tj
+-426 TJm
+(right) 29.8878 Tj
+-426 TJm
+(magic) 29.8878 Tj
+-426 TJm
+(bytes) 29.8878 Tj
+90 544.259 Td
+(BZ_UNEXPECTED_EOF) 101.619 Tj
+98.4879 532.304 Td
+(if) 11.9551 Tj
+-426 TJm
+(the) 17.9327 Tj
+-426 TJm
+(compressed) 59.7756 Tj
+-426 TJm
+(data) 23.9102 Tj
+-426 TJm
+(ends) 23.9102 Tj
+-426 TJm
+(unexpectedly) 71.7307 Tj
+90 520.349 Td
+(BZ_OK) 29.8878 Tj
+98.4879 508.394 Td
+(otherwise) 53.798 Tj
+[1 0 0 1 72 492.852] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -482.889] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 458.099 Td
+/F122_0 20.6585 Tf
+(3.6.) 34.4584 Tj
+[1 0 0 1 112.201 458.099] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -112.201 -458.099] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+112.201 458.099 Td
+/F392_0 20.6585 Tf
+(zlib) 49.5804 Tj
+[1 0 0 1 161.781 458.099] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -161.781 -458.099] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+167.524 458.099 Td
+/F122_0 20.6585 Tf
+(compatibility) 127.422 Tj
+-278 TJm
+(functions) 92.9633 Tj
+[1 0 0 1 72 453.823] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -443.86] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 436.181 Td
+/F130_0 9.9626 Tf
+(Y) 7.193 Tj
+110 TJm
+(oshioka) 30.9936 Tj
+-604 TJm
+(Tsuneo) 29.3299 Tj
+-604 TJm
+(has) 13.2801 Tj
+-604 TJm
+(contrib) 28.224 Tj
+20 TJm
+(uted) 17.1556 Tj
+-604 TJm
+(some) 21.031 Tj
+-604 TJm
+(functions) 37.0808 Tj
+-604 TJm
+(to) 7.7509 Tj
+-604 TJm
+(gi) 7.7509 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-604 TJm
+(better) 22.6848 Tj
+[1 0 0 1 356.347 436.181] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -356.347 -436.181] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+356.347 436.181 Td
+/F134_0 9.9626 Tf
+(zlib) 23.9102 Tj
+[1 0 0 1 380.257 436.181] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -380.257 -436.181] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+386.275 436.181 Td
+/F130_0 9.9626 Tf
+(compatibility) 53.1405 Tj
+65 TJm
+(.) 2.49065 Tj
+-1372 TJm
+(These) 23.7907 Tj
+-604 TJm
+(functions) 37.0808 Tj
+-604 TJm
+(are) 12.1643 Tj
+[1 0 0 1 72 424.226] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -424.226] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 424.226 Td
+/F134_0 9.9626 Tf
+(BZ2_bzopen) 59.7756 Tj
+[1 0 0 1 131.776 424.226] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -131.776 -424.226] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+131.776 424.226 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 144.283 424.226] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -144.283 -424.226] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+144.283 424.226 Td
+/F134_0 9.9626 Tf
+(BZ2_bzread) 59.7756 Tj
+[1 0 0 1 204.059 424.226] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -204.059 -424.226] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+204.059 424.226 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 216.566 424.226] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -216.566 -424.226] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+216.566 424.226 Td
+/F134_0 9.9626 Tf
+(BZ2_bzwrite) 65.7532 Tj
+[1 0 0 1 282.32 424.226] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -282.32 -424.226] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+282.32 424.226 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 294.827 424.226] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -294.827 -424.226] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+294.827 424.226 Td
+/F134_0 9.9626 Tf
+(BZ2_bzflush) 65.7532 Tj
+[1 0 0 1 360.581 424.226] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -360.581 -424.226] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+360.581 424.226 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 373.088 424.226] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -373.088 -424.226] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+373.088 424.226 Td
+/F134_0 9.9626 Tf
+(BZ2_bzclose) 65.7532 Tj
+[1 0 0 1 438.842 424.226] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -438.842 -424.226] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+438.842 424.226 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 451.349 424.226] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -451.349 -424.226] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+451.349 424.226 Td
+/F134_0 9.9626 Tf
+(BZ2_bzerror) 65.7532 Tj
+[1 0 0 1 517.102 424.226] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -517.102 -424.226] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+525.614 424.226 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 72 412.271] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -412.271] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 412.271 Td
+/F134_0 9.9626 Tf
+(BZ2_bzlibVersion) 95.641 Tj
+[1 0 0 1 167.641 412.271] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -167.641 -412.271] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+167.641 412.271 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+-1420 TJm
+(Thes) 19.3673 Tj
+1 TJm
+(e) 4.42339 Tj
+-384 TJm
+(functions) 37.0808 Tj
+-383 TJm
+(are) 12.1643 Tj
+-383 TJm
+(not) 12.7322 Tj
+-383 TJm
+(\(yet\)) 18.8094 Tj
+-384 TJm
+(of) 8.29885 Tj
+25 TJm
+(\002cially) 27.6761 Tj
+-383 TJm
+(part) 15.4918 Tj
+-383 TJm
+(of) 8.29885 Tj
+-383 TJm
+(the) 12.1743 Tj
+-384 TJm
+(library) 26.5603 Tj
+65 TJm
+(.) 2.49065 Tj
+-1419 TJm
+(If) 6.63509 Tj
+-383 TJm
+(the) 12.1743 Tj
+15 TJm
+(y) 4.9813 Tj
+-384 TJm
+(break,) 24.6176 Tj
+-416 TJm
+(you) 14.9439 Tj
+-383 TJm
+(get) 12.1743 Tj
+-384 TJm
+(to) 7.7509 Tj
+72 400.316 Td
+(k) 4.9813 Tj
+10 TJm
+(eep) 13.8281 Tj
+-250 TJm
+(all) 9.9626 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(pieces.) 27.3872 Tj
+-620 TJm
+(Ne) 11.6164 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(ertheless,) 37.3498 Tj
+-250 TJm
+(I) 3.31755 Tj
+-250 TJm
+(think) 20.4831 Tj
+-250 TJm
+(the) 12.1743 Tj
+15 TJm
+(y) 4.9813 Tj
+-250 TJm
+(w) 7.193 Tj
+10 TJm
+(ork) 13.2801 Tj
+-250 TJm
+(ok.) 12.4533 Tj
+[1 0 0 1 72 398.159] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -48.8169] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 47.8207 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 44.2341] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -388.794] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 388.794 Td
+/F134_0 9.9626 Tf
+(typedef) 41.8429 Tj
+-426 TJm
+(void) 23.9102 Tj
+-426 TJm
+(BZFILE;) 41.8429 Tj
+90 364.884 Td
+(const) 29.8878 Tj
+-426 TJm
+(char) 23.9102 Tj
+152.286 363.14 Td
+(*) 5.97756 Tj
+162.508 364.884 Td
+(BZ2_bzlibVersion) 95.641 Tj
+-426 TJm
+(\() 5.97756 Tj
+-426 TJm
+(void) 23.9102 Tj
+-426 TJm
+(\);) 11.9551 Tj
+[1 0 0 1 72 349.342] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.5492] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -339.379] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 327.424 Td
+/F130_0 9.9626 Tf
+(Returns) 30.9936 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(string) 22.6948 Tj
+-250 TJm
+(indicating) 39.8504 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(library) 26.5603 Tj
+-250 TJm
+(v) 4.9813 Tj
+15 TJm
+(ersion.) 26.8392 Tj
+[1 0 0 1 72 325.267] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -36.8618] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 35.8655 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 32.2789] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -315.902] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 315.902 Td
+/F134_0 9.9626 Tf
+(BZFILE) 35.8654 Tj
+130.109 314.159 Td
+(*) 5.97756 Tj
+140.331 315.902 Td
+(BZ2_bzopen) 59.7756 Tj
+-852 TJm
+(\() 5.97756 Tj
+-426 TJm
+(const) 29.8878 Tj
+-426 TJm
+(char) 23.9102 Tj
+281.103 314.159 Td
+(*) 5.97756 Tj
+287.08 315.902 Td
+(path,) 29.8878 Tj
+-426 TJm
+(const) 29.8878 Tj
+-426 TJm
+(char) 23.9102 Tj
+383.498 314.159 Td
+(*) 5.97756 Tj
+389.476 315.902 Td
+(mode) 23.9102 Tj
+-426 TJm
+(\);) 11.9551 Tj
+90 303.947 Td
+(BZFILE) 35.8654 Tj
+130.109 302.204 Td
+(*) 5.97756 Tj
+140.331 303.947 Td
+(BZ2_bzdopen) 65.7532 Tj
+-426 TJm
+(\() 5.97756 Tj
+-426 TJm
+(int) 17.9327 Tj
+-3408 TJm
+(fd,) 17.9327 Tj
+-1704 TJm
+(const) 29.8878 Tj
+-426 TJm
+(char) 23.9102 Tj
+369.629 302.204 Td
+(*) 5.97756 Tj
+375.607 303.947 Td
+(mode) 23.9102 Tj
+-426 TJm
+(\);) 11.9551 Tj
+[1 0 0 1 72 288.405] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.5492] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -278.443] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 266.488 Td
+/F130_0 9.9626 Tf
+(Opens) 25.4544 Tj
+-243 TJm
+(a) 4.42339 Tj
+[1 0 0 1 106.713 266.488] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -106.713 -266.488] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+106.713 266.488 Td
+/F134_0 9.9626 Tf
+(.bz2) 23.9102 Tj
+[1 0 0 1 130.624 266.488] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -130.624 -266.488] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+133.041 266.488 Td
+/F130_0 9.9626 Tf
+(\002le) 12.7322 Tj
+-243 TJm
+(for) 11.6164 Tj
+-242 TJm
+(reading) 29.8778 Tj
+-243 TJm
+(or) 8.29885 Tj
+-243 TJm
+(writing,) 31.2726 Tj
+-244 TJm
+(using) 21.589 Tj
+-243 TJm
+(ei) 7.193 Tj
+1 TJm
+(ther) 15.4918 Tj
+-243 TJm
+(its) 9.41466 Tj
+-243 TJm
+(name) 21.579 Tj
+-242 TJm
+(o) 4.9813 Tj
+-1 TJm
+(r) 3.31755 Tj
+-242 TJm
+(a) 4.42339 Tj
+-243 TJm
+(pre-e) 20.4632 Tj
+15 TJm
+(xisting) 27.1282 Tj
+-243 TJm
+(\002le) 12.7322 Tj
+-242 TJm
+(descriptor) 39.8404 Tj
+55 TJm
+(.) 2.49065 Tj
+-615 TJm
+(Analogous) 43.1679 Tj
+-243 TJm
+(to) 7.7509 Tj
+[1 0 0 1 510.112 266.488] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -510.112 -266.488] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+510.112 266.488 Td
+/F134_0 9.9626 Tf
+(fopen) 29.8878 Tj
+[1 0 0 1 540 266.488] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -540 -266.488] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 254.532 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 88.8767 254.532] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -88.8767 -254.532] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+88.8767 254.532 Td
+/F134_0 9.9626 Tf
+(fdopen) 35.8654 Tj
+[1 0 0 1 124.742 254.532] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -124.742 -254.532] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+124.742 254.532 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+[1 0 0 1 72 252.998] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -36.8618] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 35.8655 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 32.2789] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -243.633] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 243.633 Td
+/F134_0 9.9626 Tf
+(int) 17.9327 Tj
+-426 TJm
+(BZ2_bzread) 59.7756 Tj
+-852 TJm
+(\() 5.97756 Tj
+-426 TJm
+(BZFILE) 35.8654 Tj
+226.528 241.89 Td
+(*) 5.97756 Tj
+236.749 243.633 Td
+(b,) 11.9551 Tj
+-426 TJm
+(void) 23.9102 Tj
+276.859 241.89 Td
+(*) 5.97756 Tj
+287.08 243.633 Td
+(buf,) 23.9102 Tj
+-426 TJm
+(int) 17.9327 Tj
+-426 TJm
+(len) 17.9327 Tj
+-426 TJm
+(\);) 11.9551 Tj
+90 231.678 Td
+(int) 17.9327 Tj
+-426 TJm
+(BZ2_bzwrite) 65.7532 Tj
+-426 TJm
+(\() 5.97756 Tj
+-426 TJm
+(BZFILE) 35.8654 Tj
+228.261 229.935 Td
+(*) 5.97756 Tj
+238.483 231.678 Td
+(b,) 11.9551 Tj
+-426 TJm
+(void) 23.9102 Tj
+278.592 229.935 Td
+(*) 5.97756 Tj
+288.814 231.678 Td
+(buf,) 23.9102 Tj
+-426 TJm
+(int) 17.9327 Tj
+-426 TJm
+(len) 17.9327 Tj
+-426 TJm
+(\);) 11.9551 Tj
+[1 0 0 1 72 216.136] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.5492] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -206.174] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 194.219 Td
+/F130_0 9.9626 Tf
+(Reads/writes) 51.4668 Tj
+-250 TJm
+(data) 16.5977 Tj
+-250 TJm
+(from/to) 29.8878 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(pre) 12.7222 Tj
+25 TJm
+(viously) 29.3399 Tj
+-250 TJm
+(opened) 28.772 Tj
+[1 0 0 1 259.903 194.219] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -259.903 -194.219] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+259.903 194.219 Td
+/F134_0 9.9626 Tf
+(BZFILE) 35.8654 Tj
+[1 0 0 1 295.769 194.219] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -295.769 -194.219] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+295.769 194.219 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+-500 TJm
+(Analogous) 43.1679 Tj
+-250 TJm
+(to) 7.7509 Tj
+[1 0 0 1 359.141 194.219] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -359.141 -194.219] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+359.141 194.219 Td
+/F134_0 9.9626 Tf
+(fread) 29.8878 Tj
+[1 0 0 1 389.029 194.219] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -389.029 -194.219] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+391.519 194.219 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 408.396 194.219] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -408.396 -194.219] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+408.396 194.219 Td
+/F134_0 9.9626 Tf
+(fwrite) 35.8654 Tj
+[1 0 0 1 444.261 194.219] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.261 -194.219] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+444.261 194.219 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+[1 0 0 1 72 192.062] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -36.8618] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 35.8655 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 32.2789] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -182.697] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 182.697 Td
+/F134_0 9.9626 Tf
+(int) 17.9327 Tj
+-852 TJm
+(BZ2_bzflush) 65.7532 Tj
+-426 TJm
+(\() 5.97756 Tj
+-426 TJm
+(BZFILE) 35.8654 Tj
+232.505 180.954 Td
+(*) 5.97756 Tj
+242.727 182.697 Td
+(b) 5.97756 Tj
+-426 TJm
+(\);) 11.9551 Tj
+90 170.742 Td
+(void) 23.9102 Tj
+-426 TJm
+(BZ2_bzclose) 65.7532 Tj
+-426 TJm
+(\() 5.97756 Tj
+-426 TJm
+(BZFILE) 35.8654 Tj
+234.239 168.998 Td
+(*) 5.97756 Tj
+244.46 170.742 Td
+(b) 5.97756 Tj
+-426 TJm
+(\);) 11.9551 Tj
+[1 0 0 1 72 155.2] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.5492] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -145.237] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 133.282 Td
+/F130_0 9.9626 Tf
+(Flushes/closes) 57.5639 Tj
+-250 TJm
+(a) 4.42339 Tj
+[1 0 0 1 138.968 133.282] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -138.968 -133.282] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+138.968 133.282 Td
+/F134_0 9.9626 Tf
+(BZFILE) 35.8654 Tj
+[1 0 0 1 174.833 133.282] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -174.833 -133.282] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+174.833 133.282 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+[1 0 0 1 179.815 133.282] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -179.815 -133.282] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+179.815 133.282 Td
+/F134_0 9.9626 Tf
+(BZ2_bzflush) 65.7532 Tj
+[1 0 0 1 245.568 133.282] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -245.568 -133.282] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+248.059 133.282 Td
+/F130_0 9.9626 Tf
+(doesn') 26.5603 Tj
+18 TJm
+(t) 2.7696 Tj
+-250 TJm
+(actually) 31.5416 Tj
+-250 TJm
+(do) 9.9626 Tj
+-250 TJm
+(an) 9.40469 Tj
+15 TJm
+(ything.) 27.9551 Tj
+-620 TJm
+(Analogous) 43.1679 Tj
+-250 TJm
+(to) 7.7509 Tj
+[1 0 0 1 425.472 133.282] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -425.472 -133.282] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+425.472 133.282 Td
+/F134_0 9.9626 Tf
+(fflush) 35.8654 Tj
+[1 0 0 1 461.338 133.282] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -461.338 -133.282] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+463.828 133.282 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 480.705 133.282] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -480.705 -133.282] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+480.705 133.282 Td
+/F134_0 9.9626 Tf
+(fclose) 35.8654 Tj
+[1 0 0 1 516.57 133.282] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -516.57 -133.282] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+516.57 133.282 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+[1 0 0 1 72 131.125] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -24.9066] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 23.9103 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 20.3237] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3685] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -121.761] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 121.761 Td
+/F134_0 9.9626 Tf
+(const) 29.8878 Tj
+-426 TJm
+(char) 23.9102 Tj
+152.286 120.017 Td
+(*) 5.97756 Tj
+162.508 121.761 Td
+(BZ2_bzerror) 65.7532 Tj
+-426 TJm
+(\() 5.97756 Tj
+-426 TJm
+(BZFILE) 35.8654 Tj
+282.836 120.017 Td
+(*) 5.97756 Tj
+288.814 121.761 Td
+(b,) 11.9551 Tj
+-426 TJm
+(int) 17.9327 Tj
+327.19 120.017 Td
+(*) 5.97756 Tj
+333.167 121.761 Td
+(errnum) 35.8654 Tj
+-426 TJm
+(\)) 5.97756 Tj
+[1 0 0 1 72 106.219] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.5492] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -96.2563] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 84.3011 Td
+/F130_0 9.9626 Tf
+(Returns) 30.9936 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(string) 22.6948 Tj
+-250 TJm
+(describing) 41.5042 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(more) 20.4731 Tj
+-250 TJm
+(recent) 24.3386 Tj
+-250 TJm
+(error) 19.3573 Tj
+-250 TJm
+(status) 22.6948 Tj
+-250 TJm
+(of) 8.29885 Tj
+[1 0 0 1 303.858 84.3011] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -303.858 -84.3011] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+303.858 84.3011 Td
+/F134_0 9.9626 Tf
+(b) 5.97756 Tj
+[1 0 0 1 309.835 84.3011] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -309.835 -84.3011] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+309.835 84.3011 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-250 TJm
+(and) 14.386 Tj
+-250 TJm
+(also) 16.0497 Tj
+-250 TJm
+(sets) 14.9439 Tj
+[1 0 0 1 367.668 84.3011] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -367.668 -84.3011] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+367.668 82.5576 Td
+/F134_0 9.9626 Tf
+(*) 5.97756 Tj
+373.645 84.3011 Td
+(errnum) 35.8654 Tj
+[1 0 0 1 409.511 84.3011] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -409.511 -84.3011] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+412.001 84.3011 Td
+/F130_0 9.9626 Tf
+(to) 7.7509 Tj
+-250 TJm
+(its) 9.41466 Tj
+-250 TJm
+(numerical) 39.8404 Tj
+-250 TJm
+(v) 4.9813 Tj
+25 TJm
+(alue.) 19.0883 Tj
+[1 0 0 1 72 82.1443] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -21.3298] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 4.3836 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 374.394 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 6.8541] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 40.5726 -6.7545] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -495.734 -50.9514] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+536.307 50.9514 Td
+/F130_0 9.9626 Tf
+(28) 9.9626 Tj
+[1 0 0 1 455.161 50.8518] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 93.5985 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.2765 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -15.0365 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+Q
+showpage
+%%PageTrailer
+pdfEndPage
+%%Page: 32 32
+%%BeginPageSetup
+%%PageOrientation: Portrait
+pdfStartPage
+0 0 612 792 re W
+%%EndPageSetup
+[] 0 d
+1 i
+0 j
+0 J
+10 M
+1 w
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+false op
+false OP
+0 0 612 792 re
+W
+q
+[1 0 0 1 72 741.554] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 14.4459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 187.197 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 -8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 76.4979 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -342.569 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+419.067 749.245 Td
+/F130_0 9.9626 Tf
+(Programming) 54.7943 Tj
+-250 TJm
+(with) 17.7135 Tj
+[1 0 0 1 496.556 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -496.556 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+496.556 749.245 Td
+/F134_0 9.9626 Tf
+(libbzip2) 47.8205 Tj
+[1 0 0 1 544.376 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -278.305 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 280.796 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -472.974 -5.0363] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -0.4981] cm
+q
+[] 0 d
+0 J
+0.4981 w
+0 0.2491 m
+475.465 0.2491 l
+S
+Q
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 479.251 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -540 -741.554] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 704.93 Td
+/F122_0 20.6585 Tf
+(3.7.) 34.4584 Tj
+-278 TJm
+(Using) 57.3893 Tj
+-278 TJm
+(the) 30.9877 Tj
+-278 TJm
+(librar) 51.6669 Tj
+-10 TJm
+(y) 11.4861 Tj
+-278 TJm
+(in) 18.3654 Tj
+-278 TJm
+(a) 11.4861 Tj
+[1 0 0 1 322.501 704.93] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -322.501 -704.93] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+322.501 704.93 Td
+/F392_0 20.6585 Tf
+(stdio) 61.9755 Tj
+[1 0 0 1 384.477 704.93] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -384.477 -704.93] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+384.477 704.93 Td
+/F122_0 20.6585 Tf
+(-free) 44.767 Tj
+72 680.139 Td
+(en) 24.1085 Tj
+40 TJm
+(vir) 25.2653 Tj
+20 TJm
+(onment) 74.5978 Tj
+[1 0 0 1 72 679.881] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.898] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -669.983] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 649.583 Td
+/F122_0 17.2154 Tf
+(3.7.1.) 43.0729 Tj
+-278 TJm
+(Getting) 60.2539 Tj
+-278 TJm
+(rid) 22.0013 Tj
+-278 TJm
+(of) 16.2513 Tj
+[1 0 0 1 232.721 649.583] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -232.721 -649.583] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+232.721 649.583 Td
+/F392_0 17.2154 Tf
+(stdio) 51.6462 Tj
+[1 0 0 1 284.367 649.583] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -212.367 -3.8303] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.898] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -635.855] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 627.73 Td
+/F130_0 9.9626 Tf
+(In) 8.29885 Tj
+-319 TJm
+(a) 4.42339 Tj
+-319 TJm
+(deeply) 26.5603 Tj
+-319 TJm
+(embedded) 40.9463 Tj
+-319 TJm
+(application,) 46.7644 Tj
+-336 TJm
+(you) 14.9439 Tj
+-319 TJm
+(might) 23.2527 Tj
+-319 TJm
+(w) 7.193 Tj
+10 TJm
+(ant) 12.1743 Tj
+-319 TJm
+(to) 7.7509 Tj
+-319 TJm
+(use) 13.2801 Tj
+-319 TJm
+(just) 14.396 Tj
+-319 TJm
+(the) 12.1743 Tj
+-319 TJm
+(memory-to-memory) 80.7967 Tj
+-319 TJm
+(functions.) 39.5714 Tj
+-1035 TJm
+(Y) 7.193 Tj
+110 TJm
+(ou) 9.9626 Tj
+-319 TJm
+(can) 13.8281 Tj
+-319 TJm
+(do) 9.9626 Tj
+-319 TJm
+(this) 14.396 Tj
+72 615.775 Td
+(con) 14.386 Tj
+40 TJm
+(v) 4.9813 Tj
+15 TJm
+(eniently) 32.0995 Tj
+-327 TJm
+(by) 9.9626 Tj
+-327 TJm
+(compiling) 40.4083 Tj
+-327 TJm
+(the) 12.1743 Tj
+-327 TJm
+(library) 26.5603 Tj
+-327 TJm
+(with) 17.7135 Tj
+-328 TJm
+(preproces) 38.7246 Tj
+1 TJm
+(sor) 12.1743 Tj
+-328 TJm
+(symbol) 29.3399 Tj
+[1 0 0 1 336.046 615.775] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -336.046 -615.775] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+336.046 615.775 Td
+/F134_0 9.9626 Tf
+(BZ_NO_STDIO) 65.7532 Tj
+[1 0 0 1 401.799 615.775] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -401.799 -615.775] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+405.057 615.775 Td
+/F130_0 9.9626 Tf
+(de\002ned.) 31.8205 Tj
+-1083 TJm
+(Doing) 24.9065 Tj
+-327 TJm
+(this) 14.396 Tj
+-327 TJm
+(gi) 7.7509 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(es) 8.29885 Tj
+-327 TJm
+(you) 14.9439 Tj
+-327 TJm
+(a) 4.42339 Tj
+72 603.819 Td
+(library) 26.5603 Tj
+-250 TJm
+(containing) 42.0621 Tj
+-250 TJm
+(only) 17.7135 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(follo) 18.8194 Tj
+25 TJm
+(wing) 19.9252 Tj
+-250 TJm
+(eight) 19.9252 Tj
+-250 TJm
+(functions:) 39.8504 Tj
+[1 0 0 1 72 601.662] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.898] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -591.764] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 581.966 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompressInit) 107.596 Tj
+[1 0 0 1 179.596 581.966] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -179.596 -581.966] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+179.596 581.966 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 199.079 581.966] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -199.079 -581.966] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+199.079 581.966 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompress) 83.6858 Tj
+[1 0 0 1 282.765 581.966] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -282.765 -581.966] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+282.765 581.966 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 302.247 581.966] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -302.247 -581.966] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+302.247 581.966 Td
+/F134_0 9.9626 Tf
+(BZ2_bzCompressEnd) 101.619 Tj
+[1 0 0 1 403.866 581.966] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 14.0915 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -417.958 -581.966] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+417.958 581.966 Td
+/F134_0 9.9626 Tf
+(BZ2_bzDecompressInit) 119.551 Tj
+[1 0 0 1 537.509 581.966] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -537.509 -581.966] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+537.509 581.966 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 72 570.011] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -570.011] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 570.011 Td
+/F134_0 9.9626 Tf
+(BZ2_bzDecompress) 95.641 Tj
+[1 0 0 1 167.641 570.011] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -167.641 -570.011] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+167.641 570.011 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 172.144 570.011] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -172.144 -570.011] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+172.144 570.011 Td
+/F134_0 9.9626 Tf
+(BZ2_bzDecompressEnd) 113.574 Tj
+[1 0 0 1 285.719 570.011] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -287.611 -570.011] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+287.611 570.011 Td
+/F134_0 9.9626 Tf
+(BZ2_bzBuffToBuffCompress) 143.461 Tj
+[1 0 0 1 431.073 570.011] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -431.073 -570.011] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+431.073 570.011 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 435.577 570.011] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -435.577 -570.011] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+435.577 570.011 Td
+/F134_0 9.9626 Tf
+(BZ2_bzBuffToBuffDecompress) 155.417 Tj
+[1 0 0 1 590.994 570.011] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -518.994 -1.5341] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.8981] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -558.579] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 548.158 Td
+/F130_0 9.9626 Tf
+(When) 23.7907 Tj
+-250 TJm
+(compiled) 37.0808 Tj
+-250 TJm
+(lik) 10.5205 Tj
+10 TJm
+(e) 4.42339 Tj
+-250 TJm
+(this,) 16.8866 Tj
+-250 TJm
+(all) 9.9626 Tj
+-250 TJm
+(functions) 37.0808 Tj
+-250 TJm
+(will) 15.5018 Tj
+-250 TJm
+(ignore) 25.4544 Tj
+[1 0 0 1 272.526 548.158] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -272.526 -548.158] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+272.526 548.158 Td
+/F134_0 9.9626 Tf
+(verbosity) 53.798 Tj
+[1 0 0 1 326.324 548.158] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -326.324 -548.158] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+328.815 548.158 Td
+/F130_0 9.9626 Tf
+(settings.) 32.9364 Tj
+[1 0 0 1 72 546.001] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.898] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -536.103] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 517.601 Td
+/F122_0 17.2154 Tf
+(3.7.2.) 43.0729 Tj
+-278 TJm
+(Critical) 58.3602 Tj
+-278 TJm
+(err) 22.9653 Tj
+20 TJm
+(or) 17.2154 Tj
+-278 TJm
+(handling) 71.7366 Tj
+[1 0 0 1 72 513.771] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.898] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -503.873] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 495.748 Td
+/F134_0 9.9626 Tf
+(libbzip2) 47.8205 Tj
+[1 0 0 1 119.821 495.748] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -119.821 -495.748] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+124.529 495.748 Td
+/F130_0 9.9626 Tf
+(contains) 33.2053 Tj
+-473 TJm
+(a) 4.42339 Tj
+-472 TJm
+(number) 30.4357 Tj
+-473 TJm
+(of) 8.29885 Tj
+-472 TJm
+(internal) 30.4357 Tj
+-473 TJm
+(assertion) 35.417 Tj
+-472 TJm
+(checks) 27.1082 Tj
+-473 TJm
+(which) 24.3486 Tj
+-472 TJm
+(should,) 29.0609 Tj
+-529 TJm
+(needless) 33.7533 Tj
+-472 TJm
+(to) 7.7509 Tj
+-473 TJm
+(say) 13.2801 Tj
+65 TJm
+(,) 2.49065 Tj
+-528 TJm
+(ne) 9.40469 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(er) 7.74094 Tj
+-473 TJm
+(be) 9.40469 Tj
+-472 TJm
+(acti) 14.386 Tj
+25 TJm
+(v) 4.9813 Tj
+25 TJm
+(ated.) 19.0883 Tj
+72 483.793 Td
+(Ne) 11.6164 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(ertheless,) 37.3498 Tj
+-533 TJm
+(if) 6.08715 Tj
+-476 TJm
+(an) 9.40469 Tj
+-476 TJm
+(assertion) 35.417 Tj
+-476 TJm
+(should) 26.5703 Tj
+-476 TJm
+(f) 3.31755 Tj
+10 TJm
+(ail,) 12.4533 Tj
+-532 TJm
+(beha) 18.8094 Tj
+20 TJm
+(viour) 21.031 Tj
+-476 TJm
+(depends) 32.6474 Tj
+-476 TJm
+(on) 9.9626 Tj
+-476 TJm
+(whether) 32.0895 Tj
+-476 TJm
+(or) 8.29885 Tj
+-477 TJm
+(not) 12.7322 Tj
+-476 TJm
+(the) 12.1743 Tj
+-476 TJm
+(library) 26.5603 Tj
+-476 TJm
+(w) 7.193 Tj
+10 TJm
+(as) 8.29885 Tj
+-476 TJm
+(compiled) 37.0808 Tj
+-476 TJm
+(with) 17.7135 Tj
+[1 0 0 1 72 471.838] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -471.838] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 471.838 Td
+/F134_0 9.9626 Tf
+(BZ_NO_STDIO) 65.7532 Tj
+[1 0 0 1 137.753 471.838] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -137.753 -471.838] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+140.244 471.838 Td
+/F130_0 9.9626 Tf
+(set.) 13.5591 Tj
+[1 0 0 1 72 470.528] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.898] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -460.63] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 449.985 Td
+/F130_0 9.9626 Tf
+(F) 5.53921 Tj
+15 TJm
+(or) 8.29885 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(normal) 28.224 Tj
+-250 TJm
+(compile,) 34.5901 Tj
+-250 TJm
+(an) 9.40469 Tj
+-250 TJm
+(assertion) 35.417 Tj
+-250 TJm
+(f) 3.31755 Tj
+10 TJm
+(ailure) 22.6848 Tj
+-250 TJm
+(yields) 23.8007 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(message:) 36.5229 Tj
+[1 0 0 1 72 447.828] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.898] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -437.93] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 428.131 Td
+/F130_0 9.9626 Tf
+(bzip2/libbzip2:) 60.3335 Tj
+-310 TJm
+(internal) 30.4357 Tj
+-250 TJm
+(error) 19.3573 Tj
+-250 TJm
+(number) 30.4357 Tj
+-250 TJm
+(N.) 9.68365 Tj
+[1 0 0 1 72 425.975] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.898] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -416.077] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 406.278 Td
+/F130_0 9.9626 Tf
+(This) 17.7135 Tj
+-332 TJm
+(is) 6.64505 Tj
+-331 TJm
+(a) 4.42339 Tj
+-332 TJm
+(b) 4.9813 Tj
+20 TJm
+(ug) 9.9626 Tj
+-332 TJm
+(in) 7.7509 Tj
+-331 TJm
+(bzip2/libbzip2,) 60.0546 Tj
+-352 TJm
+(1.0.5) 19.9252 Tj
+-332 TJm
+(of) 8.29885 Tj
+-332 TJm
+(10) 9.9626 Tj
+-332 TJm
+(December) 40.9363 Tj
+-331 TJm
+(2007.) 22.4159 Tj
+-555 TJm
+(Please) 25.4544 Tj
+-332 TJm
+(report) 23.7907 Tj
+-332 TJm
+(it) 5.53921 Tj
+-331 TJm
+(to) 7.7509 Tj
+-332 TJm
+(me) 12.1743 Tj
+-332 TJm
+(at:) 9.9626 Tj
+-473 TJm
+(jse) 11.0684 Tj
+25 TJm
+(w) 7.193 Tj
+10 TJm
+(ard@bzip.or) 49.8429 Tj
+18 TJm
+(g.) 7.47195 Tj
+-1110 TJm
+(If) 6.63509 Tj
+-332 TJm
+(this) 14.396 Tj
+72 394.323 Td
+(happened) 38.1767 Tj
+-297 TJm
+(when) 21.579 Tj
+-298 TJm
+(you) 14.9439 Tj
+-297 TJm
+(were) 19.3573 Tj
+-297 TJm
+(using) 21.589 Tj
+-297 TJm
+(some) 21.031 Tj
+-298 TJm
+(program) 33.7533 Tj
+-297 TJm
+(which) 24.3486 Tj
+-297 TJm
+(uses) 17.1556 Tj
+-297 TJm
+(libbzip2) 32.6574 Tj
+-298 TJm
+(as) 8.29885 Tj
+-297 TJm
+(a) 4.42339 Tj
+-297 TJm
+(component,) 46.7644 Tj
+-309 TJm
+(you) 14.9439 Tj
+-298 TJm
+(should) 26.5703 Tj
+-297 TJm
+(also) 16.0497 Tj
+-297 TJm
+(report) 23.7907 Tj
+-297 TJm
+(this) 14.396 Tj
+-298 TJm
+(b) 4.9813 Tj
+20 TJm
+(ug) 9.9626 Tj
+72 382.368 Td
+(to) 7.7509 Tj
+-264 TJm
+(the) 12.1743 Tj
+-264 TJm
+(author\(s\)) 35.965 Tj
+-264 TJm
+(of) 8.29885 Tj
+-264 TJm
+(that) 14.9439 Tj
+-264 TJm
+(program.) 36.2439 Tj
+-703 TJm
+(Please) 25.4544 Tj
+-264 TJm
+(mak) 17.1556 Tj
+10 TJm
+(e) 4.42339 Tj
+-264 TJm
+(an) 9.40469 Tj
+-264 TJm
+(ef) 7.74094 Tj
+25 TJm
+(fort) 14.386 Tj
+-264 TJm
+(to) 7.7509 Tj
+-264 TJm
+(report) 23.7907 Tj
+-263 TJm
+(this) 14.396 Tj
+-264 TJm
+(b) 4.9813 Tj
+20 TJm
+(ug;) 12.7322 Tj
+-271 TJm
+(timely) 25.4644 Tj
+-264 TJm
+(and) 14.386 Tj
+-264 TJm
+(accurate) 33.1854 Tj
+-264 TJm
+(b) 4.9813 Tj
+20 TJm
+(ug) 9.9626 Tj
+-264 TJm
+(reports) 27.6661 Tj
+-264 TJm
+(e) 4.42339 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(entually) 32.0995 Tj
+72 370.413 Td
+(lead) 16.5977 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(higher) 25.4544 Tj
+-250 TJm
+(quality) 27.6761 Tj
+-250 TJm
+(softw) 22.1369 Tj
+10 TJm
+(are.) 14.655 Tj
+-620 TJm
+(Thanks.) 31.8205 Tj
+-620 TJm
+(Julian) 23.8007 Tj
+-250 TJm
+(Se) 9.9626 Tj
+25 TJm
+(w) 7.193 Tj
+10 TJm
+(ard,) 15.2129 Tj
+-250 TJm
+(10) 9.9626 Tj
+-250 TJm
+(December) 40.9363 Tj
+-250 TJm
+(2007.) 22.4159 Tj
+[1 0 0 1 72 368.256] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.801] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.898] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -348.557] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 338.758 Td
+/F130_0 9.9626 Tf
+(where) 24.3386 Tj
+[1 0 0 1 98.8312 338.758] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -98.8312 -338.758] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+98.8312 338.758 Td
+/F134_0 9.9626 Tf
+(N) 5.97756 Tj
+[1 0 0 1 104.809 338.758] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -104.809 -338.758] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+107.302 338.758 Td
+/F130_0 9.9626 Tf
+(is) 6.64505 Tj
+-250 TJm
+(some) 21.031 Tj
+-250 TJm
+(error) 19.3573 Tj
+-251 TJm
+(code) 18.8094 Tj
+-250 TJm
+(number) 30.4357 Tj
+55 TJm
+(.) 2.49065 Tj
+-621 TJm
+(If) 6.63509 Tj
+[1 0 0 1 230.81 338.758] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -230.81 -338.758] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+230.81 338.758 Td
+/F134_0 9.9626 Tf
+(N) 5.97756 Tj
+-600 TJm
+(==) 11.9551 Tj
+-600 TJm
+(1007) 23.9102 Tj
+[1 0 0 1 284.608 338.758] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -284.608 -338.758] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+284.608 338.758 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-250 TJm
+(it) 5.53921 Tj
+-250 TJm
+(also) 16.0497 Tj
+-251 TJm
+(prints) 22.6948 Tj
+-250 TJm
+(some) 21.031 Tj
+-250 TJm
+(e) 4.42339 Tj
+15 TJm
+(xtra) 15.4918 Tj
+-250 TJm
+(te) 7.193 Tj
+15 TJm
+(xt) 7.7509 Tj
+-250 TJm
+(advising) 33.7633 Tj
+-251 TJm
+(the) 12.1743 Tj
+-250 TJm
+(reader) 24.8866 Tj
+-250 TJm
+(that) 14.9439 Tj
+-250 TJm
+(unreliable) 39.8404 Tj
+72 326.803 Td
+(memory) 33.2053 Tj
+-425 TJm
+(is) 6.64505 Tj
+-424 TJm
+(often) 20.4731 Tj
+-425 TJm
+(associated) 40.9463 Tj
+-425 TJm
+(with) 17.7135 Tj
+-424 TJm
+(internal) 30.4357 Tj
+-425 TJm
+(error) 19.3573 Tj
+-424 TJm
+(1007.) 22.4159 Tj
+-834 TJm
+(\(This) 21.031 Tj
+-425 TJm
+(is) 6.64505 Tj
+-425 TJm
+(a) 4.42339 Tj
+-424 TJm
+(frequently-observ) 70.8241 Tj
+15 TJm
+(ed-phenomenon) 64.189 Tj
+-425 TJm
+(with) 17.7135 Tj
+-425 TJm
+(v) 4.9813 Tj
+15 TJm
+(ersions) 28.224 Tj
+72 314.848 Td
+(1.0.0/1.0.1\).) 48.4282 Tj
+[1 0 0 1 72 313.065] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.898] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -303.167] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 292.995 Td
+/F134_0 9.9626 Tf
+(exit\(3\)) 41.8429 Tj
+[1 0 0 1 113.843 292.995] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -113.843 -292.995] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+116.334 292.995 Td
+/F130_0 9.9626 Tf
+(is) 6.64505 Tj
+-250 TJm
+(then) 17.1556 Tj
+-250 TJm
+(called.) 26.2813 Tj
+[1 0 0 1 72 291.899] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.8981] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -282.001] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 271.142 Td
+/F130_0 9.9626 Tf
+(F) 5.53921 Tj
+15 TJm
+(or) 8.29885 Tj
+-250 TJm
+(a) 4.42339 Tj
+[1 0 0 1 95.0933 271.142] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -95.0933 -271.142] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+95.0933 271.142 Td
+/F134_0 9.9626 Tf
+(stdio) 29.8878 Tj
+[1 0 0 1 124.981 271.142] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -124.981 -271.142] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+124.981 271.142 Td
+/F130_0 9.9626 Tf
+(-free) 18.7994 Tj
+-250 TJm
+(library) 26.5603 Tj
+65 TJm
+(,) 2.49065 Tj
+-250 TJm
+(assertion) 35.417 Tj
+-250 TJm
+(f) 3.31755 Tj
+10 TJm
+(ailures) 26.5603 Tj
+-250 TJm
+(result) 22.1369 Tj
+-250 TJm
+(in) 7.7509 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(call) 14.386 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(function) 33.2053 Tj
+-250 TJm
+(declared) 33.7433 Tj
+-250 TJm
+(as:) 11.0684 Tj
+[1 0 0 1 72 268.985] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -24.9066] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 23.9103 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 20.3237] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3685] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -259.62] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 259.62 Td
+/F134_0 9.9626 Tf
+(extern) 35.8654 Tj
+-426 TJm
+(void) 23.9102 Tj
+-426 TJm
+(bz_internal_error) 101.619 Tj
+-426 TJm
+(\() 5.97756 Tj
+-426 TJm
+(int) 17.9327 Tj
+-426 TJm
+(errcode) 41.8429 Tj
+-426 TJm
+(\);) 11.9551 Tj
+[1 0 0 1 72 244.078] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.4846] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -234.18] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 222.225 Td
+/F130_0 9.9626 Tf
+(The) 15.4918 Tj
+-250 TJm
+(rele) 14.9339 Tj
+25 TJm
+(v) 4.9813 Tj
+25 TJm
+(ant) 12.1743 Tj
+-250 TJm
+(code) 18.8094 Tj
+-250 TJm
+(is) 6.64505 Tj
+-250 TJm
+(passed) 26.5603 Tj
+-250 TJm
+(as) 8.29885 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(parameter) 39.8305 Tj
+55 TJm
+(.) 2.49065 Tj
+-620 TJm
+(Y) 7.193 Tj
+110 TJm
+(ou) 9.9626 Tj
+-250 TJm
+(should) 26.5703 Tj
+-250 TJm
+(supply) 26.5703 Tj
+-250 TJm
+(such) 18.2614 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(function.) 35.696 Tj
+[1 0 0 1 72 220.068] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.898] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -210.17] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 200.372 Td
+/F130_0 9.9626 Tf
+(In) 8.29885 Tj
+-294 TJm
+(either) 22.6848 Tj
+-294 TJm
+(case,) 19.6363 Tj
+-306 TJm
+(once) 18.8094 Tj
+-294 TJm
+(an) 9.40469 Tj
+-294 TJm
+(assertion) 35.417 Tj
+-294 TJm
+(f) 3.31755 Tj
+10 TJm
+(ailure) 22.6848 Tj
+-294 TJm
+(has) 13.2801 Tj
+-295 TJm
+(occurred,) 37.3398 Tj
+-305 TJm
+(an) 9.40469 Tj
+15 TJm
+(y) 4.9813 Tj
+[1 0 0 1 306.541 200.372] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -306.541 -200.372] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+306.541 200.372 Td
+/F134_0 9.9626 Tf
+(bz_stream) 53.798 Tj
+[1 0 0 1 360.339 200.372] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -360.339 -200.372] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+363.271 200.372 Td
+/F130_0 9.9626 Tf
+(records) 29.3199 Tj
+-294 TJm
+(in) 7.7509 Tj
+40 TJm
+(v) 4.9813 Tj
+20 TJm
+(olv) 12.7322 Tj
+15 TJm
+(ed) 9.40469 Tj
+-294 TJm
+(can) 13.8281 Tj
+-295 TJm
+(be) 9.40469 Tj
+-294 TJm
+(re) 7.74094 Tj
+15 TJm
+(g) 4.9813 Tj
+5 TJm
+(arded) 22.1269 Tj
+-294 TJm
+(as) 8.29885 Tj
+-294 TJm
+(in) 7.7509 Tj
+40 TJm
+(v) 4.9813 Tj
+25 TJm
+(alid.) 17.4346 Tj
+72 188.417 Td
+(Y) 7.193 Tj
+110 TJm
+(ou) 9.9626 Tj
+-250 TJm
+(should) 26.5703 Tj
+-250 TJm
+(not) 12.7322 Tj
+-250 TJm
+(attempt) 29.8878 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(resume) 28.772 Tj
+-250 TJm
+(normal) 28.224 Tj
+-250 TJm
+(operation) 37.6287 Tj
+-250 TJm
+(with) 17.7135 Tj
+-250 TJm
+(them.) 22.4159 Tj
+[1 0 0 1 72 186.26] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.898] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -176.362] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 166.564 Td
+/F130_0 9.9626 Tf
+(Y) 7.193 Tj
+110 TJm
+(ou) 9.9626 Tj
+-299 TJm
+(may) 17.1556 Tj
+65 TJm
+(,) 2.49065 Tj
+-310 TJm
+(of) 8.29885 Tj
+-299 TJm
+(course,) 28.493 Tj
+-311 TJm
+(change) 28.2141 Tj
+-298 TJm
+(critical) 27.6661 Tj
+-299 TJm
+(error) 19.3573 Tj
+-298 TJm
+(handling) 34.8691 Tj
+-299 TJm
+(to) 7.7509 Tj
+-298 TJm
+(suit) 14.396 Tj
+-299 TJm
+(your) 18.2614 Tj
+-298 TJm
+(needs.) 25.1755 Tj
+-912 TJm
+(As) 11.0684 Tj
+-298 TJm
+(I) 3.31755 Tj
+-299 TJm
+(said) 16.0497 Tj
+-298 TJm
+(abo) 14.386 Tj
+15 TJm
+(v) 4.9813 Tj
+15 TJm
+(e,) 6.91404 Tj
+-311 TJm
+(critical) 27.6661 Tj
+-299 TJm
+(errors) 23.2328 Tj
+-298 TJm
+(indicate) 31.5416 Tj
+-299 TJm
+(b) 4.9813 Tj
+20 TJm
+(ugs) 13.8381 Tj
+72 154.608 Td
+(in) 7.7509 Tj
+-263 TJm
+(the) 12.1743 Tj
+-263 TJm
+(library) 26.5603 Tj
+-263 TJm
+(and) 14.386 Tj
+-263 TJm
+(should) 26.5703 Tj
+-263 TJm
+(not) 12.7322 Tj
+-263 TJm
+(occur) 22.1269 Tj
+55 TJm
+(.) 2.49065 Tj
+-697 TJm
+(All) 12.7322 Tj
+-263 TJm
+("normal") 36.3535 Tj
+-263 TJm
+(error) 19.3573 Tj
+-263 TJm
+(situations) 38.1966 Tj
+-263 TJm
+(are) 12.1643 Tj
+-263 TJm
+(indicated) 36.5229 Tj
+-263 TJm
+(via) 12.1743 Tj
+-263 TJm
+(error) 19.3573 Tj
+-263 TJm
+(return) 23.7907 Tj
+-263 TJm
+(codes) 22.6848 Tj
+-263 TJm
+(from) 19.3673 Tj
+-263 TJm
+(functions,) 39.5714 Tj
+72 142.653 Td
+(and) 14.386 Tj
+-250 TJm
+(can) 13.8281 Tj
+-250 TJm
+(be) 9.40469 Tj
+-250 TJm
+(reco) 17.1456 Tj
+15 TJm
+(v) 4.9813 Tj
+15 TJm
+(ered) 17.1456 Tj
+-250 TJm
+(from.) 21.8579 Tj
+[1 0 0 1 72 142.554] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.898] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -132.656] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 107.965 Td
+/F122_0 20.6585 Tf
+(3.8.) 34.4584 Tj
+-278 TJm
+(Making) 71.1685 Tj
+-278 TJm
+(a) 11.4861 Tj
+-278 TJm
+(Windo) 63.1117 Tj
+15 TJm
+(ws) 27.5584 Tj
+-278 TJm
+(DLL) 40.1601 Tj
+[1 0 0 1 72 103.369] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.898] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -93.4708] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 86.112 Td
+/F130_0 9.9626 Tf
+(Ev) 11.0684 Tj
+15 TJm
+(erything) 33.2053 Tj
+-328 TJm
+(related) 27.1082 Tj
+-327 TJm
+(to) 7.7509 Tj
+-328 TJm
+(W) 9.40469 Tj
+40 TJm
+(indo) 17.7135 Tj
+25 TJm
+(ws) 11.0684 Tj
+-328 TJm
+(has) 13.2801 Tj
+-327 TJm
+(been) 18.8094 Tj
+-328 TJm
+(contrib) 28.224 Tj
+20 TJm
+(uted) 17.1556 Tj
+-328 TJm
+(by) 9.9626 Tj
+-327 TJm
+(Y) 7.193 Tj
+110 TJm
+(oshioka) 30.9936 Tj
+-328 TJm
+(Tsuneo) 29.3299 Tj
+-328 TJm
+(\() 3.31755 Tj
+[1 0 0 1 378.139 86.112] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -378.139 -86.112] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+378.139 86.112 Td
+/F134_0 9.9626 Tf
+(tsuneo@rr.iij4u.or.jp) 125.529 Tj
+[1 0 0 1 503.668 86.112] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -503.668 -86.112] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+503.668 86.112 Td
+/F130_0 9.9626 Tf
+(\),) 5.8082 Tj
+-347 TJm
+(so) 8.85675 Tj
+-328 TJm
+(you) 14.9439 Tj
+72 74.1568 Td
+(should) 26.5703 Tj
+-250 TJm
+(send) 18.2614 Tj
+-250 TJm
+(your) 18.2614 Tj
+-250 TJm
+(queries) 28.772 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(him) 15.5018 Tj
+-250 TJm
+(\(b) 8.29885 Tj
+20 TJm
+(ut) 7.7509 Tj
+-250 TJm
+(perhaps) 30.9837 Tj
+-250 TJm
+(Cc:) 13.8381 Tj
+-310 TJm
+(me,) 14.6649 Tj
+[1 0 0 1 287.958 74.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -287.958 -74.1568] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+287.958 74.1568 Td
+/F134_0 9.9626 Tf
+(jseward@bzip.org) 95.641 Tj
+[1 0 0 1 383.6 74.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -383.6 -74.1568] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+383.6 74.1568 Td
+/F130_0 9.9626 Tf
+(\).) 5.8082 Tj
+[1 0 0 1 72 72] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -21.1482] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 374.394 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 6.9738] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 40.5726 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -493.841 -51.071] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+534.414 51.071 Td
+/F130_0 9.9626 Tf
+(29) 9.9626 Tj
+[1 0 0 1 453.269 50.8518] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 93.5985 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.2765 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+Q
+showpage
+%%PageTrailer
+pdfEndPage
+%%Page: 33 33
+%%BeginPageSetup
+%%PageOrientation: Portrait
+pdfStartPage
+0 0 612 792 re W
+%%EndPageSetup
+[] 0 d
+1 i
+0 j
+0 J
+10 M
+1 w
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+false op
+false OP
+0 0 612 792 re
+W
+q
+[1 0 0 1 72 741.554] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 14.4459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 187.197 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 -8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 8.9114] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 76.4979 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -342.569 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+419.067 749.245 Td
+/F130_0 9.9626 Tf
+(Programming) 54.7943 Tj
+-250 TJm
+(with) 17.7135 Tj
+[1 0 0 1 496.556 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -496.556 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+496.556 749.245 Td
+/F134_0 9.9626 Tf
+(libbzip2) 47.8205 Tj
+[1 0 0 1 544.376 749.245] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -278.305 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 280.796 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -472.974 -5.0363] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -0.4981] cm
+q
+[] 0 d
+0 J
+0.4981 w
+0 0.2491 m
+475.465 0.2491 l
+S
+Q
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 479.251 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -468 -21.5542] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -720] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 710.037 Td
+/F130_0 9.9626 Tf
+(My) 13.8381 Tj
+-367 TJm
+(v) 4.9813 Tj
+25 TJm
+(ague) 18.8094 Tj
+-367 TJm
+(understanding) 56.4481 Tj
+-367 TJm
+(of) 8.29885 Tj
+-367 TJm
+(what) 19.3673 Tj
+-368 TJm
+(to) 7.7509 Tj
+-367 TJm
+(do) 9.9626 Tj
+-367 TJm
+(is:) 9.41466 Tj
+-544 TJm
+(using) 21.589 Tj
+-367 TJm
+(V) 7.193 Tj
+60 TJm
+(isual) 18.8194 Tj
+-367 TJm
+(C++) 17.8829 Tj
+-367 TJm
+(5.0,) 14.9439 Tj
+-397 TJm
+(open) 19.3673 Tj
+-367 TJm
+(the) 12.1743 Tj
+-367 TJm
+(project) 27.6661 Tj
+-367 TJm
+(\002le) 12.7322 Tj
+[1 0 0 1 432.966 710.037] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -432.966 -710.037] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+432.966 710.037 Td
+/F134_0 9.9626 Tf
+(libbz2.dsp) 59.7756 Tj
+[1 0 0 1 492.742 710.037] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -492.742 -710.037] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+492.742 710.037 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-396 TJm
+(and) 14.386 Tj
+-368 TJm
+(b) 4.9813 Tj
+20 TJm
+(uild.) 17.9925 Tj
+72 698.082 Td
+(That') 21.579 Tj
+55 TJm
+(s) 3.87545 Tj
+-250 TJm
+(all.) 12.4533 Tj
+[1 0 0 1 72 697.983] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -688.02] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 676.164 Td
+/F130_0 9.9626 Tf
+(If) 6.63509 Tj
+-284 TJm
+(you) 14.9439 Tj
+-284 TJm
+(can') 17.1456 Tj
+18 TJm
+(t) 2.7696 Tj
+-285 TJm
+(open) 19.3673 Tj
+-284 TJm
+(the) 12.1743 Tj
+-284 TJm
+(project) 27.6661 Tj
+-284 TJm
+(\002le) 12.7322 Tj
+-284 TJm
+(for) 11.6164 Tj
+-285 TJm
+(some) 21.031 Tj
+-284 TJm
+(reason,) 28.493 Tj
+-293 TJm
+(mak) 17.1556 Tj
+10 TJm
+(e) 4.42339 Tj
+-284 TJm
+(a) 4.42339 Tj
+-284 TJm
+(ne) 9.40469 Tj
+25 TJm
+(w) 7.193 Tj
+-284 TJm
+(one,) 16.8766 Tj
+-293 TJm
+(naming) 29.8878 Tj
+-284 TJm
+(these) 20.4731 Tj
+-284 TJm
+(\002les:) 19.3773 Tj
+[1 0 0 1 424.505 676.164] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -424.505 -676.164] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+424.505 676.164 Td
+/F134_0 9.9626 Tf
+(blocksort.c) 65.7532 Tj
+[1 0 0 1 490.259 676.164] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -490.259 -676.164] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+490.259 676.164 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 495.666 676.164] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -495.666 -676.164] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+495.666 676.164 Td
+/F134_0 9.9626 Tf
+(bzlib.c) 41.8429 Tj
+[1 0 0 1 537.509 676.164] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -537.509 -676.164] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+537.509 676.164 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 72 664.209] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -664.209] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 664.209 Td
+/F134_0 9.9626 Tf
+(compress.c) 59.7756 Tj
+[1 0 0 1 131.776 664.209] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -131.776 -664.209] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+131.776 664.209 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 136.436 664.209] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -136.436 -664.209] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+136.436 664.209 Td
+/F134_0 9.9626 Tf
+(crctable.c) 59.7756 Tj
+[1 0 0 1 196.211 664.209] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -196.211 -664.209] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+196.211 664.209 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 200.871 664.209] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -200.871 -664.209] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+200.871 664.209 Td
+/F134_0 9.9626 Tf
+(decompress.c) 71.7307 Tj
+[1 0 0 1 272.602 664.209] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -272.602 -664.209] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+272.602 664.209 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 277.262 664.209] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -277.262 -664.209] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+277.262 664.209 Td
+/F134_0 9.9626 Tf
+(huffman.c) 53.798 Tj
+[1 0 0 1 331.06 664.209] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -331.06 -664.209] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+331.06 664.209 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 335.72 664.209] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -335.72 -664.209] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+335.72 664.209 Td
+/F134_0 9.9626 Tf
+(randtable.c) 65.7532 Tj
+[1 0 0 1 401.473 664.209] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -401.473 -664.209] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+403.562 664.209 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 420.037 664.209] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -420.037 -664.209] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+420.037 664.209 Td
+/F134_0 9.9626 Tf
+(libbz2.def) 59.7756 Tj
+[1 0 0 1 479.812 664.209] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -479.812 -664.209] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+479.812 664.209 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+-593 TJm
+(Y) 7.193 Tj
+110 TJm
+(ou) 9.9626 Tj
+-210 TJm
+(will) 15.5018 Tj
+-209 TJm
+(also) 16.0497 Tj
+72 652.254 Td
+(need) 18.8094 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(name) 21.579 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(header) 26.5503 Tj
+-250 TJm
+(\002les) 16.6077 Tj
+[1 0 0 1 190.415 652.254] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -190.415 -652.254] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+190.415 652.254 Td
+/F134_0 9.9626 Tf
+(bzlib.h) 41.8429 Tj
+[1 0 0 1 232.258 652.254] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -232.258 -652.254] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+234.748 652.254 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 251.625 652.254] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -251.625 -652.254] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+251.625 652.254 Td
+/F134_0 9.9626 Tf
+(bzlib_private.h) 89.6634 Tj
+[1 0 0 1 341.289 652.254] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -341.289 -652.254] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+341.289 652.254 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+[1 0 0 1 72 650.72] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -640.757] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 630.336 Td
+/F130_0 9.9626 Tf
+(If) 6.63509 Tj
+-250 TJm
+(you) 14.9439 Tj
+-250 TJm
+(don') 18.2614 Tj
+18 TJm
+(t) 2.7696 Tj
+-250 TJm
+(use) 13.2801 Tj
+-250 TJm
+(VC++,) 27.5665 Tj
+-250 TJm
+(you) 14.9439 Tj
+-250 TJm
+(may) 17.1556 Tj
+-250 TJm
+(need) 18.8094 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(de\002ne) 24.3486 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(proprocessor) 51.4568 Tj
+-250 TJm
+(symbol) 29.3399 Tj
+[1 0 0 1 363.634 630.336] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -363.634 -630.336] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+363.634 630.336 Td
+/F134_0 9.9626 Tf
+(_WIN32) 35.8654 Tj
+[1 0 0 1 399.5 630.336] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -399.5 -630.336] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+399.5 630.336 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+[1 0 0 1 72 628.179] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -618.217] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 608.418 Td
+/F130_0 9.9626 Tf
+(Finally) 28.234 Tj
+65 TJm
+(,) 2.49065 Tj
+[1 0 0 1 104.568 608.418] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -104.568 -608.418] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+104.568 608.418 Td
+/F134_0 9.9626 Tf
+(dlltest.c) 53.798 Tj
+[1 0 0 1 158.366 608.418] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -158.366 -608.418] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+160.856 608.418 Td
+/F130_0 9.9626 Tf
+(is) 6.64505 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(sample) 28.224 Tj
+-250 TJm
+(program) 33.7533 Tj
+-250 TJm
+(using) 21.589 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(DLL.) 21.8579 Tj
+-500 TJm
+(It) 6.08715 Tj
+-250 TJm
+(has) 13.2801 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(project) 27.6661 Tj
+-250 TJm
+(\002le,) 15.2229 Tj
+[1 0 0 1 388.58 608.418] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -388.58 -608.418] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+388.58 608.418 Td
+/F134_0 9.9626 Tf
+(dlltest.dsp) 65.7532 Tj
+[1 0 0 1 454.333 608.418] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -454.333 -608.418] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+454.333 608.418 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+[1 0 0 1 72 606.262] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -596.299] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 586.501 Td
+/F130_0 9.9626 Tf
+(If) 6.63509 Tj
+-250 TJm
+(you) 14.9439 Tj
+-250 TJm
+(just) 14.396 Tj
+-250 TJm
+(w) 7.193 Tj
+10 TJm
+(ant) 12.1743 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(mak) 17.1556 Tj
+10 TJm
+(e\002le) 17.1556 Tj
+-250 TJm
+(for) 11.6164 Tj
+-250 TJm
+(V) 7.193 Tj
+60 TJm
+(isual) 18.8194 Tj
+-250 TJm
+(C,) 9.1357 Tj
+-250 TJm
+(ha) 9.40469 Tj
+20 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(look) 17.7135 Tj
+-250 TJm
+(at) 7.193 Tj
+[1 0 0 1 292.212 586.501] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -292.212 -586.501] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+292.212 586.501 Td
+/F134_0 9.9626 Tf
+(makefile.msc) 71.7307 Tj
+[1 0 0 1 363.943 586.501] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -363.943 -586.501] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+363.943 586.501 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+[1 0 0 1 72 584.344] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -574.381] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 564.583 Td
+/F130_0 9.9626 Tf
+(Be) 11.0684 Tj
+-291 TJm
+(a) 4.42339 Tj
+15 TJm
+(w) 7.193 Tj
+10 TJm
+(are) 12.1643 Tj
+-291 TJm
+(that) 14.9439 Tj
+-291 TJm
+(if) 6.08715 Tj
+-291 TJm
+(you) 14.9439 Tj
+-291 TJm
+(compile) 32.0995 Tj
+[1 0 0 1 192.069 564.583] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -192.069 -564.583] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+192.069 564.583 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 221.958 564.583] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -221.958 -564.583] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+224.857 564.583 Td
+/F130_0 9.9626 Tf
+(itself) 19.9252 Tj
+-291 TJm
+(on) 9.9626 Tj
+-291 TJm
+(W) 9.40469 Tj
+40 TJm
+(in32,) 20.2042 Tj
+-301 TJm
+(you) 14.9439 Tj
+-291 TJm
+(must) 19.3773 Tj
+-291 TJm
+(set) 11.0684 Tj
+[1 0 0 1 346.841 564.583] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -346.841 -564.583] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+346.841 564.583 Td
+/F134_0 9.9626 Tf
+(BZ_UNIX) 41.8429 Tj
+[1 0 0 1 388.685 564.583] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -388.685 -564.583] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+391.583 564.583 Td
+/F130_0 9.9626 Tf
+(to) 7.7509 Tj
+-291 TJm
+(0) 4.9813 Tj
+-291 TJm
+(and) 14.386 Tj
+[1 0 0 1 427.399 564.583] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -427.399 -564.583] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+427.399 564.583 Td
+/F134_0 9.9626 Tf
+(BZ_LCCWIN32) 65.7532 Tj
+[1 0 0 1 493.153 564.583] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -493.153 -564.583] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+496.052 564.583 Td
+/F130_0 9.9626 Tf
+(to) 7.7509 Tj
+-291 TJm
+(1,) 7.47195 Tj
+-301 TJm
+(in) 7.7509 Tj
+-291 TJm
+(the) 12.1743 Tj
+72 552.628 Td
+(\002le) 12.7322 Tj
+[1 0 0 1 87.2227 552.628] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -87.2227 -552.628] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+87.2227 552.628 Td
+/F134_0 9.9626 Tf
+(bzip2.c) 41.8429 Tj
+[1 0 0 1 129.066 552.628] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -129.066 -552.628] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+129.066 552.628 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-250 TJm
+(before) 25.4445 Tj
+-250 TJm
+(compiling.) 42.899 Tj
+-310 TJm
+(Otherwise) 40.9463 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(resulting) 34.8691 Tj
+-250 TJm
+(binary) 25.4544 Tj
+-250 TJm
+(w) 7.193 Tj
+10 TJm
+(on') 13.2801 Tj
+18 TJm
+(t) 2.7696 Tj
+-250 TJm
+(w) 7.193 Tj
+10 TJm
+(ork) 13.2801 Tj
+-250 TJm
+(correctly) 35.4071 Tj
+65 TJm
+(.) 2.49065 Tj
+[1 0 0 1 72 550.471] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -540.508] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 530.71 Td
+/F130_0 9.9626 Tf
+(I) 3.31755 Tj
+-250 TJm
+(ha) 9.40469 Tj
+20 TJm
+(v) 4.9813 Tj
+15 TJm
+(en') 12.7222 Tj
+18 TJm
+(t) 2.7696 Tj
+-250 TJm
+(tried) 18.2614 Tj
+-250 TJm
+(an) 9.40469 Tj
+15 TJm
+(y) 4.9813 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(this) 14.396 Tj
+-250 TJm
+(stuf) 14.9439 Tj
+25 TJm
+(f) 3.31755 Tj
+-250 TJm
+(myself,) 29.6088 Tj
+-250 TJm
+(b) 4.9813 Tj
+20 TJm
+(ut) 7.7509 Tj
+-250 TJm
+(it) 5.53921 Tj
+-250 TJm
+(all) 9.9626 Tj
+-250 TJm
+(looks) 21.589 Tj
+-250 TJm
+(plausible.) 38.4656 Tj
+[1 0 0 1 72 528.553] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 0 -477.701] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 374.394 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 6.8541] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 40.5726 -6.7545] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -493.841 -50.9514] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+534.414 50.9514 Td
+/F130_0 9.9626 Tf
+(30) 9.9626 Tj
+[1 0 0 1 453.269 50.8518] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 93.5985 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.2765 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+Q
+showpage
+%%PageTrailer
+pdfEndPage
+%%Page: 34 34
+%%BeginPageSetup
+%%PageOrientation: Portrait
+pdfStartPage
+0 0 612 792 re W
+%%EndPageSetup
+[] 0 d
+1 i
+0 j
+0 J
+10 M
+1 w
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+false op
+false OP
+0 0 612 792 re
+W
+q
+[1 0 0 1 72 741.554] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 14.4459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 187.197 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 140.398 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -140.398 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 280.796 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -472.974 -13.9477] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -0.4981] cm
+q
+[] 0 d
+0 J
+0.4981 w
+0 0.2491 m
+475.465 0.2491 l
+S
+Q
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 479.251 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -21.5542] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -720] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 701.916 Td
+/F122_0 24.7902 Tf
+(4.) 20.675 Tj
+-278 TJm
+(Miscellanea) 139.172 Tj
+[1 0 0 1 72 701.606] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 0 -9.1347] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -14.1161] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -678.355] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 658.006 Td
+/F122_0 17.2154 Tf
+(T) 10.5186 Tj
+80 TJm
+(ab) 20.0904 Tj
+10 TJm
+(le) 14.3576 Tj
+-278 TJm
+(of) 16.2513 Tj
+-278 TJm
+(Contents) 74.5943 Tj
+[1 0 0 1 72 649.183] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -11.7401] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -637.443] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 637.443 Td
+/F130_0 9.9626 Tf
+(4.1.) 14.9439 Tj
+-310 TJm
+(Limitations) 45.9475 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(compressed) 47.0334 Tj
+-250 TJm
+(\002le) 12.7322 Tj
+-250 TJm
+(format) 26.5603 Tj
+[1 0 0 1 255.231 637.443] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -260.212 -637.443] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+269.154 637.443 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 637.443] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -637.443] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 637.443 Td
+/F130_0 9.9626 Tf
+(31) 9.9626 Tj
+[1 0 0 1 516.09 637.443] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7984] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -625.488] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 625.488 Td
+/F130_0 9.9626 Tf
+(4.2.) 14.9439 Tj
+-310 TJm
+(Portability) 42.0721 Tj
+-250 TJm
+(issues) 23.8007 Tj
+[1 0 0 1 158.395 625.488] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -163.376 -625.488] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+172.03 625.488 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 625.488] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -625.488] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 625.488 Td
+/F130_0 9.9626 Tf
+(32) 9.9626 Tj
+[1 0 0 1 516.09 625.488] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7984] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -613.533] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 613.533 Td
+/F130_0 9.9626 Tf
+(4.3.) 14.9439 Tj
+-310 TJm
+(Reporting) 39.8504 Tj
+-250 TJm
+(b) 4.9813 Tj
+20 TJm
+(ugs) 13.8381 Tj
+[1 0 0 1 150.993 613.533] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -155.975 -613.533] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+166.115 613.533 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 613.533] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -613.533] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 613.533 Td
+/F130_0 9.9626 Tf
+(32) 9.9626 Tj
+[1 0 0 1 516.09 613.533] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7983] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -601.578] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 601.578 Td
+/F130_0 9.9626 Tf
+(4.4.) 14.9439 Tj
+-310 TJm
+(Did) 14.9439 Tj
+-250 TJm
+(you) 14.9439 Tj
+-250 TJm
+(get) 12.1743 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(right) 18.8194 Tj
+-250 TJm
+(package?) 37.0609 Tj
+[1 0 0 1 212.602 601.578] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 3.0884 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 3.0884 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -218.778 -601.578] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+229.109 601.578 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 601.578] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -601.578] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 601.578 Td
+/F130_0 9.9626 Tf
+(33) 9.9626 Tj
+[1 0 0 1 516.09 601.578] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.7984] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -589.623] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 589.623 Td
+/F130_0 9.9626 Tf
+(4.5.) 14.9439 Tj
+-310 TJm
+(Further) 29.3299 Tj
+-250 TJm
+(Reading) 33.2053 Tj
+[1 0 0 1 155.058 589.623] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4906 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -160.039 -589.623] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+170.361 589.623 Td
+/F147_0 9.9626 Tf
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+-166 TJm
+(:) 2.7696 Tj
+-167 TJm
+(:) 2.7696 Tj
+[1 0 0 1 506.127 589.623] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -506.127 -589.623] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+506.127 589.623 Td
+/F130_0 9.9626 Tf
+(34) 9.9626 Tj
+[1 0 0 1 516.09 589.623] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -444.09 -2.1568] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.1348] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 0 -9.6315] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -568.7] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 558.901 Td
+/F130_0 9.9626 Tf
+(These) 23.7907 Tj
+-250 TJm
+(are) 12.1643 Tj
+-250 TJm
+(just) 14.396 Tj
+-250 TJm
+(some) 21.031 Tj
+-250 TJm
+(random) 30.4357 Tj
+-250 TJm
+(thoughts) 34.3212 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(mine.) 22.4159 Tj
+-620 TJm
+(Y) 7.193 Tj
+110 TJm
+(our) 13.2801 Tj
+-250 TJm
+(mileage) 31.5416 Tj
+-250 TJm
+(may) 17.1556 Tj
+-250 TJm
+(v) 4.9813 Tj
+25 TJm
+(ary) 12.7222 Tj
+65 TJm
+(.) 2.49065 Tj
+[1 0 0 1 72 556.744] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.6315] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -547.113] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 524.48 Td
+/F122_0 20.6585 Tf
+(4.1.) 34.4584 Tj
+-278 TJm
+(Limitations) 110.192 Tj
+-278 TJm
+(of) 19.5016 Tj
+-278 TJm
+(the) 30.9877 Tj
+-278 TJm
+(compressed) 121.699 Tj
+-278 TJm
+(\002le) 29.8515 Tj
+-278 TJm
+(f) 6.87928 Tj
+20 TJm
+(ormat) 57.3893 Tj
+[1 0 0 1 72 520.203] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.6315] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -510.572] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 502.893 Td
+/F134_0 9.9626 Tf
+(bzip2-1.0.X) 65.7532 Tj
+[1 0 0 1 137.753 502.893] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -137.753 -502.893] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+137.753 502.893 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+[1 0 0 1 143.405 502.893] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -143.405 -502.893] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+143.405 502.893 Td
+/F134_0 9.9626 Tf
+(0.9.5) 29.8878 Tj
+[1 0 0 1 173.293 502.893] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -173.293 -502.893] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+176.453 502.893 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 194 502.893] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -194 -502.893] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+194 502.893 Td
+/F134_0 9.9626 Tf
+(0.9.0) 29.8878 Tj
+[1 0 0 1 223.888 502.893] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -223.888 -502.893] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+227.048 502.893 Td
+/F130_0 9.9626 Tf
+(use) 13.2801 Tj
+-317 TJm
+(e) 4.42339 Tj
+15 TJm
+(xactly) 24.3486 Tj
+-317 TJm
+(the) 12.1743 Tj
+-318 TJm
+(same) 20.4731 Tj
+-317 TJm
+(\002le) 12.7322 Tj
+-317 TJm
+(format) 26.5603 Tj
+-317 TJm
+(as) 8.29885 Tj
+-318 TJm
+(the) 12.1743 Tj
+-317 TJm
+(original) 30.9936 Tj
+-317 TJm
+(v) 4.9813 Tj
+15 TJm
+(ersion,) 26.8392 Tj
+[1 0 0 1 455.801 502.893] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -455.801 -502.893] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+455.801 502.893 Td
+/F134_0 9.9626 Tf
+(bzip2-0.1) 53.798 Tj
+[1 0 0 1 509.599 502.893] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -509.599 -502.893] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+509.599 502.893 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+-1023 TJm
+(This) 17.7135 Tj
+72 490.938 Td
+(decision) 33.2053 Tj
+-222 TJm
+(w) 7.193 Tj
+10 TJm
+(as) 8.29885 Tj
+-222 TJm
+(made) 21.579 Tj
+-222 TJm
+(in) 7.7509 Tj
+-221 TJm
+(the) 12.1743 Tj
+-222 TJm
+(interests) 33.2053 Tj
+-222 TJm
+(of) 8.29885 Tj
+-222 TJm
+(stability) 32.1095 Tj
+65 TJm
+(.) 2.49065 Tj
+-601 TJm
+(Creating) 34.3112 Tj
+-222 TJm
+(yet) 12.1743 Tj
+-222 TJm
+(another) 29.8778 Tj
+-222 TJm
+(incompatible) 52.0247 Tj
+-221 TJm
+(compressed) 47.0334 Tj
+-222 TJm
+(\002le) 12.7322 Tj
+-222 TJm
+(format) 26.5603 Tj
+-222 TJm
+(w) 7.193 Tj
+10 TJm
+(ould) 17.7135 Tj
+-222 TJm
+(create) 23.7807 Tj
+72 478.983 Td
+(further) 27.1082 Tj
+-250 TJm
+(confusion) 39.2925 Tj
+-250 TJm
+(and) 14.386 Tj
+-250 TJm
+(disruption) 40.4083 Tj
+-250 TJm
+(for) 11.6164 Tj
+-250 TJm
+(users.) 22.9638 Tj
+[1 0 0 1 72 476.826] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.6315] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -467.194] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 457.396 Td
+/F130_0 9.9626 Tf
+(Ne) 11.6164 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(ertheless,) 37.3498 Tj
+-234 TJm
+(this) 14.396 Tj
+-229 TJm
+(is) 6.64505 Tj
+-230 TJm
+(not) 12.7322 Tj
+-229 TJm
+(a) 4.42339 Tj
+-230 TJm
+(painless) 32.0995 Tj
+-229 TJm
+(decision.) 35.696 Tj
+-606 TJm
+(De) 11.6164 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(elopment) 37.0808 Tj
+-230 TJm
+(w) 7.193 Tj
+10 TJm
+(ork) 13.2801 Tj
+-230 TJm
+(since) 20.4731 Tj
+-229 TJm
+(the) 12.1743 Tj
+-230 TJm
+(release) 27.6562 Tj
+-229 TJm
+(of) 8.29885 Tj
+[1 0 0 1 407.317 457.396] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -407.317 -457.396] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+407.317 457.396 Td
+/F134_0 9.9626 Tf
+(bzip2-0.1) 53.798 Tj
+[1 0 0 1 461.115 457.396] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -461.115 -457.396] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+463.402 457.396 Td
+/F130_0 9.9626 Tf
+(in) 7.7509 Tj
+-230 TJm
+(August) 28.782 Tj
+-229 TJm
+(1997) 19.9252 Tj
+-230 TJm
+(has) 13.2801 Tj
+72 445.441 Td
+(sho) 13.8381 Tj
+25 TJm
+(wn) 12.1743 Tj
+-226 TJm
+(comple) 29.3299 Tj
+15 TJm
+(xities) 21.589 Tj
+-226 TJm
+(in) 7.7509 Tj
+-225 TJm
+(the) 12.1743 Tj
+-226 TJm
+(\002le) 12.7322 Tj
+-226 TJm
+(format) 26.5603 Tj
+-226 TJm
+(which) 24.3486 Tj
+-226 TJm
+(slo) 11.6264 Tj
+25 TJm
+(w) 7.193 Tj
+-225 TJm
+(do) 9.9626 Tj
+25 TJm
+(wn) 12.1743 Tj
+-226 TJm
+(decompression) 59.7656 Tj
+-226 TJm
+(and,) 16.8766 Tj
+-231 TJm
+(in) 7.7509 Tj
+-226 TJm
+(retrospect,) 41.7732 Tj
+-230 TJm
+(are) 12.1643 Tj
+-226 TJm
+(unnecessary) 48.6872 Tj
+65 TJm
+(.) 2.49065 Tj
+-604 TJm
+(These) 23.7907 Tj
+-226 TJm
+(are:) 14.9339 Tj
+[1 0 0 1 72 443.284] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -29.0613] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.9739 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -78.9739 -414.222] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+78.9739 414.222 Td
+/F130_0 9.9626 Tf
+(\225) 3.48691 Tj
+[1 0 0 1 82.4608 414.222] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 1.9925 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -86.944 -414.222] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 414.222 Td
+/F130_0 9.9626 Tf
+(The) 15.4918 Tj
+-265 TJm
+(run-length) 41.5042 Tj
+-266 TJm
+(encoder) 31.5316 Tj
+40 TJm
+(,) 2.49065 Tj
+-269 TJm
+(which) 24.3486 Tj
+-265 TJm
+(is) 6.64505 Tj
+-265 TJm
+(the) 12.1743 Tj
+-266 TJm
+(\002rst) 15.5018 Tj
+-265 TJm
+(of) 8.29885 Tj
+-265 TJm
+(the) 12.1743 Tj
+-266 TJm
+(compression) 50.3609 Tj
+-265 TJm
+(transformations,) 65.0259 Tj
+-269 TJm
+(is) 6.64505 Tj
+-265 TJm
+(entirely) 30.4357 Tj
+-266 TJm
+(irrele) 21.0211 Tj
+25 TJm
+(v) 4.9813 Tj
+25 TJm
+(ant.) 14.6649 Tj
+-711 TJm
+(The) 15.4918 Tj
+-266 TJm
+(original) 30.9936 Tj
+86.944 402.267 Td
+(purpose) 31.5416 Tj
+-301 TJm
+(w) 7.193 Tj
+10 TJm
+(as) 8.29885 Tj
+-301 TJm
+(to) 7.7509 Tj
+-301 TJm
+(protect) 27.6661 Tj
+-301 TJm
+(the) 12.1743 Tj
+-301 TJm
+(sorting) 27.6761 Tj
+-301 TJm
+(algorithm) 38.7446 Tj
+-301 TJm
+(from) 19.3673 Tj
+-301 TJm
+(the) 12.1743 Tj
+-301 TJm
+(v) 4.9813 Tj
+15 TJm
+(ery) 12.7222 Tj
+-301 TJm
+(w) 7.193 Tj
+10 TJm
+(orst) 14.9439 Tj
+-301 TJm
+(case) 17.1456 Tj
+-301 TJm
+(input:) 23.2527 Tj
+-412 TJm
+(a) 4.42339 Tj
+-301 TJm
+(string) 22.6948 Tj
+-301 TJm
+(of) 8.29885 Tj
+-301 TJm
+(repeated) 33.7433 Tj
+-301 TJm
+(symbols.) 35.706 Tj
+-927 TJm
+(But) 14.396 Tj
+86.944 390.312 Td
+(algorithm) 38.7446 Tj
+-274 TJm
+(steps) 19.9252 Tj
+-275 TJm
+(Q6a) 16.5977 Tj
+-274 TJm
+(and) 14.386 Tj
+-274 TJm
+(Q6b) 17.1556 Tj
+-275 TJm
+(in) 7.7509 Tj
+-274 TJm
+(the) 12.1743 Tj
+-274 TJm
+(original) 30.9936 Tj
+-275 TJm
+(Burro) 23.2427 Tj
+25 TJm
+(ws-Wheel) 40.3884 Tj
+1 TJm
+(er) 7.74094 Tj
+-275 TJm
+(technical) 35.965 Tj
+-274 TJm
+(report) 23.7907 Tj
+-274 TJm
+(\(SRC-124\)) 43.7259 Tj
+-275 TJm
+(sho) 13.8381 Tj
+25 TJm
+(w) 7.193 Tj
+-274 TJm
+(ho) 9.9626 Tj
+25 TJm
+(w) 7.193 Tj
+-274 TJm
+(repeats) 28.2141 Tj
+-275 TJm
+(can) 13.8281 Tj
+86.944 378.357 Td
+(be) 9.40469 Tj
+-250 TJm
+(handled) 31.5416 Tj
+-250 TJm
+(without) 30.4457 Tj
+-250 TJm
+(dif) 11.0684 Tj
+25 TJm
+(\002culty) 25.4644 Tj
+-250 TJm
+(in) 7.7509 Tj
+-250 TJm
+(block) 22.1369 Tj
+-250 TJm
+(sorting.) 30.1668 Tj
+[1 0 0 1 269.617 378.357] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -197.617 -21.5867] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.9739 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -78.9739 -356.77] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+78.9739 356.77 Td
+/F130_0 9.9626 Tf
+(\225) 3.48691 Tj
+[1 0 0 1 82.4608 356.77] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 1.9925 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -86.944 -356.77] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 356.77 Td
+/F130_0 9.9626 Tf
+(The) 15.4918 Tj
+-293 TJm
+(randomisation) 57.006 Tj
+-293 TJm
+(mechanism) 45.3796 Tj
+-293 TJm
+(doesn') 26.5603 Tj
+18 TJm
+(t) 2.7696 Tj
+-294 TJm
+(really) 22.6848 Tj
+-293 TJm
+(need) 18.8094 Tj
+-293 TJm
+(to) 7.7509 Tj
+-293 TJm
+(be) 9.40469 Tj
+-293 TJm
+(there.) 22.4059 Tj
+-879 TJm
+(Udi) 14.9439 Tj
+-294 TJm
+(Manber) 30.9837 Tj
+-293 TJm
+(and) 14.386 Tj
+-293 TJm
+(Gene) 21.0211 Tj
+-293 TJm
+(Myers) 25.4544 Tj
+-293 TJm
+(published) 38.7446 Tj
+-294 TJm
+(a) 4.42339 Tj
+-293 TJm
+(suf) 12.1743 Tj
+25 TJm
+(\002x) 10.5205 Tj
+86.944 344.815 Td
+(array) 20.4632 Tj
+-238 TJm
+(construction) 49.2551 Tj
+-239 TJm
+(algorithm) 38.7446 Tj
+-238 TJm
+(a) 4.42339 Tj
+-238 TJm
+(fe) 7.74094 Tj
+25 TJm
+(w) 7.193 Tj
+-239 TJm
+(years) 21.0211 Tj
+-238 TJm
+(back,) 21.3 Tj
+-241 TJm
+(which) 24.3486 Tj
+-238 TJm
+(can) 13.8281 Tj
+-238 TJm
+(be) 9.40469 Tj
+-239 TJm
+(emplo) 24.9065 Tj
+10 TJm
+(yed) 14.386 Tj
+-238 TJm
+(to) 7.7509 Tj
+-238 TJm
+(sort) 14.9439 Tj
+-239 TJm
+(an) 9.40469 Tj
+15 TJm
+(y) 4.9813 Tj
+-238 TJm
+(block,) 24.6275 Tj
+-241 TJm
+(no) 9.9626 Tj
+-238 TJm
+(matter) 25.4544 Tj
+-238 TJm
+(ho) 9.9626 Tj
+25 TJm
+(w) 7.193 Tj
+-239 TJm
+(repetiti) 28.224 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(e,) 6.91404 Tj
+86.944 332.86 Td
+(in) 7.7509 Tj
+-229 TJm
+(O\(N) 17.7035 Tj
+-230 TJm
+(log) 12.7322 Tj
+-229 TJm
+(N\)) 10.5105 Tj
+-230 TJm
+(time.) 20.2042 Tj
+-606 TJm
+(Subsequent) 45.9375 Tj
+-230 TJm
+(w) 7.193 Tj
+10 TJm
+(ork) 13.2801 Tj
+-229 TJm
+(by) 9.9626 Tj
+-230 TJm
+(K) 7.193 Tj
+15 TJm
+(unihik) 25.4644 Tj
+10 TJm
+(o) 4.9813 Tj
+-229 TJm
+(Sadakane) 38.1767 Tj
+-229 TJm
+(has) 13.2801 Tj
+-230 TJm
+(produced) 37.0708 Tj
+-229 TJm
+(a) 4.42339 Tj
+-230 TJm
+(deri) 15.4918 Tj
+25 TJm
+(v) 4.9813 Tj
+25 TJm
+(ati) 9.9626 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-229 TJm
+(O\(N) 17.7035 Tj
+-230 TJm
+(\(log) 16.0497 Tj
+-229 TJm
+(N\)^2\)) 23.4818 Tj
+-230 TJm
+(algorithm) 38.7446 Tj
+86.944 320.905 Td
+(which) 24.3486 Tj
+-250 TJm
+(usually) 28.782 Tj
+-250 TJm
+(outperforms) 48.6972 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(Manber) 30.9837 Tj
+20 TJm
+(-Myers) 28.772 Tj
+-250 TJm
+(algorithm.) 41.2352 Tj
+[1 0 0 1 314.189 320.905] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -242.189 -11.7883] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -309.116] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 299.318 Td
+/F130_0 9.9626 Tf
+(I) 3.31755 Tj
+-248 TJm
+(could) 22.1369 Tj
+-248 TJm
+(ha) 9.40469 Tj
+20 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-248 TJm
+(changed) 33.1954 Tj
+-248 TJm
+(to) 7.7509 Tj
+-248 TJm
+(Sadakane') 41.4942 Tj
+55 TJm
+(s) 3.87545 Tj
+-248 TJm
+(algorithm,) 41.2352 Tj
+-249 TJm
+(b) 4.9813 Tj
+20 TJm
+(ut) 7.7509 Tj
+-248 TJm
+(I) 3.31755 Tj
+-248 TJm
+(\002nd) 15.5018 Tj
+-248 TJm
+(it) 5.53921 Tj
+-248 TJm
+(to) 7.7509 Tj
+-248 TJm
+(be) 9.40469 Tj
+-248 TJm
+(slo) 11.6264 Tj
+25 TJm
+(wer) 14.9339 Tj
+-248 TJm
+(than) 17.1556 Tj
+[1 0 0 1 392.444 299.318] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -392.444 -299.318] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+392.444 299.318 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 422.332 299.318] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -422.332 -299.318] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+422.332 299.318 Td
+/F130_0 9.9626 Tf
+(') 3.31755 Tj
+55 TJm
+(s) 3.87545 Tj
+-248 TJm
+(e) 4.42339 Tj
+15 TJm
+(xisting) 27.1282 Tj
+-248 TJm
+(algorithm) 38.7446 Tj
+-248 TJm
+(for) 11.6164 Tj
+-248 TJm
+(most) 19.3773 Tj
+86.944 287.363 Td
+(inputs,) 26.8492 Tj
+-370 TJm
+(and) 14.386 Tj
+-345 TJm
+(the) 12.1743 Tj
+-346 TJm
+(randomisation) 57.006 Tj
+-346 TJm
+(mechanism) 45.3796 Tj
+-345 TJm
+(protects) 31.5416 Tj
+-346 TJm
+(adequately) 43.158 Tj
+-345 TJm
+(ag) 9.40469 Tj
+5 TJm
+(ainst) 18.8194 Tj
+-346 TJm
+(bad) 14.386 Tj
+-346 TJm
+(cases.) 23.5117 Tj
+-1194 TJm
+(I) 3.31755 Tj
+-345 TJm
+(didn') 21.031 Tj
+18 TJm
+(t) 2.7696 Tj
+-346 TJm
+(think) 20.4831 Tj
+-346 TJm
+(it) 5.53921 Tj
+-345 TJm
+(w) 7.193 Tj
+10 TJm
+(as) 8.29885 Tj
+-346 TJm
+(a) 4.42339 Tj
+-346 TJm
+(good) 19.9252 Tj
+86.944 275.408 Td
+(tradeof) 28.2141 Tj
+25 TJm
+(f) 3.31755 Tj
+-262 TJm
+(to) 7.7509 Tj
+-261 TJm
+(mak) 17.1556 Tj
+10 TJm
+(e.) 6.91404 Tj
+-690 TJm
+(P) 5.53921 Tj
+15 TJm
+(artly) 18.2614 Tj
+-262 TJm
+(this) 14.396 Tj
+-261 TJm
+(is) 6.64505 Tj
+-262 TJm
+(due) 14.386 Tj
+-261 TJm
+(to) 7.7509 Tj
+-262 TJm
+(the) 12.1743 Tj
+-262 TJm
+(f) 3.31755 Tj
+10 TJm
+(act) 11.6164 Tj
+-261 TJm
+(that) 14.9439 Tj
+-262 TJm
+(I) 3.31755 Tj
+-261 TJm
+(w) 7.193 Tj
+10 TJm
+(as) 8.29885 Tj
+-262 TJm
+(not) 12.7322 Tj
+-262 TJm
+(\003ooded) 29.8878 Tj
+-261 TJm
+(with) 17.7135 Tj
+-262 TJm
+(email) 22.1369 Tj
+-261 TJm
+(complaints) 43.7259 Tj
+-262 TJm
+(about) 22.1369 Tj
+[1 0 0 1 479.557 275.408] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -479.557 -275.408] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+479.557 275.408 Td
+/F134_0 9.9626 Tf
+(bzip2-0.1) 53.798 Tj
+[1 0 0 1 533.355 275.408] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -533.355 -275.408] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+533.355 275.408 Td
+/F130_0 9.9626 Tf
+(') 3.31755 Tj
+55 TJm
+(s) 3.87545 Tj
+86.944 263.453 Td
+(performance) 50.341 Tj
+-250 TJm
+(on) 9.9626 Tj
+-250 TJm
+(repetiti) 28.224 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-250 TJm
+(data,) 19.0883 Tj
+-250 TJm
+(so) 8.85675 Tj
+-250 TJm
+(perhaps) 30.9837 Tj
+-250 TJm
+(it) 5.53921 Tj
+-250 TJm
+(isn') 14.9439 Tj
+18 TJm
+(t) 2.7696 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(problem) 33.2053 Tj
+-250 TJm
+(for) 11.6164 Tj
+-250 TJm
+(real) 14.9339 Tj
+-250 TJm
+(inputs.) 26.8492 Tj
+[1 0 0 1 72 261.296] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.6315] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -251.664] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 241.866 Td
+/F130_0 9.9626 Tf
+(Probably) 35.9749 Tj
+-289 TJm
+(the) 12.1743 Tj
+-288 TJm
+(best) 16.0497 Tj
+-289 TJm
+(long-term) 39.2925 Tj
+-289 TJm
+(solution,) 34.6001 Tj
+-298 TJm
+(and) 14.386 Tj
+-289 TJm
+(the) 12.1743 Tj
+-289 TJm
+(one) 14.386 Tj
+-288 TJm
+(I) 3.31755 Tj
+-289 TJm
+(ha) 9.40469 Tj
+20 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-289 TJm
+(incorporated) 50.351 Tj
+-288 TJm
+(into) 15.5018 Tj
+-289 TJm
+(0.9.5) 19.9252 Tj
+-289 TJm
+(and) 14.386 Tj
+-288 TJm
+(abo) 14.386 Tj
+15 TJm
+(v) 4.9813 Tj
+14 TJm
+(e,) 6.91404 Tj
+-298 TJm
+(is) 6.64505 Tj
+-289 TJm
+(to) 7.7509 Tj
+-288 TJm
+(use) 13.2801 Tj
+-289 TJm
+(the) 12.1743 Tj
+-289 TJm
+(e) 4.42339 Tj
+15 TJm
+(xisting) 27.1282 Tj
+86.944 229.911 Td
+(sorting) 27.6761 Tj
+-451 TJm
+(algorithm) 38.7446 Tj
+-452 TJm
+(initially) 31.0036 Tj
+65 TJm
+(,) 2.49065 Tj
+-501 TJm
+(and) 14.386 Tj
+-452 TJm
+(f) 3.31755 Tj
+10 TJm
+(all) 9.9626 Tj
+-451 TJm
+(back) 18.8094 Tj
+-452 TJm
+(to) 7.7509 Tj
+-451 TJm
+(a) 4.42339 Tj
+-451 TJm
+(O\(N) 17.7035 Tj
+-452 TJm
+(\(log) 16.0497 Tj
+-451 TJm
+(N\)^2\)) 23.4818 Tj
+-451 TJm
+(algorithm) 38.7446 Tj
+-452 TJm
+(if) 6.08715 Tj
+-451 TJm
+(the) 12.1743 Tj
+-452 TJm
+(standard) 33.7533 Tj
+-451 TJm
+(algorithm) 38.7446 Tj
+-451 TJm
+(gets) 16.0497 Tj
+-452 TJm
+(into) 15.5018 Tj
+86.944 217.956 Td
+(dif) 11.0684 Tj
+25 TJm
+(\002culties.) 34.0422 Tj
+[1 0 0 1 72 217.856] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -21.4871] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.9739 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -78.9739 -196.369] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+78.9739 196.369 Td
+/F130_0 9.9626 Tf
+(\225) 3.48691 Tj
+[1 0 0 1 82.4608 196.369] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 1.9925 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -86.944 -196.369] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 196.369 Td
+/F130_0 9.9626 Tf
+(The) 15.4918 Tj
+-299 TJm
+(compressed) 47.0334 Tj
+-299 TJm
+(\002le) 12.7322 Tj
+-299 TJm
+(format) 26.5603 Tj
+-299 TJm
+(w) 7.193 Tj
+10 TJm
+(as) 8.29885 Tj
+-300 TJm
+(ne) 9.40469 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(er) 7.74094 Tj
+-299 TJm
+(designed) 35.417 Tj
+-299 TJm
+(to) 7.7509 Tj
+-299 TJm
+(be) 9.40469 Tj
+-299 TJm
+(handled) 31.5416 Tj
+-299 TJm
+(by) 9.9626 Tj
+-299 TJm
+(a) 4.42339 Tj
+-299 TJm
+(library) 26.5603 Tj
+65 TJm
+(,) 2.49065 Tj
+-312 TJm
+(and) 14.386 Tj
+-299 TJm
+(I) 3.31755 Tj
+-299 TJm
+(ha) 9.40469 Tj
+20 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-299 TJm
+(had) 14.386 Tj
+-299 TJm
+(to) 7.7509 Tj
+-299 TJm
+(jump) 20.4831 Tj
+-300 TJm
+(though) 27.6761 Tj
+-299 TJm
+(some) 21.031 Tj
+86.944 184.414 Td
+(hoops) 23.8007 Tj
+-278 TJm
+(to) 7.7509 Tj
+-277 TJm
+(produce) 32.0895 Tj
+-278 TJm
+(an) 9.40469 Tj
+-278 TJm
+(ef) 7.74094 Tj
+25 TJm
+(\002cient) 24.9065 Tj
+-277 TJm
+(implementation) 62.5452 Tj
+-278 TJm
+(of) 8.29885 Tj
+-278 TJm
+(decompression.) 62.2563 Tj
+-786 TJm
+(It') 9.40469 Tj
+55 TJm
+(s) 3.87545 Tj
+-278 TJm
+(a) 4.42339 Tj
+-277 TJm
+(bit) 10.5205 Tj
+-278 TJm
+(hairy) 20.4731 Tj
+65 TJm
+(.) 2.49065 Tj
+-786 TJm
+(T) 6.08715 Tj
+35 TJm
+(ry) 8.29885 Tj
+-278 TJm
+(passing) 29.8878 Tj
+[1 0 0 1 468.269 184.414] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468.269 -184.414] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+468.269 184.414 Td
+/F134_0 9.9626 Tf
+(decompress.c) 71.7307 Tj
+[1 0 0 1 540 184.414] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -540 -184.414] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 172.459 Td
+/F130_0 9.9626 Tf
+(through) 30.9936 Tj
+-268 TJm
+(the) 12.1743 Tj
+-268 TJm
+(C) 6.64505 Tj
+-268 TJm
+(preprocessor) 50.8989 Tj
+-269 TJm
+(and) 14.386 Tj
+-268 TJm
+(you') 18.2614 Tj
+10 TJm
+(ll) 5.53921 Tj
+-268 TJm
+(see) 12.7222 Tj
+-268 TJm
+(what) 19.3673 Tj
+-268 TJm
+(I) 3.31755 Tj
+-268 TJm
+(mean.) 24.0696 Tj
+-729 TJm
+(Much) 23.2427 Tj
+-268 TJm
+(of) 8.29885 Tj
+-269 TJm
+(this) 14.396 Tj
+-268 TJm
+(comple) 29.3299 Tj
+15 TJm
+(xity) 15.5018 Tj
+-268 TJm
+(could) 22.1369 Tj
+-268 TJm
+(ha) 9.40469 Tj
+20 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-268 TJm
+(been) 18.8094 Tj
+-268 TJm
+(a) 4.42339 Tj
+20 TJm
+(v) 4.9813 Tj
+20 TJm
+(oided) 22.1369 Tj
+-269 TJm
+(if) 6.08715 Tj
+-268 TJm
+(the) 12.1743 Tj
+86.944 160.503 Td
+(compressed) 47.0334 Tj
+-250 TJm
+(size) 15.4918 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(each) 18.2515 Tj
+-250 TJm
+(block) 22.1369 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(data) 16.5977 Tj
+-250 TJm
+(w) 7.193 Tj
+10 TJm
+(as) 8.29885 Tj
+-250 TJm
+(recorded) 34.8492 Tj
+-250 TJm
+(in) 7.7509 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(data) 16.5977 Tj
+-250 TJm
+(stream.) 29.0509 Tj
+[1 0 0 1 368.754 160.503] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -296.754 -21.5867] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.9739 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -78.9739 -138.917] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+78.9739 138.917 Td
+/F130_0 9.9626 Tf
+(\225) 3.48691 Tj
+[1 0 0 1 82.4608 138.917] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 1.9925 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -86.944 -138.917] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 138.917 Td
+/F130_0 9.9626 Tf
+(An) 12.1743 Tj
+-250 TJm
+(Adler) 22.6848 Tj
+20 TJm
+(-32) 13.2801 Tj
+-250 TJm
+(checksum,) 42.3311 Tj
+-250 TJm
+(rather) 23.2328 Tj
+-250 TJm
+(than) 17.1556 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(CRC32) 29.8978 Tj
+-250 TJm
+(checksum,) 42.3311 Tj
+-250 TJm
+(w) 7.193 Tj
+10 TJm
+(ould) 17.7135 Tj
+-250 TJm
+(be) 9.40469 Tj
+-250 TJm
+(f) 3.31755 Tj
+10 TJm
+(aster) 18.8094 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(compute.) 36.8018 Tj
+[1 0 0 1 424.934 138.917] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -352.934 -11.7883] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -127.128] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 117.33 Td
+/F130_0 9.9626 Tf
+(It) 6.08715 Tj
+-349 TJm
+(w) 7.193 Tj
+10 TJm
+(ould) 17.7135 Tj
+-349 TJm
+(be) 9.40469 Tj
+-349 TJm
+(f) 3.31755 Tj
+10 TJm
+(air) 10.5105 Tj
+-348 TJm
+(to) 7.7509 Tj
+-349 TJm
+(say) 13.2801 Tj
+-349 TJm
+(that) 14.9439 Tj
+-349 TJm
+(the) 12.1743 Tj
+[1 0 0 1 201.979 117.33] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -201.979 -117.33] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+201.979 117.33 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 231.867 117.33] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -231.867 -117.33] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+235.342 117.33 Td
+/F130_0 9.9626 Tf
+(format) 26.5603 Tj
+-349 TJm
+(w) 7.193 Tj
+10 TJm
+(as) 8.29885 Tj
+-349 TJm
+(frozen) 25.4445 Tj
+-348 TJm
+(before) 25.4445 Tj
+-349 TJm
+(I) 3.31755 Tj
+-349 TJm
+(properly) 33.7533 Tj
+-349 TJm
+(and) 14.386 Tj
+-349 TJm
+(fully) 18.8194 Tj
+-349 TJm
+(understood) 44.2738 Tj
+-348 TJm
+(the) 12.1743 Tj
+-349 TJm
+(performance) 50.341 Tj
+72 105.375 Td
+(consequences) 54.7744 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(doing) 22.6948 Tj
+-250 TJm
+(so.) 11.3474 Tj
+[1 0 0 1 72 103.218] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.6315] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -93.5867] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 83.7883 Td
+/F130_0 9.9626 Tf
+(Impro) 24.3486 Tj
+15 TJm
+(v) 4.9813 Tj
+15 TJm
+(ements) 28.224 Tj
+-250 TJm
+(which) 24.3486 Tj
+-250 TJm
+(I) 3.31755 Tj
+-250 TJm
+(w) 7.193 Tj
+10 TJm
+(as) 8.29885 Tj
+-250 TJm
+(able) 16.5977 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(incorporate) 45.3697 Tj
+-250 TJm
+(into) 15.5018 Tj
+-250 TJm
+(0.9.0,) 22.4159 Tj
+-250 TJm
+(despite) 28.224 Tj
+-250 TJm
+(using) 21.589 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(same) 20.4731 Tj
+-250 TJm
+(\002le) 12.7322 Tj
+-250 TJm
+(format,) 29.0509 Tj
+-250 TJm
+(are:) 14.9339 Tj
+[1 0 0 1 72 81.6315] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -30.7796] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 374.394 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 6.8541] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 40.5726 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -493.841 -50.9514] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+534.414 50.9514 Td
+/F130_0 9.9626 Tf
+(31) 9.9626 Tj
+[1 0 0 1 453.269 50.8519] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 93.5985 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.2765 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+Q
+showpage
+%%PageTrailer
+pdfEndPage
+%%Page: 35 35
+%%BeginPageSetup
+%%PageOrientation: Portrait
+pdfStartPage
+0 0 612 792 re W
+%%EndPageSetup
+[] 0 d
+1 i
+0 j
+0 J
+10 M
+1 w
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+false op
+false OP
+0 0 612 792 re
+W
+q
+[1 0 0 1 72 741.554] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 14.4459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 187.197 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 -6.8541] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 6.8541] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 116.328 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -382.4 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+498.728 749.245 Td
+/F130_0 9.9626 Tf
+(Miscellanea) 48.1393 Tj
+[1 0 0 1 266.071 749.146] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 280.796 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -472.974 -7.0936] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -0.4981] cm
+q
+[] 0 d
+0 J
+0.4981 w
+0 0.2491 m
+475.465 0.2491 l
+S
+Q
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 479.251 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -31.5168] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.9739 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -78.9739 -710.037] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+78.9739 710.037 Td
+/F130_0 9.9626 Tf
+(\225) 3.48691 Tj
+[1 0 0 1 82.4608 710.037] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 1.9925 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -86.944 -710.037] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 710.037 Td
+/F130_0 9.9626 Tf
+(Single) 25.4644 Tj
+-202 TJm
+(array) 20.4632 Tj
+-201 TJm
+(implementation) 62.5452 Tj
+-202 TJm
+(of) 8.29885 Tj
+-202 TJm
+(the) 12.1743 Tj
+-201 TJm
+(in) 7.7509 Tj
+40 TJm
+(v) 4.9813 Tj
+15 TJm
+(erse) 16.0398 Tj
+-202 TJm
+(BWT) 22.1369 Tj
+74 TJm
+(.) 2.49065 Tj
+-403 TJm
+(This) 17.7135 Tj
+-202 TJm
+(signi\002cantly) 49.2651 Tj
+-201 TJm
+(speeds) 26.5603 Tj
+-202 TJm
+(up) 9.9626 Tj
+-202 TJm
+(decompression,) 62.2563 Tj
+-211 TJm
+(presumably) 46.4855 Tj
+-202 TJm
+(because) 31.5316 Tj
+86.944 698.082 Td
+(it) 5.53921 Tj
+-250 TJm
+(reduces) 30.4258 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(number) 30.4357 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(cache) 22.6749 Tj
+-250 TJm
+(misses.) 29.0609 Tj
+[1 0 0 1 240.496 698.082] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -168.496 -21.9178] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.9739 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -78.9739 -676.164] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+78.9739 676.164 Td
+/F130_0 9.9626 Tf
+(\225) 3.48691 Tj
+[1 0 0 1 82.4608 676.164] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 1.9925 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -86.944 -676.164] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 676.164 Td
+/F130_0 9.9626 Tf
+(F) 5.53921 Tj
+15 TJm
+(aster) 18.8094 Tj
+-314 TJm
+(in) 7.7509 Tj
+40 TJm
+(v) 4.9813 Tj
+15 TJm
+(erse) 16.0398 Tj
+-315 TJm
+(MTF) 20.4831 Tj
+-314 TJm
+(transform) 38.7346 Tj
+-315 TJm
+(for) 11.6164 Tj
+-314 TJm
+(lar) 10.5105 Tj
+18 TJm
+(ge) 9.40469 Tj
+-315 TJm
+(MTF) 20.4831 Tj
+-314 TJm
+(v) 4.9813 Tj
+25 TJm
+(alues.) 22.9638 Tj
+-504 TJm
+(The) 15.4918 Tj
+-314 TJm
+(ne) 9.40469 Tj
+25 TJm
+(w) 7.193 Tj
+-314 TJm
+(implementation) 62.5452 Tj
+-315 TJm
+(is) 6.64505 Tj
+-314 TJm
+(based) 22.6848 Tj
+-315 TJm
+(on) 9.9626 Tj
+-314 TJm
+(the) 12.1743 Tj
+-315 TJm
+(notion) 25.4644 Tj
+-314 TJm
+(of) 8.29885 Tj
+-315 TJm
+(sliding) 27.1282 Tj
+86.944 664.209 Td
+(blocks) 26.0123 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(v) 4.9813 Tj
+25 TJm
+(alues.) 22.9638 Tj
+[1 0 0 1 153.932 664.209] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -81.9321 -21.9178] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.9739 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -78.9739 -642.291] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+78.9739 642.291 Td
+/F130_0 9.9626 Tf
+(\225) 3.48691 Tj
+[1 0 0 1 82.4608 642.291] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 1.9925 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -86.944 -642.291] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 642.291 Td
+/F134_0 9.9626 Tf
+(bzip2-0.9.0) 65.7532 Tj
+[1 0 0 1 152.697 642.291] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -152.697 -642.291] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+155.412 642.291 Td
+/F130_0 9.9626 Tf
+(no) 9.9626 Tj
+25 TJm
+(w) 7.193 Tj
+-272 TJm
+(reads) 21.0211 Tj
+-273 TJm
+(and) 14.386 Tj
+-272 TJm
+(writes) 24.3486 Tj
+-273 TJm
+(\002les) 16.6077 Tj
+-272 TJm
+(with) 17.7135 Tj
+[1 0 0 1 282.68 642.291] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -282.68 -642.291] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+282.68 642.291 Td
+/F134_0 9.9626 Tf
+(fread) 29.8878 Tj
+[1 0 0 1 312.568 642.291] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -312.568 -642.291] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+315.282 642.291 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 332.383 642.291] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -332.383 -642.291] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+332.383 642.291 Td
+/F134_0 9.9626 Tf
+(fwrite) 35.8654 Tj
+[1 0 0 1 368.248 642.291] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -368.248 -642.291] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+368.248 642.291 Td
+/F130_0 9.9626 Tf
+(;) 2.7696 Tj
+-284 TJm
+(v) 4.9813 Tj
+15 TJm
+(ersion) 24.3486 Tj
+-272 TJm
+(0.1) 12.4533 Tj
+-273 TJm
+(used) 18.2614 Tj
+[1 0 0 1 441.882 642.291] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -441.882 -642.291] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+441.882 642.291 Td
+/F134_0 9.9626 Tf
+(putc) 23.9102 Tj
+[1 0 0 1 465.792 642.291] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -465.792 -642.291] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+468.507 642.291 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 485.607 642.291] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -485.607 -642.291] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+485.607 642.291 Td
+/F134_0 9.9626 Tf
+(getc) 23.9102 Tj
+[1 0 0 1 509.517 642.291] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -509.517 -642.291] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+509.517 642.291 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+-755 TJm
+(Duh!) 20.4731 Tj
+86.944 630.336 Td
+(W) 9.40469 Tj
+80 TJm
+(ell,) 12.4533 Tj
+-250 TJm
+(you) 14.9439 Tj
+-250 TJm
+(li) 5.53921 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-250 TJm
+(and) 14.386 Tj
+-250 TJm
+(learn.) 22.4059 Tj
+[1 0 0 1 184.248 630.336] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -112.248 -12.1195] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -618.217] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 608.418 Td
+/F130_0 9.9626 Tf
+(Further) 29.3299 Tj
+-304 TJm
+(ahead,) 25.7234 Tj
+-318 TJm
+(it) 5.53921 Tj
+-305 TJm
+(w) 7.193 Tj
+10 TJm
+(ould) 17.7135 Tj
+-304 TJm
+(be) 9.40469 Tj
+-305 TJm
+(nice) 16.5977 Tj
+-304 TJm
+(to) 7.7509 Tj
+-305 TJm
+(be) 9.40469 Tj
+-304 TJm
+(able) 16.5977 Tj
+-304 TJm
+(to) 7.7509 Tj
+-305 TJm
+(do) 9.9626 Tj
+-304 TJm
+(random) 30.4357 Tj
+-305 TJm
+(access) 25.4445 Tj
+-304 TJm
+(into) 15.5018 Tj
+-305 TJm
+(\002les.) 19.0983 Tj
+-946 TJm
+(This) 17.7135 Tj
+-305 TJm
+(will) 15.5018 Tj
+-304 TJm
+(require) 28.2141 Tj
+-304 TJm
+(some) 21.031 Tj
+-305 TJm
+(careful) 27.6562 Tj
+-304 TJm
+(design) 26.0123 Tj
+-305 TJm
+(of) 8.29885 Tj
+72 596.463 Td
+(compressed) 47.0334 Tj
+-250 TJm
+(\002le) 12.7322 Tj
+-250 TJm
+(formats.) 32.9264 Tj
+[1 0 0 1 72 594.306] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -584.344] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 561.71 Td
+/F122_0 20.6585 Tf
+(4.2.) 34.4584 Tj
+-278 TJm
+(P) 13.7792 Tj
+40 TJm
+(or) 20.6585 Tj
+-20 TJm
+(tability) 66.5823 Tj
+-278 TJm
+(issues) 64.3099 Tj
+[1 0 0 1 72 557.434] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -547.472] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 539.793 Td
+/F130_0 9.9626 Tf
+(After) 21.0211 Tj
+-250 TJm
+(some) 21.031 Tj
+-250 TJm
+(consideration,) 56.1691 Tj
+-250 TJm
+(I) 3.31755 Tj
+-250 TJm
+(ha) 9.40469 Tj
+20 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-250 TJm
+(decided) 30.9837 Tj
+-250 TJm
+(not) 12.7322 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(use) 13.2801 Tj
+-250 TJm
+(GNU) 21.579 Tj
+[1 0 0 1 303.231 539.793] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -303.231 -539.793] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+303.231 539.793 Td
+/F134_0 9.9626 Tf
+(autoconf) 47.8205 Tj
+[1 0 0 1 351.052 539.793] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -351.052 -539.793] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+353.542 539.793 Td
+/F130_0 9.9626 Tf
+(to) 7.7509 Tj
+-250 TJm
+(con\002gure) 37.6287 Tj
+-250 TJm
+(0.9.5) 19.9252 Tj
+-250 TJm
+(or) 8.29885 Tj
+-250 TJm
+(1.0.) 14.9439 Tj
+[1 0 0 1 72 537.636] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -527.673] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 517.875 Td
+/F134_0 9.9626 Tf
+(autoconf) 47.8205 Tj
+[1 0 0 1 119.821 517.875] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -119.821 -517.875] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+119.821 517.875 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-502 TJm
+(admirable) 39.8404 Tj
+-452 TJm
+(and) 14.386 Tj
+-452 TJm
+(w) 7.193 Tj
+10 TJm
+(onderful) 33.7533 Tj
+-452 TJm
+(though) 27.6761 Tj
+-452 TJm
+(it) 5.53921 Tj
+-452 TJm
+(is,) 9.1357 Tj
+-502 TJm
+(mainly) 27.6761 Tj
+-452 TJm
+(assists) 25.4644 Tj
+-452 TJm
+(with) 17.7135 Tj
+-452 TJm
+(portability) 41.5142 Tj
+-452 TJm
+(problems) 37.0808 Tj
+-452 TJm
+(between) 33.1954 Tj
+-452 TJm
+(Unix-lik) 33.7633 Tj
+10 TJm
+(e) 4.42339 Tj
+72 505.92 Td
+(platforms.) 40.6773 Tj
+-1398 TJm
+(But) 14.396 Tj
+[1 0 0 1 144.784 505.92] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -144.784 -505.92] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+144.784 505.92 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 174.672 505.92] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -174.672 -505.92] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+178.455 505.92 Td
+/F130_0 9.9626 Tf
+(doesn') 26.5603 Tj
+18 TJm
+(t) 2.7696 Tj
+-380 TJm
+(ha) 9.40469 Tj
+20 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-379 TJm
+(much) 22.1369 Tj
+-380 TJm
+(in) 7.7509 Tj
+-380 TJm
+(the) 12.1743 Tj
+-379 TJm
+(w) 7.193 Tj
+10 TJm
+(ay) 9.40469 Tj
+-380 TJm
+(of) 8.29885 Tj
+-380 TJm
+(portability) 41.5142 Tj
+-379 TJm
+(problems) 37.0808 Tj
+-380 TJm
+(on) 9.9626 Tj
+-380 TJm
+(Unix;) 22.6948 Tj
+-444 TJm
+(most) 19.3773 Tj
+-380 TJm
+(of) 8.29885 Tj
+-380 TJm
+(the) 12.1743 Tj
+-379 TJm
+(dif) 11.0684 Tj
+25 TJm
+(\002culties) 31.5516 Tj
+72 493.964 Td
+(appear) 26.5503 Tj
+-297 TJm
+(when) 21.579 Tj
+-296 TJm
+(po) 9.9626 Tj
+-1 TJm
+(r) 3.31755 Tj
+1 TJm
+(ting) 15.5018 Tj
+-297 TJm
+(to) 7.7509 Tj
+-297 TJm
+(the) 12.1743 Tj
+-297 TJm
+(Mac,) 20.1942 Tj
+-308 TJm
+(or) 8.29885 Tj
+-297 TJm
+(to) 7.7509 Tj
+-297 TJm
+(Microsoft') 42.61 Tj
+55 TJm
+(s) 3.87545 Tj
+-296 TJm
+(operating) 37.6287 Tj
+-297 TJm
+(systems.) 34.0422 Tj
+[1 0 0 1 361.339 493.964] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -361.339 -493.964] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+361.339 493.964 Td
+/F134_0 9.9626 Tf
+(autoconf) 47.8205 Tj
+[1 0 0 1 409.16 493.964] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -409.16 -493.964] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+412.116 493.964 Td
+/F130_0 9.9626 Tf
+(doesn') 26.5603 Tj
+18 TJm
+(t) 2.7696 Tj
+-297 TJm
+(help) 17.1556 Tj
+-296 TJm
+(in) 7.7509 Tj
+-297 TJm
+(those) 21.031 Tj
+-297 TJm
+(cases,) 23.5117 Tj
+-308 TJm
+(and) 14.386 Tj
+72 482.009 Td
+(brings) 24.9065 Tj
+-250 TJm
+(in) 7.7509 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(whole) 24.3486 Tj
+-250 TJm
+(load) 17.1556 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(ne) 9.40469 Tj
+25 TJm
+(w) 7.193 Tj
+-250 TJm
+(comple) 29.3299 Tj
+15 TJm
+(xity) 15.5018 Tj
+65 TJm
+(.) 2.49065 Tj
+[1 0 0 1 72 479.852] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -469.89] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 460.091 Td
+/F130_0 9.9626 Tf
+(Most) 20.4831 Tj
+-392 TJm
+(people) 26.5603 Tj
+-392 TJm
+(should) 26.5703 Tj
+-393 TJm
+(be) 9.40469 Tj
+-392 TJm
+(able) 16.5977 Tj
+-392 TJm
+(to) 7.7509 Tj
+-392 TJm
+(compile) 32.0995 Tj
+-393 TJm
+(the) 12.1743 Tj
+-392 TJm
+(library) 26.5603 Tj
+-392 TJm
+(and) 14.386 Tj
+-392 TJm
+(program) 33.7533 Tj
+-393 TJm
+(under) 22.6848 Tj
+-392 TJm
+(Unix) 19.9252 Tj
+-392 TJm
+(straight) 29.8878 Tj
+-392 TJm
+(out-of-the-box,) 60.5925 Tj
+-428 TJm
+(so) 8.85675 Tj
+-392 TJm
+(to) 7.7509 Tj
+-393 TJm
+(speak,) 25.1755 Tj
+72 448.136 Td
+(especially) 39.8404 Tj
+-250 TJm
+(if) 6.08715 Tj
+-250 TJm
+(you) 14.9439 Tj
+-250 TJm
+(ha) 9.40469 Tj
+20 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(v) 4.9813 Tj
+15 TJm
+(ersion) 24.3486 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(GNU) 21.579 Tj
+-250 TJm
+(C) 6.64505 Tj
+-250 TJm
+(a) 4.42339 Tj
+20 TJm
+(v) 4.9813 Tj
+25 TJm
+(ailable.) 29.0509 Tj
+[1 0 0 1 72 445.979] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -436.017] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 426.218 Td
+/F130_0 9.9626 Tf
+(There) 23.2328 Tj
+-259 TJm
+(are) 12.1643 Tj
+-258 TJm
+(a) 4.42339 Tj
+-259 TJm
+(couple) 26.5603 Tj
+-258 TJm
+(of) 8.29885 Tj
+[1 0 0 1 159.561 426.218] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -159.561 -426.218] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+159.561 426.218 Td
+/F134_0 9.9626 Tf
+(__inline__) 59.7756 Tj
+[1 0 0 1 219.337 426.218] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -219.337 -426.218] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+221.913 426.218 Td
+/F130_0 9.9626 Tf
+(directi) 25.4544 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(es) 8.29885 Tj
+-259 TJm
+(in) 7.7509 Tj
+-258 TJm
+(the) 12.1743 Tj
+-259 TJm
+(code.) 21.3 Tj
+-671 TJm
+(GNU) 21.579 Tj
+-259 TJm
+(C) 6.64505 Tj
+-258 TJm
+(\() 3.31755 Tj
+[1 0 0 1 352.587 426.218] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -352.587 -426.218] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+352.587 426.218 Td
+/F134_0 9.9626 Tf
+(gcc) 17.9327 Tj
+[1 0 0 1 370.52 426.218] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -370.52 -426.218] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+370.52 426.218 Td
+/F130_0 9.9626 Tf
+(\)) 3.31755 Tj
+-259 TJm
+(should) 26.5703 Tj
+-258 TJm
+(be) 9.40469 Tj
+-259 TJm
+(able) 16.5977 Tj
+-258 TJm
+(to) 7.7509 Tj
+-259 TJm
+(handle) 26.5603 Tj
+-259 TJm
+(them.) 22.4159 Tj
+-671 TJm
+(If) 6.63509 Tj
+-259 TJm
+(you') 18.2614 Tj
+50 TJm
+(re) 7.74094 Tj
+72 414.263 Td
+(not) 12.7322 Tj
+-279 TJm
+(using) 21.589 Tj
+-279 TJm
+(GNU) 21.579 Tj
+-279 TJm
+(C,) 9.1357 Tj
+-279 TJm
+(your) 18.2614 Tj
+-279 TJm
+(C) 6.64505 Tj
+-279 TJm
+(compiler) 35.417 Tj
+-279 TJm
+(shouldn') 34.8691 Tj
+18 TJm
+(t) 2.7696 Tj
+-279 TJm
+(see) 12.7222 Tj
+-279 TJm
+(them) 19.9252 Tj
+-279 TJm
+(at) 7.193 Tj
+-279 TJm
+(all.) 12.4533 Tj
+-794 TJm
+(If) 6.63509 Tj
+-279 TJm
+(your) 18.2614 Tj
+-279 TJm
+(compiler) 35.417 Tj
+-279 TJm
+(does,) 20.7521 Tj
+-286 TJm
+(for) 11.6164 Tj
+-279 TJm
+(some) 21.031 Tj
+-279 TJm
+(reason,) 28.493 Tj
+-287 TJm
+(see) 12.7222 Tj
+-279 TJm
+(them) 19.9252 Tj
+-279 TJm
+(and) 14.386 Tj
+72 402.308 Td
+(doesn') 26.5603 Tj
+18 TJm
+(t) 2.7696 Tj
+-283 TJm
+(lik) 10.5205 Tj
+10 TJm
+(e) 4.42339 Tj
+-283 TJm
+(them,) 22.4159 Tj
+-291 TJm
+(just) 14.396 Tj
+[1 0 0 1 164.167 402.308] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -164.167 -402.308] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+164.167 402.308 Td
+/F134_0 9.9626 Tf
+(#define) 41.8429 Tj
+[1 0 0 1 206.01 402.308] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.8196 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -208.829 -402.308] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+208.829 402.308 Td
+/F134_0 9.9626 Tf
+(__inline__) 59.7756 Tj
+[1 0 0 1 268.605 402.308] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -268.605 -402.308] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+271.425 402.308 Td
+/F130_0 9.9626 Tf
+(to) 7.7509 Tj
+-283 TJm
+(be) 9.40469 Tj
+[1 0 0 1 294.22 402.308] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -294.22 -402.308] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+294.22 402.308 Td
+/F134_0 9.9626 Tf
+(/) 5.97756 Tj
+300.197 400.565 Td
+(*) 5.97756 Tj
+-600 TJm
+(*) 5.97756 Tj
+318.13 402.308 Td
+(/) 5.97756 Tj
+[1 0 0 1 324.108 402.308] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -324.108 -402.308] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+324.108 402.308 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+-818 TJm
+(One) 16.5977 Tj
+-283 TJm
+(easy) 17.7035 Tj
+-283 TJm
+(w) 7.193 Tj
+10 TJm
+(ay) 9.40469 Tj
+-283 TJm
+(to) 7.7509 Tj
+-283 TJm
+(do) 9.9626 Tj
+-283 TJm
+(this) 14.396 Tj
+-283 TJm
+(is) 6.64505 Tj
+-283 TJm
+(to) 7.7509 Tj
+-283 TJm
+(compile) 32.0995 Tj
+-283 TJm
+(with) 17.7135 Tj
+-283 TJm
+(the) 12.1743 Tj
+-283 TJm
+(\003ag) 14.9439 Tj
+[1 0 0 1 72 390.353] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -390.353] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 390.353 Td
+/F134_0 9.9626 Tf
+(-D__inline__=) 77.7083 Tj
+[1 0 0 1 149.709 390.353] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -149.709 -390.353] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+149.709 390.353 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-250 TJm
+(which) 24.3486 Tj
+-250 TJm
+(should) 26.5703 Tj
+-250 TJm
+(be) 9.40469 Tj
+-250 TJm
+(understood) 44.2738 Tj
+-250 TJm
+(by) 9.9626 Tj
+-250 TJm
+(most) 19.3773 Tj
+-250 TJm
+(Unix) 19.9252 Tj
+-250 TJm
+(compilers.) 41.7831 Tj
+[1 0 0 1 72 388.196] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -378.233] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 368.435 Td
+/F130_0 9.9626 Tf
+(If) 6.63509 Tj
+-321 TJm
+(you) 14.9439 Tj
+-321 TJm
+(still) 14.9539 Tj
+-322 TJm
+(ha) 9.40469 Tj
+20 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-321 TJm
+(dif) 11.0684 Tj
+25 TJm
+(\002culties,) 34.0422 Tj
+-339 TJm
+(try) 11.0684 Tj
+-321 TJm
+(compiling) 40.4083 Tj
+-321 TJm
+(with) 17.7135 Tj
+-322 TJm
+(t) 2.7696 Tj
+1 TJm
+(he) 9.40469 Tj
+-322 TJm
+(macro) 24.8965 Tj
+[1 0 0 1 310.295 368.435] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -310.295 -368.435] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+310.295 368.435 Td
+/F134_0 9.9626 Tf
+(BZ_STRICT_ANSI) 83.6858 Tj
+[1 0 0 1 393.981 368.435] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -393.981 -368.435] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+397.18 368.435 Td
+/F130_0 9.9626 Tf
+(de\002ned.) 31.8205 Tj
+-524 TJm
+(This) 17.7135 Tj
+-321 TJm
+(should) 26.5703 Tj
+-321 TJm
+(enable) 26.0024 Tj
+-321 TJm
+(you) 14.9439 Tj
+-322 TJm
+(to) 7.7509 Tj
+72 356.48 Td
+(b) 4.9813 Tj
+20 TJm
+(uild) 15.5018 Tj
+-321 TJm
+(the) 12.1743 Tj
+-321 TJm
+(library) 26.5603 Tj
+-322 TJm
+(in) 7.7509 Tj
+-321 TJm
+(a) 4.42339 Tj
+-321 TJm
+(strictly) 27.6761 Tj
+-321 TJm
+(ANSI) 23.2427 Tj
+-321 TJm
+(compliant) 39.8504 Tj
+-322 TJm
+(en) 9.40469 Tj
+40 TJm
+(vironment.) 43.4469 Tj
+-1047 TJm
+(Building) 34.8791 Tj
+-321 TJm
+(the) 12.1743 Tj
+-321 TJm
+(program) 33.7533 Tj
+-322 TJm
+(itself) 19.9252 Tj
+-321 TJm
+(lik) 10.5205 Tj
+10 TJm
+(e) 4.42339 Tj
+-321 TJm
+(this) 14.396 Tj
+-321 TJm
+(is) 6.64505 Tj
+-321 TJm
+(dangerous) 40.9463 Tj
+-322 TJm
+(and) 14.386 Tj
+72 344.525 Td
+(not) 12.7322 Tj
+-260 TJm
+(supported,) 41.7831 Tj
+-263 TJm
+(since) 20.4731 Tj
+-260 TJm
+(you) 14.9439 Tj
+-260 TJm
+(remo) 20.4731 Tj
+15 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+[1 0 0 1 204.498 344.525] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -204.498 -344.525] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+204.498 344.525 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 234.386 344.525] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -234.386 -344.525] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+234.386 344.525 Td
+/F130_0 9.9626 Tf
+(') 3.31755 Tj
+55 TJm
+(s) 3.87545 Tj
+-260 TJm
+(checks) 27.1082 Tj
+-260 TJm
+(ag) 9.40469 Tj
+5 TJm
+(ainst) 18.8194 Tj
+-261 TJm
+(compressi) 40.3983 Tj
+1 TJm
+(ng) 9.9626 Tj
+-261 TJm
+(directories,) 44.5428 Tj
+-262 TJm
+(symbolic) 36.5329 Tj
+-261 TJm
+(links,) 21.8679 Tj
+-262 TJm
+(de) 9.40469 Tj
+25 TJm
+(vices,) 22.9638 Tj
+-263 TJm
+(and) 14.386 Tj
+-260 TJm
+(other) 20.4731 Tj
+72 332.57 Td
+(not-really-a-\002le) 62.5253 Tj
+-250 TJm
+(entities.) 31.2726 Tj
+-620 TJm
+(This) 17.7135 Tj
+-250 TJm
+(could) 22.1369 Tj
+-250 TJm
+(cause) 22.1269 Tj
+-250 TJm
+(\002lesystem) 40.4083 Tj
+-250 TJm
+(corruption!) 44.8217 Tj
+[1 0 0 1 72 330.413] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -320.45] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 310.652 Td
+/F130_0 9.9626 Tf
+(One) 16.5977 Tj
+-392 TJm
+(other) 20.4731 Tj
+-391 TJm
+(thing:) 23.2527 Tj
+-594 TJm
+(if) 6.08715 Tj
+-391 TJm
+(you) 14.9439 Tj
+-392 TJm
+(create) 23.7807 Tj
+-391 TJm
+(a) 4.42339 Tj
+[1 0 0 1 210.879 310.652] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -210.879 -310.652] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+210.879 310.652 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 240.767 310.652] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -240.767 -310.652] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+244.669 310.652 Td
+/F130_0 9.9626 Tf
+(binary) 25.4544 Tj
+-392 TJm
+(for) 11.6164 Tj
+-391 TJm
+(public) 24.9065 Tj
+-392 TJm
+(distrib) 25.4644 Tj
+20 TJm
+(ution,) 22.9738 Tj
+-427 TJm
+(please) 24.8965 Tj
+-392 TJm
+(consider) 33.7533 Tj
+-391 TJm
+(linking) 28.234 Tj
+-392 TJm
+(it) 5.53921 Tj
+-391 TJm
+(statically) 35.9749 Tj
+-392 TJm
+(\() 3.31755 Tj
+[1 0 0 1 522.067 310.652] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -522.067 -310.652] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+522.067 310.652 Td
+/F134_0 9.9626 Tf
+(gcc) 17.9327 Tj
+72 298.697 Td
+(-static) 41.8429 Tj
+[1 0 0 1 113.843 298.697] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -113.843 -298.697] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+113.843 298.697 Td
+/F130_0 9.9626 Tf
+(\).) 5.8082 Tj
+-620 TJm
+(This) 17.7135 Tj
+-250 TJm
+(a) 4.42339 Tj
+20 TJm
+(v) 4.9813 Tj
+20 TJm
+(oids) 16.6077 Tj
+-250 TJm
+(all) 9.9626 Tj
+-250 TJm
+(sorts) 18.8194 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(library-v) 34.8591 Tj
+15 TJm
+(ersion) 24.3486 Tj
+-250 TJm
+(issues) 23.8007 Tj
+-250 TJm
+(that) 14.9439 Tj
+-250 TJm
+(others) 24.3486 Tj
+-250 TJm
+(may) 17.1556 Tj
+-250 TJm
+(encounter) 39.2825 Tj
+-250 TJm
+(later) 17.7035 Tj
+-250 TJm
+(on.) 12.4533 Tj
+[1 0 0 1 72 296.54] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -286.577] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 276.779 Td
+/F130_0 9.9626 Tf
+(If) 6.63509 Tj
+-296 TJm
+(you) 14.9439 Tj
+-296 TJm
+(b) 4.9813 Tj
+20 TJm
+(uild) 15.5018 Tj
+[1 0 0 1 122.709 276.779] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -122.709 -276.779] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+122.709 276.779 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 152.596 276.779] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -152.596 -276.779] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+155.545 276.779 Td
+/F130_0 9.9626 Tf
+(on) 9.9626 Tj
+-296 TJm
+(W) 9.40469 Tj
+40 TJm
+(in32,) 20.2042 Tj
+-307 TJm
+(you) 14.9439 Tj
+-296 TJm
+(must) 19.3773 Tj
+-296 TJm
+(set) 11.0684 Tj
+[1 0 0 1 254.965 276.779] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -254.965 -276.779] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+254.965 276.779 Td
+/F134_0 9.9626 Tf
+(BZ_UNIX) 41.8429 Tj
+[1 0 0 1 296.808 276.779] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -296.808 -276.779] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+299.756 276.779 Td
+/F130_0 9.9626 Tf
+(to) 7.7509 Tj
+-296 TJm
+(0) 4.9813 Tj
+-296 TJm
+(and) 14.386 Tj
+[1 0 0 1 335.72 276.779] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -335.72 -276.779] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+335.72 276.779 Td
+/F134_0 9.9626 Tf
+(BZ_LCCWIN32) 65.7532 Tj
+[1 0 0 1 401.473 276.779] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -401.473 -276.779] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+404.422 276.779 Td
+/F130_0 9.9626 Tf
+(to) 7.7509 Tj
+-296 TJm
+(1,) 7.47195 Tj
+-307 TJm
+(in) 7.7509 Tj
+-296 TJm
+(the) 12.1743 Tj
+-296 TJm
+(\002le) 12.7322 Tj
+[1 0 0 1 467.159 276.779] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -467.159 -276.779] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+467.159 276.779 Td
+/F134_0 9.9626 Tf
+(bzip2.c) 41.8429 Tj
+[1 0 0 1 509.002 276.779] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -509.002 -276.779] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+509.002 276.779 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-307 TJm
+(before) 25.4445 Tj
+72 264.824 Td
+(compiling.) 42.899 Tj
+-310 TJm
+(Otherwise) 40.9463 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(resulting) 34.8691 Tj
+-250 TJm
+(binary) 25.4544 Tj
+-250 TJm
+(w) 7.193 Tj
+10 TJm
+(on') 13.2801 Tj
+18 TJm
+(t) 2.7696 Tj
+-250 TJm
+(w) 7.193 Tj
+10 TJm
+(ork) 13.2801 Tj
+-250 TJm
+(correctly) 35.4071 Tj
+65 TJm
+(.) 2.49065 Tj
+[1 0 0 1 72 262.667] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -252.704] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 230.071 Td
+/F122_0 20.6585 Tf
+(4.3.) 34.4584 Tj
+-278 TJm
+(Repor) 59.6824 Tj
+-20 TJm
+(ting) 37.867 Tj
+-278 TJm
+(b) 12.6223 Tj
+20 TJm
+(ugs) 36.7308 Tj
+[1 0 0 1 72 225.474] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -215.512] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 208.153 Td
+/F130_0 9.9626 Tf
+(I) 3.31755 Tj
+-228 TJm
+(tried) 18.2614 Tj
+-228 TJm
+(pretty) 23.2427 Tj
+-228 TJm
+(hard) 17.7035 Tj
+-228 TJm
+(to) 7.7509 Tj
+-228 TJm
+(mak) 17.1556 Tj
+10 TJm
+(e) 4.42339 Tj
+-228 TJm
+(sure) 16.5977 Tj
+[1 0 0 1 196.25 208.153] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -196.25 -208.153] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+196.25 208.153 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 226.138 208.153] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -226.138 -208.153] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+228.409 208.153 Td
+/F130_0 9.9626 Tf
+(is) 6.64505 Tj
+-228 TJm
+(b) 4.9813 Tj
+20 TJm
+(ug) 9.9626 Tj
+-228 TJm
+(free,) 17.9725 Tj
+-232 TJm
+(both) 17.7135 Tj
+-228 TJm
+(by) 9.9626 Tj
+-228 TJm
+(design) 26.0123 Tj
+-228 TJm
+(and) 14.386 Tj
+-228 TJm
+(by) 9.9626 Tj
+-228 TJm
+(testing.) 29.0609 Tj
+-605 TJm
+(Hopefully) 40.3983 Tj
+-228 TJm
+(you') 18.2614 Tj
+10 TJm
+(ll) 5.53921 Tj
+-228 TJm
+(ne) 9.40469 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(er) 7.74094 Tj
+-228 TJm
+(need) 18.8094 Tj
+-228 TJm
+(to) 7.7509 Tj
+-228 TJm
+(read) 17.1456 Tj
+72 196.198 Td
+(this) 14.396 Tj
+-250 TJm
+(section) 28.224 Tj
+-250 TJm
+(for) 11.6164 Tj
+-250 TJm
+(real.) 17.4246 Tj
+[1 0 0 1 72 196.098] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -186.136] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 174.28 Td
+/F130_0 9.9626 Tf
+(Ne) 11.6164 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(ertheless,) 37.3498 Tj
+-313 TJm
+(if) 6.08715 Tj
+[1 0 0 1 137.751 174.28] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -137.751 -174.28] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+137.751 174.28 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 167.639 174.28] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -167.639 -174.28] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+170.634 174.28 Td
+/F130_0 9.9626 Tf
+(dies) 16.0497 Tj
+-301 TJm
+(with) 17.7135 Tj
+-300 TJm
+(a) 4.42339 Tj
+-301 TJm
+(se) 8.29885 Tj
+15 TJm
+(gmentation) 44.8317 Tj
+-300 TJm
+(f) 3.31755 Tj
+10 TJm
+(ault,) 17.4346 Tj
+-314 TJm
+(a) 4.42339 Tj
+-300 TJm
+(b) 4.9813 Tj
+20 TJm
+(us) 8.85675 Tj
+-301 TJm
+(error) 19.3573 Tj
+-300 TJm
+(or) 8.29885 Tj
+-301 TJm
+(an) 9.40469 Tj
+-301 TJm
+(internal) 30.4357 Tj
+-300 TJm
+(assertion) 35.417 Tj
+-301 TJm
+(f) 3.31755 Tj
+10 TJm
+(ailure,) 25.1755 Tj
+-313 TJm
+(it) 5.53921 Tj
+-301 TJm
+(wil) 12.7322 Tj
+1 TJm
+(l) 2.7696 Tj
+-301 TJm
+(ask) 13.2801 Tj
+-301 TJm
+(you) 14.9439 Tj
+-300 TJm
+(to) 7.7509 Tj
+72 162.325 Td
+(email) 22.1369 Tj
+-242 TJm
+(me) 12.1743 Tj
+-243 TJm
+(a) 4.42339 Tj
+-242 TJm
+(b) 4.9813 Tj
+20 TJm
+(ug) 9.9626 Tj
+-243 TJm
+(report.) 26.2813 Tj
+-615 TJm
+(Experience) 44.8118 Tj
+-242 TJm
+(from) 19.3673 Tj
+-243 TJm
+(years) 21.0211 Tj
+-242 TJm
+(of) 8.29885 Tj
+-242 TJm
+(feedback) 35.955 Tj
+-243 TJm
+(of) 8.29885 Tj
+-242 TJm
+(bzip2) 22.1369 Tj
+-243 TJm
+(users) 20.4731 Tj
+-242 TJm
+(indicates) 35.417 Tj
+-243 TJm
+(that) 14.9439 Tj
+-242 TJm
+(almost) 26.5703 Tj
+-242 TJm
+(all) 9.9626 Tj
+-243 TJm
+(these) 20.4731 Tj
+-242 TJm
+(problems) 37.0808 Tj
+-243 TJm
+(can) 13.8281 Tj
+72 150.37 Td
+(be) 9.40469 Tj
+-250 TJm
+(traced) 24.3386 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(either) 22.6848 Tj
+-250 TJm
+(compiler) 35.417 Tj
+-250 TJm
+(b) 4.9813 Tj
+20 TJm
+(ugs) 13.8381 Tj
+-250 TJm
+(or) 8.29885 Tj
+-250 TJm
+(hardw) 24.8965 Tj
+10 TJm
+(are) 12.1643 Tj
+-250 TJm
+(problems.) 39.5714 Tj
+[1 0 0 1 72 148.213] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -97.3611] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 374.394 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 6.8541] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 40.5726 -6.7545] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -493.841 -50.9514] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+534.414 50.9514 Td
+/F130_0 9.9626 Tf
+(32) 9.9626 Tj
+[1 0 0 1 453.269 50.8518] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 93.5985 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.2765 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+Q
+showpage
+%%PageTrailer
+pdfEndPage
+%%Page: 36 36
+%%BeginPageSetup
+%%PageOrientation: Portrait
+pdfStartPage
+0 0 612 792 re W
+%%EndPageSetup
+[] 0 d
+1 i
+0 j
+0 J
+10 M
+1 w
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+false op
+false OP
+0 0 612 792 re
+W
+q
+[1 0 0 1 72 741.554] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 14.4459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 187.197 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 -6.8541] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 6.8541] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 116.328 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -382.4 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+498.728 749.245 Td
+/F130_0 9.9626 Tf
+(Miscellanea) 48.1393 Tj
+[1 0 0 1 266.071 749.146] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 280.796 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -472.974 -7.0936] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -0.4981] cm
+q
+[] 0 d
+0 J
+0.4981 w
+0 0.2491 m
+475.465 0.2491 l
+S
+Q
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 479.251 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -31.5168] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.9739 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -78.9739 -710.037] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+78.9739 710.037 Td
+/F130_0 9.9626 Tf
+(\225) 3.48691 Tj
+[1 0 0 1 82.4608 710.037] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 1.9925 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -86.944 -710.037] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 710.037 Td
+/F130_0 9.9626 Tf
+(Recompile) 43.1679 Tj
+-306 TJm
+(the) 12.1743 Tj
+-306 TJm
+(program) 33.7533 Tj
+-306 TJm
+(with) 17.7135 Tj
+-306 TJm
+(no) 9.9626 Tj
+-306 TJm
+(optimisation,) 52.3136 Tj
+-320 TJm
+(and) 14.386 Tj
+-306 TJm
+(see) 12.7222 Tj
+-306 TJm
+(if) 6.08715 Tj
+-306 TJm
+(it) 5.53921 Tj
+-306 TJm
+(w) 7.193 Tj
+10 TJm
+(orks.) 19.6462 Tj
+-956 TJm
+(And/or) 28.224 Tj
+-306 TJm
+(try) 11.0684 Tj
+-306 TJm
+(a) 4.42339 Tj
+-306 TJm
+(dif) 11.0684 Tj
+25 TJm
+(ferent) 23.2328 Tj
+-306 TJm
+(compiler) 35.417 Tj
+55 TJm
+(.) 2.49065 Tj
+-956 TJm
+(I) 3.31755 Tj
+-306 TJm
+(heard) 22.1269 Tj
+-306 TJm
+(all) 9.9626 Tj
+86.944 698.082 Td
+(sorts) 18.8194 Tj
+-282 TJm
+(of) 8.29885 Tj
+-282 TJm
+(stories) 26.0123 Tj
+-282 TJm
+(about) 22.1369 Tj
+-283 TJm
+(v) 4.9813 Tj
+25 TJm
+(arious) 24.3486 Tj
+-282 TJm
+(\003a) 9.9626 Tj
+20 TJm
+(v) 4.9813 Tj
+20 TJm
+(ours) 17.1556 Tj
+-282 TJm
+(of) 8.29885 Tj
+-282 TJm
+(GNU) 21.579 Tj
+-282 TJm
+(C) 6.64505 Tj
+-282 TJm
+(\(and) 17.7035 Tj
+-282 TJm
+(other) 20.4731 Tj
+-283 TJm
+(compilers\)) 42.61 Tj
+-282 TJm
+(generating) 42.0521 Tj
+-282 TJm
+(bad) 14.386 Tj
+-282 TJm
+(code) 18.8094 Tj
+-282 TJm
+(for) 11.6164 Tj
+[1 0 0 1 472.141 698.082] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -472.141 -698.082] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+472.141 698.082 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 502.029 698.082] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -502.029 -698.082] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+502.029 698.082 Td
+/F130_0 9.9626 Tf
+(,) 2.49065 Tj
+-290 TJm
+(and) 14.386 Tj
+-282 TJm
+(I') 6.63509 Tj
+50 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+86.944 686.127 Td
+(run) 13.2801 Tj
+-250 TJm
+(across) 24.8965 Tj
+-250 TJm
+(tw) 9.9626 Tj
+10 TJm
+(o) 4.9813 Tj
+-250 TJm
+(such) 18.2614 Tj
+-250 TJm
+(e) 4.42339 Tj
+15 TJm
+(xamples) 33.2053 Tj
+-250 TJm
+(myself.) 29.6088 Tj
+[1 0 0 1 237.767 686.127] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -165.767 -12.1195] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -674.007] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 664.209 Td
+/F130_0 9.9626 Tf
+(2.7.X) 22.1369 Tj
+-280 TJm
+(v) 4.9813 Tj
+15 TJm
+(ersions) 28.224 Tj
+-279 TJm
+(of) 8.29885 Tj
+-280 TJm
+(GNU) 21.579 Tj
+-279 TJm
+(C) 6.64505 Tj
+-280 TJm
+(are) 12.1643 Tj
+-279 TJm
+(kno) 14.9439 Tj
+25 TJm
+(wn) 12.1743 Tj
+-280 TJm
+(to) 7.7509 Tj
+-280 TJm
+(generate) 33.7433 Tj
+-279 TJm
+(bad) 14.386 Tj
+-280 TJm
+(code) 18.8094 Tj
+-279 TJm
+(from) 19.3673 Tj
+-280 TJm
+(time) 17.7135 Tj
+-279 TJm
+(to) 7.7509 Tj
+-280 TJm
+(time,) 20.2042 Tj
+-287 TJm
+(at) 7.193 Tj
+-280 TJm
+(high) 17.7135 Tj
+-279 TJm
+(optimisation) 49.823 Tj
+-280 TJm
+(le) 7.193 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(els.) 13.5591 Tj
+-797 TJm
+(If) 6.63509 Tj
+-280 TJm
+(you) 14.9439 Tj
+86.944 652.254 Td
+(get) 12.1743 Tj
+-295 TJm
+(problems,) 39.5714 Tj
+-307 TJm
+(try) 11.0684 Tj
+-296 TJm
+(using) 21.589 Tj
+-295 TJm
+(the) 12.1743 Tj
+-296 TJm
+(\003ags) 18.8194 Tj
+[1 0 0 1 220.116 652.254] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -220.116 -652.254] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+220.116 652.254 Td
+/F134_0 9.9626 Tf
+(-O2) 17.9327 Tj
+[1 0 0 1 238.049 652.254] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.9438 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -240.993 -652.254] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+240.993 652.254 Td
+/F134_0 9.9626 Tf
+(-fomit-frame-pointer) 119.551 Tj
+[1 0 0 1 360.544 652.254] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.9438 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -363.488 -652.254] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+363.488 652.254 Td
+/F134_0 9.9626 Tf
+(-fno-strength-reduce) 119.551 Tj
+[1 0 0 1 483.04 652.254] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -483.04 -652.254] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+483.04 652.254 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+-893 TJm
+(Y) 7.193 Tj
+110 TJm
+(ou) 9.9626 Tj
+-295 TJm
+(should) 26.5703 Tj
+86.944 640.299 Td
+(speci\002cally) 45.3796 Tj
+[1 0 0 1 134.814 640.299] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -134.814 -640.299] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+134.814 640.299 Td
+/F637_0 9.9626 Tf
+(not) 12.7322 Tj
+[1 0 0 1 147.546 640.299] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -147.546 -640.299] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+150.036 640.299 Td
+/F130_0 9.9626 Tf
+(use) 13.2801 Tj
+[1 0 0 1 165.807 640.299] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -165.807 -640.299] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+165.807 640.299 Td
+/F134_0 9.9626 Tf
+(-funroll-loops) 83.6858 Tj
+[1 0 0 1 249.493 640.299] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -249.493 -640.299] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+249.493 640.299 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+[1 0 0 1 72 638.142] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -628.179] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 618.381 Td
+/F130_0 9.9626 Tf
+(Y) 7.193 Tj
+110 TJm
+(ou) 9.9626 Tj
+-249 TJm
+(may) 17.1556 Tj
+-249 TJm
+(notice) 24.3486 Tj
+-248 TJm
+(that) 14.9439 Tj
+-249 TJm
+(the) 12.1743 Tj
+-249 TJm
+(Mak) 18.2614 Tj
+10 TJm
+(e\002le) 17.1556 Tj
+-249 TJm
+(runs) 17.1556 Tj
+-248 TJm
+(six) 11.6264 Tj
+-249 TJm
+(tests) 17.7135 Tj
+-249 TJm
+(as) 8.29885 Tj
+-249 TJm
+(part) 15.4918 Tj
+-249 TJm
+(of) 8.29885 Tj
+-248 TJm
+(the) 12.1743 Tj
+-249 TJm
+(b) 4.9813 Tj
+20 TJm
+(uild) 15.5018 Tj
+-249 TJm
+(process.) 32.3685 Tj
+-619 TJm
+(If) 6.63509 Tj
+-249 TJm
+(the) 12.1743 Tj
+-249 TJm
+(program) 33.7533 Tj
+-248 TJm
+(passes) 25.4544 Tj
+-249 TJm
+(all) 9.9626 Tj
+-249 TJm
+(of) 8.29885 Tj
+-249 TJm
+(these,) 22.9638 Tj
+-249 TJm
+(it') 8.85675 Tj
+55 TJm
+(s) 3.87545 Tj
+86.944 606.426 Td
+(a) 4.42339 Tj
+-250 TJm
+(pretty) 23.2427 Tj
+-250 TJm
+(good) 19.9252 Tj
+-250 TJm
+(\(b) 8.29885 Tj
+20 TJm
+(ut) 7.7509 Tj
+-250 TJm
+(not) 12.7322 Tj
+-250 TJm
+(100%\)) 26.5603 Tj
+-250 TJm
+(indication) 39.8504 Tj
+-250 TJm
+(that) 14.9439 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(compiler) 35.417 Tj
+-250 TJm
+(has) 13.2801 Tj
+-250 TJm
+(done) 19.3673 Tj
+-250 TJm
+(its) 9.41466 Tj
+-250 TJm
+(job) 12.7322 Tj
+-250 TJm
+(correctly) 35.4071 Tj
+65 TJm
+(.) 2.49065 Tj
+[1 0 0 1 72 604.269] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -19.761] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.9739 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -78.9739 -584.508] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+78.9739 584.508 Td
+/F130_0 9.9626 Tf
+(\225) 3.48691 Tj
+[1 0 0 1 82.4608 584.508] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 1.9925 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -86.944 -584.508] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 584.508 Td
+/F130_0 9.9626 Tf
+(If) 6.63509 Tj
+[1 0 0 1 95.9558 584.508] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -95.9558 -584.508] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+95.9558 584.508 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 125.844 584.508] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -125.844 -584.508] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+128.22 584.508 Td
+/F130_0 9.9626 Tf
+(crashes) 29.3199 Tj
+-239 TJm
+(randomly) 38.1866 Tj
+65 TJm
+(,) 2.49065 Tj
+-240 TJm
+(and) 14.386 Tj
+-239 TJm
+(the) 12.1743 Tj
+-239 TJm
+(crashe) 25.4445 Tj
+1 TJm
+(s) 3.87545 Tj
+-239 TJm
+(are) 12.1643 Tj
+-239 TJm
+(not) 12.7322 Tj
+-238 TJm
+(repeatable,) 43.427 Tj
+-241 TJm
+(you) 14.9439 Tj
+-239 TJm
+(may) 17.1556 Tj
+-238 TJm
+(ha) 9.40469 Tj
+20 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-239 TJm
+(a) 4.42339 Tj
+-238 TJm
+(\003ak) 14.9439 Tj
+15 TJm
+(y) 4.9813 Tj
+-239 TJm
+(memory) 33.2053 Tj
+-238 TJm
+(subsystem.) 44.0048 Tj
+[1 0 0 1 510.112 584.508] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -510.112 -584.508] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+510.112 584.508 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 540 584.508] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -540 -584.508] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 572.553 Td
+/F130_0 9.9626 Tf
+(really) 22.6848 Tj
+-254 TJm
+(hammers) 36.5229 Tj
+-253 TJm
+(your) 18.2614 Tj
+-254 TJm
+(memory) 33.2053 Tj
+-253 TJm
+(hierarch) 32.6375 Tj
+5 TJm
+(y) 4.9813 Tj
+65 TJm
+(,) 2.49065 Tj
+-255 TJm
+(and) 14.386 Tj
+-253 TJm
+(if) 6.08715 Tj
+-254 TJm
+(it') 8.85675 Tj
+55 TJm
+(s) 3.87545 Tj
+-254 TJm
+(a) 4.42339 Tj
+-253 TJm
+(bit) 10.5205 Tj
+-254 TJm
+(mar) 15.4918 Tj
+18 TJm
+(ginal,) 22.4159 Tj
+-254 TJm
+(you) 14.9439 Tj
+-254 TJm
+(may) 17.1556 Tj
+-253 TJm
+(get) 12.1743 Tj
+-254 TJm
+(these) 20.4731 Tj
+-253 TJm
+(problems.) 39.5714 Tj
+-642 TJm
+(Ditto) 20.4831 Tj
+-254 TJm
+(if) 6.08715 Tj
+-253 TJm
+(your) 18.2614 Tj
+-254 TJm
+(disk) 16.6077 Tj
+86.944 560.598 Td
+(or) 8.29885 Tj
+-250 TJm
+(I/O) 13.2801 Tj
+-250 TJm
+(subsystem) 41.5142 Tj
+-250 TJm
+(is) 6.64505 Tj
+-250 TJm
+(slo) 11.6264 Tj
+25 TJm
+(wly) 14.9439 Tj
+-250 TJm
+(f) 3.31755 Tj
+10 TJm
+(ailing.) 25.1855 Tj
+-620 TJm
+(Y) 7.193 Tj
+111 TJm
+(up,) 12.4533 Tj
+-250 TJm
+(this) 14.396 Tj
+-250 TJm
+(really) 22.6848 Tj
+-250 TJm
+(does) 18.2614 Tj
+-250 TJm
+(happen.) 31.2626 Tj
+[1 0 0 1 345.143 560.598] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -273.143 -12.1195] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -548.478] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 538.68 Td
+/F130_0 9.9626 Tf
+(T) 6.08715 Tj
+35 TJm
+(ry) 8.29885 Tj
+-250 TJm
+(using) 21.589 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(dif) 11.0684 Tj
+25 TJm
+(ferent) 23.2328 Tj
+-250 TJm
+(machine) 33.7533 Tj
+-250 TJm
+(of) 8.29885 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(same) 20.4731 Tj
+-250 TJm
+(type,) 19.6462 Tj
+-250 TJm
+(and) 14.386 Tj
+-250 TJm
+(see) 12.7222 Tj
+-250 TJm
+(if) 6.08715 Tj
+-250 TJm
+(you) 14.9439 Tj
+-250 TJm
+(can) 13.8281 Tj
+-250 TJm
+(repeat) 24.3386 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(problem.) 35.696 Tj
+[1 0 0 1 72 536.523] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -19.761] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.9739 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -78.9739 -516.762] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+78.9739 516.762 Td
+/F130_0 9.9626 Tf
+(\225) 3.48691 Tj
+[1 0 0 1 82.4608 516.762] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 1.9925 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -86.944 -516.762] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+86.944 516.762 Td
+/F130_0 9.9626 Tf
+(This) 17.7135 Tj
+-229 TJm
+(isn') 14.9439 Tj
+18 TJm
+(t) 2.7696 Tj
+-230 TJm
+(really) 22.6848 Tj
+-229 TJm
+(a) 4.42339 Tj
+-229 TJm
+(b) 4.9813 Tj
+20 TJm
+(ug,) 12.4533 Tj
+-234 TJm
+(b) 4.9813 Tj
+20 TJm
+(ut) 7.7509 Tj
+-229 TJm
+(...) 7.47195 Tj
+-303 TJm
+(If) 6.63509 Tj
+[1 0 0 1 212.232 516.762] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -212.232 -516.762] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+212.232 516.762 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 242.12 516.762] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -242.12 -516.762] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+244.405 516.762 Td
+/F130_0 9.9626 Tf
+(tells) 16.6077 Tj
+-229 TJm
+(you) 14.9439 Tj
+-230 TJm
+(your) 18.2614 Tj
+-229 TJm
+(\002le) 12.7322 Tj
+-229 TJm
+(is) 6.64505 Tj
+-230 TJm
+(corrupted) 38.1767 Tj
+-229 TJm
+(on) 9.9626 Tj
+-230 TJm
+(decompression,) 62.2563 Tj
+-233 TJm
+(and) 14.386 Tj
+-229 TJm
+(you) 14.9439 Tj
+-230 TJm
+(obtained) 34.3112 Tj
+-229 TJm
+(the) 12.1743 Tj
+-229 TJm
+(\002le) 12.7322 Tj
+86.944 504.807 Td
+(via) 12.1743 Tj
+-262 TJm
+(FTP) 17.1656 Tj
+111 TJm
+(,) 2.49065 Tj
+-263 TJm
+(there) 19.9152 Tj
+-262 TJm
+(is) 6.64505 Tj
+-262 TJm
+(a) 4.42339 Tj
+-262 TJm
+(possibility) 41.5241 Tj
+-263 TJm
+(that) 14.9439 Tj
+-262 TJm
+(you) 14.9439 Tj
+-262 TJm
+(for) 11.6164 Tj
+18 TJm
+(got) 12.7322 Tj
+-263 TJm
+(to) 7.7509 Tj
+-262 TJm
+(tell) 12.7322 Tj
+-262 TJm
+(FTP) 17.1656 Tj
+-263 TJm
+(to) 7.7509 Tj
+-262 TJm
+(do) 9.9626 Tj
+-262 TJm
+(a) 4.42339 Tj
+-262 TJm
+(binary) 25.4544 Tj
+-263 TJm
+(mode) 22.1369 Tj
+-262 TJm
+(transfer) 30.4258 Tj
+55 TJm
+(.) 2.49065 Tj
+-694 TJm
+(That) 18.2614 Tj
+-262 TJm
+(absolutely) 40.9562 Tj
+-262 TJm
+(will) 15.5018 Tj
+-263 TJm
+(cause) 22.1269 Tj
+86.944 492.852 Td
+(the) 12.1743 Tj
+-250 TJm
+(\002le) 12.7322 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(be) 9.40469 Tj
+-250 TJm
+(non-decompressible.) 82.7294 Tj
+-620 TJm
+(Y) 7.193 Tj
+110 TJm
+(ou') 13.2801 Tj
+10 TJm
+(ll) 5.53921 Tj
+-250 TJm
+(ha) 9.40469 Tj
+20 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(transfer) 30.4258 Tj
+-250 TJm
+(it) 5.53921 Tj
+-250 TJm
+(ag) 9.40469 Tj
+5 TJm
+(ain.) 14.6649 Tj
+[1 0 0 1 351.34 492.852] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -279.34 -12.1195] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -480.732] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 470.934 Td
+/F130_0 9.9626 Tf
+(If) 6.63509 Tj
+-235 TJm
+(you') 18.2614 Tj
+50 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-236 TJm
+(incor) 20.4731 Tj
+1 TJm
+(p) 4.9813 Tj
+-1 TJm
+(or) 8.29885 Tj
+1 TJm
+(ated) 16.5977 Tj
+[1 0 0 1 163.036 470.934] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -163.036 -470.934] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+163.036 470.934 Td
+/F134_0 9.9626 Tf
+(libbzip2) 47.8205 Tj
+[1 0 0 1 210.856 470.934] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -210.856 -470.934] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+213.2 470.934 Td
+/F130_0 9.9626 Tf
+(into) 15.5018 Tj
+-235 TJm
+(your) 18.2614 Tj
+-235 TJm
+(o) 4.9813 Tj
+25 TJm
+(wn) 12.1743 Tj
+-236 TJm
+(program) 33.7533 Tj
+-235 TJm
+(and) 14.386 Tj
+-235 TJm
+(are) 12.1643 Tj
+-236 TJm
+(get) 12.1743 Tj
+1 TJm
+(ting) 15.5018 Tj
+-236 TJm
+(problems,) 39.5714 Tj
+-238 TJm
+(please,) 27.3872 Tj
+-238 TJm
+(please,) 27.3872 Tj
+-238 TJm
+(please,) 27.3872 Tj
+-238 TJm
+(check) 23.2328 Tj
+-236 TJm
+(that) 14.9439 Tj
+72 458.979 Td
+(the) 12.1743 Tj
+-242 TJm
+(parameters) 43.7059 Tj
+-243 TJm
+(you) 14.9439 Tj
+-242 TJm
+(are) 12.1643 Tj
+-242 TJm
+(passing) 29.8878 Tj
+-243 TJm
+(in) 7.7509 Tj
+-242 TJm
+(calls) 18.2614 Tj
+-242 TJm
+(to) 7.7509 Tj
+-243 TJm
+(the) 12.1743 Tj
+-242 TJm
+(library) 26.5603 Tj
+65 TJm
+(,) 2.49065 Tj
+-244 TJm
+(are) 12.1643 Tj
+-242 TJm
+(correct,) 30.1468 Tj
+-244 TJm
+(and) 14.386 Tj
+-243 TJm
+(in) 7.7509 Tj
+-242 TJm
+(accordance) 44.8018 Tj
+-242 TJm
+(with) 17.7135 Tj
+-243 TJm
+(what) 19.3673 Tj
+-242 TJm
+(the) 12.1743 Tj
+-242 TJm
+(documentation) 59.2177 Tj
+-243 TJm
+(says) 17.1556 Tj
+72 447.024 Td
+(is) 6.64505 Tj
+-250 TJm
+(allo) 14.9439 Tj
+25 TJm
+(w) 7.193 Tj
+10 TJm
+(able.) 19.0883 Tj
+-310 TJm
+(I) 3.31755 Tj
+-250 TJm
+(ha) 9.40469 Tj
+20 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-250 TJm
+(tried) 18.2614 Tj
+-250 TJm
+(to) 7.7509 Tj
+-250 TJm
+(mak) 17.1556 Tj
+10 TJm
+(e) 4.42339 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(library) 26.5603 Tj
+-250 TJm
+(rob) 13.2801 Tj
+20 TJm
+(ust) 11.6264 Tj
+-250 TJm
+(ag) 9.40469 Tj
+5 TJm
+(ainst) 18.8194 Tj
+-250 TJm
+(such) 18.2614 Tj
+-250 TJm
+(problems,) 39.5714 Tj
+-250 TJm
+(b) 4.9813 Tj
+20 TJm
+(ut) 7.7509 Tj
+-250 TJm
+(I'm) 14.386 Tj
+-250 TJm
+(sure) 16.5977 Tj
+-250 TJm
+(I) 3.31755 Tj
+-250 TJm
+(ha) 9.40469 Tj
+20 TJm
+(v) 4.9813 Tj
+15 TJm
+(en') 12.7222 Tj
+18 TJm
+(t) 2.7696 Tj
+-250 TJm
+(succeeded.) 43.427 Tj
+[1 0 0 1 72 444.867] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -434.904] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 425.106 Td
+/F130_0 9.9626 Tf
+(Finally) 28.234 Tj
+65 TJm
+(,) 2.49065 Tj
+-324 TJm
+(if) 6.08715 Tj
+-310 TJm
+(the) 12.1743 Tj
+-309 TJm
+(abo) 14.386 Tj
+15 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-309 TJm
+(comments) 40.9562 Tj
+-310 TJm
+(don') 18.2614 Tj
+18 TJm
+(t) 2.7696 Tj
+-309 TJm
+(help,) 19.6462 Tj
+-324 TJm
+(you') 18.2614 Tj
+10 TJm
+(ll) 5.53921 Tj
+-310 TJm
+(ha) 9.40469 Tj
+20 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-309 TJm
+(to) 7.7509 Tj
+-309 TJm
+(send) 18.2614 Tj
+-310 TJm
+(me) 12.1743 Tj
+-309 TJm
+(a) 4.42339 Tj
+-309 TJm
+(b) 4.9813 Tj
+20 TJm
+(ug) 9.9626 Tj
+-310 TJm
+(report.) 26.2813 Tj
+-976 TJm
+(No) 12.1743 Tj
+25 TJm
+(w) 7.193 Tj
+65 TJm
+(,) 2.49065 Tj
+-324 TJm
+(it') 8.85675 Tj
+55 TJm
+(s) 3.87545 Tj
+-310 TJm
+(just) 14.396 Tj
+-309 TJm
+(amazing) 33.7533 Tj
+-309 TJm
+(ho) 9.9626 Tj
+25 TJm
+(w) 7.193 Tj
+-310 TJm
+(man) 17.1556 Tj
+15 TJm
+(y) 4.9813 Tj
+72 413.151 Td
+(people) 26.5603 Tj
+-250 TJm
+(will) 15.5018 Tj
+-250 TJm
+(send) 18.2614 Tj
+-250 TJm
+(me) 12.1743 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(b) 4.9813 Tj
+20 TJm
+(ug) 9.9626 Tj
+-250 TJm
+(report) 23.7907 Tj
+-250 TJm
+(saying) 26.0123 Tj
+-250 TJm
+(something) 41.5142 Tj
+-250 TJm
+(lik) 10.5205 Tj
+10 TJm
+(e:) 7.193 Tj
+[1 0 0 1 72 410.994] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -24.9066] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 23.9103 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 20.3237] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3685] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -401.629] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 401.629 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+-426 TJm
+(crashed) 41.8429 Tj
+-426 TJm
+(with) 23.9102 Tj
+-426 TJm
+(segmentation) 71.7307 Tj
+-426 TJm
+(fault) 29.8878 Tj
+-426 TJm
+(on) 11.9551 Tj
+-426 TJm
+(my) 11.9551 Tj
+-426 TJm
+(machine) 41.8429 Tj
+[1 0 0 1 72 386.087] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.5492] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -376.125] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 364.169 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+-241 TJm
+(absolutely) 40.9562 Tj
+-241 TJm
+(nothing) 30.4457 Tj
+-241 TJm
+(el) 7.193 Tj
+1 TJm
+(se.) 10.7895 Tj
+-614 TJm
+(Needless) 35.965 Tj
+-241 TJm
+(to) 7.7509 Tj
+-241 TJm
+(say) 13.2801 Tj
+65 TJm
+(,) 2.49065 Tj
+-243 TJm
+(a) 4.42339 Tj
+-241 TJm
+(such) 18.2614 Tj
+-240 TJm
+(a) 4.42339 Tj
+-241 TJm
+(report) 23.7907 Tj
+-241 TJm
+(is) 6.64505 Tj
+[1 0 0 1 324.681 364.169] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -324.681 -364.169] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+324.681 364.169 Td
+/F637_0 9.9626 Tf
+(totally) 25.4644 Tj
+55 TJm
+(,) 2.49065 Tj
+-243 TJm
+(utterly) 26.0123 Tj
+55 TJm
+(,) 2.49065 Tj
+-242 TJm
+(completely) 43.158 Tj
+-241 TJm
+(and) 14.9439 Tj
+-241 TJm
+(compr) 25.4544 Tj
+37 TJm
+(ehensively) 41.4942 Tj
+-241 TJm
+(100%) 23.2427 Tj
+72 352.214 Td
+(useless;) 31.5416 Tj
+-257 TJm
+(a) 4.9813 Tj
+-255 TJm
+(waste) 22.6948 Tj
+-255 TJm
+(of) 7.7509 Tj
+-255 TJm
+(your) 18.2614 Tj
+-255 TJm
+(time) 17.1556 Tj
+10 TJm
+(,) 2.49065 Tj
+-256 TJm
+(my) 11.6164 Tj
+-255 TJm
+(time) 17.1556 Tj
+10 TJm
+(,) 2.49065 Tj
+-256 TJm
+(and) 14.9439 Tj
+-255 TJm
+(net) 12.1743 Tj
+-255 TJm
+(bandwidth) 42.0721 Tj
+[1 0 0 1 302.574 352.214] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -302.574 -352.214] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+302.574 352.214 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+-650 TJm
+(W) 9.40469 Tj
+40 TJm
+(ith) 10.5205 Tj
+-254 TJm
+(no) 9.9626 Tj
+-255 TJm
+(details) 26.0123 Tj
+-255 TJm
+(at) 7.193 Tj
+-255 TJm
+(all,) 12.4533 Tj
+-256 TJm
+(there') 23.2328 Tj
+55 TJm
+(s) 3.87545 Tj
+-255 TJm
+(no) 9.9626 Tj
+-255 TJm
+(w) 7.193 Tj
+10 TJm
+(ay) 9.40469 Tj
+-255 TJm
+(I) 3.31755 Tj
+-255 TJm
+(can) 13.8281 Tj
+-255 TJm
+(possibly) 33.2153 Tj
+-255 TJm
+(be) 9.40469 Tj
+15 TJm
+(gin) 12.7322 Tj
+72 340.259 Td
+(to) 7.7509 Tj
+-250 TJm
+(\002gure) 23.2427 Tj
+-250 TJm
+(out) 12.7322 Tj
+-250 TJm
+(what) 19.3673 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(problem) 33.2053 Tj
+-250 TJm
+(is.) 9.1357 Tj
+[1 0 0 1 72 338.102] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -328.14] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 318.341 Td
+/F130_0 9.9626 Tf
+(The) 15.4918 Tj
+-309 TJm
+(rules) 19.3673 Tj
+-309 TJm
+(of) 8.29885 Tj
+-309 TJm
+(the) 12.1743 Tj
+-310 TJm
+(g) 4.9813 Tj
+5 TJm
+(ame) 16.5977 Tj
+-309 TJm
+(are:) 14.9339 Tj
+-428 TJm
+(f) 3.31755 Tj
+10 TJm
+(acts,) 17.9825 Tj
+-324 TJm
+(f) 3.31755 Tj
+10 TJm
+(acts,) 17.9825 Tj
+-324 TJm
+(f) 3.31755 Tj
+10 TJm
+(acts.) 17.9825 Tj
+-975 TJm
+(Don') 20.4731 Tj
+18 TJm
+(t) 2.7696 Tj
+-309 TJm
+(omit) 18.2714 Tj
+-309 TJm
+(them) 19.9252 Tj
+-309 TJm
+(because) 31.5316 Tj
+-309 TJm
+("oh,) 16.518 Tj
+-324 TJm
+(the) 12.1743 Tj
+15 TJm
+(y) 4.9813 Tj
+-309 TJm
+(w) 7.193 Tj
+10 TJm
+(on') 13.2801 Tj
+18 TJm
+(t) 2.7696 Tj
+-309 TJm
+(be) 9.40469 Tj
+-310 TJm
+(rele) 14.9339 Tj
+25 TJm
+(v) 4.9813 Tj
+25 TJm
+(ant".) 18.7297 Tj
+-974 TJm
+(At) 9.9626 Tj
+-310 TJm
+(the) 12.1743 Tj
+-309 TJm
+(bare) 17.1456 Tj
+72 306.386 Td
+(minimum:) 41.5241 Tj
+[1 0 0 1 72 306.287] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -60.7721] cm
+/DeviceRGB {} cs
+[0.94899 0.94899 0.976456] sc
+/DeviceRGB {} CS
+[0.94899 0.94899 0.976456] SC
+0 0 468 59.7758 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 56.1892] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -296.922] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 296.922 Td
+/F134_0 9.9626 Tf
+(Machine) 41.8429 Tj
+-426 TJm
+(type.) 29.8878 Tj
+-852 TJm
+(Operating) 53.798 Tj
+-426 TJm
+(system) 35.8654 Tj
+-426 TJm
+(version.) 47.8205 Tj
+90 284.967 Td
+(Exact) 29.8878 Tj
+-426 TJm
+(version) 41.8429 Tj
+-426 TJm
+(of) 11.9551 Tj
+-426 TJm
+(bzip2) 29.8878 Tj
+-426 TJm
+(\(do) 17.9327 Tj
+-426 TJm
+(bzip2) 29.8878 Tj
+-426 TJm
+(-V\).) 23.9102 Tj
+90 273.011 Td
+(Exact) 29.8878 Tj
+-426 TJm
+(version) 41.8429 Tj
+-426 TJm
+(of) 11.9551 Tj
+-426 TJm
+(the) 17.9327 Tj
+-426 TJm
+(compiler) 47.8205 Tj
+-426 TJm
+(used.) 29.8878 Tj
+90 261.056 Td
+(Flags) 29.8878 Tj
+-426 TJm
+(passed) 35.8654 Tj
+-426 TJm
+(to) 11.9551 Tj
+-426 TJm
+(the) 17.9327 Tj
+-426 TJm
+(compiler.) 53.798 Tj
+[1 0 0 1 72 245.514] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.5492] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -235.552] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 223.597 Td
+/F130_0 9.9626 Tf
+(Ho) 12.1743 Tj
+25 TJm
+(we) 11.6164 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(er) 7.74094 Tj
+40 TJm
+(,) 2.49065 Tj
+-254 TJm
+(the) 12.1743 Tj
+-252 TJm
+(most) 19.3773 Tj
+-253 TJm
+(important) 38.7446 Tj
+-253 TJm
+(single) 23.8007 Tj
+-253 TJm
+(thing) 20.4831 Tj
+-253 TJm
+(t) 2.7696 Tj
+1 TJm
+(hat) 12.1743 Tj
+-253 TJm
+(will) 15.5018 Tj
+-253 TJm
+(help) 17.1556 Tj
+-253 TJm
+(me) 12.1743 Tj
+-253 TJm
+(is) 6.64505 Tj
+-252 TJm
+(the) 12.1743 Tj
+-253 TJm
+(\002le) 12.7322 Tj
+-253 TJm
+(that) 14.9439 Tj
+-253 TJm
+(you) 14.9439 Tj
+-253 TJm
+(were) 19.3573 Tj
+-253 TJm
+(trying) 23.8007 Tj
+-252 TJm
+(to) 7.7509 Tj
+-253 TJm
+(compress) 37.6287 Tj
+-253 TJm
+(or) 8.29885 Tj
+-253 TJm
+(decompress) 47.0334 Tj
+72 211.641 Td
+(at) 7.193 Tj
+-304 TJm
+(the) 12.1743 Tj
+-305 TJm
+(time) 17.7135 Tj
+-304 TJm
+(the) 12.1743 Tj
+-304 TJm
+(problem) 33.2053 Tj
+-305 TJm
+(happened.) 40.6673 Tj
+-946 TJm
+(W) 9.40469 Tj
+40 TJm
+(ithout) 23.2527 Tj
+-304 TJm
+(that,) 17.4346 Tj
+-318 TJm
+(my) 12.7322 Tj
+-305 TJm
+(ability) 25.4644 Tj
+-304 TJm
+(to) 7.7509 Tj
+-304 TJm
+(do) 9.9626 Tj
+-305 TJm
+(an) 9.40469 Tj
+15 TJm
+(ything) 25.4644 Tj
+-304 TJm
+(more) 20.4731 Tj
+-304 TJm
+(than) 17.1556 Tj
+-305 TJm
+(speculate) 37.0708 Tj
+-304 TJm
+(about) 22.1369 Tj
+-304 TJm
+(the) 12.1743 Tj
+-305 TJm
+(cause,) 24.6176 Tj
+-318 TJm
+(is) 6.64505 Tj
+72 199.686 Td
+(limited.) 30.7247 Tj
+[1 0 0 1 72 199.587] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -189.624] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 164.933 Td
+/F122_0 20.6585 Tf
+(4.4.) 34.4584 Tj
+-278 TJm
+(Did) 33.2808 Tj
+-278 TJm
+(y) 11.4861 Tj
+25 TJm
+(ou) 25.2447 Tj
+-278 TJm
+(g) 12.6223 Tj
+-10 TJm
+(et) 18.3654 Tj
+-278 TJm
+(the) 30.9877 Tj
+-278 TJm
+(right) 45.9032 Tj
+-278 TJm
+(pac) 35.5946 Tj
+20 TJm
+(ka) 22.9723 Tj
+10 TJm
+(g) 12.6223 Tj
+-10 TJm
+(e?) 24.1085 Tj
+[1 0 0 1 72 160.337] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -150.374] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 143.016 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 101.888 143.016] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -101.888 -143.016] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+104.603 143.016 Td
+/F130_0 9.9626 Tf
+(is) 6.64505 Tj
+-272 TJm
+(a) 4.42339 Tj
+-273 TJm
+(resource) 33.7433 Tj
+-272 TJm
+(hog.) 17.4346 Tj
+-378 TJm
+(It) 6.08715 Tj
+-272 TJm
+(soaks) 22.1369 Tj
+-273 TJm
+(up) 9.9626 Tj
+-272 TJm
+(lar) 10.5105 Tj
+18 TJm
+(ge) 9.40469 Tj
+-273 TJm
+(amounts) 33.7633 Tj
+-272 TJm
+(of) 8.29885 Tj
+-273 TJm
+(CPU) 19.3773 Tj
+-272 TJm
+(c) 4.42339 Tj
+15 TJm
+(ycles) 20.4731 Tj
+-273 TJm
+(and) 14.386 Tj
+-272 TJm
+(memory) 33.2053 Tj
+65 TJm
+(.) 2.49065 Tj
+-755 TJm
+(Also,) 21.31 Tj
+-278 TJm
+(it) 5.53921 Tj
+-273 TJm
+(gi) 7.7509 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(es) 8.29885 Tj
+-272 TJm
+(v) 4.9813 Tj
+15 TJm
+(ery) 12.7222 Tj
+-273 TJm
+(lar) 10.5105 Tj
+18 TJm
+(ge) 9.40469 Tj
+-272 TJm
+(latencies.) 37.3498 Tj
+72 131.06 Td
+(In) 8.29885 Tj
+-251 TJm
+(the) 12.1743 Tj
+-251 TJm
+(w) 7.193 Tj
+10 TJm
+(orst) 14.9439 Tj
+-251 TJm
+(case,) 19.6363 Tj
+-251 TJm
+(you) 14.9439 Tj
+-251 TJm
+(can) 13.8281 Tj
+-251 TJm
+(feed) 17.1456 Tj
+-251 TJm
+(man) 17.1556 Tj
+15 TJm
+(y) 4.9813 Tj
+-251 TJm
+(me) 12.1743 Tj
+15 TJm
+(g) 4.9813 Tj
+4 TJm
+(abyt) 17.1556 Tj
+1 TJm
+(es) 8.29885 Tj
+-252 TJm
+(of) 8.29885 Tj
+-251 TJm
+(uncompressed) 56.996 Tj
+-251 TJm
+(data) 16.5977 Tj
+-251 TJm
+(into) 15.5018 Tj
+-251 TJm
+(the) 12.1743 Tj
+-251 TJm
+(library) 26.5603 Tj
+-251 TJm
+(before) 25.4445 Tj
+-251 TJm
+(getting) 27.6761 Tj
+-251 TJm
+(an) 9.40469 Tj
+15 TJm
+(y) 4.9813 Tj
+-251 TJm
+(compressed) 47.0334 Tj
+72 119.105 Td
+(output,) 27.9551 Tj
+-250 TJm
+(so) 8.85675 Tj
+-250 TJm
+(this) 14.396 Tj
+-250 TJm
+(probably) 35.417 Tj
+-250 TJm
+(rules) 19.3673 Tj
+-250 TJm
+(out) 12.7322 Tj
+-250 TJm
+(applications) 48.1492 Tj
+-250 TJm
+(requiring) 36.5229 Tj
+-250 TJm
+(interacti) 32.6474 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(e) 4.42339 Tj
+-250 TJm
+(beha) 18.8094 Tj
+20 TJm
+(viour) 21.031 Tj
+55 TJm
+(.) 2.49065 Tj
+[1 0 0 1 72 116.949] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -106.986] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 97.1875 Td
+/F130_0 9.9626 Tf
+(These) 23.7907 Tj
+-304 TJm
+(aren') 20.4632 Tj
+18 TJm
+(t) 2.7696 Tj
+-304 TJm
+(f) 3.31755 Tj
+10 TJm
+(aults) 18.8194 Tj
+-304 TJm
+(of) 8.29885 Tj
+-304 TJm
+(my) 12.7322 Tj
+-304 TJm
+(implementation,) 65.0359 Tj
+-317 TJm
+(I) 3.31755 Tj
+-304 TJm
+(hope,) 21.8579 Tj
+-318 TJm
+(b) 4.9813 Tj
+20 TJm
+(ut) 7.7509 Tj
+-304 TJm
+(more) 20.4731 Tj
+-304 TJm
+(an) 9.40469 Tj
+-304 TJm
+(intrinsic) 32.6574 Tj
+-304 TJm
+(property) 33.7533 Tj
+-304 TJm
+(of) 8.29885 Tj
+-304 TJm
+(the) 12.1743 Tj
+-304 TJm
+(Burro) 23.2427 Tj
+25 TJm
+(ws-Wheeler) 48.1293 Tj
+-304 TJm
+(transform) 38.7346 Tj
+72 85.2323 Td
+(\(unfortunately\).) 62.8042 Tj
+-620 TJm
+(Maybe) 27.6661 Tj
+-250 TJm
+(this) 14.396 Tj
+-250 TJm
+(isn') 14.9439 Tj
+18 TJm
+(t) 2.7696 Tj
+-250 TJm
+(what) 19.3673 Tj
+-250 TJm
+(you) 14.9439 Tj
+-250 TJm
+(w) 7.193 Tj
+10 TJm
+(ant.) 14.6649 Tj
+[1 0 0 1 72 83.0755] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -22.2611] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 374.394 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 6.8541] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 40.5726 -6.7545] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -493.841 -50.9514] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+534.414 50.9514 Td
+/F130_0 9.9626 Tf
+(33) 9.9626 Tj
+[1 0 0 1 453.269 50.8518] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 93.5985 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.2765 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+Q
+showpage
+%%PageTrailer
+pdfEndPage
+%%Page: 37 37
+%%BeginPageSetup
+%%PageOrientation: Portrait
+pdfStartPage
+0 0 612 792 re W
+%%EndPageSetup
+[] 0 d
+1 i
+0 j
+0 J
+10 M
+1 w
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+false op
+false OP
+0 0 612 792 re
+W
+q
+[1 0 0 1 72 741.554] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 14.4459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 187.197 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 -6.8541] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 6.8541] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 116.328 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -382.4 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+498.728 749.245 Td
+/F130_0 9.9626 Tf
+(Miscellanea) 48.1393 Tj
+[1 0 0 1 266.071 749.146] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 280.796 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -472.974 -7.0936] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -0.4981] cm
+q
+[] 0 d
+0 J
+0.4981 w
+0 0.2491 m
+475.465 0.2491 l
+S
+Q
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 479.251 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -540 -741.554] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 710.037 Td
+/F130_0 9.9626 Tf
+(If) 6.63509 Tj
+-275 TJm
+(you) 14.9439 Tj
+-274 TJm
+(w) 7.193 Tj
+10 TJm
+(ant) 12.1743 Tj
+-275 TJm
+(a) 4.42339 Tj
+-274 TJm
+(compressor) 45.9276 Tj
+-275 TJm
+(and/or) 25.4544 Tj
+-275 TJm
+(library) 26.5603 Tj
+-274 TJm
+(which) 24.3486 Tj
+-275 TJm
+(is) 6.64505 Tj
+-274 TJm
+(f) 3.31755 Tj
+10 TJm
+(aster) 18.8094 Tj
+40 TJm
+(,) 2.49065 Tj
+-281 TJm
+(uses) 17.1556 Tj
+-275 TJm
+(less) 14.9439 Tj
+-274 TJm
+(memory) 33.2053 Tj
+-275 TJm
+(b) 4.9813 Tj
+20 TJm
+(ut) 7.7509 Tj
+-275 TJm
+(gets) 16.0497 Tj
+-274 TJm
+(pretty) 23.2427 Tj
+-275 TJm
+(good) 19.9252 Tj
+-274 TJm
+(compression,) 52.8516 Tj
+-281 TJm
+(and) 14.386 Tj
+-275 TJm
+(has) 13.2801 Tj
+72 698.082 Td
+(minimal) 33.2153 Tj
+-288 TJm
+(latenc) 23.7907 Tj
+15 TJm
+(y) 4.9813 Tj
+65 TJm
+(,) 2.49065 Tj
+-297 TJm
+(consider) 33.7533 Tj
+-288 TJm
+(Jean-loup) 38.7346 Tj
+-288 TJm
+(Gailly') 28.224 Tj
+55 TJm
+(s) 3.87545 Tj
+-288 TJm
+(and) 14.386 Tj
+-288 TJm
+(Mark) 21.579 Tj
+-288 TJm
+(Adl) 14.9439 Tj
+1 TJm
+(er') 11.0585 Tj
+55 TJm
+(s) 3.87545 Tj
+-288 TJm
+(w) 7.193 Tj
+10 TJm
+(ork,) 15.7708 Tj
+[1 0 0 1 353.879 698.082] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -353.879 -698.082] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+353.879 698.082 Td
+/F134_0 9.9626 Tf
+(zlib-1.2.1) 59.7756 Tj
+[1 0 0 1 413.655 698.082] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -413.655 -698.082] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+416.523 698.082 Td
+/F130_0 9.9626 Tf
+(and) 14.386 Tj
+[1 0 0 1 433.777 698.082] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -433.777 -698.082] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+433.777 698.082 Td
+/F134_0 9.9626 Tf
+(gzip-1.2.4) 59.7756 Tj
+[1 0 0 1 493.553 698.082] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -493.553 -698.082] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+493.553 698.082 Td
+/F130_0 9.9626 Tf
+(.) 2.49065 Tj
+-847 TJm
+(Look) 21.031 Tj
+-288 TJm
+(for) 11.6164 Tj
+72 686.127 Td
+(them) 19.9252 Tj
+-250 TJm
+(at) 7.193 Tj
+-250 TJm
+(http://www) 45.3896 Tj
+65 TJm
+(.zlib) 17.4346 Tj
+40 TJm
+(.or) 10.7895 Tj
+18 TJm
+(g) 4.9813 Tj
+-250 TJm
+(and) 14.386 Tj
+-250 TJm
+(http://www) 45.3896 Tj
+65 TJm
+(.gzip.or) 30.4357 Tj
+18 TJm
+(g) 4.9813 Tj
+-250 TJm
+(respecti) 30.9837 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(ely) 12.1743 Tj
+65 TJm
+(.) 2.49065 Tj
+[1 0 0 1 72 683.97] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -674.008] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 664.209 Td
+/F130_0 9.9626 Tf
+(F) 5.53921 Tj
+15 TJm
+(or) 8.29885 Tj
+-582 TJm
+(something) 41.5142 Tj
+-583 TJm
+(f) 3.31755 Tj
+10 TJm
+(aster) 18.8094 Tj
+-582 TJm
+(and) 14.386 Tj
+-582 TJm
+(lighter) 26.0123 Tj
+-583 TJm
+(still,) 17.4445 Tj
+-665 TJm
+(you) 14.9439 Tj
+-582 TJm
+(might) 23.2527 Tj
+-583 TJm
+(try) 11.0684 Tj
+-582 TJm
+(Markus) 30.4357 Tj
+-582 TJm
+(F) 5.53921 Tj
+-582 TJm
+(X) 7.193 Tj
+-582 TJm
+(J) 3.87545 Tj
+-582 TJm
+(Oberhumer') 48.6872 Tj
+55 TJm
+(s) 3.87545 Tj
+[1 0 0 1 437.433 664.209] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -437.433 -664.209] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+437.433 664.209 Td
+/F134_0 9.9626 Tf
+(LZO) 17.9327 Tj
+[1 0 0 1 455.365 664.209] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -455.365 -664.209] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+461.163 664.209 Td
+/F130_0 9.9626 Tf
+(real-time) 35.965 Tj
+-582 TJm
+(compres-) 37.0708 Tj
+72 652.254 Td
+(sion/decompression) 79.1429 Tj
+-250 TJm
+(library) 26.5603 Tj
+65 TJm
+(,) 2.49065 Tj
+-250 TJm
+(at) 7.193 Tj
+-250 TJm
+(http://www) 45.3896 Tj
+65 TJm
+(.oberhumer) 45.6486 Tj
+55 TJm
+(.com/opensource.) 70.2762 Tj
+[1 0 0 1 72 650.097] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -640.135] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 617.501 Td
+/F122_0 20.6585 Tf
+(4.5.) 34.4584 Tj
+-278 TJm
+(Fur) 33.2808 Tj
+-20 TJm
+(ther) 39.0239 Tj
+-278 TJm
+(Reading) 81.4978 Tj
+[1 0 0 1 72 612.905] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9626] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -602.942] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 595.583 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 101.888 595.583] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -101.888 -595.583] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+104.923 595.583 Td
+/F130_0 9.9626 Tf
+(is) 6.64505 Tj
+-305 TJm
+(not) 12.7322 Tj
+-304 TJm
+(research) 33.1854 Tj
+-305 TJm
+(w) 7.193 Tj
+10 TJm
+(ork,) 15.7708 Tj
+-318 TJm
+(in) 7.7509 Tj
+-305 TJm
+(the) 12.1743 Tj
+-304 TJm
+(sense) 21.579 Tj
+-305 TJm
+(that) 14.9439 Tj
+-304 TJm
+(it) 5.53921 Tj
+-305 TJm
+(doesn') 26.5603 Tj
+18 TJm
+(t) 2.7696 Tj
+-305 TJm
+(present) 28.772 Tj
+-304 TJm
+(an) 9.40469 Tj
+15 TJm
+(y) 4.9813 Tj
+-305 TJm
+(ne) 9.40469 Tj
+25 TJm
+(w) 7.193 Tj
+-304 TJm
+(ideas.) 22.9638 Tj
+-474 TJm
+(Rather) 26.5603 Tj
+40 TJm
+(,) 2.49065 Tj
+-318 TJm
+(it') 8.85675 Tj
+55 TJm
+(s) 3.87545 Tj
+-305 TJm
+(an) 9.40469 Tj
+-305 TJm
+(engineeri) 37.0708 Tj
+1 TJm
+(ng) 9.9626 Tj
+-305 TJm
+(e) 4.42339 Tj
+15 TJm
+(x) 4.9813 Tj
+15 TJm
+(ercise) 23.2328 Tj
+72 583.628 Td
+(based) 22.6848 Tj
+-250 TJm
+(on) 9.9626 Tj
+-250 TJm
+(e) 4.42339 Tj
+15 TJm
+(xisting) 27.1282 Tj
+-250 TJm
+(ideas.) 22.9638 Tj
+[1 0 0 1 72 581.471] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -9.9627] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -571.509] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 561.71 Td
+/F130_0 9.9626 Tf
+(F) 5.53921 Tj
+15 TJm
+(our) 13.2801 Tj
+-250 TJm
+(documents) 43.1679 Tj
+-250 TJm
+(describe) 33.1954 Tj
+-250 TJm
+(essentially) 42.0621 Tj
+-250 TJm
+(all) 9.9626 Tj
+-250 TJm
+(the) 12.1743 Tj
+-250 TJm
+(ideas) 20.4731 Tj
+-250 TJm
+(behind) 27.1182 Tj
+[1 0 0 1 298.747 561.71] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -298.747 -561.71] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+298.747 561.71 Td
+/F134_0 9.9626 Tf
+(bzip2) 29.8878 Tj
+[1 0 0 1 328.635 561.71] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -328.635 -561.71] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+328.635 561.71 Td
+/F130_0 9.9626 Tf
+(:) 2.7696 Tj
+[1 0 0 1 72 559.554] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -299.875] cm
+/DeviceRGB {} cs
+[0.929398 0.968597 0.956848] sc
+/DeviceRGB {} CS
+[0.929398 0.968597 0.956848] SC
+0 0 468 298.879 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 295.293] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -550.189] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 550.189 Td
+/F134_0 9.9626 Tf
+(Michael) 41.8429 Tj
+-426 TJm
+(Burrows) 41.8429 Tj
+-426 TJm
+(and) 17.9327 Tj
+-426 TJm
+(D.) 11.9551 Tj
+-426 TJm
+(J.) 11.9551 Tj
+-426 TJm
+(Wheeler:) 47.8205 Tj
+98.4879 538.234 Td
+("A) 11.9551 Tj
+-426 TJm
+(block-sorting) 77.7083 Tj
+-426 TJm
+(lossless) 47.8205 Tj
+-426 TJm
+(data) 23.9102 Tj
+-426 TJm
+(compression) 65.7532 Tj
+-426 TJm
+(algorithm") 59.7756 Tj
+102.732 526.278 Td
+(10th) 23.9102 Tj
+-426 TJm
+(May) 17.9327 Tj
+-426 TJm
+(1994.) 29.8878 Tj
+102.732 514.323 Td
+(Digital) 41.8429 Tj
+-426 TJm
+(SRC) 17.9327 Tj
+-426 TJm
+(Research) 47.8205 Tj
+-426 TJm
+(Report) 35.8654 Tj
+-426 TJm
+(124.) 23.9102 Tj
+102.732 502.368 Td
+(ftp://ftp.digital.com/pub/DEC/SRC/research-reports/SRC-124.ps.g\
+z) 382.564 Tj
+102.732 490.413 Td
+(If) 11.9551 Tj
+-426 TJm
+(you) 17.9327 Tj
+-426 TJm
+(have) 23.9102 Tj
+-426 TJm
+(trouble) 41.8429 Tj
+-426 TJm
+(finding) 41.8429 Tj
+-426 TJm
+(it,) 17.9327 Tj
+-426 TJm
+(try) 17.9327 Tj
+-426 TJm
+(searching) 53.798 Tj
+-426 TJm
+(at) 11.9551 Tj
+-426 TJm
+(the) 17.9327 Tj
+102.732 478.458 Td
+(New) 17.9327 Tj
+-426 TJm
+(Zealand) 41.8429 Tj
+-426 TJm
+(Digital) 41.8429 Tj
+-426 TJm
+(Library,) 47.8205 Tj
+-426 TJm
+(http://www.nzdl.org.) 119.551 Tj
+90 454.547 Td
+(Daniel) 35.8654 Tj
+-426 TJm
+(S.) 11.9551 Tj
+-426 TJm
+(Hirschberg) 59.7756 Tj
+-426 TJm
+(and) 17.9327 Tj
+-426 TJm
+(Debra) 29.8878 Tj
+-426 TJm
+(A.) 11.9551 Tj
+-426 TJm
+(LeLewer) 41.8429 Tj
+98.4879 442.592 Td
+("Efficient) 59.7756 Tj
+-426 TJm
+(Decoding) 47.8205 Tj
+-426 TJm
+(of) 11.9551 Tj
+-426 TJm
+(Prefix) 35.8654 Tj
+-426 TJm
+(Codes") 35.8654 Tj
+102.732 430.637 Td
+(Communications) 83.6858 Tj
+-426 TJm
+(of) 11.9551 Tj
+-426 TJm
+(the) 17.9327 Tj
+-426 TJm
+(ACM,) 23.9102 Tj
+-426 TJm
+(April) 29.8878 Tj
+-426 TJm
+(1990,) 29.8878 Tj
+-426 TJm
+(Vol) 17.9327 Tj
+-426 TJm
+(33,) 17.9327 Tj
+-426 TJm
+(Number) 35.8654 Tj
+-426 TJm
+(4.) 11.9551 Tj
+102.732 418.682 Td
+(You) 17.9327 Tj
+-426 TJm
+(might) 29.8878 Tj
+-426 TJm
+(be) 11.9551 Tj
+-426 TJm
+(able) 23.9102 Tj
+-426 TJm
+(to) 11.9551 Tj
+-426 TJm
+(get) 17.9327 Tj
+-426 TJm
+(an) 11.9551 Tj
+-426 TJm
+(electronic) 59.7756 Tj
+-426 TJm
+(copy) 23.9102 Tj
+-426 TJm
+(of) 11.9551 Tj
+-426 TJm
+(this) 23.9102 Tj
+102.732 406.727 Td
+(from) 23.9102 Tj
+-426 TJm
+(the) 17.9327 Tj
+-426 TJm
+(ACM) 17.9327 Tj
+-426 TJm
+(Digital) 41.8429 Tj
+-426 TJm
+(Library.) 47.8205 Tj
+90 382.816 Td
+(David) 29.8878 Tj
+-426 TJm
+(J.) 11.9551 Tj
+-426 TJm
+(Wheeler) 41.8429 Tj
+102.732 370.861 Td
+(Program) 41.8429 Tj
+-426 TJm
+(bred3.c) 41.8429 Tj
+-426 TJm
+(and) 17.9327 Tj
+-426 TJm
+(accompanying) 71.7307 Tj
+-426 TJm
+(document) 47.8205 Tj
+-426 TJm
+(bred3.ps.) 53.798 Tj
+102.732 358.906 Td
+(This) 23.9102 Tj
+-426 TJm
+(contains) 47.8205 Tj
+-426 TJm
+(the) 17.9327 Tj
+-426 TJm
+(idea) 23.9102 Tj
+-426 TJm
+(behind) 35.8654 Tj
+-426 TJm
+(the) 17.9327 Tj
+-426 TJm
+(multi-table) 65.7532 Tj
+-426 TJm
+(Huffman) 41.8429 Tj
+-426 TJm
+(coding) 35.8654 Tj
+-426 TJm
+(scheme.) 41.8429 Tj
+102.732 346.951 Td
+(ftp://ftp.cl.cam.ac.uk/users/djw3/) 203.237 Tj
+90 323.041 Td
+(Jon) 17.9327 Tj
+-426 TJm
+(L.) 11.9551 Tj
+-426 TJm
+(Bentley) 41.8429 Tj
+-426 TJm
+(and) 17.9327 Tj
+-426 TJm
+(Robert) 35.8654 Tj
+-426 TJm
+(Sedgewick) 53.798 Tj
+98.4879 311.085 Td
+("Fast) 29.8878 Tj
+-426 TJm
+(Algorithms) 59.7756 Tj
+-426 TJm
+(for) 17.9327 Tj
+-426 TJm
+(Sorting) 41.8429 Tj
+-426 TJm
+(and) 17.9327 Tj
+-426 TJm
+(Searching) 53.798 Tj
+-426 TJm
+(Strings") 47.8205 Tj
+102.732 299.13 Td
+(Available) 53.798 Tj
+-426 TJm
+(from) 23.9102 Tj
+-426 TJm
+(Sedgewick's) 65.7532 Tj
+-426 TJm
+(web) 17.9327 Tj
+-426 TJm
+(page,) 29.8878 Tj
+102.732 287.175 Td
+(www.cs.princeton.edu/~rs) 143.461 Tj
+[1 0 0 1 72 259.678] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.5492] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -249.715] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 237.76 Td
+/F130_0 9.9626 Tf
+(The) 15.4918 Tj
+-239 TJm
+(follo) 18.8194 Tj
+25 TJm
+(wing) 19.9252 Tj
+-238 TJm
+(paper) 22.1269 Tj
+-239 TJm
+(gi) 7.7509 Tj
+25 TJm
+(v) 4.9813 Tj
+15 TJm
+(es) 8.29885 Tj
+-239 TJm
+(v) 4.9813 Tj
+25 TJm
+(aluable) 28.772 Tj
+-238 TJm
+(additional) 39.8504 Tj
+-239 TJm
+(insights) 31.0036 Tj
+-238 TJm
+(into) 15.5018 Tj
+-239 TJm
+(the) 12.1743 Tj
+-239 TJm
+(algorithm,) 41.2352 Tj
+-241 TJm
+(b) 4.9813 Tj
+20 TJm
+(ut) 7.7509 Tj
+-238 TJm
+(is) 6.64505 Tj
+-239 TJm
+(not) 12.7322 Tj
+-239 TJm
+(immedi) 30.4457 Tj
+1 TJm
+(ately) 19.3673 Tj
+-239 TJm
+(the) 12.1743 Tj
+-239 TJm
+(basis) 19.9252 Tj
+-238 TJm
+(of) 8.29885 Tj
+-239 TJm
+(an) 9.40469 Tj
+15 TJm
+(y) 4.9813 Tj
+-239 TJm
+(code) 18.8094 Tj
+72 225.805 Td
+(used) 18.2614 Tj
+-250 TJm
+(in) 7.7509 Tj
+-250 TJm
+(bzip2.) 24.6275 Tj
+[1 0 0 1 72 223.648] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -72.7273] cm
+/DeviceRGB {} cs
+[0.929398 0.968597 0.956848] sc
+/DeviceRGB {} CS
+[0.929398 0.968597 0.956848] SC
+0 0 468 71.731 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 68.1444] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -214.283] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 214.283 Td
+/F134_0 9.9626 Tf
+(Peter) 29.8878 Tj
+-426 TJm
+(Fenwick:) 47.8205 Tj
+102.732 202.328 Td
+(Block) 29.8878 Tj
+-426 TJm
+(Sorting) 41.8429 Tj
+-426 TJm
+(Text) 23.9102 Tj
+-426 TJm
+(Compression) 65.7532 Tj
+102.732 190.373 Td
+(Proceedings) 65.7532 Tj
+-426 TJm
+(of) 11.9551 Tj
+-426 TJm
+(the) 17.9327 Tj
+-426 TJm
+(19th) 23.9102 Tj
+-426 TJm
+(Australasian) 71.7307 Tj
+-426 TJm
+(Computer) 47.8205 Tj
+-426 TJm
+(Science) 41.8429 Tj
+-426 TJm
+(Conference,) 65.7532 Tj
+111.22 178.418 Td
+(Melbourne,) 59.7756 Tj
+-426 TJm
+(Australia.) 59.7756 Tj
+-852 TJm
+(Jan) 17.9327 Tj
+-426 TJm
+(31) 11.9551 Tj
+-426 TJm
+(-) 5.97756 Tj
+-426 TJm
+(Feb) 17.9327 Tj
+-426 TJm
+(2,) 11.9551 Tj
+-426 TJm
+(1996.) 29.8878 Tj
+102.732 166.463 Td
+(ftp://ftp.cs.auckland.ac.nz/pub/peter-f/ACSC96paper.ps) 322.788 Tj
+[1 0 0 1 72 150.921] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.5492] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -140.958] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 129.003 Td
+/F130_0 9.9626 Tf
+(K) 7.193 Tj
+15 TJm
+(unihik) 25.4644 Tj
+10 TJm
+(o) 4.9813 Tj
+-250 TJm
+(Sadakane') 41.4942 Tj
+55 TJm
+(s) 3.87545 Tj
+-250 TJm
+(sorting) 27.6761 Tj
+-250 TJm
+(algorithm,) 41.2352 Tj
+-250 TJm
+(mentioned) 42.0621 Tj
+-250 TJm
+(abo) 14.386 Tj
+15 TJm
+(v) 4.9813 Tj
+15 TJm
+(e,) 6.91404 Tj
+-250 TJm
+(is) 6.64505 Tj
+-250 TJm
+(a) 4.42339 Tj
+20 TJm
+(v) 4.9813 Tj
+25 TJm
+(ailable) 26.5603 Tj
+-250 TJm
+(from:) 22.1369 Tj
+[1 0 0 1 72 126.846] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -36.8618] cm
+/DeviceRGB {} cs
+[0.929398 0.968597 0.956848] sc
+/DeviceRGB {} CS
+[0.929398 0.968597 0.956848] SC
+0 0 468 35.8655 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 32.2789] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -117.482] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 117.482 Td
+/F134_0 9.9626 Tf
+(http://naomi.is.s.u-tokyo.ac.jp/~sada/papers/Sada98b.ps.gz) 346.698 Tj
+[1 0 0 1 72 89.9846] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.5492] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -29.1702] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 374.394 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 6.8542] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 40.5726 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -493.841 -50.9514] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+534.414 50.9514 Td
+/F130_0 9.9626 Tf
+(34) 9.9626 Tj
+[1 0 0 1 453.269 50.8518] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 93.5985 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.2765 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+Q
+showpage
+%%PageTrailer
+pdfEndPage
+%%Page: 38 38
+%%BeginPageSetup
+%%PageOrientation: Portrait
+pdfStartPage
+0 0 612 792 re W
+%%EndPageSetup
+[] 0 d
+1 i
+0 j
+0 J
+10 M
+1 w
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+false op
+false OP
+0 0 612 792 re
+W
+q
+[1 0 0 1 72 741.554] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 14.4459] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 187.197 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 -6.8541] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 6.8541] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 116.328 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -382.4 -749.245] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+498.728 749.245 Td
+/F130_0 9.9626 Tf
+(Miscellanea) 48.1393 Tj
+[1 0 0 1 266.071 749.146] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 280.796 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -472.974 -7.0936] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -0.4981] cm
+q
+[] 0 d
+0 J
+0.4981 w
+0 0.2491 m
+475.465 0.2491 l
+S
+Q
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 479.251 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -540 -741.554] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 710.037 Td
+/F130_0 9.9626 Tf
+(The) 15.4918 Tj
+-250 TJm
+(Manber) 30.9837 Tj
+20 TJm
+(-Myers) 28.772 Tj
+-250 TJm
+(suf) 12.1743 Tj
+25 TJm
+(\002x) 10.5205 Tj
+-250 TJm
+(array) 20.4632 Tj
+-250 TJm
+(construction) 49.2551 Tj
+-250 TJm
+(algorithm) 38.7446 Tj
+-250 TJm
+(is) 6.64505 Tj
+-250 TJm
+(described) 38.1767 Tj
+-250 TJm
+(in) 7.7509 Tj
+-250 TJm
+(a) 4.42339 Tj
+-250 TJm
+(paper) 22.1269 Tj
+-250 TJm
+(a) 4.42339 Tj
+20 TJm
+(v) 4.9813 Tj
+25 TJm
+(ailable) 26.5603 Tj
+-250 TJm
+(from:) 22.1369 Tj
+[1 0 0 1 72 707.88] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -36.8618] cm
+/DeviceRGB {} cs
+[0.929398 0.968597 0.956848] sc
+/DeviceRGB {} CS
+[0.929398 0.968597 0.956848] SC
+0 0 468 35.8655 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 32.2789] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3685] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -698.516] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 698.516 Td
+/F134_0 9.9626 Tf
+(http://www.cs.arizona.edu/people/gene/PAPERS/suffix.ps) 322.788 Tj
+[1 0 0 1 72 671.019] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -13.5492] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -72 -661.056] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+72 649.101 Td
+/F130_0 9.9626 Tf
+(Finally) 28.234 Tj
+65 TJm
+(,) 2.49065 Tj
+-227 TJm
+(the) 12.1743 Tj
+-221 TJm
+(follo) 18.8194 Tj
+25 TJm
+(wing) 19.9252 Tj
+-222 TJm
+(papers) 26.0024 Tj
+-221 TJm
+(document) 39.2925 Tj
+-221 TJm
+(some) 21.031 Tj
+-222 TJm
+(in) 7.7509 Tj
+40 TJm
+(v) 4.9813 Tj
+15 TJm
+(estig) 18.8194 Tj
+5 TJm
+(ations) 23.8007 Tj
+-221 TJm
+(I) 3.31755 Tj
+-221 TJm
+(made) 21.579 Tj
+-222 TJm
+(into) 15.5018 Tj
+-221 TJm
+(the) 12.1743 Tj
+-221 TJm
+(performance) 50.341 Tj
+-222 TJm
+(of) 8.29885 Tj
+-221 TJm
+(sorting) 27.6761 Tj
+-221 TJm
+(and) 14.386 Tj
+-222 TJm
+(decompression) 59.7656 Tj
+72 637.146 Td
+(algorithms:) 45.3896 Tj
+[1 0 0 1 72 634.989] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 -132.503] cm
+/DeviceRGB {} cs
+[0.929398 0.968597 0.956848] sc
+/DeviceRGB {} CS
+[0.929398 0.968597 0.956848] SC
+0 0 468 131.507 re
+f
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 127.92] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 18 -8.3686] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -90 -625.624] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+90 625.624 Td
+/F134_0 9.9626 Tf
+(Julian) 35.8654 Tj
+-426 TJm
+(Seward) 35.8654 Tj
+102.732 613.669 Td
+(On) 11.9551 Tj
+-426 TJm
+(the) 17.9327 Tj
+-426 TJm
+(Performance) 65.7532 Tj
+-426 TJm
+(of) 11.9551 Tj
+-426 TJm
+(BWT) 17.9327 Tj
+-426 TJm
+(Sorting) 41.8429 Tj
+-426 TJm
+(Algorithms) 59.7756 Tj
+102.732 601.714 Td
+(Proceedings) 65.7532 Tj
+-426 TJm
+(of) 11.9551 Tj
+-426 TJm
+(the) 17.9327 Tj
+-426 TJm
+(IEEE) 23.9102 Tj
+-426 TJm
+(Data) 23.9102 Tj
+-426 TJm
+(Compression) 65.7532 Tj
+-426 TJm
+(Conference) 59.7756 Tj
+-426 TJm
+(2000) 23.9102 Tj
+111.22 589.759 Td
+(Snowbird,) 53.798 Tj
+-426 TJm
+(Utah.) 29.8878 Tj
+-852 TJm
+(28-30) 29.8878 Tj
+-426 TJm
+(March) 29.8878 Tj
+-426 TJm
+(2000.) 29.8878 Tj
+90 565.848 Td
+(Julian) 35.8654 Tj
+-426 TJm
+(Seward) 35.8654 Tj
+102.732 553.893 Td
+(Space-time) 59.7756 Tj
+-426 TJm
+(Tradeoffs) 53.798 Tj
+-426 TJm
+(in) 11.9551 Tj
+-426 TJm
+(the) 17.9327 Tj
+-426 TJm
+(Inverse) 41.8429 Tj
+-426 TJm
+(B-W) 17.9327 Tj
+-426 TJm
+(Transform) 53.798 Tj
+102.732 541.938 Td
+(Proceedings) 65.7532 Tj
+-426 TJm
+(of) 11.9551 Tj
+-426 TJm
+(the) 17.9327 Tj
+-426 TJm
+(IEEE) 23.9102 Tj
+-426 TJm
+(Data) 23.9102 Tj
+-426 TJm
+(Compression) 65.7532 Tj
+-426 TJm
+(Conference) 59.7756 Tj
+-426 TJm
+(2001) 23.9102 Tj
+111.22 529.983 Td
+(Snowbird,) 53.798 Tj
+-426 TJm
+(Utah.) 29.8878 Tj
+-852 TJm
+(27-29) 29.8878 Tj
+-426 TJm
+(March) 29.8878 Tj
+-426 TJm
+(2001.) 29.8878 Tj
+[1 0 0 1 72 502.486] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 468 3.5866] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -468 -3.5866] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 0 -451.634] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 1.8929 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 374.394 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 2.4907 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 0 6.8541] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 40.5726 -6.7546] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 -493.841 -50.9513] cm
+[1 0 0 1 0 0] Tm
+0 0 Td
+534.414 50.9513 Td
+/F130_0 9.9626 Tf
+(35) 9.9626 Tj
+[1 0 0 1 453.269 50.8518] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 93.5985 0] cm
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+/DeviceRGB {} cs
+[0 0 0] sc
+/DeviceRGB {} CS
+[0 0 0] SC
+[1 0 0 1 6.2765 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+[1 0 0 1 -13.1436 0] cm
+/DeviceGray {} cs
+[0] sc
+/DeviceGray {} CS
+[0] SC
+Q
+showpage
+%%PageTrailer
+pdfEndPage
+%%Trailer
+end
+%%DocumentSuppliedResources:
+%%+ font DTUUHP+NimbusSanL-Bold
+%%+ font VXAMRV+NimbusRomNo9L-Regu
+%%+ font MFECUR+NimbusMonL-Regu
+%%+ font ZOVMRD+CMMI10
+%%+ font ERVBFT+NimbusMonL-Bold
+%%+ font BZXIEB+CMSY10
+%%+ font WWWUTU+NimbusRomNo9L-ReguItal
+%%EOF
diff --git a/Utilities/cmbzip2/manual.xml b/Utilities/cmbzip2/manual.xml
new file mode 100644
index 000000000..f22413602
--- /dev/null
+++ b/Utilities/cmbzip2/manual.xml
@@ -0,0 +1,2964 @@
+<?xml version="1.0"?> <!-- -*- sgml -*- -->
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"[
+
+<!-- various strings, dates etc. common to all docs -->
+<!ENTITY % common-ents SYSTEM "entities.xml"> %common-ents;
+]>
+
+<book lang="en" id="userman" xreflabel="bzip2 Manual">
+
+ <bookinfo>
+ <title>bzip2 and libbzip2, version 1.0.5</title>
+ <subtitle>A program and library for data compression</subtitle>
+ <copyright>
+ <year>&bz-lifespan;</year>
+ <holder>Julian Seward</holder>
+ </copyright>
+ <releaseinfo>Version &bz-version; of &bz-date;</releaseinfo>
+
+ <authorgroup>
+ <author>
+ <firstname>Julian</firstname>
+ <surname>Seward</surname>
+ <affiliation>
+ <orgname>&bz-url;</orgname>
+ </affiliation>
+ </author>
+ </authorgroup>
+
+ <legalnotice>
+
+ <para>This program, <computeroutput>bzip2</computeroutput>, the
+ associated library <computeroutput>libbzip2</computeroutput>, and
+ all documentation, are copyright &copy; &bz-lifespan; Julian Seward.
+ All rights reserved.</para>
+
+ <para>Redistribution and use in source and binary forms, with
+ or without modification, are permitted provided that the
+ following conditions are met:</para>
+
+ <itemizedlist mark='bullet'>
+
+ <listitem><para>Redistributions of source code must retain the
+ above copyright notice, this list of conditions and the
+ following disclaimer.</para></listitem>
+
+ <listitem><para>The origin of this software must not be
+ misrepresented; you must not claim that you wrote the original
+ software. If you use this software in a product, an
+ acknowledgment in the product documentation would be
+ appreciated but is not required.</para></listitem>
+
+ <listitem><para>Altered source versions must be plainly marked
+ as such, and must not be misrepresented as being the original
+ software.</para></listitem>
+
+ <listitem><para>The name of the author may not be used to
+ endorse or promote products derived from this software without
+ specific prior written permission.</para></listitem>
+
+ </itemizedlist>
+
+ <para>THIS SOFTWARE IS PROVIDED BY THE AUTHOR "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 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.</para>
+
+ <para>PATENTS: To the best of my knowledge,
+ <computeroutput>bzip2</computeroutput> and
+ <computeroutput>libbzip2</computeroutput> do not use any patented
+ algorithms. However, I do not have the resources to carry
+ out a patent search. Therefore I cannot give any guarantee of
+ the above statement.
+ </para>
+
+</legalnotice>
+
+</bookinfo>
+
+
+
+<chapter id="intro" xreflabel="Introduction">
+<title>Introduction</title>
+
+<para><computeroutput>bzip2</computeroutput> compresses files
+using the Burrows-Wheeler block-sorting text compression
+algorithm, and Huffman coding. Compression is generally
+considerably better than that achieved by more conventional
+LZ77/LZ78-based compressors, and approaches the performance of
+the PPM family of statistical compressors.</para>
+
+<para><computeroutput>bzip2</computeroutput> is built on top of
+<computeroutput>libbzip2</computeroutput>, a flexible library for
+handling compressed data in the
+<computeroutput>bzip2</computeroutput> format. This manual
+describes both how to use the program and how to work with the
+library interface. Most of the manual is devoted to this
+library, not the program, which is good news if your interest is
+only in the program.</para>
+
+<itemizedlist mark='bullet'>
+
+ <listitem><para><xref linkend="using"/> describes how to use
+ <computeroutput>bzip2</computeroutput>; this is the only part
+ you need to read if you just want to know how to operate the
+ program.</para></listitem>
+
+ <listitem><para><xref linkend="libprog"/> describes the
+ programming interfaces in detail, and</para></listitem>
+
+ <listitem><para><xref linkend="misc"/> records some
+ miscellaneous notes which I thought ought to be recorded
+ somewhere.</para></listitem>
+
+</itemizedlist>
+
+</chapter>
+
+
+<chapter id="using" xreflabel="How to use bzip2">
+<title>How to use bzip2</title>
+
+<para>This chapter contains a copy of the
+<computeroutput>bzip2</computeroutput> man page, and nothing
+else.</para>
+
+<sect1 id="name" xreflabel="NAME">
+<title>NAME</title>
+
+<itemizedlist mark='bullet'>
+
+ <listitem><para><computeroutput>bzip2</computeroutput>,
+ <computeroutput>bunzip2</computeroutput> - a block-sorting file
+ compressor, v1.0.4</para></listitem>
+
+ <listitem><para><computeroutput>bzcat</computeroutput> -
+ decompresses files to stdout</para></listitem>
+
+ <listitem><para><computeroutput>bzip2recover</computeroutput> -
+ recovers data from damaged bzip2 files</para></listitem>
+
+</itemizedlist>
+
+</sect1>
+
+
+<sect1 id="synopsis" xreflabel="SYNOPSIS">
+<title>SYNOPSIS</title>
+
+<itemizedlist mark='bullet'>
+
+ <listitem><para><computeroutput>bzip2</computeroutput> [
+ -cdfkqstvzVL123456789 ] [ filenames ... ]</para></listitem>
+
+ <listitem><para><computeroutput>bunzip2</computeroutput> [
+ -fkvsVL ] [ filenames ... ]</para></listitem>
+
+ <listitem><para><computeroutput>bzcat</computeroutput> [ -s ] [
+ filenames ... ]</para></listitem>
+
+ <listitem><para><computeroutput>bzip2recover</computeroutput>
+ filename</para></listitem>
+
+</itemizedlist>
+
+</sect1>
+
+
+<sect1 id="description" xreflabel="DESCRIPTION">
+<title>DESCRIPTION</title>
+
+<para><computeroutput>bzip2</computeroutput> compresses files
+using the Burrows-Wheeler block sorting text compression
+algorithm, and Huffman coding. Compression is generally
+considerably better than that achieved by more conventional
+LZ77/LZ78-based compressors, and approaches the performance of
+the PPM family of statistical compressors.</para>
+
+<para>The command-line options are deliberately very similar to
+those of GNU <computeroutput>gzip</computeroutput>, but they are
+not identical.</para>
+
+<para><computeroutput>bzip2</computeroutput> expects a list of
+file names to accompany the command-line flags. Each file is
+replaced by a compressed version of itself, with the name
+<computeroutput>original_name.bz2</computeroutput>. Each
+compressed file has the same modification date, permissions, and,
+when possible, ownership as the corresponding original, so that
+these properties can be correctly restored at decompression time.
+File name handling is naive in the sense that there is no
+mechanism for preserving original file names, permissions,
+ownerships or dates in filesystems which lack these concepts, or
+have serious file name length restrictions, such as
+MS-DOS.</para>
+
+<para><computeroutput>bzip2</computeroutput> and
+<computeroutput>bunzip2</computeroutput> will by default not
+overwrite existing files. If you want this to happen, specify
+the <computeroutput>-f</computeroutput> flag.</para>
+
+<para>If no file names are specified,
+<computeroutput>bzip2</computeroutput> compresses from standard
+input to standard output. In this case,
+<computeroutput>bzip2</computeroutput> will decline to write
+compressed output to a terminal, as this would be entirely
+incomprehensible and therefore pointless.</para>
+
+<para><computeroutput>bunzip2</computeroutput> (or
+<computeroutput>bzip2 -d</computeroutput>) decompresses all
+specified files. Files which were not created by
+<computeroutput>bzip2</computeroutput> will be detected and
+ignored, and a warning issued.
+<computeroutput>bzip2</computeroutput> attempts to guess the
+filename for the decompressed file from that of the compressed
+file as follows:</para>
+
+<itemizedlist mark='bullet'>
+
+ <listitem><para><computeroutput>filename.bz2 </computeroutput>
+ becomes
+ <computeroutput>filename</computeroutput></para></listitem>
+
+ <listitem><para><computeroutput>filename.bz </computeroutput>
+ becomes
+ <computeroutput>filename</computeroutput></para></listitem>
+
+ <listitem><para><computeroutput>filename.tbz2</computeroutput>
+ becomes
+ <computeroutput>filename.tar</computeroutput></para></listitem>
+
+ <listitem><para><computeroutput>filename.tbz </computeroutput>
+ becomes
+ <computeroutput>filename.tar</computeroutput></para></listitem>
+
+ <listitem><para><computeroutput>anyothername </computeroutput>
+ becomes
+ <computeroutput>anyothername.out</computeroutput></para></listitem>
+
+</itemizedlist>
+
+<para>If the file does not end in one of the recognised endings,
+<computeroutput>.bz2</computeroutput>,
+<computeroutput>.bz</computeroutput>,
+<computeroutput>.tbz2</computeroutput> or
+<computeroutput>.tbz</computeroutput>,
+<computeroutput>bzip2</computeroutput> complains that it cannot
+guess the name of the original file, and uses the original name
+with <computeroutput>.out</computeroutput> appended.</para>
+
+<para>As with compression, supplying no filenames causes
+decompression from standard input to standard output.</para>
+
+<para><computeroutput>bunzip2</computeroutput> will correctly
+decompress a file which is the concatenation of two or more
+compressed files. The result is the concatenation of the
+corresponding uncompressed files. Integrity testing
+(<computeroutput>-t</computeroutput>) of concatenated compressed
+files is also supported.</para>
+
+<para>You can also compress or decompress files to the standard
+output by giving the <computeroutput>-c</computeroutput> flag.
+Multiple files may be compressed and decompressed like this. The
+resulting outputs are fed sequentially to stdout. Compression of
+multiple files in this manner generates a stream containing
+multiple compressed file representations. Such a stream can be
+decompressed correctly only by
+<computeroutput>bzip2</computeroutput> version 0.9.0 or later.
+Earlier versions of <computeroutput>bzip2</computeroutput> will
+stop after decompressing the first file in the stream.</para>
+
+<para><computeroutput>bzcat</computeroutput> (or
+<computeroutput>bzip2 -dc</computeroutput>) decompresses all
+specified files to the standard output.</para>
+
+<para><computeroutput>bzip2</computeroutput> will read arguments
+from the environment variables
+<computeroutput>BZIP2</computeroutput> and
+<computeroutput>BZIP</computeroutput>, in that order, and will
+process them before any arguments read from the command line.
+This gives a convenient way to supply default arguments.</para>
+
+<para>Compression is always performed, even if the compressed
+file is slightly larger than the original. Files of less than
+about one hundred bytes tend to get larger, since the compression
+mechanism has a constant overhead in the region of 50 bytes.
+Random data (including the output of most file compressors) is
+coded at about 8.05 bits per byte, giving an expansion of around
+0.5%.</para>
+
+<para>As a self-check for your protection,
+<computeroutput>bzip2</computeroutput> uses 32-bit CRCs to make
+sure that the decompressed version of a file is identical to the
+original. This guards against corruption of the compressed data,
+and against undetected bugs in
+<computeroutput>bzip2</computeroutput> (hopefully very unlikely).
+The chances of data corruption going undetected is microscopic,
+about one chance in four billion for each file processed. Be
+aware, though, that the check occurs upon decompression, so it
+can only tell you that something is wrong. It can't help you
+recover the original uncompressed data. You can use
+<computeroutput>bzip2recover</computeroutput> to try to recover
+data from damaged files.</para>
+
+<para>Return values: 0 for a normal exit, 1 for environmental
+problems (file not found, invalid flags, I/O errors, etc.), 2
+to indicate a corrupt compressed file, 3 for an internal
+consistency error (eg, bug) which caused
+<computeroutput>bzip2</computeroutput> to panic.</para>
+
+</sect1>
+
+
+<sect1 id="options" xreflabel="OPTIONS">
+<title>OPTIONS</title>
+
+<variablelist>
+
+ <varlistentry>
+ <term><computeroutput>-c --stdout</computeroutput></term>
+ <listitem><para>Compress or decompress to standard
+ output.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><computeroutput>-d --decompress</computeroutput></term>
+ <listitem><para>Force decompression.
+ <computeroutput>bzip2</computeroutput>,
+ <computeroutput>bunzip2</computeroutput> and
+ <computeroutput>bzcat</computeroutput> are really the same
+ program, and the decision about what actions to take is done on
+ the basis of which name is used. This flag overrides that
+ mechanism, and forces bzip2 to decompress.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><computeroutput>-z --compress</computeroutput></term>
+ <listitem><para>The complement to
+ <computeroutput>-d</computeroutput>: forces compression,
+ regardless of the invokation name.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><computeroutput>-t --test</computeroutput></term>
+ <listitem><para>Check integrity of the specified file(s), but
+ don't decompress them. This really performs a trial
+ decompression and throws away the result.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><computeroutput>-f --force</computeroutput></term>
+ <listitem><para>Force overwrite of output files. Normally,
+ <computeroutput>bzip2</computeroutput> will not overwrite
+ existing output files. Also forces
+ <computeroutput>bzip2</computeroutput> to break hard links to
+ files, which it otherwise wouldn't do.</para>
+ <para><computeroutput>bzip2</computeroutput> normally declines
+ to decompress files which don't have the correct magic header
+ bytes. If forced (<computeroutput>-f</computeroutput>),
+ however, it will pass such files through unmodified. This is
+ how GNU <computeroutput>gzip</computeroutput> behaves.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><computeroutput>-k --keep</computeroutput></term>
+ <listitem><para>Keep (don't delete) input files during
+ compression or decompression.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><computeroutput>-s --small</computeroutput></term>
+ <listitem><para>Reduce memory usage, for compression,
+ decompression and testing. Files are decompressed and tested
+ using a modified algorithm which only requires 2.5 bytes per
+ block byte. This means any file can be decompressed in 2300k
+ of memory, albeit at about half the normal speed.</para>
+ <para>During compression, <computeroutput>-s</computeroutput>
+ selects a block size of 200k, which limits memory use to around
+ the same figure, at the expense of your compression ratio. In
+ short, if your machine is low on memory (8 megabytes or less),
+ use <computeroutput>-s</computeroutput> for everything. See
+ <xref linkend="memory-management"/> below.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><computeroutput>-q --quiet</computeroutput></term>
+ <listitem><para>Suppress non-essential warning messages.
+ Messages pertaining to I/O errors and other critical events
+ will not be suppressed.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><computeroutput>-v --verbose</computeroutput></term>
+ <listitem><para>Verbose mode -- show the compression ratio for
+ each file processed. Further
+ <computeroutput>-v</computeroutput>'s increase the verbosity
+ level, spewing out lots of information which is primarily of
+ interest for diagnostic purposes.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><computeroutput>-L --license -V --version</computeroutput></term>
+ <listitem><para>Display the software version, license terms and
+ conditions.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><computeroutput>-1</computeroutput> (or
+ <computeroutput>--fast</computeroutput>) to
+ <computeroutput>-9</computeroutput> (or
+ <computeroutput>-best</computeroutput>)</term>
+ <listitem><para>Set the block size to 100 k, 200 k ... 900 k
+ when compressing. Has no effect when decompressing. See <xref
+ linkend="memory-management" /> below. The
+ <computeroutput>--fast</computeroutput> and
+ <computeroutput>--best</computeroutput> aliases are primarily
+ for GNU <computeroutput>gzip</computeroutput> compatibility.
+ In particular, <computeroutput>--fast</computeroutput> doesn't
+ make things significantly faster. And
+ <computeroutput>--best</computeroutput> merely selects the
+ default behaviour.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><computeroutput>--</computeroutput></term>
+ <listitem><para>Treats all subsequent arguments as file names,
+ even if they start with a dash. This is so you can handle
+ files with names beginning with a dash, for example:
+ <computeroutput>bzip2 --
+ -myfilename</computeroutput>.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><computeroutput>--repetitive-fast</computeroutput></term>
+ <term><computeroutput>--repetitive-best</computeroutput></term>
+ <listitem><para>These flags are redundant in versions 0.9.5 and
+ above. They provided some coarse control over the behaviour of
+ the sorting algorithm in earlier versions, which was sometimes
+ useful. 0.9.5 and above have an improved algorithm which
+ renders these flags irrelevant.</para></listitem>
+ </varlistentry>
+
+</variablelist>
+
+</sect1>
+
+
+<sect1 id="memory-management" xreflabel="MEMORY MANAGEMENT">
+<title>MEMORY MANAGEMENT</title>
+
+<para><computeroutput>bzip2</computeroutput> compresses large
+files in blocks. The block size affects both the compression
+ratio achieved, and the amount of memory needed for compression
+and decompression. The flags <computeroutput>-1</computeroutput>
+through <computeroutput>-9</computeroutput> specify the block
+size to be 100,000 bytes through 900,000 bytes (the default)
+respectively. At decompression time, the block size used for
+compression is read from the header of the compressed file, and
+<computeroutput>bunzip2</computeroutput> then allocates itself
+just enough memory to decompress the file. Since block sizes are
+stored in compressed files, it follows that the flags
+<computeroutput>-1</computeroutput> to
+<computeroutput>-9</computeroutput> are irrelevant to and so
+ignored during decompression.</para>
+
+<para>Compression and decompression requirements, in bytes, can be
+estimated as:</para>
+<programlisting>
+Compression: 400k + ( 8 x block size )
+
+Decompression: 100k + ( 4 x block size ), or
+ 100k + ( 2.5 x block size )
+</programlisting>
+
+<para>Larger block sizes give rapidly diminishing marginal
+returns. Most of the compression comes from the first two or
+three hundred k of block size, a fact worth bearing in mind when
+using <computeroutput>bzip2</computeroutput> on small machines.
+It is also important to appreciate that the decompression memory
+requirement is set at compression time by the choice of block
+size.</para>
+
+<para>For files compressed with the default 900k block size,
+<computeroutput>bunzip2</computeroutput> will require about 3700
+kbytes to decompress. To support decompression of any file on a
+4 megabyte machine, <computeroutput>bunzip2</computeroutput> has
+an option to decompress using approximately half this amount of
+memory, about 2300 kbytes. Decompression speed is also halved,
+so you should use this option only where necessary. The relevant
+flag is <computeroutput>-s</computeroutput>.</para>
+
+<para>In general, try and use the largest block size memory
+constraints allow, since that maximises the compression achieved.
+Compression and decompression speed are virtually unaffected by
+block size.</para>
+
+<para>Another significant point applies to files which fit in a
+single block -- that means most files you'd encounter using a
+large block size. The amount of real memory touched is
+proportional to the size of the file, since the file is smaller
+than a block. For example, compressing a file 20,000 bytes long
+with the flag <computeroutput>-9</computeroutput> will cause the
+compressor to allocate around 7600k of memory, but only touch
+400k + 20000 * 8 = 560 kbytes of it. Similarly, the decompressor
+will allocate 3700k but only touch 100k + 20000 * 4 = 180
+kbytes.</para>
+
+<para>Here is a table which summarises the maximum memory usage
+for different block sizes. Also recorded is the total compressed
+size for 14 files of the Calgary Text Compression Corpus
+totalling 3,141,622 bytes. This column gives some feel for how
+compression varies with block size. These figures tend to
+understate the advantage of larger block sizes for larger files,
+since the Corpus is dominated by smaller files.</para>
+
+<programlisting>
+ Compress Decompress Decompress Corpus
+Flag usage usage -s usage Size
+
+ -1 1200k 500k 350k 914704
+ -2 2000k 900k 600k 877703
+ -3 2800k 1300k 850k 860338
+ -4 3600k 1700k 1100k 846899
+ -5 4400k 2100k 1350k 845160
+ -6 5200k 2500k 1600k 838626
+ -7 6100k 2900k 1850k 834096
+ -8 6800k 3300k 2100k 828642
+ -9 7600k 3700k 2350k 828642
+</programlisting>
+
+</sect1>
+
+
+<sect1 id="recovering" xreflabel="RECOVERING DATA FROM DAMAGED FILES">
+<title>RECOVERING DATA FROM DAMAGED FILES</title>
+
+<para><computeroutput>bzip2</computeroutput> compresses files in
+blocks, usually 900kbytes long. Each block is handled
+independently. If a media or transmission error causes a
+multi-block <computeroutput>.bz2</computeroutput> file to become
+damaged, it may be possible to recover data from the undamaged
+blocks in the file.</para>
+
+<para>The compressed representation of each block is delimited by
+a 48-bit pattern, which makes it possible to find the block
+boundaries with reasonable certainty. Each block also carries
+its own 32-bit CRC, so damaged blocks can be distinguished from
+undamaged ones.</para>
+
+<para><computeroutput>bzip2recover</computeroutput> is a simple
+program whose purpose is to search for blocks in
+<computeroutput>.bz2</computeroutput> files, and write each block
+out into its own <computeroutput>.bz2</computeroutput> file. You
+can then use <computeroutput>bzip2 -t</computeroutput> to test
+the integrity of the resulting files, and decompress those which
+are undamaged.</para>
+
+<para><computeroutput>bzip2recover</computeroutput> takes a
+single argument, the name of the damaged file, and writes a
+number of files <computeroutput>rec0001file.bz2</computeroutput>,
+<computeroutput>rec0002file.bz2</computeroutput>, etc, containing
+the extracted blocks. The output filenames are designed so that
+the use of wildcards in subsequent processing -- for example,
+<computeroutput>bzip2 -dc rec*file.bz2 &#62;
+recovered_data</computeroutput> -- lists the files in the correct
+order.</para>
+
+<para><computeroutput>bzip2recover</computeroutput> should be of
+most use dealing with large <computeroutput>.bz2</computeroutput>
+files, as these will contain many blocks. It is clearly futile
+to use it on damaged single-block files, since a damaged block
+cannot be recovered. If you wish to minimise any potential data
+loss through media or transmission errors, you might consider
+compressing with a smaller block size.</para>
+
+</sect1>
+
+
+<sect1 id="performance" xreflabel="PERFORMANCE NOTES">
+<title>PERFORMANCE NOTES</title>
+
+<para>The sorting phase of compression gathers together similar
+strings in the file. Because of this, files containing very long
+runs of repeated symbols, like "aabaabaabaab ..." (repeated
+several hundred times) may compress more slowly than normal.
+Versions 0.9.5 and above fare much better than previous versions
+in this respect. The ratio between worst-case and average-case
+compression time is in the region of 10:1. For previous
+versions, this figure was more like 100:1. You can use the
+<computeroutput>-vvvv</computeroutput> option to monitor progress
+in great detail, if you want.</para>
+
+<para>Decompression speed is unaffected by these
+phenomena.</para>
+
+<para><computeroutput>bzip2</computeroutput> usually allocates
+several megabytes of memory to operate in, and then charges all
+over it in a fairly random fashion. This means that performance,
+both for compressing and decompressing, is largely determined by
+the speed at which your machine can service cache misses.
+Because of this, small changes to the code to reduce the miss
+rate have been observed to give disproportionately large
+performance improvements. I imagine
+<computeroutput>bzip2</computeroutput> will perform best on
+machines with very large caches.</para>
+
+</sect1>
+
+
+
+<sect1 id="caveats" xreflabel="CAVEATS">
+<title>CAVEATS</title>
+
+<para>I/O error messages are not as helpful as they could be.
+<computeroutput>bzip2</computeroutput> tries hard to detect I/O
+errors and exit cleanly, but the details of what the problem is
+sometimes seem rather misleading.</para>
+
+<para>This manual page pertains to version &bz-version; of
+<computeroutput>bzip2</computeroutput>. Compressed data created by
+this version is entirely forwards and backwards compatible with the
+previous public releases, versions 0.1pl2, 0.9.0 and 0.9.5, 1.0.0,
+1.0.1, 1.0.2 and 1.0.3, but with the following exception: 0.9.0 and
+above can correctly decompress multiple concatenated compressed files.
+0.1pl2 cannot do this; it will stop after decompressing just the first
+file in the stream.</para>
+
+<para><computeroutput>bzip2recover</computeroutput> versions
+prior to 1.0.2 used 32-bit integers to represent bit positions in
+compressed files, so it could not handle compressed files more
+than 512 megabytes long. Versions 1.0.2 and above use 64-bit ints
+on some platforms which support them (GNU supported targets, and
+Windows). To establish whether or not
+<computeroutput>bzip2recover</computeroutput> was built with such
+a limitation, run it without arguments. In any event you can
+build yourself an unlimited version if you can recompile it with
+<computeroutput>MaybeUInt64</computeroutput> set to be an
+unsigned 64-bit integer.</para>
+
+</sect1>
+
+
+
+<sect1 id="author" xreflabel="AUTHOR">
+<title>AUTHOR</title>
+
+<para>Julian Seward,
+<computeroutput>&bz-email;</computeroutput></para>
+
+<para>The ideas embodied in
+<computeroutput>bzip2</computeroutput> are due to (at least) the
+following people: Michael Burrows and David Wheeler (for the
+block sorting transformation), David Wheeler (again, for the
+Huffman coder), Peter Fenwick (for the structured coding model in
+the original <computeroutput>bzip</computeroutput>, and many
+refinements), and Alistair Moffat, Radford Neal and Ian Witten
+(for the arithmetic coder in the original
+<computeroutput>bzip</computeroutput>). I am much indebted for
+their help, support and advice. See the manual in the source
+distribution for pointers to sources of documentation. Christian
+von Roques encouraged me to look for faster sorting algorithms,
+so as to speed up compression. Bela Lubkin encouraged me to
+improve the worst-case compression performance.
+Donna Robinson XMLised the documentation.
+Many people sent
+patches, helped with portability problems, lent machines, gave
+advice and were generally helpful.</para>
+
+</sect1>
+
+</chapter>
+
+
+
+<chapter id="libprog" xreflabel="Programming with libbzip2">
+<title>
+Programming with <computeroutput>libbzip2</computeroutput>
+</title>
+
+<para>This chapter describes the programming interface to
+<computeroutput>libbzip2</computeroutput>.</para>
+
+<para>For general background information, particularly about
+memory use and performance aspects, you'd be well advised to read
+<xref linkend="using"/> as well.</para>
+
+
+<sect1 id="top-level" xreflabel="Top-level structure">
+<title>Top-level structure</title>
+
+<para><computeroutput>libbzip2</computeroutput> is a flexible
+library for compressing and decompressing data in the
+<computeroutput>bzip2</computeroutput> data format. Although
+packaged as a single entity, it helps to regard the library as
+three separate parts: the low level interface, and the high level
+interface, and some utility functions.</para>
+
+<para>The structure of
+<computeroutput>libbzip2</computeroutput>'s interfaces is similar
+to that of Jean-loup Gailly's and Mark Adler's excellent
+<computeroutput>zlib</computeroutput> library.</para>
+
+<para>All externally visible symbols have names beginning
+<computeroutput>BZ2_</computeroutput>. This is new in version
+1.0. The intention is to minimise pollution of the namespaces of
+library clients.</para>
+
+<para>To use any part of the library, you need to
+<computeroutput>#include &lt;bzlib.h&gt;</computeroutput>
+into your sources.</para>
+
+
+
+<sect2 id="ll-summary" xreflabel="Low-level summary">
+<title>Low-level summary</title>
+
+<para>This interface provides services for compressing and
+decompressing data in memory. There's no provision for dealing
+with files, streams or any other I/O mechanisms, just straight
+memory-to-memory work. In fact, this part of the library can be
+compiled without inclusion of
+<computeroutput>stdio.h</computeroutput>, which may be helpful
+for embedded applications.</para>
+
+<para>The low-level part of the library has no global variables
+and is therefore thread-safe.</para>
+
+<para>Six routines make up the low level interface:
+<computeroutput>BZ2_bzCompressInit</computeroutput>,
+<computeroutput>BZ2_bzCompress</computeroutput>, and
+<computeroutput>BZ2_bzCompressEnd</computeroutput> for
+compression, and a corresponding trio
+<computeroutput>BZ2_bzDecompressInit</computeroutput>,
+<computeroutput>BZ2_bzDecompress</computeroutput> and
+<computeroutput>BZ2_bzDecompressEnd</computeroutput> for
+decompression. The <computeroutput>*Init</computeroutput>
+functions allocate memory for compression/decompression and do
+other initialisations, whilst the
+<computeroutput>*End</computeroutput> functions close down
+operations and release memory.</para>
+
+<para>The real work is done by
+<computeroutput>BZ2_bzCompress</computeroutput> and
+<computeroutput>BZ2_bzDecompress</computeroutput>. These
+compress and decompress data from a user-supplied input buffer to
+a user-supplied output buffer. These buffers can be any size;
+arbitrary quantities of data are handled by making repeated calls
+to these functions. This is a flexible mechanism allowing a
+consumer-pull style of activity, or producer-push, or a mixture
+of both.</para>
+
+</sect2>
+
+
+<sect2 id="hl-summary" xreflabel="High-level summary">
+<title>High-level summary</title>
+
+<para>This interface provides some handy wrappers around the
+low-level interface to facilitate reading and writing
+<computeroutput>bzip2</computeroutput> format files
+(<computeroutput>.bz2</computeroutput> files). The routines
+provide hooks to facilitate reading files in which the
+<computeroutput>bzip2</computeroutput> data stream is embedded
+within some larger-scale file structure, or where there are
+multiple <computeroutput>bzip2</computeroutput> data streams
+concatenated end-to-end.</para>
+
+<para>For reading files,
+<computeroutput>BZ2_bzReadOpen</computeroutput>,
+<computeroutput>BZ2_bzRead</computeroutput>,
+<computeroutput>BZ2_bzReadClose</computeroutput> and
+<computeroutput>BZ2_bzReadGetUnused</computeroutput> are
+supplied. For writing files,
+<computeroutput>BZ2_bzWriteOpen</computeroutput>,
+<computeroutput>BZ2_bzWrite</computeroutput> and
+<computeroutput>BZ2_bzWriteFinish</computeroutput> are
+available.</para>
+
+<para>As with the low-level library, no global variables are used
+so the library is per se thread-safe. However, if I/O errors
+occur whilst reading or writing the underlying compressed files,
+you may have to consult <computeroutput>errno</computeroutput> to
+determine the cause of the error. In that case, you'd need a C
+library which correctly supports
+<computeroutput>errno</computeroutput> in a multithreaded
+environment.</para>
+
+<para>To make the library a little simpler and more portable,
+<computeroutput>BZ2_bzReadOpen</computeroutput> and
+<computeroutput>BZ2_bzWriteOpen</computeroutput> require you to
+pass them file handles (<computeroutput>FILE*</computeroutput>s)
+which have previously been opened for reading or writing
+respectively. That avoids portability problems associated with
+file operations and file attributes, whilst not being much of an
+imposition on the programmer.</para>
+
+</sect2>
+
+
+<sect2 id="util-fns-summary" xreflabel="Utility functions summary">
+<title>Utility functions summary</title>
+
+<para>For very simple needs,
+<computeroutput>BZ2_bzBuffToBuffCompress</computeroutput> and
+<computeroutput>BZ2_bzBuffToBuffDecompress</computeroutput> are
+provided. These compress data in memory from one buffer to
+another buffer in a single function call. You should assess
+whether these functions fulfill your memory-to-memory
+compression/decompression requirements before investing effort in
+understanding the more general but more complex low-level
+interface.</para>
+
+<para>Yoshioka Tsuneo
+(<computeroutput>tsuneo@rr.iij4u.or.jp</computeroutput>) has
+contributed some functions to give better
+<computeroutput>zlib</computeroutput> compatibility. These
+functions are <computeroutput>BZ2_bzopen</computeroutput>,
+<computeroutput>BZ2_bzread</computeroutput>,
+<computeroutput>BZ2_bzwrite</computeroutput>,
+<computeroutput>BZ2_bzflush</computeroutput>,
+<computeroutput>BZ2_bzclose</computeroutput>,
+<computeroutput>BZ2_bzerror</computeroutput> and
+<computeroutput>BZ2_bzlibVersion</computeroutput>. You may find
+these functions more convenient for simple file reading and
+writing, than those in the high-level interface. These functions
+are not (yet) officially part of the library, and are minimally
+documented here. If they break, you get to keep all the pieces.
+I hope to document them properly when time permits.</para>
+
+<para>Yoshioka also contributed modifications to allow the
+library to be built as a Windows DLL.</para>
+
+</sect2>
+
+</sect1>
+
+
+<sect1 id="err-handling" xreflabel="Error handling">
+<title>Error handling</title>
+
+<para>The library is designed to recover cleanly in all
+situations, including the worst-case situation of decompressing
+random data. I'm not 100% sure that it can always do this, so
+you might want to add a signal handler to catch segmentation
+violations during decompression if you are feeling especially
+paranoid. I would be interested in hearing more about the
+robustness of the library to corrupted compressed data.</para>
+
+<para>Version 1.0.3 more robust in this respect than any
+previous version. Investigations with Valgrind (a tool for detecting
+problems with memory management) indicate
+that, at least for the few files I tested, all single-bit errors
+in the decompressed data are caught properly, with no
+segmentation faults, no uses of uninitialised data, no out of
+range reads or writes, and no infinite looping in the decompressor.
+So it's certainly pretty robust, although
+I wouldn't claim it to be totally bombproof.</para>
+
+<para>The file <computeroutput>bzlib.h</computeroutput> contains
+all definitions needed to use the library. In particular, you
+should definitely not include
+<computeroutput>bzlib_private.h</computeroutput>.</para>
+
+<para>In <computeroutput>bzlib.h</computeroutput>, the various
+return values are defined. The following list is not intended as
+an exhaustive description of the circumstances in which a given
+value may be returned -- those descriptions are given later.
+Rather, it is intended to convey the rough meaning of each return
+value. The first five actions are normal and not intended to
+denote an error situation.</para>
+
+<variablelist>
+
+ <varlistentry>
+ <term><computeroutput>BZ_OK</computeroutput></term>
+ <listitem><para>The requested action was completed
+ successfully.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><computeroutput>BZ_RUN_OK, BZ_FLUSH_OK,
+ BZ_FINISH_OK</computeroutput></term>
+ <listitem><para>In
+ <computeroutput>BZ2_bzCompress</computeroutput>, the requested
+ flush/finish/nothing-special action was completed
+ successfully.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><computeroutput>BZ_STREAM_END</computeroutput></term>
+ <listitem><para>Compression of data was completed, or the
+ logical stream end was detected during
+ decompression.</para></listitem>
+ </varlistentry>
+
+</variablelist>
+
+<para>The following return values indicate an error of some
+kind.</para>
+
+<variablelist>
+
+ <varlistentry>
+ <term><computeroutput>BZ_CONFIG_ERROR</computeroutput></term>
+ <listitem><para>Indicates that the library has been improperly
+ compiled on your platform -- a major configuration error.
+ Specifically, it means that
+ <computeroutput>sizeof(char)</computeroutput>,
+ <computeroutput>sizeof(short)</computeroutput> and
+ <computeroutput>sizeof(int)</computeroutput> are not 1, 2 and
+ 4 respectively, as they should be. Note that the library
+ should still work properly on 64-bit platforms which follow
+ the LP64 programming model -- that is, where
+ <computeroutput>sizeof(long)</computeroutput> and
+ <computeroutput>sizeof(void*)</computeroutput> are 8. Under
+ LP64, <computeroutput>sizeof(int)</computeroutput> is still 4,
+ so <computeroutput>libbzip2</computeroutput>, which doesn't
+ use the <computeroutput>long</computeroutput> type, is
+ OK.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><computeroutput>BZ_SEQUENCE_ERROR</computeroutput></term>
+ <listitem><para>When using the library, it is important to call
+ the functions in the correct sequence and with data structures
+ (buffers etc) in the correct states.
+ <computeroutput>libbzip2</computeroutput> checks as much as it
+ can to ensure this is happening, and returns
+ <computeroutput>BZ_SEQUENCE_ERROR</computeroutput> if not.
+ Code which complies precisely with the function semantics, as
+ detailed below, should never receive this value; such an event
+ denotes buggy code which you should
+ investigate.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><computeroutput>BZ_PARAM_ERROR</computeroutput></term>
+ <listitem><para>Returned when a parameter to a function call is
+ out of range or otherwise manifestly incorrect. As with
+ <computeroutput>BZ_SEQUENCE_ERROR</computeroutput>, this
+ denotes a bug in the client code. The distinction between
+ <computeroutput>BZ_PARAM_ERROR</computeroutput> and
+ <computeroutput>BZ_SEQUENCE_ERROR</computeroutput> is a bit
+ hazy, but still worth making.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><computeroutput>BZ_MEM_ERROR</computeroutput></term>
+ <listitem><para>Returned when a request to allocate memory
+ failed. Note that the quantity of memory needed to decompress
+ a stream cannot be determined until the stream's header has
+ been read. So
+ <computeroutput>BZ2_bzDecompress</computeroutput> and
+ <computeroutput>BZ2_bzRead</computeroutput> may return
+ <computeroutput>BZ_MEM_ERROR</computeroutput> even though some
+ of the compressed data has been read. The same is not true
+ for compression; once
+ <computeroutput>BZ2_bzCompressInit</computeroutput> or
+ <computeroutput>BZ2_bzWriteOpen</computeroutput> have
+ successfully completed,
+ <computeroutput>BZ_MEM_ERROR</computeroutput> cannot
+ occur.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><computeroutput>BZ_DATA_ERROR</computeroutput></term>
+ <listitem><para>Returned when a data integrity error is
+ detected during decompression. Most importantly, this means
+ when stored and computed CRCs for the data do not match. This
+ value is also returned upon detection of any other anomaly in
+ the compressed data.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><computeroutput>BZ_DATA_ERROR_MAGIC</computeroutput></term>
+ <listitem><para>As a special case of
+ <computeroutput>BZ_DATA_ERROR</computeroutput>, it is
+ sometimes useful to know when the compressed stream does not
+ start with the correct magic bytes (<computeroutput>'B' 'Z'
+ 'h'</computeroutput>).</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><computeroutput>BZ_IO_ERROR</computeroutput></term>
+ <listitem><para>Returned by
+ <computeroutput>BZ2_bzRead</computeroutput> and
+ <computeroutput>BZ2_bzWrite</computeroutput> when there is an
+ error reading or writing in the compressed file, and by
+ <computeroutput>BZ2_bzReadOpen</computeroutput> and
+ <computeroutput>BZ2_bzWriteOpen</computeroutput> for attempts
+ to use a file for which the error indicator (viz,
+ <computeroutput>ferror(f)</computeroutput>) is set. On
+ receipt of <computeroutput>BZ_IO_ERROR</computeroutput>, the
+ caller should consult <computeroutput>errno</computeroutput>
+ and/or <computeroutput>perror</computeroutput> to acquire
+ operating-system specific information about the
+ problem.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><computeroutput>BZ_UNEXPECTED_EOF</computeroutput></term>
+ <listitem><para>Returned by
+ <computeroutput>BZ2_bzRead</computeroutput> when the
+ compressed file finishes before the logical end of stream is
+ detected.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><computeroutput>BZ_OUTBUFF_FULL</computeroutput></term>
+ <listitem><para>Returned by
+ <computeroutput>BZ2_bzBuffToBuffCompress</computeroutput> and
+ <computeroutput>BZ2_bzBuffToBuffDecompress</computeroutput> to
+ indicate that the output data will not fit into the output
+ buffer provided.</para></listitem>
+ </varlistentry>
+
+</variablelist>
+
+</sect1>
+
+
+
+<sect1 id="low-level" xreflabel=">Low-level interface">
+<title>Low-level interface</title>
+
+
+<sect2 id="bzcompress-init" xreflabel="BZ2_bzCompressInit">
+<title><computeroutput>BZ2_bzCompressInit</computeroutput></title>
+
+<programlisting>
+typedef struct {
+ char *next_in;
+ unsigned int avail_in;
+ unsigned int total_in_lo32;
+ unsigned int total_in_hi32;
+
+ char *next_out;
+ unsigned int avail_out;
+ unsigned int total_out_lo32;
+ unsigned int total_out_hi32;
+
+ void *state;
+
+ void *(*bzalloc)(void *,int,int);
+ void (*bzfree)(void *,void *);
+ void *opaque;
+} bz_stream;
+
+int BZ2_bzCompressInit ( bz_stream *strm,
+ int blockSize100k,
+ int verbosity,
+ int workFactor );
+</programlisting>
+
+<para>Prepares for compression. The
+<computeroutput>bz_stream</computeroutput> structure holds all
+data pertaining to the compression activity. A
+<computeroutput>bz_stream</computeroutput> structure should be
+allocated and initialised prior to the call. The fields of
+<computeroutput>bz_stream</computeroutput> comprise the entirety
+of the user-visible data. <computeroutput>state</computeroutput>
+is a pointer to the private data structures required for
+compression.</para>
+
+<para>Custom memory allocators are supported, via fields
+<computeroutput>bzalloc</computeroutput>,
+<computeroutput>bzfree</computeroutput>, and
+<computeroutput>opaque</computeroutput>. The value
+<computeroutput>opaque</computeroutput> is passed to as the first
+argument to all calls to <computeroutput>bzalloc</computeroutput>
+and <computeroutput>bzfree</computeroutput>, but is otherwise
+ignored by the library. The call <computeroutput>bzalloc (
+opaque, n, m )</computeroutput> is expected to return a pointer
+<computeroutput>p</computeroutput> to <computeroutput>n *
+m</computeroutput> bytes of memory, and <computeroutput>bzfree (
+opaque, p )</computeroutput> should free that memory.</para>
+
+<para>If you don't want to use a custom memory allocator, set
+<computeroutput>bzalloc</computeroutput>,
+<computeroutput>bzfree</computeroutput> and
+<computeroutput>opaque</computeroutput> to
+<computeroutput>NULL</computeroutput>, and the library will then
+use the standard <computeroutput>malloc</computeroutput> /
+<computeroutput>free</computeroutput> routines.</para>
+
+<para>Before calling
+<computeroutput>BZ2_bzCompressInit</computeroutput>, fields
+<computeroutput>bzalloc</computeroutput>,
+<computeroutput>bzfree</computeroutput> and
+<computeroutput>opaque</computeroutput> should be filled
+appropriately, as just described. Upon return, the internal
+state will have been allocated and initialised, and
+<computeroutput>total_in_lo32</computeroutput>,
+<computeroutput>total_in_hi32</computeroutput>,
+<computeroutput>total_out_lo32</computeroutput> and
+<computeroutput>total_out_hi32</computeroutput> will have been
+set to zero. These four fields are used by the library to inform
+the caller of the total amount of data passed into and out of the
+library, respectively. You should not try to change them. As of
+version 1.0, 64-bit counts are maintained, even on 32-bit
+platforms, using the <computeroutput>_hi32</computeroutput>
+fields to store the upper 32 bits of the count. So, for example,
+the total amount of data in is <computeroutput>(total_in_hi32
+&#60;&#60; 32) + total_in_lo32</computeroutput>.</para>
+
+<para>Parameter <computeroutput>blockSize100k</computeroutput>
+specifies the block size to be used for compression. It should
+be a value between 1 and 9 inclusive, and the actual block size
+used is 100000 x this figure. 9 gives the best compression but
+takes most memory.</para>
+
+<para>Parameter <computeroutput>verbosity</computeroutput> should
+be set to a number between 0 and 4 inclusive. 0 is silent, and
+greater numbers give increasingly verbose monitoring/debugging
+output. If the library has been compiled with
+<computeroutput>-DBZ_NO_STDIO</computeroutput>, no such output
+will appear for any verbosity setting.</para>
+
+<para>Parameter <computeroutput>workFactor</computeroutput>
+controls how the compression phase behaves when presented with
+worst case, highly repetitive, input data. If compression runs
+into difficulties caused by repetitive data, the library switches
+from the standard sorting algorithm to a fallback algorithm. The
+fallback is slower than the standard algorithm by perhaps a
+factor of three, but always behaves reasonably, no matter how bad
+the input.</para>
+
+<para>Lower values of <computeroutput>workFactor</computeroutput>
+reduce the amount of effort the standard algorithm will expend
+before resorting to the fallback. You should set this parameter
+carefully; too low, and many inputs will be handled by the
+fallback algorithm and so compress rather slowly, too high, and
+your average-to-worst case compression times can become very
+large. The default value of 30 gives reasonable behaviour over a
+wide range of circumstances.</para>
+
+<para>Allowable values range from 0 to 250 inclusive. 0 is a
+special case, equivalent to using the default value of 30.</para>
+
+<para>Note that the compressed output generated is the same
+regardless of whether or not the fallback algorithm is
+used.</para>
+
+<para>Be aware also that this parameter may disappear entirely in
+future versions of the library. In principle it should be
+possible to devise a good way to automatically choose which
+algorithm to use. Such a mechanism would render the parameter
+obsolete.</para>
+
+<para>Possible return values:</para>
+
+<programlisting>
+BZ_CONFIG_ERROR
+ if the library has been mis-compiled
+BZ_PARAM_ERROR
+ if strm is NULL
+ or blockSize < 1 or blockSize > 9
+ or verbosity < 0 or verbosity > 4
+ or workFactor < 0 or workFactor > 250
+BZ_MEM_ERROR
+ if not enough memory is available
+BZ_OK
+ otherwise
+</programlisting>
+
+<para>Allowable next actions:</para>
+
+<programlisting>
+BZ2_bzCompress
+ if BZ_OK is returned
+ no specific action needed in case of error
+</programlisting>
+
+</sect2>
+
+
+<sect2 id="bzCompress" xreflabel="BZ2_bzCompress">
+<title><computeroutput>BZ2_bzCompress</computeroutput></title>
+
+<programlisting>
+int BZ2_bzCompress ( bz_stream *strm, int action );
+</programlisting>
+
+<para>Provides more input and/or output buffer space for the
+library. The caller maintains input and output buffers, and
+calls <computeroutput>BZ2_bzCompress</computeroutput> to transfer
+data between them.</para>
+
+<para>Before each call to
+<computeroutput>BZ2_bzCompress</computeroutput>,
+<computeroutput>next_in</computeroutput> should point at the data
+to be compressed, and <computeroutput>avail_in</computeroutput>
+should indicate how many bytes the library may read.
+<computeroutput>BZ2_bzCompress</computeroutput> updates
+<computeroutput>next_in</computeroutput>,
+<computeroutput>avail_in</computeroutput> and
+<computeroutput>total_in</computeroutput> to reflect the number
+of bytes it has read.</para>
+
+<para>Similarly, <computeroutput>next_out</computeroutput> should
+point to a buffer in which the compressed data is to be placed,
+with <computeroutput>avail_out</computeroutput> indicating how
+much output space is available.
+<computeroutput>BZ2_bzCompress</computeroutput> updates
+<computeroutput>next_out</computeroutput>,
+<computeroutput>avail_out</computeroutput> and
+<computeroutput>total_out</computeroutput> to reflect the number
+of bytes output.</para>
+
+<para>You may provide and remove as little or as much data as you
+like on each call of
+<computeroutput>BZ2_bzCompress</computeroutput>. In the limit,
+it is acceptable to supply and remove data one byte at a time,
+although this would be terribly inefficient. You should always
+ensure that at least one byte of output space is available at
+each call.</para>
+
+<para>A second purpose of
+<computeroutput>BZ2_bzCompress</computeroutput> is to request a
+change of mode of the compressed stream.</para>
+
+<para>Conceptually, a compressed stream can be in one of four
+states: IDLE, RUNNING, FLUSHING and FINISHING. Before
+initialisation
+(<computeroutput>BZ2_bzCompressInit</computeroutput>) and after
+termination (<computeroutput>BZ2_bzCompressEnd</computeroutput>),
+a stream is regarded as IDLE.</para>
+
+<para>Upon initialisation
+(<computeroutput>BZ2_bzCompressInit</computeroutput>), the stream
+is placed in the RUNNING state. Subsequent calls to
+<computeroutput>BZ2_bzCompress</computeroutput> should pass
+<computeroutput>BZ_RUN</computeroutput> as the requested action;
+other actions are illegal and will result in
+<computeroutput>BZ_SEQUENCE_ERROR</computeroutput>.</para>
+
+<para>At some point, the calling program will have provided all
+the input data it wants to. It will then want to finish up -- in
+effect, asking the library to process any data it might have
+buffered internally. In this state,
+<computeroutput>BZ2_bzCompress</computeroutput> will no longer
+attempt to read data from
+<computeroutput>next_in</computeroutput>, but it will want to
+write data to <computeroutput>next_out</computeroutput>. Because
+the output buffer supplied by the user can be arbitrarily small,
+the finishing-up operation cannot necessarily be done with a
+single call of
+<computeroutput>BZ2_bzCompress</computeroutput>.</para>
+
+<para>Instead, the calling program passes
+<computeroutput>BZ_FINISH</computeroutput> as an action to
+<computeroutput>BZ2_bzCompress</computeroutput>. This changes
+the stream's state to FINISHING. Any remaining input (ie,
+<computeroutput>next_in[0 .. avail_in-1]</computeroutput>) is
+compressed and transferred to the output buffer. To do this,
+<computeroutput>BZ2_bzCompress</computeroutput> must be called
+repeatedly until all the output has been consumed. At that
+point, <computeroutput>BZ2_bzCompress</computeroutput> returns
+<computeroutput>BZ_STREAM_END</computeroutput>, and the stream's
+state is set back to IDLE.
+<computeroutput>BZ2_bzCompressEnd</computeroutput> should then be
+called.</para>
+
+<para>Just to make sure the calling program does not cheat, the
+library makes a note of <computeroutput>avail_in</computeroutput>
+at the time of the first call to
+<computeroutput>BZ2_bzCompress</computeroutput> which has
+<computeroutput>BZ_FINISH</computeroutput> as an action (ie, at
+the time the program has announced its intention to not supply
+any more input). By comparing this value with that of
+<computeroutput>avail_in</computeroutput> over subsequent calls
+to <computeroutput>BZ2_bzCompress</computeroutput>, the library
+can detect any attempts to slip in more data to compress. Any
+calls for which this is detected will return
+<computeroutput>BZ_SEQUENCE_ERROR</computeroutput>. This
+indicates a programming mistake which should be corrected.</para>
+
+<para>Instead of asking to finish, the calling program may ask
+<computeroutput>BZ2_bzCompress</computeroutput> to take all the
+remaining input, compress it and terminate the current
+(Burrows-Wheeler) compression block. This could be useful for
+error control purposes. The mechanism is analogous to that for
+finishing: call <computeroutput>BZ2_bzCompress</computeroutput>
+with an action of <computeroutput>BZ_FLUSH</computeroutput>,
+remove output data, and persist with the
+<computeroutput>BZ_FLUSH</computeroutput> action until the value
+<computeroutput>BZ_RUN</computeroutput> is returned. As with
+finishing, <computeroutput>BZ2_bzCompress</computeroutput>
+detects any attempt to provide more input data once the flush has
+begun.</para>
+
+<para>Once the flush is complete, the stream returns to the
+normal RUNNING state.</para>
+
+<para>This all sounds pretty complex, but isn't really. Here's a
+table which shows which actions are allowable in each state, what
+action will be taken, what the next state is, and what the
+non-error return values are. Note that you can't explicitly ask
+what state the stream is in, but nor do you need to -- it can be
+inferred from the values returned by
+<computeroutput>BZ2_bzCompress</computeroutput>.</para>
+
+<programlisting>
+IDLE/any
+ Illegal. IDLE state only exists after BZ2_bzCompressEnd or
+ before BZ2_bzCompressInit.
+ Return value = BZ_SEQUENCE_ERROR
+
+RUNNING/BZ_RUN
+ Compress from next_in to next_out as much as possible.
+ Next state = RUNNING
+ Return value = BZ_RUN_OK
+
+RUNNING/BZ_FLUSH
+ Remember current value of next_in. Compress from next_in
+ to next_out as much as possible, but do not accept any more input.
+ Next state = FLUSHING
+ Return value = BZ_FLUSH_OK
+
+RUNNING/BZ_FINISH
+ Remember current value of next_in. Compress from next_in
+ to next_out as much as possible, but do not accept any more input.
+ Next state = FINISHING
+ Return value = BZ_FINISH_OK
+
+FLUSHING/BZ_FLUSH
+ Compress from next_in to next_out as much as possible,
+ but do not accept any more input.
+ If all the existing input has been used up and all compressed
+ output has been removed
+ Next state = RUNNING; Return value = BZ_RUN_OK
+ else
+ Next state = FLUSHING; Return value = BZ_FLUSH_OK
+
+FLUSHING/other
+ Illegal.
+ Return value = BZ_SEQUENCE_ERROR
+
+FINISHING/BZ_FINISH
+ Compress from next_in to next_out as much as possible,
+ but to not accept any more input.
+ If all the existing input has been used up and all compressed
+ output has been removed
+ Next state = IDLE; Return value = BZ_STREAM_END
+ else
+ Next state = FINISHING; Return value = BZ_FINISH_OK
+
+FINISHING/other
+ Illegal.
+ Return value = BZ_SEQUENCE_ERROR
+</programlisting>
+
+
+<para>That still looks complicated? Well, fair enough. The
+usual sequence of calls for compressing a load of data is:</para>
+
+<orderedlist>
+
+ <listitem><para>Get started with
+ <computeroutput>BZ2_bzCompressInit</computeroutput>.</para></listitem>
+
+ <listitem><para>Shovel data in and shlurp out its compressed form
+ using zero or more calls of
+ <computeroutput>BZ2_bzCompress</computeroutput> with action =
+ <computeroutput>BZ_RUN</computeroutput>.</para></listitem>
+
+ <listitem><para>Finish up. Repeatedly call
+ <computeroutput>BZ2_bzCompress</computeroutput> with action =
+ <computeroutput>BZ_FINISH</computeroutput>, copying out the
+ compressed output, until
+ <computeroutput>BZ_STREAM_END</computeroutput> is
+ returned.</para></listitem> <listitem><para>Close up and go home. Call
+ <computeroutput>BZ2_bzCompressEnd</computeroutput>.</para></listitem>
+
+</orderedlist>
+
+<para>If the data you want to compress fits into your input
+buffer all at once, you can skip the calls of
+<computeroutput>BZ2_bzCompress ( ..., BZ_RUN )</computeroutput>
+and just do the <computeroutput>BZ2_bzCompress ( ..., BZ_FINISH
+)</computeroutput> calls.</para>
+
+<para>All required memory is allocated by
+<computeroutput>BZ2_bzCompressInit</computeroutput>. The
+compression library can accept any data at all (obviously). So
+you shouldn't get any error return values from the
+<computeroutput>BZ2_bzCompress</computeroutput> calls. If you
+do, they will be
+<computeroutput>BZ_SEQUENCE_ERROR</computeroutput>, and indicate
+a bug in your programming.</para>
+
+<para>Trivial other possible return values:</para>
+
+<programlisting>
+BZ_PARAM_ERROR
+ if strm is NULL, or strm->s is NULL
+</programlisting>
+
+</sect2>
+
+
+<sect2 id="bzCompress-end" xreflabel="BZ2_bzCompressEnd">
+<title><computeroutput>BZ2_bzCompressEnd</computeroutput></title>
+
+<programlisting>
+int BZ2_bzCompressEnd ( bz_stream *strm );
+</programlisting>
+
+<para>Releases all memory associated with a compression
+stream.</para>
+
+<para>Possible return values:</para>
+
+<programlisting>
+BZ_PARAM_ERROR if strm is NULL or strm->s is NULL
+BZ_OK otherwise
+</programlisting>
+
+</sect2>
+
+
+<sect2 id="bzDecompress-init" xreflabel="BZ2_bzDecompressInit">
+<title><computeroutput>BZ2_bzDecompressInit</computeroutput></title>
+
+<programlisting>
+int BZ2_bzDecompressInit ( bz_stream *strm, int verbosity, int small );
+</programlisting>
+
+<para>Prepares for decompression. As with
+<computeroutput>BZ2_bzCompressInit</computeroutput>, a
+<computeroutput>bz_stream</computeroutput> record should be
+allocated and initialised before the call. Fields
+<computeroutput>bzalloc</computeroutput>,
+<computeroutput>bzfree</computeroutput> and
+<computeroutput>opaque</computeroutput> should be set if a custom
+memory allocator is required, or made
+<computeroutput>NULL</computeroutput> for the normal
+<computeroutput>malloc</computeroutput> /
+<computeroutput>free</computeroutput> routines. Upon return, the
+internal state will have been initialised, and
+<computeroutput>total_in</computeroutput> and
+<computeroutput>total_out</computeroutput> will be zero.</para>
+
+<para>For the meaning of parameter
+<computeroutput>verbosity</computeroutput>, see
+<computeroutput>BZ2_bzCompressInit</computeroutput>.</para>
+
+<para>If <computeroutput>small</computeroutput> is nonzero, the
+library will use an alternative decompression algorithm which
+uses less memory but at the cost of decompressing more slowly
+(roughly speaking, half the speed, but the maximum memory
+requirement drops to around 2300k). See <xref linkend="using"/>
+for more information on memory management.</para>
+
+<para>Note that the amount of memory needed to decompress a
+stream cannot be determined until the stream's header has been
+read, so even if
+<computeroutput>BZ2_bzDecompressInit</computeroutput> succeeds, a
+subsequent <computeroutput>BZ2_bzDecompress</computeroutput>
+could fail with
+<computeroutput>BZ_MEM_ERROR</computeroutput>.</para>
+
+<para>Possible return values:</para>
+
+<programlisting>
+BZ_CONFIG_ERROR
+ if the library has been mis-compiled
+BZ_PARAM_ERROR
+ if ( small != 0 && small != 1 )
+ or (verbosity <; 0 || verbosity > 4)
+BZ_MEM_ERROR
+ if insufficient memory is available
+</programlisting>
+
+<para>Allowable next actions:</para>
+
+<programlisting>
+BZ2_bzDecompress
+ if BZ_OK was returned
+ no specific action required in case of error
+</programlisting>
+
+</sect2>
+
+
+<sect2 id="bzDecompress" xreflabel="BZ2_bzDecompress">
+<title><computeroutput>BZ2_bzDecompress</computeroutput></title>
+
+<programlisting>
+int BZ2_bzDecompress ( bz_stream *strm );
+</programlisting>
+
+<para>Provides more input and/out output buffer space for the
+library. The caller maintains input and output buffers, and uses
+<computeroutput>BZ2_bzDecompress</computeroutput> to transfer
+data between them.</para>
+
+<para>Before each call to
+<computeroutput>BZ2_bzDecompress</computeroutput>,
+<computeroutput>next_in</computeroutput> should point at the
+compressed data, and <computeroutput>avail_in</computeroutput>
+should indicate how many bytes the library may read.
+<computeroutput>BZ2_bzDecompress</computeroutput> updates
+<computeroutput>next_in</computeroutput>,
+<computeroutput>avail_in</computeroutput> and
+<computeroutput>total_in</computeroutput> to reflect the number
+of bytes it has read.</para>
+
+<para>Similarly, <computeroutput>next_out</computeroutput> should
+point to a buffer in which the uncompressed output is to be
+placed, with <computeroutput>avail_out</computeroutput>
+indicating how much output space is available.
+<computeroutput>BZ2_bzCompress</computeroutput> updates
+<computeroutput>next_out</computeroutput>,
+<computeroutput>avail_out</computeroutput> and
+<computeroutput>total_out</computeroutput> to reflect the number
+of bytes output.</para>
+
+<para>You may provide and remove as little or as much data as you
+like on each call of
+<computeroutput>BZ2_bzDecompress</computeroutput>. In the limit,
+it is acceptable to supply and remove data one byte at a time,
+although this would be terribly inefficient. You should always
+ensure that at least one byte of output space is available at
+each call.</para>
+
+<para>Use of <computeroutput>BZ2_bzDecompress</computeroutput> is
+simpler than
+<computeroutput>BZ2_bzCompress</computeroutput>.</para>
+
+<para>You should provide input and remove output as described
+above, and repeatedly call
+<computeroutput>BZ2_bzDecompress</computeroutput> until
+<computeroutput>BZ_STREAM_END</computeroutput> is returned.
+Appearance of <computeroutput>BZ_STREAM_END</computeroutput>
+denotes that <computeroutput>BZ2_bzDecompress</computeroutput>
+has detected the logical end of the compressed stream.
+<computeroutput>BZ2_bzDecompress</computeroutput> will not
+produce <computeroutput>BZ_STREAM_END</computeroutput> until all
+output data has been placed into the output buffer, so once
+<computeroutput>BZ_STREAM_END</computeroutput> appears, you are
+guaranteed to have available all the decompressed output, and
+<computeroutput>BZ2_bzDecompressEnd</computeroutput> can safely
+be called.</para>
+
+<para>If case of an error return value, you should call
+<computeroutput>BZ2_bzDecompressEnd</computeroutput> to clean up
+and release memory.</para>
+
+<para>Possible return values:</para>
+
+<programlisting>
+BZ_PARAM_ERROR
+ if strm is NULL or strm->s is NULL
+ or strm->avail_out < 1
+BZ_DATA_ERROR
+ if a data integrity error is detected in the compressed stream
+BZ_DATA_ERROR_MAGIC
+ if the compressed stream doesn't begin with the right magic bytes
+BZ_MEM_ERROR
+ if there wasn't enough memory available
+BZ_STREAM_END
+ if the logical end of the data stream was detected and all
+ output in has been consumed, eg s-->avail_out > 0
+BZ_OK
+ otherwise
+</programlisting>
+
+<para>Allowable next actions:</para>
+
+<programlisting>
+BZ2_bzDecompress
+ if BZ_OK was returned
+BZ2_bzDecompressEnd
+ otherwise
+</programlisting>
+
+</sect2>
+
+
+<sect2 id="bzDecompress-end" xreflabel="BZ2_bzDecompressEnd">
+<title><computeroutput>BZ2_bzDecompressEnd</computeroutput></title>
+
+<programlisting>
+int BZ2_bzDecompressEnd ( bz_stream *strm );
+</programlisting>
+
+<para>Releases all memory associated with a decompression
+stream.</para>
+
+<para>Possible return values:</para>
+
+<programlisting>
+BZ_PARAM_ERROR
+ if strm is NULL or strm->s is NULL
+BZ_OK
+ otherwise
+</programlisting>
+
+<para>Allowable next actions:</para>
+
+<programlisting>
+ None.
+</programlisting>
+
+</sect2>
+
+</sect1>
+
+
+<sect1 id="hl-interface" xreflabel="High-level interface">
+<title>High-level interface</title>
+
+<para>This interface provides functions for reading and writing
+<computeroutput>bzip2</computeroutput> format files. First, some
+general points.</para>
+
+<itemizedlist mark='bullet'>
+
+ <listitem><para>All of the functions take an
+ <computeroutput>int*</computeroutput> first argument,
+ <computeroutput>bzerror</computeroutput>. After each call,
+ <computeroutput>bzerror</computeroutput> should be consulted
+ first to determine the outcome of the call. If
+ <computeroutput>bzerror</computeroutput> is
+ <computeroutput>BZ_OK</computeroutput>, the call completed
+ successfully, and only then should the return value of the
+ function (if any) be consulted. If
+ <computeroutput>bzerror</computeroutput> is
+ <computeroutput>BZ_IO_ERROR</computeroutput>, there was an
+ error reading/writing the underlying compressed file, and you
+ should then consult <computeroutput>errno</computeroutput> /
+ <computeroutput>perror</computeroutput> to determine the cause
+ of the difficulty. <computeroutput>bzerror</computeroutput>
+ may also be set to various other values; precise details are
+ given on a per-function basis below.</para></listitem>
+
+ <listitem><para>If <computeroutput>bzerror</computeroutput> indicates
+ an error (ie, anything except
+ <computeroutput>BZ_OK</computeroutput> and
+ <computeroutput>BZ_STREAM_END</computeroutput>), you should
+ immediately call
+ <computeroutput>BZ2_bzReadClose</computeroutput> (or
+ <computeroutput>BZ2_bzWriteClose</computeroutput>, depending on
+ whether you are attempting to read or to write) to free up all
+ resources associated with the stream. Once an error has been
+ indicated, behaviour of all calls except
+ <computeroutput>BZ2_bzReadClose</computeroutput>
+ (<computeroutput>BZ2_bzWriteClose</computeroutput>) is
+ undefined. The implication is that (1)
+ <computeroutput>bzerror</computeroutput> should be checked
+ after each call, and (2) if
+ <computeroutput>bzerror</computeroutput> indicates an error,
+ <computeroutput>BZ2_bzReadClose</computeroutput>
+ (<computeroutput>BZ2_bzWriteClose</computeroutput>) should then
+ be called to clean up.</para></listitem>
+
+ <listitem><para>The <computeroutput>FILE*</computeroutput> arguments
+ passed to <computeroutput>BZ2_bzReadOpen</computeroutput> /
+ <computeroutput>BZ2_bzWriteOpen</computeroutput> should be set
+ to binary mode. Most Unix systems will do this by default, but
+ other platforms, including Windows and Mac, will not. If you
+ omit this, you may encounter problems when moving code to new
+ platforms.</para></listitem>
+
+ <listitem><para>Memory allocation requests are handled by
+ <computeroutput>malloc</computeroutput> /
+ <computeroutput>free</computeroutput>. At present there is no
+ facility for user-defined memory allocators in the file I/O
+ functions (could easily be added, though).</para></listitem>
+
+</itemizedlist>
+
+
+
+<sect2 id="bzreadopen" xreflabel="BZ2_bzReadOpen">
+<title><computeroutput>BZ2_bzReadOpen</computeroutput></title>
+
+<programlisting>
+typedef void BZFILE;
+
+BZFILE *BZ2_bzReadOpen( int *bzerror, FILE *f,
+ int verbosity, int small,
+ void *unused, int nUnused );
+</programlisting>
+
+<para>Prepare to read compressed data from file handle
+<computeroutput>f</computeroutput>.
+<computeroutput>f</computeroutput> should refer to a file which
+has been opened for reading, and for which the error indicator
+(<computeroutput>ferror(f)</computeroutput>)is not set. If
+<computeroutput>small</computeroutput> is 1, the library will try
+to decompress using less memory, at the expense of speed.</para>
+
+<para>For reasons explained below,
+<computeroutput>BZ2_bzRead</computeroutput> will decompress the
+<computeroutput>nUnused</computeroutput> bytes starting at
+<computeroutput>unused</computeroutput>, before starting to read
+from the file <computeroutput>f</computeroutput>. At most
+<computeroutput>BZ_MAX_UNUSED</computeroutput> bytes may be
+supplied like this. If this facility is not required, you should
+pass <computeroutput>NULL</computeroutput> and
+<computeroutput>0</computeroutput> for
+<computeroutput>unused</computeroutput> and
+n<computeroutput>Unused</computeroutput> respectively.</para>
+
+<para>For the meaning of parameters
+<computeroutput>small</computeroutput> and
+<computeroutput>verbosity</computeroutput>, see
+<computeroutput>BZ2_bzDecompressInit</computeroutput>.</para>
+
+<para>The amount of memory needed to decompress a file cannot be
+determined until the file's header has been read. So it is
+possible that <computeroutput>BZ2_bzReadOpen</computeroutput>
+returns <computeroutput>BZ_OK</computeroutput> but a subsequent
+call of <computeroutput>BZ2_bzRead</computeroutput> will return
+<computeroutput>BZ_MEM_ERROR</computeroutput>.</para>
+
+<para>Possible assignments to
+<computeroutput>bzerror</computeroutput>:</para>
+
+<programlisting>
+BZ_CONFIG_ERROR
+ if the library has been mis-compiled
+BZ_PARAM_ERROR
+ if f is NULL
+ or small is neither 0 nor 1
+ or ( unused == NULL && nUnused != 0 )
+ or ( unused != NULL && !(0 <= nUnused <= BZ_MAX_UNUSED) )
+BZ_IO_ERROR
+ if ferror(f) is nonzero
+BZ_MEM_ERROR
+ if insufficient memory is available
+BZ_OK
+ otherwise.
+</programlisting>
+
+<para>Possible return values:</para>
+
+<programlisting>
+Pointer to an abstract BZFILE
+ if bzerror is BZ_OK
+NULL
+ otherwise
+</programlisting>
+
+<para>Allowable next actions:</para>
+
+<programlisting>
+BZ2_bzRead
+ if bzerror is BZ_OK
+BZ2_bzClose
+ otherwise
+</programlisting>
+
+</sect2>
+
+
+<sect2 id="bzread" xreflabel="BZ2_bzRead">
+<title><computeroutput>BZ2_bzRead</computeroutput></title>
+
+<programlisting>
+int BZ2_bzRead ( int *bzerror, BZFILE *b, void *buf, int len );
+</programlisting>
+
+<para>Reads up to <computeroutput>len</computeroutput>
+(uncompressed) bytes from the compressed file
+<computeroutput>b</computeroutput> into the buffer
+<computeroutput>buf</computeroutput>. If the read was
+successful, <computeroutput>bzerror</computeroutput> is set to
+<computeroutput>BZ_OK</computeroutput> and the number of bytes
+read is returned. If the logical end-of-stream was detected,
+<computeroutput>bzerror</computeroutput> will be set to
+<computeroutput>BZ_STREAM_END</computeroutput>, and the number of
+bytes read is returned. All other
+<computeroutput>bzerror</computeroutput> values denote an
+error.</para>
+
+<para><computeroutput>BZ2_bzRead</computeroutput> will supply
+<computeroutput>len</computeroutput> bytes, unless the logical
+stream end is detected or an error occurs. Because of this, it
+is possible to detect the stream end by observing when the number
+of bytes returned is less than the number requested.
+Nevertheless, this is regarded as inadvisable; you should instead
+check <computeroutput>bzerror</computeroutput> after every call
+and watch out for
+<computeroutput>BZ_STREAM_END</computeroutput>.</para>
+
+<para>Internally, <computeroutput>BZ2_bzRead</computeroutput>
+copies data from the compressed file in chunks of size
+<computeroutput>BZ_MAX_UNUSED</computeroutput> bytes before
+decompressing it. If the file contains more bytes than strictly
+needed to reach the logical end-of-stream,
+<computeroutput>BZ2_bzRead</computeroutput> will almost certainly
+read some of the trailing data before signalling
+<computeroutput>BZ_SEQUENCE_END</computeroutput>. To collect the
+read but unused data once
+<computeroutput>BZ_SEQUENCE_END</computeroutput> has appeared,
+call <computeroutput>BZ2_bzReadGetUnused</computeroutput>
+immediately before
+<computeroutput>BZ2_bzReadClose</computeroutput>.</para>
+
+<para>Possible assignments to
+<computeroutput>bzerror</computeroutput>:</para>
+
+<programlisting>
+BZ_PARAM_ERROR
+ if b is NULL or buf is NULL or len < 0
+BZ_SEQUENCE_ERROR
+ if b was opened with BZ2_bzWriteOpen
+BZ_IO_ERROR
+ if there is an error reading from the compressed file
+BZ_UNEXPECTED_EOF
+ if the compressed file ended before
+ the logical end-of-stream was detected
+BZ_DATA_ERROR
+ if a data integrity error was detected in the compressed stream
+BZ_DATA_ERROR_MAGIC
+ if the stream does not begin with the requisite header bytes
+ (ie, is not a bzip2 data file). This is really
+ a special case of BZ_DATA_ERROR.
+BZ_MEM_ERROR
+ if insufficient memory was available
+BZ_STREAM_END
+ if the logical end of stream was detected.
+BZ_OK
+ otherwise.
+</programlisting>
+
+<para>Possible return values:</para>
+
+<programlisting>
+number of bytes read
+ if bzerror is BZ_OK or BZ_STREAM_END
+undefined
+ otherwise
+</programlisting>
+
+<para>Allowable next actions:</para>
+
+<programlisting>
+collect data from buf, then BZ2_bzRead or BZ2_bzReadClose
+ if bzerror is BZ_OK
+collect data from buf, then BZ2_bzReadClose or BZ2_bzReadGetUnused
+ if bzerror is BZ_SEQUENCE_END
+BZ2_bzReadClose
+ otherwise
+</programlisting>
+
+</sect2>
+
+
+<sect2 id="bzreadgetunused" xreflabel="BZ2_bzReadGetUnused">
+<title><computeroutput>BZ2_bzReadGetUnused</computeroutput></title>
+
+<programlisting>
+void BZ2_bzReadGetUnused( int* bzerror, BZFILE *b,
+ void** unused, int* nUnused );
+</programlisting>
+
+<para>Returns data which was read from the compressed file but
+was not needed to get to the logical end-of-stream.
+<computeroutput>*unused</computeroutput> is set to the address of
+the data, and <computeroutput>*nUnused</computeroutput> to the
+number of bytes. <computeroutput>*nUnused</computeroutput> will
+be set to a value between <computeroutput>0</computeroutput> and
+<computeroutput>BZ_MAX_UNUSED</computeroutput> inclusive.</para>
+
+<para>This function may only be called once
+<computeroutput>BZ2_bzRead</computeroutput> has signalled
+<computeroutput>BZ_STREAM_END</computeroutput> but before
+<computeroutput>BZ2_bzReadClose</computeroutput>.</para>
+
+<para>Possible assignments to
+<computeroutput>bzerror</computeroutput>:</para>
+
+<programlisting>
+BZ_PARAM_ERROR
+ if b is NULL
+ or unused is NULL or nUnused is NULL
+BZ_SEQUENCE_ERROR
+ if BZ_STREAM_END has not been signalled
+ or if b was opened with BZ2_bzWriteOpen
+BZ_OK
+ otherwise
+</programlisting>
+
+<para>Allowable next actions:</para>
+
+<programlisting>
+BZ2_bzReadClose
+</programlisting>
+
+</sect2>
+
+
+<sect2 id="bzreadclose" xreflabel="BZ2_bzReadClose">
+<title><computeroutput>BZ2_bzReadClose</computeroutput></title>
+
+<programlisting>
+void BZ2_bzReadClose ( int *bzerror, BZFILE *b );
+</programlisting>
+
+<para>Releases all memory pertaining to the compressed file
+<computeroutput>b</computeroutput>.
+<computeroutput>BZ2_bzReadClose</computeroutput> does not call
+<computeroutput>fclose</computeroutput> on the underlying file
+handle, so you should do that yourself if appropriate.
+<computeroutput>BZ2_bzReadClose</computeroutput> should be called
+to clean up after all error situations.</para>
+
+<para>Possible assignments to
+<computeroutput>bzerror</computeroutput>:</para>
+
+<programlisting>
+BZ_SEQUENCE_ERROR
+ if b was opened with BZ2_bzOpenWrite
+BZ_OK
+ otherwise
+</programlisting>
+
+<para>Allowable next actions:</para>
+
+<programlisting>
+none
+</programlisting>
+
+</sect2>
+
+
+<sect2 id="bzwriteopen" xreflabel="BZ2_bzWriteOpen">
+<title><computeroutput>BZ2_bzWriteOpen</computeroutput></title>
+
+<programlisting>
+BZFILE *BZ2_bzWriteOpen( int *bzerror, FILE *f,
+ int blockSize100k, int verbosity,
+ int workFactor );
+</programlisting>
+
+<para>Prepare to write compressed data to file handle
+<computeroutput>f</computeroutput>.
+<computeroutput>f</computeroutput> should refer to a file which
+has been opened for writing, and for which the error indicator
+(<computeroutput>ferror(f)</computeroutput>)is not set.</para>
+
+<para>For the meaning of parameters
+<computeroutput>blockSize100k</computeroutput>,
+<computeroutput>verbosity</computeroutput> and
+<computeroutput>workFactor</computeroutput>, see
+<computeroutput>BZ2_bzCompressInit</computeroutput>.</para>
+
+<para>All required memory is allocated at this stage, so if the
+call completes successfully,
+<computeroutput>BZ_MEM_ERROR</computeroutput> cannot be signalled
+by a subsequent call to
+<computeroutput>BZ2_bzWrite</computeroutput>.</para>
+
+<para>Possible assignments to
+<computeroutput>bzerror</computeroutput>:</para>
+
+<programlisting>
+BZ_CONFIG_ERROR
+ if the library has been mis-compiled
+BZ_PARAM_ERROR
+ if f is NULL
+ or blockSize100k < 1 or blockSize100k > 9
+BZ_IO_ERROR
+ if ferror(f) is nonzero
+BZ_MEM_ERROR
+ if insufficient memory is available
+BZ_OK
+ otherwise
+</programlisting>
+
+<para>Possible return values:</para>
+
+<programlisting>
+Pointer to an abstract BZFILE
+ if bzerror is BZ_OK
+NULL
+ otherwise
+</programlisting>
+
+<para>Allowable next actions:</para>
+
+<programlisting>
+BZ2_bzWrite
+ if bzerror is BZ_OK
+ (you could go directly to BZ2_bzWriteClose, but this would be pretty pointless)
+BZ2_bzWriteClose
+ otherwise
+</programlisting>
+
+</sect2>
+
+
+<sect2 id="bzwrite" xreflabel="BZ2_bzWrite">
+<title><computeroutput>BZ2_bzWrite</computeroutput></title>
+
+<programlisting>
+void BZ2_bzWrite ( int *bzerror, BZFILE *b, void *buf, int len );
+</programlisting>
+
+<para>Absorbs <computeroutput>len</computeroutput> bytes from the
+buffer <computeroutput>buf</computeroutput>, eventually to be
+compressed and written to the file.</para>
+
+<para>Possible assignments to
+<computeroutput>bzerror</computeroutput>:</para>
+
+<programlisting>
+BZ_PARAM_ERROR
+ if b is NULL or buf is NULL or len < 0
+BZ_SEQUENCE_ERROR
+ if b was opened with BZ2_bzReadOpen
+BZ_IO_ERROR
+ if there is an error writing the compressed file.
+BZ_OK
+ otherwise
+</programlisting>
+
+</sect2>
+
+
+<sect2 id="bzwriteclose" xreflabel="BZ2_bzWriteClose">
+<title><computeroutput>BZ2_bzWriteClose</computeroutput></title>
+
+<programlisting>
+void BZ2_bzWriteClose( int *bzerror, BZFILE* f,
+ int abandon,
+ unsigned int* nbytes_in,
+ unsigned int* nbytes_out );
+
+void BZ2_bzWriteClose64( int *bzerror, BZFILE* f,
+ int abandon,
+ unsigned int* nbytes_in_lo32,
+ unsigned int* nbytes_in_hi32,
+ unsigned int* nbytes_out_lo32,
+ unsigned int* nbytes_out_hi32 );
+</programlisting>
+
+<para>Compresses and flushes to the compressed file all data so
+far supplied by <computeroutput>BZ2_bzWrite</computeroutput>.
+The logical end-of-stream markers are also written, so subsequent
+calls to <computeroutput>BZ2_bzWrite</computeroutput> are
+illegal. All memory associated with the compressed file
+<computeroutput>b</computeroutput> is released.
+<computeroutput>fflush</computeroutput> is called on the
+compressed file, but it is not
+<computeroutput>fclose</computeroutput>'d.</para>
+
+<para>If <computeroutput>BZ2_bzWriteClose</computeroutput> is
+called to clean up after an error, the only action is to release
+the memory. The library records the error codes issued by
+previous calls, so this situation will be detected automatically.
+There is no attempt to complete the compression operation, nor to
+<computeroutput>fflush</computeroutput> the compressed file. You
+can force this behaviour to happen even in the case of no error,
+by passing a nonzero value to
+<computeroutput>abandon</computeroutput>.</para>
+
+<para>If <computeroutput>nbytes_in</computeroutput> is non-null,
+<computeroutput>*nbytes_in</computeroutput> will be set to be the
+total volume of uncompressed data handled. Similarly,
+<computeroutput>nbytes_out</computeroutput> will be set to the
+total volume of compressed data written. For compatibility with
+older versions of the library,
+<computeroutput>BZ2_bzWriteClose</computeroutput> only yields the
+lower 32 bits of these counts. Use
+<computeroutput>BZ2_bzWriteClose64</computeroutput> if you want
+the full 64 bit counts. These two functions are otherwise
+absolutely identical.</para>
+
+<para>Possible assignments to
+<computeroutput>bzerror</computeroutput>:</para>
+
+<programlisting>
+BZ_SEQUENCE_ERROR
+ if b was opened with BZ2_bzReadOpen
+BZ_IO_ERROR
+ if there is an error writing the compressed file
+BZ_OK
+ otherwise
+</programlisting>
+
+</sect2>
+
+
+<sect2 id="embed" xreflabel="Handling embedded compressed data streams">
+<title>Handling embedded compressed data streams</title>
+
+<para>The high-level library facilitates use of
+<computeroutput>bzip2</computeroutput> data streams which form
+some part of a surrounding, larger data stream.</para>
+
+<itemizedlist mark='bullet'>
+
+ <listitem><para>For writing, the library takes an open file handle,
+ writes compressed data to it,
+ <computeroutput>fflush</computeroutput>es it but does not
+ <computeroutput>fclose</computeroutput> it. The calling
+ application can write its own data before and after the
+ compressed data stream, using that same file handle.</para></listitem>
+
+ <listitem><para>Reading is more complex, and the facilities are not as
+ general as they could be since generality is hard to reconcile
+ with efficiency. <computeroutput>BZ2_bzRead</computeroutput>
+ reads from the compressed file in blocks of size
+ <computeroutput>BZ_MAX_UNUSED</computeroutput> bytes, and in
+ doing so probably will overshoot the logical end of compressed
+ stream. To recover this data once decompression has ended,
+ call <computeroutput>BZ2_bzReadGetUnused</computeroutput> after
+ the last call of <computeroutput>BZ2_bzRead</computeroutput>
+ (the one returning
+ <computeroutput>BZ_STREAM_END</computeroutput>) but before
+ calling
+ <computeroutput>BZ2_bzReadClose</computeroutput>.</para></listitem>
+
+</itemizedlist>
+
+<para>This mechanism makes it easy to decompress multiple
+<computeroutput>bzip2</computeroutput> streams placed end-to-end.
+As the end of one stream, when
+<computeroutput>BZ2_bzRead</computeroutput> returns
+<computeroutput>BZ_STREAM_END</computeroutput>, call
+<computeroutput>BZ2_bzReadGetUnused</computeroutput> to collect
+the unused data (copy it into your own buffer somewhere). That
+data forms the start of the next compressed stream. To start
+uncompressing that next stream, call
+<computeroutput>BZ2_bzReadOpen</computeroutput> again, feeding in
+the unused data via the <computeroutput>unused</computeroutput> /
+<computeroutput>nUnused</computeroutput> parameters. Keep doing
+this until <computeroutput>BZ_STREAM_END</computeroutput> return
+coincides with the physical end of file
+(<computeroutput>feof(f)</computeroutput>). In this situation
+<computeroutput>BZ2_bzReadGetUnused</computeroutput> will of
+course return no data.</para>
+
+<para>This should give some feel for how the high-level interface
+can be used. If you require extra flexibility, you'll have to
+bite the bullet and get to grips with the low-level
+interface.</para>
+
+</sect2>
+
+
+<sect2 id="std-rdwr" xreflabel="Standard file-reading/writing code">
+<title>Standard file-reading/writing code</title>
+
+<para>Here's how you'd write data to a compressed file:</para>
+
+<programlisting>
+FILE* f;
+BZFILE* b;
+int nBuf;
+char buf[ /* whatever size you like */ ];
+int bzerror;
+int nWritten;
+
+f = fopen ( "myfile.bz2", "w" );
+if ( !f ) {
+ /* handle error */
+}
+b = BZ2_bzWriteOpen( &bzerror, f, 9 );
+if (bzerror != BZ_OK) {
+ BZ2_bzWriteClose ( b );
+ /* handle error */
+}
+
+while ( /* condition */ ) {
+ /* get data to write into buf, and set nBuf appropriately */
+ nWritten = BZ2_bzWrite ( &bzerror, b, buf, nBuf );
+ if (bzerror == BZ_IO_ERROR) {
+ BZ2_bzWriteClose ( &bzerror, b );
+ /* handle error */
+ }
+}
+
+BZ2_bzWriteClose( &bzerror, b );
+if (bzerror == BZ_IO_ERROR) {
+ /* handle error */
+}
+</programlisting>
+
+<para>And to read from a compressed file:</para>
+
+<programlisting>
+FILE* f;
+BZFILE* b;
+int nBuf;
+char buf[ /* whatever size you like */ ];
+int bzerror;
+int nWritten;
+
+f = fopen ( "myfile.bz2", "r" );
+if ( !f ) {
+ /* handle error */
+}
+b = BZ2_bzReadOpen ( &bzerror, f, 0, NULL, 0 );
+if ( bzerror != BZ_OK ) {
+ BZ2_bzReadClose ( &bzerror, b );
+ /* handle error */
+}
+
+bzerror = BZ_OK;
+while ( bzerror == BZ_OK && /* arbitrary other conditions */) {
+ nBuf = BZ2_bzRead ( &bzerror, b, buf, /* size of buf */ );
+ if ( bzerror == BZ_OK ) {
+ /* do something with buf[0 .. nBuf-1] */
+ }
+}
+if ( bzerror != BZ_STREAM_END ) {
+ BZ2_bzReadClose ( &bzerror, b );
+ /* handle error */
+} else {
+ BZ2_bzReadClose ( &bzerror, b );
+}
+</programlisting>
+
+</sect2>
+
+</sect1>
+
+
+<sect1 id="util-fns" xreflabel="Utility functions">
+<title>Utility functions</title>
+
+
+<sect2 id="bzbufftobuffcompress" xreflabel="BZ2_bzBuffToBuffCompress">
+<title><computeroutput>BZ2_bzBuffToBuffCompress</computeroutput></title>
+
+<programlisting>
+int BZ2_bzBuffToBuffCompress( char* dest,
+ unsigned int* destLen,
+ char* source,
+ unsigned int sourceLen,
+ int blockSize100k,
+ int verbosity,
+ int workFactor );
+</programlisting>
+
+<para>Attempts to compress the data in <computeroutput>source[0
+.. sourceLen-1]</computeroutput> into the destination buffer,
+<computeroutput>dest[0 .. *destLen-1]</computeroutput>. If the
+destination buffer is big enough,
+<computeroutput>*destLen</computeroutput> is set to the size of
+the compressed data, and <computeroutput>BZ_OK</computeroutput>
+is returned. If the compressed data won't fit,
+<computeroutput>*destLen</computeroutput> is unchanged, and
+<computeroutput>BZ_OUTBUFF_FULL</computeroutput> is
+returned.</para>
+
+<para>Compression in this manner is a one-shot event, done with a
+single call to this function. The resulting compressed data is a
+complete <computeroutput>bzip2</computeroutput> format data
+stream. There is no mechanism for making additional calls to
+provide extra input data. If you want that kind of mechanism,
+use the low-level interface.</para>
+
+<para>For the meaning of parameters
+<computeroutput>blockSize100k</computeroutput>,
+<computeroutput>verbosity</computeroutput> and
+<computeroutput>workFactor</computeroutput>, see
+<computeroutput>BZ2_bzCompressInit</computeroutput>.</para>
+
+<para>To guarantee that the compressed data will fit in its
+buffer, allocate an output buffer of size 1% larger than the
+uncompressed data, plus six hundred extra bytes.</para>
+
+<para><computeroutput>BZ2_bzBuffToBuffDecompress</computeroutput>
+will not write data at or beyond
+<computeroutput>dest[*destLen]</computeroutput>, even in case of
+buffer overflow.</para>
+
+<para>Possible return values:</para>
+
+<programlisting>
+BZ_CONFIG_ERROR
+ if the library has been mis-compiled
+BZ_PARAM_ERROR
+ if dest is NULL or destLen is NULL
+ or blockSize100k < 1 or blockSize100k > 9
+ or verbosity < 0 or verbosity > 4
+ or workFactor < 0 or workFactor > 250
+BZ_MEM_ERROR
+ if insufficient memory is available
+BZ_OUTBUFF_FULL
+ if the size of the compressed data exceeds *destLen
+BZ_OK
+ otherwise
+</programlisting>
+
+</sect2>
+
+
+<sect2 id="bzbufftobuffdecompress" xreflabel="BZ2_bzBuffToBuffDecompress">
+<title><computeroutput>BZ2_bzBuffToBuffDecompress</computeroutput></title>
+
+<programlisting>
+int BZ2_bzBuffToBuffDecompress( char* dest,
+ unsigned int* destLen,
+ char* source,
+ unsigned int sourceLen,
+ int small,
+ int verbosity );
+</programlisting>
+
+<para>Attempts to decompress the data in <computeroutput>source[0
+.. sourceLen-1]</computeroutput> into the destination buffer,
+<computeroutput>dest[0 .. *destLen-1]</computeroutput>. If the
+destination buffer is big enough,
+<computeroutput>*destLen</computeroutput> is set to the size of
+the uncompressed data, and <computeroutput>BZ_OK</computeroutput>
+is returned. If the compressed data won't fit,
+<computeroutput>*destLen</computeroutput> is unchanged, and
+<computeroutput>BZ_OUTBUFF_FULL</computeroutput> is
+returned.</para>
+
+<para><computeroutput>source</computeroutput> is assumed to hold
+a complete <computeroutput>bzip2</computeroutput> format data
+stream.
+<computeroutput>BZ2_bzBuffToBuffDecompress</computeroutput> tries
+to decompress the entirety of the stream into the output
+buffer.</para>
+
+<para>For the meaning of parameters
+<computeroutput>small</computeroutput> and
+<computeroutput>verbosity</computeroutput>, see
+<computeroutput>BZ2_bzDecompressInit</computeroutput>.</para>
+
+<para>Because the compression ratio of the compressed data cannot
+be known in advance, there is no easy way to guarantee that the
+output buffer will be big enough. You may of course make
+arrangements in your code to record the size of the uncompressed
+data, but such a mechanism is beyond the scope of this
+library.</para>
+
+<para><computeroutput>BZ2_bzBuffToBuffDecompress</computeroutput>
+will not write data at or beyond
+<computeroutput>dest[*destLen]</computeroutput>, even in case of
+buffer overflow.</para>
+
+<para>Possible return values:</para>
+
+<programlisting>
+BZ_CONFIG_ERROR
+ if the library has been mis-compiled
+BZ_PARAM_ERROR
+ if dest is NULL or destLen is NULL
+ or small != 0 && small != 1
+ or verbosity < 0 or verbosity > 4
+BZ_MEM_ERROR
+ if insufficient memory is available
+BZ_OUTBUFF_FULL
+ if the size of the compressed data exceeds *destLen
+BZ_DATA_ERROR
+ if a data integrity error was detected in the compressed data
+BZ_DATA_ERROR_MAGIC
+ if the compressed data doesn't begin with the right magic bytes
+BZ_UNEXPECTED_EOF
+ if the compressed data ends unexpectedly
+BZ_OK
+ otherwise
+</programlisting>
+
+</sect2>
+
+</sect1>
+
+
+<sect1 id="zlib-compat" xreflabel="zlib compatibility functions">
+<title><computeroutput>zlib</computeroutput> compatibility functions</title>
+
+<para>Yoshioka Tsuneo has contributed some functions to give
+better <computeroutput>zlib</computeroutput> compatibility.
+These functions are <computeroutput>BZ2_bzopen</computeroutput>,
+<computeroutput>BZ2_bzread</computeroutput>,
+<computeroutput>BZ2_bzwrite</computeroutput>,
+<computeroutput>BZ2_bzflush</computeroutput>,
+<computeroutput>BZ2_bzclose</computeroutput>,
+<computeroutput>BZ2_bzerror</computeroutput> and
+<computeroutput>BZ2_bzlibVersion</computeroutput>. These
+functions are not (yet) officially part of the library. If they
+break, you get to keep all the pieces. Nevertheless, I think
+they work ok.</para>
+
+<programlisting>
+typedef void BZFILE;
+
+const char * BZ2_bzlibVersion ( void );
+</programlisting>
+
+<para>Returns a string indicating the library version.</para>
+
+<programlisting>
+BZFILE * BZ2_bzopen ( const char *path, const char *mode );
+BZFILE * BZ2_bzdopen ( int fd, const char *mode );
+</programlisting>
+
+<para>Opens a <computeroutput>.bz2</computeroutput> file for
+reading or writing, using either its name or a pre-existing file
+descriptor. Analogous to <computeroutput>fopen</computeroutput>
+and <computeroutput>fdopen</computeroutput>.</para>
+
+<programlisting>
+int BZ2_bzread ( BZFILE* b, void* buf, int len );
+int BZ2_bzwrite ( BZFILE* b, void* buf, int len );
+</programlisting>
+
+<para>Reads/writes data from/to a previously opened
+<computeroutput>BZFILE</computeroutput>. Analogous to
+<computeroutput>fread</computeroutput> and
+<computeroutput>fwrite</computeroutput>.</para>
+
+<programlisting>
+int BZ2_bzflush ( BZFILE* b );
+void BZ2_bzclose ( BZFILE* b );
+</programlisting>
+
+<para>Flushes/closes a <computeroutput>BZFILE</computeroutput>.
+<computeroutput>BZ2_bzflush</computeroutput> doesn't actually do
+anything. Analogous to <computeroutput>fflush</computeroutput>
+and <computeroutput>fclose</computeroutput>.</para>
+
+<programlisting>
+const char * BZ2_bzerror ( BZFILE *b, int *errnum )
+</programlisting>
+
+<para>Returns a string describing the more recent error status of
+<computeroutput>b</computeroutput>, and also sets
+<computeroutput>*errnum</computeroutput> to its numerical
+value.</para>
+
+</sect1>
+
+
+<sect1 id="stdio-free"
+ xreflabel="Using the library in a stdio-free environment">
+<title>Using the library in a <computeroutput>stdio</computeroutput>-free environment</title>
+
+
+<sect2 id="stdio-bye" xreflabel="Getting rid of stdio">
+<title>Getting rid of <computeroutput>stdio</computeroutput></title>
+
+<para>In a deeply embedded application, you might want to use
+just the memory-to-memory functions. You can do this
+conveniently by compiling the library with preprocessor symbol
+<computeroutput>BZ_NO_STDIO</computeroutput> defined. Doing this
+gives you a library containing only the following eight
+functions:</para>
+
+<para><computeroutput>BZ2_bzCompressInit</computeroutput>,
+<computeroutput>BZ2_bzCompress</computeroutput>,
+<computeroutput>BZ2_bzCompressEnd</computeroutput>
+<computeroutput>BZ2_bzDecompressInit</computeroutput>,
+<computeroutput>BZ2_bzDecompress</computeroutput>,
+<computeroutput>BZ2_bzDecompressEnd</computeroutput>
+<computeroutput>BZ2_bzBuffToBuffCompress</computeroutput>,
+<computeroutput>BZ2_bzBuffToBuffDecompress</computeroutput></para>
+
+<para>When compiled like this, all functions will ignore
+<computeroutput>verbosity</computeroutput> settings.</para>
+
+</sect2>
+
+
+<sect2 id="critical-error" xreflabel="Critical error handling">
+<title>Critical error handling</title>
+
+<para><computeroutput>libbzip2</computeroutput> contains a number
+of internal assertion checks which should, needless to say, never
+be activated. Nevertheless, if an assertion should fail,
+behaviour depends on whether or not the library was compiled with
+<computeroutput>BZ_NO_STDIO</computeroutput> set.</para>
+
+<para>For a normal compile, an assertion failure yields the
+message:</para>
+
+<blockquote>
+<para>bzip2/libbzip2: internal error number N.</para>
+<para>This is a bug in bzip2/libbzip2, &bz-version; of &bz-date;.
+Please report it to me at: &bz-email;. If this happened
+when you were using some program which uses libbzip2 as a
+component, you should also report this bug to the author(s)
+of that program. Please make an effort to report this bug;
+timely and accurate bug reports eventually lead to higher
+quality software. Thanks. Julian Seward, &bz-date;.
+</para></blockquote>
+
+<para>where <computeroutput>N</computeroutput> is some error code
+number. If <computeroutput>N == 1007</computeroutput>, it also
+prints some extra text advising the reader that unreliable memory
+is often associated with internal error 1007. (This is a
+frequently-observed-phenomenon with versions 1.0.0/1.0.1).</para>
+
+<para><computeroutput>exit(3)</computeroutput> is then
+called.</para>
+
+<para>For a <computeroutput>stdio</computeroutput>-free library,
+assertion failures result in a call to a function declared
+as:</para>
+
+<programlisting>
+extern void bz_internal_error ( int errcode );
+</programlisting>
+
+<para>The relevant code is passed as a parameter. You should
+supply such a function.</para>
+
+<para>In either case, once an assertion failure has occurred, any
+<computeroutput>bz_stream</computeroutput> records involved can
+be regarded as invalid. You should not attempt to resume normal
+operation with them.</para>
+
+<para>You may, of course, change critical error handling to suit
+your needs. As I said above, critical errors indicate bugs in
+the library and should not occur. All "normal" error situations
+are indicated via error return codes from functions, and can be
+recovered from.</para>
+
+</sect2>
+
+</sect1>
+
+
+<sect1 id="win-dll" xreflabel="Making a Windows DLL">
+<title>Making a Windows DLL</title>
+
+<para>Everything related to Windows has been contributed by
+Yoshioka Tsuneo
+(<computeroutput>tsuneo@rr.iij4u.or.jp</computeroutput>), so
+you should send your queries to him (but perhaps Cc: me,
+<computeroutput>&bz-email;</computeroutput>).</para>
+
+<para>My vague understanding of what to do is: using Visual C++
+5.0, open the project file
+<computeroutput>libbz2.dsp</computeroutput>, and build. That's
+all.</para>
+
+<para>If you can't open the project file for some reason, make a
+new one, naming these files:
+<computeroutput>blocksort.c</computeroutput>,
+<computeroutput>bzlib.c</computeroutput>,
+<computeroutput>compress.c</computeroutput>,
+<computeroutput>crctable.c</computeroutput>,
+<computeroutput>decompress.c</computeroutput>,
+<computeroutput>huffman.c</computeroutput>,
+<computeroutput>randtable.c</computeroutput> and
+<computeroutput>libbz2.def</computeroutput>. You will also need
+to name the header files <computeroutput>bzlib.h</computeroutput>
+and <computeroutput>bzlib_private.h</computeroutput>.</para>
+
+<para>If you don't use VC++, you may need to define the
+proprocessor symbol
+<computeroutput>_WIN32</computeroutput>.</para>
+
+<para>Finally, <computeroutput>dlltest.c</computeroutput> is a
+sample program using the DLL. It has a project file,
+<computeroutput>dlltest.dsp</computeroutput>.</para>
+
+<para>If you just want a makefile for Visual C, have a look at
+<computeroutput>makefile.msc</computeroutput>.</para>
+
+<para>Be aware that if you compile
+<computeroutput>bzip2</computeroutput> itself on Win32, you must
+set <computeroutput>BZ_UNIX</computeroutput> to 0 and
+<computeroutput>BZ_LCCWIN32</computeroutput> to 1, in the file
+<computeroutput>bzip2.c</computeroutput>, before compiling.
+Otherwise the resulting binary won't work correctly.</para>
+
+<para>I haven't tried any of this stuff myself, but it all looks
+plausible.</para>
+
+</sect1>
+
+</chapter>
+
+
+
+<chapter id="misc" xreflabel="Miscellanea">
+<title>Miscellanea</title>
+
+<para>These are just some random thoughts of mine. Your mileage
+may vary.</para>
+
+
+<sect1 id="limits" xreflabel="Limitations of the compressed file format">
+<title>Limitations of the compressed file format</title>
+
+<para><computeroutput>bzip2-1.0.X</computeroutput>,
+<computeroutput>0.9.5</computeroutput> and
+<computeroutput>0.9.0</computeroutput> use exactly the same file
+format as the original version,
+<computeroutput>bzip2-0.1</computeroutput>. This decision was
+made in the interests of stability. Creating yet another
+incompatible compressed file format would create further
+confusion and disruption for users.</para>
+
+<para>Nevertheless, this is not a painless decision. Development
+work since the release of
+<computeroutput>bzip2-0.1</computeroutput> in August 1997 has
+shown complexities in the file format which slow down
+decompression and, in retrospect, are unnecessary. These
+are:</para>
+
+<itemizedlist mark='bullet'>
+
+ <listitem><para>The run-length encoder, which is the first of the
+ compression transformations, is entirely irrelevant. The
+ original purpose was to protect the sorting algorithm from the
+ very worst case input: a string of repeated symbols. But
+ algorithm steps Q6a and Q6b in the original Burrows-Wheeler
+ technical report (SRC-124) show how repeats can be handled
+ without difficulty in block sorting.</para></listitem>
+
+ <listitem><para>The randomisation mechanism doesn't really need to be
+ there. Udi Manber and Gene Myers published a suffix array
+ construction algorithm a few years back, which can be employed
+ to sort any block, no matter how repetitive, in O(N log N)
+ time. Subsequent work by Kunihiko Sadakane has produced a
+ derivative O(N (log N)^2) algorithm which usually outperforms
+ the Manber-Myers algorithm.</para>
+
+ <para>I could have changed to Sadakane's algorithm, but I find
+ it to be slower than <computeroutput>bzip2</computeroutput>'s
+ existing algorithm for most inputs, and the randomisation
+ mechanism protects adequately against bad cases. I didn't
+ think it was a good tradeoff to make. Partly this is due to
+ the fact that I was not flooded with email complaints about
+ <computeroutput>bzip2-0.1</computeroutput>'s performance on
+ repetitive data, so perhaps it isn't a problem for real
+ inputs.</para>
+
+ <para>Probably the best long-term solution, and the one I have
+ incorporated into 0.9.5 and above, is to use the existing
+ sorting algorithm initially, and fall back to a O(N (log N)^2)
+ algorithm if the standard algorithm gets into
+ difficulties.</para></listitem>
+
+ <listitem><para>The compressed file format was never designed to be
+ handled by a library, and I have had to jump though some hoops
+ to produce an efficient implementation of decompression. It's
+ a bit hairy. Try passing
+ <computeroutput>decompress.c</computeroutput> through the C
+ preprocessor and you'll see what I mean. Much of this
+ complexity could have been avoided if the compressed size of
+ each block of data was recorded in the data stream.</para></listitem>
+
+ <listitem><para>An Adler-32 checksum, rather than a CRC32 checksum,
+ would be faster to compute.</para></listitem>
+
+</itemizedlist>
+
+<para>It would be fair to say that the
+<computeroutput>bzip2</computeroutput> format was frozen before I
+properly and fully understood the performance consequences of
+doing so.</para>
+
+<para>Improvements which I was able to incorporate into 0.9.0,
+despite using the same file format, are:</para>
+
+<itemizedlist mark='bullet'>
+
+ <listitem><para>Single array implementation of the inverse BWT. This
+ significantly speeds up decompression, presumably because it
+ reduces the number of cache misses.</para></listitem>
+
+ <listitem><para>Faster inverse MTF transform for large MTF values.
+ The new implementation is based on the notion of sliding blocks
+ of values.</para></listitem>
+
+ <listitem><para><computeroutput>bzip2-0.9.0</computeroutput> now reads
+ and writes files with <computeroutput>fread</computeroutput>
+ and <computeroutput>fwrite</computeroutput>; version 0.1 used
+ <computeroutput>putc</computeroutput> and
+ <computeroutput>getc</computeroutput>. Duh! Well, you live
+ and learn.</para></listitem>
+
+</itemizedlist>
+
+<para>Further ahead, it would be nice to be able to do random
+access into files. This will require some careful design of
+compressed file formats.</para>
+
+</sect1>
+
+
+<sect1 id="port-issues" xreflabel="Portability issues">
+<title>Portability issues</title>
+
+<para>After some consideration, I have decided not to use GNU
+<computeroutput>autoconf</computeroutput> to configure 0.9.5 or
+1.0.</para>
+
+<para><computeroutput>autoconf</computeroutput>, admirable and
+wonderful though it is, mainly assists with portability problems
+between Unix-like platforms. But
+<computeroutput>bzip2</computeroutput> doesn't have much in the
+way of portability problems on Unix; most of the difficulties
+appear when porting to the Mac, or to Microsoft's operating
+systems. <computeroutput>autoconf</computeroutput> doesn't help
+in those cases, and brings in a whole load of new
+complexity.</para>
+
+<para>Most people should be able to compile the library and
+program under Unix straight out-of-the-box, so to speak,
+especially if you have a version of GNU C available.</para>
+
+<para>There are a couple of
+<computeroutput>__inline__</computeroutput> directives in the
+code. GNU C (<computeroutput>gcc</computeroutput>) should be
+able to handle them. If you're not using GNU C, your C compiler
+shouldn't see them at all. If your compiler does, for some
+reason, see them and doesn't like them, just
+<computeroutput>#define</computeroutput>
+<computeroutput>__inline__</computeroutput> to be
+<computeroutput>/* */</computeroutput>. One easy way to do this
+is to compile with the flag
+<computeroutput>-D__inline__=</computeroutput>, which should be
+understood by most Unix compilers.</para>
+
+<para>If you still have difficulties, try compiling with the
+macro <computeroutput>BZ_STRICT_ANSI</computeroutput> defined.
+This should enable you to build the library in a strictly ANSI
+compliant environment. Building the program itself like this is
+dangerous and not supported, since you remove
+<computeroutput>bzip2</computeroutput>'s checks against
+compressing directories, symbolic links, devices, and other
+not-really-a-file entities. This could cause filesystem
+corruption!</para>
+
+<para>One other thing: if you create a
+<computeroutput>bzip2</computeroutput> binary for public distribution,
+please consider linking it statically (<computeroutput>gcc
+-static</computeroutput>). This avoids all sorts of library-version
+issues that others may encounter later on.</para>
+
+<para>If you build <computeroutput>bzip2</computeroutput> on
+Win32, you must set <computeroutput>BZ_UNIX</computeroutput> to 0
+and <computeroutput>BZ_LCCWIN32</computeroutput> to 1, in the
+file <computeroutput>bzip2.c</computeroutput>, before compiling.
+Otherwise the resulting binary won't work correctly.</para>
+
+</sect1>
+
+
+<sect1 id="bugs" xreflabel="Reporting bugs">
+<title>Reporting bugs</title>
+
+<para>I tried pretty hard to make sure
+<computeroutput>bzip2</computeroutput> is bug free, both by
+design and by testing. Hopefully you'll never need to read this
+section for real.</para>
+
+<para>Nevertheless, if <computeroutput>bzip2</computeroutput> dies
+with a segmentation fault, a bus error or an internal assertion
+failure, it will ask you to email me a bug report. Experience from
+years of feedback of bzip2 users indicates that almost all these
+problems can be traced to either compiler bugs or hardware
+problems.</para>
+
+<itemizedlist mark='bullet'>
+
+ <listitem><para>Recompile the program with no optimisation, and
+ see if it works. And/or try a different compiler. I heard all
+ sorts of stories about various flavours of GNU C (and other
+ compilers) generating bad code for
+ <computeroutput>bzip2</computeroutput>, and I've run across two
+ such examples myself.</para>
+
+ <para>2.7.X versions of GNU C are known to generate bad code
+ from time to time, at high optimisation levels. If you get
+ problems, try using the flags
+ <computeroutput>-O2</computeroutput>
+ <computeroutput>-fomit-frame-pointer</computeroutput>
+ <computeroutput>-fno-strength-reduce</computeroutput>. You
+ should specifically <emphasis>not</emphasis> use
+ <computeroutput>-funroll-loops</computeroutput>.</para>
+
+ <para>You may notice that the Makefile runs six tests as part
+ of the build process. If the program passes all of these, it's
+ a pretty good (but not 100%) indication that the compiler has
+ done its job correctly.</para></listitem>
+
+ <listitem><para>If <computeroutput>bzip2</computeroutput>
+ crashes randomly, and the crashes are not repeatable, you may
+ have a flaky memory subsystem.
+ <computeroutput>bzip2</computeroutput> really hammers your
+ memory hierarchy, and if it's a bit marginal, you may get these
+ problems. Ditto if your disk or I/O subsystem is slowly
+ failing. Yup, this really does happen.</para>
+
+ <para>Try using a different machine of the same type, and see
+ if you can repeat the problem.</para></listitem>
+
+ <listitem><para>This isn't really a bug, but ... If
+ <computeroutput>bzip2</computeroutput> tells you your file is
+ corrupted on decompression, and you obtained the file via FTP,
+ there is a possibility that you forgot to tell FTP to do a
+ binary mode transfer. That absolutely will cause the file to
+ be non-decompressible. You'll have to transfer it
+ again.</para></listitem>
+
+</itemizedlist>
+
+<para>If you've incorporated
+<computeroutput>libbzip2</computeroutput> into your own program
+and are getting problems, please, please, please, check that the
+parameters you are passing in calls to the library, are correct,
+and in accordance with what the documentation says is allowable.
+I have tried to make the library robust against such problems,
+but I'm sure I haven't succeeded.</para>
+
+<para>Finally, if the above comments don't help, you'll have to
+send me a bug report. Now, it's just amazing how many people
+will send me a bug report saying something like:</para>
+
+<programlisting>
+bzip2 crashed with segmentation fault on my machine
+</programlisting>
+
+<para>and absolutely nothing else. Needless to say, a such a
+report is <emphasis>totally, utterly, completely and
+comprehensively 100% useless; a waste of your time, my time, and
+net bandwidth</emphasis>. With no details at all, there's no way
+I can possibly begin to figure out what the problem is.</para>
+
+<para>The rules of the game are: facts, facts, facts. Don't omit
+them because "oh, they won't be relevant". At the bare
+minimum:</para>
+
+<programlisting>
+Machine type. Operating system version.
+Exact version of bzip2 (do bzip2 -V).
+Exact version of the compiler used.
+Flags passed to the compiler.
+</programlisting>
+
+<para>However, the most important single thing that will help me
+is the file that you were trying to compress or decompress at the
+time the problem happened. Without that, my ability to do
+anything more than speculate about the cause, is limited.</para>
+
+</sect1>
+
+
+<sect1 id="package" xreflabel="Did you get the right package?">
+<title>Did you get the right package?</title>
+
+<para><computeroutput>bzip2</computeroutput> is a resource hog.
+It soaks up large amounts of CPU cycles and memory. Also, it
+gives very large latencies. In the worst case, you can feed many
+megabytes of uncompressed data into the library before getting
+any compressed output, so this probably rules out applications
+requiring interactive behaviour.</para>
+
+<para>These aren't faults of my implementation, I hope, but more
+an intrinsic property of the Burrows-Wheeler transform
+(unfortunately). Maybe this isn't what you want.</para>
+
+<para>If you want a compressor and/or library which is faster,
+uses less memory but gets pretty good compression, and has
+minimal latency, consider Jean-loup Gailly's and Mark Adler's
+work, <computeroutput>zlib-1.2.1</computeroutput> and
+<computeroutput>gzip-1.2.4</computeroutput>. Look for them at
+<ulink url="http://www.zlib.org">http://www.zlib.org</ulink> and
+<ulink url="http://www.gzip.org">http://www.gzip.org</ulink>
+respectively.</para>
+
+<para>For something faster and lighter still, you might try Markus F
+X J Oberhumer's <computeroutput>LZO</computeroutput> real-time
+compression/decompression library, at
+<ulink url="http://www.oberhumer.com/opensource">http://www.oberhumer.com/opensource</ulink>.</para>
+
+</sect1>
+
+
+
+<sect1 id="reading" xreflabel="Further Reading">
+<title>Further Reading</title>
+
+<para><computeroutput>bzip2</computeroutput> is not research
+work, in the sense that it doesn't present any new ideas.
+Rather, it's an engineering exercise based on existing
+ideas.</para>
+
+<para>Four documents describe essentially all the ideas behind
+<computeroutput>bzip2</computeroutput>:</para>
+
+<literallayout>Michael Burrows and D. J. Wheeler:
+ "A block-sorting lossless data compression algorithm"
+ 10th May 1994.
+ Digital SRC Research Report 124.
+ ftp://ftp.digital.com/pub/DEC/SRC/research-reports/SRC-124.ps.gz
+ If you have trouble finding it, try searching at the
+ New Zealand Digital Library, http://www.nzdl.org.
+
+Daniel S. Hirschberg and Debra A. LeLewer
+ "Efficient Decoding of Prefix Codes"
+ Communications of the ACM, April 1990, Vol 33, Number 4.
+ You might be able to get an electronic copy of this
+ from the ACM Digital Library.
+
+David J. Wheeler
+ Program bred3.c and accompanying document bred3.ps.
+ This contains the idea behind the multi-table Huffman coding scheme.
+ ftp://ftp.cl.cam.ac.uk/users/djw3/
+
+Jon L. Bentley and Robert Sedgewick
+ "Fast Algorithms for Sorting and Searching Strings"
+ Available from Sedgewick's web page,
+ www.cs.princeton.edu/~rs
+</literallayout>
+
+<para>The following paper gives valuable additional insights into
+the algorithm, but is not immediately the basis of any code used
+in bzip2.</para>
+
+<literallayout>Peter Fenwick:
+ Block Sorting Text Compression
+ Proceedings of the 19th Australasian Computer Science Conference,
+ Melbourne, Australia. Jan 31 - Feb 2, 1996.
+ ftp://ftp.cs.auckland.ac.nz/pub/peter-f/ACSC96paper.ps</literallayout>
+
+<para>Kunihiko Sadakane's sorting algorithm, mentioned above, is
+available from:</para>
+
+<literallayout>http://naomi.is.s.u-tokyo.ac.jp/~sada/papers/Sada98b.ps.gz
+</literallayout>
+
+<para>The Manber-Myers suffix array construction algorithm is
+described in a paper available from:</para>
+
+<literallayout>http://www.cs.arizona.edu/people/gene/PAPERS/suffix.ps
+</literallayout>
+
+<para>Finally, the following papers document some
+investigations I made into the performance of sorting
+and decompression algorithms:</para>
+
+<literallayout>Julian Seward
+ On the Performance of BWT Sorting Algorithms
+ Proceedings of the IEEE Data Compression Conference 2000
+ Snowbird, Utah. 28-30 March 2000.
+
+Julian Seward
+ Space-time Tradeoffs in the Inverse B-W Transform
+ Proceedings of the IEEE Data Compression Conference 2001
+ Snowbird, Utah. 27-29 March 2001.
+</literallayout>
+
+</sect1>
+
+</chapter>
+
+</book>
diff --git a/Utilities/cmbzip2/mk251.c b/Utilities/cmbzip2/mk251.c
new file mode 100644
index 000000000..39e94c057
--- /dev/null
+++ b/Utilities/cmbzip2/mk251.c
@@ -0,0 +1,31 @@
+
+/* Spew out a long sequence of the byte 251. When fed to bzip2
+ versions 1.0.0 or 1.0.1, causes it to die with internal error
+ 1007 in blocksort.c. This assertion misses an extremely rare
+ case, which is fixed in this version (1.0.2) and above.
+*/
+
+/* ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
+
+ bzip2/libbzip2 version 1.0.5 of 10 December 2007
+ Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
+
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------ */
+
+
+#include <stdio.h>
+
+int main ()
+{
+ int i;
+ for (i = 0; i < 48500000 ; i++)
+ putchar(251);
+ return 0;
+}
diff --git a/Utilities/cmbzip2/randtable.c b/Utilities/cmbzip2/randtable.c
new file mode 100644
index 000000000..068b76367
--- /dev/null
+++ b/Utilities/cmbzip2/randtable.c
@@ -0,0 +1,84 @@
+
+/*-------------------------------------------------------------*/
+/*--- Table for randomising repetitive blocks ---*/
+/*--- randtable.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
+
+ bzip2/libbzip2 version 1.0.5 of 10 December 2007
+ Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
+
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------ */
+
+
+#include "bzlib_private.h"
+
+
+/*---------------------------------------------*/
+Int32 BZ2_rNums[512] = {
+ 619, 720, 127, 481, 931, 816, 813, 233, 566, 247,
+ 985, 724, 205, 454, 863, 491, 741, 242, 949, 214,
+ 733, 859, 335, 708, 621, 574, 73, 654, 730, 472,
+ 419, 436, 278, 496, 867, 210, 399, 680, 480, 51,
+ 878, 465, 811, 169, 869, 675, 611, 697, 867, 561,
+ 862, 687, 507, 283, 482, 129, 807, 591, 733, 623,
+ 150, 238, 59, 379, 684, 877, 625, 169, 643, 105,
+ 170, 607, 520, 932, 727, 476, 693, 425, 174, 647,
+ 73, 122, 335, 530, 442, 853, 695, 249, 445, 515,
+ 909, 545, 703, 919, 874, 474, 882, 500, 594, 612,
+ 641, 801, 220, 162, 819, 984, 589, 513, 495, 799,
+ 161, 604, 958, 533, 221, 400, 386, 867, 600, 782,
+ 382, 596, 414, 171, 516, 375, 682, 485, 911, 276,
+ 98, 553, 163, 354, 666, 933, 424, 341, 533, 870,
+ 227, 730, 475, 186, 263, 647, 537, 686, 600, 224,
+ 469, 68, 770, 919, 190, 373, 294, 822, 808, 206,
+ 184, 943, 795, 384, 383, 461, 404, 758, 839, 887,
+ 715, 67, 618, 276, 204, 918, 873, 777, 604, 560,
+ 951, 160, 578, 722, 79, 804, 96, 409, 713, 940,
+ 652, 934, 970, 447, 318, 353, 859, 672, 112, 785,
+ 645, 863, 803, 350, 139, 93, 354, 99, 820, 908,
+ 609, 772, 154, 274, 580, 184, 79, 626, 630, 742,
+ 653, 282, 762, 623, 680, 81, 927, 626, 789, 125,
+ 411, 521, 938, 300, 821, 78, 343, 175, 128, 250,
+ 170, 774, 972, 275, 999, 639, 495, 78, 352, 126,
+ 857, 956, 358, 619, 580, 124, 737, 594, 701, 612,
+ 669, 112, 134, 694, 363, 992, 809, 743, 168, 974,
+ 944, 375, 748, 52, 600, 747, 642, 182, 862, 81,
+ 344, 805, 988, 739, 511, 655, 814, 334, 249, 515,
+ 897, 955, 664, 981, 649, 113, 974, 459, 893, 228,
+ 433, 837, 553, 268, 926, 240, 102, 654, 459, 51,
+ 686, 754, 806, 760, 493, 403, 415, 394, 687, 700,
+ 946, 670, 656, 610, 738, 392, 760, 799, 887, 653,
+ 978, 321, 576, 617, 626, 502, 894, 679, 243, 440,
+ 680, 879, 194, 572, 640, 724, 926, 56, 204, 700,
+ 707, 151, 457, 449, 797, 195, 791, 558, 945, 679,
+ 297, 59, 87, 824, 713, 663, 412, 693, 342, 606,
+ 134, 108, 571, 364, 631, 212, 174, 643, 304, 329,
+ 343, 97, 430, 751, 497, 314, 983, 374, 822, 928,
+ 140, 206, 73, 263, 980, 736, 876, 478, 430, 305,
+ 170, 514, 364, 692, 829, 82, 855, 953, 676, 246,
+ 369, 970, 294, 750, 807, 827, 150, 790, 288, 923,
+ 804, 378, 215, 828, 592, 281, 565, 555, 710, 82,
+ 896, 831, 547, 261, 524, 462, 293, 465, 502, 56,
+ 661, 821, 976, 991, 658, 869, 905, 758, 745, 193,
+ 768, 550, 608, 933, 378, 286, 215, 979, 792, 961,
+ 61, 688, 793, 644, 986, 403, 106, 366, 905, 644,
+ 372, 567, 466, 434, 645, 210, 389, 550, 919, 135,
+ 780, 773, 635, 389, 707, 100, 626, 958, 165, 504,
+ 920, 176, 193, 713, 857, 265, 203, 50, 668, 108,
+ 645, 990, 626, 197, 510, 357, 358, 850, 858, 364,
+ 936, 638
+};
+
+
+/*-------------------------------------------------------------*/
+/*--- end randtable.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/Utilities/cmbzip2/sample1.rb2 b/Utilities/cmbzip2/sample1.rb2
new file mode 100644
index 000000000..4edda362a
--- /dev/null
+++ b/Utilities/cmbzip2/sample1.rb2
Binary files differ
diff --git a/Utilities/cmbzip2/sample1.ref b/Utilities/cmbzip2/sample1.ref
new file mode 100644
index 000000000..dc869ee6d
--- /dev/null
+++ b/Utilities/cmbzip2/sample1.ref
Binary files differ
diff --git a/Utilities/cmbzip2/sample1.tst b/Utilities/cmbzip2/sample1.tst
new file mode 100644
index 000000000..dc869ee6d
--- /dev/null
+++ b/Utilities/cmbzip2/sample1.tst
Binary files differ
diff --git a/Utilities/cmbzip2/sample2.rb2 b/Utilities/cmbzip2/sample2.rb2
new file mode 100644
index 000000000..8e54297c9
--- /dev/null
+++ b/Utilities/cmbzip2/sample2.rb2
Binary files differ
diff --git a/Utilities/cmbzip2/sample2.ref b/Utilities/cmbzip2/sample2.ref
new file mode 100644
index 000000000..40e5b58f2
--- /dev/null
+++ b/Utilities/cmbzip2/sample2.ref
Binary files differ
diff --git a/Utilities/cmbzip2/sample2.tst b/Utilities/cmbzip2/sample2.tst
new file mode 100644
index 000000000..40e5b58f2
--- /dev/null
+++ b/Utilities/cmbzip2/sample2.tst
Binary files differ
diff --git a/Utilities/cmbzip2/sample3.rb2 b/Utilities/cmbzip2/sample3.rb2
new file mode 100644
index 000000000..1c9b08c47
--- /dev/null
+++ b/Utilities/cmbzip2/sample3.rb2
Binary files differ
diff --git a/Utilities/cmbzip2/sample3.ref b/Utilities/cmbzip2/sample3.ref
new file mode 100644
index 000000000..775a2f68e
--- /dev/null
+++ b/Utilities/cmbzip2/sample3.ref
@@ -0,0 +1,30007 @@
+This file is exceedingly boring. If you find yourself
+reading it, please (1) take it from me that you can safely
+guess what the rest of the file says, and (2) seek professional
+help.
+
+ps. there are no further sarcastic remarks in this file.
+
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
diff --git a/Utilities/cmbzip2/sample3.tst b/Utilities/cmbzip2/sample3.tst
new file mode 100644
index 000000000..775a2f68e
--- /dev/null
+++ b/Utilities/cmbzip2/sample3.tst
@@ -0,0 +1,30007 @@
+This file is exceedingly boring. If you find yourself
+reading it, please (1) take it from me that you can safely
+guess what the rest of the file says, and (2) seek professional
+help.
+
+ps. there are no further sarcastic remarks in this file.
+
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
+ugh
diff --git a/Utilities/cmbzip2/spewG.c b/Utilities/cmbzip2/spewG.c
new file mode 100644
index 000000000..7bd12841d
--- /dev/null
+++ b/Utilities/cmbzip2/spewG.c
@@ -0,0 +1,54 @@
+
+/* spew out a thoroughly gigantic file designed so that bzip2
+ can compress it reasonably rapidly. This is to help test
+ support for large files (> 2GB) in a reasonable amount of time.
+ I suggest you use the undocumented --exponential option to
+ bzip2 when compressing the resulting file; this saves a bit of
+ time. Note: *don't* bother with --exponential when compressing
+ Real Files; it'll just waste a lot of CPU time :-)
+ (but is otherwise harmless).
+*/
+
+/* ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
+
+ bzip2/libbzip2 version 1.0.5 of 10 December 2007
+ Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
+
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------ */
+
+
+#define _FILE_OFFSET_BITS 64
+
+#include <stdio.h>
+#include <stdlib.h>
+
+/* The number of megabytes of junk to spew out (roughly) */
+#define MEGABYTES 5000
+
+#define N_BUF 1000000
+char buf[N_BUF];
+
+int main ( int argc, char** argv )
+{
+ int ii, kk, p;
+ srandom(1);
+ setbuffer ( stdout, buf, N_BUF );
+ for (kk = 0; kk < MEGABYTES * 515; kk+=3) {
+ p = 25+random()%50;
+ for (ii = 0; ii < p; ii++)
+ printf ( "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" );
+ for (ii = 0; ii < p-1; ii++)
+ printf ( "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" );
+ for (ii = 0; ii < p+1; ii++)
+ printf ( "ccccccccccccccccccccccccccccccccccccc" );
+ }
+ fflush(stdout);
+ return 0;
+}
diff --git a/Utilities/cmbzip2/unzcrash.c b/Utilities/cmbzip2/unzcrash.c
new file mode 100644
index 000000000..a1b75463a
--- /dev/null
+++ b/Utilities/cmbzip2/unzcrash.c
@@ -0,0 +1,141 @@
+
+/* A test program written to test robustness to decompression of
+ corrupted data. Usage is
+ unzcrash filename
+ and the program will read the specified file, compress it (in memory),
+ and then repeatedly decompress it, each time with a different bit of
+ the compressed data inverted, so as to test all possible one-bit errors.
+ This should not cause any invalid memory accesses. If it does,
+ I want to know about it!
+
+ PS. As you can see from the above description, the process is
+ incredibly slow. A file of size eg 5KB will cause it to run for
+ many hours.
+*/
+
+/* ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
+
+ bzip2/libbzip2 version 1.0.5 of 10 December 2007
+ Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
+
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------ */
+
+
+#include <stdio.h>
+#include <assert.h>
+#include "bzlib.h"
+
+#define M_BLOCK 1000000
+
+typedef unsigned char uchar;
+
+#define M_BLOCK_OUT (M_BLOCK + 1000000)
+uchar inbuf[M_BLOCK];
+uchar outbuf[M_BLOCK_OUT];
+uchar zbuf[M_BLOCK + 600 + (M_BLOCK / 100)];
+
+int nIn, nOut, nZ;
+
+static char *bzerrorstrings[] = {
+ "OK"
+ ,"SEQUENCE_ERROR"
+ ,"PARAM_ERROR"
+ ,"MEM_ERROR"
+ ,"DATA_ERROR"
+ ,"DATA_ERROR_MAGIC"
+ ,"IO_ERROR"
+ ,"UNEXPECTED_EOF"
+ ,"OUTBUFF_FULL"
+ ,"???" /* for future */
+ ,"???" /* for future */
+ ,"???" /* for future */
+ ,"???" /* for future */
+ ,"???" /* for future */
+ ,"???" /* for future */
+};
+
+void flip_bit ( int bit )
+{
+ int byteno = bit / 8;
+ int bitno = bit % 8;
+ uchar mask = 1 << bitno;
+ //fprintf ( stderr, "(byte %d bit %d mask %d)",
+ // byteno, bitno, (int)mask );
+ zbuf[byteno] ^= mask;
+}
+
+int main ( int argc, char** argv )
+{
+ FILE* f;
+ int r;
+ int bit;
+ int i;
+
+ if (argc != 2) {
+ fprintf ( stderr, "usage: unzcrash filename\n" );
+ return 1;
+ }
+
+ f = fopen ( argv[1], "r" );
+ if (!f) {
+ fprintf ( stderr, "unzcrash: can't open %s\n", argv[1] );
+ return 1;
+ }
+
+ nIn = fread ( inbuf, 1, M_BLOCK, f );
+ fprintf ( stderr, "%d bytes read\n", nIn );
+
+ nZ = M_BLOCK;
+ r = BZ2_bzBuffToBuffCompress (
+ zbuf, &nZ, inbuf, nIn, 9, 0, 30 );
+
+ assert (r == BZ_OK);
+ fprintf ( stderr, "%d after compression\n", nZ );
+
+ for (bit = 0; bit < nZ*8; bit++) {
+ fprintf ( stderr, "bit %d ", bit );
+ flip_bit ( bit );
+ nOut = M_BLOCK_OUT;
+ r = BZ2_bzBuffToBuffDecompress (
+ outbuf, &nOut, zbuf, nZ, 0, 0 );
+ fprintf ( stderr, " %d %s ", r, bzerrorstrings[-r] );
+
+ if (r != BZ_OK) {
+ fprintf ( stderr, "\n" );
+ } else {
+ if (nOut != nIn) {
+ fprintf(stderr, "nIn/nOut mismatch %d %d\n", nIn, nOut );
+ return 1;
+ } else {
+ for (i = 0; i < nOut; i++)
+ if (inbuf[i] != outbuf[i]) {
+ fprintf(stderr, "mismatch at %d\n", i );
+ return 1;
+ }
+ if (i == nOut) fprintf(stderr, "really ok!\n" );
+ }
+ }
+
+ flip_bit ( bit );
+ }
+
+#if 0
+ assert (nOut == nIn);
+ for (i = 0; i < nOut; i++) {
+ if (inbuf[i] != outbuf[i]) {
+ fprintf ( stderr, "difference at %d !\n", i );
+ return 1;
+ }
+ }
+#endif
+
+ fprintf ( stderr, "all ok\n" );
+ return 0;
+}
diff --git a/Utilities/cmbzip2/words0 b/Utilities/cmbzip2/words0
new file mode 100644
index 000000000..fbf442ad6
--- /dev/null
+++ b/Utilities/cmbzip2/words0
@@ -0,0 +1,9 @@
+
+If compilation produces errors, or a large number of warnings,
+please read README.COMPILATION.PROBLEMS -- you might be able to
+adjust the flags in this Makefile to improve matters.
+
+Also in README.COMPILATION.PROBLEMS are some hints that may help
+if your build produces an executable which is unable to correctly
+handle so-called 'large files' -- files of size 2GB or more.
+
diff --git a/Utilities/cmbzip2/words1 b/Utilities/cmbzip2/words1
new file mode 100644
index 000000000..2e83de9f0
--- /dev/null
+++ b/Utilities/cmbzip2/words1
@@ -0,0 +1,4 @@
+
+Doing 6 tests (3 compress, 3 uncompress) ...
+If there's a problem, things might stop at this point.
+
diff --git a/Utilities/cmbzip2/words2 b/Utilities/cmbzip2/words2
new file mode 100644
index 000000000..caddcf422
--- /dev/null
+++ b/Utilities/cmbzip2/words2
@@ -0,0 +1,5 @@
+
+Checking test results. If any of the four "cmp"s which follow
+report any differences, something is wrong. If you can't easily
+figure out what, please let me know (jseward@bzip.org).
+
diff --git a/Utilities/cmbzip2/words3 b/Utilities/cmbzip2/words3
new file mode 100644
index 000000000..697266990
--- /dev/null
+++ b/Utilities/cmbzip2/words3
@@ -0,0 +1,30 @@
+
+If you got this far and the 'cmp's didn't complain, it looks
+like you're in business.
+
+To install in /usr/local/bin, /usr/local/lib, /usr/local/man and
+/usr/local/include, type
+
+ make install
+
+To install somewhere else, eg, /xxx/yyy/{bin,lib,man,include}, type
+
+ make install PREFIX=/xxx/yyy
+
+If you are (justifiably) paranoid and want to see what 'make install'
+is going to do, you can first do
+
+ make -n install or
+ make -n install PREFIX=/xxx/yyy respectively.
+
+The -n instructs make to show the commands it would execute, but
+not actually execute them.
+
+Instructions for use are in the preformatted manual page, in the file
+bzip2.txt. For more detailed documentation, read the full manual.
+It is available in Postscript form (manual.ps), PDF form (manual.pdf),
+and HTML form (manual.html).
+
+You can also do "bzip2 --help" to see some helpful information.
+"bzip2 -L" displays the software license.
+
diff --git a/Utilities/cmbzip2/xmlproc.sh b/Utilities/cmbzip2/xmlproc.sh
new file mode 100755
index 000000000..53841773d
--- /dev/null
+++ b/Utilities/cmbzip2/xmlproc.sh
@@ -0,0 +1,114 @@
+#!/bin/bash
+# see the README file for usage etc.
+#
+# ------------------------------------------------------------------
+# This file is part of bzip2/libbzip2, a program and library for
+# lossless, block-sorting data compression.
+#
+# bzip2/libbzip2 version 1.0.5 of 10 December 2007
+# Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
+#
+# Please read the WARNING, DISCLAIMER and PATENTS sections in the
+# README file.
+#
+# This program is released under the terms of the license contained
+# in the file LICENSE.
+# ----------------------------------------------------------------
+
+
+usage() {
+ echo '';
+ echo 'Usage: xmlproc.sh -[option] <filename.xml>';
+ echo 'Specify a target from:';
+ echo '-v verify xml file conforms to dtd';
+ echo '-html output in html format (single file)';
+ echo '-ps output in postscript format';
+ echo '-pdf output in pdf format';
+ exit;
+}
+
+if test $# -ne 2; then
+ usage
+fi
+# assign the variable for the output type
+action=$1; shift
+# assign the output filename
+xmlfile=$1; shift
+# and check user input it correct
+if !(test -f $xmlfile); then
+ echo "No such file: $xmlfile";
+ exit;
+fi
+# some other stuff we will use
+OUT=output
+xsl_fo=bz-fo.xsl
+xsl_html=bz-html.xsl
+
+basename=$xmlfile
+basename=${basename//'.xml'/''}
+
+fofile="${basename}.fo"
+htmlfile="${basename}.html"
+pdffile="${basename}.pdf"
+psfile="${basename}.ps"
+xmlfmtfile="${basename}.fmt"
+
+# first process the xmlfile with CDATA tags
+./format.pl $xmlfile $xmlfmtfile
+# so the shell knows where the catalogs live
+export XML_CATALOG_FILES=/etc/xml/catalog
+
+# post-processing tidy up
+cleanup() {
+ echo "Cleaning up: $@"
+ while [ $# != 0 ]
+ do
+ arg=$1; shift;
+ echo " deleting $arg";
+ rm $arg
+ done
+}
+
+case $action in
+ -v)
+ flags='--noout --xinclude --noblanks --postvalid'
+ dtd='--dtdvalid http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd'
+ xmllint $flags $dtd $xmlfmtfile 2> $OUT
+ egrep 'error' $OUT
+ rm $OUT
+ ;;
+
+ -html)
+ echo "Creating $htmlfile ..."
+ xsltproc --nonet --xinclude -o $htmlfile $xsl_html $xmlfmtfile
+ cleanup $xmlfmtfile
+ ;;
+
+ -pdf)
+ echo "Creating $pdffile ..."
+ xsltproc --nonet --xinclude -o $fofile $xsl_fo $xmlfmtfile
+ pdfxmltex $fofile >$OUT </dev/null
+ pdfxmltex $fofile >$OUT </dev/null
+ pdfxmltex $fofile >$OUT </dev/null
+ cleanup $OUT $xmlfmtfile *.aux *.fo *.log *.out
+ ;;
+
+ -ps)
+ echo "Creating $psfile ..."
+ xsltproc --nonet --xinclude -o $fofile $xsl_fo $xmlfmtfile
+ pdfxmltex $fofile >$OUT </dev/null
+ pdfxmltex $fofile >$OUT </dev/null
+ pdfxmltex $fofile >$OUT </dev/null
+ pdftops $pdffile $psfile
+ cleanup $OUT $xmlfmtfile $pdffile *.aux *.fo *.log *.out
+# passivetex is broken, so we can't go this route yet.
+# xmltex $fofile >$OUT </dev/null
+# xmltex $fofile >$OUT </dev/null
+# xmltex $fofile >$OUT </dev/null
+# dvips -R -q -o bzip-manual.ps *.dvi
+ ;;
+
+ *)
+ usage
+ ;;
+esac
diff --git a/Utilities/cmcompress/CMakeLists.txt b/Utilities/cmcompress/CMakeLists.txt
new file mode 100644
index 000000000..3323dcd7d
--- /dev/null
+++ b/Utilities/cmcompress/CMakeLists.txt
@@ -0,0 +1,5 @@
+PROJECT(CMCompress)
+
+ADD_LIBRARY(cmcompress cmcompress.c)
+
+INSTALL(FILES Copyright.txt DESTINATION ${CMake_DOC_DEST}/cmcompress)
diff --git a/Utilities/cmcompress/Copyright.txt b/Utilities/cmcompress/Copyright.txt
new file mode 100644
index 000000000..162332f69
--- /dev/null
+++ b/Utilities/cmcompress/Copyright.txt
@@ -0,0 +1,34 @@
+Copyright (c) 1985, 1986 The Regents of the University of California.
+All rights reserved.
+
+This code is derived from software contributed to Berkeley by
+James A. Woods, derived from original work by Spencer Thomas
+and Joseph Orost.
+
+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. All advertising materials mentioning features or use of this software
+ must display the following acknowledgement:
+ This product includes software developed by the University of
+ California, Berkeley and its contributors.
+4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
diff --git a/Utilities/cmcompress/cmcompress.c b/Utilities/cmcompress/cmcompress.c
new file mode 100644
index 000000000..ea845ed5f
--- /dev/null
+++ b/Utilities/cmcompress/cmcompress.c
@@ -0,0 +1,551 @@
+/*
+ * Copyright (c) 1985, 1986 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * James A. Woods, derived from original work by Spencer Thomas
+ * and Joseph Orost.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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 "cmcompress.h"
+
+#include <errno.h>
+#include <string.h>
+
+static const char_type magic_header[] = { "\037\235" }; /* 1F 9D */
+
+/* Defines for third byte of header */
+#define BIT_MASK 0x1f
+#define BLOCK_MASK 0x80
+#define CHECK_GAP 10000 /* ratio check interval */
+/* Masks 0x40 and 0x20 are free. I think 0x20 should mean that there is
+ a fourth header byte (for expansion).
+ */
+#define INIT_BITS 9 /* initial number of bits/code */
+
+#ifdef COMPATIBLE /* But wrong! */
+# define MAXCODE(n_bits) (1 << (n_bits) - 1)
+#else
+# define MAXCODE(n_bits) ((1 << (n_bits)) - 1)
+#endif /* COMPATIBLE */
+
+#define htabof(i) cdata->htab[i]
+#define codetabof(i) cdata->codetab[i]
+
+/*
+ * the next two codes should not be changed lightly, as they must not
+ * lie within the contiguous general code space.
+ */
+#define FIRST 257 /* first free entry */
+#define CLEAR 256 /* table clear output code */
+
+#ifdef DEBUG
+static void prratio( FILE *stream, long int num, long int den);
+#endif
+
+int cmcompress_compress_initialize(struct cmcompress_stream* cdata)
+{
+ cdata->maxbits = BITS; /* user settable max # bits/code */
+ cdata->maxmaxcode = 1 << BITS; /* should NEVER generate this code */
+ cdata->hsize = HSIZE; /* for dynamic table sizing */
+ cdata->free_ent = 0; /* first unused entry */
+ cdata->nomagic = 0; /* Use a 3-byte magic number header, unless old file */
+ cdata->block_compress = BLOCK_MASK;
+ cdata->clear_flg = 0;
+ cdata->ratio = 0;
+ cdata->checkpoint = CHECK_GAP;
+
+ cdata->input_stream = 0;
+ cdata->output_stream = 0;
+ cdata->client_data = 0;
+ return 1;
+}
+
+static void cl_hash(struct cmcompress_stream* cdata, count_int hsize) /* reset code table */
+{
+ register count_int *htab_p = cdata->htab+hsize;
+ register long i;
+ register long m1 = -1;
+
+ i = hsize - 16;
+ do
+ { /* might use Sys V memset(3) here */
+ *(htab_p-16) = m1;
+ *(htab_p-15) = m1;
+ *(htab_p-14) = m1;
+ *(htab_p-13) = m1;
+ *(htab_p-12) = m1;
+ *(htab_p-11) = m1;
+ *(htab_p-10) = m1;
+ *(htab_p-9) = m1;
+ *(htab_p-8) = m1;
+ *(htab_p-7) = m1;
+ *(htab_p-6) = m1;
+ *(htab_p-5) = m1;
+ *(htab_p-4) = m1;
+ *(htab_p-3) = m1;
+ *(htab_p-2) = m1;
+ *(htab_p-1) = m1;
+ htab_p -= 16;
+ }
+ while ((i -= 16) >= 0);
+ for ( i += 16; i > 0; i-- )
+ {
+ *--htab_p = m1;
+ }
+}
+
+/*-
+ * Output the given code.
+ * Inputs:
+ * code: A n_bits-bit integer. If == -1, then EOF. This assumes
+ * that n_bits =< (long)wordsize - 1.
+ * Outputs:
+ * Outputs code to the file.
+ * Assumptions:
+ * Chars are 8 bits long.
+ * Algorithm:
+ * Maintain a BITS character long buffer (so that 8 codes will
+ * fit in it exactly). Use the VAX insv instruction to insert each
+ * code in turn. When the buffer fills up empty it and start over.
+ */
+
+static char buf[BITS];
+
+#ifndef vax
+char_type lmask[9] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00};
+char_type rmask[9] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
+#endif /* vax */
+
+static int output(struct cmcompress_stream* cdata, code_int code)
+{
+#ifdef DEBUG
+ static int col = 0;
+#endif /* DEBUG */
+
+ /*
+ * On the VAX, it is important to have the register declarations
+ * in exactly the order given, or the asm will break.
+ */
+ register int r_off = cdata->offset, bits= cdata->n_bits;
+ register char * bp = buf;
+
+#ifdef DEBUG
+ if ( verbose )
+ {
+ fprintf( stderr, "%5d%c", code,
+ (col+=6) >= 74 ? (col = 0, '\n') : ' ' );
+ }
+#endif /* DEBUG */
+ if ( code >= 0 )
+ {
+#if defined(vax) && !defined(__GNUC__)
+ /*
+ * VAX and PCC DEPENDENT!! Implementation on other machines is
+ * below.
+ *
+ * Translation: Insert BITS bits from the argument starting at
+ * cdata->offset bits from the beginning of buf.
+ */
+ 0; /* Work around for pcc -O bug with asm and if stmt */
+ asm( "insv 4(ap),r11,r10,(r9)" );
+#else
+ /*
+ * byte/bit numbering on the VAX is simulated by the following code
+ */
+ /*
+ * Get to the first byte.
+ */
+ bp += (r_off >> 3);
+ r_off &= 7;
+ /*
+ * Since code is always >= 8 bits, only need to mask the first
+ * hunk on the left.
+ */
+ *bp = (char)((*bp & rmask[r_off]) | ((code << r_off) & lmask[r_off]));
+ bp++;
+ bits -= (8 - r_off);
+ code >>= 8 - r_off;
+ /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
+ if ( bits >= 8 )
+ {
+ *bp++ = (char)(code);
+ code >>= 8;
+ bits -= 8;
+ }
+ /* Last bits. */
+ if(bits)
+ {
+ *bp = (char)(code);
+ }
+#endif /* vax */
+ cdata->offset += cdata->n_bits;
+ if ( cdata->offset == (cdata->n_bits << 3) )
+ {
+ bp = buf;
+ bits = cdata->n_bits;
+ cdata->bytes_out += bits;
+ do
+ {
+ if ( cdata->output_stream(cdata, bp, 1) != 1 )
+ {
+ return 0;
+ }
+ bp++;
+ }
+ while(--bits);
+ cdata->offset = 0;
+ }
+
+ /*
+ * If the next entry is going to be too big for the code size,
+ * then increase it, if possible.
+ */
+ if ( cdata->free_ent > cdata->maxcode || (cdata->clear_flg > 0))
+ {
+ /*
+ * Write the whole buffer, because the input side won't
+ * discover the size increase until after it has read it.
+ */
+ if ( cdata->offset > 0 )
+ {
+ if ( cdata->output_stream(cdata, buf, cdata->n_bits) != cdata->n_bits )
+ {
+ return 0;
+ }
+ cdata->bytes_out += cdata->n_bits;
+ }
+ cdata->offset = 0;
+
+ if ( cdata->clear_flg )
+ {
+ cdata->maxcode = MAXCODE (cdata->n_bits = INIT_BITS);
+ cdata->clear_flg = 0;
+ }
+ else
+ {
+ cdata->n_bits++;
+ if ( cdata->n_bits == cdata->maxbits )
+ {
+ cdata->maxcode = cdata->maxmaxcode;
+ }
+ else
+ {
+ cdata->maxcode = MAXCODE(cdata->n_bits);
+ }
+ }
+#ifdef DEBUG
+ if ( debug )
+ {
+ fprintf( stderr, "\nChange to %d bits\n", cdata->n_bits );
+ col = 0;
+ }
+#endif /* DEBUG */
+ }
+ }
+ else
+ {
+ /*
+ * At EOF, write the rest of the buffer.
+ */
+ if ( cdata->offset > 0 )
+ {
+ cdata->offset = (cdata->offset + 7) / 8;
+ if ( cdata->output_stream(cdata, buf, cdata->offset ) != cdata->offset )
+ {
+ return 0;
+ }
+ cdata->bytes_out += cdata->offset;
+ }
+ cdata->offset = 0;
+ (void)fflush( stdout );
+ if( ferror( stdout ) )
+ {
+ return 0;
+ }
+#ifdef DEBUG
+ if ( verbose )
+ {
+ fprintf( stderr, "\n" );
+ }
+#endif
+ }
+ return 1;
+}
+
+/*
+ * compress stdin to stdout
+ *
+ * Algorithm: use open addressing double hashing (no chaining) on the
+ * prefix code / next character combination. We do a variant of Knuth's
+ * algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
+ * secondary probe. Here, the modular division first probe is gives way
+ * to a faster exclusive-or manipulation. Also do block compression with
+ * an adaptive reset, whereby the code table is cleared when the compression
+ * ratio decreases, but after the table fills. The variable-length output
+ * codes are re-sized at this point, and a special CLEAR code is generated
+ * for the decompressor. Late addition: construct the table according to
+ * file size for noticeable speed improvement on small files. Please direct
+ * questions about this implementation to ames!jaw.
+ */
+
+int cmcompress_compress_start(struct cmcompress_stream* cdata)
+{
+#ifndef COMPATIBLE
+ if (cdata->nomagic == 0)
+ {
+ char headLast = (char)(cdata->maxbits | cdata->block_compress);
+ cdata->output_stream(cdata, (const char*)magic_header, 2);
+ cdata->output_stream(cdata, &headLast, 1);
+ if(ferror(stdout))
+ {
+ printf("Error...\n");
+ }
+ }
+#endif /* COMPATIBLE */
+
+ cdata->offset = 0;
+ cdata->bytes_out = 3; /* includes 3-byte header mojo */
+ cdata->out_count = 0;
+ cdata->clear_flg = 0;
+ cdata->ratio = 0;
+ cdata->in_count = 1;
+ cdata->checkpoint = CHECK_GAP;
+ cdata->maxcode = MAXCODE(cdata->n_bits = INIT_BITS);
+ cdata->free_ent = ((cdata->block_compress) ? FIRST : 256 );
+
+ cdata->first_pass = 1;
+
+ cdata->hshift = 0;
+ for ( cdata->fcode = (long) cdata->hsize; cdata->fcode < 65536L; cdata->fcode *= 2L )
+ {
+ cdata->hshift++;
+ }
+ cdata->hshift = 8 - cdata->hshift; /* set hash code range bound */
+
+ cdata->hsize_reg = cdata->hsize;
+ cl_hash(cdata, (count_int) cdata->hsize_reg); /* clear hash table */
+
+ return 1;
+}
+
+static int cl_block (struct cmcompress_stream* cdata) /* table clear for block compress */
+{
+ register long int rat;
+
+ cdata->checkpoint = cdata->in_count + CHECK_GAP;
+#ifdef DEBUG
+ if ( cdata->debug )
+ {
+ fprintf ( stderr, "count: %ld, ratio: ", cdata->in_count );
+ prratio ( stderr, cdata->in_count, cdata->bytes_out );
+ fprintf ( stderr, "\n");
+ }
+#endif /* DEBUG */
+
+ if(cdata->in_count > 0x007fffff)
+ { /* shift will overflow */
+ rat = cdata->bytes_out >> 8;
+ if(rat == 0)
+ { /* Don't divide by zero */
+ rat = 0x7fffffff;
+ }
+ else
+ {
+ rat = cdata->in_count / rat;
+ }
+ }
+ else
+ {
+ rat = (cdata->in_count << 8) / cdata->bytes_out; /* 8 fractional bits */
+ }
+ if ( rat > cdata->ratio )
+ {
+ cdata->ratio = rat;
+ }
+ else
+ {
+ cdata->ratio = 0;
+#ifdef DEBUG
+ if(cdata->verbose)
+ {
+ dump_tab(); /* dump string table */
+ }
+#endif
+ cl_hash (cdata, (count_int) cdata->hsize );
+ cdata->free_ent = FIRST;
+ cdata->clear_flg = 1;
+ if ( !output (cdata, (code_int) CLEAR ) )
+ {
+ return 0;
+ }
+#ifdef DEBUG
+ if(cdata->debug)
+ {
+ fprintf ( stderr, "clear\n" );
+ }
+#endif /* DEBUG */
+ }
+ return 1;
+}
+
+
+int cmcompress_compress(struct cmcompress_stream* cdata, void* buff, size_t n)
+{
+ register code_int i;
+ register int c;
+ register int disp;
+
+ unsigned char* input_buffer = (unsigned char*)buff;
+
+ size_t cc;
+
+ /*printf("cmcompress_compress(%p, %p, %d)\n", cdata, buff, n);*/
+
+ if ( cdata->first_pass )
+ {
+ cdata->ent = input_buffer[0];
+ ++ input_buffer;
+ -- n;
+ cdata->first_pass = 0;
+ }
+
+ for ( cc = 0; cc < n; ++ cc )
+ {
+ c = input_buffer[cc];
+ cdata->in_count++;
+ cdata->fcode = (long) (((long) c << cdata->maxbits) + cdata->ent);
+ i = ((c << cdata->hshift) ^ cdata->ent); /* xor hashing */
+
+ if ( htabof (i) == cdata->fcode )
+ {
+ cdata->ent = codetabof (i);
+ continue;
+ }
+ else if ( (long)htabof (i) < 0 ) /* empty slot */
+ {
+ goto nomatch;
+ }
+ disp = (int)(cdata->hsize_reg - i); /* secondary hash (after G. Knott) */
+ if ( i == 0 )
+ {
+ disp = 1;
+ }
+probe:
+ if ( (i -= disp) < 0 )
+ {
+ i += cdata->hsize_reg;
+ }
+
+ if ( htabof (i) == cdata->fcode )
+ {
+ cdata->ent = codetabof (i);
+ continue;
+ }
+ if ( (long)htabof (i) > 0 )
+ {
+ goto probe;
+ }
+nomatch:
+ if ( !output(cdata, (code_int) cdata->ent ) )
+ {
+ return 0;
+ }
+ cdata->out_count++;
+ cdata->ent = c;
+ if (
+#ifdef SIGNED_COMPARE_SLOW
+ (unsigned) cdata->free_ent < (unsigned) cdata->maxmaxcode
+#else
+ cdata->free_ent < cdata->maxmaxcode
+#endif
+ )
+ {
+ codetabof (i) = (unsigned short)(cdata->free_ent++); /* code -> hashtable */
+ htabof (i) = cdata->fcode;
+ }
+ else if ( (count_int)cdata->in_count >= cdata->checkpoint && cdata->block_compress )
+ {
+ if ( !cl_block (cdata) )
+ {
+ return 0;
+ }
+ }
+ }
+
+ return 1;
+}
+
+int cmcompress_compress_finalize(struct cmcompress_stream* cdata)
+{
+ /*
+ * Put out the final code.
+ */
+ if ( !output(cdata, (code_int)cdata->ent ) )
+ {
+ return 0;
+ }
+ cdata->out_count++;
+ if ( !output(cdata, (code_int)-1 ) )
+ {
+ return 0;
+ }
+
+ if(cdata->bytes_out > cdata->in_count) /* exit(2) if no savings */
+ {
+ return 0;
+ }
+ return 1;
+}
+
+
+#if defined(DEBUG)
+static void prratio(FILE *stream, long int num, long int den)
+{
+ register int q; /* Doesn't need to be long */
+
+ if(num > 214748L)
+ { /* 2147483647/10000 */
+ q = num / (den / 10000L);
+ }
+ else
+ {
+ q = 10000L * num / den; /* Long calculations, though */
+ }
+ if (q < 0)
+ {
+ putc('-', stream);
+ q = -q;
+ }
+ fprintf(stream, "%d.%02d%%", q / 100, q % 100);
+}
+#endif
+
diff --git a/Utilities/cmcompress/cmcompress.h b/Utilities/cmcompress/cmcompress.h
new file mode 100644
index 000000000..fdb0d90b7
--- /dev/null
+++ b/Utilities/cmcompress/cmcompress.h
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 1985, 1986 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * James A. Woods, derived from original work by Spencer Thomas
+ * and Joseph Orost.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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 __cmcompress__h_
+#define __cmcompress__h_
+
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ /*
+ * Set USERMEM to the maximum amount of physical user memory available
+ * in bytes. USERMEM is used to determine the maximum BITS that can be used
+ * for compression.
+ *
+ * SACREDMEM is the amount of physical memory saved for others; compress
+ * will hog the rest.
+ */
+#ifndef SACREDMEM
+#define SACREDMEM 0
+#endif
+
+#ifndef USERMEM
+# define USERMEM 450000 /* default user memory */
+#endif
+
+#ifdef pdp11
+# define BITS 12 /* max bits/code for 16-bit machine */
+# define NO_UCHAR /* also if "unsigned char" functions as signed char */
+# undef USERMEM
+#endif /* pdp11 */ /* don't forget to compile with -i */
+
+#ifdef USERMEM
+# if USERMEM >= (433484+SACREDMEM)
+# define PBITS 16
+# else
+# if USERMEM >= (229600+SACREDMEM)
+# define PBITS 15
+# else
+# if USERMEM >= (127536+SACREDMEM)
+# define PBITS 14
+# else
+# if USERMEM >= (73464+SACREDMEM)
+# define PBITS 13
+# else
+# define PBITS 12
+# endif
+# endif
+# endif
+# endif
+# undef USERMEM
+#endif /* USERMEM */
+
+#ifdef PBITS /* Preferred BITS for this memory size */
+# ifndef BITS
+# define BITS PBITS
+# endif /* BITS */
+#endif /* PBITS */
+
+#if BITS == 16
+# define HSIZE 69001 /* 95% occupancy */
+#endif
+#if BITS == 15
+# define HSIZE 35023 /* 94% occupancy */
+#endif
+#if BITS == 14
+# define HSIZE 18013 /* 91% occupancy */
+#endif
+#if BITS == 13
+# define HSIZE 9001 /* 91% occupancy */
+#endif
+#if BITS <= 12
+# define HSIZE 5003 /* 80% occupancy */
+#endif
+
+ /*
+ * a code_int must be able to hold 2**BITS values of type int, and also -1
+ */
+#if BITS > 15
+ typedef long int code_int;
+#else
+ typedef int code_int;
+#endif
+
+#ifdef SIGNED_COMPARE_SLOW
+ typedef unsigned long int count_int;
+ typedef unsigned short int count_short;
+#else
+ typedef long int count_int;
+#endif
+
+#ifdef NO_UCHAR
+ typedef char char_type;
+#else
+ typedef unsigned char char_type;
+#endif /* UCHAR */
+
+
+
+ struct cmcompress_stream
+ {
+ int n_bits; /* number of bits/code */
+ int maxbits; /* user settable max # bits/code */
+ code_int maxcode; /* maximum code, given n_bits */
+ code_int maxmaxcode; /* should NEVER generate this code */
+
+ count_int htab [HSIZE];
+ unsigned short codetab [HSIZE];
+
+ code_int hsize; /* for dynamic table sizing */
+ code_int free_ent; /* first unused entry */
+ int nomagic; /* Use a 3-byte magic number header, unless old file */
+
+ /*
+ * block compression parameters -- after all codes are used up,
+ * and compression rate changes, start over.
+ */
+ int block_compress;
+ int clear_flg;
+ long int ratio;
+ count_int checkpoint;
+
+#ifdef DEBUG
+ int debug;
+ int verbose;
+#endif
+
+ /* compress internals */
+ int offset;
+ long int in_count; /* length of input */
+ long int bytes_out; /* length of compressed output */
+ long int out_count; /* # of codes output (for debugging) */
+
+ /* internals */
+ code_int ent;
+ code_int hsize_reg;
+ int hshift;
+
+ long fcode;
+ int first_pass;
+
+ /* For input and output */
+ int (*input_stream)(void*);
+ int (*output_stream)(void*, const char*,int);
+ void* client_data;
+ };
+
+ int cmcompress_compress_initialize(struct cmcompress_stream* cdata);
+ int cmcompress_compress_start(struct cmcompress_stream* cdata);
+ int cmcompress_compress(struct cmcompress_stream* cdata, void* buff, size_t n);
+ int cmcompress_compress_finalize(struct cmcompress_stream* cdata);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* __cmcompress__h_ */
diff --git a/Utilities/cmcompress/compress.c.original b/Utilities/cmcompress/compress.c.original
new file mode 100644
index 000000000..5062bda98
--- /dev/null
+++ b/Utilities/cmcompress/compress.c.original
@@ -0,0 +1,1308 @@
+/*
+ * Copyright (c) 1985, 1986 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * James A. Woods, derived from original work by Spencer Thomas
+ * and Joseph Orost.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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 lint
+char copyright[] =
+"@(#) Copyright (c) 1985, 1986 The Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)compress.c 5.19 (Berkeley) 3/18/91";
+#endif /* not lint */
+
+/*
+ * compress.c - File compression ala IEEE Computer, June 1984.
+ *
+ * Authors: Spencer W. Thomas (decvax!utah-cs!thomas)
+ * Jim McKie (decvax!mcvax!jim)
+ * Steve Davies (decvax!vax135!petsd!peora!srd)
+ * Ken Turkowski (decvax!decwrl!turtlevax!ken)
+ * James A. Woods (decvax!ihnp4!ames!jaw)
+ * Joe Orost (decvax!vax135!petsd!joe)
+ */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <signal.h>
+#include <utime.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
+/*
+ * Set USERMEM to the maximum amount of physical user memory available
+ * in bytes. USERMEM is used to determine the maximum BITS that can be used
+ * for compression.
+ *
+ * SACREDMEM is the amount of physical memory saved for others; compress
+ * will hog the rest.
+ */
+#ifndef SACREDMEM
+#define SACREDMEM 0
+#endif
+
+#ifndef USERMEM
+# define USERMEM 450000 /* default user memory */
+#endif
+
+#ifdef pdp11
+# define BITS 12 /* max bits/code for 16-bit machine */
+# define NO_UCHAR /* also if "unsigned char" functions as signed char */
+# undef USERMEM
+#endif /* pdp11 */ /* don't forget to compile with -i */
+
+#ifdef USERMEM
+# if USERMEM >= (433484+SACREDMEM)
+# define PBITS 16
+# else
+# if USERMEM >= (229600+SACREDMEM)
+# define PBITS 15
+# else
+# if USERMEM >= (127536+SACREDMEM)
+# define PBITS 14
+# else
+# if USERMEM >= (73464+SACREDMEM)
+# define PBITS 13
+# else
+# define PBITS 12
+# endif
+# endif
+# endif
+# endif
+# undef USERMEM
+#endif /* USERMEM */
+
+#ifdef PBITS /* Preferred BITS for this memory size */
+# ifndef BITS
+# define BITS PBITS
+# endif BITS
+#endif /* PBITS */
+
+#if BITS == 16
+# define HSIZE 69001 /* 95% occupancy */
+#endif
+#if BITS == 15
+# define HSIZE 35023 /* 94% occupancy */
+#endif
+#if BITS == 14
+# define HSIZE 18013 /* 91% occupancy */
+#endif
+#if BITS == 13
+# define HSIZE 9001 /* 91% occupancy */
+#endif
+#if BITS <= 12
+# define HSIZE 5003 /* 80% occupancy */
+#endif
+
+/*
+ * a code_int must be able to hold 2**BITS values of type int, and also -1
+ */
+#if BITS > 15
+typedef long int code_int;
+#else
+typedef int code_int;
+#endif
+
+#ifdef SIGNED_COMPARE_SLOW
+typedef unsigned long int count_int;
+typedef unsigned short int count_short;
+#else
+typedef long int count_int;
+#endif
+
+#ifdef NO_UCHAR
+ typedef char char_type;
+#else
+ typedef unsigned char char_type;
+#endif /* UCHAR */
+char_type magic_header[] = { "\037\235" }; /* 1F 9D */
+
+/* Defines for third byte of header */
+#define BIT_MASK 0x1f
+#define BLOCK_MASK 0x80
+/* Masks 0x40 and 0x20 are free. I think 0x20 should mean that there is
+ a fourth header byte (for expansion).
+*/
+#define INIT_BITS 9 /* initial number of bits/code */
+
+int n_bits; /* number of bits/code */
+int maxbits = BITS; /* user settable max # bits/code */
+code_int maxcode; /* maximum code, given n_bits */
+code_int maxmaxcode = 1 << BITS; /* should NEVER generate this code */
+#ifdef COMPATIBLE /* But wrong! */
+# define MAXCODE(n_bits) (1 << (n_bits) - 1)
+#else
+# define MAXCODE(n_bits) ((1 << (n_bits)) - 1)
+#endif /* COMPATIBLE */
+
+count_int htab [HSIZE];
+unsigned short codetab [HSIZE];
+
+#define htabof(i) htab[i]
+#define codetabof(i) codetab[i]
+code_int hsize = HSIZE; /* for dynamic table sizing */
+count_int fsize;
+
+/*
+ * To save much memory, we overlay the table used by compress() with those
+ * used by decompress(). The tab_prefix table is the same size and type
+ * as the codetab. The tab_suffix table needs 2**BITS characters. We
+ * get this from the beginning of htab. The output stack uses the rest
+ * of htab, and contains characters. There is plenty of room for any
+ * possible stack (stack used to be 8000 characters).
+ */
+
+#define tab_prefixof(i) codetabof(i)
+# define tab_suffixof(i) ((char_type *)(htab))[i]
+# define de_stack ((char_type *)&tab_suffixof(1<<BITS))
+
+code_int free_ent = 0; /* first unused entry */
+int exit_stat = 0; /* per-file status */
+int perm_stat = 0; /* permanent status */
+
+code_int getcode();
+
+int nomagic = 0; /* Use a 3-byte magic number header, unless old file */
+int zcat_flg = 0; /* Write output on stdout, suppress messages */
+int precious = 1; /* Don't unlink output file on interrupt */
+int quiet = 1; /* don't tell me about compression */
+
+/*
+ * block compression parameters -- after all codes are used up,
+ * and compression rate changes, start over.
+ */
+int block_compress = BLOCK_MASK;
+int clear_flg = 0;
+long int ratio = 0;
+#define CHECK_GAP 10000 /* ratio check interval */
+count_int checkpoint = CHECK_GAP;
+/*
+ * the next two codes should not be changed lightly, as they must not
+ * lie within the contiguous general code space.
+ */
+#define FIRST 257 /* first free entry */
+#define CLEAR 256 /* table clear output code */
+
+int force = 0;
+char ofname [100];
+#ifdef DEBUG
+int debug, verbose;
+#endif
+sig_t oldint;
+int bgnd_flag;
+
+int do_decomp = 0;
+
+/*-
+ * Algorithm from "A Technique for High Performance Data Compression",
+ * Terry A. Welch, IEEE Computer Vol 17, No 6 (June 1984), pp 8-19.
+ *
+ * Usage: compress [-dfvc] [-b bits] [file ...]
+ * Inputs:
+ * -d: If given, decompression is done instead.
+ *
+ * -c: Write output on stdout, don't remove original.
+ *
+ * -b: Parameter limits the max number of bits/code.
+ *
+ * -f: Forces output file to be generated, even if one already
+ * exists, and even if no space is saved by compressing.
+ * If -f is not used, the user will be prompted if stdin is
+ * a tty, otherwise, the output file will not be overwritten.
+ *
+ * -v: Write compression statistics
+ *
+ * file ...: Files to be compressed. If none specified, stdin
+ * is used.
+ * Outputs:
+ * file.Z: Compressed form of file with same mode, owner, and utimes
+ * or stdout (if stdin used as input)
+ *
+ * Assumptions:
+ * When filenames are given, replaces with the compressed version
+ * (.Z suffix) only if the file decreases in size.
+ * Algorithm:
+ * Modified Lempel-Ziv method (LZW). Basically finds common
+ * substrings and replaces them with a variable size code. This is
+ * deterministic, and can be done on the fly. Thus, the decompression
+ * procedure needs no input table, but tracks the way the table was built.
+ */
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ extern int optind;
+ extern char *optarg;
+ struct stat statbuf;
+ int ch, overwrite;
+ char **filelist, **fileptr, *cp, tempname[MAXPATHLEN];
+ void onintr(), oops();
+
+ /* This bg check only works for sh. */
+ if ((oldint = signal(SIGINT, SIG_IGN)) != SIG_IGN) {
+ (void)signal(SIGINT, onintr);
+ (void)signal(SIGSEGV, oops); /* XXX */
+ }
+ bgnd_flag = oldint != SIG_DFL;
+
+#ifdef COMPATIBLE
+ nomagic = 1; /* Original didn't have a magic number */
+#endif
+
+ if (cp = rindex(argv[0], '/'))
+ ++cp;
+ else
+ cp = argv[0];
+ if (strcmp(cp, "uncompress") == 0)
+ do_decomp = 1;
+ else if(strcmp(cp, "zcat") == 0) {
+ do_decomp = 1;
+ zcat_flg = 1;
+ }
+
+ /*
+ * -b maxbits => maxbits.
+ * -C => generate output compatible with compress 2.0.
+ * -c => cat all output to stdout
+ * -D => debug
+ * -d => do_decomp
+ * -f => force overwrite of output file
+ * -n => no header: useful to uncompress old files
+ * -V => print Version; debug verbose
+ * -v => unquiet
+ */
+
+ overwrite = 0;
+#ifdef DEBUG
+ while ((ch = getopt(argc, argv, "b:CcDdfnVv")) != EOF)
+#else
+ while ((ch = getopt(argc, argv, "b:Ccdfnv")) != EOF)
+#endif
+ switch(ch) {
+ case 'b':
+ maxbits = atoi(optarg);
+ break;
+ case 'C':
+ block_compress = 0;
+ break;
+ case 'c':
+ zcat_flg = 1;
+ break;
+#ifdef DEBUG
+ case 'D':
+ debug = 1;
+ break;
+#endif
+ case 'd':
+ do_decomp = 1;
+ break;
+ case 'f':
+ overwrite = 1;
+ force = 1;
+ break;
+ case 'n':
+ nomagic = 1;
+ break;
+ case 'q':
+ quiet = 1;
+ break;
+#ifdef DEBUG
+ case 'V':
+ verbose = 1;
+ break;
+#endif
+ case 'v':
+ quiet = 0;
+ break;
+ case '?':
+ default:
+ usage();
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (maxbits < INIT_BITS)
+ maxbits = INIT_BITS;
+ if (maxbits > BITS)
+ maxbits = BITS;
+ maxmaxcode = 1 << maxbits;
+
+ /* Build useless input file list. */
+ filelist = fileptr = (char **)(malloc(argc * sizeof(*argv)));
+ while (*argv)
+ *fileptr++ = *argv++;
+ *fileptr = NULL;
+
+ if (*filelist != NULL) {
+ for (fileptr = filelist; *fileptr; fileptr++) {
+ exit_stat = 0;
+ if (do_decomp) { /* DECOMPRESSION */
+ /* Check for .Z suffix */
+ if (strcmp(*fileptr + strlen(*fileptr) - 2, ".Z") != 0) {
+ /* No .Z: tack one on */
+ strcpy(tempname, *fileptr);
+ strcat(tempname, ".Z");
+ *fileptr = tempname;
+ }
+ /* Open input file */
+ if ((freopen(*fileptr, "r", stdin)) == NULL) {
+ perror(*fileptr);
+ perm_stat = 1;
+ continue;
+ }
+ /* Check the magic number */
+ if (nomagic == 0) {
+ if ((getchar() != (magic_header[0] & 0xFF))
+ || (getchar() != (magic_header[1] & 0xFF))) {
+ fprintf(stderr, "%s: not in compressed format\n",
+ *fileptr);
+ continue;
+ }
+ maxbits = getchar(); /* set -b from file */
+ block_compress = maxbits & BLOCK_MASK;
+ maxbits &= BIT_MASK;
+ maxmaxcode = 1 << maxbits;
+ if(maxbits > BITS) {
+ fprintf(stderr,
+ "%s: compressed with %d bits, can only handle %d bits\n",
+ *fileptr, maxbits, BITS);
+ continue;
+ }
+ }
+ /* Generate output filename */
+ strcpy(ofname, *fileptr);
+ ofname[strlen(*fileptr) - 2] = '\0'; /* Strip off .Z */
+ } else { /* COMPRESSION */
+ if (strcmp(*fileptr + strlen(*fileptr) - 2, ".Z") == 0) {
+ fprintf(stderr, "%s: already has .Z suffix -- no change\n",
+ *fileptr);
+ continue;
+ }
+ /* Open input file */
+ if ((freopen(*fileptr, "r", stdin)) == NULL) {
+ perror(*fileptr);
+ perm_stat = 1;
+ continue;
+ }
+ stat ( *fileptr, &statbuf );
+ fsize = (long) statbuf.st_size;
+ /*
+ * tune hash table size for small files -- ad hoc,
+ * but the sizes match earlier #defines, which
+ * serve as upper bounds on the number of output codes.
+ */
+ hsize = HSIZE;
+ if ( fsize < (1 << 12) )
+ hsize = MIN ( 5003, HSIZE );
+ else if ( fsize < (1 << 13) )
+ hsize = MIN ( 9001, HSIZE );
+ else if ( fsize < (1 << 14) )
+ hsize = MIN ( 18013, HSIZE );
+ else if ( fsize < (1 << 15) )
+ hsize = MIN ( 35023, HSIZE );
+ else if ( fsize < 47000 )
+ hsize = MIN ( 50021, HSIZE );
+
+ /* Generate output filename */
+ strcpy(ofname, *fileptr);
+ strcat(ofname, ".Z");
+ }
+ /* Check for overwrite of existing file */
+ if (overwrite == 0 && zcat_flg == 0) {
+ if (stat(ofname, &statbuf) == 0) {
+ char response[2];
+ response[0] = 'n';
+ fprintf(stderr, "%s already exists;", ofname);
+ if (bgnd_flag == 0 && isatty(2)) {
+ fprintf(stderr, " do you wish to overwrite %s (y or n)? ",
+ ofname);
+ fflush(stderr);
+ read(2, response, 2);
+ while (response[1] != '\n') {
+ if (read(2, response+1, 1) < 0) { /* Ack! */
+ perror("stderr"); break;
+ }
+ }
+ }
+ if (response[0] != 'y') {
+ fprintf(stderr, "\tnot overwritten\n");
+ continue;
+ }
+ }
+ }
+ if(zcat_flg == 0) { /* Open output file */
+ if (freopen(ofname, "w", stdout) == NULL) {
+ perror(ofname);
+ perm_stat = 1;
+ continue;
+ }
+ precious = 0;
+ if(!quiet)
+ fprintf(stderr, "%s: ", *fileptr);
+ }
+
+ /* Actually do the compression/decompression */
+ if (do_decomp == 0) compress();
+#ifndef DEBUG
+ else decompress();
+#else
+ else if (debug == 0) decompress();
+ else printcodes();
+ if (verbose) dump_tab();
+#endif /* DEBUG */
+ if(zcat_flg == 0) {
+ copystat(*fileptr, ofname); /* Copy stats */
+ precious = 1;
+ if((exit_stat == 1) || (!quiet))
+ putc('\n', stderr);
+ }
+ }
+ } else { /* Standard input */
+ if (do_decomp == 0) {
+ compress();
+#ifdef DEBUG
+ if(verbose) dump_tab();
+#endif /* DEBUG */
+ if(!quiet)
+ putc('\n', stderr);
+ } else {
+ /* Check the magic number */
+ if (nomagic == 0) {
+ if ((getchar()!=(magic_header[0] & 0xFF))
+ || (getchar()!=(magic_header[1] & 0xFF))) {
+ fprintf(stderr, "stdin: not in compressed format\n");
+ exit(1);
+ }
+ maxbits = getchar(); /* set -b from file */
+ block_compress = maxbits & BLOCK_MASK;
+ maxbits &= BIT_MASK;
+ maxmaxcode = 1 << maxbits;
+ fsize = 100000; /* assume stdin large for USERMEM */
+ if(maxbits > BITS) {
+ fprintf(stderr,
+ "stdin: compressed with %d bits, can only handle %d bits\n",
+ maxbits, BITS);
+ exit(1);
+ }
+ }
+#ifndef DEBUG
+ decompress();
+#else
+ if (debug == 0) decompress();
+ else printcodes();
+ if (verbose) dump_tab();
+#endif /* DEBUG */
+ }
+ }
+ exit(perm_stat ? perm_stat : exit_stat);
+}
+
+static int offset;
+long int in_count = 1; /* length of input */
+long int bytes_out; /* length of compressed output */
+long int out_count = 0; /* # of codes output (for debugging) */
+
+/*
+ * compress stdin to stdout
+ *
+ * Algorithm: use open addressing double hashing (no chaining) on the
+ * prefix code / next character combination. We do a variant of Knuth's
+ * algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
+ * secondary probe. Here, the modular division first probe is gives way
+ * to a faster exclusive-or manipulation. Also do block compression with
+ * an adaptive reset, whereby the code table is cleared when the compression
+ * ratio decreases, but after the table fills. The variable-length output
+ * codes are re-sized at this point, and a special CLEAR code is generated
+ * for the decompressor. Late addition: construct the table according to
+ * file size for noticeable speed improvement on small files. Please direct
+ * questions about this implementation to ames!jaw.
+ */
+
+compress()
+{
+ register long fcode;
+ register code_int i = 0;
+ register int c;
+ register code_int ent;
+ register int disp;
+ register code_int hsize_reg;
+ register int hshift;
+
+#ifndef COMPATIBLE
+ if (nomagic == 0) {
+ putchar(magic_header[0]);
+ putchar(magic_header[1]);
+ putchar((char)(maxbits | block_compress));
+ if(ferror(stdout))
+ writeerr();
+ }
+#endif /* COMPATIBLE */
+
+ offset = 0;
+ bytes_out = 3; /* includes 3-byte header mojo */
+ out_count = 0;
+ clear_flg = 0;
+ ratio = 0;
+ in_count = 1;
+ checkpoint = CHECK_GAP;
+ maxcode = MAXCODE(n_bits = INIT_BITS);
+ free_ent = ((block_compress) ? FIRST : 256 );
+
+ ent = getchar ();
+
+ hshift = 0;
+ for ( fcode = (long) hsize; fcode < 65536L; fcode *= 2L )
+ hshift++;
+ hshift = 8 - hshift; /* set hash code range bound */
+
+ hsize_reg = hsize;
+ cl_hash( (count_int) hsize_reg); /* clear hash table */
+
+#ifdef SIGNED_COMPARE_SLOW
+ while ( (c = getchar()) != (unsigned) EOF ) {
+#else
+ while ( (c = getchar()) != EOF ) {
+#endif
+ in_count++;
+ fcode = (long) (((long) c << maxbits) + ent);
+ i = ((c << hshift) ^ ent); /* xor hashing */
+
+ if ( htabof (i) == fcode ) {
+ ent = codetabof (i);
+ continue;
+ } else if ( (long)htabof (i) < 0 ) /* empty slot */
+ goto nomatch;
+ disp = hsize_reg - i; /* secondary hash (after G. Knott) */
+ if ( i == 0 )
+ disp = 1;
+probe:
+ if ( (i -= disp) < 0 )
+ i += hsize_reg;
+
+ if ( htabof (i) == fcode ) {
+ ent = codetabof (i);
+ continue;
+ }
+ if ( (long)htabof (i) > 0 )
+ goto probe;
+nomatch:
+ output ( (code_int) ent );
+ out_count++;
+ ent = c;
+#ifdef SIGNED_COMPARE_SLOW
+ if ( (unsigned) free_ent < (unsigned) maxmaxcode) {
+#else
+ if ( free_ent < maxmaxcode ) {
+#endif
+ codetabof (i) = free_ent++; /* code -> hashtable */
+ htabof (i) = fcode;
+ }
+ else if ( (count_int)in_count >= checkpoint && block_compress )
+ cl_block ();
+ }
+ /*
+ * Put out the final code.
+ */
+ output( (code_int)ent );
+ out_count++;
+ output( (code_int)-1 );
+
+ /*
+ * Print out stats on stderr
+ */
+ if(zcat_flg == 0 && !quiet) {
+#ifdef DEBUG
+ fprintf( stderr,
+ "%ld chars in, %ld codes (%ld bytes) out, compression factor: ",
+ in_count, out_count, bytes_out );
+ prratio( stderr, in_count, bytes_out );
+ fprintf( stderr, "\n");
+ fprintf( stderr, "\tCompression as in compact: " );
+ prratio( stderr, in_count-bytes_out, in_count );
+ fprintf( stderr, "\n");
+ fprintf( stderr, "\tLargest code (of last block) was %d (%d bits)\n",
+ free_ent - 1, n_bits );
+#else /* !DEBUG */
+ fprintf( stderr, "Compression: " );
+ prratio( stderr, in_count-bytes_out, in_count );
+#endif /* DEBUG */
+ }
+ if(bytes_out > in_count) /* exit(2) if no savings */
+ exit_stat = 2;
+ return;
+}
+
+/*-
+ * Output the given code.
+ * Inputs:
+ * code: A n_bits-bit integer. If == -1, then EOF. This assumes
+ * that n_bits =< (long)wordsize - 1.
+ * Outputs:
+ * Outputs code to the file.
+ * Assumptions:
+ * Chars are 8 bits long.
+ * Algorithm:
+ * Maintain a BITS character long buffer (so that 8 codes will
+ * fit in it exactly). Use the VAX insv instruction to insert each
+ * code in turn. When the buffer fills up empty it and start over.
+ */
+
+static char buf[BITS];
+
+#ifndef vax
+char_type lmask[9] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00};
+char_type rmask[9] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
+#endif /* vax */
+
+output( code )
+code_int code;
+{
+#ifdef DEBUG
+ static int col = 0;
+#endif /* DEBUG */
+
+ /*
+ * On the VAX, it is important to have the register declarations
+ * in exactly the order given, or the asm will break.
+ */
+ register int r_off = offset, bits= n_bits;
+ register char * bp = buf;
+
+#ifdef DEBUG
+ if ( verbose )
+ fprintf( stderr, "%5d%c", code,
+ (col+=6) >= 74 ? (col = 0, '\n') : ' ' );
+#endif /* DEBUG */
+ if ( code >= 0 ) {
+#if defined(vax) && !defined(__GNUC__)
+ /*
+ * VAX and PCC DEPENDENT!! Implementation on other machines is
+ * below.
+ *
+ * Translation: Insert BITS bits from the argument starting at
+ * offset bits from the beginning of buf.
+ */
+ 0; /* Work around for pcc -O bug with asm and if stmt */
+ asm( "insv 4(ap),r11,r10,(r9)" );
+#else
+/*
+ * byte/bit numbering on the VAX is simulated by the following code
+ */
+ /*
+ * Get to the first byte.
+ */
+ bp += (r_off >> 3);
+ r_off &= 7;
+ /*
+ * Since code is always >= 8 bits, only need to mask the first
+ * hunk on the left.
+ */
+ *bp = (*bp & rmask[r_off]) | (code << r_off) & lmask[r_off];
+ bp++;
+ bits -= (8 - r_off);
+ code >>= 8 - r_off;
+ /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
+ if ( bits >= 8 ) {
+ *bp++ = code;
+ code >>= 8;
+ bits -= 8;
+ }
+ /* Last bits. */
+ if(bits)
+ *bp = code;
+#endif /* vax */
+ offset += n_bits;
+ if ( offset == (n_bits << 3) ) {
+ bp = buf;
+ bits = n_bits;
+ bytes_out += bits;
+ do {
+ putchar(*bp++);
+ if (ferror(stdout))
+ writeerr();
+ } while(--bits);
+ offset = 0;
+ }
+
+ /*
+ * If the next entry is going to be too big for the code size,
+ * then increase it, if possible.
+ */
+ if ( free_ent > maxcode || (clear_flg > 0))
+ {
+ /*
+ * Write the whole buffer, because the input side won't
+ * discover the size increase until after it has read it.
+ */
+ if ( offset > 0 ) {
+ if( fwrite( buf, 1, n_bits, stdout ) != n_bits)
+ writeerr();
+ bytes_out += n_bits;
+ }
+ offset = 0;
+
+ if ( clear_flg ) {
+ maxcode = MAXCODE (n_bits = INIT_BITS);
+ clear_flg = 0;
+ }
+ else {
+ n_bits++;
+ if ( n_bits == maxbits )
+ maxcode = maxmaxcode;
+ else
+ maxcode = MAXCODE(n_bits);
+ }
+#ifdef DEBUG
+ if ( debug ) {
+ fprintf( stderr, "\nChange to %d bits\n", n_bits );
+ col = 0;
+ }
+#endif /* DEBUG */
+ }
+ } else {
+ /*
+ * At EOF, write the rest of the buffer.
+ */
+ if ( offset > 0 ) {
+ offset = (offset + 7) / 8;
+ if( fwrite( buf, 1, offset, stdout ) != offset )
+ writeerr();
+ bytes_out += offset;
+ }
+ offset = 0;
+ (void)fflush( stdout );
+ if( ferror( stdout ) )
+ writeerr();
+#ifdef DEBUG
+ if ( verbose )
+ fprintf( stderr, "\n" );
+#endif
+ }
+}
+
+/*
+ * Decompress stdin to stdout. This routine adapts to the codes in the
+ * file building the "string" table on-the-fly; requiring no table to
+ * be stored in the compressed file. The tables used herein are shared
+ * with those of the compress() routine. See the definitions above.
+ */
+
+decompress() {
+ register char_type *stackp;
+ register int finchar;
+ register code_int code, oldcode, incode;
+ int n, nwritten, offset; /* Variables for buffered write */
+ char buff[BUFSIZ]; /* Buffer for buffered write */
+
+
+ /*
+ * As above, initialize the first 256 entries in the table.
+ */
+ maxcode = MAXCODE(n_bits = INIT_BITS);
+ for ( code = 255; code >= 0; code-- ) {
+ tab_prefixof(code) = 0;
+ tab_suffixof(code) = (char_type)code;
+ }
+ free_ent = ((block_compress) ? FIRST : 256 );
+
+ finchar = oldcode = getcode();
+ if(oldcode == -1) /* EOF already? */
+ return; /* Get out of here */
+
+ /* first code must be 8 bits = char */
+ n=0;
+ buff[n++] = (char)finchar;
+
+ stackp = de_stack;
+
+ while ( (code = getcode()) > -1 ) {
+
+ if ( (code == CLEAR) && block_compress ) {
+ for ( code = 255; code >= 0; code-- )
+ tab_prefixof(code) = 0;
+ clear_flg = 1;
+ free_ent = FIRST - 1;
+ if ( (code = getcode ()) == -1 ) /* O, untimely death! */
+ break;
+ }
+ incode = code;
+ /*
+ * Special case for KwKwK string.
+ */
+ if ( code >= free_ent ) {
+ *stackp++ = finchar;
+ code = oldcode;
+ }
+
+ /*
+ * Generate output characters in reverse order
+ */
+#ifdef SIGNED_COMPARE_SLOW
+ while ( ((unsigned long)code) >= ((unsigned long)256) ) {
+#else
+ while ( code >= 256 ) {
+#endif
+ *stackp++ = tab_suffixof(code);
+ code = tab_prefixof(code);
+ }
+ *stackp++ = finchar = tab_suffixof(code);
+
+ /*
+ * And put them out in forward order
+ */
+ do {
+ /*
+ * About 60% of the time is spent in the putchar() call
+ * that appeared here. It was originally
+ * putchar ( *--stackp );
+ * If we buffer the writes ourselves, we can go faster (about
+ * 30%).
+ *
+ * At this point, the next line is the next *big* time
+ * sink in the code. It takes up about 10% of the time.
+ */
+ buff[n++] = *--stackp;
+ if (n == BUFSIZ) {
+ offset = 0;
+ do {
+ nwritten = write(fileno(stdout), &buff[offset], n);
+ if (nwritten < 0)
+ writeerr();
+ offset += nwritten;
+ } while ((n -= nwritten) > 0);
+ }
+ } while ( stackp > de_stack );
+
+ /*
+ * Generate the new entry.
+ */
+ if ( (code=free_ent) < maxmaxcode ) {
+ tab_prefixof(code) = (unsigned short)oldcode;
+ tab_suffixof(code) = finchar;
+ free_ent = code+1;
+ }
+ /*
+ * Remember previous code.
+ */
+ oldcode = incode;
+ }
+ /*
+ * Flush the stuff remaining in our buffer...
+ */
+ offset = 0;
+ while (n > 0) {
+ nwritten = write(fileno(stdout), &buff[offset], n);
+ if (nwritten < 0)
+ writeerr();
+ offset += nwritten;
+ n -= nwritten;
+ }
+}
+
+/*-
+ * Read one code from the standard input. If EOF, return -1.
+ * Inputs:
+ * stdin
+ * Outputs:
+ * code or -1 is returned.
+ */
+code_int
+getcode() {
+ /*
+ * On the VAX, it is important to have the register declarations
+ * in exactly the order given, or the asm will break.
+ */
+ register code_int code;
+ static int offset = 0, size = 0;
+ static char_type buf[BITS];
+ register int r_off, bits;
+ register char_type *bp = buf;
+
+ if ( clear_flg > 0 || offset >= size || free_ent > maxcode ) {
+ /*
+ * If the next entry will be too big for the current code
+ * size, then we must increase the size. This implies reading
+ * a new buffer full, too.
+ */
+ if ( free_ent > maxcode ) {
+ n_bits++;
+ if ( n_bits == maxbits )
+ maxcode = maxmaxcode; /* won't get any bigger now */
+ else
+ maxcode = MAXCODE(n_bits);
+ }
+ if ( clear_flg > 0) {
+ maxcode = MAXCODE (n_bits = INIT_BITS);
+ clear_flg = 0;
+ }
+ size = fread( buf, 1, n_bits, stdin );
+ if ( size <= 0 )
+ return -1; /* end of file */
+ offset = 0;
+ /* Round size down to integral number of codes */
+ size = (size << 3) - (n_bits - 1);
+ }
+ r_off = offset;
+ bits = n_bits;
+#ifdef vax
+ asm( "extzv r10,r9,(r8),r11" );
+#else /* not a vax */
+ /*
+ * Get to the first byte.
+ */
+ bp += (r_off >> 3);
+ r_off &= 7;
+ /* Get first part (low order bits) */
+#ifdef NO_UCHAR
+ code = ((*bp++ >> r_off) & rmask[8 - r_off]) & 0xff;
+#else
+ code = (*bp++ >> r_off);
+#endif /* NO_UCHAR */
+ bits -= (8 - r_off);
+ r_off = 8 - r_off; /* now, offset into code word */
+ /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
+ if ( bits >= 8 ) {
+#ifdef NO_UCHAR
+ code |= (*bp++ & 0xff) << r_off;
+#else
+ code |= *bp++ << r_off;
+#endif /* NO_UCHAR */
+ r_off += 8;
+ bits -= 8;
+ }
+ /* high order bits. */
+ code |= (*bp & rmask[bits]) << r_off;
+#endif /* vax */
+ offset += n_bits;
+
+ return code;
+}
+
+#ifdef DEBUG
+printcodes()
+{
+ /*
+ * Just print out codes from input file. For debugging.
+ */
+ code_int code;
+ int col = 0, bits;
+
+ bits = n_bits = INIT_BITS;
+ maxcode = MAXCODE(n_bits);
+ free_ent = ((block_compress) ? FIRST : 256 );
+ while ( ( code = getcode() ) >= 0 ) {
+ if ( (code == CLEAR) && block_compress ) {
+ free_ent = FIRST - 1;
+ clear_flg = 1;
+ }
+ else if ( free_ent < maxmaxcode )
+ free_ent++;
+ if ( bits != n_bits ) {
+ fprintf(stderr, "\nChange to %d bits\n", n_bits );
+ bits = n_bits;
+ col = 0;
+ }
+ fprintf(stderr, "%5d%c", code, (col+=6) >= 74 ? (col = 0, '\n') : ' ' );
+ }
+ putc( '\n', stderr );
+ exit( 0 );
+}
+
+code_int sorttab[1<<BITS]; /* sorted pointers into htab */
+
+dump_tab() /* dump string table */
+{
+ register int i, first;
+ register ent;
+#define STACK_SIZE 15000
+ int stack_top = STACK_SIZE;
+ register c;
+
+ if(do_decomp == 0) { /* compressing */
+ register int flag = 1;
+
+ for(i=0; i<hsize; i++) { /* build sort pointers */
+ if((long)htabof(i) >= 0) {
+ sorttab[codetabof(i)] = i;
+ }
+ }
+ first = block_compress ? FIRST : 256;
+ for(i = first; i < free_ent; i++) {
+ fprintf(stderr, "%5d: \"", i);
+ de_stack[--stack_top] = '\n';
+ de_stack[--stack_top] = '"';
+ stack_top = in_stack((htabof(sorttab[i])>>maxbits)&0xff,
+ stack_top);
+ for(ent=htabof(sorttab[i]) & ((1<<maxbits)-1);
+ ent > 256;
+ ent=htabof(sorttab[ent]) & ((1<<maxbits)-1)) {
+ stack_top = in_stack(htabof(sorttab[ent]) >> maxbits,
+ stack_top);
+ }
+ stack_top = in_stack(ent, stack_top);
+ fwrite( &de_stack[stack_top], 1, STACK_SIZE-stack_top, stderr);
+ stack_top = STACK_SIZE;
+ }
+ } else if(!debug) { /* decompressing */
+
+ for ( i = 0; i < free_ent; i++ ) {
+ ent = i;
+ c = tab_suffixof(ent);
+ if ( isascii(c) && isprint(c) )
+ fprintf( stderr, "%5d: %5d/'%c' \"",
+ ent, tab_prefixof(ent), c );
+ else
+ fprintf( stderr, "%5d: %5d/\\%03o \"",
+ ent, tab_prefixof(ent), c );
+ de_stack[--stack_top] = '\n';
+ de_stack[--stack_top] = '"';
+ for ( ; ent != NULL;
+ ent = (ent >= FIRST ? tab_prefixof(ent) : NULL) ) {
+ stack_top = in_stack(tab_suffixof(ent), stack_top);
+ }
+ fwrite( &de_stack[stack_top], 1, STACK_SIZE - stack_top, stderr );
+ stack_top = STACK_SIZE;
+ }
+ }
+}
+
+int
+in_stack(c, stack_top)
+ register c, stack_top;
+{
+ if ( (isascii(c) && isprint(c) && c != '\\') || c == ' ' ) {
+ de_stack[--stack_top] = c;
+ } else {
+ switch( c ) {
+ case '\n': de_stack[--stack_top] = 'n'; break;
+ case '\t': de_stack[--stack_top] = 't'; break;
+ case '\b': de_stack[--stack_top] = 'b'; break;
+ case '\f': de_stack[--stack_top] = 'f'; break;
+ case '\r': de_stack[--stack_top] = 'r'; break;
+ case '\\': de_stack[--stack_top] = '\\'; break;
+ default:
+ de_stack[--stack_top] = '0' + c % 8;
+ de_stack[--stack_top] = '0' + (c / 8) % 8;
+ de_stack[--stack_top] = '0' + c / 64;
+ break;
+ }
+ de_stack[--stack_top] = '\\';
+ }
+ return stack_top;
+}
+#endif /* DEBUG */
+
+writeerr()
+{
+ (void)fprintf(stderr, "compress: %s: %s\n",
+ ofname[0] ? ofname : "stdout", strerror(errno));
+ (void)unlink(ofname);
+ exit(1);
+}
+
+copystat(ifname, ofname)
+char *ifname, *ofname;
+{
+ struct stat statbuf;
+ int mode;
+ struct utimbuf tp;
+
+ fclose(stdout);
+ if (stat(ifname, &statbuf)) { /* Get stat on input file */
+ perror(ifname);
+ return;
+ }
+ if ((statbuf.st_mode & S_IFMT/*0170000*/) != S_IFREG/*0100000*/) {
+ if(quiet)
+ fprintf(stderr, "%s: ", ifname);
+ fprintf(stderr, " -- not a regular file: unchanged");
+ exit_stat = 1;
+ perm_stat = 1;
+ } else if (statbuf.st_nlink > 1) {
+ if(quiet)
+ fprintf(stderr, "%s: ", ifname);
+ fprintf(stderr, " -- has %d other links: unchanged",
+ statbuf.st_nlink - 1);
+ exit_stat = 1;
+ perm_stat = 1;
+ } else if (exit_stat == 2 && (!force)) { /* No compression: remove file.Z */
+ if(!quiet)
+ fprintf(stderr, " -- file unchanged");
+ } else { /* ***** Successful Compression ***** */
+ exit_stat = 0;
+ mode = statbuf.st_mode & 07777;
+ if (chmod(ofname, mode)) /* Copy modes */
+ perror(ofname);
+ chown(ofname, statbuf.st_uid, statbuf.st_gid); /* Copy ownership */
+ tp.actime = statbuf.st_atime;
+ tp.modtime = statbuf.st_mtime;
+ utime(ofname, &tp); /* Update last accessed and modified times */
+ if (unlink(ifname)) /* Remove input file */
+ perror(ifname);
+ if(!quiet)
+ fprintf(stderr, " -- replaced with %s", ofname);
+ return; /* Successful return */
+ }
+
+ /* Unsuccessful return -- one of the tests failed */
+ if (unlink(ofname))
+ perror(ofname);
+}
+
+void
+onintr ( )
+{
+ if (!precious)
+ unlink ( ofname );
+ exit ( 1 );
+}
+
+void
+oops ( ) /* wild pointer -- assume bad input */
+{
+ if ( do_decomp )
+ fprintf ( stderr, "uncompress: corrupt input\n" );
+ unlink ( ofname );
+ exit ( 1 );
+}
+
+cl_block () /* table clear for block compress */
+{
+ register long int rat;
+
+ checkpoint = in_count + CHECK_GAP;
+#ifdef DEBUG
+ if ( debug ) {
+ fprintf ( stderr, "count: %ld, ratio: ", in_count );
+ prratio ( stderr, in_count, bytes_out );
+ fprintf ( stderr, "\n");
+ }
+#endif /* DEBUG */
+
+ if(in_count > 0x007fffff) { /* shift will overflow */
+ rat = bytes_out >> 8;
+ if(rat == 0) { /* Don't divide by zero */
+ rat = 0x7fffffff;
+ } else {
+ rat = in_count / rat;
+ }
+ } else {
+ rat = (in_count << 8) / bytes_out; /* 8 fractional bits */
+ }
+ if ( rat > ratio ) {
+ ratio = rat;
+ } else {
+ ratio = 0;
+#ifdef DEBUG
+ if(verbose)
+ dump_tab(); /* dump string table */
+#endif
+ cl_hash ( (count_int) hsize );
+ free_ent = FIRST;
+ clear_flg = 1;
+ output ( (code_int) CLEAR );
+#ifdef DEBUG
+ if(debug)
+ fprintf ( stderr, "clear\n" );
+#endif /* DEBUG */
+ }
+}
+
+cl_hash(hsize) /* reset code table */
+ register count_int hsize;
+{
+ register count_int *htab_p = htab+hsize;
+ register long i;
+ register long m1 = -1;
+
+ i = hsize - 16;
+ do { /* might use Sys V memset(3) here */
+ *(htab_p-16) = m1;
+ *(htab_p-15) = m1;
+ *(htab_p-14) = m1;
+ *(htab_p-13) = m1;
+ *(htab_p-12) = m1;
+ *(htab_p-11) = m1;
+ *(htab_p-10) = m1;
+ *(htab_p-9) = m1;
+ *(htab_p-8) = m1;
+ *(htab_p-7) = m1;
+ *(htab_p-6) = m1;
+ *(htab_p-5) = m1;
+ *(htab_p-4) = m1;
+ *(htab_p-3) = m1;
+ *(htab_p-2) = m1;
+ *(htab_p-1) = m1;
+ htab_p -= 16;
+ } while ((i -= 16) >= 0);
+ for ( i += 16; i > 0; i-- )
+ *--htab_p = m1;
+}
+
+prratio(stream, num, den)
+FILE *stream;
+long int num, den;
+{
+ register int q; /* Doesn't need to be long */
+
+ if(num > 214748L) { /* 2147483647/10000 */
+ q = num / (den / 10000L);
+ } else {
+ q = 10000L * num / den; /* Long calculations, though */
+ }
+ if (q < 0) {
+ putc('-', stream);
+ q = -q;
+ }
+ fprintf(stream, "%d.%02d%%", q / 100, q % 100);
+}
+
+usage()
+{
+ (void)fprintf(stderr,
+#ifdef DEBUG
+ "compress [-CDVcdfnv] [-b maxbits] [file ...]\n");
+#else
+ "compress [-Ccdfnv] [-b maxbits] [file ...]\n");
+#endif
+ exit(1);
+}
diff --git a/Utilities/cmcurl/CMake/CMakeConfigurableFile.in b/Utilities/cmcurl/CMake/CMakeConfigurableFile.in
new file mode 100644
index 000000000..4cf74a12b
--- /dev/null
+++ b/Utilities/cmcurl/CMake/CMakeConfigurableFile.in
@@ -0,0 +1,2 @@
+@CMAKE_CONFIGURABLE_FILE_CONTENT@
+
diff --git a/Utilities/cmcurl/CMake/CurlCheckCSourceCompiles.cmake b/Utilities/cmcurl/CMake/CurlCheckCSourceCompiles.cmake
new file mode 100644
index 000000000..d025769aa
--- /dev/null
+++ b/Utilities/cmcurl/CMake/CurlCheckCSourceCompiles.cmake
@@ -0,0 +1,75 @@
+# - 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
new file mode 100644
index 000000000..19681bd85
--- /dev/null
+++ b/Utilities/cmcurl/CMake/CurlCheckCSourceRuns.cmake
@@ -0,0 +1,83 @@
+# - 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
new file mode 100644
index 000000000..d74a4f016
--- /dev/null
+++ b/Utilities/cmcurl/CMake/CurlTests.c
@@ -0,0 +1,526 @@
+#ifdef TIME_WITH_SYS_TIME
+/* Time with sys/time test */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+
+int
+main ()
+{
+if ((struct tm *) 0)
+return 0;
+ ;
+ return 0;
+}
+
+#endif
+
+#ifdef HAVE_O_NONBLOCK
+
+#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(__SVR4) || defined(__srv4__)
+# define PLATFORM_SOLARIS
+# else
+# define PLATFORM_SUNOS4
+# endif
+#endif
+#if (defined(_AIX) || defined(__xlC__)) && !defined(_AIX4)
+# define PLATFORM_AIX_V3
+#endif
+
+#if defined(PLATFORM_SUNOS4) || defined(PLATFORM_AIX_V3) || (defined(__BEOS__) && !defined(__HAIKU__))
+#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;
+}
+#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
+#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_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);
+ ;
+ 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>
+#else
+#include <sys/types.h>
+#include <sys/socket.h>
+#endif
+int
+main ()
+{
+if ((socklen_t *) 0)
+ return 0;
+if (sizeof (socklen_t))
+ return 0;
+ ;
+ return 0;
+}
+#endif
+#ifdef HAVE_IN_ADDR_T
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+
+int
+main ()
+{
+if ((in_addr_t *) 0)
+ return 0;
+if (sizeof (in_addr_t))
+ return 0;
+ ;
+ return 0;
+}
+#endif
+#ifdef STDC_HEADERS
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+int main() { return 0; }
+#endif
+#ifdef RETSIGTYPE_TEST
+#include <sys/types.h>
+#include <signal.h>
+#ifdef signal
+# undef signal
+#endif
+#ifdef __cplusplus
+extern "C" void (*signal (int, void (*)(int)))(int);
+#else
+void (*signal ()) ();
+#endif
+
+int
+main ()
+{
+ return 0;
+}
+#endif
+#ifdef HAVE_INET_NTOA_R_DECL
+#include <arpa/inet.h>
+
+typedef void (*func_type)();
+
+int main()
+{
+#ifndef inet_ntoa_r
+ func_type func;
+ func = (func_type)inet_ntoa_r;
+#endif
+ return 0;
+}
+#endif
+#ifdef HAVE_INET_NTOA_R_DECL_REENTRANT
+#define _REENTRANT
+#include <arpa/inet.h>
+
+typedef void (*func_type)();
+
+int main()
+{
+#ifndef inet_ntoa_r
+ func_type func;
+ func = (func_type)&inet_ntoa_r;
+#endif
+ return 0;
+}
+#endif
+#ifdef HAVE_GETADDRINFO
+#include <netdb.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+int main(void) {
+ struct addrinfo hints, *ai;
+ int error;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+#ifndef getaddrinfo
+ (void)getaddrinfo;
+#endif
+ error = getaddrinfo("127.0.0.1", "8080", &hints, &ai);
+ if (error) {
+ return 1;
+ }
+ return 0;
+}
+#endif
+#ifdef HAVE_FILE_OFFSET_BITS
+#ifdef _FILE_OFFSET_BITS
+#undef _FILE_OFFSET_BITS
+#endif
+#define _FILE_OFFSET_BITS 64
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int main () { ; return 0; }
+#endif
+#ifdef HAVE_IOCTLSOCKET
+#include <windows.h>
+
+int
+main ()
+{
+
+/* ioctlsocket source code */
+ int socket;
+ unsigned long flags = ioctlsocket(socket, FIONBIO, &flags);
+
+ ;
+ return 0;
+}
+
+#endif
+#ifdef HAVE_IOCTLSOCKET_CASE
+#include <windows.h>
+
+int
+main ()
+{
+
+/* IoctlSocket source code */
+ int socket;
+ int flags = IoctlSocket(socket, FIONBIO, (long)1);
+
+ ;
+ return 0;
+}
+#endif
+#ifdef HAVE_FIONBIO
+/* headers for FIONBIO test */
+#include <unistd.h>
+#include <stropts.h>
+
+int
+main ()
+{
+
+/* FIONBIO source test (old-style unix) */
+ int socket;
+ int flags = ioctl(socket, FIONBIO, &flags);
+
+ ;
+ return 0;
+}
+#endif
+#ifdef HAVE_SO_NONBLOCK
+
+/* headers for SO_NONBLOCK test (BeOS) */
+#include <sys/types.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+int main()
+{
+/* SO_NONBLOCK source code */
+ long b = 1;
+ int socket;
+ int flags = setsockopt(socket, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
+ return 0;
+}
+#endif
+#ifdef HAVE_GLIBC_STRERROR_R
+#include <string.h>
+#include <errno.h>
+int
+main () {
+ char buffer[1024]; /* big enough to play with */
+ char *string =
+ strerror_r(EACCES, buffer, sizeof(buffer));
+ /* this should've returned a string */
+ if(!string || !string[0])
+ return 99;
+ return 0;
+}
+#endif
+#ifdef HAVE_POSIX_STRERROR_R
+#include <string.h>
+#include <errno.h>
+int
+main () {
+ char buffer[1024]; /* big enough to play with */
+ int error =
+ strerror_r(EACCES, buffer, sizeof(buffer));
+ /* This should've returned zero, and written an error string in the
+ buffer.*/
+ if(!buffer[0] || error)
+ return 99;
+ return 0;
+}
+#endif
diff --git a/Utilities/cmcurl/CMake/OtherTests.cmake b/Utilities/cmcurl/CMake/OtherTests.cmake
new file mode 100644
index 000000000..7d2c66fa1
--- /dev/null
+++ b/Utilities/cmcurl/CMake/OtherTests.cmake
@@ -0,0 +1,242 @@
+INCLUDE(CurlCheckCSourceCompiles)
+SET(EXTRA_DEFINES "__unused1\n#undef inline\n#define __unused2")
+SET(HEADER_INCLUDES)
+SET(headers_hack)
+
+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)
+
+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)
+ add_header_include(HAVE_SYS_TYPES_H "sys/types.h")
+ add_header_include(HAVE_SYS_SOCKET_H "sys/socket.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("
+ ${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_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)
+
+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("
+ ${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_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(EXTRA_DEFINES "__unused1\n#undef inline\n#define __unused2")
+SET(HEADER_INCLUDES)
+SET(headers_hack)
+
+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)
+
+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")
+ 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)
+
+
+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)
+
+SET(CHECK_TYPE_SIZE_PREINCLUDE
+ "#undef inline")
+
+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)
+
+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/CMakeLists.txt b/Utilities/cmcurl/CMakeLists.txt
new file mode 100644
index 000000000..caa44f1d6
--- /dev/null
+++ b/Utilities/cmcurl/CMakeLists.txt
@@ -0,0 +1,722 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6.3 FATAL_ERROR)
+PROJECT(LIBCURL C)
+
+# 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}")
+
+# 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})
+
+# Disable warnings on Borland to avoid changing 3rd party code.
+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)
+
+# 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)
+
+# 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)
+
+# 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)
+
+# 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." OFF)
+MARK_AS_ADVANCED(CMAKE_USE_OPENSSL)
+IF(CMAKE_USE_OPENSSL)
+ SET(USE_SSLEAY TRUE)
+ SET(USE_OPENSSL TRUE)
+ IF(WIN32)
+ FIND_PATH(SSLINCLUDE openssl/crypto.h
+ PATHS c:/hoffman/Tools/openssl_w32vc6-0.9.8g/inc32)
+ INCLUDE_DIRECTORIES(${SSLINCLUDE})
+ FIND_LIBRARY(LIBEAY NAMES libeay32)
+ FIND_LIBRARY(SSLEAY NAMES ssleay32)
+ SET(CURL_LIBS ${CURL_LIBS} ${LIBEAY} ${SSLEAY} )
+ ELSE(WIN32)
+ CHECK_LIBRARY_EXISTS_CONCAT("crypto" CRYPTO_lock HAVE_LIBCRYPTO)
+ CHECK_LIBRARY_EXISTS_CONCAT("ssl" SSL_connect HAVE_LIBSSL)
+ ENDIF(WIN32)
+ 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)
+ENDIF(CMAKE_USE_OPENSSL)
+
+# Check for idn
+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 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 \
+#strlcat \
+#getpwuid \
+#geteuid \
+#dlopen \
+#utime \
+#sigsetjmp \
+#basename \
+#setlocale \
+#ftruncate \
+#pipe \
+#poll \
+#getprotobyname \
+#getrlimit \
+#setrlimit \
+#fork
+
+# 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(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)
+
+# 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)
+
+# 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
+ HAVE_IOCTLSOCKET
+ HAVE_IOCTLSOCKET_CASE
+ HAVE_O_NONBLOCK
+ HAVE_SO_NONBLOCK
+ )
+ENDIF(NOT CURL_HAVE_DISABLED_NONBLOCKING)
+FOREACH(CURL_TEST
+ ${CURL_NONBLOCKING_TESTS}
+ TIME_WITH_SYS_TIME
+ HAVE_O_NONBLOCKHAVE_GETHOSTBYADDR_R_5
+ HAVE_GETHOSTBYADDR_R_7
+ HAVE_GETHOSTBYADDR_R_8
+ HAVE_GETHOSTBYADDR_R_5_REENTRANT
+ HAVE_GETHOSTBYADDR_R_7_REENTRANT
+ HAVE_GETHOSTBYADDR_R_8_REENTRANT
+ HAVE_GETHOSTBYNAME_R_3
+ HAVE_GETHOSTBYNAME_R_5
+ HAVE_GETHOSTBYNAME_R_6
+ HAVE_GETHOSTBYNAME_R_3_REENTRANT
+ HAVE_GETHOSTBYNAME_R_5_REENTRANT
+ HAVE_GETHOSTBYNAME_R_6_REENTRANT
+ HAVE_SOCKLEN_T
+ HAVE_IN_ADDR_T
+ STDC_HEADERS
+ RETSIGTYPE_TEST
+ HAVE_INET_NTOA_R_DECL
+ HAVE_INET_NTOA_R_DECL_REENTRANT
+ 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)
+
+# Check for 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
+ 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
+ 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)
+
+# 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)
+
+# Fix libz / zlib.h
+
+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(_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
+ HAVE_IOCTLSOCKET OR
+ HAVE_IOCTLSOCKET_CASE OR
+ HAVE_O_NONBLOCK)
+ 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(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
+ 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})
+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(/bin cmcurl)
+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_DEST}/cmcurl)
diff --git a/Utilities/cmcurl/COPYING b/Utilities/cmcurl/COPYING
new file mode 100644
index 000000000..048cf5657
--- /dev/null
+++ b/Utilities/cmcurl/COPYING
@@ -0,0 +1,21 @@
+COPYRIGHT AND PERMISSION NOTICE
+
+Copyright (c) 1996 - 2009, Daniel Stenberg, <daniel@haxx.se>.
+
+All rights reserved.
+
+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", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. 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.
+
+Except as contained in this notice, the name of a copyright holder shall not
+be used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization of the copyright holder.
diff --git a/Utilities/cmcurl/Platforms/WindowsCache.cmake b/Utilities/cmcurl/Platforms/WindowsCache.cmake
new file mode 100644
index 000000000..b4515ce04
--- /dev/null
+++ b/Utilities/cmcurl/Platforms/WindowsCache.cmake
@@ -0,0 +1,121 @@
+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_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)
+ 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
new file mode 100644
index 000000000..86d10938f
--- /dev/null
+++ b/Utilities/cmcurl/Platforms/config-aix.h
@@ -0,0 +1,486 @@
+/* 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 `strlcat' function. */
+/* #undef HAVE_STRLCAT */
+
+/* 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/Testing/CMakeLists.txt b/Utilities/cmcurl/Testing/CMakeLists.txt
new file mode 100644
index 000000000..214410fd5
--- /dev/null
+++ b/Utilities/cmcurl/Testing/CMakeLists.txt
@@ -0,0 +1,19 @@
+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
new file mode 100644
index 000000000..7c9ce2a1b
--- /dev/null
+++ b/Utilities/cmcurl/Testing/curlgtk.c
@@ -0,0 +1,95 @@
+/*****************************************************************************
+ * _ _ ____ _
+ * 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/curltest.c b/Utilities/cmcurl/Testing/curltest.c
new file mode 100644
index 000000000..210868e36
--- /dev/null
+++ b/Utilities/cmcurl/Testing/curltest.c
@@ -0,0 +1,159 @@
+/* Prevent warnings on Visual Studio */
+struct _RPC_ASYNC_STATE;
+
+#include "curl/curl.h"
+#include <stdlib.h>
+#include <string.h>
+
+int GetFtpFile(void)
+{
+ int retVal = 0;
+ CURL *curl;
+ CURLcode res;
+ curl = curl_easy_init();
+ if(curl)
+ {
+ /* Get curl 7.9.2 from sunet.se's FTP site: */
+ curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
+ curl_easy_setopt(curl, CURLOPT_HEADER, 1);
+ curl_easy_setopt(curl, CURLOPT_URL,
+ "ftp://public.kitware.com/pub/cmake/cygwin/setup.hint");
+ res = curl_easy_perform(curl);
+ if ( res != 0 )
+ {
+ printf("Error fetching: ftp://public.kitware.com/pub/cmake/cygwin/setup.hint\n");
+ retVal = 1;
+ }
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+ }
+ else
+ {
+ printf("Cannot create curl object\n");
+ retVal = 1;
+ }
+ return retVal;
+}
+
+int GetWebFiles(char *url1, char *url2)
+{
+ int retVal = 0;
+ CURL *curl;
+ CURLcode res;
+
+ char proxy[1024];
+ int proxy_type = 0;
+
+ if ( getenv("HTTP_PROXY") )
+ {
+ proxy_type = 1;
+ if (getenv("HTTP_PROXY_PORT") )
+ {
+ sprintf(proxy, "%s:%s", getenv("HTTP_PROXY"), getenv("HTTP_PROXY_PORT"));
+ }
+ else
+ {
+ sprintf(proxy, "%s", getenv("HTTP_PROXY"));
+ }
+ if ( getenv("HTTP_PROXY_TYPE") )
+ {
+ /* HTTP/SOCKS4/SOCKS5 */
+ if ( strcmp(getenv("HTTP_PROXY_TYPE"), "HTTP") == 0 )
+ {
+ proxy_type = 1;
+ }
+ else if ( strcmp(getenv("HTTP_PROXY_TYPE"), "SOCKS4") == 0 )
+ {
+ proxy_type = 2;
+ }
+ else if ( strcmp(getenv("HTTP_PROXY_TYPE"), "SOCKS5") == 0 )
+ {
+ proxy_type = 3;
+ }
+ }
+ }
+
+ curl = curl_easy_init();
+ if(curl)
+ {
+ curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
+ curl_easy_setopt(curl, CURLOPT_HEADER, 1);
+
+ /* Using proxy */
+ if ( proxy_type > 0 )
+ {
+ curl_easy_setopt(curl, CURLOPT_PROXY, proxy);
+ switch (proxy_type)
+ {
+ case 2:
+ curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4);
+ break;
+ case 3:
+ curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
+ break;
+ default:
+ curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
+ }
+ }
+
+ /* get the first document */
+ curl_easy_setopt(curl, CURLOPT_URL, url1);
+ res = curl_easy_perform(curl);
+ if ( res != 0 )
+ {
+ printf("Error fetching: %s\n", url1);
+ retVal = 1;
+ }
+
+ /* get another document from the same server using the same
+ connection */
+ /* avoid warnings about url2 since below block is commented out: */
+ (void) url2;
+ /*
+ curl_easy_setopt(curl, CURLOPT_URL, url2);
+ res = curl_easy_perform(curl);
+ if ( res != 0 )
+ {
+ printf("Error fetching: %s\n", url2);
+ retVal = 1;
+ }
+ */
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+ }
+ else
+ {
+ printf("Cannot create curl object\n");
+ retVal = 1;
+ }
+
+ return retVal;
+}
+
+
+int main(int argc, char **argv)
+{
+ int retVal = 0;
+
+ curl_global_init(CURL_GLOBAL_DEFAULT);
+
+ if(argc>1)
+ {
+ retVal += GetWebFiles(argv[1], 0);
+ }
+ else
+ {
+ printf("error: first argument should be a url to download\n");
+ retVal = 1;
+ }
+
+ /* Do not check the output of FTP socks5 cannot handle FTP yet */
+ /* GetFtpFile(); */
+ /* do not test ftp right now because we don't enable that port */
+
+ curl_global_cleanup();
+
+ return retVal;
+}
diff --git a/Utilities/cmcurl/Testing/ftpget.c b/Utilities/cmcurl/Testing/ftpget.c
new file mode 100644
index 000000000..1a3633ec9
--- /dev/null
+++ b/Utilities/cmcurl/Testing/ftpget.c
@@ -0,0 +1,84 @@
+/*****************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..9548b2a34
--- /dev/null
+++ b/Utilities/cmcurl/Testing/ftpgetresp.c
@@ -0,0 +1,64 @@
+/*****************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..780c9cd27
--- /dev/null
+++ b/Utilities/cmcurl/Testing/ftpupload.c
@@ -0,0 +1,93 @@
+/*****************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..a8872da77
--- /dev/null
+++ b/Utilities/cmcurl/Testing/getinmemory.c
@@ -0,0 +1,83 @@
+/*****************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..1b4154fbf
--- /dev/null
+++ b/Utilities/cmcurl/Testing/http-post.c
@@ -0,0 +1,35 @@
+/*****************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..78275c40a
--- /dev/null
+++ b/Utilities/cmcurl/Testing/httpput.c
@@ -0,0 +1,100 @@
+/*****************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..c3936ef4a
--- /dev/null
+++ b/Utilities/cmcurl/Testing/multithread.c
@@ -0,0 +1,70 @@
+/*****************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..853470345
--- /dev/null
+++ b/Utilities/cmcurl/Testing/persistant.c
@@ -0,0 +1,53 @@
+/*****************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..9b7cda07e
--- /dev/null
+++ b/Utilities/cmcurl/Testing/postit2.c
@@ -0,0 +1,92 @@
+/*****************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..818578708
--- /dev/null
+++ b/Utilities/cmcurl/Testing/sepheaders.c
@@ -0,0 +1,78 @@
+/*****************************************************************************
+ * _ _ ____ _
+ * 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);
+ 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);
+
+ /* cleanup curl stuff */
+ curl_easy_cleanup(curl_handle);
+
+ return 0;
+}
diff --git a/Utilities/cmcurl/Testing/simple.c b/Utilities/cmcurl/Testing/simple.c
new file mode 100644
index 000000000..6dd6050ec
--- /dev/null
+++ b/Utilities/cmcurl/Testing/simple.c
@@ -0,0 +1,28 @@
+/*****************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..9a53603f4
--- /dev/null
+++ b/Utilities/cmcurl/Testing/simplessl.c
@@ -0,0 +1,118 @@
+/*****************************************************************************
+ * _ _ ____ _
+ * 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();
+
+ return 0;
+}
diff --git a/Utilities/cmcurl/Testing/testconfig.h.in b/Utilities/cmcurl/Testing/testconfig.h.in
new file mode 100644
index 000000000..faab46223
--- /dev/null
+++ b/Utilities/cmcurl/Testing/testconfig.h.in
@@ -0,0 +1,7 @@
+#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
new file mode 100644
index 000000000..5f791c8b5
--- /dev/null
+++ b/Utilities/cmcurl/Testing/win32sockets.c
@@ -0,0 +1,49 @@
+
+/*
+ * 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
new file mode 100644
index 000000000..7106f8daf
--- /dev/null
+++ b/Utilities/cmcurl/amigaos.c
@@ -0,0 +1,74 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..e5786d482
--- /dev/null
+++ b/Utilities/cmcurl/amigaos.h
@@ -0,0 +1,58 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..e6a04dcef
--- /dev/null
+++ b/Utilities/cmcurl/arpa_telnet.h
@@ -0,0 +1,101 @@
+#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
new file mode 100644
index 000000000..aa03f8346
--- /dev/null
+++ b/Utilities/cmcurl/base64.c
@@ -0,0 +1,366 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..59742bcd3
--- /dev/null
+++ b/Utilities/cmcurl/base64.h
@@ -0,0 +1,28 @@
+#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
new file mode 100644
index 000000000..12390bc7b
--- /dev/null
+++ b/Utilities/cmcurl/ca-bundle.h
@@ -0,0 +1 @@
+/* ca bundle path set in here*/
diff --git a/Utilities/cmcurl/config.h.in b/Utilities/cmcurl/config.h.in
new file mode 100644
index 000000000..6e74935a3
--- /dev/null
+++ b/Utilities/cmcurl/config.h.in
@@ -0,0 +1,726 @@
+/* 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}
+
+/* Define to 1 if you have the `ssl' library (-lssl). */
+#cmakedefine HAVE_LIBSSL ${HAVE_LIBSSL}
+
+/* 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 `strlcat' function. */
+#cmakedefine HAVE_STRLCAT ${HAVE_STRLCAT}
+
+/* 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
new file mode 100644
index 000000000..2b3897204
--- /dev/null
+++ b/Utilities/cmcurl/connect.c
@@ -0,0 +1,905 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..599572b27
--- /dev/null
+++ b/Utilities/cmcurl/connect.h
@@ -0,0 +1,46 @@
+#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
new file mode 100644
index 000000000..97f834177
--- /dev/null
+++ b/Utilities/cmcurl/content_encoding.c
@@ -0,0 +1,424 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..b31669be4
--- /dev/null
+++ b/Utilities/cmcurl/content_encoding.h
@@ -0,0 +1,41 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..2856ad882
--- /dev/null
+++ b/Utilities/cmcurl/cookie.c
@@ -0,0 +1,1017 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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");
+ 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
new file mode 100644
index 000000000..57c3acbdd
--- /dev/null
+++ b/Utilities/cmcurl/cookie.h
@@ -0,0 +1,107 @@
+#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
new file mode 100644
index 000000000..157c634a4
--- /dev/null
+++ b/Utilities/cmcurl/curl/curl.h
@@ -0,0 +1,1644 @@
+#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_URL_MALFORMAT_USER, /* 4 - NOT USED */
+ 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
new file mode 100644
index 000000000..938002285
--- /dev/null
+++ b/Utilities/cmcurl/curl/curlver.h
@@ -0,0 +1,56 @@
+#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
new file mode 100644
index 000000000..17de21070
--- /dev/null
+++ b/Utilities/cmcurl/curl/easy.h
@@ -0,0 +1,81 @@
+#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
new file mode 100644
index 000000000..5c526882f
--- /dev/null
+++ b/Utilities/cmcurl/curl/mprintf.h
@@ -0,0 +1,80 @@
+#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
new file mode 100644
index 000000000..1b6674768
--- /dev/null
+++ b/Utilities/cmcurl/curl/multi.h
@@ -0,0 +1,327 @@
+#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
new file mode 100644
index 000000000..11c1e2f6e
--- /dev/null
+++ b/Utilities/cmcurl/curl/stdcheaders.h
@@ -0,0 +1,34 @@
+#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
new file mode 100644
index 000000000..d37d6ae9e
--- /dev/null
+++ b/Utilities/cmcurl/curl/types.h
@@ -0,0 +1 @@
+/* not used */
diff --git a/Utilities/cmcurl/curlx.h b/Utilities/cmcurl/curlx.h
new file mode 100644
index 000000000..26948d305
--- /dev/null
+++ b/Utilities/cmcurl/curlx.h
@@ -0,0 +1,107 @@
+#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
new file mode 100644
index 000000000..d6443f4b9
--- /dev/null
+++ b/Utilities/cmcurl/dict.c
@@ -0,0 +1,280 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..d3da1936f
--- /dev/null
+++ b/Utilities/cmcurl/dict.h
@@ -0,0 +1,30 @@
+#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
new file mode 100644
index 000000000..209d1c3e0
--- /dev/null
+++ b/Utilities/cmcurl/easy.c
@@ -0,0 +1,895 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..4c0f7e795
--- /dev/null
+++ b/Utilities/cmcurl/easyif.h
@@ -0,0 +1,40 @@
+#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
new file mode 100644
index 000000000..9552b0f31
--- /dev/null
+++ b/Utilities/cmcurl/escape.c
@@ -0,0 +1,181 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..a0a0209c4
--- /dev/null
+++ b/Utilities/cmcurl/escape.h
@@ -0,0 +1,30 @@
+#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
new file mode 100644
index 000000000..b247a7736
--- /dev/null
+++ b/Utilities/cmcurl/file.c
@@ -0,0 +1,407 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..20a1c4c06
--- /dev/null
+++ b/Utilities/cmcurl/file.h
@@ -0,0 +1,31 @@
+#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
new file mode 100644
index 000000000..f10c6c70e
--- /dev/null
+++ b/Utilities/cmcurl/formdata.c
@@ -0,0 +1,1694 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..4ca0f3c5c
--- /dev/null
+++ b/Utilities/cmcurl/formdata.h
@@ -0,0 +1,97 @@
+#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
new file mode 100644
index 000000000..883988938
--- /dev/null
+++ b/Utilities/cmcurl/ftp.c
@@ -0,0 +1,3865 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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-existant 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
new file mode 100644
index 000000000..b64e70506
--- /dev/null
+++ b/Utilities/cmcurl/ftp.h
@@ -0,0 +1,43 @@
+#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
new file mode 100644
index 000000000..4f955f893
--- /dev/null
+++ b/Utilities/cmcurl/getenv.c
@@ -0,0 +1,69 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..5cf3bcacd
--- /dev/null
+++ b/Utilities/cmcurl/getinfo.c
@@ -0,0 +1,234 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..2fe1b5c36
--- /dev/null
+++ b/Utilities/cmcurl/getinfo.h
@@ -0,0 +1,28 @@
+#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
new file mode 100644
index 000000000..250ecada4
--- /dev/null
+++ b/Utilities/cmcurl/gtls.c
@@ -0,0 +1,640 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..bff3f8693
--- /dev/null
+++ b/Utilities/cmcurl/gtls.h
@@ -0,0 +1,46 @@
+#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
new file mode 100644
index 000000000..e00462778
--- /dev/null
+++ b/Utilities/cmcurl/hash.c
@@ -0,0 +1,315 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..ceebb5234
--- /dev/null
+++ b/Utilities/cmcurl/hash.h
@@ -0,0 +1,61 @@
+#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
new file mode 100644
index 000000000..1db0f4320
--- /dev/null
+++ b/Utilities/cmcurl/hostares.c
@@ -0,0 +1,307 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..3df147910
--- /dev/null
+++ b/Utilities/cmcurl/hostasyn.c
@@ -0,0 +1,174 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..fd555ef9d
--- /dev/null
+++ b/Utilities/cmcurl/hostip.c
@@ -0,0 +1,636 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..e6d63ca71
--- /dev/null
+++ b/Utilities/cmcurl/hostip.h
@@ -0,0 +1,271 @@
+#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
new file mode 100644
index 000000000..877baa2ca
--- /dev/null
+++ b/Utilities/cmcurl/hostip4.c
@@ -0,0 +1,389 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..c8bbdb5e9
--- /dev/null
+++ b/Utilities/cmcurl/hostip6.c
@@ -0,0 +1,306 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..2f816b858
--- /dev/null
+++ b/Utilities/cmcurl/hostsyn.c
@@ -0,0 +1,138 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..12e31ea34
--- /dev/null
+++ b/Utilities/cmcurl/hostthre.c
@@ -0,0 +1,840 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..c07053bdd
--- /dev/null
+++ b/Utilities/cmcurl/http.c
@@ -0,0 +1,2422 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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 existance 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
new file mode 100644
index 000000000..0f4b58f72
--- /dev/null
+++ b/Utilities/cmcurl/http.h
@@ -0,0 +1,85 @@
+#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
new file mode 100644
index 000000000..1b03a5569
--- /dev/null
+++ b/Utilities/cmcurl/http_chunks.c
@@ -0,0 +1,360 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..211818ab7
--- /dev/null
+++ b/Utilities/cmcurl/http_chunks.h
@@ -0,0 +1,104 @@
+#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
new file mode 100644
index 000000000..c223784f9
--- /dev/null
+++ b/Utilities/cmcurl/http_digest.c
@@ -0,0 +1,504 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..6cf025975
--- /dev/null
+++ b/Utilities/cmcurl/http_digest.h
@@ -0,0 +1,58 @@
+#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
new file mode 100644
index 000000000..bdfeefa0a
--- /dev/null
+++ b/Utilities/cmcurl/http_negotiate.c
@@ -0,0 +1,327 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..ce0d083f9
--- /dev/null
+++ b/Utilities/cmcurl/http_negotiate.h
@@ -0,0 +1,39 @@
+#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
new file mode 100644
index 000000000..aff1bb1b6
--- /dev/null
+++ b/Utilities/cmcurl/http_ntlm.c
@@ -0,0 +1,1111 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..a8de220a7
--- /dev/null
+++ b/Utilities/cmcurl/http_ntlm.h
@@ -0,0 +1,146 @@
+#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
new file mode 100644
index 000000000..b4a98c662
--- /dev/null
+++ b/Utilities/cmcurl/if2ip.c
@@ -0,0 +1,134 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..4e86e2b27
--- /dev/null
+++ b/Utilities/cmcurl/if2ip.h
@@ -0,0 +1,67 @@
+#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/inet_ntoa_r.h b/Utilities/cmcurl/inet_ntoa_r.h
new file mode 100644
index 000000000..c6c9bd895
--- /dev/null
+++ b/Utilities/cmcurl/inet_ntoa_r.h
@@ -0,0 +1,44 @@
+#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
new file mode 100644
index 000000000..9381963f5
--- /dev/null
+++ b/Utilities/cmcurl/inet_ntop.c
@@ -0,0 +1,224 @@
+/*
+ * 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
new file mode 100644
index 000000000..54d64bd19
--- /dev/null
+++ b/Utilities/cmcurl/inet_ntop.h
@@ -0,0 +1,37 @@
+#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
new file mode 100644
index 000000000..9b9f88b5e
--- /dev/null
+++ b/Utilities/cmcurl/inet_pton.c
@@ -0,0 +1,241 @@
+/* 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
new file mode 100644
index 000000000..a659a9774
--- /dev/null
+++ b/Utilities/cmcurl/inet_pton.h
@@ -0,0 +1,42 @@
+#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
new file mode 100644
index 000000000..f2b91df69
--- /dev/null
+++ b/Utilities/cmcurl/krb4.c
@@ -0,0 +1,425 @@
+/* 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
new file mode 100644
index 000000000..f46416e62
--- /dev/null
+++ b/Utilities/cmcurl/krb4.h
@@ -0,0 +1,70 @@
+#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
new file mode 100644
index 000000000..3e1144d4f
--- /dev/null
+++ b/Utilities/cmcurl/ldap.c
@@ -0,0 +1,702 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..b2d4f3973
--- /dev/null
+++ b/Utilities/cmcurl/ldap.h
@@ -0,0 +1,29 @@
+#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/llist.c b/Utilities/cmcurl/llist.c
new file mode 100644
index 000000000..921d1d1f9
--- /dev/null
+++ b/Utilities/cmcurl/llist.c
@@ -0,0 +1,138 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..5c7a8a008
--- /dev/null
+++ b/Utilities/cmcurl/llist.h
@@ -0,0 +1,60 @@
+#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
new file mode 100644
index 000000000..4cfb073ea
--- /dev/null
+++ b/Utilities/cmcurl/md5.c
@@ -0,0 +1,352 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..63cc70e84
--- /dev/null
+++ b/Utilities/cmcurl/md5.h
@@ -0,0 +1,29 @@
+#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
new file mode 100644
index 000000000..a8cca44cb
--- /dev/null
+++ b/Utilities/cmcurl/memdebug.c
@@ -0,0 +1,298 @@
+#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
new file mode 100644
index 000000000..a4ce7e59a
--- /dev/null
+++ b/Utilities/cmcurl/memdebug.h
@@ -0,0 +1,125 @@
+#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
new file mode 100644
index 000000000..076d20a28
--- /dev/null
+++ b/Utilities/cmcurl/memory.h
@@ -0,0 +1,50 @@
+#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
new file mode 100644
index 000000000..8b2f3d07e
--- /dev/null
+++ b/Utilities/cmcurl/mprintf.c
@@ -0,0 +1,1218 @@
+/****************************************************************************
+ *
+ * $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
new file mode 100644
index 000000000..b501f296f
--- /dev/null
+++ b/Utilities/cmcurl/multi.c
@@ -0,0 +1,1988 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..800aa0f5d
--- /dev/null
+++ b/Utilities/cmcurl/multiif.h
@@ -0,0 +1,46 @@
+#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
new file mode 100644
index 000000000..54d175989
--- /dev/null
+++ b/Utilities/cmcurl/netrc.c
@@ -0,0 +1,247 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..939c552df
--- /dev/null
+++ b/Utilities/cmcurl/netrc.h
@@ -0,0 +1,34 @@
+#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
new file mode 100644
index 000000000..b0eea56c7
--- /dev/null
+++ b/Utilities/cmcurl/nwlib.c
@@ -0,0 +1,300 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..ef91585e5
--- /dev/null
+++ b/Utilities/cmcurl/parsedate.c
@@ -0,0 +1,425 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..0ea2d83c3
--- /dev/null
+++ b/Utilities/cmcurl/parsedate.h
@@ -0,0 +1,28 @@
+#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
new file mode 100644
index 000000000..5ba829a03
--- /dev/null
+++ b/Utilities/cmcurl/progress.c
@@ -0,0 +1,424 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..ad9d6623e
--- /dev/null
+++ b/Utilities/cmcurl/progress.h
@@ -0,0 +1,70 @@
+#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
new file mode 100644
index 000000000..4c9aed812
--- /dev/null
+++ b/Utilities/cmcurl/security.c
@@ -0,0 +1,493 @@
+/* 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
new file mode 100644
index 000000000..51adbcf37
--- /dev/null
+++ b/Utilities/cmcurl/select.c
@@ -0,0 +1,315 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..7573b1f54
--- /dev/null
+++ b/Utilities/cmcurl/select.h
@@ -0,0 +1,60 @@
+#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
new file mode 100644
index 000000000..500bf66f0
--- /dev/null
+++ b/Utilities/cmcurl/sendf.c
@@ -0,0 +1,663 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..7877df823
--- /dev/null
+++ b/Utilities/cmcurl/sendf.h
@@ -0,0 +1,72 @@
+#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
new file mode 100644
index 000000000..5ae881fba
--- /dev/null
+++ b/Utilities/cmcurl/setup.h
@@ -0,0 +1,390 @@
+#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
new file mode 100644
index 000000000..ee6864158
--- /dev/null
+++ b/Utilities/cmcurl/setup_once.h
@@ -0,0 +1,153 @@
+#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
new file mode 100644
index 000000000..de13b6021
--- /dev/null
+++ b/Utilities/cmcurl/share.c
@@ -0,0 +1,219 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..5cfe8c792
--- /dev/null
+++ b/Utilities/cmcurl/share.h
@@ -0,0 +1,56 @@
+#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
new file mode 100644
index 000000000..78dad4d9e
--- /dev/null
+++ b/Utilities/cmcurl/sockaddr.h
@@ -0,0 +1,38 @@
+#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
new file mode 100644
index 000000000..3319e697e
--- /dev/null
+++ b/Utilities/cmcurl/socks.c
@@ -0,0 +1,585 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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)
+ strlcat((char*)socksreq + 8, proxy_name, sizeof(socksreq) - 8);
+
+ /*
+ * 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
new file mode 100644
index 000000000..0da987998
--- /dev/null
+++ b/Utilities/cmcurl/socks.h
@@ -0,0 +1,41 @@
+#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
new file mode 100644
index 000000000..adda8a963
--- /dev/null
+++ b/Utilities/cmcurl/speedcheck.c
@@ -0,0 +1,75 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..62475f640
--- /dev/null
+++ b/Utilities/cmcurl/speedcheck.h
@@ -0,0 +1,34 @@
+#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
new file mode 100644
index 000000000..9fb66c76a
--- /dev/null
+++ b/Utilities/cmcurl/splay.c
@@ -0,0 +1,425 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..16745341e
--- /dev/null
+++ b/Utilities/cmcurl/splay.h
@@ -0,0 +1,54 @@
+#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
new file mode 100644
index 000000000..24cba1bac
--- /dev/null
+++ b/Utilities/cmcurl/ssh.c
@@ -0,0 +1,979 @@
+/***************************************************************************
+* _ _ ____ _
+* 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
new file mode 100644
index 000000000..d9144903b
--- /dev/null
+++ b/Utilities/cmcurl/ssh.h
@@ -0,0 +1,49 @@
+#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
new file mode 100644
index 000000000..f110a51ea
--- /dev/null
+++ b/Utilities/cmcurl/sslgen.c
@@ -0,0 +1,618 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..c24d46bf3
--- /dev/null
+++ b/Utilities/cmcurl/sslgen.h
@@ -0,0 +1,84 @@
+#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
new file mode 100644
index 000000000..55afb2446
--- /dev/null
+++ b/Utilities/cmcurl/ssluse.c
@@ -0,0 +1,1945 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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:
+ req_method = SSLv2_client_method();
+ break;
+ 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
new file mode 100644
index 000000000..5bb7090c5
--- /dev/null
+++ b/Utilities/cmcurl/ssluse.h
@@ -0,0 +1,71 @@
+#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
new file mode 100644
index 000000000..e16e08a72
--- /dev/null
+++ b/Utilities/cmcurl/strdup.c
@@ -0,0 +1,46 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..3206db3cf
--- /dev/null
+++ b/Utilities/cmcurl/strdup.h
@@ -0,0 +1,34 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..76ad5241f
--- /dev/null
+++ b/Utilities/cmcurl/strequal.c
@@ -0,0 +1,143 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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;
+}
+
+#ifndef HAVE_STRLCAT
+/*
+ * The strlcat() function appends the NUL-terminated string src to the end
+ * of dst. It will append at most size - strlen(dst) - 1 bytes, NUL-termi-
+ * nating the result.
+ *
+ * The strlcpy() and strlcat() functions return the total length of the
+ * string they tried to create. For strlcpy() that means the length of src.
+ * For strlcat() that means the initial length of dst plus the length of
+ * src. While this may seem somewhat confusing it was done to make trunca-
+ * tion detection simple.
+ *
+ *
+ */
+size_t Curl_strlcat(char *dst, const char *src, size_t siz)
+{
+ char *d = dst;
+ const char *s = src;
+ size_t n = siz;
+ size_t dlen;
+
+ /* Find the end of dst and adjust bytes left but don't go past end */
+ while (n-- != 0 && *d != '\0')
+ d++;
+ dlen = d - dst;
+ n = siz - dlen;
+
+ if (n == 0)
+ return(dlen + strlen(s));
+ while (*s != '\0') {
+ if (n != 1) {
+ *d++ = *s;
+ n--;
+ }
+ s++;
+ }
+ *d = '\0';
+
+ return(dlen + (s - src)); /* count does not include NUL */
+}
+#endif
diff --git a/Utilities/cmcurl/strequal.h b/Utilities/cmcurl/strequal.h
new file mode 100644
index 000000000..b3caa7345
--- /dev/null
+++ b/Utilities/cmcurl/strequal.h
@@ -0,0 +1,43 @@
+#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);
+
+#ifndef HAVE_STRLCAT
+#define strlcat(x,y,z) Curl_strlcat(x,y,z)
+#endif
+size_t strlcat(char *dst, const char *src, size_t siz);
+
+#endif
diff --git a/Utilities/cmcurl/strerror.c b/Utilities/cmcurl/strerror.c
new file mode 100644
index 000000000..6304fe89d
--- /dev/null
+++ b/Utilities/cmcurl/strerror.c
@@ -0,0 +1,748 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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_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_URL_MALFORMAT_USER:
+ 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
new file mode 100644
index 000000000..b28050437
--- /dev/null
+++ b/Utilities/cmcurl/strerror.h
@@ -0,0 +1,34 @@
+#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
new file mode 100644
index 000000000..630e4e029
--- /dev/null
+++ b/Utilities/cmcurl/strtok.c
@@ -0,0 +1,68 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..cf9fac8c7
--- /dev/null
+++ b/Utilities/cmcurl/strtok.h
@@ -0,0 +1,38 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..3ab1bfdff
--- /dev/null
+++ b/Utilities/cmcurl/strtoofft.c
@@ -0,0 +1,165 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..e27b43261
--- /dev/null
+++ b/Utilities/cmcurl/strtoofft.h
@@ -0,0 +1,73 @@
+#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
new file mode 100644
index 000000000..97d22b788
--- /dev/null
+++ b/Utilities/cmcurl/telnet.c
@@ -0,0 +1,1403 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..693abf3f8
--- /dev/null
+++ b/Utilities/cmcurl/telnet.h
@@ -0,0 +1,30 @@
+#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
new file mode 100644
index 000000000..0e2e7ab45
--- /dev/null
+++ b/Utilities/cmcurl/tftp.c
@@ -0,0 +1,816 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..c7125417b
--- /dev/null
+++ b/Utilities/cmcurl/tftp.h
@@ -0,0 +1,31 @@
+#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
new file mode 100644
index 000000000..bb9c0a174
--- /dev/null
+++ b/Utilities/cmcurl/timeval.c
@@ -0,0 +1,116 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..effd741da
--- /dev/null
+++ b/Utilities/cmcurl/timeval.h
@@ -0,0 +1,76 @@
+#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
new file mode 100644
index 000000000..5cb3361d2
--- /dev/null
+++ b/Utilities/cmcurl/transfer.c
@@ -0,0 +1,2494 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..3c415cc72
--- /dev/null
+++ b/Utilities/cmcurl/transfer.h
@@ -0,0 +1,51 @@
+#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
new file mode 100644
index 000000000..da12231f1
--- /dev/null
+++ b/Utilities/cmcurl/url.c
@@ -0,0 +1,4252 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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
new file mode 100644
index 000000000..446b3d91a
--- /dev/null
+++ b/Utilities/cmcurl/url.h
@@ -0,0 +1,85 @@
+#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
new file mode 100644
index 000000000..9537ce36b
--- /dev/null
+++ b/Utilities/cmcurl/urldata.h
@@ -0,0 +1,1340 @@
+#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-specifc 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
new file mode 100644
index 000000000..9085f7df8
--- /dev/null
+++ b/Utilities/cmcurl/version.c
@@ -0,0 +1,249 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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/cmexpat/.NoDartCoverage b/Utilities/cmexpat/.NoDartCoverage
new file mode 100644
index 000000000..3c9972938
--- /dev/null
+++ b/Utilities/cmexpat/.NoDartCoverage
@@ -0,0 +1 @@
+# do not do coverage in this directory
diff --git a/Utilities/cmexpat/CMakeLists.txt b/Utilities/cmexpat/CMakeLists.txt
new file mode 100644
index 000000000..b75c11232
--- /dev/null
+++ b/Utilities/cmexpat/CMakeLists.txt
@@ -0,0 +1,34 @@
+PROJECT(CMEXPAT)
+
+SET(expat_SRCS
+ xmlparse.c
+ xmltok.c
+ xmlrole.c
+)
+
+INCLUDE(${CMAKE_ROOT}/Modules/TestBigEndian.cmake)
+TEST_BIG_ENDIAN(CMEXPAT_BIGENDIAN)
+
+INCLUDE_DIRECTORIES(
+ "${CMEXPAT_BINARY_DIR}/.."
+ )
+
+IF(WIN32)
+ IF(NOT BUILD_SHARED_LIBS)
+ SET (CM_EXPAT_STATIC 1)
+ ENDIF(NOT BUILD_SHARED_LIBS)
+ENDIF(WIN32)
+
+CONFIGURE_FILE(${CMEXPAT_SOURCE_DIR}/expatConfig.h.in
+ ${CMEXPAT_BINARY_DIR}/expatConfig.h)
+CONFIGURE_FILE(${CMEXPAT_SOURCE_DIR}/expatDllConfig.h.in
+ ${CMEXPAT_BINARY_DIR}/expatDllConfig.h)
+CONFIGURE_FILE(${CMEXPAT_SOURCE_DIR}/.NoDartCoverage
+ ${CMEXPAT_BINARY_DIR}/.NoDartCoverage)
+CONFIGURE_FILE(${CMEXPAT_SOURCE_DIR}/cm_expat_mangle.h
+ ${CMEXPAT_BINARY_DIR}/cm_expat_mangle.h)
+CONFIGURE_FILE(${CMEXPAT_SOURCE_DIR}/expat.h
+ ${CMEXPAT_BINARY_DIR}/expat.h)
+
+ADD_LIBRARY(cmexpat ${expat_SRCS})
+INSTALL(FILES COPYING DESTINATION ${CMake_DOC_DEST}/cmexpat)
diff --git a/Utilities/cmexpat/COPYING b/Utilities/cmexpat/COPYING
new file mode 100644
index 000000000..fc97b02d9
--- /dev/null
+++ b/Utilities/cmexpat/COPYING
@@ -0,0 +1,21 @@
+Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+ and Clark Cooper
+
+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.
diff --git a/Utilities/cmexpat/ascii.h b/Utilities/cmexpat/ascii.h
new file mode 100644
index 000000000..6376b1f31
--- /dev/null
+++ b/Utilities/cmexpat/ascii.h
@@ -0,0 +1,86 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file COPYING for copying permission.
+*/
+
+#define ASCII_A 0x41
+#define ASCII_B 0x42
+#define ASCII_C 0x43
+#define ASCII_D 0x44
+#define ASCII_E 0x45
+#define ASCII_F 0x46
+#define ASCII_G 0x47
+#define ASCII_H 0x48
+#define ASCII_I 0x49
+#define ASCII_J 0x4A
+#define ASCII_K 0x4B
+#define ASCII_L 0x4C
+#define ASCII_M 0x4D
+#define ASCII_N 0x4E
+#define ASCII_O 0x4F
+#define ASCII_P 0x50
+#define ASCII_Q 0x51
+#define ASCII_R 0x52
+#define ASCII_S 0x53
+#define ASCII_T 0x54
+#define ASCII_U 0x55
+#define ASCII_V 0x56
+#define ASCII_W 0x57
+#define ASCII_X 0x58
+#define ASCII_Y 0x59
+#define ASCII_Z 0x5A
+
+#define ASCII_a 0x61
+#define ASCII_b 0x62
+#define ASCII_c 0x63
+#define ASCII_d 0x64
+#define ASCII_e 0x65
+#define ASCII_f 0x66
+#define ASCII_g 0x67
+#define ASCII_h 0x68
+#define ASCII_i 0x69
+#define ASCII_j 0x6A
+#define ASCII_k 0x6B
+#define ASCII_l 0x6C
+#define ASCII_m 0x6D
+#define ASCII_n 0x6E
+#define ASCII_o 0x6F
+#define ASCII_p 0x70
+#define ASCII_q 0x71
+#define ASCII_r 0x72
+#define ASCII_s 0x73
+#define ASCII_t 0x74
+#define ASCII_u 0x75
+#define ASCII_v 0x76
+#define ASCII_w 0x77
+#define ASCII_x 0x78
+#define ASCII_y 0x79
+#define ASCII_z 0x7A
+
+#define ASCII_0 0x30
+#define ASCII_1 0x31
+#define ASCII_2 0x32
+#define ASCII_3 0x33
+#define ASCII_4 0x34
+#define ASCII_5 0x35
+#define ASCII_6 0x36
+#define ASCII_7 0x37
+#define ASCII_8 0x38
+#define ASCII_9 0x39
+
+#define ASCII_TAB 0x09
+#define ASCII_SPACE 0x20
+#define ASCII_EXCL 0x21
+#define ASCII_QUOT 0x22
+#define ASCII_AMP 0x26
+#define ASCII_APOS 0x27
+#define ASCII_MINUS 0x2D
+#define ASCII_PERIOD 0x2E
+#define ASCII_COLON 0x3A
+#define ASCII_SEMI 0x3B
+#define ASCII_LT 0x3C
+#define ASCII_EQUALS 0x3D
+#define ASCII_GT 0x3E
+#define ASCII_LSQB 0x5B
+#define ASCII_RSQB 0x5D
+#define ASCII_UNDERSCORE 0x5F
diff --git a/Utilities/cmexpat/asciitab.h b/Utilities/cmexpat/asciitab.h
new file mode 100644
index 000000000..eb445cc52
--- /dev/null
+++ b/Utilities/cmexpat/asciitab.h
@@ -0,0 +1,37 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file COPYING for copying permission.
+*/
+
+/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
+/* 0x0C */ BT_NONXML, BT_CR, BT_NONXML, BT_NONXML,
+/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
+/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
+/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
+/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
+/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
+/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
+/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
+/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
+/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
+/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
+/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
+/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
+/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
+/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
+/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
+/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,
diff --git a/Utilities/cmexpat/cm_expat_mangle.h b/Utilities/cmexpat/cm_expat_mangle.h
new file mode 100644
index 000000000..82276a56d
--- /dev/null
+++ b/Utilities/cmexpat/cm_expat_mangle.h
@@ -0,0 +1,87 @@
+#ifndef cm_expat_mangle_h
+#define cm_expat_mangle_h
+
+/*
+
+This header file mangles all symbols exported from the expat library.
+It is included in all files while building the expat library. Due to
+namespace pollution, no expat headers should be included in .h files in
+CMake.
+
+The following command was used to obtain the symbol list:
+
+nm libcmexpat.a |grep " T "
+
+*/
+
+#define XML_DefaultCurrent cm_expat_XML_DefaultCurrent
+#define XML_ErrorString cm_expat_XML_ErrorString
+#define XML_ExpatVersion cm_expat_XML_ExpatVersion
+#define XML_ExpatVersionInfo cm_expat_XML_ExpatVersionInfo
+#define XML_ExternalEntityParserCreate cm_expat_XML_ExternalEntityParserCreate
+#define XML_GetBase cm_expat_XML_GetBase
+#define XML_GetBuffer cm_expat_XML_GetBuffer
+#define XML_GetCurrentByteCount cm_expat_XML_GetCurrentByteCount
+#define XML_GetCurrentByteIndex cm_expat_XML_GetCurrentByteIndex
+#define XML_GetCurrentColumnNumber cm_expat_XML_GetCurrentColumnNumber
+#define XML_GetCurrentLineNumber cm_expat_XML_GetCurrentLineNumber
+#define XML_GetErrorCode cm_expat_XML_GetErrorCode
+#define XML_GetIdAttributeIndex cm_expat_XML_GetIdAttributeIndex
+#define XML_GetInputContext cm_expat_XML_GetInputContext
+#define XML_GetSpecifiedAttributeCount cm_expat_XML_GetSpecifiedAttributeCount
+#define XML_Parse cm_expat_XML_Parse
+#define XML_ParseBuffer cm_expat_XML_ParseBuffer
+#define XML_ParserCreate cm_expat_XML_ParserCreate
+#define XML_ParserCreateNS cm_expat_XML_ParserCreateNS
+#define XML_ParserCreate_MM cm_expat_XML_ParserCreate_MM
+#define XML_ParserFree cm_expat_XML_ParserFree
+#define XML_SetAttlistDeclHandler cm_expat_XML_SetAttlistDeclHandler
+#define XML_SetBase cm_expat_XML_SetBase
+#define XML_SetCdataSectionHandler cm_expat_XML_SetCdataSectionHandler
+#define XML_SetCharacterDataHandler cm_expat_XML_SetCharacterDataHandler
+#define XML_SetCommentHandler cm_expat_XML_SetCommentHandler
+#define XML_SetDefaultHandler cm_expat_XML_SetDefaultHandler
+#define XML_SetDefaultHandlerExpand cm_expat_XML_SetDefaultHandlerExpand
+#define XML_SetDoctypeDeclHandler cm_expat_XML_SetDoctypeDeclHandler
+#define XML_SetElementDeclHandler cm_expat_XML_SetElementDeclHandler
+#define XML_SetElementHandler cm_expat_XML_SetElementHandler
+#define XML_SetEncoding cm_expat_XML_SetEncoding
+#define XML_SetEndCdataSectionHandler cm_expat_XML_SetEndCdataSectionHandler
+#define XML_SetEndDoctypeDeclHandler cm_expat_XML_SetEndDoctypeDeclHandler
+#define XML_SetEndElementHandler cm_expat_XML_SetEndElementHandler
+#define XML_SetEndNamespaceDeclHandler cm_expat_XML_SetEndNamespaceDeclHandler
+#define XML_SetEntityDeclHandler cm_expat_XML_SetEntityDeclHandler
+#define XML_SetExternalEntityRefHandler cm_expat_XML_SetExternalEntityRefHandler
+#define XML_SetExternalEntityRefHandlerArg cm_expat_XML_SetExternalEntityRefHandlerArg
+#define XML_SetNamespaceDeclHandler cm_expat_XML_SetNamespaceDeclHandler
+#define XML_SetNotStandaloneHandler cm_expat_XML_SetNotStandaloneHandler
+#define XML_SetNotationDeclHandler cm_expat_XML_SetNotationDeclHandler
+#define XML_SetParamEntityParsing cm_expat_XML_SetParamEntityParsing
+#define XML_SetProcessingInstructionHandler cm_expat_XML_SetProcessingInstructionHandler
+#define XML_SetReturnNSTriplet cm_expat_XML_SetReturnNSTriplet
+#define XML_SetStartCdataSectionHandler cm_expat_XML_SetStartCdataSectionHandler
+#define XML_SetStartDoctypeDeclHandler cm_expat_XML_SetStartDoctypeDeclHandler
+#define XML_SetStartElementHandler cm_expat_XML_SetStartElementHandler
+#define XML_SetStartNamespaceDeclHandler cm_expat_XML_SetStartNamespaceDeclHandler
+#define XML_SetUnknownEncodingHandler cm_expat_XML_SetUnknownEncodingHandler
+#define XML_SetUnparsedEntityDeclHandler cm_expat_XML_SetUnparsedEntityDeclHandler
+#define XML_SetUserData cm_expat_XML_SetUserData
+#define XML_SetXmlDeclHandler cm_expat_XML_SetXmlDeclHandler
+#define XML_UseParserAsHandlerArg cm_expat_XML_UseParserAsHandlerArg
+#define XmlGetUtf16InternalEncoding cm_expat_XmlGetUtf16InternalEncoding
+#define XmlGetUtf16InternalEncodingNS cm_expat_XmlGetUtf16InternalEncodingNS
+#define XmlGetUtf8InternalEncoding cm_expat_XmlGetUtf8InternalEncoding
+#define XmlGetUtf8InternalEncodingNS cm_expat_XmlGetUtf8InternalEncodingNS
+#define XmlInitEncoding cm_expat_XmlInitEncoding
+#define XmlInitEncodingNS cm_expat_XmlInitEncodingNS
+#define XmlInitUnknownEncoding cm_expat_XmlInitUnknownEncoding
+#define XmlInitUnknownEncodingNS cm_expat_XmlInitUnknownEncodingNS
+#define XmlParseXmlDecl cm_expat_XmlParseXmlDecl
+#define XmlParseXmlDeclNS cm_expat_XmlParseXmlDeclNS
+#define XmlSizeOfUnknownEncoding cm_expat_XmlSizeOfUnknownEncoding
+#define XmlUtf16Encode cm_expat_XmlUtf16Encode
+#define XmlUtf8Encode cm_expat_XmlUtf8Encode
+#define XmlPrologStateInit cm_expat_XmlPrologStateInit
+#define XmlPrologStateInitExternalEntity cm_expat_XmlPrologStateInitExternalEntity
+
+#endif
diff --git a/Utilities/cmexpat/expat.h b/Utilities/cmexpat/expat.h
new file mode 100644
index 000000000..86e58a1e5
--- /dev/null
+++ b/Utilities/cmexpat/expat.h
@@ -0,0 +1,740 @@
+#include "cm_expat_mangle.h"
+/*
+Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+See the file COPYING for copying permission.
+*/
+
+#ifndef XmlParse_INCLUDED
+#define XmlParse_INCLUDED 1
+
+#include <stdlib.h>
+
+#include <cmexpat/expatDllConfig.h>
+
+#if defined(_WIN32) && !defined(CM_EXPAT_STATIC)
+# if defined(cmexpat_EXPORTS)
+# define XMLPARSEAPI(type) __declspec( dllexport ) type __cdecl
+# else
+# define XMLPARSEAPI(type) __declspec( dllimport ) type __cdecl
+# endif
+#else
+# define XMLPARSEAPI(type) type
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void *XML_Parser;
+
+/* Information is UTF-8 encoded. */
+typedef char XML_Char;
+typedef char XML_LChar;
+
+enum XML_Content_Type {
+ XML_CTYPE_EMPTY = 1,
+ XML_CTYPE_ANY,
+ XML_CTYPE_MIXED,
+ XML_CTYPE_NAME,
+ XML_CTYPE_CHOICE,
+ XML_CTYPE_SEQ
+};
+
+enum XML_Content_Quant {
+ XML_CQUANT_NONE,
+ XML_CQUANT_OPT,
+ XML_CQUANT_REP,
+ XML_CQUANT_PLUS
+};
+
+/* If type == XML_CTYPE_EMPTY or XML_CTYPE_ANY, then quant will be
+ XML_CQUANT_NONE, and the other fields will be zero or NULL.
+ If type == XML_CTYPE_MIXED, then quant will be NONE or REP and
+ numchildren will contain number of elements that may be mixed in
+ and children point to an array of XML_Content cells that will be
+ all of XML_CTYPE_NAME type with no quantification.
+
+ If type == XML_CTYPE_NAME, then the name points to the name, and
+ the numchildren field will be zero and children will be NULL. The
+ quant fields indicates any quantifiers placed on the name.
+
+ CHOICE and SEQ will have name NULL, the number of children in
+ numchildren and children will point, recursively, to an array
+ of XML_Content cells.
+
+ The EMPTY, ANY, and MIXED types will only occur at top level.
+*/
+
+typedef struct XML_cp XML_Content;
+
+struct XML_cp {
+ enum XML_Content_Type type;
+ enum XML_Content_Quant quant;
+ XML_Char * name;
+ unsigned int numchildren;
+ XML_Content * children;
+};
+
+
+/* This is called for an element declaration. See above for
+ description of the model argument. It's the caller's responsibility
+ to free model when finished with it.
+*/
+
+typedef void (*XML_ElementDeclHandler) (void *userData,
+ const XML_Char *name,
+ XML_Content *model);
+
+XMLPARSEAPI(void)
+XML_SetElementDeclHandler(XML_Parser parser,
+ XML_ElementDeclHandler eldecl);
+
+/*
+ The Attlist declaration handler is called for *each* attribute. So
+ a single Attlist declaration with multiple attributes declared will
+ generate multiple calls to this handler. The "default" parameter
+ may be NULL in the case of the "#IMPLIED" or "#REQUIRED" keyword.
+ The "isrequired" parameter will be true and the default value will
+ be NULL in the case of "#REQUIRED". If "isrequired" is true and
+ default is non-NULL, then this is a "#FIXED" default.
+ */
+
+typedef void (*XML_AttlistDeclHandler) (void *userData,
+ const XML_Char *elname,
+ const XML_Char *attname,
+ const XML_Char *att_type,
+ const XML_Char *dflt,
+ int isrequired);
+
+XMLPARSEAPI(void)
+XML_SetAttlistDeclHandler(XML_Parser parser,
+ XML_AttlistDeclHandler attdecl);
+
+
+ /* The XML declaration handler is called for *both* XML declarations and
+ text declarations. The way to distinguish is that the version parameter
+ will be null for text declarations. The encoding parameter may be null
+ for XML declarations. The standalone parameter will be -1, 0, or 1
+ indicating respectively that there was no standalone parameter in
+ the declaration, that it was given as no, or that it was given as yes.
+ */
+
+typedef void (*XML_XmlDeclHandler) (void *userData,
+ const XML_Char *version,
+ const XML_Char *encoding,
+ int standalone);
+
+XMLPARSEAPI(void)
+XML_SetXmlDeclHandler(XML_Parser parser,
+ XML_XmlDeclHandler xmldecl);
+
+
+typedef struct {
+ void *(*malloc_fcn)(size_t size);
+ void *(*realloc_fcn)(void *ptr, size_t size);
+ void (*free_fcn)(void *ptr);
+} XML_Memory_Handling_Suite;
+
+/* Constructs a new parser; encoding is the encoding specified by the
+external protocol or null if there is none specified. */
+
+XMLPARSEAPI(XML_Parser)
+XML_ParserCreate(const XML_Char *encoding);
+
+/* Constructs a new parser and namespace processor. Element type
+names and attribute names that belong to a namespace will be expanded;
+unprefixed attribute names are never expanded; unprefixed element type
+names are expanded only if there is a default namespace. The expanded
+name is the concatenation of the namespace URI, the namespace
+separator character, and the local part of the name. If the namespace
+separator is '\0' then the namespace URI and the local part will be
+concatenated without any separator. When a namespace is not declared,
+the name and prefix will be passed through without expansion. */
+
+XMLPARSEAPI(XML_Parser)
+XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator);
+
+
+/* Constructs a new parser using the memory management suit referred to
+ by memsuite. If memsuite is NULL, then use the standard library memory
+ suite. If namespaceSeparator is non-NULL it creates a parser with
+ namespace processing as described above. The character pointed at
+ will serve as the namespace separator.
+
+ All further memory operations used for the created parser will come from
+ the given suite.
+*/
+
+XMLPARSEAPI(XML_Parser)
+XML_ParserCreate_MM(const XML_Char *encoding,
+ const XML_Memory_Handling_Suite *memsuite,
+ const XML_Char *namespaceSeparator);
+
+/* atts is array of name/value pairs, terminated by 0;
+ names and values are 0 terminated. */
+
+typedef void (*XML_StartElementHandler)(void *userData,
+ const XML_Char *name,
+ const XML_Char **atts);
+
+typedef void (*XML_EndElementHandler)(void *userData,
+ const XML_Char *name);
+
+
+/* s is not 0 terminated. */
+typedef void (*XML_CharacterDataHandler)(void *userData,
+ const XML_Char *s,
+ int len);
+
+/* target and data are 0 terminated */
+typedef void (*XML_ProcessingInstructionHandler)(void *userData,
+ const XML_Char *target,
+ const XML_Char *data);
+
+/* data is 0 terminated */
+typedef void (*XML_CommentHandler)(void *userData, const XML_Char *data);
+
+typedef void (*XML_StartCdataSectionHandler)(void *userData);
+typedef void (*XML_EndCdataSectionHandler)(void *userData);
+
+/* This is called for any characters in the XML document for
+which there is no applicable handler. This includes both
+characters that are part of markup which is of a kind that is
+not reported (comments, markup declarations), or characters
+that are part of a construct which could be reported but
+for which no handler has been supplied. The characters are passed
+exactly as they were in the XML document except that
+they will be encoded in UTF-8. Line boundaries are not normalized.
+Note that a byte order mark character is not passed to the default handler.
+There are no guarantees about how characters are divided between calls
+to the default handler: for example, a comment might be split between
+multiple calls. */
+
+typedef void (*XML_DefaultHandler)(void *userData,
+ const XML_Char *s,
+ int len);
+
+/* This is called for the start of the DOCTYPE declaration, before
+ any DTD or internal subset is parsed. */
+
+typedef void (*XML_StartDoctypeDeclHandler)(void *userData,
+ const XML_Char *doctypeName,
+ const XML_Char *sysid,
+ const XML_Char *pubid,
+ int has_internal_subset);
+
+/* This is called for the start of the DOCTYPE declaration when the
+closing > is encountered, but after processing any external subset. */
+typedef void (*XML_EndDoctypeDeclHandler)(void *userData);
+
+/* This is called for entity declarations. The is_parameter_entity
+ argument will be non-zero if the entity is a parameter entity, zero
+ otherwise.
+
+ For internal entities (<!ENTITY foo "bar">), value will
+ be non-null and systemId, publicID, and notationName will be null.
+ The value string is NOT null terminated; the length is provided in
+ the value_length argument. Since it is legal to have zero-length
+ values, do not use this argument to test for internal entities.
+
+ For external entities, value will be null and systemId will be non-null.
+ The publicId argument will be null unless a public identifier was
+ provided. The notationName argument will have a non-null value only
+ for unparsed entity declarations.
+*/
+
+typedef void (*XML_EntityDeclHandler) (void *userData,
+ const XML_Char *entityName,
+ int is_parameter_entity,
+ const XML_Char *value,
+ int value_length,
+ const XML_Char *base,
+ const XML_Char *systemId,
+ const XML_Char *publicId,
+ const XML_Char *notationName);
+
+XMLPARSEAPI(void)
+XML_SetEntityDeclHandler(XML_Parser parser,
+ XML_EntityDeclHandler handler);
+
+/* OBSOLETE -- OBSOLETE -- OBSOLETE
+ This handler has been superceded by the EntityDeclHandler above.
+ It is provided here for backward compatibility.
+This is called for a declaration of an unparsed (NDATA)
+entity. The base argument is whatever was set by XML_SetBase.
+The entityName, systemId and notationName arguments will never be null.
+The other arguments may be. */
+
+typedef void (*XML_UnparsedEntityDeclHandler)(void *userData,
+ const XML_Char *entityName,
+ const XML_Char *base,
+ const XML_Char *systemId,
+ const XML_Char *publicId,
+ const XML_Char *notationName);
+
+/* This is called for a declaration of notation.
+The base argument is whatever was set by XML_SetBase.
+The notationName will never be null. The other arguments can be. */
+
+typedef void (*XML_NotationDeclHandler)(void *userData,
+ const XML_Char *notationName,
+ const XML_Char *base,
+ const XML_Char *systemId,
+ const XML_Char *publicId);
+
+/* When namespace processing is enabled, these are called once for
+each namespace declaration. The call to the start and end element
+handlers occur between the calls to the start and end namespace
+declaration handlers. For an xmlns attribute, prefix will be null.
+For an xmlns="" attribute, uri will be null. */
+
+typedef void (*XML_StartNamespaceDeclHandler)(void *userData,
+ const XML_Char *prefix,
+ const XML_Char *uri);
+
+typedef void (*XML_EndNamespaceDeclHandler)(void *userData,
+ const XML_Char *prefix);
+
+/* This is called if the document is not standalone (it has an
+external subset or a reference to a parameter entity, but does not
+have standalone="yes"). If this handler returns 0, then processing
+will not continue, and the parser will return a
+XML_ERROR_NOT_STANDALONE error. */
+
+typedef int (*XML_NotStandaloneHandler)(void *userData);
+
+/* This is called for a reference to an external parsed general entity.
+The referenced entity is not automatically parsed.
+The application can parse it immediately or later using
+XML_ExternalEntityParserCreate.
+The parser argument is the parser parsing the entity containing the reference;
+it can be passed as the parser argument to XML_ExternalEntityParserCreate.
+The systemId argument is the system identifier as specified in the entity
+declaration; it will not be null.
+The base argument is the system identifier that should be used as the base for
+resolving systemId if systemId was relative; this is set by XML_SetBase;
+it may be null.
+The publicId argument is the public identifier as specified in the entity
+declaration, or null if none was specified; the whitespace in the public
+identifier will have been normalized as required by the XML spec.
+The context argument specifies the parsing context in the format
+expected by the context argument to
+XML_ExternalEntityParserCreate; context is valid only until the handler
+returns, so if the referenced entity is to be parsed later, it must be copied.
+The handler should return 0 if processing should not continue because of
+a fatal error in the handling of the external entity.
+In this case the calling parser will return an
+XML_ERROR_EXTERNAL_ENTITY_HANDLING error.
+Note that unlike other handlers the first argument is the parser, not
+userData. */
+
+typedef int (*XML_ExternalEntityRefHandler)(XML_Parser parser,
+ const XML_Char *context,
+ const XML_Char *base,
+ const XML_Char *systemId,
+ const XML_Char *publicId);
+
+/* This structure is filled in by the XML_UnknownEncodingHandler
+to provide information to the parser about encodings that are unknown
+to the parser.
+The map[b] member gives information about byte sequences
+whose first byte is b.
+If map[b] is c where c is >= 0, then b by itself encodes the Unicode scalar
+value c.
+If map[b] is -1, then the byte sequence is malformed.
+If map[b] is -n, where n >= 2, then b is the first byte of an n-byte
+sequence that encodes a single Unicode scalar value.
+The data member will be passed as the first argument to the convert function.
+The convert function is used to convert multibyte sequences;
+s will point to a n-byte sequence where map[(unsigned char)*s] == -n.
+The convert function must return the Unicode scalar value
+represented by this byte sequence or -1 if the byte sequence is malformed.
+The convert function may be null if the encoding is a single-byte encoding,
+that is if map[b] >= -1 for all bytes b.
+When the parser is finished with the encoding, then if release is not null,
+it will call release passing it the data member;
+once release has been called, the convert function will not be called again.
+
+Expat places certain restrictions on the encodings that are supported
+using this mechanism.
+
+1. Every ASCII character that can appear in a well-formed XML document,
+other than the characters
+
+ $@\^`{}~
+
+must be represented by a single byte, and that byte must be the
+same byte that represents that character in ASCII.
+
+2. No character may require more than 4 bytes to encode.
+
+3. All characters encoded must have Unicode scalar values <= 0xFFFF, (i.e.,
+characters that would be encoded by surrogates in UTF-16 are not
+allowed). Note that this restriction doesn't apply to the built-in
+support for UTF-8 and UTF-16.
+
+4. No Unicode character may be encoded by more than one distinct sequence
+of bytes. */
+
+typedef struct {
+ int map[256];
+ void *data;
+ int (*convert)(void *data, const char *s);
+ void (*release)(void *data);
+} XML_Encoding;
+
+/* This is called for an encoding that is unknown to the parser.
+The encodingHandlerData argument is that which was passed as the
+second argument to XML_SetUnknownEncodingHandler.
+The name argument gives the name of the encoding as specified in
+the encoding declaration.
+If the callback can provide information about the encoding,
+it must fill in the XML_Encoding structure, and return 1.
+Otherwise it must return 0.
+If info does not describe a suitable encoding,
+then the parser will return an XML_UNKNOWN_ENCODING error. */
+
+typedef int (*XML_UnknownEncodingHandler)(void *encodingHandlerData,
+ const XML_Char *name,
+ XML_Encoding *info);
+
+XMLPARSEAPI(void)
+XML_SetElementHandler(XML_Parser parser,
+ XML_StartElementHandler start,
+ XML_EndElementHandler end);
+
+XMLPARSEAPI(void)
+XML_SetStartElementHandler(XML_Parser, XML_StartElementHandler);
+
+XMLPARSEAPI(void)
+XML_SetEndElementHandler(XML_Parser, XML_EndElementHandler);
+
+XMLPARSEAPI(void)
+XML_SetCharacterDataHandler(XML_Parser parser,
+ XML_CharacterDataHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetProcessingInstructionHandler(XML_Parser parser,
+ XML_ProcessingInstructionHandler handler);
+XMLPARSEAPI(void)
+XML_SetCommentHandler(XML_Parser parser,
+ XML_CommentHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetCdataSectionHandler(XML_Parser parser,
+ XML_StartCdataSectionHandler start,
+ XML_EndCdataSectionHandler end);
+
+XMLPARSEAPI(void)
+XML_SetStartCdataSectionHandler(XML_Parser parser,
+ XML_StartCdataSectionHandler start);
+
+XMLPARSEAPI(void)
+XML_SetEndCdataSectionHandler(XML_Parser parser,
+ XML_EndCdataSectionHandler end);
+
+/* This sets the default handler and also inhibits expansion of
+internal entities. The entity reference will be passed to the default
+handler. */
+
+XMLPARSEAPI(void)
+XML_SetDefaultHandler(XML_Parser parser,
+ XML_DefaultHandler handler);
+
+/* This sets the default handler but does not inhibit expansion of
+internal entities. The entity reference will not be passed to the
+default handler. */
+
+XMLPARSEAPI(void)
+XML_SetDefaultHandlerExpand(XML_Parser parser,
+ XML_DefaultHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetDoctypeDeclHandler(XML_Parser parser,
+ XML_StartDoctypeDeclHandler start,
+ XML_EndDoctypeDeclHandler end);
+
+XMLPARSEAPI(void)
+XML_SetStartDoctypeDeclHandler(XML_Parser parser,
+ XML_StartDoctypeDeclHandler start);
+
+XMLPARSEAPI(void)
+XML_SetEndDoctypeDeclHandler(XML_Parser parser,
+ XML_EndDoctypeDeclHandler end);
+
+XMLPARSEAPI(void)
+XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
+ XML_UnparsedEntityDeclHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetNotationDeclHandler(XML_Parser parser,
+ XML_NotationDeclHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetNamespaceDeclHandler(XML_Parser parser,
+ XML_StartNamespaceDeclHandler start,
+ XML_EndNamespaceDeclHandler end);
+
+XMLPARSEAPI(void)
+XML_SetStartNamespaceDeclHandler(XML_Parser parser,
+ XML_StartNamespaceDeclHandler start);
+
+XMLPARSEAPI(void)
+XML_SetEndNamespaceDeclHandler(XML_Parser parser,
+ XML_EndNamespaceDeclHandler end);
+
+XMLPARSEAPI(void)
+XML_SetNotStandaloneHandler(XML_Parser parser,
+ XML_NotStandaloneHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetExternalEntityRefHandler(XML_Parser parser,
+ XML_ExternalEntityRefHandler handler);
+
+/* If a non-null value for arg is specified here, then it will be passed
+as the first argument to the external entity ref handler instead
+of the parser object. */
+XMLPARSEAPI(void)
+XML_SetExternalEntityRefHandlerArg(XML_Parser, void *arg);
+
+XMLPARSEAPI(void)
+XML_SetUnknownEncodingHandler(XML_Parser parser,
+ XML_UnknownEncodingHandler handler,
+ void *encodingHandlerData);
+
+/* This can be called within a handler for a start element, end element,
+processing instruction or character data. It causes the corresponding
+markup to be passed to the default handler. */
+XMLPARSEAPI(void)
+XML_DefaultCurrent(XML_Parser parser);
+
+/* If do_nst is non-zero, and namespace processing is in effect, and
+ a name has a prefix (i.e. an explicit namespace qualifier) then
+ that name is returned as a triplet in a single
+ string separated by the separator character specified when the parser
+ was created: URI + sep + local_name + sep + prefix.
+
+ If do_nst is zero, then namespace information is returned in the
+ default manner (URI + sep + local_name) whether or not the names
+ has a prefix.
+*/
+
+XMLPARSEAPI(void)
+XML_SetReturnNSTriplet(XML_Parser parser, int do_nst);
+
+/* This value is passed as the userData argument to callbacks. */
+XMLPARSEAPI(void)
+XML_SetUserData(XML_Parser parser, void *userData);
+
+/* Returns the last value set by XML_SetUserData or null. */
+#define XML_GetUserData(parser) (*(void **)(parser))
+
+/* This is equivalent to supplying an encoding argument
+to XML_ParserCreate. It must not be called after XML_Parse
+or XML_ParseBuffer. */
+
+XMLPARSEAPI(int)
+XML_SetEncoding(XML_Parser parser, const XML_Char *encoding);
+
+/* If this function is called, then the parser will be passed
+as the first argument to callbacks instead of userData.
+The userData will still be accessible using XML_GetUserData. */
+
+XMLPARSEAPI(void)
+XML_UseParserAsHandlerArg(XML_Parser parser);
+
+/* Sets the base to be used for resolving relative URIs in system
+identifiers in declarations. Resolving relative identifiers is left
+to the application: this value will be passed through as the base
+argument to the XML_ExternalEntityRefHandler, XML_NotationDeclHandler
+and XML_UnparsedEntityDeclHandler. The base argument will be copied.
+Returns zero if out of memory, non-zero otherwise. */
+
+XMLPARSEAPI(int)
+XML_SetBase(XML_Parser parser, const XML_Char *base);
+
+XMLPARSEAPI(const XML_Char *)
+XML_GetBase(XML_Parser parser);
+
+/* Returns the number of the attribute/value pairs passed in last call
+to the XML_StartElementHandler that were specified in the start-tag
+rather than defaulted. Each attribute/value pair counts as 2; thus
+this correspondds to an index into the atts array passed to the
+XML_StartElementHandler. */
+
+XMLPARSEAPI(int)
+XML_GetSpecifiedAttributeCount(XML_Parser parser);
+
+/* Returns the index of the ID attribute passed in the last call to
+XML_StartElementHandler, or -1 if there is no ID attribute. Each
+attribute/value pair counts as 2; thus this correspondds to an index
+into the atts array passed to the XML_StartElementHandler. */
+
+XMLPARSEAPI(int)
+XML_GetIdAttributeIndex(XML_Parser parser);
+
+/* Parses some input. Returns 0 if a fatal error is detected.
+The last call to XML_Parse must have isFinal true;
+len may be zero for this call (or any other). */
+XMLPARSEAPI(int)
+XML_Parse(XML_Parser parser, const char *s, int len, int isFinal);
+
+XMLPARSEAPI(void *)
+XML_GetBuffer(XML_Parser parser, int len);
+
+XMLPARSEAPI(int)
+XML_ParseBuffer(XML_Parser parser, int len, int isFinal);
+
+/* Creates an XML_Parser object that can parse an external general
+entity; context is a '\0'-terminated string specifying the parse
+context; encoding is a '\0'-terminated string giving the name of the
+externally specified encoding, or null if there is no externally
+specified encoding. The context string consists of a sequence of
+tokens separated by formfeeds (\f); a token consisting of a name
+specifies that the general entity of the name is open; a token of the
+form prefix=uri specifies the namespace for a particular prefix; a
+token of the form =uri specifies the default namespace. This can be
+called at any point after the first call to an
+ExternalEntityRefHandler so longer as the parser has not yet been
+freed. The new parser is completely independent and may safely be
+used in a separate thread. The handlers and userData are initialized
+from the parser argument. Returns 0 if out of memory. Otherwise
+returns a new XML_Parser object. */
+XMLPARSEAPI(XML_Parser)
+XML_ExternalEntityParserCreate(XML_Parser parser,
+ const XML_Char *context,
+ const XML_Char *encoding);
+
+enum XML_ParamEntityParsing {
+ XML_PARAM_ENTITY_PARSING_NEVER,
+ XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE,
+ XML_PARAM_ENTITY_PARSING_ALWAYS
+};
+
+/* Controls parsing of parameter entities (including the external DTD
+subset). If parsing of parameter entities is enabled, then references
+to external parameter entities (including the external DTD subset)
+will be passed to the handler set with
+XML_SetExternalEntityRefHandler. The context passed will be 0.
+Unlike external general entities, external parameter entities can only
+be parsed synchronously. If the external parameter entity is to be
+parsed, it must be parsed during the call to the external entity ref
+handler: the complete sequence of XML_ExternalEntityParserCreate,
+XML_Parse/XML_ParseBuffer and XML_ParserFree calls must be made during
+this call. After XML_ExternalEntityParserCreate has been called to
+create the parser for the external parameter entity (context must be 0
+for this call), it is illegal to make any calls on the old parser
+until XML_ParserFree has been called on the newly created parser. If
+the library has been compiled without support for parameter entity
+parsing (ie without XML_DTD being defined), then
+XML_SetParamEntityParsing will return 0 if parsing of parameter
+entities is requested; otherwise it will return non-zero. */
+
+XMLPARSEAPI(int)
+XML_SetParamEntityParsing(XML_Parser parser,
+ enum XML_ParamEntityParsing parsing);
+
+enum XML_Error {
+ XML_ERROR_NONE,
+ XML_ERROR_NO_MEMORY,
+ XML_ERROR_SYNTAX,
+ XML_ERROR_NO_ELEMENTS,
+ XML_ERROR_INVALID_TOKEN,
+ XML_ERROR_UNCLOSED_TOKEN,
+ XML_ERROR_PARTIAL_CHAR,
+ XML_ERROR_TAG_MISMATCH,
+ XML_ERROR_DUPLICATE_ATTRIBUTE,
+ XML_ERROR_JUNK_AFTER_DOC_ELEMENT,
+ XML_ERROR_PARAM_ENTITY_REF,
+ XML_ERROR_UNDEFINED_ENTITY,
+ XML_ERROR_RECURSIVE_ENTITY_REF,
+ XML_ERROR_ASYNC_ENTITY,
+ XML_ERROR_BAD_CHAR_REF,
+ XML_ERROR_BINARY_ENTITY_REF,
+ XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF,
+ XML_ERROR_MISPLACED_XML_PI,
+ XML_ERROR_UNKNOWN_ENCODING,
+ XML_ERROR_INCORRECT_ENCODING,
+ XML_ERROR_UNCLOSED_CDATA_SECTION,
+ XML_ERROR_EXTERNAL_ENTITY_HANDLING,
+ XML_ERROR_NOT_STANDALONE,
+ XML_ERROR_UNEXPECTED_STATE
+};
+
+/* If XML_Parse or XML_ParseBuffer have returned 0, then XML_GetErrorCode
+returns information about the error. */
+
+XMLPARSEAPI(enum XML_Error)
+XML_GetErrorCode(XML_Parser parser);
+
+/* These functions return information about the current parse location.
+They may be called when XML_Parse or XML_ParseBuffer return 0;
+in this case the location is the location of the character at which
+the error was detected.
+They may also be called from any other callback called to report
+some parse event; in this the location is the location of the first
+of the sequence of characters that generated the event. */
+
+XMLPARSEAPI(int) XML_GetCurrentLineNumber(XML_Parser parser);
+XMLPARSEAPI(int) XML_GetCurrentColumnNumber(XML_Parser parser);
+XMLPARSEAPI(long) XML_GetCurrentByteIndex(XML_Parser parser);
+
+/* Return the number of bytes in the current event.
+Returns 0 if the event is in an internal entity. */
+
+XMLPARSEAPI(int)
+XML_GetCurrentByteCount(XML_Parser parser);
+
+/* If XML_CONTEXT_BYTES is defined, returns the input buffer, sets
+ the integer pointed to by offset to the offset within this buffer
+ of the current parse position, and sets the integer pointed to by size
+ to the size of this buffer (the number of input bytes). Otherwise
+ returns a null pointer. Also returns a null pointer if a parse isn't
+ active.
+
+ NOTE: The character pointer returned should not be used outside
+ the handler that makes the call. */
+
+XMLPARSEAPI(const char *)
+XML_GetInputContext(XML_Parser parser,
+ int *offset,
+ int *size);
+
+/* For backwards compatibility with previous versions. */
+#define XML_GetErrorLineNumber XML_GetCurrentLineNumber
+#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber
+#define XML_GetErrorByteIndex XML_GetCurrentByteIndex
+
+/* Frees memory used by the parser. */
+XMLPARSEAPI(void)
+XML_ParserFree(XML_Parser parser);
+
+/* Returns a string describing the error. */
+XMLPARSEAPI(const XML_LChar *)
+XML_ErrorString(int code);
+
+/* Return a string containing the version number of this expat */
+XMLPARSEAPI(const XML_LChar *)
+XML_ExpatVersion(void);
+
+typedef struct {
+ int major;
+ int minor;
+ int micro;
+} XML_Expat_Version;
+
+/* Return an XML_Expat_Version structure containing numeric version
+ number information for this version of expat */
+
+XMLPARSEAPI(XML_Expat_Version)
+XML_ExpatVersionInfo(void);
+
+#define XML_MAJOR_VERSION 1
+#define XML_MINOR_VERSION 95
+#define XML_MICRO_VERSION 2
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* not XmlParse_INCLUDED */
diff --git a/Utilities/cmexpat/expatConfig.h.in b/Utilities/cmexpat/expatConfig.h.in
new file mode 100644
index 000000000..8f9669a59
--- /dev/null
+++ b/Utilities/cmexpat/expatConfig.h.in
@@ -0,0 +1,43 @@
+#include "cm_expat_mangle.h"
+#if defined(_WIN32) || defined(WIN32)
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+#include <memory.h>
+#include <string.h>
+#define XML_BYTE_ORDER 12
+
+#else
+
+#cmakedefine CMEXPAT_BIGENDIAN
+#ifdef CMEXPAT_BIGENDIAN
+# define XML_BYTE_ORDER 21
+#else
+# define XML_BYTE_ORDER 12
+#endif
+
+#endif
+
+#define XML_NS
+#define XML_DTD
+#define XML_CONTEXT_BYTES 1024
+
+#if defined ( _MSC_VER )
+#pragma warning ( disable : 4100 )
+#pragma warning ( disable : 4127 )
+#pragma warning ( disable : 4244 )
+#pragma warning ( disable : 4251 )
+#pragma warning ( disable : 4305 )
+#pragma warning ( disable : 4309 )
+#pragma warning ( disable : 4702 )
+#pragma warning ( disable : 4706 )
+#pragma warning ( disable : 4786 )
+#pragma warning ( disable : 4057 )
+#pragma warning ( disable : 4189 )
+#pragma warning ( disable : 4505 )
+#endif
+
+#define VERSION "1.95.2"
+
+#define cmExpatUnused(x) (void)x
diff --git a/Utilities/cmexpat/expatDllConfig.h.in b/Utilities/cmexpat/expatDllConfig.h.in
new file mode 100644
index 000000000..eaaf4b018
--- /dev/null
+++ b/Utilities/cmexpat/expatDllConfig.h.in
@@ -0,0 +1,6 @@
+#ifndef _expatDllConfig_h
+#define _expatDllConfig_h
+
+#cmakedefine CM_EXPAT_STATIC
+
+#endif
diff --git a/Utilities/cmexpat/iasciitab.h b/Utilities/cmexpat/iasciitab.h
new file mode 100644
index 000000000..55dbc398b
--- /dev/null
+++ b/Utilities/cmexpat/iasciitab.h
@@ -0,0 +1,38 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file COPYING for copying permission.
+*/
+
+/* Like asciitab.h, except that 0xD has code BT_S rather than BT_CR */
+/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
+/* 0x0C */ BT_NONXML, BT_S, BT_NONXML, BT_NONXML,
+/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
+/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
+/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
+/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
+/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
+/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
+/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
+/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
+/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
+/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
+/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
+/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
+/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
+/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
+/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
+/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,
diff --git a/Utilities/cmexpat/latin1tab.h b/Utilities/cmexpat/latin1tab.h
new file mode 100644
index 000000000..178b1d186
--- /dev/null
+++ b/Utilities/cmexpat/latin1tab.h
@@ -0,0 +1,37 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file COPYING for copying permission.
+*/
+
+/* 0x80 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x84 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x88 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x8C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x90 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x94 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x98 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x9C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xA0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xA4 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xA8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
+/* 0xAC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xB0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xB4 */ BT_OTHER, BT_NMSTRT, BT_OTHER, BT_NAME,
+/* 0xB8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
+/* 0xBC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xC0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xC4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xC8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xCC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xD0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xD4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
+/* 0xD8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xDC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xE0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xE4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xE8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xEC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xF0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xF4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
+/* 0xF8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xFC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
diff --git a/Utilities/cmexpat/nametab.h b/Utilities/cmexpat/nametab.h
new file mode 100644
index 000000000..b05e62c77
--- /dev/null
+++ b/Utilities/cmexpat/nametab.h
@@ -0,0 +1,150 @@
+static const unsigned namingBitmap[] = {
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+0x00000000, 0x04000000, 0x87FFFFFE, 0x07FFFFFE,
+0x00000000, 0x00000000, 0xFF7FFFFF, 0xFF7FFFFF,
+0xFFFFFFFF, 0x7FF3FFFF, 0xFFFFFDFE, 0x7FFFFFFF,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFE00F, 0xFC31FFFF,
+0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
+0xFFFFFFFF, 0xF80001FF, 0x00000003, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0xFFFFD740, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
+0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
+0xFFFF0003, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF,
+0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
+0x0000007F, 0x00000000, 0xFFFF0000, 0x000707FF,
+0x00000000, 0x07FFFFFE, 0x000007FE, 0xFFFE0000,
+0xFFFFFFFF, 0x7CFFFFFF, 0x002F7FFF, 0x00000060,
+0xFFFFFFE0, 0x23FFFFFF, 0xFF000000, 0x00000003,
+0xFFF99FE0, 0x03C5FDFF, 0xB0000000, 0x00030003,
+0xFFF987E0, 0x036DFDFF, 0x5E000000, 0x001C0000,
+0xFFFBAFE0, 0x23EDFDFF, 0x00000000, 0x00000001,
+0xFFF99FE0, 0x23CDFDFF, 0xB0000000, 0x00000003,
+0xD63DC7E0, 0x03BFC718, 0x00000000, 0x00000000,
+0xFFFDDFE0, 0x03EFFDFF, 0x00000000, 0x00000003,
+0xFFFDDFE0, 0x03EFFDFF, 0x40000000, 0x00000003,
+0xFFFDDFE0, 0x03FFFDFF, 0x00000000, 0x00000003,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0xFFFFFFFE, 0x000D7FFF, 0x0000003F, 0x00000000,
+0xFEF02596, 0x200D6CAE, 0x0000001F, 0x00000000,
+0x00000000, 0x00000000, 0xFFFFFEFF, 0x000003FF,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0xFFFFFFFF, 0xFFFF003F, 0x007FFFFF,
+0x0007DAED, 0x50000000, 0x82315001, 0x002C62AB,
+0x40000000, 0xF580C900, 0x00000007, 0x02010800,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+0x0FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x03FFFFFF,
+0x3F3FFFFF, 0xFFFFFFFF, 0xAAFF3F3F, 0x3FFFFFFF,
+0xFFFFFFFF, 0x5FDFFFFF, 0x0FCF1FDC, 0x1FDC1FFF,
+0x00000000, 0x00004C40, 0x00000000, 0x00000000,
+0x00000007, 0x00000000, 0x00000000, 0x00000000,
+0x00000080, 0x000003FE, 0xFFFFFFFE, 0xFFFFFFFF,
+0x001FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x07FFFFFF,
+0xFFFFFFE0, 0x00001FFF, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+0xFFFFFFFF, 0x0000003F, 0x00000000, 0x00000000,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+0xFFFFFFFF, 0x0000000F, 0x00000000, 0x00000000,
+0x00000000, 0x07FF6000, 0x87FFFFFE, 0x07FFFFFE,
+0x00000000, 0x00800000, 0xFF7FFFFF, 0xFF7FFFFF,
+0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
+0xFFFFFFFF, 0xF80001FF, 0x00030003, 0x00000000,
+0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000003,
+0xFFFFD7C0, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
+0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
+0xFFFF007B, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF,
+0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
+0xFFFE007F, 0xBBFFFFFB, 0xFFFF0016, 0x000707FF,
+0x00000000, 0x07FFFFFE, 0x0007FFFF, 0xFFFF03FF,
+0xFFFFFFFF, 0x7CFFFFFF, 0xFFEF7FFF, 0x03FF3DFF,
+0xFFFFFFEE, 0xF3FFFFFF, 0xFF1E3FFF, 0x0000FFCF,
+0xFFF99FEE, 0xD3C5FDFF, 0xB080399F, 0x0003FFCF,
+0xFFF987E4, 0xD36DFDFF, 0x5E003987, 0x001FFFC0,
+0xFFFBAFEE, 0xF3EDFDFF, 0x00003BBF, 0x0000FFC1,
+0xFFF99FEE, 0xF3CDFDFF, 0xB0C0398F, 0x0000FFC3,
+0xD63DC7EC, 0xC3BFC718, 0x00803DC7, 0x0000FF80,
+0xFFFDDFEE, 0xC3EFFDFF, 0x00603DDF, 0x0000FFC3,
+0xFFFDDFEC, 0xC3EFFDFF, 0x40603DDF, 0x0000FFC3,
+0xFFFDDFEC, 0xC3FFFDFF, 0x00803DCF, 0x0000FFC3,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0xFFFFFFFE, 0x07FF7FFF, 0x03FF7FFF, 0x00000000,
+0xFEF02596, 0x3BFF6CAE, 0x03FF3F5F, 0x00000000,
+0x03000000, 0xC2A003FF, 0xFFFFFEFF, 0xFFFE03FF,
+0xFEBF0FDF, 0x02FE3FFF, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x1FFF0000, 0x00000002,
+0x000000A0, 0x003EFFFE, 0xFFFFFFFE, 0xFFFFFFFF,
+0x661FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x77FFFFFF,
+};
+static const unsigned char nmstrtPages[] = {
+0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00,
+0x00, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13,
+0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x15, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+static const unsigned char namePages[] = {
+0x19, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x00,
+0x00, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
+0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13,
+0x26, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x27, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
diff --git a/Utilities/cmexpat/utf8tab.h b/Utilities/cmexpat/utf8tab.h
new file mode 100644
index 000000000..9e3b6b83e
--- /dev/null
+++ b/Utilities/cmexpat/utf8tab.h
@@ -0,0 +1,38 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file COPYING for copying permission.
+*/
+
+
+/* 0x80 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x84 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x88 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x8C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x90 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x94 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x98 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x9C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xA0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xA4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xA8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xAC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xB0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xB4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xB8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xBC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xC0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xC4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xC8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xCC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xD0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xD4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xD8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xDC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xE0 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
+/* 0xE4 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
+/* 0xE8 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
+/* 0xEC */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
+/* 0xF0 */ BT_LEAD4, BT_LEAD4, BT_LEAD4, BT_LEAD4,
+/* 0xF4 */ BT_LEAD4, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0xF8 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0xFC */ BT_NONXML, BT_NONXML, BT_MALFORM, BT_MALFORM,
diff --git a/Utilities/cmexpat/xmlparse.c b/Utilities/cmexpat/xmlparse.c
new file mode 100644
index 000000000..29ea3d3d7
--- /dev/null
+++ b/Utilities/cmexpat/xmlparse.c
@@ -0,0 +1,4622 @@
+/*
+Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+See the file COPYING for copying permission.
+*/
+
+#include <cmexpat/expatConfig.h>
+#include <cmexpat/expat.h>
+
+#include <stddef.h>
+#include <string.h>
+
+#ifdef XML_UNICODE
+#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
+#define XmlConvert XmlUtf16Convert
+#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
+#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
+#define XmlEncode XmlUtf16Encode
+#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
+typedef unsigned short ICHAR;
+#else
+#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
+#define XmlConvert XmlUtf8Convert
+#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
+#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
+#define XmlEncode XmlUtf8Encode
+#define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
+typedef char ICHAR;
+#endif
+
+
+#ifndef XML_NS
+
+#define XmlInitEncodingNS XmlInitEncoding
+#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
+#undef XmlGetInternalEncodingNS
+#define XmlGetInternalEncodingNS XmlGetInternalEncoding
+#define XmlParseXmlDeclNS XmlParseXmlDecl
+
+#endif
+
+#ifdef XML_UNICODE_WCHAR_T
+#define XML_T(x) L ## x
+#else
+#define XML_T(x) x
+#endif
+
+/* Round up n to be a multiple of sz, where sz is a power of 2. */
+#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
+
+#include "xmltok.h"
+#include "xmlrole.h"
+
+typedef const XML_Char *KEY;
+
+typedef struct {
+ KEY name;
+} NAMED;
+
+typedef struct {
+ NAMED **v;
+ size_t size;
+ size_t used;
+ size_t usedLim;
+ XML_Memory_Handling_Suite *mem;
+} HASH_TABLE;
+
+typedef struct {
+ NAMED **p;
+ NAMED **end;
+} HASH_TABLE_ITER;
+
+#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
+#define INIT_DATA_BUF_SIZE 1024
+#define INIT_ATTS_SIZE 16
+#define INIT_BLOCK_SIZE 1024
+#define INIT_BUFFER_SIZE 1024
+
+#define EXPAND_SPARE 24
+
+typedef struct binding {
+ struct prefix *prefix;
+ struct binding *nextTagBinding;
+ struct binding *prevPrefixBinding;
+ const struct attribute_id *attId;
+ XML_Char *uri;
+ int uriLen;
+ int uriAlloc;
+} BINDING;
+
+typedef struct prefix {
+ const XML_Char *name;
+ BINDING *binding;
+} PREFIX;
+
+typedef struct {
+ const XML_Char *str;
+ const XML_Char *localPart;
+ int uriLen;
+} TAG_NAME;
+
+typedef struct tag {
+ struct tag *parent;
+ const char *rawName;
+ int rawNameLength;
+ TAG_NAME name;
+ char *buf;
+ char *bufEnd;
+ BINDING *bindings;
+} TAG;
+
+typedef struct {
+ const XML_Char *name;
+ const XML_Char *textPtr;
+ int textLen;
+ const XML_Char *systemId;
+ const XML_Char *base;
+ const XML_Char *publicId;
+ const XML_Char *notation;
+ char open;
+ char is_param;
+} ENTITY;
+
+typedef struct {
+ enum XML_Content_Type type;
+ enum XML_Content_Quant quant;
+ const XML_Char * name;
+ int firstchild;
+ int lastchild;
+ int childcnt;
+ int nextsib;
+} CONTENT_SCAFFOLD;
+
+typedef struct block {
+ struct block *next;
+ int size;
+ XML_Char s[1];
+} BLOCK;
+
+typedef struct {
+ BLOCK *blocks;
+ BLOCK *freeBlocks;
+ const XML_Char *end;
+ XML_Char *ptr;
+ XML_Char *start;
+ XML_Memory_Handling_Suite *mem;
+} STRING_POOL;
+
+/* The XML_Char before the name is used to determine whether
+an attribute has been specified. */
+typedef struct attribute_id {
+ XML_Char *name;
+ PREFIX *prefix;
+ char maybeTokenized;
+ char xmlns;
+} ATTRIBUTE_ID;
+
+typedef struct {
+ const ATTRIBUTE_ID *id;
+ char isCdata;
+ const XML_Char *value;
+} DEFAULT_ATTRIBUTE;
+
+typedef struct {
+ const XML_Char *name;
+ PREFIX *prefix;
+ const ATTRIBUTE_ID *idAtt;
+ int nDefaultAtts;
+ int allocDefaultAtts;
+ DEFAULT_ATTRIBUTE *defaultAtts;
+} ELEMENT_TYPE;
+
+typedef struct {
+ HASH_TABLE generalEntities;
+ HASH_TABLE elementTypes;
+ HASH_TABLE attributeIds;
+ HASH_TABLE prefixes;
+ STRING_POOL pool;
+ int complete;
+ int standalone;
+#ifdef XML_DTD
+ HASH_TABLE paramEntities;
+#endif /* XML_DTD */
+ PREFIX defaultPrefix;
+ /* === scaffolding for building content model === */
+ int in_eldecl;
+ CONTENT_SCAFFOLD *scaffold;
+ unsigned contentStringLen;
+ unsigned scaffSize;
+ unsigned scaffCount;
+ int scaffLevel;
+ int *scaffIndex;
+} DTD;
+
+typedef struct open_internal_entity {
+ const char *internalEventPtr;
+ const char *internalEventEndPtr;
+ struct open_internal_entity *next;
+ ENTITY *entity;
+} OPEN_INTERNAL_ENTITY;
+
+typedef enum XML_Error Processor(XML_Parser parser,
+ const char *start,
+ const char *end,
+ const char **endPtr);
+
+static Processor prologProcessor;
+static Processor prologInitProcessor;
+static Processor contentProcessor;
+static Processor cdataSectionProcessor;
+#ifdef XML_DTD
+static Processor ignoreSectionProcessor;
+#endif /* XML_DTD */
+static Processor epilogProcessor;
+static Processor errorProcessor;
+static Processor externalEntityInitProcessor;
+static Processor externalEntityInitProcessor2;
+static Processor externalEntityInitProcessor3;
+static Processor externalEntityContentProcessor;
+
+static enum XML_Error
+handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
+static enum XML_Error
+processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *, const char *);
+static enum XML_Error
+initializeEncoding(XML_Parser parser);
+static enum XML_Error
+doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
+ const char *end, int tok, const char *next, const char **nextPtr);
+static enum XML_Error
+processInternalParamEntity(XML_Parser parser, ENTITY *entity);
+static enum XML_Error
+doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
+ const char *start, const char *end, const char **endPtr);
+static enum XML_Error
+doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr);
+#ifdef XML_DTD
+static enum XML_Error
+doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr);
+#endif /* XML_DTD */
+static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *, const char *s,
+ TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
+static
+int addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr);
+
+static int
+defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *,
+ int isCdata, int isId, const XML_Char *dfltValue,
+ XML_Parser parser);
+
+static enum XML_Error
+storeAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *,
+ STRING_POOL *);
+static enum XML_Error
+appendAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *,
+ STRING_POOL *);
+static ATTRIBUTE_ID *
+getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
+static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
+static enum XML_Error
+storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
+static int
+reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
+static int
+reportComment(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
+static void
+reportDefault(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
+
+static const XML_Char *getContext(XML_Parser parser);
+static int setContext(XML_Parser parser, const XML_Char *context);
+static void normalizePublicId(XML_Char *s);
+static int dtdInit(DTD *, XML_Parser parser);
+
+static void dtdDestroy(DTD *, XML_Parser parser);
+
+static int dtdCopy(DTD *newDtd, const DTD *oldDtd, XML_Parser parser);
+
+static int copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *,
+ XML_Parser parser);
+
+#ifdef XML_DTD
+static void dtdSwap(DTD *, DTD *);
+#endif /* XML_DTD */
+
+static NAMED *lookup(HASH_TABLE *table, KEY name, size_t createSize);
+
+static void hashTableInit(HASH_TABLE *, XML_Memory_Handling_Suite *ms);
+
+static void hashTableDestroy(HASH_TABLE *);
+static void hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
+static NAMED *hashTableIterNext(HASH_TABLE_ITER *);
+static void poolInit(STRING_POOL *, XML_Memory_Handling_Suite *ms);
+static void poolClear(STRING_POOL *);
+static void poolDestroy(STRING_POOL *);
+static XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
+ const char *ptr, const char *end);
+static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
+ const char *ptr, const char *end);
+
+static int poolGrow(STRING_POOL *pool);
+
+static int nextScaffoldPart(XML_Parser parser);
+static XML_Content *build_model(XML_Parser parser);
+
+static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s);
+static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
+static const XML_Char *poolAppendString(STRING_POOL *pool, const XML_Char *s);
+static ELEMENT_TYPE * getElementType(XML_Parser Paraser,
+ const ENCODING *enc,
+ const char *ptr,
+ const char *end);
+
+#define poolStart(pool) ((pool)->start)
+#define poolEnd(pool) ((pool)->ptr)
+#define poolLength(pool) ((pool)->ptr - (pool)->start)
+#define poolChop(pool) ((void)--(pool->ptr))
+#define poolLastChar(pool) (((pool)->ptr)[-1])
+#define poolDiscard(pool) ((pool)->ptr = (pool)->start)
+#define poolFinish(pool) ((pool)->start = (pool)->ptr)
+#define poolAppendChar(pool, c) \
+ (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
+ ? 0 \
+ : ((*((pool)->ptr)++ = c), 1))
+
+typedef struct {
+ /* The first member must be userData so that the XML_GetUserData macro works. */
+ void *m_userData;
+ void *m_handlerArg;
+ char *m_buffer;
+ XML_Memory_Handling_Suite m_mem;
+ /* first character to be parsed */
+ const char *m_bufferPtr;
+ /* past last character to be parsed */
+ char *m_bufferEnd;
+ /* allocated end of buffer */
+ const char *m_bufferLim;
+ long m_parseEndByteIndex;
+ const char *m_parseEndPtr;
+ XML_Char *m_dataBuf;
+ XML_Char *m_dataBufEnd;
+ XML_StartElementHandler m_startElementHandler;
+ XML_EndElementHandler m_endElementHandler;
+ XML_CharacterDataHandler m_characterDataHandler;
+ XML_ProcessingInstructionHandler m_processingInstructionHandler;
+ XML_CommentHandler m_commentHandler;
+ XML_StartCdataSectionHandler m_startCdataSectionHandler;
+ XML_EndCdataSectionHandler m_endCdataSectionHandler;
+ XML_DefaultHandler m_defaultHandler;
+ XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
+ XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
+ XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
+ XML_NotationDeclHandler m_notationDeclHandler;
+ XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
+ XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
+ XML_NotStandaloneHandler m_notStandaloneHandler;
+ XML_ExternalEntityRefHandler m_externalEntityRefHandler;
+ void *m_externalEntityRefHandlerArg;
+ XML_UnknownEncodingHandler m_unknownEncodingHandler;
+ XML_ElementDeclHandler m_elementDeclHandler;
+ XML_AttlistDeclHandler m_attlistDeclHandler;
+ XML_EntityDeclHandler m_entityDeclHandler;
+ XML_XmlDeclHandler m_xmlDeclHandler;
+ const ENCODING *m_encoding;
+ INIT_ENCODING m_initEncoding;
+ const ENCODING *m_internalEncoding;
+ const XML_Char *m_protocolEncodingName;
+ int m_ns;
+ int m_ns_triplets;
+ void *m_unknownEncodingMem;
+ void *m_unknownEncodingData;
+ void *m_unknownEncodingHandlerData;
+ void (*m_unknownEncodingRelease)(void *);
+ PROLOG_STATE m_prologState;
+ Processor *m_processor;
+ enum XML_Error m_errorCode;
+ const char *m_eventPtr;
+ const char *m_eventEndPtr;
+ const char *m_positionPtr;
+ OPEN_INTERNAL_ENTITY *m_openInternalEntities;
+ int m_defaultExpandInternalEntities;
+ int m_tagLevel;
+ ENTITY *m_declEntity;
+ const XML_Char *m_doctypeName;
+ const XML_Char *m_doctypeSysid;
+ const XML_Char *m_doctypePubid;
+ const XML_Char *m_declAttributeType;
+ const XML_Char *m_declNotationName;
+ const XML_Char *m_declNotationPublicId;
+ ELEMENT_TYPE *m_declElementType;
+ ATTRIBUTE_ID *m_declAttributeId;
+ char m_declAttributeIsCdata;
+ char m_declAttributeIsId;
+ DTD m_dtd;
+ const XML_Char *m_curBase;
+ TAG *m_tagStack;
+ TAG *m_freeTagList;
+ BINDING *m_inheritedBindings;
+ BINDING *m_freeBindingList;
+ int m_attsSize;
+ int m_nSpecifiedAtts;
+ int m_idAttIndex;
+ ATTRIBUTE *m_atts;
+ POSITION m_position;
+ STRING_POOL m_tempPool;
+ STRING_POOL m_temp2Pool;
+ char *m_groupConnector;
+ unsigned m_groupSize;
+ int m_hadExternalDoctype;
+ XML_Char m_namespaceSeparator;
+#ifdef XML_DTD
+ enum XML_ParamEntityParsing m_paramEntityParsing;
+ XML_Parser m_parentParser;
+#endif
+} Parser;
+
+#define MALLOC(s) (((Parser *)parser)->m_mem.malloc_fcn((s)))
+#define REALLOC(p,s) (((Parser *)parser)->m_mem.realloc_fcn((p),(s)))
+#define FREE(p) (((Parser *)parser)->m_mem.free_fcn((p)))
+
+#define userData (((Parser *)parser)->m_userData)
+#define handlerArg (((Parser *)parser)->m_handlerArg)
+#define startElementHandler (((Parser *)parser)->m_startElementHandler)
+#define endElementHandler (((Parser *)parser)->m_endElementHandler)
+#define characterDataHandler (((Parser *)parser)->m_characterDataHandler)
+#define processingInstructionHandler (((Parser *)parser)->m_processingInstructionHandler)
+#define commentHandler (((Parser *)parser)->m_commentHandler)
+#define startCdataSectionHandler (((Parser *)parser)->m_startCdataSectionHandler)
+#define endCdataSectionHandler (((Parser *)parser)->m_endCdataSectionHandler)
+#define defaultHandler (((Parser *)parser)->m_defaultHandler)
+#define startDoctypeDeclHandler (((Parser *)parser)->m_startDoctypeDeclHandler)
+#define endDoctypeDeclHandler (((Parser *)parser)->m_endDoctypeDeclHandler)
+#define unparsedEntityDeclHandler (((Parser *)parser)->m_unparsedEntityDeclHandler)
+#define notationDeclHandler (((Parser *)parser)->m_notationDeclHandler)
+#define startNamespaceDeclHandler (((Parser *)parser)->m_startNamespaceDeclHandler)
+#define endNamespaceDeclHandler (((Parser *)parser)->m_endNamespaceDeclHandler)
+#define notStandaloneHandler (((Parser *)parser)->m_notStandaloneHandler)
+#define externalEntityRefHandler (((Parser *)parser)->m_externalEntityRefHandler)
+#define externalEntityRefHandlerArg (((Parser *)parser)->m_externalEntityRefHandlerArg)
+#define internalEntityRefHandler (((Parser *)parser)->m_internalEntityRefHandler)
+#define unknownEncodingHandler (((Parser *)parser)->m_unknownEncodingHandler)
+#define elementDeclHandler (((Parser *)parser)->m_elementDeclHandler)
+#define attlistDeclHandler (((Parser *)parser)->m_attlistDeclHandler)
+#define entityDeclHandler (((Parser *)parser)->m_entityDeclHandler)
+#define xmlDeclHandler (((Parser *)parser)->m_xmlDeclHandler)
+#define encoding (((Parser *)parser)->m_encoding)
+#define initEncoding (((Parser *)parser)->m_initEncoding)
+#define internalEncoding (((Parser *)parser)->m_internalEncoding)
+#define unknownEncodingMem (((Parser *)parser)->m_unknownEncodingMem)
+#define unknownEncodingData (((Parser *)parser)->m_unknownEncodingData)
+#define unknownEncodingHandlerData \
+ (((Parser *)parser)->m_unknownEncodingHandlerData)
+#define unknownEncodingRelease (((Parser *)parser)->m_unknownEncodingRelease)
+#define protocolEncodingName (((Parser *)parser)->m_protocolEncodingName)
+#define ns (((Parser *)parser)->m_ns)
+#define ns_triplets (((Parser *)parser)->m_ns_triplets)
+#define prologState (((Parser *)parser)->m_prologState)
+#define processor (((Parser *)parser)->m_processor)
+#define errorCode (((Parser *)parser)->m_errorCode)
+#define eventPtr (((Parser *)parser)->m_eventPtr)
+#define eventEndPtr (((Parser *)parser)->m_eventEndPtr)
+#define positionPtr (((Parser *)parser)->m_positionPtr)
+#define position (((Parser *)parser)->m_position)
+#define openInternalEntities (((Parser *)parser)->m_openInternalEntities)
+#define defaultExpandInternalEntities (((Parser *)parser)->m_defaultExpandInternalEntities)
+#define tagLevel (((Parser *)parser)->m_tagLevel)
+#define buffer (((Parser *)parser)->m_buffer)
+#define bufferPtr (((Parser *)parser)->m_bufferPtr)
+#define bufferEnd (((Parser *)parser)->m_bufferEnd)
+#define parseEndByteIndex (((Parser *)parser)->m_parseEndByteIndex)
+#define parseEndPtr (((Parser *)parser)->m_parseEndPtr)
+#define bufferLim (((Parser *)parser)->m_bufferLim)
+#define dataBuf (((Parser *)parser)->m_dataBuf)
+#define dataBufEnd (((Parser *)parser)->m_dataBufEnd)
+#define dtd (((Parser *)parser)->m_dtd)
+#define curBase (((Parser *)parser)->m_curBase)
+#define declEntity (((Parser *)parser)->m_declEntity)
+#define doctypeName (((Parser *)parser)->m_doctypeName)
+#define doctypeSysid (((Parser *)parser)->m_doctypeSysid)
+#define doctypePubid (((Parser *)parser)->m_doctypePubid)
+#define declAttributeType (((Parser *)parser)->m_declAttributeType)
+#define declNotationName (((Parser *)parser)->m_declNotationName)
+#define declNotationPublicId (((Parser *)parser)->m_declNotationPublicId)
+#define declElementType (((Parser *)parser)->m_declElementType)
+#define declAttributeId (((Parser *)parser)->m_declAttributeId)
+#define declAttributeIsCdata (((Parser *)parser)->m_declAttributeIsCdata)
+#define declAttributeIsId (((Parser *)parser)->m_declAttributeIsId)
+#define freeTagList (((Parser *)parser)->m_freeTagList)
+#define freeBindingList (((Parser *)parser)->m_freeBindingList)
+#define inheritedBindings (((Parser *)parser)->m_inheritedBindings)
+#define tagStack (((Parser *)parser)->m_tagStack)
+#define atts (((Parser *)parser)->m_atts)
+#define attsSize (((Parser *)parser)->m_attsSize)
+#define nSpecifiedAtts (((Parser *)parser)->m_nSpecifiedAtts)
+#define idAttIndex (((Parser *)parser)->m_idAttIndex)
+#define tempPool (((Parser *)parser)->m_tempPool)
+#define temp2Pool (((Parser *)parser)->m_temp2Pool)
+#define groupConnector (((Parser *)parser)->m_groupConnector)
+#define groupSize (((Parser *)parser)->m_groupSize)
+#define hadExternalDoctype (((Parser *)parser)->m_hadExternalDoctype)
+#define namespaceSeparator (((Parser *)parser)->m_namespaceSeparator)
+#ifdef XML_DTD
+#define parentParser (((Parser *)parser)->m_parentParser)
+#define paramEntityParsing (((Parser *)parser)->m_paramEntityParsing)
+#endif /* XML_DTD */
+
+#ifdef COMPILED_FROM_DSP
+BOOL WINAPI DllMain(HINSTANCE h, DWORD r, LPVOID p) {
+ return TRUE;
+}
+#endif /* def COMPILED_FROM_DSP */
+
+#ifdef _MSC_VER
+#ifdef _DEBUG
+Parser *asParser(XML_Parser parser)
+{
+ return parser;
+}
+#endif
+#endif
+
+XML_Parser XML_ParserCreate(const XML_Char *encodingName)
+{
+ return XML_ParserCreate_MM(encodingName, NULL, NULL);
+}
+
+XML_Parser XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
+{
+ XML_Char tmp[2];
+ *tmp = nsSep;
+ return XML_ParserCreate_MM(encodingName, NULL, tmp);
+}
+
+XML_Parser
+XML_ParserCreate_MM(const XML_Char *encodingName,
+ const XML_Memory_Handling_Suite *memsuite,
+ const XML_Char *nameSep) {
+
+ XML_Parser parser;
+ static
+ const XML_Char implicitContext[] = {
+ XML_T('x'), XML_T('m'), XML_T('l'), XML_T('='),
+ XML_T('h'), XML_T('t'), XML_T('t'), XML_T('p'), XML_T(':'),
+ XML_T('/'), XML_T('/'), XML_T('w'), XML_T('w'), XML_T('w'),
+ XML_T('.'), XML_T('w'), XML_T('3'),
+ XML_T('.'), XML_T('o'), XML_T('r'), XML_T('g'),
+ XML_T('/'), XML_T('X'), XML_T('M'), XML_T('L'),
+ XML_T('/'), XML_T('1'), XML_T('9'), XML_T('9'), XML_T('8'),
+ XML_T('/'), XML_T('n'), XML_T('a'), XML_T('m'), XML_T('e'),
+ XML_T('s'), XML_T('p'), XML_T('a'), XML_T('c'), XML_T('e'),
+ XML_T('\0')
+ };
+
+
+ if (memsuite) {
+ XML_Memory_Handling_Suite *mtemp;
+ parser = memsuite->malloc_fcn(sizeof(Parser));
+ mtemp = &(((Parser *) parser)->m_mem);
+ mtemp->malloc_fcn = memsuite->malloc_fcn;
+ mtemp->realloc_fcn = memsuite->realloc_fcn;
+ mtemp->free_fcn = memsuite->free_fcn;
+ }
+ else {
+ XML_Memory_Handling_Suite *mtemp;
+ parser = malloc(sizeof(Parser));
+ mtemp = &(((Parser *) parser)->m_mem);
+ mtemp->malloc_fcn = malloc;
+ mtemp->realloc_fcn = realloc;
+ mtemp->free_fcn = free;
+ }
+
+ if (!parser)
+ return parser;
+ processor = prologInitProcessor;
+ XmlPrologStateInit(&prologState);
+ userData = 0;
+ handlerArg = 0;
+ startElementHandler = 0;
+ endElementHandler = 0;
+ characterDataHandler = 0;
+ processingInstructionHandler = 0;
+ commentHandler = 0;
+ startCdataSectionHandler = 0;
+ endCdataSectionHandler = 0;
+ defaultHandler = 0;
+ startDoctypeDeclHandler = 0;
+ endDoctypeDeclHandler = 0;
+ unparsedEntityDeclHandler = 0;
+ notationDeclHandler = 0;
+ startNamespaceDeclHandler = 0;
+ endNamespaceDeclHandler = 0;
+ notStandaloneHandler = 0;
+ externalEntityRefHandler = 0;
+ externalEntityRefHandlerArg = parser;
+ unknownEncodingHandler = 0;
+ elementDeclHandler = 0;
+ attlistDeclHandler = 0;
+ entityDeclHandler = 0;
+ xmlDeclHandler = 0;
+ buffer = 0;
+ bufferPtr = 0;
+ bufferEnd = 0;
+ parseEndByteIndex = 0;
+ parseEndPtr = 0;
+ bufferLim = 0;
+ declElementType = 0;
+ declAttributeId = 0;
+ declEntity = 0;
+ doctypeName = 0;
+ doctypeSysid = 0;
+ doctypePubid = 0;
+ declAttributeType = 0;
+ declNotationName = 0;
+ declNotationPublicId = 0;
+ memset(&position, 0, sizeof(POSITION));
+ errorCode = XML_ERROR_NONE;
+ eventPtr = 0;
+ eventEndPtr = 0;
+ positionPtr = 0;
+ openInternalEntities = 0;
+ tagLevel = 0;
+ tagStack = 0;
+ freeTagList = 0;
+ freeBindingList = 0;
+ inheritedBindings = 0;
+ attsSize = INIT_ATTS_SIZE;
+ atts = MALLOC(attsSize * sizeof(ATTRIBUTE));
+ nSpecifiedAtts = 0;
+ dataBuf = MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
+ groupSize = 0;
+ groupConnector = 0;
+ hadExternalDoctype = 0;
+ unknownEncodingMem = 0;
+ unknownEncodingRelease = 0;
+ unknownEncodingData = 0;
+ unknownEncodingHandlerData = 0;
+ namespaceSeparator = '!';
+#ifdef XML_DTD
+ parentParser = 0;
+ paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
+#endif
+ ns = 0;
+ ns_triplets = 0;
+ poolInit(&tempPool, &(((Parser *) parser)->m_mem));
+ poolInit(&temp2Pool, &(((Parser *) parser)->m_mem));
+ protocolEncodingName = encodingName ? poolCopyString(&tempPool, encodingName) : 0;
+ curBase = 0;
+ if (!dtdInit(&dtd, parser) || !atts || !dataBuf
+ || (encodingName && !protocolEncodingName)) {
+ XML_ParserFree(parser);
+ return 0;
+ }
+ dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
+
+ if (nameSep) {
+ XmlInitEncodingNS(&initEncoding, &encoding, 0);
+ ns = 1;
+ internalEncoding = XmlGetInternalEncodingNS();
+ namespaceSeparator = *nameSep;
+
+ if (! setContext(parser, implicitContext)) {
+ XML_ParserFree(parser);
+ return 0;
+ }
+ }
+ else {
+ XmlInitEncoding(&initEncoding, &encoding, 0);
+ internalEncoding = XmlGetInternalEncoding();
+ }
+
+ return parser;
+} /* End XML_ParserCreate_MM */
+
+int XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
+{
+ if (!encodingName)
+ protocolEncodingName = 0;
+ else {
+ protocolEncodingName = poolCopyString(&tempPool, encodingName);
+ if (!protocolEncodingName)
+ return 0;
+ }
+ return 1;
+}
+
+XML_Parser XML_ExternalEntityParserCreate(XML_Parser oldParser,
+ const XML_Char *context,
+ const XML_Char *encodingName)
+{
+ XML_Parser parser = oldParser;
+ DTD *oldDtd = &dtd;
+ XML_StartElementHandler oldStartElementHandler = startElementHandler;
+ XML_EndElementHandler oldEndElementHandler = endElementHandler;
+ XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
+ XML_ProcessingInstructionHandler oldProcessingInstructionHandler = processingInstructionHandler;
+ XML_CommentHandler oldCommentHandler = commentHandler;
+ XML_StartCdataSectionHandler oldStartCdataSectionHandler = startCdataSectionHandler;
+ XML_EndCdataSectionHandler oldEndCdataSectionHandler = endCdataSectionHandler;
+ XML_DefaultHandler oldDefaultHandler = defaultHandler;
+ XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler = unparsedEntityDeclHandler;
+ XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
+ XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler = startNamespaceDeclHandler;
+ XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler = endNamespaceDeclHandler;
+ XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
+ XML_ExternalEntityRefHandler oldExternalEntityRefHandler = externalEntityRefHandler;
+ XML_UnknownEncodingHandler oldUnknownEncodingHandler = unknownEncodingHandler;
+ XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
+ XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
+ XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
+ XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
+ ELEMENT_TYPE * oldDeclElementType = declElementType;
+
+ void *oldUserData = userData;
+ void *oldHandlerArg = handlerArg;
+ int oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
+ void *oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
+#ifdef XML_DTD
+ enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;
+#endif
+ int oldns_triplets = ns_triplets;
+
+ if (ns) {
+ XML_Char tmp[2];
+
+ *tmp = namespaceSeparator;
+ parser = XML_ParserCreate_MM(encodingName, &((Parser *)parser)->m_mem,
+ tmp);
+ }
+ else {
+ parser = XML_ParserCreate_MM(encodingName, &((Parser *)parser)->m_mem,
+ NULL);
+ }
+
+ if (!parser)
+ return 0;
+
+ startElementHandler = oldStartElementHandler;
+ endElementHandler = oldEndElementHandler;
+ characterDataHandler = oldCharacterDataHandler;
+ processingInstructionHandler = oldProcessingInstructionHandler;
+ commentHandler = oldCommentHandler;
+ startCdataSectionHandler = oldStartCdataSectionHandler;
+ endCdataSectionHandler = oldEndCdataSectionHandler;
+ defaultHandler = oldDefaultHandler;
+ unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
+ notationDeclHandler = oldNotationDeclHandler;
+ startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
+ endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
+ notStandaloneHandler = oldNotStandaloneHandler;
+ externalEntityRefHandler = oldExternalEntityRefHandler;
+ unknownEncodingHandler = oldUnknownEncodingHandler;
+ elementDeclHandler = oldElementDeclHandler;
+ attlistDeclHandler = oldAttlistDeclHandler;
+ entityDeclHandler = oldEntityDeclHandler;
+ xmlDeclHandler = oldXmlDeclHandler;
+ declElementType = oldDeclElementType;
+ userData = oldUserData;
+ if (oldUserData == oldHandlerArg)
+ handlerArg = userData;
+ else
+ handlerArg = parser;
+ if (oldExternalEntityRefHandlerArg != oldParser)
+ externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
+ defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
+ ns_triplets = oldns_triplets;
+#ifdef XML_DTD
+ paramEntityParsing = oldParamEntityParsing;
+ if (context) {
+#endif /* XML_DTD */
+ if (!dtdCopy(&dtd, oldDtd, parser) || !setContext(parser, context)) {
+ XML_ParserFree(parser);
+ return 0;
+ }
+ processor = externalEntityInitProcessor;
+#ifdef XML_DTD
+ }
+ else {
+ dtdSwap(&dtd, oldDtd);
+ parentParser = oldParser;
+ XmlPrologStateInitExternalEntity(&prologState);
+ dtd.complete = 1;
+ hadExternalDoctype = 1;
+ }
+#endif /* XML_DTD */
+ return parser;
+}
+
+static
+void destroyBindings(BINDING *bindings, XML_Parser parser)
+{
+ for (;;) {
+ BINDING *b = bindings;
+ if (!b)
+ break;
+ bindings = b->nextTagBinding;
+ FREE(b->uri);
+ FREE(b);
+ }
+}
+
+void XML_ParserFree(XML_Parser parser)
+{
+ for (;;) {
+ TAG *p;
+ if (tagStack == 0) {
+ if (freeTagList == 0)
+ break;
+ tagStack = freeTagList;
+ freeTagList = 0;
+ }
+ p = tagStack;
+ tagStack = tagStack->parent;
+ FREE(p->buf);
+ destroyBindings(p->bindings, parser);
+ FREE(p);
+ }
+ destroyBindings(freeBindingList, parser);
+ destroyBindings(inheritedBindings, parser);
+ poolDestroy(&tempPool);
+ poolDestroy(&temp2Pool);
+#ifdef XML_DTD
+ if (parentParser) {
+ if (hadExternalDoctype)
+ dtd.complete = 0;
+ dtdSwap(&dtd, &((Parser *)parentParser)->m_dtd);
+ }
+#endif /* XML_DTD */
+ dtdDestroy(&dtd, parser);
+ FREE((void *)atts);
+ if (groupConnector)
+ FREE(groupConnector);
+ if (buffer)
+ FREE(buffer);
+ FREE(dataBuf);
+ if (unknownEncodingMem)
+ FREE(unknownEncodingMem);
+ if (unknownEncodingRelease)
+ unknownEncodingRelease(unknownEncodingData);
+ FREE(parser);
+}
+
+void XML_UseParserAsHandlerArg(XML_Parser parser)
+{
+ handlerArg = parser;
+}
+
+void
+XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) {
+ ns_triplets = do_nst;
+}
+
+void XML_SetUserData(XML_Parser parser, void *p)
+{
+ if (handlerArg == userData)
+ handlerArg = userData = p;
+ else
+ userData = p;
+}
+
+int XML_SetBase(XML_Parser parser, const XML_Char *p)
+{
+ if (p) {
+ p = poolCopyString(&dtd.pool, p);
+ if (!p)
+ return 0;
+ curBase = p;
+ }
+ else
+ curBase = 0;
+ return 1;
+}
+
+const XML_Char *XML_GetBase(XML_Parser parser)
+{
+ return curBase;
+}
+
+int XML_GetSpecifiedAttributeCount(XML_Parser parser)
+{
+ return nSpecifiedAtts;
+}
+
+int XML_GetIdAttributeIndex(XML_Parser parser)
+{
+ return idAttIndex;
+}
+
+void XML_SetElementHandler(XML_Parser parser,
+ XML_StartElementHandler start,
+ XML_EndElementHandler end)
+{
+ startElementHandler = start;
+ endElementHandler = end;
+}
+
+void XML_SetStartElementHandler(XML_Parser parser,
+ XML_StartElementHandler start) {
+ startElementHandler = start;
+}
+
+void XML_SetEndElementHandler(XML_Parser parser,
+ XML_EndElementHandler end) {
+ endElementHandler = end;
+}
+
+void XML_SetCharacterDataHandler(XML_Parser parser,
+ XML_CharacterDataHandler handler)
+{
+ characterDataHandler = handler;
+}
+
+void XML_SetProcessingInstructionHandler(XML_Parser parser,
+ XML_ProcessingInstructionHandler handler)
+{
+ processingInstructionHandler = handler;
+}
+
+void XML_SetCommentHandler(XML_Parser parser,
+ XML_CommentHandler handler)
+{
+ commentHandler = handler;
+}
+
+void XML_SetCdataSectionHandler(XML_Parser parser,
+ XML_StartCdataSectionHandler start,
+ XML_EndCdataSectionHandler end)
+{
+ startCdataSectionHandler = start;
+ endCdataSectionHandler = end;
+}
+
+void XML_SetStartCdataSectionHandler(XML_Parser parser,
+ XML_StartCdataSectionHandler start) {
+ startCdataSectionHandler = start;
+}
+
+void XML_SetEndCdataSectionHandler(XML_Parser parser,
+ XML_EndCdataSectionHandler end) {
+ endCdataSectionHandler = end;
+}
+
+void XML_SetDefaultHandler(XML_Parser parser,
+ XML_DefaultHandler handler)
+{
+ defaultHandler = handler;
+ defaultExpandInternalEntities = 0;
+}
+
+void XML_SetDefaultHandlerExpand(XML_Parser parser,
+ XML_DefaultHandler handler)
+{
+ defaultHandler = handler;
+ defaultExpandInternalEntities = 1;
+}
+
+void XML_SetDoctypeDeclHandler(XML_Parser parser,
+ XML_StartDoctypeDeclHandler start,
+ XML_EndDoctypeDeclHandler end)
+{
+ startDoctypeDeclHandler = start;
+ endDoctypeDeclHandler = end;
+}
+
+void XML_SetStartDoctypeDeclHandler(XML_Parser parser,
+ XML_StartDoctypeDeclHandler start) {
+ startDoctypeDeclHandler = start;
+}
+
+void XML_SetEndDoctypeDeclHandler(XML_Parser parser,
+ XML_EndDoctypeDeclHandler end) {
+ endDoctypeDeclHandler = end;
+}
+
+void XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
+ XML_UnparsedEntityDeclHandler handler)
+{
+ unparsedEntityDeclHandler = handler;
+}
+
+void XML_SetNotationDeclHandler(XML_Parser parser,
+ XML_NotationDeclHandler handler)
+{
+ notationDeclHandler = handler;
+}
+
+void XML_SetNamespaceDeclHandler(XML_Parser parser,
+ XML_StartNamespaceDeclHandler start,
+ XML_EndNamespaceDeclHandler end)
+{
+ startNamespaceDeclHandler = start;
+ endNamespaceDeclHandler = end;
+}
+
+void XML_SetStartNamespaceDeclHandler(XML_Parser parser,
+ XML_StartNamespaceDeclHandler start) {
+ startNamespaceDeclHandler = start;
+}
+
+void XML_SetEndNamespaceDeclHandler(XML_Parser parser,
+ XML_EndNamespaceDeclHandler end) {
+ endNamespaceDeclHandler = end;
+}
+
+
+void XML_SetNotStandaloneHandler(XML_Parser parser,
+ XML_NotStandaloneHandler handler)
+{
+ notStandaloneHandler = handler;
+}
+
+void XML_SetExternalEntityRefHandler(XML_Parser parser,
+ XML_ExternalEntityRefHandler handler)
+{
+ externalEntityRefHandler = handler;
+}
+
+void XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
+{
+ if (arg)
+ externalEntityRefHandlerArg = arg;
+ else
+ externalEntityRefHandlerArg = parser;
+}
+
+void XML_SetUnknownEncodingHandler(XML_Parser parser,
+ XML_UnknownEncodingHandler handler,
+ void *data)
+{
+ unknownEncodingHandler = handler;
+ unknownEncodingHandlerData = data;
+}
+
+void XML_SetElementDeclHandler(XML_Parser parser,
+ XML_ElementDeclHandler eldecl)
+{
+ elementDeclHandler = eldecl;
+}
+
+void XML_SetAttlistDeclHandler(XML_Parser parser,
+ XML_AttlistDeclHandler attdecl)
+{
+ attlistDeclHandler = attdecl;
+}
+
+void XML_SetEntityDeclHandler(XML_Parser parser,
+ XML_EntityDeclHandler handler)
+{
+ entityDeclHandler = handler;
+}
+
+void XML_SetXmlDeclHandler(XML_Parser parser,
+ XML_XmlDeclHandler handler) {
+ xmlDeclHandler = handler;
+}
+
+int XML_SetParamEntityParsing(XML_Parser parser,
+ enum XML_ParamEntityParsing parsing)
+{
+#ifdef XML_DTD
+ paramEntityParsing = parsing;
+ return 1;
+#else
+ return parsing == XML_PARAM_ENTITY_PARSING_NEVER;
+#endif
+}
+
+int XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
+{
+ if (len == 0) {
+ if (!isFinal)
+ return 1;
+ positionPtr = bufferPtr;
+ errorCode = processor(parser, bufferPtr, parseEndPtr = bufferEnd, 0);
+ if (errorCode == XML_ERROR_NONE)
+ return 1;
+ eventEndPtr = eventPtr;
+ processor = errorProcessor;
+ return 0;
+ }
+#ifndef XML_CONTEXT_BYTES
+ else if (bufferPtr == bufferEnd) {
+ const char *end;
+ int nLeftOver;
+ parseEndByteIndex += len;
+ positionPtr = s;
+ if (isFinal) {
+ errorCode = processor(parser, s, parseEndPtr = s + len, 0);
+ if (errorCode == XML_ERROR_NONE)
+ return 1;
+ eventEndPtr = eventPtr;
+ processor = errorProcessor;
+ return 0;
+ }
+ errorCode = processor(parser, s, parseEndPtr = s + len, &end);
+ if (errorCode != XML_ERROR_NONE) {
+ eventEndPtr = eventPtr;
+ processor = errorProcessor;
+ return 0;
+ }
+ XmlUpdatePosition(encoding, positionPtr, end, &position);
+ nLeftOver = s + len - end;
+ if (nLeftOver) {
+ if (buffer == 0 || nLeftOver > bufferLim - buffer) {
+ /* FIXME avoid integer overflow */
+ buffer = buffer == 0 ? MALLOC(len * 2) : REALLOC(buffer, len * 2);
+ /* FIXME storage leak if realloc fails */
+ if (!buffer) {
+ errorCode = XML_ERROR_NO_MEMORY;
+ eventPtr = eventEndPtr = 0;
+ processor = errorProcessor;
+ return 0;
+ }
+ bufferLim = buffer + len * 2;
+ }
+ memcpy(buffer, end, nLeftOver);
+ bufferPtr = buffer;
+ bufferEnd = buffer + nLeftOver;
+ }
+ return 1;
+ }
+#endif /* not defined XML_CONTEXT_BYTES */
+ else {
+ memcpy(XML_GetBuffer(parser, len), s, len);
+ return XML_ParseBuffer(parser, len, isFinal);
+ }
+}
+
+int XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
+{
+ const char *start = bufferPtr;
+ positionPtr = start;
+ bufferEnd += len;
+ parseEndByteIndex += len;
+ errorCode = processor(parser, start, parseEndPtr = bufferEnd,
+ isFinal ? (const char **)0 : &bufferPtr);
+ if (errorCode == XML_ERROR_NONE) {
+ if (!isFinal)
+ XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
+ return 1;
+ }
+ else {
+ eventEndPtr = eventPtr;
+ processor = errorProcessor;
+ return 0;
+ }
+}
+
+void *XML_GetBuffer(XML_Parser parser, int len)
+{
+ if (len > bufferLim - bufferEnd) {
+ /* FIXME avoid integer overflow */
+ int neededSize = len + (bufferEnd - bufferPtr);
+#ifdef XML_CONTEXT_BYTES
+ int keep = bufferPtr - buffer;
+
+ if (keep > XML_CONTEXT_BYTES)
+ keep = XML_CONTEXT_BYTES;
+ neededSize += keep;
+#endif /* defined XML_CONTEXT_BYTES */
+ if (neededSize <= bufferLim - buffer) {
+#ifdef XML_CONTEXT_BYTES
+ if (keep < bufferPtr - buffer) {
+ int offset = (bufferPtr - buffer) - keep;
+ memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
+ bufferEnd -= offset;
+ bufferPtr -= offset;
+ }
+#else
+ memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
+ bufferEnd = buffer + (bufferEnd - bufferPtr);
+ bufferPtr = buffer;
+#endif /* not defined XML_CONTEXT_BYTES */
+ }
+ else {
+ char *newBuf;
+ int bufferSize = bufferLim - bufferPtr;
+ if (bufferSize == 0)
+ bufferSize = INIT_BUFFER_SIZE;
+ do {
+ bufferSize *= 2;
+ } while (bufferSize < neededSize);
+ newBuf = MALLOC(bufferSize);
+ if (newBuf == 0) {
+ errorCode = XML_ERROR_NO_MEMORY;
+ return 0;
+ }
+ bufferLim = newBuf + bufferSize;
+#ifdef XML_CONTEXT_BYTES
+ if (bufferPtr) {
+ int xmKeep = bufferPtr - buffer;
+ if (xmKeep > XML_CONTEXT_BYTES)
+ xmKeep = XML_CONTEXT_BYTES;
+ memcpy(newBuf, &bufferPtr[-xmKeep], bufferEnd - bufferPtr + xmKeep);
+ FREE(buffer);
+ buffer = newBuf;
+ bufferEnd = buffer + (bufferEnd - bufferPtr) + xmKeep;
+ bufferPtr = buffer + xmKeep;
+ }
+ else {
+ bufferEnd = newBuf + (bufferEnd - bufferPtr);
+ bufferPtr = buffer = newBuf;
+ }
+#else
+ if (bufferPtr) {
+ memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
+ FREE(buffer);
+ }
+ bufferEnd = newBuf + (bufferEnd - bufferPtr);
+ bufferPtr = buffer = newBuf;
+#endif /* not defined XML_CONTEXT_BYTES */
+ }
+ }
+ return bufferEnd;
+}
+
+enum XML_Error XML_GetErrorCode(XML_Parser parser)
+{
+ return errorCode;
+}
+
+long XML_GetCurrentByteIndex(XML_Parser parser)
+{
+ if (eventPtr)
+ return parseEndByteIndex - (parseEndPtr - eventPtr);
+ return -1;
+}
+
+int XML_GetCurrentByteCount(XML_Parser parser)
+{
+ if (eventEndPtr && eventPtr)
+ return eventEndPtr - eventPtr;
+ return 0;
+}
+
+const char * XML_GetInputContext(XML_Parser parser, int *offset, int *size)
+{
+#ifdef XML_CONTEXT_BYTES
+ if (eventPtr && buffer) {
+ *offset = eventPtr - buffer;
+ *size = bufferEnd - buffer;
+ return buffer;
+ }
+#endif /* defined XML_CONTEXT_BYTES */
+ return (char *) 0;
+}
+
+int XML_GetCurrentLineNumber(XML_Parser parser)
+{
+ if (eventPtr) {
+ XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
+ positionPtr = eventPtr;
+ }
+ return position.lineNumber + 1;
+}
+
+int XML_GetCurrentColumnNumber(XML_Parser parser)
+{
+ if (eventPtr) {
+ XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
+ positionPtr = eventPtr;
+ }
+ return position.columnNumber;
+}
+
+void XML_DefaultCurrent(XML_Parser parser)
+{
+ if (defaultHandler) {
+ if (openInternalEntities)
+ reportDefault(parser,
+ internalEncoding,
+ openInternalEntities->internalEventPtr,
+ openInternalEntities->internalEventEndPtr);
+ else
+ reportDefault(parser, encoding, eventPtr, eventEndPtr);
+ }
+}
+
+const XML_LChar *XML_ErrorString(int code)
+{
+ static const XML_LChar *message[] = {
+ 0,
+ XML_T("out of memory"),
+ XML_T("syntax error"),
+ XML_T("no element found"),
+ XML_T("not well-formed (invalid token)"),
+ XML_T("unclosed token"),
+ XML_T("unclosed token"),
+ XML_T("mismatched tag"),
+ XML_T("duplicate attribute"),
+ XML_T("junk after document element"),
+ XML_T("illegal parameter entity reference"),
+ XML_T("undefined entity"),
+ XML_T("recursive entity reference"),
+ XML_T("asynchronous entity"),
+ XML_T("reference to invalid character number"),
+ XML_T("reference to binary entity"),
+ XML_T("reference to external entity in attribute"),
+ XML_T("xml processing instruction not at start of external entity"),
+ XML_T("unknown encoding"),
+ XML_T("encoding specified in XML declaration is incorrect"),
+ XML_T("unclosed CDATA section"),
+ XML_T("error in processing external entity reference"),
+ XML_T("document is not standalone"),
+ XML_T("unexpected parser state - please send a bug report")
+ };
+ if (code > 0 && code < (int)(sizeof(message)/sizeof(message[0])))
+ return message[code];
+ return 0;
+}
+
+const XML_LChar *
+XML_ExpatVersion(void) {
+ return VERSION;
+}
+
+XML_Expat_Version
+XML_ExpatVersionInfo(void) {
+ XML_Expat_Version version;
+
+ version.major = XML_MAJOR_VERSION;
+ version.minor = XML_MINOR_VERSION;
+ version.micro = XML_MICRO_VERSION;
+
+ return version;
+}
+
+static
+enum XML_Error contentProcessor(XML_Parser parser,
+ const char *start,
+ const char *end,
+ const char **endPtr)
+{
+ return doContent(parser, 0, encoding, start, end, endPtr);
+}
+
+static
+enum XML_Error externalEntityInitProcessor(XML_Parser parser,
+ const char *start,
+ const char *end,
+ const char **endPtr)
+{
+ enum XML_Error result = initializeEncoding(parser);
+ if (result != XML_ERROR_NONE)
+ return result;
+ processor = externalEntityInitProcessor2;
+ return externalEntityInitProcessor2(parser, start, end, endPtr);
+}
+
+static
+enum XML_Error externalEntityInitProcessor2(XML_Parser parser,
+ const char *start,
+ const char *end,
+ const char **endPtr)
+{
+ const char *next;
+ int tok = XmlContentTok(encoding, start, end, &next);
+ switch (tok) {
+ case XML_TOK_BOM:
+ start = next;
+ break;
+ case XML_TOK_PARTIAL:
+ if (endPtr) {
+ *endPtr = start;
+ return XML_ERROR_NONE;
+ }
+ eventPtr = start;
+ return XML_ERROR_UNCLOSED_TOKEN;
+ case XML_TOK_PARTIAL_CHAR:
+ if (endPtr) {
+ *endPtr = start;
+ return XML_ERROR_NONE;
+ }
+ eventPtr = start;
+ return XML_ERROR_PARTIAL_CHAR;
+ }
+ processor = externalEntityInitProcessor3;
+ return externalEntityInitProcessor3(parser, start, end, endPtr);
+}
+
+static
+enum XML_Error externalEntityInitProcessor3(XML_Parser parser,
+ const char *start,
+ const char *end,
+ const char **endPtr)
+{
+ const char *next;
+ int tok = XmlContentTok(encoding, start, end, &next);
+ switch (tok) {
+ case XML_TOK_XML_DECL:
+ {
+ enum XML_Error result = processXmlDecl(parser, 1, start, next);
+ if (result != XML_ERROR_NONE)
+ return result;
+ start = next;
+ }
+ break;
+ case XML_TOK_PARTIAL:
+ if (endPtr) {
+ *endPtr = start;
+ return XML_ERROR_NONE;
+ }
+ eventPtr = start;
+ return XML_ERROR_UNCLOSED_TOKEN;
+ case XML_TOK_PARTIAL_CHAR:
+ if (endPtr) {
+ *endPtr = start;
+ return XML_ERROR_NONE;
+ }
+ eventPtr = start;
+ return XML_ERROR_PARTIAL_CHAR;
+ }
+ processor = externalEntityContentProcessor;
+ tagLevel = 1;
+ return doContent(parser, 1, encoding, start, end, endPtr);
+}
+
+static
+enum XML_Error externalEntityContentProcessor(XML_Parser parser,
+ const char *start,
+ const char *end,
+ const char **endPtr)
+{
+ return doContent(parser, 1, encoding, start, end, endPtr);
+}
+
+static enum XML_Error
+doContent(XML_Parser parser,
+ int startTagLevel,
+ const ENCODING *enc,
+ const char *s,
+ const char *end,
+ const char **nextPtr)
+{
+ const char **eventPP;
+ const char **eventEndPP;
+ if (enc == encoding) {
+ eventPP = &eventPtr;
+ eventEndPP = &eventEndPtr;
+ }
+ else {
+ eventPP = &(openInternalEntities->internalEventPtr);
+ eventEndPP = &(openInternalEntities->internalEventEndPtr);
+ }
+ *eventPP = s;
+ for (;;) {
+ const char *next = s; /* XmlContentTok doesn't always set the last arg */
+ int tok = XmlContentTok(enc, s, end, &next);
+ *eventEndPP = next;
+ switch (tok) {
+ case XML_TOK_TRAILING_CR:
+ if (nextPtr) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ *eventEndPP = end;
+ if (characterDataHandler) {
+ XML_Char c = 0xA;
+ characterDataHandler(handlerArg, &c, 1);
+ }
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, end);
+ if (startTagLevel == 0)
+ return XML_ERROR_NO_ELEMENTS;
+ if (tagLevel != startTagLevel)
+ return XML_ERROR_ASYNC_ENTITY;
+ return XML_ERROR_NONE;
+ case XML_TOK_NONE:
+ if (nextPtr) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ if (startTagLevel > 0) {
+ if (tagLevel != startTagLevel)
+ return XML_ERROR_ASYNC_ENTITY;
+ return XML_ERROR_NONE;
+ }
+ return XML_ERROR_NO_ELEMENTS;
+ case XML_TOK_INVALID:
+ *eventPP = next;
+ return XML_ERROR_INVALID_TOKEN;
+ case XML_TOK_PARTIAL:
+ if (nextPtr) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ return XML_ERROR_UNCLOSED_TOKEN;
+ case XML_TOK_PARTIAL_CHAR:
+ if (nextPtr) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ return XML_ERROR_PARTIAL_CHAR;
+ case XML_TOK_ENTITY_REF:
+ {
+ const XML_Char *name;
+ ENTITY *entity;
+ XML_Char ch = XmlPredefinedEntityName(enc,
+ s + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (ch) {
+ if (characterDataHandler)
+ characterDataHandler(handlerArg, &ch, 1);
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ break;
+ }
+ name = poolStoreString(&dtd.pool, enc,
+ s + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (!name)
+ return XML_ERROR_NO_MEMORY;
+ entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0);
+ poolDiscard(&dtd.pool);
+ if (!entity) {
+ if (dtd.complete || dtd.standalone)
+ return XML_ERROR_UNDEFINED_ENTITY;
+ if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ break;
+ }
+ if (entity->open)
+ return XML_ERROR_RECURSIVE_ENTITY_REF;
+ if (entity->notation)
+ return XML_ERROR_BINARY_ENTITY_REF;
+ if (entity) {
+ if (entity->textPtr) {
+ enum XML_Error result;
+ OPEN_INTERNAL_ENTITY openEntity;
+ if (defaultHandler && !defaultExpandInternalEntities) {
+ reportDefault(parser, enc, s, next);
+ break;
+ }
+ entity->open = 1;
+ openEntity.next = openInternalEntities;
+ openInternalEntities = &openEntity;
+ openEntity.entity = entity;
+ openEntity.internalEventPtr = 0;
+ openEntity.internalEventEndPtr = 0;
+ result = doContent(parser,
+ tagLevel,
+ internalEncoding,
+ (char *)entity->textPtr,
+ (char *)(entity->textPtr + entity->textLen),
+ 0);
+ entity->open = 0;
+ openInternalEntities = openEntity.next;
+ if (result)
+ return result;
+ }
+ else if (externalEntityRefHandler) {
+ const XML_Char *context;
+ entity->open = 1;
+ context = getContext(parser);
+ entity->open = 0;
+ if (!context)
+ return XML_ERROR_NO_MEMORY;
+ if (!externalEntityRefHandler(externalEntityRefHandlerArg,
+ context,
+ entity->base,
+ entity->systemId,
+ entity->publicId))
+ return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
+ poolDiscard(&tempPool);
+ }
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ }
+ break;
+ }
+ case XML_TOK_START_TAG_WITH_ATTS:
+ if (!startElementHandler) {
+ enum XML_Error result = storeAtts(parser, enc, s, 0, 0);
+ if (result)
+ return result;
+ }
+ /* fall through */
+ case XML_TOK_START_TAG_NO_ATTS:
+ {
+ TAG *tag;
+ if (freeTagList) {
+ tag = freeTagList;
+ freeTagList = freeTagList->parent;
+ }
+ else {
+ tag = MALLOC(sizeof(TAG));
+ if (!tag)
+ return XML_ERROR_NO_MEMORY;
+ tag->buf = MALLOC(INIT_TAG_BUF_SIZE);
+ if (!tag->buf)
+ return XML_ERROR_NO_MEMORY;
+ tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
+ }
+ tag->bindings = 0;
+ tag->parent = tagStack;
+ tagStack = tag;
+ tag->name.localPart = 0;
+ tag->rawName = s + enc->minBytesPerChar;
+ tag->rawNameLength = XmlNameLength(enc, tag->rawName);
+ if (nextPtr) {
+ /* Need to guarantee that:
+ tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)) <= tag->bufEnd - sizeof(XML_Char) */
+ if (tag->rawNameLength + (int)(sizeof(XML_Char) - 1) + (int)sizeof(XML_Char) > tag->bufEnd - tag->buf) {
+ int bufSize = tag->rawNameLength * 4;
+ bufSize = ROUND_UP(bufSize, sizeof(XML_Char));
+ tag->buf = REALLOC(tag->buf, bufSize);
+ if (!tag->buf)
+ return XML_ERROR_NO_MEMORY;
+ tag->bufEnd = tag->buf + bufSize;
+ }
+ memcpy(tag->buf, tag->rawName, tag->rawNameLength);
+ tag->rawName = tag->buf;
+ }
+ ++tagLevel;
+ if (startElementHandler) {
+ enum XML_Error result;
+ XML_Char *toPtr;
+ for (;;) {
+ const char *rawNameEnd = tag->rawName + tag->rawNameLength;
+ const char *fromPtr = tag->rawName;
+ int bufSize;
+ if (nextPtr)
+ toPtr = (XML_Char *)(tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)));
+ else
+ toPtr = (XML_Char *)tag->buf;
+ tag->name.str = toPtr;
+ XmlConvert(enc,
+ &fromPtr, rawNameEnd,
+ (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
+ if (fromPtr == rawNameEnd)
+ break;
+ bufSize = (tag->bufEnd - tag->buf) << 1;
+ tag->buf = REALLOC(tag->buf, bufSize);
+ if (!tag->buf)
+ return XML_ERROR_NO_MEMORY;
+ tag->bufEnd = tag->buf + bufSize;
+ if (nextPtr)
+ tag->rawName = tag->buf;
+ }
+ *toPtr = XML_T('\0');
+ result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
+ if (result)
+ return result;
+ startElementHandler(handlerArg, tag->name.str, (const XML_Char **)atts);
+ poolClear(&tempPool);
+ }
+ else {
+ tag->name.str = 0;
+ if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ }
+ break;
+ }
+ case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
+ if (!startElementHandler) {
+ enum XML_Error result = storeAtts(parser, enc, s, 0, 0);
+ if (result)
+ return result;
+ }
+ /* fall through */
+ case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
+ if (startElementHandler || endElementHandler) {
+ const char *rawName = s + enc->minBytesPerChar;
+ enum XML_Error result;
+ BINDING *bindings = 0;
+ TAG_NAME name;
+ name.str = poolStoreString(&tempPool, enc, rawName,
+ rawName + XmlNameLength(enc, rawName));
+ if (!name.str)
+ return XML_ERROR_NO_MEMORY;
+ poolFinish(&tempPool);
+ result = storeAtts(parser, enc, s, &name, &bindings);
+ if (result)
+ return result;
+ poolFinish(&tempPool);
+ if (startElementHandler)
+ startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
+ if (endElementHandler) {
+ if (startElementHandler)
+ *eventPP = *eventEndPP;
+ endElementHandler(handlerArg, name.str);
+ }
+ poolClear(&tempPool);
+ while (bindings) {
+ BINDING *b = bindings;
+ if (endNamespaceDeclHandler)
+ endNamespaceDeclHandler(handlerArg, b->prefix->name);
+ bindings = bindings->nextTagBinding;
+ b->nextTagBinding = freeBindingList;
+ freeBindingList = b;
+ b->prefix->binding = b->prevPrefixBinding;
+ }
+ }
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ if (tagLevel == 0)
+ return epilogProcessor(parser, next, end, nextPtr);
+ break;
+ case XML_TOK_END_TAG:
+ if (tagLevel == startTagLevel)
+ return XML_ERROR_ASYNC_ENTITY;
+ else {
+ int len;
+ const char *rawName;
+ TAG *tag = tagStack;
+ tagStack = tag->parent;
+ tag->parent = freeTagList;
+ freeTagList = tag;
+ rawName = s + enc->minBytesPerChar*2;
+ len = XmlNameLength(enc, rawName);
+ if (len != tag->rawNameLength
+ || memcmp(tag->rawName, rawName, len) != 0) {
+ *eventPP = rawName;
+ return XML_ERROR_TAG_MISMATCH;
+ }
+ --tagLevel;
+ if (endElementHandler && tag->name.str) {
+ if (tag->name.localPart) {
+ XML_Char *to = (XML_Char *)tag->name.str + tag->name.uriLen;
+ const XML_Char *from = tag->name.localPart;
+ while ((*to++ = *from++) != 0)
+ ;
+ }
+ endElementHandler(handlerArg, tag->name.str);
+ }
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ while (tag->bindings) {
+ BINDING *b = tag->bindings;
+ if (endNamespaceDeclHandler)
+ endNamespaceDeclHandler(handlerArg, b->prefix->name);
+ tag->bindings = tag->bindings->nextTagBinding;
+ b->nextTagBinding = freeBindingList;
+ freeBindingList = b;
+ b->prefix->binding = b->prevPrefixBinding;
+ }
+ if (tagLevel == 0)
+ return epilogProcessor(parser, next, end, nextPtr);
+ }
+ break;
+ case XML_TOK_CHAR_REF:
+ {
+ int n = XmlCharRefNumber(enc, s);
+ if (n < 0)
+ return XML_ERROR_BAD_CHAR_REF;
+ if (characterDataHandler) {
+ XML_Char buf[XML_ENCODE_MAX];
+ characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
+ }
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ }
+ break;
+ case XML_TOK_XML_DECL:
+ return XML_ERROR_MISPLACED_XML_PI;
+ case XML_TOK_DATA_NEWLINE:
+ if (characterDataHandler) {
+ XML_Char c = 0xA;
+ characterDataHandler(handlerArg, &c, 1);
+ }
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ break;
+ case XML_TOK_CDATA_SECT_OPEN:
+ {
+ enum XML_Error result;
+ if (startCdataSectionHandler)
+ startCdataSectionHandler(handlerArg);
+#if 0
+ /* Suppose you doing a transformation on a document that involves
+ changing only the character data. You set up a defaultHandler
+ and a characterDataHandler. The defaultHandler simply copies
+ characters through. The characterDataHandler does the transformation
+ and writes the characters out escaping them as necessary. This case
+ will fail to work if we leave out the following two lines (because &
+ and < inside CDATA sections will be incorrectly escaped).
+
+ However, now we have a start/endCdataSectionHandler, so it seems
+ easier to let the user deal with this. */
+
+ else if (characterDataHandler)
+ characterDataHandler(handlerArg, dataBuf, 0);
+#endif
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ result = doCdataSection(parser, enc, &next, end, nextPtr);
+ if (!next) {
+ processor = cdataSectionProcessor;
+ return result;
+ }
+ }
+ break;
+ case XML_TOK_TRAILING_RSQB:
+ if (nextPtr) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ if (characterDataHandler) {
+ if (MUST_CONVERT(enc, s)) {
+ ICHAR *dataPtr = (ICHAR *)dataBuf;
+ XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
+ characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
+ }
+ else
+ characterDataHandler(handlerArg,
+ (XML_Char *)s,
+ (XML_Char *)end - (XML_Char *)s);
+ }
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, end);
+ if (startTagLevel == 0) {
+ *eventPP = end;
+ return XML_ERROR_NO_ELEMENTS;
+ }
+ if (tagLevel != startTagLevel) {
+ *eventPP = end;
+ return XML_ERROR_ASYNC_ENTITY;
+ }
+ return XML_ERROR_NONE;
+ case XML_TOK_DATA_CHARS:
+ if (characterDataHandler) {
+ if (MUST_CONVERT(enc, s)) {
+ for (;;) {
+ ICHAR *dataPtr = (ICHAR *)dataBuf;
+ XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
+ *eventEndPP = s;
+ characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
+ if (s == next)
+ break;
+ *eventPP = s;
+ }
+ }
+ else
+ characterDataHandler(handlerArg,
+ (XML_Char *)s,
+ (XML_Char *)next - (XML_Char *)s);
+ }
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ break;
+ case XML_TOK_PI:
+ if (!reportProcessingInstruction(parser, enc, s, next))
+ return XML_ERROR_NO_MEMORY;
+ break;
+ case XML_TOK_COMMENT:
+ if (!reportComment(parser, enc, s, next))
+ return XML_ERROR_NO_MEMORY;
+ break;
+ default:
+ if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ break;
+ }
+ *eventPP = s = next;
+ }
+ /* not reached */
+}
+
+/* If tagNamePtr is non-null, build a real list of attributes,
+otherwise just check the attributes for well-formedness. */
+
+static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *enc,
+ const char *attStr, TAG_NAME *tagNamePtr,
+ BINDING **bindingsPtr)
+{
+ ELEMENT_TYPE *elementType = 0;
+ int nDefaultAtts = 0;
+ const XML_Char **appAtts; /* the attribute list to pass to the application */
+ int attIndex = 0;
+ int i;
+ int n;
+ int nPrefixes = 0;
+ BINDING *binding;
+ const XML_Char *localPart;
+
+ /* lookup the element type name */
+ if (tagNamePtr) {
+ elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagNamePtr->str,0);
+ if (!elementType) {
+ tagNamePtr->str = poolCopyString(&dtd.pool, tagNamePtr->str);
+ if (!tagNamePtr->str)
+ return XML_ERROR_NO_MEMORY;
+ elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagNamePtr->str, sizeof(ELEMENT_TYPE));
+ if (!elementType)
+ return XML_ERROR_NO_MEMORY;
+ if (ns && !setElementTypePrefix(parser, elementType))
+ return XML_ERROR_NO_MEMORY;
+ }
+ nDefaultAtts = elementType->nDefaultAtts;
+ }
+ /* get the attributes from the tokenizer */
+ n = XmlGetAttributes(enc, attStr, attsSize, atts);
+ if (n + nDefaultAtts > attsSize) {
+ int oldAttsSize = attsSize;
+ attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
+ atts = REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
+ if (!atts)
+ return XML_ERROR_NO_MEMORY;
+ if (n > oldAttsSize)
+ XmlGetAttributes(enc, attStr, n, atts);
+ }
+ appAtts = (const XML_Char **)atts;
+ for (i = 0; i < n; i++) {
+ /* add the name and value to the attribute list */
+ ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
+ atts[i].name
+ + XmlNameLength(enc, atts[i].name));
+ if (!attId)
+ return XML_ERROR_NO_MEMORY;
+ /* detect duplicate attributes */
+ if ((attId->name)[-1]) {
+ if (enc == encoding)
+ eventPtr = atts[i].name;
+ return XML_ERROR_DUPLICATE_ATTRIBUTE;
+ }
+ (attId->name)[-1] = 1;
+ appAtts[attIndex++] = attId->name;
+ if (!atts[i].normalized) {
+ enum XML_Error result;
+ int isCdata = 1;
+
+ /* figure out whether declared as other than CDATA */
+ if (attId->maybeTokenized) {
+ int j;
+ for (j = 0; j < nDefaultAtts; j++) {
+ if (attId == elementType->defaultAtts[j].id) {
+ isCdata = elementType->defaultAtts[j].isCdata;
+ break;
+ }
+ }
+ }
+
+ /* normalize the attribute value */
+ result = storeAttributeValue(parser, enc, isCdata,
+ atts[i].valuePtr, atts[i].valueEnd,
+ &tempPool);
+ if (result)
+ return result;
+ if (tagNamePtr) {
+ appAtts[attIndex] = poolStart(&tempPool);
+ poolFinish(&tempPool);
+ }
+ else
+ poolDiscard(&tempPool);
+ }
+ else if (tagNamePtr) {
+ /* the value did not need normalizing */
+ appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr, atts[i].valueEnd);
+ if (appAtts[attIndex] == 0)
+ return XML_ERROR_NO_MEMORY;
+ poolFinish(&tempPool);
+ }
+ /* handle prefixed attribute names */
+ if (attId->prefix && tagNamePtr) {
+ if (attId->xmlns) {
+ /* deal with namespace declarations here */
+ if (!addBinding(parser, attId->prefix, attId, appAtts[attIndex], bindingsPtr))
+ return XML_ERROR_NO_MEMORY;
+ --attIndex;
+ }
+ else {
+ /* deal with other prefixed names later */
+ attIndex++;
+ nPrefixes++;
+ (attId->name)[-1] = 2;
+ }
+ }
+ else
+ attIndex++;
+ }
+ if (tagNamePtr) {
+ int j;
+ nSpecifiedAtts = attIndex;
+ if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
+ for (i = 0; i < attIndex; i += 2)
+ if (appAtts[i] == elementType->idAtt->name) {
+ idAttIndex = i;
+ break;
+ }
+ }
+ else
+ idAttIndex = -1;
+ /* do attribute defaulting */
+ for (j = 0; j < nDefaultAtts; j++) {
+ const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + j;
+ if (!(da->id->name)[-1] && da->value) {
+ if (da->id->prefix) {
+ if (da->id->xmlns) {
+ if (!addBinding(parser, da->id->prefix, da->id, da->value, bindingsPtr))
+ return XML_ERROR_NO_MEMORY;
+ }
+ else {
+ (da->id->name)[-1] = 2;
+ nPrefixes++;
+ appAtts[attIndex++] = da->id->name;
+ appAtts[attIndex++] = da->value;
+ }
+ }
+ else {
+ (da->id->name)[-1] = 1;
+ appAtts[attIndex++] = da->id->name;
+ appAtts[attIndex++] = da->value;
+ }
+ }
+ }
+ appAtts[attIndex] = 0;
+ }
+ i = 0;
+ if (nPrefixes) {
+ /* expand prefixed attribute names */
+ for (; i < attIndex; i += 2) {
+ if (appAtts[i][-1] == 2) {
+ ATTRIBUTE_ID *id;
+ ((XML_Char *)(appAtts[i]))[-1] = 0;
+ id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, appAtts[i], 0);
+ if (id->prefix->binding) {
+ int j;
+ const BINDING *b = id->prefix->binding;
+ const XML_Char *s = appAtts[i];
+ for (j = 0; j < b->uriLen; j++) {
+ if (!poolAppendChar(&tempPool, b->uri[j]))
+ return XML_ERROR_NO_MEMORY;
+ }
+ while (*s++ != ':')
+ ;
+ do {
+ if (!poolAppendChar(&tempPool, *s))
+ return XML_ERROR_NO_MEMORY;
+ } while (*s++);
+ if (ns_triplets) {
+ tempPool.ptr[-1] = namespaceSeparator;
+ s = b->prefix->name;
+ do {
+ if (!poolAppendChar(&tempPool, *s))
+ return XML_ERROR_NO_MEMORY;
+ } while (*s++);
+ }
+
+ appAtts[i] = poolStart(&tempPool);
+ poolFinish(&tempPool);
+ }
+ if (!--nPrefixes)
+ break;
+ }
+ else
+ ((XML_Char *)(appAtts[i]))[-1] = 0;
+ }
+ }
+ /* clear the flags that say whether attributes were specified */
+ for (; i < attIndex; i += 2)
+ ((XML_Char *)(appAtts[i]))[-1] = 0;
+ if (!tagNamePtr)
+ return XML_ERROR_NONE;
+ for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
+ binding->attId->name[-1] = 0;
+ /* expand the element type name */
+ if (elementType->prefix) {
+ binding = elementType->prefix->binding;
+ if (!binding)
+ return XML_ERROR_NONE;
+ localPart = tagNamePtr->str;
+ while (*localPart++ != XML_T(':'))
+ ;
+ }
+ else if (dtd.defaultPrefix.binding) {
+ binding = dtd.defaultPrefix.binding;
+ localPart = tagNamePtr->str;
+ }
+ else
+ return XML_ERROR_NONE;
+ tagNamePtr->localPart = localPart;
+ tagNamePtr->uriLen = binding->uriLen;
+ for (i = 0; localPart[i++];)
+ ;
+ n = i + binding->uriLen;
+ if (n > binding->uriAlloc) {
+ TAG *p;
+ XML_Char *uri = MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
+ if (!uri)
+ return XML_ERROR_NO_MEMORY;
+ binding->uriAlloc = n + EXPAND_SPARE;
+ memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
+ for (p = tagStack; p; p = p->parent)
+ if (p->name.str == binding->uri)
+ p->name.str = uri;
+ FREE(binding->uri);
+ binding->uri = uri;
+ }
+ memcpy(binding->uri + binding->uriLen, localPart, i * sizeof(XML_Char));
+ tagNamePtr->str = binding->uri;
+ return XML_ERROR_NONE;
+}
+
+static
+int addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr)
+{
+ BINDING *b;
+ int len;
+ for (len = 0; uri[len]; len++)
+ ;
+ if (namespaceSeparator)
+ len++;
+ if (freeBindingList) {
+ b = freeBindingList;
+ if (len > b->uriAlloc) {
+ b->uri = REALLOC(b->uri, sizeof(XML_Char) * (len + EXPAND_SPARE));
+ if (!b->uri)
+ return 0;
+ b->uriAlloc = len + EXPAND_SPARE;
+ }
+ freeBindingList = b->nextTagBinding;
+ }
+ else {
+ b = MALLOC(sizeof(BINDING));
+ if (!b)
+ return 0;
+ b->uri = MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
+ if (!b->uri) {
+ FREE(b);
+ return 0;
+ }
+ b->uriAlloc = len + EXPAND_SPARE;
+ }
+ b->uriLen = len;
+ memcpy(b->uri, uri, len * sizeof(XML_Char));
+ if (namespaceSeparator)
+ b->uri[len - 1] = namespaceSeparator;
+ b->prefix = prefix;
+ b->attId = attId;
+ b->prevPrefixBinding = prefix->binding;
+ if (*uri == XML_T('\0') && prefix == &dtd.defaultPrefix)
+ prefix->binding = 0;
+ else
+ prefix->binding = b;
+ b->nextTagBinding = *bindingsPtr;
+ *bindingsPtr = b;
+ if (startNamespaceDeclHandler)
+ startNamespaceDeclHandler(handlerArg, prefix->name,
+ prefix->binding ? uri : 0);
+ return 1;
+}
+
+/* The idea here is to avoid using stack for each CDATA section when
+the whole file is parsed with one call. */
+
+static
+enum XML_Error cdataSectionProcessor(XML_Parser parser,
+ const char *start,
+ const char *end,
+ const char **endPtr)
+{
+ enum XML_Error result = doCdataSection(parser, encoding, &start, end, endPtr);
+ if (start) {
+ processor = contentProcessor;
+ return contentProcessor(parser, start, end, endPtr);
+ }
+ return result;
+}
+
+/* startPtr gets set to non-null is the section is closed, and to null if
+the section is not yet closed. */
+
+static
+enum XML_Error doCdataSection(XML_Parser parser,
+ const ENCODING *enc,
+ const char **startPtr,
+ const char *end,
+ const char **nextPtr)
+{
+ const char *s = *startPtr;
+ const char **eventPP;
+ const char **eventEndPP;
+ if (enc == encoding) {
+ eventPP = &eventPtr;
+ *eventPP = s;
+ eventEndPP = &eventEndPtr;
+ }
+ else {
+ eventPP = &(openInternalEntities->internalEventPtr);
+ eventEndPP = &(openInternalEntities->internalEventEndPtr);
+ }
+ *eventPP = s;
+ *startPtr = 0;
+ for (;;) {
+ const char *next;
+ int tok = XmlCdataSectionTok(enc, s, end, &next);
+ *eventEndPP = next;
+ switch (tok) {
+ case XML_TOK_CDATA_SECT_CLOSE:
+ if (endCdataSectionHandler)
+ endCdataSectionHandler(handlerArg);
+#if 0
+ /* see comment under XML_TOK_CDATA_SECT_OPEN */
+ else if (characterDataHandler)
+ characterDataHandler(handlerArg, dataBuf, 0);
+#endif
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ *startPtr = next;
+ return XML_ERROR_NONE;
+ case XML_TOK_DATA_NEWLINE:
+ if (characterDataHandler) {
+ XML_Char c = 0xA;
+ characterDataHandler(handlerArg, &c, 1);
+ }
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ break;
+ case XML_TOK_DATA_CHARS:
+ if (characterDataHandler) {
+ if (MUST_CONVERT(enc, s)) {
+ for (;;) {
+ ICHAR *dataPtr = (ICHAR *)dataBuf;
+ XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
+ *eventEndPP = next;
+ characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
+ if (s == next)
+ break;
+ *eventPP = s;
+ }
+ }
+ else
+ characterDataHandler(handlerArg,
+ (XML_Char *)s,
+ (XML_Char *)next - (XML_Char *)s);
+ }
+ else if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ break;
+ case XML_TOK_INVALID:
+ *eventPP = next;
+ return XML_ERROR_INVALID_TOKEN;
+ case XML_TOK_PARTIAL_CHAR:
+ if (nextPtr) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ return XML_ERROR_PARTIAL_CHAR;
+ case XML_TOK_PARTIAL:
+ case XML_TOK_NONE:
+ if (nextPtr) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ return XML_ERROR_UNCLOSED_CDATA_SECTION;
+ default:
+ *eventPP = next;
+ return XML_ERROR_UNEXPECTED_STATE;
+ }
+ *eventPP = s = next;
+ }
+ /* not reached */
+}
+
+#ifdef XML_DTD
+
+/* The idea here is to avoid using stack for each IGNORE section when
+the whole file is parsed with one call. */
+
+static
+enum XML_Error ignoreSectionProcessor(XML_Parser parser,
+ const char *start,
+ const char *end,
+ const char **endPtr)
+{
+ enum XML_Error result = doIgnoreSection(parser, encoding, &start, end, endPtr);
+ if (start) {
+ processor = prologProcessor;
+ return prologProcessor(parser, start, end, endPtr);
+ }
+ return result;
+}
+
+/* startPtr gets set to non-null is the section is closed, and to null if
+the section is not yet closed. */
+
+static
+enum XML_Error doIgnoreSection(XML_Parser parser,
+ const ENCODING *enc,
+ const char **startPtr,
+ const char *end,
+ const char **nextPtr)
+{
+ const char *next;
+ int tok;
+ const char *s = *startPtr;
+ const char **eventPP;
+ const char **eventEndPP;
+ if (enc == encoding) {
+ eventPP = &eventPtr;
+ *eventPP = s;
+ eventEndPP = &eventEndPtr;
+ }
+ else {
+ eventPP = &(openInternalEntities->internalEventPtr);
+ eventEndPP = &(openInternalEntities->internalEventEndPtr);
+ }
+ *eventPP = s;
+ *startPtr = 0;
+ tok = XmlIgnoreSectionTok(enc, s, end, &next);
+ *eventEndPP = next;
+ switch (tok) {
+ case XML_TOK_IGNORE_SECT:
+ if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ *startPtr = next;
+ return XML_ERROR_NONE;
+ case XML_TOK_INVALID:
+ *eventPP = next;
+ return XML_ERROR_INVALID_TOKEN;
+ case XML_TOK_PARTIAL_CHAR:
+ if (nextPtr) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ return XML_ERROR_PARTIAL_CHAR;
+ case XML_TOK_PARTIAL:
+ case XML_TOK_NONE:
+ if (nextPtr) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
+ default:
+ *eventPP = next;
+ return XML_ERROR_UNEXPECTED_STATE;
+ }
+ /* not reached */
+}
+
+#endif /* XML_DTD */
+
+static enum XML_Error
+initializeEncoding(XML_Parser parser)
+{
+ const char *s;
+#ifdef XML_UNICODE
+ char encodingBuf[128];
+ if (!protocolEncodingName)
+ s = 0;
+ else {
+ int i;
+ for (i = 0; protocolEncodingName[i]; i++) {
+ if (i == sizeof(encodingBuf) - 1
+ || (protocolEncodingName[i] & ~0x7f) != 0) {
+ encodingBuf[0] = '\0';
+ break;
+ }
+ encodingBuf[i] = (char)protocolEncodingName[i];
+ }
+ encodingBuf[i] = '\0';
+ s = encodingBuf;
+ }
+#else
+ s = protocolEncodingName;
+#endif
+ if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
+ return XML_ERROR_NONE;
+ return handleUnknownEncoding(parser, protocolEncodingName);
+}
+
+static enum XML_Error
+processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
+ const char *s, const char *next)
+{
+ const char *encodingName = 0;
+ const char *storedEncName = 0;
+ const ENCODING *newEncoding = 0;
+ const char *version = 0;
+ const char *versionend;
+ const char *storedversion = 0;
+ int standalone = -1;
+ if (!(ns
+ ? XmlParseXmlDeclNS
+ : XmlParseXmlDecl)(isGeneralTextEntity,
+ encoding,
+ s,
+ next,
+ &eventPtr,
+ &version,
+ &versionend,
+ &encodingName,
+ &newEncoding,
+ &standalone))
+ return XML_ERROR_SYNTAX;
+ if (!isGeneralTextEntity && standalone == 1) {
+ dtd.standalone = 1;
+#ifdef XML_DTD
+ if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
+ paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
+#endif /* XML_DTD */
+ }
+ if (xmlDeclHandler) {
+ if (encodingName) {
+ storedEncName = poolStoreString(&temp2Pool,
+ encoding,
+ encodingName,
+ encodingName
+ + XmlNameLength(encoding, encodingName));
+ if (! storedEncName)
+ return XML_ERROR_NO_MEMORY;
+ poolFinish(&temp2Pool);
+ }
+ if (version) {
+ storedversion = poolStoreString(&temp2Pool,
+ encoding,
+ version,
+ versionend - encoding->minBytesPerChar);
+ if (! storedversion)
+ return XML_ERROR_NO_MEMORY;
+ }
+ xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
+ }
+ else if (defaultHandler)
+ reportDefault(parser, encoding, s, next);
+ if (!protocolEncodingName) {
+ if (newEncoding) {
+ if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
+ eventPtr = encodingName;
+ return XML_ERROR_INCORRECT_ENCODING;
+ }
+ encoding = newEncoding;
+ }
+ else if (encodingName) {
+ enum XML_Error result;
+ if (! storedEncName) {
+ storedEncName = poolStoreString(&temp2Pool,
+ encoding,
+ encodingName,
+ encodingName
+ + XmlNameLength(encoding, encodingName));
+ if (! storedEncName)
+ return XML_ERROR_NO_MEMORY;
+ }
+ result = handleUnknownEncoding(parser, storedEncName);
+ poolClear(&tempPool);
+ if (result == XML_ERROR_UNKNOWN_ENCODING)
+ eventPtr = encodingName;
+ return result;
+ }
+ }
+
+ if (storedEncName || storedversion)
+ poolClear(&temp2Pool);
+
+ return XML_ERROR_NONE;
+}
+
+static enum XML_Error
+handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
+{
+ if (unknownEncodingHandler) {
+ XML_Encoding info;
+ int i;
+ for (i = 0; i < 256; i++)
+ info.map[i] = -1;
+ info.convert = 0;
+ info.data = 0;
+ info.release = 0;
+ if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName, &info)) {
+ ENCODING *enc;
+ unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
+ if (!unknownEncodingMem) {
+ if (info.release)
+ info.release(info.data);
+ return XML_ERROR_NO_MEMORY;
+ }
+ enc = (ns
+ ? XmlInitUnknownEncodingNS
+ : XmlInitUnknownEncoding)(unknownEncodingMem,
+ info.map,
+ info.convert,
+ info.data);
+ if (enc) {
+ unknownEncodingData = info.data;
+ unknownEncodingRelease = info.release;
+ encoding = enc;
+ return XML_ERROR_NONE;
+ }
+ }
+ if (info.release)
+ info.release(info.data);
+ }
+ return XML_ERROR_UNKNOWN_ENCODING;
+}
+
+static enum XML_Error
+prologInitProcessor(XML_Parser parser,
+ const char *s,
+ const char *end,
+ const char **nextPtr)
+{
+ enum XML_Error result = initializeEncoding(parser);
+ if (result != XML_ERROR_NONE)
+ return result;
+ processor = prologProcessor;
+ return prologProcessor(parser, s, end, nextPtr);
+}
+
+static enum XML_Error
+prologProcessor(XML_Parser parser,
+ const char *s,
+ const char *end,
+ const char **nextPtr)
+{
+ const char *next;
+ int tok = XmlPrologTok(encoding, s, end, &next);
+ return doProlog(parser, encoding, s, end, tok, next, nextPtr);
+}
+
+static enum XML_Error
+doProlog(XML_Parser parser,
+ const ENCODING *enc,
+ const char *s,
+ const char *end,
+ int tok,
+ const char *next,
+ const char **nextPtr)
+{
+#ifdef XML_DTD
+ static const XML_Char externalSubsetName[] = { '#' , '\0' };
+#endif /* XML_DTD */
+
+ const char **eventPP;
+ const char **eventEndPP;
+ enum XML_Content_Quant quant;
+
+ if (enc == encoding) {
+ eventPP = &eventPtr;
+ eventEndPP = &eventEndPtr;
+ }
+ else {
+ eventPP = &(openInternalEntities->internalEventPtr);
+ eventEndPP = &(openInternalEntities->internalEventEndPtr);
+ }
+ for (;;) {
+ int role;
+ *eventPP = s;
+ *eventEndPP = next;
+ if (tok <= 0) {
+ if (nextPtr != 0 && tok != XML_TOK_INVALID) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ switch (tok) {
+ case XML_TOK_INVALID:
+ *eventPP = next;
+ return XML_ERROR_INVALID_TOKEN;
+ case XML_TOK_PARTIAL:
+ return XML_ERROR_UNCLOSED_TOKEN;
+ case XML_TOK_PARTIAL_CHAR:
+ return XML_ERROR_PARTIAL_CHAR;
+ case XML_TOK_NONE:
+#ifdef XML_DTD
+ if (enc != encoding)
+ return XML_ERROR_NONE;
+ if (parentParser) {
+ if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
+ == XML_ROLE_ERROR)
+ return XML_ERROR_SYNTAX;
+ hadExternalDoctype = 0;
+ return XML_ERROR_NONE;
+ }
+#endif /* XML_DTD */
+ return XML_ERROR_NO_ELEMENTS;
+ default:
+ tok = -tok;
+ next = end;
+ break;
+ }
+ }
+ role = XmlTokenRole(&prologState, tok, s, next, enc);
+ switch (role) {
+ case XML_ROLE_XML_DECL:
+ {
+ enum XML_Error result = processXmlDecl(parser, 0, s, next);
+ if (result != XML_ERROR_NONE)
+ return result;
+ enc = encoding;
+ }
+ break;
+ case XML_ROLE_DOCTYPE_NAME:
+ if (startDoctypeDeclHandler) {
+ doctypeName = poolStoreString(&tempPool, enc, s, next);
+ if (! doctypeName)
+ return XML_ERROR_NO_MEMORY;
+ poolFinish(&tempPool);
+ doctypeSysid = 0;
+ doctypePubid = 0;
+ }
+ break;
+ case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
+ if (startDoctypeDeclHandler) {
+ startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
+ doctypePubid, 1);
+ doctypeName = 0;
+ poolClear(&tempPool);
+ }
+ break;
+#ifdef XML_DTD
+ case XML_ROLE_TEXT_DECL:
+ {
+ enum XML_Error result = processXmlDecl(parser, 1, s, next);
+ if (result != XML_ERROR_NONE)
+ return result;
+ enc = encoding;
+ }
+ break;
+#endif /* XML_DTD */
+ case XML_ROLE_DOCTYPE_PUBLIC_ID:
+ if (startDoctypeDeclHandler) {
+ doctypePubid = poolStoreString(&tempPool, enc, s + 1, next - 1);
+ if (! doctypePubid)
+ return XML_ERROR_NO_MEMORY;
+ poolFinish(&tempPool);
+ }
+#ifdef XML_DTD
+ declEntity = (ENTITY *)lookup(&dtd.paramEntities,
+ externalSubsetName,
+ sizeof(ENTITY));
+ if (!declEntity)
+ return XML_ERROR_NO_MEMORY;
+#endif /* XML_DTD */
+ /* fall through */
+ case XML_ROLE_ENTITY_PUBLIC_ID:
+ if (!XmlIsPublicId(enc, s, next, eventPP))
+ return XML_ERROR_SYNTAX;
+ if (declEntity) {
+ XML_Char *tem = poolStoreString(&dtd.pool,
+ enc,
+ s + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (!tem)
+ return XML_ERROR_NO_MEMORY;
+ normalizePublicId(tem);
+ declEntity->publicId = tem;
+ poolFinish(&dtd.pool);
+ }
+ break;
+ case XML_ROLE_DOCTYPE_CLOSE:
+ if (doctypeName) {
+ startDoctypeDeclHandler(handlerArg, doctypeName,
+ doctypeSysid, doctypePubid, 0);
+ poolClear(&tempPool);
+ }
+ if (dtd.complete && hadExternalDoctype) {
+ dtd.complete = 0;
+#ifdef XML_DTD
+ if (paramEntityParsing && externalEntityRefHandler) {
+ ENTITY *entity = (ENTITY *)lookup(&dtd.paramEntities,
+ externalSubsetName,
+ 0);
+ if (!externalEntityRefHandler(externalEntityRefHandlerArg,
+ 0,
+ entity->base,
+ entity->systemId,
+ entity->publicId))
+ return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
+ }
+#endif /* XML_DTD */
+ if (!dtd.complete
+ && !dtd.standalone
+ && notStandaloneHandler
+ && !notStandaloneHandler(handlerArg))
+ return XML_ERROR_NOT_STANDALONE;
+ }
+ if (endDoctypeDeclHandler)
+ endDoctypeDeclHandler(handlerArg);
+ break;
+ case XML_ROLE_INSTANCE_START:
+ processor = contentProcessor;
+ return contentProcessor(parser, s, end, nextPtr);
+ case XML_ROLE_ATTLIST_ELEMENT_NAME:
+ declElementType = getElementType(parser, enc, s, next);
+ if (!declElementType)
+ return XML_ERROR_NO_MEMORY;
+ break;
+ case XML_ROLE_ATTRIBUTE_NAME:
+ declAttributeId = getAttributeId(parser, enc, s, next);
+ if (!declAttributeId)
+ return XML_ERROR_NO_MEMORY;
+ declAttributeIsCdata = 0;
+ declAttributeType = 0;
+ declAttributeIsId = 0;
+ break;
+ case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
+ declAttributeIsCdata = 1;
+ declAttributeType = "CDATA";
+ break;
+ case XML_ROLE_ATTRIBUTE_TYPE_ID:
+ declAttributeIsId = 1;
+ declAttributeType = "ID";
+ break;
+ case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
+ declAttributeType = "IDREF";
+ break;
+ case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
+ declAttributeType = "IDREFS";
+ break;
+ case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
+ declAttributeType = "ENTITY";
+ break;
+ case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
+ declAttributeType = "ENTITIES";
+ break;
+ case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
+ declAttributeType = "NMTOKEN";
+ break;
+ case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
+ declAttributeType = "NMTOKENS";
+ break;
+
+ case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
+ case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
+ if (attlistDeclHandler)
+ {
+ char *prefix;
+ if (declAttributeType) {
+ prefix = "|";
+ }
+ else {
+ prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
+ ? "NOTATION("
+ : "(");
+ }
+ if (! poolAppendString(&tempPool, prefix))
+ return XML_ERROR_NO_MEMORY;
+ if (! poolAppend(&tempPool, enc, s, next))
+ return XML_ERROR_NO_MEMORY;
+ declAttributeType = tempPool.start;
+ }
+ break;
+ case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
+ case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
+ if (dtd.complete
+ && !defineAttribute(declElementType, declAttributeId,
+ declAttributeIsCdata, declAttributeIsId, 0,
+ parser))
+ return XML_ERROR_NO_MEMORY;
+ if (attlistDeclHandler && declAttributeType) {
+ if (*declAttributeType == '('
+ || (*declAttributeType == 'N' && declAttributeType[1] == 'O')) {
+ /* Enumerated or Notation type */
+ if (! poolAppendChar(&tempPool, ')')
+ || ! poolAppendChar(&tempPool, '\0'))
+ return XML_ERROR_NO_MEMORY;
+ declAttributeType = tempPool.start;
+ poolFinish(&tempPool);
+ }
+ *eventEndPP = s;
+ attlistDeclHandler(handlerArg, declElementType->name,
+ declAttributeId->name, declAttributeType,
+ 0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
+ poolClear(&tempPool);
+ }
+ break;
+ case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
+ case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
+ {
+ const XML_Char *attVal;
+ enum XML_Error result
+ = storeAttributeValue(parser, enc, declAttributeIsCdata,
+ s + enc->minBytesPerChar,
+ next - enc->minBytesPerChar,
+ &dtd.pool);
+ if (result)
+ return result;
+ attVal = poolStart(&dtd.pool);
+ poolFinish(&dtd.pool);
+ if (dtd.complete
+ /* ID attributes aren't allowed to have a default */
+ && !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata, 0, attVal, parser))
+ return XML_ERROR_NO_MEMORY;
+ if (attlistDeclHandler && declAttributeType) {
+ if (*declAttributeType == '('
+ || (*declAttributeType == 'N' && declAttributeType[1] == 'O')) {
+ /* Enumerated or Notation type */
+ if (! poolAppendChar(&tempPool, ')')
+ || ! poolAppendChar(&tempPool, '\0'))
+ return XML_ERROR_NO_MEMORY;
+ declAttributeType = tempPool.start;
+ poolFinish(&tempPool);
+ }
+ *eventEndPP = s;
+ attlistDeclHandler(handlerArg, declElementType->name,
+ declAttributeId->name, declAttributeType,
+ attVal,
+ role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
+ poolClear(&tempPool);
+ }
+ break;
+ }
+ case XML_ROLE_ENTITY_VALUE:
+ {
+ enum XML_Error result = storeEntityValue(parser, enc,
+ s + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (declEntity) {
+ declEntity->textPtr = poolStart(&dtd.pool);
+ declEntity->textLen = poolLength(&dtd.pool);
+ poolFinish(&dtd.pool);
+ if (entityDeclHandler) {
+ *eventEndPP = s;
+ entityDeclHandler(handlerArg,
+ declEntity->name,
+ declEntity->is_param,
+ declEntity->textPtr,
+ declEntity->textLen,
+ curBase, 0, 0, 0);
+ }
+ }
+ else
+ poolDiscard(&dtd.pool);
+ if (result != XML_ERROR_NONE)
+ return result;
+ }
+ break;
+ case XML_ROLE_DOCTYPE_SYSTEM_ID:
+ if (startDoctypeDeclHandler) {
+ doctypeSysid = poolStoreString(&tempPool, enc, s + 1, next - 1);
+ if (! doctypeSysid)
+ return XML_ERROR_NO_MEMORY;
+ poolFinish(&tempPool);
+ }
+ if (!dtd.standalone
+#ifdef XML_DTD
+ && !paramEntityParsing
+#endif /* XML_DTD */
+ && notStandaloneHandler
+ && !notStandaloneHandler(handlerArg))
+ return XML_ERROR_NOT_STANDALONE;
+ hadExternalDoctype = 1;
+#ifndef XML_DTD
+ break;
+#else /* XML_DTD */
+ if (!declEntity) {
+ declEntity = (ENTITY *)lookup(&dtd.paramEntities,
+ externalSubsetName,
+ sizeof(ENTITY));
+ declEntity->publicId = 0;
+ if (!declEntity)
+ return XML_ERROR_NO_MEMORY;
+ }
+ /* fall through */
+#endif /* XML_DTD */
+ case XML_ROLE_ENTITY_SYSTEM_ID:
+ if (declEntity) {
+ declEntity->systemId = poolStoreString(&dtd.pool, enc,
+ s + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (!declEntity->systemId)
+ return XML_ERROR_NO_MEMORY;
+ declEntity->base = curBase;
+ poolFinish(&dtd.pool);
+ }
+ break;
+ case XML_ROLE_ENTITY_COMPLETE:
+ if (declEntity && entityDeclHandler) {
+ *eventEndPP = s;
+ entityDeclHandler(handlerArg,
+ declEntity->name,
+ 0,0,0,
+ declEntity->base,
+ declEntity->systemId,
+ declEntity->publicId,
+ 0);
+ }
+ break;
+ case XML_ROLE_ENTITY_NOTATION_NAME:
+ if (declEntity) {
+ declEntity->notation = poolStoreString(&dtd.pool, enc, s, next);
+ if (!declEntity->notation)
+ return XML_ERROR_NO_MEMORY;
+ poolFinish(&dtd.pool);
+ if (unparsedEntityDeclHandler) {
+ *eventEndPP = s;
+ unparsedEntityDeclHandler(handlerArg,
+ declEntity->name,
+ declEntity->base,
+ declEntity->systemId,
+ declEntity->publicId,
+ declEntity->notation);
+ }
+ else if (entityDeclHandler) {
+ *eventEndPP = s;
+ entityDeclHandler(handlerArg,
+ declEntity->name,
+ 0,0,0,
+ declEntity->base,
+ declEntity->systemId,
+ declEntity->publicId,
+ declEntity->notation);
+ }
+ }
+ break;
+ case XML_ROLE_GENERAL_ENTITY_NAME:
+ {
+ const XML_Char *name;
+ if (XmlPredefinedEntityName(enc, s, next)) {
+ declEntity = 0;
+ break;
+ }
+ name = poolStoreString(&dtd.pool, enc, s, next);
+ if (!name)
+ return XML_ERROR_NO_MEMORY;
+ if (dtd.complete) {
+ declEntity = (ENTITY *)lookup(&dtd.generalEntities, name, sizeof(ENTITY));
+ if (!declEntity)
+ return XML_ERROR_NO_MEMORY;
+ if (declEntity->name != name) {
+ poolDiscard(&dtd.pool);
+ declEntity = 0;
+ }
+ else {
+ poolFinish(&dtd.pool);
+ declEntity->publicId = 0;
+ declEntity->is_param = 0;
+ }
+ }
+ else {
+ poolDiscard(&dtd.pool);
+ declEntity = 0;
+ }
+ }
+ break;
+ case XML_ROLE_PARAM_ENTITY_NAME:
+#ifdef XML_DTD
+ if (dtd.complete) {
+ const XML_Char *name = poolStoreString(&dtd.pool, enc, s, next);
+ if (!name)
+ return XML_ERROR_NO_MEMORY;
+ declEntity = (ENTITY *)lookup(&dtd.paramEntities,
+ name, sizeof(ENTITY));
+ if (!declEntity)
+ return XML_ERROR_NO_MEMORY;
+ if (declEntity->name != name) {
+ poolDiscard(&dtd.pool);
+ declEntity = 0;
+ }
+ else {
+ poolFinish(&dtd.pool);
+ declEntity->publicId = 0;
+ declEntity->is_param = 1;
+ }
+ }
+#else /* not XML_DTD */
+ declEntity = 0;
+#endif /* not XML_DTD */
+ break;
+ case XML_ROLE_NOTATION_NAME:
+ declNotationPublicId = 0;
+ declNotationName = 0;
+ if (notationDeclHandler) {
+ declNotationName = poolStoreString(&tempPool, enc, s, next);
+ if (!declNotationName)
+ return XML_ERROR_NO_MEMORY;
+ poolFinish(&tempPool);
+ }
+ break;
+ case XML_ROLE_NOTATION_PUBLIC_ID:
+ if (!XmlIsPublicId(enc, s, next, eventPP))
+ return XML_ERROR_SYNTAX;
+ if (declNotationName) {
+ XML_Char *tem = poolStoreString(&tempPool,
+ enc,
+ s + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (!tem)
+ return XML_ERROR_NO_MEMORY;
+ normalizePublicId(tem);
+ declNotationPublicId = tem;
+ poolFinish(&tempPool);
+ }
+ break;
+ case XML_ROLE_NOTATION_SYSTEM_ID:
+ if (declNotationName && notationDeclHandler) {
+ const XML_Char *systemId
+ = poolStoreString(&tempPool, enc,
+ s + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (!systemId)
+ return XML_ERROR_NO_MEMORY;
+ *eventEndPP = s;
+ notationDeclHandler(handlerArg,
+ declNotationName,
+ curBase,
+ systemId,
+ declNotationPublicId);
+ }
+ poolClear(&tempPool);
+ break;
+ case XML_ROLE_NOTATION_NO_SYSTEM_ID:
+ if (declNotationPublicId && notationDeclHandler) {
+ *eventEndPP = s;
+ notationDeclHandler(handlerArg,
+ declNotationName,
+ curBase,
+ 0,
+ declNotationPublicId);
+ }
+ poolClear(&tempPool);
+ break;
+ case XML_ROLE_ERROR:
+ switch (tok) {
+ case XML_TOK_PARAM_ENTITY_REF:
+ return XML_ERROR_PARAM_ENTITY_REF;
+ case XML_TOK_XML_DECL:
+ return XML_ERROR_MISPLACED_XML_PI;
+ default:
+ return XML_ERROR_SYNTAX;
+ }
+#ifdef XML_DTD
+ case XML_ROLE_IGNORE_SECT:
+ {
+ enum XML_Error result;
+ if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ result = doIgnoreSection(parser, enc, &next, end, nextPtr);
+ if (!next) {
+ processor = ignoreSectionProcessor;
+ return result;
+ }
+ }
+ break;
+#endif /* XML_DTD */
+ case XML_ROLE_GROUP_OPEN:
+ if (prologState.level >= groupSize) {
+ if (groupSize) {
+ groupConnector = REALLOC(groupConnector, groupSize *= 2);
+ if (dtd.scaffIndex)
+ dtd.scaffIndex = REALLOC(dtd.scaffIndex, groupSize * sizeof(int));
+ }
+ else
+ groupConnector = MALLOC(groupSize = 32);
+ if (!groupConnector)
+ return XML_ERROR_NO_MEMORY;
+ }
+ groupConnector[prologState.level] = 0;
+ if (dtd.in_eldecl) {
+ int myindex = nextScaffoldPart(parser);
+ if (myindex < 0)
+ return XML_ERROR_NO_MEMORY;
+ dtd.scaffIndex[dtd.scaffLevel] = myindex;
+ dtd.scaffLevel++;
+ dtd.scaffold[myindex].type = XML_CTYPE_SEQ;
+ }
+ break;
+ case XML_ROLE_GROUP_SEQUENCE:
+ if (groupConnector[prologState.level] == '|')
+ return XML_ERROR_SYNTAX;
+ groupConnector[prologState.level] = ',';
+ break;
+ case XML_ROLE_GROUP_CHOICE:
+ if (groupConnector[prologState.level] == ',')
+ return XML_ERROR_SYNTAX;
+ if (dtd.in_eldecl
+ && ! groupConnector[prologState.level]
+ && dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]].type != XML_CTYPE_MIXED
+ ) {
+ dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]].type = XML_CTYPE_CHOICE;
+ }
+ groupConnector[prologState.level] = '|';
+ break;
+ case XML_ROLE_PARAM_ENTITY_REF:
+#ifdef XML_DTD
+ case XML_ROLE_INNER_PARAM_ENTITY_REF:
+ if (paramEntityParsing
+ && (dtd.complete || role == XML_ROLE_INNER_PARAM_ENTITY_REF)) {
+ const XML_Char *name;
+ ENTITY *entity;
+ name = poolStoreString(&dtd.pool, enc,
+ s + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (!name)
+ return XML_ERROR_NO_MEMORY;
+ entity = (ENTITY *)lookup(&dtd.paramEntities, name, 0);
+ poolDiscard(&dtd.pool);
+ if (!entity) {
+ /* FIXME what to do if !dtd.complete? */
+ return XML_ERROR_UNDEFINED_ENTITY;
+ }
+ if (entity->open)
+ return XML_ERROR_RECURSIVE_ENTITY_REF;
+ if (entity->textPtr) {
+ enum XML_Error result;
+ result = processInternalParamEntity(parser, entity);
+ if (result != XML_ERROR_NONE)
+ return result;
+ break;
+ }
+ if (role == XML_ROLE_INNER_PARAM_ENTITY_REF)
+ return XML_ERROR_PARAM_ENTITY_REF;
+ if (externalEntityRefHandler) {
+ dtd.complete = 0;
+ entity->open = 1;
+ if (!externalEntityRefHandler(externalEntityRefHandlerArg,
+ 0,
+ entity->base,
+ entity->systemId,
+ entity->publicId)) {
+ entity->open = 0;
+ return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
+ }
+ entity->open = 0;
+ if (dtd.complete)
+ break;
+ }
+ }
+#endif /* XML_DTD */
+ if (!dtd.standalone
+ && notStandaloneHandler
+ && !notStandaloneHandler(handlerArg))
+ return XML_ERROR_NOT_STANDALONE;
+ dtd.complete = 0;
+ if (defaultHandler)
+ reportDefault(parser, enc, s, next);
+ break;
+
+ /* Element declaration stuff */
+
+ case XML_ROLE_ELEMENT_NAME:
+ if (elementDeclHandler) {
+ declElementType = getElementType(parser, enc, s, next);
+ if (! declElementType)
+ return XML_ERROR_NO_MEMORY;
+ dtd.scaffLevel = 0;
+ dtd.scaffCount = 0;
+ dtd.in_eldecl = 1;
+ }
+ break;
+
+ case XML_ROLE_CONTENT_ANY:
+ case XML_ROLE_CONTENT_EMPTY:
+ if (dtd.in_eldecl) {
+ if (elementDeclHandler) {
+ XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));
+ if (! content)
+ return XML_ERROR_NO_MEMORY;
+ content->quant = XML_CQUANT_NONE;
+ content->name = 0;
+ content->numchildren = 0;
+ content->children = 0;
+ content->type = ((role == XML_ROLE_CONTENT_ANY) ?
+ XML_CTYPE_ANY :
+ XML_CTYPE_EMPTY);
+ *eventEndPP = s;
+ elementDeclHandler(handlerArg, declElementType->name, content);
+ }
+ dtd.in_eldecl = 0;
+ }
+ break;
+
+ case XML_ROLE_CONTENT_PCDATA:
+ if (dtd.in_eldecl) {
+ dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]].type = XML_CTYPE_MIXED;
+ }
+ break;
+
+ case XML_ROLE_CONTENT_ELEMENT:
+ quant = XML_CQUANT_NONE;
+ goto elementContent;
+ case XML_ROLE_CONTENT_ELEMENT_OPT:
+ quant = XML_CQUANT_OPT;
+ goto elementContent;
+ case XML_ROLE_CONTENT_ELEMENT_REP:
+ quant = XML_CQUANT_REP;
+ goto elementContent;
+ case XML_ROLE_CONTENT_ELEMENT_PLUS:
+ quant = XML_CQUANT_PLUS;
+ elementContent:
+ if (dtd.in_eldecl)
+ {
+ ELEMENT_TYPE *el;
+ const char *nxt = quant == XML_CQUANT_NONE ? next : next - 1;
+ int myindex = nextScaffoldPart(parser);
+ if (myindex < 0)
+ return XML_ERROR_NO_MEMORY;
+ dtd.scaffold[myindex].type = XML_CTYPE_NAME;
+ dtd.scaffold[myindex].quant = quant;
+ el = getElementType(parser, enc, s, nxt);
+ if (! el)
+ return XML_ERROR_NO_MEMORY;
+ dtd.scaffold[myindex].name = el->name;
+ dtd.contentStringLen += nxt - s + 1;
+ }
+ break;
+
+ case XML_ROLE_GROUP_CLOSE:
+ quant = XML_CQUANT_NONE;
+ goto closeGroup;
+ case XML_ROLE_GROUP_CLOSE_OPT:
+ quant = XML_CQUANT_OPT;
+ goto closeGroup;
+ case XML_ROLE_GROUP_CLOSE_REP:
+ quant = XML_CQUANT_REP;
+ goto closeGroup;
+ case XML_ROLE_GROUP_CLOSE_PLUS:
+ quant = XML_CQUANT_PLUS;
+ closeGroup:
+ if (dtd.in_eldecl) {
+ dtd.scaffLevel--;
+ dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel]].quant = quant;
+ if (dtd.scaffLevel == 0) {
+ if (elementDeclHandler) {
+ XML_Content *model = build_model(parser);
+ if (! model)
+ return XML_ERROR_NO_MEMORY;
+ *eventEndPP = s;
+ elementDeclHandler(handlerArg, declElementType->name, model);
+ }
+ dtd.in_eldecl = 0;
+ dtd.contentStringLen = 0;
+ }
+ }
+ break;
+ /* End element declaration stuff */
+
+ case XML_ROLE_NONE:
+ switch (tok) {
+ case XML_TOK_PI:
+ if (!reportProcessingInstruction(parser, enc, s, next))
+ return XML_ERROR_NO_MEMORY;
+ break;
+ case XML_TOK_COMMENT:
+ if (!reportComment(parser, enc, s, next))
+ return XML_ERROR_NO_MEMORY;
+ break;
+ }
+ break;
+ }
+ if (defaultHandler) {
+ switch (tok) {
+ case XML_TOK_PI:
+ case XML_TOK_COMMENT:
+ case XML_TOK_BOM:
+ case XML_TOK_XML_DECL:
+#ifdef XML_DTD
+ case XML_TOK_IGNORE_SECT:
+#endif /* XML_DTD */
+ case XML_TOK_PARAM_ENTITY_REF:
+ break;
+ default:
+#ifdef XML_DTD
+ if (role != XML_ROLE_IGNORE_SECT)
+#endif /* XML_DTD */
+ reportDefault(parser, enc, s, next);
+ }
+ }
+ s = next;
+ tok = XmlPrologTok(enc, s, end, &next);
+ }
+ /* not reached */
+}
+
+static
+enum XML_Error epilogProcessor(XML_Parser parser,
+ const char *s,
+ const char *end,
+ const char **nextPtr)
+{
+ processor = epilogProcessor;
+ eventPtr = s;
+ for (;;) {
+ const char *next;
+ int tok = XmlPrologTok(encoding, s, end, &next);
+ eventEndPtr = next;
+ switch (tok) {
+ case -XML_TOK_PROLOG_S:
+ if (defaultHandler) {
+ eventEndPtr = end;
+ reportDefault(parser, encoding, s, end);
+ }
+ /* fall through */
+ case XML_TOK_NONE:
+ if (nextPtr)
+ *nextPtr = end;
+ return XML_ERROR_NONE;
+ case XML_TOK_PROLOG_S:
+ if (defaultHandler)
+ reportDefault(parser, encoding, s, next);
+ break;
+ case XML_TOK_PI:
+ if (!reportProcessingInstruction(parser, encoding, s, next))
+ return XML_ERROR_NO_MEMORY;
+ break;
+ case XML_TOK_COMMENT:
+ if (!reportComment(parser, encoding, s, next))
+ return XML_ERROR_NO_MEMORY;
+ break;
+ case XML_TOK_INVALID:
+ eventPtr = next;
+ return XML_ERROR_INVALID_TOKEN;
+ case XML_TOK_PARTIAL:
+ if (nextPtr) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ return XML_ERROR_UNCLOSED_TOKEN;
+ case XML_TOK_PARTIAL_CHAR:
+ if (nextPtr) {
+ *nextPtr = s;
+ return XML_ERROR_NONE;
+ }
+ return XML_ERROR_PARTIAL_CHAR;
+ default:
+ return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
+ }
+ eventPtr = s = next;
+ }
+}
+
+#ifdef XML_DTD
+
+static enum XML_Error
+processInternalParamEntity(XML_Parser parser, ENTITY *entity)
+{
+ const char *s, *end, *next;
+ int tok;
+ enum XML_Error result;
+ OPEN_INTERNAL_ENTITY openEntity;
+ entity->open = 1;
+ openEntity.next = openInternalEntities;
+ openInternalEntities = &openEntity;
+ openEntity.entity = entity;
+ openEntity.internalEventPtr = 0;
+ openEntity.internalEventEndPtr = 0;
+ s = (char *)entity->textPtr;
+ end = (char *)(entity->textPtr + entity->textLen);
+ tok = XmlPrologTok(internalEncoding, s, end, &next);
+ result = doProlog(parser, internalEncoding, s, end, tok, next, 0);
+ entity->open = 0;
+ openInternalEntities = openEntity.next;
+ return result;
+}
+
+#endif /* XML_DTD */
+
+static
+enum XML_Error errorProcessor(XML_Parser parser,
+ const char *s,
+ const char *end,
+ const char **nextPtr)
+{
+ cmExpatUnused(s);
+ cmExpatUnused(end);
+ cmExpatUnused(nextPtr);
+ return errorCode;
+}
+
+static enum XML_Error
+storeAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata,
+ const char *ptr, const char *end,
+ STRING_POOL *pool)
+{
+ enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr, end, pool);
+ if (result)
+ return result;
+ if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
+ poolChop(pool);
+ if (!poolAppendChar(pool, XML_T('\0')))
+ return XML_ERROR_NO_MEMORY;
+ return XML_ERROR_NONE;
+}
+
+static enum XML_Error
+appendAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata,
+ const char *ptr, const char *end,
+ STRING_POOL *pool)
+{
+ for (;;) {
+ const char *next;
+ int tok = XmlAttributeValueTok(enc, ptr, end, &next);
+ switch (tok) {
+ case XML_TOK_NONE:
+ return XML_ERROR_NONE;
+ case XML_TOK_INVALID:
+ if (enc == encoding)
+ eventPtr = next;
+ return XML_ERROR_INVALID_TOKEN;
+ case XML_TOK_PARTIAL:
+ if (enc == encoding)
+ eventPtr = ptr;
+ return XML_ERROR_INVALID_TOKEN;
+ case XML_TOK_CHAR_REF:
+ {
+ XML_Char buf[XML_ENCODE_MAX];
+ int i;
+ int n = XmlCharRefNumber(enc, ptr);
+ if (n < 0) {
+ if (enc == encoding)
+ eventPtr = ptr;
+ return XML_ERROR_BAD_CHAR_REF;
+ }
+ if (!isCdata
+ && n == 0x20 /* space */
+ && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
+ break;
+ n = XmlEncode(n, (ICHAR *)buf);
+ if (!n) {
+ if (enc == encoding)
+ eventPtr = ptr;
+ return XML_ERROR_BAD_CHAR_REF;
+ }
+ for (i = 0; i < n; i++) {
+ if (!poolAppendChar(pool, buf[i]))
+ return XML_ERROR_NO_MEMORY;
+ }
+ }
+ break;
+ case XML_TOK_DATA_CHARS:
+ if (!poolAppend(pool, enc, ptr, next))
+ return XML_ERROR_NO_MEMORY;
+ break;
+ case XML_TOK_TRAILING_CR:
+ next = ptr + enc->minBytesPerChar;
+ /* fall through */
+ case XML_TOK_ATTRIBUTE_VALUE_S:
+ case XML_TOK_DATA_NEWLINE:
+ if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
+ break;
+ if (!poolAppendChar(pool, 0x20))
+ return XML_ERROR_NO_MEMORY;
+ break;
+ case XML_TOK_ENTITY_REF:
+ {
+ const XML_Char *name;
+ ENTITY *entity;
+ XML_Char ch = XmlPredefinedEntityName(enc,
+ ptr + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (ch) {
+ if (!poolAppendChar(pool, ch))
+ return XML_ERROR_NO_MEMORY;
+ break;
+ }
+ name = poolStoreString(&temp2Pool, enc,
+ ptr + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (!name)
+ return XML_ERROR_NO_MEMORY;
+ entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0);
+ poolDiscard(&temp2Pool);
+ if (!entity) {
+ if (dtd.complete) {
+ if (enc == encoding)
+ eventPtr = ptr;
+ return XML_ERROR_UNDEFINED_ENTITY;
+ }
+ }
+ else if (entity->open) {
+ if (enc == encoding)
+ eventPtr = ptr;
+ return XML_ERROR_RECURSIVE_ENTITY_REF;
+ }
+ else if (entity->notation) {
+ if (enc == encoding)
+ eventPtr = ptr;
+ return XML_ERROR_BINARY_ENTITY_REF;
+ }
+ else if (!entity->textPtr) {
+ if (enc == encoding)
+ eventPtr = ptr;
+ return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
+ }
+ else {
+ enum XML_Error result;
+ const XML_Char *textEnd = entity->textPtr + entity->textLen;
+ entity->open = 1;
+ result = appendAttributeValue(parser, internalEncoding, isCdata, (char *)entity->textPtr, (char *)textEnd, pool);
+ entity->open = 0;
+ if (result)
+ return result;
+ }
+ }
+ break;
+ default:
+ if (enc == encoding)
+ eventPtr = ptr;
+ return XML_ERROR_UNEXPECTED_STATE;
+ }
+ ptr = next;
+ }
+ /* not reached */
+}
+
+static
+enum XML_Error storeEntityValue(XML_Parser parser,
+ const ENCODING *enc,
+ const char *entityTextPtr,
+ const char *entityTextEnd)
+{
+ STRING_POOL *pool = &(dtd.pool);
+ for (;;) {
+ const char *next;
+ int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
+ switch (tok) {
+ case XML_TOK_PARAM_ENTITY_REF:
+#ifdef XML_DTD
+ if (parentParser || enc != encoding) {
+ enum XML_Error result;
+ const XML_Char *name;
+ ENTITY *entity;
+ name = poolStoreString(&tempPool, enc,
+ entityTextPtr + enc->minBytesPerChar,
+ next - enc->minBytesPerChar);
+ if (!name)
+ return XML_ERROR_NO_MEMORY;
+ entity = (ENTITY *)lookup(&dtd.paramEntities, name, 0);
+ poolDiscard(&tempPool);
+ if (!entity) {
+ if (enc == encoding)
+ eventPtr = entityTextPtr;
+ return XML_ERROR_UNDEFINED_ENTITY;
+ }
+ if (entity->open) {
+ if (enc == encoding)
+ eventPtr = entityTextPtr;
+ return XML_ERROR_RECURSIVE_ENTITY_REF;
+ }
+ if (entity->systemId) {
+ if (enc == encoding)
+ eventPtr = entityTextPtr;
+ return XML_ERROR_PARAM_ENTITY_REF;
+ }
+ entity->open = 1;
+ result = storeEntityValue(parser,
+ internalEncoding,
+ (char *)entity->textPtr,
+ (char *)(entity->textPtr + entity->textLen));
+ entity->open = 0;
+ if (result)
+ return result;
+ break;
+ }
+#endif /* XML_DTD */
+ eventPtr = entityTextPtr;
+ return XML_ERROR_SYNTAX;
+ case XML_TOK_NONE:
+ return XML_ERROR_NONE;
+ case XML_TOK_ENTITY_REF:
+ case XML_TOK_DATA_CHARS:
+ if (!poolAppend(pool, enc, entityTextPtr, next))
+ return XML_ERROR_NO_MEMORY;
+ break;
+ case XML_TOK_TRAILING_CR:
+ next = entityTextPtr + enc->minBytesPerChar;
+ /* fall through */
+ case XML_TOK_DATA_NEWLINE:
+ if (pool->end == pool->ptr && !poolGrow(pool))
+ return XML_ERROR_NO_MEMORY;
+ *(pool->ptr)++ = 0xA;
+ break;
+ case XML_TOK_CHAR_REF:
+ {
+ XML_Char buf[XML_ENCODE_MAX];
+ int i;
+ int n = XmlCharRefNumber(enc, entityTextPtr);
+ if (n < 0) {
+ if (enc == encoding)
+ eventPtr = entityTextPtr;
+ return XML_ERROR_BAD_CHAR_REF;
+ }
+ n = XmlEncode(n, (ICHAR *)buf);
+ if (!n) {
+ if (enc == encoding)
+ eventPtr = entityTextPtr;
+ return XML_ERROR_BAD_CHAR_REF;
+ }
+ for (i = 0; i < n; i++) {
+ if (pool->end == pool->ptr && !poolGrow(pool))
+ return XML_ERROR_NO_MEMORY;
+ *(pool->ptr)++ = buf[i];
+ }
+ }
+ break;
+ case XML_TOK_PARTIAL:
+ if (enc == encoding)
+ eventPtr = entityTextPtr;
+ return XML_ERROR_INVALID_TOKEN;
+ case XML_TOK_INVALID:
+ if (enc == encoding)
+ eventPtr = next;
+ return XML_ERROR_INVALID_TOKEN;
+ default:
+ if (enc == encoding)
+ eventPtr = entityTextPtr;
+ return XML_ERROR_UNEXPECTED_STATE;
+ }
+ entityTextPtr = next;
+ }
+ /* not reached */
+}
+
+static void
+normalizeLines(XML_Char *s)
+{
+ XML_Char *p;
+ for (;; s++) {
+ if (*s == XML_T('\0'))
+ return;
+ if (*s == 0xD)
+ break;
+ }
+ p = s;
+ do {
+ if (*s == 0xD) {
+ *p++ = 0xA;
+ if (*++s == 0xA)
+ s++;
+ }
+ else
+ *p++ = *s++;
+ } while (*s);
+ *p = XML_T('\0');
+}
+
+static int
+reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
+{
+ const XML_Char *target;
+ XML_Char *data;
+ const char *tem;
+ if (!processingInstructionHandler) {
+ if (defaultHandler)
+ reportDefault(parser, enc, start, end);
+ return 1;
+ }
+ start += enc->minBytesPerChar * 2;
+ tem = start + XmlNameLength(enc, start);
+ target = poolStoreString(&tempPool, enc, start, tem);
+ if (!target)
+ return 0;
+ poolFinish(&tempPool);
+ data = poolStoreString(&tempPool, enc,
+ XmlSkipS(enc, tem),
+ end - enc->minBytesPerChar*2);
+ if (!data)
+ return 0;
+ normalizeLines(data);
+ processingInstructionHandler(handlerArg, target, data);
+ poolClear(&tempPool);
+ return 1;
+}
+
+static int
+reportComment(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
+{
+ XML_Char *data;
+ if (!commentHandler) {
+ if (defaultHandler)
+ reportDefault(parser, enc, start, end);
+ return 1;
+ }
+ data = poolStoreString(&tempPool,
+ enc,
+ start + enc->minBytesPerChar * 4,
+ end - enc->minBytesPerChar * 3);
+ if (!data)
+ return 0;
+ normalizeLines(data);
+ commentHandler(handlerArg, data);
+ poolClear(&tempPool);
+ return 1;
+}
+
+static void
+reportDefault(XML_Parser parser, const ENCODING *enc, const char *s, const char *end)
+{
+ if (MUST_CONVERT(enc, s)) {
+ const char **eventPP;
+ const char **eventEndPP;
+ if (enc == encoding) {
+ eventPP = &eventPtr;
+ eventEndPP = &eventEndPtr;
+ }
+ else {
+ eventPP = &(openInternalEntities->internalEventPtr);
+ eventEndPP = &(openInternalEntities->internalEventEndPtr);
+ }
+ do {
+ ICHAR *dataPtr = (ICHAR *)dataBuf;
+ XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
+ *eventEndPP = s;
+ defaultHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
+ *eventPP = s;
+ } while (s != end);
+ }
+ else
+ defaultHandler(handlerArg, (XML_Char *)s, (XML_Char *)end - (XML_Char *)s);
+}
+
+
+static int
+defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, int isCdata,
+ int isId, const XML_Char *value, XML_Parser parser)
+{
+ DEFAULT_ATTRIBUTE *att;
+ if (value || isId) {
+ /* The handling of default attributes gets messed up if we have
+ a default which duplicates a non-default. */
+ int i;
+ for (i = 0; i < type->nDefaultAtts; i++)
+ if (attId == type->defaultAtts[i].id)
+ return 1;
+ if (isId && !type->idAtt && !attId->xmlns)
+ type->idAtt = attId;
+ }
+ if (type->nDefaultAtts == type->allocDefaultAtts) {
+ if (type->allocDefaultAtts == 0) {
+ type->allocDefaultAtts = 8;
+ type->defaultAtts = MALLOC(type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE));
+ }
+ else {
+ type->allocDefaultAtts *= 2;
+ type->defaultAtts = REALLOC(type->defaultAtts,
+ type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE));
+ }
+ if (!type->defaultAtts)
+ return 0;
+ }
+ att = type->defaultAtts + type->nDefaultAtts;
+ att->id = attId;
+ att->value = value;
+ att->isCdata = isCdata;
+ if (!isCdata)
+ attId->maybeTokenized = 1;
+ type->nDefaultAtts += 1;
+ return 1;
+}
+
+static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
+{
+ const XML_Char *name;
+ for (name = elementType->name; *name; name++) {
+ if (*name == XML_T(':')) {
+ PREFIX *prefix;
+ const XML_Char *s;
+ for (s = elementType->name; s != name; s++) {
+ if (!poolAppendChar(&dtd.pool, *s))
+ return 0;
+ }
+ if (!poolAppendChar(&dtd.pool, XML_T('\0')))
+ return 0;
+ prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&dtd.pool), sizeof(PREFIX));
+ if (!prefix)
+ return 0;
+ if (prefix->name == poolStart(&dtd.pool))
+ poolFinish(&dtd.pool);
+ else
+ poolDiscard(&dtd.pool);
+ elementType->prefix = prefix;
+
+ }
+ }
+ return 1;
+}
+
+static ATTRIBUTE_ID *
+getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
+{
+ ATTRIBUTE_ID *id;
+ const XML_Char *name;
+ if (!poolAppendChar(&dtd.pool, XML_T('\0')))
+ return 0;
+ name = poolStoreString(&dtd.pool, enc, start, end);
+ if (!name)
+ return 0;
+ ++name;
+ id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, name, sizeof(ATTRIBUTE_ID));
+ if (!id)
+ return 0;
+ if (id->name != name)
+ poolDiscard(&dtd.pool);
+ else {
+ poolFinish(&dtd.pool);
+ if (!ns)
+ ;
+ else if (name[0] == 'x'
+ && name[1] == 'm'
+ && name[2] == 'l'
+ && name[3] == 'n'
+ && name[4] == 's'
+ && (name[5] == XML_T('\0') || name[5] == XML_T(':'))) {
+ if (name[5] == '\0')
+ id->prefix = &dtd.defaultPrefix;
+ else
+ id->prefix = (PREFIX *)lookup(&dtd.prefixes, name + 6, sizeof(PREFIX));
+ id->xmlns = 1;
+ }
+ else {
+ int i;
+ for (i = 0; name[i]; i++) {
+ if (name[i] == XML_T(':')) {
+ int j;
+ for (j = 0; j < i; j++) {
+ if (!poolAppendChar(&dtd.pool, name[j]))
+ return 0;
+ }
+ if (!poolAppendChar(&dtd.pool, XML_T('\0')))
+ return 0;
+ id->prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&dtd.pool), sizeof(PREFIX));
+ if (id->prefix->name == poolStart(&dtd.pool))
+ poolFinish(&dtd.pool);
+ else
+ poolDiscard(&dtd.pool);
+ break;
+ }
+ }
+ }
+ }
+ return id;
+}
+
+#define CONTEXT_SEP XML_T('\f')
+
+static
+const XML_Char *getContext(XML_Parser parser)
+{
+ HASH_TABLE_ITER iter;
+ int needSep = 0;
+
+ if (dtd.defaultPrefix.binding) {
+ int i;
+ int len;
+ if (!poolAppendChar(&tempPool, XML_T('=')))
+ return 0;
+ len = dtd.defaultPrefix.binding->uriLen;
+ if (namespaceSeparator != XML_T('\0'))
+ len--;
+ for (i = 0; i < len; i++)
+ if (!poolAppendChar(&tempPool, dtd.defaultPrefix.binding->uri[i]))
+ return 0;
+ needSep = 1;
+ }
+
+ hashTableIterInit(&iter, &(dtd.prefixes));
+ for (;;) {
+ int i;
+ int len;
+ const XML_Char *s;
+ PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
+ if (!prefix)
+ break;
+ if (!prefix->binding)
+ continue;
+ if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
+ return 0;
+ for (s = prefix->name; *s; s++)
+ if (!poolAppendChar(&tempPool, *s))
+ return 0;
+ if (!poolAppendChar(&tempPool, XML_T('=')))
+ return 0;
+ len = prefix->binding->uriLen;
+ if (namespaceSeparator != XML_T('\0'))
+ len--;
+ for (i = 0; i < len; i++)
+ if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
+ return 0;
+ needSep = 1;
+ }
+
+
+ hashTableIterInit(&iter, &(dtd.generalEntities));
+ for (;;) {
+ const XML_Char *s;
+ ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
+ if (!e)
+ break;
+ if (!e->open)
+ continue;
+ if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
+ return 0;
+ for (s = e->name; *s; s++)
+ if (!poolAppendChar(&tempPool, *s))
+ return 0;
+ needSep = 1;
+ }
+
+ if (!poolAppendChar(&tempPool, XML_T('\0')))
+ return 0;
+ return tempPool.start;
+}
+
+static
+int setContext(XML_Parser parser, const XML_Char *context)
+{
+ const XML_Char *s = context;
+
+ while (*context != XML_T('\0')) {
+ if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
+ ENTITY *e;
+ if (!poolAppendChar(&tempPool, XML_T('\0')))
+ return 0;
+ e = (ENTITY *)lookup(&dtd.generalEntities, poolStart(&tempPool), 0);
+ if (e)
+ e->open = 1;
+ if (*s != XML_T('\0'))
+ s++;
+ context = s;
+ poolDiscard(&tempPool);
+ }
+ else if (*s == '=') {
+ PREFIX *prefix;
+ if (poolLength(&tempPool) == 0)
+ prefix = &dtd.defaultPrefix;
+ else {
+ if (!poolAppendChar(&tempPool, XML_T('\0')))
+ return 0;
+ prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&tempPool), sizeof(PREFIX));
+ if (!prefix)
+ return 0;
+ if (prefix->name == poolStart(&tempPool)) {
+ prefix->name = poolCopyString(&dtd.pool, prefix->name);
+ if (!prefix->name)
+ return 0;
+ }
+ poolDiscard(&tempPool);
+ }
+ for (context = s + 1; *context != CONTEXT_SEP && *context != XML_T('\0'); context++)
+ if (!poolAppendChar(&tempPool, *context))
+ return 0;
+ if (!poolAppendChar(&tempPool, XML_T('\0')))
+ return 0;
+ if (!addBinding(parser, prefix, 0, poolStart(&tempPool), &inheritedBindings))
+ return 0;
+ poolDiscard(&tempPool);
+ if (*context != XML_T('\0'))
+ ++context;
+ s = context;
+ }
+ else {
+ if (!poolAppendChar(&tempPool, *s))
+ return 0;
+ s++;
+ }
+ }
+ return 1;
+}
+
+
+static
+void normalizePublicId(XML_Char *publicId)
+{
+ XML_Char *p = publicId;
+ XML_Char *s;
+ for (s = publicId; *s; s++) {
+ switch (*s) {
+ case 0x20:
+ case 0xD:
+ case 0xA:
+ if (p != publicId && p[-1] != 0x20)
+ *p++ = 0x20;
+ break;
+ default:
+ *p++ = *s;
+ }
+ }
+ if (p != publicId && p[-1] == 0x20)
+ --p;
+ *p = XML_T('\0');
+}
+
+static int dtdInit(DTD *p, XML_Parser parser)
+{
+ XML_Memory_Handling_Suite *ms = &((Parser *) parser)->m_mem;
+ poolInit(&(p->pool), ms);
+ hashTableInit(&(p->generalEntities), ms);
+ hashTableInit(&(p->elementTypes), ms);
+ hashTableInit(&(p->attributeIds), ms);
+ hashTableInit(&(p->prefixes), ms);
+ p->complete = 1;
+ p->standalone = 0;
+#ifdef XML_DTD
+ hashTableInit(&(p->paramEntities), ms);
+#endif /* XML_DTD */
+ p->defaultPrefix.name = 0;
+ p->defaultPrefix.binding = 0;
+
+ p->in_eldecl = 0;
+ p->scaffIndex = 0;
+ p->scaffLevel = 0;
+ p->scaffold = 0;
+ p->contentStringLen = 0;
+ p->scaffSize = 0;
+ p->scaffCount = 0;
+
+ return 1;
+}
+
+#ifdef XML_DTD
+
+static void dtdSwap(DTD *p1, DTD *p2)
+{
+ DTD tem;
+ memcpy(&tem, p1, sizeof(DTD));
+ memcpy(p1, p2, sizeof(DTD));
+ memcpy(p2, &tem, sizeof(DTD));
+}
+
+#endif /* XML_DTD */
+
+static void dtdDestroy(DTD *p, XML_Parser parser)
+{
+ HASH_TABLE_ITER iter;
+ hashTableIterInit(&iter, &(p->elementTypes));
+ for (;;) {
+ ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
+ if (!e)
+ break;
+ if (e->allocDefaultAtts != 0)
+ FREE(e->defaultAtts);
+ }
+ hashTableDestroy(&(p->generalEntities));
+#ifdef XML_DTD
+ hashTableDestroy(&(p->paramEntities));
+#endif /* XML_DTD */
+ hashTableDestroy(&(p->elementTypes));
+ hashTableDestroy(&(p->attributeIds));
+ hashTableDestroy(&(p->prefixes));
+ poolDestroy(&(p->pool));
+ if (p->scaffIndex)
+ FREE(p->scaffIndex);
+ if (p->scaffold)
+ FREE(p->scaffold);
+}
+
+/* Do a deep copy of the DTD. Return 0 for out of memory; non-zero otherwise.
+The new DTD has already been initialized. */
+
+static int dtdCopy(DTD *newDtd, const DTD *oldDtd, XML_Parser parser)
+{
+ HASH_TABLE_ITER iter;
+
+ /* Copy the prefix table. */
+
+ hashTableIterInit(&iter, &(oldDtd->prefixes));
+ for (;;) {
+ const XML_Char *name;
+ const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
+ if (!oldP)
+ break;
+ name = poolCopyString(&(newDtd->pool), oldP->name);
+ if (!name)
+ return 0;
+ if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))
+ return 0;
+ }
+
+ hashTableIterInit(&iter, &(oldDtd->attributeIds));
+
+ /* Copy the attribute id table. */
+
+ for (;;) {
+ ATTRIBUTE_ID *newA;
+ const XML_Char *name;
+ const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
+
+ if (!oldA)
+ break;
+ /* Remember to allocate the scratch byte before the name. */
+ if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
+ return 0;
+ name = poolCopyString(&(newDtd->pool), oldA->name);
+ if (!name)
+ return 0;
+ ++name;
+ newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name, sizeof(ATTRIBUTE_ID));
+ if (!newA)
+ return 0;
+ newA->maybeTokenized = oldA->maybeTokenized;
+ if (oldA->prefix) {
+ newA->xmlns = oldA->xmlns;
+ if (oldA->prefix == &oldDtd->defaultPrefix)
+ newA->prefix = &newDtd->defaultPrefix;
+ else
+ newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes), oldA->prefix->name, 0);
+ }
+ }
+
+ /* Copy the element type table. */
+
+ hashTableIterInit(&iter, &(oldDtd->elementTypes));
+
+ for (;;) {
+ int i;
+ ELEMENT_TYPE *newE;
+ const XML_Char *name;
+ const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
+ if (!oldE)
+ break;
+ name = poolCopyString(&(newDtd->pool), oldE->name);
+ if (!name)
+ return 0;
+ newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name, sizeof(ELEMENT_TYPE));
+ if (!newE)
+ return 0;
+ if (oldE->nDefaultAtts) {
+ newE->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
+ if (!newE->defaultAtts)
+ return 0;
+ }
+ if (oldE->idAtt)
+ newE->idAtt = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0);
+ newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
+ if (oldE->prefix)
+ newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes), oldE->prefix->name, 0);
+ for (i = 0; i < newE->nDefaultAtts; i++) {
+ newE->defaultAtts[i].id = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
+ newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
+ if (oldE->defaultAtts[i].value) {
+ newE->defaultAtts[i].value = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
+ if (!newE->defaultAtts[i].value)
+ return 0;
+ }
+ else
+ newE->defaultAtts[i].value = 0;
+ }
+ }
+
+ /* Copy the entity tables. */
+ if (!copyEntityTable(&(newDtd->generalEntities),
+ &(newDtd->pool),
+ &(oldDtd->generalEntities), parser))
+ return 0;
+
+#ifdef XML_DTD
+ if (!copyEntityTable(&(newDtd->paramEntities),
+ &(newDtd->pool),
+ &(oldDtd->paramEntities), parser))
+ return 0;
+#endif /* XML_DTD */
+
+ newDtd->complete = oldDtd->complete;
+ newDtd->standalone = oldDtd->standalone;
+
+ /* Don't want deep copying for scaffolding */
+ newDtd->in_eldecl = oldDtd->in_eldecl;
+ newDtd->scaffold = oldDtd->scaffold;
+ newDtd->contentStringLen = oldDtd->contentStringLen;
+ newDtd->scaffSize = oldDtd->scaffSize;
+ newDtd->scaffLevel = oldDtd->scaffLevel;
+ newDtd->scaffIndex = oldDtd->scaffIndex;
+
+ return 1;
+} /* End dtdCopy */
+
+static int copyEntityTable(HASH_TABLE *newTable,
+ STRING_POOL *newPool,
+ const HASH_TABLE *oldTable,
+ XML_Parser parser)
+{
+ HASH_TABLE_ITER iter;
+ const XML_Char *cachedOldBase = 0;
+ const XML_Char *cachedNewBase = 0;
+ cmExpatUnused(parser);
+
+ hashTableIterInit(&iter, oldTable);
+
+ for (;;) {
+ ENTITY *newE;
+ const XML_Char *name;
+ const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
+ if (!oldE)
+ break;
+ name = poolCopyString(newPool, oldE->name);
+ if (!name)
+ return 0;
+ newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY));
+ if (!newE)
+ return 0;
+ if (oldE->systemId) {
+ const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
+ if (!tem)
+ return 0;
+ newE->systemId = tem;
+ if (oldE->base) {
+ if (oldE->base == cachedOldBase)
+ newE->base = cachedNewBase;
+ else {
+ cachedOldBase = oldE->base;
+ tem = poolCopyString(newPool, cachedOldBase);
+ if (!tem)
+ return 0;
+ cachedNewBase = newE->base = tem;
+ }
+ }
+ }
+ else {
+ const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr, oldE->textLen);
+ if (!tem)
+ return 0;
+ newE->textPtr = tem;
+ newE->textLen = oldE->textLen;
+ }
+ if (oldE->notation) {
+ const XML_Char *tem = poolCopyString(newPool, oldE->notation);
+ if (!tem)
+ return 0;
+ newE->notation = tem;
+ }
+ }
+ return 1;
+}
+
+#define INIT_SIZE 64
+
+static
+int keyeq(KEY s1, KEY s2)
+{
+ for (; *s1 == *s2; s1++, s2++)
+ if (*s1 == 0)
+ return 1;
+ return 0;
+}
+
+static
+unsigned long hash(KEY s)
+{
+ unsigned long h = 0;
+ while (*s)
+ h = (h << 5) + h + (unsigned char)*s++;
+ return h;
+}
+
+static
+NAMED *lookup(HASH_TABLE *table, KEY name, size_t createSize)
+{
+ size_t i;
+ if (table->size == 0) {
+ size_t tsize;
+
+ if (!createSize)
+ return 0;
+ tsize = INIT_SIZE * sizeof(NAMED *);
+ table->v = table->mem->malloc_fcn(tsize);
+ if (!table->v)
+ return 0;
+ memset(table->v, 0, tsize);
+ table->size = INIT_SIZE;
+ table->usedLim = INIT_SIZE / 2;
+ i = hash(name) & (table->size - 1);
+ }
+ else {
+ unsigned long h = hash(name);
+ for (i = h & (table->size - 1);
+ table->v[i];
+ i == 0 ? i = table->size - 1 : --i) {
+ if (keyeq(name, table->v[i]->name))
+ return table->v[i];
+ }
+ if (!createSize)
+ return 0;
+ if (table->used == table->usedLim) {
+ /* check for overflow */
+ size_t newSize = table->size * 2;
+ size_t tsize = newSize * sizeof(NAMED *);
+ NAMED **newV = table->mem->malloc_fcn(tsize);
+ if (!newV)
+ return 0;
+ memset(newV, 0, tsize);
+ for (i = 0; i < table->size; i++)
+ if (table->v[i]) {
+ size_t j;
+ for (j = hash(table->v[i]->name) & (newSize - 1);
+ newV[j];
+ j == 0 ? j = newSize - 1 : --j)
+ ;
+ newV[j] = table->v[i];
+ }
+ table->mem->free_fcn(table->v);
+ table->v = newV;
+ table->size = newSize;
+ table->usedLim = newSize/2;
+ for (i = h & (table->size - 1);
+ table->v[i];
+ i == 0 ? i = table->size - 1 : --i)
+ ;
+ }
+ }
+ table->v[i] = table->mem->malloc_fcn(createSize);
+ if (!table->v[i])
+ return 0;
+ memset(table->v[i], 0, createSize);
+ table->v[i]->name = name;
+ (table->used)++;
+ return table->v[i];
+}
+
+static
+void hashTableDestroy(HASH_TABLE *table)
+{
+ size_t i;
+ for (i = 0; i < table->size; i++) {
+ NAMED *p = table->v[i];
+ if (p)
+ table->mem->free_fcn(p);
+ }
+ if (table->v)
+ table->mem->free_fcn(table->v);
+}
+
+static
+void hashTableInit(HASH_TABLE *p, XML_Memory_Handling_Suite *ms)
+{
+ p->size = 0;
+ p->usedLim = 0;
+ p->used = 0;
+ p->v = 0;
+ p->mem = ms;
+}
+
+static
+void hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
+{
+ iter->p = table->v;
+ iter->end = iter->p + table->size;
+}
+
+static
+NAMED *hashTableIterNext(HASH_TABLE_ITER *iter)
+{
+ while (iter->p != iter->end) {
+ NAMED *tem = *(iter->p)++;
+ if (tem)
+ return tem;
+ }
+ return 0;
+}
+
+
+static
+void poolInit(STRING_POOL *pool, XML_Memory_Handling_Suite *ms)
+{
+ pool->blocks = 0;
+ pool->freeBlocks = 0;
+ pool->start = 0;
+ pool->ptr = 0;
+ pool->end = 0;
+ pool->mem = ms;
+}
+
+static
+void poolClear(STRING_POOL *pool)
+{
+ if (!pool->freeBlocks)
+ pool->freeBlocks = pool->blocks;
+ else {
+ BLOCK *p = pool->blocks;
+ while (p) {
+ BLOCK *tem = p->next;
+ p->next = pool->freeBlocks;
+ pool->freeBlocks = p;
+ p = tem;
+ }
+ }
+ pool->blocks = 0;
+ pool->start = 0;
+ pool->ptr = 0;
+ pool->end = 0;
+}
+
+static
+void poolDestroy(STRING_POOL *pool)
+{
+ BLOCK *p = pool->blocks;
+ while (p) {
+ BLOCK *tem = p->next;
+ pool->mem->free_fcn(p);
+ p = tem;
+ }
+ pool->blocks = 0;
+ p = pool->freeBlocks;
+ while (p) {
+ BLOCK *tem = p->next;
+ pool->mem->free_fcn(p);
+ p = tem;
+ }
+ pool->freeBlocks = 0;
+ pool->ptr = 0;
+ pool->start = 0;
+ pool->end = 0;
+}
+
+static
+XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
+ const char *ptr, const char *end)
+{
+ if (!pool->ptr && !poolGrow(pool))
+ return 0;
+ for (;;) {
+ XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
+ if (ptr == end)
+ break;
+ if (!poolGrow(pool))
+ return 0;
+ }
+ return pool->start;
+}
+
+static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s)
+{
+ do {
+ if (!poolAppendChar(pool, *s))
+ return 0;
+ } while (*s++);
+ s = pool->start;
+ poolFinish(pool);
+ return s;
+}
+
+static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
+{
+ if (!pool->ptr && !poolGrow(pool))
+ return 0;
+ for (; n > 0; --n, s++) {
+ if (!poolAppendChar(pool, *s))
+ return 0;
+
+ }
+ s = pool->start;
+ poolFinish(pool);
+ return s;
+}
+
+static
+const XML_Char *poolAppendString(STRING_POOL *pool, const XML_Char *s)
+{
+ while (*s) {
+ if (!poolAppendChar(pool, *s))
+ return 0;
+ s++;
+ }
+ return pool->start;
+} /* End poolAppendString */
+
+static
+XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
+ const char *ptr, const char *end)
+{
+ if (!poolAppend(pool, enc, ptr, end))
+ return 0;
+ if (pool->ptr == pool->end && !poolGrow(pool))
+ return 0;
+ *(pool->ptr)++ = 0;
+ return pool->start;
+}
+
+static
+int poolGrow(STRING_POOL *pool)
+{
+ if (pool->freeBlocks) {
+ if (pool->start == 0) {
+ pool->blocks = pool->freeBlocks;
+ pool->freeBlocks = pool->freeBlocks->next;
+ pool->blocks->next = 0;
+ pool->start = pool->blocks->s;
+ pool->end = pool->start + pool->blocks->size;
+ pool->ptr = pool->start;
+ return 1;
+ }
+ if (pool->end - pool->start < pool->freeBlocks->size) {
+ BLOCK *tem = pool->freeBlocks->next;
+ pool->freeBlocks->next = pool->blocks;
+ pool->blocks = pool->freeBlocks;
+ pool->freeBlocks = tem;
+ memcpy(pool->blocks->s, pool->start, (pool->end - pool->start) * sizeof(XML_Char));
+ pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
+ pool->start = pool->blocks->s;
+ pool->end = pool->start + pool->blocks->size;
+ return 1;
+ }
+ }
+ if (pool->blocks && pool->start == pool->blocks->s) {
+ int blockSize = (pool->end - pool->start)*2;
+ pool->blocks = pool->mem->realloc_fcn(pool->blocks, offsetof(BLOCK, s) + blockSize * sizeof(XML_Char));
+ if (!pool->blocks)
+ return 0;
+ pool->blocks->size = blockSize;
+ pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
+ pool->start = pool->blocks->s;
+ pool->end = pool->start + blockSize;
+ }
+ else {
+ BLOCK *tem;
+ int blockSize = pool->end - pool->start;
+ if (blockSize < INIT_BLOCK_SIZE)
+ blockSize = INIT_BLOCK_SIZE;
+ else
+ blockSize *= 2;
+ tem = pool->mem->malloc_fcn(offsetof(BLOCK, s) + blockSize * sizeof(XML_Char));
+ if (!tem)
+ return 0;
+ tem->size = blockSize;
+ tem->next = pool->blocks;
+ pool->blocks = tem;
+ if (pool->ptr != pool->start)
+ memcpy(tem->s, pool->start, (pool->ptr - pool->start) * sizeof(XML_Char));
+ pool->ptr = tem->s + (pool->ptr - pool->start);
+ pool->start = tem->s;
+ pool->end = tem->s + blockSize;
+ }
+ return 1;
+}
+
+static int
+nextScaffoldPart(XML_Parser parser)
+{
+ CONTENT_SCAFFOLD * me;
+ int next;
+
+ if (! dtd.scaffIndex) {
+ dtd.scaffIndex = MALLOC(groupSize * sizeof(int));
+ if (! dtd.scaffIndex)
+ return -1;
+ dtd.scaffIndex[0] = 0;
+ }
+
+ if (dtd.scaffCount >= dtd.scaffSize) {
+ if (dtd.scaffold) {
+ dtd.scaffSize *= 2;
+ dtd.scaffold = (CONTENT_SCAFFOLD *) REALLOC(dtd.scaffold,
+ dtd.scaffSize * sizeof(CONTENT_SCAFFOLD));
+ }
+ else {
+ dtd.scaffSize = 32;
+ dtd.scaffold = (CONTENT_SCAFFOLD *) MALLOC(dtd.scaffSize * sizeof(CONTENT_SCAFFOLD));
+ }
+ if (! dtd.scaffold)
+ return -1;
+ }
+ next = dtd.scaffCount++;
+ me = &dtd.scaffold[next];
+ if (dtd.scaffLevel) {
+ CONTENT_SCAFFOLD *parent = &dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]];
+ if (parent->lastchild) {
+ dtd.scaffold[parent->lastchild].nextsib = next;
+ }
+ if (! parent->childcnt)
+ parent->firstchild = next;
+ parent->lastchild = next;
+ parent->childcnt++;
+ }
+ me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
+ return next;
+} /* End nextScaffoldPart */
+
+static void
+build_node (XML_Parser parser,
+ int src_node,
+ XML_Content *dest,
+ XML_Content **contpos,
+ char **strpos)
+{
+ dest->type = dtd.scaffold[src_node].type;
+ dest->quant = dtd.scaffold[src_node].quant;
+ if (dest->type == XML_CTYPE_NAME) {
+ const char *src;
+ dest->name = *strpos;
+ src = dtd.scaffold[src_node].name;
+ for (;;) {
+ *(*strpos)++ = *src;
+ if (! *src)
+ break;
+ src++;
+ }
+ dest->numchildren = 0;
+ dest->children = 0;
+ }
+ else {
+ unsigned int i;
+ int cn;
+ dest->numchildren = dtd.scaffold[src_node].childcnt;
+ dest->children = *contpos;
+ *contpos += dest->numchildren;
+ for (i = 0, cn = dtd.scaffold[src_node].firstchild;
+ i < dest->numchildren;
+ i++, cn = dtd.scaffold[cn].nextsib) {
+ build_node(parser, cn, &(dest->children[i]), contpos, strpos);
+ }
+ dest->name = 0;
+ }
+} /* End build_node */
+
+static XML_Content *
+build_model (XML_Parser parser)
+{
+ XML_Content *ret;
+ XML_Content *cpos;
+ char * str;
+ int allocsize = dtd.scaffCount * sizeof(XML_Content) + dtd.contentStringLen;
+
+ ret = MALLOC(allocsize);
+ if (! ret)
+ return 0;
+
+ str = (char *) (&ret[dtd.scaffCount]);
+ cpos = &ret[1];
+
+ build_node(parser, 0, ret, &cpos, &str);
+ return ret;
+} /* End build_model */
+
+static ELEMENT_TYPE *
+getElementType(XML_Parser parser,
+ const ENCODING *enc,
+ const char *ptr,
+ const char *end)
+{
+ const XML_Char *name = poolStoreString(&dtd.pool, enc, ptr, end);
+ ELEMENT_TYPE *ret;
+
+ if (! name)
+ return 0;
+ ret = (ELEMENT_TYPE *) lookup(&dtd.elementTypes, name, sizeof(ELEMENT_TYPE));
+ if (! ret)
+ return 0;
+ if (ret->name != name)
+ poolDiscard(&dtd.pool);
+ else {
+ poolFinish(&dtd.pool);
+ if (!setElementTypePrefix(parser, ret))
+ return 0;
+ }
+ return ret;
+} /* End getElementType */
diff --git a/Utilities/cmexpat/xmlrole.c b/Utilities/cmexpat/xmlrole.c
new file mode 100644
index 000000000..289964ca5
--- /dev/null
+++ b/Utilities/cmexpat/xmlrole.c
@@ -0,0 +1,1401 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file COPYING for copying permission.
+*/
+
+static char RCSId[]
+ = "$Header$";
+const char* cm_expat_GetXMLRole_RCSId()
+{
+ /* Avoid warning about unused static without removing RCSId from original. */
+ return RCSId;
+}
+
+#include <cmexpat/expatConfig.h>
+
+#include "xmlrole.h"
+#include "ascii.h"
+
+/* Doesn't check:
+
+ that ,| are not mixed in a model group
+ content of literals
+
+*/
+
+static const char KW_ANY[] = { ASCII_A, ASCII_N, ASCII_Y, '\0' };
+static const char KW_ATTLIST[] = { ASCII_A, ASCII_T, ASCII_T, ASCII_L, ASCII_I, ASCII_S, ASCII_T, '\0' };
+static const char KW_CDATA[] = { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
+static const char KW_DOCTYPE[] = { ASCII_D, ASCII_O, ASCII_C, ASCII_T, ASCII_Y, ASCII_P, ASCII_E, '\0' };
+static const char KW_ELEMENT[] = { ASCII_E, ASCII_L, ASCII_E, ASCII_M, ASCII_E, ASCII_N, ASCII_T, '\0' };
+static const char KW_EMPTY[] = { ASCII_E, ASCII_M, ASCII_P, ASCII_T, ASCII_Y, '\0' };
+static const char KW_ENTITIES[] = { ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, '\0' };
+static const char KW_ENTITY[] = { ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' };
+static const char KW_FIXED[] = { ASCII_F, ASCII_I, ASCII_X, ASCII_E, ASCII_D, '\0' };
+static const char KW_ID[] = { ASCII_I, ASCII_D, '\0' };
+static const char KW_IDREF[] = { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' };
+static const char KW_IDREFS[] = { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' };
+static const char KW_IGNORE[] = { ASCII_I, ASCII_G, ASCII_N, ASCII_O, ASCII_R, ASCII_E, '\0' };
+static const char KW_IMPLIED[] = { ASCII_I, ASCII_M, ASCII_P, ASCII_L, ASCII_I, ASCII_E, ASCII_D, '\0' };
+static const char KW_INCLUDE[] = { ASCII_I, ASCII_N, ASCII_C, ASCII_L, ASCII_U, ASCII_D, ASCII_E, '\0' };
+static const char KW_NDATA[] = { ASCII_N, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
+static const char KW_NMTOKEN[] = { ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' };
+static const char KW_NMTOKENS[] = { ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '\0' };
+static const char KW_NOTATION[] = { ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, '\0' };
+static const char KW_PCDATA[] = { ASCII_P, ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
+static const char KW_PUBLIC[] = { ASCII_P, ASCII_U, ASCII_B, ASCII_L, ASCII_I, ASCII_C, '\0' };
+static const char KW_REQUIRED[] = { ASCII_R, ASCII_E, ASCII_Q, ASCII_U, ASCII_I, ASCII_R, ASCII_E, ASCII_D, '\0' };
+static const char KW_SYSTEM[] = { ASCII_S, ASCII_Y, ASCII_S, ASCII_T, ASCII_E, ASCII_M, '\0' };
+
+#ifndef MIN_BYTES_PER_CHAR
+#define MIN_BYTES_PER_CHAR(enc) ((enc)->minBytesPerChar)
+#endif
+
+#ifdef XML_DTD
+#define setTopLevel(state) \
+ ((state)->handler = ((state)->documentEntity \
+ ? internalSubset \
+ : externalSubset1))
+#else /* not XML_DTD */
+#define setTopLevel(state) ((state)->handler = internalSubset)
+#endif /* not XML_DTD */
+
+typedef int PROLOG_HANDLER(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc);
+
+static PROLOG_HANDLER
+ prolog0, prolog1, prolog2,
+ doctype0, doctype1, doctype2, doctype3, doctype4, doctype5,
+ internalSubset,
+ entity0, entity1, entity2, entity3, entity4, entity5, entity6,
+ entity7, entity8, entity9,
+ notation0, notation1, notation2, notation3, notation4,
+ attlist0, attlist1, attlist2, attlist3, attlist4, attlist5, attlist6,
+ attlist7, attlist8, attlist9,
+ element0, element1, element2, element3, element4, element5, element6,
+ element7,
+#ifdef XML_DTD
+ externalSubset0, externalSubset1,
+ condSect0, condSect1, condSect2,
+#endif /* XML_DTD */
+ declClose,
+ error;
+
+static
+int common(PROLOG_STATE *state, int tok);
+
+static
+int prolog0(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ state->handler = prolog1;
+ return XML_ROLE_NONE;
+ case XML_TOK_XML_DECL:
+ state->handler = prolog1;
+ return XML_ROLE_XML_DECL;
+ case XML_TOK_PI:
+ state->handler = prolog1;
+ return XML_ROLE_NONE;
+ case XML_TOK_COMMENT:
+ state->handler = prolog1;
+ case XML_TOK_BOM:
+ return XML_ROLE_NONE;
+ case XML_TOK_DECL_OPEN:
+ if (!XmlNameMatchesAscii(enc,
+ ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+ end,
+ KW_DOCTYPE))
+ break;
+ state->handler = doctype0;
+ return XML_ROLE_NONE;
+ case XML_TOK_INSTANCE_START:
+ state->handler = error;
+ return XML_ROLE_INSTANCE_START;
+ }
+ return common(state, tok);
+}
+
+static
+int prolog1(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_PI:
+ case XML_TOK_COMMENT:
+ case XML_TOK_BOM:
+ return XML_ROLE_NONE;
+ case XML_TOK_DECL_OPEN:
+ if (!XmlNameMatchesAscii(enc,
+ ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+ end,
+ KW_DOCTYPE))
+ break;
+ state->handler = doctype0;
+ return XML_ROLE_NONE;
+ case XML_TOK_INSTANCE_START:
+ state->handler = error;
+ return XML_ROLE_INSTANCE_START;
+ }
+ return common(state, tok);
+}
+
+static
+int prolog2(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ cmExpatUnused(ptr);
+ cmExpatUnused(end);
+ cmExpatUnused(enc);
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_PI:
+ case XML_TOK_COMMENT:
+ return XML_ROLE_NONE;
+ case XML_TOK_INSTANCE_START:
+ state->handler = error;
+ return XML_ROLE_INSTANCE_START;
+ }
+ return common(state, tok);
+}
+
+static
+int doctype0(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ cmExpatUnused(ptr);
+ cmExpatUnused(end);
+ cmExpatUnused(enc);
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_NAME:
+ case XML_TOK_PREFIXED_NAME:
+ state->handler = doctype1;
+ return XML_ROLE_DOCTYPE_NAME;
+ }
+ return common(state, tok);
+}
+
+static
+int doctype1(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_OPEN_BRACKET:
+ state->handler = internalSubset;
+ return XML_ROLE_DOCTYPE_INTERNAL_SUBSET;
+ case XML_TOK_DECL_CLOSE:
+ state->handler = prolog2;
+ return XML_ROLE_DOCTYPE_CLOSE;
+ case XML_TOK_NAME:
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
+ state->handler = doctype3;
+ return XML_ROLE_NONE;
+ }
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
+ state->handler = doctype2;
+ return XML_ROLE_NONE;
+ }
+ break;
+ }
+ return common(state, tok);
+}
+
+static
+int doctype2(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ cmExpatUnused(ptr);
+ cmExpatUnused(end);
+ cmExpatUnused(enc);
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_LITERAL:
+ state->handler = doctype3;
+ return XML_ROLE_DOCTYPE_PUBLIC_ID;
+ }
+ return common(state, tok);
+}
+
+static
+int doctype3(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ cmExpatUnused(ptr);
+ cmExpatUnused(end);
+ cmExpatUnused(enc);
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_LITERAL:
+ state->handler = doctype4;
+ return XML_ROLE_DOCTYPE_SYSTEM_ID;
+ }
+ return common(state, tok);
+}
+
+static
+int doctype4(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ cmExpatUnused(ptr);
+ cmExpatUnused(end);
+ cmExpatUnused(enc);
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_OPEN_BRACKET:
+ state->handler = internalSubset;
+ return XML_ROLE_DOCTYPE_INTERNAL_SUBSET;
+ case XML_TOK_DECL_CLOSE:
+ state->handler = prolog2;
+ return XML_ROLE_DOCTYPE_CLOSE;
+ }
+ return common(state, tok);
+}
+
+static
+int doctype5(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ cmExpatUnused(ptr);
+ cmExpatUnused(end);
+ cmExpatUnused(enc);
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_DECL_CLOSE:
+ state->handler = prolog2;
+ return XML_ROLE_DOCTYPE_CLOSE;
+ }
+ return common(state, tok);
+}
+
+static
+int internalSubset(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_DECL_OPEN:
+ if (XmlNameMatchesAscii(enc,
+ ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+ end,
+ KW_ENTITY)) {
+ state->handler = entity0;
+ return XML_ROLE_NONE;
+ }
+ if (XmlNameMatchesAscii(enc,
+ ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+ end,
+ KW_ATTLIST)) {
+ state->handler = attlist0;
+ return XML_ROLE_NONE;
+ }
+ if (XmlNameMatchesAscii(enc,
+ ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+ end,
+ KW_ELEMENT)) {
+ state->handler = element0;
+ return XML_ROLE_NONE;
+ }
+ if (XmlNameMatchesAscii(enc,
+ ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+ end,
+ KW_NOTATION)) {
+ state->handler = notation0;
+ return XML_ROLE_NONE;
+ }
+ break;
+ case XML_TOK_PI:
+ case XML_TOK_COMMENT:
+ return XML_ROLE_NONE;
+ case XML_TOK_PARAM_ENTITY_REF:
+ return XML_ROLE_PARAM_ENTITY_REF;
+ case XML_TOK_CLOSE_BRACKET:
+ state->handler = doctype5;
+ return XML_ROLE_NONE;
+ }
+ return common(state, tok);
+}
+
+#ifdef XML_DTD
+
+static
+int externalSubset0(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ state->handler = externalSubset1;
+ if (tok == XML_TOK_XML_DECL)
+ return XML_ROLE_TEXT_DECL;
+ return externalSubset1(state, tok, ptr, end, enc);
+}
+
+static
+int externalSubset1(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_COND_SECT_OPEN:
+ state->handler = condSect0;
+ return XML_ROLE_NONE;
+ case XML_TOK_COND_SECT_CLOSE:
+ if (state->includeLevel == 0)
+ break;
+ state->includeLevel -= 1;
+ return XML_ROLE_NONE;
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_CLOSE_BRACKET:
+ break;
+ case XML_TOK_NONE:
+ if (state->includeLevel)
+ break;
+ return XML_ROLE_NONE;
+ default:
+ return internalSubset(state, tok, ptr, end, enc);
+ }
+ return common(state, tok);
+}
+
+#endif /* XML_DTD */
+
+static
+int entity0(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ cmExpatUnused(ptr);
+ cmExpatUnused(end);
+ cmExpatUnused(enc);
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_PERCENT:
+ state->handler = entity1;
+ return XML_ROLE_NONE;
+ case XML_TOK_NAME:
+ state->handler = entity2;
+ return XML_ROLE_GENERAL_ENTITY_NAME;
+ }
+ return common(state, tok);
+}
+
+static
+int entity1(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ cmExpatUnused(ptr);
+ cmExpatUnused(end);
+ cmExpatUnused(enc);
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_NAME:
+ state->handler = entity7;
+ return XML_ROLE_PARAM_ENTITY_NAME;
+ }
+ return common(state, tok);
+}
+
+static
+int entity2(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_NAME:
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
+ state->handler = entity4;
+ return XML_ROLE_NONE;
+ }
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
+ state->handler = entity3;
+ return XML_ROLE_NONE;
+ }
+ break;
+ case XML_TOK_LITERAL:
+ state->handler = declClose;
+ return XML_ROLE_ENTITY_VALUE;
+ }
+ return common(state, tok);
+}
+
+static
+int entity3(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ cmExpatUnused(ptr);
+ cmExpatUnused(end);
+ cmExpatUnused(enc);
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_LITERAL:
+ state->handler = entity4;
+ return XML_ROLE_ENTITY_PUBLIC_ID;
+ }
+ return common(state, tok);
+}
+
+
+static
+int entity4(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ cmExpatUnused(ptr);
+ cmExpatUnused(end);
+ cmExpatUnused(enc);
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_LITERAL:
+ state->handler = entity5;
+ return XML_ROLE_ENTITY_SYSTEM_ID;
+ }
+ return common(state, tok);
+}
+
+static
+int entity5(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_DECL_CLOSE:
+ setTopLevel(state);
+ return XML_ROLE_ENTITY_COMPLETE;
+ case XML_TOK_NAME:
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_NDATA)) {
+ state->handler = entity6;
+ return XML_ROLE_NONE;
+ }
+ break;
+ }
+ return common(state, tok);
+}
+
+static
+int entity6(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ cmExpatUnused(ptr);
+ cmExpatUnused(end);
+ cmExpatUnused(enc);
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_NAME:
+ state->handler = declClose;
+ return XML_ROLE_ENTITY_NOTATION_NAME;
+ }
+ return common(state, tok);
+}
+
+static
+int entity7(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_NAME:
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
+ state->handler = entity9;
+ return XML_ROLE_NONE;
+ }
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
+ state->handler = entity8;
+ return XML_ROLE_NONE;
+ }
+ break;
+ case XML_TOK_LITERAL:
+ state->handler = declClose;
+ return XML_ROLE_ENTITY_VALUE;
+ }
+ return common(state, tok);
+}
+
+static
+int entity8(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ cmExpatUnused(ptr);
+ cmExpatUnused(end);
+ cmExpatUnused(enc);
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_LITERAL:
+ state->handler = entity9;
+ return XML_ROLE_ENTITY_PUBLIC_ID;
+ }
+ return common(state, tok);
+}
+
+static
+int entity9(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ cmExpatUnused(ptr);
+ cmExpatUnused(end);
+ cmExpatUnused(enc);
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_LITERAL:
+ state->handler = declClose;
+ return XML_ROLE_ENTITY_SYSTEM_ID;
+ }
+ return common(state, tok);
+}
+
+static
+int notation0(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ cmExpatUnused(ptr);
+ cmExpatUnused(end);
+ cmExpatUnused(enc);
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_NAME:
+ state->handler = notation1;
+ return XML_ROLE_NOTATION_NAME;
+ }
+ return common(state, tok);
+}
+
+static
+int notation1(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_NAME:
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
+ state->handler = notation3;
+ return XML_ROLE_NONE;
+ }
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
+ state->handler = notation2;
+ return XML_ROLE_NONE;
+ }
+ break;
+ }
+ return common(state, tok);
+}
+
+static
+int notation2(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ cmExpatUnused(ptr);
+ cmExpatUnused(end);
+ cmExpatUnused(enc);
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_LITERAL:
+ state->handler = notation4;
+ return XML_ROLE_NOTATION_PUBLIC_ID;
+ }
+ return common(state, tok);
+}
+
+static
+int notation3(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ cmExpatUnused(ptr);
+ cmExpatUnused(end);
+ cmExpatUnused(enc);
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_LITERAL:
+ state->handler = declClose;
+ return XML_ROLE_NOTATION_SYSTEM_ID;
+ }
+ return common(state, tok);
+}
+
+static
+int notation4(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ cmExpatUnused(ptr);
+ cmExpatUnused(end);
+ cmExpatUnused(enc);
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_LITERAL:
+ state->handler = declClose;
+ return XML_ROLE_NOTATION_SYSTEM_ID;
+ case XML_TOK_DECL_CLOSE:
+ setTopLevel(state);
+ return XML_ROLE_NOTATION_NO_SYSTEM_ID;
+ }
+ return common(state, tok);
+}
+
+static
+int attlist0(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ cmExpatUnused(ptr);
+ cmExpatUnused(end);
+ cmExpatUnused(enc);
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_NAME:
+ case XML_TOK_PREFIXED_NAME:
+ state->handler = attlist1;
+ return XML_ROLE_ATTLIST_ELEMENT_NAME;
+ }
+ return common(state, tok);
+}
+
+static
+int attlist1(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ cmExpatUnused(ptr);
+ cmExpatUnused(end);
+ cmExpatUnused(enc);
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_DECL_CLOSE:
+ setTopLevel(state);
+ return XML_ROLE_NONE;
+ case XML_TOK_NAME:
+ case XML_TOK_PREFIXED_NAME:
+ state->handler = attlist2;
+ return XML_ROLE_ATTRIBUTE_NAME;
+ }
+ return common(state, tok);
+}
+
+static
+int attlist2(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ cmExpatUnused(ptr);
+ cmExpatUnused(end);
+ cmExpatUnused(enc);
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_NAME:
+ {
+ static const char *types[] = {
+ KW_CDATA,
+ KW_ID,
+ KW_IDREF,
+ KW_IDREFS,
+ KW_ENTITY,
+ KW_ENTITIES,
+ KW_NMTOKEN,
+ KW_NMTOKENS,
+ };
+ int i;
+ for (i = 0; i < (int)(sizeof(types)/sizeof(types[0])); i++)
+ if (XmlNameMatchesAscii(enc, ptr, end, types[i])) {
+ state->handler = attlist8;
+ return XML_ROLE_ATTRIBUTE_TYPE_CDATA + i;
+ }
+ }
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_NOTATION)) {
+ state->handler = attlist5;
+ return XML_ROLE_NONE;
+ }
+ break;
+ case XML_TOK_OPEN_PAREN:
+ state->handler = attlist3;
+ return XML_ROLE_NONE;
+ }
+ return common(state, tok);
+}
+
+static
+int attlist3(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ cmExpatUnused(ptr);
+ cmExpatUnused(end);
+ cmExpatUnused(enc);
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_NMTOKEN:
+ case XML_TOK_NAME:
+ case XML_TOK_PREFIXED_NAME:
+ state->handler = attlist4;
+ return XML_ROLE_ATTRIBUTE_ENUM_VALUE;
+ }
+ return common(state, tok);
+}
+
+static
+int attlist4(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ cmExpatUnused(ptr);
+ cmExpatUnused(end);
+ cmExpatUnused(enc);
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_CLOSE_PAREN:
+ state->handler = attlist8;
+ return XML_ROLE_NONE;
+ case XML_TOK_OR:
+ state->handler = attlist3;
+ return XML_ROLE_NONE;
+ }
+ return common(state, tok);
+}
+
+static
+int attlist5(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ cmExpatUnused(ptr);
+ cmExpatUnused(end);
+ cmExpatUnused(enc);
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_OPEN_PAREN:
+ state->handler = attlist6;
+ return XML_ROLE_NONE;
+ }
+ return common(state, tok);
+}
+
+
+static
+int attlist6(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ cmExpatUnused(ptr);
+ cmExpatUnused(end);
+ cmExpatUnused(enc);
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_NAME:
+ state->handler = attlist7;
+ return XML_ROLE_ATTRIBUTE_NOTATION_VALUE;
+ }
+ return common(state, tok);
+}
+
+static
+int attlist7(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ cmExpatUnused(ptr);
+ cmExpatUnused(end);
+ cmExpatUnused(enc);
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_CLOSE_PAREN:
+ state->handler = attlist8;
+ return XML_ROLE_NONE;
+ case XML_TOK_OR:
+ state->handler = attlist6;
+ return XML_ROLE_NONE;
+ }
+ return common(state, tok);
+}
+
+/* default value */
+static
+int attlist8(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ cmExpatUnused(ptr);
+ cmExpatUnused(end);
+ cmExpatUnused(enc);
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_POUND_NAME:
+ if (XmlNameMatchesAscii(enc,
+ ptr + MIN_BYTES_PER_CHAR(enc),
+ end,
+ KW_IMPLIED)) {
+ state->handler = attlist1;
+ return XML_ROLE_IMPLIED_ATTRIBUTE_VALUE;
+ }
+ if (XmlNameMatchesAscii(enc,
+ ptr + MIN_BYTES_PER_CHAR(enc),
+ end,
+ KW_REQUIRED)) {
+ state->handler = attlist1;
+ return XML_ROLE_REQUIRED_ATTRIBUTE_VALUE;
+ }
+ if (XmlNameMatchesAscii(enc,
+ ptr + MIN_BYTES_PER_CHAR(enc),
+ end,
+ KW_FIXED)) {
+ state->handler = attlist9;
+ return XML_ROLE_NONE;
+ }
+ break;
+ case XML_TOK_LITERAL:
+ state->handler = attlist1;
+ return XML_ROLE_DEFAULT_ATTRIBUTE_VALUE;
+ }
+ return common(state, tok);
+}
+
+static
+int attlist9(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ cmExpatUnused(ptr);
+ cmExpatUnused(end);
+ cmExpatUnused(enc);
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_LITERAL:
+ state->handler = attlist1;
+ return XML_ROLE_FIXED_ATTRIBUTE_VALUE;
+ }
+ return common(state, tok);
+}
+
+static
+int element0(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ cmExpatUnused(ptr);
+ cmExpatUnused(end);
+ cmExpatUnused(enc);
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_NAME:
+ case XML_TOK_PREFIXED_NAME:
+ state->handler = element1;
+ return XML_ROLE_ELEMENT_NAME;
+ }
+ return common(state, tok);
+}
+
+static
+int element1(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ cmExpatUnused(ptr);
+ cmExpatUnused(end);
+ cmExpatUnused(enc);
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_NAME:
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_EMPTY)) {
+ state->handler = declClose;
+ return XML_ROLE_CONTENT_EMPTY;
+ }
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_ANY)) {
+ state->handler = declClose;
+ return XML_ROLE_CONTENT_ANY;
+ }
+ break;
+ case XML_TOK_OPEN_PAREN:
+ state->handler = element2;
+ state->level = 1;
+ return XML_ROLE_GROUP_OPEN;
+ }
+ return common(state, tok);
+}
+
+static
+int element2(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ cmExpatUnused(ptr);
+ cmExpatUnused(end);
+ cmExpatUnused(enc);
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_POUND_NAME:
+ if (XmlNameMatchesAscii(enc,
+ ptr + MIN_BYTES_PER_CHAR(enc),
+ end,
+ KW_PCDATA)) {
+ state->handler = element3;
+ return XML_ROLE_CONTENT_PCDATA;
+ }
+ break;
+ case XML_TOK_OPEN_PAREN:
+ state->level = 2;
+ state->handler = element6;
+ return XML_ROLE_GROUP_OPEN;
+ case XML_TOK_NAME:
+ case XML_TOK_PREFIXED_NAME:
+ state->handler = element7;
+ return XML_ROLE_CONTENT_ELEMENT;
+ case XML_TOK_NAME_QUESTION:
+ state->handler = element7;
+ return XML_ROLE_CONTENT_ELEMENT_OPT;
+ case XML_TOK_NAME_ASTERISK:
+ state->handler = element7;
+ return XML_ROLE_CONTENT_ELEMENT_REP;
+ case XML_TOK_NAME_PLUS:
+ state->handler = element7;
+ return XML_ROLE_CONTENT_ELEMENT_PLUS;
+ }
+ return common(state, tok);
+}
+
+static
+int element3(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ cmExpatUnused(ptr);
+ cmExpatUnused(end);
+ cmExpatUnused(enc);
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_CLOSE_PAREN:
+ state->handler = declClose;
+ return XML_ROLE_GROUP_CLOSE;
+ case XML_TOK_CLOSE_PAREN_ASTERISK:
+ state->handler = declClose;
+ return XML_ROLE_GROUP_CLOSE_REP;
+ case XML_TOK_OR:
+ state->handler = element4;
+ return XML_ROLE_NONE;
+ }
+ return common(state, tok);
+}
+
+static
+int element4(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ cmExpatUnused(ptr);
+ cmExpatUnused(end);
+ cmExpatUnused(enc);
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_NAME:
+ case XML_TOK_PREFIXED_NAME:
+ state->handler = element5;
+ return XML_ROLE_CONTENT_ELEMENT;
+ }
+ return common(state, tok);
+}
+
+static
+int element5(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ cmExpatUnused(ptr);
+ cmExpatUnused(end);
+ cmExpatUnused(enc);
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_CLOSE_PAREN_ASTERISK:
+ state->handler = declClose;
+ return XML_ROLE_GROUP_CLOSE_REP;
+ case XML_TOK_OR:
+ state->handler = element4;
+ return XML_ROLE_NONE;
+ }
+ return common(state, tok);
+}
+
+static
+int element6(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ cmExpatUnused(ptr);
+ cmExpatUnused(end);
+ cmExpatUnused(enc);
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_OPEN_PAREN:
+ state->level += 1;
+ return XML_ROLE_GROUP_OPEN;
+ case XML_TOK_NAME:
+ case XML_TOK_PREFIXED_NAME:
+ state->handler = element7;
+ return XML_ROLE_CONTENT_ELEMENT;
+ case XML_TOK_NAME_QUESTION:
+ state->handler = element7;
+ return XML_ROLE_CONTENT_ELEMENT_OPT;
+ case XML_TOK_NAME_ASTERISK:
+ state->handler = element7;
+ return XML_ROLE_CONTENT_ELEMENT_REP;
+ case XML_TOK_NAME_PLUS:
+ state->handler = element7;
+ return XML_ROLE_CONTENT_ELEMENT_PLUS;
+ }
+ return common(state, tok);
+}
+
+static
+int element7(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ cmExpatUnused(ptr);
+ cmExpatUnused(end);
+ cmExpatUnused(enc);
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_CLOSE_PAREN:
+ state->level -= 1;
+ if (state->level == 0)
+ state->handler = declClose;
+ return XML_ROLE_GROUP_CLOSE;
+ case XML_TOK_CLOSE_PAREN_ASTERISK:
+ state->level -= 1;
+ if (state->level == 0)
+ state->handler = declClose;
+ return XML_ROLE_GROUP_CLOSE_REP;
+ case XML_TOK_CLOSE_PAREN_QUESTION:
+ state->level -= 1;
+ if (state->level == 0)
+ state->handler = declClose;
+ return XML_ROLE_GROUP_CLOSE_OPT;
+ case XML_TOK_CLOSE_PAREN_PLUS:
+ state->level -= 1;
+ if (state->level == 0)
+ state->handler = declClose;
+ return XML_ROLE_GROUP_CLOSE_PLUS;
+ case XML_TOK_COMMA:
+ state->handler = element6;
+ return XML_ROLE_GROUP_SEQUENCE;
+ case XML_TOK_OR:
+ state->handler = element6;
+ return XML_ROLE_GROUP_CHOICE;
+ }
+ return common(state, tok);
+}
+
+#ifdef XML_DTD
+
+static
+int condSect0(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ cmExpatUnused(ptr);
+ cmExpatUnused(end);
+ cmExpatUnused(enc);
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_NAME:
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_INCLUDE)) {
+ state->handler = condSect1;
+ return XML_ROLE_NONE;
+ }
+ if (XmlNameMatchesAscii(enc, ptr, end, KW_IGNORE)) {
+ state->handler = condSect2;
+ return XML_ROLE_NONE;
+ }
+ break;
+ }
+ return common(state, tok);
+}
+
+static
+int condSect1(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ cmExpatUnused(ptr);
+ cmExpatUnused(end);
+ cmExpatUnused(enc);
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_OPEN_BRACKET:
+ state->handler = externalSubset1;
+ state->includeLevel += 1;
+ return XML_ROLE_NONE;
+ }
+ return common(state, tok);
+}
+
+static
+int condSect2(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ cmExpatUnused(ptr);
+ cmExpatUnused(end);
+ cmExpatUnused(enc);
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_OPEN_BRACKET:
+ state->handler = externalSubset1;
+ return XML_ROLE_IGNORE_SECT;
+ }
+ return common(state, tok);
+}
+
+#endif /* XML_DTD */
+
+static
+int declClose(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ cmExpatUnused(ptr);
+ cmExpatUnused(end);
+ cmExpatUnused(enc);
+ switch (tok) {
+ case XML_TOK_PROLOG_S:
+ return XML_ROLE_NONE;
+ case XML_TOK_DECL_CLOSE:
+ setTopLevel(state);
+ return XML_ROLE_NONE;
+ }
+ return common(state, tok);
+}
+
+#if 0
+
+static
+int ignore(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ cmExpatUnused(ptr);
+ cmExpatUnused(end);
+ cmExpatUnused(enc);
+ switch (tok) {
+ case XML_TOK_DECL_CLOSE:
+ state->handler = internalSubset;
+ return 0;
+ default:
+ return XML_ROLE_NONE;
+ }
+ return common(state, tok);
+}
+#endif
+
+static
+int error(PROLOG_STATE *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc)
+{
+ cmExpatUnused(state);
+ cmExpatUnused(tok);
+ cmExpatUnused(ptr);
+ cmExpatUnused(end);
+ cmExpatUnused(enc);
+ return XML_ROLE_NONE;
+}
+
+static
+int common(PROLOG_STATE *state, int tok)
+{
+#ifdef XML_DTD
+ if (!state->documentEntity && tok == XML_TOK_PARAM_ENTITY_REF)
+ return XML_ROLE_INNER_PARAM_ENTITY_REF;
+#endif
+ state->handler = error;
+ return XML_ROLE_ERROR;
+}
+
+void XmlPrologStateInit(PROLOG_STATE *state)
+{
+ state->handler = prolog0;
+#ifdef XML_DTD
+ state->documentEntity = 1;
+ state->includeLevel = 0;
+#endif /* XML_DTD */
+}
+
+#ifdef XML_DTD
+
+void XmlPrologStateInitExternalEntity(PROLOG_STATE *state)
+{
+ state->handler = externalSubset0;
+ state->documentEntity = 0;
+ state->includeLevel = 0;
+}
+
+#endif /* XML_DTD */
diff --git a/Utilities/cmexpat/xmlrole.h b/Utilities/cmexpat/xmlrole.h
new file mode 100644
index 000000000..6f2579306
--- /dev/null
+++ b/Utilities/cmexpat/xmlrole.h
@@ -0,0 +1,100 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file COPYING for copying permission.
+*/
+
+#ifndef XmlRole_INCLUDED
+#define XmlRole_INCLUDED 1
+
+#include "xmltok.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum {
+ XML_ROLE_ERROR = -1,
+ XML_ROLE_NONE = 0,
+ XML_ROLE_XML_DECL,
+ XML_ROLE_INSTANCE_START,
+ XML_ROLE_DOCTYPE_NAME,
+ XML_ROLE_DOCTYPE_SYSTEM_ID,
+ XML_ROLE_DOCTYPE_PUBLIC_ID,
+ XML_ROLE_DOCTYPE_INTERNAL_SUBSET,
+ XML_ROLE_DOCTYPE_CLOSE,
+ XML_ROLE_GENERAL_ENTITY_NAME,
+ XML_ROLE_PARAM_ENTITY_NAME,
+ XML_ROLE_ENTITY_VALUE,
+ XML_ROLE_ENTITY_SYSTEM_ID,
+ XML_ROLE_ENTITY_PUBLIC_ID,
+ XML_ROLE_ENTITY_COMPLETE,
+ XML_ROLE_ENTITY_NOTATION_NAME,
+ XML_ROLE_NOTATION_NAME,
+ XML_ROLE_NOTATION_SYSTEM_ID,
+ XML_ROLE_NOTATION_NO_SYSTEM_ID,
+ XML_ROLE_NOTATION_PUBLIC_ID,
+ XML_ROLE_ATTRIBUTE_NAME,
+ XML_ROLE_ATTRIBUTE_TYPE_CDATA,
+ XML_ROLE_ATTRIBUTE_TYPE_ID,
+ XML_ROLE_ATTRIBUTE_TYPE_IDREF,
+ XML_ROLE_ATTRIBUTE_TYPE_IDREFS,
+ XML_ROLE_ATTRIBUTE_TYPE_ENTITY,
+ XML_ROLE_ATTRIBUTE_TYPE_ENTITIES,
+ XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN,
+ XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS,
+ XML_ROLE_ATTRIBUTE_ENUM_VALUE,
+ XML_ROLE_ATTRIBUTE_NOTATION_VALUE,
+ XML_ROLE_ATTLIST_ELEMENT_NAME,
+ XML_ROLE_IMPLIED_ATTRIBUTE_VALUE,
+ XML_ROLE_REQUIRED_ATTRIBUTE_VALUE,
+ XML_ROLE_DEFAULT_ATTRIBUTE_VALUE,
+ XML_ROLE_FIXED_ATTRIBUTE_VALUE,
+ XML_ROLE_ELEMENT_NAME,
+ XML_ROLE_CONTENT_ANY,
+ XML_ROLE_CONTENT_EMPTY,
+ XML_ROLE_CONTENT_PCDATA,
+ XML_ROLE_GROUP_OPEN,
+ XML_ROLE_GROUP_CLOSE,
+ XML_ROLE_GROUP_CLOSE_REP,
+ XML_ROLE_GROUP_CLOSE_OPT,
+ XML_ROLE_GROUP_CLOSE_PLUS,
+ XML_ROLE_GROUP_CHOICE,
+ XML_ROLE_GROUP_SEQUENCE,
+ XML_ROLE_CONTENT_ELEMENT,
+ XML_ROLE_CONTENT_ELEMENT_REP,
+ XML_ROLE_CONTENT_ELEMENT_OPT,
+ XML_ROLE_CONTENT_ELEMENT_PLUS,
+#ifdef XML_DTD
+ XML_ROLE_TEXT_DECL,
+ XML_ROLE_IGNORE_SECT,
+ XML_ROLE_INNER_PARAM_ENTITY_REF,
+#endif /* XML_DTD */
+ XML_ROLE_PARAM_ENTITY_REF
+};
+
+typedef struct prolog_state {
+ int (*handler)(struct prolog_state *state,
+ int tok,
+ const char *ptr,
+ const char *end,
+ const ENCODING *enc);
+ unsigned level;
+#ifdef XML_DTD
+ unsigned includeLevel;
+ int documentEntity;
+#endif /* XML_DTD */
+} PROLOG_STATE;
+
+void XmlPrologStateInit(PROLOG_STATE *);
+#ifdef XML_DTD
+void XmlPrologStateInitExternalEntity(PROLOG_STATE *);
+#endif /* XML_DTD */
+
+#define XmlTokenRole(state, tok, ptr, end, enc) \
+ (((state)->handler)(state, tok, ptr, end, enc))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* not XmlRole_INCLUDED */
diff --git a/Utilities/cmexpat/xmltok.c b/Utilities/cmexpat/xmltok.c
new file mode 100644
index 000000000..8ee9c7519
--- /dev/null
+++ b/Utilities/cmexpat/xmltok.c
@@ -0,0 +1,1584 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file COPYING for copying permission.
+*/
+
+#include <cmexpat/expatConfig.h>
+
+#include "xmltok.h"
+#include "nametab.h"
+
+#if defined(__BORLANDC__)
+#pragma warn -8008 // Disable "condition is always true" warning.
+#pragma warn -8066 // Disable "unreachable code" warning.
+#endif
+
+#ifdef XML_DTD
+#define IGNORE_SECTION_TOK_VTABLE , PREFIX(ignoreSectionTok)
+#else
+#define IGNORE_SECTION_TOK_VTABLE /* as nothing */
+#endif
+
+#define VTABLE1 \
+ { PREFIX(prologTok), PREFIX(contentTok), \
+ PREFIX(cdataSectionTok) IGNORE_SECTION_TOK_VTABLE }, \
+ { PREFIX(attributeValueTok), PREFIX(entityValueTok) }, \
+ PREFIX(sameName), \
+ PREFIX(nameMatchesAscii), \
+ PREFIX(nameLength), \
+ PREFIX(skipS), \
+ PREFIX(getAtts), \
+ PREFIX(charRefNumber), \
+ PREFIX(predefinedEntityName), \
+ PREFIX(updatePosition), \
+ PREFIX(isPublicId)
+
+#define VTABLE VTABLE1, PREFIX(toUtf8), PREFIX(toUtf16)
+
+#define UCS2_GET_NAMING(pages, hi, lo) \
+ (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1 << ((lo) & 0x1F)))
+
+/* A 2 byte UTF-8 representation splits the characters 11 bits
+between the bottom 5 and 6 bits of the bytes.
+We need 8 bits to index into pages, 3 bits to add to that index and
+5 bits to generate the mask. */
+#define UTF8_GET_NAMING2(pages, byte) \
+ (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3) \
+ + ((((byte)[0]) & 3) << 1) \
+ + ((((byte)[1]) >> 5) & 1)] \
+ & (1 << (((byte)[1]) & 0x1F)))
+
+/* A 3 byte UTF-8 representation splits the characters 16 bits
+between the bottom 4, 6 and 6 bits of the bytes.
+We need 8 bits to index into pages, 3 bits to add to that index and
+5 bits to generate the mask. */
+#define UTF8_GET_NAMING3(pages, byte) \
+ (namingBitmap[((pages)[((((byte)[0]) & 0xF) << 4) \
+ + ((((byte)[1]) >> 2) & 0xF)] \
+ << 3) \
+ + ((((byte)[1]) & 3) << 1) \
+ + ((((byte)[2]) >> 5) & 1)] \
+ & (1 << (((byte)[2]) & 0x1F)))
+
+#define UTF8_GET_NAMING(pages, p, n) \
+ ((n) == 2 \
+ ? UTF8_GET_NAMING2(pages, (const unsigned char *)(p)) \
+ : ((n) == 3 \
+ ? UTF8_GET_NAMING3(pages, (const unsigned char *)(p)) \
+ : 0))
+
+#define UTF8_INVALID3(p) \
+ ((*p) == 0xED \
+ ? (((p)[1] & 0x20) != 0) \
+ : ((*p) == 0xEF \
+ ? ((p)[1] == 0xBF && ((p)[2] == 0xBF || (p)[2] == 0xBE)) \
+ : 0))
+
+#define UTF8_INVALID4(p) ((*p) == 0xF4 && ((p)[1] & 0x30) != 0)
+
+static
+int isNever(const ENCODING *enc, const char *p)
+{
+ cmExpatUnused(enc);
+ cmExpatUnused(p);
+ return 0;
+}
+
+static
+int utf8_isName2(const ENCODING *enc, const char *p)
+{
+ cmExpatUnused(enc);
+ return UTF8_GET_NAMING2(namePages, (const unsigned char *)p);
+}
+
+static
+int utf8_isName3(const ENCODING *enc, const char *p)
+{
+ cmExpatUnused(enc);
+ return UTF8_GET_NAMING3(namePages, (const unsigned char *)p);
+}
+
+#define utf8_isName4 isNever
+
+static
+int utf8_isNmstrt2(const ENCODING *enc, const char *p)
+{
+ cmExpatUnused(enc);
+ return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p);
+}
+
+static
+int utf8_isNmstrt3(const ENCODING *enc, const char *p)
+{
+ cmExpatUnused(enc);
+ return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p);
+}
+
+#define utf8_isNmstrt4 isNever
+
+#define utf8_isInvalid2 isNever
+
+static
+int utf8_isInvalid3(const ENCODING *enc, const char *p)
+{
+ cmExpatUnused(enc);
+ return UTF8_INVALID3((const unsigned char *)p);
+}
+
+static
+int utf8_isInvalid4(const ENCODING *enc, const char *p)
+{
+ cmExpatUnused(enc);
+ return UTF8_INVALID4((const unsigned char *)p);
+}
+
+struct normal_encoding {
+ ENCODING enc;
+ unsigned char type[256];
+#ifdef XML_MIN_SIZE
+ int (*byteType)(const ENCODING *, const char *);
+ int (*isNameMin)(const ENCODING *, const char *);
+ int (*isNmstrtMin)(const ENCODING *, const char *);
+ int (*byteToAscii)(const ENCODING *, const char *);
+ int (*charMatches)(const ENCODING *, const char *, int);
+#endif /* XML_MIN_SIZE */
+ int (*isName2)(const ENCODING *, const char *);
+ int (*isName3)(const ENCODING *, const char *);
+ int (*isName4)(const ENCODING *, const char *);
+ int (*isNmstrt2)(const ENCODING *, const char *);
+ int (*isNmstrt3)(const ENCODING *, const char *);
+ int (*isNmstrt4)(const ENCODING *, const char *);
+ int (*isInvalid2)(const ENCODING *, const char *);
+ int (*isInvalid3)(const ENCODING *, const char *);
+ int (*isInvalid4)(const ENCODING *, const char *);
+};
+
+#ifdef XML_MIN_SIZE
+
+#define STANDARD_VTABLE(E) \
+ E ## byteType, \
+ E ## isNameMin, \
+ E ## isNmstrtMin, \
+ E ## byteToAscii, \
+ E ## charMatches,
+
+#else
+
+#define STANDARD_VTABLE(E) /* as nothing */
+
+#endif
+
+#define NORMAL_VTABLE(E) \
+ E ## isName2, \
+ E ## isName3, \
+ E ## isName4, \
+ E ## isNmstrt2, \
+ E ## isNmstrt3, \
+ E ## isNmstrt4, \
+ E ## isInvalid2, \
+ E ## isInvalid3, \
+ E ## isInvalid4
+
+#define EMPTY_VTABLE(E) 0, 0, 0, 0, 0, 0, 0, 0, 0
+
+static int checkCharRefNumber(int);
+
+#include "xmltok_impl.h"
+#include "ascii.h"
+
+#ifdef XML_MIN_SIZE
+#define sb_isNameMin isNever
+#define sb_isNmstrtMin isNever
+#endif
+
+#ifdef XML_MIN_SIZE
+#define MINBPC(enc) ((enc)->minBytesPerChar)
+#else
+/* minimum bytes per character */
+#define MINBPC(enc) 1
+#endif
+
+#define SB_BYTE_TYPE(enc, p) \
+ (((struct normal_encoding *)(enc))->type[(unsigned char)*(p)])
+
+#ifdef XML_MIN_SIZE
+static
+int sb_byteType(const ENCODING *enc, const char *p)
+{
+ return SB_BYTE_TYPE(enc, p);
+}
+#define BYTE_TYPE(enc, p) \
+ (((const struct normal_encoding *)(enc))->byteType(enc, p))
+#else
+#define BYTE_TYPE(enc, p) SB_BYTE_TYPE(enc, p)
+#endif
+
+#ifdef XML_MIN_SIZE
+#define BYTE_TO_ASCII(enc, p) \
+ (((const struct normal_encoding *)(enc))->byteToAscii(enc, p))
+static
+int sb_byteToAscii(const ENCODING *enc, const char *p)
+{
+ return *p;
+}
+#else
+#define BYTE_TO_ASCII(enc, p) (*(p))
+#endif
+
+#define IS_NAME_CHAR(enc, p, n) \
+ (((const struct normal_encoding *)(enc))->isName ## n(enc, p))
+#define IS_NMSTRT_CHAR(enc, p, n) \
+ (((const struct normal_encoding *)(enc))->isNmstrt ## n(enc, p))
+#define IS_INVALID_CHAR(enc, p, n) \
+ (((const struct normal_encoding *)(enc))->isInvalid ## n(enc, p))
+
+#ifdef XML_MIN_SIZE
+#define IS_NAME_CHAR_MINBPC(enc, p) \
+ (((const struct normal_encoding *)(enc))->isNameMin(enc, p))
+#define IS_NMSTRT_CHAR_MINBPC(enc, p) \
+ (((const struct normal_encoding *)(enc))->isNmstrtMin(enc, p))
+#else
+#define IS_NAME_CHAR_MINBPC(enc, p) (0)
+#define IS_NMSTRT_CHAR_MINBPC(enc, p) (0)
+#endif
+
+#ifdef XML_MIN_SIZE
+#define CHAR_MATCHES(enc, p, c) \
+ (((const struct normal_encoding *)(enc))->charMatches(enc, p, c))
+static
+int sb_charMatches(const ENCODING *enc, const char *p, int c)
+{
+ return *p == c;
+}
+#else
+/* c is an ASCII character */
+#define CHAR_MATCHES(enc, p, c) (*(p) == c)
+#endif
+
+#define PREFIX(ident) normal_ ## ident
+#include "xmltok_impl.c"
+
+#undef MINBPC
+#undef BYTE_TYPE
+#undef BYTE_TO_ASCII
+#undef CHAR_MATCHES
+#undef IS_NAME_CHAR
+#undef IS_NAME_CHAR_MINBPC
+#undef IS_NMSTRT_CHAR
+#undef IS_NMSTRT_CHAR_MINBPC
+#undef IS_INVALID_CHAR
+
+enum { /* UTF8_cvalN is value of masked first byte of N byte sequence */
+ UTF8_cval1 = 0x00,
+ UTF8_cval2 = 0xc0,
+ UTF8_cval3 = 0xe0,
+ UTF8_cval4 = 0xf0
+};
+
+static
+void utf8_toUtf8(const ENCODING *enc,
+ const char **fromP, const char *fromLim,
+ char **toP, const char *toLim)
+{
+ char *to;
+ const char *from;
+ cmExpatUnused(enc);
+ if (fromLim - *fromP > toLim - *toP) {
+ /* Avoid copying partial characters. */
+ for (fromLim = *fromP + (toLim - *toP); fromLim > *fromP; fromLim--)
+ if (((unsigned char)fromLim[-1] & 0xc0) != 0x80)
+ break;
+ }
+ for (to = *toP, from = *fromP; from != fromLim; from++, to++)
+ *to = *from;
+ *fromP = from;
+ *toP = to;
+}
+
+static
+void utf8_toUtf16(const ENCODING *enc,
+ const char **fromP, const char *fromLim,
+ unsigned short **toP, const unsigned short *toLim)
+{
+ unsigned short *to = *toP;
+ const char *from = *fromP;
+ while (from != fromLim && to != toLim) {
+ switch (((struct normal_encoding *)enc)->type[(unsigned char)*from]) {
+ case BT_LEAD2:
+ *to++ = ((from[0] & 0x1f) << 6) | (from[1] & 0x3f);
+ from += 2;
+ break;
+ case BT_LEAD3:
+ *to++ = ((from[0] & 0xf) << 12) | ((from[1] & 0x3f) << 6) | (from[2] & 0x3f);
+ from += 3;
+ break;
+ case BT_LEAD4:
+ {
+ unsigned long n;
+ if (to + 1 == toLim)
+ break;
+ n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12) | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f);
+ n -= 0x10000;
+ to[0] = (unsigned short)((n >> 10) | 0xD800);
+ to[1] = (unsigned short)((n & 0x3FF) | 0xDC00);
+ to += 2;
+ from += 4;
+ }
+ break;
+ default:
+ *to++ = *from++;
+ break;
+ }
+ }
+ *fromP = from;
+ *toP = to;
+}
+
+#ifdef XML_NS
+static const struct normal_encoding utf8_encoding_ns = {
+ { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
+ {
+#include "asciitab.h"
+#include "utf8tab.h"
+ },
+ STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
+};
+#endif
+
+static const struct normal_encoding utf8_encoding = {
+ { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
+ {
+#define BT_COLON BT_NMSTRT
+#include "asciitab.h"
+#undef BT_COLON
+#include "utf8tab.h"
+ },
+ STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
+};
+
+#ifdef XML_NS
+
+static const struct normal_encoding internal_utf8_encoding_ns = {
+ { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
+ {
+#include "iasciitab.h"
+#include "utf8tab.h"
+ },
+ STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
+};
+
+#endif
+
+static const struct normal_encoding internal_utf8_encoding = {
+ { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
+ {
+#define BT_COLON BT_NMSTRT
+#include "iasciitab.h"
+#undef BT_COLON
+#include "utf8tab.h"
+ },
+ STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
+};
+
+static
+void latin1_toUtf8(const ENCODING *enc,
+ const char **fromP, const char *fromLim,
+ char **toP, const char *toLim)
+{
+ cmExpatUnused(enc);
+ for (;;) {
+ unsigned char c;
+ if (*fromP == fromLim)
+ break;
+ c = (unsigned char)**fromP;
+ if (c & 0x80) {
+ if (toLim - *toP < 2)
+ break;
+ *(*toP)++ = ((c >> 6) | UTF8_cval2);
+ *(*toP)++ = ((c & 0x3f) | 0x80);
+ (*fromP)++;
+ }
+ else {
+ if (*toP == toLim)
+ break;
+ *(*toP)++ = *(*fromP)++;
+ }
+ }
+}
+
+static
+void latin1_toUtf16(const ENCODING *enc,
+ const char **fromP, const char *fromLim,
+ unsigned short **toP, const unsigned short *toLim)
+{
+ cmExpatUnused(enc);
+ while (*fromP != fromLim && *toP != toLim)
+ *(*toP)++ = (unsigned char)*(*fromP)++;
+}
+
+#ifdef XML_NS
+
+static const struct normal_encoding latin1_encoding_ns = {
+ { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 },
+ {
+#include "asciitab.h"
+#include "latin1tab.h"
+ },
+ STANDARD_VTABLE(sb_) EMPTY_VTABLE(sb_)
+};
+
+#endif
+
+static const struct normal_encoding latin1_encoding = {
+ { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 },
+ {
+#define BT_COLON BT_NMSTRT
+#include "asciitab.h"
+#undef BT_COLON
+#include "latin1tab.h"
+ },
+ STANDARD_VTABLE(sb_) EMPTY_VTABLE(sb_)
+};
+
+static
+void ascii_toUtf8(const ENCODING *enc,
+ const char **fromP, const char *fromLim,
+ char **toP, const char *toLim)
+{
+ cmExpatUnused(enc);
+ while (*fromP != fromLim && *toP != toLim)
+ *(*toP)++ = *(*fromP)++;
+}
+
+#ifdef XML_NS
+
+static const struct normal_encoding ascii_encoding_ns = {
+ { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 },
+ {
+#include "asciitab.h"
+/* BT_NONXML == 0 */
+ },
+ STANDARD_VTABLE(sb_) EMPTY_VTABLE(sb_)
+};
+
+#endif
+
+static const struct normal_encoding ascii_encoding = {
+ { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 },
+ {
+#define BT_COLON BT_NMSTRT
+#include "asciitab.h"
+#undef BT_COLON
+/* BT_NONXML == 0 */
+ },
+ STANDARD_VTABLE(sb_) EMPTY_VTABLE(sb_)
+};
+
+static int unicode_byte_type(char hi, char lo)
+{
+ switch ((unsigned char)hi) {
+ case 0xD8: case 0xD9: case 0xDA: case 0xDB:
+ return BT_LEAD4;
+ case 0xDC: case 0xDD: case 0xDE: case 0xDF:
+ return BT_TRAIL;
+ case 0xFF:
+ switch ((unsigned char)lo) {
+ case 0xFF:
+ case 0xFE:
+ return BT_NONXML;
+ }
+ break;
+ }
+ return BT_NONASCII;
+}
+
+#define DEFINE_UTF16_TO_UTF8(E) \
+static \
+void E ## toUtf8(const ENCODING *enc, \
+ const char **fromP, const char *fromLim, \
+ char **toP, const char *toLim) \
+{ \
+ const char *from; \
+ cmExpatUnused(enc);\
+ for (from = *fromP; from != fromLim; from += 2) { \
+ int plane; \
+ unsigned char lo2; \
+ unsigned char lo = GET_LO(from); \
+ unsigned char hi = GET_HI(from); \
+ switch (hi) { \
+ case 0: \
+ if (lo < 0x80) { \
+ if (*toP == toLim) { \
+ *fromP = from; \
+ return; \
+ } \
+ *(*toP)++ = lo; \
+ break; \
+ } \
+ /* fall through */ \
+ case 0x1: case 0x2: case 0x3: \
+ case 0x4: case 0x5: case 0x6: case 0x7: \
+ if (toLim - *toP < 2) { \
+ *fromP = from; \
+ return; \
+ } \
+ *(*toP)++ = ((lo >> 6) | (hi << 2) | UTF8_cval2); \
+ *(*toP)++ = ((lo & 0x3f) | 0x80); \
+ break; \
+ default: \
+ if (toLim - *toP < 3) { \
+ *fromP = from; \
+ return; \
+ } \
+ /* 16 bits divided 4, 6, 6 amongst 3 bytes */ \
+ *(*toP)++ = ((hi >> 4) | UTF8_cval3); \
+ *(*toP)++ = (((hi & 0xf) << 2) | (lo >> 6) | 0x80); \
+ *(*toP)++ = ((lo & 0x3f) | 0x80); \
+ break; \
+ case 0xD8: case 0xD9: case 0xDA: case 0xDB: \
+ if (toLim - *toP < 4) { \
+ *fromP = from; \
+ return; \
+ } \
+ plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1; \
+ *(*toP)++ = ((plane >> 2) | UTF8_cval4); \
+ *(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80); \
+ from += 2; \
+ lo2 = GET_LO(from); \
+ *(*toP)++ = (((lo & 0x3) << 4) \
+ | ((GET_HI(from) & 0x3) << 2) \
+ | (lo2 >> 6) \
+ | 0x80); \
+ *(*toP)++ = ((lo2 & 0x3f) | 0x80); \
+ break; \
+ } \
+ } \
+ *fromP = from; \
+}
+
+#define DEFINE_UTF16_TO_UTF16(E) \
+static \
+void E ## toUtf16(const ENCODING *enc, \
+ const char **fromP, const char *fromLim, \
+ unsigned short **toP, const unsigned short *toLim) \
+{ \
+ cmExpatUnused(enc);\
+ /* Avoid copying first half only of surrogate */ \
+ if (fromLim - *fromP > ((toLim - *toP) << 1) \
+ && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) \
+ fromLim -= 2; \
+ for (; *fromP != fromLim && *toP != toLim; *fromP += 2) \
+ *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \
+}
+
+#define SET2(ptr, ch) \
+ (((ptr)[0] = ((ch) & 0xff)), ((ptr)[1] = ((ch) >> 8)))
+#define GET_LO(ptr) ((unsigned char)(ptr)[0])
+#define GET_HI(ptr) ((unsigned char)(ptr)[1])
+
+DEFINE_UTF16_TO_UTF8(little2_)
+DEFINE_UTF16_TO_UTF16(little2_)
+
+#undef SET2
+#undef GET_LO
+#undef GET_HI
+
+#define SET2(ptr, ch) \
+ (((ptr)[0] = ((ch) >> 8)), ((ptr)[1] = ((ch) & 0xFF)))
+#define GET_LO(ptr) ((unsigned char)(ptr)[1])
+#define GET_HI(ptr) ((unsigned char)(ptr)[0])
+
+DEFINE_UTF16_TO_UTF8(big2_)
+DEFINE_UTF16_TO_UTF16(big2_)
+
+#undef SET2
+#undef GET_LO
+#undef GET_HI
+
+#define LITTLE2_BYTE_TYPE(enc, p) \
+ ((p)[1] == 0 \
+ ? ((struct normal_encoding *)(enc))->type[(unsigned char)*(p)] \
+ : unicode_byte_type((p)[1], (p)[0]))
+#define LITTLE2_BYTE_TO_ASCII(enc, p) ((p)[1] == 0 ? (p)[0] : -1)
+#define LITTLE2_CHAR_MATCHES(enc, p, c) ((p)[1] == 0 && (p)[0] == c)
+#define LITTLE2_IS_NAME_CHAR_MINBPC(enc, p) \
+ UCS2_GET_NAMING(namePages, (unsigned char)p[1], (unsigned char)p[0])
+#define LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p) \
+ UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[1], (unsigned char)p[0])
+
+#ifdef XML_MIN_SIZE
+
+static
+int little2_byteType(const ENCODING *enc, const char *p)
+{
+ return LITTLE2_BYTE_TYPE(enc, p);
+}
+
+static
+int little2_byteToAscii(const ENCODING *enc, const char *p)
+{
+ return LITTLE2_BYTE_TO_ASCII(enc, p);
+}
+
+static
+int little2_charMatches(const ENCODING *enc, const char *p, int c)
+{
+ return LITTLE2_CHAR_MATCHES(enc, p, c);
+}
+
+static
+int little2_isNameMin(const ENCODING *enc, const char *p)
+{
+ return LITTLE2_IS_NAME_CHAR_MINBPC(enc, p);
+}
+
+static
+int little2_isNmstrtMin(const ENCODING *enc, const char *p)
+{
+ return LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p);
+}
+
+#undef VTABLE
+#define VTABLE VTABLE1, little2_toUtf8, little2_toUtf16
+
+#else /* not XML_MIN_SIZE */
+
+#undef PREFIX
+#define PREFIX(ident) little2_ ## ident
+#define MINBPC(enc) 2
+/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */
+#define BYTE_TYPE(enc, p) LITTLE2_BYTE_TYPE(enc, p)
+#define BYTE_TO_ASCII(enc, p) LITTLE2_BYTE_TO_ASCII(enc, p)
+#define CHAR_MATCHES(enc, p, c) LITTLE2_CHAR_MATCHES(enc, p, c)
+#define IS_NAME_CHAR(enc, p, n) 0
+#define IS_NAME_CHAR_MINBPC(enc, p) LITTLE2_IS_NAME_CHAR_MINBPC(enc, p)
+#define IS_NMSTRT_CHAR(enc, p, n) (0)
+#define IS_NMSTRT_CHAR_MINBPC(enc, p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p)
+
+#include "xmltok_impl.c"
+
+#undef MINBPC
+#undef BYTE_TYPE
+#undef BYTE_TO_ASCII
+#undef CHAR_MATCHES
+#undef IS_NAME_CHAR
+#undef IS_NAME_CHAR_MINBPC
+#undef IS_NMSTRT_CHAR
+#undef IS_NMSTRT_CHAR_MINBPC
+#undef IS_INVALID_CHAR
+
+#endif /* not XML_MIN_SIZE */
+
+#ifdef XML_NS
+
+static const struct normal_encoding little2_encoding_ns = {
+ { VTABLE, 2, 0,
+#if XML_BYTE_ORDER == 12
+ 1
+#else
+ 0
+#endif
+ },
+ {
+#include "asciitab.h"
+#include "latin1tab.h"
+ },
+ STANDARD_VTABLE(little2_) EMPTY_VTABLE(little2_)
+};
+
+#endif
+
+static const struct normal_encoding little2_encoding = {
+ { VTABLE, 2, 0,
+#if XML_BYTE_ORDER == 12
+ 1
+#else
+ 0
+#endif
+ },
+ {
+#define BT_COLON BT_NMSTRT
+#include "asciitab.h"
+#undef BT_COLON
+#include "latin1tab.h"
+ },
+ STANDARD_VTABLE(little2_) EMPTY_VTABLE(little2_)
+};
+
+#if XML_BYTE_ORDER != 21
+
+#ifdef XML_NS
+
+static const struct normal_encoding internal_little2_encoding_ns = {
+ { VTABLE, 2, 0, 1 },
+ {
+#include "iasciitab.h"
+#include "latin1tab.h"
+ },
+ STANDARD_VTABLE(little2_) EMPTY_VTABLE(little2_)
+};
+
+#endif
+
+static const struct normal_encoding internal_little2_encoding = {
+ { VTABLE, 2, 0, 1 },
+ {
+#define BT_COLON BT_NMSTRT
+#include "iasciitab.h"
+#undef BT_COLON
+#include "latin1tab.h"
+ },
+ STANDARD_VTABLE(little2_) EMPTY_VTABLE(little2_)
+};
+
+#endif
+
+
+#define BIG2_BYTE_TYPE(enc, p) \
+ ((p)[0] == 0 \
+ ? ((struct normal_encoding *)(enc))->type[(unsigned char)(p)[1]] \
+ : unicode_byte_type((p)[0], (p)[1]))
+#define BIG2_BYTE_TO_ASCII(enc, p) ((p)[0] == 0 ? (p)[1] : -1)
+#define BIG2_CHAR_MATCHES(enc, p, c) ((p)[0] == 0 && (p)[1] == c)
+#define BIG2_IS_NAME_CHAR_MINBPC(enc, p) \
+ UCS2_GET_NAMING(namePages, (unsigned char)p[0], (unsigned char)p[1])
+#define BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p) \
+ UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[0], (unsigned char)p[1])
+
+#ifdef XML_MIN_SIZE
+
+static
+int big2_byteType(const ENCODING *enc, const char *p)
+{
+ return BIG2_BYTE_TYPE(enc, p);
+}
+
+static
+int big2_byteToAscii(const ENCODING *enc, const char *p)
+{
+ return BIG2_BYTE_TO_ASCII(enc, p);
+}
+
+static
+int big2_charMatches(const ENCODING *enc, const char *p, int c)
+{
+ return BIG2_CHAR_MATCHES(enc, p, c);
+}
+
+static
+int big2_isNameMin(const ENCODING *enc, const char *p)
+{
+ return BIG2_IS_NAME_CHAR_MINBPC(enc, p);
+}
+
+static
+int big2_isNmstrtMin(const ENCODING *enc, const char *p)
+{
+ return BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p);
+}
+
+#undef VTABLE
+#define VTABLE VTABLE1, big2_toUtf8, big2_toUtf16
+
+#else /* not XML_MIN_SIZE */
+
+#undef PREFIX
+#define PREFIX(ident) big2_ ## ident
+#define MINBPC(enc) 2
+/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */
+#define BYTE_TYPE(enc, p) BIG2_BYTE_TYPE(enc, p)
+#define BYTE_TO_ASCII(enc, p) BIG2_BYTE_TO_ASCII(enc, p)
+#define CHAR_MATCHES(enc, p, c) BIG2_CHAR_MATCHES(enc, p, c)
+#define IS_NAME_CHAR(enc, p, n) 0
+#define IS_NAME_CHAR_MINBPC(enc, p) BIG2_IS_NAME_CHAR_MINBPC(enc, p)
+#define IS_NMSTRT_CHAR(enc, p, n) (0)
+#define IS_NMSTRT_CHAR_MINBPC(enc, p) BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p)
+
+#include "xmltok_impl.c"
+
+#undef MINBPC
+#undef BYTE_TYPE
+#undef BYTE_TO_ASCII
+#undef CHAR_MATCHES
+#undef IS_NAME_CHAR
+#undef IS_NAME_CHAR_MINBPC
+#undef IS_NMSTRT_CHAR
+#undef IS_NMSTRT_CHAR_MINBPC
+#undef IS_INVALID_CHAR
+
+#endif /* not XML_MIN_SIZE */
+
+#ifdef XML_NS
+
+static const struct normal_encoding big2_encoding_ns = {
+ { VTABLE, 2, 0,
+#if XML_BYTE_ORDER == 21
+ 1
+#else
+ 0
+#endif
+ },
+ {
+#include "asciitab.h"
+#include "latin1tab.h"
+ },
+ STANDARD_VTABLE(big2_) EMPTY_VTABLE(big2_)
+};
+
+#endif
+
+static const struct normal_encoding big2_encoding = {
+ { VTABLE, 2, 0,
+#if XML_BYTE_ORDER == 21
+ 1
+#else
+ 0
+#endif
+ },
+ {
+#define BT_COLON BT_NMSTRT
+#include "asciitab.h"
+#undef BT_COLON
+#include "latin1tab.h"
+ },
+ STANDARD_VTABLE(big2_) EMPTY_VTABLE(big2_)
+};
+
+#if XML_BYTE_ORDER != 12
+
+#ifdef XML_NS
+
+static const struct normal_encoding internal_big2_encoding_ns = {
+ { VTABLE, 2, 0, 1 },
+ {
+#include "iasciitab.h"
+#include "latin1tab.h"
+ },
+ STANDARD_VTABLE(big2_) EMPTY_VTABLE(big2_)
+};
+
+#endif
+
+static const struct normal_encoding internal_big2_encoding = {
+ { VTABLE, 2, 0, 1 },
+ {
+#define BT_COLON BT_NMSTRT
+#include "iasciitab.h"
+#undef BT_COLON
+#include "latin1tab.h"
+ },
+ STANDARD_VTABLE(big2_) EMPTY_VTABLE(big2_)
+};
+
+#endif
+
+#undef PREFIX
+
+static
+int streqci(const char *s1, const char *s2)
+{
+ for (;;) {
+ char c1 = *s1++;
+ char c2 = *s2++;
+ if (ASCII_a <= c1 && c1 <= ASCII_z)
+ c1 += ASCII_A - ASCII_a;
+ if (ASCII_a <= c2 && c2 <= ASCII_z)
+ c2 += ASCII_A - ASCII_a;
+ if (c1 != c2)
+ return 0;
+ if (!c1)
+ break;
+ }
+ return 1;
+}
+
+static
+void initUpdatePosition(const ENCODING *enc, const char *ptr,
+ const char *end, POSITION *pos)
+{
+ cmExpatUnused(enc);
+ normal_updatePosition(&utf8_encoding.enc, ptr, end, pos);
+}
+
+static
+int toAscii(const ENCODING *enc, const char *ptr, const char *end)
+{
+ char buf[1];
+ char *p = buf;
+ XmlUtf8Convert(enc, &ptr, end, &p, p + 1);
+ if (p == buf)
+ return -1;
+ else
+ return buf[0];
+}
+
+static
+int isSpace(int c)
+{
+ switch (c) {
+ case 0x20:
+ case 0xD:
+ case 0xA:
+ case 0x9:
+ return 1;
+ }
+ return 0;
+}
+
+/* Return 1 if there's just optional white space
+or there's an S followed by name=val. */
+static
+int parsePseudoAttribute(const ENCODING *enc,
+ const char *ptr,
+ const char *end,
+ const char **namePtr,
+ const char **nameEndPtr,
+ const char **valPtr,
+ const char **nextTokPtr)
+{
+ int c;
+ char open;
+ if (ptr == end) {
+ *namePtr = 0;
+ return 1;
+ }
+ if (!isSpace(toAscii(enc, ptr, end))) {
+ *nextTokPtr = ptr;
+ return 0;
+ }
+ do {
+ ptr += enc->minBytesPerChar;
+ } while (isSpace(toAscii(enc, ptr, end)));
+ if (ptr == end) {
+ *namePtr = 0;
+ return 1;
+ }
+ *namePtr = ptr;
+ for (;;) {
+ c = toAscii(enc, ptr, end);
+ if (c == -1) {
+ *nextTokPtr = ptr;
+ return 0;
+ }
+ if (c == ASCII_EQUALS) {
+ *nameEndPtr = ptr;
+ break;
+ }
+ if (isSpace(c)) {
+ *nameEndPtr = ptr;
+ do {
+ ptr += enc->minBytesPerChar;
+ } while (isSpace(c = toAscii(enc, ptr, end)));
+ if (c != ASCII_EQUALS) {
+ *nextTokPtr = ptr;
+ return 0;
+ }
+ break;
+ }
+ ptr += enc->minBytesPerChar;
+ }
+ if (ptr == *namePtr) {
+ *nextTokPtr = ptr;
+ return 0;
+ }
+ ptr += enc->minBytesPerChar;
+ c = toAscii(enc, ptr, end);
+ while (isSpace(c)) {
+ ptr += enc->minBytesPerChar;
+ c = toAscii(enc, ptr, end);
+ }
+ if (c != ASCII_QUOT && c != ASCII_APOS) {
+ *nextTokPtr = ptr;
+ return 0;
+ }
+ open = c;
+ ptr += enc->minBytesPerChar;
+ *valPtr = ptr;
+ for (;; ptr += enc->minBytesPerChar) {
+ c = toAscii(enc, ptr, end);
+ if (c == open)
+ break;
+ if (!(ASCII_a <= c && c <= ASCII_z)
+ && !(ASCII_A <= c && c <= ASCII_Z)
+ && !(ASCII_0 <= c && c <= ASCII_9)
+ && c != ASCII_PERIOD
+ && c != ASCII_MINUS
+ && c != ASCII_UNDERSCORE) {
+ *nextTokPtr = ptr;
+ return 0;
+ }
+ }
+ *nextTokPtr = ptr + enc->minBytesPerChar;
+ return 1;
+}
+
+static const char KW_version[] = {
+ ASCII_v, ASCII_e, ASCII_r, ASCII_s, ASCII_i, ASCII_o, ASCII_n, '\0'
+};
+
+static const char KW_encoding[] = {
+ ASCII_e, ASCII_n, ASCII_c, ASCII_o, ASCII_d, ASCII_i, ASCII_n, ASCII_g, '\0'
+};
+
+static const char KW_standalone[] = {
+ ASCII_s, ASCII_t, ASCII_a, ASCII_n, ASCII_d, ASCII_a, ASCII_l, ASCII_o, ASCII_n, ASCII_e, '\0'
+};
+
+static const char KW_yes[] = {
+ ASCII_y, ASCII_e, ASCII_s, '\0'
+};
+
+static const char KW_no[] = {
+ ASCII_n, ASCII_o, '\0'
+};
+
+static
+int doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *,
+ const char *,
+ const char *),
+ int isGeneralTextEntity,
+ const ENCODING *enc,
+ const char *ptr,
+ const char *end,
+ const char **badPtr,
+ const char **versionPtr,
+ const char **versionEndPtr,
+ const char **encodingName,
+ const ENCODING **encoding,
+ int *standalone)
+{
+ const char *val = 0;
+ const char *name = 0;
+ const char *nameEnd = 0;
+ ptr += 5 * enc->minBytesPerChar;
+ end -= 2 * enc->minBytesPerChar;
+ if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr) || !name) {
+ *badPtr = ptr;
+ return 0;
+ }
+ if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_version)) {
+ if (!isGeneralTextEntity) {
+ *badPtr = name;
+ return 0;
+ }
+ }
+ else {
+ if (versionPtr)
+ *versionPtr = val;
+ if (versionEndPtr)
+ *versionEndPtr = ptr;
+ if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) {
+ *badPtr = ptr;
+ return 0;
+ }
+ if (!name) {
+ if (isGeneralTextEntity) {
+ /* a TextDecl must have an EncodingDecl */
+ *badPtr = ptr;
+ return 0;
+ }
+ return 1;
+ }
+ }
+ if (XmlNameMatchesAscii(enc, name, nameEnd, KW_encoding)) {
+ int c = toAscii(enc, val, end);
+ if (!(ASCII_a <= c && c <= ASCII_z) && !(ASCII_A <= c && c <= ASCII_Z)) {
+ *badPtr = val;
+ return 0;
+ }
+ if (encodingName)
+ *encodingName = val;
+ if (encoding)
+ *encoding = encodingFinder(enc, val, ptr - enc->minBytesPerChar);
+ if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) {
+ *badPtr = ptr;
+ return 0;
+ }
+ if (!name)
+ return 1;
+ }
+ if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_standalone) || isGeneralTextEntity) {
+ *badPtr = name;
+ return 0;
+ }
+ if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_yes)) {
+ if (standalone)
+ *standalone = 1;
+ }
+ else if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_no)) {
+ if (standalone)
+ *standalone = 0;
+ }
+ else {
+ *badPtr = val;
+ return 0;
+ }
+ while (isSpace(toAscii(enc, ptr, end)))
+ ptr += enc->minBytesPerChar;
+ if (ptr != end) {
+ *badPtr = ptr;
+ return 0;
+ }
+ return 1;
+}
+
+static
+int checkCharRefNumber(int result)
+{
+ switch (result >> 8) {
+ case 0xD8: case 0xD9: case 0xDA: case 0xDB:
+ case 0xDC: case 0xDD: case 0xDE: case 0xDF:
+ return -1;
+ case 0:
+ if (latin1_encoding.type[result] == BT_NONXML)
+ return -1;
+ break;
+ case 0xFF:
+ if (result == 0xFFFE || result == 0xFFFF)
+ return -1;
+ break;
+ }
+ return result;
+}
+
+int XmlUtf8Encode(int c, char *buf)
+{
+ enum {
+ /* minN is minimum legal resulting value for N byte sequence */
+ min2 = 0x80,
+ min3 = 0x800,
+ min4 = 0x10000
+ };
+
+ if (c < 0)
+ return 0;
+ if (c < min2) {
+ buf[0] = (c | UTF8_cval1);
+ return 1;
+ }
+ if (c < min3) {
+ buf[0] = ((c >> 6) | UTF8_cval2);
+ buf[1] = ((c & 0x3f) | 0x80);
+ return 2;
+ }
+ if (c < min4) {
+ buf[0] = ((c >> 12) | UTF8_cval3);
+ buf[1] = (((c >> 6) & 0x3f) | 0x80);
+ buf[2] = ((c & 0x3f) | 0x80);
+ return 3;
+ }
+ if (c < 0x110000) {
+ buf[0] = ((c >> 18) | UTF8_cval4);
+ buf[1] = (((c >> 12) & 0x3f) | 0x80);
+ buf[2] = (((c >> 6) & 0x3f) | 0x80);
+ buf[3] = ((c & 0x3f) | 0x80);
+ return 4;
+ }
+ return 0;
+}
+
+int XmlUtf16Encode(int charNum, unsigned short *buf)
+{
+ if (charNum < 0)
+ return 0;
+ if (charNum < 0x10000) {
+ buf[0] = charNum;
+ return 1;
+ }
+ if (charNum < 0x110000) {
+ charNum -= 0x10000;
+ buf[0] = (charNum >> 10) + 0xD800;
+ buf[1] = (charNum & 0x3FF) + 0xDC00;
+ return 2;
+ }
+ return 0;
+}
+
+struct unknown_encoding {
+ struct normal_encoding normal;
+ int (*convert)(void *userData, const char *p);
+ void *userData;
+ unsigned short utf16[256];
+ char utf8[256][4];
+};
+
+int XmlSizeOfUnknownEncoding(void)
+{
+ return sizeof(struct unknown_encoding);
+}
+
+static
+int unknown_isName(const ENCODING *enc, const char *p)
+{
+ int c = ((const struct unknown_encoding *)enc)
+ ->convert(((const struct unknown_encoding *)enc)->userData, p);
+ if (c & ~0xFFFF)
+ return 0;
+ return UCS2_GET_NAMING(namePages, c >> 8, c & 0xFF);
+}
+
+static
+int unknown_isNmstrt(const ENCODING *enc, const char *p)
+{
+ int c = ((const struct unknown_encoding *)enc)
+ ->convert(((const struct unknown_encoding *)enc)->userData, p);
+ if (c & ~0xFFFF)
+ return 0;
+ return UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xFF);
+}
+
+static
+int unknown_isInvalid(const ENCODING *enc, const char *p)
+{
+ int c = ((const struct unknown_encoding *)enc)
+ ->convert(((const struct unknown_encoding *)enc)->userData, p);
+ return (c & ~0xFFFF) || checkCharRefNumber(c) < 0;
+}
+
+static
+void unknown_toUtf8(const ENCODING *enc,
+ const char **fromP, const char *fromLim,
+ char **toP, const char *toLim)
+{
+ char buf[XML_UTF8_ENCODE_MAX];
+ for (;;) {
+ const char *utf8;
+ int n;
+ if (*fromP == fromLim)
+ break;
+ utf8 = ((const struct unknown_encoding *)enc)->utf8[(unsigned char)**fromP];
+ n = *utf8++;
+ if (n == 0) {
+ int c = ((const struct unknown_encoding *)enc)
+ ->convert(((const struct unknown_encoding *)enc)->userData, *fromP);
+ n = XmlUtf8Encode(c, buf);
+ if (n > toLim - *toP)
+ break;
+ utf8 = buf;
+ *fromP += ((const struct normal_encoding *)enc)->type[(unsigned char)**fromP]
+ - (BT_LEAD2 - 2);
+ }
+ else {
+ if (n > toLim - *toP)
+ break;
+ (*fromP)++;
+ }
+ do {
+ *(*toP)++ = *utf8++;
+ } while (--n != 0);
+ }
+}
+
+static
+void unknown_toUtf16(const ENCODING *enc,
+ const char **fromP, const char *fromLim,
+ unsigned short **toP, const unsigned short *toLim)
+{
+ while (*fromP != fromLim && *toP != toLim) {
+ unsigned short c
+ = ((const struct unknown_encoding *)enc)->utf16[(unsigned char)**fromP];
+ if (c == 0) {
+ c = (unsigned short)((const struct unknown_encoding *)enc)
+ ->convert(((const struct unknown_encoding *)enc)->userData, *fromP);
+ *fromP += ((const struct normal_encoding *)enc)->type[(unsigned char)**fromP]
+ - (BT_LEAD2 - 2);
+ }
+ else
+ (*fromP)++;
+ *(*toP)++ = c;
+ }
+}
+
+ENCODING *
+XmlInitUnknownEncoding(void *mem,
+ int *table,
+ int (*convert)(void *userData, const char *p),
+ void *userData)
+{
+ int i;
+ struct unknown_encoding *e = mem;
+ for (i = 0; i < (int)sizeof(struct normal_encoding); i++)
+ ((char *)mem)[i] = ((char *)&latin1_encoding)[i];
+ for (i = 0; i < 128; i++)
+ if (latin1_encoding.type[i] != BT_OTHER
+ && latin1_encoding.type[i] != BT_NONXML
+ && table[i] != i)
+ return 0;
+ for (i = 0; i < 256; i++) {
+ int c = table[i];
+ if (c == -1) {
+ e->normal.type[i] = BT_MALFORM;
+ /* This shouldn't really get used. */
+ e->utf16[i] = 0xFFFF;
+ e->utf8[i][0] = 1;
+ e->utf8[i][1] = 0;
+ }
+ else if (c < 0) {
+ if (c < -4)
+ return 0;
+ e->normal.type[i] = BT_LEAD2 - (c + 2);
+ e->utf8[i][0] = 0;
+ e->utf16[i] = 0;
+ }
+ else if (c < 0x80) {
+ if (latin1_encoding.type[c] != BT_OTHER
+ && latin1_encoding.type[c] != BT_NONXML
+ && c != i)
+ return 0;
+ e->normal.type[i] = latin1_encoding.type[c];
+ e->utf8[i][0] = 1;
+ e->utf8[i][1] = (char)c;
+ e->utf16[i] = c == 0 ? 0xFFFF : c;
+ }
+ else if (checkCharRefNumber(c) < 0) {
+ e->normal.type[i] = BT_NONXML;
+ /* This shouldn't really get used. */
+ e->utf16[i] = 0xFFFF;
+ e->utf8[i][0] = 1;
+ e->utf8[i][1] = 0;
+ }
+ else {
+ if (c > 0xFFFF)
+ return 0;
+ if (UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xff))
+ e->normal.type[i] = BT_NMSTRT;
+ else if (UCS2_GET_NAMING(namePages, c >> 8, c & 0xff))
+ e->normal.type[i] = BT_NAME;
+ else
+ e->normal.type[i] = BT_OTHER;
+ e->utf8[i][0] = (char)XmlUtf8Encode(c, e->utf8[i] + 1);
+ e->utf16[i] = c;
+ }
+ }
+ e->userData = userData;
+ e->convert = convert;
+ if (convert) {
+ e->normal.isName2 = unknown_isName;
+ e->normal.isName3 = unknown_isName;
+ e->normal.isName4 = unknown_isName;
+ e->normal.isNmstrt2 = unknown_isNmstrt;
+ e->normal.isNmstrt3 = unknown_isNmstrt;
+ e->normal.isNmstrt4 = unknown_isNmstrt;
+ e->normal.isInvalid2 = unknown_isInvalid;
+ e->normal.isInvalid3 = unknown_isInvalid;
+ e->normal.isInvalid4 = unknown_isInvalid;
+ }
+ e->normal.enc.utf8Convert = unknown_toUtf8;
+ e->normal.enc.utf16Convert = unknown_toUtf16;
+ return &(e->normal.enc);
+}
+
+/* If this enumeration is changed, getEncodingIndex and encodings
+must also be changed. */
+enum {
+ UNKNOWN_ENC = -1,
+ ISO_8859_1_ENC = 0,
+ US_ASCII_ENC,
+ UTF_8_ENC,
+ UTF_16_ENC,
+ UTF_16BE_ENC,
+ UTF_16LE_ENC,
+ /* must match encodingNames up to here */
+ NO_ENC
+};
+
+static const char KW_ISO_8859_1[] = {
+ ASCII_I, ASCII_S, ASCII_O, ASCII_MINUS, ASCII_8, ASCII_8, ASCII_5, ASCII_9, ASCII_MINUS, ASCII_1, '\0'
+};
+static const char KW_US_ASCII[] = {
+ ASCII_U, ASCII_S, ASCII_MINUS, ASCII_A, ASCII_S, ASCII_C, ASCII_I, ASCII_I, '\0'
+};
+static const char KW_UTF_8[] = {
+ ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_8, '\0'
+};
+static const char KW_UTF_16[] = {
+ ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, '\0'
+};
+static const char KW_UTF_16BE[] = {
+ ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_B, ASCII_E, '\0'
+};
+static const char KW_UTF_16LE[] = {
+ ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_L, ASCII_E, '\0'
+};
+
+static
+int getEncodingIndex(const char *name)
+{
+ static const char *encodingNames[] = {
+ KW_ISO_8859_1,
+ KW_US_ASCII,
+ KW_UTF_8,
+ KW_UTF_16,
+ KW_UTF_16BE,
+ KW_UTF_16LE,
+ };
+ int i;
+ if (name == 0)
+ return NO_ENC;
+ for (i = 0; i < (int)(sizeof(encodingNames)/sizeof(encodingNames[0])); i++)
+ if (streqci(name, encodingNames[i]))
+ return i;
+ return UNKNOWN_ENC;
+}
+
+/* For binary compatibility, we store the index of the encoding specified
+at initialization in the isUtf16 member. */
+
+#define INIT_ENC_INDEX(enc) ((int)(enc)->initEnc.isUtf16)
+#define SET_INIT_ENC_INDEX(enc, i) ((enc)->initEnc.isUtf16 = (char)i)
+
+/* This is what detects the encoding.
+encodingTable maps from encoding indices to encodings;
+INIT_ENC_INDEX(enc) is the index of the external (protocol) specified encoding;
+state is XML_CONTENT_STATE if we're parsing an external text entity,
+and XML_PROLOG_STATE otherwise.
+*/
+
+
+static
+int initScan(const ENCODING **encodingTable,
+ const INIT_ENCODING *enc,
+ int state,
+ const char *ptr,
+ const char *end,
+ const char **nextTokPtr)
+{
+ const ENCODING **encPtr;
+
+ if (ptr == end)
+ return XML_TOK_NONE;
+ encPtr = enc->encPtr;
+ if (ptr + 1 == end) {
+ /* only a single byte available for auto-detection */
+#ifndef XML_DTD /* FIXME */
+ /* a well-formed document entity must have more than one byte */
+ if (state != XML_CONTENT_STATE)
+ return XML_TOK_PARTIAL;
+#endif
+ /* so we're parsing an external text entity... */
+ /* if UTF-16 was externally specified, then we need at least 2 bytes */
+ switch (INIT_ENC_INDEX(enc)) {
+ case UTF_16_ENC:
+ case UTF_16LE_ENC:
+ case UTF_16BE_ENC:
+ return XML_TOK_PARTIAL;
+ }
+ switch ((unsigned char)*ptr) {
+ case 0xFE:
+ case 0xFF:
+ case 0xEF: /* possibly first byte of UTF-8 BOM */
+ if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
+ && state == XML_CONTENT_STATE)
+ break;
+ /* fall through */
+ case 0x00:
+ case 0x3C:
+ return XML_TOK_PARTIAL;
+ }
+ }
+ else {
+ switch (((unsigned char)ptr[0] << 8) | (unsigned char)ptr[1]) {
+ case 0xFEFF:
+ if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
+ && state == XML_CONTENT_STATE)
+ break;
+ *nextTokPtr = ptr + 2;
+ *encPtr = encodingTable[UTF_16BE_ENC];
+ return XML_TOK_BOM;
+ /* 00 3C is handled in the default case */
+ case 0x3C00:
+ if ((INIT_ENC_INDEX(enc) == UTF_16BE_ENC
+ || INIT_ENC_INDEX(enc) == UTF_16_ENC)
+ && state == XML_CONTENT_STATE)
+ break;
+ *encPtr = encodingTable[UTF_16LE_ENC];
+ return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
+ case 0xFFFE:
+ if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
+ && state == XML_CONTENT_STATE)
+ break;
+ *nextTokPtr = ptr + 2;
+ *encPtr = encodingTable[UTF_16LE_ENC];
+ return XML_TOK_BOM;
+ case 0xEFBB:
+ /* Maybe a UTF-8 BOM (EF BB BF) */
+ /* If there's an explicitly specified (external) encoding
+ of ISO-8859-1 or some flavour of UTF-16
+ and this is an external text entity,
+ don't look for the BOM,
+ because it might be a legal data. */
+ if (state == XML_CONTENT_STATE) {
+ int e = INIT_ENC_INDEX(enc);
+ if (e == ISO_8859_1_ENC || e == UTF_16BE_ENC || e == UTF_16LE_ENC || e == UTF_16_ENC)
+ break;
+ }
+ if (ptr + 2 == end)
+ return XML_TOK_PARTIAL;
+ if ((unsigned char)ptr[2] == 0xBF) {
+ *nextTokPtr = ptr + 3;
+ *encPtr = encodingTable[UTF_8_ENC];
+ return XML_TOK_BOM;
+ }
+ break;
+ default:
+ if (ptr[0] == '\0') {
+ /* 0 isn't a legal data character. Furthermore a document entity can only
+ start with ASCII characters. So the only way this can fail to be big-endian
+ UTF-16 if it it's an external parsed general entity that's labelled as
+ UTF-16LE. */
+ if (state == XML_CONTENT_STATE && INIT_ENC_INDEX(enc) == UTF_16LE_ENC)
+ break;
+ *encPtr = encodingTable[UTF_16BE_ENC];
+ return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
+ }
+ else if (ptr[1] == '\0') {
+ /* We could recover here in the case:
+ - parsing an external entity
+ - second byte is 0
+ - no externally specified encoding
+ - no encoding declaration
+ by assuming UTF-16LE. But we don't, because this would mean when
+ presented just with a single byte, we couldn't reliably determine
+ whether we needed further bytes. */
+ if (state == XML_CONTENT_STATE)
+ break;
+ *encPtr = encodingTable[UTF_16LE_ENC];
+ return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
+ }
+ break;
+ }
+ }
+ *encPtr = encodingTable[INIT_ENC_INDEX(enc)];
+ return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
+}
+
+
+#define NS(x) x
+#define ns(x) x
+#include "xmltok_ns.c"
+#undef NS
+#undef ns
+
+#ifdef XML_NS
+
+#define NS(x) x ## NS
+#define ns(x) x ## _ns
+
+#include "xmltok_ns.c"
+
+#undef NS
+#undef ns
+
+ENCODING *
+XmlInitUnknownEncodingNS(void *mem,
+ int *table,
+ int (*convert)(void *userData, const char *p),
+ void *userData)
+{
+ ENCODING *enc = XmlInitUnknownEncoding(mem, table, convert, userData);
+ if (enc)
+ ((struct normal_encoding *)enc)->type[ASCII_COLON] = BT_COLON;
+ return enc;
+}
+
+#endif /* XML_NS */
diff --git a/Utilities/cmexpat/xmltok.h b/Utilities/cmexpat/xmltok.h
new file mode 100644
index 000000000..cdf49b2cb
--- /dev/null
+++ b/Utilities/cmexpat/xmltok.h
@@ -0,0 +1,299 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file COPYING for copying permission.
+*/
+
+#ifndef XmlTok_INCLUDED
+#define XmlTok_INCLUDED 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* The following token may be returned by XmlContentTok */
+#define XML_TOK_TRAILING_RSQB -5 /* ] or ]] at the end of the scan; might be start of
+ illegal ]]> sequence */
+/* The following tokens may be returned by both XmlPrologTok and XmlContentTok */
+#define XML_TOK_NONE -4 /* The string to be scanned is empty */
+#define XML_TOK_TRAILING_CR -3 /* A CR at the end of the scan;
+ might be part of CRLF sequence */
+#define XML_TOK_PARTIAL_CHAR -2 /* only part of a multibyte sequence */
+#define XML_TOK_PARTIAL -1 /* only part of a token */
+#define XML_TOK_INVALID 0
+
+/* The following tokens are returned by XmlContentTok; some are also
+ returned by XmlAttributeValueTok, XmlEntityTok, XmlCdataSectionTok */
+
+#define XML_TOK_START_TAG_WITH_ATTS 1
+#define XML_TOK_START_TAG_NO_ATTS 2
+#define XML_TOK_EMPTY_ELEMENT_WITH_ATTS 3 /* empty element tag <e/> */
+#define XML_TOK_EMPTY_ELEMENT_NO_ATTS 4
+#define XML_TOK_END_TAG 5
+#define XML_TOK_DATA_CHARS 6
+#define XML_TOK_DATA_NEWLINE 7
+#define XML_TOK_CDATA_SECT_OPEN 8
+#define XML_TOK_ENTITY_REF 9
+#define XML_TOK_CHAR_REF 10 /* numeric character reference */
+
+/* The following tokens may be returned by both XmlPrologTok and XmlContentTok */
+#define XML_TOK_PI 11 /* processing instruction */
+#define XML_TOK_XML_DECL 12 /* XML decl or text decl */
+#define XML_TOK_COMMENT 13
+#define XML_TOK_BOM 14 /* Byte order mark */
+
+/* The following tokens are returned only by XmlPrologTok */
+#define XML_TOK_PROLOG_S 15
+#define XML_TOK_DECL_OPEN 16 /* <!foo */
+#define XML_TOK_DECL_CLOSE 17 /* > */
+#define XML_TOK_NAME 18
+#define XML_TOK_NMTOKEN 19
+#define XML_TOK_POUND_NAME 20 /* #name */
+#define XML_TOK_OR 21 /* | */
+#define XML_TOK_PERCENT 22
+#define XML_TOK_OPEN_PAREN 23
+#define XML_TOK_CLOSE_PAREN 24
+#define XML_TOK_OPEN_BRACKET 25
+#define XML_TOK_CLOSE_BRACKET 26
+#define XML_TOK_LITERAL 27
+#define XML_TOK_PARAM_ENTITY_REF 28
+#define XML_TOK_INSTANCE_START 29
+
+/* The following occur only in element type declarations */
+#define XML_TOK_NAME_QUESTION 30 /* name? */
+#define XML_TOK_NAME_ASTERISK 31 /* name* */
+#define XML_TOK_NAME_PLUS 32 /* name+ */
+#define XML_TOK_COND_SECT_OPEN 33 /* <![ */
+#define XML_TOK_COND_SECT_CLOSE 34 /* ]]> */
+#define XML_TOK_CLOSE_PAREN_QUESTION 35 /* )? */
+#define XML_TOK_CLOSE_PAREN_ASTERISK 36 /* )* */
+#define XML_TOK_CLOSE_PAREN_PLUS 37 /* )+ */
+#define XML_TOK_COMMA 38
+
+/* The following token is returned only by XmlAttributeValueTok */
+#define XML_TOK_ATTRIBUTE_VALUE_S 39
+
+/* The following token is returned only by XmlCdataSectionTok */
+#define XML_TOK_CDATA_SECT_CLOSE 40
+
+/* With namespace processing this is returned by XmlPrologTok
+ for a name with a colon. */
+#define XML_TOK_PREFIXED_NAME 41
+
+#ifdef XML_DTD
+#define XML_TOK_IGNORE_SECT 42
+#endif /* XML_DTD */
+
+#ifdef XML_DTD
+#define XML_N_STATES 4
+#else /* not XML_DTD */
+#define XML_N_STATES 3
+#endif /* not XML_DTD */
+
+#define XML_PROLOG_STATE 0
+#define XML_CONTENT_STATE 1
+#define XML_CDATA_SECTION_STATE 2
+#ifdef XML_DTD
+#define XML_IGNORE_SECTION_STATE 3
+#endif /* XML_DTD */
+
+#define XML_N_LITERAL_TYPES 2
+#define XML_ATTRIBUTE_VALUE_LITERAL 0
+#define XML_ENTITY_VALUE_LITERAL 1
+
+/* The size of the buffer passed to XmlUtf8Encode must be at least this. */
+#define XML_UTF8_ENCODE_MAX 4
+/* The size of the buffer passed to XmlUtf16Encode must be at least this. */
+#define XML_UTF16_ENCODE_MAX 2
+
+typedef struct position {
+ /* first line and first column are 0 not 1 */
+ unsigned long lineNumber;
+ unsigned long columnNumber;
+} POSITION;
+
+typedef struct {
+ const char *name;
+ const char *valuePtr;
+ const char *valueEnd;
+ char normalized;
+} ATTRIBUTE;
+
+struct encoding;
+typedef struct encoding ENCODING;
+
+struct encoding {
+ int (*scanners[XML_N_STATES])(const ENCODING *,
+ const char *,
+ const char *,
+ const char **);
+ int (*literalScanners[XML_N_LITERAL_TYPES])(const ENCODING *,
+ const char *,
+ const char *,
+ const char **);
+ int (*sameName)(const ENCODING *,
+ const char *, const char *);
+ int (*nameMatchesAscii)(const ENCODING *,
+ const char *, const char *, const char *);
+ int (*nameLength)(const ENCODING *, const char *);
+ const char *(*skipS)(const ENCODING *, const char *);
+ int (*getAtts)(const ENCODING *enc, const char *ptr,
+ int attsMax, ATTRIBUTE *atts);
+ int (*charRefNumber)(const ENCODING *enc, const char *ptr);
+ int (*predefinedEntityName)(const ENCODING *, const char *, const char *);
+ void (*updatePosition)(const ENCODING *,
+ const char *ptr,
+ const char *end,
+ POSITION *);
+ int (*isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **badPtr);
+ void (*utf8Convert)(const ENCODING *enc,
+ const char **fromP,
+ const char *fromLim,
+ char **toP,
+ const char *toLim);
+ void (*utf16Convert)(const ENCODING *enc,
+ const char **fromP,
+ const char *fromLim,
+ unsigned short **toP,
+ const unsigned short *toLim);
+ int minBytesPerChar;
+ char isUtf8;
+ char isUtf16;
+};
+
+/*
+Scan the string starting at ptr until the end of the next complete token,
+but do not scan past eptr. Return an integer giving the type of token.
+
+Return XML_TOK_NONE when ptr == eptr; nextTokPtr will not be set.
+
+Return XML_TOK_PARTIAL when the string does not contain a complete token;
+nextTokPtr will not be set.
+
+Return XML_TOK_INVALID when the string does not start a valid token; nextTokPtr
+will be set to point to the character which made the token invalid.
+
+Otherwise the string starts with a valid token; nextTokPtr will be set to point
+to the character following the end of that token.
+
+Each data character counts as a single token, but adjacent data characters
+may be returned together. Similarly for characters in the prolog outside
+literals, comments and processing instructions.
+*/
+
+
+#define XmlTok(enc, state, ptr, end, nextTokPtr) \
+ (((enc)->scanners[state])(enc, ptr, end, nextTokPtr))
+
+#define XmlPrologTok(enc, ptr, end, nextTokPtr) \
+ XmlTok(enc, XML_PROLOG_STATE, ptr, end, nextTokPtr)
+
+#define XmlContentTok(enc, ptr, end, nextTokPtr) \
+ XmlTok(enc, XML_CONTENT_STATE, ptr, end, nextTokPtr)
+
+#define XmlCdataSectionTok(enc, ptr, end, nextTokPtr) \
+ XmlTok(enc, XML_CDATA_SECTION_STATE, ptr, end, nextTokPtr)
+
+#ifdef XML_DTD
+
+#define XmlIgnoreSectionTok(enc, ptr, end, nextTokPtr) \
+ XmlTok(enc, XML_IGNORE_SECTION_STATE, ptr, end, nextTokPtr)
+
+#endif /* XML_DTD */
+
+/* This is used for performing a 2nd-level tokenization on
+the content of a literal that has already been returned by XmlTok. */
+
+#define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr) \
+ (((enc)->literalScanners[literalType])(enc, ptr, end, nextTokPtr))
+
+#define XmlAttributeValueTok(enc, ptr, end, nextTokPtr) \
+ XmlLiteralTok(enc, XML_ATTRIBUTE_VALUE_LITERAL, ptr, end, nextTokPtr)
+
+#define XmlEntityValueTok(enc, ptr, end, nextTokPtr) \
+ XmlLiteralTok(enc, XML_ENTITY_VALUE_LITERAL, ptr, end, nextTokPtr)
+
+#define XmlSameName(enc, ptr1, ptr2) (((enc)->sameName)(enc, ptr1, ptr2))
+
+#define XmlNameMatchesAscii(enc, ptr1, end1, ptr2) \
+ (((enc)->nameMatchesAscii)(enc, ptr1, end1, ptr2))
+
+#define XmlNameLength(enc, ptr) \
+ (((enc)->nameLength)(enc, ptr))
+
+#define XmlSkipS(enc, ptr) \
+ (((enc)->skipS)(enc, ptr))
+
+#define XmlGetAttributes(enc, ptr, attsMax, atts) \
+ (((enc)->getAtts)(enc, ptr, attsMax, atts))
+
+#define XmlCharRefNumber(enc, ptr) \
+ (((enc)->charRefNumber)(enc, ptr))
+
+#define XmlPredefinedEntityName(enc, ptr, end) \
+ (((enc)->predefinedEntityName)(enc, ptr, end))
+
+#define XmlUpdatePosition(enc, ptr, end, pos) \
+ (((enc)->updatePosition)(enc, ptr, end, pos))
+
+#define XmlIsPublicId(enc, ptr, end, badPtr) \
+ (((enc)->isPublicId)(enc, ptr, end, badPtr))
+
+#define XmlUtf8Convert(enc, fromP, fromLim, toP, toLim) \
+ (((enc)->utf8Convert)(enc, fromP, fromLim, toP, toLim))
+
+#define XmlUtf16Convert(enc, fromP, fromLim, toP, toLim) \
+ (((enc)->utf16Convert)(enc, fromP, fromLim, toP, toLim))
+
+typedef struct {
+ ENCODING initEnc;
+ const ENCODING **encPtr;
+} INIT_ENCODING;
+
+int XmlParseXmlDecl(int isGeneralTextEntity,
+ const ENCODING *enc,
+ const char *ptr,
+ const char *end,
+ const char **badPtr,
+ const char **versionPtr,
+ const char **versionEndPtr,
+ const char **encodingNamePtr,
+ const ENCODING **namedEncodingPtr,
+ int *standalonePtr);
+
+int XmlInitEncoding(INIT_ENCODING *, const ENCODING **, const char *name);
+const ENCODING *XmlGetUtf8InternalEncoding(void);
+const ENCODING *XmlGetUtf16InternalEncoding(void);
+int XmlUtf8Encode(int charNumber, char *buf);
+int XmlUtf16Encode(int charNumber, unsigned short *buf);
+
+int XmlSizeOfUnknownEncoding(void);
+ENCODING *
+XmlInitUnknownEncoding(void *mem,
+ int *table,
+ int (*conv)(void *userData, const char *p),
+ void *userData);
+
+int XmlParseXmlDeclNS(int isGeneralTextEntity,
+ const ENCODING *enc,
+ const char *ptr,
+ const char *end,
+ const char **badPtr,
+ const char **versionPtr,
+ const char **versionEndPtr,
+ const char **encodingNamePtr,
+ const ENCODING **namedEncodingPtr,
+ int *standalonePtr);
+int XmlInitEncodingNS(INIT_ENCODING *, const ENCODING **, const char *name);
+const ENCODING *XmlGetUtf8InternalEncodingNS(void);
+const ENCODING *XmlGetUtf16InternalEncodingNS(void);
+ENCODING *
+XmlInitUnknownEncodingNS(void *mem,
+ int *table,
+ int (*conv)(void *userData, const char *p),
+ void *userData);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* not XmlTok_INCLUDED */
diff --git a/Utilities/cmexpat/xmltok_impl.c b/Utilities/cmexpat/xmltok_impl.c
new file mode 100644
index 000000000..6e0be9551
--- /dev/null
+++ b/Utilities/cmexpat/xmltok_impl.c
@@ -0,0 +1,1775 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file COPYING for copying permission.
+*/
+
+#ifndef IS_INVALID_CHAR
+#define IS_INVALID_CHAR(enc, ptr, n) (0)
+#endif
+
+#ifndef INVALID_LEAD_CASE
+#define INVALID_LEAD_CASE(n, ptr, nextTokPtr) \
+ case BT_LEAD ## n: \
+ if (end - ptr < n) \
+ return XML_TOK_PARTIAL_CHAR; \
+ if (IS_INVALID_CHAR(enc, ptr, n)) { \
+ *(nextTokPtr) = (ptr); \
+ return XML_TOK_INVALID; \
+ } \
+ ptr += n; \
+ break;
+#endif
+
+#define INVALID_CASES(ptr, nextTokPtr) \
+ INVALID_LEAD_CASE(2, ptr, nextTokPtr) \
+ INVALID_LEAD_CASE(3, ptr, nextTokPtr) \
+ INVALID_LEAD_CASE(4, ptr, nextTokPtr) \
+ case BT_NONXML: \
+ case BT_MALFORM: \
+ case BT_TRAIL: \
+ *(nextTokPtr) = (ptr); \
+ return XML_TOK_INVALID;
+
+#define CHECK_NAME_CASE(n, enc, ptr, end, nextTokPtr) \
+ case BT_LEAD ## n: \
+ if (end - ptr < n) \
+ return XML_TOK_PARTIAL_CHAR; \
+ if (!IS_NAME_CHAR(enc, ptr, n)) { \
+ *nextTokPtr = ptr; \
+ return XML_TOK_INVALID; \
+ } \
+ ptr += n; \
+ break;
+
+#define CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) \
+ case BT_NONASCII: \
+ if (!IS_NAME_CHAR_MINBPC(enc, ptr)) { \
+ *nextTokPtr = ptr; \
+ return XML_TOK_INVALID; \
+ } \
+ case BT_NMSTRT: \
+ case BT_HEX: \
+ case BT_DIGIT: \
+ case BT_NAME: \
+ case BT_MINUS: \
+ ptr += MINBPC(enc); \
+ break; \
+ CHECK_NAME_CASE(2, enc, ptr, end, nextTokPtr) \
+ CHECK_NAME_CASE(3, enc, ptr, end, nextTokPtr) \
+ CHECK_NAME_CASE(4, enc, ptr, end, nextTokPtr)
+
+#define CHECK_NMSTRT_CASE(n, enc, ptr, end, nextTokPtr) \
+ case BT_LEAD ## n: \
+ if (end - ptr < n) \
+ return XML_TOK_PARTIAL_CHAR; \
+ if (!IS_NMSTRT_CHAR(enc, ptr, n)) { \
+ *nextTokPtr = ptr; \
+ return XML_TOK_INVALID; \
+ } \
+ ptr += n; \
+ break;
+
+#define CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) \
+ case BT_NONASCII: \
+ if (!IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { \
+ *nextTokPtr = ptr; \
+ return XML_TOK_INVALID; \
+ } \
+ case BT_NMSTRT: \
+ case BT_HEX: \
+ ptr += MINBPC(enc); \
+ break; \
+ CHECK_NMSTRT_CASE(2, enc, ptr, end, nextTokPtr) \
+ CHECK_NMSTRT_CASE(3, enc, ptr, end, nextTokPtr) \
+ CHECK_NMSTRT_CASE(4, enc, ptr, end, nextTokPtr)
+
+#ifndef PREFIX
+#define PREFIX(ident) ident
+#endif
+
+/* ptr points to character following "<!-" */
+
+static
+int PREFIX(scanComment)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr)
+{
+ if (ptr != end) {
+ if (!CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ ptr += MINBPC(enc);
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ INVALID_CASES(ptr, nextTokPtr)
+ case BT_MINUS:
+ if ((ptr += MINBPC(enc)) == end)
+ return XML_TOK_PARTIAL;
+ if (CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {
+ if ((ptr += MINBPC(enc)) == end)
+ return XML_TOK_PARTIAL;
+ if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_COMMENT;
+ }
+ break;
+ default:
+ ptr += MINBPC(enc);
+ break;
+ }
+ }
+ }
+ return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following "<!" */
+
+static
+int PREFIX(scanDecl)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr)
+{
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_MINUS:
+ return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ case BT_LSQB:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_COND_SECT_OPEN;
+ case BT_NMSTRT:
+ case BT_HEX:
+ ptr += MINBPC(enc);
+ break;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_PERCNT:
+ if (ptr + MINBPC(enc) == end)
+ return XML_TOK_PARTIAL;
+ /* don't allow <!ENTITY% foo "whatever"> */
+ switch (BYTE_TYPE(enc, ptr + MINBPC(enc))) {
+ case BT_S: case BT_CR: case BT_LF: case BT_PERCNT:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ /* fall through */
+ case BT_S: case BT_CR: case BT_LF:
+ *nextTokPtr = ptr;
+ return XML_TOK_DECL_OPEN;
+ case BT_NMSTRT:
+ case BT_HEX:
+ ptr += MINBPC(enc);
+ break;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ return XML_TOK_PARTIAL;
+}
+
+static
+int PREFIX(checkPiTarget)(const ENCODING *enc, const char *ptr, const char *end, int *tokPtr)
+{
+ int upper = 0;
+ cmExpatUnused(enc);
+ *tokPtr = XML_TOK_PI;
+ if (end - ptr != MINBPC(enc)*3)
+ return 1;
+ switch (BYTE_TO_ASCII(enc, ptr)) {
+ case ASCII_x:
+ break;
+ case ASCII_X:
+ upper = 1;
+ break;
+ default:
+ return 1;
+ }
+ ptr += MINBPC(enc);
+ switch (BYTE_TO_ASCII(enc, ptr)) {
+ case ASCII_m:
+ break;
+ case ASCII_M:
+ upper = 1;
+ break;
+ default:
+ return 1;
+ }
+ ptr += MINBPC(enc);
+ switch (BYTE_TO_ASCII(enc, ptr)) {
+ case ASCII_l:
+ break;
+ case ASCII_L:
+ upper = 1;
+ break;
+ default:
+ return 1;
+ }
+ if (upper)
+ return 0;
+ *tokPtr = XML_TOK_XML_DECL;
+ return 1;
+}
+
+/* ptr points to character following "<?" */
+
+static
+int PREFIX(scanPi)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr)
+{
+ int tok;
+ const char *target = ptr;
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+ case BT_S: case BT_CR: case BT_LF:
+ if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ ptr += MINBPC(enc);
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ INVALID_CASES(ptr, nextTokPtr)
+ case BT_QUEST:
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+ *nextTokPtr = ptr + MINBPC(enc);
+ return tok;
+ }
+ break;
+ default:
+ ptr += MINBPC(enc);
+ break;
+ }
+ }
+ return XML_TOK_PARTIAL;
+ case BT_QUEST:
+ if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+ *nextTokPtr = ptr + MINBPC(enc);
+ return tok;
+ }
+ /* fall through */
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ return XML_TOK_PARTIAL;
+}
+
+
+static
+int PREFIX(scanCdataSection)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr)
+{
+ static const char CDATA_LSQB[] = { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, ASCII_LSQB };
+ int i;
+ cmExpatUnused(enc);
+ /* CDATA[ */
+ if (end - ptr < 6 * MINBPC(enc))
+ return XML_TOK_PARTIAL;
+ for (i = 0; i < 6; i++, ptr += MINBPC(enc)) {
+ if (!CHAR_MATCHES(enc, ptr, CDATA_LSQB[i])) {
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_CDATA_SECT_OPEN;
+}
+
+static
+int PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr)
+{
+ if (ptr == end)
+ return XML_TOK_NONE;
+ if (MINBPC(enc) > 1) {
+ size_t n = end - ptr;
+ if (n & (MINBPC(enc) - 1)) {
+ n &= ~(MINBPC(enc) - 1);
+ if (n == 0)
+ return XML_TOK_PARTIAL;
+ end = ptr + n;
+ }
+ }
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_RSQB:
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB))
+ break;
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+ ptr -= MINBPC(enc);
+ break;
+ }
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_CDATA_SECT_CLOSE;
+ case BT_CR:
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ if (BYTE_TYPE(enc, ptr) == BT_LF)
+ ptr += MINBPC(enc);
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_NEWLINE;
+ case BT_LF:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_DATA_NEWLINE;
+ INVALID_CASES(ptr, nextTokPtr)
+ default:
+ ptr += MINBPC(enc);
+ break;
+ }
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+ case BT_LEAD ## n: \
+ if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \
+ *nextTokPtr = ptr; \
+ return XML_TOK_DATA_CHARS; \
+ } \
+ ptr += n; \
+ break;
+ LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+ case BT_NONXML:
+ case BT_MALFORM:
+ case BT_TRAIL:
+ case BT_CR:
+ case BT_LF:
+ case BT_RSQB:
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+ default:
+ ptr += MINBPC(enc);
+ break;
+ }
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+}
+
+/* ptr points to character following "</" */
+
+static
+int PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr)
+{
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+ case BT_S: case BT_CR: case BT_LF:
+ for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_S: case BT_CR: case BT_LF:
+ break;
+ case BT_GT:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_END_TAG;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ return XML_TOK_PARTIAL;
+#ifdef XML_NS
+ case BT_COLON:
+ /* no need to check qname syntax here, since end-tag must match exactly */
+ ptr += MINBPC(enc);
+ break;
+#endif
+ case BT_GT:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_END_TAG;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following "&#X" */
+
+static
+int PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr)
+{
+ if (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_DIGIT:
+ case BT_HEX:
+ break;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_DIGIT:
+ case BT_HEX:
+ break;
+ case BT_SEMI:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_CHAR_REF;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ }
+ return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following "&#" */
+
+static
+int PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr)
+{
+ if (ptr != end) {
+ if (CHAR_MATCHES(enc, ptr, ASCII_x))
+ return PREFIX(scanHexCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_DIGIT:
+ break;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_DIGIT:
+ break;
+ case BT_SEMI:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_CHAR_REF;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ }
+ return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following "&" */
+
+static
+int PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr)
+{
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+ case BT_NUM:
+ return PREFIX(scanCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+ case BT_SEMI:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_ENTITY_REF;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following first character of attribute name */
+
+static
+int PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr)
+{
+#ifdef XML_NS
+ int hadColon = 0;
+#endif
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+#ifdef XML_NS
+ case BT_COLON:
+ if (hadColon) {
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ hadColon = 1;
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ break;
+#endif
+ case BT_S: case BT_CR: case BT_LF:
+ for (;;) {
+ int t;
+
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ t = BYTE_TYPE(enc, ptr);
+ if (t == BT_EQUALS)
+ break;
+ switch (t) {
+ case BT_S:
+ case BT_LF:
+ case BT_CR:
+ break;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ /* fall through */
+ case BT_EQUALS:
+ {
+ int open;
+#ifdef XML_NS
+ hadColon = 0;
+#endif
+ for (;;) {
+
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ open = BYTE_TYPE(enc, ptr);
+ if (open == BT_QUOT || open == BT_APOS)
+ break;
+ switch (open) {
+ case BT_S:
+ case BT_LF:
+ case BT_CR:
+ break;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ ptr += MINBPC(enc);
+ /* in attribute value */
+ for (;;) {
+ int t;
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ t = BYTE_TYPE(enc, ptr);
+ if (t == open)
+ break;
+ switch (t) {
+ INVALID_CASES(ptr, nextTokPtr)
+ case BT_AMP:
+ {
+ int tok = PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, &ptr);
+ if (tok <= 0) {
+ if (tok == XML_TOK_INVALID)
+ *nextTokPtr = ptr;
+ return tok;
+ }
+ break;
+ }
+ case BT_LT:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ default:
+ ptr += MINBPC(enc);
+ break;
+ }
+ }
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_S:
+ case BT_CR:
+ case BT_LF:
+ break;
+ case BT_SOL:
+ goto sol;
+ case BT_GT:
+ goto gt;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ /* ptr points to closing quote */
+ for (;;) {
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+ case BT_S: case BT_CR: case BT_LF:
+ continue;
+ case BT_GT:
+ gt:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_START_TAG_WITH_ATTS;
+ case BT_SOL:
+ sol:
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_EMPTY_ELEMENT_WITH_ATTS;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ break;
+ }
+ break;
+ }
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following "<" */
+
+static
+int PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr)
+{
+#ifdef XML_NS
+ int hadColon;
+#endif
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+ case BT_EXCL:
+ if ((ptr += MINBPC(enc)) == end)
+ return XML_TOK_PARTIAL;
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_MINUS:
+ return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ case BT_LSQB:
+ return PREFIX(scanCdataSection)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ case BT_QUEST:
+ return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ case BT_SOL:
+ return PREFIX(scanEndTag)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+#ifdef XML_NS
+ hadColon = 0;
+#endif
+ /* we have a start-tag */
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+#ifdef XML_NS
+ case BT_COLON:
+ if (hadColon) {
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ hadColon = 1;
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ break;
+#endif
+ case BT_S: case BT_CR: case BT_LF:
+ {
+ ptr += MINBPC(enc);
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+ case BT_GT:
+ goto gt;
+ case BT_SOL:
+ goto sol;
+ case BT_S: case BT_CR: case BT_LF:
+ ptr += MINBPC(enc);
+ continue;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ return PREFIX(scanAtts)(enc, ptr, end, nextTokPtr);
+ }
+ return XML_TOK_PARTIAL;
+ }
+ case BT_GT:
+ gt:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_START_TAG_NO_ATTS;
+ case BT_SOL:
+ sol:
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_EMPTY_ELEMENT_NO_ATTS;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ return XML_TOK_PARTIAL;
+}
+
+static
+int PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr)
+{
+ if (ptr == end)
+ return XML_TOK_NONE;
+ if (MINBPC(enc) > 1) {
+ size_t n = end - ptr;
+ if (n & (MINBPC(enc) - 1)) {
+ n &= ~(MINBPC(enc) - 1);
+ if (n == 0)
+ return XML_TOK_PARTIAL;
+ end = ptr + n;
+ }
+ }
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_LT:
+ return PREFIX(scanLt)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ case BT_AMP:
+ return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ case BT_CR:
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_TRAILING_CR;
+ if (BYTE_TYPE(enc, ptr) == BT_LF)
+ ptr += MINBPC(enc);
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_NEWLINE;
+ case BT_LF:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_DATA_NEWLINE;
+ case BT_RSQB:
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_TRAILING_RSQB;
+ if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB))
+ break;
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_TRAILING_RSQB;
+ if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+ ptr -= MINBPC(enc);
+ break;
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ INVALID_CASES(ptr, nextTokPtr)
+ default:
+ ptr += MINBPC(enc);
+ break;
+ }
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+ case BT_LEAD ## n: \
+ if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \
+ *nextTokPtr = ptr; \
+ return XML_TOK_DATA_CHARS; \
+ } \
+ ptr += n; \
+ break;
+ LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+ case BT_RSQB:
+ if (ptr + MINBPC(enc) != end) {
+ if (!CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_RSQB)) {
+ ptr += MINBPC(enc);
+ break;
+ }
+ if (ptr + 2*MINBPC(enc) != end) {
+ if (!CHAR_MATCHES(enc, ptr + 2*MINBPC(enc), ASCII_GT)) {
+ ptr += MINBPC(enc);
+ break;
+ }
+ *nextTokPtr = ptr + 2*MINBPC(enc);
+ return XML_TOK_INVALID;
+ }
+ }
+ /* fall through */
+ case BT_AMP:
+ case BT_LT:
+ case BT_NONXML:
+ case BT_MALFORM:
+ case BT_TRAIL:
+ case BT_CR:
+ case BT_LF:
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+ default:
+ ptr += MINBPC(enc);
+ break;
+ }
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+}
+
+/* ptr points to character following "%" */
+
+static
+int PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr)
+{
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+ case BT_S: case BT_LF: case BT_CR: case BT_PERCNT:
+ *nextTokPtr = ptr;
+ return XML_TOK_PERCENT;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+ case BT_SEMI:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_PARAM_ENTITY_REF;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ return XML_TOK_PARTIAL;
+}
+
+static
+int PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr)
+{
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+ case BT_CR: case BT_LF: case BT_S:
+ case BT_RPAR: case BT_GT: case BT_PERCNT: case BT_VERBAR:
+ *nextTokPtr = ptr;
+ return XML_TOK_POUND_NAME;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ return -XML_TOK_POUND_NAME;
+}
+
+static
+int PREFIX(scanLit)(int open, const ENCODING *enc,
+ const char *ptr, const char *end,
+ const char **nextTokPtr)
+{
+ while (ptr != end) {
+ int t = BYTE_TYPE(enc, ptr);
+ switch (t) {
+ INVALID_CASES(ptr, nextTokPtr)
+ case BT_QUOT:
+ case BT_APOS:
+ ptr += MINBPC(enc);
+ if (t != open)
+ break;
+ if (ptr == end)
+ return -XML_TOK_LITERAL;
+ *nextTokPtr = ptr;
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_S: case BT_CR: case BT_LF:
+ case BT_GT: case BT_PERCNT: case BT_LSQB:
+ return XML_TOK_LITERAL;
+ default:
+ return XML_TOK_INVALID;
+ }
+ default:
+ ptr += MINBPC(enc);
+ break;
+ }
+ }
+ return XML_TOK_PARTIAL;
+}
+
+static
+int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr)
+{
+ int tok;
+ if (ptr == end)
+ return XML_TOK_NONE;
+ if (MINBPC(enc) > 1) {
+ size_t n = end - ptr;
+ if (n & (MINBPC(enc) - 1)) {
+ n &= ~(MINBPC(enc) - 1);
+ if (n == 0)
+ return XML_TOK_PARTIAL;
+ end = ptr + n;
+ }
+ }
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_QUOT:
+ return PREFIX(scanLit)(BT_QUOT, enc, ptr + MINBPC(enc), end, nextTokPtr);
+ case BT_APOS:
+ return PREFIX(scanLit)(BT_APOS, enc, ptr + MINBPC(enc), end, nextTokPtr);
+ case BT_LT:
+ {
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_EXCL:
+ return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ case BT_QUEST:
+ return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ case BT_NMSTRT:
+ case BT_HEX:
+ case BT_NONASCII:
+ case BT_LEAD2:
+ case BT_LEAD3:
+ case BT_LEAD4:
+ *nextTokPtr = ptr - MINBPC(enc);
+ return XML_TOK_INSTANCE_START;
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ case BT_CR:
+ if (ptr + MINBPC(enc) == end)
+ return -XML_TOK_PROLOG_S;
+ /* fall through */
+ case BT_S: case BT_LF:
+ for (;;) {
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ break;
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_S: case BT_LF:
+ break;
+ case BT_CR:
+ /* don't split CR/LF pair */
+ if (ptr + MINBPC(enc) != end)
+ break;
+ /* fall through */
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_PROLOG_S;
+ }
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_PROLOG_S;
+ case BT_PERCNT:
+ return PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ case BT_COMMA:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_COMMA;
+ case BT_LSQB:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_OPEN_BRACKET;
+ case BT_RSQB:
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return -XML_TOK_CLOSE_BRACKET;
+ if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {
+ if (ptr + MINBPC(enc) == end)
+ return XML_TOK_PARTIAL;
+ if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_GT)) {
+ *nextTokPtr = ptr + 2*MINBPC(enc);
+ return XML_TOK_COND_SECT_CLOSE;
+ }
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_CLOSE_BRACKET;
+ case BT_LPAR:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_OPEN_PAREN;
+ case BT_RPAR:
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return -XML_TOK_CLOSE_PAREN;
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_AST:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_CLOSE_PAREN_ASTERISK;
+ case BT_QUEST:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_CLOSE_PAREN_QUESTION;
+ case BT_PLUS:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_CLOSE_PAREN_PLUS;
+ case BT_CR: case BT_LF: case BT_S:
+ case BT_GT: case BT_COMMA: case BT_VERBAR:
+ case BT_RPAR:
+ *nextTokPtr = ptr;
+ return XML_TOK_CLOSE_PAREN;
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ case BT_VERBAR:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_OR;
+ case BT_GT:
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_DECL_CLOSE;
+ case BT_NUM:
+ return PREFIX(scanPoundName)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+#define LEAD_CASE(n) \
+ case BT_LEAD ## n: \
+ if (end - ptr < n) \
+ return XML_TOK_PARTIAL_CHAR; \
+ if (IS_NMSTRT_CHAR(enc, ptr, n)) { \
+ ptr += n; \
+ tok = XML_TOK_NAME; \
+ break; \
+ } \
+ if (IS_NAME_CHAR(enc, ptr, n)) { \
+ ptr += n; \
+ tok = XML_TOK_NMTOKEN; \
+ break; \
+ } \
+ *nextTokPtr = ptr; \
+ return XML_TOK_INVALID;
+ LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+ case BT_NMSTRT:
+ case BT_HEX:
+ tok = XML_TOK_NAME;
+ ptr += MINBPC(enc);
+ break;
+ case BT_DIGIT:
+ case BT_NAME:
+ case BT_MINUS:
+#ifdef XML_NS
+ case BT_COLON:
+#endif
+ tok = XML_TOK_NMTOKEN;
+ ptr += MINBPC(enc);
+ break;
+ case BT_NONASCII:
+ if (IS_NMSTRT_CHAR_MINBPC(enc, ptr)) {
+ ptr += MINBPC(enc);
+ tok = XML_TOK_NAME;
+ break;
+ }
+ if (IS_NAME_CHAR_MINBPC(enc, ptr)) {
+ ptr += MINBPC(enc);
+ tok = XML_TOK_NMTOKEN;
+ break;
+ }
+ /* fall through */
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+ case BT_GT: case BT_RPAR: case BT_COMMA:
+ case BT_VERBAR: case BT_LSQB: case BT_PERCNT:
+ case BT_S: case BT_CR: case BT_LF:
+ *nextTokPtr = ptr;
+ return tok;
+#ifdef XML_NS
+ case BT_COLON:
+ ptr += MINBPC(enc);
+ switch (tok) {
+ case XML_TOK_NAME:
+ if (ptr == end)
+ return XML_TOK_PARTIAL;
+ tok = XML_TOK_PREFIXED_NAME;
+ switch (BYTE_TYPE(enc, ptr)) {
+ CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+ default:
+ tok = XML_TOK_NMTOKEN;
+ break;
+ }
+ break;
+ case XML_TOK_PREFIXED_NAME:
+ tok = XML_TOK_NMTOKEN;
+ break;
+ }
+ break;
+#endif
+ case BT_PLUS:
+ if (tok == XML_TOK_NMTOKEN) {
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_NAME_PLUS;
+ case BT_AST:
+ if (tok == XML_TOK_NMTOKEN) {
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_NAME_ASTERISK;
+ case BT_QUEST:
+ if (tok == XML_TOK_NMTOKEN) {
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_NAME_QUESTION;
+ default:
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ }
+ }
+ return -tok;
+}
+
+static
+int PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr)
+{
+ const char *start;
+ if (ptr == end)
+ return XML_TOK_NONE;
+ start = ptr;
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+ case BT_LEAD ## n: ptr += n; break;
+ LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+ case BT_AMP:
+ if (ptr == start)
+ return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+ case BT_LT:
+ /* this is for inside entity references */
+ *nextTokPtr = ptr;
+ return XML_TOK_INVALID;
+ case BT_LF:
+ if (ptr == start) {
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_DATA_NEWLINE;
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+ case BT_CR:
+ if (ptr == start) {
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_TRAILING_CR;
+ if (BYTE_TYPE(enc, ptr) == BT_LF)
+ ptr += MINBPC(enc);
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_NEWLINE;
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+ case BT_S:
+ if (ptr == start) {
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_ATTRIBUTE_VALUE_S;
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+ default:
+ ptr += MINBPC(enc);
+ break;
+ }
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+}
+
+static
+int PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr)
+{
+ const char *start;
+ if (ptr == end)
+ return XML_TOK_NONE;
+ start = ptr;
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+ case BT_LEAD ## n: ptr += n; break;
+ LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+ case BT_AMP:
+ if (ptr == start)
+ return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+ case BT_PERCNT:
+ if (ptr == start) {
+ int tok = PREFIX(scanPercent)(enc, ptr + MINBPC(enc),
+ end, nextTokPtr);
+ return (tok == XML_TOK_PERCENT) ? XML_TOK_INVALID : tok;
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+ case BT_LF:
+ if (ptr == start) {
+ *nextTokPtr = ptr + MINBPC(enc);
+ return XML_TOK_DATA_NEWLINE;
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+ case BT_CR:
+ if (ptr == start) {
+ ptr += MINBPC(enc);
+ if (ptr == end)
+ return XML_TOK_TRAILING_CR;
+ if (BYTE_TYPE(enc, ptr) == BT_LF)
+ ptr += MINBPC(enc);
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_NEWLINE;
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+ default:
+ ptr += MINBPC(enc);
+ break;
+ }
+ }
+ *nextTokPtr = ptr;
+ return XML_TOK_DATA_CHARS;
+}
+
+#ifdef XML_DTD
+
+static
+int PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr)
+{
+ int level = 0;
+ if (MINBPC(enc) > 1) {
+ size_t n = end - ptr;
+ if (n & (MINBPC(enc) - 1)) {
+ n &= ~(MINBPC(enc) - 1);
+ end = ptr + n;
+ }
+ }
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ INVALID_CASES(ptr, nextTokPtr)
+ case BT_LT:
+ if ((ptr += MINBPC(enc)) == end)
+ return XML_TOK_PARTIAL;
+ if (CHAR_MATCHES(enc, ptr, ASCII_EXCL)) {
+ if ((ptr += MINBPC(enc)) == end)
+ return XML_TOK_PARTIAL;
+ if (CHAR_MATCHES(enc, ptr, ASCII_LSQB)) {
+ ++level;
+ ptr += MINBPC(enc);
+ }
+ }
+ break;
+ case BT_RSQB:
+ if ((ptr += MINBPC(enc)) == end)
+ return XML_TOK_PARTIAL;
+ if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {
+ if ((ptr += MINBPC(enc)) == end)
+ return XML_TOK_PARTIAL;
+ if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+ ptr += MINBPC(enc);
+ if (level == 0) {
+ *nextTokPtr = ptr;
+ return XML_TOK_IGNORE_SECT;
+ }
+ --level;
+ }
+ }
+ break;
+ default:
+ ptr += MINBPC(enc);
+ break;
+ }
+ }
+ return XML_TOK_PARTIAL;
+}
+
+#endif /* XML_DTD */
+
+static
+int PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **badPtr)
+{
+ ptr += MINBPC(enc);
+ end -= MINBPC(enc);
+ for (; ptr != end; ptr += MINBPC(enc)) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_DIGIT:
+ case BT_HEX:
+ case BT_MINUS:
+ case BT_APOS:
+ case BT_LPAR:
+ case BT_RPAR:
+ case BT_PLUS:
+ case BT_COMMA:
+ case BT_SOL:
+ case BT_EQUALS:
+ case BT_QUEST:
+ case BT_CR:
+ case BT_LF:
+ case BT_SEMI:
+ case BT_EXCL:
+ case BT_AST:
+ case BT_PERCNT:
+ case BT_NUM:
+#ifdef XML_NS
+ case BT_COLON:
+#endif
+ break;
+ case BT_S:
+ if (CHAR_MATCHES(enc, ptr, ASCII_TAB)) {
+ *badPtr = ptr;
+ return 0;
+ }
+ break;
+ case BT_NAME:
+ case BT_NMSTRT:
+ if (!(BYTE_TO_ASCII(enc, ptr) & ~0x7f))
+ break;
+ default:
+ switch (BYTE_TO_ASCII(enc, ptr)) {
+ case 0x24: /* $ */
+ case 0x40: /* @ */
+ break;
+ default:
+ *badPtr = ptr;
+ return 0;
+ }
+ break;
+ }
+ }
+ return 1;
+}
+
+/* This must only be called for a well-formed start-tag or empty element tag.
+Returns the number of attributes. Pointers to the first attsMax attributes
+are stored in atts. */
+
+static
+int PREFIX(getAtts)(const ENCODING *enc, const char *ptr,
+ int attsMax, ATTRIBUTE *atts)
+{
+ enum { other, inName, inValue } state = inName;
+ int nAtts = 0;
+ int open = 0; /* defined when state == inValue;
+ initialization just to shut up compilers */
+
+ for (ptr += MINBPC(enc);; ptr += MINBPC(enc)) {
+ switch (BYTE_TYPE(enc, ptr)) {
+#define START_NAME \
+ if (state == other) { \
+ if (nAtts < attsMax) { \
+ atts[nAtts].name = ptr; \
+ atts[nAtts].normalized = 1; \
+ } \
+ state = inName; \
+ }
+#define LEAD_CASE(n) \
+ case BT_LEAD ## n: START_NAME ptr += (n - MINBPC(enc)); break;
+ LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+ case BT_NONASCII:
+ case BT_NMSTRT:
+ case BT_HEX:
+ START_NAME
+ break;
+#undef START_NAME
+ case BT_QUOT:
+ if (state != inValue) {
+ if (nAtts < attsMax)
+ atts[nAtts].valuePtr = ptr + MINBPC(enc);
+ state = inValue;
+ open = BT_QUOT;
+ }
+ else if (open == BT_QUOT) {
+ state = other;
+ if (nAtts < attsMax)
+ atts[nAtts].valueEnd = ptr;
+ nAtts++;
+ }
+ break;
+ case BT_APOS:
+ if (state != inValue) {
+ if (nAtts < attsMax)
+ atts[nAtts].valuePtr = ptr + MINBPC(enc);
+ state = inValue;
+ open = BT_APOS;
+ }
+ else if (open == BT_APOS) {
+ state = other;
+ if (nAtts < attsMax)
+ atts[nAtts].valueEnd = ptr;
+ nAtts++;
+ }
+ break;
+ case BT_AMP:
+ if (nAtts < attsMax)
+ atts[nAtts].normalized = 0;
+ break;
+ case BT_S:
+ if (state == inName)
+ state = other;
+ else if (state == inValue
+ && nAtts < attsMax
+ && atts[nAtts].normalized
+ && (ptr == atts[nAtts].valuePtr
+ || BYTE_TO_ASCII(enc, ptr) != ASCII_SPACE
+ || BYTE_TO_ASCII(enc, ptr + MINBPC(enc)) == ASCII_SPACE
+ || BYTE_TYPE(enc, ptr + MINBPC(enc)) == open))
+ atts[nAtts].normalized = 0;
+ break;
+ case BT_CR: case BT_LF:
+ /* This case ensures that the first attribute name is counted
+ Apart from that we could just change state on the quote. */
+ if (state == inName)
+ state = other;
+ else if (state == inValue && nAtts < attsMax)
+ atts[nAtts].normalized = 0;
+ break;
+ case BT_GT:
+ case BT_SOL:
+ if (state != inValue)
+ return nAtts;
+ break;
+ default:
+ break;
+ }
+ }
+ /* not reached */
+}
+
+static
+int PREFIX(charRefNumber)(const ENCODING *enc, const char *ptr)
+{
+ int result = 0;
+ cmExpatUnused(enc);
+ /* skip &# */
+ ptr += 2*MINBPC(enc);
+ if (CHAR_MATCHES(enc, ptr, ASCII_x)) {
+ for (ptr += MINBPC(enc); !CHAR_MATCHES(enc, ptr, ASCII_SEMI); ptr += MINBPC(enc)) {
+ int c = BYTE_TO_ASCII(enc, ptr);
+ switch (c) {
+ case ASCII_0: case ASCII_1: case ASCII_2: case ASCII_3: case ASCII_4:
+ case ASCII_5: case ASCII_6: case ASCII_7: case ASCII_8: case ASCII_9:
+ result <<= 4;
+ result |= (c - ASCII_0);
+ break;
+ case ASCII_A: case ASCII_B: case ASCII_C: case ASCII_D: case ASCII_E: case ASCII_F:
+ result <<= 4;
+ result += 10 + (c - ASCII_A);
+ break;
+ case ASCII_a: case ASCII_b: case ASCII_c: case ASCII_d: case ASCII_e: case ASCII_f:
+ result <<= 4;
+ result += 10 + (c - ASCII_a);
+ break;
+ }
+ if (result >= 0x110000)
+ return -1;
+ }
+ }
+ else {
+ for (; !CHAR_MATCHES(enc, ptr, ASCII_SEMI); ptr += MINBPC(enc)) {
+ int c = BYTE_TO_ASCII(enc, ptr);
+ result *= 10;
+ result += (c - ASCII_0);
+ if (result >= 0x110000)
+ return -1;
+ }
+ }
+ return checkCharRefNumber(result);
+}
+
+static
+int PREFIX(predefinedEntityName)(const ENCODING *enc, const char *ptr, const char *end)
+{
+ cmExpatUnused(enc);
+ switch ((end - ptr)/MINBPC(enc)) {
+ case 2:
+ if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_t)) {
+ switch (BYTE_TO_ASCII(enc, ptr)) {
+ case ASCII_l:
+ return ASCII_LT;
+ case ASCII_g:
+ return ASCII_GT;
+ }
+ }
+ break;
+ case 3:
+ if (CHAR_MATCHES(enc, ptr, ASCII_a)) {
+ ptr += MINBPC(enc);
+ if (CHAR_MATCHES(enc, ptr, ASCII_m)) {
+ ptr += MINBPC(enc);
+ if (CHAR_MATCHES(enc, ptr, ASCII_p))
+ return ASCII_AMP;
+ }
+ }
+ break;
+ case 4:
+ switch (BYTE_TO_ASCII(enc, ptr)) {
+ case ASCII_q:
+ ptr += MINBPC(enc);
+ if (CHAR_MATCHES(enc, ptr, ASCII_u)) {
+ ptr += MINBPC(enc);
+ if (CHAR_MATCHES(enc, ptr, ASCII_o)) {
+ ptr += MINBPC(enc);
+ if (CHAR_MATCHES(enc, ptr, ASCII_t))
+ return ASCII_QUOT;
+ }
+ }
+ break;
+ case ASCII_a:
+ ptr += MINBPC(enc);
+ if (CHAR_MATCHES(enc, ptr, ASCII_p)) {
+ ptr += MINBPC(enc);
+ if (CHAR_MATCHES(enc, ptr, ASCII_o)) {
+ ptr += MINBPC(enc);
+ if (CHAR_MATCHES(enc, ptr, ASCII_s))
+ return ASCII_APOS;
+ }
+ }
+ break;
+ }
+ }
+ return 0;
+}
+
+static
+int PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2)
+{
+ for (;;) {
+ switch (BYTE_TYPE(enc, ptr1)) {
+#define LEAD_CASE(n) \
+ case BT_LEAD ## n: \
+ if (*ptr1++ != *ptr2++) \
+ return 0;
+ LEAD_CASE(4) LEAD_CASE(3) LEAD_CASE(2)
+#undef LEAD_CASE
+ /* fall through */
+ if (*ptr1++ != *ptr2++)
+ return 0;
+ break;
+ case BT_NONASCII:
+ case BT_NMSTRT:
+#ifdef XML_NS
+ case BT_COLON:
+#endif
+ case BT_HEX:
+ case BT_DIGIT:
+ case BT_NAME:
+ case BT_MINUS:
+ if (*ptr2++ != *ptr1++)
+ return 0;
+ if (MINBPC(enc) > 1) {
+ if (*ptr2++ != *ptr1++)
+ return 0;
+ if (MINBPC(enc) > 2) {
+ if (*ptr2++ != *ptr1++)
+ return 0;
+ if (MINBPC(enc) > 3) {
+ if (*ptr2++ != *ptr1++)
+ return 0;
+ }
+ }
+ }
+ break;
+ default:
+ if (MINBPC(enc) == 1 && *ptr1 == *ptr2)
+ return 1;
+ switch (BYTE_TYPE(enc, ptr2)) {
+ case BT_LEAD2:
+ case BT_LEAD3:
+ case BT_LEAD4:
+ case BT_NONASCII:
+ case BT_NMSTRT:
+#ifdef XML_NS
+ case BT_COLON:
+#endif
+ case BT_HEX:
+ case BT_DIGIT:
+ case BT_NAME:
+ case BT_MINUS:
+ return 0;
+ default:
+ return 1;
+ }
+ }
+ }
+ /* not reached */
+}
+
+static
+int PREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1,
+ const char *end1, const char *ptr2)
+{
+ cmExpatUnused(enc);
+ for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) {
+ if (ptr1 == end1)
+ return 0;
+ if (!CHAR_MATCHES(enc, ptr1, *ptr2))
+ return 0;
+ }
+ return ptr1 == end1;
+}
+
+static
+int PREFIX(nameLength)(const ENCODING *enc, const char *ptr)
+{
+ const char *start = ptr;
+ for (;;) {
+ switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+ case BT_LEAD ## n: ptr += n; break;
+ LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+ case BT_NONASCII:
+ case BT_NMSTRT:
+#ifdef XML_NS
+ case BT_COLON:
+#endif
+ case BT_HEX:
+ case BT_DIGIT:
+ case BT_NAME:
+ case BT_MINUS:
+ ptr += MINBPC(enc);
+ break;
+ default:
+ return ptr - start;
+ }
+ }
+}
+
+static
+const char *PREFIX(skipS)(const ENCODING *enc, const char *ptr)
+{
+ for (;;) {
+ switch (BYTE_TYPE(enc, ptr)) {
+ case BT_LF:
+ case BT_CR:
+ case BT_S:
+ ptr += MINBPC(enc);
+ break;
+ default:
+ return ptr;
+ }
+ }
+}
+
+static
+void PREFIX(updatePosition)(const ENCODING *enc,
+ const char *ptr,
+ const char *end,
+ POSITION *pos)
+{
+ while (ptr != end) {
+ switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+ case BT_LEAD ## n: \
+ ptr += n; \
+ break;
+ LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+ case BT_LF:
+ pos->columnNumber = (unsigned)-1;
+ pos->lineNumber++;
+ ptr += MINBPC(enc);
+ break;
+ case BT_CR:
+ pos->lineNumber++;
+ ptr += MINBPC(enc);
+ if (ptr != end && BYTE_TYPE(enc, ptr) == BT_LF)
+ ptr += MINBPC(enc);
+ pos->columnNumber = (unsigned)-1;
+ break;
+ default:
+ ptr += MINBPC(enc);
+ break;
+ }
+ pos->columnNumber++;
+ }
+}
+
+#undef DO_LEAD_CASE
+#undef MULTIBYTE_CASES
+#undef INVALID_CASES
+#undef CHECK_NAME_CASE
+#undef CHECK_NAME_CASES
+#undef CHECK_NMSTRT_CASE
+#undef CHECK_NMSTRT_CASES
diff --git a/Utilities/cmexpat/xmltok_impl.h b/Utilities/cmexpat/xmltok_impl.h
new file mode 100644
index 000000000..da0ea60a6
--- /dev/null
+++ b/Utilities/cmexpat/xmltok_impl.h
@@ -0,0 +1,46 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file COPYING for copying permission.
+*/
+
+enum {
+ BT_NONXML,
+ BT_MALFORM,
+ BT_LT,
+ BT_AMP,
+ BT_RSQB,
+ BT_LEAD2,
+ BT_LEAD3,
+ BT_LEAD4,
+ BT_TRAIL,
+ BT_CR,
+ BT_LF,
+ BT_GT,
+ BT_QUOT,
+ BT_APOS,
+ BT_EQUALS,
+ BT_QUEST,
+ BT_EXCL,
+ BT_SOL,
+ BT_SEMI,
+ BT_NUM,
+ BT_LSQB,
+ BT_S,
+ BT_NMSTRT,
+ BT_COLON,
+ BT_HEX,
+ BT_DIGIT,
+ BT_NAME,
+ BT_MINUS,
+ BT_OTHER, /* known not to be a name or name start character */
+ BT_NONASCII, /* might be a name or name start character */
+ BT_PERCNT,
+ BT_LPAR,
+ BT_RPAR,
+ BT_AST,
+ BT_PLUS,
+ BT_COMMA,
+ BT_VERBAR
+};
+
+#include <stddef.h>
diff --git a/Utilities/cmexpat/xmltok_ns.c b/Utilities/cmexpat/xmltok_ns.c
new file mode 100644
index 000000000..fa78adffc
--- /dev/null
+++ b/Utilities/cmexpat/xmltok_ns.c
@@ -0,0 +1,98 @@
+const ENCODING *NS(XmlGetUtf8InternalEncoding)(void)
+{
+ return &ns(internal_utf8_encoding).enc;
+}
+
+const ENCODING *NS(XmlGetUtf16InternalEncoding)(void)
+{
+#if XML_BYTE_ORDER == 12
+ return &ns(internal_little2_encoding).enc;
+#elif XML_BYTE_ORDER == 21
+ return &ns(internal_big2_encoding).enc;
+#else
+ const short n = 1;
+ return *(const char *)&n ? &ns(internal_little2_encoding).enc : &ns(internal_big2_encoding).enc;
+#endif
+}
+
+static
+const ENCODING *NS(encodings)[] = {
+ &ns(latin1_encoding).enc,
+ &ns(ascii_encoding).enc,
+ &ns(utf8_encoding).enc,
+ &ns(big2_encoding).enc,
+ &ns(big2_encoding).enc,
+ &ns(little2_encoding).enc,
+ &ns(utf8_encoding).enc /* NO_ENC */
+};
+
+static
+int NS(initScanProlog)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr)
+{
+ return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_PROLOG_STATE, ptr, end, nextTokPtr);
+}
+
+static
+int NS(initScanContent)(const ENCODING *enc, const char *ptr, const char *end,
+ const char **nextTokPtr)
+{
+ return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_CONTENT_STATE, ptr, end, nextTokPtr);
+}
+
+int NS(XmlInitEncoding)(INIT_ENCODING *p, const ENCODING **encPtr, const char *name)
+{
+ int i = getEncodingIndex(name);
+ if (i == UNKNOWN_ENC)
+ return 0;
+ SET_INIT_ENC_INDEX(p, i);
+ p->initEnc.scanners[XML_PROLOG_STATE] = NS(initScanProlog);
+ p->initEnc.scanners[XML_CONTENT_STATE] = NS(initScanContent);
+ p->initEnc.updatePosition = initUpdatePosition;
+ p->encPtr = encPtr;
+ *encPtr = &(p->initEnc);
+ return 1;
+}
+
+static
+const ENCODING *NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end)
+{
+#define ENCODING_MAX 128
+ char buf[ENCODING_MAX];
+ char *p = buf;
+ int i;
+ XmlUtf8Convert(enc, &ptr, end, &p, p + ENCODING_MAX - 1);
+ if (ptr != end)
+ return 0;
+ *p = 0;
+ if (streqci(buf, KW_UTF_16) && enc->minBytesPerChar == 2)
+ return enc;
+ i = getEncodingIndex(buf);
+ if (i == UNKNOWN_ENC)
+ return 0;
+ return NS(encodings)[i];
+}
+
+int NS(XmlParseXmlDecl)(int isGeneralTextEntity,
+ const ENCODING *enc,
+ const char *ptr,
+ const char *end,
+ const char **badPtr,
+ const char **versionPtr,
+ const char **versionEndPtr,
+ const char **encodingName,
+ const ENCODING **encoding,
+ int *standalone)
+{
+ return doParseXmlDecl(NS(findEncoding),
+ isGeneralTextEntity,
+ enc,
+ ptr,
+ end,
+ badPtr,
+ versionPtr,
+ versionEndPtr,
+ encodingName,
+ encoding,
+ standalone);
+}
diff --git a/Utilities/cmlibarchive/.gitattributes b/Utilities/cmlibarchive/.gitattributes
new file mode 100644
index 000000000..be7062b6e
--- /dev/null
+++ b/Utilities/cmlibarchive/.gitattributes
@@ -0,0 +1,2 @@
+*.h whitespace=indent-with-non-tab,-blank-at-eol
+*.c whitespace=indent-with-non-tab,-blank-at-eol
diff --git a/Utilities/cmlibarchive/CMakeLists.txt b/Utilities/cmlibarchive/CMakeLists.txt
new file mode 100644
index 000000000..ebf28ae92
--- /dev/null
+++ b/Utilities/cmlibarchive/CMakeLists.txt
@@ -0,0 +1,1114 @@
+#
+#
+PROJECT(libarchive C)
+#
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
+SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/build/cmake")
+if(NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY)
+ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${libarchive_BINARY_DIR}/bin)
+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)
+
+#
+# Version - read from 'version' file.
+#
+FILE(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/build/version _version)
+STRING(REGEX REPLACE
+ "^([0-9])[0-9][0-9][0-9][0-9][0-9][0-9][a-z]?$" "\\1" _major ${_version})
+STRING(REGEX REPLACE
+ "^[0-9]([0-9][0-9][0-9])[0-9][0-9][0-9][a-z]?$" "\\1" _minor ${_version})
+STRING(REGEX REPLACE
+ "^[0-9][0-9][0-9][0-9]([0-9][0-9][0-9])[a-z]?$" "\\1" _revision ${_version})
+STRING(REGEX REPLACE
+ "^[0-9][0-9][0-9][0-9][0-9][0-9][0-9]([a-z]?)$" "\\1" _quality ${_version})
+SET(_version_number ${_major}${_minor}${_revision})
+STRING(REGEX REPLACE "[0]*([^0]*[0-9])$" "\\1" _trimmed_minor ${_minor})
+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(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.8 == interface version 10 = 2 + 8
+# libarchive 2.9 == interface version 11 = 2 + 9
+# libarchive 3.0 == interface version 12
+# libarchive 3.x == interface version 12 + x
+math(EXPR INTERFACE_VERSION "12 + ${_minor}")
+
+# Set SOVERSION == Interface version
+# ?? Should there be more here ??
+SET(SOVERSION "${INTERFACE_VERSION}")
+
+# Disable warnings to avoid changing 3rd party code.
+IF("${CMAKE_C_COMPILER_ID}" MATCHES
+ "^(GNU|Clang|XL|VisualAge|SunPro|MIPSpro|HP|Intel)$")
+ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w")
+ELSEIF("${CMAKE_C_COMPILER_ID}" MATCHES "^(PathScale)$")
+ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -woffall")
+ELSEIF(BORLAND)
+ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w-")
+ENDIF()
+
+# Enable CTest/CDash support
+include(CTest)
+
+OPTION(ENABLE_NETTLE "Enable use of Nettle" ON)
+OPTION(ENABLE_OPENSSL "Enable use of OpenSSL" ON)
+OPTION(ENABLE_XATTR "Enable extended attribute support" ON)
+OPTION(ENABLE_ACL "Enable ACL support" ON)
+OPTION(ENABLE_ICONV "Enable iconv support" ON)
+
+IF(WIN32)
+ IF(MSVC60)
+ SET(WINVER 0x0400)
+ ELSE()
+ SET(WINVER 0x0500)
+ ENDIF()
+ SET(_WIN32_WINNT ${WINVER})
+ENDIF(WIN32)
+
+IF("${CMAKE_C_PLATFORM_ID}" MATCHES "^(HP-UX)$")
+ ADD_DEFINITIONS(-D_XOPEN_SOURCE=500) # Ask wchar.h for mbstate_t
+ENDIF()
+
+#
+INCLUDE(CheckCSourceCompiles)
+INCLUDE(CheckCSourceRuns)
+INCLUDE(CheckFileOffsetBits)
+INCLUDE(CheckFuncs)
+INCLUDE(CheckHeaderDirent)
+INCLUDE(CheckIncludeFile)
+INCLUDE(CheckIncludeFiles)
+INCLUDE(CheckLibraryExists)
+INCLUDE(CheckStructMember)
+INCLUDE(CheckSymbolExists)
+INCLUDE(CheckTypeExists)
+INCLUDE(CheckTypeSize)
+
+#
+# Generate list.h
+#
+MACRO (GENERATE_LIST_H _listfile _cmlist __list_sources)
+ SET(_argv ${ARGV})
+ # Remove _listfile and _cmlist from _argv
+ LIST(REMOVE_AT _argv 0 1)
+ IF (NOT EXISTS "${_listfile}" OR
+ ${_cmlist} IS_NEWER_THAN "${_listfile}")
+
+ MESSAGE(STATUS "Generating ${_listfile}")
+ FILE(WRITE ${_listfile} "")
+ FOREACH (testfile ${_argv})
+ IF (testfile MATCHES "^test_[^/]+[.]c$")
+ FILE(STRINGS ${testfile} testvar REGEX "^DEFINE_TEST")
+ FOREACH (deftest ${testvar})
+ FILE(APPEND ${_listfile} "${deftest}\n")
+ ENDFOREACH (deftest)
+ ENDIF (testfile MATCHES "^test_[^/]+[.]c$")
+ ENDFOREACH (testfile)
+
+ ENDIF (NOT EXISTS "${_listfile}" OR
+ ${_cmlist} IS_NEWER_THAN "${_listfile}")
+ENDMACRO (GENERATE_LIST_H)
+#
+# Generate installation rules for man pages.
+#
+MACRO (INSTALL_MAN __mans)
+ FOREACH (_man ${ARGV})
+ STRING(REGEX REPLACE "^.+[.]([1-9])" "\\1" _mansect ${_man})
+ INSTALL(FILES ${_man} DESTINATION "share/man/man${_mansect}")
+ ENDFOREACH (_man)
+ENDMACRO (INSTALL_MAN __mans)
+
+#
+# Check compress/decompress libraries
+#
+IF(WIN32 AND NOT CMAKE_CL_64 AND NOT CYGWIN)
+ # GnuWin32 is only for Win32, not Win64.
+ SET(__GNUWIN32PATH "C:/Program Files/GnuWin32")
+ENDIF(WIN32 AND NOT CMAKE_CL_64 AND NOT CYGWIN)
+IF(DEFINED __GNUWIN32PATH AND EXISTS "${__GNUWIN32PATH}")
+ # You have to add a path availabel DLL file into PATH environment variable.
+ # Maybe DLL path is "C:/Program Files/GnuWin32/bin".
+ # The zlib and the bzip2 Setup program have installed programs and DLLs into
+ # "C:/Program Files/GnuWin32" by default.
+ # This is convenience setting for Windows.
+ SET(CMAKE_PREFIX_PATH ${__GNUWIN32PATH} $(CMAKE_PREFIX_PATH))
+ #
+ # If you didn't use Setup program or installed into nonstandard path,
+ # cmake cannot find out your zlib or bzip2 libraries and include files,
+ # you should execute cmake with -DCMAKE_PREFIX_PATH option.
+ # e.g.
+ # cmake -DCMAKE_PREFIX_PATH=<your-GnuWin32-path> <path-to-source>
+ #
+ # If compiling error occured in zconf.h, You may need patch to zconf.h.
+ #--- 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 */
+ #+# include <stdio.h> /* for SEEK_* and off_t */
+ # # ifdef VMS
+ # # include <unixio.h> /* for off_t */
+ # # endif
+ENDIF(DEFINED __GNUWIN32PATH AND EXISTS "${__GNUWIN32PATH}")
+
+SET(ADDITIONAL_LIBS "")
+#
+# Find ZLIB
+#
+FIND_PACKAGE(ZLIB)
+IF(ZLIB_FOUND)
+ SET(HAVE_LIBZ 1)
+ SET(HAVE_ZLIB_H 1)
+ INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR})
+ LIST(APPEND ADDITIONAL_LIBS ${ZLIB_LIBRARIES})
+ IF(WIN32 AND NOT CYGWIN)
+ SET(CMAKE_REQUIRED_INCLUDES ${ZLIB_INCLUDE_DIR})
+ SET(CMAKE_REQUIRED_LIBRARIES ${ZLIB_LIBRARIES})
+ CHECK_C_SOURCE_Runs(
+ "#ifndef ZLIB_WINAPI\n#define ZLIB_WINAPI\n#endif\n#include <zlib.h>\nint main() {uLong f = zlibCompileFlags(); return (f&(1U<<10))?0:-1; }"
+ ZLIB_WINAPI)
+ SET(CMAKE_REQUIRED_INCLUDES)
+ SET(CMAKE_REQUIRED_LIBRARIES)
+ ENDIF(WIN32 AND NOT CYGWIN)
+ELSE(ZLIB_FOUND)
+ MESSAGE(FATAL_ERROR "CMake requires zlib to be available to libarchive")
+ENDIF(ZLIB_FOUND)
+#
+# Find BZip2
+#
+FIND_PACKAGE(BZip2)
+IF(BZIP2_FOUND)
+ SET(HAVE_LIBBZ2 1)
+ SET(HAVE_BZLIB_H 1)
+ INCLUDE_DIRECTORIES(${BZIP2_INCLUDE_DIR})
+ LIST(APPEND ADDITIONAL_LIBS ${BZIP2_LIBRARIES})
+ENDIF(BZIP2_FOUND)
+MARK_AS_ADVANCED(CLEAR BZIP2_INCLUDE_DIR)
+MARK_AS_ADVANCED(CLEAR BZIP2_LIBRARY)
+
+IF(0) # CMake does not need LZMA support in libarchive
+#
+# Find LZMA
+#
+FIND_PACKAGE(LZMA)
+IF(LZMA_FOUND)
+ SET(HAVE_LIBLZMA 1)
+ SET(HAVE_LZMA_H 1)
+ INCLUDE_DIRECTORIES(${LZMA_INCLUDE_DIR})
+ LIST(APPEND ADDITIONAL_LIBS ${LZMA_LIBRARIES})
+ELSEIF(LZMADEC_FOUND)
+ SET(HAVE_LIBLZMADEC 1)
+ SET(HAVE_LZMADEC_H 1)
+ INCLUDE_DIRECTORIES(${LZMADEC_INCLUDE_DIR})
+ LIST(APPEND ADDITIONAL_LIBS ${LZMADEC_LIBRARIES})
+ENDIF(LZMA_FOUND)
+ENDIF()
+
+#
+# Check headers
+#
+CHECK_HEADER_DIRENT()
+
+SET(INCLUDES "")
+MACRO (LA_CHECK_INCLUDE_FILE header var)
+ CHECK_INCLUDE_FILES("${INCLUDES};${header}" ${var})
+ IF (${var})
+ SET(INCLUDES ${INCLUDES} ${header})
+ ENDIF (${var})
+ENDMACRO (LA_CHECK_INCLUDE_FILE)
+
+# Some FreeBSD headers assume sys/types.h was already included.
+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)
+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)
+LA_CHECK_INCLUDE_FILE("dlfcn.h" HAVE_DLFCN_H)
+LA_CHECK_INCLUDE_FILE("errno.h" HAVE_ERRNO_H)
+LA_CHECK_INCLUDE_FILE("ext2fs/ext2_fs.h" HAVE_EXT2FS_EXT2_FS_H)
+
+CHECK_C_SOURCE_COMPILES("#include <sys/ioctl.h>
+#include <ext2fs/ext2_fs.h>
+int main(void) { return EXT2_IOC_GETFLAGS; }" HAVE_WORKING_EXT2_IOC_GETFLAGS)
+
+LA_CHECK_INCLUDE_FILE("fcntl.h" HAVE_FCNTL_H)
+LA_CHECK_INCLUDE_FILE("grp.h" HAVE_GRP_H)
+LA_CHECK_INCLUDE_FILE("inttypes.h" HAVE_INTTYPES_H)
+LA_CHECK_INCLUDE_FILE("io.h" HAVE_IO_H)
+LA_CHECK_INCLUDE_FILE("langinfo.h" HAVE_LANGINFO_H)
+LA_CHECK_INCLUDE_FILE("limits.h" HAVE_LIMITS_H)
+LA_CHECK_INCLUDE_FILE("linux/types.h" HAVE_LINUX_TYPES_H)
+LA_CHECK_INCLUDE_FILE("linux/fiemap.h" HAVE_LINUX_FIEMAP_H)
+LA_CHECK_INCLUDE_FILE("linux/fs.h" HAVE_LINUX_FS_H)
+LA_CHECK_INCLUDE_FILE("linux/magic.h" HAVE_LINUX_MAGIC_H)
+LA_CHECK_INCLUDE_FILE("locale.h" HAVE_LOCALE_H)
+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("pwd.h" HAVE_PWD_H)
+LA_CHECK_INCLUDE_FILE("regex.h" HAVE_REGEX_H)
+LA_CHECK_INCLUDE_FILE("signal.h" HAVE_SIGNAL_H)
+LA_CHECK_INCLUDE_FILE("stdarg.h" HAVE_STDARG_H)
+LA_CHECK_INCLUDE_FILE("stdint.h" HAVE_STDINT_H)
+LA_CHECK_INCLUDE_FILE("stdlib.h" HAVE_STDLIB_H)
+LA_CHECK_INCLUDE_FILE("string.h" HAVE_STRING_H)
+LA_CHECK_INCLUDE_FILE("strings.h" HAVE_STRINGS_H)
+LA_CHECK_INCLUDE_FILE("sys/acl.h" HAVE_SYS_ACL_H)
+LA_CHECK_INCLUDE_FILE("sys/cdefs.h" HAVE_SYS_CDEFS_H)
+LA_CHECK_INCLUDE_FILE("sys/ioctl.h" HAVE_SYS_IOCTL_H)
+LA_CHECK_INCLUDE_FILE("sys/mkdev.h" HAVE_SYS_MKDEV_H)
+LA_CHECK_INCLUDE_FILE("sys/mount.h" HAVE_SYS_MOUNT_H)
+LA_CHECK_INCLUDE_FILE("sys/param.h" HAVE_SYS_PARAM_H)
+LA_CHECK_INCLUDE_FILE("sys/poll.h" HAVE_SYS_POLL_H)
+LA_CHECK_INCLUDE_FILE("sys/select.h" HAVE_SYS_SELECT_H)
+LA_CHECK_INCLUDE_FILE("sys/stat.h" HAVE_SYS_STAT_H)
+LA_CHECK_INCLUDE_FILE("sys/statfs.h" HAVE_SYS_STATFS_H)
+LA_CHECK_INCLUDE_FILE("sys/statvfs.h" HAVE_SYS_STATVFS_H)
+LA_CHECK_INCLUDE_FILE("sys/time.h" HAVE_SYS_TIME_H)
+LA_CHECK_INCLUDE_FILE("sys/utime.h" HAVE_SYS_UTIME_H)
+LA_CHECK_INCLUDE_FILE("sys/utsname.h" HAVE_SYS_UTSNAME_H)
+LA_CHECK_INCLUDE_FILE("sys/vfs.h" HAVE_SYS_VFS_H)
+LA_CHECK_INCLUDE_FILE("sys/wait.h" HAVE_SYS_WAIT_H)
+LA_CHECK_INCLUDE_FILE("time.h" HAVE_TIME_H)
+LA_CHECK_INCLUDE_FILE("unistd.h" HAVE_UNISTD_H)
+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)
+# 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)
+
+#
+# Check whether use of __EXTENSIONS__ is safe.
+# We need some macro such as _GNU_SOURCE to use extension functions.
+#
+SET(_INCLUDE_FILES)
+FOREACH (it ${_HEADER})
+ SET(_INCLUDE_FILES "${_INCLUDE_FILES}#include <${it}>\n")
+ENDFOREACH (it)
+
+CHECK_C_SOURCE_COMPILES(
+ "#define __EXTENSIONS__ 1
+ ${_INCLUDE_FILES}
+ int main() { return 0;}"
+ SAFE_TO_DEFINE_EXTENSIONS)
+
+#
+# Find Nettle
+#
+IF(ENABLE_NETTLE)
+ CHECK_LIBRARY_EXISTS(nettle "nettle_sha1_digest" "" NETTLE_FOUND)
+ IF(NETTLE_FOUND)
+ SET(CMAKE_REQUIRED_LIBRARIES "nettle")
+ FIND_LIBRARY(NETTLE_LIBRARY NAMES nettle)
+ LIST(APPEND ADDITIONAL_LIBS ${NETTLE_LIBRARY})
+ ELSE(NETTLE_FOUND)
+ SET(ENABLE_NETTLE OFF)
+ ENDIF(NETTLE_FOUND)
+ENDIF(ENABLE_NETTLE)
+
+#
+# Find OpenSSL
+# (Except on Mac, where OpenSSL is deprecated.)
+#
+IF(ENABLE_OPENSSL AND NOT CMAKE_SYSTEM_NAME MATCHES "Darwin")
+ FIND_PACKAGE(OpenSSL)
+ELSE()
+ SET(OPENSSL_FOUND FALSE) # Override cached value
+ENDIF()
+
+# FreeBSD libmd
+CHECK_LIBRARY_EXISTS(md "MD5Init" "" LIBMD_FOUND)
+IF(LIBMD_FOUND)
+ SET(CMAKE_REQUIRED_LIBRARIES "md")
+ FIND_LIBRARY(LIBMD_LIBRARY NAMES md)
+ LIST(APPEND ADDITIONAL_LIBS ${LIBMD_LIBRARY})
+ENDIF(LIBMD_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
+# required libraries.
+#
+MACRO(CHECK_CRYPTO ALGORITHMS IMPLEMENTATION)
+ IF(HAVE_SYS_TYPES_H)
+ SET(CRYPTO_HEADER_CONFIG "#define HAVE_SYS_TYPES_H 1\n")
+ ELSE(HAVE_SYS_TYPES_H)
+ SET(CRYPTO_HEADER_CONFIG "")
+ ENDIF(HAVE_SYS_TYPES_H)
+
+ FOREACH(ALGORITHM ${ALGORITHMS})
+ STRING(TOLOWER "${ALGORITHM}" lower_algorithm)
+ STRING(TOUPPER "${ALGORITHM}" algorithm)
+ IF ("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND NOT OPENSSL_FOUND)
+ SET(ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION} FALSE)
+ ELSEIF("${IMPLEMENTATION}" MATCHES "^NETTLE$" AND NOT NETTLE_FOUND)
+ SET(ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION} FALSE)
+ ENDIF("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND NOT OPENSSL_FOUND)
+
+ IF(NOT DEFINED ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION})
+ # Probe the local implementation for whether this
+ # crypto implementation is available on this platform.
+ SET(TRY_CRYPTO_REQUIRED_INCLUDES
+ "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_CURRENT_SOURCE_DIR}/libarchive;${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp")
+ SET(TRY_CRYPTO_REQUIRED_LIBS)
+ IF ("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND OPENSSL_FOUND)
+ SET(TRY_CRYPTO_REQUIRED_INCLUDES
+ "${TRY_CRYPTO_REQUIRED_INCLUDES};${OPENSSL_INCLUDE_DIR}")
+ SET(TRY_CRYPTO_REQUIRED_LIBS
+ "-DLINK_LIBRARIES:STRING=${OPENSSL_LIBRARIES}")
+ ELSEIF("${IMPLEMENTATION}" MATCHES "^NETTLE$" AND NETTLE_FOUND)
+ SET(TRY_CRYPTO_REQUIRED_LIBS
+ "-DLINK_LIBRARIES:STRING=${NETTLE_LIBRARY}")
+ ELSEIF("${IMPLEMENTATION}" MATCHES "^LIBMD$" AND LIBMD_FOUND)
+ SET(TRY_CRYPTO_REQUIRED_LIBS
+ "-DLINK_LIBRARIES:STRING=${LIBMD_LIBRARY}")
+ ENDIF("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND OPENSSL_FOUND)
+
+ FILE(READ "${CMAKE_CURRENT_SOURCE_DIR}/libarchive/archive_crypto.c"
+ ARCHIVE_CRYPTO_C)
+
+ SET(SOURCE "
+#define ARCHIVE_${algorithm}_COMPILE_TEST
+#define ARCHIVE_CRYPTO_${algorithm}_${IMPLEMENTATION}
+#define PLATFORM_CONFIG_H \"check_crypto_md.h\"
+
+${ARCHIVE_CRYPTO_C}
+
+int
+main(int argc, char **argv)
+{
+ archive_${lower_crypto}_ctx ctx;
+ archive_${lower_crypto}_init(&ctx);
+ archive_${lower_crypto}_update(&ctx, *argv, argc);
+ archive_${lower_crypto}_final(&ctx, NULL);
+ return 0;
+}
+")
+
+ FILE(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check_crypto_md.h" "")
+ FILE(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check_crypto_md.c" "${SOURCE}")
+ MESSAGE(STATUS "Checking support for ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION}")
+
+ TRY_COMPILE(ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION}
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check_crypto_md.c
+ CMAKE_FLAGS
+ "${TRY_CRYPTO_REQUIRED_LIBS}"
+ "${TRY_CRYPTO_REQUIRED_INCLUDES}"
+ OUTPUT_VARIABLE OUTPUT)
+
+ # Inform user whether or not we found it; if not, log why we didn't.
+ IF (ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION})
+ MESSAGE(STATUS "Checking support for ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION} -- found")
+ ELSE (ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION})
+ MESSAGE(STATUS "Checking support for ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION} -- not found")
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "Checking support for ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION} failed with the following output:\n"
+ "${OUTPUT}\n"
+ "Source file was:\n${SOURCE}\n")
+ ENDIF (ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION})
+ ENDIF(NOT DEFINED ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION})
+
+ # Add appropriate libs/includes depending on whether the implementation
+ # was found on this platform.
+ IF (ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION})
+ IF ("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND OPENSSL_FOUND)
+ INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR})
+ LIST(APPEND ADDITIONAL_LIBS ${OPENSSL_LIBRARIES})
+ LIST(REMOVE_DUPLICATES ADDITIONAL_LIBS)
+ ENDIF ("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND OPENSSL_FOUND)
+ ENDIF (ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION})
+ ENDFOREACH(ALGORITHM ${ALGORITHMS})
+ENDMACRO(CHECK_CRYPTO ALGORITHMS IMPLEMENTATION)
+
+#
+# CRYPTO functions on Windows is defined at archive_windows.c, thus we do not
+# need the test what the functions can be mapped to archive_{crypto name}_init,
+# archive_{crypto name}_update and archive_{crypto name}_final.
+# The functions on Windows use CALG_{crypto name} macro to create a crypt object
+# and then we need to know what CALG_{crypto name} macros is available to show
+# ARCHIVE_CRYPTO_{crypto name}_WIN macros because Windows 2000 and earlier version
+# of Windows XP do not support SHA256, SHA384 and SHA512.
+#
+MACRO(CHECK_CRYPTO_WIN CRYPTO_LIST)
+ IF(WIN32 AND NOT CYGWIN)
+ FOREACH(CRYPTO ${CRYPTO_LIST})
+ IF(NOT DEFINED ARCHIVE_CRYPTO_${CRYPTO}_WIN)
+ STRING(TOUPPER "${CRYPTO}" crypto)
+ SET(ALGID "")
+ IF ("${CRYPTO}" MATCHES "^MD5$")
+ SET(ALGID "CALG_MD5")
+ ENDIF ("${CRYPTO}" MATCHES "^MD5$")
+ IF ("${CRYPTO}" MATCHES "^SHA1$")
+ SET(ALGID "CALG_SHA1")
+ ENDIF ("${CRYPTO}" MATCHES "^SHA1$")
+ IF ("${CRYPTO}" MATCHES "^SHA256$")
+ SET(ALGID "CALG_SHA_256")
+ ENDIF ("${CRYPTO}" MATCHES "^SHA256$")
+ IF ("${CRYPTO}" MATCHES "^SHA384$")
+ SET(ALGID "CALG_SHA_384")
+ ENDIF ("${CRYPTO}" MATCHES "^SHA384$")
+ IF ("${CRYPTO}" MATCHES "^SHA512$")
+ SET(ALGID "CALG_SHA_512")
+ ENDIF ("${CRYPTO}" MATCHES "^SHA512$")
+
+ SET(SOURCE "#define ${crypto}_COMPILE_TEST
+#define _WIN32_WINNT ${_WIN32_WINNT}
+#define WINVER ${WINVER}
+#include <windows.h>
+#include <wincrypt.h>
+
+int
+main(int argc, char **argv)
+{
+ return ${ALGID};
+}
+")
+ SET(SOURCE_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check_crypto_win.c")
+
+ FILE(WRITE "${SOURCE_FILE}" "${SOURCE}")
+ MESSAGE(STATUS "Checking support for ARCHIVE_CRYPTO_${CRYPTO}_WIN")
+
+ TRY_COMPILE(ARCHIVE_CRYPTO_${CRYPTO}_WIN
+ ${CMAKE_BINARY_DIR}
+ ${SOURCE_FILE}
+ CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_CURRENT_SOURCE_DIR}/libarchive"
+ OUTPUT_VARIABLE OUTPUT)
+
+ IF (ARCHIVE_CRYPTO_${CRYPTO}_WIN)
+ MESSAGE(STATUS
+ "Checking support for ARCHIVE_CRYPTO_${CRYPTO}_WIN -- found")
+ ELSE (ARCHIVE_CRYPTO_${CRYPTO}_WIN)
+ MESSAGE(STATUS
+ "Checking support for ARCHIVE_CRYPTO_${CRYPTO}_WIN -- not found")
+ FILE(APPEND
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "Checking support for ARCHIVE_CRYPTO_${CRYPTO}_WIN failed with the following output:\n"
+ "${OUTPUT}\n"
+ "Source file was:\n${SOURCE}\n")
+ ENDIF (ARCHIVE_CRYPTO_${CRYPTO}_WIN)
+
+ ENDIF(NOT DEFINED ARCHIVE_CRYPTO_${CRYPTO}_WIN)
+ ENDFOREACH(CRYPTO)
+ ENDIF(WIN32 AND NOT CYGWIN)
+ENDMACRO(CHECK_CRYPTO_WIN CRYPTO_LIST)
+
+#
+# Find iconv
+# POSIX defines the second arg as const char **
+# and requires it to be in libc. But we can accept
+# a non-const argument here and can support iconv()
+# being in libiconv.
+#
+MACRO(CHECK_ICONV LIB TRY_ICONV_CONST)
+ IF(NOT HAVE_ICONV)
+ CHECK_C_SOURCE_COMPILES(
+ "#include <stdlib.h>
+ #include <iconv.h>
+ int main() {
+ ${TRY_ICONV_CONST} char *ccp;
+ iconv_t cd = iconv_open(\"\", \"\");
+ iconv(cd, &ccp, (size_t *)0, (char **)0, (size_t *)0);
+ iconv_close(cd);
+ return 0;
+ }"
+ HAVE_ICONV_${LIB}_${TRY_ICONV_CONST})
+ IF(HAVE_ICONV_${LIB}_${TRY_ICONV_CONST})
+ SET(HAVE_ICONV true)
+ SET(ICONV_CONST ${TRY_ICONV_CONST})
+ ENDIF(HAVE_ICONV_${LIB}_${TRY_ICONV_CONST})
+ ENDIF(NOT HAVE_ICONV)
+ENDMACRO(CHECK_ICONV TRY_ICONV_CONST)
+
+IF(ENABLE_ICONV)
+ FIND_PATH(ICONV_INCLUDE_DIR iconv.h)
+ MARK_AS_ADVANCED(ICONV_INCLUDE_DIR)
+ IF(ICONV_INCLUDE_DIR)
+ #SET(INCLUDES ${INCLUDES} "iconv.h")
+ SET(HAVE_ICONV_H 1)
+ INCLUDE_DIRECTORIES(${ICONV_INCLUDE_DIR})
+ SET(CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIR})
+ CHECK_ICONV("libc" "const")
+ CHECK_ICONV("libc" "")
+
+ # If iconv isn't in libc and we have a libiconv, try that.
+ FIND_LIBRARY(LIBICONV_PATH iconv)
+ IF(NOT HAVE_ICONV AND LIBICONV_PATH)
+ LIST(APPEND CMAKE_REQUIRED_LIBRARIES ${LIBICONV_PATH})
+ CHECK_ICONV("libiconv" "const")
+ CHECK_ICONV("libiconv" "")
+ IF (HAVE_ICONV)
+ LIST(APPEND ADDITIONAL_LIBS ${LIBICONV_PATH})
+ ENDIF(HAVE_ICONV)
+ ENDIF(NOT HAVE_ICONV AND LIBICONV_PATH)
+ ENDIF(ICONV_INCLUDE_DIR)
+ #
+ # Find locale_charset() for libiconv.
+ #
+ IF(LIBICONV_PATH)
+ CHECK_INCLUDE_FILES("localcharset.h" HAVE_LOCALCHARSET_H)
+ CHECK_FUNCTION_EXISTS_GLIBC(locale_charset HAVE_LOCALE_CHARSET)
+ IF(NOT HAVE_LOCALE_CHARSET)
+ FIND_LIBRARY(LIBCHARSET_PATH charset)
+ IF(LIBCHARSET_PATH)
+ SET(CMAKE_REQUIRED_LIBRARIES ${LIBCHARSET_PATH})
+ CHECK_FUNCTION_EXISTS_GLIBC(locale_charset HAVE_LOCALE_CHARSET)
+ IF(HAVE_LOCALE_CHARSET)
+ LIST(APPEND ADDITIONAL_LIBS ${LIBCHARSET_PATH})
+ ENDIF(HAVE_LOCALE_CHARSET)
+ ENDIF(LIBCHARSET_PATH)
+ ENDIF(NOT HAVE_LOCALE_CHARSET)
+ ENDIF(LIBICONV_PATH)
+ELSE(ENABLE_ICONV)
+ # Make sure ICONV variables are not in CACHE after ENABLE_ICONV disabled
+ # (once enabled).
+ UNSET(HAVE_LOCALE_CHARSET CACHE)
+ UNSET(HAVE_ICONV CACHE)
+ UNSET(HAVE_ICONV_libc_ CACHE)
+ UNSET(HAVE_ICONV_libc_const CACHE)
+ UNSET(HAVE_ICONV_libiconv_ CACHE)
+ UNSET(HAVE_ICONV_libiconv_const CACHE)
+ UNSET(ICONV_INCLUDE_DIR CACHE)
+ UNSET(LIBICONV_PATH CACHE)
+ENDIF(ENABLE_ICONV)
+
+IF(0) # CMake does not need XML support in libarchive
+#
+# Find Libxml2
+#
+FIND_PACKAGE(LibXml2)
+IF(LIBXML2_FOUND)
+ INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR})
+ LIST(APPEND ADDITIONAL_LIBS ${LIBXML2_LIBRARIES})
+ SET(HAVE_LIBXML2 1)
+ # libxml2's include files use iconv.h
+ SET(CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIR} ${LIBXML2_INCLUDE_DIR})
+ CHECK_INCLUDE_FILES("libxml/xmlreader.h" HAVE_LIBXML_XMLREADER_H)
+ CHECK_INCLUDE_FILES("libxml/xmlwriter.h" HAVE_LIBXML_XMLWRITER_H)
+ SET(CMAKE_REQUIRED_INCLUDES "")
+ELSE(LIBXML2_FOUND)
+ #
+ # Find Expat
+ #
+ FIND_PACKAGE(EXPAT)
+ IF(EXPAT_FOUND)
+ INCLUDE_DIRECTORIES(${EXPAT_INCLUDE_DIR})
+ LIST(APPEND ADDITIONAL_LIBS ${EXPAT_LIBRARIES})
+ SET(HAVE_LIBEXPAT 1)
+ LA_CHECK_INCLUDE_FILE("expat.h" HAVE_EXPAT_H)
+ ENDIF(EXPAT_FOUND)
+ENDIF(LIBXML2_FOUND)
+ENDIF()
+
+#
+# Check functions
+#
+IF ("CMAKE_C_COMPILER_ID" MATCHES "^GNU$")
+ #
+ # 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(SAVE_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
+ SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fno-builtin")
+ENDIF ("CMAKE_C_COMPILER_ID" MATCHES "^GNU$")
+CHECK_SYMBOL_EXISTS(_CrtSetReportMode "crtdbg.h" HAVE__CrtSetReportMode)
+CHECK_FUNCTION_EXISTS_GLIBC(chflags HAVE_CHFLAGS)
+CHECK_FUNCTION_EXISTS_GLIBC(chown HAVE_CHOWN)
+CHECK_FUNCTION_EXISTS_GLIBC(chroot HAVE_CHROOT)
+CHECK_FUNCTION_EXISTS_GLIBC(ctime_r HAVE_CTIME_R)
+CHECK_FUNCTION_EXISTS_GLIBC(fchdir HAVE_FCHDIR)
+CHECK_FUNCTION_EXISTS_GLIBC(fchflags HAVE_FCHFLAGS)
+CHECK_FUNCTION_EXISTS_GLIBC(fchmod HAVE_FCHMOD)
+CHECK_FUNCTION_EXISTS_GLIBC(fchown HAVE_FCHOWN)
+CHECK_FUNCTION_EXISTS_GLIBC(fcntl HAVE_FCNTL)
+CHECK_FUNCTION_EXISTS_GLIBC(fdopendir HAVE_FDOPENDIR)
+CHECK_FUNCTION_EXISTS_GLIBC(fork HAVE_FORK)
+CHECK_FUNCTION_EXISTS_GLIBC(fstat HAVE_FSTAT)
+CHECK_FUNCTION_EXISTS_GLIBC(fstatat HAVE_FSTATAT)
+CHECK_FUNCTION_EXISTS_GLIBC(fstatfs HAVE_FSTATFS)
+CHECK_FUNCTION_EXISTS_GLIBC(fstatvfs HAVE_FSTATVFS)
+CHECK_FUNCTION_EXISTS_GLIBC(ftruncate HAVE_FTRUNCATE)
+CHECK_FUNCTION_EXISTS_GLIBC(futimens HAVE_FUTIMENS)
+CHECK_FUNCTION_EXISTS_GLIBC(futimes HAVE_FUTIMES)
+CHECK_FUNCTION_EXISTS_GLIBC(futimesat HAVE_FUTIMESAT)
+CHECK_FUNCTION_EXISTS_GLIBC(geteuid HAVE_GETEUID)
+CHECK_FUNCTION_EXISTS_GLIBC(getgrgid_r HAVE_GETGRGID_R)
+CHECK_FUNCTION_EXISTS_GLIBC(getgrnam_r HAVE_GETGRNAM_R)
+CHECK_FUNCTION_EXISTS_GLIBC(getpwnam_r HAVE_GETPWNAM_R)
+CHECK_FUNCTION_EXISTS_GLIBC(getpwuid_r HAVE_GETPWUID_R)
+CHECK_FUNCTION_EXISTS_GLIBC(getpid HAVE_GETPID)
+CHECK_FUNCTION_EXISTS_GLIBC(getvfsbyname HAVE_GETVFSBYNAME)
+CHECK_FUNCTION_EXISTS_GLIBC(gmtime_r HAVE_GMTIME_R)
+CHECK_FUNCTION_EXISTS_GLIBC(lchflags HAVE_LCHFLAGS)
+CHECK_FUNCTION_EXISTS_GLIBC(lchmod HAVE_LCHMOD)
+CHECK_FUNCTION_EXISTS_GLIBC(lchown HAVE_LCHOWN)
+CHECK_FUNCTION_EXISTS_GLIBC(link HAVE_LINK)
+CHECK_FUNCTION_EXISTS_GLIBC(localtime_r HAVE_LOCALTIME_R)
+CHECK_FUNCTION_EXISTS_GLIBC(lstat HAVE_LSTAT)
+CHECK_FUNCTION_EXISTS_GLIBC(lutimes HAVE_LUTIMES)
+CHECK_FUNCTION_EXISTS_GLIBC(mbrtowc HAVE_MBRTOWC)
+CHECK_FUNCTION_EXISTS_GLIBC(mbsnrtowcs HAVE_MBSNRTOWCS)
+CHECK_FUNCTION_EXISTS_GLIBC(memmove HAVE_MEMMOVE)
+CHECK_FUNCTION_EXISTS_GLIBC(mkdir HAVE_MKDIR)
+CHECK_FUNCTION_EXISTS_GLIBC(mkfifo HAVE_MKFIFO)
+CHECK_FUNCTION_EXISTS_GLIBC(mknod HAVE_MKNOD)
+CHECK_FUNCTION_EXISTS_GLIBC(mkstemp HAVE_MKSTEMP)
+CHECK_FUNCTION_EXISTS_GLIBC(nl_langinfo HAVE_NL_LANGINFO)
+CHECK_FUNCTION_EXISTS_GLIBC(openat HAVE_OPENAT)
+CHECK_FUNCTION_EXISTS_GLIBC(pipe HAVE_PIPE)
+CHECK_FUNCTION_EXISTS_GLIBC(poll HAVE_POLL)
+CHECK_FUNCTION_EXISTS_GLIBC(readlink HAVE_READLINK)
+CHECK_FUNCTION_EXISTS_GLIBC(select HAVE_SELECT)
+CHECK_FUNCTION_EXISTS_GLIBC(setenv HAVE_SETENV)
+CHECK_FUNCTION_EXISTS_GLIBC(setlocale HAVE_SETLOCALE)
+CHECK_FUNCTION_EXISTS_GLIBC(sigaction HAVE_SIGACTION)
+CHECK_FUNCTION_EXISTS_GLIBC(statfs HAVE_STATFS)
+CHECK_FUNCTION_EXISTS_GLIBC(statvfs HAVE_STATVFS)
+CHECK_FUNCTION_EXISTS_GLIBC(strchr HAVE_STRCHR)
+CHECK_FUNCTION_EXISTS_GLIBC(strdup HAVE_STRDUP)
+CHECK_FUNCTION_EXISTS_GLIBC(strerror HAVE_STRERROR)
+CHECK_FUNCTION_EXISTS_GLIBC(strncpy_s HAVE_STRNCPY_S)
+CHECK_FUNCTION_EXISTS_GLIBC(strrchr HAVE_STRRCHR)
+CHECK_FUNCTION_EXISTS_GLIBC(symlink HAVE_SYMLINK)
+CHECK_FUNCTION_EXISTS_GLIBC(timegm HAVE_TIMEGM)
+CHECK_FUNCTION_EXISTS_GLIBC(tzset HAVE_TZSET)
+CHECK_FUNCTION_EXISTS_GLIBC(unsetenv HAVE_UNSETENV)
+CHECK_FUNCTION_EXISTS_GLIBC(utime HAVE_UTIME)
+CHECK_FUNCTION_EXISTS_GLIBC(utimes HAVE_UTIMES)
+CHECK_FUNCTION_EXISTS_GLIBC(utimensat HAVE_UTIMENSAT)
+CHECK_FUNCTION_EXISTS_GLIBC(vfork HAVE_VFORK)
+CHECK_FUNCTION_EXISTS_GLIBC(wcrtomb HAVE_WCRTOMB)
+CHECK_FUNCTION_EXISTS_GLIBC(wcscmp HAVE_WCSCMP)
+CHECK_FUNCTION_EXISTS_GLIBC(wcscpy HAVE_WCSCPY)
+CHECK_FUNCTION_EXISTS_GLIBC(wcslen HAVE_WCSLEN)
+CHECK_FUNCTION_EXISTS_GLIBC(wcsnrtombs HAVE_WCSNRTOMBS)
+CHECK_FUNCTION_EXISTS_GLIBC(wctomb HAVE_WCTOMB)
+CHECK_FUNCTION_EXISTS_GLIBC(_ctime64_s HAVE__CTIME64_S)
+CHECK_FUNCTION_EXISTS_GLIBC(_fseeki64 HAVE__FSEEKI64)
+CHECK_FUNCTION_EXISTS_GLIBC(_get_timezone HAVE__GET_TIMEZONE)
+CHECK_FUNCTION_EXISTS_GLIBC(_localtime64_s HAVE__LOCALTIME64_S)
+CHECK_FUNCTION_EXISTS_GLIBC(_mkgmtime64 HAVE__MKGMTIME64)
+
+SET(CMAKE_REQUIRED_LIBRARIES "")
+CHECK_FUNCTION_EXISTS(cygwin_conv_path HAVE_CYGWIN_CONV_PATH)
+CHECK_FUNCTION_EXISTS(fseeko HAVE_FSEEKO)
+CHECK_FUNCTION_EXISTS(strerror_r HAVE_STRERROR_R)
+CHECK_FUNCTION_EXISTS(strftime HAVE_STRFTIME)
+CHECK_FUNCTION_EXISTS(vprintf HAVE_VPRINTF)
+CHECK_FUNCTION_EXISTS(wmemcmp HAVE_WMEMCMP)
+CHECK_FUNCTION_EXISTS(wmemcpy HAVE_WMEMCPY)
+
+# Restore CMAKE_REQUIRED_FLAGS
+IF ("CMAKE_C_COMPILER_ID" MATCHES "^GNU$")
+ SET(CMAKE_REQUIRED_FLAGS ${SAVE_CMAKE_REQUIRED_FLAGS})
+ENDIF ("CMAKE_C_COMPILER_ID" MATCHES "^GNU$")
+
+# Make sure we have the POSIX version of readdir_r, not the
+# older 2-argument version.
+CHECK_C_SOURCE_COMPILES(
+ "#include <dirent.h>\nint main() {DIR *d = opendir(\".\"); struct dirent e,*r; return readdir_r(d,&e,&r);}"
+ HAVE_READDIR_R)
+
+
+# Only detect readlinkat() if we also have AT_FDCWD in unistd.h.
+# NOTE: linux requires fcntl.h for AT_FDCWD.
+CHECK_C_SOURCE_COMPILES(
+ "#include <fcntl.h>\n#include <unistd.h>\nint main() {char buf[10]; return readlinkat(AT_FDCWD, \"\", buf, 0);}"
+ HAVE_READLINKAT)
+
+
+# To verify major(), we need to both include the header
+# of interest and verify that the result can be linked.
+# CHECK_FUNCTION_EXISTS doesn't accept a header argument,
+# CHECK_SYMBOL_EXISTS doesn't test linkage.
+CHECK_C_SOURCE_COMPILES(
+ "#include <sys/mkdev.h>\nint main() { return major(256); }"
+ MAJOR_IN_MKDEV)
+CHECK_C_SOURCE_COMPILES(
+ "#include <sys/sysmacros.h>\nint main() { return major(256); }"
+ MAJOR_IN_SYSMACROS)
+
+IF(HAVE_STRERROR_R)
+ SET(HAVE_DECL_STRERROR_R 1)
+ENDIF(HAVE_STRERROR_R)
+
+#
+# Check defines
+#
+SET(headers "limits.h")
+IF(HAVE_STDINT_H)
+ LIST(APPEND headers "stdint.h")
+ENDIF(HAVE_STDINT_H)
+IF(HAVE_INTTYPES_H)
+ LIST(APPEND headers "inttypes.h")
+ENDIF(HAVE_INTTYPES_H)
+CHECK_SYMBOL_EXISTS(EFTYPE "errno.h" HAVE_EFTYPE)
+CHECK_SYMBOL_EXISTS(EILSEQ "errno.h" HAVE_EILSEQ)
+CHECK_SYMBOL_EXISTS(D_MD_ORDER "langinfo.h" HAVE_D_MD_ORDER)
+CHECK_SYMBOL_EXISTS(INT64_MAX "${headers}" HAVE_DECL_INT64_MAX)
+CHECK_SYMBOL_EXISTS(INT64_MIN "${headers}" HAVE_DECL_INT64_MIN)
+CHECK_SYMBOL_EXISTS(UINT32_MAX "${headers}" HAVE_DECL_UINT32_MAX)
+CHECK_SYMBOL_EXISTS(UINT64_MAX "${headers}" HAVE_DECL_UINT64_MAX)
+CHECK_SYMBOL_EXISTS(SIZE_MAX "${headers}" HAVE_DECL_SIZE_MAX)
+CHECK_SYMBOL_EXISTS(SSIZE_MAX "limits.h" HAVE_DECL_SSIZE_MAX)
+
+#
+# Check struct members
+#
+# Check for tm_gmtoff in struct tm
+CHECK_STRUCT_MEMBER("struct tm" tm_gmtoff
+ "time.h" HAVE_STRUCT_TM_TM_GMTOFF)
+CHECK_STRUCT_MEMBER("struct tm" __tm_gmtoff
+ "time.h" HAVE_STRUCT_TM___TM_GMTOFF)
+
+# Check for f_namemax in struct statfs
+CHECK_STRUCT_MEMBER("struct statfs" f_namemax
+ "sys/param.h;sys/mount.h" HAVE_STRUCT_STATFS_F_NAMEMAX)
+
+# Check for birthtime in struct stat
+CHECK_STRUCT_MEMBER("struct stat" st_birthtime
+ "sys/types.h;sys/stat.h" HAVE_STRUCT_STAT_ST_BIRTHTIME)
+
+# Check for high-resolution timestamps in struct stat
+CHECK_STRUCT_MEMBER("struct stat" st_birthtimespec.tv_nsec
+ "sys/types.h;sys/stat.h" HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC)
+CHECK_STRUCT_MEMBER("struct stat" st_mtimespec.tv_nsec
+ "sys/types.h;sys/stat.h" HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
+CHECK_STRUCT_MEMBER("struct stat" st_mtim.tv_nsec
+ "sys/types.h;sys/stat.h" HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
+CHECK_STRUCT_MEMBER("struct stat" st_mtime_n
+ "sys/types.h;sys/stat.h" HAVE_STRUCT_STAT_ST_MTIME_N)
+CHECK_STRUCT_MEMBER("struct stat" st_umtime
+ "sys/types.h;sys/stat.h" HAVE_STRUCT_STAT_ST_UMTIME)
+CHECK_STRUCT_MEMBER("struct stat" st_mtime_usec
+ "sys/types.h;sys/stat.h" HAVE_STRUCT_STAT_ST_MTIME_USEC)
+# Check for block size support in struct stat
+CHECK_STRUCT_MEMBER("struct stat" st_blksize
+ "sys/types.h;sys/stat.h" HAVE_STRUCT_STAT_ST_BLKSIZE)
+# Check for st_flags in struct stat (BSD fflags)
+CHECK_STRUCT_MEMBER("struct stat" st_flags
+ "sys/types.h;sys/stat.h" HAVE_STRUCT_STAT_ST_FLAGS)
+
+IF(HAVE_SYS_STATVFS_H)
+ CHECK_STRUCT_MEMBER("struct statvfs" f_iosize
+ "sys/types.h;sys/statvfs.h" HAVE_STRUCT_STATVFS_F_IOSIZE)
+ENDIF()
+
+#
+#
+CHECK_STRUCT_MEMBER("struct tm" tm_sec
+ "sys/types.h;sys/time.h;time.h" TIME_WITH_SYS_TIME)
+
+#
+# Check for integer types
+#
+#
+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("__int64" __INT64)
+CHECK_TYPE_SIZE("unsigned __int64" UNSIGNED___INT64)
+
+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(dev_t DEV_T)
+IF(NOT HAVE_DEV_T)
+ IF(MSVC)
+ SET(dev_t "unsigned int")
+ ENDIF(MSVC)
+ENDIF(NOT HAVE_DEV_T)
+#
+CHECK_TYPE_SIZE(gid_t GID_T)
+IF(NOT HAVE_GID_T)
+ IF(WIN32)
+ SET(gid_t "short")
+ ELSE(WIN32)
+ SET(gid_t "unsigned int")
+ ENDIF(WIN32)
+ENDIF(NOT HAVE_GID_T)
+#
+CHECK_TYPE_SIZE(id_t ID_T)
+IF(NOT HAVE_ID_T)
+ IF(WIN32)
+ SET(id_t "short")
+ ELSE(WIN32)
+ SET(id_t "unsigned int")
+ ENDIF(WIN32)
+ENDIF(NOT HAVE_ID_T)
+#
+CHECK_TYPE_SIZE(mode_t MODE_T)
+IF(NOT HAVE_MODE_T)
+ IF(WIN32)
+ SET(mode_t "unsigned short")
+ ELSE(WIN32)
+ SET(mode_t "int")
+ ENDIF(WIN32)
+ENDIF(NOT HAVE_MODE_T)
+#
+CHECK_TYPE_SIZE(off_t OFF_T)
+IF(NOT HAVE_OFF_T)
+ SET(off_t "__int64")
+ENDIF(NOT HAVE_OFF_T)
+#
+CHECK_TYPE_SIZE(size_t SIZE_T)
+IF(NOT HAVE_SIZE_T)
+ IF("${CMAKE_SIZEOF_VOID_P}" EQUAL 8)
+ SET(size_t "uint64_t")
+ ELSE("${CMAKE_SIZEOF_VOID_P}" EQUAL 8)
+ SET(size_t "uint32_t")
+ ENDIF("${CMAKE_SIZEOF_VOID_P}" EQUAL 8)
+ENDIF(NOT HAVE_SIZE_T)
+#
+CHECK_TYPE_SIZE(ssize_t SSIZE_T)
+IF(NOT HAVE_SSIZE_T)
+ IF("${CMAKE_SIZEOF_VOID_P}" EQUAL 8)
+ SET(ssize_t "int64_t")
+ ELSE("${CMAKE_SIZEOF_VOID_P}" EQUAL 8)
+ SET(ssize_t "long")
+ ENDIF("${CMAKE_SIZEOF_VOID_P}" EQUAL 8)
+ENDIF(NOT HAVE_SSIZE_T)
+#
+CHECK_TYPE_SIZE(uid_t UID_T)
+IF(NOT HAVE_UID_T)
+ IF(WIN32)
+ SET(uid_t "short")
+ ELSE(WIN32)
+ SET(uid_t "unsigned int")
+ ENDIF(WIN32)
+ENDIF(NOT HAVE_UID_T)
+#
+CHECK_TYPE_SIZE(pid_t PID_T)
+IF(NOT HAVE_PID_T)
+ IF(WIN32)
+ SET(pid_t "int")
+ ELSE(WIN32)
+ MESSAGE(FATAL_ERROR "pid_t doesn't exist on this platform?")
+ ENDIF(WIN32)
+ENDIF(NOT HAVE_PID_T)
+#
+CHECK_TYPE_SIZE(intptr_t INTPTR_T)
+IF(NOT HAVE_INTPTR_T)
+ IF("${CMAKE_SIZEOF_VOID_P}" EQUAL 8)
+ SET(intptr_t "int64_t")
+ ELSE()
+ SET(intptr_t "int32_t")
+ ENDIF()
+ENDIF(NOT HAVE_INTPTR_T)
+#
+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(NOT HAVE_UINTPTR_T)
+#
+CHECK_TYPE_SIZE(wchar_t SIZEOF_WCHAR_T)
+IF(HAVE_SIZEOF_WCHAR_T)
+ SET(HAVE_WCHAR_T 1)
+ENDIF(HAVE_SIZEOF_WCHAR_T)
+#
+# Check if _FILE_OFFSET_BITS macro needed for large files
+#
+CHECK_FILE_OFFSET_BITS()
+
+#
+# Check for Extended Attribute libraries, headers, and functions
+#
+IF(ENABLE_XATTR)
+ LA_CHECK_INCLUDE_FILE(attr/xattr.h HAVE_ATTR_XATTR_H)
+ LA_CHECK_INCLUDE_FILE(sys/xattr.h HAVE_SYS_XATTR_H)
+ LA_CHECK_INCLUDE_FILE(sys/extattr.h HAVE_SYS_EXTATTR_H)
+ CHECK_LIBRARY_EXISTS(attr "setxattr" "" HAVE_LIBATTR)
+ IF(HAVE_LIBATTR)
+ SET(CMAKE_REQUIRED_LIBRARIES "attr")
+ ENDIF(HAVE_LIBATTR)
+ CHECK_SYMBOL_EXISTS(EXTATTR_NAMESPACE_USER "sys/types.h;sys/extattr.h" HAVE_DECL_EXTATTR_NAMESPACE_USER)
+ CHECK_FUNCTION_EXISTS_GLIBC(extattr_get_file HAVE_EXTATTR_GET_FILE)
+ CHECK_FUNCTION_EXISTS_GLIBC(extattr_list_file HAVE_EXTATTR_LIST_FILE)
+ CHECK_FUNCTION_EXISTS_GLIBC(extattr_set_fd HAVE_EXTATTR_SET_FD)
+ CHECK_FUNCTION_EXISTS_GLIBC(extattr_set_file HAVE_EXTATTR_SET_FILE)
+ CHECK_FUNCTION_EXISTS_GLIBC(fgetxattr HAVE_FGETXATTR)
+ CHECK_FUNCTION_EXISTS_GLIBC(flistxattr HAVE_FLISTXATTR)
+ CHECK_FUNCTION_EXISTS_GLIBC(fsetxattr HAVE_FSETXATTR)
+ CHECK_FUNCTION_EXISTS_GLIBC(getxattr HAVE_GETXATTR)
+ CHECK_FUNCTION_EXISTS_GLIBC(lgetxattr HAVE_LGETXATTR)
+ CHECK_FUNCTION_EXISTS_GLIBC(listxattr HAVE_LISTXATTR)
+ CHECK_FUNCTION_EXISTS_GLIBC(llistxattr HAVE_LLISTXATTR)
+ CHECK_FUNCTION_EXISTS_GLIBC(lsetxattr HAVE_LSETXATTR)
+ CHECK_FUNCTION_EXISTS_GLIBC(fgetea HAVE_FGETEA)
+ CHECK_FUNCTION_EXISTS_GLIBC(flistea HAVE_FLISTEA)
+ CHECK_FUNCTION_EXISTS_GLIBC(fsetea HAVE_FSETEA)
+ CHECK_FUNCTION_EXISTS_GLIBC(getea HAVE_GETEA)
+ CHECK_FUNCTION_EXISTS_GLIBC(lgetea HAVE_LGETEA)
+ CHECK_FUNCTION_EXISTS_GLIBC(listea HAVE_LISTEA)
+ CHECK_FUNCTION_EXISTS_GLIBC(llistea HAVE_LLISTEA)
+ CHECK_FUNCTION_EXISTS_GLIBC(lsetea HAVE_LSETEA)
+ELSE(ENABLE_XATTR)
+ SET(HAVE_ATTR_LIB FALSE)
+ SET(HAVE_ATTR_XATTR_H FALSE)
+ SET(HAVE_DECL_EXTATTR_NAMESPACE_USER FALSE)
+ SET(HAVE_EXTATTR_GET_FILE FALSE)
+ SET(HAVE_EXTATTR_LIST_FILE FALSE)
+ SET(HAVE_EXTATTR_SET_FD FALSE)
+ SET(HAVE_EXTATTR_SET_FILE FALSE)
+ SET(HAVE_FGETEA FALSE)
+ SET(HAVE_FGETXATTR FALSE)
+ SET(HAVE_FLISTEA FALSE)
+ SET(HAVE_FLISTXATTR FALSE)
+ SET(HAVE_FSETEA FALSE)
+ SET(HAVE_FSETXATTR FALSE)
+ SET(HAVE_GETEA FALSE)
+ SET(HAVE_GETXATTR FALSE)
+ SET(HAVE_LGETEA FALSE)
+ SET(HAVE_LGETXATTR FALSE)
+ SET(HAVE_LISTEA FALSE)
+ SET(HAVE_LISTXATTR FALSE)
+ SET(HAVE_LLISTEA FALSE)
+ SET(HAVE_LLISTXATTR FALSE)
+ SET(HAVE_LSETEA FALSE)
+ SET(HAVE_LSETXATTR FALSE)
+ SET(HAVE_SYS_EXTATTR_H FALSE)
+ SET(HAVE_SYS_XATTR_H FALSE)
+ENDIF(ENABLE_XATTR)
+
+#
+# Check for ACL libraries, headers, and functions
+#
+# The ACL support in libarchive is written against the POSIX1e draft,
+# which was never officially approved and varies quite a bit across
+# platforms. Worse, some systems have completely non-POSIX acl functions,
+# which makes the following checks rather more complex than I would like.
+#
+IF(ENABLE_ACL)
+ CHECK_LIBRARY_EXISTS(acl "acl_get_file" "" HAVE_LIBACL)
+ IF(HAVE_LIBACL)
+ SET(CMAKE_REQUIRED_LIBRARIES "acl")
+ FIND_LIBRARY(ACL_LIBRARY NAMES acl)
+ LIST(APPEND ADDITIONAL_LIBS ${ACL_LIBRARY})
+ ENDIF(HAVE_LIBACL)
+ #
+ CHECK_FUNCTION_EXISTS_GLIBC(acl_create_entry HAVE_ACL_CREATE_ENTRY)
+ CHECK_FUNCTION_EXISTS_GLIBC(acl_init HAVE_ACL_INIT)
+ CHECK_FUNCTION_EXISTS_GLIBC(acl_set_fd HAVE_ACL_SET_FD)
+ CHECK_FUNCTION_EXISTS_GLIBC(acl_set_fd_np HAVE_ACL_SET_FD_NP)
+ CHECK_FUNCTION_EXISTS_GLIBC(acl_set_file HAVE_ACL_SET_FILE)
+ CHECK_TYPE_EXISTS(acl_permset_t "${INCLUDES}" HAVE_ACL_PERMSET_T)
+
+ # The "acl_get_perm()" function was omitted from the POSIX draft.
+ # (It's a pretty obvious oversight; otherwise, there's no way to
+ # test for specific permissions in a permset.) Linux uses the obvious
+ # name, FreeBSD adds _np to mark it as "non-Posix extension."
+ # Test for both as a double-check that we really have POSIX-style ACL support.
+ CHECK_FUNCTION_EXISTS(acl_get_perm HAVE_ACL_GET_PERM)
+ CHECK_FUNCTION_EXISTS(acl_get_perm_np HAVE_ACL_GET_PERM_NP)
+ CHECK_FUNCTION_EXISTS(acl_get_link HAVE_ACL_GET_LINK)
+ CHECK_FUNCTION_EXISTS(acl_get_link_np HAVE_ACL_GET_LINK_NP)
+
+ # MacOS has an acl.h that isn't POSIX. It can be detected by
+ # checking for ACL_USER
+ CHECK_SYMBOL_EXISTS(ACL_USER "${INCLUDES}" HAVE_ACL_USER)
+ELSE(ENABLE_ACL)
+ # If someone runs cmake, then disables ACL support, we need
+ # to forcibly override the cached values for these.
+ SET(HAVE_ACL_CREATE_ENTRY FALSE)
+ SET(HAVE_ACL_GET_LINK FALSE)
+ SET(HAVE_ACL_GET_LINK_NP FALSE)
+ SET(HAVE_ACL_GET_PERM FALSE)
+ SET(HAVE_ACL_GET_PERM_NP FALSE)
+ SET(HAVE_ACL_INIT FALSE)
+ SET(HAVE_ACL_LIB FALSE)
+ SET(HAVE_ACL_PERMSET_T FALSE)
+ SET(HAVE_ACL_SET_FD FALSE)
+ SET(HAVE_ACL_SET_FD_NP FALSE)
+ SET(HAVE_ACL_SET_FILE FALSE)
+ SET(HAVE_ACL_USER FALSE)
+ENDIF(ENABLE_ACL)
+
+#
+# Check MD5/RMD160/SHA support
+# NOTE: Crypto checks must be run last before generating config.h
+#
+CHECK_CRYPTO("MD5;RMD160;SHA1;SHA256;SHA384;SHA512" LIBC)
+CHECK_CRYPTO("SHA256;SHA384;SHA512" LIBC2)
+CHECK_CRYPTO("SHA256;SHA384;SHA512" LIBC3)
+CHECK_CRYPTO("MD5;SHA1;SHA256;SHA384;SHA512" LIBSYSTEM)
+CHECK_CRYPTO("MD5;RMD160;SHA1;SHA256;SHA384;SHA512" NETTLE)
+CHECK_CRYPTO("MD5;RMD160;SHA1;SHA256;SHA384;SHA512" OPENSSL)
+
+# Libmd has to be probed after OpenSSL.
+CHECK_CRYPTO("MD5;RMD160;SHA1;SHA256;SHA512" LIBMD)
+
+CHECK_CRYPTO_WIN("MD5;SHA1;SHA256;SHA384;SHA512")
+
+# Generate "config.h" from "build/cmake/config.h.in"
+CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/build/cmake/config.h.in
+ ${CMAKE_CURRENT_BINARY_DIR}/config.h)
+INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_BINARY_DIR})
+ADD_DEFINITIONS(-DHAVE_CONFIG_H)
+
+#
+# Register installation of PDF documents.
+#
+IF(WIN32 AND NOT CYGWIN)
+ #
+ # On Windows platform, It's better that we install PDF documents
+ # on one's computer.
+ # These PDF documents are available in the release package.
+ #
+ IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/doc/pdf)
+ INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/doc/pdf
+ DESTINATION share/man
+ FILES_MATCHING PATTERN "*.pdf"
+ )
+ ENDIF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/doc/pdf)
+ENDIF(WIN32 AND NOT CYGWIN)
+#
+#
+#
+INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/libarchive)
+#
+IF(MSVC)
+ ADD_DEFINITIONS(-D_CRT_SECURE_NO_DEPRECATE)
+ENDIF(MSVC)
+
+# We need CoreServices on Mac OS.
+IF(APPLE)
+ LIST(APPEND ADDITIONAL_LIBS "-framework CoreServices")
+ENDIF(APPLE)
+
+add_subdirectory(libarchive)
+
+install(FILES COPYING DESTINATION ${CMake_DOC_DEST}/cmlibarchive)
diff --git a/Utilities/cmlibarchive/COPYING b/Utilities/cmlibarchive/COPYING
new file mode 100644
index 000000000..b25880600
--- /dev/null
+++ b/Utilities/cmlibarchive/COPYING
@@ -0,0 +1,60 @@
+The libarchive distribution as a whole is Copyright by Tim Kientzle
+and is subject to the copyright notice reproduced at the bottom of
+this file.
+
+Each individual file in this distribution should have a clear
+copyright/licensing statement at the beginning of the file. If any do
+not, please let me know and I will rectify it. The following is
+intended to summarize the copyright status of the individual files;
+the actual statements in the files are controlling.
+
+* Except as listed below, all C sources (including .c and .h files)
+ and documentation files are subject to the copyright notice reproduced
+ at the bottom of this file.
+
+* The following source files are also subject in whole or in part to
+ a 3-clause UC Regents copyright; please read the individual source
+ files for details:
+ libarchive/archive_entry.c
+ libarchive/archive_read_support_filter_compress.c
+ libarchive/archive_write_set_filter_compress.c
+ libarchive/mtree.5
+ tar/matching.c
+
+* The following source files are in the public domain:
+ tar/getdate.c
+
+* The build files---including Makefiles, configure scripts,
+ and auxiliary scripts used as part of the compile process---have
+ widely varying licensing terms. Please check individual files before
+ distributing them to see if those restrictions apply to you.
+
+I intend for all new source code to use the license below and hope over
+time to replace code with other licenses with new implementations that
+do use the license below. The varying licensing of the build scripts
+seems to be an unavoidable mess.
+
+
+Copyright (c) 2003-2009 <author(s)>
+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
+ in this position and unchanged.
+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.
diff --git a/Utilities/cmlibarchive/CTestConfig.cmake b/Utilities/cmlibarchive/CTestConfig.cmake
new file mode 100644
index 000000000..7a09742db
--- /dev/null
+++ b/Utilities/cmlibarchive/CTestConfig.cmake
@@ -0,0 +1,11 @@
+# TODO: This file should be moved into the build/cmake directory...
+
+# The libarchive CDash page appears at
+# http://my.cdash.org/index.php?project=libarchive
+set(CTEST_PROJECT_NAME "libarchive")
+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=libarchive")
+set(CTEST_DROP_SITE_CDASH TRUE)
diff --git a/Utilities/cmlibarchive/README-CMake.txt b/Utilities/cmlibarchive/README-CMake.txt
new file mode 100644
index 000000000..45cb0939e
--- /dev/null
+++ b/Utilities/cmlibarchive/README-CMake.txt
@@ -0,0 +1,66 @@
+The Utilities/cmlibarchive directory contains a reduced distribution
+of the libarchive 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 libarchive snapshots and
+nothing else. No Git ref points explicitly to the head of this
+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 4f4fe6e5
+
+Use a temporary directory to checkout the branch:
+
+ mkdir libarchive-tmp
+ cd libarchive-tmp
+ git init
+ git pull .. libarchive-upstream
+ rm -rf *
+
+Now place the (reduced) libarchive content in this directory. See
+instructions shown by
+
+ git log 4f4fe6e5
+
+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='LibArchive Upstream' \
+ GIT_AUTHOR_EMAIL='libarchive-discuss@googlegroups.com' \
+ GIT_AUTHOR_DATE='2011-12-31 13:54:34 -0500' \
+ git commit -m 'libarchive 3.0.2-r4051 (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:libarchive-upstream
+ cd ..
+ rm -rf libarchive-tmp
+
+Create a topic in the main repository on which to perform the update:
+
+ git checkout -b update-libarchive master
+
+Merge the libarchive-upstream branch as a subtree:
+
+ git merge -s recursive -X subtree=Utilities/cmlibarchive \
+ libarchive-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 libarchive-upstream
+
+to get the commit from which the libarchive-upstream branch must be started
+on the next update. Edit the "git branch libarchive-upstream" line above to
+record it, and commit this file.
diff --git a/Utilities/cmlibarchive/build/cmake/CheckFileOffsetBits.c b/Utilities/cmlibarchive/build/cmake/CheckFileOffsetBits.c
new file mode 100644
index 000000000..d948fecf2
--- /dev/null
+++ b/Utilities/cmlibarchive/build/cmake/CheckFileOffsetBits.c
@@ -0,0 +1,14 @@
+#include <sys/types.h>
+
+#define KB ((off_t)1024)
+#define MB ((off_t)1024 * KB)
+#define GB ((off_t)1024 * MB)
+#define TB ((off_t)1024 * GB)
+int t2[(((64 * GB -1) % 671088649) == 268434537)
+ && (((TB - (64 * GB -1) + 255) % 1792151290) == 305159546)? 1: -1];
+
+int main()
+{
+ ;
+ return 0;
+}
diff --git a/Utilities/cmlibarchive/build/cmake/CheckFileOffsetBits.cmake b/Utilities/cmlibarchive/build/cmake/CheckFileOffsetBits.cmake
new file mode 100644
index 000000000..b347c9366
--- /dev/null
+++ b/Utilities/cmlibarchive/build/cmake/CheckFileOffsetBits.cmake
@@ -0,0 +1,44 @@
+# - Check if _FILE_OFFSET_BITS macro needed for large files
+# CHECK_FILE_OFFSET_BITS ()
+#
+# 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
+# Copyright (c) 2009, Michihiro NAKAJIMA
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+#INCLUDE(CheckCXXSourceCompiles)
+
+GET_FILENAME_COMPONENT(_selfdir_CheckFileOffsetBits
+ "${CMAKE_CURRENT_LIST_FILE}" PATH)
+
+MACRO (CHECK_FILE_OFFSET_BITS)
+ IF(NOT DEFINED _FILE_OFFSET_BITS)
+ MESSAGE(STATUS "Checking _FILE_OFFSET_BITS for large files")
+ TRY_COMPILE(__WITHOUT_FILE_OFFSET_BITS_64
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${_selfdir_CheckFileOffsetBits}/CheckFileOffsetBits.c
+ COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS})
+ IF(NOT __WITHOUT_FILE_OFFSET_BITS_64)
+ TRY_COMPILE(__WITH_FILE_OFFSET_BITS_64
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${_selfdir_CheckFileOffsetBits}/CheckFileOffsetBits.c
+ COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} -D_FILE_OFFSET_BITS=64)
+ ENDIF(NOT __WITHOUT_FILE_OFFSET_BITS_64)
+
+ IF(NOT __WITHOUT_FILE_OFFSET_BITS_64 AND __WITH_FILE_OFFSET_BITS_64)
+ SET(_FILE_OFFSET_BITS 64 CACHE INTERNAL "_FILE_OFFSET_BITS macro needed for large files")
+ MESSAGE(STATUS "Checking _FILE_OFFSET_BITS for large files - needed")
+ ELSE(NOT __WITHOUT_FILE_OFFSET_BITS_64 AND __WITH_FILE_OFFSET_BITS_64)
+ SET(_FILE_OFFSET_BITS "" CACHE INTERNAL "_FILE_OFFSET_BITS macro needed for large files")
+ MESSAGE(STATUS "Checking _FILE_OFFSET_BITS for large files - not needed")
+ ENDIF(NOT __WITHOUT_FILE_OFFSET_BITS_64 AND __WITH_FILE_OFFSET_BITS_64)
+ ENDIF(NOT DEFINED _FILE_OFFSET_BITS)
+
+ENDMACRO (CHECK_FILE_OFFSET_BITS)
+
diff --git a/Utilities/cmlibarchive/build/cmake/CheckFuncs.cmake b/Utilities/cmlibarchive/build/cmake/CheckFuncs.cmake
new file mode 100644
index 000000000..0670df97f
--- /dev/null
+++ b/Utilities/cmlibarchive/build/cmake/CheckFuncs.cmake
@@ -0,0 +1,49 @@
+# Check if the system has the specified function; treat glibc "stub"
+# functions as nonexistent:
+# CHECK_FUNCTION_EXISTS_GLIBC (FUNCTION FUNCVAR)
+#
+# FUNCTION - the function(s) where the prototype should be declared
+# FUNCVAR - variable to define if the function does exist
+#
+# In particular, this understands the glibc convention of
+# defining macros __stub_XXXX or __stub___XXXX if the function
+# does appear in the library but is merely a stub that does nothing.
+# By detecting this case, we can select alternate behavior on
+# platforms that don't support this functionality.
+#
+# 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
+# Copyright (c) 2009, Michihiro NAKAJIMA
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+INCLUDE(CheckFunctionExists)
+GET_FILENAME_COMPONENT(_selfdir_CheckFunctionExistsGlibc
+ "${CMAKE_CURRENT_LIST_FILE}" PATH)
+
+MACRO (CHECK_FUNCTION_EXISTS_GLIBC _FUNC _FUNCVAR)
+ IF(NOT DEFINED ${_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)
+ TRY_COMPILE(__stub
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}/cmake.tmp/CheckFuncs_stub.c
+ COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+ CMAKE_FLAGS
+ -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_INCLUDE_FILE_FLAGS}
+ "${CHECK_INCLUDE_FILE_C_INCLUDE_DIRS}")
+ IF (__stub)
+ SET("${_FUNCVAR}" "" CACHE INTERNAL "Have function ${_FUNC}")
+ ELSE (__stub)
+ CHECK_FUNCTION_EXISTS("${_FUNC}" "${_FUNCVAR}")
+ ENDIF (__stub)
+ ENDIF(NOT DEFINED ${_FUNCVAR})
+ENDMACRO (CHECK_FUNCTION_EXISTS_GLIBC)
+
diff --git a/Utilities/cmlibarchive/build/cmake/CheckFuncs_stub.c.in b/Utilities/cmlibarchive/build/cmake/CheckFuncs_stub.c.in
new file mode 100644
index 000000000..50da414b5
--- /dev/null
+++ b/Utilities/cmlibarchive/build/cmake/CheckFuncs_stub.c.in
@@ -0,0 +1,16 @@
+#ifdef __STDC__
+#include <limits.h>
+#else
+#include <assert.h>
+#endif
+
+int
+main()
+{
+#if defined ${CHECK_STUB_FUNC_1} || defined ${CHECK_STUB_FUNC_2}
+ return 0;
+#else
+this system have stub
+ return 0;
+#endif
+}
diff --git a/Utilities/cmlibarchive/build/cmake/CheckHeaderDirent.cmake b/Utilities/cmlibarchive/build/cmake/CheckHeaderDirent.cmake
new file mode 100644
index 000000000..e9a7ea855
--- /dev/null
+++ b/Utilities/cmlibarchive/build/cmake/CheckHeaderDirent.cmake
@@ -0,0 +1,32 @@
+# - Check if the system has the specified type
+# CHECK_HEADER_DIRENT (HEADER1 HEARDER2 ...)
+#
+# HEADER - the header(s) where the prototype should be declared
+#
+# 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
+# Copyright (c) 2009, Michihiro NAKAJIMA
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+
+INCLUDE(CheckTypeExists)
+
+MACRO (CHECK_HEADER_DIRENT)
+ CHECK_TYPE_EXISTS("DIR *" dirent.h HAVE_DIRENT_H)
+ IF(NOT HAVE_DIRENT_H)
+ CHECK_TYPE_EXISTS("DIR *" sys/ndir.h HAVE_SYS_NDIR_H)
+ IF(NOT HAVE_SYS_NDIR_H)
+ CHECK_TYPE_EXISTS("DIR *" ndir.h HAVE_NDIR_H)
+ IF(NOT HAVE_NDIR_H)
+ CHECK_TYPE_EXISTS("DIR *" sys/dir.h HAVE_SYS_DIR_H)
+ ENDIF(NOT HAVE_NDIR_H)
+ ENDIF(NOT HAVE_SYS_NDIR_H)
+ ENDIF(NOT HAVE_DIRENT_H)
+ENDMACRO (CHECK_HEADER_DIRENT)
+
diff --git a/Utilities/cmlibarchive/build/cmake/CheckStructMember.cmake b/Utilities/cmlibarchive/build/cmake/CheckStructMember.cmake
new file mode 100644
index 000000000..05ddb3a11
--- /dev/null
+++ b/Utilities/cmlibarchive/build/cmake/CheckStructMember.cmake
@@ -0,0 +1,43 @@
+# - Check if the given struct or class has the specified member variable
+# CHECK_STRUCT_MEMBER (STRUCT MEMBER HEADER VARIABLE)
+#
+# 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
+#
+# 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
+
+# Copyright (c) 2006, Alexander Neundorf, <neundorf@kde.org>
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+
+INCLUDE(CheckCSourceCompiles)
+
+MACRO (CHECK_STRUCT_MEMBER _STRUCT _MEMBER _HEADER _RESULT)
+ SET(_INCLUDE_FILES)
+ FOREACH (it ${_HEADER})
+ SET(_INCLUDE_FILES "${_INCLUDE_FILES}#include <${it}>\n")
+ ENDFOREACH (it)
+
+ SET(_CHECK_STRUCT_MEMBER_SOURCE_CODE "
+${_INCLUDE_FILES}
+int main()
+{
+ static ${_STRUCT} tmp;
+ if (sizeof(tmp.${_MEMBER}))
+ return 0;
+ return 0;
+}
+")
+ CHECK_C_SOURCE_COMPILES("${_CHECK_STRUCT_MEMBER_SOURCE_CODE}" ${_RESULT})
+
+ENDMACRO (CHECK_STRUCT_MEMBER)
+
diff --git a/Utilities/cmlibarchive/build/cmake/CheckTypeExists.cmake b/Utilities/cmlibarchive/build/cmake/CheckTypeExists.cmake
new file mode 100644
index 000000000..b05234fd8
--- /dev/null
+++ b/Utilities/cmlibarchive/build/cmake/CheckTypeExists.cmake
@@ -0,0 +1,42 @@
+# - Check if the system has the specified type
+# CHECK_TYPE_EXISTS (TYPE HEADER VARIABLE)
+#
+# TYPE - the name of the type or struct or class you are interested in
+# HEADER - the header(s) where the prototype should be declared
+# VARIABLE - variable to store the result
+#
+# 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
+# Copyright (c) 2009, Michihiro NAKAJIMA
+# Copyright (c) 2006, Alexander Neundorf, <neundorf@kde.org>
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+
+INCLUDE(CheckCSourceCompiles)
+
+MACRO (CHECK_TYPE_EXISTS _TYPE _HEADER _RESULT)
+ SET(_INCLUDE_FILES)
+ FOREACH (it ${_HEADER})
+ SET(_INCLUDE_FILES "${_INCLUDE_FILES}#include <${it}>\n")
+ ENDFOREACH (it)
+
+ SET(_CHECK_TYPE_EXISTS_SOURCE_CODE "
+${_INCLUDE_FILES}
+int main()
+{
+ static ${_TYPE} tmp;
+ if (sizeof(tmp))
+ return 0;
+ return 0;
+}
+")
+ CHECK_C_SOURCE_COMPILES("${_CHECK_TYPE_EXISTS_SOURCE_CODE}" ${_RESULT})
+
+ENDMACRO (CHECK_TYPE_EXISTS)
+
diff --git a/Utilities/cmlibarchive/build/cmake/FindLZMA.cmake b/Utilities/cmlibarchive/build/cmake/FindLZMA.cmake
new file mode 100644
index 000000000..0b46b2cdd
--- /dev/null
+++ b/Utilities/cmlibarchive/build/cmake/FindLZMA.cmake
@@ -0,0 +1,48 @@
+# - Find lzma and lzmadec
+# Find the native LZMA includes and library
+#
+# LZMA_INCLUDE_DIR - where to find lzma.h, etc.
+# LZMA_LIBRARIES - List of libraries when using liblzma.
+# LZMA_FOUND - True if liblzma found.
+# LZMADEC_INCLUDE_DIR - where to find lzmadec.h, etc.
+# LZMADEC_LIBRARIES - List of libraries when using liblzmadec.
+# LZMADEC_FOUND - True if liblzmadec found.
+
+IF (LZMA_INCLUDE_DIR)
+ # Already in cache, be silent
+ SET(LZMA_FIND_QUIETLY TRUE)
+ENDIF (LZMA_INCLUDE_DIR)
+
+FIND_PATH(LZMA_INCLUDE_DIR lzma.h)
+FIND_LIBRARY(LZMA_LIBRARY NAMES lzma liblzma)
+
+# handle the QUIETLY and REQUIRED arguments and set LZMA_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(LZMA DEFAULT_MSG LZMA_LIBRARY LZMA_INCLUDE_DIR)
+
+IF(LZMA_FOUND)
+ SET( LZMA_LIBRARIES ${LZMA_LIBRARY} )
+ELSE(LZMA_FOUND)
+ SET( LZMA_LIBRARIES )
+
+ IF (LZMADEC_INCLUDE_DIR)
+ # Already in cache, be silent
+ SET(LZMADEC_FIND_QUIETLY TRUE)
+ ENDIF (LZMADEC_INCLUDE_DIR)
+
+ FIND_PATH(LZMADEC_INCLUDE_DIR lzmadec.h)
+ FIND_LIBRARY(LZMADEC_LIBRARY NAMES lzmadec )
+
+ # handle the QUIETLY and REQUIRED arguments and set LZMADEC_FOUND to TRUE if
+ # all listed variables are TRUE
+ INCLUDE(FindPackageHandleStandardArgs)
+ FIND_PACKAGE_HANDLE_STANDARD_ARGS(LZMADEC DEFAULT_MSG LZMADEC_LIBRARY
+ LZMADEC_INCLUDE_DIR)
+
+ IF(LZMADEC_FOUND)
+ SET( LZMADEC_LIBRARIES ${LZMADEC_LIBRARY} )
+ ELSE(LZMADEC_FOUND)
+ SET( LZMADEC_LIBRARIES )
+ ENDIF(LZMADEC_FOUND)
+ENDIF(LZMA_FOUND)
diff --git a/Utilities/cmlibarchive/build/cmake/config.h.in b/Utilities/cmlibarchive/build/cmake/config.h.in
new file mode 100644
index 000000000..ff97cbd98
--- /dev/null
+++ b/Utilities/cmlibarchive/build/cmake/config.h.in
@@ -0,0 +1,1110 @@
+/* config.h. Generated from build/cmake/config.h.in by cmake configure */
+#if defined(__osf__)
+# define _OSF_SOURCE
+#endif
+
+/*
+ * 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@
+
+/*
+ * 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 long 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
+
+/* Define ZLIB_WINAPI if zlib was built on Visual Studio. */
+#cmakedefine ZLIB_WINAPI 1
+
+/* MD5 via ARCHIVE_CRYPTO_MD5_LIBC supported. */
+#cmakedefine ARCHIVE_CRYPTO_MD5_LIBC 1
+
+/* MD5 via ARCHIVE_CRYPTO_MD5_LIBSYSTEM supported. */
+#cmakedefine ARCHIVE_CRYPTO_MD5_LIBSYSTEM 1
+
+/* MD5 via ARCHIVE_CRYPTO_MD5_NETTLE supported. */
+#cmakedefine ARCHIVE_CRYPTO_MD5_NETTLE 1
+
+/* MD5 via ARCHIVE_CRYPTO_MD5_OPENSSL supported. */
+#cmakedefine ARCHIVE_CRYPTO_MD5_OPENSSL 1
+
+/* MD5 via ARCHIVE_CRYPTO_MD5_WIN supported. */
+#cmakedefine ARCHIVE_CRYPTO_MD5_WIN 1
+
+/* RMD160 via ARCHIVE_CRYPTO_RMD160_LIBC supported. */
+#cmakedefine ARCHIVE_CRYPTO_RMD160_LIBC 1
+
+/* RMD160 via ARCHIVE_CRYPTO_RMD160_NETTLE supported. */
+#cmakedefine ARCHIVE_CRYPTO_RMD160_NETTLE 1
+
+/* RMD160 via ARCHIVE_CRYPTO_RMD160_OPENSSL supported. */
+#cmakedefine ARCHIVE_CRYPTO_RMD160_OPENSSL 1
+
+/* SHA1 via ARCHIVE_CRYPTO_SHA1_LIBC supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA1_LIBC 1
+
+/* SHA1 via ARCHIVE_CRYPTO_SHA1_LIBSYSTEM supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA1_LIBSYSTEM 1
+
+/* SHA1 via ARCHIVE_CRYPTO_SHA1_NETTLE supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA1_NETTLE 1
+
+/* SHA1 via ARCHIVE_CRYPTO_SHA1_OPENSSL supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA1_OPENSSL 1
+
+/* SHA1 via ARCHIVE_CRYPTO_SHA1_WIN supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA1_WIN 1
+
+/* SHA256 via ARCHIVE_CRYPTO_SHA256_LIBC supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA256_LIBC 1
+
+/* SHA256 via ARCHIVE_CRYPTO_SHA256_LIBC2 supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA256_LIBC2 1
+
+/* SHA256 via ARCHIVE_CRYPTO_SHA256_LIBC3 supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA256_LIBC3 1
+
+/* SHA256 via ARCHIVE_CRYPTO_SHA256_LIBSYSTEM supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA256_LIBSYSTEM 1
+
+/* SHA256 via ARCHIVE_CRYPTO_SHA256_NETTLE supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA256_NETTLE 1
+
+/* SHA256 via ARCHIVE_CRYPTO_SHA256_OPENSSL supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA256_OPENSSL 1
+
+/* SHA256 via ARCHIVE_CRYPTO_SHA256_WIN supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA256_WIN 1
+
+/* SHA384 via ARCHIVE_CRYPTO_SHA384_LIBC supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA384_LIBC 1
+
+/* SHA384 via ARCHIVE_CRYPTO_SHA384_LIBC2 supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA384_LIBC2 1
+
+/* SHA384 via ARCHIVE_CRYPTO_SHA384_LIBC3 supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA384_LIBC3 1
+
+/* SHA384 via ARCHIVE_CRYPTO_SHA384_LIBSYSTEM supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA384_LIBSYSTEM 1
+
+/* SHA384 via ARCHIVE_CRYPTO_SHA384_NETTLE supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA384_NETTLE 1
+
+/* SHA384 via ARCHIVE_CRYPTO_SHA384_OPENSSL supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA384_OPENSSL 1
+
+/* SHA384 via ARCHIVE_CRYPTO_SHA384_WIN supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA384_WIN 1
+
+/* SHA512 via ARCHIVE_CRYPTO_SHA512_LIBC supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA512_LIBC 1
+
+/* SHA512 via ARCHIVE_CRYPTO_SHA512_LIBC2 supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA512_LIBC2 1
+
+/* SHA512 via ARCHIVE_CRYPTO_SHA512_LIBC3 supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA512_LIBC3 1
+
+/* SHA512 via ARCHIVE_CRYPTO_SHA512_LIBSYSTEM supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA512_LIBSYSTEM 1
+
+/* SHA512 via ARCHIVE_CRYPTO_SHA512_NETTLE supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA512_NETTLE 1
+
+/* SHA512 via ARCHIVE_CRYPTO_SHA512_OPENSSL supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA512_OPENSSL 1
+
+/* SHA512 via ARCHIVE_CRYPTO_SHA512_WIN supported. */
+#cmakedefine ARCHIVE_CRYPTO_SHA512_WIN 1
+
+/* Version number of bsdcpio */
+#cmakedefine BSDCPIO_VERSION_STRING "${BSDCPIO_VERSION_STRING}"
+
+/* Version number of bsdtar */
+#cmakedefine BSDTAR_VERSION_STRING "${BSDTAR_VERSION_STRING}"
+
+/* Define to 1 if you have the `acl_create_entry' function. */
+#cmakedefine HAVE_ACL_CREATE_ENTRY 1
+
+/* Define to 1 if you have the `acl_get_link' function. */
+#cmakedefine HAVE_ACL_GET_LINK 1
+
+/* Define to 1 if you have the `acl_get_link_np' function. */
+#cmakedefine HAVE_ACL_GET_LINK_NP 1
+
+/* Define to 1 if you have the `acl_get_perm' function. */
+#cmakedefine HAVE_ACL_GET_PERM 1
+
+/* Define to 1 if you have the `acl_get_perm_np' function. */
+#cmakedefine HAVE_ACL_GET_PERM_NP 1
+
+/* Define to 1 if you have the `acl_init' function. */
+#cmakedefine HAVE_ACL_INIT 1
+
+/* Define to 1 if you have the <acl/libacl.h> header file. */
+#cmakedefine HAVE_ACL_LIBACL_H 1
+
+/* Define to 1 if the system has the type `acl_permset_t'. */
+#cmakedefine HAVE_ACL_PERMSET_T 1
+
+/* Define to 1 if you have the `acl_set_fd' function. */
+#cmakedefine HAVE_ACL_SET_FD 1
+
+/* Define to 1 if you have the `acl_set_fd_np' function. */
+#cmakedefine HAVE_ACL_SET_FD_NP 1
+
+/* Define to 1 if you have the `acl_set_file' function. */
+#cmakedefine HAVE_ACL_SET_FILE 1
+
+/* True for systems with POSIX ACL support */
+#cmakedefine HAVE_ACL_USER 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 <bsdxml.h> header file. */
+#cmakedefine HAVE_BSDXML_H 1
+
+/* Define to 1 if you have the <bzlib.h> header file. */
+#cmakedefine HAVE_BZLIB_H 1
+
+/* Define to 1 if you have the `chflags' function. */
+#cmakedefine HAVE_CHFLAGS 1
+
+/* Define to 1 if you have the `chown' function. */
+#cmakedefine HAVE_CHOWN 1
+
+/* Define to 1 if you have the `chroot' function. */
+#cmakedefine HAVE_CHROOT 1
+
+/* Define to 1 if you have the <copyfile.h> header file. */
+#cmakedefine HAVE_COPYFILE_H 1
+
+/* Define to 1 if you have the `ctime_r' function. */
+#cmakedefine HAVE_CTIME_R 1
+
+/* Define to 1 if you have the <ctype.h> header file. */
+#cmakedefine HAVE_CTYPE_H 1
+
+/* Define to 1 if you have the `cygwin_conv_path' function. */
+#cmakedefine HAVE_CYGWIN_CONV_PATH 1
+
+/* Define to 1 if you have the declaration of `INT64_MAX', and to 0 if you
+ don't. */
+#cmakedefine HAVE_DECL_INT64_MAX 1
+
+/* Define to 1 if you have the declaration of `INT64_MIN', and to 0 if you
+ don't. */
+#cmakedefine HAVE_DECL_INT64_MIN 1
+
+/* Define to 1 if you have the declaration of `SIZE_MAX', and to 0 if you
+ don't. */
+#cmakedefine HAVE_DECL_SIZE_MAX 1
+
+/* Define to 1 if you have the declaration of `SSIZE_MAX', and to 0 if you
+ don't. */
+#cmakedefine HAVE_DECL_SSIZE_MAX 1
+
+/* Define to 1 if you have the declaration of `strerror_r', and to 0 if you
+ don't. */
+#cmakedefine HAVE_DECL_STRERROR_R 1
+
+/* Define to 1 if you have the declaration of `UINT32_MAX', and to 0 if you
+ don't. */
+#cmakedefine HAVE_DECL_UINT32_MAX 1
+
+/* Define to 1 if you have the declaration of `UINT64_MAX', and to 0 if you
+ don't. */
+#cmakedefine HAVE_DECL_UINT64_MAX 1
+
+/* Define to 1 if you have the <direct.h> header file. */
+#cmakedefine HAVE_DIRECT_H 1
+
+/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
+ */
+#cmakedefine HAVE_DIRENT_H 1
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#cmakedefine HAVE_DLFCN_H 1
+
+/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
+#cmakedefine HAVE_DOPRNT 1
+
+/* Define to 1 if nl_langinfo supports D_MD_ORDER */
+#cmakedefine HAVE_D_MD_ORDER 1
+
+/* A possible errno value for invalid file format errors */
+#cmakedefine HAVE_EFTYPE 1
+
+/* A possible errno value for invalid file format errors */
+#cmakedefine HAVE_EILSEQ 1
+
+/* Define to 1 if you have the <errno.h> header file. */
+#cmakedefine HAVE_ERRNO_H 1
+
+/* Define to 1 if you have the <expat.h> header file. */
+#cmakedefine HAVE_EXPAT_H 1
+
+/* Define to 1 if you have the <ext2fs/ext2_fs.h> header file. */
+#cmakedefine HAVE_EXT2FS_EXT2_FS_H 1
+
+/* Define to 1 if you have the `extattr_get_file' function. */
+#cmakedefine HAVE_EXTATTR_GET_FILE 1
+
+/* Define to 1 if you have the `extattr_list_file' function. */
+#cmakedefine HAVE_EXTATTR_LIST_FILE 1
+
+/* Define to 1 if you have the `extattr_set_fd' function. */
+#cmakedefine HAVE_EXTATTR_SET_FD 1
+
+/* Define to 1 if you have the `extattr_set_file' function. */
+#cmakedefine HAVE_EXTATTR_SET_FILE 1
+
+/* Define to 1 if EXTATTR_NAMESPACE_USER is defined in sys/extattr.h. */
+#cmakedefine HAVE_DECL_EXTATTR_NAMESPACE_USER 1
+
+/* Define to 1 if you have the `fchdir' function. */
+#cmakedefine HAVE_FCHDIR 1
+
+/* Define to 1 if you have the `fchflags' function. */
+#cmakedefine HAVE_FCHFLAGS 1
+
+/* Define to 1 if you have the `fchmod' function. */
+#cmakedefine HAVE_FCHMOD 1
+
+/* Define to 1 if you have the `fchown' function. */
+#cmakedefine HAVE_FCHOWN 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 the `fdopendir' function. */
+#cmakedefine HAVE_FDOPENDIR 1
+
+/* Define to 1 if you have the `fgetea' function. */
+#cmakedefine HAVE_FGETEA 1
+
+/* Define to 1 if you have the `fgetxattr' function. */
+#cmakedefine HAVE_FGETXATTR 1
+
+/* Define to 1 if you have the `flistea' function. */
+#cmakedefine HAVE_FLISTEA 1
+
+/* Define to 1 if you have the `flistxattr' function. */
+#cmakedefine HAVE_FLISTXATTR 1
+
+/* Define to 1 if you have the `fork' function. */
+#cmakedefine HAVE_FORK 1
+
+/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
+#cmakedefine HAVE_FSEEKO 1
+
+/* Define to 1 if you have the `fsetea' function. */
+#cmakedefine HAVE_FSETEA 1
+
+/* Define to 1 if you have the `fsetxattr' function. */
+#cmakedefine HAVE_FSETXATTR 1
+
+/* Define to 1 if you have the `fstat' function. */
+#cmakedefine HAVE_FSTAT 1
+
+/* Define to 1 if you have the `fstatat' function. */
+#cmakedefine HAVE_FSTATAT 1
+
+/* Define to 1 if you have the `fstatfs' function. */
+#cmakedefine HAVE_FSTATFS 1
+
+/* Define to 1 if you have the `fstatvfs' function. */
+#cmakedefine HAVE_FSTATVFS 1
+
+/* Define to 1 if you have the `ftruncate' function. */
+#cmakedefine HAVE_FTRUNCATE 1
+
+/* Define to 1 if you have the `futimens' function. */
+#cmakedefine HAVE_FUTIMENS 1
+
+/* Define to 1 if you have the `futimes' function. */
+#cmakedefine HAVE_FUTIMES 1
+
+/* Define to 1 if you have the `futimesat' function. */
+#cmakedefine HAVE_FUTIMESAT 1
+
+/* Define to 1 if you have the `getea' function. */
+#cmakedefine HAVE_GETEA 1
+
+/* Define to 1 if you have the `geteuid' function. */
+#cmakedefine HAVE_GETEUID 1
+
+/* Define to 1 if you have the `getgrgid_r' function. */
+#cmakedefine HAVE_GETGRGID_R 1
+
+/* Define to 1 if you have the `getgrnam_r' function. */
+#cmakedefine HAVE_GETGRNAM_R 1
+
+/* Define to 1 if you have the `getpid' function. */
+#cmakedefine HAVE_GETPID 1
+
+/* Define to 1 if you have the `getpwnam_r' function. */
+#cmakedefine HAVE_GETPWNAM_R 1
+
+/* Define to 1 if you have the `getpwuid_r' function. */
+#cmakedefine HAVE_GETPWUID_R 1
+
+/* Define to 1 if you have the `getvfsbyname' function. */
+#cmakedefine HAVE_GETVFSBYNAME 1
+
+/* Define to 1 if you have the `getxattr' function. */
+#cmakedefine HAVE_GETXATTR 1
+
+/* Define to 1 if you have the `gmtime_r' function. */
+#cmakedefine HAVE_GMTIME_R 1
+
+/* Define to 1 if you have the <grp.h> header file. */
+#cmakedefine HAVE_GRP_H 1
+
+/* Define to 1 if you have the `iconv' function. */
+#cmakedefine HAVE_ICONV 1
+
+/* Define to 1 if you have the <iconv.h> header file. */
+#cmakedefine HAVE_ICONV_H 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#cmakedefine HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the <io.h> header file. */
+#cmakedefine HAVE_IO_H 1
+
+/* Define to 1 if you have the <langinfo.h> header file. */
+#cmakedefine HAVE_LANGINFO_H 1
+
+/* Define to 1 if you have the `lchflags' function. */
+#cmakedefine HAVE_LCHFLAGS 1
+
+/* Define to 1 if you have the `lchmod' function. */
+#cmakedefine HAVE_LCHMOD 1
+
+/* Define to 1 if you have the `lchown' function. */
+#cmakedefine HAVE_LCHOWN 1
+
+/* Define to 1 if you have the `lgetea' function. */
+#cmakedefine HAVE_LGETEA 1
+
+/* Define to 1 if you have the `lgetxattr' function. */
+#cmakedefine HAVE_LGETXATTR 1
+
+/* Define to 1 if you have the `acl' library (-lacl). */
+#cmakedefine HAVE_LIBACL 1
+
+/* Define to 1 if you have the `attr' library (-lattr). */
+#cmakedefine HAVE_LIBATTR 1
+
+/* Define to 1 if you have the `bsdxml' library (-lbsdxml). */
+#cmakedefine HAVE_LIBBSDXML 1
+
+/* Define to 1 if you have the `bz2' library (-lbz2). */
+#cmakedefine HAVE_LIBBZ2 1
+
+/* Define to 1 if you have the `expat' library (-lexpat). */
+#cmakedefine HAVE_LIBEXPAT 1
+
+/* Define to 1 if you have the `lzma' library (-llzma). */
+#cmakedefine HAVE_LIBLZMA 1
+
+/* Define to 1 if you have the `lzmadec' library (-llzmadec). */
+#cmakedefine HAVE_LIBLZMADEC 1
+
+/* Define to 1 if you have the `xml2' library (-lxml2). */
+#cmakedefine HAVE_LIBXML2 1
+
+/* Define to 1 if you have the <libxml/xmlreader.h> header file. */
+#cmakedefine HAVE_LIBXML_XMLREADER_H 1
+
+/* Define to 1 if you have the <libxml/xmlwriter.h> header file. */
+#cmakedefine HAVE_LIBXML_XMLWRITER_H 1
+
+/* Define to 1 if you have the `z' library (-lz). */
+#cmakedefine HAVE_LIBZ 1
+
+/* Define to 1 if you have the <limits.h> header file. */
+#cmakedefine HAVE_LIMITS_H 1
+
+/* Define to 1 if you have the `link' function. */
+#cmakedefine HAVE_LINK 1
+
+/* Define to 1 if you have the <linux/types.h> header file. */
+#cmakedefine HAVE_LINUX_TYPES_H 1
+
+/* Define to 1 if you have the <linux/fiemap.h> header file. */
+#cmakedefine HAVE_LINUX_FIEMAP_H 1
+
+/* Define to 1 if you have the <linux/fs.h> header file. */
+#cmakedefine HAVE_LINUX_FS_H 1
+
+/* Define to 1 if you have the <linux/magic.h> header file. */
+#cmakedefine HAVE_LINUX_MAGIC_H 1
+
+/* Define to 1 if you have the `listea' function. */
+#cmakedefine HAVE_LISTEA 1
+
+/* Define to 1 if you have the `listxattr' function. */
+#cmakedefine HAVE_LISTXATTR 1
+
+/* Define to 1 if you have the `llistea' function. */
+#cmakedefine HAVE_LLISTEA 1
+
+/* Define to 1 if you have the `llistxattr' function. */
+#cmakedefine HAVE_LLISTXATTR 1
+
+/* Define to 1 if you have the <localcharset.h> header file. */
+#cmakedefine HAVE_LOCALCHARSET_H 1
+
+/* Define to 1 if you have the `locale_charset' function. */
+#cmakedefine HAVE_LOCALE_CHARSET 1
+
+/* Define to 1 if you have the <locale.h> header file. */
+#cmakedefine HAVE_LOCALE_H 1
+
+/* Define to 1 if you have the `localtime_r' function. */
+#cmakedefine HAVE_LOCALTIME_R 1
+
+/* Define to 1 if the system has the type `long long int'. */
+#cmakedefine HAVE_LONG_LONG_INT 1
+
+/* Define to 1 if you have the `lsetea' function. */
+#cmakedefine HAVE_LSETEA 1
+
+/* Define to 1 if you have the `lsetxattr' function. */
+#cmakedefine HAVE_LSETXATTR 1
+
+/* Define to 1 if you have the `lstat' function. */
+#cmakedefine HAVE_LSTAT 1
+
+/* Define to 1 if `lstat' has the bug that it succeeds when given the
+ zero-length file name argument. */
+#cmakedefine HAVE_LSTAT_EMPTY_STRING_BUG 1
+
+/* Define to 1 if you have the `lutimes' function. */
+#cmakedefine HAVE_LUTIMES 1
+
+/* Define to 1 if you have the <lzmadec.h> header file. */
+#cmakedefine HAVE_LZMADEC_H 1
+
+/* Define to 1 if you have the <lzma.h> header file. */
+#cmakedefine HAVE_LZMA_H 1
+
+/* Define to 1 if you have the `mbrtowc' function. */
+#cmakedefine HAVE_MBRTOWC 1
+
+/* Define to 1 if you have the `mbsnrtowcs' function. */
+#cmakedefine HAVE_MBSNRTOWCS 1
+
+/* Define to 1 if you have the `memmove' function. */
+#cmakedefine HAVE_MEMMOVE 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#cmakedefine HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the `mkdir' function. */
+#cmakedefine HAVE_MKDIR 1
+
+/* Define to 1 if you have the `mkfifo' function. */
+#cmakedefine HAVE_MKFIFO 1
+
+/* Define to 1 if you have the `mknod' function. */
+#cmakedefine HAVE_MKNOD 1
+
+/* Define to 1 if you have the `mkstemp' function. */
+#cmakedefine HAVE_MKSTEMP 1
+
+/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
+#cmakedefine HAVE_NDIR_H 1
+
+/* Define to 1 if you have the `nl_langinfo' function. */
+#cmakedefine HAVE_NL_LANGINFO 1
+
+/* Define to 1 if you have the `openat' function. */
+#cmakedefine HAVE_OPENAT 1
+
+/* Define to 1 if you have the <paths.h> header file. */
+#cmakedefine HAVE_PATHS_H 1
+
+/* Define to 1 if you have the `pipe' function. */
+#cmakedefine HAVE_PIPE 1
+
+/* Define to 1 if you have the `poll' function. */
+#cmakedefine HAVE_POLL 1
+
+/* Define to 1 if you have the <poll.h> header file. */
+#cmakedefine HAVE_POLL_H 1
+
+/* Define to 1 if you have the <process.h> header file. */
+#cmakedefine HAVE_PROCESS_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 `readdir_r' function. */
+#cmakedefine HAVE_READDIR_R 1
+
+/* Define to 1 if you have the `readlink' function. */
+#cmakedefine HAVE_READLINK 1
+
+/* Define to 1 if you have the `readlinkat' function. */
+#cmakedefine HAVE_READLINKAT 1
+
+/* Define to 1 if you have the <regex.h> header file. */
+#cmakedefine HAVE_REGEX_H 1
+
+/* Define to 1 if you have the `select' function. */
+#cmakedefine HAVE_SELECT 1
+
+/* Define to 1 if you have the `setenv' function. */
+#cmakedefine HAVE_SETENV 1
+
+/* Define to 1 if you have the `setlocale' function. */
+#cmakedefine HAVE_SETLOCALE 1
+
+/* Define to 1 if you have the `sigaction' function. */
+#cmakedefine HAVE_SIGACTION 1
+
+/* Define to 1 if you have the <signal.h> header file. */
+#cmakedefine HAVE_SIGNAL_H 1
+
+/* Define to 1 if you have the `statfs' function. */
+#cmakedefine HAVE_STATFS 1
+
+/* Define to 1 if you have the `statvfs' function. */
+#cmakedefine HAVE_STATVFS 1
+
+/* Define to 1 if `stat' has the bug that it succeeds when given the
+ zero-length file name argument. */
+#cmakedefine HAVE_STAT_EMPTY_STRING_BUG 1
+
+/* Define to 1 if you have the <stdarg.h> header file. */
+#cmakedefine HAVE_STDARG_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 <stdlib.h> header file. */
+#cmakedefine HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the `strchr' function. */
+#cmakedefine HAVE_STRCHR 1
+
+/* Define to 1 if you have the `strdup' function. */
+#cmakedefine HAVE_STRDUP 1
+
+/* Define to 1 if you have the `strerror' function. */
+#cmakedefine HAVE_STRERROR 1
+
+/* Define to 1 if you have the `strerror_r' function. */
+#cmakedefine HAVE_STRERROR_R 1
+
+/* Define to 1 if you have the `strftime' function. */
+#cmakedefine HAVE_STRFTIME 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 `strrchr' function. */
+#cmakedefine HAVE_STRRCHR 1
+
+/* Define to 1 if `f_namemax' is a member of `struct statfs'. */
+#cmakedefine HAVE_STRUCT_STATFS_F_NAMEMAX 1
+
+/* Define to 1 if `f_iosize' is a member of `struct statvfs'. */
+#cmakedefine HAVE_STRUCT_STATVFS_F_IOSIZE 1
+
+/* Define to 1 if `st_birthtime' is a member of `struct stat'. */
+#cmakedefine HAVE_STRUCT_STAT_ST_BIRTHTIME 1
+
+/* Define to 1 if `st_birthtimespec.tv_nsec' is a member of `struct stat'. */
+#cmakedefine HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC 1
+
+/* Define to 1 if `st_blksize' is a member of `struct stat'. */
+#cmakedefine HAVE_STRUCT_STAT_ST_BLKSIZE 1
+
+/* Define to 1 if `st_flags' is a member of `struct stat'. */
+#cmakedefine HAVE_STRUCT_STAT_ST_FLAGS 1
+
+/* Define to 1 if `st_mtimespec.tv_nsec' is a member of `struct stat'. */
+#cmakedefine HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC 1
+
+/* Define to 1 if `st_mtime_n' is a member of `struct stat'. */
+#cmakedefine HAVE_STRUCT_STAT_ST_MTIME_N 1
+
+/* Define to 1 if `st_mtime_usec' is a member of `struct stat'. */
+#cmakedefine HAVE_STRUCT_STAT_ST_MTIME_USEC 1
+
+/* Define to 1 if `st_mtim.tv_nsec' is a member of `struct stat'. */
+#cmakedefine HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC 1
+
+/* Define to 1 if `st_umtime' is a member of `struct stat'. */
+#cmakedefine HAVE_STRUCT_STAT_ST_UMTIME 1
+
+/* Define to 1 if `tm_gmtoff' is a member of `struct tm'. */
+#cmakedefine HAVE_STRUCT_TM_TM_GMTOFF 1
+
+/* Define to 1 if `__tm_gmtoff' is a member of `struct tm'. */
+#cmakedefine HAVE_STRUCT_TM___TM_GMTOFF 1
+
+/* Define to 1 if you have the `symlink' function. */
+#cmakedefine HAVE_SYMLINK 1
+
+/* Define to 1 if you have the <sys/acl.h> header file. */
+#cmakedefine HAVE_SYS_ACL_H 1
+
+/* Define to 1 if you have the <sys/cdefs.h> header file. */
+#cmakedefine HAVE_SYS_CDEFS_H 1
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
+ */
+#cmakedefine HAVE_SYS_DIR_H 1
+
+/* Define to 1 if you have the <sys/ea.h> header file. */
+#cmakedefine HAVE_SYS_EA_H 1
+
+/* Define to 1 if you have the <sys/extattr.h> header file. */
+#cmakedefine HAVE_SYS_EXTATTR_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/mkdev.h> header file. */
+#cmakedefine HAVE_SYS_MKDEV_H 1
+
+/* Define to 1 if you have the <sys/mount.h> header file. */
+#cmakedefine HAVE_SYS_MOUNT_H 1
+
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
+ */
+#cmakedefine HAVE_SYS_NDIR_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/select.h> header file. */
+#cmakedefine HAVE_SYS_SELECT_H 1
+
+/* Define to 1 if you have the <sys/statfs.h> header file. */
+#cmakedefine HAVE_SYS_STATFS_H 1
+
+/* Define to 1 if you have the <sys/statvfs.h> header file. */
+#cmakedefine HAVE_SYS_STATVFS_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/utime.h> header file. */
+#cmakedefine HAVE_SYS_UTIME_H 1
+
+/* Define to 1 if you have the <sys/utsname.h> header file. */
+#cmakedefine HAVE_SYS_UTSNAME_H 1
+
+/* Define to 1 if you have the <sys/vfs.h> header file. */
+#cmakedefine HAVE_SYS_VFS_H 1
+
+/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
+#cmakedefine HAVE_SYS_WAIT_H 1
+
+/* Define to 1 if you have the <sys/xattr.h> header file. */
+#cmakedefine HAVE_SYS_XATTR_H 1
+
+/* Define to 1 if you have the `timegm' function. */
+#cmakedefine HAVE_TIMEGM 1
+
+/* Define to 1 if you have the <time.h> header file. */
+#cmakedefine HAVE_TIME_H 1
+
+/* Define to 1 if you have the `tzset' function. */
+#cmakedefine HAVE_TZSET 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#cmakedefine HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the `unsetenv' function. */
+#cmakedefine HAVE_UNSETENV 1
+
+/* Define to 1 if the system has the type `unsigned long long'. */
+#cmakedefine HAVE_UNSIGNED_LONG_LONG 1
+
+/* Define to 1 if the system has the type `unsigned long long int'. */
+#cmakedefine HAVE_UNSIGNED_LONG_LONG_INT 1
+
+/* Define to 1 if you have the `utime' function. */
+#cmakedefine HAVE_UTIME 1
+
+/* Define to 1 if you have the `utimensat' function. */
+#cmakedefine HAVE_UTIMENSAT 1
+
+/* Define to 1 if you have the `utimes' function. */
+#cmakedefine HAVE_UTIMES 1
+
+/* Define to 1 if you have the <utime.h> header file. */
+#cmakedefine HAVE_UTIME_H 1
+
+/* Define to 1 if you have the `vfork' function. */
+#cmakedefine HAVE_VFORK 1
+
+/* Define to 1 if you have the `vprintf' function. */
+#cmakedefine HAVE_VPRINTF 1
+
+/* Define to 1 if you have the <wchar.h> header file. */
+#cmakedefine HAVE_WCHAR_H 1
+
+/* Define to 1 if the system has the type `wchar_t'. */
+#cmakedefine HAVE_WCHAR_T 1
+
+/* Define to 1 if you have the `wcrtomb' function. */
+#cmakedefine HAVE_WCRTOMB 1
+
+/* Define to 1 if you have the `wcscmp' function. */
+#cmakedefine HAVE_WCSCMP 1
+
+/* Define to 1 if you have the `wcscpy' function. */
+#cmakedefine HAVE_WCSCPY 1
+
+/* Define to 1 if you have the `wcslen' function. */
+#cmakedefine HAVE_WCSLEN 1
+
+/* Define to 1 if you have the `wcsnrtombs' function. */
+#cmakedefine HAVE_WCSNRTOMBS 1
+
+/* Define to 1 if you have the `wctomb' function. */
+#cmakedefine HAVE_WCTOMB 1
+
+/* Define to 1 if you have the <wctype.h> header file. */
+#cmakedefine HAVE_WCTYPE_H 1
+
+/* Define to 1 if you have the <wincrypt.h> header file. */
+#cmakedefine HAVE_WINCRYPT_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 <winioctl.h> header file. */
+#cmakedefine HAVE_WINIOCTL_H 1
+
+/* Define to 1 if you have _CrtSetReportMode in <crtdbg.h> */
+#cmakedefine HAVE__CrtSetReportMode 1
+
+/* Define to 1 if you have the `wmemcmp' function. */
+#cmakedefine HAVE_WMEMCMP 1
+
+/* Define to 1 if you have the `wmemcpy' function. */
+#cmakedefine HAVE_WMEMCPY 1
+
+/* Define to 1 if you have a working EXT2_IOC_GETFLAGS */
+#cmakedefine HAVE_WORKING_EXT2_IOC_GETFLAGS 1
+
+/* Define to 1 if you have the <zlib.h> header file. */
+#cmakedefine HAVE_ZLIB_H 1
+
+/* Define to 1 if you have the `_ctime64_s' function. */
+#cmakedefine HAVE__CTIME64_S 1
+
+/* Define to 1 if you have the `_fseeki64' function. */
+#cmakedefine HAVE__FSEEKI64 1
+
+/* Define to 1 if you have the `_get_timezone' function. */
+#cmakedefine HAVE__GET_TIMEZONE 1
+
+/* Define to 1 if you have the `_localtime64_s' function. */
+#cmakedefine HAVE__LOCALTIME64_S 1
+
+/* Define to 1 if you have the `_mkgmtime64' function. */
+#cmakedefine HAVE__MKGMTIME64 1
+
+/* Define as const if the declaration of iconv() needs const. */
+#define ICONV_CONST ${ICONV_CONST}
+
+/* Version number of libarchive as a single integer */
+#cmakedefine LIBARCHIVE_VERSION_NUMBER "${LIBARCHIVE_VERSION_NUMBER}"
+
+/* Version number of libarchive */
+#cmakedefine LIBARCHIVE_VERSION_STRING "${LIBARCHIVE_VERSION_STRING}"
+
+/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
+ slash. */
+#cmakedefine LSTAT_FOLLOWS_SLASHED_SYMLINK 1
+
+/* Define to 1 if `major', `minor', and `makedev' are declared in <mkdev.h>.
+ */
+#cmakedefine MAJOR_IN_MKDEV 1
+
+/* Define to 1 if `major', `minor', and `makedev' are declared in
+ <sysmacros.h>. */
+#cmakedefine MAJOR_IN_SYSMACROS 1
+
+/* Define to 1 if your C compiler doesn't accept -c and -o together. */
+#cmakedefine NO_MINUS_C_MINUS_O 1
+
+/* The size of `wchar_t', as computed by sizeof. */
+#cmakedefine SIZEOF_WCHAR_T ${SIZEOF_WCHAR_T}
+
+/* Define to 1 if strerror_r returns char *. */
+#cmakedefine STRERROR_R_CHAR_P 1
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#cmakedefine TIME_WITH_SYS_TIME 1
+
+/*
+ * Some platform requires a macro to use extension functions.
+ */
+#cmakedefine SAFE_TO_DEFINE_EXTENSIONS 1
+#ifdef SAFE_TO_DEFINE_EXTENSIONS
+/* Enable extensions on AIX 3, Interix. */
+#ifndef _ALL_SOURCE
+# define _ALL_SOURCE 1
+#endif
+/* Enable GNU extensions on systems that have them. */
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE 1
+#endif
+/* Enable threading extensions on Solaris. */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# define _POSIX_PTHREAD_SEMANTICS 1
+#endif
+/* Enable extensions on HP NonStop. */
+#ifndef _TANDEM_SOURCE
+# define _TANDEM_SOURCE 1
+#endif
+/* Enable general extensions on Solaris. */
+#ifndef __EXTENSIONS__
+# define __EXTENSIONS__ 1
+#endif
+#endif /* SAFE_TO_DEFINE_EXTENSIONS */
+
+/* Version number of package */
+#cmakedefine VERSION "${VERSION}"
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+#cmakedefine _FILE_OFFSET_BITS ${_FILE_OFFSET_BITS}
+
+/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
+#cmakedefine _LARGEFILE_SOURCE 1
+
+/* Define for large files, on AIX-style hosts. */
+#cmakedefine _LARGE_FILES ${_LARGE_FILES}
+
+/* Define for Windows to use Windows 2000+ APIs. */
+#cmakedefine _WIN32_WINNT ${_WIN32_WINNT}
+#cmakedefine WINVER ${WINVER}
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#cmakedefine const ${const}
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#cmakedefine gid_t ${gid_t}
+
+/* Define to `unsigned long' if <sys/types.h> does not define. */
+#cmakedefine id_t ${id_t}
+
+/* Define to `int' if <sys/types.h> does not define. */
+#cmakedefine mode_t ${mode_t}
+
+/* Define to `long long' if <sys/types.h> does not define. */
+#cmakedefine off_t ${off_t}
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#cmakedefine pid_t ${pid_t}
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#cmakedefine size_t ${size_t}
+
+/* Define to `int' if <sys/types.h> does not define. */
+#cmakedefine ssize_t ${ssize_t}
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#cmakedefine uid_t ${uid_t}
+
+/* Define to `int' if <sys/types.h> does not define. */
+#cmakedefine intptr_t ${intptr_t}
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#cmakedefine uintptr_t ${uintptr_t}
diff --git a/Utilities/cmlibarchive/build/pkgconfig/libarchive.pc.in b/Utilities/cmlibarchive/build/pkgconfig/libarchive.pc.in
new file mode 100644
index 000000000..95d715951
--- /dev/null
+++ b/Utilities/cmlibarchive/build/pkgconfig/libarchive.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libarchive
+Description: library that can create and read several streaming archive formats
+Version: @VERSION@
+Cflags: -I${includedir}
+Libs: -L${libdir} -larchive
+Libs.private: @LIBS@
diff --git a/Utilities/cmlibarchive/build/utils/gen_archive_string_composition_h.sh b/Utilities/cmlibarchive/build/utils/gen_archive_string_composition_h.sh
new file mode 100644
index 000000000..95dbe167d
--- /dev/null
+++ b/Utilities/cmlibarchive/build/utils/gen_archive_string_composition_h.sh
@@ -0,0 +1,418 @@
+#!/bin/sh
+#
+# This needs http://unicode.org/Public/UNIDATA/UnicodeData.txt
+#
+inputfile="$1" # Expect UnicodeData.txt
+outfile=archive_string_composition.h
+pickout=/tmp/mk_unicode_composition_tbl$$.awk
+#################################################################################
+#
+# Append the file header of "archive_string_composition.h"
+#
+#################################################################################
+append_copyright()
+{
+cat > ${outfile} <<CR_END
+/*-
+ * Copyright (c) 2011 libarchive Project
+ * 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.
+ *
+ * \$FreeBSD\$
+ *
+ */
+
+/*
+ * ATTENTION!
+ * This file is generated by build/utils/gen_archive_string_composition_h.sh
+ * from http://unicode.org/Public/UNIDATA/UnicodeData.txt
+ *
+ * See also http://unicode.org/report/tr15/
+ */
+
+#ifndef __LIBARCHIVE_BUILD
+#error This header is only to be used internally to libarchive.
+#endif
+
+#ifndef ARCHIVE_STRING_COMPOSITION_H_INCLUDED
+#define ARCHIVE_STRING_COMPOSITION_H_INCLUDED
+
+struct unicode_composition_table {
+ uint32_t cp1;
+ uint32_t cp2;
+ uint32_t nfc;
+};
+
+CR_END
+}
+#################################################################################
+#
+# awk script
+#
+#################################################################################
+cat > ${pickout} <<AWK_END
+#
+BEGIN {
+ FS = ";"
+ min = "";
+ max = "";
+ cmd="sort | awk -F ' ' '{printf \"\\\\t{ 0x%s , 0x%s , 0x%s },\\\\n\",\$1,\$2,\$3}'"
+ print "static const struct unicode_composition_table u_composition_table[] = {"
+}
+END {
+ close(cmd)
+ print "};"
+ print ""
+ #
+ # Output Canonical Combining Class tables used for translating NFD to NFC.
+ #
+ printf "#define CANONICAL_CLASS_MIN\\t0x%s\\n", min
+ printf "#define CANONICAL_CLASS_MAX\\t0x%s\\n", max
+ print ""
+ printf "#define IS_DECOMPOSABLE_BLOCK(uc)\\t\\\\\n"
+ printf "\\t(((uc)>>8) <= 0x%X && u_decomposable_blocks[(uc)>>8])\\n", highnum
+ printf "static const char u_decomposable_blocks[0x%X+1] = {\\n\\t", highnum
+ #
+ # Output blockmap
+ for (i = 0; i <= highnum; i++) {
+ if (i != 0 && i % 32 == 0)
+ printf "\\n\\t"
+ # Additionally Hangul[11XX(17), AC00(172) - D7FF(215)] is decomposable.
+ if (blockmap[i] || i == 17 || (i >= 172 && i <= 215))
+ printf "1,"
+ else
+ printf "0,"
+ }
+ printf "\\n};\\n\\n"
+ #
+ # Output a macro to get a canonical combining class.
+ #
+ print "/* Get Canonical Combining Class(CCC). */"
+ printf "#define CCC(uc)\\t\\\\\n"
+ printf "\\t(((uc) > 0x%s)?0:\\\\\\n", max
+ printf "\\tccc_val[ccc_val_index[ccc_index[(uc)>>8]][((uc)>>4)&0x0F]][(uc)&0x0F])\\n"
+ print ""
+ #
+ # Output a canonical combining class value table.
+ #
+ midcnt = 0
+ printf "/* The table of the value of Canonical Cimbining Class */\\n"
+ print "static const unsigned char ccc_val[][16] = {"
+ print " /* idx=0: XXXX0 - XXXXF */"
+ print " { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },"
+ for (h = 0; h <= highnum; h++) {
+ if (!blockmap[h])
+ continue;
+ for (m = 0; m < 16; m++) {
+ if (!xx_blockmap[h, m])
+ continue;
+ midcnt++
+ printf " /* idx=%d: %03X%1X0 - %03X%1XF */\\n {", midcnt, h, m, h, m
+ for (l = 0; l < 15; l++) {
+ printf "%d, ", xxx_blockmap[h, m, l]
+ }
+ printf "%d },\n", xxx_blockmap[h, m, 15]
+ }
+ }
+ printf "};\n"
+ #
+ # Output the index table of the canonical combining class value table.
+ #
+ cnt = 0
+ midcnt = 0
+ printf "\\n/* The index table to ccc_val[*][16] */\\n"
+ print "static const unsigned char ccc_val_index[][16] = {"
+ print " /* idx=0: XXX00 - XXXFF */"
+ print " { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },"
+ for (h = 0; h <= highnum; h++) {
+ if (!blockmap[h])
+ continue;
+ cnt++
+ printf " /* idx=%d: %03X00 - %03XFF */\\n {", cnt, h, h
+ for (m = 0; m < 16; m++) {
+ if (m != 0)
+ printf ","
+ if (xx_blockmap[h, m]) {
+ midcnt++
+ printf "%2d", midcnt
+ } else
+ printf " 0"
+ }
+ printf " },\\n"
+ }
+ printf "};\\n"
+ #
+ # Output the index table to the index table of the canonical combining
+ # class value table.
+ #
+ printf "\\n/* The index table to ccc_val_index[*][16] */\\n"
+ printf "static const unsigned char ccc_index[] = {\\n ", h
+ cnt = 0
+ for (h = 0; h <= highnum; h++) {
+ if (h != 0 && h % 24 == 0)
+ printf "\\n "
+ if (blockmap[h]) {
+ cnt++;
+ printf "%2d,", cnt
+ } else
+ printf " 0,"
+ }
+ print "};"
+ print ""
+ print "#endif /* ARCHIVE_STRING_COMPOSITION_H_INCLUDED */"
+}
+#
+#
+function hextoi(hex)
+{
+ dec = 0
+ for (i=0; i < length(hex); i++) {
+ x = substr(hex, i+1, 1)
+ if (x ~/[0-9]/)
+ dec = dec * 16 + x;
+ else if (x == "A")
+ dec = dec * 16 + 10;
+ else if (x == "B")
+ dec = dec * 16 + 11;
+ else if (x == "C")
+ dec = dec * 16 + 12;
+ else if (x == "D")
+ dec = dec * 16 + 13;
+ else if (x == "E")
+ dec = dec * 16 + 14;
+ else if (x == "F")
+ dec = dec * 16 + 15;
+ }
+ return dec
+}
+#
+# Collect Canonical Combining Class values.
+#
+\$4 ~/^[0-9A-F]+$/ {
+ if (\$4 !~/^0$/) {
+ if (min == "") {
+ min = \$1
+ }
+ max = \$1
+ high = substr(\$1, 1, length(\$1) -2)
+ highnum = hextoi(high)
+ mid = substr(\$1, length(\$1) -1, 1)
+ midnum = hextoi(mid)
+ low = substr(\$1, length(\$1), 1)
+ lownum = hextoi(low)
+ blockmap[highnum] = 1
+ xx_blockmap[highnum, midnum] = 1
+ xxx_blockmap[highnum, midnum, lownum] = \$4
+ }
+}
+#
+# Following code points are not decomposed in MAC OS.
+# U+2000 - U+2FFF
+# U+F900 - U+FAFF
+# U+2F800 - U+2FAFF
+#
+#\$1 ~/^2[0-9A-F][0-9A-F][0-9A-F]\$/ {
+# next
+#}
+#\$1 ~/^F[9A][0-9A-F][0-9A-F]\$/ {
+# next
+#}
+#\$1 ~/^2F[89A][0-9A-F][0-9A-F]\$/ {
+# next
+#}
+#
+# Exclusion code points specified by
+# http://unicode.org/Public/UNIDATA/CompositionExclusions.txt
+##
+# 1. Script Specifices
+##
+\$1 ~/^095[89ABCDEF]\$/ {
+ next
+}
+\$1 ~/^09D[CDF]\$/ {
+ next
+}
+\$1 ~/^0A3[36]\$/ {
+ next
+}
+\$1 ~/^0A5[9ABE]\$/ {
+ next
+}
+\$1 ~/^0B5[CD]\$/ {
+ next
+}
+\$1 ~/^0F4[3D]\$/ {
+ next
+}
+\$1 ~/^0F5[27C]\$/ {
+ next
+}
+\$1 ~/^0F69\$/ {
+ next
+}
+\$1 ~/^0F7[68]\$/ {
+ next
+}
+\$1 ~/^0F9[3D]\$/ {
+ next
+}
+\$1 ~/^0FA[27C]\$/ {
+ next
+}
+\$1 ~/^0FB9\$/ {
+ next
+}
+\$1 ~/^FB1[DF]\$/ {
+ next
+}
+\$1 ~/^FB2[ABCDEF]\$/ {
+ next
+}
+\$1 ~/^FB3[012345689ABCE]\$/ {
+ next
+}
+\$1 ~/^FB4[01346789ABCDE]\$/ {
+ next
+}
+##
+# 2. Post Composition Version precomposed characters
+##
+\$1 ~/^2ADC\$/ {
+ next
+}
+\$1 ~/^1D15[EF]\$/ {
+ next
+}
+\$1 ~/^1D16[01234]\$/ {
+ next
+}
+\$1 ~/^1D1B[BCDEF]\$/ {
+ next
+}
+\$1 ~/^1D1C0\$/ {
+ next
+}
+##
+# 3. Singleton Decompositions
+##
+\$1 ~/^034[01]\$/ {
+ next
+}
+\$1 ~/^037[4E]\$/ {
+ next
+}
+\$1 ~/^0387\$/ {
+ next
+}
+\$1 ~/^1F7[13579BD]\$/ {
+ next
+}
+\$1 ~/^1FB[BE]\$/ {
+ next
+}
+\$1 ~/^1FC[9B]\$/ {
+ next
+}
+\$1 ~/^1FD[3B]\$/ {
+ next
+}
+\$1 ~/^1FE[3BEF]\$/ {
+ next
+}
+\$1 ~/^1FF[9BD]\$/ {
+ next
+}
+\$1 ~/^200[01]\$/ {
+ next
+}
+\$1 ~/^212[6AB]\$/ {
+ next
+}
+\$1 ~/^232[9A]\$/ {
+ next
+}
+\$1 ~/^F9[0-9A-F][0-9A-F]\$/ {
+ next
+}
+\$1 ~/^FA0[0-9A-D]\$/ {
+ next
+}
+\$1 ~/^FA1[025-9A-E]\$/ {
+ next
+}
+\$1 ~/^FA2[0256A-D]\$/ {
+ next
+}
+\$1 ~/^FA[3-5][0-9A-F]\$/ {
+ next
+}
+\$1 ~/^FA6[0-9A-D]\$/ {
+ next
+}
+\$1 ~/^FA[7-9A-C][0-9A-F]\$/ {
+ next
+}
+\$1 ~/^FAD[0-9]\$/ {
+ next
+}
+\$1 ~/^2F[89][0-9A-F][0-9A-F]\$/ {
+ next
+}
+\$1 ~/^2FA0[0-9A-F]\$/ {
+ next
+}
+\$1 ~/^2FA1[0-9A-D]\$/ {
+ next
+}
+##
+# 4. Non-Starter Decompositions
+##
+\$1 ~/^0344\$/ {
+ next
+}
+\$1 ~/^0F7[35]\$/ {
+ next
+}
+\$1 ~/^0F81\$/ {
+ next
+}
+#
+# Output combinations for NFD ==> NFC.
+#
+\$6 ~/^[0-9A-F]+ [0-9A-F]+\$/ {
+ split(\$6, cp, " ")
+ if (length(\$1) == 4)
+ print "0"cp[1], "0"cp[2], "0"\$1 | cmd
+ else
+ print cp[1], cp[2], \$1 | cmd
+}
+AWK_END
+#################################################################################
+#
+# Run awk a script.
+#
+#################################################################################
+append_copyright
+awk -f ${pickout} ${inputfile} >> ${outfile}
+#
+# Remove awk the script.
+rm ${pickout}
diff --git a/Utilities/cmlibarchive/build/version b/Utilities/cmlibarchive/build/version
new file mode 100644
index 000000000..ee575c8f5
--- /dev/null
+++ b/Utilities/cmlibarchive/build/version
@@ -0,0 +1 @@
+3000002
diff --git a/Utilities/cmlibarchive/libarchive/CMakeLists.txt b/Utilities/cmlibarchive/libarchive/CMakeLists.txt
new file mode 100644
index 000000000..738419597
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/CMakeLists.txt
@@ -0,0 +1,152 @@
+
+############################################
+#
+# How to build libarchive
+#
+############################################
+
+# Public headers
+SET(include_HEADERS
+ archive.h
+ archive_entry.h
+)
+
+# Sources and private headers
+SET(libarchive_SOURCES
+ archive_acl.c
+ archive_check_magic.c
+ archive_crypto.c
+ archive_crypto_private.h
+ archive_endian.h
+ archive_entry.c
+ archive_entry.h
+ archive_entry_copy_stat.c
+ archive_entry_link_resolver.c
+ archive_entry_locale.h
+ archive_entry_private.h
+ archive_entry_sparse.c
+ archive_entry_stat.c
+ archive_entry_strmode.c
+ archive_entry_xattr.c
+ archive_options.c
+ archive_options_private.h
+ archive_platform.h
+ archive_ppmd_private.h
+ archive_ppmd7.c
+ archive_ppmd7_private.h
+ archive_private.h
+ archive_rb.c
+ archive_rb.h
+ archive_read.c
+ archive_read_data_into_fd.c
+ archive_read_disk_entry_from_file.c
+ archive_read_disk_posix.c
+ archive_read_disk_private.h
+ archive_read_disk_set_standard_lookup.c
+ archive_read_extract.c
+ archive_read_open_fd.c
+ archive_read_open_file.c
+ archive_read_open_filename.c
+ archive_read_open_memory.c
+ archive_read_private.h
+ archive_read_set_options.c
+ archive_read_support_filter_all.c
+ archive_read_support_filter_bzip2.c
+ archive_read_support_filter_compress.c
+ archive_read_support_filter_gzip.c
+ archive_read_support_filter_none.c
+ archive_read_support_filter_program.c
+ archive_read_support_filter_rpm.c
+ archive_read_support_filter_uu.c
+ archive_read_support_filter_xz.c
+ archive_read_support_format_7zip.c
+ archive_read_support_format_all.c
+ archive_read_support_format_ar.c
+ archive_read_support_format_by_code.c
+ archive_read_support_format_cab.c
+ archive_read_support_format_cpio.c
+ archive_read_support_format_empty.c
+ archive_read_support_format_iso9660.c
+ archive_read_support_format_lha.c
+ archive_read_support_format_mtree.c
+ archive_read_support_format_rar.c
+ archive_read_support_format_raw.c
+ archive_read_support_format_tar.c
+ archive_read_support_format_xar.c
+ archive_read_support_format_zip.c
+ archive_string.c
+ archive_string.h
+ archive_string_composition.h
+ archive_string_sprintf.c
+ archive_util.c
+ archive_virtual.c
+ archive_write.c
+ archive_write_disk_posix.c
+ archive_write_disk_private.h
+ archive_write_disk_set_standard_lookup.c
+ archive_write_private.h
+ archive_write_open_fd.c
+ archive_write_open_file.c
+ archive_write_open_filename.c
+ archive_write_open_memory.c
+ archive_write_add_filter_bzip2.c
+ archive_write_add_filter_compress.c
+ archive_write_add_filter_gzip.c
+ archive_write_add_filter_none.c
+ archive_write_add_filter_program.c
+ archive_write_add_filter_xz.c
+ archive_write_set_format.c
+ archive_write_set_format_7zip.c
+ archive_write_set_format_ar.c
+ archive_write_set_format_by_name.c
+ archive_write_set_format_cpio.c
+ archive_write_set_format_cpio_newc.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_shar.c
+ archive_write_set_format_ustar.c
+ archive_write_set_format_xar.c
+ archive_write_set_format_zip.c
+ archive_write_set_options.c
+ filter_fork.c
+ filter_fork.h
+)
+
+# Man pages
+SET(libarchive_MANS
+ archive_entry.3
+ archive_entry_acl.3
+ archive_entry_linkify.3
+ archive_entry_paths.3
+ archive_entry_perms.3
+ archive_entry_stat.3
+ archive_entry_time.3
+ archive_read.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
+ cpio.5
+ libarchive.3
+ libarchive_internals.3
+ libarchive-formats.5
+ mtree.5
+ tar.5
+)
+
+IF(WIN32 AND NOT CYGWIN)
+ LIST(APPEND libarchive_SOURCES archive_entry_copy_bhfi.c)
+ LIST(APPEND libarchive_SOURCES archive_read_disk_windows.c)
+ LIST(APPEND libarchive_SOURCES archive_windows.c)
+ LIST(APPEND libarchive_SOURCES archive_windows.h)
+ LIST(APPEND libarchive_SOURCES archive_write_disk_windows.c)
+ LIST(APPEND libarchive_SOURCES filter_fork_windows.c)
+ENDIF(WIN32 AND NOT CYGWIN)
+
+# CMake needs just one static "cmlibarchive" library.
+ADD_LIBRARY(cmlibarchive STATIC ${libarchive_SOURCES} ${include_HEADERS})
+TARGET_LINK_LIBRARIES(cmlibarchive ${ADDITIONAL_LIBS})
diff --git a/Utilities/cmlibarchive/libarchive/archive.h b/Utilities/cmlibarchive/libarchive/archive.h
new file mode 100644
index 000000000..9b6b1b0c2
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive.h
@@ -0,0 +1,826 @@
+/*-
+ * Copyright (c) 2003-2010 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.
+ *
+ * $FreeBSD: src/lib/libarchive/archive.h.in,v 1.50 2008/05/26 17:00:22 kientzle Exp $
+ */
+
+#ifndef ARCHIVE_H_INCLUDED
+#define ARCHIVE_H_INCLUDED
+
+#include <sys/stat.h>
+#include <stddef.h> /* for wchar_t */
+#include <stdio.h> /* For FILE * */
+
+/*
+ * Note: archive.h is for use outside of libarchive; the configuration
+ * headers (config.h, archive_platform.h, etc.) are purely internal.
+ * Do NOT use HAVE_XXX configuration macros to control the behavior of
+ * this header! If you must conditionalize, use predefined compiler and/or
+ * platform macros.
+ */
+#if defined(__BORLANDC__) && __BORLANDC__ >= 0x560
+# include <stdint.h>
+#elif !defined(__WATCOMC__) && !defined(_MSC_VER) && !defined(__INTERIX) && !defined(__BORLANDC__) && !defined(_SCO_DS) && !defined(__osf__)
+# 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_
+#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
+# endif
+# if defined(__BORLANDC__)
+# define __LA_UID_T uid_t
+# define __LA_GID_T gid_t
+# else
+# define __LA_UID_T short
+# define __LA_GID_T short
+# endif
+#else
+# include <unistd.h> /* ssize_t, uid_t, and gid_t */
+# if defined(_SCO_DS) || defined(__osf__)
+# define __LA_INT64_T long long
+# else
+# define __LA_INT64_T int64_t
+# endif
+# define __LA_SSIZE_T ssize_t
+# define __LA_UID_T uid_t
+# define __LA_GID_T gid_t
+#endif
+
+/*
+ * On Windows, define LIBARCHIVE_STATIC if you're building or using a
+ * .lib. The default here assumes you're building a DLL. Only
+ * libarchive source should ever define __LIBARCHIVE_BUILD.
+ */
+#if ((defined __WIN32__) || (defined _WIN32) || defined(__CYGWIN__)) && (!defined LIBARCHIVE_STATIC)
+# ifdef __LIBARCHIVE_BUILD
+# ifdef __GNUC__
+# define __LA_DECL __attribute__((dllexport)) extern
+# else
+# define __LA_DECL __declspec(dllexport)
+# endif
+# else
+# ifdef __GNUC__
+# define __LA_DECL
+# else
+# define __LA_DECL __declspec(dllimport)
+# endif
+# endif
+#else
+/* Static libraries or non-Windows needs no special declaration. */
+# define __LA_DECL
+#endif
+
+#if defined(__GNUC__) && __GNUC__ >= 3 && !defined(__MINGW32__)
+#define __LA_PRINTF(fmtarg, firstvararg) \
+ __attribute__((__format__ (__printf__, fmtarg, firstvararg)))
+#else
+#define __LA_PRINTF(fmtarg, firstvararg) /* nothing */
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The version number is provided as both a macro and a function.
+ * The macro identifies the installed header; the function identifies
+ * the library version (which may not be the same if you're using a
+ * dynamically-linked version of the library). Of course, if the
+ * 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 3000002
+__LA_DECL int archive_version_number(void);
+
+/*
+ * Textual name/version of the library, useful for version displays.
+ */
+#define ARCHIVE_VERSION_STRING "libarchive 3.0.2"
+__LA_DECL const char * archive_version_string(void);
+
+/* Declare our basic types. */
+struct archive;
+struct archive_entry;
+
+/*
+ * Error codes: Use archive_errno() and archive_error_string()
+ * to retrieve details. Unless specified otherwise, all functions
+ * that return 'int' use these codes.
+ */
+#define ARCHIVE_EOF 1 /* Found end of archive. */
+#define ARCHIVE_OK 0 /* Operation was successful. */
+#define ARCHIVE_RETRY (-10) /* Retry might succeed. */
+#define ARCHIVE_WARN (-20) /* Partial success. */
+/* For example, if write_header "fails", then you can't push data. */
+#define ARCHIVE_FAILED (-25) /* Current operation cannot complete. */
+/* But if write_header is "fatal," then this archive is dead and useless. */
+#define ARCHIVE_FATAL (-30) /* No more operations are possible. */
+
+/*
+ * As far as possible, archive_errno returns standard platform errno codes.
+ * Of course, the details vary by platform, so the actual definitions
+ * here are stored in "archive_platform.h". The symbols are listed here
+ * for reference; as a rule, clients should not need to know the exact
+ * platform-dependent error code.
+ */
+/* Unrecognized or invalid file format. */
+/* #define ARCHIVE_ERRNO_FILE_FORMAT */
+/* Illegal usage of the library. */
+/* #define ARCHIVE_ERRNO_PROGRAMMER_ERROR */
+/* Unknown or unclassified error. */
+/* #define ARCHIVE_ERRNO_MISC */
+
+/*
+ * Callbacks are invoked to automatically read/skip/write/open/close the
+ * archive. You can provide your own for complex tasks (like breaking
+ * archives across multiple tapes) or use standard ones built into the
+ * library.
+ */
+
+/* Returns pointer and size of next block of data from 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.
+ * This may skip fewer bytes than requested; it may even skip zero bytes.
+ * 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);
+
+/* 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);
+
+/* Returns size actually written, zero on EOF, -1 on error. */
+typedef __LA_SSIZE_T archive_write_callback(struct archive *,
+ void *_client_data,
+ const void *_buffer, size_t _length);
+
+typedef int archive_open_callback(struct archive *, void *_client_data);
+
+typedef int archive_close_callback(struct archive *, void *_client_data);
+
+/*
+ * Codes to identify various stream filters.
+ */
+#define ARCHIVE_FILTER_NONE 0
+#define ARCHIVE_FILTER_GZIP 1
+#define ARCHIVE_FILTER_BZIP2 2
+#define ARCHIVE_FILTER_COMPRESS 3
+#define ARCHIVE_FILTER_PROGRAM 4
+#define ARCHIVE_FILTER_LZMA 5
+#define ARCHIVE_FILTER_XZ 6
+#define ARCHIVE_FILTER_UU 7
+#define ARCHIVE_FILTER_RPM 8
+#define ARCHIVE_FILTER_LZIP 9
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+#define ARCHIVE_COMPRESSION_NONE ARCHIVE_FILTER_NONE
+#define ARCHIVE_COMPRESSION_GZIP ARCHIVE_FILTER_GZIP
+#define ARCHIVE_COMPRESSION_BZIP2 ARCHIVE_FILTER_BZIP2
+#define ARCHIVE_COMPRESSION_COMPRESS ARCHIVE_FILTER_COMPRESS
+#define ARCHIVE_COMPRESSION_PROGRAM ARCHIVE_FILTER_PROGRAM
+#define ARCHIVE_COMPRESSION_LZMA ARCHIVE_FILTER_LZMA
+#define ARCHIVE_COMPRESSION_XZ ARCHIVE_FILTER_XZ
+#define ARCHIVE_COMPRESSION_UU ARCHIVE_FILTER_UU
+#define ARCHIVE_COMPRESSION_RPM ARCHIVE_FILTER_RPM
+#define ARCHIVE_COMPRESSION_LZIP ARCHIVE_FILTER_LZIP
+#endif
+
+/*
+ * Codes returned by archive_format.
+ *
+ * Top 16 bits identifies the format family (e.g., "tar"); lower
+ * 16 bits indicate the variant. This is updated by read_next_header.
+ * Note that the lower 16 bits will often vary from entry to entry.
+ * In some cases, this variation occurs as libarchive learns more about
+ * the archive (for example, later entries might utilize extensions that
+ * weren't necessary earlier in the archive; in this case, libarchive
+ * will change the format code to indicate the extended format that
+ * was used). In other cases, it's because different tools have
+ * modified the archive and so different parts of the archive
+ * actually have slightly different formats. (Both tar and cpio store
+ * format codes in each entry, so it is quite possible for each
+ * entry to be in a different format.)
+ */
+#define ARCHIVE_FORMAT_BASE_MASK 0xff0000
+#define ARCHIVE_FORMAT_CPIO 0x10000
+#define ARCHIVE_FORMAT_CPIO_POSIX (ARCHIVE_FORMAT_CPIO | 1)
+#define ARCHIVE_FORMAT_CPIO_BIN_LE (ARCHIVE_FORMAT_CPIO | 2)
+#define ARCHIVE_FORMAT_CPIO_BIN_BE (ARCHIVE_FORMAT_CPIO | 3)
+#define ARCHIVE_FORMAT_CPIO_SVR4_NOCRC (ARCHIVE_FORMAT_CPIO | 4)
+#define ARCHIVE_FORMAT_CPIO_SVR4_CRC (ARCHIVE_FORMAT_CPIO | 5)
+#define ARCHIVE_FORMAT_CPIO_AFIO_LARGE (ARCHIVE_FORMAT_CPIO | 6)
+#define ARCHIVE_FORMAT_SHAR 0x20000
+#define ARCHIVE_FORMAT_SHAR_BASE (ARCHIVE_FORMAT_SHAR | 1)
+#define ARCHIVE_FORMAT_SHAR_DUMP (ARCHIVE_FORMAT_SHAR | 2)
+#define ARCHIVE_FORMAT_TAR 0x30000
+#define ARCHIVE_FORMAT_TAR_USTAR (ARCHIVE_FORMAT_TAR | 1)
+#define ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE (ARCHIVE_FORMAT_TAR | 2)
+#define ARCHIVE_FORMAT_TAR_PAX_RESTRICTED (ARCHIVE_FORMAT_TAR | 3)
+#define ARCHIVE_FORMAT_TAR_GNUTAR (ARCHIVE_FORMAT_TAR | 4)
+#define ARCHIVE_FORMAT_ISO9660 0x40000
+#define ARCHIVE_FORMAT_ISO9660_ROCKRIDGE (ARCHIVE_FORMAT_ISO9660 | 1)
+#define ARCHIVE_FORMAT_ZIP 0x50000
+#define ARCHIVE_FORMAT_EMPTY 0x60000
+#define ARCHIVE_FORMAT_AR 0x70000
+#define ARCHIVE_FORMAT_AR_GNU (ARCHIVE_FORMAT_AR | 1)
+#define ARCHIVE_FORMAT_AR_BSD (ARCHIVE_FORMAT_AR | 2)
+#define ARCHIVE_FORMAT_MTREE 0x80000
+#define ARCHIVE_FORMAT_RAW 0x90000
+#define ARCHIVE_FORMAT_XAR 0xA0000
+#define ARCHIVE_FORMAT_LHA 0xB0000
+#define ARCHIVE_FORMAT_CAB 0xC0000
+#define ARCHIVE_FORMAT_RAR 0xD0000
+#define ARCHIVE_FORMAT_7ZIP 0xE0000
+
+/*-
+ * Basic outline for reading an archive:
+ * 1) Ask archive_read_new for an archive reader object.
+ * 2) Update any global properties as appropriate.
+ * In particular, you'll certainly want to call appropriate
+ * archive_read_support_XXX functions.
+ * 3) Call archive_read_open_XXX to open the archive
+ * 4) Repeatedly call archive_read_next_header to get information about
+ * successive archive entries. Call archive_read_data to extract
+ * data for entries of interest.
+ * 5) Call archive_read_finish to end processing.
+ */
+__LA_DECL struct archive *archive_read_new(void);
+
+/*
+ * The archive_read_support_XXX calls enable auto-detect for this
+ * archive handle. They also link in the necessary support code.
+ * For example, if you don't want bzlib linked in, don't invoke
+ * support_compression_bzip2(). The "all" functions provide the
+ * obvious shorthand.
+ */
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+__LA_DECL int archive_read_support_compression_all(struct archive *);
+__LA_DECL int archive_read_support_compression_bzip2(struct archive *);
+__LA_DECL int archive_read_support_compression_compress(struct archive *);
+__LA_DECL int archive_read_support_compression_gzip(struct archive *);
+__LA_DECL int archive_read_support_compression_lzip(struct archive *);
+__LA_DECL int archive_read_support_compression_lzma(struct archive *);
+__LA_DECL int archive_read_support_compression_none(struct archive *);
+__LA_DECL int archive_read_support_compression_program(struct archive *,
+ const char *command);
+__LA_DECL int archive_read_support_compression_program_signature
+ (struct archive *, const char *,
+ const void * /* match */, size_t);
+
+__LA_DECL int archive_read_support_compression_rpm(struct archive *);
+__LA_DECL int archive_read_support_compression_uu(struct archive *);
+__LA_DECL int archive_read_support_compression_xz(struct archive *);
+#endif
+
+__LA_DECL int archive_read_support_filter_all(struct archive *);
+__LA_DECL int archive_read_support_filter_bzip2(struct archive *);
+__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_lzip(struct archive *);
+__LA_DECL int archive_read_support_filter_lzma(struct archive *);
+__LA_DECL int archive_read_support_filter_none(struct archive *);
+__LA_DECL int archive_read_support_filter_program(struct archive *,
+ const char *command);
+__LA_DECL int archive_read_support_filter_program_signature
+ (struct archive *, const char *,
+ const void * /* match */, size_t);
+
+__LA_DECL int archive_read_support_filter_rpm(struct archive *);
+__LA_DECL int archive_read_support_filter_uu(struct archive *);
+__LA_DECL int archive_read_support_filter_xz(struct archive *);
+
+__LA_DECL int archive_read_support_format_7zip(struct archive *);
+__LA_DECL int archive_read_support_format_all(struct archive *);
+__LA_DECL int archive_read_support_format_ar(struct archive *);
+__LA_DECL int archive_read_support_format_by_code(struct archive *, int);
+__LA_DECL int archive_read_support_format_cab(struct archive *);
+__LA_DECL int archive_read_support_format_cpio(struct archive *);
+__LA_DECL int archive_read_support_format_empty(struct archive *);
+__LA_DECL int archive_read_support_format_gnutar(struct archive *);
+__LA_DECL int archive_read_support_format_iso9660(struct archive *);
+__LA_DECL int archive_read_support_format_lha(struct archive *);
+__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_xar(struct archive *);
+__LA_DECL int archive_read_support_format_zip(struct archive *);
+
+/* Set various callbacks. */
+__LA_DECL int archive_read_set_open_callback(struct archive *,
+ archive_open_callback *);
+__LA_DECL int archive_read_set_read_callback(struct archive *,
+ archive_read_callback *);
+__LA_DECL int archive_read_set_seek_callback(struct archive *,
+ archive_seek_callback *);
+__LA_DECL int archive_read_set_skip_callback(struct archive *,
+ archive_skip_callback *);
+__LA_DECL int archive_read_set_close_callback(struct archive *,
+ archive_close_callback *);
+/* The callback data is provided to all of the callbacks above. */
+__LA_DECL int archive_read_set_callback_data(struct archive *, void *);
+/* Opening freezes the callbacks. */
+__LA_DECL int archive_read_open1(struct archive *);
+
+/* Convenience wrappers around the above. */
+__LA_DECL int archive_read_open(struct archive *, void *_client_data,
+ archive_open_callback *, archive_read_callback *,
+ archive_close_callback *);
+__LA_DECL int archive_read_open2(struct archive *, void *_client_data,
+ archive_open_callback *, archive_read_callback *,
+ archive_skip_callback *, archive_close_callback *);
+
+/*
+ * A variety of shortcuts that invoke archive_read_open() with
+ * canned callbacks suitable for common situations. The ones that
+ * accept a block size handle tape blocking correctly.
+ */
+/* Use this if you know the filename. Note: NULL indicates stdin. */
+__LA_DECL int archive_read_open_filename(struct archive *,
+ const char *_filename, size_t _block_size);
+__LA_DECL int archive_read_open_filename_w(struct archive *,
+ const wchar_t *_filename, size_t _block_size);
+/* archive_read_open_file() is a deprecated synonym for ..._open_filename(). */
+__LA_DECL int archive_read_open_file(struct archive *,
+ const char *_filename, size_t _block_size);
+/* Read an archive that's stored in memory. */
+__LA_DECL int archive_read_open_memory(struct archive *,
+ 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,
+ 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,
+ size_t _block_size);
+/* Read an archive that's already open, using a FILE *. */
+/* Note: DO NOT use this with tape drives. */
+__LA_DECL int archive_read_open_FILE(struct archive *, FILE *_file);
+
+/* Parses and returns next entry header. */
+__LA_DECL int archive_read_next_header(struct archive *,
+ struct archive_entry **);
+
+/* Parses and returns next entry header using the archive_entry passed in */
+__LA_DECL int archive_read_next_header2(struct archive *,
+ struct archive_entry *);
+
+/*
+ * Retrieve the byte offset in UNCOMPRESSED data where last-read
+ * header started.
+ */
+__LA_DECL __LA_INT64_T archive_read_header_position(struct archive *);
+
+/* Read data from the body of an entry. Similar to read(2). */
+__LA_DECL __LA_SSIZE_T archive_read_data(struct archive *,
+ void *, size_t);
+
+/*
+ * A zero-copy version of archive_read_data that also exposes the file offset
+ * of each returned block. Note that the client has no way to specify
+ * the desired size of the block. The API does guarantee that offsets will
+ * 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);
+
+/*-
+ * Some convenience functions that are built on archive_read_data:
+ * 'skip': skips entire entry
+ * 'into_buffer': writes data into memory buffer that you provide
+ * 'into_fd': writes data to specified filedes
+ */
+__LA_DECL int archive_read_data_skip(struct archive *);
+__LA_DECL int archive_read_data_into_fd(struct archive *, int fd);
+
+/*
+ * Set read options.
+ */
+/* Apply option to the format only. */
+__LA_DECL int archive_read_set_format_option(struct archive *_a,
+ const char *m, const char *o,
+ const char *v);
+/* Apply option to the filter only. */
+__LA_DECL int archive_read_set_filter_option(struct archive *_a,
+ const char *m, const char *o,
+ const char *v);
+/* Apply option to both the format and the filter. */
+__LA_DECL int archive_read_set_option(struct archive *_a,
+ const char *m, const char *o,
+ const char *v);
+/* Apply option string to both the format and the filter. */
+__LA_DECL int archive_read_set_options(struct archive *_a,
+ const char *opts);
+
+/*-
+ * Convenience function to recreate the current entry (whose header
+ * has just been read) on disk.
+ *
+ * This does quite a bit more than just copy data to disk. It also:
+ * - Creates intermediate directories as required.
+ * - Manages directory permissions: non-writable directories will
+ * be initially created with write permission enabled; when the
+ * archive is closed, dir permissions are edited to the values specified
+ * in the archive.
+ * - Checks hardlinks: hardlinks will not be extracted unless the
+ * linked-to file was also extracted within the same session. (TODO)
+ */
+
+/* The "flags" argument selects optional behavior, 'OR' the flags you want. */
+
+/* Default: Do not try to set owner/group. */
+#define ARCHIVE_EXTRACT_OWNER (0x0001)
+/* Default: Do obey umask, do not restore SUID/SGID/SVTX bits. */
+#define ARCHIVE_EXTRACT_PERM (0x0002)
+/* Default: Do not restore mtime/atime. */
+#define ARCHIVE_EXTRACT_TIME (0x0004)
+/* Default: Replace existing files. */
+#define ARCHIVE_EXTRACT_NO_OVERWRITE (0x0008)
+/* Default: Try create first, unlink only if create fails with EEXIST. */
+#define ARCHIVE_EXTRACT_UNLINK (0x0010)
+/* Default: Do not restore ACLs. */
+#define ARCHIVE_EXTRACT_ACL (0x0020)
+/* Default: Do not restore fflags. */
+#define ARCHIVE_EXTRACT_FFLAGS (0x0040)
+/* Default: Do not restore xattrs. */
+#define ARCHIVE_EXTRACT_XATTR (0x0080)
+/* Default: Do not try to guard against extracts redirected by symlinks. */
+/* Note: With ARCHIVE_EXTRACT_UNLINK, will remove any intermediate symlink. */
+#define ARCHIVE_EXTRACT_SECURE_SYMLINKS (0x0100)
+/* Default: Do not reject entries with '..' as path elements. */
+#define ARCHIVE_EXTRACT_SECURE_NODOTDOT (0x0200)
+/* Default: Create parent directories as needed. */
+#define ARCHIVE_EXTRACT_NO_AUTODIR (0x0400)
+/* Default: Overwrite files, even if one on disk is newer. */
+#define ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER (0x0800)
+/* Detect blocks of 0 and write holes instead. */
+#define ARCHIVE_EXTRACT_SPARSE (0x1000)
+/* Default: Do not restore Mac extended metadata. */
+/* This has no effect except on Mac OS. */
+#define ARCHIVE_EXTRACT_MAC_METADATA (0x2000)
+
+__LA_DECL int archive_read_extract(struct archive *, struct archive_entry *,
+ int flags);
+__LA_DECL int archive_read_extract2(struct archive *, struct archive_entry *,
+ struct archive * /* dest */);
+__LA_DECL void archive_read_extract_set_progress_callback(struct archive *,
+ void (*_progress_func)(void *), void *_user_data);
+
+/* 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);
+
+/* Close the file and release most resources. */
+__LA_DECL int archive_read_close(struct archive *);
+/* Release all resources and destroy the object. */
+/* Note that archive_read_free will call archive_read_close for you. */
+__LA_DECL int archive_read_free(struct archive *);
+#if ARCHIVE_VERSION_NUMBER < 4000000
+/* Synonym for archive_read_free() for backwards compatibility. */
+__LA_DECL int archive_read_finish(struct archive *);
+#endif
+
+/*-
+ * To create an archive:
+ * 1) Ask archive_write_new for an archive writer object.
+ * 2) Set any global properties. In particular, you should set
+ * the compression and format to use.
+ * 3) Call archive_write_open to open the file (most people
+ * will use archive_write_open_file or archive_write_open_fd,
+ * which provide convenient canned I/O callbacks for you).
+ * 4) For each entry:
+ * - construct an appropriate struct archive_entry structure
+ * - archive_write_header to write the header
+ * - archive_write_data to write the entry data
+ * 5) archive_write_close to close the output
+ * 6) archive_write_free to cleanup the writer and release resources
+ */
+__LA_DECL struct archive *archive_write_new(void);
+__LA_DECL int archive_write_set_bytes_per_block(struct archive *,
+ int bytes_per_block);
+__LA_DECL int archive_write_get_bytes_per_block(struct archive *);
+/* XXX This is badly misnamed; suggestions appreciated. XXX */
+__LA_DECL int archive_write_set_bytes_in_last_block(struct archive *,
+ int bytes_in_last_block);
+__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);
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+__LA_DECL int archive_write_set_compression_bzip2(struct archive *);
+__LA_DECL int archive_write_set_compression_compress(struct archive *);
+__LA_DECL int archive_write_set_compression_gzip(struct archive *);
+__LA_DECL int archive_write_set_compression_lzip(struct archive *);
+__LA_DECL int archive_write_set_compression_lzma(struct archive *);
+__LA_DECL int archive_write_set_compression_none(struct archive *);
+__LA_DECL int archive_write_set_compression_program(struct archive *,
+ const char *cmd);
+__LA_DECL int archive_write_set_compression_xz(struct archive *);
+#endif
+
+__LA_DECL int archive_write_add_filter_bzip2(struct archive *);
+__LA_DECL int archive_write_add_filter_compress(struct archive *);
+__LA_DECL int archive_write_add_filter_gzip(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_none(struct archive *);
+__LA_DECL int archive_write_add_filter_program(struct archive *,
+ const char *cmd);
+__LA_DECL int archive_write_add_filter_xz(struct archive *);
+
+
+/* A convenience function to set the format based on the code or name. */
+__LA_DECL int archive_write_set_format(struct archive *, int format_code);
+__LA_DECL int archive_write_set_format_by_name(struct archive *,
+ const char *name);
+/* To minimize link pollution, use one or more of the following. */
+__LA_DECL int archive_write_set_format_7zip(struct archive *);
+__LA_DECL int archive_write_set_format_ar_bsd(struct archive *);
+__LA_DECL int archive_write_set_format_ar_svr4(struct archive *);
+__LA_DECL int archive_write_set_format_cpio(struct archive *);
+__LA_DECL int archive_write_set_format_cpio_newc(struct archive *);
+__LA_DECL int archive_write_set_format_gnutar(struct archive *);
+__LA_DECL int archive_write_set_format_iso9660(struct archive *);
+__LA_DECL int archive_write_set_format_mtree(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_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_xar(struct archive *);
+__LA_DECL int archive_write_set_format_zip(struct archive *);
+__LA_DECL int archive_write_open(struct archive *, void *,
+ archive_open_callback *, archive_write_callback *,
+ archive_close_callback *);
+__LA_DECL int archive_write_open_fd(struct archive *, int _fd);
+__LA_DECL int archive_write_open_filename(struct archive *, const char *_file);
+__LA_DECL int archive_write_open_filename_w(struct archive *,
+ const wchar_t *_file);
+/* A deprecated synonym for archive_write_open_filename() */
+__LA_DECL int archive_write_open_file(struct archive *, const char *_file);
+__LA_DECL int archive_write_open_FILE(struct archive *, FILE *);
+/* _buffSize is the size of the buffer, _used refers to a variable that
+ * will be updated after each write into the buffer. */
+__LA_DECL int archive_write_open_memory(struct archive *,
+ void *_buffer, size_t _buffSize, size_t *_used);
+
+/*
+ * Note that the library will truncate writes beyond the size provided
+ * to archive_write_header or pad if the provided data is short.
+ */
+__LA_DECL int archive_write_header(struct archive *,
+ struct archive_entry *);
+__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 int archive_write_finish_entry(struct archive *);
+__LA_DECL int archive_write_close(struct archive *);
+/* This can fail if the archive wasn't already closed, in which case
+ * archive_write_free() will implicitly call archive_write_close(). */
+__LA_DECL int archive_write_free(struct archive *);
+#if ARCHIVE_VERSION_NUMBER < 4000000
+/* Synonym for archive_write_free() for backwards compatibility. */
+__LA_DECL int archive_write_finish(struct archive *);
+#endif
+
+/*
+ * Set write options.
+ */
+/* Apply option to the format only. */
+__LA_DECL int archive_write_set_format_option(struct archive *_a,
+ const char *m, const char *o,
+ const char *v);
+/* Apply option to the filter only. */
+__LA_DECL int archive_write_set_filter_option(struct archive *_a,
+ const char *m, const char *o,
+ const char *v);
+/* Apply option to both the format and the filter. */
+__LA_DECL int archive_write_set_option(struct archive *_a,
+ const char *m, const char *o,
+ const char *v);
+/* Apply option string to both the format and the filter. */
+__LA_DECL int archive_write_set_options(struct archive *_a,
+ const char *opts);
+
+/*-
+ * ARCHIVE_WRITE_DISK API
+ *
+ * To create objects on disk:
+ * 1) Ask archive_write_disk_new for a new archive_write_disk object.
+ * 2) Set any global properties. In particular, you probably
+ * want to set the options.
+ * 3) For each entry:
+ * - construct an appropriate struct archive_entry structure
+ * - archive_write_header to create the file/dir/etc on disk
+ * - archive_write_data to write the entry data
+ * 4) archive_write_free to cleanup the writer and release resources
+ *
+ * In particular, you can use this in conjunction with archive_read()
+ * to pull entries out of an archive and create them on disk.
+ */
+__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);
+/* 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 *,
+ int flags);
+/*
+ * The lookup functions are given uname/uid (or gname/gid) pairs and
+ * return a uid (gid) suitable for this system. These are used for
+ * restoring ownership and for setting ACLs. The default functions
+ * are naive, they just return the uid/gid. These are small, so reasonable
+ * for applications that don't need to preserve ownership; they
+ * are probably also appropriate for applications that are doing
+ * same-system backup and restore.
+ */
+/*
+ * The "standard" lookup functions use common system calls to lookup
+ * the uname/gname, falling back to the uid/gid if the names can't be
+ * found. They cache lookups and are reasonably fast, but can be very
+ * large, so they are not used unless you ask for them. In
+ * particular, these match the specifications of POSIX "pax" and old
+ * POSIX "tar".
+ */
+__LA_DECL int archive_write_disk_set_standard_lookup(struct archive *);
+/*
+ * If neither the default (naive) nor the standard (big) functions suit
+ * your needs, you can write your own and register them. Be sure to
+ * include a cleanup function if you have allocated private data.
+ */
+__LA_DECL int archive_write_disk_set_group_lookup(struct archive *,
+ void * /* private_data */,
+ __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),
+ 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);
+
+/*
+ * ARCHIVE_READ_DISK API
+ *
+ * This is still evolving and somewhat experimental.
+ */
+__LA_DECL struct archive *archive_read_disk_new(void);
+/* The names for symlink modes here correspond to an old BSD
+ * command-line argument convention: -L, -P, -H */
+/* Follow all symlinks. */
+__LA_DECL int archive_read_disk_set_symlink_logical(struct archive *);
+/* Follow no symlinks. */
+__LA_DECL int archive_read_disk_set_symlink_physical(struct archive *);
+/* Follow symlink initially, then not. */
+__LA_DECL int archive_read_disk_set_symlink_hybrid(struct archive *);
+/* TODO: Handle Linux stat32/stat64 ugliness. <sigh> */
+__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);
+/* "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),
+ 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),
+ void (* /* cleanup_fn */)(void *));
+/* Start traversal. */
+__LA_DECL int archive_read_disk_open(struct archive *, const char *);
+__LA_DECL int archive_read_disk_open_w(struct archive *, const wchar_t *);
+/*
+ * Request that current entry be visited. If you invoke it on every
+ * directory, you'll get a physical traversal. This is ignored if the
+ * current entry isn't a directory or a link to a directory. So, if
+ * you invoke this on every returned path, you'll get a full logical
+ * traversal.
+ */
+__LA_DECL int archive_read_disk_descend(struct archive *);
+__LA_DECL int archive_read_disk_current_filesystem(struct archive *);
+__LA_DECL int archive_read_disk_current_filesystem_is_synthetic(struct archive *);
+__LA_DECL int archive_read_disk_current_filesystem_is_remote(struct archive *);
+/* Request that the access time of the entry visited by travesal be restored. */
+__LA_DECL int archive_read_disk_set_atime_restored(struct archive *);
+
+/*
+ * Accessor functions to read/set various information in
+ * the struct archive object:
+ */
+
+/* Number of filters in the current filter pipeline. */
+/* Filter #0 is the one closest to the format, -1 is a synonym for the
+ * 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 int archive_filter_code(struct archive *, int);
+__LA_DECL const char * archive_filter_name(struct archive *, int);
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+/* 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 *);
+/* 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 *);
+/* As of libarchive 3.0, this is an alias for archive_filter_name(a, 0); */
+__LA_DECL const char *archive_compression_name(struct archive *);
+/* As of libarchive 3.0, this is an alias for archive_filter_code(a, 0); */
+__LA_DECL int archive_compression(struct archive *);
+#endif
+
+__LA_DECL int archive_errno(struct archive *);
+__LA_DECL const char *archive_error_string(struct archive *);
+__LA_DECL const char *archive_format_name(struct archive *);
+__LA_DECL int archive_format(struct archive *);
+__LA_DECL void archive_clear_error(struct archive *);
+__LA_DECL void archive_set_error(struct archive *, int _err,
+ const char *fmt, ...) __LA_PRINTF(3, 4);
+__LA_DECL void archive_copy_error(struct archive *dest,
+ struct archive *src);
+__LA_DECL int archive_file_count(struct archive *);
+
+#ifdef __cplusplus
+}
+#endif
+
+/* These are meaningless outside of this header. */
+#undef __LA_DECL
+#undef __LA_GID_T
+#undef __LA_UID_T
+
+/* 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_acl.c b/Utilities/cmlibarchive/libarchive/archive_acl.c
new file mode 100644
index 000000000..4747a4c5a
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_acl.c
@@ -0,0 +1,1264 @@
+/*-
+ * Copyright (c) 2003-2010 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$");
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifdef HAVE_WCHAR_H
+#include <wchar.h>
+#endif
+
+#include "archive_acl_private.h"
+#include "archive_entry.h"
+#include "archive_private.h"
+
+#undef max
+#define max(a, b) ((a)>(b)?(a):(b))
+
+#ifndef HAVE_WMEMCMP
+/* Good enough for simple equality testing, but not for sorting. */
+#define wmemcmp(a,b,i) memcmp((a), (b), (i) * sizeof(wchar_t))
+#endif
+
+static int acl_special(struct archive_acl *acl,
+ int type, int permset, int tag);
+static struct archive_acl_entry *acl_new_entry(struct archive_acl *acl,
+ int type, int permset, int tag, int id);
+static int isint_w(const wchar_t *start, const wchar_t *end, int *result);
+static int ismode_w(const wchar_t *start, const wchar_t *end, int *result);
+static void next_field_w(const wchar_t **wp, const wchar_t **start,
+ const wchar_t **end, wchar_t *sep);
+static int prefix_w(const wchar_t *start, const wchar_t *end,
+ const wchar_t *test);
+static void append_entry_w(wchar_t **wp, const wchar_t *prefix, int tag,
+ const wchar_t *wname, int perm, int id);
+static void append_id_w(wchar_t **wp, int id);
+static int isint(const char *start, const char *end, int *result);
+static int ismode(const char *start, const char *end, int *result);
+static void next_field(const char **p, const char **start,
+ const char **end, char *sep);
+static int prefix(const char *start, const char *end,
+ const char *test);
+static void append_entry(char **p, const char *prefix, int tag,
+ const char *name, int perm, int id);
+static void append_id(char **p, int id);
+
+void
+archive_acl_clear(struct archive_acl *acl)
+{
+ struct archive_acl_entry *ap;
+
+ while (acl->acl_head != NULL) {
+ ap = acl->acl_head->next;
+ archive_mstring_clean(&acl->acl_head->name);
+ free(acl->acl_head);
+ acl->acl_head = ap;
+ }
+ if (acl->acl_text_w != NULL) {
+ free(acl->acl_text_w);
+ acl->acl_text_w = NULL;
+ }
+ if (acl->acl_text != NULL) {
+ free(acl->acl_text);
+ acl->acl_text = NULL;
+ }
+ acl->acl_p = NULL;
+ acl->acl_state = 0; /* Not counting. */
+}
+
+void
+archive_acl_copy(struct archive_acl *dest, struct archive_acl *src)
+{
+ struct archive_acl_entry *ap, *ap2;
+
+ archive_acl_clear(dest);
+
+ dest->mode = src->mode;
+ ap = src->acl_head;
+ while (ap != NULL) {
+ ap2 = acl_new_entry(dest,
+ ap->type, ap->permset, ap->tag, ap->id);
+ if (ap2 != NULL)
+ archive_mstring_copy(&ap2->name, &ap->name);
+ ap = ap->next;
+ }
+}
+
+int
+archive_acl_add_entry(struct archive_acl *acl,
+ int type, int permset, int tag, int id, const char *name)
+{
+ struct archive_acl_entry *ap;
+
+ if (acl_special(acl, type, permset, tag) == 0)
+ return ARCHIVE_OK;
+ ap = acl_new_entry(acl, type, permset, tag, id);
+ if (ap == NULL) {
+ /* XXX Error XXX */
+ return ARCHIVE_FAILED;
+ }
+ if (name != NULL && *name != '\0')
+ archive_mstring_copy_mbs(&ap->name, name);
+ else
+ archive_mstring_clean(&ap->name);
+ return ARCHIVE_OK;
+}
+
+int
+archive_acl_add_entry_w_len(struct archive_acl *acl,
+ int type, int permset, int tag, int id, const wchar_t *name, size_t len)
+{
+ struct archive_acl_entry *ap;
+
+ if (acl_special(acl, type, permset, tag) == 0)
+ return ARCHIVE_OK;
+ ap = acl_new_entry(acl, type, permset, tag, id);
+ if (ap == NULL) {
+ /* XXX Error XXX */
+ return ARCHIVE_FAILED;
+ }
+ if (name != NULL && *name != L'\0' && len > 0)
+ archive_mstring_copy_wcs_len(&ap->name, name, len);
+ else
+ archive_mstring_clean(&ap->name);
+ return ARCHIVE_OK;
+}
+
+int
+archive_acl_add_entry_len_l(struct archive_acl *acl,
+ int type, int permset, int tag, int id, const char *name, size_t len,
+ struct archive_string_conv *sc)
+{
+ struct archive_acl_entry *ap;
+ int r;
+
+ if (acl_special(acl, type, permset, tag) == 0)
+ return ARCHIVE_OK;
+ ap = acl_new_entry(acl, type, permset, tag, id);
+ if (ap == NULL) {
+ /* XXX Error XXX */
+ return ARCHIVE_FAILED;
+ }
+ if (name != NULL && *name != '\0' && len > 0) {
+ r = archive_mstring_copy_mbs_len_l(&ap->name, name, len, sc);
+ } else {
+ r = 0;
+ archive_mstring_clean(&ap->name);
+ }
+ if (r == 0)
+ return (ARCHIVE_OK);
+ else if (errno == ENOMEM)
+ return (ARCHIVE_FATAL);
+ else
+ return (ARCHIVE_WARN);
+}
+
+/*
+ * If this ACL entry is part of the standard POSIX permissions set,
+ * store the permissions in the stat structure and return zero.
+ */
+static int
+acl_special(struct archive_acl *acl, int type, int permset, int tag)
+{
+ if (type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS
+ && ((permset & ~007) == 0)) {
+ switch (tag) {
+ case ARCHIVE_ENTRY_ACL_USER_OBJ:
+ acl->mode &= ~0700;
+ acl->mode |= (permset & 7) << 6;
+ return (0);
+ case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
+ acl->mode &= ~0070;
+ acl->mode |= (permset & 7) << 3;
+ return (0);
+ case ARCHIVE_ENTRY_ACL_OTHER:
+ acl->mode &= ~0007;
+ acl->mode |= permset & 7;
+ return (0);
+ }
+ }
+ return (1);
+}
+
+/*
+ * Allocate and populate a new ACL entry with everything but the
+ * name.
+ */
+static struct archive_acl_entry *
+acl_new_entry(struct archive_acl *acl,
+ int type, int permset, int tag, int id)
+{
+ struct archive_acl_entry *ap, *aq;
+
+ /* Type argument must be a valid NFS4 or POSIX.1e type.
+ * The type must agree with anything already set and
+ * the permset must be compatible. */
+ if (type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
+ if (acl->acl_types & ~ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
+ return (NULL);
+ }
+ if (permset &
+ ~(ARCHIVE_ENTRY_ACL_PERMS_NFS4
+ | ARCHIVE_ENTRY_ACL_INHERITANCE_NFS4)) {
+ return (NULL);
+ }
+ } else if (type & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) {
+ if (acl->acl_types & ~ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) {
+ return (NULL);
+ }
+ if (permset & ~ARCHIVE_ENTRY_ACL_PERMS_POSIX1E) {
+ return (NULL);
+ }
+ } else {
+ return (NULL);
+ }
+
+ /* Verify the tag is valid and compatible with NFS4 or POSIX.1e. */
+ switch (tag) {
+ case ARCHIVE_ENTRY_ACL_USER:
+ case ARCHIVE_ENTRY_ACL_USER_OBJ:
+ case ARCHIVE_ENTRY_ACL_GROUP:
+ case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
+ /* Tags valid in both NFS4 and POSIX.1e */
+ break;
+ case ARCHIVE_ENTRY_ACL_MASK:
+ case ARCHIVE_ENTRY_ACL_OTHER:
+ /* Tags valid only in POSIX.1e. */
+ if (type & ~ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) {
+ return (NULL);
+ }
+ break;
+ case ARCHIVE_ENTRY_ACL_EVERYONE:
+ /* Tags valid only in NFS4. */
+ if (type & ~ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
+ return (NULL);
+ }
+ break;
+ default:
+ /* No other values are valid. */
+ return (NULL);
+ }
+
+ if (acl->acl_text_w != NULL) {
+ free(acl->acl_text_w);
+ acl->acl_text_w = NULL;
+ }
+ if (acl->acl_text != NULL) {
+ free(acl->acl_text);
+ acl->acl_text = NULL;
+ }
+
+ /* If there's a matching entry already in the list, overwrite it. */
+ ap = acl->acl_head;
+ aq = NULL;
+ while (ap != NULL) {
+ if (ap->type == type && ap->tag == tag && ap->id == id) {
+ ap->permset = permset;
+ return (ap);
+ }
+ aq = ap;
+ ap = ap->next;
+ }
+
+ /* Add a new entry to the end of the list. */
+ ap = (struct archive_acl_entry *)malloc(sizeof(*ap));
+ if (ap == NULL)
+ return (NULL);
+ memset(ap, 0, sizeof(*ap));
+ if (aq == NULL)
+ acl->acl_head = ap;
+ else
+ aq->next = ap;
+ ap->type = type;
+ ap->tag = tag;
+ ap->id = id;
+ ap->permset = permset;
+ acl->acl_types |= type;
+ return (ap);
+}
+
+/*
+ * Return a count of entries matching "want_type".
+ */
+int
+archive_acl_count(struct archive_acl *acl, int want_type)
+{
+ int count;
+ struct archive_acl_entry *ap;
+
+ count = 0;
+ ap = acl->acl_head;
+ while (ap != NULL) {
+ if ((ap->type & want_type) != 0)
+ count++;
+ ap = ap->next;
+ }
+
+ if (count > 0 && ((want_type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0))
+ count += 3;
+ return (count);
+}
+
+/*
+ * Prepare for reading entries from the ACL data. Returns a count
+ * of entries matching "want_type", or zero if there are no
+ * non-extended ACL entries of that type.
+ */
+int
+archive_acl_reset(struct archive_acl *acl, int want_type)
+{
+ int count, cutoff;
+
+ count = archive_acl_count(acl, want_type);
+
+ /*
+ * If the only entries are the three standard ones,
+ * then don't return any ACL data. (In this case,
+ * client can just use chmod(2) to set permissions.)
+ */
+ if ((want_type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0)
+ cutoff = 3;
+ else
+ cutoff = 0;
+
+ if (count > cutoff)
+ acl->acl_state = ARCHIVE_ENTRY_ACL_USER_OBJ;
+ else
+ acl->acl_state = 0;
+ acl->acl_p = acl->acl_head;
+ return (count);
+}
+
+
+/*
+ * Return the next ACL entry in the list. Fake entries for the
+ * standard permissions and include them in the returned list.
+ */
+int
+archive_acl_next(struct archive *a, struct archive_acl *acl, int want_type, int *type,
+ int *permset, int *tag, int *id, const char **name)
+{
+ *name = NULL;
+ *id = -1;
+
+ /*
+ * The acl_state is either zero (no entries available), -1
+ * (reading from list), or an entry type (retrieve that type
+ * from ae_stat.aest_mode).
+ */
+ if (acl->acl_state == 0)
+ return (ARCHIVE_WARN);
+
+ /* The first three access entries are special. */
+ if ((want_type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
+ switch (acl->acl_state) {
+ case ARCHIVE_ENTRY_ACL_USER_OBJ:
+ *permset = (acl->mode >> 6) & 7;
+ *type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
+ *tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
+ acl->acl_state = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
+ return (ARCHIVE_OK);
+ case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
+ *permset = (acl->mode >> 3) & 7;
+ *type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
+ *tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
+ acl->acl_state = ARCHIVE_ENTRY_ACL_OTHER;
+ return (ARCHIVE_OK);
+ case ARCHIVE_ENTRY_ACL_OTHER:
+ *permset = acl->mode & 7;
+ *type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
+ *tag = ARCHIVE_ENTRY_ACL_OTHER;
+ acl->acl_state = -1;
+ acl->acl_p = acl->acl_head;
+ return (ARCHIVE_OK);
+ default:
+ break;
+ }
+ }
+
+ while (acl->acl_p != NULL && (acl->acl_p->type & want_type) == 0)
+ acl->acl_p = acl->acl_p->next;
+ if (acl->acl_p == NULL) {
+ acl->acl_state = 0;
+ *type = 0;
+ *permset = 0;
+ *tag = 0;
+ *id = -1;
+ *name = NULL;
+ return (ARCHIVE_EOF); /* End of ACL entries. */
+ }
+ *type = acl->acl_p->type;
+ *permset = acl->acl_p->permset;
+ *tag = acl->acl_p->tag;
+ *id = acl->acl_p->id;
+ if (archive_mstring_get_mbs(a, &acl->acl_p->name, name) != 0)
+ *name = NULL;
+ acl->acl_p = acl->acl_p->next;
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Generate a text version of the ACL. The flags parameter controls
+ * the style of the generated ACL.
+ */
+const wchar_t *
+archive_acl_text_w(struct archive *a, struct archive_acl *acl, int flags)
+{
+ int count;
+ size_t length;
+ const wchar_t *wname;
+ const wchar_t *prefix;
+ wchar_t separator;
+ struct archive_acl_entry *ap;
+ int id;
+ wchar_t *wp;
+
+ if (acl->acl_text_w != NULL) {
+ free (acl->acl_text_w);
+ acl->acl_text_w = NULL;
+ }
+
+ separator = L',';
+ count = 0;
+ length = 0;
+ ap = acl->acl_head;
+ while (ap != NULL) {
+ if ((ap->type & flags) != 0) {
+ count++;
+ if ((flags & ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT) &&
+ (ap->type & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT))
+ length += 8; /* "default:" */
+ length += 5; /* tag name */
+ length += 1; /* colon */
+ if (archive_mstring_get_wcs(a, &ap->name, &wname) == 0 &&
+ wname != NULL)
+ length += wcslen(wname);
+ else
+ length += sizeof(uid_t) * 3 + 1;
+ length ++; /* colon */
+ length += 3; /* rwx */
+ length += 1; /* colon */
+ length += max(sizeof(uid_t), sizeof(gid_t)) * 3 + 1;
+ length ++; /* newline */
+ }
+ ap = ap->next;
+ }
+
+ if (count > 0 && ((flags & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0)) {
+ length += 10; /* "user::rwx\n" */
+ length += 11; /* "group::rwx\n" */
+ length += 11; /* "other::rwx\n" */
+ }
+
+ if (count == 0)
+ return (NULL);
+
+ /* Now, allocate the string and actually populate it. */
+ wp = acl->acl_text_w = (wchar_t *)malloc(length * sizeof(wchar_t));
+ if (wp == NULL)
+ __archive_errx(1, "No memory to generate the text version of the ACL");
+ count = 0;
+ if ((flags & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
+ append_entry_w(&wp, NULL, ARCHIVE_ENTRY_ACL_USER_OBJ, NULL,
+ acl->mode & 0700, -1);
+ *wp++ = ',';
+ append_entry_w(&wp, NULL, ARCHIVE_ENTRY_ACL_GROUP_OBJ, NULL,
+ acl->mode & 0070, -1);
+ *wp++ = ',';
+ append_entry_w(&wp, NULL, ARCHIVE_ENTRY_ACL_OTHER, NULL,
+ acl->mode & 0007, -1);
+ count += 3;
+
+ ap = acl->acl_head;
+ while (ap != NULL) {
+ if ((ap->type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0 &&
+ archive_mstring_get_wcs(a, &ap->name, &wname) == 0) {
+ *wp++ = separator;
+ if (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID)
+ id = ap->id;
+ else
+ id = -1;
+ append_entry_w(&wp, NULL, ap->tag, wname,
+ ap->permset, id);
+ count++;
+ }
+ ap = ap->next;
+ }
+ }
+
+
+ if ((flags & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0) {
+ if (flags & ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT)
+ prefix = L"default:";
+ else
+ prefix = NULL;
+ ap = acl->acl_head;
+ count = 0;
+ while (ap != NULL) {
+ if ((ap->type & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0 &&
+ archive_mstring_get_wcs(a, &ap->name, &wname) == 0) {
+ if (count > 0)
+ *wp++ = separator;
+ if (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID)
+ id = ap->id;
+ else
+ id = -1;
+ append_entry_w(&wp, prefix, ap->tag,
+ wname, ap->permset, id);
+ count ++;
+ }
+ ap = ap->next;
+ }
+ }
+
+ return (acl->acl_text_w);
+}
+
+
+static void
+append_id_w(wchar_t **wp, int id)
+{
+ if (id < 0)
+ id = 0;
+ if (id > 9)
+ append_id_w(wp, id / 10);
+ *(*wp)++ = L"0123456789"[id % 10];
+}
+
+static void
+append_entry_w(wchar_t **wp, const wchar_t *prefix, int tag,
+ const wchar_t *wname, int perm, int id)
+{
+ if (prefix != NULL) {
+ wcscpy(*wp, prefix);
+ *wp += wcslen(*wp);
+ }
+ switch (tag) {
+ case ARCHIVE_ENTRY_ACL_USER_OBJ:
+ wname = NULL;
+ id = -1;
+ /* FALLTHROUGH */
+ case ARCHIVE_ENTRY_ACL_USER:
+ wcscpy(*wp, L"user");
+ break;
+ case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
+ wname = NULL;
+ id = -1;
+ /* FALLTHROUGH */
+ case ARCHIVE_ENTRY_ACL_GROUP:
+ wcscpy(*wp, L"group");
+ break;
+ case ARCHIVE_ENTRY_ACL_MASK:
+ wcscpy(*wp, L"mask");
+ wname = NULL;
+ id = -1;
+ break;
+ case ARCHIVE_ENTRY_ACL_OTHER:
+ wcscpy(*wp, L"other");
+ wname = NULL;
+ id = -1;
+ break;
+ }
+ *wp += wcslen(*wp);
+ *(*wp)++ = L':';
+ if (wname != NULL) {
+ wcscpy(*wp, wname);
+ *wp += wcslen(*wp);
+ } else if (tag == ARCHIVE_ENTRY_ACL_USER
+ || tag == ARCHIVE_ENTRY_ACL_GROUP) {
+ append_id_w(wp, id);
+ id = -1;
+ }
+ *(*wp)++ = L':';
+ *(*wp)++ = (perm & 0444) ? L'r' : L'-';
+ *(*wp)++ = (perm & 0222) ? L'w' : L'-';
+ *(*wp)++ = (perm & 0111) ? L'x' : L'-';
+ if (id != -1) {
+ *(*wp)++ = L':';
+ append_id_w(wp, id);
+ }
+ **wp = L'\0';
+}
+
+int
+archive_acl_text_l(struct archive_acl *acl, int flags,
+ const char **acl_text, size_t *acl_text_len,
+ struct archive_string_conv *sc)
+{
+ int count;
+ size_t length;
+ const char *name;
+ const char *prefix;
+ char separator;
+ struct archive_acl_entry *ap;
+ size_t len;
+ int id, r;
+ char *p;
+
+ if (acl->acl_text != NULL) {
+ free (acl->acl_text);
+ acl->acl_text = NULL;
+ }
+
+ *acl_text = NULL;
+ if (acl_text_len != NULL)
+ *acl_text_len = 0;
+ separator = ',';
+ count = 0;
+ length = 0;
+ ap = acl->acl_head;
+ while (ap != NULL) {
+ if ((ap->type & flags) != 0) {
+ count++;
+ if ((flags & ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT) &&
+ (ap->type & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT))
+ length += 8; /* "default:" */
+ length += 5; /* tag name */
+ length += 1; /* colon */
+ r = archive_mstring_get_mbs_l(
+ &ap->name, &name, &len, sc);
+ if (r != 0)
+ return (-1);
+ if (len > 0 && name != NULL)
+ length += len;
+ else
+ length += sizeof(uid_t) * 3 + 1;
+ length ++; /* colon */
+ length += 3; /* rwx */
+ length += 1; /* colon */
+ length += max(sizeof(uid_t), sizeof(gid_t)) * 3 + 1;
+ length ++; /* newline */
+ }
+ ap = ap->next;
+ }
+
+ if (count > 0 && ((flags & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0)) {
+ length += 10; /* "user::rwx\n" */
+ length += 11; /* "group::rwx\n" */
+ length += 11; /* "other::rwx\n" */
+ }
+
+ if (count == 0)
+ return (0);
+
+ /* Now, allocate the string and actually populate it. */
+ p = acl->acl_text = (char *)malloc(length);
+ if (p == NULL)
+ __archive_errx(1, "No memory to generate the text version of the ACL");
+ count = 0;
+ if ((flags & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
+ append_entry(&p, NULL, ARCHIVE_ENTRY_ACL_USER_OBJ, NULL,
+ acl->mode & 0700, -1);
+ *p++ = ',';
+ append_entry(&p, NULL, ARCHIVE_ENTRY_ACL_GROUP_OBJ, NULL,
+ acl->mode & 0070, -1);
+ *p++ = ',';
+ append_entry(&p, NULL, ARCHIVE_ENTRY_ACL_OTHER, NULL,
+ acl->mode & 0007, -1);
+ count += 3;
+
+ for (ap = acl->acl_head; ap != NULL; ap = ap->next) {
+ if ((ap->type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) == 0)
+ continue;
+ r = archive_mstring_get_mbs_l(
+ &ap->name, &name, &len, sc);
+ if (r != 0)
+ return (-1);
+ *p++ = separator;
+ if (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID)
+ id = ap->id;
+ else
+ id = -1;
+ append_entry(&p, NULL, ap->tag, name,
+ ap->permset, id);
+ count++;
+ }
+ }
+
+
+ if ((flags & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0) {
+ if (flags & ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT)
+ prefix = "default:";
+ else
+ prefix = NULL;
+ count = 0;
+ for (ap = acl->acl_head; ap != NULL; ap = ap->next) {
+ if ((ap->type & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) == 0)
+ continue;
+ r = archive_mstring_get_mbs_l(
+ &ap->name, &name, &len, sc);
+ if (r != 0)
+ return (-1);
+ if (count > 0)
+ *p++ = separator;
+ if (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID)
+ id = ap->id;
+ else
+ id = -1;
+ append_entry(&p, prefix, ap->tag,
+ name, ap->permset, id);
+ count ++;
+ }
+ }
+
+ *acl_text = acl->acl_text;
+ if (acl_text_len != NULL)
+ *acl_text_len = strlen(acl->acl_text);
+ return (0);
+}
+
+static void
+append_id(char **p, int id)
+{
+ if (id < 0)
+ id = 0;
+ if (id > 9)
+ append_id(p, id / 10);
+ *(*p)++ = "0123456789"[id % 10];
+}
+
+static void
+append_entry(char **p, const char *prefix, int tag,
+ const char *name, int perm, int id)
+{
+ if (prefix != NULL) {
+ strcpy(*p, prefix);
+ *p += strlen(*p);
+ }
+ switch (tag) {
+ case ARCHIVE_ENTRY_ACL_USER_OBJ:
+ name = NULL;
+ id = -1;
+ /* FALLTHROUGH */
+ case ARCHIVE_ENTRY_ACL_USER:
+ strcpy(*p, "user");
+ break;
+ case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
+ name = NULL;
+ id = -1;
+ /* FALLTHROUGH */
+ case ARCHIVE_ENTRY_ACL_GROUP:
+ strcpy(*p, "group");
+ break;
+ case ARCHIVE_ENTRY_ACL_MASK:
+ strcpy(*p, "mask");
+ name = NULL;
+ id = -1;
+ break;
+ case ARCHIVE_ENTRY_ACL_OTHER:
+ strcpy(*p, "other");
+ name = NULL;
+ id = -1;
+ break;
+ }
+ *p += strlen(*p);
+ *(*p)++ = ':';
+ if (name != NULL) {
+ strcpy(*p, name);
+ *p += strlen(*p);
+ } else if (tag == ARCHIVE_ENTRY_ACL_USER
+ || tag == ARCHIVE_ENTRY_ACL_GROUP) {
+ append_id(p, id);
+ id = -1;
+ }
+ *(*p)++ = ':';
+ *(*p)++ = (perm & 0444) ? 'r' : '-';
+ *(*p)++ = (perm & 0222) ? 'w' : '-';
+ *(*p)++ = (perm & 0111) ? 'x' : '-';
+ if (id != -1) {
+ *(*p)++ = ':';
+ append_id(p, id);
+ }
+ **p = '\0';
+}
+
+/*
+ * Parse a textual ACL. This automatically recognizes and supports
+ * extensions described above. The 'type' argument is used to
+ * indicate the type that should be used for any entries not
+ * explicitly marked as "default:".
+ */
+int
+archive_acl_parse_w(struct archive_acl *acl,
+ const wchar_t *text, int default_type)
+{
+ struct {
+ const wchar_t *start;
+ const wchar_t *end;
+ } field[4], name;
+
+ int fields, n;
+ int type, tag, permset, id;
+ wchar_t sep;
+
+ while (text != NULL && *text != L'\0') {
+ /*
+ * Parse the fields out of the next entry,
+ * advance 'text' to start of next entry.
+ */
+ fields = 0;
+ do {
+ const wchar_t *start, *end;
+ next_field_w(&text, &start, &end, &sep);
+ if (fields < 4) {
+ field[fields].start = start;
+ field[fields].end = end;
+ }
+ ++fields;
+ } while (sep == L':');
+
+ /* Set remaining fields to blank. */
+ for (n = fields; n < 4; ++n)
+ field[n].start = field[n].end = NULL;
+
+ /* Check for a numeric ID in field 1 or 3. */
+ id = -1;
+ isint_w(field[1].start, field[1].end, &id);
+ /* Field 3 is optional. */
+ if (id == -1 && fields > 3)
+ isint_w(field[3].start, field[3].end, &id);
+
+ /*
+ * Solaris extension: "defaultuser::rwx" is the
+ * default ACL corresponding to "user::rwx", etc.
+ */
+ if (field[0].end - field[0].start > 7
+ && wmemcmp(field[0].start, L"default", 7) == 0) {
+ type = ARCHIVE_ENTRY_ACL_TYPE_DEFAULT;
+ field[0].start += 7;
+ } else
+ type = default_type;
+
+ name.start = name.end = NULL;
+ if (prefix_w(field[0].start, field[0].end, L"user")) {
+ if (!ismode_w(field[2].start, field[2].end, &permset))
+ return (ARCHIVE_WARN);
+ if (id != -1 || field[1].start < field[1].end) {
+ tag = ARCHIVE_ENTRY_ACL_USER;
+ name = field[1];
+ } else
+ tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
+ } else if (prefix_w(field[0].start, field[0].end, L"group")) {
+ if (!ismode_w(field[2].start, field[2].end, &permset))
+ return (ARCHIVE_WARN);
+ if (id != -1 || field[1].start < field[1].end) {
+ tag = ARCHIVE_ENTRY_ACL_GROUP;
+ name = field[1];
+ } else
+ tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
+ } else if (prefix_w(field[0].start, field[0].end, L"other")) {
+ if (fields == 2
+ && field[1].start < field[1].end
+ && ismode_w(field[1].start, field[1].end, &permset)) {
+ /* This is Solaris-style "other:rwx" */
+ } else if (fields == 3
+ && field[1].start == field[1].end
+ && field[2].start < field[2].end
+ && ismode_w(field[2].start, field[2].end, &permset)) {
+ /* This is FreeBSD-style "other::rwx" */
+ } else
+ return (ARCHIVE_WARN);
+ tag = ARCHIVE_ENTRY_ACL_OTHER;
+ } else if (prefix_w(field[0].start, field[0].end, L"mask")) {
+ if (fields == 2
+ && field[1].start < field[1].end
+ && ismode_w(field[1].start, field[1].end, &permset)) {
+ /* This is Solaris-style "mask:rwx" */
+ } else if (fields == 3
+ && field[1].start == field[1].end
+ && field[2].start < field[2].end
+ && ismode_w(field[2].start, field[2].end, &permset)) {
+ /* This is FreeBSD-style "mask::rwx" */
+ } else
+ return (ARCHIVE_WARN);
+ tag = ARCHIVE_ENTRY_ACL_MASK;
+ } else
+ return (ARCHIVE_WARN);
+
+ /* Add entry to the internal list. */
+ archive_acl_add_entry_w_len(acl, type, permset,
+ tag, id, name.start, name.end - name.start);
+ }
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Parse a string to a positive decimal integer. Returns true if
+ * the string is non-empty and consists only of decimal digits,
+ * false otherwise.
+ */
+static int
+isint_w(const wchar_t *start, const wchar_t *end, int *result)
+{
+ int n = 0;
+ if (start >= end)
+ return (0);
+ while (start < end) {
+ if (*start < '0' || *start > '9')
+ return (0);
+ if (n > (INT_MAX / 10) ||
+ (n == INT_MAX / 10 && (*start - '0') > INT_MAX % 10)) {
+ n = INT_MAX;
+ } else {
+ n *= 10;
+ n += *start - '0';
+ }
+ start++;
+ }
+ *result = n;
+ return (1);
+}
+
+/*
+ * Parse a string as a mode field. Returns true if
+ * the string is non-empty and consists only of mode characters,
+ * false otherwise.
+ */
+static int
+ismode_w(const wchar_t *start, const wchar_t *end, int *permset)
+{
+ const wchar_t *p;
+
+ if (start >= end)
+ return (0);
+ p = start;
+ *permset = 0;
+ while (p < end) {
+ switch (*p++) {
+ case 'r': case 'R':
+ *permset |= ARCHIVE_ENTRY_ACL_READ;
+ break;
+ case 'w': case 'W':
+ *permset |= ARCHIVE_ENTRY_ACL_WRITE;
+ break;
+ case 'x': case 'X':
+ *permset |= ARCHIVE_ENTRY_ACL_EXECUTE;
+ break;
+ case '-':
+ break;
+ default:
+ return (0);
+ }
+ }
+ return (1);
+}
+
+/*
+ * Match "[:whitespace:]*(.*)[:whitespace:]*[:,\n]". *wp is updated
+ * to point to just after the separator. *start points to the first
+ * character of the matched text and *end just after the last
+ * character of the matched identifier. In particular *end - *start
+ * is the length of the field body, not including leading or trailing
+ * whitespace.
+ */
+static void
+next_field_w(const wchar_t **wp, const wchar_t **start,
+ const wchar_t **end, wchar_t *sep)
+{
+ /* Skip leading whitespace to find start of field. */
+ while (**wp == L' ' || **wp == L'\t' || **wp == L'\n') {
+ (*wp)++;
+ }
+ *start = *wp;
+
+ /* Scan for the separator. */
+ while (**wp != L'\0' && **wp != L',' && **wp != L':' &&
+ **wp != L'\n') {
+ (*wp)++;
+ }
+ *sep = **wp;
+
+ /* Trim trailing whitespace to locate end of field. */
+ *end = *wp - 1;
+ while (**end == L' ' || **end == L'\t' || **end == L'\n') {
+ (*end)--;
+ }
+ (*end)++;
+
+ /* Adjust scanner location. */
+ if (**wp != L'\0')
+ (*wp)++;
+}
+
+/*
+ * Return true if the characters [start...end) are a prefix of 'test'.
+ * This makes it easy to handle the obvious abbreviations: 'u' for 'user', etc.
+ */
+static int
+prefix_w(const wchar_t *start, const wchar_t *end, const wchar_t *test)
+{
+ if (start == end)
+ return (0);
+
+ if (*start++ != *test++)
+ return (0);
+
+ while (start < end && *start++ == *test++)
+ ;
+
+ if (start < end)
+ return (0);
+
+ return (1);
+}
+
+/*
+ * Parse a textual ACL. This automatically recognizes and supports
+ * extensions described above. The 'type' argument is used to
+ * indicate the type that should be used for any entries not
+ * explicitly marked as "default:".
+ */
+int
+archive_acl_parse_l(struct archive_acl *acl,
+ const char *text, int default_type, struct archive_string_conv *sc)
+{
+ struct {
+ const char *start;
+ const char *end;
+ } field[4], name;
+
+ int fields, n, r, ret = ARCHIVE_OK;
+ int type, tag, permset, id;
+ char sep;
+
+ while (text != NULL && *text != '\0') {
+ /*
+ * Parse the fields out of the next entry,
+ * advance 'text' to start of next entry.
+ */
+ fields = 0;
+ do {
+ const char *start, *end;
+ next_field(&text, &start, &end, &sep);
+ if (fields < 4) {
+ field[fields].start = start;
+ field[fields].end = end;
+ }
+ ++fields;
+ } while (sep == ':');
+
+ /* Set remaining fields to blank. */
+ for (n = fields; n < 4; ++n)
+ field[n].start = field[n].end = NULL;
+
+ /* Check for a numeric ID in field 1 or 3. */
+ id = -1;
+ isint(field[1].start, field[1].end, &id);
+ /* Field 3 is optional. */
+ if (id == -1 && fields > 3)
+ isint(field[3].start, field[3].end, &id);
+
+ /*
+ * Solaris extension: "defaultuser::rwx" is the
+ * default ACL corresponding to "user::rwx", etc.
+ */
+ if (field[0].end - field[0].start > 7
+ && memcmp(field[0].start, "default", 7) == 0) {
+ type = ARCHIVE_ENTRY_ACL_TYPE_DEFAULT;
+ field[0].start += 7;
+ } else
+ type = default_type;
+
+ name.start = name.end = NULL;
+ if (prefix(field[0].start, field[0].end, "user")) {
+ if (!ismode(field[2].start, field[2].end, &permset))
+ return (ARCHIVE_WARN);
+ if (id != -1 || field[1].start < field[1].end) {
+ tag = ARCHIVE_ENTRY_ACL_USER;
+ name = field[1];
+ } else
+ tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
+ } else if (prefix(field[0].start, field[0].end, "group")) {
+ if (!ismode(field[2].start, field[2].end, &permset))
+ return (ARCHIVE_WARN);
+ if (id != -1 || field[1].start < field[1].end) {
+ tag = ARCHIVE_ENTRY_ACL_GROUP;
+ name = field[1];
+ } else
+ tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
+ } else if (prefix(field[0].start, field[0].end, "other")) {
+ if (fields == 2
+ && field[1].start < field[1].end
+ && ismode(field[1].start, field[1].end, &permset)) {
+ /* This is Solaris-style "other:rwx" */
+ } else if (fields == 3
+ && field[1].start == field[1].end
+ && field[2].start < field[2].end
+ && ismode(field[2].start, field[2].end, &permset)) {
+ /* This is FreeBSD-style "other::rwx" */
+ } else
+ return (ARCHIVE_WARN);
+ tag = ARCHIVE_ENTRY_ACL_OTHER;
+ } else if (prefix(field[0].start, field[0].end, "mask")) {
+ if (fields == 2
+ && field[1].start < field[1].end
+ && ismode(field[1].start, field[1].end, &permset)) {
+ /* This is Solaris-style "mask:rwx" */
+ } else if (fields == 3
+ && field[1].start == field[1].end
+ && field[2].start < field[2].end
+ && ismode(field[2].start, field[2].end, &permset)) {
+ /* This is FreeBSD-style "mask::rwx" */
+ } else
+ return (ARCHIVE_WARN);
+ tag = ARCHIVE_ENTRY_ACL_MASK;
+ } else
+ return (ARCHIVE_WARN);
+
+ /* Add entry to the internal list. */
+ r = archive_acl_add_entry_len_l(acl, type, permset,
+ tag, id, name.start, name.end - name.start, sc);
+ if (r < ARCHIVE_WARN)
+ return (r);
+ if (r != ARCHIVE_OK)
+ ret = ARCHIVE_WARN;
+ }
+ return (ret);
+}
+
+/*
+ * Parse a string to a positive decimal integer. Returns true if
+ * the string is non-empty and consists only of decimal digits,
+ * false otherwise.
+ */
+static int
+isint(const char *start, const char *end, int *result)
+{
+ int n = 0;
+ if (start >= end)
+ return (0);
+ while (start < end) {
+ if (*start < '0' || *start > '9')
+ return (0);
+ if (n > (INT_MAX / 10) ||
+ (n == INT_MAX / 10 && (*start - '0') > INT_MAX % 10)) {
+ n = INT_MAX;
+ } else {
+ n *= 10;
+ n += *start - '0';
+ }
+ start++;
+ }
+ *result = n;
+ return (1);
+}
+
+/*
+ * Parse a string as a mode field. Returns true if
+ * the string is non-empty and consists only of mode characters,
+ * false otherwise.
+ */
+static int
+ismode(const char *start, const char *end, int *permset)
+{
+ const char *p;
+
+ if (start >= end)
+ return (0);
+ p = start;
+ *permset = 0;
+ while (p < end) {
+ switch (*p++) {
+ case 'r': case 'R':
+ *permset |= ARCHIVE_ENTRY_ACL_READ;
+ break;
+ case 'w': case 'W':
+ *permset |= ARCHIVE_ENTRY_ACL_WRITE;
+ break;
+ case 'x': case 'X':
+ *permset |= ARCHIVE_ENTRY_ACL_EXECUTE;
+ break;
+ case '-':
+ break;
+ default:
+ return (0);
+ }
+ }
+ return (1);
+}
+
+/*
+ * Match "[:whitespace:]*(.*)[:whitespace:]*[:,\n]". *wp is updated
+ * to point to just after the separator. *start points to the first
+ * character of the matched text and *end just after the last
+ * character of the matched identifier. In particular *end - *start
+ * is the length of the field body, not including leading or trailing
+ * whitespace.
+ */
+static void
+next_field(const char **p, const char **start,
+ const char **end, char *sep)
+{
+ /* Skip leading whitespace to find start of field. */
+ while (**p == ' ' || **p == '\t' || **p == '\n') {
+ (*p)++;
+ }
+ *start = *p;
+
+ /* Scan for the separator. */
+ while (**p != '\0' && **p != ',' && **p != ':' && **p != '\n') {
+ (*p)++;
+ }
+ *sep = **p;
+
+ /* Trim trailing whitespace to locate end of field. */
+ *end = *p - 1;
+ while (**end == ' ' || **end == '\t' || **end == '\n') {
+ (*end)--;
+ }
+ (*end)++;
+
+ /* Adjust scanner location. */
+ if (**p != '\0')
+ (*p)++;
+}
+
+/*
+ * Return true if the characters [start...end) are a prefix of 'test'.
+ * This makes it easy to handle the obvious abbreviations: 'u' for 'user', etc.
+ */
+static int
+prefix(const char *start, const char *end, const char *test)
+{
+ if (start == end)
+ return (0);
+
+ if (*start++ != *test++)
+ return (0);
+
+ while (start < end && *start++ == *test++)
+ ;
+
+ if (start < end)
+ return (0);
+
+ return (1);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_acl_private.h b/Utilities/cmlibarchive/libarchive/archive_acl_private.h
new file mode 100644
index 000000000..1421adbf8
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_acl_private.h
@@ -0,0 +1,87 @@
+/*-
+ * Copyright (c) 2003-2010 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __LIBARCHIVE_BUILD
+#error This header is only to be used internally to libarchive.
+#endif
+
+#ifndef ARCHIVE_ACL_PRIVATE_H_INCLUDED
+#define ARCHIVE_ACL_PRIVATE_H_INCLUDED
+
+#include "archive_string.h"
+
+struct archive_acl_entry {
+ struct archive_acl_entry *next;
+ int type; /* E.g., access or default */
+ int tag; /* E.g., user/group/other/mask */
+ int permset; /* r/w/x bits */
+ int id; /* uid/gid for user/group */
+ struct archive_mstring name; /* uname/gname */
+};
+
+struct archive_acl {
+ mode_t mode;
+ struct archive_acl_entry *acl_head;
+ struct archive_acl_entry *acl_p;
+ int acl_state; /* See acl_next for details. */
+ wchar_t *acl_text_w;
+ char *acl_text;
+ int acl_types;
+};
+
+void archive_acl_clear(struct archive_acl *);
+void archive_acl_copy(struct archive_acl *, struct archive_acl *);
+int archive_acl_count(struct archive_acl *, int);
+int archive_acl_reset(struct archive_acl *, int);
+int archive_acl_next(struct archive *, struct archive_acl *, int,
+ int *, int *, int *, int *, const char **);
+
+int archive_acl_add_entry(struct archive_acl *, int, int, int, int, const char *);
+int archive_acl_add_entry_w_len(struct archive_acl *,
+ int, int, int, int, const wchar_t *, size_t);
+int archive_acl_add_entry_len(struct archive_acl *,
+ int, int, int, int, const char *, size_t);
+
+const wchar_t *archive_acl_text_w(struct archive *, struct archive_acl *, int);
+int archive_acl_text_l(struct archive_acl *, int, const char **, size_t *,
+ struct archive_string_conv *);
+
+/*
+ * Private ACL parser. This is private because it handles some
+ * very weird formats that clients should not be messing with.
+ * Clients should only deal with their platform-native formats.
+ * Because of the need to support many formats cleanly, new arguments
+ * are likely to get added on a regular basis. Clients who try to use
+ * this interface are likely to be surprised when it changes.
+ */
+int archive_acl_parse_w(struct archive_acl *,
+ const wchar_t *, int /* type */);
+int archive_acl_parse_l(struct archive_acl *,
+ const char *, int /* type */,
+ struct archive_string_conv *);
+
+#endif /* ARCHIVE_ENTRY_PRIVATE_H_INCLUDED */
diff --git a/Utilities/cmlibarchive/libarchive/archive_check_magic.c b/Utilities/cmlibarchive/libarchive/archive_check_magic.c
new file mode 100644
index 000000000..91229557a
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_check_magic.c
@@ -0,0 +1,174 @@
+/*-
+ * Copyright (c) 2003-2010 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: head/lib/libarchive/archive_check_magic.c 201089 2009-12-28 02:20:23Z kientzle $");
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.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
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#include <windows.h>
+#include <winbase.h>
+#endif
+
+#include "archive_private.h"
+
+static void
+errmsg(const char *m)
+{
+ size_t s = strlen(m);
+ ssize_t written;
+
+ while (s > 0) {
+ written = write(2, m, strlen(m));
+ if (written <= 0)
+ return;
+ m += written;
+ s -= written;
+ }
+}
+
+static void
+diediedie(void)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__) && defined(_DEBUG)
+ /* Cause a breakpoint exception */
+ DebugBreak();
+#endif
+ abort(); /* Terminate the program abnormally. */
+}
+
+static const char *
+state_name(unsigned s)
+{
+ switch (s) {
+ case ARCHIVE_STATE_NEW: return ("new");
+ case ARCHIVE_STATE_HEADER: return ("header");
+ case ARCHIVE_STATE_DATA: return ("data");
+ case ARCHIVE_STATE_EOF: return ("eof");
+ case ARCHIVE_STATE_CLOSED: return ("closed");
+ case ARCHIVE_STATE_FATAL: return ("fatal");
+ default: return ("??");
+ }
+}
+
+static const char *
+archive_handle_type_name(unsigned m)
+{
+ switch (m) {
+ case ARCHIVE_WRITE_MAGIC: return ("archive_write");
+ case ARCHIVE_READ_MAGIC: return ("archive_read");
+ case ARCHIVE_WRITE_DISK_MAGIC: return ("archive_write_disk");
+ case ARCHIVE_READ_DISK_MAGIC: return ("archive_read_disk");
+ default: return NULL;
+ }
+}
+
+
+static char *
+write_all_states(char *buff, unsigned int states)
+{
+ unsigned int lowbit;
+
+ buff[0] = '\0';
+
+ /* A trick for computing the lowest set bit. */
+ while ((lowbit = states & (1 + ~states)) != 0) {
+ states &= ~lowbit; /* Clear the low bit. */
+ strcat(buff, state_name(lowbit));
+ if (states != 0)
+ strcat(buff, "/");
+ }
+ return buff;
+}
+
+/*
+ * Check magic value and current state.
+ * Magic value mismatches are fatal and result in calls to abort().
+ * State mismatches return ARCHIVE_FATAL.
+ * Otherwise, returns ARCHIVE_OK.
+ *
+ * This is designed to catch serious programming errors that violate
+ * the libarchive API.
+ */
+int
+__archive_check_magic(struct archive *a, unsigned int magic,
+ unsigned int state, const char *function)
+{
+ char states1[64];
+ char states2[64];
+ const char *handle_type;
+
+ /*
+ * If this isn't some form of archive handle,
+ * then the library user has screwed up so bad that
+ * we don't even have a reliable way to report an error.
+ */
+ handle_type = archive_handle_type_name(a->magic);
+
+ if (!handle_type) {
+ errmsg("PROGRAMMER ERROR: Function ");
+ errmsg(function);
+ errmsg(" invoked with invalid archive handle.\n");
+ diediedie();
+ }
+
+ if (a->magic != magic) {
+ archive_set_error(a, -1,
+ "PROGRAMMER ERROR: Function '%s' invoked"
+ " on '%s' archive object, which is not supported.",
+ function,
+ handle_type);
+ a->state = ARCHIVE_STATE_FATAL;
+ return (ARCHIVE_FATAL);
+ }
+
+ if ((a->state & state) == 0) {
+ /* If we're already FATAL, don't overwrite the error. */
+ if (a->state != ARCHIVE_STATE_FATAL)
+ archive_set_error(a, -1,
+ "INTERNAL ERROR: Function '%s' invoked with"
+ " archive structure in state '%s',"
+ " should be in state '%s'",
+ function,
+ write_all_states(states1, a->state),
+ write_all_states(states2, state));
+ a->state = ARCHIVE_STATE_FATAL;
+ return (ARCHIVE_FATAL);
+ }
+ return ARCHIVE_OK;
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_crc32.h b/Utilities/cmlibarchive/libarchive/archive_crc32.h
new file mode 100644
index 000000000..cd633af89
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_crc32.h
@@ -0,0 +1,78 @@
+/*-
+ * Copyright (c) 2009 Joerg Sonnenberger
+ * 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.
+ *
+ * $FreeBSD: head/lib/libarchive/archive_crc32.h 201102 2009-12-28 03:11:36Z kientzle $
+ */
+
+#ifndef __LIBARCHIVE_BUILD
+#error This header is only to be used internally to libarchive.
+#endif
+
+/*
+ * When zlib is unavailable, we should still be able to validate
+ * uncompressed zip archives. That requires us to be able to compute
+ * the CRC32 check value. This is a drop-in compatible replacement
+ * for crc32() from zlib. It's slower than the zlib implementation,
+ * but still pretty fast: This runs about 300MB/s on my 3GHz P4
+ * compared to about 800MB/s for the zlib implementation.
+ */
+static unsigned long
+crc32(unsigned long crc, const void *_p, size_t len)
+{
+ unsigned long crc2, b, i;
+ const unsigned char *p = _p;
+ static volatile int crc_tbl_inited = 0;
+ static unsigned long crc_tbl[256];
+
+ if (!crc_tbl_inited) {
+ for (b = 0; b < 256; ++b) {
+ crc2 = b;
+ for (i = 8; i > 0; --i) {
+ if (crc2 & 1)
+ crc2 = (crc2 >> 1) ^ 0xedb88320UL;
+ else
+ crc2 = (crc2 >> 1);
+ }
+ crc_tbl[b] = crc2;
+ }
+ crc_tbl_inited = 1;
+ }
+
+ crc = crc ^ 0xffffffffUL;
+ /* A use of this loop is about 20% - 30% faster than
+ * no use version in any optimization option of gcc. */
+ for (;len >= 8; len -= 8) {
+ crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
+ crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
+ crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
+ crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
+ crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
+ crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
+ crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
+ crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
+ }
+ while (len--)
+ crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8);
+ return (crc ^ 0xffffffffUL);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_crypto.c b/Utilities/cmlibarchive/libarchive/archive_crypto.c
new file mode 100644
index 000000000..2caf57169
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_crypto.c
@@ -0,0 +1,1427 @@
+/*-
+* 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 = 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. OpenSSL
+ * 6. 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
new file mode 100644
index 000000000..f8b1fb3c3
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_crypto_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_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_endian.h b/Utilities/cmlibarchive/libarchive/archive_endian.h
new file mode 100644
index 000000000..bbf58fd10
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_endian.h
@@ -0,0 +1,168 @@
+/*-
+ * Copyright (c) 2002 Thomas Moestl <tmm@FreeBSD.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 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: head/lib/libarchive/archive_endian.h 201085 2009-12-28 02:17:15Z kientzle $
+ *
+ * Borrowed from FreeBSD's <sys/endian.h>
+ */
+
+#ifndef __LIBARCHIVE_BUILD
+#error This header is only to be used internally to libarchive.
+#endif
+
+/* Note: This is a purely internal header! */
+/* Do not use this outside of libarchive internal code! */
+
+#ifndef ARCHIVE_ENDIAN_H_INCLUDED
+#define ARCHIVE_ENDIAN_H_INCLUDED
+
+
+/*
+ * Disabling inline keyword for compilers known to choke on it:
+ * - Watcom C++ in C code. (For any version?)
+ * - SGI MIPSpro
+ * - Microsoft Visual C++ 6.0 (supposedly newer versions too)
+ * - IBM VisualAge 6 (XL v6)
+ * - Sun WorkShop C (SunPro) before 5.9
+ */
+#if defined(__WATCOMC__) || defined(__sgi) || defined(__hpux) || defined(__BORLANDC__)
+#define inline
+#elif defined(__IBMC__) && __IBMC__ < 700
+#define inline
+#elif defined(__SUNPRO_C) && __SUNPRO_C < 0x590
+#define inline
+#elif defined(_MSC_VER) || defined(__osf__)
+#define inline __inline
+#endif
+
+/* Alignment-agnostic encode/decode bytestream to/from little/big endian. */
+
+static inline uint16_t
+archive_be16dec(const void *pp)
+{
+ unsigned char const *p = (unsigned char const *)pp;
+
+ return ((p[0] << 8) | p[1]);
+}
+
+static inline uint32_t
+archive_be32dec(const void *pp)
+{
+ unsigned char const *p = (unsigned char const *)pp;
+
+ return ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
+}
+
+static inline uint64_t
+archive_be64dec(const void *pp)
+{
+ unsigned char const *p = (unsigned char const *)pp;
+
+ return (((uint64_t)archive_be32dec(p) << 32) | archive_be32dec(p + 4));
+}
+
+static inline uint16_t
+archive_le16dec(const void *pp)
+{
+ unsigned char const *p = (unsigned char const *)pp;
+
+ return ((p[1] << 8) | p[0]);
+}
+
+static inline uint32_t
+archive_le32dec(const void *pp)
+{
+ unsigned char const *p = (unsigned char const *)pp;
+
+ return ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]);
+}
+
+static inline uint64_t
+archive_le64dec(const void *pp)
+{
+ unsigned char const *p = (unsigned char const *)pp;
+
+ return (((uint64_t)archive_le32dec(p + 4) << 32) | archive_le32dec(p));
+}
+
+static inline void
+archive_be16enc(void *pp, uint16_t u)
+{
+ unsigned char *p = (unsigned char *)pp;
+
+ p[0] = (u >> 8) & 0xff;
+ p[1] = u & 0xff;
+}
+
+static inline void
+archive_be32enc(void *pp, uint32_t u)
+{
+ unsigned char *p = (unsigned char *)pp;
+
+ p[0] = (u >> 24) & 0xff;
+ p[1] = (u >> 16) & 0xff;
+ p[2] = (u >> 8) & 0xff;
+ p[3] = u & 0xff;
+}
+
+static inline void
+archive_be64enc(void *pp, uint64_t u)
+{
+ unsigned char *p = (unsigned char *)pp;
+
+ archive_be32enc(p, u >> 32);
+ archive_be32enc(p + 4, u & 0xffffffff);
+}
+
+static inline void
+archive_le16enc(void *pp, uint16_t u)
+{
+ unsigned char *p = (unsigned char *)pp;
+
+ p[0] = u & 0xff;
+ p[1] = (u >> 8) & 0xff;
+}
+
+static inline void
+archive_le32enc(void *pp, uint32_t u)
+{
+ unsigned char *p = (unsigned char *)pp;
+
+ p[0] = u & 0xff;
+ p[1] = (u >> 8) & 0xff;
+ p[2] = (u >> 16) & 0xff;
+ p[3] = (u >> 24) & 0xff;
+}
+
+static inline void
+archive_le64enc(void *pp, uint64_t u)
+{
+ unsigned char *p = (unsigned char *)pp;
+
+ archive_le32enc(p, u & 0xffffffff);
+ archive_le32enc(p + 4, u >> 32);
+}
+
+#endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry.3 b/Utilities/cmlibarchive/libarchive/archive_entry.3
new file mode 100644
index 000000000..10e3c34cc
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_entry.3
@@ -0,0 +1,148 @@
+.\" Copyright (c) 2003-2007 Tim Kientzle
+.\" Copyright (c) 2010 Joerg Sonnenberger
+.\" 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: src/lib/libarchive/archive_entry.3,v 1.18 2008/05/26 17:00:22 kientzle Exp $
+.\"
+.Dd Feburary 22, 2010
+.Dt ARCHIVE_ENTRY 3
+.Os
+.Sh NAME
+.Nm archive_entry_clear ,
+.Nm archive_entry_clone ,
+.Nm archive_entry_free ,
+.Nm archive_entry_new ,
+.Nd functions for managing archive entry descriptions
+.Sh SYNOPSIS
+.In archive_entry.h
+.Ft "struct archive_entry *"
+.Fn archive_entry_clear "struct archive_entry *"
+.Ft struct archive_entry *
+.Fn archive_entry_clone "struct archive_entry *"
+.Ft void
+.Fn archive_entry_free "struct archive_entry *"
+.Ft struct archive_entry *
+.Fn archive_entry_new "void"
+.Sh DESCRIPTION
+These functions create and manipulate data objects that
+represent entries within an archive.
+You can think of a
+.Tn struct archive_entry
+as a heavy-duty version of
+.Tn struct stat :
+it includes everything from
+.Tn struct stat
+plus associated pathname, textual group and user names, etc.
+These objects are used by
+.Xr libarchive 3
+to represent the metadata associated with a particular
+entry in an archive.
+.Ss Create and Destroy
+There are functions to allocate, destroy, clear, and copy
+.Va archive_entry
+objects:
+.Bl -tag -compact -width indent
+.It Fn archive_entry_clear
+Erases the object, resetting all internal fields to the
+same state as a newly-created object.
+This is provided to allow you to quickly recycle objects
+without thrashing the heap.
+.It Fn archive_entry_clone
+A deep copy operation; all text fields are duplicated.
+.It Fn archive_entry_free
+Releases the
+.Tn struct archive_entry
+object.
+.It Fn archive_entry_new
+Allocate and return a blank
+.Tn struct archive_entry
+object.
+.El
+.Ss Function groups
+Due to high number of functions, the accessor functions can be found in
+man pages grouped by the purpose.
+.Bl -tag -width ".Xr archive_entry_perms 3"
+.It Xr archive_entry_acl 3
+Access Control List manipulation
+.It Xr archive_entry_paths 3
+Path name manipulation
+.It Xr archive_entry_perms 3
+User, group and mode manipulation
+.It Xr archive_entry_stat 3
+Functions not in the other groups and copying to/from
+.Vt struct stat .
+.It Xr archive_entry_time 3
+Time field manipulation
+.El
+.Pp
+Most of the functions set or read entries in an object.
+Such functions have one of the following forms:
+.Bl -tag -compact -width indent
+.It Fn archive_entry_set_XXXX
+Stores the provided data in the object.
+In particular, for strings, the pointer is stored,
+not the referenced string.
+.It Fn archive_entry_copy_XXXX
+As above, except that the referenced data is copied
+into the object.
+.It Fn archive_entry_XXXX
+Returns the specified data.
+In the case of strings, a const-qualified pointer to
+the string is returned.
+.El
+String data can be set or accessed as wide character strings
+or normal
+.Va char
+strings.
+The functions that use wide character strings are suffixed with
+.Cm _w .
+Note that these are different representations of the same data:
+For example, if you store a narrow string and read the corresponding
+wide string, the object will transparently convert formats
+using the current locale.
+Similarly, if you store a wide string and then store a
+narrow string for the same data, the previously-set wide string will
+be discarded in favor of the new data.
+.Pp
+.\" .Sh EXAMPLE
+.\" .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
+.Sh HISTORY
+The
+.Nm libarchive
+library first appeared in
+.Fx 5.3 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm libarchive
+library was written by
+.An Tim Kientzle Aq kientzle@acm.org .
+.\" .Sh BUGS
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry.c b/Utilities/cmlibarchive/libarchive/archive_entry.c
new file mode 100644
index 000000000..cbdda8a44
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_entry.c
@@ -0,0 +1,1651 @@
+/*-
+ * 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: head/lib/libarchive/archive_entry.c 201096 2009-12-28 02:41:27Z kientzle $");
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if MAJOR_IN_MKDEV
+#include <sys/mkdev.h>
+#define HAVE_MAJOR
+#elif MAJOR_IN_SYSMACROS
+#include <sys/sysmacros.h>
+#define HAVE_MAJOR
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifdef HAVE_LINUX_FS_H
+#include <linux/fs.h> /* for Linux file flags */
+#endif
+/*
+ * Some Linux distributions have both linux/ext2_fs.h and ext2fs/ext2_fs.h.
+ * As the include guards don't agree, the order of include is important.
+ */
+#ifdef HAVE_LINUX_EXT2_FS_H
+#include <linux/ext2_fs.h> /* for Linux file flags */
+#endif
+#if defined(HAVE_EXT2FS_EXT2_FS_H) && !defined(__CYGWIN__)
+#include <ext2fs/ext2_fs.h> /* for Linux file flags */
+#endif
+#include <stddef.h>
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_WCHAR_H
+#include <wchar.h>
+#endif
+
+#include "archive.h"
+#include "archive_acl_private.h"
+#include "archive_entry.h"
+#include "archive_entry_locale.h"
+#include "archive_private.h"
+#include "archive_entry_private.h"
+
+#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 ae_makedev(maj, min) makedev(ND_LOCAL_NODE, (maj), (min))
+#elif defined makedev
+/* There's a "makedev" macro. */
+#define ae_makedev(maj, min) makedev((maj), (min))
+#elif defined mkdev || ((defined _WIN32 || defined __WIN32__) && !defined(__CYGWIN__))
+/* Windows. <sigh> */
+#define ae_makedev(maj, min) mkdev((maj), (min))
+#else
+/* There's a "makedev" function. */
+#define ae_makedev(maj, min) makedev((maj), (min))
+#endif
+
+/*
+ * This adjustment is needed to support the following idiom for adding
+ * 1000ns to the stored time:
+ * archive_entry_set_atime(archive_entry_atime(),
+ * archive_entry_atime_nsec() + 1000)
+ * The additional if() here compensates for ambiguity in the C standard,
+ * which permits two possible interpretations of a % b when a is negative.
+ */
+#define FIX_NS(t,ns) \
+ do { \
+ t += ns / 1000000000; \
+ ns %= 1000000000; \
+ if (ns < 0) { --t; ns += 1000000000; } \
+ } while (0)
+
+static char * ae_fflagstostr(unsigned long bitset, unsigned long bitclear);
+static const wchar_t *ae_wcstofflags(const wchar_t *stringp,
+ unsigned long *setp, unsigned long *clrp);
+static const char *ae_strtofflags(const char *stringp,
+ unsigned long *setp, unsigned long *clrp);
+
+#ifndef HAVE_WCSCPY
+static wchar_t * wcscpy(wchar_t *s1, const wchar_t *s2)
+{
+ wchar_t *dest = s1;
+ while ((*s1 = *s2) != L'\0')
+ ++s1, ++s2;
+ return dest;
+}
+#endif
+#ifndef HAVE_WCSLEN
+static size_t wcslen(const wchar_t *s)
+{
+ const wchar_t *p = s;
+ while (*p != L'\0')
+ ++p;
+ return p - s;
+}
+#endif
+#ifndef HAVE_WMEMCMP
+/* Good enough for simple equality testing, but not for sorting. */
+#define wmemcmp(a,b,i) memcmp((a), (b), (i) * sizeof(wchar_t))
+#endif
+
+/****************************************************************************
+ *
+ * Public Interface
+ *
+ ****************************************************************************/
+
+struct archive_entry *
+archive_entry_clear(struct archive_entry *entry)
+{
+ if (entry == NULL)
+ return (NULL);
+ archive_mstring_clean(&entry->ae_fflags_text);
+ archive_mstring_clean(&entry->ae_gname);
+ archive_mstring_clean(&entry->ae_hardlink);
+ archive_mstring_clean(&entry->ae_pathname);
+ archive_mstring_clean(&entry->ae_sourcepath);
+ archive_mstring_clean(&entry->ae_symlink);
+ archive_mstring_clean(&entry->ae_uname);
+ archive_entry_copy_mac_metadata(entry, NULL, 0);
+ archive_acl_clear(&entry->acl);
+ archive_entry_xattr_clear(entry);
+ archive_entry_sparse_clear(entry);
+ free(entry->stat);
+ memset(entry, 0, sizeof(*entry));
+ return entry;
+}
+
+struct archive_entry *
+archive_entry_clone(struct archive_entry *entry)
+{
+ struct archive_entry *entry2;
+ struct ae_xattr *xp;
+ struct ae_sparse *sp;
+ size_t s;
+ const void *p;
+
+ /* Allocate new structure and copy over all of the fields. */
+ /* TODO: Should we copy the archive over? Or require a new archive
+ * as an argument? */
+ entry2 = archive_entry_new2(entry->archive);
+ if (entry2 == NULL)
+ return (NULL);
+ entry2->ae_stat = entry->ae_stat;
+ entry2->ae_fflags_set = entry->ae_fflags_set;
+ entry2->ae_fflags_clear = entry->ae_fflags_clear;
+
+ /* TODO: XXX If clone can have a different archive, what do we do here if
+ * character sets are different? XXX */
+ archive_mstring_copy(&entry2->ae_fflags_text, &entry->ae_fflags_text);
+ archive_mstring_copy(&entry2->ae_gname, &entry->ae_gname);
+ archive_mstring_copy(&entry2->ae_hardlink, &entry->ae_hardlink);
+ archive_mstring_copy(&entry2->ae_pathname, &entry->ae_pathname);
+ archive_mstring_copy(&entry2->ae_sourcepath, &entry->ae_sourcepath);
+ archive_mstring_copy(&entry2->ae_symlink, &entry->ae_symlink);
+ entry2->ae_set = entry->ae_set;
+ archive_mstring_copy(&entry2->ae_uname, &entry->ae_uname);
+
+ /* Copy ACL data over. */
+ archive_acl_copy(&entry2->acl, &entry->acl);
+
+ /* Copy Mac OS metadata. */
+ p = archive_entry_mac_metadata(entry, &s);
+ archive_entry_copy_mac_metadata(entry2, p, s);
+
+ /* Copy xattr data over. */
+ xp = entry->xattr_head;
+ while (xp != NULL) {
+ archive_entry_xattr_add_entry(entry2,
+ xp->name, xp->value, xp->size);
+ xp = xp->next;
+ }
+
+ /* Copy sparse data over. */
+ sp = entry->sparse_head;
+ while (sp != NULL) {
+ archive_entry_sparse_add_entry(entry2,
+ sp->offset, sp->length);
+ sp = sp->next;
+ }
+
+ return (entry2);
+}
+
+void
+archive_entry_free(struct archive_entry *entry)
+{
+ archive_entry_clear(entry);
+ free(entry);
+}
+
+struct archive_entry *
+archive_entry_new(void)
+{
+ return archive_entry_new2(NULL);
+}
+
+struct archive_entry *
+archive_entry_new2(struct archive *a)
+{
+ struct archive_entry *entry;
+
+ entry = (struct archive_entry *)malloc(sizeof(*entry));
+ if (entry == NULL)
+ return (NULL);
+ memset(entry, 0, sizeof(*entry));
+ entry->archive = a;
+ return (entry);
+}
+
+/*
+ * Functions for reading fields from an archive_entry.
+ */
+
+time_t
+archive_entry_atime(struct archive_entry *entry)
+{
+ return (entry->ae_stat.aest_atime);
+}
+
+long
+archive_entry_atime_nsec(struct archive_entry *entry)
+{
+ return (entry->ae_stat.aest_atime_nsec);
+}
+
+int
+archive_entry_atime_is_set(struct archive_entry *entry)
+{
+ return (entry->ae_set & AE_SET_ATIME);
+}
+
+time_t
+archive_entry_birthtime(struct archive_entry *entry)
+{
+ return (entry->ae_stat.aest_birthtime);
+}
+
+long
+archive_entry_birthtime_nsec(struct archive_entry *entry)
+{
+ return (entry->ae_stat.aest_birthtime_nsec);
+}
+
+int
+archive_entry_birthtime_is_set(struct archive_entry *entry)
+{
+ return (entry->ae_set & AE_SET_BIRTHTIME);
+}
+
+time_t
+archive_entry_ctime(struct archive_entry *entry)
+{
+ return (entry->ae_stat.aest_ctime);
+}
+
+int
+archive_entry_ctime_is_set(struct archive_entry *entry)
+{
+ return (entry->ae_set & AE_SET_CTIME);
+}
+
+long
+archive_entry_ctime_nsec(struct archive_entry *entry)
+{
+ return (entry->ae_stat.aest_ctime_nsec);
+}
+
+dev_t
+archive_entry_dev(struct archive_entry *entry)
+{
+ if (entry->ae_stat.aest_dev_is_broken_down)
+ return ae_makedev(entry->ae_stat.aest_devmajor,
+ entry->ae_stat.aest_devminor);
+ else
+ return (entry->ae_stat.aest_dev);
+}
+
+int
+archive_entry_dev_is_set(struct archive_entry *entry)
+{
+ return (entry->ae_set & AE_SET_DEV);
+}
+
+dev_t
+archive_entry_devmajor(struct archive_entry *entry)
+{
+ if (entry->ae_stat.aest_dev_is_broken_down)
+ return (entry->ae_stat.aest_devmajor);
+ else
+ return major(entry->ae_stat.aest_dev);
+}
+
+dev_t
+archive_entry_devminor(struct archive_entry *entry)
+{
+ if (entry->ae_stat.aest_dev_is_broken_down)
+ return (entry->ae_stat.aest_devminor);
+ else
+ return minor(entry->ae_stat.aest_dev);
+}
+
+mode_t
+archive_entry_filetype(struct archive_entry *entry)
+{
+ return (AE_IFMT & entry->acl.mode);
+}
+
+void
+archive_entry_fflags(struct archive_entry *entry,
+ unsigned long *set, unsigned long *clear)
+{
+ *set = entry->ae_fflags_set;
+ *clear = entry->ae_fflags_clear;
+}
+
+/*
+ * Note: if text was provided, this just returns that text. If you
+ * really need the text to be rebuilt in a canonical form, set the
+ * text, ask for the bitmaps, then set the bitmaps. (Setting the
+ * bitmaps clears any stored text.) This design is deliberate: if
+ * we're editing archives, we don't want to discard flags just because
+ * they aren't supported on the current system. The bitmap<->text
+ * conversions are platform-specific (see below).
+ */
+const char *
+archive_entry_fflags_text(struct archive_entry *entry)
+{
+ const char *f;
+ char *p;
+
+ if (archive_mstring_get_mbs(entry->archive,
+ &entry->ae_fflags_text, &f) == 0 && f != NULL)
+ return (f);
+
+ if (entry->ae_fflags_set == 0 && entry->ae_fflags_clear == 0)
+ return (NULL);
+
+ p = ae_fflagstostr(entry->ae_fflags_set, entry->ae_fflags_clear);
+ if (p == NULL)
+ return (NULL);
+
+ archive_mstring_copy_mbs(&entry->ae_fflags_text, p);
+ free(p);
+ if (archive_mstring_get_mbs(entry->archive,
+ &entry->ae_fflags_text, &f) == 0)
+ return (f);
+ return (NULL);
+}
+
+int64_t
+archive_entry_gid(struct archive_entry *entry)
+{
+ return (entry->ae_stat.aest_gid);
+}
+
+const char *
+archive_entry_gname(struct archive_entry *entry)
+{
+ const char *p;
+ if (archive_mstring_get_mbs(entry->archive, &entry->ae_gname, &p) == 0)
+ return (p);
+ return (NULL);
+}
+
+const wchar_t *
+archive_entry_gname_w(struct archive_entry *entry)
+{
+ const wchar_t *p;
+ if (archive_mstring_get_wcs(entry->archive, &entry->ae_gname, &p) == 0)
+ return (p);
+ return (NULL);
+}
+
+int
+_archive_entry_gname_l(struct archive_entry *entry,
+ const char **p, size_t *len, struct archive_string_conv *sc)
+{
+ return (archive_mstring_get_mbs_l(&entry->ae_gname, p, len, sc));
+}
+
+const char *
+archive_entry_hardlink(struct archive_entry *entry)
+{
+ const char *p;
+ if ((entry->ae_set & AE_SET_HARDLINK) && archive_mstring_get_mbs(
+ entry->archive, &entry->ae_hardlink, &p) == 0)
+ return (p);
+ return (NULL);
+}
+
+const wchar_t *
+archive_entry_hardlink_w(struct archive_entry *entry)
+{
+ const wchar_t *p;
+ if ((entry->ae_set & AE_SET_HARDLINK) && archive_mstring_get_wcs(
+ entry->archive, &entry->ae_hardlink, &p) == 0)
+ return (p);
+ return (NULL);
+}
+
+int
+_archive_entry_hardlink_l(struct archive_entry *entry,
+ const char **p, size_t *len, struct archive_string_conv *sc)
+{
+ if ((entry->ae_set & AE_SET_HARDLINK) == 0) {
+ *p = NULL;
+ *len = 0;
+ return (0);
+ }
+ return (archive_mstring_get_mbs_l(&entry->ae_hardlink, p, len, sc));
+}
+
+int64_t
+archive_entry_ino(struct archive_entry *entry)
+{
+ return (entry->ae_stat.aest_ino);
+}
+
+int
+archive_entry_ino_is_set(struct archive_entry *entry)
+{
+ return (entry->ae_set & AE_SET_INO);
+}
+
+int64_t
+archive_entry_ino64(struct archive_entry *entry)
+{
+ return (entry->ae_stat.aest_ino);
+}
+
+mode_t
+archive_entry_mode(struct archive_entry *entry)
+{
+ return (entry->acl.mode);
+}
+
+time_t
+archive_entry_mtime(struct archive_entry *entry)
+{
+ return (entry->ae_stat.aest_mtime);
+}
+
+long
+archive_entry_mtime_nsec(struct archive_entry *entry)
+{
+ return (entry->ae_stat.aest_mtime_nsec);
+}
+
+int
+archive_entry_mtime_is_set(struct archive_entry *entry)
+{
+ return (entry->ae_set & AE_SET_MTIME);
+}
+
+unsigned int
+archive_entry_nlink(struct archive_entry *entry)
+{
+ return (entry->ae_stat.aest_nlink);
+}
+
+const char *
+archive_entry_pathname(struct archive_entry *entry)
+{
+ const char *p;
+ if (archive_mstring_get_mbs(
+ entry->archive, &entry->ae_pathname, &p) == 0)
+ return (p);
+ return (NULL);
+}
+
+const wchar_t *
+archive_entry_pathname_w(struct archive_entry *entry)
+{
+ const wchar_t *p;
+ if (archive_mstring_get_wcs(
+ entry->archive, &entry->ae_pathname, &p) == 0)
+ return (p);
+ return (NULL);
+}
+
+int
+_archive_entry_pathname_l(struct archive_entry *entry,
+ const char **p, size_t *len, struct archive_string_conv *sc)
+{
+ return (archive_mstring_get_mbs_l(&entry->ae_pathname, p, len, sc));
+}
+
+mode_t
+archive_entry_perm(struct archive_entry *entry)
+{
+ return (~AE_IFMT & entry->acl.mode);
+}
+
+dev_t
+archive_entry_rdev(struct archive_entry *entry)
+{
+ if (entry->ae_stat.aest_rdev_is_broken_down)
+ return ae_makedev(entry->ae_stat.aest_rdevmajor,
+ entry->ae_stat.aest_rdevminor);
+ else
+ return (entry->ae_stat.aest_rdev);
+}
+
+dev_t
+archive_entry_rdevmajor(struct archive_entry *entry)
+{
+ if (entry->ae_stat.aest_rdev_is_broken_down)
+ return (entry->ae_stat.aest_rdevmajor);
+ else
+ return major(entry->ae_stat.aest_rdev);
+}
+
+dev_t
+archive_entry_rdevminor(struct archive_entry *entry)
+{
+ if (entry->ae_stat.aest_rdev_is_broken_down)
+ return (entry->ae_stat.aest_rdevminor);
+ else
+ return minor(entry->ae_stat.aest_rdev);
+}
+
+int64_t
+archive_entry_size(struct archive_entry *entry)
+{
+ return (entry->ae_stat.aest_size);
+}
+
+int
+archive_entry_size_is_set(struct archive_entry *entry)
+{
+ return (entry->ae_set & AE_SET_SIZE);
+}
+
+const char *
+archive_entry_sourcepath(struct archive_entry *entry)
+{
+ const char *p;
+ if (archive_mstring_get_mbs(
+ entry->archive, &entry->ae_sourcepath, &p) == 0)
+ return (p);
+ return (NULL);
+}
+
+const wchar_t *
+archive_entry_sourcepath_w(struct archive_entry *entry)
+{
+ const wchar_t *p;
+ if (archive_mstring_get_wcs(
+ entry->archive, &entry->ae_sourcepath, &p) == 0)
+ return (p);
+ return (NULL);
+}
+
+const char *
+archive_entry_symlink(struct archive_entry *entry)
+{
+ const char *p;
+ if ((entry->ae_set & AE_SET_SYMLINK) && archive_mstring_get_mbs(
+ entry->archive, &entry->ae_symlink, &p) == 0)
+ return (p);
+ return (NULL);
+}
+
+const wchar_t *
+archive_entry_symlink_w(struct archive_entry *entry)
+{
+ const wchar_t *p;
+ if ((entry->ae_set & AE_SET_SYMLINK) && archive_mstring_get_wcs(
+ entry->archive, &entry->ae_symlink, &p) == 0)
+ return (p);
+ return (NULL);
+}
+
+int
+_archive_entry_symlink_l(struct archive_entry *entry,
+ const char **p, size_t *len, struct archive_string_conv *sc)
+{
+ if ((entry->ae_set & AE_SET_SYMLINK) == 0) {
+ *p = NULL;
+ *len = 0;
+ return (0);
+ }
+ return (archive_mstring_get_mbs_l( &entry->ae_symlink, p, len, sc));
+}
+
+int64_t
+archive_entry_uid(struct archive_entry *entry)
+{
+ return (entry->ae_stat.aest_uid);
+}
+
+const char *
+archive_entry_uname(struct archive_entry *entry)
+{
+ const char *p;
+ if (archive_mstring_get_mbs(entry->archive, &entry->ae_uname, &p) == 0)
+ return (p);
+ return (NULL);
+}
+
+const wchar_t *
+archive_entry_uname_w(struct archive_entry *entry)
+{
+ const wchar_t *p;
+ if (archive_mstring_get_wcs(entry->archive, &entry->ae_uname, &p) == 0)
+ return (p);
+ return (NULL);
+}
+
+int
+_archive_entry_uname_l(struct archive_entry *entry,
+ const char **p, size_t *len, struct archive_string_conv *sc)
+{
+ return (archive_mstring_get_mbs_l(&entry->ae_uname, p, len, sc));
+}
+
+/*
+ * Functions to set archive_entry properties.
+ */
+
+void
+archive_entry_set_filetype(struct archive_entry *entry, unsigned int type)
+{
+ entry->stat_valid = 0;
+ entry->acl.mode &= ~AE_IFMT;
+ entry->acl.mode |= AE_IFMT & type;
+}
+
+void
+archive_entry_set_fflags(struct archive_entry *entry,
+ unsigned long set, unsigned long clear)
+{
+ archive_mstring_clean(&entry->ae_fflags_text);
+ entry->ae_fflags_set = set;
+ entry->ae_fflags_clear = clear;
+}
+
+const char *
+archive_entry_copy_fflags_text(struct archive_entry *entry,
+ const char *flags)
+{
+ archive_mstring_copy_mbs(&entry->ae_fflags_text, flags);
+ return (ae_strtofflags(flags,
+ &entry->ae_fflags_set, &entry->ae_fflags_clear));
+}
+
+const wchar_t *
+archive_entry_copy_fflags_text_w(struct archive_entry *entry,
+ const wchar_t *flags)
+{
+ archive_mstring_copy_wcs(&entry->ae_fflags_text, flags);
+ return (ae_wcstofflags(flags,
+ &entry->ae_fflags_set, &entry->ae_fflags_clear));
+}
+
+void
+archive_entry_set_gid(struct archive_entry *entry, int64_t g)
+{
+ entry->stat_valid = 0;
+ entry->ae_stat.aest_gid = g;
+}
+
+void
+archive_entry_set_gname(struct archive_entry *entry, const char *name)
+{
+ archive_mstring_copy_mbs(&entry->ae_gname, name);
+}
+
+void
+archive_entry_copy_gname(struct archive_entry *entry, const char *name)
+{
+ archive_mstring_copy_mbs(&entry->ae_gname, name);
+}
+
+void
+archive_entry_copy_gname_w(struct archive_entry *entry, const wchar_t *name)
+{
+ archive_mstring_copy_wcs(&entry->ae_gname, name);
+}
+
+int
+archive_entry_update_gname_utf8(struct archive_entry *entry, const char *name)
+{
+ if (archive_mstring_update_utf8(entry->archive,
+ &entry->ae_gname, name) == 0)
+ return (1);
+ return (0);
+}
+
+int
+_archive_entry_copy_gname_l(struct archive_entry *entry,
+ const char *name, size_t len, struct archive_string_conv *sc)
+{
+ return (archive_mstring_copy_mbs_len_l(&entry->ae_gname, name, len, sc));
+}
+
+void
+archive_entry_set_ino(struct archive_entry *entry, int64_t ino)
+{
+ entry->stat_valid = 0;
+ entry->ae_set |= AE_SET_INO;
+ entry->ae_stat.aest_ino = ino;
+}
+
+void
+archive_entry_set_ino64(struct archive_entry *entry, int64_t ino)
+{
+ entry->stat_valid = 0;
+ entry->ae_set |= AE_SET_INO;
+ entry->ae_stat.aest_ino = ino;
+}
+
+void
+archive_entry_set_hardlink(struct archive_entry *entry, const char *target)
+{
+ archive_mstring_copy_mbs(&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);
+ if (target != NULL)
+ entry->ae_set |= AE_SET_HARDLINK;
+ else
+ entry->ae_set &= ~AE_SET_HARDLINK;
+}
+
+void
+archive_entry_copy_hardlink_w(struct archive_entry *entry, const wchar_t *target)
+{
+ archive_mstring_copy_wcs(&entry->ae_hardlink, target);
+ if (target != NULL)
+ entry->ae_set |= AE_SET_HARDLINK;
+ else
+ entry->ae_set &= ~AE_SET_HARDLINK;
+}
+
+int
+archive_entry_update_hardlink_utf8(struct archive_entry *entry, const char *target)
+{
+ if (target != NULL)
+ entry->ae_set |= AE_SET_HARDLINK;
+ else
+ entry->ae_set &= ~AE_SET_HARDLINK;
+ if (archive_mstring_update_utf8(entry->archive,
+ &entry->ae_hardlink, target) == 0)
+ return (1);
+ return (0);
+}
+
+int
+_archive_entry_copy_hardlink_l(struct archive_entry *entry,
+ const char *target, size_t len, struct archive_string_conv *sc)
+{
+ int r;
+
+ r = archive_mstring_copy_mbs_len_l(&entry->ae_hardlink,
+ target, len, sc);
+ if (target != NULL && r == 0)
+ entry->ae_set |= AE_SET_HARDLINK;
+ else
+ entry->ae_set &= ~AE_SET_HARDLINK;
+ return (r);
+}
+
+void
+archive_entry_set_atime(struct archive_entry *entry, time_t t, long ns)
+{
+ FIX_NS(t, ns);
+ entry->stat_valid = 0;
+ entry->ae_set |= AE_SET_ATIME;
+ entry->ae_stat.aest_atime = t;
+ entry->ae_stat.aest_atime_nsec = ns;
+}
+
+void
+archive_entry_unset_atime(struct archive_entry *entry)
+{
+ archive_entry_set_atime(entry, 0, 0);
+ entry->ae_set &= ~AE_SET_ATIME;
+}
+
+void
+archive_entry_set_birthtime(struct archive_entry *entry, time_t t, long ns)
+{
+ FIX_NS(t, ns);
+ entry->stat_valid = 0;
+ entry->ae_set |= AE_SET_BIRTHTIME;
+ entry->ae_stat.aest_birthtime = t;
+ entry->ae_stat.aest_birthtime_nsec = ns;
+}
+
+void
+archive_entry_unset_birthtime(struct archive_entry *entry)
+{
+ archive_entry_set_birthtime(entry, 0, 0);
+ entry->ae_set &= ~AE_SET_BIRTHTIME;
+}
+
+void
+archive_entry_set_ctime(struct archive_entry *entry, time_t t, long ns)
+{
+ FIX_NS(t, ns);
+ entry->stat_valid = 0;
+ entry->ae_set |= AE_SET_CTIME;
+ entry->ae_stat.aest_ctime = t;
+ entry->ae_stat.aest_ctime_nsec = ns;
+}
+
+void
+archive_entry_unset_ctime(struct archive_entry *entry)
+{
+ archive_entry_set_ctime(entry, 0, 0);
+ entry->ae_set &= ~AE_SET_CTIME;
+}
+
+void
+archive_entry_set_dev(struct archive_entry *entry, dev_t d)
+{
+ entry->stat_valid = 0;
+ entry->ae_set |= AE_SET_DEV;
+ entry->ae_stat.aest_dev_is_broken_down = 0;
+ entry->ae_stat.aest_dev = d;
+}
+
+void
+archive_entry_set_devmajor(struct archive_entry *entry, dev_t m)
+{
+ entry->stat_valid = 0;
+ entry->ae_set |= AE_SET_DEV;
+ entry->ae_stat.aest_dev_is_broken_down = 1;
+ entry->ae_stat.aest_devmajor = m;
+}
+
+void
+archive_entry_set_devminor(struct archive_entry *entry, dev_t m)
+{
+ entry->stat_valid = 0;
+ entry->ae_set |= AE_SET_DEV;
+ entry->ae_stat.aest_dev_is_broken_down = 1;
+ entry->ae_stat.aest_devminor = m;
+}
+
+/* Set symlink if symlink is already set, else set hardlink. */
+void
+archive_entry_set_link(struct archive_entry *entry, const char *target)
+{
+ if (entry->ae_set & AE_SET_SYMLINK)
+ archive_mstring_copy_mbs(&entry->ae_symlink, target);
+ else
+ archive_mstring_copy_mbs(&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)
+{
+ if (entry->ae_set & AE_SET_SYMLINK)
+ archive_mstring_copy_mbs(&entry->ae_symlink, target);
+ else
+ archive_mstring_copy_mbs(&entry->ae_hardlink, target);
+}
+
+/* Set symlink if symlink is already set, else set hardlink. */
+void
+archive_entry_copy_link_w(struct archive_entry *entry, const wchar_t *target)
+{
+ if (entry->ae_set & AE_SET_SYMLINK)
+ archive_mstring_copy_wcs(&entry->ae_symlink, target);
+ else
+ archive_mstring_copy_wcs(&entry->ae_hardlink, target);
+}
+
+int
+archive_entry_update_link_utf8(struct archive_entry *entry, const char *target)
+{
+ int r;
+ if (entry->ae_set & AE_SET_SYMLINK)
+ r = archive_mstring_update_utf8(entry->archive,
+ &entry->ae_symlink, target);
+ else
+ r = archive_mstring_update_utf8(entry->archive,
+ &entry->ae_hardlink, target);
+ return ((r == 0)? 1: 0);
+}
+
+int
+_archive_entry_copy_link_l(struct archive_entry *entry,
+ const char *target, size_t len, struct archive_string_conv *sc)
+{
+ int r;
+
+ if (entry->ae_set & AE_SET_SYMLINK)
+ r = archive_mstring_copy_mbs_len_l(&entry->ae_symlink,
+ target, len, sc);
+ else
+ r = archive_mstring_copy_mbs_len_l(&entry->ae_hardlink,
+ target, len, sc);
+ return (r);
+}
+
+void
+archive_entry_set_mode(struct archive_entry *entry, mode_t m)
+{
+ entry->stat_valid = 0;
+ entry->acl.mode = m;
+}
+
+void
+archive_entry_set_mtime(struct archive_entry *entry, time_t t, long ns)
+{
+ FIX_NS(t, ns);
+ entry->stat_valid = 0;
+ entry->ae_set |= AE_SET_MTIME;
+ entry->ae_stat.aest_mtime = t;
+ entry->ae_stat.aest_mtime_nsec = ns;
+}
+
+void
+archive_entry_unset_mtime(struct archive_entry *entry)
+{
+ archive_entry_set_mtime(entry, 0, 0);
+ entry->ae_set &= ~AE_SET_MTIME;
+}
+
+void
+archive_entry_set_nlink(struct archive_entry *entry, unsigned int nlink)
+{
+ entry->stat_valid = 0;
+ entry->ae_stat.aest_nlink = nlink;
+}
+
+void
+archive_entry_set_pathname(struct archive_entry *entry, const char *name)
+{
+ archive_mstring_copy_mbs(&entry->ae_pathname, name);
+}
+
+void
+archive_entry_copy_pathname(struct archive_entry *entry, const char *name)
+{
+ archive_mstring_copy_mbs(&entry->ae_pathname, name);
+}
+
+void
+archive_entry_copy_pathname_w(struct archive_entry *entry, const wchar_t *name)
+{
+ archive_mstring_copy_wcs(&entry->ae_pathname, name);
+}
+
+int
+archive_entry_update_pathname_utf8(struct archive_entry *entry, const char *name)
+{
+ if (archive_mstring_update_utf8(entry->archive,
+ &entry->ae_pathname, name) == 0)
+ return (1);
+ return (0);
+}
+
+int
+_archive_entry_copy_pathname_l(struct archive_entry *entry,
+ const char *name, size_t len, struct archive_string_conv *sc)
+{
+ return (archive_mstring_copy_mbs_len_l(&entry->ae_pathname,
+ name, len, sc));
+}
+
+void
+archive_entry_set_perm(struct archive_entry *entry, mode_t p)
+{
+ entry->stat_valid = 0;
+ entry->acl.mode &= AE_IFMT;
+ entry->acl.mode |= ~AE_IFMT & p;
+}
+
+void
+archive_entry_set_rdev(struct archive_entry *entry, dev_t m)
+{
+ entry->stat_valid = 0;
+ entry->ae_stat.aest_rdev = m;
+ entry->ae_stat.aest_rdev_is_broken_down = 0;
+}
+
+void
+archive_entry_set_rdevmajor(struct archive_entry *entry, dev_t m)
+{
+ entry->stat_valid = 0;
+ entry->ae_stat.aest_rdev_is_broken_down = 1;
+ entry->ae_stat.aest_rdevmajor = m;
+}
+
+void
+archive_entry_set_rdevminor(struct archive_entry *entry, dev_t m)
+{
+ entry->stat_valid = 0;
+ entry->ae_stat.aest_rdev_is_broken_down = 1;
+ entry->ae_stat.aest_rdevminor = m;
+}
+
+void
+archive_entry_set_size(struct archive_entry *entry, int64_t s)
+{
+ entry->stat_valid = 0;
+ entry->ae_stat.aest_size = s;
+ entry->ae_set |= AE_SET_SIZE;
+}
+
+void
+archive_entry_unset_size(struct archive_entry *entry)
+{
+ archive_entry_set_size(entry, 0);
+ entry->ae_set &= ~AE_SET_SIZE;
+}
+
+void
+archive_entry_copy_sourcepath(struct archive_entry *entry, const char *path)
+{
+ archive_mstring_copy_mbs(&entry->ae_sourcepath, path);
+}
+
+void
+archive_entry_copy_sourcepath_w(struct archive_entry *entry, const wchar_t *path)
+{
+ archive_mstring_copy_wcs(&entry->ae_sourcepath, path);
+}
+
+void
+archive_entry_set_symlink(struct archive_entry *entry, const char *linkname)
+{
+ archive_mstring_copy_mbs(&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);
+ if (linkname != NULL)
+ entry->ae_set |= AE_SET_SYMLINK;
+ else
+ entry->ae_set &= ~AE_SET_SYMLINK;
+}
+
+void
+archive_entry_copy_symlink_w(struct archive_entry *entry, const wchar_t *linkname)
+{
+ archive_mstring_copy_wcs(&entry->ae_symlink, linkname);
+ if (linkname != NULL)
+ entry->ae_set |= AE_SET_SYMLINK;
+ else
+ entry->ae_set &= ~AE_SET_SYMLINK;
+}
+
+int
+archive_entry_update_symlink_utf8(struct archive_entry *entry, const char *linkname)
+{
+ if (linkname != NULL)
+ entry->ae_set |= AE_SET_SYMLINK;
+ else
+ entry->ae_set &= ~AE_SET_SYMLINK;
+ if (archive_mstring_update_utf8(entry->archive,
+ &entry->ae_symlink, linkname) == 0)
+ return (1);
+ return (0);
+}
+
+int
+_archive_entry_copy_symlink_l(struct archive_entry *entry,
+ const char *linkname, size_t len, struct archive_string_conv *sc)
+{
+ int r;
+
+ r = archive_mstring_copy_mbs_len_l(&entry->ae_symlink,
+ linkname, len, sc);
+ if (linkname != NULL && r == 0)
+ entry->ae_set |= AE_SET_SYMLINK;
+ else
+ entry->ae_set &= ~AE_SET_SYMLINK;
+ return (r);
+}
+
+void
+archive_entry_set_uid(struct archive_entry *entry, int64_t u)
+{
+ entry->stat_valid = 0;
+ entry->ae_stat.aest_uid = u;
+}
+
+void
+archive_entry_set_uname(struct archive_entry *entry, const char *name)
+{
+ archive_mstring_copy_mbs(&entry->ae_uname, name);
+}
+
+void
+archive_entry_copy_uname(struct archive_entry *entry, const char *name)
+{
+ archive_mstring_copy_mbs(&entry->ae_uname, name);
+}
+
+void
+archive_entry_copy_uname_w(struct archive_entry *entry, const wchar_t *name)
+{
+ archive_mstring_copy_wcs(&entry->ae_uname, name);
+}
+
+int
+archive_entry_update_uname_utf8(struct archive_entry *entry, const char *name)
+{
+ if (archive_mstring_update_utf8(entry->archive,
+ &entry->ae_uname, name) == 0)
+ return (1);
+ return (0);
+}
+
+int
+_archive_entry_copy_uname_l(struct archive_entry *entry,
+ const char *name, size_t len, struct archive_string_conv *sc)
+{
+ return (archive_mstring_copy_mbs_len_l(&entry->ae_uname,
+ name, len, sc));
+}
+
+const void *
+archive_entry_mac_metadata(struct archive_entry *entry, size_t *s)
+{
+ *s = entry->mac_metadata_size;
+ return entry->mac_metadata;
+}
+
+void
+archive_entry_copy_mac_metadata(struct archive_entry *entry,
+ const void *p, size_t s)
+{
+ free(entry->mac_metadata);
+ if (p == NULL || s == 0) {
+ entry->mac_metadata = NULL;
+ entry->mac_metadata_size = 0;
+ } else {
+ entry->mac_metadata_size = s;
+ entry->mac_metadata = malloc(s);
+ if (entry->mac_metadata == NULL)
+ abort();
+ memcpy(entry->mac_metadata, p, s);
+ }
+}
+
+/*
+ * ACL management. The following would, of course, be a lot simpler
+ * if: 1) the last draft of POSIX.1e were a really thorough and
+ * complete standard that addressed the needs of ACL archiving and 2)
+ * everyone followed it faithfully. Alas, neither is true, so the
+ * following is a lot more complex than might seem necessary to the
+ * uninitiated.
+ */
+
+struct archive_acl *
+archive_entry_acl(struct archive_entry *entry)
+{
+ return &entry->acl;
+}
+
+void
+archive_entry_acl_clear(struct archive_entry *entry)
+{
+ archive_acl_clear(&entry->acl);
+}
+
+/*
+ * Add a single ACL entry to the internal list of ACL data.
+ */
+int
+archive_entry_acl_add_entry(struct archive_entry *entry,
+ int type, int permset, int tag, int id, const char *name)
+{
+ return archive_acl_add_entry(&entry->acl, type, permset, tag, id, name);
+}
+
+/*
+ * As above, but with a wide-character name.
+ */
+int
+archive_entry_acl_add_entry_w(struct archive_entry *entry,
+ int type, int permset, int tag, int id, const wchar_t *name)
+{
+ return archive_acl_add_entry_w_len(&entry->acl,
+ type, permset, tag, id, name, wcslen(name));
+}
+
+/*
+ * Return a count of entries matching "want_type".
+ */
+int
+archive_entry_acl_count(struct archive_entry *entry, int want_type)
+{
+ return archive_acl_count(&entry->acl, want_type);
+}
+
+/*
+ * Prepare for reading entries from the ACL data. Returns a count
+ * of entries matching "want_type", or zero if there are no
+ * non-extended ACL entries of that type.
+ */
+int
+archive_entry_acl_reset(struct archive_entry *entry, int want_type)
+{
+ return archive_acl_reset(&entry->acl, want_type);
+}
+
+/*
+ * Return the next ACL entry in the list. Fake entries for the
+ * standard permissions and include them in the returned list.
+ */
+int
+archive_entry_acl_next(struct archive_entry *entry, int want_type, int *type,
+ int *permset, int *tag, int *id, const char **name)
+{
+ return archive_acl_next(entry->archive, &entry->acl, want_type, type, permset, tag, id, name);
+}
+
+/*
+ * Generate a text version of the ACL. The flags parameter controls
+ * the style of the generated ACL.
+ */
+const wchar_t *
+archive_entry_acl_text_w(struct archive_entry *entry, int flags)
+{
+ return archive_acl_text_w(entry->archive, &entry->acl, flags);
+}
+
+const char *
+archive_entry_acl_text(struct archive_entry *entry, int flags)
+{
+ const char *p;
+ if (archive_acl_text_l(&entry->acl, flags, &p, NULL, NULL) != 0
+ && errno == ENOMEM)
+ return (NULL);
+ return (p);
+}
+
+int
+_archive_entry_acl_text_l(struct archive_entry *entry, int flags,
+ const char **acl_text, size_t *len, struct archive_string_conv *sc)
+{
+ return (archive_acl_text_l(&entry->acl, flags, acl_text, len, sc));
+}
+
+/*
+ * Following code is modified from UC Berkeley sources, and
+ * is subject to the following copyright notice.
+ */
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. 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.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ */
+
+static struct flag {
+ const char *name;
+ const wchar_t *wname;
+ unsigned long set;
+ unsigned long clear;
+} flags[] = {
+ /* Preferred (shorter) names per flag first, all prefixed by "no" */
+#ifdef SF_APPEND
+ { "nosappnd", L"nosappnd", SF_APPEND, 0 },
+ { "nosappend", L"nosappend", SF_APPEND, 0 },
+#endif
+#ifdef EXT2_APPEND_FL /* 'a' */
+ { "nosappnd", L"nosappnd", EXT2_APPEND_FL, 0 },
+ { "nosappend", L"nosappend", EXT2_APPEND_FL, 0 },
+#endif
+#ifdef SF_ARCHIVED
+ { "noarch", L"noarch", SF_ARCHIVED, 0 },
+ { "noarchived", L"noarchived", SF_ARCHIVED, 0 },
+#endif
+#ifdef SF_IMMUTABLE
+ { "noschg", L"noschg", SF_IMMUTABLE, 0 },
+ { "noschange", L"noschange", SF_IMMUTABLE, 0 },
+ { "nosimmutable", L"nosimmutable", SF_IMMUTABLE, 0 },
+#endif
+#ifdef EXT2_IMMUTABLE_FL /* 'i' */
+ { "noschg", L"noschg", EXT2_IMMUTABLE_FL, 0 },
+ { "noschange", L"noschange", EXT2_IMMUTABLE_FL, 0 },
+ { "nosimmutable", L"nosimmutable", EXT2_IMMUTABLE_FL, 0 },
+#endif
+#ifdef SF_NOUNLINK
+ { "nosunlnk", L"nosunlnk", SF_NOUNLINK, 0 },
+ { "nosunlink", L"nosunlink", SF_NOUNLINK, 0 },
+#endif
+#ifdef SF_SNAPSHOT
+ { "nosnapshot", L"nosnapshot", SF_SNAPSHOT, 0 },
+#endif
+#ifdef UF_APPEND
+ { "nouappnd", L"nouappnd", UF_APPEND, 0 },
+ { "nouappend", L"nouappend", UF_APPEND, 0 },
+#endif
+#ifdef UF_IMMUTABLE
+ { "nouchg", L"nouchg", UF_IMMUTABLE, 0 },
+ { "nouchange", L"nouchange", UF_IMMUTABLE, 0 },
+ { "nouimmutable", L"nouimmutable", UF_IMMUTABLE, 0 },
+#endif
+#ifdef UF_NODUMP
+ { "nodump", L"nodump", 0, UF_NODUMP},
+#endif
+#ifdef EXT2_NODUMP_FL /* 'd' */
+ { "nodump", L"nodump", 0, EXT2_NODUMP_FL},
+#endif
+#ifdef UF_OPAQUE
+ { "noopaque", L"noopaque", UF_OPAQUE, 0 },
+#endif
+#ifdef UF_NOUNLINK
+ { "nouunlnk", L"nouunlnk", UF_NOUNLINK, 0 },
+ { "nouunlink", L"nouunlink", UF_NOUNLINK, 0 },
+#endif
+#ifdef EXT2_UNRM_FL
+ { "nouunlink", L"nouunlink", EXT2_UNRM_FL, 0},
+#endif
+
+#ifdef EXT2_BTREE_FL
+ { "nobtree", L"nobtree", EXT2_BTREE_FL, 0 },
+#endif
+
+#ifdef EXT2_ECOMPR_FL
+ { "nocomperr", L"nocomperr", EXT2_ECOMPR_FL, 0 },
+#endif
+
+#ifdef EXT2_COMPR_FL /* 'c' */
+ { "nocompress", L"nocompress", EXT2_COMPR_FL, 0 },
+#endif
+
+#ifdef EXT2_NOATIME_FL /* 'A' */
+ { "noatime", L"noatime", 0, EXT2_NOATIME_FL},
+#endif
+
+#ifdef EXT2_DIRTY_FL
+ { "nocompdirty",L"nocompdirty", EXT2_DIRTY_FL, 0},
+#endif
+
+#ifdef EXT2_COMPRBLK_FL
+#ifdef EXT2_NOCOMPR_FL
+ { "nocomprblk", L"nocomprblk", EXT2_COMPRBLK_FL, EXT2_NOCOMPR_FL},
+#else
+ { "nocomprblk", L"nocomprblk", EXT2_COMPRBLK_FL, 0},
+#endif
+#endif
+#ifdef EXT2_DIRSYNC_FL
+ { "nodirsync", L"nodirsync", EXT2_DIRSYNC_FL, 0},
+#endif
+#ifdef EXT2_INDEX_FL
+ { "nohashidx", L"nohashidx", EXT2_INDEX_FL, 0},
+#endif
+#ifdef EXT2_IMAGIC_FL
+ { "noimagic", L"noimagic", EXT2_IMAGIC_FL, 0},
+#endif
+#ifdef EXT3_JOURNAL_DATA_FL
+ { "nojournal", L"nojournal", EXT3_JOURNAL_DATA_FL, 0},
+#endif
+#ifdef EXT2_SECRM_FL
+ { "nosecuredeletion",L"nosecuredeletion",EXT2_SECRM_FL, 0},
+#endif
+#ifdef EXT2_SYNC_FL
+ { "nosync", L"nosync", EXT2_SYNC_FL, 0},
+#endif
+#ifdef EXT2_NOTAIL_FL
+ { "notail", L"notail", 0, EXT2_NOTAIL_FL},
+#endif
+#ifdef EXT2_TOPDIR_FL
+ { "notopdir", L"notopdir", EXT2_TOPDIR_FL, 0},
+#endif
+#ifdef EXT2_RESERVED_FL
+ { "noreserved", L"noreserved", EXT2_RESERVED_FL, 0},
+#endif
+
+ { NULL, NULL, 0, 0 }
+};
+
+/*
+ * fflagstostr --
+ * Convert file flags to a comma-separated string. If no flags
+ * are set, return the empty string.
+ */
+static char *
+ae_fflagstostr(unsigned long bitset, unsigned long bitclear)
+{
+ char *string, *dp;
+ const char *sp;
+ unsigned long bits;
+ struct flag *flag;
+ size_t length;
+
+ bits = bitset | bitclear;
+ length = 0;
+ for (flag = flags; flag->name != NULL; flag++)
+ if (bits & (flag->set | flag->clear)) {
+ length += strlen(flag->name) + 1;
+ bits &= ~(flag->set | flag->clear);
+ }
+
+ if (length == 0)
+ return (NULL);
+ string = (char *)malloc(length);
+ if (string == NULL)
+ return (NULL);
+
+ dp = string;
+ for (flag = flags; flag->name != NULL; flag++) {
+ if (bitset & flag->set || bitclear & flag->clear) {
+ sp = flag->name + 2;
+ } else if (bitset & flag->clear || bitclear & flag->set) {
+ sp = flag->name;
+ } else
+ continue;
+ bitset &= ~(flag->set | flag->clear);
+ bitclear &= ~(flag->set | flag->clear);
+ if (dp > string)
+ *dp++ = ',';
+ while ((*dp++ = *sp++) != '\0')
+ ;
+ dp--;
+ }
+
+ *dp = '\0';
+ return (string);
+}
+
+/*
+ * strtofflags --
+ * Take string of arguments and return file flags. This
+ * version works a little differently than strtofflags(3).
+ * In particular, it always tests every token, skipping any
+ * unrecognized tokens. It returns a pointer to the first
+ * unrecognized token, or NULL if every token was recognized.
+ * This version is also const-correct and does not modify the
+ * provided string.
+ */
+static const char *
+ae_strtofflags(const char *s, unsigned long *setp, unsigned long *clrp)
+{
+ const char *start, *end;
+ struct flag *flag;
+ unsigned long set, clear;
+ const char *failed;
+
+ set = clear = 0;
+ start = s;
+ failed = NULL;
+ /* Find start of first token. */
+ while (*start == '\t' || *start == ' ' || *start == ',')
+ start++;
+ while (*start != '\0') {
+ /* Locate end of token. */
+ end = start;
+ while (*end != '\0' && *end != '\t' &&
+ *end != ' ' && *end != ',')
+ end++;
+ for (flag = flags; flag->name != NULL; flag++) {
+ if (memcmp(start, flag->name, end - start) == 0) {
+ /* Matched "noXXXX", so reverse the sense. */
+ clear |= flag->set;
+ set |= flag->clear;
+ break;
+ } else if (memcmp(start, flag->name + 2, end - start)
+ == 0) {
+ /* Matched "XXXX", so don't reverse. */
+ set |= flag->set;
+ clear |= flag->clear;
+ break;
+ }
+ }
+ /* Ignore unknown flag names. */
+ if (flag->name == NULL && failed == NULL)
+ failed = start;
+
+ /* Find start of next token. */
+ start = end;
+ while (*start == '\t' || *start == ' ' || *start == ',')
+ start++;
+
+ }
+
+ if (setp)
+ *setp = set;
+ if (clrp)
+ *clrp = clear;
+
+ /* Return location of first failure. */
+ return (failed);
+}
+
+/*
+ * wcstofflags --
+ * Take string of arguments and return file flags. This
+ * version works a little differently than strtofflags(3).
+ * In particular, it always tests every token, skipping any
+ * unrecognized tokens. It returns a pointer to the first
+ * unrecognized token, or NULL if every token was recognized.
+ * This version is also const-correct and does not modify the
+ * provided string.
+ */
+static const wchar_t *
+ae_wcstofflags(const wchar_t *s, unsigned long *setp, unsigned long *clrp)
+{
+ const wchar_t *start, *end;
+ struct flag *flag;
+ unsigned long set, clear;
+ const wchar_t *failed;
+
+ set = clear = 0;
+ start = s;
+ failed = NULL;
+ /* Find start of first token. */
+ while (*start == L'\t' || *start == L' ' || *start == L',')
+ start++;
+ while (*start != L'\0') {
+ /* Locate end of token. */
+ end = start;
+ while (*end != L'\0' && *end != L'\t' &&
+ *end != L' ' && *end != L',')
+ end++;
+ for (flag = flags; flag->wname != NULL; flag++) {
+ if (wmemcmp(start, flag->wname, end - start) == 0) {
+ /* Matched "noXXXX", so reverse the sense. */
+ clear |= flag->set;
+ set |= flag->clear;
+ break;
+ } else if (wmemcmp(start, flag->wname + 2, end - start)
+ == 0) {
+ /* Matched "XXXX", so don't reverse. */
+ set |= flag->set;
+ clear |= flag->clear;
+ break;
+ }
+ }
+ /* Ignore unknown flag names. */
+ if (flag->wname == NULL && failed == NULL)
+ failed = start;
+
+ /* Find start of next token. */
+ start = end;
+ while (*start == L'\t' || *start == L' ' || *start == L',')
+ start++;
+
+ }
+
+ if (setp)
+ *setp = set;
+ if (clrp)
+ *clrp = clear;
+
+ /* Return location of first failure. */
+ return (failed);
+}
+
+
+#ifdef TEST
+#include <stdio.h>
+int
+main(int argc, char **argv)
+{
+ struct archive_entry *entry = archive_entry_new();
+ unsigned long set, clear;
+ const wchar_t *remainder;
+
+ remainder = archive_entry_copy_fflags_text_w(entry, L"nosappnd dump archive,,,,,,,");
+ archive_entry_fflags(entry, &set, &clear);
+
+ wprintf(L"set=0x%lX clear=0x%lX remainder='%ls'\n", set, clear, remainder);
+
+ wprintf(L"new flags='%s'\n", archive_entry_fflags_text(entry));
+ return (0);
+}
+#endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry.h b/Utilities/cmlibarchive/libarchive/archive_entry.h
new file mode 100644
index 000000000..9c44e25f8
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_entry.h
@@ -0,0 +1,620 @@
+/*-
+ * Copyright (c) 2003-2008 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.
+ *
+ * $FreeBSD: head/lib/libarchive/archive_entry.h 201096 2009-12-28 02:41:27Z kientzle $
+ */
+
+#ifndef ARCHIVE_ENTRY_H_INCLUDED
+#define ARCHIVE_ENTRY_H_INCLUDED
+
+/* Note: Compiler will complain if this does not match archive.h! */
+#define ARCHIVE_VERSION_NUMBER 3000002
+
+/*
+ * Note: archive_entry.h is for use outside of libarchive; the
+ * configuration headers (config.h, archive_platform.h, etc.) are
+ * purely internal. Do NOT use HAVE_XXX configuration macros to
+ * control the behavior of this header! If you must conditionalize,
+ * use predefined compiler and/or platform macros.
+ */
+
+#include <sys/types.h>
+#include <stddef.h> /* for wchar_t */
+#include <time.h>
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#include <windows.h>
+#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(__BORLANDC__)
+# define __LA_UID_T uid_t /* Remove in libarchive 3.2 */
+# define __LA_GID_T gid_t /* Remove in libarchive 3.2 */
+# define __LA_DEV_T dev_t
+# define __LA_MODE_T mode_t
+# else
+# define __LA_UID_T short /* Remove in libarchive 3.2 */
+# define __LA_GID_T short /* Remove in libarchive 3.2 */
+# define __LA_DEV_T unsigned int
+# define __LA_MODE_T unsigned short
+# endif
+#else
+#include <unistd.h>
+# if defined(_SCO_DS) || defined(__osf__)
+# define __LA_INT64_T long long
+# else
+# define __LA_INT64_T int64_t
+# endif
+# define __LA_UID_T uid_t /* Remove in libarchive 3.2 */
+# define __LA_GID_T gid_t /* Remove in libarchive 3.2 */
+# define __LA_DEV_T dev_t
+# define __LA_MODE_T mode_t
+#endif
+
+/*
+ * Remove this for libarchive 3.2, since ino_t is no longer used.
+ */
+#define __LA_INO_T ino_t
+
+
+/*
+ * On Windows, define LIBARCHIVE_STATIC if you're building or using a
+ * .lib. The default here assumes you're building a DLL. Only
+ * libarchive source should ever define __LIBARCHIVE_BUILD.
+ */
+#if ((defined __WIN32__) || (defined _WIN32) || defined(__CYGWIN__)) && (!defined LIBARCHIVE_STATIC)
+# ifdef __LIBARCHIVE_BUILD
+# ifdef __GNUC__
+# define __LA_DECL __attribute__((dllexport)) extern
+# else
+# define __LA_DECL __declspec(dllexport)
+# endif
+# else
+# ifdef __GNUC__
+# define __LA_DECL
+# else
+# define __LA_DECL __declspec(dllimport)
+# endif
+# endif
+#else
+/* Static libraries on all platforms and shared libraries on non-Windows. */
+# define __LA_DECL
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Description of an archive entry.
+ *
+ * You can think of this as "struct stat" with some text fields added in.
+ *
+ * TODO: Add "comment", "charset", and possibly other entries that are
+ * supported by "pax interchange" format. However, GNU, ustar, cpio,
+ * and other variants don't support these features, so they're not an
+ * excruciatingly high priority right now.
+ *
+ * TODO: "pax interchange" format allows essentially arbitrary
+ * key/value attributes to be attached to any entry. Supporting
+ * such extensions may make this library useful for special
+ * applications (e.g., a package manager could attach special
+ * package-management attributes to each entry).
+ */
+struct archive;
+struct archive_entry;
+
+/*
+ * File-type constants. These are returned from archive_entry_filetype()
+ * and passed to archive_entry_set_filetype().
+ *
+ * These values match S_XXX defines on every platform I've checked,
+ * including Windows, AIX, Linux, Solaris, and BSD. They're
+ * (re)defined here because platforms generally don't define the ones
+ * they don't support. For example, Windows doesn't define S_IFLNK or
+ * S_IFBLK. Instead of having a mass of conditional logic and system
+ * checks to define any S_XXX values that aren't supported locally,
+ * I've just defined a new set of such constants so that
+ * libarchive-based applications can manipulate and identify archive
+ * entries properly even if the hosting platform can't store them on
+ * disk.
+ *
+ * These values are also used directly within some portable formats,
+ * such as cpio. If you find a platform that varies from these, the
+ * correct solution is to leave these alone and translate from these
+ * portable values to platform-native values when entries are read from
+ * or written to disk.
+ */
+#define AE_IFMT ((__LA_MODE_T)0170000)
+#define AE_IFREG ((__LA_MODE_T)0100000)
+#define AE_IFLNK ((__LA_MODE_T)0120000)
+#define AE_IFSOCK ((__LA_MODE_T)0140000)
+#define AE_IFCHR ((__LA_MODE_T)0020000)
+#define AE_IFBLK ((__LA_MODE_T)0060000)
+#define AE_IFDIR ((__LA_MODE_T)0040000)
+#define AE_IFIFO ((__LA_MODE_T)0010000)
+
+/*
+ * Basic object manipulation
+ */
+
+__LA_DECL struct archive_entry *archive_entry_clear(struct archive_entry *);
+/* The 'clone' function does a deep copy; all of the strings are copied too. */
+__LA_DECL struct archive_entry *archive_entry_clone(struct archive_entry *);
+__LA_DECL void archive_entry_free(struct archive_entry *);
+__LA_DECL struct archive_entry *archive_entry_new(void);
+
+/*
+ * This form of archive_entry_new2() will pull character-set
+ * conversion information from the specified archive handle. The
+ * older archive_entry_new(void) form is equivalent to calling
+ * archive_entry_new2(NULL) and will result in the use of an internal
+ * default character-set conversion.
+ */
+__LA_DECL struct archive_entry *archive_entry_new2(struct archive *);
+
+/*
+ * Retrieve fields from an archive_entry.
+ *
+ * There are a number of implicit conversions among these fields. For
+ * example, if a regular string field is set and you read the _w wide
+ * character field, the entry will implicitly convert narrow-to-wide
+ * using the current locale. Similarly, dev values are automatically
+ * updated when you write devmajor or devminor and vice versa.
+ *
+ * In addition, fields can be "set" or "unset." Unset string fields
+ * return NULL, non-string fields have _is_set() functions to test
+ * whether they've been set. You can "unset" a string field by
+ * assigning NULL; non-string fields have _unset() functions to
+ * unset them.
+ *
+ * Note: There is one ambiguity in the above; string fields will
+ * also return NULL when implicit character set conversions fail.
+ * This is usually what you want.
+ */
+__LA_DECL time_t archive_entry_atime(struct archive_entry *);
+__LA_DECL long archive_entry_atime_nsec(struct archive_entry *);
+__LA_DECL int archive_entry_atime_is_set(struct archive_entry *);
+__LA_DECL time_t archive_entry_birthtime(struct archive_entry *);
+__LA_DECL long archive_entry_birthtime_nsec(struct archive_entry *);
+__LA_DECL int archive_entry_birthtime_is_set(struct archive_entry *);
+__LA_DECL time_t archive_entry_ctime(struct archive_entry *);
+__LA_DECL long archive_entry_ctime_nsec(struct archive_entry *);
+__LA_DECL int archive_entry_ctime_is_set(struct archive_entry *);
+__LA_DECL dev_t archive_entry_dev(struct archive_entry *);
+__LA_DECL int archive_entry_dev_is_set(struct archive_entry *);
+__LA_DECL dev_t archive_entry_devmajor(struct archive_entry *);
+__LA_DECL dev_t archive_entry_devminor(struct archive_entry *);
+__LA_DECL __LA_MODE_T archive_entry_filetype(struct archive_entry *);
+__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 const char *archive_entry_gname(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 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 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 *);
+__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 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 *);
+__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 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 wchar_t *archive_entry_symlink_w(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 wchar_t *archive_entry_uname_w(struct archive_entry *);
+
+/*
+ * Set fields in an archive_entry.
+ *
+ * Note: Before libarchive 2.4, there were 'set' and 'copy' versions
+ * of the string setters. 'copy' copied the actual string, 'set' just
+ * stored the pointer. In libarchive 2.4 and later, strings are
+ * always copied.
+ */
+
+__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 *);
+#endif
+__LA_DECL void archive_entry_set_birthtime(struct archive_entry *, time_t, long);
+__LA_DECL void archive_entry_unset_birthtime(struct archive_entry *);
+__LA_DECL void archive_entry_set_ctime(struct archive_entry *, time_t, long);
+__LA_DECL void archive_entry_unset_ctime(struct archive_entry *);
+__LA_DECL void archive_entry_set_dev(struct archive_entry *, dev_t);
+__LA_DECL void archive_entry_set_devmajor(struct archive_entry *, dev_t);
+__LA_DECL void archive_entry_set_devminor(struct archive_entry *, dev_t);
+__LA_DECL void archive_entry_set_filetype(struct archive_entry *, unsigned int);
+__LA_DECL void archive_entry_set_fflags(struct archive_entry *,
+ unsigned long /* set */, unsigned long /* clear */);
+/* Returns pointer to start of first invalid token, or NULL if none. */
+/* Note that all recognized tokens are processed, regardless. */
+__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_gname(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_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_link(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 *);
+__LA_DECL void archive_entry_set_mode(struct archive_entry *, __LA_MODE_T);
+__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_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 *);
+__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_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_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_uname(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 *);
+/*
+ * Routines to bulk copy fields to/from a platform-native "struct
+ * stat." Libarchive used to just store a struct stat inside of each
+ * archive_entry object, but this created issues when trying to
+ * manipulate archives on systems different than the ones they were
+ * created on.
+ *
+ * TODO: On Linux, provide both stat32 and stat64 versions of these functions.
+ */
+__LA_DECL const struct stat *archive_entry_stat(struct archive_entry *);
+__LA_DECL void archive_entry_copy_stat(struct archive_entry *, const struct stat *);
+
+/*
+ * Storage for Mac OS-specific AppleDouble metadata information.
+ * Apple-format tar files store a separate binary blob containing
+ * encoded metadata with ACL, extended attributes, etc.
+ * This provides a place to store that blob.
+ */
+
+__LA_DECL const void * archive_entry_mac_metadata(struct archive_entry *, size_t *);
+__LA_DECL void archive_entry_copy_mac_metadata(struct archive_entry *, const void *, size_t);
+
+/*
+ * ACL routines. This used to simply store and return text-format ACL
+ * strings, but that proved insufficient for a number of reasons:
+ * = clients need control over uname/uid and gname/gid mappings
+ * = there are many different ACL text formats
+ * = would like to be able to read/convert archives containing ACLs
+ * on platforms that lack ACL libraries
+ *
+ * This last point, in particular, forces me to implement a reasonably
+ * complete set of ACL support routines.
+ */
+
+/*
+ * Permission bits.
+ */
+#define ARCHIVE_ENTRY_ACL_EXECUTE 0x00000001
+#define ARCHIVE_ENTRY_ACL_WRITE 0x00000002
+#define ARCHIVE_ENTRY_ACL_READ 0x00000004
+#define ARCHIVE_ENTRY_ACL_READ_DATA 0x00000008
+#define ARCHIVE_ENTRY_ACL_LIST_DIRECTORY 0x00000008
+#define ARCHIVE_ENTRY_ACL_WRITE_DATA 0x00000010
+#define ARCHIVE_ENTRY_ACL_ADD_FILE 0x00000010
+#define ARCHIVE_ENTRY_ACL_APPEND_DATA 0x00000020
+#define ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY 0x00000020
+#define ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS 0x00000040
+#define ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS 0x00000080
+#define ARCHIVE_ENTRY_ACL_DELETE_CHILD 0x00000100
+#define ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES 0x00000200
+#define ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES 0x00000400
+#define ARCHIVE_ENTRY_ACL_DELETE 0x00000800
+#define ARCHIVE_ENTRY_ACL_READ_ACL 0x00001000
+#define ARCHIVE_ENTRY_ACL_WRITE_ACL 0x00002000
+#define ARCHIVE_ENTRY_ACL_WRITE_OWNER 0x00004000
+#define ARCHIVE_ENTRY_ACL_SYNCHRONIZE 0x00008000
+
+#define ARCHIVE_ENTRY_ACL_PERMS_POSIX1E \
+ (ARCHIVE_ENTRY_ACL_EXECUTE \
+ | ARCHIVE_ENTRY_ACL_WRITE \
+ | ARCHIVE_ENTRY_ACL_READ)
+
+#define ARCHIVE_ENTRY_ACL_PERMS_NFS4 \
+ (ARCHIVE_ENTRY_ACL_EXECUTE \
+ | ARCHIVE_ENTRY_ACL_READ_DATA \
+ | ARCHIVE_ENTRY_ACL_LIST_DIRECTORY \
+ | ARCHIVE_ENTRY_ACL_WRITE_DATA \
+ | ARCHIVE_ENTRY_ACL_ADD_FILE \
+ | ARCHIVE_ENTRY_ACL_APPEND_DATA \
+ | ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY \
+ | ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS \
+ | ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS \
+ | ARCHIVE_ENTRY_ACL_DELETE_CHILD \
+ | ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES \
+ | ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES \
+ | ARCHIVE_ENTRY_ACL_DELETE \
+ | ARCHIVE_ENTRY_ACL_READ_ACL \
+ | ARCHIVE_ENTRY_ACL_WRITE_ACL \
+ | ARCHIVE_ENTRY_ACL_WRITE_OWNER \
+ | ARCHIVE_ENTRY_ACL_SYNCHRONIZE)
+
+/*
+ * Inheritance values (NFS4 ACLs only); included in permset.
+ */
+#define ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT 0x02000000
+#define ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT 0x04000000
+#define ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT 0x08000000
+#define ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY 0x10000000
+#define ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS 0x20000000
+#define ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS 0x40000000
+
+#define ARCHIVE_ENTRY_ACL_INHERITANCE_NFS4 \
+ (ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT \
+ | ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT \
+ | ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT \
+ | ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY \
+ | ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS \
+ | ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS)
+
+/* We need to be able to specify combinations of these. */
+#define ARCHIVE_ENTRY_ACL_TYPE_ACCESS 256 /* POSIX.1e only */
+#define ARCHIVE_ENTRY_ACL_TYPE_DEFAULT 512 /* POSIX.1e only */
+#define ARCHIVE_ENTRY_ACL_TYPE_ALLOW 1024 /* NFS4 only */
+#define ARCHIVE_ENTRY_ACL_TYPE_DENY 2048 /* NFS4 only */
+#define ARCHIVE_ENTRY_ACL_TYPE_AUDIT 4096 /* NFS4 only */
+#define ARCHIVE_ENTRY_ACL_TYPE_ALARM 8192 /* NFS4 only */
+#define ARCHIVE_ENTRY_ACL_TYPE_POSIX1E (ARCHIVE_ENTRY_ACL_TYPE_ACCESS \
+ | ARCHIVE_ENTRY_ACL_TYPE_DEFAULT)
+#define ARCHIVE_ENTRY_ACL_TYPE_NFS4 (ARCHIVE_ENTRY_ACL_TYPE_ALLOW \
+ | ARCHIVE_ENTRY_ACL_TYPE_DENY \
+ | ARCHIVE_ENTRY_ACL_TYPE_AUDIT \
+ | ARCHIVE_ENTRY_ACL_TYPE_ALARM)
+
+/* Tag values mimic POSIX.1e */
+#define ARCHIVE_ENTRY_ACL_USER 10001 /* Specified user. */
+#define ARCHIVE_ENTRY_ACL_USER_OBJ 10002 /* User who owns the file. */
+#define ARCHIVE_ENTRY_ACL_GROUP 10003 /* Specified group. */
+#define ARCHIVE_ENTRY_ACL_GROUP_OBJ 10004 /* Group who owns the file. */
+#define ARCHIVE_ENTRY_ACL_MASK 10005 /* Modify group access (POSIX.1e only) */
+#define ARCHIVE_ENTRY_ACL_OTHER 10006 /* Public (POSIX.1e only) */
+#define ARCHIVE_ENTRY_ACL_EVERYONE 10107 /* Everyone (NFS4 only) */
+
+/*
+ * Set the ACL by clearing it and adding entries one at a time.
+ * Unlike the POSIX.1e ACL routines, you must specify the type
+ * (access/default) for each entry. Internally, the ACL data is just
+ * a soup of entries. API calls here allow you to retrieve just the
+ * entries of interest. This design (which goes against the spirit of
+ * POSIX.1e) is useful for handling archive formats that combine
+ * default and access information in a single ACL list.
+ */
+__LA_DECL void archive_entry_acl_clear(struct archive_entry *);
+__LA_DECL int archive_entry_acl_add_entry(struct archive_entry *,
+ int /* type */, int /* permset */, int /* tag */,
+ int /* qual */, const char * /* name */);
+__LA_DECL int archive_entry_acl_add_entry_w(struct archive_entry *,
+ int /* type */, int /* permset */, int /* tag */,
+ int /* qual */, const wchar_t * /* name */);
+
+/*
+ * To retrieve the ACL, first "reset", then repeatedly ask for the
+ * "next" entry. The want_type parameter allows you to request only
+ * certain types of entries.
+ */
+__LA_DECL int archive_entry_acl_reset(struct archive_entry *, int /* want_type */);
+__LA_DECL int archive_entry_acl_next(struct archive_entry *, int /* want_type */,
+ int * /* type */, int * /* permset */, int * /* tag */,
+ int * /* qual */, const char ** /* name */);
+__LA_DECL int archive_entry_acl_next_w(struct archive_entry *, int /* want_type */,
+ int * /* type */, int * /* permset */, int * /* tag */,
+ int * /* qual */, const wchar_t ** /* name */);
+
+/*
+ * Construct a text-format ACL. The flags argument is a bitmask that
+ * can include any of the following:
+ *
+ * ARCHIVE_ENTRY_ACL_TYPE_ACCESS - Include POSIX.1e "access" entries.
+ * ARCHIVE_ENTRY_ACL_TYPE_DEFAULT - Include POSIX.1e "default" entries.
+ * ARCHIVE_ENTRY_ACL_TYPE_NFS4 - Include NFS4 entries.
+ * ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID - Include extra numeric ID field in
+ * each ACL entry. ('star' introduced this for POSIX.1e, this flag
+ * also applies to NFS4.)
+ * ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT - Include "default:" before each
+ * default ACL entry, as used in old Solaris ACLs.
+ */
+#define ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID 1024
+#define ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT 2048
+__LA_DECL const wchar_t *archive_entry_acl_text_w(struct archive_entry *,
+ int /* flags */);
+__LA_DECL const char *archive_entry_acl_text(struct archive_entry *,
+ int /* flags */);
+
+/* Return a count of entries matching 'want_type' */
+__LA_DECL int archive_entry_acl_count(struct archive_entry *, int /* want_type */);
+
+/* Return an opaque ACL object. */
+/* There's not yet anything clients can actually do with this... */
+struct archive_acl;
+__LA_DECL struct archive_acl *archive_entry_acl(struct archive_entry *);
+
+/*
+ * extended attributes
+ */
+
+__LA_DECL void archive_entry_xattr_clear(struct archive_entry *);
+__LA_DECL void archive_entry_xattr_add_entry(struct archive_entry *,
+ const char * /* name */, const void * /* value */,
+ size_t /* size */);
+
+/*
+ * To retrieve the xattr list, first "reset", then repeatedly ask for the
+ * "next" entry.
+ */
+
+__LA_DECL int archive_entry_xattr_count(struct archive_entry *);
+__LA_DECL int archive_entry_xattr_reset(struct archive_entry *);
+__LA_DECL int archive_entry_xattr_next(struct archive_entry *,
+ const char ** /* name */, const void ** /* value */, size_t *);
+
+/*
+ * sparse
+ */
+
+__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 */);
+
+/*
+ * To retrieve the xattr list, first "reset", then repeatedly ask for the
+ * "next" 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 */);
+
+/*
+ * Utility to match up hardlinks.
+ *
+ * The 'struct archive_entry_linkresolver' is a cache of archive entries
+ * for files with multiple links. Here's how to use it:
+ * 1. Create a lookup object with archive_entry_linkresolver_new()
+ * 2. Tell it the archive format you're using.
+ * 3. Hand each archive_entry to archive_entry_linkify().
+ * That function will return 0, 1, or 2 entries that should
+ * be written.
+ * 4. Call archive_entry_linkify(resolver, NULL) until
+ * no more entries are returned.
+ * 5. Call archive_entry_linkresolver_free(resolver) to free resources.
+ *
+ * The entries returned have their hardlink and size fields updated
+ * appropriately. If an entry is passed in that does not refer to
+ * a file with multiple links, it is returned unchanged. The intention
+ * is that you should be able to simply filter all entries through
+ * this machine.
+ *
+ * To make things more efficient, be sure that each entry has a valid
+ * nlinks value. The hardlink cache uses this to track when all links
+ * have been found. If the nlinks value is zero, it will keep every
+ * name in the cache indefinitely, which can use a lot of memory.
+ *
+ * Note that archive_entry_size() is reset to zero if the file
+ * body should not be written to the archive. Pay attention!
+ */
+struct archive_entry_linkresolver;
+
+/*
+ * There are three different strategies for marking hardlinks.
+ * The descriptions below name them after the best-known
+ * formats that rely on each strategy:
+ *
+ * "Old cpio" is the simplest, it always returns any entry unmodified.
+ * As far as I know, only cpio formats use this. Old cpio archives
+ * store every link with the full body; the onus is on the dearchiver
+ * to detect and properly link the files as they are restored.
+ * "tar" is also pretty simple; it caches a copy the first time it sees
+ * any link. Subsequent appearances are modified to be hardlink
+ * references to the first one without any body. Used by all tar
+ * formats, although the newest tar formats permit the "old cpio" strategy
+ * as well. This strategy is very simple for the dearchiver,
+ * and reasonably straightforward for the archiver.
+ * "new cpio" is trickier. It stores the body only with the last
+ * occurrence. The complication is that we might not
+ * see every link to a particular file in a single session, so
+ * there's no easy way to know when we've seen the last occurrence.
+ * The solution here is to queue one link until we see the next.
+ * At the end of the session, you can enumerate any remaining
+ * entries by calling archive_entry_linkify(NULL) and store those
+ * bodies. If you have a file with three links l1, l2, and l3,
+ * you'll get the following behavior if you see all three links:
+ * linkify(l1) => NULL (the resolver stores l1 internally)
+ * linkify(l2) => l1 (resolver stores l2, you write l1)
+ * linkify(l3) => l2, l3 (all links seen, you can write both).
+ * If you only see l1 and l2, you'll get this behavior:
+ * linkify(l1) => NULL
+ * linkify(l2) => l1
+ * linkify(NULL) => l2 (at end, you retrieve remaining links)
+ * As the name suggests, this strategy is used by newer cpio variants.
+ * It's noticeably more complex for the archiver, slightly more complex
+ * for the dearchiver than the tar strategy, but makes it straightforward
+ * to restore a file using any link by simply continuing to scan until
+ * you see a link that is stored with a body. In contrast, the tar
+ * strategy requires you to rescan the archive from the beginning to
+ * correctly extract an arbitrary link.
+ */
+
+__LA_DECL struct archive_entry_linkresolver *archive_entry_linkresolver_new(void);
+__LA_DECL void archive_entry_linkresolver_set_strategy(
+ struct archive_entry_linkresolver *, int /* format_code */);
+__LA_DECL void archive_entry_linkresolver_free(struct archive_entry_linkresolver *);
+__LA_DECL void archive_entry_linkify(struct archive_entry_linkresolver *,
+ struct archive_entry **, struct archive_entry **);
+__LA_DECL struct archive_entry *archive_entry_partial_links(
+ struct archive_entry_linkresolver *res, unsigned int *links);
+
+#ifdef __cplusplus
+}
+#endif
+
+/* This is meaningless outside of this header. */
+#undef __LA_DECL
+
+#endif /* !ARCHIVE_ENTRY_H_INCLUDED */
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_acl.3 b/Utilities/cmlibarchive/libarchive/archive_entry_acl.3
new file mode 100644
index 000000000..93906e798
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_acl.3
@@ -0,0 +1,233 @@
+.\" Copyright (c) 2010 Joerg Sonnenberger
+.\" 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.
+.\"
+.Dd February 21, 2010
+.Dt ARCHIVE_ENTRY_ACL 3
+.Os
+.Sh NAME
+.Nm archive_entry_acl_add_entry ,
+.Nm archive_entry_acl_add_entry_w ,
+.Nm archive_entry_acl_clear ,
+.Nm archive_entry_acl_count ,
+.Nm archive_entry_acl_next ,
+.Nm archive_entry_acl_next_w ,
+.Nm archive_entry_acl_reset ,
+.Nm archive_entry_acl_text_w
+.Nd functions for manipulating Access Control Lists in archive entry descriptions
+.Sh SYNOPSIS
+.In archive_entry.h
+.Ft void
+.Fo archive_entry_acl_add_entry
+.Fa "struct archive_entry *a"
+.Fa "int type"
+.Fa "int permset"
+.Fa "int tag"
+.Fa "int qualifier"
+.Fa "const char *name"
+.Fc
+.Ft void
+.Fo archive_entry_acl_add_entry_w
+.Fa "struct archive_entry *a"
+.Fa "int type"
+.Fa "int permset"
+.Fa "int tag"
+.Fa "int qualifier"
+.Fa "const wchar_t *name"
+.Fc
+.Ft void
+.Fn archive_entry_acl_clear "struct archive_entry *a"
+.Ft int
+.Fn archive_entry_acl_count "struct archive_entry *a" "int type"
+.Ft int
+.Fo archive_entry_acl_next
+.Fa "struct archive_entry *a"
+.Fa "int type"
+.Fa "int *ret_type"
+.Fa "int *ret_permset"
+.Fa "int *ret_tag"
+.Fa "int *ret_qual"
+.Fa "const char **ret_name"
+.Fc
+.Ft int
+.Fo archive_entry_acl_next_w
+.Fa "struct archive_entry *a"
+.Fa "int type"
+.Fa "int *ret_type"
+.Fa "int *ret_permset"
+.Fa "int *ret_tag"
+.Fa "int *ret_qual"
+.Fa "const wchar_t **ret_name"
+.Fc
+.Ft int
+.Fn archive_entry_acl_reset "struct archive_entry *a" "int type"
+.Ft const wchar_t *
+.Fn archive_entry_acl_text_w "struct archive_entry *a" "int flags"
+.\" enum?
+.Sh DESCRIPTION
+An
+.Dq Access Control List
+is a generalisation of the classic Unix permission system.
+The ACL interface of
+.Nm libarchive
+is derived from the POSIX.1e draft, but restricted to simplify dealing
+with practical implementations in various Operating Systems and archive formats.
+.Pp
+An ACL consists of a number of independent entries.
+Each entry specifies the permission set as bitmask of basic permissions.
+Valid permissions are:
+.Bl -tag -offset indent -compact -width "ARCHIVE_ENTRY_ACL_EXECUTE"
+.It Dv ARCHIVE_ENTRY_ACL_EXECUTE
+.It Dv ARCHIVE_ENTRY_ACL_WRITE
+.It Dv ARCHIVE_ENTRY_ACL_READ
+.El
+The permissions correspond to the normal Unix permissions.
+.Pp
+The tag specifies the principal to which the permission applies.
+Valid values are:
+.Bl -tag -offset indent -compact -width "ARCHIVE_ENTRY_ACL_GROUP_OBJ"
+.It Dv ARCHIVE_ENTRY_ACL_USER
+The user specified by the name field.
+.It Dv ARCHIVE_ENTRY_ACL_USER_OBJ
+The owner of the file.
+.It Dv ARCHIVE_ENTRY_ACL_GROUP
+The group specied by the name field.
+.It Dv ARCHIVE_ENTRY_ACL_GROUP_OBJ
+The group who owns the file.
+.It Dv ARCHIVE_ENTRY_ACL_MASK
+The maximum permissions to be obtained via group permissions.
+.It Dv ARCHIVE_ENTRY_ACL_OTHER
+Any principal who doesn't have a user or group entry.
+.El
+The principals
+.Dv ARCHIVE_ENTRY_ACL_USER_OBJ ,
+.Dv ARCHIVE_ENTRY_ACL_GROUP_OBJ
+and
+.Dv ARCHIVE_ENTRY_ACL_OTHER
+are equivalent to user, group and other in the classic Unix permission
+model and specify non-extended ACL entries.
+.Pp
+All files have an access ACL
+.Pq Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS .
+This specifies the permissions required for access to the file itself.
+Directories have an additional ACL
+.Pq Dv ARCHIVE_ENTRY_ACL_TYPE_DEFAULT ,
+which controlls the initial access ACL for newly created directory entries.
+.Pp
+.Fn archive_entry_acl_add_entry
+and
+.Fn archive_entry_acl_add_entry_w
+add a single ACL entry.
+For the access ACL and non-extended principals, the classic Unix permissions
+are updated.
+.Pp
+.Fn archive_entry_acl_clear
+removes all ACL entries and resets the enumeration pointer.
+.Pp
+.Fn archive_entry_acl_count
+counts the ACL entries that have the given type mask.
+.Fa type
+can be the bitwise-or of
+.Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS
+and
+.Dv ARCHIVE_ENTRY_ACL_TYPE_DEFAULT .
+If
+.Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS
+is included and at least one extended ACL entry is found,
+the three non-extened ACLs are added.
+.Pp
+.Fn archive_entry_acl_next
+and
+.Fn archive_entry_acl_next_w
+return the next entry of the ACL list.
+This functions may only be called after
+.Fn archive_entry_acl_reset
+has indicated the presence of extended ACL entries.
+.Pp
+.Fn archive_entry_acl_reset
+prepare reading the list of ACL entries with
+.Fn archive_entry_acl_next
+or
+.Fn archive_entry_acl_next_w .
+The function returns either 0, if no non-extended ACLs are found.
+In this case, the access permissions should be obtained by
+.Xr archive_entry_mode 3
+or set using
+.Xr chmod 2 .
+Otherwise, the function returns the same value as
+.Fn archive_entry_acl_count .
+.Pp
+.Fn archive_entry_acl_text_w
+converts the ACL entries for the given type mask into a wide string.
+In addition to the normal type flags,
+.Dv ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID
+and
+.Dv ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT
+can be specified to further customize the result.
+The returned long string is valid until the next call to
+.Fn archive_entry_acl_clear ,
+.Fn archive_entry_acl_add_entry ,
+.Fn archive_entry_acl_add_entry_w
+or
+.Fn archive_entry_acl_text_w .
+.Sh RETURN VALUES
+.Fn archive_entry_acl_count
+and
+.Fn archive_entry_acl_reset
+returns the number of ACL entries that match the given type mask.
+If the type mask includes
+.Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS
+and at least one extended ACL entry exists, the three classic Unix
+permissions are counted.
+.Pp
+.Fn archive_entry_acl_next
+and
+.Fn archive_entry_acl_next_w
+return
+.Dv ARCHIVE_OK
+on success,
+.Dv ARCHIVE_EOF
+if no more ACL entries exist
+and
+.Dv ARCHIVE_WARN
+if
+.Fn archive_entry_acl_reset
+has not been called first.
+.Pp
+.Fn archive_entry_text_w
+returns a wide string representation of the ACL entrise matching the
+given type mask.
+The returned long string is valid until the next call to
+.Fn archive_entry_acl_clear ,
+.Fn archive_entry_acl_add_entry ,
+.Fn archive_entry_acl_add_entry_w
+or
+.Fn archive_entry_acl_text_w .
+.Sh SEE ALSO
+.Xr archive 3 ,
+.Xr archive_entry 3
+.Sh BUGS
+.Dv ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID
+and
+.Dv ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT
+are not documented.
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_copy_bhfi.c b/Utilities/cmlibarchive/libarchive/archive_entry_copy_bhfi.c
new file mode 100644
index 000000000..7a4bc9cd0
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_copy_bhfi.c
@@ -0,0 +1,75 @@
+/*-
+ * 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$");
+
+#include "archive_private.h"
+#include "archive_entry.h"
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+
+#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
+
+__inline static void
+fileTimeToUtc(const FILETIME *filetime, time_t *time, long *ns)
+{
+ ULARGE_INTEGER utc;
+
+ utc.HighPart = filetime->dwHighDateTime;
+ utc.LowPart = filetime->dwLowDateTime;
+ if (utc.QuadPart >= EPOC_TIME) {
+ utc.QuadPart -= EPOC_TIME;
+ *time = (time_t)(utc.QuadPart / 10000000); /* milli seconds base */
+ *ns = (long)(utc.QuadPart % 10000000) * 100;/* nano seconds base */
+ } else {
+ *time = 0;
+ *ns = 0;
+ }
+}
+
+void
+archive_entry_copy_bhfi(struct archive_entry *entry,
+ BY_HANDLE_FILE_INFORMATION *bhfi)
+{
+ time_t secs;
+ long nsecs;
+
+ fileTimeToUtc(&bhfi->ftLastAccessTime, &secs, &nsecs);
+ archive_entry_set_atime(entry, secs, nsecs);
+ fileTimeToUtc(&bhfi->ftLastWriteTime, &secs, &nsecs);
+ archive_entry_set_mtime(entry, secs, nsecs);
+ fileTimeToUtc(&bhfi->ftCreationTime, &secs, &nsecs);
+ archive_entry_set_birthtime(entry, secs, nsecs);
+ archive_entry_set_ctime(entry, secs, nsecs);
+ archive_entry_set_dev(entry, bhfi->dwVolumeSerialNumber);
+ archive_entry_set_ino64(entry, (((int64_t)bhfi->nFileIndexHigh) << 32)
+ + bhfi->nFileIndexLow);
+ archive_entry_set_nlink(entry, bhfi->nNumberOfLinks);
+ archive_entry_set_size(entry, (((int64_t)bhfi->nFileSizeHigh) << 32)
+ + bhfi->nFileSizeLow);
+ /* archive_entry_set_mode(entry, st->st_mode); */
+}
+#endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_copy_stat.c b/Utilities/cmlibarchive/libarchive/archive_entry_copy_stat.c
new file mode 100644
index 000000000..37d4d6edb
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_copy_stat.c
@@ -0,0 +1,79 @@
+/*-
+ * 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: head/lib/libarchive/archive_entry_copy_stat.c 189466 2009-03-07 00:52:02Z kientzle $");
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+#include "archive.h"
+#include "archive_entry.h"
+
+void
+archive_entry_copy_stat(struct archive_entry *entry, const struct stat *st)
+{
+#if HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC
+ archive_entry_set_atime(entry, st->st_atime, st->st_atimespec.tv_nsec);
+ archive_entry_set_ctime(entry, st->st_ctime, st->st_ctimespec.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_atime(entry, st->st_atime, st->st_atim.tv_nsec);
+ archive_entry_set_ctime(entry, st->st_ctime, st->st_ctim.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_atime(entry, st->st_atime, st->st_atime_n);
+ archive_entry_set_ctime(entry, st->st_ctime, st->st_ctime_n);
+ archive_entry_set_mtime(entry, st->st_mtime, st->st_mtime_n);
+#elif HAVE_STRUCT_STAT_ST_UMTIME
+ archive_entry_set_atime(entry, st->st_atime, st->st_uatime * 1000);
+ archive_entry_set_ctime(entry, st->st_ctime, st->st_uctime * 1000);
+ archive_entry_set_mtime(entry, st->st_mtime, st->st_umtime * 1000);
+#elif HAVE_STRUCT_STAT_ST_MTIME_USEC
+ archive_entry_set_atime(entry, st->st_atime, st->st_atime_usec * 1000);
+ archive_entry_set_ctime(entry, st->st_ctime, st->st_ctime_usec * 1000);
+ archive_entry_set_mtime(entry, st->st_mtime, st->st_mtime_usec * 1000);
+#else
+ archive_entry_set_atime(entry, st->st_atime, 0);
+ archive_entry_set_ctime(entry, st->st_ctime, 0);
+ archive_entry_set_mtime(entry, st->st_mtime, 0);
+#endif
+#if HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC
+ archive_entry_set_birthtime(entry, st->st_birthtime, st->st_birthtimespec.tv_nsec);
+#elif HAVE_STRUCT_STAT_ST_BIRTHTIME
+ archive_entry_set_birthtime(entry, st->st_birthtime, 0);
+#else
+ archive_entry_unset_birthtime(entry);
+#endif
+ archive_entry_set_dev(entry, st->st_dev);
+ archive_entry_set_gid(entry, st->st_gid);
+ archive_entry_set_uid(entry, st->st_uid);
+ archive_entry_set_ino(entry, st->st_ino);
+ archive_entry_set_nlink(entry, st->st_nlink);
+ archive_entry_set_rdev(entry, st->st_rdev);
+ archive_entry_set_size(entry, st->st_size);
+ archive_entry_set_mode(entry, st->st_mode);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_link_resolver.c b/Utilities/cmlibarchive/libarchive/archive_entry_link_resolver.c
new file mode 100644
index 000000000..a18144dd5
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_link_resolver.c
@@ -0,0 +1,444 @@
+/*-
+ * 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: head/lib/libarchive/archive_entry_link_resolver.c 201100 2009-12-28 03:05:31Z kientzle $");
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#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
+
+#include "archive.h"
+#include "archive_entry.h"
+
+/*
+ * This is mostly a pretty straightforward hash table implementation.
+ * The only interesting bit is the different strategies used to
+ * match up links. These strategies match those used by various
+ * archiving formats:
+ * tar - content stored with first link, remainder refer back to it.
+ * This requires us to match each subsequent link up with the
+ * first appearance.
+ * cpio - Old cpio just stored body with each link, match-ups were
+ * implicit. This is trivial.
+ * new cpio - New cpio only stores body with last link, match-ups
+ * are implicit. This is actually quite tricky; see the notes
+ * below.
+ */
+
+/* Users pass us a format code, we translate that into a strategy here. */
+#define ARCHIVE_ENTRY_LINKIFY_LIKE_TAR 0
+#define ARCHIVE_ENTRY_LINKIFY_LIKE_MTREE 1
+#define ARCHIVE_ENTRY_LINKIFY_LIKE_OLD_CPIO 2
+#define ARCHIVE_ENTRY_LINKIFY_LIKE_NEW_CPIO 3
+
+/* Initial size of link cache. */
+#define links_cache_initial_size 1024
+
+struct links_entry {
+ struct links_entry *next;
+ struct links_entry *previous;
+ struct archive_entry *canonical;
+ struct archive_entry *entry;
+ size_t hash;
+ unsigned int links; /* # links not yet seen */
+};
+
+struct archive_entry_linkresolver {
+ struct links_entry **buckets;
+ struct links_entry *spare;
+ unsigned long number_entries;
+ size_t number_buckets;
+ int strategy;
+};
+
+#define NEXT_ENTRY_DEFERRED 1
+#define NEXT_ENTRY_PARTIAL 2
+#define NEXT_ENTRY_ALL (NEXT_ENTRY_DEFERRED | NEXT_ENTRY_PARTIAL)
+
+static struct links_entry *find_entry(struct archive_entry_linkresolver *,
+ struct archive_entry *);
+static void grow_hash(struct archive_entry_linkresolver *);
+static struct links_entry *insert_entry(struct archive_entry_linkresolver *,
+ struct archive_entry *);
+static struct links_entry *next_entry(struct archive_entry_linkresolver *,
+ int);
+
+struct archive_entry_linkresolver *
+archive_entry_linkresolver_new(void)
+{
+ struct archive_entry_linkresolver *res;
+
+ /* Check for positive power-of-two */
+ if (links_cache_initial_size == 0 ||
+ (links_cache_initial_size & (links_cache_initial_size - 1)) != 0)
+ return (NULL);
+
+ res = calloc(1, sizeof(struct archive_entry_linkresolver));
+ if (res == NULL)
+ return (NULL);
+ res->number_buckets = links_cache_initial_size;
+ res->buckets = calloc(res->number_buckets, sizeof(res->buckets[0]));
+ if (res->buckets == NULL) {
+ free(res);
+ return (NULL);
+ }
+ return (res);
+}
+
+void
+archive_entry_linkresolver_set_strategy(struct archive_entry_linkresolver *res,
+ int fmt)
+{
+ int fmtbase = fmt & ARCHIVE_FORMAT_BASE_MASK;
+
+ switch (fmtbase) {
+ case ARCHIVE_FORMAT_7ZIP:
+ case ARCHIVE_FORMAT_AR:
+ case ARCHIVE_FORMAT_ZIP:
+ res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_OLD_CPIO;
+ break;
+ case ARCHIVE_FORMAT_CPIO:
+ switch (fmt) {
+ case ARCHIVE_FORMAT_CPIO_SVR4_NOCRC:
+ case ARCHIVE_FORMAT_CPIO_SVR4_CRC:
+ res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_NEW_CPIO;
+ break;
+ default:
+ res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_OLD_CPIO;
+ break;
+ }
+ break;
+ case ARCHIVE_FORMAT_MTREE:
+ res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_MTREE;
+ break;
+ case ARCHIVE_FORMAT_ISO9660:
+ case ARCHIVE_FORMAT_SHAR:
+ case ARCHIVE_FORMAT_TAR:
+ case ARCHIVE_FORMAT_XAR:
+ res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_TAR;
+ break;
+ default:
+ res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_OLD_CPIO;
+ break;
+ }
+}
+
+void
+archive_entry_linkresolver_free(struct archive_entry_linkresolver *res)
+{
+ struct links_entry *le;
+
+ if (res == NULL)
+ return;
+
+ while ((le = next_entry(res, NEXT_ENTRY_ALL)) != NULL)
+ archive_entry_free(le->entry);
+ free(res->buckets);
+ free(res);
+}
+
+void
+archive_entry_linkify(struct archive_entry_linkresolver *res,
+ struct archive_entry **e, struct archive_entry **f)
+{
+ struct links_entry *le;
+ struct archive_entry *t;
+
+ *f = NULL; /* Default: Don't return a second entry. */
+
+ if (*e == NULL) {
+ le = next_entry(res, NEXT_ENTRY_DEFERRED);
+ if (le != NULL) {
+ *e = le->entry;
+ le->entry = NULL;
+ }
+ return;
+ }
+
+ /* If it has only one link, then we're done. */
+ if (archive_entry_nlink(*e) == 1)
+ return;
+ /* Directories, devices never have hardlinks. */
+ if (archive_entry_filetype(*e) == AE_IFDIR
+ || archive_entry_filetype(*e) == AE_IFBLK
+ || archive_entry_filetype(*e) == AE_IFCHR)
+ return;
+
+ switch (res->strategy) {
+ case ARCHIVE_ENTRY_LINKIFY_LIKE_TAR:
+ le = find_entry(res, *e);
+ if (le != NULL) {
+ archive_entry_unset_size(*e);
+ archive_entry_copy_hardlink(*e,
+ archive_entry_pathname(le->canonical));
+ } else
+ insert_entry(res, *e);
+ return;
+ case ARCHIVE_ENTRY_LINKIFY_LIKE_MTREE:
+ le = find_entry(res, *e);
+ if (le != NULL) {
+ archive_entry_copy_hardlink(*e,
+ archive_entry_pathname(le->canonical));
+ } else
+ insert_entry(res, *e);
+ return;
+ case ARCHIVE_ENTRY_LINKIFY_LIKE_OLD_CPIO:
+ /* This one is trivial. */
+ return;
+ case ARCHIVE_ENTRY_LINKIFY_LIKE_NEW_CPIO:
+ le = find_entry(res, *e);
+ if (le != NULL) {
+ /*
+ * Put the new entry in le, return the
+ * old entry from le.
+ */
+ t = *e;
+ *e = le->entry;
+ le->entry = t;
+ /* Make the old entry into a hardlink. */
+ archive_entry_unset_size(*e);
+ archive_entry_copy_hardlink(*e,
+ archive_entry_pathname(le->canonical));
+ /* If we ran out of links, return the
+ * final entry as well. */
+ if (le->links == 0) {
+ *f = le->entry;
+ le->entry = NULL;
+ }
+ } else {
+ /*
+ * If we haven't seen it, tuck it away
+ * for future use.
+ */
+ le = insert_entry(res, *e);
+ le->entry = *e;
+ *e = NULL;
+ }
+ return;
+ default:
+ break;
+ }
+ return;
+}
+
+static struct links_entry *
+find_entry(struct archive_entry_linkresolver *res,
+ struct archive_entry *entry)
+{
+ struct links_entry *le;
+ size_t hash, bucket;
+ dev_t dev;
+ int64_t ino;
+
+ /* Free a held entry. */
+ if (res->spare != NULL) {
+ archive_entry_free(res->spare->canonical);
+ archive_entry_free(res->spare->entry);
+ free(res->spare);
+ res->spare = NULL;
+ }
+
+ dev = archive_entry_dev(entry);
+ ino = archive_entry_ino64(entry);
+ hash = (size_t)(dev ^ ino);
+
+ /* Try to locate this entry in the links cache. */
+ bucket = hash & (res->number_buckets - 1);
+ for (le = res->buckets[bucket]; le != NULL; le = le->next) {
+ if (le->hash == hash
+ && dev == archive_entry_dev(le->canonical)
+ && ino == archive_entry_ino64(le->canonical)) {
+ /*
+ * Decrement link count each time and release
+ * the entry if it hits zero. This saves
+ * memory and is necessary for detecting
+ * missed links.
+ */
+ --le->links;
+ if (le->links > 0)
+ return (le);
+ /* Remove it from this hash bucket. */
+ if (le->previous != NULL)
+ le->previous->next = le->next;
+ if (le->next != NULL)
+ le->next->previous = le->previous;
+ if (res->buckets[bucket] == le)
+ res->buckets[bucket] = le->next;
+ res->number_entries--;
+ /* Defer freeing this entry. */
+ res->spare = le;
+ return (le);
+ }
+ }
+ return (NULL);
+}
+
+static struct links_entry *
+next_entry(struct archive_entry_linkresolver *res, int mode)
+{
+ struct links_entry *le;
+ size_t bucket;
+
+ /* Free a held entry. */
+ if (res->spare != NULL) {
+ archive_entry_free(res->spare->canonical);
+ archive_entry_free(res->spare->entry);
+ free(res->spare);
+ res->spare = NULL;
+ }
+
+ /* Look for next non-empty bucket in the links cache. */
+ for (bucket = 0; bucket < res->number_buckets; bucket++) {
+ for (le = res->buckets[bucket]; le != NULL; le = le->next) {
+ if (le->entry != NULL &&
+ (mode & NEXT_ENTRY_DEFERRED) == 0)
+ continue;
+ if (le->entry == NULL &&
+ (mode & NEXT_ENTRY_PARTIAL) == 0)
+ continue;
+ /* Remove it from this hash bucket. */
+ if (le->next != NULL)
+ le->next->previous = le->previous;
+ if (le->previous != NULL)
+ le->previous->next = le->next;
+ else
+ res->buckets[bucket] = le->next;
+ res->number_entries--;
+ /* Defer freeing this entry. */
+ res->spare = le;
+ return (le);
+ }
+ }
+ return (NULL);
+}
+
+static struct links_entry *
+insert_entry(struct archive_entry_linkresolver *res,
+ struct archive_entry *entry)
+{
+ struct links_entry *le;
+ size_t hash, bucket;
+
+ /* Add this entry to the links cache. */
+ le = calloc(1, sizeof(struct links_entry));
+ if (le == NULL)
+ return (NULL);
+ le->canonical = archive_entry_clone(entry);
+
+ /* If the links cache is getting too full, enlarge the hash table. */
+ if (res->number_entries > res->number_buckets * 2)
+ grow_hash(res);
+
+ hash = archive_entry_dev(entry) ^ archive_entry_ino64(entry);
+ bucket = hash & (res->number_buckets - 1);
+
+ /* If we could allocate the entry, record it. */
+ if (res->buckets[bucket] != NULL)
+ res->buckets[bucket]->previous = le;
+ res->number_entries++;
+ le->next = res->buckets[bucket];
+ le->previous = NULL;
+ res->buckets[bucket] = le;
+ le->hash = hash;
+ le->links = archive_entry_nlink(entry) - 1;
+ return (le);
+}
+
+static void
+grow_hash(struct archive_entry_linkresolver *res)
+{
+ struct links_entry *le, **new_buckets;
+ size_t new_size;
+ size_t i, bucket;
+
+ /* Try to enlarge the bucket list. */
+ new_size = res->number_buckets * 2;
+ if (new_size < res->number_buckets)
+ return;
+ new_buckets = calloc(new_size, sizeof(struct links_entry *));
+
+ if (new_buckets == NULL)
+ return;
+
+ for (i = 0; i < res->number_buckets; i++) {
+ while (res->buckets[i] != NULL) {
+ /* Remove entry from old bucket. */
+ le = res->buckets[i];
+ res->buckets[i] = le->next;
+
+ /* Add entry to new bucket. */
+ bucket = le->hash & (new_size - 1);
+
+ if (new_buckets[bucket] != NULL)
+ new_buckets[bucket]->previous = le;
+ le->next = new_buckets[bucket];
+ le->previous = NULL;
+ new_buckets[bucket] = le;
+ }
+ }
+ free(res->buckets);
+ res->buckets = new_buckets;
+ res->number_buckets = new_size;
+}
+
+struct archive_entry *
+archive_entry_partial_links(struct archive_entry_linkresolver *res,
+ unsigned int *links)
+{
+ struct archive_entry *e;
+ struct links_entry *le;
+
+ /* Free a held entry. */
+ if (res->spare != NULL) {
+ archive_entry_free(res->spare->canonical);
+ archive_entry_free(res->spare->entry);
+ free(res->spare);
+ res->spare = NULL;
+ }
+
+ le = next_entry(res, NEXT_ENTRY_PARTIAL);
+ if (le != NULL) {
+ e = le->canonical;
+ if (links != NULL)
+ *links = le->links;
+ le->canonical = NULL;
+ } else {
+ e = NULL;
+ if (links != NULL)
+ *links = 0;
+ }
+ return (e);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_linkify.3 b/Utilities/cmlibarchive/libarchive/archive_entry_linkify.3
new file mode 100644
index 000000000..a34b095e7
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_linkify.3
@@ -0,0 +1,224 @@
+.\" Copyright (c) 2010 Joerg Sonnenberger
+.\" 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.
+.\"
+.Dd February 20, 2010
+.Dt ARCHIVE_ENTRY_LINKIFY 3
+.Os
+.Sh NAME
+.Nm archive_entry_linkresolver ,
+.Nm archive_entry_linkresolver_new ,
+.Nm archive_entry_linkresolver_set_strategy ,
+.Nm archive_entry_linkresolver_free ,
+.Nm archive_entry_linkify
+.Nd hardlink resolver functions
+.Sh LIBRARY
+.Lb libarchive
+.Sh SYNOPSIS
+.In archive_entry.h
+.Ft struct archive_entry_linkresolver *
+.Fn archive_entry_linkresolver_new void
+.Ft void
+.Fo archive_entry_linkresolver_set_strategy
+.Fa "struct archive_entry_linkresolver *resolver"
+.Fa "int format"
+.Fc
+.Ft void
+.Fo archive_entry_linkresolver_free
+.Fa "struct archive_entry_linkresolver *resolver"
+.Fc
+.Ft void
+.Fo archive_entry_linkify
+.Fa "struct archive_entry_linkresolver *resolver"
+.Fa "struct archive_entry **entry"
+.Fa "struct archive_entry **sparse"
+.Fc
+.Sh DESCRIPTION
+Programs that want to create archives have to deal with hardlinks.
+Hardlinks are handled in different ways by the archive formats.
+The basic strategies are:
+.Bl -enum
+.It
+Ignore hardlinks and store the body for each reference (old cpio, zip).
+.It
+Store the body the first time an inode is seen (ustar, pax).
+.It
+Store the body the last time an inode is seen (new cpio).
+.El
+.Pp
+The
+.Nm
+functions help by providing a unified interface and handling the complexity
+behind the scene.
+.Pp
+The
+.Nm
+functions assume that
+.Vt archive_entry
+instances have valid nlinks, inode and device values.
+The inode and device value is used to match entries.
+The nlinks value is used to determined if all references have been found and
+if the internal references can be recycled.
+.Pp
+The
+.Fn archive_entry_linkresolver_new
+function allocates a new link resolver.
+The instance can be freed using
+.Fn archive_entry_linkresolver_free .
+All deferred entries are flushed and the internal storage is freed.
+.Pp
+The
+.Fn archive_entry_linkresolver_set_strategy
+function selects the optimal hardlink strategy for the given format.
+The format code can be obtained from
+.Xr archive_format 3 .
+The function can be called more than once, but it is recommended to
+flush all deferred entries first.
+.Pp
+The
+.Fn archive_entry_linkify
+function is the core of
+.Nm .
+The
+.Fn entry
+argument points to the
+.Vt archive_entry
+that should be written.
+Depending on the strategy one of the following actions is taken:
+.Bl -enum
+.It
+For the simple archive formats
+.Va *entry
+is left unmodified and
+.Va *sparse
+is set to
+.Dv NULL .
+.It
+For tar like archive formats,
+.Va *sparse
+is set to
+.Dv NULL .
+If
+.Va *entry
+is
+.Dv NULL ,
+no action is taken.
+If the hardlink count of
+.Va *entry
+is larger than 1 and the file type is a regular file or symbolic link,
+the internal list is searched for a matching inode.
+If such an inode is found, the link count is decremented and the file size
+of
+.Va *entry
+is set to 0 to notify that no body should be written.
+If no such inode is found, a copy of the entry is added to the internal cache
+with a link count reduced by one.
+.It
+For new cpio like archive formats a value for
+.Va *entry
+of
+.Dv NULL
+is used to flush deferred entries.
+In that case
+.Va *entry
+is set to an arbitrary deferred entry and the entry itself is removed from the
+internal list.
+If the internal list is empty,
+.Va *entry
+is set to
+.Dv NULL .
+In either case,
+.Va *sparse
+is set to
+.Dv NULL
+and the function returns.
+If the hardlink count of
+.Va *entry
+is one or the file type is a directory or device,
+.Va *sparse
+is set to
+.Dv NULL
+and no further action is taken.
+Otherwise, the internal list is searched for a matching inode.
+If such an inode is not found, the entry is added to the internal list,
+both
+.Va *entry
+and
+.Va *sparse
+are set to
+.Dv NULL
+and the function returns.
+If such an inode is found, the link count is decremented.
+If it remains larger than one, the existing entry on the internal list
+is swapped with
+.Va *entry
+after retaining the link count.
+The existing entry is returned in
+.Va *entry .
+If the link count reached one, the new entry is also removed from the
+internal list and returned in
+.Va *sparse .
+Otherwise
+.Va *sparse
+is set to
+.Dv NULL .
+.El
+.Pp
+The general usage is therefore:
+.Bl -enum
+.It
+For each new archive entry, call
+.Fn archive_entry_linkify .
+.It
+Keep in mind that the entries returned may have a size of 0 now.
+.It
+If
+.Va *entry
+is not
+.Dv NULL ,
+archive it.
+.It
+If
+.Va *sparse
+is not
+.Dv NULL ,
+archive it.
+.It
+After all entries have been written to disk, call
+.Fn archive_entry_linkify
+with
+.Va *entry
+set to
+.Dv NULL
+and archive the returned entry as long as it is not
+.Dv NULL .
+.El
+.Sh RETURN VALUES
+.Fn archive_entry_linkresolver_new
+returns
+.Dv NULL
+on
+.Xr malloc 3
+failures.
+.Sh SEE ALSO
+.Xr archive_entry 3
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_locale.h b/Utilities/cmlibarchive/libarchive/archive_entry_locale.h
new file mode 100644
index 000000000..02e024ae2
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_locale.h
@@ -0,0 +1,88 @@
+/*-
+ * 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __LIBARCHIVE_BUILD
+#error This header is only to be used internally to libarchive.
+#endif
+
+#ifndef ARCHIVE_ENTRY_LOCALE_H_INCLUDED
+#define ARCHIVE_ENTRY_LOCALE_H_INCLUDED
+
+struct archive_entry;
+struct archive_string_conv;
+
+/*
+ * Utility functions to set and get entry attributes by translating
+ * character-set. These are designed for use in format readers and writers.
+ *
+ * The return code and interface of these are quite different from other
+ * functions for archive_entry defined in archive_entry.h.
+ * Common return code are:
+ * Return 0 if the string conversion succeeded.
+ * Return -1 if the string conversion failed.
+ */
+
+#define archive_entry_gname_l _archive_entry_gname_l
+int _archive_entry_gname_l(struct archive_entry *,
+ const char **, size_t *, struct archive_string_conv *);
+#define archive_entry_hardlink_l _archive_entry_hardlink_l
+int _archive_entry_hardlink_l(struct archive_entry *,
+ const char **, size_t *, struct archive_string_conv *);
+#define archive_entry_pathname_l _archive_entry_pathname_l
+int _archive_entry_pathname_l(struct archive_entry *,
+ const char **, size_t *, struct archive_string_conv *);
+#define archive_entry_symlink_l _archive_entry_symlink_l
+int _archive_entry_symlink_l(struct archive_entry *,
+ const char **, size_t *, struct archive_string_conv *);
+#define archive_entry_uname_l _archive_entry_uname_l
+int _archive_entry_uname_l(struct archive_entry *,
+ const char **, size_t *, struct archive_string_conv *);
+#define archive_entry_acl_text_l _archive_entry_acl_text_l
+int _archive_entry_acl_text_l(struct archive_entry *, int,
+ const char **, size_t *, struct archive_string_conv *);
+
+
+#define archive_entry_copy_gname_l _archive_entry_copy_gname_l
+int _archive_entry_copy_gname_l(struct archive_entry *,
+ const char *, size_t, struct archive_string_conv *);
+#define archive_entry_copy_hardlink_l _archive_entry_copy_hardlink_l
+int _archive_entry_copy_hardlink_l(struct archive_entry *,
+ const char *, size_t, struct archive_string_conv *);
+#define archive_entry_copy_link_l _archive_entry_copy_link_l
+int _archive_entry_copy_link_l(struct archive_entry *,
+ const char *, size_t, struct archive_string_conv *);
+#define archive_entry_copy_pathname_l _archive_entry_copy_pathname_l
+int _archive_entry_copy_pathname_l(struct archive_entry *,
+ const char *, size_t, struct archive_string_conv *);
+#define archive_entry_copy_symlink_l _archive_entry_copy_symlink_l
+int _archive_entry_copy_symlink_l(struct archive_entry *,
+ const char *, size_t, struct archive_string_conv *);
+#define archive_entry_copy_uname_l _archive_entry_copy_uname_l
+int _archive_entry_copy_uname_l(struct archive_entry *,
+ const char *, size_t, struct archive_string_conv *);
+
+#endif /* ARCHIVE_ENTRY_LOCALE_H_INCLUDED */
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_paths.3 b/Utilities/cmlibarchive/libarchive/archive_entry_paths.3
new file mode 100644
index 000000000..621f65518
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_paths.3
@@ -0,0 +1,151 @@
+.\" Copyright (c) 2010 Joerg Sonnenberger
+.\" 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.
+.\"
+.Dd February 22, 2010
+.Dt ARCHIVE_ENTRY_PATHS 3
+.Os
+.Sh NAME
+.Nm archive_entry_hardlink ,
+.Nm archive_entry_hardlink_w ,
+.Nm archive_entry_set_hardlink ,
+.Nm archive_entry_copy_hardlink ,
+.Nm archive_entry_copy_hardlink_w ,
+.Nm archve_entry_update_hardlink_utf8 ,
+.Nm archive_entry_set_link ,
+.Nm archive_entry_copy_link ,
+.Nm archive_entry_copy_link_w ,
+.Nm archve_entry_update_link_utf8 ,
+.Nm archive_entry_pathname ,
+.Nm archive_entry_pathname_w ,
+.Nm archive_entry_set_pathname ,
+.Nm archive_entry_copy_pathname ,
+.Nm archive_entry_copy_pathname_w ,
+.Nm archve_entry_update_pathname_utf8 ,
+.Nm archive_entry_sourcepath ,
+.Nm archive_entry_copy_sourcepath ,
+.Nm archive_entry_symlink,
+.Nm archive_entry_symlink_w,
+.Nm archive_entry_set_symlink ,
+.Nm archive_entry_copy_symlink ,
+.Nm archive_entry_copy_symlink_w ,
+.Nm archve_entry_update_symlink_utf8
+.Nd functions for manipulating path names in archive entry descriptions
+.Sh SYNOPSIS
+.In archive_entry.h
+.Ft const char *
+.Fn archive_entry_hardlink "struct archive_entry *a"
+.Ft const wchar_t *
+.Fn archive_entry_hardlink_w "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_hardlink "struct archive_entry *a" "const char *path"
+.Ft void
+.Fn archive_entry_copy_hardlink "struct archive_entry *a" "const char *path"
+.Ft void
+.Fn archive_entry_copy_hardlink_w "struct archive_entry *a "const wchar_t *path"
+.Ft int
+.Fn archive_entry_update_hardlink_utf8 "struct archive_entry *a" "const char *path"
+.Ft void
+.Fn archive_entry_set_link "struct archive_entry *a" "const char *path"
+.Ft void
+.Fn archive_entry_copy_link "struct archive_entry *a" " const char *path"
+.Ft void
+.Fn archive_entry_copy_link_w "struct archive_entry *a" " const wchar_t *path"
+.Ft int
+.Fn archive_entry_update_link_utf8 "struct archive_entry *a" " const char *path"
+.Ft const char *
+.Fn archive_entry_pathname "struct archive_entry *a"
+.Ft const wchar_t *
+.Fn archive_entry_pathname_w "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_pathname "struct archive_entry *a" "const char *path"
+.Ft void
+.Fn archive_entry_copy_pathname "struct archive_entry *a" "const char *path"
+.Ft void
+.Fn archive_entry_copy_pathname_w "struct archive_entry *a" "const wchar_t *path"
+.Ft int
+.Fn archive_entry_update_pathname_utf8 "struct archive_entry *a" "const char *path"
+.Ft const char *
+.Fn archive_entry_sourcepath "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_copy_sourcepath "struct archive_entry *a" "const char *path"
+.Ft const char *
+.Fn archive_entry_symlink "struct archive_entry *a"
+.Ft const wchar_t *
+.Fn archive_entry_symlink_w "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_symlink "struct archive_entry *a" "const char *path"
+.Ft void
+.Fn archive_entry_copy_symlink "struct archive_entry *a" "const char *path"
+.Ft void
+.Fn archive_entry_copy_symlink_w "struct archive_entry *a" "const wchar_t *path"
+.Ft int
+.Fn archive_entry_update_symlink_utf8 "struct archive_entry *a" "const char *path"
+.Sh DESCRIPTION
+Path names supported by
+.Xr archive_entry 3 :
+.Bl -tag -width "sourcepath" -compact
+.It hardlink
+Destination of the hardlink.
+.It link
+Update only.
+For a symlink, update the destination.
+Otherwise, make the entry a hardlink and alter
+the destination for that.
+.It pathname
+Path in the archive
+.It sourcepath
+Path on the disk for use by
+.Xr archive_read_disk 3 .
+.It symlink
+Destination of the symbolic link.
+.El
+.Pp
+Path names can be provided in one of three different ways:
+.Bl -tag -width "wchar_t *"
+.It char *
+Multibyte strings in the current locale.
+.It wchar_t *
+Wide character strings in the current locale.
+The accessor functions are named
+.Fn XXX_w .
+.It UTF-8
+Unicode strings encoded as UTF-8.
+This are convience functions to update both the multibyte and wide
+character strings at the same time.
+.El
+.Pp
+The sourcepath is a pure filesystem concept and never stored in an
+archive directly.
+.Pp
+For that reason, it is only available as multibyte string.
+The link path is a convience function for conditionally setting
+hardlink or symlink destination.
+It doesn't have a corresponding get accessor function.
+.Pp
+.Fn archive_entry_set_XXX
+is an alias for
+.Fn archive_entry_copy_XXX .
+.Sh SEE ALSO
+.Xr archive 3 ,
+.Xr archive_entry 3
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_perms.3 b/Utilities/cmlibarchive/libarchive/archive_entry_perms.3
new file mode 100644
index 000000000..164af9731
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_perms.3
@@ -0,0 +1,207 @@
+.\" Copyright (c) 2003-2007 Tim Kientzle
+.\" Copyright (c) 2010 Joerg Sonnenberger
+.\" 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.
+.\"
+.Dd February 22, 2010
+.Dt ARCHIVE_ENTRY_PERMS 3
+.Os
+.Sh NAME
+.Nm archive_entry_gid ,
+.Nm archive_entry_set_gid ,
+.Nm archive_entry_uid ,
+.Nm archive_entry_set_uid ,
+.Nm archive_entry_perm ,
+.Nm archive_entry_set_perm ,
+.Nm archive_entry_strmode ,
+.Nm archive_entry_uname
+.Nm archive_entry_uname_w
+.Nm archive_entry_set_uname ,
+.Nm archive_entry_copy_uname ,
+.Nm archive_entry_copy_uname_w ,
+.Nm archive_entry_update_uname_utf8 ,
+.Nm archive_entry_gname ,
+.Nm archive_entry_gname_w ,
+.Nm archive_entry_set_gname ,
+.Nm archive_entry_copy_gname ,
+.Nm archive_entry_copy_gname_w ,
+.Nm archive_entry_update_gname_utf8 ,
+.Nm archive_entry_fflags ,
+.Nm archive_entry_fflags_text ,
+.Nm archive_entry_set_fflags ,
+.Nm archive_entry_copy_fflags_text ,
+.Nm archive_entry_copy_fflags_text_w
+.Nd functions for manipulating ownership and permissions in archive entry descriptions
+.Sh SYNOPSIS
+.In archive_entry.h
+.Ft gid_t
+.Fn archive_entry_gid "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_gid "struct archive_entry *a" "gid_t gid"
+.Ft uid_t
+.Fn archive_entry_uid "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_uid "struct archive_entry *a" "uid_t uid"
+.Ft mode_t
+.Fn archive_entry_perm "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_perm "struct archive_entry *a" "mode_t mode"
+.Ft const char *
+.Fn archive_entry_strmode "struct archive_entry *a"
+.Ft const char *
+.Fn archive_entry_gname "struct archive_entry *a"
+.Ft const wchar_t *
+.Fn archive_entry_gname_w "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_gname "struct archive_entry *a" "const char *a"
+.Ft void
+.Fn archive_entry_copy_gname "struct archive_entry *a" "const char *name"
+.Ft void
+.Fn archive_entry_copy_gname_w "struct archive_entry *a" "const wchar_t *name"
+.Ft int
+.Fn archive_entry_update_gname_utf8 "struct archive_entry *a" "const char *name"
+.Ft const char *
+.Fn archive_entry_uname "struct archive_entry *a"
+.Ft const wchar_t *
+.Fn archive_entry_uname_w "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_uname "struct archive_entry *a" "const char *name"
+.Ft void
+.Fn archive_entry_copy_uname "struct archive_entry *a" "const char *name"
+.Ft void
+.Fn archive_entry_copy_uname_w "struct archive_entry *a" "const wchar_t *name"
+.Ft int
+.Fn archive_entry_update_uname_utf8 "struct archive_entry *a" "const char *name"
+.Ft void
+.Fo archive_entry_fflags
+.Fa "struct archive_entry *a"
+.Fa "unsigned long *set_bits"
+.Fa "unsigned long *clear_bits"
+.Fc
+.Ft const char *
+.Fn archive_entry_fflags_text "struct archive_entry *a"
+.Ft void
+.Fo archive_entry_set_fflags
+.Fa "struct archive_entry *a"
+.Fa "unsigned long set_bits"
+.Fa "unsigned long clear_bits"
+.Fc
+.Ft const char *
+.Fn archive_entry_copy_fflags_text "struct archive_entry *a" "const char *text"
+.Ft const wchar_t *
+.Fn archive_entry_copy_fflags_text_w "struct archive_entry *a" "const wchar_t *text"
+.Sh DESCRIPTION
+.Ss User id, group id and mode
+The functions
+.Fn archive_entry_uid ,
+.Fn archive_entry_gid ,
+and
+.Fn archive_entry_perm
+can be used to extract the user id, group id and permission from the given entry.
+The corresponding functions
+.Fn archive_entry_set_uid ,
+.Fn archive_entry_set_gid ,
+and
+.Fn archive_entry_set_perm
+store the given user id, group id and permission in the entry.
+The permission is also set as side effect of calling
+.Fn archive_entry_set_mode .
+.Pp
+.Fn archive_entry_strmode
+returns a string representation of the permission as used by the long mode of
+.Xr ls 1 .
+.Ss User and group name
+User and group names can be provided in one of three different ways:
+.Bl -tag -width "wchar_t *"
+.It char *
+Multibyte strings in the current locale.
+.It wchar_t *
+Wide character strings in the current locale.
+The accessor functions are named
+.Fn XXX_w .
+.It UTF-8
+Unicode strings encoded as UTF-8.
+This are convience functions to update both the multibyte and wide
+character strings at the same time.
+.El
+.Pp
+.Fn archive_entry_set_XXX
+is an alias for
+.Fn archive_entry_copy_XXX .
+.Ss File Flags
+File flags are transparently converted between a bitmap
+representation and a textual format.
+For example, if you set the bitmap and ask for text, the library
+will build a canonical text format.
+However, if you set a text format and request a text format,
+you will get back the same text, even if it is ill-formed.
+If you need to canonicalize a textual flags string, you should first set the
+text form, then request the bitmap form, then use that to set the bitmap form.
+Setting the bitmap format will clear the internal text representation
+and force it to be reconstructed when you next request the text form.
+.Pp
+The bitmap format consists of two integers, one containing bits
+that should be set, the other specifying bits that should be
+cleared.
+Bits not mentioned in either bitmap will be ignored.
+Usually, the bitmap of bits to be cleared will be set to zero.
+In unusual circumstances, you can force a fully-specified set
+of file flags by setting the bitmap of flags to clear to the complement
+of the bitmap of flags to set.
+(This differs from
+.Xr fflagstostr 3 ,
+which only includes names for set bits.)
+Converting a bitmap to a textual string is a platform-specific
+operation; bits that are not meaningful on the current platform
+will be ignored.
+.Pp
+The canonical text format is a comma-separated list of flag names.
+The
+.Fn archive_entry_copy_fflags_text
+and
+.Fn archive_entry_copy_fflags_text_w
+functions parse the provided text and sets the internal bitmap values.
+This is a platform-specific operation; names that are not meaningful
+on the current platform will be ignored.
+The function returns a pointer to the start of the first name that was not
+recognized, or NULL if every name was recognized.
+Note that every name \(em including names that follow an unrecognized
+name \(em will be evaluated, and the bitmaps will be set to reflect
+every name that is recognized.
+(In particular, this differs from
+.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
+.Sh BUGS
+The platform types
+.Vt uid_t
+and
+.Vt gid_t
+are often 16 or 32 bit wide.
+In this case it is possible that the ids can not be correctly restored
+from archives and get truncated.
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_private.h b/Utilities/cmlibarchive/libarchive/archive_entry_private.h
new file mode 100644
index 000000000..e3547c3e3
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_private.h
@@ -0,0 +1,176 @@
+/*-
+ * 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.
+ *
+ * $FreeBSD: head/lib/libarchive/archive_entry_private.h 201096 2009-12-28 02:41:27Z kientzle $
+ */
+
+#ifndef __LIBARCHIVE_BUILD
+#error This header is only to be used internally to libarchive.
+#endif
+
+#ifndef ARCHIVE_ENTRY_PRIVATE_H_INCLUDED
+#define ARCHIVE_ENTRY_PRIVATE_H_INCLUDED
+
+#include "archive_acl_private.h"
+#include "archive_string.h"
+
+struct ae_xattr {
+ struct ae_xattr *next;
+
+ char *name;
+ void *value;
+ size_t size;
+};
+
+struct ae_sparse {
+ struct ae_sparse *next;
+
+ int64_t offset;
+ int64_t length;
+};
+
+/*
+ * Description of an archive entry.
+ *
+ * Basically, this is a "struct stat" with a few text fields added in.
+ *
+ * TODO: Add "comment", "charset", and possibly other entries
+ * that are supported by "pax interchange" format. However, GNU, ustar,
+ * cpio, and other variants don't support these features, so they're not an
+ * excruciatingly high priority right now.
+ *
+ * TODO: "pax interchange" format allows essentially arbitrary
+ * key/value attributes to be attached to any entry. Supporting
+ * such extensions may make this library useful for special
+ * applications (e.g., a package manager could attach special
+ * package-management attributes to each entry). There are tricky
+ * API issues involved, so this is not going to happen until
+ * there's a real demand for it.
+ *
+ * TODO: Design a good API for handling sparse files.
+ */
+struct archive_entry {
+ struct archive *archive;
+
+ /*
+ * Note that ae_stat.st_mode & AE_IFMT can be 0!
+ *
+ * This occurs when the actual file type of the object is not
+ * in the archive. For example, 'tar' archives store
+ * hardlinks without marking the type of the underlying
+ * object.
+ */
+
+ /*
+ * We have a "struct aest" for holding file metadata rather than just
+ * a "struct stat" because on some platforms the "struct stat" has
+ * fields which are too narrow to hold the range of possible values;
+ * we don't want to lose information if we read an archive and write
+ * out another (e.g., in "tar -cf new.tar @old.tar").
+ *
+ * The "stat" pointer points to some form of platform-specific struct
+ * stat; it is declared as a void * rather than a struct stat * as
+ * some platforms have multiple varieties of stat structures.
+ */
+ void *stat;
+ int stat_valid; /* Set to 0 whenever a field in aest changes. */
+
+ struct aest {
+ int64_t aest_atime;
+ uint32_t aest_atime_nsec;
+ int64_t aest_ctime;
+ uint32_t aest_ctime_nsec;
+ int64_t aest_mtime;
+ uint32_t aest_mtime_nsec;
+ int64_t aest_birthtime;
+ uint32_t aest_birthtime_nsec;
+ int64_t aest_gid;
+ int64_t aest_ino;
+ uint32_t aest_nlink;
+ uint64_t aest_size;
+ int64_t aest_uid;
+ /*
+ * Because converting between device codes and
+ * major/minor values is platform-specific and
+ * inherently a bit risky, we only do that conversion
+ * lazily. That way, we will do a better job of
+ * preserving information in those cases where no
+ * conversion is actually required.
+ */
+ int aest_dev_is_broken_down;
+ dev_t aest_dev;
+ dev_t aest_devmajor;
+ dev_t aest_devminor;
+ int aest_rdev_is_broken_down;
+ dev_t aest_rdev;
+ dev_t aest_rdevmajor;
+ dev_t aest_rdevminor;
+ } ae_stat;
+
+ int ae_set; /* bitmap of fields that are currently set */
+#define AE_SET_HARDLINK 1
+#define AE_SET_SYMLINK 2
+#define AE_SET_ATIME 4
+#define AE_SET_CTIME 8
+#define AE_SET_MTIME 16
+#define AE_SET_BIRTHTIME 32
+#define AE_SET_SIZE 64
+#define AE_SET_INO 128
+#define AE_SET_DEV 256
+
+ /*
+ * Use aes here so that we get transparent mbs<->wcs conversions.
+ */
+ struct archive_mstring ae_fflags_text; /* Text fflags per fflagstostr(3) */
+ unsigned long ae_fflags_set; /* Bitmap fflags */
+ unsigned long ae_fflags_clear;
+ struct archive_mstring ae_gname; /* Name of owning group */
+ struct archive_mstring ae_hardlink; /* Name of target for hardlink */
+ struct archive_mstring ae_pathname; /* Name of entry */
+ struct archive_mstring ae_symlink; /* symlink contents */
+ struct archive_mstring ae_uname; /* Name of owner */
+
+ /* Not used within libarchive; useful for some clients. */
+ struct archive_mstring ae_sourcepath; /* Path this entry is sourced from. */
+
+ void *mac_metadata;
+ size_t mac_metadata_size;
+
+ /* ACL support. */
+ struct archive_acl acl;
+
+ /* extattr support. */
+ struct ae_xattr *xattr_head;
+ struct ae_xattr *xattr_p;
+
+ /* sparse support. */
+ struct ae_sparse *sparse_head;
+ struct ae_sparse *sparse_tail;
+ struct ae_sparse *sparse_p;
+
+ /* Miscellaneous. */
+ char strmode[12];
+};
+
+#endif /* ARCHIVE_ENTRY_PRIVATE_H_INCLUDED */
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_sparse.c b/Utilities/cmlibarchive/libarchive/archive_entry_sparse.c
new file mode 100644
index 000000000..10c54474a
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_sparse.c
@@ -0,0 +1,156 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2010-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"
+__FBSDID("$FreeBSD$");
+
+#include "archive.h"
+#include "archive_entry.h"
+#include "archive_private.h"
+#include "archive_entry_private.h"
+
+/*
+ * sparse handling
+ */
+
+void
+archive_entry_sparse_clear(struct archive_entry *entry)
+{
+ struct ae_sparse *sp;
+
+ while (entry->sparse_head != NULL) {
+ sp = entry->sparse_head->next;
+ free(entry->sparse_head);
+ entry->sparse_head = sp;
+ }
+ entry->sparse_tail = NULL;
+}
+
+void
+archive_entry_sparse_add_entry(struct archive_entry *entry,
+ int64_t offset, int64_t length)
+{
+ struct ae_sparse *sp;
+
+ if (offset < 0 || length < 0)
+ /* Invalid value */
+ return;
+ if (offset + length < 0 ||
+ offset + length > archive_entry_size(entry))
+ /* A value of "length" parameter is too large. */
+ return;
+ if ((sp = entry->sparse_tail) != NULL) {
+ if (sp->offset + sp->length > offset)
+ /* Invalid value. */
+ return;
+ if (sp->offset + sp->length == offset) {
+ if (sp->offset + sp->length + length < 0)
+ /* A value of "length" parameter is
+ * too large. */
+ return;
+ /* Expand existing sparse block size. */
+ sp->length += length;
+ return;
+ }
+ }
+
+ if ((sp = (struct ae_sparse *)malloc(sizeof(*sp))) == NULL)
+ /* XXX Error XXX */
+ return;
+
+ sp->offset = offset;
+ sp->length = length;
+ sp->next = NULL;
+
+ if (entry->sparse_head == NULL)
+ entry->sparse_head = entry->sparse_tail = sp;
+ else {
+ /* Add a new sparse block to the tail of list. */
+ if (entry->sparse_tail != NULL)
+ entry->sparse_tail->next = sp;
+ entry->sparse_tail = sp;
+ }
+}
+
+
+/*
+ * returns number of the sparse entries
+ */
+int
+archive_entry_sparse_count(struct archive_entry *entry)
+{
+ struct ae_sparse *sp;
+ int count = 0;
+
+ for (sp = entry->sparse_head; sp != NULL; sp = sp->next)
+ count++;
+
+ /*
+ * Sanity check if this entry is exactly sparse.
+ * If amount of sparse blocks is just one and it indicates the whole
+ * file data, we should remove it and return zero.
+ */
+ if (count == 1) {
+ sp = entry->sparse_head;
+ if (sp->offset == 0 &&
+ sp->length >= archive_entry_size(entry)) {
+ count = 0;
+ archive_entry_sparse_clear(entry);
+ }
+ }
+
+ return (count);
+}
+
+int
+archive_entry_sparse_reset(struct archive_entry * entry)
+{
+ entry->sparse_p = entry->sparse_head;
+
+ return archive_entry_sparse_count(entry);
+}
+
+int
+archive_entry_sparse_next(struct archive_entry * entry,
+ int64_t *offset, int64_t *length)
+{
+ if (entry->sparse_p) {
+ *offset = entry->sparse_p->offset;
+ *length = entry->sparse_p->length;
+
+ entry->sparse_p = entry->sparse_p->next;
+
+ return (ARCHIVE_OK);
+ } else {
+ *offset = 0;
+ *length = 0;
+ return (ARCHIVE_WARN);
+ }
+}
+
+/*
+ * end of sparse handling
+ */
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_stat.3 b/Utilities/cmlibarchive/libarchive/archive_entry_stat.3
new file mode 100644
index 000000000..36a7efb23
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_stat.3
@@ -0,0 +1,272 @@
+.\" Copyright (c) 2010 Joerg Sonnenberger
+.\" 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.
+.\"
+.Dd May 12, 2008
+.Dt ARCHIVE_ENTRY 3
+.Os
+.Sh NAME
+.Nm archive_entry_stat ,
+.Nm archive_entry_copy_stat ,
+.Nm archive_entry_filetype ,
+.Nm archive_entry_set_filetype ,
+.Nm archive_entry_mode ,
+.Nm archive_entry_set_mode ,
+.Nm archive_entry_size ,
+.Nm archive_entry_size_is_set ,
+.Nm archive_entry_set_size ,
+.Nm archive_entry_unset_size ,
+.Nm archive_entry_dev ,
+.Nm archive_entry_set_dev ,
+.Nm archive_entry_dev_is_set ,
+.Nm archive_entry_devmajor ,
+.Nm archive_entry_set_devmajor ,
+.Nm archive_entry_devminor ,
+.Nm archive_entry_set_devminor ,
+.Nm archive_entry_ino ,
+.Nm archive_entry_set_ino ,
+.Nm archive_entry_ino_is_set ,
+.Nm archive_entry_ino64 ,
+.Nm archive_entry_set_ino64 ,
+.Nm archive_entry_nlink ,
+.Nm archive_entry_rdev ,
+.Nm archive_entry_set_rdev ,
+.Nm archive_entry_rdevmajor ,
+.Nm archive_entry_set_rdevmajor ,
+.Nm archive_entry_rdevminor ,
+.Nm archive_entry_set_rdevminor ,
+.Nd accessor functions for manipulating archive entry descriptions
+.Sh SYNOPSIS
+.In archive_entry.h
+.Ft const struct stat *
+.Fn archive_entry_stat "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_copy_stat "struct archive_entry *a" "const struct stat *sb"
+.Ft mode_t
+.Fn archive_entry_filetype "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_filetype "struct archive_entry *a" "unsigned int type"
+.Ft mode_t
+.Fn archive_entry_mode "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_mode "struct archive_entry *a" "mode_t mode"
+.Ft int64_t
+.Fn archive_entry_size "struct archive_entry *a"
+.Ft int
+.Fn archive_entry_size_is_set "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_size "struct archive_entry *a" "int64_t size"
+.Ft void
+.Fn archive_entry_unset_size "struct archive_entry *a"
+.Ft dev_t
+.Fn archive_entry_dev "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_dev "struct archive_entry *a" "dev_t dev"
+.Ft int
+.Fn archive_entry_dev_is_set "struct archive_entry *a"
+.Ft dev_t
+.Fn archive_entry_devmajor "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_devmajor "struct archive_entry *a" "dev_t major"
+.Ft dev_t
+.Fn archive_entry_devminor "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_devminor "struct archive_entry *a" "dev_t minor"
+.Ft ino_t
+.Fn archive_entry_ino "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_ino "struct archive_entry *a" "unsigned long ino"
+.Ft int
+.Fn archive_entry_ino_is_set "struct archive_entry *a"
+.Ft int64_t
+.Fn archive_entry_ino64 "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_ino64 "struct archive_entry *a" "int64_t ino"
+.Ft unsigned int
+.Fn archive_entry_nlink "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_nlink "struct archive_entry *a" "unsigned int count"
+.Ft dev_t
+.Fn archive_entry_rdev "struct archive_entry *a"
+.Ft dev_t
+.Fn archive_entry_rdevmajor "struct archive_entry *a"
+.Ft dev_t
+.Fn archive_entry_rdevminor "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_rdev "struct archive_entry *a" "dev_t dev"
+.Ft void
+.Fn archive_entry_set_rdevmajor "struct archive_entry *a" "dev_t major"
+.Ft void
+.Fn archive_entry_set_rdevminor "struct archive_entry *a" "dev_t minor"
+.Sh DESCRIPTION
+.Ss Copying to and from Vt struct stat
+The function
+.Fn archive_entry_stat
+converts the various fields stored in the archive entry to the format
+used by
+.Xr stat 2 .
+The return value remains valid until either
+.Fn archive_entry_clear
+or
+.Fn archive_entry_free
+is called.
+It is not affected by calls to the set accessor functions.
+It currently sets the following values in
+.Vt struct stat :
+.Vt st_atime ,
+.Vt st_ctime ,
+.Vt st_dev ,
+.Vt st_gid ,
+.Vt st_ino ,
+.Vt st_mode ,
+.Vt st_mtime ,
+.Vt st_nlink ,
+.Vt st_rdev ,
+.Vt st_size ,
+.Vt st_uid .
+In addition,
+.Vt st_birthtime
+and high-precision information for time-related fields
+will be included on platforms that support it.
+.Pp
+The function
+.Fn archive_entry_copy_stat
+copies fields from the platform's
+.Vt struct stat .
+Fields not provided by
+.Vt struct stat
+are unchanged.
+.Ss General accessor functions
+The functions
+.Fn archive_entry_filetype
+and
+.Fn archive_entry_set_filetype
+get respectively set the filetype.
+The file type is one of the following constants:
+.Bl -tag -width "AE_IFSOCK" -compact -offset indent
+.It AE_IFREG
+Regular file
+.It AE_IFLNK
+Symbolic link
+.It AE_IFSOCK
+Socket
+.It AE_IFCHR
+Character device
+.It AE_IFBLK
+Block device
+.It AE_IFDIR
+Directory
+.It AE_IFIFO
+Named pipe (fifo)
+.El
+Not all file types are supported by all platforms.
+The constants used by
+.Xr stat 2
+may have different numeric values from the
+corresponding constants above.
+.Pp
+The functions
+.Fn archive_entry_mode
+and
+.Fn archive_entry_set_mode
+get/set a combination of file type and permissions and provide the
+equivalent of
+.Va st_mode .
+Use of
+.Fn archive_entry_filetype
+and
+.Fn archive_entry_perm
+for getting and
+.Fn archive_entry_set_filetype
+and
+.Fn archive_entry_set_perm
+for setting is recommended.
+.Pp
+The function
+.Fn archive_entry_size
+returns the file size, if it has been set, and 0 otherwise.
+.Fn archive_entry_size
+can be used to query that status.
+.Fn archive_entry_set_size
+and
+.Fn archive_entry_unset_size
+set and unset the size, respectively.
+.Pp
+The number of references (hardlinks) can be obtained by calling
+.Fn archive_entry_nlinks
+and set with
+.Fn archive_entry_set_nlinks .
+.Ss Identifying unique files
+The functions
+.Fn archive_entry_dev
+and
+.Fn archive_entry_ino64
+are used by
+.Xr archive_entry_linkify 3
+to find hardlinks.
+The pair of device and inode is suppossed to identify hardlinked files.
+.Pp
+The device major and minor number can be obtained independently using
+.Fn archive_entry_devmajor
+and
+.Fn archive_entry_devminor .
+The device can be set either via
+.Fn archive_entry_set_dev
+or by the combination of major and minor number using
+.Fn archive_entry_set_devmajor
+and
+.Fn archive_entry_set_devminor .
+.Pp
+The inode number can be obtained using
+.Fn archive_entry_ino .
+This is a legacy interface that uses the platform
+.Vt ino_t ,
+which may be very small.
+To set the inode number,
+.Fn archive_entry_set_ino64
+is the preferred interface.
+.Ss Accessor functions for block and character devices
+Block and character devices are characterised either using a device number
+or a pair of major and minor number.
+The combined device number can be obtained with
+.Fn archive_device_rdev
+and set with
+.Fn archive_device_set_rdev .
+The major and minor numbers are accessed by
+.Fn archive_device_rdevmajor ,
+.Fn archive_device_rdevminor
+.Fn archive_device_set_rdevmajor
+and
+.Fn archive_device_set_rdevminor .
+.Pp
+The process of splitting the combined device number into major and
+minor number and the reverse process of combing them differs between
+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 stat 2
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_stat.c b/Utilities/cmlibarchive/libarchive/archive_entry_stat.c
new file mode 100644
index 000000000..d5ed1cb13
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_stat.c
@@ -0,0 +1,118 @@
+/*-
+ * 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: head/lib/libarchive/archive_entry_stat.c 201100 2009-12-28 03:05:31Z kientzle $");
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#include "archive_entry.h"
+#include "archive_entry_private.h"
+
+const struct stat *
+archive_entry_stat(struct archive_entry *entry)
+{
+ struct stat *st;
+ if (entry->stat == NULL) {
+ entry->stat = calloc(1, sizeof(*st));
+ if (entry->stat == NULL)
+ return (NULL);
+ entry->stat_valid = 0;
+ }
+
+ /*
+ * If none of the underlying fields have been changed, we
+ * don't need to regenerate. In theory, we could use a bitmap
+ * here to flag only those items that have changed, but the
+ * extra complexity probably isn't worth it. It will be very
+ * rare for anyone to change just one field then request a new
+ * stat structure.
+ */
+ if (entry->stat_valid)
+ return (entry->stat);
+
+ st = entry->stat;
+ /*
+ * Use the public interfaces to extract items, so that
+ * the appropriate conversions get invoked.
+ */
+ st->st_atime = archive_entry_atime(entry);
+#if HAVE_STRUCT_STAT_ST_BIRTHTIME
+ st->st_birthtime = archive_entry_birthtime(entry);
+#endif
+ st->st_ctime = archive_entry_ctime(entry);
+ st->st_mtime = archive_entry_mtime(entry);
+ st->st_dev = archive_entry_dev(entry);
+ st->st_gid = archive_entry_gid(entry);
+ st->st_uid = archive_entry_uid(entry);
+ st->st_ino = archive_entry_ino64(entry);
+ st->st_nlink = archive_entry_nlink(entry);
+ st->st_rdev = archive_entry_rdev(entry);
+ st->st_size = archive_entry_size(entry);
+ st->st_mode = archive_entry_mode(entry);
+
+ /*
+ * On systems that support high-res timestamps, copy that
+ * information into struct stat.
+ */
+#if HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC
+ st->st_atimespec.tv_nsec = archive_entry_atime_nsec(entry);
+ st->st_ctimespec.tv_nsec = archive_entry_ctime_nsec(entry);
+ st->st_mtimespec.tv_nsec = archive_entry_mtime_nsec(entry);
+#elif HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
+ st->st_atim.tv_nsec = archive_entry_atime_nsec(entry);
+ st->st_ctim.tv_nsec = archive_entry_ctime_nsec(entry);
+ st->st_mtim.tv_nsec = archive_entry_mtime_nsec(entry);
+#elif HAVE_STRUCT_STAT_ST_MTIME_N
+ st->st_atime_n = archive_entry_atime_nsec(entry);
+ st->st_ctime_n = archive_entry_ctime_nsec(entry);
+ st->st_mtime_n = archive_entry_mtime_nsec(entry);
+#elif HAVE_STRUCT_STAT_ST_UMTIME
+ st->st_uatime = archive_entry_atime_nsec(entry) / 1000;
+ st->st_uctime = archive_entry_ctime_nsec(entry) / 1000;
+ st->st_umtime = archive_entry_mtime_nsec(entry) / 1000;
+#elif HAVE_STRUCT_STAT_ST_MTIME_USEC
+ st->st_atime_usec = archive_entry_atime_nsec(entry) / 1000;
+ st->st_ctime_usec = archive_entry_ctime_nsec(entry) / 1000;
+ st->st_mtime_usec = archive_entry_mtime_nsec(entry) / 1000;
+#endif
+#if HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC
+ st->st_birthtimespec.tv_nsec = archive_entry_birthtime_nsec(entry);
+#endif
+
+ /*
+ * TODO: On Linux, store 32 or 64 here depending on whether
+ * the cached stat structure is a stat32 or a stat64. This
+ * will allow us to support both variants interchangably.
+ */
+ entry->stat_valid = 1;
+
+ return (st);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_strmode.c b/Utilities/cmlibarchive/libarchive/archive_entry_strmode.c
new file mode 100644
index 000000000..16cb3f7bb
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_strmode.c
@@ -0,0 +1,87 @@
+/*-
+ * 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_entry_strmode.c,v 1.4 2008/06/15 05:14:01 kientzle Exp $");
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include "archive_entry.h"
+#include "archive_entry_private.h"
+
+const char *
+archive_entry_strmode(struct archive_entry *entry)
+{
+ static const mode_t permbits[] =
+ { 0400, 0200, 0100, 0040, 0020, 0010, 0004, 0002, 0001 };
+ char *bp = entry->strmode;
+ mode_t mode;
+ int i;
+
+ /* Fill in a default string, then selectively override. */
+ strcpy(bp, "?rwxrwxrwx ");
+
+ mode = archive_entry_mode(entry);
+ switch (archive_entry_filetype(entry)) {
+ case AE_IFREG: bp[0] = '-'; break;
+ case AE_IFBLK: bp[0] = 'b'; break;
+ case AE_IFCHR: bp[0] = 'c'; break;
+ case AE_IFDIR: bp[0] = 'd'; break;
+ case AE_IFLNK: bp[0] = 'l'; break;
+ case AE_IFSOCK: bp[0] = 's'; break;
+ case AE_IFIFO: bp[0] = 'p'; break;
+ default:
+ if (archive_entry_hardlink(entry) != NULL) {
+ bp[0] = 'h';
+ break;
+ }
+ }
+
+ for (i = 0; i < 9; i++)
+ if (!(mode & permbits[i]))
+ bp[i+1] = '-';
+
+ if (mode & S_ISUID) {
+ if (mode & 0100) bp[3] = 's';
+ else bp[3] = 'S';
+ }
+ if (mode & S_ISGID) {
+ if (mode & 0010) bp[6] = 's';
+ else bp[6] = 'S';
+ }
+ if (mode & S_ISVTX) {
+ if (mode & 0001) bp[9] = 't';
+ else bp[9] = 'T';
+ }
+ if (archive_entry_acl_count(entry, ARCHIVE_ENTRY_ACL_TYPE_ACCESS))
+ bp[10] = '+';
+
+ return (bp);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_time.3 b/Utilities/cmlibarchive/libarchive/archive_entry_time.3
new file mode 100644
index 000000000..85a8209e8
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_time.3
@@ -0,0 +1,127 @@
+.\" Copyright (c) 2003-2007 Tim Kientzle
+.\" Copyright (c) 2010 Joerg Sonnenberger
+.\" 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: src/lib/libarchive/archive_entry.3,v 1.18 2008/05/26 17:00:22 kientzle Exp $
+.\"
+.Dd February 21, 2010
+.Dt ARCHIVE_ENTRY_TIME 3
+.Os
+.Sh NAME
+.Nm archive_entry_atime ,
+.Nm archive_entry_atime_nsec ,
+.Nm archive_entry_atime_is_set ,
+.Nm archive_entry_set_atime ,
+.Nm archive_entry_unset_atime ,
+.Nm archive_entry_birthtime ,
+.Nm archive_entry_birthtime_nsec ,
+.Nm archive_entry_birthtime_is_set ,
+.Nm archive_entry_set_birthtime ,
+.Nm archive_entry_unset_birthtime ,
+.Nm archive_entry_ctime ,
+.Nm archive_entry_ctime_nsec ,
+.Nm archive_entry_ctime_is_set ,
+.Nm archive_entry_set_ctime ,
+.Nm archive_entry_unset_ctime ,
+.Nm archive_entry_mtime ,
+.Nm archive_entry_mtime_nsec ,
+.Nm archive_entry_mtime_is_set ,
+.Nm archive_entry_set_mtime ,
+.Nm archive_entry_unset_mtime ,
+.Nd functions for manipulating times in archive entry descriptions
+.Sh SYNOPSIS
+.In archive_entry.h
+.Ft time_t
+.Fn archive_entry_atime "struct archive_entry *a"
+.Ft long
+.Fn archive_entry_atime_nsec "struct archive_entry *a"
+.Ft int
+.Fn archive_entry_atime_is_set "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_atime "struct archive_entry *a" "time_t sec" "long nanosec"
+.Ft void
+.Fn archive_entry_unset_atime "struct archive_entry *a"
+.Ft time_t
+.Fn archive_entry_birthtime "struct archive_entry *a"
+.Ft long
+.Fn archive_entry_birthtime_nsec "struct archive_entry *a"
+.Ft int
+.Fn archive_entry_birthtime_is_set "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_birthtime "struct archive_entry *a" "time_t sec" "long nanosec"
+.Ft void
+.Fn archive_entry_unset_birthtime "struct archive_entry *a"
+.Ft time_t
+.Fn archive_entry_ctime "struct archive_entry *a"
+.Ft long
+.Fn archive_entry_ctime_nsec "struct archive_entry *a"
+.Ft int
+.Fn archive_entry_ctime_is_set "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_ctime "struct archive_entry *a" "time_t sec" "long nanosec"
+.Ft void
+.Fn archive_entry_unset_ctime "struct archive_entry *a"
+.Ft time_t
+.Fn archive_entry_mtime "struct archive_entry *a"
+.Ft long
+.Fn archive_entry_mtime_nsec "struct archive_entry *a"
+.Ft int
+.Fn archive_entry_mtime_is_set "struct archive_entry *a"
+.Ft void
+.Fn archive_entry_set_mtime "struct archive_entry *a" "time_t sec" "long nanosec"
+.Ft void
+.Fn archive_entry_unset_mtime "struct archive_entry *a"
+.Sh DESCRIPTION
+These functions create and manipulate the time fields in an
+.Vt archive_entry .
+Supported time fields are atime (access time), birthtime (creation time),
+ctime (last time an inode property was changed) and mtime (modification time).
+.Pp
+.Xr libarchive 3
+provides a high-resolution interface.
+The timestamps are truncated automatically depending on the archive format
+(for archiving) or the filesystem capabilities (for restoring).
+.Pp
+All timestamp fields are optional.
+The
+.Fn XXX_unset
+functions can be used to mark the corresponding field as missing.
+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
+.Sh HISTORY
+The
+.Nm libarchive
+library first appeared in
+.Fx 5.3 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm libarchive
+library was written by
+.An Tim Kientzle Aq kientzle@acm.org .
+.\" .Sh BUGS
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_xattr.c b/Utilities/cmlibarchive/libarchive/archive_entry_xattr.c
new file mode 100644
index 000000000..a3efe7ca8
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_xattr.c
@@ -0,0 +1,158 @@
+/*-
+ * 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: head/lib/libarchive/archive_entry_xattr.c 201096 2009-12-28 02:41:27Z kientzle $");
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifdef HAVE_LINUX_FS_H
+#include <linux/fs.h> /* for Linux file flags */
+#endif
+/*
+ * Some Linux distributions have both linux/ext2_fs.h and ext2fs/ext2_fs.h.
+ * As the include guards don't agree, the order of include is important.
+ */
+#ifdef HAVE_LINUX_EXT2_FS_H
+#include <linux/ext2_fs.h> /* for Linux file flags */
+#endif
+#if defined(HAVE_EXT2FS_EXT2_FS_H) && !defined(__CYGWIN__)
+#include <ext2fs/ext2_fs.h> /* for Linux file flags */
+#endif
+#include <stddef.h>
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_WCHAR_H
+#include <wchar.h>
+#endif
+
+#include "archive.h"
+#include "archive_entry.h"
+#include "archive_private.h"
+#include "archive_entry_private.h"
+
+/*
+ * extended attribute handling
+ */
+
+void
+archive_entry_xattr_clear(struct archive_entry *entry)
+{
+ struct ae_xattr *xp;
+
+ while (entry->xattr_head != NULL) {
+ xp = entry->xattr_head->next;
+ free(entry->xattr_head->name);
+ free(entry->xattr_head->value);
+ free(entry->xattr_head);
+ entry->xattr_head = xp;
+ }
+
+ entry->xattr_head = NULL;
+}
+
+void
+archive_entry_xattr_add_entry(struct archive_entry *entry,
+ const char *name, const void *value, size_t size)
+{
+ struct ae_xattr *xp;
+
+ for (xp = entry->xattr_head; xp != NULL; xp = xp->next)
+ ;
+
+ if ((xp = (struct ae_xattr *)malloc(sizeof(struct ae_xattr))) == NULL)
+ /* XXX Error XXX */
+ return;
+
+ xp->name = strdup(name);
+ if ((xp->value = malloc(size)) != NULL) {
+ memcpy(xp->value, value, size);
+ xp->size = size;
+ } else
+ xp->size = 0;
+
+ xp->next = entry->xattr_head;
+ entry->xattr_head = xp;
+}
+
+
+/*
+ * returns number of the extended attribute entries
+ */
+int
+archive_entry_xattr_count(struct archive_entry *entry)
+{
+ struct ae_xattr *xp;
+ int count = 0;
+
+ for (xp = entry->xattr_head; xp != NULL; xp = xp->next)
+ count++;
+
+ return count;
+}
+
+int
+archive_entry_xattr_reset(struct archive_entry * entry)
+{
+ entry->xattr_p = entry->xattr_head;
+
+ return archive_entry_xattr_count(entry);
+}
+
+int
+archive_entry_xattr_next(struct archive_entry * entry,
+ const char **name, const void **value, size_t *size)
+{
+ if (entry->xattr_p) {
+ *name = entry->xattr_p->name;
+ *value = entry->xattr_p->value;
+ *size = entry->xattr_p->size;
+
+ entry->xattr_p = entry->xattr_p->next;
+
+ return (ARCHIVE_OK);
+ } else {
+ *name = NULL;
+ *value = NULL;
+ *size = (size_t)0;
+ return (ARCHIVE_WARN);
+ }
+}
+
+/*
+ * end of xattr handling
+ */
diff --git a/Utilities/cmlibarchive/libarchive/archive_options.c b/Utilities/cmlibarchive/libarchive/archive_options.c
new file mode 100644
index 000000000..79b4ffbda
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_options.c
@@ -0,0 +1,164 @@
+/*-
+ * Copyright (c) 2011 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$");
+
+#include "archive_options_private.h"
+
+static const char *
+parse_option(const char **str,
+ const char **mod, const char **opt, const char **val);
+
+int
+_archive_set_option(struct archive *a,
+ const char *m, const char *o, const char *v,
+ int magic, const char *fn, option_handler use_option)
+{
+ const char *mp, *op, *vp;
+
+ archive_check_magic(a, magic, ARCHIVE_STATE_NEW, fn);
+
+ mp = m != NULL && m[0] != '\0' ? m : NULL;
+ op = o != NULL && o[0] != '\0' ? o : NULL;
+ vp = v != NULL && v[0] != '\0' ? v : NULL;
+
+ if (op == NULL && vp == NULL)
+ return (ARCHIVE_OK);
+ if (op == NULL)
+ return (ARCHIVE_FAILED);
+
+ return use_option(a, mp, op, vp);
+}
+
+int
+_archive_set_either_option(struct archive *a, const char *m, const char *o, const char *v,
+ option_handler use_format_option, option_handler use_filter_option)
+{
+ int r1, r2;
+
+ if (o == NULL && v == NULL)
+ return (ARCHIVE_OK);
+ if (o == NULL)
+ return (ARCHIVE_FAILED);
+
+ r1 = use_format_option(a, m, o, v);
+ if (r1 == ARCHIVE_FATAL)
+ return (ARCHIVE_FATAL);
+
+ r2 = use_filter_option(a, m, o, v);
+ if (r2 == ARCHIVE_FATAL)
+ return (ARCHIVE_FATAL);
+
+ return r1 > r2 ? r1 : r2;
+}
+
+int
+_archive_set_options(struct archive *a, const char *options,
+ int magic, const char *fn, option_handler use_option)
+{
+ int allok = 1, anyok = 0, r;
+ char *data;
+ const char *s, *mod, *opt, *val;
+
+ archive_check_magic(a, magic, ARCHIVE_STATE_NEW, fn);
+
+ if (options == NULL || options[0] == '\0')
+ return ARCHIVE_OK;
+
+ data = (char *)malloc(strlen(options) + 1);
+ strcpy(data, options);
+ s = (const char *)data;
+
+ do {
+ mod = opt = val = NULL;
+
+ parse_option(&s, &mod, &opt, &val);
+
+ r = use_option(a, mod, opt, val);
+ if (r == ARCHIVE_FATAL) {
+ free(data);
+ return (ARCHIVE_FATAL);
+ }
+ if (r == ARCHIVE_OK)
+ anyok = 1;
+ else
+ allok = 0;
+ } while (s != NULL);
+
+ free(data);
+ return allok ? ARCHIVE_OK : anyok ? ARCHIVE_WARN : ARCHIVE_FAILED;
+}
+
+static const char *
+parse_option(const char **s, const char **m, const char **o, const char **v)
+{
+ const char *end, *mod, *opt, *val;
+ char *p;
+
+ end = NULL;
+ mod = NULL;
+ opt = *s;
+ val = "1";
+
+ p = strchr(opt, ',');
+
+ if (p != NULL) {
+ *p = '\0';
+ end = ((const char *)p) + 1;
+ }
+
+ if (0 == strlen(opt)) {
+ *s = end;
+ *m = NULL;
+ *o = NULL;
+ *v = NULL;
+ return end;
+ }
+
+ p = strchr(opt, ':');
+ if (p != NULL) {
+ *p = '\0';
+ mod = opt;
+ opt = ++p;
+ }
+
+ p = strchr(opt, '=');
+ if (p != NULL) {
+ *p = '\0';
+ val = ++p;
+ } else if (opt[0] == '!') {
+ ++opt;
+ val = NULL;
+ }
+
+ *s = end;
+ *m = mod;
+ *o = opt;
+ *v = val;
+
+ return end;
+}
+
diff --git a/Utilities/cmlibarchive/libarchive/archive_options_private.h b/Utilities/cmlibarchive/libarchive/archive_options_private.h
new file mode 100644
index 000000000..6ef0165af
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_options_private.h
@@ -0,0 +1,47 @@
+/*-
+ * Copyright (c) 2011 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$");
+
+#include "archive_private.h"
+
+typedef int (*option_handler)(struct archive *a,
+ const char *mod, const char *opt, const char *val);
+
+int
+_archive_set_option(struct archive *a,
+ const char *mod, const char *opt, const char *val,
+ int magic, const char *fn, option_handler use_option);
+
+int
+_archive_set_options(struct archive *a, const char *options,
+ int magic, const char *fn, option_handler use_option);
+
+int
+_archive_set_either_option(struct archive *a,
+ const char *m, const char *o, const char *v,
+ option_handler use_format_option, option_handler use_filter_option);
+
diff --git a/Utilities/cmlibarchive/libarchive/archive_platform.h b/Utilities/cmlibarchive/libarchive/archive_platform.h
new file mode 100644
index 000000000..cdd9c7c86
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_platform.h
@@ -0,0 +1,170 @@
+/*-
+ * 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.
+ *
+ * $FreeBSD: head/lib/libarchive/archive_platform.h 201090 2009-12-28 02:22:04Z kientzle $
+ */
+
+/* !!ONLY FOR USE INTERNALLY TO LIBARCHIVE!! */
+
+/*
+ * This header is the first thing included in any of the libarchive
+ * source files. As far as possible, platform-specific issues should
+ * be dealt with here and not within individual source files. I'm
+ * actively trying to minimize #if blocks within the main source,
+ * since they obfuscate the code.
+ */
+
+#ifndef ARCHIVE_PLATFORM_H_INCLUDED
+#define ARCHIVE_PLATFORM_H_INCLUDED
+
+/* archive.h and archive_entry.h require this. */
+#define __LIBARCHIVE_BUILD 1
+
+#if defined(PLATFORM_CONFIG_H)
+/* Use hand-built config.h in environments that need it. */
+#include PLATFORM_CONFIG_H
+#elif defined(HAVE_CONFIG_H)
+/* Most POSIX platforms use the 'configure' script to build config.h */
+#include "config.h"
+#else
+/* Warn if the library hasn't been (automatically or manually) configured. */
+#error Oops: No config.h and no pre-built configuration in archive_platform.h.
+#endif
+
+/* It should be possible to get rid of this by extending the feature-test
+ * macros to cover Windows API functions, probably along with non-trivial
+ * refactoring of code to find structures that sit more cleanly on top of
+ * either Windows or Posix APIs. */
+#if (defined(__WIN32__) || defined(_WIN32) || defined(__WIN32)) && !defined(__CYGWIN__)
+#include "archive_windows.h"
+#endif
+
+/*
+ * The config files define a lot of feature macros. The following
+ * uses those macros to select/define replacements and include key
+ * headers as required.
+ */
+
+/* Get a real definition for __FBSDID if we can */
+#if HAVE_SYS_CDEFS_H
+#include <sys/cdefs.h>
+#endif
+
+/* If not, define it so as to avoid dangling semicolons. */
+#ifndef __FBSDID
+#define __FBSDID(a) struct _undefined_hack
+#endif
+
+/* Old glibc mbsnrtowcs fails assertions in our use case. */
+#if defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ <= 1
+# undef HAVE_MBSNRTOWCS
+#endif
+
+/* Try to get standard C99-style integer type definitions. */
+#if HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+/* Borland warns about its own constants! */
+#if defined(__BORLANDC__)
+# if HAVE_DECL_UINT64_MAX
+# undef UINT64_MAX
+# undef HAVE_DECL_UINT64_MAX
+# endif
+# if HAVE_DECL_UINT64_MIN
+# undef UINT64_MIN
+# undef HAVE_DECL_UINT64_MIN
+# endif
+# if HAVE_DECL_INT64_MAX
+# undef INT64_MAX
+# undef HAVE_DECL_INT64_MAX
+# endif
+# if HAVE_DECL_INT64_MIN
+# undef INT64_MIN
+# undef HAVE_DECL_INT64_MIN
+# endif
+#endif
+
+/* Some platforms lack the standard *_MAX definitions. */
+#if !HAVE_DECL_SIZE_MAX
+#define SIZE_MAX (~(size_t)0)
+#endif
+#if !HAVE_DECL_SSIZE_MAX
+#define SSIZE_MAX ((ssize_t)(SIZE_MAX >> 1))
+#endif
+#if !HAVE_DECL_UINT32_MAX
+#define UINT32_MAX (~(uint32_t)0)
+#endif
+#if !HAVE_DECL_UINT64_MAX
+#define UINT64_MAX (~(uint64_t)0)
+#endif
+#if !HAVE_DECL_INT64_MAX
+#define INT64_MAX ((int64_t)(UINT64_MAX >> 1))
+#endif
+#if !HAVE_DECL_INT64_MIN
+#define INT64_MIN ((int64_t)(~INT64_MAX))
+#endif
+
+/*
+ * If this platform has <sys/acl.h>, acl_create(), acl_init(),
+ * acl_set_file(), and ACL_USER, we assume it has the rest of the
+ * POSIX.1e draft functions used in archive_read_extract.c.
+ */
+#if HAVE_SYS_ACL_H && HAVE_ACL_CREATE_ENTRY && HAVE_ACL_INIT && HAVE_ACL_SET_FILE && HAVE_ACL_USER
+#define HAVE_POSIX_ACL 1
+#endif
+
+/*
+ * If we can't restore metadata using a file descriptor, then
+ * for compatibility's sake, close files before trying to restore metadata.
+ */
+#if defined(HAVE_FCHMOD) || defined(HAVE_FUTIMES) || defined(HAVE_ACL_SET_FD) || defined(HAVE_ACL_SET_FD_NP) || defined(HAVE_FCHOWN)
+#define CAN_RESTORE_METADATA_FD
+#endif
+
+/* Set up defaults for internal error codes. */
+#ifndef ARCHIVE_ERRNO_FILE_FORMAT
+#if HAVE_EFTYPE
+#define ARCHIVE_ERRNO_FILE_FORMAT EFTYPE
+#else
+#if HAVE_EILSEQ
+#define ARCHIVE_ERRNO_FILE_FORMAT EILSEQ
+#else
+#define ARCHIVE_ERRNO_FILE_FORMAT EINVAL
+#endif
+#endif
+#endif
+
+#ifndef ARCHIVE_ERRNO_PROGRAMMER
+#define ARCHIVE_ERRNO_PROGRAMMER EINVAL
+#endif
+
+#ifndef ARCHIVE_ERRNO_MISC
+#define ARCHIVE_ERRNO_MISC (-1)
+#endif
+
+#endif /* !ARCHIVE_PLATFORM_H_INCLUDED */
diff --git a/Utilities/cmlibarchive/libarchive/archive_ppmd7.c b/Utilities/cmlibarchive/libarchive/archive_ppmd7.c
new file mode 100644
index 000000000..b2e8c3a34
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_ppmd7.c
@@ -0,0 +1,1164 @@
+/* Ppmd7.c -- PPMdH codec
+2010-03-12 : Igor Pavlov : Public domain
+This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
+
+#include "archive_platform.h"
+
+#include <memory.h>
+
+#include "archive_ppmd7_private.h"
+
+#ifdef PPMD_32BIT
+ #define Ppmd7_GetPtr(p, ptr) (ptr)
+ #define Ppmd7_GetContext(p, ptr) (ptr)
+ #define Ppmd7_GetStats(p, ctx) ((ctx)->Stats)
+#else
+ #define Ppmd7_GetPtr(p, offs) ((void *)((p)->Base + (offs)))
+ #define Ppmd7_GetContext(p, offs) ((CPpmd7_Context *)Ppmd7_GetPtr((p), (offs)))
+ #define Ppmd7_GetStats(p, ctx) ((CPpmd_State *)Ppmd7_GetPtr((p), ((ctx)->Stats)))
+#endif
+
+#define Ppmd7_GetBinSumm(p) \
+ &p->BinSumm[Ppmd7Context_OneState(p->MinContext)->Freq - 1][p->PrevSuccess + \
+ p->NS2BSIndx[Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + \
+ (p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]) + \
+ 2 * p->HB2Flag[Ppmd7Context_OneState(p->MinContext)->Symbol] + \
+ ((p->RunLength >> 26) & 0x20)]
+
+#define kTopValue (1 << 24)
+#define MAX_FREQ 124
+#define UNIT_SIZE 12
+
+#define U2B(nu) ((UInt32)(nu) * UNIT_SIZE)
+#define U2I(nu) (p->Units2Indx[(nu) - 1])
+#define I2U(indx) (p->Indx2Units[indx])
+
+#ifdef PPMD_32BIT
+ #define REF(ptr) (ptr)
+#else
+ #define REF(ptr) ((UInt32)((Byte *)(ptr) - (p)->Base))
+#endif
+
+#define STATS_REF(ptr) ((CPpmd_State_Ref)REF(ptr))
+
+#define CTX(ref) ((CPpmd7_Context *)Ppmd7_GetContext(p, ref))
+#define STATS(ctx) Ppmd7_GetStats(p, ctx)
+#define ONE_STATE(ctx) Ppmd7Context_OneState(ctx)
+#define SUFFIX(ctx) CTX((ctx)->Suffix)
+
+static const UInt16 kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051};
+static const Byte PPMD7_kExpEscape[16] = { 25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 };
+
+typedef CPpmd7_Context * CTX_PTR;
+
+struct CPpmd7_Node_;
+
+typedef
+ #ifdef PPMD_32BIT
+ struct CPpmd7_Node_ *
+ #else
+ UInt32
+ #endif
+ CPpmd7_Node_Ref;
+
+typedef struct CPpmd7_Node_
+{
+ UInt16 Stamp; /* must be at offset 0 as CPpmd7_Context::NumStats. Stamp=0 means free */
+ UInt16 NU;
+ CPpmd7_Node_Ref Next; /* must be at offset >= 4 */
+ CPpmd7_Node_Ref Prev;
+} CPpmd7_Node;
+
+#ifdef PPMD_32BIT
+ #define NODE(ptr) (ptr)
+#else
+ #define NODE(offs) ((CPpmd7_Node *)(p->Base + (offs)))
+#endif
+
+static void Ppmd7_Update1(CPpmd7 *p);
+static void Ppmd7_Update1_0(CPpmd7 *p);
+static void Ppmd7_Update2(CPpmd7 *p);
+static void Ppmd7_UpdateBin(CPpmd7 *p);
+static CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked,
+ UInt32 *scale);
+
+/* ----------- Base ----------- */
+
+static void Ppmd7_Construct(CPpmd7 *p)
+{
+ unsigned i, k, m;
+
+ p->Base = 0;
+
+ for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++)
+ {
+ unsigned step = (i >= 12 ? 4 : (i >> 2) + 1);
+ do { p->Units2Indx[k++] = (Byte)i; } while(--step);
+ p->Indx2Units[i] = (Byte)k;
+ }
+
+ p->NS2BSIndx[0] = (0 << 1);
+ p->NS2BSIndx[1] = (1 << 1);
+ memset(p->NS2BSIndx + 2, (2 << 1), 9);
+ memset(p->NS2BSIndx + 11, (3 << 1), 256 - 11);
+
+ for (i = 0; i < 3; i++)
+ p->NS2Indx[i] = (Byte)i;
+ for (m = i, k = 1; i < 256; i++)
+ {
+ p->NS2Indx[i] = (Byte)m;
+ if (--k == 0)
+ k = (++m) - 2;
+ }
+
+ memset(p->HB2Flag, 0, 0x40);
+ memset(p->HB2Flag + 0x40, 8, 0x100 - 0x40);
+}
+
+static void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc)
+{
+ alloc->Free(alloc, p->Base);
+ p->Size = 0;
+ p->Base = 0;
+}
+
+static Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc)
+{
+ if (p->Base == 0 || p->Size != size)
+ {
+ Ppmd7_Free(p, alloc);
+ p->AlignOffset =
+ #ifdef PPMD_32BIT
+ (4 - size) & 3;
+ #else
+ 4 - (size & 3);
+ #endif
+ if ((p->Base = (Byte *)alloc->Alloc(alloc, p->AlignOffset + size
+ #ifndef PPMD_32BIT
+ + UNIT_SIZE
+ #endif
+ )) == 0)
+ return False;
+ p->Size = size;
+ }
+ return True;
+}
+
+static void InsertNode(CPpmd7 *p, void *node, unsigned indx)
+{
+ *((CPpmd_Void_Ref *)node) = p->FreeList[indx];
+ p->FreeList[indx] = REF(node);
+}
+
+static void *RemoveNode(CPpmd7 *p, unsigned indx)
+{
+ CPpmd_Void_Ref *node = (CPpmd_Void_Ref *)Ppmd7_GetPtr(p, p->FreeList[indx]);
+ p->FreeList[indx] = *node;
+ return node;
+}
+
+static void SplitBlock(CPpmd7 *p, void *ptr, unsigned oldIndx, unsigned newIndx)
+{
+ unsigned i, nu = I2U(oldIndx) - I2U(newIndx);
+ ptr = (Byte *)ptr + U2B(I2U(newIndx));
+ if (I2U(i = U2I(nu)) != nu)
+ {
+ unsigned k = I2U(--i);
+ InsertNode(p, ((Byte *)ptr) + U2B(k), nu - k - 1);
+ }
+ InsertNode(p, ptr, i);
+}
+
+static void GlueFreeBlocks(CPpmd7 *p)
+{
+ #ifdef PPMD_32BIT
+ CPpmd7_Node headItem;
+ CPpmd7_Node_Ref head = &headItem;
+ #else
+ CPpmd7_Node_Ref head = p->AlignOffset + p->Size;
+ #endif
+
+ CPpmd7_Node_Ref n = head;
+ unsigned i;
+
+ p->GlueCount = 255;
+
+ /* create doubly-linked list of free blocks */
+ for (i = 0; i < PPMD_NUM_INDEXES; i++)
+ {
+ UInt16 nu = I2U(i);
+ CPpmd7_Node_Ref next = (CPpmd7_Node_Ref)p->FreeList[i];
+ p->FreeList[i] = 0;
+ while (next != 0)
+ {
+ CPpmd7_Node *node = NODE(next);
+ node->Next = n;
+ n = NODE(n)->Prev = next;
+ next = *(const CPpmd7_Node_Ref *)node;
+ node->Stamp = 0;
+ node->NU = (UInt16)nu;
+ }
+ }
+ NODE(head)->Stamp = 1;
+ NODE(head)->Next = n;
+ NODE(n)->Prev = head;
+ if (p->LoUnit != p->HiUnit)
+ ((CPpmd7_Node *)p->LoUnit)->Stamp = 1;
+
+ /* Glue free blocks */
+ while (n != head)
+ {
+ CPpmd7_Node *node = NODE(n);
+ UInt32 nu = (UInt32)node->NU;
+ for (;;)
+ {
+ CPpmd7_Node *node2 = NODE(n) + nu;
+ nu += node2->NU;
+ if (node2->Stamp != 0 || nu >= 0x10000)
+ break;
+ NODE(node2->Prev)->Next = node2->Next;
+ NODE(node2->Next)->Prev = node2->Prev;
+ node->NU = (UInt16)nu;
+ }
+ n = node->Next;
+ }
+
+ /* Fill lists of free blocks */
+ for (n = NODE(head)->Next; n != head;)
+ {
+ CPpmd7_Node *node = NODE(n);
+ unsigned nu;
+ CPpmd7_Node_Ref next = node->Next;
+ for (nu = node->NU; nu > 128; nu -= 128, node += 128)
+ InsertNode(p, node, PPMD_NUM_INDEXES - 1);
+ if (I2U(i = U2I(nu)) != nu)
+ {
+ unsigned k = I2U(--i);
+ InsertNode(p, node + k, nu - k - 1);
+ }
+ InsertNode(p, node, i);
+ n = next;
+ }
+}
+
+static void *AllocUnitsRare(CPpmd7 *p, unsigned indx)
+{
+ unsigned i;
+ void *retVal;
+ if (p->GlueCount == 0)
+ {
+ GlueFreeBlocks(p);
+ if (p->FreeList[indx] != 0)
+ return RemoveNode(p, indx);
+ }
+ i = indx;
+ do
+ {
+ if (++i == PPMD_NUM_INDEXES)
+ {
+ UInt32 numBytes = U2B(I2U(indx));
+ p->GlueCount--;
+ return ((UInt32)(p->UnitsStart - p->Text) > numBytes) ? (p->UnitsStart -= numBytes) : (NULL);
+ }
+ }
+ while (p->FreeList[i] == 0);
+ retVal = RemoveNode(p, i);
+ SplitBlock(p, retVal, i, indx);
+ return retVal;
+}
+
+static void *AllocUnits(CPpmd7 *p, unsigned indx)
+{
+ UInt32 numBytes;
+ if (p->FreeList[indx] != 0)
+ return RemoveNode(p, indx);
+ numBytes = U2B(I2U(indx));
+ if (numBytes <= (UInt32)(p->HiUnit - p->LoUnit))
+ {
+ void *retVal = p->LoUnit;
+ p->LoUnit += numBytes;
+ return retVal;
+ }
+ return AllocUnitsRare(p, indx);
+}
+
+#define MyMem12Cpy(dest, src, num) \
+ { UInt32 *d = (UInt32 *)dest; const UInt32 *s = (const UInt32 *)src; UInt32 n = num; \
+ do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while(--n); }
+
+static void *ShrinkUnits(CPpmd7 *p, void *oldPtr, unsigned oldNU, unsigned newNU)
+{
+ unsigned i0 = U2I(oldNU);
+ unsigned i1 = U2I(newNU);
+ if (i0 == i1)
+ return oldPtr;
+ if (p->FreeList[i1] != 0)
+ {
+ void *ptr = RemoveNode(p, i1);
+ MyMem12Cpy(ptr, oldPtr, newNU);
+ InsertNode(p, oldPtr, i0);
+ return ptr;
+ }
+ SplitBlock(p, oldPtr, i0, i1);
+ return oldPtr;
+}
+
+#define SUCCESSOR(p) ((CPpmd_Void_Ref)((p)->SuccessorLow | ((UInt32)(p)->SuccessorHigh << 16)))
+
+static void SetSuccessor(CPpmd_State *p, CPpmd_Void_Ref v)
+{
+ (p)->SuccessorLow = (UInt16)((UInt32)(v) & 0xFFFF);
+ (p)->SuccessorHigh = (UInt16)(((UInt32)(v) >> 16) & 0xFFFF);
+}
+
+static void RestartModel(CPpmd7 *p)
+{
+ unsigned i, k, m;
+
+ memset(p->FreeList, 0, sizeof(p->FreeList));
+ p->Text = p->Base + p->AlignOffset;
+ p->HiUnit = p->Text + p->Size;
+ p->LoUnit = p->UnitsStart = p->HiUnit - p->Size / 8 / UNIT_SIZE * 7 * UNIT_SIZE;
+ p->GlueCount = 0;
+
+ p->OrderFall = p->MaxOrder;
+ p->RunLength = p->InitRL = -(Int32)((p->MaxOrder < 12) ? p->MaxOrder : 12) - 1;
+ p->PrevSuccess = 0;
+
+ p->MinContext = p->MaxContext = (CTX_PTR)(p->HiUnit -= UNIT_SIZE); /* AllocContext(p); */
+ p->MinContext->Suffix = 0;
+ p->MinContext->NumStats = 256;
+ p->MinContext->SummFreq = 256 + 1;
+ p->FoundState = (CPpmd_State *)p->LoUnit; /* AllocUnits(p, PPMD_NUM_INDEXES - 1); */
+ p->LoUnit += U2B(256 / 2);
+ p->MinContext->Stats = REF(p->FoundState);
+ for (i = 0; i < 256; i++)
+ {
+ CPpmd_State *s = &p->FoundState[i];
+ s->Symbol = (Byte)i;
+ s->Freq = 1;
+ SetSuccessor(s, 0);
+ }
+
+ for (i = 0; i < 128; i++)
+ for (k = 0; k < 8; k++)
+ {
+ UInt16 *dest = p->BinSumm[i] + k;
+ UInt16 val = (UInt16)(PPMD_BIN_SCALE - kInitBinEsc[k] / (i + 2));
+ for (m = 0; m < 64; m += 8)
+ dest[m] = val;
+ }
+
+ for (i = 0; i < 25; i++)
+ for (k = 0; k < 16; k++)
+ {
+ CPpmd_See *s = &p->See[i][k];
+ s->Summ = (UInt16)((5 * i + 10) << (s->Shift = PPMD_PERIOD_BITS - 4));
+ s->Count = 4;
+ }
+}
+
+static void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder)
+{
+ p->MaxOrder = maxOrder;
+ RestartModel(p);
+ p->DummySee.Shift = PPMD_PERIOD_BITS;
+ p->DummySee.Summ = 0; /* unused */
+ p->DummySee.Count = 64; /* unused */
+}
+
+static CTX_PTR CreateSuccessors(CPpmd7 *p, Bool skip)
+{
+ CPpmd_State upState;
+ CTX_PTR c = p->MinContext;
+ CPpmd_Byte_Ref upBranch = (CPpmd_Byte_Ref)SUCCESSOR(p->FoundState);
+ CPpmd_State *ps[PPMD7_MAX_ORDER];
+ unsigned numPs = 0;
+
+ if (!skip)
+ ps[numPs++] = p->FoundState;
+
+ while (c->Suffix)
+ {
+ CPpmd_Void_Ref successor;
+ CPpmd_State *s;
+ c = SUFFIX(c);
+ if (c->NumStats != 1)
+ {
+ for (s = STATS(c); s->Symbol != p->FoundState->Symbol; s++);
+ }
+ else
+ s = ONE_STATE(c);
+ successor = SUCCESSOR(s);
+ if (successor != upBranch)
+ {
+ c = CTX(successor);
+ if (numPs == 0)
+ return c;
+ break;
+ }
+ ps[numPs++] = s;
+ }
+
+ upState.Symbol = *(const Byte *)Ppmd7_GetPtr(p, upBranch);
+ SetSuccessor(&upState, upBranch + 1);
+
+ if (c->NumStats == 1)
+ upState.Freq = ONE_STATE(c)->Freq;
+ else
+ {
+ UInt32 cf, s0;
+ CPpmd_State *s;
+ for (s = STATS(c); s->Symbol != upState.Symbol; s++);
+ cf = s->Freq - 1;
+ s0 = c->SummFreq - c->NumStats - cf;
+ upState.Freq = (Byte)(1 + ((2 * cf <= s0) ? (5 * cf > s0) : ((2 * cf + 3 * s0 - 1) / (2 * s0))));
+ }
+
+ do
+ {
+ /* Create Child */
+ CTX_PTR c1; /* = AllocContext(p); */
+ if (p->HiUnit != p->LoUnit)
+ c1 = (CTX_PTR)(p->HiUnit -= UNIT_SIZE);
+ else if (p->FreeList[0] != 0)
+ c1 = (CTX_PTR)RemoveNode(p, 0);
+ else
+ {
+ c1 = (CTX_PTR)AllocUnitsRare(p, 0);
+ if (!c1)
+ return NULL;
+ }
+ c1->NumStats = 1;
+ *ONE_STATE(c1) = upState;
+ c1->Suffix = REF(c);
+ SetSuccessor(ps[--numPs], REF(c1));
+ c = c1;
+ }
+ while (numPs != 0);
+
+ return c;
+}
+
+static void SwapStates(CPpmd_State *t1, CPpmd_State *t2)
+{
+ CPpmd_State tmp = *t1;
+ *t1 = *t2;
+ *t2 = tmp;
+}
+
+static void UpdateModel(CPpmd7 *p)
+{
+ CPpmd_Void_Ref successor, fSuccessor = SUCCESSOR(p->FoundState);
+ CTX_PTR c;
+ unsigned s0, ns;
+
+ if (p->FoundState->Freq < MAX_FREQ / 4 && p->MinContext->Suffix != 0)
+ {
+ c = SUFFIX(p->MinContext);
+
+ if (c->NumStats == 1)
+ {
+ CPpmd_State *s = ONE_STATE(c);
+ if (s->Freq < 32)
+ s->Freq++;
+ }
+ else
+ {
+ CPpmd_State *s = STATS(c);
+ if (s->Symbol != p->FoundState->Symbol)
+ {
+ do { s++; } while (s->Symbol != p->FoundState->Symbol);
+ if (s[0].Freq >= s[-1].Freq)
+ {
+ SwapStates(&s[0], &s[-1]);
+ s--;
+ }
+ }
+ if (s->Freq < MAX_FREQ - 9)
+ {
+ s->Freq += 2;
+ c->SummFreq += 2;
+ }
+ }
+ }
+
+ if (p->OrderFall == 0)
+ {
+ p->MinContext = p->MaxContext = CreateSuccessors(p, True);
+ if (p->MinContext == 0)
+ {
+ RestartModel(p);
+ return;
+ }
+ SetSuccessor(p->FoundState, REF(p->MinContext));
+ return;
+ }
+
+ *p->Text++ = p->FoundState->Symbol;
+ successor = REF(p->Text);
+ if (p->Text >= p->UnitsStart)
+ {
+ RestartModel(p);
+ return;
+ }
+
+ if (fSuccessor)
+ {
+ if (fSuccessor <= successor)
+ {
+ CTX_PTR cs = CreateSuccessors(p, False);
+ if (cs == NULL)
+ {
+ RestartModel(p);
+ return;
+ }
+ fSuccessor = REF(cs);
+ }
+ if (--p->OrderFall == 0)
+ {
+ successor = fSuccessor;
+ p->Text -= (p->MaxContext != p->MinContext);
+ }
+ }
+ else
+ {
+ SetSuccessor(p->FoundState, successor);
+ fSuccessor = REF(p->MinContext);
+ }
+
+ s0 = p->MinContext->SummFreq - (ns = p->MinContext->NumStats) - (p->FoundState->Freq - 1);
+
+ for (c = p->MaxContext; c != p->MinContext; c = SUFFIX(c))
+ {
+ unsigned ns1;
+ UInt32 cf, sf;
+ if ((ns1 = c->NumStats) != 1)
+ {
+ if ((ns1 & 1) == 0)
+ {
+ /* Expand for one UNIT */
+ unsigned oldNU = ns1 >> 1;
+ unsigned i = U2I(oldNU);
+ if (i != U2I(oldNU + 1))
+ {
+ void *ptr = AllocUnits(p, i + 1);
+ void *oldPtr;
+ if (!ptr)
+ {
+ RestartModel(p);
+ return;
+ }
+ oldPtr = STATS(c);
+ MyMem12Cpy(ptr, oldPtr, oldNU);
+ InsertNode(p, oldPtr, i);
+ c->Stats = STATS_REF(ptr);
+ }
+ }
+ c->SummFreq = (UInt16)(c->SummFreq + (2 * ns1 < ns) + 2 * ((4 * ns1 <= ns) & (c->SummFreq <= 8 * ns1)));
+ }
+ else
+ {
+ CPpmd_State *s = (CPpmd_State*)AllocUnits(p, 0);
+ if (!s)
+ {
+ RestartModel(p);
+ return;
+ }
+ *s = *ONE_STATE(c);
+ c->Stats = REF(s);
+ if (s->Freq < MAX_FREQ / 4 - 1)
+ s->Freq <<= 1;
+ else
+ s->Freq = MAX_FREQ - 4;
+ c->SummFreq = (UInt16)(s->Freq + p->InitEsc + (ns > 3));
+ }
+ cf = 2 * (UInt32)p->FoundState->Freq * (c->SummFreq + 6);
+ sf = (UInt32)s0 + c->SummFreq;
+ if (cf < 6 * sf)
+ {
+ cf = 1 + (cf > sf) + (cf >= 4 * sf);
+ c->SummFreq += 3;
+ }
+ else
+ {
+ cf = 4 + (cf >= 9 * sf) + (cf >= 12 * sf) + (cf >= 15 * sf);
+ c->SummFreq = (UInt16)(c->SummFreq + cf);
+ }
+ {
+ CPpmd_State *s = STATS(c) + ns1;
+ SetSuccessor(s, successor);
+ s->Symbol = p->FoundState->Symbol;
+ s->Freq = (Byte)cf;
+ c->NumStats = (UInt16)(ns1 + 1);
+ }
+ }
+ p->MaxContext = p->MinContext = CTX(fSuccessor);
+}
+
+static void Rescale(CPpmd7 *p)
+{
+ unsigned i, adder, sumFreq, escFreq;
+ CPpmd_State *stats = STATS(p->MinContext);
+ CPpmd_State *s = p->FoundState;
+ {
+ CPpmd_State tmp = *s;
+ for (; s != stats; s--)
+ s[0] = s[-1];
+ *s = tmp;
+ }
+ escFreq = p->MinContext->SummFreq - s->Freq;
+ s->Freq += 4;
+ adder = (p->OrderFall != 0);
+ s->Freq = (Byte)((s->Freq + adder) >> 1);
+ sumFreq = s->Freq;
+
+ i = p->MinContext->NumStats - 1;
+ do
+ {
+ escFreq -= (++s)->Freq;
+ s->Freq = (Byte)((s->Freq + adder) >> 1);
+ sumFreq += s->Freq;
+ if (s[0].Freq > s[-1].Freq)
+ {
+ CPpmd_State *s1 = s;
+ CPpmd_State tmp = *s1;
+ do
+ s1[0] = s1[-1];
+ while (--s1 != stats && tmp.Freq > s1[-1].Freq);
+ *s1 = tmp;
+ }
+ }
+ while (--i);
+
+ if (s->Freq == 0)
+ {
+ unsigned numStats = p->MinContext->NumStats;
+ unsigned n0, n1;
+ do { i++; } while ((--s)->Freq == 0);
+ escFreq += i;
+ p->MinContext->NumStats = (UInt16)(p->MinContext->NumStats - i);
+ if (p->MinContext->NumStats == 1)
+ {
+ CPpmd_State tmp = *stats;
+ do
+ {
+ tmp.Freq = (Byte)(tmp.Freq - (tmp.Freq >> 1));
+ escFreq >>= 1;
+ }
+ while (escFreq > 1);
+ InsertNode(p, stats, U2I(((numStats + 1) >> 1)));
+ *(p->FoundState = ONE_STATE(p->MinContext)) = tmp;
+ return;
+ }
+ n0 = (numStats + 1) >> 1;
+ n1 = (p->MinContext->NumStats + 1) >> 1;
+ if (n0 != n1)
+ p->MinContext->Stats = STATS_REF(ShrinkUnits(p, stats, n0, n1));
+ }
+ p->MinContext->SummFreq = (UInt16)(sumFreq + escFreq - (escFreq >> 1));
+ p->FoundState = STATS(p->MinContext);
+}
+
+static CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *escFreq)
+{
+ CPpmd_See *see;
+ unsigned nonMasked = p->MinContext->NumStats - numMasked;
+ if (p->MinContext->NumStats != 256)
+ {
+ see = p->See[p->NS2Indx[nonMasked - 1]] +
+ (nonMasked < (unsigned)SUFFIX(p->MinContext)->NumStats - p->MinContext->NumStats) +
+ 2 * (p->MinContext->SummFreq < 11 * p->MinContext->NumStats) +
+ 4 * (numMasked > nonMasked) +
+ p->HiBitsFlag;
+ {
+ unsigned r = (see->Summ >> see->Shift);
+ see->Summ = (UInt16)(see->Summ - r);
+ *escFreq = r + (r == 0);
+ }
+ }
+ else
+ {
+ see = &p->DummySee;
+ *escFreq = 1;
+ }
+ return see;
+}
+
+static void NextContext(CPpmd7 *p)
+{
+ CTX_PTR c = CTX(SUCCESSOR(p->FoundState));
+ if (p->OrderFall == 0 && (Byte *)c > p->Text)
+ p->MinContext = p->MaxContext = c;
+ else
+ UpdateModel(p);
+}
+
+static void Ppmd7_Update1(CPpmd7 *p)
+{
+ CPpmd_State *s = p->FoundState;
+ s->Freq += 4;
+ p->MinContext->SummFreq += 4;
+ if (s[0].Freq > s[-1].Freq)
+ {
+ SwapStates(&s[0], &s[-1]);
+ p->FoundState = --s;
+ if (s->Freq > MAX_FREQ)
+ Rescale(p);
+ }
+ NextContext(p);
+}
+
+static void Ppmd7_Update1_0(CPpmd7 *p)
+{
+ p->PrevSuccess = (2 * p->FoundState->Freq > p->MinContext->SummFreq);
+ p->RunLength += p->PrevSuccess;
+ p->MinContext->SummFreq += 4;
+ if ((p->FoundState->Freq += 4) > MAX_FREQ)
+ Rescale(p);
+ NextContext(p);
+}
+
+static void Ppmd7_UpdateBin(CPpmd7 *p)
+{
+ p->FoundState->Freq = (Byte)(p->FoundState->Freq + (p->FoundState->Freq < 128 ? 1: 0));
+ p->PrevSuccess = 1;
+ p->RunLength++;
+ NextContext(p);
+}
+
+static void Ppmd7_Update2(CPpmd7 *p)
+{
+ p->MinContext->SummFreq += 4;
+ if ((p->FoundState->Freq += 4) > MAX_FREQ)
+ Rescale(p);
+ p->RunLength = p->InitRL;
+ UpdateModel(p);
+}
+
+/* ---------- Decode ---------- */
+
+static Bool Ppmd_RangeDec_Init(CPpmd7z_RangeDec *p)
+{
+ unsigned i;
+ p->Low = p->Bottom = 0;
+ p->Range = 0xFFFFFFFF;
+ for (i = 0; i < 4; i++)
+ p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
+ return (p->Code < 0xFFFFFFFF);
+}
+
+static Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p)
+{
+ if (p->Stream->Read((void *)p->Stream) != 0)
+ return False;
+ return Ppmd_RangeDec_Init(p);
+}
+
+static Bool PpmdRAR_RangeDec_Init(CPpmd7z_RangeDec *p)
+{
+ if (!Ppmd_RangeDec_Init(p))
+ return False;
+ p->Bottom = 0x8000;
+ return True;
+}
+
+static UInt32 Range_GetThreshold(void *pp, UInt32 total)
+{
+ CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
+ return (p->Code - p->Low) / (p->Range /= total);
+}
+
+static void Range_Normalize(CPpmd7z_RangeDec *p)
+{
+ while (1)
+ {
+ if((p->Low ^ (p->Low + p->Range)) >= kTopValue)
+ {
+ if(p->Range >= p->Bottom)
+ break;
+ else
+ p->Range = -p->Low & (p->Bottom - 1);
+ }
+ p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
+ p->Range <<= 8;
+ p->Low <<= 8;
+ }
+}
+
+static void Range_Decode_7z(void *pp, UInt32 start, UInt32 size)
+{
+ CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
+ p->Code -= start * p->Range;
+ p->Range *= size;
+ Range_Normalize(p);
+}
+
+static void Range_Decode_RAR(void *pp, UInt32 start, UInt32 size)
+{
+ CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
+ p->Low += start * p->Range;
+ p->Range *= size;
+ Range_Normalize(p);
+}
+
+static UInt32 Range_DecodeBit_7z(void *pp, UInt32 size0)
+{
+ CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
+ UInt32 newBound = (p->Range >> 14) * size0;
+ UInt32 symbol;
+ if (p->Code < newBound)
+ {
+ symbol = 0;
+ p->Range = newBound;
+ }
+ else
+ {
+ symbol = 1;
+ p->Code -= newBound;
+ p->Range -= newBound;
+ }
+ Range_Normalize(p);
+ return symbol;
+}
+
+static UInt32 Range_DecodeBit_RAR(void *pp, UInt32 size0)
+{
+ CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
+ UInt32 bit, value = p->p.GetThreshold(p, PPMD_BIN_SCALE);
+ if(value < size0)
+ {
+ bit = 0;
+ p->p.Decode(p, 0, size0);
+ }
+ else
+ {
+ bit = 1;
+ p->p.Decode(p, size0, PPMD_BIN_SCALE - size0);
+ }
+ return bit;
+}
+
+static void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p)
+{
+ p->p.GetThreshold = Range_GetThreshold;
+ p->p.Decode = Range_Decode_7z;
+ p->p.DecodeBit = Range_DecodeBit_7z;
+}
+
+static void PpmdRAR_RangeDec_CreateVTable(CPpmd7z_RangeDec *p)
+{
+ p->p.GetThreshold = Range_GetThreshold;
+ p->p.Decode = Range_Decode_RAR;
+ p->p.DecodeBit = Range_DecodeBit_RAR;
+}
+
+#define MASK(sym) ((signed char *)charMask)[sym]
+
+static int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc)
+{
+ size_t charMask[256 / sizeof(size_t)];
+ if (p->MinContext->NumStats != 1)
+ {
+ CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext);
+ unsigned i;
+ UInt32 count, hiCnt;
+ if ((count = rc->GetThreshold(rc, p->MinContext->SummFreq)) < (hiCnt = s->Freq))
+ {
+ Byte symbol;
+ rc->Decode(rc, 0, s->Freq);
+ p->FoundState = s;
+ symbol = s->Symbol;
+ Ppmd7_Update1_0(p);
+ return symbol;
+ }
+ p->PrevSuccess = 0;
+ i = p->MinContext->NumStats - 1;
+ do
+ {
+ if ((hiCnt += (++s)->Freq) > count)
+ {
+ Byte symbol;
+ rc->Decode(rc, hiCnt - s->Freq, s->Freq);
+ p->FoundState = s;
+ symbol = s->Symbol;
+ Ppmd7_Update1(p);
+ return symbol;
+ }
+ }
+ while (--i);
+ if (count >= p->MinContext->SummFreq)
+ return -2;
+ p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol];
+ rc->Decode(rc, hiCnt, p->MinContext->SummFreq - hiCnt);
+ PPMD_SetAllBitsIn256Bytes(charMask);
+ MASK(s->Symbol) = 0;
+ i = p->MinContext->NumStats - 1;
+ do { MASK((--s)->Symbol) = 0; } while (--i);
+ }
+ else
+ {
+ UInt16 *prob = Ppmd7_GetBinSumm(p);
+ if (rc->DecodeBit(rc, *prob) == 0)
+ {
+ Byte symbol;
+ *prob = (UInt16)PPMD_UPDATE_PROB_0(*prob);
+ symbol = (p->FoundState = Ppmd7Context_OneState(p->MinContext))->Symbol;
+ Ppmd7_UpdateBin(p);
+ return symbol;
+ }
+ *prob = (UInt16)PPMD_UPDATE_PROB_1(*prob);
+ p->InitEsc = PPMD7_kExpEscape[*prob >> 10];
+ PPMD_SetAllBitsIn256Bytes(charMask);
+ MASK(Ppmd7Context_OneState(p->MinContext)->Symbol) = 0;
+ p->PrevSuccess = 0;
+ }
+ for (;;)
+ {
+ CPpmd_State *ps[256], *s;
+ UInt32 freqSum, count, hiCnt;
+ CPpmd_See *see;
+ unsigned i, num, numMasked = p->MinContext->NumStats;
+ do
+ {
+ p->OrderFall++;
+ if (!p->MinContext->Suffix)
+ return -1;
+ p->MinContext = Ppmd7_GetContext(p, p->MinContext->Suffix);
+ }
+ while (p->MinContext->NumStats == numMasked);
+ hiCnt = 0;
+ s = Ppmd7_GetStats(p, p->MinContext);
+ i = 0;
+ num = p->MinContext->NumStats - numMasked;
+ do
+ {
+ int k = (int)(MASK(s->Symbol));
+ hiCnt += (s->Freq & k);
+ ps[i] = s++;
+ i -= k;
+ }
+ while (i != num);
+
+ see = Ppmd7_MakeEscFreq(p, numMasked, &freqSum);
+ freqSum += hiCnt;
+ count = rc->GetThreshold(rc, freqSum);
+
+ if (count < hiCnt)
+ {
+ Byte symbol;
+ CPpmd_State **pps = ps;
+ for (hiCnt = 0; (hiCnt += (*pps)->Freq) <= count; pps++);
+ s = *pps;
+ rc->Decode(rc, hiCnt - s->Freq, s->Freq);
+ Ppmd_See_Update(see);
+ p->FoundState = s;
+ symbol = s->Symbol;
+ Ppmd7_Update2(p);
+ return symbol;
+ }
+ if (count >= freqSum)
+ return -2;
+ rc->Decode(rc, hiCnt, freqSum - hiCnt);
+ see->Summ = (UInt16)(see->Summ + freqSum);
+ do { MASK(ps[--i]->Symbol) = 0; } while (i != 0);
+ }
+}
+
+/* ---------- Encode ---------- Ppmd7Enc.c */
+
+#define kTopValue (1 << 24)
+
+static void Ppmd7z_RangeEnc_Init(CPpmd7z_RangeEnc *p)
+{
+ p->Low = 0;
+ p->Range = 0xFFFFFFFF;
+ p->Cache = 0;
+ p->CacheSize = 1;
+}
+
+static void RangeEnc_ShiftLow(CPpmd7z_RangeEnc *p)
+{
+ if ((UInt32)p->Low < (UInt32)0xFF000000 || (unsigned)(p->Low >> 32) != 0)
+ {
+ Byte temp = p->Cache;
+ do
+ {
+ p->Stream->Write(p->Stream, (Byte)(temp + (Byte)(p->Low >> 32)));
+ temp = 0xFF;
+ }
+ while(--p->CacheSize != 0);
+ p->Cache = (Byte)((UInt32)p->Low >> 24);
+ }
+ p->CacheSize++;
+ p->Low = (UInt32)p->Low << 8;
+}
+
+static void RangeEnc_Encode(CPpmd7z_RangeEnc *p, UInt32 start, UInt32 size, UInt32 total)
+{
+ p->Low += start * (p->Range /= total);
+ p->Range *= size;
+ while (p->Range < kTopValue)
+ {
+ p->Range <<= 8;
+ RangeEnc_ShiftLow(p);
+ }
+}
+
+static void RangeEnc_EncodeBit_0(CPpmd7z_RangeEnc *p, UInt32 size0)
+{
+ p->Range = (p->Range >> 14) * size0;
+ while (p->Range < kTopValue)
+ {
+ p->Range <<= 8;
+ RangeEnc_ShiftLow(p);
+ }
+}
+
+static void RangeEnc_EncodeBit_1(CPpmd7z_RangeEnc *p, UInt32 size0)
+{
+ UInt32 newBound = (p->Range >> 14) * size0;
+ p->Low += newBound;
+ p->Range -= newBound;
+ while (p->Range < kTopValue)
+ {
+ p->Range <<= 8;
+ RangeEnc_ShiftLow(p);
+ }
+}
+
+static void Ppmd7z_RangeEnc_FlushData(CPpmd7z_RangeEnc *p)
+{
+ unsigned i;
+ for (i = 0; i < 5; i++)
+ RangeEnc_ShiftLow(p);
+}
+
+
+#define MASK(sym) ((signed char *)charMask)[sym]
+
+static void Ppmd7_EncodeSymbol(CPpmd7 *p, CPpmd7z_RangeEnc *rc, int symbol)
+{
+ size_t charMask[256 / sizeof(size_t)];
+ if (p->MinContext->NumStats != 1)
+ {
+ CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext);
+ UInt32 sum;
+ unsigned i;
+ if (s->Symbol == symbol)
+ {
+ RangeEnc_Encode(rc, 0, s->Freq, p->MinContext->SummFreq);
+ p->FoundState = s;
+ Ppmd7_Update1_0(p);
+ return;
+ }
+ p->PrevSuccess = 0;
+ sum = s->Freq;
+ i = p->MinContext->NumStats - 1;
+ do
+ {
+ if ((++s)->Symbol == symbol)
+ {
+ RangeEnc_Encode(rc, sum, s->Freq, p->MinContext->SummFreq);
+ p->FoundState = s;
+ Ppmd7_Update1(p);
+ return;
+ }
+ sum += s->Freq;
+ }
+ while (--i);
+
+ p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol];
+ PPMD_SetAllBitsIn256Bytes(charMask);
+ MASK(s->Symbol) = 0;
+ i = p->MinContext->NumStats - 1;
+ do { MASK((--s)->Symbol) = 0; } while (--i);
+ RangeEnc_Encode(rc, sum, p->MinContext->SummFreq - sum, p->MinContext->SummFreq);
+ }
+ else
+ {
+ UInt16 *prob = Ppmd7_GetBinSumm(p);
+ CPpmd_State *s = Ppmd7Context_OneState(p->MinContext);
+ if (s->Symbol == symbol)
+ {
+ RangeEnc_EncodeBit_0(rc, *prob);
+ *prob = (UInt16)PPMD_UPDATE_PROB_0(*prob);
+ p->FoundState = s;
+ Ppmd7_UpdateBin(p);
+ return;
+ }
+ else
+ {
+ RangeEnc_EncodeBit_1(rc, *prob);
+ *prob = (UInt16)PPMD_UPDATE_PROB_1(*prob);
+ p->InitEsc = PPMD7_kExpEscape[*prob >> 10];
+ PPMD_SetAllBitsIn256Bytes(charMask);
+ MASK(s->Symbol) = 0;
+ p->PrevSuccess = 0;
+ }
+ }
+ for (;;)
+ {
+ UInt32 escFreq;
+ CPpmd_See *see;
+ CPpmd_State *s;
+ UInt32 sum;
+ unsigned i, numMasked = p->MinContext->NumStats;
+ do
+ {
+ p->OrderFall++;
+ if (!p->MinContext->Suffix)
+ return; /* EndMarker (symbol = -1) */
+ p->MinContext = Ppmd7_GetContext(p, p->MinContext->Suffix);
+ }
+ while (p->MinContext->NumStats == numMasked);
+
+ see = Ppmd7_MakeEscFreq(p, numMasked, &escFreq);
+ s = Ppmd7_GetStats(p, p->MinContext);
+ sum = 0;
+ i = p->MinContext->NumStats;
+ do
+ {
+ int cur = s->Symbol;
+ if (cur == symbol)
+ {
+ UInt32 low = sum;
+ CPpmd_State *s1 = s;
+ do
+ {
+ sum += (s->Freq & (int)(MASK(s->Symbol)));
+ s++;
+ }
+ while (--i);
+ RangeEnc_Encode(rc, low, s1->Freq, sum + escFreq);
+ Ppmd_See_Update(see);
+ p->FoundState = s1;
+ Ppmd7_Update2(p);
+ return;
+ }
+ sum += (s->Freq & (int)(MASK(cur)));
+ MASK(cur) = 0;
+ s++;
+ }
+ while (--i);
+
+ RangeEnc_Encode(rc, sum, escFreq, sum + escFreq);
+ see->Summ = (UInt16)(see->Summ + sum + escFreq);
+ }
+}
+
+const IPpmd7 __archive_ppmd7_functions =
+{
+ &Ppmd7_Construct,
+ &Ppmd7_Alloc,
+ &Ppmd7_Free,
+ &Ppmd7_Init,
+ &Ppmd7z_RangeDec_CreateVTable,
+ &PpmdRAR_RangeDec_CreateVTable,
+ &Ppmd7z_RangeDec_Init,
+ &PpmdRAR_RangeDec_Init,
+ &Ppmd7_DecodeSymbol,
+ &Ppmd7z_RangeEnc_Init,
+ &Ppmd7z_RangeEnc_FlushData,
+ &Ppmd7_EncodeSymbol
+};
diff --git a/Utilities/cmlibarchive/libarchive/archive_ppmd7_private.h b/Utilities/cmlibarchive/libarchive/archive_ppmd7_private.h
new file mode 100644
index 000000000..3a6b9eb41
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_ppmd7_private.h
@@ -0,0 +1,119 @@
+/* Ppmd7.h -- PPMdH compression codec
+2010-03-12 : Igor Pavlov : Public domain
+This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
+
+/* This code supports virtual RangeDecoder and includes the implementation
+of RangeCoder from 7z, instead of RangeCoder from original PPMd var.H.
+If you need the compatibility with original PPMd var.H, you can use external RangeDecoder */
+
+#ifndef __LIBARCHIVE_BUILD
+#error This header is only to be used internally to libarchive.
+#endif
+
+#ifndef ARCHIVE_PPMD7_PRIVATE_H_INCLUDED
+#define ARCHIVE_PPMD7_PRIVATE_H_INCLUDED
+
+#include "archive_ppmd_private.h"
+
+#define PPMD7_MIN_ORDER 2
+#define PPMD7_MAX_ORDER 64
+
+#define PPMD7_MIN_MEM_SIZE (1 << 11)
+#define PPMD7_MAX_MEM_SIZE (0xFFFFFFFF - 12 * 3)
+
+struct CPpmd7_Context_;
+
+typedef
+ #ifdef PPMD_32BIT
+ struct CPpmd7_Context_ *
+ #else
+ UInt32
+ #endif
+ CPpmd7_Context_Ref;
+
+typedef struct CPpmd7_Context_
+{
+ UInt16 NumStats;
+ UInt16 SummFreq;
+ CPpmd_State_Ref Stats;
+ CPpmd7_Context_Ref Suffix;
+} CPpmd7_Context;
+
+#define Ppmd7Context_OneState(p) ((CPpmd_State *)&(p)->SummFreq)
+
+typedef struct
+{
+ CPpmd7_Context *MinContext, *MaxContext;
+ CPpmd_State *FoundState;
+ unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder, HiBitsFlag;
+ Int32 RunLength, InitRL; /* must be 32-bit at least */
+
+ UInt32 Size;
+ UInt32 GlueCount;
+ Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart;
+ UInt32 AlignOffset;
+
+ Byte Indx2Units[PPMD_NUM_INDEXES];
+ Byte Units2Indx[128];
+ CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES];
+ Byte NS2Indx[256], NS2BSIndx[256], HB2Flag[256];
+ CPpmd_See DummySee, See[25][16];
+ UInt16 BinSumm[128][64];
+} CPpmd7;
+
+/* ---------- Decode ---------- */
+
+typedef struct
+{
+ UInt32 (*GetThreshold)(void *p, UInt32 total);
+ void (*Decode)(void *p, UInt32 start, UInt32 size);
+ UInt32 (*DecodeBit)(void *p, UInt32 size0);
+} IPpmd7_RangeDec;
+
+typedef struct
+{
+ IPpmd7_RangeDec p;
+ UInt32 Range;
+ UInt32 Code;
+ UInt32 Low;
+ UInt32 Bottom;
+ IByteIn *Stream;
+} CPpmd7z_RangeDec;
+
+/* ---------- Encode ---------- */
+
+typedef struct
+{
+ UInt64 Low;
+ UInt32 Range;
+ Byte Cache;
+ UInt64 CacheSize;
+ IByteOut *Stream;
+} CPpmd7z_RangeEnc;
+
+typedef struct
+{
+ /* Base Functions */
+ void (*Ppmd7_Construct)(CPpmd7 *p);
+ Bool (*Ppmd7_Alloc)(CPpmd7 *p, UInt32 size, ISzAlloc *alloc);
+ void (*Ppmd7_Free)(CPpmd7 *p, ISzAlloc *alloc);
+ void (*Ppmd7_Init)(CPpmd7 *p, unsigned maxOrder);
+ #define Ppmd7_WasAllocated(p) ((p)->Base != NULL)
+
+ /* Decode Functions */
+ void (*Ppmd7z_RangeDec_CreateVTable)(CPpmd7z_RangeDec *p);
+ void (*PpmdRAR_RangeDec_CreateVTable)(CPpmd7z_RangeDec *p);
+ Bool (*Ppmd7z_RangeDec_Init)(CPpmd7z_RangeDec *p);
+ Bool (*PpmdRAR_RangeDec_Init)(CPpmd7z_RangeDec *p);
+ #define Ppmd7z_RangeDec_IsFinishedOK(p) ((p)->Code == 0)
+ int (*Ppmd7_DecodeSymbol)(CPpmd7 *p, IPpmd7_RangeDec *rc);
+
+ /* Encode Functions */
+ void (*Ppmd7z_RangeEnc_Init)(CPpmd7z_RangeEnc *p);
+ void (*Ppmd7z_RangeEnc_FlushData)(CPpmd7z_RangeEnc *p);
+
+ void (*Ppmd7_EncodeSymbol)(CPpmd7 *p, CPpmd7z_RangeEnc *rc, int symbol);
+} IPpmd7;
+
+extern const IPpmd7 __archive_ppmd7_functions;
+#endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_ppmd_private.h b/Utilities/cmlibarchive/libarchive/archive_ppmd_private.h
new file mode 100644
index 000000000..266676878
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_ppmd_private.h
@@ -0,0 +1,158 @@
+/* Ppmd.h -- PPMD codec common code
+2010-03-12 : Igor Pavlov : Public domain
+This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
+
+#ifndef __LIBARCHIVE_BUILD
+#error This header is only to be used internally to libarchive.
+#endif
+
+#ifndef ARCHIVE_PPMD_PRIVATE_H_INCLUDED
+#define ARCHIVE_PPMD_PRIVATE_H_INCLUDED
+
+#include <stddef.h>
+
+#include "archive_read_private.h"
+
+/*** Begin defined in Types.h ***/
+
+#if !defined(ZCONF_H)
+typedef unsigned char Byte;
+#endif
+typedef short Int16;
+typedef unsigned short UInt16;
+
+#ifdef _LZMA_UINT32_IS_ULONG
+typedef long Int32;
+typedef unsigned long UInt32;
+#else
+typedef int Int32;
+typedef unsigned int UInt32;
+#endif
+
+#ifdef _SZ_NO_INT_64
+
+/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.
+ NOTES: Some code will work incorrectly in that case! */
+
+typedef long Int64;
+typedef unsigned long UInt64;
+
+#else
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+typedef __int64 Int64;
+typedef unsigned __int64 UInt64;
+#define UINT64_CONST(n) n
+#else
+typedef long long int Int64;
+typedef unsigned long long int UInt64;
+#define UINT64_CONST(n) n ## ULL
+#endif
+
+#endif
+
+typedef int Bool;
+#define True 1
+#define False 0
+
+/* The following interfaces use first parameter as pointer to structure */
+
+typedef struct
+{
+ struct archive_read *a;
+ Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */
+} IByteIn;
+
+typedef struct
+{
+ struct archive_write *a;
+ void (*Write)(void *p, Byte b);
+} IByteOut;
+
+
+typedef struct
+{
+ void *(*Alloc)(void *p, size_t size);
+ void (*Free)(void *p, void *address); /* address can be 0 */
+} ISzAlloc;
+
+/*** End defined in Types.h ***/
+/*** Begin defined in CpuArch.h ***/
+
+#if defined(_M_IX86) || defined(__i386__)
+#define MY_CPU_X86
+#endif
+
+#if defined(MY_CPU_X86) || defined(_M_ARM)
+#define MY_CPU_32BIT
+#endif
+
+#ifdef MY_CPU_32BIT
+#define PPMD_32BIT
+#endif
+
+/*** End defined in CpuArch.h ***/
+
+#define PPMD_INT_BITS 7
+#define PPMD_PERIOD_BITS 7
+#define PPMD_BIN_SCALE (1 << (PPMD_INT_BITS + PPMD_PERIOD_BITS))
+
+#define PPMD_GET_MEAN_SPEC(summ, shift, round) (((summ) + (1 << ((shift) - (round)))) >> (shift))
+#define PPMD_GET_MEAN(summ) PPMD_GET_MEAN_SPEC((summ), PPMD_PERIOD_BITS, 2)
+#define PPMD_UPDATE_PROB_0(prob) ((prob) + (1 << PPMD_INT_BITS) - PPMD_GET_MEAN(prob))
+#define PPMD_UPDATE_PROB_1(prob) ((prob) - PPMD_GET_MEAN(prob))
+
+#define PPMD_N1 4
+#define PPMD_N2 4
+#define PPMD_N3 4
+#define PPMD_N4 ((128 + 3 - 1 * PPMD_N1 - 2 * PPMD_N2 - 3 * PPMD_N3) / 4)
+#define PPMD_NUM_INDEXES (PPMD_N1 + PPMD_N2 + PPMD_N3 + PPMD_N4)
+
+/* SEE-contexts for PPM-contexts with masked symbols */
+typedef struct
+{
+ UInt16 Summ; /* Freq */
+ Byte Shift; /* Speed of Freq change; low Shift is for fast change */
+ Byte Count; /* Count to next change of Shift */
+} CPpmd_See;
+
+#define Ppmd_See_Update(p) if ((p)->Shift < PPMD_PERIOD_BITS && --(p)->Count == 0) \
+ { (p)->Summ <<= 1; (p)->Count = (Byte)(3 << (p)->Shift++); }
+
+typedef struct
+{
+ Byte Symbol;
+ Byte Freq;
+ UInt16 SuccessorLow;
+ UInt16 SuccessorHigh;
+} CPpmd_State;
+
+typedef
+ #ifdef PPMD_32BIT
+ CPpmd_State *
+ #else
+ UInt32
+ #endif
+ CPpmd_State_Ref;
+
+typedef
+ #ifdef PPMD_32BIT
+ void *
+ #else
+ UInt32
+ #endif
+ CPpmd_Void_Ref;
+
+typedef
+ #ifdef PPMD_32BIT
+ Byte *
+ #else
+ UInt32
+ #endif
+ CPpmd_Byte_Ref;
+
+#define PPMD_SetAllBitsIn256Bytes(p) \
+ { unsigned i; for (i = 0; i < 256 / sizeof(p[0]); i += 8) { \
+ p[i+7] = p[i+6] = p[i+5] = p[i+4] = p[i+3] = p[i+2] = p[i+1] = p[i+0] = ~(size_t)0; }}
+
+#endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_private.h b/Utilities/cmlibarchive/libarchive/archive_private.h
new file mode 100644
index 000000000..9941e9661
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_private.h
@@ -0,0 +1,150 @@
+/*-
+ * 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.
+ *
+ * $FreeBSD: head/lib/libarchive/archive_private.h 201098 2009-12-28 02:58:14Z kientzle $
+ */
+
+#ifndef __LIBARCHIVE_BUILD
+#error This header is only to be used internally to libarchive.
+#endif
+
+#ifndef ARCHIVE_PRIVATE_H_INCLUDED
+#define ARCHIVE_PRIVATE_H_INCLUDED
+
+#if HAVE_ICONV_H
+#include <iconv.h>
+#endif
+
+#include "archive.h"
+#include "archive_string.h"
+
+#if defined(__GNUC__) && (__GNUC__ > 2 || \
+ (__GNUC__ == 2 && __GNUC_MINOR__ >= 5))
+#define __LA_DEAD __attribute__((__noreturn__))
+#else
+#define __LA_DEAD
+#endif
+
+#define ARCHIVE_WRITE_MAGIC (0xb0c5c0deU)
+#define ARCHIVE_READ_MAGIC (0xdeb0c5U)
+#define ARCHIVE_WRITE_DISK_MAGIC (0xc001b0c5U)
+#define ARCHIVE_READ_DISK_MAGIC (0xbadb0c5U)
+
+#define ARCHIVE_STATE_NEW 1U
+#define ARCHIVE_STATE_HEADER 2U
+#define ARCHIVE_STATE_DATA 4U
+#define ARCHIVE_STATE_EOF 0x10U
+#define ARCHIVE_STATE_CLOSED 0x20U
+#define ARCHIVE_STATE_FATAL 0x8000U
+#define ARCHIVE_STATE_ANY (0xFFFFU & ~ARCHIVE_STATE_FATAL)
+
+struct archive_vtable {
+ int (*archive_close)(struct archive *);
+ int (*archive_free)(struct archive *);
+ int (*archive_write_header)(struct archive *,
+ struct archive_entry *);
+ int (*archive_write_finish_entry)(struct archive *);
+ ssize_t (*archive_write_data)(struct archive *,
+ const void *, size_t);
+ ssize_t (*archive_write_data_block)(struct archive *,
+ const void *, size_t, int64_t);
+
+ int (*archive_read_next_header)(struct archive *,
+ struct archive_entry **);
+ int (*archive_read_next_header2)(struct archive *,
+ struct archive_entry *);
+ int (*archive_read_data_block)(struct archive *,
+ const void **, size_t *, int64_t *);
+
+ int (*archive_filter_count)(struct archive *);
+ int64_t (*archive_filter_bytes)(struct archive *, int);
+ int (*archive_filter_code)(struct archive *, int);
+ const char * (*archive_filter_name)(struct archive *, int);
+};
+
+struct archive_string_conv;
+
+struct archive {
+ /*
+ * The magic/state values are used to sanity-check the
+ * client's usage. If an API function is called at a
+ * ridiculous time, or the client passes us an invalid
+ * pointer, these values allow me to catch that.
+ */
+ unsigned int magic;
+ unsigned int state;
+
+ /*
+ * Some public API functions depend on the "real" type of the
+ * archive object.
+ */
+ struct archive_vtable *vtable;
+
+ int archive_format;
+ const char *archive_format_name;
+
+ int compression_code; /* Currently active compression. */
+ const char *compression_name;
+
+ /* Number of file entries processed. */
+ int file_count;
+
+ int archive_error_number;
+ const char *error;
+ struct archive_string error_string;
+
+ char *current_code;
+ unsigned current_codepage; /* Current ACP(ANSI CodePage). */
+ unsigned current_oemcp; /* Current OEMCP(OEM CodePage). */
+ struct archive_string_conv *sconv;
+};
+
+/* Check magic value and state; return(ARCHIVE_FATAL) if it isn't valid. */
+int __archive_check_magic(struct archive *, unsigned int magic,
+ unsigned int state, const char *func);
+#define archive_check_magic(a, expected_magic, allowed_states, function_name) \
+ do { \
+ int magic_test = __archive_check_magic((a), (expected_magic), \
+ (allowed_states), (function_name)); \
+ if (magic_test == ARCHIVE_FATAL) \
+ return ARCHIVE_FATAL; \
+ } while (0)
+
+void __archive_errx(int retvalue, const char *msg) __LA_DEAD;
+
+int __archive_mktemp(const char *tmpdir);
+
+int __archive_clean(struct archive *);
+
+#define err_combine(a,b) ((a) < (b) ? (a) : (b))
+
+#if defined(__BORLANDC__) || (defined(_MSC_VER) && _MSC_VER <= 1300)
+# define ARCHIVE_LITERAL_LL(x) x##i64
+# define ARCHIVE_LITERAL_ULL(x) x##ui64
+#else
+# define ARCHIVE_LITERAL_LL(x) x##ll
+# define ARCHIVE_LITERAL_ULL(x) x##ull
+#endif
+
+#endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_rb.c b/Utilities/cmlibarchive/libarchive/archive_rb.c
new file mode 100644
index 000000000..f8035d9df
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_rb.c
@@ -0,0 +1,701 @@
+/*-
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matt Thomas <matt@3am-software.com>.
+ *
+ * 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.
+ *
+ * Based on: NetBSD: rb.c,v 1.6 2010/04/30 13:58:09 joerg Exp
+ */
+
+#include "archive_platform.h"
+
+#include <stddef.h>
+
+#include "archive_rb.h"
+
+/* Keep in sync with archive_rb.h */
+#define RB_DIR_LEFT 0
+#define RB_DIR_RIGHT 1
+#define RB_DIR_OTHER 1
+#define rb_left rb_nodes[RB_DIR_LEFT]
+#define rb_right rb_nodes[RB_DIR_RIGHT]
+
+#define RB_FLAG_POSITION 0x2
+#define RB_FLAG_RED 0x1
+#define RB_FLAG_MASK (RB_FLAG_POSITION|RB_FLAG_RED)
+#define RB_FATHER(rb) \
+ ((struct archive_rb_node *)((rb)->rb_info & ~RB_FLAG_MASK))
+#define RB_SET_FATHER(rb, father) \
+ ((void)((rb)->rb_info = (uintptr_t)(father)|((rb)->rb_info & RB_FLAG_MASK)))
+
+#define RB_SENTINEL_P(rb) ((rb) == NULL)
+#define RB_LEFT_SENTINEL_P(rb) RB_SENTINEL_P((rb)->rb_left)
+#define RB_RIGHT_SENTINEL_P(rb) RB_SENTINEL_P((rb)->rb_right)
+#define RB_FATHER_SENTINEL_P(rb) RB_SENTINEL_P(RB_FATHER((rb)))
+#define RB_CHILDLESS_P(rb) \
+ (RB_SENTINEL_P(rb) || (RB_LEFT_SENTINEL_P(rb) && RB_RIGHT_SENTINEL_P(rb)))
+#define RB_TWOCHILDREN_P(rb) \
+ (!RB_SENTINEL_P(rb) && !RB_LEFT_SENTINEL_P(rb) && !RB_RIGHT_SENTINEL_P(rb))
+
+#define RB_POSITION(rb) \
+ (((rb)->rb_info & RB_FLAG_POSITION) ? RB_DIR_RIGHT : RB_DIR_LEFT)
+#define RB_RIGHT_P(rb) (RB_POSITION(rb) == RB_DIR_RIGHT)
+#define RB_LEFT_P(rb) (RB_POSITION(rb) == RB_DIR_LEFT)
+#define RB_RED_P(rb) (!RB_SENTINEL_P(rb) && ((rb)->rb_info & RB_FLAG_RED) != 0)
+#define RB_BLACK_P(rb) (RB_SENTINEL_P(rb) || ((rb)->rb_info & RB_FLAG_RED) == 0)
+#define RB_MARK_RED(rb) ((void)((rb)->rb_info |= RB_FLAG_RED))
+#define RB_MARK_BLACK(rb) ((void)((rb)->rb_info &= ~RB_FLAG_RED))
+#define RB_INVERT_COLOR(rb) ((void)((rb)->rb_info ^= RB_FLAG_RED))
+#define RB_ROOT_P(rbt, rb) ((rbt)->rbt_root == (rb))
+#define RB_SET_POSITION(rb, position) \
+ ((void)((position) ? ((rb)->rb_info |= RB_FLAG_POSITION) : \
+ ((rb)->rb_info &= ~RB_FLAG_POSITION)))
+#define RB_ZERO_PROPERTIES(rb) ((void)((rb)->rb_info &= ~RB_FLAG_MASK))
+#define RB_COPY_PROPERTIES(dst, src) \
+ ((void)((dst)->rb_info ^= ((dst)->rb_info ^ (src)->rb_info) & RB_FLAG_MASK))
+#define RB_SWAP_PROPERTIES(a, b) do { \
+ uintptr_t xorinfo = ((a)->rb_info ^ (b)->rb_info) & RB_FLAG_MASK; \
+ (a)->rb_info ^= xorinfo; \
+ (b)->rb_info ^= xorinfo; \
+ } while (/*CONSTCOND*/ 0)
+
+static void __archive_rb_tree_insert_rebalance(struct archive_rb_tree *,
+ struct archive_rb_node *);
+static void __archive_rb_tree_removal_rebalance(struct archive_rb_tree *,
+ struct archive_rb_node *, unsigned int);
+
+#define RB_SENTINEL_NODE NULL
+
+#define T 1
+#define F 0
+
+void
+__archive_rb_tree_init(struct archive_rb_tree *rbt,
+ const struct archive_rb_tree_ops *ops)
+{
+ rbt->rbt_ops = ops;
+ *((const struct archive_rb_node **)&rbt->rbt_root) = RB_SENTINEL_NODE;
+}
+
+struct archive_rb_node *
+__archive_rb_tree_find_node(struct archive_rb_tree *rbt, const void *key)
+{
+ archive_rbto_compare_key_fn compare_key = rbt->rbt_ops->rbto_compare_key;
+ struct archive_rb_node *parent = rbt->rbt_root;
+
+ while (!RB_SENTINEL_P(parent)) {
+ const signed int diff = (*compare_key)(parent, key);
+ if (diff == 0)
+ return parent;
+ parent = parent->rb_nodes[diff > 0];
+ }
+
+ return NULL;
+}
+
+struct archive_rb_node *
+__archive_rb_tree_find_node_geq(struct archive_rb_tree *rbt, const void *key)
+{
+ archive_rbto_compare_key_fn compare_key = rbt->rbt_ops->rbto_compare_key;
+ struct archive_rb_node *parent = rbt->rbt_root;
+ struct archive_rb_node *last = NULL;
+
+ while (!RB_SENTINEL_P(parent)) {
+ const signed int diff = (*compare_key)(parent, key);
+ if (diff == 0)
+ return parent;
+ if (diff < 0)
+ last = parent;
+ parent = parent->rb_nodes[diff > 0];
+ }
+
+ return last;
+}
+
+struct archive_rb_node *
+__archive_rb_tree_find_node_leq(struct archive_rb_tree *rbt, const void *key)
+{
+ archive_rbto_compare_key_fn compare_key = rbt->rbt_ops->rbto_compare_key;
+ struct archive_rb_node *parent = rbt->rbt_root;
+ struct archive_rb_node *last = NULL;
+
+ while (!RB_SENTINEL_P(parent)) {
+ const signed int diff = (*compare_key)(parent, key);
+ if (diff == 0)
+ return parent;
+ if (diff > 0)
+ last = parent;
+ parent = parent->rb_nodes[diff > 0];
+ }
+
+ return last;
+}
+
+int
+__archive_rb_tree_insert_node(struct archive_rb_tree *rbt,
+ struct archive_rb_node *self)
+{
+ archive_rbto_compare_nodes_fn compare_nodes = rbt->rbt_ops->rbto_compare_nodes;
+ struct archive_rb_node *parent, *tmp;
+ unsigned int position;
+ int rebalance;
+
+ tmp = rbt->rbt_root;
+ /*
+ * This is a hack. Because rbt->rbt_root is just a
+ * struct archive_rb_node *, just like rb_node->rb_nodes[RB_DIR_LEFT],
+ * we can use this fact to avoid a lot of tests for root and know
+ * that even at root, updating
+ * RB_FATHER(rb_node)->rb_nodes[RB_POSITION(rb_node)] will
+ * update rbt->rbt_root.
+ */
+ parent = (struct archive_rb_node *)(void *)&rbt->rbt_root;
+ position = RB_DIR_LEFT;
+
+ /*
+ * Find out where to place this new leaf.
+ */
+ while (!RB_SENTINEL_P(tmp)) {
+ const signed int diff = (*compare_nodes)(tmp, self);
+ if (diff == 0) {
+ /*
+ * Node already exists; don't insert.
+ */
+ return F;
+ }
+ parent = tmp;
+ position = (diff > 0);
+ tmp = parent->rb_nodes[position];
+ }
+
+ /*
+ * Initialize the node and insert as a leaf into the tree.
+ */
+ RB_SET_FATHER(self, parent);
+ RB_SET_POSITION(self, position);
+ if (parent == (struct archive_rb_node *)(void *)&rbt->rbt_root) {
+ RB_MARK_BLACK(self); /* root is always black */
+ rebalance = F;
+ } else {
+ /*
+ * All new nodes are colored red. We only need to rebalance
+ * if our parent is also red.
+ */
+ RB_MARK_RED(self);
+ rebalance = RB_RED_P(parent);
+ }
+ self->rb_left = parent->rb_nodes[position];
+ self->rb_right = parent->rb_nodes[position];
+ parent->rb_nodes[position] = self;
+
+ /*
+ * Rebalance tree after insertion
+ */
+ if (rebalance)
+ __archive_rb_tree_insert_rebalance(rbt, self);
+
+ return T;
+}
+
+/*
+ * Swap the location and colors of 'self' and its child @ which. The child
+ * can not be a sentinel node. This is our rotation function. However,
+ * since it preserves coloring, it great simplifies both insertion and
+ * removal since rotation almost always involves the exchanging of colors
+ * as a separate step.
+ */
+/*ARGSUSED*/
+static void
+__archive_rb_tree_reparent_nodes(
+ struct archive_rb_node *old_father, const unsigned int which)
+{
+ const unsigned int other = which ^ RB_DIR_OTHER;
+ struct archive_rb_node * const grandpa = RB_FATHER(old_father);
+ struct archive_rb_node * const old_child = old_father->rb_nodes[which];
+ struct archive_rb_node * const new_father = old_child;
+ struct archive_rb_node * const new_child = old_father;
+
+ /*
+ * Exchange descendant linkages.
+ */
+ grandpa->rb_nodes[RB_POSITION(old_father)] = new_father;
+ new_child->rb_nodes[which] = old_child->rb_nodes[other];
+ new_father->rb_nodes[other] = new_child;
+
+ /*
+ * Update ancestor linkages
+ */
+ RB_SET_FATHER(new_father, grandpa);
+ RB_SET_FATHER(new_child, new_father);
+
+ /*
+ * Exchange properties between new_father and new_child. The only
+ * change is that new_child's position is now on the other side.
+ */
+ RB_SWAP_PROPERTIES(new_father, new_child);
+ RB_SET_POSITION(new_child, other);
+
+ /*
+ * Make sure to reparent the new child to ourself.
+ */
+ if (!RB_SENTINEL_P(new_child->rb_nodes[which])) {
+ RB_SET_FATHER(new_child->rb_nodes[which], new_child);
+ RB_SET_POSITION(new_child->rb_nodes[which], which);
+ }
+
+}
+
+static void
+__archive_rb_tree_insert_rebalance(struct archive_rb_tree *rbt,
+ struct archive_rb_node *self)
+{
+ struct archive_rb_node * father = RB_FATHER(self);
+ struct archive_rb_node * grandpa;
+ struct archive_rb_node * uncle;
+ unsigned int which;
+ unsigned int other;
+
+ for (;;) {
+ /*
+ * We are red and our parent is red, therefore we must have a
+ * grandfather and he must be black.
+ */
+ grandpa = RB_FATHER(father);
+ which = (father == grandpa->rb_right);
+ other = which ^ RB_DIR_OTHER;
+ uncle = grandpa->rb_nodes[other];
+
+ if (RB_BLACK_P(uncle))
+ break;
+
+ /*
+ * Case 1: our uncle is red
+ * Simply invert the colors of our parent and
+ * uncle and make our grandparent red. And
+ * then solve the problem up at his level.
+ */
+ RB_MARK_BLACK(uncle);
+ RB_MARK_BLACK(father);
+ if (RB_ROOT_P(rbt, grandpa)) {
+ /*
+ * If our grandpa is root, don't bother
+ * setting him to red, just return.
+ */
+ return;
+ }
+ RB_MARK_RED(grandpa);
+ self = grandpa;
+ father = RB_FATHER(self);
+ if (RB_BLACK_P(father)) {
+ /*
+ * If our greatgrandpa is black, we're done.
+ */
+ return;
+ }
+ }
+
+ /*
+ * Case 2&3: our uncle is black.
+ */
+ if (self == father->rb_nodes[other]) {
+ /*
+ * Case 2: we are on the same side as our uncle
+ * Swap ourselves with our parent so this case
+ * becomes case 3. Basically our parent becomes our
+ * child.
+ */
+ __archive_rb_tree_reparent_nodes(father, other);
+ }
+ /*
+ * Case 3: we are opposite a child of a black uncle.
+ * Swap our parent and grandparent. Since our grandfather
+ * is black, our father will become black and our new sibling
+ * (former grandparent) will become red.
+ */
+ __archive_rb_tree_reparent_nodes(grandpa, which);
+
+ /*
+ * Final step: Set the root to black.
+ */
+ RB_MARK_BLACK(rbt->rbt_root);
+}
+
+static void
+__archive_rb_tree_prune_node(struct archive_rb_tree *rbt,
+ struct archive_rb_node *self, int rebalance)
+{
+ const unsigned int which = RB_POSITION(self);
+ struct archive_rb_node *father = RB_FATHER(self);
+
+ /*
+ * Since we are childless, we know that self->rb_left is pointing
+ * to the sentinel node.
+ */
+ father->rb_nodes[which] = self->rb_left;
+
+ /*
+ * Rebalance if requested.
+ */
+ if (rebalance)
+ __archive_rb_tree_removal_rebalance(rbt, father, which);
+}
+
+/*
+ * When deleting an interior node
+ */
+static void
+__archive_rb_tree_swap_prune_and_rebalance(struct archive_rb_tree *rbt,
+ struct archive_rb_node *self, struct archive_rb_node *standin)
+{
+ const unsigned int standin_which = RB_POSITION(standin);
+ unsigned int standin_other = standin_which ^ RB_DIR_OTHER;
+ struct archive_rb_node *standin_son;
+ struct archive_rb_node *standin_father = RB_FATHER(standin);
+ int rebalance = RB_BLACK_P(standin);
+
+ if (standin_father == self) {
+ /*
+ * As a child of self, any childen would be opposite of
+ * our parent.
+ */
+ standin_son = standin->rb_nodes[standin_which];
+ } else {
+ /*
+ * Since we aren't a child of self, any childen would be
+ * on the same side as our parent.
+ */
+ standin_son = standin->rb_nodes[standin_other];
+ }
+
+ if (RB_RED_P(standin_son)) {
+ /*
+ * We know we have a red child so if we flip it to black
+ * we don't have to rebalance.
+ */
+ RB_MARK_BLACK(standin_son);
+ rebalance = F;
+
+ if (standin_father != self) {
+ /*
+ * Change the son's parentage to point to his grandpa.
+ */
+ RB_SET_FATHER(standin_son, standin_father);
+ RB_SET_POSITION(standin_son, standin_which);
+ }
+ }
+
+ if (standin_father == self) {
+ /*
+ * If we are about to delete the standin's father, then when
+ * we call rebalance, we need to use ourselves as our father.
+ * Otherwise remember our original father. Also, sincef we are
+ * our standin's father we only need to reparent the standin's
+ * brother.
+ *
+ * | R --> S |
+ * | Q S --> Q T |
+ * | t --> |
+ *
+ * Have our son/standin adopt his brother as his new son.
+ */
+ standin_father = standin;
+ } else {
+ /*
+ * | R --> S . |
+ * | / \ | T --> / \ | / |
+ * | ..... | S --> ..... | T |
+ *
+ * Sever standin's connection to his father.
+ */
+ standin_father->rb_nodes[standin_which] = standin_son;
+ /*
+ * Adopt the far son.
+ */
+ standin->rb_nodes[standin_other] = self->rb_nodes[standin_other];
+ RB_SET_FATHER(standin->rb_nodes[standin_other], standin);
+ /*
+ * Use standin_other because we need to preserve standin_which
+ * for the removal_rebalance.
+ */
+ standin_other = standin_which;
+ }
+
+ /*
+ * Move the only remaining son to our standin. If our standin is our
+ * son, this will be the only son needed to be moved.
+ */
+ standin->rb_nodes[standin_other] = self->rb_nodes[standin_other];
+ RB_SET_FATHER(standin->rb_nodes[standin_other], standin);
+
+ /*
+ * Now copy the result of self to standin and then replace
+ * self with standin in the tree.
+ */
+ RB_COPY_PROPERTIES(standin, self);
+ RB_SET_FATHER(standin, RB_FATHER(self));
+ RB_FATHER(standin)->rb_nodes[RB_POSITION(standin)] = standin;
+
+ if (rebalance)
+ __archive_rb_tree_removal_rebalance(rbt, standin_father, standin_which);
+}
+
+/*
+ * We could do this by doing
+ * __archive_rb_tree_node_swap(rbt, self, which);
+ * __archive_rb_tree_prune_node(rbt, self, F);
+ *
+ * But it's more efficient to just evalate and recolor the child.
+ */
+static void
+__archive_rb_tree_prune_blackred_branch(
+ struct archive_rb_node *self, unsigned int which)
+{
+ struct archive_rb_node *father = RB_FATHER(self);
+ struct archive_rb_node *son = self->rb_nodes[which];
+
+ /*
+ * Remove ourselves from the tree and give our former child our
+ * properties (position, color, root).
+ */
+ RB_COPY_PROPERTIES(son, self);
+ father->rb_nodes[RB_POSITION(son)] = son;
+ RB_SET_FATHER(son, father);
+}
+/*
+ *
+ */
+void
+__archive_rb_tree_remove_node(struct archive_rb_tree *rbt,
+ struct archive_rb_node *self)
+{
+ struct archive_rb_node *standin;
+ unsigned int which;
+
+ /*
+ * In the following diagrams, we (the node to be removed) are S. Red
+ * nodes are lowercase. T could be either red or black.
+ *
+ * Remember the major axiom of the red-black tree: the number of
+ * black nodes from the root to each leaf is constant across all
+ * leaves, only the number of red nodes varies.
+ *
+ * Thus removing a red leaf doesn't require any other changes to a
+ * red-black tree. So if we must remove a node, attempt to rearrange
+ * the tree so we can remove a red node.
+ *
+ * The simpliest case is a childless red node or a childless root node:
+ *
+ * | T --> T | or | R --> * |
+ * | s --> * |
+ */
+ if (RB_CHILDLESS_P(self)) {
+ const int rebalance = RB_BLACK_P(self) && !RB_ROOT_P(rbt, self);
+ __archive_rb_tree_prune_node(rbt, self, rebalance);
+ return;
+ }
+ if (!RB_TWOCHILDREN_P(self)) {
+ /*
+ * The next simpliest case is the node we are deleting is
+ * black and has one red child.
+ *
+ * | T --> T --> T |
+ * | S --> R --> R |
+ * | r --> s --> * |
+ */
+ which = RB_LEFT_SENTINEL_P(self) ? RB_DIR_RIGHT : RB_DIR_LEFT;
+ __archive_rb_tree_prune_blackred_branch(self, which);
+ return;
+ }
+
+ /*
+ * We invert these because we prefer to remove from the inside of
+ * the tree.
+ */
+ which = RB_POSITION(self) ^ RB_DIR_OTHER;
+
+ /*
+ * Let's find the node closes to us opposite of our parent
+ * Now swap it with ourself, "prune" it, and rebalance, if needed.
+ */
+ standin = __archive_rb_tree_iterate(rbt, self, which);
+ __archive_rb_tree_swap_prune_and_rebalance(rbt, self, standin);
+}
+
+static void
+__archive_rb_tree_removal_rebalance(struct archive_rb_tree *rbt,
+ struct archive_rb_node *parent, unsigned int which)
+{
+
+ while (RB_BLACK_P(parent->rb_nodes[which])) {
+ unsigned int other = which ^ RB_DIR_OTHER;
+ struct archive_rb_node *brother = parent->rb_nodes[other];
+
+ /*
+ * For cases 1, 2a, and 2b, our brother's children must
+ * be black and our father must be black
+ */
+ if (RB_BLACK_P(parent)
+ && RB_BLACK_P(brother->rb_left)
+ && RB_BLACK_P(brother->rb_right)) {
+ if (RB_RED_P(brother)) {
+ /*
+ * Case 1: Our brother is red, swap its
+ * position (and colors) with our parent.
+ * This should now be case 2b (unless C or E
+ * has a red child which is case 3; thus no
+ * explicit branch to case 2b).
+ *
+ * B -> D
+ * A d -> b E
+ * C E -> A C
+ */
+ __archive_rb_tree_reparent_nodes(parent, other);
+ brother = parent->rb_nodes[other];
+ } else {
+ /*
+ * Both our parent and brother are black.
+ * Change our brother to red, advance up rank
+ * and go through the loop again.
+ *
+ * B -> *B
+ * *A D -> A d
+ * C E -> C E
+ */
+ RB_MARK_RED(brother);
+ if (RB_ROOT_P(rbt, parent))
+ return; /* root == parent == black */
+ which = RB_POSITION(parent);
+ parent = RB_FATHER(parent);
+ continue;
+ }
+ }
+ /*
+ * Avoid an else here so that case 2a above can hit either
+ * case 2b, 3, or 4.
+ */
+ if (RB_RED_P(parent)
+ && RB_BLACK_P(brother)
+ && RB_BLACK_P(brother->rb_left)
+ && RB_BLACK_P(brother->rb_right)) {
+ /*
+ * We are black, our father is red, our brother and
+ * both nephews are black. Simply invert/exchange the
+ * colors of our father and brother (to black and red
+ * respectively).
+ *
+ * | f --> F |
+ * | * B --> * b |
+ * | N N --> N N |
+ */
+ RB_MARK_BLACK(parent);
+ RB_MARK_RED(brother);
+ break; /* We're done! */
+ } else {
+ /*
+ * Our brother must be black and have at least one
+ * red child (it may have two).
+ */
+ if (RB_BLACK_P(brother->rb_nodes[other])) {
+ /*
+ * Case 3: our brother is black, our near
+ * nephew is red, and our far nephew is black.
+ * Swap our brother with our near nephew.
+ * This result in a tree that matches case 4.
+ * (Our father could be red or black).
+ *
+ * | F --> F |
+ * | x B --> x B |
+ * | n --> n |
+ */
+ __archive_rb_tree_reparent_nodes(brother, which);
+ brother = parent->rb_nodes[other];
+ }
+ /*
+ * Case 4: our brother is black and our far nephew
+ * is red. Swap our father and brother locations and
+ * change our far nephew to black. (these can be
+ * done in either order so we change the color first).
+ * The result is a valid red-black tree and is a
+ * terminal case. (again we don't care about the
+ * father's color)
+ *
+ * If the father is red, we will get a red-black-black
+ * tree:
+ * | f -> f --> b |
+ * | B -> B --> F N |
+ * | n -> N --> |
+ *
+ * If the father is black, we will get an all black
+ * tree:
+ * | F -> F --> B |
+ * | B -> B --> F N |
+ * | n -> N --> |
+ *
+ * If we had two red nephews, then after the swap,
+ * our former father would have a red grandson.
+ */
+ RB_MARK_BLACK(brother->rb_nodes[other]);
+ __archive_rb_tree_reparent_nodes(parent, other);
+ break; /* We're done! */
+ }
+ }
+}
+
+struct archive_rb_node *
+__archive_rb_tree_iterate(struct archive_rb_tree *rbt,
+ struct archive_rb_node *self, const unsigned int direction)
+{
+ const unsigned int other = direction ^ RB_DIR_OTHER;
+
+ if (self == NULL) {
+ self = rbt->rbt_root;
+ if (RB_SENTINEL_P(self))
+ return NULL;
+ while (!RB_SENTINEL_P(self->rb_nodes[direction]))
+ self = self->rb_nodes[direction];
+ return self;
+ }
+ /*
+ * We can't go any further in this direction. We proceed up in the
+ * opposite direction until our parent is in direction we want to go.
+ */
+ if (RB_SENTINEL_P(self->rb_nodes[direction])) {
+ while (!RB_ROOT_P(rbt, self)) {
+ if (other == RB_POSITION(self))
+ return RB_FATHER(self);
+ self = RB_FATHER(self);
+ }
+ return NULL;
+ }
+
+ /*
+ * Advance down one in current direction and go down as far as possible
+ * in the opposite direction.
+ */
+ self = self->rb_nodes[direction];
+ while (!RB_SENTINEL_P(self->rb_nodes[other]))
+ self = self->rb_nodes[other];
+ return self;
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_rb.h b/Utilities/cmlibarchive/libarchive/archive_rb.h
new file mode 100644
index 000000000..4562e9ebc
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_rb.h
@@ -0,0 +1,100 @@
+/*-
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matt Thomas <matt@3am-software.com>.
+ *
+ * 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.
+ *
+ * Based on NetBSD: rb.h,v 1.13 2009/08/16 10:57:01 yamt Exp
+ */
+#ifndef ARCHIVE_RB_H_
+#define ARCHIVE_RB_H_
+
+struct archive_rb_node {
+ struct archive_rb_node *rb_nodes[2];
+ /*
+ * rb_info contains the two flags and the parent back pointer.
+ * We put the two flags in the low two bits since we know that
+ * rb_node will have an alignment of 4 or 8 bytes.
+ */
+ uintptr_t rb_info;
+};
+
+#define ARCHIVE_RB_DIR_LEFT 0
+#define ARCHIVE_RB_DIR_RIGHT 1
+
+#define ARCHIVE_RB_TREE_MIN(T) \
+ __archive_rb_tree_iterate((T), NULL, ARCHIVE_RB_DIR_LEFT)
+#define ARCHIVE_RB_TREE_MAX(T) \
+ __archive_rb_tree_iterate((T), NULL, ARCHIVE_RB_DIR_RIGHT)
+#define ARCHIVE_RB_TREE_FOREACH(N, T) \
+ for ((N) = ARCHIVE_RB_TREE_MIN(T); (N); \
+ (N) = __archive_rb_tree_iterate((T), (N), ARCHIVE_RB_DIR_RIGHT))
+#define ARCHIVE_RB_TREE_FOREACH_REVERSE(N, T) \
+ for ((N) = ARCHIVE_RB_TREE_MAX(T); (N); \
+ (N) = __archive_rb_tree_iterate((T), (N), ARCHIVE_RB_DIR_LEFT))
+
+/*
+ * archive_rbto_compare_nodes_fn:
+ * return a positive value if the first node < the second node.
+ * return a negative value if the first node > the second node.
+ * return 0 if they are considered same.
+ *
+ * archive_rbto_compare_key_fn:
+ * return a positive value if the node < the key.
+ * return a negative value if the node > the key.
+ * return 0 if they are considered same.
+ */
+
+typedef signed int (*const archive_rbto_compare_nodes_fn)(const struct archive_rb_node *,
+ const struct archive_rb_node *);
+typedef signed int (*const archive_rbto_compare_key_fn)(const struct archive_rb_node *,
+ const void *);
+
+struct archive_rb_tree_ops {
+ archive_rbto_compare_nodes_fn rbto_compare_nodes;
+ archive_rbto_compare_key_fn rbto_compare_key;
+};
+
+struct archive_rb_tree {
+ struct archive_rb_node *rbt_root;
+ const struct archive_rb_tree_ops *rbt_ops;
+};
+
+void __archive_rb_tree_init(struct archive_rb_tree *,
+ const struct archive_rb_tree_ops *);
+int __archive_rb_tree_insert_node(struct archive_rb_tree *,
+ struct archive_rb_node *);
+struct archive_rb_node *
+ __archive_rb_tree_find_node(struct archive_rb_tree *, const void *);
+struct archive_rb_node *
+ __archive_rb_tree_find_node_geq(struct archive_rb_tree *, const void *);
+struct archive_rb_node *
+ __archive_rb_tree_find_node_leq(struct archive_rb_tree *, const void *);
+void __archive_rb_tree_remove_node(struct archive_rb_tree *, struct archive_rb_node *);
+struct archive_rb_node *
+ __archive_rb_tree_iterate(struct archive_rb_tree *,
+ struct archive_rb_node *, const unsigned int);
+
+#endif /* ARCHIVE_RB_H_*/
diff --git a/Utilities/cmlibarchive/libarchive/archive_read.3 b/Utilities/cmlibarchive/libarchive/archive_read.3
new file mode 100644
index 000000000..52851925c
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read.3
@@ -0,0 +1,250 @@
+.\" 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 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: head/lib/libarchive/archive_read.3 191595 2009-04-27 20:13:13Z kientzle $
+.\"
+.Dd March 23, 2011
+.Dt ARCHIVE_READ 3
+.Os
+.Sh NAME
+.Nm archive_read
+.Nd functions for reading streaming archives
+.Sh SYNOPSIS
+.In archive.h
+.Sh DESCRIPTION
+These functions provide a complete API for reading streaming archives.
+The general process is to first create the
+.Tn struct archive
+object, set options, initialize the reader, iterate over the archive
+headers and associated data, then close the archive and release all
+resources.
+.\"
+.Ss Create archive object
+See
+.Xr archive_read_new 3 .
+.Pp
+To read an archive, you must first obtain an initialized
+.Tn struct archive
+object from
+.Fn archive_read_new .
+.\"
+.Ss Enable filters and formats
+See
+.Xr archive_read_filter 3
+and
+.Xr archive_read_format 3 .
+.Pp
+You can then modify this object for the desired operations with the
+various
+.Fn archive_read_set_XXX
+and
+.Fn archive_read_support_XXX
+functions.
+In particular, you will need to invoke appropriate
+.Fn archive_read_support_XXX
+functions to enable the corresponding compression and format
+support.
+Note that these latter functions perform two distinct operations:
+they cause the corresponding support code to be linked into your
+program, and they enable the corresponding auto-detect code.
+Unless you have specific constraints, you will generally want
+to invoke
+.Fn archive_read_support_filter_all
+and
+.Fn archive_read_support_format_all
+to enable auto-detect for all formats and compression types
+currently supported by the library.
+.\"
+.Ss Set options
+See
+.Xr archive_read_set_options 3 .
+.\"
+.Ss Open archive
+See
+.Xr archive_read_open 3 .
+.Pp
+Once you have prepared the
+.Tn struct archive
+object, you call
+.Fn archive_read_open
+to actually open the archive and prepare it for reading.
+There are several variants of this function;
+the most basic expects you to provide pointers to several
+functions that can provide blocks of bytes from the archive.
+There are convenience forms that allow you to
+specify a filename, file descriptor,
+.Ft "FILE *"
+object, or a block of memory from which to read the archive data.
+Note that the core library makes no assumptions about the
+size of the blocks read;
+callback functions are free to read whatever block size is
+most appropriate for the medium.
+.\"
+.Ss Consume archive
+See
+.Xr archive_read_header 3 ,
+.Xr archive_read_data 3
+and
+.Xr archive_read_extract 3 .
+.Pp
+Each archive entry consists of a header followed by a certain
+amount of data.
+You can obtain the next header with
+.Fn archive_read_next_header ,
+which returns a pointer to an
+.Tn struct archive_entry
+structure with information about the current archive element.
+If the entry is a regular file, then the header will be followed
+by the file data.
+You can use
+.Fn archive_read_data
+(which works much like the
+.Xr read 2
+system call)
+to read this data from the archive, or
+.Fn archive_read_data_block
+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 ,
+which copies the data to the provided file descriptor, or
+.Fn archive_read_extract ,
+which recreates the specified entry on disk and copies data
+from the archive.
+In particular, note that
+.Fn archive_read_extract
+uses the
+.Tn struct archive_entry
+structure that you provide it, which may differ from the
+entry just read from the archive.
+In particular, many applications will want to override the
+pathname, file permissions, or ownership.
+.\"
+.Ss Release resources
+See
+.Xr archive_read_free 3 .
+.Pp
+Once you have finished reading data from the archive, you
+should call
+.Fn archive_read_close
+to close the archive, then call
+.Fn archive_read_free
+to release all resources, including all memory allocated by the library.
+.\"
+.Sh EXAMPLE
+The following illustrates basic usage of the library.
+In this example,
+the callback functions are simply wrappers around the standard
+.Xr open 2 ,
+.Xr read 2 ,
+and
+.Xr close 2
+system calls.
+.Bd -literal -offset indent
+void
+list_archive(const char *name)
+{
+ struct mydata *mydata;
+ struct archive *a;
+ struct archive_entry *entry;
+
+ mydata = malloc(sizeof(struct mydata));
+ a = archive_read_new();
+ mydata->name = name;
+ archive_read_support_filter_all(a);
+ archive_read_support_format_all(a);
+ archive_read_open(a, mydata, myopen, myread, myclose);
+ while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
+ printf("%s\en",archive_entry_pathname(entry));
+ archive_read_data_skip(a);
+ }
+ archive_read_free(a);
+ free(mydata);
+}
+
+ssize_t
+myread(struct archive *a, void *client_data, const void **buff)
+{
+ struct mydata *mydata = client_data;
+
+ *buff = mydata->buff;
+ return (read(mydata->fd, mydata->buff, 10240));
+}
+
+int
+myopen(struct archive *a, void *client_data)
+{
+ struct mydata *mydata = client_data;
+
+ mydata->fd = open(mydata->name, O_RDONLY);
+ return (mydata->fd >= 0 ? ARCHIVE_OK : ARCHIVE_FATAL);
+}
+
+int
+myclose(struct archive *a, void *client_data)
+{
+ struct mydata *mydata = client_data;
+
+ if (mydata->fd > 0)
+ close(mydata->fd);
+ return (ARCHIVE_OK);
+}
+.Ed
+.\" .Sh ERRORS
+.Sh SEE ALSO
+.Xr tar 1 ,
+.Xr libarchive 3 ,
+.Xr archive_read_new 3 ,
+.Xr archive_read_data 3 ,
+.Xr archive_read_extract 3 ,
+.Xr archive_read_filter 3 ,
+.Xr archive_read_format 3 ,
+.Xr archive_read_header 3 ,
+.Xr archive_read_open 3 ,
+.Xr archive_read_set_options 3 ,
+.Xr archive_util 3 ,
+.Xr tar 5
+.Sh HISTORY
+The
+.Nm libarchive
+library first appeared in
+.Fx 5.3 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm libarchive
+library was written by
+.An Tim Kientzle Aq kientzle@acm.org .
+.Sh BUGS
+Many traditional archiver programs treat
+empty files as valid empty archives.
+For example, many implementations of
+.Xr tar 1
+allow you to append entries to an empty file.
+Of course, it is impossible to determine the format of an empty file
+by inspecting the contents, so this library treats empty files as
+having a special
+.Dq empty
+format.
diff --git a/Utilities/cmlibarchive/libarchive/archive_read.c b/Utilities/cmlibarchive/libarchive/archive_read.c
new file mode 100644
index 000000000..baf9dc467
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read.c
@@ -0,0 +1,1342 @@
+/*-
+ * Copyright (c) 2003-2011 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.
+ */
+
+/*
+ * This file contains the "essential" portions of the read API, that
+ * is, stuff that will probably always be used by any client that
+ * actually needs to read an archive. Optional pieces have been, as
+ * far as possible, separated out into separate files to avoid
+ * needlessly bloating statically-linked clients.
+ */
+
+#include "archive_platform.h"
+__FBSDID("$FreeBSD: head/lib/libarchive/archive_read.c 201157 2009-12-29 05:30:23Z kientzle $");
+
+#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
+
+#include "archive.h"
+#include "archive_entry.h"
+#include "archive_private.h"
+#include "archive_read_private.h"
+
+#define minimum(a, b) (a < b ? a : b)
+
+static int choose_filters(struct archive_read *);
+static int choose_format(struct archive_read *);
+static void free_filters(struct archive_read *);
+static int close_filters(struct archive_read *);
+static struct archive_vtable *archive_read_vtable(void);
+static int64_t _archive_filter_bytes(struct archive *, int);
+static int _archive_filter_code(struct archive *, int);
+static const char *_archive_filter_name(struct archive *, int);
+static int _archive_filter_count(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_free(struct archive *);
+static int _archive_read_next_header(struct archive *,
+ struct archive_entry **);
+static int _archive_read_next_header2(struct archive *,
+ struct archive_entry *);
+static int64_t advance_file_pointer(struct archive_read_filter *, int64_t);
+
+static struct archive_vtable *
+archive_read_vtable(void)
+{
+ static struct archive_vtable av;
+ static int inited = 0;
+
+ if (!inited) {
+ av.archive_filter_bytes = _archive_filter_bytes;
+ av.archive_filter_code = _archive_filter_code;
+ av.archive_filter_name = _archive_filter_name;
+ av.archive_filter_count = _archive_filter_count;
+ 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;
+ av.archive_free = _archive_read_free;
+ av.archive_close = _archive_read_close;
+ inited = 1;
+ }
+ return (&av);
+}
+
+/*
+ * Allocate, initialize and return a struct archive object.
+ */
+struct archive *
+archive_read_new(void)
+{
+ struct archive_read *a;
+
+ a = (struct archive_read *)malloc(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();
+
+ return (&a->archive);
+}
+
+/*
+ * Record the do-not-extract-to file. This belongs in archive_read_extract.c.
+ */
+void
+archive_read_extract_set_skip_file(struct archive *_a, int64_t d, int64_t i)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+
+ if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_extract_set_skip_file"))
+ return;
+ a->skip_file_set = 1;
+ a->skip_file_dev = d;
+ a->skip_file_ino = i;
+}
+
+/*
+ * Open the archive
+ */
+int
+archive_read_open(struct archive *a, void *client_data,
+ archive_open_callback *client_opener, archive_read_callback *client_reader,
+ archive_close_callback *client_closer)
+{
+ /* Old archive_read_open() is just a thin shell around
+ * archive_read_open1. */
+ archive_read_set_open_callback(a, client_opener);
+ archive_read_set_read_callback(a, client_reader);
+ archive_read_set_close_callback(a, client_closer);
+ archive_read_set_callback_data(a, client_data);
+ return archive_read_open1(a);
+}
+
+
+int
+archive_read_open2(struct archive *a, void *client_data,
+ archive_open_callback *client_opener,
+ archive_read_callback *client_reader,
+ archive_skip_callback *client_skipper,
+ archive_close_callback *client_closer)
+{
+ /* Old archive_read_open2() is just a thin shell around
+ * archive_read_open1. */
+ archive_read_set_callback_data(a, client_data);
+ archive_read_set_open_callback(a, client_opener);
+ archive_read_set_read_callback(a, client_reader);
+ archive_read_set_skip_callback(a, client_skipper);
+ archive_read_set_close_callback(a, client_closer);
+ return archive_read_open1(a);
+}
+
+static ssize_t
+client_read_proxy(struct archive_read_filter *self, const void **buff)
+{
+ ssize_t r;
+ r = (self->archive->client.reader)(&self->archive->archive,
+ self->data, buff);
+ return (r);
+}
+
+static int64_t
+client_skip_proxy(struct archive_read_filter *self, int64_t request)
+{
+ if (request < 0)
+ __archive_errx(1, "Negative skip requested.");
+ if (request == 0)
+ return 0;
+
+ if (self->archive->client.skipper != NULL) {
+ /* Seek requests over 1GiB are broken down into
+ * multiple seeks. This avoids overflows when the
+ * requests get passed through 32-bit arguments. */
+ int64_t skip_limit = (int64_t)1 << 30;
+ int64_t total = 0;
+ for (;;) {
+ int64_t get, ask = request;
+ if (ask > skip_limit)
+ ask = skip_limit;
+ get = (self->archive->client.skipper)(&self->archive->archive,
+ self->data, ask);
+ if (get == 0)
+ return (total);
+ request -= get;
+ total += get;
+ }
+ return total;
+ } else if (self->archive->client.seeker != NULL
+ && request > 64 * 1024) {
+ /* If the client provided a seeker but not a skipper,
+ * we can use the seeker to skip forward.
+ *
+ * Note: This isn't always a good idea. The client
+ * skipper is allowed to skip by less than requested
+ * if it needs to maintain block alignment. The
+ * seeker is not allowed to play such games, so using
+ * the seeker here may be a performance loss compared
+ * to just reading and discarding. That's why we
+ * only do this for skips of over 64k.
+ */
+ int64_t before = self->position;
+ int64_t after = (self->archive->client.seeker)(&self->archive->archive,
+ self->data, request, SEEK_CUR);
+ if (after != before + request)
+ return ARCHIVE_FATAL;
+ return after - before;
+ }
+ return 0;
+}
+
+static int64_t
+client_seek_proxy(struct archive_read_filter *self, int64_t offset, int whence)
+{
+ /* DO NOT use the skipper here! If we transparently handled
+ * forward seek here by using the skipper, that will break
+ * other libarchive code that assumes a successful forward
+ * seek means it can also seek backwards.
+ */
+ if (self->archive->client.seeker == NULL)
+ return (ARCHIVE_FAILED);
+ return (self->archive->client.seeker)(&self->archive->archive,
+ self->data, offset, whence);
+}
+
+static int
+client_close_proxy(struct archive_read_filter *self)
+{
+ int r = ARCHIVE_OK;
+
+ if (self->archive->client.closer != NULL)
+ r = (self->archive->client.closer)((struct archive *)self->archive,
+ self->data);
+ return (r);
+}
+
+int
+archive_read_set_open_callback(struct archive *_a,
+ archive_open_callback *client_opener)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
+ "archive_read_set_open_callback");
+ a->client.opener = client_opener;
+ return ARCHIVE_OK;
+}
+
+int
+archive_read_set_read_callback(struct archive *_a,
+ archive_read_callback *client_reader)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
+ "archive_read_set_read_callback");
+ a->client.reader = client_reader;
+ return ARCHIVE_OK;
+}
+
+int
+archive_read_set_skip_callback(struct archive *_a,
+ archive_skip_callback *client_skipper)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
+ "archive_read_set_skip_callback");
+ a->client.skipper = client_skipper;
+ return ARCHIVE_OK;
+}
+
+int
+archive_read_set_seek_callback(struct archive *_a,
+ archive_seek_callback *client_seeker)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
+ "archive_read_set_seek_callback");
+ a->client.seeker = client_seeker;
+ return ARCHIVE_OK;
+}
+
+int
+archive_read_set_close_callback(struct archive *_a,
+ archive_close_callback *client_closer)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
+ "archive_read_set_close_callback");
+ a->client.closer = client_closer;
+ return ARCHIVE_OK;
+}
+
+int
+archive_read_set_callback_data(struct archive *_a, void *client_data)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
+ "archive_read_set_callback_data");
+ a->client.data = client_data;
+ return ARCHIVE_OK;
+}
+
+int
+archive_read_open1(struct archive *_a)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ struct archive_read_filter *filter;
+ int slot, e;
+
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
+ "archive_read_open");
+ archive_clear_error(&a->archive);
+
+ if (a->client.reader == NULL) {
+ archive_set_error(&a->archive, EINVAL,
+ "No reader function provided to archive_read_open");
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ return (ARCHIVE_FATAL);
+ }
+
+ /* Open data source. */
+ if (a->client.opener != NULL) {
+ e =(a->client.opener)(&a->archive, a->client.data);
+ if (e != 0) {
+ /* If the open failed, call the closer to clean up. */
+ if (a->client.closer)
+ (a->client.closer)(&a->archive, a->client.data);
+ return (e);
+ }
+ }
+
+ filter = calloc(1, sizeof(*filter));
+ if (filter == NULL)
+ return (ARCHIVE_FATAL);
+ filter->bidder = NULL;
+ filter->upstream = NULL;
+ filter->archive = a;
+ filter->data = a->client.data;
+ filter->read = client_read_proxy;
+ filter->skip = client_skip_proxy;
+ filter->seek = client_seek_proxy;
+ filter->close = client_close_proxy;
+ filter->name = "none";
+ filter->code = ARCHIVE_COMPRESSION_NONE;
+ a->filter = filter;
+
+ /* Build out the input pipeline. */
+ e = choose_filters(a);
+ if (e < ARCHIVE_WARN) {
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ return (ARCHIVE_FATAL);
+ }
+
+ slot = choose_format(a);
+ if (slot < 0) {
+ close_filters(a);
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ return (ARCHIVE_FATAL);
+ }
+ a->format = &(a->formats[slot]);
+
+ a->archive.state = ARCHIVE_STATE_HEADER;
+ return (e);
+}
+
+/*
+ * Allow each registered stream transform to bid on whether
+ * it wants to handle this stream. Repeat until we've finished
+ * building the pipeline.
+ */
+static int
+choose_filters(struct archive_read *a)
+{
+ int number_bidders, i, bid, best_bid;
+ struct archive_read_filter_bidder *bidder, *best_bidder;
+ struct archive_read_filter *filter;
+ ssize_t avail;
+ int r;
+
+ for (;;) {
+ number_bidders = sizeof(a->bidders) / sizeof(a->bidders[0]);
+
+ best_bid = 0;
+ best_bidder = NULL;
+
+ bidder = a->bidders;
+ for (i = 0; i < number_bidders; i++, bidder++) {
+ if (bidder->bid != NULL) {
+ bid = (bidder->bid)(bidder, a->filter);
+ if (bid > best_bid) {
+ best_bid = bid;
+ best_bidder = bidder;
+ }
+ }
+ }
+
+ /* If no bidder, we're done. */
+ if (best_bidder == NULL) {
+ /* Verify the filter by asking it for some data. */
+ __archive_read_filter_ahead(a->filter, 1, &avail);
+ if (avail < 0) {
+ close_filters(a);
+ free_filters(a);
+ return (ARCHIVE_FATAL);
+ }
+ a->archive.compression_name = a->filter->name;
+ a->archive.compression_code = a->filter->code;
+ return (ARCHIVE_OK);
+ }
+
+ filter
+ = (struct archive_read_filter *)calloc(1, sizeof(*filter));
+ if (filter == NULL)
+ return (ARCHIVE_FATAL);
+ filter->bidder = best_bidder;
+ filter->archive = a;
+ filter->upstream = a->filter;
+ a->filter = filter;
+ r = (best_bidder->init)(a->filter);
+ if (r != ARCHIVE_OK) {
+ close_filters(a);
+ free_filters(a);
+ return (ARCHIVE_FATAL);
+ }
+ }
+}
+
+/*
+ * Read header of next entry.
+ */
+static int
+_archive_read_next_header2(struct archive *_a, struct archive_entry *entry)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ int r1 = ARCHIVE_OK, r2;
+
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
+ "archive_read_next_header");
+
+ archive_entry_clear(entry);
+ archive_clear_error(&a->archive);
+
+ /*
+ * If client didn't consume entire data, skip any remainder
+ * (This is especially important for GNU incremental directories.)
+ */
+ if (a->archive.state == ARCHIVE_STATE_DATA) {
+ r1 = archive_read_data_skip(&a->archive);
+ if (r1 == ARCHIVE_EOF)
+ archive_set_error(&a->archive, EIO,
+ "Premature end-of-file.");
+ if (r1 == ARCHIVE_EOF || r1 == ARCHIVE_FATAL) {
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ /* Record start-of-header offset in uncompressed stream. */
+ a->header_position = a->filter->position;
+
+ ++_a->file_count;
+ r2 = (a->format->read_header)(a, entry);
+
+ /*
+ * EOF and FATAL are persistent at this layer. By
+ * modifying the state, we guarantee that future calls to
+ * read a header or read data will fail.
+ */
+ switch (r2) {
+ case ARCHIVE_EOF:
+ a->archive.state = ARCHIVE_STATE_EOF;
+ --_a->file_count;/* Revert a file counter. */
+ break;
+ case ARCHIVE_OK:
+ a->archive.state = ARCHIVE_STATE_DATA;
+ break;
+ case ARCHIVE_WARN:
+ a->archive.state = ARCHIVE_STATE_DATA;
+ break;
+ case ARCHIVE_RETRY:
+ break;
+ case ARCHIVE_FATAL:
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ break;
+ }
+
+ a->read_data_output_offset = 0;
+ a->read_data_remaining = 0;
+ /* EOF always wins; otherwise return the worst error. */
+ return (r2 < r1 || r2 == ARCHIVE_EOF) ? r2 : r1;
+}
+
+int
+_archive_read_next_header(struct archive *_a, struct archive_entry **entryp)
+{
+ int ret;
+ struct archive_read *a = (struct archive_read *)_a;
+ *entryp = NULL;
+ ret = _archive_read_next_header2(_a, a->entry);
+ *entryp = a->entry;
+ return ret;
+}
+
+/*
+ * Allow each registered format to bid on whether it wants to handle
+ * the next entry. Return index of winning bidder.
+ */
+static int
+choose_format(struct archive_read *a)
+{
+ int slots;
+ int i;
+ int bid, best_bid;
+ int best_bid_slot;
+
+ slots = sizeof(a->formats) / sizeof(a->formats[0]);
+ best_bid = -1;
+ best_bid_slot = -1;
+
+ /* Set up a->format for convenience of bidders. */
+ a->format = &(a->formats[0]);
+ for (i = 0; i < slots; i++, a->format++) {
+ if (a->format->bid) {
+ bid = (a->format->bid)(a, best_bid);
+ if (bid == ARCHIVE_FATAL)
+ return (ARCHIVE_FATAL);
+ if (a->filter->position != 0)
+ __archive_read_seek(a, 0, SEEK_SET);
+ if ((bid > best_bid) || (best_bid_slot < 0)) {
+ best_bid = bid;
+ best_bid_slot = i;
+ }
+ }
+ }
+
+ /*
+ * There were no bidders; this is a serious programmer error
+ * and demands a quick and definitive abort.
+ */
+ if (best_bid_slot < 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "No formats registered");
+ return (ARCHIVE_FATAL);
+ }
+
+ /*
+ * There were bidders, but no non-zero bids; this means we
+ * can't support this stream.
+ */
+ if (best_bid < 1) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Unrecognized archive format");
+ return (ARCHIVE_FATAL);
+ }
+
+ return (best_bid_slot);
+}
+
+/*
+ * Return the file offset (within the uncompressed data stream) where
+ * the last header started.
+ */
+int64_t
+archive_read_header_position(struct archive *_a)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_header_position");
+ return (a->header_position);
+}
+
+/*
+ * 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
+ * buffer, filling any gaps with zero bytes. Clients using this
+ * API can be completely ignorant of sparse-file issues; sparse files
+ * will simply be padded with nulls.
+ *
+ * DO NOT intermingle calls to this function and archive_read_data_block
+ * to read a single entry body.
+ */
+ssize_t
+archive_read_data(struct archive *_a, void *buff, size_t s)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ char *dest;
+ const void *read_buf;
+ size_t bytes_read;
+ size_t len;
+ int r;
+
+ bytes_read = 0;
+ dest = (char *)buff;
+
+ while (s > 0) {
+ if (a->read_data_remaining == 0) {
+ read_buf = a->read_data_block;
+ r = _archive_read_data_block(&a->archive, &read_buf,
+ &a->read_data_remaining, &a->read_data_offset);
+ a->read_data_block = read_buf;
+ if (r == ARCHIVE_EOF)
+ return (bytes_read);
+ /*
+ * Error codes are all negative, so the status
+ * return here cannot be confused with a valid
+ * byte count. (ARCHIVE_OK is zero.)
+ */
+ if (r < ARCHIVE_OK)
+ return (r);
+ }
+
+ if (a->read_data_offset < a->read_data_output_offset) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Encountered out-of-order sparse blocks");
+ return (ARCHIVE_RETRY);
+ }
+
+ /* Compute the amount of zero padding needed. */
+ if (a->read_data_output_offset + s <
+ a->read_data_offset) {
+ len = s;
+ } else if (a->read_data_output_offset <
+ a->read_data_offset) {
+ len = a->read_data_offset -
+ a->read_data_output_offset;
+ } else
+ len = 0;
+
+ /* Add zeroes. */
+ memset(dest, 0, len);
+ s -= len;
+ a->read_data_output_offset += len;
+ dest += len;
+ bytes_read += len;
+
+ /* Copy data if there is any space left. */
+ if (s > 0) {
+ len = a->read_data_remaining;
+ if (len > s)
+ len = s;
+ memcpy(dest, a->read_data_block, len);
+ s -= len;
+ a->read_data_block += len;
+ a->read_data_remaining -= len;
+ a->read_data_output_offset += len;
+ a->read_data_offset += len;
+ dest += len;
+ bytes_read += len;
+ }
+ }
+ return (bytes_read);
+}
+
+/*
+ * Skip over all remaining data in this entry.
+ */
+int
+archive_read_data_skip(struct archive *_a)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ int r;
+ const void *buff;
+ size_t size;
+ int64_t offset;
+
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_DATA,
+ "archive_read_data_skip");
+
+ if (a->format->read_data_skip != NULL)
+ r = (a->format->read_data_skip)(a);
+ else {
+ while ((r = archive_read_data_block(&a->archive,
+ &buff, &size, &offset))
+ == ARCHIVE_OK)
+ ;
+ }
+
+ if (r == ARCHIVE_EOF)
+ r = ARCHIVE_OK;
+
+ a->archive.state = ARCHIVE_STATE_HEADER;
+ return (r);
+}
+
+/*
+ * Read the next block of entry data from the archive.
+ * This is a zero-copy interface; the client receives a pointer,
+ * size, and file offset of the next available block of data.
+ *
+ * Returns ARCHIVE_OK if the operation is successful, ARCHIVE_EOF if
+ * the end of entry is encountered.
+ */
+static int
+_archive_read_data_block(struct archive *_a,
+ const void **buff, size_t *size, int64_t *offset)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_DATA,
+ "archive_read_data_block");
+
+ if (a->format->read_data == NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
+ "Internal error: "
+ "No format_read_data_block function registered");
+ return (ARCHIVE_FATAL);
+ }
+
+ return (a->format->read_data)(a, buff, size, offset);
+}
+
+static int
+close_filters(struct archive_read *a)
+{
+ struct archive_read_filter *f = a->filter;
+ int r = ARCHIVE_OK;
+ /* Close each filter in the pipeline. */
+ while (f != NULL) {
+ struct archive_read_filter *t = f->upstream;
+ if (!f->closed && f->close != NULL) {
+ int r1 = (f->close)(f);
+ f->closed = 1;
+ if (r1 < r)
+ r = r1;
+ }
+ free(f->buffer);
+ f->buffer = NULL;
+ f = t;
+ }
+ return r;
+}
+
+static void
+free_filters(struct archive_read *a)
+{
+ while (a->filter != NULL) {
+ struct archive_read_filter *t = a->filter->upstream;
+ free(a->filter);
+ a->filter = t;
+ }
+}
+
+/*
+ * return the count of # of filters in use
+ */
+static int
+_archive_filter_count(struct archive *_a)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ struct archive_read_filter *p = a->filter;
+ int count = 0;
+ while(p) {
+ count++;
+ p = p->upstream;
+ }
+ return count;
+}
+
+/*
+ * Close the file and all I/O.
+ */
+static int
+_archive_read_close(struct archive *_a)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ int r = ARCHIVE_OK, r1 = ARCHIVE_OK;
+
+ archive_check_magic(&a->archive, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_close");
+ if (a->archive.state == ARCHIVE_STATE_CLOSED)
+ return (ARCHIVE_OK);
+ archive_clear_error(&a->archive);
+ a->archive.state = ARCHIVE_STATE_CLOSED;
+
+ /* TODO: Clean up the formatters. */
+
+ /* Release the filter objects. */
+ r1 = close_filters(a);
+ if (r1 < r)
+ r = r1;
+
+ return (r);
+}
+
+/*
+ * Release memory and other resources.
+ */
+static int
+_archive_read_free(struct archive *_a)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ int i, n;
+ int slots;
+ int r = ARCHIVE_OK;
+
+ if (_a == NULL)
+ return (ARCHIVE_OK);
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_free");
+ if (a->archive.state != ARCHIVE_STATE_CLOSED
+ && a->archive.state != ARCHIVE_STATE_FATAL)
+ r = archive_read_close(&a->archive);
+
+ /* Call cleanup functions registered by optional components. */
+ if (a->cleanup_archive_extract != NULL)
+ r = (a->cleanup_archive_extract)(a);
+
+ /* Cleanup format-specific data. */
+ slots = sizeof(a->formats) / sizeof(a->formats[0]);
+ for (i = 0; i < slots; i++) {
+ a->format = &(a->formats[i]);
+ if (a->formats[i].cleanup)
+ (a->formats[i].cleanup)(a);
+ }
+
+ /* Free the filters */
+ free_filters(a);
+
+ /* Release the bidder objects. */
+ n = sizeof(a->bidders)/sizeof(a->bidders[0]);
+ for (i = 0; i < n; i++) {
+ if (a->bidders[i].free != NULL) {
+ int r1 = (a->bidders[i].free)(&a->bidders[i]);
+ if (r1 < r)
+ r = r1;
+ }
+ }
+
+ archive_string_free(&a->archive.error_string);
+ if (a->entry)
+ archive_entry_free(a->entry);
+ a->archive.magic = 0;
+ __archive_clean(&a->archive);
+ free(a);
+ return (r);
+}
+
+static struct archive_read_filter *
+get_filter(struct archive *_a, int n)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ struct archive_read_filter *f = a->filter;
+ /* We use n == -1 for 'the last filter', which is always the client proxy. */
+ if (n == -1 && f != NULL) {
+ struct archive_read_filter *last = f;
+ f = f->upstream;
+ while (f != NULL) {
+ last = f;
+ f = f->upstream;
+ }
+ return (last);
+ }
+ if (n < 0)
+ return NULL;
+ while (n > 0 && f != NULL) {
+ f = f->upstream;
+ --n;
+ }
+ return (f);
+}
+
+static int
+_archive_filter_code(struct archive *_a, int n)
+{
+ struct archive_read_filter *f = get_filter(_a, n);
+ return f == NULL ? -1 : f->code;
+}
+
+static const char *
+_archive_filter_name(struct archive *_a, int n)
+{
+ struct archive_read_filter *f = get_filter(_a, n);
+ return f != NULL ? f->name : NULL;
+}
+
+static int64_t
+_archive_filter_bytes(struct archive *_a, int n)
+{
+ struct archive_read_filter *f = get_filter(_a, n);
+ return f == NULL ? -1 : f->position;
+}
+
+/*
+ * Used internally by read format handlers to register their bid and
+ * initialization functions.
+ */
+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 *),
+ int (*cleanup)(struct archive_read *))
+{
+ int i, number_slots;
+
+ archive_check_magic(&a->archive,
+ ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
+ "__archive_read_register_format");
+
+ number_slots = sizeof(a->formats) / sizeof(a->formats[0]);
+
+ for (i = 0; i < number_slots; i++) {
+ if (a->formats[i].bid == bid)
+ return (ARCHIVE_WARN); /* We've already installed */
+ if (a->formats[i].bid == NULL) {
+ a->formats[i].bid = bid;
+ a->formats[i].options = options;
+ a->formats[i].read_header = read_header;
+ a->formats[i].read_data = read_data;
+ a->formats[i].read_data_skip = read_data_skip;
+ a->formats[i].cleanup = cleanup;
+ a->formats[i].data = format_data;
+ a->formats[i].name = name;
+ return (ARCHIVE_OK);
+ }
+ }
+
+ archive_set_error(&a->archive, ENOMEM,
+ "Not enough slots for format registration");
+ return (ARCHIVE_FATAL);
+}
+
+/*
+ * Used internally by decompression routines to register their bid and
+ * initialization functions.
+ */
+int
+__archive_read_get_bidder(struct archive_read *a,
+ struct archive_read_filter_bidder **bidder)
+{
+ int i, number_slots;
+
+ number_slots = sizeof(a->bidders) / sizeof(a->bidders[0]);
+
+ for (i = 0; i < number_slots; i++) {
+ if (a->bidders[i].bid == NULL) {
+ memset(a->bidders + i, 0, sizeof(a->bidders[0]));
+ *bidder = (a->bidders + i);
+ return (ARCHIVE_OK);
+ }
+ }
+
+ archive_set_error(&a->archive, ENOMEM,
+ "Not enough slots for filter registration");
+ return (ARCHIVE_FATAL);
+}
+
+/*
+ * The next section implements the peek/consume internal I/O
+ * system used by archive readers. This system allows simple
+ * read-ahead for consumers while preserving zero-copy operation
+ * most of the time.
+ *
+ * The two key operations:
+ * * The read-ahead function returns a pointer to a block of data
+ * that satisfies a minimum request.
+ * * The consume function advances the file pointer.
+ *
+ * In the ideal case, filters generate blocks of data
+ * and __archive_read_ahead() just returns pointers directly into
+ * those blocks. Then __archive_read_consume() just bumps those
+ * pointers. Only if your request would span blocks does the I/O
+ * layer use a copy buffer to provide you with a contiguous block of
+ * data.
+ *
+ * A couple of useful idioms:
+ * * "I just want some data." Ask for 1 byte and pay attention to
+ * the "number of bytes available" from __archive_read_ahead().
+ * Consume whatever you actually use.
+ * * "I want to output a large block of data." As above, ask for 1 byte,
+ * emit all that's available (up to whatever limit you have), consume
+ * it all, then repeat until you're done. This effectively means that
+ * you're passing along the blocks that came from your provider.
+ * * "I want to peek ahead by a large amount." Ask for 4k or so, then
+ * double and repeat until you get an error or have enough. Note
+ * that the I/O layer will likely end up expanding its copy buffer
+ * to fit your request, so use this technique cautiously. This
+ * technique is used, for example, by some of the format tasting
+ * code that has uncertain look-ahead needs.
+ */
+
+/*
+ * Looks ahead in the input stream:
+ * * If 'avail' pointer is provided, that returns number of bytes available
+ * in the current buffer, which may be much larger than requested.
+ * * If end-of-file, *avail gets set to zero.
+ * * If error, *avail gets error code.
+ * * If request can be met, returns pointer to data.
+ * * If minimum request cannot be met, returns NULL.
+ *
+ * Note: If you just want "some data", ask for 1 byte and pay attention
+ * to *avail, which will have the actual amount available. If you
+ * know exactly how many bytes you need, just ask for that and treat
+ * a NULL return as an error.
+ *
+ * Important: This does NOT move the file pointer. See
+ * __archive_read_consume() below.
+ */
+const void *
+__archive_read_ahead(struct archive_read *a, size_t min, ssize_t *avail)
+{
+ return (__archive_read_filter_ahead(a->filter, min, avail));
+}
+
+const void *
+__archive_read_filter_ahead(struct archive_read_filter *filter,
+ size_t min, ssize_t *avail)
+{
+ ssize_t bytes_read;
+ size_t tocopy;
+
+ if (filter->fatal) {
+ if (avail)
+ *avail = ARCHIVE_FATAL;
+ return (NULL);
+ }
+
+ /*
+ * Keep pulling more data until we can satisfy the request.
+ */
+ for (;;) {
+
+ /*
+ * If we can satisfy from the copy buffer (and the
+ * copy buffer isn't empty), we're done. In particular,
+ * note that min == 0 is a perfectly well-defined
+ * request.
+ */
+ if (filter->avail >= min && filter->avail > 0) {
+ if (avail != NULL)
+ *avail = filter->avail;
+ return (filter->next);
+ }
+
+ /*
+ * We can satisfy directly from client buffer if everything
+ * currently in the copy buffer is still in the client buffer.
+ */
+ if (filter->client_total >= filter->client_avail + filter->avail
+ && filter->client_avail + filter->avail >= min) {
+ /* "Roll back" to client buffer. */
+ filter->client_avail += filter->avail;
+ filter->client_next -= filter->avail;
+ /* Copy buffer is now empty. */
+ filter->avail = 0;
+ filter->next = filter->buffer;
+ /* Return data from client buffer. */
+ if (avail != NULL)
+ *avail = filter->client_avail;
+ return (filter->client_next);
+ }
+
+ /* Move data forward in copy buffer if necessary. */
+ if (filter->next > filter->buffer &&
+ filter->next + min > filter->buffer + filter->buffer_size) {
+ if (filter->avail > 0)
+ memmove(filter->buffer, filter->next, filter->avail);
+ filter->next = filter->buffer;
+ }
+
+ /* If we've used up the client data, get more. */
+ if (filter->client_avail <= 0) {
+ if (filter->end_of_file) {
+ if (avail != NULL)
+ *avail = 0;
+ return (NULL);
+ }
+ bytes_read = (filter->read)(filter,
+ &filter->client_buff);
+ if (bytes_read < 0) { /* Read error. */
+ filter->client_total = filter->client_avail = 0;
+ filter->client_next = filter->client_buff = NULL;
+ filter->fatal = 1;
+ if (avail != NULL)
+ *avail = ARCHIVE_FATAL;
+ return (NULL);
+ }
+ if (bytes_read == 0) { /* Premature end-of-file. */
+ filter->client_total = filter->client_avail = 0;
+ filter->client_next = filter->client_buff = NULL;
+ filter->end_of_file = 1;
+ /* Return whatever we do have. */
+ if (avail != NULL)
+ *avail = filter->avail;
+ return (NULL);
+ }
+ filter->client_total = bytes_read;
+ filter->client_avail = filter->client_total;
+ filter->client_next = filter->client_buff;
+ }
+ else
+ {
+ /*
+ * We can't satisfy the request from the copy
+ * buffer or the existing client data, so we
+ * need to copy more client data over to the
+ * copy buffer.
+ */
+
+ /* Ensure the buffer is big enough. */
+ if (min > filter->buffer_size) {
+ size_t s, t;
+ char *p;
+
+ /* Double the buffer; watch for overflow. */
+ s = t = filter->buffer_size;
+ if (s == 0)
+ s = min;
+ while (s < min) {
+ t *= 2;
+ if (t <= s) { /* Integer overflow! */
+ archive_set_error(
+ &filter->archive->archive,
+ ENOMEM,
+ "Unable to allocate copy buffer");
+ filter->fatal = 1;
+ if (avail != NULL)
+ *avail = ARCHIVE_FATAL;
+ return (NULL);
+ }
+ s = t;
+ }
+ /* Now s >= min, so allocate a new buffer. */
+ p = (char *)malloc(s);
+ if (p == NULL) {
+ archive_set_error(
+ &filter->archive->archive,
+ ENOMEM,
+ "Unable to allocate copy buffer");
+ filter->fatal = 1;
+ if (avail != NULL)
+ *avail = ARCHIVE_FATAL;
+ return (NULL);
+ }
+ /* Move data into newly-enlarged buffer. */
+ if (filter->avail > 0)
+ memmove(p, filter->next, filter->avail);
+ free(filter->buffer);
+ filter->next = filter->buffer = p;
+ filter->buffer_size = s;
+ }
+
+ /* We can add client data to copy buffer. */
+ /* First estimate: copy to fill rest of buffer. */
+ tocopy = (filter->buffer + filter->buffer_size)
+ - (filter->next + filter->avail);
+ /* Don't waste time buffering more than we need to. */
+ if (tocopy + filter->avail > min)
+ tocopy = min - filter->avail;
+ /* Don't copy more than is available. */
+ if (tocopy > filter->client_avail)
+ tocopy = filter->client_avail;
+
+ memcpy(filter->next + filter->avail, filter->client_next,
+ tocopy);
+ /* Remove this data from client buffer. */
+ filter->client_next += tocopy;
+ filter->client_avail -= tocopy;
+ /* add it to copy buffer. */
+ filter->avail += tocopy;
+ }
+ }
+}
+
+/*
+ * Move the file pointer forward.
+ */
+int64_t
+__archive_read_consume(struct archive_read *a, int64_t request)
+{
+ return (__archive_read_filter_consume(a->filter, request));
+}
+
+int64_t
+__archive_read_filter_consume(struct archive_read_filter * filter,
+ int64_t request)
+{
+ int64_t skipped;
+
+ if (request == 0)
+ return 0;
+
+ skipped = advance_file_pointer(filter, request);
+ if (skipped == request)
+ return (skipped);
+ /* We hit EOF before we satisfied the skip request. */
+ if (skipped < 0) /* Map error code to 0 for error message below. */
+ skipped = 0;
+ archive_set_error(&filter->archive->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Truncated input file (needed %jd bytes, only %jd available)",
+ (intmax_t)request, (intmax_t)skipped);
+ return (ARCHIVE_FATAL);
+}
+
+/*
+ * Advance the file pointer by the amount requested.
+ * Returns the amount actually advanced, which may be less than the
+ * request if EOF is encountered first.
+ * Returns a negative value if there's an I/O error.
+ */
+static int64_t
+advance_file_pointer(struct archive_read_filter *filter, int64_t request)
+{
+ int64_t bytes_skipped, total_bytes_skipped = 0;
+ ssize_t bytes_read;
+ size_t min;
+
+ if (filter->fatal)
+ return (-1);
+
+ /* Use up the copy buffer first. */
+ if (filter->avail > 0) {
+ min = minimum(request, (int64_t)filter->avail);
+ filter->next += min;
+ filter->avail -= min;
+ request -= min;
+ filter->position += min;
+ total_bytes_skipped += min;
+ }
+
+ /* Then use up the client buffer. */
+ if (filter->client_avail > 0) {
+ min = minimum(request, (int64_t)filter->client_avail);
+ filter->client_next += min;
+ filter->client_avail -= min;
+ request -= min;
+ filter->position += min;
+ total_bytes_skipped += min;
+ }
+ if (request == 0)
+ return (total_bytes_skipped);
+
+ /* If there's an optimized skip function, use it. */
+ if (filter->skip != NULL) {
+ bytes_skipped = (filter->skip)(filter, request);
+ if (bytes_skipped < 0) { /* error */
+ filter->fatal = 1;
+ return (bytes_skipped);
+ }
+ filter->position += bytes_skipped;
+ total_bytes_skipped += bytes_skipped;
+ request -= bytes_skipped;
+ if (request == 0)
+ return (total_bytes_skipped);
+ }
+
+ /* Use ordinary reads as necessary to complete the request. */
+ for (;;) {
+ bytes_read = (filter->read)(filter, &filter->client_buff);
+ if (bytes_read < 0) {
+ filter->client_buff = NULL;
+ filter->fatal = 1;
+ return (bytes_read);
+ }
+
+ if (bytes_read == 0) {
+ filter->client_buff = NULL;
+ filter->end_of_file = 1;
+ return (total_bytes_skipped);
+ }
+
+ if (bytes_read >= request) {
+ filter->client_next =
+ ((const char *)filter->client_buff) + request;
+ filter->client_avail = bytes_read - request;
+ filter->client_total = bytes_read;
+ total_bytes_skipped += request;
+ filter->position += request;
+ return (total_bytes_skipped);
+ }
+
+ filter->position += bytes_read;
+ total_bytes_skipped += bytes_read;
+ request -= bytes_read;
+ }
+}
+
+/**
+ * Returns ARCHIVE_FAILED if seeking isn't supported.
+ */
+int64_t
+__archive_read_seek(struct archive_read *a, int64_t offset, int whence)
+{
+ return __archive_read_filter_seek(a->filter, offset, whence);
+}
+
+int64_t
+__archive_read_filter_seek(struct archive_read_filter *filter, int64_t offset, int whence)
+{
+ int64_t r;
+
+ if (filter->closed || filter->fatal)
+ return (ARCHIVE_FATAL);
+ if (filter->seek == NULL)
+ return (ARCHIVE_FAILED);
+ r = filter->seek(filter, offset, whence);
+ if (r >= 0) {
+ /*
+ * Ouch. Clearing the buffer like this hurts, especially
+ * at bid time. A lot of our efficiency at bid time comes
+ * from having bidders reuse the data we've already read.
+ *
+ * TODO: If the seek request is in data we already
+ * have, then don't call the seek callback.
+ *
+ * TODO: Zip seeks to end-of-file at bid time. If
+ * other formats also start doing this, we may need to
+ * find a way for clients to fudge the seek offset to
+ * a block boundary.
+ *
+ * Hmmm... If whence was SEEK_END, we know the file
+ * size is (r - offset). Can we use that to simplify
+ * the TODO items above?
+ */
+ filter->avail = filter->client_avail = 0;
+ filter->next = filter->buffer;
+ filter->position = r;
+ filter->end_of_file = 0;
+ }
+ return r;
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_data.3 b/Utilities/cmlibarchive/libarchive/archive_read_data.3
new file mode 100644
index 000000000..78d049782
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_data.3
@@ -0,0 +1,128 @@
+.\" Copyright (c) 2003-2011 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 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 March 22, 2011
+.Dt ARCHIVE_READ_DATA 3
+.Os
+.Sh NAME
+.Nm archive_read_data
+.Nm archive_read_data_block ,
+.Nm archive_read_data_skip ,
+.Nm archive_read_data_into_fd
+.Nd functions for reading streaming archives
+.Sh SYNOPSIS
+.In archive.h
+.Ft ssize_t
+.Fn archive_read_data "struct archive *" "void *buff" "size_t len"
+.Ft int
+.Fo archive_read_data_block
+.Fa "struct archive *"
+.Fa "const void **buff"
+.Fa "size_t *len"
+.Fa "off_t *offset"
+.Fc
+.Ft int
+.Fn archive_read_data_skip "struct archive *"
+.Ft int
+.Fn archive_read_data_into_fd "struct archive *" "int fd"
+.\"
+.Sh DESCRIPTION
+.Bl -tag -compact -width indent
+.It Fn archive_read_data
+Read data associated with the header just read.
+Internally, this is a convenience function that calls
+.Fn archive_read_data_block
+and fills any gaps with nulls so that callers see a single
+continuous stream of data.
+.It Fn archive_read_data_block
+Return the next available block of data for this entry.
+Unlike
+.Fn archive_read_data ,
+the
+.Fn archive_read_data_block
+function avoids copying data and allows you to correctly handle
+sparse files, as supported by some archive formats.
+The library guarantees that offsets will increase and that blocks
+will not overlap.
+Note that the blocks returned from this function can be much larger
+than the block size read from disk, due to compression
+and internal buffer optimizations.
+.It Fn archive_read_data_skip
+A convenience function that repeatedly calls
+.Fn archive_read_data_block
+to skip all of the data for this archive entry.
+Note that this function is invoked automatically by
+.Fn archive_read_next_header2
+if the previous entry was not completely consumed.
+.It Fn archive_read_data_into_fd
+A convenience function that repeatedly calls
+.Fn archive_read_data_block
+to copy the entire entry to the provided file descriptor.
+.El
+.\"
+.Sh RETURN VALUES
+Most functions return zero on success, non-zero on error.
+The possible return codes include:
+.Cm ARCHIVE_OK
+(the operation succeeded),
+.Cm ARCHIVE_WARN
+(the operation succeeded but a non-critical error was encountered),
+.Cm ARCHIVE_EOF
+(end-of-archive was encountered),
+.Cm ARCHIVE_RETRY
+(the operation failed but can be retried),
+and
+.Cm ARCHIVE_FATAL
+(there was a fatal error; the archive should be closed immediately).
+.Pp
+.Fn archive_read_data
+returns a count of bytes actually read or zero at the end of the entry.
+On error, a value of
+.Cm ARCHIVE_FATAL ,
+.Cm ARCHIVE_WARN ,
+or
+.Cm ARCHIVE_RETRY
+is returned.
+.\"
+.Sh ERRORS
+Detailed error codes and textual descriptions are available from the
+.Fn archive_errno
+and
+.Fn archive_error_string
+functions.
+.\"
+.Sh SEE ALSO
+.Xr tar 1 ,
+.Xr libarchive 3 ,
+.Xr archive_read 3 ,
+.Xr archive_read_extract 3 ,
+.Xr archive_read_filter 3 ,
+.Xr archive_read_format 3 ,
+.Xr archive_read_header 3 ,
+.Xr archive_read_open 3 ,
+.Xr archive_read_set_options 3 ,
+.Xr archive_util 3 ,
+.Xr tar 5
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_data_into_fd.c b/Utilities/cmlibarchive/libarchive/archive_read_data_into_fd.c
new file mode 100644
index 000000000..14f941070
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_data_into_fd.c
@@ -0,0 +1,139 @@
+/*-
+ * 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_data_into_fd.c,v 1.16 2008/05/23 05:01:29 cperciva Exp $");
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "archive.h"
+#include "archive_private.h"
+
+/* Maximum amount of data to write at one time. */
+#define MAX_WRITE (1024 * 1024)
+
+/*
+ * This implementation minimizes copying of data and is sparse-file aware.
+ */
+static int
+pad_to(struct archive *a, int fd, int can_lseek,
+ size_t nulls_size, const char *nulls,
+ int64_t target_offset, int64_t actual_offset)
+{
+ size_t to_write;
+ ssize_t bytes_written;
+
+ if (can_lseek) {
+ actual_offset = lseek(fd,
+ target_offset - actual_offset, SEEK_CUR);
+ if (actual_offset != target_offset) {
+ archive_set_error(a, errno, "Seek error");
+ return (ARCHIVE_FATAL);
+ }
+ return (ARCHIVE_OK);
+ }
+ while (target_offset > actual_offset) {
+ to_write = nulls_size;
+ if (target_offset < actual_offset + nulls_size)
+ to_write = (size_t)(target_offset - actual_offset);
+ bytes_written = write(fd, nulls, to_write);
+ if (bytes_written < 0) {
+ archive_set_error(a, errno, "Write error");
+ return (ARCHIVE_FATAL);
+ }
+ actual_offset += bytes_written;
+ }
+ return (ARCHIVE_OK);
+}
+
+
+int
+archive_read_data_into_fd(struct archive *a, int fd)
+{
+ struct stat st;
+ int r, r2;
+ const void *buff;
+ size_t size, bytes_to_write;
+ ssize_t bytes_written;
+ int64_t target_offset;
+ int64_t actual_offset = 0;
+ int can_lseek;
+ char *nulls = NULL;
+ size_t nulls_size = 16384;
+
+ archive_check_magic(a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_DATA,
+ "archive_read_data_into_fd");
+
+ can_lseek = (fstat(fd, &st) == 0) && S_ISREG(st.st_mode);
+ if (!can_lseek)
+ nulls = calloc(1, nulls_size);
+
+ while ((r = archive_read_data_block(a, &buff, &size, &target_offset)) ==
+ ARCHIVE_OK) {
+ const char *p = buff;
+ if (target_offset > actual_offset) {
+ r = pad_to(a, fd, can_lseek, nulls_size, nulls,
+ target_offset, actual_offset);
+ if (r != ARCHIVE_OK)
+ break;
+ actual_offset = target_offset;
+ }
+ while (size > 0) {
+ bytes_to_write = size;
+ if (bytes_to_write > MAX_WRITE)
+ bytes_to_write = MAX_WRITE;
+ bytes_written = write(fd, p, bytes_to_write);
+ if (bytes_written < 0) {
+ archive_set_error(a, errno, "Write error");
+ r = ARCHIVE_FATAL;
+ goto cleanup;
+ }
+ actual_offset += bytes_written;
+ p += bytes_written;
+ size -= bytes_written;
+ }
+ }
+
+ if (r == ARCHIVE_EOF && target_offset > actual_offset) {
+ r2 = pad_to(a, fd, can_lseek, nulls_size, nulls,
+ target_offset, actual_offset);
+ if (r2 != ARCHIVE_OK)
+ r = r2;
+ }
+
+cleanup:
+ free(nulls);
+ if (r != ARCHIVE_EOF)
+ return (r);
+ return (ARCHIVE_OK);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_disk.3 b/Utilities/cmlibarchive/libarchive/archive_read_disk.3
new file mode 100644
index 000000000..3c49bffc8
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_disk.3
@@ -0,0 +1,315 @@
+.\" Copyright (c) 2003-2009 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 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: head/lib/libarchive/archive_read_disk.3 190957 2009-04-12 05:04:02Z kientzle $
+.\"
+.Dd March 10, 2009
+.Dt ARCHIVE_READ_DISK 3
+.Os
+.Sh NAME
+.Nm archive_read_disk_new ,
+.Nm archive_read_disk_set_symlink_logical ,
+.Nm archive_read_disk_set_symlink_physical ,
+.Nm archive_read_disk_set_symlink_hybrid ,
+.Nm archive_read_disk_entry_from_file ,
+.Nm archive_read_disk_gname ,
+.Nm archive_read_disk_uname ,
+.Nm archive_read_disk_set_uname_lookup ,
+.Nm archive_read_disk_set_gname_lookup ,
+.Nm archive_read_disk_set_standard_lookup ,
+.Nm archive_read_close ,
+.Nm archive_read_finish ,
+.Nm archive_read_free
+.Nd functions for reading objects from disk
+.Sh SYNOPSIS
+.In archive.h
+.Ft struct archive *
+.Fn archive_read_disk_new "void"
+.Ft int
+.Fn archive_read_disk_set_symlink_logical "struct archive *"
+.Ft int
+.Fn archive_read_disk_set_symlink_physical "struct archive *"
+.Ft int
+.Fn archive_read_disk_set_symlink_hybrid "struct archive *"
+.Ft int
+.Fn archive_read_disk_gname "struct archive *" "gid_t"
+.Ft int
+.Fn archive_read_disk_uname "struct archive *" "uid_t"
+.Ft int
+.Fo archive_read_disk_set_gname_lookup
+.Fa "struct archive *"
+.Fa "void *"
+.Fa "const char *(*lookup)(void *, gid_t)"
+.Fa "void (*cleanup)(void *)"
+.Fc
+.Ft int
+.Fo archive_read_disk_set_uname_lookup
+.Fa "struct archive *"
+.Fa "void *"
+.Fa "const char *(*lookup)(void *, uid_t)"
+.Fa "void (*cleanup)(void *)"
+.Fc
+.Ft int
+.Fn archive_read_disk_set_standard_lookup "struct archive *"
+.Ft int
+.Fo archive_read_disk_entry_from_file
+.Fa "struct archive *"
+.Fa "struct archive_entry *"
+.Fa "int fd"
+.Fa "const struct stat *"
+.Fc
+.Ft int
+.Fn archive_read_close "struct archive *"
+.Ft int
+.Fn archive_read_finish "struct archive *"
+.Ft int
+.Fn archive_read_free "struct archive *"
+.Sh DESCRIPTION
+These functions provide an API for reading information about
+objects on disk.
+In particular, they provide an interface for populating
+.Tn struct archive_entry
+objects.
+.Bl -tag -width indent
+.It Fn archive_read_disk_new
+Allocates and initializes a
+.Tn struct archive
+object suitable for reading object information from disk.
+.It Xo
+.Fn archive_read_disk_set_symlink_logical ,
+.Fn archive_read_disk_set_symlink_physical ,
+.Fn archive_read_disk_set_symlink_hybrid
+.Xc
+This sets the mode used for handling symbolic links.
+The
+.Dq logical
+mode follows all symbolic links.
+The
+.Dq physical
+mode does not follow any symbolic links.
+The
+.Dq hybrid
+mode currently behaves identically to the
+.Dq logical
+mode.
+.It Xo
+.Fn archive_read_disk_gname ,
+.Fn archive_read_disk_uname
+.Xc
+Returns a user or group name given a gid or uid value.
+By default, these always return a NULL string.
+.It Xo
+.Fn archive_read_disk_set_gname_lookup ,
+.Fn archive_read_disk_set_uname_lookup
+.Xc
+These allow you to override the functions used for
+user and group name lookups.
+You may also provide a
+.Tn void *
+pointer to a private data structure and a cleanup function for
+that data.
+The cleanup function will be invoked when the
+.Tn struct archive
+object is destroyed or when new lookup functions are registered.
+.It Fn archive_read_disk_set_standard_lookup
+This convenience function installs a standard set of user
+and group name lookup functions.
+These functions use
+.Xr getpwuid 3
+and
+.Xr getgrgid 3
+to convert ids to names, defaulting to NULL if the names cannot
+be looked up.
+These functions also implement a simple memory cache to reduce
+the number of calls to
+.Xr getpwuid 3
+and
+.Xr getgrgid 3 .
+.It Fn archive_read_disk_entry_from_file
+Populates a
+.Tn struct archive_entry
+object with information about a particular file.
+The
+.Tn archive_entry
+object must have already been created with
+.Xr archive_entry_new 3
+and at least one of the source path or path fields must already be set.
+(If both are set, the source path will be used.)
+.Pp
+Information is read from disk using the path name from the
+.Tn struct archive_entry
+object.
+If a file descriptor is provided, some information will be obtained using
+that file descriptor, on platforms that support the appropriate
+system calls.
+.Pp
+If a pointer to a
+.Tn struct stat
+is provided, information from that structure will be used instead
+of reading from the disk where appropriate.
+This can provide performance benefits in scenarios where
+.Tn struct stat
+information has already been read from the disk as a side effect
+of some other operation.
+(For example, directory traversal libraries often provide this information.)
+.Pp
+Where necessary, user and group ids are converted to user and group names
+using the currently registered lookup functions above.
+This affects the file ownership fields and ACL values in the
+.Tn struct archive_entry
+object.
+.It Fn archive_read_close
+Does nothing for
+.Tn archive_read_disk
+handles.
+.It Fn archive_read_finish
+This is a deprecated synonym for
+.Fn archive_read_free .
+.It Fn archive_read_free
+Invokes
+.Fn archive_read_close
+if it was not invoked manually, then releases all resources.
+.El
+More information about the
+.Va struct archive
+object and the overall design of the library can be found in the
+.Xr libarchive 3
+overview.
+.Sh EXAMPLE
+The following illustrates basic usage of the library by
+showing how to use it to copy an item on disk into an archive.
+.Bd -literal -offset indent
+void
+file_to_archive(struct archive *a, const char *name)
+{
+ char buff[8192];
+ size_t bytes_read;
+ struct archive *ard;
+ struct archive_entry *entry;
+ int fd;
+
+ ard = archive_read_disk_new();
+ archive_read_disk_set_standard_lookup(ard);
+ entry = archive_entry_new();
+ fd = open(name, O_RDONLY);
+ if (fd < 0)
+ return;
+ archive_entry_copy_pathname(entry, name);
+ archive_read_disk_entry_from_file(ard, entry, fd, NULL);
+ archive_write_header(a, entry);
+ while ((bytes_read = read(fd, buff, sizeof(buff))) > 0)
+ archive_write_data(a, buff, bytes_read);
+ archive_write_finish_entry(a);
+ archive_read_free(ard);
+ archive_entry_free(entry);
+}
+.Ed
+.Sh RETURN VALUES
+Most functions return
+.Cm ARCHIVE_OK
+(zero) on success, or one of several negative
+error codes for errors.
+Specific error codes include:
+.Cm ARCHIVE_RETRY
+for operations that might succeed if retried,
+.Cm ARCHIVE_WARN
+for unusual conditions that do not prevent further operations, and
+.Cm ARCHIVE_FATAL
+for serious errors that make remaining operations impossible.
+.Pp
+.Fn archive_read_disk_new
+returns a pointer to a newly-allocated
+.Tn struct archive
+object or NULL if the allocation failed for any reason.
+.Pp
+.Fn archive_read_disk_gname
+and
+.Fn archive_read_disk_uname
+return
+.Tn const char *
+pointers to the textual name or NULL if the lookup failed for any reason.
+The returned pointer points to internal storage that
+may be reused on the next call to either of these functions;
+callers should copy the string if they need to continue accessing it.
+.\"
+.Sh ERRORS
+Detailed error codes and textual descriptions are available from the
+.Fn archive_errno
+and
+.Fn archive_error_string
+functions.
+.\"
+.Sh SEE ALSO
+.Xr archive_read 3 ,
+.Xr archive_util 3 ,
+.Xr archive_write 3 ,
+.Xr archive_write_disk 3 ,
+.Xr tar 1 ,
+.Xr libarchive 3
+.Sh HISTORY
+The
+.Nm libarchive
+library first appeared in
+.Fx 5.3 .
+The
+.Nm archive_read_disk
+interface was added to
+.Nm libarchive 2.6
+and first appeared in
+.Fx 8.0 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm libarchive
+library was written by
+.An Tim Kientzle Aq kientzle@FreeBSD.org .
+.Sh BUGS
+The
+.Dq standard
+user name and group name lookup functions are not the defaults because
+.Xr getgrgid 3
+and
+.Xr getpwuid 3
+are sometimes too large for particular applications.
+The current design allows the application author to use a more
+compact implementation when appropriate.
+.Pp
+The full list of metadata read from disk by
+.Fn archive_read_disk_entry_from_file
+is necessarily system-dependent.
+.Pp
+The
+.Fn archive_read_disk_entry_from_file
+function reads as much information as it can from disk.
+Some method should be provided to limit this so that clients who
+do not need ACLs, for instance, can avoid the extra work needed
+to look up such information.
+.Pp
+This API should provide a set of methods for walking a directory tree.
+That would make it a direct parallel of the
+.Xr archive_read 3
+API.
+When such methods are implemented, the
+.Dq hybrid
+symbolic link mode will make sense.
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_disk_entry_from_file.c b/Utilities/cmlibarchive/libarchive/archive_read_disk_entry_from_file.c
new file mode 100644
index 000000000..fdeb5166d
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_disk_entry_from_file.c
@@ -0,0 +1,1008 @@
+/*-
+ * Copyright (c) 2003-2009 Tim Kientzle
+ * Copyright (c) 2010 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: head/lib/libarchive/archive_read_disk_entry_from_file.c 201084 2009-12-28 02:14:09Z kientzle $");
+
+/* This is the tree-walking code for POSIX systems. */
+#if !defined(_WIN32) || defined(__CYGWIN__)
+
+#ifdef HAVE_SYS_TYPES_H
+/* Mac OSX requires sys/types.h before sys/acl.h. */
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_ACL_H
+#include <sys/acl.h>
+#endif
+#ifdef HAVE_SYS_EXTATTR_H
+#include <sys/extattr.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_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_XATTR_H
+#include <sys/xattr.h>
+#endif
+#ifdef HAVE_SYS_EA_H
+#include <sys/ea.h>
+#endif
+#ifdef HAVE_ACL_LIBACL_H
+#include <acl/libacl.h>
+#endif
+#ifdef HAVE_ATTR_XATTR_H
+#include <attr/xattr.h>
+#endif
+#ifdef HAVE_COPYFILE_H
+#include <copyfile.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifdef HAVE_LINUX_TYPES_H
+#include <linux/types.h>
+#endif
+#ifdef HAVE_LINUX_FIEMAP_H
+#include <linux/fiemap.h>
+#endif
+#ifdef HAVE_LINUX_FS_H
+#include <linux/fs.h>
+#endif
+/*
+ * Some Linux distributions have both linux/ext2_fs.h and ext2fs/ext2_fs.h.
+ * As the include guards don't agree, the order of include is important.
+ */
+#ifdef HAVE_LINUX_EXT2_FS_H
+#include <linux/ext2_fs.h> /* for Linux file flags */
+#endif
+#if defined(HAVE_EXT2FS_EXT2_FS_H) && !defined(__CYGWIN__)
+#include <ext2fs/ext2_fs.h> /* Linux file flags, broken on Cygwin */
+#endif
+#ifdef HAVE_PATHS_H
+#include <paths.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "archive.h"
+#include "archive_entry.h"
+#include "archive_private.h"
+#include "archive_read_disk_private.h"
+
+/*
+ * Linux and FreeBSD plug this obvious hole in POSIX.1e in
+ * different ways.
+ */
+#if HAVE_ACL_GET_PERM
+#define ACL_GET_PERM acl_get_perm
+#elif HAVE_ACL_GET_PERM_NP
+#define ACL_GET_PERM acl_get_perm_np
+#endif
+
+static int setup_acls_posix1e(struct archive_read_disk *,
+ struct archive_entry *, int fd);
+static int setup_mac_metadata(struct archive_read_disk *,
+ struct archive_entry *, int fd);
+static int setup_xattrs(struct archive_read_disk *,
+ struct archive_entry *, int fd);
+static int setup_sparse(struct archive_read_disk *,
+ struct archive_entry *, int fd);
+
+int
+archive_read_disk_entry_from_file(struct archive *_a,
+ struct archive_entry *entry,
+ int fd,
+ const struct stat *st)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ const char *path, *name;
+ struct stat s;
+ int initial_fd = fd;
+ int r, r1;
+
+ archive_clear_error(_a);
+ path = archive_entry_sourcepath(entry);
+ if (path == NULL)
+ path = archive_entry_pathname(entry);
+
+ if (a->tree == NULL) {
+ if (st == NULL) {
+#if HAVE_FSTAT
+ if (fd >= 0) {
+ if (fstat(fd, &s) != 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't fstat");
+ return (ARCHIVE_FAILED);
+ }
+ } else
+#endif
+#if HAVE_LSTAT
+ if (!a->follow_symlinks) {
+ if (lstat(path, &s) != 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't lstat %s", path);
+ return (ARCHIVE_FAILED);
+ }
+ } else
+#endif
+ if (stat(path, &s) != 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't stat %s", path);
+ return (ARCHIVE_FAILED);
+ }
+ st = &s;
+ }
+ archive_entry_copy_stat(entry, st);
+ }
+
+ /* Lookup uname/gname */
+ name = archive_read_disk_uname(_a, archive_entry_uid(entry));
+ if (name != NULL)
+ archive_entry_copy_uname(entry, name);
+ name = archive_read_disk_gname(_a, archive_entry_gid(entry));
+ if (name != NULL)
+ archive_entry_copy_gname(entry, name);
+
+#ifdef HAVE_STRUCT_STAT_ST_FLAGS
+ /* On FreeBSD, we get flags for free with the stat. */
+ /* TODO: Does this belong in copy_stat()? */
+ if (st->st_flags != 0)
+ archive_entry_set_fflags(entry, st->st_flags, 0);
+#endif
+
+#if defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)
+ /* Linux requires an extra ioctl to pull the flags. Although
+ * this is an extra step, it has a nice side-effect: We get an
+ * open file descriptor which we can use in the subsequent lookups. */
+ if ((S_ISREG(st->st_mode) || S_ISDIR(st->st_mode))) {
+ if (fd < 0)
+ fd = open(path, O_RDONLY | O_NONBLOCK);
+ if (fd >= 0) {
+ unsigned long stflags;
+ int r = ioctl(fd, EXT2_IOC_GETFLAGS, &stflags);
+ if (r == 0 && stflags != 0)
+ archive_entry_set_fflags(entry, stflags, 0);
+ }
+ }
+#endif
+
+#if defined(HAVE_READLINK) || defined(HAVE_READLINKAT)
+ if (S_ISLNK(st->st_mode)) {
+ size_t linkbuffer_len = st->st_size + 1;
+ char *linkbuffer;
+ int lnklen;
+
+ linkbuffer = malloc(linkbuffer_len);
+ if (linkbuffer == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Couldn't read link data");
+ return (ARCHIVE_FAILED);
+ }
+#ifdef HAVE_READLINKAT
+ if (a->entry_wd_fd >= 0)
+ lnklen = readlinkat(a->entry_wd_fd, path,
+ linkbuffer, linkbuffer_len);
+ else
+#endif /* HAVE_READLINKAT */
+ lnklen = readlink(path, linkbuffer, linkbuffer_len);
+ if (lnklen < 0) {
+ archive_set_error(&a->archive, errno,
+ "Couldn't read link data");
+ free(linkbuffer);
+ return (ARCHIVE_FAILED);
+ }
+ linkbuffer[lnklen] = 0;
+ archive_entry_set_symlink(entry, linkbuffer);
+ free(linkbuffer);
+ }
+#endif /* HAVE_READLINK || HAVE_READLINKAT */
+
+ r = setup_acls_posix1e(a, entry, fd);
+ r1 = setup_xattrs(a, entry, fd);
+ if (r1 < r)
+ r = r1;
+ r1 = setup_mac_metadata(a, entry, fd);
+ if (r1 < r)
+ r = r1;
+ r1 = setup_sparse(a, entry, fd);
+ if (r1 < r)
+ r = r1;
+
+ /* If we opened the file earlier in this function, close it. */
+ if (initial_fd != fd)
+ close(fd);
+ return (r);
+}
+
+#if defined(__APPLE__) && defined(HAVE_COPYFILE_H)
+/*
+ * The Mac OS "copyfile()" API copies the extended metadata for a
+ * file into a separate file in AppleDouble format (see RFC 1740).
+ *
+ * Mac OS tar and cpio implementations store this extended
+ * metadata as a separate entry just before the regular entry
+ * with a "._" prefix added to the filename.
+ *
+ * Note that this is currently done unconditionally; the tar program has
+ * an option to discard this information before the archive is written.
+ *
+ * TODO: If there's a failure, report it and return ARCHIVE_WARN.
+ */
+static int
+setup_mac_metadata(struct archive_read_disk *a,
+ struct archive_entry *entry, int fd)
+{
+ int tempfd = -1;
+ int copyfile_flags = COPYFILE_NOFOLLOW | COPYFILE_ACL | COPYFILE_XATTR;
+ struct stat copyfile_stat;
+ int ret = ARCHIVE_OK;
+ void *buff;
+ int have_attrs;
+ const char *name, *tempdir, *tempfile = NULL;
+
+ name = archive_entry_sourcepath(entry);
+ if (name == NULL)
+ name = archive_entry_pathname(entry);
+ if (name == NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Can't open file to read extended attributes: No name");
+ return (ARCHIVE_WARN);
+ }
+
+ /* Short-circuit if there's nothing to do. */
+ have_attrs = copyfile(name, NULL, 0, copyfile_flags | COPYFILE_CHECK);
+ if (have_attrs == -1) {
+ archive_set_error(&a->archive, errno,
+ "Could not check extended attributes");
+ return (ARCHIVE_WARN);
+ }
+ if (have_attrs == 0)
+ return (ARCHIVE_OK);
+
+ tempdir = NULL;
+ if (issetugid() == 0)
+ tempdir = getenv("TMPDIR");
+ if (tempdir == NULL)
+ tempdir = _PATH_TMP;
+ tempfile = tempnam(tempdir, "tar.md.");
+
+ /* XXX I wish copyfile() could pack directly to a memory
+ * buffer; that would avoid the temp file here. For that
+ * matter, it would be nice if fcopyfile() actually worked,
+ * that would reduce the many open/close races here. */
+ if (copyfile(name, tempfile, 0, copyfile_flags | COPYFILE_PACK)) {
+ archive_set_error(&a->archive, errno,
+ "Could not pack extended attributes");
+ ret = ARCHIVE_WARN;
+ goto cleanup;
+ }
+ tempfd = open(tempfile, O_RDONLY);
+ if (tempfd < 0) {
+ archive_set_error(&a->archive, errno,
+ "Could not open extended attribute file");
+ ret = ARCHIVE_WARN;
+ goto cleanup;
+ }
+ if (fstat(tempfd, &copyfile_stat)) {
+ archive_set_error(&a->archive, errno,
+ "Could not check size of extended attributes");
+ ret = ARCHIVE_WARN;
+ goto cleanup;
+ }
+ buff = malloc(copyfile_stat.st_size);
+ if (buff == NULL) {
+ archive_set_error(&a->archive, errno,
+ "Could not allocate memory for extended attributes");
+ ret = ARCHIVE_WARN;
+ goto cleanup;
+ }
+ if (copyfile_stat.st_size != read(tempfd, buff, copyfile_stat.st_size)) {
+ archive_set_error(&a->archive, errno,
+ "Could not read extended attributes into memory");
+ ret = ARCHIVE_WARN;
+ goto cleanup;
+ }
+ archive_entry_copy_mac_metadata(entry, buff, copyfile_stat.st_size);
+
+cleanup:
+ if (tempfd >= 0)
+ close(tempfd);
+ if (tempfile != NULL)
+ unlink(tempfile);
+ return (ret);
+}
+
+#else
+
+/*
+ * Stub implementation for non-Mac systems.
+ */
+static int
+setup_mac_metadata(struct archive_read_disk *a,
+ struct archive_entry *entry, int fd)
+{
+ (void)a; /* UNUSED */
+ (void)entry; /* UNUSED */
+ (void)fd; /* UNUSED */
+ return (ARCHIVE_OK);
+}
+#endif
+
+
+#ifdef HAVE_POSIX_ACL
+static void setup_acl_posix1e(struct archive_read_disk *a,
+ struct archive_entry *entry, acl_t acl, int archive_entry_acl_type);
+
+static int
+setup_acls_posix1e(struct archive_read_disk *a,
+ struct archive_entry *entry, int fd)
+{
+ const char *accpath;
+ acl_t acl;
+
+ accpath = archive_entry_sourcepath(entry);
+ if (accpath == NULL)
+ accpath = archive_entry_pathname(entry);
+
+ archive_entry_acl_clear(entry);
+
+ /* Retrieve access ACL from file. */
+ if (fd >= 0)
+ acl = acl_get_fd(fd);
+#if HAVE_ACL_GET_LINK_NP
+ else if (!a->follow_symlinks)
+ acl = acl_get_link_np(accpath, ACL_TYPE_ACCESS);
+#else
+ else if ((!a->follow_symlinks)
+ && (archive_entry_filetype(entry) == AE_IFLNK))
+ /* We can't get the ACL of a symlink, so we assume it can't
+ have one. */
+ acl = NULL;
+#endif
+ else
+ acl = acl_get_file(accpath, ACL_TYPE_ACCESS);
+ if (acl != NULL) {
+ setup_acl_posix1e(a, entry, acl,
+ ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
+ acl_free(acl);
+ }
+
+ /* Only directories can have default ACLs. */
+ if (S_ISDIR(archive_entry_mode(entry))) {
+ acl = acl_get_file(accpath, ACL_TYPE_DEFAULT);
+ if (acl != NULL) {
+ setup_acl_posix1e(a, entry, acl,
+ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT);
+ acl_free(acl);
+ }
+ }
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Translate POSIX.1e ACL into libarchive internal structure.
+ */
+static void
+setup_acl_posix1e(struct archive_read_disk *a,
+ struct archive_entry *entry, acl_t acl, int archive_entry_acl_type)
+{
+ acl_tag_t acl_tag;
+ acl_entry_t acl_entry;
+ acl_permset_t acl_permset;
+ int s, ae_id, ae_tag, ae_perm;
+ const char *ae_name;
+
+ s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry);
+ while (s == 1) {
+ ae_id = -1;
+ ae_name = NULL;
+
+ acl_get_tag_type(acl_entry, &acl_tag);
+ if (acl_tag == ACL_USER) {
+ ae_id = (int)*(uid_t *)acl_get_qualifier(acl_entry);
+ ae_name = archive_read_disk_uname(&a->archive, ae_id);
+ ae_tag = ARCHIVE_ENTRY_ACL_USER;
+ } else if (acl_tag == ACL_GROUP) {
+ ae_id = (int)*(gid_t *)acl_get_qualifier(acl_entry);
+ ae_name = archive_read_disk_gname(&a->archive, ae_id);
+ ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
+ } else if (acl_tag == ACL_MASK) {
+ ae_tag = ARCHIVE_ENTRY_ACL_MASK;
+ } else if (acl_tag == ACL_USER_OBJ) {
+ ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
+ } else if (acl_tag == ACL_GROUP_OBJ) {
+ ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
+ } else if (acl_tag == ACL_OTHER) {
+ ae_tag = ARCHIVE_ENTRY_ACL_OTHER;
+ } else {
+ /* Skip types that libarchive can't support. */
+ continue;
+ }
+
+ acl_get_permset(acl_entry, &acl_permset);
+ ae_perm = 0;
+ /*
+ * acl_get_perm() is spelled differently on different
+ * platforms; see above.
+ */
+ if (ACL_GET_PERM(acl_permset, ACL_EXECUTE))
+ ae_perm |= ARCHIVE_ENTRY_ACL_EXECUTE;
+ if (ACL_GET_PERM(acl_permset, ACL_READ))
+ ae_perm |= ARCHIVE_ENTRY_ACL_READ;
+ if (ACL_GET_PERM(acl_permset, ACL_WRITE))
+ ae_perm |= ARCHIVE_ENTRY_ACL_WRITE;
+
+ archive_entry_acl_add_entry(entry,
+ archive_entry_acl_type, ae_perm, ae_tag,
+ ae_id, ae_name);
+
+ s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
+ }
+}
+#else
+static int
+setup_acls_posix1e(struct archive_read_disk *a,
+ struct archive_entry *entry, int fd)
+{
+ (void)a; /* UNUSED */
+ (void)entry; /* UNUSED */
+ (void)fd; /* UNUSED */
+ return (ARCHIVE_OK);
+}
+#endif
+
+#if (HAVE_FGETXATTR && HAVE_FLISTXATTR && HAVE_LISTXATTR && \
+ HAVE_LLISTXATTR && HAVE_GETXATTR && HAVE_LGETXATTR) || \
+ (HAVE_FGETEA && HAVE_FLISTEA && HAVE_LISTEA)
+
+/*
+ * Linux and AIX extended attribute support.
+ *
+ * TODO: By using a stack-allocated buffer for the first
+ * call to getxattr(), we might be able to avoid the second
+ * call entirely. We only need the second call if the
+ * stack-allocated buffer is too small. But a modest buffer
+ * of 1024 bytes or so will often be big enough. Same applies
+ * to listxattr().
+ */
+
+
+static int
+setup_xattr(struct archive_read_disk *a,
+ struct archive_entry *entry, const char *name, int fd)
+{
+ ssize_t size;
+ void *value = NULL;
+ const char *accpath;
+
+ accpath = archive_entry_sourcepath(entry);
+ if (accpath == NULL)
+ accpath = archive_entry_pathname(entry);
+
+#if HAVE_FGETXATTR
+ if (fd >= 0)
+ size = fgetxattr(fd, name, NULL, 0);
+ else if (!a->follow_symlinks)
+ size = lgetxattr(accpath, name, NULL, 0);
+ else
+ size = getxattr(accpath, name, NULL, 0);
+#elif HAVE_FGETEA
+ if (fd >= 0)
+ size = fgetea(fd, name, NULL, 0);
+ else if (!a->follow_symlinks)
+ size = lgetea(accpath, name, NULL, 0);
+ else
+ size = getea(accpath, name, NULL, 0);
+#endif
+
+ if (size == -1) {
+ archive_set_error(&a->archive, errno,
+ "Couldn't query extended attribute");
+ return (ARCHIVE_WARN);
+ }
+
+ if (size > 0 && (value = malloc(size)) == NULL) {
+ archive_set_error(&a->archive, errno, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
+
+#if HAVE_FGETXATTR
+ if (fd >= 0)
+ size = fgetxattr(fd, name, value, size);
+ else if (!a->follow_symlinks)
+ size = lgetxattr(accpath, name, value, size);
+ else
+ size = getxattr(accpath, name, value, size);
+#elif HAVE_FGETEA
+ if (fd >= 0)
+ size = fgetea(fd, name, value, size);
+ else if (!a->follow_symlinks)
+ size = lgetea(accpath, name, value, size);
+ else
+ size = getea(accpath, name, value, size);
+#endif
+
+ if (size == -1) {
+ archive_set_error(&a->archive, errno,
+ "Couldn't read extended attribute");
+ return (ARCHIVE_WARN);
+ }
+
+ archive_entry_xattr_add_entry(entry, name, value, size);
+
+ free(value);
+ return (ARCHIVE_OK);
+}
+
+static int
+setup_xattrs(struct archive_read_disk *a,
+ struct archive_entry *entry, int fd)
+{
+ char *list, *p;
+ const char *path;
+ ssize_t list_size;
+
+ path = archive_entry_sourcepath(entry);
+ if (path == NULL)
+ path = archive_entry_pathname(entry);
+
+#if HAVE_FLISTXATTR
+ if (fd >= 0)
+ list_size = flistxattr(fd, NULL, 0);
+ else if (!a->follow_symlinks)
+ list_size = llistxattr(path, NULL, 0);
+ else
+ list_size = listxattr(path, NULL, 0);
+#elif HAVE_FLISTEA
+ if (fd >= 0)
+ list_size = flistea(fd, NULL, 0);
+ else if (!a->follow_symlinks)
+ list_size = llistea(path, NULL, 0);
+ else
+ list_size = listea(path, NULL, 0);
+#endif
+
+ if (list_size == -1) {
+ if (errno == ENOTSUP || errno == ENOSYS)
+ return (ARCHIVE_OK);
+ archive_set_error(&a->archive, errno,
+ "Couldn't list extended attributes");
+ return (ARCHIVE_WARN);
+ }
+
+ if (list_size == 0)
+ return (ARCHIVE_OK);
+
+ if ((list = malloc(list_size)) == NULL) {
+ archive_set_error(&a->archive, errno, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
+
+#if HAVE_FLISTXATTR
+ if (fd >= 0)
+ list_size = flistxattr(fd, list, list_size);
+ else if (!a->follow_symlinks)
+ list_size = llistxattr(path, list, list_size);
+ else
+ list_size = listxattr(path, list, list_size);
+#elif HAVE_FLISTEA
+ if (fd >= 0)
+ list_size = flistea(fd, list, list_size);
+ else if (!a->follow_symlinks)
+ list_size = llistea(path, list, list_size);
+ else
+ list_size = listea(path, list, list_size);
+#endif
+
+ if (list_size == -1) {
+ archive_set_error(&a->archive, errno,
+ "Couldn't retrieve extended attributes");
+ free(list);
+ return (ARCHIVE_WARN);
+ }
+
+ for (p = list; (p - list) < list_size; p += strlen(p) + 1) {
+ if (strncmp(p, "system.", 7) == 0 ||
+ strncmp(p, "xfsroot.", 8) == 0)
+ continue;
+ setup_xattr(a, entry, p, fd);
+ }
+
+ free(list);
+ return (ARCHIVE_OK);
+}
+
+#elif HAVE_EXTATTR_GET_FILE && HAVE_EXTATTR_LIST_FILE && \
+ HAVE_DECL_EXTATTR_NAMESPACE_USER
+
+/*
+ * FreeBSD extattr interface.
+ */
+
+/* TODO: Implement this. Follow the Linux model above, but
+ * with FreeBSD-specific system calls, of course. Be careful
+ * to not include the system extattrs that hold ACLs; we handle
+ * those separately.
+ */
+static int
+setup_xattr(struct archive_read_disk *a, struct archive_entry *entry,
+ int namespace, const char *name, const char *fullname, int fd);
+
+static int
+setup_xattr(struct archive_read_disk *a, struct archive_entry *entry,
+ int namespace, const char *name, const char *fullname, int fd)
+{
+ ssize_t size;
+ void *value = NULL;
+ const char *accpath;
+
+ accpath = archive_entry_sourcepath(entry);
+ if (accpath == NULL)
+ accpath = archive_entry_pathname(entry);
+
+ if (fd >= 0)
+ size = extattr_get_fd(fd, namespace, name, NULL, 0);
+ else if (!a->follow_symlinks)
+ size = extattr_get_link(accpath, namespace, name, NULL, 0);
+ else
+ size = extattr_get_file(accpath, namespace, name, NULL, 0);
+
+ if (size == -1) {
+ archive_set_error(&a->archive, errno,
+ "Couldn't query extended attribute");
+ return (ARCHIVE_WARN);
+ }
+
+ if (size > 0 && (value = malloc(size)) == NULL) {
+ archive_set_error(&a->archive, errno, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
+
+ if (fd >= 0)
+ size = extattr_get_fd(fd, namespace, name, value, size);
+ else if (!a->follow_symlinks)
+ size = extattr_get_link(accpath, namespace, name, value, size);
+ else
+ size = extattr_get_file(accpath, namespace, name, value, size);
+
+ if (size == -1) {
+ archive_set_error(&a->archive, errno,
+ "Couldn't read extended attribute");
+ return (ARCHIVE_WARN);
+ }
+
+ archive_entry_xattr_add_entry(entry, fullname, value, size);
+
+ free(value);
+ return (ARCHIVE_OK);
+}
+
+static int
+setup_xattrs(struct archive_read_disk *a,
+ struct archive_entry *entry, int fd)
+{
+ char buff[512];
+ char *list, *p;
+ ssize_t list_size;
+ const char *path;
+ int namespace = EXTATTR_NAMESPACE_USER;
+
+ path = archive_entry_sourcepath(entry);
+ if (path == NULL)
+ path = archive_entry_pathname(entry);
+
+ if (fd >= 0)
+ list_size = extattr_list_fd(fd, namespace, NULL, 0);
+ else if (!a->follow_symlinks)
+ list_size = extattr_list_link(path, namespace, NULL, 0);
+ else
+ list_size = extattr_list_file(path, namespace, NULL, 0);
+
+ if (list_size == -1 && errno == EOPNOTSUPP)
+ return (ARCHIVE_OK);
+ if (list_size == -1) {
+ archive_set_error(&a->archive, errno,
+ "Couldn't list extended attributes");
+ return (ARCHIVE_WARN);
+ }
+
+ if (list_size == 0)
+ return (ARCHIVE_OK);
+
+ if ((list = malloc(list_size)) == NULL) {
+ archive_set_error(&a->archive, errno, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
+
+ if (fd >= 0)
+ list_size = extattr_list_fd(fd, namespace, list, list_size);
+ else if (!a->follow_symlinks)
+ list_size = extattr_list_link(path, namespace, list, list_size);
+ else
+ list_size = extattr_list_file(path, namespace, list, list_size);
+
+ if (list_size == -1) {
+ archive_set_error(&a->archive, errno,
+ "Couldn't retrieve extended attributes");
+ free(list);
+ return (ARCHIVE_WARN);
+ }
+
+ p = list;
+ while ((p - list) < list_size) {
+ size_t len = 255 & (int)*p;
+ char *name;
+
+ strcpy(buff, "user.");
+ name = buff + strlen(buff);
+ memcpy(name, p + 1, len);
+ name[len] = '\0';
+ setup_xattr(a, entry, namespace, name, buff, fd);
+ p += 1 + len;
+ }
+
+ free(list);
+ return (ARCHIVE_OK);
+}
+
+#else
+
+/*
+ * Generic (stub) extended attribute support.
+ */
+static int
+setup_xattrs(struct archive_read_disk *a,
+ struct archive_entry *entry, int fd)
+{
+ (void)a; /* UNUSED */
+ (void)entry; /* UNUSED */
+ (void)fd; /* UNUSED */
+ return (ARCHIVE_OK);
+}
+
+#endif
+
+#if defined(HAVE_LINUX_FIEMAP_H)
+
+/*
+ * Linux sparse interface.
+ *
+ * The FIEMAP ioctl returns an "extent" for each physical allocation
+ * on disk. We need to process those to generate a more compact list
+ * of logical file blocks. We also need to be very careful to use
+ * FIEMAP_FLAG_SYNC here, since there are reports that Linux sometimes
+ * does not report allocations for newly-written data that hasn't
+ * been synced to disk.
+ *
+ * It's important to return a minimal sparse file list because we want
+ * to not trigger sparse file extensions if we don't have to, since
+ * not all readers support them.
+ */
+
+static int
+setup_sparse(struct archive_read_disk *a,
+ struct archive_entry *entry, int fd)
+{
+ char buff[4096];
+ struct fiemap *fm;
+ struct fiemap_extent *fe;
+ int64_t size;
+ int count, do_fiemap;
+ int initial_fd = fd;
+ int exit_sts = ARCHIVE_OK;
+
+ if (archive_entry_filetype(entry) != AE_IFREG
+ || archive_entry_size(entry) <= 0
+ || archive_entry_hardlink(entry) != NULL)
+ return (ARCHIVE_OK);
+
+ if (fd < 0) {
+ const char *path;
+
+ path = archive_entry_sourcepath(entry);
+ if (path == NULL)
+ path = archive_entry_pathname(entry);
+ fd = open(path, O_RDONLY | O_NONBLOCK);
+ if (fd < 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't open `%s'", path);
+ return (ARCHIVE_FAILED);
+ }
+ }
+
+ count = (sizeof(buff) - sizeof(*fm))/sizeof(*fe);
+ fm = (struct fiemap *)buff;
+ fm->fm_start = 0;
+ fm->fm_length = ~0ULL;;
+ fm->fm_flags = FIEMAP_FLAG_SYNC;
+ fm->fm_extent_count = count;
+ do_fiemap = 1;
+ size = archive_entry_size(entry);
+ for (;;) {
+ int i, r;
+
+ r = ioctl(fd, FS_IOC_FIEMAP, fm);
+ if (r < 0) {
+ /* When errno is ENOTTY, it is better we should
+ * return ARCHIVE_OK because an earlier version
+ *(<2.6.28) cannot perfom FS_IOC_FIEMAP.
+ * We should also check if errno is EOPNOTSUPP,
+ * it means "Operation not supported". */
+ if (errno != ENOTTY && errno != EOPNOTSUPP) {
+ archive_set_error(&a->archive, errno,
+ "FIEMAP failed");
+ exit_sts = ARCHIVE_FAILED;
+ }
+ goto exit_setup_sparse;
+ }
+ if (fm->fm_mapped_extents == 0)
+ break;
+ fe = fm->fm_extents;
+ for (i = 0; i < fm->fm_mapped_extents; i++, fe++) {
+ if (!(fe->fe_flags & FIEMAP_EXTENT_UNWRITTEN)) {
+ /* The fe_length of the last block does not
+ * adjust itself to its size files. */
+ int64_t length = fe->fe_length;
+ if (fe->fe_logical + length > size)
+ length -= fe->fe_logical + length - size;
+ if (fe->fe_logical == 0 && length == size) {
+ /* This is not sparse. */
+ do_fiemap = 0;
+ break;
+ }
+ if (length > 0)
+ archive_entry_sparse_add_entry(entry,
+ fe->fe_logical, length);
+ }
+ if (fe->fe_flags & FIEMAP_EXTENT_LAST)
+ do_fiemap = 0;
+ }
+ if (do_fiemap) {
+ fe = fm->fm_extents + fm->fm_mapped_extents -1;
+ fm->fm_start = fe->fe_logical + fe->fe_length;
+ } else
+ break;
+ }
+exit_setup_sparse:
+ if (initial_fd != fd)
+ close(fd);
+ return (exit_sts);
+}
+
+#elif defined(SEEK_HOLE) && defined(SEEK_DATA) && defined(_PC_MIN_HOLE_SIZE)
+
+/*
+ * FreeBSD and Solaris sparse interface.
+ */
+
+static int
+setup_sparse(struct archive_read_disk *a,
+ struct archive_entry *entry, int fd)
+{
+ int64_t size;
+ int initial_fd = fd;
+ off_t initial_off; /* FreeBSD/Solaris only, so off_t okay here */
+ off_t off_s, off_e; /* FreeBSD/Solaris only, so off_t okay here */
+ int exit_sts = ARCHIVE_OK;
+
+ if (archive_entry_filetype(entry) != AE_IFREG
+ || archive_entry_size(entry) <= 0
+ || archive_entry_hardlink(entry) != NULL)
+ return (ARCHIVE_OK);
+
+ /* Does filesystem support the reporting of hole ? */
+ if (fd >= 0) {
+ if (fpathconf(fd, _PC_MIN_HOLE_SIZE) <= 0)
+ return (ARCHIVE_OK);
+ initial_off = lseek(fd, 0, SEEK_CUR);
+ if (initial_off != 0)
+ lseek(fd, 0, SEEK_SET);
+ } else {
+ const char *path;
+
+ path = archive_entry_sourcepath(entry);
+ if (path == NULL)
+ path = archive_entry_pathname(entry);
+ if (pathconf(path, _PC_MIN_HOLE_SIZE) <= 0)
+ return (ARCHIVE_OK);
+ fd = open(path, O_RDONLY | O_NONBLOCK);
+ if (fd < 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't open `%s'", path);
+ return (ARCHIVE_FAILED);
+ }
+ initial_off = 0;
+ }
+
+ off_s = 0;
+ size = archive_entry_size(entry);
+ while (off_s < size) {
+ off_s = lseek(fd, off_s, SEEK_DATA);
+ if (off_s == (off_t)-1) {
+ if (errno == ENXIO)
+ break;/* no more hole */
+ archive_set_error(&a->archive, errno,
+ "lseek(SEEK_HOLE) failed");
+ exit_sts = ARCHIVE_FAILED;
+ goto exit_setup_sparse;
+ }
+ off_e = lseek(fd, off_s, SEEK_HOLE);
+ if (off_s == (off_t)-1) {
+ if (errno == ENXIO) {
+ off_e = lseek(fd, 0, SEEK_END);
+ if (off_e != (off_t)-1)
+ break;/* no more data */
+ }
+ archive_set_error(&a->archive, errno,
+ "lseek(SEEK_DATA) failed");
+ exit_sts = ARCHIVE_FAILED;
+ goto exit_setup_sparse;
+ }
+ if (off_s == 0 && off_e == size)
+ break;/* This is not spase. */
+ archive_entry_sparse_add_entry(entry, off_s,
+ off_e - off_s);
+ off_s = off_e;
+ }
+exit_setup_sparse:
+ if (initial_fd != fd)
+ close(fd);
+ else
+ lseek(fd, initial_off, SEEK_SET);
+ return (exit_sts);
+}
+
+#else
+
+/*
+ * Generic (stub) sparse support.
+ */
+static int
+setup_sparse(struct archive_read_disk *a,
+ struct archive_entry *entry, int fd)
+{
+ (void)a; /* UNUSED */
+ (void)entry; /* UNUSED */
+ (void)fd; /* UNUSED */
+ return (ARCHIVE_OK);
+}
+
+#endif
+
+#endif /* !defined(_WIN32) || defined(__CYGWIN__) */
+
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c b/Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c
new file mode 100644
index 000000000..7d7eecadc
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c
@@ -0,0 +1,2318 @@
+/*-
+ * Copyright (c) 2003-2009 Tim Kientzle
+ * Copyright (c) 2010,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
+ * in this position and unchanged.
+ * 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.
+ */
+
+/* This is the tree-walking code for POSIX systems. */
+#if !defined(_WIN32) || defined(__CYGWIN__)
+
+#include "archive_platform.h"
+__FBSDID("$FreeBSD$");
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifdef HAVE_SYS_MOUNT_H
+#include <sys/mount.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_STATFS_H
+#include <sys/statfs.h>
+#endif
+#ifdef HAVE_SYS_STATVFS_H
+#include <sys/statvfs.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_LINUX_MAGIC_H
+#include <linux/magic.h>
+#endif
+#ifdef HAVE_DIRECT_H
+#include <direct.h>
+#endif
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "archive.h"
+#include "archive_string.h"
+#include "archive_entry.h"
+#include "archive_private.h"
+#include "archive_read_disk_private.h"
+
+#ifndef HAVE_FCHDIR
+#error fchdir function required.
+#endif
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+/*-
+ * This is a new directory-walking system that addresses a number
+ * of problems I've had with fts(3). In particular, it has no
+ * pathname-length limits (other than the size of 'int'), handles
+ * deep logical traversals, uses considerably less memory, and has
+ * an opaque interface (easier to modify in the future).
+ *
+ * Internally, it keeps a single list of "tree_entry" items that
+ * represent filesystem objects that require further attention.
+ * Non-directories are not kept in memory: they are pulled from
+ * readdir(), returned to the client, then freed as soon as possible.
+ * Any directory entry to be traversed gets pushed onto the stack.
+ *
+ * There is surprisingly little information that needs to be kept for
+ * each item on the stack. Just the name, depth (represented here as the
+ * string length of the parent directory's pathname), and some markers
+ * indicating how to get back to the parent (via chdir("..") for a
+ * regular dir or via fchdir(2) for a symlink).
+ */
+/*
+ * TODO:
+ * 1) Loop checking.
+ * 3) Arbitrary logical traversals by closing/reopening intermediate fds.
+ */
+
+struct restore_time {
+ const char *name;
+ time_t mtime;
+ long mtime_nsec;
+ time_t atime;
+ long atime_nsec;
+ mode_t filetype;
+ int noatime;
+};
+
+struct tree_entry {
+ int depth;
+ struct tree_entry *next;
+ struct tree_entry *parent;
+ struct archive_string name;
+ size_t dirname_length;
+ int64_t dev;
+ int64_t ino;
+ int flags;
+ int filesystem_id;
+ /* How to return back to the parent of a symlink. */
+ int symlink_parent_fd;
+ /* How to restore time of a directory. */
+ struct restore_time restore_time;
+};
+
+struct filesystem {
+ int64_t dev;
+ int synthetic;
+ int remote;
+ int noatime;
+#if defined(HAVE_READDIR_R)
+ size_t name_max;
+#endif
+ long incr_xfer_size;
+ long max_xfer_size;
+ long min_xfer_size;
+ long xfer_align;
+
+ /*
+ * Buffer used for reading file contents.
+ */
+ /* Exactly allocated memory pointer. */
+ unsigned char *allocation_ptr;
+ /* Pointer adjusted to the filesystem alignment . */
+ unsigned char *buff;
+ size_t buff_size;
+};
+
+/* Definitions for tree_entry.flags bitmap. */
+#define isDir 1 /* This entry is a regular directory. */
+#define isDirLink 2 /* This entry is a symbolic link to a directory. */
+#define needsFirstVisit 4 /* This is an initial entry. */
+#define needsDescent 8 /* This entry needs to be previsited. */
+#define needsOpen 16 /* This is a directory that needs to be opened. */
+#define needsAscent 32 /* This entry needs to be postvisited. */
+
+/*
+ * Local data for this package.
+ */
+struct tree {
+ struct tree_entry *stack;
+ struct tree_entry *current;
+ DIR *d;
+#define INVALID_DIR_HANDLE NULL
+ struct dirent *de;
+#if defined(HAVE_READDIR_R)
+ struct dirent *dirent;
+ size_t dirent_allocated;
+#endif
+ int flags;
+ int visit_type;
+ /* Error code from last failed operation. */
+ int tree_errno;
+
+ /* Dynamically-sized buffer for holding path */
+ struct archive_string path;
+
+ /* Last path element */
+ const char *basename;
+ /* Leading dir length */
+ size_t dirname_length;
+
+ int depth;
+ int openCount;
+ int maxOpenCount;
+ int initial_dir_fd;
+ int working_dir_fd;
+
+ struct stat lst;
+ struct stat st;
+ int descend;
+ int nlink;
+ /* How to restore time of a file. */
+ struct restore_time restore_time;
+
+ struct entry_sparse {
+ int64_t length;
+ int64_t offset;
+ } *sparse_list, *current_sparse;
+ int sparse_count;
+ int sparse_list_size;
+
+ char initial_symlink_mode;
+ char symlink_mode;
+ struct filesystem *current_filesystem;
+ struct filesystem *filesystem_table;
+ int current_filesystem_id;
+ int max_filesystem_id;
+ int allocated_filesytem;
+
+ int entry_fd;
+ int entry_eof;
+ int64_t entry_remaining_bytes;
+ int64_t entry_total;
+ unsigned char *entry_buff;
+ size_t entry_buff_size;
+};
+
+/* Definitions for tree.flags bitmap. */
+#define hasStat 16 /* The st entry is valid. */
+#define hasLstat 32 /* The lst entry is valid. */
+#define onWorkingDir 64 /* We are on the working dir where we are
+ * reading directory entry at this time. */
+#define needsRestoreTimes 128
+
+static int
+tree_dir_next_posix(struct tree *t);
+
+#ifdef HAVE_DIRENT_D_NAMLEN
+/* BSD extension; avoids need for a strlen() call. */
+#define D_NAMELEN(dp) (dp)->d_namlen
+#else
+#define D_NAMELEN(dp) (strlen((dp)->d_name))
+#endif
+
+/* Initiate/terminate a tree traversal. */
+static struct tree *tree_open(const char *, int, int);
+static struct tree *tree_reopen(struct tree *, const char *, int);
+static void tree_close(struct tree *);
+static void tree_free(struct tree *);
+static void tree_push(struct tree *, const char *, int, int64_t, int64_t,
+ struct restore_time *);
+static int tree_enter_initial_dir(struct tree *);
+static int tree_enter_working_dir(struct tree *);
+static int tree_current_dir_fd(struct tree *);
+
+/*
+ * tree_next() returns Zero if there is no next entry, non-zero if
+ * there is. Note that directories are visited three times.
+ * Directories are always visited first as part of enumerating their
+ * parent; that is a "regular" visit. If tree_descend() is invoked at
+ * that time, the directory is added to a work list and will
+ * subsequently be visited two more times: once just after descending
+ * into the directory ("postdescent") and again just after ascending
+ * back to the parent ("postascent").
+ *
+ * TREE_ERROR_DIR is returned if the descent failed (because the
+ * directory couldn't be opened, for instance). This is returned
+ * instead of TREE_POSTDESCENT/TREE_POSTASCENT. TREE_ERROR_DIR is not a
+ * fatal error, but it does imply that the relevant subtree won't be
+ * visited. TREE_ERROR_FATAL is returned for an error that left the
+ * traversal completely hosed. Right now, this is only returned for
+ * chdir() failures during ascent.
+ */
+#define TREE_REGULAR 1
+#define TREE_POSTDESCENT 2
+#define TREE_POSTASCENT 3
+#define TREE_ERROR_DIR -1
+#define TREE_ERROR_FATAL -2
+
+static int tree_next(struct tree *);
+
+/*
+ * Return information about the current entry.
+ */
+
+/*
+ * The current full pathname, length of the full pathname, and a name
+ * that can be used to access the file. Because tree does use chdir
+ * extensively, the access path is almost never the same as the full
+ * current path.
+ *
+ * TODO: On platforms that support it, use openat()-style operations
+ * to eliminate the chdir() operations entirely while still supporting
+ * arbitrarily deep traversals. This makes access_path troublesome to
+ * support, of course, which means we'll need a rich enough interface
+ * that clients can function without it. (In particular, we'll need
+ * tree_current_open() that returns an open file descriptor.)
+ *
+ */
+static const char *tree_current_path(struct tree *);
+static const char *tree_current_access_path(struct tree *);
+
+/*
+ * Request the lstat() or stat() data for the current path. Since the
+ * tree package needs to do some of this anyway, and caches the
+ * results, you should take advantage of it here if you need it rather
+ * than make a redundant stat() or lstat() call of your own.
+ */
+static const struct stat *tree_current_stat(struct tree *);
+static const struct stat *tree_current_lstat(struct tree *);
+static int tree_current_is_symblic_link_target(struct tree *);
+
+/* The following functions use tricks to avoid a certain number of
+ * stat()/lstat() calls. */
+/* "is_physical_dir" is equivalent to S_ISDIR(tree_current_lstat()->st_mode) */
+static int tree_current_is_physical_dir(struct tree *);
+/* "is_dir" is equivalent to S_ISDIR(tree_current_stat()->st_mode) */
+static int tree_current_is_dir(struct tree *);
+static int update_current_filesystem(struct archive_read_disk *a,
+ int64_t dev);
+static int setup_current_filesystem(struct archive_read_disk *);
+static int tree_target_is_same_as_parent(struct tree *, const struct stat *);
+
+static int _archive_read_disk_open(struct archive *, const char *);
+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_header2(struct archive *,
+ struct archive_entry *);
+static const char *trivial_lookup_gname(void *, int64_t gid);
+static const char *trivial_lookup_uname(void *, int64_t uid);
+static int setup_sparse(struct archive_read_disk *, struct archive_entry *);
+static int close_and_restore_time(int fd, struct tree *,
+ struct restore_time *);
+
+
+static struct archive_vtable *
+archive_read_disk_vtable(void)
+{
+ static struct archive_vtable av;
+ static int inited = 0;
+
+ if (!inited) {
+ 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_header2 = _archive_read_next_header2;
+ inited = 1;
+ }
+ return (&av);
+}
+
+const char *
+archive_read_disk_gname(struct archive *_a, int64_t gid)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_gname"))
+ return (NULL);
+ if (a->lookup_gname == NULL)
+ return (NULL);
+ return ((*a->lookup_gname)(a->lookup_gname_data, gid));
+}
+
+const char *
+archive_read_disk_uname(struct archive *_a, int64_t uid)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_uname"))
+ return (NULL);
+ if (a->lookup_uname == NULL)
+ return (NULL);
+ return ((*a->lookup_uname)(a->lookup_uname_data, uid));
+}
+
+int
+archive_read_disk_set_gname_lookup(struct archive *_a,
+ void *private_data,
+ const char * (*lookup_gname)(void *private, int64_t gid),
+ void (*cleanup_gname)(void *private))
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_set_gname_lookup");
+
+ if (a->cleanup_gname != NULL && a->lookup_gname_data != NULL)
+ (a->cleanup_gname)(a->lookup_gname_data);
+
+ a->lookup_gname = lookup_gname;
+ a->cleanup_gname = cleanup_gname;
+ a->lookup_gname_data = private_data;
+ return (ARCHIVE_OK);
+}
+
+int
+archive_read_disk_set_uname_lookup(struct archive *_a,
+ void *private_data,
+ const char * (*lookup_uname)(void *private, int64_t uid),
+ void (*cleanup_uname)(void *private))
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_set_uname_lookup");
+
+ if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL)
+ (a->cleanup_uname)(a->lookup_uname_data);
+
+ a->lookup_uname = lookup_uname;
+ a->cleanup_uname = cleanup_uname;
+ a->lookup_uname_data = private_data;
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Create a new archive_read_disk object and initialize it with global state.
+ */
+struct archive *
+archive_read_disk_new(void)
+{
+ struct archive_read_disk *a;
+
+ a = (struct archive_read_disk *)malloc(sizeof(*a));
+ if (a == NULL)
+ return (NULL);
+ memset(a, 0, sizeof(*a));
+ a->archive.magic = ARCHIVE_READ_DISK_MAGIC;
+ a->archive.state = ARCHIVE_STATE_NEW;
+ a->archive.vtable = archive_read_disk_vtable();
+ a->lookup_uname = trivial_lookup_uname;
+ a->lookup_gname = trivial_lookup_gname;
+ a->entry_wd_fd = -1;
+ return (&a->archive);
+}
+
+static int
+_archive_read_free(struct archive *_a)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ int r;
+
+ if (_a == NULL)
+ return (ARCHIVE_OK);
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_free");
+
+ if (a->archive.state != ARCHIVE_STATE_CLOSED)
+ r = _archive_read_close(&a->archive);
+ else
+ r = ARCHIVE_OK;
+
+ tree_free(a->tree);
+ if (a->cleanup_gname != NULL && a->lookup_gname_data != NULL)
+ (a->cleanup_gname)(a->lookup_gname_data);
+ if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL)
+ (a->cleanup_uname)(a->lookup_uname_data);
+ archive_string_free(&a->archive.error_string);
+ a->archive.magic = 0;
+ __archive_clean(&a->archive);
+ free(a);
+ return (r);
+}
+
+static int
+_archive_read_close(struct archive *_a)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_close");
+
+ if (a->archive.state != ARCHIVE_STATE_FATAL)
+ a->archive.state = ARCHIVE_STATE_CLOSED;
+
+ tree_close(a->tree);
+
+ return (ARCHIVE_OK);
+}
+
+static void
+setup_symlink_mode(struct archive_read_disk *a, char symlink_mode,
+ int follow_symlinks)
+{
+ a->symlink_mode = symlink_mode;
+ a->follow_symlinks = follow_symlinks;
+ if (a->tree != NULL) {
+ a->tree->initial_symlink_mode = a->symlink_mode;
+ a->tree->symlink_mode = a->symlink_mode;
+ }
+}
+
+int
+archive_read_disk_set_symlink_logical(struct archive *_a)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_logical");
+ setup_symlink_mode(a, 'L', 1);
+ return (ARCHIVE_OK);
+}
+
+int
+archive_read_disk_set_symlink_physical(struct archive *_a)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_physical");
+ setup_symlink_mode(a, 'P', 0);
+ return (ARCHIVE_OK);
+}
+
+int
+archive_read_disk_set_symlink_hybrid(struct archive *_a)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_hybrid");
+ setup_symlink_mode(a, 'H', 1);/* Follow symlinks initially. */
+ return (ARCHIVE_OK);
+}
+
+int
+archive_read_disk_set_atime_restored(struct archive *_a)
+{
+#ifndef HAVE_UTIMES
+ static int warning_done = 0;
+#endif
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_restore_atime");
+#ifdef HAVE_UTIMES
+ a->restore_time = 1;
+ if (a->tree != NULL)
+ a->tree->flags |= needsRestoreTimes;
+ return (ARCHIVE_OK);
+#else
+ if (warning_done)
+ /* Warning was already emitted; suppress further warnings. */
+ return (ARCHIVE_OK);
+
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Cannot restore access time on this system");
+ warning_done = 1;
+ return (ARCHIVE_WARN);
+#endif
+}
+
+/*
+ * Trivial implementations of gname/uname lookup functions.
+ * These are normally overridden by the client, but these stub
+ * versions ensure that we always have something that works.
+ */
+static const char *
+trivial_lookup_gname(void *private_data, int64_t gid)
+{
+ (void)private_data; /* UNUSED */
+ (void)gid; /* UNUSED */
+ return (NULL);
+}
+
+static const char *
+trivial_lookup_uname(void *private_data, int64_t uid)
+{
+ (void)private_data; /* UNUSED */
+ (void)uid; /* UNUSED */
+ return (NULL);
+}
+
+/*
+ * Allocate memory for the reading buffer adjusted to the filesystem
+ * alignment.
+ */
+static int
+setup_suitable_read_buffer(struct archive_read_disk *a)
+{
+ struct tree *t = a->tree;
+ struct filesystem *cf = t->current_filesystem;
+ size_t asize;
+ size_t s;
+
+ if (cf->allocation_ptr == NULL) {
+ /* If we couldn't get a filesystem alignment,
+ * we use 4096 as default value but we won't use
+ * O_DIRECT to open() and openat() operations. */
+ long xfer_align = (cf->xfer_align == -1)?4096:cf->xfer_align;
+
+ if (cf->max_xfer_size != -1)
+ asize = cf->max_xfer_size + xfer_align;
+ else {
+ long incr = cf->incr_xfer_size;
+ /* Some platform does not set a proper value to
+ * incr_xfer_size.*/
+ if (incr < 0)
+ incr = cf->min_xfer_size;
+ if (cf->min_xfer_size < 0) {
+ incr = xfer_align;
+ asize = xfer_align;
+ } else
+ asize = cf->min_xfer_size;
+
+ /* Increase a buffer size up to 64K bytes in
+ * a proper incremant size. */
+ while (asize < 1024*64)
+ asize += incr;
+ /* Take a margin to adjust to the filesystem
+ * alignment. */
+ asize += xfer_align;
+ }
+ cf->allocation_ptr = malloc(asize);
+ if (cf->allocation_ptr == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Couldn't allocate memory");
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ return (ARCHIVE_FATAL);
+ }
+
+ /*
+ * Calculate proper address for the filesystem.
+ */
+ s = (uintptr_t)cf->allocation_ptr;
+ s %= xfer_align;
+ if (s > 0)
+ s = xfer_align - s;
+
+ /*
+ * Set a read buffer pointer in the proper alignment of
+ * the current filesystem.
+ */
+ cf->buff = cf->allocation_ptr + s;
+ cf->buff_size = asize - xfer_align;
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+_archive_read_data_block(struct archive *_a, const void **buff,
+ size_t *size, int64_t *offset)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ struct tree *t = a->tree;
+ int r;
+ ssize_t bytes;
+ size_t buffbytes;
+
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
+ "archive_read_data_block");
+
+ if (t->entry_eof || t->entry_remaining_bytes <= 0) {
+ r = ARCHIVE_EOF;
+ goto abort_read_data;
+ }
+
+ /*
+ * Open the current file.
+ */
+ if (t->entry_fd < 0) {
+ int flags = O_RDONLY | O_BINARY;
+
+ /*
+ * Eliminate or reduce cache effects if we can.
+ *
+ * Carefully consider this to be enabled.
+ */
+#if defined(O_DIRECT) && 0/* Disabled for now */
+ if (t->current_filesystem->xfer_align != -1 &&
+ t->nlink == 1)
+ flags |= O_DIRECT;
+#endif
+#if defined(O_NOATIME)
+ /*
+ * Linux has O_NOATIME flag; use it if we need.
+ */
+ if ((t->flags & needsRestoreTimes) != 0 &&
+ t->restore_time.noatime == 0)
+ flags |= O_NOATIME;
+ do {
+#endif
+#ifdef HAVE_OPENAT
+ t->entry_fd = openat(tree_current_dir_fd(t),
+ tree_current_access_path(t), flags);
+#else
+ tree_enter_working_dir(t);
+ t->entry_fd = open(tree_current_access_path(t), flags);
+#endif
+#if defined(O_NOATIME)
+ /*
+ * When we did open the file with O_NOATIME flag,
+ * if successful, set 1 to t->restore_time.noatime
+ * not to restore an atime of the file later.
+ * if failed by EPERM, retry it without O_NOATIME flag.
+ */
+ if (flags & O_NOATIME) {
+ if (t->entry_fd >= 0)
+ t->restore_time.noatime = 1;
+ else if (errno == EPERM) {
+ flags &= ~O_NOATIME;
+ continue;
+ }
+ }
+ } while (0);
+#endif
+ if (t->entry_fd < 0) {
+ archive_set_error(&a->archive, errno,
+ "Couldn't open %s", tree_current_path(t));
+ r = ARCHIVE_FAILED;
+ tree_enter_initial_dir(t);
+ goto abort_read_data;
+ }
+ tree_enter_initial_dir(t);
+ }
+
+ /*
+ * Allocate read buffer if not allocated.
+ */
+ if (t->current_filesystem->allocation_ptr == NULL) {
+ r = setup_suitable_read_buffer(a);
+ if (r != ARCHIVE_OK) {
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ goto abort_read_data;
+ }
+ }
+ t->entry_buff = t->current_filesystem->buff;
+ t->entry_buff_size = t->current_filesystem->buff_size;
+
+ buffbytes = t->entry_buff_size;
+ if (buffbytes > t->current_sparse->length)
+ buffbytes = t->current_sparse->length;
+
+ /*
+ * Skip hole.
+ * TODO: Should we consider t->current_filesystem->xfer_align?
+ */
+ if (t->current_sparse->offset > t->entry_total) {
+ if (lseek(t->entry_fd,
+ (off_t)t->current_sparse->offset, SEEK_SET) < 0) {
+ archive_set_error(&a->archive, errno, "Seek error");
+ r = ARCHIVE_FATAL;
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ goto abort_read_data;
+ }
+ bytes = t->current_sparse->offset - t->entry_total;
+ t->entry_remaining_bytes -= bytes;
+ t->entry_total += bytes;
+ }
+
+ /*
+ * Read file contents.
+ */
+ if (buffbytes > 0) {
+ bytes = read(t->entry_fd, t->entry_buff, buffbytes);
+ if (bytes < 0) {
+ archive_set_error(&a->archive, errno, "Read error");
+ r = ARCHIVE_FATAL;
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ goto abort_read_data;
+ }
+ } else
+ bytes = 0;
+ if (bytes == 0) {
+ /* Get EOF */
+ t->entry_eof = 1;
+ r = ARCHIVE_EOF;
+ goto abort_read_data;
+ }
+ *buff = t->entry_buff;
+ *size = bytes;
+ *offset = t->entry_total;
+ t->entry_total += bytes;
+ t->entry_remaining_bytes -= bytes;
+ if (t->entry_remaining_bytes == 0) {
+ /* Close the current file descriptor */
+ close_and_restore_time(t->entry_fd, t, &t->restore_time);
+ t->entry_fd = -1;
+ t->entry_eof = 1;
+ }
+ t->current_sparse->offset += bytes;
+ t->current_sparse->length -= bytes;
+ if (t->current_sparse->length == 0 && !t->entry_eof)
+ t->current_sparse++;
+ return (ARCHIVE_OK);
+
+abort_read_data:
+ *buff = NULL;
+ *size = 0;
+ *offset = t->entry_total;
+ if (t->entry_fd >= 0) {
+ /* Close the current file descriptor */
+ close_and_restore_time(t->entry_fd, t, &t->restore_time);
+ t->entry_fd = -1;
+ }
+ return (r);
+}
+
+static int
+_archive_read_next_header2(struct archive *_a, struct archive_entry *entry)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ struct tree *t;
+ const struct stat *st; /* info to use for this entry */
+ const struct stat *lst;/* lstat() information */
+ int descend, fd = -1, r;
+
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
+ "archive_read_next_header2");
+
+ t = a->tree;
+ if (t->entry_fd >= 0) {
+ close_and_restore_time(t->entry_fd, t, &t->restore_time);
+ t->entry_fd = -1;
+ }
+#if !(defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR))
+ /* Restore working directory. */
+ tree_enter_working_dir(t);
+#endif
+ st = NULL;
+ lst = NULL;
+ do {
+ switch (tree_next(t)) {
+ case TREE_ERROR_FATAL:
+ archive_set_error(&a->archive, t->tree_errno,
+ "%s: Unable to continue traversing directory tree",
+ tree_current_path(t));
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ tree_enter_initial_dir(t);
+ return (ARCHIVE_FATAL);
+ case TREE_ERROR_DIR:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "%s: Couldn't visit directory",
+ tree_current_path(t));
+ tree_enter_initial_dir(t);
+ return (ARCHIVE_FAILED);
+ case 0:
+ tree_enter_initial_dir(t);
+ return (ARCHIVE_EOF);
+ case TREE_POSTDESCENT:
+ case TREE_POSTASCENT:
+ break;
+ case TREE_REGULAR:
+ lst = tree_current_lstat(t);
+ if (lst == NULL) {
+ archive_set_error(&a->archive, errno,
+ "%s: Cannot stat",
+ tree_current_path(t));
+ tree_enter_initial_dir(t);
+ return (ARCHIVE_FAILED);
+ }
+ break;
+ }
+ } while (lst == NULL);
+
+ /*
+ * Distinguish 'L'/'P'/'H' symlink following.
+ */
+ switch(t->symlink_mode) {
+ case 'H':
+ /* 'H': After the first item, rest like 'P'. */
+ t->symlink_mode = 'P';
+ /* 'H': First item (from command line) like 'L'. */
+ /* FALLTHROUGH */
+ case 'L':
+ /* 'L': Do descend through a symlink to dir. */
+ descend = tree_current_is_dir(t);
+ /* 'L': Follow symlinks to files. */
+ a->symlink_mode = 'L';
+ a->follow_symlinks = 1;
+ /* 'L': Archive symlinks as targets, if we can. */
+ st = tree_current_stat(t);
+ if (st != NULL && !tree_target_is_same_as_parent(t, st))
+ break;
+ /* If stat fails, we have a broken symlink;
+ * in that case, don't follow the link. */
+ /* FALLTHROUGH */
+ default:
+ /* 'P': Don't descend through a symlink to dir. */
+ descend = tree_current_is_physical_dir(t);
+ /* 'P': Don't follow symlinks to files. */
+ a->symlink_mode = 'P';
+ a->follow_symlinks = 0;
+ /* 'P': Archive symlinks as symlinks. */
+ st = lst;
+ break;
+ }
+
+ if (update_current_filesystem(a, st->st_dev) != ARCHIVE_OK) {
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ tree_enter_initial_dir(t);
+ return (ARCHIVE_FATAL);
+ }
+ t->descend = descend;
+
+ archive_entry_set_pathname(entry, tree_current_path(t));
+ archive_entry_copy_sourcepath(entry, tree_current_access_path(t));
+ archive_entry_copy_stat(entry, st);
+
+ /* Save the times to be restored. */
+ t->restore_time.mtime = archive_entry_mtime(entry);
+ t->restore_time.mtime_nsec = archive_entry_mtime_nsec(entry);
+ t->restore_time.atime = archive_entry_atime(entry);
+ t->restore_time.atime_nsec = archive_entry_atime_nsec(entry);
+ t->restore_time.filetype = archive_entry_filetype(entry);
+ t->restore_time.noatime = t->current_filesystem->noatime;
+
+#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR)
+ /*
+ * Open the current file to freely gather its metadata anywhere in
+ * working directory.
+ * Note: A symbolic link file cannot be opened with O_NOFOLLOW.
+ */
+ if (a->follow_symlinks || archive_entry_filetype(entry) != AE_IFLNK)
+ fd = openat(tree_current_dir_fd(t), tree_current_access_path(t),
+ O_RDONLY | O_NONBLOCK);
+ /* Restore working directory if openat() operation failed or
+ * the file is a symbolic link. */
+ if (fd < 0)
+ tree_enter_working_dir(t);
+
+ /* The current direcotry fd is needed at
+ * archive_read_disk_entry_from_file() function to read link data
+ * with readlinkat(). */
+ a->entry_wd_fd = tree_current_dir_fd(t);
+#endif
+
+ /*
+ * Populate the archive_entry with metadata from the disk.
+ */
+ r = archive_read_disk_entry_from_file(&(a->archive), entry, fd, st);
+
+ /* Close the file descriptor used for reding the current file
+ * metadata at archive_read_disk_entry_from_file(). */
+ if (fd >= 0)
+ close(fd);
+
+ /* Return to the initial directory. */
+ tree_enter_initial_dir(t);
+ archive_entry_copy_sourcepath(entry, tree_current_path(t));
+
+ /*
+ * EOF and FATAL are persistent at this layer. By
+ * modifying the state, we guarantee that future calls to
+ * read a header or read data will fail.
+ */
+ switch (r) {
+ case ARCHIVE_EOF:
+ a->archive.state = ARCHIVE_STATE_EOF;
+ break;
+ case ARCHIVE_OK:
+ case ARCHIVE_WARN:
+ t->entry_total = 0;
+ if (archive_entry_filetype(entry) == AE_IFREG) {
+ t->nlink = archive_entry_nlink(entry);
+ t->entry_remaining_bytes = archive_entry_size(entry);
+ t->entry_eof = (t->entry_remaining_bytes == 0)? 1: 0;
+ if (!t->entry_eof &&
+ setup_sparse(a, entry) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ } else {
+ t->entry_remaining_bytes = 0;
+ t->entry_eof = 1;
+ }
+ a->archive.state = ARCHIVE_STATE_DATA;
+ break;
+ case ARCHIVE_RETRY:
+ break;
+ case ARCHIVE_FATAL:
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ break;
+ }
+
+ return (r);
+}
+
+static int
+setup_sparse(struct archive_read_disk *a, struct archive_entry *entry)
+{
+ struct tree *t = a->tree;
+ int64_t length, offset;
+ int i;
+
+ t->sparse_count = archive_entry_sparse_reset(entry);
+ if (t->sparse_count+1 > t->sparse_list_size) {
+ free(t->sparse_list);
+ t->sparse_list_size = t->sparse_count + 1;
+ t->sparse_list = malloc(sizeof(t->sparse_list[0]) *
+ t->sparse_list_size);
+ if (t->sparse_list == NULL) {
+ t->sparse_list_size = 0;
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate data");
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ return (ARCHIVE_FATAL);
+ }
+ }
+ for (i = 0; i < t->sparse_count; i++) {
+ archive_entry_sparse_next(entry, &offset, &length);
+ t->sparse_list[i].offset = offset;
+ t->sparse_list[i].length = length;
+ }
+ if (i == 0) {
+ t->sparse_list[i].offset = 0;
+ t->sparse_list[i].length = archive_entry_size(entry);
+ } else {
+ t->sparse_list[i].offset = archive_entry_size(entry);
+ t->sparse_list[i].length = 0;
+ }
+ t->current_sparse = t->sparse_list;
+
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Called by the client to mark the directory just returned from
+ * tree_next() as needing to be visited.
+ */
+int
+archive_read_disk_descend(struct archive *_a)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ struct tree *t = a->tree;
+
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
+ "archive_read_disk_descend");
+
+ if (t->visit_type != TREE_REGULAR || !t->descend) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Ignored the request descending the current object");
+ return (ARCHIVE_WARN);
+ }
+
+ if (tree_current_is_physical_dir(t)) {
+ tree_push(t, t->basename, t->current_filesystem_id,
+ t->lst.st_dev, t->lst.st_ino, &t->restore_time);
+ t->stack->flags |= isDir;
+ } else if (tree_current_is_dir(t)) {
+ tree_push(t, t->basename, t->current_filesystem_id,
+ t->st.st_dev, t->st.st_ino, &t->restore_time);
+ t->stack->flags |= isDirLink;
+ }
+ t->descend = 0;
+ return (ARCHIVE_OK);
+}
+
+int
+archive_read_disk_open(struct archive *_a, const char *pathname)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_NEW | ARCHIVE_STATE_CLOSED,
+ "archive_read_disk_open");
+ archive_clear_error(&a->archive);
+
+ return (_archive_read_disk_open(_a, pathname));
+}
+
+int
+archive_read_disk_open_w(struct archive *_a, const wchar_t *pathname)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ struct archive_string path;
+ int ret;
+
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_NEW | ARCHIVE_STATE_CLOSED,
+ "archive_read_disk_open_w");
+ archive_clear_error(&a->archive);
+
+ /* Make a char string from a wchar_t string. */
+ archive_string_init(&path);
+ if (archive_string_append_from_wcs(&path, pathname,
+ wcslen(pathname)) != 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Can't convert a path to a char string");
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ ret = ARCHIVE_FATAL;
+ } else
+ ret = _archive_read_disk_open(_a, path.s);
+
+ archive_string_free(&path);
+ return (ret);
+}
+
+static int
+_archive_read_disk_open(struct archive *_a, const char *pathname)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+
+ if (a->tree != NULL)
+ a->tree = tree_reopen(a->tree, pathname, a->restore_time);
+ else
+ a->tree = tree_open(pathname, a->symlink_mode,
+ a->restore_time);
+ if (a->tree == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate tar data");
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ return (ARCHIVE_FATAL);
+ }
+ a->archive.state = ARCHIVE_STATE_HEADER;
+
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Return a current filesystem ID which is index of the filesystem entry
+ * you've visited through archive_read_disk.
+ */
+int
+archive_read_disk_current_filesystem(struct archive *_a)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
+ "archive_read_disk_current_filesystem");
+
+ return (a->tree->current_filesystem_id);
+}
+
+static int
+update_current_filesystem(struct archive_read_disk *a, int64_t dev)
+{
+ struct tree *t = a->tree;
+ int i, fid;
+
+ if (t->current_filesystem != NULL &&
+ t->current_filesystem->dev == dev)
+ return (ARCHIVE_OK);
+
+ for (i = 0; i < t->max_filesystem_id; i++) {
+ if (t->filesystem_table[i].dev == dev) {
+ /* There is the filesytem ID we've already generated. */
+ t->current_filesystem_id = i;
+ t->current_filesystem = &(t->filesystem_table[i]);
+ return (ARCHIVE_OK);
+ }
+ }
+
+ /*
+ * This is the new filesytem which we have to generate a new ID for.
+ */
+ fid = t->max_filesystem_id++;
+ if (t->max_filesystem_id > t->allocated_filesytem) {
+ size_t s;
+
+ s = t->max_filesystem_id * 2;
+ t->filesystem_table = realloc(t->filesystem_table,
+ s * sizeof(*t->filesystem_table));
+ if (t->filesystem_table == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate tar data");
+ return (ARCHIVE_FATAL);
+ }
+ t->allocated_filesytem = s;
+ }
+ t->current_filesystem_id = fid;
+ t->current_filesystem = &(t->filesystem_table[fid]);
+ t->current_filesystem->dev = dev;
+ t->current_filesystem->allocation_ptr = NULL;
+ t->current_filesystem->buff = NULL;
+
+ /* Setup the current filesystem properties which depend on
+ * platform specific. */
+ return (setup_current_filesystem(a));
+}
+
+/*
+ * Returns 1 if current filesystem is generated filesystem, 0 if it is not
+ * or -1 if it is unknown.
+ */
+int
+archive_read_disk_current_filesystem_is_synthetic(struct archive *_a)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
+ "archive_read_disk_current_filesystem");
+
+ return (a->tree->current_filesystem->synthetic);
+}
+
+/*
+ * Returns 1 if current filesystem is remote filesystem, 0 if it is not
+ * or -1 if it is unknown.
+ */
+int
+archive_read_disk_current_filesystem_is_remote(struct archive *_a)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
+ "archive_read_disk_current_filesystem");
+
+ return (a->tree->current_filesystem->remote);
+}
+
+#if defined(_PC_REC_INCR_XFER_SIZE) && defined(_PC_REC_MAX_XFER_SIZE) &&\
+ defined(_PC_REC_MIN_XFER_SIZE) && defined(_PC_REC_XFER_ALIGN)
+static int
+get_xfer_size(struct tree *t, int fd, const char *path)
+{
+ t->current_filesystem->xfer_align = -1;
+ errno = 0;
+ if (fd >= 0) {
+ t->current_filesystem->incr_xfer_size =
+ fpathconf(fd, _PC_REC_INCR_XFER_SIZE);
+ t->current_filesystem->max_xfer_size =
+ fpathconf(fd, _PC_REC_MAX_XFER_SIZE);
+ t->current_filesystem->min_xfer_size =
+ fpathconf(fd, _PC_REC_MIN_XFER_SIZE);
+ t->current_filesystem->xfer_align =
+ fpathconf(fd, _PC_REC_XFER_ALIGN);
+ } else if (path != NULL) {
+ t->current_filesystem->incr_xfer_size =
+ pathconf(path, _PC_REC_INCR_XFER_SIZE);
+ t->current_filesystem->max_xfer_size =
+ pathconf(path, _PC_REC_MAX_XFER_SIZE);
+ t->current_filesystem->min_xfer_size =
+ pathconf(path, _PC_REC_MIN_XFER_SIZE);
+ t->current_filesystem->xfer_align =
+ pathconf(path, _PC_REC_XFER_ALIGN);
+ }
+ /* At least we need an alignment size. */
+ if (t->current_filesystem->xfer_align == -1)
+ return ((errno == EINVAL)?1:-1);
+ else
+ return (0);
+}
+#else
+static int
+get_xfer_size(struct tree *t, int fd, const char *path)
+{
+ (void)t; /* UNUSED */
+ (void)fd; /* UNUSED */
+ (void)path; /* UNUSED */
+ return (1);/* Not supported */
+}
+#endif
+
+#if defined(HAVE_STATFS) && defined(HAVE_FSTATFS) && defined(MNT_LOCAL) \
+ && !defined(ST_LOCAL)
+
+/*
+ * Gather current filesystem properties on FreeBSD, OpenBSD and Mac OS X.
+ */
+static int
+setup_current_filesystem(struct archive_read_disk *a)
+{
+ struct tree *t = a->tree;
+ struct statfs sfs;
+#if defined(HAVE_GETVFSBYNAME) && defined(VFCF_SYNTHETIC)
+ struct xvfsconf vfc;
+#endif
+ int r, xr = 0;
+#if !defined(HAVE_STRUCT_STATFS_F_NAMEMAX)
+ long nm;
+#endif
+
+ t->current_filesystem->synthetic = -1;
+ t->current_filesystem->remote = -1;
+ if (tree_current_is_symblic_link_target(t)) {
+#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR)
+ /*
+ * Get file system statistics on any directory
+ * where current is.
+ */
+ int fd = openat(tree_current_dir_fd(t),
+ tree_current_access_path(t), O_RDONLY);
+ if (fd < 0) {
+ archive_set_error(&a->archive, errno,
+ "openat failed");
+ return (ARCHIVE_FAILED);
+ }
+ r = fstatfs(fd, &sfs);
+ if (r == 0)
+ xr = get_xfer_size(t, fd, NULL);
+ close(fd);
+#else
+ r = statfs(tree_current_access_path(t), &sfs);
+ if (r == 0)
+ xr = get_xfer_size(t, -1, tree_current_access_path(t));
+#endif
+ } else {
+ r = fstatfs(tree_current_dir_fd(t), &sfs);
+ if (r == 0)
+ xr = get_xfer_size(t, tree_current_dir_fd(t), NULL);
+ }
+ if (r == -1 || xr == -1) {
+ archive_set_error(&a->archive, errno, "statfs failed");
+ return (ARCHIVE_FAILED);
+ } else if (xr == 1) {
+ /* pathconf(_PC_REX_*) operations are not supported. */
+ t->current_filesystem->xfer_align = sfs.f_bsize;
+ t->current_filesystem->max_xfer_size = -1;
+ t->current_filesystem->min_xfer_size = sfs.f_iosize;
+ t->current_filesystem->incr_xfer_size = sfs.f_iosize;
+ }
+ if (sfs.f_flags & MNT_LOCAL)
+ t->current_filesystem->remote = 0;
+ else
+ t->current_filesystem->remote = 1;
+
+#if defined(HAVE_GETVFSBYNAME) && defined(VFCF_SYNTHETIC)
+ r = getvfsbyname(sfs.f_fstypename, &vfc);
+ if (r == -1) {
+ archive_set_error(&a->archive, errno, "getvfsbyname failed");
+ return (ARCHIVE_FAILED);
+ }
+ if (vfc.vfc_flags & VFCF_SYNTHETIC)
+ t->current_filesystem->synthetic = 1;
+ else
+ t->current_filesystem->synthetic = 0;
+#endif
+
+#if defined(MNT_NOATIME)
+ if (sfs.f_flags & MNT_NOATIME)
+ t->current_filesystem->noatime = 1;
+ else
+#endif
+ t->current_filesystem->noatime = 0;
+
+#if defined(HAVE_READDIR_R)
+ /* Set maximum filename length. */
+#if defined(HAVE_STRUCT_STATFS_F_NAMEMAX)
+ t->current_filesystem->name_max = sfs.f_namemax;
+#else
+ /* Mac OS X does not have f_namemax in struct statfs. */
+ if (tree_current_is_symblic_link_target(t))
+ nm = pathconf(tree_current_access_path(t), _PC_NAME_MAX);
+ else
+ nm = fpathconf(tree_current_dir_fd(t), _PC_NAME_MAX);
+ if (nm == -1)
+ t->current_filesystem->name_max = NAME_MAX;
+ else
+ t->current_filesystem->name_max = nm;
+#endif
+#endif /* HAVE_READDIR_R */
+ return (ARCHIVE_OK);
+}
+
+#elif (defined(HAVE_STATVFS) || defined(HAVE_FSTATVFS)) && defined(ST_LOCAL)
+
+/*
+ * Gather current filesystem properties on NetBSD
+ */
+static int
+setup_current_filesystem(struct archive_read_disk *a)
+{
+ struct tree *t = a->tree;
+ struct statvfs sfs;
+ int r, xr = 0;
+
+ t->current_filesystem->synthetic = -1;
+ if (tree_current_is_symblic_link_target(t)) {
+ r = statvfs(tree_current_access_path(t), &sfs);
+ if (r == 0)
+ xr = get_xfer_size(t, -1, tree_current_access_path(t));
+ } else {
+#ifdef HAVE_FSTATVFS
+ r = fstatvfs(tree_current_dir_fd(t), &sfs);
+ if (r == 0)
+ xr = get_xfer_size(t, tree_current_dir_fd(t), NULL);
+#else
+ r = statvfs(".", &sfs);
+ if (r == 0)
+ xr = get_xfer_size(t, -1, ".");
+#endif
+ }
+ if (r == -1 || xr == -1) {
+ t->current_filesystem->remote = -1;
+ archive_set_error(&a->archive, errno, "statvfs failed");
+ return (ARCHIVE_FAILED);
+ } else if (xr == 1) {
+ /* Usuall come here unless NetBSD supports _PC_REC_XFER_ALIGN
+ * for pathconf() function. */
+ t->current_filesystem->xfer_align = sfs.f_frsize;
+ t->current_filesystem->max_xfer_size = -1;
+#if defined(HAVE_STRUCT_STATVFS_F_IOSIZE)
+ t->current_filesystem->min_xfer_size = sfs.f_iosize;
+ t->current_filesystem->incr_xfer_size = sfs.f_iosize;
+#else
+ t->current_filesystem->min_xfer_size = sfs.f_bsize;
+ t->current_filesystem->incr_xfer_size = sfs.f_bsize;
+#endif
+ }
+ if (sfs.f_flag & ST_LOCAL)
+ t->current_filesystem->remote = 0;
+ else
+ t->current_filesystem->remote = 1;
+
+#if defined(ST_NOATIME)
+ if (sfs.f_flag & ST_NOATIME)
+ t->current_filesystem->noatime = 1;
+ else
+#endif
+ t->current_filesystem->noatime = 0;
+
+ /* Set maximum filename length. */
+ t->current_filesystem->name_max = sfs.f_namemax;
+ return (ARCHIVE_OK);
+}
+
+#elif defined(HAVE_SYS_STATFS_H) && defined(HAVE_LINUX_MAGIC_H) &&\
+ defined(HAVE_STATFS) && defined(HAVE_FSTATFS)
+/*
+ * Note: statfs is deprecated since LSB 3.2
+ */
+
+#ifndef CIFS_SUPER_MAGIC
+#define CIFS_SUPER_MAGIC 0xFF534D42
+#endif
+#ifndef DEVFS_SUPER_MAGIC
+#define DEVFS_SUPER_MAGIC 0x1373
+#endif
+
+/*
+ * Gather current filesystem properties on Linux
+ */
+static int
+setup_current_filesystem(struct archive_read_disk *a)
+{
+ struct tree *t = a->tree;
+ struct statfs sfs;
+ struct statvfs svfs;
+ int r, vr = 0, xr = 0;
+
+ if (tree_current_is_symblic_link_target(t)) {
+#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR)
+ /*
+ * Get file system statistics on any directory
+ * where current is.
+ */
+ int fd = openat(tree_current_dir_fd(t),
+ tree_current_access_path(t), O_RDONLY);
+ if (fd < 0) {
+ archive_set_error(&a->archive, errno,
+ "openat failed");
+ return (ARCHIVE_FAILED);
+ }
+ vr = fstatvfs(fd, &svfs);/* for f_flag, mount flags */
+ r = fstatfs(fd, &sfs);
+ if (r == 0)
+ xr = get_xfer_size(t, fd, NULL);
+ close(fd);
+#else
+ vr = statvfs(tree_current_access_path(t), &svfs);
+ r = statfs(tree_current_access_path(t), &sfs);
+ if (r == 0)
+ xr = get_xfer_size(t, -1, tree_current_access_path(t));
+#endif
+ } else {
+#ifdef HAVE_FSTATFS
+ vr = fstatvfs(tree_current_dir_fd(t), &svfs);
+ r = fstatfs(tree_current_dir_fd(t), &sfs);
+ if (r == 0)
+ xr = get_xfer_size(t, tree_current_dir_fd(t), NULL);
+#elif defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR)
+#error "Unexpected case. Please tell us about this error."
+#else
+ vr = statvfs(".", &svfs);
+ r = statfs(".", &sfs);
+ if (r == 0)
+ xr = get_xfer_size(t, -1, ".");
+#endif
+ }
+ if (r == -1 || xr == -1 || vr == -1) {
+ t->current_filesystem->synthetic = -1;
+ t->current_filesystem->remote = -1;
+ archive_set_error(&a->archive, errno, "statfs failed");
+ return (ARCHIVE_FAILED);
+ } else if (xr == 1) {
+ /* pathconf(_PC_REX_*) operations are not supported. */
+ t->current_filesystem->xfer_align = svfs.f_frsize;
+ t->current_filesystem->max_xfer_size = -1;
+ t->current_filesystem->min_xfer_size = svfs.f_bsize;
+ t->current_filesystem->incr_xfer_size = svfs.f_bsize;
+ }
+ switch (sfs.f_type) {
+ case AFS_SUPER_MAGIC:
+ case CIFS_SUPER_MAGIC:
+ case CODA_SUPER_MAGIC:
+ case NCP_SUPER_MAGIC:/* NetWare */
+ case NFS_SUPER_MAGIC:
+ case SMB_SUPER_MAGIC:
+ t->current_filesystem->remote = 1;
+ t->current_filesystem->synthetic = 0;
+ break;
+ case DEVFS_SUPER_MAGIC:
+ case PROC_SUPER_MAGIC:
+ case USBDEVICE_SUPER_MAGIC:
+ t->current_filesystem->remote = 0;
+ t->current_filesystem->synthetic = 1;
+ break;
+ default:
+ t->current_filesystem->remote = 0;
+ t->current_filesystem->synthetic = 0;
+ break;
+ }
+
+#if defined(ST_NOATIME)
+ if (svfs.f_flag & ST_NOATIME)
+ t->current_filesystem->noatime = 1;
+ else
+#endif
+ t->current_filesystem->noatime = 0;
+
+#if defined(HAVE_READDIR_R)
+ /* Set maximum filename length. */
+ t->current_filesystem->name_max = sfs.f_namelen;
+#endif
+ return (ARCHIVE_OK);
+}
+
+#elif defined(HAVE_SYS_STATVFS_H) &&\
+ (defined(HAVE_STATVFS) || defined(HAVE_FSTATVFS))
+
+/*
+ * Gather current filesystem properties on other posix platform.
+ */
+static int
+setup_current_filesystem(struct archive_read_disk *a)
+{
+ struct tree *t = a->tree;
+ struct statvfs sfs;
+ int r, xr = 0;
+
+ t->current_filesystem->synthetic = -1;/* Not supported */
+ t->current_filesystem->remote = -1;/* Not supported */
+ if (tree_current_is_symblic_link_target(t)) {
+#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR)
+ /*
+ * Get file system statistics on any directory
+ * where current is.
+ */
+ int fd = openat(tree_current_dir_fd(t),
+ tree_current_access_path(t), O_RDONLY);
+ if (fd < 0) {
+ archive_set_error(&a->archive, errno,
+ "openat failed");
+ return (ARCHIVE_FAILED);
+ }
+ r = fstatvfs(fd, &sfs);
+ if (r == 0)
+ xr = get_xfer_size(t, fd, NULL);
+ close(fd);
+#else
+ r = statvfs(tree_current_access_path(t), &sfs);
+ if (r == 0)
+ xr = get_xfer_size(t, -1, tree_current_access_path(t));
+#endif
+ } else {
+#ifdef HAVE_FSTATVFS
+ r = fstatvfs(tree_current_dir_fd(t), &sfs);
+ if (r == 0)
+ xr = get_xfer_size(t, tree_current_dir_fd(t), NULL);
+#elif defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR)
+#error "Unexpected case. Please tell us about this error."
+#else
+ r = statvfs(".", &sfs);
+ if (r == 0)
+ xr = get_xfer_size(t, -1, ".");
+#endif
+ }
+ if (r == -1 || xr == -1) {
+ t->current_filesystem->synthetic = -1;
+ t->current_filesystem->remote = -1;
+ archive_set_error(&a->archive, errno, "statvfs failed");
+ return (ARCHIVE_FAILED);
+ } else if (xr == 1) {
+ /* pathconf(_PC_REX_*) operations are not supported. */
+ t->current_filesystem->xfer_align = sfs.f_frsize;
+ t->current_filesystem->max_xfer_size = -1;
+ t->current_filesystem->min_xfer_size = sfs.f_bsize;
+ t->current_filesystem->incr_xfer_size = sfs.f_bsize;
+ }
+
+#if defined(ST_NOATIME)
+ if (sfs.f_flag & ST_NOATIME)
+ t->current_filesystem->noatime = 1;
+ else
+#endif
+ t->current_filesystem->noatime = 0;
+
+#if defined(HAVE_READDIR_R)
+ /* Set maximum filename length. */
+ t->current_filesystem->name_max = sfs.f_namemax;
+#endif
+ return (ARCHIVE_OK);
+}
+
+#else
+
+/*
+ * Generic: Gather current filesystem properties.
+ * TODO: Is this generic function really needed?
+ */
+static int
+setup_current_filesystem(struct archive_read_disk *a)
+{
+ struct tree *t = a->tree;
+#if defined(_PC_NAME_MAX) && defined(HAVE_READDIR_R)
+ long nm;
+#endif
+ t->current_filesystem->synthetic = -1;/* Not supported */
+ t->current_filesystem->remote = -1;/* Not supported */
+ t->current_filesystem->noatime = 0;
+ (void)get_xfer_size(t, -1, ".");/* Dummy call to avoid build error. */
+ t->current_filesystem->xfer_align = -1;/* Unknown */
+ t->current_filesystem->max_xfer_size = -1;
+ t->current_filesystem->min_xfer_size = -1;
+ t->current_filesystem->incr_xfer_size = -1;
+
+#if defined(HAVE_READDIR_R)
+ /* Set maximum filename length. */
+# if defined(_PC_NAME_MAX)
+ if (tree_current_is_symblic_link_target(t))
+ nm = pathconf(tree_current_access_path(t), _PC_NAME_MAX);
+ else
+ nm = fpathconf(tree_current_dir_fd(t), _PC_NAME_MAX);
+ if (nm == -1)
+# endif /* _PC_NAME_MAX */
+ /*
+ * Some sysmtes (HP-UX or others?) incorrectly defined
+ * NAME_MAX macro to be a smaller value.
+ */
+# if defined(NAME_MAX) && NAME_MAX >= 255
+ t->current_filesystem->name_max = NAME_MAX;
+# else
+ /* No way to get a trusted value of maximum filename
+ * length. */
+ t->current_filesystem->name_max = PATH_MAX;
+# endif /* NAME_MAX */
+# if defined(_PC_NAME_MAX)
+ else
+ t->current_filesystem->name_max = nm;
+# endif /* _PC_NAME_MAX */
+#endif /* HAVE_READDIR_R */
+ return (ARCHIVE_OK);
+}
+
+#endif
+
+static int
+close_and_restore_time(int fd, struct tree *t, struct restore_time *rt)
+{
+#ifndef HAVE_UTIMES
+ (void)a; /* UNUSED */
+ return (close(fd));
+#else
+#if defined(HAVE_FUTIMENS) && !defined(__CYGWIN__)
+ struct timespec timespecs[2];
+#endif
+ struct timeval times[2];
+
+ if ((t->flags & needsRestoreTimes) == 0 || rt->noatime) {
+ if (fd >= 0)
+ return (close(fd));
+ else
+ return (0);
+ }
+
+#if defined(HAVE_FUTIMENS) && !defined(__CYGWIN__)
+ timespecs[1].tv_sec = rt->mtime;
+ timespecs[1].tv_nsec = rt->mtime_nsec;
+
+ timespecs[0].tv_sec = rt->atime;
+ timespecs[0].tv_nsec = rt->atime_nsec;
+ /* futimens() is defined in POSIX.1-2008. */
+ if (futimens(fd, timespecs) == 0)
+ return (close(fd));
+#endif
+
+ times[1].tv_sec = rt->mtime;
+ times[1].tv_usec = rt->mtime_nsec / 1000;
+
+ times[0].tv_sec = rt->atime;
+ times[0].tv_usec = rt->atime_nsec / 1000;
+
+#if !defined(HAVE_FUTIMENS) && defined(HAVE_FUTIMES) && !defined(__CYGWIN__)
+ if (futimes(fd, times) == 0)
+ return (close(fd));
+#endif
+ close(fd);
+#if defined(HAVE_FUTIMESAT)
+ if (futimesat(tree_current_dir_fd(t), rt->name, times) == 0)
+ return (0);
+#endif
+#ifdef HAVE_LUTIMES
+ if (lutimes(rt->name, times) != 0)
+#else
+ if (AE_IFLNK != rt->filetype && utimes(rt->name, times) != 0)
+#endif
+ return (-1);
+#endif
+ return (0);
+}
+
+/*
+ * Add a directory path to the current stack.
+ */
+static void
+tree_push(struct tree *t, const char *path, int filesystem_id,
+ int64_t dev, int64_t ino, struct restore_time *rt)
+{
+ struct tree_entry *te;
+
+ te = malloc(sizeof(*te));
+ memset(te, 0, sizeof(*te));
+ te->next = t->stack;
+ te->parent = t->current;
+ if (te->parent)
+ te->depth = te->parent->depth + 1;
+ t->stack = te;
+ archive_string_init(&te->name);
+ te->symlink_parent_fd = -1;
+ archive_strcpy(&te->name, path);
+ te->flags = needsDescent | needsOpen | needsAscent;
+ te->filesystem_id = filesystem_id;
+ te->dev = dev;
+ te->ino = ino;
+ te->dirname_length = t->dirname_length;
+ te->restore_time.name = te->name.s;
+ if (rt != NULL) {
+ te->restore_time.mtime = rt->mtime;
+ te->restore_time.mtime_nsec = rt->mtime_nsec;
+ te->restore_time.atime = rt->atime;
+ te->restore_time.atime_nsec = rt->atime_nsec;
+ te->restore_time.filetype = rt->filetype;
+ te->restore_time.noatime = rt->noatime;
+ }
+}
+
+/*
+ * Append a name to the current dir path.
+ */
+static void
+tree_append(struct tree *t, const char *name, size_t name_length)
+{
+ size_t size_needed;
+
+ t->path.s[t->dirname_length] = '\0';
+ t->path.length = t->dirname_length;
+ /* Strip trailing '/' from name, unless entire name is "/". */
+ while (name_length > 1 && name[name_length - 1] == '/')
+ name_length--;
+
+ /* Resize pathname buffer as needed. */
+ size_needed = name_length + t->dirname_length + 2;
+ archive_string_ensure(&t->path, size_needed);
+ /* Add a separating '/' if it's needed. */
+ if (t->dirname_length > 0 && t->path.s[archive_strlen(&t->path)-1] != '/')
+ archive_strappend_char(&t->path, '/');
+ t->basename = t->path.s + archive_strlen(&t->path);
+ archive_strncat(&t->path, name, name_length);
+ t->restore_time.name = t->basename;
+}
+
+/*
+ * Open a directory tree for traversal.
+ */
+static struct tree *
+tree_open(const char *path, int symlink_mode, int restore_time)
+{
+ struct tree *t;
+
+ if ((t = malloc(sizeof(*t))) == NULL)
+ return (NULL);
+ memset(t, 0, sizeof(*t));
+ archive_string_init(&t->path);
+ archive_string_ensure(&t->path, 31);
+ t->initial_symlink_mode = symlink_mode;
+ return (tree_reopen(t, path, restore_time));
+}
+
+static struct tree *
+tree_reopen(struct tree *t, const char *path, int restore_time)
+{
+ t->flags = (restore_time)?needsRestoreTimes:0;
+ t->visit_type = 0;
+ t->tree_errno = 0;
+ t->dirname_length = 0;
+ t->depth = 0;
+ t->descend = 0;
+ t->current = NULL;
+ t->d = INVALID_DIR_HANDLE;
+ t->symlink_mode = t->initial_symlink_mode;
+ archive_string_empty(&t->path);
+ t->entry_fd = -1;
+ t->entry_eof = 0;
+ t->entry_remaining_bytes = 0;
+
+ /* First item is set up a lot like a symlink traversal. */
+ tree_push(t, path, 0, 0, 0, NULL);
+ t->stack->flags = needsFirstVisit;
+ t->maxOpenCount = t->openCount = 1;
+ t->initial_dir_fd = open(".", O_RDONLY);
+ t->working_dir_fd = dup(t->initial_dir_fd);
+ return (t);
+}
+
+static int
+tree_descent(struct tree *t)
+{
+ int r = 0;
+
+#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR)
+ int new_fd;
+ t->dirname_length = archive_strlen(&t->path);
+ new_fd = openat(t->working_dir_fd, t->stack->name.s, O_RDONLY);
+ if (new_fd < 0) {
+ t->tree_errno = errno;
+ r = TREE_ERROR_DIR;
+ } else {
+ t->depth++;
+ /* If it is a link, set up fd for the ascent. */
+ if (t->stack->flags & isDirLink) {
+ t->stack->symlink_parent_fd = t->working_dir_fd;
+ t->openCount++;
+ if (t->openCount > t->maxOpenCount)
+ t->maxOpenCount = t->openCount;
+ } else
+ close(t->working_dir_fd);
+ t->working_dir_fd = new_fd;
+ }
+#else
+ /* If it is a link, set up fd for the ascent. */
+ if (t->stack->flags & isDirLink)
+ t->stack->symlink_parent_fd = t->working_dir_fd;
+ else {
+ close(t->working_dir_fd);
+ t->openCount--;
+ }
+ t->working_dir_fd = -1;
+ t->dirname_length = archive_strlen(&t->path);
+ if (chdir(t->stack->name.s) != 0)
+ {
+ t->tree_errno = errno;
+ r = TREE_ERROR_DIR;
+ } else {
+ t->depth++;
+ t->working_dir_fd = open(".", O_RDONLY);
+ t->openCount++;
+ if (t->openCount > t->maxOpenCount)
+ t->maxOpenCount = t->openCount;
+ }
+#endif
+ return (r);
+}
+
+/*
+ * We've finished a directory; ascend back to the parent.
+ */
+static int
+tree_ascend(struct tree *t)
+{
+ struct tree_entry *te;
+ int r = 0, prev_dir_fd;
+
+ te = t->stack;
+ prev_dir_fd = t->working_dir_fd;
+#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_FDOPENDIR)
+ if (te->flags & isDirLink)
+ t->working_dir_fd = te->symlink_parent_fd;
+ else {
+ int new_fd = openat(t->working_dir_fd, "..", O_RDONLY);
+ if (new_fd < 0) {
+ t->tree_errno = errno;
+ r = TREE_ERROR_FATAL;
+ } else
+ t->working_dir_fd = new_fd;
+ }
+#else
+ if (te->flags & isDirLink) {
+ if (fchdir(te->symlink_parent_fd) != 0) {
+ t->tree_errno = errno;
+ r = TREE_ERROR_FATAL;
+ } else
+ t->working_dir_fd = te->symlink_parent_fd;
+ } else {
+ if (chdir("..") != 0) {
+ t->tree_errno = errno;
+ r = TREE_ERROR_FATAL;
+ } else
+ t->working_dir_fd = open(".", O_RDONLY);
+ }
+#endif
+ if (r == 0) {
+ /* Current directory has been changed, we should
+ * close an fd of previous working directory. */
+ close_and_restore_time(prev_dir_fd, t, &te->restore_time);
+ if (te->flags & isDirLink) {
+ t->openCount--;
+ te->symlink_parent_fd = -1;
+ }
+ t->depth--;
+ }
+ return (r);
+}
+
+/*
+ * Return to the initial directory where tree_open() was performed.
+ */
+static int
+tree_enter_initial_dir(struct tree *t)
+{
+ int r = 0;
+
+ if (t->flags & onWorkingDir) {
+ r = fchdir(t->initial_dir_fd);
+ if (r == 0)
+ t->flags &= ~onWorkingDir;
+ }
+ return (r);
+}
+
+/*
+ * Restore working directory of directory traversals.
+ */
+static int
+tree_enter_working_dir(struct tree *t)
+{
+ int r = 0;
+
+ /*
+ * Change the current directory if really needed.
+ * Sometimes this is unneeded when we did not do
+ * descent.
+ */
+ if (t->depth > 0 && (t->flags & onWorkingDir) == 0) {
+ r = fchdir(t->working_dir_fd);
+ if (r == 0)
+ t->flags |= onWorkingDir;
+ }
+ return (r);
+}
+
+static int
+tree_current_dir_fd(struct tree *t)
+{
+ return (t->working_dir_fd);
+}
+
+/*
+ * Pop the working stack.
+ */
+static void
+tree_pop(struct tree *t)
+{
+ struct tree_entry *te;
+
+ t->path.s[t->dirname_length] = '\0';
+ t->path.length = t->dirname_length;
+ if (t->stack == t->current && t->current != NULL)
+ t->current = t->current->parent;
+ te = t->stack;
+ t->stack = te->next;
+ t->dirname_length = te->dirname_length;
+ t->basename = t->path.s + t->dirname_length;
+ while (t->basename[0] == '/')
+ t->basename++;
+ archive_string_free(&te->name);
+ free(te);
+}
+
+/*
+ * Get the next item in the tree traversal.
+ */
+static int
+tree_next(struct tree *t)
+{
+ int r;
+
+ while (t->stack != NULL) {
+ /* If there's an open dir, get the next entry from there. */
+ if (t->d != INVALID_DIR_HANDLE) {
+ r = tree_dir_next_posix(t);
+ if (r == 0)
+ continue;
+ return (r);
+ }
+
+ if (t->stack->flags & needsFirstVisit) {
+ /* Top stack item needs a regular visit. */
+ t->current = t->stack;
+ tree_append(t, t->stack->name.s,
+ archive_strlen(&(t->stack->name)));
+ /* t->dirname_length = t->path_length; */
+ /* tree_pop(t); */
+ t->stack->flags &= ~needsFirstVisit;
+ return (t->visit_type = TREE_REGULAR);
+ } else if (t->stack->flags & needsDescent) {
+ /* Top stack item is dir to descend into. */
+ t->current = t->stack;
+ tree_append(t, t->stack->name.s,
+ archive_strlen(&(t->stack->name)));
+ t->stack->flags &= ~needsDescent;
+ r = tree_descent(t);
+ if (r != 0) {
+ tree_pop(t);
+ t->visit_type = r;
+ } else
+ t->visit_type = TREE_POSTDESCENT;
+ return (t->visit_type);
+ } else if (t->stack->flags & needsOpen) {
+ t->stack->flags &= ~needsOpen;
+ r = tree_dir_next_posix(t);
+ if (r == 0)
+ continue;
+ return (r);
+ } else if (t->stack->flags & needsAscent) {
+ /* Top stack item is dir and we're done with it. */
+ r = tree_ascend(t);
+ tree_pop(t);
+ t->visit_type = r != 0 ? r : TREE_POSTASCENT;
+ return (t->visit_type);
+ } else {
+ /* Top item on stack is dead. */
+ tree_pop(t);
+ t->flags &= ~hasLstat;
+ t->flags &= ~hasStat;
+ }
+ }
+ return (t->visit_type = 0);
+}
+
+static int
+tree_dir_next_posix(struct tree *t)
+{
+ int r;
+ const char *name;
+ size_t namelen;
+
+ if (t->d == NULL) {
+#if defined(HAVE_READDIR_R)
+ size_t dirent_size;
+#endif
+
+#if defined(HAVE_FDOPENDIR)
+ if ((t->d = fdopendir(dup(t->working_dir_fd))) == NULL) {
+#else
+ if ((t->d = opendir(".")) == NULL) {
+#endif
+ r = tree_ascend(t); /* Undo "chdir" */
+ tree_pop(t);
+ t->tree_errno = errno;
+ t->visit_type = r != 0 ? r : TREE_ERROR_DIR;
+ return (t->visit_type);
+ }
+#if defined(HAVE_READDIR_R)
+ dirent_size = offsetof(struct dirent, d_name) +
+ t->filesystem_table[t->current->filesystem_id].name_max + 1;
+ if (t->dirent == NULL || t->dirent_allocated < dirent_size) {
+ free(t->dirent);
+ t->dirent = malloc(dirent_size);
+ if (t->dirent == NULL) {
+ closedir(t->d);
+ t->d = INVALID_DIR_HANDLE;
+ (void)tree_ascend(t);
+ tree_pop(t);
+ t->tree_errno = ENOMEM;
+ t->visit_type = TREE_ERROR_DIR;
+ return (t->visit_type);
+ }
+ t->dirent_allocated = dirent_size;
+ }
+#endif /* HAVE_READDIR_R */
+ }
+ for (;;) {
+#if defined(HAVE_READDIR_R)
+ r = readdir_r(t->d, t->dirent, &t->de);
+ if (r != 0 || t->de == NULL) {
+#else
+ errno = 0;
+ t->de = readdir(t->d);
+ if (t->de == NULL) {
+ r = errno;
+#endif
+ closedir(t->d);
+ t->d = INVALID_DIR_HANDLE;
+ if (r != 0) {
+ t->tree_errno = r;
+ t->visit_type = TREE_ERROR_DIR;
+ return (t->visit_type);
+ } else
+ return (0);
+ }
+ name = t->de->d_name;
+ namelen = D_NAMELEN(t->de);
+ t->flags &= ~hasLstat;
+ t->flags &= ~hasStat;
+ if (name[0] == '.' && name[1] == '\0')
+ continue;
+ if (name[0] == '.' && name[1] == '.' && name[2] == '\0')
+ continue;
+ tree_append(t, name, namelen);
+ return (t->visit_type = TREE_REGULAR);
+ }
+}
+
+
+/*
+ * Get the stat() data for the entry just returned from tree_next().
+ */
+static const struct stat *
+tree_current_stat(struct tree *t)
+{
+ if (!(t->flags & hasStat)) {
+#ifdef HAVE_FSTATAT
+ if (fstatat(tree_current_dir_fd(t),
+ tree_current_access_path(t), &t->st, 0) != 0)
+#else
+ if (stat(tree_current_access_path(t), &t->st) != 0)
+#endif
+ return NULL;
+ t->flags |= hasStat;
+ }
+ return (&t->st);
+}
+
+/*
+ * Get the lstat() data for the entry just returned from tree_next().
+ */
+static const struct stat *
+tree_current_lstat(struct tree *t)
+{
+ if (!(t->flags & hasLstat)) {
+#ifdef HAVE_FSTATAT
+ if (fstatat(tree_current_dir_fd(t),
+ tree_current_access_path(t), &t->lst,
+ AT_SYMLINK_NOFOLLOW) != 0)
+#else
+ if (lstat(tree_current_access_path(t), &t->lst) != 0)
+#endif
+ return NULL;
+ t->flags |= hasLstat;
+ }
+ return (&t->lst);
+}
+
+/*
+ * Test whether current entry is a dir or link to a dir.
+ */
+static int
+tree_current_is_dir(struct tree *t)
+{
+ const struct stat *st;
+ /*
+ * If we already have lstat() info, then try some
+ * cheap tests to determine if this is a dir.
+ */
+ if (t->flags & hasLstat) {
+ /* If lstat() says it's a dir, it must be a dir. */
+ if (S_ISDIR(tree_current_lstat(t)->st_mode))
+ return 1;
+ /* Not a dir; might be a link to a dir. */
+ /* If it's not a link, then it's not a link to a dir. */
+ if (!S_ISLNK(tree_current_lstat(t)->st_mode))
+ return 0;
+ /*
+ * It's a link, but we don't know what it's a link to,
+ * so we'll have to use stat().
+ */
+ }
+
+ st = tree_current_stat(t);
+ /* If we can't stat it, it's not a dir. */
+ if (st == NULL)
+ return 0;
+ /* Use the definitive test. Hopefully this is cached. */
+ return (S_ISDIR(st->st_mode));
+}
+
+/*
+ * Test whether current entry is a physical directory. Usually, we
+ * already have at least one of stat() or lstat() in memory, so we
+ * use tricks to try to avoid an extra trip to the disk.
+ */
+static int
+tree_current_is_physical_dir(struct tree *t)
+{
+ const struct stat *st;
+
+ /*
+ * If stat() says it isn't a dir, then it's not a dir.
+ * If stat() data is cached, this check is free, so do it first.
+ */
+ if ((t->flags & hasStat)
+ && (!S_ISDIR(tree_current_stat(t)->st_mode)))
+ return 0;
+
+ /*
+ * Either stat() said it was a dir (in which case, we have
+ * to determine whether it's really a link to a dir) or
+ * stat() info wasn't available. So we use lstat(), which
+ * hopefully is already cached.
+ */
+
+ st = tree_current_lstat(t);
+ /* If we can't stat it, it's not a dir. */
+ if (st == NULL)
+ return 0;
+ /* Use the definitive test. Hopefully this is cached. */
+ return (S_ISDIR(st->st_mode));
+}
+
+/*
+ * Test whether the same file has been in the tree as its parent.
+ */
+static int
+tree_target_is_same_as_parent(struct tree *t, const struct stat *st)
+{
+ struct tree_entry *te;
+
+ for (te = t->current->parent; te != NULL; te = te->parent) {
+ if (te->dev == st->st_dev && te->ino == st->st_ino)
+ return (1);
+ }
+ return (0);
+}
+
+/*
+ * Test whether the current file is symbolic link target and
+ * on the other filesystem.
+ */
+static int
+tree_current_is_symblic_link_target(struct tree *t)
+{
+ static const struct stat *lst, *st;
+
+ lst = tree_current_lstat(t);
+ st = tree_current_stat(t);
+ return (st != NULL && st->st_dev == t->current_filesystem->dev &&
+ st->st_dev != lst->st_dev);
+}
+
+/*
+ * Return the access path for the entry just returned from tree_next().
+ */
+static const char *
+tree_current_access_path(struct tree *t)
+{
+ return (t->basename);
+}
+
+/*
+ * Return the full path for the entry just returned from tree_next().
+ */
+static const char *
+tree_current_path(struct tree *t)
+{
+ return (t->path.s);
+}
+
+/*
+ * Terminate the traversal.
+ */
+static void
+tree_close(struct tree *t)
+{
+
+ if (t == NULL)
+ return;
+ if (t->entry_fd >= 0) {
+ close_and_restore_time(t->entry_fd, t, &t->restore_time);
+ t->entry_fd = -1;
+ }
+ /* Close the handle of readdir(). */
+ if (t->d != INVALID_DIR_HANDLE) {
+ closedir(t->d);
+ t->d = INVALID_DIR_HANDLE;
+ }
+ /* Release anything remaining in the stack. */
+ while (t->stack != NULL) {
+ if (t->stack->flags & isDirLink)
+ close(t->stack->symlink_parent_fd);
+ tree_pop(t);
+ }
+ if (t->working_dir_fd >= 0) {
+ close(t->working_dir_fd);
+ t->working_dir_fd = -1;
+ }
+ if (t->initial_dir_fd >= 0) {
+ close(t->initial_dir_fd);
+ t->initial_dir_fd = -1;
+ }
+}
+
+/*
+ * Release any resources.
+ */
+static void
+tree_free(struct tree *t)
+{
+ int i;
+
+ if (t == NULL)
+ return;
+ archive_string_free(&t->path);
+#if defined(HAVE_READDIR_R)
+ free(t->dirent);
+#endif
+ free(t->sparse_list);
+ for (i = 0; i < t->max_filesystem_id; i++)
+ free(t->filesystem_table[i].allocation_ptr);
+ free(t->filesystem_table);
+ free(t);
+}
+
+#endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_disk_private.h b/Utilities/cmlibarchive/libarchive/archive_read_disk_private.h
new file mode 100644
index 000000000..4446474eb
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_disk_private.h
@@ -0,0 +1,71 @@
+/*-
+ * Copyright (c) 2003-2009 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
+ * in this position and unchanged.
+ * 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.
+ *
+ * $FreeBSD: head/lib/libarchive/archive_read_disk_private.h 201105 2009-12-28 03:20:54Z kientzle $
+ */
+
+#ifndef __LIBARCHIVE_BUILD
+#error This header is only to be used internally to libarchive.
+#endif
+
+#ifndef ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED
+#define ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED
+
+struct tree;
+
+struct archive_read_disk {
+ struct archive archive;
+
+ /*
+ * Symlink mode is one of 'L'ogical, 'P'hysical, or 'H'ybrid,
+ * following an old BSD convention. 'L' follows all symlinks,
+ * 'P' follows none, 'H' follows symlinks only for the first
+ * item.
+ */
+ char symlink_mode;
+
+ /*
+ * Since symlink interaction changes, we need to track whether
+ * we're following symlinks for the current item. 'L' mode above
+ * sets this true, 'P' sets it false, 'H' changes it as we traverse.
+ */
+ char follow_symlinks; /* Either 'L' or 'P'. */
+
+ /* Directory traversals. */
+ struct tree *tree;
+
+ /* Set 1 if users request to restore atime . */
+ int restore_time;
+ int entry_wd_fd;
+
+ const char * (*lookup_gname)(void *private, int64_t gid);
+ void (*cleanup_gname)(void *private);
+ void *lookup_gname_data;
+ const char * (*lookup_uname)(void *private, int64_t uid);
+ void (*cleanup_uname)(void *private);
+ void *lookup_uname_data;
+};
+
+#endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_disk_set_standard_lookup.c b/Utilities/cmlibarchive/libarchive/archive_read_disk_set_standard_lookup.c
new file mode 100644
index 000000000..3bc52c70d
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_disk_set_standard_lookup.c
@@ -0,0 +1,311 @@
+/*-
+ * 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: head/lib/libarchive/archive_read_disk_set_standard_lookup.c 201109 2009-12-28 03:30:31Z kientzle $");
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_GRP_H
+#include <grp.h>
+#endif
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include "archive.h"
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+int
+archive_read_disk_set_standard_lookup(struct archive *a)
+{
+ archive_set_error(a, -1, "Standard lookups not available on Windows");
+ return (ARCHIVE_FATAL);
+}
+#else /* ! (_WIN32 && !__CYGWIN__) */
+#define name_cache_size 127
+
+static const char * const NO_NAME = "(noname)";
+
+struct name_cache {
+ struct archive *archive;
+ char *buff;
+ size_t buff_size;
+ int probes;
+ int hits;
+ size_t size;
+ struct {
+ id_t id;
+ const char *name;
+ } cache[name_cache_size];
+};
+
+static const char * lookup_gname(void *, int64_t);
+static const char * lookup_uname(void *, int64_t);
+static void cleanup(void *);
+static const char * lookup_gname_helper(struct name_cache *, id_t gid);
+static const char * lookup_uname_helper(struct name_cache *, id_t uid);
+
+/*
+ * Installs functions that use getpwuid()/getgrgid()---along with
+ * 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
+ * it inappropriate for some space-constrained applications.
+ *
+ * Applications that are size-sensitive may want to just use the
+ * real default functions (defined in archive_read_disk.c) that just
+ * use the uid/gid without the lookup. Or define your own custom functions
+ * if you prefer.
+ */
+int
+archive_read_disk_set_standard_lookup(struct archive *a)
+{
+ struct name_cache *ucache = malloc(sizeof(struct name_cache));
+ struct name_cache *gcache = malloc(sizeof(struct name_cache));
+
+ if (ucache == NULL || gcache == NULL) {
+ archive_set_error(a, ENOMEM,
+ "Can't allocate uname/gname lookup cache");
+ free(ucache);
+ free(gcache);
+ return (ARCHIVE_FATAL);
+ }
+
+ memset(ucache, 0, sizeof(*ucache));
+ ucache->archive = a;
+ ucache->size = name_cache_size;
+ memset(gcache, 0, sizeof(*gcache));
+ gcache->archive = a;
+ gcache->size = name_cache_size;
+
+ archive_read_disk_set_gname_lookup(a, gcache, lookup_gname, cleanup);
+ archive_read_disk_set_uname_lookup(a, ucache, lookup_uname, cleanup);
+
+ return (ARCHIVE_OK);
+}
+
+static void
+cleanup(void *data)
+{
+ struct name_cache *cache = (struct name_cache *)data;
+ size_t i;
+
+ if (cache != NULL) {
+ for (i = 0; i < cache->size; i++) {
+ if (cache->cache[i].name != NULL &&
+ cache->cache[i].name != NO_NAME)
+ free((void *)(uintptr_t)cache->cache[i].name);
+ }
+ free(cache->buff);
+ free(cache);
+ }
+}
+
+/*
+ * Lookup uid/gid from uname/gname, return NULL if no match.
+ */
+static const char *
+lookup_name(struct name_cache *cache,
+ const char * (*lookup_fn)(struct name_cache *, id_t), id_t id)
+{
+ const char *name;
+ int slot;
+
+
+ cache->probes++;
+
+ slot = id % cache->size;
+ if (cache->cache[slot].name != NULL) {
+ if (cache->cache[slot].id == id) {
+ cache->hits++;
+ if (cache->cache[slot].name == NO_NAME)
+ return (NULL);
+ return (cache->cache[slot].name);
+ }
+ if (cache->cache[slot].name != NO_NAME)
+ free((void *)(uintptr_t)cache->cache[slot].name);
+ cache->cache[slot].name = NULL;
+ }
+
+ name = (lookup_fn)(cache, id);
+ if (name == NULL) {
+ /* Cache and return the negative response. */
+ cache->cache[slot].name = NO_NAME;
+ cache->cache[slot].id = id;
+ return (NULL);
+ }
+
+ cache->cache[slot].name = name;
+ cache->cache[slot].id = id;
+ return (cache->cache[slot].name);
+}
+
+static const char *
+lookup_uname(void *data, int64_t uid)
+{
+ struct name_cache *uname_cache = (struct name_cache *)data;
+ return (lookup_name(uname_cache,
+ &lookup_uname_helper, (id_t)uid));
+}
+
+#if HAVE_GETPWUID_R
+static const char *
+lookup_uname_helper(struct name_cache *cache, id_t id)
+{
+ struct passwd pwent, *result;
+ char * nbuff;
+ size_t nbuff_size;
+ int r;
+
+ if (cache->buff_size == 0) {
+ cache->buff_size = 256;
+ cache->buff = malloc(cache->buff_size);
+ }
+ if (cache->buff == NULL)
+ return (NULL);
+ for (;;) {
+ result = &pwent; /* Old getpwuid_r ignores last arg. */
+ r = getpwuid_r((uid_t)id, &pwent,
+ cache->buff, cache->buff_size, &result);
+ if (r == 0)
+ break;
+ if (r != ERANGE)
+ break;
+ /* ERANGE means our buffer was too small, but POSIX
+ * doesn't tell us how big the buffer should be, so
+ * we just double it and try again. Because the buffer
+ * is kept around in the cache object, we shouldn't
+ * have to do this very often. */
+ nbuff_size = cache->buff_size * 2;
+ nbuff = realloc(cache->buff, nbuff_size);
+ if (nbuff == NULL)
+ break;
+ cache->buff = nbuff;
+ cache->buff_size = nbuff_size;
+ }
+ if (r != 0) {
+ archive_set_error(cache->archive, errno,
+ "Can't lookup user for id %d", (int)id);
+ return (NULL);
+ }
+ if (result == NULL)
+ return (NULL);
+
+ return strdup(result->pw_name);
+}
+#else
+static const char *
+lookup_uname_helper(struct name_cache *cache, id_t id)
+{
+ struct passwd *result;
+
+ result = getpwuid((uid_t)id);
+
+ if (result == NULL)
+ return (NULL);
+
+ return strdup(result->pw_name);
+}
+#endif
+
+static const char *
+lookup_gname(void *data, int64_t gid)
+{
+ struct name_cache *gname_cache = (struct name_cache *)data;
+ return (lookup_name(gname_cache,
+ &lookup_gname_helper, (id_t)gid));
+}
+
+#if HAVE_GETGRGID_R
+static const char *
+lookup_gname_helper(struct name_cache *cache, id_t id)
+{
+ struct group grent, *result;
+ char * nbuff;
+ size_t nbuff_size;
+ int r;
+
+ if (cache->buff_size == 0) {
+ cache->buff_size = 256;
+ cache->buff = malloc(cache->buff_size);
+ }
+ if (cache->buff == NULL)
+ return (NULL);
+ for (;;) {
+ result = &grent; /* Old getgrgid_r ignores last arg. */
+ r = getgrgid_r((gid_t)id, &grent,
+ cache->buff, cache->buff_size, &result);
+ if (r == 0)
+ break;
+ if (r != ERANGE)
+ break;
+ /* ERANGE means our buffer was too small, but POSIX
+ * doesn't tell us how big the buffer should be, so
+ * we just double it and try again. */
+ nbuff_size = cache->buff_size * 2;
+ nbuff = realloc(cache->buff, nbuff_size);
+ if (nbuff == NULL)
+ break;
+ cache->buff = nbuff;
+ cache->buff_size = nbuff_size;
+ }
+ if (r != 0) {
+ archive_set_error(cache->archive, errno,
+ "Can't lookup group for id %d", (int)id);
+ return (NULL);
+ }
+ if (result == NULL)
+ return (NULL);
+
+ return strdup(result->gr_name);
+}
+#else
+static const char *
+lookup_gname_helper(struct name_cache *cache, id_t id)
+{
+ struct group *result;
+
+ result = getgrgid((gid_t)id);
+
+ if (result == NULL)
+ return (NULL);
+
+ return strdup(result->gr_name);
+}
+#endif
+
+#endif /* ! (_WIN32 && !__CYGWIN__) */
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_disk_windows.c b/Utilities/cmlibarchive/libarchive/archive_read_disk_windows.c
new file mode 100644
index 000000000..d8a1f5577
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_disk_windows.c
@@ -0,0 +1,1983 @@
+/*-
+ * Copyright (c) 2003-2009 Tim Kientzle
+ * Copyright (c) 2010-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
+ * in this position and unchanged.
+ * 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$");
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifdef HAVE_SYS_MOUNT_H
+#include <sys/mount.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_STATVFS_H
+#include <sys/statvfs.h>
+#endif
+#ifdef HAVE_SYS_VFS_H
+#include <sys/vfs.h>
+#endif
+#ifdef HAVE_LINUX_MAGIC_H
+#include <linux/magic.h>
+#endif
+#ifdef HAVE_DIRECT_H
+#include <direct.h>
+#endif
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if defined(HAVE_WINIOCTL_H) && !defined(__CYGWIN__)
+#include <winioctl.h>
+#endif
+
+#include "archive.h"
+#include "archive_string.h"
+#include "archive_entry.h"
+#include "archive_private.h"
+#include "archive_read_disk_private.h"
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+#ifndef IO_REPARSE_TAG_SYMLINK
+/* Old SDKs do not provide IO_REPARSE_TAG_SYMLINK */
+#define IO_REPARSE_TAG_SYMLINK 0xA000000CL
+#endif
+
+static BOOL SetFilePointerEx_perso(HANDLE hFile,
+ LARGE_INTEGER liDistanceToMove,
+ PLARGE_INTEGER lpNewFilePointer,
+ DWORD dwMoveMethod)
+{
+ LARGE_INTEGER li;
+ li.QuadPart = liDistanceToMove.QuadPart;
+ li.LowPart = SetFilePointer(
+ hFile, li.LowPart, &li.HighPart, dwMoveMethod);
+ if(lpNewFilePointer) {
+ lpNewFilePointer->QuadPart = li.QuadPart;
+ }
+ return li.LowPart != -1 || GetLastError() == NO_ERROR;
+}
+
+/*-
+ * This is a new directory-walking system that addresses a number
+ * of problems I've had with fts(3). In particular, it has no
+ * pathname-length limits (other than the size of 'int'), handles
+ * deep logical traversals, uses considerably less memory, and has
+ * an opaque interface (easier to modify in the future).
+ *
+ * Internally, it keeps a single list of "tree_entry" items that
+ * represent filesystem objects that require further attention.
+ * Non-directories are not kept in memory: they are pulled from
+ * readdir(), returned to the client, then freed as soon as possible.
+ * Any directory entry to be traversed gets pushed onto the stack.
+ *
+ * There is surprisingly little information that needs to be kept for
+ * each item on the stack. Just the name, depth (represented here as the
+ * string length of the parent directory's pathname), and some markers
+ * indicating how to get back to the parent (via chdir("..") for a
+ * regular dir or via fchdir(2) for a symlink).
+ */
+/*
+ * TODO:
+ * 1) Loop checking.
+ * 3) Arbitrary logical traversals by closing/reopening intermediate fds.
+ */
+
+struct restore_time {
+ const wchar_t *full_path;
+ FILETIME lastWriteTime;
+ FILETIME lastAccessTime;
+ mode_t filetype;
+};
+
+struct tree_entry {
+ int depth;
+ struct tree_entry *next;
+ struct tree_entry *parent;
+ size_t full_path_dir_length;
+ struct archive_wstring name;
+ struct archive_wstring full_path;
+ size_t dirname_length;
+ int64_t dev;
+ int64_t ino;
+ int flags;
+ int filesystem_id;
+ /* How to restore time of a directory. */
+ struct restore_time restore_time;
+};
+
+struct filesystem {
+ int64_t dev;
+ int synthetic;
+ int remote;
+};
+
+/* Definitions for tree_entry.flags bitmap. */
+#define isDir 1 /* This entry is a regular directory. */
+#define isDirLink 2 /* This entry is a symbolic link to a directory. */
+#define needsFirstVisit 4 /* This is an initial entry. */
+#define needsDescent 8 /* This entry needs to be previsited. */
+#define needsOpen 16 /* This is a directory that needs to be opened. */
+#define needsAscent 32 /* This entry needs to be postvisited. */
+
+/*
+ * On Windows, "first visit" is handled as a pattern to be handed to
+ * _findfirst(). This is consistent with Windows conventions that
+ * file patterns are handled within the application. On Posix,
+ * "first visit" is just returned to the client.
+ */
+
+/*
+ * Local data for this package.
+ */
+struct tree {
+ struct tree_entry *stack;
+ struct tree_entry *current;
+ HANDLE d;
+#define INVALID_DIR_HANDLE INVALID_HANDLE_VALUE
+ WIN32_FIND_DATAW _findData;
+ WIN32_FIND_DATAW *findData;
+ int flags;
+ int visit_type;
+ /* Error code from last failed operation. */
+ int tree_errno;
+
+ /* A full path with "\\?\" prefix. */
+ struct archive_wstring full_path;
+ size_t full_path_dir_length;
+ /* Dynamically-sized buffer for holding path */
+ struct archive_wstring path;
+
+ /* Last path element */
+ const wchar_t *basename;
+ /* Leading dir length */
+ size_t dirname_length;
+
+ int depth;
+
+ BY_HANDLE_FILE_INFORMATION lst;
+ BY_HANDLE_FILE_INFORMATION st;
+ int descend;
+ /* How to restore time of a file. */
+ struct restore_time restore_time;
+
+ struct entry_sparse {
+ int64_t length;
+ int64_t offset;
+ } *sparse_list, *current_sparse;
+ int sparse_count;
+ int sparse_list_size;
+
+ char initial_symlink_mode;
+ char symlink_mode;
+ struct filesystem *current_filesystem;
+ struct filesystem *filesystem_table;
+ int current_filesystem_id;
+ int max_filesystem_id;
+ int allocated_filesytem;
+
+ HANDLE entry_fh;
+ int entry_eof;
+ int64_t entry_remaining_bytes;
+ int64_t entry_total;
+ unsigned char *entry_buff;
+ size_t entry_buff_size;
+};
+
+#define bhfi_dev(bhfi) ((bhfi)->dwVolumeSerialNumber)
+/* Treat FileIndex as i-node. We should remove a sequence number
+ * which is high-16-bits of nFileIndexHigh. */
+#define bhfi_ino(bhfi) \
+ ((((int64_t)((bhfi)->nFileIndexHigh & 0x0000FFFFUL)) << 32) \
+ + (bhfi)->nFileIndexLow)
+
+/* Definitions for tree.flags bitmap. */
+#define hasStat 16 /* The st entry is valid. */
+#define hasLstat 32 /* The lst entry is valid. */
+#define needsRestoreTimes 128
+
+static int
+tree_dir_next_windows(struct tree *t, const wchar_t *pattern);
+
+#ifdef HAVE_DIRENT_D_NAMLEN
+/* BSD extension; avoids need for a strlen() call. */
+#define D_NAMELEN(dp) (dp)->d_namlen
+#else
+#define D_NAMELEN(dp) (strlen((dp)->d_name))
+#endif
+
+/* Initiate/terminate a tree traversal. */
+static struct tree *tree_open(const wchar_t *, int, int);
+static struct tree *tree_reopen(struct tree *, const wchar_t *, int);
+static void tree_close(struct tree *);
+static void tree_free(struct tree *);
+static void tree_push(struct tree *, const wchar_t *, const wchar_t *,
+ int, int64_t, int64_t, struct restore_time *);
+
+/*
+ * tree_next() returns Zero if there is no next entry, non-zero if
+ * there is. Note that directories are visited three times.
+ * Directories are always visited first as part of enumerating their
+ * parent; that is a "regular" visit. If tree_descend() is invoked at
+ * that time, the directory is added to a work list and will
+ * subsequently be visited two more times: once just after descending
+ * into the directory ("postdescent") and again just after ascending
+ * back to the parent ("postascent").
+ *
+ * TREE_ERROR_DIR is returned if the descent failed (because the
+ * directory couldn't be opened, for instance). This is returned
+ * instead of TREE_POSTDESCENT/TREE_POSTASCENT. TREE_ERROR_DIR is not a
+ * fatal error, but it does imply that the relevant subtree won't be
+ * visited. TREE_ERROR_FATAL is returned for an error that left the
+ * traversal completely hosed. Right now, this is only returned for
+ * chdir() failures during ascent.
+ */
+#define TREE_REGULAR 1
+#define TREE_POSTDESCENT 2
+#define TREE_POSTASCENT 3
+#define TREE_ERROR_DIR -1
+#define TREE_ERROR_FATAL -2
+
+static int tree_next(struct tree *);
+
+/*
+ * Return information about the current entry.
+ */
+
+/*
+ * The current full pathname, length of the full pathname, and a name
+ * that can be used to access the file. Because tree does use chdir
+ * extensively, the access path is almost never the same as the full
+ * current path.
+ *
+ */
+static const wchar_t *tree_current_path(struct tree *);
+static const wchar_t *tree_current_access_path(struct tree *);
+
+/*
+ * Request the lstat() or stat() data for the current path. Since the
+ * tree package needs to do some of this anyway, and caches the
+ * results, you should take advantage of it here if you need it rather
+ * than make a redundant stat() or lstat() call of your own.
+ */
+static const BY_HANDLE_FILE_INFORMATION *tree_current_stat(struct tree *);
+static const BY_HANDLE_FILE_INFORMATION *tree_current_lstat(struct tree *);
+
+/* The following functions use tricks to avoid a certain number of
+ * stat()/lstat() calls. */
+/* "is_physical_dir" is equivalent to S_ISDIR(tree_current_lstat()->st_mode) */
+static int tree_current_is_physical_dir(struct tree *);
+/* "is_physical_link" is equivalent to S_ISLNK(tree_current_lstat()->st_mode) */
+static int tree_current_is_physical_link(struct tree *);
+/* Instead of archive_entry_copy_stat for BY_HANDLE_FILE_INFORMATION */
+static void tree_archive_entry_copy_bhfi(struct archive_entry *,
+ struct tree *, const BY_HANDLE_FILE_INFORMATION *);
+/* "is_dir" is equivalent to S_ISDIR(tree_current_stat()->st_mode) */
+static int tree_current_is_dir(struct tree *);
+static int update_current_filesystem(struct archive_read_disk *a,
+ int64_t dev);
+static int setup_current_filesystem(struct archive_read_disk *);
+static int tree_target_is_same_as_parent(struct tree *,
+ const BY_HANDLE_FILE_INFORMATION *);
+
+static int _archive_read_disk_open_w(struct archive *, const wchar_t *);
+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_header2(struct archive *,
+ struct archive_entry *);
+static const char *trivial_lookup_gname(void *, int64_t gid);
+static const char *trivial_lookup_uname(void *, int64_t uid);
+static int setup_sparse(struct archive_read_disk *, struct archive_entry *);
+static int close_and_restore_time(HANDLE, struct tree *,
+ struct restore_time *);
+static int setup_sparse_from_disk(struct archive_read_disk *,
+ struct archive_entry *, HANDLE);
+
+
+
+static struct archive_vtable *
+archive_read_disk_vtable(void)
+{
+ static struct archive_vtable av;
+ static int inited = 0;
+
+ if (!inited) {
+ 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_header2 = _archive_read_next_header2;
+ inited = 1;
+ }
+ return (&av);
+}
+
+const char *
+archive_read_disk_gname(struct archive *_a, int64_t gid)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_gname"))
+ return (NULL);
+ if (a->lookup_gname == NULL)
+ return (NULL);
+ return ((*a->lookup_gname)(a->lookup_gname_data, gid));
+}
+
+const char *
+archive_read_disk_uname(struct archive *_a, int64_t uid)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_uname"))
+ return (NULL);
+ if (a->lookup_uname == NULL)
+ return (NULL);
+ return ((*a->lookup_uname)(a->lookup_uname_data, uid));
+}
+
+int
+archive_read_disk_set_gname_lookup(struct archive *_a,
+ void *private_data,
+ const char * (*lookup_gname)(void *private, int64_t gid),
+ void (*cleanup_gname)(void *private))
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_set_gname_lookup");
+
+ if (a->cleanup_gname != NULL && a->lookup_gname_data != NULL)
+ (a->cleanup_gname)(a->lookup_gname_data);
+
+ a->lookup_gname = lookup_gname;
+ a->cleanup_gname = cleanup_gname;
+ a->lookup_gname_data = private_data;
+ return (ARCHIVE_OK);
+}
+
+int
+archive_read_disk_set_uname_lookup(struct archive *_a,
+ void *private_data,
+ const char * (*lookup_uname)(void *private, int64_t uid),
+ void (*cleanup_uname)(void *private))
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_set_uname_lookup");
+
+ if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL)
+ (a->cleanup_uname)(a->lookup_uname_data);
+
+ a->lookup_uname = lookup_uname;
+ a->cleanup_uname = cleanup_uname;
+ a->lookup_uname_data = private_data;
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Create a new archive_read_disk object and initialize it with global state.
+ */
+struct archive *
+archive_read_disk_new(void)
+{
+ struct archive_read_disk *a;
+
+ a = (struct archive_read_disk *)malloc(sizeof(*a));
+ if (a == NULL)
+ return (NULL);
+ memset(a, 0, sizeof(*a));
+ a->archive.magic = ARCHIVE_READ_DISK_MAGIC;
+ a->archive.state = ARCHIVE_STATE_NEW;
+ a->archive.vtable = archive_read_disk_vtable();
+ a->lookup_uname = trivial_lookup_uname;
+ a->lookup_gname = trivial_lookup_gname;
+ a->entry_wd_fd = -1;
+ return (&a->archive);
+}
+
+static int
+_archive_read_free(struct archive *_a)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ int r;
+
+ if (_a == NULL)
+ return (ARCHIVE_OK);
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_free");
+
+ if (a->archive.state != ARCHIVE_STATE_CLOSED)
+ r = _archive_read_close(&a->archive);
+ else
+ r = ARCHIVE_OK;
+
+ tree_free(a->tree);
+ if (a->cleanup_gname != NULL && a->lookup_gname_data != NULL)
+ (a->cleanup_gname)(a->lookup_gname_data);
+ if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL)
+ (a->cleanup_uname)(a->lookup_uname_data);
+ archive_string_free(&a->archive.error_string);
+ a->archive.magic = 0;
+ free(a);
+ return (r);
+}
+
+static int
+_archive_read_close(struct archive *_a)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_close");
+
+ if (a->archive.state != ARCHIVE_STATE_FATAL)
+ a->archive.state = ARCHIVE_STATE_CLOSED;
+
+ tree_close(a->tree);
+
+ return (ARCHIVE_OK);
+}
+
+static void
+setup_symlink_mode(struct archive_read_disk *a, char symlink_mode,
+ int follow_symlinks)
+{
+ a->symlink_mode = symlink_mode;
+ a->follow_symlinks = follow_symlinks;
+ if (a->tree != NULL) {
+ a->tree->initial_symlink_mode = a->symlink_mode;
+ a->tree->symlink_mode = a->symlink_mode;
+ }
+}
+
+int
+archive_read_disk_set_symlink_logical(struct archive *_a)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_logical");
+ setup_symlink_mode(a, 'L', 1);
+ return (ARCHIVE_OK);
+}
+
+int
+archive_read_disk_set_symlink_physical(struct archive *_a)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_physical");
+ setup_symlink_mode(a, 'P', 0);
+ return (ARCHIVE_OK);
+}
+
+int
+archive_read_disk_set_symlink_hybrid(struct archive *_a)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_hybrid");
+ setup_symlink_mode(a, 'H', 1);/* Follow symlinks initially. */
+ return (ARCHIVE_OK);
+}
+
+int
+archive_read_disk_set_atime_restored(struct archive *_a)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_restore_atime");
+ a->restore_time = 1;
+ if (a->tree != NULL)
+ a->tree->flags |= needsRestoreTimes;
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Trivial implementations of gname/uname lookup functions.
+ * These are normally overridden by the client, but these stub
+ * versions ensure that we always have something that works.
+ */
+static const char *
+trivial_lookup_gname(void *private_data, int64_t gid)
+{
+ (void)private_data; /* UNUSED */
+ (void)gid; /* UNUSED */
+ return (NULL);
+}
+
+static const char *
+trivial_lookup_uname(void *private_data, int64_t uid)
+{
+ (void)private_data; /* UNUSED */
+ (void)uid; /* UNUSED */
+ return (NULL);
+}
+
+static int
+_archive_read_data_block(struct archive *_a, const void **buff,
+ size_t *size, int64_t *offset)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ struct tree *t = a->tree;
+ int r;
+ int64_t bytes;
+ size_t buffbytes;
+
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
+ "archive_read_data_block");
+
+ if (t->entry_eof || t->entry_remaining_bytes <= 0) {
+ r = ARCHIVE_EOF;
+ goto abort_read_data;
+ }
+
+ /* Allocate read buffer. */
+ if (t->entry_buff == NULL) {
+ t->entry_buff = malloc(1024 * 64);
+ if (t->entry_buff == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Couldn't allocate memory");
+ r = ARCHIVE_FATAL;
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ goto abort_read_data;
+ }
+ t->entry_buff_size = 1024 * 64;
+ }
+
+ buffbytes = t->entry_buff_size;
+ if (buffbytes > t->current_sparse->length)
+ buffbytes = t->current_sparse->length;
+
+ /*
+ * Skip hole.
+ */
+ if (t->current_sparse->offset > t->entry_total) {
+ LARGE_INTEGER distance;
+ distance.QuadPart = t->current_sparse->offset;
+ if (!SetFilePointerEx_perso(t->entry_fh, distance, NULL, FILE_BEGIN)) {
+ DWORD lasterr;
+
+ lasterr = GetLastError();
+ if (lasterr == ERROR_ACCESS_DENIED)
+ errno = EBADF;
+ else
+ la_dosmaperr(lasterr);
+ archive_set_error(&a->archive, errno, "Seek error");
+ r = ARCHIVE_FATAL;
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ goto abort_read_data;
+ }
+ bytes = t->current_sparse->offset - t->entry_total;
+ t->entry_remaining_bytes -= bytes;
+ t->entry_total += bytes;
+ }
+ if (buffbytes > 0) {
+ DWORD bytes_read;
+ if (!ReadFile(t->entry_fh, t->entry_buff,
+ (uint32_t)buffbytes, &bytes_read, NULL)) {
+ DWORD lasterr;
+
+ lasterr = GetLastError();
+ if (lasterr == ERROR_NO_DATA)
+ errno = EAGAIN;
+ else if (lasterr == ERROR_ACCESS_DENIED)
+ errno = EBADF;
+ else
+ la_dosmaperr(lasterr);
+ archive_set_error(&a->archive, errno, "Read error");
+ r = ARCHIVE_FATAL;
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ goto abort_read_data;
+ }
+ bytes = bytes_read;
+ } else
+ bytes = 0;
+ if (bytes == 0) {
+ /* Get EOF */
+ t->entry_eof = 1;
+ r = ARCHIVE_EOF;
+ goto abort_read_data;
+ }
+ *buff = t->entry_buff;
+ *size = bytes;
+ *offset = t->entry_total;
+ t->entry_total += bytes;
+ t->entry_remaining_bytes -= bytes;
+ if (t->entry_remaining_bytes == 0) {
+ /* Close the current file descriptor */
+ close_and_restore_time(t->entry_fh, t, &t->restore_time);
+ t->entry_fh = INVALID_HANDLE_VALUE;
+ t->entry_eof = 1;
+ }
+ t->current_sparse->offset += bytes;
+ t->current_sparse->length -= bytes;
+ if (t->current_sparse->length == 0 && !t->entry_eof)
+ t->current_sparse++;
+ return (ARCHIVE_OK);
+
+abort_read_data:
+ *buff = NULL;
+ *size = 0;
+ *offset = t->entry_total;
+ if (t->entry_fh != INVALID_HANDLE_VALUE) {
+ /* Close the current file descriptor */
+ close_and_restore_time(t->entry_fh, t, &t->restore_time);
+ t->entry_fh = INVALID_HANDLE_VALUE;
+ }
+ return (r);
+}
+
+static int
+_archive_read_next_header2(struct archive *_a, struct archive_entry *entry)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ struct tree *t;
+ const BY_HANDLE_FILE_INFORMATION *st;
+ const BY_HANDLE_FILE_INFORMATION *lst;
+ const char*name;
+ int descend, r;
+
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
+ "archive_read_next_header2");
+
+ t = a->tree;
+ if (t->entry_fh != INVALID_HANDLE_VALUE) {
+ close_and_restore_time(t->entry_fh, t, &t->restore_time);
+ t->entry_fh = INVALID_HANDLE_VALUE;
+ }
+ st = NULL;
+ lst = NULL;
+ do {
+ switch (tree_next(t)) {
+ case TREE_ERROR_FATAL:
+ archive_set_error(&a->archive, t->tree_errno,
+ "%ls: Unable to continue traversing directory tree",
+ tree_current_path(t));
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ return (ARCHIVE_FATAL);
+ case TREE_ERROR_DIR:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "%ls: Couldn't visit directory",
+ tree_current_path(t));
+ return (ARCHIVE_FAILED);
+ case 0:
+ return (ARCHIVE_EOF);
+ case TREE_POSTDESCENT:
+ case TREE_POSTASCENT:
+ break;
+ case TREE_REGULAR:
+ lst = tree_current_lstat(t);
+ if (lst == NULL) {
+ archive_set_error(&a->archive, errno,
+ "%ls: Cannot stat",
+ tree_current_path(t));
+ return (ARCHIVE_FAILED);
+ }
+ break;
+ }
+ } while (lst == NULL);
+
+ /*
+ * Distinguish 'L'/'P'/'H' symlink following.
+ */
+ switch(t->symlink_mode) {
+ case 'H':
+ /* 'H': After the first item, rest like 'P'. */
+ t->symlink_mode = 'P';
+ /* 'H': First item (from command line) like 'L'. */
+ /* FALLTHROUGH */
+ case 'L':
+ /* 'L': Do descend through a symlink to dir. */
+ descend = tree_current_is_dir(t);
+ /* 'L': Follow symlinks to files. */
+ a->symlink_mode = 'L';
+ a->follow_symlinks = 1;
+ /* 'L': Archive symlinks as targets, if we can. */
+ st = tree_current_stat(t);
+ if (st != NULL && !tree_target_is_same_as_parent(t, st))
+ break;
+ /* If stat fails, we have a broken symlink;
+ * in that case, don't follow the link. */
+ /* FALLTHROUGH */
+ default:
+ /* 'P': Don't descend through a symlink to dir. */
+ descend = tree_current_is_physical_dir(t);
+ /* 'P': Don't follow symlinks to files. */
+ a->symlink_mode = 'P';
+ a->follow_symlinks = 0;
+ /* 'P': Archive symlinks as symlinks. */
+ st = lst;
+ break;
+ }
+
+ if (update_current_filesystem(a, bhfi_dev(st)) != ARCHIVE_OK) {
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ return (ARCHIVE_FATAL);
+ }
+ t->descend = descend;
+
+ archive_entry_copy_pathname_w(entry, tree_current_path(t));
+ archive_entry_copy_sourcepath_w(entry, tree_current_access_path(t));
+ tree_archive_entry_copy_bhfi(entry, t, st);
+
+ /* Save the times to be restored. */
+ t->restore_time.lastWriteTime = st->ftLastWriteTime;
+ t->restore_time.lastAccessTime = st->ftLastAccessTime;
+ t->restore_time.filetype = archive_entry_filetype(entry);
+
+ /* Lookup uname/gname */
+ name = archive_read_disk_uname(_a, archive_entry_uid(entry));
+ if (name != NULL)
+ archive_entry_copy_uname(entry, name);
+ name = archive_read_disk_gname(_a, archive_entry_gid(entry));
+ if (name != NULL)
+ archive_entry_copy_gname(entry, name);
+
+ r = ARCHIVE_OK;
+ if (archive_entry_filetype(entry) == AE_IFREG &&
+ archive_entry_size(entry) > 0) {
+ t->entry_fh = CreateFileW(tree_current_access_path(t),
+ GENERIC_READ, 0, NULL, OPEN_EXISTING,
+ FILE_FLAG_SEQUENTIAL_SCAN, NULL);
+ if (t->entry_fh == INVALID_HANDLE_VALUE) {
+ archive_set_error(&a->archive, errno,
+ "Couldn't open %ls", tree_current_path(a->tree));
+ return (ARCHIVE_FAILED);
+ }
+
+ /* Find sparse data from the disk. */
+ if (archive_entry_hardlink(entry) == NULL &&
+ (st->dwFileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) != 0)
+ r = setup_sparse_from_disk(a, entry, t->entry_fh);
+ }
+
+ /*
+ * EOF and FATAL are persistent at this layer. By
+ * modifying the state, we guarantee that future calls to
+ * read a header or read data will fail.
+ */
+ switch (r) {
+ case ARCHIVE_EOF:
+ a->archive.state = ARCHIVE_STATE_EOF;
+ break;
+ case ARCHIVE_OK:
+ case ARCHIVE_WARN:
+ t->entry_total = 0;
+ if (archive_entry_filetype(entry) == AE_IFREG) {
+ t->entry_remaining_bytes = archive_entry_size(entry);
+ t->entry_eof = (t->entry_remaining_bytes == 0)? 1: 0;
+ if (!t->entry_eof &&
+ setup_sparse(a, entry) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ } else {
+ t->entry_remaining_bytes = 0;
+ t->entry_eof = 1;
+ }
+ a->archive.state = ARCHIVE_STATE_DATA;
+ break;
+ case ARCHIVE_RETRY:
+ break;
+ case ARCHIVE_FATAL:
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ break;
+ }
+
+ return (r);
+}
+
+static int
+setup_sparse(struct archive_read_disk *a, struct archive_entry *entry)
+{
+ struct tree *t = a->tree;
+ int64_t length, offset;
+ int i;
+
+ t->sparse_count = archive_entry_sparse_reset(entry);
+ if (t->sparse_count+1 > t->sparse_list_size) {
+ free(t->sparse_list);
+ t->sparse_list_size = t->sparse_count + 1;
+ t->sparse_list = malloc(sizeof(t->sparse_list[0]) *
+ t->sparse_list_size);
+ if (t->sparse_list == NULL) {
+ t->sparse_list_size = 0;
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate data");
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ return (ARCHIVE_FATAL);
+ }
+ }
+ for (i = 0; i < t->sparse_count; i++) {
+ archive_entry_sparse_next(entry, &offset, &length);
+ t->sparse_list[i].offset = offset;
+ t->sparse_list[i].length = length;
+ }
+ if (i == 0) {
+ t->sparse_list[i].offset = 0;
+ t->sparse_list[i].length = archive_entry_size(entry);
+ } else {
+ t->sparse_list[i].offset = archive_entry_size(entry);
+ t->sparse_list[i].length = 0;
+ }
+ t->current_sparse = t->sparse_list;
+
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Called by the client to mark the directory just returned from
+ * tree_next() as needing to be visited.
+ */
+int
+archive_read_disk_descend(struct archive *_a)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ struct tree *t = a->tree;
+
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
+ "archive_read_disk_descend");
+
+ if (t->visit_type != TREE_REGULAR || !t->descend) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Ignored the request descending the current object");
+ return (ARCHIVE_WARN);
+ }
+
+ if (tree_current_is_physical_dir(t)) {
+ tree_push(t, t->basename, t->full_path.s,
+ t->current_filesystem_id,
+ bhfi_dev(&(t->lst)), bhfi_ino(&(t->lst)),
+ &t->restore_time);
+ t->stack->flags |= isDir;
+ } else if (tree_current_is_dir(t)) {
+ tree_push(t, t->basename, t->full_path.s,
+ t->current_filesystem_id,
+ bhfi_dev(&(t->st)), bhfi_ino(&(t->st)),
+ &t->restore_time);
+ t->stack->flags |= isDirLink;
+ }
+ t->descend = 0;
+ return (ARCHIVE_OK);
+}
+
+int
+archive_read_disk_open(struct archive *_a, const char *pathname)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ struct archive_wstring wpath;
+ int ret;
+
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_NEW | ARCHIVE_STATE_CLOSED,
+ "archive_read_disk_open");
+ archive_clear_error(&a->archive);
+
+ /* Make a wchar_t string from a char string. */
+ archive_string_init(&wpath);
+ if (archive_wstring_append_from_mbs(&wpath, pathname,
+ strlen(pathname)) != 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Can't convert a path to a wchar_t string");
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ ret = ARCHIVE_FATAL;
+ } else
+ ret = _archive_read_disk_open_w(_a, wpath.s);
+
+ archive_wstring_free(&wpath);
+ return (ret);
+}
+
+int
+archive_read_disk_open_w(struct archive *_a, const wchar_t *pathname)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_NEW | ARCHIVE_STATE_CLOSED,
+ "archive_read_disk_open_w");
+ archive_clear_error(&a->archive);
+
+ return (_archive_read_disk_open_w(_a, pathname));
+}
+
+static int
+_archive_read_disk_open_w(struct archive *_a, const wchar_t *pathname)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+
+ if (a->tree != NULL)
+ a->tree = tree_reopen(a->tree, pathname, a->restore_time);
+ else
+ a->tree = tree_open(pathname, a->symlink_mode, a->restore_time);
+ if (a->tree == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate direcotry traversal data");
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ return (ARCHIVE_FATAL);
+ }
+ a->archive.state = ARCHIVE_STATE_HEADER;
+
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Return a current filesystem ID which is index of the filesystem entry
+ * you've visited through archive_read_disk.
+ */
+int
+archive_read_disk_current_filesystem(struct archive *_a)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
+ "archive_read_disk_current_filesystem");
+
+ return (a->tree->current_filesystem_id);
+}
+
+static int
+update_current_filesystem(struct archive_read_disk *a, int64_t dev)
+{
+ struct tree *t = a->tree;
+ int i, fid;
+
+ if (t->current_filesystem != NULL &&
+ t->current_filesystem->dev == dev)
+ return (ARCHIVE_OK);
+
+ for (i = 0; i < t->max_filesystem_id; i++) {
+ if (t->filesystem_table[i].dev == dev) {
+ /* There is the filesytem ID we've already generated. */
+ t->current_filesystem_id = i;
+ t->current_filesystem = &(t->filesystem_table[i]);
+ return (ARCHIVE_OK);
+ }
+ }
+
+ /*
+ * There is a new filesytem, we generate a new ID for.
+ */
+ fid = t->max_filesystem_id++;
+ if (t->max_filesystem_id > t->allocated_filesytem) {
+ size_t s;
+
+ s = t->max_filesystem_id * 2;
+ t->filesystem_table = realloc(t->filesystem_table,
+ s * sizeof(*t->filesystem_table));
+ if (t->filesystem_table == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate tar data");
+ return (ARCHIVE_FATAL);
+ }
+ t->allocated_filesytem = s;
+ }
+ t->current_filesystem_id = fid;
+ t->current_filesystem = &(t->filesystem_table[fid]);
+ t->current_filesystem->dev = dev;
+
+ return (setup_current_filesystem(a));
+}
+
+/*
+ * Returns 1 if current filesystem is generated filesystem, 0 if it is not
+ * or -1 if it is unknown.
+ */
+int
+archive_read_disk_current_filesystem_is_synthetic(struct archive *_a)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
+ "archive_read_disk_current_filesystem");
+
+ return (a->tree->current_filesystem->synthetic);
+}
+
+/*
+ * Returns 1 if current filesystem is remote filesystem, 0 if it is not
+ * or -1 if it is unknown.
+ */
+int
+archive_read_disk_current_filesystem_is_remote(struct archive *_a)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
+ "archive_read_disk_current_filesystem");
+
+ return (a->tree->current_filesystem->remote);
+}
+
+/*
+ * If symlink is broken, statfs or statvfs will fail.
+ * Use its directory path instead.
+ */
+static wchar_t *
+safe_path_for_statfs(struct tree *t)
+{
+ const wchar_t *path;
+ wchar_t *cp, *p = NULL;
+
+ path = tree_current_access_path(t);
+ if (tree_current_stat(t) == NULL) {
+ p = _wcsdup(path);
+ cp = wcsrchr(p, '/');
+ if (cp != NULL && wcslen(cp) >= 2) {
+ cp[1] = '.';
+ cp[2] = '\0';
+ path = p;
+ }
+ } else
+ p = _wcsdup(path);
+ return (p);
+}
+
+/*
+ * Get conditions of synthetic and remote on Windows
+ */
+static int
+setup_current_filesystem(struct archive_read_disk *a)
+{
+ struct tree *t = a->tree;
+ wchar_t vol[256];
+ wchar_t *path;
+
+ t->current_filesystem->synthetic = -1;/* Not supported */
+ path = safe_path_for_statfs(t);
+ if (!GetVolumePathNameW(path, vol, sizeof(vol)/sizeof(vol[0]))) {
+ free(path);
+ t->current_filesystem->remote = -1;
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "GetVolumePathName failed: %d", (int)GetLastError());
+ return (ARCHIVE_FAILED);
+ }
+ free(path);
+ switch (GetDriveTypeW(vol)) {
+ case DRIVE_UNKNOWN:
+ case DRIVE_NO_ROOT_DIR:
+ t->current_filesystem->remote = -1;
+ break;
+ case DRIVE_REMOTE:
+ t->current_filesystem->remote = 1;
+ break;
+ default:
+ t->current_filesystem->remote = 0;
+ break;
+ }
+
+ return (ARCHIVE_OK);
+}
+
+static int
+close_and_restore_time(HANDLE h, struct tree *t, struct restore_time *rt)
+{
+ HANDLE handle;
+ int r = 0;
+
+ if (h == INVALID_HANDLE_VALUE && AE_IFLNK == rt->filetype)
+ return (0);
+
+ /* Close a file descritor.
+ * It will not be used for SetFileTime() because it has been opened
+ * by a read only mode.
+ */
+ if (h != INVALID_HANDLE_VALUE)
+ CloseHandle(h);
+ if ((t->flags & needsRestoreTimes) == 0)
+ return (r);
+
+ handle = CreateFileW(rt->full_path, FILE_WRITE_ATTRIBUTES,
+ 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ if (handle == INVALID_HANDLE_VALUE) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ if (SetFileTime(handle, NULL, &rt->lastAccessTime,
+ &rt->lastWriteTime) == 0) {
+ errno = EINVAL;
+ r = -1;
+ } else
+ r = 0;
+ CloseHandle(handle);
+ return (r);
+}
+
+/*
+ * Add a directory path to the current stack.
+ */
+static void
+tree_push(struct tree *t, const wchar_t *path, const wchar_t *full_path,
+ int filesystem_id, int64_t dev, int64_t ino, struct restore_time *rt)
+{
+ struct tree_entry *te;
+
+ te = malloc(sizeof(*te));
+ memset(te, 0, sizeof(*te));
+ te->next = t->stack;
+ te->parent = t->current;
+ if (te->parent)
+ te->depth = te->parent->depth + 1;
+ t->stack = te;
+ archive_string_init(&te->name);
+ archive_wstrcpy(&te->name, path);
+ archive_string_init(&te->full_path);
+ archive_wstrcpy(&te->full_path, full_path);
+ te->flags = needsDescent | needsOpen | needsAscent;
+ te->filesystem_id = filesystem_id;
+ te->dev = dev;
+ te->ino = ino;
+ te->dirname_length = t->dirname_length;
+ te->full_path_dir_length = t->full_path_dir_length;
+ te->restore_time.full_path = te->full_path.s;
+ if (rt != NULL) {
+ te->restore_time.lastWriteTime = rt->lastWriteTime;
+ te->restore_time.lastAccessTime = rt->lastAccessTime;
+ te->restore_time.filetype = rt->filetype;
+ }
+}
+
+/*
+ * Append a name to the current dir path.
+ */
+static void
+tree_append(struct tree *t, const wchar_t *name, size_t name_length)
+{
+ size_t size_needed;
+
+ t->path.s[t->dirname_length] = L'\0';
+ t->path.length = t->dirname_length;
+ /* Strip trailing '/' from name, unless entire name is "/". */
+ while (name_length > 1 && name[name_length - 1] == L'/')
+ name_length--;
+
+ /* Resize pathname buffer as needed. */
+ size_needed = name_length + t->dirname_length + 2;
+ archive_wstring_ensure(&t->path, size_needed);
+ /* Add a separating '/' if it's needed. */
+ if (t->dirname_length > 0 &&
+ t->path.s[archive_strlen(&t->path)-1] != L'/')
+ archive_wstrappend_wchar(&t->path, L'/');
+ t->basename = t->path.s + archive_strlen(&t->path);
+ archive_wstrncat(&t->path, name, name_length);
+ t->restore_time.full_path = t->basename;
+ if (t->full_path_dir_length > 0) {
+ t->full_path.s[t->full_path_dir_length] = L'\0';
+ t->full_path.length = t->full_path_dir_length;
+ size_needed = name_length + t->full_path_dir_length + 2;
+ archive_wstring_ensure(&t->full_path, size_needed);
+ /* Add a separating '\' if it's needed. */
+ if (t->full_path.s[archive_strlen(&t->full_path)-1] != L'\\')
+ archive_wstrappend_wchar(&t->full_path, L'\\');
+ archive_wstrncat(&t->full_path, name, name_length);
+ t->restore_time.full_path = t->full_path.s;
+ }
+}
+
+/*
+ * Open a directory tree for traversal.
+ */
+static struct tree *
+tree_open(const wchar_t *path, int symlink_mode, int restore_time)
+{
+ struct tree *t;
+
+ t = malloc(sizeof(*t));
+ memset(t, 0, sizeof(*t));
+ archive_string_init(&(t->full_path));
+ archive_string_init(&t->path);
+ archive_wstring_ensure(&t->path, 15);
+ t->initial_symlink_mode = symlink_mode;
+ return (tree_reopen(t, path, restore_time));
+}
+
+static struct tree *
+tree_reopen(struct tree *t, const wchar_t *path, int restore_time)
+{
+ struct archive_wstring ws;
+ wchar_t *pathname, *p, *base;
+
+ t->flags = (restore_time)?needsRestoreTimes:0;
+ t->visit_type = 0;
+ t->tree_errno = 0;
+ t->full_path_dir_length = 0;
+ t->dirname_length = 0;
+ t->depth = 0;
+ t->descend = 0;
+ t->current = NULL;
+ t->d = INVALID_DIR_HANDLE;
+ t->symlink_mode = t->initial_symlink_mode;
+ archive_string_empty(&(t->full_path));
+ archive_string_empty(&t->path);
+ t->entry_fh = INVALID_HANDLE_VALUE;
+ t->entry_eof = 0;
+ t->entry_remaining_bytes = 0;
+
+ /* Get wchar_t strings from char strings. */
+ archive_string_init(&ws);
+ archive_wstrcpy(&ws, path);
+ pathname = ws.s;
+ /* Get a full-path-name. */
+ p = __la_win_permissive_name_w(pathname);
+ if (p == NULL)
+ goto failed;
+ archive_wstrcpy(&(t->full_path), p);
+ free(p);
+
+ /* Convert path separators from '\' to '/' */
+ for (p = pathname; *p != L'\0'; ++p) {
+ if (*p == L'\\')
+ *p = L'/';
+ }
+ base = pathname;
+
+ /* First item is set up a lot like a symlink traversal. */
+ /* printf("Looking for wildcard in %s\n", path); */
+ /* TODO: wildcard detection here screws up on \\?\c:\ UNC names */
+ if (wcschr(base, L'*') || wcschr(base, L'?')) {
+ // It has a wildcard in it...
+ // Separate the last element.
+ p = wcsrchr(base, L'/');
+ if (p != NULL) {
+ *p = L'\0';
+ tree_append(t, base, p - base);
+ t->dirname_length = archive_strlen(&t->path);
+ base = p + 1;
+ }
+ p = wcsrchr(t->full_path.s, L'\\');
+ if (p != NULL) {
+ *p = L'\0';
+ t->full_path.length = wcslen(t->full_path.s);
+ t->full_path_dir_length = archive_strlen(&t->full_path);
+ }
+ }
+ tree_push(t, base, t->full_path.s, 0, 0, 0, NULL);
+ archive_wstring_free(&ws);
+ t->stack->flags = needsFirstVisit;
+ return (t);
+failed:
+ archive_wstring_free(&ws);
+ tree_free(t);
+ return (NULL);
+}
+
+static int
+tree_descent(struct tree *t)
+{
+ t->dirname_length = archive_strlen(&t->path);
+ t->full_path_dir_length = archive_strlen(&t->full_path);
+ t->depth++;
+ return (0);
+}
+
+/*
+ * We've finished a directory; ascend back to the parent.
+ */
+static int
+tree_ascend(struct tree *t)
+{
+ struct tree_entry *te;
+
+ te = t->stack;
+ t->depth--;
+ close_and_restore_time(INVALID_DIR_HANDLE, t, &te->restore_time);
+ return (0);
+}
+
+/*
+ * Pop the working stack.
+ */
+static void
+tree_pop(struct tree *t)
+{
+ struct tree_entry *te;
+
+ t->full_path.s[t->full_path_dir_length] = L'\0';
+ t->full_path.length = t->full_path_dir_length;
+ t->path.s[t->dirname_length] = L'\0';
+ t->path.length = t->dirname_length;
+ if (t->stack == t->current && t->current != NULL)
+ t->current = t->current->parent;
+ te = t->stack;
+ t->stack = te->next;
+ t->dirname_length = te->dirname_length;
+ t->basename = t->path.s + t->dirname_length;
+ t->full_path_dir_length = te->full_path_dir_length;
+ while (t->basename[0] == L'/')
+ t->basename++;
+ archive_wstring_free(&te->name);
+ archive_wstring_free(&te->full_path);
+ free(te);
+}
+
+/*
+ * Get the next item in the tree traversal.
+ */
+static int
+tree_next(struct tree *t)
+{
+ int r;
+
+ while (t->stack != NULL) {
+ /* If there's an open dir, get the next entry from there. */
+ if (t->d != INVALID_DIR_HANDLE) {
+ r = tree_dir_next_windows(t, NULL);
+ if (r == 0)
+ continue;
+ return (r);
+ }
+
+ if (t->stack->flags & needsFirstVisit) {
+ wchar_t *d = t->stack->name.s;
+ t->stack->flags &= ~needsFirstVisit;
+ if (wcschr(d, L'*') || wcschr(d, L'?')) {
+ r = tree_dir_next_windows(t, d);
+ if (r == 0)
+ continue;
+ return (r);
+ } else {
+ HANDLE h = FindFirstFileW(d, &t->_findData);
+ if (h == INVALID_DIR_HANDLE) {
+ t->tree_errno = errno;
+ t->visit_type = TREE_ERROR_DIR;
+ return (t->visit_type);
+ }
+ t->findData = &t->_findData;
+ FindClose(h);
+ }
+ /* Top stack item needs a regular visit. */
+ t->current = t->stack;
+ tree_append(t, t->stack->name.s,
+ archive_strlen(&(t->stack->name)));
+ //t->dirname_length = t->path_length;
+ //tree_pop(t);
+ t->stack->flags &= ~needsFirstVisit;
+ return (t->visit_type = TREE_REGULAR);
+ } else if (t->stack->flags & needsDescent) {
+ /* Top stack item is dir to descend into. */
+ t->current = t->stack;
+ tree_append(t, t->stack->name.s,
+ archive_strlen(&(t->stack->name)));
+ t->stack->flags &= ~needsDescent;
+ r = tree_descent(t);
+ if (r != 0) {
+ tree_pop(t);
+ t->visit_type = r;
+ } else
+ t->visit_type = TREE_POSTDESCENT;
+ return (t->visit_type);
+ } else if (t->stack->flags & needsOpen) {
+ t->stack->flags &= ~needsOpen;
+ r = tree_dir_next_windows(t, L"*");
+ if (r == 0)
+ continue;
+ return (r);
+ } else if (t->stack->flags & needsAscent) {
+ /* Top stack item is dir and we're done with it. */
+ r = tree_ascend(t);
+ tree_pop(t);
+ t->visit_type = r != 0 ? r : TREE_POSTASCENT;
+ return (t->visit_type);
+ } else {
+ /* Top item on stack is dead. */
+ tree_pop(t);
+ t->flags &= ~hasLstat;
+ t->flags &= ~hasStat;
+ }
+ }
+ return (t->visit_type = 0);
+}
+
+static int
+tree_dir_next_windows(struct tree *t, const wchar_t *pattern)
+{
+ const wchar_t *name;
+ size_t namelen;
+ int r;
+
+ for (;;) {
+ if (pattern != NULL) {
+ struct archive_wstring pt;
+
+ archive_string_init(&pt);
+ archive_wstring_ensure(&pt,
+ archive_strlen(&(t->full_path))
+ + 2 + wcslen(pattern));
+ archive_wstring_copy(&pt, &(t->full_path));
+ archive_wstrappend_wchar(&pt, L'\\');
+ archive_wstrcat(&pt, pattern);
+ t->d = FindFirstFileW(pt.s, &t->_findData);
+ archive_wstring_free(&pt);
+ if (t->d == INVALID_DIR_HANDLE) {
+ r = tree_ascend(t); /* Undo "chdir" */
+ tree_pop(t);
+ t->tree_errno = errno;
+ t->visit_type = r != 0 ? r : TREE_ERROR_DIR;
+ return (t->visit_type);
+ }
+ t->findData = &t->_findData;
+ pattern = NULL;
+ } else if (!FindNextFileW(t->d, &t->_findData)) {
+ FindClose(t->d);
+ t->d = INVALID_DIR_HANDLE;
+ t->findData = NULL;
+ return (0);
+ }
+ name = t->findData->cFileName;
+ namelen = wcslen(name);
+ t->flags &= ~hasLstat;
+ t->flags &= ~hasStat;
+ if (name[0] == L'.' && name[1] == L'\0')
+ continue;
+ if (name[0] == L'.' && name[1] == L'.' && name[2] == L'\0')
+ continue;
+ tree_append(t, name, namelen);
+ return (t->visit_type = TREE_REGULAR);
+ }
+}
+
+#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
+static void
+fileTimeToUtc(const FILETIME *filetime, time_t *time, long *ns)
+{
+ ULARGE_INTEGER utc;
+
+ utc.HighPart = filetime->dwHighDateTime;
+ utc.LowPart = filetime->dwLowDateTime;
+ if (utc.QuadPart >= EPOC_TIME) {
+ utc.QuadPart -= EPOC_TIME;
+ /* milli seconds base */
+ *time = (time_t)(utc.QuadPart / 10000000);
+ /* nano seconds base */
+ *ns = (long)(utc.QuadPart % 10000000) * 100;
+ } else {
+ *time = 0;
+ *ns = 0;
+ }
+}
+
+static void
+entry_copy_bhfi(struct archive_entry *entry, const wchar_t *path,
+ const WIN32_FIND_DATAW *findData,
+ const BY_HANDLE_FILE_INFORMATION *bhfi)
+{
+ time_t secs;
+ long nsecs;
+ mode_t mode;
+
+ fileTimeToUtc(&bhfi->ftLastAccessTime, &secs, &nsecs);
+ archive_entry_set_atime(entry, secs, nsecs);
+ fileTimeToUtc(&bhfi->ftLastWriteTime, &secs, &nsecs);
+ archive_entry_set_mtime(entry, secs, nsecs);
+ fileTimeToUtc(&bhfi->ftCreationTime, &secs, &nsecs);
+ archive_entry_set_birthtime(entry, secs, nsecs);
+ archive_entry_set_ctime(entry, secs, nsecs);
+ archive_entry_set_dev(entry, bhfi_dev(bhfi));
+ archive_entry_set_ino64(entry, bhfi_ino(bhfi));
+ if (bhfi->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ archive_entry_set_nlink(entry, bhfi->nNumberOfLinks + 1);
+ else
+ archive_entry_set_nlink(entry, bhfi->nNumberOfLinks);
+ archive_entry_set_size(entry,
+ (((int64_t)bhfi->nFileSizeHigh) << 32)
+ + bhfi->nFileSizeLow);
+ archive_entry_set_uid(entry, 0);
+ archive_entry_set_gid(entry, 0);
+ archive_entry_set_rdev(entry, 0);
+
+ mode = S_IRUSR | S_IRGRP | S_IROTH;
+ if ((bhfi->dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0)
+ mode |= S_IWUSR | S_IWGRP | S_IWOTH;
+ if ((bhfi->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
+ findData != NULL &&
+ findData->dwReserved0 == IO_REPARSE_TAG_SYMLINK)
+ mode |= S_IFLNK;
+ else if (bhfi->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
+ else {
+ const wchar_t *p;
+
+ mode |= S_IFREG;
+ p = wcsrchr(path, L'.');
+ if (p != NULL && wcslen(p) == 4) {
+ switch (p[1]) {
+ case L'B': case L'b':
+ if ((p[2] == L'A' || p[2] == L'a' ) &&
+ (p[3] == L'T' || p[3] == L't' ))
+ mode |= S_IXUSR | S_IXGRP | S_IXOTH;
+ 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;
+ case L'E': case L'e':
+ if ((p[2] == L'X' || p[2] == L'x' ) &&
+ (p[3] == L'E' || p[3] == L'e' ))
+ mode |= S_IXUSR | S_IXGRP | S_IXOTH;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ archive_entry_set_mode(entry, mode);
+}
+
+static void
+tree_archive_entry_copy_bhfi(struct archive_entry *entry, struct tree *t,
+ const BY_HANDLE_FILE_INFORMATION *bhfi)
+{
+ entry_copy_bhfi(entry, tree_current_path(t), t->findData, bhfi);
+}
+
+static int
+tree_current_file_information(struct tree *t, BY_HANDLE_FILE_INFORMATION *st,
+ int sim_lstat)
+{
+ HANDLE h;
+ int r;
+ DWORD flag = FILE_FLAG_BACKUP_SEMANTICS;
+
+ 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,
+ OPEN_EXISTING, flag, NULL);
+ if (h == INVALID_HANDLE_VALUE)
+ return (0);
+ r = GetFileInformationByHandle(h, st);
+ CloseHandle(h);
+ return (r);
+}
+
+/*
+ * Get the stat() data for the entry just returned from tree_next().
+ */
+static const BY_HANDLE_FILE_INFORMATION *
+tree_current_stat(struct tree *t)
+{
+ if (!(t->flags & hasStat)) {
+ if (!tree_current_file_information(t, &t->st, 0))
+ return NULL;
+ t->flags |= hasStat;
+ }
+ return (&t->st);
+}
+
+/*
+ * Get the lstat() data for the entry just returned from tree_next().
+ */
+static const BY_HANDLE_FILE_INFORMATION *
+tree_current_lstat(struct tree *t)
+{
+ if (!(t->flags & hasLstat)) {
+ if (!tree_current_file_information(t, &t->lst, 1))
+ return NULL;
+ t->flags |= hasLstat;
+ }
+ return (&t->lst);
+}
+
+/*
+ * Test whether current entry is a dir or link to a dir.
+ */
+static int
+tree_current_is_dir(struct tree *t)
+{
+ if (t->findData)
+ return (t->findData->dwFileAttributes
+ & FILE_ATTRIBUTE_DIRECTORY);
+ return (0);
+}
+
+/*
+ * Test whether current entry is a physical directory. Usually, we
+ * already have at least one of stat() or lstat() in memory, so we
+ * use tricks to try to avoid an extra trip to the disk.
+ */
+static int
+tree_current_is_physical_dir(struct tree *t)
+{
+ if (tree_current_is_physical_link(t))
+ return (0);
+ return (tree_current_is_dir(t));
+}
+
+/*
+ * Test whether current entry is a symbolic link.
+ */
+static int
+tree_current_is_physical_link(struct tree *t)
+{
+ if (t->findData)
+ return ((t->findData->dwFileAttributes
+ & FILE_ATTRIBUTE_REPARSE_POINT) &&
+ (t->findData->dwReserved0
+ == IO_REPARSE_TAG_SYMLINK));
+ return (0);
+}
+
+/*
+ * Test whether the same file has been in the tree as its parent.
+ */
+static int
+tree_target_is_same_as_parent(struct tree *t,
+ const BY_HANDLE_FILE_INFORMATION *st)
+{
+ struct tree_entry *te;
+ int64_t dev = bhfi_dev(st);
+ int64_t ino = bhfi_ino(st);
+
+ for (te = t->current->parent; te != NULL; te = te->parent) {
+ if (te->dev == dev && te->ino == ino)
+ return (1);
+ }
+ return (0);
+}
+
+/*
+ * Return the access path for the entry just returned from tree_next().
+ */
+static const wchar_t *
+tree_current_access_path(struct tree *t)
+{
+ return (t->full_path.s);
+}
+
+/*
+ * Return the full path for the entry just returned from tree_next().
+ */
+static const wchar_t *
+tree_current_path(struct tree *t)
+{
+ return (t->path.s);
+}
+
+/*
+ * Terminate the traversal.
+ */
+static void
+tree_close(struct tree *t)
+{
+
+ if (t == NULL)
+ return;
+ if (t->entry_fh != INVALID_HANDLE_VALUE) {
+ close_and_restore_time(t->entry_fh, t, &t->restore_time);
+ t->entry_fh = INVALID_HANDLE_VALUE;
+ }
+ /* Close the handle of FindFirstFileW */
+ if (t->d != INVALID_DIR_HANDLE) {
+ FindClose(t->d);
+ t->d = INVALID_DIR_HANDLE;
+ t->findData = NULL;
+ }
+ /* Release anything remaining in the stack. */
+ while (t->stack != NULL)
+ tree_pop(t);
+}
+
+/*
+ * Release any resources.
+ */
+static void
+tree_free(struct tree *t)
+{
+ if (t == NULL)
+ return;
+ archive_wstring_free(&t->path);
+ archive_wstring_free(&t->full_path);
+ free(t->sparse_list);
+ free(t->filesystem_table);
+ free(t->entry_buff);
+ free(t);
+}
+
+
+/*
+ * Populate the archive_entry with metadata from the disk.
+ */
+int
+archive_read_disk_entry_from_file(struct archive *_a,
+ struct archive_entry *entry, int fd, const struct stat *st)
+{
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ const wchar_t *path;
+ const wchar_t *wname;
+ const char *name;
+ HANDLE h;
+ BY_HANDLE_FILE_INFORMATION bhfi;
+ DWORD fileAttributes = 0;
+ int r;
+
+ archive_clear_error(_a);
+ wname = archive_entry_sourcepath_w(entry);
+ if (wname == NULL)
+ wname = archive_entry_pathname_w(entry);
+ if (wname == NULL) {
+ archive_set_error(&a->archive, EINVAL,
+ "Can't get a wide character version of the path");
+ return (ARCHIVE_FAILED);
+ }
+ path = __la_win_permissive_name_w(wname);
+
+ if (st == NULL) {
+ /*
+ * Get metadata through GetFileInformationByHandle().
+ */
+ if (fd >= 0) {
+ h = (HANDLE)_get_osfhandle(fd);
+ r = GetFileInformationByHandle(h, &bhfi);
+ if (r == 0) {
+ archive_set_error(&a->archive, GetLastError(),
+ "Can't GetFileInformationByHandle");
+ return (ARCHIVE_FAILED);
+ }
+ entry_copy_bhfi(entry, path, NULL, &bhfi);
+ } else {
+ WIN32_FIND_DATAW findData;
+ DWORD flag, desiredAccess;
+
+ h = FindFirstFileW(path, &findData);
+ if (h == INVALID_DIR_HANDLE) {
+ archive_set_error(&a->archive, GetLastError(),
+ "Can't FindFirstFileW");
+ return (ARCHIVE_FAILED);
+ }
+ FindClose(h);
+
+ flag = FILE_FLAG_BACKUP_SEMANTICS;
+ if (!a->follow_symlinks &&
+ (findData.dwFileAttributes
+ & FILE_ATTRIBUTE_REPARSE_POINT) &&
+ (findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK)) {
+ flag |= FILE_FLAG_OPEN_REPARSE_POINT;
+ desiredAccess = 0;
+ } else if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+ desiredAccess = 0;
+ } else
+ desiredAccess = GENERIC_READ;
+
+ h = CreateFileW(path, desiredAccess, 0, NULL,
+ OPEN_EXISTING, flag, NULL);
+ if (h == INVALID_HANDLE_VALUE) {
+ archive_set_error(&a->archive,
+ GetLastError(),
+ "Can't CreateFileW");
+ return (ARCHIVE_FAILED);
+ }
+ r = GetFileInformationByHandle(h, &bhfi);
+ if (r == 0) {
+ archive_set_error(&a->archive,
+ GetLastError(),
+ "Can't GetFileInformationByHandle");
+ CloseHandle(h);
+ return (ARCHIVE_FAILED);
+ }
+ entry_copy_bhfi(entry, path, &findData, &bhfi);
+ }
+ fileAttributes = bhfi.dwFileAttributes;
+ } else {
+ archive_entry_copy_stat(entry, st);
+ h = INVALID_DIR_HANDLE;
+ }
+
+ /* Lookup uname/gname */
+ name = archive_read_disk_uname(_a, archive_entry_uid(entry));
+ if (name != NULL)
+ archive_entry_copy_uname(entry, name);
+ name = archive_read_disk_gname(_a, archive_entry_gid(entry));
+ if (name != NULL)
+ archive_entry_copy_gname(entry, name);
+
+ /*
+ * Can this file be sparse file ?
+ */
+ if (archive_entry_filetype(entry) != AE_IFREG
+ || archive_entry_size(entry) <= 0
+ || archive_entry_hardlink(entry) != NULL) {
+ if (h != INVALID_HANDLE_VALUE && fd < 0)
+ CloseHandle(h);
+ return (ARCHIVE_OK);
+ }
+
+ if (h == INVALID_HANDLE_VALUE) {
+ if (fd >= 0) {
+ h = (HANDLE)_get_osfhandle(fd);
+ } else {
+ h = CreateFileW(path, GENERIC_READ, 0, NULL,
+ OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ if (h == INVALID_HANDLE_VALUE) {
+ archive_set_error(&a->archive, GetLastError(),
+ "Can't CreateFileW");
+ return (ARCHIVE_FAILED);
+ }
+ }
+ r = GetFileInformationByHandle(h, &bhfi);
+ if (r == 0) {
+ archive_set_error(&a->archive, GetLastError(),
+ "Can't GetFileInformationByHandle");
+ if (h != INVALID_HANDLE_VALUE && fd < 0)
+ CloseHandle(h);
+ return (ARCHIVE_FAILED);
+ }
+ fileAttributes = bhfi.dwFileAttributes;
+ }
+
+ /* Sparse file must be set a mark, FILE_ATTRIBUTE_SPARSE_FILE */
+ if ((fileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) == 0) {
+ if (fd < 0)
+ CloseHandle(h);
+ return (ARCHIVE_OK);
+ }
+
+ r = setup_sparse_from_disk(a, entry, h);
+ if (fd < 0)
+ CloseHandle(h);
+
+ return (r);
+}
+
+/*
+ * Windows sparse interface.
+ */
+#if defined(__MINGW32__) && !defined(FSCTL_QUERY_ALLOCATED_RANGES)
+#define FSCTL_QUERY_ALLOCATED_RANGES 0x940CF
+typedef struct {
+ LARGE_INTEGER FileOffset;
+ LARGE_INTEGER Length;
+} FILE_ALLOCATED_RANGE_BUFFER;
+#endif
+
+static int
+setup_sparse_from_disk(struct archive_read_disk *a,
+ struct archive_entry *entry, HANDLE handle)
+{
+ FILE_ALLOCATED_RANGE_BUFFER range, *outranges = NULL;
+ size_t outranges_size;
+ int64_t entry_size = archive_entry_size(entry);
+ int exit_sts = ARCHIVE_OK;
+
+ range.FileOffset.QuadPart = 0;
+ range.Length.QuadPart = entry_size;
+ outranges_size = 2048;
+ outranges = (FILE_ALLOCATED_RANGE_BUFFER *)malloc(outranges_size);
+ if (outranges == NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Couldn't allocate memory");
+ exit_sts = ARCHIVE_FATAL;
+ goto exit_setup_sparse;
+ }
+
+ for (;;) {
+ DWORD retbytes;
+ BOOL ret;
+
+ for (;;) {
+ ret = DeviceIoControl(handle,
+ FSCTL_QUERY_ALLOCATED_RANGES,
+ &range, sizeof(range), outranges,
+ outranges_size, &retbytes, NULL);
+ if (ret == 0 && GetLastError() == ERROR_MORE_DATA) {
+ free(outranges);
+ outranges_size *= 2;
+ outranges = (FILE_ALLOCATED_RANGE_BUFFER *)
+ malloc(outranges_size);
+ if (outranges == NULL) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Couldn't allocate memory");
+ exit_sts = ARCHIVE_FATAL;
+ goto exit_setup_sparse;
+ }
+ continue;
+ } else
+ break;
+ }
+ if (ret != 0) {
+ if (retbytes > 0) {
+ DWORD i, n;
+
+ n = retbytes / sizeof(outranges[0]);
+ if (n == 1 &&
+ outranges[0].FileOffset.QuadPart == 0 &&
+ outranges[0].Length.QuadPart == entry_size)
+ break;/* This is not sparse. */
+ for (i = 0; i < n; i++)
+ archive_entry_sparse_add_entry(entry,
+ outranges[i].FileOffset.QuadPart,
+ outranges[i].Length.QuadPart);
+ range.FileOffset.QuadPart =
+ outranges[n-1].FileOffset.QuadPart
+ + outranges[n-1].Length.QuadPart;
+ range.Length.QuadPart =
+ entry_size - range.FileOffset.QuadPart;
+ if (range.Length.QuadPart > 0)
+ continue;
+ } else {
+ /* The remaining data is hole. */
+ archive_entry_sparse_add_entry(entry,
+ range.FileOffset.QuadPart,
+ range.Length.QuadPart);
+ }
+ break;
+ } else {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "DeviceIoControl Failed: %lu", GetLastError());
+ exit_sts = ARCHIVE_FAILED;
+ goto exit_setup_sparse;
+ }
+ }
+exit_setup_sparse:
+ free(outranges);
+
+ return (exit_sts);
+}
+
+#endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_extract.3 b/Utilities/cmlibarchive/libarchive/archive_read_extract.3
new file mode 100644
index 000000000..882c6e199
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_extract.3
@@ -0,0 +1,135 @@
+.\" Copyright (c) 2003-2011 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 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 March 22, 2011
+.Dt ARCHIVE_READ_EXTRACT 3
+.Os
+.Sh NAME
+.Nm archive_read_extract ,
+.Nm archive_read_extract2 ,
+.Nm archive_read_extract_set_progress_callback
+.Nd functions for reading streaming archives
+.Sh SYNOPSIS
+.In archive.h
+.Ft int
+.Fo archive_read_extract
+.Fa "struct archive *"
+.Fa "struct archive_entry *"
+.Fa "int flags"
+.Fc
+.Ft int
+.Fo archive_read_extract2
+.Fa "struct archive *src"
+.Fa "struct archive_entry *"
+.Fa "struct archive *dest"
+.Fc
+.Ft void
+.Fo archive_read_extract_set_progress_callback
+.Fa "struct archive *"
+.Fa "void (*func)(void *)"
+.Fa "void *user_data"
+.Fc
+.Sh DESCRIPTION
+.Bl -tag -compact -width indent
+.It Fn archive_read_extract , Fn archive_read_extract_set_skip_file
+A convenience function that wraps the corresponding
+.Xr archive_write_disk 3
+interfaces.
+The first call to
+.Fn archive_read_extract
+creates a restore object using
+.Xr archive_write_disk_new 3
+and
+.Xr archive_write_disk_set_standard_lookup 3 ,
+then transparently invokes
+.Xr archive_write_disk_set_options 3 ,
+.Xr archive_write_header 3 ,
+.Xr archive_write_data 3 ,
+and
+.Xr archive_write_finish_entry 3
+to create the entry on disk and copy data into it.
+The
+.Va flags
+argument is passed unmodified to
+.Xr archive_write_disk_set_options 3 .
+.It Fn archive_read_extract2
+This is another version of
+.Fn archive_read_extract
+that allows you to provide your own restore object.
+In particular, this allows you to override the standard lookup functions
+using
+.Xr archive_write_disk_set_group_lookup 3 ,
+and
+.Xr archive_write_disk_set_user_lookup 3 .
+Note that
+.Fn archive_read_extract2
+does not accept a
+.Va flags
+argument; you should use
+.Fn archive_write_disk_set_options
+to set the restore options yourself.
+.It Fn archive_read_extract_set_progress_callback
+Sets a pointer to a user-defined callback that can be used
+for updating progress displays during extraction.
+The progress function will be invoked during the extraction of large
+regular files.
+The progress function will be invoked with the pointer provided to this call.
+Generally, the data pointed to should include a reference to the archive
+object and the archive_entry object so that various statistics
+can be retrieved for the progress display.
+.El
+.\"
+.Sh RETURN VALUES
+Most functions return zero on success, non-zero on error.
+The possible return codes include:
+.Cm ARCHIVE_OK
+(the operation succeeded),
+.Cm ARCHIVE_WARN
+(the operation succeeded but a non-critical error was encountered),
+.Cm ARCHIVE_EOF
+(end-of-archive was encountered),
+.Cm ARCHIVE_RETRY
+(the operation failed but can be retried),
+and
+.Cm ARCHIVE_FATAL
+(there was a fatal error; the archive should be closed immediately).
+.Sh ERRORS
+Detailed error codes and textual descriptions are available from the
+.Fn archive_errno
+and
+.Fn archive_error_string
+functions.
+.Sh SEE ALSO
+.Xr tar 1 ,
+.Xr libarchive 3 ,
+.Xr archive_read 3 ,
+.Xr archive_read_data 3 ,
+.Xr archive_read_filter 3 ,
+.Xr archive_read_format 3 ,
+.Xr archive_read_open 3 ,
+.Xr archive_read_set_options 3 ,
+.Xr archive_util 3 ,
+.Xr tar 5
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_extract.c b/Utilities/cmlibarchive/libarchive/archive_read_extract.c
new file mode 100644
index 000000000..aad8ac516
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_extract.c
@@ -0,0 +1,183 @@
+/*-
+ * 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_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;
+
+ extract = get_extract((struct archive_read *)_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 = 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);
+ }
+}
+
+/*
+ * 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);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_filter.3 b/Utilities/cmlibarchive/libarchive/archive_read_filter.3
new file mode 100644
index 000000000..1cfa21599
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_filter.3
@@ -0,0 +1,127 @@
+.\" Copyright (c) 2003-2011 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 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 March 19, 2011
+.Dt ARCHIVE_READ_FILTER 3
+.Os
+.Sh NAME
+.Nm archive_read_support_filter_all ,
+.Nm archive_read_support_filter_bzip2 ,
+.Nm archive_read_support_filter_compress ,
+.Nm archive_read_support_filter_gzip ,
+.Nm archive_read_support_filter_lzma ,
+.Nm archive_read_support_filter_none ,
+.Nm archive_read_support_filter_xz ,
+.Nm archive_read_support_filter_program ,
+.Nm archive_read_support_filter_program_signature
+.Nd functions for reading streaming archives
+.\"
+.Sh SYNOPSIS
+.In archive.h
+.Ft int
+.Fn archive_read_support_filter_all "struct archive *"
+.Ft int
+.Fn archive_read_support_filter_bzip2 "struct archive *"
+.Ft int
+.Fn archive_read_support_filter_compress "struct archive *"
+.Ft int
+.Fn archive_read_support_filter_gzip "struct archive *"
+.Ft int
+.Fn archive_read_support_filter_lzma "struct archive *"
+.Ft int
+.Fn archive_read_support_filter_none "struct archive *"
+.Ft int
+.Fn archive_read_support_filter_xz "struct archive *"
+.Ft int
+.Fo archive_read_support_filter_program
+.Fa "struct archive *"
+.Fa "const char *cmd"
+.Fc
+.Ft int
+.Fo archive_read_support_filter_program_signature
+.Fa "struct archive *"
+.Fa "const char *cmd"
+.Fa "const void *signature"
+.Fa "size_t signature_length"
+.Fc
+.\"
+.Sh DESCRIPTION
+.Bl -tag -compact -width indent
+.It Xo
+.Fn archive_read_support_filter_bzip2 ,
+.Fn archive_read_support_filter_compress ,
+.Fn archive_read_support_filter_gzip ,
+.Fn archive_read_support_filter_lzma ,
+.Fn archive_read_support_filter_none ,
+.Fn archive_read_support_filter_xz
+.Xc
+Enables auto-detection code and decompression support for the
+specified compression.
+These functions may fall back on external programs if an appropriate
+library was not available at build time.
+Decompression using an external program is usually slower than
+decompression through built-in libraries.
+Note that
+.Dq none
+is always enabled by default.
+.It Fn archive_read_support_filter_all
+Enables all available decompression filters.
+.It Fn archive_read_support_filter_program
+Data is fed through the specified external program before being dearchived.
+Note that this disables automatic detection of the compression format,
+so it makes no sense to specify this in conjunction with any other
+decompression option.
+.It Fn archive_read_support_filter_program_signature
+This feeds data through the specified external program
+but only if the initial bytes of the data match the specified
+signature value.
+.El
+.\"
+.\". Sh EXAMPLE
+.\"
+.Sh RETURN VALUES
+These functions return
+.Cm ARCHIVE_OK
+if the compression is fully supported,
+.Cm ARCHIVE_WARN
+if the compression is supported only through an external program.
+.Pp
+.Fn archive_read_support_filter_none
+always succeeds.
+.\"
+.Sh ERRORS
+Detailed error codes and textual descriptions are available from the
+.Fn archive_errno
+and
+.Fn archive_error_string
+functions.
+.\"
+.Sh SEE ALSO
+.Xr libarchive 3 ,
+.Xr archive_read 3 ,
+.Xr archive_read_data 3 ,
+.Xr archive_read_format 3 ,
+.Xr archive_read_format 3
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_format.3 b/Utilities/cmlibarchive/libarchive/archive_read_format.3
new file mode 100644
index 000000000..e707e05f6
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_format.3
@@ -0,0 +1,175 @@
+.\" Copyright (c) 2003-2011 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 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: head/lib/libarchive/archive_read.3 191595 2009-04-27 20:13:13Z kientzle $
+.\"
+.Dd March 19, 2011
+.Dt ARCHIVE_READ_FORMAT 3
+.Os
+.Sh NAME
+.Nm archive_read_support_format_7zip ,
+.Nm archive_read_support_format_all ,
+.Nm archive_read_support_format_ar ,
+.Nm archive_read_support_format_by_code ,
+.Nm archive_read_support_format_cab ,
+.Nm archive_read_support_format_cpio ,
+.Nm archive_read_support_format_empty ,
+.Nm archive_read_support_format_iso9660 ,
+.Nm archive_read_support_format_lha ,
+.Nm archive_read_support_format_mtree,
+.Nm archive_read_support_format_rar,
+.Nm archive_read_support_format_raw,
+.Nm archive_read_support_format_tar ,
+.Nm archive_read_support_format_xar ,
+.Nm archive_read_support_format_zip
+.Nd functions for reading streaming archives
+.\"
+.Sh SYNOPSIS
+.In archive.h
+.Ft int
+.Fn archive_read_support_format_7zip "struct archive *"
+.Ft int
+.Fn archive_read_support_format_all "struct archive *"
+.Ft int
+.Fn archive_read_support_format_ar "struct archive *"
+.Ft int
+.Fn archive_read_support_format_by_code "struct archive *" "int"
+.Ft int
+.Fn archive_read_support_format_cab "struct archive *"
+.Ft int
+.Fn archive_read_support_format_cpio "struct archive *"
+.Ft int
+.Fn archive_read_support_format_empty "struct archive *"
+.Ft int
+.Fn archive_read_support_format_iso9660 "struct archive *"
+.Ft int
+.Fn archive_read_support_format_lha "struct archive *"
+.Ft int
+.Fn archive_read_support_format_mtree "struct archive *"
+.Ft int
+.Fn archive_read_support_format_rar "struct archive *"
+.Ft int
+.Fn archive_read_support_format_raw "struct archive *"
+.Ft int
+.Fn archive_read_support_format_tar "struct archive *"
+.Ft int
+.Fn archive_read_support_format_xar "struct archive *"
+.Ft int
+.Fn archive_read_support_format_zip "struct archive *"
+.\"
+.Sh DESCRIPTION
+.Bl -tag -compact -width indent
+.It Xo
+.Fn archive_read_support_format_7zip ,
+.Fn archive_read_support_format_ar ,
+.Fn archive_read_support_format_cab ,
+.Fn archive_read_support_format_cpio ,
+.Fn archive_read_support_format_iso9660 ,
+.Fn archive_read_support_format_lha ,
+.Fn archive_read_support_format_mtree ,
+.Fn archive_read_support_format_rar ,
+.Fn archive_read_support_format_raw ,
+.Fn archive_read_support_format_tar ,
+.Fn archive_read_support_format_xar ,
+.Fn archive_read_support_format_zip
+.Xc
+Enables support---including auto-detection code---for the
+specified archive format.
+For example,
+.Fn archive_read_support_format_tar
+enables support for a variety of standard tar formats, old-style tar,
+ustar, pax interchange format, and many common variants.
+.It Fn archive_read_support_format_all
+Enables support for all available formats except the
+.Dq raw
+format (see below).
+.It Fn archive_read_support_format_by_code
+Enables a single format specified by the format code.
+This can be useful when reading a single archive twice;
+use
+.Fn archive_format
+after reading the first time and pass the resulting code
+to this function to selectively enable only the necessary
+format support.
+Note: In statically-linked executables, this will cause
+your program to include support for every format.
+If executable size is a concern, you may wish to avoid
+using this function.
+.It Fn archive_read_support_format_empty
+Enables support for treating empty files as empty archives.
+Because empty files are valid for several different formats,
+it is not possible to accurately determine a format for
+an empty file based purely on contents.
+So empty files are treated by libarchive as a distinct
+format.
+.It Fn archive_read_support_format_raw
+The
+.Dq raw
+format handler allows libarchive to be used to read arbitrary data.
+It treats any data stream as an archive with a single entry.
+The pathname of this entry is
+.Dq data ;
+all other entry fields are unset.
+This is not enabled by
+.Fn archive_read_support_format_all
+in order to avoid erroneous handling of damaged archives.
+.El
+.\" .Sh EXAMPLE
+.Sh RETURN VALUES
+These functions return
+.Cm ARCHIVE_OK
+on success, or
+.Cm ARCHIVE_FATAL .
+.\"
+.Sh ERRORS
+Detailed error codes and textual descriptions are available from the
+.Fn archive_errno
+and
+.Fn archive_error_string
+functions.
+.\"
+.Sh SEE ALSO
+.Xr tar 1 ,
+.Xr libarchive 3 ,
+.Xr archive_read_data 3 ,
+.Xr archive_read_filter 3 ,
+.Xr archive_read_set_options 3 ,
+.Xr archive_util 3 ,
+.Xr tar 5
+.Sh BUGS
+Many traditional archiver programs treat
+empty files as valid empty archives.
+For example, many implementations of
+.Xr tar 1
+allow you to append entries to an empty file.
+Of course, it is impossible to determine the format of an empty file
+by inspecting the contents, so this library treats empty files as
+having a special
+.Dq empty
+format.
+.Pp
+Using the
+.Dq raw
+handler together with any other handler will often work
+but can produce surprising results.
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_free.3 b/Utilities/cmlibarchive/libarchive/archive_read_free.3
new file mode 100644
index 000000000..f5f2515a8
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_free.3
@@ -0,0 +1,91 @@
+.\" Copyright (c) 2003-2011 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 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: head/lib/libarchive/archive_read.3 191595 2009-04-27 20:13:13Z kientzle $
+.\"
+.Dd March 20, 2011
+.Dt ARCHIVE_READ_FREE 3
+.Os
+.Sh NAME
+.Nm archive_read_close ,
+.Nm archive_read_finish ,
+.Nm archive_read_free
+.Nd functions for reading streaming archives
+.Sh SYNOPSIS
+.In archive.h
+.Ft int
+.Fn archive_read_close "struct archive *"
+.Ft int
+.Fn archive_read_finish "struct archive *"
+.Ft int
+.Fn archive_read_free "struct archive *"
+.\"
+.Sh DESCRIPTION
+.Bl -tag -compact -width indent
+.It Fn archive_read_close
+Complete the archive and invoke the close callback.
+.It Fn archive_read_finish
+This is a deprecated synonym for
+.Fn archive_read_free .
+The new name was introduced with libarchive 3.0.
+Applications that need to compile with either libarchive 2
+or libarchive 3 should continue to use the
+.Fn archive_read_finish
+name.
+Both names will be supported until libarchive 4.0 is
+released, which is not expected to occur earlier
+than 2013.
+.It Fn archive_read_free
+Invokes
+.Fn archive_read_close
+if it was not invoked manually, then release all resources.
+Note: In libarchive 1.x, this function was declared to return
+.Ft void ,
+which made it impossible to detect certain errors when
+.Fn archive_read_close
+was invoked implicitly from this function.
+The declaration is corrected beginning with libarchive 2.0.
+.El
+.Sh RETURN VALUES
+These functions return
+.Cm ARCHIVE_OK
+on success, or
+.Cm ARCHIVE_FATAL .
+.\"
+.Sh ERRORS
+Detailed error codes and textual descriptions are available from the
+.Fn archive_errno
+and
+.Fn archive_error_string
+functions.
+.\"
+.Sh SEE ALSO
+.Xr libarchive 3 ,
+.Xr archive_read_new 3 ,
+.Xr archive_read_data 3 ,
+.Xr archive_read_filter 3 ,
+.Xr archive_read_format 3 ,
+.Xr archive_read_open 3 ,
+.Xr archive_read_set_options 3 ,
+.Xr archive_util 3
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_header.3 b/Utilities/cmlibarchive/libarchive/archive_read_header.3
new file mode 100644
index 000000000..999e963cf
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_header.3
@@ -0,0 +1,89 @@
+.\" Copyright (c) 2003-2011 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 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 March 22, 2011
+.Dt ARCHIVE_READ_HEADER 3
+.Os
+.Sh NAME
+.Nm archive_read_next_header ,
+.Nm archive_read_next_header2
+.Nd functions for reading streaming archives
+.Sh SYNOPSIS
+.In archive.h
+.Ft int
+.Fn archive_read_next_header "struct archive *" "struct archive_entry **"
+.Ft int
+.Fn archive_read_next_header2 "struct archive *" "struct archive_entry *"
+.\"
+.Sh DESCRIPTION
+.Bl -tag -compact -width indent
+.It Fn archive_read_next_header
+Read the header for the next entry and return a pointer to
+a
+.Tn struct archive_entry .
+This is a convenience wrapper around
+.Fn archive_read_next_header2
+that reuses an internal
+.Tn struct archive_entry
+object for each request.
+.It Fn archive_read_next_header2
+Read the header for the next entry and populate the provided
+.Tn struct archive_entry .
+.El
+.\"
+.Sh RETURN VALUES
+These functions return
+.Cm ARCHIVE_OK
+(the operation succeeded),
+.Cm ARCHIVE_WARN
+(the operation succeeded but a non-critical error was encountered),
+.Cm ARCHIVE_EOF
+(end-of-archive was encountered),
+.Cm ARCHIVE_RETRY
+(the operation failed but can be retried),
+and
+.Cm ARCHIVE_FATAL
+(there was a fatal error; the archive should be closed immediately).
+.\"
+.Sh ERRORS
+Detailed error codes and textual descriptions are available from the
+.Fn archive_errno
+and
+.Fn archive_error_string
+functions.
+.\"
+.Sh SEE ALSO
+.Xr tar 1 ,
+.Xr libarchive 3 ,
+.Xr archive_read 3 ,
+.Xr archive_read_data 3 ,
+.Xr archive_read_extract 3 ,
+.Xr archive_read_filter 3 ,
+.Xr archive_read_format 3 ,
+.Xr archive_read_open 3 ,
+.Xr archive_read_set_options 3 ,
+.Xr archive_util 3 ,
+.Xr tar 5
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_new.3 b/Utilities/cmlibarchive/libarchive/archive_read_new.3
new file mode 100644
index 000000000..e04406aa6
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_new.3
@@ -0,0 +1,57 @@
+.\" Copyright (c) 2003-2011 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 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: head/lib/libarchive/archive_read.3 191595 2009-04-27 20:13:13Z kientzle $
+.\"
+.Dd March 20, 2011
+.Dt ARCHIVE_READ_NEW 3
+.Os
+.Sh NAME
+.Nm archive_read_new
+.Nd functions for reading streaming archives
+.Sh SYNOPSIS
+.In archive.h
+.Ft struct archive *
+.Fn archive_read_new "void"
+.Sh DESCRIPTION
+Allocates and initializes a
+.Tn struct archive
+object suitable for reading from an archive.
+.Dv NULL
+is returned on error.
+.Pp
+A complete description of the
+.Tn struct archive
+object can be found in the overview manual page for
+.Xr libarchive 3 .
+.\" .Sh ERRORS
+.Sh SEE ALSO
+.Xr tar 1 ,
+.Xr libarchive 3 ,
+.Xr archive_read_data 3 ,
+.Xr archive_read_filter 3 ,
+.Xr archive_read_format 3 ,
+.Xr archive_read_set_options 3 ,
+.Xr archive_util 3 ,
+.Xr tar 5
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_open.3 b/Utilities/cmlibarchive/libarchive/archive_read_open.3
new file mode 100644
index 000000000..09c057568
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_open.3
@@ -0,0 +1,231 @@
+.\" Copyright (c) 2003-2011 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 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: head/lib/libarchive/archive_read.3 191595 2009-04-27 20:13:13Z kientzle $
+.\"
+.Dd March 19, 2011
+.Dt ARCHIVE_READ_OPEN 3
+.Os
+.Sh NAME
+.Nm archive_read_open ,
+.Nm archive_read_open2 ,
+.Nm archive_read_open_fd ,
+.Nm archive_read_open_FILE ,
+.Nm archive_read_open_filename ,
+.Nm archive_read_open_memory ,
+.Nd functions for reading streaming archives
+.Sh SYNOPSIS
+.In archive.h
+.Ft int
+.Fo archive_read_open
+.Fa "struct archive *"
+.Fa "void *client_data"
+.Fa "archive_open_callback *"
+.Fa "archive_read_callback *"
+.Fa "archive_close_callback *"
+.Fc
+.Ft int
+.Fo archive_read_open2
+.Fa "struct archive *"
+.Fa "void *client_data"
+.Fa "archive_open_callback *"
+.Fa "archive_read_callback *"
+.Fa "archive_skip_callback *"
+.Fa "archive_close_callback *"
+.Fc
+.Ft int
+.Fn archive_read_open_FILE "struct archive *" "FILE *file"
+.Ft int
+.Fn archive_read_open_fd "struct archive *" "int fd" "size_t block_size"
+.Ft int
+.Fo archive_read_open_filename
+.Fa "struct archive *"
+.Fa "const char *filename"
+.Fa "size_t block_size"
+.Fc
+.Ft int
+.Fn archive_read_open_memory "struct archive *" "void *buff" "size_t size"
+.Sh DESCRIPTION
+.Bl -tag -compact -width indent
+.It Fn archive_read_open
+The same as
+.Fn archive_read_open2 ,
+except that the skip callback is assumed to be
+.Dv NULL .
+.It Fn archive_read_open2
+Freeze the settings, open the archive, and prepare for reading entries.
+This is the most generic version of this call, which accepts
+four callback functions.
+Most clients will want to use
+.Fn archive_read_open_filename ,
+.Fn archive_read_open_FILE ,
+.Fn archive_read_open_fd ,
+or
+.Fn archive_read_open_memory
+instead.
+The library invokes the client-provided functions to obtain
+raw bytes from the archive.
+.It Fn archive_read_open_FILE
+Like
+.Fn archive_read_open ,
+except that it accepts a
+.Ft "FILE *"
+pointer.
+This function should not be used with tape drives or other devices
+that require strict I/O blocking.
+.It Fn archive_read_open_fd
+Like
+.Fn archive_read_open ,
+except that it accepts a file descriptor and block size rather than
+a set of function pointers.
+Note that the file descriptor will not be automatically closed at
+end-of-archive.
+This function is safe for use with tape drives or other blocked devices.
+.It Fn archive_read_open_file
+This is a deprecated synonym for
+.Fn archive_read_open_filename .
+.It Fn archive_read_open_filename
+Like
+.Fn archive_read_open ,
+except that it accepts a simple filename and a block size.
+A NULL filename represents standard input.
+This function is safe for use with tape drives or other blocked devices.
+.It Fn archive_read_open_memory
+Like
+.Fn archive_read_open ,
+except that it accepts a pointer and size of a block of
+memory containing the archive data.
+.El
+.Pp
+A complete description of the
+.Tn struct archive
+and
+.Tn struct archive_entry
+objects can be found in the overview manual page for
+.Xr libarchive 3 .
+.Sh CLIENT CALLBACKS
+The callback functions must match the following prototypes:
+.Bl -item -offset indent
+.It
+.Ft typedef ssize_t
+.Fo archive_read_callback
+.Fa "struct archive *"
+.Fa "void *client_data"
+.Fa "const void **buffer"
+.Fc
+.It
+.Ft typedef off_t
+.Fo archive_skip_callback
+.Fa "struct archive *"
+.Fa "void *client_data"
+.Fa "off_t request"
+.Fc
+.It
+.Ft typedef int
+.Fn archive_open_callback "struct archive *" "void *client_data"
+.It
+.Ft typedef int
+.Fn archive_close_callback "struct archive *" "void *client_data"
+.El
+.Pp
+The open callback is invoked by
+.Fn archive_open .
+It should return
+.Cm ARCHIVE_OK
+if the underlying file or data source is successfully
+opened.
+If the open fails, it should call
+.Fn archive_set_error
+to register an error code and message and return
+.Cm ARCHIVE_FATAL .
+.Pp
+The read callback is invoked whenever the library
+requires raw bytes from the archive.
+The read callback should read data into a buffer,
+set the
+.Li const void **buffer
+argument to point to the available data, and
+return a count of the number of bytes available.
+The library will invoke the read callback again
+only after it has consumed this data.
+The library imposes no constraints on the size
+of the data blocks returned.
+On end-of-file, the read callback should
+return zero.
+On error, the read callback should invoke
+.Fn archive_set_error
+to register an error code and message and
+return -1.
+.Pp
+The skip callback is invoked when the
+library wants to ignore a block of data.
+The return value is the number of bytes actually
+skipped, which may differ from the request.
+If the callback cannot skip data, it should return
+zero.
+If the skip callback is not provided (the
+function pointer is
+.Dv NULL ),
+the library will invoke the read function
+instead and simply discard the result.
+A skip callback can provide significant
+performance gains when reading uncompressed
+archives from slow disk drives or other media
+that can skip quickly.
+.Pp
+The close callback is invoked by archive_close when
+the archive processing is complete.
+The callback should return
+.Cm ARCHIVE_OK
+on success.
+On failure, the callback should invoke
+.Fn archive_set_error
+to register an error code and message and
+return
+.Cm ARCHIVE_FATAL.
+.\" .Sh EXAMPLE
+.\"
+.Sh RETURN VALUES
+These functions return
+.Cm ARCHIVE_OK
+on success, or
+.Cm ARCHIVE_FATAL .
+.\"
+.Sh ERRORS
+Detailed error codes and textual descriptions are available from the
+.Fn archive_errno
+and
+.Fn archive_error_string
+functions.
+.\"
+.Sh SEE ALSO
+.Xr tar 1 ,
+.Xr libarchive 3 ,
+.Xr archive_read 3 ,
+.Xr archive_read_data 3 ,
+.Xr archive_read_filter 3 ,
+.Xr archive_read_format 3 ,
+.Xr archive_read_set_options 3 ,
+.Xr archive_util 3 ,
+.Xr tar 5
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_open_fd.c b/Utilities/cmlibarchive/libarchive/archive_read_open_fd.c
new file mode 100644
index 000000000..d8f657295
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_open_fd.c
@@ -0,0 +1,181 @@
+/*-
+ * 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: head/lib/libarchive/archive_read_open_fd.c 201103 2009-12-28 03:13:49Z kientzle $");
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "archive.h"
+
+struct read_fd_data {
+ int fd;
+ size_t block_size;
+ char use_lseek;
+ void *buffer;
+};
+
+static int file_close(struct archive *, void *);
+static ssize_t file_read(struct archive *, void *, const void **buff);
+static int64_t file_skip(struct archive *, void *, int64_t request);
+
+int
+archive_read_open_fd(struct archive *a, int fd, size_t block_size)
+{
+ struct stat st;
+ struct read_fd_data *mine;
+ void *b;
+
+ archive_clear_error(a);
+ if (fstat(fd, &st) != 0) {
+ archive_set_error(a, errno, "Can't stat fd %d", fd);
+ return (ARCHIVE_FATAL);
+ }
+
+ mine = (struct read_fd_data *)calloc(1, sizeof(*mine));
+ b = malloc(block_size);
+ if (mine == NULL || b == NULL) {
+ archive_set_error(a, ENOMEM, "No memory");
+ free(mine);
+ free(b);
+ return (ARCHIVE_FATAL);
+ }
+ mine->block_size = block_size;
+ mine->buffer = b;
+ mine->fd = fd;
+ /*
+ * Skip support is a performance optimization for anything
+ * that supports lseek(). On FreeBSD, only regular files and
+ * raw disk devices support lseek() and there's no portable
+ * way to determine if a device is a raw disk device, so we
+ * only enable this optimization for regular files.
+ */
+ if (S_ISREG(st.st_mode)) {
+ archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino);
+ mine->use_lseek = 1;
+ }
+#if defined(__CYGWIN__) || defined(_WIN32)
+ setmode(mine->fd, O_BINARY);
+#endif
+
+ archive_read_set_read_callback(a, file_read);
+ archive_read_set_skip_callback(a, file_skip);
+ archive_read_set_close_callback(a, file_close);
+ archive_read_set_callback_data(a, mine);
+ return (archive_read_open1(a));
+}
+
+static ssize_t
+file_read(struct archive *a, void *client_data, const void **buff)
+{
+ struct read_fd_data *mine = (struct read_fd_data *)client_data;
+ ssize_t bytes_read;
+
+ *buff = mine->buffer;
+ for (;;) {
+ bytes_read = read(mine->fd, mine->buffer, mine->block_size);
+ if (bytes_read < 0) {
+ if (errno == EINTR)
+ continue;
+ archive_set_error(a, errno, "Error reading fd %d", mine->fd);
+ }
+ return (bytes_read);
+ }
+}
+
+static int64_t
+file_skip(struct archive *a, void *client_data, int64_t request)
+{
+ struct read_fd_data *mine = (struct read_fd_data *)client_data;
+ off_t skip = (off_t)request;
+ off_t old_offset, new_offset;
+ int skip_bits = sizeof(skip) * 8 - 1; /* off_t is a signed type. */
+
+ if (!mine->use_lseek)
+ return (0);
+
+ /* Reduce a request that would overflow the 'skip' variable. */
+ if (sizeof(request) > sizeof(skip)) {
+ int64_t max_skip =
+ (((int64_t)1 << (skip_bits - 1)) - 1) * 2 + 1;
+ if (request > max_skip)
+ skip = max_skip;
+ }
+
+ /* Reduce request to the next smallest multiple of block_size */
+ request = (request / mine->block_size) * mine->block_size;
+ if (request == 0)
+ return (0);
+
+ if (((old_offset = lseek(mine->fd, 0, SEEK_CUR)) >= 0) &&
+ ((new_offset = lseek(mine->fd, skip, SEEK_CUR)) >= 0))
+ return (new_offset - old_offset);
+
+ /* If seek failed once, it will probably fail again. */
+ mine->use_lseek = 0;
+
+ /* Let libarchive recover with read+discard. */
+ if (errno == ESPIPE)
+ return (0);
+
+ /*
+ * There's been an error other than ESPIPE. This is most
+ * likely caused by a programmer error (too large request)
+ * or a corrupted archive file.
+ */
+ archive_set_error(a, errno, "Error seeking");
+ return (-1);
+}
+
+static int
+file_close(struct archive *a, void *client_data)
+{
+ struct read_fd_data *mine = (struct read_fd_data *)client_data;
+
+ (void)a; /* UNUSED */
+ free(mine->buffer);
+ free(mine);
+ return (ARCHIVE_OK);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_open_file.c b/Utilities/cmlibarchive/libarchive/archive_read_open_file.c
new file mode 100644
index 000000000..b1aac0a7c
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_open_file.c
@@ -0,0 +1,177 @@
+/*-
+ * 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: head/lib/libarchive/archive_read_open_file.c 201093 2009-12-28 02:28:44Z kientzle $");
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "archive.h"
+
+struct read_FILE_data {
+ FILE *f;
+ size_t block_size;
+ void *buffer;
+ char can_skip;
+};
+
+static int file_close(struct archive *, void *);
+static ssize_t file_read(struct archive *, void *, const void **buff);
+static int64_t file_skip(struct archive *, void *, int64_t request);
+
+int
+archive_read_open_FILE(struct archive *a, FILE *f)
+{
+ struct stat st;
+ struct read_FILE_data *mine;
+ size_t block_size = 128 * 1024;
+ void *b;
+
+ archive_clear_error(a);
+ mine = (struct read_FILE_data *)malloc(sizeof(*mine));
+ b = malloc(block_size);
+ if (mine == NULL || b == NULL) {
+ archive_set_error(a, ENOMEM, "No memory");
+ free(mine);
+ free(b);
+ return (ARCHIVE_FATAL);
+ }
+ mine->block_size = block_size;
+ mine->buffer = b;
+ mine->f = f;
+ /*
+ * If we can't fstat() the file, it may just be that it's not
+ * a file. (FILE * objects can wrap many kinds of I/O
+ * streams, some of which don't support fileno()).)
+ */
+ if (fstat(fileno(mine->f), &st) == 0 && S_ISREG(st.st_mode)) {
+ archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino);
+ /* Enable the seek optimization only for regular files. */
+ mine->can_skip = 1;
+ } else
+ mine->can_skip = 0;
+
+#if defined(__CYGWIN__) || defined(_WIN32)
+ setmode(fileno(mine->f), O_BINARY);
+#endif
+
+ archive_read_set_read_callback(a, file_read);
+ archive_read_set_skip_callback(a, file_skip);
+ archive_read_set_close_callback(a, file_close);
+ archive_read_set_callback_data(a, mine);
+ return (archive_read_open1(a));
+}
+
+static ssize_t
+file_read(struct archive *a, void *client_data, const void **buff)
+{
+ struct read_FILE_data *mine = (struct read_FILE_data *)client_data;
+ ssize_t bytes_read;
+
+ *buff = mine->buffer;
+ bytes_read = fread(mine->buffer, 1, mine->block_size, mine->f);
+ if (bytes_read < 0) {
+ archive_set_error(a, errno, "Error reading file");
+ }
+ return (bytes_read);
+}
+
+static int64_t
+file_skip(struct archive *a, void *client_data, int64_t request)
+{
+ struct read_FILE_data *mine = (struct read_FILE_data *)client_data;
+#if HAVE_FSEEKO
+ off_t skip = (off_t)request;
+#elif HAVE__FSEEKI64
+ int64_t skip = request;
+#else
+ long skip = (long)request;
+#endif
+ int skip_bits = sizeof(skip) * 8 - 1;
+
+ (void)a; /* UNUSED */
+
+ /*
+ * If we can't skip, return 0 as the amount we did step and
+ * the caller will work around by reading and discarding.
+ */
+ if (!mine->can_skip)
+ return (0);
+ if (request == 0)
+ return (0);
+
+ /* If request is too big for a long or an off_t, reduce it. */
+ if (sizeof(request) > sizeof(skip)) {
+ int64_t max_skip =
+ (((int64_t)1 << (skip_bits - 1)) - 1) * 2 + 1;
+ if (request > max_skip)
+ skip = max_skip;
+ }
+
+#if HAVE_FSEEKO
+ if (fseeko(mine->f, skip, SEEK_CUR) != 0)
+#elif HAVE__FSEEKI64
+ if (_fseeki64(mine->f, skip, SEEK_CUR) != 0)
+#else
+ if (fseek(mine->f, skip, SEEK_CUR) != 0)
+#endif
+ {
+ mine->can_skip = 0;
+ return (0);
+ }
+ return (request);
+}
+
+static int
+file_close(struct archive *a, void *client_data)
+{
+ struct read_FILE_data *mine = (struct read_FILE_data *)client_data;
+
+ (void)a; /* UNUSED */
+ if (mine->buffer != NULL)
+ free(mine->buffer);
+ free(mine);
+ return (ARCHIVE_OK);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_open_filename.c b/Utilities/cmlibarchive/libarchive/archive_read_open_filename.c
new file mode 100644
index 000000000..bf5269724
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_open_filename.c
@@ -0,0 +1,509 @@
+/*-
+ * Copyright (c) 2003-2010 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: head/lib/libarchive/archive_read_open_filename.c 201093 2009-12-28 02:28:44Z kientzle $");
+
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#include <sys/disk.h>
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
+#include <sys/disklabel.h>
+#include <sys/dkio.h>
+#elif defined(__DragonFly__)
+#include <sys/diskslice.h>
+#endif
+
+#include "archive.h"
+#include "archive_string.h"
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+struct read_file_data {
+ int fd;
+ size_t block_size;
+ void *buffer;
+ mode_t st_mode; /* Mode bits for opened file. */
+ char use_lseek;
+ enum fnt_e { FNT_STDIN, FNT_MBS, FNT_WCS } filename_type;
+ union {
+ char m[1];/* MBS filename. */
+ wchar_t w[1];/* WCS filename. */
+ } filename; /* Must be last! */
+};
+
+static int file_close(struct archive *, void *);
+static int file_open_filename(struct archive *, enum fnt_e, const void *,
+ size_t);
+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);
+static int64_t file_skip_lseek(struct archive *, void *, int64_t request);
+
+int
+archive_read_open_file(struct archive *a, const char *filename,
+ size_t block_size)
+{
+ return (archive_read_open_filename(a, filename, block_size));
+}
+
+int
+archive_read_open_filename(struct archive *a, const char *filename,
+ size_t block_size)
+{
+ enum fnt_e filename_type;
+
+ if (filename == NULL || filename[0] == '\0') {
+ filename_type = FNT_STDIN;
+ } else
+ filename_type = FNT_MBS;
+ return (file_open_filename(a, filename_type, filename, block_size));
+}
+
+int
+archive_read_open_filename_w(struct archive *a, const wchar_t *wfilename,
+ size_t block_size)
+{
+ enum fnt_e filename_type;
+
+ if (wfilename == NULL || wfilename[0] == L'\0') {
+ filename_type = FNT_STDIN;
+ } else {
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ filename_type = FNT_WCS;
+#else
+ /*
+ * POSIX system does not support a wchar_t interface for
+ * open() system call, so we have to translate a whcar_t
+ * filename to multi-byte one and use it.
+ */
+ struct archive_string fn;
+ int r;
+
+ archive_string_init(&fn);
+ if (archive_string_append_from_wcs(&fn, wfilename,
+ wcslen(wfilename)) != 0) {
+ archive_set_error(a, EINVAL,
+ "Failed to convert a wide-character filename to"
+ " a multi-byte filename");
+ archive_string_free(&fn);
+ return (ARCHIVE_FATAL);
+ }
+ r = file_open_filename(a, FNT_MBS, fn.s, block_size);
+ archive_string_free(&fn);
+ return (r);
+#endif
+ }
+ return (file_open_filename(a, filename_type, wfilename, block_size));
+}
+
+static int
+file_open_filename(struct archive *a, enum fnt_e filename_type,
+ const void *_filename, size_t block_size)
+{
+ struct stat st;
+ struct read_file_data *mine;
+ void *buffer;
+ const char *filename = NULL;
+ const wchar_t *wfilename = NULL;
+ int fd;
+ int is_disk_like = 0;
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+ off_t mediasize = 0; /* FreeBSD-specific, so off_t okay here. */
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
+ struct disklabel dl;
+#elif defined(__DragonFly__)
+ struct partinfo pi;
+#endif
+
+ archive_clear_error(a);
+ if (filename_type == FNT_STDIN) {
+ /* We used to delegate stdin support by
+ * directly calling archive_read_open_fd(a,0,block_size)
+ * here, but that doesn't (and shouldn't) handle the
+ * end-of-file flush when reading stdout from a pipe.
+ * Basically, read_open_fd() is intended for folks who
+ * are willing to handle such details themselves. This
+ * API is intended to be a little smarter for folks who
+ * want easy handling of the common case.
+ */
+ fd = 0;
+#if defined(__CYGWIN__) || defined(_WIN32)
+ setmode(0, O_BINARY);
+#endif
+ filename = "";
+ } else if (filename_type == FNT_MBS) {
+ filename = (const char *)_filename;
+ fd = open(filename, O_RDONLY | O_BINARY);
+ if (fd < 0) {
+ archive_set_error(a, errno,
+ "Failed to open '%s'", filename);
+ return (ARCHIVE_FATAL);
+ }
+ } else {
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ wfilename = (const wchar_t *)_filename;
+ fd = _wopen(wfilename, O_RDONLY | O_BINARY);
+ if (fd < 0 && errno == ENOENT) {
+ wchar_t *fullpath;
+ fullpath = __la_win_permissive_name_w(wfilename);
+ if (fullpath != NULL) {
+ fd = _wopen(fullpath, O_RDONLY | O_BINARY);
+ free(fullpath);
+ }
+ }
+ if (fd < 0) {
+ archive_set_error(a, errno,
+ "Failed to open '%S'", wfilename);
+ return (ARCHIVE_FATAL);
+ }
+#else
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Unexpedted operation in archive_read_open_filename");
+ return (ARCHIVE_FATAL);
+#endif
+ }
+ if (fstat(fd, &st) != 0) {
+ if (filename_type == FNT_WCS)
+ archive_set_error(a, errno, "Can't stat '%S'",
+ wfilename);
+ else
+ archive_set_error(a, errno, "Can't stat '%s'",
+ filename);
+ return (ARCHIVE_FATAL);
+ }
+
+ /*
+ * Determine whether the input looks like a disk device or a
+ * tape device. The results are used below to select an I/O
+ * strategy:
+ * = "disk-like" devices support arbitrary lseek() and will
+ * support I/O requests of any size. So we get easy skipping
+ * and can cheat on block sizes to get better performance.
+ * = "tape-like" devices require strict blocking and use
+ * specialized ioctls for seeking.
+ * = "socket-like" devices cannot seek at all but can improve
+ * performance by using nonblocking I/O to read "whatever is
+ * available right now".
+ *
+ * Right now, we only specially recognize disk-like devices,
+ * but it should be straightforward to add probes and strategy
+ * here for tape-like and socket-like devices.
+ */
+ if (S_ISREG(st.st_mode)) {
+ /* Safety: Tell the extractor not to overwrite the input. */
+ archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino);
+ /* Regular files act like disks. */
+ is_disk_like = 1;
+ }
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+ /* FreeBSD: if it supports DIOCGMEDIASIZE ioctl, it's disk-like. */
+ else if (S_ISCHR(st.st_mode) &&
+ ioctl(fd, DIOCGMEDIASIZE, &mediasize) == 0 &&
+ mediasize > 0) {
+ is_disk_like = 1;
+ }
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
+ /* Net/OpenBSD: if it supports DIOCGDINFO ioctl, it's disk-like. */
+ else if ((S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) &&
+ ioctl(fd, DIOCGDINFO, &dl) == 0 &&
+ dl.d_partitions[DISKPART(st.st_rdev)].p_size > 0) {
+ is_disk_like = 1;
+ }
+#elif defined(__DragonFly__)
+ /* DragonFly BSD: if it supports DIOCGPART ioctl, it's disk-like. */
+ else if (S_ISCHR(st.st_mode) &&
+ ioctl(fd, DIOCGPART, &pi) == 0 &&
+ pi.media_size > 0) {
+ is_disk_like = 1;
+ }
+#elif defined(__linux__)
+ /* Linux: All block devices are disk-like. */
+ else if (S_ISBLK(st.st_mode) &&
+ lseek(fd, 0, SEEK_CUR) == 0 &&
+ lseek(fd, 0, SEEK_SET) == 0 &&
+ lseek(fd, 0, SEEK_END) > 0 &&
+ lseek(fd, 0, SEEK_SET) == 0) {
+ is_disk_like = 1;
+ }
+#endif
+ /* TODO: Add an "is_tape_like" variable and appropriate tests. */
+
+ if (filename_type == FNT_WCS)
+ mine = (struct read_file_data *)calloc(1,
+ sizeof(*mine) + wcslen(wfilename) * sizeof(wchar_t));
+ else
+ mine = (struct read_file_data *)calloc(1,
+ sizeof(*mine) + strlen(filename));
+ /* Disk-like devices prefer power-of-two block sizes. */
+ /* Use provided block_size as a guide so users have some control. */
+ if (is_disk_like) {
+ size_t new_block_size = 64 * 1024;
+ while (new_block_size < block_size
+ && new_block_size < 64 * 1024 * 1024)
+ new_block_size *= 2;
+ block_size = new_block_size;
+ }
+ buffer = malloc(block_size);
+ if (mine == NULL || buffer == NULL) {
+ archive_set_error(a, ENOMEM, "No memory");
+ free(mine);
+ free(buffer);
+ return (ARCHIVE_FATAL);
+ }
+ if (filename_type == FNT_WCS)
+ wcscpy(mine->filename.w, wfilename);
+ else
+ strcpy(mine->filename.m, filename);
+ mine->filename_type = filename_type;
+ mine->block_size = block_size;
+ mine->buffer = buffer;
+ mine->fd = fd;
+ /* Remember mode so close can decide whether to flush. */
+ mine->st_mode = st.st_mode;
+
+ /* Disk-like inputs can use lseek(). */
+ if (is_disk_like) {
+ archive_read_set_seek_callback(a, file_seek);
+ mine->use_lseek = 1;
+ }
+
+ archive_read_set_read_callback(a, file_read);
+ archive_read_set_skip_callback(a, file_skip);
+ archive_read_set_close_callback(a, file_close);
+ archive_read_set_callback_data(a, mine);
+ return (archive_read_open1(a));
+}
+
+static ssize_t
+file_read(struct archive *a, void *client_data, const void **buff)
+{
+ struct read_file_data *mine = (struct read_file_data *)client_data;
+ ssize_t bytes_read;
+
+ /* TODO: If a recent lseek() operation has left us
+ * mis-aligned, read and return a short block to try to get
+ * us back in alignment. */
+
+ /* TODO: Someday, try mmap() here; if that succeeds, give
+ * the entire file to libarchive as a single block. That
+ * could be a lot faster than block-by-block manual I/O. */
+
+ /* TODO: We might be able to improve performance on pipes and
+ * sockets by setting non-blocking I/O and just accepting
+ * whatever we get here instead of waiting for a full block
+ * worth of data. */
+
+ *buff = mine->buffer;
+ for (;;) {
+ bytes_read = read(mine->fd, mine->buffer, mine->block_size);
+ if (bytes_read < 0) {
+ if (errno == EINTR)
+ continue;
+ else if (mine->filename_type == FNT_STDIN)
+ archive_set_error(a, errno,
+ "Error reading stdin");
+ else if (mine->filename_type == FNT_MBS)
+ archive_set_error(a, errno,
+ "Error reading '%s'", mine->filename.m);
+ else
+ archive_set_error(a, errno,
+ "Error reading '%S'", mine->filename.w);
+ }
+ return (bytes_read);
+ }
+}
+
+/*
+ * Regular files and disk-like block devices can use simple lseek
+ * without needing to round the request to the block size.
+ *
+ * TODO: This can leave future reads mis-aligned. Since we know the
+ * offset here, we should store it and use it in file_read() above
+ * to determine whether we should perform a short read to get back
+ * into alignment. Long series of mis-aligned reads can negatively
+ * impact disk throughput. (Of course, the performance impact should
+ * be carefully tested; extra code complexity is only worthwhile if
+ * it does provide measurable improvement.)
+ *
+ * TODO: Be lazy about the actual seek. There are a few pathological
+ * cases where libarchive makes a bunch of seek requests in a row
+ * without any intervening reads. This isn't a huge performance
+ * problem, since the kernel handles seeks lazily already, but
+ * it would be very slightly faster if we simply remembered the
+ * seek request here and then actually performed the seek at the
+ * top of the read callback above.
+ */
+static int64_t
+file_skip_lseek(struct archive *a, void *client_data, int64_t request)
+{
+ struct read_file_data *mine = (struct read_file_data *)client_data;
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ /* We use _lseeki64() on Windows. */
+ int64_t old_offset, new_offset;
+#else
+ off_t old_offset, new_offset;
+#endif
+
+ /* We use off_t here because lseek() is declared that way. */
+
+ /* TODO: Deal with case where off_t isn't 64 bits.
+ * This shouldn't be a problem on Linux or other POSIX
+ * systems, since the configuration logic for libarchive
+ * tries to obtain a 64-bit off_t. It's still an issue
+ * on Windows, though, so it might suffice to just use
+ * _lseeki64() on Windows.
+ */
+ if ((old_offset = lseek(mine->fd, 0, SEEK_CUR)) >= 0 &&
+ (new_offset = lseek(mine->fd, request, SEEK_CUR)) >= 0)
+ return (new_offset - old_offset);
+
+ /* If lseek() fails, don't bother trying again. */
+ mine->use_lseek = 0;
+
+ /* Let libarchive recover with read+discard */
+ if (errno == ESPIPE)
+ return (0);
+
+ /* If the input is corrupted or truncated, fail. */
+ if (mine->filename_type == FNT_STDIN)
+ archive_set_error(a, errno, "Error seeking in stdin");
+ else if (mine->filename_type == FNT_MBS)
+ archive_set_error(a, errno, "Error seeking in '%s'",
+ mine->filename.m);
+ else
+ archive_set_error(a, errno, "Error seeking in '%S'",
+ mine->filename.w);
+ return (-1);
+}
+
+
+/*
+ * TODO: Implement another file_skip_XXXX that uses MTIO ioctls to
+ * accelerate operation on tape drives.
+ */
+
+static int64_t
+file_skip(struct archive *a, void *client_data, int64_t request)
+{
+ struct read_file_data *mine = (struct read_file_data *)client_data;
+
+ /* Delegate skip requests. */
+ if (mine->use_lseek)
+ return (file_skip_lseek(a, client_data, request));
+
+ /* If we can't skip, return 0; libarchive will read+discard instead. */
+ return (0);
+}
+
+/*
+ * 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_file_data *mine = (struct read_file_data *)client_data;
+ off_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 the input is corrupted or truncated, fail. */
+ if (mine->filename_type == FNT_STDIN)
+ archive_set_error(a, errno, "Error seeking in stdin");
+ else if (mine->filename_type == FNT_MBS)
+ archive_set_error(a, errno, "Error seeking in '%s'",
+ mine->filename.m);
+ else
+ archive_set_error(a, errno, "Error seeking in '%S'",
+ mine->filename.w);
+ return (ARCHIVE_FATAL);
+}
+
+static int
+file_close(struct archive *a, void *client_data)
+{
+ struct read_file_data *mine = (struct read_file_data *)client_data;
+
+ (void)a; /* UNUSED */
+
+ /* Only flush and close if open succeeded. */
+ if (mine->fd >= 0) {
+ /*
+ * Sometimes, we should flush the input before closing.
+ * Regular files: faster to just close without flush.
+ * Disk-like devices: Ditto.
+ * Tapes: must not flush (user might need to
+ * read the "next" item on a non-rewind device).
+ * Pipes and sockets: must flush (otherwise, the
+ * program feeding the pipe or socket may complain).
+ * Here, I flush everything except for regular files and
+ * device nodes.
+ */
+ if (!S_ISREG(mine->st_mode)
+ && !S_ISCHR(mine->st_mode)
+ && !S_ISBLK(mine->st_mode)) {
+ ssize_t bytesRead;
+ do {
+ bytesRead = read(mine->fd, mine->buffer,
+ mine->block_size);
+ } while (bytesRead > 0);
+ }
+ /* If a named file was opened, then it needs to be closed. */
+ if (mine->filename_type != FNT_STDIN)
+ close(mine->fd);
+ }
+ free(mine->buffer);
+ free(mine);
+ return (ARCHIVE_OK);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_open_memory.c b/Utilities/cmlibarchive/libarchive/archive_read_open_memory.c
new file mode 100644
index 000000000..07940a2ac
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_open_memory.c
@@ -0,0 +1,186 @@
+/*-
+ * 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_open_memory.c,v 1.6 2007/07/06 15:51:59 kientzle Exp $");
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "archive.h"
+
+/*
+ * Glue to read an archive from a block of memory.
+ *
+ * This is mostly a huge help in building test harnesses;
+ * test programs can build archives in memory and read them
+ * back again without having to mess with files on disk.
+ */
+
+struct read_memory_data {
+ unsigned char *start;
+ unsigned char *p;
+ unsigned char *end;
+ ssize_t read_size;
+};
+
+static int memory_read_close(struct archive *, void *);
+static int memory_read_open(struct archive *, void *);
+static int64_t memory_read_seek(struct archive *, void *, int64_t offset, int whence);
+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)
+{
+ return archive_read_open_memory2(a, buff, size, size);
+}
+
+/*
+ * Don't use _open_memory2() in production code; the archive_read_open_memory()
+ * version is the one you really want. This is just here so that
+ * test harnesses can exercise block operations inside the library.
+ */
+int
+archive_read_open_memory2(struct archive *a, void *buff,
+ size_t size, size_t read_size)
+{
+ struct read_memory_data *mine;
+
+ mine = (struct read_memory_data *)malloc(sizeof(*mine));
+ if (mine == NULL) {
+ archive_set_error(a, ENOMEM, "No memory");
+ return (ARCHIVE_FATAL);
+ }
+ memset(mine, 0, sizeof(*mine));
+ mine->start = mine->p = (unsigned char *)buff;
+ mine->end = mine->start + size;
+ mine->read_size = read_size;
+ archive_read_set_open_callback(a, memory_read_open);
+ archive_read_set_read_callback(a, memory_read);
+ archive_read_set_seek_callback(a, memory_read_seek);
+ archive_read_set_skip_callback(a, memory_read_skip);
+ archive_read_set_close_callback(a, memory_read_close);
+ archive_read_set_callback_data(a, mine);
+ return (archive_read_open1(a));
+}
+
+/*
+ * There's nothing to open.
+ */
+static int
+memory_read_open(struct archive *a, void *client_data)
+{
+ (void)a; /* UNUSED */
+ (void)client_data; /* UNUSED */
+ return (ARCHIVE_OK);
+}
+
+/*
+ * This is scary simple: Just advance a pointer. Limiting
+ * to read_size is not technically necessary, but it exercises
+ * more of the internal logic when used with a small block size
+ * in a test harness. Production use should not specify a block
+ * size; then this is much faster.
+ */
+static ssize_t
+memory_read(struct archive *a, void *client_data, const void **buff)
+{
+ struct read_memory_data *mine = (struct read_memory_data *)client_data;
+ ssize_t size;
+
+ (void)a; /* UNUSED */
+ *buff = mine->p;
+ size = mine->end - mine->p;
+ if (size > mine->read_size)
+ size = mine->read_size;
+ mine->p += size;
+ return (size);
+}
+
+/*
+ * Advancing is just as simple. Again, this is doing more than
+ * necessary in order to better exercise internal code when used
+ * as a test harness.
+ */
+static int64_t
+memory_read_skip(struct archive *a, void *client_data, int64_t skip)
+{
+ struct read_memory_data *mine = (struct read_memory_data *)client_data;
+
+ (void)a; /* UNUSED */
+ if ((int64_t)skip > (int64_t)(mine->end - mine->p))
+ skip = mine->end - mine->p;
+ /* Round down to block size. */
+ skip /= mine->read_size;
+ skip *= mine->read_size;
+ mine->p += skip;
+ return (skip);
+}
+
+/*
+ * Seeking.
+ */
+static int64_t
+memory_read_seek(struct archive *a, void *client_data, int64_t offset, int whence)
+{
+ struct read_memory_data *mine = (struct read_memory_data *)client_data;
+
+ switch (whence) {
+ case SEEK_SET:
+ mine->p = mine->start + offset;
+ break;
+ case SEEK_CUR:
+ mine->p += offset;
+ break;
+ case SEEK_END:
+ mine->p = mine->end + offset;
+ break;
+ default:
+ return ARCHIVE_FATAL;
+ }
+ if (mine->p < mine->start) {
+ mine->p = mine->start;
+ return ARCHIVE_FAILED;
+ }
+ if (mine->p > mine->end) {
+ mine->p = mine->end;
+ return ARCHIVE_FAILED;
+ }
+ return (mine->p - mine->start);
+}
+
+/*
+ * Close is just cleaning up our one small bit of data.
+ */
+static int
+memory_read_close(struct archive *a, void *client_data)
+{
+ struct read_memory_data *mine = (struct read_memory_data *)client_data;
+ (void)a; /* UNUSED */
+ free(mine);
+ return (ARCHIVE_OK);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_private.h b/Utilities/cmlibarchive/libarchive/archive_read_private.h
new file mode 100644
index 000000000..76d0b91d9
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_private.h
@@ -0,0 +1,210 @@
+/*-
+ * 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.
+ *
+ * $FreeBSD: head/lib/libarchive/archive_read_private.h 201088 2009-12-28 02:18:55Z kientzle $
+ */
+
+#ifndef __LIBARCHIVE_BUILD
+#error This header is only to be used internally to libarchive.
+#endif
+
+#ifndef ARCHIVE_READ_PRIVATE_H_INCLUDED
+#define ARCHIVE_READ_PRIVATE_H_INCLUDED
+
+#include "archive.h"
+#include "archive_string.h"
+#include "archive_private.h"
+
+struct archive_read;
+struct archive_read_filter_bidder;
+struct archive_read_filter;
+
+/*
+ * How bidding works for filters:
+ * * The bid manager initializes the client-provided reader as the
+ * first filter.
+ * * It invokes the bidder for each registered filter with the
+ * current head filter.
+ * * The bidders can use archive_read_filter_ahead() to peek ahead
+ * at the incoming data to compose their bids.
+ * * The bid manager creates a new filter structure for the winning
+ * bidder and gives the winning bidder a chance to initialize it.
+ * * The new filter becomes the new top filter and we repeat the
+ * process.
+ * This ends only when no bidder provides a non-zero bid. Then
+ * we perform a similar dance with the registered format handlers.
+ */
+struct archive_read_filter_bidder {
+ /* Configuration data for the bidder. */
+ void *data;
+ /* Taste the upstream filter to see if we handle this. */
+ int (*bid)(struct archive_read_filter_bidder *,
+ struct archive_read_filter *);
+ /* Initialize a newly-created filter. */
+ int (*init)(struct archive_read_filter *);
+ /* Set an option for the filter bidder. */
+ int (*options)(struct archive_read_filter_bidder *,
+ const char *key, const char *value);
+ /* Release the bidder's configuration data. */
+ int (*free)(struct archive_read_filter_bidder *);
+};
+
+/*
+ * This structure is allocated within the archive_read core
+ * and initialized by archive_read and the init() method of the
+ * corresponding bidder above.
+ */
+struct archive_read_filter {
+ int64_t position;
+ /* Essentially all filters will need these values, so
+ * just declare them here. */
+ struct archive_read_filter_bidder *bidder; /* My bidder. */
+ struct archive_read_filter *upstream; /* Who I read from. */
+ struct archive_read *archive; /* Associated archive. */
+ /* Return next block. */
+ ssize_t (*read)(struct archive_read_filter *, const void **);
+ /* Skip forward this many bytes. */
+ int64_t (*skip)(struct archive_read_filter *self, int64_t request);
+ /* Seek to an absolute location. */
+ int64_t (*seek)(struct archive_read_filter *self, int64_t offset, int whence);
+ /* Close (just this filter) and free(self). */
+ int (*close)(struct archive_read_filter *self);
+ /* My private data. */
+ void *data;
+
+ const char *name;
+ int code;
+
+ /* Used by reblocking logic. */
+ char *buffer;
+ size_t buffer_size;
+ char *next; /* Current read location. */
+ size_t avail; /* Bytes in my buffer. */
+ const void *client_buff; /* Client buffer information. */
+ size_t client_total;
+ const char *client_next;
+ size_t client_avail;
+ char end_of_file;
+ char closed;
+ char fatal;
+};
+
+/*
+ * The client looks a lot like a filter, so we just wrap it here.
+ *
+ * TODO: Make archive_read_filter and archive_read_client identical so
+ * that users of the library can easily register their own
+ * transformation filters. This will probably break the API/ABI and
+ * so should be deferred at least until libarchive 3.0.
+ */
+struct archive_read_client {
+ archive_open_callback *opener;
+ archive_read_callback *reader;
+ archive_skip_callback *skipper;
+ archive_seek_callback *seeker;
+ archive_close_callback *closer;
+ void *data;
+};
+
+struct archive_read {
+ struct archive archive;
+
+ struct archive_entry *entry;
+
+ /* Dev/ino of the archive being read/written. */
+ int skip_file_set;
+ dev_t skip_file_dev;
+ ino_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;
+
+ /* Callbacks to open/read/write/close client archive stream. */
+ struct archive_read_client client;
+
+ /* Registered filter bidders. */
+ struct archive_read_filter_bidder bidders[9];
+
+ /* Last filter in chain */
+ struct archive_read_filter *filter;
+
+ /* File offset of beginning of most recently-read header. */
+ int64_t header_position;
+
+ /*
+ * Format detection is mostly the same as compression
+ * detection, with one significant difference: The bidders
+ * use the read_ahead calls above to examine the stream rather
+ * than having the supervisor hand them a block of data to
+ * examine.
+ */
+
+ struct archive_format_descriptor {
+ void *data;
+ const char *name;
+ int (*bid)(struct archive_read *, int best_bid);
+ int (*options)(struct archive_read *, const char *key,
+ const char *value);
+ 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 *);
+ int (*cleanup)(struct archive_read *);
+ } formats[16];
+ struct archive_format_descriptor *format; /* Active format. */
+
+ /*
+ * Various information needed by archive_extract.
+ */
+ struct extract *extract;
+ int (*cleanup_archive_extract)(struct archive_read *);
+};
+
+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 *),
+ int (*cleanup)(struct archive_read *));
+
+int __archive_read_get_bidder(struct archive_read *a,
+ struct archive_read_filter_bidder **bidder);
+
+const void *__archive_read_ahead(struct archive_read *, size_t, ssize_t *);
+const void *__archive_read_filter_ahead(struct archive_read_filter *,
+ size_t, ssize_t *);
+int64_t __archive_read_seek(struct archive_read*, int64_t, int);
+int64_t __archive_read_filter_seek(struct archive_read_filter *, int64_t, int);
+int64_t __archive_read_consume(struct archive_read *, int64_t);
+int64_t __archive_read_filter_consume(struct archive_read_filter *, int64_t);
+int __archive_read_program(struct archive_read_filter *, const char *);
+#endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_set_options.3 b/Utilities/cmlibarchive/libarchive/archive_read_set_options.3
new file mode 100644
index 000000000..81efb08b5
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_set_options.3
@@ -0,0 +1,207 @@
+.\" Copyright (c) 2011 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 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 April 13, 2009
+.Dt ARCHIVE_READ_OPTIONS 3
+.Os
+.Sh NAME
+.Nm archive_read_set_filter_option ,
+.Nm archive_read_set_format_option ,
+.Nm archive_read_set_option ,
+.Nm archive_read_set_options
+.Nd functions controlling options for reading archives
+.\"
+.Sh SYNOPSIS
+.Ft int
+.Fo archive_read_set_filter_option
+.Fa "struct archive *"
+.Fa "const char *module"
+.Fa "const char *option"
+.Fa "const char *value"
+.Fc
+.Ft int
+.Fo archive_read_set_format_option
+.Fa "struct archive *"
+.Fa "const char *module"
+.Fa "const char *option"
+.Fa "const char *value"
+.Fc
+.Ft int
+.Fo archive_read_set_option
+.Fa "struct archive *"
+.Fa "const char *module"
+.Fa "const char *option"
+.Fa "const char *value"
+.Fc
+.Ft int
+.Fo archive_read_set_options
+.Fa "struct archive *"
+.Fa "const char *options"
+.Fc
+.Sh DESCRIPTION
+These functions provide a way for libarchive clients to configure
+specific read modules.
+.Bl -tag -width indent
+.It Xo
+.Fn archive_read_set_filter_option ,
+.Fn archive_read_set_format_option
+.Xc
+Specifies an option that will be passed to currently-registered
+filters (including decompression filters) or format readers.
+.Pp
+If
+.Ar option
+and
+.Ar value
+are both
+.Dv NULL ,
+these functions will do nothing and
+.Cm ARCHIVE_OK
+will be returned.
+If
+.Ar option
+is
+.Dv NULL
+but
+.Ar value
+is not, these functions will do nothing and
+.Cm ARCHIVE_FAILED
+will be returned.
+.Pp
+If
+.Ar module
+is not
+.Dv NULL ,
+.Ar option
+and
+.Ar value
+will be provided to the filter or reader named
+.Ar module .
+The return value will be that of the module.
+If there is no such module,
+.Cm ARCHIVE_FAILED
+will be returned.
+.Pp
+If
+.Ar module
+is
+.Dv NULL ,
+.Ar option
+and
+.Ar value
+will be provided to every registered module.
+If any module returns
+.Cm ARCHIVE_FATAL ,
+this value will be returned immediately.
+Otherwise,
+.Cm ARCHIVE_OK
+will be returned if any module accepts the option, and
+.Cm ARCHIVE_FAILED
+in all other cases.
+.\"
+.It Xo
+.Fn archive_read_set_option
+.Xc
+Calls
+.Fn archive_read_set_format_option ,
+then
+.Fn archive_read_set_filter_option .
+If either function returns
+.Cm ARCHIVE_FATAL ,
+.Cm ARCHIVE_FATAL
+will be returned
+immediately.
+Otherwise, greater of the two values will be returned.
+.\"
+.It Xo
+.Fn archive_read_set_options
+.Xc
+.Ar options
+is a comma-separated list of options.
+If
+.Ar options
+is
+.Dv NULL
+or empty,
+.Cm ARCHIVE_OK
+will be returned immediately.
+.Pp
+Calls
+.Fn archive_read_set_option
+with each option in turn.
+If any
+.Fn archive_read_set_option
+call returns
+.Cm ARCHIVE_FATAL ,
+.Cm ARCHIVE_FATAL
+will be returned immediately.
+.Pp
+Individual options have one of the following forms:
+.Bl -tag -compact -width indent
+.It Ar option=value
+The option/value pair will be provided to every module.
+Modules that do not accept an option with this name will ignore it.
+.It Ar option
+The option will be provided to every module with a value of
+.Dq 1 .
+.It Ar !option
+The option will be provided to every module with a NULL value.
+.It Ar module:option=value , Ar module:option , Ar module:!option
+As above, but the corresponding option and value will be provided
+only to modules whose name matches
+.Ar module .
+.El
+.El
+.\"
+.Sh OPTIONS
+.Bl -tag -compact -width indent
+.It Format iso9660
+.Bl -tag -compact -width indent
+.It Cm joliet
+Support Joliet extensions.
+Defaults to enabled, use
+.Cm !joliet
+to disable.
+.It Cm rockridge
+Support RockRidge extensions.
+Defaults to enabled, use
+.Cm !rockridge
+to disable.
+.El
+.El
+.\"
+.Sh ERRORS
+Detailed error codes and textual descriptions are available from the
+.Fn archive_errno
+and
+.Fn archive_error_string
+functions.
+.\"
+.Sh SEE ALSO
+.Xr tar 1 ,
+.Xr libarchive 3 ,
+.Xr archive_write_set_options 3 ,
+.Xr archive_read 3
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_set_options.c b/Utilities/cmlibarchive/libarchive/archive_read_set_options.c
new file mode 100644
index 000000000..d6a5f45cc
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_set_options.c
@@ -0,0 +1,148 @@
+/*-
+ * Copyright (c) 2011 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$");
+
+#include "archive_read_private.h"
+#include "archive_options_private.h"
+
+static int archive_set_format_option(struct archive *a,
+ const char *m, const char *o, const char *v);
+static int archive_set_filter_option(struct archive *a,
+ const char *m, const char *o, const char *v);
+static int archive_set_option(struct archive *a,
+ const char *m, const char *o, const char *v);
+
+int
+archive_read_set_format_option(struct archive *a, const char *m, const char *o,
+ const char *v)
+{
+ return _archive_set_option(a, m, o, v,
+ ARCHIVE_READ_MAGIC, "archive_read_set_format_option",
+ archive_set_format_option);
+}
+
+int
+archive_read_set_filter_option(struct archive *a, const char *m, const char *o,
+ const char *v)
+{
+ return _archive_set_option(a, m, o, v,
+ ARCHIVE_READ_MAGIC, "archive_read_set_filter_option",
+ archive_set_filter_option);
+}
+
+int
+archive_read_set_option(struct archive *a, const char *m, const char *o,
+ const char *v)
+{
+ return _archive_set_option(a, m, o, v,
+ ARCHIVE_READ_MAGIC, "archive_read_set_option",
+ archive_set_option);
+}
+
+int
+archive_read_set_options(struct archive *a, const char *options)
+{
+ return _archive_set_options(a, options,
+ ARCHIVE_READ_MAGIC, "archive_read_set_options",
+ archive_set_option);
+}
+
+static int
+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_FAILED;
+
+ 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)
+ /* This format does not support option. */
+ continue;
+ if (m != NULL && strcmp(format->name, m) != 0)
+ continue;
+
+ a->format = format;
+ r = format->options(a, o, v);
+ a->format = NULL;
+
+ if (r == ARCHIVE_FATAL)
+ return (ARCHIVE_FATAL);
+
+ if (m != NULL)
+ return (r);
+
+ if (r == ARCHIVE_OK)
+ rv = ARCHIVE_OK;
+ }
+ return (rv);
+}
+
+static int
+archive_set_filter_option(struct archive *_a, const char *m, const char *o,
+ const char *v)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ struct archive_read_filter *filter;
+ struct archive_read_filter_bidder *bidder;
+ int r, rv = ARCHIVE_FAILED;
+
+ for (filter = a->filter; filter != NULL; filter = filter->upstream) {
+ bidder = filter->bidder;
+ if (bidder == NULL)
+ continue;
+ if (bidder->options == NULL)
+ /* This bidder does not support option */
+ continue;
+ if (m != NULL && strcmp(filter->name, m) != 0)
+ continue;
+
+ 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;
+ }
+ return (rv);
+}
+
+static int
+archive_set_option(struct archive *a, const char *m, const char *o,
+ const char *v)
+{
+ return _archive_set_either_option(a, m, o, v,
+ archive_set_format_option,
+ archive_set_filter_option);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_all.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_all.c
new file mode 100644
index 000000000..733d86298
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_all.c
@@ -0,0 +1,75 @@
+/*-
+ * Copyright (c) 2003-2011 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$");
+
+#include "archive.h"
+#include "archive_private.h"
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+/* Deprecated; remove in libarchive 4.0 */
+int
+archive_read_support_compression_all(struct archive *a)
+{
+ return archive_read_support_filter_all(a);
+}
+#endif
+
+int
+archive_read_support_filter_all(struct archive *a)
+{
+ archive_check_magic(a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_filter_all");
+
+ /* Bzip falls back to "bunzip2" command-line */
+ archive_read_support_filter_bzip2(a);
+ /* The decompress code doesn't use an outside library. */
+ archive_read_support_filter_compress(a);
+ /* Gzip decompress falls back to "gunzip" command-line. */
+ archive_read_support_filter_gzip(a);
+ /* Lzip falls back to "unlzip" command-line program. */
+ archive_read_support_filter_lzip(a);
+ /* The LZMA file format has a very weak signature, so it
+ * may not be feasible to keep this here, but we'll try.
+ * This will come back out if there are problems. */
+ /* Lzma falls back to "unlzma" command-line program. */
+ archive_read_support_filter_lzma(a);
+ /* Xz falls back to "unxz" command-line program. */
+ archive_read_support_filter_xz(a);
+ /* The decode code doesn't use an outside library. */
+ archive_read_support_filter_uu(a);
+ /* The decode code doesn't use an outside library. */
+ archive_read_support_filter_rpm(a);
+
+ /* Note: We always return ARCHIVE_OK here, even if some of the
+ * above return ARCHIVE_WARN. The intent here is to enable
+ * "as much as possible." Clients who need specific
+ * compression should enable those individually so they can
+ * verify the level of support. */
+ /* Clear any warning messages set by the above functions. */
+ archive_clear_error(a);
+ return (ARCHIVE_OK);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_bzip2.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_bzip2.c
new file mode 100644
index 000000000..af618b09a
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_bzip2.c
@@ -0,0 +1,370 @@
+/*-
+ * 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$");
+
+#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_BZLIB_H
+#include <cm_bzlib.h>
+#endif
+
+#include "archive.h"
+#include "archive_private.h"
+#include "archive_read_private.h"
+
+#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
+struct private_data {
+ bz_stream stream;
+ char *out_block;
+ size_t out_block_size;
+ char valid; /* True = decompressor is initialized */
+ char eof; /* True = found end of compressed data. */
+};
+
+/* Bzip2 filter */
+static ssize_t bzip2_filter_read(struct archive_read_filter *, const void **);
+static int bzip2_filter_close(struct archive_read_filter *);
+#endif
+
+/*
+ * Note that we can detect bzip2 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 bzlib is unavailable.
+ */
+static int bzip2_reader_bid(struct archive_read_filter_bidder *, struct archive_read_filter *);
+static int bzip2_reader_init(struct archive_read_filter *);
+static int bzip2_reader_free(struct archive_read_filter_bidder *);
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+/* Deprecated; remove in libarchive 4.0 */
+int
+archive_read_support_compression_bzip2(struct archive *a)
+{
+ return archive_read_support_filter_bzip2(a);
+}
+#endif
+
+int
+archive_read_support_filter_bzip2(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_bzip2");
+
+ if (__archive_read_get_bidder(a, &reader) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ reader->data = NULL;
+ reader->bid = bzip2_reader_bid;
+ reader->init = bzip2_reader_init;
+ reader->options = NULL;
+ reader->free = bzip2_reader_free;
+#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
+ return (ARCHIVE_OK);
+#else
+ archive_set_error(_a, ARCHIVE_ERRNO_MISC,
+ "Using external bunzip2 program");
+ return (ARCHIVE_WARN);
+#endif
+}
+
+static int
+bzip2_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
+bzip2_reader_bid(struct archive_read_filter_bidder *self, struct archive_read_filter *filter)
+{
+ const unsigned char *buffer;
+ ssize_t avail;
+ int bits_checked;
+
+ (void)self; /* UNUSED */
+
+ /* Minimal bzip2 archive is 14 bytes. */
+ buffer = __archive_read_filter_ahead(filter, 14, &avail);
+ if (buffer == NULL)
+ return (0);
+
+ /* First three bytes must be "BZh" */
+ bits_checked = 0;
+ if (memcmp(buffer, "BZh", 3) != 0)
+ return (0);
+ bits_checked += 24;
+
+ /* Next follows a compression flag which must be an ASCII digit. */
+ if (buffer[3] < '1' || buffer[3] > '9')
+ return (0);
+ bits_checked += 5;
+
+ /* After BZh[1-9], there must be either a data block
+ * which begins with 0x314159265359 or an end-of-data
+ * marker of 0x177245385090. */
+ if (memcmp(buffer + 4, "\x31\x41\x59\x26\x53\x59", 6) == 0)
+ bits_checked += 48;
+ else if (memcmp(buffer + 4, "\x17\x72\x45\x38\x50\x90", 6) == 0)
+ bits_checked += 48;
+ else
+ return (0);
+
+ return (bits_checked);
+}
+
+#if !defined(HAVE_BZLIB_H) || !defined(BZ_CONFIG_ERROR)
+
+/*
+ * 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
+bzip2_reader_init(struct archive_read_filter *self)
+{
+ int r;
+
+ r = __archive_read_program(self, "bunzip2");
+ /* 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_COMPRESSION_BZIP2;
+ self->name = "bzip2";
+ return (r);
+}
+
+
+#else
+
+/*
+ * Setup the callbacks.
+ */
+static int
+bzip2_reader_init(struct archive_read_filter *self)
+{
+ static const size_t out_block_size = 64 * 1024;
+ void *out_block;
+ struct private_data *state;
+
+ self->code = ARCHIVE_COMPRESSION_BZIP2;
+ self->name = "bzip2";
+
+ state = (struct private_data *)calloc(sizeof(*state), 1);
+ out_block = (unsigned char *)malloc(out_block_size);
+ if (state == NULL || out_block == NULL) {
+ archive_set_error(&self->archive->archive, ENOMEM,
+ "Can't allocate data for bzip2 decompression");
+ free(out_block);
+ free(state);
+ return (ARCHIVE_FATAL);
+ }
+
+ self->data = state;
+ state->out_block_size = out_block_size;
+ state->out_block = out_block;
+ self->read = bzip2_filter_read;
+ self->skip = NULL; /* not supported */
+ self->close = bzip2_filter_close;
+
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Return the next block of decompressed data.
+ */
+static ssize_t
+bzip2_filter_read(struct archive_read_filter *self, const void **p)
+{
+ struct private_data *state;
+ size_t decompressed;
+ const char *read_buf;
+ ssize_t ret;
+
+ state = (struct private_data *)self->data;
+
+ if (state->eof) {
+ *p = NULL;
+ return (0);
+ }
+
+ /* Empty our output buffer. */
+ state->stream.next_out = state->out_block;
+ state->stream.avail_out = state->out_block_size;
+
+ /* Try to fill the output buffer. */
+ for (;;) {
+ if (!state->valid) {
+ if (bzip2_reader_bid(self->bidder, self->upstream) == 0) {
+ state->eof = 1;
+ *p = state->out_block;
+ decompressed = state->stream.next_out
+ - state->out_block;
+ return (decompressed);
+ }
+ /* Initialize compression library. */
+ ret = BZ2_bzDecompressInit(&(state->stream),
+ 0 /* library verbosity */,
+ 0 /* don't use low-mem algorithm */);
+
+ /* If init fails, try low-memory algorithm instead. */
+ if (ret == BZ_MEM_ERROR)
+ ret = BZ2_bzDecompressInit(&(state->stream),
+ 0 /* library verbosity */,
+ 1 /* do use low-mem algo */);
+
+ if (ret != BZ_OK) {
+ const char *detail = NULL;
+ int err = ARCHIVE_ERRNO_MISC;
+ switch (ret) {
+ case BZ_PARAM_ERROR:
+ detail = "invalid setup parameter";
+ break;
+ case BZ_MEM_ERROR:
+ err = ENOMEM;
+ detail = "out of memory";
+ break;
+ case BZ_CONFIG_ERROR:
+ detail = "mis-compiled library";
+ break;
+ }
+ archive_set_error(&self->archive->archive, err,
+ "Internal error initializing decompressor%s%s",
+ detail == NULL ? "" : ": ",
+ detail);
+ return (ARCHIVE_FATAL);
+ }
+ state->valid = 1;
+ }
+
+ /* stream.next_in is really const, but bzlib
+ * doesn't declare it so. <sigh> */
+ read_buf =
+ __archive_read_filter_ahead(self->upstream, 1, &ret);
+ if (read_buf == NULL) {
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC,
+ "truncated bzip2 input");
+ return (ARCHIVE_FATAL);
+ }
+ state->stream.next_in = (char *)(uintptr_t)read_buf;
+ state->stream.avail_in = ret;
+ /* There is no more data, return whatever we have. */
+ if (ret == 0) {
+ state->eof = 1;
+ *p = state->out_block;
+ decompressed = state->stream.next_out
+ - state->out_block;
+ return (decompressed);
+ }
+
+ /* Decompress as much as we can in one pass. */
+ ret = BZ2_bzDecompress(&(state->stream));
+ __archive_read_filter_consume(self->upstream,
+ state->stream.next_in - read_buf);
+
+ switch (ret) {
+ case BZ_STREAM_END: /* Found end of stream. */
+ switch (BZ2_bzDecompressEnd(&(state->stream))) {
+ case BZ_OK:
+ break;
+ default:
+ archive_set_error(&(self->archive->archive),
+ ARCHIVE_ERRNO_MISC,
+ "Failed to clean up decompressor");
+ return (ARCHIVE_FATAL);
+ }
+ state->valid = 0;
+ /* FALLTHROUGH */
+ case BZ_OK: /* Decompressor made some progress. */
+ /* If we filled our buffer, update stats and return. */
+ if (state->stream.avail_out == 0) {
+ *p = state->out_block;
+ decompressed = state->stream.next_out
+ - state->out_block;
+ return (decompressed);
+ }
+ break;
+ default: /* Return an error. */
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC, "bzip decompression failed");
+ return (ARCHIVE_FATAL);
+ }
+ }
+}
+
+/*
+ * Clean up the decompressor.
+ */
+static int
+bzip2_filter_close(struct archive_read_filter *self)
+{
+ struct private_data *state;
+ int ret = ARCHIVE_OK;
+
+ state = (struct private_data *)self->data;
+
+ if (state->valid) {
+ switch (BZ2_bzDecompressEnd(&state->stream)) {
+ case BZ_OK:
+ break;
+ default:
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Failed to clean up decompressor");
+ ret = ARCHIVE_FATAL;
+ }
+ state->valid = 0;
+ }
+
+ free(state->out_block);
+ free(state);
+ return (ret);
+}
+
+#endif /* HAVE_BZLIB_H && BZ_CONFIG_ERROR */
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_compress.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_compress.c
new file mode 100644
index 000000000..1b8530004
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_compress.c
@@ -0,0 +1,454 @@
+/*-
+ * 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.
+ */
+
+/*
+ * This code borrows heavily from "compress" source code, which is
+ * protected by the following copyright. (Clause 3 dropped by request
+ * of the Regents.)
+ */
+
+/*-
+ * Copyright (c) 1985, 1986, 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Diomidis Spinellis and James A. Woods, derived from original
+ * work by Spencer Thomas and Joseph Orost.
+ *
+ * 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.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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 "archive_platform.h"
+__FBSDID("$FreeBSD$");
+
+#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_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "archive.h"
+#include "archive_private.h"
+#include "archive_read_private.h"
+
+/*
+ * Because LZW decompression is pretty simple, I've just implemented
+ * the whole decompressor here (cribbing from "compress" source code,
+ * of course), rather than relying on an external library. I have
+ * made an effort to clarify and simplify the algorithm, so the
+ * names and structure here don't exactly match those used by compress.
+ */
+
+struct private_data {
+ /* Input variables. */
+ const unsigned char *next_in;
+ size_t avail_in;
+ size_t consume_unnotified;
+ int bit_buffer;
+ int bits_avail;
+ size_t bytes_in_section;
+
+ /* Output variables. */
+ size_t out_block_size;
+ void *out_block;
+
+ /* Decompression status variables. */
+ int use_reset_code;
+ int end_of_stream; /* EOF status. */
+ int maxcode; /* Largest code. */
+ int maxcode_bits; /* Length of largest code. */
+ int section_end_code; /* When to increase bits. */
+ int bits; /* Current code length. */
+ int oldcode; /* Previous code. */
+ int finbyte; /* Last byte of prev code. */
+
+ /* Dictionary. */
+ int free_ent; /* Next dictionary entry. */
+ unsigned char suffix[65536];
+ uint16_t prefix[65536];
+
+ /*
+ * Scratch area for expanding dictionary entries. Note:
+ * "worst" case here comes from compressing /dev/zero: the
+ * last code in the dictionary will code a sequence of
+ * 65536-256 zero bytes. Thus, we need stack space to expand
+ * a 65280-byte dictionary entry. (Of course, 32640:1
+ * compression could also be considered the "best" case. ;-)
+ */
+ unsigned char *stackp;
+ unsigned char stack[65300];
+};
+
+static int compress_bidder_bid(struct archive_read_filter_bidder *, struct archive_read_filter *);
+static int compress_bidder_init(struct archive_read_filter *);
+static int compress_bidder_free(struct archive_read_filter_bidder *);
+
+static ssize_t compress_filter_read(struct archive_read_filter *, const void **);
+static int compress_filter_close(struct archive_read_filter *);
+
+static int getbits(struct archive_read_filter *, int n);
+static int next_code(struct archive_read_filter *);
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+/* Deprecated; remove in libarchive 4.0 */
+int
+archive_read_support_compression_compress(struct archive *a)
+{
+ return archive_read_support_filter_compress(a);
+}
+#endif
+
+int
+archive_read_support_filter_compress(struct archive *_a)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ struct archive_read_filter_bidder *bidder;
+
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_filter_compress");
+
+ if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ bidder->data = NULL;
+ bidder->bid = compress_bidder_bid;
+ bidder->init = compress_bidder_init;
+ bidder->options = NULL;
+ bidder->free = compress_bidder_free;
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Test whether we can handle this data.
+ * This logic returns zero if any part of the signature fails.
+ */
+static int
+compress_bidder_bid(struct archive_read_filter_bidder *self,
+ struct archive_read_filter *filter)
+{
+ const unsigned char *buffer;
+ ssize_t avail;
+ int bits_checked;
+
+ (void)self; /* UNUSED */
+
+ buffer = __archive_read_filter_ahead(filter, 2, &avail);
+
+ if (buffer == NULL)
+ return (0);
+
+ bits_checked = 0;
+ if (buffer[0] != 0x1F || buffer[1] != 0x9D)
+ return (0);
+ bits_checked += 16;
+
+ /*
+ * TODO: Verify more.
+ */
+
+ return (bits_checked);
+}
+
+/*
+ * Setup the callbacks.
+ */
+static int
+compress_bidder_init(struct archive_read_filter *self)
+{
+ struct private_data *state;
+ static const size_t out_block_size = 64 * 1024;
+ void *out_block;
+ int code;
+
+ self->code = ARCHIVE_COMPRESSION_COMPRESS;
+ self->name = "compress (.Z)";
+
+ state = (struct private_data *)calloc(sizeof(*state), 1);
+ out_block = malloc(out_block_size);
+ if (state == NULL || out_block == NULL) {
+ free(out_block);
+ free(state);
+ archive_set_error(&self->archive->archive, ENOMEM,
+ "Can't allocate data for %s decompression",
+ self->name);
+ return (ARCHIVE_FATAL);
+ }
+
+ self->data = state;
+ state->out_block_size = out_block_size;
+ state->out_block = out_block;
+ self->read = compress_filter_read;
+ self->skip = NULL; /* not supported */
+ self->close = compress_filter_close;
+
+ /* XXX MOVE THE FOLLOWING OUT OF INIT() XXX */
+
+ (void)getbits(self, 8); /* Skip first signature byte. */
+ (void)getbits(self, 8); /* Skip second signature byte. */
+
+ code = getbits(self, 8);
+ state->maxcode_bits = code & 0x1f;
+ state->maxcode = (1 << state->maxcode_bits);
+ state->use_reset_code = code & 0x80;
+
+ /* Initialize decompressor. */
+ state->free_ent = 256;
+ state->stackp = state->stack;
+ if (state->use_reset_code)
+ state->free_ent++;
+ state->bits = 9;
+ state->section_end_code = (1<<state->bits) - 1;
+ state->oldcode = -1;
+ for (code = 255; code >= 0; code--) {
+ state->prefix[code] = 0;
+ state->suffix[code] = code;
+ }
+ next_code(self);
+
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Return a block of data from the decompression buffer. Decompress more
+ * as necessary.
+ */
+static ssize_t
+compress_filter_read(struct archive_read_filter *self, const void **pblock)
+{
+ struct private_data *state;
+ unsigned char *p, *start, *end;
+ int ret;
+
+ state = (struct private_data *)self->data;
+ if (state->end_of_stream) {
+ *pblock = NULL;
+ return (0);
+ }
+ p = start = (unsigned char *)state->out_block;
+ end = start + state->out_block_size;
+
+ while (p < end && !state->end_of_stream) {
+ if (state->stackp > state->stack) {
+ *p++ = *--state->stackp;
+ } else {
+ ret = next_code(self);
+ if (ret == -1)
+ state->end_of_stream = ret;
+ else if (ret != ARCHIVE_OK)
+ return (ret);
+ }
+ }
+
+ *pblock = start;
+ return (p - start);
+}
+
+/*
+ * Clean up the reader.
+ */
+static int
+compress_bidder_free(struct archive_read_filter_bidder *self)
+{
+ self->data = NULL;
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Close and release the filter.
+ */
+static int
+compress_filter_close(struct archive_read_filter *self)
+{
+ struct private_data *state = (struct private_data *)self->data;
+
+ free(state->out_block);
+ free(state);
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Process the next code and fill the stack with the expansion
+ * of the code. Returns ARCHIVE_FATAL if there is a fatal I/O or
+ * format error, ARCHIVE_EOF if we hit end of data, ARCHIVE_OK otherwise.
+ */
+static int
+next_code(struct archive_read_filter *self)
+{
+ struct private_data *state = (struct private_data *)self->data;
+ int code, newcode;
+
+ static int debug_buff[1024];
+ static unsigned debug_index;
+
+ code = newcode = getbits(self, state->bits);
+ if (code < 0)
+ return (code);
+
+ debug_buff[debug_index++] = code;
+ if (debug_index >= sizeof(debug_buff)/sizeof(debug_buff[0]))
+ debug_index = 0;
+
+ /* If it's a reset code, reset the dictionary. */
+ if ((code == 256) && state->use_reset_code) {
+ /*
+ * The original 'compress' implementation blocked its
+ * I/O in a manner that resulted in junk bytes being
+ * inserted after every reset. The next section skips
+ * this junk. (Yes, the number of *bytes* to skip is
+ * a function of the current *bit* length.)
+ */
+ int skip_bytes = state->bits -
+ (state->bytes_in_section % state->bits);
+ skip_bytes %= state->bits;
+ state->bits_avail = 0; /* Discard rest of this byte. */
+ while (skip_bytes-- > 0) {
+ code = getbits(self, 8);
+ if (code < 0)
+ return (code);
+ }
+ /* Now, actually do the reset. */
+ state->bytes_in_section = 0;
+ state->bits = 9;
+ state->section_end_code = (1 << state->bits) - 1;
+ state->free_ent = 257;
+ state->oldcode = -1;
+ return (next_code(self));
+ }
+
+ if (code > state->free_ent) {
+ /* An invalid code is a fatal error. */
+ archive_set_error(&(self->archive->archive), -1,
+ "Invalid compressed data");
+ return (ARCHIVE_FATAL);
+ }
+
+ /* Special case for KwKwK string. */
+ if (code >= state->free_ent) {
+ *state->stackp++ = state->finbyte;
+ code = state->oldcode;
+ }
+
+ /* Generate output characters in reverse order. */
+ while (code >= 256) {
+ *state->stackp++ = state->suffix[code];
+ code = state->prefix[code];
+ }
+ *state->stackp++ = state->finbyte = code;
+
+ /* Generate the new entry. */
+ code = state->free_ent;
+ if (code < state->maxcode && state->oldcode >= 0) {
+ state->prefix[code] = state->oldcode;
+ state->suffix[code] = state->finbyte;
+ ++state->free_ent;
+ }
+ if (state->free_ent > state->section_end_code) {
+ state->bits++;
+ state->bytes_in_section = 0;
+ if (state->bits == state->maxcode_bits)
+ state->section_end_code = state->maxcode;
+ else
+ state->section_end_code = (1 << state->bits) - 1;
+ }
+
+ /* Remember previous code. */
+ state->oldcode = newcode;
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Return next 'n' bits from stream.
+ *
+ * -1 indicates end of available data.
+ */
+static int
+getbits(struct archive_read_filter *self, int n)
+{
+ struct private_data *state = (struct private_data *)self->data;
+ int code;
+ ssize_t ret;
+ static const int mask[] = {
+ 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff,
+ 0x1ff, 0x3ff, 0x7ff, 0xfff, 0x1fff, 0x3fff, 0x7fff, 0xffff
+ };
+
+ while (state->bits_avail < n) {
+ if (state->avail_in <= 0) {
+ if (state->consume_unnotified) {
+ __archive_read_filter_consume(self->upstream,
+ state->consume_unnotified);
+ state->consume_unnotified = 0;
+ }
+ state->next_in
+ = __archive_read_filter_ahead(self->upstream,
+ 1, &ret);
+ if (ret == 0)
+ return (-1);
+ if (ret < 0 || state->next_in == NULL)
+ return (ARCHIVE_FATAL);
+ state->consume_unnotified = state->avail_in = ret;
+ }
+ state->bit_buffer |= *state->next_in++ << state->bits_avail;
+ state->avail_in--;
+ state->bits_avail += 8;
+ state->bytes_in_section++;
+ }
+
+ code = state->bit_buffer;
+ state->bit_buffer >>= n;
+ state->bits_avail -= n;
+
+ return (code & mask[n]);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_gzip.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_gzip.c
new file mode 100644
index 000000000..9d03b2b2c
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_gzip.c
@@ -0,0 +1,476 @@
+/*-
+ * 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$");
+
+
+#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_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_ZLIB_H
+#include <cm_zlib.h>
+#endif
+
+#include "archive.h"
+#include "archive_private.h"
+#include "archive_read_private.h"
+
+#ifdef HAVE_ZLIB_H
+struct private_data {
+ z_stream stream;
+ char in_stream;
+ unsigned char *out_block;
+ size_t out_block_size;
+ int64_t total_out;
+ unsigned long crc;
+ char eof; /* True = found end of compressed data. */
+};
+
+/* Gzip Filter. */
+static ssize_t gzip_filter_read(struct archive_read_filter *, const void **);
+static int gzip_filter_close(struct archive_read_filter *);
+#endif
+
+/*
+ * Note that we can detect gzip 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 zlib is unavailable.
+ *
+ * TODO: If zlib is unavailable, gzip_bidder_init() should
+ * use the compress_program framework to try to fire up an external
+ * gunzip program.
+ */
+static int gzip_bidder_bid(struct archive_read_filter_bidder *,
+ struct archive_read_filter *);
+static int gzip_bidder_init(struct archive_read_filter *);
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+/* Deprecated; remove in libarchive 4.0 */
+int
+archive_read_support_compression_gzip(struct archive *a)
+{
+ return archive_read_support_filter_gzip(a);
+}
+#endif
+
+int
+archive_read_support_filter_gzip(struct archive *_a)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ struct archive_read_filter_bidder *bidder;
+
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_filter_gzip");
+
+ if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ bidder->data = NULL;
+ bidder->bid = gzip_bidder_bid;
+ bidder->init = gzip_bidder_init;
+ bidder->options = NULL;
+ bidder->free = NULL; /* No data, so no cleanup necessary. */
+ /* Signal the extent of gzip support with the return value here. */
+#if HAVE_ZLIB_H
+ return (ARCHIVE_OK);
+#else
+ archive_set_error(_a, ARCHIVE_ERRNO_MISC,
+ "Using external gunzip program");
+ return (ARCHIVE_WARN);
+#endif
+}
+
+/*
+ * Read and verify the header.
+ *
+ * Returns zero if the header couldn't be validated, else returns
+ * number of bytes in header. If pbits is non-NULL, it receives a
+ * count of bits verified, suitable for use by bidder.
+ */
+static int
+peek_at_header(struct archive_read_filter *filter, int *pbits)
+{
+ const unsigned char *p;
+ ssize_t avail, len;
+ int bits = 0;
+ int header_flags;
+
+ /* Start by looking at the first ten bytes of the header, which
+ * is all fixed layout. */
+ len = 10;
+ p = __archive_read_filter_ahead(filter, len, &avail);
+ if (p == NULL || avail == 0)
+ return (0);
+ /* We only support deflation- third byte must be 0x08. */
+ if (memcmp(p, "\x1F\x8B\x08", 3) != 0)
+ return (0);
+ bits += 24;
+ if ((p[3] & 0xE0)!= 0) /* No reserved flags set. */
+ return (0);
+ bits += 3;
+ header_flags = p[3];
+ /* Bytes 4-7 are mod time. */
+ /* Byte 8 is deflate flags. */
+ /* XXXX TODO: return deflate flags back to consume_header for use
+ in initializing the decompressor. */
+ /* Byte 9 is OS. */
+
+ /* Optional extra data: 2 byte length plus variable body. */
+ if (header_flags & 4) {
+ p = __archive_read_filter_ahead(filter, len + 2, &avail);
+ if (p == NULL)
+ return (0);
+ len += ((int)p[len + 1] << 8) | (int)p[len];
+ len += 2;
+ }
+
+ /* Null-terminated optional filename. */
+ if (header_flags & 8) {
+ do {
+ ++len;
+ if (avail < len)
+ p = __archive_read_filter_ahead(filter,
+ len, &avail);
+ if (p == NULL)
+ return (0);
+ } while (p[len - 1] != 0);
+ }
+
+ /* Null-terminated optional comment. */
+ if (header_flags & 16) {
+ do {
+ ++len;
+ if (avail < len)
+ p = __archive_read_filter_ahead(filter,
+ len, &avail);
+ if (p == NULL)
+ return (0);
+ } while (p[len - 1] != 0);
+ }
+
+ /* Optional header CRC */
+ if ((header_flags & 2)) {
+ p = __archive_read_filter_ahead(filter, len + 2, &avail);
+ if (p == NULL)
+ return (0);
+#if 0
+ int hcrc = ((int)p[len + 1] << 8) | (int)p[len];
+ int crc = /* XXX TODO: Compute header CRC. */;
+ if (crc != hcrc)
+ return (0);
+ bits += 16;
+#endif
+ len += 2;
+ }
+
+ if (pbits != NULL)
+ *pbits = bits;
+ return (len);
+}
+
+/*
+ * Bidder just verifies the header and returns the number of verified bits.
+ */
+static int
+gzip_bidder_bid(struct archive_read_filter_bidder *self,
+ struct archive_read_filter *filter)
+{
+ int bits_checked;
+
+ (void)self; /* UNUSED */
+
+ if (peek_at_header(filter, &bits_checked))
+ return (bits_checked);
+ return (0);
+}
+
+
+#ifndef HAVE_ZLIB_H
+
+/*
+ * If we don't have the library on this system, we can't do the
+ * decompression directly. We can, however, try to run gunzip
+ * in case that's available.
+ */
+static int
+gzip_bidder_init(struct archive_read_filter *self)
+{
+ int r;
+
+ r = __archive_read_program(self, "gunzip");
+ /* 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_COMPRESSION_GZIP;
+ self->name = "gzip";
+ return (r);
+}
+
+#else
+
+/*
+ * Initialize the filter object.
+ */
+static int
+gzip_bidder_init(struct archive_read_filter *self)
+{
+ struct private_data *state;
+ static const size_t out_block_size = 64 * 1024;
+ void *out_block;
+
+ self->code = ARCHIVE_COMPRESSION_GZIP;
+ self->name = "gzip";
+
+ state = (struct private_data *)calloc(sizeof(*state), 1);
+ out_block = (unsigned char *)malloc(out_block_size);
+ if (state == NULL || out_block == NULL) {
+ free(out_block);
+ free(state);
+ archive_set_error(&self->archive->archive, ENOMEM,
+ "Can't allocate data for gzip decompression");
+ return (ARCHIVE_FATAL);
+ }
+
+ self->data = state;
+ state->out_block_size = out_block_size;
+ state->out_block = out_block;
+ self->read = gzip_filter_read;
+ self->skip = NULL; /* not supported */
+ self->close = gzip_filter_close;
+
+ state->in_stream = 0; /* We're not actually within a stream yet. */
+
+ return (ARCHIVE_OK);
+}
+
+static int
+consume_header(struct archive_read_filter *self)
+{
+ struct private_data *state;
+ ssize_t avail;
+ size_t len;
+ int ret;
+
+ state = (struct private_data *)self->data;
+
+ /* If this is a real header, consume it. */
+ len = peek_at_header(self->upstream, NULL);
+ if (len == 0)
+ return (ARCHIVE_EOF);
+ __archive_read_filter_consume(self->upstream, len);
+
+ /* Initialize CRC accumulator. */
+ state->crc = crc32(0L, NULL, 0);
+
+ /* Initialize compression library. */
+ state->stream.next_in = (unsigned char *)(uintptr_t)
+ __archive_read_filter_ahead(self->upstream, 1, &avail);
+ state->stream.avail_in = avail;
+ ret = inflateInit2(&(state->stream),
+ -15 /* Don't check for zlib header */);
+
+ /* Decipher the error code. */
+ switch (ret) {
+ case Z_OK:
+ state->in_stream = 1;
+ return (ARCHIVE_OK);
+ case Z_STREAM_ERROR:
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Internal error initializing compression library: "
+ "invalid setup parameter");
+ break;
+ case Z_MEM_ERROR:
+ archive_set_error(&self->archive->archive, ENOMEM,
+ "Internal error initializing compression library: "
+ "out of memory");
+ break;
+ case Z_VERSION_ERROR:
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Internal error initializing compression library: "
+ "invalid library version");
+ break;
+ default:
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Internal error initializing compression library: "
+ " Zlib error %d", ret);
+ break;
+ }
+ return (ARCHIVE_FATAL);
+}
+
+static int
+consume_trailer(struct archive_read_filter *self)
+{
+ struct private_data *state;
+ const unsigned char *p;
+ ssize_t avail;
+
+ state = (struct private_data *)self->data;
+
+ state->in_stream = 0;
+ switch (inflateEnd(&(state->stream))) {
+ case Z_OK:
+ break;
+ default:
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Failed to clean up gzip decompressor");
+ return (ARCHIVE_FATAL);
+ }
+
+ /* GZip trailer is a fixed 8 byte structure. */
+ p = __archive_read_filter_ahead(self->upstream, 8, &avail);
+ if (p == NULL || avail == 0)
+ return (ARCHIVE_FATAL);
+
+ /* XXX TODO: Verify the length and CRC. */
+
+ /* We've verified the trailer, so consume it now. */
+ __archive_read_filter_consume(self->upstream, 8);
+
+ return (ARCHIVE_OK);
+}
+
+static ssize_t
+gzip_filter_read(struct archive_read_filter *self, const void **p)
+{
+ struct private_data *state;
+ size_t decompressed;
+ ssize_t avail_in;
+ int ret;
+
+ state = (struct private_data *)self->data;
+
+ /* Empty our output buffer. */
+ state->stream.next_out = state->out_block;
+ state->stream.avail_out = state->out_block_size;
+
+ /* Try to fill the output buffer. */
+ while (state->stream.avail_out > 0 && !state->eof) {
+ /* If we're not in a stream, read a header
+ * and initialize the decompression library. */
+ if (!state->in_stream) {
+ ret = consume_header(self);
+ if (ret == ARCHIVE_EOF) {
+ state->eof = 1;
+ break;
+ }
+ if (ret < ARCHIVE_OK)
+ return (ret);
+ }
+
+ /* Peek at the next available data. */
+ /* ZLib treats stream.next_in as const but doesn't declare
+ * it so, hence this ugly cast. */
+ state->stream.next_in = (unsigned char *)(uintptr_t)
+ __archive_read_filter_ahead(self->upstream, 1, &avail_in);
+ if (state->stream.next_in == NULL) {
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC,
+ "truncated gzip input");
+ return (ARCHIVE_FATAL);
+ }
+ state->stream.avail_in = avail_in;
+
+ /* Decompress and consume some of that data. */
+ ret = inflate(&(state->stream), 0);
+ switch (ret) {
+ case Z_OK: /* Decompressor made some progress. */
+ __archive_read_filter_consume(self->upstream,
+ avail_in - state->stream.avail_in);
+ break;
+ case Z_STREAM_END: /* Found end of stream. */
+ __archive_read_filter_consume(self->upstream,
+ avail_in - state->stream.avail_in);
+ /* Consume the stream trailer; release the
+ * decompression library. */
+ ret = consume_trailer(self);
+ if (ret < ARCHIVE_OK)
+ return (ret);
+ break;
+ default:
+ /* Return an error. */
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC,
+ "gzip decompression failed");
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ /* We've read as much as we can. */
+ decompressed = state->stream.next_out - state->out_block;
+ state->total_out += decompressed;
+ if (decompressed == 0)
+ *p = NULL;
+ else
+ *p = state->out_block;
+ return (decompressed);
+}
+
+/*
+ * Clean up the decompressor.
+ */
+static int
+gzip_filter_close(struct archive_read_filter *self)
+{
+ struct private_data *state;
+ int ret;
+
+ state = (struct private_data *)self->data;
+ ret = ARCHIVE_OK;
+
+ if (state->in_stream) {
+ switch (inflateEnd(&(state->stream))) {
+ case Z_OK:
+ break;
+ default:
+ archive_set_error(&(self->archive->archive),
+ ARCHIVE_ERRNO_MISC,
+ "Failed to clean up gzip compressor");
+ ret = ARCHIVE_FATAL;
+ }
+ }
+
+ free(state->out_block);
+ free(state);
+ return (ret);
+}
+
+#endif /* HAVE_ZLIB_H */
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_none.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_none.c
new file mode 100644
index 000000000..95e5cfdb1
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_none.c
@@ -0,0 +1,52 @@
+/*-
+ * 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$");
+
+#include "archive.h"
+#include "archive_private.h"
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+/* Deprecated; remove in libarchive 4.0 */
+int
+archive_read_support_compression_none(struct archive *a)
+{
+ return archive_read_support_filter_none(a);
+}
+#endif
+
+/*
+ * Uncompressed streams are handled implicitly by the read core,
+ * so this is now a no-op.
+ */
+int
+archive_read_support_filter_none(struct archive *a)
+{
+ archive_check_magic(a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_filter_none");
+
+ return (ARCHIVE_OK);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_program.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_program.c
new file mode 100644
index 000000000..b05eb0342
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_program.c
@@ -0,0 +1,476 @@
+/*-
+ * Copyright (c) 2007 Joerg Sonnenberger
+ * 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_SYS_WAIT_H
+# include <sys/wait.h>
+#endif
+#ifdef HAVE_ERRNO_H
+# include <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+#ifdef HAVE_LIMITS_H
+# include <limits.h>
+#endif
+#ifdef HAVE_SIGNAL_H
+# include <signal.h>
+#endif
+#ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#include "archive.h"
+#include "archive_private.h"
+#include "archive_read_private.h"
+
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+/* Deprecated; remove in libarchive 4.0 */
+int
+archive_read_support_compression_program(struct archive *a, const char *cmd)
+{
+ return archive_read_support_filter_program(a, cmd);
+}
+
+int
+archive_read_support_compression_program_signature(struct archive *a,
+ const char *cmd, const void *signature, size_t signature_len)
+{
+ return archive_read_support_filter_program_signature(a,
+ cmd, signature, signature_len);
+}
+#endif
+
+int
+archive_read_support_filter_program(struct archive *a, const char *cmd)
+{
+ return (archive_read_support_filter_program_signature(a, cmd, NULL, 0));
+}
+
+
+/* This capability is only available on POSIX systems. */
+#if (!defined(HAVE_PIPE) || !defined(HAVE_FCNTL) || \
+ !(defined(HAVE_FORK) || defined(HAVE_VFORK))) && (!defined(_WIN32) || defined(__CYGWIN__))
+
+/*
+ * On non-Posix systems, allow the program to build, but choke if
+ * this function is actually invoked.
+ */
+int
+archive_read_support_filter_program_signature(struct archive *_a,
+ const char *cmd, const void *signature, size_t signature_len)
+{
+ (void)_a; /* UNUSED */
+ (void)cmd; /* UNUSED */
+ (void)signature; /* UNUSED */
+ (void)signature_len; /* UNUSED */
+
+ archive_set_error(_a, -1,
+ "External compression programs not supported on this platform");
+ return (ARCHIVE_FATAL);
+}
+
+int
+__archive_read_program(struct archive_read_filter *self, const char *cmd)
+{
+ (void)self; /* UNUSED */
+ (void)cmd; /* UNUSED */
+
+ archive_set_error(&self->archive->archive, -1,
+ "External compression programs not supported on this platform");
+ return (ARCHIVE_FATAL);
+}
+
+#else
+
+#include "filter_fork.h"
+
+/*
+ * The bidder object stores the command and the signature to watch for.
+ * The 'inhibit' entry here is used to ensure that unchecked filters never
+ * bid twice in the same pipeline.
+ */
+struct program_bidder {
+ char *cmd;
+ void *signature;
+ size_t signature_len;
+ int inhibit;
+};
+
+static int program_bidder_bid(struct archive_read_filter_bidder *,
+ struct archive_read_filter *upstream);
+static int program_bidder_init(struct archive_read_filter *);
+static int program_bidder_free(struct archive_read_filter_bidder *);
+
+/*
+ * The actual filter needs to track input and output data.
+ */
+struct program_filter {
+ char *description;
+ pid_t child;
+ int exit_status;
+ int waitpid_return;
+ int child_stdin, child_stdout;
+
+ char *out_buf;
+ size_t out_buf_len;
+};
+
+static ssize_t program_filter_read(struct archive_read_filter *,
+ const void **);
+static int program_filter_close(struct archive_read_filter *);
+
+int
+archive_read_support_filter_program_signature(struct archive *_a,
+ const char *cmd, const void *signature, size_t signature_len)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ struct archive_read_filter_bidder *bidder;
+ struct program_bidder *state;
+
+ /*
+ * Get a bidder object from the read core.
+ */
+ if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ /*
+ * Allocate our private state.
+ */
+ state = (struct program_bidder *)calloc(sizeof (*state), 1);
+ if (state == NULL)
+ return (ARCHIVE_FATAL);
+ state->cmd = strdup(cmd);
+ if (signature != NULL && signature_len > 0) {
+ state->signature_len = signature_len;
+ state->signature = malloc(signature_len);
+ memcpy(state->signature, signature, signature_len);
+ }
+
+ /*
+ * Fill in the bidder object.
+ */
+ bidder->data = state;
+ bidder->bid = program_bidder_bid;
+ bidder->init = program_bidder_init;
+ bidder->options = NULL;
+ bidder->free = program_bidder_free;
+ return (ARCHIVE_OK);
+}
+
+static int
+program_bidder_free(struct archive_read_filter_bidder *self)
+{
+ struct program_bidder *state = (struct program_bidder *)self->data;
+ free(state->cmd);
+ free(state->signature);
+ free(self->data);
+ return (ARCHIVE_OK);
+}
+
+/*
+ * If we do have a signature, bid only if that matches.
+ *
+ * If there's no signature, we bid INT_MAX the first time
+ * we're called, then never bid again.
+ */
+static int
+program_bidder_bid(struct archive_read_filter_bidder *self,
+ struct archive_read_filter *upstream)
+{
+ struct program_bidder *state = self->data;
+ const char *p;
+
+ /* If we have a signature, use that to match. */
+ if (state->signature_len > 0) {
+ p = __archive_read_filter_ahead(upstream,
+ state->signature_len, NULL);
+ if (p == NULL)
+ return (0);
+ /* No match, so don't bid. */
+ if (memcmp(p, state->signature, state->signature_len) != 0)
+ return (0);
+ return ((int)state->signature_len * 8);
+ }
+
+ /* Otherwise, bid once and then never bid again. */
+ if (state->inhibit)
+ return (0);
+ state->inhibit = 1;
+ return (INT_MAX);
+}
+
+/*
+ * Shut down the child, return ARCHIVE_OK if it exited normally.
+ *
+ * Note that the return value is sticky; if we're called again,
+ * we won't reap the child again, but we will return the same status
+ * (including error message if the child came to a bad end).
+ */
+static int
+child_stop(struct archive_read_filter *self, struct program_filter *state)
+{
+ /* Close our side of the I/O with the child. */
+ if (state->child_stdin != -1) {
+ close(state->child_stdin);
+ state->child_stdin = -1;
+ }
+ if (state->child_stdout != -1) {
+ close(state->child_stdout);
+ state->child_stdout = -1;
+ }
+
+ if (state->child != 0) {
+ /* Reap the child. */
+ do {
+ state->waitpid_return
+ = waitpid(state->child, &state->exit_status, 0);
+ } while (state->waitpid_return == -1 && errno == EINTR);
+ state->child = 0;
+ }
+
+ if (state->waitpid_return < 0) {
+ /* waitpid() failed? This is ugly. */
+ archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
+ "Child process exited badly");
+ return (ARCHIVE_WARN);
+ }
+
+#if !defined(_WIN32) || defined(__CYGWIN__)
+ if (WIFSIGNALED(state->exit_status)) {
+#ifdef SIGPIPE
+ /* If the child died because we stopped reading before
+ * it was done, that's okay. Some archive formats
+ * have padding at the end that we routinely ignore. */
+ /* The alternative to this would be to add a step
+ * before close(child_stdout) above to read from the
+ * child until the child has no more to write. */
+ if (WTERMSIG(state->exit_status) == SIGPIPE)
+ return (ARCHIVE_OK);
+#endif
+ archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
+ "Child process exited with signal %d",
+ WTERMSIG(state->exit_status));
+ return (ARCHIVE_WARN);
+ }
+#endif /* !_WIN32 || __CYGWIN__ */
+
+ if (WIFEXITED(state->exit_status)) {
+ if (WEXITSTATUS(state->exit_status) == 0)
+ return (ARCHIVE_OK);
+
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Child process exited with status %d",
+ WEXITSTATUS(state->exit_status));
+ return (ARCHIVE_WARN);
+ }
+
+ return (ARCHIVE_WARN);
+}
+
+/*
+ * Use select() to decide whether the child is ready for read or write.
+ */
+static ssize_t
+child_read(struct archive_read_filter *self, char *buf, size_t buf_len)
+{
+ struct program_filter *state = self->data;
+ ssize_t ret, requested, avail;
+ const char *p;
+
+ requested = buf_len > SSIZE_MAX ? SSIZE_MAX : buf_len;
+
+ for (;;) {
+ do {
+ ret = read(state->child_stdout, buf, requested);
+ } while (ret == -1 && errno == EINTR);
+
+ if (ret > 0)
+ return (ret);
+ if (ret == 0 || (ret == -1 && errno == EPIPE))
+ /* Child has closed its output; reap the child
+ * and return the status. */
+ return (child_stop(self, state));
+ if (ret == -1 && errno != EAGAIN)
+ return (-1);
+
+ if (state->child_stdin == -1) {
+ /* Block until child has some I/O ready. */
+ __archive_check_child(state->child_stdin,
+ state->child_stdout);
+ continue;
+ }
+
+ /* Get some more data from upstream. */
+ p = __archive_read_filter_ahead(self->upstream, 1, &avail);
+ if (p == NULL) {
+ close(state->child_stdin);
+ state->child_stdin = -1;
+ fcntl(state->child_stdout, F_SETFL, 0);
+ if (avail < 0)
+ return (avail);
+ continue;
+ }
+
+ do {
+ ret = write(state->child_stdin, p, avail);
+ } while (ret == -1 && errno == EINTR);
+
+ if (ret > 0) {
+ /* Consume whatever we managed to write. */
+ __archive_read_filter_consume(self->upstream, ret);
+ } else if (ret == -1 && errno == EAGAIN) {
+ /* Block until child has some I/O ready. */
+ __archive_check_child(state->child_stdin,
+ state->child_stdout);
+ } else {
+ /* Write failed. */
+ close(state->child_stdin);
+ state->child_stdin = -1;
+ fcntl(state->child_stdout, F_SETFL, 0);
+ /* If it was a bad error, we're done; otherwise
+ * it was EPIPE or EOF, and we can still read
+ * from the child. */
+ if (ret == -1 && errno != EPIPE)
+ return (-1);
+ }
+ }
+}
+
+int
+__archive_read_program(struct archive_read_filter *self, const char *cmd)
+{
+ struct program_filter *state;
+ static const size_t out_buf_len = 65536;
+ char *out_buf;
+ char *description;
+ const char *prefix = "Program: ";
+
+ state = (struct program_filter *)calloc(1, sizeof(*state));
+ out_buf = (char *)malloc(out_buf_len);
+ description = (char *)malloc(strlen(prefix) + strlen(cmd) + 1);
+ if (state == NULL || out_buf == NULL || description == NULL) {
+ archive_set_error(&self->archive->archive, ENOMEM,
+ "Can't allocate input data");
+ free(state);
+ free(out_buf);
+ free(description);
+ return (ARCHIVE_FATAL);
+ }
+
+ self->code = ARCHIVE_COMPRESSION_PROGRAM;
+ state->description = description;
+ strcpy(state->description, prefix);
+ strcat(state->description, cmd);
+ self->name = state->description;
+
+ state->out_buf = out_buf;
+ state->out_buf_len = out_buf_len;
+
+ if ((state->child = __archive_create_child(cmd,
+ &state->child_stdin, &state->child_stdout)) == -1) {
+ free(state->out_buf);
+ free(state);
+ archive_set_error(&self->archive->archive, EINVAL,
+ "Can't initialize filter; unable to run program \"%s\"", cmd);
+ return (ARCHIVE_FATAL);
+ }
+
+ self->data = state;
+ self->read = program_filter_read;
+ self->skip = NULL;
+ self->close = program_filter_close;
+
+ /* XXX Check that we can read at least one byte? */
+ return (ARCHIVE_OK);
+}
+
+static int
+program_bidder_init(struct archive_read_filter *self)
+{
+ struct program_bidder *bidder_state;
+
+ bidder_state = (struct program_bidder *)self->bidder->data;
+ return (__archive_read_program(self, bidder_state->cmd));
+}
+
+static ssize_t
+program_filter_read(struct archive_read_filter *self, const void **buff)
+{
+ struct program_filter *state;
+ ssize_t bytes;
+ size_t total;
+ char *p;
+
+ state = (struct program_filter *)self->data;
+
+ total = 0;
+ p = state->out_buf;
+ while (state->child_stdout != -1 && total < state->out_buf_len) {
+ bytes = child_read(self, p, state->out_buf_len - total);
+ if (bytes < 0)
+ /* No recovery is possible if we can no longer
+ * read from the child. */
+ return (ARCHIVE_FATAL);
+ if (bytes == 0)
+ /* We got EOF from the child. */
+ break;
+ total += bytes;
+ p += bytes;
+ }
+
+ *buff = state->out_buf;
+ return (total);
+}
+
+static int
+program_filter_close(struct archive_read_filter *self)
+{
+ struct program_filter *state;
+ int e;
+
+ state = (struct program_filter *)self->data;
+ e = child_stop(self, state);
+
+ /* Release our private data. */
+ free(state->out_buf);
+ free(state->description);
+ free(state);
+
+ return (e);
+}
+
+#endif /* !defined(HAVE_PIPE) || !defined(HAVE_VFORK) || !defined(HAVE_FCNTL) */
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_rpm.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_rpm.c
new file mode 100644
index 000000000..7dbfc0ebc
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_rpm.c
@@ -0,0 +1,288 @@
+/*-
+ * Copyright (c) 2009 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_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#include "archive.h"
+#include "archive_endian.h"
+#include "archive_private.h"
+#include "archive_read_private.h"
+
+struct rpm {
+ int64_t total_in;
+ size_t hpos;
+ size_t hlen;
+ unsigned char header[16];
+ enum {
+ ST_LEAD, /* Skipping 'Lead' section. */
+ ST_HEADER, /* Reading 'Header' section;
+ * first 16 bytes. */
+ ST_HEADER_DATA, /* Skipping 'Header' section. */
+ ST_PADDING, /* Skipping padding data after the
+ * 'Header' section. */
+ ST_ARCHIVE /* Reading 'Archive' section. */
+ } state;
+ int first_header;
+};
+#define RPM_LEAD_SIZE 96 /* Size of 'Lead' section. */
+
+static int rpm_bidder_bid(struct archive_read_filter_bidder *,
+ struct archive_read_filter *);
+static int rpm_bidder_init(struct archive_read_filter *);
+
+static ssize_t rpm_filter_read(struct archive_read_filter *,
+ const void **);
+static int rpm_filter_close(struct archive_read_filter *);
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+/* Deprecated; remove in libarchive 4.0 */
+int
+archive_read_support_compression_rpm(struct archive *a)
+{
+ return archive_read_support_filter_rpm(a);
+}
+#endif
+
+int
+archive_read_support_filter_rpm(struct archive *_a)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ struct archive_read_filter_bidder *bidder;
+
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_filter_rpm");
+
+ if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ bidder->data = NULL;
+ bidder->bid = rpm_bidder_bid;
+ bidder->init = rpm_bidder_init;
+ bidder->options = NULL;
+ bidder->free = NULL;
+ return (ARCHIVE_OK);
+}
+
+static int
+rpm_bidder_bid(struct archive_read_filter_bidder *self,
+ struct archive_read_filter *filter)
+{
+ const unsigned char *b;
+ ssize_t avail;
+ int bits_checked;
+
+ (void)self; /* UNUSED */
+
+ b = __archive_read_filter_ahead(filter, 8, &avail);
+ if (b == NULL)
+ return (0);
+
+ bits_checked = 0;
+ /*
+ * Verify Header Magic Bytes : 0XED 0XAB 0XEE 0XDB
+ */
+ if (memcmp(b, "\xED\xAB\xEE\xDB", 4) != 0)
+ return (0);
+ bits_checked += 32;
+ /*
+ * Check major version.
+ */
+ if (b[4] != 3 && b[4] != 4)
+ return (0);
+ bits_checked += 8;
+ /*
+ * Check package type; binary or source.
+ */
+ if (b[6] != 0)
+ return (0);
+ bits_checked += 8;
+ if (b[7] != 0 && b[7] != 1)
+ return (0);
+ bits_checked += 8;
+
+ return (bits_checked);
+}
+
+static int
+rpm_bidder_init(struct archive_read_filter *self)
+{
+ struct rpm *rpm;
+
+ self->code = ARCHIVE_COMPRESSION_RPM;
+ self->name = "rpm";
+ self->read = rpm_filter_read;
+ self->skip = NULL; /* not supported */
+ self->close = rpm_filter_close;
+
+ rpm = (struct rpm *)calloc(sizeof(*rpm), 1);
+ if (rpm == NULL) {
+ archive_set_error(&self->archive->archive, ENOMEM,
+ "Can't allocate data for rpm");
+ return (ARCHIVE_FATAL);
+ }
+
+ self->data = rpm;
+ rpm->state = ST_LEAD;
+
+ return (ARCHIVE_OK);
+}
+
+static ssize_t
+rpm_filter_read(struct archive_read_filter *self, const void **buff)
+{
+ struct rpm *rpm;
+ const unsigned char *b;
+ ssize_t avail_in, total;
+ size_t used, n;
+ uint32_t section;
+ uint32_t bytes;
+
+ rpm = (struct rpm *)self->data;
+ *buff = NULL;
+ total = avail_in = 0;
+ b = NULL;
+ used = 0;
+ do {
+ if (b == NULL) {
+ b = __archive_read_filter_ahead(self->upstream, 1,
+ &avail_in);
+ if (b == NULL) {
+ if (avail_in < 0)
+ return (ARCHIVE_FATAL);
+ else
+ break;
+ }
+ }
+
+ switch (rpm->state) {
+ case ST_LEAD:
+ if (rpm->total_in + avail_in < RPM_LEAD_SIZE)
+ used += avail_in;
+ else {
+ n = RPM_LEAD_SIZE - rpm->total_in;
+ used += n;
+ b += n;
+ rpm->state = ST_HEADER;
+ rpm->hpos = 0;
+ rpm->hlen = 0;
+ rpm->first_header = 1;
+ }
+ break;
+ case ST_HEADER:
+ n = 16 - rpm->hpos;
+ if (n > avail_in - used)
+ n = avail_in - used;
+ memcpy(rpm->header+rpm->hpos, b, n);
+ b += n;
+ used += n;
+ rpm->hpos += n;
+
+ if (rpm->hpos == 16) {
+ if (rpm->header[0] != 0x8e ||
+ rpm->header[1] != 0xad ||
+ rpm->header[2] != 0xe8 ||
+ rpm->header[3] != 0x01) {
+ if (rpm->first_header) {
+ archive_set_error(
+ &self->archive->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Unrecoginized rpm header");
+ return (ARCHIVE_FATAL);
+ }
+ rpm->state = ST_ARCHIVE;
+ *buff = rpm->header;
+ total = rpm->hpos;
+ break;
+ }
+ /* Calculate 'Header' length. */
+ section = archive_be32dec(rpm->header+8);
+ bytes = archive_be32dec(rpm->header+12);
+ rpm->hlen = 16 + section * 16 + bytes;
+ rpm->state = ST_HEADER_DATA;
+ rpm->first_header = 0;
+ }
+ break;
+ case ST_HEADER_DATA:
+ n = rpm->hlen - rpm->hpos;
+ if (n > avail_in - used)
+ n = avail_in - used;
+ b += n;
+ used += n;
+ rpm->hpos += n;
+ if (rpm->hpos == rpm->hlen)
+ rpm->state = ST_PADDING;
+ break;
+ case ST_PADDING:
+ while (used < (size_t)avail_in) {
+ if (*b != 0) {
+ /* Read next header. */
+ rpm->state = ST_HEADER;
+ rpm->hpos = 0;
+ rpm->hlen = 0;
+ break;
+ }
+ b++;
+ used++;
+ }
+ break;
+ case ST_ARCHIVE:
+ *buff = b;
+ total = avail_in;
+ used = avail_in;
+ break;
+ }
+ if (used == (size_t)avail_in) {
+ rpm->total_in += used;
+ __archive_read_filter_consume(self->upstream, used);
+ b = NULL;
+ used = 0;
+ }
+ } while (total == 0 && avail_in > 0);
+
+ if (used > 0 && b != NULL) {
+ rpm->total_in += used;
+ __archive_read_filter_consume(self->upstream, used);
+ }
+ return (total);
+}
+
+static int
+rpm_filter_close(struct archive_read_filter *self)
+{
+ struct rpm *rpm;
+
+ rpm = (struct rpm *)self->data;
+ free(rpm);
+
+ return (ARCHIVE_OK);
+}
+
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_uu.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_uu.c
new file mode 100644
index 000000000..a75ef7560
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_uu.c
@@ -0,0 +1,680 @@
+/*-
+ * Copyright (c) 2009-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"
+__FBSDID("$FreeBSD$");
+
+#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_private.h"
+#include "archive_read_private.h"
+
+/* Maximum lookahead during bid phase */
+#define UUENCODE_BID_MAX_READ 128*1024 /* in bytes */
+
+struct uudecode {
+ int64_t total;
+ unsigned char *in_buff;
+#define IN_BUFF_SIZE (1024)
+ int in_cnt;
+ size_t in_allocated;
+ unsigned char *out_buff;
+#define OUT_BUFF_SIZE (64 * 1024)
+ int state;
+#define ST_FIND_HEAD 0
+#define ST_READ_UU 1
+#define ST_UUEND 2
+#define ST_READ_BASE64 3
+};
+
+static int uudecode_bidder_bid(struct archive_read_filter_bidder *,
+ struct archive_read_filter *filter);
+static int uudecode_bidder_init(struct archive_read_filter *);
+
+static ssize_t uudecode_filter_read(struct archive_read_filter *,
+ const void **);
+static int uudecode_filter_close(struct archive_read_filter *);
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+/* Deprecated; remove in libarchive 4.0 */
+int
+archive_read_support_compression_uu(struct archive *a)
+{
+ return archive_read_support_filter_uu(a);
+}
+#endif
+
+int
+archive_read_support_filter_uu(struct archive *_a)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ struct archive_read_filter_bidder *bidder;
+
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_filter_uu");
+
+ if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ bidder->data = NULL;
+ bidder->bid = uudecode_bidder_bid;
+ bidder->init = uudecode_bidder_init;
+ bidder->options = NULL;
+ bidder->free = NULL;
+ return (ARCHIVE_OK);
+}
+
+static const unsigned char ascii[256] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '\n', 0, 0, '\r', 0, 0, /* 00 - 0F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 - 1F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 20 - 2F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 30 - 3F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 40 - 4F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 50 - 5F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 60 - 6F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* 70 - 7F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 - 8F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90 - 9F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A0 - AF */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* B0 - BF */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* C0 - CF */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* D0 - DF */
+ 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 */
+};
+
+static const unsigned char uuchar[256] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 00 - 0F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 - 1F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 20 - 2F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 30 - 3F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 40 - 4F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 50 - 5F */
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 60 - 6F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 70 - 7F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 - 8F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90 - 9F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A0 - AF */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* B0 - BF */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* C0 - CF */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* D0 - DF */
+ 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 */
+};
+
+static const unsigned char base64[256] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 00 - 0F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 - 1F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, /* 20 - 2F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, /* 30 - 3F */
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 40 - 4F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 50 - 5F */
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 60 - 6F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 70 - 7F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 - 8F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90 - 9F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A0 - AF */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* B0 - BF */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* C0 - CF */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* D0 - DF */
+ 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 */
+};
+
+static const int base64num[128] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, /* 00 - 0F */
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, /* 10 - 1F */
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 62, 0, 0, 0, 63, /* 20 - 2F */
+ 52, 53, 54, 55, 56, 57, 58, 59,
+ 60, 61, 0, 0, 0, 0, 0, 0, /* 30 - 3F */
+ 0, 0, 1, 2, 3, 4, 5, 6,
+ 7, 8, 9, 10, 11, 12, 13, 14, /* 40 - 4F */
+ 15, 16, 17, 18, 19, 20, 21, 22,
+ 23, 24, 25, 0, 0, 0, 0, 0, /* 50 - 5F */
+ 0, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 36, 37, 38, 39, 40, /* 60 - 6F */
+ 41, 42, 43, 44, 45, 46, 47, 48,
+ 49, 50, 51, 0, 0, 0, 0, 0, /* 70 - 7F */
+};
+
+static ssize_t
+get_line(const unsigned char *b, ssize_t avail, ssize_t *nlsize)
+{
+ ssize_t len;
+
+ len = 0;
+ while (len < avail) {
+ switch (ascii[*b]) {
+ case 0: /* Non-ascii character or control character. */
+ if (nlsize != NULL)
+ *nlsize = 0;
+ return (-1);
+ case '\r':
+ if (avail-len > 1 && b[1] == '\n') {
+ if (nlsize != NULL)
+ *nlsize = 2;
+ return (len+2);
+ }
+ /* FALL THROUGH */
+ case '\n':
+ if (nlsize != NULL)
+ *nlsize = 1;
+ return (len+1);
+ case 1:
+ b++;
+ len++;
+ break;
+ }
+ }
+ if (nlsize != NULL)
+ *nlsize = 0;
+ return (avail);
+}
+
+static ssize_t
+bid_get_line(struct archive_read_filter *filter,
+ const unsigned char **b, ssize_t *avail, ssize_t *ravail,
+ ssize_t *nl, size_t* nbytes_read)
+{
+ ssize_t len;
+ int quit;
+
+ quit = 0;
+ if (*avail == 0) {
+ *nl = 0;
+ len = 0;
+ } else
+ len = get_line(*b, *avail, nl);
+
+ /*
+ * Read bytes more while it does not reach the end of line.
+ */
+ while (*nl == 0 && len == *avail && !quit &&
+ *nbytes_read < UUENCODE_BID_MAX_READ) {
+ ssize_t diff = *ravail - *avail;
+ size_t nbytes_req = (*ravail+1023) & ~1023U;
+ ssize_t tested;
+
+ /* Increase reading bytes if it is not enough to at least
+ * new two lines. */
+ if (nbytes_req < (size_t)*ravail + 160)
+ nbytes_req <<= 1;
+
+ *b = __archive_read_filter_ahead(filter, nbytes_req, avail);
+ if (*b == NULL) {
+ if (*ravail >= *avail)
+ return (0);
+ /* Reading bytes reaches the end of a stream. */
+ *b = __archive_read_filter_ahead(filter, *avail, avail);
+ quit = 1;
+ }
+ *nbytes_read = *avail;
+ *ravail = *avail;
+ *b += diff;
+ *avail -= diff;
+ tested = len;/* Skip some bytes we already determinated. */
+ len = get_line(*b + tested, *avail - tested, nl);
+ if (len >= 0)
+ len += tested;
+ }
+ return (len);
+}
+
+#define UUDECODE(c) (((c) - 0x20) & 0x3f)
+
+static int
+uudecode_bidder_bid(struct archive_read_filter_bidder *self,
+ struct archive_read_filter *filter)
+{
+ const unsigned char *b;
+ ssize_t avail, ravail;
+ ssize_t len, nl;
+ int l;
+ int firstline;
+ size_t nbytes_read;
+
+ (void)self; /* UNUSED */
+
+ b = __archive_read_filter_ahead(filter, 1, &avail);
+ if (b == NULL)
+ return (0);
+
+ firstline = 20;
+ ravail = avail;
+ nbytes_read = avail;
+ for (;;) {
+ len = bid_get_line(filter, &b, &avail, &ravail, &nl, &nbytes_read);
+ if (len < 0 || nl == 0)
+ return (0); /* No match found. */
+ if (len - nl >= 11 && memcmp(b, "begin ", 6) == 0)
+ l = 6;
+ else if (len -nl >= 18 && memcmp(b, "begin-base64 ", 13) == 0)
+ l = 13;
+ else
+ l = 0;
+
+ if (l > 0 && (b[l] < '0' || b[l] > '7' ||
+ b[l+1] < '0' || b[l+1] > '7' ||
+ b[l+2] < '0' || b[l+2] > '7' || b[l+3] != ' '))
+ l = 0;
+
+ b += len;
+ avail -= len;
+ if (l)
+ break;
+ firstline = 0;
+
+ /* Do not read more than UUENCODE_BID_MAX_READ bytes */
+ if (nbytes_read >= UUENCODE_BID_MAX_READ)
+ return (0);
+ }
+ if (!avail)
+ return (0);
+ len = bid_get_line(filter, &b, &avail, &ravail, &nl, &nbytes_read);
+ if (len < 0 || nl == 0)
+ return (0);/* There are non-ascii characters. */
+ avail -= len;
+
+ if (l == 6) {
+ if (!uuchar[*b])
+ return (0);
+ /* Get a length of decoded bytes. */
+ l = UUDECODE(*b++); len--;
+ if (l > 45)
+ /* Normally, maximum length is 45(character 'M'). */
+ return (0);
+ while (l && len-nl > 0) {
+ if (l > 0) {
+ if (!uuchar[*b++])
+ return (0);
+ if (!uuchar[*b++])
+ return (0);
+ len -= 2;
+ --l;
+ }
+ if (l > 0) {
+ if (!uuchar[*b++])
+ return (0);
+ --len;
+ --l;
+ }
+ if (l > 0) {
+ if (!uuchar[*b++])
+ return (0);
+ --len;
+ --l;
+ }
+ }
+ if (len-nl < 0)
+ return (0);
+ if (len-nl == 1 &&
+ (uuchar[*b] || /* Check sum. */
+ (*b >= 'a' && *b <= 'z'))) {/* Padding data(MINIX). */
+ ++b;
+ --len;
+ }
+ b += nl;
+ if (avail && uuchar[*b])
+ return (firstline+30);
+ }
+ if (l == 13) {
+ while (len-nl > 0) {
+ if (!base64[*b++])
+ return (0);
+ --len;
+ }
+ b += nl;
+
+ if (avail >= 5 && memcmp(b, "====\n", 5) == 0)
+ return (firstline+40);
+ if (avail >= 6 && memcmp(b, "====\r\n", 6) == 0)
+ return (firstline+40);
+ if (avail > 0 && base64[*b])
+ return (firstline+30);
+ }
+
+ return (0);
+}
+
+static int
+uudecode_bidder_init(struct archive_read_filter *self)
+{
+ struct uudecode *uudecode;
+ void *out_buff;
+ void *in_buff;
+
+ self->code = ARCHIVE_COMPRESSION_UU;
+ self->name = "uu";
+ self->read = uudecode_filter_read;
+ self->skip = NULL; /* not supported */
+ self->close = uudecode_filter_close;
+
+ uudecode = (struct uudecode *)calloc(sizeof(*uudecode), 1);
+ out_buff = malloc(OUT_BUFF_SIZE);
+ in_buff = malloc(IN_BUFF_SIZE);
+ if (uudecode == NULL || out_buff == NULL || in_buff == NULL) {
+ archive_set_error(&self->archive->archive, ENOMEM,
+ "Can't allocate data for uudecode");
+ free(uudecode);
+ free(out_buff);
+ free(in_buff);
+ return (ARCHIVE_FATAL);
+ }
+
+ self->data = uudecode;
+ uudecode->in_buff = in_buff;
+ uudecode->in_cnt = 0;
+ uudecode->in_allocated = IN_BUFF_SIZE;
+ uudecode->out_buff = out_buff;
+ uudecode->state = ST_FIND_HEAD;
+
+ return (ARCHIVE_OK);
+}
+
+static int
+ensure_in_buff_size(struct archive_read_filter *self,
+ struct uudecode *uudecode, size_t size)
+{
+
+ if (size > uudecode->in_allocated) {
+ unsigned char *ptr;
+ size_t newsize;
+
+ /*
+ * Calculate a new buffer size for in_buff.
+ * Increase its value until it has enough size we need.
+ */
+ newsize = uudecode->in_allocated;
+ do {
+ if (newsize < IN_BUFF_SIZE*32)
+ newsize <<= 1;
+ else
+ newsize += IN_BUFF_SIZE;
+ } while (size > newsize);
+ /* Allocate the new buffer. */
+ ptr = malloc(newsize);
+ if (ptr == NULL) {
+ free(ptr);
+ archive_set_error(&self->archive->archive,
+ ENOMEM,
+ "Can't allocate data for uudecode");
+ return (ARCHIVE_FATAL);
+ }
+ /* Move the remaining data in in_buff into the new buffer. */
+ if (uudecode->in_cnt)
+ memmove(ptr, uudecode->in_buff, uudecode->in_cnt);
+ /* Replace in_buff with the new buffer. */
+ free(uudecode->in_buff);
+ uudecode->in_buff = ptr;
+ uudecode->in_allocated = newsize;
+ }
+ return (ARCHIVE_OK);
+}
+
+static ssize_t
+uudecode_filter_read(struct archive_read_filter *self, const void **buff)
+{
+ struct uudecode *uudecode;
+ const unsigned char *b, *d;
+ unsigned char *out;
+ ssize_t avail_in, ravail;
+ ssize_t used;
+ ssize_t total;
+ ssize_t len, llen, nl;
+
+ uudecode = (struct uudecode *)self->data;
+
+read_more:
+ d = __archive_read_filter_ahead(self->upstream, 1, &avail_in);
+ if (d == NULL && avail_in < 0)
+ return (ARCHIVE_FATAL);
+ /* Quiet a code analyzer; make sure avail_in must be zero
+ * when d is NULL. */
+ if (d == NULL)
+ avail_in = 0;
+ used = 0;
+ total = 0;
+ out = uudecode->out_buff;
+ ravail = avail_in;
+ if (uudecode->in_cnt) {
+ /*
+ * If there is remaining data which is saved by
+ * previous calling, use it first.
+ */
+ if (ensure_in_buff_size(self, uudecode,
+ avail_in + uudecode->in_cnt) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ memcpy(uudecode->in_buff + uudecode->in_cnt,
+ d, avail_in);
+ d = uudecode->in_buff;
+ avail_in += uudecode->in_cnt;
+ uudecode->in_cnt = 0;
+ }
+ for (;used < avail_in; d += llen, used += llen) {
+ int l, body;
+
+ b = d;
+ len = get_line(b, avail_in - used, &nl);
+ if (len < 0) {
+ /* Non-ascii character is found. */
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Insufficient compressed data");
+ return (ARCHIVE_FATAL);
+ }
+ llen = len;
+ if (nl == 0) {
+ /*
+ * Save remaining data which does not contain
+ * NL('\n','\r').
+ */
+ if (ensure_in_buff_size(self, uudecode, len)
+ != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ if (uudecode->in_buff != b)
+ memmove(uudecode->in_buff, b, len);
+ uudecode->in_cnt = len;
+ if (total == 0) {
+ /* Do not return 0; it means end-of-file.
+ * We should try to read bytes more. */
+ __archive_read_filter_consume(
+ self->upstream, ravail);
+ goto read_more;
+ }
+ break;
+ }
+ switch (uudecode->state) {
+ default:
+ case ST_FIND_HEAD:
+ /* Do not read more than UUENCODE_BID_MAX_READ bytes */
+ if (total + len >= UUENCODE_BID_MAX_READ) {
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid format data");
+ return (ARCHIVE_FATAL);
+ }
+ if (len - nl >= 11 && memcmp(b, "begin ", 6) == 0)
+ l = 6;
+ else if (len - nl >= 18 &&
+ memcmp(b, "begin-base64 ", 13) == 0)
+ l = 13;
+ else
+ l = 0;
+ if (l != 0 && b[l] >= '0' && b[l] <= '7' &&
+ b[l+1] >= '0' && b[l+1] <= '7' &&
+ b[l+2] >= '0' && b[l+2] <= '7' && b[l+3] == ' ') {
+ if (l == 6)
+ uudecode->state = ST_READ_UU;
+ else
+ uudecode->state = ST_READ_BASE64;
+ }
+ break;
+ case ST_READ_UU:
+ if (total + len * 2 > OUT_BUFF_SIZE)
+ break;
+ body = len - nl;
+ if (!uuchar[*b] || body <= 0) {
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Insufficient compressed data");
+ return (ARCHIVE_FATAL);
+ }
+ /* Get length of undecoded bytes of curent line. */
+ l = UUDECODE(*b++);
+ body--;
+ if (l > body) {
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Insufficient compressed data");
+ return (ARCHIVE_FATAL);
+ }
+ if (l == 0) {
+ uudecode->state = ST_UUEND;
+ break;
+ }
+ while (l > 0) {
+ int n = 0;
+
+ if (l > 0) {
+ if (!uuchar[b[0]] || !uuchar[b[1]])
+ break;
+ n = UUDECODE(*b++) << 18;
+ n |= UUDECODE(*b++) << 12;
+ *out++ = n >> 16; total++;
+ --l;
+ }
+ if (l > 0) {
+ if (!uuchar[b[0]])
+ break;
+ n |= UUDECODE(*b++) << 6;
+ *out++ = (n >> 8) & 0xFF; total++;
+ --l;
+ }
+ if (l > 0) {
+ if (!uuchar[b[0]])
+ break;
+ n |= UUDECODE(*b++);
+ *out++ = n & 0xFF; total++;
+ --l;
+ }
+ }
+ if (l) {
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Insufficient compressed data");
+ return (ARCHIVE_FATAL);
+ }
+ break;
+ case ST_UUEND:
+ if (len - nl == 3 && memcmp(b, "end ", 3) == 0)
+ uudecode->state = ST_FIND_HEAD;
+ else {
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Insufficient compressed data");
+ return (ARCHIVE_FATAL);
+ }
+ break;
+ case ST_READ_BASE64:
+ if (total + len * 2 > OUT_BUFF_SIZE)
+ break;
+ l = len - nl;
+ if (l >= 3 && b[0] == '=' && b[1] == '=' &&
+ b[2] == '=') {
+ uudecode->state = ST_FIND_HEAD;
+ break;
+ }
+ while (l > 0) {
+ int n = 0;
+
+ if (l > 0) {
+ if (!base64[b[0]] || !base64[b[1]])
+ break;
+ n = base64num[*b++] << 18;
+ n |= base64num[*b++] << 12;
+ *out++ = n >> 16; total++;
+ l -= 2;
+ }
+ if (l > 0) {
+ if (*b == '=')
+ break;
+ if (!base64[*b])
+ break;
+ n |= base64num[*b++] << 6;
+ *out++ = (n >> 8) & 0xFF; total++;
+ --l;
+ }
+ if (l > 0) {
+ if (*b == '=')
+ break;
+ if (!base64[*b])
+ break;
+ n |= base64num[*b++];
+ *out++ = n & 0xFF; total++;
+ --l;
+ }
+ }
+ if (l && *b != '=') {
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Insufficient compressed data");
+ return (ARCHIVE_FATAL);
+ }
+ break;
+ }
+ }
+
+ __archive_read_filter_consume(self->upstream, ravail);
+
+ *buff = uudecode->out_buff;
+ uudecode->total += total;
+ return (total);
+}
+
+static int
+uudecode_filter_close(struct archive_read_filter *self)
+{
+ struct uudecode *uudecode;
+
+ uudecode = (struct uudecode *)self->data;
+ free(uudecode->in_buff);
+ free(uudecode->out_buff);
+ free(uudecode);
+
+ return (ARCHIVE_OK);
+}
+
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_xz.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_xz.c
new file mode 100644
index 000000000..cf762a46d
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_xz.c
@@ -0,0 +1,985 @@
+/*-
+ * Copyright (c) 2009-2011 Michihiro NAKAJIMA
+ * Copyright (c) 2003-2008 Tim Kientzle and Miklos Vajna
+ * 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
+#if HAVE_LZMA_H
+#include <lzma.h>
+#elif HAVE_LZMADEC_H
+#include <lzmadec.h>
+#endif
+
+#include "archive.h"
+#include "archive_endian.h"
+#include "archive_private.h"
+#include "archive_read_private.h"
+
+#if HAVE_LZMA_H && HAVE_LIBLZMA
+
+struct private_data {
+ lzma_stream stream;
+ unsigned char *out_block;
+ size_t out_block_size;
+ int64_t total_out;
+ char eof; /* True = found end of compressed data. */
+ char in_stream;
+
+ /* Following variables are used for lzip only. */
+ char lzip_ver;
+ uint32_t crc32;
+ int64_t member_in;
+ int64_t member_out;
+};
+
+#if LZMA_VERSION_MAJOR >= 5
+/* Effectively disable the limiter. */
+#define LZMA_MEMLIMIT UINT64_MAX
+#else
+/* NOTE: This needs to check memory size which running system has. */
+#define LZMA_MEMLIMIT (1U << 30)
+#endif
+
+/* Combined lzip/lzma/xz filter */
+static ssize_t xz_filter_read(struct archive_read_filter *, const void **);
+static int xz_filter_close(struct archive_read_filter *);
+static int xz_lzma_bidder_init(struct archive_read_filter *);
+
+#elif HAVE_LZMADEC_H && HAVE_LIBLZMADEC
+
+struct private_data {
+ lzmadec_stream stream;
+ unsigned char *out_block;
+ size_t out_block_size;
+ int64_t total_out;
+ char eof; /* True = found end of compressed data. */
+};
+
+/* Lzma-only filter */
+static ssize_t lzma_filter_read(struct archive_read_filter *, const void **);
+static int lzma_filter_close(struct archive_read_filter *);
+#endif
+
+/*
+ * Note that we can detect xz and lzma compressed files 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 no lzma library is available.
+ */
+static int xz_bidder_bid(struct archive_read_filter_bidder *,
+ struct archive_read_filter *);
+static int xz_bidder_init(struct archive_read_filter *);
+static int lzma_bidder_bid(struct archive_read_filter_bidder *,
+ struct archive_read_filter *);
+static int lzma_bidder_init(struct archive_read_filter *);
+static int lzip_has_member(struct archive_read_filter *);
+static int lzip_bidder_bid(struct archive_read_filter_bidder *,
+ struct archive_read_filter *);
+static int lzip_bidder_init(struct archive_read_filter *);
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+/* Deprecated; remove in libarchive 4.0 */
+int
+archive_read_support_compression_xz(struct archive *a)
+{
+ return archive_read_support_filter_xz(a);
+}
+#endif
+
+int
+archive_read_support_filter_xz(struct archive *_a)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ struct archive_read_filter_bidder *bidder;
+
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_filter_xz");
+
+ if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ bidder->data = NULL;
+ bidder->bid = xz_bidder_bid;
+ bidder->init = xz_bidder_init;
+ bidder->options = NULL;
+ bidder->free = NULL;
+#if HAVE_LZMA_H && HAVE_LIBLZMA
+ return (ARCHIVE_OK);
+#else
+ archive_set_error(_a, ARCHIVE_ERRNO_MISC,
+ "Using external unxz program for xz decompression");
+ return (ARCHIVE_WARN);
+#endif
+}
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+int
+archive_read_support_compression_lzma(struct archive *a)
+{
+ return archive_read_support_filter_lzma(a);
+}
+#endif
+
+int
+archive_read_support_filter_lzma(struct archive *_a)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ struct archive_read_filter_bidder *bidder;
+
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_filter_lzma");
+
+ if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ bidder->data = NULL;
+ bidder->bid = lzma_bidder_bid;
+ bidder->init = lzma_bidder_init;
+ bidder->options = NULL;
+ bidder->free = NULL;
+#if HAVE_LZMA_H && HAVE_LIBLZMA
+ return (ARCHIVE_OK);
+#elif HAVE_LZMADEC_H && HAVE_LIBLZMADEC
+ return (ARCHIVE_OK);
+#else
+ archive_set_error(_a, ARCHIVE_ERRNO_MISC,
+ "Using external unlzma program for lzma decompression");
+ return (ARCHIVE_WARN);
+#endif
+}
+
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+int
+archive_read_support_compression_lzip(struct archive *a)
+{
+ return archive_read_support_filter_lzip(a);
+}
+#endif
+
+int
+archive_read_support_filter_lzip(struct archive *_a)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ struct archive_read_filter_bidder *bidder;
+
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_filter_lzip");
+
+ if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ bidder->data = NULL;
+ bidder->bid = lzip_bidder_bid;
+ bidder->init = lzip_bidder_init;
+ bidder->options = NULL;
+ bidder->free = NULL;
+#if HAVE_LZMA_H && HAVE_LIBLZMA
+ return (ARCHIVE_OK);
+#else
+ archive_set_error(_a, ARCHIVE_ERRNO_MISC,
+ "Using external lzip program for lzip decompression");
+ return (ARCHIVE_WARN);
+#endif
+}
+
+/*
+ * Test whether we can handle this data.
+ */
+static int
+xz_bidder_bid(struct archive_read_filter_bidder *self,
+ struct archive_read_filter *filter)
+{
+ const unsigned char *buffer;
+ ssize_t avail;
+
+ (void)self; /* UNUSED */
+
+ buffer = __archive_read_filter_ahead(filter, 6, &avail);
+ if (buffer == NULL)
+ return (0);
+
+ /*
+ * Verify Header Magic Bytes : FD 37 7A 58 5A 00
+ */
+ if (memcmp(buffer, "\xFD\x37\x7A\x58\x5A\x00", 6) != 0)
+ return (0);
+
+ return (48);
+}
+
+/*
+ * Test whether we can handle this data.
+ *
+ * <sigh> LZMA has a rather poor file signature. Zeros do not
+ * make good signature bytes as a rule, and the only non-zero byte
+ * here is an ASCII character. For example, an uncompressed tar
+ * archive whose first file is ']' would satisfy this check. It may
+ * be necessary to exclude LZMA from compression_all() because of
+ * this. Clients of libarchive would then have to explicitly enable
+ * LZMA checking instead of (or in addition to) compression_all() when
+ * they have other evidence (file name, command-line option) to go on.
+ */
+static int
+lzma_bidder_bid(struct archive_read_filter_bidder *self,
+ struct archive_read_filter *filter)
+{
+ const unsigned char *buffer;
+ ssize_t avail;
+ uint32_t dicsize;
+ uint64_t uncompressed_size;
+ int bits_checked;
+
+ (void)self; /* UNUSED */
+
+ buffer = __archive_read_filter_ahead(filter, 14, &avail);
+ if (buffer == NULL)
+ return (0);
+
+ /* First byte of raw LZMA stream is commonly 0x5d.
+ * The first byte is a special number, which consists of
+ * three parameters of LZMA compression, a number of literal
+ * context bits(which is from 0 to 8, default is 3), a number
+ * of literal pos bits(which is from 0 to 4, default is 0),
+ * a number of pos bits(which is from 0 to 4, default is 2).
+ * The first byte is made by
+ * (pos bits * 5 + literal pos bit) * 9 + * literal contest bit,
+ * and so the default value in this field is
+ * (2 * 5 + 0) * 9 + 3 = 0x5d.
+ * lzma of LZMA SDK has options to change those parameters.
+ * It means a range of this field is from 0 to 224. And lzma of
+ * XZ Utils with option -e records 0x5e in this field. */
+ /* NOTE: If this checking of the first byte increases false
+ * recognition, we should allow only 0x5d and 0x5e for the first
+ * byte of LZMA stream. */
+ bits_checked = 0;
+ if (buffer[0] > (4 * 5 + 4) * 9 + 8)
+ return (0);
+ /* Most likely value in the first byte of LZMA stream. */
+ if (buffer[0] == 0x5d || buffer[0] == 0x5e)
+ bits_checked += 8;
+
+ /* Sixth through fourteenth bytes are uncompressed size,
+ * stored in little-endian order. `-1' means uncompressed
+ * size is unknown and lzma of XZ Utils always records `-1'
+ * in this field. */
+ uncompressed_size = archive_le64dec(buffer+5);
+ if (uncompressed_size == (uint64_t)ARCHIVE_LITERAL_LL(-1))
+ bits_checked += 64;
+
+ /* Second through fifth bytes are dictionary size, stored in
+ * little-endian order. The minimum dictionary size is
+ * 1 << 12(4KiB) which the lzma of LZMA SDK uses with option
+ * -d12 and the maxinam dictionary size is 1 << 27(128MiB)
+ * which the one uses with option -d27.
+ * NOTE: A comment of LZMA SDK source code says this dictionary
+ * range is from 1 << 12 to 1 << 30. */
+ dicsize = archive_le32dec(buffer+1);
+ switch (dicsize) {
+ case 0x00001000:/* lzma of LZMA SDK option -d12. */
+ case 0x00002000:/* lzma of LZMA SDK option -d13. */
+ case 0x00004000:/* lzma of LZMA SDK option -d14. */
+ case 0x00008000:/* lzma of LZMA SDK option -d15. */
+ case 0x00010000:/* lzma of XZ Utils option -0 and -1.
+ * lzma of LZMA SDK option -d16. */
+ case 0x00020000:/* lzma of LZMA SDK option -d17. */
+ case 0x00040000:/* lzma of LZMA SDK option -d18. */
+ case 0x00080000:/* lzma of XZ Utils option -2.
+ * lzma of LZMA SDK option -d19. */
+ case 0x00100000:/* lzma of XZ Utils option -3.
+ * lzma of LZMA SDK option -d20. */
+ case 0x00200000:/* lzma of XZ Utils option -4.
+ * lzma of LZMA SDK option -d21. */
+ case 0x00400000:/* lzma of XZ Utils option -5.
+ * lzma of LZMA SDK option -d22. */
+ case 0x00800000:/* lzma of XZ Utils option -6.
+ * lzma of LZMA SDK option -d23. */
+ case 0x01000000:/* lzma of XZ Utils option -7.
+ * lzma of LZMA SDK option -d24. */
+ case 0x02000000:/* lzma of XZ Utils option -8.
+ * lzma of LZMA SDK option -d25. */
+ case 0x04000000:/* lzma of XZ Utils option -9.
+ * lzma of LZMA SDK option -d26. */
+ case 0x08000000:/* lzma of LZMA SDK option -d27. */
+ bits_checked += 32;
+ break;
+ default:
+ /* If a memory usage for encoding was not enough on
+ * the platform where LZMA stream was made, lzma of
+ * XZ Utils automatically decreased the dictionary
+ * size to enough memory for encoding by 1Mi bytes
+ * (1 << 20).*/
+ if (dicsize <= 0x03F00000 && dicsize >= 0x00300000 &&
+ (dicsize & ((1 << 20)-1)) == 0 &&
+ bits_checked == 8 + 64) {
+ bits_checked += 32;
+ break;
+ }
+ /* Otherwise dictionary size is unlikely. But it is
+ * possible that someone makes lzma stream with
+ * liblzma/LZMA SDK in one's dictionary size. */
+ return (0);
+ }
+
+ /* TODO: The above test is still very weak. It would be
+ * good to do better. */
+
+ return (bits_checked);
+}
+
+static int
+lzip_has_member(struct archive_read_filter *filter)
+{
+ const unsigned char *buffer;
+ ssize_t avail;
+ int bits_checked;
+ int log2dic;
+
+ buffer = __archive_read_filter_ahead(filter, 6, &avail);
+ if (buffer == NULL)
+ return (0);
+
+ /*
+ * Verify Header Magic Bytes : 4C 5A 49 50 (`LZIP')
+ */
+ bits_checked = 0;
+ if (memcmp(buffer, "LZIP", 4) != 0)
+ return (0);
+ bits_checked += 32;
+
+ /* A version number must be 0 or 1 */
+ if (buffer[4] != 0 && buffer[4] != 1)
+ return (0);
+ bits_checked += 8;
+
+ /* Dictionary size. */
+ log2dic = buffer[5] & 0x1f;
+ if (log2dic < 12 || log2dic > 27)
+ return (0);
+ bits_checked += 8;
+
+ return (bits_checked);
+}
+
+static int
+lzip_bidder_bid(struct archive_read_filter_bidder *self,
+ struct archive_read_filter *filter)
+{
+
+ (void)self; /* UNUSED */
+ return (lzip_has_member(filter));
+}
+
+#if HAVE_LZMA_H && HAVE_LIBLZMA
+
+/*
+ * liblzma 4.999.7 and later support both lzma and xz streams.
+ */
+static int
+xz_bidder_init(struct archive_read_filter *self)
+{
+ self->code = ARCHIVE_COMPRESSION_XZ;
+ self->name = "xz";
+ return (xz_lzma_bidder_init(self));
+}
+
+static int
+lzma_bidder_init(struct archive_read_filter *self)
+{
+ self->code = ARCHIVE_COMPRESSION_LZMA;
+ self->name = "lzma";
+ return (xz_lzma_bidder_init(self));
+}
+
+static int
+lzip_bidder_init(struct archive_read_filter *self)
+{
+ self->code = ARCHIVE_COMPRESSION_LZIP;
+ self->name = "lzip";
+ return (xz_lzma_bidder_init(self));
+}
+
+/*
+ * Set an error code and choose an error message
+ */
+static void
+set_error(struct archive_read_filter *self, int ret)
+{
+
+ switch (ret) {
+ case LZMA_STREAM_END: /* Found end of stream. */
+ case LZMA_OK: /* Decompressor made some progress. */
+ break;
+ case LZMA_MEM_ERROR:
+ archive_set_error(&self->archive->archive, ENOMEM,
+ "Lzma library error: Cannot allocate memory");
+ break;
+ case LZMA_MEMLIMIT_ERROR:
+ archive_set_error(&self->archive->archive, ENOMEM,
+ "Lzma library error: Out of memory");
+ break;
+ case LZMA_FORMAT_ERROR:
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Lzma library error: format not recognized");
+ break;
+ case LZMA_OPTIONS_ERROR:
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Lzma library error: Invalid options");
+ break;
+ case LZMA_DATA_ERROR:
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Lzma library error: Corrupted input data");
+ break;
+ case LZMA_BUF_ERROR:
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Lzma library error: No progress is possible");
+ break;
+ default:
+ /* Return an error. */
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Lzma decompression failed: Unknown error");
+ break;
+ }
+}
+
+/*
+ * Setup the callbacks.
+ */
+static int
+xz_lzma_bidder_init(struct archive_read_filter *self)
+{
+ static const size_t out_block_size = 64 * 1024;
+ void *out_block;
+ struct private_data *state;
+ int ret;
+
+ state = (struct private_data *)calloc(sizeof(*state), 1);
+ out_block = (unsigned char *)malloc(out_block_size);
+ if (state == NULL || out_block == NULL) {
+ archive_set_error(&self->archive->archive, ENOMEM,
+ "Can't allocate data for xz decompression");
+ free(out_block);
+ free(state);
+ return (ARCHIVE_FATAL);
+ }
+
+ self->data = state;
+ state->out_block_size = out_block_size;
+ state->out_block = out_block;
+ self->read = xz_filter_read;
+ self->skip = NULL; /* not supported */
+ self->close = xz_filter_close;
+
+ state->stream.avail_in = 0;
+
+ state->stream.next_out = state->out_block;
+ state->stream.avail_out = state->out_block_size;
+
+ state->crc32 = 0;
+ if (self->code == ARCHIVE_COMPRESSION_LZIP) {
+ /*
+ * We have to read a lzip header and use it to initialize
+ * compression library, thus we cannot initialize the
+ * library for lzip here.
+ */
+ state->in_stream = 0;
+ return (ARCHIVE_OK);
+ } else
+ state->in_stream = 1;
+
+ /* Initialize compression library. */
+ if (self->code == ARCHIVE_COMPRESSION_XZ)
+ ret = lzma_stream_decoder(&(state->stream),
+ LZMA_MEMLIMIT,/* memlimit */
+ LZMA_CONCATENATED);
+ else
+ ret = lzma_alone_decoder(&(state->stream),
+ LZMA_MEMLIMIT);/* memlimit */
+
+ if (ret == LZMA_OK)
+ return (ARCHIVE_OK);
+
+ /* Library setup failed: Choose an error message and clean up. */
+ set_error(self, ret);
+
+ free(state->out_block);
+ free(state);
+ self->data = NULL;
+ return (ARCHIVE_FATAL);
+}
+
+static int
+lzip_init(struct archive_read_filter *self)
+{
+ struct private_data *state;
+ const unsigned char *h;
+ lzma_filter filters[2];
+ unsigned char props[5];
+ ssize_t avail_in;
+ uint32_t dicsize;
+ int log2dic, ret;
+
+ state = (struct private_data *)self->data;
+ h = __archive_read_filter_ahead(self->upstream, 6, &avail_in);
+ if (h == NULL)
+ return (ARCHIVE_FATAL);
+
+ /* Get a version number. */
+ state->lzip_ver = h[4];
+
+ /*
+ * Setup lzma property.
+ */
+ props[0] = 0x5d;
+
+ /* Get dictionary size. */
+ log2dic = h[5] & 0x1f;
+ if (log2dic < 12 || log2dic > 27)
+ return (ARCHIVE_FATAL);
+ dicsize = 1U << log2dic;
+ if (log2dic > 12)
+ dicsize -= (dicsize / 16) * (h[5] >> 5);
+ archive_le32enc(props+1, dicsize);
+
+ /* Consume lzip header. */
+ __archive_read_filter_consume(self->upstream, 6);
+ state->member_in = 6;
+
+ filters[0].id = LZMA_FILTER_LZMA1;
+ filters[0].options = NULL;
+ filters[1].id = LZMA_VLI_UNKNOWN;
+ filters[1].options = NULL;
+
+ ret = lzma_properties_decode(&filters[0], NULL, props, sizeof(props));
+ if (ret != LZMA_OK) {
+ set_error(self, ret);
+ return (ARCHIVE_FATAL);
+ }
+ ret = lzma_raw_decoder(&(state->stream), filters);
+#if LZMA_VERSION < 50000030
+ free(filters[0].options);
+#endif
+ if (ret != LZMA_OK) {
+ set_error(self, ret);
+ return (ARCHIVE_FATAL);
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+lzip_tail(struct archive_read_filter *self)
+{
+ struct private_data *state;
+ const unsigned char *f;
+ ssize_t avail_in;
+ int tail;
+
+ state = (struct private_data *)self->data;
+ if (state->lzip_ver == 0)
+ tail = 12;
+ else
+ tail = 20;
+ f = __archive_read_filter_ahead(self->upstream, tail, &avail_in);
+ if (f == NULL && avail_in < 0)
+ return (ARCHIVE_FATAL);
+ if (avail_in < tail) {
+ archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
+ "Lzip: Remaining data is less bytes");
+ return (ARCHIVE_FAILED);
+ }
+
+ /* Check the crc32 value of the uncompressed data of the current
+ * member */
+ if (state->crc32 != archive_le32dec(f)) {
+ archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
+ "Lzip: CRC32 error");
+ return (ARCHIVE_FAILED);
+ }
+
+ /* Check the uncompressed size of the current member */
+ if ((uint64_t)state->member_out != archive_le64dec(f + 4)) {
+ archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
+ "Lzip: Uncompressed size error");
+ return (ARCHIVE_FAILED);
+ }
+
+ /* Check the total size of the current member */
+ if (state->lzip_ver == 1 &&
+ (uint64_t)state->member_in + tail != archive_le64dec(f + 12)) {
+ archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
+ "Lzip: Member size error");
+ return (ARCHIVE_FAILED);
+ }
+ __archive_read_filter_consume(self->upstream, tail);
+
+ /* If current lzip data consists of multi member, try decompressing
+ * a next member. */
+ if (lzip_has_member(self->upstream) != 0) {
+ state->in_stream = 0;
+ state->crc32 = 0;
+ state->member_out = 0;
+ state->member_in = 0;
+ state->eof = 0;
+ }
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Return the next block of decompressed data.
+ */
+static ssize_t
+xz_filter_read(struct archive_read_filter *self, const void **p)
+{
+ struct private_data *state;
+ size_t decompressed;
+ ssize_t avail_in;
+ int ret;
+
+ state = (struct private_data *)self->data;
+
+ /* Empty our output buffer. */
+ state->stream.next_out = state->out_block;
+ state->stream.avail_out = state->out_block_size;
+
+ /* Try to fill the output buffer. */
+ while (state->stream.avail_out > 0 && !state->eof) {
+ if (!state->in_stream) {
+ /*
+ * Initialize liblzma for lzip
+ */
+ ret = lzip_init(self);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ state->in_stream = 1;
+ }
+ state->stream.next_in =
+ __archive_read_filter_ahead(self->upstream, 1, &avail_in);
+ if (state->stream.next_in == NULL && avail_in < 0) {
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC,
+ "truncated input");
+ return (ARCHIVE_FATAL);
+ }
+ state->stream.avail_in = avail_in;
+
+ /* Decompress as much as we can in one pass. */
+ ret = lzma_code(&(state->stream),
+ (state->stream.avail_in == 0)? LZMA_FINISH: LZMA_RUN);
+ switch (ret) {
+ case LZMA_STREAM_END: /* Found end of stream. */
+ state->eof = 1;
+ /* FALL THROUGH */
+ case LZMA_OK: /* Decompressor made some progress. */
+ __archive_read_filter_consume(self->upstream,
+ avail_in - state->stream.avail_in);
+ state->member_in +=
+ avail_in - state->stream.avail_in;
+ break;
+ default:
+ set_error(self, ret);
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ decompressed = state->stream.next_out - state->out_block;
+ state->total_out += decompressed;
+ state->member_out += decompressed;
+ if (decompressed == 0)
+ *p = NULL;
+ else {
+ *p = state->out_block;
+ if (self->code == ARCHIVE_COMPRESSION_LZIP) {
+ state->crc32 = lzma_crc32(state->out_block,
+ decompressed, state->crc32);
+ if (state->eof) {
+ ret = lzip_tail(self);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ }
+ }
+ }
+ return (decompressed);
+}
+
+/*
+ * Clean up the decompressor.
+ */
+static int
+xz_filter_close(struct archive_read_filter *self)
+{
+ struct private_data *state;
+
+ state = (struct private_data *)self->data;
+ lzma_end(&(state->stream));
+ free(state->out_block);
+ free(state);
+ return (ARCHIVE_OK);
+}
+
+#else
+
+#if HAVE_LZMADEC_H && HAVE_LIBLZMADEC
+
+/*
+ * If we have the older liblzmadec library, then we can handle
+ * LZMA streams but not XZ streams.
+ */
+
+/*
+ * Setup the callbacks.
+ */
+static int
+lzma_bidder_init(struct archive_read_filter *self)
+{
+ static const size_t out_block_size = 64 * 1024;
+ void *out_block;
+ struct private_data *state;
+ ssize_t ret, avail_in;
+
+ self->code = ARCHIVE_COMPRESSION_LZMA;
+ self->name = "lzma";
+
+ state = (struct private_data *)calloc(sizeof(*state), 1);
+ out_block = (unsigned char *)malloc(out_block_size);
+ if (state == NULL || out_block == NULL) {
+ archive_set_error(&self->archive->archive, ENOMEM,
+ "Can't allocate data for lzma decompression");
+ free(out_block);
+ free(state);
+ return (ARCHIVE_FATAL);
+ }
+
+ self->data = state;
+ state->out_block_size = out_block_size;
+ state->out_block = out_block;
+ self->read = lzma_filter_read;
+ self->skip = NULL; /* not supported */
+ self->close = lzma_filter_close;
+
+ /* Prime the lzma library with 18 bytes of input. */
+ state->stream.next_in = (unsigned char *)(uintptr_t)
+ __archive_read_filter_ahead(self->upstream, 18, &avail_in);
+ if (state->stream.next_in == NULL)
+ return (ARCHIVE_FATAL);
+ state->stream.avail_in = avail_in;
+ state->stream.next_out = state->out_block;
+ state->stream.avail_out = state->out_block_size;
+
+ /* Initialize compression library. */
+ ret = lzmadec_init(&(state->stream));
+ __archive_read_filter_consume(self->upstream,
+ avail_in - state->stream.avail_in);
+ if (ret == LZMADEC_OK)
+ return (ARCHIVE_OK);
+
+ /* Library setup failed: Clean up. */
+ archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
+ "Internal error initializing lzma library");
+
+ /* Override the error message if we know what really went wrong. */
+ switch (ret) {
+ case LZMADEC_HEADER_ERROR:
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Internal error initializing compression library: "
+ "invalid header");
+ break;
+ case LZMADEC_MEM_ERROR:
+ archive_set_error(&self->archive->archive, ENOMEM,
+ "Internal error initializing compression library: "
+ "out of memory");
+ break;
+ }
+
+ free(state->out_block);
+ free(state);
+ self->data = NULL;
+ return (ARCHIVE_FATAL);
+}
+
+/*
+ * Return the next block of decompressed data.
+ */
+static ssize_t
+lzma_filter_read(struct archive_read_filter *self, const void **p)
+{
+ struct private_data *state;
+ size_t decompressed;
+ ssize_t avail_in, ret;
+
+ state = (struct private_data *)self->data;
+
+ /* Empty our output buffer. */
+ state->stream.next_out = state->out_block;
+ state->stream.avail_out = state->out_block_size;
+
+ /* Try to fill the output buffer. */
+ while (state->stream.avail_out > 0 && !state->eof) {
+ state->stream.next_in = (unsigned char *)(uintptr_t)
+ __archive_read_filter_ahead(self->upstream, 1, &avail_in);
+ if (state->stream.next_in == NULL && avail_in < 0) {
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC,
+ "truncated lzma input");
+ return (ARCHIVE_FATAL);
+ }
+ state->stream.avail_in = avail_in;
+
+ /* Decompress as much as we can in one pass. */
+ ret = lzmadec_decode(&(state->stream), avail_in == 0);
+ switch (ret) {
+ case LZMADEC_STREAM_END: /* Found end of stream. */
+ state->eof = 1;
+ /* FALL THROUGH */
+ case LZMADEC_OK: /* Decompressor made some progress. */
+ __archive_read_filter_consume(self->upstream,
+ avail_in - state->stream.avail_in);
+ break;
+ case LZMADEC_BUF_ERROR: /* Insufficient input data? */
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Insufficient compressed data");
+ return (ARCHIVE_FATAL);
+ default:
+ /* Return an error. */
+ archive_set_error(&self->archive->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Lzma decompression failed");
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ decompressed = state->stream.next_out - state->out_block;
+ state->total_out += decompressed;
+ if (decompressed == 0)
+ *p = NULL;
+ else
+ *p = state->out_block;
+ return (decompressed);
+}
+
+/*
+ * Clean up the decompressor.
+ */
+static int
+lzma_filter_close(struct archive_read_filter *self)
+{
+ struct private_data *state;
+ int ret;
+
+ state = (struct private_data *)self->data;
+ ret = ARCHIVE_OK;
+ switch (lzmadec_end(&(state->stream))) {
+ case LZMADEC_OK:
+ break;
+ default:
+ archive_set_error(&(self->archive->archive),
+ ARCHIVE_ERRNO_MISC,
+ "Failed to clean up %s compressor",
+ self->archive->archive.compression_name);
+ ret = ARCHIVE_FATAL;
+ }
+
+ free(state->out_block);
+ free(state);
+ return (ret);
+}
+
+#else
+
+/*
+ *
+ * If we have no suitable 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
+lzma_bidder_init(struct archive_read_filter *self)
+{
+ int r;
+
+ r = __archive_read_program(self, "unlzma");
+ /* 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_COMPRESSION_LZMA;
+ self->name = "lzma";
+ return (r);
+}
+
+#endif /* HAVE_LZMADEC_H */
+
+
+static int
+xz_bidder_init(struct archive_read_filter *self)
+{
+ int r;
+
+ r = __archive_read_program(self, "unxz");
+ /* 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_COMPRESSION_XZ;
+ self->name = "xz";
+ return (r);
+}
+
+static int
+lzip_bidder_init(struct archive_read_filter *self)
+{
+ int r;
+
+ r = __archive_read_program(self, "unlzip");
+ /* 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_COMPRESSION_LZIP;
+ self->name = "lzip";
+ return (r);
+}
+
+
+#endif /* HAVE_LZMA_H */
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c
new file mode 100644
index 000000000..2be226726
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c
@@ -0,0 +1,3706 @@
+/*-
+ * 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"
+__FBSDID("$FreeBSD$");
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_BZLIB_H
+#include <cm_bzlib.h>
+#endif
+#ifdef HAVE_LZMA_H
+#include <lzma.h>
+#endif
+#ifdef HAVE_ZLIB_H
+#include <cm_zlib.h>
+#endif
+
+#include "archive.h"
+#include "archive_entry.h"
+#include "archive_entry_locale.h"
+#include "archive_ppmd7_private.h"
+#include "archive_private.h"
+#include "archive_read_private.h"
+#include "archive_endian.h"
+
+#ifndef HAVE_ZLIB_H
+#include "archive_crc32.h"
+#endif
+
+#define _7ZIP_SIGNATURE "7z\xBC\xAF\x27\x1C"
+#define SFX_MIN_ADDR 0x27000
+#define SFX_MAX_ADDR 0x60000
+
+
+/*
+ * Codec ID
+ */
+#define _7Z_COPY 0
+#define _7Z_LZMA 0x030101
+#define _7Z_LZMA2 0x21
+#define _7Z_DEFLATE 0x040108
+#define _7Z_BZ2 0x040202
+#define _7Z_PPMD 0x030401
+#define _7Z_DELTA 0x03
+#define _7Z_CRYPTO 0x06F10701
+#define _7Z_X86 0x03030103
+#define _7Z_X86_BCJ2 0x0303011B
+#define _7Z_POWERPC 0x03030205
+#define _7Z_IA64 0x03030401
+#define _7Z_ARM 0x03030501
+#define _7Z_ARMTHUMB 0x03030701
+#define _7Z_SPARC 0x03030805
+
+/*
+ * 7-Zip header property IDs.
+ */
+#define kEnd 0x00
+#define kHeader 0x01
+#define kArchiveProperties 0x02
+#define kAdditionalStreamsInfo 0x03
+#define kMainStreamsInfo 0x04
+#define kFilesInfo 0x05
+#define kPackInfo 0x06
+#define kUnPackInfo 0x07
+#define kSubStreamsInfo 0x08
+#define kSize 0x09
+#define kCRC 0x0A
+#define kFolder 0x0B
+#define kCodersUnPackSize 0x0C
+#define kNumUnPackStream 0x0D
+#define kEmptyStream 0x0E
+#define kEmptyFile 0x0F
+#define kAnti 0x10
+#define kName 0x11
+#define kCTime 0x12
+#define kATime 0x13
+#define kMTime 0x14
+#define kAttributes 0x15
+#define kEncodedHeader 0x17
+
+struct _7z_digests {
+ unsigned char *defineds;
+ uint32_t *digests;
+};
+
+
+struct _7z_folder {
+ uint64_t numCoders;
+ struct _7z_coder {
+ unsigned long codec;
+ uint64_t numInStreams;
+ uint64_t numOutStreams;
+ uint64_t propertiesSize;
+ unsigned char *properties;
+ } *coders;
+ uint64_t numBindPairs;
+ struct {
+ uint64_t inIndex;
+ uint64_t outIndex;
+ } *bindPairs;
+ uint64_t numPackedStreams;
+ uint64_t *packedStreams;
+ uint64_t numInStreams;
+ uint64_t numOutStreams;
+ uint64_t *unPackSize;
+ unsigned char digest_defined;
+ uint32_t digest;
+ uint64_t numUnpackStreams;
+ uint32_t packIndex;
+ /* Unoperated bytes. */
+ uint64_t skipped_bytes;
+};
+
+struct _7z_coders_info {
+ uint64_t numFolders;
+ struct _7z_folder *folders;
+ uint64_t dataStreamIndex;
+};
+
+struct _7z_pack_info {
+ uint64_t pos;
+ uint64_t numPackStreams;
+ uint64_t *sizes;
+ struct _7z_digests digest;
+ /* Calculated from pos and numPackStreams. */
+ uint64_t *positions;
+};
+
+struct _7z_substream_info {
+ size_t unpack_streams;
+ uint64_t *unpackSizes;
+ unsigned char *digestsDefined;
+ uint32_t *digests;
+};
+
+struct _7z_stream_info {
+ struct _7z_pack_info pi;
+ struct _7z_coders_info ci;
+ struct _7z_substream_info ss;
+};
+
+struct _7z_header_info {
+ uint64_t dataIndex;
+
+ unsigned char *emptyStreamBools;
+ unsigned char *emptyFileBools;
+ unsigned char *antiBools;
+ unsigned char *attrBools;
+};
+
+struct _7zip_entry {
+ size_t name_len;
+ unsigned char *utf16name;
+#if defined(_WIN32) && !defined(__CYGWIN__) && defined(_DEBUG)
+ const wchar_t *wname;
+#endif
+ uint32_t folderIndex;
+ uint32_t ssIndex;
+ unsigned flg;
+#define MTIME_IS_SET (1<<0)
+#define ATIME_IS_SET (1<<1)
+#define CTIME_IS_SET (1<<2)
+#define CRC32_IS_SET (1<<3)
+#define HAS_STREAM (1<<4)
+
+ time_t mtime;
+ time_t atime;
+ time_t ctime;
+ long mtime_ns;
+ long atime_ns;
+ long ctime_ns;
+ uint32_t mode;
+ uint32_t attr;
+};
+
+struct _7zip {
+ /* Structural information about the archive. */
+ struct _7z_stream_info si;
+
+ int header_is_being_read;
+ int header_is_encoded;
+ uint64_t header_bytes_remaining;
+ unsigned long header_crc32;
+ /* Header offset to check that reading pointes of the file contens
+ * will not exceed the header. */
+ uint64_t header_offset;
+ /* Base offset of the archive file for a seek in case reading SFX. */
+ uint64_t seek_base;
+
+ /* List of entries */
+ size_t entries_remaining;
+ uint64_t numFiles;
+ struct _7zip_entry *entries;
+ struct _7zip_entry *entry;
+ unsigned char *entry_names;
+
+ /* entry_bytes_remaining is the number of bytes we expect. */
+ int64_t entry_offset;
+ uint64_t entry_bytes_remaining;
+
+ /* Running CRC32 of the decompressed data */
+ unsigned long entry_crc32;
+
+ /* Flags to mark progress of decompression. */
+ char end_of_entry;
+
+ /* Uncompressed buffer control. */
+#define UBUFF_SIZE (64 * 1024)
+ unsigned char *uncompressed_buffer;
+ unsigned char *uncompressed_buffer_pointer;
+ size_t uncompressed_buffer_size;
+ size_t uncompressed_buffer_bytes_remaining;
+
+ /* Offset of the compressed data. */
+ int64_t stream_offset;
+
+ /*
+ * Decompressing control data.
+ */
+ unsigned folder_index;
+ uint64_t folder_outbytes_remaining;
+ unsigned pack_stream_index;
+ unsigned pack_stream_remaining;
+ uint64_t pack_stream_inbytes_remaining;
+ size_t pack_stream_bytes_unconsumed;
+
+ /* The codec information of a folder. */
+ unsigned long codec;
+ unsigned long codec2;
+
+ /*
+ * Decompressor controllers.
+ */
+ /* Decording LZMA1 and LZMA2 data. */
+#ifdef HAVE_LZMA_H
+ lzma_stream lzstream;
+ int lzstream_valid;
+#endif
+ /* Decording bzip2 data. */
+#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
+ bz_stream bzstream;
+ int bzstream_valid;
+#endif
+ /* Decording deflate data. */
+#ifdef HAVE_ZLIB_H
+ z_stream stream;
+ int stream_valid;
+#endif
+ /* Decording PPMd data. */
+ int ppmd7_stat;
+ CPpmd7 ppmd7_context;
+ CPpmd7z_RangeDec range_dec;
+ IByteIn bytein;
+ struct {
+ const unsigned char *next_in;
+ int64_t avail_in;
+ int64_t total_in;
+ unsigned char *next_out;
+ int64_t avail_out;
+ int64_t total_out;
+ int overconsumed;
+ } ppstream;
+ int ppmd7_valid;
+
+ /* Decoding BCJ and BCJ2 data. */
+ uint32_t bcj_state;
+ size_t odd_bcj_size;
+ unsigned char odd_bcj[4];
+ /* Decoding BCJ data. */
+ size_t bcj_prevPosT;
+ uint32_t bcj_prevMask;
+ uint32_t bcj_ip;
+
+ /* Decoding BCJ2 data. */
+ size_t main_stream_bytes_remaining;
+ unsigned char *sub_stream_buff[3];
+ size_t sub_stream_size[3];
+ size_t sub_stream_bytes_remaining[3];
+ unsigned char *tmp_stream_buff;
+ size_t tmp_stream_buff_size;
+ size_t tmp_stream_bytes_avail;
+ size_t tmp_stream_bytes_remaining;
+#ifdef _LZMA_PROB32
+#define CProb uint32_t
+#else
+#define CProb uint16_t
+#endif
+ CProb bcj2_p[256 + 2];
+ uint8_t bcj2_prevByte;
+ uint32_t bcj2_range;
+ uint32_t bcj2_code;
+ uint64_t bcj2_outPos;
+
+ /* Filename character-set convertion data. */
+ struct archive_string_conv *sconv;
+
+ char format_name[64];
+};
+
+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 *,
+ const void **, size_t *, int64_t *);
+static int archive_read_format_7zip_read_data_skip(struct archive_read *);
+static int archive_read_format_7zip_read_header(struct archive_read *,
+ struct archive_entry *);
+static int check_7zip_header_in_sfx(const char *);
+static unsigned long decode_codec_id(const unsigned char *, size_t);
+static int decode_encoded_header_info(struct archive_read *,
+ struct _7z_stream_info *);
+static int decompress(struct archive_read *, struct _7zip *,
+ void *, size_t *, const void *, size_t *);
+static ssize_t extract_pack_stream(struct archive_read *, size_t);
+static void fileTimeToUtc(uint64_t, time_t *, long *);
+static uint64_t folder_uncompressed_size(struct _7z_folder *);
+static void free_CodersInfo(struct _7z_coders_info *);
+static void free_Digest(struct _7z_digests *);
+static void free_Folder(struct _7z_folder *);
+static void free_Header(struct _7z_header_info *);
+static void free_PackInfo(struct _7z_pack_info *);
+static void free_StreamsInfo(struct _7z_stream_info *);
+static void free_SubStreamsInfo(struct _7z_substream_info *);
+static int free_decompression(struct archive_read *, struct _7zip *);
+static ssize_t get_uncompressed_data(struct archive_read *, const void **,
+ size_t, size_t);
+static const unsigned char * header_bytes(struct archive_read *, size_t);
+static int init_decompression(struct archive_read *, struct _7zip *,
+ const struct _7z_coder *, const struct _7z_coder *);
+static int parse_7zip_uint64(struct archive_read *, uint64_t *);
+static int read_Bools(struct archive_read *, unsigned char *, size_t);
+static int read_CodersInfo(struct archive_read *,
+ struct _7z_coders_info *);
+static int read_Digests(struct archive_read *, struct _7z_digests *,
+ size_t);
+static int read_Folder(struct archive_read *, struct _7z_folder *);
+static int read_Header(struct archive_read *, struct _7z_header_info *,
+ int);
+static int read_PackInfo(struct archive_read *, struct _7z_pack_info *);
+static int read_StreamsInfo(struct archive_read *,
+ struct _7z_stream_info *);
+static int read_SubStreamsInfo(struct archive_read *,
+ struct _7z_substream_info *, struct _7z_folder *, size_t);
+static int read_Times(struct archive_read *, struct _7z_header_info *,
+ int);
+static void read_consume(struct archive_read *);
+static ssize_t read_stream(struct archive_read *, const void **, size_t,
+ size_t);
+static int seek_pack(struct archive_read *);
+static int64_t skip_stream(struct archive_read *, size_t);
+static int skip_sfx(struct archive_read *, ssize_t);
+static int slurp_central_directory(struct archive_read *, struct _7zip *,
+ struct _7z_header_info *);
+static int setup_decode_folder(struct archive_read *, struct _7z_folder *,
+ int);
+static void x86_Init(struct _7zip *);
+static size_t x86_Convert(struct _7zip *, uint8_t *, size_t);
+static ssize_t Bcj2_Decode(struct _7zip *, uint8_t *, size_t);
+
+
+int
+archive_read_support_format_7zip(struct archive *_a)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ struct _7zip *zip;
+ int r;
+
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_7zip");
+
+ zip = calloc(1, sizeof(*zip));
+ if (zip == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate 7zip data");
+ return (ARCHIVE_FATAL);
+ }
+
+ r = __archive_read_register_format(a,
+ zip,
+ "7zip",
+ archive_read_format_7zip_bid,
+ NULL,
+ archive_read_format_7zip_read_header,
+ archive_read_format_7zip_read_data,
+ archive_read_format_7zip_read_data_skip,
+ archive_read_format_7zip_cleanup);
+
+ if (r != ARCHIVE_OK)
+ free(zip);
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_read_format_7zip_bid(struct archive_read *a, int best_bid)
+{
+ const char *p;
+
+ /* If someone has already bid more than 32, then avoid
+ trashing the look-ahead buffers with a seek. */
+ if (best_bid > 32)
+ return (-1);
+
+ if ((p = __archive_read_ahead(a, 6, NULL)) == NULL)
+ return (0);
+
+ /* If first six bytes are the 7-Zip signature,
+ * return the bid right now. */
+ if (memcmp(p, _7ZIP_SIGNATURE, 6) == 0)
+ return (48);
+
+ /*
+ * It may a 7-Zip SFX archive file. If first two bytes are
+ * 'M' and 'Z' available on Windows or first four bytes are
+ * "\x7F\x45LF" available on posix like system, seek the 7-Zip
+ * signature. Although we will perform a seek when reading
+ * a header, what we do not use __archive_read_seek() here is
+ * due to a bidding performance.
+ */
+ if ((p[0] == 'M' && p[1] == 'Z') || memcmp(p, "\x7F\x45LF", 4) == 0) {
+ ssize_t offset = SFX_MIN_ADDR;
+ ssize_t window = 4096;
+ ssize_t bytes_avail;
+ while (offset + window <= (SFX_MAX_ADDR)) {
+ const char *buff = __archive_read_ahead(a,
+ offset + window, &bytes_avail);
+ if (buff == NULL) {
+ /* Remaining bytes are less than window. */
+ window >>= 1;
+ if (window < 0x40)
+ return (0);
+ continue;
+ }
+ p = buff + offset;
+ while (p + 32 < buff + bytes_avail) {
+ int step = check_7zip_header_in_sfx(p);
+ if (step == 0)
+ return (48);
+ p += step;
+ }
+ offset = p - buff;
+ }
+ }
+ return (0);
+}
+
+static int
+check_7zip_header_in_sfx(const char *p)
+{
+ switch ((unsigned char)p[5]) {
+ case 0x1C:
+ if (memcmp(p, _7ZIP_SIGNATURE, 6) != 0)
+ return (6);
+ /*
+ * Test the CRC because its extraction code has 7-Zip
+ * Magic Code, so we should do this in order not to
+ * make a mis-detection.
+ */
+ if (crc32(0, (unsigned char *)p + 12, 20)
+ != archive_le32dec(p + 8))
+ 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);
+ }
+}
+
+static int
+skip_sfx(struct archive_read *a, ssize_t bytes_avail)
+{
+ const void *h;
+ const char *p, *q;
+ size_t skip, offset;
+ ssize_t bytes, window;
+
+ /*
+ * If bytes_avail > SFX_MIN_ADDR we do not have to call
+ * __archive_read_seek() at this time since we have
+ * alredy had enough data.
+ */
+ if (bytes_avail > SFX_MIN_ADDR)
+ __archive_read_consume(a, SFX_MIN_ADDR);
+ else if (__archive_read_seek(a, SFX_MIN_ADDR, SEEK_SET) < 0)
+ return (ARCHIVE_FATAL);
+
+ offset = 0;
+ window = 1;
+ while (offset + window <= SFX_MAX_ADDR - SFX_MIN_ADDR) {
+ h = __archive_read_ahead(a, window, &bytes);
+ if (h == NULL) {
+ /* Remaining bytes are less than window. */
+ window >>= 1;
+ if (window < 0x40)
+ goto fatal;
+ continue;
+ }
+ if (bytes < 6) {
+ /* This case might happen when window == 1. */
+ window = 4096;
+ continue;
+ }
+ p = (const char *)h;
+ q = p + bytes;
+
+ /*
+ * Scan ahead until we find something that looks
+ * like the 7-Zip header.
+ */
+ while (p + 32 < q) {
+ int step = check_7zip_header_in_sfx(p);
+ if (step == 0) {
+ struct _7zip *zip =
+ (struct _7zip *)a->format->data;
+ skip = p - (const char *)h;
+ __archive_read_consume(a, skip);
+ zip->seek_base = SFX_MIN_ADDR + offset + skip;
+ return (ARCHIVE_OK);
+ }
+ p += step;
+ }
+ skip = p - (const char *)h;
+ __archive_read_consume(a, skip);
+ offset += skip;
+ if (window == 1)
+ window = 4096;
+ }
+fatal:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Couldn't find out 7-Zip header");
+ return (ARCHIVE_FATAL);
+}
+
+static int
+archive_read_format_7zip_read_header(struct archive_read *a,
+ struct archive_entry *entry)
+{
+ struct _7zip *zip = (struct _7zip *)a->format->data;
+ struct _7zip_entry *zip_entry;
+ int r, ret = ARCHIVE_OK;
+
+ a->archive.archive_format = ARCHIVE_FORMAT_7ZIP;
+ if (a->archive.archive_format_name == NULL)
+ a->archive.archive_format_name = "7-Zip";
+
+ if (zip->entries == NULL) {
+ struct _7z_header_info header;
+
+ memset(&header, 0, sizeof(header));
+ r = slurp_central_directory(a, zip, &header);
+ free_Header(&header);
+ if (r != ARCHIVE_OK)
+ return (r);
+ zip->entries_remaining = zip->numFiles;
+ zip->entry = zip->entries;
+ } else {
+ ++zip->entry;
+ }
+ zip_entry = zip->entry;
+
+ if (zip->entries_remaining <= 0)
+ return ARCHIVE_EOF;
+ --zip->entries_remaining;
+
+ zip->entry_offset = 0;
+ zip->end_of_entry = 0;
+ zip->entry_crc32 = crc32(0, NULL, 0);
+
+ /* Setup a string conversion for a filename. */
+ if (zip->sconv == NULL) {
+ zip->sconv = archive_string_conversion_from_charset(
+ &a->archive, "UTF-16LE", 1);
+ if (zip->sconv == NULL)
+ return (ARCHIVE_FATAL);
+ }
+
+ if (archive_entry_copy_pathname_l(entry,
+ (const char *)zip_entry->utf16name,
+ zip_entry->name_len, zip->sconv) != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Pathname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Pathname cannot be converted "
+ "from %s to current locale.",
+ archive_string_conversion_charset_name(zip->sconv));
+ ret = ARCHIVE_WARN;
+ }
+
+ /* Populate some additional entry fields: */
+ archive_entry_set_mode(entry, zip_entry->mode);
+ if (zip_entry->flg & MTIME_IS_SET)
+ archive_entry_set_mtime(entry, zip_entry->mtime,
+ zip_entry->mtime_ns);
+ if (zip_entry->flg & CTIME_IS_SET)
+ archive_entry_set_ctime(entry, zip_entry->ctime,
+ zip_entry->ctime_ns);
+ if (zip_entry->flg & ATIME_IS_SET)
+ archive_entry_set_atime(entry, zip_entry->atime,
+ zip_entry->atime_ns);
+ if (zip_entry->ssIndex != -1) {
+ zip->entry_bytes_remaining =
+ zip->si.ss.unpackSizes[zip_entry->ssIndex];
+ archive_entry_set_size(entry, zip->entry_bytes_remaining);
+ } else {
+ zip->entry_bytes_remaining = 0;
+ archive_entry_set_size(entry, 0);
+ }
+
+ /* If there's no body, force read_data() to return EOF immediately. */
+ if (zip->entry_bytes_remaining < 1)
+ zip->end_of_entry = 1;
+
+ if ((zip_entry->mode & AE_IFMT) == AE_IFLNK) {
+ unsigned char *symname = NULL;
+ size_t symsize = 0;
+ int r;
+
+ /*
+ * Symbolic-name is recorded as its contents. We have to
+ * read the contents at this time.
+ */
+ while (zip->entry_bytes_remaining > 0) {
+ const void *buff;
+ size_t size;
+ int64_t offset;
+
+ r = archive_read_format_7zip_read_data(a, &buff,
+ &size, &offset);
+ if (r < ARCHIVE_WARN)
+ return (r);
+ symname = realloc(symname, symsize + size + 1);
+ if (symname == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Symname");
+ return (ARCHIVE_FATAL);
+ }
+ memcpy(symname+symsize, buff, size);
+ symsize += size;
+ }
+ if (symsize == 0) {
+ /* If there is no synname, handle it as a regular
+ * file. */
+ zip_entry->mode &= ~AE_IFMT;
+ zip_entry->mode |= AE_IFREG;
+ archive_entry_set_mode(entry, zip_entry->mode);
+ } else {
+ symname[symsize] = '\0';
+ archive_entry_copy_symlink(entry,
+ (const char *)symname);
+ free(symname);
+ }
+ archive_entry_set_size(entry, 0);
+ }
+
+ /* Set up a more descriptive format name. */
+ sprintf(zip->format_name, "7-Zip");
+ a->archive.archive_format_name = zip->format_name;
+
+ return (ret);
+}
+
+static int
+archive_read_format_7zip_read_data(struct archive_read *a,
+ const void **buff, size_t *size, int64_t *offset)
+{
+ struct _7zip *zip;
+ ssize_t bytes;
+ int ret = ARCHIVE_OK;
+
+ zip = (struct _7zip *)(a->format->data);
+
+ if (zip->pack_stream_bytes_unconsumed)
+ read_consume(a);
+
+ /*
+ * If we hit end-of-entry last time, clean up and return
+ * ARCHIVE_EOF this time.
+ */
+ if (zip->end_of_entry) {
+ *offset = zip->entry_offset;
+ *size = 0;
+ *buff = NULL;
+ return (ARCHIVE_EOF);
+ }
+
+ bytes = read_stream(a, buff, zip->entry_bytes_remaining, 0);
+ if (bytes < 0)
+ return ((int)bytes);
+ if (bytes == 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated 7-Zip file body");
+ return (ARCHIVE_FATAL);
+ }
+ zip->entry_bytes_remaining -= bytes;
+ if (zip->entry_bytes_remaining == 0)
+ zip->end_of_entry = 1;
+
+ /* Update checksum */
+ if ((zip->entry->flg & CRC32_IS_SET) && bytes)
+ zip->entry_crc32 = crc32(zip->entry_crc32, *buff, bytes);
+
+ /* If we hit the end, swallow any end-of-data marker. */
+ if (zip->end_of_entry) {
+ /* Check computed CRC against file contents. */
+ if ((zip->entry->flg & CRC32_IS_SET) &&
+ zip->si.ss.digests[zip->entry->ssIndex] !=
+ zip->entry_crc32) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "7-Zip bad CRC: 0x%lx should be 0x%lx",
+ (unsigned long)zip->entry_crc32,
+ (unsigned long)zip->si.ss.digests[
+ zip->entry->ssIndex]);
+ ret = ARCHIVE_WARN;
+ }
+ }
+
+ *size = bytes;
+ *offset = zip->entry_offset;
+ zip->entry_offset += bytes;
+
+ return (ret);
+}
+
+static int
+archive_read_format_7zip_read_data_skip(struct archive_read *a)
+{
+ struct _7zip *zip;
+ int64_t bytes_skipped;
+
+ zip = (struct _7zip *)(a->format->data);
+
+ if (zip->pack_stream_bytes_unconsumed)
+ read_consume(a);
+
+ /* If we've already read to end of data, we're done. */
+ if (zip->end_of_entry)
+ return (ARCHIVE_OK);
+
+ /*
+ * If the length is at the beginning, we can skip the
+ * compressed data much more quickly.
+ */
+ bytes_skipped = skip_stream(a, zip->entry_bytes_remaining);
+ if (bytes_skipped < 0)
+ return (ARCHIVE_FATAL);
+ zip->entry_bytes_remaining = 0;
+
+ /* This entry is finished and done. */
+ zip->end_of_entry = 1;
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_read_format_7zip_cleanup(struct archive_read *a)
+{
+ struct _7zip *zip;
+
+ zip = (struct _7zip *)(a->format->data);
+ free_StreamsInfo(&(zip->si));
+ free(zip->entries);
+ free(zip->entry_names);
+ free_decompression(a, zip);
+ free(zip->uncompressed_buffer);
+ free(zip->sub_stream_buff[0]);
+ free(zip->sub_stream_buff[1]);
+ free(zip->sub_stream_buff[2]);
+ free(zip->tmp_stream_buff);
+ free(zip);
+ (a->format->data) = NULL;
+ return (ARCHIVE_OK);
+}
+
+static void
+read_consume(struct archive_read *a)
+{
+ struct _7zip *zip = (struct _7zip *)a->format->data;
+
+ if (zip->pack_stream_bytes_unconsumed) {
+ __archive_read_consume(a, zip->pack_stream_bytes_unconsumed);
+ zip->stream_offset += zip->pack_stream_bytes_unconsumed;
+ zip->pack_stream_bytes_unconsumed = 0;
+ }
+}
+
+#ifdef HAVE_LZMA_H
+
+/*
+ * Set an error code and choose an error message for liblzma.
+ */
+static void
+set_error(struct archive_read *a, int ret)
+{
+
+ switch (ret) {
+ case LZMA_STREAM_END: /* Found end of stream. */
+ case LZMA_OK: /* Decompressor made some progress. */
+ break;
+ case LZMA_MEM_ERROR:
+ archive_set_error(&a->archive, ENOMEM,
+ "Lzma library error: Cannot allocate memory");
+ break;
+ case LZMA_MEMLIMIT_ERROR:
+ archive_set_error(&a->archive, ENOMEM,
+ "Lzma library error: Out of memory");
+ break;
+ case LZMA_FORMAT_ERROR:
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Lzma library error: format not recognized");
+ break;
+ case LZMA_OPTIONS_ERROR:
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Lzma library error: Invalid options");
+ break;
+ case LZMA_DATA_ERROR:
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Lzma library error: Corrupted input data");
+ break;
+ case LZMA_BUF_ERROR:
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Lzma library error: No progress is possible");
+ break;
+ default:
+ /* Return an error. */
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Lzma decompression failed: Unknown error");
+ break;
+ }
+}
+
+#endif
+
+static unsigned long
+decode_codec_id(const unsigned char *codecId, size_t id_size)
+{
+ unsigned i;
+ unsigned long id = 0;
+
+ for (i = 0; i < id_size; i++) {
+ id <<= 8;
+ id += codecId[i];
+ }
+ return (id);
+}
+
+static void *
+ppmd_alloc(void *p, size_t size)
+{
+ (void)p;
+ return malloc(size);
+}
+static void
+ppmd_free(void *p, void *address)
+{
+ (void)p;
+ free(address);
+}
+static Byte
+ppmd_read(void *p)
+{
+ struct archive_read *a = ((IByteIn*)p)->a;
+ struct _7zip *zip = (struct _7zip *)(a->format->data);
+ Byte b;
+
+ if (zip->ppstream.avail_in == 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated RAR file data");
+ zip->ppstream.overconsumed = 1;
+ return (0);
+ }
+ b = *zip->ppstream.next_in++;
+ zip->ppstream.avail_in--;
+ zip->ppstream.total_in++;
+ return (b);
+}
+
+static ISzAlloc g_szalloc = { ppmd_alloc, ppmd_free };
+
+static int
+init_decompression(struct archive_read *a, struct _7zip *zip,
+ const struct _7z_coder *coder1, const struct _7z_coder *coder2)
+{
+ int r;
+
+ zip->codec = coder1->codec;
+ zip->codec2 = -1;
+
+ switch (zip->codec) {
+ case _7Z_COPY:
+ case _7Z_BZ2:
+ case _7Z_DEFLATE:
+ case _7Z_PPMD:
+ if (coder2 != NULL) {
+ if (coder2->codec != _7Z_X86 &&
+ coder2->codec != _7Z_X86_BCJ2) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Unsupported filter %lx for %lx",
+ coder2->codec, coder1->codec);
+ return (ARCHIVE_FAILED);
+ }
+ zip->codec2 = coder2->codec;
+ zip->bcj_state = 0;
+ if (coder2->codec == _7Z_X86)
+ x86_Init(zip);
+ }
+ break;
+ default:
+ break;
+ }
+
+ switch (zip->codec) {
+ case _7Z_COPY:
+ break;
+
+ case _7Z_LZMA: case _7Z_LZMA2:
+#ifdef HAVE_LZMA_H
+#if LZMA_VERSION_MAJOR >= 5
+/* Effectively disable the limiter. */
+#define LZMA_MEMLIMIT UINT64_MAX
+#else
+/* NOTE: This needs to check memory size which running system has. */
+#define LZMA_MEMLIMIT (1U << 30)
+#endif
+ {
+ lzma_options_delta delta_opt;
+ lzma_filter filters[LZMA_FILTERS_MAX];
+#if LZMA_VERSION < 50000030
+ lzma_filter *ff;
+#endif
+ int fi = 0;
+
+ if (zip->lzstream_valid) {
+ lzma_end(&(zip->lzstream));
+ zip->lzstream_valid = 0;
+ }
+
+ /*
+ * NOTE: liblzma incompletely handle the BCJ+LZMA compressed
+ * data made by 7-Zip because 7-Zip does not add End-Of-
+ * Payload Marker(EOPM) at the end of LZMA compressed data,
+ * and so liblzma cannot know the end of the compressed data
+ * without EOPM. So consequently liblzma will not return last
+ * three or four bytes of uncompressed data because
+ * LZMA_FILTER_X86 filter does not handle input data if its
+ * data size is less than five bytes. If liblzma detect EOPM
+ * or know the uncompressed data size, liblzma will flush out
+ * the remaining that three or four bytes of uncompressed
+ * data. That is why we have to use our converting program
+ * 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.
+ * Discussion about this can be found at XZ Utils forum.
+ */
+ if (coder2 != NULL) {
+ zip->codec2 = coder2->codec;
+
+ filters[fi].options = NULL;
+ switch (zip->codec2) {
+ case _7Z_X86:
+ if (zip->codec == _7Z_LZMA2) {
+ filters[fi].id = LZMA_FILTER_X86;
+ fi++;
+ } else
+ /* Use our filter. */
+ x86_Init(zip);
+ break;
+ case _7Z_X86_BCJ2:
+ /* Use our filter. */
+ zip->bcj_state = 0;
+ break;
+ case _7Z_DELTA:
+ filters[fi].id = LZMA_FILTER_DELTA;
+ memset(&delta_opt, 0, sizeof(delta_opt));
+ delta_opt.type = LZMA_DELTA_TYPE_BYTE;
+ delta_opt.dist = 1;
+ filters[fi].options = &delta_opt;
+ fi++;
+ break;
+ /* Following filters have not been tested yet. */
+ case _7Z_POWERPC:
+ filters[fi].id = LZMA_FILTER_POWERPC;
+ fi++;
+ break;
+ case _7Z_IA64:
+ filters[fi].id = LZMA_FILTER_IA64;
+ fi++;
+ break;
+ case _7Z_ARM:
+ filters[fi].id = LZMA_FILTER_ARM;
+ fi++;
+ break;
+ case _7Z_ARMTHUMB:
+ filters[fi].id = LZMA_FILTER_ARMTHUMB;
+ fi++;
+ break;
+ case _7Z_SPARC:
+ filters[fi].id = LZMA_FILTER_SPARC;
+ fi++;
+ break;
+ default:
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Unexpected codec ID: %lX", zip->codec2);
+ return (ARCHIVE_FAILED);
+ }
+ }
+
+ if (zip->codec == _7Z_LZMA2)
+ filters[fi].id = LZMA_FILTER_LZMA2;
+ else
+ filters[fi].id = LZMA_FILTER_LZMA1;
+ filters[fi].options = NULL;
+#if LZMA_VERSION < 50000030
+ ff = &filters[fi];
+#endif
+ r = lzma_properties_decode(&filters[fi], NULL,
+ coder1->properties, coder1->propertiesSize);
+ if (r != LZMA_OK) {
+ set_error(a, r);
+ return (ARCHIVE_FAILED);
+ }
+ fi++;
+
+ filters[fi].id = LZMA_VLI_UNKNOWN;
+ filters[fi].options = NULL;
+ r = lzma_raw_decoder(&(zip->lzstream), filters);
+#if LZMA_VERSION < 50000030
+ free(ff->options);
+#endif
+ if (r != LZMA_OK) {
+ set_error(a, r);
+ return (ARCHIVE_FAILED);
+ }
+ zip->lzstream_valid = 1;
+ zip->lzstream.total_in = 0;
+ zip->lzstream.total_out = 0;
+ break;
+ }
+#else
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "LZMA codec is unsupported");
+ return (ARCHIVE_FAILED);
+#endif
+ case _7Z_BZ2:
+#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
+ if (zip->bzstream_valid) {
+ BZ2_bzDecompressEnd(&(zip->bzstream));
+ zip->bzstream_valid = 0;
+ }
+ r = BZ2_bzDecompressInit(&(zip->bzstream), 0, 0);
+ if (r == BZ_MEM_ERROR)
+ r = BZ2_bzDecompressInit(&(zip->bzstream), 0, 1);
+ if (r != BZ_OK) {
+ int err = ARCHIVE_ERRNO_MISC;
+ const char *detail = NULL;
+ switch (r) {
+ case BZ_PARAM_ERROR:
+ detail = "invalid setup parameter";
+ break;
+ case BZ_MEM_ERROR:
+ err = ENOMEM;
+ detail = "out of memory";
+ break;
+ case BZ_CONFIG_ERROR:
+ detail = "mis-compiled library";
+ break;
+ }
+ archive_set_error(&a->archive, err,
+ "Internal error initializing decompressor: %s",
+ detail != NULL ? detail : "??");
+ zip->bzstream_valid = 0;
+ return (ARCHIVE_FAILED);
+ }
+ zip->bzstream_valid = 1;
+ zip->bzstream.total_in_lo32 = 0;
+ zip->bzstream.total_in_hi32 = 0;
+ zip->bzstream.total_out_lo32 = 0;
+ zip->bzstream.total_out_hi32 = 0;
+ break;
+#else
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "BZ2 codec is unsupported");
+ return (ARCHIVE_FAILED);
+#endif
+ case _7Z_DEFLATE:
+#ifdef HAVE_ZLIB_H
+ if (zip->stream_valid)
+ r = inflateReset(&(zip->stream));
+ else
+ r = inflateInit2(&(zip->stream),
+ -15 /* Don't check for zlib header */);
+ if (r != Z_OK) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Couldn't initialize zlib stream.");
+ return (ARCHIVE_FAILED);
+ }
+ zip->stream_valid = 1;
+ zip->stream.total_in = 0;
+ zip->stream.total_out = 0;
+ break;
+#else
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "DEFLATE codec is unsupported");
+ return (ARCHIVE_FAILED);
+#endif
+ case _7Z_PPMD:
+ {
+ unsigned order;
+ uint32_t msize;
+
+ if (zip->ppmd7_valid) {
+ __archive_ppmd7_functions.Ppmd7_Free(
+ &zip->ppmd7_context, &g_szalloc);
+ zip->ppmd7_valid = 0;
+ }
+
+ if (coder1->propertiesSize < 5) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Malformed PPMd parameter");
+ return (ARCHIVE_FAILED);
+ }
+ order = coder1->properties[0];
+ msize = archive_le32dec(&(coder1->properties[1]));
+ if (order < PPMD7_MIN_ORDER || order > PPMD7_MAX_ORDER ||
+ msize < PPMD7_MIN_MEM_SIZE || msize > PPMD7_MAX_MEM_SIZE) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Malformed PPMd parameter");
+ return (ARCHIVE_FAILED);
+ }
+ __archive_ppmd7_functions.Ppmd7_Construct(&zip->ppmd7_context);
+ r = __archive_ppmd7_functions.Ppmd7_Alloc(
+ &zip->ppmd7_context, msize, &g_szalloc);
+ if (r == 0) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Coludn't allocate memory for PPMd");
+ return (ARCHIVE_FATAL);
+ }
+ __archive_ppmd7_functions.Ppmd7_Init(
+ &zip->ppmd7_context, order);
+ __archive_ppmd7_functions.Ppmd7z_RangeDec_CreateVTable(
+ &zip->range_dec);
+ zip->ppmd7_valid = 1;
+ zip->ppmd7_stat = 0;
+ zip->ppstream.overconsumed = 0;
+ zip->ppstream.total_in = 0;
+ zip->ppstream.total_out = 0;
+ break;
+ }
+ case _7Z_X86:
+ case _7Z_X86_BCJ2:
+ case _7Z_POWERPC:
+ case _7Z_IA64:
+ case _7Z_ARM:
+ case _7Z_ARMTHUMB:
+ case _7Z_SPARC:
+ case _7Z_DELTA:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Unexpected codec ID: %lX", zip->codec);
+ return (ARCHIVE_FAILED);
+ default:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Unknown codec ID: %lX", zip->codec);
+ return (ARCHIVE_FAILED);
+ }
+
+ return (ARCHIVE_OK);
+}
+
+static int
+decompress(struct archive_read *a, struct _7zip *zip,
+ void *buff, size_t *outbytes, const void *b, size_t *used)
+{
+ const uint8_t *t_next_in;
+ uint8_t *t_next_out;
+ size_t o_avail_in, o_avail_out;
+ size_t t_avail_in, t_avail_out;
+ uint8_t *bcj2_next_out;
+ size_t bcj2_avail_out;
+ int r, ret = ARCHIVE_OK;
+
+ t_avail_in = o_avail_in = *used;
+ t_avail_out = o_avail_out = *outbytes;
+ t_next_in = b;
+ t_next_out = buff;
+
+ if (zip->codec != _7Z_LZMA2 && zip->codec2 == _7Z_X86) {
+ int i;
+
+ /* Do not copy out the BCJ remaining bytes when the output
+ * buffer size is less than five bytes. */
+ if (o_avail_in != 0 && t_avail_out < 5 && zip->odd_bcj_size) {
+ *used = 0;
+ *outbytes = 0;
+ return (ret);
+ }
+ for (i = 0; zip->odd_bcj_size > 0 && t_avail_out; i++) {
+ *t_next_out++ = zip->odd_bcj[i];
+ t_avail_out--;
+ zip->odd_bcj_size--;
+ }
+ if (o_avail_in == 0 || t_avail_out == 0) {
+ *used = o_avail_in - t_avail_in;
+ *outbytes = o_avail_out - t_avail_out;
+ if (o_avail_in == 0)
+ ret = ARCHIVE_EOF;
+ return (ret);
+ }
+ }
+
+ bcj2_next_out = t_next_out;
+ bcj2_avail_out = t_avail_out;
+ if (zip->codec2 == _7Z_X86_BCJ2) {
+ /*
+ * Decord a remaining decompressed main stream for BCJ2.
+ */
+ if (zip->tmp_stream_bytes_remaining) {
+ ssize_t bytes;
+ size_t remaining = zip->tmp_stream_bytes_remaining;
+ bytes = Bcj2_Decode(zip, t_next_out, t_avail_out);
+ if (bytes < 0) {
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "BCJ2 conversion Failed");
+ return (ARCHIVE_FAILED);
+ }
+ zip->main_stream_bytes_remaining -=
+ remaining - zip->tmp_stream_bytes_remaining;
+ t_avail_out -= bytes;
+ if (o_avail_in == 0 || t_avail_out == 0) {
+ *used = 0;
+ *outbytes = o_avail_out - t_avail_out;
+ if (o_avail_in == 0 &&
+ zip->tmp_stream_bytes_remaining)
+ ret = ARCHIVE_EOF;
+ return (ret);
+ }
+ t_next_out += bytes;
+ bcj2_next_out = t_next_out;
+ bcj2_avail_out = t_avail_out;
+ }
+ t_next_out = zip->tmp_stream_buff;
+ t_avail_out = zip->tmp_stream_buff_size;
+ }
+
+ switch (zip->codec) {
+ case _7Z_COPY:
+ {
+ size_t bytes =
+ (t_avail_in > t_avail_out)?t_avail_out:t_avail_in;
+
+ memcpy(t_next_out, t_next_in, bytes);
+ t_avail_in -= bytes;
+ t_avail_out -= bytes;
+ if (o_avail_in == 0)
+ ret = ARCHIVE_EOF;
+ break;
+ }
+#ifdef HAVE_LZMA_H
+ case _7Z_LZMA: case _7Z_LZMA2:
+ zip->lzstream.next_in = t_next_in;
+ zip->lzstream.avail_in = t_avail_in;
+ zip->lzstream.next_out = t_next_out;
+ zip->lzstream.avail_out = t_avail_out;
+
+ r = lzma_code(&(zip->lzstream), LZMA_RUN);
+ switch (r) {
+ case LZMA_STREAM_END: /* Found end of stream. */
+ lzma_end(&(zip->lzstream));
+ zip->lzstream_valid = 0;
+ ret = ARCHIVE_EOF;
+ break;
+ case LZMA_OK: /* Decompressor made some progress. */
+ break;
+ default:
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "Decompression failed(%d)",
+ r);
+ return (ARCHIVE_FAILED);
+ }
+ t_avail_in = zip->lzstream.avail_in;
+ t_avail_out = zip->lzstream.avail_out;
+ break;
+#endif
+#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
+ case _7Z_BZ2:
+ zip->bzstream.next_in = (char *)(uintptr_t)t_next_in;
+ zip->bzstream.avail_in = t_avail_in;
+ zip->bzstream.next_out = (char *)(uintptr_t)t_next_out;
+ zip->bzstream.avail_out = t_avail_out;
+ r = BZ2_bzDecompress(&(zip->bzstream));
+ switch (r) {
+ case BZ_STREAM_END: /* Found end of stream. */
+ switch (BZ2_bzDecompressEnd(&(zip->bzstream))) {
+ case BZ_OK:
+ break;
+ default:
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "Failed to clean up decompressor");
+ return (ARCHIVE_FAILED);
+ }
+ zip->bzstream_valid = 0;
+ ret = ARCHIVE_EOF;
+ break;
+ case BZ_OK: /* Decompressor made some progress. */
+ break;
+ default:
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "bzip decompression failed");
+ return (ARCHIVE_FAILED);
+ }
+ t_avail_in = zip->bzstream.avail_in;
+ t_avail_out = zip->bzstream.avail_out;
+ break;
+#endif
+#ifdef HAVE_ZLIB_H
+ case _7Z_DEFLATE:
+ zip->stream.next_in = (Bytef *)(uintptr_t)t_next_in;
+ zip->stream.avail_in = t_avail_in;
+ zip->stream.next_out = t_next_out;
+ zip->stream.avail_out = t_avail_out;
+ r = inflate(&(zip->stream), 0);
+ switch (r) {
+ case Z_STREAM_END: /* Found end of stream. */
+ ret = ARCHIVE_EOF;
+ break;
+ case Z_OK: /* Decompressor made some progress.*/
+ break;
+ default:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "File decompression failed (%d)", r);
+ return (ARCHIVE_FAILED);
+ }
+ t_avail_in = zip->stream.avail_in;
+ t_avail_out = zip->stream.avail_out;
+ break;
+#endif
+ case _7Z_PPMD:
+ {
+ uint64_t flush_bytes;
+
+ if (!zip->ppmd7_valid || zip->ppmd7_stat < 0 ||
+ t_avail_in < 0 || t_avail_out <= 0) {
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "Decompression internal error");
+ return (ARCHIVE_FAILED);
+ }
+ zip->ppstream.next_in = t_next_in;
+ zip->ppstream.avail_in = t_avail_in;
+ zip->ppstream.next_out = t_next_out;
+ zip->ppstream.avail_out = t_avail_out;
+ if (zip->ppmd7_stat == 0) {
+ zip->bytein.a = a;
+ zip->bytein.Read = &ppmd_read;
+ zip->range_dec.Stream = &zip->bytein;
+ r = __archive_ppmd7_functions.Ppmd7z_RangeDec_Init(
+ &(zip->range_dec));
+ if (r == 0) {
+ zip->ppmd7_stat = -1;
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Failed to initialize PPMd range decorder");
+ return (ARCHIVE_FAILED);
+ }
+ if (zip->ppstream.overconsumed) {
+ zip->ppmd7_stat = -1;
+ return (ARCHIVE_FAILED);
+ }
+ zip->ppmd7_stat = 1;
+ }
+
+ if (t_avail_in == 0)
+ /* XXX Flush out remaining decoded data XXX */
+ flush_bytes = zip->folder_outbytes_remaining;
+ else
+ flush_bytes = 0;
+
+ do {
+ int sym;
+
+ sym = __archive_ppmd7_functions.Ppmd7_DecodeSymbol(
+ &(zip->ppmd7_context), &(zip->range_dec.p));
+ if (sym < 0) {
+ zip->ppmd7_stat = -1;
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Failed to decode PPMd");
+ return (ARCHIVE_FAILED);
+ }
+ if (zip->ppstream.overconsumed) {
+ zip->ppmd7_stat = -1;
+ return (ARCHIVE_FAILED);
+ }
+ *zip->ppstream.next_out++ = (unsigned char)sym;
+ zip->ppstream.avail_out--;
+ zip->ppstream.total_out++;
+ if (flush_bytes)
+ flush_bytes--;
+ } while (zip->ppstream.avail_out &&
+ (zip->ppstream.avail_in || flush_bytes));
+
+ t_avail_in = zip->ppstream.avail_in;
+ t_avail_out = zip->ppstream.avail_out;
+ break;
+ }
+ default:
+ archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
+ "Decompression internal error");
+ return (ARCHIVE_FAILED);
+ }
+ if (ret != ARCHIVE_OK && ret != ARCHIVE_EOF)
+ return (ret);
+
+ *used = o_avail_in - t_avail_in;
+ *outbytes = o_avail_out - t_avail_out;
+
+ /*
+ * Decord BCJ.
+ */
+ if (zip->codec != _7Z_LZMA2 && zip->codec2 == _7Z_X86) {
+ size_t l = x86_Convert(zip, buff, *outbytes);
+ zip->odd_bcj_size = *outbytes - l;
+ if (zip->odd_bcj_size > 0 && zip->odd_bcj_size <= 4 &&
+ o_avail_in && ret != ARCHIVE_EOF) {
+ memcpy(zip->odd_bcj, ((unsigned char *)buff) + l,
+ zip->odd_bcj_size);
+ *outbytes = l;
+ } else
+ zip->odd_bcj_size = 0;
+ }
+
+ /*
+ * Decord BCJ2 with a decompressed main stream.
+ */
+ if (zip->codec2 == _7Z_X86_BCJ2) {
+ ssize_t bytes;
+
+ zip->tmp_stream_bytes_avail =
+ zip->tmp_stream_buff_size - t_avail_out;
+ if (zip->tmp_stream_bytes_avail >
+ zip->main_stream_bytes_remaining)
+ zip->tmp_stream_bytes_avail =
+ zip->main_stream_bytes_remaining;
+ zip->tmp_stream_bytes_remaining = zip->tmp_stream_bytes_avail;
+ bytes = Bcj2_Decode(zip, bcj2_next_out, bcj2_avail_out);
+ if (bytes < 0) {
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC, "BCJ2 conversion Failed");
+ return (ARCHIVE_FAILED);
+ }
+ zip->main_stream_bytes_remaining -=
+ zip->tmp_stream_bytes_avail
+ - zip->tmp_stream_bytes_remaining;
+ bcj2_avail_out -= bytes;
+ *outbytes = o_avail_out - bcj2_avail_out;
+ }
+
+ return (ret);
+}
+
+static int
+free_decompression(struct archive_read *a, struct _7zip *zip)
+{
+ int r = ARCHIVE_OK;
+
+#ifdef HAVE_LZMA_H
+ if (zip->lzstream_valid)
+ lzma_end(&(zip->lzstream));
+#endif
+#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
+ if (zip->bzstream_valid) {
+ if (BZ2_bzDecompressEnd(&(zip->bzstream)) != BZ_OK) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Failed to clean up bzip2 decompressor");
+ r = ARCHIVE_FATAL;
+ }
+ zip->bzstream_valid = 0;
+ }
+#endif
+#ifdef HAVE_ZLIB_H
+ if (zip->stream_valid) {
+ if (inflateEnd(&(zip->stream)) != Z_OK) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Failed to clean up zlib decompressor");
+ r = ARCHIVE_FATAL;
+ }
+ zip->stream_valid = 0;
+ }
+#endif
+ if (zip->ppmd7_valid) {
+ __archive_ppmd7_functions.Ppmd7_Free(
+ &zip->ppmd7_context, &g_szalloc);
+ zip->ppmd7_valid = 0;
+ }
+ return (r);
+}
+
+static int
+parse_7zip_uint64(struct archive_read *a, uint64_t *val)
+{
+ const unsigned char *p;
+ unsigned char avail, mask;
+ int i;
+
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ avail = *p;
+ mask = 0x80;
+ *val = 0;
+ for (i = 0; i < 8; i++) {
+ if (avail & mask) {
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ *val |= ((uint64_t)*p) << (8 * i);
+ mask >>= 1;
+ continue;
+ }
+ *val += (avail & (mask -1)) << (8 * i);
+ break;
+ }
+ return (0);
+}
+
+static int
+read_Bools(struct archive_read *a, unsigned char *data, size_t num)
+{
+ const unsigned char *p;
+ unsigned i, mask = 0, avail = 0;
+
+ for (i = 0; i < num; i++) {
+ if (mask == 0) {
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ avail = *p;
+ mask = 0x80;
+ }
+ data[i] = (avail & mask)?1:0;
+ mask >>= 1;
+ }
+ return (0);
+}
+
+static void
+free_Digest(struct _7z_digests *d)
+{
+ free(d->defineds);
+ free(d->digests);
+}
+
+static int
+read_Digests(struct archive_read *a, struct _7z_digests *d, size_t num)
+{
+ const unsigned char *p;
+ unsigned i;
+
+ memset(d, 0, sizeof(*d));
+
+
+ d->defineds = malloc(num);
+ if (d->defineds == NULL)
+ return (-1);
+ /*
+ * Read Bools.
+ */
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ if (*p == 0) {
+ if (read_Bools(a, d->defineds, num) < 0)
+ return (-1);
+ } else
+ /* All are defined */
+ memset(d->defineds, 1, num);
+
+ d->digests = calloc(num, sizeof(*d->digests));
+ if (d->digests == NULL)
+ return (-1);
+ for (i = 0; i < num; i++) {
+ if (d->defineds[i]) {
+ if ((p = header_bytes(a, 4)) == NULL)
+ return (-1);
+ d->digests[i] = archive_le32dec(p);
+ }
+ }
+
+ return (0);
+}
+
+static void
+free_PackInfo(struct _7z_pack_info *pi)
+{
+ free(pi->sizes);
+ free(pi->positions);
+ free_Digest(&(pi->digest));
+}
+
+static int
+read_PackInfo(struct archive_read *a, struct _7z_pack_info *pi)
+{
+ const unsigned char *p;
+ unsigned i;
+
+ memset(pi, 0, sizeof(*pi));
+
+ /*
+ * Read PackPos.
+ */
+ if (parse_7zip_uint64(a, &(pi->pos)) < 0)
+ return (-1);
+
+ /*
+ * Read NumPackStreams.
+ */
+ if (parse_7zip_uint64(a, &(pi->numPackStreams)) < 0)
+ return (-1);
+ if (pi->numPackStreams == 0)
+ return (-1);
+ if (1000000 < pi->numPackStreams)
+ return (-1);
+
+ /*
+ * Read PackSizes[num]
+ */
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ if (*p == kEnd)
+ /* PackSizes[num] are not present. */
+ return (0);
+ if (*p != kSize)
+ return (-1);
+ pi->sizes = calloc(pi->numPackStreams, sizeof(uint64_t));
+ pi->positions = calloc(pi->numPackStreams, sizeof(uint64_t));
+ if (pi->sizes == NULL || pi->positions == NULL)
+ return (-1);
+
+ for (i = 0; i < pi->numPackStreams; i++) {
+ if (parse_7zip_uint64(a, &(pi->sizes[i])) < 0)
+ return (-1);
+ }
+
+ /*
+ * Read PackStreamDigests[num]
+ */
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ if (*p == kEnd) {
+ /* PackStreamDigests[num] are not present. */
+ pi->digest.defineds =
+ calloc(pi->numPackStreams, sizeof(*pi->digest.defineds));
+ pi->digest.digests =
+ calloc(pi->numPackStreams, sizeof(*pi->digest.digests));
+ if (pi->digest.defineds == NULL || pi->digest.digests == NULL)
+ return (-1);
+ return (0);
+ }
+
+ if (*p != kSize)
+ return (-1);
+
+ if (read_Digests(a, &(pi->digest), pi->numPackStreams) < 0)
+ return (-1);
+
+ /*
+ * Must be marked by kEnd.
+ */
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ if (*p != kEnd)
+ return (-1);
+ return (0);
+}
+
+static void
+free_Folder(struct _7z_folder *f)
+{
+ unsigned i;
+
+ if (f->coders) {
+ for (i = 0; i< f->numCoders; i++) {
+ free(f->coders[i].properties);
+ }
+ free(f->coders);
+ }
+ free(f->bindPairs);
+ free(f->packedStreams);
+ free(f->unPackSize);
+}
+
+static int
+read_Folder(struct archive_read *a, struct _7z_folder *f)
+{
+ struct _7zip *zip = (struct _7zip *)a->format->data;
+ const unsigned char *p;
+ uint64_t numInStreamsTotal = 0;
+ uint64_t numOutStreamsTotal = 0;
+ unsigned i;
+
+ memset(f, 0, sizeof(*f));
+
+ /*
+ * Read NumCoders.
+ */
+ if (parse_7zip_uint64(a, &(f->numCoders)) < 0)
+ return (-1);
+ if (f->numCoders > 4)
+ /* Too many coders. */
+ return (-1);
+
+ f->coders = calloc(f->numCoders, sizeof(*f->coders));
+ if (f->coders == NULL)
+ return (-1);
+ for (i = 0; i< f->numCoders; i++) {
+ size_t codec_size;
+ int simple, attr;
+
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ /*
+ * 0:3 CodecIdSize
+ * 4: 0 - IsSimple
+ * 1 - Is not Simple
+ * 5: 0 - No Attributes
+ * 1 - There are Attributes;
+ * 7: Must be zero.
+ */
+ codec_size = *p & 0xf;
+ simple = (*p & 0x10)?0:1;
+ attr = *p & 0x20;
+ if (*p & 0x80)
+ return (-1);/* Not supported. */
+
+ /*
+ * Read Decompression Method IDs.
+ */
+ if ((p = header_bytes(a, codec_size)) == NULL)
+ return (-1);
+
+ f->coders[i].codec = decode_codec_id(p, codec_size);
+
+ if (simple) {
+ f->coders[i].numInStreams = 1;
+ f->coders[i].numOutStreams = 1;
+ } else {
+ if (parse_7zip_uint64(
+ a, &(f->coders[i].numInStreams)) < 0)
+ return (-1);
+ if (1000000 < f->coders[i].numInStreams)
+ return (-1);
+ if (parse_7zip_uint64(
+ a, &(f->coders[i].numOutStreams)) < 0)
+ return (-1);
+ if (1000000 < f->coders[i].numOutStreams)
+ return (-1);
+ }
+
+ if (attr) {
+ if (parse_7zip_uint64(
+ a, &(f->coders[i].propertiesSize)) < 0)
+ return (-1);
+ if ((p = header_bytes(
+ a, f->coders[i].propertiesSize)) == NULL)
+ return (-1);
+ f->coders[i].properties =
+ malloc(f->coders[i].propertiesSize);
+ if (f->coders[i].properties == NULL)
+ return (-1);
+ memcpy(f->coders[i].properties, p,
+ f->coders[i].propertiesSize);
+ }
+
+ numInStreamsTotal += f->coders[i].numInStreams;
+ numOutStreamsTotal += f->coders[i].numOutStreams;
+ }
+
+ if (numOutStreamsTotal == 0 ||
+ numInStreamsTotal < numOutStreamsTotal-1)
+ return (-1);
+
+ f->numBindPairs = numOutStreamsTotal - 1;
+ if (zip->header_bytes_remaining < f->numBindPairs)
+ return (-1);
+ f->bindPairs = calloc(f->numBindPairs, sizeof(*f->bindPairs));
+ if (f->bindPairs == NULL)
+ return (-1);
+ 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)
+ return (-1);
+ if (parse_7zip_uint64(a, &(f->bindPairs[i].outIndex)) < 0)
+ return (-1);
+ if (1000000 < f->bindPairs[i].outIndex)
+ return (-1);
+ }
+
+ f->numPackedStreams = numInStreamsTotal - f->numBindPairs;
+ f->packedStreams =
+ calloc(f->numPackedStreams, sizeof(*f->packedStreams));
+ if (f->packedStreams == NULL)
+ return (-1);
+ if (f->numPackedStreams == 1) {
+ for (i = 0; i < numInStreamsTotal; i++) {
+ unsigned j;
+ for (j = 0; j < f->numBindPairs; j++) {
+ if (f->bindPairs[j].inIndex == i)
+ break;
+ }
+ if (j == f->numBindPairs)
+ break;
+ }
+ if (i == numInStreamsTotal)
+ return (-1);
+ f->packedStreams[0] = i;
+ } else {
+ for (i = 0; i < f->numPackedStreams; i++) {
+ if (parse_7zip_uint64(a, &(f->packedStreams[i])) < 0)
+ return (-1);
+ if (1000000 < f->packedStreams[i])
+ return (-1);
+ }
+ }
+ f->numInStreams = numInStreamsTotal;
+ f->numOutStreams = numOutStreamsTotal;
+
+ return (0);
+}
+
+static void
+free_CodersInfo(struct _7z_coders_info *ci)
+{
+ unsigned i;
+
+ if (ci->folders) {
+ for (i = 0; i < ci->numFolders; i++)
+ free_Folder(&(ci->folders[i]));
+ free(ci->folders);
+ }
+}
+
+static int
+read_CodersInfo(struct archive_read *a, struct _7z_coders_info *ci)
+{
+ const unsigned char *p;
+ struct _7z_digests digest;
+ unsigned i;
+
+ memset(ci, 0, sizeof(*ci));
+ memset(&digest, 0, sizeof(digest));
+
+ if ((p = header_bytes(a, 1)) == NULL)
+ goto failed;
+ if (*p != kFolder)
+ goto failed;
+
+ /*
+ * Read NumFolders.
+ */
+ if (parse_7zip_uint64(a, &(ci->numFolders)) < 0)
+ goto failed;
+ if (1000000 < ci->numFolders)
+ return (-1);
+
+ /*
+ * Read External.
+ */
+ if ((p = header_bytes(a, 1)) == NULL)
+ goto failed;
+ switch (*p) {
+ case 0:
+ ci->folders = calloc(ci->numFolders, sizeof(*ci->folders));
+ if (ci->folders == NULL)
+ return (-1);
+ for (i = 0; i < ci->numFolders; i++) {
+ if (read_Folder(a, &(ci->folders[i])) < 0)
+ goto failed;
+ }
+ break;
+ case 1:
+ if (parse_7zip_uint64(a, &(ci->dataStreamIndex)) < 0)
+ return (-1);
+ if (1000000 < ci->dataStreamIndex)
+ return (-1);
+ break;
+ }
+
+ if ((p = header_bytes(a, 1)) == NULL)
+ goto failed;
+ if (*p != kCodersUnPackSize)
+ goto failed;
+
+ for (i = 0; i < ci->numFolders; i++) {
+ struct _7z_folder *folder = &(ci->folders[i]);
+ unsigned j;
+
+ folder->unPackSize =
+ calloc(folder->numOutStreams, sizeof(*folder->unPackSize));
+ if (folder->unPackSize == NULL)
+ goto failed;
+ for (j = 0; j < folder->numOutStreams; j++) {
+ if (parse_7zip_uint64(a, &(folder->unPackSize[j])) < 0)
+ goto failed;
+ }
+ }
+
+ /*
+ * Read CRCs.
+ */
+ if ((p = header_bytes(a, 1)) == NULL)
+ goto failed;
+ if (*p == kEnd)
+ return (0);
+ if (*p != kCRC)
+ goto failed;
+ if (read_Digests(a, &digest, ci->numFolders) < 0)
+ goto failed;
+ for (i = 0; i < ci->numFolders; i++) {
+ ci->folders[i].digest_defined = digest.defineds[i];
+ ci->folders[i].digest = digest.digests[i];
+ }
+
+ /*
+ * Must be kEnd.
+ */
+ if ((p = header_bytes(a, 1)) == NULL)
+ goto failed;
+ if (*p != kEnd)
+ goto failed;
+ free_Digest(&digest);
+ return (0);
+failed:
+ free_Digest(&digest);
+ return (-1);
+}
+
+static uint64_t
+folder_uncompressed_size(struct _7z_folder *f)
+{
+ int n = f->numOutStreams;
+ unsigned pairs = f->numBindPairs;
+
+ while (--n >= 0) {
+ unsigned i;
+ for (i = 0; i < pairs; i++) {
+ if (f->bindPairs[i].outIndex == n)
+ break;
+ }
+ if (i >= pairs)
+ return (f->unPackSize[n]);
+ }
+ return (0);
+}
+
+static void
+free_SubStreamsInfo(struct _7z_substream_info *ss)
+{
+ free(ss->unpackSizes);
+ free(ss->digestsDefined);
+ free(ss->digests);
+}
+
+static int
+read_SubStreamsInfo(struct archive_read *a, struct _7z_substream_info *ss,
+ struct _7z_folder *f, size_t numFolders)
+{
+ const unsigned char *p;
+ uint64_t *usizes;
+ size_t unpack_streams;
+ int type;
+ unsigned i;
+ uint32_t numDigests;
+
+ memset(ss, 0, sizeof(*ss));
+
+ for (i = 0; i < numFolders; i++)
+ f[i].numUnpackStreams = 1;
+
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ type = *p;
+
+ if (type == kNumUnPackStream) {
+ unpack_streams = 0;
+ for (i = 0; i < numFolders; i++) {
+ if (parse_7zip_uint64(a, &(f[i].numUnpackStreams)) < 0)
+ return (-1);
+ if (1000000 < f[i].numUnpackStreams)
+ return (-1);
+ unpack_streams += f[i].numUnpackStreams;
+ }
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ type = *p;
+ } else
+ unpack_streams = numFolders;
+
+ ss->unpack_streams = unpack_streams;
+ if (unpack_streams) {
+ ss->unpackSizes = calloc(unpack_streams,
+ sizeof(*ss->unpackSizes));
+ ss->digestsDefined = calloc(unpack_streams,
+ sizeof(*ss->digestsDefined));
+ ss->digests = calloc(unpack_streams,
+ sizeof(*ss->digests));
+ if (ss->unpackSizes == NULL || ss->digestsDefined == NULL ||
+ ss->digests == NULL)
+ return (-1);
+ }
+
+ usizes = ss->unpackSizes;
+ for (i = 0; i < numFolders; i++) {
+ unsigned pack;
+ uint64_t sum;
+
+ if (f[i].numUnpackStreams == 0)
+ continue;
+
+ sum = 0;
+ if (type == kSize) {
+ for (pack = 1; pack < f[i].numUnpackStreams; pack++) {
+ if (parse_7zip_uint64(a, usizes) < 0)
+ return (-1);
+ sum += *usizes++;
+ }
+ }
+ *usizes++ = folder_uncompressed_size(&f[i]) - sum;
+ }
+
+ if (type == kSize) {
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ type = *p;
+ }
+
+ for (i = 0; i < unpack_streams; i++) {
+ ss->digestsDefined[i] = 0;
+ ss->digests[i] = 0;
+ }
+
+ numDigests = 0;
+ for (i = 0; i < numFolders; i++) {
+ if (f[i].numUnpackStreams != 1 || !f[i].digest_defined)
+ numDigests += f[i].numUnpackStreams;
+ }
+
+ if (type == kCRC) {
+ struct _7z_digests tmpDigests;
+ unsigned char *digestsDefined = ss->digestsDefined;
+ uint32_t * digests = ss->digests;
+ int di = 0;
+
+ memset(&tmpDigests, 0, sizeof(tmpDigests));
+ if (read_Digests(a, &(tmpDigests), numDigests) < 0) {
+ free_Digest(&tmpDigests);
+ return (-1);
+ }
+ for (i = 0; i < numFolders; i++) {
+ if (f[i].numUnpackStreams == 1 && f[i].digest_defined) {
+ *digestsDefined++ = 1;
+ *digests++ = f[i].digest;
+ } else {
+ unsigned j;
+
+ for (j = 0; j < f[i].numUnpackStreams;
+ j++, di++) {
+ *digestsDefined++ =
+ tmpDigests.defineds[di];
+ *digests++ =
+ tmpDigests.digests[di];
+ }
+ }
+ }
+ free_Digest(&tmpDigests);
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ type = *p;
+ }
+
+ /*
+ * Must be kEnd.
+ */
+ if (type != kEnd)
+ return (-1);
+ return (0);
+}
+
+static void
+free_StreamsInfo(struct _7z_stream_info *si)
+{
+ free_PackInfo(&(si->pi));
+ free_CodersInfo(&(si->ci));
+ free_SubStreamsInfo(&(si->ss));
+}
+
+static int
+read_StreamsInfo(struct archive_read *a, struct _7z_stream_info *si)
+{
+ struct _7zip *zip = (struct _7zip *)a->format->data;
+ const unsigned char *p;
+ unsigned i;
+
+ memset(si, 0, sizeof(*si));
+
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ if (*p == kPackInfo) {
+ uint64_t packPos;
+
+ if (read_PackInfo(a, &(si->pi)) < 0)
+ return (-1);
+
+ if (si->pi.positions == NULL || si->pi.sizes == NULL)
+ return (-1);
+ /*
+ * Calculate packed stream positions.
+ */
+ packPos = si->pi.pos;
+ for (i = 0; i < si->pi.numPackStreams; i++) {
+ si->pi.positions[i] = packPos;
+ packPos += si->pi.sizes[i];
+ if (packPos > zip->header_offset)
+ return (-1);
+ }
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ }
+ if (*p == kUnPackInfo) {
+ uint32_t packIndex;
+ struct _7z_folder *f;
+
+ if (read_CodersInfo(a, &(si->ci)) < 0)
+ return (-1);
+
+ /*
+ * Calculate packed stream indexes.
+ */
+ packIndex = 0;
+ f = si->ci.folders;
+ for (i = 0; i < si->ci.numFolders; i++) {
+ f[i].packIndex = packIndex;
+ packIndex += f[i].numPackedStreams;
+ if (packIndex > si->pi.numPackStreams)
+ return (-1);
+ }
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ }
+
+ if (*p == kSubStreamsInfo) {
+ if (read_SubStreamsInfo(a, &(si->ss),
+ si->ci.folders, si->ci.numFolders) < 0)
+ return (-1);
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ }
+
+ /*
+ * Must be kEnd.
+ */
+ if (*p != kEnd)
+ return (-1);
+ return (0);
+}
+
+static void
+free_Header(struct _7z_header_info *h)
+{
+ free(h->emptyStreamBools);
+ free(h->emptyFileBools);
+ free(h->antiBools);
+ free(h->attrBools);
+}
+
+static int
+read_Header(struct archive_read *a, struct _7z_header_info *h,
+ int check_header_id)
+{
+ struct _7zip *zip = (struct _7zip *)a->format->data;
+ const unsigned char *p;
+ struct _7z_folder *folders;
+ struct _7z_stream_info *si = &(zip->si);
+ struct _7zip_entry *entries;
+ uint32_t folderIndex, indexInFolder;
+ unsigned i;
+ int eindex, empty_streams, sindex;
+
+ if (check_header_id) {
+ /*
+ * Read Header.
+ */
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ if (*p != kHeader)
+ return (-1);
+ }
+
+ /*
+ * Read ArchiveProperties.
+ */
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ if (*p == kArchiveProperties) {
+ for (;;) {
+ uint64_t size;
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ if (*p == 0)
+ break;
+ if (parse_7zip_uint64(a, &size) < 0)
+ return (-1);
+ }
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ }
+
+ /*
+ * Read MainStreamsInfo.
+ */
+ if (*p == kMainStreamsInfo) {
+ if (read_StreamsInfo(a, &(zip->si)) < 0)
+ return (-1);
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ }
+ if (*p == kEnd)
+ return (0);
+
+ /*
+ * Read FilesInfo.
+ */
+ if (*p != kFilesInfo)
+ return (-1);
+
+ if (parse_7zip_uint64(a, &(zip->numFiles)) < 0)
+ return (-1);
+ if (1000000 < zip->numFiles)
+ return (-1);
+
+ zip->entries = calloc(zip->numFiles, sizeof(*zip->entries));
+ if (zip->entries == NULL)
+ return (-1);
+ entries = zip->entries;
+
+ empty_streams = 0;
+ for (;;) {
+ int type;
+ uint64_t size;
+ size_t ll;
+
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ type = *p;
+ if (type == kEnd)
+ break;
+
+ if (parse_7zip_uint64(a, &size) < 0)
+ return (-1);
+ if (zip->header_bytes_remaining < size)
+ return (-1);
+ ll = (size_t)size;
+
+ switch (type) {
+ case kEmptyStream:
+ h->emptyStreamBools = calloc(zip->numFiles,
+ sizeof(*h->emptyStreamBools));
+ if (h->emptyStreamBools == NULL)
+ return (-1);
+ if (read_Bools(
+ a, h->emptyStreamBools, zip->numFiles) < 0)
+ return (-1);
+ empty_streams = 0;
+ for (i = 0; i < zip->numFiles; i++) {
+ if (h->emptyStreamBools[i])
+ empty_streams++;
+ }
+ break;
+ case kEmptyFile:
+ h->emptyFileBools = calloc(empty_streams,
+ sizeof(*h->emptyFileBools));
+ if (h->emptyFileBools == NULL)
+ return (-1);
+ if (read_Bools(a, h->emptyFileBools, empty_streams) < 0)
+ return (-1);
+ break;
+ case kAnti:
+ h->antiBools = calloc(empty_streams,
+ sizeof(*h->antiBools));
+ if (h->antiBools == NULL)
+ return (-1);
+ if (read_Bools(a, h->antiBools, empty_streams) < 0)
+ return (-1);
+ break;
+ case kCTime:
+ case kATime:
+ case kMTime:
+ if (read_Times(a, h, type) < 0)
+ return (-1);
+ break;
+ case kName:
+ {
+ unsigned char *np;
+ size_t nl, nb;
+
+ /* Skip one byte. */
+ if ((p = header_bytes(a, 1)) == NULL)
+ return (-1);
+ ll--;
+
+ if ((ll & 1) || ll < zip->numFiles * 4)
+ return (-1);
+
+ zip->entry_names = malloc(ll);
+ if (zip->entry_names == NULL)
+ return (-1);
+ np = zip->entry_names;
+ nb = ll;
+ /*
+ * Copy whole file names.
+ * NOTE: This loop prevents from expanding
+ * the uncompressed buffer in order not to
+ * use extra memory resource.
+ */
+ while (nb) {
+ size_t b;
+ if (nb > UBUFF_SIZE)
+ b = UBUFF_SIZE;
+ else
+ b = nb;
+ if ((p = header_bytes(a, b)) == NULL)
+ return (-1);
+ memcpy(np, p, b);
+ np += b;
+ nb -= b;
+ }
+ np = zip->entry_names;
+ nl = ll;
+
+ for (i = 0; i < zip->numFiles; i++) {
+ entries[i].utf16name = np;
+#if defined(_WIN32) && !defined(__CYGWIN__) && defined(_DEBUG)
+ entries[i].wname = (wchar_t *)np;
+#endif
+
+ /* Find a terminator. */
+ while (nl >= 2 && (np[0] || np[1])) {
+ np += 2;
+ nl -= 2;
+ }
+ if (nl < 2)
+ return (-1);/* Terminator not found */
+ entries[i].name_len = np - entries[i].utf16name;
+ np += 2;
+ nl -= 2;
+ }
+ break;
+ }
+ case kAttributes:
+ {
+ int allAreDefined;
+
+ if ((p = header_bytes(a, 2)) == NULL)
+ return (-1);
+ allAreDefined = *p;
+ h->attrBools = calloc(zip->numFiles,
+ sizeof(*h->attrBools));
+ if (h->attrBools == NULL)
+ return (-1);
+ if (allAreDefined)
+ memset(h->attrBools, 1, zip->numFiles);
+ else {
+ if (read_Bools(a, h->attrBools,
+ zip->numFiles) < 0)
+ return (-1);
+ }
+ for (i = 0; i < zip->numFiles; i++) {
+ if (h->attrBools[i]) {
+ if ((p = header_bytes(a, 4)) == NULL)
+ return (-1);
+ entries[i].attr = archive_le32dec(p);
+ }
+ }
+ break;
+ }
+ default:
+ if (header_bytes(a, ll) == NULL)
+ return (-1);
+ break;
+ }
+ }
+
+ /*
+ * Set up entry's attributes.
+ */
+ folders = si->ci.folders;
+ eindex = sindex = 0;
+ folderIndex = indexInFolder = 0;
+ for (i = 0; i < zip->numFiles; i++) {
+ if (h->emptyStreamBools == NULL || h->emptyStreamBools[i] == 0)
+ entries[i].flg |= HAS_STREAM;
+ /* The high 16 bits of attributes is a posix file mode. */
+ entries[i].mode = entries[i].attr >> 16;
+ if (entries[i].flg & HAS_STREAM) {
+ if ((size_t)sindex >= si->ss.unpack_streams)
+ return (-1);
+ if (entries[i].mode == 0)
+ entries[i].mode = AE_IFREG | 0777;
+ if (si->ss.digestsDefined[sindex])
+ entries[i].flg |= CRC32_IS_SET;
+ entries[i].ssIndex = sindex;
+ sindex++;
+ } else {
+ int dir;
+ if (h->emptyFileBools == NULL)
+ dir = 1;
+ else {
+ if (h->emptyFileBools[eindex])
+ dir = 0;
+ else
+ dir = 1;
+ eindex++;
+ }
+ if (entries[i].mode == 0) {
+ if (dir)
+ entries[i].mode = AE_IFDIR | 0777;
+ else
+ entries[i].mode = AE_IFREG | 0777;
+ } else if (dir &&
+ (entries[i].mode & AE_IFMT) != AE_IFDIR) {
+ entries[i].mode &= ~AE_IFMT;
+ entries[i].mode |= AE_IFDIR;
+ }
+ if ((entries[i].mode & AE_IFMT) == AE_IFDIR &&
+ entries[i].name_len >= 2 &&
+ (entries[i].utf16name[entries[i].name_len-2] != '/' ||
+ entries[i].utf16name[entries[i].name_len-1] != 0)) {
+ entries[i].utf16name[entries[i].name_len] = '/';
+ entries[i].utf16name[entries[i].name_len+1] = 0;
+ entries[i].name_len += 2;
+ }
+ entries[i].ssIndex = -1;
+ }
+ if (entries[i].attr & 0x01)
+ entries[i].mode &= ~0222;/* Read only. */
+
+ if ((entries[i].flg & HAS_STREAM) == 0 && indexInFolder == 0) {
+ /*
+ * The entry is an empty file or a directory file,
+ * those both have no contents.
+ */
+ entries[i].folderIndex = -1;
+ continue;
+ }
+ if (indexInFolder == 0) {
+ for (;;) {
+ if (folderIndex >= si->ci.numFolders)
+ return (-1);
+ if (folders[folderIndex].numUnpackStreams)
+ break;
+ folderIndex++;
+ }
+ }
+ entries[i].folderIndex = folderIndex;
+ if ((entries[i].flg & HAS_STREAM) == 0)
+ continue;
+ indexInFolder++;
+ if (indexInFolder >= folders[folderIndex].numUnpackStreams) {
+ folderIndex++;
+ indexInFolder = 0;
+ }
+ }
+
+ return (0);
+}
+
+#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
+static void
+fileTimeToUtc(uint64_t fileTime, time_t *time, long *ns)
+{
+
+ if (fileTime >= EPOC_TIME) {
+ fileTime -= EPOC_TIME;
+ /* milli seconds base */
+ *time = (time_t)(fileTime / 10000000);
+ /* nano seconds base */
+ *ns = (long)(fileTime % 10000000) * 100;
+ } else {
+ *time = 0;
+ *ns = 0;
+ }
+}
+
+static int
+read_Times(struct archive_read *a, struct _7z_header_info *h, int type)
+{
+ struct _7zip *zip = (struct _7zip *)a->format->data;
+ const unsigned char *p;
+ struct _7zip_entry *entries = zip->entries;
+ unsigned char *timeBools;
+ int allAreDefined;
+ unsigned i;
+
+ timeBools = calloc(zip->numFiles, sizeof(*timeBools));
+ if (timeBools == NULL)
+ return (-1);
+
+ /* Read allAreDefined. */
+ if ((p = header_bytes(a, 1)) == NULL)
+ goto failed;
+ allAreDefined = *p;
+ if (allAreDefined)
+ memset(timeBools, 1, zip->numFiles);
+ else {
+ if (read_Bools(a, timeBools, zip->numFiles) < 0)
+ goto failed;
+ }
+
+ /* Read external. */
+ if ((p = header_bytes(a, 1)) == NULL)
+ goto failed;
+ if (*p) {
+ if (parse_7zip_uint64(a, &(h->dataIndex)) < 0)
+ goto failed;
+ if (1000000 < h->dataIndex)
+ return (-1);
+ }
+
+ for (i = 0; i < zip->numFiles; i++) {
+ if (!timeBools[i])
+ continue;
+ if ((p = header_bytes(a, 8)) == NULL)
+ goto failed;
+ switch (type) {
+ case kCTime:
+ fileTimeToUtc(archive_le64dec(p),
+ &(entries[i].ctime),
+ &(entries[i].ctime_ns));
+ entries[i].flg |= CTIME_IS_SET;
+ break;
+ case kATime:
+ fileTimeToUtc(archive_le64dec(p),
+ &(entries[i].atime),
+ &(entries[i].atime_ns));
+ entries[i].flg |= ATIME_IS_SET;
+ break;
+ case kMTime:
+ fileTimeToUtc(archive_le64dec(p),
+ &(entries[i].mtime),
+ &(entries[i].mtime_ns));
+ entries[i].flg |= MTIME_IS_SET;
+ break;
+ }
+ }
+
+ free(timeBools);
+ return (0);
+failed:
+ free(timeBools);
+ return (-1);
+}
+
+static int
+decode_encoded_header_info(struct archive_read *a, struct _7z_stream_info *si)
+{
+ struct _7zip *zip = (struct _7zip *)a->format->data;
+
+ errno = 0;
+ if (read_StreamsInfo(a, si) < 0) {
+ if (errno == ENOMEM)
+ archive_set_error(&a->archive, -1,
+ "Couldn't allocate memory");
+ else
+ archive_set_error(&a->archive, -1,
+ "Malformed 7-Zip archive");
+ return (ARCHIVE_FATAL);
+ }
+
+ if (si->pi.numPackStreams == 0 || si->ci.numFolders == 0) {
+ archive_set_error(&a->archive, -1, "Malformed 7-Zip archive");
+ return (ARCHIVE_FATAL);
+ }
+
+ if (zip->header_offset < si->pi.pos + si->pi.sizes[0] ||
+ (int64_t)(si->pi.pos + si->pi.sizes[0]) < 0 ||
+ si->pi.sizes[0] == 0 || (int64_t)si->pi.pos < 0) {
+ archive_set_error(&a->archive, -1, "Malformed Header offset");
+ return (ARCHIVE_FATAL);
+ }
+
+ return (ARCHIVE_OK);
+}
+
+static const unsigned char *
+header_bytes(struct archive_read *a, size_t rbytes)
+{
+ struct _7zip *zip = (struct _7zip *)a->format->data;
+ const unsigned char *p;
+
+ if (zip->header_bytes_remaining < rbytes)
+ return (NULL);
+ if (zip->pack_stream_bytes_unconsumed)
+ read_consume(a);
+
+ if (zip->header_is_encoded == 0) {
+ p = __archive_read_ahead(a, rbytes, NULL);
+ if (p == NULL)
+ return (NULL);
+ zip->header_bytes_remaining -= rbytes;
+ zip->pack_stream_bytes_unconsumed = rbytes;
+ } else {
+ const void *buff;
+ ssize_t bytes;
+
+ bytes = read_stream(a, &buff, rbytes, rbytes);
+ if (bytes <= 0)
+ return (NULL);
+ zip->header_bytes_remaining -= bytes;
+ p = buff;
+ }
+
+ /* Update checksum */
+ zip->header_crc32 = crc32(zip->header_crc32, p, rbytes);
+ return (p);
+}
+
+static int
+slurp_central_directory(struct archive_read *a, struct _7zip *zip,
+ struct _7z_header_info *header)
+{
+ const unsigned char *p;
+ uint64_t next_header_offset;
+ uint64_t next_header_size;
+ uint32_t next_header_crc;
+ ssize_t bytes_avail;
+ int check_header_crc, r;
+
+ if ((p = __archive_read_ahead(a, 32, &bytes_avail)) == NULL)
+ return (ARCHIVE_FATAL);
+
+ if ((p[0] == 'M' && p[1] == 'Z') || memcmp(p, "\x7F\x45LF", 4) == 0) {
+ /* This is an executable ? Must be self-extracting... */
+ r = skip_sfx(a, bytes_avail);
+ if (r < ARCHIVE_WARN)
+ return (r);
+ if ((p = __archive_read_ahead(a, 32, &bytes_avail)) == NULL)
+ return (ARCHIVE_FATAL);
+ }
+ zip->seek_base += 32;
+
+ if (memcmp(p, _7ZIP_SIGNATURE, 6) != 0) {
+ archive_set_error(&a->archive, -1, "Not 7-Zip archive file");
+ return (ARCHIVE_FATAL);
+ }
+
+ /* CRC check. */
+ if (crc32(0, (unsigned char *)p + 12, 20) != archive_le32dec(p + 8)) {
+ archive_set_error(&a->archive, -1, "Header CRC error");
+ return (ARCHIVE_FATAL);
+ }
+
+ next_header_offset = archive_le64dec(p + 12);
+ next_header_size = archive_le64dec(p + 20);
+ next_header_crc = archive_le32dec(p + 28);
+
+ if (next_header_size == 0)
+ /* There is no entry in an archive file. */
+ return (ARCHIVE_EOF);
+
+ if (((int64_t)next_header_offset) < 0) {
+ archive_set_error(&a->archive, -1, "Malformed 7-Zip archive");
+ return (ARCHIVE_FATAL);
+ }
+ __archive_read_consume(a, 32);
+ if (next_header_offset != 0) {
+ if (bytes_avail >= next_header_offset)
+ __archive_read_consume(a, next_header_offset);
+ else if (__archive_read_seek(a,
+ next_header_offset + zip->seek_base, SEEK_SET) < 0)
+ return (ARCHIVE_FATAL);
+ }
+ zip->stream_offset = next_header_offset;
+ zip->header_offset = next_header_offset;
+ zip->header_bytes_remaining = next_header_size;
+ zip->header_crc32 = 0;
+ zip->header_is_encoded = 0;
+ zip->header_is_being_read = 1;
+ check_header_crc = 1;
+
+ if ((p = header_bytes(a, 1)) == NULL) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated 7-Zip file body");
+ return (ARCHIVE_FATAL);
+ }
+ /* Parse ArchiveProperties. */
+ switch (p[0]) {
+ case kEncodedHeader:
+ /*
+ * The archive has an encoded header and we have to decode it
+ * in order to parse the header correctly.
+ */
+ r = decode_encoded_header_info(a, &(zip->si));
+
+ /* Check the EncodedHeader CRC.*/
+ if (r == 0 && zip->header_crc32 != next_header_crc) {
+ archive_set_error(&a->archive, -1,
+ "Damaged 7-Zip archive");
+ r = -1;
+ }
+ if (r == 0) {
+ if (zip->si.ci.folders[0].digest_defined)
+ next_header_crc = zip->si.ci.folders[0].digest;
+ else
+ check_header_crc = 0;
+ if (zip->pack_stream_bytes_unconsumed)
+ read_consume(a);
+ r = setup_decode_folder(a, zip->si.ci.folders, 1);
+ if (r == 0) {
+ zip->header_bytes_remaining =
+ zip->folder_outbytes_remaining;
+ r = seek_pack(a);
+ }
+ }
+ /* Clean up StreamsInfo. */
+ free_StreamsInfo(&(zip->si));
+ memset(&(zip->si), 0, sizeof(zip->si));
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ zip->header_is_encoded = 1;
+ zip->header_crc32 = 0;
+ /* FALL THROUGH */
+ case kHeader:
+ /*
+ * Parse the header.
+ */
+ errno = 0;
+ r = read_Header(a, header, zip->header_is_encoded);
+ if (r < 0) {
+ if (errno == ENOMEM)
+ archive_set_error(&a->archive, -1,
+ "Couldn't allocate memory");
+ else
+ archive_set_error(&a->archive, -1,
+ "Damaged 7-Zip archive");
+ return (ARCHIVE_FATAL);
+ }
+
+ /*
+ * Must be kEnd.
+ */
+ if ((p = header_bytes(a, 1)) == NULL ||*p != kEnd) {
+ archive_set_error(&a->archive, -1,
+ "Malformed 7-Zip archive");
+ return (ARCHIVE_FATAL);
+ }
+
+ /* Check the Header CRC.*/
+ if (check_header_crc && zip->header_crc32 != next_header_crc) {
+ archive_set_error(&a->archive, -1,
+ "Malformed 7-Zip archive");
+ return (ARCHIVE_FATAL);
+ }
+ break;
+ default:
+ archive_set_error(&a->archive, -1,
+ "Unexpected Property ID = %X", p[0]);
+ return (ARCHIVE_FATAL);
+ }
+
+ /* Clean up variables be used for decoding the archive header */
+ zip->pack_stream_remaining = 0;
+ zip->pack_stream_index = 0;
+ zip->folder_outbytes_remaining = 0;
+ zip->uncompressed_buffer_bytes_remaining = 0;
+ zip->pack_stream_bytes_unconsumed = 0;
+ zip->header_is_being_read = 0;
+
+ return (ARCHIVE_OK);
+}
+
+static ssize_t
+get_uncompressed_data(struct archive_read *a, const void **buff, size_t size,
+ size_t minimum)
+{
+ struct _7zip *zip = (struct _7zip *)a->format->data;
+ ssize_t bytes_avail;
+
+ if (zip->codec == _7Z_COPY && zip->codec2 == -1) {
+ /* Copy mode. */
+
+ /*
+ * Note: '1' here is a performance optimization.
+ * Recall that the decompression layer returns a count of
+ * available bytes; asking for more than that forces the
+ * decompressor to combine reads by copying data.
+ */
+ *buff = __archive_read_ahead(a, 1, &bytes_avail);
+ if (bytes_avail <= 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated 7-Zip file data");
+ return (ARCHIVE_FATAL);
+ }
+ if ((size_t)bytes_avail >
+ zip->uncompressed_buffer_bytes_remaining)
+ bytes_avail = (ssize_t)
+ zip->uncompressed_buffer_bytes_remaining;
+ if ((size_t)bytes_avail > size)
+ bytes_avail = (ssize_t)size;
+
+ zip->pack_stream_bytes_unconsumed = bytes_avail;
+ } else if (zip->uncompressed_buffer_pointer == NULL) {
+ /* Decompression has failed. */
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC, "Damaged 7-Zip archive");
+ return (ARCHIVE_FATAL);
+ } else {
+ /* Packed mode. */
+ if (minimum > zip->uncompressed_buffer_bytes_remaining) {
+ /*
+ * If remaining uncompressed data size is less than
+ * the minimum size, fill the buffer up to the
+ * minimum size.
+ */
+ if (extract_pack_stream(a, minimum) < 0)
+ return (ARCHIVE_FATAL);
+ }
+ if (size > zip->uncompressed_buffer_bytes_remaining)
+ bytes_avail = (ssize_t)
+ zip->uncompressed_buffer_bytes_remaining;
+ else
+ bytes_avail = (ssize_t)size;
+ *buff = zip->uncompressed_buffer_pointer;
+ zip->uncompressed_buffer_pointer += bytes_avail;
+ }
+ zip->uncompressed_buffer_bytes_remaining -= bytes_avail;
+ return (bytes_avail);
+}
+
+static ssize_t
+extract_pack_stream(struct archive_read *a, size_t minimum)
+{
+ struct _7zip *zip = (struct _7zip *)a->format->data;
+ ssize_t bytes_avail;
+ int r;
+
+ if (zip->codec == _7Z_COPY && zip->codec2 == -1) {
+ if (minimum == 0)
+ minimum = 1;
+ if (__archive_read_ahead(a, minimum, &bytes_avail) == NULL
+ || bytes_avail <= 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated 7-Zip file body");
+ return (ARCHIVE_FATAL);
+ }
+ if (bytes_avail > zip->pack_stream_inbytes_remaining)
+ bytes_avail = zip->pack_stream_inbytes_remaining;
+ zip->pack_stream_inbytes_remaining -= bytes_avail;
+ if (bytes_avail > zip->folder_outbytes_remaining)
+ bytes_avail = zip->folder_outbytes_remaining;
+ zip->folder_outbytes_remaining -= bytes_avail;
+ zip->uncompressed_buffer_bytes_remaining = bytes_avail;
+ return (ARCHIVE_OK);
+ }
+
+ /* If the buffer hasn't been allocated, allocate it now. */
+ if (zip->uncompressed_buffer == NULL) {
+ zip->uncompressed_buffer_size = UBUFF_SIZE;
+ if (zip->uncompressed_buffer_size < minimum) {
+ zip->uncompressed_buffer_size = minimum + 1023;
+ zip->uncompressed_buffer_size &= ~0x3ff;
+ }
+ zip->uncompressed_buffer =
+ malloc(zip->uncompressed_buffer_size);
+ if (zip->uncompressed_buffer == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "No memory for 7-Zip decompression");
+ return (ARCHIVE_FATAL);
+ }
+ zip->uncompressed_buffer_bytes_remaining = 0;
+ } else if (zip->uncompressed_buffer_size < minimum ||
+ zip->uncompressed_buffer_bytes_remaining < minimum) {
+ /*
+ * Make sure the uncompressed buffer can have bytes
+ * at least `minimum' bytes.
+ * NOTE: This case happen when reading the header.
+ */
+ size_t used;
+ if (zip->uncompressed_buffer_pointer != 0)
+ used = zip->uncompressed_buffer_pointer -
+ zip->uncompressed_buffer;
+ else
+ used = 0;
+ if (zip->uncompressed_buffer_size < minimum) {
+ /*
+ * Expand the uncompressed buffer up to
+ * the minimum size.
+ */
+ zip->uncompressed_buffer_size = minimum + 1023;
+ zip->uncompressed_buffer_size &= ~0x3ff;
+ zip->uncompressed_buffer =
+ realloc(zip->uncompressed_buffer,
+ zip->uncompressed_buffer_size);
+ if (zip->uncompressed_buffer == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "No memory for 7-Zip decompression");
+ return (ARCHIVE_FATAL);
+ }
+ }
+ /*
+ * Move unconsumed bytes to the head.
+ */
+ if (used) {
+ memmove(zip->uncompressed_buffer,
+ zip->uncompressed_buffer + used,
+ zip->uncompressed_buffer_bytes_remaining);
+ }
+ } else
+ zip->uncompressed_buffer_bytes_remaining = 0;
+ zip->uncompressed_buffer_pointer = NULL;
+ for (;;) {
+ size_t bytes_in, bytes_out;
+ const void *buff_in;
+ unsigned char *buff_out;
+ int eof;
+
+ /*
+ * Note: '1' here is a performance optimization.
+ * Recall that the decompression layer returns a count of
+ * available bytes; asking for more than that forces the
+ * decompressor to combine reads by copying data.
+ */
+ buff_in = __archive_read_ahead(a, 1, &bytes_avail);
+ if (bytes_avail <= 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated 7-Zip file body");
+ return (ARCHIVE_FATAL);
+ }
+
+ buff_out = zip->uncompressed_buffer
+ + zip->uncompressed_buffer_bytes_remaining;
+ bytes_out = zip->uncompressed_buffer_size
+ - zip->uncompressed_buffer_bytes_remaining;
+ bytes_in = bytes_avail;
+ if (bytes_in > zip->pack_stream_inbytes_remaining)
+ bytes_in = zip->pack_stream_inbytes_remaining;
+ /* Drive decompression. */
+ r = decompress(a, zip, buff_out, &bytes_out,
+ buff_in, &bytes_in);
+ switch (r) {
+ case ARCHIVE_OK:
+ eof = 0;
+ break;
+ case ARCHIVE_EOF:
+ eof = 1;
+ break;
+ default:
+ return (ARCHIVE_FATAL);
+ }
+ zip->pack_stream_inbytes_remaining -= bytes_in;
+ if (bytes_out > zip->folder_outbytes_remaining)
+ bytes_out = zip->folder_outbytes_remaining;
+ zip->folder_outbytes_remaining -= bytes_out;
+ zip->uncompressed_buffer_bytes_remaining += bytes_out;
+ zip->pack_stream_bytes_unconsumed = bytes_in;
+
+ /*
+ * Continue decompression until uncompressed_buffer is full.
+ */
+ if (zip->uncompressed_buffer_bytes_remaining ==
+ zip->uncompressed_buffer_size)
+ break;
+ if (zip->codec2 == _7Z_X86 && zip->odd_bcj_size &&
+ zip->uncompressed_buffer_bytes_remaining + 5 >
+ zip->uncompressed_buffer_size)
+ break;
+ if (zip->pack_stream_inbytes_remaining == 0 &&
+ zip->folder_outbytes_remaining == 0)
+ break;
+ if (eof || (bytes_in == 0 && bytes_out == 0)) {
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC, "Damaged 7-Zip archive");
+ return (ARCHIVE_FATAL);
+ }
+ read_consume(a);
+ }
+ if (zip->uncompressed_buffer_bytes_remaining < minimum) {
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC, "Damaged 7-Zip archive");
+ return (ARCHIVE_FATAL);
+ }
+ zip->uncompressed_buffer_pointer = zip->uncompressed_buffer;
+ return (ARCHIVE_OK);
+}
+
+static int
+seek_pack(struct archive_read *a)
+{
+ struct _7zip *zip = (struct _7zip *)a->format->data;
+ uint64_t pack_offset;
+
+ if (zip->pack_stream_remaining <= 0) {
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC, "Damaged 7-Zip archive");
+ return (ARCHIVE_FATAL);
+ }
+ zip->pack_stream_inbytes_remaining =
+ zip->si.pi.sizes[zip->pack_stream_index];
+ pack_offset = zip->si.pi.positions[zip->pack_stream_index];
+ if (zip->stream_offset != pack_offset) {
+ if (0 > __archive_read_seek(a, pack_offset + zip->seek_base,
+ SEEK_SET))
+ return (ARCHIVE_FATAL);
+ zip->stream_offset = pack_offset;
+ }
+ zip->pack_stream_index++;
+ zip->pack_stream_remaining--;
+ return (ARCHIVE_OK);
+}
+
+static ssize_t
+read_stream(struct archive_read *a, const void **buff, size_t size,
+ size_t minimum)
+{
+ struct _7zip *zip = (struct _7zip *)a->format->data;
+ uint64_t skip_bytes = 0;
+ int r;
+
+ if (zip->uncompressed_buffer_bytes_remaining == 0) {
+ if (zip->pack_stream_inbytes_remaining > 0) {
+ r = extract_pack_stream(a, 0);
+ if (r < 0)
+ return (r);
+ return (get_uncompressed_data(a, buff, size, minimum));
+ } else if (zip->folder_outbytes_remaining > 0) {
+ /* Extract a remaining pack stream. */
+ r = extract_pack_stream(a, 0);
+ if (r < 0)
+ return (r);
+ return (get_uncompressed_data(a, buff, size, minimum));
+ }
+ } else
+ return (get_uncompressed_data(a, buff, size, minimum));
+
+ /*
+ * Current pack stream has been consumed.
+ */
+ if (zip->pack_stream_remaining == 0) {
+ if (zip->header_is_being_read) {
+ /* Invalid sequence. This might happen when
+ * reading a malformed archive. */
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC, "Malformed 7-Zip archive");
+ return (ARCHIVE_FATAL);
+ }
+
+ /*
+ * All current folder's pack streams have been
+ * consumed. Switch to next folder.
+ */
+ if (zip->folder_index == 0 &&
+ (zip->si.ci.folders[zip->entry->folderIndex].skipped_bytes
+ || zip->folder_index != zip->entry->folderIndex)) {
+ zip->folder_index = zip->entry->folderIndex;
+ skip_bytes =
+ zip->si.ci.folders[zip->folder_index].skipped_bytes;
+ }
+
+ if (zip->folder_index >= zip->si.ci.numFolders) {
+ /*
+ * We have consumed all folders and its pack streams.
+ */
+ *buff = NULL;
+ return (0);
+ }
+ r = setup_decode_folder(a,
+ &(zip->si.ci.folders[zip->folder_index]), 0);
+ if (r != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ zip->folder_index++;
+ }
+
+ /*
+ * Switch to next pack stream.
+ */
+ r = seek_pack(a);
+ if (r < 0)
+ return (r);
+
+ /* Extract a new pack stream. */
+ r = extract_pack_stream(a, 0);
+ if (r < 0)
+ return (r);
+
+ /*
+ * Skip the bytes we alrady has skipped in skip_stream().
+ */
+ while (skip_bytes) {
+ ssize_t skipped;
+
+ if (zip->uncompressed_buffer_bytes_remaining == 0) {
+ if (zip->pack_stream_inbytes_remaining > 0) {
+ r = extract_pack_stream(a, 0);
+ if (r < 0)
+ return (r);
+ } else if (zip->folder_outbytes_remaining > 0) {
+ /* Extract a remaining pack stream. */
+ r = extract_pack_stream(a, 0);
+ if (r < 0)
+ return (r);
+ } else {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated 7-Zip file body");
+ return (ARCHIVE_FATAL);
+ }
+ }
+ skipped = get_uncompressed_data(a, buff, skip_bytes, 0);
+ if (skipped < 0)
+ return (skipped);
+ skip_bytes -= skipped;
+ if (zip->pack_stream_bytes_unconsumed)
+ read_consume(a);
+ }
+
+ return (get_uncompressed_data(a, buff, size, minimum));
+}
+
+static int
+setup_decode_folder(struct archive_read *a, struct _7z_folder *folder,
+ int header)
+{
+ struct _7zip *zip = (struct _7zip *)a->format->data;
+ const struct _7z_coder *coder1, *coder2;
+ const char *cname = (header)?"archive header":"file content";
+ unsigned i;
+ int r, found_bcj2 = 0;
+
+ /*
+ * Release the memory which the previous folder used for BCJ2.
+ */
+ for (i = 0; i < 3; i++) {
+ if (zip->sub_stream_buff[i] != NULL)
+ free(zip->sub_stream_buff[i]);
+ zip->sub_stream_buff[i] = NULL;
+ }
+
+ /*
+ * Initialize a stream reader.
+ */
+ zip->pack_stream_remaining = (unsigned)folder->numPackedStreams;
+ zip->pack_stream_index = (unsigned)folder->packIndex;
+ zip->folder_outbytes_remaining = folder_uncompressed_size(folder);
+ zip->uncompressed_buffer_bytes_remaining = 0;
+
+ /*
+ * 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);
+ }
+ if (folder->coders[i].codec == _7Z_X86_BCJ2)
+ found_bcj2++;
+ }
+ if ((folder->numCoders > 2 && !found_bcj2) || found_bcj2 > 1) {
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "The %s is encoded with many filters, "
+ "but currently not supported", cname);
+ return (ARCHIVE_FATAL);
+ }
+ coder1 = &(folder->coders[0]);
+ if (folder->numCoders == 2)
+ coder2 = &(folder->coders[1]);
+ else
+ coder2 = NULL;
+
+ if (found_bcj2) {
+ /*
+ * Preparation to decode BCJ2.
+ * Decoding BCJ2 requires four sources. Those are at least,
+ * as far as I know, two types of the storage form.
+ */
+ const struct _7z_coder *fc = folder->coders;
+ static const struct _7z_coder coder_copy = {0, 1, 1, 0, NULL};
+ const struct _7z_coder *scoder[3] =
+ {&coder_copy, &coder_copy, &coder_copy};
+ const void *buff;
+ ssize_t bytes;
+ unsigned char *b[3] = {NULL, NULL, NULL};
+ uint64_t sunpack[3] ={-1, -1, -1};
+ size_t s[3] = {0, 0, 0};
+ int idx[3] = {0, 1, 2};
+
+ if (folder->numCoders == 4 && fc[3].codec == _7Z_X86_BCJ2 &&
+ folder->numInStreams == 7 && folder->numOutStreams == 4 &&
+ zip->pack_stream_remaining == 4) {
+ /* Source type 1 made by 7zr or 7z with -m options. */
+ if (folder->bindPairs[0].inIndex == 5) {
+ /* The form made by 7zr */
+ idx[0] = 1; idx[1] = 2; idx[2] = 0;
+ scoder[1] = &(fc[1]);
+ scoder[2] = &(fc[0]);
+ sunpack[1] = folder->unPackSize[1];
+ sunpack[2] = folder->unPackSize[0];
+ coder1 = &(fc[2]);
+ } else {
+ /*
+ * NOTE: Some patterns do not work.
+ * work:
+ * 7z a -m0=BCJ2 -m1=COPY -m2=COPY
+ * -m3=(any)
+ * 7z a -m0=BCJ2 -m1=COPY -m2=(any)
+ * -m3=COPY
+ * 7z a -m0=BCJ2 -m1=(any) -m2=COPY
+ * -m3=COPY
+ * not work:
+ * other patterns.
+ *
+ * We have to handle this like `pipe' or
+ * our libarchive7s filter frame work,
+ * decoding the BCJ2 main stream sequentially,
+ * m3 -> m2 -> m1 -> BCJ2.
+ *
+ */
+ if (fc[0].codec == _7Z_COPY &&
+ fc[1].codec == _7Z_COPY)
+ coder1 = &(folder->coders[2]);
+ else if (fc[0].codec == _7Z_COPY &&
+ fc[2].codec == _7Z_COPY)
+ coder1 = &(folder->coders[1]);
+ else if (fc[1].codec == _7Z_COPY &&
+ fc[2].codec == _7Z_COPY)
+ coder1 = &(folder->coders[0]);
+ else {
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "Unsupported form of "
+ "BCJ2 streams");
+ return (ARCHIVE_FATAL);
+ }
+ }
+ coder2 = &(fc[3]);
+ zip->main_stream_bytes_remaining =
+ folder->unPackSize[2];
+ } else if (coder2 != NULL && coder2->codec == _7Z_X86_BCJ2 &&
+ zip->pack_stream_remaining == 4 &&
+ folder->numInStreams == 5 && folder->numOutStreams == 2) {
+ /* Source type 0 made by 7z */
+ zip->main_stream_bytes_remaining =
+ folder->unPackSize[0];
+ } else {
+ /* We got an unexpected form. */
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "Unsupported form of BCJ2 streams");
+ return (ARCHIVE_FATAL);
+ }
+
+ /* Skip the main stream at this time. */
+ if ((r = seek_pack(a)) < 0)
+ return (r);
+ zip->pack_stream_bytes_unconsumed =
+ zip->pack_stream_inbytes_remaining;
+ read_consume(a);
+
+ /* Read following three sub streams. */
+ for (i = 0; i < 3; i++) {
+ const struct _7z_coder *coder = scoder[i];
+
+ if ((r = seek_pack(a)) < 0)
+ return (r);
+
+ if (sunpack[i] == -1)
+ zip->folder_outbytes_remaining =
+ zip->pack_stream_inbytes_remaining;
+ else
+ zip->folder_outbytes_remaining = sunpack[i];
+
+ r = init_decompression(a, zip, coder, NULL);
+ if (r != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ /* Allocate memory for the decorded data of a sub
+ * stream. */
+ b[i] = malloc(zip->folder_outbytes_remaining);
+ if (b[i] == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "No memory for 7-Zip decompression");
+ return (ARCHIVE_FATAL);
+ }
+
+ /* Extract a sub stream. */
+ while (zip->pack_stream_inbytes_remaining > 0) {
+ r = extract_pack_stream(a, 0);
+ if (r < 0)
+ return (r);
+ bytes = get_uncompressed_data(a, &buff,
+ zip->uncompressed_buffer_bytes_remaining,
+ 0);
+ if (bytes < 0)
+ return ((int)bytes);
+ memcpy(b[i]+s[i], buff, bytes);
+ s[i] += bytes;
+ if (zip->pack_stream_bytes_unconsumed)
+ read_consume(a);
+ }
+ }
+
+ /* Set the sub streams to the right place. */
+ for (i = 0; i < 3; i++) {
+ zip->sub_stream_buff[i] = b[idx[i]];
+ zip->sub_stream_size[i] = s[idx[i]];
+ zip->sub_stream_bytes_remaining[i] = s[idx[i]];
+ }
+
+ /* Allocate memory used for decoded main stream bytes. */
+ if (zip->tmp_stream_buff == NULL) {
+ zip->tmp_stream_buff_size = 32 * 1024;
+ zip->tmp_stream_buff =
+ malloc(zip->tmp_stream_buff_size);
+ if (zip->tmp_stream_buff == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "No memory for 7-Zip decompression");
+ return (ARCHIVE_FATAL);
+ }
+ }
+ zip->tmp_stream_bytes_avail = 0;
+ zip->tmp_stream_bytes_remaining = 0;
+ zip->odd_bcj_size = 0;
+ zip->bcj2_outPos = 0;
+
+ /*
+ * Reset a stream reader in order to read the main stream
+ * of BCJ2.
+ */
+ zip->pack_stream_remaining = 1;
+ zip->pack_stream_index = (unsigned)folder->packIndex;
+ zip->folder_outbytes_remaining =
+ folder_uncompressed_size(folder);
+ zip->uncompressed_buffer_bytes_remaining = 0;
+ }
+
+ /*
+ * Initialize the decompressor for the new folder's pack streams.
+ */
+ r = init_decompression(a, zip, coder1, coder2);
+ if (r != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ return (ARCHIVE_OK);
+}
+
+static int64_t
+skip_stream(struct archive_read *a, size_t skip_bytes)
+{
+ struct _7zip *zip = (struct _7zip *)a->format->data;
+ const void *p;
+ int64_t skipped_bytes;
+ size_t bytes = skip_bytes;
+
+ if (zip->folder_index == 0) {
+ /*
+ * Optimization for a list mode.
+ * Avoid unncecessary decoding operations.
+ */
+ zip->si.ci.folders[zip->entry->folderIndex].skipped_bytes
+ += skip_bytes;
+ return (skip_bytes);
+ }
+
+ while (bytes) {
+ skipped_bytes = read_stream(a, &p, bytes, 0);
+ if (skipped_bytes < 0)
+ return (skipped_bytes);
+ if (skipped_bytes == 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated 7-Zip file body");
+ return (ARCHIVE_FATAL);
+ }
+ bytes -= skipped_bytes;
+ if (zip->pack_stream_bytes_unconsumed)
+ read_consume(a);
+ }
+ return (skip_bytes);
+}
+
+/*
+ * Brought from LZMA SDK.
+ *
+ * Bra86.c -- Converter for x86 code (BCJ)
+ * 2008-10-04 : Igor Pavlov : Public domain
+ *
+ */
+
+#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF)
+
+static void
+x86_Init(struct _7zip *zip)
+{
+ zip->bcj_state = 0;
+ zip->bcj_prevPosT = (size_t)0 - 1;
+ zip->bcj_prevMask = 0;
+ zip->bcj_ip = 5;
+}
+
+static size_t
+x86_Convert(struct _7zip *zip, uint8_t *data, size_t size)
+{
+ static const uint8_t kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0};
+ static const uint8_t kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3};
+ size_t bufferPos, prevPosT;
+ uint32_t ip, prevMask;
+
+ if (size < 5)
+ return 0;
+
+ bufferPos = 0;
+ prevPosT = zip->bcj_prevPosT;
+ prevMask = zip->bcj_prevMask;
+ ip = zip->bcj_ip;
+
+ for (;;) {
+ uint8_t *p = data + bufferPos;
+ uint8_t *limit = data + size - 4;
+
+ for (; p < limit; p++)
+ if ((*p & 0xFE) == 0xE8)
+ break;
+ bufferPos = (size_t)(p - data);
+ if (p >= limit)
+ break;
+ prevPosT = bufferPos - prevPosT;
+ if (prevPosT > 3)
+ prevMask = 0;
+ else {
+ prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7;
+ if (prevMask != 0) {
+ unsigned char b =
+ p[4 - kMaskToBitNumber[prevMask]];
+ if (!kMaskToAllowedStatus[prevMask] ||
+ Test86MSByte(b)) {
+ prevPosT = bufferPos;
+ prevMask = ((prevMask << 1) & 0x7) | 1;
+ bufferPos++;
+ continue;
+ }
+ }
+ }
+ prevPosT = bufferPos;
+
+ if (Test86MSByte(p[4])) {
+ uint32_t src = ((uint32_t)p[4] << 24) |
+ ((uint32_t)p[3] << 16) | ((uint32_t)p[2] << 8) |
+ ((uint32_t)p[1]);
+ uint32_t dest;
+ for (;;) {
+ uint8_t b;
+ int index;
+
+ dest = src - (ip + (uint32_t)bufferPos);
+ if (prevMask == 0)
+ break;
+ index = kMaskToBitNumber[prevMask] * 8;
+ b = (uint8_t)(dest >> (24 - index));
+ if (!Test86MSByte(b))
+ break;
+ src = dest ^ ((1 << (32 - index)) - 1);
+ }
+ p[4] = (uint8_t)(~(((dest >> 24) & 1) - 1));
+ p[3] = (uint8_t)(dest >> 16);
+ p[2] = (uint8_t)(dest >> 8);
+ p[1] = (uint8_t)dest;
+ bufferPos += 5;
+ } else {
+ prevMask = ((prevMask << 1) & 0x7) | 1;
+ bufferPos++;
+ }
+ }
+ zip->bcj_prevPosT = prevPosT;
+ zip->bcj_prevMask = prevMask;
+ zip->bcj_ip += bufferPos;
+ return (bufferPos);
+}
+
+/*
+ * Brought from LZMA SDK.
+ *
+ * Bcj2.c -- Converter for x86 code (BCJ2)
+ * 2008-10-04 : Igor Pavlov : Public domain
+ *
+ */
+
+#define SZ_ERROR_DATA ARCHIVE_FAILED
+
+#define IsJcc(b0, b1) ((b0) == 0x0F && ((b1) & 0xF0) == 0x80)
+#define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1))
+
+#define kNumTopBits 24
+#define kTopValue ((uint32_t)1 << kNumTopBits)
+
+#define kNumBitModelTotalBits 11
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kNumMoveBits 5
+
+#define RC_READ_BYTE (*buffer++)
+#define RC_TEST { if (buffer == bufferLim) return SZ_ERROR_DATA; }
+#define RC_INIT2 zip->bcj2_code = 0; zip->bcj2_range = 0xFFFFFFFF; \
+ { int i; for (i = 0; i < 5; i++) { RC_TEST; zip->bcj2_code = (zip->bcj2_code << 8) | RC_READ_BYTE; }}
+
+#define NORMALIZE if (zip->bcj2_range < kTopValue) { RC_TEST; zip->bcj2_range <<= 8; zip->bcj2_code = (zip->bcj2_code << 8) | RC_READ_BYTE; }
+
+#define IF_BIT_0(p) ttt = *(p); bound = (zip->bcj2_range >> kNumBitModelTotalBits) * ttt; if (zip->bcj2_code < bound)
+#define UPDATE_0(p) zip->bcj2_range = bound; *(p) = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); NORMALIZE;
+#define UPDATE_1(p) zip->bcj2_range -= bound; zip->bcj2_code -= bound; *(p) = (CProb)(ttt - (ttt >> kNumMoveBits)); NORMALIZE;
+
+static ssize_t
+Bcj2_Decode(struct _7zip *zip, uint8_t *outBuf, size_t outSize)
+{
+ size_t inPos = 0, outPos = 0;
+ const uint8_t *buf0, *buf1, *buf2, *buf3;
+ size_t size0, size1, size2, size3;
+ const uint8_t *buffer, *bufferLim;
+ unsigned int i, j;
+
+ size0 = zip->tmp_stream_bytes_remaining;
+ buf0 = zip->tmp_stream_buff + zip->tmp_stream_bytes_avail - size0;
+ size1 = zip->sub_stream_bytes_remaining[0];
+ buf1 = zip->sub_stream_buff[0] + zip->sub_stream_size[0] - size1;
+ size2 = zip->sub_stream_bytes_remaining[1];
+ buf2 = zip->sub_stream_buff[1] + zip->sub_stream_size[1] - size2;
+ size3 = zip->sub_stream_bytes_remaining[2];
+ buf3 = zip->sub_stream_buff[2] + zip->sub_stream_size[2] - size3;
+
+ buffer = buf3;
+ bufferLim = buffer + size3;
+
+ if (zip->bcj_state == 0) {
+ /*
+ * Initialize.
+ */
+ zip->bcj2_prevByte = 0;
+ for (i = 0;
+ i < sizeof(zip->bcj2_p) / sizeof(zip->bcj2_p[0]); i++)
+ zip->bcj2_p[i] = kBitModelTotal >> 1;
+ RC_INIT2;
+ zip->bcj_state = 1;
+ }
+
+ /*
+ * Gather the odd bytes of a previous call.
+ */
+ for (i = 0; zip->odd_bcj_size > 0 && outPos < outSize; i++) {
+ outBuf[outPos++] = zip->odd_bcj[i];
+ zip->odd_bcj_size--;
+ }
+
+ if (outSize == 0) {
+ zip->bcj2_outPos += outPos;
+ return (outPos);
+ }
+
+ for (;;) {
+ uint8_t b;
+ CProb *prob;
+ uint32_t bound;
+ uint32_t ttt;
+
+ size_t limit = size0 - inPos;
+ if (outSize - outPos < limit)
+ limit = outSize - outPos;
+
+ if (zip->bcj_state == 1) {
+ while (limit != 0) {
+ uint8_t b = buf0[inPos];
+ outBuf[outPos++] = b;
+ if (IsJ(zip->bcj2_prevByte, b)) {
+ zip->bcj_state = 2;
+ break;
+ }
+ inPos++;
+ zip->bcj2_prevByte = b;
+ limit--;
+ }
+ }
+
+ if (limit == 0 || outPos == outSize)
+ break;
+ zip->bcj_state = 1;
+
+ b = buf0[inPos++];
+
+ if (b == 0xE8)
+ prob = zip->bcj2_p + zip->bcj2_prevByte;
+ else if (b == 0xE9)
+ prob = zip->bcj2_p + 256;
+ else
+ prob = zip->bcj2_p + 257;
+
+ IF_BIT_0(prob) {
+ UPDATE_0(prob)
+ zip->bcj2_prevByte = b;
+ } else {
+ uint32_t dest;
+ const uint8_t *v;
+ uint8_t out[4];
+
+ UPDATE_1(prob)
+ if (b == 0xE8) {
+ v = buf1;
+ if (size1 < 4)
+ return SZ_ERROR_DATA;
+ buf1 += 4;
+ size1 -= 4;
+ } else {
+ v = buf2;
+ if (size2 < 4)
+ return SZ_ERROR_DATA;
+ buf2 += 4;
+ size2 -= 4;
+ }
+ dest = (((uint32_t)v[0] << 24) |
+ ((uint32_t)v[1] << 16) |
+ ((uint32_t)v[2] << 8) |
+ ((uint32_t)v[3])) -
+ ((uint32_t)zip->bcj2_outPos + outPos + 4);
+ out[0] = (uint8_t)dest;
+ out[1] = (uint8_t)(dest >> 8);
+ out[2] = (uint8_t)(dest >> 16);
+ out[3] = zip->bcj2_prevByte = (uint8_t)(dest >> 24);
+
+ for (i = 0; i < 4 && outPos < outSize; i++)
+ outBuf[outPos++] = out[i];
+ if (i < 4) {
+ /*
+ * Save odd bytes which we could not add into
+ * the output buffer because of out of space.
+ */
+ zip->odd_bcj_size = 4 -i;
+ for (; i < 4; i++) {
+ j = i - 4 + zip->odd_bcj_size;
+ zip->odd_bcj[j] = out[i];
+ }
+ break;
+ }
+ }
+ }
+ zip->tmp_stream_bytes_remaining -= inPos;
+ zip->sub_stream_bytes_remaining[0] = size1;
+ zip->sub_stream_bytes_remaining[1] = size2;
+ zip->sub_stream_bytes_remaining[2] = bufferLim - buffer;
+ zip->bcj2_outPos += outPos;
+
+ return ((ssize_t)outPos);
+}
+
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_all.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_all.c
new file mode 100644
index 000000000..53fe6fa39
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_all.c
@@ -0,0 +1,87 @@
+/*-
+ * Copyright (c) 2003-2011 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: head/lib/libarchive/archive_read_support_format_all.c 174991 2007-12-30 04:58:22Z kientzle $");
+
+#include "archive.h"
+#include "archive_private.h"
+
+int
+archive_read_support_format_all(struct archive *a)
+{
+ archive_check_magic(a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_all");
+
+ /* TODO: It would be nice to compute the ordering
+ * here automatically so that people who enable just
+ * a few formats can still get the benefits. That
+ * may just require the format registration to include
+ * a "maximum read-ahead" value (anything that uses seek
+ * would be essentially infinite read-ahead). The core
+ * bid management can then sort the bidders before calling
+ * them.
+ *
+ * If you implement the above, please return the list below
+ * to alphabetic order.
+ */
+
+ /*
+ * These bidders are all pretty cheap; they just examine a
+ * small initial part of the archive. If one of these bids
+ * high, we can maybe avoid running any of the more expensive
+ * bidders below.
+ */
+ archive_read_support_format_ar(a);
+ archive_read_support_format_cpio(a);
+ archive_read_support_format_empty(a);
+ archive_read_support_format_lha(a);
+ archive_read_support_format_mtree(a);
+ archive_read_support_format_tar(a);
+ archive_read_support_format_xar(a);
+
+ /*
+ * Install expensive bidders last. By doing them last, we
+ * increase the chance that a high bid from someone else will
+ * make it unnecessary for these to do anything at all.
+ */
+ /* These three have potentially large look-ahead. */
+ archive_read_support_format_7zip(a);
+ archive_read_support_format_cab(a);
+ archive_read_support_format_rar(a);
+ archive_read_support_format_iso9660(a);
+ /* Seek is really bad, since it forces the read-ahead
+ * logic to discard buffered data. */
+ archive_read_support_format_zip(a);
+
+ /* Note: We always return ARCHIVE_OK here, even if some of the
+ * above return ARCHIVE_WARN. The intent here is to enable
+ * "as much as possible." Clients who need specific
+ * compression should enable those individually so they can
+ * verify the level of support. */
+ /* Clear any warning messages set by the above functions. */
+ archive_clear_error(a);
+ return (ARCHIVE_OK);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_ar.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_ar.c
new file mode 100644
index 000000000..9feb547db
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_ar.c
@@ -0,0 +1,625 @@
+/*-
+ * Copyright (c) 2007 Kai Wang
+ * Copyright (c) 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
+ * in this position and unchanged.
+ * 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_read_support_format_ar.c 201101 2009-12-28 03:06:27Z kientzle $");
+
+#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
+
+#include "archive.h"
+#include "archive_entry.h"
+#include "archive_private.h"
+#include "archive_read_private.h"
+
+struct ar {
+ int64_t entry_bytes_remaining;
+ /* unconsumed is purely to track data we've gotten from readahead,
+ * but haven't yet marked as consumed. Must be paired with
+ * entry_bytes_remaining usage/modification.
+ */
+ size_t entry_bytes_unconsumed;
+ int64_t entry_offset;
+ int64_t entry_padding;
+ char *strtab;
+ size_t strtab_size;
+ char read_global_header;
+};
+
+/*
+ * Define structure of the "ar" header.
+ */
+#define AR_name_offset 0
+#define AR_name_size 16
+#define AR_date_offset 16
+#define AR_date_size 12
+#define AR_uid_offset 28
+#define AR_uid_size 6
+#define AR_gid_offset 34
+#define AR_gid_size 6
+#define AR_mode_offset 40
+#define AR_mode_size 8
+#define AR_size_offset 48
+#define AR_size_size 10
+#define AR_fmag_offset 58
+#define AR_fmag_size 2
+
+static int archive_read_format_ar_bid(struct archive_read *a, int);
+static int archive_read_format_ar_cleanup(struct archive_read *a);
+static int archive_read_format_ar_read_data(struct archive_read *a,
+ const void **buff, size_t *size, int64_t *offset);
+static int archive_read_format_ar_skip(struct archive_read *a);
+static int archive_read_format_ar_read_header(struct archive_read *a,
+ struct archive_entry *e);
+static uint64_t ar_atol8(const char *p, unsigned char_cnt);
+static uint64_t ar_atol10(const char *p, unsigned char_cnt);
+static int ar_parse_gnu_filename_table(struct archive_read *a);
+static int ar_parse_common_header(struct ar *ar, struct archive_entry *,
+ const char *h);
+
+int
+archive_read_support_format_ar(struct archive *_a)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ struct ar *ar;
+ int r;
+
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_ar");
+
+ ar = (struct ar *)malloc(sizeof(*ar));
+ if (ar == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate ar data");
+ return (ARCHIVE_FATAL);
+ }
+ memset(ar, 0, sizeof(*ar));
+ ar->strtab = NULL;
+
+ r = __archive_read_register_format(a,
+ ar,
+ "ar",
+ archive_read_format_ar_bid,
+ NULL,
+ archive_read_format_ar_read_header,
+ archive_read_format_ar_read_data,
+ archive_read_format_ar_skip,
+ archive_read_format_ar_cleanup);
+
+ if (r != ARCHIVE_OK) {
+ free(ar);
+ return (r);
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_read_format_ar_cleanup(struct archive_read *a)
+{
+ struct ar *ar;
+
+ ar = (struct ar *)(a->format->data);
+ if (ar->strtab)
+ free(ar->strtab);
+ free(ar);
+ (a->format->data) = NULL;
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_read_format_ar_bid(struct archive_read *a, int best_bid)
+{
+ const void *h;
+
+ (void)best_bid; /* UNUSED */
+
+ /*
+ * Verify the 8-byte file signature.
+ * TODO: Do we need to check more than this?
+ */
+ if ((h = __archive_read_ahead(a, 8, NULL)) == NULL)
+ return (-1);
+ if (memcmp(h, "!<arch>\n", 8) == 0) {
+ return (64);
+ }
+ return (-1);
+}
+
+static int
+_ar_read_header(struct archive_read *a, struct archive_entry *entry,
+ struct ar *ar, const char *h, size_t *unconsumed)
+{
+ char filename[AR_name_size + 1];
+ uint64_t number; /* Used to hold parsed numbers before validation. */
+ size_t bsd_name_length, entry_size;
+ char *p, *st;
+ const void *b;
+ int r;
+
+ /* Verify the magic signature on the file header. */
+ if (strncmp(h + AR_fmag_offset, "`\n", 2) != 0) {
+ archive_set_error(&a->archive, EINVAL,
+ "Incorrect file header signature");
+ return (ARCHIVE_WARN);
+ }
+
+ /* Copy filename into work buffer. */
+ strncpy(filename, h + AR_name_offset, AR_name_size);
+ filename[AR_name_size] = '\0';
+
+ /*
+ * Guess the format variant based on the filename.
+ */
+ if (a->archive.archive_format == ARCHIVE_FORMAT_AR) {
+ /* We don't already know the variant, so let's guess. */
+ /*
+ * Biggest clue is presence of '/': GNU starts special
+ * filenames with '/', appends '/' as terminator to
+ * non-special names, so anything with '/' should be
+ * GNU except for BSD long filenames.
+ */
+ if (strncmp(filename, "#1/", 3) == 0)
+ a->archive.archive_format = ARCHIVE_FORMAT_AR_BSD;
+ else if (strchr(filename, '/') != NULL)
+ a->archive.archive_format = ARCHIVE_FORMAT_AR_GNU;
+ else if (strncmp(filename, "__.SYMDEF", 9) == 0)
+ a->archive.archive_format = ARCHIVE_FORMAT_AR_BSD;
+ /*
+ * XXX Do GNU/SVR4 'ar' programs ever omit trailing '/'
+ * if name exactly fills 16-byte field? If so, we
+ * can't assume entries without '/' are BSD. XXX
+ */
+ }
+
+ /* Update format name from the code. */
+ if (a->archive.archive_format == ARCHIVE_FORMAT_AR_GNU)
+ a->archive.archive_format_name = "ar (GNU/SVR4)";
+ else if (a->archive.archive_format == ARCHIVE_FORMAT_AR_BSD)
+ a->archive.archive_format_name = "ar (BSD)";
+ else
+ a->archive.archive_format_name = "ar";
+
+ /*
+ * Remove trailing spaces from the filename. GNU and BSD
+ * variants both pad filename area out with spaces.
+ * This will only be wrong if GNU/SVR4 'ar' implementations
+ * omit trailing '/' for 16-char filenames and we have
+ * a 16-char filename that ends in ' '.
+ */
+ p = filename + AR_name_size - 1;
+ while (p >= filename && *p == ' ') {
+ *p = '\0';
+ p--;
+ }
+
+ /*
+ * Remove trailing slash unless first character is '/'.
+ * (BSD entries never end in '/', so this will only trim
+ * GNU-format entries. GNU special entries start with '/'
+ * and are not terminated in '/', so we don't trim anything
+ * that starts with '/'.)
+ */
+ if (filename[0] != '/' && *p == '/')
+ *p = '\0';
+
+ /*
+ * '//' is the GNU filename table.
+ * Later entries can refer to names in this table.
+ */
+ if (strcmp(filename, "//") == 0) {
+ /* This must come before any call to _read_ahead. */
+ ar_parse_common_header(ar, entry, h);
+ archive_entry_copy_pathname(entry, filename);
+ archive_entry_set_filetype(entry, AE_IFREG);
+ /* Get the size of the filename table. */
+ number = ar_atol10(h + AR_size_offset, AR_size_size);
+ if (number > SIZE_MAX) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Filename table too large");
+ return (ARCHIVE_FATAL);
+ }
+ entry_size = (size_t)number;
+ if (entry_size == 0) {
+ archive_set_error(&a->archive, EINVAL,
+ "Invalid string table");
+ return (ARCHIVE_WARN);
+ }
+ if (ar->strtab != NULL) {
+ archive_set_error(&a->archive, EINVAL,
+ "More than one string tables exist");
+ return (ARCHIVE_WARN);
+ }
+
+ /* Read the filename table into memory. */
+ st = malloc(entry_size);
+ if (st == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate filename table buffer");
+ return (ARCHIVE_FATAL);
+ }
+ ar->strtab = st;
+ ar->strtab_size = entry_size;
+
+ if (*unconsumed) {
+ __archive_read_consume(a, *unconsumed);
+ *unconsumed = 0;
+ }
+
+ if ((b = __archive_read_ahead(a, entry_size, NULL)) == NULL)
+ return (ARCHIVE_FATAL);
+ memcpy(st, b, entry_size);
+ __archive_read_consume(a, entry_size);
+ /* All contents are consumed. */
+ ar->entry_bytes_remaining = 0;
+ archive_entry_set_size(entry, ar->entry_bytes_remaining);
+
+ /* Parse the filename table. */
+ return (ar_parse_gnu_filename_table(a));
+ }
+
+ /*
+ * GNU variant handles long filenames by storing /<number>
+ * to indicate a name stored in the filename table.
+ * XXX TODO: Verify that it's all digits... Don't be fooled
+ * by "/9xyz" XXX
+ */
+ if (filename[0] == '/' && filename[1] >= '0' && filename[1] <= '9') {
+ number = ar_atol10(h + AR_name_offset + 1, AR_name_size - 1);
+ /*
+ * If we can't look up the real name, warn and return
+ * the entry with the wrong name.
+ */
+ if (ar->strtab == NULL || number > ar->strtab_size) {
+ archive_set_error(&a->archive, EINVAL,
+ "Can't find long filename for entry");
+ archive_entry_copy_pathname(entry, filename);
+ /* Parse the time, owner, mode, size fields. */
+ ar_parse_common_header(ar, entry, h);
+ return (ARCHIVE_WARN);
+ }
+
+ archive_entry_copy_pathname(entry, &ar->strtab[(size_t)number]);
+ /* Parse the time, owner, mode, size fields. */
+ return (ar_parse_common_header(ar, entry, h));
+ }
+
+ /*
+ * BSD handles long filenames by storing "#1/" followed by the
+ * length of filename as a decimal number, then prepends the
+ * the filename to the file contents.
+ */
+ if (strncmp(filename, "#1/", 3) == 0) {
+ /* Parse the time, owner, mode, size fields. */
+ /* This must occur before _read_ahead is called again. */
+ ar_parse_common_header(ar, entry, h);
+
+ /* Parse the size of the name, adjust the file size. */
+ number = ar_atol10(h + AR_name_offset + 3, AR_name_size - 3);
+ bsd_name_length = (size_t)number;
+ /* Guard against the filename + trailing NUL
+ * overflowing a size_t and against the filename size
+ * being larger than the entire entry. */
+ if (number > (uint64_t)(bsd_name_length + 1)
+ || (int64_t)bsd_name_length > ar->entry_bytes_remaining) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Bad input file size");
+ return (ARCHIVE_FATAL);
+ }
+ ar->entry_bytes_remaining -= bsd_name_length;
+ /* Adjust file size reported to client. */
+ archive_entry_set_size(entry, ar->entry_bytes_remaining);
+
+ if (*unconsumed) {
+ __archive_read_consume(a, *unconsumed);
+ *unconsumed = 0;
+ }
+
+ /* Read the long name into memory. */
+ if ((b = __archive_read_ahead(a, bsd_name_length, NULL)) == NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Truncated input file");
+ return (ARCHIVE_FATAL);
+ }
+ /* Store it in the entry. */
+ p = (char *)malloc(bsd_name_length + 1);
+ if (p == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate fname buffer");
+ return (ARCHIVE_FATAL);
+ }
+ strncpy(p, b, bsd_name_length);
+ p[bsd_name_length] = '\0';
+
+ __archive_read_consume(a, bsd_name_length);
+
+ archive_entry_copy_pathname(entry, p);
+ free(p);
+ return (ARCHIVE_OK);
+ }
+
+ /*
+ * "/" is the SVR4/GNU archive symbol table.
+ */
+ if (strcmp(filename, "/") == 0) {
+ archive_entry_copy_pathname(entry, "/");
+ /* Parse the time, owner, mode, size fields. */
+ r = ar_parse_common_header(ar, entry, h);
+ /* Force the file type to a regular file. */
+ archive_entry_set_filetype(entry, AE_IFREG);
+ return (r);
+ }
+
+ /*
+ * "__.SYMDEF" is a BSD archive symbol table.
+ */
+ if (strcmp(filename, "__.SYMDEF") == 0) {
+ archive_entry_copy_pathname(entry, filename);
+ /* Parse the time, owner, mode, size fields. */
+ return (ar_parse_common_header(ar, entry, h));
+ }
+
+ /*
+ * Otherwise, this is a standard entry. The filename
+ * has already been trimmed as much as possible, based
+ * on our current knowledge of the format.
+ */
+ archive_entry_copy_pathname(entry, filename);
+ return (ar_parse_common_header(ar, entry, h));
+}
+
+static int
+archive_read_format_ar_read_header(struct archive_read *a,
+ struct archive_entry *entry)
+{
+ struct ar *ar = (struct ar*)(a->format->data);
+ size_t unconsumed;
+ const void *header_data;
+ int ret;
+
+ if (!ar->read_global_header) {
+ /*
+ * We are now at the beginning of the archive,
+ * so we need first consume the ar global header.
+ */
+ __archive_read_consume(a, 8);
+ ar->read_global_header = 1;
+ /* Set a default format code for now. */
+ a->archive.archive_format = ARCHIVE_FORMAT_AR;
+ }
+
+ /* Read the header for the next file entry. */
+ if ((header_data = __archive_read_ahead(a, 60, NULL)) == NULL)
+ /* Broken header. */
+ return (ARCHIVE_EOF);
+
+ unconsumed = 60;
+
+ ret = _ar_read_header(a, entry, ar, (const char *)header_data, &unconsumed);
+
+ if (unconsumed)
+ __archive_read_consume(a, unconsumed);
+
+ return ret;
+}
+
+
+static int
+ar_parse_common_header(struct ar *ar, struct archive_entry *entry,
+ const char *h)
+{
+ uint64_t n;
+
+ /* Copy remaining header */
+ archive_entry_set_mtime(entry,
+ (time_t)ar_atol10(h + AR_date_offset, AR_date_size), 0L);
+ archive_entry_set_uid(entry,
+ (uid_t)ar_atol10(h + AR_uid_offset, AR_uid_size));
+ archive_entry_set_gid(entry,
+ (gid_t)ar_atol10(h + AR_gid_offset, AR_gid_size));
+ archive_entry_set_mode(entry,
+ (mode_t)ar_atol8(h + AR_mode_offset, AR_mode_size));
+ n = ar_atol10(h + AR_size_offset, AR_size_size);
+
+ ar->entry_offset = 0;
+ ar->entry_padding = n % 2;
+ archive_entry_set_size(entry, n);
+ ar->entry_bytes_remaining = n;
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_read_format_ar_read_data(struct archive_read *a,
+ const void **buff, size_t *size, int64_t *offset)
+{
+ ssize_t bytes_read;
+ struct ar *ar;
+
+ ar = (struct ar *)(a->format->data);
+
+ if (ar->entry_bytes_unconsumed) {
+ __archive_read_consume(a, ar->entry_bytes_unconsumed);
+ ar->entry_bytes_unconsumed = 0;
+ }
+
+ if (ar->entry_bytes_remaining > 0) {
+ *buff = __archive_read_ahead(a, 1, &bytes_read);
+ if (bytes_read == 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Truncated ar archive");
+ return (ARCHIVE_FATAL);
+ }
+ if (bytes_read < 0)
+ return (ARCHIVE_FATAL);
+ if (bytes_read > ar->entry_bytes_remaining)
+ bytes_read = (ssize_t)ar->entry_bytes_remaining;
+ *size = bytes_read;
+ ar->entry_bytes_unconsumed = bytes_read;
+ *offset = ar->entry_offset;
+ ar->entry_offset += bytes_read;
+ ar->entry_bytes_remaining -= bytes_read;
+ return (ARCHIVE_OK);
+ } else {
+ int64_t skipped = __archive_read_consume(a, ar->entry_padding);
+ if (skipped >= 0) {
+ ar->entry_padding -= skipped;
+ }
+ if (ar->entry_padding) {
+ if (skipped >= 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Truncated ar archive- failed consuming padding");
+ }
+ return (ARCHIVE_FATAL);
+ }
+ *buff = NULL;
+ *size = 0;
+ *offset = ar->entry_offset;
+ return (ARCHIVE_EOF);
+ }
+}
+
+static int
+archive_read_format_ar_skip(struct archive_read *a)
+{
+ int64_t bytes_skipped;
+ struct ar* ar;
+
+ ar = (struct ar *)(a->format->data);
+
+ bytes_skipped = __archive_read_consume(a,
+ ar->entry_bytes_remaining + ar->entry_padding
+ + ar->entry_bytes_unconsumed);
+ if (bytes_skipped < 0)
+ return (ARCHIVE_FATAL);
+
+ ar->entry_bytes_remaining = 0;
+ ar->entry_bytes_unconsumed = 0;
+ ar->entry_padding = 0;
+
+ return (ARCHIVE_OK);
+}
+
+static int
+ar_parse_gnu_filename_table(struct archive_read *a)
+{
+ struct ar *ar;
+ char *p;
+ size_t size;
+
+ ar = (struct ar*)(a->format->data);
+ size = ar->strtab_size;
+
+ for (p = ar->strtab; p < ar->strtab + size - 1; ++p) {
+ if (*p == '/') {
+ *p++ = '\0';
+ if (*p != '\n')
+ goto bad_string_table;
+ *p = '\0';
+ }
+ }
+ /*
+ * GNU ar always pads the table to an even size.
+ * The pad character is either '\n' or '`'.
+ */
+ if (p != ar->strtab + size && *p != '\n' && *p != '`')
+ goto bad_string_table;
+
+ /* Enforce zero termination. */
+ ar->strtab[size - 1] = '\0';
+
+ return (ARCHIVE_OK);
+
+bad_string_table:
+ archive_set_error(&a->archive, EINVAL,
+ "Invalid string table");
+ free(ar->strtab);
+ ar->strtab = NULL;
+ return (ARCHIVE_WARN);
+}
+
+static uint64_t
+ar_atol8(const char *p, unsigned char_cnt)
+{
+ uint64_t l, limit, last_digit_limit;
+ unsigned int digit, base;
+
+ base = 8;
+ limit = UINT64_MAX / base;
+ last_digit_limit = UINT64_MAX % base;
+
+ while ((*p == ' ' || *p == '\t') && char_cnt-- > 0)
+ p++;
+
+ l = 0;
+ digit = *p - '0';
+ while (*p >= '0' && digit < base && char_cnt-- > 0) {
+ if (l>limit || (l == limit && digit > last_digit_limit)) {
+ l = UINT64_MAX; /* Truncate on overflow. */
+ break;
+ }
+ l = (l * base) + digit;
+ digit = *++p - '0';
+ }
+ return (l);
+}
+
+static uint64_t
+ar_atol10(const char *p, unsigned char_cnt)
+{
+ uint64_t l, limit, last_digit_limit;
+ unsigned int base, digit;
+
+ base = 10;
+ limit = UINT64_MAX / base;
+ last_digit_limit = UINT64_MAX % base;
+
+ while ((*p == ' ' || *p == '\t') && char_cnt-- > 0)
+ p++;
+ l = 0;
+ digit = *p - '0';
+ while (*p >= '0' && digit < base && char_cnt-- > 0) {
+ if (l > limit || (l == limit && digit > last_digit_limit)) {
+ l = UINT64_MAX; /* Truncate on overflow. */
+ break;
+ }
+ l = (l * base) + digit;
+ digit = *++p - '0';
+ }
+ return (l);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_by_code.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_by_code.c
new file mode 100644
index 000000000..084563f43
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_by_code.c
@@ -0,0 +1,74 @@
+/*-
+ * Copyright (c) 2003-2011 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$");
+
+#include "archive.h"
+#include "archive_private.h"
+
+int
+archive_read_support_format_by_code(struct archive *a, int format_code)
+{
+ archive_check_magic(a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_by_code");
+
+ switch (format_code & ARCHIVE_FORMAT_BASE_MASK) {
+ case ARCHIVE_FORMAT_7ZIP:
+ return archive_read_support_format_7zip(a);
+ break;
+ case ARCHIVE_FORMAT_AR:
+ return archive_read_support_format_ar(a);
+ break;
+ case ARCHIVE_FORMAT_CAB:
+ return archive_read_support_format_cab(a);
+ break;
+ case ARCHIVE_FORMAT_CPIO:
+ return archive_read_support_format_cpio(a);
+ break;
+ case ARCHIVE_FORMAT_ISO9660:
+ return archive_read_support_format_iso9660(a);
+ break;
+ case ARCHIVE_FORMAT_LHA:
+ return archive_read_support_format_lha(a);
+ break;
+ case ARCHIVE_FORMAT_MTREE:
+ return archive_read_support_format_mtree(a);
+ break;
+ case ARCHIVE_FORMAT_RAR:
+ return archive_read_support_format_rar(a);
+ break;
+ case ARCHIVE_FORMAT_TAR:
+ return archive_read_support_format_tar(a);
+ break;
+ case ARCHIVE_FORMAT_XAR:
+ return archive_read_support_format_xar(a);
+ break;
+ case ARCHIVE_FORMAT_ZIP:
+ return archive_read_support_format_zip(a);
+ break;
+ }
+ return (ARCHIVE_FATAL);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c
new file mode 100644
index 000000000..e65010e10
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c
@@ -0,0 +1,3315 @@
+/*-
+ * Copyright (c) 2010-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"
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_ZLIB_H
+#include <cm_zlib.h>
+#endif
+
+#include "archive.h"
+#include "archive_entry.h"
+#include "archive_entry_locale.h"
+#include "archive_private.h"
+#include "archive_read_private.h"
+#include "archive_endian.h"
+
+
+struct lzx_dec {
+ /* Decoding status. */
+ int state;
+
+ /*
+ * Window to see last decoded data, from 32KBi to 2MBi.
+ */
+ int w_size;
+ int w_mask;
+ /* Window buffer, which is a loop buffer. */
+ unsigned char *w_buff;
+ /* The insert position to the window. */
+ int w_pos;
+ /* The position where we can copy decoded code from the window. */
+ int copy_pos;
+ /* The length how many bytes we can copy decoded code from
+ * the window. */
+ int copy_len;
+ /* Translation reversal for x86 proccessor CALL byte sequence(E8).
+ * This is used for LZX only. */
+ uint32_t translation_size;
+ char translation;
+ char block_type;
+#define VERBATIM_BLOCK 1
+#define ALIGNED_OFFSET_BLOCK 2
+#define UNCOMPRESSED_BLOCK 3
+ size_t block_size;
+ size_t block_bytes_avail;
+ /* Repeated offset. */
+ int r0, r1, r2;
+ unsigned char rbytes[4];
+ int rbytes_avail;
+ int length_header;
+ int position_slot;
+ int offset_bits;
+
+ struct lzx_pos_tbl {
+ int base;
+ int footer_bits;
+ } *pos_tbl;
+ /*
+ * Bit stream reader.
+ */
+ struct lzx_br {
+#define CACHE_TYPE uint64_t
+#define CACHE_BITS (8 * sizeof(CACHE_TYPE))
+ /* Cache buffer. */
+ CACHE_TYPE cache_buffer;
+ /* Indicates how many bits avail in cache_buffer. */
+ int cache_avail;
+ unsigned char odd;
+ char have_odd;
+ } br;
+
+ /*
+ * Huffman coding.
+ */
+ struct huffman {
+ int len_size;
+ int freq[17];
+ unsigned char *bitlen;
+
+ /*
+ * Use a index table. It's faster than searching a huffman
+ * coding tree, which is a binary tree. But a use of a large
+ * index table causes L1 cache read miss many times.
+ */
+#define HTBL_BITS 10
+ int max_bits;
+ int shift_bits;
+ int tbl_bits;
+ int tree_used;
+ int tree_avail;
+ /* Direct access table. */
+ uint16_t *tbl;
+ /* Binary tree table for extra bits over the direct access. */
+ struct htree_t {
+ uint16_t left;
+ uint16_t right;
+ } *tree;
+ } at, lt, mt, pt;
+
+ int loop;
+ int error;
+};
+
+static const int slots[] = {
+ 30, 32, 34, 36, 38, 42, 50, 66, 98, 162, 290
+};
+#define SLOT_BASE 15
+#define SLOT_MAX 21/*->25*/
+
+struct lzx_stream {
+ const unsigned char *next_in;
+ int64_t avail_in;
+ int64_t total_in;
+ unsigned char *next_out;
+ int64_t avail_out;
+ int64_t total_out;
+ struct lzx_dec *ds;
+};
+
+/*
+ * Cabinet file definitions.
+ */
+/* CFHEADER offset */
+#define CFHEADER_signature 0
+#define CFHEADER_cbCabinet 8
+#define CFHEADER_coffFiles 16
+#define CFHEADER_versionMinor 24
+#define CFHEADER_versionMajor 25
+#define CFHEADER_cFolders 26
+#define CFHEADER_cFiles 28
+#define CFHEADER_flags 30
+#define CFHEADER_setID 32
+#define CFHEADER_iCabinet 34
+#define CFHEADER_cbCFHeader 36
+#define CFHEADER_cbCFFolder 38
+#define CFHEADER_cbCFData 39
+
+/* CFFOLDER offset */
+#define CFFOLDER_coffCabStart 0
+#define CFFOLDER_cCFData 4
+#define CFFOLDER_typeCompress 6
+#define CFFOLDER_abReserve 8
+
+/* CFFILE offset */
+#define CFFILE_cbFile 0
+#define CFFILE_uoffFolderStart 4
+#define CFFILE_iFolder 8
+#define CFFILE_date_time 10
+#define CFFILE_attribs 14
+
+/* CFDATA offset */
+#define CFDATA_csum 0
+#define CFDATA_cbData 4
+#define CFDATA_cbUncomp 6
+
+static const char *compression_name[] = {
+ "NONE",
+ "MSZIP",
+ "Quantum",
+ "LZX",
+};
+
+struct cfdata {
+ /* Sum value of this CFDATA. */
+ uint32_t sum;
+ uint16_t compressed_size;
+ uint16_t compressed_bytes_remaining;
+ uint16_t uncompressed_size;
+ uint16_t uncompressed_bytes_remaining;
+ /* To know how many bytes we have decompressed. */
+ uint16_t uncompressed_avail;
+ /* Offset from the beginning of compressed data of this CFDATA */
+ uint16_t read_offset;
+ int64_t unconsumed;
+ /* To keep memory image of this CFDATA to compute the sum. */
+ size_t memimage_size;
+ unsigned char *memimage;
+ /* Result of calculation of sum. */
+ uint32_t sum_calculated;
+ unsigned char sum_extra[4];
+ int sum_extra_avail;
+ const void *sum_ptr;
+};
+
+struct cffolder {
+ uint32_t cfdata_offset_in_cab;
+ uint16_t cfdata_count;
+ uint16_t comptype;
+#define COMPTYPE_NONE 0x0000
+#define COMPTYPE_MSZIP 0x0001
+#define COMPTYPE_QUANTUM 0x0002
+#define COMPTYPE_LZX 0x0003
+ uint16_t compdata;
+ const char *compname;
+ /* At the time reading CFDATA */
+ struct cfdata cfdata;
+ int cfdata_index;
+ /* Flags to mark progress of decompression. */
+ char decompress_init;
+};
+
+struct cffile {
+ uint32_t uncompressed_size;
+ uint32_t offset;
+ time_t mtime;
+ uint16_t folder;
+#define iFoldCONTINUED_FROM_PREV 0xFFFD
+#define iFoldCONTINUED_TO_NEXT 0xFFFE
+#define iFoldCONTINUED_PREV_AND_NEXT 0xFFFF
+ unsigned char attr;
+#define ATTR_RDONLY 0x01
+#define ATTR_NAME_IS_UTF 0x80
+ struct archive_string pathname;
+};
+
+struct cfheader {
+ /* Total bytes of all file size in a Cabinet. */
+ uint32_t total_bytes;
+ uint32_t files_offset;
+ uint16_t folder_count;
+ uint16_t file_count;
+ uint16_t flags;
+#define PREV_CABINET 0x0001
+#define NEXT_CABINET 0x0002
+#define RESERVE_PRESENT 0x0004
+ uint16_t setid;
+ uint16_t cabinet;
+ /* Version number. */
+ unsigned char major;
+ unsigned char minor;
+ unsigned char cffolder;
+ unsigned char cfdata;
+ /* All folders in a cabinet. */
+ struct cffolder *folder_array;
+ /* All files in a cabinet. */
+ struct cffile *file_array;
+ int file_index;
+};
+
+struct cab {
+ /* entry_bytes_remaining is the number of bytes we expect. */
+ int64_t entry_offset;
+ int64_t entry_bytes_remaining;
+ int64_t entry_unconsumed;
+ int64_t entry_compressed_bytes_read;
+ int64_t entry_uncompressed_bytes_read;
+ struct cffolder *entry_cffolder;
+ struct cffile *entry_cffile;
+ struct cfdata *entry_cfdata;
+
+ /* Offset from beginning of a cabinet file. */
+ int64_t cab_offset;
+ struct cfheader cfheader;
+ struct archive_wstring ws;
+
+ /* Flag to mark progress that an archive was read their first header.*/
+ char found_header;
+ char end_of_archive;
+ char end_of_entry;
+ char end_of_entry_cleanup;
+
+ unsigned char *uncompressed_buffer;
+ size_t uncompressed_buffer_size;
+
+ int init_default_conversion;
+ struct archive_string_conv *sconv;
+ struct archive_string_conv *sconv_default;
+ struct archive_string_conv *sconv_utf8;
+ char format_name[64];
+
+#ifdef HAVE_ZLIB_H
+ z_stream stream;
+ char stream_valid;
+#endif
+ struct lzx_stream xstrm;
+};
+
+static int archive_read_format_cab_bid(struct archive_read *, int);
+static int archive_read_format_cab_options(struct archive_read *,
+ const char *, const char *);
+static int archive_read_format_cab_read_header(struct archive_read *,
+ struct archive_entry *);
+static int archive_read_format_cab_read_data(struct archive_read *,
+ const void **, size_t *, int64_t *);
+static int archive_read_format_cab_read_data_skip(struct archive_read *);
+static int archive_read_format_cab_cleanup(struct archive_read *);
+
+static int cab_skip_sfx(struct archive_read *);
+static time_t cab_dos_time(const unsigned char *);
+static int cab_read_data(struct archive_read *, const void **,
+ size_t *, int64_t *);
+static int cab_read_header(struct archive_read *);
+static uint32_t cab_checksum_cfdata_4(const void *, size_t bytes, uint32_t);
+static uint32_t cab_checksum_cfdata(const void *, size_t bytes, uint32_t);
+static void cab_checksum_update(struct archive_read *, size_t);
+static int cab_checksum_finish(struct archive_read *);
+static int cab_next_cfdata(struct archive_read *);
+static const void *cab_read_ahead_cfdata(struct archive_read *, ssize_t *);
+static const void *cab_read_ahead_cfdata_none(struct archive_read *, ssize_t *);
+static const void *cab_read_ahead_cfdata_deflate(struct archive_read *,
+ ssize_t *);
+static const void *cab_read_ahead_cfdata_lzx(struct archive_read *,
+ ssize_t *);
+static int64_t cab_consume_cfdata(struct archive_read *, int64_t);
+static int64_t cab_minimum_consume_cfdata(struct archive_read *, int64_t);
+static int lzx_decode_init(struct lzx_stream *, int);
+static int lzx_read_blocks(struct lzx_stream *, int);
+static int lzx_decode_blocks(struct lzx_stream *, int);
+static void lzx_decode_free(struct lzx_stream *);
+static void lzx_translation(struct lzx_stream *, void *, size_t, uint32_t);
+static void lzx_cleanup_bitstream(struct lzx_stream *);
+static int lzx_decode(struct lzx_stream *, int);
+static int lzx_read_pre_tree(struct lzx_stream *);
+static int lzx_read_bitlen(struct lzx_stream *, struct huffman *, int);
+static int lzx_huffman_init(struct huffman *, size_t, int);
+static void lzx_huffman_free(struct huffman *);
+static int lzx_make_huffman_table(struct huffman *);
+static int inline lzx_decode_huffman(struct huffman *, unsigned);
+static int lzx_decode_huffman_tree(struct huffman *, unsigned, int);
+
+
+int
+archive_read_support_format_cab(struct archive *_a)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ struct cab *cab;
+ int r;
+
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_cab");
+
+ cab = (struct cab *)calloc(1, sizeof(*cab));
+ if (cab == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate CAB data");
+ return (ARCHIVE_FATAL);
+ }
+ archive_string_init(&cab->ws);
+ archive_wstring_ensure(&cab->ws, 256);
+
+ r = __archive_read_register_format(a,
+ cab,
+ "cab",
+ archive_read_format_cab_bid,
+ archive_read_format_cab_options,
+ archive_read_format_cab_read_header,
+ archive_read_format_cab_read_data,
+ archive_read_format_cab_read_data_skip,
+ archive_read_format_cab_cleanup);
+
+ if (r != ARCHIVE_OK)
+ free(cab);
+ return (ARCHIVE_OK);
+}
+
+static int
+find_cab_magic(const char *p)
+{
+ switch (p[4]) {
+ case 0:
+ /*
+ * Note: Self-Extraction program has 'MSCF' string in their
+ * program. If we were finding 'MSCF' string only, we got
+ * wrong place for Cabinet header, thus, we have to check
+ * following four bytes which are reserved and must be set
+ * to zero.
+ */
+ if (memcmp(p, "MSCF\0\0\0\0", 8) == 0)
+ return 0;
+ return 5;
+ case 'F': return 1;
+ case 'C': return 2;
+ case 'S': return 3;
+ case 'M': return 4;
+ default: return 5;
+ }
+}
+
+static int
+archive_read_format_cab_bid(struct archive_read *a, int best_bid)
+{
+ const char *p;
+ ssize_t bytes_avail, offset, window;
+
+ /* If there's already a better bid than we can ever
+ make, don't bother testing. */
+ if (best_bid > 64)
+ return (-1);
+
+ if ((p = __archive_read_ahead(a, 8, NULL)) == NULL)
+ return (-1);
+
+ if (memcmp(p, "MSCF\0\0\0\0", 8) == 0)
+ return (64);
+
+ /*
+ * Attempt to handle self-extracting archives
+ * by noting a PE header and searching forward
+ * up to 128k for a 'MSCF' marker.
+ */
+ if (p[0] == 'M' && p[1] == 'Z') {
+ offset = 0;
+ window = 4096;
+ while (offset < (1024 * 128)) {
+ const char *h = __archive_read_ahead(a, offset + window,
+ &bytes_avail);
+ if (h == NULL) {
+ /* Remaining bytes are less than window. */
+ window >>= 1;
+ if (window < 128)
+ return (0);
+ continue;
+ }
+ p = h + offset;
+ while (p + 8 < h + bytes_avail) {
+ int next;
+ if ((next = find_cab_magic(p)) == 0)
+ return (64);
+ p += next;
+ }
+ offset = p - h;
+ }
+ }
+ return (0);
+}
+
+static int
+archive_read_format_cab_options(struct archive_read *a,
+ const char *key, const char *val)
+{
+ struct cab *cab;
+ int ret = ARCHIVE_FAILED;
+
+ cab = (struct cab *)(a->format->data);
+ if (strcmp(key, "hdrcharset") == 0) {
+ if (val == NULL || val[0] == 0)
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "cab: hdrcharset option needs a character-set name");
+ else {
+ cab->sconv = archive_string_conversion_from_charset(
+ &a->archive, val, 0);
+ if (cab->sconv != NULL)
+ ret = ARCHIVE_OK;
+ else
+ ret = ARCHIVE_FATAL;
+ }
+ } else
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "cab: unknown keyword ``%s''", key);
+
+ return (ret);
+}
+
+static int
+cab_skip_sfx(struct archive_read *a)
+{
+ const char *p, *q;
+ size_t skip;
+ ssize_t bytes, window;
+
+ window = 4096;
+ for (;;) {
+ const char *h = __archive_read_ahead(a, window, &bytes);
+ if (h == NULL) {
+ /* Remaining size are less than window. */
+ window >>= 1;
+ if (window < 128) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Couldn't find out CAB header");
+ return (ARCHIVE_FATAL);
+ }
+ continue;
+ }
+ p = h;
+ q = p + bytes;
+
+ /*
+ * Scan ahead until we find something that looks
+ * like the cab header.
+ */
+ while (p + 8 < q) {
+ int next;
+ if ((next = find_cab_magic(p)) == 0) {
+ skip = p - h;
+ __archive_read_consume(a, skip);
+ return (ARCHIVE_OK);
+ }
+ p += next;
+ }
+ skip = p - h;
+ __archive_read_consume(a, skip);
+ }
+}
+
+static int
+truncated_error(struct archive_read *a)
+{
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated CAB header");
+ return (ARCHIVE_FATAL);
+}
+
+static int
+cab_strnlen(const unsigned char *p, size_t maxlen)
+{
+ size_t i;
+
+ for (i = 0; i <= maxlen; i++) {
+ if (p[i] == 0)
+ break;
+ }
+ if (i > maxlen)
+ return (-1);/* invalid */
+ return (i);
+}
+
+/* Read bytes as much as remaining. */
+static const void *
+cab_read_ahead_remaining(struct archive_read *a, size_t min, ssize_t *avail)
+{
+ const void *p;
+
+ while (min > 0) {
+ p = __archive_read_ahead(a, min, avail);
+ if (p != NULL)
+ return (p);
+ min--;
+ }
+ return (NULL);
+}
+
+/* Convert a path separator '\' -> '/' */
+static int
+cab_convert_path_separator_1(struct archive_string *fn, unsigned char attr)
+{
+ size_t i;
+ int mb;
+
+ /* Easy check if we have '\' in multi-byte string. */
+ mb = 0;
+ for (i = 0; i < archive_strlen(fn); i++) {
+ if (fn->s[i] == '\\') {
+ if (mb) {
+ /* This may be second byte of multi-byte
+ * character. */
+ break;
+ }
+ fn->s[i] = '/';
+ mb = 0;
+ } else if ((fn->s[i] & 0x80) && !(attr & ATTR_NAME_IS_UTF))
+ mb = 1;
+ else
+ mb = 0;
+ }
+ if (i == archive_strlen(fn))
+ return (0);
+ return (-1);
+}
+
+/*
+ * Replace a character '\' with '/' in wide character.
+ */
+static void
+cab_convert_path_separator_2(struct cab *cab, struct archive_entry *entry)
+{
+ const wchar_t *wp;
+ size_t i;
+
+ /* If a conversion to wide character failed, force the replacement. */
+ if ((wp = archive_entry_pathname_w(entry)) != NULL) {
+ archive_wstrcpy(&(cab->ws), wp);
+ for (i = 0; i < archive_strlen(&(cab->ws)); i++) {
+ if (cab->ws.s[i] == L'\\')
+ cab->ws.s[i] = L'/';
+ }
+ archive_entry_copy_pathname_w(entry, cab->ws.s);
+ }
+}
+
+/*
+ * Read CFHEADER, CFFOLDER and CFFILE.
+ */
+static int
+cab_read_header(struct archive_read *a)
+{
+ const unsigned char *p;
+ struct cab *cab;
+ struct cfheader *hd;
+ size_t bytes, used;
+ int64_t skip;
+ int err, i, len;
+ int cur_folder, prev_folder;
+ uint32_t offset32;
+
+ a->archive.archive_format = ARCHIVE_FORMAT_CAB;
+ if (a->archive.archive_format_name == NULL)
+ a->archive.archive_format_name = "CAB";
+
+ if ((p = __archive_read_ahead(a, 42, NULL)) == NULL)
+ return (truncated_error(a));
+
+ cab = (struct cab *)(a->format->data);
+ if (cab->found_header == 0 &&
+ p[0] == 'M' && p[1] == 'Z') {
+ /* This is an executable? Must be self-extracting... */
+ err = cab_skip_sfx(a);
+ if (err < ARCHIVE_WARN)
+ return (err);
+
+ if ((p = __archive_read_ahead(a, sizeof(*p), NULL)) == NULL)
+ return (truncated_error(a));
+ }
+
+ cab->cab_offset = 0;
+ /*
+ * Read CFHEADER.
+ */
+ hd = &cab->cfheader;
+ if (p[CFHEADER_signature+0] != 'M' || p[CFHEADER_signature+1] != 'S' ||
+ p[CFHEADER_signature+2] != 'C' || p[CFHEADER_signature+3] != 'F') {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Couldn't find out CAB header");
+ return (ARCHIVE_FATAL);
+ }
+ hd->total_bytes = archive_le32dec(p + CFHEADER_cbCabinet);
+ hd->files_offset = archive_le32dec(p + CFHEADER_coffFiles);
+ hd->minor = p[CFHEADER_versionMinor];
+ hd->major = p[CFHEADER_versionMajor];
+ hd->folder_count = archive_le16dec(p + CFHEADER_cFolders);
+ if (hd->folder_count == 0)
+ goto invalid;
+ hd->file_count = archive_le16dec(p + CFHEADER_cFiles);
+ if (hd->file_count == 0)
+ goto invalid;
+ hd->flags = archive_le16dec(p + CFHEADER_flags);
+ hd->setid = archive_le16dec(p + CFHEADER_setID);
+ hd->cabinet = archive_le16dec(p + CFHEADER_iCabinet);
+ used = CFHEADER_iCabinet + 2;
+ if (hd->flags & RESERVE_PRESENT) {
+ uint16_t cfheader;
+ cfheader = archive_le16dec(p + CFHEADER_cbCFHeader);
+ if (cfheader > 60000U)
+ goto invalid;
+ hd->cffolder = p[CFHEADER_cbCFFolder];
+ hd->cfdata = p[CFHEADER_cbCFData];
+ used += 4;/* cbCFHeader, cbCFFolder and cbCFData */
+ used += cfheader;/* abReserve */
+ } else
+ hd->cffolder = 0;/* Avoid compiling warning. */
+ if (hd->flags & PREV_CABINET) {
+ /* How many bytes are used for szCabinetPrev. */
+ if ((p = __archive_read_ahead(a, used+256, NULL)) == NULL)
+ return (truncated_error(a));
+ if ((len = cab_strnlen(p + used, 255)) <= 0)
+ goto invalid;
+ used += len + 1;
+ /* How many bytes are used for szDiskPrev. */
+ if ((p = __archive_read_ahead(a, used+256, NULL)) == NULL)
+ return (truncated_error(a));
+ if ((len = cab_strnlen(p + used, 255)) <= 0)
+ goto invalid;
+ used += len + 1;
+ }
+ if (hd->flags & NEXT_CABINET) {
+ /* How many bytes are used for szCabinetNext. */
+ if ((p = __archive_read_ahead(a, used+256, NULL)) == NULL)
+ return (truncated_error(a));
+ if ((len = cab_strnlen(p + used, 255)) <= 0)
+ goto invalid;
+ used += len + 1;
+ /* How many bytes are used for szDiskNext. */
+ if ((p = __archive_read_ahead(a, used+256, NULL)) == NULL)
+ return (truncated_error(a));
+ if ((len = cab_strnlen(p + used, 255)) <= 0)
+ goto invalid;
+ used += len + 1;
+ }
+ __archive_read_consume(a, used);
+ cab->cab_offset += used;
+ used = 0;
+
+ /*
+ * Read CFFOLDER.
+ */
+ hd->folder_array = (struct cffolder *)calloc(
+ hd->folder_count, sizeof(struct cffolder));
+ if (hd->folder_array == NULL)
+ goto nomem;
+
+ bytes = 8;
+ if (hd->flags & RESERVE_PRESENT)
+ bytes += hd->cffolder;
+ bytes *= hd->folder_count;
+ if ((p = __archive_read_ahead(a, bytes, NULL)) == NULL)
+ return (truncated_error(a));
+ offset32 = 0;
+ for (i = 0; i < hd->folder_count; i++) {
+ struct cffolder *folder = &(hd->folder_array[i]);
+ folder->cfdata_offset_in_cab =
+ archive_le32dec(p + CFFOLDER_coffCabStart);
+ folder->cfdata_count = archive_le16dec(p+CFFOLDER_cCFData);
+ folder->comptype =
+ archive_le16dec(p+CFFOLDER_typeCompress) & 0x0F;
+ folder->compdata =
+ archive_le16dec(p+CFFOLDER_typeCompress) >> 8;
+ /* Get a compression name. */
+ if (folder->comptype <
+ sizeof(compression_name) / sizeof(compression_name[0]))
+ folder->compname = compression_name[folder->comptype];
+ else
+ folder->compname = "UNKNOWN";
+ p += 8;
+ used += 8;
+ if (hd->flags & RESERVE_PRESENT) {
+ p += hd->cffolder;/* abReserve */
+ used += hd->cffolder;
+ }
+ /*
+ * Sanity check if each data is acceptable.
+ */
+ if (offset32 >= folder->cfdata_offset_in_cab)
+ goto invalid;
+ offset32 = folder->cfdata_offset_in_cab;
+
+ /* Set a request to initialize zlib for the CFDATA of
+ * this folder. */
+ folder->decompress_init = 0;
+ }
+ __archive_read_consume(a, used);
+ cab->cab_offset += used;
+
+ /*
+ * Read CFFILE.
+ */
+ /* Seek read pointer to the offset of CFFILE if needed. */
+ skip = (int64_t)hd->files_offset - cab->cab_offset;
+ if (skip < 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Invalid offset of CFFILE %jd < %jd",
+ (intmax_t)hd->files_offset, (intmax_t)cab->cab_offset);
+ return (ARCHIVE_FATAL);
+ }
+ if (skip) {
+ __archive_read_consume(a, skip);
+ cab->cab_offset += skip;
+ }
+ /* Allocate memory for CFDATA */
+ hd->file_array = (struct cffile *)calloc(
+ hd->file_count, sizeof(struct cffile));
+ if (hd->file_array == NULL)
+ goto nomem;
+
+ prev_folder = -1;
+ for (i = 0; i < hd->file_count; i++) {
+ struct cffile *file = &(hd->file_array[i]);
+ ssize_t avail;
+
+ if ((p = __archive_read_ahead(a, 16, NULL)) == NULL)
+ return (truncated_error(a));
+ file->uncompressed_size = archive_le32dec(p + CFFILE_cbFile);
+ file->offset = archive_le32dec(p + CFFILE_uoffFolderStart);
+ file->folder = archive_le16dec(p + CFFILE_iFolder);
+ file->mtime = cab_dos_time(p + CFFILE_date_time);
+ file->attr = archive_le16dec(p + CFFILE_attribs);
+ __archive_read_consume(a, 16);
+
+ cab->cab_offset += 16;
+ if ((p = cab_read_ahead_remaining(a, 256, &avail)) == NULL)
+ return (truncated_error(a));
+ if ((len = cab_strnlen(p, avail-1)) <= 0)
+ goto invalid;
+
+ /* Copy a pathname. */
+ archive_string_init(&(file->pathname));
+ archive_strncpy(&(file->pathname), p, len);
+ __archive_read_consume(a, len + 1);
+ cab->cab_offset += len + 1;
+
+ /*
+ * Sanity check if each data is acceptable.
+ */
+ if (file->uncompressed_size > 0x7FFF8000)
+ goto invalid;/* Too large */
+ if ((int64_t)file->offset + (int64_t)file->uncompressed_size
+ > ARCHIVE_LITERAL_LL(0x7FFF8000))
+ goto invalid;/* Too large */
+ switch (file->folder) {
+ case iFoldCONTINUED_TO_NEXT:
+ /* This must be last file in a folder. */
+ if (i != hd->file_count -1)
+ goto invalid;
+ cur_folder = hd->folder_count -1;
+ break;
+ case iFoldCONTINUED_PREV_AND_NEXT:
+ /* This must be only one file in a folder. */
+ if (hd->file_count != 1)
+ goto invalid;
+ /* FALL THROUGH */
+ case iFoldCONTINUED_FROM_PREV:
+ /* This must be first file in a folder. */
+ if (i != 0)
+ goto invalid;
+ prev_folder = cur_folder = 0;
+ offset32 = file->offset;
+ break;
+ default:
+ if (file->folder >= hd->folder_count)
+ goto invalid;
+ cur_folder = file->folder;
+ break;
+ }
+ /* Dot not back track. */
+ if (cur_folder < prev_folder)
+ goto invalid;
+ if (cur_folder != prev_folder)
+ offset32 = 0;
+ prev_folder = cur_folder;
+
+ /* Make sure there are not any blanks from last file
+ * contents. */
+ if (offset32 != file->offset)
+ goto invalid;
+ offset32 += file->uncompressed_size;
+
+ /* CFDATA is available for file contents. */
+ if (file->uncompressed_size > 0 &&
+ hd->folder_array[cur_folder].cfdata_count == 0)
+ goto invalid;
+ }
+
+ if (hd->cabinet != 0 || hd->flags & (PREV_CABINET | NEXT_CABINET)) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Multivolume cabinet file is unsupported");
+ return (ARCHIVE_WARN);
+ }
+ return (ARCHIVE_OK);
+invalid:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid CAB header");
+ return (ARCHIVE_FATAL);
+nomem:
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for CAB data");
+ return (ARCHIVE_FATAL);
+}
+
+static int
+archive_read_format_cab_read_header(struct archive_read *a,
+ struct archive_entry *entry)
+{
+ struct cab *cab;
+ struct cfheader *hd;
+ struct cffolder *prev_folder;
+ struct cffile *file;
+ struct archive_string_conv *sconv;
+ int err = ARCHIVE_OK, r;
+
+ cab = (struct cab *)(a->format->data);
+ if (cab->found_header == 0) {
+ err = cab_read_header(a);
+ if (err < ARCHIVE_WARN)
+ return (err);
+ /* We've found the header. */
+ cab->found_header = 1;
+ }
+ hd = &cab->cfheader;
+
+ if (hd->file_index >= hd->file_count) {
+ cab->end_of_archive = 1;
+ return (ARCHIVE_EOF);
+ }
+ file = &hd->file_array[hd->file_index++];
+
+ cab->end_of_entry = 0;
+ cab->end_of_entry_cleanup = 0;
+ cab->entry_compressed_bytes_read = 0;
+ cab->entry_uncompressed_bytes_read = 0;
+ cab->entry_unconsumed = 0;
+ cab->entry_cffile = file;
+
+ /*
+ * Choose a proper folder.
+ */
+ prev_folder = cab->entry_cffolder;
+ switch (file->folder) {
+ case iFoldCONTINUED_FROM_PREV:
+ case iFoldCONTINUED_PREV_AND_NEXT:
+ cab->entry_cffolder = &hd->folder_array[0];
+ break;
+ case iFoldCONTINUED_TO_NEXT:
+ cab->entry_cffolder = &hd->folder_array[hd->folder_count-1];
+ break;
+ default:
+ cab->entry_cffolder = &hd->folder_array[file->folder];
+ break;
+ }
+ /* If a cffolder of this file is changed, reset a cfdata to read
+ * file contents from next cfdata. */
+ if (prev_folder != cab->entry_cffolder)
+ cab->entry_cfdata = NULL;
+
+ /* If a pathname is UTF-8, prepare a string conversion object
+ * for UTF-8 and use it. */
+ if (file->attr & ATTR_NAME_IS_UTF) {
+ if (cab->sconv_utf8 == NULL) {
+ cab->sconv_utf8 =
+ archive_string_conversion_from_charset(
+ &(a->archive), "UTF-8", 1);
+ if (cab->sconv_utf8 == NULL)
+ return (ARCHIVE_FATAL);
+ }
+ sconv = cab->sconv_utf8;
+ } else if (cab->sconv != NULL) {
+ /* Choose the conversion specified by the option. */
+ sconv = cab->sconv;
+ } else {
+ /* Choose the default conversion. */
+ if (!cab->init_default_conversion) {
+ cab->sconv_default =
+ archive_string_default_conversion_for_read(
+ &(a->archive));
+ cab->init_default_conversion = 1;
+ }
+ sconv = cab->sconv_default;
+ }
+
+ /*
+ * Set a default value and common data
+ */
+ r = cab_convert_path_separator_1(&(file->pathname), file->attr);
+ if (archive_entry_copy_pathname_l(entry, file->pathname.s,
+ archive_strlen(&(file->pathname)), sconv) != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Pathname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Pathname cannot be converted "
+ "from %s to current locale.",
+ archive_string_conversion_charset_name(sconv));
+ err = ARCHIVE_WARN;
+ }
+ if (r < 0) {
+ /* Convert a path separator '\' -> '/' */
+ cab_convert_path_separator_2(cab, entry);
+ }
+
+ archive_entry_set_size(entry, file->uncompressed_size);
+ if (file->attr & ATTR_RDONLY)
+ archive_entry_set_mode(entry, AE_IFREG | 0555);
+ else
+ archive_entry_set_mode(entry, AE_IFREG | 0777);
+ archive_entry_set_mtime(entry, file->mtime, 0);
+
+ cab->entry_bytes_remaining = file->uncompressed_size;
+ cab->entry_offset = 0;
+ /* We don't need compress data. */
+ if (file->uncompressed_size == 0)
+ cab->end_of_entry_cleanup = cab->end_of_entry = 1;
+
+ /* Set up a more descriptive format name. */
+ sprintf(cab->format_name, "CAB %d.%d (%s)",
+ hd->major, hd->minor, cab->entry_cffolder->compname);
+ a->archive.archive_format_name = cab->format_name;
+
+ return (err);
+}
+
+static int
+archive_read_format_cab_read_data(struct archive_read *a,
+ const void **buff, size_t *size, int64_t *offset)
+{
+ struct cab *cab = (struct cab *)(a->format->data);
+ int r;
+
+ switch (cab->entry_cffile->folder) {
+ case iFoldCONTINUED_FROM_PREV:
+ case iFoldCONTINUED_TO_NEXT:
+ case iFoldCONTINUED_PREV_AND_NEXT:
+ *buff = NULL;
+ *size = 0;
+ *offset = 0;
+ archive_clear_error(&a->archive);
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Cannot restore this file split in multivolume.");
+ return (ARCHIVE_FAILED);
+ default:
+ break;
+ }
+ if (cab->entry_unconsumed) {
+ /* Consume as much as the compressor actually used. */
+ r = cab_consume_cfdata(a, cab->entry_unconsumed);
+ cab->entry_unconsumed = 0;
+ if (r < 0)
+ return (r);
+ }
+ if (cab->end_of_archive || cab->end_of_entry) {
+ if (!cab->end_of_entry_cleanup) {
+ /* End-of-entry cleanup done. */
+ cab->end_of_entry_cleanup = 1;
+ }
+ *offset = cab->entry_offset;
+ *size = 0;
+ *buff = NULL;
+ return (ARCHIVE_EOF);
+ }
+
+ return (cab_read_data(a, buff, size, offset));
+}
+
+static uint32_t
+cab_checksum_cfdata_4(const void *p, size_t bytes, uint32_t seed)
+{
+ const unsigned char *b;
+ int u32num;
+ uint32_t sum;
+
+ u32num = bytes / 4;
+ sum = seed;
+ b = p;
+ while (--u32num >= 0) {
+ sum ^= archive_le32dec(b);
+ b += 4;
+ }
+ return (sum);
+}
+
+static uint32_t
+cab_checksum_cfdata(const void *p, size_t bytes, uint32_t seed)
+{
+ const unsigned char *b;
+ uint32_t sum;
+ uint32_t t;
+
+ sum = cab_checksum_cfdata_4(p, bytes, seed);
+ b = p;
+ b += bytes & ~3;
+ t = 0;
+ switch (bytes & 3) {
+ case 3:
+ t |= ((uint32_t)(*b++)) << 16;
+ /* FALL THROUGH */
+ case 2:
+ t |= ((uint32_t)(*b++)) << 8;
+ /* FALL THROUGH */
+ case 1:
+ t |= *b;
+ /* FALL THROUGH */
+ default:
+ break;
+ }
+ sum ^= t;
+
+ return (sum);
+}
+
+static void
+cab_checksum_update(struct archive_read *a, size_t bytes)
+{
+ struct cab *cab = (struct cab *)(a->format->data);
+ struct cfdata *cfdata = cab->entry_cfdata;
+ const unsigned char *p;
+ size_t sumbytes;
+
+ if (cfdata->sum == 0 || cfdata->sum_ptr == NULL)
+ return;
+ /*
+ * Calculate the sum of this CFDATA.
+ * Make sure CFDATA must be calculated in four bytes.
+ */
+ p = cfdata->sum_ptr;
+ sumbytes = bytes;
+ if (cfdata->sum_extra_avail) {
+ while (cfdata->sum_extra_avail < 4 && sumbytes > 0) {
+ cfdata->sum_extra[
+ cfdata->sum_extra_avail++] = *p++;
+ sumbytes--;
+ }
+ if (cfdata->sum_extra_avail == 4) {
+ cfdata->sum_calculated = cab_checksum_cfdata_4(
+ cfdata->sum_extra, 4, cfdata->sum_calculated);
+ cfdata->sum_extra_avail = 0;
+ }
+ }
+ if (sumbytes) {
+ int odd = sumbytes & 3;
+ if (sumbytes - odd > 0)
+ cfdata->sum_calculated = cab_checksum_cfdata_4(
+ p, sumbytes - odd, cfdata->sum_calculated);
+ if (odd)
+ memcpy(cfdata->sum_extra, p + sumbytes - odd, odd);
+ cfdata->sum_extra_avail = odd;
+ }
+ cfdata->sum_ptr = NULL;
+}
+
+static int
+cab_checksum_finish(struct archive_read *a)
+{
+ struct cab *cab = (struct cab *)(a->format->data);
+ struct cfdata *cfdata = cab->entry_cfdata;
+ int l;
+
+ /* Do not need to compute a sum. */
+ if (cfdata->sum == 0)
+ return (ARCHIVE_OK);
+
+ /*
+ * Calculate the sum of remaining CFDATA.
+ */
+ if (cfdata->sum_extra_avail) {
+ cfdata->sum_calculated =
+ cab_checksum_cfdata(cfdata->sum_extra,
+ cfdata->sum_extra_avail, cfdata->sum_calculated);
+ cfdata->sum_extra_avail = 0;
+ }
+
+ l = 4;
+ if (cab->cfheader.flags & RESERVE_PRESENT)
+ l += cab->cfheader.cfdata;
+ cfdata->sum_calculated = cab_checksum_cfdata(
+ cfdata->memimage + CFDATA_cbData, l, cfdata->sum_calculated);
+ if (cfdata->sum_calculated != cfdata->sum) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Checksum error CFDATA[%d] %x:%x in %d bytes",
+ cab->entry_cffolder->cfdata_index -1,
+ cfdata->sum, cfdata->sum_calculated,
+ cfdata->compressed_size);
+ return (ARCHIVE_FAILED);
+ }
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Read CFDATA if needed.
+ */
+static int
+cab_next_cfdata(struct archive_read *a)
+{
+ struct cab *cab = (struct cab *)(a->format->data);
+ struct cfdata *cfdata = cab->entry_cfdata;
+
+ /* There are remaining bytes in current CFDATA, use it first. */
+ if (cfdata != NULL && cfdata->uncompressed_bytes_remaining > 0)
+ return (ARCHIVE_OK);
+
+ if (cfdata == NULL) {
+ int64_t skip;
+
+ cab->entry_cffolder->cfdata_index = 0;
+
+ /* Seek read pointer to the offset of CFDATA if needed. */
+ skip = cab->entry_cffolder->cfdata_offset_in_cab
+ - cab->cab_offset;
+ if (skip < 0) {
+ int folder_index;
+ switch (cab->entry_cffile->folder) {
+ case iFoldCONTINUED_FROM_PREV:
+ case iFoldCONTINUED_PREV_AND_NEXT:
+ folder_index = 0;
+ break;
+ case iFoldCONTINUED_TO_NEXT:
+ folder_index = cab->cfheader.folder_count-1;
+ break;
+ default:
+ folder_index = cab->entry_cffile->folder;
+ break;
+ }
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Invalid offset of CFDATA in folder(%d) %jd < %jd",
+ folder_index,
+ (intmax_t)cab->entry_cffolder->cfdata_offset_in_cab,
+ (intmax_t)cab->cab_offset);
+ return (ARCHIVE_FATAL);
+ }
+ if (skip > 0) {
+ if (__archive_read_consume(a, skip) < 0)
+ return (ARCHIVE_FATAL);
+ cab->cab_offset =
+ cab->entry_cffolder->cfdata_offset_in_cab;
+ }
+ }
+
+ /*
+ * Read a CFDATA.
+ */
+ if (cab->entry_cffolder->cfdata_index <
+ cab->entry_cffolder->cfdata_count) {
+ const unsigned char *p;
+ int l;
+
+ cfdata = &(cab->entry_cffolder->cfdata);
+ cab->entry_cffolder->cfdata_index++;
+ cab->entry_cfdata = cfdata;
+ cfdata->sum_calculated = 0;
+ cfdata->sum_extra_avail = 0;
+ cfdata->sum_ptr = NULL;
+ l = 8;
+ if (cab->cfheader.flags & RESERVE_PRESENT)
+ l += cab->cfheader.cfdata;
+ if ((p = __archive_read_ahead(a, l, NULL)) == NULL)
+ return (truncated_error(a));
+ cfdata->sum = archive_le32dec(p + CFDATA_csum);
+ cfdata->compressed_size = archive_le16dec(p + CFDATA_cbData);
+ cfdata->compressed_bytes_remaining = cfdata->compressed_size;
+ cfdata->uncompressed_size =
+ archive_le16dec(p + CFDATA_cbUncomp);
+ cfdata->uncompressed_bytes_remaining =
+ cfdata->uncompressed_size;
+ cfdata->uncompressed_avail = 0;
+ cfdata->read_offset = 0;
+ cfdata->unconsumed = 0;
+
+ /*
+ * Sanity check if data size is acceptable.
+ */
+ if (cfdata->compressed_size == 0 ||
+ cfdata->compressed_size > (0x8000+6144))
+ goto invalid;
+ if (cfdata->uncompressed_size > 0x8000)
+ goto invalid;
+ if (cfdata->uncompressed_size == 0) {
+ switch (cab->entry_cffile->folder) {
+ case iFoldCONTINUED_PREV_AND_NEXT:
+ case iFoldCONTINUED_TO_NEXT:
+ break;
+ case iFoldCONTINUED_FROM_PREV:
+ default:
+ goto invalid;
+ }
+ }
+ /* If CFDATA is not last in a folder, an uncompressed
+ * size must be 0x8000(32KBi) */
+ if ((cab->entry_cffolder->cfdata_index <
+ cab->entry_cffolder->cfdata_count) &&
+ cfdata->uncompressed_size != 0x8000)
+ goto invalid;
+
+ /* A compressed data size and an uncompressed data size must
+ * be the same in no compression mode. */
+ if (cab->entry_cffolder->comptype == COMPTYPE_NONE &&
+ cfdata->compressed_size != cfdata->uncompressed_size)
+ goto invalid;
+
+ /*
+ * Save CFDATA image for sum check.
+ */
+ if (cfdata->memimage_size < (size_t)l) {
+ free(cfdata->memimage);
+ cfdata->memimage = malloc(l);
+ if (cfdata->memimage == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for CAB data");
+ return (ARCHIVE_FATAL);
+ }
+ cfdata->memimage_size = l;
+ }
+ memcpy(cfdata->memimage, p, l);
+
+ /* Consume bytes as much as we used. */
+ __archive_read_consume(a, l);
+ cab->cab_offset += l;
+ } else if (cab->entry_cffolder->cfdata_count > 0) {
+ /* Run out of all CFDATA in a folder. */
+ cfdata->compressed_size = 0;
+ cfdata->uncompressed_size = 0;
+ cfdata->compressed_bytes_remaining = 0;
+ cfdata->uncompressed_bytes_remaining = 0;
+ } else {
+ /* Current folder does not have any CFDATA. */
+ cfdata = &(cab->entry_cffolder->cfdata);
+ cab->entry_cfdata = cfdata;
+ memset(cfdata, 0, sizeof(*cfdata));
+ }
+ return (ARCHIVE_OK);
+invalid:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid CFDATA");
+ return (ARCHIVE_FATAL);
+}
+
+/*
+ * Read ahead CFDATA.
+ */
+static const void *
+cab_read_ahead_cfdata(struct archive_read *a, ssize_t *avail)
+{
+ struct cab *cab = (struct cab *)(a->format->data);
+ int err;
+
+ err = cab_next_cfdata(a);
+ if (err < ARCHIVE_OK) {
+ *avail = err;
+ return (NULL);
+ }
+
+ switch (cab->entry_cffolder->comptype) {
+ case COMPTYPE_NONE:
+ return (cab_read_ahead_cfdata_none(a, avail));
+ case COMPTYPE_MSZIP:
+ return (cab_read_ahead_cfdata_deflate(a, avail));
+ case COMPTYPE_LZX:
+ return (cab_read_ahead_cfdata_lzx(a, avail));
+ default: /* Unsupported compression. */
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Unsupported CAB compression : %s",
+ cab->entry_cffolder->compname);
+ *avail = ARCHIVE_FAILED;
+ return (NULL);
+ }
+}
+
+/*
+ * Read ahead CFDATA as uncompressed data.
+ */
+static const void *
+cab_read_ahead_cfdata_none(struct archive_read *a, ssize_t *avail)
+{
+ struct cab *cab = (struct cab *)(a->format->data);
+ struct cfdata *cfdata;
+ const void *d;
+ int64_t skipped_bytes;
+
+ cfdata = cab->entry_cfdata;
+
+ if (cfdata->uncompressed_avail == 0 &&
+ cfdata->read_offset > 0) {
+ /* we've already skipped some bytes before really read. */
+ skipped_bytes = cfdata->read_offset;
+ cfdata->read_offset = 0;
+ cfdata->uncompressed_bytes_remaining += skipped_bytes;
+ } else
+ skipped_bytes = 0;
+ do {
+ /*
+ * Note: '1' here is a performance optimization.
+ * Recall that the decompression layer returns a count of
+ * available bytes; asking for more than that forces the
+ * decompressor to combine reads by copying data.
+ */
+ d = __archive_read_ahead(a, 1, avail);
+ if (*avail <= 0) {
+ *avail = truncated_error(a);
+ return (NULL);
+ }
+ if (*avail > cfdata->uncompressed_bytes_remaining)
+ *avail = cfdata->uncompressed_bytes_remaining;
+ cfdata->uncompressed_avail = cfdata->uncompressed_size;
+ cfdata->unconsumed = *avail;
+ cfdata->sum_ptr = d;
+ if (skipped_bytes > 0) {
+ skipped_bytes =
+ cab_minimum_consume_cfdata(a, skipped_bytes);
+ if (skipped_bytes < 0) {
+ *avail = ARCHIVE_FATAL;
+ return (NULL);
+ }
+ continue;
+ }
+ } while (0);
+
+ return (d);
+}
+
+/*
+ * Read ahead CFDATA as deflate data.
+ */
+#ifdef HAVE_ZLIB_H
+static const void *
+cab_read_ahead_cfdata_deflate(struct archive_read *a, ssize_t *avail)
+{
+ struct cab *cab = (struct cab *)(a->format->data);
+ struct cfdata *cfdata;
+ const void *d;
+ int r, mszip;
+ uint16_t uavail;
+ char eod = 0;
+
+ cfdata = cab->entry_cfdata;
+ /* If the buffer hasn't been allocated, allocate it now. */
+ if (cab->uncompressed_buffer == NULL) {
+ cab->uncompressed_buffer_size = 0x8000;
+ cab->uncompressed_buffer
+ = (unsigned char *)malloc(cab->uncompressed_buffer_size);
+ if (cab->uncompressed_buffer == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "No memory for CAB reader");
+ *avail = ARCHIVE_FATAL;
+ return (NULL);
+ }
+ }
+
+ uavail = cfdata->uncompressed_avail;
+ if (uavail == cfdata->uncompressed_size) {
+ d = cab->uncompressed_buffer + cfdata->read_offset;
+ *avail = uavail - cfdata->read_offset;
+ return (d);
+ }
+
+ if (!cab->entry_cffolder->decompress_init) {
+ cab->stream.next_in = NULL;
+ cab->stream.avail_in = 0;
+ cab->stream.total_in = 0;
+ cab->stream.next_out = NULL;
+ cab->stream.avail_out = 0;
+ cab->stream.total_out = 0;
+ if (cab->stream_valid)
+ r = inflateReset(&cab->stream);
+ else
+ r = inflateInit2(&cab->stream,
+ -15 /* Don't check for zlib header */);
+ if (r != Z_OK) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Can't initialize deflate decompression.");
+ *avail = ARCHIVE_FATAL;
+ return (NULL);
+ }
+ /* Stream structure has been set up. */
+ cab->stream_valid = 1;
+ /* We've initialized decompression for this stream. */
+ cab->entry_cffolder->decompress_init = 1;
+ }
+
+ if (cfdata->compressed_bytes_remaining == cfdata->compressed_size)
+ mszip = 2;
+ else
+ mszip = 0;
+ eod = 0;
+ cab->stream.total_out = uavail;
+ /*
+ * We always uncompress all data in current CFDATA.
+ */
+ while (!eod && cab->stream.total_out < cfdata->uncompressed_size) {
+ ssize_t bytes_avail;
+
+ cab->stream.next_out =
+ cab->uncompressed_buffer + cab->stream.total_out;
+ cab->stream.avail_out =
+ cfdata->uncompressed_size - cab->stream.total_out;
+
+ d = __archive_read_ahead(a, 1, &bytes_avail);
+ if (bytes_avail <= 0) {
+ *avail = truncated_error(a);
+ return (NULL);
+ }
+ if (bytes_avail > cfdata->compressed_bytes_remaining)
+ bytes_avail = cfdata->compressed_bytes_remaining;
+ /*
+ * A bug in zlib.h: stream.next_in should be marked 'const'
+ * but isn't (the library never alters data through the
+ * next_in pointer, only reads it). The result: this ugly
+ * cast to remove 'const'.
+ */
+ cab->stream.next_in = (Bytef *)(uintptr_t)d;
+ cab->stream.avail_in = bytes_avail;
+ cab->stream.total_in = 0;
+
+ /* Cut out a tow-byte MSZIP signature(0x43, 0x4b). */
+ if (mszip > 0) {
+ if (bytes_avail <= mszip) {
+ if (mszip == 2) {
+ if (cab->stream.next_in[0] != 0x43)
+ goto nomszip;
+ if (bytes_avail > 1 &&
+ cab->stream.next_in[1] != 0x4b)
+ goto nomszip;
+ } else if (cab->stream.next_in[0] != 0x4b)
+ goto nomszip;
+ cfdata->unconsumed = bytes_avail;
+ cfdata->sum_ptr = d;
+ if (cab_minimum_consume_cfdata(
+ a, cfdata->unconsumed) < 0) {
+ *avail = ARCHIVE_FATAL;
+ return (NULL);
+ }
+ mszip -= bytes_avail;
+ continue;
+ }
+ if (mszip == 1 && cab->stream.next_in[0] != 0x4b)
+ goto nomszip;
+ else if (cab->stream.next_in[0] != 0x43 ||
+ cab->stream.next_in[1] != 0x4b)
+ goto nomszip;
+ cab->stream.next_in += mszip;
+ cab->stream.avail_in -= mszip;
+ cab->stream.total_in += mszip;
+ mszip = 0;
+ }
+
+ r = inflate(&cab->stream, 0);
+ switch (r) {
+ case Z_OK:
+ break;
+ case Z_STREAM_END:
+ eod = 1;
+ break;
+ default:
+ goto zlibfailed;
+ }
+ cfdata->unconsumed = cab->stream.total_in;
+ cfdata->sum_ptr = d;
+ if (cab_minimum_consume_cfdata(a, cfdata->unconsumed) < 0) {
+ *avail = ARCHIVE_FATAL;
+ return (NULL);
+ }
+ }
+ uavail = cab->stream.total_out;
+
+ if (uavail < cfdata->uncompressed_size) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Invalid uncompressed size (%d < %d)",
+ uavail, cfdata->uncompressed_size);
+ *avail = ARCHIVE_FATAL;
+ return (NULL);
+ }
+
+ /*
+ * Note: I suspect there is a bug in makecab.exe because, in rare
+ * case, compressed bytes are still remaining regardless we have
+ * gotten all uncompressed bytes, which size is recoded in CFDATA,
+ * as much as we need, and we have to use the garbage so as to
+ * correctly compute the sum of CFDATA accordingly.
+ */
+ if (cfdata->compressed_bytes_remaining > 0) {
+ ssize_t bytes_avail;
+
+ d = __archive_read_ahead(a, cfdata->compressed_bytes_remaining,
+ &bytes_avail);
+ if (bytes_avail <= 0) {
+ *avail = truncated_error(a);
+ return (NULL);
+ }
+ cfdata->unconsumed = cfdata->compressed_bytes_remaining;
+ cfdata->sum_ptr = d;
+ if (cab_minimum_consume_cfdata(a, cfdata->unconsumed) < 0) {
+ *avail = ARCHIVE_FATAL;
+ return (NULL);
+ }
+ }
+
+ /*
+ * Set dictionary data for decompressing of next CFDATA, which
+ * in the same folder. This is why we always do decompress CFDATA
+ * even if beginning CFDATA or some of CFDATA are not used in
+ * skipping file data.
+ */
+ if (cab->entry_cffolder->cfdata_index <
+ cab->entry_cffolder->cfdata_count) {
+ r = inflateReset(&cab->stream);
+ if (r != Z_OK)
+ goto zlibfailed;
+ r = inflateSetDictionary(&cab->stream,
+ cab->uncompressed_buffer, cfdata->uncompressed_size);
+ if (r != Z_OK)
+ goto zlibfailed;
+ }
+
+ d = cab->uncompressed_buffer + cfdata->read_offset;
+ *avail = uavail - cfdata->read_offset;
+ cfdata->uncompressed_avail = uavail;
+
+ return (d);
+
+zlibfailed:
+ switch (r) {
+ case Z_MEM_ERROR:
+ archive_set_error(&a->archive, ENOMEM,
+ "Out of memory for deflate decompression");
+ break;
+ default:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Deflate decompression failed (%d)", r);
+ break;
+ }
+ *avail = ARCHIVE_FATAL;
+ return (NULL);
+nomszip:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "CFDATA incorrect(no MSZIP signature)");
+ *avail = ARCHIVE_FATAL;
+ return (NULL);
+}
+
+#else /* HAVE_ZLIB_H */
+
+static const void *
+cab_read_ahead_cfdata_deflate(struct archive_read *a, ssize_t *avail)
+{
+ *avail = ARCHIVE_FATAL;
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "libarchive compiled without deflate support (no libz)");
+ return (NULL);
+}
+
+#endif /* HAVE_ZLIB_H */
+
+static const void *
+cab_read_ahead_cfdata_lzx(struct archive_read *a, ssize_t *avail)
+{
+ struct cab *cab = (struct cab *)(a->format->data);
+ struct cfdata *cfdata;
+ const void *d;
+ int r;
+ uint16_t uavail;
+
+ cfdata = cab->entry_cfdata;
+ /* If the buffer hasn't been allocated, allocate it now. */
+ if (cab->uncompressed_buffer == NULL) {
+ cab->uncompressed_buffer_size = 0x8000;
+ cab->uncompressed_buffer
+ = (unsigned char *)malloc(cab->uncompressed_buffer_size);
+ if (cab->uncompressed_buffer == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "No memory for CAB reader");
+ *avail = ARCHIVE_FATAL;
+ return (NULL);
+ }
+ }
+
+ uavail = cfdata->uncompressed_avail;
+ if (uavail == cfdata->uncompressed_size) {
+ d = cab->uncompressed_buffer + cfdata->read_offset;
+ *avail = uavail - cfdata->read_offset;
+ return (d);
+ }
+
+ if (!cab->entry_cffolder->decompress_init) {
+ r = lzx_decode_init(&cab->xstrm,
+ cab->entry_cffolder->compdata);
+ if (r != ARCHIVE_OK) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Can't initialize LZX decompression.");
+ *avail = ARCHIVE_FATAL;
+ return (NULL);
+ }
+ /* We've initialized decompression for this stream. */
+ cab->entry_cffolder->decompress_init = 1;
+ }
+
+ /* Clean up remaining bits of previous CFDATA. */
+ lzx_cleanup_bitstream(&cab->xstrm);
+ cab->xstrm.total_out = uavail;
+ while (cab->xstrm.total_out < cfdata->uncompressed_size) {
+ ssize_t bytes_avail;
+
+ cab->xstrm.next_out =
+ cab->uncompressed_buffer + cab->xstrm.total_out;
+ cab->xstrm.avail_out =
+ cfdata->uncompressed_size - cab->xstrm.total_out;
+
+ d = __archive_read_ahead(a, 1, &bytes_avail);
+ if (bytes_avail <= 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated CAB file data");
+ *avail = ARCHIVE_FATAL;
+ return (NULL);
+ }
+ if (bytes_avail > cfdata->compressed_bytes_remaining)
+ bytes_avail = cfdata->compressed_bytes_remaining;
+
+ cab->xstrm.next_in = d;
+ cab->xstrm.avail_in = bytes_avail;
+ cab->xstrm.total_in = 0;
+ r = lzx_decode(&cab->xstrm,
+ cfdata->compressed_bytes_remaining == bytes_avail);
+ switch (r) {
+ case ARCHIVE_OK:
+ case ARCHIVE_EOF:
+ break;
+ default:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "LZX decompression failed (%d)", r);
+ *avail = ARCHIVE_FATAL;
+ return (NULL);
+ }
+ cfdata->unconsumed = cab->xstrm.total_in;
+ cfdata->sum_ptr = d;
+ if (cab_minimum_consume_cfdata(a, cfdata->unconsumed) < 0) {
+ *avail = ARCHIVE_FATAL;
+ return (NULL);
+ }
+ }
+
+ uavail = cab->xstrm.total_out;
+ /*
+ * Make sure a read pointer advances to next CFDATA.
+ */
+ if (cfdata->compressed_bytes_remaining > 0) {
+ ssize_t bytes_avail;
+
+ d = __archive_read_ahead(a, cfdata->compressed_bytes_remaining,
+ &bytes_avail);
+ if (bytes_avail <= 0) {
+ *avail = truncated_error(a);
+ return (NULL);
+ }
+ cfdata->unconsumed = cfdata->compressed_bytes_remaining;
+ cfdata->sum_ptr = d;
+ if (cab_minimum_consume_cfdata(a, cfdata->unconsumed) < 0) {
+ *avail = ARCHIVE_FATAL;
+ return (NULL);
+ }
+ }
+
+ /*
+ * Translation reversal of x86 proccessor CALL byte sequence(E8).
+ */
+ lzx_translation(&cab->xstrm, cab->uncompressed_buffer,
+ cfdata->uncompressed_size,
+ (cab->entry_cffolder->cfdata_index-1) * 0x8000);
+
+ d = cab->uncompressed_buffer + cfdata->read_offset;
+ *avail = uavail - cfdata->read_offset;
+ cfdata->uncompressed_avail = uavail;
+
+ return (d);
+}
+
+/*
+ * Consume CFDATA.
+ * We always decompress CFDATA to consume CFDATA as much as we need
+ * in uncompressed bytes because all CFDATA in a folder are related
+ * so we do not skip any CFDATA without decompressing.
+ * Note: If the folder of a CFFILE is iFoldCONTINUED_PREV_AND_NEXT or
+ * iFoldCONTINUED_FROM_PREV, we won't decompress because a CFDATA for
+ * the CFFILE is remaining bytes of previous Multivolume CAB file.
+ */
+static int64_t
+cab_consume_cfdata(struct archive_read *a, int64_t consumed_bytes)
+{
+ struct cab *cab = (struct cab *)(a->format->data);
+ struct cfdata *cfdata;
+ int64_t cbytes, rbytes;
+ int err;
+
+ rbytes = cab_minimum_consume_cfdata(a, consumed_bytes);
+ if (rbytes < 0)
+ return (ARCHIVE_FATAL);
+
+ cfdata = cab->entry_cfdata;
+ while (rbytes > 0) {
+ ssize_t avail;
+
+ if (cfdata->compressed_size == 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid CFDATA");
+ return (ARCHIVE_FATAL);
+ }
+ cbytes = cfdata->uncompressed_bytes_remaining;
+ if (cbytes > rbytes)
+ cbytes = rbytes;
+ rbytes -= cbytes;
+
+ if (cfdata->uncompressed_avail == 0 &&
+ (cab->entry_cffolder->comptype == COMPTYPE_NONE ||
+ cab->entry_cffile->folder == iFoldCONTINUED_PREV_AND_NEXT ||
+ cab->entry_cffile->folder == iFoldCONTINUED_FROM_PREV)) {
+ /* We have not read any data yet. */
+ if (cbytes == cfdata->uncompressed_bytes_remaining) {
+ /* Skip whole current CFDATA. */
+ __archive_read_consume(a,
+ cfdata->compressed_size);
+ cab->cab_offset += cfdata->compressed_size;
+ cfdata->compressed_bytes_remaining = 0;
+ cfdata->uncompressed_bytes_remaining = 0;
+ err = cab_next_cfdata(a);
+ if (err < 0)
+ return (err);
+ cfdata = cab->entry_cfdata;
+ if (cfdata->uncompressed_size == 0) {
+ switch (cab->entry_cffile->folder) {
+ case iFoldCONTINUED_PREV_AND_NEXT:
+ case iFoldCONTINUED_TO_NEXT:
+ case iFoldCONTINUED_FROM_PREV:
+ rbytes = 0;
+ break;
+ default:
+ break;
+ }
+ }
+ continue;
+ }
+ cfdata->read_offset += cbytes;
+ cfdata->uncompressed_bytes_remaining -= cbytes;
+ break;
+ } else if (cbytes == 0) {
+ err = cab_next_cfdata(a);
+ if (err < 0)
+ return (err);
+ cfdata = cab->entry_cfdata;
+ if (cfdata->uncompressed_size == 0) {
+ switch (cab->entry_cffile->folder) {
+ case iFoldCONTINUED_PREV_AND_NEXT:
+ case iFoldCONTINUED_TO_NEXT:
+ case iFoldCONTINUED_FROM_PREV:
+ return (ARCHIVE_FATAL);
+ default:
+ break;
+ }
+ }
+ continue;
+ }
+ while (cbytes > 0) {
+ (void)cab_read_ahead_cfdata(a, &avail);
+ if (avail <= 0)
+ return (ARCHIVE_FATAL);
+ if (avail > cbytes)
+ avail = cbytes;
+ if (cab_minimum_consume_cfdata(a, avail) < 0)
+ return (ARCHIVE_FATAL);
+ cbytes -= avail;
+ }
+ }
+ return (consumed_bytes);
+}
+
+/*
+ * Consume CFDATA as much as we have already gotten and
+ * compute the sum of CFDATA.
+ */
+static int64_t
+cab_minimum_consume_cfdata(struct archive_read *a, int64_t consumed_bytes)
+{
+ struct cab *cab = (struct cab *)(a->format->data);
+ struct cfdata *cfdata;
+ int64_t cbytes, rbytes;
+ int err;
+
+ cfdata = cab->entry_cfdata;
+ rbytes = consumed_bytes;
+ if (cab->entry_cffolder->comptype == COMPTYPE_NONE) {
+ if (consumed_bytes < cfdata->unconsumed)
+ cbytes = consumed_bytes;
+ else
+ cbytes = cfdata->unconsumed;
+ rbytes -= cbytes;
+ cfdata->read_offset += cbytes;
+ cfdata->uncompressed_bytes_remaining -= cbytes;
+ cfdata->unconsumed -= cbytes;
+ } else {
+ cbytes = cfdata->uncompressed_avail - cfdata->read_offset;
+ if (cbytes > 0) {
+ if (consumed_bytes < cbytes)
+ cbytes = consumed_bytes;
+ rbytes -= cbytes;
+ cfdata->read_offset += cbytes;
+ cfdata->uncompressed_bytes_remaining -= cbytes;
+ }
+
+ if (cfdata->unconsumed) {
+ cbytes = cfdata->unconsumed;
+ cfdata->unconsumed = 0;
+ } else
+ cbytes = 0;
+ }
+ if (cbytes) {
+ /* Compute the sum. */
+ cab_checksum_update(a, cbytes);
+
+ /* Consume as much as the compressor actually used. */
+ __archive_read_consume(a, cbytes);
+ cab->cab_offset += cbytes;
+ cfdata->compressed_bytes_remaining -= cbytes;
+ if (cfdata->compressed_bytes_remaining == 0) {
+ err = cab_checksum_finish(a);
+ if (err < 0)
+ return (err);
+ }
+ }
+ return (rbytes);
+}
+
+/*
+ * Returns ARCHIVE_OK if successful, ARCHIVE_FATAL otherwise, sets
+ * cab->end_of_entry if it consumes all of the data.
+ */
+static int
+cab_read_data(struct archive_read *a, const void **buff,
+ size_t *size, int64_t *offset)
+{
+ struct cab *cab = (struct cab *)(a->format->data);
+ ssize_t bytes_avail;
+
+ if (cab->entry_bytes_remaining == 0) {
+ *buff = NULL;
+ *size = 0;
+ *offset = cab->entry_offset;
+ cab->end_of_entry = 1;
+ return (ARCHIVE_OK);
+ }
+
+ *buff = cab_read_ahead_cfdata(a, &bytes_avail);
+ if (bytes_avail <= 0) {
+ *buff = NULL;
+ *size = 0;
+ *offset = 0;
+ if (bytes_avail == 0 &&
+ cab->entry_cfdata->uncompressed_size == 0) {
+ /* All of CFDATA in a folder has been handled. */
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT, "Invalid CFDATA");
+ return (ARCHIVE_FATAL);
+ } else
+ return (bytes_avail);
+ }
+ if (bytes_avail > cab->entry_bytes_remaining)
+ bytes_avail = cab->entry_bytes_remaining;
+
+ *size = bytes_avail;
+ *offset = cab->entry_offset;
+ cab->entry_offset += bytes_avail;
+ cab->entry_bytes_remaining -= bytes_avail;
+ if (cab->entry_bytes_remaining == 0)
+ cab->end_of_entry = 1;
+ cab->entry_unconsumed = bytes_avail;
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_read_format_cab_read_data_skip(struct archive_read *a)
+{
+ struct cab *cab;
+ int64_t bytes_skipped;
+ int r;
+
+ cab = (struct cab *)(a->format->data);
+
+ if (cab->end_of_archive)
+ return (ARCHIVE_EOF);
+
+ if (cab->entry_unconsumed) {
+ /* Consume as much as the compressor actually used. */
+ r = cab_consume_cfdata(a, cab->entry_unconsumed);
+ cab->entry_unconsumed = 0;
+ if (r < 0)
+ return (r);
+ } else if (cab->entry_cfdata == NULL) {
+ r = cab_next_cfdata(a);
+ if (r < 0)
+ return (r);
+ }
+
+ /* if we've already read to end of data, we're done. */
+ if (cab->end_of_entry_cleanup)
+ return (ARCHIVE_OK);
+
+ /*
+ * If the length is at the beginning, we can skip the
+ * compressed data much more quickly.
+ */
+ bytes_skipped = cab_consume_cfdata(a, cab->entry_bytes_remaining);
+ if (bytes_skipped < 0)
+ return (ARCHIVE_FATAL);
+
+ /* This entry is finished and done. */
+ cab->end_of_entry_cleanup = cab->end_of_entry = 1;
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_read_format_cab_cleanup(struct archive_read *a)
+{
+ struct cab *cab = (struct cab *)(a->format->data);
+ struct cfheader *hd = &cab->cfheader;
+ int i;
+
+ if (hd->folder_array != NULL) {
+ for (i = 0; i < hd->folder_count; i++)
+ free(hd->folder_array[i].cfdata.memimage);
+ free(hd->folder_array);
+ }
+ if (hd->file_array != NULL) {
+ for (i = 0; i < cab->cfheader.file_count; i++)
+ archive_string_free(&(hd->file_array[i].pathname));
+ free(hd->file_array);
+ }
+#ifdef HAVE_ZLIB_H
+ if (cab->stream_valid)
+ inflateEnd(&cab->stream);
+#endif
+ lzx_decode_free(&cab->xstrm);
+ archive_wstring_free(&cab->ws);
+ free(cab->uncompressed_buffer);
+ free(cab);
+ (a->format->data) = NULL;
+ return (ARCHIVE_OK);
+}
+
+/* Convert an MSDOS-style date/time into Unix-style time. */
+static time_t
+cab_dos_time(const unsigned char *p)
+{
+ int msTime, msDate;
+ struct tm ts;
+
+ msDate = archive_le16dec(p);
+ msTime = archive_le16dec(p+2);
+
+ 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));
+}
+
+/*****************************************************************
+ *
+ * LZX decompression code.
+ *
+ *****************************************************************/
+
+/*
+ * Initialize LZX decoder.
+ *
+ * Returns ARCHIVE_OK if initialization was successful.
+ * Returns ARCHIVE_FAILED if w_bits has unsupported value.
+ * Returns ARCHIVE_FATAL if initialization failed; memory allocation
+ * error occurred.
+ */
+static int
+lzx_decode_init(struct lzx_stream *strm, int w_bits)
+{
+ struct lzx_dec *ds;
+ int slot, w_size, w_slot;
+ int base, footer;
+
+ if (strm->ds == NULL) {
+ strm->ds = calloc(1, sizeof(*strm->ds));
+ if (strm->ds == NULL)
+ return (ARCHIVE_FATAL);
+ }
+ ds = strm->ds;
+ ds->error = ARCHIVE_FAILED;
+
+ /* Allow bits from 15(32KBi) up to 21(2MBi) */
+ if (w_bits < SLOT_BASE || w_bits > SLOT_MAX)
+ return (ARCHIVE_FAILED);
+
+ ds->error = ARCHIVE_FATAL;
+
+ /*
+ * Alloc window
+ */
+ w_size = ds->w_size;
+ w_slot = slots[w_bits - SLOT_BASE];
+ ds->w_size = 1U << w_bits;
+ ds->w_mask = ds->w_size -1;
+ if (ds->w_buff == NULL || w_size != ds->w_size) {
+ free(ds->w_buff);
+ ds->w_buff = malloc(ds->w_size);
+ if (ds->w_buff == NULL)
+ return (ARCHIVE_FATAL);
+ free(ds->pos_tbl);
+ ds->pos_tbl = malloc(sizeof(ds->pos_tbl[0]) * w_slot);
+ if (ds->pos_tbl == NULL)
+ return (ARCHIVE_FATAL);
+ lzx_huffman_free(&(ds->mt));
+ }
+
+ base = footer = 0;
+ for (slot = 0; slot < w_slot; slot++) {
+ int n;
+ if (footer == 0)
+ base = slot;
+ else
+ base += 1 << footer;
+ if (footer < 17) {
+ footer = -2;
+ for (n = base; n; n >>= 1)
+ footer++;
+ if (footer <= 0)
+ footer = 0;
+ }
+ ds->pos_tbl[slot].base = base;
+ ds->pos_tbl[slot].footer_bits = footer;
+ }
+
+ ds->w_pos = 0;
+ ds->state = 0;
+ ds->br.cache_buffer = 0;
+ ds->br.cache_avail = 0;
+ ds->r0 = ds->r1 = ds->r2 = 1;
+
+ /* Initialize aligned offset tree. */
+ if (lzx_huffman_init(&(ds->at), 8, 8) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ /* Initialize pre-tree. */
+ if (lzx_huffman_init(&(ds->pt), 20, 10) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ /* Initialize Main tree. */
+ if (lzx_huffman_init(&(ds->mt), 256+(w_slot<<3), 16)
+ != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ /* Initialize Length tree. */
+ if (lzx_huffman_init(&(ds->lt), 249, 16) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ ds->error = 0;
+
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Release LZX decoder.
+ */
+static void
+lzx_decode_free(struct lzx_stream *strm)
+{
+
+ if (strm->ds == NULL)
+ return;
+ free(strm->ds->w_buff);
+ free(strm->ds->pos_tbl);
+ lzx_huffman_free(&(strm->ds->at));
+ lzx_huffman_free(&(strm->ds->pt));
+ lzx_huffman_free(&(strm->ds->mt));
+ lzx_huffman_free(&(strm->ds->lt));
+ free(strm->ds);
+ strm->ds = NULL;
+}
+
+/*
+ * E8 Call Translation reversal.
+ */
+static void
+lzx_translation(struct lzx_stream *strm, void *p, size_t size, uint32_t offset)
+{
+ struct lzx_dec *ds = strm->ds;
+ unsigned char *b, *end;
+
+ if (!ds->translation || size <= 10)
+ return;
+ b = p;
+ end = b + size - 10;
+ while (b < end && (b = memchr(b, 0xE8, end - b)) != NULL) {
+ size_t i = b - (unsigned char *)p;
+ long cp, displacement, value;
+
+ cp = offset + i;
+ value = archive_le32dec(&b[1]);
+ if (value >= -cp && value < (long)ds->translation_size) {
+ if (value >= 0)
+ displacement = value - cp;
+ else
+ displacement = value + ds->translation_size;
+ archive_le32enc(&b[1], (uint32_t)displacement);
+ }
+ b += 5;
+ }
+}
+
+/*
+ * Bit stream reader.
+ */
+/* Check that the cache buffer has enough bits. */
+#define lzx_br_has(br, n) ((br)->cache_avail >= n)
+/* Get compressed data by bit. */
+#define lzx_br_bits(br, n) \
+ (((uint32_t)((br)->cache_buffer >> \
+ ((br)->cache_avail - (n)))) & cache_masks[n])
+#define lzx_br_bits_forced(br, n) \
+ (((uint32_t)((br)->cache_buffer << \
+ ((n) - (br)->cache_avail))) & cache_masks[n])
+/* Read ahead to make sure the cache buffer has enough compressed data we
+ * will use.
+ * True : completed, there is enough data in the cache buffer.
+ * False : we met that strm->next_in is empty, we have to get following
+ * bytes. */
+#define lzx_br_read_ahead_0(strm, br, n) \
+ (lzx_br_has((br), (n)) || lzx_br_fillup(strm, br))
+/* True : the cache buffer has some bits as much as we need.
+ * False : there are no enough bits in the cache buffer to be used,
+ * we have to get following bytes if we could. */
+#define lzx_br_read_ahead(strm, br, n) \
+ (lzx_br_read_ahead_0((strm), (br), (n)) || lzx_br_has((br), (n)))
+
+/* Notify how many bits we consumed. */
+#define lzx_br_consume(br, n) ((br)->cache_avail -= (n))
+#define lzx_br_consume_unalined_bits(br) ((br)->cache_avail &= ~0x0f)
+
+static const uint32_t cache_masks[] = {
+ 0x00000000, 0x00000001, 0x00000003, 0x00000007,
+ 0x0000000F, 0x0000001F, 0x0000003F, 0x0000007F,
+ 0x000000FF, 0x000001FF, 0x000003FF, 0x000007FF,
+ 0x00000FFF, 0x00001FFF, 0x00003FFF, 0x00007FFF,
+ 0x0000FFFF, 0x0001FFFF, 0x0003FFFF, 0x0007FFFF,
+ 0x000FFFFF, 0x001FFFFF, 0x003FFFFF, 0x007FFFFF,
+ 0x00FFFFFF, 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF,
+ 0x0FFFFFFF, 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
+};
+
+/*
+ * Shift away used bits in the cache data and fill it up with following bits.
+ * Call this when cache buffer does not have enough bits you need.
+ *
+ * Returns 1 if the cache buffer is full.
+ * Returns 0 if the cache buffer is not full; input buffer is empty.
+ */
+static int
+lzx_br_fillup(struct lzx_stream *strm, struct lzx_br *br)
+{
+/*
+ * x86 proccessor family can read misaligned data without an access error.
+ */
+ int n = CACHE_BITS - br->cache_avail;
+
+ for (;;) {
+ switch (n >> 4) {
+ case 4:
+ if (strm->avail_in >= 8) {
+ br->cache_buffer =
+ ((uint64_t)strm->next_in[1]) << 56 |
+ ((uint64_t)strm->next_in[0]) << 48 |
+ ((uint64_t)strm->next_in[3]) << 40 |
+ ((uint64_t)strm->next_in[2]) << 32 |
+ ((uint32_t)strm->next_in[5]) << 24 |
+ ((uint32_t)strm->next_in[4]) << 16 |
+ ((uint32_t)strm->next_in[7]) << 8 |
+ (uint32_t)strm->next_in[6];
+ strm->next_in += 8;
+ strm->avail_in -= 8;
+ br->cache_avail += 8 * 8;
+ return (1);
+ }
+ break;
+ case 3:
+ if (strm->avail_in >= 6) {
+ br->cache_buffer =
+ (br->cache_buffer << 48) |
+ ((uint64_t)strm->next_in[1]) << 40 |
+ ((uint64_t)strm->next_in[0]) << 32 |
+ ((uint32_t)strm->next_in[3]) << 24 |
+ ((uint32_t)strm->next_in[2]) << 16 |
+ ((uint32_t)strm->next_in[5]) << 8 |
+ (uint32_t)strm->next_in[4];
+ strm->next_in += 6;
+ strm->avail_in -= 6;
+ br->cache_avail += 6 * 8;
+ return (1);
+ }
+ break;
+ case 0:
+ /* We have enough compressed data in
+ * the cache buffer.*/
+ return (1);
+ default:
+ break;
+ }
+ if (strm->avail_in < 2) {
+ /* There is not enough compressed data to
+ * fill up the cache buffer. */
+ if (strm->avail_in == 1) {
+ br->odd = *strm->next_in++;
+ strm->avail_in--;
+ br->have_odd = 1;
+ }
+ return (0);
+ }
+ br->cache_buffer =
+ (br->cache_buffer << 16) |
+ archive_le16dec(strm->next_in);
+ strm->next_in += 2;
+ strm->avail_in -= 2;
+ br->cache_avail += 16;
+ n -= 16;
+ }
+}
+
+static void
+lzx_br_fixup(struct lzx_stream *strm, struct lzx_br *br)
+{
+ int n = CACHE_BITS - br->cache_avail;
+
+ if (br->have_odd && n >= 16 && strm->avail_in > 0) {
+ br->cache_buffer =
+ (br->cache_buffer << 16) |
+ ((uint16_t)(*strm->next_in)) << 8 | br->odd;
+ strm->next_in++;
+ strm->avail_in--;
+ br->cache_avail += 16;
+ br->have_odd = 0;
+ }
+}
+
+static void
+lzx_cleanup_bitstream(struct lzx_stream *strm)
+{
+ strm->ds->br.cache_avail = 0;
+ strm->ds->br.have_odd = 0;
+}
+
+/*
+ * Decode LZX.
+ *
+ * 1. Returns ARCHIVE_OK if output buffer or input buffer are empty.
+ * Please set available buffer and call this function again.
+ * 2. Returns ARCHIVE_EOF if decompression has been completed.
+ * 3. Returns ARCHIVE_FAILED if an error occurred; compressed data
+ * is broken or you do not set 'last' flag properly.
+ */
+#define ST_RD_TRANSLATION 0
+#define ST_RD_TRANSLATION_SIZE 1
+#define ST_RD_BLOCK_TYPE 2
+#define ST_RD_BLOCK_SIZE 3
+#define ST_RD_R0 4
+#define ST_RD_R1 5
+#define ST_RD_R2 6
+#define ST_COPY_UNCOMP1 7
+#define ST_COPY_UNCOMP2 8
+#define ST_RD_ALIGNED_OFFSET 9
+#define ST_RD_VERBATIM 10
+#define ST_RD_PRE_MAIN_TREE_256 11
+#define ST_MAIN_TREE_256 12
+#define ST_RD_PRE_MAIN_TREE_REM 13
+#define ST_MAIN_TREE_REM 14
+#define ST_RD_PRE_LENGTH_TREE 15
+#define ST_LENGTH_TREE 16
+#define ST_MAIN 17
+#define ST_LENGTH 18
+#define ST_OFFSET 19
+#define ST_REAL_POS 20
+#define ST_COPY 21
+
+static int
+lzx_decode(struct lzx_stream *strm, int last)
+{
+ struct lzx_dec *ds = strm->ds;
+ int64_t avail_in;
+ int r;
+
+ if (ds->error)
+ return (ds->error);
+
+ avail_in = strm->avail_in;
+ lzx_br_fixup(strm, &(ds->br));
+ do {
+ if (ds->state < ST_MAIN)
+ r = lzx_read_blocks(strm, last);
+ else {
+ int64_t bytes_written = strm->avail_out;
+ r = lzx_decode_blocks(strm, last);
+ bytes_written -= strm->avail_out;
+ strm->next_out += bytes_written;
+ strm->total_out += bytes_written;
+ }
+ } while (r == 100);
+ strm->total_in += avail_in - strm->avail_in;
+ return (r);
+}
+
+static int
+lzx_read_blocks(struct lzx_stream *strm, int last)
+{
+ struct lzx_dec *ds = strm->ds;
+ struct lzx_br *br = &(ds->br);
+ int i, r;
+
+ for (;;) {
+ switch (ds->state) {
+ case ST_RD_TRANSLATION:
+ if (!lzx_br_read_ahead(strm, br, 1)) {
+ ds->state = ST_RD_TRANSLATION;
+ if (last)
+ goto failed;
+ return (ARCHIVE_OK);
+ }
+ ds->translation = lzx_br_bits(br, 1);
+ lzx_br_consume(br, 1);
+ /* FALL THROUGH */
+ case ST_RD_TRANSLATION_SIZE:
+ if (ds->translation) {
+ if (!lzx_br_read_ahead(strm, br, 32)) {
+ ds->state = ST_RD_TRANSLATION_SIZE;
+ if (last)
+ goto failed;
+ return (ARCHIVE_OK);
+ }
+ ds->translation_size = lzx_br_bits(br, 16);
+ lzx_br_consume(br, 16);
+ ds->translation_size <<= 16;
+ ds->translation_size |= lzx_br_bits(br, 16);
+ lzx_br_consume(br, 16);
+ }
+ /* FALL THROUGH */
+ case ST_RD_BLOCK_TYPE:
+ if (!lzx_br_read_ahead(strm, br, 3)) {
+ ds->state = ST_RD_BLOCK_TYPE;
+ if (last)
+ goto failed;
+ return (ARCHIVE_OK);
+ }
+ ds->block_type = lzx_br_bits(br, 3);
+ lzx_br_consume(br, 3);
+ /* Check a block type. */
+ switch (ds->block_type) {
+ case VERBATIM_BLOCK:
+ case ALIGNED_OFFSET_BLOCK:
+ case UNCOMPRESSED_BLOCK:
+ break;
+ default:
+ goto failed;/* Invalid */
+ }
+ /* FALL THROUGH */
+ case ST_RD_BLOCK_SIZE:
+ if (!lzx_br_read_ahead(strm, br, 24)) {
+ ds->state = ST_RD_BLOCK_SIZE;
+ if (last)
+ goto failed;
+ return (ARCHIVE_OK);
+ }
+ ds->block_size = lzx_br_bits(br, 8);
+ lzx_br_consume(br, 8);
+ ds->block_size <<= 16;
+ ds->block_size |= lzx_br_bits(br, 16);
+ lzx_br_consume(br, 16);
+ if (ds->block_size == 0)
+ goto failed;
+ ds->block_bytes_avail = ds->block_size;
+ if (ds->block_type != UNCOMPRESSED_BLOCK) {
+ if (ds->block_type == VERBATIM_BLOCK)
+ ds->state = ST_RD_VERBATIM;
+ else
+ ds->state = ST_RD_ALIGNED_OFFSET;
+ break;
+ }
+ /*
+ * Handle an Uncompressed Block.
+ */
+ /* Skip padding to align following field on
+ * 16-bit boundary. */
+ lzx_br_consume_unalined_bits(br);
+ /* Preparation to read repeated offsets R0,R1 and R2. */
+ ds->rbytes_avail = 0;
+ ds->state = ST_RD_R0;
+ /* FALL THROUGH */
+ case ST_RD_R0:
+ case ST_RD_R1:
+ case ST_RD_R2:
+ do {
+ uint16_t u16;
+ /* Drain bits in the cache buffer of
+ * bit-stream. */
+ if (lzx_br_has(br, 32)) {
+ u16 = lzx_br_bits(br, 16);
+ lzx_br_consume(br, 16);
+ archive_le16enc(ds->rbytes, u16);
+ u16 = lzx_br_bits(br, 16);
+ lzx_br_consume(br, 16);
+ archive_le16enc(ds->rbytes+2, u16);
+ ds->rbytes_avail = 4;
+ } else if (lzx_br_has(br, 16)) {
+ u16 = lzx_br_bits(br, 16);
+ lzx_br_consume(br, 16);
+ archive_le16enc(ds->rbytes, u16);
+ ds->rbytes_avail = 2;
+ } else
+ ds->rbytes_avail = 0;
+ if (ds->rbytes_avail < 4 && ds->br.have_odd) {
+ ds->rbytes[ds->rbytes_avail++] =
+ ds->br.odd;
+ ds->br.have_odd = 0;
+ }
+ while (ds->rbytes_avail < 4) {
+ if (strm->avail_in <= 0) {
+ if (last)
+ goto failed;
+ return (ARCHIVE_OK);
+ }
+ ds->rbytes[ds->rbytes_avail++] =
+ *strm->next_in++;
+ strm->avail_in--;
+ }
+ if (ds->state == ST_RD_R0) {
+ ds->r0 = archive_le32dec(ds->rbytes);
+ if (ds->r0 < 0)
+ goto failed;
+ ds->state = ST_RD_R1;
+ } else if (ds->state == ST_RD_R1) {
+ ds->r1 = archive_le32dec(ds->rbytes);
+ if (ds->r1 < 0)
+ goto failed;
+ ds->state = ST_RD_R2;
+ } else if (ds->state == ST_RD_R2) {
+ ds->r2 = archive_le32dec(ds->rbytes);
+ if (ds->r2 < 0)
+ goto failed;
+ /* We've gotten all repeated offsets. */
+ ds->state = ST_COPY_UNCOMP1;
+ }
+ } while (ds->state != ST_COPY_UNCOMP1);
+ /* FALL THROUGH */
+ case ST_COPY_UNCOMP1:
+ /*
+ * Copy bytes form next_in to next_out directly.
+ */
+ while (ds->block_bytes_avail) {
+ unsigned char *d;
+ int l,ll;
+
+ if (strm->avail_out <= 0)
+ /* Output buffer is empty. */
+ return (ARCHIVE_OK);
+ if (strm->avail_in <= 0) {
+ /* Input buffer is empty. */
+ if (last)
+ goto failed;
+ return (ARCHIVE_OK);
+ }
+ l = ds->block_bytes_avail;
+ if (l > ds->w_size - ds->w_pos)
+ l = ds->w_size - ds->w_pos;
+ if (l > strm->avail_out)
+ l = (int)strm->avail_out;
+ if (l > strm->avail_in)
+ l = (int)strm->avail_in;
+ ll = l;
+ d = &(ds->w_buff[ds->w_pos]);
+ while (--l >= 0) {
+ *strm->next_out++ = *strm->next_in;
+ *d++ = *strm->next_in++;
+ }
+ strm->avail_out -= ll;
+ strm->total_out += ll;
+ strm->avail_in -= ll;
+ ds->w_pos = (ds->w_pos + ll) & ds->w_mask;
+ ds->block_bytes_avail -= ll;
+ }
+ /* FALL THROUGH */
+ case ST_COPY_UNCOMP2:
+ /* Re-align; skip padding byte. */
+ if (ds->block_size & 1) {
+ if (strm->avail_in <= 0) {
+ /* Input buffer is empty. */
+ ds->state = ST_COPY_UNCOMP2;
+ if (last)
+ goto failed;
+ return (ARCHIVE_OK);
+ }
+ strm->next_in++;
+ strm->avail_in --;
+ }
+ /* This block ended. */
+ ds->state = ST_RD_BLOCK_TYPE;
+ return (ARCHIVE_EOF);
+ /********************/
+ case ST_RD_ALIGNED_OFFSET:
+ /*
+ * Read Aligned offset tree.
+ */
+ if (!lzx_br_read_ahead(strm, br, 3 * ds->at.len_size)) {
+ ds->state = ST_RD_ALIGNED_OFFSET;
+ if (last)
+ goto failed;
+ return (ARCHIVE_OK);
+ }
+ memset(ds->at.freq, 0, sizeof(ds->at.freq));
+ for (i = 0; i < ds->at.len_size; i++) {
+ ds->at.bitlen[i] = lzx_br_bits(br, 3);
+ ds->at.freq[ds->at.bitlen[i]]++;
+ lzx_br_consume(br, 3);
+ }
+ if (!lzx_make_huffman_table(&ds->at))
+ goto failed;
+ /* FALL THROUGH */
+ case ST_RD_VERBATIM:
+ ds->loop = 0;
+ /* FALL THROUGH */
+ case ST_RD_PRE_MAIN_TREE_256:
+ /*
+ * Read Pre-tree for first 256 elements of main tree.
+ */
+ if (!lzx_read_pre_tree(strm)) {
+ ds->state = ST_RD_PRE_MAIN_TREE_256;
+ if (last)
+ goto failed;
+ return (ARCHIVE_OK);
+ }
+ if (!lzx_make_huffman_table(&ds->pt))
+ goto failed;
+ ds->loop = 0;
+ /* FALL THROUGH */
+ case ST_MAIN_TREE_256:
+ /*
+ * Get path lengths of first 256 elements of main tree.
+ */
+ r = lzx_read_bitlen(strm, &ds->mt, 256);
+ if (r < 0)
+ goto failed;
+ else if (!r) {
+ ds->state = ST_MAIN_TREE_256;
+ if (last)
+ goto failed;
+ return (ARCHIVE_OK);
+ }
+ ds->loop = 0;
+ /* FALL THROUGH */
+ case ST_RD_PRE_MAIN_TREE_REM:
+ /*
+ * Read Pre-tree for remaining elements of main tree.
+ */
+ if (!lzx_read_pre_tree(strm)) {
+ ds->state = ST_RD_PRE_MAIN_TREE_REM;
+ if (last)
+ goto failed;
+ return (ARCHIVE_OK);
+ }
+ if (!lzx_make_huffman_table(&ds->pt))
+ goto failed;
+ ds->loop = 256;
+ /* FALL THROUGH */
+ case ST_MAIN_TREE_REM:
+ /*
+ * Get path lengths of remaining elements of main tree.
+ */
+ r = lzx_read_bitlen(strm, &ds->mt, -1);
+ if (r < 0)
+ goto failed;
+ else if (!r) {
+ ds->state = ST_MAIN_TREE_REM;
+ if (last)
+ goto failed;
+ return (ARCHIVE_OK);
+ }
+ if (!lzx_make_huffman_table(&ds->mt))
+ goto failed;
+ ds->loop = 0;
+ /* FALL THROUGH */
+ case ST_RD_PRE_LENGTH_TREE:
+ /*
+ * Read Pre-tree for remaining elements of main tree.
+ */
+ if (!lzx_read_pre_tree(strm)) {
+ ds->state = ST_RD_PRE_LENGTH_TREE;
+ if (last)
+ goto failed;
+ return (ARCHIVE_OK);
+ }
+ if (!lzx_make_huffman_table(&ds->pt))
+ goto failed;
+ ds->loop = 0;
+ /* FALL THROUGH */
+ case ST_LENGTH_TREE:
+ /*
+ * Get path lengths of remaining elements of main tree.
+ */
+ r = lzx_read_bitlen(strm, &ds->lt, -1);
+ if (r < 0)
+ goto failed;
+ else if (!r) {
+ ds->state = ST_LENGTH_TREE;
+ if (last)
+ goto failed;
+ return (ARCHIVE_OK);
+ }
+ if (!lzx_make_huffman_table(&ds->lt))
+ goto failed;
+ ds->state = ST_MAIN;
+ return (100);
+ }
+ }
+failed:
+ return (ds->error = ARCHIVE_FAILED);
+}
+
+static int
+lzx_decode_blocks(struct lzx_stream *strm, int last)
+{
+ struct lzx_dec *ds = strm->ds;
+ struct lzx_br bre = ds->br;
+ struct huffman *at = &(ds->at), *lt = &(ds->lt), *mt = &(ds->mt);
+ const struct lzx_pos_tbl *pos_tbl = ds->pos_tbl;
+ unsigned char *outp = strm->next_out;
+ unsigned char *endp = outp + strm->avail_out;
+ unsigned char *w_buff = ds->w_buff;
+ unsigned char *at_bitlen = at->bitlen;
+ unsigned char *lt_bitlen = lt->bitlen;
+ unsigned char *mt_bitlen = mt->bitlen;
+ size_t block_bytes_avail = ds->block_bytes_avail;
+ int at_max_bits = at->max_bits;
+ int lt_max_bits = lt->max_bits;
+ int mt_max_bits = mt->max_bits;
+ int c, copy_len = ds->copy_len, copy_pos = ds->copy_pos;
+ int w_pos = ds->w_pos, w_mask = ds->w_mask, w_size = ds->w_size;
+ int length_header = ds->length_header;
+ int offset_bits = ds->offset_bits;
+ int position_slot = ds->position_slot;
+ int r0 = ds->r0, r1 = ds->r1, r2 = ds->r2;
+ int state = ds->state;
+ char block_type = ds->block_type;
+
+ for (;;) {
+ switch (state) {
+ case ST_MAIN:
+ for (;;) {
+ if (block_bytes_avail == 0) {
+ /* This block ended. */
+ ds->state = ST_RD_BLOCK_TYPE;
+ ds->br = bre;
+ ds->block_bytes_avail =
+ block_bytes_avail;
+ ds->copy_len = copy_len;
+ ds->copy_pos = copy_pos;
+ ds->length_header = length_header;
+ ds->position_slot = position_slot;
+ ds->r0 = r0; ds->r1 = r1; ds->r2 = r2;
+ ds->w_pos = w_pos;
+ strm->avail_out = endp - outp;
+ return (ARCHIVE_EOF);
+ }
+ if (outp >= endp)
+ /* Output buffer is empty. */
+ goto next_data;
+
+ if (!lzx_br_read_ahead(strm, &bre,
+ mt_max_bits)) {
+ if (!last)
+ goto next_data;
+ /* Remaining bits are less than
+ * maximum bits(mt.max_bits) but maybe
+ * it still remains as much as we need,
+ * so we should try to use it with
+ * dummy bits. */
+ c = lzx_decode_huffman(mt,
+ lzx_br_bits_forced(
+ &bre, mt_max_bits));
+ lzx_br_consume(&bre, mt_bitlen[c]);
+ if (!lzx_br_has(&bre, 0))
+ goto failed;/* Over read. */
+ } else {
+ c = lzx_decode_huffman(mt,
+ lzx_br_bits(&bre, mt_max_bits));
+ lzx_br_consume(&bre, mt_bitlen[c]);
+ }
+ if (c > UCHAR_MAX)
+ break;
+ /*
+ * 'c' is exactly literal code.
+ */
+ /* Save a decoded code to reference it
+ * afterward. */
+ w_buff[w_pos] = c;
+ w_pos = (w_pos + 1) & w_mask;
+ /* Store the decoded code to output buffer. */
+ *outp++ = c;
+ block_bytes_avail--;
+ }
+ /*
+ * Get a match code, its length and offset.
+ */
+ c -= UCHAR_MAX + 1;
+ length_header = c & 7;
+ position_slot = c >> 3;
+ /* FALL THROUGH */
+ case ST_LENGTH:
+ /*
+ * Get a length.
+ */
+ if (length_header == 7) {
+ if (!lzx_br_read_ahead(strm, &bre,
+ lt_max_bits)) {
+ if (!last) {
+ state = ST_LENGTH;
+ goto next_data;
+ }
+ c = lzx_decode_huffman(lt,
+ lzx_br_bits_forced(
+ &bre, lt_max_bits));
+ lzx_br_consume(&bre, lt_bitlen[c]);
+ if (!lzx_br_has(&bre, 0))
+ goto failed;/* Over read. */
+ } else {
+ c = lzx_decode_huffman(lt,
+ lzx_br_bits(&bre, lt_max_bits));
+ lzx_br_consume(&bre, lt_bitlen[c]);
+ }
+ copy_len = c + 7 + 2;
+ } else
+ copy_len = length_header + 2;
+ if ((size_t)copy_len > block_bytes_avail)
+ goto failed;
+ /*
+ * Get an offset.
+ */
+ switch (position_slot) {
+ case 0: /* Use repeated offset 0. */
+ copy_pos = r0;
+ state = ST_REAL_POS;
+ continue;
+ case 1: /* Use repeated offset 1. */
+ copy_pos = r1;
+ /* Swap repeated offset. */
+ r1 = r0;
+ r0 = copy_pos;
+ state = ST_REAL_POS;
+ continue;
+ case 2: /* Use repeated offset 2. */
+ copy_pos = r2;
+ /* Swap repeated offset. */
+ r2 = r0;
+ r0 = copy_pos;
+ state = ST_REAL_POS;
+ continue;
+ default:
+ offset_bits =
+ pos_tbl[position_slot].footer_bits;
+ break;
+ }
+ /* FALL THROUGH */
+ case ST_OFFSET:
+ /*
+ * Get the offset, which is a distance from
+ * current window position.
+ */
+ if (block_type == ALIGNED_OFFSET_BLOCK &&
+ offset_bits >= 3) {
+ int offbits = offset_bits - 3;
+
+ if (!lzx_br_read_ahead(strm, &bre, offbits)) {
+ state = ST_OFFSET;
+ if (last)
+ goto failed;
+ goto next_data;
+ }
+ copy_pos = lzx_br_bits(&bre, offbits) << 3;
+
+ /* Get an aligned number. */
+ if (!lzx_br_read_ahead(strm, &bre,
+ offbits + at_max_bits)) {
+ if (!last) {
+ state = ST_OFFSET;
+ goto next_data;
+ }
+ lzx_br_consume(&bre, offbits);
+ c = lzx_decode_huffman(at,
+ lzx_br_bits_forced(&bre,
+ at_max_bits));
+ lzx_br_consume(&bre, at_bitlen[c]);
+ if (!lzx_br_has(&bre, 0))
+ goto failed;/* Over read. */
+ } else {
+ lzx_br_consume(&bre, offbits);
+ c = lzx_decode_huffman(at,
+ lzx_br_bits(&bre, at_max_bits));
+ lzx_br_consume(&bre, at_bitlen[c]);
+ }
+ /* Add an aligned number. */
+ copy_pos += c;
+ } else {
+ if (!lzx_br_read_ahead(strm, &bre,
+ offset_bits)) {
+ state = ST_OFFSET;
+ if (last)
+ goto failed;
+ goto next_data;
+ }
+ copy_pos = lzx_br_bits(&bre, offset_bits);
+ lzx_br_consume(&bre, offset_bits);
+ }
+ copy_pos += pos_tbl[position_slot].base -2;
+
+ /* Update repeated offset LRU queue. */
+ r2 = r1;
+ r1 = r0;
+ r0 = copy_pos;
+ /* FALL THROUGH */
+ case ST_REAL_POS:
+ /*
+ * Compute a real position in window.
+ */
+ copy_pos = (w_pos - copy_pos) & w_mask;
+ /* FALL THROUGH */
+ case ST_COPY:
+ /*
+ * Copy several bytes as extracted data from the window
+ * into the output buffer.
+ */
+ for (;;) {
+ const unsigned char *s;
+ int l;
+
+ l = copy_len;
+ if (copy_pos > w_pos) {
+ if (l > w_size - copy_pos)
+ l = w_size - copy_pos;
+ } else {
+ if (l > w_size - w_pos)
+ l = w_size - w_pos;
+ }
+ if (outp + l >= endp)
+ l = endp - outp;
+ s = w_buff + copy_pos;
+ if (l >= 8 && ((copy_pos + l < w_pos)
+ || (w_pos + l < copy_pos))) {
+ memcpy(w_buff + w_pos, s, l);
+ memcpy(outp, s, l);
+ } else {
+ unsigned char *d;
+ int li;
+
+ d = w_buff + w_pos;
+ for (li = 0; li < l; li++)
+ outp[li] = d[li] = s[li];
+ }
+ outp += l;
+ copy_pos = (copy_pos + l) & w_mask;
+ w_pos = (w_pos + l) & w_mask;
+ block_bytes_avail -= l;
+ if (copy_len <= l)
+ /* A copy of current pattern ended. */
+ break;
+ copy_len -= l;
+ if (outp >= endp) {
+ /* Output buffer is empty. */
+ state = ST_COPY;
+ goto next_data;
+ }
+ }
+ state = ST_MAIN;
+ break;
+ }
+ }
+failed:
+ return (ds->error = ARCHIVE_FAILED);
+next_data:
+ ds->br = bre;
+ ds->block_bytes_avail = block_bytes_avail;
+ ds->copy_len = copy_len;
+ ds->copy_pos = copy_pos;
+ ds->length_header = length_header;
+ ds->offset_bits = offset_bits;
+ ds->position_slot = position_slot;
+ ds->r0 = r0; ds->r1 = r1; ds->r2 = r2;
+ ds->state = state;
+ ds->w_pos = w_pos;
+ strm->avail_out = endp - outp;
+ return (ARCHIVE_OK);
+}
+
+static int
+lzx_read_pre_tree(struct lzx_stream *strm)
+{
+ struct lzx_dec *ds = strm->ds;
+ struct lzx_br *br = &(ds->br);
+ int i;
+
+ if (ds->loop == 0)
+ memset(ds->pt.freq, 0, sizeof(ds->pt.freq));
+ for (i = ds->loop; i < ds->pt.len_size; i++) {
+ if (!lzx_br_read_ahead(strm, br, 4)) {
+ ds->loop = i;
+ return (0);
+ }
+ ds->pt.bitlen[i] = lzx_br_bits(br, 4);
+ ds->pt.freq[ds->pt.bitlen[i]]++;
+ lzx_br_consume(br, 4);
+ }
+ ds->loop = i;
+ return (1);
+}
+
+/*
+ * Read a bunch of bit-lengths from pre-tree.
+ */
+static int
+lzx_read_bitlen(struct lzx_stream *strm, struct huffman *d, int end)
+{
+ struct lzx_dec *ds = strm->ds;
+ struct lzx_br *br = &(ds->br);
+ int c, i, j, ret, same;
+ unsigned rbits;
+
+ i = ds->loop;
+ if (i == 0)
+ memset(d->freq, 0, sizeof(d->freq));
+ ret = 0;
+ if (end < 0)
+ end = d->len_size;
+ while (i < end) {
+ ds->loop = i;
+ if (!lzx_br_read_ahead(strm, br, ds->pt.max_bits))
+ goto getdata;
+ rbits = lzx_br_bits(br, ds->pt.max_bits);
+ c = lzx_decode_huffman(&(ds->pt), rbits);
+ switch (c) {
+ case 17:/* several zero lengths, from 4 to 19. */
+ if (!lzx_br_read_ahead(strm, br, ds->pt.bitlen[c]+4))
+ goto getdata;
+ lzx_br_consume(br, ds->pt.bitlen[c]);
+ same = lzx_br_bits(br, 4) + 4;
+ if (i + same > end)
+ return (-1);/* Invalid */
+ lzx_br_consume(br, 4);
+ for (j = 0; j < same; j++)
+ d->bitlen[i++] = 0;
+ break;
+ case 18:/* many zero lengths, from 20 to 51. */
+ if (!lzx_br_read_ahead(strm, br, ds->pt.bitlen[c]+5))
+ goto getdata;
+ lzx_br_consume(br, ds->pt.bitlen[c]);
+ same = lzx_br_bits(br, 5) + 20;
+ if (i + same > end)
+ return (-1);/* Invalid */
+ lzx_br_consume(br, 5);
+ memset(d->bitlen + i, 0, same);
+ i += same;
+ break;
+ case 19:/* a few same lengths. */
+ if (!lzx_br_read_ahead(strm, br,
+ ds->pt.bitlen[c]+1+ds->pt.max_bits))
+ goto getdata;
+ lzx_br_consume(br, ds->pt.bitlen[c]);
+ same = lzx_br_bits(br, 1) + 4;
+ if (i + same > end)
+ return (-1);
+ lzx_br_consume(br, 1);
+ rbits = lzx_br_bits(br, ds->pt.max_bits);
+ c = lzx_decode_huffman(&(ds->pt), rbits);
+ lzx_br_consume(br, ds->pt.bitlen[c]);
+ c = (d->bitlen[i] - c + 17) % 17;
+ if (c < 0)
+ return (-1);/* Invalid */
+ for (j = 0; j < same; j++)
+ d->bitlen[i++] = c;
+ d->freq[c] += same;
+ break;
+ default:
+ lzx_br_consume(br, ds->pt.bitlen[c]);
+ c = (d->bitlen[i] - c + 17) % 17;
+ if (c < 0)
+ return (-1);/* Invalid */
+ d->freq[c]++;
+ d->bitlen[i++] = c;
+ break;
+ }
+ }
+ ret = 1;
+getdata:
+ ds->loop = i;
+ return (ret);
+}
+
+static int
+lzx_huffman_init(struct huffman *hf, size_t len_size, int tbl_bits)
+{
+ int bits;
+
+ if (hf->bitlen == NULL || hf->len_size != (int)len_size) {
+ free(hf->bitlen);
+ hf->bitlen = calloc(len_size, sizeof(hf->bitlen[0]));
+ if (hf->bitlen == NULL)
+ return (ARCHIVE_FATAL);
+ hf->len_size = len_size;
+ } else
+ memset(hf->bitlen, 0, len_size * sizeof(hf->bitlen[0]));
+ if (hf->tbl == NULL) {
+ if (tbl_bits < HTBL_BITS)
+ bits = tbl_bits;
+ else
+ bits = HTBL_BITS;
+ hf->tbl = malloc((1 << bits) * sizeof(hf->tbl[0]));
+ if (hf->tbl == NULL)
+ return (ARCHIVE_FATAL);
+ hf->tbl_bits = tbl_bits;
+ }
+ if (hf->tree == NULL && tbl_bits > HTBL_BITS) {
+ hf->tree_avail = 1 << (tbl_bits - HTBL_BITS + 4);
+ hf->tree = malloc(hf->tree_avail * sizeof(hf->tree[0]));
+ if (hf->tree == NULL)
+ return (ARCHIVE_FATAL);
+ }
+ return (ARCHIVE_OK);
+}
+
+static void
+lzx_huffman_free(struct huffman *hf)
+{
+ free(hf->bitlen);
+ free(hf->tbl);
+ free(hf->tree);
+}
+
+/*
+ * Make a huffman coding table.
+ */
+static int
+lzx_make_huffman_table(struct huffman *hf)
+{
+ uint16_t *tbl;
+ const unsigned char *bitlen;
+ int bitptn[17], weight[17];
+ int i, maxbits = 0, ptn, tbl_size, w;
+ int diffbits, len_avail;
+
+ /*
+ * Initialize bit patterns.
+ */
+ ptn = 0;
+ for (i = 1, w = 1 << 15; i <= 16; i++, w >>= 1) {
+ bitptn[i] = ptn;
+ weight[i] = w;
+ if (hf->freq[i]) {
+ ptn += hf->freq[i] * w;
+ maxbits = i;
+ }
+ }
+ if ((ptn & 0xffff) != 0 || maxbits > hf->tbl_bits)
+ return (0);/* Invalid */
+
+ hf->max_bits = maxbits;
+
+ /*
+ * Cut out extra bits which we won't house in the table.
+ * This preparation reduces the same calculation in the for-loop
+ * making the table.
+ */
+ if (maxbits < 16) {
+ int ebits = 16 - maxbits;
+ for (i = 1; i <= maxbits; i++) {
+ bitptn[i] >>= ebits;
+ weight[i] >>= ebits;
+ }
+ }
+ if (maxbits > HTBL_BITS) {
+ int htbl_max;
+ uint16_t *p;
+
+ diffbits = maxbits - HTBL_BITS;
+ for (i = 1; i <= HTBL_BITS; i++) {
+ bitptn[i] >>= diffbits;
+ weight[i] >>= diffbits;
+ }
+ htbl_max = bitptn[HTBL_BITS] +
+ weight[HTBL_BITS] * hf->freq[HTBL_BITS];
+ p = &(hf->tbl[htbl_max]);
+ while (p < &hf->tbl[1U<<HTBL_BITS])
+ *p++ = 0;
+ } else
+ diffbits = 0;
+ hf->shift_bits = diffbits;
+
+ /*
+ * Make the table.
+ */
+ tbl_size = 1 << HTBL_BITS;
+ tbl = hf->tbl;
+ bitlen = hf->bitlen;
+ len_avail = hf->len_size;
+ hf->tree_used = 0;
+ for (i = 0; i < len_avail; i++) {
+ uint16_t *p;
+ int len, cnt;
+ uint16_t bit;
+ int extlen;
+ struct htree_t *ht;
+
+ if (bitlen[i] == 0)
+ continue;
+ /* Get a bit pattern */
+ len = bitlen[i];
+ ptn = bitptn[len];
+ cnt = weight[len];
+ if (len <= HTBL_BITS) {
+ /* Calculate next bit pattern */
+ if ((bitptn[len] = ptn + cnt) > tbl_size)
+ return (0);/* Invalid */
+ /* Update the table */
+ p = &(tbl[ptn]);
+ while (--cnt >= 0)
+ p[cnt] = (uint16_t)i;
+ continue;
+ }
+
+ /*
+ * A bit length is too big to be housed to a direct table,
+ * so we use a tree model for its extra bits.
+ */
+ bitptn[len] = ptn + cnt;
+ bit = 1U << (diffbits -1);
+ extlen = len - HTBL_BITS;
+
+ p = &(tbl[ptn >> diffbits]);
+ if (*p == 0) {
+ *p = len_avail + hf->tree_used;
+ ht = &(hf->tree[hf->tree_used++]);
+ if (hf->tree_used > hf->tree_avail)
+ return (0);/* Invalid */
+ ht->left = 0;
+ ht->right = 0;
+ } else {
+ if (*p < len_avail ||
+ *p >= (len_avail + hf->tree_used))
+ return (0);/* Invalid */
+ ht = &(hf->tree[*p - len_avail]);
+ }
+ while (--extlen > 0) {
+ if (ptn & bit) {
+ if (ht->left < len_avail) {
+ ht->left = len_avail + hf->tree_used;
+ ht = &(hf->tree[hf->tree_used++]);
+ if (hf->tree_used > hf->tree_avail)
+ return (0);/* Invalid */
+ ht->left = 0;
+ ht->right = 0;
+ } else {
+ ht = &(hf->tree[ht->left - len_avail]);
+ }
+ } else {
+ if (ht->right < len_avail) {
+ ht->right = len_avail + hf->tree_used;
+ ht = &(hf->tree[hf->tree_used++]);
+ if (hf->tree_used > hf->tree_avail)
+ return (0);/* Invalid */
+ ht->left = 0;
+ ht->right = 0;
+ } else {
+ ht = &(hf->tree[ht->right - len_avail]);
+ }
+ }
+ bit >>= 1;
+ }
+ if (ptn & bit) {
+ if (ht->left != 0)
+ return (0);/* Invalid */
+ ht->left = (uint16_t)i;
+ } else {
+ if (ht->right != 0)
+ return (0);/* Invalid */
+ ht->right = (uint16_t)i;
+ }
+ }
+ return (1);
+}
+
+static int
+lzx_decode_huffman_tree(struct huffman *hf, unsigned rbits, int c)
+{
+ struct htree_t *ht;
+ int extlen;
+
+ ht = hf->tree;
+ extlen = hf->shift_bits;
+ while (c >= hf->len_size) {
+ c -= hf->len_size;
+ if (extlen-- <= 0 || c >= hf->tree_used)
+ return (0);
+ if (rbits & (1U << extlen))
+ c = ht[c].left;
+ else
+ c = ht[c].right;
+ }
+ return (c);
+}
+
+static inline int
+lzx_decode_huffman(struct huffman *hf, unsigned rbits)
+{
+ int c;
+ /*
+ * At first search an index table for a bit pattern.
+ * If it fails, search a huffman tree for.
+ */
+ c = hf->tbl[rbits >> hf->shift_bits];
+ if (c < hf->len_size)
+ return (c);
+ /* This bit pattern needs to be found out at a huffman tree. */
+ return (lzx_decode_huffman_tree(hf, rbits, c));
+}
+
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_cpio.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_cpio.c
new file mode 100644
index 000000000..5ae73d770
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_cpio.c
@@ -0,0 +1,1048 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2010-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"
+__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_cpio.c 201163 2009-12-29 05:50:34Z kientzle $");
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+/* #include <stdint.h> */ /* See archive_platform.h */
+#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_entry_locale.h"
+#include "archive_private.h"
+#include "archive_read_private.h"
+
+#define bin_magic_offset 0
+#define bin_magic_size 2
+#define bin_dev_offset 2
+#define bin_dev_size 2
+#define bin_ino_offset 4
+#define bin_ino_size 2
+#define bin_mode_offset 6
+#define bin_mode_size 2
+#define bin_uid_offset 8
+#define bin_uid_size 2
+#define bin_gid_offset 10
+#define bin_gid_size 2
+#define bin_nlink_offset 12
+#define bin_nlink_size 2
+#define bin_rdev_offset 14
+#define bin_rdev_size 2
+#define bin_mtime_offset 16
+#define bin_mtime_size 4
+#define bin_namesize_offset 20
+#define bin_namesize_size 2
+#define bin_filesize_offset 22
+#define bin_filesize_size 4
+#define bin_header_size 26
+
+#define odc_magic_offset 0
+#define odc_magic_size 6
+#define odc_dev_offset 6
+#define odc_dev_size 6
+#define odc_ino_offset 12
+#define odc_ino_size 6
+#define odc_mode_offset 18
+#define odc_mode_size 6
+#define odc_uid_offset 24
+#define odc_uid_size 6
+#define odc_gid_offset 30
+#define odc_gid_size 6
+#define odc_nlink_offset 36
+#define odc_nlink_size 6
+#define odc_rdev_offset 42
+#define odc_rdev_size 6
+#define odc_mtime_offset 48
+#define odc_mtime_size 11
+#define odc_namesize_offset 59
+#define odc_namesize_size 6
+#define odc_filesize_offset 65
+#define odc_filesize_size 11
+#define odc_header_size 76
+
+#define newc_magic_offset 0
+#define newc_magic_size 6
+#define newc_ino_offset 6
+#define newc_ino_size 8
+#define newc_mode_offset 14
+#define newc_mode_size 8
+#define newc_uid_offset 22
+#define newc_uid_size 8
+#define newc_gid_offset 30
+#define newc_gid_size 8
+#define newc_nlink_offset 38
+#define newc_nlink_size 8
+#define newc_mtime_offset 46
+#define newc_mtime_size 8
+#define newc_filesize_offset 54
+#define newc_filesize_size 8
+#define newc_devmajor_offset 62
+#define newc_devmajor_size 8
+#define newc_devminor_offset 70
+#define newc_devminor_size 8
+#define newc_rdevmajor_offset 78
+#define newc_rdevmajor_size 8
+#define newc_rdevminor_offset 86
+#define newc_rdevminor_size 8
+#define newc_namesize_offset 94
+#define newc_namesize_size 8
+#define newc_checksum_offset 102
+#define newc_checksum_size 8
+#define newc_header_size 110
+
+/*
+ * An afio large ASCII header, which they named itself.
+ * afio utility uses this header, if a file size is larger than 2G bytes
+ * or inode/uid/gid is bigger than 65535(0xFFFF) or mtime is bigger than
+ * 0x7fffffff, which we cannot record to odc header because of its limit.
+ * If not, uses odc header.
+ */
+#define afiol_magic_offset 0
+#define afiol_magic_size 6
+#define afiol_dev_offset 6
+#define afiol_dev_size 8 /* hex */
+#define afiol_ino_offset 14
+#define afiol_ino_size 16 /* hex */
+#define afiol_ino_m_offset 30 /* 'm' */
+#define afiol_mode_offset 31
+#define afiol_mode_size 6 /* oct */
+#define afiol_uid_offset 37
+#define afiol_uid_size 8 /* hex */
+#define afiol_gid_offset 45
+#define afiol_gid_size 8 /* hex */
+#define afiol_nlink_offset 53
+#define afiol_nlink_size 8 /* hex */
+#define afiol_rdev_offset 61
+#define afiol_rdev_size 8 /* hex */
+#define afiol_mtime_offset 69
+#define afiol_mtime_size 16 /* hex */
+#define afiol_mtime_n_offset 85 /* 'n' */
+#define afiol_namesize_offset 86
+#define afiol_namesize_size 4 /* hex */
+#define afiol_flag_offset 90
+#define afiol_flag_size 4 /* hex */
+#define afiol_xsize_offset 94
+#define afiol_xsize_size 4 /* hex */
+#define afiol_xsize_s_offset 98 /* 's' */
+#define afiol_filesize_offset 99
+#define afiol_filesize_size 16 /* hex */
+#define afiol_filesize_c_offset 115 /* ':' */
+#define afiol_header_size 116
+
+
+struct links_entry {
+ struct links_entry *next;
+ struct links_entry *previous;
+ int links;
+ dev_t dev;
+ int64_t ino;
+ char *name;
+};
+
+#define CPIO_MAGIC 0x13141516
+struct cpio {
+ int magic;
+ int (*read_header)(struct archive_read *, struct cpio *,
+ struct archive_entry *, size_t *, size_t *);
+ struct links_entry *links_head;
+ int64_t entry_bytes_remaining;
+ int64_t entry_bytes_unconsumed;
+ int64_t entry_offset;
+ int64_t entry_padding;
+
+ struct archive_string_conv *opt_sconv;
+ struct archive_string_conv *sconv_default;
+ int init_default_conversion;
+};
+
+static int64_t atol16(const char *, unsigned);
+static int64_t atol8(const char *, unsigned);
+static int archive_read_format_cpio_bid(struct archive_read *, int);
+static int archive_read_format_cpio_options(struct archive_read *,
+ const char *, const char *);
+static int archive_read_format_cpio_cleanup(struct archive_read *);
+static int archive_read_format_cpio_read_data(struct archive_read *,
+ const void **, size_t *, int64_t *);
+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 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 *,
+ struct archive_entry *, size_t *, size_t *);
+static int header_bin_le(struct archive_read *, struct cpio *,
+ struct archive_entry *, size_t *, size_t *);
+static int header_newc(struct archive_read *, struct cpio *,
+ struct archive_entry *, size_t *, size_t *);
+static int header_odc(struct archive_read *, struct cpio *,
+ struct archive_entry *, size_t *, size_t *);
+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 int record_hardlink(struct archive_read *a,
+ struct cpio *cpio, struct archive_entry *entry);
+
+int
+archive_read_support_format_cpio(struct archive *_a)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ struct cpio *cpio;
+ int r;
+
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_cpio");
+
+ cpio = (struct cpio *)calloc(1, sizeof(*cpio));
+ if (cpio == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Can't allocate cpio data");
+ return (ARCHIVE_FATAL);
+ }
+ cpio->magic = CPIO_MAGIC;
+
+ r = __archive_read_register_format(a,
+ cpio,
+ "cpio",
+ archive_read_format_cpio_bid,
+ archive_read_format_cpio_options,
+ archive_read_format_cpio_read_header,
+ archive_read_format_cpio_read_data,
+ archive_read_format_cpio_skip,
+ archive_read_format_cpio_cleanup);
+
+ if (r != ARCHIVE_OK)
+ free(cpio);
+ return (ARCHIVE_OK);
+}
+
+
+static int
+archive_read_format_cpio_bid(struct archive_read *a, int best_bid)
+{
+ const unsigned char *p;
+ struct cpio *cpio;
+ int bid;
+
+ (void)best_bid; /* UNUSED */
+
+ cpio = (struct cpio *)(a->format->data);
+
+ if ((p = __archive_read_ahead(a, 6, NULL)) == NULL)
+ return (-1);
+
+ bid = 0;
+ if (memcmp(p, "070707", 6) == 0) {
+ /* ASCII cpio archive (odc, POSIX.1) */
+ cpio->read_header = header_odc;
+ bid += 48;
+ /*
+ * XXX TODO: More verification; Could check that only octal
+ * digits appear in appropriate header locations. XXX
+ */
+ } else if (memcmp(p, "070727", 6) == 0) {
+ /* afio large ASCII cpio archive */
+ cpio->read_header = header_odc;
+ bid += 48;
+ /*
+ * XXX TODO: More verification; Could check that almost hex
+ * digits appear in appropriate header locations. XXX
+ */
+ } else if (memcmp(p, "070701", 6) == 0) {
+ /* ASCII cpio archive (SVR4 without CRC) */
+ cpio->read_header = header_newc;
+ bid += 48;
+ /*
+ * XXX TODO: More verification; Could check that only hex
+ * digits appear in appropriate header locations. XXX
+ */
+ } else if (memcmp(p, "070702", 6) == 0) {
+ /* ASCII cpio archive (SVR4 with CRC) */
+ /* XXX TODO: Flag that we should check the CRC. XXX */
+ cpio->read_header = header_newc;
+ bid += 48;
+ /*
+ * XXX TODO: More verification; Could check that only hex
+ * digits appear in appropriate header locations. XXX
+ */
+ } else if (p[0] * 256 + p[1] == 070707) {
+ /* big-endian binary cpio archives */
+ cpio->read_header = header_bin_be;
+ bid += 16;
+ /* Is more verification possible here? */
+ } else if (p[0] + p[1] * 256 == 070707) {
+ /* little-endian binary cpio archives */
+ cpio->read_header = header_bin_le;
+ bid += 16;
+ /* Is more verification possible here? */
+ } else
+ return (ARCHIVE_WARN);
+
+ return (bid);
+}
+
+static int
+archive_read_format_cpio_options(struct archive_read *a,
+ const char *key, const char *val)
+{
+ struct cpio *cpio;
+ int ret = ARCHIVE_FAILED;
+
+ cpio = (struct cpio *)(a->format->data);
+ if (strcmp(key, "compat-2x") == 0) {
+ /* Handle filnames as libarchive 2.x */
+ cpio->init_default_conversion = (val != NULL)?1:0;
+ ret = ARCHIVE_OK;
+ } else if (strcmp(key, "hdrcharset") == 0) {
+ if (val == NULL || val[0] == 0)
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "cpio: hdrcharset option needs a character-set name");
+ else {
+ cpio->opt_sconv =
+ archive_string_conversion_from_charset(
+ &a->archive, val, 0);
+ if (cpio->opt_sconv != NULL)
+ ret = ARCHIVE_OK;
+ else
+ ret = ARCHIVE_FATAL;
+ }
+ } else
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "cpio: unknown keyword ``%s''", key);
+
+ return (ret);
+}
+
+static int
+archive_read_format_cpio_read_header(struct archive_read *a,
+ struct archive_entry *entry)
+{
+ struct cpio *cpio;
+ const void *h;
+ struct archive_string_conv *sconv;
+ size_t namelength;
+ size_t name_pad;
+ int r;
+
+ cpio = (struct cpio *)(a->format->data);
+ sconv = cpio->opt_sconv;
+ if (sconv == NULL) {
+ if (!cpio->init_default_conversion) {
+ cpio->sconv_default =
+ archive_string_default_conversion_for_read(
+ &(a->archive));
+ cpio->init_default_conversion = 1;
+ }
+ sconv = cpio->sconv_default;
+ }
+
+ r = (cpio->read_header(a, cpio, entry, &namelength, &name_pad));
+
+ if (r < ARCHIVE_WARN)
+ return (r);
+
+ /* Read name from buffer. */
+ h = __archive_read_ahead(a, namelength + name_pad, NULL);
+ if (h == NULL)
+ return (ARCHIVE_FATAL);
+ if (archive_entry_copy_pathname_l(entry,
+ (const char *)h, namelength, sconv) != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Pathname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Pathname can't be converted from %s to current locale.",
+ archive_string_conversion_charset_name(sconv));
+ r = ARCHIVE_WARN;
+ }
+ cpio->entry_offset = 0;
+
+ __archive_read_consume(a, namelength + name_pad);
+
+ /* If this is a symlink, read the link contents. */
+ if (archive_entry_filetype(entry) == AE_IFLNK) {
+ h = __archive_read_ahead(a, cpio->entry_bytes_remaining, NULL);
+ if (h == NULL)
+ return (ARCHIVE_FATAL);
+ if (archive_entry_copy_symlink_l(entry, (const char *)h,
+ cpio->entry_bytes_remaining, sconv) != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Linkname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Linkname can't be converted from %s to "
+ "current locale.",
+ archive_string_conversion_charset_name(sconv));
+ r = ARCHIVE_WARN;
+ }
+ __archive_read_consume(a, cpio->entry_bytes_remaining);
+ cpio->entry_bytes_remaining = 0;
+ }
+
+ /* XXX TODO: If the full mode is 0160200, then this is a Solaris
+ * ACL description for the following entry. Read this body
+ * and parse it as a Solaris-style ACL, then read the next
+ * header. XXX */
+
+ /* Compare name to "TRAILER!!!" to test for end-of-archive. */
+ if (namelength == 11 && strcmp((const char *)h, "TRAILER!!!") == 0) {
+ /* TODO: Store file location of start of block. */
+ archive_clear_error(&a->archive);
+ return (ARCHIVE_EOF);
+ }
+
+ /* Detect and record hardlinks to previously-extracted entries. */
+ if (record_hardlink(a, cpio, entry) != ARCHIVE_OK) {
+ return (ARCHIVE_FATAL);
+ }
+
+ return (r);
+}
+
+static int
+archive_read_format_cpio_read_data(struct archive_read *a,
+ const void **buff, size_t *size, int64_t *offset)
+{
+ ssize_t bytes_read;
+ struct cpio *cpio;
+
+ cpio = (struct cpio *)(a->format->data);
+
+ if (cpio->entry_bytes_unconsumed) {
+ __archive_read_consume(a, cpio->entry_bytes_unconsumed);
+ cpio->entry_bytes_unconsumed = 0;
+ }
+
+ if (cpio->entry_bytes_remaining > 0) {
+ *buff = __archive_read_ahead(a, 1, &bytes_read);
+ if (bytes_read <= 0)
+ return (ARCHIVE_FATAL);
+ if (bytes_read > cpio->entry_bytes_remaining)
+ bytes_read = cpio->entry_bytes_remaining;
+ *size = bytes_read;
+ cpio->entry_bytes_unconsumed = bytes_read;
+ *offset = cpio->entry_offset;
+ cpio->entry_offset += bytes_read;
+ cpio->entry_bytes_remaining -= bytes_read;
+ return (ARCHIVE_OK);
+ } else {
+ if (cpio->entry_padding !=
+ __archive_read_consume(a, cpio->entry_padding)) {
+ return (ARCHIVE_FATAL);
+ }
+ cpio->entry_padding = 0;
+ *buff = NULL;
+ *size = 0;
+ *offset = cpio->entry_offset;
+ return (ARCHIVE_EOF);
+ }
+}
+
+static int
+archive_read_format_cpio_skip(struct archive_read *a)
+{
+ struct cpio *cpio = (struct cpio *)(a->format->data);
+ int64_t to_skip = cpio->entry_bytes_remaining + cpio->entry_padding +
+ cpio->entry_bytes_unconsumed;
+
+ if (to_skip != __archive_read_consume(a, to_skip)) {
+ return (ARCHIVE_FATAL);
+ }
+ cpio->entry_bytes_remaining = 0;
+ cpio->entry_padding = 0;
+ cpio->entry_bytes_unconsumed = 0;
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Skip forward to the next cpio newc header by searching for the
+ * 07070[12] string. This should be generalized and merged with
+ * find_odc_header below.
+ */
+static int
+is_hex(const char *p, size_t len)
+{
+ while (len-- > 0) {
+ if ((*p >= '0' && *p <= '9')
+ || (*p >= 'a' && *p <= 'f')
+ || (*p >= 'A' && *p <= 'F'))
+ ++p;
+ else
+ return (0);
+ }
+ return (1);
+}
+
+static int
+find_newc_header(struct archive_read *a)
+{
+ const void *h;
+ const char *p, *q;
+ size_t skip, skipped = 0;
+ ssize_t bytes;
+
+ for (;;) {
+ h = __archive_read_ahead(a, newc_header_size, &bytes);
+ if (h == NULL)
+ return (ARCHIVE_FATAL);
+ p = h;
+ q = p + bytes;
+
+ /* Try the typical case first, then go into the slow search.*/
+ if (memcmp("07070", p, 5) == 0
+ && (p[5] == '1' || p[5] == '2')
+ && is_hex(p, newc_header_size))
+ return (ARCHIVE_OK);
+
+ /*
+ * Scan ahead until we find something that looks
+ * like a newc header.
+ */
+ while (p + newc_header_size <= q) {
+ switch (p[5]) {
+ case '1':
+ case '2':
+ if (memcmp("07070", p, 5) == 0
+ && is_hex(p, newc_header_size)) {
+ skip = p - (const char *)h;
+ __archive_read_consume(a, skip);
+ skipped += skip;
+ if (skipped > 0) {
+ archive_set_error(&a->archive,
+ 0,
+ "Skipped %d bytes before "
+ "finding valid header",
+ (int)skipped);
+ return (ARCHIVE_WARN);
+ }
+ return (ARCHIVE_OK);
+ }
+ p += 2;
+ break;
+ case '0':
+ p++;
+ break;
+ default:
+ p += 6;
+ break;
+ }
+ }
+ skip = p - (const char *)h;
+ __archive_read_consume(a, skip);
+ skipped += skip;
+ }
+}
+
+static int
+header_newc(struct archive_read *a, struct cpio *cpio,
+ struct archive_entry *entry, size_t *namelength, size_t *name_pad)
+{
+ const void *h;
+ const char *header;
+ int r;
+
+ r = find_newc_header(a);
+ if (r < ARCHIVE_WARN)
+ return (r);
+
+ /* Read fixed-size portion of header. */
+ h = __archive_read_ahead(a, newc_header_size, NULL);
+ if (h == NULL)
+ return (ARCHIVE_FATAL);
+
+ /* Parse out hex fields. */
+ header = (const char *)h;
+
+ if (memcmp(header + newc_magic_offset, "070701", 6) == 0) {
+ a->archive.archive_format = ARCHIVE_FORMAT_CPIO_SVR4_NOCRC;
+ a->archive.archive_format_name = "ASCII cpio (SVR4 with no CRC)";
+ } else if (memcmp(header + newc_magic_offset, "070702", 6) == 0) {
+ a->archive.archive_format = ARCHIVE_FORMAT_CPIO_SVR4_CRC;
+ a->archive.archive_format_name = "ASCII cpio (SVR4 with CRC)";
+ } else {
+ /* TODO: Abort here? */
+ }
+
+ archive_entry_set_devmajor(entry, atol16(header + newc_devmajor_offset, newc_devmajor_size));
+ archive_entry_set_devminor(entry, atol16(header + newc_devminor_offset, newc_devminor_size));
+ archive_entry_set_ino(entry, atol16(header + newc_ino_offset, newc_ino_size));
+ archive_entry_set_mode(entry, atol16(header + newc_mode_offset, newc_mode_size));
+ archive_entry_set_uid(entry, atol16(header + newc_uid_offset, newc_uid_size));
+ archive_entry_set_gid(entry, atol16(header + newc_gid_offset, newc_gid_size));
+ archive_entry_set_nlink(entry, atol16(header + newc_nlink_offset, newc_nlink_size));
+ archive_entry_set_rdevmajor(entry, atol16(header + newc_rdevmajor_offset, newc_rdevmajor_size));
+ archive_entry_set_rdevminor(entry, atol16(header + newc_rdevminor_offset, newc_rdevminor_size));
+ archive_entry_set_mtime(entry, atol16(header + newc_mtime_offset, newc_mtime_size), 0);
+ *namelength = atol16(header + newc_namesize_offset, newc_namesize_size);
+ /* Pad name to 2 more than a multiple of 4. */
+ *name_pad = (2 - *namelength) & 3;
+
+ /*
+ * Note: entry_bytes_remaining is at least 64 bits and
+ * therefore guaranteed to be big enough for a 33-bit file
+ * size.
+ */
+ cpio->entry_bytes_remaining =
+ atol16(header + newc_filesize_offset, newc_filesize_size);
+ archive_entry_set_size(entry, cpio->entry_bytes_remaining);
+ /* Pad file contents to a multiple of 4. */
+ cpio->entry_padding = 3 & -cpio->entry_bytes_remaining;
+ __archive_read_consume(a, newc_header_size);
+ return (r);
+}
+
+/*
+ * Skip forward to the next cpio odc header by searching for the
+ * 070707 string. This is a hand-optimized search that could
+ * probably be easily generalized to handle all character-based
+ * cpio variants.
+ */
+static int
+is_octal(const char *p, size_t len)
+{
+ while (len-- > 0) {
+ if (*p < '0' || *p > '7')
+ return (0);
+ ++p;
+ }
+ return (1);
+}
+
+static int
+is_afio_large(const char *h, size_t len)
+{
+ if (len < afiol_header_size)
+ return (0);
+ if (h[afiol_ino_m_offset] != 'm'
+ || h[afiol_mtime_n_offset] != 'n'
+ || h[afiol_xsize_s_offset] != 's'
+ || h[afiol_filesize_c_offset] != ':')
+ return (0);
+ if (!is_hex(h + afiol_dev_offset, afiol_ino_m_offset - afiol_dev_offset))
+ return (0);
+ if (!is_hex(h + afiol_mode_offset, afiol_mtime_n_offset - afiol_mode_offset))
+ return (0);
+ if (!is_hex(h + afiol_namesize_offset, afiol_xsize_s_offset - afiol_namesize_offset))
+ return (0);
+ if (!is_hex(h + afiol_filesize_offset, afiol_filesize_size))
+ return (0);
+ return (1);
+}
+
+static int
+find_odc_header(struct archive_read *a)
+{
+ const void *h;
+ const char *p, *q;
+ size_t skip, skipped = 0;
+ ssize_t bytes;
+
+ for (;;) {
+ h = __archive_read_ahead(a, odc_header_size, &bytes);
+ if (h == NULL)
+ return (ARCHIVE_FATAL);
+ p = h;
+ q = p + bytes;
+
+ /* Try the typical case first, then go into the slow search.*/
+ if (memcmp("070707", p, 6) == 0 && is_octal(p, odc_header_size))
+ return (ARCHIVE_OK);
+ if (memcmp("070727", p, 6) == 0 && is_afio_large(p, bytes)) {
+ a->archive.archive_format = ARCHIVE_FORMAT_CPIO_AFIO_LARGE;
+ return (ARCHIVE_OK);
+ }
+
+ /*
+ * Scan ahead until we find something that looks
+ * like an odc header.
+ */
+ while (p + odc_header_size <= q) {
+ switch (p[5]) {
+ case '7':
+ if ((memcmp("070707", p, 6) == 0
+ && is_octal(p, odc_header_size))
+ || (memcmp("070727", p, 6) == 0
+ && is_afio_large(p, q - p))) {
+ skip = p - (const char *)h;
+ __archive_read_consume(a, skip);
+ skipped += skip;
+ if (p[4] == '2')
+ a->archive.archive_format =
+ ARCHIVE_FORMAT_CPIO_AFIO_LARGE;
+ if (skipped > 0) {
+ archive_set_error(&a->archive,
+ 0,
+ "Skipped %d bytes before "
+ "finding valid header",
+ (int)skipped);
+ return (ARCHIVE_WARN);
+ }
+ return (ARCHIVE_OK);
+ }
+ p += 2;
+ break;
+ case '0':
+ p++;
+ break;
+ default:
+ p += 6;
+ break;
+ }
+ }
+ skip = p - (const char *)h;
+ __archive_read_consume(a, skip);
+ skipped += skip;
+ }
+}
+
+static int
+header_odc(struct archive_read *a, struct cpio *cpio,
+ struct archive_entry *entry, size_t *namelength, size_t *name_pad)
+{
+ const void *h;
+ int r;
+ const char *header;
+
+ a->archive.archive_format = ARCHIVE_FORMAT_CPIO_POSIX;
+ a->archive.archive_format_name = "POSIX octet-oriented cpio";
+
+ /* Find the start of the next header. */
+ r = find_odc_header(a);
+ if (r < ARCHIVE_WARN)
+ return (r);
+
+ if (a->archive.archive_format == ARCHIVE_FORMAT_CPIO_AFIO_LARGE) {
+ int r2 = (header_afiol(a, cpio, entry, namelength, name_pad));
+ if (r2 == ARCHIVE_OK)
+ return (r);
+ else
+ return (r2);
+ }
+
+ /* Read fixed-size portion of header. */
+ h = __archive_read_ahead(a, odc_header_size, NULL);
+ if (h == NULL)
+ return (ARCHIVE_FATAL);
+
+ /* Parse out octal fields. */
+ header = (const char *)h;
+
+ archive_entry_set_dev(entry, atol8(header + odc_dev_offset, odc_dev_size));
+ archive_entry_set_ino(entry, atol8(header + odc_ino_offset, odc_ino_size));
+ archive_entry_set_mode(entry, atol8(header + odc_mode_offset, odc_mode_size));
+ archive_entry_set_uid(entry, atol8(header + odc_uid_offset, odc_uid_size));
+ archive_entry_set_gid(entry, atol8(header + odc_gid_offset, odc_gid_size));
+ archive_entry_set_nlink(entry, atol8(header + odc_nlink_offset, odc_nlink_size));
+ archive_entry_set_rdev(entry, atol8(header + odc_rdev_offset, odc_rdev_size));
+ archive_entry_set_mtime(entry, atol8(header + odc_mtime_offset, odc_mtime_size), 0);
+ *namelength = atol8(header + odc_namesize_offset, odc_namesize_size);
+ *name_pad = 0; /* No padding of filename. */
+
+ /*
+ * Note: entry_bytes_remaining is at least 64 bits and
+ * therefore guaranteed to be big enough for a 33-bit file
+ * size.
+ */
+ cpio->entry_bytes_remaining =
+ atol8(header + odc_filesize_offset, odc_filesize_size);
+ archive_entry_set_size(entry, cpio->entry_bytes_remaining);
+ cpio->entry_padding = 0;
+ __archive_read_consume(a, odc_header_size);
+ return (r);
+}
+
+/*
+ * NOTE: if a filename suffix is ".z", it is the file gziped by afio.
+ * it would be nice that we can show uncompressed file size and we can
+ * uncompressed file contents automatically, unfortunately we have nothing
+ * to get a uncompressed file size while reading each header. it means
+ * we also cannot uncompressed file contens under the our framework.
+ */
+static int
+header_afiol(struct archive_read *a, struct cpio *cpio,
+ struct archive_entry *entry, size_t *namelength, size_t *name_pad)
+{
+ const void *h;
+ const char *header;
+
+ a->archive.archive_format = ARCHIVE_FORMAT_CPIO_AFIO_LARGE;
+ a->archive.archive_format_name = "afio large ASCII";
+
+ /* Read fixed-size portion of header. */
+ h = __archive_read_ahead(a, afiol_header_size, NULL);
+ if (h == NULL)
+ return (ARCHIVE_FATAL);
+
+ /* Parse out octal fields. */
+ header = (const char *)h;
+
+ archive_entry_set_dev(entry, atol16(header + afiol_dev_offset, afiol_dev_size));
+ archive_entry_set_ino(entry, atol16(header + afiol_ino_offset, afiol_ino_size));
+ archive_entry_set_mode(entry, atol8(header + afiol_mode_offset, afiol_mode_size));
+ archive_entry_set_uid(entry, atol16(header + afiol_uid_offset, afiol_uid_size));
+ archive_entry_set_gid(entry, atol16(header + afiol_gid_offset, afiol_gid_size));
+ archive_entry_set_nlink(entry, atol16(header + afiol_nlink_offset, afiol_nlink_size));
+ archive_entry_set_rdev(entry, atol16(header + afiol_rdev_offset, afiol_rdev_size));
+ archive_entry_set_mtime(entry, atol16(header + afiol_mtime_offset, afiol_mtime_size), 0);
+ *namelength = atol16(header + afiol_namesize_offset, afiol_namesize_size);
+ *name_pad = 0; /* No padding of filename. */
+
+ cpio->entry_bytes_remaining =
+ atol16(header + afiol_filesize_offset, afiol_filesize_size);
+ archive_entry_set_size(entry, cpio->entry_bytes_remaining);
+ cpio->entry_padding = 0;
+ __archive_read_consume(a, afiol_header_size);
+ return (ARCHIVE_OK);
+}
+
+
+static int
+header_bin_le(struct archive_read *a, struct cpio *cpio,
+ struct archive_entry *entry, size_t *namelength, size_t *name_pad)
+{
+ const void *h;
+ const unsigned char *header;
+
+ a->archive.archive_format = ARCHIVE_FORMAT_CPIO_BIN_LE;
+ a->archive.archive_format_name = "cpio (little-endian binary)";
+
+ /* Read fixed-size portion of header. */
+ h = __archive_read_ahead(a, bin_header_size, NULL);
+ if (h == NULL)
+ return (ARCHIVE_FATAL);
+
+ /* Parse out binary fields. */
+ header = (const unsigned char *)h;
+
+ archive_entry_set_dev(entry, header[bin_dev_offset] + header[bin_dev_offset + 1] * 256);
+ archive_entry_set_ino(entry, header[bin_ino_offset] + header[bin_ino_offset + 1] * 256);
+ archive_entry_set_mode(entry, header[bin_mode_offset] + header[bin_mode_offset + 1] * 256);
+ archive_entry_set_uid(entry, header[bin_uid_offset] + header[bin_uid_offset + 1] * 256);
+ archive_entry_set_gid(entry, header[bin_gid_offset] + header[bin_gid_offset + 1] * 256);
+ archive_entry_set_nlink(entry, header[bin_nlink_offset] + header[bin_nlink_offset + 1] * 256);
+ archive_entry_set_rdev(entry, header[bin_rdev_offset] + header[bin_rdev_offset + 1] * 256);
+ archive_entry_set_mtime(entry, le4(header + bin_mtime_offset), 0);
+ *namelength = header[bin_namesize_offset] + header[bin_namesize_offset + 1] * 256;
+ *name_pad = *namelength & 1; /* Pad to even. */
+
+ cpio->entry_bytes_remaining = le4(header + bin_filesize_offset);
+ archive_entry_set_size(entry, cpio->entry_bytes_remaining);
+ cpio->entry_padding = cpio->entry_bytes_remaining & 1; /* Pad to even. */
+ __archive_read_consume(a, bin_header_size);
+ return (ARCHIVE_OK);
+}
+
+static int
+header_bin_be(struct archive_read *a, struct cpio *cpio,
+ struct archive_entry *entry, size_t *namelength, size_t *name_pad)
+{
+ const void *h;
+ const unsigned char *header;
+
+ a->archive.archive_format = ARCHIVE_FORMAT_CPIO_BIN_BE;
+ a->archive.archive_format_name = "cpio (big-endian binary)";
+
+ /* Read fixed-size portion of header. */
+ h = __archive_read_ahead(a, bin_header_size, NULL);
+ if (h == NULL)
+ return (ARCHIVE_FATAL);
+
+ /* Parse out binary fields. */
+ header = (const unsigned char *)h;
+
+ archive_entry_set_dev(entry, header[bin_dev_offset] * 256 + header[bin_dev_offset + 1]);
+ archive_entry_set_ino(entry, header[bin_ino_offset] * 256 + header[bin_ino_offset + 1]);
+ archive_entry_set_mode(entry, header[bin_mode_offset] * 256 + header[bin_mode_offset + 1]);
+ archive_entry_set_uid(entry, header[bin_uid_offset] * 256 + header[bin_uid_offset + 1]);
+ archive_entry_set_gid(entry, header[bin_gid_offset] * 256 + header[bin_gid_offset + 1]);
+ archive_entry_set_nlink(entry, header[bin_nlink_offset] * 256 + header[bin_nlink_offset + 1]);
+ archive_entry_set_rdev(entry, header[bin_rdev_offset] * 256 + header[bin_rdev_offset + 1]);
+ archive_entry_set_mtime(entry, be4(header + bin_mtime_offset), 0);
+ *namelength = header[bin_namesize_offset] * 256 + header[bin_namesize_offset + 1];
+ *name_pad = *namelength & 1; /* Pad to even. */
+
+ cpio->entry_bytes_remaining = be4(header + bin_filesize_offset);
+ archive_entry_set_size(entry, cpio->entry_bytes_remaining);
+ cpio->entry_padding = cpio->entry_bytes_remaining & 1; /* Pad to even. */
+ __archive_read_consume(a, bin_header_size);
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_read_format_cpio_cleanup(struct archive_read *a)
+{
+ struct cpio *cpio;
+
+ cpio = (struct cpio *)(a->format->data);
+ /* Free inode->name map */
+ while (cpio->links_head != NULL) {
+ struct links_entry *lp = cpio->links_head->next;
+
+ if (cpio->links_head->name)
+ free(cpio->links_head->name);
+ free(cpio->links_head);
+ cpio->links_head = lp;
+ }
+ free(cpio);
+ (a->format->data) = NULL;
+ return (ARCHIVE_OK);
+}
+
+static int
+le4(const unsigned char *p)
+{
+ return ((p[0]<<16) + (p[1]<<24) + (p[2]<<0) + (p[3]<<8));
+}
+
+
+static int
+be4(const unsigned char *p)
+{
+ return ((p[0]<<24) + (p[1]<<16) + (p[2]<<8) + (p[3]));
+}
+
+/*
+ * Note that this implementation does not (and should not!) obey
+ * locale settings; you cannot simply substitute strtol here, since
+ * it does obey locale.
+ */
+static int64_t
+atol8(const char *p, unsigned char_cnt)
+{
+ int64_t l;
+ int digit;
+
+ l = 0;
+ while (char_cnt-- > 0) {
+ if (*p >= '0' && *p <= '7')
+ digit = *p - '0';
+ else
+ return (l);
+ p++;
+ l <<= 3;
+ l |= digit;
+ }
+ return (l);
+}
+
+static int64_t
+atol16(const char *p, unsigned char_cnt)
+{
+ int64_t l;
+ int digit;
+
+ l = 0;
+ while (char_cnt-- > 0) {
+ if (*p >= 'a' && *p <= 'f')
+ digit = *p - 'a' + 10;
+ else if (*p >= 'A' && *p <= 'F')
+ digit = *p - 'A' + 10;
+ else if (*p >= '0' && *p <= '9')
+ digit = *p - '0';
+ else
+ return (l);
+ p++;
+ l <<= 4;
+ l |= digit;
+ }
+ return (l);
+}
+
+static int
+record_hardlink(struct archive_read *a,
+ struct cpio *cpio, struct archive_entry *entry)
+{
+ struct links_entry *le;
+ dev_t dev;
+ int64_t ino;
+
+ if (archive_entry_nlink(entry) <= 1)
+ return (ARCHIVE_OK);
+
+ dev = archive_entry_dev(entry);
+ ino = archive_entry_ino64(entry);
+
+ /*
+ * First look in the list of multiply-linked files. If we've
+ * already dumped it, convert this entry to a hard link entry.
+ */
+ for (le = cpio->links_head; le; le = le->next) {
+ if (le->dev == dev && le->ino == ino) {
+ archive_entry_copy_hardlink(entry, le->name);
+
+ if (--le->links <= 0) {
+ if (le->previous != NULL)
+ le->previous->next = le->next;
+ if (le->next != NULL)
+ le->next->previous = le->previous;
+ if (cpio->links_head == le)
+ cpio->links_head = le->next;
+ free(le->name);
+ free(le);
+ }
+
+ return (ARCHIVE_OK);
+ }
+ }
+
+ le = (struct links_entry *)malloc(sizeof(struct links_entry));
+ if (le == NULL) {
+ archive_set_error(&a->archive,
+ ENOMEM, "Out of memory adding file to list");
+ return (ARCHIVE_FATAL);
+ }
+ if (cpio->links_head != NULL)
+ cpio->links_head->previous = le;
+ le->next = cpio->links_head;
+ le->previous = NULL;
+ cpio->links_head = le;
+ le->dev = dev;
+ le->ino = ino;
+ le->links = archive_entry_nlink(entry) - 1;
+ le->name = strdup(archive_entry_pathname(entry));
+ if (le->name == NULL) {
+ archive_set_error(&a->archive,
+ ENOMEM, "Out of memory adding file to list");
+ return (ARCHIVE_FATAL);
+ }
+
+ return (ARCHIVE_OK);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_empty.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_empty.c
new file mode 100644
index 000000000..3dc2196cb
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_empty.c
@@ -0,0 +1,93 @@
+/*-
+ * 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: head/lib/libarchive/archive_read_support_format_empty.c 191524 2009-04-26 18:24:14Z kientzle $");
+
+#include "archive.h"
+#include "archive_entry.h"
+#include "archive_private.h"
+#include "archive_read_private.h"
+
+static int archive_read_format_empty_bid(struct archive_read *, int);
+static int archive_read_format_empty_read_data(struct archive_read *,
+ const void **, size_t *, int64_t *);
+static int archive_read_format_empty_read_header(struct archive_read *,
+ struct archive_entry *);
+int
+archive_read_support_format_empty(struct archive *_a)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ int r;
+
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_empty");
+
+ r = __archive_read_register_format(a,
+ NULL,
+ NULL,
+ archive_read_format_empty_bid,
+ NULL,
+ archive_read_format_empty_read_header,
+ archive_read_format_empty_read_data,
+ NULL,
+ NULL);
+
+ return (r);
+}
+
+
+static int
+archive_read_format_empty_bid(struct archive_read *a, int best_bid)
+{
+ if (best_bid < 1 && __archive_read_ahead(a, 1, NULL) == NULL)
+ return (1);
+ return (-1);
+}
+
+static int
+archive_read_format_empty_read_header(struct archive_read *a,
+ struct archive_entry *entry)
+{
+ (void)a; /* UNUSED */
+ (void)entry; /* UNUSED */
+
+ a->archive.archive_format = ARCHIVE_FORMAT_EMPTY;
+ a->archive.archive_format_name = "Empty file";
+
+ return (ARCHIVE_EOF);
+}
+
+static int
+archive_read_format_empty_read_data(struct archive_read *a,
+ const void **buff, size_t *size, int64_t *offset)
+{
+ (void)a; /* UNUSED */
+ (void)buff; /* UNUSED */
+ (void)size; /* UNUSED */
+ (void)offset; /* UNUSED */
+
+ return (ARCHIVE_EOF);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c
new file mode 100644
index 000000000..db7aa9d9b
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c
@@ -0,0 +1,3213 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2009 Andreas Henriksson <andreas@fatal.se>
+ * Copyright (c) 2009-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"
+__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_iso9660.c 201246 2009-12-30 05:30:35Z kientzle $");
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+/* #include <stdint.h> */ /* See archive_platform.h */
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#include <time.h>
+#ifdef HAVE_ZLIB_H
+#include <cm_zlib.h>
+#endif
+
+#include "archive.h"
+#include "archive_endian.h"
+#include "archive_entry.h"
+#include "archive_entry_locale.h"
+#include "archive_private.h"
+#include "archive_read_private.h"
+#include "archive_string.h"
+
+/*
+ * An overview of ISO 9660 format:
+ *
+ * Each disk is laid out as follows:
+ * * 32k reserved for private use
+ * * Volume descriptor table. Each volume descriptor
+ * is 2k and specifies basic format information.
+ * The "Primary Volume Descriptor" (PVD) is defined by the
+ * standard and should always be present; other volume
+ * descriptors include various vendor-specific extensions.
+ * * Files and directories. Each file/dir is specified by
+ * an "extent" (starting sector and length in bytes).
+ * Dirs are just files with directory records packed one
+ * after another. The PVD contains a single dir entry
+ * specifying the location of the root directory. Everything
+ * else follows from there.
+ *
+ * This module works by first reading the volume descriptors, then
+ * building a list of directory entries, sorted by starting
+ * sector. At each step, I look for the earliest dir entry that
+ * hasn't yet been read, seek forward to that location and read
+ * that entry. If it's a dir, I slurp in the new dir entries and
+ * add them to the heap; if it's a regular file, I return the
+ * corresponding archive_entry and wait for the client to request
+ * the file body. This strategy allows us to read most compliant
+ * CDs with a single pass through the data, as required by libarchive.
+ */
+#define LOGICAL_BLOCK_SIZE 2048
+#define SYSTEM_AREA_BLOCK 16
+
+/* Structure of on-disk primary volume descriptor. */
+#define PVD_type_offset 0
+#define PVD_type_size 1
+#define PVD_id_offset (PVD_type_offset + PVD_type_size)
+#define PVD_id_size 5
+#define PVD_version_offset (PVD_id_offset + PVD_id_size)
+#define PVD_version_size 1
+#define PVD_reserved1_offset (PVD_version_offset + PVD_version_size)
+#define PVD_reserved1_size 1
+#define PVD_system_id_offset (PVD_reserved1_offset + PVD_reserved1_size)
+#define PVD_system_id_size 32
+#define PVD_volume_id_offset (PVD_system_id_offset + PVD_system_id_size)
+#define PVD_volume_id_size 32
+#define PVD_reserved2_offset (PVD_volume_id_offset + PVD_volume_id_size)
+#define PVD_reserved2_size 8
+#define PVD_volume_space_size_offset (PVD_reserved2_offset + PVD_reserved2_size)
+#define PVD_volume_space_size_size 8
+#define PVD_reserved3_offset (PVD_volume_space_size_offset + PVD_volume_space_size_size)
+#define PVD_reserved3_size 32
+#define PVD_volume_set_size_offset (PVD_reserved3_offset + PVD_reserved3_size)
+#define PVD_volume_set_size_size 4
+#define PVD_volume_sequence_number_offset (PVD_volume_set_size_offset + PVD_volume_set_size_size)
+#define PVD_volume_sequence_number_size 4
+#define PVD_logical_block_size_offset (PVD_volume_sequence_number_offset + PVD_volume_sequence_number_size)
+#define PVD_logical_block_size_size 4
+#define PVD_path_table_size_offset (PVD_logical_block_size_offset + PVD_logical_block_size_size)
+#define PVD_path_table_size_size 8
+#define PVD_type_1_path_table_offset (PVD_path_table_size_offset + PVD_path_table_size_size)
+#define PVD_type_1_path_table_size 4
+#define PVD_opt_type_1_path_table_offset (PVD_type_1_path_table_offset + PVD_type_1_path_table_size)
+#define PVD_opt_type_1_path_table_size 4
+#define PVD_type_m_path_table_offset (PVD_opt_type_1_path_table_offset + PVD_opt_type_1_path_table_size)
+#define PVD_type_m_path_table_size 4
+#define PVD_opt_type_m_path_table_offset (PVD_type_m_path_table_offset + PVD_type_m_path_table_size)
+#define PVD_opt_type_m_path_table_size 4
+#define PVD_root_directory_record_offset (PVD_opt_type_m_path_table_offset + PVD_opt_type_m_path_table_size)
+#define PVD_root_directory_record_size 34
+#define PVD_volume_set_id_offset (PVD_root_directory_record_offset + PVD_root_directory_record_size)
+#define PVD_volume_set_id_size 128
+#define PVD_publisher_id_offset (PVD_volume_set_id_offset + PVD_volume_set_id_size)
+#define PVD_publisher_id_size 128
+#define PVD_preparer_id_offset (PVD_publisher_id_offset + PVD_publisher_id_size)
+#define PVD_preparer_id_size 128
+#define PVD_application_id_offset (PVD_preparer_id_offset + PVD_preparer_id_size)
+#define PVD_application_id_size 128
+#define PVD_copyright_file_id_offset (PVD_application_id_offset + PVD_application_id_size)
+#define PVD_copyright_file_id_size 37
+#define PVD_abstract_file_id_offset (PVD_copyright_file_id_offset + PVD_copyright_file_id_size)
+#define PVD_abstract_file_id_size 37
+#define PVD_bibliographic_file_id_offset (PVD_abstract_file_id_offset + PVD_abstract_file_id_size)
+#define PVD_bibliographic_file_id_size 37
+#define PVD_creation_date_offset (PVD_bibliographic_file_id_offset + PVD_bibliographic_file_id_size)
+#define PVD_creation_date_size 17
+#define PVD_modification_date_offset (PVD_creation_date_offset + PVD_creation_date_size)
+#define PVD_modification_date_size 17
+#define PVD_expiration_date_offset (PVD_modification_date_offset + PVD_modification_date_size)
+#define PVD_expiration_date_size 17
+#define PVD_effective_date_offset (PVD_expiration_date_offset + PVD_expiration_date_size)
+#define PVD_effective_date_size 17
+#define PVD_file_structure_version_offset (PVD_effective_date_offset + PVD_effective_date_size)
+#define PVD_file_structure_version_size 1
+#define PVD_reserved4_offset (PVD_file_structure_version_offset + PVD_file_structure_version_size)
+#define PVD_reserved4_size 1
+#define PVD_application_data_offset (PVD_reserved4_offset + PVD_reserved4_size)
+#define PVD_application_data_size 512
+#define PVD_reserved5_offset (PVD_application_data_offset + PVD_application_data_size)
+#define PVD_reserved5_size (2048 - PVD_reserved5_offset)
+
+/* TODO: It would make future maintenance easier to just hardcode the
+ * above values. In particular, ECMA119 states the offsets as part of
+ * the standard. That would eliminate the need for the following check.*/
+#if PVD_reserved5_offset != 1395
+#error PVD offset and size definitions are wrong.
+#endif
+
+
+/* Structure of optional on-disk supplementary volume descriptor. */
+#define SVD_type_offset 0
+#define SVD_type_size 1
+#define SVD_id_offset (SVD_type_offset + SVD_type_size)
+#define SVD_id_size 5
+#define SVD_version_offset (SVD_id_offset + SVD_id_size)
+#define SVD_version_size 1
+/* ... */
+#define SVD_reserved1_offset 72
+#define SVD_reserved1_size 8
+#define SVD_volume_space_size_offset 80
+#define SVD_volume_space_size_size 8
+#define SVD_escape_sequences_offset (SVD_volume_space_size_offset + SVD_volume_space_size_size)
+#define SVD_escape_sequences_size 32
+/* ... */
+#define SVD_logical_block_size_offset 128
+#define SVD_logical_block_size_size 4
+#define SVD_type_L_path_table_offset 140
+#define SVD_type_M_path_table_offset 148
+/* ... */
+#define SVD_root_directory_record_offset 156
+#define SVD_root_directory_record_size 34
+#define SVD_file_structure_version_offset 881
+#define SVD_reserved2_offset 882
+#define SVD_reserved2_size 1
+#define SVD_reserved3_offset 1395
+#define SVD_reserved3_size 653
+/* ... */
+/* FIXME: validate correctness of last SVD entry offset. */
+
+/* Structure of an on-disk directory record. */
+/* Note: ISO9660 stores each multi-byte integer twice, once in
+ * each byte order. The sizes here are the size of just one
+ * of the two integers. (This is why the offset of a field isn't
+ * the same as the offset+size of the previous field.) */
+#define DR_length_offset 0
+#define DR_length_size 1
+#define DR_ext_attr_length_offset 1
+#define DR_ext_attr_length_size 1
+#define DR_extent_offset 2
+#define DR_extent_size 4
+#define DR_size_offset 10
+#define DR_size_size 4
+#define DR_date_offset 18
+#define DR_date_size 7
+#define DR_flags_offset 25
+#define DR_flags_size 1
+#define DR_file_unit_size_offset 26
+#define DR_file_unit_size_size 1
+#define DR_interleave_offset 27
+#define DR_interleave_size 1
+#define DR_volume_sequence_number_offset 28
+#define DR_volume_sequence_number_size 2
+#define DR_name_len_offset 32
+#define DR_name_len_size 1
+#define DR_name_offset 33
+
+#ifdef HAVE_ZLIB_H
+static const unsigned char zisofs_magic[8] = {
+ 0x37, 0xE4, 0x53, 0x96, 0xC9, 0xDB, 0xD6, 0x07
+};
+
+struct zisofs {
+ /* Set 1 if this file compressed by paged zlib */
+ int pz;
+ int pz_log2_bs; /* Log2 of block size */
+ uint64_t pz_uncompressed_size;
+
+ int initialized;
+ unsigned char *uncompressed_buffer;
+ size_t uncompressed_buffer_size;
+
+ uint32_t pz_offset;
+ unsigned char header[16];
+ size_t header_avail;
+ int header_passed;
+ unsigned char *block_pointers;
+ size_t block_pointers_alloc;
+ size_t block_pointers_size;
+ size_t block_pointers_avail;
+ size_t block_off;
+ uint32_t block_avail;
+
+ z_stream stream;
+ int stream_valid;
+};
+#else
+struct zisofs {
+ /* Set 1 if this file compressed by paged zlib */
+ int pz;
+};
+#endif
+
+struct content {
+ uint64_t offset;/* Offset on disk. */
+ uint64_t size; /* File size in bytes. */
+ struct content *next;
+};
+
+/* In-memory storage for a directory record. */
+struct file_info {
+ struct file_info *use_next;
+ struct file_info *parent;
+ struct file_info *next;
+ struct file_info *re_next;
+ int subdirs;
+ uint64_t key; /* Heap Key. */
+ uint64_t offset; /* Offset on disk. */
+ uint64_t size; /* File size in bytes. */
+ uint32_t ce_offset; /* Offset of CE. */
+ uint32_t ce_size; /* Size of CE. */
+ char rr_moved; /* Flag to rr_moved. */
+ char rr_moved_has_re_only;
+ char re; /* Having RRIP "RE" extension. */
+ char re_descendant;
+ uint64_t cl_offset; /* Having RRIP "CL" extension. */
+ int birthtime_is_set;
+ time_t birthtime; /* File created time. */
+ time_t mtime; /* File last modified time. */
+ time_t atime; /* File last accessed time. */
+ time_t ctime; /* File attribute change time. */
+ uint64_t rdev; /* Device number. */
+ mode_t mode;
+ uid_t uid;
+ gid_t gid;
+ int64_t number;
+ int nlinks;
+ struct archive_string name; /* Pathname */
+ unsigned char *utf16be_name;
+ size_t utf16be_bytes;
+ char name_continues; /* Non-zero if name continues */
+ struct archive_string symlink;
+ char symlink_continues; /* Non-zero if link continues */
+ /* Set 1 if this file compressed by paged zlib(zisofs) */
+ int pz;
+ int pz_log2_bs; /* Log2 of block size */
+ uint64_t pz_uncompressed_size;
+ /* Set 1 if this file is multi extent. */
+ int multi_extent;
+ struct {
+ struct content *first;
+ struct content **last;
+ } contents;
+ struct {
+ struct file_info *first;
+ struct file_info **last;
+ } rede_files;
+};
+
+struct heap_queue {
+ struct file_info **files;
+ int allocated;
+ int used;
+};
+
+struct iso9660 {
+ int magic;
+#define ISO9660_MAGIC 0x96609660
+
+ int opt_support_joliet;
+ int opt_support_rockridge;
+
+ struct archive_string pathname;
+ char seenRockridge; /* Set true if RR extensions are used. */
+ char seenSUSP; /* Set true if SUSP is beging used. */
+ char seenJoliet;
+
+ unsigned char suspOffset;
+ struct file_info *rr_moved;
+ struct read_ce_queue {
+ struct read_ce_req {
+ uint64_t offset;/* Offset of CE on disk. */
+ struct file_info *file;
+ } *reqs;
+ int cnt;
+ int allocated;
+ } read_ce_req;
+
+ int64_t previous_number;
+ struct archive_string previous_pathname;
+
+ struct file_info *use_files;
+ struct heap_queue pending_files;
+ struct {
+ struct file_info *first;
+ struct file_info **last;
+ } cache_files;
+ struct {
+ struct file_info *first;
+ struct file_info **last;
+ } re_files;
+
+ uint64_t current_position;
+ ssize_t logical_block_size;
+ uint64_t volume_size; /* Total size of volume in bytes. */
+ int32_t volume_block;/* Total size of volume in logical blocks. */
+
+ struct vd {
+ int location; /* Location of Extent. */
+ uint32_t size;
+ } primary, joliet;
+
+ int64_t entry_sparse_offset;
+ int64_t entry_bytes_remaining;
+ size_t entry_bytes_unconsumed;
+ struct zisofs entry_zisofs;
+ struct content *entry_content;
+ struct archive_string_conv *sconv_utf16be;
+ /*
+ * Buffers for a full pathname in UTF-16BE in Joliet extensions.
+ */
+#define UTF16_NAME_MAX 1024
+ unsigned char *utf16be_path;
+ size_t utf16be_path_len;
+ unsigned char *utf16be_previous_path;
+ size_t utf16be_previous_path_len;
+};
+
+static int archive_read_format_iso9660_bid(struct archive_read *, int);
+static int archive_read_format_iso9660_options(struct archive_read *,
+ const char *, const char *);
+static int archive_read_format_iso9660_cleanup(struct archive_read *);
+static int archive_read_format_iso9660_read_data(struct archive_read *,
+ const void **, size_t *, int64_t *);
+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 int build_pathname_utf16be(unsigned char *, size_t, size_t *,
+ struct file_info *);
+#if DEBUG
+static void dump_isodirrec(FILE *, const unsigned char *isodirrec);
+#endif
+static time_t time_from_tm(struct tm *);
+static time_t isodate17(const unsigned char *);
+static time_t isodate7(const unsigned char *);
+static int isBootRecord(struct iso9660 *, const unsigned char *);
+static int isVolumePartition(struct iso9660 *, const unsigned char *);
+static int isVDSetTerminator(struct iso9660 *, const unsigned char *);
+static int isJolietSVD(struct iso9660 *, const unsigned char *);
+static int isSVD(struct iso9660 *, const unsigned char *);
+static int isEVD(struct iso9660 *, const unsigned char *);
+static int isPVD(struct iso9660 *, const unsigned char *);
+static int next_cache_entry(struct archive_read *, struct iso9660 *,
+ struct file_info **);
+static int next_entry_seek(struct archive_read *, struct iso9660 *,
+ struct file_info **);
+static struct file_info *
+ parse_file_info(struct archive_read *a,
+ struct file_info *parent, const unsigned char *isodirrec);
+static int parse_rockridge(struct archive_read *a,
+ struct file_info *file, const unsigned char *start,
+ const unsigned char *end);
+static int register_CE(struct archive_read *a, int32_t location,
+ struct file_info *file);
+static int read_CE(struct archive_read *a, struct iso9660 *iso9660);
+static void parse_rockridge_NM1(struct file_info *,
+ const unsigned char *, int);
+static void parse_rockridge_SL1(struct file_info *,
+ const unsigned char *, int);
+static void parse_rockridge_TF1(struct file_info *,
+ const unsigned char *, int);
+static void parse_rockridge_ZF1(struct file_info *,
+ const unsigned char *, int);
+static void register_file(struct iso9660 *, struct file_info *);
+static void release_files(struct iso9660 *);
+static unsigned toi(const void *p, int n);
+static inline void re_add_entry(struct iso9660 *, struct file_info *);
+static inline struct file_info * re_get_entry(struct iso9660 *);
+static inline int rede_add_entry(struct file_info *);
+static inline struct file_info * rede_get_entry(struct file_info *);
+static inline void cache_add_entry(struct iso9660 *iso9660,
+ struct file_info *file);
+static inline struct file_info *cache_get_entry(struct iso9660 *iso9660);
+static int heap_add_entry(struct archive_read *a, struct heap_queue *heap,
+ struct file_info *file, uint64_t key);
+static struct file_info *heap_get_entry(struct heap_queue *heap);
+
+#define add_entry(arch, iso9660, file) \
+ heap_add_entry(arch, &((iso9660)->pending_files), file, file->offset)
+#define next_entry(iso9660) \
+ heap_get_entry(&((iso9660)->pending_files))
+
+int
+archive_read_support_format_iso9660(struct archive *_a)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ struct iso9660 *iso9660;
+ int r;
+
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_iso9660");
+
+ iso9660 = (struct iso9660 *)calloc(1, sizeof(*iso9660));
+ if (iso9660 == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate iso9660 data");
+ return (ARCHIVE_FATAL);
+ }
+ iso9660->magic = ISO9660_MAGIC;
+ iso9660->cache_files.first = NULL;
+ iso9660->cache_files.last = &(iso9660->cache_files.first);
+ iso9660->re_files.first = NULL;
+ iso9660->re_files.last = &(iso9660->re_files.first);
+ /* Enable to support Joliet extensions by default. */
+ iso9660->opt_support_joliet = 1;
+ /* Enable to support Rock Ridge extensions by default. */
+ iso9660->opt_support_rockridge = 1;
+
+ r = __archive_read_register_format(a,
+ iso9660,
+ "iso9660",
+ archive_read_format_iso9660_bid,
+ archive_read_format_iso9660_options,
+ archive_read_format_iso9660_read_header,
+ archive_read_format_iso9660_read_data,
+ archive_read_format_iso9660_read_data_skip,
+ archive_read_format_iso9660_cleanup);
+
+ if (r != ARCHIVE_OK) {
+ free(iso9660);
+ return (r);
+ }
+ return (ARCHIVE_OK);
+}
+
+
+static int
+archive_read_format_iso9660_bid(struct archive_read *a, int best_bid)
+{
+ struct iso9660 *iso9660;
+ ssize_t bytes_read;
+ const unsigned char *p;
+ int seenTerminator;
+
+ /* If there's already a better bid than we can ever
+ make, don't bother testing. */
+ if (best_bid > 48)
+ return (-1);
+
+ iso9660 = (struct iso9660 *)(a->format->data);
+
+ /*
+ * Skip the first 32k (reserved area) and get the first
+ * 8 sectors of the volume descriptor table. Of course,
+ * if the I/O layer gives us more, we'll take it.
+ */
+#define RESERVED_AREA (SYSTEM_AREA_BLOCK * LOGICAL_BLOCK_SIZE)
+ p = __archive_read_ahead(a,
+ RESERVED_AREA + 8 * LOGICAL_BLOCK_SIZE,
+ &bytes_read);
+ if (p == NULL)
+ return (-1);
+
+ /* Skip the reserved area. */
+ bytes_read -= RESERVED_AREA;
+ p += RESERVED_AREA;
+
+ /* Check each volume descriptor. */
+ seenTerminator = 0;
+ for (; bytes_read > LOGICAL_BLOCK_SIZE;
+ bytes_read -= LOGICAL_BLOCK_SIZE, p += LOGICAL_BLOCK_SIZE) {
+ /* Do not handle undefined Volume Descriptor Type. */
+ if (p[0] >= 4 && p[0] <= 254)
+ return (0);
+ /* Standard Identifier must be "CD001" */
+ if (memcmp(p + 1, "CD001", 5) != 0)
+ return (0);
+ if (isPVD(iso9660, p))
+ continue;
+ if (!iso9660->joliet.location) {
+ if (isJolietSVD(iso9660, p))
+ continue;
+ }
+ if (isBootRecord(iso9660, p))
+ continue;
+ if (isEVD(iso9660, p))
+ continue;
+ if (isSVD(iso9660, p))
+ continue;
+ if (isVolumePartition(iso9660, p))
+ continue;
+ if (isVDSetTerminator(iso9660, p)) {
+ seenTerminator = 1;
+ break;
+ }
+ return (0);
+ }
+ /*
+ * ISO 9660 format must have Primary Volume Descriptor and
+ * Volume Descriptor Set Terminator.
+ */
+ if (seenTerminator && iso9660->primary.location > 16)
+ return (48);
+
+ /* We didn't find a valid PVD; return a bid of zero. */
+ return (0);
+}
+
+static int
+archive_read_format_iso9660_options(struct archive_read *a,
+ const char *key, const char *val)
+{
+ struct iso9660 *iso9660;
+
+ iso9660 = (struct iso9660 *)(a->format->data);
+
+ if (strcmp(key, "joliet") == 0) {
+ if (val == NULL || strcmp(val, "off") == 0 ||
+ strcmp(val, "ignore") == 0 ||
+ strcmp(val, "disable") == 0 ||
+ strcmp(val, "0") == 0)
+ iso9660->opt_support_joliet = 0;
+ else
+ iso9660->opt_support_joliet = 1;
+ return (ARCHIVE_OK);
+ }
+ if (strcmp(key, "rockridge") == 0 ||
+ strcmp(key, "Rockridge") == 0) {
+ iso9660->opt_support_rockridge = val != 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);
+}
+
+static int
+isBootRecord(struct iso9660 *iso9660, const unsigned char *h)
+{
+ (void)iso9660; /* UNUSED */
+
+ /* Type of the Volume Descriptor Boot Record must be 0. */
+ if (h[0] != 0)
+ return (0);
+
+ /* Volume Descriptor Version must be 1. */
+ if (h[6] != 1)
+ return (0);
+
+ return (1);
+}
+
+static int
+isVolumePartition(struct iso9660 *iso9660, const unsigned char *h)
+{
+ int32_t location;
+
+ /* Type of the Volume Partition Descriptor must be 3. */
+ if (h[0] != 3)
+ return (0);
+
+ /* Volume Descriptor Version must be 1. */
+ if (h[6] != 1)
+ return (0);
+ /* Unused Field */
+ if (h[7] != 0)
+ return (0);
+
+ location = archive_le32dec(h + 72);
+ if (location <= SYSTEM_AREA_BLOCK ||
+ location >= iso9660->volume_block)
+ return (0);
+ if ((uint32_t)location != archive_be32dec(h + 76))
+ return (0);
+
+ return (1);
+}
+
+static int
+isVDSetTerminator(struct iso9660 *iso9660, const unsigned char *h)
+{
+ int i;
+
+ (void)iso9660; /* UNUSED */
+
+ /* Type of the Volume Descriptor Set Terminator must be 255. */
+ if (h[0] != 255)
+ return (0);
+
+ /* Volume Descriptor Version must be 1. */
+ if (h[6] != 1)
+ return (0);
+
+ /* Reserved field must be 0. */
+ for (i = 7; i < 2048; ++i)
+ if (h[i] != 0)
+ return (0);
+
+ return (1);
+}
+
+static int
+isJolietSVD(struct iso9660 *iso9660, const unsigned char *h)
+{
+ const unsigned char *p;
+ ssize_t logical_block_size;
+ int32_t volume_block;
+
+ /* Check if current sector is a kind of Supplementary Volume
+ * Descriptor. */
+ if (!isSVD(iso9660, h))
+ return (0);
+
+ /* FIXME: do more validations according to joliet spec. */
+
+ /* check if this SVD contains joliet extension! */
+ p = h + SVD_escape_sequences_offset;
+ /* N.B. Joliet spec says p[1] == '\\', but.... */
+ if (p[0] == '%' && p[1] == '/') {
+ int level = 0;
+
+ if (p[2] == '@')
+ level = 1;
+ else if (p[2] == 'C')
+ level = 2;
+ else if (p[2] == 'E')
+ level = 3;
+ else /* not joliet */
+ return (0);
+
+ iso9660->seenJoliet = level;
+
+ } else /* not joliet */
+ return (0);
+
+ logical_block_size =
+ archive_le16dec(h + SVD_logical_block_size_offset);
+ volume_block = archive_le32dec(h + SVD_volume_space_size_offset);
+
+ iso9660->logical_block_size = logical_block_size;
+ iso9660->volume_block = volume_block;
+ iso9660->volume_size = logical_block_size * (uint64_t)volume_block;
+ /* Read Root Directory Record in Volume Descriptor. */
+ p = h + SVD_root_directory_record_offset;
+ iso9660->joliet.location = archive_le32dec(p + DR_extent_offset);
+ iso9660->joliet.size = archive_le32dec(p + DR_size_offset);
+
+ return (48);
+}
+
+static int
+isSVD(struct iso9660 *iso9660, const unsigned char *h)
+{
+ const unsigned char *p;
+ ssize_t logical_block_size;
+ int32_t volume_block;
+ int32_t location;
+ int i;
+
+ (void)iso9660; /* UNUSED */
+
+ /* Type 2 means it's a SVD. */
+ if (h[SVD_type_offset] != 2)
+ return (0);
+
+ /* Reserved field must be 0. */
+ for (i = 0; i < SVD_reserved1_size; ++i)
+ if (h[SVD_reserved1_offset + i] != 0)
+ return (0);
+ for (i = 0; i < SVD_reserved2_size; ++i)
+ if (h[SVD_reserved2_offset + i] != 0)
+ return (0);
+ for (i = 0; i < SVD_reserved3_size; ++i)
+ if (h[SVD_reserved3_offset + i] != 0)
+ return (0);
+
+ /* File structure version must be 1 for ISO9660/ECMA119. */
+ if (h[SVD_file_structure_version_offset] != 1)
+ return (0);
+
+ logical_block_size =
+ archive_le16dec(h + SVD_logical_block_size_offset);
+ if (logical_block_size <= 0)
+ return (0);
+
+ volume_block = archive_le32dec(h + SVD_volume_space_size_offset);
+ if (volume_block <= SYSTEM_AREA_BLOCK+4)
+ return (0);
+
+ /* Location of Occurrence of Type L Path Table must be
+ * available location,
+ * >= SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */
+ location = archive_le32dec(h+SVD_type_L_path_table_offset);
+ if (location < SYSTEM_AREA_BLOCK+2 || location >= volume_block)
+ return (0);
+
+ /* The Type M Path Table must be at a valid location (WinISO
+ * and probably other programs omit this, so we allow zero)
+ *
+ * >= SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */
+ location = archive_be32dec(h+SVD_type_M_path_table_offset);
+ if ((location > 0 && location < SYSTEM_AREA_BLOCK+2)
+ || location >= volume_block)
+ return (0);
+
+ /* Read Root Directory Record in Volume Descriptor. */
+ p = h + SVD_root_directory_record_offset;
+ if (p[DR_length_offset] != 34)
+ return (0);
+
+ return (48);
+}
+
+static int
+isEVD(struct iso9660 *iso9660, const unsigned char *h)
+{
+ const unsigned char *p;
+ ssize_t logical_block_size;
+ int32_t volume_block;
+ int32_t location;
+ int i;
+
+ (void)iso9660; /* UNUSED */
+
+ /* Type of the Enhanced Volume Descriptor must be 2. */
+ if (h[PVD_type_offset] != 2)
+ return (0);
+
+ /* EVD version must be 2. */
+ if (h[PVD_version_offset] != 2)
+ return (0);
+
+ /* Reserved field must be 0. */
+ if (h[PVD_reserved1_offset] != 0)
+ return (0);
+
+ /* Reserved field must be 0. */
+ for (i = 0; i < PVD_reserved2_size; ++i)
+ if (h[PVD_reserved2_offset + i] != 0)
+ return (0);
+
+ /* Reserved field must be 0. */
+ for (i = 0; i < PVD_reserved3_size; ++i)
+ if (h[PVD_reserved3_offset + i] != 0)
+ return (0);
+
+ /* Logical block size must be > 0. */
+ /* I've looked at Ecma 119 and can't find any stronger
+ * restriction on this field. */
+ logical_block_size =
+ archive_le16dec(h + PVD_logical_block_size_offset);
+ if (logical_block_size <= 0)
+ return (0);
+
+ volume_block =
+ archive_le32dec(h + PVD_volume_space_size_offset);
+ if (volume_block <= SYSTEM_AREA_BLOCK+4)
+ return (0);
+
+ /* File structure version must be 2 for ISO9660:1999. */
+ if (h[PVD_file_structure_version_offset] != 2)
+ return (0);
+
+ /* Location of Occurrence of Type L Path Table must be
+ * available location,
+ * >= SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */
+ location = archive_le32dec(h+PVD_type_1_path_table_offset);
+ if (location < SYSTEM_AREA_BLOCK+2 || location >= volume_block)
+ return (0);
+
+ /* Location of Occurrence of Type M Path Table must be
+ * available location,
+ * >= SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */
+ location = archive_be32dec(h+PVD_type_m_path_table_offset);
+ if ((location > 0 && location < SYSTEM_AREA_BLOCK+2)
+ || location >= volume_block)
+ return (0);
+
+ /* Reserved field must be 0. */
+ for (i = 0; i < PVD_reserved4_size; ++i)
+ if (h[PVD_reserved4_offset + i] != 0)
+ return (0);
+
+ /* Reserved field must be 0. */
+ for (i = 0; i < PVD_reserved5_size; ++i)
+ if (h[PVD_reserved5_offset + i] != 0)
+ return (0);
+
+ /* Read Root Directory Record in Volume Descriptor. */
+ p = h + PVD_root_directory_record_offset;
+ if (p[DR_length_offset] != 34)
+ return (0);
+
+ return (48);
+}
+
+static int
+isPVD(struct iso9660 *iso9660, const unsigned char *h)
+{
+ const unsigned char *p;
+ ssize_t logical_block_size;
+ int32_t volume_block;
+ int32_t location;
+ int i;
+
+ /* Type of the Primary Volume Descriptor must be 1. */
+ if (h[PVD_type_offset] != 1)
+ return (0);
+
+ /* PVD version must be 1. */
+ if (h[PVD_version_offset] != 1)
+ return (0);
+
+ /* Reserved field must be 0. */
+ if (h[PVD_reserved1_offset] != 0)
+ return (0);
+
+ /* Reserved field must be 0. */
+ for (i = 0; i < PVD_reserved2_size; ++i)
+ if (h[PVD_reserved2_offset + i] != 0)
+ return (0);
+
+ /* Reserved field must be 0. */
+ for (i = 0; i < PVD_reserved3_size; ++i)
+ if (h[PVD_reserved3_offset + i] != 0)
+ return (0);
+
+ /* Logical block size must be > 0. */
+ /* I've looked at Ecma 119 and can't find any stronger
+ * restriction on this field. */
+ logical_block_size =
+ archive_le16dec(h + PVD_logical_block_size_offset);
+ if (logical_block_size <= 0)
+ return (0);
+
+ volume_block = archive_le32dec(h + PVD_volume_space_size_offset);
+ if (volume_block <= SYSTEM_AREA_BLOCK+4)
+ return (0);
+
+ /* File structure version must be 1 for ISO9660/ECMA119. */
+ if (h[PVD_file_structure_version_offset] != 1)
+ return (0);
+
+ /* Location of Occurrence of Type L Path Table must be
+ * available location,
+ * > SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */
+ location = archive_le32dec(h+PVD_type_1_path_table_offset);
+ if (location < SYSTEM_AREA_BLOCK+2 || location >= volume_block)
+ return (0);
+
+ /* The Type M Path Table must also be at a valid location
+ * (although ECMA 119 requires a Type M Path Table, WinISO and
+ * probably other programs omit it, so we permit a zero here)
+ *
+ * >= SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */
+ location = archive_be32dec(h+PVD_type_m_path_table_offset);
+ if ((location > 0 && location < SYSTEM_AREA_BLOCK+2)
+ || location >= volume_block)
+ return (0);
+
+ /* Reserved field must be 0. */
+ /* But accept NetBSD/FreeBSD "makefs" images with 0x20 here. */
+ for (i = 0; i < PVD_reserved4_size; ++i)
+ if (h[PVD_reserved4_offset + i] != 0
+ && h[PVD_reserved4_offset + i] != 0x20)
+ return (0);
+
+ /* Reserved field must be 0. */
+ for (i = 0; i < PVD_reserved5_size; ++i)
+ if (h[PVD_reserved5_offset + i] != 0)
+ return (0);
+
+ /* XXX TODO: Check other values for sanity; reject more
+ * malformed PVDs. XXX */
+
+ /* Read Root Directory Record in Volume Descriptor. */
+ p = h + PVD_root_directory_record_offset;
+ if (p[DR_length_offset] != 34)
+ return (0);
+
+ if (!iso9660->primary.location) {
+ iso9660->logical_block_size = logical_block_size;
+ iso9660->volume_block = volume_block;
+ iso9660->volume_size = logical_block_size * (uint64_t)volume_block;
+ iso9660->primary.location = archive_le32dec(p + DR_extent_offset);
+ iso9660->primary.size = archive_le32dec(p + DR_size_offset);
+ }
+
+ return (48);
+}
+
+static int
+read_children(struct archive_read *a, struct file_info *parent)
+{
+ struct iso9660 *iso9660;
+ const unsigned char *b, *p;
+ struct file_info *multi;
+ size_t step, skip_size;
+
+ iso9660 = (struct iso9660 *)(a->format->data);
+ if (iso9660->current_position > parent->offset) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Ignoring out-of-order directory (%s) %jd > %jd",
+ parent->name.s,
+ (intmax_t)iso9660->current_position,
+ (intmax_t)parent->offset);
+ return (ARCHIVE_WARN);
+ }
+ if (parent->offset + parent->size > iso9660->volume_size) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Directory is beyond end-of-media: %s",
+ parent->name.s);
+ return (ARCHIVE_WARN);
+ }
+ if (iso9660->current_position < parent->offset) {
+ int64_t skipsize;
+
+ skipsize = parent->offset - iso9660->current_position;
+ skipsize = __archive_read_consume(a, skipsize);
+ if (skipsize < 0)
+ return ((int)skipsize);
+ iso9660->current_position = parent->offset;
+ }
+
+ step = ((parent->size + iso9660->logical_block_size -1) /
+ iso9660->logical_block_size) * iso9660->logical_block_size;
+ b = __archive_read_ahead(a, step, NULL);
+ if (b == NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Failed to read full block when scanning "
+ "ISO9660 directory list");
+ return (ARCHIVE_FATAL);
+ }
+ iso9660->current_position += step;
+ multi = NULL;
+ skip_size = step;
+ while (step) {
+ p = b;
+ b += iso9660->logical_block_size;
+ step -= iso9660->logical_block_size;
+ for (; *p != 0 && p < b && p + *p <= b; p += *p) {
+ struct file_info *child;
+
+ /* N.B.: these special directory identifiers
+ * are 8 bit "values" even on a
+ * Joliet CD with UCS-2 (16bit) encoding.
+ */
+
+ /* Skip '.' entry. */
+ if (*(p + DR_name_len_offset) == 1
+ && *(p + DR_name_offset) == '\0')
+ continue;
+ /* Skip '..' entry. */
+ if (*(p + DR_name_len_offset) == 1
+ && *(p + DR_name_offset) == '\001')
+ continue;
+ child = parse_file_info(a, parent, p);
+ if (child == NULL) {
+ __archive_read_consume(a, skip_size);
+ return (ARCHIVE_FATAL);
+ }
+ if (child->cl_offset == 0 &&
+ (child->multi_extent || multi != NULL)) {
+ struct content *con;
+
+ if (multi == NULL) {
+ multi = child;
+ multi->contents.first = NULL;
+ multi->contents.last =
+ &(multi->contents.first);
+ }
+ con = malloc(sizeof(struct content));
+ if (con == NULL) {
+ archive_set_error(
+ &a->archive, ENOMEM,
+ "No memory for multi extent");
+ __archive_read_consume(a, skip_size);
+ return (ARCHIVE_FATAL);
+ }
+ con->offset = child->offset;
+ con->size = child->size;
+ con->next = NULL;
+ *multi->contents.last = con;
+ multi->contents.last = &(con->next);
+ if (multi == child) {
+ if (add_entry(a, iso9660, child)
+ != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ } else {
+ multi->size += child->size;
+ if (!child->multi_extent)
+ multi = NULL;
+ }
+ } else
+ if (add_entry(a, iso9660, child) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ __archive_read_consume(a, skip_size);
+
+ /* Read data which recorded by RRIP "CE" extension. */
+ if (read_CE(a, iso9660) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_read_format_iso9660_read_header(struct archive_read *a,
+ struct archive_entry *entry)
+{
+ struct iso9660 *iso9660;
+ struct file_info *file;
+ int r, rd_r = ARCHIVE_OK;
+
+ iso9660 = (struct iso9660 *)(a->format->data);
+
+ if (!a->archive.archive_format) {
+ a->archive.archive_format = ARCHIVE_FORMAT_ISO9660;
+ a->archive.archive_format_name = "ISO9660";
+ }
+
+ if (iso9660->current_position == 0) {
+ int64_t skipsize;
+ struct vd *vd;
+ const void *block;
+ char seenJoliet;
+
+ vd = &(iso9660->primary);
+ if (!iso9660->opt_support_joliet)
+ iso9660->seenJoliet = 0;
+ if (iso9660->seenJoliet &&
+ vd->location > iso9660->joliet.location)
+ /* This condition is unlikely; by way of caution. */
+ vd = &(iso9660->joliet);
+
+ skipsize = LOGICAL_BLOCK_SIZE * vd->location;
+ skipsize = __archive_read_consume(a, skipsize);
+ if (skipsize < 0)
+ return ((int)skipsize);
+ iso9660->current_position = skipsize;
+
+ block = __archive_read_ahead(a, vd->size, NULL);
+ if (block == NULL) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Failed to read full block when scanning "
+ "ISO9660 directory list");
+ return (ARCHIVE_FATAL);
+ }
+
+ /*
+ * While reading Root Directory, flag seenJoliet
+ * must be zero to avoid converting special name
+ * 0x00(Current Directory) and next byte to UCS2.
+ */
+ seenJoliet = iso9660->seenJoliet;/* Save flag. */
+ iso9660->seenJoliet = 0;
+ file = parse_file_info(a, NULL, block);
+ if (file == NULL)
+ return (ARCHIVE_FATAL);
+ iso9660->seenJoliet = seenJoliet;
+ if (vd == &(iso9660->primary) && iso9660->seenRockridge
+ && iso9660->seenJoliet)
+ /*
+ * If iso image has RockRidge and Joliet,
+ * we use RockRidge Extensions.
+ */
+ iso9660->seenJoliet = 0;
+ if (vd == &(iso9660->primary) && !iso9660->seenRockridge
+ && iso9660->seenJoliet) {
+ /* Switch reading data from primary to joliet. */
+ vd = &(iso9660->joliet);
+ skipsize = LOGICAL_BLOCK_SIZE * vd->location;
+ skipsize -= iso9660->current_position;
+ skipsize = __archive_read_consume(a, skipsize);
+ if (skipsize < 0)
+ return ((int)skipsize);
+ iso9660->current_position += skipsize;
+
+ block = __archive_read_ahead(a, vd->size, NULL);
+ if (block == NULL) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Failed to read full block when scanning "
+ "ISO9660 directory list");
+ return (ARCHIVE_FATAL);
+ }
+ iso9660->seenJoliet = 0;
+ file = parse_file_info(a, NULL, block);
+ if (file == NULL)
+ return (ARCHIVE_FATAL);
+ iso9660->seenJoliet = seenJoliet;
+ }
+ /* Store the root directory in the pending list. */
+ if (add_entry(a, iso9660, file) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ if (iso9660->seenRockridge) {
+ a->archive.archive_format =
+ ARCHIVE_FORMAT_ISO9660_ROCKRIDGE;
+ a->archive.archive_format_name =
+ "ISO9660 with Rockridge extensions";
+ }
+ }
+
+ file = NULL;/* Eliminate a warning. */
+ /* Get the next entry that appears after the current offset. */
+ r = next_entry_seek(a, iso9660, &file);
+ if (r != ARCHIVE_OK)
+ return (r);
+
+ if (iso9660->seenJoliet) {
+ /*
+ * Convert UTF-16BE of a filename to local locale MBS
+ * and store the result into a filename field.
+ */
+ if (iso9660->sconv_utf16be == NULL) {
+ iso9660->sconv_utf16be =
+ archive_string_conversion_from_charset(
+ &(a->archive), "UTF-16BE", 1);
+ if (iso9660->sconv_utf16be == NULL)
+ /* Coundn't allocate memory */
+ return (ARCHIVE_FATAL);
+ }
+ if (iso9660->utf16be_path == NULL) {
+ iso9660->utf16be_path = malloc(UTF16_NAME_MAX);
+ if (iso9660->utf16be_path == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "No memory");
+ return (ARCHIVE_FATAL);
+ }
+ }
+ if (iso9660->utf16be_previous_path == NULL) {
+ iso9660->utf16be_previous_path = malloc(UTF16_NAME_MAX);
+ if (iso9660->utf16be_previous_path == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "No memory");
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ iso9660->utf16be_path_len = 0;
+ if (build_pathname_utf16be(iso9660->utf16be_path,
+ UTF16_NAME_MAX, &(iso9660->utf16be_path_len), file) != 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Pathname is too long");
+ }
+
+ r = archive_entry_copy_pathname_l(entry,
+ (const char *)iso9660->utf16be_path,
+ iso9660->utf16be_path_len,
+ iso9660->sconv_utf16be);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "No memory for Pathname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Pathname cannot be converted "
+ "from %s to current locale.",
+ archive_string_conversion_charset_name(
+ iso9660->sconv_utf16be));
+
+ rd_r = ARCHIVE_WARN;
+ }
+ } else {
+ archive_string_empty(&iso9660->pathname);
+ archive_entry_set_pathname(entry,
+ build_pathname(&iso9660->pathname, file));
+ }
+
+ iso9660->entry_bytes_remaining = file->size;
+ iso9660->entry_sparse_offset = 0; /* Offset for sparse-file-aware clients. */
+
+ if (file->offset + file->size > iso9660->volume_size) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "File is beyond end-of-media: %s",
+ archive_entry_pathname(entry));
+ iso9660->entry_bytes_remaining = 0;
+ iso9660->entry_sparse_offset = 0;
+ return (ARCHIVE_WARN);
+ }
+
+ /* Set up the entry structure with information about this entry. */
+ archive_entry_set_mode(entry, file->mode);
+ archive_entry_set_uid(entry, file->uid);
+ archive_entry_set_gid(entry, file->gid);
+ archive_entry_set_nlink(entry, file->nlinks);
+ if (file->birthtime_is_set)
+ archive_entry_set_birthtime(entry, file->birthtime, 0);
+ else
+ archive_entry_unset_birthtime(entry);
+ archive_entry_set_mtime(entry, file->mtime, 0);
+ archive_entry_set_ctime(entry, file->ctime, 0);
+ archive_entry_set_atime(entry, file->atime, 0);
+ /* N.B.: Rock Ridge supports 64-bit device numbers. */
+ archive_entry_set_rdev(entry, (dev_t)file->rdev);
+ archive_entry_set_size(entry, iso9660->entry_bytes_remaining);
+ if (file->symlink.s != NULL)
+ archive_entry_copy_symlink(entry, file->symlink.s);
+
+ /* Note: If the input isn't seekable, we can't rewind to
+ * return the same body again, so if the next entry refers to
+ * the same data, we have to return it as a hardlink to the
+ * original entry. */
+ if (file->number != -1 &&
+ file->number == iso9660->previous_number) {
+ if (iso9660->seenJoliet) {
+ r = archive_entry_copy_hardlink_l(entry,
+ (const char *)iso9660->utf16be_previous_path,
+ iso9660->utf16be_previous_path_len,
+ iso9660->sconv_utf16be);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "No memory for Linkname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Linkname cannot be converted "
+ "from %s to current locale.",
+ archive_string_conversion_charset_name(
+ iso9660->sconv_utf16be));
+ rd_r = ARCHIVE_WARN;
+ }
+ } else
+ archive_entry_set_hardlink(entry,
+ iso9660->previous_pathname.s);
+ archive_entry_unset_size(entry);
+ iso9660->entry_bytes_remaining = 0;
+ iso9660->entry_sparse_offset = 0;
+ return (rd_r);
+ }
+
+ /* Except for the hardlink case above, if the offset of the
+ * next entry is before our current position, we can't seek
+ * backwards to extract it, so issue a warning. Note that
+ * this can only happen if this entry was added to the heap
+ * after we passed this offset, that is, only if the directory
+ * mentioning this entry is later than the body of the entry.
+ * Such layouts are very unusual; most ISO9660 writers lay out
+ * and record all directory information first, then store
+ * all file bodies. */
+ /* TODO: Someday, libarchive's I/O core will support optional
+ * seeking. When that day comes, this code should attempt to
+ * seek and only return the error if the seek fails. That
+ * will give us support for whacky ISO images that require
+ * seeking while retaining the ability to read almost all ISO
+ * images in a streaming fashion. */
+ if ((file->mode & AE_IFMT) != AE_IFDIR &&
+ file->offset < iso9660->current_position) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Ignoring out-of-order file @%jx (%s) %jd < %jd",
+ (intmax_t)file->number,
+ iso9660->pathname.s,
+ (intmax_t)file->offset,
+ (intmax_t)iso9660->current_position);
+ iso9660->entry_bytes_remaining = 0;
+ iso9660->entry_sparse_offset = 0;
+ return (ARCHIVE_WARN);
+ }
+
+ /* Initialize zisofs variables. */
+ iso9660->entry_zisofs.pz = file->pz;
+ if (file->pz) {
+#ifdef HAVE_ZLIB_H
+ struct zisofs *zisofs;
+
+ zisofs = &iso9660->entry_zisofs;
+ zisofs->initialized = 0;
+ zisofs->pz_log2_bs = file->pz_log2_bs;
+ zisofs->pz_uncompressed_size = file->pz_uncompressed_size;
+ zisofs->pz_offset = 0;
+ zisofs->header_avail = 0;
+ zisofs->header_passed = 0;
+ zisofs->block_pointers_avail = 0;
+#endif
+ archive_entry_set_size(entry, file->pz_uncompressed_size);
+ }
+
+ iso9660->previous_number = file->number;
+ if (iso9660->seenJoliet) {
+ memcpy(iso9660->utf16be_previous_path, iso9660->utf16be_path,
+ iso9660->utf16be_path_len);
+ iso9660->utf16be_previous_path_len = iso9660->utf16be_path_len;
+ } else
+ archive_strcpy(
+ &iso9660->previous_pathname, iso9660->pathname.s);
+
+ /* Reset entry_bytes_remaining if the file is multi extent. */
+ iso9660->entry_content = file->contents.first;
+ if (iso9660->entry_content != NULL)
+ iso9660->entry_bytes_remaining = iso9660->entry_content->size;
+
+ if (archive_entry_filetype(entry) == AE_IFDIR) {
+ /* Overwrite nlinks by proper link number which is
+ * calculated from number of sub directories. */
+ archive_entry_set_nlink(entry, 2 + file->subdirs);
+ /* Directory data has been read completely. */
+ iso9660->entry_bytes_remaining = 0;
+ iso9660->entry_sparse_offset = 0;
+ }
+
+ if (rd_r != ARCHIVE_OK)
+ return (rd_r);
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_read_format_iso9660_read_data_skip(struct archive_read *a)
+{
+ /* Because read_next_header always does an explicit skip
+ * to the next entry, we don't need to do anything here. */
+ (void)a; /* UNUSED */
+ return (ARCHIVE_OK);
+}
+
+#ifdef HAVE_ZLIB_H
+
+static int
+zisofs_read_data(struct archive_read *a,
+ const void **buff, size_t *size, int64_t *offset)
+{
+ struct iso9660 *iso9660;
+ struct zisofs *zisofs;
+ const unsigned char *p;
+ size_t avail;
+ ssize_t bytes_read;
+ size_t uncompressed_size;
+ int r;
+
+ iso9660 = (struct iso9660 *)(a->format->data);
+ zisofs = &iso9660->entry_zisofs;
+
+ p = __archive_read_ahead(a, 1, &bytes_read);
+ if (bytes_read <= 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated zisofs file body");
+ return (ARCHIVE_FATAL);
+ }
+ if (bytes_read > iso9660->entry_bytes_remaining)
+ bytes_read = iso9660->entry_bytes_remaining;
+ avail = bytes_read;
+ uncompressed_size = 0;
+
+ if (!zisofs->initialized) {
+ size_t ceil, xsize;
+
+ /* Allocate block pointers buffer. */
+ ceil = (zisofs->pz_uncompressed_size +
+ (((int64_t)1) << zisofs->pz_log2_bs) - 1)
+ >> zisofs->pz_log2_bs;
+ xsize = (ceil + 1) * 4;
+ if (zisofs->block_pointers_alloc < xsize) {
+ size_t alloc;
+
+ if (zisofs->block_pointers != NULL)
+ free(zisofs->block_pointers);
+ alloc = ((xsize >> 10) + 1) << 10;
+ zisofs->block_pointers = malloc(alloc);
+ if (zisofs->block_pointers == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "No memory for zisofs decompression");
+ return (ARCHIVE_FATAL);
+ }
+ zisofs->block_pointers_alloc = alloc;
+ }
+ zisofs->block_pointers_size = xsize;
+
+ /* Allocate uncompressed data buffer. */
+ xsize = 1UL << zisofs->pz_log2_bs;
+ if (zisofs->uncompressed_buffer_size < xsize) {
+ if (zisofs->uncompressed_buffer != NULL)
+ free(zisofs->uncompressed_buffer);
+ zisofs->uncompressed_buffer = malloc(xsize);
+ if (zisofs->uncompressed_buffer == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "No memory for zisofs decompression");
+ return (ARCHIVE_FATAL);
+ }
+ }
+ zisofs->uncompressed_buffer_size = xsize;
+
+ /*
+ * Read the file header, and check the magic code of zisofs.
+ */
+ if (zisofs->header_avail < sizeof(zisofs->header)) {
+ xsize = sizeof(zisofs->header) - zisofs->header_avail;
+ if (avail < xsize)
+ xsize = avail;
+ memcpy(zisofs->header + zisofs->header_avail, p, xsize);
+ zisofs->header_avail += xsize;
+ avail -= xsize;
+ p += xsize;
+ }
+ if (!zisofs->header_passed &&
+ zisofs->header_avail == sizeof(zisofs->header)) {
+ int err = 0;
+
+ if (memcmp(zisofs->header, zisofs_magic,
+ sizeof(zisofs_magic)) != 0)
+ err = 1;
+ if (archive_le32dec(zisofs->header + 8)
+ != zisofs->pz_uncompressed_size)
+ err = 1;
+ if (zisofs->header[12] != 4)
+ err = 1;
+ if (zisofs->header[13] != zisofs->pz_log2_bs)
+ err = 1;
+ if (err) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Illegal zisofs file body");
+ return (ARCHIVE_FATAL);
+ }
+ zisofs->header_passed = 1;
+ }
+ /*
+ * Read block pointers.
+ */
+ if (zisofs->header_passed &&
+ zisofs->block_pointers_avail < zisofs->block_pointers_size) {
+ xsize = zisofs->block_pointers_size
+ - zisofs->block_pointers_avail;
+ if (avail < xsize)
+ xsize = avail;
+ memcpy(zisofs->block_pointers
+ + zisofs->block_pointers_avail, p, xsize);
+ zisofs->block_pointers_avail += xsize;
+ avail -= xsize;
+ p += xsize;
+ if (zisofs->block_pointers_avail
+ == zisofs->block_pointers_size) {
+ /* We've got all block pointers and initialize
+ * related variables. */
+ zisofs->block_off = 0;
+ zisofs->block_avail = 0;
+ /* Complete a initialization */
+ zisofs->initialized = 1;
+ }
+ }
+
+ if (!zisofs->initialized)
+ goto next_data; /* We need more data. */
+ }
+
+ /*
+ * Get block offsets from block pointers.
+ */
+ if (zisofs->block_avail == 0) {
+ uint32_t bst, bed;
+
+ if (zisofs->block_off + 4 >= zisofs->block_pointers_size) {
+ /* There isn't a pair of offsets. */
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Illegal zisofs block pointers");
+ return (ARCHIVE_FATAL);
+ }
+ bst = archive_le32dec(
+ zisofs->block_pointers + zisofs->block_off);
+ if (bst != zisofs->pz_offset + (bytes_read - avail)) {
+ /* TODO: Should we seek offset of current file
+ * by bst ? */
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Illegal zisofs block pointers(cannot seek)");
+ return (ARCHIVE_FATAL);
+ }
+ bed = archive_le32dec(
+ zisofs->block_pointers + zisofs->block_off + 4);
+ if (bed < bst) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Illegal zisofs block pointers");
+ return (ARCHIVE_FATAL);
+ }
+ zisofs->block_avail = bed - bst;
+ zisofs->block_off += 4;
+
+ /* Initialize compression library for new block. */
+ if (zisofs->stream_valid)
+ r = inflateReset(&zisofs->stream);
+ else
+ r = inflateInit(&zisofs->stream);
+ if (r != Z_OK) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Can't initialize zisofs decompression.");
+ return (ARCHIVE_FATAL);
+ }
+ zisofs->stream_valid = 1;
+ zisofs->stream.total_in = 0;
+ zisofs->stream.total_out = 0;
+ }
+
+ /*
+ * Make uncompressed data.
+ */
+ if (zisofs->block_avail == 0) {
+ memset(zisofs->uncompressed_buffer, 0,
+ zisofs->uncompressed_buffer_size);
+ uncompressed_size = zisofs->uncompressed_buffer_size;
+ } else {
+ zisofs->stream.next_in = (Bytef *)(uintptr_t)(const void *)p;
+ if (avail > zisofs->block_avail)
+ zisofs->stream.avail_in = zisofs->block_avail;
+ else
+ zisofs->stream.avail_in = avail;
+ zisofs->stream.next_out = zisofs->uncompressed_buffer;
+ zisofs->stream.avail_out = zisofs->uncompressed_buffer_size;
+
+ r = inflate(&zisofs->stream, 0);
+ switch (r) {
+ case Z_OK: /* Decompressor made some progress.*/
+ case Z_STREAM_END: /* Found end of stream. */
+ break;
+ default:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "zisofs decompression failed (%d)", r);
+ return (ARCHIVE_FATAL);
+ }
+ uncompressed_size =
+ zisofs->uncompressed_buffer_size - zisofs->stream.avail_out;
+ avail -= zisofs->stream.next_in - p;
+ zisofs->block_avail -= zisofs->stream.next_in - p;
+ }
+next_data:
+ bytes_read -= avail;
+ *buff = zisofs->uncompressed_buffer;
+ *size = uncompressed_size;
+ *offset = iso9660->entry_sparse_offset;
+ iso9660->entry_sparse_offset += uncompressed_size;
+ iso9660->entry_bytes_remaining -= bytes_read;
+ iso9660->current_position += bytes_read;
+ zisofs->pz_offset += bytes_read;
+ iso9660->entry_bytes_unconsumed += bytes_read;
+
+ return (ARCHIVE_OK);
+}
+
+#else /* HAVE_ZLIB_H */
+
+static int
+zisofs_read_data(struct archive_read *a,
+ const void **buff, size_t *size, int64_t *offset)
+{
+
+ (void)buff;/* UNUSED */
+ (void)size;/* UNUSED */
+ (void)offset;/* UNUSED */
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "zisofs is not supported on this platform.");
+ return (ARCHIVE_FAILED);
+}
+
+#endif /* HAVE_ZLIB_H */
+
+static int
+archive_read_format_iso9660_read_data(struct archive_read *a,
+ const void **buff, size_t *size, int64_t *offset)
+{
+ ssize_t bytes_read;
+ struct iso9660 *iso9660;
+
+ iso9660 = (struct iso9660 *)(a->format->data);
+
+ if (iso9660->entry_bytes_unconsumed) {
+ __archive_read_consume(a, iso9660->entry_bytes_unconsumed);
+ iso9660->entry_bytes_unconsumed = 0;
+ }
+
+ if (iso9660->entry_bytes_remaining <= 0) {
+ if (iso9660->entry_content != NULL)
+ iso9660->entry_content = iso9660->entry_content->next;
+ if (iso9660->entry_content == NULL) {
+ *buff = NULL;
+ *size = 0;
+ *offset = iso9660->entry_sparse_offset;
+ return (ARCHIVE_EOF);
+ }
+ /* Seek forward to the start of the entry. */
+ if (iso9660->current_position < iso9660->entry_content->offset) {
+ int64_t step;
+
+ step = iso9660->entry_content->offset -
+ iso9660->current_position;
+ step = __archive_read_consume(a, step);
+ if (step < 0)
+ return ((int)step);
+ iso9660->current_position =
+ iso9660->entry_content->offset;
+ }
+ if (iso9660->entry_content->offset < iso9660->current_position) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Ignoring out-of-order file (%s) %jd < %jd",
+ iso9660->pathname.s,
+ (intmax_t)iso9660->entry_content->offset,
+ (intmax_t)iso9660->current_position);
+ *buff = NULL;
+ *size = 0;
+ *offset = iso9660->entry_sparse_offset;
+ return (ARCHIVE_WARN);
+ }
+ iso9660->entry_bytes_remaining = iso9660->entry_content->size;
+ }
+ if (iso9660->entry_zisofs.pz)
+ return (zisofs_read_data(a, buff, size, offset));
+
+ *buff = __archive_read_ahead(a, 1, &bytes_read);
+ if (bytes_read == 0)
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Truncated input file");
+ if (*buff == NULL)
+ return (ARCHIVE_FATAL);
+ if (bytes_read > iso9660->entry_bytes_remaining)
+ bytes_read = iso9660->entry_bytes_remaining;
+ *size = bytes_read;
+ *offset = iso9660->entry_sparse_offset;
+ iso9660->entry_sparse_offset += bytes_read;
+ iso9660->entry_bytes_remaining -= bytes_read;
+ iso9660->entry_bytes_unconsumed = bytes_read;
+ iso9660->current_position += bytes_read;
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_read_format_iso9660_cleanup(struct archive_read *a)
+{
+ struct iso9660 *iso9660;
+ int r = ARCHIVE_OK;
+
+ iso9660 = (struct iso9660 *)(a->format->data);
+ release_files(iso9660);
+ free(iso9660->read_ce_req.reqs);
+ archive_string_free(&iso9660->pathname);
+ archive_string_free(&iso9660->previous_pathname);
+ if (iso9660->pending_files.files)
+ free(iso9660->pending_files.files);
+#ifdef HAVE_ZLIB_H
+ free(iso9660->entry_zisofs.uncompressed_buffer);
+ free(iso9660->entry_zisofs.block_pointers);
+ if (iso9660->entry_zisofs.stream_valid) {
+ if (inflateEnd(&iso9660->entry_zisofs.stream) != Z_OK) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Failed to clean up zlib decompressor");
+ r = ARCHIVE_FATAL;
+ }
+ }
+#endif
+ free(iso9660->utf16be_path);
+ free(iso9660->utf16be_previous_path);
+ free(iso9660);
+ (a->format->data) = NULL;
+ return (r);
+}
+
+/*
+ * This routine parses a single ISO directory record, makes sense
+ * of any extensions, and stores the result in memory.
+ */
+static struct file_info *
+parse_file_info(struct archive_read *a, struct file_info *parent,
+ const unsigned char *isodirrec)
+{
+ struct iso9660 *iso9660;
+ struct file_info *file;
+ size_t name_len;
+ const unsigned char *rr_start, *rr_end;
+ const unsigned char *p;
+ size_t dr_len;
+ uint64_t fsize;
+ int32_t location;
+ int flags;
+
+ iso9660 = (struct iso9660 *)(a->format->data);
+
+ dr_len = (size_t)isodirrec[DR_length_offset];
+ name_len = (size_t)isodirrec[DR_name_len_offset];
+ location = archive_le32dec(isodirrec + DR_extent_offset);
+ fsize = toi(isodirrec + DR_size_offset, DR_size_size);
+ /* Sanity check that dr_len needs at least 34. */
+ if (dr_len < 34) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Invalid length of directory record");
+ return (NULL);
+ }
+ /* Sanity check that name_len doesn't exceed dr_len. */
+ if (dr_len - 33 < name_len || name_len == 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Invalid length of file identifier");
+ return (NULL);
+ }
+ /* Sanity check that location doesn't exceed volume block.
+ * Don't check lower limit of location; it's possibility
+ * the location has negative value when file type is symbolic
+ * link or file size is zero. As far as I know latest mkisofs
+ * do that.
+ */
+ if (location > 0 &&
+ (location + ((fsize + iso9660->logical_block_size -1)
+ / iso9660->logical_block_size)) > iso9660->volume_block) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Invalid location of extent of file");
+ return (NULL);
+ }
+ /* Sanity check that location doesn't have a negative value
+ * when the file is not empty. it's too large. */
+ if (fsize != 0 && location < 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Invalid location of extent of file");
+ 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) {
+ archive_set_error(&a->archive, ENOMEM,
+ "No memory for file entry");
+ return (NULL);
+ }
+ file->parent = parent;
+ file->offset = iso9660->logical_block_size * (uint64_t)location;
+ file->size = fsize;
+ file->mtime = isodate7(isodirrec + DR_date_offset);
+ file->ctime = file->atime = file->mtime;
+ file->rede_files.first = NULL;
+ file->rede_files.last = &(file->rede_files.first);
+
+ p = isodirrec + DR_name_offset;
+ /* Rockridge extensions (if any) follow name. Compute this
+ * before fidgeting the name_len below. */
+ rr_start = p + name_len + (name_len & 1 ? 0 : 1);
+ rr_end = isodirrec + dr_len;
+
+ if (iso9660->seenJoliet) {
+ /* Joliet names are max 64 chars (128 bytes) according to spec,
+ * but genisoimage/mkisofs allows recording longer Joliet
+ * names which are 103 UCS2 characters(206 bytes) by their
+ * option '-joliet-long'.
+ */
+ if (name_len > 206)
+ name_len = 206;
+ name_len &= ~1;
+
+ /* trim trailing first version and dot from filename.
+ *
+ * Remember we were in UTF-16BE land!
+ * SEPARATOR 1 (.) and SEPARATOR 2 (;) are both
+ * 16 bits big endian characters on Joliet.
+ *
+ * TODO: sanitize filename?
+ * Joliet allows any UCS-2 char except:
+ * *, /, :, ;, ? and \.
+ */
+ /* Chop off trailing ';1' from files. */
+ if (name_len > 4 && p[name_len-4] == 0 && p[name_len-3] == ';'
+ && p[name_len-2] == 0 && p[name_len-1] == '1')
+ name_len -= 4;
+#if 0 /* XXX: this somehow manages to strip of single-character file extensions, like '.c'. */
+ /* Chop off trailing '.' from filenames. */
+ if (name_len > 2 && p[name_len-2] == 0 && p[name_len-1] == '.')
+ name_len -= 2;
+#endif
+ if ((file->utf16be_name = malloc(name_len)) == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "No memory for file name");
+ return (NULL);
+ }
+ memcpy(file->utf16be_name, p, name_len);
+ file->utf16be_bytes = name_len;
+ } else {
+ /* Chop off trailing ';1' from files. */
+ if (name_len > 2 && p[name_len - 2] == ';' &&
+ p[name_len - 1] == '1')
+ name_len -= 2;
+ /* Chop off trailing '.' from filenames. */
+ if (name_len > 1 && p[name_len - 1] == '.')
+ --name_len;
+
+ archive_strncpy(&file->name, (const char *)p, name_len);
+ }
+
+ flags = isodirrec[DR_flags_offset];
+ if (flags & 0x02)
+ file->mode = AE_IFDIR | 0700;
+ else
+ file->mode = AE_IFREG | 0400;
+ if (flags & 0x80)
+ file->multi_extent = 1;
+ else
+ file->multi_extent = 0;
+ /*
+ * Use a location for the file number, which is treated as an inode
+ * number to find out hardlink target. If Rockridge extensions is
+ * being used, the file number will be overwritten by FILE SERIAL
+ * NUMBER of RRIP "PX" extension.
+ * Note: Old mkisofs did not record that FILE SERIAL NUMBER
+ * in ISO images.
+ * Note2: xorriso set 0 to the location of a symlink file.
+ */
+ if (file->size == 0 && location >= 0) {
+ /* If file->size is zero, its location points wrong place,
+ * and so we should not use it for the file number.
+ * When the location has negative value, it can be used
+ * for the file number.
+ */
+ file->number = -1;
+ /* Do not appear before any directory entries. */
+ file->offset = -1;
+ } else
+ file->number = (int64_t)(uint32_t)location;
+
+ /* Rockridge extensions overwrite information from above. */
+ if (iso9660->opt_support_rockridge) {
+ if (parent == NULL && rr_end - rr_start >= 7) {
+ p = rr_start;
+ if (p[0] == 'S' && p[1] == 'P'
+ && p[2] == 7 && p[3] == 1
+ && p[4] == 0xBE && p[5] == 0xEF) {
+ /*
+ * SP extension stores the suspOffset
+ * (Number of bytes to skip between
+ * filename and SUSP records.)
+ * It is mandatory by the SUSP standard
+ * (IEEE 1281).
+ *
+ * It allows SUSP to coexist with
+ * non-SUSP uses of the System
+ * Use Area by placing non-SUSP data
+ * before SUSP data.
+ *
+ * SP extension must be in the root
+ * directory entry, disable all SUSP
+ * processing if not found.
+ */
+ iso9660->suspOffset = p[6];
+ iso9660->seenSUSP = 1;
+ rr_start += 7;
+ }
+ }
+ if (iso9660->seenSUSP) {
+ int r;
+
+ file->name_continues = 0;
+ file->symlink_continues = 0;
+ rr_start += iso9660->suspOffset;
+ r = parse_rockridge(a, file, rr_start, rr_end);
+ if (r != ARCHIVE_OK) {
+ free(file);
+ return (NULL);
+ }
+ } else
+ /* If there isn't SUSP, disable parsing
+ * rock ridge extensions. */
+ iso9660->opt_support_rockridge = 0;
+ }
+
+ file->nlinks = 1;/* Reset nlink. we'll calculate it later. */
+ /* Tell file's parent how many children that parent has. */
+ if (parent != NULL && (flags & 0x02))
+ parent->subdirs++;
+
+ if (iso9660->seenRockridge) {
+ if (parent != NULL && parent->parent == NULL &&
+ (flags & 0x02) && iso9660->rr_moved == NULL &&
+ (strcmp(file->name.s, "rr_moved") == 0 ||
+ strcmp(file->name.s, ".rr_moved") == 0)) {
+ iso9660->rr_moved = file;
+ file->rr_moved = 1;
+ file->rr_moved_has_re_only = 1;
+ file->re = 0;
+ parent->subdirs--;
+ } else if (file->re) {
+ /*
+ * Sanity check: file's parent is rr_moved.
+ */
+ if (parent == NULL || parent->rr_moved == 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Invalid Rockridge RE");
+ return (NULL);
+ }
+ /*
+ * Sanity check: file does not have "CL" extension.
+ */
+ if (file->cl_offset) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Invalid Rockridge RE and CL");
+ return (NULL);
+ }
+ /*
+ * Sanity check: The file type must be a directory.
+ */
+ if ((flags & 0x02) == 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Invalid Rockridge RE");
+ return (NULL);
+ }
+ } else if (parent != NULL && parent->rr_moved)
+ file->rr_moved_has_re_only = 0;
+ else if (parent != NULL && (flags & 0x02) &&
+ (parent->re || parent->re_descendant))
+ file->re_descendant = 1;
+ if (file->cl_offset) {
+ struct file_info *r;
+
+ if (parent == NULL || parent->parent == NULL) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Invalid Rockridge CL");
+ return (NULL);
+ }
+ /*
+ * Sanity check: The file type must be a regular file.
+ */
+ if ((flags & 0x02) != 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Invalid Rockridge CL");
+ return (NULL);
+ }
+ parent->subdirs++;
+ /* Overwrite an offset and a number of this "CL" entry
+ * to appear before other dirs. "+1" to those is to
+ * make sure to appear after "RE" entry which this
+ * "CL" entry should be connected with. */
+ file->offset = file->number = file->cl_offset + 1;
+
+ /*
+ * Sanity check: cl_offset does not point at its
+ * the parents or itself.
+ */
+ for (r = parent; r; r = r->parent) {
+ if (r->offset == file->cl_offset) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Invalid Rockridge CL");
+ return (NULL);
+ }
+ }
+ if (file->cl_offset == file->offset ||
+ parent->rr_moved) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Invalid Rockridge CL");
+ return (NULL);
+ }
+ }
+ }
+
+#if DEBUG
+ /* DEBUGGING: Warn about attributes I don't yet fully support. */
+ if ((flags & ~0x02) != 0) {
+ fprintf(stderr, "\n ** Unrecognized flag: ");
+ dump_isodirrec(stderr, isodirrec);
+ fprintf(stderr, "\n");
+ } else if (toi(isodirrec + DR_volume_sequence_number_offset, 2) != 1) {
+ fprintf(stderr, "\n ** Unrecognized sequence number: ");
+ dump_isodirrec(stderr, isodirrec);
+ fprintf(stderr, "\n");
+ } else if (*(isodirrec + DR_file_unit_size_offset) != 0) {
+ fprintf(stderr, "\n ** Unexpected file unit size: ");
+ dump_isodirrec(stderr, isodirrec);
+ fprintf(stderr, "\n");
+ } else if (*(isodirrec + DR_interleave_offset) != 0) {
+ fprintf(stderr, "\n ** Unexpected interleave: ");
+ dump_isodirrec(stderr, isodirrec);
+ fprintf(stderr, "\n");
+ } else if (*(isodirrec + DR_ext_attr_length_offset) != 0) {
+ fprintf(stderr, "\n ** Unexpected extended attribute length: ");
+ dump_isodirrec(stderr, isodirrec);
+ fprintf(stderr, "\n");
+ }
+#endif
+ register_file(iso9660, file);
+ return (file);
+}
+
+static int
+parse_rockridge(struct archive_read *a, struct file_info *file,
+ const unsigned char *p, const unsigned char *end)
+{
+ struct iso9660 *iso9660;
+
+ iso9660 = (struct iso9660 *)(a->format->data);
+
+ while (p + 4 <= end /* Enough space for another entry. */
+ && p[0] >= 'A' && p[0] <= 'Z' /* Sanity-check 1st char of name. */
+ && p[1] >= 'A' && p[1] <= 'Z' /* Sanity-check 2nd char of name. */
+ && p[2] >= 4 /* Sanity-check length. */
+ && p + p[2] <= end) { /* Sanity-check length. */
+ const unsigned char *data = p + 4;
+ int data_length = p[2] - 4;
+ int version = p[3];
+
+ /*
+ * Yes, each 'if' here does test p[0] again.
+ * Otherwise, the fall-through handling to catch
+ * unsupported extensions doesn't work.
+ */
+ switch(p[0]) {
+ case 'C':
+ if (p[0] == 'C' && p[1] == 'E') {
+ if (version == 1 && data_length == 24) {
+ /*
+ * CE extension comprises:
+ * 8 byte sector containing extension
+ * 8 byte offset w/in above sector
+ * 8 byte length of continuation
+ */
+ int32_t location =
+ archive_le32dec(data);
+ file->ce_offset =
+ archive_le32dec(data+8);
+ file->ce_size =
+ archive_le32dec(data+16);
+ if (register_CE(a, location, file)
+ != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
+ break;
+ }
+ if (p[0] == 'C' && p[1] == 'L') {
+ if (version == 1 && data_length == 8) {
+ file->cl_offset = (uint64_t)
+ iso9660->logical_block_size *
+ (uint64_t)archive_le32dec(data);
+ iso9660->seenRockridge = 1;
+ }
+ break;
+ }
+ /* FALLTHROUGH */
+ case 'N':
+ if (p[0] == 'N' && p[1] == 'M') {
+ if (version == 1) {
+ parse_rockridge_NM1(file,
+ data, data_length);
+ iso9660->seenRockridge = 1;
+ }
+ break;
+ }
+ /* FALLTHROUGH */
+ case 'P':
+ if (p[0] == 'P' && p[1] == 'D') {
+ /*
+ * PD extension is padding;
+ * contents are always ignored.
+ */
+ break;
+ }
+ if (p[0] == 'P' && p[1] == 'L') {
+ /*
+ * PL extension won't appear;
+ * contents are always ignored.
+ */
+ break;
+ }
+ if (p[0] == 'P' && p[1] == 'N') {
+ if (version == 1 && data_length == 16) {
+ file->rdev = toi(data,4);
+ file->rdev <<= 32;
+ file->rdev |= toi(data + 8, 4);
+ iso9660->seenRockridge = 1;
+ }
+ break;
+ }
+ if (p[0] == 'P' && p[1] == 'X') {
+ /*
+ * PX extension comprises:
+ * 8 bytes for mode,
+ * 8 bytes for nlinks,
+ * 8 bytes for uid,
+ * 8 bytes for gid,
+ * 8 bytes for inode.
+ */
+ if (version == 1) {
+ if (data_length >= 8)
+ file->mode
+ = toi(data, 4);
+ if (data_length >= 16)
+ file->nlinks
+ = toi(data + 8, 4);
+ if (data_length >= 24)
+ file->uid
+ = toi(data + 16, 4);
+ if (data_length >= 32)
+ file->gid
+ = toi(data + 24, 4);
+ if (data_length >= 40)
+ file->number
+ = toi(data + 32, 4);
+ iso9660->seenRockridge = 1;
+ }
+ break;
+ }
+ /* FALLTHROUGH */
+ case 'R':
+ if (p[0] == 'R' && p[1] == 'E' && version == 1) {
+ file->re = 1;
+ iso9660->seenRockridge = 1;
+ break;
+ }
+ if (p[0] == 'R' && p[1] == 'R' && version == 1) {
+ /*
+ * RR extension comprises:
+ * one byte flag value
+ * This extension is obsolete,
+ * so contents are always ignored.
+ */
+ break;
+ }
+ /* FALLTHROUGH */
+ case 'S':
+ if (p[0] == 'S' && p[1] == 'L') {
+ if (version == 1) {
+ parse_rockridge_SL1(file,
+ data, data_length);
+ iso9660->seenRockridge = 1;
+ }
+ break;
+ }
+ if (p[0] == 'S' && p[1] == 'T'
+ && data_length == 0 && version == 1) {
+ /*
+ * ST extension marks end of this
+ * block of SUSP entries.
+ *
+ * It allows SUSP to coexist with
+ * non-SUSP uses of the System
+ * Use Area by placing non-SUSP data
+ * after SUSP data.
+ */
+ iso9660->seenSUSP = 0;
+ iso9660->seenRockridge = 0;
+ return (ARCHIVE_OK);
+ }
+ case 'T':
+ if (p[0] == 'T' && p[1] == 'F') {
+ if (version == 1) {
+ parse_rockridge_TF1(file,
+ data, data_length);
+ iso9660->seenRockridge = 1;
+ }
+ break;
+ }
+ /* FALLTHROUGH */
+ case 'Z':
+ if (p[0] == 'Z' && p[1] == 'F') {
+ if (version == 1)
+ parse_rockridge_ZF1(file,
+ data, data_length);
+ break;
+ }
+ /* FALLTHROUGH */
+ default:
+ /* The FALLTHROUGHs above leave us here for
+ * any unsupported extension. */
+ break;
+ }
+
+
+
+ p += p[2];
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+register_CE(struct archive_read *a, int32_t location,
+ struct file_info *file)
+{
+ struct iso9660 *iso9660;
+ struct read_ce_queue *heap;
+ struct read_ce_req *p;
+ uint64_t offset, parent_offset;
+ int hole, parent;
+
+ iso9660 = (struct iso9660 *)(a->format->data);
+ offset = ((uint64_t)location) * (uint64_t)iso9660->logical_block_size;
+ if (((file->mode & AE_IFMT) == AE_IFREG &&
+ offset >= file->offset) ||
+ offset < iso9660->current_position ||
+ (((uint64_t)file->ce_offset) + file->ce_size)
+ > iso9660->logical_block_size ||
+ offset + file->ce_offset + file->ce_size
+ > iso9660->volume_size) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Invalid parameter in SUSP \"CE\" extension");
+ return (ARCHIVE_FATAL);
+ }
+
+ /* Expand our CE list as necessary. */
+ heap = &(iso9660->read_ce_req);
+ if (heap->cnt >= heap->allocated) {
+ int new_size;
+
+ if (heap->allocated < 16)
+ new_size = 16;
+ else
+ new_size = heap->allocated * 2;
+ /* Overflow might keep us from growing the list. */
+ if (new_size <= heap->allocated) {
+ archive_set_error(&a->archive, ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
+ p = malloc(new_size * sizeof(p[0]));
+ if (p == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
+ if (heap->reqs != NULL) {
+ memcpy(p, heap->reqs, heap->cnt * sizeof(*p));
+ free(heap->reqs);
+ }
+ heap->reqs = p;
+ heap->allocated = new_size;
+ }
+
+ /*
+ * Start with hole at end, walk it up tree to find insertion point.
+ */
+ hole = heap->cnt++;
+ while (hole > 0) {
+ parent = (hole - 1)/2;
+ parent_offset = heap->reqs[parent].offset;
+ if (offset >= parent_offset) {
+ heap->reqs[hole].offset = offset;
+ heap->reqs[hole].file = file;
+ return (ARCHIVE_OK);
+ }
+ /* Move parent into hole <==> move hole up tree. */
+ heap->reqs[hole] = heap->reqs[parent];
+ hole = parent;
+ }
+ heap->reqs[0].offset = offset;
+ heap->reqs[0].file = file;
+ return (ARCHIVE_OK);
+}
+
+static void
+next_CE(struct read_ce_queue *heap)
+{
+ uint64_t a_offset, b_offset, c_offset;
+ int a, b, c;
+ struct read_ce_req tmp;
+
+ if (heap->cnt < 1)
+ return;
+
+ /*
+ * Move the last item in the heap to the root of the tree
+ */
+ heap->reqs[0] = heap->reqs[--(heap->cnt)];
+
+ /*
+ * Rebalance the heap.
+ */
+ a = 0; /* Starting element and its offset */
+ a_offset = heap->reqs[a].offset;
+ for (;;) {
+ b = a + a + 1; /* First child */
+ if (b >= heap->cnt)
+ return;
+ b_offset = heap->reqs[b].offset;
+ c = b + 1; /* Use second child if it is smaller. */
+ if (c < heap->cnt) {
+ c_offset = heap->reqs[c].offset;
+ if (c_offset < b_offset) {
+ b = c;
+ b_offset = c_offset;
+ }
+ }
+ if (a_offset <= b_offset)
+ return;
+ tmp = heap->reqs[a];
+ heap->reqs[a] = heap->reqs[b];
+ heap->reqs[b] = tmp;
+ a = b;
+ }
+}
+
+
+static int
+read_CE(struct archive_read *a, struct iso9660 *iso9660)
+{
+ struct read_ce_queue *heap;
+ const unsigned char *b, *p, *end;
+ struct file_info *file;
+ size_t step;
+ int r;
+
+ /* Read data which RRIP "CE" extension points. */
+ heap = &(iso9660->read_ce_req);
+ step = iso9660->logical_block_size;
+ while (heap->cnt &&
+ heap->reqs[0].offset == iso9660->current_position) {
+ b = __archive_read_ahead(a, step, NULL);
+ if (b == NULL) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Failed to read full block when scanning "
+ "ISO9660 directory list");
+ return (ARCHIVE_FATAL);
+ }
+ do {
+ file = heap->reqs[0].file;
+ if (file->ce_offset + file->ce_size > step) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Malformed CE information");
+ return (ARCHIVE_FATAL);
+ }
+ p = b + file->ce_offset;
+ end = p + file->ce_size;
+ next_CE(heap);
+ r = parse_rockridge(a, file, p, end);
+ if (r != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ } while (heap->cnt &&
+ heap->reqs[0].offset == iso9660->current_position);
+ /* NOTE: Do not move this consume's code to fron of
+ * do-while loop. Registration of nested CE extension
+ * might cause error because of current position. */
+ __archive_read_consume(a, step);
+ iso9660->current_position += step;
+ }
+ return (ARCHIVE_OK);
+}
+
+static void
+parse_rockridge_NM1(struct file_info *file,
+ const unsigned char *data, int data_length)
+{
+ if (!file->name_continues)
+ archive_string_empty(&file->name);
+ file->name_continues = 0;
+ if (data_length < 1)
+ return;
+ /*
+ * NM version 1 extension comprises:
+ * 1 byte flag, value is one of:
+ * = 0: remainder is name
+ * = 1: remainder is name, next NM entry continues name
+ * = 2: "."
+ * = 4: ".."
+ * = 32: Implementation specific
+ * All other values are reserved.
+ */
+ switch(data[0]) {
+ case 0:
+ if (data_length < 2)
+ return;
+ archive_strncat(&file->name,
+ (const char *)data + 1, data_length - 1);
+ break;
+ case 1:
+ if (data_length < 2)
+ return;
+ archive_strncat(&file->name,
+ (const char *)data + 1, data_length - 1);
+ file->name_continues = 1;
+ break;
+ case 2:
+ archive_strcat(&file->name, ".");
+ break;
+ case 4:
+ archive_strcat(&file->name, "..");
+ break;
+ default:
+ return;
+ }
+
+}
+
+static void
+parse_rockridge_TF1(struct file_info *file, const unsigned char *data,
+ int data_length)
+{
+ char flag;
+ /*
+ * TF extension comprises:
+ * one byte flag
+ * create time (optional)
+ * modify time (optional)
+ * access time (optional)
+ * attribute time (optional)
+ * Time format and presence of fields
+ * is controlled by flag bits.
+ */
+ if (data_length < 1)
+ return;
+ flag = data[0];
+ ++data;
+ --data_length;
+ if (flag & 0x80) {
+ /* Use 17-byte time format. */
+ if ((flag & 1) && data_length >= 17) {
+ /* Create time. */
+ file->birthtime_is_set = 1;
+ file->birthtime = isodate17(data);
+ data += 17;
+ data_length -= 17;
+ }
+ if ((flag & 2) && data_length >= 17) {
+ /* Modify time. */
+ file->mtime = isodate17(data);
+ data += 17;
+ data_length -= 17;
+ }
+ if ((flag & 4) && data_length >= 17) {
+ /* Access time. */
+ file->atime = isodate17(data);
+ data += 17;
+ data_length -= 17;
+ }
+ if ((flag & 8) && data_length >= 17) {
+ /* Attribute change time. */
+ file->ctime = isodate17(data);
+ }
+ } else {
+ /* Use 7-byte time format. */
+ if ((flag & 1) && data_length >= 7) {
+ /* Create time. */
+ file->birthtime_is_set = 1;
+ file->birthtime = isodate7(data);
+ data += 7;
+ data_length -= 7;
+ }
+ if ((flag & 2) && data_length >= 7) {
+ /* Modify time. */
+ file->mtime = isodate7(data);
+ data += 7;
+ data_length -= 7;
+ }
+ if ((flag & 4) && data_length >= 7) {
+ /* Access time. */
+ file->atime = isodate7(data);
+ data += 7;
+ data_length -= 7;
+ }
+ if ((flag & 8) && data_length >= 7) {
+ /* Attribute change time. */
+ file->ctime = isodate7(data);
+ }
+ }
+}
+
+static void
+parse_rockridge_SL1(struct file_info *file, const unsigned char *data,
+ int data_length)
+{
+ const char *separator = "";
+
+ if (!file->symlink_continues || file->symlink.length < 1)
+ archive_string_empty(&file->symlink);
+ else if (!file->symlink_continues &&
+ file->symlink.s[file->symlink.length - 1] != '/')
+ separator = "/";
+ file->symlink_continues = 0;
+
+ /*
+ * Defined flag values:
+ * 0: This is the last SL record for this symbolic link
+ * 1: this symbolic link field continues in next SL entry
+ * All other values are reserved.
+ */
+ if (data_length < 1)
+ return;
+ switch(*data) {
+ case 0:
+ break;
+ case 1:
+ file->symlink_continues = 1;
+ break;
+ default:
+ return;
+ }
+ ++data; /* Skip flag byte. */
+ --data_length;
+
+ /*
+ * SL extension body stores "components".
+ * Basically, this is a complicated way of storing
+ * a POSIX path. It also interferes with using
+ * symlinks for storing non-path data. <sigh>
+ *
+ * Each component is 2 bytes (flag and length)
+ * possibly followed by name data.
+ */
+ while (data_length >= 2) {
+ unsigned char flag = *data++;
+ unsigned char nlen = *data++;
+ data_length -= 2;
+
+ archive_strcat(&file->symlink, separator);
+ separator = "/";
+
+ switch(flag) {
+ case 0: /* Usual case, this is text. */
+ if (data_length < nlen)
+ return;
+ archive_strncat(&file->symlink,
+ (const char *)data, nlen);
+ break;
+ case 0x01: /* Text continues in next component. */
+ if (data_length < nlen)
+ return;
+ archive_strncat(&file->symlink,
+ (const char *)data, nlen);
+ separator = "";
+ break;
+ case 0x02: /* Current dir. */
+ archive_strcat(&file->symlink, ".");
+ break;
+ case 0x04: /* Parent dir. */
+ archive_strcat(&file->symlink, "..");
+ break;
+ case 0x08: /* Root of filesystem. */
+ archive_strcat(&file->symlink, "/");
+ separator = "";
+ break;
+ case 0x10: /* Undefined (historically "volume root" */
+ archive_string_empty(&file->symlink);
+ archive_strcat(&file->symlink, "ROOT");
+ break;
+ case 0x20: /* Undefined (historically "hostname") */
+ archive_strcat(&file->symlink, "hostname");
+ break;
+ default:
+ /* TODO: issue a warning ? */
+ return;
+ }
+ data += nlen;
+ data_length -= nlen;
+ }
+}
+
+static void
+parse_rockridge_ZF1(struct file_info *file, const unsigned char *data,
+ int data_length)
+{
+
+ if (data[0] == 0x70 && data[1] == 0x7a && data_length == 12) {
+ /* paged zlib */
+ file->pz = 1;
+ file->pz_log2_bs = data[3];
+ file->pz_uncompressed_size = archive_le32dec(&data[4]);
+ }
+}
+
+static void
+register_file(struct iso9660 *iso9660, struct file_info *file)
+{
+
+ file->use_next = iso9660->use_files;
+ iso9660->use_files = file;
+}
+
+static void
+release_files(struct iso9660 *iso9660)
+{
+ struct content *con, *connext;
+ struct file_info *file;
+
+ file = iso9660->use_files;
+ while (file != NULL) {
+ struct file_info *next = file->use_next;
+
+ archive_string_free(&file->name);
+ archive_string_free(&file->symlink);
+ free(file->utf16be_name);
+ con = file->contents.first;
+ while (con != NULL) {
+ connext = con->next;
+ free(con);
+ con = connext;
+ }
+ free(file);
+ file = next;
+ }
+}
+
+static int
+next_entry_seek(struct archive_read *a, struct iso9660 *iso9660,
+ struct file_info **pfile)
+{
+ struct file_info *file;
+ int r;
+
+ r = next_cache_entry(a, iso9660, pfile);
+ if (r != ARCHIVE_OK)
+ return (r);
+ file = *pfile;
+
+ /* Don't waste time seeking for zero-length bodies. */
+ if (file->size == 0)
+ file->offset = iso9660->current_position;
+
+ /* flush any remaining bytes from the last round to ensure
+ * we're positioned */
+ if (iso9660->entry_bytes_unconsumed) {
+ __archive_read_consume(a, iso9660->entry_bytes_unconsumed);
+ iso9660->entry_bytes_unconsumed = 0;
+ }
+
+ /* Seek forward to the start of the entry. */
+ if (iso9660->current_position < file->offset) {
+ int64_t step;
+
+ step = file->offset - iso9660->current_position;
+ step = __archive_read_consume(a, step);
+ if (step < 0)
+ return ((int)step);
+ iso9660->current_position = file->offset;
+ }
+
+ /* We found body of file; handle it now. */
+ return (ARCHIVE_OK);
+}
+
+static int
+next_cache_entry(struct archive_read *a, struct iso9660 *iso9660,
+ struct file_info **pfile)
+{
+ struct file_info *file;
+ struct {
+ struct file_info *first;
+ struct file_info **last;
+ } empty_files;
+ int64_t number;
+ int count;
+
+ file = cache_get_entry(iso9660);
+ if (file != NULL) {
+ *pfile = file;
+ return (ARCHIVE_OK);
+ }
+
+ for (;;) {
+ struct file_info *re, *d;
+
+ *pfile = file = next_entry(iso9660);
+ if (file == NULL) {
+ /*
+ * If directory entries all which are descendant of
+ * rr_moved are stil remaning, expose their.
+ */
+ if (iso9660->re_files.first != NULL &&
+ iso9660->rr_moved != NULL &&
+ iso9660->rr_moved->rr_moved_has_re_only)
+ /* Expose "rr_moved" entry. */
+ cache_add_entry(iso9660, iso9660->rr_moved);
+ while ((re = re_get_entry(iso9660)) != NULL) {
+ /* Expose its descendant dirs. */
+ while ((d = rede_get_entry(re)) != NULL)
+ cache_add_entry(iso9660, d);
+ }
+ if (iso9660->cache_files.first != NULL)
+ return (next_cache_entry(a, iso9660, pfile));
+ return (ARCHIVE_EOF);
+ }
+
+ if (file->cl_offset) {
+ struct file_info *first_re = NULL;
+ int nexted_re = 0;
+
+ /*
+ * Find "RE" dir for the current file, which
+ * has "CL" flag.
+ */
+ while ((re = re_get_entry(iso9660))
+ != first_re) {
+ if (first_re == NULL)
+ first_re = re;
+ if (re->offset == file->cl_offset) {
+ re->parent->subdirs--;
+ re->parent = file->parent;
+ re->re = 0;
+ if (re->parent->re_descendant) {
+ nexted_re = 1;
+ re->re_descendant = 1;
+ if (rede_add_entry(re) < 0)
+ goto fatal_rr;
+ /* Move a list of descendants
+ * to a new ancestor. */
+ while ((d = rede_get_entry(
+ re)) != NULL)
+ if (rede_add_entry(d)
+ < 0)
+ goto fatal_rr;
+ break;
+ }
+ /* Replace the current file
+ * with "RE" dir */
+ *pfile = file = re;
+ /* Expose its descendant */
+ while ((d = rede_get_entry(
+ file)) != NULL)
+ cache_add_entry(
+ iso9660, d);
+ break;
+ } else
+ re_add_entry(iso9660, re);
+ }
+ if (nexted_re) {
+ /*
+ * Do not expose this at this time
+ * because we have not gotten its full-path
+ * name yet.
+ */
+ continue;
+ }
+ } else if ((file->mode & AE_IFMT) == AE_IFDIR) {
+ int r;
+
+ /* Read file entries in this dir. */
+ r = read_children(a, file);
+ if (r != ARCHIVE_OK)
+ return (r);
+
+ /*
+ * Handle a special dir of Rockridge extensions,
+ * "rr_moved".
+ */
+ if (file->rr_moved) {
+ /*
+ * If this has only the subdirectories which
+ * have "RE" flags, do not expose at this time.
+ */
+ if (file->rr_moved_has_re_only)
+ continue;
+ /* Otherwise expose "rr_moved" entry. */
+ } else if (file->re) {
+ /*
+ * Do not expose this at this time
+ * because we have not gotten its full-path
+ * name yet.
+ */
+ re_add_entry(iso9660, file);
+ continue;
+ } else if (file->re_descendant) {
+ /*
+ * If the top level "RE" entry of this entry
+ * is not exposed, we, accordingly, should not
+ * expose this entry at this time because
+ * we cannot make its proper full-path name.
+ */
+ if (rede_add_entry(file) == 0)
+ continue;
+ /* Otherwise we can expose this entry because
+ * it seems its top level "RE" has already been
+ * exposed. */
+ }
+ }
+ break;
+ }
+
+ if ((file->mode & AE_IFMT) != AE_IFREG || file->number == -1)
+ return (ARCHIVE_OK);
+
+ count = 0;
+ number = file->number;
+ iso9660->cache_files.first = NULL;
+ iso9660->cache_files.last = &(iso9660->cache_files.first);
+ empty_files.first = NULL;
+ empty_files.last = &empty_files.first;
+ /* Collect files which has the same file serial number.
+ * Peek pending_files so that file which number is different
+ * is not put bak. */
+ while (iso9660->pending_files.used > 0 &&
+ (iso9660->pending_files.files[0]->number == -1 ||
+ iso9660->pending_files.files[0]->number == number)) {
+ if (file->number == -1) {
+ /* This file has the same offset
+ * but it's wrong offset which empty files
+ * and symlink files have.
+ * NOTE: This wrong offse was recorded by
+ * old mkisofs utility. If ISO images is
+ * created by latest mkisofs, this does not
+ * happen.
+ */
+ file->next = NULL;
+ *empty_files.last = file;
+ empty_files.last = &(file->next);
+ } else {
+ count++;
+ cache_add_entry(iso9660, file);
+ }
+ file = next_entry(iso9660);
+ }
+
+ if (count == 0) {
+ *pfile = file;
+ return ((file == NULL)?ARCHIVE_EOF:ARCHIVE_OK);
+ }
+ if (file->number == -1) {
+ file->next = NULL;
+ *empty_files.last = file;
+ empty_files.last = &(file->next);
+ } else {
+ count++;
+ cache_add_entry(iso9660, file);
+ }
+
+ if (count > 1) {
+ /* The count is the same as number of hardlink,
+ * so much so that each nlinks of files in cache_file
+ * is overwritten by value of the count.
+ */
+ for (file = iso9660->cache_files.first;
+ file != NULL; file = file->next)
+ file->nlinks = count;
+ }
+ /* If there are empty files, that files are added
+ * to the tail of the cache_files. */
+ if (empty_files.first != NULL) {
+ *iso9660->cache_files.last = empty_files.first;
+ iso9660->cache_files.last = empty_files.last;
+ }
+ *pfile = cache_get_entry(iso9660);
+ return ((*pfile == NULL)?ARCHIVE_EOF:ARCHIVE_OK);
+
+fatal_rr:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Failed to connect 'CL' pointer to 'RE' rr_moved pointer of"
+ "Rockridge extensions");
+ return (ARCHIVE_FATAL);
+}
+
+static inline void
+re_add_entry(struct iso9660 *iso9660, struct file_info *file)
+{
+ file->re_next = NULL;
+ *iso9660->re_files.last = file;
+ iso9660->re_files.last = &(file->re_next);
+}
+
+static inline struct file_info *
+re_get_entry(struct iso9660 *iso9660)
+{
+ struct file_info *file;
+
+ if ((file = iso9660->re_files.first) != NULL) {
+ iso9660->re_files.first = file->re_next;
+ if (iso9660->re_files.first == NULL)
+ iso9660->re_files.last =
+ &(iso9660->re_files.first);
+ }
+ return (file);
+}
+
+static inline int
+rede_add_entry(struct file_info *file)
+{
+ struct file_info *re;
+
+ /*
+ * Find "RE" entry.
+ */
+ re = file->parent;
+ while (re != NULL && !re->re)
+ re = re->parent;
+ if (re == NULL)
+ return (-1);
+
+ file->re_next = NULL;
+ *re->rede_files.last = file;
+ re->rede_files.last = &(file->re_next);
+ return (0);
+}
+
+static inline struct file_info *
+rede_get_entry(struct file_info *re)
+{
+ struct file_info *file;
+
+ if ((file = re->rede_files.first) != NULL) {
+ re->rede_files.first = file->re_next;
+ if (re->rede_files.first == NULL)
+ re->rede_files.last =
+ &(re->rede_files.first);
+ }
+ return (file);
+}
+
+static inline void
+cache_add_entry(struct iso9660 *iso9660, struct file_info *file)
+{
+ file->next = NULL;
+ *iso9660->cache_files.last = file;
+ iso9660->cache_files.last = &(file->next);
+}
+
+static inline struct file_info *
+cache_get_entry(struct iso9660 *iso9660)
+{
+ struct file_info *file;
+
+ if ((file = iso9660->cache_files.first) != NULL) {
+ iso9660->cache_files.first = file->next;
+ if (iso9660->cache_files.first == NULL)
+ iso9660->cache_files.last =
+ &(iso9660->cache_files.first);
+ }
+ return (file);
+}
+
+static int
+heap_add_entry(struct archive_read *a, struct heap_queue *heap,
+ struct file_info *file, uint64_t key)
+{
+ uint64_t file_key, parent_key;
+ int hole, parent;
+
+ /* Expand our pending files list as necessary. */
+ if (heap->used >= heap->allocated) {
+ struct file_info **new_pending_files;
+ int new_size = heap->allocated * 2;
+
+ if (heap->allocated < 1024)
+ new_size = 1024;
+ /* Overflow might keep us from growing the list. */
+ if (new_size <= heap->allocated) {
+ archive_set_error(&a->archive,
+ ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
+ new_pending_files = (struct file_info **)
+ malloc(new_size * sizeof(new_pending_files[0]));
+ if (new_pending_files == NULL) {
+ archive_set_error(&a->archive,
+ ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
+ memcpy(new_pending_files, heap->files,
+ heap->allocated * sizeof(new_pending_files[0]));
+ if (heap->files != NULL)
+ free(heap->files);
+ heap->files = new_pending_files;
+ heap->allocated = new_size;
+ }
+
+ file_key = file->key = key;
+
+ /*
+ * Start with hole at end, walk it up tree to find insertion point.
+ */
+ hole = heap->used++;
+ while (hole > 0) {
+ parent = (hole - 1)/2;
+ parent_key = heap->files[parent]->key;
+ if (file_key >= parent_key) {
+ heap->files[hole] = file;
+ return (ARCHIVE_OK);
+ }
+ /* Move parent into hole <==> move hole up tree. */
+ heap->files[hole] = heap->files[parent];
+ hole = parent;
+ }
+ heap->files[0] = file;
+
+ return (ARCHIVE_OK);
+}
+
+static struct file_info *
+heap_get_entry(struct heap_queue *heap)
+{
+ uint64_t a_key, b_key, c_key;
+ int a, b, c;
+ struct file_info *r, *tmp;
+
+ if (heap->used < 1)
+ return (NULL);
+
+ /*
+ * The first file in the list is the earliest; we'll return this.
+ */
+ r = heap->files[0];
+
+ /*
+ * Move the last item in the heap to the root of the tree
+ */
+ heap->files[0] = heap->files[--(heap->used)];
+
+ /*
+ * Rebalance the heap.
+ */
+ a = 0; /* Starting element and its heap key */
+ a_key = heap->files[a]->key;
+ for (;;) {
+ b = a + a + 1; /* First child */
+ if (b >= heap->used)
+ return (r);
+ b_key = heap->files[b]->key;
+ c = b + 1; /* Use second child if it is smaller. */
+ if (c < heap->used) {
+ c_key = heap->files[c]->key;
+ if (c_key < b_key) {
+ b = c;
+ b_key = c_key;
+ }
+ }
+ if (a_key <= b_key)
+ return (r);
+ tmp = heap->files[a];
+ heap->files[a] = heap->files[b];
+ heap->files[b] = tmp;
+ a = b;
+ }
+}
+
+static unsigned int
+toi(const void *p, int n)
+{
+ const unsigned char *v = (const unsigned char *)p;
+ if (n > 1)
+ return v[0] + 256 * toi(v + 1, n - 1);
+ if (n == 1)
+ return v[0];
+ return (0);
+}
+
+static time_t
+isodate7(const unsigned char *v)
+{
+ struct tm tm;
+ int offset;
+ memset(&tm, 0, sizeof(tm));
+ tm.tm_year = v[0];
+ tm.tm_mon = v[1] - 1;
+ tm.tm_mday = v[2];
+ tm.tm_hour = v[3];
+ tm.tm_min = v[4];
+ tm.tm_sec = v[5];
+ /* v[6] is the signed timezone offset, in 1/4-hour increments. */
+ offset = ((const signed char *)v)[6];
+ if (offset > -48 && offset < 52) {
+ tm.tm_hour -= offset / 4;
+ tm.tm_min -= (offset % 4) * 15;
+ }
+ return (time_from_tm(&tm));
+}
+
+static time_t
+isodate17(const unsigned char *v)
+{
+ struct tm tm;
+ int offset;
+ memset(&tm, 0, sizeof(tm));
+ tm.tm_year = (v[0] - '0') * 1000 + (v[1] - '0') * 100
+ + (v[2] - '0') * 10 + (v[3] - '0')
+ - 1900;
+ tm.tm_mon = (v[4] - '0') * 10 + (v[5] - '0');
+ tm.tm_mday = (v[6] - '0') * 10 + (v[7] - '0');
+ tm.tm_hour = (v[8] - '0') * 10 + (v[9] - '0');
+ tm.tm_min = (v[10] - '0') * 10 + (v[11] - '0');
+ tm.tm_sec = (v[12] - '0') * 10 + (v[13] - '0');
+ /* v[16] is the signed timezone offset, in 1/4-hour increments. */
+ offset = ((const signed char *)v)[16];
+ if (offset > -48 && offset < 52) {
+ tm.tm_hour -= offset / 4;
+ tm.tm_min -= (offset % 4) * 15;
+ }
+ return (time_from_tm(&tm));
+}
+
+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. */
+ 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
+}
+
+static const char *
+build_pathname(struct archive_string *as, struct file_info *file)
+{
+ if (file->parent != NULL && archive_strlen(&file->parent->name) > 0) {
+ build_pathname(as, file->parent);
+ archive_strcat(as, "/");
+ }
+ if (archive_strlen(&file->name) == 0)
+ archive_strcat(as, ".");
+ else
+ archive_string_concat(as, &file->name);
+ return (as->s);
+}
+
+static int
+build_pathname_utf16be(unsigned char *p, size_t max, size_t *len,
+ struct file_info *file)
+{
+ if (file->parent != NULL && file->parent->utf16be_bytes > 0) {
+ if (build_pathname_utf16be(p, max, len, file->parent) != 0)
+ return (-1);
+ p[*len] = 0;
+ p[*len + 1] = '/';
+ *len += 2;
+ }
+ if (file->utf16be_bytes == 0) {
+ if (*len + 2 > max)
+ return (-1);/* Path is too long! */
+ p[*len] = 0;
+ p[*len + 1] = '.';
+ *len += 2;
+ } else {
+ if (*len + file->utf16be_bytes > max)
+ return (-1);/* Path is too long! */
+ memcpy(p + *len, file->utf16be_name, file->utf16be_bytes);
+ *len += file->utf16be_bytes;
+ }
+ return (0);
+}
+
+#if DEBUG
+static void
+dump_isodirrec(FILE *out, const unsigned char *isodirrec)
+{
+ fprintf(out, " l %d,",
+ toi(isodirrec + DR_length_offset, DR_length_size));
+ fprintf(out, " a %d,",
+ toi(isodirrec + DR_ext_attr_length_offset, DR_ext_attr_length_size));
+ fprintf(out, " ext 0x%x,",
+ toi(isodirrec + DR_extent_offset, DR_extent_size));
+ fprintf(out, " s %d,",
+ toi(isodirrec + DR_size_offset, DR_extent_size));
+ fprintf(out, " f 0x%x,",
+ toi(isodirrec + DR_flags_offset, DR_flags_size));
+ fprintf(out, " u %d,",
+ toi(isodirrec + DR_file_unit_size_offset, DR_file_unit_size_size));
+ fprintf(out, " ilv %d,",
+ toi(isodirrec + DR_interleave_offset, DR_interleave_size));
+ fprintf(out, " seq %d,",
+ toi(isodirrec + DR_volume_sequence_number_offset, DR_volume_sequence_number_size));
+ fprintf(out, " nl %d:",
+ toi(isodirrec + DR_name_len_offset, DR_name_len_size));
+ fprintf(out, " `%.*s'",
+ toi(isodirrec + DR_name_len_offset, DR_name_len_size), isodirrec + DR_name_offset);
+}
+#endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c
new file mode 100644
index 000000000..50256b161
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c
@@ -0,0 +1,2745 @@
+/*-
+ * Copyright (c) 2008-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"
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.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_entry_locale.h"
+#include "archive_private.h"
+#include "archive_read_private.h"
+#include "archive_endian.h"
+
+
+#define MAXMATCH 256 /* Maximum match length. */
+#define MINMATCH 3 /* Minimum match length. */
+/*
+ * Literal table format:
+ * +0 +256 +510
+ * +---------------+-------------------------+
+ * | literal code | match length |
+ * | 0 ... 255 | MINMATCH ... MAXMATCH |
+ * +---------------+-------------------------+
+ * <--- LT_BITLEN_SIZE --->
+ */
+/* Literal table size. */
+#define LT_BITLEN_SIZE (UCHAR_MAX + 1 + MAXMATCH - MINMATCH + 1)
+/* Position table size.
+ * Note: this used for both position table and pre literal table.*/
+#define PT_BITLEN_SIZE (3 + 16)
+
+struct lzh_dec {
+ /* Decoding status. */
+ int state;
+
+ /*
+ * Window to see last 8Ki(lh5),32Ki(lh6),64Ki(lh7) bytes of decoded
+ * data.
+ */
+ int w_size;
+ int w_mask;
+ /* Window buffer, which is a loop buffer. */
+ unsigned char *w_buff;
+ /* The insert position to the window. */
+ int w_pos;
+ /* The position where we can copy decoded code from the window. */
+ int copy_pos;
+ /* 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.
+ */
+ struct lzh_br {
+#define CACHE_TYPE uint64_t
+#define CACHE_BITS (8 * sizeof(CACHE_TYPE))
+ /* Cache buffer. */
+ CACHE_TYPE cache_buffer;
+ /* Indicates how many bits avail in cache_buffer. */
+ int cache_avail;
+ } br;
+
+ /*
+ * Huffman coding.
+ */
+ struct huffman {
+ int len_size;
+ int len_avail;
+ int len_bits;
+ int freq[17];
+ unsigned char *bitlen;
+
+ /*
+ * Use a index table. It's faster than searching a huffman
+ * coding tree, which is a binary tree. But a use of a large
+ * index table causes L1 cache read miss many times.
+ */
+#define HTBL_BITS 10
+ int max_bits;
+ int shift_bits;
+ int tbl_bits;
+ int tree_used;
+ int tree_avail;
+ /* Direct access table. */
+ uint16_t *tbl;
+ /* Binary tree table for extra bits over the direct access. */
+ struct htree_t {
+ uint16_t left;
+ uint16_t right;
+ } *tree;
+ } lt, pt;
+
+ int blocks_avail;
+ int pos_pt_len_size;
+ int pos_pt_len_bits;
+ int literal_pt_len_size;
+ int literal_pt_len_bits;
+ int reading_position;
+ int loop;
+ int error;
+};
+
+struct lzh_stream {
+ const unsigned char *next_in;
+ int64_t avail_in;
+ int64_t total_in;
+ unsigned char *next_out;
+ int64_t avail_out;
+ int64_t total_out;
+ struct lzh_dec *ds;
+};
+
+struct lha {
+ /* entry_bytes_remaining is the number of bytes we expect. */
+ int64_t entry_offset;
+ int64_t entry_bytes_remaining;
+ int64_t entry_unconsumed;
+ uint16_t entry_crc_calculated;
+
+ size_t header_size; /* header size */
+ unsigned char level; /* header level */
+ char method[3]; /* compress type */
+ int64_t compsize; /* compressed data size */
+ int64_t origsize; /* original file size */
+ int setflag;
+#define BIRTHTIME_IS_SET 1
+#define ATIME_IS_SET 2
+#define UNIX_MODE_IS_SET 4
+#define CRC_IS_SET 8
+ time_t birthtime;
+ long birthtime_tv_nsec;
+ time_t mtime;
+ long mtime_tv_nsec;
+ time_t atime;
+ long atime_tv_nsec;
+ mode_t mode;
+ int64_t uid;
+ int64_t gid;
+ struct archive_string uname;
+ struct archive_string gname;
+ uint16_t header_crc;
+ uint16_t crc;
+ struct archive_string_conv *sconv;
+ struct archive_string_conv *opt_sconv;
+
+ struct archive_string dirname;
+ struct archive_string filename;
+ struct archive_wstring ws;
+
+ unsigned char dos_attr;
+
+ /* Flag to mark progress that an archive was read their first header.*/
+ char found_first_header;
+ /* Flag to mark that indicates an empty directory. */
+ char directory;
+
+ /* Flags to mark progress of decompression. */
+ char decompress_init;
+ char end_of_entry;
+ 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;
+};
+
+/*
+ * LHA header common member offset.
+ */
+#define H_METHOD_OFFSET 2 /* Compress type. */
+#define H_ATTR_OFFSET 19 /* DOS attribute. */
+#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 *);
+static int archive_read_format_lha_read_header(struct archive_read *,
+ struct archive_entry *);
+static int archive_read_format_lha_read_data(struct archive_read *,
+ const void **, size_t *, int64_t *);
+static int archive_read_format_lha_read_data_skip(struct archive_read *);
+static int archive_read_format_lha_cleanup(struct archive_read *);
+
+static void lha_replace_path_separator(struct lha *,
+ struct archive_entry *);
+static int lha_read_file_header_0(struct archive_read *, struct lha *);
+static int lha_read_file_header_1(struct archive_read *, struct lha *);
+static int lha_read_file_header_2(struct archive_read *, struct lha *);
+static int lha_read_file_header_3(struct archive_read *, struct lha *);
+static int lha_read_file_extended_header(struct archive_read *,
+ struct lha *, uint16_t *, int, size_t, size_t *);
+static size_t lha_check_header_format(const void *);
+static int lha_skip_sfx(struct archive_read *);
+static time_t lha_dos_time(const unsigned char *);
+static time_t lha_win_time(uint64_t, long *);
+static unsigned char lha_calcsum(unsigned char, const void *,
+ int, int);
+static int lha_parse_linkname(struct archive_string *,
+ struct archive_string *);
+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 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 *);
+static int lzh_decode(struct lzh_stream *, int);
+static int lzh_br_fillup(struct lzh_stream *, struct lzh_br *);
+static int lzh_huffman_init(struct huffman *, size_t, int);
+static void lzh_huffman_free(struct huffman *);
+static int lzh_read_pt_bitlen(struct lzh_stream *, int start, int end);
+static int lzh_make_fake_table(struct huffman *, uint16_t);
+static int lzh_make_huffman_table(struct huffman *);
+static int inline lzh_decode_huffman(struct huffman *, unsigned);
+static int lzh_decode_huffman_tree(struct huffman *, unsigned, int);
+
+
+int
+archive_read_support_format_lha(struct archive *_a)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ struct lha *lha;
+ int r;
+
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_lha");
+
+ lha = (struct lha *)calloc(1, sizeof(*lha));
+ if (lha == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate lha data");
+ return (ARCHIVE_FATAL);
+ }
+ archive_string_init(&lha->ws);
+
+ r = __archive_read_register_format(a,
+ lha,
+ "lha",
+ archive_read_format_lha_bid,
+ archive_read_format_lha_options,
+ archive_read_format_lha_read_header,
+ archive_read_format_lha_read_data,
+ archive_read_format_lha_read_data_skip,
+ archive_read_format_lha_cleanup);
+
+ if (r != ARCHIVE_OK)
+ free(lha);
+ return (ARCHIVE_OK);
+}
+
+static size_t
+lha_check_header_format(const void *h)
+{
+ const unsigned char *p = h;
+ size_t next_skip_bytes;
+
+ switch (p[H_METHOD_OFFSET+3]) {
+ /*
+ * "-lh0-" ... "-lh7-" "-lhd-"
+ * "-lzs-" "-lz5-"
+ */
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ case 'd':
+ case 's':
+ next_skip_bytes = 4;
+
+ /* b0 == 0 means the end of an LHa archive file. */
+ if (p[0] == 0)
+ break;
+ if (p[H_METHOD_OFFSET] != '-' || p[H_METHOD_OFFSET+1] != 'l'
+ || p[H_METHOD_OFFSET+4] != '-')
+ break;
+
+ if (p[H_METHOD_OFFSET+2] == 'h') {
+ /* "-lh?-" */
+ if (p[H_METHOD_OFFSET+3] == 's')
+ break;
+ if (p[H_LEVEL_OFFSET] == 0)
+ return (0);
+ if (p[H_LEVEL_OFFSET] <= 3 && p[H_ATTR_OFFSET] == 0x20)
+ return (0);
+ }
+ if (p[H_METHOD_OFFSET+2] == 'z') {
+ /* LArc extensions: -lzs-,-lz4- and -lz5- */
+ if (p[H_LEVEL_OFFSET] != 0)
+ break;
+ if (p[H_METHOD_OFFSET+3] == 's'
+ || p[H_METHOD_OFFSET+3] == '4'
+ || p[H_METHOD_OFFSET+3] == '5')
+ return (0);
+ }
+ break;
+ case 'h': next_skip_bytes = 1; break;
+ case 'z': next_skip_bytes = 1; break;
+ case 'l': next_skip_bytes = 2; break;
+ case '-': next_skip_bytes = 3; break;
+ default : next_skip_bytes = 4; break;
+ }
+
+ return (next_skip_bytes);
+}
+
+static int
+archive_read_format_lha_bid(struct archive_read *a, int best_bid)
+{
+ const char *p;
+ const void *buff;
+ ssize_t bytes_avail, offset, window;
+ size_t next;
+
+ /* If there's already a better bid than we can ever
+ make, don't bother testing. */
+ if (best_bid > 30)
+ return (-1);
+
+ if ((p = __archive_read_ahead(a, H_SIZE, NULL)) == NULL)
+ return (-1);
+
+ if (lha_check_header_format(p) == 0)
+ return (30);
+
+ if (p[0] == 'M' && p[1] == 'Z') {
+ /* PE file */
+ offset = 0;
+ window = 4096;
+ while (offset < (1024 * 20)) {
+ buff = __archive_read_ahead(a, offset + window,
+ &bytes_avail);
+ if (buff == NULL) {
+ /* Remaining bytes are less than window. */
+ window >>= 1;
+ if (window < (H_SIZE + 3))
+ return (0);
+ continue;
+ }
+ p = (const char *)buff + offset;
+ while (p + H_SIZE < (const char *)buff + bytes_avail) {
+ if ((next = lha_check_header_format(p)) == 0)
+ return (30);
+ p += next;
+ }
+ offset = p - (const char *)buff;
+ }
+ }
+ return (0);
+}
+
+static int
+archive_read_format_lha_options(struct archive_read *a,
+ const char *key, const char *val)
+{
+ struct lha *lha;
+ int ret = ARCHIVE_FAILED;
+
+ lha = (struct lha *)(a->format->data);
+ if (strcmp(key, "hdrcharset") == 0) {
+ if (val == NULL || val[0] == 0)
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "lha: hdrcharset option needs a character-set name");
+ else {
+ lha->opt_sconv =
+ archive_string_conversion_from_charset(
+ &a->archive, val, 0);
+ if (lha->opt_sconv != NULL)
+ ret = ARCHIVE_OK;
+ else
+ ret = ARCHIVE_FATAL;
+ }
+ } else
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "lha: unknown keyword ``%s''", key);
+
+ return (ret);
+}
+
+static int
+lha_skip_sfx(struct archive_read *a)
+{
+ const void *h;
+ const char *p, *q;
+ size_t next, skip;
+ ssize_t bytes, window;
+
+ window = 4096;
+ for (;;) {
+ h = __archive_read_ahead(a, window, &bytes);
+ if (h == NULL) {
+ /* Remaining bytes are less than window. */
+ window >>= 1;
+ if (window < (H_SIZE + 3))
+ goto fatal;
+ continue;
+ }
+ if (bytes < H_SIZE)
+ goto fatal;
+ p = h;
+ q = p + bytes;
+
+ /*
+ * Scan ahead until we find something that looks
+ * like the lha header.
+ */
+ while (p + H_SIZE < q) {
+ if ((next = lha_check_header_format(p)) == 0) {
+ skip = p - (const char *)h;
+ __archive_read_consume(a, skip);
+ return (ARCHIVE_OK);
+ }
+ p += next;
+ }
+ skip = p - (const char *)h;
+ __archive_read_consume(a, skip);
+ }
+fatal:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Couldn't find out LHa header");
+ return (ARCHIVE_FATAL);
+}
+
+static int
+truncated_error(struct archive_read *a)
+{
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated LHa header");
+ return (ARCHIVE_FATAL);
+}
+
+static int
+archive_read_format_lha_read_header(struct archive_read *a,
+ struct archive_entry *entry)
+{
+ struct archive_string linkname;
+ struct archive_string pathname;
+ struct lha *lha;
+ const unsigned char *p;
+ const char *signature;
+ int err;
+
+ a->archive.archive_format = ARCHIVE_FORMAT_LHA;
+ if (a->archive.archive_format_name == NULL)
+ a->archive.archive_format_name = "lha";
+
+ lha = (struct lha *)(a->format->data);
+ lha->decompress_init = 0;
+ lha->end_of_entry = 0;
+ lha->end_of_entry_cleanup = 0;
+ lha->entry_unconsumed = 0;
+
+ if ((p = __archive_read_ahead(a, H_SIZE, NULL)) == NULL) {
+ /*
+ * LHa archiver added 0 to the tail of its archive file as
+ * the mark of the end of the archive.
+ */
+ signature = __archive_read_ahead(a, sizeof(signature[0]), NULL);
+ if (signature == NULL || signature[0] == 0)
+ return (ARCHIVE_EOF);
+ return (truncated_error(a));
+ }
+
+ signature = (const char *)p;
+ if (lha->found_first_header == 0 &&
+ signature[0] == 'M' && signature[1] == 'Z') {
+ /* This is an executable? Must be self-extracting... */
+ err = lha_skip_sfx(a);
+ if (err < ARCHIVE_WARN)
+ return (err);
+
+ if ((p = __archive_read_ahead(a, sizeof(*p), NULL)) == NULL)
+ return (truncated_error(a));
+ signature = (const char *)p;
+ }
+ /* signature[0] == 0 means the end of an LHa archive file. */
+ if (signature[0] == 0)
+ return (ARCHIVE_EOF);
+
+ /*
+ * Check the header format and method type.
+ */
+ if (lha_check_header_format(p) != 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Bad LHa file");
+ return (ARCHIVE_FATAL);
+ }
+
+ /* We've found the first header. */
+ lha->found_first_header = 1;
+ /* Set a default value and common data */
+ lha->header_size = 0;
+ lha->level = p[H_LEVEL_OFFSET];
+ lha->method[0] = p[H_METHOD_OFFSET+1];
+ lha->method[1] = p[H_METHOD_OFFSET+2];
+ lha->method[2] = p[H_METHOD_OFFSET+3];
+ if (memcmp(lha->method, "lhd", 3) == 0)
+ lha->directory = 1;
+ else
+ lha->directory = 0;
+ if (memcmp(lha->method, "lh0", 3) == 0 ||
+ memcmp(lha->method, "lz4", 3) == 0)
+ lha->entry_is_compressed = 0;
+ else
+ lha->entry_is_compressed = 1;
+
+ lha->compsize = 0;
+ lha->origsize = 0;
+ lha->setflag = 0;
+ lha->birthtime = 0;
+ lha->birthtime_tv_nsec = 0;
+ lha->mtime = 0;
+ lha->mtime_tv_nsec = 0;
+ lha->atime = 0;
+ lha->atime_tv_nsec = 0;
+ lha->mode = (lha->directory)? 0777 : 0666;
+ lha->uid = 0;
+ lha->gid = 0;
+ archive_string_empty(&lha->dirname);
+ archive_string_empty(&lha->filename);
+ lha->dos_attr = 0;
+ if (lha->opt_sconv != NULL)
+ lha->sconv = lha->opt_sconv;
+ else
+ lha->sconv = NULL;
+
+ switch (p[H_LEVEL_OFFSET]) {
+ case 0:
+ err = lha_read_file_header_0(a, lha);
+ break;
+ case 1:
+ err = lha_read_file_header_1(a, lha);
+ break;
+ case 2:
+ err = lha_read_file_header_2(a, lha);
+ break;
+ case 3:
+ err = lha_read_file_header_3(a, lha);
+ break;
+ default:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Unsupported LHa header level %d", p[H_LEVEL_OFFSET]);
+ err = ARCHIVE_FATAL;
+ break;
+ }
+ if (err < ARCHIVE_WARN)
+ return (err);
+
+
+ if (!lha->directory && archive_strlen(&lha->filename) == 0)
+ /* The filename has not been set */
+ return (truncated_error(a));
+
+ /*
+ * Make a pathname from a dirname and a filename.
+ */
+ archive_string_concat(&lha->dirname, &lha->filename);
+ archive_string_init(&pathname);
+ archive_string_init(&linkname);
+ archive_string_copy(&pathname, &lha->dirname);
+
+ if ((lha->mode & AE_IFMT) == AE_IFLNK) {
+ /*
+ * Extract the symlink-name if it's included in the pathname.
+ */
+ if (!lha_parse_linkname(&linkname, &pathname)) {
+ /* We couldn't get the symlink-name. */
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Unknown symlink-name");
+ archive_string_free(&pathname);
+ archive_string_free(&linkname);
+ return (ARCHIVE_FAILED);
+ }
+ } else {
+ /*
+ * Make sure a file-type is set.
+ * The mode has been overridden if it is in the extended data.
+ */
+ lha->mode = (lha->mode & ~AE_IFMT) |
+ ((lha->directory)? AE_IFDIR: AE_IFREG);
+ }
+ if ((lha->setflag & UNIX_MODE_IS_SET) == 0 &&
+ (lha->dos_attr & 1) != 0)
+ lha->mode &= ~(0222);/* read only. */
+
+ /*
+ * Set basic file parameters.
+ */
+ if (archive_entry_copy_pathname_l(entry, pathname.s,
+ pathname.length, lha->sconv) != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Pathname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Pathname cannot be converted "
+ "from %s to current locale.",
+ archive_string_conversion_charset_name(lha->sconv));
+ err = ARCHIVE_WARN;
+ }
+ archive_string_free(&pathname);
+ if (archive_strlen(&linkname) > 0) {
+ if (archive_entry_copy_symlink_l(entry, linkname.s,
+ linkname.length, lha->sconv) != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Linkname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Linkname cannot be converted "
+ "from %s to current locale.",
+ archive_string_conversion_charset_name(lha->sconv));
+ err = ARCHIVE_WARN;
+ }
+ } else
+ archive_entry_set_symlink(entry, NULL);
+ archive_string_free(&linkname);
+ /*
+ * When a header level is 0, there is a possibilty that
+ * a pathname and a symlink has '\' character, a directory
+ * separator in DOS/Windows. So we should convert it to '/'.
+ */
+ if (p[H_LEVEL_OFFSET] == 0)
+ lha_replace_path_separator(lha, entry);
+
+ archive_entry_set_mode(entry, lha->mode);
+ archive_entry_set_uid(entry, lha->uid);
+ archive_entry_set_gid(entry, lha->gid);
+ if (archive_strlen(&lha->uname) > 0)
+ archive_entry_set_uname(entry, lha->uname.s);
+ if (archive_strlen(&lha->gname) > 0)
+ archive_entry_set_gname(entry, lha->gname.s);
+ if (lha->setflag & BIRTHTIME_IS_SET) {
+ archive_entry_set_birthtime(entry, lha->birthtime,
+ lha->birthtime_tv_nsec);
+ archive_entry_set_ctime(entry, lha->birthtime,
+ lha->birthtime_tv_nsec);
+ } else {
+ archive_entry_unset_birthtime(entry);
+ archive_entry_unset_ctime(entry);
+ }
+ archive_entry_set_mtime(entry, lha->mtime, lha->mtime_tv_nsec);
+ if (lha->setflag & ATIME_IS_SET)
+ archive_entry_set_atime(entry, lha->atime,
+ lha->atime_tv_nsec);
+ else
+ archive_entry_unset_atime(entry);
+ if (lha->directory || archive_entry_symlink(entry) != NULL)
+ archive_entry_unset_size(entry);
+ else
+ archive_entry_set_size(entry, lha->origsize);
+
+ /*
+ * Prepare variables used to read a file content.
+ */
+ lha->entry_bytes_remaining = lha->compsize;
+ lha->entry_offset = 0;
+ lha->entry_crc_calculated = 0;
+
+ /*
+ * This file does not have a content.
+ */
+ if (lha->directory || lha->compsize == 0)
+ lha->end_of_entry = 1;
+
+ sprintf(lha->format_name, "lha -%c%c%c-",
+ lha->method[0], lha->method[1], lha->method[2]);
+ a->archive.archive_format_name = lha->format_name;
+
+ return (err);
+}
+
+/*
+ * Replace a DOS path separator '\' by a character '/'.
+ * Some multi-byte character set have a character '\' in its second byte.
+ */
+static void
+lha_replace_path_separator(struct lha *lha, struct archive_entry *entry)
+{
+ const wchar_t *wp;
+ size_t i;
+
+ if ((wp = archive_entry_pathname_w(entry)) != NULL) {
+ archive_wstrcpy(&(lha->ws), wp);
+ for (i = 0; i < archive_strlen(&(lha->ws)); i++) {
+ if (lha->ws.s[i] == L'\\')
+ lha->ws.s[i] = L'/';
+ }
+ archive_entry_copy_pathname_w(entry, lha->ws.s);
+ }
+
+ if ((wp = archive_entry_symlink_w(entry)) != NULL) {
+ archive_wstrcpy(&(lha->ws), wp);
+ for (i = 0; i < archive_strlen(&(lha->ws)); i++) {
+ if (lha->ws.s[i] == L'\\')
+ lha->ws.s[i] = L'/';
+ }
+ archive_entry_copy_symlink_w(entry, lha->ws.s);
+ }
+}
+
+/*
+ * Header 0 format
+ *
+ * +0 +1 +2 +7 +11
+ * +---------------+----------+----------------+-------------------+
+ * |header size(*1)|header sum|compression type|compressed size(*2)|
+ * +---------------+----------+----------------+-------------------+
+ * <---------------------(*1)----------*
+ *
+ * +11 +15 +17 +19 +20 +21
+ * +-----------------+---------+---------+--------------+----------------+
+ * |uncompressed size|time(DOS)|date(DOS)|attribute(DOS)|header level(=0)|
+ * +-----------------+---------+---------+--------------+----------------+
+ * *--------------------------------(*1)---------------------------------*
+ *
+ * +21 +22 +22+(*3) +22+(*3)+2 +22+(*3)+2+(*4)
+ * +---------------+---------+----------+----------------+------------------+
+ * |name length(*3)|file name|file CRC16|extra header(*4)| compressed data |
+ * +---------------+---------+----------+----------------+------------------+
+ * <--(*3)-> <------(*2)------>
+ * *----------------------(*1)-------------------------->
+ *
+ */
+#define H0_HEADER_SIZE_OFFSET 0
+#define H0_HEADER_SUM_OFFSET 1
+#define H0_COMP_SIZE_OFFSET 7
+#define H0_ORIG_SIZE_OFFSET 11
+#define H0_DOS_TIME_OFFSET 15
+#define H0_NAME_LEN_OFFSET 21
+#define H0_FILE_NAME_OFFSET 22
+#define H0_FIXED_SIZE 24
+static int
+lha_read_file_header_0(struct archive_read *a, struct lha *lha)
+{
+ const unsigned char *p;
+ int extdsize, namelen;
+ unsigned char headersum, sum_calculated;
+
+ if ((p = __archive_read_ahead(a, H0_FIXED_SIZE, NULL)) == NULL)
+ return (truncated_error(a));
+ lha->header_size = p[H0_HEADER_SIZE_OFFSET] + 2;
+ headersum = p[H0_HEADER_SUM_OFFSET];
+ lha->compsize = archive_le32dec(p + H0_COMP_SIZE_OFFSET);
+ lha->origsize = archive_le32dec(p + H0_ORIG_SIZE_OFFSET);
+ lha->mtime = lha_dos_time(p + H0_DOS_TIME_OFFSET);
+ namelen = p[H0_NAME_LEN_OFFSET];
+ extdsize = (int)lha->header_size - H0_FIXED_SIZE - namelen;
+ if ((namelen > 221 || extdsize < 0) && extdsize != -2) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid LHa header");
+ return (ARCHIVE_FATAL);
+ }
+ if ((p = __archive_read_ahead(a, lha->header_size, NULL)) == NULL)
+ return (truncated_error(a));
+
+ archive_strncpy(&lha->filename, p + H0_FILE_NAME_OFFSET, namelen);
+ /* When extdsize == -2, A CRC16 value is not present in the header. */
+ if (extdsize >= 0) {
+ lha->crc = archive_le16dec(p + H0_FILE_NAME_OFFSET + namelen);
+ lha->setflag |= CRC_IS_SET;
+ }
+ sum_calculated = lha_calcsum(0, p, 2, lha->header_size - 2);
+
+ /* Read an extended header */
+ if (extdsize > 0) {
+ /* This extended data is set by 'LHa for UNIX' only.
+ * Maybe fixed size.
+ */
+ p += H0_FILE_NAME_OFFSET + namelen + 2;
+ if (p[0] == 'U' && extdsize == 12) {
+ /* p[1] is a minor version. */
+ lha->mtime = archive_le32dec(&p[2]);
+ lha->mode = archive_le16dec(&p[6]);
+ lha->uid = archive_le16dec(&p[8]);
+ lha->gid = archive_le16dec(&p[10]);
+ lha->setflag |= UNIX_MODE_IS_SET;
+ }
+ }
+ __archive_read_consume(a, lha->header_size);
+
+ if (sum_calculated != headersum) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "LHa header sum error");
+ return (ARCHIVE_FATAL);
+ }
+
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Header 1 format
+ *
+ * +0 +1 +2 +7 +11
+ * +---------------+----------+----------------+-------------+
+ * |header size(*1)|header sum|compression type|skip size(*2)|
+ * +---------------+----------+----------------+-------------+
+ * <---------------(*1)----------*
+ *
+ * +11 +15 +17 +19 +20 +21
+ * +-----------------+---------+---------+--------------+----------------+
+ * |uncompressed size|time(DOS)|date(DOS)|attribute(DOS)|header level(=1)|
+ * +-----------------+---------+---------+--------------+----------------+
+ * *-------------------------------(*1)----------------------------------*
+ *
+ * +21 +22 +22+(*3) +22+(*3)+2 +22+(*3)+3 +22+(*3)+3+(*4)
+ * +---------------+---------+----------+-----------+-----------+
+ * |name length(*3)|file name|file CRC16| creator |padding(*4)|
+ * +---------------+---------+----------+-----------+-----------+
+ * <--(*3)->
+ * *----------------------------(*1)----------------------------*
+ *
+ * +22+(*3)+3+(*4) +22+(*3)+3+(*4)+2 +22+(*3)+3+(*4)+2+(*5)
+ * +----------------+---------------------+------------------------+
+ * |next header size| extended header(*5) | compressed data |
+ * +----------------+---------------------+------------------------+
+ * *------(*1)-----> <--------------------(*2)-------------------->
+ */
+#define H1_HEADER_SIZE_OFFSET 0
+#define H1_HEADER_SUM_OFFSET 1
+#define H1_COMP_SIZE_OFFSET 7
+#define H1_ORIG_SIZE_OFFSET 11
+#define H1_DOS_TIME_OFFSET 15
+#define H1_NAME_LEN_OFFSET 21
+#define H1_FILE_NAME_OFFSET 22
+#define H1_FIXED_SIZE 27
+static int
+lha_read_file_header_1(struct archive_read *a, struct lha *lha)
+{
+ const unsigned char *p;
+ size_t extdsize;
+ int i, err, err2;
+ int namelen, padding;
+ unsigned char headersum, sum_calculated;
+
+ err = ARCHIVE_OK;
+
+ if ((p = __archive_read_ahead(a, H1_FIXED_SIZE, NULL)) == NULL)
+ return (truncated_error(a));
+
+ lha->header_size = p[H1_HEADER_SIZE_OFFSET] + 2;
+ headersum = p[H1_HEADER_SUM_OFFSET];
+ /* Note: An extended header size is included in a compsize. */
+ lha->compsize = archive_le32dec(p + H1_COMP_SIZE_OFFSET);
+ lha->origsize = archive_le32dec(p + H1_ORIG_SIZE_OFFSET);
+ lha->mtime = lha_dos_time(p + H1_DOS_TIME_OFFSET);
+ namelen = p[H1_NAME_LEN_OFFSET];
+ /* Calculate a padding size. The result will be normally 0 only(?) */
+ padding = ((int)lha->header_size) - H1_FIXED_SIZE - namelen;
+
+ if (namelen > 230 || padding < 0)
+ goto invalid;
+
+ if ((p = __archive_read_ahead(a, lha->header_size, NULL)) == NULL)
+ return (truncated_error(a));
+
+ for (i = 0; i < namelen; i++) {
+ if (p[i + H1_FILE_NAME_OFFSET] == 0xff)
+ goto invalid;/* Invalid filename. */
+ }
+ archive_strncpy(&lha->filename, p + H1_FILE_NAME_OFFSET, namelen);
+ lha->crc = archive_le16dec(p + H1_FILE_NAME_OFFSET + namelen);
+ lha->setflag |= CRC_IS_SET;
+
+ sum_calculated = lha_calcsum(0, p, 2, lha->header_size - 2);
+ /* Consume used bytes but not include `next header size' data
+ * since it will be consumed in lha_read_file_extended_header(). */
+ __archive_read_consume(a, lha->header_size - 2);
+
+ /* Read extended headers */
+ err2 = lha_read_file_extended_header(a, lha, NULL, 2,
+ lha->compsize + 2, &extdsize);
+ if (err2 < ARCHIVE_WARN)
+ return (err2);
+ if (err2 < err)
+ err = err2;
+ /* Get a real compressed file size. */
+ lha->compsize -= extdsize - 2;
+
+ if (sum_calculated != headersum) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "LHa header sum error");
+ return (ARCHIVE_FATAL);
+ }
+ return (err);
+invalid:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid LHa header");
+ return (ARCHIVE_FATAL);
+}
+
+/*
+ * Header 2 format
+ *
+ * +0 +2 +7 +11 +15
+ * +---------------+----------------+-------------------+-----------------+
+ * |header size(*1)|compression type|compressed size(*2)|uncompressed size|
+ * +---------------+----------------+-------------------+-----------------+
+ * <--------------------------------(*1)---------------------------------*
+ *
+ * +15 +19 +20 +21 +23 +24
+ * +-----------------+------------+----------------+----------+-----------+
+ * |data/time(time_t)| 0x20 fixed |header level(=2)|file CRC16| creator |
+ * +-----------------+------------+----------------+----------+-----------+
+ * *---------------------------------(*1)---------------------------------*
+ *
+ * +24 +26 +26+(*3) +26+(*3)+(*4)
+ * +----------------+-------------------+-------------+-------------------+
+ * |next header size|extended header(*3)| padding(*4) | compressed data |
+ * +----------------+-------------------+-------------+-------------------+
+ * *--------------------------(*1)-------------------> <------(*2)------->
+ *
+ */
+#define H2_HEADER_SIZE_OFFSET 0
+#define H2_COMP_SIZE_OFFSET 7
+#define H2_ORIG_SIZE_OFFSET 11
+#define H2_TIME_OFFSET 15
+#define H2_CRC_OFFSET 21
+#define H2_FIXED_SIZE 24
+static int
+lha_read_file_header_2(struct archive_read *a, struct lha *lha)
+{
+ const unsigned char *p;
+ size_t extdsize;
+ int err, padding;
+ uint16_t header_crc;
+
+ if ((p = __archive_read_ahead(a, H2_FIXED_SIZE, NULL)) == NULL)
+ return (truncated_error(a));
+
+ lha->header_size =archive_le16dec(p + H2_HEADER_SIZE_OFFSET);
+ lha->compsize = archive_le32dec(p + H2_COMP_SIZE_OFFSET);
+ lha->origsize = archive_le32dec(p + H2_ORIG_SIZE_OFFSET);
+ lha->mtime = archive_le32dec(p + H2_TIME_OFFSET);
+ lha->crc = archive_le16dec(p + H2_CRC_OFFSET);
+ lha->setflag |= CRC_IS_SET;
+
+ if (lha->header_size < H2_FIXED_SIZE) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid LHa header size");
+ return (ARCHIVE_FATAL);
+ }
+
+ header_crc = lha_crc16(0, p, H2_FIXED_SIZE);
+ __archive_read_consume(a, H2_FIXED_SIZE);
+
+ /* Read extended headers */
+ err = lha_read_file_extended_header(a, lha, &header_crc, 2,
+ lha->header_size - H2_FIXED_SIZE, &extdsize);
+ if (err < ARCHIVE_WARN)
+ return (err);
+
+ /* Calculate a padding size. The result will be normally 0 or 1. */
+ padding = (int)lha->header_size - (int)(H2_FIXED_SIZE + extdsize);
+ if (padding > 0) {
+ if ((p = __archive_read_ahead(a, padding, NULL)) == NULL)
+ return (truncated_error(a));
+ header_crc = lha_crc16(header_crc, p, padding);
+ __archive_read_consume(a, padding);
+ }
+
+ if (header_crc != lha->header_crc) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "LHa header CRC error");
+ return (ARCHIVE_FATAL);
+ }
+ return (err);
+}
+
+/*
+ * Header 3 format
+ *
+ * +0 +2 +7 +11 +15
+ * +------------+----------------+-------------------+-----------------+
+ * | 0x04 fixed |compression type|compressed size(*2)|uncompressed size|
+ * +------------+----------------+-------------------+-----------------+
+ * <-------------------------------(*1)-------------------------------*
+ *
+ * +15 +19 +20 +21 +23 +24
+ * +-----------------+------------+----------------+----------+-----------+
+ * |date/time(time_t)| 0x20 fixed |header level(=3)|file CRC16| creator |
+ * +-----------------+------------+----------------+----------+-----------+
+ * *--------------------------------(*1)----------------------------------*
+ *
+ * +24 +28 +32 +32+(*3)
+ * +---------------+----------------+-------------------+-----------------+
+ * |header size(*1)|next header size|extended header(*3)| compressed data |
+ * +---------------+----------------+-------------------+-----------------+
+ * *------------------------(*1)-----------------------> <------(*2)----->
+ *
+ */
+#define H3_FIELD_LEN_OFFSET 0
+#define H3_COMP_SIZE_OFFSET 7
+#define H3_ORIG_SIZE_OFFSET 11
+#define H3_TIME_OFFSET 15
+#define H3_CRC_OFFSET 21
+#define H3_HEADER_SIZE_OFFSET 24
+#define H3_FIXED_SIZE 28
+static int
+lha_read_file_header_3(struct archive_read *a, struct lha *lha)
+{
+ const unsigned char *p;
+ size_t extdsize;
+ int err;
+ uint16_t header_crc;
+
+ if ((p = __archive_read_ahead(a, H3_FIXED_SIZE, NULL)) == NULL)
+ return (truncated_error(a));
+
+ if (archive_le16dec(p + H3_FIELD_LEN_OFFSET) != 4)
+ goto invalid;
+ lha->header_size =archive_le32dec(p + H3_HEADER_SIZE_OFFSET);
+ lha->compsize = archive_le32dec(p + H3_COMP_SIZE_OFFSET);
+ lha->origsize = archive_le32dec(p + H3_ORIG_SIZE_OFFSET);
+ lha->mtime = archive_le32dec(p + H3_TIME_OFFSET);
+ lha->crc = archive_le16dec(p + H3_CRC_OFFSET);
+ lha->setflag |= CRC_IS_SET;
+
+ if (lha->header_size < H3_FIXED_SIZE + 4)
+ goto invalid;
+ header_crc = lha_crc16(0, p, H3_FIXED_SIZE);
+ __archive_read_consume(a, H3_FIXED_SIZE);
+
+ /* Read extended headers */
+ err = lha_read_file_extended_header(a, lha, &header_crc, 4,
+ lha->header_size - H3_FIXED_SIZE, &extdsize);
+ if (err < ARCHIVE_WARN)
+ return (err);
+
+ if (header_crc != lha->header_crc) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "LHa header CRC error");
+ return (ARCHIVE_FATAL);
+ }
+ return (err);
+invalid:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid LHa header");
+ return (ARCHIVE_FATAL);
+}
+
+/*
+ * Extended header format
+ *
+ * +0 +2 +3 -- used in header 1 and 2
+ * +0 +4 +5 -- used in header 3
+ * +--------------+---------+-------------------+--------------+--
+ * |ex-header size|header id| data |ex-header size| .......
+ * +--------------+---------+-------------------+--------------+--
+ * <-------------( ex-header size)------------> <-- next extended header --*
+ *
+ * If the ex-header size is zero, it is the make of the end of extended
+ * headers.
+ *
+ */
+static int
+lha_read_file_extended_header(struct archive_read *a, struct lha *lha,
+ uint16_t *crc, int sizefield_length, size_t limitsize, size_t *total_size)
+{
+ const void *h;
+ const unsigned char *extdheader;
+ size_t extdsize;
+ size_t datasize;
+ unsigned int i;
+ unsigned char extdtype;
+
+#define EXT_HEADER_CRC 0x00 /* Header CRC and information*/
+#define EXT_FILENAME 0x01 /* Filename */
+#define EXT_DIRECTORY 0x02 /* Directory name */
+#define EXT_DOS_ATTR 0x40 /* MS-DOS attribute */
+#define EXT_TIMESTAMP 0x41 /* Windows time stamp */
+#define EXT_FILESIZE 0x42 /* Large file size */
+#define EXT_TIMEZONE 0x43 /* Time zone */
+#define EXT_UTF16_FILENAME 0x44 /* UTF-16 filename */
+#define EXT_UTF16_DIRECTORY 0x45 /* UTF-16 directory name */
+#define EXT_CODEPAGE 0x46 /* Codepage */
+#define EXT_UNIX_MODE 0x50 /* File permission */
+#define EXT_UNIX_GID_UID 0x51 /* gid,uid */
+#define EXT_UNIX_GNAME 0x52 /* Group name */
+#define EXT_UNIX_UNAME 0x53 /* User name */
+#define EXT_UNIX_MTIME 0x54 /* Modified time */
+#define EXT_OS2_NEW_ATTR 0x7f /* new attribute(OS/2 only) */
+#define EXT_NEW_ATTR 0xff /* new attribute */
+
+ *total_size = sizefield_length;
+
+ for (;;) {
+ /* Read an extended header size. */
+ if ((h =
+ __archive_read_ahead(a, sizefield_length, NULL)) == NULL)
+ return (truncated_error(a));
+ /* Check if the size is the zero indicates the end of the
+ * extended header. */
+ if (sizefield_length == sizeof(uint16_t))
+ extdsize = archive_le16dec(h);
+ else
+ extdsize = archive_le32dec(h);
+ if (extdsize == 0) {
+ /* End of extended header */
+ if (crc != NULL)
+ *crc = lha_crc16(*crc, h, sizefield_length);
+ __archive_read_consume(a, sizefield_length);
+ return (ARCHIVE_OK);
+ }
+
+ /* Sanity check to the extended header size. */
+ if (((uint64_t)*total_size + extdsize) >
+ (uint64_t)limitsize ||
+ extdsize <= (size_t)sizefield_length)
+ goto invalid;
+
+ /* Read the extended header. */
+ if ((h = __archive_read_ahead(a, extdsize, NULL)) == NULL)
+ return (truncated_error(a));
+ *total_size += extdsize;
+
+ extdheader = (const unsigned char *)h;
+ /* Get the extended header type. */
+ extdtype = extdheader[sizefield_length];
+ /* Calculate an extended data size. */
+ datasize = extdsize - (1 + sizefield_length);
+ /* Skip an extended header size field and type field. */
+ extdheader += sizefield_length + 1;
+
+ if (crc != NULL && extdtype != EXT_HEADER_CRC)
+ *crc = lha_crc16(*crc, h, extdsize);
+ switch (extdtype) {
+ case EXT_HEADER_CRC:
+ /* We only use a header CRC. Following data will not
+ * be used. */
+ if (datasize >= 2) {
+ lha->header_crc = archive_le16dec(extdheader);
+ if (crc != NULL) {
+ static const char zeros[2] = {0, 0};
+ *crc = lha_crc16(*crc, h,
+ extdsize - datasize);
+ /* CRC value itself as zero */
+ *crc = lha_crc16(*crc, zeros, 2);
+ *crc = lha_crc16(*crc,
+ extdheader+2, datasize - 2);
+ }
+ }
+ break;
+ case EXT_FILENAME:
+ if (datasize == 0) {
+ /* maybe directory header */
+ archive_string_empty(&lha->filename);
+ break;
+ }
+ archive_strncpy(&lha->filename,
+ (const char *)extdheader, datasize);
+ break;
+ case EXT_DIRECTORY:
+ if (datasize == 0)
+ /* no directory name data. exit this case. */
+ break;
+
+ archive_strncpy(&lha->dirname,
+ (const char *)extdheader, datasize);
+ /*
+ * Convert directory delimiter from 0xFF
+ * to '/' for local system.
+ */
+ for (i = 0; i < lha->dirname.length; i++) {
+ if ((unsigned char)lha->dirname.s[i] == 0xFF)
+ lha->dirname.s[i] = '/';
+ }
+ /* Is last character directory separator? */
+ if (lha->dirname.s[lha->dirname.length-1] != '/')
+ /* invalid directory data */
+ goto invalid;
+ break;
+ case EXT_DOS_ATTR:
+ if (datasize == 2)
+ lha->dos_attr = (unsigned char)
+ (archive_le16dec(extdheader) & 0xff);
+ break;
+ case EXT_TIMESTAMP:
+ if (datasize == (sizeof(uint64_t) * 3)) {
+ lha->birthtime = lha_win_time(
+ archive_le64dec(extdheader),
+ &lha->birthtime_tv_nsec);
+ extdheader += sizeof(uint64_t);
+ lha->mtime = lha_win_time(
+ archive_le64dec(extdheader),
+ &lha->mtime_tv_nsec);
+ extdheader += sizeof(uint64_t);
+ lha->atime = lha_win_time(
+ archive_le64dec(extdheader),
+ &lha->atime_tv_nsec);
+ lha->setflag |= BIRTHTIME_IS_SET |
+ ATIME_IS_SET;
+ }
+ break;
+ case EXT_FILESIZE:
+ if (datasize == sizeof(uint64_t) * 2) {
+ lha->compsize = archive_le64dec(extdheader);
+ extdheader += sizeof(uint64_t);
+ lha->origsize = archive_le64dec(extdheader);
+ }
+ break;
+ case EXT_CODEPAGE:
+ /* Get an archived filename charset from codepage.
+ * This overwrites the charset specified by
+ * hdrcharset option. */
+ if (datasize == sizeof(uint32_t)) {
+ struct archive_string cp;
+ const char *charset;
+
+ archive_string_init(&cp);
+ switch (archive_le32dec(extdheader)) {
+ case 65001: /* UTF-8 */
+ charset = "UTF-8";
+ break;
+ default:
+ archive_string_sprintf(&cp, "CP%d",
+ (int)archive_le32dec(extdheader));
+ charset = cp.s;
+ break;
+ }
+ lha->sconv =
+ archive_string_conversion_from_charset(
+ &(a->archive), charset, 1);
+ archive_string_free(&cp);
+ if (lha->sconv == NULL)
+ return (ARCHIVE_FATAL);
+ }
+ break;
+ case EXT_UNIX_MODE:
+ if (datasize == sizeof(uint16_t)) {
+ lha->mode = archive_le16dec(extdheader);
+ lha->setflag |= UNIX_MODE_IS_SET;
+ }
+ break;
+ case EXT_UNIX_GID_UID:
+ if (datasize == (sizeof(uint16_t) * 2)) {
+ lha->gid = archive_le16dec(extdheader);
+ lha->uid = archive_le16dec(extdheader+2);
+ }
+ break;
+ case EXT_UNIX_GNAME:
+ if (datasize > 0)
+ archive_strncpy(&lha->gname,
+ (const char *)extdheader, datasize);
+ break;
+ case EXT_UNIX_UNAME:
+ if (datasize > 0)
+ archive_strncpy(&lha->uname,
+ (const char *)extdheader, datasize);
+ break;
+ case EXT_UNIX_MTIME:
+ if (datasize == sizeof(uint32_t))
+ lha->mtime = archive_le32dec(extdheader);
+ break;
+ case EXT_OS2_NEW_ATTR:
+ /* This extended header is OS/2 depend. */
+ if (datasize == 16) {
+ lha->dos_attr = (unsigned char)
+ (archive_le16dec(extdheader) & 0xff);
+ lha->mode = archive_le16dec(extdheader+2);
+ lha->gid = archive_le16dec(extdheader+4);
+ lha->uid = archive_le16dec(extdheader+6);
+ lha->birthtime = archive_le32dec(extdheader+8);
+ lha->atime = archive_le32dec(extdheader+12);
+ lha->setflag |= UNIX_MODE_IS_SET
+ | BIRTHTIME_IS_SET | ATIME_IS_SET;
+ }
+ break;
+ case EXT_NEW_ATTR:
+ if (datasize == 20) {
+ lha->mode = (mode_t)archive_le32dec(extdheader);
+ lha->gid = archive_le32dec(extdheader+4);
+ lha->uid = archive_le32dec(extdheader+8);
+ lha->birthtime = archive_le32dec(extdheader+12);
+ lha->atime = archive_le32dec(extdheader+16);
+ lha->setflag |= UNIX_MODE_IS_SET
+ | BIRTHTIME_IS_SET | ATIME_IS_SET;
+ }
+ break;
+ case EXT_TIMEZONE: /* Not supported */
+ case EXT_UTF16_FILENAME: /* Not supported */
+ case EXT_UTF16_DIRECTORY: /* Not supported */
+ default:
+ break;
+ }
+
+ __archive_read_consume(a, extdsize);
+ }
+invalid:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid extended LHa header");
+ return (ARCHIVE_FATAL);
+}
+
+static int
+archive_read_format_lha_read_data(struct archive_read *a,
+ const void **buff, size_t *size, int64_t *offset)
+{
+ struct lha *lha = (struct lha *)(a->format->data);
+ int r;
+
+ if (lha->entry_unconsumed) {
+ /* Consume as much as the decompressor actually used. */
+ __archive_read_consume(a, lha->entry_unconsumed);
+ 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);
+ }
+
+ if (lha->entry_is_compressed)
+ r = lha_read_data_lzh(a, buff, size, offset);
+ else
+ /* No compression. */
+ r = lha_read_data_none(a, buff, size, offset);
+ return (r);
+}
+
+/*
+ * Read a file content in no compression.
+ *
+ * Returns ARCHIVE_OK if successful, ARCHIVE_FATAL otherwise, sets
+ * lha->end_of_entry if it consumes all of the data.
+ */
+static int
+lha_read_data_none(struct archive_read *a, const void **buff,
+ size_t *size, int64_t *offset)
+{
+ struct lha *lha = (struct lha *)(a->format->data);
+ ssize_t bytes_avail;
+
+ if (lha->entry_bytes_remaining == 0) {
+ *buff = NULL;
+ *size = 0;
+ *offset = lha->entry_offset;
+ lha->end_of_entry = 1;
+ return (ARCHIVE_OK);
+ }
+ /*
+ * Note: '1' here is a performance optimization.
+ * Recall that the decompression layer returns a count of
+ * available bytes; asking for more than that forces the
+ * decompressor to combine reads by copying data.
+ */
+ *buff = __archive_read_ahead(a, 1, &bytes_avail);
+ if (bytes_avail <= 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated LHa file data");
+ return (ARCHIVE_FATAL);
+ }
+ if (bytes_avail > lha->entry_bytes_remaining)
+ bytes_avail = lha->entry_bytes_remaining;
+ lha->entry_crc_calculated =
+ lha_crc16(lha->entry_crc_calculated, *buff, bytes_avail);
+ *size = bytes_avail;
+ *offset = lha->entry_offset;
+ lha->entry_offset += bytes_avail;
+ lha->entry_bytes_remaining -= bytes_avail;
+ if (lha->entry_bytes_remaining == 0)
+ lha->end_of_entry = 1;
+ lha->entry_unconsumed = bytes_avail;
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Read a file content in LZHUFF encoding.
+ *
+ * Returns ARCHIVE_OK if successful, returns ARCHIVE_WARN if compression is
+ * unsupported, ARCHIVE_FATAL otherwise, sets lha->end_of_entry if it consumes
+ * all of the data.
+ */
+static int
+lha_read_data_lzh(struct archive_read *a, const void **buff,
+ size_t *size, int64_t *offset)
+{
+ struct lha *lha = (struct lha *)(a->format->data);
+ 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);
+ switch (r) {
+ case ARCHIVE_OK:
+ break;
+ case ARCHIVE_FAILED:
+ /* Unsupported compression. */
+ *buff = NULL;
+ *size = 0;
+ *offset = 0;
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Unsupported lzh compression method -%c%c%c-",
+ lha->method[0], lha->method[1], lha->method[2]);
+ /* We know compressed size; just skip it. */
+ archive_read_format_lha_read_data_skip(a);
+ return (ARCHIVE_WARN);
+ default:
+ archive_set_error(&a->archive, ENOMEM,
+ "Couldn't allocate memory "
+ "for lzh decompression");
+ return (ARCHIVE_FATAL);
+ }
+ /* We've initialized decompression for this stream. */
+ lha->decompress_init = 1;
+ lha->strm.avail_out = 0;
+ lha->strm.total_out = 0;
+ }
+
+ /*
+ * Note: '1' here is a performance optimization.
+ * Recall that the decompression layer returns a count of
+ * available bytes; asking for more than that forces the
+ * decompressor to combine reads by copying data.
+ */
+ lha->strm.next_in = __archive_read_ahead(a, 1, &bytes_avail);
+ if (bytes_avail <= 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated LHa file body");
+ return (ARCHIVE_FATAL);
+ }
+ if (bytes_avail > lha->entry_bytes_remaining)
+ bytes_avail = lha->entry_bytes_remaining;
+
+ lha->strm.avail_in = 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;
+ }
+
+ r = lzh_decode(&(lha->strm), bytes_avail == lha->entry_bytes_remaining);
+ switch (r) {
+ case ARCHIVE_OK:
+ break;
+ case ARCHIVE_EOF:
+ lha->end_of_entry = 1;
+ break;
+ default:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Bad lzh data");
+ return (ARCHIVE_FAILED);
+ }
+ 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) {
+ *offset = lha->entry_offset;
+ *size = lha->strm.next_out - lha->uncompressed_buffer;
+ *buff = lha->uncompressed_buffer;
+ lha->entry_crc_calculated =
+ lha_crc16(lha->entry_crc_calculated, *buff, *size);
+ lha->entry_offset += *size;
+ } else {
+ *offset = lha->entry_offset;
+ *size = 0;
+ *buff = NULL;
+ }
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Skip a file content.
+ */
+static int
+archive_read_format_lha_read_data_skip(struct archive_read *a)
+{
+ struct lha *lha;
+ off_t bytes_skipped;
+
+ lha = (struct lha *)(a->format->data);
+
+ if (lha->entry_unconsumed) {
+ /* Consume as much as the decompressor actually used. */
+ __archive_read_consume(a, lha->entry_unconsumed);
+ lha->entry_unconsumed = 0;
+ }
+
+ /* if we've already read to end of data, we're done. */
+ if (lha->end_of_entry_cleanup)
+ return (ARCHIVE_OK);
+
+ /*
+ * If the length is at the beginning, we can skip the
+ * compressed data much more quickly.
+ */
+ bytes_skipped = __archive_read_consume(a, lha->entry_bytes_remaining);
+ if (bytes_skipped < 0)
+ return (ARCHIVE_FATAL);
+
+ /* This entry is finished and done. */
+ lha->end_of_entry_cleanup = lha->end_of_entry = 1;
+ return (ARCHIVE_OK);
+}
+
+static int
+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));
+ archive_string_free(&(lha->gname));
+ archive_wstring_free(&(lha->ws));
+ free(lha);
+ (a->format->data) = NULL;
+ return (ARCHIVE_OK);
+}
+
+/*
+ * 'LHa for UNIX' utility has archived a symbolic-link name after
+ * a pathname with '|' character.
+ * This function extracts the symbolic-link name from the pathname.
+ *
+ * example.
+ * 1. a symbolic-name is 'aaa/bb/cc'
+ * 2. a filename is 'xxx/bbb'
+ * then a archived pathname is 'xxx/bbb|aaa/bb/cc'
+ */
+static int
+lha_parse_linkname(struct archive_string *linkname,
+ struct archive_string *pathname)
+{
+ char * linkptr;
+ int symlen;
+
+ linkptr = strchr(pathname->s, '|');
+ if (linkptr != NULL) {
+ symlen = strlen(linkptr + 1);
+ archive_strncpy(linkname, linkptr+1, symlen);
+
+ *linkptr = 0;
+ pathname->length = strlen(pathname->s);
+
+ return (1);
+ }
+ return (0);
+}
+
+/* Convert an MSDOS-style date/time into Unix-style time. */
+static time_t
+lha_dos_time(const unsigned char *p)
+{
+ int msTime, msDate;
+ struct tm ts;
+
+ msTime = archive_le16dec(p);
+ msDate = archive_le16dec(p+2);
+
+ 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));
+}
+
+/* Convert an MS-Windows-style date/time into Unix-style time. */
+static time_t
+lha_win_time(uint64_t wintime, long *ns)
+{
+#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
+
+ if (wintime >= EPOC_TIME) {
+ wintime -= EPOC_TIME; /* 1970-01-01 00:00:00 (UTC) */
+ if (ns != NULL)
+ *ns = (long)(wintime % 10000000) * 100;
+ return (wintime / 10000000);
+ } else {
+ if (ns != NULL)
+ *ns = 0;
+ return (0);
+ }
+}
+
+static unsigned char
+lha_calcsum(unsigned char sum, const void *pp, int offset, int size)
+{
+ unsigned char const *p = (unsigned char const *)pp;
+
+ p += offset;
+ while (--size >= 0)
+ sum += *p++;
+ return (sum);
+}
+
+#define CRC16(crc, v) do { \
+ (crc) = crc16tbl[((crc) ^ v) & 0xFF] ^ ((crc) >> 8); \
+} while (0)
+
+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;
+ }
+ 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;
+ }
+ return (crc);
+}
+
+
+/*
+ * Initialize LZHUF decoder.
+ *
+ * Returns ARCHIVE_OK if initialization was successful.
+ * Returns ARCHIVE_FAILED if method is unsupported.
+ * Returns ARCHIVE_FATAL if initialization failed; memory allocation
+ * error occurred.
+ */
+static int
+lzh_decode_init(struct lzh_stream *strm, const char *method)
+{
+ struct lzh_dec *ds;
+ int w_bits, w_size;
+
+ if (strm->ds == NULL) {
+ strm->ds = calloc(1, sizeof(*strm->ds));
+ if (strm->ds == NULL)
+ return (ARCHIVE_FATAL);
+ }
+ ds = strm->ds;
+ ds->error = ARCHIVE_FAILED;
+ if (method == NULL || method[0] != 'l' || method[1] != 'h')
+ return (ARCHIVE_FAILED);
+ switch (method[2]) {
+ case '5':
+ w_bits = 13;/* 8KiB for window */
+ break;
+ case '6':
+ w_bits = 15;/* 32KiB for window */
+ break;
+ case '7':
+ w_bits = 16;/* 64KiB for window */
+ break;
+ default:
+ return (ARCHIVE_FAILED);/* Not supported. */
+ }
+ ds->error = ARCHIVE_FATAL;
+ w_size = ds->w_size;
+ ds->w_size = 1U << w_bits;
+ ds->w_mask = ds->w_size -1;
+ if (ds->w_buff == NULL || w_size != ds->w_size) {
+ free(ds->w_buff);
+ ds->w_buff = malloc(ds->w_size);
+ if (ds->w_buff == NULL)
+ return (ARCHIVE_FATAL);
+ }
+ memset(ds->w_buff, 0x20, ds->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;
+ ds->literal_pt_len_size = PT_BITLEN_SIZE;
+ ds->literal_pt_len_bits = 5;
+ ds->br.cache_buffer = 0;
+ ds->br.cache_avail = 0;
+
+ if (lzh_huffman_init(&(ds->lt), LT_BITLEN_SIZE, 16)
+ != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ ds->lt.len_bits = 9;
+ if (lzh_huffman_init(&(ds->pt), PT_BITLEN_SIZE, 16)
+ != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ ds->error = 0;
+
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Release LZHUF decoder.
+ */
+static void
+lzh_decode_free(struct lzh_stream *strm)
+{
+
+ if (strm->ds == NULL)
+ return;
+ free(strm->ds->w_buff);
+ lzh_huffman_free(&(strm->ds->lt));
+ lzh_huffman_free(&(strm->ds->pt));
+ free(strm->ds);
+ strm->ds = NULL;
+}
+
+/*
+ * Bit stream reader.
+ */
+/* Check that the cache buffer has enough bits. */
+#define lzh_br_has(br, n) ((br)->cache_avail >= n)
+/* Get compressed data by bit. */
+#define lzh_br_bits(br, n) \
+ (((uint16_t)((br)->cache_buffer >> \
+ ((br)->cache_avail - (n)))) & cache_masks[n])
+#define lzh_br_bits_forced(br, n) \
+ (((uint16_t)((br)->cache_buffer << \
+ ((n) - (br)->cache_avail))) & cache_masks[n])
+/* Read ahead to make sure the cache buffer has enough compressed data we
+ * will use.
+ * True : completed, there is enough data in the cache buffer.
+ * False : we met that strm->next_in is empty, we have to get following
+ * bytes. */
+#define lzh_br_read_ahead_0(strm, br, n) \
+ (lzh_br_has(br, (n)) || lzh_br_fillup(strm, br))
+/* True : the cache buffer has some bits as much as we need.
+ * False : there are no enough bits in the cache buffer to be used,
+ * we have to get following bytes if we could. */
+#define lzh_br_read_ahead(strm, br, n) \
+ (lzh_br_read_ahead_0((strm), (br), (n)) || lzh_br_has((br), (n)))
+
+/* Notify how many bits we consumed. */
+#define lzh_br_consume(br, n) ((br)->cache_avail -= (n))
+#define lzh_br_unconsume(br, n) ((br)->cache_avail += (n))
+
+static const uint16_t cache_masks[] = {
+ 0x0000, 0x0001, 0x0003, 0x0007,
+ 0x000F, 0x001F, 0x003F, 0x007F,
+ 0x00FF, 0x01FF, 0x03FF, 0x07FF,
+ 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF,
+ 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF
+};
+
+/*
+ * Shift away used bits in the cache data and fill it up with following bits.
+ * Call this when cache buffer does not have enough bits you need.
+ *
+ * Returns 1 if the cache buffer is full.
+ * Returns 0 if the cache buffer is not full; input buffer is empty.
+ */
+static int
+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) {
+ br->cache_buffer =
+ ((uint64_t)strm->next_in[0]) << 56 |
+ ((uint64_t)strm->next_in[1]) << 48 |
+ ((uint64_t)strm->next_in[2]) << 40 |
+ ((uint64_t)strm->next_in[3]) << 32 |
+ ((uint32_t)strm->next_in[4]) << 24 |
+ ((uint32_t)strm->next_in[5]) << 16 |
+ ((uint32_t)strm->next_in[6]) << 8 |
+ (uint32_t)strm->next_in[7];
+ strm->next_in += 8;
+ strm->avail_in -= 8;
+ br->cache_avail += 8 * 8;
+ return (1);
+ }
+ break;
+ case 7:
+ if (strm->avail_in >= 7) {
+ br->cache_buffer =
+ (br->cache_buffer << 56) |
+ ((uint64_t)strm->next_in[0]) << 48 |
+ ((uint64_t)strm->next_in[1]) << 40 |
+ ((uint64_t)strm->next_in[2]) << 32 |
+ ((uint32_t)strm->next_in[3]) << 24 |
+ ((uint32_t)strm->next_in[4]) << 16 |
+ ((uint32_t)strm->next_in[5]) << 8 |
+ (uint32_t)strm->next_in[6];
+ strm->next_in += 7;
+ strm->avail_in -= 7;
+ br->cache_avail += 7 * 8;
+ return (1);
+ }
+ break;
+ case 6:
+ if (strm->avail_in >= 6) {
+ br->cache_buffer =
+ (br->cache_buffer << 48) |
+ ((uint64_t)strm->next_in[0]) << 40 |
+ ((uint64_t)strm->next_in[1]) << 32 |
+ ((uint32_t)strm->next_in[2]) << 24 |
+ ((uint32_t)strm->next_in[3]) << 16 |
+ ((uint32_t)strm->next_in[4]) << 8 |
+ (uint32_t)strm->next_in[5];
+ strm->next_in += 6;
+ strm->avail_in -= 6;
+ br->cache_avail += 6 * 8;
+ return (1);
+ }
+ 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
+ * cache buffer. */
+ return (0);
+ }
+ br->cache_buffer =
+ (br->cache_buffer << 8) | *strm->next_in++;
+ strm->avail_in--;
+ br->cache_avail += 8;
+ n -= 8;
+ }
+}
+
+/*
+ * Decode LZHUF.
+ *
+ * 1. Returns ARCHIVE_OK if output buffer or input buffer are empty.
+ * Please set available buffer and call this function again.
+ * 2. Returns ARCHIVE_EOF if decompression has been completed.
+ * 3. Returns ARCHIVE_FAILED if an error occurred; compressed data
+ * is broken or you do not set 'last' flag properly.
+ * 4. 'last' flag is very important, you must set 1 to the flag if there
+ * is no input data. The lha compressed data format does not provide how
+ * to know the compressed data is really finished.
+ * Note: lha command utility check if the total size of output bytes is
+ * reached the uncompressed size recorded in its header. it does not mind
+ * that the decoding process is properly finished.
+ * GNU ZIP can decompress another compressed file made by SCO LZH compress.
+ * it handles EOF as null to fill read buffer with zero until the decoding
+ * process meet 2 bytes of zeros at reading a size of a next chunk, so the
+ * zeros are treated as the mark of the end of the data although the zeros
+ * is dummy, not the file data.
+ */
+static int lzh_read_blocks(struct lzh_stream *, int);
+static int lzh_decode_blocks(struct lzh_stream *, int);
+#define ST_RD_BLOCK 0
+#define ST_RD_PT_1 1
+#define ST_RD_PT_2 2
+#define ST_RD_PT_3 3
+#define ST_RD_PT_4 4
+#define ST_RD_LITERAL_1 5
+#define ST_RD_LITERAL_2 6
+#define ST_RD_LITERAL_3 7
+#define ST_RD_POS_DATA_1 8
+#define ST_GET_LITERAL 9
+#define ST_GET_POS_1 10
+#define ST_GET_POS_2 11
+#define ST_COPY_DATA 12
+
+static int
+lzh_decode(struct lzh_stream *strm, int last)
+{
+ struct lzh_dec *ds = strm->ds;
+ int64_t avail_in;
+ int r;
+
+ if (ds->error)
+ return (ds->error);
+
+ avail_in = strm->avail_in;
+ do {
+ if (ds->state < ST_GET_LITERAL)
+ r = lzh_read_blocks(strm, last);
+ else
+ r = lzh_decode_blocks(strm, last);
+ } while (r == 100);
+ strm->total_in += avail_in - strm->avail_in;
+ return (r);
+}
+
+static int
+lzh_copy_from_window(struct lzh_stream *strm, struct lzh_dec *ds)
+{
+ 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 = strm->avail_out;
+ memcpy(strm->next_out,
+ ds->w_buff + ds->copy_pos, copy_bytes);
+ ds->copy_pos += copy_bytes;
+ } else {
+ if (ds->w_remaining <= strm->avail_out)
+ copy_bytes = ds->w_remaining;
+ else
+ copy_bytes = strm->avail_out;
+ memcpy(strm->next_out,
+ ds->w_buff + ds->w_size - ds->w_remaining, copy_bytes);
+ ds->w_remaining -= 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);
+}
+
+static int
+lzh_read_blocks(struct lzh_stream *strm, int last)
+{
+ struct lzh_dec *ds = strm->ds;
+ struct lzh_br *br = &(ds->br);
+ int c = 0, i;
+ unsigned rbits;
+
+ for (;;) {
+ switch (ds->state) {
+ case ST_RD_BLOCK:
+ /*
+ * Read a block number indicates how many blocks
+ * we will handle. The block is composed of a
+ * literal and a match, sometimes a literal only
+ * in particular, there are no reference data at
+ * the beginning of the decompression.
+ */
+ if (!lzh_br_read_ahead_0(strm, br, 16)) {
+ if (!last)
+ /* We need following data. */
+ return (ARCHIVE_OK);
+ if (lzh_br_has(br, 8)) {
+ /*
+ * It seems there are extra bits.
+ * 1. Compressed data is broken.
+ * 2. `last' flag does not properly
+ * set.
+ */
+ goto failed;
+ }
+ if (ds->w_pos > 0) {
+ if (!lzh_copy_from_window(strm, ds))
+ return (ARCHIVE_OK);
+ }
+ /* End of compressed data; we have completely
+ * handled all compressed data. */
+ return (ARCHIVE_EOF);
+ }
+ ds->blocks_avail = lzh_br_bits(br, 16);
+ if (ds->blocks_avail == 0)
+ goto failed;
+ lzh_br_consume(br, 16);
+ /*
+ * Read a literal table compressed in huffman
+ * coding.
+ */
+ ds->pt.len_size = ds->literal_pt_len_size;
+ ds->pt.len_bits = ds->literal_pt_len_bits;
+ ds->reading_position = 0;
+ /* FALL THROUGH */
+ case ST_RD_PT_1:
+ /* Note: ST_RD_PT_1, ST_RD_PT_2 and ST_RD_PT_4 are
+ * used in reading both a literal table and a
+ * position table. */
+ if (!lzh_br_read_ahead(strm, br, ds->pt.len_bits)) {
+ if (last)
+ goto failed;/* Truncated data. */
+ ds->state = ST_RD_PT_1;
+ return (ARCHIVE_OK);
+ }
+ ds->pt.len_avail = lzh_br_bits(br, ds->pt.len_bits);
+ lzh_br_consume(br, ds->pt.len_bits);
+ /* FALL THROUGH */
+ case ST_RD_PT_2:
+ if (ds->pt.len_avail == 0) {
+ /* There is no bitlen. */
+ if (!lzh_br_read_ahead(strm, br,
+ ds->pt.len_bits)) {
+ if (last)
+ goto failed;/* Truncated data.*/
+ ds->state = ST_RD_PT_2;
+ return (ARCHIVE_OK);
+ }
+ if (!lzh_make_fake_table(&(ds->pt),
+ lzh_br_bits(br, ds->pt.len_bits)))
+ goto failed;/* Invalid data. */
+ lzh_br_consume(br, ds->pt.len_bits);
+ if (ds->reading_position)
+ ds->state = ST_GET_LITERAL;
+ else
+ ds->state = ST_RD_LITERAL_1;
+ break;
+ } else if (ds->pt.len_avail > ds->pt.len_size)
+ goto failed;/* Invalid data. */
+ ds->loop = 0;
+ memset(ds->pt.freq, 0, sizeof(ds->pt.freq));
+ if (ds->pt.len_avail < 3 ||
+ ds->pt.len_size == ds->pos_pt_len_size) {
+ ds->state = ST_RD_PT_4;
+ break;
+ }
+ /* FALL THROUGH */
+ case ST_RD_PT_3:
+ ds->loop = lzh_read_pt_bitlen(strm, ds->loop, 3);
+ if (ds->loop < 3) {
+ if (ds->loop < 0 || last)
+ goto failed;/* Invalid data. */
+ /* Not completed, get following data. */
+ ds->state = ST_RD_PT_3;
+ return (ARCHIVE_OK);
+ }
+ /* There are some null in bitlen of the literal. */
+ if (!lzh_br_read_ahead(strm, br, 2)) {
+ if (last)
+ goto failed;/* Truncated data. */
+ ds->state = ST_RD_PT_3;
+ return (ARCHIVE_OK);
+ }
+ c = lzh_br_bits(br, 2);
+ lzh_br_consume(br, 2);
+ if (c > ds->pt.len_avail - 3)
+ goto failed;/* Invalid data. */
+ for (i = 3; c-- > 0 ;)
+ ds->pt.bitlen[i++] = 0;
+ ds->loop = i;
+ /* FALL THROUGH */
+ case ST_RD_PT_4:
+ ds->loop = lzh_read_pt_bitlen(strm, ds->loop,
+ ds->pt.len_avail);
+ if (ds->loop < ds->pt.len_avail) {
+ if (ds->loop < 0 || last)
+ goto failed;/* Invalid data. */
+ /* Not completed, get following data. */
+ ds->state = ST_RD_PT_4;
+ return (ARCHIVE_OK);
+ }
+ if (!lzh_make_huffman_table(&(ds->pt)))
+ goto failed;/* Invalid data */
+ if (ds->reading_position) {
+ ds->state = ST_GET_LITERAL;
+ break;
+ }
+ /* FALL THROUGH */
+ case ST_RD_LITERAL_1:
+ if (!lzh_br_read_ahead(strm, br, ds->lt.len_bits)) {
+ if (last)
+ goto failed;/* Truncated data. */
+ ds->state = ST_RD_LITERAL_1;
+ return (ARCHIVE_OK);
+ }
+ ds->lt.len_avail = lzh_br_bits(br, ds->lt.len_bits);
+ lzh_br_consume(br, ds->lt.len_bits);
+ /* FALL THROUGH */
+ case ST_RD_LITERAL_2:
+ if (ds->lt.len_avail == 0) {
+ /* There is no bitlen. */
+ if (!lzh_br_read_ahead(strm, br,
+ ds->lt.len_bits)) {
+ if (last)
+ goto failed;/* Truncated data.*/
+ ds->state = ST_RD_LITERAL_2;
+ return (ARCHIVE_OK);
+ }
+ if (!lzh_make_fake_table(&(ds->lt),
+ lzh_br_bits(br, ds->lt.len_bits)))
+ goto failed;/* Invalid data */
+ lzh_br_consume(br, ds->lt.len_bits);
+ ds->state = ST_RD_POS_DATA_1;
+ break;
+ } else if (ds->lt.len_avail > ds->lt.len_size)
+ goto failed;/* Invalid data */
+ ds->loop = 0;
+ memset(ds->lt.freq, 0, sizeof(ds->lt.freq));
+ /* FALL THROUGH */
+ case ST_RD_LITERAL_3:
+ i = ds->loop;
+ while (i < ds->lt.len_avail) {
+ if (!lzh_br_read_ahead(strm, br,
+ ds->pt.max_bits)) {
+ if (last)
+ goto failed;/* Truncated data.*/
+ ds->loop = i;
+ ds->state = ST_RD_LITERAL_3;
+ return (ARCHIVE_OK);
+ }
+ rbits = lzh_br_bits(br, ds->pt.max_bits);
+ c = lzh_decode_huffman(&(ds->pt), rbits);
+ if (c > 2) {
+ /* Note: 'c' will never be more than
+ * eighteen since it's limited by
+ * PT_BITLEN_SIZE, which is being set
+ * to ds->pt.len_size through
+ * ds->literal_pt_len_size. */
+ lzh_br_consume(br, ds->pt.bitlen[c]);
+ c -= 2;
+ ds->lt.freq[c]++;
+ ds->lt.bitlen[i++] = c;
+ } else if (c == 0) {
+ lzh_br_consume(br, ds->pt.bitlen[c]);
+ ds->lt.bitlen[i++] = 0;
+ } else {
+ /* c == 1 or c == 2 */
+ int n = (c == 1)?4:9;
+ if (!lzh_br_read_ahead(strm, br,
+ ds->pt.bitlen[c] + n)) {
+ if (last) /* Truncated data. */
+ goto failed;
+ ds->loop = i;
+ ds->state = ST_RD_LITERAL_3;
+ return (ARCHIVE_OK);
+ }
+ lzh_br_consume(br, ds->pt.bitlen[c]);
+ c = lzh_br_bits(br, n);
+ lzh_br_consume(br, n);
+ c += (n == 4)?3:20;
+ if (i + c > ds->lt.len_avail)
+ goto failed;/* Invalid data */
+ memset(&(ds->lt.bitlen[i]), 0, c);
+ i += c;
+ }
+ }
+ if (i > ds->lt.len_avail ||
+ !lzh_make_huffman_table(&(ds->lt)))
+ goto failed;/* Invalid data */
+ /* FALL THROUGH */
+ case ST_RD_POS_DATA_1:
+ /*
+ * Read a position table compressed in huffman
+ * coding.
+ */
+ ds->pt.len_size = ds->pos_pt_len_size;
+ ds->pt.len_bits = ds->pos_pt_len_bits;
+ ds->reading_position = 1;
+ ds->state = ST_RD_PT_1;
+ break;
+ case ST_GET_LITERAL:
+ return (100);
+ }
+ }
+failed:
+ return (ds->error = ARCHIVE_FAILED);
+}
+
+static int
+lzh_decode_blocks(struct lzh_stream *strm, int last)
+{
+ struct lzh_dec *ds = strm->ds;
+ struct lzh_br bre = ds->br;
+ struct huffman *lt = &(ds->lt);
+ struct huffman *pt = &(ds->pt);
+ unsigned char *w_buff = ds->w_buff;
+ unsigned char *lt_bitlen = lt->bitlen;
+ unsigned char *pt_bitlen = pt->bitlen;
+ int blocks_avail = ds->blocks_avail, c = 0;
+ int copy_len = ds->copy_len, copy_pos = ds->copy_pos;
+ int w_pos = ds->w_pos, w_mask = ds->w_mask, w_size = ds->w_size;
+ 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:
+ for (;;) {
+ if (blocks_avail == 0) {
+ /* We have decoded all blocks.
+ * Let's handle next blocks. */
+ ds->state = ST_RD_BLOCK;
+ ds->br = bre;
+ ds->blocks_avail = 0;
+ ds->w_pos = w_pos;
+ ds->copy_pos = 0;
+ return (100);
+ }
+
+ /* lzh_br_read_ahead() always try to fill the
+ * cache buffer up. In specific situation we
+ * are close to the end of the data, the cache
+ * buffer will not be full and thus we have to
+ * determine if the cache buffer has some bits
+ * as much as we need after lzh_br_read_ahead()
+ * failed. */
+ if (!lzh_br_read_ahead(strm, &bre,
+ lt_max_bits)) {
+ if (!last)
+ goto next_data;
+ /* Remaining bits are less than
+ * maximum bits(lt.max_bits) but maybe
+ * it still remains as much as we need,
+ * so we should try to use it with
+ * dummy bits. */
+ c = lzh_decode_huffman(lt,
+ lzh_br_bits_forced(&bre,
+ lt_max_bits));
+ lzh_br_consume(&bre, lt_bitlen[c]);
+ if (!lzh_br_has(&bre, 0))
+ goto failed;/* Over read. */
+ } else {
+ c = lzh_decode_huffman(lt,
+ lzh_br_bits(&bre, lt_max_bits));
+ lzh_br_consume(&bre, lt_bitlen[c]);
+ }
+ blocks_avail--;
+ if (c > UCHAR_MAX)
+ /* Current block is a match data. */
+ break;
+ /*
+ * 'c' is exactly a literal code.
+ */
+ /* Save a decoded code to reference it
+ * afterward. */
+ 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;
+ }
+ }
+ /* 'c' is the length of a match pattern we have
+ * already extracted, which has be stored in
+ * window(ds->w_buff). */
+ copy_len = c - (UCHAR_MAX + 1) + MINMATCH;
+ /* FALL THROUGH */
+ case ST_GET_POS_1:
+ /*
+ * Get a reference position.
+ */
+ if (!lzh_br_read_ahead(strm, &bre, pt_max_bits)) {
+ if (!last) {
+ state = ST_GET_POS_1;
+ ds->copy_len = copy_len;
+ goto next_data;
+ }
+ copy_pos = lzh_decode_huffman(pt,
+ lzh_br_bits_forced(&bre, pt_max_bits));
+ lzh_br_consume(&bre, pt_bitlen[copy_pos]);
+ if (!lzh_br_has(&bre, 0))
+ goto failed;/* Over read. */
+ } else {
+ copy_pos = lzh_decode_huffman(pt,
+ lzh_br_bits(&bre, pt_max_bits));
+ lzh_br_consume(&bre, pt_bitlen[copy_pos]);
+ }
+ /* FALL THROUGH */
+ case ST_GET_POS_2:
+ if (copy_pos > 1) {
+ /* We need an additional adjustment number to
+ * the position. */
+ int p = copy_pos - 1;
+ if (!lzh_br_read_ahead(strm, &bre, p)) {
+ if (last)
+ goto failed;/* Truncated data.*/
+ state = ST_GET_POS_2;
+ ds->copy_len = copy_len;
+ ds->copy_pos = copy_pos;
+ goto next_data;
+ }
+ copy_pos = (1 << p) + lzh_br_bits(&bre, p);
+ lzh_br_consume(&bre, p);
+ }
+ /* The position is actually a distance from the last
+ * code we had extracted and thus we have to convert
+ * it to a position of the window. */
+ copy_pos = (w_pos - copy_pos - 1) & w_mask;
+ /* FALL THROUGH */
+ case ST_COPY_DATA:
+ /*
+ * Copy `copy_len' bytes as extracted data from
+ * the window into the output buffer.
+ */
+ for (;;) {
+ int l;
+
+ l = copy_len;
+ if (copy_pos > w_pos) {
+ if (l > w_size - copy_pos)
+ l = w_size - copy_pos;
+ } else {
+ if (l > w_size - w_pos)
+ l = w_size - w_pos;
+ }
+ if ((copy_pos + l < w_pos)
+ || (w_pos + l < copy_pos)) {
+ /* No overlap. */
+ memcpy(w_buff + w_pos,
+ w_buff + copy_pos, l);
+ } else {
+ const unsigned char *s;
+ unsigned char *d;
+ int li;
+
+ d = w_buff + w_pos;
+ s = w_buff + copy_pos;
+ for (li = 0; li < l; li++)
+ 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;
+ }
+ }
+ if (copy_len <= l)
+ /* A copy of current pattern ended. */
+ break;
+ copy_len -= l;
+ copy_pos = (copy_pos + l) & w_mask;
+ }
+ state = ST_GET_LITERAL;
+ break;
+ }
+ }
+failed:
+ return (ds->error = ARCHIVE_FAILED);
+next_data:
+ ds->br = bre;
+ ds->blocks_avail = blocks_avail;
+ ds->state = state;
+ ds->w_pos = w_pos;
+ return (ARCHIVE_OK);
+}
+
+static int
+lzh_huffman_init(struct huffman *hf, size_t len_size, int tbl_bits)
+{
+ int bits;
+
+ if (hf->bitlen == NULL) {
+ hf->bitlen = malloc(len_size * sizeof(hf->bitlen[0]));
+ if (hf->bitlen == NULL)
+ return (ARCHIVE_FATAL);
+ }
+ if (hf->tbl == NULL) {
+ if (tbl_bits < HTBL_BITS)
+ bits = tbl_bits;
+ else
+ bits = HTBL_BITS;
+ hf->tbl = malloc((1 << bits) * sizeof(hf->tbl[0]));
+ if (hf->tbl == NULL)
+ return (ARCHIVE_FATAL);
+ }
+ if (hf->tree == NULL && tbl_bits > HTBL_BITS) {
+ hf->tree_avail = 1 << (tbl_bits - HTBL_BITS + 4);
+ hf->tree = malloc(hf->tree_avail * sizeof(hf->tree[0]));
+ if (hf->tree == NULL)
+ return (ARCHIVE_FATAL);
+ }
+ hf->len_size = len_size;
+ hf->tbl_bits = tbl_bits;
+ return (ARCHIVE_OK);
+}
+
+static void
+lzh_huffman_free(struct huffman *hf)
+{
+ free(hf->bitlen);
+ free(hf->tbl);
+ free(hf->tree);
+}
+
+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);
+ int c, i;
+
+ for (i = start; i < end;) {
+ /*
+ * bit pattern the number we need
+ * 000 -> 0
+ * 001 -> 1
+ * 010 -> 2
+ * ...
+ * 110 -> 6
+ * 1110 -> 7
+ * 11110 -> 8
+ * ...
+ * 1111111111110 -> 16
+ */
+ 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)
+ return (-1);/* Invalid data. */
+ lzh_br_consume(br, c - 3);
+ } else
+ lzh_br_consume(br, 3);
+ ds->pt.bitlen[i++] = c;
+ ds->pt.freq[c]++;
+ }
+ return (i);
+}
+
+static int
+lzh_make_fake_table(struct huffman *hf, uint16_t c)
+{
+ if (c >= hf->len_size)
+ return (0);
+ hf->tbl[0] = c;
+ hf->max_bits = 0;
+ hf->shift_bits = 0;
+ hf->bitlen[hf->tbl[0]] = 0;
+ return (1);
+}
+
+/*
+ * Make a huffman coding table.
+ */
+static int
+lzh_make_huffman_table(struct huffman *hf)
+{
+ uint16_t *tbl;
+ const unsigned char *bitlen;
+ int bitptn[17], weight[17];
+ int i, maxbits = 0, ptn, tbl_size, w;
+ int diffbits, len_avail;
+
+ /*
+ * Initialize bit patterns.
+ */
+ ptn = 0;
+ for (i = 1, w = 1 << 15; i <= 16; i++, w >>= 1) {
+ bitptn[i] = ptn;
+ weight[i] = w;
+ if (hf->freq[i]) {
+ ptn += hf->freq[i] * w;
+ maxbits = i;
+ }
+ }
+ if (ptn != 0x10000 || maxbits > hf->tbl_bits)
+ return (0);/* Invalid */
+
+ hf->max_bits = maxbits;
+
+ /*
+ * Cut out extra bits which we won't house in the table.
+ * This preparation reduces the same calculation in the for-loop
+ * making the table.
+ */
+ if (maxbits < 16) {
+ int ebits = 16 - maxbits;
+ for (i = 1; i <= maxbits; i++) {
+ bitptn[i] >>= ebits;
+ weight[i] >>= ebits;
+ }
+ }
+ if (maxbits > HTBL_BITS) {
+ int htbl_max;
+ uint16_t *p;
+
+ diffbits = maxbits - HTBL_BITS;
+ for (i = 1; i <= HTBL_BITS; i++) {
+ bitptn[i] >>= diffbits;
+ weight[i] >>= diffbits;
+ }
+ htbl_max = bitptn[HTBL_BITS] +
+ weight[HTBL_BITS] * hf->freq[HTBL_BITS];
+ p = &(hf->tbl[htbl_max]);
+ while (p < &hf->tbl[1U<<HTBL_BITS])
+ *p++ = 0;
+ } else
+ diffbits = 0;
+ hf->shift_bits = diffbits;
+
+ /*
+ * Make the table.
+ */
+ tbl_size = 1 << HTBL_BITS;
+ tbl = hf->tbl;
+ bitlen = hf->bitlen;
+ len_avail = hf->len_avail;
+ hf->tree_used = 0;
+ for (i = 0; i < len_avail; i++) {
+ uint16_t *p;
+ int len, cnt;
+ uint16_t bit;
+ int extlen;
+ struct htree_t *ht;
+
+ if (bitlen[i] == 0)
+ continue;
+ /* Get a bit pattern */
+ len = bitlen[i];
+ ptn = bitptn[len];
+ cnt = weight[len];
+ if (len <= HTBL_BITS) {
+ /* Calculate next bit pattern */
+ if ((bitptn[len] = ptn + cnt) > tbl_size)
+ return (0);/* Invalid */
+ /* Update the table */
+ p = &(tbl[ptn]);
+ while (--cnt >= 0)
+ p[cnt] = (uint16_t)i;
+ continue;
+ }
+
+ /*
+ * A bit length is too big to be housed to a direct table,
+ * so we use a tree model for its extra bits.
+ */
+ bitptn[len] = ptn + cnt;
+ bit = 1U << (diffbits -1);
+ extlen = len - HTBL_BITS;
+
+ p = &(tbl[ptn >> diffbits]);
+ if (*p == 0) {
+ *p = len_avail + hf->tree_used;
+ ht = &(hf->tree[hf->tree_used++]);
+ if (hf->tree_used > hf->tree_avail)
+ return (0);/* Invalid */
+ ht->left = 0;
+ ht->right = 0;
+ } else {
+ if (*p < len_avail ||
+ *p >= (len_avail + hf->tree_used))
+ return (0);/* Invalid */
+ ht = &(hf->tree[*p - len_avail]);
+ }
+ while (--extlen > 0) {
+ if (ptn & bit) {
+ if (ht->left < len_avail) {
+ ht->left = len_avail + hf->tree_used;
+ ht = &(hf->tree[hf->tree_used++]);
+ if (hf->tree_used > hf->tree_avail)
+ return (0);/* Invalid */
+ ht->left = 0;
+ ht->right = 0;
+ } else {
+ ht = &(hf->tree[ht->left - len_avail]);
+ }
+ } else {
+ if (ht->right < len_avail) {
+ ht->right = len_avail + hf->tree_used;
+ ht = &(hf->tree[hf->tree_used++]);
+ if (hf->tree_used > hf->tree_avail)
+ return (0);/* Invalid */
+ ht->left = 0;
+ ht->right = 0;
+ } else {
+ ht = &(hf->tree[ht->right - len_avail]);
+ }
+ }
+ bit >>= 1;
+ }
+ if (ptn & bit) {
+ if (ht->left != 0)
+ return (0);/* Invalid */
+ ht->left = (uint16_t)i;
+ } else {
+ if (ht->right != 0)
+ return (0);/* Invalid */
+ ht->right = (uint16_t)i;
+ }
+ }
+ return (1);
+}
+
+static int
+lzh_decode_huffman_tree(struct huffman *hf, unsigned rbits, int c)
+{
+ struct htree_t *ht;
+ int extlen;
+
+ ht = hf->tree;
+ extlen = hf->shift_bits;
+ while (c >= hf->len_avail) {
+ c -= hf->len_avail;
+ if (extlen-- <= 0 || c >= hf->tree_used)
+ return (0);
+ if (rbits & (1U << extlen))
+ c = ht[c].left;
+ else
+ c = ht[c].right;
+ }
+ return (c);
+}
+
+static inline int
+lzh_decode_huffman(struct huffman *hf, unsigned rbits)
+{
+ int c;
+ /*
+ * At first search an index table for a bit pattern.
+ * If it fails, search a huffman tree for.
+ */
+ c = hf->tbl[rbits >> hf->shift_bits];
+ if (c < hf->len_avail)
+ 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
new file mode 100644
index 000000000..6ac7db807
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c
@@ -0,0 +1,1744 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2008 Joerg Sonnenberger
+ * 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"
+__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_mtree.c 201165 2009-12-29 05:52:13Z kientzle $");
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#include <stddef.h>
+/* #include <stdint.h> */ /* See archive_platform.h */
+#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_string.h"
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+#define MTREE_HAS_DEVICE 0x0001
+#define MTREE_HAS_FFLAGS 0x0002
+#define MTREE_HAS_GID 0x0004
+#define MTREE_HAS_GNAME 0x0008
+#define MTREE_HAS_MTIME 0x0010
+#define MTREE_HAS_NLINK 0x0020
+#define MTREE_HAS_PERM 0x0040
+#define MTREE_HAS_SIZE 0x0080
+#define MTREE_HAS_TYPE 0x0100
+#define MTREE_HAS_UID 0x0200
+#define MTREE_HAS_UNAME 0x0400
+
+#define MTREE_HAS_OPTIONAL 0x0800
+
+struct mtree_option {
+ struct mtree_option *next;
+ char *value;
+};
+
+struct mtree_entry {
+ struct mtree_entry *next;
+ struct mtree_option *options;
+ char *name;
+ char full;
+ char used;
+};
+
+struct mtree {
+ struct archive_string line;
+ size_t buffsize;
+ char *buff;
+ int64_t offset;
+ int fd;
+ int archive_format;
+ const char *archive_format_name;
+ struct mtree_entry *entries;
+ struct mtree_entry *this_entry;
+ struct archive_string current_dir;
+ struct archive_string contents_name;
+
+ struct archive_entry_linkresolver *resolver;
+
+ int64_t cur_size;
+};
+
+static int cleanup(struct archive_read *);
+static int mtree_bid(struct archive_read *, int);
+static int parse_file(struct archive_read *, struct archive_entry *,
+ struct mtree *, struct mtree_entry *, int *);
+static void parse_escapes(char *, struct mtree_entry *);
+static int parse_line(struct archive_read *, struct archive_entry *,
+ struct mtree *, struct mtree_entry *, int *);
+static int parse_keyword(struct archive_read *, struct mtree *,
+ struct archive_entry *, struct mtree_option *, int *);
+static int read_data(struct archive_read *a,
+ const void **buff, size_t *size, int64_t *offset);
+static ssize_t readline(struct archive_read *, struct mtree *, char **, ssize_t);
+static int skip(struct archive_read *a);
+static int read_header(struct archive_read *,
+ struct archive_entry *);
+static int64_t mtree_atol10(char **);
+static int64_t mtree_atol8(char **);
+static int64_t mtree_atol(char **);
+
+/*
+ * There's no standard for TIME_T_MAX/TIME_T_MIN. So we compute them
+ * here. TODO: Move this to configure time, but be careful
+ * about cross-compile environments.
+ */
+static int64_t
+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;
+ }
+ }
+ return t;
+#endif
+}
+
+static int64_t
+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;
+ }
+ return t;
+#endif
+}
+
+static void
+free_options(struct mtree_option *head)
+{
+ struct mtree_option *next;
+
+ for (; head != NULL; head = next) {
+ next = head->next;
+ free(head->value);
+ free(head);
+ }
+}
+
+int
+archive_read_support_format_mtree(struct archive *_a)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ struct mtree *mtree;
+ int r;
+
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_mtree");
+
+ mtree = (struct mtree *)malloc(sizeof(*mtree));
+ if (mtree == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate mtree data");
+ return (ARCHIVE_FATAL);
+ }
+ memset(mtree, 0, sizeof(*mtree));
+ mtree->fd = -1;
+
+ r = __archive_read_register_format(a, mtree, "mtree",
+ mtree_bid, NULL, read_header, read_data, skip, cleanup);
+
+ if (r != ARCHIVE_OK)
+ free(mtree);
+ return (ARCHIVE_OK);
+}
+
+static int
+cleanup(struct archive_read *a)
+{
+ struct mtree *mtree;
+ struct mtree_entry *p, *q;
+
+ mtree = (struct mtree *)(a->format->data);
+
+ p = mtree->entries;
+ while (p != NULL) {
+ q = p->next;
+ free(p->name);
+ free_options(p->options);
+ free(p);
+ p = q;
+ }
+ archive_string_free(&mtree->line);
+ archive_string_free(&mtree->current_dir);
+ archive_string_free(&mtree->contents_name);
+ archive_entry_linkresolver_free(mtree->resolver);
+
+ free(mtree->buff);
+ free(mtree);
+ (a->format->data) = NULL;
+ return (ARCHIVE_OK);
+}
+
+static ssize_t
+get_line_size(const char *b, ssize_t avail, ssize_t *nlsize)
+{
+ ssize_t len;
+
+ len = 0;
+ while (len < avail) {
+ switch (*b) {
+ case '\0':/* Non-ascii character or control character. */
+ if (nlsize != NULL)
+ *nlsize = 0;
+ return (-1);
+ case '\r':
+ if (avail-len > 1 && b[1] == '\n') {
+ if (nlsize != NULL)
+ *nlsize = 2;
+ return (len+2);
+ }
+ /* FALL THROUGH */
+ case '\n':
+ if (nlsize != NULL)
+ *nlsize = 1;
+ return (len+1);
+ default:
+ b++;
+ len++;
+ break;
+ }
+ }
+ if (nlsize != NULL)
+ *nlsize = 0;
+ return (avail);
+}
+
+static ssize_t
+next_line(struct archive_read *a,
+ const char **b, ssize_t *avail, ssize_t *ravail, ssize_t *nl)
+{
+ ssize_t len;
+ int quit;
+
+ quit = 0;
+ if (*avail == 0) {
+ *nl = 0;
+ len = 0;
+ } else
+ len = get_line_size(*b, *avail, nl);
+ /*
+ * Read bytes more while it does not reach the end of line.
+ */
+ while (*nl == 0 && len == *avail && !quit) {
+ ssize_t diff = *ravail - *avail;
+ size_t nbytes_req = (*ravail+1023) & ~1023U;
+ ssize_t tested;
+
+ /* Increase reading bytes if it is not enough to at least
+ * new two lines. */
+ if (nbytes_req < (size_t)*ravail + 160)
+ nbytes_req <<= 1;
+
+ *b = __archive_read_ahead(a, nbytes_req, avail);
+ if (*b == NULL) {
+ if (*ravail >= *avail)
+ return (0);
+ /* Reading bytes reaches the end of file. */
+ *b = __archive_read_ahead(a, *avail, avail);
+ quit = 1;
+ }
+ *ravail = *avail;
+ *b += diff;
+ *avail -= diff;
+ tested = len;/* Skip some bytes we already determinated. */
+ len = get_line_size(*b, *avail, nl);
+ if (len >= 0)
+ len += tested;
+ }
+ return (len);
+}
+
+/*
+ * Compare characters with a mtree keyword.
+ * Returns the length of a mtree keyword if matched.
+ * Returns 0 if not matched.
+ */
+int
+bid_keycmp(const char *p, const char *key, ssize_t len)
+{
+ int match_len = 0;
+
+ while (len > 0 && *p && *key) {
+ if (*p == *key) {
+ --len;
+ ++p;
+ ++key;
+ ++match_len;
+ continue;
+ }
+ return (0);/* Not match */
+ }
+ if (*key != '\0')
+ return (0);/* Not match */
+
+ /* A following character should be specified characters */
+ if (p[0] == '=' || p[0] == ' ' || p[0] == '\t' ||
+ p[0] == '\n' || p[0] == '\r' ||
+ (p[0] == '\\' && (p[1] == '\n' || p[1] == '\r')))
+ return (match_len);
+ return (0);/* Not match */
+}
+
+/*
+ * Test whether the characters 'p' has is mtree keyword.
+ * Returns the length of a detected keyword.
+ * Returns 0 if any keywords were not found.
+ */
+static ssize_t
+bid_keyword(const char *p, ssize_t len)
+{
+ static const char *keys_c[] = {
+ "content", "contents", "cksum", NULL
+ };
+ static const char *keys_df[] = {
+ "device", "flags", NULL
+ };
+ static const char *keys_g[] = {
+ "gid", "gname", NULL
+ };
+ static const char *keys_il[] = {
+ "ignore", "link", NULL
+ };
+ static const char *keys_m[] = {
+ "md5", "md5digest", "mode", NULL
+ };
+ static const char *keys_no[] = {
+ "nlink", "optional", NULL
+ };
+ static const char *keys_r[] = {
+ "rmd160", "rmd160digest", NULL
+ };
+ static const char *keys_s[] = {
+ "sha1", "sha1digest",
+ "sha256", "sha256digest",
+ "sha384", "sha384digest",
+ "sha512", "sha512digest",
+ "size", NULL
+ };
+ static const char *keys_t[] = {
+ "tags", "time", "type", NULL
+ };
+ static const char *keys_u[] = {
+ "uid", "uname", NULL
+ };
+ const char **keys;
+ int i;
+
+ switch (*p) {
+ case 'c': keys = keys_c; break;
+ case 'd': case 'f': keys = keys_df; break;
+ case 'g': keys = keys_g; break;
+ case 'i': case 'l': keys = keys_il; break;
+ case 'm': keys = keys_m; break;
+ case 'n': case 'o': keys = keys_no; break;
+ case 'r': keys = keys_r; break;
+ case 's': keys = keys_s; break;
+ case 't': keys = keys_t; break;
+ case 'u': keys = keys_u; break;
+ default: return (0);/* Unknown key */
+ }
+
+ for (i = 0; keys[i] != NULL; i++) {
+ int l = bid_keycmp(p, keys[i], len);
+ if (l > 0)
+ return (l);
+ }
+ return (0);/* Unkown key */
+}
+
+/*
+ * Test whether there is a set of mtree keywords.
+ * Returns the number of keyword.
+ * Returns -1 if we got incorrect sequence.
+ * This function expects a set of "<space characters>keyword=value".
+ * When "unset" is specified, expects a set of "<space characters>keyword".
+ */
+static int
+bid_keyword_list(const char *p, ssize_t len, int unset)
+{
+ int l;
+ int keycnt = 0;
+
+ while (len > 0 && *p) {
+ int blank = 0;
+
+ /* Test whether there are blank characters in the line. */
+ while (len >0 && (*p == ' ' || *p == '\t')) {
+ ++p;
+ --len;
+ blank = 1;
+ }
+ if (*p == '\n' || *p == '\r')
+ break;
+ if (p[0] == '\\' && (p[1] == '\n' || p[1] == '\r'))
+ break;
+ if (!blank) /* No blank character. */
+ return (-1);
+
+ if (unset) {
+ l = bid_keycmp(p, "all", len);
+ if (l > 0)
+ return (1);
+ }
+ /* Test whether there is a correct key in the line. */
+ l = bid_keyword(p, len);
+ if (l == 0)
+ return (-1);/* Unknown keyword was found. */
+ p += l;
+ len -= l;
+ keycnt++;
+
+ /* Skip value */
+ if (*p == '=') {
+ int value = 0;
+ ++p;
+ --len;
+ while (len > 0 && *p != ' ' && *p != '\t') {
+ ++p;
+ --len;
+ value = 1;
+ }
+ /* A keyword should have a its value unless
+ * "/unset" operation. */
+ if (!unset && value == 0)
+ return (-1);
+ }
+ }
+ return (keycnt);
+}
+
+static int
+bid_entry(const char *p, ssize_t len)
+{
+ int f = 0;
+ static const unsigned char safe_char[256] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 00 - 0F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 - 1F */
+ /* !"$%&'()*+,-./ EXCLUSION:( )(#) */
+ 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 20 - 2F */
+ /* 0123456789:;<>? EXCLUSION:(=) */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, /* 30 - 3F */
+ /* @ABCDEFGHIJKLMNO */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 40 - 4F */
+ /* PQRSTUVWXYZ[\]^_ */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 50 - 5F */
+ /* `abcdefghijklmno */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 60 - 6F */
+ /* pqrstuvwxyz{|}~ */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* 70 - 7F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 - 8F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90 - 9F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A0 - AF */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* B0 - BF */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* C0 - CF */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* D0 - DF */
+ 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 */
+ };
+
+ /*
+ * Skip the path-name which is quoted.
+ */
+ while (len > 0 && *p != ' ' && *p != '\t') {
+ if (!safe_char[*(const unsigned char *)p])
+ return (-1);
+ ++p;
+ --len;
+ ++f;
+ }
+ /* If a path-name was not found, returns error. */
+ if (f == 0)
+ return (-1);
+
+ return (bid_keyword_list(p, len, 0));
+}
+
+#define MAX_BID_ENTRY 3
+
+static int
+mtree_bid(struct archive_read *a, int best_bid)
+{
+ const char *signature = "#mtree";
+ const char *p;
+ ssize_t avail, ravail;
+ ssize_t len, nl;
+ int detected_bytes = 0, entry_cnt = 0, multiline = 0;
+
+ (void)best_bid; /* UNUSED */
+
+ /* Now let's look at the actual header and see if it matches. */
+ p = __archive_read_ahead(a, strlen(signature), &avail);
+ if (p == NULL)
+ return (-1);
+
+ if (memcmp(p, signature, strlen(signature)) == 0)
+ return (8 * (int)strlen(signature));
+
+ /*
+ * There is not a mtree signature. Let's try to detect mtree format.
+ */
+ ravail = avail;
+ for (;;) {
+ len = next_line(a, &p, &avail, &ravail, &nl);
+ /* The terminal character of the line should be
+ * a new line character, '\r\n' or '\n'. */
+ if (len <= 0 || nl == 0)
+ break;
+ if (!multiline) {
+ /* Leading whitespace is never significant,
+ * ignore it. */
+ while (len > 0 && (*p == ' ' || *p == '\t')) {
+ ++p;
+ --avail;
+ --len;
+ }
+ /* Skip comment or empty line. */
+ if (p[0] == '#' || p[0] == '\n' || p[0] == '\r') {
+ p += len;
+ avail -= len;
+ continue;
+ }
+ } else {
+ /* A continuance line; the terminal
+ * character of previous line was '\' character. */
+ if (bid_keyword_list(p, len, 0) <= 0)
+ break;
+ if (multiline == 1)
+ detected_bytes += len;
+ if (p[len-nl-1] != '\\') {
+ if (multiline == 1 &&
+ ++entry_cnt >= MAX_BID_ENTRY)
+ break;
+ multiline = 0;
+ }
+ p += len;
+ avail -= len;
+ continue;
+ }
+ if (p[0] != '/') {
+ if (bid_entry(p, len) >= 0) {
+ detected_bytes += len;
+ if (p[len-nl-1] == '\\')
+ /* This line continues. */
+ multiline = 1;
+ else {
+ /* We've got plenty of correct lines
+ * to assume that this file is a mtree
+ * format. */
+ if (++entry_cnt >= MAX_BID_ENTRY)
+ break;
+ }
+ } else
+ break;
+ } else if (strncmp(p, "/set", 4) == 0) {
+ if (bid_keyword_list(p+4, len-4, 0) <= 0)
+ break;
+ /* This line continues. */
+ if (p[len-nl-1] == '\\')
+ multiline = 2;
+ } else if (strncmp(p, "/unset", 6) == 0) {
+ if (bid_keyword_list(p+6, len-6, 1) <= 0)
+ break;
+ /* This line continues. */
+ if (p[len-nl-1] == '\\')
+ multiline = 2;
+ } else
+ break;
+
+ /* Test next line. */
+ p += len;
+ avail -= len;
+ }
+ if (entry_cnt >= MAX_BID_ENTRY || (entry_cnt > 0 && len == 0))
+ return (32);
+
+ return (0);
+}
+
+/*
+ * The extended mtree format permits multiple lines specifying
+ * attributes for each file. For those entries, only the last line
+ * is actually used. Practically speaking, that means we have
+ * to read the entire mtree file into memory up front.
+ *
+ * The parsing is done in two steps. First, it is decided if a line
+ * changes the global defaults and if it is, processed accordingly.
+ * Otherwise, the options of the line are merged with the current
+ * global options.
+ */
+static int
+add_option(struct archive_read *a, struct mtree_option **global,
+ const char *value, size_t len)
+{
+ struct mtree_option *opt;
+
+ if ((opt = malloc(sizeof(*opt))) == NULL) {
+ archive_set_error(&a->archive, errno, "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+ if ((opt->value = malloc(len + 1)) == NULL) {
+ free(opt);
+ archive_set_error(&a->archive, errno, "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+ memcpy(opt->value, value, len);
+ opt->value[len] = '\0';
+ opt->next = *global;
+ *global = opt;
+ return (ARCHIVE_OK);
+}
+
+static void
+remove_option(struct mtree_option **global, const char *value, size_t len)
+{
+ struct mtree_option *iter, *last;
+
+ last = NULL;
+ for (iter = *global; iter != NULL; last = iter, iter = iter->next) {
+ if (strncmp(iter->value, value, len) == 0 &&
+ (iter->value[len] == '\0' ||
+ iter->value[len] == '='))
+ break;
+ }
+ if (iter == NULL)
+ return;
+ if (last == NULL)
+ *global = iter->next;
+ else
+ last->next = iter->next;
+
+ free(iter->value);
+ free(iter);
+}
+
+static int
+process_global_set(struct archive_read *a,
+ struct mtree_option **global, const char *line)
+{
+ const char *next, *eq;
+ size_t len;
+ int r;
+
+ line += 4;
+ for (;;) {
+ next = line + strspn(line, " \t\r\n");
+ if (*next == '\0')
+ return (ARCHIVE_OK);
+ line = next;
+ next = line + strcspn(line, " \t\r\n");
+ eq = strchr(line, '=');
+ if (eq > next)
+ len = next - line;
+ else
+ len = eq - line;
+
+ remove_option(global, line, len);
+ r = add_option(a, global, line, next - line);
+ if (r != ARCHIVE_OK)
+ return (r);
+ line = next;
+ }
+}
+
+static int
+process_global_unset(struct archive_read *a,
+ struct mtree_option **global, const char *line)
+{
+ const char *next;
+ size_t len;
+
+ line += 6;
+ if (strchr(line, '=') != NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "/unset shall not contain `='");
+ return ARCHIVE_FATAL;
+ }
+
+ for (;;) {
+ next = line + strspn(line, " \t\r\n");
+ if (*next == '\0')
+ return (ARCHIVE_OK);
+ line = next;
+ len = strcspn(line, " \t\r\n");
+
+ if (len == 3 && strncmp(line, "all", 3) == 0) {
+ free_options(*global);
+ *global = NULL;
+ } else {
+ remove_option(global, line, len);
+ }
+
+ line += len;
+ }
+}
+
+static int
+process_add_entry(struct archive_read *a, struct mtree *mtree,
+ struct mtree_option **global, const char *line,
+ struct mtree_entry **last_entry)
+{
+ struct mtree_entry *entry;
+ struct mtree_option *iter;
+ const char *next, *eq;
+ size_t len;
+ int r;
+
+ if ((entry = malloc(sizeof(*entry))) == NULL) {
+ archive_set_error(&a->archive, errno, "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+ entry->next = NULL;
+ entry->options = NULL;
+ entry->name = NULL;
+ entry->used = 0;
+ entry->full = 0;
+
+ /* Add this entry to list. */
+ if (*last_entry == NULL)
+ mtree->entries = entry;
+ else
+ (*last_entry)->next = entry;
+ *last_entry = entry;
+
+ len = strcspn(line, " \t\r\n");
+ if ((entry->name = malloc(len + 1)) == NULL) {
+ archive_set_error(&a->archive, errno, "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+
+ memcpy(entry->name, line, len);
+ entry->name[len] = '\0';
+ parse_escapes(entry->name, entry);
+
+ line += len;
+ for (iter = *global; iter != NULL; iter = iter->next) {
+ r = add_option(a, &entry->options, iter->value,
+ strlen(iter->value));
+ if (r != ARCHIVE_OK)
+ return (r);
+ }
+
+ for (;;) {
+ next = line + strspn(line, " \t\r\n");
+ if (*next == '\0')
+ return (ARCHIVE_OK);
+ line = next;
+ next = line + strcspn(line, " \t\r\n");
+ eq = strchr(line, '=');
+ if (eq == NULL || eq > next)
+ len = next - line;
+ else
+ len = eq - line;
+
+ remove_option(&entry->options, line, len);
+ r = add_option(a, &entry->options, line, next - line);
+ if (r != ARCHIVE_OK)
+ return (r);
+ line = next;
+ }
+}
+
+static int
+read_mtree(struct archive_read *a, struct mtree *mtree)
+{
+ ssize_t len;
+ uintmax_t counter;
+ char *p;
+ struct mtree_option *global;
+ struct mtree_entry *last_entry;
+ int r;
+
+ mtree->archive_format = ARCHIVE_FORMAT_MTREE;
+ mtree->archive_format_name = "mtree";
+
+ global = NULL;
+ last_entry = NULL;
+
+ for (counter = 1; ; ++counter) {
+ len = readline(a, mtree, &p, 65536);
+ if (len == 0) {
+ mtree->this_entry = mtree->entries;
+ free_options(global);
+ return (ARCHIVE_OK);
+ }
+ if (len < 0) {
+ free_options(global);
+ return (len);
+ }
+ /* Leading whitespace is never significant, ignore it. */
+ while (*p == ' ' || *p == '\t') {
+ ++p;
+ --len;
+ }
+ /* Skip content lines and blank lines. */
+ if (*p == '#')
+ continue;
+ if (*p == '\r' || *p == '\n' || *p == '\0')
+ continue;
+ if (*p != '/') {
+ r = process_add_entry(a, mtree, &global, p,
+ &last_entry);
+ } else if (strncmp(p, "/set", 4) == 0) {
+ if (p[4] != ' ' && p[4] != '\t')
+ break;
+ r = process_global_set(a, &global, p);
+ } else if (strncmp(p, "/unset", 6) == 0) {
+ if (p[6] != ' ' && p[6] != '\t')
+ break;
+ r = process_global_unset(a, &global, p);
+ } else
+ break;
+
+ if (r != ARCHIVE_OK) {
+ free_options(global);
+ return r;
+ }
+ }
+
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't parse line %ju", counter);
+ free_options(global);
+ return (ARCHIVE_FATAL);
+}
+
+/*
+ * Read in the entire mtree file into memory on the first request.
+ * Then use the next unused file to satisfy each header request.
+ */
+static int
+read_header(struct archive_read *a, struct archive_entry *entry)
+{
+ struct mtree *mtree;
+ char *p;
+ int r, use_next;
+
+ mtree = (struct mtree *)(a->format->data);
+
+ if (mtree->fd >= 0) {
+ close(mtree->fd);
+ mtree->fd = -1;
+ }
+
+ if (mtree->entries == NULL) {
+ mtree->resolver = archive_entry_linkresolver_new();
+ if (mtree->resolver == NULL)
+ return ARCHIVE_FATAL;
+ archive_entry_linkresolver_set_strategy(mtree->resolver,
+ ARCHIVE_FORMAT_MTREE);
+ r = read_mtree(a, mtree);
+ if (r != ARCHIVE_OK)
+ return (r);
+ }
+
+ a->archive.archive_format = mtree->archive_format;
+ a->archive.archive_format_name = mtree->archive_format_name;
+
+ for (;;) {
+ if (mtree->this_entry == NULL)
+ return (ARCHIVE_EOF);
+ if (strcmp(mtree->this_entry->name, "..") == 0) {
+ mtree->this_entry->used = 1;
+ if (archive_strlen(&mtree->current_dir) > 0) {
+ /* Roll back current path. */
+ p = mtree->current_dir.s
+ + mtree->current_dir.length - 1;
+ while (p >= mtree->current_dir.s && *p != '/')
+ --p;
+ if (p >= mtree->current_dir.s)
+ --p;
+ mtree->current_dir.length
+ = p - mtree->current_dir.s + 1;
+ }
+ }
+ if (!mtree->this_entry->used) {
+ use_next = 0;
+ r = parse_file(a, entry, mtree, mtree->this_entry, &use_next);
+ if (use_next == 0)
+ return (r);
+ }
+ mtree->this_entry = mtree->this_entry->next;
+ }
+}
+
+/*
+ * A single file can have multiple lines contribute specifications.
+ * Parse as many lines as necessary, then pull additional information
+ * from a backing file on disk as necessary.
+ */
+static int
+parse_file(struct archive_read *a, struct archive_entry *entry,
+ struct mtree *mtree, struct mtree_entry *mentry, int *use_next)
+{
+ const char *path;
+ struct stat st_storage, *st;
+ struct mtree_entry *mp;
+ struct archive_entry *sparse_entry;
+ int r = ARCHIVE_OK, r1, parsed_kws;
+
+ mentry->used = 1;
+
+ /* Initialize reasonable defaults. */
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_size(entry, 0);
+ archive_string_empty(&mtree->contents_name);
+
+ /* Parse options from this line. */
+ parsed_kws = 0;
+ r = parse_line(a, entry, mtree, mentry, &parsed_kws);
+
+ if (mentry->full) {
+ archive_entry_copy_pathname(entry, mentry->name);
+ /*
+ * "Full" entries are allowed to have multiple lines
+ * and those lines aren't required to be adjacent. We
+ * don't support multiple lines for "relative" entries
+ * nor do we make any attempt to merge data from
+ * separate "relative" and "full" entries. (Merging
+ * "relative" and "full" entries would require dealing
+ * with pathname canonicalization, which is a very
+ * tricky subject.)
+ */
+ for (mp = mentry->next; mp != NULL; mp = mp->next) {
+ if (mp->full && !mp->used
+ && strcmp(mentry->name, mp->name) == 0) {
+ /* Later lines override earlier ones. */
+ mp->used = 1;
+ r1 = parse_line(a, entry, mtree, mp,
+ &parsed_kws);
+ if (r1 < r)
+ r = r1;
+ }
+ }
+ } else {
+ /*
+ * Relative entries require us to construct
+ * the full path and possibly update the
+ * current directory.
+ */
+ size_t n = archive_strlen(&mtree->current_dir);
+ if (n > 0)
+ archive_strcat(&mtree->current_dir, "/");
+ archive_strcat(&mtree->current_dir, mentry->name);
+ archive_entry_copy_pathname(entry, mtree->current_dir.s);
+ if (archive_entry_filetype(entry) != AE_IFDIR)
+ 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);
+ 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 = 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)
+#ifdef S_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)
+#endif
+#ifdef S_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)
+#endif
+ || ((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)
+#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;
+ }
+ 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 &&
+ (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)
+ archive_entry_set_gid(entry, st->st_gid);
+ if ((parsed_kws & (MTREE_HAS_UID | MTREE_HAS_UNAME)) == 0)
+ archive_entry_set_uid(entry, st->st_uid);
+ if ((parsed_kws & MTREE_HAS_MTIME) == 0) {
+#if HAVE_STRUCT_STAT_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);
+#elif HAVE_STRUCT_STAT_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);
+#elif HAVE_STRUCT_STAT_ST_MTIME_USEC
+ archive_entry_set_mtime(entry, st->st_mtime,
+ st->st_mtime_usec*1000);
+#else
+ archive_entry_set_mtime(entry, st->st_mtime, 0);
+#endif
+ }
+ if ((parsed_kws & MTREE_HAS_NLINK) == 0)
+ archive_entry_set_nlink(entry, st->st_nlink);
+ if ((parsed_kws & MTREE_HAS_PERM) == 0)
+ archive_entry_set_perm(entry, st->st_mode);
+ if ((parsed_kws & MTREE_HAS_SIZE) == 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);
+ mtree->offset = 0;
+
+ return r;
+}
+
+/*
+ * Each line contains a sequence of keywords.
+ */
+static int
+parse_line(struct archive_read *a, struct archive_entry *entry,
+ struct mtree *mtree, struct mtree_entry *mp, int *parsed_kws)
+{
+ struct mtree_option *iter;
+ int r = ARCHIVE_OK, r1;
+
+ for (iter = mp->options; iter != NULL; iter = iter->next) {
+ r1 = parse_keyword(a, mtree, entry, iter, parsed_kws);
+ if (r1 < r)
+ r = r1;
+ }
+ if (r == ARCHIVE_OK && (*parsed_kws & MTREE_HAS_TYPE) == 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Missing type keyword in mtree specification");
+ return (ARCHIVE_WARN);
+ }
+ return (r);
+}
+
+/*
+ * 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.
+ */
+static int
+parse_device(struct archive *a, struct archive_entry *entry, char *val)
+{
+ char *comma1, *comma2;
+
+ comma1 = strchr(val, ',');
+ if (comma1 == NULL) {
+ archive_entry_set_dev(entry, 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);
+ }
+ ++comma2;
+ archive_entry_set_rdevmajor(entry, mtree_atol(&comma1));
+ archive_entry_set_rdevminor(entry, mtree_atol(&comma2));
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Parse a single keyword and its value.
+ */
+static int
+parse_keyword(struct archive_read *a, struct mtree *mtree,
+ struct archive_entry *entry, struct mtree_option *opt, int *parsed_kws)
+{
+ char *val, *key;
+
+ key = opt->value;
+
+ if (*key == '\0')
+ return (ARCHIVE_OK);
+
+ if (strcmp(key, "optional") == 0) {
+ *parsed_kws |= MTREE_HAS_OPTIONAL;
+ return (ARCHIVE_OK);
+ }
+ if (strcmp(key, "ignore") == 0) {
+ /*
+ * The mtree processing is not recursive, so
+ * recursion will only happen for explicitly listed
+ * entries.
+ */
+ return (ARCHIVE_OK);
+ }
+
+ val = strchr(key, '=');
+ if (val == NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Malformed attribute \"%s\" (%d)", key, key[0]);
+ return (ARCHIVE_WARN);
+ }
+
+ *val = '\0';
+ ++val;
+
+ switch (key[0]) {
+ case 'c':
+ if (strcmp(key, "content") == 0
+ || strcmp(key, "contents") == 0) {
+ parse_escapes(val, NULL);
+ archive_strcpy(&mtree->contents_name, val);
+ break;
+ }
+ if (strcmp(key, "cksum") == 0)
+ break;
+ case 'd':
+ if (strcmp(key, "device") == 0) {
+ *parsed_kws |= MTREE_HAS_DEVICE;
+ return parse_device(&a->archive, entry, val);
+ }
+ case 'f':
+ if (strcmp(key, "flags") == 0) {
+ *parsed_kws |= MTREE_HAS_FFLAGS;
+ archive_entry_copy_fflags_text(entry, val);
+ break;
+ }
+ case 'g':
+ if (strcmp(key, "gid") == 0) {
+ *parsed_kws |= MTREE_HAS_GID;
+ archive_entry_set_gid(entry, mtree_atol10(&val));
+ break;
+ }
+ if (strcmp(key, "gname") == 0) {
+ *parsed_kws |= MTREE_HAS_GNAME;
+ archive_entry_copy_gname(entry, val);
+ break;
+ }
+ case 'l':
+ if (strcmp(key, "link") == 0) {
+ archive_entry_copy_symlink(entry, val);
+ break;
+ }
+ case 'm':
+ if (strcmp(key, "md5") == 0 || strcmp(key, "md5digest") == 0)
+ break;
+ if (strcmp(key, "mode") == 0) {
+ if (val[0] >= '0' && val[0] <= '9') {
+ *parsed_kws |= MTREE_HAS_PERM;
+ archive_entry_set_perm(entry,
+ mtree_atol8(&val));
+ } else {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Symbolic mode \"%s\" unsupported", val);
+ return ARCHIVE_WARN;
+ }
+ break;
+ }
+ case 'n':
+ if (strcmp(key, "nlink") == 0) {
+ *parsed_kws |= MTREE_HAS_NLINK;
+ archive_entry_set_nlink(entry, mtree_atol10(&val));
+ break;
+ }
+ case 'r':
+ if (strcmp(key, "rmd160") == 0 ||
+ strcmp(key, "rmd160digest") == 0)
+ break;
+ case 's':
+ if (strcmp(key, "sha1") == 0 || strcmp(key, "sha1digest") == 0)
+ break;
+ if (strcmp(key, "sha256") == 0 ||
+ strcmp(key, "sha256digest") == 0)
+ break;
+ if (strcmp(key, "sha384") == 0 ||
+ strcmp(key, "sha384digest") == 0)
+ break;
+ if (strcmp(key, "sha512") == 0 ||
+ strcmp(key, "sha512digest") == 0)
+ break;
+ if (strcmp(key, "size") == 0) {
+ archive_entry_set_size(entry, mtree_atol10(&val));
+ break;
+ }
+ case 't':
+ if (strcmp(key, "tags") == 0) {
+ /*
+ * Comma delimited list of tags.
+ * Ignore the tags for now, but the interface
+ * should be extended to allow inclusion/exclusion.
+ */
+ break;
+ }
+ if (strcmp(key, "time") == 0) {
+ int64_t m;
+ int64_t my_time_t_max = get_time_t_max();
+ int64_t my_time_t_min = get_time_t_min();
+ long ns;
+
+ *parsed_kws |= MTREE_HAS_MTIME;
+ m = mtree_atol10(&val);
+ /* Replicate an old mtree bug:
+ * 123456789.1 represents 123456789
+ * seconds and 1 nanosecond. */
+ if (*val == '.') {
+ ++val;
+ ns = (long)mtree_atol10(&val);
+ } else
+ ns = 0;
+ if (m > my_time_t_max)
+ m = my_time_t_max;
+ else if (m < my_time_t_min)
+ m = my_time_t_min;
+ archive_entry_set_mtime(entry, (time_t)m, ns);
+ break;
+ }
+ if (strcmp(key, "type") == 0) {
+ switch (val[0]) {
+ case 'b':
+ if (strcmp(val, "block") == 0) {
+ archive_entry_set_filetype(entry, AE_IFBLK);
+ break;
+ }
+ case 'c':
+ if (strcmp(val, "char") == 0) {
+ archive_entry_set_filetype(entry, AE_IFCHR);
+ break;
+ }
+ case 'd':
+ if (strcmp(val, "dir") == 0) {
+ archive_entry_set_filetype(entry, AE_IFDIR);
+ break;
+ }
+ case 'f':
+ if (strcmp(val, "fifo") == 0) {
+ archive_entry_set_filetype(entry, AE_IFIFO);
+ break;
+ }
+ if (strcmp(val, "file") == 0) {
+ archive_entry_set_filetype(entry, AE_IFREG);
+ break;
+ }
+ case 'l':
+ if (strcmp(val, "link") == 0) {
+ 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);
+ archive_entry_set_filetype(entry, AE_IFREG);
+ return (ARCHIVE_WARN);
+ }
+ *parsed_kws |= MTREE_HAS_TYPE;
+ break;
+ }
+ case 'u':
+ if (strcmp(key, "uid") == 0) {
+ *parsed_kws |= MTREE_HAS_UID;
+ archive_entry_set_uid(entry, mtree_atol10(&val));
+ break;
+ }
+ if (strcmp(key, "uname") == 0) {
+ *parsed_kws |= MTREE_HAS_UNAME;
+ archive_entry_copy_uname(entry, val);
+ break;
+ }
+ default:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Unrecognized key %s=%s", key, val);
+ return (ARCHIVE_WARN);
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+read_data(struct archive_read *a, const void **buff, size_t *size, int64_t *offset)
+{
+ size_t bytes_to_read;
+ ssize_t bytes_read;
+ struct mtree *mtree;
+
+ mtree = (struct mtree *)(a->format->data);
+ if (mtree->fd < 0) {
+ *buff = NULL;
+ *offset = 0;
+ *size = 0;
+ return (ARCHIVE_EOF);
+ }
+ if (mtree->buff == NULL) {
+ mtree->buffsize = 64 * 1024;
+ mtree->buff = malloc(mtree->buffsize);
+ if (mtree->buff == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ *buff = mtree->buff;
+ *offset = mtree->offset;
+ if ((int64_t)mtree->buffsize > mtree->cur_size - mtree->offset)
+ bytes_to_read = mtree->cur_size - mtree->offset;
+ else
+ bytes_to_read = mtree->buffsize;
+ bytes_read = read(mtree->fd, mtree->buff, bytes_to_read);
+ if (bytes_read < 0) {
+ archive_set_error(&a->archive, errno, "Can't read");
+ return (ARCHIVE_WARN);
+ }
+ if (bytes_read == 0) {
+ *size = 0;
+ return (ARCHIVE_EOF);
+ }
+ mtree->offset += bytes_read;
+ *size = bytes_read;
+ return (ARCHIVE_OK);
+}
+
+/* Skip does nothing except possibly close the contents file. */
+static int
+skip(struct archive_read *a)
+{
+ struct mtree *mtree;
+
+ mtree = (struct mtree *)(a->format->data);
+ if (mtree->fd >= 0) {
+ close(mtree->fd);
+ mtree->fd = -1;
+ }
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Since parsing backslash sequences always makes strings shorter,
+ * we can always do this conversion in-place.
+ */
+static void
+parse_escapes(char *src, struct mtree_entry *mentry)
+{
+ char *dest = src;
+ char c;
+
+ if (mentry != NULL && strcmp(src, ".") == 0)
+ mentry->full = 1;
+
+ while (*src != '\0') {
+ c = *src++;
+ if (c == '/' && mentry != NULL)
+ mentry->full = 1;
+ if (c == '\\') {
+ switch (src[0]) {
+ case '0':
+ if (src[1] < '0' || src[1] > '7') {
+ c = 0;
+ ++src;
+ break;
+ }
+ /* FALLTHROUGH */
+ case '1':
+ case '2':
+ case '3':
+ if (src[1] >= '0' && src[1] <= '7' &&
+ src[2] >= '0' && src[2] <= '7') {
+ c = (src[0] - '0') << 6;
+ c |= (src[1] - '0') << 3;
+ c |= (src[2] - '0');
+ src += 3;
+ }
+ break;
+ case 'a':
+ c = '\a';
+ ++src;
+ break;
+ case 'b':
+ c = '\b';
+ ++src;
+ break;
+ case 'f':
+ c = '\f';
+ ++src;
+ break;
+ case 'n':
+ c = '\n';
+ ++src;
+ break;
+ case 'r':
+ c = '\r';
+ ++src;
+ break;
+ case 's':
+ c = ' ';
+ ++src;
+ break;
+ case 't':
+ c = '\t';
+ ++src;
+ break;
+ case 'v':
+ c = '\v';
+ ++src;
+ break;
+ }
+ }
+ *dest++ = c;
+ }
+ *dest = '\0';
+}
+
+/*
+ * Note that this implementation does not (and should not!) obey
+ * locale settings; you cannot simply substitute strtol here, since
+ * it does obey locale.
+ */
+static int64_t
+mtree_atol8(char **p)
+{
+ int64_t l, limit, last_digit_limit;
+ int digit, base;
+
+ base = 8;
+ limit = INT64_MAX / base;
+ last_digit_limit = INT64_MAX % base;
+
+ l = 0;
+ digit = **p - '0';
+ while (digit >= 0 && digit < base) {
+ if (l>limit || (l == limit && digit > last_digit_limit)) {
+ l = INT64_MAX; /* Truncate on overflow. */
+ break;
+ }
+ l = (l * base) + digit;
+ digit = *++(*p) - '0';
+ }
+ return (l);
+}
+
+/*
+ * Note that this implementation does not (and should not!) obey
+ * locale settings; you cannot simply substitute strtol here, since
+ * it does obey locale.
+ */
+static int64_t
+mtree_atol10(char **p)
+{
+ int64_t l, limit, last_digit_limit;
+ int base, digit, sign;
+
+ base = 10;
+
+ if (**p == '-') {
+ sign = -1;
+ limit = ((uint64_t)(INT64_MAX) + 1) / base;
+ last_digit_limit = ((uint64_t)(INT64_MAX) + 1) % base;
+ ++(*p);
+ } else {
+ sign = 1;
+ limit = INT64_MAX / base;
+ last_digit_limit = INT64_MAX % base;
+ }
+
+ l = 0;
+ digit = **p - '0';
+ while (digit >= 0 && digit < base) {
+ if (l > limit || (l == limit && digit > last_digit_limit))
+ return (sign < 0) ? INT64_MIN : INT64_MAX;
+ l = (l * base) + digit;
+ digit = *++(*p) - '0';
+ }
+ return (sign < 0) ? -l : l;
+}
+
+/* Parse a hex digit. */
+static int
+parsehex(char c)
+{
+ if (c >= '0' && c <= '9')
+ return c - '0';
+ else if (c >= 'a' && c <= 'f')
+ return c - 'a';
+ else if (c >= 'A' && c <= 'F')
+ return c - 'A';
+ else
+ return -1;
+}
+
+/*
+ * Note that this implementation does not (and should not!) obey
+ * locale settings; you cannot simply substitute strtol here, since
+ * it does obey locale.
+ */
+static int64_t
+mtree_atol16(char **p)
+{
+ int64_t l, limit, last_digit_limit;
+ int base, digit, sign;
+
+ base = 16;
+
+ if (**p == '-') {
+ sign = -1;
+ limit = ((uint64_t)(INT64_MAX) + 1) / base;
+ last_digit_limit = ((uint64_t)(INT64_MAX) + 1) % base;
+ ++(*p);
+ } else {
+ sign = 1;
+ limit = INT64_MAX / base;
+ last_digit_limit = INT64_MAX % base;
+ }
+
+ l = 0;
+ digit = parsehex(**p);
+ while (digit >= 0 && digit < base) {
+ if (l > limit || (l == limit && digit > last_digit_limit))
+ return (sign < 0) ? INT64_MIN : INT64_MAX;
+ l = (l * base) + digit;
+ digit = parsehex(*++(*p));
+ }
+ return (sign < 0) ? -l : l;
+}
+
+static int64_t
+mtree_atol(char **p)
+{
+ if (**p != '0')
+ return mtree_atol10(p);
+ if ((*p)[1] == 'x' || (*p)[1] == 'X') {
+ *p += 2;
+ return mtree_atol16(p);
+ }
+ return mtree_atol8(p);
+}
+
+/*
+ * Returns length of line (including trailing newline)
+ * or negative on error. 'start' argument is updated to
+ * point to first character of line.
+ */
+static ssize_t
+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;
+ char *u;
+
+ /* Accumulate line in a line buffer. */
+ for (;;) {
+ /* Read some more. */
+ t = __archive_read_ahead(a, 1, &bytes_read);
+ if (t == NULL)
+ 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;
+ }
+ if (total_size + bytes_read + 1 > limit) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Line too long");
+ return (ARCHIVE_FATAL);
+ }
+ if (archive_string_ensure(&mtree->line,
+ total_size + bytes_read + 1) == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate working buffer");
+ return (ARCHIVE_FATAL);
+ }
+ 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') {
+ *start = mtree->line.s;
+ return total_size;
+ }
+ if (u[0] == '#') {
+ if (p == NULL)
+ 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;
+ }
+ 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
new file mode 100644
index 000000000..d5a8d86ee
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c
@@ -0,0 +1,2574 @@
+/*-
+* 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.
+*/
+
+#include "archive_platform.h"
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include <time.h>
+#include <limits.h>
+#ifdef HAVE_ZLIB_H
+#include <cm_zlib.h> /* crc32 */
+#endif
+
+#include "archive.h"
+#ifndef HAVE_ZLIB_H
+#include "archive_crc32.h"
+#endif
+#include "archive_endian.h"
+#include "archive_entry.h"
+#include "archive_entry_locale.h"
+#include "archive_ppmd7_private.h"
+#include "archive_private.h"
+#include "archive_read_private.h"
+
+/* RAR signature, also known as the mark header */
+#define RAR_SIGNATURE "\x52\x61\x72\x21\x1A\x07\x00"
+
+/* Header types */
+#define MARK_HEAD 0x72
+#define MAIN_HEAD 0x73
+#define FILE_HEAD 0x74
+#define COMM_HEAD 0x75
+#define AV_HEAD 0x76
+#define SUB_HEAD 0x77
+#define PROTECT_HEAD 0x78
+#define SIGN_HEAD 0x79
+#define NEWSUB_HEAD 0x7a
+#define ENDARC_HEAD 0x7b
+
+/* Main Header Flags */
+#define MHD_VOLUME 0x0001
+#define MHD_COMMENT 0x0002
+#define MHD_LOCK 0x0004
+#define MHD_SOLID 0x0008
+#define MHD_NEWNUMBERING 0x0010
+#define MHD_AV 0x0020
+#define MHD_PROTECT 0x0040
+#define MHD_PASSWORD 0x0080
+#define MHD_FIRSTVOLUME 0x0100
+#define MHD_ENCRYPTVER 0x0200
+
+/* Flags common to all headers */
+#define HD_MARKDELETION 0x4000
+#define HD_ADD_SIZE_PRESENT 0x8000
+
+/* File Header Flags */
+#define FHD_SPLIT_BEFORE 0x0001
+#define FHD_SPLIT_AFTER 0x0002
+#define FHD_PASSWORD 0x0004
+#define FHD_COMMENT 0x0008
+#define FHD_SOLID 0x0010
+#define FHD_LARGE 0x0100
+#define FHD_UNICODE 0x0200
+#define FHD_SALT 0x0400
+#define FHD_VERSION 0x0800
+#define FHD_EXTTIME 0x1000
+#define FHD_EXTFLAGS 0x2000
+
+/* File dictionary sizes */
+#define DICTIONARY_SIZE_64 0x00
+#define DICTIONARY_SIZE_128 0x20
+#define DICTIONARY_SIZE_256 0x40
+#define DICTIONARY_SIZE_512 0x60
+#define DICTIONARY_SIZE_1024 0x80
+#define DICTIONARY_SIZE_2048 0xA0
+#define DICTIONARY_SIZE_4096 0xC0
+#define FILE_IS_DIRECTORY 0xE0
+#define DICTIONARY_MASK FILE_IS_DIRECTORY
+
+/* OS Flags */
+#define OS_MSDOS 0
+#define OS_OS2 1
+#define OS_WIN32 2
+#define OS_UNIX 3
+#define OS_MAC_OS 4
+#define OS_BEOS 5
+
+/* Compression Methods */
+#define COMPRESS_METHOD_STORE 0x30
+/* LZSS */
+#define COMPRESS_METHOD_FASTEST 0x31
+#define COMPRESS_METHOD_FAST 0x32
+#define COMPRESS_METHOD_NORMAL 0x33
+/* PPMd Variant H */
+#define COMPRESS_METHOD_GOOD 0x34
+#define COMPRESS_METHOD_BEST 0x35
+
+#define CRC_POLYNOMIAL 0xEDB88320
+
+#define NS_UNIT 10000000
+
+#define DICTIONARY_MAX_SIZE 0x400000
+
+#define MAINCODE_SIZE 299
+#define OFFSETCODE_SIZE 60
+#define LOWOFFSETCODE_SIZE 17
+#define LENGTHCODE_SIZE 28
+#define HUFFMAN_TABLE_SIZE \
+ MAINCODE_SIZE + OFFSETCODE_SIZE + LOWOFFSETCODE_SIZE + LENGTHCODE_SIZE
+
+#define MAX_SYMBOL_LENGTH 0xF
+#define MAX_SYMBOLS 20
+
+/*
+ * Considering L1,L2 cache miss and a calling of write sytem-call,
+ * the best size of the output buffer(uncompressed buffer) is 128K.
+ * If the structure of extracting process is changed, this value
+ * might be researched again.
+ */
+#define UNP_BUFFER_SIZE (128 * 1024)
+
+/* Define this here for non-Windows platforms */
+#if !((defined(__WIN32__) || defined(_WIN32) || defined(__WIN32)) && !defined(__CYGWIN__))
+#define FILE_ATTRIBUTE_DIRECTORY 0x10
+#endif
+
+/* Fields common to all headers */
+struct rar_header
+{
+ char crc[2];
+ char type;
+ char flags[2];
+ char size[2];
+};
+
+/* Fields common to all file headers */
+struct rar_file_header
+{
+ char pack_size[4];
+ char unp_size[4];
+ char host_os;
+ char file_crc[4];
+ char file_time[4];
+ char unp_ver;
+ char method;
+ char name_size[2];
+ char file_attr[4];
+};
+
+struct huffman_tree_node
+{
+ int branches[2];
+};
+
+struct huffman_table_entry
+{
+ unsigned int length;
+ int value;
+};
+
+struct huffman_code
+{
+ struct huffman_tree_node *tree;
+ int numentries;
+ int minlength;
+ int maxlength;
+ int tablesize;
+ struct huffman_table_entry *table;
+};
+
+struct lzss
+{
+ unsigned char *window;
+ int mask;
+ int64_t position;
+};
+
+struct rar
+{
+ /* Entries from main RAR header */
+ unsigned main_flags;
+ unsigned long file_crc;
+ char reserved1[2];
+ char reserved2[4];
+ char encryptver;
+
+ /* File header entries */
+ char compression_method;
+ unsigned file_flags;
+ int64_t packed_size;
+ int64_t unp_size;
+ time_t mtime;
+ long mnsec;
+ mode_t mode;
+ char *filename;
+ size_t filename_allocated;
+
+ /* File header optional entries */
+ char salt[8];
+ time_t atime;
+ long ansec;
+ time_t ctime;
+ long cnsec;
+ time_t arctime;
+ long arcnsec;
+
+ /* Fields to help with tracking decompression of files. */
+ int64_t bytes_unconsumed;
+ int64_t bytes_remaining;
+ int64_t bytes_uncopied;
+ int64_t offset;
+ int64_t offset_outgoing;
+ char valid;
+ unsigned int unp_offset;
+ unsigned int unp_buffer_size;
+ unsigned char *unp_buffer;
+ unsigned int dictionary_size;
+ char start_new_block;
+ char entry_eof;
+ unsigned long crc_calculated;
+ int found_first_header;
+
+ /* LZSS members */
+ struct huffman_code maincode;
+ struct huffman_code offsetcode;
+ struct huffman_code lowoffsetcode;
+ struct huffman_code lengthcode;
+ unsigned char lengthtable[HUFFMAN_TABLE_SIZE];
+ struct lzss lzss;
+ char output_last_match;
+ unsigned int lastlength;
+ unsigned int lastoffset;
+ unsigned int oldoffset[4];
+ unsigned int lastlowoffset;
+ unsigned int numlowoffsetrepeats;
+ int64_t filterstart;
+ char start_new_table;
+
+ /* PPMd Variant H members */
+ char ppmd_valid;
+ char ppmd_eod;
+ char is_ppmd_block;
+ int ppmd_escape;
+ CPpmd7 ppmd7_context;
+ CPpmd7z_RangeDec range_dec;
+ IByteIn bytein;
+
+ /*
+ * String conversion object.
+ */
+ int init_default_conversion;
+ struct archive_string_conv *sconv_default;
+ struct archive_string_conv *opt_sconv;
+ struct archive_string_conv *sconv_utf8;
+ struct archive_string_conv *sconv_utf16be;
+
+ /*
+ * Bit stream reader.
+ */
+ struct rar_br {
+#define CACHE_TYPE uint64_t
+#define CACHE_BITS (8 * sizeof(CACHE_TYPE))
+ /* Cache buffer. */
+ CACHE_TYPE cache_buffer;
+ /* Indicates how many bits avail in cache_buffer. */
+ int cache_avail;
+ ssize_t avail_in;
+ const unsigned char *next_in;
+ } br;
+};
+
+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 *);
+static int archive_read_format_rar_read_header(struct archive_read *,
+ struct archive_entry *);
+static int archive_read_format_rar_read_data(struct archive_read *,
+ const void **, size_t *, int64_t *);
+static int archive_read_format_rar_read_data_skip(struct archive_read *a);
+static int archive_read_format_rar_cleanup(struct archive_read *);
+
+/* Support functions */
+static int read_header(struct archive_read *, struct archive_entry *, char);
+static time_t get_time(int time);
+static int read_exttime(const char *, struct rar *, const char *);
+static int read_symlink_stored(struct archive_read *, struct archive_entry *,
+ struct archive_string_conv *);
+static int read_data_stored(struct archive_read *, const void **, size_t *,
+ int64_t *);
+static int read_data_compressed(struct archive_read *, const void **, size_t *,
+ int64_t *);
+static int rar_br_preparation(struct archive_read *, struct rar_br *);
+static int parse_codes(struct archive_read *);
+static void free_codes(struct archive_read *);
+static int read_next_symbol(struct archive_read *, struct huffman_code *);
+static int create_code(struct archive_read *, struct huffman_code *,
+ unsigned char *, int, char);
+static int add_value(struct archive_read *, struct huffman_code *, int, int,
+ int);
+static int new_node(struct huffman_code *);
+static int make_table(struct archive_read *, struct huffman_code *);
+static int make_table_recurse(struct archive_read *, struct huffman_code *, int,
+ struct huffman_table_entry *, int, int);
+static int64_t expand(struct archive_read *, int64_t);
+static int copy_from_lzss_window(struct archive_read *, const void **,
+ int64_t, int);
+
+/*
+ * Bit stream reader.
+ */
+/* Check that the cache buffer has enough bits. */
+#define rar_br_has(br, n) ((br)->cache_avail >= n)
+/* Get compressed data by bit. */
+#define rar_br_bits(br, n) \
+ (((uint32_t)((br)->cache_buffer >> \
+ ((br)->cache_avail - (n)))) & cache_masks[n])
+#define rar_br_bits_forced(br, n) \
+ (((uint32_t)((br)->cache_buffer << \
+ ((n) - (br)->cache_avail))) & cache_masks[n])
+/* Read ahead to make sure the cache buffer has enough compressed data we
+ * will use.
+ * True : completed, there is enough data in the cache buffer.
+ * False : there is no data in the stream. */
+#define rar_br_read_ahead(a, br, n) \
+ ((rar_br_has(br, (n)) || rar_br_fillup(a, br)) || rar_br_has(br, (n)))
+/* Notify how many bits we consumed. */
+#define rar_br_consume(br, n) ((br)->cache_avail -= (n))
+#define rar_br_consume_unalined_bits(br) ((br)->cache_avail &= ~7)
+
+static const uint32_t cache_masks[] = {
+ 0x00000000, 0x00000001, 0x00000003, 0x00000007,
+ 0x0000000F, 0x0000001F, 0x0000003F, 0x0000007F,
+ 0x000000FF, 0x000001FF, 0x000003FF, 0x000007FF,
+ 0x00000FFF, 0x00001FFF, 0x00003FFF, 0x00007FFF,
+ 0x0000FFFF, 0x0001FFFF, 0x0003FFFF, 0x0007FFFF,
+ 0x000FFFFF, 0x001FFFFF, 0x003FFFFF, 0x007FFFFF,
+ 0x00FFFFFF, 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF,
+ 0x0FFFFFFF, 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
+};
+
+/*
+ * Shift away used bits in the cache data and fill it up with following bits.
+ * Call this when cache buffer does not have enough bits you need.
+ *
+ * Returns 1 if the cache buffer is full.
+ * Returns 0 if the cache buffer is not full; input buffer is empty.
+ */
+static int
+rar_br_fillup(struct archive_read *a, struct rar_br *br)
+{
+ struct rar *rar = (struct rar *)(a->format->data);
+ int n = CACHE_BITS - br->cache_avail;
+
+ for (;;) {
+ switch (n >> 3) {
+ case 8:
+ if (br->avail_in >= 8) {
+ br->cache_buffer =
+ ((uint64_t)br->next_in[0]) << 56 |
+ ((uint64_t)br->next_in[1]) << 48 |
+ ((uint64_t)br->next_in[2]) << 40 |
+ ((uint64_t)br->next_in[3]) << 32 |
+ ((uint32_t)br->next_in[4]) << 24 |
+ ((uint32_t)br->next_in[5]) << 16 |
+ ((uint32_t)br->next_in[6]) << 8 |
+ (uint32_t)br->next_in[7];
+ br->next_in += 8;
+ br->avail_in -= 8;
+ br->cache_avail += 8 * 8;
+ rar->bytes_unconsumed += 8;
+ rar->bytes_remaining -= 8;
+ return (1);
+ }
+ break;
+ case 7:
+ if (br->avail_in >= 7) {
+ br->cache_buffer =
+ (br->cache_buffer << 56) |
+ ((uint64_t)br->next_in[0]) << 48 |
+ ((uint64_t)br->next_in[1]) << 40 |
+ ((uint64_t)br->next_in[2]) << 32 |
+ ((uint32_t)br->next_in[3]) << 24 |
+ ((uint32_t)br->next_in[4]) << 16 |
+ ((uint32_t)br->next_in[5]) << 8 |
+ (uint32_t)br->next_in[6];
+ br->next_in += 7;
+ br->avail_in -= 7;
+ br->cache_avail += 7 * 8;
+ rar->bytes_unconsumed += 7;
+ rar->bytes_remaining -= 7;
+ return (1);
+ }
+ break;
+ case 6:
+ if (br->avail_in >= 6) {
+ br->cache_buffer =
+ (br->cache_buffer << 48) |
+ ((uint64_t)br->next_in[0]) << 40 |
+ ((uint64_t)br->next_in[1]) << 32 |
+ ((uint32_t)br->next_in[2]) << 24 |
+ ((uint32_t)br->next_in[3]) << 16 |
+ ((uint32_t)br->next_in[4]) << 8 |
+ (uint32_t)br->next_in[5];
+ br->next_in += 6;
+ br->avail_in -= 6;
+ br->cache_avail += 6 * 8;
+ rar->bytes_unconsumed += 6;
+ rar->bytes_remaining -= 6;
+ return (1);
+ }
+ break;
+ case 0:
+ /* We have enough compressed data in
+ * the cache buffer.*/
+ return (1);
+ default:
+ break;
+ }
+ if (br->avail_in <= 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;
+ }
+ br->next_in = __archive_read_ahead(a, 1, &(br->avail_in));
+ if (br->next_in == NULL)
+ return (0);
+ if (br->avail_in > rar->bytes_remaining)
+ br->avail_in = rar->bytes_remaining;
+ if (br->avail_in == 0)
+ return (0);
+ }
+ br->cache_buffer =
+ (br->cache_buffer << 8) | *br->next_in++;
+ br->avail_in--;
+ br->cache_avail += 8;
+ n -= 8;
+ rar->bytes_unconsumed++;
+ rar->bytes_remaining--;
+ }
+}
+
+static int
+rar_br_preparation(struct archive_read *a, struct rar_br *br)
+{
+ struct rar *rar = (struct rar *)(a->format->data);
+
+ if (rar->bytes_remaining > 0) {
+ br->next_in = __archive_read_ahead(a, 1, &(br->avail_in));
+ if (br->next_in == NULL) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated RAR file data");
+ return (ARCHIVE_FATAL);
+ }
+ if (br->avail_in > rar->bytes_remaining)
+ br->avail_in = rar->bytes_remaining;
+ if (br->cache_avail == 0)
+ (void)rar_br_fillup(a, br);
+ }
+ return (ARCHIVE_OK);
+}
+
+/* Find last bit set */
+static inline int
+rar_fls(unsigned int word)
+{
+ word |= (word >> 1);
+ word |= (word >> 2);
+ word |= (word >> 4);
+ word |= (word >> 8);
+ word |= (word >> 16);
+ return word - (word >> 1);
+}
+
+/* LZSS functions */
+static inline int64_t
+lzss_position(struct lzss *lzss)
+{
+ return lzss->position;
+}
+
+static inline int
+lzss_mask(struct lzss *lzss)
+{
+ return lzss->mask;
+}
+
+static inline int
+lzss_size(struct lzss *lzss)
+{
+ return lzss->mask + 1;
+}
+
+static inline int
+lzss_offset_for_position(struct lzss *lzss, int64_t pos)
+{
+ return pos & lzss->mask;
+}
+
+static inline unsigned char *
+lzss_pointer_for_position(struct lzss *lzss, int64_t pos)
+{
+ return &lzss->window[lzss_offset_for_position(lzss, pos)];
+}
+
+static inline int
+lzss_current_offset(struct lzss *lzss)
+{
+ return lzss_offset_for_position(lzss, lzss->position);
+}
+
+static inline uint8_t *
+lzss_current_pointer(struct lzss *lzss)
+{
+ return lzss_pointer_for_position(lzss, lzss->position);
+}
+
+static inline void
+lzss_emit_literal(struct rar *rar, uint8_t literal)
+{
+ *lzss_current_pointer(&rar->lzss) = literal;
+ rar->lzss.position++;
+}
+
+static inline void
+lzss_emit_match(struct rar *rar, int offset, int length)
+{
+ int dstoffs = lzss_current_offset(&rar->lzss);
+ int srcoffs = (dstoffs - offset) & lzss_mask(&rar->lzss);
+ int l, li, remaining;
+ unsigned char *d, *s;
+
+ remaining = length;
+ while (remaining > 0) {
+ l = remaining;
+ if (dstoffs > srcoffs) {
+ if (l > lzss_size(&rar->lzss) - dstoffs)
+ l = lzss_size(&rar->lzss) - dstoffs;
+ } else {
+ if (l > lzss_size(&rar->lzss) - srcoffs)
+ l = lzss_size(&rar->lzss) - srcoffs;
+ }
+ d = &(rar->lzss.window[dstoffs]);
+ s = &(rar->lzss.window[srcoffs]);
+ if ((dstoffs + l < srcoffs) || (srcoffs + l < dstoffs))
+ memcpy(d, s, l);
+ else {
+ for (li = 0; li < l; li++)
+ d[li] = s[li];
+ }
+ remaining -= l;
+ dstoffs = (dstoffs + l) & lzss_mask(&(rar->lzss));
+ srcoffs = (srcoffs + l) & lzss_mask(&(rar->lzss));
+ }
+ rar->lzss.position += length;
+}
+
+static void *
+ppmd_alloc(void *p, size_t size)
+{
+ (void)p;
+ return malloc(size);
+}
+static void
+ppmd_free(void *p, void *address)
+{
+ (void)p;
+ free(address);
+}
+static ISzAlloc g_szalloc = { ppmd_alloc, ppmd_free };
+
+static Byte
+ppmd_read(void *p)
+{
+ struct archive_read *a = ((IByteIn*)p)->a;
+ struct rar *rar = (struct rar *)(a->format->data);
+ struct rar_br *br = &(rar->br);
+ Byte b;
+ if (!rar_br_read_ahead(a, br, 8))
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated RAR file data");
+ rar->valid = 0;
+ return 0;
+ }
+ b = rar_br_bits(br, 8);
+ rar_br_consume(br, 8);
+ return b;
+}
+
+int
+archive_read_support_format_rar(struct archive *_a)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ struct rar *rar;
+ int r;
+
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
+ "archive_read_support_format_rar");
+
+ rar = (struct rar *)malloc(sizeof(*rar));
+ if (rar == NULL)
+ {
+ archive_set_error(&a->archive, ENOMEM, "Can't allocate rar data");
+ return (ARCHIVE_FATAL);
+ }
+ memset(rar, 0, sizeof(*rar));
+
+ r = __archive_read_register_format(a,
+ rar,
+ "rar",
+ archive_read_format_rar_bid,
+ archive_read_format_rar_options,
+ archive_read_format_rar_read_header,
+ archive_read_format_rar_read_data,
+ archive_read_format_rar_read_data_skip,
+ archive_read_format_rar_cleanup);
+
+ if (r != ARCHIVE_OK)
+ free(rar);
+ return (r);
+}
+
+static int
+archive_read_format_rar_bid(struct archive_read *a, int best_bid)
+{
+ const char *p;
+
+ /* If there's already a bid > 30, we'll never win. */
+ if (best_bid > 30)
+ return (-1);
+
+ if ((p = __archive_read_ahead(a, 7, NULL)) == NULL)
+ return (-1);
+
+ if (memcmp(p, RAR_SIGNATURE, 7) == 0)
+ return (30);
+
+ if ((p[0] == 'M' && p[1] == 'Z') || memcmp(p, "\x7F\x45LF", 4) == 0) {
+ /* This is a PE file */
+ ssize_t offset = 0x10000;
+ ssize_t window = 4096;
+ ssize_t bytes_avail;
+ while (offset + window <= (1024 * 128)) {
+ const char *buff = __archive_read_ahead(a, offset + window, &bytes_avail);
+ if (buff == NULL) {
+ /* Remaining bytes are less than window. */
+ window >>= 1;
+ if (window < 0x40)
+ return (0);
+ continue;
+ }
+ p = buff + offset;
+ while (p + 7 < buff + bytes_avail) {
+ if (memcmp(p, RAR_SIGNATURE, 7) == 0)
+ return (30);
+ p += 0x10;
+ }
+ offset = p - buff;
+ }
+ }
+ return (0);
+}
+
+static int
+skip_sfx(struct archive_read *a)
+{
+ const void *h;
+ const char *p, *q;
+ size_t skip, total;
+ ssize_t bytes, window;
+
+ total = 0;
+ window = 4096;
+ while (total + window <= (1024 * 128)) {
+ h = __archive_read_ahead(a, window, &bytes);
+ if (h == NULL) {
+ /* Remaining bytes are less than window. */
+ window >>= 1;
+ if (window < 0x40)
+ goto fatal;
+ continue;
+ }
+ if (bytes < 0x40)
+ goto fatal;
+ p = h;
+ q = p + bytes;
+
+ /*
+ * Scan ahead until we find something that looks
+ * like the RAR header.
+ */
+ while (p + 7 < q) {
+ if (memcmp(p, RAR_SIGNATURE, 7) == 0) {
+ skip = p - (const char *)h;
+ __archive_read_consume(a, skip);
+ return (ARCHIVE_OK);
+ }
+ p += 0x10;
+ }
+ skip = p - (const char *)h;
+ __archive_read_consume(a, skip);
+ total += skip;
+ }
+fatal:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Couldn't find out RAR header");
+ return (ARCHIVE_FATAL);
+}
+
+static int
+archive_read_format_rar_options(struct archive_read *a,
+ const char *key, const char *val)
+{
+ struct rar *rar;
+ int ret = ARCHIVE_FAILED;
+
+ rar = (struct rar *)(a->format->data);
+ if (strcmp(key, "hdrcharset") == 0) {
+ if (val == NULL || val[0] == 0)
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "rar: hdrcharset option needs a character-set name");
+ else {
+ rar->opt_sconv =
+ archive_string_conversion_from_charset(
+ &a->archive, val, 0);
+ if (rar->opt_sconv != NULL)
+ ret = ARCHIVE_OK;
+ else
+ ret = ARCHIVE_FATAL;
+ }
+ } else
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "rar: unknown keyword ``%s''", key);
+
+ return (ret);
+}
+
+static int
+archive_read_format_rar_read_header(struct archive_read *a,
+ struct archive_entry *entry)
+{
+ const void *h;
+ const char *p;
+ struct rar *rar;
+ size_t skip;
+ char head_type;
+ int ret;
+ unsigned flags;
+
+ a->archive.archive_format = ARCHIVE_FORMAT_RAR;
+ if (a->archive.archive_format_name == NULL)
+ a->archive.archive_format_name = "RAR";
+
+ rar = (struct rar *)(a->format->data);
+
+ /* RAR files can be generated without EOF headers, so return ARCHIVE_EOF if
+ * this fails.
+ */
+ if ((h = __archive_read_ahead(a, 7, NULL)) == NULL)
+ return (ARCHIVE_EOF);
+
+ p = h;
+ if (rar->found_first_header == 0 &&
+ ((p[0] == 'M' && p[1] == 'Z') || memcmp(p, "\x7F\x45LF", 4) == 0)) {
+ /* This is an executable ? Must be self-extracting... */
+ ret = skip_sfx(a);
+ if (ret < ARCHIVE_WARN)
+ return (ret);
+ }
+ rar->found_first_header = 1;
+
+ while (1)
+ {
+ unsigned long crc32_val;
+
+ if ((h = __archive_read_ahead(a, 7, NULL)) == NULL)
+ return (ARCHIVE_FATAL);
+ p = h;
+
+ head_type = p[2];
+ switch(head_type)
+ {
+ case MARK_HEAD:
+ if (memcmp(p, RAR_SIGNATURE, 7) != 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid marker header");
+ return (ARCHIVE_FATAL);
+ }
+ __archive_read_consume(a, 7);
+ break;
+
+ case MAIN_HEAD:
+ rar->main_flags = archive_le16dec(p + 3);
+ skip = archive_le16dec(p + 5);
+ if (skip < 7 + sizeof(rar->reserved1) + sizeof(rar->reserved2)) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid header size");
+ return (ARCHIVE_FATAL);
+ }
+ if ((h = __archive_read_ahead(a, skip, NULL)) == NULL)
+ return (ARCHIVE_FATAL);
+ p = h;
+ memcpy(rar->reserved1, p + 7, sizeof(rar->reserved1));
+ memcpy(rar->reserved2, p + 7 + sizeof(rar->reserved1),
+ sizeof(rar->reserved2));
+ if (rar->main_flags & MHD_ENCRYPTVER) {
+ if (skip < 7 + sizeof(rar->reserved1) + sizeof(rar->reserved2)+1) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid header size");
+ return (ARCHIVE_FATAL);
+ }
+ rar->encryptver = *(p + 7 + sizeof(rar->reserved1) +
+ sizeof(rar->reserved2));
+ }
+
+ if (rar->main_flags & MHD_VOLUME ||
+ rar->main_flags & MHD_FIRSTVOLUME)
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "RAR volume support unavailable.");
+ return (ARCHIVE_FATAL);
+ }
+ if (rar->main_flags & MHD_PASSWORD)
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "RAR encryption support unavailable.");
+ return (ARCHIVE_FATAL);
+ }
+
+ crc32_val = crc32(0, (const unsigned char *)p + 2, skip - 2);
+ if ((crc32_val & 0xffff) != archive_le16dec(p)) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Header CRC error");
+ return (ARCHIVE_FATAL);
+ }
+ __archive_read_consume(a, skip);
+ break;
+
+ case FILE_HEAD:
+ return read_header(a, entry, head_type);
+
+ case COMM_HEAD:
+ case AV_HEAD:
+ case SUB_HEAD:
+ case PROTECT_HEAD:
+ case SIGN_HEAD:
+ flags = archive_le16dec(p + 3);
+ skip = archive_le16dec(p + 5);
+ if (skip < 7) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid header size");
+ return (ARCHIVE_FATAL);
+ }
+ if (skip > 7) {
+ if ((h = __archive_read_ahead(a, skip, NULL)) == NULL)
+ return (ARCHIVE_FATAL);
+ p = h;
+ }
+ if (flags & HD_ADD_SIZE_PRESENT)
+ {
+ if (skip < 7 + 4) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid header size");
+ return (ARCHIVE_FATAL);
+ }
+ skip += archive_le32dec(p + 7);
+ if ((h = __archive_read_ahead(a, skip, NULL)) == NULL)
+ return (ARCHIVE_FATAL);
+ p = h;
+ }
+
+ crc32_val = crc32(0, (const unsigned char *)p + 2, skip - 2);
+ if ((crc32_val & 0xffff) != archive_le16dec(p)) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Header CRC error");
+ return (ARCHIVE_FATAL);
+ }
+ __archive_read_consume(a, skip);
+ break;
+
+ case NEWSUB_HEAD:
+ if ((ret = read_header(a, entry, head_type)) < ARCHIVE_WARN)
+ return ret;
+ break;
+
+ case ENDARC_HEAD:
+ return (ARCHIVE_EOF);
+
+ default:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Bad RAR file");
+ return (ARCHIVE_FATAL);
+ }
+ }
+}
+
+static int
+archive_read_format_rar_read_data(struct archive_read *a, const void **buff,
+ size_t *size, int64_t *offset)
+{
+ struct rar *rar = (struct rar *)(a->format->data);
+ int ret;
+
+ if (rar->bytes_unconsumed > 0) {
+ /* Consume as much as the decompressor actually used. */
+ __archive_read_consume(a, rar->bytes_unconsumed);
+ rar->bytes_unconsumed = 0;
+ }
+
+ if (rar->entry_eof) {
+ *buff = NULL;
+ *size = 0;
+ *offset = rar->offset;
+ return (ARCHIVE_EOF);
+ }
+
+ switch (rar->compression_method)
+ {
+ case COMPRESS_METHOD_STORE:
+ ret = read_data_stored(a, buff, size, offset);
+ break;
+
+ case COMPRESS_METHOD_FASTEST:
+ case COMPRESS_METHOD_FAST:
+ case COMPRESS_METHOD_NORMAL:
+ case COMPRESS_METHOD_GOOD:
+ case COMPRESS_METHOD_BEST:
+ 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;
+
+ default:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Unsupported compression method for RAR file.");
+ ret = ARCHIVE_FATAL;
+ break;
+ }
+ return (ret);
+}
+
+static int
+archive_read_format_rar_read_data_skip(struct archive_read *a)
+{
+ struct rar *rar;
+ int64_t bytes_skipped;
+
+ rar = (struct rar *)(a->format->data);
+
+ if (rar->bytes_unconsumed > 0) {
+ /* Consume as much as the decompressor actually used. */
+ __archive_read_consume(a, rar->bytes_unconsumed);
+ rar->bytes_unconsumed = 0;
+ }
+
+ if (rar->bytes_remaining > 0) {
+ bytes_skipped = __archive_read_consume(a, rar->bytes_remaining);
+ if (bytes_skipped < 0)
+ return (ARCHIVE_FATAL);
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_read_format_rar_cleanup(struct archive_read *a)
+{
+ struct rar *rar;
+
+ rar = (struct rar *)(a->format->data);
+ free_codes(a);
+ free(rar->filename);
+ free(rar->unp_buffer);
+ free(rar->lzss.window);
+ __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc);
+ free(rar);
+ (a->format->data) = NULL;
+ return (ARCHIVE_OK);
+}
+
+static int
+read_header(struct archive_read *a, struct archive_entry *entry,
+ char head_type)
+{
+ const void *h;
+ const char *p, *endp;
+ struct rar *rar;
+ struct rar_header rar_header;
+ struct rar_file_header file_header;
+ int64_t header_size;
+ unsigned filename_size, end;
+ char *filename;
+ char *strp;
+ char packed_size[8];
+ char unp_size[8];
+ int time;
+ struct archive_string_conv *sconv, *fn_sconv;
+ unsigned long crc32_val;
+ int ret = (ARCHIVE_OK), ret2;
+
+ rar = (struct rar *)(a->format->data);
+
+ /* Setup a string conversion object for non-rar-unicode filenames. */
+ sconv = rar->opt_sconv;
+ if (sconv == NULL) {
+ if (!rar->init_default_conversion) {
+ rar->sconv_default =
+ archive_string_default_conversion_for_read(
+ &(a->archive));
+ rar->init_default_conversion = 1;
+ }
+ sconv = rar->sconv_default;
+ }
+
+
+ if ((h = __archive_read_ahead(a, 7, NULL)) == NULL)
+ return (ARCHIVE_FATAL);
+ p = h;
+ memcpy(&rar_header, p, sizeof(rar_header));
+ rar->file_flags = archive_le16dec(rar_header.flags);
+ header_size = archive_le16dec(rar_header.size);
+ if (header_size < sizeof(file_header) + 7) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid header size");
+ return (ARCHIVE_FATAL);
+ }
+ crc32_val = crc32(0, (const unsigned char *)p + 2, 7 - 2);
+ __archive_read_consume(a, 7);
+
+ if (!(rar->file_flags & FHD_SOLID))
+ {
+ rar->compression_method = 0;
+ rar->packed_size = 0;
+ rar->unp_size = 0;
+ rar->mtime = 0;
+ rar->ctime = 0;
+ rar->atime = 0;
+ rar->arctime = 0;
+ rar->mode = 0;
+ memset(&rar->salt, 0, sizeof(rar->salt));
+ rar->atime = 0;
+ rar->ansec = 0;
+ rar->ctime = 0;
+ rar->cnsec = 0;
+ rar->mtime = 0;
+ rar->mnsec = 0;
+ rar->arctime = 0;
+ rar->arcnsec = 0;
+ }
+ else
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "RAR solid archive support unavailable.");
+ return (ARCHIVE_FATAL);
+ }
+
+ if ((h = __archive_read_ahead(a, header_size - 7, NULL)) == NULL)
+ return (ARCHIVE_FATAL);
+
+ /* File Header CRC check. */
+ crc32_val = crc32(crc32_val, h, header_size - 7);
+ if ((crc32_val & 0xffff) != archive_le16dec(rar_header.crc)) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Header CRC error");
+ return (ARCHIVE_FATAL);
+ }
+ /* If no CRC error, Go on parsing File Header. */
+ p = h;
+ endp = p + header_size - 7;
+ memcpy(&file_header, p, sizeof(file_header));
+ p += sizeof(file_header);
+
+ rar->compression_method = file_header.method;
+
+ time = archive_le32dec(file_header.file_time);
+ rar->mtime = get_time(time);
+
+ rar->file_crc = archive_le32dec(file_header.file_crc);
+
+ if (rar->file_flags & FHD_PASSWORD)
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "RAR encryption support unavailable.");
+ return (ARCHIVE_FATAL);
+ }
+
+ if (rar->file_flags & FHD_LARGE)
+ {
+ memcpy(packed_size, file_header.pack_size, 4);
+ memcpy(packed_size + 4, p, 4); /* High pack size */
+ p += 4;
+ memcpy(unp_size, file_header.unp_size, 4);
+ memcpy(unp_size + 4, p, 4); /* High unpack size */
+ p += 4;
+ rar->packed_size = archive_le64dec(&packed_size);
+ rar->unp_size = archive_le64dec(&unp_size);
+ }
+ else
+ {
+ rar->packed_size = archive_le32dec(file_header.pack_size);
+ rar->unp_size = archive_le32dec(file_header.unp_size);
+ }
+
+ /* TODO: Need to use CRC check for these kind of cases.
+ * For now, check if sizes are not < 0.
+ */
+ if (rar->packed_size < 0 || rar->unp_size < 0)
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid sizes specified.");
+ return (ARCHIVE_FATAL);
+ }
+
+ /* TODO: RARv3 subblocks contain comments. For now the complete block is
+ * consumed at the end.
+ */
+ if (head_type == NEWSUB_HEAD) {
+ size_t distance = p - (const char *)h;
+ header_size += rar->packed_size;
+ /* Make sure we have the extended data. */
+ if ((h = __archive_read_ahead(a, header_size - 7, NULL)) == NULL)
+ return (ARCHIVE_FATAL);
+ p = h;
+ endp = p + header_size - 7;
+ p += distance;
+ }
+
+ filename_size = archive_le16dec(file_header.name_size);
+ if (p + filename_size > endp) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid filename size");
+ return (ARCHIVE_FATAL);
+ }
+ if (rar->filename_allocated < filename_size+2) {
+ rar->filename = realloc(rar->filename, filename_size+2);
+ if (rar->filename == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Couldn't allocate memory.");
+ return (ARCHIVE_FATAL);
+ }
+ }
+ filename = rar->filename;
+ memcpy(filename, p, filename_size);
+ filename[filename_size] = '\0';
+ if (rar->file_flags & FHD_UNICODE)
+ {
+ if (filename_size != strlen(filename))
+ {
+ unsigned char highbyte, flagbits, flagbyte, length, offset;
+
+ end = filename_size;
+ filename_size = 0;
+ offset = strlen(filename) + 1;
+ highbyte = *(p + offset++);
+ flagbits = 0;
+ flagbyte = 0;
+ while (offset < end && filename_size < end)
+ {
+ if (!flagbits)
+ {
+ flagbyte = *(p + offset++);
+ flagbits = 8;
+ }
+
+ flagbits -= 2;
+ switch((flagbyte >> flagbits) & 3)
+ {
+ case 0:
+ filename[filename_size++] = '\0';
+ filename[filename_size++] = *(p + offset++);
+ break;
+ case 1:
+ filename[filename_size++] = highbyte;
+ filename[filename_size++] = *(p + offset++);
+ break;
+ case 2:
+ filename[filename_size++] = *(p + offset + 1);
+ filename[filename_size++] = *(p + offset);
+ offset += 2;
+ break;
+ case 3:
+ {
+ length = *(p + offset++);
+ while (length)
+ {
+ if (filename_size >= end)
+ break;
+ filename[filename_size++] = *(p + offset);
+ length--;
+ }
+ }
+ break;
+ }
+ }
+ if (filename_size >= end) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid filename");
+ return (ARCHIVE_FATAL);
+ }
+ filename[filename_size++] = '\0';
+ filename[filename_size++] = '\0';
+
+ /* Decoded unicode form is UTF-16BE, so we have to update a string
+ * conversion object for it. */
+ if (rar->sconv_utf16be == NULL) {
+ rar->sconv_utf16be = archive_string_conversion_from_charset(
+ &a->archive, "UTF-16BE", 1);
+ if (rar->sconv_utf16be == NULL)
+ return (ARCHIVE_FATAL);
+ }
+ fn_sconv = rar->sconv_utf16be;
+
+ strp = filename;
+ while (memcmp(strp, "\x00\x00", 2))
+ {
+ if (!memcmp(strp, "\x00\\", 2))
+ *(strp + 1) = '/';
+ strp += 2;
+ }
+ p += offset;
+ } else {
+ /*
+ * If FHD_UNICODE is set but no unicode data, this file name form
+ * is UTF-8, so we have to update a string conversion object for
+ * it accordingly.
+ */
+ if (rar->sconv_utf8 == NULL) {
+ rar->sconv_utf8 = archive_string_conversion_from_charset(
+ &a->archive, "UTF-8", 1);
+ if (rar->sconv_utf8 == NULL)
+ return (ARCHIVE_FATAL);
+ }
+ fn_sconv = rar->sconv_utf8;
+ while ((strp = strchr(filename, '\\')) != NULL)
+ *strp = '/';
+ p += filename_size;
+ }
+ }
+ else
+ {
+ fn_sconv = sconv;
+ while ((strp = strchr(filename, '\\')) != NULL)
+ *strp = '/';
+ p += filename_size;
+ }
+
+ if (rar->file_flags & FHD_SALT)
+ {
+ if (p + 8 > endp) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid header size");
+ return (ARCHIVE_FATAL);
+ }
+ memcpy(rar->salt, p, 8);
+ p += 8;
+ }
+
+ if (rar->file_flags & FHD_EXTTIME) {
+ if (read_exttime(p, rar, endp) < 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid header size");
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ __archive_read_consume(a, header_size - 7);
+
+ switch(file_header.host_os)
+ {
+ case OS_MSDOS:
+ case OS_OS2:
+ case OS_WIN32:
+ rar->mode = archive_le32dec(file_header.file_attr);
+ if (rar->mode & FILE_ATTRIBUTE_DIRECTORY)
+ rar->mode = AE_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
+ else
+ rar->mode = AE_IFREG;
+ rar->mode |= S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
+ break;
+
+ case OS_UNIX:
+ case OS_MAC_OS:
+ case OS_BEOS:
+ rar->mode = archive_le32dec(file_header.file_attr);
+ break;
+
+ default:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Unknown file attributes from RAR file's host OS");
+ return (ARCHIVE_FATAL);
+ }
+
+ rar->bytes_remaining = rar->packed_size;
+ rar->bytes_uncopied = rar->bytes_unconsumed = 0;
+ rar->lzss.position = rar->dictionary_size = rar->offset = 0;
+ rar->offset_outgoing = 0;
+ rar->br.cache_avail = 0;
+ rar->br.avail_in = 0;
+ rar->crc_calculated = 0;
+ rar->entry_eof = 0;
+ rar->valid = 1;
+ rar->is_ppmd_block = 0;
+ rar->start_new_table = 1;
+ free(rar->unp_buffer);
+ rar->unp_buffer = NULL;
+ rar->unp_offset = 0;
+ rar->unp_buffer_size = UNP_BUFFER_SIZE;
+ memset(rar->lengthtable, 0, sizeof(rar->lengthtable));
+ __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc);
+ rar->ppmd_valid = rar->ppmd_eod = 0;
+
+ /* Don't set any archive entries for non-file header types */
+ if (head_type == NEWSUB_HEAD)
+ return ret;
+
+ archive_entry_set_mtime(entry, rar->mtime, rar->mnsec);
+ archive_entry_set_ctime(entry, rar->ctime, rar->cnsec);
+ archive_entry_set_atime(entry, rar->atime, rar->ansec);
+ archive_entry_set_size(entry, rar->unp_size);
+ archive_entry_set_mode(entry, rar->mode);
+
+ if (archive_entry_copy_pathname_l(entry, filename, filename_size, fn_sconv))
+ {
+ if (errno == ENOMEM)
+ {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Pathname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Pathname cannot be converted from %s to current locale.",
+ archive_string_conversion_charset_name(fn_sconv));
+ ret = (ARCHIVE_WARN);
+ }
+
+ if (((rar->mode) & AE_IFMT) == AE_IFLNK)
+ {
+ /* Make sure a symbolic-link file does not have its body. */
+ rar->bytes_remaining = 0;
+ archive_entry_set_size(entry, 0);
+
+ /* Read a symbolic-link name. */
+ if ((ret2 = read_symlink_stored(a, entry, sconv)) < (ARCHIVE_WARN))
+ return ret2;
+ if (ret > ret2)
+ ret = ret2;
+ }
+
+ if (rar->bytes_remaining == 0)
+ rar->entry_eof = 1;
+
+ return ret;
+}
+
+static time_t
+get_time(int time)
+{
+ struct tm tm;
+ tm.tm_sec = 2 * (time & 0x1f);
+ tm.tm_min = (time >> 5) & 0x3f;
+ tm.tm_hour = (time >> 11) & 0x1f;
+ tm.tm_mday = (time >> 16) & 0x1f;
+ tm.tm_mon = ((time >> 21) & 0x0f) - 1;
+ tm.tm_year = ((time >> 25) & 0x7f) + 80;
+ tm.tm_isdst = -1;
+ return mktime(&tm);
+}
+
+static int
+read_exttime(const char *p, struct rar *rar, const char *endp)
+{
+ unsigned rmode, flags, rem, j, count;
+ int time, i;
+ struct tm *tm;
+ time_t t;
+ long nsec;
+
+ if (p + 2 > endp)
+ return (-1);
+ flags = archive_le16dec(p);
+ p += 2;
+
+ for (i = 3; i >= 0; i--)
+ {
+ t = 0;
+ if (i == 3)
+ t = rar->mtime;
+ rmode = flags >> i * 4;
+ if (rmode & 8)
+ {
+ if (!t)
+ {
+ if (p + 4 > endp)
+ return (-1);
+ time = archive_le32dec(p);
+ t = get_time(time);
+ p += 4;
+ }
+ rem = 0;
+ count = rmode & 3;
+ if (p + count > endp)
+ return (-1);
+ for (j = 0; j < count; j++)
+ {
+ rem = ((*p) << 16) | (rem >> 8);
+ p++;
+ }
+ tm = localtime(&t);
+ nsec = tm->tm_sec + rem / NS_UNIT;
+ if (rmode & 4)
+ {
+ tm->tm_sec++;
+ t = mktime(tm);
+ }
+ if (i == 3)
+ {
+ rar->mtime = t;
+ rar->mnsec = nsec;
+ }
+ else if (i == 2)
+ {
+ rar->ctime = t;
+ rar->cnsec = nsec;
+ }
+ else if (i == 1)
+ {
+ rar->atime = t;
+ rar->ansec = nsec;
+ }
+ else
+ {
+ rar->arctime = t;
+ rar->arcnsec = nsec;
+ }
+ }
+ }
+ return (0);
+}
+
+static int
+read_symlink_stored(struct archive_read *a, struct archive_entry *entry,
+ struct archive_string_conv *sconv)
+{
+ const void *h;
+ const char *p;
+ struct rar *rar;
+ int ret = (ARCHIVE_OK);
+
+ rar = (struct rar *)(a->format->data);
+ if ((h = __archive_read_ahead(a, rar->packed_size, NULL)) == NULL)
+ return (ARCHIVE_FATAL);
+ p = h;
+
+ if (archive_entry_copy_symlink_l(entry, p, rar->packed_size, sconv))
+ {
+ if (errno == ENOMEM)
+ {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for link");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "link cannot be converted from %s to current locale.",
+ archive_string_conversion_charset_name(sconv));
+ ret = (ARCHIVE_WARN);
+ }
+ __archive_read_consume(a, rar->packed_size);
+ return ret;
+}
+
+static int
+read_data_stored(struct archive_read *a, const void **buff, size_t *size,
+ int64_t *offset)
+{
+ struct rar *rar;
+ ssize_t bytes_avail;
+
+ rar = (struct rar *)(a->format->data);
+ if (rar->bytes_remaining == 0)
+ {
+ *buff = NULL;
+ *size = 0;
+ *offset = rar->offset;
+ if (rar->file_crc != rar->crc_calculated) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "File CRC error");
+ return (ARCHIVE_FATAL);
+ }
+ rar->entry_eof = 1;
+ return (ARCHIVE_EOF);
+ }
+
+ *buff = __archive_read_ahead(a, 1, &bytes_avail);
+ if (bytes_avail <= 0)
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated RAR file data");
+ return (ARCHIVE_FATAL);
+ }
+ if (bytes_avail > rar->bytes_remaining)
+ bytes_avail = rar->bytes_remaining;
+
+ *size = bytes_avail;
+ *offset = rar->offset;
+ rar->offset += bytes_avail;
+ rar->bytes_remaining -= bytes_avail;
+ rar->bytes_unconsumed = bytes_avail;
+ /* Calculate File CRC. */
+ rar->crc_calculated = crc32(rar->crc_calculated, *buff, bytes_avail);
+ return (ARCHIVE_OK);
+}
+
+static int
+read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
+ int64_t *offset)
+{
+ struct rar *rar;
+ int64_t start, end, actualend;
+ size_t bs;
+ int ret = (ARCHIVE_OK), sym, code, lzss_offset, length, i;
+
+ rar = (struct rar *)(a->format->data);
+
+ do {
+ if (!rar->valid)
+ return (ARCHIVE_FATAL);
+ if (rar->ppmd_eod ||
+ (rar->dictionary_size && rar->offset >= rar->unp_size))
+ {
+ if (rar->unp_offset > 0) {
+ /*
+ * We have unprocessed extracted data. write it out.
+ */
+ *buff = rar->unp_buffer;
+ *size = rar->unp_offset;
+ *offset = rar->offset_outgoing;
+ rar->offset_outgoing += *size;
+ /* Calculate File CRC. */
+ rar->crc_calculated = crc32(rar->crc_calculated, *buff, *size);
+ rar->unp_offset = 0;
+ return (ARCHIVE_OK);
+ }
+ *buff = NULL;
+ *size = 0;
+ *offset = rar->offset;
+ if (rar->file_crc != rar->crc_calculated) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "File CRC error");
+ return (ARCHIVE_FATAL);
+ }
+ rar->entry_eof = 1;
+ return (ARCHIVE_EOF);
+ }
+
+ if (!rar->is_ppmd_block && rar->dictionary_size && rar->bytes_uncopied > 0)
+ {
+ if (rar->bytes_uncopied > (rar->unp_buffer_size - rar->unp_offset))
+ bs = rar->unp_buffer_size - rar->unp_offset;
+ else
+ bs = rar->bytes_uncopied;
+ ret = copy_from_lzss_window(a, buff, rar->offset, bs);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ rar->offset += bs;
+ rar->bytes_uncopied -= bs;
+ if (*buff != NULL) {
+ rar->unp_offset = 0;
+ *size = rar->unp_buffer_size;
+ *offset = rar->offset_outgoing;
+ rar->offset_outgoing += *size;
+ /* Calculate File CRC. */
+ rar->crc_calculated = crc32(rar->crc_calculated, *buff, *size);
+ return (ret);
+ }
+ continue;
+ }
+
+ if (!rar->br.next_in &&
+ (ret = rar_br_preparation(a, &(rar->br))) < ARCHIVE_WARN)
+ return (ret);
+ if (rar->start_new_table && ((ret = parse_codes(a)) < (ARCHIVE_WARN)))
+ return (ret);
+
+ if (rar->is_ppmd_block)
+ {
+ if ((sym = __archive_ppmd7_functions.Ppmd7_DecodeSymbol(
+ &rar->ppmd7_context, &rar->range_dec.p)) < 0)
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid symbol");
+ return (ARCHIVE_FATAL);
+ }
+ if(sym != rar->ppmd_escape)
+ {
+ lzss_emit_literal(rar, sym);
+ rar->bytes_uncopied++;
+ }
+ else
+ {
+ if ((code = __archive_ppmd7_functions.Ppmd7_DecodeSymbol(
+ &rar->ppmd7_context, &rar->range_dec.p)) < 0)
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid symbol");
+ return (ARCHIVE_FATAL);
+ }
+
+ switch(code)
+ {
+ case 0:
+ rar->start_new_table = 1;
+ return read_data_compressed(a, buff, size, offset);
+
+ case 2:
+ rar->ppmd_eod = 1;/* End Of ppmd Data. */
+ continue;
+
+ case 3:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Parsing filters is unsupported.");
+ return (ARCHIVE_FAILED);
+
+ case 4:
+ lzss_offset = 0;
+ for (i = 2; i >= 0; i--)
+ {
+ if ((code = __archive_ppmd7_functions.Ppmd7_DecodeSymbol(
+ &rar->ppmd7_context, &rar->range_dec.p)) < 0)
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid symbol");
+ return (ARCHIVE_FATAL);
+ }
+ lzss_offset |= code << (i * 8);
+ }
+ if ((length = __archive_ppmd7_functions.Ppmd7_DecodeSymbol(
+ &rar->ppmd7_context, &rar->range_dec.p)) < 0)
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid symbol");
+ return (ARCHIVE_FATAL);
+ }
+ lzss_emit_match(rar, lzss_offset + 2, length + 32);
+ rar->bytes_uncopied += length + 32;
+ break;
+
+ case 5:
+ if ((length = __archive_ppmd7_functions.Ppmd7_DecodeSymbol(
+ &rar->ppmd7_context, &rar->range_dec.p)) < 0)
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid symbol");
+ return (ARCHIVE_FATAL);
+ }
+ lzss_emit_match(rar, 1, length + 4);
+ rar->bytes_uncopied += length + 4;
+ break;
+
+ default:
+ lzss_emit_literal(rar, sym);
+ rar->bytes_uncopied++;
+ }
+ }
+ }
+ else
+ {
+ start = rar->offset;
+ end = start + rar->dictionary_size;
+ rar->filterstart = INT64_MAX;
+
+ if ((actualend = expand(a, end)) < 0)
+ return ((int)actualend);
+
+ rar->bytes_uncopied = actualend - start;
+ if (rar->bytes_uncopied == 0) {
+ /* Broken RAR files cause this case.
+ * NOTE: If this case were possible on a normal RAR file
+ * we would find out where it was actually bad and
+ * what we would do to solve it. */
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Internal error extracting RAR file");
+ return (ARCHIVE_FATAL);
+ }
+ }
+ if (rar->bytes_uncopied > (rar->unp_buffer_size - rar->unp_offset))
+ bs = rar->unp_buffer_size - rar->unp_offset;
+ else
+ bs = rar->bytes_uncopied;
+ ret = copy_from_lzss_window(a, buff, rar->offset, bs);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ rar->offset += bs;
+ rar->bytes_uncopied -= bs;
+ /*
+ * If *buff is NULL, it means unp_buffer is not full.
+ * So we have to continue extracting a RAR file.
+ */
+ } while (*buff == NULL);
+
+ rar->unp_offset = 0;
+ *size = rar->unp_buffer_size;
+ *offset = rar->offset_outgoing;
+ rar->offset_outgoing += *size;
+ /* Calculate File CRC. */
+ rar->crc_calculated = crc32(rar->crc_calculated, *buff, *size);
+ return ret;
+}
+
+static int
+parse_codes(struct archive_read *a)
+{
+ int i, j, val, n, r;
+ unsigned char bitlengths[MAX_SYMBOLS], zerocount, ppmd_flags;
+ unsigned int maxorder;
+ struct huffman_code precode;
+ struct rar *rar = (struct rar *)(a->format->data);
+ struct rar_br *br = &(rar->br);
+
+ free_codes(a);
+
+ /* Skip to the next byte */
+ rar_br_consume_unalined_bits(br);
+
+ /* PPMd block flag */
+ if (!rar_br_read_ahead(a, br, 1))
+ goto truncated_data;
+ if ((rar->is_ppmd_block = rar_br_bits(br, 1)) != 0)
+ {
+ rar_br_consume(br, 1);
+ if (!rar_br_read_ahead(a, br, 7))
+ goto truncated_data;
+ ppmd_flags = rar_br_bits(br, 7);
+ rar_br_consume(br, 7);
+
+ /* Memory is allocated in MB */
+ if (ppmd_flags & 0x20)
+ {
+ if (!rar_br_read_ahead(a, br, 8))
+ goto truncated_data;
+ rar->dictionary_size = (rar_br_bits(br, 8) + 1) << 20;
+ rar_br_consume(br, 8);
+ }
+
+ if (ppmd_flags & 0x40)
+ {
+ if (!rar_br_read_ahead(a, br, 8))
+ goto truncated_data;
+ rar->ppmd_escape = rar->ppmd7_context.InitEsc = rar_br_bits(br, 8);
+ rar_br_consume(br, 8);
+ }
+ else
+ rar->ppmd_escape = 2;
+
+ if (ppmd_flags & 0x20)
+ {
+ maxorder = (ppmd_flags & 0x1F) + 1;
+ if(maxorder > 16)
+ maxorder = 16 + (maxorder - 16) * 3;
+
+ if (maxorder == 1)
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated RAR file data");
+ return (ARCHIVE_FATAL);
+ }
+
+ /* Make sure ppmd7_contest is freed before Ppmd7_Construct
+ * because reading a broken file cause this abnormal sequence. */
+ __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context, &g_szalloc);
+
+ rar->bytein.a = a;
+ rar->bytein.Read = &ppmd_read;
+ __archive_ppmd7_functions.PpmdRAR_RangeDec_CreateVTable(&rar->range_dec);
+ rar->range_dec.Stream = &rar->bytein;
+ __archive_ppmd7_functions.Ppmd7_Construct(&rar->ppmd7_context);
+
+ if (!__archive_ppmd7_functions.Ppmd7_Alloc(&rar->ppmd7_context,
+ rar->dictionary_size, &g_szalloc))
+ {
+ archive_set_error(&a->archive, ENOMEM,
+ "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
+ if (!__archive_ppmd7_functions.PpmdRAR_RangeDec_Init(&rar->range_dec))
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Unable to initialize PPMd range decoder");
+ return (ARCHIVE_FATAL);
+ }
+ __archive_ppmd7_functions.Ppmd7_Init(&rar->ppmd7_context, maxorder);
+ rar->ppmd_valid = 1;
+ }
+ else
+ {
+ if (!rar->ppmd_valid) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid PPMd sequence");
+ return (ARCHIVE_FATAL);
+ }
+ if (!__archive_ppmd7_functions.PpmdRAR_RangeDec_Init(&rar->range_dec))
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Unable to initialize PPMd range decoder");
+ return (ARCHIVE_FATAL);
+ }
+ }
+ }
+ else
+ {
+ rar_br_consume(br, 1);
+
+ /* Keep existing table flag */
+ if (!rar_br_read_ahead(a, br, 1))
+ goto truncated_data;
+ if (!rar_br_bits(br, 1))
+ memset(rar->lengthtable, 0, sizeof(rar->lengthtable));
+ rar_br_consume(br, 1);
+
+ memset(&bitlengths, 0, sizeof(bitlengths));
+ for (i = 0; i < MAX_SYMBOLS;)
+ {
+ if (!rar_br_read_ahead(a, br, 4))
+ goto truncated_data;
+ bitlengths[i++] = rar_br_bits(br, 4);
+ rar_br_consume(br, 4);
+ if (bitlengths[i-1] == 0xF)
+ {
+ if (!rar_br_read_ahead(a, br, 4))
+ goto truncated_data;
+ zerocount = rar_br_bits(br, 4);
+ rar_br_consume(br, 4);
+ if (zerocount)
+ {
+ i--;
+ for (j = 0; j < zerocount + 2 && i < MAX_SYMBOLS; j++)
+ bitlengths[i++] = 0;
+ }
+ }
+ }
+
+ memset(&precode, 0, sizeof(precode));
+ r = create_code(a, &precode, bitlengths, MAX_SYMBOLS, MAX_SYMBOL_LENGTH);
+ if (r != ARCHIVE_OK) {
+ free(precode.tree);
+ free(precode.table);
+ return (r);
+ }
+
+ for (i = 0; i < HUFFMAN_TABLE_SIZE;)
+ {
+ if ((val = read_next_symbol(a, &precode)) < 0) {
+ free(precode.tree);
+ free(precode.table);
+ return (ARCHIVE_FATAL);
+ }
+ if (val < 16)
+ {
+ rar->lengthtable[i] = (rar->lengthtable[i] + val) & 0xF;
+ i++;
+ }
+ else if (val < 18)
+ {
+ if (i == 0)
+ {
+ free(precode.tree);
+ free(precode.table);
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Internal error extracting RAR file.");
+ return (ARCHIVE_FATAL);
+ }
+
+ if(val == 16) {
+ if (!rar_br_read_ahead(a, br, 3)) {
+ free(precode.tree);
+ free(precode.table);
+ goto truncated_data;
+ }
+ n = rar_br_bits(br, 3) + 3;
+ rar_br_consume(br, 3);
+ } else {
+ if (!rar_br_read_ahead(a, br, 7)) {
+ free(precode.tree);
+ free(precode.table);
+ goto truncated_data;
+ }
+ n = rar_br_bits(br, 7) + 11;
+ rar_br_consume(br, 7);
+ }
+
+ for (j = 0; j < n && i < HUFFMAN_TABLE_SIZE; j++)
+ {
+ rar->lengthtable[i] = rar->lengthtable[i-1];
+ i++;
+ }
+ }
+ else
+ {
+ if(val == 18) {
+ if (!rar_br_read_ahead(a, br, 3)) {
+ free(precode.tree);
+ free(precode.table);
+ goto truncated_data;
+ }
+ n = rar_br_bits(br, 3) + 3;
+ rar_br_consume(br, 3);
+ } else {
+ if (!rar_br_read_ahead(a, br, 7)) {
+ free(precode.tree);
+ free(precode.table);
+ goto truncated_data;
+ }
+ n = rar_br_bits(br, 7) + 11;
+ rar_br_consume(br, 7);
+ }
+
+ for(j = 0; j < n && i < HUFFMAN_TABLE_SIZE; j++)
+ rar->lengthtable[i++] = 0;
+ }
+ }
+ free(precode.tree);
+ free(precode.table);
+
+ r = create_code(a, &rar->maincode, &rar->lengthtable[0], MAINCODE_SIZE,
+ MAX_SYMBOL_LENGTH);
+ if (r != ARCHIVE_OK)
+ return (r);
+ r = create_code(a, &rar->offsetcode, &rar->lengthtable[MAINCODE_SIZE],
+ OFFSETCODE_SIZE, MAX_SYMBOL_LENGTH);
+ if (r != ARCHIVE_OK)
+ return (r);
+ r = create_code(a, &rar->lowoffsetcode,
+ &rar->lengthtable[MAINCODE_SIZE + OFFSETCODE_SIZE],
+ LOWOFFSETCODE_SIZE, MAX_SYMBOL_LENGTH);
+ if (r != ARCHIVE_OK)
+ return (r);
+ r = create_code(a, &rar->lengthcode,
+ &rar->lengthtable[MAINCODE_SIZE + OFFSETCODE_SIZE +
+ LOWOFFSETCODE_SIZE], LENGTHCODE_SIZE, MAX_SYMBOL_LENGTH);
+ if (r != ARCHIVE_OK)
+ return (r);
+ }
+
+ if (!rar->dictionary_size || !rar->lzss.window)
+ {
+ /* Seems as though dictionary sizes are not used. Even so, minimize
+ * memory usage as much as possible.
+ */
+ if (rar->unp_size >= DICTIONARY_MAX_SIZE)
+ rar->dictionary_size = DICTIONARY_MAX_SIZE;
+ else
+ rar->dictionary_size = rar_fls(rar->unp_size) << 1;
+ rar->lzss.window = (unsigned char *)realloc(rar->lzss.window,
+ rar->dictionary_size);
+ if (rar->lzss.window == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Unable to allocate memory for uncompressed data.");
+ return (ARCHIVE_FATAL);
+ }
+ memset(rar->lzss.window, 0, rar->dictionary_size);
+ rar->lzss.mask = rar->dictionary_size - 1;
+ }
+
+ rar->start_new_table = 0;
+ return (ARCHIVE_OK);
+truncated_data:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated RAR file data");
+ rar->valid = 0;
+ return (ARCHIVE_FATAL);
+}
+
+static void
+free_codes(struct archive_read *a)
+{
+ struct rar *rar = (struct rar *)(a->format->data);
+ free(rar->maincode.tree);
+ free(rar->offsetcode.tree);
+ free(rar->lowoffsetcode.tree);
+ free(rar->lengthcode.tree);
+ free(rar->maincode.table);
+ free(rar->offsetcode.table);
+ free(rar->lowoffsetcode.table);
+ free(rar->lengthcode.table);
+ memset(&rar->maincode, 0, sizeof(rar->maincode));
+ memset(&rar->offsetcode, 0, sizeof(rar->offsetcode));
+ memset(&rar->lowoffsetcode, 0, sizeof(rar->lowoffsetcode));
+ memset(&rar->lengthcode, 0, sizeof(rar->lengthcode));
+}
+
+
+static int
+read_next_symbol(struct archive_read *a, struct huffman_code *code)
+{
+ unsigned char bit;
+ unsigned int bits;
+ int length, value, node;
+ struct rar *rar;
+ struct rar_br *br;
+
+ if (!code->table)
+ {
+ if (make_table(a, code) != (ARCHIVE_OK))
+ return -1;
+ }
+
+ rar = (struct rar *)(a->format->data);
+ br = &(rar->br);
+
+ /* Look ahead (peek) at bits */
+ if (!rar_br_read_ahead(a, br, code->tablesize)) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated RAR file data");
+ rar->valid = 0;
+ return -1;
+ }
+ bits = rar_br_bits(br, code->tablesize);
+
+ length = code->table[bits].length;
+ value = code->table[bits].value;
+
+ if (length < 0)
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid prefix code in bitstream");
+ return -1;
+ }
+
+ if (length <= code->tablesize)
+ {
+ /* Skip length bits */
+ rar_br_consume(br, length);
+ return value;
+ }
+
+ /* Skip tablesize bits */
+ rar_br_consume(br, code->tablesize);
+
+ node = value;
+ while (!(code->tree[node].branches[0] ==
+ code->tree[node].branches[1]))
+ {
+ if (!rar_br_read_ahead(a, br, 1)) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated RAR file data");
+ rar->valid = 0;
+ return -1;
+ }
+ bit = rar_br_bits(br, 1);
+ rar_br_consume(br, 1);
+
+ if (code->tree[node].branches[bit] < 0)
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid prefix code in bitstream");
+ return -1;
+ }
+ node = code->tree[node].branches[bit];
+ }
+
+ return code->tree[node].branches[0];
+}
+
+static int
+create_code(struct archive_read *a, struct huffman_code *code,
+ unsigned char *lengths, int numsymbols, char maxlength)
+{
+ int i, j, codebits = 0, symbolsleft = numsymbols;
+
+ if (new_node(code) < 0) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Unable to allocate memory for node data.");
+ return (ARCHIVE_FATAL);
+ }
+ code->numentries = 1;
+ code->minlength = INT_MAX;
+ code->maxlength = INT_MIN;
+ codebits = 0;
+ for(i = 1; i <= maxlength; i++)
+ {
+ for(j = 0; j < numsymbols; j++)
+ {
+ if (lengths[j] != i) continue;
+ if (add_value(a, code, j, codebits, i) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ codebits++;
+ if (--symbolsleft <= 0) { break; break; }
+ }
+ codebits <<= 1;
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+add_value(struct archive_read *a, struct huffman_code *code, int value,
+ int codebits, int length)
+{
+ int repeatpos, lastnode, bitpos, bit, repeatnode, nextnode;
+
+ free(code->table);
+ code->table = NULL;
+
+ if(length > code->maxlength)
+ code->maxlength = length;
+ if(length < code->minlength)
+ code->minlength = length;
+
+ repeatpos = -1;
+ if (repeatpos == 0 || (repeatpos >= 0
+ && (((codebits >> (repeatpos - 1)) & 3) == 0
+ || ((codebits >> (repeatpos - 1)) & 3) == 3)))
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid repeat position");
+ return (ARCHIVE_FATAL);
+ }
+
+ lastnode = 0;
+ for (bitpos = length - 1; bitpos >= 0; bitpos--)
+ {
+ bit = (codebits >> bitpos) & 1;
+
+ /* Leaf node check */
+ if (code->tree[lastnode].branches[0] ==
+ code->tree[lastnode].branches[1])
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Prefix found");
+ return (ARCHIVE_FATAL);
+ }
+
+ if (bitpos == repeatpos)
+ {
+ /* Open branch check */
+ if (!(code->tree[lastnode].branches[bit] < 0))
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid repeating code");
+ return (ARCHIVE_FATAL);
+ }
+
+ if ((repeatnode = new_node(code)) < 0) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Unable to allocate memory for node data.");
+ return (ARCHIVE_FATAL);
+ }
+ if ((nextnode = new_node(code)) < 0) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Unable to allocate memory for node data.");
+ return (ARCHIVE_FATAL);
+ }
+
+ /* Set branches */
+ code->tree[lastnode].branches[bit] = repeatnode;
+ code->tree[repeatnode].branches[bit] = repeatnode;
+ code->tree[repeatnode].branches[bit^1] = nextnode;
+ lastnode = nextnode;
+
+ bitpos++; /* terminating bit already handled, skip it */
+ }
+ else
+ {
+ /* Open branch check */
+ if (code->tree[lastnode].branches[bit] < 0)
+ {
+ if (new_node(code) < 0) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Unable to allocate memory for node data.");
+ return (ARCHIVE_FATAL);
+ }
+ code->tree[lastnode].branches[bit] = code->numentries++;
+ }
+
+ /* set to branch */
+ lastnode = code->tree[lastnode].branches[bit];
+ }
+ }
+
+ if (!(code->tree[lastnode].branches[0] == -1
+ && code->tree[lastnode].branches[1] == -2))
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Prefix found");
+ return (ARCHIVE_FATAL);
+ }
+
+ /* Set leaf value */
+ code->tree[lastnode].branches[0] = value;
+ code->tree[lastnode].branches[1] = value;
+
+ return (ARCHIVE_OK);
+}
+
+static int
+new_node(struct huffman_code *code)
+{
+ code->tree = (struct huffman_tree_node *)realloc(code->tree,
+ (code->numentries + 1) * sizeof(*code->tree));
+ if (code->tree == NULL)
+ return (-1);
+ code->tree[code->numentries].branches[0] = -1;
+ code->tree[code->numentries].branches[1] = -2;
+ return 1;
+}
+
+static int
+make_table(struct archive_read *a, struct huffman_code *code)
+{
+ if (code->maxlength < code->minlength || code->maxlength > 10)
+ code->tablesize = 10;
+ else
+ code->tablesize = code->maxlength;
+
+ code->table =
+ (struct huffman_table_entry *)malloc(sizeof(*code->table)
+ * (1 << code->tablesize));
+
+ return make_table_recurse(a, code, 0, code->table, 0, code->tablesize);
+}
+
+static int
+make_table_recurse(struct archive_read *a, struct huffman_code *code, int node,
+ struct huffman_table_entry *table, int depth,
+ int maxdepth)
+{
+ int currtablesize, i, ret = (ARCHIVE_OK);
+
+ if (!code->tree)
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Huffman tree was not created.");
+ return (ARCHIVE_FATAL);
+ }
+ if (node < 0 || node >= code->numentries)
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid location to Huffman tree specified.");
+ return (ARCHIVE_FATAL);
+ }
+
+ currtablesize = 1 << (maxdepth - depth);
+
+ if (code->tree[node].branches[0] ==
+ code->tree[node].branches[1])
+ {
+ for(i = 0; i < currtablesize; i++)
+ {
+ table[i].length = depth;
+ table[i].value = code->tree[node].branches[0];
+ }
+ }
+ else if (node < 0)
+ {
+ for(i = 0; i < currtablesize; i++)
+ table[i].length = -1;
+ }
+ else
+ {
+ if(depth == maxdepth)
+ {
+ table[0].length = maxdepth + 1;
+ table[0].value = node;
+ }
+ else
+ {
+ ret |= make_table_recurse(a, code, code->tree[node].branches[0], table,
+ depth + 1, maxdepth);
+ ret |= make_table_recurse(a, code, code->tree[node].branches[1],
+ table + currtablesize / 2, depth + 1, maxdepth);
+ }
+ }
+ return ret;
+}
+
+static int64_t
+expand(struct archive_read *a, int64_t end)
+{
+ static const unsigned char lengthbases[] =
+ { 0, 1, 2, 3, 4, 5, 6,
+ 7, 8, 10, 12, 14, 16, 20,
+ 24, 28, 32, 40, 48, 56, 64,
+ 80, 96, 112, 128, 160, 192, 224 };
+ static const unsigned char lengthbits[] =
+ { 0, 0, 0, 0, 0, 0, 0,
+ 0, 1, 1, 1, 1, 2, 2,
+ 2, 2, 3, 3, 3, 3, 4,
+ 4, 4, 4, 5, 5, 5, 5 };
+ static const unsigned int offsetbases[] =
+ { 0, 1, 2, 3, 4, 6,
+ 8, 12, 16, 24, 32, 48,
+ 64, 96, 128, 192, 256, 384,
+ 512, 768, 1024, 1536, 2048, 3072,
+ 4096, 6144, 8192, 12288, 16384, 24576,
+ 32768, 49152, 65536, 98304, 131072, 196608,
+ 262144, 327680, 393216, 458752, 524288, 589824,
+ 655360, 720896, 786432, 851968, 917504, 983040,
+ 1048576, 1310720, 1572864, 1835008, 2097152, 2359296,
+ 2621440, 2883584, 3145728, 3407872, 3670016, 3932160 };
+ static const unsigned char offsetbits[] =
+ { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4,
+ 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10,
+ 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18 };
+ static const unsigned char shortbases[] =
+ { 0, 4, 8, 16, 32, 64, 128, 192 };
+ static const unsigned char shortbits[] =
+ { 2, 2, 3, 4, 5, 6, 6, 6 };
+
+ int symbol, offs, len, offsindex, lensymbol, i, offssymbol, lowoffsetsymbol;
+ unsigned char newfile;
+ struct rar *rar = (struct rar *)(a->format->data);
+ struct rar_br *br = &(rar->br);
+
+ if (rar->filterstart < end)
+ end = rar->filterstart;
+
+ while (1)
+ {
+ if (rar->output_last_match &&
+ lzss_position(&rar->lzss) + rar->lastlength <= end)
+ {
+ lzss_emit_match(rar, rar->lastoffset, rar->lastlength);
+ rar->output_last_match = 0;
+ }
+
+ if(rar->is_ppmd_block || rar->output_last_match ||
+ lzss_position(&rar->lzss) >= end)
+ return lzss_position(&rar->lzss);
+
+ 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);
+ continue;
+ }
+ else if (symbol == 256)
+ {
+ if (!rar_br_read_ahead(a, br, 1))
+ goto truncated_data;
+ newfile = !rar_br_bits(br, 1);
+ rar_br_consume(br, 1);
+
+ if(newfile)
+ {
+ rar->start_new_block = 1;
+ if (!rar_br_read_ahead(a, br, 1))
+ goto truncated_data;
+ rar->start_new_table = rar_br_bits(br, 1);
+ rar_br_consume(br, 1);
+ return lzss_position(&rar->lzss);
+ }
+ else
+ {
+ if (parse_codes(a) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ continue;
+ }
+ }
+ else if(symbol==257)
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Parsing filters is unsupported.");
+ return (ARCHIVE_FAILED);
+ }
+ else if(symbol==258)
+ {
+ if(rar->lastlength == 0)
+ continue;
+
+ offs = rar->lastoffset;
+ len = rar->lastlength;
+ }
+ else if (symbol <= 262)
+ {
+ offsindex = symbol - 259;
+ offs = rar->oldoffset[offsindex];
+
+ if ((lensymbol = read_next_symbol(a, &rar->lengthcode)) < 0)
+ goto bad_data;
+ if (lensymbol > sizeof(lengthbases)/sizeof(lengthbases[0]))
+ goto bad_data;
+ if (lensymbol > sizeof(lengthbits)/sizeof(lengthbits[0]))
+ goto bad_data;
+ len = lengthbases[lensymbol] + 2;
+ if (lengthbits[lensymbol] > 0) {
+ if (!rar_br_read_ahead(a, br, lengthbits[lensymbol]))
+ goto truncated_data;
+ len += rar_br_bits(br, lengthbits[lensymbol]);
+ rar_br_consume(br, lengthbits[lensymbol]);
+ }
+
+ for (i = offsindex; i > 0; i--)
+ rar->oldoffset[i] = rar->oldoffset[i-1];
+ rar->oldoffset[0] = offs;
+ }
+ else if(symbol<=270)
+ {
+ offs = shortbases[symbol-263] + 1;
+ if(shortbits[symbol-263] > 0) {
+ if (!rar_br_read_ahead(a, br, shortbits[symbol-263]))
+ goto truncated_data;
+ offs += rar_br_bits(br, shortbits[symbol-263]);
+ rar_br_consume(br, shortbits[symbol-263]);
+ }
+
+ len = 2;
+
+ for(i = 3; i > 0; i--)
+ rar->oldoffset[i] = rar->oldoffset[i-1];
+ rar->oldoffset[0] = offs;
+ }
+ else
+ {
+ if (symbol-271 > sizeof(lengthbases)/sizeof(lengthbases[0]))
+ goto bad_data;
+ if (symbol-271 > sizeof(lengthbits)/sizeof(lengthbits[0]))
+ goto bad_data;
+ len = lengthbases[symbol-271]+3;
+ if(lengthbits[symbol-271] > 0) {
+ if (!rar_br_read_ahead(a, br, lengthbits[symbol-271]))
+ goto truncated_data;
+ len += rar_br_bits(br, lengthbits[symbol-271]);
+ rar_br_consume(br, lengthbits[symbol-271]);
+ }
+
+ if ((offssymbol = read_next_symbol(a, &rar->offsetcode)) < 0)
+ goto bad_data;
+ if (offssymbol > sizeof(offsetbases)/sizeof(offsetbases[0]))
+ goto bad_data;
+ if (offssymbol > sizeof(offsetbits)/sizeof(offsetbits[0]))
+ goto bad_data;
+ offs = offsetbases[offssymbol]+1;
+ if(offsetbits[offssymbol] > 0)
+ {
+ if(offssymbol > 9)
+ {
+ if(offsetbits[offssymbol] > 4) {
+ if (!rar_br_read_ahead(a, br, offsetbits[offssymbol] - 4))
+ goto truncated_data;
+ offs += rar_br_bits(br, offsetbits[offssymbol] - 4) << 4;
+ rar_br_consume(br, offsetbits[offssymbol] - 4);
+ }
+
+ if(rar->numlowoffsetrepeats > 0)
+ {
+ rar->numlowoffsetrepeats--;
+ offs += rar->lastlowoffset;
+ }
+ else
+ {
+ if ((lowoffsetsymbol =
+ read_next_symbol(a, &rar->lowoffsetcode)) < 0)
+ return (ARCHIVE_FATAL);
+ if(lowoffsetsymbol == 16)
+ {
+ rar->numlowoffsetrepeats = 15;
+ offs += rar->lastlowoffset;
+ }
+ else
+ {
+ offs += lowoffsetsymbol;
+ rar->lastlowoffset = lowoffsetsymbol;
+ }
+ }
+ }
+ else {
+ if (!rar_br_read_ahead(a, br, offsetbits[offssymbol]))
+ goto truncated_data;
+ offs += rar_br_bits(br, offsetbits[offssymbol]);
+ rar_br_consume(br, offsetbits[offssymbol]);
+ }
+ }
+
+ if (offs >= 0x40000)
+ len++;
+ if (offs >= 0x2000)
+ len++;
+
+ for(i = 3; i > 0; i--)
+ rar->oldoffset[i] = rar->oldoffset[i-1];
+ rar->oldoffset[0] = offs;
+ }
+
+ rar->lastoffset = offs;
+ rar->lastlength = len;
+ rar->output_last_match = 1;
+ }
+truncated_data:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated RAR file data");
+ rar->valid = 0;
+ return (ARCHIVE_FATAL);
+bad_data:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Bad RAR file data");
+ return (ARCHIVE_FATAL);
+}
+
+static int
+copy_from_lzss_window(struct archive_read *a, const void **buffer,
+ int64_t startpos, int length)
+{
+ int windowoffs, firstpart;
+ struct rar *rar = (struct rar *)(a->format->data);
+
+ if (!rar->unp_buffer)
+ {
+ if ((rar->unp_buffer = malloc(rar->unp_buffer_size)) == NULL)
+ {
+ archive_set_error(&a->archive, ENOMEM,
+ "Unable to allocate memory for uncompressed data.");
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ windowoffs = lzss_offset_for_position(&rar->lzss, startpos);
+ if(windowoffs + length <= lzss_size(&rar->lzss))
+ memcpy(&rar->unp_buffer[rar->unp_offset], &rar->lzss.window[windowoffs],
+ length);
+ else
+ {
+ firstpart = lzss_size(&rar->lzss) - windowoffs;
+ if (firstpart < 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Bad RAR file data");
+ return (ARCHIVE_FATAL);
+ }
+ if (firstpart < length) {
+ memcpy(&rar->unp_buffer[rar->unp_offset],
+ &rar->lzss.window[windowoffs], firstpart);
+ memcpy(&rar->unp_buffer[rar->unp_offset + firstpart],
+ &rar->lzss.window[0], length - firstpart);
+ } else
+ memcpy(&rar->unp_buffer[rar->unp_offset],
+ &rar->lzss.window[windowoffs], length);
+ }
+ rar->unp_offset += length;
+ if (rar->unp_offset >= rar->unp_buffer_size)
+ *buffer = rar->unp_buffer;
+ else
+ *buffer = NULL;
+ return (ARCHIVE_OK);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_raw.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_raw.c
new file mode 100644
index 000000000..df2c00c96
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_raw.c
@@ -0,0 +1,187 @@
+/*-
+ * Copyright (c) 2003-2009 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: head/lib/libarchive/archive_read_support_format_raw.c 201107 2009-12-28 03:25:33Z kientzle $");
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#include "archive.h"
+#include "archive_entry.h"
+#include "archive_private.h"
+#include "archive_read_private.h"
+
+struct raw_info {
+ int64_t offset; /* Current position in the file. */
+ int64_t unconsumed;
+ int end_of_file;
+};
+
+static int archive_read_format_raw_bid(struct archive_read *, int);
+static int archive_read_format_raw_cleanup(struct archive_read *);
+static int archive_read_format_raw_read_data(struct archive_read *,
+ const void **, size_t *, int64_t *);
+static int archive_read_format_raw_read_data_skip(struct archive_read *);
+static int archive_read_format_raw_read_header(struct archive_read *,
+ struct archive_entry *);
+
+int
+archive_read_support_format_raw(struct archive *_a)
+{
+ struct raw_info *info;
+ struct archive_read *a = (struct archive_read *)_a;
+ int r;
+
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_raw");
+
+ info = (struct raw_info *)calloc(1, sizeof(*info));
+ if (info == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate raw_info data");
+ return (ARCHIVE_FATAL);
+ }
+
+ r = __archive_read_register_format(a,
+ info,
+ "raw",
+ archive_read_format_raw_bid,
+ NULL,
+ archive_read_format_raw_read_header,
+ archive_read_format_raw_read_data,
+ archive_read_format_raw_read_data_skip,
+ archive_read_format_raw_cleanup);
+ if (r != ARCHIVE_OK)
+ free(info);
+ return (r);
+}
+
+/*
+ * Bid 1 if this is a non-empty file. Anyone who can really support
+ * this should outbid us, so it should generally be safe to use "raw"
+ * in conjunction with other formats. But, this could really confuse
+ * folks if there are bid errors or minor file damage, so we don't
+ * include "raw" as part of support_format_all().
+ */
+static int
+archive_read_format_raw_bid(struct archive_read *a, int best_bid)
+{
+ if (best_bid < 1 && __archive_read_ahead(a, 1, NULL) != NULL)
+ return (1);
+ return (-1);
+}
+
+/*
+ * Mock up a fake header.
+ */
+static int
+archive_read_format_raw_read_header(struct archive_read *a,
+ struct archive_entry *entry)
+{
+ struct raw_info *info;
+
+ info = (struct raw_info *)(a->format->data);
+ if (info->end_of_file)
+ return (ARCHIVE_EOF);
+
+ a->archive.archive_format = ARCHIVE_FORMAT_RAW;
+ a->archive.archive_format_name = "raw";
+ archive_entry_set_pathname(entry, "data");
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_perm(entry, 0644);
+ /* I'm deliberately leaving most fields unset here. */
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_read_format_raw_read_data(struct archive_read *a,
+ const void **buff, size_t *size, int64_t *offset)
+{
+ struct raw_info *info;
+ ssize_t avail;
+
+ info = (struct raw_info *)(a->format->data);
+
+ /* Consume the bytes we read last time. */
+ if (info->unconsumed) {
+ __archive_read_consume(a, info->unconsumed);
+ info->unconsumed = 0;
+ }
+
+ if (info->end_of_file)
+ return (ARCHIVE_EOF);
+
+ /* Get whatever bytes are immediately available. */
+ *buff = __archive_read_ahead(a, 1, &avail);
+ if (avail > 0) {
+ /* Return the bytes we just read */
+ *size = avail;
+ *offset = info->offset;
+ info->offset += *size;
+ info->unconsumed = avail;
+ return (ARCHIVE_OK);
+ } else if (0 == avail) {
+ /* Record and return end-of-file. */
+ info->end_of_file = 1;
+ *size = 0;
+ *offset = info->offset;
+ return (ARCHIVE_EOF);
+ } else {
+ /* Record and return an error. */
+ *size = 0;
+ *offset = info->offset;
+ return (avail);
+ }
+}
+
+static int
+archive_read_format_raw_read_data_skip(struct archive_read *a)
+{
+ struct raw_info *info = (struct raw_info *)(a->format->data);
+
+ /* Consume the bytes we read last time. */
+ if (info->unconsumed) {
+ __archive_read_consume(a, info->unconsumed);
+ info->unconsumed = 0;
+ }
+ info->end_of_file = 1;
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_read_format_raw_cleanup(struct archive_read *a)
+{
+ struct raw_info *info;
+
+ info = (struct raw_info *)(a->format->data);
+ free(info);
+ a->format->data = NULL;
+ return (ARCHIVE_OK);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c
new file mode 100644
index 000000000..89a1d4f2a
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c
@@ -0,0 +1,2692 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * 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"
+__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_tar.c 201161 2009-12-29 05:44:39Z kientzle $");
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include <stddef.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include "archive.h"
+#include "archive_acl_private.h" /* For ACL parsing routines. */
+#include "archive_entry.h"
+#include "archive_entry_locale.h"
+#include "archive_private.h"
+#include "archive_read_private.h"
+
+#define tar_min(a,b) ((a) < (b) ? (a) : (b))
+
+/*
+ * Layout of POSIX 'ustar' tar header.
+ */
+struct archive_entry_header_ustar {
+ char name[100];
+ char mode[8];
+ char uid[8];
+ char gid[8];
+ char size[12];
+ char mtime[12];
+ char checksum[8];
+ char typeflag[1];
+ char linkname[100]; /* "old format" header ends here */
+ char magic[6]; /* For POSIX: "ustar\0" */
+ char version[2]; /* For POSIX: "00" */
+ char uname[32];
+ char gname[32];
+ char rdevmajor[8];
+ char rdevminor[8];
+ char prefix[155];
+};
+
+/*
+ * Structure of GNU tar header
+ */
+struct gnu_sparse {
+ char offset[12];
+ char numbytes[12];
+};
+
+struct archive_entry_header_gnutar {
+ char name[100];
+ char mode[8];
+ char uid[8];
+ char gid[8];
+ char size[12];
+ char mtime[12];
+ char checksum[8];
+ char typeflag[1];
+ char linkname[100];
+ char magic[8]; /* "ustar \0" (note blank/blank/null at end) */
+ char uname[32];
+ char gname[32];
+ char rdevmajor[8];
+ char rdevminor[8];
+ char atime[12];
+ char ctime[12];
+ char offset[12];
+ char longnames[4];
+ char unused[1];
+ struct gnu_sparse sparse[4];
+ char isextended[1];
+ char realsize[12];
+ /*
+ * Old GNU format doesn't use POSIX 'prefix' field; they use
+ * the 'L' (longname) entry instead.
+ */
+};
+
+/*
+ * Data specific to this format.
+ */
+struct sparse_block {
+ struct sparse_block *next;
+ int64_t offset;
+ int64_t remaining;
+ int hole;
+};
+
+struct tar {
+ struct archive_string acl_text;
+ struct archive_string entry_pathname;
+ /* For "GNU.sparse.name" and other similar path extensions. */
+ struct archive_string entry_pathname_override;
+ struct archive_string entry_linkpath;
+ struct archive_string entry_uname;
+ struct archive_string entry_gname;
+ struct archive_string longlink;
+ struct archive_string longname;
+ struct archive_string pax_header;
+ struct archive_string pax_global;
+ struct archive_string line;
+ int pax_hdrcharset_binary;
+ int header_recursion_depth;
+ int64_t entry_bytes_remaining;
+ int64_t entry_offset;
+ int64_t entry_padding;
+ int64_t entry_bytes_unconsumed;
+ int64_t realsize;
+ struct sparse_block *sparse_list;
+ struct sparse_block *sparse_last;
+ int64_t sparse_offset;
+ int64_t sparse_numbytes;
+ int sparse_gnu_major;
+ int sparse_gnu_minor;
+ char sparse_gnu_pending;
+
+ struct archive_string localname;
+ struct archive_string_conv *opt_sconv;
+ struct archive_string_conv *sconv;
+ struct archive_string_conv *sconv_acl;
+ struct archive_string_conv *sconv_default;
+ int init_default_conversion;
+ int compat_2x;
+};
+
+static int archive_block_is_null(const char *p);
+static char *base64_decode(const char *, size_t, size_t *);
+static int gnu_add_sparse_entry(struct archive_read *, struct tar *,
+ int64_t offset, int64_t remaining);
+
+static void gnu_clear_sparse_list(struct tar *);
+static int gnu_sparse_old_read(struct archive_read *, struct tar *,
+ const struct archive_entry_header_gnutar *header, size_t *);
+static int gnu_sparse_old_parse(struct archive_read *, struct tar *,
+ const struct gnu_sparse *sparse, int length);
+static int gnu_sparse_01_parse(struct archive_read *, struct tar *,
+ const char *);
+static ssize_t gnu_sparse_10_read(struct archive_read *, struct tar *,
+ size_t *);
+static int header_Solaris_ACL(struct archive_read *, struct tar *,
+ struct archive_entry *, const void *, size_t *);
+static int header_common(struct archive_read *, struct tar *,
+ struct archive_entry *, const void *);
+static int header_old_tar(struct archive_read *, struct tar *,
+ struct archive_entry *, const void *);
+static int header_pax_extensions(struct archive_read *, struct tar *,
+ struct archive_entry *, const void *, size_t *);
+static int header_pax_global(struct archive_read *, struct tar *,
+ struct archive_entry *, const void *h, size_t *);
+static int header_longlink(struct archive_read *, struct tar *,
+ struct archive_entry *, const void *h, size_t *);
+static int header_longname(struct archive_read *, struct tar *,
+ struct archive_entry *, const void *h, size_t *);
+static int read_mac_metadata_blob(struct archive_read *, struct tar *,
+ struct archive_entry *, const void *h, size_t *);
+static int header_volume(struct archive_read *, struct tar *,
+ struct archive_entry *, const void *h, size_t *);
+static int header_ustar(struct archive_read *, struct tar *,
+ struct archive_entry *, const void *h);
+static int header_gnutar(struct archive_read *, struct tar *,
+ struct archive_entry *, const void *h, size_t *);
+static int archive_read_format_tar_bid(struct archive_read *, int);
+static int archive_read_format_tar_options(struct archive_read *,
+ const char *, const char *);
+static int archive_read_format_tar_cleanup(struct archive_read *);
+static int archive_read_format_tar_read_data(struct archive_read *a,
+ const void **buff, size_t *size, int64_t *offset);
+static int archive_read_format_tar_skip(struct archive_read *a);
+static int archive_read_format_tar_read_header(struct archive_read *,
+ struct archive_entry *);
+static int checksum(struct archive_read *, const void *);
+static int pax_attribute(struct archive_read *, struct tar *,
+ struct archive_entry *, char *key, char *value);
+static int pax_header(struct archive_read *, struct tar *,
+ struct archive_entry *, char *attr);
+static void pax_time(const char *, int64_t *sec, long *nanos);
+static ssize_t readline(struct archive_read *, struct tar *, const char **,
+ ssize_t limit, size_t *);
+static int read_body_to_string(struct archive_read *, struct tar *,
+ struct archive_string *, const void *h, size_t *);
+static int solaris_sparse_parse(struct archive_read *, struct tar *,
+ struct archive_entry *, const char *);
+static int64_t tar_atol(const char *, unsigned);
+static int64_t tar_atol10(const char *, unsigned);
+static int64_t tar_atol256(const char *, unsigned);
+static int64_t tar_atol8(const char *, unsigned);
+static int tar_read_header(struct archive_read *, struct tar *,
+ struct archive_entry *, size_t *);
+static int tohex(int c);
+static char *url_decode(const char *);
+static void tar_flush_unconsumed(struct archive_read *, size_t *);
+
+
+int
+archive_read_support_format_gnutar(struct archive *a)
+{
+ archive_check_magic(a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_gnutar");
+ return (archive_read_support_format_tar(a));
+}
+
+
+int
+archive_read_support_format_tar(struct archive *_a)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ struct tar *tar;
+ int r;
+
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_tar");
+
+ tar = (struct tar *)calloc(1, sizeof(*tar));
+ if (tar == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate tar data");
+ return (ARCHIVE_FATAL);
+ }
+
+ r = __archive_read_register_format(a, tar, "tar",
+ archive_read_format_tar_bid,
+ archive_read_format_tar_options,
+ archive_read_format_tar_read_header,
+ archive_read_format_tar_read_data,
+ archive_read_format_tar_skip,
+ archive_read_format_tar_cleanup);
+
+ if (r != ARCHIVE_OK)
+ free(tar);
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_read_format_tar_cleanup(struct archive_read *a)
+{
+ struct tar *tar;
+
+ tar = (struct tar *)(a->format->data);
+ gnu_clear_sparse_list(tar);
+ archive_string_free(&tar->acl_text);
+ archive_string_free(&tar->entry_pathname);
+ archive_string_free(&tar->entry_pathname_override);
+ archive_string_free(&tar->entry_linkpath);
+ archive_string_free(&tar->entry_uname);
+ archive_string_free(&tar->entry_gname);
+ archive_string_free(&tar->line);
+ archive_string_free(&tar->pax_global);
+ archive_string_free(&tar->pax_header);
+ archive_string_free(&tar->longname);
+ archive_string_free(&tar->longlink);
+ archive_string_free(&tar->localname);
+ free(tar);
+ (a->format->data) = NULL;
+ return (ARCHIVE_OK);
+}
+
+
+static int
+archive_read_format_tar_bid(struct archive_read *a, int best_bid)
+{
+ int bid;
+ const char *h;
+ const struct archive_entry_header_ustar *header;
+
+ (void)best_bid; /* UNUSED */
+
+ bid = 0;
+
+ /* Now let's look at the actual header and see if it matches. */
+ h = __archive_read_ahead(a, 512, NULL);
+ if (h == NULL)
+ return (-1);
+
+ /* If it's an end-of-archive mark, we can handle it. */
+ if (h[0] == 0 && archive_block_is_null(h)) {
+ /*
+ * Usually, I bid the number of bits verified, but
+ * in this case, 4096 seems excessive so I picked 10 as
+ * an arbitrary but reasonable-seeming value.
+ */
+ return (10);
+ }
+
+ /* If it's not an end-of-archive mark, it must have a valid checksum.*/
+ if (!checksum(a, h))
+ return (0);
+ bid += 48; /* Checksum is usually 6 octal digits. */
+
+ header = (const struct archive_entry_header_ustar *)h;
+
+ /* Recognize POSIX formats. */
+ if ((memcmp(header->magic, "ustar\0", 6) == 0)
+ && (memcmp(header->version, "00", 2) == 0))
+ bid += 56;
+
+ /* Recognize GNU tar format. */
+ if ((memcmp(header->magic, "ustar ", 6) == 0)
+ && (memcmp(header->version, " \0", 2) == 0))
+ bid += 56;
+
+ /* Type flag must be null, digit or A-Z, a-z. */
+ if (header->typeflag[0] != 0 &&
+ !( header->typeflag[0] >= '0' && header->typeflag[0] <= '9') &&
+ !( header->typeflag[0] >= 'A' && header->typeflag[0] <= 'Z') &&
+ !( header->typeflag[0] >= 'a' && header->typeflag[0] <= 'z') )
+ return (0);
+ bid += 2; /* 6 bits of variation in an 8-bit field leaves 2 bits. */
+
+ /* Sanity check: Look at first byte of mode field. */
+ switch (255 & (unsigned)header->mode[0]) {
+ case 0: case 255:
+ /* Base-256 value: No further verification possible! */
+ break;
+ case ' ': /* Not recommended, but not illegal, either. */
+ break;
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ /* Octal Value. */
+ /* TODO: Check format of remainder of this field. */
+ break;
+ default:
+ /* Not a valid mode; bail out here. */
+ return (0);
+ }
+ /* TODO: Sanity test uid/gid/size/mtime/rdevmajor/rdevminor fields. */
+
+ return (bid);
+}
+
+static int
+archive_read_format_tar_options(struct archive_read *a,
+ const char *key, const char *val)
+{
+ struct tar *tar;
+ int ret = ARCHIVE_FAILED;
+
+ 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->init_default_conversion = tar->compat_2x;
+ ret = ARCHIVE_OK;
+ } else if (strcmp(key, "hdrcharset") == 0) {
+ if (val == NULL || val[0] == 0)
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "tar: hdrcharset option needs a character-set name");
+ else {
+ tar->opt_sconv =
+ archive_string_conversion_from_charset(
+ &a->archive, val, 0);
+ if (tar->opt_sconv != NULL)
+ ret = ARCHIVE_OK;
+ else
+ ret = ARCHIVE_FATAL;
+ }
+ } else
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "tar: unknown keyword ``%s''", key);
+
+ return (ret);
+}
+
+/* utility function- this exists to centralize the logic of tracking
+ * how much unconsumed data we have floating around, and to consume
+ * anything outstanding since we're going to do read_aheads
+ */
+static void
+tar_flush_unconsumed(struct archive_read *a, size_t *unconsumed)
+{
+ if (*unconsumed) {
+/*
+ void *data = (void *)__archive_read_ahead(a, *unconsumed, NULL);
+ * this block of code is to poison claimed unconsumed space, ensuring
+ * things break if it is in use still.
+ * currently it WILL break things, so enable it only for debugging this issue
+ if (data) {
+ memset(data, 0xff, *unconsumed);
+ }
+*/
+ __archive_read_consume(a, *unconsumed);
+ *unconsumed = 0;
+ }
+}
+
+/*
+ * The function invoked by archive_read_next_header(). This
+ * just sets up a few things and then calls the internal
+ * tar_read_header() function below.
+ */
+static int
+archive_read_format_tar_read_header(struct archive_read *a,
+ struct archive_entry *entry)
+{
+ /*
+ * When converting tar archives to cpio archives, it is
+ * essential that each distinct file have a distinct inode
+ * number. To simplify this, we keep a static count here to
+ * assign fake dev/inode numbers to each tar entry. Note that
+ * pax format archives may overwrite this with something more
+ * useful.
+ *
+ * Ideally, we would track every file read from the archive so
+ * that we could assign the same dev/ino pair to hardlinks,
+ * but the memory required to store a complete lookup table is
+ * probably not worthwhile just to support the relatively
+ * obscure tar->cpio conversion case.
+ */
+ static int default_inode;
+ static int default_dev;
+ struct tar *tar;
+ const char *p;
+ int r;
+ size_t l, unconsumed = 0;
+
+ /* Assign default device/inode values. */
+ archive_entry_set_dev(entry, 1 + default_dev); /* Don't use zero. */
+ archive_entry_set_ino(entry, ++default_inode); /* Don't use zero. */
+ /* Limit generated st_ino number to 16 bits. */
+ if (default_inode >= 0xffff) {
+ ++default_dev;
+ default_inode = 0;
+ }
+
+ tar = (struct tar *)(a->format->data);
+ tar->entry_offset = 0;
+ gnu_clear_sparse_list(tar);
+ tar->realsize = -1; /* Mark this as "unset" */
+
+ /* Setup default string conversion. */
+ tar->sconv = tar->opt_sconv;
+ if (tar->sconv == NULL) {
+ if (!tar->init_default_conversion) {
+ tar->sconv_default =
+ archive_string_default_conversion_for_read(&(a->archive));
+ tar->init_default_conversion = 1;
+ }
+ tar->sconv = tar->sconv_default;
+ }
+
+ r = tar_read_header(a, tar, entry, &unconsumed);
+
+ tar_flush_unconsumed(a, &unconsumed);
+
+ /*
+ * "non-sparse" files are really just sparse files with
+ * a single block.
+ */
+ if (tar->sparse_list == NULL) {
+ if (gnu_add_sparse_entry(a, tar, 0, tar->entry_bytes_remaining)
+ != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ } else {
+ struct sparse_block *sb;
+
+ for (sb = tar->sparse_list; sb != NULL; sb = sb->next) {
+ if (!sb->hole)
+ archive_entry_sparse_add_entry(entry,
+ sb->offset, sb->remaining);
+ }
+ }
+
+ if (r == ARCHIVE_OK) {
+ /*
+ * "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) {
+ l = wcslen(wp);
+ if (archive_entry_filetype(entry) == AE_IFREG
+ && wp[l-1] == L'/')
+ archive_entry_set_filetype(entry, AE_IFDIR);
+ } else {
+ p = archive_entry_pathname(entry);
+ if (p == NULL)
+ return (ARCHIVE_FAILED);
+ l = strlen(p);
+ if (archive_entry_filetype(entry) == AE_IFREG
+ && p[l-1] == '/')
+ archive_entry_set_filetype(entry, AE_IFDIR);
+ }
+ }
+ return (r);
+}
+
+static int
+archive_read_format_tar_read_data(struct archive_read *a,
+ const void **buff, size_t *size, int64_t *offset)
+{
+ ssize_t bytes_read;
+ struct tar *tar;
+ struct sparse_block *p;
+
+ tar = (struct tar *)(a->format->data);
+
+skip_hole:
+ /* Remove exhausted entries from sparse list. */
+ while (tar->sparse_list != NULL &&
+ tar->sparse_list->remaining == 0) {
+ p = tar->sparse_list;
+ tar->sparse_list = p->next;
+ free(p);
+ }
+
+ if (tar->entry_bytes_unconsumed) {
+ __archive_read_consume(a, tar->entry_bytes_unconsumed);
+ tar->entry_bytes_unconsumed = 0;
+ }
+
+ /* If we're at end of file, return EOF. */
+ if (tar->sparse_list == NULL || tar->entry_bytes_remaining == 0) {
+ if (__archive_read_consume(a, tar->entry_padding) < 0)
+ return (ARCHIVE_FATAL);
+ tar->entry_padding = 0;
+ *buff = NULL;
+ *size = 0;
+ *offset = tar->realsize;
+ return (ARCHIVE_EOF);
+ }
+
+ *buff = __archive_read_ahead(a, 1, &bytes_read);
+ if (bytes_read < 0)
+ return (ARCHIVE_FATAL);
+ if (*buff == NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Truncated tar archive");
+ return (ARCHIVE_FATAL);
+ }
+ if (bytes_read > tar->entry_bytes_remaining)
+ bytes_read = tar->entry_bytes_remaining;
+ /* Don't read more than is available in the
+ * current sparse block. */
+ if (tar->sparse_list->remaining < bytes_read)
+ bytes_read = tar->sparse_list->remaining;
+ *size = bytes_read;
+ *offset = tar->sparse_list->offset;
+ tar->sparse_list->remaining -= bytes_read;
+ tar->sparse_list->offset += bytes_read;
+ tar->entry_bytes_remaining -= bytes_read;
+ tar->entry_bytes_unconsumed = bytes_read;
+
+ if (tar->sparse_list->hole)
+ goto skip_hole;
+
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_read_format_tar_skip(struct archive_read *a)
+{
+ int64_t bytes_skipped;
+ 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);
+ if (bytes_skipped < 0)
+ return (ARCHIVE_FATAL);
+
+ tar->entry_bytes_remaining = 0;
+ tar->entry_bytes_unconsumed = 0;
+ tar->entry_padding = 0;
+
+ /* Free the sparse list. */
+ gnu_clear_sparse_list(tar);
+
+ return (ARCHIVE_OK);
+}
+
+/*
+ * This function recursively interprets all of the headers associated
+ * with a single entry.
+ */
+static int
+tar_read_header(struct archive_read *a, struct tar *tar,
+ struct archive_entry *entry, size_t *unconsumed)
+{
+ ssize_t bytes;
+ int err;
+ const char *h;
+ const struct archive_entry_header_ustar *header;
+
+ tar_flush_unconsumed(a, unconsumed);
+
+ /* Read 512-byte header record */
+ h = __archive_read_ahead(a, 512, &bytes);
+ if (bytes < 0)
+ return (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);
+ if (a->archive.archive_format_name == NULL) {
+ a->archive.archive_format = ARCHIVE_FORMAT_TAR;
+ a->archive.archive_format_name = "tar";
+ }
+ return (ARCHIVE_EOF);
+ }
+
+ /*
+ * Note: If the checksum fails and we return ARCHIVE_RETRY,
+ * then the client is likely to just retry. This is a very
+ * crude way to search for the next valid header!
+ *
+ * TODO: Improve this by implementing a real header scan.
+ */
+ if (!checksum(a, h)) {
+ tar_flush_unconsumed(a, unconsumed);
+ archive_set_error(&a->archive, EINVAL, "Damaged tar archive");
+ return (ARCHIVE_RETRY); /* Retryable: Invalid header */
+ }
+
+ if (++tar->header_recursion_depth > 32) {
+ tar_flush_unconsumed(a, unconsumed);
+ archive_set_error(&a->archive, EINVAL, "Too many special headers");
+ return (ARCHIVE_WARN);
+ }
+
+ /* Determine the format variant. */
+ header = (const struct archive_entry_header_ustar *)h;
+
+ switch(header->typeflag[0]) {
+ case 'A': /* Solaris tar ACL */
+ a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE;
+ a->archive.archive_format_name = "Solaris tar";
+ err = header_Solaris_ACL(a, tar, entry, h, unconsumed);
+ break;
+ case 'g': /* POSIX-standard 'g' header. */
+ 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);
+ break;
+ case 'K': /* Long link name (GNU tar, others) */
+ err = header_longlink(a, tar, entry, h, unconsumed);
+ break;
+ case 'L': /* Long filename (GNU tar, others) */
+ err = header_longname(a, tar, entry, h, unconsumed);
+ break;
+ case 'V': /* GNU volume header */
+ err = header_volume(a, tar, entry, h, unconsumed);
+ break;
+ case 'X': /* Used by SUN tar; same as 'x'. */
+ a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE;
+ a->archive.archive_format_name =
+ "POSIX pax interchange format (Sun variant)";
+ err = header_pax_extensions(a, tar, entry, h, unconsumed);
+ break;
+ case 'x': /* POSIX-standard 'x' header. */
+ a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE;
+ a->archive.archive_format_name = "POSIX pax interchange format";
+ err = header_pax_extensions(a, tar, entry, h, unconsumed);
+ break;
+ default:
+ if (memcmp(header->magic, "ustar \0", 8) == 0) {
+ a->archive.archive_format = ARCHIVE_FORMAT_TAR_GNUTAR;
+ a->archive.archive_format_name = "GNU tar format";
+ err = header_gnutar(a, tar, entry, h, unconsumed);
+ } else if (memcmp(header->magic, "ustar", 5) == 0) {
+ if (a->archive.archive_format != ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE) {
+ a->archive.archive_format = ARCHIVE_FORMAT_TAR_USTAR;
+ a->archive.archive_format_name = "POSIX ustar format";
+ }
+ err = header_ustar(a, tar, entry, h);
+ } else {
+ a->archive.archive_format = ARCHIVE_FORMAT_TAR;
+ a->archive.archive_format_name = "tar (non-POSIX)";
+ err = header_old_tar(a, tar, entry, h);
+ }
+ }
+ if (err == ARCHIVE_FATAL)
+ return (err);
+
+ tar_flush_unconsumed(a, unconsumed);
+
+ h = NULL;
+ header = NULL;
+
+ --tar->header_recursion_depth;
+ /* Yuck. Apple's design here ends up storing long pathname
+ * 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) {
+ int err2 = read_mac_metadata_blob(a, tar, entry, h, unconsumed);
+ if (err2 < err)
+ err = err2;
+ }
+
+ /* We return warnings or success as-is. Anything else is fatal. */
+ if (err == ARCHIVE_WARN || err == ARCHIVE_OK) {
+ if (tar->sparse_gnu_pending) {
+ if (tar->sparse_gnu_major == 1 &&
+ tar->sparse_gnu_minor == 0) {
+ ssize_t bytes_read;
+
+ tar->sparse_gnu_pending = 0;
+ /* Read initial sparse map. */
+ bytes_read = gnu_sparse_10_read(a, tar, unconsumed);
+ tar->entry_bytes_remaining -= bytes_read;
+ if (bytes_read < 0)
+ return (bytes_read);
+ } else {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Unrecognized GNU sparse file format");
+ return (ARCHIVE_WARN);
+ }
+ tar->sparse_gnu_pending = 0;
+ }
+ return (err);
+ }
+ if (err == ARCHIVE_EOF)
+ /* EOF when recursively reading a header is bad. */
+ archive_set_error(&a->archive, EINVAL, "Damaged tar archive");
+ return (ARCHIVE_FATAL);
+}
+
+/*
+ * Return true if block checksum is correct.
+ */
+static int
+checksum(struct archive_read *a, const void *h)
+{
+ const unsigned char *bytes;
+ const struct archive_entry_header_ustar *header;
+ int check, i, sum;
+
+ (void)a; /* UNUSED */
+ bytes = (const unsigned char *)h;
+ header = (const struct archive_entry_header_ustar *)h;
+
+ /*
+ * Test the checksum. Note that POSIX specifies _unsigned_
+ * bytes for this calculation.
+ */
+ sum = tar_atol(header->checksum, sizeof(header->checksum));
+ check = 0;
+ for (i = 0; i < 148; i++)
+ check += (unsigned char)bytes[i];
+ for (; i < 156; i++)
+ check += 32;
+ for (; i < 512; i++)
+ check += (unsigned char)bytes[i];
+ if (sum == check)
+ return (1);
+
+ /*
+ * Repeat test with _signed_ bytes, just in case this archive
+ * was created by an old BSD, Solaris, or HP-UX tar with a
+ * broken checksum calculation.
+ */
+ check = 0;
+ for (i = 0; i < 148; i++)
+ check += (signed char)bytes[i];
+ for (; i < 156; i++)
+ check += 32;
+ for (; i < 512; i++)
+ check += (signed char)bytes[i];
+ if (sum == check)
+ return (1);
+
+ return (0);
+}
+
+/*
+ * Return true if this block contains only nulls.
+ */
+static int
+archive_block_is_null(const char *p)
+{
+ unsigned i;
+
+ for (i = 0; i < 512; i++)
+ if (*p++)
+ return (0);
+ return (1);
+}
+
+/*
+ * Interpret 'A' Solaris ACL header
+ */
+static int
+header_Solaris_ACL(struct archive_read *a, struct tar *tar,
+ struct archive_entry *entry, const void *h, size_t *unconsumed)
+{
+ const struct archive_entry_header_ustar *header;
+ size_t size;
+ int err;
+ int64_t type;
+ char *acl, *p;
+
+ /*
+ * read_body_to_string adds a NUL terminator, but we need a little
+ * more to make sure that we don't overrun acl_text later.
+ */
+ header = (const struct archive_entry_header_ustar *)h;
+ size = tar_atol(header->size, sizeof(header->size));
+ err = read_body_to_string(a, tar, &(tar->acl_text), h, unconsumed);
+ if (err != ARCHIVE_OK)
+ return (err);
+
+ /* Recursively read next header */
+ err = tar_read_header(a, tar, entry, unconsumed);
+ if ((err != ARCHIVE_OK) && (err != ARCHIVE_WARN))
+ return (err);
+
+ /* TODO: Examine the first characters to see if this
+ * is an AIX ACL descriptor. We'll likely never support
+ * them, but it would be polite to recognize and warn when
+ * we do see them. */
+
+ /* Leading octal number indicates ACL type and number of entries. */
+ p = acl = tar->acl_text.s;
+ type = 0;
+ while (*p != '\0' && p < acl + size) {
+ if (*p < '0' || *p > '7') {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Malformed Solaris ACL attribute (invalid digit)");
+ return(ARCHIVE_WARN);
+ }
+ type <<= 3;
+ type += *p - '0';
+ if (type > 077777777) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Malformed Solaris ACL attribute (count too large)");
+ return (ARCHIVE_WARN);
+ }
+ p++;
+ }
+ switch ((int)type & ~0777777) {
+ case 01000000:
+ /* POSIX.1e ACL */
+ break;
+ case 03000000:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Solaris NFSv4 ACLs not supported");
+ return (ARCHIVE_WARN);
+ default:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Malformed Solaris ACL attribute (unsupported type %o)",
+ (int)type);
+ return (ARCHIVE_WARN);
+ }
+ p++;
+
+ if (p >= acl + size) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Malformed Solaris ACL attribute (body overflow)");
+ return(ARCHIVE_WARN);
+ }
+
+ /* ACL text is null-terminated; find the end. */
+ size -= (p - acl);
+ acl = p;
+
+ while (*p != '\0' && p < acl + size)
+ p++;
+
+ if (tar->sconv_acl == NULL) {
+ tar->sconv_acl = archive_string_conversion_from_charset(
+ &(a->archive), "UTF-8", 1);
+ if (tar->sconv_acl == NULL)
+ return (ARCHIVE_FATAL);
+ }
+ archive_strncpy(&(tar->localname), acl, p - acl);
+ err = archive_acl_parse_l(archive_entry_acl(entry),
+ tar->localname.s, ARCHIVE_ENTRY_ACL_TYPE_ACCESS, tar->sconv_acl);
+ if (err != ARCHIVE_OK) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for ACL");
+ } else
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Malformed Solaris ACL attribute (unparsable)");
+ }
+ return (err);
+}
+
+/*
+ * Interpret 'K' long linkname header.
+ */
+static int
+header_longlink(struct archive_read *a, struct tar *tar,
+ struct archive_entry *entry, const void *h, size_t *unconsumed)
+{
+ int err;
+
+ err = read_body_to_string(a, tar, &(tar->longlink), h, unconsumed);
+ if (err != ARCHIVE_OK)
+ return (err);
+ err = tar_read_header(a, tar, entry, unconsumed);
+ if ((err != ARCHIVE_OK) && (err != ARCHIVE_WARN))
+ return (err);
+ /* Set symlink if symlink already set, else hardlink. */
+ archive_entry_copy_link(entry, tar->longlink.s);
+ return (ARCHIVE_OK);
+}
+
+static int
+set_conversion_failed_error(struct archive_read *a,
+ struct archive_string_conv *sconv, const char *name)
+{
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for %s", name);
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "%s can't be converted from %s to current locale.",
+ name, archive_string_conversion_charset_name(sconv));
+ return (ARCHIVE_WARN);
+}
+
+/*
+ * Interpret 'L' long filename header.
+ */
+static int
+header_longname(struct archive_read *a, struct tar *tar,
+ struct archive_entry *entry, const void *h, size_t *unconsumed)
+{
+ int err;
+
+ err = read_body_to_string(a, tar, &(tar->longname), h, unconsumed);
+ if (err != ARCHIVE_OK)
+ return (err);
+ /* Read and parse "real" header, then override name. */
+ err = tar_read_header(a, tar, entry, unconsumed);
+ if ((err != ARCHIVE_OK) && (err != ARCHIVE_WARN))
+ return (err);
+ if (archive_entry_copy_pathname_l(entry, tar->longname.s,
+ archive_strlen(&(tar->longname)), tar->sconv) != 0)
+ err = set_conversion_failed_error(a, tar->sconv, "Pathname");
+ return (err);
+}
+
+
+/*
+ * Interpret 'V' GNU tar volume header.
+ */
+static int
+header_volume(struct archive_read *a, struct tar *tar,
+ struct archive_entry *entry, const void *h, size_t *unconsumed)
+{
+ (void)h;
+
+ /* Just skip this and read the next header. */
+ return (tar_read_header(a, tar, entry, unconsumed));
+}
+
+/*
+ * Read body of an archive entry into an archive_string object.
+ */
+static int
+read_body_to_string(struct archive_read *a, struct tar *tar,
+ struct archive_string *as, const void *h, size_t *unconsumed)
+{
+ int64_t size;
+ const struct archive_entry_header_ustar *header;
+ const void *src;
+
+ (void)tar; /* UNUSED */
+ header = (const struct archive_entry_header_ustar *)h;
+ size = tar_atol(header->size, sizeof(header->size));
+ if ((size > 1048576) || (size < 0)) {
+ archive_set_error(&a->archive, EINVAL,
+ "Special header too large");
+ return (ARCHIVE_FATAL);
+ }
+
+ /* Fail if we can't make our buffer big enough. */
+ if (archive_string_ensure(as, size+1) == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "No memory");
+ return (ARCHIVE_FATAL);
+ }
+
+ tar_flush_unconsumed(a, unconsumed);
+
+ /* Read the body into the string. */
+ *unconsumed = (size + 511) & ~ 511;
+ src = __archive_read_ahead(a, *unconsumed, NULL);
+ if (src == NULL) {
+ *unconsumed = 0;
+ return (ARCHIVE_FATAL);
+ }
+ memcpy(as->s, src, size);
+ as->s[size] = '\0';
+ as->length = size;
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Parse out common header elements.
+ *
+ * This would be the same as header_old_tar, except that the
+ * filename is handled slightly differently for old and POSIX
+ * entries (POSIX entries support a 'prefix'). This factoring
+ * allows header_old_tar and header_ustar
+ * to handle filenames differently, while still putting most of the
+ * common parsing into one place.
+ */
+static int
+header_common(struct archive_read *a, struct tar *tar,
+ struct archive_entry *entry, const void *h)
+{
+ const struct archive_entry_header_ustar *header;
+ char tartype;
+ int err = ARCHIVE_OK;
+
+ header = (const struct archive_entry_header_ustar *)h;
+ if (header->linkname[0])
+ archive_strncpy(&(tar->entry_linkpath),
+ header->linkname, sizeof(header->linkname));
+ else
+ archive_string_empty(&(tar->entry_linkpath));
+
+ /* Parse out the numeric fields (all are octal) */
+ archive_entry_set_mode(entry, tar_atol(header->mode, sizeof(header->mode)));
+ archive_entry_set_uid(entry, tar_atol(header->uid, sizeof(header->uid)));
+ archive_entry_set_gid(entry, tar_atol(header->gid, sizeof(header->gid)));
+ tar->entry_bytes_remaining = tar_atol(header->size, sizeof(header->size));
+ if (tar->entry_bytes_remaining < 0) {
+ tar->entry_bytes_remaining = 0;
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Tar entry has negative size?");
+ err = ARCHIVE_WARN;
+ }
+ tar->realsize = tar->entry_bytes_remaining;
+ archive_entry_set_size(entry, tar->entry_bytes_remaining);
+ archive_entry_set_mtime(entry, tar_atol(header->mtime, sizeof(header->mtime)), 0);
+
+ /* Handle the tar type flag appropriately. */
+ tartype = header->typeflag[0];
+
+ switch (tartype) {
+ case '1': /* Hard link */
+ if (archive_entry_copy_hardlink_l(entry, tar->entry_linkpath.s,
+ archive_strlen(&(tar->entry_linkpath)), tar->sconv) != 0) {
+ err = set_conversion_failed_error(a, tar->sconv,
+ "Linkname");
+ if (err == ARCHIVE_FATAL)
+ return (err);
+ }
+ /*
+ * The following may seem odd, but: Technically, tar
+ * does not store the file type for a "hard link"
+ * entry, only the fact that it is a hard link. So, I
+ * leave the type zero normally. But, pax interchange
+ * format allows hard links to have data, which
+ * implies that the underlying entry is a regular
+ * file.
+ */
+ if (archive_entry_size(entry) > 0)
+ archive_entry_set_filetype(entry, AE_IFREG);
+
+ /*
+ * A tricky point: Traditionally, tar readers have
+ * ignored the size field when reading hardlink
+ * entries, and some writers put non-zero sizes even
+ * though the body is empty. POSIX blessed this
+ * convention in the 1988 standard, but broke with
+ * this tradition in 2001 by permitting hardlink
+ * entries to store valid bodies in pax interchange
+ * format, but not in ustar format. Since there is no
+ * hard and fast way to distinguish pax interchange
+ * from earlier archives (the 'x' and 'g' entries are
+ * optional, after all), we need a heuristic.
+ */
+ if (archive_entry_size(entry) == 0) {
+ /* If the size is already zero, we're done. */
+ } else if (a->archive.archive_format
+ == ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE) {
+ /* Definitely pax extended; must obey hardlink size. */
+ } else if (a->archive.archive_format == ARCHIVE_FORMAT_TAR
+ || a->archive.archive_format == ARCHIVE_FORMAT_TAR_GNUTAR)
+ {
+ /* Old-style or GNU tar: we must ignore the size. */
+ archive_entry_set_size(entry, 0);
+ tar->entry_bytes_remaining = 0;
+ } else if (archive_read_format_tar_bid(a, 50) > 50) {
+ /*
+ * We don't know if it's pax: If the bid
+ * function sees a valid ustar header
+ * immediately following, then let's ignore
+ * the hardlink size.
+ */
+ archive_entry_set_size(entry, 0);
+ tar->entry_bytes_remaining = 0;
+ }
+ /*
+ * TODO: There are still two cases I'd like to handle:
+ * = a ustar non-pax archive with a hardlink entry at
+ * end-of-archive. (Look for block of nulls following?)
+ * = a pax archive that has not seen any pax headers
+ * and has an entry which is a hardlink entry storing
+ * a body containing an uncompressed tar archive.
+ * The first is worth addressing; I don't see any reliable
+ * way to deal with the second possibility.
+ */
+ break;
+ case '2': /* Symlink */
+ archive_entry_set_filetype(entry, AE_IFLNK);
+ archive_entry_set_size(entry, 0);
+ tar->entry_bytes_remaining = 0;
+ if (archive_entry_copy_symlink_l(entry, tar->entry_linkpath.s,
+ archive_strlen(&(tar->entry_linkpath)), tar->sconv) != 0) {
+ err = set_conversion_failed_error(a, tar->sconv,
+ "Linkname");
+ if (err == ARCHIVE_FATAL)
+ return (err);
+ }
+ break;
+ case '3': /* Character device */
+ archive_entry_set_filetype(entry, AE_IFCHR);
+ archive_entry_set_size(entry, 0);
+ tar->entry_bytes_remaining = 0;
+ break;
+ case '4': /* Block device */
+ archive_entry_set_filetype(entry, AE_IFBLK);
+ archive_entry_set_size(entry, 0);
+ tar->entry_bytes_remaining = 0;
+ break;
+ case '5': /* Dir */
+ archive_entry_set_filetype(entry, AE_IFDIR);
+ archive_entry_set_size(entry, 0);
+ tar->entry_bytes_remaining = 0;
+ break;
+ case '6': /* FIFO device */
+ archive_entry_set_filetype(entry, AE_IFIFO);
+ archive_entry_set_size(entry, 0);
+ tar->entry_bytes_remaining = 0;
+ break;
+ case 'D': /* GNU incremental directory type */
+ /*
+ * No special handling is actually required here.
+ * It might be nice someday to preprocess the file list and
+ * provide it to the client, though.
+ */
+ archive_entry_set_filetype(entry, AE_IFDIR);
+ break;
+ case 'M': /* GNU "Multi-volume" (remainder of file from last archive)*/
+ /*
+ * As far as I can tell, this is just like a regular file
+ * entry, except that the contents should be _appended_ to
+ * the indicated file at the indicated offset. This may
+ * require some API work to fully support.
+ */
+ break;
+ case 'N': /* Old GNU "long filename" entry. */
+ /* The body of this entry is a script for renaming
+ * previously-extracted entries. Ugh. It will never
+ * be supported by libarchive. */
+ archive_entry_set_filetype(entry, AE_IFREG);
+ break;
+ case 'S': /* GNU sparse files */
+ /*
+ * Sparse files are really just regular files with
+ * sparse information in the extended area.
+ */
+ /* FALLTHROUGH */
+ default: /* Regular file and non-standard types */
+ /*
+ * Per POSIX: non-recognized types should always be
+ * treated as regular files.
+ */
+ archive_entry_set_filetype(entry, AE_IFREG);
+ break;
+ }
+ return (err);
+}
+
+/*
+ * Parse out header elements for "old-style" tar archives.
+ */
+static int
+header_old_tar(struct archive_read *a, struct tar *tar,
+ struct archive_entry *entry, const void *h)
+{
+ const struct archive_entry_header_ustar *header;
+ int err = ARCHIVE_OK, err2;
+
+ /* Copy filename over (to ensure null termination). */
+ header = (const struct archive_entry_header_ustar *)h;
+ if (archive_entry_copy_pathname_l(entry,
+ header->name, sizeof(header->name), tar->sconv) != 0) {
+ err = set_conversion_failed_error(a, tar->sconv, "Pathname");
+ if (err == ARCHIVE_FATAL)
+ return (err);
+ }
+
+ /* Grab rest of common fields */
+ err2 = header_common(a, tar, entry, h);
+ if (err > err2)
+ err = err2;
+
+ tar->entry_padding = 0x1ff & (-tar->entry_bytes_remaining);
+ return (err);
+}
+
+/*
+ * Read a Mac AppleDouble-encoded blob of file metadata,
+ * if there is one.
+ */
+static int
+read_mac_metadata_blob(struct archive_read *a, struct tar *tar,
+ struct archive_entry *entry, const void *h, size_t *unconsumed)
+{
+ int64_t size;
+ const void *data;
+ const char *p, *name;
+ const wchar_t *wp, *wname;
+
+ (void)h; /* UNUSED */
+
+ wname = wp = archive_entry_pathname_w(entry);
+ if (wp != NULL) {
+ /* Find the last path element. */
+ for (; *wp != L'\0'; ++wp) {
+ if (wp[0] == '/' && wp[1] != L'\0')
+ wname = wp + 1;
+ }
+ /*
+ * If last path element starts with "._", then
+ * this is a Mac extension.
+ */
+ if (wname[0] != L'.' || wname[1] != L'_' || wname[2] == L'\0')
+ return ARCHIVE_OK;
+ } else {
+ /* Find the last path element. */
+ name = p = archive_entry_pathname(entry);
+ if (p == NULL)
+ return (ARCHIVE_FAILED);
+ for (; *p != '\0'; ++p) {
+ if (p[0] == '/' && p[1] != '\0')
+ name = p + 1;
+ }
+ /*
+ * If last path element starts with "._", then
+ * this is a Mac extension.
+ */
+ if (name[0] != '.' || name[1] != '_' || name[2] == '\0')
+ return ARCHIVE_OK;
+ }
+
+ /* Read the body as a Mac OS metadata blob. */
+ size = archive_entry_size(entry);
+
+ /*
+ * TODO: Look beyond the body here to peek at the next header.
+ * If it's a regular header (not an extension header)
+ * that has the wrong name, just return the current
+ * entry as-is, without consuming the body here.
+ * That would reduce the risk of us mis-identifying
+ * an ordinary file that just happened to have
+ * a name starting with "._".
+ *
+ * Q: Is the above idea really possible? Even
+ * when there are GNU or pax extension entries?
+ */
+ data = __archive_read_ahead(a, size, NULL);
+ if (data == NULL) {
+ *unconsumed = 0;
+ return (ARCHIVE_FATAL);
+ }
+ archive_entry_copy_mac_metadata(entry, data, size);
+ *unconsumed = (size + 511) & ~ 511;
+ tar_flush_unconsumed(a, unconsumed);
+ return (tar_read_header(a, tar, entry, unconsumed));
+}
+
+/*
+ * Parse a file header for a pax extended archive entry.
+ */
+static int
+header_pax_global(struct archive_read *a, struct tar *tar,
+ struct archive_entry *entry, const void *h, size_t *unconsumed)
+{
+ int err;
+
+ err = read_body_to_string(a, tar, &(tar->pax_global), h, unconsumed);
+ if (err != ARCHIVE_OK)
+ return (err);
+ err = tar_read_header(a, tar, entry, unconsumed);
+ return (err);
+}
+
+static int
+header_pax_extensions(struct archive_read *a, struct tar *tar,
+ struct archive_entry *entry, const void *h, size_t *unconsumed)
+{
+ int err, err2;
+
+ err = read_body_to_string(a, tar, &(tar->pax_header), h, unconsumed);
+ if (err != ARCHIVE_OK)
+ return (err);
+
+ /* Parse the next header. */
+ err = tar_read_header(a, tar, entry, unconsumed);
+ if ((err != ARCHIVE_OK) && (err != ARCHIVE_WARN))
+ return (err);
+
+ /*
+ * TODO: Parse global/default options into 'entry' struct here
+ * before handling file-specific options.
+ *
+ * This design (parse standard header, then overwrite with pax
+ * extended attribute data) usually works well, but isn't ideal;
+ * it would be better to parse the pax extended attributes first
+ * and then skip any fields in the standard header that were
+ * defined in the pax header.
+ */
+ err2 = pax_header(a, tar, entry, tar->pax_header.s);
+ err = err_combine(err, err2);
+ tar->entry_padding = 0x1ff & (-tar->entry_bytes_remaining);
+ return (err);
+}
+
+
+/*
+ * Parse a file header for a Posix "ustar" archive entry. This also
+ * handles "pax" or "extended ustar" entries.
+ */
+static int
+header_ustar(struct archive_read *a, struct tar *tar,
+ struct archive_entry *entry, const void *h)
+{
+ const struct archive_entry_header_ustar *header;
+ struct archive_string *as;
+ int err = ARCHIVE_OK, r;
+
+ header = (const struct archive_entry_header_ustar *)h;
+
+ /* Copy name into an internal buffer to ensure null-termination. */
+ as = &(tar->entry_pathname);
+ if (header->prefix[0]) {
+ archive_strncpy(as, header->prefix, sizeof(header->prefix));
+ if (as->s[archive_strlen(as) - 1] != '/')
+ archive_strappend_char(as, '/');
+ archive_strncat(as, header->name, sizeof(header->name));
+ } else {
+ archive_strncpy(as, header->name, sizeof(header->name));
+ }
+ if (archive_entry_copy_pathname_l(entry, as->s, archive_strlen(as),
+ tar->sconv) != 0) {
+ err = set_conversion_failed_error(a, tar->sconv, "Pathname");
+ if (err == ARCHIVE_FATAL)
+ return (err);
+ }
+
+ /* Handle rest of common fields. */
+ r = header_common(a, tar, entry, h);
+ if (r == ARCHIVE_FATAL)
+ return (r);
+ if (r < err)
+ err = r;
+
+ /* Handle POSIX ustar fields. */
+ if (archive_entry_copy_uname_l(entry,
+ header->uname, sizeof(header->uname), tar->sconv) != 0) {
+ err = set_conversion_failed_error(a, tar->sconv, "Uname");
+ if (err == ARCHIVE_FATAL)
+ return (err);
+ }
+
+ if (archive_entry_copy_gname_l(entry,
+ header->gname, sizeof(header->gname), tar->sconv) != 0) {
+ err = set_conversion_failed_error(a, tar->sconv, "Gname");
+ if (err == ARCHIVE_FATAL)
+ return (err);
+ }
+
+ /* Parse out device numbers only for char and block specials. */
+ if (header->typeflag[0] == '3' || header->typeflag[0] == '4') {
+ archive_entry_set_rdevmajor(entry,
+ tar_atol(header->rdevmajor, sizeof(header->rdevmajor)));
+ archive_entry_set_rdevminor(entry,
+ tar_atol(header->rdevminor, sizeof(header->rdevminor)));
+ }
+
+ tar->entry_padding = 0x1ff & (-tar->entry_bytes_remaining);
+
+ return (err);
+}
+
+
+/*
+ * Parse the pax extended attributes record.
+ *
+ * Returns non-zero if there's an error in the data.
+ */
+static int
+pax_header(struct archive_read *a, struct tar *tar,
+ struct archive_entry *entry, char *attr)
+{
+ size_t attr_length, l, line_length;
+ char *p;
+ char *key, *value;
+ struct archive_string *as;
+ struct archive_string_conv *sconv;
+ int err, err2;
+
+ attr_length = strlen(attr);
+ tar->pax_hdrcharset_binary = 0;
+ archive_string_empty(&(tar->entry_gname));
+ archive_string_empty(&(tar->entry_linkpath));
+ archive_string_empty(&(tar->entry_pathname));
+ archive_string_empty(&(tar->entry_pathname_override));
+ archive_string_empty(&(tar->entry_uname));
+ err = ARCHIVE_OK;
+ while (attr_length > 0) {
+ /* Parse decimal length field at start of line. */
+ line_length = 0;
+ l = attr_length;
+ p = attr; /* Record start of line. */
+ while (l>0) {
+ if (*p == ' ') {
+ p++;
+ l--;
+ break;
+ }
+ if (*p < '0' || *p > '9') {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Ignoring malformed pax extended attributes");
+ return (ARCHIVE_WARN);
+ }
+ line_length *= 10;
+ line_length += *p - '0';
+ if (line_length > 999999) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Rejecting pax extended attribute > 1MB");
+ return (ARCHIVE_WARN);
+ }
+ p++;
+ l--;
+ }
+
+ /*
+ * Parsed length must be no bigger than available data,
+ * at least 1, and the last character of the line must
+ * be '\n'.
+ */
+ if (line_length > attr_length
+ || line_length < 1
+ || attr[line_length - 1] != '\n')
+ {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Ignoring malformed pax extended attribute");
+ return (ARCHIVE_WARN);
+ }
+
+ /* Null-terminate the line. */
+ attr[line_length - 1] = '\0';
+
+ /* Find end of key and null terminate it. */
+ key = p;
+ if (key[0] == '=')
+ return (-1);
+ while (*p && *p != '=')
+ ++p;
+ if (*p == '\0') {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Invalid pax extended attributes");
+ return (ARCHIVE_WARN);
+ }
+ *p = '\0';
+
+ /* Identify null-terminated 'value' portion. */
+ value = p + 1;
+
+ /* Identify this attribute and set it in the entry. */
+ err2 = pax_attribute(a, tar, entry, key, value);
+ if (err2 == ARCHIVE_FATAL)
+ return (err2);
+ err = err_combine(err, err2);
+
+ /* Skip to next line */
+ attr += line_length;
+ attr_length -= line_length;
+ }
+
+ /*
+ * PAX format uses UTF-8 as default charset for its metadata
+ * unless hdrcharset=BINARY is present in its header.
+ * We apply the charset specified by the hdrcharset option only
+ * when the hdrcharset attribute(in PAX header) is BINARY because
+ * we respect the charset described in PAX header and BINARY also
+ * means that metadata(filename,uname and gname) character-set
+ * is unknown.
+ */
+ if (tar->pax_hdrcharset_binary)
+ sconv = tar->opt_sconv;
+ else {
+ sconv = archive_string_conversion_from_charset(
+ &(a->archive), "UTF-8", 1);
+ if (sconv == NULL)
+ return (ARCHIVE_FATAL);
+ if (tar->compat_2x)
+ archive_string_conversion_set_opt(sconv,
+ SCONV_SET_OPT_UTF8_LIBARCHIVE2X);
+ }
+
+ if (archive_strlen(&(tar->entry_gname)) > 0) {
+ if (archive_entry_copy_gname_l(entry, tar->entry_gname.s,
+ archive_strlen(&(tar->entry_gname)), sconv) != 0) {
+ err = set_conversion_failed_error(a, sconv, "Gname");
+ if (err == ARCHIVE_FATAL)
+ return (err);
+ /* Use a converted an original name. */
+ archive_entry_copy_gname(entry, tar->entry_gname.s);
+ }
+ }
+ if (archive_strlen(&(tar->entry_linkpath)) > 0) {
+ if (archive_entry_copy_link_l(entry, tar->entry_linkpath.s,
+ archive_strlen(&(tar->entry_linkpath)), sconv) != 0) {
+ err = set_conversion_failed_error(a, sconv, "Linkname");
+ if (err == ARCHIVE_FATAL)
+ return (err);
+ /* Use a converted an original name. */
+ archive_entry_copy_link(entry, tar->entry_linkpath.s);
+ }
+ }
+ /*
+ * Some extensions (such as the GNU sparse file extensions)
+ * deliberately store a synthetic name under the regular 'path'
+ * attribute and the real file name under a different attribute.
+ * Since we're supposed to not care about the order, we
+ * have no choice but to store all of the various filenames
+ * we find and figure it all out afterwards. This is the
+ * figuring out part.
+ */
+ as = NULL;
+ if (archive_strlen(&(tar->entry_pathname_override)) > 0)
+ as = &(tar->entry_pathname_override);
+ else if (archive_strlen(&(tar->entry_pathname)) > 0)
+ as = &(tar->entry_pathname);
+ if (as != NULL) {
+ if (archive_entry_copy_pathname_l(entry, as->s,
+ archive_strlen(as), sconv) != 0) {
+ err = set_conversion_failed_error(a, sconv, "Pathname");
+ if (err == ARCHIVE_FATAL)
+ return (err);
+ /* Use a converted an original name. */
+ archive_entry_copy_pathname(entry, as->s);
+ }
+ }
+ if (archive_strlen(&(tar->entry_uname)) > 0) {
+ if (archive_entry_copy_uname_l(entry, tar->entry_uname.s,
+ archive_strlen(&(tar->entry_uname)), sconv) != 0) {
+ err = set_conversion_failed_error(a, sconv, "Uname");
+ if (err == ARCHIVE_FATAL)
+ return (err);
+ /* Use a converted an original name. */
+ archive_entry_copy_uname(entry, tar->entry_uname.s);
+ }
+ }
+ return (err);
+}
+
+static int
+pax_attribute_xattr(struct archive_entry *entry,
+ char *name, char *value)
+{
+ char *name_decoded;
+ void *value_decoded;
+ size_t value_len;
+
+ if (strlen(name) < 18 || (memcmp(name, "LIBARCHIVE.xattr.", 17)) != 0)
+ return 3;
+
+ name += 17;
+
+ /* URL-decode name */
+ name_decoded = url_decode(name);
+ if (name_decoded == NULL)
+ return 2;
+
+ /* Base-64 decode value */
+ value_decoded = base64_decode(value, strlen(value), &value_len);
+ if (value_decoded == NULL) {
+ free(name_decoded);
+ return 1;
+ }
+
+ archive_entry_xattr_add_entry(entry, name_decoded,
+ value_decoded, value_len);
+
+ free(name_decoded);
+ free(value_decoded);
+ return 0;
+}
+
+/*
+ * Parse a single key=value attribute. key/value pointers are
+ * assumed to point into reasonably long-lived storage.
+ *
+ * Note that POSIX reserves all-lowercase keywords. Vendor-specific
+ * extensions should always have keywords of the form "VENDOR.attribute"
+ * In particular, it's quite feasible to support many different
+ * vendor extensions here. I'm using "LIBARCHIVE" for extensions
+ * unique to this library.
+ *
+ * Investigate other vendor-specific extensions and see if
+ * any of them look useful.
+ */
+static int
+pax_attribute(struct archive_read *a, struct tar *tar,
+ struct archive_entry *entry, char *key, char *value)
+{
+ int64_t s;
+ long n;
+ int err = ARCHIVE_OK, r;
+
+ switch (key[0]) {
+ case 'G':
+ /* GNU "0.0" sparse pax format. */
+ if (strcmp(key, "GNU.sparse.numblocks") == 0) {
+ tar->sparse_offset = -1;
+ tar->sparse_numbytes = -1;
+ tar->sparse_gnu_major = 0;
+ tar->sparse_gnu_minor = 0;
+ }
+ if (strcmp(key, "GNU.sparse.offset") == 0) {
+ tar->sparse_offset = tar_atol10(value, strlen(value));
+ if (tar->sparse_numbytes != -1) {
+ if (gnu_add_sparse_entry(a, tar,
+ tar->sparse_offset, tar->sparse_numbytes)
+ != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ tar->sparse_offset = -1;
+ tar->sparse_numbytes = -1;
+ }
+ }
+ if (strcmp(key, "GNU.sparse.numbytes") == 0) {
+ tar->sparse_numbytes = tar_atol10(value, strlen(value));
+ if (tar->sparse_numbytes != -1) {
+ if (gnu_add_sparse_entry(a, tar,
+ tar->sparse_offset, tar->sparse_numbytes)
+ != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ tar->sparse_offset = -1;
+ tar->sparse_numbytes = -1;
+ }
+ }
+ if (strcmp(key, "GNU.sparse.size") == 0) {
+ tar->realsize = tar_atol10(value, strlen(value));
+ archive_entry_set_size(entry, tar->realsize);
+ }
+
+ /* GNU "0.1" sparse pax format. */
+ if (strcmp(key, "GNU.sparse.map") == 0) {
+ tar->sparse_gnu_major = 0;
+ tar->sparse_gnu_minor = 1;
+ if (gnu_sparse_01_parse(a, tar, value) != ARCHIVE_OK)
+ return (ARCHIVE_WARN);
+ }
+
+ /* GNU "1.0" sparse pax format */
+ if (strcmp(key, "GNU.sparse.major") == 0) {
+ tar->sparse_gnu_major = tar_atol10(value, strlen(value));
+ tar->sparse_gnu_pending = 1;
+ }
+ if (strcmp(key, "GNU.sparse.minor") == 0) {
+ tar->sparse_gnu_minor = tar_atol10(value, strlen(value));
+ tar->sparse_gnu_pending = 1;
+ }
+ if (strcmp(key, "GNU.sparse.name") == 0) {
+ /*
+ * The real filename; when storing sparse
+ * files, GNU tar puts a synthesized name into
+ * the regular 'path' attribute in an attempt
+ * to limit confusion. ;-)
+ */
+ archive_strcpy(&(tar->entry_pathname_override), value);
+ }
+ if (strcmp(key, "GNU.sparse.realsize") == 0) {
+ tar->realsize = tar_atol10(value, strlen(value));
+ archive_entry_set_size(entry, tar->realsize);
+ }
+ break;
+ case 'L':
+ /* Our extensions */
+/* TODO: Handle arbitrary extended attributes... */
+/*
+ if (strcmp(key, "LIBARCHIVE.xxxxxxx") == 0)
+ archive_entry_set_xxxxxx(entry, value);
+*/
+ if (strcmp(key, "LIBARCHIVE.creationtime") == 0) {
+ pax_time(value, &s, &n);
+ archive_entry_set_birthtime(entry, s, n);
+ }
+ if (memcmp(key, "LIBARCHIVE.xattr.", 17) == 0)
+ pax_attribute_xattr(entry, key, value);
+ break;
+ case 'S':
+ /* We support some keys used by the "star" archiver */
+ if (strcmp(key, "SCHILY.acl.access") == 0) {
+ if (tar->sconv_acl == NULL) {
+ tar->sconv_acl =
+ archive_string_conversion_from_charset(
+ &(a->archive), "UTF-8", 1);
+ if (tar->sconv_acl == NULL)
+ return (ARCHIVE_FATAL);
+ }
+
+ r = archive_acl_parse_l(archive_entry_acl(entry),
+ value, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
+ tar->sconv_acl);
+ if (r != ARCHIVE_OK) {
+ err = r;
+ if (err == ARCHIVE_FATAL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for "
+ "SCHILY.acl.access");
+ return (err);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Parse error: SCHILY.acl.access");
+ }
+ } else if (strcmp(key, "SCHILY.acl.default") == 0) {
+ if (tar->sconv_acl == NULL) {
+ tar->sconv_acl =
+ archive_string_conversion_from_charset(
+ &(a->archive), "UTF-8", 1);
+ if (tar->sconv_acl == NULL)
+ return (ARCHIVE_FATAL);
+ }
+
+ r = archive_acl_parse_l(archive_entry_acl(entry),
+ value, ARCHIVE_ENTRY_ACL_TYPE_DEFAULT,
+ tar->sconv_acl);
+ if (r != ARCHIVE_OK) {
+ err = r;
+ if (err == ARCHIVE_FATAL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for "
+ "SCHILY.acl.default");
+ return (err);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Parse error: SCHILY.acl.default");
+ }
+ } else if (strcmp(key, "SCHILY.devmajor") == 0) {
+ archive_entry_set_rdevmajor(entry,
+ tar_atol10(value, strlen(value)));
+ } else if (strcmp(key, "SCHILY.devminor") == 0) {
+ archive_entry_set_rdevminor(entry,
+ tar_atol10(value, strlen(value)));
+ } else if (strcmp(key, "SCHILY.fflags") == 0) {
+ archive_entry_copy_fflags_text(entry, value);
+ } else if (strcmp(key, "SCHILY.dev") == 0) {
+ archive_entry_set_dev(entry,
+ tar_atol10(value, strlen(value)));
+ } else if (strcmp(key, "SCHILY.ino") == 0) {
+ archive_entry_set_ino(entry,
+ tar_atol10(value, strlen(value)));
+ } else if (strcmp(key, "SCHILY.nlink") == 0) {
+ archive_entry_set_nlink(entry,
+ tar_atol10(value, strlen(value)));
+ } else if (strcmp(key, "SCHILY.realsize") == 0) {
+ tar->realsize = tar_atol10(value, strlen(value));
+ archive_entry_set_size(entry, tar->realsize);
+ } else if (strcmp(key, "SUN.holesdata") == 0) {
+ /* A Solaris extension for sparse. */
+ r = solaris_sparse_parse(a, tar, entry, value);
+ if (r < err) {
+ if (r == ARCHIVE_FATAL)
+ return (r);
+ err = r;
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Parse error: SUN.holesdata");
+ }
+ }
+ break;
+ case 'a':
+ if (strcmp(key, "atime") == 0) {
+ pax_time(value, &s, &n);
+ archive_entry_set_atime(entry, s, n);
+ }
+ break;
+ case 'c':
+ if (strcmp(key, "ctime") == 0) {
+ pax_time(value, &s, &n);
+ archive_entry_set_ctime(entry, s, n);
+ } else if (strcmp(key, "charset") == 0) {
+ /* TODO: Publish charset information in entry. */
+ } else if (strcmp(key, "comment") == 0) {
+ /* TODO: Publish comment in entry. */
+ }
+ break;
+ case 'g':
+ if (strcmp(key, "gid") == 0) {
+ archive_entry_set_gid(entry,
+ tar_atol10(value, strlen(value)));
+ } else if (strcmp(key, "gname") == 0) {
+ archive_strcpy(&(tar->entry_gname), value);
+ }
+ break;
+ case 'h':
+ if (strcmp(key, "hdrcharset") == 0) {
+ if (strcmp(value, "BINARY") == 0)
+ /* Binary mode. */
+ tar->pax_hdrcharset_binary = 1;
+ else if (strcmp(value, "ISO-IR 10646 2000 UTF-8") == 0)
+ tar->pax_hdrcharset_binary = 0;
+ }
+ break;
+ case 'l':
+ /* pax interchange doesn't distinguish hardlink vs. symlink. */
+ if (strcmp(key, "linkpath") == 0) {
+ archive_strcpy(&(tar->entry_linkpath), value);
+ }
+ break;
+ case 'm':
+ if (strcmp(key, "mtime") == 0) {
+ pax_time(value, &s, &n);
+ archive_entry_set_mtime(entry, s, n);
+ }
+ break;
+ case 'p':
+ if (strcmp(key, "path") == 0) {
+ archive_strcpy(&(tar->entry_pathname), value);
+ }
+ break;
+ case 'r':
+ /* POSIX has reserved 'realtime.*' */
+ break;
+ case 's':
+ /* POSIX has reserved 'security.*' */
+ /* Someday: if (strcmp(key, "security.acl") == 0) { ... } */
+ if (strcmp(key, "size") == 0) {
+ /* "size" is the size of the data in the entry. */
+ tar->entry_bytes_remaining
+ = tar_atol10(value, strlen(value));
+ /*
+ * But, "size" is not necessarily the size of
+ * the file on disk; if this is a sparse file,
+ * the disk size may have already been set from
+ * GNU.sparse.realsize or GNU.sparse.size or
+ * an old GNU header field or SCHILY.realsize
+ * or ....
+ */
+ if (tar->realsize < 0) {
+ archive_entry_set_size(entry,
+ tar->entry_bytes_remaining);
+ tar->realsize
+ = tar->entry_bytes_remaining;
+ }
+ }
+ break;
+ case 'u':
+ if (strcmp(key, "uid") == 0) {
+ archive_entry_set_uid(entry,
+ tar_atol10(value, strlen(value)));
+ } else if (strcmp(key, "uname") == 0) {
+ archive_strcpy(&(tar->entry_uname), value);
+ }
+ break;
+ }
+ return (err);
+}
+
+
+
+/*
+ * parse a decimal time value, which may include a fractional portion
+ */
+static void
+pax_time(const char *p, int64_t *ps, long *pn)
+{
+ char digit;
+ int64_t s;
+ unsigned long l;
+ int sign;
+ int64_t limit, last_digit_limit;
+
+ limit = INT64_MAX / 10;
+ last_digit_limit = INT64_MAX % 10;
+
+ s = 0;
+ sign = 1;
+ if (*p == '-') {
+ sign = -1;
+ p++;
+ }
+ while (*p >= '0' && *p <= '9') {
+ digit = *p - '0';
+ if (s > limit ||
+ (s == limit && digit > last_digit_limit)) {
+ s = INT64_MAX;
+ break;
+ }
+ s = (s * 10) + digit;
+ ++p;
+ }
+
+ *ps = s * sign;
+
+ /* Calculate nanoseconds. */
+ *pn = 0;
+
+ if (*p != '.')
+ return;
+
+ l = 100000000UL;
+ do {
+ ++p;
+ if (*p >= '0' && *p <= '9')
+ *pn += (*p - '0') * l;
+ else
+ break;
+ } while (l /= 10);
+}
+
+/*
+ * Parse GNU tar header
+ */
+static int
+header_gnutar(struct archive_read *a, struct tar *tar,
+ struct archive_entry *entry, const void *h, size_t *unconsumed)
+{
+ const struct archive_entry_header_gnutar *header;
+ int64_t t;
+ int err = ARCHIVE_OK;
+
+ /*
+ * GNU header is like POSIX ustar, except 'prefix' is
+ * replaced with some other fields. This also means the
+ * filename is stored as in old-style archives.
+ */
+
+ /* Grab fields common to all tar variants. */
+ err = header_common(a, tar, entry, h);
+ if (err == ARCHIVE_FATAL)
+ return (err);
+
+ /* Copy filename over (to ensure null termination). */
+ header = (const struct archive_entry_header_gnutar *)h;
+ if (archive_entry_copy_pathname_l(entry,
+ header->name, sizeof(header->name), tar->sconv) != 0) {
+ err = set_conversion_failed_error(a, tar->sconv, "Pathname");
+ if (err == ARCHIVE_FATAL)
+ return (err);
+ }
+
+ /* Fields common to ustar and GNU */
+ /* XXX Can the following be factored out since it's common
+ * to ustar and gnu tar? Is it okay to move it down into
+ * header_common, perhaps? */
+ if (archive_entry_copy_uname_l(entry,
+ header->uname, sizeof(header->uname), tar->sconv) != 0) {
+ err = set_conversion_failed_error(a, tar->sconv, "Uname");
+ if (err == ARCHIVE_FATAL)
+ return (err);
+ }
+
+ if (archive_entry_copy_gname_l(entry,
+ header->gname, sizeof(header->gname), tar->sconv) != 0) {
+ err = set_conversion_failed_error(a, tar->sconv, "Gname");
+ if (err == ARCHIVE_FATAL)
+ return (err);
+ }
+
+ /* Parse out device numbers only for char and block specials */
+ if (header->typeflag[0] == '3' || header->typeflag[0] == '4') {
+ archive_entry_set_rdevmajor(entry,
+ tar_atol(header->rdevmajor, sizeof(header->rdevmajor)));
+ archive_entry_set_rdevminor(entry,
+ tar_atol(header->rdevminor, sizeof(header->rdevminor)));
+ } else
+ archive_entry_set_rdev(entry, 0);
+
+ tar->entry_padding = 0x1ff & (-tar->entry_bytes_remaining);
+
+ /* Grab GNU-specific fields. */
+ t = tar_atol(header->atime, sizeof(header->atime));
+ if (t > 0)
+ archive_entry_set_atime(entry, t, 0);
+ t = tar_atol(header->ctime, sizeof(header->ctime));
+ if (t > 0)
+ archive_entry_set_ctime(entry, t, 0);
+
+ if (header->realsize[0] != 0) {
+ tar->realsize
+ = tar_atol(header->realsize, sizeof(header->realsize));
+ archive_entry_set_size(entry, tar->realsize);
+ }
+
+ if (header->sparse[0].offset[0] != 0) {
+ if (gnu_sparse_old_read(a, tar, header, unconsumed)
+ != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ } else {
+ if (header->isextended[0] != 0) {
+ /* XXX WTF? XXX */
+ }
+ }
+
+ return (err);
+}
+
+static int
+gnu_add_sparse_entry(struct archive_read *a, struct tar *tar,
+ int64_t offset, int64_t remaining)
+{
+ struct sparse_block *p;
+
+ p = (struct sparse_block *)malloc(sizeof(*p));
+ if (p == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
+ memset(p, 0, sizeof(*p));
+ if (tar->sparse_last != NULL)
+ tar->sparse_last->next = p;
+ else
+ tar->sparse_list = p;
+ tar->sparse_last = p;
+ p->offset = offset;
+ p->remaining = remaining;
+ return (ARCHIVE_OK);
+}
+
+static void
+gnu_clear_sparse_list(struct tar *tar)
+{
+ struct sparse_block *p;
+
+ while (tar->sparse_list != NULL) {
+ p = tar->sparse_list;
+ tar->sparse_list = p->next;
+ free(p);
+ }
+ tar->sparse_last = NULL;
+}
+
+/*
+ * GNU tar old-format sparse data.
+ *
+ * GNU old-format sparse data is stored in a fixed-field
+ * format. Offset/size values are 11-byte octal fields (same
+ * format as 'size' field in ustart header). These are
+ * stored in the header, allocating subsequent header blocks
+ * as needed. Extending the header in this way is a pretty
+ * severe POSIX violation; this design has earned GNU tar a
+ * lot of criticism.
+ */
+
+static int
+gnu_sparse_old_read(struct archive_read *a, struct tar *tar,
+ const struct archive_entry_header_gnutar *header, size_t *unconsumed)
+{
+ ssize_t bytes_read;
+ const void *data;
+ struct extended {
+ struct gnu_sparse sparse[21];
+ char isextended[1];
+ char padding[7];
+ };
+ const struct extended *ext;
+
+ if (gnu_sparse_old_parse(a, tar, header->sparse, 4) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ if (header->isextended[0] == 0)
+ return (ARCHIVE_OK);
+
+ do {
+ tar_flush_unconsumed(a, unconsumed);
+ data = __archive_read_ahead(a, 512, &bytes_read);
+ if (bytes_read < 0)
+ return (ARCHIVE_FATAL);
+ if (bytes_read < 512) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated tar archive "
+ "detected while reading sparse file data");
+ return (ARCHIVE_FATAL);
+ }
+ *unconsumed = 512;
+ ext = (const struct extended *)data;
+ if (gnu_sparse_old_parse(a, tar, ext->sparse, 21) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ } while (ext->isextended[0] != 0);
+ if (tar->sparse_list != NULL)
+ tar->entry_offset = tar->sparse_list->offset;
+ return (ARCHIVE_OK);
+}
+
+static int
+gnu_sparse_old_parse(struct archive_read *a, struct tar *tar,
+ const struct gnu_sparse *sparse, int length)
+{
+ while (length > 0 && sparse->offset[0] != 0) {
+ if (gnu_add_sparse_entry(a, tar,
+ tar_atol(sparse->offset, sizeof(sparse->offset)),
+ tar_atol(sparse->numbytes, sizeof(sparse->numbytes)))
+ != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ sparse++;
+ length--;
+ }
+ return (ARCHIVE_OK);
+}
+
+/*
+ * GNU tar sparse format 0.0
+ *
+ * Beginning with GNU tar 1.15, sparse files are stored using
+ * information in the pax extended header. The GNU tar maintainers
+ * have gone through a number of variations in the process of working
+ * out this scheme; fortunately, they're all numbered.
+ *
+ * Sparse format 0.0 uses attribute GNU.sparse.numblocks to store the
+ * number of blocks, and GNU.sparse.offset/GNU.sparse.numbytes to
+ * store offset/size for each block. The repeated instances of these
+ * latter fields violate the pax specification (which frowns on
+ * duplicate keys), so this format was quickly replaced.
+ */
+
+/*
+ * GNU tar sparse format 0.1
+ *
+ * This version replaced the offset/numbytes attributes with
+ * a single "map" attribute that stored a list of integers. This
+ * format had two problems: First, the "map" attribute could be very
+ * long, which caused problems for some implementations. More
+ * importantly, the sparse data was lost when extracted by archivers
+ * that didn't recognize this extension.
+ */
+
+static int
+gnu_sparse_01_parse(struct archive_read *a, struct tar *tar, const char *p)
+{
+ const char *e;
+ int64_t offset = -1, size = -1;
+
+ for (;;) {
+ e = p;
+ while (*e != '\0' && *e != ',') {
+ if (*e < '0' || *e > '9')
+ return (ARCHIVE_WARN);
+ e++;
+ }
+ if (offset < 0) {
+ offset = tar_atol10(p, e - p);
+ if (offset < 0)
+ return (ARCHIVE_WARN);
+ } else {
+ size = tar_atol10(p, e - p);
+ if (size < 0)
+ return (ARCHIVE_WARN);
+ if (gnu_add_sparse_entry(a, tar, offset, size)
+ != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ offset = -1;
+ }
+ if (*e == '\0')
+ return (ARCHIVE_OK);
+ p = e + 1;
+ }
+}
+
+/*
+ * GNU tar sparse format 1.0
+ *
+ * The idea: The offset/size data is stored as a series of base-10
+ * ASCII numbers prepended to the file data, so that dearchivers that
+ * don't support this format will extract the block map along with the
+ * data and a separate post-process can restore the sparseness.
+ *
+ * Unfortunately, GNU tar 1.16 had a bug that added unnecessary
+ * padding to the body of the file when using this format. GNU tar
+ * 1.17 corrected this bug without bumping the version number, so
+ * it's not possible to support both variants. This code supports
+ * the later variant at the expense of not supporting the former.
+ *
+ * This variant also replaced GNU.sparse.size with GNU.sparse.realsize
+ * and introduced the GNU.sparse.major/GNU.sparse.minor attributes.
+ */
+
+/*
+ * Read the next line from the input, and parse it as a decimal
+ * integer followed by '\n'. Returns positive integer value or
+ * negative on error.
+ */
+static int64_t
+gnu_sparse_10_atol(struct archive_read *a, struct tar *tar,
+ int64_t *remaining, size_t *unconsumed)
+{
+ int64_t l, limit, last_digit_limit;
+ const char *p;
+ ssize_t bytes_read;
+ int base, digit;
+
+ base = 10;
+ limit = INT64_MAX / base;
+ last_digit_limit = INT64_MAX % base;
+
+ /*
+ * Skip any lines starting with '#'; GNU tar specs
+ * don't require this, but they should.
+ */
+ do {
+ bytes_read = readline(a, tar, &p, tar_min(*remaining, 100), unconsumed);
+ if (bytes_read <= 0)
+ return (ARCHIVE_FATAL);
+ *remaining -= bytes_read;
+ } while (p[0] == '#');
+
+ l = 0;
+ while (bytes_read > 0) {
+ if (*p == '\n')
+ return (l);
+ if (*p < '0' || *p >= '0' + base)
+ return (ARCHIVE_WARN);
+ digit = *p - '0';
+ if (l > limit || (l == limit && digit > last_digit_limit))
+ l = INT64_MAX; /* Truncate on overflow. */
+ else
+ l = (l * base) + digit;
+ p++;
+ bytes_read--;
+ }
+ /* TODO: Error message. */
+ return (ARCHIVE_WARN);
+}
+
+/*
+ * Returns length (in bytes) of the sparse data description
+ * that was read.
+ */
+static ssize_t
+gnu_sparse_10_read(struct archive_read *a, struct tar *tar, size_t *unconsumed)
+{
+ ssize_t bytes_read;
+ int entries;
+ int64_t offset, size, to_skip, remaining;
+
+ /* Clear out the existing sparse list. */
+ gnu_clear_sparse_list(tar);
+
+ remaining = tar->entry_bytes_remaining;
+
+ /* Parse entries. */
+ entries = gnu_sparse_10_atol(a, tar, &remaining, unconsumed);
+ if (entries < 0)
+ return (ARCHIVE_FATAL);
+ /* Parse the individual entries. */
+ while (entries-- > 0) {
+ /* Parse offset/size */
+ offset = gnu_sparse_10_atol(a, tar, &remaining, unconsumed);
+ if (offset < 0)
+ return (ARCHIVE_FATAL);
+ size = gnu_sparse_10_atol(a, tar, &remaining, unconsumed);
+ if (size < 0)
+ return (ARCHIVE_FATAL);
+ /* Add a new sparse entry. */
+ if (gnu_add_sparse_entry(a, tar, offset, size) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
+ /* Skip rest of block... */
+ tar_flush_unconsumed(a, unconsumed);
+ bytes_read = tar->entry_bytes_remaining - remaining;
+ to_skip = 0x1ff & -bytes_read;
+ if (to_skip != __archive_read_consume(a, to_skip))
+ return (ARCHIVE_FATAL);
+ return (bytes_read + to_skip);
+}
+
+/*
+ * Solaris pax extension for a sparse file. This is recorded with the
+ * data and hole pairs. The way recording sparse infomation by Solaris'
+ * pax simply indicates where data and sparse are, so the stored contents
+ * consist of both data and hole.
+ */
+static int
+solaris_sparse_parse(struct archive_read *a, struct tar *tar,
+ struct archive_entry *entry, const char *p)
+{
+ const char *e;
+ int64_t start, end;
+ int hole = 1;
+
+ end = 0;
+ if (*p == ' ')
+ p++;
+ else
+ return (ARCHIVE_WARN);
+ for (;;) {
+ e = p;
+ while (*e != '\0' && *e != ' ') {
+ if (*e < '0' || *e > '9')
+ return (ARCHIVE_WARN);
+ e++;
+ }
+ start = end;
+ end = tar_atol10(p, e - p);
+ if (end < 0)
+ return (ARCHIVE_WARN);
+ if (start < end) {
+ if (gnu_add_sparse_entry(a, tar, start,
+ end - start) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ tar->sparse_last->hole = hole;
+ }
+ if (*e == '\0')
+ return (ARCHIVE_OK);
+ p = e + 1;
+ hole = hole == 0;
+ }
+}
+
+/*-
+ * Convert text->integer.
+ *
+ * Traditional tar formats (including POSIX) specify base-8 for
+ * all of the standard numeric fields. This is a significant limitation
+ * in practice:
+ * = file size is limited to 8GB
+ * = rdevmajor and rdevminor are limited to 21 bits
+ * = uid/gid are limited to 21 bits
+ *
+ * There are two workarounds for this:
+ * = pax extended headers, which use variable-length string fields
+ * = GNU tar and STAR both allow either base-8 or base-256 in
+ * most fields. The high bit is set to indicate base-256.
+ *
+ * On read, this implementation supports both extensions.
+ */
+static int64_t
+tar_atol(const char *p, unsigned char_cnt)
+{
+ /*
+ * Technically, GNU tar considers a field to be in base-256
+ * only if the first byte is 0xff or 0x80.
+ */
+ if (*p & 0x80)
+ return (tar_atol256(p, char_cnt));
+ return (tar_atol8(p, char_cnt));
+}
+
+/*
+ * Note that this implementation does not (and should not!) obey
+ * locale settings; you cannot simply substitute strtol here, since
+ * it does obey locale.
+ */
+static int64_t
+tar_atol8(const char *p, unsigned char_cnt)
+{
+ int64_t l, limit, last_digit_limit;
+ int digit, sign, base;
+
+ base = 8;
+ limit = INT64_MAX / base;
+ last_digit_limit = INT64_MAX % base;
+
+ while (*p == ' ' || *p == '\t')
+ p++;
+ if (*p == '-') {
+ sign = -1;
+ p++;
+ } else
+ sign = 1;
+
+ l = 0;
+ 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;
+ }
+ l = (l * base) + digit;
+ digit = *++p - '0';
+ }
+ return (sign < 0) ? -l : l;
+}
+
+/*
+ * Note that this implementation does not (and should not!) obey
+ * locale settings; you cannot simply substitute strtol here, since
+ * it does obey locale.
+ */
+static int64_t
+tar_atol10(const char *p, unsigned char_cnt)
+{
+ int64_t l, limit, last_digit_limit;
+ int base, digit, sign;
+
+ base = 10;
+ limit = INT64_MAX / base;
+ last_digit_limit = INT64_MAX % base;
+
+ while (*p == ' ' || *p == '\t')
+ p++;
+ if (*p == '-') {
+ sign = -1;
+ p++;
+ } else
+ sign = 1;
+
+ l = 0;
+ 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;
+ }
+ l = (l * base) + digit;
+ digit = *++p - '0';
+ }
+ return (sign < 0) ? -l : l;
+}
+
+/*
+ * 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.
+ */
+static int64_t
+tar_atol256(const char *_p, unsigned char_cnt)
+{
+ int64_t l, upper_limit, lower_limit;
+ const unsigned char *p = (const unsigned char *)_p;
+
+ upper_limit = INT64_MAX / 256;
+ lower_limit = INT64_MIN / 256;
+
+ /* 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++);
+ 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++);
+ }
+ return (l);
+}
+
+/*
+ * Returns length of line (including trailing newline)
+ * or negative on error. 'start' argument is updated to
+ * point to first character of line. This avoids copying
+ * when possible.
+ */
+static ssize_t
+readline(struct archive_read *a, struct tar *tar, const char **start,
+ ssize_t limit, size_t *unconsumed)
+{
+ ssize_t bytes_read;
+ ssize_t total_size = 0;
+ const void *t;
+ const char *s;
+ void *p;
+
+ tar_flush_unconsumed(a, unconsumed);
+
+ t = __archive_read_ahead(a, 1, &bytes_read);
+ if (bytes_read <= 0)
+ return (ARCHIVE_FATAL);
+ s = t; /* Start of line? */
+ p = memchr(t, '\n', bytes_read);
+ /* If we found '\n' in the read buffer, return pointer to that. */
+ if (p != NULL) {
+ bytes_read = 1 + ((const char *)p) - s;
+ if (bytes_read > limit) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Line too long");
+ return (ARCHIVE_FATAL);
+ }
+ *unconsumed = bytes_read;
+ *start = s;
+ return (bytes_read);
+ }
+ *unconsumed = bytes_read;
+ /* Otherwise, we need to accumulate in a line buffer. */
+ for (;;) {
+ if (total_size + bytes_read > limit) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Line too long");
+ return (ARCHIVE_FATAL);
+ }
+ if (archive_string_ensure(&tar->line, total_size + bytes_read) == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate working buffer");
+ return (ARCHIVE_FATAL);
+ }
+ memcpy(tar->line.s + total_size, t, bytes_read);
+ tar_flush_unconsumed(a, unconsumed);
+ total_size += bytes_read;
+ /* If we found '\n', clean up and return. */
+ if (p != NULL) {
+ *start = tar->line.s;
+ return (total_size);
+ }
+ /* Read some more. */
+ t = __archive_read_ahead(a, 1, &bytes_read);
+ 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;
+ }
+ *unconsumed = bytes_read;
+ }
+}
+
+/*
+ * base64_decode - Base64 decode
+ *
+ * This accepts most variations of base-64 encoding, including:
+ * * with or without line breaks
+ * * with or without the final group padded with '=' or '_' characters
+ * (The most economical Base-64 variant does not pad the last group and
+ * omits line breaks; RFC1341 used for MIME requires both.)
+ */
+static char *
+base64_decode(const char *s, size_t len, size_t *out_len)
+{
+ static const unsigned char digits[64] = {
+ 'A','B','C','D','E','F','G','H','I','J','K','L','M','N',
+ 'O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b',
+ 'c','d','e','f','g','h','i','j','k','l','m','n','o','p',
+ 'q','r','s','t','u','v','w','x','y','z','0','1','2','3',
+ '4','5','6','7','8','9','+','/' };
+ static unsigned char decode_table[128];
+ char *out, *d;
+ const unsigned char *src = (const unsigned char *)s;
+
+ /* If the decode table is not yet initialized, prepare it. */
+ if (decode_table[digits[1]] != 1) {
+ unsigned i;
+ memset(decode_table, 0xff, sizeof(decode_table));
+ for (i = 0; i < sizeof(digits); i++)
+ decode_table[digits[i]] = i;
+ }
+
+ /* Allocate enough space to hold the entire output. */
+ /* Note that we may not use all of this... */
+ out = (char *)malloc(len - len / 4 + 1);
+ if (out == NULL) {
+ *out_len = 0;
+ return (NULL);
+ }
+ d = out;
+
+ while (len > 0) {
+ /* Collect the next group of (up to) four characters. */
+ int v = 0;
+ int group_size = 0;
+ while (group_size < 4 && len > 0) {
+ /* '=' or '_' padding indicates final group. */
+ if (*src == '=' || *src == '_') {
+ len = 0;
+ break;
+ }
+ /* Skip illegal characters (including line breaks) */
+ if (*src > 127 || *src < 32
+ || decode_table[*src] == 0xff) {
+ len--;
+ src++;
+ continue;
+ }
+ v <<= 6;
+ v |= decode_table[*src++];
+ len --;
+ group_size++;
+ }
+ /* Align a short group properly. */
+ v <<= 6 * (4 - group_size);
+ /* Unpack the group we just collected. */
+ switch (group_size) {
+ case 4: d[2] = v & 0xff;
+ /* FALLTHROUGH */
+ case 3: d[1] = (v >> 8) & 0xff;
+ /* FALLTHROUGH */
+ case 2: d[0] = (v >> 16) & 0xff;
+ break;
+ case 1: /* this is invalid! */
+ break;
+ }
+ d += group_size * 3 / 4;
+ }
+
+ *out_len = d - out;
+ return (out);
+}
+
+static char *
+url_decode(const char *in)
+{
+ char *out, *d;
+ const char *s;
+
+ out = (char *)malloc(strlen(in) + 1);
+ if (out == NULL)
+ return (NULL);
+ for (s = in, d = out; *s != '\0'; ) {
+ if (s[0] == '%' && s[1] != '\0' && s[2] != '\0') {
+ /* Try to convert % escape */
+ int digit1 = tohex(s[1]);
+ int digit2 = tohex(s[2]);
+ if (digit1 >= 0 && digit2 >= 0) {
+ /* Looks good, consume three chars */
+ s += 3;
+ /* Convert output */
+ *d++ = ((digit1 << 4) | digit2);
+ continue;
+ }
+ /* Else fall through and treat '%' as normal char */
+ }
+ *d++ = *s++;
+ }
+ *d = '\0';
+ return (out);
+}
+
+static int
+tohex(int c)
+{
+ if (c >= '0' && c <= '9')
+ return (c - '0');
+ else if (c >= 'A' && c <= 'F')
+ return (c - 'A' + 10);
+ else if (c >= 'a' && c <= 'f')
+ return (c - 'a' + 10);
+ else
+ return (-1);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c
new file mode 100644
index 000000000..0834e6fc3
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c
@@ -0,0 +1,3324 @@
+/*-
+ * Copyright (c) 2009 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
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_LIBXML_XMLREADER_H
+#include <libxml/xmlreader.h>
+#elif HAVE_BSDXML_H
+#include <bsdxml.h>
+#elif HAVE_EXPAT_H
+#include <expat.h>
+#endif
+#ifdef HAVE_BZLIB_H
+#include <cm_bzlib.h>
+#endif
+#if HAVE_LZMA_H
+#include <lzma.h>
+#elif HAVE_LZMADEC_H
+#include <lzmadec.h>
+#endif
+#ifdef HAVE_ZLIB_H
+#include <cm_zlib.h>
+#endif
+
+#include "archive.h"
+#include "archive_crypto_private.h"
+#include "archive_endian.h"
+#include "archive_entry.h"
+#include "archive_entry_locale.h"
+#include "archive_private.h"
+#include "archive_read_private.h"
+
+#if (!defined(HAVE_LIBXML_XMLREADER_H) && \
+ !defined(HAVE_BSDXML_H) && !defined(HAVE_EXPAT_H)) ||\
+ !defined(HAVE_ZLIB_H) || \
+ !defined(ARCHIVE_HAS_MD5) || !defined(ARCHIVE_HAS_SHA1)
+/*
+ * xar needs several external libraries.
+ * o libxml2 or expat --- XML parser
+ * o openssl or MD5/SHA1 hash function
+ * o zlib
+ * o bzlib2 (option)
+ * o liblzma (option)
+ */
+int
+archive_read_support_format_xar(struct archive *_a)
+{
+ struct archive_read *a = (struct archive_read *)_a;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_xar");
+
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Xar not supported on this platform");
+ return (ARCHIVE_WARN);
+}
+
+#else /* Support xar format */
+
+/* #define DEBUG 1 */
+/* #define DEBUG_PRINT_TOC 1 */
+#if DEBUG_PRINT_TOC
+#define PRINT_TOC(d, outbytes) do { \
+ unsigned char *x = (unsigned char *)(uintptr_t)d; \
+ unsigned char c = x[outbytes-1]; \
+ x[outbytes - 1] = 0; \
+ fprintf(stderr, "%s", x); \
+ fprintf(stderr, "%c", c); \
+ x[outbytes - 1] = c; \
+} while (0)
+#else
+#define PRINT_TOC(d, outbytes)
+#endif
+
+#define HEADER_MAGIC 0x78617221
+#define HEADER_SIZE 28
+#define HEADER_VERSION 1
+#define CKSUM_NONE 0
+#define CKSUM_SHA1 1
+#define CKSUM_MD5 2
+
+#define MD5_SIZE 16
+#define SHA1_SIZE 20
+#define MAX_SUM_SIZE 20
+
+enum enctype {
+ NONE,
+ GZIP,
+ BZIP2,
+ LZMA,
+ XZ,
+};
+
+struct chksumval {
+ int alg;
+ size_t len;
+ unsigned char val[MAX_SUM_SIZE];
+};
+
+struct chksumwork {
+ int alg;
+#ifdef ARCHIVE_HAS_MD5
+ archive_md5_ctx md5ctx;
+#endif
+#ifdef ARCHIVE_HAS_SHA1
+ archive_sha1_ctx sha1ctx;
+#endif
+};
+
+struct xattr {
+ struct xattr *next;
+ struct archive_string name;
+ uint64_t id;
+ uint64_t length;
+ uint64_t offset;
+ uint64_t size;
+ enum enctype encoding;
+ struct chksumval a_sum;
+ struct chksumval e_sum;
+ struct archive_string fstype;
+};
+
+struct xar_file {
+ struct xar_file *next;
+ struct xar_file *hdnext;
+ struct xar_file *parent;
+ int subdirs;
+
+ unsigned int has;
+#define HAS_DATA 0x00001
+#define HAS_PATHNAME 0x00002
+#define HAS_SYMLINK 0x00004
+#define HAS_TIME 0x00008
+#define HAS_UID 0x00010
+#define HAS_GID 0x00020
+#define HAS_MODE 0x00040
+#define HAS_TYPE 0x00080
+#define HAS_DEV 0x00100
+#define HAS_DEVMAJOR 0x00200
+#define HAS_DEVMINOR 0x00400
+#define HAS_INO 0x00800
+#define HAS_FFLAGS 0x01000
+#define HAS_XATTR 0x02000
+#define HAS_ACL 0x04000
+
+ uint64_t id;
+ uint64_t length;
+ uint64_t offset;
+ uint64_t size;
+ enum enctype encoding;
+ struct chksumval a_sum;
+ struct chksumval e_sum;
+ struct archive_string pathname;
+ struct archive_string symlink;
+ time_t ctime;
+ time_t mtime;
+ time_t atime;
+ struct archive_string uname;
+ uid_t uid;
+ struct archive_string gname;
+ gid_t gid;
+ mode_t mode;
+ dev_t dev;
+ dev_t devmajor;
+ dev_t devminor;
+ int64_t ino64;
+ struct archive_string fflags_text;
+ unsigned int link;
+ unsigned int nlink;
+ struct archive_string hardlink;
+ struct xattr *xattr_list;
+};
+
+struct hdlink {
+ struct hdlink *next;
+
+ unsigned int id;
+ int cnt;
+ struct xar_file *files;
+};
+
+struct heap_queue {
+ struct xar_file **files;
+ int allocated;
+ int used;
+};
+
+enum xmlstatus {
+ INIT,
+ XAR,
+ TOC,
+ TOC_CREATION_TIME,
+ TOC_CHECKSUM,
+ TOC_CHECKSUM_OFFSET,
+ TOC_CHECKSUM_SIZE,
+ TOC_FILE,
+ FILE_DATA,
+ FILE_DATA_LENGTH,
+ FILE_DATA_OFFSET,
+ FILE_DATA_SIZE,
+ FILE_DATA_ENCODING,
+ FILE_DATA_A_CHECKSUM,
+ FILE_DATA_E_CHECKSUM,
+ FILE_DATA_CONTENT,
+ FILE_EA,
+ FILE_EA_LENGTH,
+ FILE_EA_OFFSET,
+ FILE_EA_SIZE,
+ FILE_EA_ENCODING,
+ FILE_EA_A_CHECKSUM,
+ FILE_EA_E_CHECKSUM,
+ FILE_EA_NAME,
+ FILE_EA_FSTYPE,
+ FILE_CTIME,
+ FILE_MTIME,
+ FILE_ATIME,
+ FILE_GROUP,
+ FILE_GID,
+ FILE_USER,
+ FILE_UID,
+ FILE_MODE,
+ FILE_DEVICE,
+ FILE_DEVICE_MAJOR,
+ FILE_DEVICE_MINOR,
+ FILE_DEVICENO,
+ FILE_INODE,
+ FILE_LINK,
+ FILE_TYPE,
+ FILE_NAME,
+ FILE_ACL,
+ FILE_ACL_DEFAULT,
+ FILE_ACL_ACCESS,
+ FILE_ACL_APPLEEXTENDED,
+ /* BSD file flags. */
+ FILE_FLAGS,
+ FILE_FLAGS_USER_NODUMP,
+ FILE_FLAGS_USER_IMMUTABLE,
+ FILE_FLAGS_USER_APPEND,
+ FILE_FLAGS_USER_OPAQUE,
+ FILE_FLAGS_USER_NOUNLINK,
+ FILE_FLAGS_SYS_ARCHIVED,
+ FILE_FLAGS_SYS_IMMUTABLE,
+ FILE_FLAGS_SYS_APPEND,
+ FILE_FLAGS_SYS_NOUNLINK,
+ FILE_FLAGS_SYS_SNAPSHOT,
+ /* Linux file flags. */
+ FILE_EXT2,
+ FILE_EXT2_SecureDeletion,
+ FILE_EXT2_Undelete,
+ FILE_EXT2_Compress,
+ FILE_EXT2_Synchronous,
+ FILE_EXT2_Immutable,
+ FILE_EXT2_AppendOnly,
+ FILE_EXT2_NoDump,
+ FILE_EXT2_NoAtime,
+ FILE_EXT2_CompDirty,
+ FILE_EXT2_CompBlock,
+ FILE_EXT2_NoCompBlock,
+ FILE_EXT2_CompError,
+ FILE_EXT2_BTree,
+ FILE_EXT2_HashIndexed,
+ FILE_EXT2_iMagic,
+ FILE_EXT2_Journaled,
+ FILE_EXT2_NoTail,
+ FILE_EXT2_DirSync,
+ FILE_EXT2_TopDir,
+ FILE_EXT2_Reserved,
+ UNKNOWN,
+};
+
+struct unknown_tag {
+ struct unknown_tag *next;
+ struct archive_string name;
+};
+
+struct xar {
+ uint64_t offset; /* Current position in the file. */
+ int64_t total;
+ uint64_t h_base;
+ int end_of_file;
+#define OUTBUFF_SIZE (1024 * 64)
+ unsigned char *outbuff;
+
+ enum xmlstatus xmlsts;
+ enum xmlstatus xmlsts_unknown;
+ struct unknown_tag *unknowntags;
+ int base64text;
+
+ /*
+ * TOC
+ */
+ uint64_t toc_remaining;
+ uint64_t toc_total;
+ uint64_t toc_chksum_offset;
+ uint64_t toc_chksum_size;
+
+ /*
+ * For Decoding data.
+ */
+ enum enctype rd_encoding;
+ z_stream stream;
+ int stream_valid;
+#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
+ bz_stream bzstream;
+ int bzstream_valid;
+#endif
+#if HAVE_LZMA_H && HAVE_LIBLZMA
+ lzma_stream lzstream;
+ int lzstream_valid;
+#elif HAVE_LZMADEC_H && HAVE_LIBLZMADEC
+ lzmadec_stream lzstream;
+ int lzstream_valid;
+#endif
+ /*
+ * For Checksum data.
+ */
+ struct chksumwork a_sumwrk;
+ struct chksumwork e_sumwrk;
+
+ struct xar_file *file; /* current reading file. */
+ struct xattr *xattr; /* current reading extended attribute. */
+ struct heap_queue file_queue;
+ struct xar_file *hdlink_orgs;
+ struct hdlink *hdlink_list;
+
+ int entry_init;
+ uint64_t entry_total;
+ uint64_t entry_remaining;
+ size_t entry_unconsumed;
+ uint64_t entry_size;
+ enum enctype entry_encoding;
+ struct chksumval entry_a_sum;
+ struct chksumval entry_e_sum;
+
+ struct archive_string_conv *sconv;
+};
+
+struct xmlattr {
+ struct xmlattr *next;
+ char *name;
+ char *value;
+};
+
+struct xmlattr_list {
+ struct xmlattr *first;
+ struct xmlattr **last;
+};
+
+static int xar_bid(struct archive_read *, int);
+static int xar_read_header(struct archive_read *,
+ struct archive_entry *);
+static int xar_read_data(struct archive_read *,
+ const void **, size_t *, int64_t *);
+static int xar_read_data_skip(struct archive_read *);
+static int xar_cleanup(struct archive_read *);
+static int move_reading_point(struct archive_read *, uint64_t);
+static int rd_contents_init(struct archive_read *,
+ enum enctype, int, int);
+static int rd_contents(struct archive_read *, const void **,
+ size_t *, size_t *, uint64_t);
+static uint64_t atol10(const char *, size_t);
+static int64_t atol8(const char *, size_t);
+static size_t atohex(unsigned char *, size_t, const char *, size_t);
+static time_t parse_time(const char *p, size_t n);
+static int heap_add_entry(struct archive_read *a,
+ struct heap_queue *, struct xar_file *);
+static struct xar_file *heap_get_entry(struct heap_queue *);
+static int add_link(struct archive_read *,
+ struct xar *, struct xar_file *);
+static void checksum_init(struct archive_read *, int, int);
+static void checksum_update(struct archive_read *, const void *,
+ size_t, const void *, size_t);
+static int checksum_final(struct archive_read *, const void *,
+ size_t, const void *, size_t);
+static int decompression_init(struct archive_read *, enum enctype);
+static int decompress(struct archive_read *, const void **,
+ size_t *, const void *, size_t *);
+static int decompression_cleanup(struct archive_read *);
+static void xmlattr_cleanup(struct xmlattr_list *);
+static int file_new(struct archive_read *,
+ struct xar *, struct xmlattr_list *);
+static void file_free(struct xar_file *);
+static int xattr_new(struct archive_read *,
+ struct xar *, struct xmlattr_list *);
+static void xattr_free(struct xattr *);
+static int getencoding(struct xmlattr_list *);
+static int getsumalgorithm(struct xmlattr_list *);
+static int unknowntag_start(struct archive_read *,
+ struct xar *, const char *);
+static void unknowntag_end(struct xar *, const char *);
+static int xml_start(struct archive_read *,
+ const char *, struct xmlattr_list *);
+static void xml_end(void *, const char *);
+static void xml_data(void *, const char *, int);
+static int xml_parse_file_flags(struct xar *, const char *);
+static int xml_parse_file_ext2(struct xar *, const char *);
+#if defined(HAVE_LIBXML_XMLREADER_H)
+static int xml2_xmlattr_setup(struct archive_read *,
+ struct xmlattr_list *, xmlTextReaderPtr);
+static int xml2_read_cb(void *, char *, int);
+static int xml2_close_cb(void *);
+static void xml2_error_hdr(void *, const char *, xmlParserSeverities,
+ xmlTextReaderLocatorPtr);
+static int xml2_read_toc(struct archive_read *);
+#elif defined(HAVE_BSDXML_H) || defined(HAVE_EXPAT_H)
+struct expat_userData {
+ int state;
+ struct archive_read *archive;
+};
+static int expat_xmlattr_setup(struct archive_read *,
+ struct xmlattr_list *, const XML_Char **);
+static void expat_start_cb(void *, const XML_Char *, const XML_Char **);
+static void expat_end_cb(void *, const XML_Char *);
+static void expat_data_cb(void *, const XML_Char *, int);
+static int expat_read_toc(struct archive_read *);
+#endif
+
+int
+archive_read_support_format_xar(struct archive *_a)
+{
+ struct xar *xar;
+ struct archive_read *a = (struct archive_read *)_a;
+ int r;
+
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_xar");
+
+ xar = (struct xar *)calloc(1, sizeof(*xar));
+ if (xar == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate xar data");
+ return (ARCHIVE_FATAL);
+ }
+
+ r = __archive_read_register_format(a,
+ xar,
+ "xar",
+ xar_bid,
+ NULL,
+ xar_read_header,
+ xar_read_data,
+ xar_read_data_skip,
+ xar_cleanup);
+ if (r != ARCHIVE_OK)
+ free(xar);
+ return (r);
+}
+
+static int
+xar_bid(struct archive_read *a, int best_bid)
+{
+ const unsigned char *b;
+ int bid;
+
+ (void)best_bid; /* UNUSED */
+
+ b = __archive_read_ahead(a, HEADER_SIZE, NULL);
+ if (b == NULL)
+ return (-1);
+
+ bid = 0;
+ /*
+ * Verify magic code
+ */
+ if (archive_be32dec(b) != HEADER_MAGIC)
+ return (0);
+ bid += 32;
+ /*
+ * Verify header size
+ */
+ if (archive_be16dec(b+4) != HEADER_SIZE)
+ return (0);
+ bid += 16;
+ /*
+ * Verify header version
+ */
+ if (archive_be16dec(b+6) != HEADER_VERSION)
+ return (0);
+ bid += 16;
+ /*
+ * Verify type of checksum
+ */
+ switch (archive_be32dec(b+24)) {
+ case CKSUM_NONE:
+ case CKSUM_SHA1:
+ case CKSUM_MD5:
+ bid += 32;
+ break;
+ default:
+ return (0);
+ }
+
+ return (bid);
+}
+
+static int
+read_toc(struct archive_read *a)
+{
+ struct xar *xar;
+ struct xar_file *file;
+ const unsigned char *b;
+ uint64_t toc_compressed_size;
+ uint64_t toc_uncompressed_size;
+ uint32_t toc_chksum_alg;
+ ssize_t bytes;
+ int r;
+
+ xar = (struct xar *)(a->format->data);
+
+ /*
+ * Read xar header.
+ */
+ b = __archive_read_ahead(a, HEADER_SIZE, &bytes);
+ if (bytes < 0)
+ return ((int)bytes);
+ if (bytes < HEADER_SIZE) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated archive header");
+ return (ARCHIVE_FATAL);
+ }
+
+ if (archive_be32dec(b) != HEADER_MAGIC) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid header magic");
+ return (ARCHIVE_FATAL);
+ }
+ if (archive_be16dec(b+6) != HEADER_VERSION) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Unsupported header version(%d)",
+ archive_be16dec(b+6));
+ return (ARCHIVE_FATAL);
+ }
+ toc_compressed_size = archive_be64dec(b+8);
+ xar->toc_remaining = toc_compressed_size;
+ toc_uncompressed_size = archive_be64dec(b+16);
+ toc_chksum_alg = archive_be32dec(b+24);
+ __archive_read_consume(a, HEADER_SIZE);
+ xar->offset += HEADER_SIZE;
+ xar->toc_total = 0;
+
+ /*
+ * Read TOC(Table of Contents).
+ */
+ /* Initialize reading contents. */
+ r = move_reading_point(a, HEADER_SIZE);
+ if (r != ARCHIVE_OK)
+ return (r);
+ r = rd_contents_init(a, GZIP, toc_chksum_alg, CKSUM_NONE);
+ if (r != ARCHIVE_OK)
+ return (r);
+
+#ifdef HAVE_LIBXML_XMLREADER_H
+ r = xml2_read_toc(a);
+#elif defined(HAVE_BSDXML_H) || defined(HAVE_EXPAT_H)
+ r = expat_read_toc(a);
+#endif
+ if (r != ARCHIVE_OK)
+ return (r);
+
+ /* Set 'The HEAP' base. */
+ xar->h_base = xar->offset;
+ if (xar->toc_total != toc_uncompressed_size) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "TOC uncompressed size error");
+ return (ARCHIVE_FATAL);
+ }
+
+ /*
+ * Checksum TOC
+ */
+ if (toc_chksum_alg != CKSUM_NONE) {
+ r = move_reading_point(a, xar->toc_chksum_offset);
+ if (r != ARCHIVE_OK)
+ return (r);
+ b = __archive_read_ahead(a, xar->toc_chksum_size, &bytes);
+ if (bytes < 0)
+ return ((int)bytes);
+ if ((uint64_t)bytes < xar->toc_chksum_size) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated archive file");
+ return (ARCHIVE_FATAL);
+ }
+ r = checksum_final(a, b, xar->toc_chksum_size, NULL, 0);
+ __archive_read_consume(a, xar->toc_chksum_size);
+ xar->offset += xar->toc_chksum_size;
+ if (r != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
+
+ /*
+ * Connect hardlinked files.
+ */
+ for (file = xar->hdlink_orgs; file != NULL; file = file->hdnext) {
+ struct hdlink **hdlink;
+
+ for (hdlink = &(xar->hdlink_list); *hdlink != NULL;
+ hdlink = &((*hdlink)->next)) {
+ if ((*hdlink)->id == file->id) {
+ struct hdlink *hltmp;
+ struct xar_file *f2;
+ int nlink = (*hdlink)->cnt + 1;
+
+ file->nlink = nlink;
+ for (f2 = (*hdlink)->files; f2 != NULL;
+ f2 = f2->hdnext) {
+ f2->nlink = nlink;
+ archive_string_copy(
+ &(f2->hardlink), &(file->pathname));
+ }
+ /* Remove resolved files from hdlist_list. */
+ hltmp = *hdlink;
+ *hdlink = hltmp->next;
+ free(hltmp);
+ break;
+ }
+ }
+ }
+ a->archive.archive_format = ARCHIVE_FORMAT_XAR;
+ a->archive.archive_format_name = "xar";
+
+ return (ARCHIVE_OK);
+}
+
+static int
+xar_read_header(struct archive_read *a, struct archive_entry *entry)
+{
+ struct xar *xar;
+ struct xar_file *file;
+ struct xattr *xattr;
+ int r;
+
+ xar = (struct xar *)(a->format->data);
+ r = ARCHIVE_OK;
+
+ if (xar->offset == 0) {
+ /* Create a character conversion object. */
+ if (xar->sconv == NULL) {
+ xar->sconv = archive_string_conversion_from_charset(
+ &(a->archive), "UTF-8", 1);
+ if (xar->sconv == NULL)
+ return (ARCHIVE_FATAL);
+ }
+
+ /* Read TOC. */
+ r = read_toc(a);
+ if (r != ARCHIVE_OK)
+ return (r);
+ }
+
+ for (;;) {
+ file = xar->file = heap_get_entry(&(xar->file_queue));
+ if (file == NULL) {
+ xar->end_of_file = 1;
+ return (ARCHIVE_EOF);
+ }
+ if ((file->mode & AE_IFMT) != AE_IFDIR)
+ break;
+ if (file->has != (HAS_PATHNAME | HAS_TYPE))
+ break;
+ /*
+ * If a file type is a directory and it does not have
+ * any metadata, do not export.
+ */
+ file_free(file);
+ }
+ archive_entry_set_atime(entry, file->atime, 0);
+ archive_entry_set_ctime(entry, file->ctime, 0);
+ archive_entry_set_mtime(entry, file->mtime, 0);
+ archive_entry_set_gid(entry, file->gid);
+ if (file->gname.length > 0 &&
+ archive_entry_copy_gname_l(entry, file->gname.s,
+ archive_strlen(&(file->gname)), xar->sconv) != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Gname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Gname cannot be converted from %s to current locale.",
+ archive_string_conversion_charset_name(xar->sconv));
+ r = ARCHIVE_WARN;
+ }
+ archive_entry_set_uid(entry, file->uid);
+ if (file->uname.length > 0 &&
+ archive_entry_copy_uname_l(entry, file->uname.s,
+ archive_strlen(&(file->uname)), xar->sconv) != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Uname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Uname cannot be converted from %s to current locale.",
+ archive_string_conversion_charset_name(xar->sconv));
+ r = ARCHIVE_WARN;
+ }
+ archive_entry_set_mode(entry, file->mode);
+ if (archive_entry_copy_pathname_l(entry, file->pathname.s,
+ archive_strlen(&(file->pathname)), xar->sconv) != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Pathname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Pathname cannot be converted from %s to current locale.",
+ archive_string_conversion_charset_name(xar->sconv));
+ r = ARCHIVE_WARN;
+ }
+
+
+ if (file->symlink.length > 0 &&
+ archive_entry_copy_symlink_l(entry, file->symlink.s,
+ archive_strlen(&(file->symlink)), xar->sconv) != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Linkname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Linkname cannot be converted from %s to current locale.",
+ archive_string_conversion_charset_name(xar->sconv));
+ r = ARCHIVE_WARN;
+ }
+ /* Set proper nlink. */
+ if ((file->mode & AE_IFMT) == AE_IFDIR)
+ archive_entry_set_nlink(entry, file->subdirs + 2);
+ else
+ archive_entry_set_nlink(entry, file->nlink);
+ archive_entry_set_size(entry, file->size);
+ if (archive_strlen(&(file->hardlink)) > 0)
+ archive_entry_set_hardlink(entry, file->hardlink.s);
+ archive_entry_set_ino64(entry, file->ino64);
+ if (file->has & HAS_DEV)
+ archive_entry_set_dev(entry, file->dev);
+ if (file->has & HAS_DEVMAJOR)
+ archive_entry_set_devmajor(entry, file->devmajor);
+ if (file->has & HAS_DEVMINOR)
+ archive_entry_set_devminor(entry, file->devminor);
+ if (archive_strlen(&(file->fflags_text)) > 0)
+ archive_entry_copy_fflags_text(entry, file->fflags_text.s);
+
+ xar->entry_init = 1;
+ xar->entry_total = 0;
+ xar->entry_remaining = file->length;
+ xar->entry_size = file->size;
+ xar->entry_encoding = file->encoding;
+ xar->entry_a_sum = file->a_sum;
+ xar->entry_e_sum = file->e_sum;
+ /*
+ * Read extended attributes.
+ */
+ xattr = file->xattr_list;
+ while (xattr != NULL) {
+ const void *d;
+ size_t outbytes, used;
+
+ r = move_reading_point(a, xattr->offset);
+ if (r != ARCHIVE_OK)
+ break;
+ r = rd_contents_init(a, xattr->encoding,
+ xattr->a_sum.alg, xattr->e_sum.alg);
+ if (r != ARCHIVE_OK)
+ break;
+ d = NULL;
+ r = rd_contents(a, &d, &outbytes, &used, xattr->length);
+ if (r != ARCHIVE_OK)
+ break;
+ if (outbytes != xattr->size) {
+ archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
+ "Decompressed size error");
+ r = ARCHIVE_FATAL;
+ break;
+ }
+ r = checksum_final(a,
+ xattr->a_sum.val, xattr->a_sum.len,
+ xattr->e_sum.val, xattr->e_sum.len);
+ if (r != ARCHIVE_OK)
+ break;
+ archive_entry_xattr_add_entry(entry,
+ xattr->name.s, d, outbytes);
+ xattr = xattr->next;
+ }
+ if (r != ARCHIVE_OK) {
+ file_free(file);
+ return (r);
+ }
+
+ if (xar->entry_remaining > 0)
+ /* Move reading point to the beginning of current
+ * file contents. */
+ r = move_reading_point(a, file->offset);
+ else
+ r = ARCHIVE_OK;
+
+ file_free(file);
+ return (r);
+}
+
+static int
+xar_read_data(struct archive_read *a,
+ const void **buff, size_t *size, int64_t *offset)
+{
+ struct xar *xar;
+ size_t used;
+ int r;
+
+ xar = (struct xar *)(a->format->data);
+
+ if (xar->entry_unconsumed) {
+ __archive_read_consume(a, xar->entry_unconsumed);
+ xar->entry_unconsumed = 0;
+ }
+
+ if (xar->end_of_file || xar->entry_remaining <= 0) {
+ r = ARCHIVE_EOF;
+ goto abort_read_data;
+ }
+
+ if (xar->entry_init) {
+ r = rd_contents_init(a, xar->entry_encoding,
+ xar->entry_a_sum.alg, xar->entry_e_sum.alg);
+ if (r != ARCHIVE_OK) {
+ xar->entry_remaining = 0;
+ return (r);
+ }
+ xar->entry_init = 0;
+ }
+
+ *buff = NULL;
+ r = rd_contents(a, buff, size, &used, xar->entry_remaining);
+ if (r != ARCHIVE_OK)
+ goto abort_read_data;
+
+ *offset = xar->entry_total;
+ xar->entry_total += *size;
+ xar->total += *size;
+ xar->offset += used;
+ xar->entry_remaining -= used;
+ xar->entry_unconsumed = used;
+
+ if (xar->entry_remaining == 0) {
+ if (xar->entry_total != xar->entry_size) {
+ archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
+ "Decompressed size error");
+ r = ARCHIVE_FATAL;
+ goto abort_read_data;
+ }
+ r = checksum_final(a,
+ xar->entry_a_sum.val, xar->entry_a_sum.len,
+ xar->entry_e_sum.val, xar->entry_e_sum.len);
+ if (r != ARCHIVE_OK)
+ goto abort_read_data;
+ }
+
+ return (ARCHIVE_OK);
+abort_read_data:
+ *buff = NULL;
+ *size = 0;
+ *offset = xar->total;
+ return (r);
+}
+
+static int
+xar_read_data_skip(struct archive_read *a)
+{
+ struct xar *xar;
+ int64_t bytes_skipped;
+
+ xar = (struct xar *)(a->format->data);
+ if (xar->end_of_file)
+ return (ARCHIVE_EOF);
+ bytes_skipped = __archive_read_consume(a, xar->entry_remaining +
+ xar->entry_unconsumed);
+ if (bytes_skipped < 0)
+ return (ARCHIVE_FATAL);
+ xar->offset += bytes_skipped;
+ xar->entry_unconsumed = 0;
+ return (ARCHIVE_OK);
+}
+
+static int
+xar_cleanup(struct archive_read *a)
+{
+ struct xar *xar;
+ struct hdlink *hdlink;
+ int i;
+ int r;
+
+ xar = (struct xar *)(a->format->data);
+ r = decompression_cleanup(a);
+ hdlink = xar->hdlink_list;
+ while (hdlink != NULL) {
+ struct hdlink *next = hdlink->next;
+
+ free(hdlink);
+ hdlink = next;
+ }
+ for (i = 0; i < xar->file_queue.used; i++)
+ file_free(xar->file_queue.files[i]);
+ while (xar->unknowntags != NULL) {
+ struct unknown_tag *tag;
+
+ tag = xar->unknowntags;
+ xar->unknowntags = tag->next;
+ archive_string_free(&(tag->name));
+ free(tag);
+ }
+ free(xar->outbuff);
+ free(xar);
+ a->format->data = NULL;
+ return (r);
+}
+
+static int
+move_reading_point(struct archive_read *a, uint64_t offset)
+{
+ struct xar *xar;
+
+ xar = (struct xar *)(a->format->data);
+ if (xar->offset - xar->h_base != offset) {
+ /* Seek forward to the start of file contents. */
+ int64_t step;
+
+ step = offset - (xar->offset - xar->h_base);
+ if (step > 0) {
+ step = __archive_read_consume(a, step);
+ if (step < 0)
+ return ((int)step);
+ xar->offset += step;
+ } else {
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "Cannot seek.");
+ return (ARCHIVE_FAILED);
+ }
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+rd_contents_init(struct archive_read *a, enum enctype encoding,
+ int a_sum_alg, int e_sum_alg)
+{
+ int r;
+
+ /* Init decompress library. */
+ if ((r = decompression_init(a, encoding)) != ARCHIVE_OK)
+ return (r);
+ /* Init checksum library. */
+ checksum_init(a, a_sum_alg, e_sum_alg);
+ return (ARCHIVE_OK);
+}
+
+static int
+rd_contents(struct archive_read *a, const void **buff, size_t *size,
+ size_t *used, uint64_t remaining)
+{
+ const unsigned char *b;
+ ssize_t bytes;
+
+ /* Get whatever bytes are immediately available. */
+ b = __archive_read_ahead(a, 1, &bytes);
+ if (bytes < 0)
+ return ((int)bytes);
+ if (bytes == 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Truncated archive file");
+ return (ARCHIVE_FATAL);
+ }
+ if ((uint64_t)bytes > remaining)
+ bytes = (ssize_t)remaining;
+
+ /*
+ * Decompress contents of file.
+ */
+ *used = bytes;
+ if (decompress(a, buff, size, b, used) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ /*
+ * Update checksum of a compressed data and a extracted data.
+ */
+ checksum_update(a, b, *used, *buff, *size);
+
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Note that this implementation does not (and should not!) obey
+ * locale settings; you cannot simply substitute strtol here, since
+ * it does obey locale.
+ */
+
+static uint64_t
+atol10(const char *p, size_t char_cnt)
+{
+ uint64_t l;
+ int digit;
+
+ l = 0;
+ digit = *p - '0';
+ while (digit >= 0 && digit < 10 && char_cnt-- > 0) {
+ l = (l * 10) + digit;
+ digit = *++p - '0';
+ }
+ return (l);
+}
+
+static int64_t
+atol8(const char *p, size_t char_cnt)
+{
+ int64_t l;
+ int digit;
+
+ l = 0;
+ while (char_cnt-- > 0) {
+ if (*p >= '0' && *p <= '7')
+ digit = *p - '0';
+ else
+ break;
+ p++;
+ l <<= 3;
+ l |= digit;
+ }
+ return (l);
+}
+
+static size_t
+atohex(unsigned char *b, size_t bsize, const char *p, size_t psize)
+{
+ size_t fbsize = bsize;
+
+ while (bsize && psize > 1) {
+ unsigned char x;
+
+ if (p[0] >= 'a' && p[0] <= 'z')
+ x = (p[0] - 'a' + 0x0a) << 4;
+ else if (p[0] >= 'A' && p[0] <= 'Z')
+ x = (p[0] - 'A' + 0x0a) << 4;
+ else if (p[0] >= '0' && p[0] <= '9')
+ x = (p[0] - '0') << 4;
+ else
+ return (-1);
+ if (p[1] >= 'a' && p[1] <= 'z')
+ x |= p[1] - 'a' + 0x0a;
+ else if (p[1] >= 'A' && p[1] <= 'Z')
+ x |= p[1] - 'A' + 0x0a;
+ else if (p[1] >= '0' && p[1] <= '9')
+ x |= p[1] - '0';
+ else
+ return (-1);
+
+ *b++ = x;
+ bsize--;
+ p += 2;
+ psize -= 2;
+ }
+ return (fbsize - bsize);
+}
+
+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. */
+ 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
+}
+
+static time_t
+parse_time(const char *p, size_t n)
+{
+ struct tm tm;
+ time_t t = 0;
+ int64_t data;
+
+ memset(&tm, 0, sizeof(tm));
+ if (n != 20)
+ return (t);
+ data = atol10(p, 4);
+ if (data < 1900)
+ return (t);
+ tm.tm_year = (int)data - 1900;
+ p += 4;
+ if (*p++ != '-')
+ return (t);
+ data = atol10(p, 2);
+ if (data < 1 || data > 12)
+ return (t);
+ tm.tm_mon = (int)data -1;
+ p += 2;
+ if (*p++ != '-')
+ return (t);
+ data = atol10(p, 2);
+ if (data < 1 || data > 31)
+ return (t);
+ tm.tm_mday = (int)data;
+ p += 2;
+ if (*p++ != 'T')
+ return (t);
+ data = atol10(p, 2);
+ if (data < 0 || data > 23)
+ return (t);
+ tm.tm_hour = (int)data;
+ p += 2;
+ if (*p++ != ':')
+ return (t);
+ data = atol10(p, 2);
+ if (data < 0 || data > 59)
+ return (t);
+ tm.tm_min = (int)data;
+ p += 2;
+ if (*p++ != ':')
+ return (t);
+ data = atol10(p, 2);
+ if (data < 0 || data > 60)
+ return (t);
+ tm.tm_sec = (int)data;
+#if 0
+ p += 2;
+ if (*p != 'Z')
+ return (t);
+#endif
+
+ t = time_from_tm(&tm);
+
+ return (t);
+}
+
+static int
+heap_add_entry(struct archive_read *a,
+ struct heap_queue *heap, struct xar_file *file)
+{
+ uint64_t file_id, parent_id;
+ int hole, parent;
+
+ /* Expand our pending files list as necessary. */
+ if (heap->used >= heap->allocated) {
+ struct xar_file **new_pending_files;
+ int new_size = heap->allocated * 2;
+
+ if (heap->allocated < 1024)
+ new_size = 1024;
+ /* Overflow might keep us from growing the list. */
+ if (new_size <= heap->allocated) {
+ archive_set_error(&a->archive,
+ ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
+ new_pending_files = (struct xar_file **)
+ malloc(new_size * sizeof(new_pending_files[0]));
+ if (new_pending_files == NULL) {
+ archive_set_error(&a->archive,
+ ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
+ memcpy(new_pending_files, heap->files,
+ heap->allocated * sizeof(new_pending_files[0]));
+ if (heap->files != NULL)
+ free(heap->files);
+ heap->files = new_pending_files;
+ heap->allocated = new_size;
+ }
+
+ file_id = file->id;
+
+ /*
+ * Start with hole at end, walk it up tree to find insertion point.
+ */
+ hole = heap->used++;
+ while (hole > 0) {
+ parent = (hole - 1)/2;
+ parent_id = heap->files[parent]->id;
+ if (file_id >= parent_id) {
+ heap->files[hole] = file;
+ return (ARCHIVE_OK);
+ }
+ /* Move parent into hole <==> move hole up tree. */
+ heap->files[hole] = heap->files[parent];
+ hole = parent;
+ }
+ heap->files[0] = file;
+
+ return (ARCHIVE_OK);
+}
+
+static struct xar_file *
+heap_get_entry(struct heap_queue *heap)
+{
+ uint64_t a_id, b_id, c_id;
+ int a, b, c;
+ struct xar_file *r, *tmp;
+
+ if (heap->used < 1)
+ return (NULL);
+
+ /*
+ * The first file in the list is the earliest; we'll return this.
+ */
+ r = heap->files[0];
+
+ /*
+ * Move the last item in the heap to the root of the tree
+ */
+ heap->files[0] = heap->files[--(heap->used)];
+
+ /*
+ * Rebalance the heap.
+ */
+ a = 0; /* Starting element and its heap key */
+ a_id = heap->files[a]->id;
+ for (;;) {
+ b = a + a + 1; /* First child */
+ if (b >= heap->used)
+ return (r);
+ b_id = heap->files[b]->id;
+ c = b + 1; /* Use second child if it is smaller. */
+ if (c < heap->used) {
+ c_id = heap->files[c]->id;
+ if (c_id < b_id) {
+ b = c;
+ b_id = c_id;
+ }
+ }
+ if (a_id <= b_id)
+ return (r);
+ tmp = heap->files[a];
+ heap->files[a] = heap->files[b];
+ heap->files[b] = tmp;
+ a = b;
+ }
+}
+
+static int
+add_link(struct archive_read *a, struct xar *xar, struct xar_file *file)
+{
+ struct hdlink *hdlink;
+
+ for (hdlink = xar->hdlink_list; hdlink != NULL; hdlink = hdlink->next) {
+ if (hdlink->id == file->link) {
+ file->hdnext = hdlink->files;
+ hdlink->cnt++;
+ hdlink->files = file;
+ return (ARCHIVE_OK);
+ }
+ }
+ hdlink = malloc(sizeof(*hdlink));
+ if (hdlink == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
+ file->hdnext = NULL;
+ hdlink->id = file->link;
+ hdlink->cnt = 1;
+ hdlink->files = file;
+ hdlink->next = xar->hdlink_list;
+ xar->hdlink_list = hdlink;
+ return (ARCHIVE_OK);
+}
+
+static void
+_checksum_init(struct chksumwork *sumwrk, int sum_alg)
+{
+ sumwrk->alg = sum_alg;
+ switch (sum_alg) {
+ case CKSUM_NONE:
+ break;
+ case CKSUM_SHA1:
+ archive_sha1_init(&(sumwrk->sha1ctx));
+ break;
+ case CKSUM_MD5:
+ archive_md5_init(&(sumwrk->md5ctx));
+ break;
+ }
+}
+
+static void
+_checksum_update(struct chksumwork *sumwrk, const void *buff, size_t size)
+{
+
+ switch (sumwrk->alg) {
+ case CKSUM_NONE:
+ break;
+ case CKSUM_SHA1:
+ archive_sha1_update(&(sumwrk->sha1ctx), buff, size);
+ break;
+ case CKSUM_MD5:
+ archive_md5_update(&(sumwrk->md5ctx), buff, size);
+ break;
+ }
+}
+
+static int
+_checksum_final(struct chksumwork *sumwrk, const void *val, size_t len)
+{
+ unsigned char sum[MAX_SUM_SIZE];
+ int r = ARCHIVE_OK;
+
+ switch (sumwrk->alg) {
+ case CKSUM_NONE:
+ break;
+ case CKSUM_SHA1:
+ archive_sha1_final(&(sumwrk->sha1ctx), sum);
+ if (len != SHA1_SIZE ||
+ memcmp(val, sum, SHA1_SIZE) != 0)
+ r = ARCHIVE_FAILED;
+ break;
+ case CKSUM_MD5:
+ archive_md5_final(&(sumwrk->md5ctx), sum);
+ if (len != MD5_SIZE ||
+ memcmp(val, sum, MD5_SIZE) != 0)
+ r = ARCHIVE_FAILED;
+ break;
+ }
+ return (r);
+}
+
+static void
+checksum_init(struct archive_read *a, int a_sum_alg, int e_sum_alg)
+{
+ struct xar *xar;
+
+ xar = (struct xar *)(a->format->data);
+ _checksum_init(&(xar->a_sumwrk), a_sum_alg);
+ _checksum_init(&(xar->e_sumwrk), e_sum_alg);
+}
+
+static void
+checksum_update(struct archive_read *a, const void *abuff, size_t asize,
+ const void *ebuff, size_t esize)
+{
+ struct xar *xar;
+
+ xar = (struct xar *)(a->format->data);
+ _checksum_update(&(xar->a_sumwrk), abuff, asize);
+ _checksum_update(&(xar->e_sumwrk), ebuff, esize);
+}
+
+static int
+checksum_final(struct archive_read *a, const void *a_sum_val,
+ size_t a_sum_len, const void *e_sum_val, size_t e_sum_len)
+{
+ struct xar *xar;
+ int r;
+
+ xar = (struct xar *)(a->format->data);
+ r = _checksum_final(&(xar->a_sumwrk), a_sum_val, a_sum_len);
+ if (r == ARCHIVE_OK)
+ r = _checksum_final(&(xar->e_sumwrk), e_sum_val, e_sum_len);
+ if (r != ARCHIVE_OK)
+ archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
+ "Sumcheck error");
+ return (r);
+}
+
+static int
+decompression_init(struct archive_read *a, enum enctype encoding)
+{
+ struct xar *xar;
+ const char *detail;
+ int r;
+
+ xar = (struct xar *)(a->format->data);
+ xar->rd_encoding = encoding;
+ switch (encoding) {
+ case NONE:
+ break;
+ case GZIP:
+ if (xar->stream_valid)
+ r = inflateReset(&(xar->stream));
+ else
+ r = inflateInit(&(xar->stream));
+ if (r != Z_OK) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Couldn't initialize zlib stream.");
+ return (ARCHIVE_FATAL);
+ }
+ xar->stream_valid = 1;
+ xar->stream.total_in = 0;
+ xar->stream.total_out = 0;
+ break;
+#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
+ case BZIP2:
+ if (xar->bzstream_valid) {
+ BZ2_bzDecompressEnd(&(xar->bzstream));
+ xar->bzstream_valid = 0;
+ }
+ r = BZ2_bzDecompressInit(&(xar->bzstream), 0, 0);
+ if (r == BZ_MEM_ERROR)
+ r = BZ2_bzDecompressInit(&(xar->bzstream), 0, 1);
+ if (r != BZ_OK) {
+ int err = ARCHIVE_ERRNO_MISC;
+ detail = NULL;
+ switch (r) {
+ case BZ_PARAM_ERROR:
+ detail = "invalid setup parameter";
+ break;
+ case BZ_MEM_ERROR:
+ err = ENOMEM;
+ detail = "out of memory";
+ break;
+ case BZ_CONFIG_ERROR:
+ detail = "mis-compiled library";
+ break;
+ }
+ archive_set_error(&a->archive, err,
+ "Internal error initializing decompressor: %s",
+ detail == NULL ? "??" : detail);
+ xar->bzstream_valid = 0;
+ return (ARCHIVE_FATAL);
+ }
+ xar->bzstream_valid = 1;
+ xar->bzstream.total_in_lo32 = 0;
+ xar->bzstream.total_in_hi32 = 0;
+ xar->bzstream.total_out_lo32 = 0;
+ xar->bzstream.total_out_hi32 = 0;
+ break;
+#endif
+#if defined(HAVE_LZMA_H) && defined(HAVE_LIBLZMA)
+#if LZMA_VERSION_MAJOR >= 5
+/* Effectively disable the limiter. */
+#define LZMA_MEMLIMIT UINT64_MAX
+#else
+/* NOTE: This needs to check memory size which running system has. */
+#define LZMA_MEMLIMIT (1U << 30)
+#endif
+ case XZ:
+ case LZMA:
+ if (xar->lzstream_valid) {
+ lzma_end(&(xar->lzstream));
+ xar->lzstream_valid = 0;
+ }
+ if (xar->entry_encoding == XZ)
+ r = lzma_stream_decoder(&(xar->lzstream),
+ LZMA_MEMLIMIT,/* memlimit */
+ LZMA_CONCATENATED);
+ else
+ r = lzma_alone_decoder(&(xar->lzstream),
+ LZMA_MEMLIMIT);/* memlimit */
+ if (r != LZMA_OK) {
+ switch (r) {
+ case LZMA_MEM_ERROR:
+ archive_set_error(&a->archive,
+ ENOMEM,
+ "Internal error initializing "
+ "compression library: "
+ "Cannot allocate memory");
+ break;
+ case LZMA_OPTIONS_ERROR:
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Internal error initializing "
+ "compression library: "
+ "Invalid or unsupported options");
+ break;
+ default:
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Internal error initializing "
+ "lzma library");
+ break;
+ }
+ return (ARCHIVE_FATAL);
+ }
+ xar->lzstream_valid = 1;
+ xar->lzstream.total_in = 0;
+ xar->lzstream.total_out = 0;
+ break;
+#elif defined(HAVE_LZMADEC_H) && defined(HAVE_LIBLZMADEC)
+ case LZMA:
+ if (xar->lzstream_valid)
+ lzmadec_end(&(xar->lzstream));
+ r = lzmadec_init(&(xar->lzstream));
+ if (r != LZMADEC_OK) {
+ switch (r) {
+ case LZMADEC_HEADER_ERROR:
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Internal error initializing "
+ "compression library: "
+ "invalid header");
+ break;
+ case LZMADEC_MEM_ERROR:
+ archive_set_error(&a->archive,
+ ENOMEM,
+ "Internal error initializing "
+ "compression library: "
+ "out of memory");
+ break;
+ }
+ return (ARCHIVE_FATAL);
+ }
+ xar->lzstream_valid = 1;
+ xar->lzstream.total_in = 0;
+ xar->lzstream.total_out = 0;
+ break;
+#endif
+ /*
+ * Unsupported compression.
+ */
+ default:
+#if !defined(HAVE_BZLIB_H) || !defined(BZ_CONFIG_ERROR)
+ case BZIP2:
+#endif
+#if !defined(HAVE_LZMA_H) || !defined(HAVE_LIBLZMA)
+#if !defined(HAVE_LZMADEC_H) || !defined(HAVE_LIBLZMADEC)
+ case LZMA:
+#endif
+ case XZ:
+#endif
+ switch (xar->entry_encoding) {
+ case BZIP2: detail = "bzip2"; break;
+ case LZMA: detail = "lzma"; break;
+ case XZ: detail = "xz"; break;
+ default: detail = "??"; break;
+ }
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "%s compression not supported on this platform",
+ detail);
+ return (ARCHIVE_FAILED);
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+decompress(struct archive_read *a, const void **buff, size_t *outbytes,
+ const void *b, size_t *used)
+{
+ struct xar *xar;
+ void *outbuff;
+ size_t avail_in, avail_out;
+ int r;
+
+ xar = (struct xar *)(a->format->data);
+ avail_in = *used;
+ outbuff = (void *)(uintptr_t)*buff;
+ if (outbuff == NULL) {
+ if (xar->outbuff == NULL) {
+ xar->outbuff = malloc(OUTBUFF_SIZE);
+ if (xar->outbuff == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Couldn't allocate memory for out buffer");
+ return (ARCHIVE_FATAL);
+ }
+ }
+ outbuff = xar->outbuff;
+ *buff = outbuff;
+ avail_out = OUTBUFF_SIZE;
+ } else
+ avail_out = *outbytes;
+ switch (xar->rd_encoding) {
+ case GZIP:
+ xar->stream.next_in = (Bytef *)(uintptr_t)b;
+ xar->stream.avail_in = avail_in;
+ xar->stream.next_out = (unsigned char *)outbuff;
+ xar->stream.avail_out = avail_out;
+ r = inflate(&(xar->stream), 0);
+ switch (r) {
+ case Z_OK: /* Decompressor made some progress.*/
+ case Z_STREAM_END: /* Found end of stream. */
+ break;
+ default:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "File decompression failed (%d)", r);
+ return (ARCHIVE_FATAL);
+ }
+ *used = avail_in - xar->stream.avail_in;
+ *outbytes = avail_out - xar->stream.avail_out;
+ break;
+#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
+ case BZIP2:
+ xar->bzstream.next_in = (char *)(uintptr_t)b;
+ xar->bzstream.avail_in = avail_in;
+ xar->bzstream.next_out = (char *)outbuff;
+ xar->bzstream.avail_out = avail_out;
+ r = BZ2_bzDecompress(&(xar->bzstream));
+ switch (r) {
+ case BZ_STREAM_END: /* Found end of stream. */
+ switch (BZ2_bzDecompressEnd(&(xar->bzstream))) {
+ case BZ_OK:
+ break;
+ default:
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "Failed to clean up decompressor");
+ return (ARCHIVE_FATAL);
+ }
+ xar->bzstream_valid = 0;
+ /* FALLTHROUGH */
+ case BZ_OK: /* Decompressor made some progress. */
+ break;
+ default:
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "bzip decompression failed");
+ return (ARCHIVE_FATAL);
+ }
+ *used = avail_in - xar->bzstream.avail_in;
+ *outbytes = avail_out - xar->bzstream.avail_out;
+ break;
+#endif
+#if defined(HAVE_LZMA_H) && defined(HAVE_LIBLZMA)
+ case LZMA:
+ case XZ:
+ xar->lzstream.next_in = b;
+ xar->lzstream.avail_in = avail_in;
+ xar->lzstream.next_out = (unsigned char *)outbuff;
+ xar->lzstream.avail_out = avail_out;
+ r = lzma_code(&(xar->lzstream), LZMA_RUN);
+ switch (r) {
+ case LZMA_STREAM_END: /* Found end of stream. */
+ lzma_end(&(xar->lzstream));
+ xar->lzstream_valid = 0;
+ /* FALLTHROUGH */
+ case LZMA_OK: /* Decompressor made some progress. */
+ break;
+ default:
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "%s decompression failed(%d)",
+ (xar->entry_encoding == XZ)?"xz":"lzma",
+ r);
+ return (ARCHIVE_FATAL);
+ }
+ *used = avail_in - xar->lzstream.avail_in;
+ *outbytes = avail_out - xar->lzstream.avail_out;
+ break;
+#elif defined(HAVE_LZMADEC_H) && defined(HAVE_LIBLZMADEC)
+ case LZMA:
+ xar->lzstream.next_in = (unsigned char *)(uintptr_t)b;
+ xar->lzstream.avail_in = avail_in;
+ xar->lzstream.next_out = (unsigned char *)outbuff;
+ xar->lzstream.avail_out = avail_out;
+ r = lzmadec_decode(&(xar->lzstream), 0);
+ switch (r) {
+ case LZMADEC_STREAM_END: /* Found end of stream. */
+ switch (lzmadec_end(&(xar->lzstream))) {
+ case LZMADEC_OK:
+ break;
+ default:
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "Failed to clean up lzmadec decompressor");
+ return (ARCHIVE_FATAL);
+ }
+ xar->lzstream_valid = 0;
+ /* FALLTHROUGH */
+ case LZMADEC_OK: /* Decompressor made some progress. */
+ break;
+ default:
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "lzmadec decompression failed(%d)",
+ r);
+ return (ARCHIVE_FATAL);
+ }
+ *used = avail_in - xar->lzstream.avail_in;
+ *outbytes = avail_out - xar->lzstream.avail_out;
+ break;
+#endif
+#if !defined(HAVE_BZLIB_H) || !defined(BZ_CONFIG_ERROR)
+ case BZIP2:
+#endif
+#if !defined(HAVE_LZMA_H) || !defined(HAVE_LIBLZMA)
+#if !defined(HAVE_LZMADEC_H) || !defined(HAVE_LIBLZMADEC)
+ case LZMA:
+#endif
+ case XZ:
+#endif
+ case NONE:
+ default:
+ if (outbuff == xar->outbuff) {
+ *buff = b;
+ *used = avail_in;
+ *outbytes = avail_in;
+ } else {
+ if (avail_out > avail_in)
+ avail_out = avail_in;
+ memcpy(outbuff, b, avail_out);
+ *used = avail_out;
+ *outbytes = avail_out;
+ }
+ break;
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+decompression_cleanup(struct archive_read *a)
+{
+ struct xar *xar;
+ int r;
+
+ xar = (struct xar *)(a->format->data);
+ r = ARCHIVE_OK;
+ if (xar->stream_valid) {
+ if (inflateEnd(&(xar->stream)) != Z_OK) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Failed to clean up zlib decompressor");
+ r = ARCHIVE_FATAL;
+ }
+ }
+#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
+ if (xar->bzstream_valid) {
+ if (BZ2_bzDecompressEnd(&(xar->bzstream)) != BZ_OK) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Failed to clean up bzip2 decompressor");
+ r = ARCHIVE_FATAL;
+ }
+ }
+#endif
+#if defined(HAVE_LZMA_H) && defined(HAVE_LIBLZMA)
+ if (xar->lzstream_valid)
+ lzma_end(&(xar->lzstream));
+#elif defined(HAVE_LZMA_H) && defined(HAVE_LIBLZMA)
+ if (xar->lzstream_valid) {
+ if (lzmadec_end(&(xar->lzstream)) != LZMADEC_OK) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Failed to clean up lzmadec decompressor");
+ r = ARCHIVE_FATAL;
+ }
+ }
+#endif
+ return (r);
+}
+
+static void
+xmlattr_cleanup(struct xmlattr_list *list)
+{
+ struct xmlattr *attr, *next;
+
+ attr = list->first;
+ while (attr != NULL) {
+ next = attr->next;
+ free(attr->name);
+ free(attr->value);
+ free(attr);
+ attr = next;
+ }
+ list->first = NULL;
+ list->last = &(list->first);
+}
+
+static int
+file_new(struct archive_read *a, struct xar *xar, struct xmlattr_list *list)
+{
+ struct xar_file *file;
+ struct xmlattr *attr;
+
+ file = calloc(1, sizeof(*file));
+ if (file == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
+ file->parent = xar->file;
+ file->mode = 0777 | AE_IFREG;
+ file->atime = time(NULL);
+ file->mtime = time(NULL);
+ xar->file = file;
+ xar->xattr = NULL;
+ for (attr = list->first; attr != NULL; attr = attr->next) {
+ if (strcmp(attr->name, "id") == 0)
+ file->id = atol10(attr->value, strlen(attr->value));
+ }
+ file->nlink = 1;
+ if (heap_add_entry(a, &(xar->file_queue), file) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ return (ARCHIVE_OK);
+}
+
+static void
+file_free(struct xar_file *file)
+{
+ struct xattr *xattr;
+
+ archive_string_free(&(file->pathname));
+ archive_string_free(&(file->symlink));
+ archive_string_free(&(file->uname));
+ archive_string_free(&(file->gname));
+ archive_string_free(&(file->hardlink));
+ xattr = file->xattr_list;
+ while (xattr != NULL) {
+ struct xattr *next;
+
+ next = xattr->next;
+ xattr_free(xattr);
+ xattr = next;
+ }
+
+ free(file);
+}
+
+static int
+xattr_new(struct archive_read *a, struct xar *xar, struct xmlattr_list *list)
+{
+ struct xattr *xattr, **nx;
+ struct xmlattr *attr;
+
+ xattr = calloc(1, sizeof(*xattr));
+ if (xattr == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
+ xar->xattr = xattr;
+ for (attr = list->first; attr != NULL; attr = attr->next) {
+ if (strcmp(attr->name, "id") == 0)
+ xattr->id = atol10(attr->value, strlen(attr->value));
+ }
+ /* Chain to xattr list. */
+ for (nx = &(xar->file->xattr_list);
+ *nx != NULL; nx = &((*nx)->next)) {
+ if (xattr->id < (*nx)->id)
+ break;
+ }
+ xattr->next = *nx;
+ *nx = xattr;
+
+ return (ARCHIVE_OK);
+}
+
+static void
+xattr_free(struct xattr *xattr)
+{
+ archive_string_free(&(xattr->name));
+ free(xattr);
+}
+
+static int
+getencoding(struct xmlattr_list *list)
+{
+ struct xmlattr *attr;
+ enum enctype encoding = NONE;
+
+ for (attr = list->first; attr != NULL; attr = attr->next) {
+ if (strcmp(attr->name, "style") == 0) {
+ if (strcmp(attr->value, "application/octet-stream") == 0)
+ encoding = NONE;
+ else if (strcmp(attr->value, "application/x-gzip") == 0)
+ encoding = GZIP;
+ else if (strcmp(attr->value, "application/x-bzip2") == 0)
+ encoding = BZIP2;
+ else if (strcmp(attr->value, "application/x-lzma") == 0)
+ encoding = LZMA;
+ else if (strcmp(attr->value, "application/x-xz") == 0)
+ encoding = XZ;
+ }
+ }
+ return (encoding);
+}
+
+static int
+getsumalgorithm(struct xmlattr_list *list)
+{
+ struct xmlattr *attr;
+ int alg = CKSUM_NONE;
+
+ for (attr = list->first; attr != NULL; attr = attr->next) {
+ if (strcmp(attr->name, "style") == 0) {
+ const char *v = attr->value;
+ if ((v[0] == 'S' || v[0] == 's') &&
+ (v[1] == 'H' || v[1] == 'h') &&
+ (v[2] == 'A' || v[2] == 'a') &&
+ v[3] == '1' && v[4] == '\0')
+ alg = CKSUM_SHA1;
+ if ((v[0] == 'M' || v[0] == 'm') &&
+ (v[1] == 'D' || v[1] == 'd') &&
+ v[2] == '5' && v[3] == '\0')
+ alg = CKSUM_MD5;
+ }
+ }
+ return (alg);
+}
+
+static int
+unknowntag_start(struct archive_read *a, struct xar *xar, const char *name)
+{
+ struct unknown_tag *tag;
+
+#if DEBUG
+ fprintf(stderr, "unknowntag_start:%s\n", name);
+#endif
+ tag = malloc(sizeof(*tag));
+ if (tag == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
+ tag->next = xar->unknowntags;
+ archive_string_init(&(tag->name));
+ archive_strcpy(&(tag->name), name);
+ if (xar->unknowntags == NULL) {
+ xar->xmlsts_unknown = xar->xmlsts;
+ xar->xmlsts = UNKNOWN;
+ }
+ xar->unknowntags = tag;
+ return (ARCHIVE_OK);
+}
+
+static void
+unknowntag_end(struct xar *xar, const char *name)
+{
+ struct unknown_tag *tag;
+
+#if DEBUG
+ fprintf(stderr, "unknowntag_end:%s\n", name);
+#endif
+ tag = xar->unknowntags;
+ if (tag == NULL || name == NULL)
+ return;
+ if (strcmp(tag->name.s, name) == 0) {
+ xar->unknowntags = tag->next;
+ archive_string_free(&(tag->name));
+ free(tag);
+ if (xar->unknowntags == NULL)
+ xar->xmlsts = xar->xmlsts_unknown;
+ }
+}
+
+static int
+xml_start(struct archive_read *a, const char *name, struct xmlattr_list *list)
+{
+ struct xar *xar;
+ struct xmlattr *attr;
+
+ xar = (struct xar *)(a->format->data);
+
+#if DEBUG
+ fprintf(stderr, "xml_sta:[%s]\n", name);
+ for (attr = list->first; attr != NULL; attr = attr->next)
+ fprintf(stderr, " attr:\"%s\"=\"%s\"\n",
+ attr->name, attr->value);
+#endif
+ xar->base64text = 0;
+ switch (xar->xmlsts) {
+ case INIT:
+ if (strcmp(name, "xar") == 0)
+ xar->xmlsts = XAR;
+ else
+ if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ break;
+ case XAR:
+ if (strcmp(name, "toc") == 0)
+ xar->xmlsts = TOC;
+ else
+ if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ break;
+ case TOC:
+ if (strcmp(name, "creation-time") == 0)
+ xar->xmlsts = TOC_CREATION_TIME;
+ else if (strcmp(name, "checksum") == 0)
+ xar->xmlsts = TOC_CHECKSUM;
+ else if (strcmp(name, "file") == 0) {
+ if (file_new(a, xar, list) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ xar->xmlsts = TOC_FILE;
+ }
+ else
+ if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ break;
+ case TOC_CHECKSUM:
+ if (strcmp(name, "offset") == 0)
+ xar->xmlsts = TOC_CHECKSUM_OFFSET;
+ else if (strcmp(name, "size") == 0)
+ xar->xmlsts = TOC_CHECKSUM_SIZE;
+ else
+ if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ break;
+ case TOC_FILE:
+ if (strcmp(name, "file") == 0) {
+ if (file_new(a, xar, list) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
+ else if (strcmp(name, "data") == 0)
+ xar->xmlsts = FILE_DATA;
+ else if (strcmp(name, "ea") == 0) {
+ if (xattr_new(a, xar, list) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ xar->xmlsts = FILE_EA;
+ }
+ else if (strcmp(name, "ctime") == 0)
+ xar->xmlsts = FILE_CTIME;
+ else if (strcmp(name, "mtime") == 0)
+ xar->xmlsts = FILE_MTIME;
+ else if (strcmp(name, "atime") == 0)
+ xar->xmlsts = FILE_ATIME;
+ else if (strcmp(name, "group") == 0)
+ xar->xmlsts = FILE_GROUP;
+ else if (strcmp(name, "gid") == 0)
+ xar->xmlsts = FILE_GID;
+ else if (strcmp(name, "user") == 0)
+ xar->xmlsts = FILE_USER;
+ else if (strcmp(name, "uid") == 0)
+ xar->xmlsts = FILE_UID;
+ else if (strcmp(name, "mode") == 0)
+ xar->xmlsts = FILE_MODE;
+ else if (strcmp(name, "device") == 0)
+ xar->xmlsts = FILE_DEVICE;
+ else if (strcmp(name, "deviceno") == 0)
+ xar->xmlsts = FILE_DEVICENO;
+ else if (strcmp(name, "inode") == 0)
+ xar->xmlsts = FILE_INODE;
+ else if (strcmp(name, "link") == 0)
+ xar->xmlsts = FILE_LINK;
+ else if (strcmp(name, "type") == 0) {
+ xar->xmlsts = FILE_TYPE;
+ for (attr = list->first; attr != NULL;
+ attr = attr->next) {
+ if (strcmp(attr->name, "link") != 0)
+ continue;
+ if (strcmp(attr->value, "original") == 0) {
+ xar->file->hdnext = xar->hdlink_orgs;
+ xar->hdlink_orgs = xar->file;
+ } else {
+ xar->file->link = atol10(attr->value,
+ strlen(attr->value));
+ if (xar->file->link > 0)
+ if (add_link(a, xar, xar->file) != ARCHIVE_OK) {
+ return (ARCHIVE_FATAL);
+ };
+ }
+ }
+ }
+ else if (strcmp(name, "name") == 0) {
+ xar->xmlsts = FILE_NAME;
+ for (attr = list->first; attr != NULL;
+ attr = attr->next) {
+ if (strcmp(attr->name, "enctype") == 0 &&
+ strcmp(attr->value, "base64") == 0)
+ xar->base64text = 1;
+ }
+ }
+ else if (strcmp(name, "acl") == 0)
+ xar->xmlsts = FILE_ACL;
+ else if (strcmp(name, "flags") == 0)
+ xar->xmlsts = FILE_FLAGS;
+ else if (strcmp(name, "ext2") == 0)
+ xar->xmlsts = FILE_EXT2;
+ else
+ if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ break;
+ case FILE_DATA:
+ if (strcmp(name, "length") == 0)
+ xar->xmlsts = FILE_DATA_LENGTH;
+ else if (strcmp(name, "offset") == 0)
+ xar->xmlsts = FILE_DATA_OFFSET;
+ else if (strcmp(name, "size") == 0)
+ xar->xmlsts = FILE_DATA_SIZE;
+ else if (strcmp(name, "encoding") == 0) {
+ xar->xmlsts = FILE_DATA_ENCODING;
+ xar->file->encoding = getencoding(list);
+ }
+ else if (strcmp(name, "archived-checksum") == 0) {
+ xar->xmlsts = FILE_DATA_A_CHECKSUM;
+ xar->file->a_sum.alg = getsumalgorithm(list);
+ }
+ else if (strcmp(name, "extracted-checksum") == 0) {
+ xar->xmlsts = FILE_DATA_E_CHECKSUM;
+ xar->file->e_sum.alg = getsumalgorithm(list);
+ }
+ else if (strcmp(name, "content") == 0)
+ xar->xmlsts = FILE_DATA_CONTENT;
+ else
+ if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ break;
+ case FILE_DEVICE:
+ if (strcmp(name, "major") == 0)
+ xar->xmlsts = FILE_DEVICE_MAJOR;
+ else if (strcmp(name, "minor") == 0)
+ xar->xmlsts = FILE_DEVICE_MINOR;
+ else
+ if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ break;
+ case FILE_DATA_CONTENT:
+ if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ break;
+ case FILE_EA:
+ if (strcmp(name, "length") == 0)
+ xar->xmlsts = FILE_EA_LENGTH;
+ else if (strcmp(name, "offset") == 0)
+ xar->xmlsts = FILE_EA_OFFSET;
+ else if (strcmp(name, "size") == 0)
+ xar->xmlsts = FILE_EA_SIZE;
+ else if (strcmp(name, "encoding") == 0) {
+ xar->xmlsts = FILE_EA_ENCODING;
+ xar->xattr->encoding = getencoding(list);
+ } else if (strcmp(name, "archived-checksum") == 0)
+ xar->xmlsts = FILE_EA_A_CHECKSUM;
+ else if (strcmp(name, "extracted-checksum") == 0)
+ xar->xmlsts = FILE_EA_E_CHECKSUM;
+ else if (strcmp(name, "name") == 0)
+ xar->xmlsts = FILE_EA_NAME;
+ else if (strcmp(name, "fstype") == 0)
+ xar->xmlsts = FILE_EA_FSTYPE;
+ else
+ if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ break;
+ case FILE_ACL:
+ if (strcmp(name, "appleextended") == 0)
+ xar->xmlsts = FILE_ACL_APPLEEXTENDED;
+ if (strcmp(name, "default") == 0)
+ xar->xmlsts = FILE_ACL_DEFAULT;
+ else if (strcmp(name, "access") == 0)
+ xar->xmlsts = FILE_ACL_ACCESS;
+ else
+ if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ break;
+ case FILE_FLAGS:
+ if (!xml_parse_file_flags(xar, name))
+ if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ break;
+ case FILE_EXT2:
+ if (!xml_parse_file_ext2(xar, name))
+ if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ break;
+ case TOC_CREATION_TIME:
+ case TOC_CHECKSUM_OFFSET:
+ case TOC_CHECKSUM_SIZE:
+ case FILE_DATA_LENGTH:
+ case FILE_DATA_OFFSET:
+ case FILE_DATA_SIZE:
+ case FILE_DATA_ENCODING:
+ case FILE_DATA_A_CHECKSUM:
+ case FILE_DATA_E_CHECKSUM:
+ case FILE_EA_LENGTH:
+ case FILE_EA_OFFSET:
+ case FILE_EA_SIZE:
+ case FILE_EA_ENCODING:
+ case FILE_EA_A_CHECKSUM:
+ case FILE_EA_E_CHECKSUM:
+ case FILE_EA_NAME:
+ case FILE_EA_FSTYPE:
+ case FILE_CTIME:
+ case FILE_MTIME:
+ case FILE_ATIME:
+ case FILE_GROUP:
+ case FILE_GID:
+ case FILE_USER:
+ case FILE_UID:
+ case FILE_INODE:
+ case FILE_DEVICE_MAJOR:
+ case FILE_DEVICE_MINOR:
+ case FILE_DEVICENO:
+ case FILE_MODE:
+ case FILE_TYPE:
+ case FILE_LINK:
+ case FILE_NAME:
+ case FILE_ACL_DEFAULT:
+ case FILE_ACL_ACCESS:
+ case FILE_ACL_APPLEEXTENDED:
+ case FILE_FLAGS_USER_NODUMP:
+ case FILE_FLAGS_USER_IMMUTABLE:
+ case FILE_FLAGS_USER_APPEND:
+ case FILE_FLAGS_USER_OPAQUE:
+ case FILE_FLAGS_USER_NOUNLINK:
+ case FILE_FLAGS_SYS_ARCHIVED:
+ case FILE_FLAGS_SYS_IMMUTABLE:
+ case FILE_FLAGS_SYS_APPEND:
+ case FILE_FLAGS_SYS_NOUNLINK:
+ case FILE_FLAGS_SYS_SNAPSHOT:
+ case FILE_EXT2_SecureDeletion:
+ case FILE_EXT2_Undelete:
+ case FILE_EXT2_Compress:
+ case FILE_EXT2_Synchronous:
+ case FILE_EXT2_Immutable:
+ case FILE_EXT2_AppendOnly:
+ case FILE_EXT2_NoDump:
+ case FILE_EXT2_NoAtime:
+ case FILE_EXT2_CompDirty:
+ case FILE_EXT2_CompBlock:
+ case FILE_EXT2_NoCompBlock:
+ case FILE_EXT2_CompError:
+ case FILE_EXT2_BTree:
+ case FILE_EXT2_HashIndexed:
+ case FILE_EXT2_iMagic:
+ case FILE_EXT2_Journaled:
+ case FILE_EXT2_NoTail:
+ case FILE_EXT2_DirSync:
+ case FILE_EXT2_TopDir:
+ case FILE_EXT2_Reserved:
+ case UNKNOWN:
+ if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ break;
+ }
+ return (ARCHIVE_OK);
+}
+
+static void
+xml_end(void *userData, const char *name)
+{
+ struct archive_read *a;
+ struct xar *xar;
+
+ a = (struct archive_read *)userData;
+ xar = (struct xar *)(a->format->data);
+
+#if DEBUG
+ fprintf(stderr, "xml_end:[%s]\n", name);
+#endif
+ switch (xar->xmlsts) {
+ case INIT:
+ break;
+ case XAR:
+ if (strcmp(name, "xar") == 0)
+ xar->xmlsts = INIT;
+ break;
+ case TOC:
+ if (strcmp(name, "toc") == 0)
+ xar->xmlsts = XAR;
+ break;
+ case TOC_CREATION_TIME:
+ if (strcmp(name, "creation-time") == 0)
+ xar->xmlsts = TOC;
+ break;
+ case TOC_CHECKSUM:
+ if (strcmp(name, "checksum") == 0)
+ xar->xmlsts = TOC;
+ break;
+ case TOC_CHECKSUM_OFFSET:
+ if (strcmp(name, "offset") == 0)
+ xar->xmlsts = TOC_CHECKSUM;
+ break;
+ case TOC_CHECKSUM_SIZE:
+ if (strcmp(name, "size") == 0)
+ xar->xmlsts = TOC_CHECKSUM;
+ break;
+ case TOC_FILE:
+ if (strcmp(name, "file") == 0) {
+ if (xar->file->parent != NULL &&
+ ((xar->file->mode & AE_IFMT) == AE_IFDIR))
+ xar->file->parent->subdirs++;
+ xar->file = xar->file->parent;
+ if (xar->file == NULL)
+ xar->xmlsts = TOC;
+ }
+ break;
+ case FILE_DATA:
+ if (strcmp(name, "data") == 0)
+ xar->xmlsts = TOC_FILE;
+ break;
+ case FILE_DATA_LENGTH:
+ if (strcmp(name, "length") == 0)
+ xar->xmlsts = FILE_DATA;
+ break;
+ case FILE_DATA_OFFSET:
+ if (strcmp(name, "offset") == 0)
+ xar->xmlsts = FILE_DATA;
+ break;
+ case FILE_DATA_SIZE:
+ if (strcmp(name, "size") == 0)
+ xar->xmlsts = FILE_DATA;
+ break;
+ case FILE_DATA_ENCODING:
+ if (strcmp(name, "encoding") == 0)
+ xar->xmlsts = FILE_DATA;
+ break;
+ case FILE_DATA_A_CHECKSUM:
+ if (strcmp(name, "archived-checksum") == 0)
+ xar->xmlsts = FILE_DATA;
+ break;
+ case FILE_DATA_E_CHECKSUM:
+ if (strcmp(name, "extracted-checksum") == 0)
+ xar->xmlsts = FILE_DATA;
+ break;
+ case FILE_DATA_CONTENT:
+ if (strcmp(name, "content") == 0)
+ xar->xmlsts = FILE_DATA;
+ break;
+ case FILE_EA:
+ if (strcmp(name, "ea") == 0) {
+ xar->xmlsts = TOC_FILE;
+ xar->xattr = NULL;
+ }
+ break;
+ case FILE_EA_LENGTH:
+ if (strcmp(name, "length") == 0)
+ xar->xmlsts = FILE_EA;
+ break;
+ case FILE_EA_OFFSET:
+ if (strcmp(name, "offset") == 0)
+ xar->xmlsts = FILE_EA;
+ break;
+ case FILE_EA_SIZE:
+ if (strcmp(name, "size") == 0)
+ xar->xmlsts = FILE_EA;
+ break;
+ case FILE_EA_ENCODING:
+ if (strcmp(name, "encoding") == 0)
+ xar->xmlsts = FILE_EA;
+ break;
+ case FILE_EA_A_CHECKSUM:
+ if (strcmp(name, "archived-checksum") == 0)
+ xar->xmlsts = FILE_EA;
+ break;
+ case FILE_EA_E_CHECKSUM:
+ if (strcmp(name, "extracted-checksum") == 0)
+ xar->xmlsts = FILE_EA;
+ break;
+ case FILE_EA_NAME:
+ if (strcmp(name, "name") == 0)
+ xar->xmlsts = FILE_EA;
+ break;
+ case FILE_EA_FSTYPE:
+ if (strcmp(name, "fstype") == 0)
+ xar->xmlsts = FILE_EA;
+ break;
+ case FILE_CTIME:
+ if (strcmp(name, "ctime") == 0)
+ xar->xmlsts = TOC_FILE;
+ break;
+ case FILE_MTIME:
+ if (strcmp(name, "mtime") == 0)
+ xar->xmlsts = TOC_FILE;
+ break;
+ case FILE_ATIME:
+ if (strcmp(name, "atime") == 0)
+ xar->xmlsts = TOC_FILE;
+ break;
+ case FILE_GROUP:
+ if (strcmp(name, "group") == 0)
+ xar->xmlsts = TOC_FILE;
+ break;
+ case FILE_GID:
+ if (strcmp(name, "gid") == 0)
+ xar->xmlsts = TOC_FILE;
+ break;
+ case FILE_USER:
+ if (strcmp(name, "user") == 0)
+ xar->xmlsts = TOC_FILE;
+ break;
+ case FILE_UID:
+ if (strcmp(name, "uid") == 0)
+ xar->xmlsts = TOC_FILE;
+ break;
+ case FILE_MODE:
+ if (strcmp(name, "mode") == 0)
+ xar->xmlsts = TOC_FILE;
+ break;
+ case FILE_DEVICE:
+ if (strcmp(name, "device") == 0)
+ xar->xmlsts = TOC_FILE;
+ break;
+ case FILE_DEVICE_MAJOR:
+ if (strcmp(name, "major") == 0)
+ xar->xmlsts = FILE_DEVICE;
+ break;
+ case FILE_DEVICE_MINOR:
+ if (strcmp(name, "minor") == 0)
+ xar->xmlsts = FILE_DEVICE;
+ break;
+ case FILE_DEVICENO:
+ if (strcmp(name, "deviceno") == 0)
+ xar->xmlsts = TOC_FILE;
+ break;
+ case FILE_INODE:
+ if (strcmp(name, "inode") == 0)
+ xar->xmlsts = TOC_FILE;
+ break;
+ case FILE_LINK:
+ if (strcmp(name, "link") == 0)
+ xar->xmlsts = TOC_FILE;
+ break;
+ case FILE_TYPE:
+ if (strcmp(name, "type") == 0)
+ xar->xmlsts = TOC_FILE;
+ break;
+ case FILE_NAME:
+ if (strcmp(name, "name") == 0)
+ xar->xmlsts = TOC_FILE;
+ break;
+ case FILE_ACL:
+ if (strcmp(name, "acl") == 0)
+ xar->xmlsts = TOC_FILE;
+ break;
+ case FILE_ACL_DEFAULT:
+ if (strcmp(name, "default") == 0)
+ xar->xmlsts = FILE_ACL;
+ break;
+ case FILE_ACL_ACCESS:
+ if (strcmp(name, "access") == 0)
+ xar->xmlsts = FILE_ACL;
+ break;
+ case FILE_ACL_APPLEEXTENDED:
+ if (strcmp(name, "appleextended") == 0)
+ xar->xmlsts = FILE_ACL;
+ break;
+ case FILE_FLAGS:
+ if (strcmp(name, "flags") == 0)
+ xar->xmlsts = TOC_FILE;
+ break;
+ case FILE_FLAGS_USER_NODUMP:
+ if (strcmp(name, "UserNoDump") == 0)
+ xar->xmlsts = FILE_FLAGS;
+ break;
+ case FILE_FLAGS_USER_IMMUTABLE:
+ if (strcmp(name, "UserImmutable") == 0)
+ xar->xmlsts = FILE_FLAGS;
+ break;
+ case FILE_FLAGS_USER_APPEND:
+ if (strcmp(name, "UserAppend") == 0)
+ xar->xmlsts = FILE_FLAGS;
+ break;
+ case FILE_FLAGS_USER_OPAQUE:
+ if (strcmp(name, "UserOpaque") == 0)
+ xar->xmlsts = FILE_FLAGS;
+ break;
+ case FILE_FLAGS_USER_NOUNLINK:
+ if (strcmp(name, "UserNoUnlink") == 0)
+ xar->xmlsts = FILE_FLAGS;
+ break;
+ case FILE_FLAGS_SYS_ARCHIVED:
+ if (strcmp(name, "SystemArchived") == 0)
+ xar->xmlsts = FILE_FLAGS;
+ break;
+ case FILE_FLAGS_SYS_IMMUTABLE:
+ if (strcmp(name, "SystemImmutable") == 0)
+ xar->xmlsts = FILE_FLAGS;
+ break;
+ case FILE_FLAGS_SYS_APPEND:
+ if (strcmp(name, "SystemAppend") == 0)
+ xar->xmlsts = FILE_FLAGS;
+ break;
+ case FILE_FLAGS_SYS_NOUNLINK:
+ if (strcmp(name, "SystemNoUnlink") == 0)
+ xar->xmlsts = FILE_FLAGS;
+ break;
+ case FILE_FLAGS_SYS_SNAPSHOT:
+ if (strcmp(name, "SystemSnapshot") == 0)
+ xar->xmlsts = FILE_FLAGS;
+ break;
+ case FILE_EXT2:
+ if (strcmp(name, "ext2") == 0)
+ xar->xmlsts = TOC_FILE;
+ break;
+ case FILE_EXT2_SecureDeletion:
+ if (strcmp(name, "SecureDeletion") == 0)
+ xar->xmlsts = FILE_EXT2;
+ break;
+ case FILE_EXT2_Undelete:
+ if (strcmp(name, "Undelete") == 0)
+ xar->xmlsts = FILE_EXT2;
+ break;
+ case FILE_EXT2_Compress:
+ if (strcmp(name, "Compress") == 0)
+ xar->xmlsts = FILE_EXT2;
+ break;
+ case FILE_EXT2_Synchronous:
+ if (strcmp(name, "Synchronous") == 0)
+ xar->xmlsts = FILE_EXT2;
+ break;
+ case FILE_EXT2_Immutable:
+ if (strcmp(name, "Immutable") == 0)
+ xar->xmlsts = FILE_EXT2;
+ break;
+ case FILE_EXT2_AppendOnly:
+ if (strcmp(name, "AppendOnly") == 0)
+ xar->xmlsts = FILE_EXT2;
+ break;
+ case FILE_EXT2_NoDump:
+ if (strcmp(name, "NoDump") == 0)
+ xar->xmlsts = FILE_EXT2;
+ break;
+ case FILE_EXT2_NoAtime:
+ if (strcmp(name, "NoAtime") == 0)
+ xar->xmlsts = FILE_EXT2;
+ break;
+ case FILE_EXT2_CompDirty:
+ if (strcmp(name, "CompDirty") == 0)
+ xar->xmlsts = FILE_EXT2;
+ break;
+ case FILE_EXT2_CompBlock:
+ if (strcmp(name, "CompBlock") == 0)
+ xar->xmlsts = FILE_EXT2;
+ break;
+ case FILE_EXT2_NoCompBlock:
+ if (strcmp(name, "NoCompBlock") == 0)
+ xar->xmlsts = FILE_EXT2;
+ break;
+ case FILE_EXT2_CompError:
+ if (strcmp(name, "CompError") == 0)
+ xar->xmlsts = FILE_EXT2;
+ break;
+ case FILE_EXT2_BTree:
+ if (strcmp(name, "BTree") == 0)
+ xar->xmlsts = FILE_EXT2;
+ break;
+ case FILE_EXT2_HashIndexed:
+ if (strcmp(name, "HashIndexed") == 0)
+ xar->xmlsts = FILE_EXT2;
+ break;
+ case FILE_EXT2_iMagic:
+ if (strcmp(name, "iMagic") == 0)
+ xar->xmlsts = FILE_EXT2;
+ break;
+ case FILE_EXT2_Journaled:
+ if (strcmp(name, "Journaled") == 0)
+ xar->xmlsts = FILE_EXT2;
+ break;
+ case FILE_EXT2_NoTail:
+ if (strcmp(name, "NoTail") == 0)
+ xar->xmlsts = FILE_EXT2;
+ break;
+ case FILE_EXT2_DirSync:
+ if (strcmp(name, "DirSync") == 0)
+ xar->xmlsts = FILE_EXT2;
+ break;
+ case FILE_EXT2_TopDir:
+ if (strcmp(name, "TopDir") == 0)
+ xar->xmlsts = FILE_EXT2;
+ break;
+ case FILE_EXT2_Reserved:
+ if (strcmp(name, "Reserved") == 0)
+ xar->xmlsts = FILE_EXT2;
+ break;
+ case UNKNOWN:
+ unknowntag_end(xar, name);
+ break;
+ }
+}
+
+static const int base64[256] = {
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, /* 00 - 0F */
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, /* 10 - 1F */
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 62, -1, -1, -1, 63, /* 20 - 2F */
+ 52, 53, 54, 55, 56, 57, 58, 59,
+ 60, 61, -1, -1, -1, -1, -1, -1, /* 30 - 3F */
+ -1, 0, 1, 2, 3, 4, 5, 6,
+ 7, 8, 9, 10, 11, 12, 13, 14, /* 40 - 4F */
+ 15, 16, 17, 18, 19, 20, 21, 22,
+ 23, 24, 25, -1, -1, -1, -1, -1, /* 50 - 5F */
+ -1, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 36, 37, 38, 39, 40, /* 60 - 6F */
+ 41, 42, 43, 44, 45, 46, 47, 48,
+ 49, 50, 51, -1, -1, -1, -1, -1, /* 70 - 7F */
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, /* 80 - 8F */
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, /* 90 - 9F */
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, /* A0 - AF */
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, /* B0 - BF */
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, /* C0 - CF */
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, /* D0 - DF */
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, /* E0 - EF */
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, /* F0 - FF */
+};
+
+static void
+strappend_base64(struct xar *xar,
+ struct archive_string *as, const char *s, size_t l)
+{
+ unsigned char buff[256];
+ unsigned char *out;
+ const unsigned char *b;
+ size_t len;
+
+ len = 0;
+ out = buff;
+ b = (const unsigned char *)s;
+ while (l > 0) {
+ int n = 0;
+
+ if (l > 0) {
+ if (base64[b[0]] < 0 || base64[b[1]] < 0)
+ break;
+ n = base64[*b++] << 18;
+ n |= base64[*b++] << 12;
+ *out++ = n >> 16;
+ len++;
+ l -= 2;
+ }
+ if (l > 0) {
+ if (base64[*b] < 0)
+ break;
+ n |= base64[*b++] << 6;
+ *out++ = (n >> 8) & 0xFF;
+ len++;
+ --l;
+ }
+ if (l > 0) {
+ if (base64[*b] < 0)
+ break;
+ n |= base64[*b++];
+ *out++ = n & 0xFF;
+ len++;
+ --l;
+ }
+ if (len+3 >= sizeof(buff)) {
+ archive_strncat(as, (const char *)buff, len);
+ len = 0;
+ out = buff;
+ }
+ }
+ if (len > 0)
+ archive_strncat(as, (const char *)buff, len);
+}
+
+static void
+xml_data(void *userData, const char *s, int len)
+{
+ struct archive_read *a;
+ struct xar *xar;
+
+ a = (struct archive_read *)userData;
+ xar = (struct xar *)(a->format->data);
+
+#if DEBUG
+ {
+ char buff[1024];
+ if (len > sizeof(buff)-1)
+ len = sizeof(buff)-1;
+ memcpy(buff, s, len);
+ buff[len] = 0;
+ fprintf(stderr, "\tlen=%d:\"%s\"\n", len, buff);
+ }
+#endif
+ switch (xar->xmlsts) {
+ case TOC_CHECKSUM_OFFSET:
+ xar->toc_chksum_offset = atol10(s, len);
+ break;
+ case TOC_CHECKSUM_SIZE:
+ xar->toc_chksum_size = atol10(s, len);
+ break;
+ default:
+ break;
+ }
+ if (xar->file == NULL)
+ return;
+
+ switch (xar->xmlsts) {
+ case FILE_NAME:
+ if (xar->file->parent != NULL) {
+ archive_string_concat(&(xar->file->pathname),
+ &(xar->file->parent->pathname));
+ archive_strappend_char(&(xar->file->pathname), '/');
+ }
+ xar->file->has |= HAS_PATHNAME;
+ if (xar->base64text) {
+ strappend_base64(xar,
+ &(xar->file->pathname), s, len);
+ } else
+ archive_strncat(&(xar->file->pathname), s, len);
+ break;
+ case FILE_LINK:
+ xar->file->has |= HAS_SYMLINK;
+ archive_strncpy(&(xar->file->symlink), s, len);
+ break;
+ case FILE_TYPE:
+ if (strncmp("file", s, len) == 0 ||
+ strncmp("hardlink", s, len) == 0)
+ xar->file->mode =
+ (xar->file->mode & ~AE_IFMT) | AE_IFREG;
+ if (strncmp("directory", s, len) == 0)
+ xar->file->mode =
+ (xar->file->mode & ~AE_IFMT) | AE_IFDIR;
+ if (strncmp("symlink", s, len) == 0)
+ xar->file->mode =
+ (xar->file->mode & ~AE_IFMT) | AE_IFLNK;
+ if (strncmp("character special", s, len) == 0)
+ xar->file->mode =
+ (xar->file->mode & ~AE_IFMT) | AE_IFCHR;
+ if (strncmp("block special", s, len) == 0)
+ xar->file->mode =
+ (xar->file->mode & ~AE_IFMT) | AE_IFBLK;
+ if (strncmp("socket", s, len) == 0)
+ xar->file->mode =
+ (xar->file->mode & ~AE_IFMT) | AE_IFSOCK;
+ if (strncmp("fifo", s, len) == 0)
+ xar->file->mode =
+ (xar->file->mode & ~AE_IFMT) | AE_IFIFO;
+ xar->file->has |= HAS_TYPE;
+ break;
+ case FILE_INODE:
+ xar->file->has |= HAS_INO;
+ xar->file->ino64 = atol10(s, len);
+ break;
+ case FILE_DEVICE_MAJOR:
+ xar->file->has |= HAS_DEVMAJOR;
+ xar->file->devmajor = (dev_t)atol10(s, len);
+ break;
+ case FILE_DEVICE_MINOR:
+ xar->file->has |= HAS_DEVMINOR;
+ xar->file->devminor = (dev_t)atol10(s, len);
+ break;
+ case FILE_DEVICENO:
+ xar->file->has |= HAS_DEV;
+ xar->file->dev = (dev_t)atol10(s, len);
+ break;
+ case FILE_MODE:
+ xar->file->has |= HAS_MODE;
+ xar->file->mode =
+ (xar->file->mode & AE_IFMT) |
+ (atol8(s, len) & ~AE_IFMT);
+ break;
+ case FILE_GROUP:
+ xar->file->has |= HAS_GID;
+ archive_strncpy(&(xar->file->gname), s, len);
+ break;
+ case FILE_GID:
+ xar->file->has |= HAS_GID;
+ xar->file->gid = atol10(s, len);
+ break;
+ case FILE_USER:
+ xar->file->has |= HAS_UID;
+ archive_strncpy(&(xar->file->uname), s, len);
+ break;
+ case FILE_UID:
+ xar->file->has |= HAS_UID;
+ xar->file->uid = atol10(s, len);
+ break;
+ case FILE_CTIME:
+ xar->file->has |= HAS_TIME;
+ xar->file->ctime = parse_time(s, len);
+ break;
+ case FILE_MTIME:
+ xar->file->has |= HAS_TIME;
+ xar->file->mtime = parse_time(s, len);
+ break;
+ case FILE_ATIME:
+ xar->file->has |= HAS_TIME;
+ xar->file->atime = parse_time(s, len);
+ break;
+ case FILE_DATA_LENGTH:
+ xar->file->has |= HAS_DATA;
+ xar->file->length = atol10(s, len);
+ break;
+ case FILE_DATA_OFFSET:
+ xar->file->has |= HAS_DATA;
+ xar->file->offset = atol10(s, len);
+ break;
+ case FILE_DATA_SIZE:
+ xar->file->has |= HAS_DATA;
+ xar->file->size = atol10(s, len);
+ break;
+ case FILE_DATA_A_CHECKSUM:
+ xar->file->a_sum.len = atohex(xar->file->a_sum.val,
+ sizeof(xar->file->a_sum.val), s, len);
+ break;
+ case FILE_DATA_E_CHECKSUM:
+ xar->file->e_sum.len = atohex(xar->file->e_sum.val,
+ sizeof(xar->file->e_sum.val), s, len);
+ break;
+ case FILE_EA_LENGTH:
+ xar->file->has |= HAS_XATTR;
+ xar->xattr->length = atol10(s, len);
+ break;
+ case FILE_EA_OFFSET:
+ xar->file->has |= HAS_XATTR;
+ xar->xattr->offset = atol10(s, len);
+ break;
+ case FILE_EA_SIZE:
+ xar->file->has |= HAS_XATTR;
+ xar->xattr->size = atol10(s, len);
+ break;
+ case FILE_EA_A_CHECKSUM:
+ xar->file->has |= HAS_XATTR;
+ xar->xattr->a_sum.len = atohex(xar->xattr->a_sum.val,
+ sizeof(xar->xattr->a_sum.val), s, len);
+ break;
+ case FILE_EA_E_CHECKSUM:
+ xar->file->has |= HAS_XATTR;
+ xar->xattr->e_sum.len = atohex(xar->xattr->e_sum.val,
+ sizeof(xar->xattr->e_sum.val), s, len);
+ break;
+ case FILE_EA_NAME:
+ xar->file->has |= HAS_XATTR;
+ archive_strncpy(&(xar->xattr->name), s, len);
+ break;
+ case FILE_EA_FSTYPE:
+ xar->file->has |= HAS_XATTR;
+ archive_strncpy(&(xar->xattr->fstype), s, len);
+ break;
+ break;
+ case FILE_ACL_DEFAULT:
+ case FILE_ACL_ACCESS:
+ case FILE_ACL_APPLEEXTENDED:
+ xar->file->has |= HAS_ACL;
+ /* TODO */
+ break;
+ case INIT:
+ case XAR:
+ case TOC:
+ case TOC_CREATION_TIME:
+ case TOC_CHECKSUM:
+ case TOC_CHECKSUM_OFFSET:
+ case TOC_CHECKSUM_SIZE:
+ case TOC_FILE:
+ case FILE_DATA:
+ case FILE_DATA_ENCODING:
+ case FILE_DATA_CONTENT:
+ case FILE_DEVICE:
+ case FILE_EA:
+ case FILE_EA_ENCODING:
+ case FILE_ACL:
+ case FILE_FLAGS:
+ case FILE_FLAGS_USER_NODUMP:
+ case FILE_FLAGS_USER_IMMUTABLE:
+ case FILE_FLAGS_USER_APPEND:
+ case FILE_FLAGS_USER_OPAQUE:
+ case FILE_FLAGS_USER_NOUNLINK:
+ case FILE_FLAGS_SYS_ARCHIVED:
+ case FILE_FLAGS_SYS_IMMUTABLE:
+ case FILE_FLAGS_SYS_APPEND:
+ case FILE_FLAGS_SYS_NOUNLINK:
+ case FILE_FLAGS_SYS_SNAPSHOT:
+ case FILE_EXT2:
+ case FILE_EXT2_SecureDeletion:
+ case FILE_EXT2_Undelete:
+ case FILE_EXT2_Compress:
+ case FILE_EXT2_Synchronous:
+ case FILE_EXT2_Immutable:
+ case FILE_EXT2_AppendOnly:
+ case FILE_EXT2_NoDump:
+ case FILE_EXT2_NoAtime:
+ case FILE_EXT2_CompDirty:
+ case FILE_EXT2_CompBlock:
+ case FILE_EXT2_NoCompBlock:
+ case FILE_EXT2_CompError:
+ case FILE_EXT2_BTree:
+ case FILE_EXT2_HashIndexed:
+ case FILE_EXT2_iMagic:
+ case FILE_EXT2_Journaled:
+ case FILE_EXT2_NoTail:
+ case FILE_EXT2_DirSync:
+ case FILE_EXT2_TopDir:
+ case FILE_EXT2_Reserved:
+ case UNKNOWN:
+ break;
+ }
+}
+
+/*
+ * BSD file flags.
+ */
+static int
+xml_parse_file_flags(struct xar *xar, const char *name)
+{
+ const char *flag = NULL;
+
+ if (strcmp(name, "UserNoDump") == 0) {
+ xar->xmlsts = FILE_FLAGS_USER_NODUMP;
+ flag = "nodump";
+ }
+ else if (strcmp(name, "UserImmutable") == 0) {
+ xar->xmlsts = FILE_FLAGS_USER_IMMUTABLE;
+ flag = "uimmutable";
+ }
+ else if (strcmp(name, "UserAppend") == 0) {
+ xar->xmlsts = FILE_FLAGS_USER_APPEND;
+ flag = "uappend";
+ }
+ else if (strcmp(name, "UserOpaque") == 0) {
+ xar->xmlsts = FILE_FLAGS_USER_OPAQUE;
+ flag = "opaque";
+ }
+ else if (strcmp(name, "UserNoUnlink") == 0) {
+ xar->xmlsts = FILE_FLAGS_USER_NOUNLINK;
+ flag = "nouunlink";
+ }
+ else if (strcmp(name, "SystemArchived") == 0) {
+ xar->xmlsts = FILE_FLAGS_SYS_ARCHIVED;
+ flag = "archived";
+ }
+ else if (strcmp(name, "SystemImmutable") == 0) {
+ xar->xmlsts = FILE_FLAGS_SYS_IMMUTABLE;
+ flag = "simmutable";
+ }
+ else if (strcmp(name, "SystemAppend") == 0) {
+ xar->xmlsts = FILE_FLAGS_SYS_APPEND;
+ flag = "sappend";
+ }
+ else if (strcmp(name, "SystemNoUnlink") == 0) {
+ xar->xmlsts = FILE_FLAGS_SYS_NOUNLINK;
+ flag = "nosunlink";
+ }
+ else if (strcmp(name, "SystemSnapshot") == 0) {
+ xar->xmlsts = FILE_FLAGS_SYS_SNAPSHOT;
+ flag = "snapshot";
+ }
+
+ if (flag == NULL)
+ return (0);
+ xar->file->has |= HAS_FFLAGS;
+ if (archive_strlen(&(xar->file->fflags_text)) > 0)
+ archive_strappend_char(&(xar->file->fflags_text), ',');
+ archive_strcat(&(xar->file->fflags_text), flag);
+ return (1);
+}
+
+/*
+ * Linux file flags.
+ */
+static int
+xml_parse_file_ext2(struct xar *xar, const char *name)
+{
+ const char *flag = NULL;
+
+ if (strcmp(name, "SecureDeletion") == 0) {
+ xar->xmlsts = FILE_EXT2_SecureDeletion;
+ flag = "securedeletion";
+ }
+ else if (strcmp(name, "Undelete") == 0) {
+ xar->xmlsts = FILE_EXT2_Undelete;
+ flag = "nouunlink";
+ }
+ else if (strcmp(name, "Compress") == 0) {
+ xar->xmlsts = FILE_EXT2_Compress;
+ flag = "compress";
+ }
+ else if (strcmp(name, "Synchronous") == 0) {
+ xar->xmlsts = FILE_EXT2_Synchronous;
+ flag = "sync";
+ }
+ else if (strcmp(name, "Immutable") == 0) {
+ xar->xmlsts = FILE_EXT2_Immutable;
+ flag = "simmutable";
+ }
+ else if (strcmp(name, "AppendOnly") == 0) {
+ xar->xmlsts = FILE_EXT2_AppendOnly;
+ flag = "sappend";
+ }
+ else if (strcmp(name, "NoDump") == 0) {
+ xar->xmlsts = FILE_EXT2_NoDump;
+ flag = "nodump";
+ }
+ else if (strcmp(name, "NoAtime") == 0) {
+ xar->xmlsts = FILE_EXT2_NoAtime;
+ flag = "noatime";
+ }
+ else if (strcmp(name, "CompDirty") == 0) {
+ xar->xmlsts = FILE_EXT2_CompDirty;
+ flag = "compdirty";
+ }
+ else if (strcmp(name, "CompBlock") == 0) {
+ xar->xmlsts = FILE_EXT2_CompBlock;
+ flag = "comprblk";
+ }
+ else if (strcmp(name, "NoCompBlock") == 0) {
+ xar->xmlsts = FILE_EXT2_NoCompBlock;
+ flag = "nocomprblk";
+ }
+ else if (strcmp(name, "CompError") == 0) {
+ xar->xmlsts = FILE_EXT2_CompError;
+ flag = "comperr";
+ }
+ else if (strcmp(name, "BTree") == 0) {
+ xar->xmlsts = FILE_EXT2_BTree;
+ flag = "btree";
+ }
+ else if (strcmp(name, "HashIndexed") == 0) {
+ xar->xmlsts = FILE_EXT2_HashIndexed;
+ flag = "hashidx";
+ }
+ else if (strcmp(name, "iMagic") == 0) {
+ xar->xmlsts = FILE_EXT2_iMagic;
+ flag = "imagic";
+ }
+ else if (strcmp(name, "Journaled") == 0) {
+ xar->xmlsts = FILE_EXT2_Journaled;
+ flag = "journal";
+ }
+ else if (strcmp(name, "NoTail") == 0) {
+ xar->xmlsts = FILE_EXT2_NoTail;
+ flag = "notail";
+ }
+ else if (strcmp(name, "DirSync") == 0) {
+ xar->xmlsts = FILE_EXT2_DirSync;
+ flag = "dirsync";
+ }
+ else if (strcmp(name, "TopDir") == 0) {
+ xar->xmlsts = FILE_EXT2_TopDir;
+ flag = "topdir";
+ }
+ else if (strcmp(name, "Reserved") == 0) {
+ xar->xmlsts = FILE_EXT2_Reserved;
+ flag = "reserved";
+ }
+
+ if (flag == NULL)
+ return (0);
+ if (archive_strlen(&(xar->file->fflags_text)) > 0)
+ archive_strappend_char(&(xar->file->fflags_text), ',');
+ archive_strcat(&(xar->file->fflags_text), flag);
+ return (1);
+}
+
+#ifdef HAVE_LIBXML_XMLREADER_H
+
+static int
+xml2_xmlattr_setup(struct archive_read *a,
+ struct xmlattr_list *list, xmlTextReaderPtr reader)
+{
+ struct xmlattr *attr;
+ int r;
+
+ list->first = NULL;
+ list->last = &(list->first);
+ r = xmlTextReaderMoveToFirstAttribute(reader);
+ while (r == 1) {
+ attr = malloc(sizeof*(attr));
+ if (attr == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
+ attr->name = strdup(
+ (const char *)xmlTextReaderConstLocalName(reader));
+ if (attr->name == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
+ attr->value = strdup(
+ (const char *)xmlTextReaderConstValue(reader));
+ if (attr->value == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
+ attr->next = NULL;
+ *list->last = attr;
+ list->last = &(attr->next);
+ r = xmlTextReaderMoveToNextAttribute(reader);
+ }
+ return (r);
+}
+
+static int
+xml2_read_cb(void *context, char *buffer, int len)
+{
+ struct archive_read *a;
+ struct xar *xar;
+ const void *d;
+ size_t outbytes;
+ size_t used;
+ int r;
+
+ a = (struct archive_read *)context;
+ xar = (struct xar *)(a->format->data);
+
+ if (xar->toc_remaining <= 0)
+ return (0);
+ d = buffer;
+ outbytes = len;
+ r = rd_contents(a, &d, &outbytes, &used, xar->toc_remaining);
+ if (r != ARCHIVE_OK)
+ return (r);
+ __archive_read_consume(a, used);
+ xar->toc_remaining -= used;
+ xar->offset += used;
+ xar->toc_total += outbytes;
+ PRINT_TOC(buffer, len);
+
+ return ((int)outbytes);
+}
+
+static int
+xml2_close_cb(void *context)
+{
+
+ (void)context; /* UNUSED */
+ return (0);
+}
+
+static void
+xml2_error_hdr(void *arg, const char *msg, xmlParserSeverities severity,
+ xmlTextReaderLocatorPtr locator)
+{
+ struct archive_read *a;
+
+ (void)locator; /* UNUSED */
+ a = (struct archive_read *)arg;
+ switch (severity) {
+ case XML_PARSER_SEVERITY_VALIDITY_WARNING:
+ case XML_PARSER_SEVERITY_WARNING:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "XML Parsing error: %s", msg);
+ break;
+ case XML_PARSER_SEVERITY_VALIDITY_ERROR:
+ case XML_PARSER_SEVERITY_ERROR:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "XML Parsing error: %s", msg);
+ break;
+ }
+}
+
+static int
+xml2_read_toc(struct archive_read *a)
+{
+ xmlTextReaderPtr reader;
+ struct xmlattr_list list;
+ int r;
+
+ reader = xmlReaderForIO(xml2_read_cb, xml2_close_cb, a, NULL, NULL, 0);
+ if (reader == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Couldn't allocate memory for xml parser");
+ return (ARCHIVE_FATAL);
+ }
+ xmlTextReaderSetErrorHandler(reader, xml2_error_hdr, a);
+
+ while ((r = xmlTextReaderRead(reader)) == 1) {
+ const char *name, *value;
+ int type, empty;
+
+ type = xmlTextReaderNodeType(reader);
+ name = (const char *)xmlTextReaderConstLocalName(reader);
+ switch (type) {
+ 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);
+ xmlattr_cleanup(&list);
+ if (r != ARCHIVE_OK)
+ return (r);
+ if (empty)
+ xml_end(a, name);
+ break;
+ case XML_READER_TYPE_END_ELEMENT:
+ xml_end(a, name);
+ break;
+ case XML_READER_TYPE_TEXT:
+ value = (const char *)xmlTextReaderConstValue(reader);
+ xml_data(a, value, strlen(value));
+ break;
+ case XML_READER_TYPE_SIGNIFICANT_WHITESPACE:
+ default:
+ break;
+ }
+ if (r < 0)
+ break;
+ }
+ xmlFreeTextReader(reader);
+ xmlCleanupParser();
+
+ return ((r == 0)?ARCHIVE_OK:ARCHIVE_FATAL);
+}
+
+#elif defined(HAVE_BSDXML_H) || defined(HAVE_EXPAT_H)
+
+static int
+expat_xmlattr_setup(struct archive_read *a,
+ struct xmlattr_list *list, const XML_Char **atts)
+{
+ struct xmlattr *attr;
+ char *name, *value;
+
+ list->first = NULL;
+ list->last = &(list->first);
+ if (atts == NULL)
+ return (ARCHIVE_OK);
+ while (atts[0] != NULL && atts[1] != NULL) {
+ attr = malloc(sizeof*(attr));
+ name = strdup(atts[0]);
+ value = strdup(atts[1]);
+ if (attr == NULL || name == NULL || value == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
+ attr->name = name;
+ attr->value = value;
+ attr->next = NULL;
+ *list->last = attr;
+ list->last = &(attr->next);
+ atts += 2;
+ }
+ return (ARCHIVE_OK);
+}
+
+static void
+expat_start_cb(void *userData, const XML_Char *name, const XML_Char **atts)
+{
+ struct expat_userData *ud = (struct expat_userData *)userData;
+ struct archive_read *a = ud->archive;
+ struct xmlattr_list list;
+ int r;
+
+ r = expat_xmlattr_setup(a, &list, atts);
+ if (r == ARCHIVE_OK)
+ r = xml_start(a, (const char *)name, &list);
+ xmlattr_cleanup(&list);
+ ud->state = r;
+}
+
+static void
+expat_end_cb(void *userData, const XML_Char *name)
+{
+ struct expat_userData *ud = (struct expat_userData *)userData;
+
+ xml_end(ud->archive, (const char *)name);
+}
+
+static void
+expat_data_cb(void *userData, const XML_Char *s, int len)
+{
+ struct expat_userData *ud = (struct expat_userData *)userData;
+
+ xml_data(ud->archive, s, len);
+}
+
+static int
+expat_read_toc(struct archive_read *a)
+{
+ struct xar *xar;
+ XML_Parser parser;
+ struct expat_userData ud;
+
+ ud.state = ARCHIVE_OK;
+ ud.archive = a;
+
+ xar = (struct xar *)(a->format->data);
+
+ /* Initialize XML Parser library. */
+ parser = XML_ParserCreate(NULL);
+ if (parser == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Couldn't allocate memory for xml parser");
+ return (ARCHIVE_FATAL);
+ }
+ XML_SetUserData(parser, &ud);
+ XML_SetElementHandler(parser, expat_start_cb, expat_end_cb);
+ XML_SetCharacterDataHandler(parser, expat_data_cb);
+ xar->xmlsts = INIT;
+
+ while (xar->toc_remaining && ud.state == ARCHIVE_OK) {
+ enum XML_Status xr;
+ const void *d;
+ size_t outbytes;
+ size_t used;
+ int r;
+
+ d = NULL;
+ r = rd_contents(a, &d, &outbytes, &used, xar->toc_remaining);
+ if (r != ARCHIVE_OK)
+ return (r);
+ xar->toc_remaining -= used;
+ xar->offset += used;
+ xar->toc_total += outbytes;
+ PRINT_TOC(d, outbytes);
+
+ xr = XML_Parse(parser, d, outbytes, xar->toc_remaining == 0);
+ __archive_read_consume(a, used);
+ if (xr == XML_STATUS_ERROR) {
+ XML_ParserFree(parser);
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "XML Parsing failed");
+ return (ARCHIVE_FATAL);
+ }
+ }
+ XML_ParserFree(parser);
+ return (ud.state);
+}
+#endif /* defined(HAVE_BSDXML_H) || defined(HAVE_EXPAT_H) */
+
+#endif /* Support xar format */
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c
new file mode 100644
index 000000000..d15080263
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c
@@ -0,0 +1,1266 @@
+/*-
+ * Copyright (c) 2004 Tim Kientzle
+ * 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"
+__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_zip.c 201102 2009-12-28 03:11:36Z kientzle $");
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_ZLIB_H
+#include <cm_zlib.h>
+#endif
+
+#include "archive.h"
+#include "archive_entry.h"
+#include "archive_entry_locale.h"
+#include "archive_private.h"
+#include "archive_read_private.h"
+#include "archive_endian.h"
+
+#ifndef HAVE_ZLIB_H
+#include "archive_crc32.h"
+#endif
+
+struct zip_entry {
+ int64_t local_header_offset;
+ int64_t compressed_size;
+ int64_t uncompressed_size;
+ int64_t gid;
+ int64_t uid;
+ struct archive_entry *entry;
+ time_t mtime;
+ time_t atime;
+ time_t ctime;
+ uint32_t crc32;
+ uint16_t mode;
+ uint16_t flags;
+ char compression;
+ char system;
+};
+
+struct zip {
+ /* Structural information about the archive. */
+ int64_t central_directory_offset;
+ size_t central_directory_size;
+ size_t central_directory_entries;
+ char have_central_directory;
+
+ /* List of entries (seekable Zip only) */
+ size_t entries_remaining;
+ struct zip_entry *zip_entries;
+ struct zip_entry *entry;
+
+ size_t unconsumed;
+
+ /* entry_bytes_remaining is the number of bytes we expect. */
+ int64_t entry_bytes_remaining;
+
+ /* These count the number of bytes actually read for the entry. */
+ int64_t entry_compressed_bytes_read;
+ int64_t entry_uncompressed_bytes_read;
+
+ /* Running CRC32 of the decompressed data */
+ unsigned long entry_crc32;
+
+ /* Flags to mark progress of decompression. */
+ char decompress_init;
+ char end_of_entry;
+
+ ssize_t filename_length;
+ ssize_t extra_length;
+
+ 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];
+};
+
+#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 *);
+#ifdef HAVE_ZLIB_H
+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 *);
+
+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));
+
+ 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,
+ archive_read_format_zip_cleanup);
+
+ if (r != ARCHIVE_OK)
+ free(zip);
+ 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 *)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));
+
+ 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,
+ 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.
+ *
+ * Consider passing in the winning bid value to subsequent
+ * bidders so that this bidder in particular can avoid
+ * seeking if it knows it's going to lose anyway.
+ */
+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 filesize;
+ const char *p;
+
+ /* 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)
+ return 0;
+
+ /* 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);
+
+ /* 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 + zip->central_directory_size > filesize)
+ return 0;
+
+ /* 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;
+}
+
+static int
+slurp_central_directory(struct archive_read *a, struct zip *zip)
+{
+ unsigned i;
+
+ __archive_read_seek(a, zip->central_directory_offset, SEEK_SET);
+
+ 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 *p;
+
+ 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 = 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);
+
+ if (zip_entry->system == 3) {
+ zip_entry->mode = external_attributes >> 16;
+ } else {
+ zip_entry->mode = AE_IFREG | 0777;
+ }
+
+ /* Do we need to parse filename here? */
+ /* Or can we wait until we read the local header? */
+ __archive_read_consume(a,
+ 46 + filename_length + extra_length + comment_length);
+ }
+
+ /* TODO: Sort zip entries. */
+
+ return ARCHIVE_OK;
+}
+
+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;
+ int r;
+
+ 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;
+ zip->entry = zip->zip_entries;
+ } else {
+ ++zip->entry;
+ }
+
+ if (zip->entries_remaining <= 0)
+ return ARCHIVE_EOF;
+ --zip->entries_remaining;
+
+ /* TODO: If entries are sorted by offset within the file, we
+ should be able to skip here instead of seeking. Skipping is
+ typically faster (easier for I/O layer to optimize). */
+ __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 ((zip->entry->mode & AE_IFMT) == AE_IFLNK) {
+ const void *p;
+ size_t linkname_length = 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;
+ }
+
+ if (archive_entry_copy_symlink_l(entry, p, linkname_length,
+ NULL) != 0) {
+ /* NOTE: If the last argument is NULL, this will
+ * fail only by memeory allocation failure. */
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Symlink");
+ return (ARCHIVE_FATAL);
+ }
+ /* TODO: handle character-set issues? */
+ }
+ return ARCHIVE_OK;
+}
+
+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);
+ }
+
+ 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;
+ ret = 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;
+ }
+ } else
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "zip: unknown keyword ``%s''", key);
+
+ return (ret);
+}
+
+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);
+
+ /* 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));
+
+ /* 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] == '\001' && p[3] == '\002')
+ /* Beginning of central directory. */
+ return (ARCHIVE_EOF);
+
+ if (p[2] == '\003' && p[3] == '\004') {
+ /* Regular file entry. */
+ __archive_read_consume(a, skipped);
+ return zip_read_local_file_header(a, entry, zip);
+ }
+
+ if (p[2] == '\005' && p[3] == '\006')
+ /* End of central directory. */
+ return (ARCHIVE_EOF);
+ }
+ ++p;
+ ++skipped;
+ }
+ __archive_read_consume(a, skipped);
+ }
+}
+
+/*
+ * Assumes file pointer is at beginning of local file header.
+ */
+static int
+zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
+ struct zip *zip)
+{
+ const char *p;
+ const void *h;
+ const wchar_t *wp;
+ const char *cp;
+ 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;
+ int ret = ARCHIVE_OK;
+ char version;
+
+ 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);
+
+ /* Setup default conversion. */
+ if (zip->sconv == NULL && !zip->init_default_conversion) {
+ zip->sconv_default =
+ archive_string_default_conversion_for_read(&(a->archive));
+ zip->init_default_conversion = 1;
+ }
+
+ if ((p = __archive_read_ahead(a, 30, NULL)) == NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated ZIP file header");
+ return (ARCHIVE_FATAL);
+ }
+
+ if (memcmp(p, "PK\003\004", 4) != 0) {
+ archive_set_error(&a->archive, -1, "Damaged Zip archive");
+ return ARCHIVE_FATAL;
+ }
+ version = p[4];
+ zip_entry->system = p[5];
+ zip_entry->flags = archive_le16dec(p + 6);
+ zip_entry->compression = 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);
+ filename_length = archive_le16dec(p + 26);
+ extra_length = archive_le16dec(p + 28);
+
+ __archive_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;
+ }
+
+ /* Read the filename. */
+ if ((h = __archive_read_ahead(a, filename_length, NULL)) == NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated ZIP file header");
+ return (ARCHIVE_FATAL);
+ }
+ if (zip_entry->flags & ZIP_UTF8_NAME) {
+ /* The filename is stored to be UTF-8. */
+ if (zip->sconv_utf8 == NULL) {
+ zip->sconv_utf8 =
+ archive_string_conversion_from_charset(
+ &a->archive, "UTF-8", 1);
+ if (zip->sconv_utf8 == NULL)
+ return (ARCHIVE_FATAL);
+ }
+ sconv = zip->sconv_utf8;
+ } else if (zip->sconv != NULL)
+ sconv = zip->sconv;
+ else
+ sconv = zip->sconv_default;
+
+ if (archive_entry_copy_pathname_l(entry,
+ h, filename_length, sconv) != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Pathname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Pathname cannot be converted "
+ "from %s to current locale.",
+ archive_string_conversion_charset_name(sconv));
+ ret = ARCHIVE_WARN;
+ }
+ __archive_read_consume(a, filename_length);
+
+ if (zip_entry->mode == 0) {
+ /* Especially in streaming mode, we can end up
+ here without having seen any 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;
+ else
+ zip_entry->mode = AE_IFREG | 0777;
+ } else {
+ cp = archive_entry_pathname(entry);
+ len = (cp != NULL)?strlen(cp):0;
+ if (len > 0 && cp[len - 1] == '/')
+ zip_entry->mode = AE_IFDIR | 0777;
+ else
+ zip_entry->mode = AE_IFREG | 0777;
+ }
+ }
+
+ /* Read the extra data. */
+ if ((h = __archive_read_ahead(a, extra_length, NULL)) == NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated ZIP file header");
+ return (ARCHIVE_FATAL);
+ }
+ process_extra(h, extra_length, zip_entry);
+ __archive_read_consume(a, extra_length);
+
+ /* Populate some additional entry fields: */
+ archive_entry_set_mode(entry, zip_entry->mode);
+ archive_entry_set_uid(entry, zip_entry->uid);
+ archive_entry_set_gid(entry, zip_entry->gid);
+ 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);
+
+ 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)
+ && 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)",
+ version / 10, version % 10,
+ compression_name(zip->entry->compression));
+ a->archive.archive_format_name = zip->format_name;
+
+ 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 (compression <
+ 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)
+{
+ 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);
+ }
+
+ __archive_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, *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 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);
+ return (ARCHIVE_WARN);
+ }
+ }
+
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Read "uncompressed" data. There are three cases:
+ * 1) We know the size of the data. This is always true for the
+ * seeking reader (we've examined the Central Directory already).
+ * 2) ZIP_LENGTH_AT_END was set, but only the CRC was deferred.
+ * Info-ZIP seems to do this; we know the size but have to grab
+ * the CRC from the data descriptor afterwards.
+ * 3) We're streaming and ZIP_LENGTH_AT_END was specified and
+ * we have no size information. In this case, we can do pretty
+ * well by watching for the data descriptor record. The data
+ * descriptor is 16 bytes and includes a computed CRC that should
+ * provide a strong check.
+ *
+ * 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.
+ *
+ * Returns ARCHIVE_OK if successful, ARCHIVE_FATAL otherwise, sets
+ * zip->end_of_entry if it consumes all of the data.
+ */
+static int
+zip_read_data_none(struct archive_read *a, const void **_buff,
+ size_t *size, int64_t *offset)
+{
+ struct zip *zip;
+ const char *buff;
+ ssize_t bytes_avail;
+
+ zip = (struct zip *)(a->format->data);
+
+ if (zip->entry->flags & ZIP_LENGTH_AT_END) {
+ const char *p;
+
+ /* Grab at least 16 bytes. */
+ buff = __archive_read_ahead(a, 16, &bytes_avail);
+ if (bytes_avail < 16) {
+ /* 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
+ 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. */
+ p = buff;
+ 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);
+ zip->end_of_entry = 1;
+ zip->unconsumed = 16;
+ return (ARCHIVE_OK);
+ }
+ /* If not at EOF, ensure we consume at least one byte. */
+ ++p;
+
+ /* Scan forward until we see where a PK\007\010 signature might be. */
+ /* Return bytes up until that point. On the next call, the code
+ above will verify the data descriptor. */
+ while (p < buff + bytes_avail - 4) {
+ if (p[3] == 'P') { p += 3; }
+ else if (p[3] == 'K') { p += 2; }
+ else if (p[3] == '\007') { p += 1; }
+ else if (p[3] == '\010' && p[2] == '\007'
+ && p[1] == 'K' && p[0] == 'P') {
+ break;
+ } else { p += 4; }
+ }
+ bytes_avail = p - buff;
+ } else {
+ if (zip->entry_bytes_remaining == 0) {
+ zip->end_of_entry = 1;
+ return (ARCHIVE_OK);
+ }
+ /* Grab a bunch of bytes. */
+ buff = __archive_read_ahead(a, 1, &bytes_avail);
+ if (bytes_avail <= 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated ZIP file data");
+ return (ARCHIVE_FATAL);
+ }
+ if (bytes_avail > zip->entry_bytes_remaining)
+ bytes_avail = zip->entry_bytes_remaining;
+ }
+ *size = bytes_avail;
+ zip->entry_bytes_remaining -= bytes_avail;
+ zip->entry_uncompressed_bytes_read += bytes_avail;
+ zip->entry_compressed_bytes_read += bytes_avail;
+ zip->unconsumed += bytes_avail;
+ *_buff = buff;
+ return (ARCHIVE_OK);
+}
+
+#ifdef HAVE_ZLIB_H
+static int
+zip_read_data_deflate(struct archive_read *a, const void **buff,
+ size_t *size, int64_t *offset)
+{
+ struct zip *zip;
+ ssize_t bytes_avail;
+ const void *compressed_buff;
+ int r;
+
+ zip = (struct zip *)(a->format->data);
+
+ /* If the buffer hasn't been allocated, allocate it now. */
+ if (zip->uncompressed_buffer == NULL) {
+ zip->uncompressed_buffer_size = 256 * 1024;
+ zip->uncompressed_buffer
+ = (unsigned char *)malloc(zip->uncompressed_buffer_size);
+ if (zip->uncompressed_buffer == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "No memory for ZIP decompression");
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ /* If we haven't yet read any data, initialize the decompressor. */
+ if (!zip->decompress_init) {
+ if (zip->stream_valid)
+ r = inflateReset(&zip->stream);
+ else
+ r = inflateInit2(&zip->stream,
+ -15 /* Don't check for zlib header */);
+ if (r != Z_OK) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Can't initialize ZIP decompression.");
+ return (ARCHIVE_FATAL);
+ }
+ /* Stream structure has been set up. */
+ zip->stream_valid = 1;
+ /* We've initialized decompression for this stream. */
+ zip->decompress_init = 1;
+ }
+
+ /*
+ * Note: '1' here is a performance optimization.
+ * Recall that the decompression layer returns a count of
+ * 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)
+ && bytes_avail > zip->entry_bytes_remaining) {
+ bytes_avail = zip->entry_bytes_remaining;
+ }
+ if (bytes_avail <= 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated ZIP file body");
+ return (ARCHIVE_FATAL);
+ }
+
+ /*
+ * A bug in zlib.h: stream.next_in should be marked 'const'
+ * but isn't (the library never alters data through the
+ * next_in pointer, only reads it). The result: this ugly
+ * cast to remove 'const'.
+ */
+ zip->stream.next_in = (Bytef *)(uintptr_t)(const void *)compressed_buff;
+ zip->stream.avail_in = bytes_avail;
+ zip->stream.total_in = 0;
+ zip->stream.next_out = zip->uncompressed_buffer;
+ zip->stream.avail_out = zip->uncompressed_buffer_size;
+ zip->stream.total_out = 0;
+
+ r = inflate(&zip->stream, 0);
+ switch (r) {
+ case Z_OK:
+ break;
+ case Z_STREAM_END:
+ zip->end_of_entry = 1;
+ break;
+ case Z_MEM_ERROR:
+ archive_set_error(&a->archive, ENOMEM,
+ "Out of memory for ZIP decompression");
+ return (ARCHIVE_FATAL);
+ default:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "ZIP decompression failed (%d)", r);
+ return (ARCHIVE_FATAL);
+ }
+
+ /* Consume as much as the compressor actually used. */
+ bytes_avail = zip->stream.total_in;
+ __archive_read_consume(a, bytes_avail);
+ zip->entry_bytes_remaining -= bytes_avail;
+ zip->entry_compressed_bytes_read += bytes_avail;
+
+ *size = zip->stream.total_out;
+ 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)) {
+ const char *p;
+
+ if (NULL == (p = __archive_read_ahead(a, 16, NULL))) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated ZIP end-of-file record");
+ return (ARCHIVE_FATAL);
+ }
+ /* 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;
+ }
+ }
+
+ return (ARCHIVE_OK);
+}
+#endif
+
+static int
+archive_read_format_zip_read_data_skip(struct archive_read *a)
+{
+ struct zip *zip;
+
+ zip = (struct zip *)(a->format->data);
+
+ /* If we've already read to end of data, we're done. */
+ if (zip->end_of_entry)
+ return (ARCHIVE_OK);
+ /* If we're seeking, we're done. */
+ if (zip->have_central_directory)
+ return (ARCHIVE_OK);
+
+ /* So we know we're streaming... */
+ if (0 == (zip->entry->flags & ZIP_LENGTH_AT_END)) {
+ /* We know the compressed length, so we can just skip. */
+ int64_t bytes_skipped = __archive_read_consume(a,
+ zip->entry_bytes_remaining + zip->unconsumed);
+ if (bytes_skipped < 0)
+ return (ARCHIVE_FATAL);
+ zip->unconsumed = 0;
+ return (ARCHIVE_OK);
+ }
+
+ /* 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. */
+ switch (zip->entry->compression) {
+#ifdef HAVE_ZLIB_H
+ case 8: /* Deflate compression. */
+ while (!zip->end_of_entry) {
+ int64_t offset = 0;
+ const void *buff = NULL;
+ size_t size = 0;
+ int r;
+ r = zip_read_data_deflate(a, &buff, &size, &offset);
+ if (r != ARCHIVE_OK)
+ return (r);
+ }
+ break;
+#endif
+ default: /* Uncompressed or unknown. */
+ /* Scan for a PK\007\010 signature. */
+ __archive_read_consume(a, zip->unconsumed);
+ zip->unconsumed = 0;
+ for (;;) {
+ const char *p, *buff;
+ ssize_t bytes_avail;
+ buff = __archive_read_ahead(a, 16, &bytes_avail);
+ if (bytes_avail < 16) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated ZIP file data");
+ return (ARCHIVE_FATAL);
+ }
+ p = buff;
+ while (p < buff + bytes_avail - 16) {
+ if (p[3] == 'P') { p += 3; }
+ else if (p[3] == 'K') { p += 2; }
+ else if (p[3] == '\007') { p += 1; }
+ else if (p[3] == '\010' && p[2] == '\007'
+ && p[1] == 'K' && p[0] == 'P') {
+ __archive_read_consume(a, p - buff + 16);
+ return ARCHIVE_OK;
+ } else { p += 4; }
+ }
+ __archive_read_consume(a, p - buff);
+ }
+ }
+ return ARCHIVE_OK;
+}
+
+static int
+archive_read_format_zip_cleanup(struct archive_read *a)
+{
+ struct zip *zip;
+
+ zip = (struct zip *)(a->format->data);
+#ifdef HAVE_ZLIB_H
+ if (zip->stream_valid)
+ inflateEnd(&zip->stream);
+#endif
+ free(zip->zip_entries);
+ free(zip->uncompressed_buffer);
+ archive_string_free(&(zip->extra));
+ free(zip);
+ (a->format->data) = NULL;
+ 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.
+ */
+static void
+process_extra(const char *p, size_t extra_length, struct zip_entry* zip_entry)
+{
+ unsigned offset = 0;
+
+ 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)
+ 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);
+ 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;
+ }
+ break;
+ }
+ 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);
+ }
+ 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));
+#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 (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);
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ offset += datasize;
+ }
+#ifdef DEBUG
+ if (offset != extra_length)
+ {
+ fprintf(stderr,
+ "Extra data field contents do not match reported size!\n");
+ }
+#endif
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_string.c b/Utilities/cmlibarchive/libarchive/archive_string.c
new file mode 100644
index 000000000..cbfad2c5b
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_string.c
@@ -0,0 +1,4237 @@
+/*-
+ * Copyright (c) 2003-2011 Tim Kientzle
+ * 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"
+__FBSDID("$FreeBSD: head/lib/libarchive/archive_string.c 201095 2009-12-28 02:33:22Z kientzle $");
+
+/*
+ * Basic resizable string support, to simplify manipulating arbitrary-sized
+ * strings while minimizing heap activity.
+ *
+ * In particular, the buffer used by a string object is only grown, it
+ * never shrinks, so you can clear and reuse the same string object
+ * without incurring additional memory allocations.
+ */
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_ICONV_H
+#include <iconv.h>
+#endif
+#ifdef HAVE_LANGINFO_H
+#include <langinfo.h>
+#endif
+#ifdef HAVE_LOCALCHARSET_H
+#include <localcharset.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_WCHAR_H
+#include <wchar.h>
+#endif
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#include <windows.h>
+#include <locale.h>
+#endif
+#if defined(__APPLE__)
+#include <CoreServices/CoreServices.h>
+#endif
+
+#include "archive_endian.h"
+#include "archive_private.h"
+#include "archive_string.h"
+#include "archive_string_composition.h"
+
+#if !defined(HAVE_WMEMCPY) && !defined(wmemcpy)
+#define wmemcpy(a,b,i) (wchar_t *)memcpy((a), (b), (i) * sizeof(wchar_t))
+#endif
+
+struct archive_string_conv {
+ struct archive_string_conv *next;
+ char *from_charset;
+ char *to_charset;
+ unsigned from_cp;
+ unsigned to_cp;
+ /* Set 1 if from_charset and to_charset are the same. */
+ int same;
+ int flag;
+#define SCONV_TO_CHARSET 1 /* MBS is being converted to specified
+ * charset. */
+#define SCONV_FROM_CHARSET (1<<1) /* MBS is being converted from
+ * specified charset. */
+#define SCONV_BEST_EFFORT (1<<2) /* Copy at least ASCII code. */
+#define SCONV_WIN_CP (1<<3) /* Use Windows API for converting
+ * MBS. */
+#define SCONV_UTF8_LIBARCHIVE_2 (1<<4) /* Incorrect UTF-8 made by libarchive
+ * 2.x in the wrong assumption. */
+#define SCONV_NORMALIZATION_C (1<<6) /* Need normalization to be Form C.
+ * Before UTF-8 characters are actually
+ * processed. */
+#define SCONV_NORMALIZATION_D (1<<7) /* Need normalization to be Form D.
+ * Before UTF-8 characters are actually
+ * processed.
+ * Currently this only for MAC OS X. */
+#define SCONV_TO_UTF8 (1<<8) /* "to charset" side is UTF-8. */
+#define SCONV_FROM_UTF8 (1<<9) /* "from charset" side is UTF-8. */
+#define SCONV_TO_UTF16BE (1<<10) /* "to charset" side is UTF-16BE. */
+#define SCONV_FROM_UTF16BE (1<<11) /* "from charset" side is UTF-16BE. */
+#define SCONV_TO_UTF16LE (1<<12) /* "to charset" side is UTF-16LE. */
+#define SCONV_FROM_UTF16LE (1<<13) /* "from charset" side is UTF-16LE. */
+#define SCONV_TO_UTF16 (SCONV_TO_UTF16BE | SCONV_TO_UTF16LE)
+#define SCONV_FROM_UTF16 (SCONV_FROM_UTF16BE | SCONV_FROM_UTF16LE)
+
+#if HAVE_ICONV
+ iconv_t cd;
+ iconv_t cd_w;/* Use at archive_mstring on
+ * Windows. */
+#endif
+ /* A temporary buffer for normalization. */
+ struct archive_string utftmp;
+#if defined(__APPLE__)
+ UnicodeToTextInfo uniInfo;
+ struct archive_string utf16nfc;
+ struct archive_string utf16nfd;
+#endif
+ int (*converter[2])(struct archive_string *, const void *, size_t,
+ struct archive_string_conv *);
+ int nconverter;
+};
+
+#define CP_C_LOCALE 0 /* "C" locale only for this file. */
+#define CP_UTF16LE 1200
+#define CP_UTF16BE 1201
+
+#define IS_HIGH_SURROGATE_LA(uc) ((uc) >= 0xD800 && (uc) <= 0xDBFF)
+#define IS_LOW_SURROGATE_LA(uc) ((uc) >= 0xDC00 && (uc) <= 0xDFFF)
+#define IS_SURROGATE_PAIR_LA(uc) ((uc) >= 0xD800 && (uc) <= 0xDFFF)
+#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 struct archive_string_conv *find_sconv_object(struct archive *,
+ const char *, const char *);
+static void add_sconv_object(struct archive *, struct archive_string_conv *);
+static struct archive_string_conv *create_sconv_object(const char *,
+ const char *, unsigned, int);
+static void free_sconv_object(struct archive_string_conv *);
+static struct archive_string_conv *get_sconv_object(struct archive *,
+ const char *, const char *, int);
+static unsigned make_codepage_from_charset(const char *);
+static unsigned get_current_codepage(void);
+static unsigned get_current_oemcp(void);
+static size_t mbsnbytes(const void *, size_t);
+static size_t utf16nbytes(const void *, size_t);
+#if defined(_WIN32) && !defined(__CYGWIN__)
+static int archive_wstring_append_from_mbs_in_codepage(
+ struct archive_wstring *, const char *, size_t,
+ struct archive_string_conv *);
+static int archive_string_append_from_wcs_in_codepage(struct archive_string *,
+ const wchar_t *, size_t, struct archive_string_conv *);
+static int is_big_endian(void);
+static int strncat_in_codepage(struct archive_string *, const void *,
+ size_t, struct archive_string_conv *);
+static int win_strncat_from_utf16be(struct archive_string *, const void *, size_t,
+ struct archive_string_conv *);
+static int win_strncat_from_utf16le(struct archive_string *, const void *, size_t,
+ struct archive_string_conv *);
+static int win_strncat_to_utf16be(struct archive_string *, const void *, size_t,
+ struct archive_string_conv *);
+static int win_strncat_to_utf16le(struct archive_string *, const void *, size_t,
+ struct archive_string_conv *);
+#endif
+static int best_effort_strncat_from_utf16be(struct archive_string *, const void *,
+ size_t, struct archive_string_conv *);
+static int best_effort_strncat_from_utf16le(struct archive_string *, const void *,
+ size_t, struct archive_string_conv *);
+static int best_effort_strncat_to_utf16be(struct archive_string *, const void *,
+ size_t, struct archive_string_conv *);
+static int best_effort_strncat_to_utf16le(struct archive_string *, const void *,
+ size_t, struct archive_string_conv *);
+#if defined(HAVE_ICONV)
+static int iconv_strncat_in_locale(struct archive_string *, const void *,
+ size_t, struct archive_string_conv *);
+#endif
+static int best_effort_strncat_in_locale(struct archive_string *, const void *,
+ size_t, struct archive_string_conv *);
+static int _utf8_to_unicode(uint32_t *, const char *, size_t);
+static int utf8_to_unicode(uint32_t *, const char *, size_t);
+static inline uint32_t combine_surrogate_pair(uint32_t, uint32_t);
+static int cesu8_to_unicode(uint32_t *, const char *, size_t);
+static size_t unicode_to_utf8(char *, size_t, uint32_t);
+static int utf16_to_unicode(uint32_t *, const char *, size_t, int);
+static size_t unicode_to_utf16be(char *, size_t, uint32_t);
+static size_t unicode_to_utf16le(char *, size_t, uint32_t);
+static int strncat_from_utf8_libarchive2(struct archive_string *,
+ const void *, size_t, struct archive_string_conv *);
+static int strncat_from_utf8_to_utf8(struct archive_string *, const void *,
+ size_t, struct archive_string_conv *);
+static int archive_string_normalize_C(struct archive_string *, const void *,
+ size_t, struct archive_string_conv *);
+#if defined(__APPLE__)
+static int archive_string_normalize_D(struct archive_string *, const void *,
+ size_t, struct archive_string_conv *);
+#endif
+static int archive_string_append_unicode(struct archive_string *,
+ const void *, size_t, struct archive_string_conv *);
+
+static struct archive_string *
+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);
+ as->length += s;
+ as->s[as->length] = 0;
+ return (as);
+}
+
+static struct archive_wstring *
+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);
+ as->length += s;
+ as->s[as->length] = 0;
+ return (as);
+}
+
+void
+archive_string_concat(struct archive_string *dest, struct archive_string *src)
+{
+ if (archive_string_append(dest, src->s, src->length) == NULL)
+ __archive_errx(1, "Out of memory");
+}
+
+void
+archive_wstring_concat(struct archive_wstring *dest, struct archive_wstring *src)
+{
+ if (archive_wstring_append(dest, src->s, src->length) == NULL)
+ __archive_errx(1, "Out of memory");
+}
+
+void
+archive_string_free(struct archive_string *as)
+{
+ as->length = 0;
+ as->buffer_length = 0;
+ free(as->s);
+ as->s = NULL;
+}
+
+void
+archive_wstring_free(struct archive_wstring *as)
+{
+ as->length = 0;
+ as->buffer_length = 0;
+ free(as->s);
+ as->s = NULL;
+}
+
+struct archive_wstring *
+archive_wstring_ensure(struct archive_wstring *as, size_t s)
+{
+ return (struct archive_wstring *)
+ archive_string_ensure((struct archive_string *)as,
+ s * sizeof(wchar_t));
+}
+
+/* Returns NULL on any allocation failure. */
+struct archive_string *
+archive_string_ensure(struct archive_string *as, size_t s)
+{
+ char *p;
+ size_t new_length;
+
+ /* If buffer is already big enough, don't reallocate. */
+ if (as->s && (s <= as->buffer_length))
+ return (as);
+
+ /*
+ * Growing the buffer at least exponentially ensures that
+ * append operations are always linear in the number of
+ * characters appended. Using a smaller growth rate for
+ * larger buffers reduces memory waste somewhat at the cost of
+ * a larger constant factor.
+ */
+ if (as->buffer_length < 32)
+ /* Start with a minimum 32-character buffer. */
+ new_length = 32;
+ else if (as->buffer_length < 8192)
+ /* Buffers under 8k are doubled for speed. */
+ new_length = as->buffer_length + as->buffer_length;
+ else {
+ /* Buffers 8k and over grow by at least 25% each time. */
+ new_length = as->buffer_length + as->buffer_length / 4;
+ /* Be safe: If size wraps, fail. */
+ if (new_length < as->buffer_length) {
+ /* On failure, wipe the string and return NULL. */
+ archive_string_free(as);
+ errno = ENOMEM;/* Make sure errno has ENOMEM. */
+ return (NULL);
+ }
+ }
+ /*
+ * The computation above is a lower limit to how much we'll
+ * grow the buffer. In any case, we have to grow it enough to
+ * hold the request.
+ */
+ if (new_length < s)
+ new_length = s;
+ /* Now we can reallocate the buffer. */
+ p = (char *)realloc(as->s, new_length);
+ if (p == NULL) {
+ /* On failure, wipe the string and return NULL. */
+ archive_string_free(as);
+ errno = ENOMEM;/* Make sure errno has ENOMEM. */
+ return (NULL);
+ }
+
+ as->s = p;
+ as->buffer_length = new_length;
+ return (as);
+}
+
+/*
+ * TODO: See if there's a way to avoid scanning
+ * the source string twice. Then test to see
+ * if it actually helps (remember that we're almost
+ * always called with pretty short arguments, so
+ * such an optimization might not help).
+ */
+struct archive_string *
+archive_strncat(struct archive_string *as, const void *_p, size_t n)
+{
+ size_t s;
+ const char *p, *pp;
+
+ p = (const char *)_p;
+
+ /* Like strlen(p), except won't examine positions beyond p[n]. */
+ s = 0;
+ pp = p;
+ while (s < n && *pp) {
+ pp++;
+ s++;
+ }
+ if ((as = archive_string_append(as, p, s)) == NULL)
+ __archive_errx(1, "Out of memory");
+ return (as);
+}
+
+struct archive_wstring *
+archive_wstrncat(struct archive_wstring *as, const wchar_t *p, size_t n)
+{
+ size_t s;
+ const wchar_t *pp;
+
+ /* Like strlen(p), except won't examine positions beyond p[n]. */
+ s = 0;
+ pp = p;
+ while (s < n && *pp) {
+ pp++;
+ s++;
+ }
+ if ((as = archive_wstring_append(as, p, s)) == NULL)
+ __archive_errx(1, "Out of memory");
+ return (as);
+}
+
+struct archive_string *
+archive_strcat(struct archive_string *as, const void *p)
+{
+ /* strcat is just strncat without an effective limit.
+ * Assert that we'll never get called with a source
+ * string over 16MB.
+ * TODO: Review all uses of strcat in the source
+ * and try to replace them with strncat().
+ */
+ return archive_strncat(as, p, 0x1000000);
+}
+
+struct archive_wstring *
+archive_wstrcat(struct archive_wstring *as, const wchar_t *p)
+{
+ /* Ditto. */
+ return archive_wstrncat(as, p, 0x1000000);
+}
+
+struct archive_string *
+archive_strappend_char(struct archive_string *as, char c)
+{
+ if ((as = archive_string_append(as, &c, 1)) == NULL)
+ __archive_errx(1, "Out of memory");
+ return (as);
+}
+
+struct archive_wstring *
+archive_wstrappend_wchar(struct archive_wstring *as, wchar_t c)
+{
+ if ((as = archive_wstring_append(as, &c, 1)) == NULL)
+ __archive_errx(1, "Out of memory");
+ return (as);
+}
+
+/*
+ * Get the "current character set" name to use with iconv.
+ * On FreeBSD, the empty character set name "" chooses
+ * the correct character encoding for the current locale,
+ * so this isn't necessary.
+ * But iconv on Mac OS 10.6 doesn't seem to handle this correctly;
+ * on that system, we have to explicitly call nl_langinfo()
+ * to get the right name. Not sure about other platforms.
+ *
+ * NOTE: GNU libiconv does not recognize the character-set name
+ * which some platform nl_langinfo(CODESET) returns, so we should
+ * use locale_charset() instead of nl_langinfo(CODESET) for GNU libiconv.
+ */
+static const char *
+default_iconv_charset(const char *charset) {
+ if (charset != NULL && charset[0] != '\0')
+ return charset;
+#if HAVE_LOCALE_CHARSET && !defined(__APPLE__)
+ /* locale_charset() is broken on Mac OS */
+ return locale_charset();
+#elif HAVE_NL_LANGINFO
+ return nl_langinfo(CODESET);
+#else
+ return "";
+#endif
+}
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+
+/*
+ * Convert MBS to WCS.
+ * Note: returns -1 if conversion fails.
+ */
+int
+archive_wstring_append_from_mbs(struct archive_wstring *dest,
+ const char *p, size_t len)
+{
+ int r = archive_wstring_append_from_mbs_in_codepage(dest, p, len, NULL);
+ if (r != 0 && errno == ENOMEM)
+ __archive_errx(1, "No memory");
+ return (r);
+}
+
+static int
+archive_wstring_append_from_mbs_in_codepage(struct archive_wstring *dest,
+ const char *s, size_t length, struct archive_string_conv *sc)
+{
+ int count, ret = 0;
+ UINT from_cp;
+
+ if (sc != NULL)
+ from_cp = sc->from_cp;
+ else
+ from_cp = get_current_codepage();
+
+ if (from_cp == CP_C_LOCALE) {
+ /*
+ * "C" locale special process.
+ */
+ wchar_t *ws;
+ const unsigned char *mp;
+
+ if (NULL == archive_wstring_ensure(dest,
+ dest->length + length + 1))
+ return (-1);
+
+ ws = dest->s + dest->length;
+ mp = (const unsigned char *)s;
+ count = 0;
+ while (count < (int)length && *mp) {
+ *ws++ = (wchar_t)*mp++;
+ count++;
+ }
+ } else if (sc != NULL && (sc->flag & SCONV_NORMALIZATION_C)) {
+ /*
+ * Normalize UTF-8 and UTF-16BE and convert it directly
+ * to UTF-16 as wchar_t.
+ */
+ struct archive_string u16;
+ int saved_flag = sc->flag;/* save current flag. */
+
+ if (is_big_endian())
+ sc->flag |= SCONV_TO_UTF16BE;
+ else
+ sc->flag |= SCONV_TO_UTF16LE;
+
+ if (sc->flag & SCONV_FROM_UTF16) {
+ /*
+ * UTF-16BE/LE NFD ===> UTF-16 NFC
+ */
+ count = utf16nbytes(s, length);
+ } else {
+ /*
+ * UTF-8 NFD ===> UTF-16 NFC
+ */
+ count = mbsnbytes(s, length);
+ }
+ u16.s = (char *)dest->s;
+ u16.length = dest->length << 1;;
+ u16.buffer_length = dest->buffer_length;
+ ret = archive_string_normalize_C(&u16, s, count, sc);
+ dest->s = (wchar_t *)u16.s;
+ dest->length = u16.length >> 1;
+ dest->buffer_length = u16.buffer_length;
+ sc->flag = saved_flag;/* restore the saved flag. */
+ return (ret);
+ } else if (sc != NULL && (sc->flag & SCONV_FROM_UTF16)) {
+ count = utf16nbytes(s, length);
+ count >>= 1; /* to be WCS length */
+ /* Allocate memory for WCS. */
+ if (NULL == archive_wstring_ensure(dest,
+ dest->length + count + 1))
+ return (-1);
+ wmemcpy(dest->s + dest->length, (wchar_t *)s, count);
+ if ((sc->flag & SCONV_FROM_UTF16BE) && !is_big_endian()) {
+ uint16_t *u16 = (uint16_t *)(dest->s + dest->length);
+ int b;
+ for (b = 0; b < count; b++) {
+ uint16_t val = archive_le16dec(u16+b);
+ archive_be16enc(u16+b, val);
+ }
+ } else if ((sc->flag & SCONV_FROM_UTF16LE) && is_big_endian()) {
+ uint16_t *u16 = (uint16_t *)(dest->s + dest->length);
+ int b;
+ for (b = 0; b < count; b++) {
+ uint16_t val = archive_be16dec(u16+b);
+ archive_le16enc(u16+b, val);
+ }
+ }
+ } else {
+ DWORD mbflag;
+
+ if (sc == NULL)
+ mbflag = 0;
+ else if (sc->flag & SCONV_FROM_CHARSET) {
+ /* Do not trust the length which comes from
+ * an archive file. */
+ length = mbsnbytes(s, length);
+ mbflag = 0;
+ } else
+ mbflag = MB_PRECOMPOSED;
+
+ if (length == 0) {
+ /*
+ * We do not need to convert any characters but make
+ * sure `dest' has a valid buffer(no NULL pointer).
+ */
+ if (NULL == archive_wstring_ensure(dest,
+ dest->length + 1))
+ return (-1);
+ dest->s[dest->length] = L'\0';
+ return (0);
+ }
+
+ /*
+ * Count how many bytes are needed for WCS.
+ */
+ count = MultiByteToWideChar(from_cp,
+ mbflag, s, length, NULL, 0);
+ if (count == 0) {
+ if (dest->s == NULL) {
+ if (NULL == archive_wstring_ensure(dest,
+ dest->length + 1))
+ return (-1);
+ }
+ dest->s[dest->length] = L'\0';
+ return (-1);
+ }
+ /* Allocate memory for WCS. */
+ if (NULL == archive_wstring_ensure(dest,
+ dest->length + count + 1))
+ return (-1);
+ /* Convert MBS to WCS. */
+ count = MultiByteToWideChar(from_cp,
+ mbflag, s, length, dest->s + dest->length, count);
+ if (count == 0)
+ ret = -1;
+ }
+ dest->length += count;
+ dest->s[dest->length] = L'\0';
+ return (ret);
+}
+
+#elif defined(HAVE_MBSNRTOWCS)
+
+/*
+ * Convert MBS to WCS.
+ * Note: returns -1 if conversion fails.
+ */
+int
+archive_wstring_append_from_mbs(struct archive_wstring *dest,
+ const char *p, size_t len)
+{
+ size_t r;
+ /*
+ * No single byte will be more than one wide character,
+ * so this length estimate will always be big enough.
+ */
+ size_t wcs_length = len;
+ size_t mbs_length = len;
+ const char *mbs = p;
+ wchar_t *wcs;
+ mbstate_t shift_state;
+
+ memset(&shift_state, 0, sizeof(shift_state));
+ if (NULL == archive_wstring_ensure(dest, dest->length + wcs_length + 1))
+ __archive_errx(1,
+ "No memory for archive_wstring_append_from_mbs()");
+ wcs = dest->s + dest->length;
+ r = mbsnrtowcs(wcs, &mbs, mbs_length, wcs_length, &shift_state);
+ if (r != (size_t)-1) {
+ dest->length += r;
+ dest->s[dest->length] = L'\0';
+ return (0);
+ }
+ dest->s[dest->length] = L'\0';
+ return (-1);
+}
+
+#else
+
+/*
+ * Convert MBS to WCS.
+ * Note: returns -1 if conversion fails.
+ */
+int
+archive_wstring_append_from_mbs(struct archive_wstring *dest,
+ const char *p, size_t len)
+{
+ size_t r;
+ /*
+ * No single byte will be more than one wide character,
+ * so this length estimate will always be big enough.
+ */
+ size_t wcs_length = len;
+ size_t mbs_length = len;
+ const char *mbs = p;
+ wchar_t *wcs;
+#if HAVE_MBRTOWC
+ mbstate_t shift_state;
+
+ memset(&shift_state, 0, sizeof(shift_state));
+#endif
+ if (NULL == archive_wstring_ensure(dest, dest->length + wcs_length + 1))
+ __archive_errx(1,
+ "No memory for archive_wstring_append_from_mbs()");
+ wcs = dest->s + dest->length;
+ /*
+ * We cannot use mbsrtowcs/mbstowcs here because those may convert
+ * extra MBS when strlen(p) > len and one wide character consis of
+ * multi bytes.
+ */
+ while (wcs_length > 0 && *mbs && mbs_length > 0) {
+#if HAVE_MBRTOWC
+ r = mbrtowc(wcs, mbs, wcs_length, &shift_state);
+#else
+ r = mbtowc(wcs, mbs, wcs_length);
+#endif
+ if (r == (size_t)-1 || r == (size_t)-2) {
+ dest->s[dest->length] = L'\0';
+ return (-1);
+ }
+ if (r == 0 || r > mbs_length)
+ break;
+ wcs++;
+ wcs_length--;
+ mbs += r;
+ mbs_length -= r;
+ }
+ dest->length = wcs - dest->s;
+ dest->s[dest->length] = L'\0';
+ return (0);
+}
+
+#endif
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+
+/*
+ * WCS ==> MBS.
+ * Note: returns -1 if conversion fails.
+ *
+ * Win32 builds use WideCharToMultiByte from the Windows API.
+ * (Maybe Cygwin should too? WideCharToMultiByte will know a
+ * lot more about local character encodings than the wcrtomb()
+ * wrapper is going to know.)
+ */
+int
+archive_string_append_from_wcs(struct archive_string *as,
+ const wchar_t *w, size_t len)
+{
+ int r = archive_string_append_from_wcs_in_codepage(as, w, len, NULL);
+ if (r != 0 && errno == ENOMEM)
+ __archive_errx(1, "No memory");
+ return (r);
+}
+
+static int
+archive_string_append_from_wcs_in_codepage(struct archive_string *as,
+ const wchar_t *ws, size_t len, struct archive_string_conv *sc)
+{
+ BOOL defchar_used, *dp;
+ int count, ret = 0;
+ UINT to_cp;
+ int wslen = (int)len;
+
+ if (sc != NULL)
+ to_cp = sc->to_cp;
+ else
+ to_cp = get_current_codepage();
+
+ if (to_cp == CP_C_LOCALE) {
+ /*
+ * "C" locale special process.
+ */
+ const wchar_t *wp = ws;
+ char *p;
+
+ if (NULL == archive_string_ensure(as,
+ as->length + wslen +1))
+ return (-1);
+ p = as->s + as->length;
+ count = 0;
+ defchar_used = 0;
+ while (count < wslen && *wp) {
+ if (*wp > 255) {
+ *p++ = '?';
+ wp++;
+ defchar_used = 1;
+ } else
+ *p++ = (char)*wp++;
+ count++;
+ }
+ } else if (sc != NULL && (sc->flag & SCONV_TO_UTF16)) {
+ uint16_t *u16;
+
+ if (NULL ==
+ archive_string_ensure(as, as->length + len * 2 + 2))
+ return (-1);
+ u16 = (uint16_t *)(as->s + as->length);
+ count = 0;
+ defchar_used = 0;
+ if (sc->flag & SCONV_TO_UTF16BE) {
+ while (count < (int)len && *ws) {
+ archive_be16enc(u16+count, *ws);
+ ws++;
+ count++;
+ }
+ } else {
+ while (count < (int)len && *ws) {
+ archive_le16enc(u16+count, *ws);
+ ws++;
+ count++;
+ }
+ }
+ count <<= 1; /* to be byte size */
+ } else {
+ /* Make sure the MBS buffer has plenty to set. */
+ if (NULL ==
+ archive_string_ensure(as, as->length + len * 2 + 1))
+ return (-1);
+ do {
+ defchar_used = 0;
+ if (to_cp == CP_UTF8 || sc == NULL)
+ dp = NULL;
+ else
+ dp = &defchar_used;
+ count = WideCharToMultiByte(to_cp, 0, ws, wslen,
+ as->s + as->length, as->buffer_length-1, NULL, dp);
+ if (count == 0 &&
+ GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+ /* Expand the MBS buffer and retry. */
+ if (NULL == archive_string_ensure(as,
+ as->buffer_length + len))
+ return (-1);
+ continue;
+ }
+ if (count == 0)
+ ret = -1;
+ } while (0);
+ }
+ as->length += count;
+ as->s[as->length] = '\0';
+ return (defchar_used?-1:ret);
+}
+
+#elif defined(HAVE_WCSNRTOMBS)
+
+/*
+ * Translates a wide character string into current locale character set
+ * and appends to the archive_string. Note: returns -1 if conversion
+ * fails.
+ */
+int
+archive_string_append_from_wcs(struct archive_string *as,
+ const wchar_t *w, size_t len)
+{
+ mbstate_t shift_state;
+ size_t r, ndest, nwc;
+ char *dest;
+ const wchar_t *wp, *wpp;
+ int ret_val = 0;
+
+ wp = w;
+ nwc = len;
+ ndest = len * 2;
+ /* Initialize the shift state. */
+ memset(&shift_state, 0, sizeof(shift_state));
+ while (nwc > 0) {
+ /* Allocate buffer for MBS. */
+ if (archive_string_ensure(as, as->length + ndest + 1) == NULL)
+ __archive_errx(1, "Out of memory");
+
+ dest = as->s + as->length;
+ wpp = wp;
+ r = wcsnrtombs(dest, &wp, nwc,
+ as->buffer_length - as->length -1,
+ &shift_state);
+ if (r == (size_t)-1) {
+ if (errno == EILSEQ) {
+ /* Retry conversion just for safe WCS. */
+ size_t xwc = wp - wpp;
+ wp = wpp;
+ r = wcsnrtombs(dest, &wp, xwc,
+ as->buffer_length - as->length -1,
+ &shift_state);
+ if (r == (size_t)-1)
+ /* This would not happen. */
+ return (-1);
+ as->length += r;
+ nwc -= wp - wpp;
+ /* Skip an illegal wide char. */
+ as->s[as->length++] = '?';
+ wp++;
+ nwc--;
+ ret_val = -1;
+ continue;
+ } else {
+ ret_val = -1;
+ break;
+ }
+ }
+ as->length += r;
+ if (wp == NULL || (wp - wpp) >= nwc)
+ break;
+ /* Get a remaining WCS lenth. */
+ nwc -= wp - wpp;
+ }
+ /* All wide characters are translated to MBS. */
+ as->s[as->length] = '\0';
+ return (ret_val);
+}
+
+#elif defined(HAVE_WCTOMB) || defined(HAVE_WCRTOMB)
+
+/*
+ * Translates a wide character string into current locale character set
+ * and appends to the archive_string. Note: returns -1 if conversion
+ * fails.
+ */
+int
+archive_string_append_from_wcs(struct archive_string *as,
+ const wchar_t *w, size_t len)
+{
+ /* We cannot use the standard wcstombs() here because it
+ * cannot tell us how big the output buffer should be. So
+ * I've built a loop around wcrtomb() or wctomb() that
+ * converts a character at a time and resizes the string as
+ * needed. We prefer wcrtomb() when it's available because
+ * it's thread-safe. */
+ int n, ret_val = 0;
+ char *p;
+ char *end;
+#if HAVE_WCRTOMB
+ mbstate_t shift_state;
+
+ memset(&shift_state, 0, sizeof(shift_state));
+#else
+ /* Clear the shift state before starting. */
+ wctomb(NULL, L'\0');
+#endif
+ /*
+ * Allocate buffer for MBS.
+ * We need this allocation here since it is possible that
+ * as->s is still NULL.
+ */
+ if (archive_string_ensure(as, as->length + len + 1) == NULL)
+ __archive_errx(1, "Out of memory");
+
+ p = as->s + as->length;
+ end = as->s + as->buffer_length - MB_CUR_MAX -1;
+ while (*w != L'\0' && len > 0) {
+ if (p >= end) {
+ as->length = p - as->s;
+ as->s[as->length] = '\0';
+ /* Re-allocate buffer for MBS. */
+ if (archive_string_ensure(as,
+ as->length + len * 2 + 1) == NULL)
+ __archive_errx(1, "Out of memory");
+ p = as->s + as->length;
+ end = as->s + as->buffer_length - MB_CUR_MAX -1;
+ }
+#if HAVE_WCRTOMB
+ n = wcrtomb(p, *w++, &shift_state);
+#else
+ n = wctomb(p, *w++);
+#endif
+ if (n == -1) {
+ if (errno == EILSEQ) {
+ /* Skip an illegal wide char. */
+ *p++ = '?';
+ ret_val = -1;
+ } else {
+ ret_val = -1;
+ break;
+ }
+ } else
+ p += n;
+ len--;
+ }
+ as->length = p - as->s;
+ as->s[as->length] = '\0';
+ return (ret_val);
+}
+
+#else /* HAVE_WCTOMB || HAVE_WCRTOMB */
+
+/*
+ * TODO: Test if __STDC_ISO_10646__ is defined.
+ * Non-Windows uses ISO C wcrtomb() or wctomb() to perform the conversion
+ * one character at a time. If a non-Windows platform doesn't have
+ * either of these, fall back to the built-in UTF8 conversion.
+ */
+int
+archive_string_append_from_wcs(struct archive_string *as,
+ const wchar_t *w, size_t len)
+{
+ (void)as;/* UNUSED */
+ (void)w;/* UNUSED */
+ (void)len;/* UNUSED */
+ return (-1);
+}
+
+#endif /* HAVE_WCTOMB || HAVE_WCRTOMB */
+
+/*
+ * Find a string conversion object by a pair of 'from' charset name
+ * and 'to' charset name from an archive object.
+ * Return NULL if not found.
+ */
+static struct archive_string_conv *
+find_sconv_object(struct archive *a, const char *fc, const char *tc)
+{
+ struct archive_string_conv *sc;
+
+ if (a == NULL)
+ return (NULL);
+
+ for (sc = a->sconv; sc != NULL; sc = sc->next) {
+ if (strcmp(sc->from_charset, fc) == 0 &&
+ strcmp(sc->to_charset, tc) == 0)
+ break;
+ }
+ return (sc);
+}
+
+/*
+ * Register a string object to an archive object.
+ */
+static void
+add_sconv_object(struct archive *a, struct archive_string_conv *sc)
+{
+ struct archive_string_conv **psc;
+
+ /* Add a new sconv to sconv list. */
+ psc = &(a->sconv);
+ while (*psc != NULL)
+ psc = &((*psc)->next);
+ *psc = sc;
+}
+
+#if defined(__APPLE__)
+
+static int
+createUniInfo(struct archive_string_conv *sconv)
+{
+ UnicodeMapping map;
+ OSStatus err;
+
+ map.unicodeEncoding = CreateTextEncoding(kTextEncodingUnicodeDefault,
+ kUnicodeNoSubset, kUnicode16BitFormat);
+ map.otherEncoding = CreateTextEncoding(kTextEncodingUnicodeDefault,
+ kUnicodeHFSPlusDecompVariant, kUnicode16BitFormat);
+ map.mappingVersion = kUnicodeUseLatestMapping;
+
+ sconv->uniInfo = NULL;
+ err = CreateUnicodeToTextInfo(&map, &(sconv->uniInfo));
+ return ((err == noErr)? 0: -1);
+}
+
+#endif /* __APPLE__ */
+
+static void
+add_converter(struct archive_string_conv *sc, int (*converter)
+ (struct archive_string *, const void *, size_t,
+ struct archive_string_conv *))
+{
+ if (sc == NULL || sc->nconverter >= 2)
+ __archive_errx(1, "Programing error");
+ sc->converter[sc->nconverter++] = converter;
+}
+
+static void
+setup_converter(struct archive_string_conv *sc)
+{
+
+ /* Reset. */
+ sc->nconverter = 0;
+
+ /*
+ * Perform special sequence for the incorrect UTF-8 filenames
+ * made by libarchive2.x.
+ */
+ if (sc->flag & SCONV_UTF8_LIBARCHIVE_2) {
+ add_converter(sc, strncat_from_utf8_libarchive2);
+ return;
+ }
+
+ /*
+ * Convert a string to UTF-16BE/LE.
+ */
+ if (sc->flag & SCONV_TO_UTF16) {
+ /*
+ * If the current locale is UTF-8, we can translate
+ * a UTF-8 string into a UTF-16BE string.
+ */
+ if (sc->flag & SCONV_FROM_UTF8) {
+ add_converter(sc, archive_string_append_unicode);
+ return;
+ }
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ if (sc->flag & SCONV_WIN_CP) {
+ if (sc->flag & SCONV_TO_UTF16BE)
+ add_converter(sc, win_strncat_to_utf16be);
+ else
+ add_converter(sc, win_strncat_to_utf16le);
+ return;
+ }
+#endif
+
+#if defined(HAVE_ICONV)
+ if (sc->cd != (iconv_t)-1) {
+ add_converter(sc, iconv_strncat_in_locale);
+ return;
+ }
+#endif
+
+ if (sc->flag & SCONV_BEST_EFFORT) {
+ if (sc->flag & SCONV_TO_UTF16BE)
+ add_converter(sc, best_effort_strncat_to_utf16be);
+ else
+ add_converter(sc, best_effort_strncat_to_utf16le);
+ } else
+ /* Make sure we have no converter. */
+ sc->nconverter = 0;
+ return;
+ }
+
+ /*
+ * Convert a string from UTF-16BE/LE.
+ */
+ if (sc->flag & SCONV_FROM_UTF16) {
+ /*
+ * At least we should normalize a UTF-16BE string.
+ */
+#if defined(__APPLE__)
+ if (sc->flag & SCONV_NORMALIZATION_D)
+ add_converter(sc,archive_string_normalize_D);
+ else
+#endif
+ if (sc->flag & SCONV_NORMALIZATION_C)
+ add_converter(sc, archive_string_normalize_C);
+
+ if (sc->flag & SCONV_TO_UTF8) {
+ /*
+ * If the current locale is UTF-8, we can translate
+ * a UTF-16BE/LE string into a UTF-8 string directly.
+ */
+ if (!(sc->flag &
+ (SCONV_NORMALIZATION_D |SCONV_NORMALIZATION_C)))
+ add_converter(sc,
+ archive_string_append_unicode);
+ return;
+ }
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ if (sc->flag & SCONV_WIN_CP) {
+ if (sc->flag & SCONV_FROM_UTF16BE)
+ add_converter(sc, win_strncat_from_utf16be);
+ else
+ add_converter(sc, win_strncat_from_utf16le);
+ return;
+ }
+#endif
+
+#if defined(HAVE_ICONV)
+ if (sc->cd != (iconv_t)-1) {
+ add_converter(sc, iconv_strncat_in_locale);
+ return;
+ }
+#endif
+
+ if ((sc->flag & (SCONV_BEST_EFFORT | SCONV_FROM_UTF16BE))
+ == (SCONV_BEST_EFFORT | SCONV_FROM_UTF16BE))
+ add_converter(sc, best_effort_strncat_from_utf16be);
+ else if ((sc->flag & (SCONV_BEST_EFFORT | SCONV_FROM_UTF16LE))
+ == (SCONV_BEST_EFFORT | SCONV_FROM_UTF16LE))
+ add_converter(sc, best_effort_strncat_from_utf16le);
+ else
+ /* Make sure we have no converter. */
+ sc->nconverter = 0;
+ return;
+ }
+
+ if (sc->flag & SCONV_FROM_UTF8) {
+ /*
+ * At least we should normalize a UTF-8 string.
+ */
+#if defined(__APPLE__)
+ if (sc->flag & SCONV_NORMALIZATION_D)
+ add_converter(sc,archive_string_normalize_D);
+ else
+#endif
+ if (sc->flag & SCONV_NORMALIZATION_C)
+ add_converter(sc, archive_string_normalize_C);
+
+ /*
+ * Copy UTF-8 string with a check of CESU-8.
+ * Apparently, iconv does not check surrogate pairs in UTF-8
+ * when both from-charset and to-charset are UTF-8, and then
+ * we use our UTF-8 copy code.
+ */
+ if (sc->flag & SCONV_TO_UTF8) {
+ /*
+ * If the current locale is UTF-8, we can translate
+ * a UTF-16BE string into a UTF-8 string directly.
+ */
+ if (!(sc->flag &
+ (SCONV_NORMALIZATION_D |SCONV_NORMALIZATION_C)))
+ add_converter(sc, strncat_from_utf8_to_utf8);
+ return;
+ }
+ }
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ /*
+ * On Windows we can use Windows API for a string conversion.
+ */
+ if (sc->flag & SCONV_WIN_CP) {
+ add_converter(sc, strncat_in_codepage);
+ return;
+ }
+#endif
+
+#if HAVE_ICONV
+ if (sc->cd != (iconv_t)-1) {
+ add_converter(sc, iconv_strncat_in_locale);
+ return;
+ }
+#endif
+
+ /*
+ * Try conversion in the best effort or no conversion.
+ */
+ if ((sc->flag & SCONV_BEST_EFFORT) || sc->same)
+ add_converter(sc, best_effort_strncat_in_locale);
+ else
+ /* Make sure we have no converter. */
+ sc->nconverter = 0;
+}
+
+/*
+ * Return canonicalized charset-name but this supports just UTF-8, UTF-16BE
+ * and CP932 which are referenced in create_sconv_object().
+ */
+static const char *
+canonical_charset_name(const char *charset)
+{
+ char cs[16];
+ char *p;
+ const char *s;
+
+ if (charset == NULL || charset[0] == '\0'
+ || strlen(charset) > 15)
+ return (charset);
+
+ /* Copy name to uppercase. */
+ p = cs;
+ s = charset;
+ while (*s) {
+ char c = *s++;
+ if (c >= 'a' && c <= 'z')
+ c -= 'a' - 'A';
+ *p++ = c;
+ }
+ *p++ = '\0';
+
+ if (strcmp(cs, "UTF-8") == 0 ||
+ strcmp(cs, "UTF8") == 0)
+ return ("UTF-8");
+ if (strcmp(cs, "UTF-16BE") == 0 ||
+ strcmp(cs, "UTF16BE") == 0)
+ return ("UTF-16BE");
+ if (strcmp(cs, "UTF-16LE") == 0 ||
+ strcmp(cs, "UTF16LE") == 0)
+ return ("UTF-16LE");
+ if (strcmp(cs, "CP932") == 0)
+ return ("CP932");
+ return (charset);
+}
+
+/*
+ * Create a string conversion object.
+ */
+static struct archive_string_conv *
+create_sconv_object(const char *fc, const char *tc,
+ unsigned current_codepage, int flag)
+{
+ struct archive_string_conv *sc;
+
+ sc = calloc(1, sizeof(*sc));
+ if (sc == NULL)
+ return (NULL);
+ sc->next = NULL;
+ sc->from_charset = strdup(fc);
+ if (sc->from_charset == NULL) {
+ free(sc);
+ return (NULL);
+ }
+ sc->to_charset = strdup(tc);
+ if (sc->to_charset == NULL) {
+ free(sc);
+ free(sc->from_charset);
+ return (NULL);
+ }
+ archive_string_init(&sc->utftmp);
+#if defined(__APPLE__)
+ archive_string_init(&sc->utf16nfc);
+ archive_string_init(&sc->utf16nfd);
+#endif
+
+ if (flag & SCONV_TO_CHARSET) {
+ /*
+ * Convert characters from the current locale charset to
+ * a specified charset.
+ */
+ sc->from_cp = current_codepage;
+ sc->to_cp = make_codepage_from_charset(tc);
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ if (IsValidCodePage(sc->to_cp))
+ flag |= SCONV_WIN_CP;
+#endif
+ } else if (flag & SCONV_FROM_CHARSET) {
+ /*
+ * Convert characters from a specified charset to
+ * the current locale charset.
+ */
+ sc->to_cp = current_codepage;
+ sc->from_cp = make_codepage_from_charset(fc);
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ if (IsValidCodePage(sc->from_cp))
+ flag |= SCONV_WIN_CP;
+#endif
+ }
+
+ /*
+ * Check if "from charset" and "to charset" are the same.
+ */
+ if (strcmp(fc, tc) == 0 ||
+ (sc->from_cp != -1 && sc->from_cp == sc->to_cp))
+ sc->same = 1;
+ else
+ sc->same = 0;
+
+ /*
+ * Mark if "from charset" or "to charset" are UTF-8 or UTF-16BE/LE.
+ */
+ if (strcmp(tc, "UTF-8") == 0)
+ flag |= SCONV_TO_UTF8;
+ else if (strcmp(tc, "UTF-16BE") == 0)
+ flag |= SCONV_TO_UTF16BE;
+ else if (strcmp(tc, "UTF-16LE") == 0)
+ flag |= SCONV_TO_UTF16LE;
+ if (strcmp(fc, "UTF-8") == 0)
+ flag |= SCONV_FROM_UTF8;
+ else if (strcmp(fc, "UTF-16BE") == 0)
+ flag |= SCONV_FROM_UTF16BE;
+ else if (strcmp(fc, "UTF-16LE") == 0)
+ flag |= SCONV_FROM_UTF16LE;
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ if (sc->to_cp == CP_UTF8)
+ flag |= SCONV_TO_UTF8;
+ else if (sc->to_cp == CP_UTF16BE)
+ flag |= SCONV_TO_UTF16BE | SCONV_WIN_CP;
+ else if (sc->to_cp == CP_UTF16LE)
+ flag |= SCONV_TO_UTF16LE | SCONV_WIN_CP;
+ if (sc->from_cp == CP_UTF8)
+ flag |= SCONV_FROM_UTF8;
+ else if (sc->from_cp == CP_UTF16BE)
+ flag |= SCONV_FROM_UTF16BE | SCONV_WIN_CP;
+ else if (sc->from_cp == CP_UTF16LE)
+ flag |= SCONV_FROM_UTF16LE | SCONV_WIN_CP;
+#endif
+
+ /*
+ * Set a flag for Unicode NFD. Usually iconv cannot correctly
+ * handle it. So we have to translate NFD characters to NFC ones
+ * ourselves before iconv handles. Another reason is to prevent
+ * that the same sight of two filenames, one is NFC and other
+ * is NFD, would be in its directory.
+ * On Mac OS X, although its filesystem layer automatically
+ * convert filenames to NFD, it would be useful for filename
+ * comparing to find out the same filenames that we normalize
+ * that to be NFD ourselves.
+ */
+ if ((flag & SCONV_FROM_CHARSET) &&
+ (flag & (SCONV_FROM_UTF16 | SCONV_FROM_UTF8))) {
+#if defined(__APPLE__)
+ if (flag & SCONV_TO_UTF8) {
+ if (createUniInfo(sc) == 0)
+ flag |= SCONV_NORMALIZATION_D;
+ } else
+#endif
+ flag |= SCONV_NORMALIZATION_C;
+ }
+
+#if defined(HAVE_ICONV)
+ sc->cd_w = (iconv_t)-1;
+ /*
+ * Create an iconv object.
+ */
+ if (((flag & (SCONV_TO_UTF8 | SCONV_TO_UTF16)) &&
+ (flag & (SCONV_FROM_UTF8 | SCONV_FROM_UTF16))) ||
+ (flag & SCONV_WIN_CP)) {
+ /* This case we won't use iconv. */
+ sc->cd = (iconv_t)-1;
+#if defined(__APPLE__)
+ } else if ((flag & SCONV_FROM_CHARSET) && (flag & SCONV_TO_UTF8)) {
+ /*
+ * In case reading an archive file.
+ * Translate non-Unicode filenames in an archive file to
+ * UTF-8-MAC filenames.
+ */
+ sc->cd = iconv_open("UTF-8-MAC", fc);
+ if (sc->cd == (iconv_t)-1) {
+ if ((sc->flag & SCONV_BEST_EFFORT) &&
+ strcmp(fc, "CP932") == 0) {
+ sc->cd = iconv_open("UTF-8-MAC", "SJIS");
+ if (sc->cd == (iconv_t)-1) {
+ sc->cd = iconv_open(tc, fc);
+ if (sc->cd == (iconv_t)-1)
+ sc->cd = iconv_open(tc, "SJIS");
+ }
+ } else
+ sc->cd = iconv_open(tc, fc);
+ }
+ } else if ((flag & SCONV_TO_CHARSET) && (flag & SCONV_FROM_UTF8)) {
+ /*
+ * In case writing an archive file.
+ * Translate UTF-8-MAC filenames in HFS Plus to non-Unicode
+ * filenames.
+ */
+ sc->cd = iconv_open(tc, "UTF-8-MAC");
+ if (sc->cd == (iconv_t)-1) {
+ if ((sc->flag & SCONV_BEST_EFFORT) &&
+ strcmp(tc, "CP932") == 0) {
+ sc->cd = iconv_open("SJIS", "UTF-8-MAC");
+ if (sc->cd == (iconv_t)-1) {
+ sc->cd = iconv_open(tc, fc);
+ if (sc->cd == (iconv_t)-1)
+ sc->cd = iconv_open("SJIS", fc);
+ }
+ } else
+ sc->cd = iconv_open(tc, fc);
+ }
+#endif
+ } else {
+ sc->cd = iconv_open(tc, fc);
+ if (sc->cd == (iconv_t)-1 && (sc->flag & SCONV_BEST_EFFORT)) {
+ /*
+ * Unfortunaly, all of iconv implements do support
+ * "CP932" character-set, so we should use "SJIS"
+ * instead if iconv_open failed.
+ */
+ if (strcmp(tc, "CP932") == 0)
+ sc->cd = iconv_open("SJIS", fc);
+ else if (strcmp(fc, "CP932") == 0)
+ sc->cd = iconv_open(tc, "SJIS");
+ }
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ /*
+ * archive_mstring on Windows directly convert multi-bytes
+ * into archive_wstring in order not to depend on locale
+ * so that you can do a I18N programing. This will be
+ * used only in archive_mstring_copy_mbs_len_l so far.
+ */
+ if (flag & SCONV_FROM_CHARSET) {
+ sc->cd_w = iconv_open("UTF-8", fc);
+ if (sc->cd_w == (iconv_t)-1 &&
+ (sc->flag & SCONV_BEST_EFFORT)) {
+ if (strcmp(fc, "CP932") == 0)
+ sc->cd_w = iconv_open("UTF-8", "SJIS");
+ }
+ }
+#endif /* _WIN32 && !__CYGWIN__ */
+ }
+#endif /* HAVE_ICONV */
+
+ sc->flag = flag;
+
+ /*
+ * Setup converters.
+ */
+ setup_converter(sc);
+
+ return (sc);
+}
+
+/*
+ * Free a string conversion object.
+ */
+static void
+free_sconv_object(struct archive_string_conv *sc)
+{
+ free(sc->from_charset);
+ free(sc->to_charset);
+ archive_string_free(&sc->utftmp);
+#if HAVE_ICONV
+ if (sc->cd != (iconv_t)-1)
+ iconv_close(sc->cd);
+ if (sc->cd_w != (iconv_t)-1)
+ iconv_close(sc->cd_w);
+#endif
+#if defined(__APPLE__)
+ archive_string_free(&sc->utf16nfc);
+ archive_string_free(&sc->utf16nfd);
+ if (sc->uniInfo != NULL)
+ DisposeUnicodeToTextInfo(&(sc->uniInfo));
+#endif
+ free(sc);
+}
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+static unsigned
+my_atoi(const char *p)
+{
+ unsigned cp;
+
+ cp = 0;
+ while (*p) {
+ if (*p >= '0' && *p <= '9')
+ cp = cp * 10 + (*p - '0');
+ else
+ return (-1);
+ p++;
+ }
+ return (cp);
+}
+
+/*
+ * Translate Charset name (as used by iconv) into CodePage (as used by Windows)
+ * Return -1 if failed.
+ *
+ * Note: This translation code may be insufficient.
+ */
+static struct charset {
+ const char *name;
+ unsigned cp;
+} charsets[] = {
+ /* MUST BE SORTED! */
+ {"ASCII", 1252},
+ {"ASMO-708", 708},
+ {"BIG5", 950},
+ {"CHINESE", 936},
+ {"CP367", 1252},
+ {"CP819", 1252},
+ {"CP1025", 21025},
+ {"DOS-720", 720},
+ {"DOS-862", 862},
+ {"EUC-CN", 51936},
+ {"EUC-JP", 51932},
+ {"EUC-KR", 949},
+ {"EUCCN", 51936},
+ {"EUCJP", 51932},
+ {"EUCKR", 949},
+ {"GB18030", 54936},
+ {"GB2312", 936},
+ {"HEBREW", 1255},
+ {"HZ-GB-2312", 52936},
+ {"IBM273", 20273},
+ {"IBM277", 20277},
+ {"IBM278", 20278},
+ {"IBM280", 20280},
+ {"IBM284", 20284},
+ {"IBM285", 20285},
+ {"IBM290", 20290},
+ {"IBM297", 20297},
+ {"IBM367", 1252},
+ {"IBM420", 20420},
+ {"IBM423", 20423},
+ {"IBM424", 20424},
+ {"IBM819", 1252},
+ {"IBM871", 20871},
+ {"IBM880", 20880},
+ {"IBM905", 20905},
+ {"IBM924", 20924},
+ {"ISO-8859-1", 28591},
+ {"ISO-8859-13", 28603},
+ {"ISO-8859-15", 28605},
+ {"ISO-8859-2", 28592},
+ {"ISO-8859-3", 28593},
+ {"ISO-8859-4", 28594},
+ {"ISO-8859-5", 28595},
+ {"ISO-8859-6", 28596},
+ {"ISO-8859-7", 28597},
+ {"ISO-8859-8", 28598},
+ {"ISO-8859-9", 28599},
+ {"ISO8859-1", 28591},
+ {"ISO8859-13", 28603},
+ {"ISO8859-15", 28605},
+ {"ISO8859-2", 28592},
+ {"ISO8859-3", 28593},
+ {"ISO8859-4", 28594},
+ {"ISO8859-5", 28595},
+ {"ISO8859-6", 28596},
+ {"ISO8859-7", 28597},
+ {"ISO8859-8", 28598},
+ {"ISO8859-9", 28599},
+ {"JOHAB", 1361},
+ {"KOI8-R", 20866},
+ {"KOI8-U", 21866},
+ {"KS_C_5601-1987", 949},
+ {"LATIN1", 1252},
+ {"LATIN2", 28592},
+ {"MACINTOSH", 10000},
+ {"SHIFT-JIS", 932},
+ {"SHIFT_JIS", 932},
+ {"SJIS", 932},
+ {"US", 1252},
+ {"US-ASCII", 1252},
+ {"UTF-16", 1200},
+ {"UTF-16BE", 1201},
+ {"UTF-16LE", 1200},
+ {"UTF-8", CP_UTF8},
+ {"X-EUROPA", 29001},
+ {"X-MAC-ARABIC", 10004},
+ {"X-MAC-CE", 10029},
+ {"X-MAC-CHINESEIMP", 10008},
+ {"X-MAC-CHINESETRAD", 10002},
+ {"X-MAC-CROATIAN", 10082},
+ {"X-MAC-CYRILLIC", 10007},
+ {"X-MAC-GREEK", 10006},
+ {"X-MAC-HEBREW", 10005},
+ {"X-MAC-ICELANDIC", 10079},
+ {"X-MAC-JAPANESE", 10001},
+ {"X-MAC-KOREAN", 10003},
+ {"X-MAC-ROMANIAN", 10010},
+ {"X-MAC-THAI", 10021},
+ {"X-MAC-TURKISH", 10081},
+ {"X-MAC-UKRAINIAN", 10017},
+};
+static unsigned
+make_codepage_from_charset(const char *charset)
+{
+ char cs[16];
+ char *p;
+ unsigned cp;
+ int a, b;
+
+ if (charset == NULL || strlen(charset) > 15)
+ return -1;
+
+ /* Copy name to uppercase. */
+ p = cs;
+ while (*charset) {
+ char c = *charset++;
+ if (c >= 'a' && c <= 'z')
+ c -= 'a' - 'A';
+ *p++ = c;
+ }
+ *p++ = '\0';
+ cp = -1;
+
+ /* Look it up in the table first, so that we can easily
+ * override CP367, which we map to 1252 instead of 367. */
+ a = 0;
+ b = sizeof(charsets)/sizeof(charsets[0]);
+ while (b > a) {
+ int c = (b + a) / 2;
+ int r = strcmp(charsets[c].name, cs);
+ if (r < 0)
+ a = c + 1;
+ else if (r > 0)
+ b = c;
+ else
+ return charsets[c].cp;
+ }
+
+ /* If it's not in the table, try to parse it. */
+ switch (*cs) {
+ case 'C':
+ if (cs[1] == 'P' && cs[2] >= '0' && cs[2] <= '9') {
+ cp = my_atoi(cs + 2);
+ } else if (strcmp(cs, "CP_ACP") == 0)
+ cp = get_current_codepage();
+ else if (strcmp(cs, "CP_OEMCP") == 0)
+ cp = get_current_oemcp();
+ break;
+ case 'I':
+ if (cs[1] == 'B' && cs[2] == 'M' &&
+ cs[3] >= '0' && cs[3] <= '9') {
+ cp = my_atoi(cs + 3);
+ }
+ break;
+ case 'W':
+ if (strncmp(cs, "WINDOWS-", 8) == 0) {
+ cp = my_atoi(cs + 8);
+ if (cp != 874 && (cp < 1250 || cp > 1258))
+ cp = -1;/* This may invalid code. */
+ }
+ break;
+ }
+ return (cp);
+}
+
+/*
+ * Return ANSI Code Page of current locale set by setlocale().
+ */
+static unsigned
+get_current_codepage()
+{
+ char *locale, *p;
+ unsigned cp;
+
+ locale = setlocale(LC_CTYPE, NULL);
+ if (locale == NULL)
+ return (GetACP());
+ if (locale[0] == 'C' && locale[1] == '\0')
+ return (CP_C_LOCALE);
+ p = strrchr(locale, '.');
+ if (p == NULL)
+ return (GetACP());
+ cp = my_atoi(p+1);
+ if (cp <= 0)
+ return (GetACP());
+ return (cp);
+}
+
+/*
+ * Translation table between Locale Name and ACP/OEMCP.
+ */
+static struct {
+ unsigned acp;
+ unsigned ocp;
+ const char *locale;
+} acp_ocp_map[] = {
+ { 950, 950, "Chinese_Taiwan" },
+ { 936, 936, "Chinese_People's Republic of China" },
+ { 950, 950, "Chinese_Taiwan" },
+ { 1250, 852, "Czech_Czech Republic" },
+ { 1252, 850, "Danish_Denmark" },
+ { 1252, 850, "Dutch_Netherlands" },
+ { 1252, 850, "Dutch_Belgium" },
+ { 1252, 437, "English_United States" },
+ { 1252, 850, "English_Australia" },
+ { 1252, 850, "English_Canada" },
+ { 1252, 850, "English_New Zealand" },
+ { 1252, 850, "English_United Kingdom" },
+ { 1252, 437, "English_United States" },
+ { 1252, 850, "Finnish_Finland" },
+ { 1252, 850, "French_France" },
+ { 1252, 850, "French_Belgium" },
+ { 1252, 850, "French_Canada" },
+ { 1252, 850, "French_Switzerland" },
+ { 1252, 850, "German_Germany" },
+ { 1252, 850, "German_Austria" },
+ { 1252, 850, "German_Switzerland" },
+ { 1253, 737, "Greek_Greece" },
+ { 1250, 852, "Hungarian_Hungary" },
+ { 1252, 850, "Icelandic_Iceland" },
+ { 1252, 850, "Italian_Italy" },
+ { 1252, 850, "Italian_Switzerland" },
+ { 932, 932, "Japanese_Japan" },
+ { 949, 949, "Korean_Korea" },
+ { 1252, 850, "Norwegian (BokmOl)_Norway" },
+ { 1252, 850, "Norwegian (BokmOl)_Norway" },
+ { 1252, 850, "Norwegian-Nynorsk_Norway" },
+ { 1250, 852, "Polish_Poland" },
+ { 1252, 850, "Portuguese_Portugal" },
+ { 1252, 850, "Portuguese_Brazil" },
+ { 1251, 866, "Russian_Russia" },
+ { 1250, 852, "Slovak_Slovakia" },
+ { 1252, 850, "Spanish_Spain" },
+ { 1252, 850, "Spanish_Mexico" },
+ { 1252, 850, "Spanish_Spain" },
+ { 1252, 850, "Swedish_Sweden" },
+ { 1254, 857, "Turkish_Turkey" },
+ { 0, 0, NULL}
+};
+
+/*
+ * Return OEM Code Page of current locale set by setlocale().
+ */
+static unsigned
+get_current_oemcp()
+{
+ int i;
+ char *locale, *p;
+ size_t len;
+
+ locale = setlocale(LC_CTYPE, NULL);
+ if (locale == NULL)
+ return (GetOEMCP());
+ if (locale[0] == 'C' && locale[1] == '\0')
+ return (CP_C_LOCALE);
+
+ p = strrchr(locale, '.');
+ if (p == NULL)
+ return (GetOEMCP());
+ len = p - locale;
+ for (i = 0; acp_ocp_map[i].acp; i++) {
+ if (strncmp(acp_ocp_map[i].locale, locale, len) == 0)
+ return (acp_ocp_map[i].ocp);
+ }
+ return (GetOEMCP());
+}
+#else
+
+/*
+ * POSIX platform does not use CodePage.
+ */
+
+static unsigned
+get_current_codepage()
+{
+ return (-1);/* Unknown */
+}
+static unsigned
+make_codepage_from_charset(const char *charset)
+{
+ (void)charset; /* UNUSED */
+ return (-1);/* Unknown */
+}
+static unsigned
+get_current_oemcp()
+{
+ return (-1);/* Unknown */
+}
+
+#endif /* defined(_WIN32) && !defined(__CYGWIN__) */
+
+/*
+ * Return a string conversion object.
+ */
+static struct archive_string_conv *
+get_sconv_object(struct archive *a, const char *fc, const char *tc, int flag)
+{
+ struct archive_string_conv *sc;
+ unsigned current_codepage;
+
+ /* Check if we have made the sconv object. */
+ sc = find_sconv_object(a, fc, tc);
+ if (sc != NULL)
+ return (sc);
+
+ if (a == NULL)
+ current_codepage = get_current_codepage();
+ else
+ current_codepage = a->current_codepage;
+
+ sc = create_sconv_object(canonical_charset_name(fc),
+ canonical_charset_name(tc), current_codepage, flag);
+ if (sc == NULL) {
+ if (a != NULL)
+ archive_set_error(a, ENOMEM,
+ "Could not allocate memory for "
+ "a string conversion object");
+ return (NULL);
+ }
+
+ /*
+ * If there is no converter for current string conversion object,
+ * we cannot handle this conversion.
+ */
+ if (sc->nconverter == 0) {
+ if (a != NULL) {
+#if HAVE_ICONV
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "iconv_open failed : Cannot handle ``%s''",
+ (flag & SCONV_TO_CHARSET)?tc:fc);
+#else
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "A character-set conversion not fully supported "
+ "on this platform");
+#endif
+ }
+ /* Failed; free a sconv object. */
+ free_sconv_object(sc);
+ return (NULL);
+ }
+
+ /*
+ * Success!
+ */
+ if (a != NULL)
+ add_sconv_object(a, sc);
+ return (sc);
+}
+
+static const char *
+get_current_charset(struct archive *a)
+{
+ const char *cur_charset;
+
+ if (a == NULL)
+ cur_charset = default_iconv_charset("");
+ else {
+ cur_charset = default_iconv_charset(a->current_code);
+ if (a->current_code == NULL) {
+ a->current_code = strdup(cur_charset);
+ a->current_codepage = get_current_codepage();
+ a->current_oemcp = get_current_oemcp();
+ }
+ }
+ return (cur_charset);
+}
+
+/*
+ * Make and Return a string conversion object.
+ * Return NULL if the platform does not support the specified conversion
+ * and best_effort is 0.
+ * If best_effort is set, A string conversion object must be returned
+ * unless memory allocation for the object fails, but the conversion
+ * might fail when non-ASCII code is found.
+ */
+struct archive_string_conv *
+archive_string_conversion_to_charset(struct archive *a, const char *charset,
+ int best_effort)
+{
+ int flag = SCONV_TO_CHARSET;
+
+ if (best_effort)
+ flag |= SCONV_BEST_EFFORT;
+ return (get_sconv_object(a, get_current_charset(a), charset, flag));
+}
+
+struct archive_string_conv *
+archive_string_conversion_from_charset(struct archive *a, const char *charset,
+ int best_effort)
+{
+ int flag = SCONV_FROM_CHARSET;
+
+ if (best_effort)
+ flag |= SCONV_BEST_EFFORT;
+ return (get_sconv_object(a, charset, get_current_charset(a), flag));
+}
+
+/*
+ * archive_string_default_conversion_*_archive() are provided for Windows
+ * platform because other archiver application use CP_OEMCP for
+ * MultiByteToWideChar() and WideCharToMultiByte() for the filenames
+ * in tar or zip files. But mbstowcs/wcstombs(CRT) usually use CP_ACP
+ * unless you use setlocale(LC_ALL, ".OCP")(specify CP_OEMCP).
+ * So we should make a string conversion between CP_ACP and CP_OEMCP
+ * for compatibillty.
+ */
+#if defined(_WIN32) && !defined(__CYGWIN__)
+struct archive_string_conv *
+archive_string_default_conversion_for_read(struct archive *a)
+{
+ const char *cur_charset = get_current_charset(a);
+ char oemcp[16];
+
+ /* NOTE: a check of cur_charset is unneeded but we need
+ * that get_current_charset() has been surely called at
+ * this time whatever C compiler optimized. */
+ if (cur_charset != NULL &&
+ (a->current_codepage == CP_C_LOCALE ||
+ a->current_codepage == a->current_oemcp))
+ return (NULL);/* no conversion. */
+
+ _snprintf(oemcp, sizeof(oemcp)-1, "CP%d", a->current_oemcp);
+ /* Make sure a null termination must be set. */
+ oemcp[sizeof(oemcp)-1] = '\0';
+ return (get_sconv_object(a, oemcp, cur_charset,
+ SCONV_FROM_CHARSET));
+}
+
+struct archive_string_conv *
+archive_string_default_conversion_for_write(struct archive *a)
+{
+ const char *cur_charset = get_current_charset(a);
+ char oemcp[16];
+
+ /* NOTE: a check of cur_charset is unneeded but we need
+ * that get_current_charset() has been surely called at
+ * this time whatever C compiler optimized. */
+ if (cur_charset != NULL &&
+ (a->current_codepage == CP_C_LOCALE ||
+ a->current_codepage == a->current_oemcp))
+ return (NULL);/* no conversion. */
+
+ _snprintf(oemcp, sizeof(oemcp)-1, "CP%d", a->current_oemcp);
+ /* Make sure a null termination must be set. */
+ oemcp[sizeof(oemcp)-1] = '\0';
+ return (get_sconv_object(a, cur_charset, oemcp,
+ SCONV_TO_CHARSET));
+}
+#else
+struct archive_string_conv *
+archive_string_default_conversion_for_read(struct archive *a)
+{
+ (void)a; /* UNUSED */
+ return (NULL);
+}
+
+struct archive_string_conv *
+archive_string_default_conversion_for_write(struct archive *a)
+{
+ (void)a; /* UNUSED */
+ return (NULL);
+}
+#endif
+
+/*
+ * Dispose of all character conversion objects in the archive object.
+ */
+void
+archive_string_conversion_free(struct archive *a)
+{
+ struct archive_string_conv *sc;
+ struct archive_string_conv *sc_next;
+
+ for (sc = a->sconv; sc != NULL; sc = sc_next) {
+ sc_next = sc->next;
+ free_sconv_object(sc);
+ }
+ a->sconv = NULL;
+ free(a->current_code);
+ a->current_code = NULL;
+}
+
+/*
+ * Return a conversion charset name.
+ */
+const char *
+archive_string_conversion_charset_name(struct archive_string_conv *sc)
+{
+ if (sc->flag & SCONV_TO_CHARSET)
+ return (sc->to_charset);
+ else
+ return (sc->from_charset);
+}
+
+/*
+ * Change the behavior of a string conversion.
+ */
+void
+archive_string_conversion_set_opt(struct archive_string_conv *sc, int opt)
+{
+ switch (opt) {
+ /*
+ * A filename in UTF-8 was made with libarchive 2.x in a wrong
+ * assumption that wchar_t was Unicode.
+ * This option enables simulating the assumption in order to read
+ * that filname correctly.
+ */
+ case SCONV_SET_OPT_UTF8_LIBARCHIVE2X:
+#if (defined(_WIN32) && !defined(__CYGWIN__)) \
+ || defined(__STDC_ISO_10646__) || defined(__APPLE__)
+ /*
+ * Nothing to do for it since wchar_t on these platforms
+ * is really Unicode.
+ */
+ (void)sc; /* UNUSED */
+#else
+ if ((sc->flag & SCONV_UTF8_LIBARCHIVE_2) == 0) {
+ sc->flag |= SCONV_UTF8_LIBARCHIVE_2;
+ /* Re-setup string converters. */
+ setup_converter(sc);
+ }
+#endif
+ break;
+ default:
+ break;
+ }
+}
+
+/*
+ *
+ * Copy one archive_string to another in locale conversion.
+ *
+ * archive_strncpy_in_locale();
+ * archive_strcpy_in_locale();
+ *
+ */
+
+static size_t
+mbsnbytes(const void *_p, size_t n)
+{
+ size_t s;
+ const char *p, *pp;
+
+ if (_p == NULL)
+ return (0);
+ p = (const char *)_p;
+
+ /* Like strlen(p), except won't examine positions beyond p[n]. */
+ s = 0;
+ pp = p;
+ while (s < n && *pp) {
+ pp++;
+ s++;
+ }
+ return (s);
+}
+
+static size_t
+utf16nbytes(const void *_p, size_t n)
+{
+ size_t s;
+ const char *p, *pp;
+
+ if (_p == NULL)
+ return (0);
+ p = (const char *)_p;
+
+ /* Like strlen(p), except won't examine positions beyond p[n]. */
+ s = 0;
+ pp = p;
+ n >>= 1;
+ while (s < n && (pp[0] || pp[1])) {
+ pp += 2;
+ s++;
+ }
+ return (s<<1);
+}
+
+int
+archive_strncpy_in_locale(struct archive_string *as, const void *_p, size_t n,
+ struct archive_string_conv *sc)
+{
+ as->length = 0;
+ return (archive_strncat_in_locale(as, _p, n, sc));
+}
+
+int
+archive_strncat_in_locale(struct archive_string *as, const void *_p, size_t n,
+ struct archive_string_conv *sc)
+{
+ const void *s;
+ size_t length;
+ int i, r = 0, r2;
+
+ /* We must allocate memory even if there is no data for conversion
+ * or copy. This simulates archive_string_append behavior. */
+ if (_p == NULL || n == 0) {
+ int tn = 1;
+ if (sc != NULL && (sc->flag & SCONV_TO_UTF16))
+ tn = 2;
+ if (archive_string_ensure(as, as->length + tn) == NULL)
+ return (-1);
+ as->s[as->length] = 0;
+ if (tn == 2)
+ as->s[as->length+1] = 0;
+ return (0);
+ }
+
+ /*
+ * If sc is NULL, we just make a copy.
+ */
+ if (sc == NULL) {
+ length = mbsnbytes(_p, n);
+ if (archive_string_append(as, _p, length) == NULL)
+ return (-1);/* No memory */
+ return (0);
+ }
+
+ if (sc->flag & SCONV_FROM_UTF16)
+ length = utf16nbytes(_p, n);
+ else
+ length = mbsnbytes(_p, n);
+ s = _p;
+ i = 0;
+ if (sc->nconverter > 1) {
+ sc->utftmp.length = 0;
+ r2 = sc->converter[0](&(sc->utftmp), s, length, sc);
+ if (r2 != 0 && errno == ENOMEM)
+ return (r2);
+ if (r > r2)
+ r = r2;
+ s = sc->utftmp.s;
+ length = sc->utftmp.length;
+ ++i;
+ }
+ r2 = sc->converter[i](as, s, length, sc);
+ if (r > r2)
+ r = r2;
+ return (r);
+}
+
+#if HAVE_ICONV
+
+/*
+ * Return -1 if conversion failes.
+ */
+static int
+iconv_strncat_in_locale(struct archive_string *as, const void *_p,
+ size_t length, struct archive_string_conv *sc)
+{
+ ICONV_CONST char *inp;
+ size_t remaining;
+ iconv_t cd;
+ char *outp;
+ size_t avail, bs;
+ int return_value = 0; /* success */
+ int to_size, from_size;
+
+ if (sc->flag & SCONV_TO_UTF16)
+ to_size = 2;
+ else
+ to_size = 1;
+ if (sc->flag & SCONV_FROM_UTF16)
+ from_size = 2;
+ else
+ from_size = 1;
+
+ if (archive_string_ensure(as, as->length + length*2+to_size) == NULL)
+ return (-1);
+
+ cd = sc->cd;
+ inp = (char *)(uintptr_t)_p;
+ remaining = length;
+ outp = as->s + as->length;
+ avail = as->buffer_length - as->length - to_size;
+ while (remaining >= (size_t)from_size) {
+ size_t result = iconv(cd, &inp, &remaining, &outp, &avail);
+
+ if (result != (size_t)-1)
+ break; /* Conversion completed. */
+
+ if (errno == EILSEQ || errno == EINVAL) {
+ /*
+ * If an output charset is UTF-8 or UTF-16BE/LE,
+ * unknown character should be U+FFFD
+ * (replacement character).
+ */
+ if (sc->flag & (SCONV_TO_UTF8 | SCONV_TO_UTF16)) {
+ size_t rbytes;
+ if (sc->flag & SCONV_TO_UTF8)
+ rbytes = UTF8_R_CHAR_SIZE;
+ else
+ rbytes = 2;
+
+ if (avail < rbytes) {
+ as->length = outp - as->s;
+ bs = as->buffer_length +
+ (remaining * to_size) + rbytes;
+ if (NULL ==
+ archive_string_ensure(as, bs))
+ return (-1);
+ outp = as->s + as->length;
+ avail = as->buffer_length
+ - as->length - to_size;
+ }
+ if (sc->flag & SCONV_TO_UTF8)
+ UTF8_SET_R_CHAR(outp);
+ else if (sc->flag & SCONV_TO_UTF16BE)
+ archive_be16enc(outp, UNICODE_R_CHAR);
+ else
+ archive_le16enc(outp, UNICODE_R_CHAR);
+ outp += rbytes;
+ avail -= rbytes;
+ } else {
+ /* Skip the illegal input bytes. */
+ *outp++ = '?';
+ avail--;
+ }
+ inp += from_size;
+ remaining -= from_size;
+ return_value = -1; /* failure */
+ } else {
+ /* E2BIG no output buffer,
+ * Increase an output buffer. */
+ as->length = outp - as->s;
+ bs = as->buffer_length + remaining * 2;
+ if (NULL == archive_string_ensure(as, bs))
+ return (-1);
+ outp = as->s + as->length;
+ avail = as->buffer_length - as->length - to_size;
+ }
+ }
+ as->length = outp - as->s;
+ as->s[as->length] = 0;
+ if (to_size == 2)
+ as->s[as->length+1] = 0;
+ return (return_value);
+}
+
+#endif /* HAVE_ICONV */
+
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+
+/*
+ * Translate a string from a some CodePage to an another CodePage by
+ * Windows APIs, and copy the result. Return -1 if conversion failes.
+ */
+static int
+strncat_in_codepage(struct archive_string *as,
+ const void *_p, size_t length, struct archive_string_conv *sc)
+{
+ const char *s = (const char *)_p;
+ struct archive_wstring aws;
+ size_t l;
+ int r, saved_flag;
+
+ archive_string_init(&aws);
+ saved_flag = sc->flag;
+ sc->flag &= ~(SCONV_NORMALIZATION_D | SCONV_NORMALIZATION_C);
+ r = archive_wstring_append_from_mbs_in_codepage(&aws, s, length, sc);
+ sc->flag = saved_flag;
+ if (r != 0) {
+ archive_wstring_free(&aws);
+ if (errno != ENOMEM)
+ archive_string_append(as, s, length);
+ return (-1);
+ }
+
+ l = as->length;
+ r = archive_string_append_from_wcs_in_codepage(
+ as, aws.s, aws.length, sc);
+ if (r != 0 && errno != ENOMEM && l == as->length)
+ archive_string_append(as, s, length);
+ archive_wstring_free(&aws);
+ return (r);
+}
+
+/*
+ * Test whether MBS ==> WCS is okay.
+ */
+static int
+invalid_mbs(const void *_p, size_t n, struct archive_string_conv *sc)
+{
+ const char *p = (const char *)_p;
+ unsigned codepage;
+ DWORD mbflag = MB_ERR_INVALID_CHARS;
+
+ if (sc->flag & SCONV_FROM_CHARSET)
+ codepage = sc->to_cp;
+ else
+ codepage = sc->from_cp;
+
+ if (codepage == CP_C_LOCALE)
+ return (0);
+ if (codepage != CP_UTF8)
+ mbflag |= MB_PRECOMPOSED;
+
+ if (MultiByteToWideChar(codepage, mbflag, p, n, NULL, 0) == 0)
+ return (-1); /* Invalid */
+ return (0); /* Okay */
+}
+
+#else
+
+/*
+ * Test whether MBS ==> WCS is okay.
+ */
+static int
+invalid_mbs(const void *_p, size_t n, struct archive_string_conv *sc)
+{
+ const char *p = (const char *)_p;
+ size_t r;
+
+#if HAVE_MBRTOWC
+ mbstate_t shift_state;
+
+ memset(&shift_state, 0, sizeof(shift_state));
+#else
+ /* Clear the shift state before starting. */
+ mbtowc(NULL, NULL, 0);
+#endif
+ while (n) {
+ wchar_t wc;
+
+#if HAVE_MBRTOWC
+ r = mbrtowc(&wc, p, n, &shift_state);
+#else
+ r = mbtowc(&wc, p, n);
+#endif
+ if (r == (size_t)-1 || r == (size_t)-2)
+ return (-1);/* Invalid. */
+ if (r == 0)
+ break;
+ p += r;
+ n -= r;
+ }
+ (void)sc; /* UNUSED */
+ return (0); /* All Okey. */
+}
+
+#endif /* defined(_WIN32) && !defined(__CYGWIN__) */
+
+/*
+ * Basically returns -1 because we cannot make a conversion of charset
+ * without iconv but in some cases this would return 0.
+ * Returns 0 if all copied characters are ASCII.
+ * Returns 0 if both from-locale and to-locale are the same and those
+ * can be WCS with no error.
+ */
+static int
+best_effort_strncat_in_locale(struct archive_string *as, const void *_p,
+ size_t length, struct archive_string_conv *sc)
+{
+ size_t remaining;
+ char *outp;
+ const char *inp;
+ size_t avail;
+ int return_value = 0; /* success */
+
+ /*
+ * If both from-locale and to-locale is the same, this makes a copy.
+ * And then this checks all copied MBS can be WCS if so returns 0.
+ */
+ if (sc->same) {
+ if (archive_string_append(as, _p, length) == NULL)
+ return (-1);/* No memory */
+ return (invalid_mbs(_p, length, sc));
+ }
+
+ /*
+ * If a character is ASCII, this just copies it. If not, this
+ * assigns '?' charater instead but in UTF-8 locale this assigns
+ * 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;
+ inp = (const char *)_p;
+ outp = as->s + as->length;
+ avail = as->buffer_length - as->length -1;
+ while (*inp && remaining > 0) {
+ if (*inp < 0 && (sc->flag & SCONV_TO_UTF8)) {
+ if (avail < UTF8_R_CHAR_SIZE) {
+ as->length = outp - as->s;
+ if (NULL == archive_string_ensure(as,
+ as->buffer_length + remaining +
+ UTF8_R_CHAR_SIZE))
+ return (-1);
+ outp = as->s + as->length;
+ avail = as->buffer_length - as->length -1;
+ }
+ /*
+ * When coping a string in UTF-8, unknown character
+ * should be U+FFFD (replacement character).
+ */
+ UTF8_SET_R_CHAR(outp);
+ outp += UTF8_R_CHAR_SIZE;
+ avail -= UTF8_R_CHAR_SIZE;
+ inp++;
+ remaining--;
+ return_value = -1;
+ } else if (*inp < 0) {
+ *outp++ = '?';
+ inp++;
+ remaining--;
+ return_value = -1;
+ } else {
+ *outp++ = *inp++;
+ remaining--;
+ }
+ }
+ as->length = outp - as->s;
+ as->s[as->length] = '\0';
+ return (return_value);
+}
+
+
+/*
+ * Unicode conversion functions.
+ * - UTF-8 <===> UTF-8 in removing surrogate pairs.
+ * - UTF-8 NFD ===> UTF-8 NFC in removing surrogate pairs.
+ * - UTF-8 made by libarchive 2.x ===> UTF-8.
+ * - UTF-16BE <===> UTF-8.
+ *
+ */
+
+/*
+ * Utility to convert a single UTF-8 sequence.
+ *
+ * Usually return used bytes, return used byte in negative value when
+ * a unicode character is replaced with U+FFFD.
+ * See also http://unicode.org/review/pr-121.html Public Review Issue #121
+ * Recommended Practice for Replacement Characters.
+ */
+static int
+_utf8_to_unicode(uint32_t *pwc, const char *s, size_t n)
+{
+ static const char utf8_count[256] = {
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 00 - 0F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 10 - 1F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 20 - 2F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 30 - 3F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40 - 4F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 50 - 5F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 60 - 6F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 70 - 7F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 80 - 8F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 90 - 9F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* A0 - AF */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* B0 - BF */
+ 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,/* C0 - CF */
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,/* D0 - DF */
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,/* E0 - EF */
+ 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* F0 - FF */
+ };
+ int ch, i;
+ int cnt;
+ uint32_t wc;
+
+ /* Sanity check. */
+ if (n == 0)
+ return (0);
+ /*
+ * Decode 1-4 bytes depending on the value of the first byte.
+ */
+ ch = (unsigned char)*s;
+ if (ch == 0)
+ return (0); /* Standard: return 0 for end-of-string. */
+ cnt = utf8_count[ch];
+
+ /* Invalide sequence or there are not plenty bytes. */
+ if ((int)n < cnt) {
+ cnt = n;
+ for (i = 1; i < cnt; i++) {
+ if ((s[i] & 0xc0) != 0x80) {
+ cnt = i;
+ break;
+ }
+ }
+ goto invalid_sequence;
+ }
+
+ /* Make a Unicode code point from a single UTF-8 sequence. */
+ switch (cnt) {
+ case 1: /* 1 byte sequence. */
+ *pwc = ch & 0x7f;
+ return (cnt);
+ case 2: /* 2 bytes sequence. */
+ if ((s[1] & 0xc0) != 0x80) {
+ cnt = 1;
+ goto invalid_sequence;
+ }
+ *pwc = ((ch & 0x1f) << 6) | (s[1] & 0x3f);
+ return (cnt);
+ case 3: /* 3 bytes sequence. */
+ if ((s[1] & 0xc0) != 0x80) {
+ cnt = 1;
+ goto invalid_sequence;
+ }
+ if ((s[2] & 0xc0) != 0x80) {
+ cnt = 2;
+ goto invalid_sequence;
+ }
+ wc = ((ch & 0x0f) << 12)
+ | ((s[1] & 0x3f) << 6)
+ | (s[2] & 0x3f);
+ if (wc < 0x800)
+ goto invalid_sequence;/* Overlong sequence. */
+ break;
+ case 4: /* 4 bytes sequence. */
+ if ((s[1] & 0xc0) != 0x80) {
+ cnt = 1;
+ goto invalid_sequence;
+ }
+ if ((s[2] & 0xc0) != 0x80) {
+ cnt = 2;
+ goto invalid_sequence;
+ }
+ if ((s[3] & 0xc0) != 0x80) {
+ cnt = 3;
+ goto invalid_sequence;
+ }
+ wc = ((ch & 0x07) << 18)
+ | ((s[1] & 0x3f) << 12)
+ | ((s[2] & 0x3f) << 6)
+ | (s[3] & 0x3f);
+ if (wc < 0x10000)
+ goto invalid_sequence;/* Overlong sequence. */
+ break;
+ default: /* Others are all invalid sequence. */
+ if (ch == 0xc0 || ch == 0xc1)
+ cnt = 2;
+ else if (ch >= 0xf5 && ch <= 0xf7)
+ cnt = 4;
+ else if (ch >= 0xf8 && ch <= 0xfb)
+ cnt = 5;
+ else if (ch == 0xfc || ch == 0xfd)
+ cnt = 6;
+ else
+ cnt = 1;
+ if ((int)n < cnt)
+ cnt = n;
+ for (i = 1; i < cnt; i++) {
+ if ((s[i] & 0xc0) != 0x80) {
+ cnt = i;
+ break;
+ }
+ }
+ goto invalid_sequence;
+ }
+
+ /* The code point larger than 0x10FFFF is not leagal
+ * Unicode values. */
+ if (wc > UNICODE_MAX)
+ goto invalid_sequence;
+ /* Correctly gets a Unicode, returns used bytes. */
+ *pwc = wc;
+ return (cnt);
+invalid_sequence:
+ *pwc = UNICODE_R_CHAR;/* set the Replacement Character instead. */
+ return (cnt * -1);
+}
+
+static int
+utf8_to_unicode(uint32_t *pwc, const char *s, size_t n)
+{
+ int cnt;
+
+ cnt = _utf8_to_unicode(pwc, s, n);
+ /* Any of Surrogate pair is not leagal Unicode values. */
+ if (cnt == 3 && IS_SURROGATE_PAIR_LA(*pwc))
+ return (-3);
+ return (cnt);
+}
+
+static inline uint32_t
+combine_surrogate_pair(uint32_t uc, uint32_t uc2)
+{
+ uc -= 0xD800;
+ uc *= 0x400;
+ uc += uc2 - 0xDC00;
+ uc += 0x10000;
+ return (uc);
+}
+
+/*
+ * Convert a single UTF-8/CESU-8 sequence to a Unicode code point in
+ * removing surrogate pairs.
+ *
+ * CESU-8: The Compatibility Encoding Scheme for UTF-16.
+ *
+ * Usually return used bytes, return used byte in negative value when
+ * a unicode character is replaced with U+FFFD.
+ */
+static int
+cesu8_to_unicode(uint32_t *pwc, const char *s, size_t n)
+{
+ uint32_t wc, wc2;
+ int cnt;
+
+ cnt = _utf8_to_unicode(&wc, s, n);
+ if (cnt == 3 && IS_HIGH_SURROGATE_LA(wc)) {
+ if (n - 3 < 3) {
+ /* Invalid byte sequence. */
+ goto invalid_sequence;
+ }
+ cnt = _utf8_to_unicode(&wc2, s+3, n-3);
+ if (cnt != 3 || !IS_LOW_SURROGATE_LA(wc2)) {
+ /* Invalid byte sequence. */
+ goto invalid_sequence;
+ }
+ wc = combine_surrogate_pair(wc, wc2);
+ cnt = 6;
+ } else if (cnt == 3 && IS_LOW_SURROGATE_LA(wc)) {
+ /* Invalid byte sequence. */
+ goto invalid_sequence;
+ }
+ *pwc = wc;
+ return (cnt);
+invalid_sequence:
+ *pwc = UNICODE_R_CHAR;/* set the Replacement Character instead. */
+ if (cnt > 0)
+ cnt *= -1;
+ return (cnt);
+}
+
+/*
+ * Convert a Unicode code point to a single UTF-8 sequence.
+ *
+ * NOTE:This function does not check if the Unicode is leagal or not.
+ * Please you definitely check it before calling this.
+ */
+static size_t
+unicode_to_utf8(char *p, size_t remaining, uint32_t uc)
+{
+ char *_p = p;
+
+ /* Translate code point to UTF8 */
+ if (uc <= 0x7f) {
+ if (remaining == 0)
+ return (0);
+ *p++ = (char)uc;
+ } else if (uc <= 0x7ff) {
+ if (remaining < 2)
+ return (0);
+ *p++ = 0xc0 | ((uc >> 6) & 0x1f);
+ *p++ = 0x80 | (uc & 0x3f);
+ } else if (uc <= 0xffff) {
+ if (remaining < 3)
+ return (0);
+ *p++ = 0xe0 | ((uc >> 12) & 0x0f);
+ *p++ = 0x80 | ((uc >> 6) & 0x3f);
+ *p++ = 0x80 | (uc & 0x3f);
+ } else if (uc <= UNICODE_MAX) {
+ 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);
+}
+
+static int
+utf16be_to_unicode(uint32_t *pwc, const char *s, size_t n)
+{
+ return (utf16_to_unicode(pwc, s, n, 1));
+}
+
+static int
+utf16le_to_unicode(uint32_t *pwc, const char *s, size_t n)
+{
+ return (utf16_to_unicode(pwc, s, n, 0));
+}
+
+static int
+utf16_to_unicode(uint32_t *pwc, const char *s, size_t n, int be)
+{
+ const char *utf16 = s;
+ unsigned uc;
+
+ if (n == 0)
+ return (0);
+ if (n == 1) {
+ /* set the Replacement Character instead. */
+ *pwc = UNICODE_R_CHAR;
+ return (-1);
+ }
+
+ if (be)
+ uc = archive_be16dec(utf16);
+ else
+ uc = archive_le16dec(utf16);
+ utf16 += 2;
+
+ /* If this is a surrogate pair, assemble the full code point.*/
+ if (IS_HIGH_SURROGATE_LA(uc)) {
+ unsigned uc2;
+
+ if (n >= 4) {
+ if (be)
+ uc2 = archive_be16dec(utf16);
+ else
+ uc2 = archive_le16dec(utf16);
+ } else
+ uc2 = 0;
+ if (IS_LOW_SURROGATE_LA(uc2)) {
+ uc = combine_surrogate_pair(uc, uc2);
+ utf16 += 2;
+ } else {
+ /* Undescribed code point should be U+FFFD
+ * (replacement character). */
+ *pwc = UNICODE_R_CHAR;
+ return (-2);
+ }
+ }
+
+ /*
+ * Surrogate pair values(0xd800 through 0xdfff) are only
+ * used by UTF-16, so, after above culculation, the code
+ * must not be surrogate values, and Unicode has no codes
+ * larger than 0x10ffff. Thus, those are not leagal Unicode
+ * values.
+ */
+ if (IS_SURROGATE_PAIR_LA(uc) || uc > UNICODE_MAX) {
+ /* Undescribed code point should be U+FFFD
+ * (replacement character). */
+ *pwc = UNICODE_R_CHAR;
+ return (((int)(utf16 - s)) * -1);
+ }
+ *pwc = uc;
+ return ((int)(utf16 - s));
+}
+
+static size_t
+unicode_to_utf16be(char *p, size_t remaining, uint32_t uc)
+{
+ char *utf16 = p;
+
+ if (uc > 0xffff) {
+ /* We have a code point that won't fit into a
+ * wchar_t; convert it to a surrogate pair. */
+ if (remaining < 4)
+ return (0);
+ uc -= 0x10000;
+ archive_be16enc(utf16, ((uc >> 10) & 0x3ff) + 0xD800);
+ archive_be16enc(utf16+2, (uc & 0x3ff) + 0xDC00);
+ return (4);
+ } else {
+ if (remaining < 2)
+ return (0);
+ archive_be16enc(utf16, uc);
+ return (2);
+ }
+}
+
+static size_t
+unicode_to_utf16le(char *p, size_t remaining, uint32_t uc)
+{
+ char *utf16 = p;
+
+ if (uc > 0xffff) {
+ /* We have a code point that won't fit into a
+ * wchar_t; convert it to a surrogate pair. */
+ if (remaining < 4)
+ return (0);
+ uc -= 0x10000;
+ archive_le16enc(utf16, ((uc >> 10) & 0x3ff) + 0xD800);
+ archive_le16enc(utf16+2, (uc & 0x3ff) + 0xDC00);
+ return (4);
+ } else {
+ if (remaining < 2)
+ return (0);
+ archive_le16enc(utf16, uc);
+ return (2);
+ }
+}
+
+/*
+ * Copy UTF-8 string in checking surrogate pair.
+ * If any surrogate pair are found, it would be canonicalized.
+ */
+static int
+strncat_from_utf8_to_utf8(struct archive_string *as, const void *_p, size_t len,
+ struct archive_string_conv *sc)
+{
+ const char *s;
+ char *p, *endp;
+ int n, ret = 0;
+
+ (void)sc; /* UNUSED */
+
+ if (archive_string_ensure(as, as->length + len + 1) == NULL)
+ return (-1);
+
+ s = (const char *)_p;
+ p = as->s + as->length;
+ endp = as->s + as->buffer_length -1;
+ do {
+ uint32_t uc;
+ const char *ss = s;
+ size_t w;
+
+ /*
+ * Forward byte sequence until a conversion of that is needed.
+ */
+ while ((n = utf8_to_unicode(&uc, s, len)) > 0) {
+ s += n;
+ len -= n;
+ }
+ if (ss < s) {
+ if (p + (s - ss) > endp) {
+ as->length = p - as->s;
+ if (archive_string_ensure(as,
+ as->buffer_length + len + 1) == NULL)
+ return (-1);
+ p = as->s + as->length;
+ endp = as->s + as->buffer_length -1;
+ }
+
+ memcpy(p, ss, s - ss);
+ p += s - ss;
+ }
+
+ /*
+ * If n is negative, current byte sequence needs a replacement.
+ */
+ if (n < 0) {
+ if (n == -3 && IS_SURROGATE_PAIR_LA(uc)) {
+ /* Current byte sequence may be CESU-8. */
+ n = cesu8_to_unicode(&uc, s, len);
+ }
+ if (n < 0) {
+ ret = -1;
+ n *= -1;/* Use a replaced unicode character. */
+ }
+
+ /* Rebuild UTF-8 byte sequence. */
+ while ((w = unicode_to_utf8(p, endp - p, uc)) == 0) {
+ as->length = p - as->s;
+ if (archive_string_ensure(as,
+ as->buffer_length + len + 1) == NULL)
+ return (-1);
+ p = as->s + as->length;
+ endp = as->s + as->buffer_length -1;
+ }
+ p += w;
+ s += n;
+ len -= n;
+ }
+ } while (n > 0);
+ as->length = p - as->s;
+ as->s[as->length] = '\0';
+ return (ret);
+}
+
+static int
+archive_string_append_unicode(struct archive_string *as, const void *_p,
+ size_t len, struct archive_string_conv *sc)
+{
+ const char *s;
+ char *p, *endp;
+ uint32_t uc;
+ size_t w;
+ int n, ret = 0, ts, tm;
+ int (*parse)(uint32_t *, const char *, size_t);
+ size_t (*unparse)(char *, size_t, uint32_t);
+
+ if (sc->flag & SCONV_TO_UTF16BE) {
+ unparse = unicode_to_utf16be;
+ ts = 2;
+ } else if (sc->flag & SCONV_TO_UTF16LE) {
+ unparse = unicode_to_utf16le;
+ ts = 2;
+ } else if (sc->flag & SCONV_TO_UTF8) {
+ unparse = unicode_to_utf8;
+ ts = 1;
+ } else {
+ /*
+ * This case is going to be converted to another
+ * character-set through iconv.
+ */
+ if (sc->flag & SCONV_FROM_UTF16BE) {
+ unparse = unicode_to_utf16be;
+ ts = 2;
+ } else if (sc->flag & SCONV_FROM_UTF16LE) {
+ unparse = unicode_to_utf16le;
+ ts = 2;
+ } else {
+ unparse = unicode_to_utf8;
+ ts = 1;
+ }
+ }
+
+ if (sc->flag & SCONV_FROM_UTF16BE) {
+ parse = utf16be_to_unicode;
+ tm = 1;
+ } else if (sc->flag & SCONV_FROM_UTF16LE) {
+ parse = utf16le_to_unicode;
+ tm = 1;
+ } else {
+ parse = cesu8_to_unicode;
+ tm = ts;
+ }
+
+ if (archive_string_ensure(as, as->length + len * tm + ts) == NULL)
+ return (-1);
+
+ s = (const char *)_p;
+ p = as->s + as->length;
+ endp = as->s + as->buffer_length - ts;
+ while ((n = parse(&uc, s, len)) != 0) {
+ if (n < 0) {
+ /* Use a replaced unicode character. */
+ n *= -1;
+ ret = -1;
+ }
+ s += n;
+ len -= n;
+ while ((w = unparse(p, endp - p, uc)) == 0) {
+ /* There is not enough output buffer so
+ * we have to expand it. */
+ as->length = p - as->s;
+ if (archive_string_ensure(as,
+ as->buffer_length + len * tm + ts) == NULL)
+ return (-1);
+ p = as->s + as->length;
+ endp = as->s + as->buffer_length - ts;
+ }
+ p += w;
+ }
+ as->length = p - as->s;
+ as->s[as->length] = '\0';
+ if (ts == 2)
+ as->s[as->length+1] = '\0';
+ return (ret);
+}
+
+/*
+ * Following Constants for Hangul compositions this information comes from
+ * Unicode Standard Annex #15 http://unicode.org/reports/tr15/
+ */
+#define HC_SBASE 0xAC00
+#define HC_LBASE 0x1100
+#define HC_VBASE 0x1161
+#define HC_TBASE 0x11A7
+#define HC_LCOUNT 19
+#define HC_VCOUNT 21
+#define HC_TCOUNT 28
+#define HC_NCOUNT (HC_VCOUNT * HC_TCOUNT)
+#define HC_SCOUNT (HC_LCOUNT * HC_NCOUNT)
+
+static uint32_t
+get_nfc(uint32_t uc, uint32_t uc2)
+{
+ int t, b;
+
+ t = 0;
+ b = sizeof(u_composition_table)/sizeof(u_composition_table[0]) -1;
+ while (b >= t) {
+ int m = (t + b) / 2;
+ if (u_composition_table[m].cp1 < uc)
+ t = m + 1;
+ else if (u_composition_table[m].cp1 > uc)
+ b = m - 1;
+ else if (u_composition_table[m].cp2 < uc2)
+ t = m + 1;
+ else if (u_composition_table[m].cp2 > uc2)
+ b = m - 1;
+ else
+ return (u_composition_table[m].nfc);
+ }
+ return (0);
+}
+
+#define FDC_MAX 10 /* The maximum number of Following Decomposable
+ * Characters. */
+
+/*
+ * Update first code point.
+ */
+#define UPDATE_UC(new_uc) do { \
+ uc = new_uc; \
+ ucptr = NULL; \
+} while (0)
+
+/*
+ * Replace first code point with second code point.
+ */
+#define REPLACE_UC_WITH_UC2() do { \
+ uc = uc2; \
+ ucptr = uc2ptr; \
+ n = n2; \
+} while (0)
+
+#define EXPAND_BUFFER() do { \
+ as->length = p - as->s; \
+ if (archive_string_ensure(as, \
+ as->buffer_length + len * tm + ts) == NULL)\
+ return (-1); \
+ p = as->s + as->length; \
+ endp = as->s + as->buffer_length - ts; \
+} while (0)
+
+#define UNPARSE(p, endp, uc) do { \
+ while ((w = unparse(p, (endp) - (p), uc)) == 0) {\
+ EXPAND_BUFFER(); \
+ } \
+ p += w; \
+} while (0)
+
+/*
+ * Write first code point.
+ * If the code point has not be changed from its original code,
+ * this just copies it from its original buffer pointer.
+ * If not, this converts it to UTF-8 byte sequence and copies it.
+ */
+#define WRITE_UC() do { \
+ if (ucptr) { \
+ if (p + n > endp) \
+ EXPAND_BUFFER(); \
+ switch (n) { \
+ case 4: \
+ *p++ = *ucptr++; \
+ /* FALL THROUGH */ \
+ case 3: \
+ *p++ = *ucptr++; \
+ /* FALL THROUGH */ \
+ case 2: \
+ *p++ = *ucptr++; \
+ /* FALL THROUGH */ \
+ case 1: \
+ *p++ = *ucptr; \
+ break; \
+ } \
+ ucptr = NULL; \
+ } else { \
+ UNPARSE(p, endp, uc); \
+ } \
+} while (0)
+
+/*
+ * Collect following decomposable code points.
+ */
+#define COLLECT_CPS(start) do { \
+ int _i; \
+ for (_i = start; _i < FDC_MAX ; _i++) { \
+ nx = parse(&ucx[_i], s, len); \
+ if (nx <= 0) \
+ break; \
+ cx = CCC(ucx[_i]); \
+ if (cl >= cx && cl != 228 && cx != 228)\
+ break; \
+ s += nx; \
+ len -= nx; \
+ cl = cx; \
+ ccx[_i] = cx; \
+ } \
+ if (_i >= FDC_MAX) { \
+ ret = -1; \
+ ucx_size = FDC_MAX; \
+ } else \
+ ucx_size = _i; \
+} while (0)
+
+/*
+ * Normalize UTF-8/UTF-16BE characters to Form C and copy the result.
+ *
+ * TODO: Convert composition exclusions,which are never converted
+ * from NFC,NFD,NFKC and NFKD, to Form C.
+ */
+static int
+archive_string_normalize_C(struct archive_string *as, const void *_p,
+ size_t len, struct archive_string_conv *sc)
+{
+ const char *s = (const char *)_p;
+ char *p, *endp;
+ uint32_t uc, uc2;
+ size_t w;
+ int always_replace, n, n2, ret = 0, spair, ts, tm;
+ int (*parse)(uint32_t *, const char *, size_t);
+ size_t (*unparse)(char *, size_t, uint32_t);
+
+ always_replace = 1;
+ ts = 1;/* text size. */
+ if (sc->flag & SCONV_TO_UTF16BE) {
+ unparse = unicode_to_utf16be;
+ ts = 2;
+ if (sc->flag & SCONV_FROM_UTF16BE)
+ always_replace = 0;
+ } else if (sc->flag & SCONV_TO_UTF16LE) {
+ unparse = unicode_to_utf16le;
+ ts = 2;
+ if (sc->flag & SCONV_FROM_UTF16LE)
+ always_replace = 0;
+ } else if (sc->flag & SCONV_TO_UTF8) {
+ unparse = unicode_to_utf8;
+ if (sc->flag & SCONV_FROM_UTF8)
+ always_replace = 0;
+ } else {
+ /*
+ * This case is going to be converted to another
+ * character-set through iconv.
+ */
+ always_replace = 0;
+ if (sc->flag & SCONV_FROM_UTF16BE) {
+ unparse = unicode_to_utf16be;
+ ts = 2;
+ } else if (sc->flag & SCONV_FROM_UTF16LE) {
+ unparse = unicode_to_utf16le;
+ ts = 2;
+ } else {
+ unparse = unicode_to_utf8;
+ }
+ }
+
+ if (sc->flag & SCONV_FROM_UTF16BE) {
+ parse = utf16be_to_unicode;
+ tm = 1;
+ spair = 4;/* surrogate pair size in UTF-16. */
+ } else if (sc->flag & SCONV_FROM_UTF16LE) {
+ parse = utf16le_to_unicode;
+ tm = 1;
+ spair = 4;/* surrogate pair size in UTF-16. */
+ } else {
+ parse = cesu8_to_unicode;
+ tm = ts;
+ spair = 6;/* surrogate pair size in UTF-8. */
+ }
+
+ if (archive_string_ensure(as, as->length + len * tm + ts) == NULL)
+ return (-1);
+
+ p = as->s + as->length;
+ endp = as->s + as->buffer_length - ts;
+ while ((n = parse(&uc, s, len)) != 0) {
+ const char *ucptr, *uc2ptr;
+
+ if (n < 0) {
+ /* Use a replaced unicode character. */
+ UNPARSE(p, endp, uc);
+ s += n*-1;
+ len -= n*-1;
+ ret = -1;
+ continue;
+ } else if (n == spair || always_replace)
+ /* uc is converted from a surrogate pair.
+ * this should be treated as a changed code. */
+ ucptr = NULL;
+ else
+ ucptr = s;
+ s += n;
+ len -= n;
+
+ /* Read second code point. */
+ while ((n2 = parse(&uc2, s, len)) > 0) {
+ uint32_t ucx[FDC_MAX];
+ int ccx[FDC_MAX];
+ int cl, cx, i, nx, ucx_size;
+ int LIndex,SIndex;
+ uint32_t nfc;
+
+ if (n2 == spair || always_replace)
+ /* uc2 is converted from a surrogate pair.
+ * this should be treated as a changed code. */
+ uc2ptr = NULL;
+ else
+ uc2ptr = s;
+ s += n2;
+ len -= n2;
+
+ /*
+ * If current second code point is out of decomposable
+ * code points, finding compositions is unneeded.
+ */
+ if (!IS_DECOMPOSABLE_BLOCK(uc2)) {
+ WRITE_UC();
+ REPLACE_UC_WITH_UC2();
+ continue;
+ }
+
+ /*
+ * Try to combine current code points.
+ */
+ /*
+ * We have to combine Hangul characters according to
+ * http://uniicode.org/reports/tr15/#Hangul
+ */
+ if (0 <= (LIndex = uc - HC_LBASE) &&
+ LIndex < HC_LCOUNT) {
+ /*
+ * Hangul Composition.
+ * 1. Two current code points are L and V.
+ */
+ int VIndex = uc2 - HC_VBASE;
+ if (0 <= VIndex && VIndex < HC_VCOUNT) {
+ /* Make syllable of form LV. */
+ UPDATE_UC(HC_SBASE +
+ (LIndex * HC_VCOUNT + VIndex) *
+ HC_TCOUNT);
+ } else {
+ WRITE_UC();
+ REPLACE_UC_WITH_UC2();
+ }
+ continue;
+ } else if (0 <= (SIndex = uc - HC_SBASE) &&
+ SIndex < HC_SCOUNT && (SIndex % HC_TCOUNT) == 0) {
+ /*
+ * Hangul Composition.
+ * 2. Two current code points are LV and T.
+ */
+ int TIndex = uc2 - HC_TBASE;
+ if (0 < TIndex && TIndex < HC_TCOUNT) {
+ /* Make syllable of form LVT. */
+ UPDATE_UC(uc + TIndex);
+ } else {
+ WRITE_UC();
+ REPLACE_UC_WITH_UC2();
+ }
+ continue;
+ } else if ((nfc = get_nfc(uc, uc2)) != 0) {
+ /* A composition to current code points
+ * is found. */
+ UPDATE_UC(nfc);
+ continue;
+ } else if ((cl = CCC(uc2)) == 0) {
+ /* Clearly 'uc2' the second code point is not
+ * a decomposable code. */
+ WRITE_UC();
+ REPLACE_UC_WITH_UC2();
+ continue;
+ }
+
+ /*
+ * Collect following decomposable code points.
+ */
+ cx = 0;
+ ucx[0] = uc2;
+ ccx[0] = cl;
+ COLLECT_CPS(1);
+
+ /*
+ * Find a composed code in the collected code points.
+ */
+ i = 1;
+ while (i < ucx_size) {
+ int j;
+
+ if ((nfc = get_nfc(uc, ucx[i])) == 0) {
+ i++;
+ continue;
+ }
+
+ /*
+ * nfc is composed of uc and ucx[i].
+ */
+ UPDATE_UC(nfc);
+
+ /*
+ * Remove ucx[i] by shifting
+ * follwoing code points.
+ */
+ for (j = i; j+1 < ucx_size; j++) {
+ ucx[j] = ucx[j+1];
+ ccx[j] = ccx[j+1];
+ }
+ ucx_size --;
+
+ /*
+ * Collect following code points blocked
+ * by ucx[i] the removed code point.
+ */
+ if (ucx_size > 0 && i == ucx_size &&
+ nx > 0 && cx == cl) {
+ cl = ccx[ucx_size-1];
+ COLLECT_CPS(ucx_size);
+ }
+ /*
+ * Restart finding a composed code with
+ * the updated uc from the top of the
+ * collected code points.
+ */
+ i = 0;
+ }
+
+ /*
+ * Apparently the current code points are not
+ * decomposed characters or already composed.
+ */
+ WRITE_UC();
+ for (i = 0; i < ucx_size; i++)
+ UNPARSE(p, endp, ucx[i]);
+
+ /*
+ * Flush out remaining canonical combining characters.
+ */
+ if (nx > 0 && cx == cl && len > 0) {
+ while ((nx = parse(&ucx[0], s, len))
+ > 0) {
+ cx = CCC(ucx[0]);
+ if (cl > cx)
+ break;
+ s += nx;
+ len -= nx;
+ cl = cx;
+ UNPARSE(p, endp, ucx[0]);
+ }
+ }
+ break;
+ }
+ if (n2 < 0) {
+ WRITE_UC();
+ /* Use a replaced unicode character. */
+ UNPARSE(p, endp, uc2);
+ s += n2*-1;
+ len -= n2*-1;
+ ret = -1;
+ continue;
+ } else if (n2 == 0) {
+ WRITE_UC();
+ break;
+ }
+ }
+ as->length = p - as->s;
+ as->s[as->length] = '\0';
+ if (ts == 2)
+ as->s[as->length+1] = '\0';
+ return (ret);
+}
+
+#if defined(__APPLE__)
+
+/*
+ * Normalize UTF-8 characters to Form D and copy the result.
+ */
+static int
+archive_string_normalize_D(struct archive_string *as, const void *_p,
+ size_t len, struct archive_string_conv *sc)
+{
+ const UniChar *inp;
+ char *outp;
+ size_t newsize;
+ ByteCount inCount, outCount;
+ ByteCount inAvail, outAvail;
+ OSStatus err;
+ int ret, saved_flag;
+
+ /*
+ * Convert the current string to UTF-16LE for normalization.
+ * The character-set of the current string must be UTF-16BE or
+ * UTF-8.
+ */
+ archive_string_empty(&(sc->utf16nfc));
+ saved_flag = sc->flag;/* save a flag. */
+ sc->flag &= ~(SCONV_TO_UTF16BE | SCONV_TO_UTF8);
+ sc->flag |= SCONV_TO_UTF16LE;
+ ret = archive_string_append_unicode(&(sc->utf16nfc), _p, len, sc);
+ sc->flag = saved_flag;/* restore the saved flag */
+ if (archive_strlen(&(sc->utf16nfc)) == 0) {
+ if (archive_string_ensure(as, as->length + 1) == NULL)
+ return (-1);
+ return (ret);
+ }
+
+ /*
+ * Normalize an NFC string to be an NFD(HFS Plus version).
+ */
+ newsize = sc->utf16nfc.length + 2;
+ if (archive_string_ensure(&(sc->utf16nfd), newsize) == NULL)
+ return (-1);
+
+ inp = (UniChar *)sc->utf16nfc.s;
+ inAvail = archive_strlen(&(sc->utf16nfc));
+ sc->utf16nfd.length = 0;
+ outp = sc->utf16nfd.s;
+ outAvail = sc->utf16nfd.buffer_length -2;
+
+ do {
+ /* Reinitialize all state information. */
+ if (ResetUnicodeToTextInfo(sc->uniInfo) != noErr)
+ goto return_no_changed_data;
+
+ inCount = outCount = 0;
+ err = ConvertFromUnicodeToText(sc->uniInfo,
+ inAvail, inp,
+ kUnicodeDefaultDirectionMask, 0, NULL, NULL, NULL,
+ outAvail, &inCount, &outCount, outp);
+
+ if (err == noErr) {
+ sc->utf16nfd.length = outCount;
+ sc->utf16nfd.s[sc->utf16nfd.length] = 0;
+ sc->utf16nfd.s[sc->utf16nfd.length+1] = 0;
+ } else if (err == kTECOutputBufferFullStatus) {
+ newsize = inAvail - inCount;
+ if (newsize > inAvail)
+ newsize = inAvail;
+ newsize += sc->utf16nfd.buffer_length + 2;
+ if (archive_string_ensure(&(sc->utf16nfd), newsize)
+ == NULL)
+ return (-1);
+ outp = sc->utf16nfd.s;
+ outAvail = sc->utf16nfd.buffer_length -2;
+ } else
+ goto return_no_changed_data;
+ } while (err == kTECOutputBufferFullStatus);
+
+ /*
+ * If there is a next-step conversion, we should convert
+ * a UTF-16LE(NFD) string back to the original Unicode type.
+ */
+ saved_flag = sc->flag;/* save a flag. */
+ if (!(sc->flag &
+ (SCONV_TO_UTF16BE | SCONV_TO_UTF16LE | SCONV_TO_UTF8))) {
+ /*
+ * This case is going to be converted to another
+ * character-set through iconv.
+ */
+ if (sc->flag & SCONV_FROM_UTF16BE)
+ sc->flag |= SCONV_TO_UTF16BE;
+ else if (sc->flag & SCONV_FROM_UTF16LE)
+ sc->flag |= SCONV_TO_UTF16LE;
+ else
+ sc->flag |= SCONV_TO_UTF8;
+ }
+ sc->flag &= ~(SCONV_FROM_UTF16BE | SCONV_FROM_UTF8);
+ sc->flag |= SCONV_FROM_UTF16LE;
+ if (archive_string_append_unicode(as, sc->utf16nfd.s,
+ sc->utf16nfd.length, sc) != 0)
+ ret = -1;
+ sc->flag = saved_flag;/* restore the saved flag */
+ return (ret);
+
+return_no_changed_data:
+ /*
+ * Something conversion error happend, so we return a no normalized
+ * string with an error.
+ */
+ (void)archive_string_append_unicode(as, _p, len, sc);
+ return (-1);
+}
+
+#endif /* __APPLE__ */
+
+/*
+ * libarchive 2.x made incorrect UTF-8 strings in the wrong assumuption
+ * that WCS is Unicode. it is true for servel platforms but some are false.
+ * And then people who did not use UTF-8 locale on the non Unicode WCS
+ * platform and made a tar file with libarchive(mostly bsdtar) 2.x. Those
+ * now cannot get right filename from libarchive 3.x and later since we
+ * fixed the wrong assumption and it is incompatible to older its versions.
+ * So we provide special option, "compat-2x.x", for resolving it.
+ * That option enable the string conversion of libarchive 2.x.
+ *
+ * Translates the wrong UTF-8 string made by libarchive 2.x into current
+ * locale character set and appends to the archive_string.
+ * Note: returns -1 if conversion fails.
+ */
+static int
+strncat_from_utf8_libarchive2(struct archive_string *as,
+ const void *_p, size_t len, struct archive_string_conv *sc)
+{
+ const char *s;
+ int n;
+ char *p;
+ char *end;
+ uint32_t unicode;
+#if HAVE_WCRTOMB
+ mbstate_t shift_state;
+
+ memset(&shift_state, 0, sizeof(shift_state));
+#else
+ /* Clear the shift state before starting. */
+ wctomb(NULL, L'\0');
+#endif
+ (void)sc; /* UNUSED */
+ /*
+ * Allocate buffer for MBS.
+ * We need this allocation here since it is possible that
+ * as->s is still NULL.
+ */
+ if (archive_string_ensure(as, as->length + len + 1) == NULL)
+ return (-1);
+
+ s = (const char *)_p;
+ p = as->s + as->length;
+ end = as->s + as->buffer_length - MB_CUR_MAX -1;
+ while ((n = _utf8_to_unicode(&unicode, s, len)) != 0) {
+ wchar_t wc;
+
+ if (p >= end) {
+ as->length = p - as->s;
+ /* Re-allocate buffer for MBS. */
+ if (archive_string_ensure(as,
+ as->length + len * 2 + 1) == NULL)
+ return (-1);
+ p = as->s + as->length;
+ end = as->s + as->buffer_length - MB_CUR_MAX -1;
+ }
+
+ /*
+ * As libarchie 2.x, translates the UTF-8 characters into
+ * wide-characters in the assumption that WCS is Unicode.
+ */
+ if (n < 0) {
+ n *= -1;
+ wc = L'?';
+ } else
+ wc = (wchar_t)unicode;
+
+ s += n;
+ len -= n;
+ /*
+ * Translates the wide-character into the current locale MBS.
+ */
+#if HAVE_WCRTOMB
+ n = wcrtomb(p, wc, &shift_state);
+#else
+ n = wctomb(p, wc);
+#endif
+ if (n == -1)
+ return (-1);
+ p += n;
+ }
+ as->length = p - as->s;
+ as->s[as->length] = '\0';
+ return (0);
+}
+
+
+/*
+ * Conversion functions between current locale dependent MBS and UTF-16BE.
+ * strncat_from_utf16be() : UTF-16BE --> MBS
+ * strncat_to_utf16be() : MBS --> UTF16BE
+ */
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+
+/*
+ * Convert a UTF-16BE/LE string to current locale and copy the result.
+ * Return -1 if conversion failes.
+ */
+static int
+win_strncat_from_utf16(struct archive_string *as, const void *_p, size_t bytes,
+ struct archive_string_conv *sc, int be)
+{
+ struct archive_string tmp;
+ const char *u16;
+ int ll;
+ BOOL defchar;
+ char *mbs;
+ size_t mbs_size, b;
+ int ret = 0;
+
+ bytes &= ~1;
+ if (archive_string_ensure(as, as->length + bytes +1) == NULL)
+ return (-1);
+
+ mbs = as->s + as->length;
+ mbs_size = as->buffer_length - as->length -1;
+
+ if (sc->to_cp == CP_C_LOCALE) {
+ /*
+ * "C" locale special process.
+ */
+ u16 = _p;
+ ll = 0;
+ for (b = 0; b < bytes; b += 2) {
+ uint16_t val;
+ if (be)
+ val = archive_be16dec(u16+b);
+ else
+ val = archive_le16dec(u16+b);
+ if (val > 255) {
+ *mbs++ = '?';
+ ret = -1;
+ } else
+ *mbs++ = (char)(val&0xff);
+ ll++;
+ }
+ as->length += ll;
+ as->s[as->length] = '\0';
+ return (ret);
+ }
+
+ archive_string_init(&tmp);
+ if (be) {
+ if (is_big_endian()) {
+ u16 = _p;
+ } else {
+ if (archive_string_ensure(&tmp, bytes+2) == NULL)
+ return (-1);
+ memcpy(tmp.s, _p, bytes);
+ for (b = 0; b < bytes; b += 2) {
+ uint16_t val = archive_be16dec(tmp.s+b);
+ archive_le16enc(tmp.s+b, val);
+ }
+ u16 = tmp.s;
+ }
+ } else {
+ if (!is_big_endian()) {
+ u16 = _p;
+ } else {
+ if (archive_string_ensure(&tmp, bytes+2) == NULL)
+ return (-1);
+ memcpy(tmp.s, _p, bytes);
+ for (b = 0; b < bytes; b += 2) {
+ uint16_t val = archive_le16dec(tmp.s+b);
+ archive_be16enc(tmp.s+b, val);
+ }
+ u16 = tmp.s;
+ }
+ }
+
+ do {
+ defchar = 0;
+ ll = WideCharToMultiByte(sc->to_cp, 0,
+ (LPCWSTR)u16, bytes>>1, mbs, mbs_size,
+ NULL, &defchar);
+ if (ll == 0 &&
+ GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+ /* Need more buffer for MBS. */
+ ll = WideCharToMultiByte(sc->to_cp, 0,
+ (LPCWSTR)u16, bytes, NULL, 0, NULL, NULL);
+ if (archive_string_ensure(as, ll +1) == NULL)
+ return (-1);
+ mbs = as->s + as->length;
+ mbs_size = as->buffer_length - as->length -1;
+ continue;
+ }
+ } while (0);
+ archive_string_free(&tmp);
+ as->length += ll;
+ as->s[as->length] = '\0';
+ if (ll == 0 || defchar)
+ ret = -1;
+ return (ret);
+}
+
+static int
+win_strncat_from_utf16be(struct archive_string *as, const void *_p, size_t bytes,
+ struct archive_string_conv *sc)
+{
+ return (win_strncat_from_utf16(as, _p, bytes, sc, 1));
+}
+
+static int
+win_strncat_from_utf16le(struct archive_string *as, const void *_p, size_t bytes,
+ struct archive_string_conv *sc)
+{
+ return (win_strncat_from_utf16(as, _p, bytes, sc, 0));
+}
+
+static int
+is_big_endian(void)
+{
+ uint16_t d = 1;
+
+ return (archive_be16dec(&d) == 1);
+}
+
+/*
+ * Convert a current locale string to UTF-16BE/LE and copy the result.
+ * Return -1 if conversion failes.
+ */
+static int
+win_strncat_to_utf16(struct archive_string *as16, const void *_p, size_t length,
+ struct archive_string_conv *sc, int bigendian)
+{
+ const char *s = (const char *)_p;
+ char *u16;
+ size_t count, avail;
+
+ if (archive_string_ensure(as16,
+ as16->length + (length + 1) * 2) == NULL)
+ return (-1);
+
+ u16 = as16->s + as16->length;
+ avail = as16->buffer_length - 2;
+ if (sc->from_cp == CP_C_LOCALE) {
+ /*
+ * "C" locale special process.
+ */
+ count = 0;
+ while (count < length && *s) {
+ if (bigendian)
+ archive_be16enc(u16, *s);
+ else
+ archive_le16enc(u16, *s);
+ u16 += 2;
+ s++;
+ count++;
+ }
+ as16->length += count << 1;
+ as16->s[as16->length] = 0;
+ as16->s[as16->length+1] = 0;
+ return (0);
+ }
+ do {
+ count = MultiByteToWideChar(sc->from_cp,
+ MB_PRECOMPOSED, s, length, (LPWSTR)u16, (int)avail>>1);
+ if (count == 0 &&
+ GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+ /* Need more buffer for UTF-16 string */
+ count = MultiByteToWideChar(sc->from_cp,
+ MB_PRECOMPOSED, s, length, NULL, 0);
+ if (archive_string_ensure(as16, (count +1) * 2)
+ == NULL)
+ return (-1);
+ u16 = as16->s + as16->length;
+ avail = as16->buffer_length - 2;
+ continue;
+ }
+ } while (0);
+ as16->length += count * 2;
+ as16->s[as16->length] = 0;
+ as16->s[as16->length+1] = 0;
+ if (count == 0)
+ return (-1);
+
+ if (is_big_endian()) {
+ if (!bigendian) {
+ while (count > 0) {
+ uint16_t v = archive_be16dec(u16);
+ archive_le16enc(u16, v);
+ u16 += 2;
+ count--;
+ }
+ }
+ } else {
+ if (bigendian) {
+ while (count > 0) {
+ uint16_t v = archive_le16dec(u16);
+ archive_be16enc(u16, v);
+ u16 += 2;
+ count--;
+ }
+ }
+ }
+ return (0);
+}
+
+static int
+win_strncat_to_utf16be(struct archive_string *as16, const void *_p, size_t length,
+ struct archive_string_conv *sc)
+{
+ return (win_strncat_to_utf16(as16, _p, length, sc, 1));
+}
+
+static int
+win_strncat_to_utf16le(struct archive_string *as16, const void *_p, size_t length,
+ struct archive_string_conv *sc)
+{
+ return (win_strncat_to_utf16(as16, _p, length, sc, 0));
+}
+
+#endif /* _WIN32 && !__CYGWIN__ */
+
+/*
+ * Do the best effort for conversions.
+ * We cannot handle UTF-16BE character-set without such iconv,
+ * but there is a chance if a string consists just ASCII code or
+ * a current locale is UTF-8.
+ */
+
+/*
+ * Convert a UTF-16BE string to current locale and copy the result.
+ * Return -1 if conversion failes.
+ */
+static int
+best_effort_strncat_from_utf16(struct archive_string *as, const void *_p,
+ size_t bytes, struct archive_string_conv *sc, int be)
+{
+ const char *utf16 = (const char *)_p;
+ char *mbs;
+ uint32_t uc;
+ int n, ret;
+
+ (void)sc; /* UNUSED */
+ /*
+ * Other case, we should do the best effort.
+ * If all character are ASCII(<0x7f), we can convert it.
+ * if not , we set a alternative character and return -1.
+ */
+ ret = 0;
+ if (archive_string_ensure(as, as->length + bytes +1) == NULL)
+ return (-1);
+ mbs = as->s + as->length;
+
+ while ((n = utf16_to_unicode(&uc, utf16, bytes, be)) != 0) {
+ if (n < 0) {
+ n *= -1;
+ ret = -1;
+ }
+ bytes -= n;
+ utf16 += n;
+
+ if (uc > 127) {
+ /* We cannot handle it. */
+ *mbs++ = '?';
+ ret = -1;
+ } else
+ *mbs++ = (char)uc;
+ }
+ as->length = mbs - as->s;
+ as->s[as->length] = '\0';
+ return (ret);
+}
+
+static int
+best_effort_strncat_from_utf16be(struct archive_string *as, const void *_p,
+ size_t bytes, struct archive_string_conv *sc)
+{
+ return (best_effort_strncat_from_utf16(as, _p, bytes, sc, 1));
+}
+
+static int
+best_effort_strncat_from_utf16le(struct archive_string *as, const void *_p,
+ size_t bytes, struct archive_string_conv *sc)
+{
+ return (best_effort_strncat_from_utf16(as, _p, bytes, sc, 0));
+}
+
+/*
+ * Convert a current locale string to UTF-16BE/LE and copy the result.
+ * Return -1 if conversion failes.
+ */
+static int
+best_effort_strncat_to_utf16(struct archive_string *as16, const void *_p,
+ size_t length, struct archive_string_conv *sc, int bigendian)
+{
+ const char *s = (const char *)_p;
+ char *utf16;
+ size_t remaining;
+ int ret;
+
+ (void)sc; /* UNUSED */
+ /*
+ * Other case, we should do the best effort.
+ * If all character are ASCII(<0x7f), we can convert it.
+ * if not , we set a alternative character and return -1.
+ */
+ ret = 0;
+ remaining = length;
+
+ if (archive_string_ensure(as16,
+ as16->length + (length + 1) * 2) == NULL)
+ return (-1);
+
+ utf16 = as16->s + as16->length;
+ while (remaining--) {
+ unsigned c = *s++;
+ if (c > 127) {
+ /* We cannot handle it. */
+ c = UNICODE_R_CHAR;
+ ret = -1;
+ }
+ if (bigendian)
+ archive_be16enc(utf16, c);
+ else
+ archive_le16enc(utf16, c);
+ utf16 += 2;
+ }
+ as16->length = utf16 - as16->s;
+ as16->s[as16->length] = 0;
+ as16->s[as16->length+1] = 0;
+ return (ret);
+}
+
+static int
+best_effort_strncat_to_utf16be(struct archive_string *as16, const void *_p,
+ size_t length, struct archive_string_conv *sc)
+{
+ return (best_effort_strncat_to_utf16(as16, _p, length, sc, 1));
+}
+
+static int
+best_effort_strncat_to_utf16le(struct archive_string *as16, const void *_p,
+ size_t length, struct archive_string_conv *sc)
+{
+ return (best_effort_strncat_to_utf16(as16, _p, length, sc, 0));
+}
+
+
+/*
+ * Multistring operations.
+ */
+
+void
+archive_mstring_clean(struct archive_mstring *aes)
+{
+ archive_wstring_free(&(aes->aes_wcs));
+ archive_string_free(&(aes->aes_mbs));
+ archive_string_free(&(aes->aes_utf8));
+ archive_string_free(&(aes->aes_mbs_in_locale));
+ aes->aes_set = 0;
+}
+
+void
+archive_mstring_copy(struct archive_mstring *dest, struct archive_mstring *src)
+{
+ dest->aes_set = src->aes_set;
+ archive_string_copy(&(dest->aes_mbs), &(src->aes_mbs));
+ archive_string_copy(&(dest->aes_utf8), &(src->aes_utf8));
+ archive_wstring_copy(&(dest->aes_wcs), &(src->aes_wcs));
+}
+
+int
+archive_mstring_get_utf8(struct archive *a, struct archive_mstring *aes,
+ const char **p)
+{
+ struct archive_string_conv *sc;
+ int r;
+
+ /* If we already have a UTF8 form, return that immediately. */
+ if (aes->aes_set & AES_SET_UTF8) {
+ *p = aes->aes_utf8.s;
+ return (0);
+ }
+
+ *p = NULL;
+ if (aes->aes_set & AES_SET_MBS) {
+ sc = archive_string_conversion_to_charset(a, "UTF-8", 1);
+ if (sc == NULL)
+ return (-1);/* Couldn't allocate memory for sc. */
+ r = archive_strncpy_in_locale(&(aes->aes_mbs), aes->aes_mbs.s,
+ aes->aes_mbs.length, sc);
+ if (a == NULL)
+ free_sconv_object(sc);
+ if (r == 0) {
+ aes->aes_set |= AES_SET_UTF8;
+ *p = aes->aes_utf8.s;
+ return (0);/* success. */
+ } else
+ return (-1);/* failure. */
+ }
+ return (0);/* success. */
+}
+
+int
+archive_mstring_get_mbs(struct archive *a, struct archive_mstring *aes,
+ const char **p)
+{
+ int r, ret = 0;
+
+ (void)a; /* UNUSED */
+ /* If we already have an MBS form, return that immediately. */
+ if (aes->aes_set & AES_SET_MBS) {
+ *p = aes->aes_mbs.s;
+ return (ret);
+ }
+
+ *p = NULL;
+ /* If there's a WCS form, try converting with the native locale. */
+ if (aes->aes_set & AES_SET_WCS) {
+ archive_string_empty(&(aes->aes_mbs));
+ r = archive_string_append_from_wcs(&(aes->aes_mbs),
+ aes->aes_wcs.s, aes->aes_wcs.length);
+ *p = aes->aes_mbs.s;
+ if (r == 0) {
+ aes->aes_set |= AES_SET_MBS;
+ return (ret);
+ } else
+ ret = -1;
+ }
+
+ /*
+ * Only a UTF-8 form cannot avail because its conversion already
+ * failed at archive_mstring_update_utf8().
+ */
+ return (ret);
+}
+
+int
+archive_mstring_get_wcs(struct archive *a, struct archive_mstring *aes,
+ const wchar_t **wp)
+{
+ int r, ret = 0;
+
+ (void)a;/* UNUSED */
+ /* Return WCS form if we already have it. */
+ if (aes->aes_set & AES_SET_WCS) {
+ *wp = aes->aes_wcs.s;
+ return (ret);
+ }
+
+ *wp = NULL;
+ /* Try converting MBS to WCS using native locale. */
+ if (aes->aes_set & AES_SET_MBS) {
+ archive_wstring_empty(&(aes->aes_wcs));
+ r = archive_wstring_append_from_mbs(&(aes->aes_wcs),
+ aes->aes_mbs.s, aes->aes_mbs.length);
+ if (r == 0) {
+ aes->aes_set |= AES_SET_WCS;
+ *wp = aes->aes_wcs.s;
+ } else
+ ret = -1;/* failure. */
+ }
+ return (ret);
+}
+
+int
+archive_mstring_get_mbs_l(struct archive_mstring *aes,
+ const char **p, size_t *length, struct archive_string_conv *sc)
+{
+ int r, ret = 0;
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ /*
+ * Internationalization programing on Windows must use Wide
+ * characters because Windows platform cannot make locale UTF-8.
+ */
+ if (sc != NULL && (aes->aes_set & AES_SET_WCS) != 0) {
+ archive_string_empty(&(aes->aes_mbs_in_locale));
+ r = archive_string_append_from_wcs_in_codepage(
+ &(aes->aes_mbs_in_locale), aes->aes_wcs.s,
+ aes->aes_wcs.length, sc);
+ if (r == 0) {
+ *p = aes->aes_mbs_in_locale.s;
+ if (length != NULL)
+ *length = aes->aes_mbs_in_locale.length;
+ return (0);
+ } else if (errno == ENOMEM)
+ return (-1);
+ else
+ ret = -1;
+ }
+#endif
+
+ /* If there is not an MBS form but is a WCS form, try converting
+ * with the native locale to be used for translating it to specified
+ * character-set. */
+ if ((aes->aes_set & AES_SET_MBS) == 0 &&
+ (aes->aes_set & AES_SET_WCS) != 0) {
+ archive_string_empty(&(aes->aes_mbs));
+ r = archive_string_append_from_wcs(&(aes->aes_mbs),
+ aes->aes_wcs.s, aes->aes_wcs.length);
+ if (r == 0)
+ aes->aes_set |= AES_SET_MBS;
+ else if (errno == ENOMEM)
+ return (-1);
+ else
+ ret = -1;
+ }
+ /* If we already have an MBS form, use it to be translated to
+ * specified character-set. */
+ if (aes->aes_set & AES_SET_MBS) {
+ if (sc == NULL) {
+ /* Conversion is unneeded. */
+ *p = aes->aes_mbs.s;
+ if (length != NULL)
+ *length = aes->aes_mbs.length;
+ return (0);
+ }
+ ret = archive_strncpy_in_locale(&(aes->aes_mbs_in_locale),
+ aes->aes_mbs.s, aes->aes_mbs.length, sc);
+ *p = aes->aes_mbs_in_locale.s;
+ if (length != NULL)
+ *length = aes->aes_mbs_in_locale.length;
+ } else {
+ *p = NULL;
+ if (length != NULL)
+ *length = 0;
+ }
+ return (ret);
+}
+
+int
+archive_mstring_copy_mbs(struct archive_mstring *aes, const char *mbs)
+{
+ if (mbs == NULL) {
+ aes->aes_set = 0;
+ return (0);
+ }
+ return (archive_mstring_copy_mbs_len(aes, mbs, strlen(mbs)));
+}
+
+int
+archive_mstring_copy_mbs_len(struct archive_mstring *aes, const char *mbs,
+ size_t len)
+{
+ if (mbs == NULL) {
+ aes->aes_set = 0;
+ return (0);
+ }
+ aes->aes_set = AES_SET_MBS; /* Only MBS form is set now. */
+ archive_strncpy(&(aes->aes_mbs), mbs, len);
+ archive_string_empty(&(aes->aes_utf8));
+ archive_wstring_empty(&(aes->aes_wcs));
+ return (0);
+}
+
+int
+archive_mstring_copy_wcs(struct archive_mstring *aes, const wchar_t *wcs)
+{
+ return archive_mstring_copy_wcs_len(aes, wcs, wcs == NULL ? 0 : wcslen(wcs));
+}
+
+int
+archive_mstring_copy_wcs_len(struct archive_mstring *aes, const wchar_t *wcs,
+ size_t len)
+{
+ if (wcs == NULL) {
+ aes->aes_set = 0;
+ }
+ aes->aes_set = AES_SET_WCS; /* Only WCS form set. */
+ archive_string_empty(&(aes->aes_mbs));
+ archive_string_empty(&(aes->aes_utf8));
+ archive_wstrncpy(&(aes->aes_wcs), wcs, len);
+ return (0);
+}
+
+int
+archive_mstring_copy_mbs_len_l(struct archive_mstring *aes,
+ const char *mbs, size_t len, struct archive_string_conv *sc)
+{
+ int r;
+
+ if (mbs == NULL) {
+ aes->aes_set = 0;
+ return (0);
+ }
+ archive_string_empty(&(aes->aes_mbs));
+ archive_wstring_empty(&(aes->aes_wcs));
+ archive_string_empty(&(aes->aes_utf8));
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ /*
+ * Internationalization programing on Windows must use Wide
+ * characters because Windows platform cannot make locale UTF-8.
+ */
+ if (sc == NULL) {
+ if (archive_string_append(&(aes->aes_mbs),
+ mbs, mbsnbytes(mbs, len)) == NULL) {
+ aes->aes_set = 0;
+ r = -1;
+ } else {
+ aes->aes_set = AES_SET_MBS;
+ r = 0;
+ }
+#if defined(HAVE_ICONV)
+ } else if (sc != NULL && sc->cd_w != (iconv_t)-1) {
+ /*
+ * This case happens only when MultiByteToWideChar() cannot
+ * handle sc->from_cp, and we have to iconv in order to
+ * translate character-set to wchar_t,UTF-16.
+ */
+ iconv_t cd = sc->cd;
+ unsigned from_cp;
+ int flag;
+
+ /*
+ * Translate multi-bytes from some character-set to UTF-8.
+ */
+ sc->cd = sc->cd_w;
+ r = archive_strncpy_in_locale(&(aes->aes_utf8), mbs, len, sc);
+ sc->cd = cd;
+ if (r != 0) {
+ aes->aes_set = 0;
+ return (r);
+ }
+ aes->aes_set = AES_SET_UTF8;
+
+ /*
+ * Append the UTF-8 string into wstring.
+ */
+ flag = sc->flag;
+ sc->flag &= ~(SCONV_NORMALIZATION_C
+ | SCONV_TO_UTF16| SCONV_FROM_UTF16);
+ from_cp = sc->from_cp;
+ sc->from_cp = CP_UTF8;
+ r = archive_wstring_append_from_mbs_in_codepage(&(aes->aes_wcs),
+ aes->aes_utf8.s, aes->aes_utf8.length, sc);
+ sc->flag = flag;
+ sc->from_cp = from_cp;
+ if (r == 0)
+ aes->aes_set |= AES_SET_WCS;
+#endif
+ } else {
+ r = archive_wstring_append_from_mbs_in_codepage(
+ &(aes->aes_wcs), mbs, len, sc);
+ if (r == 0)
+ aes->aes_set = AES_SET_WCS;
+ else
+ aes->aes_set = 0;
+ }
+#else
+ r = archive_strncpy_in_locale(&(aes->aes_mbs), mbs, len, sc);
+ if (r == 0)
+ aes->aes_set = AES_SET_MBS; /* Only MBS form is set now. */
+ else
+ aes->aes_set = 0;
+#endif
+ return (r);
+}
+
+/*
+ * The 'update' form tries to proactively update all forms of
+ * this string (WCS and MBS) and returns an error if any of
+ * them fail. This is used by the 'pax' handler, for instance,
+ * to detect and report character-conversion failures early while
+ * still allowing clients to get potentially useful values from
+ * the more tolerant lazy conversions. (get_mbs and get_wcs will
+ * strive to give the user something useful, so you can get hopefully
+ * usable values even if some of the character conversions are failing.)
+ */
+int
+archive_mstring_update_utf8(struct archive *a, struct archive_mstring *aes,
+ const char *utf8)
+{
+ struct archive_string_conv *sc;
+ int r;
+
+ if (utf8 == NULL) {
+ aes->aes_set = 0;
+ return (0); /* Succeeded in clearing everything. */
+ }
+
+ /* Save the UTF8 string. */
+ archive_strcpy(&(aes->aes_utf8), utf8);
+
+ /* Empty the mbs and wcs strings. */
+ archive_string_empty(&(aes->aes_mbs));
+ archive_wstring_empty(&(aes->aes_wcs));
+
+ aes->aes_set = AES_SET_UTF8; /* Only UTF8 is set now. */
+
+ /* Try converting UTF-8 to MBS, return false on failure. */
+ sc = archive_string_conversion_from_charset(a, "UTF-8", 1);
+ if (sc == NULL)
+ return (-1);/* Couldn't allocate memory for sc. */
+ r = archive_strcpy_in_locale(&(aes->aes_mbs), utf8, sc);
+ if (a == NULL)
+ free_sconv_object(sc);
+ if (r != 0)
+ return (-1);
+ aes->aes_set = AES_SET_UTF8 | AES_SET_MBS; /* Both UTF8 and MBS set. */
+
+ /* Try converting MBS to WCS, return false on failure. */
+ if (archive_wstring_append_from_mbs(&(aes->aes_wcs), aes->aes_mbs.s,
+ aes->aes_mbs.length))
+ return (-1);
+ aes->aes_set = AES_SET_UTF8 | AES_SET_WCS | AES_SET_MBS;
+
+ /* All conversions succeeded. */
+ return (0);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_string.h b/Utilities/cmlibarchive/libarchive/archive_string.h
new file mode 100644
index 000000000..0e4c9b904
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_string.h
@@ -0,0 +1,237 @@
+/*-
+ * Copyright (c) 2003-2010 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.
+ *
+ * $FreeBSD: head/lib/libarchive/archive_string.h 201092 2009-12-28 02:26:06Z kientzle $
+ *
+ */
+
+#ifndef __LIBARCHIVE_BUILD
+#ifndef __LIBARCHIVE_TEST
+#error This header is only to be used internally to libarchive.
+#endif
+#endif
+
+#ifndef ARCHIVE_STRING_H_INCLUDED
+#define ARCHIVE_STRING_H_INCLUDED
+
+#include <stdarg.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h> /* required for wchar_t on some systems */
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_WCHAR_H
+#include <wchar.h>
+#endif
+
+#include "archive.h"
+
+/*
+ * Basic resizable/reusable string support similar to Java's "StringBuffer."
+ *
+ * Unlike sbuf(9), the buffers here are fully reusable and track the
+ * length throughout.
+ */
+
+struct archive_string {
+ char *s; /* Pointer to the storage */
+ size_t length; /* Length of 's' in characters */
+ size_t buffer_length; /* Length of malloc-ed storage in bytes. */
+};
+
+struct archive_wstring {
+ wchar_t *s; /* Pointer to the storage */
+ size_t length; /* Length of 's' in characters */
+ size_t buffer_length; /* Length of malloc-ed storage in bytes. */
+};
+
+struct archive_string_conv;
+
+/* Initialize an archive_string object on the stack or elsewhere. */
+#define archive_string_init(a) \
+ do { (a)->s = NULL; (a)->length = 0; (a)->buffer_length = 0; } while(0)
+
+/* Append a C char to an archive_string, resizing as necessary. */
+struct archive_string *
+archive_strappend_char(struct archive_string *, char);
+
+/* Ditto for a wchar_t and an archive_wstring. */
+struct archive_wstring *
+archive_wstrappend_wchar(struct archive_wstring *, wchar_t);
+
+/* Convert a Unicode string to current locale and append the result. */
+/* Returns -1 if conversion fails. */
+int
+archive_string_append_from_wcs(struct archive_string *, const wchar_t *, size_t);
+
+
+/* Create a string conversion object.
+ * Return NULL and set a error message if the conversion is not supported
+ * on the platform. */
+struct archive_string_conv *
+archive_string_conversion_to_charset(struct archive *, const char *, int);
+struct archive_string_conv *
+archive_string_conversion_from_charset(struct archive *, const char *, int);
+/* Create the default string conversion object for reading/writing an archive.
+ * Return NULL if the conversion is unneeded.
+ * Note: On non Windows platform this always returns NULL.
+ */
+struct archive_string_conv *
+archive_string_default_conversion_for_read(struct archive *);
+struct archive_string_conv *
+archive_string_default_conversion_for_write(struct archive *);
+/* Dispose of a string conversion object. */
+void
+archive_string_conversion_free(struct archive *);
+const char *
+archive_string_conversion_charset_name(struct archive_string_conv *);
+void
+archive_string_conversion_set_opt(struct archive_string_conv *, int);
+#define SCONV_SET_OPT_UTF8_LIBARCHIVE2X 1
+
+
+/* Copy one archive_string to another in locale conversion.
+ * Return -1 if conversion failes. */
+int
+archive_strncpy_in_locale(struct archive_string *, const void *, size_t,
+ struct archive_string_conv *);
+
+/* Copy one archive_string to another in locale conversion.
+ * Return -1 if conversion failes. */
+int
+archive_strncat_in_locale(struct archive_string *, const void *, size_t,
+ struct archive_string_conv *);
+
+
+/* Copy one archive_string to another */
+#define archive_string_copy(dest, src) \
+ ((dest)->length = 0, archive_string_concat((dest), (src)))
+#define archive_wstring_copy(dest, src) \
+ ((dest)->length = 0, archive_wstring_concat((dest), (src)))
+
+/* Concatenate one archive_string to another */
+void archive_string_concat(struct archive_string *dest, struct archive_string *src);
+void archive_wstring_concat(struct archive_wstring *dest, struct archive_wstring *src);
+
+/* Ensure that the underlying buffer is at least as large as the request. */
+struct archive_string *
+archive_string_ensure(struct archive_string *, size_t);
+struct archive_wstring *
+archive_wstring_ensure(struct archive_wstring *, size_t);
+
+/* Append C string, which may lack trailing \0. */
+/* The source is declared void * here because this gets used with
+ * "signed char *", "unsigned char *" and "char *" arguments.
+ * Declaring it "char *" as with some of the other functions just
+ * leads to a lot of extra casts. */
+struct archive_string *
+archive_strncat(struct archive_string *, const void *, size_t);
+struct archive_wstring *
+archive_wstrncat(struct archive_wstring *, const wchar_t *, size_t);
+
+/* Append a C string to an archive_string, resizing as necessary. */
+struct archive_string *
+archive_strcat(struct archive_string *, const void *);
+struct archive_wstring *
+archive_wstrcat(struct archive_wstring *, const wchar_t *);
+
+/* Copy a C string to an archive_string, resizing as necessary. */
+#define archive_strcpy(as,p) \
+ archive_strncpy((as), (p), ((p) == NULL ? 0 : strlen(p)))
+#define archive_wstrcpy(as,p) \
+ archive_wstrncpy((as), (p), ((p) == NULL ? 0 : wcslen(p)))
+#define archive_strcpy_in_locale(as,p,lo) \
+ archive_strncpy_in_locale((as), (p), ((p) == NULL ? 0 : strlen(p)), (lo))
+
+/* Copy a C string to an archive_string with limit, resizing as necessary. */
+#define archive_strncpy(as,p,l) \
+ ((as)->length=0, archive_strncat((as), (p), (l)))
+#define archive_wstrncpy(as,p,l) \
+ ((as)->length = 0, archive_wstrncat((as), (p), (l)))
+
+/* Return length of string. */
+#define archive_strlen(a) ((a)->length)
+
+/* Set string length to zero. */
+#define archive_string_empty(a) ((a)->length = 0)
+#define archive_wstring_empty(a) ((a)->length = 0)
+
+/* Release any allocated storage resources. */
+void archive_string_free(struct archive_string *);
+void archive_wstring_free(struct archive_wstring *);
+
+/* Like 'vsprintf', but resizes the underlying string as necessary. */
+/* Note: This only implements a small subset of standard printf functionality. */
+void archive_string_vsprintf(struct archive_string *, const char *,
+ va_list) __LA_PRINTF(2, 0);
+void archive_string_sprintf(struct archive_string *, const char *, ...)
+ __LA_PRINTF(2, 3);
+
+/* Translates from MBS to Unicode. */
+/* Returns non-zero if conversion failed in any way. */
+int archive_wstring_append_from_mbs(struct archive_wstring *dest,
+ const char *, size_t);
+
+
+/* A "multistring" can hold Unicode, UTF8, or MBS versions of
+ * the string. If you set and read the same version, no translation
+ * is done. If you set and read different versions, the library
+ * will attempt to transparently convert.
+ */
+struct archive_mstring {
+ struct archive_string aes_mbs;
+ struct archive_string aes_utf8;
+ struct archive_wstring aes_wcs;
+ struct archive_string aes_mbs_in_locale;
+ /* Bitmap of which of the above are valid. Because we're lazy
+ * about malloc-ing and reusing the underlying storage, we
+ * can't rely on NULL pointers to indicate whether a string
+ * has been set. */
+ int aes_set;
+#define AES_SET_MBS 1
+#define AES_SET_UTF8 2
+#define AES_SET_WCS 4
+};
+
+void archive_mstring_clean(struct archive_mstring *);
+void archive_mstring_copy(struct archive_mstring *dest, struct archive_mstring *src);
+int archive_mstring_get_mbs(struct archive *, struct archive_mstring *, const char **);
+int archive_mstring_get_utf8(struct archive *, struct archive_mstring *, const char **);
+int archive_mstring_get_wcs(struct archive *, struct archive_mstring *, const wchar_t **);
+int archive_mstring_get_mbs_l(struct archive_mstring *, const char **,
+ size_t *, struct archive_string_conv *);
+int archive_mstring_copy_mbs(struct archive_mstring *, const char *mbs);
+int archive_mstring_copy_mbs_len(struct archive_mstring *, const char *mbs,
+ size_t);
+int archive_mstring_copy_utf8(struct archive_mstring *, const char *utf8);
+int archive_mstring_copy_wcs(struct archive_mstring *, const wchar_t *wcs);
+int archive_mstring_copy_wcs_len(struct archive_mstring *,
+ const wchar_t *wcs, size_t);
+int archive_mstring_copy_mbs_len_l(struct archive_mstring *,
+ const char *mbs, size_t, struct archive_string_conv *);
+int archive_mstring_update_utf8(struct archive *, struct archive_mstring *aes, const char *utf8);
+
+
+#endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_string_composition.h b/Utilities/cmlibarchive/libarchive/archive_string_composition.h
new file mode 100644
index 000000000..cc4bf46c0
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_string_composition.h
@@ -0,0 +1,1351 @@
+/*-
+ * Copyright (c) 2011 libarchive Project
+ * 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.
+ *
+ * $FreeBSD$
+ *
+ */
+
+/*
+ * ATTENTION!
+ * This file is generated by build/utils/gen_archive_string_composition_h.sh
+ * from http://unicode.org/Public/UNIDATA/UnicodeData.txt
+ *
+ * See also http://unicode.org/report/tr15/
+ */
+
+#ifndef __LIBARCHIVE_BUILD
+#error This header is only to be used internally to libarchive.
+#endif
+
+#ifndef ARCHIVE_STRING_COMPOSITION_H_INCLUDED
+#define ARCHIVE_STRING_COMPOSITION_H_INCLUDED
+
+struct unicode_composition_table {
+ uint32_t cp1;
+ uint32_t cp2;
+ uint32_t nfc;
+};
+
+static const struct unicode_composition_table u_composition_table[] = {
+ { 0x0003C , 0x00338 , 0x0226E },
+ { 0x0003D , 0x00338 , 0x02260 },
+ { 0x0003E , 0x00338 , 0x0226F },
+ { 0x00041 , 0x00300 , 0x000C0 },
+ { 0x00041 , 0x00301 , 0x000C1 },
+ { 0x00041 , 0x00302 , 0x000C2 },
+ { 0x00041 , 0x00303 , 0x000C3 },
+ { 0x00041 , 0x00304 , 0x00100 },
+ { 0x00041 , 0x00306 , 0x00102 },
+ { 0x00041 , 0x00307 , 0x00226 },
+ { 0x00041 , 0x00308 , 0x000C4 },
+ { 0x00041 , 0x00309 , 0x01EA2 },
+ { 0x00041 , 0x0030A , 0x000C5 },
+ { 0x00041 , 0x0030C , 0x001CD },
+ { 0x00041 , 0x0030F , 0x00200 },
+ { 0x00041 , 0x00311 , 0x00202 },
+ { 0x00041 , 0x00323 , 0x01EA0 },
+ { 0x00041 , 0x00325 , 0x01E00 },
+ { 0x00041 , 0x00328 , 0x00104 },
+ { 0x00042 , 0x00307 , 0x01E02 },
+ { 0x00042 , 0x00323 , 0x01E04 },
+ { 0x00042 , 0x00331 , 0x01E06 },
+ { 0x00043 , 0x00301 , 0x00106 },
+ { 0x00043 , 0x00302 , 0x00108 },
+ { 0x00043 , 0x00307 , 0x0010A },
+ { 0x00043 , 0x0030C , 0x0010C },
+ { 0x00043 , 0x00327 , 0x000C7 },
+ { 0x00044 , 0x00307 , 0x01E0A },
+ { 0x00044 , 0x0030C , 0x0010E },
+ { 0x00044 , 0x00323 , 0x01E0C },
+ { 0x00044 , 0x00327 , 0x01E10 },
+ { 0x00044 , 0x0032D , 0x01E12 },
+ { 0x00044 , 0x00331 , 0x01E0E },
+ { 0x00045 , 0x00300 , 0x000C8 },
+ { 0x00045 , 0x00301 , 0x000C9 },
+ { 0x00045 , 0x00302 , 0x000CA },
+ { 0x00045 , 0x00303 , 0x01EBC },
+ { 0x00045 , 0x00304 , 0x00112 },
+ { 0x00045 , 0x00306 , 0x00114 },
+ { 0x00045 , 0x00307 , 0x00116 },
+ { 0x00045 , 0x00308 , 0x000CB },
+ { 0x00045 , 0x00309 , 0x01EBA },
+ { 0x00045 , 0x0030C , 0x0011A },
+ { 0x00045 , 0x0030F , 0x00204 },
+ { 0x00045 , 0x00311 , 0x00206 },
+ { 0x00045 , 0x00323 , 0x01EB8 },
+ { 0x00045 , 0x00327 , 0x00228 },
+ { 0x00045 , 0x00328 , 0x00118 },
+ { 0x00045 , 0x0032D , 0x01E18 },
+ { 0x00045 , 0x00330 , 0x01E1A },
+ { 0x00046 , 0x00307 , 0x01E1E },
+ { 0x00047 , 0x00301 , 0x001F4 },
+ { 0x00047 , 0x00302 , 0x0011C },
+ { 0x00047 , 0x00304 , 0x01E20 },
+ { 0x00047 , 0x00306 , 0x0011E },
+ { 0x00047 , 0x00307 , 0x00120 },
+ { 0x00047 , 0x0030C , 0x001E6 },
+ { 0x00047 , 0x00327 , 0x00122 },
+ { 0x00048 , 0x00302 , 0x00124 },
+ { 0x00048 , 0x00307 , 0x01E22 },
+ { 0x00048 , 0x00308 , 0x01E26 },
+ { 0x00048 , 0x0030C , 0x0021E },
+ { 0x00048 , 0x00323 , 0x01E24 },
+ { 0x00048 , 0x00327 , 0x01E28 },
+ { 0x00048 , 0x0032E , 0x01E2A },
+ { 0x00049 , 0x00300 , 0x000CC },
+ { 0x00049 , 0x00301 , 0x000CD },
+ { 0x00049 , 0x00302 , 0x000CE },
+ { 0x00049 , 0x00303 , 0x00128 },
+ { 0x00049 , 0x00304 , 0x0012A },
+ { 0x00049 , 0x00306 , 0x0012C },
+ { 0x00049 , 0x00307 , 0x00130 },
+ { 0x00049 , 0x00308 , 0x000CF },
+ { 0x00049 , 0x00309 , 0x01EC8 },
+ { 0x00049 , 0x0030C , 0x001CF },
+ { 0x00049 , 0x0030F , 0x00208 },
+ { 0x00049 , 0x00311 , 0x0020A },
+ { 0x00049 , 0x00323 , 0x01ECA },
+ { 0x00049 , 0x00328 , 0x0012E },
+ { 0x00049 , 0x00330 , 0x01E2C },
+ { 0x0004A , 0x00302 , 0x00134 },
+ { 0x0004B , 0x00301 , 0x01E30 },
+ { 0x0004B , 0x0030C , 0x001E8 },
+ { 0x0004B , 0x00323 , 0x01E32 },
+ { 0x0004B , 0x00327 , 0x00136 },
+ { 0x0004B , 0x00331 , 0x01E34 },
+ { 0x0004C , 0x00301 , 0x00139 },
+ { 0x0004C , 0x0030C , 0x0013D },
+ { 0x0004C , 0x00323 , 0x01E36 },
+ { 0x0004C , 0x00327 , 0x0013B },
+ { 0x0004C , 0x0032D , 0x01E3C },
+ { 0x0004C , 0x00331 , 0x01E3A },
+ { 0x0004D , 0x00301 , 0x01E3E },
+ { 0x0004D , 0x00307 , 0x01E40 },
+ { 0x0004D , 0x00323 , 0x01E42 },
+ { 0x0004E , 0x00300 , 0x001F8 },
+ { 0x0004E , 0x00301 , 0x00143 },
+ { 0x0004E , 0x00303 , 0x000D1 },
+ { 0x0004E , 0x00307 , 0x01E44 },
+ { 0x0004E , 0x0030C , 0x00147 },
+ { 0x0004E , 0x00323 , 0x01E46 },
+ { 0x0004E , 0x00327 , 0x00145 },
+ { 0x0004E , 0x0032D , 0x01E4A },
+ { 0x0004E , 0x00331 , 0x01E48 },
+ { 0x0004F , 0x00300 , 0x000D2 },
+ { 0x0004F , 0x00301 , 0x000D3 },
+ { 0x0004F , 0x00302 , 0x000D4 },
+ { 0x0004F , 0x00303 , 0x000D5 },
+ { 0x0004F , 0x00304 , 0x0014C },
+ { 0x0004F , 0x00306 , 0x0014E },
+ { 0x0004F , 0x00307 , 0x0022E },
+ { 0x0004F , 0x00308 , 0x000D6 },
+ { 0x0004F , 0x00309 , 0x01ECE },
+ { 0x0004F , 0x0030B , 0x00150 },
+ { 0x0004F , 0x0030C , 0x001D1 },
+ { 0x0004F , 0x0030F , 0x0020C },
+ { 0x0004F , 0x00311 , 0x0020E },
+ { 0x0004F , 0x0031B , 0x001A0 },
+ { 0x0004F , 0x00323 , 0x01ECC },
+ { 0x0004F , 0x00328 , 0x001EA },
+ { 0x00050 , 0x00301 , 0x01E54 },
+ { 0x00050 , 0x00307 , 0x01E56 },
+ { 0x00052 , 0x00301 , 0x00154 },
+ { 0x00052 , 0x00307 , 0x01E58 },
+ { 0x00052 , 0x0030C , 0x00158 },
+ { 0x00052 , 0x0030F , 0x00210 },
+ { 0x00052 , 0x00311 , 0x00212 },
+ { 0x00052 , 0x00323 , 0x01E5A },
+ { 0x00052 , 0x00327 , 0x00156 },
+ { 0x00052 , 0x00331 , 0x01E5E },
+ { 0x00053 , 0x00301 , 0x0015A },
+ { 0x00053 , 0x00302 , 0x0015C },
+ { 0x00053 , 0x00307 , 0x01E60 },
+ { 0x00053 , 0x0030C , 0x00160 },
+ { 0x00053 , 0x00323 , 0x01E62 },
+ { 0x00053 , 0x00326 , 0x00218 },
+ { 0x00053 , 0x00327 , 0x0015E },
+ { 0x00054 , 0x00307 , 0x01E6A },
+ { 0x00054 , 0x0030C , 0x00164 },
+ { 0x00054 , 0x00323 , 0x01E6C },
+ { 0x00054 , 0x00326 , 0x0021A },
+ { 0x00054 , 0x00327 , 0x00162 },
+ { 0x00054 , 0x0032D , 0x01E70 },
+ { 0x00054 , 0x00331 , 0x01E6E },
+ { 0x00055 , 0x00300 , 0x000D9 },
+ { 0x00055 , 0x00301 , 0x000DA },
+ { 0x00055 , 0x00302 , 0x000DB },
+ { 0x00055 , 0x00303 , 0x00168 },
+ { 0x00055 , 0x00304 , 0x0016A },
+ { 0x00055 , 0x00306 , 0x0016C },
+ { 0x00055 , 0x00308 , 0x000DC },
+ { 0x00055 , 0x00309 , 0x01EE6 },
+ { 0x00055 , 0x0030A , 0x0016E },
+ { 0x00055 , 0x0030B , 0x00170 },
+ { 0x00055 , 0x0030C , 0x001D3 },
+ { 0x00055 , 0x0030F , 0x00214 },
+ { 0x00055 , 0x00311 , 0x00216 },
+ { 0x00055 , 0x0031B , 0x001AF },
+ { 0x00055 , 0x00323 , 0x01EE4 },
+ { 0x00055 , 0x00324 , 0x01E72 },
+ { 0x00055 , 0x00328 , 0x00172 },
+ { 0x00055 , 0x0032D , 0x01E76 },
+ { 0x00055 , 0x00330 , 0x01E74 },
+ { 0x00056 , 0x00303 , 0x01E7C },
+ { 0x00056 , 0x00323 , 0x01E7E },
+ { 0x00057 , 0x00300 , 0x01E80 },
+ { 0x00057 , 0x00301 , 0x01E82 },
+ { 0x00057 , 0x00302 , 0x00174 },
+ { 0x00057 , 0x00307 , 0x01E86 },
+ { 0x00057 , 0x00308 , 0x01E84 },
+ { 0x00057 , 0x00323 , 0x01E88 },
+ { 0x00058 , 0x00307 , 0x01E8A },
+ { 0x00058 , 0x00308 , 0x01E8C },
+ { 0x00059 , 0x00300 , 0x01EF2 },
+ { 0x00059 , 0x00301 , 0x000DD },
+ { 0x00059 , 0x00302 , 0x00176 },
+ { 0x00059 , 0x00303 , 0x01EF8 },
+ { 0x00059 , 0x00304 , 0x00232 },
+ { 0x00059 , 0x00307 , 0x01E8E },
+ { 0x00059 , 0x00308 , 0x00178 },
+ { 0x00059 , 0x00309 , 0x01EF6 },
+ { 0x00059 , 0x00323 , 0x01EF4 },
+ { 0x0005A , 0x00301 , 0x00179 },
+ { 0x0005A , 0x00302 , 0x01E90 },
+ { 0x0005A , 0x00307 , 0x0017B },
+ { 0x0005A , 0x0030C , 0x0017D },
+ { 0x0005A , 0x00323 , 0x01E92 },
+ { 0x0005A , 0x00331 , 0x01E94 },
+ { 0x00061 , 0x00300 , 0x000E0 },
+ { 0x00061 , 0x00301 , 0x000E1 },
+ { 0x00061 , 0x00302 , 0x000E2 },
+ { 0x00061 , 0x00303 , 0x000E3 },
+ { 0x00061 , 0x00304 , 0x00101 },
+ { 0x00061 , 0x00306 , 0x00103 },
+ { 0x00061 , 0x00307 , 0x00227 },
+ { 0x00061 , 0x00308 , 0x000E4 },
+ { 0x00061 , 0x00309 , 0x01EA3 },
+ { 0x00061 , 0x0030A , 0x000E5 },
+ { 0x00061 , 0x0030C , 0x001CE },
+ { 0x00061 , 0x0030F , 0x00201 },
+ { 0x00061 , 0x00311 , 0x00203 },
+ { 0x00061 , 0x00323 , 0x01EA1 },
+ { 0x00061 , 0x00325 , 0x01E01 },
+ { 0x00061 , 0x00328 , 0x00105 },
+ { 0x00062 , 0x00307 , 0x01E03 },
+ { 0x00062 , 0x00323 , 0x01E05 },
+ { 0x00062 , 0x00331 , 0x01E07 },
+ { 0x00063 , 0x00301 , 0x00107 },
+ { 0x00063 , 0x00302 , 0x00109 },
+ { 0x00063 , 0x00307 , 0x0010B },
+ { 0x00063 , 0x0030C , 0x0010D },
+ { 0x00063 , 0x00327 , 0x000E7 },
+ { 0x00064 , 0x00307 , 0x01E0B },
+ { 0x00064 , 0x0030C , 0x0010F },
+ { 0x00064 , 0x00323 , 0x01E0D },
+ { 0x00064 , 0x00327 , 0x01E11 },
+ { 0x00064 , 0x0032D , 0x01E13 },
+ { 0x00064 , 0x00331 , 0x01E0F },
+ { 0x00065 , 0x00300 , 0x000E8 },
+ { 0x00065 , 0x00301 , 0x000E9 },
+ { 0x00065 , 0x00302 , 0x000EA },
+ { 0x00065 , 0x00303 , 0x01EBD },
+ { 0x00065 , 0x00304 , 0x00113 },
+ { 0x00065 , 0x00306 , 0x00115 },
+ { 0x00065 , 0x00307 , 0x00117 },
+ { 0x00065 , 0x00308 , 0x000EB },
+ { 0x00065 , 0x00309 , 0x01EBB },
+ { 0x00065 , 0x0030C , 0x0011B },
+ { 0x00065 , 0x0030F , 0x00205 },
+ { 0x00065 , 0x00311 , 0x00207 },
+ { 0x00065 , 0x00323 , 0x01EB9 },
+ { 0x00065 , 0x00327 , 0x00229 },
+ { 0x00065 , 0x00328 , 0x00119 },
+ { 0x00065 , 0x0032D , 0x01E19 },
+ { 0x00065 , 0x00330 , 0x01E1B },
+ { 0x00066 , 0x00307 , 0x01E1F },
+ { 0x00067 , 0x00301 , 0x001F5 },
+ { 0x00067 , 0x00302 , 0x0011D },
+ { 0x00067 , 0x00304 , 0x01E21 },
+ { 0x00067 , 0x00306 , 0x0011F },
+ { 0x00067 , 0x00307 , 0x00121 },
+ { 0x00067 , 0x0030C , 0x001E7 },
+ { 0x00067 , 0x00327 , 0x00123 },
+ { 0x00068 , 0x00302 , 0x00125 },
+ { 0x00068 , 0x00307 , 0x01E23 },
+ { 0x00068 , 0x00308 , 0x01E27 },
+ { 0x00068 , 0x0030C , 0x0021F },
+ { 0x00068 , 0x00323 , 0x01E25 },
+ { 0x00068 , 0x00327 , 0x01E29 },
+ { 0x00068 , 0x0032E , 0x01E2B },
+ { 0x00068 , 0x00331 , 0x01E96 },
+ { 0x00069 , 0x00300 , 0x000EC },
+ { 0x00069 , 0x00301 , 0x000ED },
+ { 0x00069 , 0x00302 , 0x000EE },
+ { 0x00069 , 0x00303 , 0x00129 },
+ { 0x00069 , 0x00304 , 0x0012B },
+ { 0x00069 , 0x00306 , 0x0012D },
+ { 0x00069 , 0x00308 , 0x000EF },
+ { 0x00069 , 0x00309 , 0x01EC9 },
+ { 0x00069 , 0x0030C , 0x001D0 },
+ { 0x00069 , 0x0030F , 0x00209 },
+ { 0x00069 , 0x00311 , 0x0020B },
+ { 0x00069 , 0x00323 , 0x01ECB },
+ { 0x00069 , 0x00328 , 0x0012F },
+ { 0x00069 , 0x00330 , 0x01E2D },
+ { 0x0006A , 0x00302 , 0x00135 },
+ { 0x0006A , 0x0030C , 0x001F0 },
+ { 0x0006B , 0x00301 , 0x01E31 },
+ { 0x0006B , 0x0030C , 0x001E9 },
+ { 0x0006B , 0x00323 , 0x01E33 },
+ { 0x0006B , 0x00327 , 0x00137 },
+ { 0x0006B , 0x00331 , 0x01E35 },
+ { 0x0006C , 0x00301 , 0x0013A },
+ { 0x0006C , 0x0030C , 0x0013E },
+ { 0x0006C , 0x00323 , 0x01E37 },
+ { 0x0006C , 0x00327 , 0x0013C },
+ { 0x0006C , 0x0032D , 0x01E3D },
+ { 0x0006C , 0x00331 , 0x01E3B },
+ { 0x0006D , 0x00301 , 0x01E3F },
+ { 0x0006D , 0x00307 , 0x01E41 },
+ { 0x0006D , 0x00323 , 0x01E43 },
+ { 0x0006E , 0x00300 , 0x001F9 },
+ { 0x0006E , 0x00301 , 0x00144 },
+ { 0x0006E , 0x00303 , 0x000F1 },
+ { 0x0006E , 0x00307 , 0x01E45 },
+ { 0x0006E , 0x0030C , 0x00148 },
+ { 0x0006E , 0x00323 , 0x01E47 },
+ { 0x0006E , 0x00327 , 0x00146 },
+ { 0x0006E , 0x0032D , 0x01E4B },
+ { 0x0006E , 0x00331 , 0x01E49 },
+ { 0x0006F , 0x00300 , 0x000F2 },
+ { 0x0006F , 0x00301 , 0x000F3 },
+ { 0x0006F , 0x00302 , 0x000F4 },
+ { 0x0006F , 0x00303 , 0x000F5 },
+ { 0x0006F , 0x00304 , 0x0014D },
+ { 0x0006F , 0x00306 , 0x0014F },
+ { 0x0006F , 0x00307 , 0x0022F },
+ { 0x0006F , 0x00308 , 0x000F6 },
+ { 0x0006F , 0x00309 , 0x01ECF },
+ { 0x0006F , 0x0030B , 0x00151 },
+ { 0x0006F , 0x0030C , 0x001D2 },
+ { 0x0006F , 0x0030F , 0x0020D },
+ { 0x0006F , 0x00311 , 0x0020F },
+ { 0x0006F , 0x0031B , 0x001A1 },
+ { 0x0006F , 0x00323 , 0x01ECD },
+ { 0x0006F , 0x00328 , 0x001EB },
+ { 0x00070 , 0x00301 , 0x01E55 },
+ { 0x00070 , 0x00307 , 0x01E57 },
+ { 0x00072 , 0x00301 , 0x00155 },
+ { 0x00072 , 0x00307 , 0x01E59 },
+ { 0x00072 , 0x0030C , 0x00159 },
+ { 0x00072 , 0x0030F , 0x00211 },
+ { 0x00072 , 0x00311 , 0x00213 },
+ { 0x00072 , 0x00323 , 0x01E5B },
+ { 0x00072 , 0x00327 , 0x00157 },
+ { 0x00072 , 0x00331 , 0x01E5F },
+ { 0x00073 , 0x00301 , 0x0015B },
+ { 0x00073 , 0x00302 , 0x0015D },
+ { 0x00073 , 0x00307 , 0x01E61 },
+ { 0x00073 , 0x0030C , 0x00161 },
+ { 0x00073 , 0x00323 , 0x01E63 },
+ { 0x00073 , 0x00326 , 0x00219 },
+ { 0x00073 , 0x00327 , 0x0015F },
+ { 0x00074 , 0x00307 , 0x01E6B },
+ { 0x00074 , 0x00308 , 0x01E97 },
+ { 0x00074 , 0x0030C , 0x00165 },
+ { 0x00074 , 0x00323 , 0x01E6D },
+ { 0x00074 , 0x00326 , 0x0021B },
+ { 0x00074 , 0x00327 , 0x00163 },
+ { 0x00074 , 0x0032D , 0x01E71 },
+ { 0x00074 , 0x00331 , 0x01E6F },
+ { 0x00075 , 0x00300 , 0x000F9 },
+ { 0x00075 , 0x00301 , 0x000FA },
+ { 0x00075 , 0x00302 , 0x000FB },
+ { 0x00075 , 0x00303 , 0x00169 },
+ { 0x00075 , 0x00304 , 0x0016B },
+ { 0x00075 , 0x00306 , 0x0016D },
+ { 0x00075 , 0x00308 , 0x000FC },
+ { 0x00075 , 0x00309 , 0x01EE7 },
+ { 0x00075 , 0x0030A , 0x0016F },
+ { 0x00075 , 0x0030B , 0x00171 },
+ { 0x00075 , 0x0030C , 0x001D4 },
+ { 0x00075 , 0x0030F , 0x00215 },
+ { 0x00075 , 0x00311 , 0x00217 },
+ { 0x00075 , 0x0031B , 0x001B0 },
+ { 0x00075 , 0x00323 , 0x01EE5 },
+ { 0x00075 , 0x00324 , 0x01E73 },
+ { 0x00075 , 0x00328 , 0x00173 },
+ { 0x00075 , 0x0032D , 0x01E77 },
+ { 0x00075 , 0x00330 , 0x01E75 },
+ { 0x00076 , 0x00303 , 0x01E7D },
+ { 0x00076 , 0x00323 , 0x01E7F },
+ { 0x00077 , 0x00300 , 0x01E81 },
+ { 0x00077 , 0x00301 , 0x01E83 },
+ { 0x00077 , 0x00302 , 0x00175 },
+ { 0x00077 , 0x00307 , 0x01E87 },
+ { 0x00077 , 0x00308 , 0x01E85 },
+ { 0x00077 , 0x0030A , 0x01E98 },
+ { 0x00077 , 0x00323 , 0x01E89 },
+ { 0x00078 , 0x00307 , 0x01E8B },
+ { 0x00078 , 0x00308 , 0x01E8D },
+ { 0x00079 , 0x00300 , 0x01EF3 },
+ { 0x00079 , 0x00301 , 0x000FD },
+ { 0x00079 , 0x00302 , 0x00177 },
+ { 0x00079 , 0x00303 , 0x01EF9 },
+ { 0x00079 , 0x00304 , 0x00233 },
+ { 0x00079 , 0x00307 , 0x01E8F },
+ { 0x00079 , 0x00308 , 0x000FF },
+ { 0x00079 , 0x00309 , 0x01EF7 },
+ { 0x00079 , 0x0030A , 0x01E99 },
+ { 0x00079 , 0x00323 , 0x01EF5 },
+ { 0x0007A , 0x00301 , 0x0017A },
+ { 0x0007A , 0x00302 , 0x01E91 },
+ { 0x0007A , 0x00307 , 0x0017C },
+ { 0x0007A , 0x0030C , 0x0017E },
+ { 0x0007A , 0x00323 , 0x01E93 },
+ { 0x0007A , 0x00331 , 0x01E95 },
+ { 0x000A8 , 0x00300 , 0x01FED },
+ { 0x000A8 , 0x00301 , 0x00385 },
+ { 0x000A8 , 0x00342 , 0x01FC1 },
+ { 0x000C2 , 0x00300 , 0x01EA6 },
+ { 0x000C2 , 0x00301 , 0x01EA4 },
+ { 0x000C2 , 0x00303 , 0x01EAA },
+ { 0x000C2 , 0x00309 , 0x01EA8 },
+ { 0x000C4 , 0x00304 , 0x001DE },
+ { 0x000C5 , 0x00301 , 0x001FA },
+ { 0x000C6 , 0x00301 , 0x001FC },
+ { 0x000C6 , 0x00304 , 0x001E2 },
+ { 0x000C7 , 0x00301 , 0x01E08 },
+ { 0x000CA , 0x00300 , 0x01EC0 },
+ { 0x000CA , 0x00301 , 0x01EBE },
+ { 0x000CA , 0x00303 , 0x01EC4 },
+ { 0x000CA , 0x00309 , 0x01EC2 },
+ { 0x000CF , 0x00301 , 0x01E2E },
+ { 0x000D4 , 0x00300 , 0x01ED2 },
+ { 0x000D4 , 0x00301 , 0x01ED0 },
+ { 0x000D4 , 0x00303 , 0x01ED6 },
+ { 0x000D4 , 0x00309 , 0x01ED4 },
+ { 0x000D5 , 0x00301 , 0x01E4C },
+ { 0x000D5 , 0x00304 , 0x0022C },
+ { 0x000D5 , 0x00308 , 0x01E4E },
+ { 0x000D6 , 0x00304 , 0x0022A },
+ { 0x000D8 , 0x00301 , 0x001FE },
+ { 0x000DC , 0x00300 , 0x001DB },
+ { 0x000DC , 0x00301 , 0x001D7 },
+ { 0x000DC , 0x00304 , 0x001D5 },
+ { 0x000DC , 0x0030C , 0x001D9 },
+ { 0x000E2 , 0x00300 , 0x01EA7 },
+ { 0x000E2 , 0x00301 , 0x01EA5 },
+ { 0x000E2 , 0x00303 , 0x01EAB },
+ { 0x000E2 , 0x00309 , 0x01EA9 },
+ { 0x000E4 , 0x00304 , 0x001DF },
+ { 0x000E5 , 0x00301 , 0x001FB },
+ { 0x000E6 , 0x00301 , 0x001FD },
+ { 0x000E6 , 0x00304 , 0x001E3 },
+ { 0x000E7 , 0x00301 , 0x01E09 },
+ { 0x000EA , 0x00300 , 0x01EC1 },
+ { 0x000EA , 0x00301 , 0x01EBF },
+ { 0x000EA , 0x00303 , 0x01EC5 },
+ { 0x000EA , 0x00309 , 0x01EC3 },
+ { 0x000EF , 0x00301 , 0x01E2F },
+ { 0x000F4 , 0x00300 , 0x01ED3 },
+ { 0x000F4 , 0x00301 , 0x01ED1 },
+ { 0x000F4 , 0x00303 , 0x01ED7 },
+ { 0x000F4 , 0x00309 , 0x01ED5 },
+ { 0x000F5 , 0x00301 , 0x01E4D },
+ { 0x000F5 , 0x00304 , 0x0022D },
+ { 0x000F5 , 0x00308 , 0x01E4F },
+ { 0x000F6 , 0x00304 , 0x0022B },
+ { 0x000F8 , 0x00301 , 0x001FF },
+ { 0x000FC , 0x00300 , 0x001DC },
+ { 0x000FC , 0x00301 , 0x001D8 },
+ { 0x000FC , 0x00304 , 0x001D6 },
+ { 0x000FC , 0x0030C , 0x001DA },
+ { 0x00102 , 0x00300 , 0x01EB0 },
+ { 0x00102 , 0x00301 , 0x01EAE },
+ { 0x00102 , 0x00303 , 0x01EB4 },
+ { 0x00102 , 0x00309 , 0x01EB2 },
+ { 0x00103 , 0x00300 , 0x01EB1 },
+ { 0x00103 , 0x00301 , 0x01EAF },
+ { 0x00103 , 0x00303 , 0x01EB5 },
+ { 0x00103 , 0x00309 , 0x01EB3 },
+ { 0x00112 , 0x00300 , 0x01E14 },
+ { 0x00112 , 0x00301 , 0x01E16 },
+ { 0x00113 , 0x00300 , 0x01E15 },
+ { 0x00113 , 0x00301 , 0x01E17 },
+ { 0x0014C , 0x00300 , 0x01E50 },
+ { 0x0014C , 0x00301 , 0x01E52 },
+ { 0x0014D , 0x00300 , 0x01E51 },
+ { 0x0014D , 0x00301 , 0x01E53 },
+ { 0x0015A , 0x00307 , 0x01E64 },
+ { 0x0015B , 0x00307 , 0x01E65 },
+ { 0x00160 , 0x00307 , 0x01E66 },
+ { 0x00161 , 0x00307 , 0x01E67 },
+ { 0x00168 , 0x00301 , 0x01E78 },
+ { 0x00169 , 0x00301 , 0x01E79 },
+ { 0x0016A , 0x00308 , 0x01E7A },
+ { 0x0016B , 0x00308 , 0x01E7B },
+ { 0x0017F , 0x00307 , 0x01E9B },
+ { 0x001A0 , 0x00300 , 0x01EDC },
+ { 0x001A0 , 0x00301 , 0x01EDA },
+ { 0x001A0 , 0x00303 , 0x01EE0 },
+ { 0x001A0 , 0x00309 , 0x01EDE },
+ { 0x001A0 , 0x00323 , 0x01EE2 },
+ { 0x001A1 , 0x00300 , 0x01EDD },
+ { 0x001A1 , 0x00301 , 0x01EDB },
+ { 0x001A1 , 0x00303 , 0x01EE1 },
+ { 0x001A1 , 0x00309 , 0x01EDF },
+ { 0x001A1 , 0x00323 , 0x01EE3 },
+ { 0x001AF , 0x00300 , 0x01EEA },
+ { 0x001AF , 0x00301 , 0x01EE8 },
+ { 0x001AF , 0x00303 , 0x01EEE },
+ { 0x001AF , 0x00309 , 0x01EEC },
+ { 0x001AF , 0x00323 , 0x01EF0 },
+ { 0x001B0 , 0x00300 , 0x01EEB },
+ { 0x001B0 , 0x00301 , 0x01EE9 },
+ { 0x001B0 , 0x00303 , 0x01EEF },
+ { 0x001B0 , 0x00309 , 0x01EED },
+ { 0x001B0 , 0x00323 , 0x01EF1 },
+ { 0x001B7 , 0x0030C , 0x001EE },
+ { 0x001EA , 0x00304 , 0x001EC },
+ { 0x001EB , 0x00304 , 0x001ED },
+ { 0x00226 , 0x00304 , 0x001E0 },
+ { 0x00227 , 0x00304 , 0x001E1 },
+ { 0x00228 , 0x00306 , 0x01E1C },
+ { 0x00229 , 0x00306 , 0x01E1D },
+ { 0x0022E , 0x00304 , 0x00230 },
+ { 0x0022F , 0x00304 , 0x00231 },
+ { 0x00292 , 0x0030C , 0x001EF },
+ { 0x00391 , 0x00300 , 0x01FBA },
+ { 0x00391 , 0x00301 , 0x00386 },
+ { 0x00391 , 0x00304 , 0x01FB9 },
+ { 0x00391 , 0x00306 , 0x01FB8 },
+ { 0x00391 , 0x00313 , 0x01F08 },
+ { 0x00391 , 0x00314 , 0x01F09 },
+ { 0x00391 , 0x00345 , 0x01FBC },
+ { 0x00395 , 0x00300 , 0x01FC8 },
+ { 0x00395 , 0x00301 , 0x00388 },
+ { 0x00395 , 0x00313 , 0x01F18 },
+ { 0x00395 , 0x00314 , 0x01F19 },
+ { 0x00397 , 0x00300 , 0x01FCA },
+ { 0x00397 , 0x00301 , 0x00389 },
+ { 0x00397 , 0x00313 , 0x01F28 },
+ { 0x00397 , 0x00314 , 0x01F29 },
+ { 0x00397 , 0x00345 , 0x01FCC },
+ { 0x00399 , 0x00300 , 0x01FDA },
+ { 0x00399 , 0x00301 , 0x0038A },
+ { 0x00399 , 0x00304 , 0x01FD9 },
+ { 0x00399 , 0x00306 , 0x01FD8 },
+ { 0x00399 , 0x00308 , 0x003AA },
+ { 0x00399 , 0x00313 , 0x01F38 },
+ { 0x00399 , 0x00314 , 0x01F39 },
+ { 0x0039F , 0x00300 , 0x01FF8 },
+ { 0x0039F , 0x00301 , 0x0038C },
+ { 0x0039F , 0x00313 , 0x01F48 },
+ { 0x0039F , 0x00314 , 0x01F49 },
+ { 0x003A1 , 0x00314 , 0x01FEC },
+ { 0x003A5 , 0x00300 , 0x01FEA },
+ { 0x003A5 , 0x00301 , 0x0038E },
+ { 0x003A5 , 0x00304 , 0x01FE9 },
+ { 0x003A5 , 0x00306 , 0x01FE8 },
+ { 0x003A5 , 0x00308 , 0x003AB },
+ { 0x003A5 , 0x00314 , 0x01F59 },
+ { 0x003A9 , 0x00300 , 0x01FFA },
+ { 0x003A9 , 0x00301 , 0x0038F },
+ { 0x003A9 , 0x00313 , 0x01F68 },
+ { 0x003A9 , 0x00314 , 0x01F69 },
+ { 0x003A9 , 0x00345 , 0x01FFC },
+ { 0x003AC , 0x00345 , 0x01FB4 },
+ { 0x003AE , 0x00345 , 0x01FC4 },
+ { 0x003B1 , 0x00300 , 0x01F70 },
+ { 0x003B1 , 0x00301 , 0x003AC },
+ { 0x003B1 , 0x00304 , 0x01FB1 },
+ { 0x003B1 , 0x00306 , 0x01FB0 },
+ { 0x003B1 , 0x00313 , 0x01F00 },
+ { 0x003B1 , 0x00314 , 0x01F01 },
+ { 0x003B1 , 0x00342 , 0x01FB6 },
+ { 0x003B1 , 0x00345 , 0x01FB3 },
+ { 0x003B5 , 0x00300 , 0x01F72 },
+ { 0x003B5 , 0x00301 , 0x003AD },
+ { 0x003B5 , 0x00313 , 0x01F10 },
+ { 0x003B5 , 0x00314 , 0x01F11 },
+ { 0x003B7 , 0x00300 , 0x01F74 },
+ { 0x003B7 , 0x00301 , 0x003AE },
+ { 0x003B7 , 0x00313 , 0x01F20 },
+ { 0x003B7 , 0x00314 , 0x01F21 },
+ { 0x003B7 , 0x00342 , 0x01FC6 },
+ { 0x003B7 , 0x00345 , 0x01FC3 },
+ { 0x003B9 , 0x00300 , 0x01F76 },
+ { 0x003B9 , 0x00301 , 0x003AF },
+ { 0x003B9 , 0x00304 , 0x01FD1 },
+ { 0x003B9 , 0x00306 , 0x01FD0 },
+ { 0x003B9 , 0x00308 , 0x003CA },
+ { 0x003B9 , 0x00313 , 0x01F30 },
+ { 0x003B9 , 0x00314 , 0x01F31 },
+ { 0x003B9 , 0x00342 , 0x01FD6 },
+ { 0x003BF , 0x00300 , 0x01F78 },
+ { 0x003BF , 0x00301 , 0x003CC },
+ { 0x003BF , 0x00313 , 0x01F40 },
+ { 0x003BF , 0x00314 , 0x01F41 },
+ { 0x003C1 , 0x00313 , 0x01FE4 },
+ { 0x003C1 , 0x00314 , 0x01FE5 },
+ { 0x003C5 , 0x00300 , 0x01F7A },
+ { 0x003C5 , 0x00301 , 0x003CD },
+ { 0x003C5 , 0x00304 , 0x01FE1 },
+ { 0x003C5 , 0x00306 , 0x01FE0 },
+ { 0x003C5 , 0x00308 , 0x003CB },
+ { 0x003C5 , 0x00313 , 0x01F50 },
+ { 0x003C5 , 0x00314 , 0x01F51 },
+ { 0x003C5 , 0x00342 , 0x01FE6 },
+ { 0x003C9 , 0x00300 , 0x01F7C },
+ { 0x003C9 , 0x00301 , 0x003CE },
+ { 0x003C9 , 0x00313 , 0x01F60 },
+ { 0x003C9 , 0x00314 , 0x01F61 },
+ { 0x003C9 , 0x00342 , 0x01FF6 },
+ { 0x003C9 , 0x00345 , 0x01FF3 },
+ { 0x003CA , 0x00300 , 0x01FD2 },
+ { 0x003CA , 0x00301 , 0x00390 },
+ { 0x003CA , 0x00342 , 0x01FD7 },
+ { 0x003CB , 0x00300 , 0x01FE2 },
+ { 0x003CB , 0x00301 , 0x003B0 },
+ { 0x003CB , 0x00342 , 0x01FE7 },
+ { 0x003CE , 0x00345 , 0x01FF4 },
+ { 0x003D2 , 0x00301 , 0x003D3 },
+ { 0x003D2 , 0x00308 , 0x003D4 },
+ { 0x00406 , 0x00308 , 0x00407 },
+ { 0x00410 , 0x00306 , 0x004D0 },
+ { 0x00410 , 0x00308 , 0x004D2 },
+ { 0x00413 , 0x00301 , 0x00403 },
+ { 0x00415 , 0x00300 , 0x00400 },
+ { 0x00415 , 0x00306 , 0x004D6 },
+ { 0x00415 , 0x00308 , 0x00401 },
+ { 0x00416 , 0x00306 , 0x004C1 },
+ { 0x00416 , 0x00308 , 0x004DC },
+ { 0x00417 , 0x00308 , 0x004DE },
+ { 0x00418 , 0x00300 , 0x0040D },
+ { 0x00418 , 0x00304 , 0x004E2 },
+ { 0x00418 , 0x00306 , 0x00419 },
+ { 0x00418 , 0x00308 , 0x004E4 },
+ { 0x0041A , 0x00301 , 0x0040C },
+ { 0x0041E , 0x00308 , 0x004E6 },
+ { 0x00423 , 0x00304 , 0x004EE },
+ { 0x00423 , 0x00306 , 0x0040E },
+ { 0x00423 , 0x00308 , 0x004F0 },
+ { 0x00423 , 0x0030B , 0x004F2 },
+ { 0x00427 , 0x00308 , 0x004F4 },
+ { 0x0042B , 0x00308 , 0x004F8 },
+ { 0x0042D , 0x00308 , 0x004EC },
+ { 0x00430 , 0x00306 , 0x004D1 },
+ { 0x00430 , 0x00308 , 0x004D3 },
+ { 0x00433 , 0x00301 , 0x00453 },
+ { 0x00435 , 0x00300 , 0x00450 },
+ { 0x00435 , 0x00306 , 0x004D7 },
+ { 0x00435 , 0x00308 , 0x00451 },
+ { 0x00436 , 0x00306 , 0x004C2 },
+ { 0x00436 , 0x00308 , 0x004DD },
+ { 0x00437 , 0x00308 , 0x004DF },
+ { 0x00438 , 0x00300 , 0x0045D },
+ { 0x00438 , 0x00304 , 0x004E3 },
+ { 0x00438 , 0x00306 , 0x00439 },
+ { 0x00438 , 0x00308 , 0x004E5 },
+ { 0x0043A , 0x00301 , 0x0045C },
+ { 0x0043E , 0x00308 , 0x004E7 },
+ { 0x00443 , 0x00304 , 0x004EF },
+ { 0x00443 , 0x00306 , 0x0045E },
+ { 0x00443 , 0x00308 , 0x004F1 },
+ { 0x00443 , 0x0030B , 0x004F3 },
+ { 0x00447 , 0x00308 , 0x004F5 },
+ { 0x0044B , 0x00308 , 0x004F9 },
+ { 0x0044D , 0x00308 , 0x004ED },
+ { 0x00456 , 0x00308 , 0x00457 },
+ { 0x00474 , 0x0030F , 0x00476 },
+ { 0x00475 , 0x0030F , 0x00477 },
+ { 0x004D8 , 0x00308 , 0x004DA },
+ { 0x004D9 , 0x00308 , 0x004DB },
+ { 0x004E8 , 0x00308 , 0x004EA },
+ { 0x004E9 , 0x00308 , 0x004EB },
+ { 0x00627 , 0x00653 , 0x00622 },
+ { 0x00627 , 0x00654 , 0x00623 },
+ { 0x00627 , 0x00655 , 0x00625 },
+ { 0x00648 , 0x00654 , 0x00624 },
+ { 0x0064A , 0x00654 , 0x00626 },
+ { 0x006C1 , 0x00654 , 0x006C2 },
+ { 0x006D2 , 0x00654 , 0x006D3 },
+ { 0x006D5 , 0x00654 , 0x006C0 },
+ { 0x00928 , 0x0093C , 0x00929 },
+ { 0x00930 , 0x0093C , 0x00931 },
+ { 0x00933 , 0x0093C , 0x00934 },
+ { 0x009C7 , 0x009BE , 0x009CB },
+ { 0x009C7 , 0x009D7 , 0x009CC },
+ { 0x00B47 , 0x00B3E , 0x00B4B },
+ { 0x00B47 , 0x00B56 , 0x00B48 },
+ { 0x00B47 , 0x00B57 , 0x00B4C },
+ { 0x00B92 , 0x00BD7 , 0x00B94 },
+ { 0x00BC6 , 0x00BBE , 0x00BCA },
+ { 0x00BC6 , 0x00BD7 , 0x00BCC },
+ { 0x00BC7 , 0x00BBE , 0x00BCB },
+ { 0x00C46 , 0x00C56 , 0x00C48 },
+ { 0x00CBF , 0x00CD5 , 0x00CC0 },
+ { 0x00CC6 , 0x00CC2 , 0x00CCA },
+ { 0x00CC6 , 0x00CD5 , 0x00CC7 },
+ { 0x00CC6 , 0x00CD6 , 0x00CC8 },
+ { 0x00CCA , 0x00CD5 , 0x00CCB },
+ { 0x00D46 , 0x00D3E , 0x00D4A },
+ { 0x00D46 , 0x00D57 , 0x00D4C },
+ { 0x00D47 , 0x00D3E , 0x00D4B },
+ { 0x00DD9 , 0x00DCA , 0x00DDA },
+ { 0x00DD9 , 0x00DCF , 0x00DDC },
+ { 0x00DD9 , 0x00DDF , 0x00DDE },
+ { 0x00DDC , 0x00DCA , 0x00DDD },
+ { 0x01025 , 0x0102E , 0x01026 },
+ { 0x01B05 , 0x01B35 , 0x01B06 },
+ { 0x01B07 , 0x01B35 , 0x01B08 },
+ { 0x01B09 , 0x01B35 , 0x01B0A },
+ { 0x01B0B , 0x01B35 , 0x01B0C },
+ { 0x01B0D , 0x01B35 , 0x01B0E },
+ { 0x01B11 , 0x01B35 , 0x01B12 },
+ { 0x01B3A , 0x01B35 , 0x01B3B },
+ { 0x01B3C , 0x01B35 , 0x01B3D },
+ { 0x01B3E , 0x01B35 , 0x01B40 },
+ { 0x01B3F , 0x01B35 , 0x01B41 },
+ { 0x01B42 , 0x01B35 , 0x01B43 },
+ { 0x01E36 , 0x00304 , 0x01E38 },
+ { 0x01E37 , 0x00304 , 0x01E39 },
+ { 0x01E5A , 0x00304 , 0x01E5C },
+ { 0x01E5B , 0x00304 , 0x01E5D },
+ { 0x01E62 , 0x00307 , 0x01E68 },
+ { 0x01E63 , 0x00307 , 0x01E69 },
+ { 0x01EA0 , 0x00302 , 0x01EAC },
+ { 0x01EA0 , 0x00306 , 0x01EB6 },
+ { 0x01EA1 , 0x00302 , 0x01EAD },
+ { 0x01EA1 , 0x00306 , 0x01EB7 },
+ { 0x01EB8 , 0x00302 , 0x01EC6 },
+ { 0x01EB9 , 0x00302 , 0x01EC7 },
+ { 0x01ECC , 0x00302 , 0x01ED8 },
+ { 0x01ECD , 0x00302 , 0x01ED9 },
+ { 0x01F00 , 0x00300 , 0x01F02 },
+ { 0x01F00 , 0x00301 , 0x01F04 },
+ { 0x01F00 , 0x00342 , 0x01F06 },
+ { 0x01F00 , 0x00345 , 0x01F80 },
+ { 0x01F01 , 0x00300 , 0x01F03 },
+ { 0x01F01 , 0x00301 , 0x01F05 },
+ { 0x01F01 , 0x00342 , 0x01F07 },
+ { 0x01F01 , 0x00345 , 0x01F81 },
+ { 0x01F02 , 0x00345 , 0x01F82 },
+ { 0x01F03 , 0x00345 , 0x01F83 },
+ { 0x01F04 , 0x00345 , 0x01F84 },
+ { 0x01F05 , 0x00345 , 0x01F85 },
+ { 0x01F06 , 0x00345 , 0x01F86 },
+ { 0x01F07 , 0x00345 , 0x01F87 },
+ { 0x01F08 , 0x00300 , 0x01F0A },
+ { 0x01F08 , 0x00301 , 0x01F0C },
+ { 0x01F08 , 0x00342 , 0x01F0E },
+ { 0x01F08 , 0x00345 , 0x01F88 },
+ { 0x01F09 , 0x00300 , 0x01F0B },
+ { 0x01F09 , 0x00301 , 0x01F0D },
+ { 0x01F09 , 0x00342 , 0x01F0F },
+ { 0x01F09 , 0x00345 , 0x01F89 },
+ { 0x01F0A , 0x00345 , 0x01F8A },
+ { 0x01F0B , 0x00345 , 0x01F8B },
+ { 0x01F0C , 0x00345 , 0x01F8C },
+ { 0x01F0D , 0x00345 , 0x01F8D },
+ { 0x01F0E , 0x00345 , 0x01F8E },
+ { 0x01F0F , 0x00345 , 0x01F8F },
+ { 0x01F10 , 0x00300 , 0x01F12 },
+ { 0x01F10 , 0x00301 , 0x01F14 },
+ { 0x01F11 , 0x00300 , 0x01F13 },
+ { 0x01F11 , 0x00301 , 0x01F15 },
+ { 0x01F18 , 0x00300 , 0x01F1A },
+ { 0x01F18 , 0x00301 , 0x01F1C },
+ { 0x01F19 , 0x00300 , 0x01F1B },
+ { 0x01F19 , 0x00301 , 0x01F1D },
+ { 0x01F20 , 0x00300 , 0x01F22 },
+ { 0x01F20 , 0x00301 , 0x01F24 },
+ { 0x01F20 , 0x00342 , 0x01F26 },
+ { 0x01F20 , 0x00345 , 0x01F90 },
+ { 0x01F21 , 0x00300 , 0x01F23 },
+ { 0x01F21 , 0x00301 , 0x01F25 },
+ { 0x01F21 , 0x00342 , 0x01F27 },
+ { 0x01F21 , 0x00345 , 0x01F91 },
+ { 0x01F22 , 0x00345 , 0x01F92 },
+ { 0x01F23 , 0x00345 , 0x01F93 },
+ { 0x01F24 , 0x00345 , 0x01F94 },
+ { 0x01F25 , 0x00345 , 0x01F95 },
+ { 0x01F26 , 0x00345 , 0x01F96 },
+ { 0x01F27 , 0x00345 , 0x01F97 },
+ { 0x01F28 , 0x00300 , 0x01F2A },
+ { 0x01F28 , 0x00301 , 0x01F2C },
+ { 0x01F28 , 0x00342 , 0x01F2E },
+ { 0x01F28 , 0x00345 , 0x01F98 },
+ { 0x01F29 , 0x00300 , 0x01F2B },
+ { 0x01F29 , 0x00301 , 0x01F2D },
+ { 0x01F29 , 0x00342 , 0x01F2F },
+ { 0x01F29 , 0x00345 , 0x01F99 },
+ { 0x01F2A , 0x00345 , 0x01F9A },
+ { 0x01F2B , 0x00345 , 0x01F9B },
+ { 0x01F2C , 0x00345 , 0x01F9C },
+ { 0x01F2D , 0x00345 , 0x01F9D },
+ { 0x01F2E , 0x00345 , 0x01F9E },
+ { 0x01F2F , 0x00345 , 0x01F9F },
+ { 0x01F30 , 0x00300 , 0x01F32 },
+ { 0x01F30 , 0x00301 , 0x01F34 },
+ { 0x01F30 , 0x00342 , 0x01F36 },
+ { 0x01F31 , 0x00300 , 0x01F33 },
+ { 0x01F31 , 0x00301 , 0x01F35 },
+ { 0x01F31 , 0x00342 , 0x01F37 },
+ { 0x01F38 , 0x00300 , 0x01F3A },
+ { 0x01F38 , 0x00301 , 0x01F3C },
+ { 0x01F38 , 0x00342 , 0x01F3E },
+ { 0x01F39 , 0x00300 , 0x01F3B },
+ { 0x01F39 , 0x00301 , 0x01F3D },
+ { 0x01F39 , 0x00342 , 0x01F3F },
+ { 0x01F40 , 0x00300 , 0x01F42 },
+ { 0x01F40 , 0x00301 , 0x01F44 },
+ { 0x01F41 , 0x00300 , 0x01F43 },
+ { 0x01F41 , 0x00301 , 0x01F45 },
+ { 0x01F48 , 0x00300 , 0x01F4A },
+ { 0x01F48 , 0x00301 , 0x01F4C },
+ { 0x01F49 , 0x00300 , 0x01F4B },
+ { 0x01F49 , 0x00301 , 0x01F4D },
+ { 0x01F50 , 0x00300 , 0x01F52 },
+ { 0x01F50 , 0x00301 , 0x01F54 },
+ { 0x01F50 , 0x00342 , 0x01F56 },
+ { 0x01F51 , 0x00300 , 0x01F53 },
+ { 0x01F51 , 0x00301 , 0x01F55 },
+ { 0x01F51 , 0x00342 , 0x01F57 },
+ { 0x01F59 , 0x00300 , 0x01F5B },
+ { 0x01F59 , 0x00301 , 0x01F5D },
+ { 0x01F59 , 0x00342 , 0x01F5F },
+ { 0x01F60 , 0x00300 , 0x01F62 },
+ { 0x01F60 , 0x00301 , 0x01F64 },
+ { 0x01F60 , 0x00342 , 0x01F66 },
+ { 0x01F60 , 0x00345 , 0x01FA0 },
+ { 0x01F61 , 0x00300 , 0x01F63 },
+ { 0x01F61 , 0x00301 , 0x01F65 },
+ { 0x01F61 , 0x00342 , 0x01F67 },
+ { 0x01F61 , 0x00345 , 0x01FA1 },
+ { 0x01F62 , 0x00345 , 0x01FA2 },
+ { 0x01F63 , 0x00345 , 0x01FA3 },
+ { 0x01F64 , 0x00345 , 0x01FA4 },
+ { 0x01F65 , 0x00345 , 0x01FA5 },
+ { 0x01F66 , 0x00345 , 0x01FA6 },
+ { 0x01F67 , 0x00345 , 0x01FA7 },
+ { 0x01F68 , 0x00300 , 0x01F6A },
+ { 0x01F68 , 0x00301 , 0x01F6C },
+ { 0x01F68 , 0x00342 , 0x01F6E },
+ { 0x01F68 , 0x00345 , 0x01FA8 },
+ { 0x01F69 , 0x00300 , 0x01F6B },
+ { 0x01F69 , 0x00301 , 0x01F6D },
+ { 0x01F69 , 0x00342 , 0x01F6F },
+ { 0x01F69 , 0x00345 , 0x01FA9 },
+ { 0x01F6A , 0x00345 , 0x01FAA },
+ { 0x01F6B , 0x00345 , 0x01FAB },
+ { 0x01F6C , 0x00345 , 0x01FAC },
+ { 0x01F6D , 0x00345 , 0x01FAD },
+ { 0x01F6E , 0x00345 , 0x01FAE },
+ { 0x01F6F , 0x00345 , 0x01FAF },
+ { 0x01F70 , 0x00345 , 0x01FB2 },
+ { 0x01F74 , 0x00345 , 0x01FC2 },
+ { 0x01F7C , 0x00345 , 0x01FF2 },
+ { 0x01FB6 , 0x00345 , 0x01FB7 },
+ { 0x01FBF , 0x00300 , 0x01FCD },
+ { 0x01FBF , 0x00301 , 0x01FCE },
+ { 0x01FBF , 0x00342 , 0x01FCF },
+ { 0x01FC6 , 0x00345 , 0x01FC7 },
+ { 0x01FF6 , 0x00345 , 0x01FF7 },
+ { 0x01FFE , 0x00300 , 0x01FDD },
+ { 0x01FFE , 0x00301 , 0x01FDE },
+ { 0x01FFE , 0x00342 , 0x01FDF },
+ { 0x02190 , 0x00338 , 0x0219A },
+ { 0x02192 , 0x00338 , 0x0219B },
+ { 0x02194 , 0x00338 , 0x021AE },
+ { 0x021D0 , 0x00338 , 0x021CD },
+ { 0x021D2 , 0x00338 , 0x021CF },
+ { 0x021D4 , 0x00338 , 0x021CE },
+ { 0x02203 , 0x00338 , 0x02204 },
+ { 0x02208 , 0x00338 , 0x02209 },
+ { 0x0220B , 0x00338 , 0x0220C },
+ { 0x02223 , 0x00338 , 0x02224 },
+ { 0x02225 , 0x00338 , 0x02226 },
+ { 0x0223C , 0x00338 , 0x02241 },
+ { 0x02243 , 0x00338 , 0x02244 },
+ { 0x02245 , 0x00338 , 0x02247 },
+ { 0x02248 , 0x00338 , 0x02249 },
+ { 0x0224D , 0x00338 , 0x0226D },
+ { 0x02261 , 0x00338 , 0x02262 },
+ { 0x02264 , 0x00338 , 0x02270 },
+ { 0x02265 , 0x00338 , 0x02271 },
+ { 0x02272 , 0x00338 , 0x02274 },
+ { 0x02273 , 0x00338 , 0x02275 },
+ { 0x02276 , 0x00338 , 0x02278 },
+ { 0x02277 , 0x00338 , 0x02279 },
+ { 0x0227A , 0x00338 , 0x02280 },
+ { 0x0227B , 0x00338 , 0x02281 },
+ { 0x0227C , 0x00338 , 0x022E0 },
+ { 0x0227D , 0x00338 , 0x022E1 },
+ { 0x02282 , 0x00338 , 0x02284 },
+ { 0x02283 , 0x00338 , 0x02285 },
+ { 0x02286 , 0x00338 , 0x02288 },
+ { 0x02287 , 0x00338 , 0x02289 },
+ { 0x02291 , 0x00338 , 0x022E2 },
+ { 0x02292 , 0x00338 , 0x022E3 },
+ { 0x022A2 , 0x00338 , 0x022AC },
+ { 0x022A8 , 0x00338 , 0x022AD },
+ { 0x022A9 , 0x00338 , 0x022AE },
+ { 0x022AB , 0x00338 , 0x022AF },
+ { 0x022B2 , 0x00338 , 0x022EA },
+ { 0x022B3 , 0x00338 , 0x022EB },
+ { 0x022B4 , 0x00338 , 0x022EC },
+ { 0x022B5 , 0x00338 , 0x022ED },
+ { 0x03046 , 0x03099 , 0x03094 },
+ { 0x0304B , 0x03099 , 0x0304C },
+ { 0x0304D , 0x03099 , 0x0304E },
+ { 0x0304F , 0x03099 , 0x03050 },
+ { 0x03051 , 0x03099 , 0x03052 },
+ { 0x03053 , 0x03099 , 0x03054 },
+ { 0x03055 , 0x03099 , 0x03056 },
+ { 0x03057 , 0x03099 , 0x03058 },
+ { 0x03059 , 0x03099 , 0x0305A },
+ { 0x0305B , 0x03099 , 0x0305C },
+ { 0x0305D , 0x03099 , 0x0305E },
+ { 0x0305F , 0x03099 , 0x03060 },
+ { 0x03061 , 0x03099 , 0x03062 },
+ { 0x03064 , 0x03099 , 0x03065 },
+ { 0x03066 , 0x03099 , 0x03067 },
+ { 0x03068 , 0x03099 , 0x03069 },
+ { 0x0306F , 0x03099 , 0x03070 },
+ { 0x0306F , 0x0309A , 0x03071 },
+ { 0x03072 , 0x03099 , 0x03073 },
+ { 0x03072 , 0x0309A , 0x03074 },
+ { 0x03075 , 0x03099 , 0x03076 },
+ { 0x03075 , 0x0309A , 0x03077 },
+ { 0x03078 , 0x03099 , 0x03079 },
+ { 0x03078 , 0x0309A , 0x0307A },
+ { 0x0307B , 0x03099 , 0x0307C },
+ { 0x0307B , 0x0309A , 0x0307D },
+ { 0x0309D , 0x03099 , 0x0309E },
+ { 0x030A6 , 0x03099 , 0x030F4 },
+ { 0x030AB , 0x03099 , 0x030AC },
+ { 0x030AD , 0x03099 , 0x030AE },
+ { 0x030AF , 0x03099 , 0x030B0 },
+ { 0x030B1 , 0x03099 , 0x030B2 },
+ { 0x030B3 , 0x03099 , 0x030B4 },
+ { 0x030B5 , 0x03099 , 0x030B6 },
+ { 0x030B7 , 0x03099 , 0x030B8 },
+ { 0x030B9 , 0x03099 , 0x030BA },
+ { 0x030BB , 0x03099 , 0x030BC },
+ { 0x030BD , 0x03099 , 0x030BE },
+ { 0x030BF , 0x03099 , 0x030C0 },
+ { 0x030C1 , 0x03099 , 0x030C2 },
+ { 0x030C4 , 0x03099 , 0x030C5 },
+ { 0x030C6 , 0x03099 , 0x030C7 },
+ { 0x030C8 , 0x03099 , 0x030C9 },
+ { 0x030CF , 0x03099 , 0x030D0 },
+ { 0x030CF , 0x0309A , 0x030D1 },
+ { 0x030D2 , 0x03099 , 0x030D3 },
+ { 0x030D2 , 0x0309A , 0x030D4 },
+ { 0x030D5 , 0x03099 , 0x030D6 },
+ { 0x030D5 , 0x0309A , 0x030D7 },
+ { 0x030D8 , 0x03099 , 0x030D9 },
+ { 0x030D8 , 0x0309A , 0x030DA },
+ { 0x030DB , 0x03099 , 0x030DC },
+ { 0x030DB , 0x0309A , 0x030DD },
+ { 0x030EF , 0x03099 , 0x030F7 },
+ { 0x030F0 , 0x03099 , 0x030F8 },
+ { 0x030F1 , 0x03099 , 0x030F9 },
+ { 0x030F2 , 0x03099 , 0x030FA },
+ { 0x030FD , 0x03099 , 0x030FE },
+ { 0x11099 , 0x110BA , 0x1109A },
+ { 0x1109B , 0x110BA , 0x1109C },
+ { 0x110A5 , 0x110BA , 0x110AB },
+};
+
+#define CANONICAL_CLASS_MIN 0x0300
+#define CANONICAL_CLASS_MAX 0x1D244
+
+#define IS_DECOMPOSABLE_BLOCK(uc) \
+ (((uc)>>8) <= 0x1D2 && u_decomposable_blocks[(uc)>>8])
+static const char u_decomposable_blocks[0x1D2+1] = {
+ 0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,1,1,1,1,1,1,1,0,0,
+ 1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,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,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,1,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,1,1,1,1,1,1,1,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,1,0,0,1,0,
+ 0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,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,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,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,0,0,0,1,1,
+};
+
+/* Get Canonical Combining Class(CCC). */
+#define CCC(uc) \
+ (((uc) > 0x1D244)?0:\
+ ccc_val[ccc_val_index[ccc_index[(uc)>>8]][((uc)>>4)&0x0F]][(uc)&0x0F])
+
+/* The table of the value of Canonical Cimbining Class */
+static const unsigned char ccc_val[][16] = {
+ /* idx=0: XXXX0 - XXXXF */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=1: 00300 - 0030F */
+ {230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230 },
+ /* idx=2: 00310 - 0031F */
+ {230, 230, 230, 230, 230, 232, 220, 220, 220, 220, 232, 216, 220, 220, 220, 220 },
+ /* idx=3: 00320 - 0032F */
+ {220, 202, 202, 220, 220, 220, 220, 202, 202, 220, 220, 220, 220, 220, 220, 220 },
+ /* idx=4: 00330 - 0033F */
+ {220, 220, 220, 220, 1, 1, 1, 1, 1, 220, 220, 220, 220, 230, 230, 230 },
+ /* idx=5: 00340 - 0034F */
+ {230, 230, 230, 230, 230, 240, 230, 220, 220, 220, 230, 230, 230, 220, 220, 0 },
+ /* idx=6: 00350 - 0035F */
+ {230, 230, 230, 220, 220, 220, 220, 230, 232, 220, 220, 230, 233, 234, 234, 233 },
+ /* idx=7: 00360 - 0036F */
+ {234, 234, 233, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230 },
+ /* idx=8: 00480 - 0048F */
+ {0, 0, 0, 230, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=9: 00590 - 0059F */
+ {0, 220, 230, 230, 230, 230, 220, 230, 230, 230, 222, 220, 230, 230, 230, 230 },
+ /* idx=10: 005A0 - 005AF */
+ {230, 230, 220, 220, 220, 220, 220, 220, 230, 230, 220, 230, 230, 222, 228, 230 },
+ /* idx=11: 005B0 - 005BF */
+ {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 0, 23 },
+ /* idx=12: 005C0 - 005CF */
+ {0, 24, 25, 0, 230, 220, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=13: 00610 - 0061F */
+ {230, 230, 230, 230, 230, 230, 230, 230, 30, 31, 32, 0, 0, 0, 0, 0 },
+ /* idx=14: 00640 - 0064F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 28, 29, 30, 31 },
+ /* idx=15: 00650 - 0065F */
+ {32, 33, 34, 230, 230, 220, 220, 230, 230, 230, 230, 230, 220, 230, 230, 220 },
+ /* idx=16: 00670 - 0067F */
+ {35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=17: 006D0 - 006DF */
+ {0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 230, 230, 230, 0, 0, 230 },
+ /* idx=18: 006E0 - 006EF */
+ {230, 230, 230, 220, 230, 0, 0, 230, 230, 0, 220, 230, 230, 220, 0, 0 },
+ /* idx=19: 00710 - 0071F */
+ {0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=20: 00730 - 0073F */
+ {230, 220, 230, 230, 220, 230, 230, 220, 220, 220, 230, 220, 220, 230, 220, 230 },
+ /* idx=21: 00740 - 0074F */
+ {230, 230, 220, 230, 220, 230, 220, 230, 220, 230, 230, 0, 0, 0, 0, 0 },
+ /* idx=22: 007E0 - 007EF */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 230 },
+ /* idx=23: 007F0 - 007FF */
+ {230, 230, 220, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=24: 00810 - 0081F */
+ {0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 0, 230, 230, 230, 230, 230 },
+ /* idx=25: 00820 - 0082F */
+ {230, 230, 230, 230, 0, 230, 230, 230, 0, 230, 230, 230, 230, 230, 0, 0 },
+ /* idx=26: 00850 - 0085F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 220, 220, 0, 0, 0, 0 },
+ /* idx=27: 00930 - 0093F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0 },
+ /* idx=28: 00940 - 0094F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0 },
+ /* idx=29: 00950 - 0095F */
+ {0, 230, 220, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=30: 009B0 - 009BF */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0 },
+ /* idx=31: 009C0 - 009CF */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0 },
+ /* idx=32: 00A30 - 00A3F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0 },
+ /* idx=33: 00A40 - 00A4F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0 },
+ /* idx=34: 00AB0 - 00ABF */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0 },
+ /* idx=35: 00AC0 - 00ACF */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0 },
+ /* idx=36: 00B30 - 00B3F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0 },
+ /* idx=37: 00B40 - 00B4F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0 },
+ /* idx=38: 00BC0 - 00BCF */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0 },
+ /* idx=39: 00C40 - 00C4F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0 },
+ /* idx=40: 00C50 - 00C5F */
+ {0, 0, 0, 0, 0, 84, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=41: 00CB0 - 00CBF */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0 },
+ /* idx=42: 00CC0 - 00CCF */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0 },
+ /* idx=43: 00D40 - 00D4F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0 },
+ /* idx=44: 00DC0 - 00DCF */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0 },
+ /* idx=45: 00E30 - 00E3F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 103, 103, 9, 0, 0, 0, 0, 0 },
+ /* idx=46: 00E40 - 00E4F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 0, 0, 0, 0 },
+ /* idx=47: 00EB0 - 00EBF */
+ {0, 0, 0, 0, 0, 0, 0, 0, 118, 118, 0, 0, 0, 0, 0, 0 },
+ /* idx=48: 00EC0 - 00ECF */
+ {0, 0, 0, 0, 0, 0, 0, 0, 122, 122, 122, 122, 0, 0, 0, 0 },
+ /* idx=49: 00F10 - 00F1F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 220, 220, 0, 0, 0, 0, 0, 0 },
+ /* idx=50: 00F30 - 00F3F */
+ {0, 0, 0, 0, 0, 220, 0, 220, 0, 216, 0, 0, 0, 0, 0, 0 },
+ /* idx=51: 00F70 - 00F7F */
+ {0, 129, 130, 0, 132, 0, 0, 0, 0, 0, 130, 130, 130, 130, 0, 0 },
+ /* idx=52: 00F80 - 00F8F */
+ {130, 0, 230, 230, 9, 0, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=53: 00FC0 - 00FCF */
+ {0, 0, 0, 0, 0, 0, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=54: 01030 - 0103F */
+ {0, 0, 0, 0, 0, 0, 0, 7, 0, 9, 9, 0, 0, 0, 0, 0 },
+ /* idx=55: 01080 - 0108F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 0 },
+ /* idx=56: 01350 - 0135F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230 },
+ /* idx=57: 01710 - 0171F */
+ {0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=58: 01730 - 0173F */
+ {0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=59: 017D0 - 017DF */
+ {0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 0, 0 },
+ /* idx=60: 018A0 - 018AF */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0 },
+ /* idx=61: 01930 - 0193F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 222, 230, 220, 0, 0, 0, 0 },
+ /* idx=62: 01A10 - 01A1F */
+ {0, 0, 0, 0, 0, 0, 0, 230, 220, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=63: 01A60 - 01A6F */
+ {9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=64: 01A70 - 01A7F */
+ {0, 0, 0, 0, 0, 230, 230, 230, 230, 230, 230, 230, 230, 0, 0, 220 },
+ /* idx=65: 01B30 - 01B3F */
+ {0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=66: 01B40 - 01B4F */
+ {0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=67: 01B60 - 01B6F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 220, 230, 230, 230 },
+ /* idx=68: 01B70 - 01B7F */
+ {230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=69: 01BA0 - 01BAF */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0 },
+ /* idx=70: 01BE0 - 01BEF */
+ {0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=71: 01BF0 - 01BFF */
+ {0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=72: 01C30 - 01C3F */
+ {0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=73: 01CD0 - 01CDF */
+ {230, 230, 230, 0, 1, 220, 220, 220, 220, 220, 230, 230, 220, 220, 220, 220 },
+ /* idx=74: 01CE0 - 01CEF */
+ {230, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 220, 0, 0 },
+ /* idx=75: 01DC0 - 01DCF */
+ {230, 230, 220, 230, 230, 230, 230, 230, 230, 230, 220, 230, 230, 234, 214, 220 },
+ /* idx=76: 01DD0 - 01DDF */
+ {202, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230 },
+ /* idx=77: 01DE0 - 01DEF */
+ {230, 230, 230, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=78: 01DF0 - 01DFF */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 233, 220, 230, 220 },
+ /* idx=79: 020D0 - 020DF */
+ {230, 230, 1, 1, 230, 230, 230, 230, 1, 1, 1, 230, 230, 0, 0, 0 },
+ /* idx=80: 020E0 - 020EF */
+ {0, 230, 0, 0, 0, 1, 1, 230, 220, 230, 1, 1, 220, 220, 220, 220 },
+ /* idx=81: 020F0 - 020FF */
+ {230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=82: 02CE0 - 02CEF */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230 },
+ /* idx=83: 02CF0 - 02CFF */
+ {230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=84: 02D70 - 02D7F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9 },
+ /* idx=85: 02DE0 - 02DEF */
+ {230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230 },
+ /* idx=86: 02DF0 - 02DFF */
+ {230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230 },
+ /* idx=87: 03020 - 0302F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 218, 228, 232, 222, 224, 224 },
+ /* idx=88: 03090 - 0309F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0 },
+ /* idx=89: 0A660 - 0A66F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230 },
+ /* idx=90: 0A670 - 0A67F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 0, 0 },
+ /* idx=91: 0A6F0 - 0A6FF */
+ {230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=92: 0A800 - 0A80F */
+ {0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=93: 0A8C0 - 0A8CF */
+ {0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=94: 0A8E0 - 0A8EF */
+ {230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230 },
+ /* idx=95: 0A8F0 - 0A8FF */
+ {230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=96: 0A920 - 0A92F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 220, 220, 0, 0 },
+ /* idx=97: 0A950 - 0A95F */
+ {0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=98: 0A9B0 - 0A9BF */
+ {0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=99: 0A9C0 - 0A9CF */
+ {9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=100: 0AAB0 - 0AABF */
+ {230, 0, 230, 230, 220, 0, 0, 230, 230, 0, 0, 0, 0, 0, 230, 230 },
+ /* idx=101: 0AAC0 - 0AACF */
+ {0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=102: 0ABE0 - 0ABEF */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0 },
+ /* idx=103: 0FB10 - 0FB1F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0 },
+ /* idx=104: 0FE20 - 0FE2F */
+ {230, 230, 230, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=105: 101F0 - 101FF */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 0 },
+ /* idx=106: 10A00 - 10A0F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 230 },
+ /* idx=107: 10A30 - 10A3F */
+ {0, 0, 0, 0, 0, 0, 0, 0, 230, 1, 220, 0, 0, 0, 0, 9 },
+ /* idx=108: 11040 - 1104F */
+ {0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=109: 110B0 - 110BF */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 7, 0, 0, 0, 0, 0 },
+ /* idx=110: 1D160 - 1D16F */
+ {0, 0, 0, 0, 0, 216, 216, 1, 1, 1, 0, 0, 0, 226, 216, 216 },
+ /* idx=111: 1D170 - 1D17F */
+ {216, 216, 216, 0, 0, 0, 0, 0, 0, 0, 0, 220, 220, 220, 220, 220 },
+ /* idx=112: 1D180 - 1D18F */
+ {220, 220, 220, 0, 0, 230, 230, 230, 230, 230, 220, 220, 0, 0, 0, 0 },
+ /* idx=113: 1D1A0 - 1D1AF */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 0, 0 },
+ /* idx=114: 1D240 - 1D24F */
+ {0, 0, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+};
+
+/* The index table to ccc_val[*][16] */
+static const unsigned char ccc_val_index[][16] = {
+ /* idx=0: XXX00 - XXXFF */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=1: 00300 - 003FF */
+ { 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=2: 00400 - 004FF */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=3: 00500 - 005FF */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,10,11,12, 0, 0, 0 },
+ /* idx=4: 00600 - 006FF */
+ { 0,13, 0, 0,14,15, 0,16, 0, 0, 0, 0, 0,17,18, 0 },
+ /* idx=5: 00700 - 007FF */
+ { 0,19, 0,20,21, 0, 0, 0, 0, 0, 0, 0, 0, 0,22,23 },
+ /* idx=6: 00800 - 008FF */
+ { 0,24,25, 0, 0,26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=7: 00900 - 009FF */
+ { 0, 0, 0,27,28,29, 0, 0, 0, 0, 0,30,31, 0, 0, 0 },
+ /* idx=8: 00A00 - 00AFF */
+ { 0, 0, 0,32,33, 0, 0, 0, 0, 0, 0,34,35, 0, 0, 0 },
+ /* idx=9: 00B00 - 00BFF */
+ { 0, 0, 0,36,37, 0, 0, 0, 0, 0, 0, 0,38, 0, 0, 0 },
+ /* idx=10: 00C00 - 00CFF */
+ { 0, 0, 0, 0,39,40, 0, 0, 0, 0, 0,41,42, 0, 0, 0 },
+ /* idx=11: 00D00 - 00DFF */
+ { 0, 0, 0, 0,43, 0, 0, 0, 0, 0, 0, 0,44, 0, 0, 0 },
+ /* idx=12: 00E00 - 00EFF */
+ { 0, 0, 0,45,46, 0, 0, 0, 0, 0, 0,47,48, 0, 0, 0 },
+ /* idx=13: 00F00 - 00FFF */
+ { 0,49, 0,50, 0, 0, 0,51,52, 0, 0, 0,53, 0, 0, 0 },
+ /* idx=14: 01000 - 010FF */
+ { 0, 0, 0,54, 0, 0, 0, 0,55, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=15: 01300 - 013FF */
+ { 0, 0, 0, 0, 0,56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=16: 01700 - 017FF */
+ { 0,57, 0,58, 0, 0, 0, 0, 0, 0, 0, 0, 0,59, 0, 0 },
+ /* idx=17: 01800 - 018FF */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,60, 0, 0, 0, 0, 0 },
+ /* idx=18: 01900 - 019FF */
+ { 0, 0, 0,61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=19: 01A00 - 01AFF */
+ { 0,62, 0, 0, 0, 0,63,64, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=20: 01B00 - 01BFF */
+ { 0, 0, 0,65,66, 0,67,68, 0, 0,69, 0, 0, 0,70,71 },
+ /* idx=21: 01C00 - 01CFF */
+ { 0, 0, 0,72, 0, 0, 0, 0, 0, 0, 0, 0, 0,73,74, 0 },
+ /* idx=22: 01D00 - 01DFF */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,75,76,77,78 },
+ /* idx=23: 02000 - 020FF */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,79,80,81 },
+ /* idx=24: 02C00 - 02CFF */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,82,83 },
+ /* idx=25: 02D00 - 02DFF */
+ { 0, 0, 0, 0, 0, 0, 0,84, 0, 0, 0, 0, 0, 0,85,86 },
+ /* idx=26: 03000 - 030FF */
+ { 0, 0,87, 0, 0, 0, 0, 0, 0,88, 0, 0, 0, 0, 0, 0 },
+ /* idx=27: 0A600 - 0A6FF */
+ { 0, 0, 0, 0, 0, 0,89,90, 0, 0, 0, 0, 0, 0, 0,91 },
+ /* idx=28: 0A800 - 0A8FF */
+ {92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,93, 0,94,95 },
+ /* idx=29: 0A900 - 0A9FF */
+ { 0, 0,96, 0, 0,97, 0, 0, 0, 0, 0,98,99, 0, 0, 0 },
+ /* idx=30: 0AA00 - 0AAFF */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,100,101, 0, 0, 0 },
+ /* idx=31: 0AB00 - 0ABFF */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,102, 0 },
+ /* idx=32: 0FB00 - 0FBFF */
+ { 0,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=33: 0FE00 - 0FEFF */
+ { 0, 0,104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=34: 10100 - 101FF */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,105 },
+ /* idx=35: 10A00 - 10AFF */
+ {106, 0, 0,107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ /* idx=36: 11000 - 110FF */
+ { 0, 0, 0, 0,108, 0, 0, 0, 0, 0, 0,109, 0, 0, 0, 0 },
+ /* idx=37: 1D100 - 1D1FF */
+ { 0, 0, 0, 0, 0, 0,110,111,112, 0,113, 0, 0, 0, 0, 0 },
+ /* idx=38: 1D200 - 1D2FF */
+ { 0, 0, 0, 0,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+};
+
+/* The index table to ccc_val_index[*][16] */
+static const unsigned char ccc_index[] = {
+ 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, 0, 0,15, 0, 0, 0,16,
+ 17,18,19,20,21,22, 0, 0,23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,24,25, 0, 0,
+ 26, 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, 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,27, 0,
+ 28,29,30,31, 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, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,32, 0, 0,33, 0, 0,34, 0, 0, 0, 0, 0, 0,
+ 0, 0,35, 0, 0, 0, 0, 0,36, 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,
+ 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, 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, 0, 0, 0,37,38,};
+
+#endif /* ARCHIVE_STRING_COMPOSITION_H_INCLUDED */
diff --git a/Utilities/cmlibarchive/libarchive/archive_string_sprintf.c b/Utilities/cmlibarchive/libarchive/archive_string_sprintf.c
new file mode 100644
index 000000000..7d7d9713c
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_string_sprintf.c
@@ -0,0 +1,186 @@
+/*-
+ * 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: head/lib/libarchive/archive_string_sprintf.c 189435 2009-03-06 05:14:55Z kientzle $");
+
+/*
+ * The use of printf()-family functions can be troublesome
+ * for space-constrained applications. In addition, correctly
+ * implementing this function in terms of vsnprintf() requires
+ * two calls (one to determine the size, another to format the
+ * result), which in turn requires duplicating the argument list
+ * using va_copy, which isn't yet universally available. <sigh>
+ *
+ * So, I've implemented a bare minimum of printf()-like capability
+ * here. This is only used to format error messages, so doesn't
+ * require any floating-point support or field-width handling.
+ */
+
+#include <stdio.h>
+
+#include "archive_string.h"
+#include "archive_private.h"
+
+/*
+ * Utility functions to format signed/unsigned integers and append
+ * them to an archive_string.
+ */
+static void
+append_uint(struct archive_string *as, uintmax_t d, unsigned base)
+{
+ static const char *digits = "0123456789abcdef";
+ if (d >= base)
+ append_uint(as, d/base, base);
+ archive_strappend_char(as, digits[d % base]);
+}
+
+static void
+append_int(struct archive_string *as, intmax_t d, unsigned base)
+{
+ uintmax_t ud;
+
+ if (d < 0) {
+ archive_strappend_char(as, '-');
+ ud = (d == INTMAX_MIN) ? (uintmax_t)(INTMAX_MAX) + 1 : (uintmax_t)(-d);
+ } else
+ ud = d;
+ append_uint(as, ud, base);
+}
+
+
+void
+archive_string_sprintf(struct archive_string *as, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ archive_string_vsprintf(as, fmt, ap);
+ va_end(ap);
+}
+
+/*
+ * Like 'vsprintf', but ensures the target is big enough, resizing if
+ * necessary.
+ */
+void
+archive_string_vsprintf(struct archive_string *as, const char *fmt,
+ va_list ap)
+{
+ char long_flag;
+ intmax_t s; /* Signed integer temp. */
+ uintmax_t u; /* Unsigned integer temp. */
+ const char *p, *p2;
+ const wchar_t *pw;
+
+ if (archive_string_ensure(as, 64) == NULL)
+ __archive_errx(1, "Out of memory");
+
+ if (fmt == NULL) {
+ as->s[0] = 0;
+ return;
+ }
+
+ for (p = fmt; *p != '\0'; p++) {
+ const char *saved_p = p;
+
+ if (*p != '%') {
+ archive_strappend_char(as, *p);
+ continue;
+ }
+
+ p++;
+
+ long_flag = '\0';
+ switch(*p) {
+ case 'j':
+ case 'l':
+ case 'z':
+ long_flag = *p;
+ p++;
+ break;
+ }
+
+ switch (*p) {
+ case '%':
+ archive_strappend_char(as, '%');
+ break;
+ case 'c':
+ s = va_arg(ap, int);
+ archive_strappend_char(as, s);
+ break;
+ case 'd':
+ switch(long_flag) {
+ case 'j': s = va_arg(ap, intmax_t); break;
+ case 'l': s = va_arg(ap, long); break;
+ case 'z': s = va_arg(ap, ssize_t); break;
+ default: s = va_arg(ap, int); break;
+ }
+ append_int(as, s, 10);
+ break;
+ case 's':
+ switch(long_flag) {
+ case 'l':
+ pw = va_arg(ap, wchar_t *);
+ if (pw == NULL)
+ pw = L"(null)";
+ archive_string_append_from_wcs(as, pw, wcslen(pw));
+ break;
+ default:
+ p2 = va_arg(ap, char *);
+ if (p2 == NULL)
+ p2 = "(null)";
+ archive_strcat(as, p2);
+ break;
+ }
+ break;
+ case 'S':
+ pw = va_arg(ap, wchar_t *);
+ if (pw == NULL)
+ pw = L"(null)";
+ archive_string_append_from_wcs(as, pw, wcslen(pw));
+ break;
+ case 'o': case 'u': case 'x': case 'X':
+ /* Common handling for unsigned integer formats. */
+ switch(long_flag) {
+ case 'j': u = va_arg(ap, uintmax_t); break;
+ case 'l': u = va_arg(ap, unsigned long); break;
+ case 'z': u = va_arg(ap, size_t); break;
+ default: u = va_arg(ap, unsigned int); break;
+ }
+ /* Format it in the correct base. */
+ switch (*p) {
+ case 'o': append_uint(as, u, 8); break;
+ case 'u': append_uint(as, u, 10); break;
+ default: append_uint(as, u, 16); break;
+ }
+ break;
+ default:
+ /* Rewind and print the initial '%' literally. */
+ p = saved_p;
+ archive_strappend_char(as, *p);
+ }
+ }
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_util.3 b/Utilities/cmlibarchive/libarchive/archive_util.3
new file mode 100644
index 000000000..cd05d03f1
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_util.3
@@ -0,0 +1,222 @@
+.\" 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 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: head/lib/libarchive/archive_util.3 201098 2009-12-28 02:58:14Z kientzle $
+.\"
+.Dd January 8, 2005
+.Dt ARCHIVE_UTIL 3
+.Os
+.Sh NAME
+.Nm archive_clear_error ,
+.Nm archive_compression ,
+.Nm archive_compression_name ,
+.Nm archive_copy_error ,
+.Nm archive_errno ,
+.Nm archive_error_string ,
+.Nm archive_file_count ,
+.Nm archive_filter_code ,
+.Nm archive_filter_count ,
+.Nm archive_filter_name ,
+.Nm archive_format ,
+.Nm archive_format_name ,
+.Nm archive_position ,
+.Nm archive_set_error
+.Nd libarchive utility functions
+.Sh SYNOPSIS
+.In archive.h
+.Ft void
+.Fn archive_clear_error "struct archive *"
+.Ft int
+.Fn archive_compression "struct archive *"
+.Ft const char *
+.Fn archive_compression_name "struct archive *"
+.Ft void
+.Fn archive_copy_error "struct archive *" "struct archive *"
+.Ft int
+.Fn archive_errno "struct archive *"
+.Ft const char *
+.Fn archive_error_string "struct archive *"
+.Ft int
+.Fn archive_file_count "struct archive *"
+.Ft int
+.Fn archive_filter_code "struct archive *" "int"
+.Ft int
+.Fn archive_filter_count "struct archive *" "int"
+.Ft const char *
+.Fn archive_filter_name "struct archive *" "int"
+.Ft int
+.Fn archive_format "struct archive *"
+.Ft const char *
+.Fn archive_format_name "struct archive *"
+.Ft int64_t
+.Fn archive_position "struct archive *" "int"
+.Ft void
+.Fo archive_set_error
+.Fa "struct archive *"
+.Fa "int error_code"
+.Fa "const char *fmt"
+.Fa "..."
+.Fc
+.Sh DESCRIPTION
+These functions provide access to various information about the
+.Tn struct archive
+object used in the
+.Xr libarchive 3
+library.
+.Bl -tag -compact -width indent
+.It Fn archive_clear_error
+Clears any error information left over from a previous call.
+Not generally used in client code.
+.It Fn archive_compression
+Synonym for
+.Fn archive_filter_code(a, 0) .
+.It Fn archive_compression_name
+Synonym for
+.Fn archive_filter_name(a, 0) .
+.It Fn archive_copy_error
+Copies error information from one archive to another.
+.It Fn archive_errno
+Returns a numeric error code (see
+.Xr errno 2 )
+indicating the reason for the most recent error return.
+Note that this can not be reliably used to detect whether an
+error has occurred.
+It should be used only after another libarchive function
+has returned an error status.
+.It Fn archive_error_string
+Returns a textual error message suitable for display.
+The error message here is usually more specific than that
+obtained from passing the result of
+.Fn archive_errno
+to
+.Xr strerror 3 .
+.It Fn archive_file_count
+Returns a count of the number of files processed by this archive object.
+The count is incremented by calls to
+.Xr archive_write_header 3
+or
+.Xr archive_read_next_header 3 .
+.It Fn archive_filter_code
+Returns a numeric code identifying the indicated filter.
+See
+.Fn archive_filter_count
+for details of the numbering.
+.It Fn archive_filter_count
+Returns the number of filters in the current pipeline.
+For read archive handles, these filters are added automatically
+by the automatic format detection.
+For write archive handles, these filters are added by calls to the various
+.Fn archive_write_add_filter_XXX
+functions.
+Filters in the resulting pipeline are numbered so that filter 0
+is the filter closest to the format handler.
+As a convenience, functions that expect a filter number will
+accept -1 as a synonym for the highest-numbered filter.
+.Pp
+For example, when reading a uuencoded gzipped tar archive, there
+are three filters:
+filter 0 is the gunzip filter,
+filter 1 is the uudecode filter,
+and filter 2 is the pseudo-filter that wraps the archive read functions.
+In this case, requesting
+.Fn archive_position(a, -1)
+would be a synonym for
+.Fn archive_position(a, 2)
+which would return the number of bytes currently read from the archive, while
+.Fn archive_position(a, 1)
+would return the number of bytes after uudecoding, and
+.Fn archive_position(a, 0)
+would return the number of bytes after decompression.
+.It Fn archive_filter_name
+Returns a textual name identifying the indicated filter.
+See
+.Fn archive_filter_count
+for details of the numbering.
+.It Fn archive_format
+Returns a numeric code indicating the format of the current
+archive entry.
+This value is set by a successful call to
+.Fn archive_read_next_header .
+Note that it is common for this value to change from
+entry to entry.
+For example, a tar archive might have several entries that
+utilize GNU tar extensions and several entries that do not.
+These entries will have different format codes.
+.It Fn archive_format_name
+A textual description of the format of the current entry.
+.It Fn archive_position
+Returns the number of bytes read from or written to the indicated filter.
+In particular,
+.Fn archive_position(a, 0)
+returns the number of bytes read or written by the format handler, while
+.Fn archive_position(a, -1)
+returns the number of bytes read or written to the archive.
+See
+.Fn archive_filter_count
+for details of the numbering here.
+.It Fn archive_set_error
+Sets the numeric error code and error description that will be returned
+by
+.Fn archive_errno
+and
+.Fn archive_error_string .
+This function should be used within I/O callbacks to set system-specific
+error codes and error descriptions.
+This function accepts a printf-like format string and arguments.
+However, you should be careful to use only the following printf
+format specifiers:
+.Dq %c ,
+.Dq %d ,
+.Dq %jd ,
+.Dq %jo ,
+.Dq %ju ,
+.Dq %jx ,
+.Dq %ld ,
+.Dq %lo ,
+.Dq %lu ,
+.Dq %lx ,
+.Dq %o ,
+.Dq %u ,
+.Dq %s ,
+.Dq %x ,
+.Dq %% .
+Field-width specifiers and other printf features are
+not uniformly supported and should not be used.
+.El
+.Sh SEE ALSO
+.Xr archive_read 3 ,
+.Xr archive_write 3 ,
+.Xr libarchive 3 ,
+.Xr printf 3
+.Sh HISTORY
+The
+.Nm libarchive
+library first appeared in
+.Fx 5.3 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm libarchive
+library was written by
+.An Tim Kientzle Aq kientzle@acm.org .
diff --git a/Utilities/cmlibarchive/libarchive/archive_util.c b/Utilities/cmlibarchive/libarchive/archive_util.c
new file mode 100644
index 000000000..e0852a3b5
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_util.c
@@ -0,0 +1,465 @@
+/*-
+ * Copyright (c) 2009,2010 Michihiro NAKAJIMA
+ * 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: head/lib/libarchive/archive_util.c 201098 2009-12-28 02:58:14Z kientzle $");
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#if defined(HAVE_WINCRYPT_H) && !defined(__CYGWIN__)
+#include <wincrypt.h>
+#endif
+
+#include "archive.h"
+#include "archive_private.h"
+#include "archive_string.h"
+
+/* Generic initialization of 'struct archive' objects. */
+int
+__archive_clean(struct archive *a)
+{
+ archive_string_conversion_free(a);
+ return (ARCHIVE_OK);
+}
+
+int
+archive_version_number(void)
+{
+ return (ARCHIVE_VERSION_NUMBER);
+}
+
+const char *
+archive_version_string(void)
+{
+ return (ARCHIVE_VERSION_STRING);
+}
+
+int
+archive_errno(struct archive *a)
+{
+ return (a->archive_error_number);
+}
+
+const char *
+archive_error_string(struct archive *a)
+{
+
+ if (a->error != NULL && *a->error != '\0')
+ return (a->error);
+ else
+ return (NULL);
+}
+
+int
+archive_file_count(struct archive *a)
+{
+ return (a->file_count);
+}
+
+int
+archive_format(struct archive *a)
+{
+ return (a->archive_format);
+}
+
+const char *
+archive_format_name(struct archive *a)
+{
+ return (a->archive_format_name);
+}
+
+
+int
+archive_compression(struct archive *a)
+{
+ return archive_filter_code(a, 0);
+}
+
+const char *
+archive_compression_name(struct archive *a)
+{
+ return archive_filter_name(a, 0);
+}
+
+
+/*
+ * Return a count of the number of compressed bytes processed.
+ */
+int64_t
+archive_position_compressed(struct archive *a)
+{
+ return archive_filter_bytes(a, -1);
+}
+
+/*
+ * Return a count of the number of uncompressed bytes processed.
+ */
+int64_t
+archive_position_uncompressed(struct archive *a)
+{
+ return archive_filter_bytes(a, 0);
+}
+
+void
+archive_clear_error(struct archive *a)
+{
+ archive_string_empty(&a->error_string);
+ a->error = NULL;
+ a->archive_error_number = 0;
+}
+
+void
+archive_set_error(struct archive *a, int error_number, const char *fmt, ...)
+{
+ va_list ap;
+
+ a->archive_error_number = error_number;
+ if (fmt == NULL) {
+ a->error = NULL;
+ return;
+ }
+
+ archive_string_empty(&(a->error_string));
+ va_start(ap, fmt);
+ archive_string_vsprintf(&(a->error_string), fmt, ap);
+ va_end(ap);
+ a->error = a->error_string.s;
+}
+
+void
+archive_copy_error(struct archive *dest, struct archive *src)
+{
+ dest->archive_error_number = src->archive_error_number;
+
+ archive_string_copy(&dest->error_string, &src->error_string);
+ dest->error = dest->error_string.s;
+}
+
+void
+__archive_errx(int retvalue, const char *msg)
+{
+ static const char *msg1 = "Fatal Internal Error in libarchive: ";
+ size_t s;
+
+ s = write(2, msg1, strlen(msg1));
+ (void)s; /* UNUSED */
+ s = write(2, msg, strlen(msg));
+ (void)s; /* UNUSED */
+ s = write(2, "\n", 1);
+ (void)s; /* UNUSED */
+ exit(retvalue);
+}
+
+/*
+ * Create a temporary file
+ */
+#if defined(_WIN32) && !defined(__CYGWIN__)
+
+/*
+ * Do not use Windows tmpfile() function.
+ * It will make a temporary file under the root directory
+ * and it'll cause permission error if a user who is
+ * non-Administrator creates temporary files.
+ * Also Windows version of mktemp family including _mktemp_s
+ * are not secure.
+ */
+int
+__archive_mktemp(const char *tmpdir)
+{
+ 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',
+ L'G', L'H', L'I', L'J', L'K', L'L', L'M', L'N',
+ L'O', L'P', L'Q', L'R', L'S', L'T', L'U', L'V',
+ L'W', L'X', L'Y', L'Z', L'a', L'b', L'c', L'd',
+ L'e', L'f', L'g', L'h', L'i', L'j', L'k', L'l',
+ L'm', L'n', L'o', L'p', L'q', L'r', L's', L't',
+ L'u', L'v', L'w', L'x', L'y', L'z'
+ };
+ HCRYPTPROV hProv;
+ struct archive_wstring temp_name;
+ wchar_t *ws;
+ DWORD attr;
+ wchar_t *xp, *ep;
+ int fd;
+
+ hProv = (HCRYPTPROV)NULL;
+ fd = -1;
+ ws = NULL;
+ archive_string_init(&temp_name);
+
+ /* Get a temporary directory. */
+ if (tmpdir == NULL) {
+ size_t l;
+ wchar_t *tmp;
+
+ l = GetTempPathW(0, NULL);
+ if (l == 0) {
+ la_dosmaperr(GetLastError());
+ goto exit_tmpfile;
+ }
+ tmp = malloc(l*sizeof(wchar_t));
+ if (tmp == NULL) {
+ errno = ENOMEM;
+ goto exit_tmpfile;
+ }
+ GetTempPathW(l, tmp);
+ archive_wstrcpy(&temp_name, tmp);
+ free(tmp);
+ } else {
+ archive_wstring_append_from_mbs(&temp_name, tmpdir,
+ strlen(tmpdir));
+ if (temp_name.s[temp_name.length-1] != L'/')
+ archive_wstrappend_wchar(&temp_name, L'/');
+ }
+
+ /* Check if temp_name is a directory. */
+ attr = GetFileAttributesW(temp_name.s);
+ if (attr == (DWORD)-1) {
+ if (GetLastError() != ERROR_FILE_NOT_FOUND) {
+ la_dosmaperr(GetLastError());
+ goto exit_tmpfile;
+ }
+ ws = __la_win_permissive_name_w(temp_name.s);
+ if (ws == NULL) {
+ errno = EINVAL;
+ goto exit_tmpfile;
+ }
+ attr = GetFileAttributesW(ws);
+ if (attr == (DWORD)-1) {
+ la_dosmaperr(GetLastError());
+ goto exit_tmpfile;
+ }
+ }
+ if (!(attr & FILE_ATTRIBUTE_DIRECTORY)) {
+ errno = ENOTDIR;
+ goto exit_tmpfile;
+ }
+
+ /*
+ * Create a temporary file.
+ */
+ archive_wstrcat(&temp_name, L"libarchive_");
+ xp = temp_name.s + archive_strlen(&temp_name);
+ archive_wstrcat(&temp_name, L"XXXXXXXXXX");
+ ep = temp_name.s + archive_strlen(&temp_name);
+
+ if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
+ CRYPT_VERIFYCONTEXT)) {
+ la_dosmaperr(GetLastError());
+ goto exit_tmpfile;
+ }
+
+ for (;;) {
+ wchar_t *p;
+ HANDLE h;
+
+ /* Generate a random file name through CryptGenRandom(). */
+ p = xp;
+ if (!CryptGenRandom(hProv, (ep - p)*sizeof(wchar_t), (BYTE*)p)) {
+ la_dosmaperr(GetLastError());
+ goto exit_tmpfile;
+ }
+ for (; p < ep; p++)
+ *p = num[((DWORD)*p) % (sizeof(num)/sizeof(num[0]))];
+
+ free(ws);
+ ws = __la_win_permissive_name_w(temp_name.s);
+ if (ws == NULL) {
+ errno = EINVAL;
+ goto exit_tmpfile;
+ }
+ /* Specifies FILE_FLAG_DELETE_ON_CLOSE flag is to
+ * delete this temporary file immediately when this
+ * file closed. */
+ h = CreateFileW(ws,
+ GENERIC_READ | GENERIC_WRITE | DELETE,
+ 0,/* Not share */
+ NULL,
+ CREATE_NEW,/* Create a new file only */
+ FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,
+ NULL);
+ if (h == INVALID_HANDLE_VALUE) {
+ /* The same file already exists. retry with
+ * a new filename. */
+ if (GetLastError() == ERROR_FILE_EXISTS)
+ continue;
+ /* Otherwise, fail creation temporary file. */
+ la_dosmaperr(GetLastError());
+ goto exit_tmpfile;
+ }
+ fd = _open_osfhandle((intptr_t)h, _O_BINARY | _O_RDWR);
+ if (fd == -1) {
+ CloseHandle(h);
+ goto exit_tmpfile;
+ } else
+ break;/* success! */
+ }
+exit_tmpfile:
+ if (hProv != (HCRYPTPROV)NULL)
+ CryptReleaseContext(hProv, 0);
+ free(ws);
+ archive_wstring_free(&temp_name);
+ return (fd);
+}
+
+#else
+
+static int
+get_tempdir(struct archive_string *temppath)
+{
+ const char *tmp;
+
+ tmp = getenv("TMPDIR");
+ if (tmp == NULL)
+#ifdef _PATH_TMP
+ tmp = _PATH_TMP;
+#else
+ tmp = "/tmp";
+#endif
+ archive_strcpy(temppath, tmp);
+ if (temppath->s[temppath->length-1] != '/')
+ archive_strappend_char(temppath, '/');
+ return (ARCHIVE_OK);
+}
+
+#if defined(HAVE_MKSTEMP)
+
+/*
+ * We can use mkstemp().
+ */
+
+int
+__archive_mktemp(const char *tmpdir)
+{
+ struct archive_string temp_name;
+ int fd = -1;
+
+ archive_string_init(&temp_name);
+ if (tmpdir == NULL) {
+ if (get_tempdir(&temp_name) != ARCHIVE_OK)
+ goto exit_tmpfile;
+ } else {
+ archive_strcpy(&temp_name, tmpdir);
+ if (temp_name.s[temp_name.length-1] != '/')
+ archive_strappend_char(&temp_name, '/');
+ }
+ archive_strcat(&temp_name, "libarchive_XXXXXX");
+ fd = mkstemp(temp_name.s);
+ if (fd < 0)
+ goto exit_tmpfile;
+ unlink(temp_name.s);
+exit_tmpfile:
+ archive_string_free(&temp_name);
+ return (fd);
+}
+
+#else
+
+/*
+ * We use a private routine.
+ */
+
+int
+__archive_mktemp(const char *tmpdir)
+{
+ static const char num[] = {
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
+ 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
+ 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
+ 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
+ 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
+ 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
+ 'u', 'v', 'w', 'x', 'y', 'z'
+ };
+ struct archive_string temp_name;
+ struct stat st;
+ int fd;
+ char *tp, *ep;
+ unsigned seed;
+
+ fd = -1;
+ archive_string_init(&temp_name);
+ if (tmpdir == NULL) {
+ if (get_tempdir(&temp_name) != ARCHIVE_OK)
+ goto exit_tmpfile;
+ } else
+ archive_strcpy(&temp_name, tmpdir);
+ if (temp_name.s[temp_name.length-1] == '/') {
+ temp_name.s[temp_name.length-1] = '\0';
+ temp_name.length --;
+ }
+ if (stat(temp_name.s, &st) < 0)
+ goto exit_tmpfile;
+ if (!S_ISDIR(st.st_mode)) {
+ errno = ENOTDIR;
+ goto exit_tmpfile;
+ }
+ archive_strcat(&temp_name, "/libarchive_");
+ tp = temp_name.s + archive_strlen(&temp_name);
+ archive_strcat(&temp_name, "XXXXXXXXXX");
+ ep = temp_name.s + archive_strlen(&temp_name);
+
+ fd = open("/dev/random", O_RDONLY);
+ 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)];
+ fd = open(temp_name.s, O_CREAT | O_EXCL | O_RDWR, 0600);
+ } while (fd < 0 && errno == EEXIST);
+ if (fd < 0)
+ goto exit_tmpfile;
+ unlink(temp_name.s);
+exit_tmpfile:
+ archive_string_free(&temp_name);
+ return (fd);
+}
+
+#endif /* HAVE_MKSTEMP */
+#endif /* !_WIN32 || __CYGWIN__ */
diff --git a/Utilities/cmlibarchive/libarchive/archive_virtual.c b/Utilities/cmlibarchive/libarchive/archive_virtual.c
new file mode 100644
index 000000000..752dc17c2
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_virtual.c
@@ -0,0 +1,147 @@
+/*-
+ * 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: head/lib/libarchive/archive_virtual.c 201098 2009-12-28 02:58:14Z kientzle $");
+
+#include "archive.h"
+#include "archive_entry.h"
+#include "archive_private.h"
+
+int
+archive_filter_code(struct archive *a, int n)
+{
+ return ((a->vtable->archive_filter_code)(a, n));
+}
+
+int
+archive_filter_count(struct archive *a)
+{
+ return ((a->vtable->archive_filter_count)(a));
+}
+
+const char *
+archive_filter_name(struct archive *a, int n)
+{
+ return ((a->vtable->archive_filter_name)(a, n));
+}
+
+int64_t
+archive_filter_bytes(struct archive *a, int n)
+{
+ return ((a->vtable->archive_filter_bytes)(a, n));
+}
+
+int
+archive_write_close(struct archive *a)
+{
+ return ((a->vtable->archive_close)(a));
+}
+
+int
+archive_read_close(struct archive *a)
+{
+ return ((a->vtable->archive_close)(a));
+}
+
+int
+archive_write_free(struct archive *a)
+{
+ return ((a->vtable->archive_free)(a));
+}
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+/* For backwards compatibility; will be removed with libarchive 4.0. */
+int
+archive_write_finish(struct archive *a)
+{
+ return ((a->vtable->archive_free)(a));
+}
+#endif
+
+int
+archive_read_free(struct archive *a)
+{
+ return ((a->vtable->archive_free)(a));
+}
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+/* For backwards compatibility; will be removed with libarchive 4.0. */
+int
+archive_read_finish(struct archive *a)
+{
+ return ((a->vtable->archive_free)(a));
+}
+#endif
+
+int
+archive_write_header(struct archive *a, struct archive_entry *entry)
+{
+ ++a->file_count;
+ return ((a->vtable->archive_write_header)(a, entry));
+}
+
+int
+archive_write_finish_entry(struct archive *a)
+{
+ return ((a->vtable->archive_write_finish_entry)(a));
+}
+
+ssize_t
+archive_write_data(struct archive *a, const void *buff, size_t s)
+{
+ return ((a->vtable->archive_write_data)(a, buff, s));
+}
+
+ssize_t
+archive_write_data_block(struct archive *a, const void *buff, size_t s, int64_t o)
+{
+ if (a->vtable->archive_write_data_block == NULL) {
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "archive_write_data_block not supported");
+ a->state = ARCHIVE_STATE_FATAL;
+ return (ARCHIVE_FATAL);
+ }
+ return ((a->vtable->archive_write_data_block)(a, buff, s, o));
+}
+
+int
+archive_read_next_header(struct archive *a, struct archive_entry **entry)
+{
+ return ((a->vtable->archive_read_next_header)(a, entry));
+}
+
+int
+archive_read_next_header2(struct archive *a, struct archive_entry *entry)
+{
+ return ((a->vtable->archive_read_next_header2)(a, entry));
+}
+
+int
+archive_read_data_block(struct archive *a,
+ const void **buff, size_t *s, int64_t *o)
+{
+ return ((a->vtable->archive_read_data_block)(a, buff, s, o));
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_windows.c b/Utilities/cmlibarchive/libarchive/archive_windows.c
new file mode 100644
index 000000000..8f5d566a5
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_windows.c
@@ -0,0 +1,813 @@
+/*-
+ * Copyright (c) 2009-2011 Michihiro NAKAJIMA
+ * Copyright (c) 2003-2007 Kees Zeelenberg
+ * 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.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * A set of compatibility glue for building libarchive on Windows platforms.
+ *
+ * Originally created as "libarchive-nonposix.c" by Kees Zeelenberg
+ * for the GnuWin32 project, trimmed significantly by Tim Kientzle.
+ *
+ * Much of the original file was unnecessary for libarchive, because
+ * many of the features it emulated were not strictly necessary for
+ * libarchive. I hope for this to shrink further as libarchive
+ * internals are gradually reworked to sit more naturally on both
+ * POSIX and Windows. Any ideas for this are greatly appreciated.
+ *
+ * The biggest remaining issue is the dev/ino emulation; libarchive
+ * has a couple of public APIs that rely on dev/ino uniquely
+ * identifying a file. This doesn't match well with Windows. I'm
+ * considering alternative APIs.
+ */
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+
+#include "archive_platform.h"
+#include "archive_private.h"
+#include <ctype.h>
+#include <errno.h>
+#include <stddef.h>
+#ifdef HAVE_SYS_UTIME_H
+#include <sys/utime.h>
+#endif
+#include <sys/stat.h>
+#include <locale.h>
+#include <process.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <windows.h>
+#include <share.h>
+
+#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
+
+#if defined(__LA_LSEEK_NEEDED)
+static BOOL SetFilePointerEx_perso(HANDLE hFile,
+ LARGE_INTEGER liDistanceToMove,
+ PLARGE_INTEGER lpNewFilePointer,
+ DWORD dwMoveMethod)
+{
+ LARGE_INTEGER li;
+ li.QuadPart = liDistanceToMove.QuadPart;
+ li.LowPart = SetFilePointer(
+ hFile, li.LowPart, &li.HighPart, dwMoveMethod);
+ if(lpNewFilePointer) {
+ lpNewFilePointer->QuadPart = li.QuadPart;
+ }
+ return li.LowPart != -1 || GetLastError() == NO_ERROR;
+}
+#endif
+
+struct ustat {
+ int64_t st_atime;
+ uint32_t st_atime_nsec;
+ int64_t st_ctime;
+ uint32_t st_ctime_nsec;
+ int64_t st_mtime;
+ uint32_t st_mtime_nsec;
+ gid_t st_gid;
+ /* 64bits ino */
+ int64_t st_ino;
+ mode_t st_mode;
+ uint32_t st_nlink;
+ uint64_t st_size;
+ uid_t st_uid;
+ dev_t st_dev;
+ dev_t st_rdev;
+};
+
+/* Transform 64-bits ino into 32-bits by hashing.
+ * You do not forget that really unique number size is 64-bits.
+ */
+#define INOSIZE (8*sizeof(ino_t)) /* 32 */
+static __inline ino_t
+getino(struct ustat *ub)
+{
+ ULARGE_INTEGER ino64;
+ ino64.QuadPart = ub->st_ino;
+ /* I don't know this hashing is correct way */
+ return (ino64.LowPart ^ (ino64.LowPart >> INOSIZE));
+}
+
+/*
+ * Prepend "\\?\" to the path name and convert it to unicode to permit
+ * an extended-length path for a maximum total path length of 32767
+ * characters.
+ * see also http://msdn.microsoft.com/en-us/library/aa365247.aspx
+ */
+wchar_t *
+__la_win_permissive_name(const char *name)
+{
+ wchar_t *wn;
+ wchar_t *ws;
+ size_t ll;
+
+ ll = strlen(name);
+ wn = malloc((ll + 1) * sizeof(wchar_t));
+ if (wn == NULL)
+ return (NULL);
+ ll = mbstowcs(wn, name, ll);
+ if (ll == (size_t)-1) {
+ free(wn);
+ return (NULL);
+ }
+ wn[ll] = L'\0';
+ ws = __la_win_permissive_name_w(wn);
+ free(wn);
+ return (ws);
+}
+
+wchar_t *
+__la_win_permissive_name_w(const wchar_t *wname)
+{
+ wchar_t *wn, *wnp;
+ wchar_t *ws, *wsp;
+ DWORD l, len, slen;
+ int unc;
+
+ /* Get a full-pathname. */
+ l = GetFullPathNameW(wname, 0, NULL, NULL);
+ if (l == 0)
+ return (NULL);
+ /* NOTE: GetFullPathNameW has a bug that if the length of the file
+ * name is just one that return imcomplete buffer size. Thus, we
+ * have to add three to the size to allocate a sufficient buffer
+ * size for the full-pathname of the file name. */
+ l += 3;
+ wnp = malloc(l * sizeof(wchar_t));
+ if (wnp == NULL)
+ return (NULL);
+ len = GetFullPathNameW(wname, l, wnp, NULL);
+ wn = wnp;
+
+ if (wnp[0] == L'\\' && wnp[1] == L'\\' &&
+ wnp[2] == L'?' && wnp[3] == L'\\')
+ /* We have already a permissive name. */
+ return (wn);
+
+ if (wnp[0] == L'\\' && wnp[1] == L'\\' &&
+ wnp[2] == L'.' && wnp[3] == L'\\') {
+ /* This is a device name */
+ if (((wnp[4] >= L'a' && wnp[4] <= L'z') ||
+ (wnp[4] >= L'A' && wnp[4] <= L'Z')) &&
+ wnp[5] == L':' && wnp[6] == L'\\')
+ wnp[2] = L'?';/* Not device name. */
+ return (wn);
+ }
+
+ unc = 0;
+ if (wnp[0] == L'\\' && wnp[1] == L'\\' && wnp[2] != L'\\') {
+ wchar_t *p = &wnp[2];
+
+ /* Skip server-name letters. */
+ while (*p != L'\\' && *p != L'\0')
+ ++p;
+ if (*p == L'\\') {
+ wchar_t *rp = ++p;
+ /* Skip share-name letters. */
+ while (*p != L'\\' && *p != L'\0')
+ ++p;
+ if (*p == L'\\' && p != rp) {
+ /* Now, match patterns such as
+ * "\\server-name\share-name\" */
+ wnp += 2;
+ len -= 2;
+ unc = 1;
+ }
+ }
+ }
+
+ slen = 4 + (unc * 4) + len + 1;
+ ws = wsp = malloc(slen * sizeof(wchar_t));
+ if (ws == NULL) {
+ free(wn);
+ return (NULL);
+ }
+ /* prepend "\\?\" */
+ wcsncpy(wsp, L"\\\\?\\", 4);
+ wsp += 4;
+ slen -= 4;
+ if (unc) {
+ /* append "UNC\" ---> "\\?\UNC\" */
+ wcsncpy(wsp, L"UNC\\", 4);
+ wsp += 4;
+ slen -= 4;
+ }
+ wcsncpy(wsp, wnp, slen);
+ wsp[slen - 1] = L'\0'; /* Ensure null termination. */
+ free(wn);
+ return (ws);
+}
+
+/*
+ * Create a file handle.
+ * This can exceed MAX_PATH limitation.
+ */
+static HANDLE
+la_CreateFile(const char *path, DWORD dwDesiredAccess, DWORD dwShareMode,
+ LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition,
+ DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
+{
+ wchar_t *wpath;
+ HANDLE handle;
+
+ handle = CreateFileA(path, dwDesiredAccess, dwShareMode,
+ lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
+ hTemplateFile);
+ if (handle != INVALID_HANDLE_VALUE)
+ return (handle);
+ if (GetLastError() != ERROR_PATH_NOT_FOUND)
+ return (handle);
+ wpath = __la_win_permissive_name(path);
+ if (wpath == NULL)
+ return (handle);
+ handle = CreateFileW(wpath, dwDesiredAccess, dwShareMode,
+ lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
+ hTemplateFile);
+ free(wpath);
+ return (handle);
+}
+
+#if defined(__LA_LSEEK_NEEDED)
+__int64
+__la_lseek(int fd, __int64 offset, int whence)
+{
+ LARGE_INTEGER distance;
+ LARGE_INTEGER newpointer;
+ HANDLE handle;
+
+ if (fd < 0) {
+ errno = EBADF;
+ return (-1);
+ }
+ handle = (HANDLE)_get_osfhandle(fd);
+ if (GetFileType(handle) != FILE_TYPE_DISK) {
+ errno = EBADF;
+ return (-1);
+ }
+ distance.QuadPart = offset;
+ if (!SetFilePointerEx_perso(handle, distance, &newpointer, whence)) {
+ DWORD lasterr;
+
+ lasterr = GetLastError();
+ if (lasterr == ERROR_BROKEN_PIPE)
+ return (0);
+ if (lasterr == ERROR_ACCESS_DENIED)
+ errno = EBADF;
+ else
+ la_dosmaperr(lasterr);
+ return (-1);
+ }
+ return (newpointer.QuadPart);
+}
+#endif
+
+/* This can exceed MAX_PATH limitation. */
+int
+__la_open(const char *path, int flags, ...)
+{
+ va_list ap;
+ wchar_t *ws;
+ int r, pmode;
+ DWORD attr;
+
+ va_start(ap, flags);
+ pmode = va_arg(ap, int);
+ va_end(ap);
+ ws = NULL;
+ if ((flags & ~O_BINARY) == O_RDONLY) {
+ /*
+ * When we open a directory, _open function returns
+ * "Permission denied" error.
+ */
+ attr = GetFileAttributesA(path);
+ if (attr == (DWORD)-1 && GetLastError() == ERROR_PATH_NOT_FOUND) {
+ ws = __la_win_permissive_name(path);
+ if (ws == NULL) {
+ errno = EINVAL;
+ return (-1);
+ }
+ attr = GetFileAttributesW(ws);
+ }
+ if (attr == (DWORD)-1) {
+ la_dosmaperr(GetLastError());
+ free(ws);
+ return (-1);
+ }
+ if (attr & FILE_ATTRIBUTE_DIRECTORY) {
+ HANDLE handle;
+
+ if (ws != NULL)
+ handle = CreateFileW(ws, 0, 0, NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS |
+ FILE_ATTRIBUTE_READONLY,
+ NULL);
+ else
+ handle = CreateFileA(path, 0, 0, NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS |
+ FILE_ATTRIBUTE_READONLY,
+ NULL);
+ free(ws);
+ if (handle == INVALID_HANDLE_VALUE) {
+ la_dosmaperr(GetLastError());
+ return (-1);
+ }
+ r = _open_osfhandle((intptr_t)handle, _O_RDONLY);
+ return (r);
+ }
+ }
+ if (ws == NULL) {
+#if defined(__BORLANDC__)
+ /* Borland has no mode argument.
+ TODO: Fix mode of new file. */
+ r = _open(path, flags);
+#else
+ r = _open(path, flags, pmode);
+#endif
+ if (r < 0 && errno == EACCES && (flags & O_CREAT) != 0) {
+ /* Simulate other POSIX system action to pass our test suite. */
+ attr = GetFileAttributesA(path);
+ if (attr == (DWORD)-1)
+ la_dosmaperr(GetLastError());
+ else if (attr & FILE_ATTRIBUTE_DIRECTORY)
+ errno = EISDIR;
+ else
+ errno = EACCES;
+ return (-1);
+ }
+ if (r >= 0 || errno != ENOENT)
+ return (r);
+ ws = __la_win_permissive_name(path);
+ if (ws == NULL) {
+ errno = EINVAL;
+ return (-1);
+ }
+ }
+ r = _wopen(ws, flags, pmode);
+ if (r < 0 && errno == EACCES && (flags & O_CREAT) != 0) {
+ /* Simulate other POSIX system action to pass our test suite. */
+ attr = GetFileAttributesW(ws);
+ if (attr == (DWORD)-1)
+ la_dosmaperr(GetLastError());
+ else if (attr & FILE_ATTRIBUTE_DIRECTORY)
+ errno = EISDIR;
+ else
+ errno = EACCES;
+ }
+ free(ws);
+ return (r);
+}
+
+ssize_t
+__la_read(int fd, void *buf, size_t nbytes)
+{
+ HANDLE handle;
+ DWORD bytes_read, lasterr;
+ int r;
+
+#ifdef _WIN64
+ if (nbytes > UINT32_MAX)
+ nbytes = UINT32_MAX;
+#endif
+ if (fd < 0) {
+ errno = EBADF;
+ return (-1);
+ }
+ /* Do not pass 0 to third parameter of ReadFile(), read bytes.
+ * This will not return to application side. */
+ if (nbytes == 0)
+ return (0);
+ handle = (HANDLE)_get_osfhandle(fd);
+ r = ReadFile(handle, buf, (uint32_t)nbytes,
+ &bytes_read, NULL);
+ if (r == 0) {
+ lasterr = GetLastError();
+ if (lasterr == ERROR_NO_DATA) {
+ errno = EAGAIN;
+ return (-1);
+ }
+ if (lasterr == ERROR_BROKEN_PIPE)
+ return (0);
+ if (lasterr == ERROR_ACCESS_DENIED)
+ errno = EBADF;
+ else
+ la_dosmaperr(lasterr);
+ return (-1);
+ }
+ return ((ssize_t)bytes_read);
+}
+
+/* Convert Windows FILETIME to UTC */
+__inline static void
+fileTimeToUTC(const FILETIME *filetime, time_t *time, long *ns)
+{
+ ULARGE_INTEGER utc;
+
+ utc.HighPart = filetime->dwHighDateTime;
+ utc.LowPart = filetime->dwLowDateTime;
+ if (utc.QuadPart >= EPOC_TIME) {
+ utc.QuadPart -= EPOC_TIME;
+ *time = (time_t)(utc.QuadPart / 10000000); /* milli seconds base */
+ *ns = (long)(utc.QuadPart % 10000000) * 100;/* nano seconds base */
+ } else {
+ *time = 0;
+ *ns = 0;
+ }
+}
+
+/* Stat by handle
+ * Windows' stat() does not accept the path added "\\?\" especially "?"
+ * character.
+ * It means we cannot access the long name path longer than MAX_PATH.
+ * So I've implemented simular Windows' stat() to access the long name path.
+ * And I've added some feature.
+ * 1. set st_ino by nFileIndexHigh and nFileIndexLow of
+ * BY_HANDLE_FILE_INFORMATION.
+ * 2. set st_nlink by nNumberOfLinks of BY_HANDLE_FILE_INFORMATION.
+ * 3. set st_dev by dwVolumeSerialNumber by BY_HANDLE_FILE_INFORMATION.
+ */
+static int
+__hstat(HANDLE handle, struct ustat *st)
+{
+ BY_HANDLE_FILE_INFORMATION info;
+ ULARGE_INTEGER ino64;
+ DWORD ftype;
+ mode_t mode;
+ time_t time;
+ long ns;
+
+ switch (ftype = GetFileType(handle)) {
+ case FILE_TYPE_UNKNOWN:
+ errno = EBADF;
+ return (-1);
+ case FILE_TYPE_CHAR:
+ case FILE_TYPE_PIPE:
+ if (ftype == FILE_TYPE_CHAR) {
+ st->st_mode = S_IFCHR;
+ st->st_size = 0;
+ } else {
+ DWORD avail;
+
+ st->st_mode = S_IFIFO;
+ if (PeekNamedPipe(handle, NULL, 0, NULL, &avail, NULL))
+ st->st_size = avail;
+ else
+ st->st_size = 0;
+ }
+ st->st_atime = 0;
+ st->st_atime_nsec = 0;
+ st->st_mtime = 0;
+ st->st_mtime_nsec = 0;
+ st->st_ctime = 0;
+ st->st_ctime_nsec = 0;
+ st->st_ino = 0;
+ st->st_nlink = 1;
+ st->st_uid = 0;
+ st->st_gid = 0;
+ st->st_rdev = 0;
+ st->st_dev = 0;
+ return (0);
+ case FILE_TYPE_DISK:
+ break;
+ default:
+ /* This ftype is undocumented type. */
+ la_dosmaperr(GetLastError());
+ return (-1);
+ }
+
+ ZeroMemory(&info, sizeof(info));
+ if (!GetFileInformationByHandle (handle, &info)) {
+ la_dosmaperr(GetLastError());
+ return (-1);
+ }
+
+ mode = S_IRUSR | S_IRGRP | S_IROTH;
+ if ((info.dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0)
+ mode |= S_IWUSR | S_IWGRP | S_IWOTH;
+ if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
+ else
+ mode |= S_IFREG;
+ st->st_mode = mode;
+
+ fileTimeToUTC(&info.ftLastAccessTime, &time, &ns);
+ st->st_atime = time;
+ st->st_atime_nsec = ns;
+ fileTimeToUTC(&info.ftLastWriteTime, &time, &ns);
+ st->st_mtime = time;
+ st->st_mtime_nsec = ns;
+ fileTimeToUTC(&info.ftCreationTime, &time, &ns);
+ st->st_ctime = time;
+ st->st_ctime_nsec = ns;
+ st->st_size =
+ ((int64_t)(info.nFileSizeHigh) * ((int64_t)MAXDWORD + 1))
+ + (int64_t)(info.nFileSizeLow);
+#ifdef SIMULATE_WIN_STAT
+ st->st_ino = 0;
+ st->st_nlink = 1;
+ st->st_dev = 0;
+#else
+ /* Getting FileIndex as i-node. We should remove a sequence which
+ * is high-16-bits of nFileIndexHigh. */
+ ino64.HighPart = info.nFileIndexHigh & 0x0000FFFFUL;
+ ino64.LowPart = info.nFileIndexLow;
+ st->st_ino = ino64.QuadPart;
+ st->st_nlink = info.nNumberOfLinks;
+ if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ ++st->st_nlink;/* Add parent directory. */
+ st->st_dev = info.dwVolumeSerialNumber;
+#endif
+ st->st_uid = 0;
+ st->st_gid = 0;
+ st->st_rdev = 0;
+ return (0);
+}
+
+static void
+copy_stat(struct stat *st, struct ustat *us)
+{
+ st->st_atime = us->st_atime;
+ st->st_ctime = us->st_ctime;
+ st->st_mtime = us->st_mtime;
+ st->st_gid = us->st_gid;
+ st->st_ino = getino(us);
+ st->st_mode = us->st_mode;
+ st->st_nlink = us->st_nlink;
+ st->st_size = us->st_size;
+ st->st_uid = us->st_uid;
+ st->st_dev = us->st_dev;
+ st->st_rdev = us->st_rdev;
+}
+
+/*
+ * TODO: Remove a use of __la_fstat and __la_stat.
+ * We should use GetFileInformationByHandle in place
+ * where We still use the *stat functions.
+ */
+int
+__la_fstat(int fd, struct stat *st)
+{
+ struct ustat u;
+ int ret;
+
+ if (fd < 0) {
+ errno = EBADF;
+ return (-1);
+ }
+ ret = __hstat((HANDLE)_get_osfhandle(fd), &u);
+ if (ret >= 0) {
+ copy_stat(st, &u);
+ if (u.st_mode & (S_IFCHR | S_IFIFO)) {
+ st->st_dev = fd;
+ st->st_rdev = fd;
+ }
+ }
+ return (ret);
+}
+
+/* This can exceed MAX_PATH limitation. */
+int
+__la_stat(const char *path, struct stat *st)
+{
+ HANDLE handle;
+ struct ustat u;
+ int ret;
+
+ handle = la_CreateFile(path, 0, 0, NULL, OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS,
+ NULL);
+ if (handle == INVALID_HANDLE_VALUE) {
+ la_dosmaperr(GetLastError());
+ return (-1);
+ }
+ ret = __hstat(handle, &u);
+ CloseHandle(handle);
+ if (ret >= 0) {
+ char *p;
+
+ copy_stat(st, &u);
+ p = strrchr(path, '.');
+ if (p != NULL && strlen(p) == 4) {
+ char exttype[4];
+
+ ++ p;
+ exttype[0] = toupper(*p++);
+ exttype[1] = toupper(*p++);
+ exttype[2] = toupper(*p++);
+ exttype[3] = '\0';
+ if (!strcmp(exttype, "EXE") || !strcmp(exttype, "CMD") ||
+ !strcmp(exttype, "BAT") || !strcmp(exttype, "COM"))
+ st->st_mode |= S_IXUSR | S_IXGRP | S_IXOTH;
+ }
+ }
+ return (ret);
+}
+
+/*
+ * This waitpid is limited implementation.
+ */
+pid_t
+__la_waitpid(pid_t wpid, int *status, int option)
+{
+ HANDLE child;
+ DWORD cs, ret;
+
+ (void)option;/* UNUSED */
+ *status = 0;
+ child = OpenProcess(PROCESS_QUERY_INFORMATION | SYNCHRONIZE, FALSE, wpid);
+ if (child == NULL) {
+ la_dosmaperr(GetLastError());
+ return (-1);
+ }
+ ret = WaitForSingleObject(child, INFINITE);
+ if (ret == WAIT_FAILED) {
+ CloseHandle(child);
+ la_dosmaperr(GetLastError());
+ return (-1);
+ }
+ if (GetExitCodeProcess(child, &cs) == 0) {
+ CloseHandle(child);
+ la_dosmaperr(GetLastError());
+ return (-1);
+ }
+ if (cs == STILL_ACTIVE)
+ *status = 0x100;
+ else
+ *status = (int)(cs & 0xff);
+ CloseHandle(child);
+ return (wpid);
+}
+
+ssize_t
+__la_write(int fd, const void *buf, size_t nbytes)
+{
+ DWORD bytes_written;
+
+#ifdef _WIN64
+ if (nbytes > UINT32_MAX)
+ nbytes = UINT32_MAX;
+#endif
+ if (fd < 0) {
+ errno = EBADF;
+ return (-1);
+ }
+ if (!WriteFile((HANDLE)_get_osfhandle(fd), buf, (uint32_t)nbytes,
+ &bytes_written, NULL)) {
+ DWORD lasterr;
+
+ lasterr = GetLastError();
+ if (lasterr == ERROR_ACCESS_DENIED)
+ errno = EBADF;
+ else
+ la_dosmaperr(lasterr);
+ return (-1);
+ }
+ return (bytes_written);
+}
+
+/*
+ * The following function was modified from PostgreSQL sources and is
+ * subject to the copyright below.
+ */
+/*-------------------------------------------------------------------------
+ *
+ * win32error.c
+ * Map win32 error codes to errno values
+ *
+ * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ * $PostgreSQL: pgsql/src/port/win32error.c,v 1.4 2008/01/01 19:46:00 momjian Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+/*
+PostgreSQL Database Management System
+(formerly known as Postgres, then as Postgres95)
+
+Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
+
+Portions Copyright (c) 1994, The Regents of the University of California
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose, without fee, and without a written agreement
+is hereby granted, provided that the above copyright notice and this
+paragraph and the following two paragraphs appear in all copies.
+
+IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
+LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
+DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO
+PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+*/
+
+static const struct {
+ DWORD winerr;
+ int doserr;
+} doserrors[] =
+{
+ { ERROR_INVALID_FUNCTION, EINVAL },
+ { ERROR_FILE_NOT_FOUND, ENOENT },
+ { ERROR_PATH_NOT_FOUND, ENOENT },
+ { ERROR_TOO_MANY_OPEN_FILES, EMFILE },
+ { ERROR_ACCESS_DENIED, EACCES },
+ { ERROR_INVALID_HANDLE, EBADF },
+ { ERROR_ARENA_TRASHED, ENOMEM },
+ { ERROR_NOT_ENOUGH_MEMORY, ENOMEM },
+ { ERROR_INVALID_BLOCK, ENOMEM },
+ { ERROR_BAD_ENVIRONMENT, E2BIG },
+ { ERROR_BAD_FORMAT, ENOEXEC },
+ { ERROR_INVALID_ACCESS, EINVAL },
+ { ERROR_INVALID_DATA, EINVAL },
+ { ERROR_INVALID_DRIVE, ENOENT },
+ { ERROR_CURRENT_DIRECTORY, EACCES },
+ { ERROR_NOT_SAME_DEVICE, EXDEV },
+ { ERROR_NO_MORE_FILES, ENOENT },
+ { ERROR_LOCK_VIOLATION, EACCES },
+ { ERROR_SHARING_VIOLATION, EACCES },
+ { ERROR_BAD_NETPATH, ENOENT },
+ { ERROR_NETWORK_ACCESS_DENIED, EACCES },
+ { ERROR_BAD_NET_NAME, ENOENT },
+ { ERROR_FILE_EXISTS, EEXIST },
+ { ERROR_CANNOT_MAKE, EACCES },
+ { ERROR_FAIL_I24, EACCES },
+ { ERROR_INVALID_PARAMETER, EINVAL },
+ { ERROR_NO_PROC_SLOTS, EAGAIN },
+ { ERROR_DRIVE_LOCKED, EACCES },
+ { ERROR_BROKEN_PIPE, EPIPE },
+ { ERROR_DISK_FULL, ENOSPC },
+ { ERROR_INVALID_TARGET_HANDLE, EBADF },
+ { ERROR_INVALID_HANDLE, EINVAL },
+ { ERROR_WAIT_NO_CHILDREN, ECHILD },
+ { ERROR_CHILD_NOT_COMPLETE, ECHILD },
+ { ERROR_DIRECT_ACCESS_HANDLE, EBADF },
+ { ERROR_NEGATIVE_SEEK, EINVAL },
+ { ERROR_SEEK_ON_DEVICE, EACCES },
+ { ERROR_DIR_NOT_EMPTY, ENOTEMPTY },
+ { ERROR_NOT_LOCKED, EACCES },
+ { ERROR_BAD_PATHNAME, ENOENT },
+ { ERROR_MAX_THRDS_REACHED, EAGAIN },
+ { ERROR_LOCK_FAILED, EACCES },
+ { ERROR_ALREADY_EXISTS, EEXIST },
+ { ERROR_FILENAME_EXCED_RANGE, ENOENT },
+ { ERROR_NESTING_NOT_ALLOWED, EAGAIN },
+ { ERROR_NOT_ENOUGH_QUOTA, ENOMEM }
+};
+
+void
+__la_dosmaperr(unsigned long e)
+{
+ int i;
+
+ if (e == 0)
+ {
+ errno = 0;
+ return;
+ }
+
+ for (i = 0; i < sizeof(doserrors); i++)
+ {
+ if (doserrors[i].winerr == e)
+ {
+ errno = doserrors[i].doserr;
+ return;
+ }
+ }
+
+ /* fprintf(stderr, "unrecognized win32 error code: %lu", e); */
+ errno = EINVAL;
+ return;
+}
+
+#endif /* _WIN32 && !__CYGWIN__ */
diff --git a/Utilities/cmlibarchive/libarchive/archive_windows.h b/Utilities/cmlibarchive/libarchive/archive_windows.h
new file mode 100644
index 000000000..c581af317
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_windows.h
@@ -0,0 +1,297 @@
+/*-
+ * Copyright (c) 2009-2011 Michihiro NAKAJIMA
+ * Copyright (c) 2003-2006 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
+ * in this position and unchanged.
+ * 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __LIBARCHIVE_BUILD
+#error This header is only to be used internally to libarchive.
+#endif
+
+/*
+ * TODO: A lot of stuff in here isn't actually used by libarchive and
+ * can be trimmed out. Note that this file is used by libarchive and
+ * libarchive_test but nowhere else. (But note that it gets compiled
+ * with many different Windows environments, including MinGW, Visual
+ * Studio, and Cygwin. Significant changes should be tested in all three.)
+ */
+
+/*
+ * TODO: Don't use off_t in here. Use __int64 instead. Note that
+ * Visual Studio and the Windows SDK define off_t as 32 bits; Win32's
+ * more modern file handling APIs all use __int64 instead of off_t.
+ */
+
+#ifndef LIBARCHIVE_ARCHIVE_WINDOWS_H_INCLUDED
+#define LIBARCHIVE_ARCHIVE_WINDOWS_H_INCLUDED
+
+/* Start of configuration for native Win32 */
+
+#include <errno.h>
+#define set_errno(val) ((errno)=val)
+#include <io.h>
+#include <stdlib.h> //brings in NULL
+#if defined(HAVE_STDINT_H)
+#include <stdint.h>
+#endif
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <process.h>
+#include <direct.h>
+#if defined(__MINGW32__) && defined(HAVE_UNISTD_H)
+/* Prevent build error from a type mismatch of ftruncate().
+ * This unistd.h defines it as ftruncate(int, off_t). */
+#include <unistd.h>
+#endif
+#define NOCRYPT
+#include <windows.h>
+//#define EFTYPE 7
+
+#if defined(_MSC_VER)
+/* TODO: Fix the code, don't suppress the warnings. */
+#pragma warning(push,1)
+#pragma warning(disable:4761) /* integral size mismatch in argument; conversion supplied */
+#endif
+#if defined(__BORLANDC__)
+#pragma warn -8068 /* Constant out of range in comparison. */
+#pragma warn -8072 /* Suspicious pointer arithmetic. */
+#endif
+
+#ifndef NULL
+#ifdef __cplusplus
+#define NULL 0
+#else
+#define NULL ((void *)0)
+#endif
+#endif
+
+/* Alias the Windows _function to the POSIX equivalent. */
+#define close _close
+#define fcntl(fd, cmd, flg) /* No operation. */
+#ifndef fileno
+#define fileno _fileno
+#endif
+#define fstat __la_fstat
+#if !defined(__BORLANDC__)
+#define lseek _lseeki64
+#else
+#define lseek __la_lseek
+#define __LA_LSEEK_NEEDED
+#endif
+#define lstat __la_stat
+#define open __la_open
+#define read __la_read
+#if !defined(__BORLANDC__)
+#define setmode _setmode
+#endif
+#define stat(path,stref) __la_stat(path,stref)
+#if !defined(__BORLANDC__)
+#define strdup _strdup
+#endif
+#define tzset _tzset
+#if !defined(__BORLANDC__)
+#define umask _umask
+#endif
+#define waitpid __la_waitpid
+#define write __la_write
+
+#ifndef O_RDONLY
+#define O_RDONLY _O_RDONLY
+#define O_WRONLY _O_WRONLY
+#define O_TRUNC _O_TRUNC
+#define O_CREAT _O_CREAT
+#define O_EXCL _O_EXCL
+#define O_BINARY _O_BINARY
+#endif
+
+#ifndef _S_IFIFO
+ #define _S_IFIFO 0010000 /* pipe */
+#endif
+#ifndef _S_IFCHR
+ #define _S_IFCHR 0020000 /* character special */
+#endif
+#ifndef _S_IFDIR
+ #define _S_IFDIR 0040000 /* directory */
+#endif
+#ifndef _S_IFBLK
+ #define _S_IFBLK 0060000 /* block special */
+#endif
+#ifndef _S_IFLNK
+ #define _S_IFLNK 0120000 /* symbolic link */
+#endif
+#ifndef _S_IFSOCK
+ #define _S_IFSOCK 0140000 /* socket */
+#endif
+#ifndef _S_IFREG
+ #define _S_IFREG 0100000 /* regular */
+#endif
+#ifndef _S_IFMT
+ #define _S_IFMT 0170000 /* file type mask */
+#endif
+
+#ifndef S_IFIFO
+#define S_IFIFO _S_IFIFO
+#endif
+//#define S_IFCHR _S_IFCHR
+//#define S_IFDIR _S_IFDIR
+#ifndef S_IFBLK
+#define S_IFBLK _S_IFBLK
+#endif
+#ifndef S_IFLNK
+#define S_IFLNK _S_IFLNK
+#endif
+#ifndef S_IFSOCK
+#define S_IFSOCK _S_IFSOCK
+#endif
+//#define S_IFREG _S_IFREG
+//#define S_IFMT _S_IFMT
+
+#ifndef S_ISBLK
+#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) /* block special */
+#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) /* fifo or socket */
+#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) /* char special */
+#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 */
+
+#define _S_ISUID 0004000 /* set user id on execution */
+#define _S_ISGID 0002000 /* set group id on execution */
+#define _S_ISVTX 0001000 /* save swapped text even after use */
+
+#define S_ISUID _S_ISUID
+#define S_ISGID _S_ISGID
+#define S_ISVTX _S_ISVTX
+
+#define _S_IRWXU (_S_IREAD | _S_IWRITE | _S_IEXEC)
+#define _S_IXUSR _S_IEXEC /* read permission, user */
+#define _S_IWUSR _S_IWRITE /* write permission, user */
+#define _S_IRUSR _S_IREAD /* execute/search permission, user */
+#define _S_IRWXG (_S_IRWXU >> 3)
+#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_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 */
+
+#ifndef S_IRWXU
+#define S_IRWXU _S_IRWXU
+#define S_IXUSR _S_IXUSR
+#define S_IWUSR _S_IWUSR
+#define S_IRUSR _S_IRUSR
+#endif
+#define S_IRWXG _S_IRWXG
+#define S_IXGRP _S_IXGRP
+#define S_IWGRP _S_IWGRP
+#define S_IRGRP _S_IRGRP
+#define S_IRWXO _S_IRWXO
+#define S_IXOTH _S_IXOTH
+#define S_IWOTH _S_IWOTH
+#define S_IROTH _S_IROTH
+
+#define F_DUPFD 0 /* Duplicate file descriptor. */
+#define F_GETFD 1 /* Get file descriptor flags. */
+#define F_SETFD 2 /* Set file descriptor flags. */
+#define F_GETFL 3 /* Get file status flags. */
+#define F_SETFL 4 /* Set file status flags. */
+#define F_GETOWN 5 /* Get owner (receiver of SIGIO). */
+#define F_SETOWN 6 /* Set owner (receiver of SIGIO). */
+#define F_GETLK 7 /* Get record locking info. */
+#define F_SETLK 8 /* Set record locking info (non-blocking). */
+#define F_SETLKW 9 /* Set record locking info (blocking). */
+
+/* XXX missing */
+#define F_GETLK64 7 /* Get record locking info. */
+#define F_SETLK64 8 /* Set record locking info (non-blocking). */
+#define F_SETLKW64 9 /* Set record locking info (blocking). */
+
+/* File descriptor flags used with F_GETFD and F_SETFD. */
+#define FD_CLOEXEC 1 /* Close on exec. */
+
+//NOT SURE IF O_NONBLOCK is OK here but at least the 0x0004 flag is not used by anything else...
+#define O_NONBLOCK 0x0004 /* Non-blocking I/O. */
+//#define O_NDELAY O_NONBLOCK
+
+/* Symbolic constants for the access() function */
+#if !defined(F_OK)
+ #define R_OK 4 /* Test for read permission */
+ #define W_OK 2 /* Test for write permission */
+ #define X_OK 1 /* Test for execute permission */
+ #define F_OK 0 /* Test for existence of file */
+#endif
+
+
+/* Replacement POSIX function */
+extern int __la_fstat(int fd, struct stat *st);
+extern int __la_lstat(const char *path, struct stat *st);
+#if defined(__LA_LSEEK_NEEDED)
+extern __int64 __la_lseek(int fd, __int64 offset, int whence);
+#endif
+extern int __la_open(const char *path, int flags, ...);
+extern ssize_t __la_read(int fd, void *buf, size_t nbytes);
+extern int __la_stat(const char *path, struct stat *st);
+extern pid_t __la_waitpid(pid_t wpid, int *status, int option);
+extern ssize_t __la_write(int fd, const void *buf, size_t nbytes);
+
+#define _stat64i32(path, st) __la_stat(path, st)
+#define _stat64(path, st) __la_stat(path, st)
+/* for status returned by la_waitpid */
+#define WIFEXITED(sts) ((sts & 0x100) == 0)
+#define WEXITSTATUS(sts) (sts & 0x0FF)
+
+extern wchar_t *__la_win_permissive_name(const char *name);
+extern wchar_t *__la_win_permissive_name_w(const wchar_t *wname);
+extern void __la_dosmaperr(unsigned long e);
+#define la_dosmaperr(e) __la_dosmaperr(e)
+
+#if defined(HAVE_WCRTOMB) && defined(__BORLANDC__)
+typedef int mbstate_t;
+size_t wcrtomb(char *, wchar_t, mbstate_t *);
+#endif
+
+#if defined(_MSC_VER) && _MSC_VER < 1300
+WINBASEAPI BOOL WINAPI GetVolumePathNameW(
+ LPCWSTR lpszFileName,
+ LPWSTR lpszVolumePathName,
+ DWORD cchBufferLength
+ );
+# if _WIN32_WINNT < 0x0500 /* windows.h not providing 0x500 API */
+typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
+ LARGE_INTEGER FileOffset;
+ LARGE_INTEGER Length;
+} FILE_ALLOCATED_RANGE_BUFFER, *PFILE_ALLOCATED_RANGE_BUFFER;
+# define FSCTL_SET_SPARSE \
+ CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 49, METHOD_BUFFERED, FILE_WRITE_DATA)
+# define FSCTL_QUERY_ALLOCATED_RANGES \
+ CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 51, METHOD_NEITHER, FILE_READ_DATA)
+# endif
+#endif
+
+#endif /* LIBARCHIVE_ARCHIVE_WINDOWS_H_INCLUDED */
diff --git a/Utilities/cmlibarchive/libarchive/archive_write.3 b/Utilities/cmlibarchive/libarchive/archive_write.3
new file mode 100644
index 000000000..f87386a8b
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write.3
@@ -0,0 +1,261 @@
+.\" Copyright (c) 2003-2011 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 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: head/lib/libarchive/archive_write.3 201110 2009-12-28 03:31:29Z kientzle $
+.\"
+.Dd March 23, 2011
+.Dt ARCHIVE_WRITE 3
+.Os
+.Sh NAME
+.Nm archive_write
+.Nd functions for creating archives
+.Sh SYNOPSIS
+.In archive.h
+.Sh DESCRIPTION
+These functions provide a complete API for creating streaming
+archive files.
+The general process is to first create the
+.Tn struct archive
+object, set any desired options, initialize the archive, append entries, then
+close the archive and release all resources.
+.\"
+.Ss Create archive object
+See
+.Xr archive_write_new 3 .
+.Pp
+To write an archive, you must first obtain an initialized
+.Tn struct archive
+object from
+.Fn archive_write_new .
+.\"
+.Ss Enable filters and formats, configure block size and padding
+See
+.Xr archive_write_filter 3 ,
+.Xr archive_write_format 3
+and
+.Xr archive_write_blocksize 3 .
+.Pp
+You can then modify this object for the desired operations with the
+various
+.Fn archive_write_set_XXX
+functions.
+In particular, you will need to invoke appropriate
+.Fn archive_write_add_XXX
+and
+.Fn archive_write_set_XXX
+functions to enable the corresponding compression and format
+support.
+.\"
+.Ss Set options
+See
+.Xr archive_read_set_options 3 .
+.\"
+.Ss Open archive
+See
+.Xr archive_write_open 3 .
+.Pp
+Once you have prepared the
+.Tn struct archive
+object, you call
+.Fn archive_write_open
+to actually open the archive and prepare it for writing.
+There are several variants of this function;
+the most basic expects you to provide pointers to several
+functions that can provide blocks of bytes from the archive.
+There are convenience forms that allow you to
+specify a filename, file descriptor,
+.Ft "FILE *"
+object, or a block of memory from which to write the archive data.
+.\"
+.Ss Produce archive
+See
+.Xr archive_write_header 3
+and
+.Xr archive_write_data 3 .
+.Pp
+Individual archive entries are written in a three-step
+process:
+You first initialize a
+.Tn struct archive_entry
+structure with information about the new entry.
+At a minimum, you should set the pathname of the
+entry and provide a
+.Va struct stat
+with a valid
+.Va st_mode
+field, which specifies the type of object and
+.Va st_size
+field, which specifies the size of the data portion of the object.
+.\"
+.Ss Release resources
+See
+.Xr archive_write_free 3 .
+.Pp
+After all entries have been written, use the
+.Fn archive_write_free
+function to release all resources.
+.\"
+.Sh EXAMPLE
+The following sketch illustrates basic usage of the library.
+In this example,
+the callback functions are simply wrappers around the standard
+.Xr open 2 ,
+.Xr write 2 ,
+and
+.Xr close 2
+system calls.
+.Bd -literal -offset indent
+#ifdef __linux__
+#define _FILE_OFFSET_BITS 64
+#endif
+#include <sys/stat.h>
+#include <archive.h>
+#include <archive_entry.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+struct mydata {
+ const char *name;
+ int fd;
+};
+
+int
+myopen(struct archive *a, void *client_data)
+{
+ struct mydata *mydata = client_data;
+
+ mydata->fd = open(mydata->name, O_WRONLY | O_CREAT, 0644);
+ if (mydata->fd >= 0)
+ return (ARCHIVE_OK);
+ else
+ return (ARCHIVE_FATAL);
+}
+
+ssize_t
+mywrite(struct archive *a, void *client_data, const void *buff, size_t n)
+{
+ struct mydata *mydata = client_data;
+
+ return (write(mydata->fd, buff, n));
+}
+
+int
+myclose(struct archive *a, void *client_data)
+{
+ struct mydata *mydata = client_data;
+
+ if (mydata->fd > 0)
+ close(mydata->fd);
+ return (0);
+}
+
+void
+write_archive(const char *outname, const char **filename)
+{
+ struct mydata *mydata = malloc(sizeof(struct mydata));
+ struct archive *a;
+ struct archive_entry *entry;
+ struct stat st;
+ char buff[8192];
+ int len;
+ int fd;
+
+ a = archive_write_new();
+ mydata->name = outname;
+ 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);
+ entry = archive_entry_new();
+ archive_entry_copy_stat(entry, &st);
+ archive_entry_set_pathname(entry, *filename);
+ archive_write_header(a, entry);
+ if ((fd = open(*filename, O_RDONLY)) != -1) {
+ len = read(fd, buff, sizeof(buff));
+ while ( len > 0 ) {
+ archive_write_data(a, buff, len);
+ len = read(fd, buff, sizeof(buff));
+ }
+ close(fd);
+ }
+ archive_entry_free(entry);
+ filename++;
+ }
+ archive_write_free(a);
+}
+
+int main(int argc, const char **argv)
+{
+ const char *outname;
+ argv++;
+ outname = argv++;
+ write_archive(outname, argv);
+ return 0;
+}
+.Ed
+.Sh SEE ALSO
+.Xr tar 1 ,
+.Xr libarchive 3 ,
+.Xr archive_write_set_options 3 ,
+.Xr cpio 5 ,
+.Xr mtree 5 ,
+.Xr tar 5
+.Sh HISTORY
+The
+.Nm libarchive
+library first appeared in
+.Fx 5.3 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm libarchive
+library was written by
+.An Tim Kientzle Aq kientzle@acm.org .
+.Sh BUGS
+There are many peculiar bugs in historic tar implementations that may cause
+certain programs to reject archives written by this library.
+For example, several historic implementations calculated header checksums
+incorrectly and will thus reject valid archives; GNU tar does not fully support
+pax interchange format; some old tar implementations required specific
+field terminations.
+.Pp
+The default pax interchange format eliminates most of the historic
+tar limitations and provides a generic key/value attribute facility
+for vendor-defined extensions.
+One oversight in POSIX is the failure to provide a standard attribute
+for large device numbers.
+This library uses
+.Dq SCHILY.devminor
+and
+.Dq SCHILY.devmajor
+for device numbers that exceed the range supported by the backwards-compatible
+ustar header.
+These keys are compatible with Joerg Schilling's
+.Nm star
+archiver.
+Other implementations may not recognize these keys and will thus be unable
+to correctly restore device nodes with large device numbers from archives
+created by this library.
diff --git a/Utilities/cmlibarchive/libarchive/archive_write.c b/Utilities/cmlibarchive/libarchive/archive_write.c
new file mode 100644
index 000000000..b4b3867f0
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write.c
@@ -0,0 +1,709 @@
+/*-
+ * Copyright (c) 2003-2010 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: head/lib/libarchive/archive_write.c 201099 2009-12-28 03:03:00Z kientzle $");
+
+/*
+ * This file contains the "essential" portions of the write API, that
+ * is, stuff that will essentially always be used by any client that
+ * actually needs to write an archive. Optional pieces have been, as
+ * far as possible, separated out into separate files to reduce
+ * needlessly bloating statically-linked clients.
+ */
+
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#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
+#include <time.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "archive.h"
+#include "archive_entry.h"
+#include "archive_private.h"
+#include "archive_write_private.h"
+
+static struct archive_vtable *archive_write_vtable(void);
+
+static int _archive_filter_code(struct archive *, int);
+static const char *_archive_filter_name(struct archive *, int);
+static int64_t _archive_filter_bytes(struct archive *, int);
+static int _archive_write_filter_count(struct archive *);
+static int _archive_write_close(struct archive *);
+static int _archive_write_free(struct archive *);
+static int _archive_write_header(struct archive *, struct archive_entry *);
+static int _archive_write_finish_entry(struct archive *);
+static ssize_t _archive_write_data(struct archive *, const void *, size_t);
+
+struct archive_none {
+ size_t buffer_size;
+ size_t avail;
+ char *buffer;
+ char *next;
+};
+
+static struct archive_vtable *
+archive_write_vtable(void)
+{
+ static struct archive_vtable av;
+ static int inited = 0;
+
+ if (!inited) {
+ av.archive_close = _archive_write_close;
+ av.archive_filter_bytes = _archive_filter_bytes;
+ av.archive_filter_code = _archive_filter_code;
+ av.archive_filter_name = _archive_filter_name;
+ av.archive_filter_count = _archive_write_filter_count;
+ av.archive_free = _archive_write_free;
+ av.archive_write_header = _archive_write_header;
+ av.archive_write_finish_entry = _archive_write_finish_entry;
+ av.archive_write_data = _archive_write_data;
+ inited = 1;
+ }
+ return (&av);
+}
+
+/*
+ * Allocate, initialize and return an archive object.
+ */
+struct archive *
+archive_write_new(void)
+{
+ struct archive_write *a;
+ unsigned char *nulls;
+
+ a = (struct archive_write *)malloc(sizeof(*a));
+ if (a == NULL)
+ return (NULL);
+ memset(a, 0, sizeof(*a));
+ a->archive.magic = ARCHIVE_WRITE_MAGIC;
+ a->archive.state = ARCHIVE_STATE_NEW;
+ a->archive.vtable = archive_write_vtable();
+ /*
+ * The value 10240 here matches the traditional tar default,
+ * but is otherwise arbitrary.
+ * TODO: Set the default block size from the format selected.
+ */
+ a->bytes_per_block = 10240;
+ a->bytes_in_last_block = -1; /* Default */
+
+ /* Initialize a block of nulls for padding purposes. */
+ a->null_length = 1024;
+ nulls = (unsigned char *)malloc(a->null_length);
+ if (nulls == NULL) {
+ free(a);
+ return (NULL);
+ }
+ memset(nulls, 0, a->null_length);
+ a->nulls = nulls;
+ return (&a->archive);
+}
+
+/*
+ * Set the block size. Returns 0 if successful.
+ */
+int
+archive_write_set_bytes_per_block(struct archive *_a, int bytes_per_block)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_bytes_per_block");
+ a->bytes_per_block = bytes_per_block;
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Get the current block size. -1 if it has never been set.
+ */
+int
+archive_write_get_bytes_per_block(struct archive *_a)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_write_get_bytes_per_block");
+ return (a->bytes_per_block);
+}
+
+/*
+ * Set the size for the last block.
+ * Returns 0 if successful.
+ */
+int
+archive_write_set_bytes_in_last_block(struct archive *_a, int bytes)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_write_set_bytes_in_last_block");
+ a->bytes_in_last_block = bytes;
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Return the value set above. -1 indicates it has not been set.
+ */
+int
+archive_write_get_bytes_in_last_block(struct archive *_a)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_write_get_bytes_in_last_block");
+ return (a->bytes_in_last_block);
+}
+
+/*
+ * dev/ino of a file to be rejected. Used to prevent adding
+ * an archive to itself recursively.
+ */
+int
+archive_write_set_skip_file(struct archive *_a, int64_t d, int64_t i)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_write_set_skip_file");
+ a->skip_file_set = 1;
+ a->skip_file_dev = d;
+ a->skip_file_ino = i;
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Allocate and return the next filter structure.
+ */
+struct archive_write_filter *
+__archive_write_allocate_filter(struct archive *_a)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ struct archive_write_filter *f;
+
+ f = calloc(1, sizeof(*f));
+ f->archive = _a;
+ if (a->filter_first == NULL)
+ a->filter_first = f;
+ else
+ a->filter_last->next_filter = f;
+ a->filter_last = f;
+ return f;
+}
+
+/*
+ * Write data to a particular filter.
+ */
+int
+__archive_write_filter(struct archive_write_filter *f,
+ const void *buff, size_t length)
+{
+ int r;
+ if (length == 0)
+ return(ARCHIVE_OK);
+ r = (f->write)(f, buff, length);
+ f->bytes_written += length;
+ return (r);
+}
+
+/*
+ * Open a filter.
+ */
+int
+__archive_write_open_filter(struct archive_write_filter *f)
+{
+ if (f->open == NULL)
+ return (ARCHIVE_OK);
+ return (f->open)(f);
+}
+
+/*
+ * Close a filter.
+ */
+int
+__archive_write_close_filter(struct archive_write_filter *f)
+{
+ if (f->close != NULL)
+ return (f->close)(f);
+ if (f->next_filter != NULL)
+ return (__archive_write_close_filter(f->next_filter));
+ return (ARCHIVE_OK);
+}
+
+int
+__archive_write_output(struct archive_write *a, const void *buff, size_t length)
+{
+ return (__archive_write_filter(a->filter_first, buff, length));
+}
+
+int
+__archive_write_nulls(struct archive_write *a, size_t length)
+{
+ if (length == 0)
+ return (ARCHIVE_OK);
+
+ while (length > 0) {
+ size_t to_write = length < a->null_length ? length : a->null_length;
+ int r = __archive_write_output(a, a->nulls, to_write);
+ if (r < ARCHIVE_OK)
+ return (r);
+ length -= to_write;
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_write_client_open(struct archive_write_filter *f)
+{
+ struct archive_write *a = (struct archive_write *)f->archive;
+ struct archive_none *state;
+ void *buffer;
+ size_t buffer_size;
+
+ f->bytes_per_block = archive_write_get_bytes_per_block(f->archive);
+ f->bytes_in_last_block =
+ archive_write_get_bytes_in_last_block(f->archive);
+ buffer_size = f->bytes_per_block;
+
+ state = (struct archive_none *)calloc(1, sizeof(*state));
+ buffer = (char *)malloc(buffer_size);
+ if (state == NULL || buffer == NULL) {
+ free(state);
+ free(buffer);
+ archive_set_error(f->archive, ENOMEM,
+ "Can't allocate data for output buffering");
+ return (ARCHIVE_FATAL);
+ }
+
+ state->buffer_size = buffer_size;
+ state->buffer = buffer;
+ state->next = state->buffer;
+ state->avail = state->buffer_size;
+ f->data = state;
+
+ if (a->client_opener == NULL)
+ return (ARCHIVE_OK);
+ return (a->client_opener(f->archive, a->client_data));
+}
+
+static int
+archive_write_client_write(struct archive_write_filter *f,
+ const void *_buff, size_t length)
+{
+ struct archive_write *a = (struct archive_write *)f->archive;
+ struct archive_none *state = (struct archive_none *)f->data;
+ const char *buff = (const char *)_buff;
+ ssize_t remaining, to_copy;
+ ssize_t bytes_written;
+
+ remaining = length;
+
+ /*
+ * If there is no buffer for blocking, just pass the data
+ * straight through to the client write callback. In
+ * particular, this supports "no write delay" operation for
+ * special applications. Just set the block size to zero.
+ */
+ if (state->buffer_size == 0) {
+ while (remaining > 0) {
+ bytes_written = (a->client_writer)(&a->archive,
+ a->client_data, buff, remaining);
+ if (bytes_written <= 0)
+ return (ARCHIVE_FATAL);
+ remaining -= bytes_written;
+ buff += bytes_written;
+ }
+ return (ARCHIVE_OK);
+ }
+
+ /* If the copy buffer isn't empty, try to fill it. */
+ if (state->avail < state->buffer_size) {
+ /* If buffer is not empty... */
+ /* ... copy data into buffer ... */
+ to_copy = ((size_t)remaining > state->avail) ?
+ state->avail : (size_t)remaining;
+ memcpy(state->next, buff, to_copy);
+ state->next += to_copy;
+ state->avail -= to_copy;
+ buff += to_copy;
+ remaining -= to_copy;
+ /* ... if it's full, write it out. */
+ if (state->avail == 0) {
+ char *p = state->buffer;
+ size_t to_write = state->buffer_size;
+ while (to_write > 0) {
+ bytes_written = (a->client_writer)(&a->archive,
+ a->client_data, p, to_write);
+ if (bytes_written <= 0)
+ return (ARCHIVE_FATAL);
+ if ((size_t)bytes_written > to_write) {
+ archive_set_error(&(a->archive),
+ -1, "write overrun");
+ return (ARCHIVE_FATAL);
+ }
+ p += bytes_written;
+ to_write -= bytes_written;
+ }
+ state->next = state->buffer;
+ state->avail = state->buffer_size;
+ }
+ }
+
+ while ((size_t)remaining > state->buffer_size) {
+ /* Write out full blocks directly to client. */
+ bytes_written = (a->client_writer)(&a->archive,
+ a->client_data, buff, state->buffer_size);
+ if (bytes_written <= 0)
+ return (ARCHIVE_FATAL);
+ buff += bytes_written;
+ remaining -= bytes_written;
+ }
+
+ if (remaining > 0) {
+ /* Copy last bit into copy buffer. */
+ memcpy(state->next, buff, remaining);
+ state->next += remaining;
+ state->avail -= remaining;
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_write_client_close(struct archive_write_filter *f)
+{
+ struct archive_write *a = (struct archive_write *)f->archive;
+ struct archive_none *state = (struct archive_none *)f->data;
+ ssize_t block_length;
+ ssize_t target_block_length;
+ ssize_t bytes_written;
+ int ret = ARCHIVE_OK;
+
+ /* If there's pending data, pad and write the last block */
+ if (state->next != state->buffer) {
+ block_length = state->buffer_size - state->avail;
+
+ /* Tricky calculation to determine size of last block */
+ if (a->bytes_in_last_block <= 0)
+ /* Default or Zero: pad to full block */
+ target_block_length = a->bytes_per_block;
+ else
+ /* Round to next multiple of bytes_in_last_block. */
+ target_block_length = a->bytes_in_last_block *
+ ( (block_length + a->bytes_in_last_block - 1) /
+ a->bytes_in_last_block);
+ if (target_block_length > a->bytes_per_block)
+ target_block_length = a->bytes_per_block;
+ if (block_length < target_block_length) {
+ memset(state->next, 0,
+ target_block_length - block_length);
+ block_length = target_block_length;
+ }
+ bytes_written = (a->client_writer)(&a->archive,
+ a->client_data, state->buffer, block_length);
+ ret = bytes_written <= 0 ? ARCHIVE_FATAL : ARCHIVE_OK;
+ }
+ if (a->client_closer)
+ (*a->client_closer)(&a->archive, a->client_data);
+ free(state->buffer);
+ free(state);
+ a->client_data = NULL;
+ return (ret);
+}
+
+/*
+ * Open the archive using the current settings.
+ */
+int
+archive_write_open(struct archive *_a, void *client_data,
+ archive_open_callback *opener, archive_write_callback *writer,
+ archive_close_callback *closer)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ struct archive_write_filter *client_filter;
+ int ret, r1;
+
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_open");
+ archive_clear_error(&a->archive);
+
+ a->client_writer = writer;
+ a->client_opener = opener;
+ a->client_closer = closer;
+ a->client_data = client_data;
+
+ client_filter = __archive_write_allocate_filter(_a);
+ client_filter->open = archive_write_client_open;
+ client_filter->write = archive_write_client_write;
+ client_filter->close = archive_write_client_close;
+
+ ret = __archive_write_open_filter(a->filter_first);
+ if (ret < ARCHIVE_WARN) {
+ r1 = __archive_write_close_filter(a->filter_first);
+ return (r1 < ret ? r1 : ret);
+ }
+
+ a->archive.state = ARCHIVE_STATE_HEADER;
+ if (a->format_init)
+ ret = (a->format_init)(a);
+ return (ret);
+}
+
+/*
+ * Close out the archive.
+ */
+static int
+_archive_write_close(struct archive *_a)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ int r = ARCHIVE_OK, r1 = ARCHIVE_OK;
+
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL,
+ "archive_write_close");
+ if (a->archive.state == ARCHIVE_STATE_NEW
+ || a->archive.state == ARCHIVE_STATE_CLOSED)
+ return (ARCHIVE_OK); /* Okay to close() when not open. */
+
+ archive_clear_error(&a->archive);
+
+ /* Finish the last entry. */
+ if (a->archive.state == ARCHIVE_STATE_DATA)
+ r = ((a->format_finish_entry)(a));
+
+ /* Finish off the archive. */
+ /* TODO: have format closers invoke compression close. */
+ if (a->format_close != NULL) {
+ r1 = (a->format_close)(a);
+ if (r1 < r)
+ r = r1;
+ }
+
+ /* Finish the compression and close the stream. */
+ r1 = __archive_write_close_filter(a->filter_first);
+ if (r1 < r)
+ r = r1;
+
+ if (a->archive.state != ARCHIVE_STATE_FATAL)
+ a->archive.state = ARCHIVE_STATE_CLOSED;
+ return (r);
+}
+
+static int
+_archive_write_filter_count(struct archive *_a)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ struct archive_write_filter *p = a->filter_first;
+ int count = 0;
+ while(p) {
+ count++;
+ p = p->next_filter;
+ }
+ return count;
+}
+
+void
+__archive_write_filters_free(struct archive *_a)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ int r = ARCHIVE_OK, r1;
+
+ while (a->filter_first != NULL) {
+ struct archive_write_filter *next
+ = a->filter_first->next_filter;
+ if (a->filter_first->free != NULL) {
+ r1 = (*a->filter_first->free)(a->filter_first);
+ if (r > r1)
+ r = r1;
+ }
+ free(a->filter_first);
+ a->filter_first = next;
+ }
+ a->filter_last = NULL;
+}
+
+/*
+ * Destroy the archive structure.
+ *
+ * Be careful: user might just call write_new and then write_free.
+ * Don't assume we actually wrote anything or performed any non-trivial
+ * initialization.
+ */
+static int
+_archive_write_free(struct archive *_a)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ int r = ARCHIVE_OK, r1;
+
+ if (_a == NULL)
+ return (ARCHIVE_OK);
+ /* It is okay to call free() in state FATAL. */
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_write_free");
+ if (a->archive.state != ARCHIVE_STATE_FATAL)
+ r = archive_write_close(&a->archive);
+
+ /* Release format resources. */
+ if (a->format_free != NULL) {
+ r1 = (a->format_free)(a);
+ if (r1 < r)
+ r = r1;
+ }
+
+ __archive_write_filters_free(_a);
+
+ /* Release various dynamic buffers. */
+ free((void *)(uintptr_t)(const void *)a->nulls);
+ archive_string_free(&a->archive.error_string);
+ a->archive.magic = 0;
+ __archive_clean(&a->archive);
+ free(a);
+ return (r);
+}
+
+/*
+ * Write the appropriate header.
+ */
+static int
+_archive_write_header(struct archive *_a, struct archive_entry *entry)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ int ret, r2;
+
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_DATA | ARCHIVE_STATE_HEADER, "archive_write_header");
+ archive_clear_error(&a->archive);
+
+ if (a->format_write_header == NULL) {
+ archive_set_error(&(a->archive), -1,
+ "Format must be set before you can write to an archive.");
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ return (ARCHIVE_FATAL);
+ }
+
+ /* In particular, "retry" and "fatal" get returned immediately. */
+ ret = archive_write_finish_entry(&a->archive);
+ if (ret == ARCHIVE_FATAL) {
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ return (ARCHIVE_FATAL);
+ }
+ if (ret < ARCHIVE_OK && ret != ARCHIVE_WARN)
+ return (ret);
+
+ if (a->skip_file_set &&
+ archive_entry_dev_is_set(entry) &&
+ archive_entry_ino_is_set(entry) &&
+ archive_entry_dev(entry) == a->skip_file_dev &&
+ archive_entry_ino64(entry) == a->skip_file_ino) {
+ archive_set_error(&a->archive, 0,
+ "Can't add archive to itself");
+ return (ARCHIVE_FAILED);
+ }
+
+ /* Format and write header. */
+ r2 = ((a->format_write_header)(a, entry));
+ if (r2 == ARCHIVE_FATAL) {
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ return (ARCHIVE_FATAL);
+ }
+ if (r2 < ret)
+ ret = r2;
+
+ a->archive.state = ARCHIVE_STATE_DATA;
+ return (ret);
+}
+
+static int
+_archive_write_finish_entry(struct archive *_a)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ int ret = ARCHIVE_OK;
+
+ 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)
+ ret = (a->format_finish_entry)(a);
+ a->archive.state = ARCHIVE_STATE_HEADER;
+ return (ret);
+}
+
+/*
+ * Note that the compressor is responsible for blocking.
+ */
+static ssize_t
+_archive_write_data(struct archive *_a, const void *buff, size_t s)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_DATA, "archive_write_data");
+ archive_clear_error(&a->archive);
+ return ((a->format_write_data)(a, buff, s));
+}
+
+static struct archive_write_filter *
+filter_lookup(struct archive *_a, int n)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ struct archive_write_filter *f = a->filter_first;
+ if (n == -1)
+ return a->filter_last;
+ if (n < 0)
+ return NULL;
+ while (n > 0 && f != NULL) {
+ f = f->next_filter;
+ --n;
+ }
+ return f;
+}
+
+static int
+_archive_filter_code(struct archive *_a, int n)
+{
+ struct archive_write_filter *f = filter_lookup(_a, n);
+ return f == NULL ? -1 : f->code;
+}
+
+static const char *
+_archive_filter_name(struct archive *_a, int n)
+{
+ struct archive_write_filter *f = filter_lookup(_a, n);
+ return f != NULL ? f->name : NULL;
+}
+
+static int64_t
+_archive_filter_bytes(struct archive *_a, int n)
+{
+ struct archive_write_filter *f = filter_lookup(_a, n);
+ return f == NULL ? -1 : f->bytes_written;
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_bzip2.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_bzip2.c
new file mode 100644
index 000000000..096a6a4c7
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_bzip2.c
@@ -0,0 +1,335 @@
+/*-
+ * 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: head/lib/libarchive/archive_write_set_compression_bzip2.c 201091 2009-12-28 02:22:41Z kientzle $");
+
+#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_BZLIB_H
+#include <cm_bzlib.h>
+#endif
+
+#include "archive.h"
+#include "archive_private.h"
+#include "archive_write_private.h"
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+int
+archive_write_set_compression_bzip2(struct archive *a)
+{
+ __archive_write_filters_free(a);
+ return (archive_write_add_filter_bzip2(a));
+}
+#endif
+
+#if !defined(HAVE_BZLIB_H) || !defined(BZ_CONFIG_ERROR)
+int
+archive_write_add_filter_bzip2(struct archive *a)
+{
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "bzip2 compression not supported on this platform");
+ return (ARCHIVE_FATAL);
+}
+#else
+/* Don't compile this if we don't have bzlib. */
+
+struct private_data {
+ int compression_level;
+ bz_stream stream;
+ int64_t total_in;
+ char *compressed;
+ size_t compressed_buffer_size;
+};
+
+/*
+ * Yuck. bzlib.h is not const-correct, so I need this one bit
+ * of ugly hackery to convert a const * pointer to a non-const pointer.
+ */
+#define SET_NEXT_IN(st,src) \
+ (st)->stream.next_in = (char *)(uintptr_t)(const void *)(src)
+
+static int archive_compressor_bzip2_close(struct archive_write_filter *);
+static int archive_compressor_bzip2_free(struct archive_write_filter *);
+static int archive_compressor_bzip2_open(struct archive_write_filter *);
+static int archive_compressor_bzip2_options(struct archive_write_filter *,
+ const char *, const char *);
+static int archive_compressor_bzip2_write(struct archive_write_filter *,
+ const void *, size_t);
+static int drive_compressor(struct archive_write_filter *,
+ struct private_data *, int finishing);
+
+/*
+ * Add a bzip2 compression filter to this write handle.
+ */
+int
+archive_write_add_filter_bzip2(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_bzip2");
+
+ data = calloc(1, sizeof(*data));
+ if (data == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
+ data->compression_level = 9; /* default */
+
+ f->data = data;
+ f->options = &archive_compressor_bzip2_options;
+ f->close = &archive_compressor_bzip2_close;
+ f->free = &archive_compressor_bzip2_free;
+ f->open = &archive_compressor_bzip2_open;
+ f->code = ARCHIVE_COMPRESSION_BZIP2;
+ f->name = "bzip2";
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Setup callback.
+ */
+static int
+archive_compressor_bzip2_open(struct archive_write_filter *f)
+{
+ struct private_data *data = (struct private_data *)f->data;
+ int ret;
+
+ ret = __archive_write_open_filter(f->next_filter);
+ if (ret != 0)
+ return (ret);
+
+ /* TODO: Find a better way to size this. (Maybe look at the */
+ /* block size expected by the following filter?) */
+ if (data->compressed == NULL) {
+ data->compressed_buffer_size = 65536;
+ data->compressed
+ = (char *)malloc(data->compressed_buffer_size);
+ if (data->compressed == NULL) {
+ archive_set_error(f->archive, ENOMEM,
+ "Can't allocate data for compression buffer");
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ memset(&data->stream, 0, sizeof(data->stream));
+ data->stream.next_out = data->compressed;
+ data->stream.avail_out = data->compressed_buffer_size;
+ f->write = archive_compressor_bzip2_write;
+
+ /* Initialize compression library */
+ ret = BZ2_bzCompressInit(&(data->stream),
+ data->compression_level, 0, 30);
+ if (ret == BZ_OK) {
+ f->data = data;
+ return (ARCHIVE_OK);
+ }
+
+ /* Library setup failed: clean up. */
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "Internal error initializing compression library");
+
+ /* Override the error message if we know what really went wrong. */
+ switch (ret) {
+ case BZ_PARAM_ERROR:
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "Internal error initializing compression library: "
+ "invalid setup parameter");
+ break;
+ case BZ_MEM_ERROR:
+ archive_set_error(f->archive, ENOMEM,
+ "Internal error initializing compression library: "
+ "out of memory");
+ break;
+ case BZ_CONFIG_ERROR:
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "Internal error initializing compression library: "
+ "mis-compiled library");
+ break;
+ }
+
+ return (ARCHIVE_FATAL);
+
+}
+
+/*
+ * Set write options.
+ */
+static int
+archive_compressor_bzip2_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] >= '0' && value[0] <= '9') ||
+ value[1] != '\0')
+ return (ARCHIVE_WARN);
+ data->compression_level = value[0] - '0';
+ /* Make '0' be a synonym for '1'. */
+ /* This way, bzip2 compressor supports the same 0..9
+ * range of levels as gzip. */
+ if (data->compression_level < 1)
+ data->compression_level = 1;
+ return (ARCHIVE_OK);
+ }
+
+ return (ARCHIVE_WARN);
+}
+
+/*
+ * Write data to the compressed stream.
+ *
+ * Returns ARCHIVE_OK if all data written, error otherwise.
+ */
+static int
+archive_compressor_bzip2_write(struct archive_write_filter *f,
+ const void *buff, size_t length)
+{
+ struct private_data *data = (struct private_data *)f->data;
+
+ /* Update statistics */
+ data->total_in += length;
+
+ /* Compress input data to output buffer */
+ SET_NEXT_IN(data, buff);
+ data->stream.avail_in = length;
+ if (drive_compressor(f, data, 0))
+ return (ARCHIVE_FATAL);
+ return (ARCHIVE_OK);
+}
+
+
+/*
+ * Finish the compression.
+ */
+static int
+archive_compressor_bzip2_close(struct archive_write_filter *f)
+{
+ struct private_data *data = (struct private_data *)f->data;
+ int ret, r1;
+
+ /* Finish compression cycle. */
+ ret = drive_compressor(f, data, 1);
+ if (ret == ARCHIVE_OK) {
+ /* Write the last block */
+ ret = __archive_write_filter(f->next_filter,
+ data->compressed,
+ data->compressed_buffer_size - data->stream.avail_out);
+ }
+
+ switch (BZ2_bzCompressEnd(&(data->stream))) {
+ case BZ_OK:
+ break;
+ default:
+ archive_set_error(f->archive, ARCHIVE_ERRNO_PROGRAMMER,
+ "Failed to clean up compressor");
+ ret = ARCHIVE_FATAL;
+ }
+
+ r1 = __archive_write_close_filter(f->next_filter);
+ return (r1 < ret ? r1 : ret);
+}
+
+static int
+archive_compressor_bzip2_free(struct archive_write_filter *f)
+{
+ struct private_data *data = (struct private_data *)f->data;
+ free(data->compressed);
+ free(data);
+ f->data = NULL;
+ return (ARCHIVE_OK);
+}
+
+/*
+ * 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,
+ struct private_data *data, int finishing)
+{
+ int ret;
+
+ for (;;) {
+ if (data->stream.avail_out == 0) {
+ ret = __archive_write_filter(f->next_filter,
+ data->compressed,
+ data->compressed_buffer_size);
+ if (ret != ARCHIVE_OK) {
+ /* TODO: Handle this write failure */
+ return (ARCHIVE_FATAL);
+ }
+ data->stream.next_out = data->compressed;
+ data->stream.avail_out = data->compressed_buffer_size;
+ }
+
+ /* If there's nothing to do, we're done. */
+ if (!finishing && data->stream.avail_in == 0)
+ return (ARCHIVE_OK);
+
+ ret = BZ2_bzCompress(&(data->stream),
+ finishing ? BZ_FINISH : BZ_RUN);
+
+ switch (ret) {
+ case BZ_RUN_OK:
+ /* In non-finishing case, did compressor
+ * consume everything? */
+ if (!finishing && data->stream.avail_in == 0)
+ return (ARCHIVE_OK);
+ break;
+ case BZ_FINISH_OK: /* Finishing: There's more work to do */
+ break;
+ case BZ_STREAM_END: /* Finishing: all done */
+ /* Only occurs in finishing case */
+ return (ARCHIVE_OK);
+ default:
+ /* Any other return value indicates an error */
+ archive_set_error(f->archive,
+ ARCHIVE_ERRNO_PROGRAMMER,
+ "Bzip2 compression failed;"
+ " BZ2_bzCompress() returned %d",
+ ret);
+ return (ARCHIVE_FATAL);
+ }
+ }
+}
+
+#endif /* HAVE_BZLIB_H && BZ_CONFIG_ERROR */
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_compress.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_compress.c
new file mode 100644
index 000000000..465ff0e77
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_compress.c
@@ -0,0 +1,445 @@
+/*-
+ * Copyright (c) 2008 Joerg Sonnenberger
+ * 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.
+ */
+
+/*-
+ * Copyright (c) 1985, 1986, 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Diomidis Spinellis and James A. Woods, derived from original
+ * work by Spencer Thomas and Joseph Orost.
+ *
+ * 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 University 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 REGENTS 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 REGENTS 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 "archive_platform.h"
+
+__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_compression_compress.c 201111 2009-12-28 03:33:05Z kientzle $");
+
+#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_private.h"
+#include "archive_write_private.h"
+
+#define HSIZE 69001 /* 95% occupancy */
+#define HSHIFT 8 /* 8 - trunc(log2(HSIZE / 65536)) */
+#define CHECK_GAP 10000 /* Ratio check interval. */
+
+#define MAXCODE(bits) ((1 << (bits)) - 1)
+
+/*
+ * the next two codes should not be changed lightly, as they must not
+ * lie within the contiguous general code space.
+ */
+#define FIRST 257 /* First free entry. */
+#define CLEAR 256 /* Table clear output code. */
+
+struct private_data {
+ int64_t in_count, out_count, checkpoint;
+
+ int code_len; /* Number of bits/code. */
+ int cur_maxcode; /* Maximum code, given n_bits. */
+ int max_maxcode; /* Should NEVER generate this code. */
+ int hashtab [HSIZE];
+ unsigned short codetab [HSIZE];
+ int first_free; /* First unused entry. */
+ int compress_ratio;
+
+ int cur_code, cur_fcode;
+
+ int bit_offset;
+ unsigned char bit_buf;
+
+ unsigned char *compressed;
+ size_t compressed_buffer_size;
+ size_t compressed_offset;
+};
+
+static int archive_compressor_compress_open(struct archive_write_filter *);
+static int archive_compressor_compress_write(struct archive_write_filter *,
+ const void *, size_t);
+static int archive_compressor_compress_close(struct archive_write_filter *);
+static int archive_compressor_compress_free(struct archive_write_filter *);
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+int
+archive_write_set_compression_compress(struct archive *a)
+{
+ __archive_write_filters_free(a);
+ return (archive_write_add_filter_compress(a));
+}
+#endif
+
+/*
+ * Add a compress filter to this write handle.
+ */
+int
+archive_write_add_filter_compress(struct archive *_a)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ struct archive_write_filter *f = __archive_write_allocate_filter(_a);
+
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_add_filter_compress");
+ f->open = &archive_compressor_compress_open;
+ f->code = ARCHIVE_COMPRESSION_COMPRESS;
+ f->name = "compress";
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Setup callback.
+ */
+static int
+archive_compressor_compress_open(struct archive_write_filter *f)
+{
+ int ret;
+ struct private_data *state;
+
+ f->code = ARCHIVE_COMPRESSION_COMPRESS;
+ f->name = "compress";
+
+ ret = __archive_write_open_filter(f->next_filter);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+
+ state = (struct private_data *)calloc(1, sizeof(*state));
+ if (state == NULL) {
+ archive_set_error(f->archive, ENOMEM,
+ "Can't allocate data for compression");
+ return (ARCHIVE_FATAL);
+ }
+
+ state->compressed_buffer_size = 65536;
+ state->compressed = malloc(state->compressed_buffer_size);
+
+ if (state->compressed == NULL) {
+ archive_set_error(f->archive, ENOMEM,
+ "Can't allocate data for compression buffer");
+ free(state);
+ return (ARCHIVE_FATAL);
+ }
+
+ f->write = archive_compressor_compress_write;
+ f->close = archive_compressor_compress_close;
+ f->free = archive_compressor_compress_free;
+
+ state->max_maxcode = 0x10000; /* Should NEVER generate this code. */
+ state->in_count = 0; /* Length of input. */
+ state->bit_buf = 0;
+ state->bit_offset = 0;
+ state->out_count = 3; /* Includes 3-byte header mojo. */
+ state->compress_ratio = 0;
+ state->checkpoint = CHECK_GAP;
+ state->code_len = 9;
+ state->cur_maxcode = MAXCODE(state->code_len);
+ state->first_free = FIRST;
+
+ memset(state->hashtab, 0xff, sizeof(state->hashtab));
+
+ /* Prime output buffer with a gzip header. */
+ state->compressed[0] = 0x1f; /* Compress */
+ state->compressed[1] = 0x9d;
+ state->compressed[2] = 0x90; /* Block mode, 16bit max */
+ state->compressed_offset = 3;
+
+ f->data = state;
+ return (0);
+}
+
+/*-
+ * Output the given code.
+ * Inputs:
+ * code: A n_bits-bit integer. If == -1, then EOF. This assumes
+ * that n_bits <= (long)wordsize - 1.
+ * Outputs:
+ * Outputs code to the file.
+ * Assumptions:
+ * Chars are 8 bits long.
+ * Algorithm:
+ * Maintain a BITS character long buffer (so that 8 codes will
+ * fit in it exactly). Use the VAX insv instruction to insert each
+ * code in turn. When the buffer fills up empty it and start over.
+ */
+
+static const unsigned char rmask[9] =
+ {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
+
+static int
+output_byte(struct archive_write_filter *f, unsigned char c)
+{
+ struct private_data *state = f->data;
+
+ state->compressed[state->compressed_offset++] = c;
+ ++state->out_count;
+
+ if (state->compressed_buffer_size == state->compressed_offset) {
+ int ret = __archive_write_filter(f->next_filter,
+ state->compressed, state->compressed_buffer_size);
+ if (ret != ARCHIVE_OK)
+ return ARCHIVE_FATAL;
+ state->compressed_offset = 0;
+ }
+
+ return ARCHIVE_OK;
+}
+
+static int
+output_code(struct archive_write_filter *f, int ocode)
+{
+ struct private_data *state = f->data;
+ int bits, ret, clear_flg, bit_offset;
+
+ clear_flg = ocode == CLEAR;
+
+ /*
+ * Since ocode is always >= 8 bits, only need to mask the first
+ * hunk on the left.
+ */
+ bit_offset = state->bit_offset % 8;
+ state->bit_buf |= (ocode << bit_offset) & 0xff;
+ output_byte(f, state->bit_buf);
+
+ bits = state->code_len - (8 - bit_offset);
+ ocode >>= 8 - bit_offset;
+ /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
+ if (bits >= 8) {
+ output_byte(f, ocode & 0xff);
+ ocode >>= 8;
+ bits -= 8;
+ }
+ /* Last bits. */
+ state->bit_offset += state->code_len;
+ state->bit_buf = ocode & rmask[bits];
+ if (state->bit_offset == state->code_len * 8)
+ state->bit_offset = 0;
+
+ /*
+ * If the next entry is going to be too big for the ocode size,
+ * then increase it, if possible.
+ */
+ if (clear_flg || state->first_free > state->cur_maxcode) {
+ /*
+ * Write the whole buffer, because the input side won't
+ * discover the size increase until after it has read it.
+ */
+ if (state->bit_offset > 0) {
+ while (state->bit_offset < state->code_len * 8) {
+ ret = output_byte(f, state->bit_buf);
+ if (ret != ARCHIVE_OK)
+ return ret;
+ state->bit_offset += 8;
+ state->bit_buf = 0;
+ }
+ }
+ state->bit_buf = 0;
+ state->bit_offset = 0;
+
+ if (clear_flg) {
+ state->code_len = 9;
+ state->cur_maxcode = MAXCODE(state->code_len);
+ } else {
+ state->code_len++;
+ if (state->code_len == 16)
+ state->cur_maxcode = state->max_maxcode;
+ else
+ state->cur_maxcode = MAXCODE(state->code_len);
+ }
+ }
+
+ return (ARCHIVE_OK);
+}
+
+static int
+output_flush(struct archive_write_filter *f)
+{
+ struct private_data *state = f->data;
+ int ret;
+
+ /* At EOF, write the rest of the buffer. */
+ if (state->bit_offset % 8) {
+ state->code_len = (state->bit_offset % 8 + 7) / 8;
+ ret = output_byte(f, state->bit_buf);
+ if (ret != ARCHIVE_OK)
+ return ret;
+ }
+
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Write data to the compressed stream.
+ */
+static int
+archive_compressor_compress_write(struct archive_write_filter *f,
+ const void *buff, size_t length)
+{
+ struct private_data *state = (struct private_data *)f->data;
+ int i;
+ int ratio;
+ int c, disp, ret;
+ const unsigned char *bp;
+
+ if (length == 0)
+ return ARCHIVE_OK;
+
+ bp = buff;
+
+ if (state->in_count == 0) {
+ state->cur_code = *bp++;
+ ++state->in_count;
+ --length;
+ }
+
+ while (length--) {
+ c = *bp++;
+ state->in_count++;
+ state->cur_fcode = (c << 16) + state->cur_code;
+ i = ((c << HSHIFT) ^ state->cur_code); /* Xor hashing. */
+
+ if (state->hashtab[i] == state->cur_fcode) {
+ state->cur_code = state->codetab[i];
+ continue;
+ }
+ if (state->hashtab[i] < 0) /* Empty slot. */
+ goto nomatch;
+ /* Secondary hash (after G. Knott). */
+ if (i == 0)
+ disp = 1;
+ else
+ disp = HSIZE - i;
+ probe:
+ if ((i -= disp) < 0)
+ i += HSIZE;
+
+ if (state->hashtab[i] == state->cur_fcode) {
+ state->cur_code = state->codetab[i];
+ continue;
+ }
+ if (state->hashtab[i] >= 0)
+ goto probe;
+ nomatch:
+ ret = output_code(f, state->cur_code);
+ if (ret != ARCHIVE_OK)
+ return ret;
+ state->cur_code = c;
+ if (state->first_free < state->max_maxcode) {
+ state->codetab[i] = state->first_free++; /* code -> hashtable */
+ state->hashtab[i] = state->cur_fcode;
+ continue;
+ }
+ if (state->in_count < state->checkpoint)
+ continue;
+
+ state->checkpoint = state->in_count + CHECK_GAP;
+
+ if (state->in_count <= 0x007fffff)
+ ratio = state->in_count * 256 / state->out_count;
+ else if ((ratio = state->out_count / 256) == 0)
+ ratio = 0x7fffffff;
+ else
+ ratio = state->in_count / ratio;
+
+ if (ratio > state->compress_ratio)
+ state->compress_ratio = ratio;
+ else {
+ state->compress_ratio = 0;
+ memset(state->hashtab, 0xff, sizeof(state->hashtab));
+ state->first_free = FIRST;
+ ret = output_code(f, CLEAR);
+ if (ret != ARCHIVE_OK)
+ return ret;
+ }
+ }
+
+ return (ARCHIVE_OK);
+}
+
+
+/*
+ * Finish the compression...
+ */
+static int
+archive_compressor_compress_close(struct archive_write_filter *f)
+{
+ struct private_data *state = (struct private_data *)f->data;
+ int ret, ret2;
+
+ ret = output_code(f, state->cur_code);
+ if (ret != ARCHIVE_OK)
+ goto cleanup;
+ ret = output_flush(f);
+ if (ret != ARCHIVE_OK)
+ goto cleanup;
+
+ /* Write the last block */
+ ret = __archive_write_filter(f->next_filter,
+ state->compressed, state->compressed_offset);
+cleanup:
+ ret2 = __archive_write_close_filter(f->next_filter);
+ if (ret > ret2)
+ ret = ret2;
+ free(state->compressed);
+ free(state);
+ return (ret);
+}
+
+static int
+archive_compressor_compress_free(struct archive_write_filter *f)
+{
+ (void)f; /* UNUSED */
+ return (ARCHIVE_OK);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_gzip.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_gzip.c
new file mode 100644
index 000000000..d08ee265b
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_gzip.c
@@ -0,0 +1,356 @@
+/*-
+ * 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: head/lib/libarchive/archive_write_set_compression_gzip.c 201081 2009-12-28 02:04:42Z kientzle $");
+
+#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 <time.h>
+#ifdef HAVE_ZLIB_H
+#include <cm_zlib.h>
+#endif
+
+#include "archive.h"
+#include "archive_private.h"
+#include "archive_write_private.h"
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+int
+archive_write_set_compression_gzip(struct archive *a)
+{
+ __archive_write_filters_free(a);
+ return (archive_write_add_filter_gzip(a));
+}
+#endif
+
+#ifndef HAVE_ZLIB_H
+int
+archive_write_add_filter_gzip(struct archive *a)
+{
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "gzip compression not supported on this platform");
+ return (ARCHIVE_FATAL);
+}
+#else
+/* Don't compile this if we don't have zlib. */
+
+struct private_data {
+ int compression_level;
+ z_stream stream;
+ int64_t total_in;
+ unsigned char *compressed;
+ size_t compressed_buffer_size;
+ unsigned long crc;
+};
+
+/*
+ * Yuck. zlib.h is not const-correct, so I need this one bit
+ * of ugly hackery to convert a const * pointer to a non-const pointer.
+ */
+#define SET_NEXT_IN(st,src) \
+ (st)->stream.next_in = (Bytef *)(uintptr_t)(const void *)(src)
+
+static int archive_compressor_gzip_options(struct archive_write_filter *,
+ const char *, const char *);
+static int archive_compressor_gzip_open(struct archive_write_filter *);
+static int archive_compressor_gzip_write(struct archive_write_filter *,
+ const void *, size_t);
+static int archive_compressor_gzip_close(struct archive_write_filter *);
+static int archive_compressor_gzip_free(struct archive_write_filter *);
+static int drive_compressor(struct archive_write_filter *,
+ struct private_data *, int finishing);
+
+
+/*
+ * Add a gzip compression filter to this write handle.
+ */
+int
+archive_write_add_filter_gzip(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_gzip");
+
+ data = calloc(1, sizeof(*data));
+ if (data == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
+ f->data = data;
+ data->compression_level = Z_DEFAULT_COMPRESSION;
+ f->open = &archive_compressor_gzip_open;
+ f->options = &archive_compressor_gzip_options;
+ f->close = &archive_compressor_gzip_close;
+ f->free = &archive_compressor_gzip_free;
+ f->code = ARCHIVE_COMPRESSION_GZIP;
+ f->name = "gzip";
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Setup callback.
+ */
+static int
+archive_compressor_gzip_open(struct archive_write_filter *f)
+{
+ struct private_data *data = (struct private_data *)f->data;
+ int ret;
+ time_t t;
+
+ ret = __archive_write_open_filter(f->next_filter);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+
+ if (data->compressed == NULL) {
+ data->compressed_buffer_size = 65536;
+ data->compressed
+ = (unsigned char *)malloc(data->compressed_buffer_size);
+ if (data->compressed == NULL) {
+ archive_set_error(f->archive, ENOMEM,
+ "Can't allocate data for compression buffer");
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ data->crc = crc32(0L, NULL, 0);
+ data->stream.next_out = data->compressed;
+ data->stream.avail_out = data->compressed_buffer_size;
+
+ /* Prime output buffer with a gzip header. */
+ t = time(NULL);
+ data->compressed[0] = 0x1f; /* GZip signature bytes */
+ data->compressed[1] = 0x8b;
+ data->compressed[2] = 0x08; /* "Deflate" compression */
+ data->compressed[3] = 0; /* No options */
+ data->compressed[4] = (t)&0xff; /* Timestamp */
+ data->compressed[5] = (t>>8)&0xff;
+ data->compressed[6] = (t>>16)&0xff;
+ data->compressed[7] = (t>>24)&0xff;
+ data->compressed[8] = 0; /* No deflate options */
+ data->compressed[9] = 3; /* OS=Unix */
+ data->stream.next_out += 10;
+ data->stream.avail_out -= 10;
+
+ f->write = archive_compressor_gzip_write;
+
+ /* Initialize compression library. */
+ ret = deflateInit2(&(data->stream),
+ data->compression_level,
+ Z_DEFLATED,
+ -15 /* < 0 to suppress zlib header */,
+ 8,
+ Z_DEFAULT_STRATEGY);
+
+ if (ret == Z_OK) {
+ f->data = data;
+ return (ARCHIVE_OK);
+ }
+
+ /* Library setup failed: clean up. */
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC, "Internal error "
+ "initializing compression library");
+
+ /* Override the error message if we know what really went wrong. */
+ switch (ret) {
+ case Z_STREAM_ERROR:
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "Internal error initializing "
+ "compression library: invalid setup parameter");
+ break;
+ case Z_MEM_ERROR:
+ archive_set_error(f->archive, ENOMEM, "Internal error initializing "
+ "compression library");
+ break;
+ case Z_VERSION_ERROR:
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "Internal error initializing "
+ "compression library: invalid library version");
+ break;
+ }
+
+ return (ARCHIVE_FATAL);
+}
+
+/*
+ * Set write options.
+ */
+static int
+archive_compressor_gzip_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] >= '0' && value[0] <= '9') ||
+ value[1] != '\0')
+ return (ARCHIVE_WARN);
+ data->compression_level = value[0] - '0';
+ return (ARCHIVE_OK);
+ }
+ return (ARCHIVE_WARN);
+}
+
+/*
+ * Write data to the compressed stream.
+ */
+static int
+archive_compressor_gzip_write(struct archive_write_filter *f, const void *buff,
+ size_t length)
+{
+ struct private_data *data = (struct private_data *)f->data;
+ int ret;
+
+ /* Update statistics */
+ data->crc = crc32(data->crc, (const Bytef *)buff, length);
+ data->total_in += length;
+
+ /* Compress input data to output buffer */
+ SET_NEXT_IN(data, buff);
+ data->stream.avail_in = length;
+ if ((ret = drive_compressor(f, data, 0)) != ARCHIVE_OK)
+ return (ret);
+
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Finish the compression...
+ */
+static int
+archive_compressor_gzip_close(struct archive_write_filter *f)
+{
+ unsigned char trailer[8];
+ struct private_data *data = (struct private_data *)f->data;
+ int ret, r1;
+
+ /* Finish compression cycle */
+ ret = drive_compressor(f, data, 1);
+ if (ret == ARCHIVE_OK) {
+ /* Write the last compressed data. */
+ ret = __archive_write_filter(f->next_filter,
+ data->compressed,
+ data->compressed_buffer_size - data->stream.avail_out);
+ }
+ if (ret == ARCHIVE_OK) {
+ /* Build and write out 8-byte trailer. */
+ trailer[0] = (data->crc)&0xff;
+ trailer[1] = (data->crc >> 8)&0xff;
+ trailer[2] = (data->crc >> 16)&0xff;
+ trailer[3] = (data->crc >> 24)&0xff;
+ trailer[4] = (data->total_in)&0xff;
+ trailer[5] = (data->total_in >> 8)&0xff;
+ trailer[6] = (data->total_in >> 16)&0xff;
+ trailer[7] = (data->total_in >> 24)&0xff;
+ ret = __archive_write_filter(f->next_filter, trailer, 8);
+ }
+
+ switch (deflateEnd(&(data->stream))) {
+ case Z_OK:
+ break;
+ default:
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "Failed to clean up compressor");
+ ret = ARCHIVE_FATAL;
+ }
+ r1 = __archive_write_close_filter(f->next_filter);
+ return (r1 < ret ? r1 : ret);
+}
+
+static int
+archive_compressor_gzip_free(struct archive_write_filter *f)
+{
+ struct private_data *data = (struct private_data *)f->data;
+ free(data->compressed);
+ free(data);
+ f->data = NULL;
+ return (ARCHIVE_OK);
+}
+
+/*
+ * 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,
+ struct private_data *data, int finishing)
+{
+ int ret;
+
+ for (;;) {
+ if (data->stream.avail_out == 0) {
+ ret = __archive_write_filter(f->next_filter,
+ data->compressed,
+ data->compressed_buffer_size);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ data->stream.next_out = data->compressed;
+ data->stream.avail_out = data->compressed_buffer_size;
+ }
+
+ /* If there's nothing to do, we're done. */
+ if (!finishing && data->stream.avail_in == 0)
+ return (ARCHIVE_OK);
+
+ ret = deflate(&(data->stream),
+ finishing ? Z_FINISH : Z_NO_FLUSH );
+
+ switch (ret) {
+ case Z_OK:
+ /* In non-finishing case, check if compressor
+ * consumed everything */
+ if (!finishing && data->stream.avail_in == 0)
+ return (ARCHIVE_OK);
+ /* In finishing case, this return always means
+ * there's more work */
+ break;
+ case Z_STREAM_END:
+ /* This return can only occur in finishing case. */
+ return (ARCHIVE_OK);
+ default:
+ /* Any other return value indicates an error. */
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "GZip compression failed:"
+ " deflate() call returned status %d",
+ ret);
+ return (ARCHIVE_FATAL);
+ }
+ }
+}
+
+#endif /* HAVE_ZLIB_H */
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_none.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_none.c
new file mode 100644
index 000000000..3c06c642e
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_none.c
@@ -0,0 +1,43 @@
+/*-
+ * Copyright (c) 2003-2010 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: head/lib/libarchive/archive_write_set_compression_none.c 201080 2009-12-28 02:03:54Z kientzle $");
+
+#include "archive.h"
+
+int
+archive_write_set_compression_none(struct archive *a)
+{
+ (void)a; /* UNUSED */
+ return (ARCHIVE_OK);
+}
+
+int
+archive_write_add_filter_none(struct archive *a)
+{
+ (void)a; /* UNUSED */
+ return (ARCHIVE_OK);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_program.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_program.c
new file mode 100644
index 000000000..3dcc9df7b
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_program.c
@@ -0,0 +1,327 @@
+/*-
+ * Copyright (c) 2007 Joerg Sonnenberger
+ * 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_compression_program.c 201104 2009-12-28 03:14:30Z kientzle $");
+
+#ifdef HAVE_SYS_WAIT_H
+# include <sys/wait.h>
+#endif
+#ifdef HAVE_ERRNO_H
+# include <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+#ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif
+
+#include "archive.h"
+#include "archive_private.h"
+#include "archive_write_private.h"
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+int
+archive_write_set_compression_program(struct archive *a, const char *cmd)
+{
+ __archive_write_filters_free(a);
+ return (archive_write_add_filter_program(a, cmd));
+}
+#endif
+
+/* This capability is only available on POSIX systems. */
+#if (!defined(HAVE_PIPE) || !defined(HAVE_FCNTL) || \
+ !(defined(HAVE_FORK) || defined(HAVE_VFORK))) && (!defined(_WIN32) || defined(__CYGWIN__))
+
+/*
+ * On non-Posix systems, allow the program to build, but choke if
+ * this function is actually invoked.
+ */
+int
+archive_write_add_filter_program(struct archive *_a, const char *cmd)
+{
+ archive_set_error(_a, -1,
+ "External compression programs not supported on this platform");
+ return (ARCHIVE_FATAL);
+}
+
+#else
+
+#include "filter_fork.h"
+
+struct private_data {
+ char *cmd;
+ char *description;
+ pid_t child;
+ int child_stdin, child_stdout;
+
+ char *child_buf;
+ size_t child_buf_len, child_buf_avail;
+};
+
+static int archive_compressor_program_open(struct archive_write_filter *);
+static int archive_compressor_program_write(struct archive_write_filter *,
+ const void *, size_t);
+static int archive_compressor_program_close(struct archive_write_filter *);
+static int archive_compressor_program_free(struct archive_write_filter *);
+
+/*
+ * Add a filter to this write handle that passes all data through an
+ * external program.
+ */
+int
+archive_write_add_filter_program(struct archive *_a, const char *cmd)
+{
+ struct archive_write_filter *f = __archive_write_allocate_filter(_a);
+ struct archive_write *a = (struct archive_write *)_a;
+ struct private_data *data;
+ static const char *prefix = "Program: ";
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_add_filter_program");
+ data = calloc(1, sizeof(*data));
+ if (data == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
+ data->cmd = strdup(cmd);
+ data->description = (char *)malloc(strlen(prefix) + strlen(cmd) + 1);
+ strcpy(data->description, prefix);
+ strcat(data->description, cmd);
+
+ f->name = data->description;
+ f->data = data;
+ f->open = &archive_compressor_program_open;
+ f->code = ARCHIVE_COMPRESSION_PROGRAM;
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Setup callback.
+ */
+static int
+archive_compressor_program_open(struct archive_write_filter *f)
+{
+ struct private_data *data = (struct private_data *)f->data;
+ int ret;
+
+ ret = __archive_write_open_filter(f->next_filter);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+
+ if (data->child_buf == NULL) {
+ data->child_buf_len = 65536;
+ data->child_buf_avail = 0;
+ data->child_buf = malloc(data->child_buf_len);
+
+ if (data->child_buf == NULL) {
+ archive_set_error(f->archive, ENOMEM,
+ "Can't allocate compression buffer");
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ if ((data->child = __archive_create_child(data->cmd,
+ &data->child_stdin, &data->child_stdout)) == -1) {
+ archive_set_error(f->archive, EINVAL,
+ "Can't initialise filter");
+ return (ARCHIVE_FATAL);
+ }
+
+ f->write = archive_compressor_program_write;
+ f->close = archive_compressor_program_close;
+ f->free = archive_compressor_program_free;
+ return (0);
+}
+
+static ssize_t
+child_write(struct archive_write_filter *f, const char *buf, size_t buf_len)
+{
+ struct private_data *data = f->data;
+ ssize_t ret;
+
+ if (data->child_stdin == -1)
+ return (-1);
+
+ if (buf_len == 0)
+ return (-1);
+
+restart_write:
+ do {
+ ret = write(data->child_stdin, buf, buf_len);
+ } while (ret == -1 && errno == EINTR);
+
+ if (ret > 0)
+ return (ret);
+ if (ret == 0) {
+ close(data->child_stdin);
+ data->child_stdin = -1;
+ fcntl(data->child_stdout, F_SETFL, 0);
+ return (0);
+ }
+ if (ret == -1 && errno != EAGAIN)
+ return (-1);
+
+ if (data->child_stdout == -1) {
+ fcntl(data->child_stdin, F_SETFL, 0);
+ __archive_check_child(data->child_stdin, data->child_stdout);
+ goto restart_write;
+ }
+
+ do {
+ ret = read(data->child_stdout,
+ data->child_buf + data->child_buf_avail,
+ data->child_buf_len - data->child_buf_avail);
+ } while (ret == -1 && errno == EINTR);
+
+ if (ret == 0 || (ret == -1 && errno == EPIPE)) {
+ close(data->child_stdout);
+ data->child_stdout = -1;
+ fcntl(data->child_stdin, F_SETFL, 0);
+ goto restart_write;
+ }
+ if (ret == -1 && errno == EAGAIN) {
+ __archive_check_child(data->child_stdin, data->child_stdout);
+ goto restart_write;
+ }
+ if (ret == -1)
+ return (-1);
+
+ data->child_buf_avail += ret;
+
+ ret = __archive_write_filter(f->next_filter,
+ data->child_buf, data->child_buf_avail);
+ if (ret <= 0)
+ return (-1);
+
+ if ((size_t)ret < data->child_buf_avail) {
+ memmove(data->child_buf, data->child_buf + ret,
+ data->child_buf_avail - ret);
+ }
+ data->child_buf_avail -= ret;
+ goto restart_write;
+}
+
+/*
+ * Write data to the compressed stream.
+ */
+static int
+archive_compressor_program_write(struct archive_write_filter *f,
+ const void *buff, size_t length)
+{
+ ssize_t ret;
+ const char *buf;
+
+ buf = buff;
+ while (length > 0) {
+ ret = child_write(f, buf, length);
+ if (ret == -1 || ret == 0) {
+ archive_set_error(f->archive, EIO,
+ "Can't write to filter");
+ return (ARCHIVE_FATAL);
+ }
+ length -= ret;
+ buf += ret;
+ }
+ return (ARCHIVE_OK);
+}
+
+
+/*
+ * Finish the compression...
+ */
+static int
+archive_compressor_program_close(struct archive_write_filter *f)
+{
+ struct private_data *data = (struct private_data *)f->data;
+ int ret, r1, status;
+ ssize_t bytes_read;
+
+ ret = 0;
+ close(data->child_stdin);
+ data->child_stdin = -1;
+ fcntl(data->child_stdout, F_SETFL, 0);
+
+ for (;;) {
+ do {
+ bytes_read = read(data->child_stdout,
+ data->child_buf + data->child_buf_avail,
+ data->child_buf_len - data->child_buf_avail);
+ } while (bytes_read == -1 && errno == EINTR);
+
+ if (bytes_read == 0 || (bytes_read == -1 && errno == EPIPE))
+ break;
+
+ if (bytes_read == -1) {
+ archive_set_error(f->archive, errno,
+ "Read from filter failed unexpectedly.");
+ ret = ARCHIVE_FATAL;
+ goto cleanup;
+ }
+ data->child_buf_avail += bytes_read;
+
+ ret = __archive_write_filter(f->next_filter,
+ data->child_buf, data->child_buf_avail);
+ if (ret != ARCHIVE_OK) {
+ ret = ARCHIVE_FATAL;
+ goto cleanup;
+ }
+ data->child_buf_avail = 0;
+ }
+
+cleanup:
+ /* Shut down the child. */
+ if (data->child_stdin != -1)
+ close(data->child_stdin);
+ if (data->child_stdout != -1)
+ close(data->child_stdout);
+ while (waitpid(data->child, &status, 0) == -1 && errno == EINTR)
+ continue;
+
+ if (status != 0) {
+ archive_set_error(f->archive, EIO,
+ "Filter exited with failure.");
+ ret = ARCHIVE_FATAL;
+ }
+ r1 = __archive_write_close_filter(f->next_filter);
+ return (r1 < ret ? r1 : ret);
+}
+
+static int
+archive_compressor_program_free(struct archive_write_filter *f)
+{
+ struct private_data *data = (struct private_data *)f->data;
+ free(data->cmd);
+ free(data->description);
+ free(data->child_buf);
+ free(data);
+ f->data = NULL;
+ return (ARCHIVE_OK);
+}
+
+#endif /* !defined(HAVE_PIPE) || !defined(HAVE_VFORK) || !defined(HAVE_FCNTL) */
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_xz.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_xz.c
new file mode 100644
index 000000000..b06775224
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_xz.c
@@ -0,0 +1,502 @@
+/*-
+ * Copyright (c) 2009,2010 Michihiro NAKAJIMA
+ * Copyright (c) 2003-2010 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: head/lib/libarchive/archive_write_set_compression_xz.c 201108 2009-12-28 03:28:21Z kientzle $");
+
+#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 <time.h>
+#ifdef HAVE_LZMA_H
+#include <lzma.h>
+#endif
+
+#include "archive.h"
+#include "archive_endian.h"
+#include "archive_private.h"
+#include "archive_write_private.h"
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+int
+archive_write_set_compression_lzip(struct archive *a)
+{
+ __archive_write_filters_free(a);
+ return (archive_write_add_filter_lzip(a));
+}
+
+int
+archive_write_set_compression_lzma(struct archive *a)
+{
+ __archive_write_filters_free(a);
+ return (archive_write_add_filter_lzma(a));
+}
+
+int
+archive_write_set_compression_xz(struct archive *a)
+{
+ __archive_write_filters_free(a);
+ return (archive_write_add_filter_xz(a));
+}
+
+#endif
+
+#ifndef HAVE_LZMA_H
+int
+archive_write_add_filter_xz(struct archive *a)
+{
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "xz compression not supported on this platform");
+ return (ARCHIVE_FATAL);
+}
+
+int
+archive_write_add_filter_lzma(struct archive *a)
+{
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "lzma compression not supported on this platform");
+ return (ARCHIVE_FATAL);
+}
+
+int
+archive_write_add_filter_lzip(struct archive *a)
+{
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "lzma compression not supported on this platform");
+ return (ARCHIVE_FATAL);
+}
+#else
+/* Don't compile this if we don't have liblzma. */
+
+struct private_data {
+ int compression_level;
+ lzma_stream stream;
+ lzma_filter lzmafilters[2];
+ lzma_options_lzma lzma_opt;
+ int64_t total_in;
+ unsigned char *compressed;
+ size_t compressed_buffer_size;
+ int64_t total_out;
+ /* the CRC32 value of uncompressed data for lzip */
+ uint32_t crc32;
+};
+
+static int archive_compressor_xz_options(struct archive_write_filter *,
+ const char *, const char *);
+static int archive_compressor_xz_open(struct archive_write_filter *);
+static int archive_compressor_xz_write(struct archive_write_filter *,
+ const void *, size_t);
+static int archive_compressor_xz_close(struct archive_write_filter *);
+static int archive_compressor_xz_free(struct archive_write_filter *);
+static int drive_compressor(struct archive_write_filter *,
+ struct private_data *, int finishing);
+
+struct option_value {
+ uint32_t dict_size;
+ uint32_t nice_len;
+ lzma_match_finder mf;
+};
+static const struct option_value option_values[] = {
+ { 1 << 16, 32, LZMA_MF_HC3},
+ { 1 << 20, 32, LZMA_MF_HC3},
+ { 3 << 19, 32, LZMA_MF_HC4},
+ { 1 << 21, 32, LZMA_MF_BT4},
+ { 3 << 20, 32, LZMA_MF_BT4},
+ { 1 << 22, 32, LZMA_MF_BT4},
+ { 1 << 23, 64, LZMA_MF_BT4},
+ { 1 << 24, 64, LZMA_MF_BT4},
+ { 3 << 23, 64, LZMA_MF_BT4},
+ { 1 << 25, 64, LZMA_MF_BT4}
+};
+
+static int
+common_setup(struct archive_write_filter *f)
+{
+ struct private_data *data;
+ struct archive_write *a = (struct archive_write *)f->archive;
+ data = calloc(1, sizeof(*data));
+ if (data == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
+ f->data = data;
+ data->compression_level = LZMA_PRESET_DEFAULT;
+ f->open = &archive_compressor_xz_open;
+ f->close = archive_compressor_xz_close;
+ f->free = archive_compressor_xz_free;
+ f->options = &archive_compressor_xz_options;
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Add an xz compression filter to this write handle.
+ */
+int
+archive_write_add_filter_xz(struct archive *_a)
+{
+ struct archive_write_filter *f;
+ int r;
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_add_filter_xz");
+ f = __archive_write_allocate_filter(_a);
+ r = common_setup(f);
+ if (r == ARCHIVE_OK) {
+ f->code = ARCHIVE_COMPRESSION_XZ;
+ f->name = "xz";
+ }
+ return (r);
+}
+
+/* LZMA is handled identically, we just need a different compression
+ * code set. (The liblzma setup looks at the code to determine
+ * the one place that XZ and LZMA require different handling.) */
+int
+archive_write_add_filter_lzma(struct archive *_a)
+{
+ struct archive_write_filter *f;
+ int r;
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_add_filter_lzma");
+ f = __archive_write_allocate_filter(_a);
+ r = common_setup(f);
+ if (r == ARCHIVE_OK) {
+ f->code = ARCHIVE_COMPRESSION_LZMA;
+ f->name = "lzma";
+ }
+ return (r);
+}
+
+int
+archive_write_add_filter_lzip(struct archive *_a)
+{
+ struct archive_write_filter *f;
+ int r;
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_add_filter_lzip");
+ f = __archive_write_allocate_filter(_a);
+ r = common_setup(f);
+ if (r == ARCHIVE_OK) {
+ f->code = ARCHIVE_COMPRESSION_LZIP;
+ f->name = "lzip";
+ }
+ return (r);
+}
+
+static int
+archive_compressor_xz_init_stream(struct archive_write_filter *f,
+ struct private_data *data)
+{
+ static const lzma_stream lzma_stream_init_data = LZMA_STREAM_INIT;
+ int ret;
+
+ data->stream = lzma_stream_init_data;
+ data->stream.next_out = data->compressed;
+ data->stream.avail_out = data->compressed_buffer_size;
+ if (f->code == ARCHIVE_COMPRESSION_XZ)
+ ret = lzma_stream_encoder(&(data->stream),
+ data->lzmafilters, LZMA_CHECK_CRC64);
+ else if (f->code == ARCHIVE_COMPRESSION_LZMA)
+ ret = lzma_alone_encoder(&(data->stream), &data->lzma_opt);
+ else { /* ARCHIVE_COMPRESSION_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",
+ dict_size);
+ return (ARCHIVE_FATAL);
+ }
+ for (log2dic = 27; log2dic >= 12; log2dic--) {
+ if (dict_size & (1 << log2dic))
+ break;
+ }
+ if (dict_size > (1 << log2dic)) {
+ log2dic++;
+ wedges =
+ ((1 << log2dic) - dict_size) / (1 << (log2dic - 4));
+ } else
+ wedges = 0;
+ ds = ((wedges << 5) & 0xe0) | (log2dic & 0x1f);
+
+ data->crc32 = 0;
+ /* Make a header */
+ data->compressed[0] = 0x4C;
+ data->compressed[1] = 0x5A;
+ data->compressed[2] = 0x49;
+ data->compressed[3] = 0x50;
+ data->compressed[4] = 1;/* Version */
+ data->compressed[5] = (unsigned char)ds;
+ data->stream.next_out += 6;
+ data->stream.avail_out -= 6;
+
+ ret = lzma_raw_encoder(&(data->stream), data->lzmafilters);
+ }
+ if (ret == LZMA_OK)
+ return (ARCHIVE_OK);
+
+ switch (ret) {
+ case LZMA_MEM_ERROR:
+ archive_set_error(f->archive, ENOMEM,
+ "Internal error initializing compression library: "
+ "Cannot allocate memory");
+ break;
+ default:
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "Internal error initializing compression library: "
+ "It's a bug in liblzma");
+ break;
+ }
+ return (ARCHIVE_FATAL);
+}
+
+/*
+ * Setup callback.
+ */
+static int
+archive_compressor_xz_open(struct archive_write_filter *f)
+{
+ struct private_data *data = f->data;
+ int ret;
+
+ ret = __archive_write_open_filter(f->next_filter);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+
+ if (data->compressed == NULL) {
+ data->compressed_buffer_size = 65536;
+ data->compressed
+ = (unsigned char *)malloc(data->compressed_buffer_size);
+ if (data->compressed == NULL) {
+ archive_set_error(f->archive, ENOMEM,
+ "Can't allocate data for compression buffer");
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ f->write = archive_compressor_xz_write;
+
+ /* Initialize compression library. */
+ if (f->code == ARCHIVE_COMPRESSION_LZIP) {
+ const struct option_value *val =
+ &option_values[data->compression_level];
+
+ data->lzma_opt.dict_size = val->dict_size;
+ data->lzma_opt.preset_dict = NULL;
+ data->lzma_opt.preset_dict_size = 0;
+ data->lzma_opt.lc = LZMA_LC_DEFAULT;
+ data->lzma_opt.lp = LZMA_LP_DEFAULT;
+ data->lzma_opt.pb = LZMA_PB_DEFAULT;
+ data->lzma_opt.mode =
+ data->compression_level<= 2? LZMA_MODE_FAST:LZMA_MODE_NORMAL;
+ data->lzma_opt.nice_len = val->nice_len;
+ data->lzma_opt.mf = val->mf;
+ data->lzma_opt.depth = 0;
+ data->lzmafilters[0].id = LZMA_FILTER_LZMA1;
+ data->lzmafilters[0].options = &data->lzma_opt;
+ data->lzmafilters[1].id = LZMA_VLI_UNKNOWN;/* Terminate */
+ } else {
+ if (lzma_lzma_preset(&data->lzma_opt, data->compression_level)) {
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "Internal error initializing compression library");
+ }
+ data->lzmafilters[0].id = LZMA_FILTER_LZMA2;
+ data->lzmafilters[0].options = &data->lzma_opt;
+ data->lzmafilters[1].id = LZMA_VLI_UNKNOWN;/* Terminate */
+ }
+ ret = archive_compressor_xz_init_stream(f, data);
+ if (ret == LZMA_OK) {
+ f->data = data;
+ return (0);
+ }
+ return (ARCHIVE_FATAL);
+}
+
+/*
+ * Set write options.
+ */
+static int
+archive_compressor_xz_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] >= '0' && value[0] <= '9') ||
+ value[1] != '\0')
+ return (ARCHIVE_WARN);
+ data->compression_level = value[0] - '0';
+ if (data->compression_level > 6)
+ data->compression_level = 6;
+ return (ARCHIVE_OK);
+ }
+
+ return (ARCHIVE_WARN);
+}
+
+/*
+ * Write data to the compressed stream.
+ */
+static int
+archive_compressor_xz_write(struct archive_write_filter *f,
+ const void *buff, size_t length)
+{
+ struct private_data *data = (struct private_data *)f->data;
+ int ret;
+
+ /* Update statistics */
+ data->total_in += length;
+ if (f->code == ARCHIVE_COMPRESSION_LZIP)
+ data->crc32 = lzma_crc32(buff, length, data->crc32);
+
+ /* Compress input data to output buffer */
+ data->stream.next_in = buff;
+ data->stream.avail_in = length;
+ if ((ret = drive_compressor(f, data, 0)) != ARCHIVE_OK)
+ return (ret);
+
+ return (ARCHIVE_OK);
+}
+
+
+/*
+ * Finish the compression...
+ */
+static int
+archive_compressor_xz_close(struct archive_write_filter *f)
+{
+ struct private_data *data = (struct private_data *)f->data;
+ int ret, r1;
+
+ ret = drive_compressor(f, data, 1);
+ if (ret == ARCHIVE_OK) {
+ data->total_out +=
+ data->compressed_buffer_size - data->stream.avail_out;
+ ret = __archive_write_filter(f->next_filter,
+ data->compressed,
+ data->compressed_buffer_size - data->stream.avail_out);
+ if (f->code == ARCHIVE_COMPRESSION_LZIP && ret == ARCHIVE_OK) {
+ archive_le32enc(data->compressed, data->crc32);
+ archive_le64enc(data->compressed+4, data->total_in);
+ archive_le64enc(data->compressed+12, data->total_out + 20);
+ ret = __archive_write_filter(f->next_filter,
+ data->compressed, 20);
+ }
+ }
+ lzma_end(&(data->stream));
+ r1 = __archive_write_close_filter(f->next_filter);
+ return (r1 < ret ? r1 : ret);
+}
+
+static int
+archive_compressor_xz_free(struct archive_write_filter *f)
+{
+ struct private_data *data = (struct private_data *)f->data;
+ free(data->compressed);
+ free(data);
+ f->data = NULL;
+ return (ARCHIVE_OK);
+}
+
+/*
+ * 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,
+ struct private_data *data, int finishing)
+{
+ int ret;
+
+ for (;;) {
+ if (data->stream.avail_out == 0) {
+ data->total_out += data->compressed_buffer_size;
+ ret = __archive_write_filter(f->next_filter,
+ data->compressed,
+ data->compressed_buffer_size);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ data->stream.next_out = data->compressed;
+ data->stream.avail_out = data->compressed_buffer_size;
+ }
+
+ /* If there's nothing to do, we're done. */
+ if (!finishing && data->stream.avail_in == 0)
+ return (ARCHIVE_OK);
+
+ ret = lzma_code(&(data->stream),
+ finishing ? LZMA_FINISH : LZMA_RUN );
+
+ switch (ret) {
+ case LZMA_OK:
+ /* In non-finishing case, check if compressor
+ * consumed everything */
+ if (!finishing && data->stream.avail_in == 0)
+ return (ARCHIVE_OK);
+ /* In finishing case, this return always means
+ * there's more work */
+ break;
+ case LZMA_STREAM_END:
+ /* This return can only occur in finishing case. */
+ if (finishing)
+ return (ARCHIVE_OK);
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "lzma compression data error");
+ return (ARCHIVE_FATAL);
+ case LZMA_MEMLIMIT_ERROR:
+ archive_set_error(f->archive, ENOMEM,
+ "lzma compression error: "
+ "%ju MiB would have been needed",
+ (uintmax_t)((lzma_memusage(&(data->stream))
+ + 1024 * 1024 -1)
+ / (1024 * 1024)));
+ return (ARCHIVE_FATAL);
+ default:
+ /* Any other return value indicates an error. */
+ archive_set_error(f->archive, ARCHIVE_ERRNO_MISC,
+ "lzma compression failed:"
+ " lzma_code() call returned status %d",
+ ret);
+ return (ARCHIVE_FATAL);
+ }
+ }
+}
+
+#endif /* HAVE_LZMA_H */
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_blocksize.3 b/Utilities/cmlibarchive/libarchive/archive_write_blocksize.3
new file mode 100644
index 000000000..96c75382a
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_blocksize.3
@@ -0,0 +1,112 @@
+.\" Copyright (c) 2003-2011 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 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 March 23, 2011
+.Dt ARCHIVE_WRITE_BLOCKSIZE 3
+.Os
+.Sh NAME
+.Nm archive_write_get_bytes_per_block ,
+.Nm archive_write_set_bytes_per_block ,
+.Nm archive_write_get_bytes_in_last_block ,
+.Nm archive_write_set_bytes_in_last_block
+.Nd functions for creating archives
+.Sh SYNOPSIS
+.In archive.h
+.Ft int
+.Fn archive_write_get_bytes_per_block "struct archive *"
+.Ft int
+.Fn archive_write_set_bytes_per_block "struct archive *" "int bytes_per_block"
+.Ft int
+.Fn archive_write_get_bytes_in_last_block "struct archive *"
+.Ft int
+.Fn archive_write_set_bytes_in_last_block "struct archive *" "int"
+.Sh DESCRIPTION
+.Bl -tag -width indent
+.It Fn archive_write_set_bytes_per_block
+Sets the block size used for writing the archive data.
+Every call to the write callback function, except possibly the last one, will
+use this value for the length.
+The default is to use a block size of 10240 bytes.
+Note that a block size of zero will suppress internal blocking
+and cause writes to be sent directly to the write callback as they occur.
+.It Fn archive_write_get_bytes_per_block
+Retrieve the block size to be used for writing.
+A value of -1 here indicates that the library should use default values.
+A value of zero indicates that internal blocking is suppressed.
+.It Fn archive_write_set_bytes_in_last_block
+Sets the block size used for writing the last block.
+If this value is zero, the last block will be padded to the same size
+as the other blocks.
+Otherwise, the final block will be padded to a multiple of this size.
+In particular, setting it to 1 will cause the final block to not be padded.
+For compressed output, any padding generated by this option
+is applied only after the compression.
+The uncompressed data is always unpadded.
+The default is to pad the last block to the full block size (note that
+.Fn archive_write_open_filename
+will set this based on the file type).
+Unlike the other
+.Dq set
+functions, this function can be called after the archive is opened.
+.It Fn archive_write_get_bytes_in_last_block
+Retrieve the currently-set value for last block size.
+A value of -1 here indicates that the library should use default values.
+.El
+.\" .Sh EXAMPLE
+.Sh RETURN VALUES
+.Fn archive_write_set_bytes_per_block
+and
+.Fn archive_write_set_bytes_in_last_block
+return
+.Cm ARCHIVE_OK
+on success, or
+.Cm ARCHIVE_FATAL .
+.Pp
+.Fn archive_write_get_bytes_per_block
+and
+.Fn archive_write_get_bytes_in_last_block
+return currently configured block size
+.Po
+.Li -1
+indicates the default block size
+.Pc ,
+or
+.Cm ARCHIVE_FATAL .
+.\"
+.Sh ERRORS
+Detailed error codes and textual descriptions are available from the
+.Fn archive_errno
+and
+.Fn archive_error_string
+functions.
+.\"
+.Sh SEE ALSO
+.Xr tar 1 ,
+.Xr libarchive 3 ,
+.Xr archive_write_set_options 3 ,
+.Xr cpio 5 ,
+.Xr mtree 5 ,
+.Xr tar 5
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_data.3 b/Utilities/cmlibarchive/libarchive/archive_write_data.3
new file mode 100644
index 000000000..fc399bc30
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_data.3
@@ -0,0 +1,60 @@
+.\" Copyright (c) 2003-2011 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 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: head/lib/libarchive/archive_write.3 201110 2009-12-28 03:31:29Z kientzle $
+.\"
+.Dd March 23, 2011
+.Dt ARCHIVE_WRITE 3
+.Os
+.Sh NAME
+.Nm archive_write_data
+.Nd functions for creating archives
+.Sh SYNOPSIS
+.In archive.h
+.Ft ssize_t
+.Fn archive_write_data "struct archive *" "const void *" "size_t"
+.Sh DESCRIPTION
+Write data corresponding to the header just written.
+.\" .Sh EXAMPLE
+.\"
+.Sh RETURN VALUES
+This function returns the number of bytes actually written, or
+.Li -1
+on error.
+.\"
+.Sh ERRORS
+Detailed error codes and textual descriptions are available from the
+.Fn archive_errno
+and
+.Fn archive_error_string
+functions.
+.\"
+.Sh SEE ALSO
+.Xr tar 1 ,
+.Xr libarchive 3 ,
+.Xr archive_write_finish_entry 3 ,
+.Xr archive_write_set_options 3 ,
+.Xr cpio 5 ,
+.Xr mtree 5 ,
+.Xr tar 5
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_disk.3 b/Utilities/cmlibarchive/libarchive/archive_write_disk.3
new file mode 100644
index 000000000..ffadb04fe
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_disk.3
@@ -0,0 +1,401 @@
+.\" 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 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: src/lib/libarchive/archive_write_disk.3,v 1.4 2008/09/04 05:22:00 kientzle Exp $
+.\"
+.Dd August 5, 2008
+.Dt ARCHIVE_WRITE_DISK 3
+.Os
+.Sh NAME
+.Nm archive_write_disk_new ,
+.Nm archive_write_disk_set_options ,
+.Nm archive_write_disk_set_skip_file ,
+.Nm archive_write_disk_set_group_lookup ,
+.Nm archive_write_disk_set_standard_lookup ,
+.Nm archive_write_disk_set_user_lookup ,
+.Nm archive_write_header ,
+.Nm archive_write_data ,
+.Nm archive_write_data_block ,
+.Nm archive_write_finish_entry ,
+.Nm archive_write_close ,
+.Nm archive_write_finish
+.Nm archive_write_free
+.Nd functions for creating objects on disk
+.Sh SYNOPSIS
+.In archive.h
+.Ft struct archive *
+.Fn archive_write_disk_new "void"
+.Ft int
+.Fn archive_write_disk_set_options "struct archive *" "int flags"
+.Ft int
+.Fn archive_write_disk_set_skip_file "struct archive *" "dev_t" "ino_t"
+.Ft int
+.Fo archive_write_disk_set_group_lookup
+.Fa "struct archive *"
+.Fa "void *"
+.Fa "gid_t (*)(void *, const char *gname, gid_t gid)"
+.Fa "void (*cleanup)(void *)"
+.Fc
+.Ft int
+.Fn archive_write_disk_set_standard_lookup "struct archive *"
+.Ft int
+.Fo archive_write_disk_set_user_lookup
+.Fa "struct archive *"
+.Fa "void *"
+.Fa "uid_t (*)(void *, const char *uname, uid_t uid)"
+.Fa "void (*cleanup)(void *)"
+.Fc
+.Ft int
+.Fn archive_write_header "struct archive *" "struct archive_entry *"
+.Ft ssize_t
+.Fn archive_write_data "struct archive *" "const void *" "size_t"
+.Ft 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 *"
+.Ft int
+.Fn archive_write_close "struct archive *"
+.Ft int
+.Fn archive_write_finish "struct archive *"
+.Ft int
+.Fn archive_write_free "struct archive *"
+.Sh DESCRIPTION
+These functions provide a complete API for creating objects on
+disk from
+.Tn struct archive_entry
+descriptions.
+They are most naturally used when extracting objects from an archive
+using the
+.Fn archive_read
+interface.
+The general process is to read
+.Tn struct archive_entry
+objects from an archive, then write those objects to a
+.Tn struct archive
+object created using the
+.Fn archive_write_disk
+family functions.
+This interface is deliberately very similar to the
+.Fn archive_write
+interface used to write objects to a streaming archive.
+.Bl -tag -width indent
+.It Fn archive_write_disk_new
+Allocates and initializes a
+.Tn struct archive
+object suitable for writing objects to disk.
+.It Fn archive_write_disk_set_skip_file
+Records the device and inode numbers of a file that should not be
+overwritten.
+This is typically used to ensure that an extraction process does not
+overwrite the archive from which objects are being read.
+This capability is technically unnecessary but can be a significant
+performance optimization in practice.
+.It Fn archive_write_disk_set_options
+The options field consists of a bitwise OR of one or more of the
+following values:
+.Bl -tag -compact -width "indent"
+.It Cm ARCHIVE_EXTRACT_OWNER
+The user and group IDs should be set on the restored file.
+By default, the user and group IDs are not restored.
+.It Cm ARCHIVE_EXTRACT_PERM
+Full permissions (including SGID, SUID, and sticky bits) should
+be restored exactly as specified, without obeying the
+current umask.
+Note that SUID and SGID bits can only be restored if the
+user and group ID of the object on disk are correct.
+If
+.Cm ARCHIVE_EXTRACT_OWNER
+is not specified, then SUID and SGID bits will only be restored
+if the default user and group IDs of newly-created objects on disk
+happen to match those specified in the archive entry.
+By default, only basic permissions are restored, and umask is obeyed.
+.It Cm ARCHIVE_EXTRACT_TIME
+The timestamps (mtime, ctime, and atime) should be restored.
+By default, they are ignored.
+Note that restoring of atime is not currently supported.
+.It Cm ARCHIVE_EXTRACT_NO_OVERWRITE
+Existing files on disk will not be overwritten.
+By default, existing regular files are truncated and overwritten;
+existing directories will have their permissions updated;
+other pre-existing objects are unlinked and recreated from scratch.
+.It Cm ARCHIVE_EXTRACT_UNLINK
+Existing files on disk will be unlinked before any attempt to
+create them.
+In some cases, this can prove to be a significant performance improvement.
+By default, existing files are truncated and rewritten, but
+the file is not recreated.
+In particular, the default behavior does not break existing hard links.
+.It Cm ARCHIVE_EXTRACT_ACL
+Attempt to restore ACLs.
+By default, extended ACLs are ignored.
+.It Cm ARCHIVE_EXTRACT_FFLAGS
+Attempt to restore extended file flags.
+By default, file flags are ignored.
+.It Cm ARCHIVE_EXTRACT_XATTR
+Attempt to restore POSIX.1e extended attributes.
+By default, they are ignored.
+.It Cm ARCHIVE_EXTRACT_SECURE_SYMLINKS
+Refuse to extract any object whose final location would be altered
+by a symlink on disk.
+This is intended to help guard against a variety of mischief
+caused by archives that (deliberately or otherwise) extract
+files outside of the current directory.
+The default is not to perform this check.
+If
+.Cm ARCHIVE_EXTRACT_UNLINK
+is specified together with this option, the library will
+remove any intermediate symlinks it finds and return an
+error only if such symlink could not be removed.
+.It Cm ARCHIVE_EXTRACT_SECURE_NODOTDOT
+Refuse to extract a path that contains a
+.Pa ..
+element anywhere within it.
+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_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.
+.El
+.It Xo
+.Fn archive_write_disk_set_group_lookup ,
+.Fn archive_write_disk_set_user_lookup
+.Xc
+The
+.Tn struct archive_entry
+objects contain both names and ids that can be used to identify users
+and groups.
+These names and ids describe the ownership of the file itself and
+also appear in ACL lists.
+By default, the library uses the ids and ignores the names, but
+this can be overridden by registering user and group lookup functions.
+To register, you must provide a lookup function which
+accepts both a name and id and returns a suitable id.
+You may also provide a
+.Tn void *
+pointer to a private data structure and a cleanup function for
+that data.
+The cleanup function will be invoked when the
+.Tn struct archive
+object is destroyed.
+.It Fn archive_write_disk_set_standard_lookup
+This convenience function installs a standard set of user
+and group lookup functions.
+These functions use
+.Xr getpwnam 3
+and
+.Xr getgrnam 3
+to convert names to ids, defaulting to the ids if the names cannot
+be looked up.
+These functions also implement a simple memory cache to reduce
+the number of calls to
+.Xr getpwnam 3
+and
+.Xr getgrnam 3 .
+.It Fn archive_write_header
+Build and write a header using the data in the provided
+.Tn struct archive_entry
+structure.
+See
+.Xr archive_entry 3
+for information on creating and populating
+.Tn struct archive_entry
+objects.
+.It Fn archive_write_data
+Write data corresponding to the header just written.
+Returns number of bytes written or -1 on error.
+.It Fn archive_write_data_block
+Write data corresponding to the header just written.
+This is like
+.Fn archive_write_data
+except that it performs a seek on the file being
+written to the specified offset before writing the data.
+This is useful when restoring sparse files from archive
+formats that support sparse files.
+Returns number of bytes written or -1 on error.
+(Note: This is currently not supported for
+.Tn archive_write
+handles, only for
+.Tn archive_write_disk
+handles.)
+.It Fn archive_write_finish_entry
+Close out the entry just written.
+Ordinarily, clients never need to call this, as it
+is called automatically by
+.Fn archive_write_next_header
+and
+.Fn archive_write_close
+as needed.
+However, some file attributes are written to disk only
+after the file is closed, so this can be necessary
+if you need to work with the file on disk right away.
+.It Fn archive_write_close
+Set any attributes that could not be set during the initial restore.
+For example, directory timestamps are not restored initially because
+restoring a subsequent file would alter that timestamp.
+Similarly, non-writable directories are initially created with
+write permissions (so that their contents can be restored).
+The
+.Nm
+library maintains a list of all such deferred attributes and
+sets them when this function is invoked.
+.It Fn archive_write_finish
+This is a deprecated synonym for
+.Fn archive_write_free .
+.It Fn archive_write_free
+Invokes
+.Fn archive_write_close
+if it was not invoked manually, then releases all resources.
+.El
+More information about the
+.Va struct archive
+object and the overall design of the library can be found in the
+.Xr libarchive 3
+overview.
+Many of these functions are also documented under
+.Xr archive_write 3 .
+.Sh RETURN VALUES
+Most functions return
+.Cm ARCHIVE_OK
+(zero) on success, or one of several non-zero
+error codes for errors.
+Specific error codes include:
+.Cm ARCHIVE_RETRY
+for operations that might succeed if retried,
+.Cm ARCHIVE_WARN
+for unusual conditions that do not prevent further operations, and
+.Cm ARCHIVE_FATAL
+for serious errors that make remaining operations impossible.
+.Pp
+.Fn archive_write_disk_new
+returns a pointer to a newly-allocated
+.Tn struct archive
+object.
+.Pp
+.Fn archive_write_data
+returns a count of the number of bytes actually written,
+or
+.Li -1
+on error.
+.\"
+.Sh ERRORS
+Detailed error codes and textual descriptions are available from the
+.Fn archive_errno
+and
+.Fn archive_error_string
+functions.
+.\"
+.Sh SEE ALSO
+.Xr archive_read 3 ,
+.Xr archive_write 3 ,
+.Xr tar 1 ,
+.Xr libarchive 3
+.Sh HISTORY
+The
+.Nm libarchive
+library first appeared in
+.Fx 5.3 .
+The
+.Nm archive_write_disk
+interface was added to
+.Nm libarchive 2.0
+and first appeared in
+.Fx 6.3 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm libarchive
+library was written by
+.An Tim Kientzle Aq kientzle@acm.org .
+.Sh BUGS
+Directories are actually extracted in two distinct phases.
+Directories are created during
+.Fn archive_write_header ,
+but final permissions are not set until
+.Fn archive_write_close .
+This separation is necessary to correctly handle borderline
+cases such as a non-writable directory containing
+files, but can cause unexpected results.
+In particular, directory permissions are not fully
+restored until the archive is closed.
+If you use
+.Xr chdir 2
+to change the current directory between calls to
+.Fn archive_read_extract
+or before calling
+.Fn archive_read_close ,
+you may confuse the permission-setting logic with
+the result that directory permissions are restored
+incorrectly.
+.Pp
+The library attempts to create objects with filenames longer than
+.Cm PATH_MAX
+by creating prefixes of the full path and changing the current directory.
+Currently, this logic is limited in scope; the fixup pass does
+not work correctly for such objects and the symlink security check
+option disables the support for very long pathnames.
+.Pp
+Restoring the path
+.Pa aa/../bb
+does create each intermediate directory.
+In particular, the directory
+.Pa aa
+is created as well as the final object
+.Pa bb .
+In theory, this can be exploited to create an entire directory hierarchy
+with a single request.
+Of course, this does not work if the
+.Cm ARCHIVE_EXTRACT_NODOTDOT
+option is specified.
+.Pp
+Implicit directories are always created obeying the current umask.
+Explicit objects are created obeying the current umask unless
+.Cm ARCHIVE_EXTRACT_PERM
+is specified, in which case they current umask is ignored.
+.Pp
+SGID and SUID bits are restored only if the correct user and
+group could be set.
+If
+.Cm ARCHIVE_EXTRACT_OWNER
+is not specified, then no attempt is made to set the ownership.
+In this case, SGID and SUID bits are restored only if the
+user and group of the final object happen to match those specified
+in the entry.
+.Pp
+The
+.Dq standard
+user-id and group-id lookup functions are not the defaults because
+.Xr getgrnam 3
+and
+.Xr getpwnam 3
+are sometimes too large for particular applications.
+The current design allows the application author to use a more
+compact implementation when appropriate.
+.Pp
+There should be a corresponding
+.Nm archive_read_disk
+interface that walks a directory hierarchy and returns archive
+entry objects.
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c b/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c
new file mode 100644
index 000000000..99afab2f6
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c
@@ -0,0 +1,2844 @@
+/*-
+ * Copyright (c) 2003-2010 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
+ * in this position and unchanged.
+ * 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$");
+
+#if !defined(_WIN32) || defined(__CYGWIN__)
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_ACL_H
+#include <sys/acl.h>
+#endif
+#ifdef HAVE_SYS_EXTATTR_H
+#include <sys/extattr.h>
+#endif
+#ifdef HAVE_SYS_XATTR_H
+#include <sys/xattr.h>
+#endif
+#ifdef HAVE_SYS_EA_H
+#include <sys/ea.h>
+#endif
+#ifdef HAVE_ATTR_XATTR_H
+#include <attr/xattr.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_UTIME_H
+#include <sys/utime.h>
+#endif
+#ifdef HAVE_COPYFILE_H
+#include <copyfile.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_GRP_H
+#include <grp.h>
+#endif
+#ifdef HAVE_LANGINFO_H
+#include <langinfo.h>
+#endif
+#ifdef HAVE_LINUX_FS_H
+#include <linux/fs.h> /* for Linux file flags */
+#endif
+/*
+ * Some Linux distributions have both linux/ext2_fs.h and ext2fs/ext2_fs.h.
+ * As the include guards don't agree, the order of include is important.
+ */
+#ifdef HAVE_LINUX_EXT2_FS_H
+#include <linux/ext2_fs.h> /* for Linux file flags */
+#endif
+#if defined(HAVE_EXT2FS_EXT2_FS_H) && !defined(__CYGWIN__)
+#include <ext2fs/ext2_fs.h> /* Linux file flags, broken on Cygwin */
+#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifdef HAVE_PWD_H
+#include <pwd.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_UTIME_H
+#include <utime.h>
+#endif
+#ifdef F_GETTIMES /* Tru64 specific */
+#include <sys/fcntl1.h>
+#endif
+
+#if __APPLE__
+#include <TargetConditionals.h>
+#if TARGET_OS_MAC && !TARGET_OS_EMBEDDED && HAVE_QUARANTINE_H
+#include <quarantine.h>
+#define HAVE_QUARANTINE 1
+#endif
+#endif
+
+/* TODO: Support Mac OS 'quarantine' feature. This is really just a
+ * standard tag to mark files that have been downloaded as "tainted".
+ * On Mac OS, we should mark the extracted files as tainted if the
+ * archive being read was tainted. Windows has a similar feature; we
+ * should investigate ways to support this generically. */
+
+#include "archive.h"
+#include "archive_acl_private.h"
+#include "archive_string.h"
+#include "archive_entry.h"
+#include "archive_private.h"
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+struct fixup_entry {
+ struct fixup_entry *next;
+ struct archive_acl acl;
+ mode_t mode;
+ int64_t atime;
+ int64_t birthtime;
+ int64_t mtime;
+ int64_t ctime;
+ unsigned long atime_nanos;
+ unsigned long birthtime_nanos;
+ unsigned long mtime_nanos;
+ unsigned long ctime_nanos;
+ unsigned long fflags_set;
+ size_t mac_metadata_size;
+ void *mac_metadata;
+ int fixup; /* bitmask of what needs fixing */
+ char *name;
+};
+
+/*
+ * We use a bitmask to track which operations remain to be done for
+ * this file. In particular, this helps us avoid unnecessary
+ * operations when it's possible to take care of one step as a
+ * side-effect of another. For example, mkdir() can specify the mode
+ * for the newly-created object but symlink() cannot. This means we
+ * can skip chmod() if mkdir() succeeded, but we must explicitly
+ * chmod() if we're trying to create a directory that already exists
+ * (mkdir() failed) or if we're restoring a symlink. Similarly, we
+ * need to verify UID/GID before trying to restore SUID/SGID bits;
+ * that verification can occur explicitly through a stat() call or
+ * implicitly because of a successful chown() call.
+ */
+#define TODO_MODE_FORCE 0x40000000
+#define TODO_MODE_BASE 0x20000000
+#define TODO_SUID 0x10000000
+#define TODO_SUID_CHECK 0x08000000
+#define TODO_SGID 0x04000000
+#define TODO_SGID_CHECK 0x02000000
+#define TODO_MODE (TODO_MODE_BASE|TODO_SUID|TODO_SGID)
+#define TODO_TIMES ARCHIVE_EXTRACT_TIME
+#define TODO_OWNER ARCHIVE_EXTRACT_OWNER
+#define TODO_FFLAGS ARCHIVE_EXTRACT_FFLAGS
+#define TODO_ACLS ARCHIVE_EXTRACT_ACL
+#define TODO_XATTR ARCHIVE_EXTRACT_XATTR
+#define TODO_MAC_METADATA ARCHIVE_EXTRACT_MAC_METADATA
+
+struct archive_write_disk {
+ struct archive archive;
+
+ mode_t user_umask;
+ struct fixup_entry *fixup_list;
+ struct fixup_entry *current_fixup;
+ int64_t user_uid;
+ int skip_file_set;
+ dev_t skip_file_dev;
+ ino_t skip_file_ino;
+ time_t start_time;
+
+ int64_t (*lookup_gid)(void *private, const char *gname, int64_t gid);
+ void (*cleanup_gid)(void *private);
+ void *lookup_gid_data;
+ int64_t (*lookup_uid)(void *private, const char *uname, int64_t uid);
+ void (*cleanup_uid)(void *private);
+ void *lookup_uid_data;
+
+ /*
+ * Full path of last file to satisfy symlink checks.
+ */
+ struct archive_string path_safe;
+
+ /*
+ * Cached stat data from disk for the current entry.
+ * If this is valid, pst points to st. Otherwise,
+ * pst is null.
+ */
+ struct stat st;
+ struct stat *pst;
+
+ /* Information about the object being restored right now. */
+ struct archive_entry *entry; /* Entry being extracted. */
+ char *name; /* Name of entry, possibly edited. */
+ struct archive_string _name_data; /* backing store for 'name' */
+ /* Tasks remaining for this object. */
+ int todo;
+ /* Tasks deferred until end-of-archive. */
+ int deferred;
+ /* Options requested by the client. */
+ int flags;
+ /* Handle for the file we're restoring. */
+ int fd;
+ /* Current offset for writing data to the file. */
+ int64_t offset;
+ /* Last offset actually written to disk. */
+ int64_t fd_offset;
+ /* Total bytes actually written to files. */
+ int64_t total_bytes_written;
+ /* Maximum size of file, -1 if unknown. */
+ int64_t filesize;
+ /* Dir we were in before this restore; only for deep paths. */
+ int restore_pwd;
+ /* Mode we should use for this entry; affected by _PERM and umask. */
+ mode_t mode;
+ /* UID/GID to use in restoring this entry. */
+ int64_t uid;
+ int64_t gid;
+};
+
+/*
+ * Default mode for dirs created automatically (will be modified by umask).
+ * Note that POSIX specifies 0777 for implicitly-created dirs, "modified
+ * by the process' file creation mask."
+ */
+#define DEFAULT_DIR_MODE 0777
+/*
+ * Dir modes are restored in two steps: During the extraction, the permissions
+ * in the archive are modified to match the following limits. During
+ * the post-extract fixup pass, the permissions from the archive are
+ * applied.
+ */
+#define MINIMUM_DIR_MODE 0700
+#define MAXIMUM_DIR_MODE 0775
+
+static int check_symlinks(struct archive_write_disk *);
+static int create_filesystem_object(struct archive_write_disk *);
+static struct fixup_entry *current_fixup(struct archive_write_disk *, const char *pathname);
+#if defined(HAVE_FCHDIR) && defined(PATH_MAX)
+static void edit_deep_directories(struct archive_write_disk *ad);
+#endif
+static int cleanup_pathname(struct archive_write_disk *);
+static int create_dir(struct archive_write_disk *, char *);
+static int create_parent_dir(struct archive_write_disk *, char *);
+static int older(struct stat *, struct archive_entry *);
+static int restore_entry(struct archive_write_disk *);
+#ifdef HAVE_POSIX_ACL
+static int set_acl(struct archive_write_disk *, int fd, const char *, struct archive_acl *,
+ acl_type_t, int archive_entry_acl_type, const char *tn);
+#endif
+static int set_acls(struct archive_write_disk *, int fd, const char *, struct archive_acl *);
+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 set_fflags(struct archive_write_disk *);
+static int set_fflags_platform(struct archive_write_disk *, int fd,
+ const char *name, mode_t mode,
+ unsigned long fflags_set, unsigned long fflags_clear);
+static int set_ownership(struct archive_write_disk *);
+static int set_mode(struct archive_write_disk *, int mode);
+static int set_time(int, int, const char *, time_t, long, time_t, long);
+static int set_times(struct archive_write_disk *, int, int, const char *,
+ time_t, long, time_t, long, time_t, long, time_t, long);
+static int set_times_from_entry(struct archive_write_disk *);
+static struct fixup_entry *sort_dir_list(struct fixup_entry *p);
+static ssize_t write_data_block(struct archive_write_disk *,
+ const char *, size_t);
+
+static struct archive_vtable *archive_write_disk_vtable(void);
+
+static int _archive_write_disk_close(struct archive *);
+static int _archive_write_disk_free(struct archive *);
+static int _archive_write_disk_header(struct archive *, struct archive_entry *);
+static int64_t _archive_write_disk_filter_bytes(struct archive *, int);
+static int _archive_write_disk_finish_entry(struct archive *);
+static ssize_t _archive_write_disk_data(struct archive *, const void *, size_t);
+static ssize_t _archive_write_disk_data_block(struct archive *, const void *, size_t, int64_t);
+
+static int
+lazy_stat(struct archive_write_disk *a)
+{
+ if (a->pst != NULL) {
+ /* Already have stat() data available. */
+ return (ARCHIVE_OK);
+ }
+#ifdef HAVE_FSTAT
+ if (a->fd >= 0 && fstat(a->fd, &a->st) == 0) {
+ a->pst = &a->st;
+ return (ARCHIVE_OK);
+ }
+#endif
+ /*
+ * XXX At this point, symlinks should not be hit, otherwise
+ * XXX a race occurred. Do we want to check explicitly for that?
+ */
+ if (lstat(a->name, &a->st) == 0) {
+ a->pst = &a->st;
+ return (ARCHIVE_OK);
+ }
+ archive_set_error(&a->archive, errno, "Couldn't stat file");
+ return (ARCHIVE_WARN);
+}
+
+static struct archive_vtable *
+archive_write_disk_vtable(void)
+{
+ static struct archive_vtable av;
+ static int inited = 0;
+
+ if (!inited) {
+ av.archive_close = _archive_write_disk_close;
+ av.archive_filter_bytes = _archive_write_disk_filter_bytes;
+ av.archive_free = _archive_write_disk_free;
+ av.archive_write_header = _archive_write_disk_header;
+ av.archive_write_finish_entry
+ = _archive_write_disk_finish_entry;
+ av.archive_write_data = _archive_write_disk_data;
+ av.archive_write_data_block = _archive_write_disk_data_block;
+ inited = 1;
+ }
+ return (&av);
+}
+
+static int64_t
+_archive_write_disk_filter_bytes(struct archive *_a, int n)
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+ (void)n; /* UNUSED */
+ if (n == -1 || n == 0)
+ return (a->total_bytes_written);
+ return (-1);
+}
+
+
+int
+archive_write_disk_set_options(struct archive *_a, int flags)
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+
+ a->flags = flags;
+ return (ARCHIVE_OK);
+}
+
+
+/*
+ * Extract this entry to disk.
+ *
+ * TODO: Validate hardlinks. According to the standards, we're
+ * supposed to check each extracted hardlink and squawk if it refers
+ * to a file that we didn't restore. I'm not entirely convinced this
+ * is a good idea, but more importantly: Is there any way to validate
+ * hardlinks without keeping a complete list of filenames from the
+ * entire archive?? Ugh.
+ *
+ */
+static int
+_archive_write_disk_header(struct archive *_a, struct archive_entry *entry)
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+ struct fixup_entry *fe;
+ int ret, r;
+
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
+ "archive_write_disk_header");
+ archive_clear_error(&a->archive);
+ if (a->archive.state & ARCHIVE_STATE_DATA) {
+ r = _archive_write_disk_finish_entry(&a->archive);
+ if (r == ARCHIVE_FATAL)
+ return (r);
+ }
+
+ /* Set up for this particular entry. */
+ a->pst = NULL;
+ a->current_fixup = NULL;
+ a->deferred = 0;
+ if (a->entry) {
+ archive_entry_free(a->entry);
+ a->entry = NULL;
+ }
+ a->entry = archive_entry_clone(entry);
+ a->fd = -1;
+ a->fd_offset = 0;
+ a->offset = 0;
+ a->restore_pwd = -1;
+ a->uid = a->user_uid;
+ a->mode = archive_entry_mode(a->entry);
+ if (archive_entry_size_is_set(a->entry))
+ a->filesize = archive_entry_size(a->entry);
+ else
+ a->filesize = -1;
+ archive_strcpy(&(a->_name_data), archive_entry_pathname(a->entry));
+ a->name = a->_name_data.s;
+ archive_clear_error(&a->archive);
+
+ /*
+ * Clean up the requested path. This is necessary for correct
+ * dir restores; the dir restore logic otherwise gets messed
+ * up by nonsense like "dir/.".
+ */
+ ret = cleanup_pathname(a);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+
+ /*
+ * Query the umask so we get predictable mode settings.
+ * This gets done on every call to _write_header in case the
+ * user edits their umask during the extraction for some
+ * reason.
+ */
+ umask(a->user_umask = umask(0));
+
+ /* Figure out what we need to do for this entry. */
+ a->todo = TODO_MODE_BASE;
+ if (a->flags & ARCHIVE_EXTRACT_PERM) {
+ a->todo |= TODO_MODE_FORCE; /* Be pushy about permissions. */
+ /*
+ * SGID requires an extra "check" step because we
+ * cannot easily predict the GID that the system will
+ * assign. (Different systems assign GIDs to files
+ * based on a variety of criteria, including process
+ * credentials and the gid of the enclosing
+ * directory.) We can only restore the SGID bit if
+ * the file has the right GID, and we only know the
+ * GID if we either set it (see set_ownership) or if
+ * we've actually called stat() on the file after it
+ * was restored. Since there are several places at
+ * which we might verify the GID, we need a TODO bit
+ * to keep track.
+ */
+ if (a->mode & S_ISGID)
+ a->todo |= TODO_SGID | TODO_SGID_CHECK;
+ /*
+ * Verifying the SUID is simpler, but can still be
+ * done in multiple ways, hence the separate "check" bit.
+ */
+ if (a->mode & S_ISUID)
+ a->todo |= TODO_SUID | TODO_SUID_CHECK;
+ } else {
+ /*
+ * User didn't request full permissions, so don't
+ * restore SUID, SGID bits and obey umask.
+ */
+ a->mode &= ~S_ISUID;
+ a->mode &= ~S_ISGID;
+ a->mode &= ~S_ISVTX;
+ a->mode &= ~a->user_umask;
+ }
+ if (a->flags & ARCHIVE_EXTRACT_OWNER)
+ a->todo |= TODO_OWNER;
+ if (a->flags & ARCHIVE_EXTRACT_TIME)
+ a->todo |= TODO_TIMES;
+ if (a->flags & ARCHIVE_EXTRACT_ACL) {
+ if (archive_entry_filetype(a->entry) == AE_IFDIR)
+ a->deferred |= TODO_ACLS;
+ else
+ a->todo |= TODO_ACLS;
+ }
+ if (a->flags & ARCHIVE_EXTRACT_MAC_METADATA) {
+ if (archive_entry_filetype(a->entry) == AE_IFDIR)
+ a->deferred |= TODO_MAC_METADATA;
+ else
+ a->todo |= TODO_MAC_METADATA;
+ }
+ if (a->flags & ARCHIVE_EXTRACT_XATTR)
+ a->todo |= TODO_XATTR;
+ if (a->flags & ARCHIVE_EXTRACT_FFLAGS)
+ a->todo |= TODO_FFLAGS;
+ if (a->flags & ARCHIVE_EXTRACT_SECURE_SYMLINKS) {
+ ret = check_symlinks(a);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ }
+#if defined(HAVE_FCHDIR) && defined(PATH_MAX)
+ /* If path exceeds PATH_MAX, shorten the path. */
+ edit_deep_directories(a);
+#endif
+
+ ret = restore_entry(a);
+
+ /*
+ * TODO: There are rumours that some extended attributes must
+ * be restored before file data is written. If this is true,
+ * then we either need to write all extended attributes both
+ * before and after restoring the data, or find some rule for
+ * determining which must go first and which last. Due to the
+ * many ways people are using xattrs, this may prove to be an
+ * intractable problem.
+ */
+
+#ifdef HAVE_FCHDIR
+ /* If we changed directory above, restore it here. */
+ if (a->restore_pwd >= 0) {
+ r = fchdir(a->restore_pwd);
+ if (r != 0) {
+ archive_set_error(&a->archive, errno, "chdir() failure");
+ ret = ARCHIVE_FATAL;
+ }
+ close(a->restore_pwd);
+ a->restore_pwd = -1;
+ }
+#endif
+
+ /*
+ * Fixup uses the unedited pathname from archive_entry_pathname(),
+ * because it is relative to the base dir and the edited path
+ * might be relative to some intermediate dir as a result of the
+ * deep restore logic.
+ */
+ if (a->deferred & TODO_MODE) {
+ fe = current_fixup(a, archive_entry_pathname(entry));
+ fe->fixup |= TODO_MODE_BASE;
+ fe->mode = a->mode;
+ }
+
+ if ((a->deferred & TODO_TIMES)
+ && (archive_entry_mtime_is_set(entry)
+ || archive_entry_atime_is_set(entry))) {
+ fe = current_fixup(a, archive_entry_pathname(entry));
+ fe->mode = a->mode;
+ fe->fixup |= TODO_TIMES;
+ if (archive_entry_atime_is_set(entry)) {
+ fe->atime = archive_entry_atime(entry);
+ fe->atime_nanos = archive_entry_atime_nsec(entry);
+ } else {
+ /* If atime is unset, use start time. */
+ fe->atime = a->start_time;
+ fe->atime_nanos = 0;
+ }
+ if (archive_entry_mtime_is_set(entry)) {
+ fe->mtime = archive_entry_mtime(entry);
+ fe->mtime_nanos = archive_entry_mtime_nsec(entry);
+ } else {
+ /* If mtime is unset, use start time. */
+ fe->mtime = a->start_time;
+ fe->mtime_nanos = 0;
+ }
+ if (archive_entry_birthtime_is_set(entry)) {
+ fe->birthtime = archive_entry_birthtime(entry);
+ fe->birthtime_nanos = archive_entry_birthtime_nsec(entry);
+ } else {
+ /* If birthtime is unset, use mtime. */
+ fe->birthtime = fe->mtime;
+ fe->birthtime_nanos = fe->mtime_nanos;
+ }
+ }
+
+ if (a->deferred & TODO_ACLS) {
+ fe = current_fixup(a, archive_entry_pathname(entry));
+ archive_acl_copy(&fe->acl, archive_entry_acl(entry));
+ }
+
+ if (a->deferred & TODO_MAC_METADATA) {
+ const void *metadata;
+ size_t metadata_size;
+ metadata = archive_entry_mac_metadata(a->entry, &metadata_size);
+ if (metadata != NULL && metadata_size > 0) {
+ fe = current_fixup(a, archive_entry_pathname(entry));
+ fe->mac_metadata = malloc(metadata_size);
+ if (fe->mac_metadata != NULL) {
+ memcpy(fe->mac_metadata, metadata, metadata_size);
+ fe->mac_metadata_size = metadata_size;
+ fe->fixup |= TODO_MAC_METADATA;
+ }
+ }
+ }
+
+ if (a->deferred & TODO_FFLAGS) {
+ fe = current_fixup(a, archive_entry_pathname(entry));
+ fe->fixup |= TODO_FFLAGS;
+ /* TODO: Complete this.. defer fflags from below. */
+ }
+
+ /* We've created the object and are ready to pour data into it. */
+ if (ret >= ARCHIVE_WARN)
+ a->archive.state = ARCHIVE_STATE_DATA;
+ /*
+ * If it's not open, tell our client not to try writing.
+ * In particular, dirs, links, etc, don't get written to.
+ */
+ if (a->fd < 0) {
+ archive_entry_set_size(entry, 0);
+ a->filesize = 0;
+ }
+
+ return (ret);
+}
+
+int
+archive_write_disk_set_skip_file(struct archive *_a, int64_t d, int64_t i)
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_write_disk_set_skip_file");
+ a->skip_file_set = 1;
+ a->skip_file_dev = d;
+ a->skip_file_ino = i;
+ return (ARCHIVE_OK);
+}
+
+static ssize_t
+write_data_block(struct archive_write_disk *a, const char *buff, size_t size)
+{
+ uint64_t start_size = size;
+ ssize_t bytes_written = 0;
+ ssize_t block_size = 0, bytes_to_write;
+
+ if (size == 0)
+ return (ARCHIVE_OK);
+
+ if (a->filesize == 0 || a->fd < 0) {
+ archive_set_error(&a->archive, 0,
+ "Attempt to write to an empty file");
+ return (ARCHIVE_WARN);
+ }
+
+ if (a->flags & ARCHIVE_EXTRACT_SPARSE) {
+#if HAVE_STRUCT_STAT_ST_BLKSIZE
+ int r;
+ if ((r = lazy_stat(a)) != ARCHIVE_OK)
+ return (r);
+ block_size = a->pst->st_blksize;
+#else
+ /* XXX TODO XXX Is there a more appropriate choice here ? */
+ /* This needn't match the filesystem allocation size. */
+ block_size = 16*1024;
+#endif
+ }
+
+ /* If this write would run beyond the file size, truncate it. */
+ if (a->filesize >= 0 && (int64_t)(a->offset + size) > a->filesize)
+ start_size = size = (size_t)(a->filesize - a->offset);
+
+ /* Write the data. */
+ while (size > 0) {
+ if (block_size == 0) {
+ bytes_to_write = size;
+ } else {
+ /* We're sparsifying the file. */
+ const char *p, *end;
+ int64_t block_end;
+
+ /* Skip leading zero bytes. */
+ for (p = buff, end = buff + size; p < end; ++p) {
+ if (*p != '\0')
+ break;
+ }
+ a->offset += p - buff;
+ size -= p - buff;
+ buff = p;
+ if (size == 0)
+ break;
+
+ /* Calculate next block boundary after offset. */
+ block_end
+ = (a->offset / block_size + 1) * block_size;
+
+ /* If the adjusted write would cross block boundary,
+ * truncate it to the block boundary. */
+ bytes_to_write = size;
+ if (a->offset + bytes_to_write > block_end)
+ bytes_to_write = block_end - a->offset;
+ }
+ /* Seek if necessary to the specified offset. */
+ if (a->offset != a->fd_offset) {
+ if (lseek(a->fd, a->offset, SEEK_SET) < 0) {
+ archive_set_error(&a->archive, errno,
+ "Seek failed");
+ return (ARCHIVE_FATAL);
+ }
+ a->fd_offset = a->offset;
+ }
+ bytes_written = write(a->fd, buff, bytes_to_write);
+ if (bytes_written < 0) {
+ archive_set_error(&a->archive, errno, "Write failed");
+ return (ARCHIVE_WARN);
+ }
+ buff += bytes_written;
+ size -= bytes_written;
+ a->total_bytes_written += bytes_written;
+ a->offset += bytes_written;
+ a->fd_offset = a->offset;
+ }
+ return (start_size - size);
+}
+
+static ssize_t
+_archive_write_disk_data_block(struct archive *_a,
+ const void *buff, size_t size, int64_t offset)
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+ ssize_t r;
+
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_DATA, "archive_write_data_block");
+
+ a->offset = offset;
+ r = write_data_block(a, buff, size);
+ if (r < ARCHIVE_OK)
+ return (r);
+ if ((size_t)r < size) {
+ archive_set_error(&a->archive, 0,
+ "Write request too large");
+ return (ARCHIVE_WARN);
+ }
+ return (ARCHIVE_OK);
+}
+
+static ssize_t
+_archive_write_disk_data(struct archive *_a, const void *buff, size_t size)
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_DATA, "archive_write_data");
+
+ return (write_data_block(a, buff, size));
+}
+
+static int
+_archive_write_disk_finish_entry(struct archive *_a)
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+ int ret = ARCHIVE_OK;
+
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
+ "archive_write_finish_entry");
+ if (a->archive.state & ARCHIVE_STATE_HEADER)
+ return (ARCHIVE_OK);
+ archive_clear_error(&a->archive);
+
+ /* Pad or truncate file to the right size. */
+ if (a->fd < 0) {
+ /* There's no file. */
+ } else if (a->filesize < 0) {
+ /* File size is unknown, so we can't set the size. */
+ } else if (a->fd_offset == a->filesize) {
+ /* Last write ended at exactly the filesize; we're done. */
+ /* Hopefully, this is the common case. */
+ } else {
+#if HAVE_FTRUNCATE
+ if (ftruncate(a->fd, a->filesize) == -1 &&
+ a->filesize == 0) {
+ archive_set_error(&a->archive, errno,
+ "File size could not be restored");
+ return (ARCHIVE_FAILED);
+ }
+#endif
+ /*
+ * Not all platforms implement the XSI option to
+ * extend files via ftruncate. Stat() the file again
+ * to see what happened.
+ */
+ a->pst = NULL;
+ if ((ret = lazy_stat(a)) != ARCHIVE_OK)
+ return (ret);
+ /* We can use lseek()/write() to extend the file if
+ * ftruncate didn't work or isn't available. */
+ if (a->st.st_size < a->filesize) {
+ const char nul = '\0';
+ if (lseek(a->fd, a->filesize - 1, SEEK_SET) < 0) {
+ archive_set_error(&a->archive, errno,
+ "Seek failed");
+ return (ARCHIVE_FATAL);
+ }
+ if (write(a->fd, &nul, 1) < 0) {
+ archive_set_error(&a->archive, errno,
+ "Write to restore size failed");
+ return (ARCHIVE_FATAL);
+ }
+ a->pst = NULL;
+ }
+ }
+
+ /* Restore metadata. */
+
+ /*
+ * Look up the "real" UID only if we're going to need it.
+ * TODO: the TODO_SGID condition can be dropped here, can't it?
+ */
+ if (a->todo & (TODO_OWNER | TODO_SUID | TODO_SGID)) {
+ a->uid = archive_write_disk_uid(&a->archive,
+ archive_entry_uname(a->entry),
+ archive_entry_uid(a->entry));
+ }
+ /* Look up the "real" GID only if we're going to need it. */
+ /* TODO: the TODO_SUID condition can be dropped here, can't it? */
+ if (a->todo & (TODO_OWNER | TODO_SGID | TODO_SUID)) {
+ a->gid = archive_write_disk_gid(&a->archive,
+ archive_entry_gname(a->entry),
+ archive_entry_gid(a->entry));
+ }
+
+ /*
+ * Restore ownership before set_mode tries to restore suid/sgid
+ * bits. If we set the owner, we know what it is and can skip
+ * a stat() call to examine the ownership of the file on disk.
+ */
+ if (a->todo & TODO_OWNER)
+ ret = set_ownership(a);
+
+ /*
+ * set_mode must precede ACLs on systems such as Solaris and
+ * FreeBSD where setting the mode implicitly clears extended ACLs
+ */
+ if (a->todo & TODO_MODE) {
+ int r2 = set_mode(a, a->mode);
+ if (r2 < ret) ret = r2;
+ }
+
+ /*
+ * Security-related extended attributes (such as
+ * security.capability on Linux) have to be restored last,
+ * since they're implicitly removed by other file changes.
+ */
+ if (a->todo & TODO_XATTR) {
+ int r2 = set_xattrs(a);
+ if (r2 < ret) ret = r2;
+ }
+
+ /*
+ * Some flags prevent file modification; they must be restored after
+ * file contents are written.
+ */
+ if (a->todo & TODO_FFLAGS) {
+ int r2 = set_fflags(a);
+ if (r2 < ret) ret = r2;
+ }
+
+ /*
+ * Time must follow most other metadata;
+ * otherwise atime will get changed.
+ */
+ if (a->todo & TODO_TIMES) {
+ int r2 = set_times_from_entry(a);
+ if (r2 < ret) ret = r2;
+ }
+
+ /*
+ * Mac extended metadata includes ACLs.
+ */
+ if (a->todo & TODO_MAC_METADATA) {
+ const void *metadata;
+ size_t metadata_size;
+ metadata = archive_entry_mac_metadata(a->entry, &metadata_size);
+ if (metadata != NULL && metadata_size > 0) {
+ int r2 = set_mac_metadata(a, archive_entry_pathname(a->entry), metadata, metadata_size);
+ if (r2 < ret) ret = r2;
+ }
+ }
+
+ /*
+ * ACLs must be restored after timestamps because there are
+ * ACLs that prevent attribute changes (including time).
+ */
+ if (a->todo & TODO_ACLS) {
+ int r2 = set_acls(a, a->fd,
+ archive_entry_pathname(a->entry),
+ archive_entry_acl(a->entry));
+ if (r2 < ret) ret = r2;
+ }
+
+ /* If there's an fd, we can close it now. */
+ if (a->fd >= 0) {
+ close(a->fd);
+ a->fd = -1;
+ }
+ /* If there's an entry, we can release it now. */
+ if (a->entry) {
+ archive_entry_free(a->entry);
+ a->entry = NULL;
+ }
+ a->archive.state = ARCHIVE_STATE_HEADER;
+ return (ret);
+}
+
+int
+archive_write_disk_set_group_lookup(struct archive *_a,
+ void *private_data,
+ int64_t (*lookup_gid)(void *private, const char *gname, int64_t gid),
+ void (*cleanup_gid)(void *private))
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_write_disk_set_group_lookup");
+
+ if (a->cleanup_gid != NULL && a->lookup_gid_data != NULL)
+ (a->cleanup_gid)(a->lookup_gid_data);
+
+ a->lookup_gid = lookup_gid;
+ a->cleanup_gid = cleanup_gid;
+ a->lookup_gid_data = private_data;
+ return (ARCHIVE_OK);
+}
+
+int
+archive_write_disk_set_user_lookup(struct archive *_a,
+ void *private_data,
+ int64_t (*lookup_uid)(void *private, const char *uname, int64_t uid),
+ void (*cleanup_uid)(void *private))
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_write_disk_set_user_lookup");
+
+ if (a->cleanup_uid != NULL && a->lookup_uid_data != NULL)
+ (a->cleanup_uid)(a->lookup_uid_data);
+
+ a->lookup_uid = lookup_uid;
+ a->cleanup_uid = cleanup_uid;
+ a->lookup_uid_data = private_data;
+ return (ARCHIVE_OK);
+}
+
+int64_t
+archive_write_disk_gid(struct archive *_a, const char *name, int64_t id)
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_write_disk_gid");
+ if (a->lookup_gid)
+ return (a->lookup_gid)(a->lookup_gid_data, name, id);
+ return (id);
+}
+
+int64_t
+archive_write_disk_uid(struct archive *_a, const char *name, int64_t id)
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_write_disk_uid");
+ if (a->lookup_uid)
+ return (a->lookup_uid)(a->lookup_uid_data, name, id);
+ return (id);
+}
+
+/*
+ * Create a new archive_write_disk object and initialize it with global state.
+ */
+struct archive *
+archive_write_disk_new(void)
+{
+ struct archive_write_disk *a;
+
+ a = (struct archive_write_disk *)malloc(sizeof(*a));
+ if (a == NULL)
+ return (NULL);
+ memset(a, 0, sizeof(*a));
+ a->archive.magic = ARCHIVE_WRITE_DISK_MAGIC;
+ /* We're ready to write a header immediately. */
+ a->archive.state = ARCHIVE_STATE_HEADER;
+ a->archive.vtable = archive_write_disk_vtable();
+ a->start_time = time(NULL);
+ /* Query and restore the umask. */
+ umask(a->user_umask = umask(0));
+#ifdef HAVE_GETEUID
+ a->user_uid = geteuid();
+#endif /* HAVE_GETEUID */
+ if (archive_string_ensure(&a->path_safe, 512) == NULL) {
+ free(a);
+ return (NULL);
+ }
+ return (&a->archive);
+}
+
+
+/*
+ * If pathname is longer than PATH_MAX, chdir to a suitable
+ * intermediate dir and edit the path down to a shorter suffix. Note
+ * that this routine never returns an error; if the chdir() attempt
+ * fails for any reason, we just go ahead with the long pathname. The
+ * object creation is likely to fail, but any error will get handled
+ * at that time.
+ */
+#if defined(HAVE_FCHDIR) && defined(PATH_MAX)
+static void
+edit_deep_directories(struct archive_write_disk *a)
+{
+ int ret;
+ char *tail = a->name;
+
+ /* If path is short, avoid the open() below. */
+ if (strlen(tail) <= PATH_MAX)
+ return;
+
+ /* Try to record our starting dir. */
+ a->restore_pwd = open(".", O_RDONLY | O_BINARY);
+ if (a->restore_pwd < 0)
+ return;
+
+ /* As long as the path is too long... */
+ while (strlen(tail) > PATH_MAX) {
+ /* Locate a dir prefix shorter than PATH_MAX. */
+ tail += PATH_MAX - 8;
+ while (tail > a->name && *tail != '/')
+ tail--;
+ /* Exit if we find a too-long path component. */
+ if (tail <= a->name)
+ return;
+ /* Create the intermediate dir and chdir to it. */
+ *tail = '\0'; /* Terminate dir portion */
+ ret = create_dir(a, a->name);
+ if (ret == ARCHIVE_OK && chdir(a->name) != 0)
+ ret = ARCHIVE_FAILED;
+ *tail = '/'; /* Restore the / we removed. */
+ if (ret != ARCHIVE_OK)
+ return;
+ tail++;
+ /* The chdir() succeeded; we've now shortened the path. */
+ a->name = tail;
+ }
+ return;
+}
+#endif
+
+/*
+ * The main restore function.
+ */
+static int
+restore_entry(struct archive_write_disk *a)
+{
+ int ret = ARCHIVE_OK, en;
+
+ if (a->flags & ARCHIVE_EXTRACT_UNLINK && !S_ISDIR(a->mode)) {
+ /*
+ * TODO: Fix this. Apparently, there are platforms
+ * that still allow root to hose the entire filesystem
+ * by unlinking a dir. The S_ISDIR() test above
+ * prevents us from using unlink() here if the new
+ * object is a dir, but that doesn't mean the old
+ * object isn't a dir.
+ */
+ if (unlink(a->name) == 0) {
+ /* We removed it, reset cached stat. */
+ a->pst = NULL;
+ } else if (errno == ENOENT) {
+ /* File didn't exist, that's just as good. */
+ } else if (rmdir(a->name) == 0) {
+ /* It was a dir, but now it's gone. */
+ a->pst = NULL;
+ } else {
+ /* We tried, but couldn't get rid of it. */
+ archive_set_error(&a->archive, errno,
+ "Could not unlink");
+ return(ARCHIVE_FAILED);
+ }
+ }
+
+ /* Try creating it first; if this fails, we'll try to recover. */
+ en = create_filesystem_object(a);
+
+ if ((en == ENOTDIR || en == ENOENT)
+ && !(a->flags & ARCHIVE_EXTRACT_NO_AUTODIR)) {
+ /* If the parent dir doesn't exist, try creating it. */
+ create_parent_dir(a, a->name);
+ /* Now try to create the object again. */
+ en = create_filesystem_object(a);
+ }
+
+ if ((en == EISDIR || en == EEXIST)
+ && (a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE)) {
+ /* If we're not overwriting, we're done. */
+ archive_entry_unset_size(a->entry);
+ return (ARCHIVE_OK);
+ }
+
+ /*
+ * Some platforms return EISDIR if you call
+ * open(O_WRONLY | O_EXCL | O_CREAT) on a directory, some
+ * return EEXIST. POSIX is ambiguous, requiring EISDIR
+ * for open(O_WRONLY) on a dir and EEXIST for open(O_EXCL | O_CREAT)
+ * on an existing item.
+ */
+ if (en == EISDIR) {
+ /* A dir is in the way of a non-dir, rmdir it. */
+ if (rmdir(a->name) != 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't remove already-existing dir");
+ return (ARCHIVE_FAILED);
+ }
+ a->pst = NULL;
+ /* Try again. */
+ en = create_filesystem_object(a);
+ } else if (en == EEXIST) {
+ /*
+ * We know something is in the way, but we don't know what;
+ * we need to find out before we go any further.
+ */
+ int r = 0;
+ /*
+ * The SECURE_SYMLINKS logic has already removed a
+ * symlink to a dir if the client wants that. So
+ * follow the symlink if we're creating a dir.
+ */
+ if (S_ISDIR(a->mode))
+ r = stat(a->name, &a->st);
+ /*
+ * If it's not a dir (or it's a broken symlink),
+ * then don't follow it.
+ */
+ if (r != 0 || !S_ISDIR(a->mode))
+ r = lstat(a->name, &a->st);
+ if (r != 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't stat existing object");
+ return (ARCHIVE_FAILED);
+ }
+
+ /*
+ * NO_OVERWRITE_NEWER doesn't apply to directories.
+ */
+ if ((a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER)
+ && !S_ISDIR(a->st.st_mode)) {
+ if (!older(&(a->st), a->entry)) {
+ archive_entry_unset_size(a->entry);
+ return (ARCHIVE_OK);
+ }
+ }
+
+ /* If it's our archive, we're done. */
+ if (a->skip_file_set &&
+ a->st.st_dev == a->skip_file_dev &&
+ a->st.st_ino == a->skip_file_ino) {
+ archive_set_error(&a->archive, 0, "Refusing to overwrite archive");
+ return (ARCHIVE_FAILED);
+ }
+
+ if (!S_ISDIR(a->st.st_mode)) {
+ /* A non-dir is in the way, unlink it. */
+ if (unlink(a->name) != 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't unlink already-existing object");
+ return (ARCHIVE_FAILED);
+ }
+ a->pst = NULL;
+ /* Try again. */
+ en = create_filesystem_object(a);
+ } else if (!S_ISDIR(a->mode)) {
+ /* A dir is in the way of a non-dir, rmdir it. */
+ if (rmdir(a->name) != 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't remove already-existing dir");
+ return (ARCHIVE_FAILED);
+ }
+ /* Try again. */
+ en = create_filesystem_object(a);
+ } else {
+ /*
+ * There's a dir in the way of a dir. Don't
+ * waste time with rmdir()/mkdir(), just fix
+ * up the permissions on the existing dir.
+ * Note that we don't change perms on existing
+ * dirs unless _EXTRACT_PERM is specified.
+ */
+ if ((a->mode != a->st.st_mode)
+ && (a->todo & TODO_MODE_FORCE))
+ a->deferred |= (a->todo & TODO_MODE);
+ /* Ownership doesn't need deferred fixup. */
+ en = 0; /* Forget the EEXIST. */
+ }
+ }
+
+ if (en) {
+ /* Everything failed; give up here. */
+ archive_set_error(&a->archive, en, "Can't create '%s'",
+ a->name);
+ return (ARCHIVE_FAILED);
+ }
+
+ a->pst = NULL; /* Cached stat data no longer valid. */
+ return (ret);
+}
+
+/*
+ * Returns 0 if creation succeeds, or else returns errno value from
+ * the failed system call. Note: This function should only ever perform
+ * a single system call.
+ */
+static int
+create_filesystem_object(struct archive_write_disk *a)
+{
+ /* Create the entry. */
+ const char *linkname;
+ mode_t final_mode, mode;
+ int r;
+
+ /* We identify hard/symlinks according to the link names. */
+ /* Since link(2) and symlink(2) don't handle modes, we're done here. */
+ linkname = archive_entry_hardlink(a->entry);
+ if (linkname != NULL) {
+#if !HAVE_LINK
+ return (EPERM);
+#else
+ r = link(linkname, a->name) ? errno : 0;
+ /*
+ * New cpio and pax formats allow hardlink entries
+ * to carry data, so we may have to open the file
+ * for hardlink entries.
+ *
+ * If the hardlink was successfully created and
+ * the archive doesn't have carry data for it,
+ * consider it to be non-authoritive for meta data.
+ * This is consistent with GNU tar and BSD pax.
+ * If the hardlink does carry data, let the last
+ * archive entry decide ownership.
+ */
+ if (r == 0 && a->filesize <= 0) {
+ a->todo = 0;
+ a->deferred = 0;
+ } else if (r == 0 && a->filesize > 0) {
+ a->fd = open(a->name, O_WRONLY | O_TRUNC | O_BINARY);
+ if (a->fd < 0)
+ r = errno;
+ }
+ return (r);
+#endif
+ }
+ linkname = archive_entry_symlink(a->entry);
+ if (linkname != NULL) {
+#if HAVE_SYMLINK
+ return symlink(linkname, a->name) ? errno : 0;
+#else
+ return (EPERM);
+#endif
+ }
+
+ /*
+ * The remaining system calls all set permissions, so let's
+ * try to take advantage of that to avoid an extra chmod()
+ * call. (Recall that umask is set to zero right now!)
+ */
+
+ /* Mode we want for the final restored object (w/o file type bits). */
+ final_mode = a->mode & 07777;
+ /*
+ * The mode that will actually be restored in this step. Note
+ * that SUID, SGID, etc, require additional work to ensure
+ * security, so we never restore them at this point.
+ */
+ mode = final_mode & 0777 & a->user_umask;
+
+ switch (a->mode & AE_IFMT) {
+ default:
+ /* POSIX requires that we fall through here. */
+ /* FALLTHROUGH */
+ case AE_IFREG:
+ a->fd = open(a->name,
+ O_WRONLY | O_CREAT | O_EXCL | O_BINARY, mode);
+ r = (a->fd < 0);
+ break;
+ case AE_IFCHR:
+#ifdef HAVE_MKNOD
+ /* Note: we use AE_IFCHR for the case label, and
+ * S_IFCHR for the mknod() call. This is correct. */
+ r = mknod(a->name, mode | S_IFCHR,
+ archive_entry_rdev(a->entry));
+ break;
+#else
+ /* TODO: Find a better way to warn about our inability
+ * to restore a char device node. */
+ return (EINVAL);
+#endif /* HAVE_MKNOD */
+ case AE_IFBLK:
+#ifdef HAVE_MKNOD
+ r = mknod(a->name, mode | S_IFBLK,
+ archive_entry_rdev(a->entry));
+ break;
+#else
+ /* TODO: Find a better way to warn about our inability
+ * to restore a block device node. */
+ return (EINVAL);
+#endif /* HAVE_MKNOD */
+ case AE_IFDIR:
+ mode = (mode | MINIMUM_DIR_MODE) & MAXIMUM_DIR_MODE;
+ r = mkdir(a->name, mode);
+ if (r == 0) {
+ /* Defer setting dir times. */
+ a->deferred |= (a->todo & TODO_TIMES);
+ a->todo &= ~TODO_TIMES;
+ /* Never use an immediate chmod(). */
+ /* We can't avoid the chmod() entirely if EXTRACT_PERM
+ * because of SysV SGID inheritance. */
+ if ((mode != final_mode)
+ || (a->flags & ARCHIVE_EXTRACT_PERM))
+ a->deferred |= (a->todo & TODO_MODE);
+ a->todo &= ~TODO_MODE;
+ }
+ break;
+ case AE_IFIFO:
+#ifdef HAVE_MKFIFO
+ r = mkfifo(a->name, mode);
+ break;
+#else
+ /* TODO: Find a better way to warn about our inability
+ * to restore a fifo. */
+ return (EINVAL);
+#endif /* HAVE_MKFIFO */
+ }
+
+ /* All the system calls above set errno on failure. */
+ if (r)
+ return (errno);
+
+ /* If we managed to set the final mode, we've avoided a chmod(). */
+ if (mode == final_mode)
+ a->todo &= ~TODO_MODE;
+ return (0);
+}
+
+/*
+ * Cleanup function for archive_extract. Mostly, this involves processing
+ * the fixup list, which is used to address a number of problems:
+ * * Dir permissions might prevent us from restoring a file in that
+ * dir, so we restore the dir with minimum 0700 permissions first,
+ * then correct the mode at the end.
+ * * Similarly, the act of restoring a file touches the directory
+ * and changes the timestamp on the dir, so we have to touch-up dir
+ * timestamps at the end as well.
+ * * Some file flags can interfere with the restore by, for example,
+ * preventing the creation of hardlinks to those files.
+ * * Mac OS extended metadata includes ACLs, so must be deferred on dirs.
+ *
+ * Note that tar/cpio do not require that archives be in a particular
+ * order; there is no way to know when the last file has been restored
+ * within a directory, so there's no way to optimize the memory usage
+ * here by fixing up the directory any earlier than the
+ * end-of-archive.
+ *
+ * XXX TODO: Directory ACLs should be restored here, for the same
+ * reason we set directory perms here. XXX
+ */
+static int
+_archive_write_disk_close(struct archive *_a)
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+ struct fixup_entry *next, *p;
+ int ret;
+
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
+ "archive_write_disk_close");
+ ret = _archive_write_disk_finish_entry(&a->archive);
+
+ /* Sort dir list so directories are fixed up in depth-first order. */
+ p = sort_dir_list(a->fixup_list);
+
+ while (p != NULL) {
+ a->pst = NULL; /* Mark stat cache as out-of-date. */
+ if (p->fixup & TODO_TIMES) {
+ set_times(a, -1, p->mode, p->name,
+ p->atime, p->atime_nanos,
+ p->birthtime, p->birthtime_nanos,
+ p->mtime, p->mtime_nanos,
+ p->ctime, p->ctime_nanos);
+ }
+ if (p->fixup & TODO_MODE_BASE)
+ chmod(p->name, p->mode);
+ if (p->fixup & TODO_ACLS)
+ set_acls(a, -1, p->name, &p->acl);
+ if (p->fixup & TODO_FFLAGS)
+ set_fflags_platform(a, -1, p->name,
+ p->mode, p->fflags_set, 0);
+ if (p->fixup & TODO_MAC_METADATA)
+ set_mac_metadata(a, p->name, p->mac_metadata,
+ p->mac_metadata_size);
+ next = p->next;
+ archive_acl_clear(&p->acl);
+ free(p->mac_metadata);
+ free(p->name);
+ free(p);
+ p = next;
+ }
+ a->fixup_list = NULL;
+ return (ret);
+}
+
+static int
+_archive_write_disk_free(struct archive *_a)
+{
+ struct archive_write_disk *a;
+ int ret;
+ if (_a == NULL)
+ return (ARCHIVE_OK);
+ archive_check_magic(_a, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_write_disk_free");
+ a = (struct archive_write_disk *)_a;
+ ret = _archive_write_disk_close(&a->archive);
+ archive_write_disk_set_group_lookup(&a->archive, NULL, NULL, NULL);
+ archive_write_disk_set_user_lookup(&a->archive, NULL, NULL, NULL);
+ if (a->entry)
+ archive_entry_free(a->entry);
+ archive_string_free(&a->_name_data);
+ archive_string_free(&a->archive.error_string);
+ archive_string_free(&a->path_safe);
+ a->archive.magic = 0;
+ __archive_clean(&a->archive);
+ free(a);
+ return (ret);
+}
+
+/*
+ * Simple O(n log n) merge sort to order the fixup list. In
+ * particular, we want to restore dir timestamps depth-first.
+ */
+static struct fixup_entry *
+sort_dir_list(struct fixup_entry *p)
+{
+ struct fixup_entry *a, *b, *t;
+
+ if (p == NULL)
+ return (NULL);
+ /* A one-item list is already sorted. */
+ if (p->next == NULL)
+ return (p);
+
+ /* Step 1: split the list. */
+ t = p;
+ a = p->next->next;
+ while (a != NULL) {
+ /* Step a twice, t once. */
+ a = a->next;
+ if (a != NULL)
+ a = a->next;
+ t = t->next;
+ }
+ /* Now, t is at the mid-point, so break the list here. */
+ b = t->next;
+ t->next = NULL;
+ a = p;
+
+ /* Step 2: Recursively sort the two sub-lists. */
+ a = sort_dir_list(a);
+ b = sort_dir_list(b);
+
+ /* Step 3: Merge the returned lists. */
+ /* Pick the first element for the merged list. */
+ if (strcmp(a->name, b->name) > 0) {
+ t = p = a;
+ a = a->next;
+ } else {
+ t = p = b;
+ b = b->next;
+ }
+
+ /* Always put the later element on the list first. */
+ while (a != NULL && b != NULL) {
+ if (strcmp(a->name, b->name) > 0) {
+ t->next = a;
+ a = a->next;
+ } else {
+ t->next = b;
+ b = b->next;
+ }
+ t = t->next;
+ }
+
+ /* Only one list is non-empty, so just splice it on. */
+ if (a != NULL)
+ t->next = a;
+ if (b != NULL)
+ t->next = b;
+
+ return (p);
+}
+
+/*
+ * Returns a new, initialized fixup entry.
+ *
+ * TODO: Reduce the memory requirements for this list by using a tree
+ * structure rather than a simple list of names.
+ */
+static struct fixup_entry *
+new_fixup(struct archive_write_disk *a, const char *pathname)
+{
+ struct fixup_entry *fe;
+
+ fe = (struct fixup_entry *)calloc(1, sizeof(struct fixup_entry));
+ if (fe == NULL)
+ return (NULL);
+ fe->next = a->fixup_list;
+ a->fixup_list = fe;
+ fe->fixup = 0;
+ fe->name = strdup(pathname);
+ return (fe);
+}
+
+/*
+ * Returns a fixup structure for the current entry.
+ */
+static struct fixup_entry *
+current_fixup(struct archive_write_disk *a, const char *pathname)
+{
+ if (a->current_fixup == NULL)
+ a->current_fixup = new_fixup(a, pathname);
+ return (a->current_fixup);
+}
+
+/* TODO: Make this work. */
+/*
+ * TODO: The deep-directory support bypasses this; disable deep directory
+ * support if we're doing symlink checks.
+ */
+/*
+ * TODO: Someday, integrate this with the deep dir support; they both
+ * scan the path and both can be optimized by comparing against other
+ * recent paths.
+ */
+/* TODO: Extend this to support symlinks on Windows Vista and later. */
+static int
+check_symlinks(struct archive_write_disk *a)
+{
+#if !defined(HAVE_LSTAT)
+ /* Platform doesn't have lstat, so we can't look for symlinks. */
+ (void)a; /* UNUSED */
+ return (ARCHIVE_OK);
+#else
+ char *pn;
+ char c;
+ int r;
+ struct stat st;
+
+ /*
+ * Guard against symlink tricks. Reject any archive entry whose
+ * destination would be altered by a symlink.
+ */
+ /* Whatever we checked last time doesn't need to be re-checked. */
+ pn = a->name;
+ if (archive_strlen(&(a->path_safe)) > 0) {
+ char *p = a->path_safe.s;
+ while ((*pn != '\0') && (*p == *pn))
+ ++p, ++pn;
+ }
+ c = pn[0];
+ /* Keep going until we've checked the entire name. */
+ while (pn[0] != '\0' && (pn[0] != '/' || pn[1] != '\0')) {
+ /* Skip the next path element. */
+ while (*pn != '\0' && *pn != '/')
+ ++pn;
+ c = pn[0];
+ pn[0] = '\0';
+ /* Check that we haven't hit a symlink. */
+ r = lstat(a->name, &st);
+ if (r != 0) {
+ /* We've hit a dir that doesn't exist; stop now. */
+ if (errno == ENOENT)
+ break;
+ } else if (S_ISLNK(st.st_mode)) {
+ if (c == '\0') {
+ /*
+ * Last element is symlink; remove it
+ * so we can overwrite it with the
+ * item being extracted.
+ */
+ if (unlink(a->name)) {
+ archive_set_error(&a->archive, errno,
+ "Could not remove symlink %s",
+ a->name);
+ pn[0] = c;
+ return (ARCHIVE_FAILED);
+ }
+ a->pst = NULL;
+ /*
+ * Even if we did remove it, a warning
+ * is in order. The warning is silly,
+ * though, if we're just replacing one
+ * symlink with another symlink.
+ */
+ if (!S_ISLNK(a->mode)) {
+ archive_set_error(&a->archive, 0,
+ "Removing symlink %s",
+ a->name);
+ }
+ /* Symlink gone. No more problem! */
+ pn[0] = c;
+ return (0);
+ } else if (a->flags & ARCHIVE_EXTRACT_UNLINK) {
+ /* User asked us to remove problems. */
+ if (unlink(a->name) != 0) {
+ archive_set_error(&a->archive, 0,
+ "Cannot remove intervening symlink %s",
+ a->name);
+ pn[0] = c;
+ return (ARCHIVE_FAILED);
+ }
+ a->pst = NULL;
+ } else {
+ archive_set_error(&a->archive, 0,
+ "Cannot extract through symlink %s",
+ a->name);
+ pn[0] = c;
+ return (ARCHIVE_FAILED);
+ }
+ }
+ }
+ pn[0] = c;
+ /* We've checked and/or cleaned the whole path, so remember it. */
+ archive_strcpy(&a->path_safe, a->name);
+ return (ARCHIVE_OK);
+#endif
+}
+
+#if defined(__CYGWIN__)
+/*
+ * 1. Convert a path separator from '\' to '/' .
+ * We shouldn't check multibyte character directly because some
+ * character-set have been using the '\' character for a part of
+ * its multibyte character code.
+ * 2. Replace unusable characters in Windows with underscore('_').
+ * See also : http://msdn.microsoft.com/en-us/library/aa365247.aspx
+ */
+static void
+cleanup_pathname_win(struct archive_write_disk *a)
+{
+ wchar_t wc;
+ char *p;
+ size_t alen, l;
+ int mb, complete, utf8;
+
+ alen = 0;
+ mb = 0;
+ complete = 1;
+ utf8 = (strcmp(nl_langinfo(CODESET), "UTF-8") == 0)? 1: 0;
+ for (p = a->name; *p != '\0'; p++) {
+ ++alen;
+ if (*p == '\\') {
+ /* If previous byte is smaller than 128,
+ * this is not second byte of multibyte characters,
+ * so we can replace '\' with '/'. */
+ if (utf8 || !mb)
+ *p = '/';
+ else
+ complete = 0;/* uncompleted. */
+ } else if (*(unsigned char *)p > 127)
+ mb = 1;
+ else
+ mb = 0;
+ /* Rewrite the path name if its next character is unusable. */
+ if (*p == ':' || *p == '*' || *p == '?' || *p == '"' ||
+ *p == '<' || *p == '>' || *p == '|')
+ *p = '_';
+ }
+ if (complete)
+ return;
+
+ /*
+ * Convert path separator in wide-character.
+ */
+ p = a->name;
+ while (*p != '\0' && alen) {
+ l = mbtowc(&wc, p, alen);
+ if (l == -1) {
+ while (*p != '\0') {
+ if (*p == '\\')
+ *p = '/';
+ ++p;
+ }
+ break;
+ }
+ if (l == 1 && wc == L'\\')
+ *p = '/';
+ p += l;
+ alen -= l;
+ }
+}
+#endif
+
+/*
+ * 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.
+ */
+static int
+cleanup_pathname(struct archive_write_disk *a)
+{
+ char *dest, *src;
+ char separator = '\0';
+
+ dest = src = a->name;
+ if (*src == '\0') {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Invalid empty pathname");
+ return (ARCHIVE_FAILED);
+ }
+
+#if defined(__CYGWIN__)
+ cleanup_pathname_win(a);
+#endif
+ /* Skip leading '/'. */
+ if (*src == '/')
+ separator = *src++;
+
+ /* Scan the pathname one element at a time. */
+ for (;;) {
+ /* src points to first char after '/' */
+ if (src[0] == '\0') {
+ break;
+ } else if (src[0] == '/') {
+ /* Found '//', ignore second one. */
+ src++;
+ continue;
+ } else if (src[0] == '.') {
+ if (src[1] == '\0') {
+ /* Ignore trailing '.' */
+ break;
+ } else if (src[1] == '/') {
+ /* Skip './'. */
+ src += 2;
+ continue;
+ } else if (src[1] == '.') {
+ if (src[2] == '/' || src[2] == '\0') {
+ /* Conditionally warn about '..' */
+ if (a->flags & ARCHIVE_EXTRACT_SECURE_NODOTDOT) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Path contains '..'");
+ return (ARCHIVE_FAILED);
+ }
+ }
+ /*
+ * Note: Under no circumstances do we
+ * remove '..' elements. In
+ * particular, restoring
+ * '/foo/../bar/' should create the
+ * 'foo' dir as a side-effect.
+ */
+ }
+ }
+
+ /* Copy current element, including leading '/'. */
+ if (separator)
+ *dest++ = '/';
+ while (*src != '\0' && *src != '/') {
+ *dest++ = *src++;
+ }
+
+ if (*src == '\0')
+ break;
+
+ /* Skip '/' separator. */
+ separator = *src++;
+ }
+ /*
+ * We've just copied zero or more path elements, not including the
+ * final '/'.
+ */
+ if (dest == a->name) {
+ /*
+ * Nothing got copied. The path must have been something
+ * like '.' or '/' or './' or '/././././/./'.
+ */
+ if (separator)
+ *dest++ = '/';
+ else
+ *dest++ = '.';
+ }
+ /* Terminate the result. */
+ *dest = '\0';
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Create the parent directory of the specified path, assuming path
+ * is already in mutable storage.
+ */
+static int
+create_parent_dir(struct archive_write_disk *a, char *path)
+{
+ char *slash;
+ int r;
+
+ /* Remove tail element to obtain parent name. */
+ slash = strrchr(path, '/');
+ if (slash == NULL)
+ return (ARCHIVE_OK);
+ *slash = '\0';
+ r = create_dir(a, path);
+ *slash = '/';
+ return (r);
+}
+
+/*
+ * Create the specified dir, recursing to create parents as necessary.
+ *
+ * Returns ARCHIVE_OK if the path exists when we're done here.
+ * Otherwise, returns ARCHIVE_FAILED.
+ * Assumes path is in mutable storage; path is unchanged on exit.
+ */
+static int
+create_dir(struct archive_write_disk *a, char *path)
+{
+ struct stat st;
+ struct fixup_entry *le;
+ char *slash, *base;
+ mode_t mode_final, mode;
+ int r;
+
+ /* Check for special names and just skip them. */
+ slash = strrchr(path, '/');
+ if (slash == NULL)
+ base = path;
+ else
+ base = slash + 1;
+
+ if (base[0] == '\0' ||
+ (base[0] == '.' && base[1] == '\0') ||
+ (base[0] == '.' && base[1] == '.' && base[2] == '\0')) {
+ /* Don't bother trying to create null path, '.', or '..'. */
+ if (slash != NULL) {
+ *slash = '\0';
+ r = create_dir(a, path);
+ *slash = '/';
+ return (r);
+ }
+ return (ARCHIVE_OK);
+ }
+
+ /*
+ * Yes, this should be stat() and not lstat(). Using lstat()
+ * here loses the ability to extract through symlinks. Also note
+ * that this should not use the a->st cache.
+ */
+ if (stat(path, &st) == 0) {
+ if (S_ISDIR(st.st_mode))
+ return (ARCHIVE_OK);
+ if ((a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE)) {
+ archive_set_error(&a->archive, EEXIST,
+ "Can't create directory '%s'", path);
+ return (ARCHIVE_FAILED);
+ }
+ if (unlink(path) != 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't create directory '%s': "
+ "Conflicting file cannot be removed",
+ path);
+ return (ARCHIVE_FAILED);
+ }
+ } else if (errno != ENOENT && errno != ENOTDIR) {
+ /* Stat failed? */
+ archive_set_error(&a->archive, errno, "Can't test directory '%s'", path);
+ return (ARCHIVE_FAILED);
+ } else if (slash != NULL) {
+ *slash = '\0';
+ r = create_dir(a, path);
+ *slash = '/';
+ if (r != ARCHIVE_OK)
+ return (r);
+ }
+
+ /*
+ * Mode we want for the final restored directory. Per POSIX,
+ * implicitly-created dirs must be created obeying the umask.
+ * There's no mention whether this is different for privileged
+ * restores (which the rest of this code handles by pretending
+ * umask=0). I've chosen here to always obey the user's umask for
+ * implicit dirs, even if _EXTRACT_PERM was specified.
+ */
+ mode_final = DEFAULT_DIR_MODE & ~a->user_umask;
+ /* Mode we want on disk during the restore process. */
+ mode = mode_final;
+ mode |= MINIMUM_DIR_MODE;
+ mode &= MAXIMUM_DIR_MODE;
+ if (mkdir(path, mode) == 0) {
+ if (mode != mode_final) {
+ le = new_fixup(a, path);
+ le->fixup |=TODO_MODE_BASE;
+ le->mode = mode_final;
+ }
+ return (ARCHIVE_OK);
+ }
+
+ /*
+ * Without the following check, a/b/../b/c/d fails at the
+ * second visit to 'b', so 'd' can't be created. Note that we
+ * don't add it to the fixup list here, as it's already been
+ * added.
+ */
+ if (stat(path, &st) == 0 && S_ISDIR(st.st_mode))
+ return (ARCHIVE_OK);
+
+ archive_set_error(&a->archive, errno, "Failed to create dir '%s'",
+ path);
+ return (ARCHIVE_FAILED);
+}
+
+/*
+ * Note: Although we can skip setting the user id if the desired user
+ * id matches the current user, we cannot skip setting the group, as
+ * many systems set the gid based on the containing directory. So
+ * we have to perform a chown syscall if we want to set the SGID
+ * bit. (The alternative is to stat() and then possibly chown(); it's
+ * more efficient to skip the stat() and just always chown().) Note
+ * that a successful chown() here clears the TODO_SGID_CHECK bit, which
+ * allows set_mode to skip the stat() check for the GID.
+ */
+static int
+set_ownership(struct archive_write_disk *a)
+{
+#ifndef __CYGWIN__
+/* unfortunately, on win32 there is no 'root' user with uid 0,
+ so we just have to try the chown and see if it works */
+
+ /* If we know we can't change it, don't bother trying. */
+ if (a->user_uid != 0 && a->user_uid != a->uid) {
+ archive_set_error(&a->archive, errno,
+ "Can't set UID=%jd", (intmax_t)a->uid);
+ return (ARCHIVE_WARN);
+ }
+#endif
+
+#ifdef HAVE_FCHOWN
+ /* If we have an fd, we can avoid a race. */
+ if (a->fd >= 0 && fchown(a->fd, a->uid, a->gid) == 0) {
+ /* We've set owner and know uid/gid are correct. */
+ a->todo &= ~(TODO_OWNER | TODO_SGID_CHECK | TODO_SUID_CHECK);
+ return (ARCHIVE_OK);
+ }
+#endif
+
+ /* We prefer lchown() but will use chown() if that's all we have. */
+ /* Of course, if we have neither, this will always fail. */
+#ifdef HAVE_LCHOWN
+ if (lchown(a->name, a->uid, a->gid) == 0) {
+ /* We've set owner and know uid/gid are correct. */
+ a->todo &= ~(TODO_OWNER | TODO_SGID_CHECK | TODO_SUID_CHECK);
+ return (ARCHIVE_OK);
+ }
+#elif HAVE_CHOWN
+ if (!S_ISLNK(a->mode) && chown(a->name, a->uid, a->gid) == 0) {
+ /* We've set owner and know uid/gid are correct. */
+ a->todo &= ~(TODO_OWNER | TODO_SGID_CHECK | TODO_SUID_CHECK);
+ return (ARCHIVE_OK);
+ }
+#endif
+
+ archive_set_error(&a->archive, errno,
+ "Can't set user=%jd/group=%jd for %s",
+ (intmax_t)a->uid, (intmax_t)a->gid, a->name);
+ return (ARCHIVE_WARN);
+}
+
+/*
+ * Note: Returns 0 on success, non-zero on failure.
+ */
+static int
+set_time(int fd, int mode, const char *name,
+ time_t atime, long atime_nsec,
+ time_t mtime, long mtime_nsec)
+{
+ /* Select the best implementation for this platform. */
+#if defined(HAVE_UTIMENSAT) && defined(HAVE_FUTIMENS)
+ /*
+ * utimensat() and futimens() are defined in
+ * POSIX.1-2008. They support ns resolution and setting times
+ * on fds and symlinks.
+ */
+ struct timespec ts[2];
+ ts[0].tv_sec = atime;
+ ts[0].tv_nsec = atime_nsec;
+ ts[1].tv_sec = mtime;
+ ts[1].tv_nsec = mtime_nsec;
+ if (fd >= 0)
+ return futimens(fd, ts);
+ return utimensat(AT_FDCWD, name, ts, AT_SYMLINK_NOFOLLOW);
+
+#elif HAVE_UTIMES
+ /*
+ * The utimes()-family functions support µs-resolution and
+ * setting times fds and symlinks. utimes() is documented as
+ * LEGACY by POSIX, futimes() and lutimes() are not described
+ * in POSIX.
+ */
+ struct timeval times[2];
+
+ times[0].tv_sec = atime;
+ times[0].tv_usec = atime_nsec / 1000;
+ times[1].tv_sec = mtime;
+ times[1].tv_usec = mtime_nsec / 1000;
+
+#ifdef HAVE_FUTIMES
+ if (fd >= 0)
+ return (futimes(fd, times));
+#else
+ (void)fd; /* UNUSED */
+#endif
+#ifdef HAVE_LUTIMES
+ (void)mode; /* UNUSED */
+ return (lutimes(name, times));
+#else
+ if (S_ISLNK(mode))
+ return (0);
+ return (utimes(name, times));
+#endif
+
+#elif defined(HAVE_UTIME)
+ /*
+ * utime() is POSIX-standard but only supports 1s resolution and
+ * does not support fds or symlinks.
+ */
+ struct utimbuf times;
+ (void)fd; /* UNUSED */
+ (void)name; /* UNUSED */
+ (void)atime_nsec; /* UNUSED */
+ (void)mtime_nsec; /* UNUSED */
+ times.actime = atime;
+ times.modtime = mtime;
+ if (S_ISLNK(mode))
+ return (ARCHIVE_OK);
+ return (utime(name, &times));
+
+#else
+ /*
+ * We don't know how to set the time on this platform.
+ */
+ return (ARCHIVE_WARN);
+#endif
+}
+
+#ifdef F_SETTIMES /* Tru64 */
+static int
+set_time_tru64(int fd, int mode, const char *name,
+ time_t atime, long atime_nsec,
+ time_t mtime, long mtime_nsec,
+ 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];
+ return (fcntl(fd,F_SETTIMES,&tstamp));
+}
+#endif /* Tru64 */
+
+static int
+set_times(struct archive_write_disk *a,
+ int fd, int mode, const char *name,
+ time_t atime, long atime_nanos,
+ time_t birthtime, long birthtime_nanos,
+ time_t mtime, long mtime_nanos,
+ time_t ctime, long ctime_nanos)
+{
+ /* Note: set_time doesn't use libarchive return conventions!
+ * It uses syscall conventions. So 0 here instead of ARCHIVE_OK. */
+ int r1 = 0, r2 = 0;
+
+#ifdef F_SETTIMES
+ /*
+ * on Tru64 try own fcntl first which can restore even the
+ * ctime, fall back to default code path below if it fails
+ * or if we are not running as root
+ */
+ if (a->user_uid == 0 &&
+ set_time_tru64(fd, mode, name,
+ atime, atime_nanos, mtime,
+ mtime_nanos, ctime, ctime_nanos) == 0) {
+ return (ARCHIVE_OK);
+ }
+#endif /* Tru64 */
+
+#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
+ /*
+ * If you have struct stat.st_birthtime, we assume BSD
+ * birthtime semantics, in which {f,l,}utimes() updates
+ * birthtime to earliest mtime. So we set the time twice,
+ * first using the birthtime, then using the mtime. If
+ * birthtime == mtime, this isn't necessary, so we skip it.
+ * If birthtime > mtime, then this won't work, so we skip it.
+ */
+ if (birthtime < mtime
+ || (birthtime == mtime && birthtime_nanos < mtime_nanos))
+ r1 = set_time(fd, mode, name,
+ atime, atime_nanos,
+ birthtime, birthtime_nanos);
+#endif
+ r2 = set_time(fd, mode, name,
+ atime, atime_nanos,
+ mtime, mtime_nanos);
+ if (r1 != 0 || r2 != 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't restore time");
+ return (ARCHIVE_WARN);
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+set_times_from_entry(struct archive_write_disk *a)
+{
+ time_t atime, birthtime, mtime, ctime;
+ long atime_nsec, birthtime_nsec, mtime_nsec, ctime_nsec;
+
+ /* Suitable defaults. */
+ atime = birthtime = mtime = ctime = a->start_time;
+ atime_nsec = birthtime_nsec = mtime_nsec = ctime_nsec = 0;
+
+ /* If no time was provided, we're done. */
+ if (!archive_entry_atime_is_set(a->entry)
+#if HAVE_STRUCT_STAT_ST_BIRTHTIME
+ && !archive_entry_birthtime_is_set(a->entry)
+#endif
+ && !archive_entry_mtime_is_set(a->entry))
+ return (ARCHIVE_OK);
+
+ if (archive_entry_atime_is_set(a->entry)) {
+ atime = archive_entry_atime(a->entry);
+ atime_nsec = archive_entry_atime_nsec(a->entry);
+ }
+ if (archive_entry_birthtime_is_set(a->entry)) {
+ birthtime = archive_entry_birthtime(a->entry);
+ birthtime_nsec = archive_entry_birthtime_nsec(a->entry);
+ }
+ if (archive_entry_mtime_is_set(a->entry)) {
+ mtime = archive_entry_mtime(a->entry);
+ mtime_nsec = archive_entry_mtime_nsec(a->entry);
+ }
+ if (archive_entry_ctime_is_set(a->entry)) {
+ ctime = archive_entry_ctime(a->entry);
+ ctime_nsec = archive_entry_ctime_nsec(a->entry);
+ }
+
+ return set_times(a, a->fd, a->mode, a->name,
+ atime, atime_nsec,
+ birthtime, birthtime_nsec,
+ mtime, mtime_nsec,
+ ctime, ctime_nsec);
+}
+
+static int
+set_mode(struct archive_write_disk *a, int mode)
+{
+ int r = ARCHIVE_OK;
+ mode &= 07777; /* Strip off file type bits. */
+
+ if (a->todo & TODO_SGID_CHECK) {
+ /*
+ * If we don't know the GID is right, we must stat()
+ * to verify it. We can't just check the GID of this
+ * process, since systems sometimes set GID from
+ * the enclosing dir or based on ACLs.
+ */
+ if ((r = lazy_stat(a)) != ARCHIVE_OK)
+ return (r);
+ if (a->pst->st_gid != a->gid) {
+ mode &= ~ S_ISGID;
+ if (a->flags & ARCHIVE_EXTRACT_OWNER) {
+ /*
+ * This is only an error if you
+ * requested owner restore. If you
+ * didn't, we'll try to restore
+ * sgid/suid, but won't consider it a
+ * problem if we can't.
+ */
+ archive_set_error(&a->archive, -1,
+ "Can't restore SGID bit");
+ r = ARCHIVE_WARN;
+ }
+ }
+ /* While we're here, double-check the UID. */
+ if (a->pst->st_uid != a->uid
+ && (a->todo & TODO_SUID)) {
+ mode &= ~ S_ISUID;
+ if (a->flags & ARCHIVE_EXTRACT_OWNER) {
+ archive_set_error(&a->archive, -1,
+ "Can't restore SUID bit");
+ r = ARCHIVE_WARN;
+ }
+ }
+ a->todo &= ~TODO_SGID_CHECK;
+ a->todo &= ~TODO_SUID_CHECK;
+ } else if (a->todo & TODO_SUID_CHECK) {
+ /*
+ * If we don't know the UID is right, we can just check
+ * the user, since all systems set the file UID from
+ * the process UID.
+ */
+ if (a->user_uid != a->uid) {
+ mode &= ~ S_ISUID;
+ if (a->flags & ARCHIVE_EXTRACT_OWNER) {
+ archive_set_error(&a->archive, -1,
+ "Can't make file SUID");
+ r = ARCHIVE_WARN;
+ }
+ }
+ a->todo &= ~TODO_SUID_CHECK;
+ }
+
+ if (S_ISLNK(a->mode)) {
+#ifdef HAVE_LCHMOD
+ /*
+ * If this is a symlink, use lchmod(). If the
+ * platform doesn't support lchmod(), just skip it. A
+ * platform that doesn't provide a way to set
+ * permissions on symlinks probably ignores
+ * permissions on symlinks, so a failure here has no
+ * 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;
+ }
+#endif
+ } else if (!S_ISDIR(a->mode)) {
+ /*
+ * If it's not a symlink and not a dir, then use
+ * fchmod() or chmod(), depending on whether we have
+ * an fd. Dirs get their perms set during the
+ * post-extract fixup, which is handled elsewhere.
+ */
+#ifdef HAVE_FCHMOD
+ if (a->fd >= 0) {
+ if (fchmod(a->fd, mode) != 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't set permissions to 0%o", (int)mode);
+ r = ARCHIVE_WARN;
+ }
+ } else
+#endif
+ /* If this platform lacks fchmod(), then
+ * we'll just use chmod(). */
+ if (chmod(a->name, mode) != 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't set permissions to 0%o", (int)mode);
+ r = ARCHIVE_WARN;
+ }
+ }
+ return (r);
+}
+
+static int
+set_fflags(struct archive_write_disk *a)
+{
+ struct fixup_entry *le;
+ unsigned long set, clear;
+ int r;
+ int critical_flags;
+ mode_t mode = archive_entry_mode(a->entry);
+
+ /*
+ * Make 'critical_flags' hold all file flags that can't be
+ * immediately restored. For example, on BSD systems,
+ * SF_IMMUTABLE prevents hardlinks from being created, so
+ * should not be set until after any hardlinks are created. To
+ * preserve some semblance of portability, this uses #ifdef
+ * extensively. Ugly, but it works.
+ *
+ * Yes, Virginia, this does create a security race. It's mitigated
+ * somewhat by the practice of creating dirs 0700 until the extract
+ * is done, but it would be nice if we could do more than that.
+ * People restoring critical file systems should be wary of
+ * other programs that might try to muck with files as they're
+ * being restored.
+ */
+ /* Hopefully, the compiler will optimize this mess into a constant. */
+ critical_flags = 0;
+#ifdef SF_IMMUTABLE
+ critical_flags |= SF_IMMUTABLE;
+#endif
+#ifdef UF_IMMUTABLE
+ critical_flags |= UF_IMMUTABLE;
+#endif
+#ifdef SF_APPEND
+ critical_flags |= SF_APPEND;
+#endif
+#ifdef UF_APPEND
+ critical_flags |= UF_APPEND;
+#endif
+#ifdef EXT2_APPEND_FL
+ critical_flags |= EXT2_APPEND_FL;
+#endif
+#ifdef EXT2_IMMUTABLE_FL
+ critical_flags |= EXT2_IMMUTABLE_FL;
+#endif
+
+ if (a->todo & TODO_FFLAGS) {
+ archive_entry_fflags(a->entry, &set, &clear);
+
+ /*
+ * The first test encourages the compiler to eliminate
+ * all of this if it's not necessary.
+ */
+ if ((critical_flags != 0) && (set & critical_flags)) {
+ le = current_fixup(a, a->name);
+ le->fixup |= TODO_FFLAGS;
+ le->fflags_set = set;
+ /* Store the mode if it's not already there. */
+ if ((le->fixup & TODO_MODE) == 0)
+ le->mode = mode;
+ } else {
+ r = set_fflags_platform(a, a->fd,
+ a->name, mode, set, clear);
+ if (r != ARCHIVE_OK)
+ return (r);
+ }
+ }
+ return (ARCHIVE_OK);
+}
+
+
+#if ( defined(HAVE_LCHFLAGS) || defined(HAVE_CHFLAGS) || defined(HAVE_FCHFLAGS) ) && defined(HAVE_STRUCT_STAT_ST_FLAGS)
+/*
+ * BSD reads flags using stat() and sets them with one of {f,l,}chflags()
+ */
+static int
+set_fflags_platform(struct archive_write_disk *a, int fd, const char *name,
+ mode_t mode, unsigned long set, unsigned long clear)
+{
+ int r;
+
+ (void)mode; /* UNUSED */
+ if (set == 0 && clear == 0)
+ return (ARCHIVE_OK);
+
+ /*
+ * XXX Is the stat here really necessary? Or can I just use
+ * the 'set' flags directly? In particular, I'm not sure
+ * about the correct approach if we're overwriting an existing
+ * file that already has flags on it. XXX
+ */
+ if ((r = lazy_stat(a)) != ARCHIVE_OK)
+ return (r);
+
+ a->st.st_flags &= ~clear;
+ a->st.st_flags |= set;
+#ifdef HAVE_FCHFLAGS
+ /* If platform has fchflags() and we were given an fd, use it. */
+ if (fd >= 0 && fchflags(fd, a->st.st_flags) == 0)
+ return (ARCHIVE_OK);
+#endif
+ /*
+ * If we can't use the fd to set the flags, we'll use the
+ * pathname to set flags. We prefer lchflags() but will use
+ * chflags() if we must.
+ */
+#ifdef HAVE_LCHFLAGS
+ if (lchflags(name, a->st.st_flags) == 0)
+ return (ARCHIVE_OK);
+#elif defined(HAVE_CHFLAGS)
+ if (S_ISLNK(a->st.st_mode)) {
+ archive_set_error(&a->archive, errno,
+ "Can't set file flags on symlink.");
+ return (ARCHIVE_WARN);
+ }
+ if (chflags(name, a->st.st_flags) == 0)
+ return (ARCHIVE_OK);
+#endif
+ archive_set_error(&a->archive, errno,
+ "Failed to set file flags");
+ return (ARCHIVE_WARN);
+}
+
+#elif defined(EXT2_IOC_GETFLAGS) && defined(EXT2_IOC_SETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)
+/*
+ * Linux uses ioctl() to read and write file flags.
+ */
+static int
+set_fflags_platform(struct archive_write_disk *a, int fd, const char *name,
+ mode_t mode, unsigned long set, unsigned long clear)
+{
+ int ret;
+ int myfd = fd;
+ unsigned long newflags, oldflags;
+ unsigned long sf_mask = 0;
+
+ if (set == 0 && clear == 0)
+ return (ARCHIVE_OK);
+ /* Only regular files and dirs can have flags. */
+ if (!S_ISREG(mode) && !S_ISDIR(mode))
+ return (ARCHIVE_OK);
+
+ /* If we weren't given an fd, open it ourselves. */
+ if (myfd < 0)
+ myfd = open(name, O_RDONLY | O_NONBLOCK | O_BINARY);
+ if (myfd < 0)
+ return (ARCHIVE_OK);
+
+ /*
+ * Linux has no define for the flags that are only settable by
+ * the root user. This code may seem a little complex, but
+ * there seem to be some Linux systems that lack these
+ * defines. (?) The code below degrades reasonably gracefully
+ * if sf_mask is incomplete.
+ */
+#ifdef EXT2_IMMUTABLE_FL
+ sf_mask |= EXT2_IMMUTABLE_FL;
+#endif
+#ifdef EXT2_APPEND_FL
+ sf_mask |= EXT2_APPEND_FL;
+#endif
+ /*
+ * XXX As above, this would be way simpler if we didn't have
+ * to read the current flags from disk. XXX
+ */
+ ret = ARCHIVE_OK;
+
+ /* Read the current file flags. */
+ if (ioctl(myfd, EXT2_IOC_GETFLAGS, &oldflags) < 0)
+ goto fail;
+
+ /* Try setting the flags as given. */
+ newflags = (oldflags & ~clear) | set;
+ if (ioctl(myfd, EXT2_IOC_SETFLAGS, &newflags) >= 0)
+ goto cleanup;
+ if (errno != EPERM)
+ goto fail;
+
+ /* If we couldn't set all the flags, try again with a subset. */
+ newflags &= ~sf_mask;
+ oldflags &= sf_mask;
+ newflags |= oldflags;
+ if (ioctl(myfd, EXT2_IOC_SETFLAGS, &newflags) >= 0)
+ goto cleanup;
+
+ /* We couldn't set the flags, so report the failure. */
+fail:
+ archive_set_error(&a->archive, errno,
+ "Failed to set file flags");
+ ret = ARCHIVE_WARN;
+cleanup:
+ if (fd < 0)
+ close(myfd);
+ return (ret);
+}
+
+#else
+
+/*
+ * Of course, some systems have neither BSD chflags() nor Linux' flags
+ * support through ioctl().
+ */
+static int
+set_fflags_platform(struct archive_write_disk *a, int fd, const char *name,
+ mode_t mode, unsigned long set, unsigned long clear)
+{
+ (void)a; /* UNUSED */
+ (void)fd; /* UNUSED */
+ (void)name; /* UNUSED */
+ (void)mode; /* UNUSED */
+ (void)set; /* UNUSED */
+ (void)clear; /* UNUSED */
+ return (ARCHIVE_OK);
+}
+
+#endif /* __linux */
+
+#ifndef HAVE_COPYFILE_H
+/* Default is to simply drop Mac extended metadata. */
+static int
+set_mac_metadata(struct archive_write_disk *a, const char *pathname,
+ const void *metadata, size_t metadata_size)
+{
+ (void)a; /* UNUSED */
+ (void)pathname; /* UNUSED */
+ (void)metadata; /* UNUSED */
+ (void)metadata_size; /* UNUSED */
+ return (ARCHIVE_OK);
+}
+#else
+
+/*
+ * On Mac OS, we use copyfile() to unpack the metadata and
+ * apply it to the target file.
+ */
+static int
+set_mac_metadata(struct archive_write_disk *a, const char *pathname,
+ const void *metadata, size_t metadata_size)
+{
+ struct archive_string tmp;
+ ssize_t written;
+ int fd;
+ int ret = ARCHIVE_OK;
+
+ /* This would be simpler if copyfile() could just accept the
+ * metadata as a block of memory; then we could sidestep this
+ * silly dance of writing the data to disk just so that
+ * copyfile() can read it back in again. */
+ archive_string_init(&tmp);
+ archive_strcpy(&tmp, pathname);
+ archive_strcat(&tmp, ".XXXXXX");
+ fd = mkstemp(tmp.s);
+
+ if (fd < 0) {
+ archive_set_error(&a->archive, errno,
+ "Failed to restore metadata");
+ return (ARCHIVE_WARN);
+ }
+ written = write(fd, metadata, metadata_size);
+ close(fd);
+ if (written != metadata_size
+ || copyfile(tmp.s, pathname, 0,
+ COPYFILE_UNPACK | COPYFILE_NOFOLLOW
+ | COPYFILE_ACL | COPYFILE_XATTR)) {
+ archive_set_error(&a->archive, errno,
+ "Failed to restore metadata");
+ ret = ARCHIVE_WARN;
+ }
+ unlink(tmp.s);
+ return (ret);
+}
+#endif
+
+#ifndef HAVE_POSIX_ACL
+/* Default empty function body to satisfy mainline code. */
+static int
+set_acls(struct archive_write_disk *a, int fd, const char *name,
+ struct archive_acl *acl)
+{
+ (void)a; /* UNUSED */
+ (void)fd; /* UNUSED */
+ (void)name; /* UNUSED */
+ (void)acl; /* UNUSED */
+ return (ARCHIVE_OK);
+}
+
+#else
+
+/*
+ * XXX TODO: What about ACL types other than ACCESS and DEFAULT?
+ */
+static int
+set_acls(struct archive_write_disk *a, int fd, const char *name,
+ struct archive_acl *abstract_acl)
+{
+ int ret;
+
+ ret = set_acl(a, fd, name, abstract_acl, ACL_TYPE_ACCESS,
+ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, "access");
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ ret = set_acl(a, fd, name, abstract_acl, ACL_TYPE_DEFAULT,
+ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, "default");
+ return (ret);
+}
+
+
+static int
+set_acl(struct archive_write_disk *a, int fd, const char *name,
+ struct archive_acl *abstract_acl,
+ acl_type_t acl_type, int ae_requested_type, const char *tname)
+{
+ acl_t acl;
+ acl_entry_t acl_entry;
+ acl_permset_t acl_permset;
+ int ret;
+ int ae_type, ae_permset, ae_tag, ae_id;
+ uid_t ae_uid;
+ gid_t ae_gid;
+ const char *ae_name;
+ int entries;
+
+ ret = ARCHIVE_OK;
+ entries = archive_acl_reset(abstract_acl, ae_requested_type);
+ if (entries == 0)
+ return (ARCHIVE_OK);
+ acl = acl_init(entries);
+ while (archive_acl_next(&a->archive, abstract_acl,
+ ae_requested_type, &ae_type, &ae_permset, &ae_tag, &ae_id,
+ &ae_name) == ARCHIVE_OK) {
+ acl_create_entry(&acl, &acl_entry);
+
+ switch (ae_tag) {
+ case ARCHIVE_ENTRY_ACL_USER:
+ acl_set_tag_type(acl_entry, ACL_USER);
+ ae_uid = archive_write_disk_uid(&a->archive,
+ ae_name, ae_id);
+ acl_set_qualifier(acl_entry, &ae_uid);
+ break;
+ case ARCHIVE_ENTRY_ACL_GROUP:
+ acl_set_tag_type(acl_entry, ACL_GROUP);
+ ae_gid = archive_write_disk_gid(&a->archive,
+ ae_name, ae_id);
+ acl_set_qualifier(acl_entry, &ae_gid);
+ break;
+ case ARCHIVE_ENTRY_ACL_USER_OBJ:
+ acl_set_tag_type(acl_entry, ACL_USER_OBJ);
+ break;
+ case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
+ acl_set_tag_type(acl_entry, ACL_GROUP_OBJ);
+ break;
+ case ARCHIVE_ENTRY_ACL_MASK:
+ acl_set_tag_type(acl_entry, ACL_MASK);
+ break;
+ case ARCHIVE_ENTRY_ACL_OTHER:
+ acl_set_tag_type(acl_entry, ACL_OTHER);
+ break;
+ default:
+ /* XXX */
+ break;
+ }
+
+ acl_get_permset(acl_entry, &acl_permset);
+ acl_clear_perms(acl_permset);
+ if (ae_permset & ARCHIVE_ENTRY_ACL_EXECUTE)
+ acl_add_perm(acl_permset, ACL_EXECUTE);
+ if (ae_permset & ARCHIVE_ENTRY_ACL_WRITE)
+ acl_add_perm(acl_permset, ACL_WRITE);
+ if (ae_permset & ARCHIVE_ENTRY_ACL_READ)
+ acl_add_perm(acl_permset, ACL_READ);
+ }
+
+ /* Try restoring the ACL through 'fd' if we can. */
+#if HAVE_ACL_SET_FD
+ if (fd >= 0 && acl_type == ACL_TYPE_ACCESS && acl_set_fd(fd, acl) == 0)
+ ret = ARCHIVE_OK;
+ else
+#else
+#if HAVE_ACL_SET_FD_NP
+ if (fd >= 0 && acl_set_fd_np(fd, acl, acl_type) == 0)
+ ret = ARCHIVE_OK;
+ else
+#endif
+#endif
+ if (acl_set_file(name, acl_type, acl) != 0) {
+ archive_set_error(&a->archive, errno, "Failed to set %s acl", tname);
+ ret = ARCHIVE_WARN;
+ }
+ acl_free(acl);
+ return (ret);
+}
+#endif
+
+#if HAVE_LSETXATTR || HAVE_LSETEA
+/*
+ * Restore extended attributes - Linux and AIX implementations:
+ * AIX' ea interface is syntaxwise identical to the Linux xattr interface.
+ */
+static int
+set_xattrs(struct archive_write_disk *a)
+{
+ struct archive_entry *entry = a->entry;
+ static int warning_done = 0;
+ int ret = ARCHIVE_OK;
+ int i = archive_entry_xattr_reset(entry);
+
+ while (i--) {
+ const char *name;
+ const void *value;
+ size_t size;
+ archive_entry_xattr_next(entry, &name, &value, &size);
+ if (name != NULL &&
+ strncmp(name, "xfsroot.", 8) != 0 &&
+ strncmp(name, "system.", 7) != 0) {
+ int e;
+#if HAVE_FSETXATTR
+ if (a->fd >= 0)
+ e = fsetxattr(a->fd, name, value, size, 0);
+ else
+#elif HAVE_FSETEA
+ if (a->fd >= 0)
+ e = fsetea(a->fd, name, value, size, 0);
+ else
+#endif
+ {
+#if HAVE_LSETXATTR
+ e = lsetxattr(archive_entry_pathname(entry),
+ name, value, size, 0);
+#elif HAVE_LSETEA
+ e = lsetea(archive_entry_pathname(entry),
+ name, value, size, 0);
+#endif
+ }
+ if (e == -1) {
+ if (errno == ENOTSUP || errno == ENOSYS) {
+ if (!warning_done) {
+ warning_done = 1;
+ archive_set_error(&a->archive, errno,
+ "Cannot restore extended "
+ "attributes on this file "
+ "system");
+ }
+ } else
+ archive_set_error(&a->archive, errno,
+ "Failed to set extended attribute");
+ ret = ARCHIVE_WARN;
+ }
+ } else {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Invalid extended attribute encountered");
+ ret = ARCHIVE_WARN;
+ }
+ }
+ return (ret);
+}
+#elif HAVE_EXTATTR_SET_FILE && HAVE_DECL_EXTATTR_NAMESPACE_USER
+/*
+ * Restore extended attributes - FreeBSD implementation
+ */
+static int
+set_xattrs(struct archive_write_disk *a)
+{
+ struct archive_entry *entry = a->entry;
+ static int warning_done = 0;
+ int ret = ARCHIVE_OK;
+ int i = archive_entry_xattr_reset(entry);
+
+ while (i--) {
+ const char *name;
+ const void *value;
+ size_t size;
+ archive_entry_xattr_next(entry, &name, &value, &size);
+ if (name != NULL) {
+ int e;
+ int namespace;
+
+ if (strncmp(name, "user.", 5) == 0) {
+ /* "user." attributes go to user namespace */
+ name += 5;
+ namespace = EXTATTR_NAMESPACE_USER;
+ } else {
+ /* Warn about other extended attributes. */
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't restore extended attribute ``%s''",
+ name);
+ ret = ARCHIVE_WARN;
+ continue;
+ }
+ errno = 0;
+#if HAVE_EXTATTR_SET_FD
+ if (a->fd >= 0)
+ e = extattr_set_fd(a->fd, namespace, name, value, size);
+ else
+#endif
+ /* TODO: should we use extattr_set_link() instead? */
+ {
+ e = extattr_set_file(archive_entry_pathname(entry),
+ namespace, name, value, size);
+ }
+ if (e != (int)size) {
+ if (errno == ENOTSUP || errno == ENOSYS) {
+ if (!warning_done) {
+ warning_done = 1;
+ archive_set_error(&a->archive, errno,
+ "Cannot restore extended "
+ "attributes on this file "
+ "system");
+ }
+ } else {
+ archive_set_error(&a->archive, errno,
+ "Failed to set extended attribute");
+ }
+
+ ret = ARCHIVE_WARN;
+ }
+ }
+ }
+ return (ret);
+}
+#else
+/*
+ * Restore extended attributes - stub implementation for unsupported systems
+ */
+static int
+set_xattrs(struct archive_write_disk *a)
+{
+ static int warning_done = 0;
+
+ /* If there aren't any extended attributes, then it's okay not
+ * to extract them, otherwise, issue a single warning. */
+ if (archive_entry_xattr_count(a->entry) != 0 && !warning_done) {
+ warning_done = 1;
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Cannot restore extended attributes on this system");
+ return (ARCHIVE_WARN);
+ }
+ /* Warning was already emitted; suppress further warnings. */
+ return (ARCHIVE_OK);
+}
+#endif
+
+/*
+ * Test if file on disk is older than entry.
+ */
+static int
+older(struct stat *st, struct archive_entry *entry)
+{
+ /* First, test the seconds and return if we have a definite answer. */
+ /* Definitely older. */
+ if (st->st_mtime < archive_entry_mtime(entry))
+ return (1);
+ /* Definitely younger. */
+ if (st->st_mtime > archive_entry_mtime(entry))
+ return (0);
+ /* If this platform supports fractional seconds, try those. */
+#if HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC
+ /* Definitely older. */
+ if (st->st_mtimespec.tv_nsec < archive_entry_mtime_nsec(entry))
+ return (1);
+#elif HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
+ /* Definitely older. */
+ if (st->st_mtim.tv_nsec < archive_entry_mtime_nsec(entry))
+ return (1);
+#elif HAVE_STRUCT_STAT_ST_MTIME_N
+ /* older. */
+ if (st->st_mtime_n < archive_entry_mtime_nsec(entry))
+ return (1);
+#elif HAVE_STRUCT_STAT_ST_UMTIME
+ /* older. */
+ if (st->st_umtime * 1000 < archive_entry_mtime_nsec(entry))
+ return (1);
+#elif HAVE_STRUCT_STAT_ST_MTIME_USEC
+ /* older. */
+ if (st->st_mtime_usec * 1000 < archive_entry_mtime_nsec(entry))
+ return (1);
+#else
+ /* This system doesn't have high-res timestamps. */
+#endif
+ /* Same age or newer, so not older. */
+ return (0);
+}
+
+#endif /* !_WIN32 || __CYGWIN__ */
+
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_disk_private.h b/Utilities/cmlibarchive/libarchive/archive_write_disk_private.h
new file mode 100644
index 000000000..707c0cf03
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_disk_private.h
@@ -0,0 +1,38 @@
+/*-
+ * 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
+ * in this position and unchanged.
+ * 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.
+ *
+ * $FreeBSD: head/lib/libarchive/archive_write_disk_private.h 201086 2009-12-28 02:17:53Z kientzle $
+ */
+
+#ifndef __LIBARCHIVE_BUILD
+#error This header is only to be used internally to libarchive.
+#endif
+
+#ifndef ARCHIVE_WRITE_DISK_PRIVATE_H_INCLUDED
+#define ARCHIVE_WRITE_DISK_PRIVATE_H_INCLUDED
+
+struct archive_write_disk;
+
+#endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_disk_set_standard_lookup.c b/Utilities/cmlibarchive/libarchive/archive_write_disk_set_standard_lookup.c
new file mode 100644
index 000000000..5ee89a79a
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_disk_set_standard_lookup.c
@@ -0,0 +1,262 @@
+/*-
+ * 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: head/lib/libarchive/archive_write_disk_set_standard_lookup.c 201083 2009-12-28 02:09:57Z kientzle $");
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_GRP_H
+#include <grp.h>
+#endif
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include "archive.h"
+#include "archive_private.h"
+#include "archive_read_private.h"
+#include "archive_write_disk_private.h"
+
+struct bucket {
+ char *name;
+ int hash;
+ id_t id;
+};
+
+static const size_t cache_size = 127;
+static unsigned int hash(const char *);
+static int64_t lookup_gid(void *, const char *uname, int64_t);
+static int64_t lookup_uid(void *, const char *uname, int64_t);
+static void cleanup(void *);
+
+/*
+ * Installs functions that use getpwnam()/getgrnam()---along with
+ * 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
+ * it inappropriate for some space-constrained applications.
+ *
+ * Applications that are size-sensitive may want to just use the
+ * real default functions (defined in archive_write_disk.c) that just
+ * use the uid/gid without the lookup. Or define your own custom functions
+ * if you prefer.
+ *
+ * TODO: Replace these hash tables with simpler move-to-front LRU
+ * lists with a bounded size (128 items?). The hash is a bit faster,
+ * but has a bad pathology in which it thrashes a single bucket. Even
+ * walking a list of 128 items is a lot faster than calling
+ * getpwnam()!
+ */
+int
+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));
+ 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);
+ archive_write_disk_set_user_lookup(a, ucache, lookup_uid, cleanup);
+ return (ARCHIVE_OK);
+}
+
+static int64_t
+lookup_gid(void *private_data, const char *gname, int64_t gid)
+{
+ int h;
+ struct bucket *b;
+ struct bucket *gcache = (struct bucket *)private_data;
+
+ /* If no gname, just use the gid provided. */
+ if (gname == NULL || *gname == '\0')
+ return (gid);
+
+ /* Try to find gname in the cache. */
+ h = hash(gname);
+ b = &gcache[h % cache_size ];
+ if (b->name != NULL && b->hash == h && strcmp(gname, b->name) == 0)
+ return ((gid_t)b->id);
+
+ /* Free the cache slot for a new entry. */
+ if (b->name != NULL)
+ free(b->name);
+ b->name = strdup(gname);
+ /* Note: If strdup fails, that's okay; we just won't cache. */
+ b->hash = h;
+#if HAVE_GRP_H
+# if HAVE_GETGRNAM_R
+ {
+ char _buffer[128];
+ size_t bufsize = 128;
+ char *buffer = _buffer;
+ struct group grent, *result;
+ int r;
+
+ for (;;) {
+ result = &grent; /* Old getgrnam_r ignores last arg. */
+ r = getgrnam_r(gname, &grent, buffer, bufsize, &result);
+ if (r == 0)
+ break;
+ if (r != ERANGE)
+ break;
+ bufsize *= 2;
+ if (buffer != _buffer)
+ free(buffer);
+ buffer = malloc(bufsize);
+ if (buffer == NULL)
+ break;
+ }
+ if (result != NULL)
+ gid = result->gr_gid;
+ if (buffer != _buffer)
+ free(buffer);
+ }
+# else /* HAVE_GETGRNAM_R */
+ {
+ struct group *result;
+
+ result = getgrnam(gname);
+ if (result != NULL)
+ gid = result->gr_gid;
+ }
+# endif /* HAVE_GETGRNAM_R */
+#elif defined(_WIN32) && !defined(__CYGWIN__)
+ /* TODO: do a gname->gid lookup for Windows. */
+#else
+ #error No way to perform gid lookups on this platform
+#endif
+ b->id = gid;
+
+ return (gid);
+}
+
+static int64_t
+lookup_uid(void *private_data, const char *uname, int64_t uid)
+{
+ int h;
+ struct bucket *b;
+ struct bucket *ucache = (struct bucket *)private_data;
+
+ /* If no uname, just use the uid provided. */
+ if (uname == NULL || *uname == '\0')
+ return (uid);
+
+ /* Try to find uname in the cache. */
+ h = hash(uname);
+ b = &ucache[h % cache_size ];
+ if (b->name != NULL && b->hash == h && strcmp(uname, b->name) == 0)
+ return ((uid_t)b->id);
+
+ /* Free the cache slot for a new entry. */
+ if (b->name != NULL)
+ free(b->name);
+ b->name = strdup(uname);
+ /* Note: If strdup fails, that's okay; we just won't cache. */
+ b->hash = h;
+#if HAVE_PWD_H
+# if HAVE_GETPWNAM_R
+ {
+ char _buffer[128];
+ size_t bufsize = 128;
+ char *buffer = _buffer;
+ struct passwd pwent, *result;
+ int r;
+
+ for (;;) {
+ result = &pwent; /* Old getpwnam_r ignores last arg. */
+ r = getpwnam_r(uname, &pwent, buffer, bufsize, &result);
+ if (r == 0)
+ break;
+ if (r != ERANGE)
+ break;
+ bufsize *= 2;
+ if (buffer != _buffer)
+ free(buffer);
+ buffer = malloc(bufsize);
+ if (buffer == NULL)
+ break;
+ }
+ if (result != NULL)
+ uid = result->pw_uid;
+ if (buffer != _buffer)
+ free(buffer);
+ }
+# else /* HAVE_GETPWNAM_R */
+ {
+ struct passwd *result;
+
+ result = getpwnam(uname);
+ if (result != NULL)
+ uid = result->pw_uid;
+ }
+#endif /* HAVE_GETPWNAM_R */
+#elif defined(_WIN32) && !defined(__CYGWIN__)
+ /* TODO: do a uname->uid lookup for Windows. */
+#else
+ #error No way to look up uids on this platform
+#endif
+ b->id = uid;
+
+ return (uid);
+}
+
+static void
+cleanup(void *private)
+{
+ size_t i;
+ struct bucket *cache = (struct bucket *)private;
+
+ for (i = 0; i < cache_size; i++)
+ free(cache[i].name);
+ free(cache);
+}
+
+
+static unsigned int
+hash(const char *p)
+{
+ /* A 32-bit version of Peter Weinberger's (PJW) hash algorithm,
+ as used by ELF for hashing function names. */
+ unsigned g, h = 0;
+ while (*p != '\0') {
+ h = (h << 4) + *p++;
+ if ((g = h & 0xF0000000) != 0) {
+ h ^= g >> 24;
+ h &= 0x0FFFFFFF;
+ }
+ }
+ return h;
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c b/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c
new file mode 100644
index 000000000..2dc2d92e8
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c
@@ -0,0 +1,2551 @@
+/*-
+ * Copyright (c) 2003-2010 Tim Kientzle
+ * 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
+ * in this position and unchanged.
+ * 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$");
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_UTIME_H
+#include <sys/utime.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#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
+#include <winioctl.h>
+
+/* TODO: Support Mac OS 'quarantine' feature. This is really just a
+ * standard tag to mark files that have been downloaded as "tainted".
+ * On Mac OS, we should mark the extracted files as tainted if the
+ * archive being read was tainted. Windows has a similar feature; we
+ * should investigate ways to support this generically. */
+
+#include "archive.h"
+#include "archive_acl_private.h"
+#include "archive_string.h"
+#include "archive_entry.h"
+#include "archive_private.h"
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+#ifndef IO_REPARSE_TAG_SYMLINK
+/* Old SDKs do not provide IO_REPARSE_TAG_SYMLINK */
+#define IO_REPARSE_TAG_SYMLINK 0xA000000CL
+#endif
+
+static BOOL SetFilePointerEx_perso(HANDLE hFile,
+ LARGE_INTEGER liDistanceToMove,
+ PLARGE_INTEGER lpNewFilePointer,
+ DWORD dwMoveMethod)
+{
+ LARGE_INTEGER li;
+ li.QuadPart = liDistanceToMove.QuadPart;
+ li.LowPart = SetFilePointer(
+ hFile, li.LowPart, &li.HighPart, dwMoveMethod);
+ if(lpNewFilePointer) {
+ lpNewFilePointer->QuadPart = li.QuadPart;
+ }
+ return li.LowPart != -1 || GetLastError() == NO_ERROR;
+}
+
+struct fixup_entry {
+ struct fixup_entry *next;
+ struct archive_acl acl;
+ mode_t mode;
+ int64_t atime;
+ int64_t birthtime;
+ int64_t mtime;
+ int64_t ctime;
+ unsigned long atime_nanos;
+ unsigned long birthtime_nanos;
+ unsigned long mtime_nanos;
+ unsigned long ctime_nanos;
+ unsigned long fflags_set;
+ int fixup; /* bitmask of what needs fixing */
+ wchar_t *name;
+};
+
+/*
+ * We use a bitmask to track which operations remain to be done for
+ * this file. In particular, this helps us avoid unnecessary
+ * operations when it's possible to take care of one step as a
+ * side-effect of another. For example, mkdir() can specify the mode
+ * for the newly-created object but symlink() cannot. This means we
+ * can skip chmod() if mkdir() succeeded, but we must explicitly
+ * chmod() if we're trying to create a directory that already exists
+ * (mkdir() failed) or if we're restoring a symlink. Similarly, we
+ * need to verify UID/GID before trying to restore SUID/SGID bits;
+ * that verification can occur explicitly through a stat() call or
+ * implicitly because of a successful chown() call.
+ */
+#define TODO_MODE_FORCE 0x40000000
+#define TODO_MODE_BASE 0x20000000
+#define TODO_SUID 0x10000000
+#define TODO_SUID_CHECK 0x08000000
+#define TODO_SGID 0x04000000
+#define TODO_SGID_CHECK 0x02000000
+#define TODO_MODE (TODO_MODE_BASE|TODO_SUID|TODO_SGID)
+#define TODO_TIMES ARCHIVE_EXTRACT_TIME
+#define TODO_OWNER ARCHIVE_EXTRACT_OWNER
+#define TODO_FFLAGS ARCHIVE_EXTRACT_FFLAGS
+#define TODO_ACLS ARCHIVE_EXTRACT_ACL
+#define TODO_XATTR ARCHIVE_EXTRACT_XATTR
+#define TODO_MAC_METADATA ARCHIVE_EXTRACT_MAC_METADATA
+
+struct archive_write_disk {
+ struct archive archive;
+
+ mode_t user_umask;
+ struct fixup_entry *fixup_list;
+ struct fixup_entry *current_fixup;
+ int64_t user_uid;
+ int skip_file_set;
+ dev_t skip_file_dev;
+ ino_t skip_file_ino;
+ time_t start_time;
+
+ int64_t (*lookup_gid)(void *private, const char *gname, int64_t gid);
+ void (*cleanup_gid)(void *private);
+ void *lookup_gid_data;
+ int64_t (*lookup_uid)(void *private, const char *uname, int64_t uid);
+ void (*cleanup_uid)(void *private);
+ void *lookup_uid_data;
+
+ /*
+ * Full path of last file to satisfy symlink checks.
+ */
+ struct archive_wstring path_safe;
+
+ /*
+ * Cached stat data from disk for the current entry.
+ * If this is valid, pst points to st. Otherwise,
+ * pst is null.
+ */
+ BY_HANDLE_FILE_INFORMATION st;
+ BY_HANDLE_FILE_INFORMATION *pst;
+
+ /* Information about the object being restored right now. */
+ struct archive_entry *entry; /* Entry being extracted. */
+ wchar_t *name; /* Name of entry, possibly edited. */
+ struct archive_wstring _name_data; /* backing store for 'name' */
+ /* Tasks remaining for this object. */
+ int todo;
+ /* Tasks deferred until end-of-archive. */
+ int deferred;
+ /* Options requested by the client. */
+ int flags;
+ /* Handle for the file we're restoring. */
+ HANDLE fh;
+ /* Current offset for writing data to the file. */
+ int64_t offset;
+ /* Last offset actually written to disk. */
+ int64_t fd_offset;
+ /* Total bytes actually written to files. */
+ int64_t total_bytes_written;
+ /* Maximum size of file, -1 if unknown. */
+ int64_t filesize;
+ /* Dir we were in before this restore; only for deep paths. */
+ int restore_pwd;
+ /* Mode we should use for this entry; affected by _PERM and umask. */
+ mode_t mode;
+ /* UID/GID to use in restoring this entry. */
+ int64_t uid;
+ int64_t gid;
+};
+
+/*
+ * Default mode for dirs created automatically (will be modified by umask).
+ * Note that POSIX specifies 0777 for implicity-created dirs, "modified
+ * by the process' file creation mask."
+ */
+#define DEFAULT_DIR_MODE 0777
+/*
+ * Dir modes are restored in two steps: During the extraction, the permissions
+ * in the archive are modified to match the following limits. During
+ * the post-extract fixup pass, the permissions from the archive are
+ * applied.
+ */
+#define MINIMUM_DIR_MODE 0700
+#define MAXIMUM_DIR_MODE 0775
+
+static int check_symlinks(struct archive_write_disk *);
+static int create_filesystem_object(struct archive_write_disk *);
+static struct fixup_entry *current_fixup(struct archive_write_disk *, const wchar_t *pathname);
+#if defined(HAVE_FCHDIR) && defined(PATH_MAX)
+static void edit_deep_directories(struct archive_write_disk *ad);
+#endif
+static int cleanup_pathname(struct archive_write_disk *);
+static int create_dir(struct archive_write_disk *, wchar_t *);
+static int create_parent_dir(struct archive_write_disk *, wchar_t *);
+static int older(BY_HANDLE_FILE_INFORMATION *, struct archive_entry *);
+static int restore_entry(struct archive_write_disk *);
+#ifdef HAVE_POSIX_ACL
+static int set_acl(struct archive_write_disk *, int fd, const char *, struct archive_acl *,
+ acl_type_t, int archive_entry_acl_type, const char *tn);
+#endif
+static int set_acls(struct archive_write_disk *, HANDLE h, const wchar_t *, struct archive_acl *);
+static int set_xattrs(struct archive_write_disk *);
+static int set_fflags(struct archive_write_disk *);
+static int set_ownership(struct archive_write_disk *);
+static int set_mode(struct archive_write_disk *, int mode);
+static int set_times(struct archive_write_disk *, HANDLE, int, const wchar_t *,
+ time_t, long, time_t, long, time_t, long, time_t, long);
+static int set_times_from_entry(struct archive_write_disk *);
+static struct fixup_entry *sort_dir_list(struct fixup_entry *p);
+static ssize_t write_data_block(struct archive_write_disk *,
+ const char *, size_t);
+
+static struct archive_vtable *archive_write_disk_vtable(void);
+
+static int _archive_write_disk_close(struct archive *);
+static int _archive_write_disk_free(struct archive *);
+static int _archive_write_disk_header(struct archive *, struct archive_entry *);
+static int64_t _archive_write_disk_filter_bytes(struct archive *, int);
+static int _archive_write_disk_finish_entry(struct archive *);
+static ssize_t _archive_write_disk_data(struct archive *, const void *, size_t);
+static ssize_t _archive_write_disk_data_block(struct archive *, const void *, size_t, int64_t);
+
+#define bhfi_dev(bhfi) ((bhfi)->dwVolumeSerialNumber)
+/* Treat FileIndex as i-node. We should remove a sequence number
+ * which is high-16-bits of nFileIndexHigh. */
+#define bhfi_ino(bhfi) \
+ ((((int64_t)((bhfi)->nFileIndexHigh & 0x0000FFFFUL)) << 32) \
+ + (bhfi)->nFileIndexLow)
+#define bhfi_size(bhfi) \
+ ((((int64_t)(bhfi)->nFileSizeHigh) << 32) + (bhfi)->nFileSizeLow)
+
+static int
+file_information(struct archive_write_disk *a, wchar_t *path,
+ BY_HANDLE_FILE_INFORMATION *st, mode_t *mode, int sim_lstat)
+{
+ HANDLE h;
+ int r;
+ DWORD flag = FILE_FLAG_BACKUP_SEMANTICS;
+ WIN32_FIND_DATAW findData;
+
+ if (sim_lstat || mode != NULL) {
+ h = FindFirstFileW(path, &findData);
+ if (h == INVALID_HANDLE_VALUE &&
+ GetLastError() == ERROR_INVALID_NAME) {
+ wchar_t *full;
+ full = __la_win_permissive_name_w(path);
+ h = FindFirstFileW(full, &findData);
+ free(full);
+ }
+ if (h == INVALID_HANDLE_VALUE) {
+ la_dosmaperr(GetLastError());
+ return (-1);
+ }
+ FindClose(h);
+ }
+
+ /* Is symlink file ? */
+ if (sim_lstat &&
+ ((findData.dwFileAttributes
+ & FILE_ATTRIBUTE_REPARSE_POINT) &&
+ (findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK)))
+ flag |= FILE_FLAG_OPEN_REPARSE_POINT;
+
+ h = CreateFileW(a->name, 0, 0, NULL,
+ OPEN_EXISTING, flag, NULL);
+ if (h == INVALID_HANDLE_VALUE &&
+ GetLastError() == ERROR_INVALID_NAME) {
+ wchar_t *full;
+ full = __la_win_permissive_name_w(path);
+ h = CreateFileW(full, 0, 0, NULL,
+ OPEN_EXISTING, flag, NULL);
+ free(full);
+ }
+ if (h == INVALID_HANDLE_VALUE) {
+ la_dosmaperr(GetLastError());
+ return (-1);
+ }
+ r = GetFileInformationByHandle(h, st);
+ CloseHandle(h);
+ if (r == 0) {
+ la_dosmaperr(GetLastError());
+ return (-1);
+ }
+
+ if (mode == NULL)
+ return (0);
+
+ *mode = S_IRUSR | S_IRGRP | S_IROTH;
+ if ((st->dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0)
+ *mode |= S_IWUSR | S_IWGRP | S_IWOTH;
+ if ((st->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
+ findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK)
+ *mode |= S_IFLNK;
+ else if (st->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ *mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
+ else {
+ const wchar_t *p;
+
+ *mode |= S_IFREG;
+ p = wcsrchr(path, L'.');
+ if (p != NULL && wcslen(p) == 4) {
+ switch (p[1]) {
+ case L'B': case L'b':
+ if ((p[2] == L'A' || p[2] == L'a' ) &&
+ (p[3] == L'T' || p[3] == L't' ))
+ *mode |= S_IXUSR | S_IXGRP | S_IXOTH;
+ 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;
+ case L'E': case L'e':
+ if ((p[2] == L'X' || p[2] == L'x' ) &&
+ (p[3] == L'E' || p[3] == L'e' ))
+ *mode |= S_IXUSR | S_IXGRP | S_IXOTH;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return (0);
+}
+
+/*
+ * Note: The path, for example, "aa/a/../b../c" will be converted to "aa/c"
+ * by GetFullPathNameW() W32 API, which __la_win_permissive_name_w uses.
+ * It means we cannot handle multiple dirs in one archive_entry.
+ * So we have to make the full-pathname in another way, which does not
+ * break "../" path string.
+ */
+int
+permissive_name_w(struct archive_write_disk *a)
+{
+ wchar_t *wn, *wnp;
+ wchar_t *ws, *wsp;
+ DWORD l;
+
+ wnp = a->name;
+ if (wnp[0] == L'\\' && wnp[1] == L'\\' &&
+ wnp[2] == L'?' && wnp[3] == L'\\')
+ /* We have already a permissive name. */
+ return (0);
+
+ if (wnp[0] == L'\\' && wnp[1] == L'\\' &&
+ wnp[2] == L'.' && wnp[3] == L'\\') {
+ /* This is a device name */
+ if (((wnp[4] >= L'a' && wnp[4] <= L'z') ||
+ (wnp[4] >= L'A' && wnp[4] <= L'Z')) &&
+ wnp[5] == L':' && wnp[6] == L'\\') {
+ wnp[2] = L'?';/* Not device name. */
+ return (0);
+ }
+ }
+
+ /*
+ * A full-pathname starting with a drive name like "C:\abc".
+ */
+ if (((wnp[0] >= L'a' && wnp[0] <= L'z') ||
+ (wnp[0] >= L'A' && wnp[0] <= L'Z')) &&
+ wnp[1] == L':' && wnp[2] == L'\\') {
+ wn = _wcsdup(wnp);
+ if (wn == NULL)
+ return (-1);
+ archive_wstring_ensure(&(a->_name_data), 4 + wcslen(wn) + 1);
+ a->name = a->_name_data.s;
+ /* Prepend "\\?\" */
+ archive_wstrncpy(&(a->_name_data), L"\\\\?\\", 4);
+ archive_wstrcat(&(a->_name_data), wn);
+ free(wn);
+ return (0);
+ }
+
+ /*
+ * A full-pathname pointig a network drive
+ * like "\\<server-name>\<share-name>\file".
+ */
+ if (wnp[0] == L'\\' && wnp[1] == L'\\' && wnp[2] != L'\\') {
+ const wchar_t *p = &wnp[2];
+
+ /* Skip server-name letters. */
+ while (*p != L'\\' && *p != L'\0')
+ ++p;
+ if (*p == L'\\') {
+ const wchar_t *rp = ++p;
+ /* Skip share-name letters. */
+ while (*p != L'\\' && *p != L'\0')
+ ++p;
+ if (*p == L'\\' && p != rp) {
+ /* Now, match patterns such as
+ * "\\server-name\share-name\" */
+ wn = _wcsdup(wnp);
+ if (wn == NULL)
+ return (-1);
+ archive_wstring_ensure(&(a->_name_data), 8 + wcslen(wn) + 1);
+ a->name = a->_name_data.s;
+ /* Prepend "\\?\UNC\" */
+ archive_wstrncpy(&(a->_name_data), L"\\\\?\\UNC\\", 8);
+ archive_wstrcat(&(a->_name_data), wn+2);
+ free(wn);
+ return (0);
+ }
+ }
+ return (0);
+ }
+
+ /*
+ * Get current working directory.
+ */
+ l = GetCurrentDirectoryW(0, NULL);
+ if (l == 0)
+ return (-1);
+ ws = malloc(l * sizeof(wchar_t));
+ l = GetCurrentDirectoryW(l, ws);
+ if (l == 0) {
+ free(ws);
+ return (-1);
+ }
+ wsp = ws;
+
+ /*
+ * A full-pathname starting without a drive name like "\abc".
+ */
+ if (wnp[0] == L'\\') {
+ wn = _wcsdup(wnp);
+ if (wn == NULL)
+ return (-1);
+ archive_wstring_ensure(&(a->_name_data), 4 + 2 + wcslen(wn) + 1);
+ a->name = a->_name_data.s;
+ /* Prepend "\\?\" and drive name. */
+ archive_wstrncpy(&(a->_name_data), L"\\\\?\\", 4);
+ archive_wstrncat(&(a->_name_data), wsp, 2);
+ archive_wstrcat(&(a->_name_data), wn);
+ free(wsp);
+ free(wn);
+ return (0);
+ }
+
+ wn = _wcsdup(wnp);
+ if (wn == NULL)
+ return (-1);
+ archive_wstring_ensure(&(a->_name_data), 4 + l + 1 + wcslen(wn) + 1);
+ a->name = a->_name_data.s;
+ /* Prepend "\\?\" and drive name. */
+ archive_wstrncpy(&(a->_name_data), L"\\\\?\\", 4);
+ archive_wstrncat(&(a->_name_data), wsp, l);
+ archive_wstrncat(&(a->_name_data), L"\\", 1);
+ archive_wstrcat(&(a->_name_data), wn);
+ a->name = a->_name_data.s;
+ free(wsp);
+ free(wn);
+ return (0);
+}
+
+int
+la_chmod(const wchar_t *path, mode_t mode)
+{
+ DWORD attr;
+ BOOL r;
+ wchar_t *fullname;
+ int ret = 0;
+
+ fullname = NULL;
+ attr = GetFileAttributesW(path);
+ if (attr == (DWORD)-1 &&
+ GetLastError() == ERROR_INVALID_NAME) {
+ fullname = __la_win_permissive_name_w(path);
+ attr = GetFileAttributesW(fullname);
+ }
+ if (attr == (DWORD)-1) {
+ la_dosmaperr(GetLastError());
+ ret = -1;
+ goto exit_chmode;
+ }
+ if (mode & _S_IWRITE)
+ attr &= ~FILE_ATTRIBUTE_READONLY;
+ else
+ attr |= FILE_ATTRIBUTE_READONLY;
+ if (fullname != NULL)
+ r = SetFileAttributesW(fullname, attr);
+ else
+ r = SetFileAttributesW(path, attr);
+ if (r == 0) {
+ la_dosmaperr(GetLastError());
+ ret = -1;
+ }
+exit_chmode:
+ free(fullname);
+ return (ret);
+}
+
+static void *
+la_GetFunctionKernel32(const char *name)
+{
+ static HINSTANCE lib;
+ static int set;
+ if (!set) {
+ set = 1;
+ lib = LoadLibrary("kernel32.dll");
+ }
+ if (lib == NULL) {
+ fprintf(stderr, "Can't load kernel32.dll?!\n");
+ exit(1);
+ }
+ return (void *)GetProcAddress(lib, name);
+}
+
+static int
+la_CreateHardLinkW(wchar_t *linkname, wchar_t *target)
+{
+ static BOOLEAN (WINAPI *f)(LPWSTR, LPWSTR, LPSECURITY_ATTRIBUTES);
+ static int set;
+ BOOL ret;
+
+ if (!set) {
+ set = 1;
+ f = la_GetFunctionKernel32("CreateHardLinkW");
+ }
+ if (!f)
+ return (0);
+ ret = (*f)(linkname, target, NULL);
+ if (!ret) {
+ /* Under windows 2000, it is necessary to remove
+ * the "\\?\" prefix. */
+#define IS_UNC(name) ((name[0] == L'U' || name[0] == L'u') && \
+ (name[1] == L'N' || name[1] == L'n') && \
+ (name[2] == L'C' || name[2] == L'c') && \
+ name[3] == L'\\')
+ if (!wcsncmp(linkname,L"\\\\?\\", 4)) {
+ linkname += 4;
+ if (IS_UNC(linkname))
+ linkname += 4;
+ }
+ if (!wcsncmp(target,L"\\\\?\\", 4)) {
+ target += 4;
+ if (IS_UNC(target))
+ target += 4;
+ }
+#undef IS_UNC
+ ret = (*f)(linkname, target, NULL);
+ }
+ return (ret);
+}
+
+static int
+la_ftruncate(HANDLE handle, int64_t length)
+{
+ LARGE_INTEGER distance;
+
+ if (GetFileType(handle) != FILE_TYPE_DISK) {
+ errno = EBADF;
+ return (-1);
+ }
+ distance.QuadPart = length;
+ if (!SetFilePointerEx_perso(handle, distance, NULL, FILE_BEGIN)) {
+ la_dosmaperr(GetLastError());
+ return (-1);
+ }
+ if (!SetEndOfFile(handle)) {
+ la_dosmaperr(GetLastError());
+ return (-1);
+ }
+ return (0);
+}
+
+static int
+lazy_stat(struct archive_write_disk *a)
+{
+ if (a->pst != NULL) {
+ /* Already have stat() data available. */
+ return (ARCHIVE_OK);
+ }
+ if (a->fh != INVALID_HANDLE_VALUE &&
+ GetFileInformationByHandle(a->fh, &a->st) == 0) {
+ a->pst = &a->st;
+ return (ARCHIVE_OK);
+ }
+
+ /*
+ * XXX At this point, symlinks should not be hit, otherwise
+ * XXX a race occured. Do we want to check explicitly for that?
+ */
+ if (file_information(a, a->name, &a->st, NULL, 1) == 0) {
+ a->pst = &a->st;
+ return (ARCHIVE_OK);
+ }
+ archive_set_error(&a->archive, errno, "Couldn't stat file");
+ return (ARCHIVE_WARN);
+}
+
+static struct archive_vtable *
+archive_write_disk_vtable(void)
+{
+ static struct archive_vtable av;
+ static int inited = 0;
+
+ if (!inited) {
+ av.archive_close = _archive_write_disk_close;
+ av.archive_filter_bytes = _archive_write_disk_filter_bytes;
+ av.archive_free = _archive_write_disk_free;
+ av.archive_write_header = _archive_write_disk_header;
+ av.archive_write_finish_entry
+ = _archive_write_disk_finish_entry;
+ av.archive_write_data = _archive_write_disk_data;
+ av.archive_write_data_block = _archive_write_disk_data_block;
+ inited = 1;
+ }
+ return (&av);
+}
+
+static int64_t
+_archive_write_disk_filter_bytes(struct archive *_a, int n)
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+ (void)n; /* UNUSED */
+ if (n == -1 || n == 0)
+ return (a->total_bytes_written);
+ return (-1);
+}
+
+
+int
+archive_write_disk_set_options(struct archive *_a, int flags)
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+
+ a->flags = flags;
+ return (ARCHIVE_OK);
+}
+
+
+/*
+ * Extract this entry to disk.
+ *
+ * TODO: Validate hardlinks. According to the standards, we're
+ * supposed to check each extracted hardlink and squawk if it refers
+ * to a file that we didn't restore. I'm not entirely convinced this
+ * is a good idea, but more importantly: Is there any way to validate
+ * hardlinks without keeping a complete list of filenames from the
+ * entire archive?? Ugh.
+ *
+ */
+static int
+_archive_write_disk_header(struct archive *_a, struct archive_entry *entry)
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+ struct fixup_entry *fe;
+ int ret, r;
+
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
+ "archive_write_disk_header");
+ archive_clear_error(&a->archive);
+ if (a->archive.state & ARCHIVE_STATE_DATA) {
+ r = _archive_write_disk_finish_entry(&a->archive);
+ if (r == ARCHIVE_FATAL)
+ return (r);
+ }
+
+ /* Set up for this particular entry. */
+ a->pst = NULL;
+ a->current_fixup = NULL;
+ a->deferred = 0;
+ if (a->entry) {
+ archive_entry_free(a->entry);
+ a->entry = NULL;
+ }
+ a->entry = archive_entry_clone(entry);
+ a->fh = INVALID_HANDLE_VALUE;
+ a->fd_offset = 0;
+ a->offset = 0;
+ a->restore_pwd = -1;
+ a->uid = a->user_uid;
+ a->mode = archive_entry_mode(a->entry);
+ if (archive_entry_size_is_set(a->entry))
+ a->filesize = archive_entry_size(a->entry);
+ else
+ a->filesize = -1;
+ archive_wstrcpy(&(a->_name_data), archive_entry_pathname_w(a->entry));
+ a->name = a->_name_data.s;
+ archive_clear_error(&a->archive);
+
+ /*
+ * Clean up the requested path. This is necessary for correct
+ * dir restores; the dir restore logic otherwise gets messed
+ * up by nonsense like "dir/.".
+ */
+ ret = cleanup_pathname(a);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+
+ /*
+ * Generate a full-pathname and use it from here.
+ */
+ if (permissive_name_w(a) < 0) {
+ errno = EINVAL;
+ return (ARCHIVE_FAILED);
+ }
+
+ /*
+ * Query the umask so we get predictable mode settings.
+ * This gets done on every call to _write_header in case the
+ * user edits their umask during the extraction for some
+ * reason.
+ */
+ umask(a->user_umask = umask(0));
+
+ /* Figure out what we need to do for this entry. */
+ a->todo = TODO_MODE_BASE;
+ if (a->flags & ARCHIVE_EXTRACT_PERM) {
+ a->todo |= TODO_MODE_FORCE; /* Be pushy about permissions. */
+ /*
+ * SGID requires an extra "check" step because we
+ * cannot easily predict the GID that the system will
+ * assign. (Different systems assign GIDs to files
+ * based on a variety of criteria, including process
+ * credentials and the gid of the enclosing
+ * directory.) We can only restore the SGID bit if
+ * the file has the right GID, and we only know the
+ * GID if we either set it (see set_ownership) or if
+ * we've actually called stat() on the file after it
+ * was restored. Since there are several places at
+ * which we might verify the GID, we need a TODO bit
+ * to keep track.
+ */
+ if (a->mode & S_ISGID)
+ a->todo |= TODO_SGID | TODO_SGID_CHECK;
+ /*
+ * Verifying the SUID is simpler, but can still be
+ * done in multiple ways, hence the separate "check" bit.
+ */
+ if (a->mode & S_ISUID)
+ a->todo |= TODO_SUID | TODO_SUID_CHECK;
+ } else {
+ /*
+ * User didn't request full permissions, so don't
+ * restore SUID, SGID bits and obey umask.
+ */
+ a->mode &= ~S_ISUID;
+ a->mode &= ~S_ISGID;
+ a->mode &= ~S_ISVTX;
+ a->mode &= ~a->user_umask;
+ }
+#if 0
+ if (a->flags & ARCHIVE_EXTRACT_OWNER)
+ a->todo |= TODO_OWNER;
+#endif
+ if (a->flags & ARCHIVE_EXTRACT_TIME)
+ a->todo |= TODO_TIMES;
+ if (a->flags & ARCHIVE_EXTRACT_ACL) {
+ if (archive_entry_filetype(a->entry) == AE_IFDIR)
+ a->deferred |= TODO_ACLS;
+ else
+ a->todo |= TODO_ACLS;
+ }
+ if (a->flags & ARCHIVE_EXTRACT_XATTR)
+ a->todo |= TODO_XATTR;
+ if (a->flags & ARCHIVE_EXTRACT_FFLAGS)
+ a->todo |= TODO_FFLAGS;
+ if (a->flags & ARCHIVE_EXTRACT_SECURE_SYMLINKS) {
+ ret = check_symlinks(a);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ }
+
+ ret = restore_entry(a);
+
+ /*
+ * TODO: There are rumours that some extended attributes must
+ * be restored before file data is written. If this is true,
+ * then we either need to write all extended attributes both
+ * before and after restoring the data, or find some rule for
+ * determining which must go first and which last. Due to the
+ * many ways people are using xattrs, this may prove to be an
+ * intractable problem.
+ */
+
+ /*
+ * Fixup uses the unedited pathname from archive_entry_pathname(),
+ * because it is relative to the base dir and the edited path
+ * might be relative to some intermediate dir as a result of the
+ * deep restore logic.
+ */
+ if (a->deferred & TODO_MODE) {
+ fe = current_fixup(a, archive_entry_pathname_w(entry));
+ fe->fixup |= TODO_MODE_BASE;
+ fe->mode = a->mode;
+ }
+
+ if ((a->deferred & TODO_TIMES)
+ && (archive_entry_mtime_is_set(entry)
+ || archive_entry_atime_is_set(entry))) {
+ fe = current_fixup(a, archive_entry_pathname_w(entry));
+ fe->mode = a->mode;
+ fe->fixup |= TODO_TIMES;
+ if (archive_entry_atime_is_set(entry)) {
+ fe->atime = archive_entry_atime(entry);
+ fe->atime_nanos = archive_entry_atime_nsec(entry);
+ } else {
+ /* If atime is unset, use start time. */
+ fe->atime = a->start_time;
+ fe->atime_nanos = 0;
+ }
+ if (archive_entry_mtime_is_set(entry)) {
+ fe->mtime = archive_entry_mtime(entry);
+ fe->mtime_nanos = archive_entry_mtime_nsec(entry);
+ } else {
+ /* If mtime is unset, use start time. */
+ fe->mtime = a->start_time;
+ fe->mtime_nanos = 0;
+ }
+ if (archive_entry_birthtime_is_set(entry)) {
+ fe->birthtime = archive_entry_birthtime(entry);
+ fe->birthtime_nanos = archive_entry_birthtime_nsec(entry);
+ } else {
+ /* If birthtime is unset, use mtime. */
+ fe->birthtime = fe->mtime;
+ fe->birthtime_nanos = fe->mtime_nanos;
+ }
+ }
+
+ if (a->deferred & TODO_ACLS) {
+ fe = current_fixup(a, archive_entry_pathname_w(entry));
+ archive_acl_copy(&fe->acl, archive_entry_acl(entry));
+ }
+
+ if (a->deferred & TODO_FFLAGS) {
+ fe = current_fixup(a, archive_entry_pathname_w(entry));
+ fe->fixup |= TODO_FFLAGS;
+ /* TODO: Complete this.. defer fflags from below. */
+ }
+
+ /*
+ * On Windows, A creating sparse file requires a special mark.
+ */
+ if (a->fh != INVALID_HANDLE_VALUE &&
+ archive_entry_sparse_count(entry) > 0) {
+ int64_t base = 0, offset, length;
+ int i, cnt = archive_entry_sparse_reset(entry);
+ int sparse = 0;
+
+ for (i = 0; i < cnt; i++) {
+ archive_entry_sparse_next(entry, &offset, &length);
+ if (offset - base >= 4096) {
+ sparse = 1;/* we have a hole. */
+ break;
+ }
+ base = offset + length;
+ }
+ if (sparse) {
+ DWORD dmy;
+ /* Mark this file as sparse. */
+ DeviceIoControl(a->fh, FSCTL_SET_SPARSE,
+ NULL, 0, NULL, 0, &dmy, NULL);
+ }
+ }
+
+ /* We've created the object and are ready to pour data into it. */
+ if (ret >= ARCHIVE_WARN)
+ a->archive.state = ARCHIVE_STATE_DATA;
+ /*
+ * If it's not open, tell our client not to try writing.
+ * In particular, dirs, links, etc, don't get written to.
+ */
+ if (a->fh == INVALID_HANDLE_VALUE) {
+ archive_entry_set_size(entry, 0);
+ a->filesize = 0;
+ }
+
+ return (ret);
+}
+
+int
+archive_write_disk_set_skip_file(struct archive *_a, int64_t d, int64_t i)
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_write_disk_set_skip_file");
+ a->skip_file_set = 1;
+ a->skip_file_dev = d;
+ a->skip_file_ino = i;
+ return (ARCHIVE_OK);
+}
+
+static ssize_t
+write_data_block(struct archive_write_disk *a, const char *buff, size_t size)
+{
+ uint64_t start_size = size;
+ DWORD bytes_written = 0;
+ ssize_t block_size = 0, bytes_to_write;
+
+ if (size == 0)
+ return (ARCHIVE_OK);
+
+ if (a->filesize == 0 || a->fh == INVALID_HANDLE_VALUE) {
+ archive_set_error(&a->archive, 0,
+ "Attempt to write to an empty file");
+ return (ARCHIVE_WARN);
+ }
+
+ if (a->flags & ARCHIVE_EXTRACT_SPARSE) {
+ /* XXX TODO XXX Is there a more appropriate choice here ? */
+ /* This needn't match the filesystem allocation size. */
+ block_size = 16*1024;
+ }
+
+ /* If this write would run beyond the file size, truncate it. */
+ if (a->filesize >= 0 && (int64_t)(a->offset + size) > a->filesize)
+ start_size = size = (size_t)(a->filesize - a->offset);
+
+ /* Write the data. */
+ while (size > 0) {
+ if (block_size == 0) {
+ bytes_to_write = size;
+ } else {
+ /* We're sparsifying the file. */
+ const char *p, *end;
+ int64_t block_end;
+
+ /* Skip leading zero bytes. */
+ for (p = buff, end = buff + size; p < end; ++p) {
+ if (*p != '\0')
+ break;
+ }
+ a->offset += p - buff;
+ size -= p - buff;
+ buff = p;
+ if (size == 0)
+ break;
+
+ /* Calculate next block boundary after offset. */
+ block_end
+ = (a->offset / block_size + 1) * block_size;
+
+ /* If the adjusted write would cross block boundary,
+ * truncate it to the block boundary. */
+ bytes_to_write = size;
+ if (a->offset + bytes_to_write > block_end)
+ bytes_to_write = block_end - a->offset;
+ }
+ /* Seek if necessary to the specified offset. */
+ if (a->offset != a->fd_offset) {
+ LARGE_INTEGER distance;
+ distance.QuadPart = a->offset;
+ if (SetFilePointerEx_perso(a->fh, distance, NULL, FILE_BEGIN) == 0) {
+ DWORD lasterr = GetLastError();
+ if (lasterr == ERROR_ACCESS_DENIED)
+ errno = EBADF;
+ else
+ la_dosmaperr(lasterr);
+ archive_set_error(&a->archive, errno,
+ "Seek failed");
+ return (ARCHIVE_FATAL);
+ }
+ a->fd_offset = a->offset;
+ }
+ if (!WriteFile(a->fh, buff, (uint32_t)bytes_to_write,
+ &bytes_written, NULL)) {
+ DWORD lasterr;
+
+ lasterr = GetLastError();
+ if (lasterr == ERROR_ACCESS_DENIED)
+ errno = EBADF;
+ else
+ la_dosmaperr(lasterr);
+ archive_set_error(&a->archive, errno, "Write failed");
+ return (ARCHIVE_WARN);
+ }
+ buff += bytes_written;
+ size -= bytes_written;
+ a->total_bytes_written += bytes_written;
+ a->offset += bytes_written;
+ a->fd_offset = a->offset;
+ }
+ return (start_size - size);
+}
+
+static ssize_t
+_archive_write_disk_data_block(struct archive *_a,
+ const void *buff, size_t size, int64_t offset)
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+ ssize_t r;
+
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_DATA, "archive_write_data_block");
+
+ a->offset = offset;
+ r = write_data_block(a, buff, size);
+ if (r < ARCHIVE_OK)
+ return (r);
+ if ((size_t)r < size) {
+ archive_set_error(&a->archive, 0,
+ "Write request too large");
+ return (ARCHIVE_WARN);
+ }
+ return (ARCHIVE_OK);
+}
+
+static ssize_t
+_archive_write_disk_data(struct archive *_a, const void *buff, size_t size)
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_DATA, "archive_write_data");
+
+ return (write_data_block(a, buff, size));
+}
+
+static int
+_archive_write_disk_finish_entry(struct archive *_a)
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+ int ret = ARCHIVE_OK;
+
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
+ "archive_write_finish_entry");
+ if (a->archive.state & ARCHIVE_STATE_HEADER)
+ return (ARCHIVE_OK);
+ archive_clear_error(&a->archive);
+
+ /* Pad or truncate file to the right size. */
+ if (a->fh == INVALID_HANDLE_VALUE) {
+ /* There's no file. */
+ } else if (a->filesize < 0) {
+ /* File size is unknown, so we can't set the size. */
+ } else if (a->fd_offset == a->filesize) {
+ /* Last write ended at exactly the filesize; we're done. */
+ /* Hopefully, this is the common case. */
+ } else {
+ if (la_ftruncate(a->fh, a->filesize) == -1 &&
+ a->filesize == 0) {
+ archive_set_error(&a->archive, errno,
+ "File size could not be restored");
+ return (ARCHIVE_FAILED);
+ }
+ /*
+ * Not all platforms implement the XSI option to
+ * extend files via ftruncate. Stat() the file again
+ * to see what happened.
+ */
+ a->pst = NULL;
+ if ((ret = lazy_stat(a)) != ARCHIVE_OK)
+ return (ret);
+ /* We can use lseek()/write() to extend the file if
+ * ftruncate didn't work or isn't available. */
+ if (bhfi_size(&(a->st)) < a->filesize) {
+ const char nul = '\0';
+ LARGE_INTEGER distance;
+ distance.QuadPart = a->filesize - 1;
+ if (!SetFilePointerEx_perso(a->fh, distance, NULL, FILE_BEGIN)) {
+ DWORD lasterr = GetLastError();
+ if (lasterr == ERROR_ACCESS_DENIED)
+ errno = EBADF;
+ else
+ la_dosmaperr(lasterr);
+ archive_set_error(&a->archive, errno,
+ "Seek failed");
+ return (ARCHIVE_FATAL);
+ }
+ if (!WriteFile(a->fh, &nul, 1, NULL, NULL)) {
+ DWORD lasterr = GetLastError();
+ if (lasterr == ERROR_ACCESS_DENIED)
+ errno = EBADF;
+ else
+ la_dosmaperr(lasterr);
+ archive_set_error(&a->archive, errno,
+ "Write to restore size failed");
+ return (ARCHIVE_FATAL);
+ }
+ a->pst = NULL;
+ }
+ }
+
+ /* Restore metadata. */
+
+ /*
+ * Look up the "real" UID only if we're going to need it.
+ * TODO: the TODO_SGID condition can be dropped here, can't it?
+ */
+ if (a->todo & (TODO_OWNER | TODO_SUID | TODO_SGID)) {
+ a->uid = archive_write_disk_uid(&a->archive,
+ archive_entry_uname(a->entry),
+ archive_entry_uid(a->entry));
+ }
+ /* Look up the "real" GID only if we're going to need it. */
+ /* TODO: the TODO_SUID condition can be dropped here, can't it? */
+ if (a->todo & (TODO_OWNER | TODO_SGID | TODO_SUID)) {
+ a->gid = archive_write_disk_gid(&a->archive,
+ archive_entry_gname(a->entry),
+ archive_entry_gid(a->entry));
+ }
+
+ /*
+ * Restore ownership before set_mode tries to restore suid/sgid
+ * bits. If we set the owner, we know what it is and can skip
+ * a stat() call to examine the ownership of the file on disk.
+ */
+ if (a->todo & TODO_OWNER)
+ ret = set_ownership(a);
+
+ /*
+ * set_mode must precede ACLs on systems such as Solaris and
+ * FreeBSD where setting the mode implicitly clears extended ACLs
+ */
+ if (a->todo & TODO_MODE) {
+ int r2 = set_mode(a, a->mode);
+ if (r2 < ret) ret = r2;
+ }
+
+ /*
+ * Security-related extended attributes (such as
+ * security.capability on Linux) have to be restored last,
+ * since they're implicitly removed by other file changes.
+ */
+ if (a->todo & TODO_XATTR) {
+ int r2 = set_xattrs(a);
+ if (r2 < ret) ret = r2;
+ }
+
+ /*
+ * Some flags prevent file modification; they must be restored after
+ * file contents are written.
+ */
+ if (a->todo & TODO_FFLAGS) {
+ int r2 = set_fflags(a);
+ if (r2 < ret) ret = r2;
+ }
+
+ /*
+ * Time must follow most other metadata;
+ * otherwise atime will get changed.
+ */
+ if (a->todo & TODO_TIMES) {
+ int r2 = set_times_from_entry(a);
+ if (r2 < ret) ret = r2;
+ }
+
+ /*
+ * ACLs must be restored after timestamps because there are
+ * ACLs that prevent attribute changes (including time).
+ */
+ if (a->todo & TODO_ACLS) {
+ int r2 = set_acls(a, a->fh,
+ archive_entry_pathname_w(a->entry),
+ archive_entry_acl(a->entry));
+ if (r2 < ret) ret = r2;
+ }
+
+ /* If there's an fd, we can close it now. */
+ if (a->fh != INVALID_HANDLE_VALUE) {
+ CloseHandle(a->fh);
+ a->fh = INVALID_HANDLE_VALUE;
+ }
+ /* If there's an entry, we can release it now. */
+ if (a->entry) {
+ archive_entry_free(a->entry);
+ a->entry = NULL;
+ }
+ a->archive.state = ARCHIVE_STATE_HEADER;
+ return (ret);
+}
+
+int
+archive_write_disk_set_group_lookup(struct archive *_a,
+ void *private_data,
+ int64_t (*lookup_gid)(void *private, const char *gname, int64_t gid),
+ void (*cleanup_gid)(void *private))
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_write_disk_set_group_lookup");
+
+ if (a->cleanup_gid != NULL && a->lookup_gid_data != NULL)
+ (a->cleanup_gid)(a->lookup_gid_data);
+
+ a->lookup_gid = lookup_gid;
+ a->cleanup_gid = cleanup_gid;
+ a->lookup_gid_data = private_data;
+ return (ARCHIVE_OK);
+}
+
+int
+archive_write_disk_set_user_lookup(struct archive *_a,
+ void *private_data,
+ int64_t (*lookup_uid)(void *private, const char *uname, int64_t uid),
+ void (*cleanup_uid)(void *private))
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_write_disk_set_user_lookup");
+
+ if (a->cleanup_uid != NULL && a->lookup_uid_data != NULL)
+ (a->cleanup_uid)(a->lookup_uid_data);
+
+ a->lookup_uid = lookup_uid;
+ a->cleanup_uid = cleanup_uid;
+ a->lookup_uid_data = private_data;
+ return (ARCHIVE_OK);
+}
+
+int64_t
+archive_write_disk_gid(struct archive *_a, const char *name, int64_t id)
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_write_disk_gid");
+ if (a->lookup_gid)
+ return (a->lookup_gid)(a->lookup_gid_data, name, id);
+ return (id);
+}
+
+int64_t
+archive_write_disk_uid(struct archive *_a, const char *name, int64_t id)
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_write_disk_uid");
+ if (a->lookup_uid)
+ return (a->lookup_uid)(a->lookup_uid_data, name, id);
+ return (id);
+}
+
+/*
+ * Create a new archive_write_disk object and initialize it with global state.
+ */
+struct archive *
+archive_write_disk_new(void)
+{
+ struct archive_write_disk *a;
+
+ a = (struct archive_write_disk *)malloc(sizeof(*a));
+ if (a == NULL)
+ return (NULL);
+ memset(a, 0, sizeof(*a));
+ a->archive.magic = ARCHIVE_WRITE_DISK_MAGIC;
+ /* We're ready to write a header immediately. */
+ a->archive.state = ARCHIVE_STATE_HEADER;
+ a->archive.vtable = archive_write_disk_vtable();
+ a->start_time = time(NULL);
+ /* Query and restore the umask. */
+ umask(a->user_umask = umask(0));
+ if (archive_wstring_ensure(&a->path_safe, 512) == NULL) {
+ free(a);
+ return (NULL);
+ }
+ return (&a->archive);
+}
+
+static int
+disk_unlink(wchar_t *path)
+{
+ wchar_t *fullname;
+ int r;
+
+ r = _wunlink(path);
+ if (r != 0 && GetLastError() == ERROR_INVALID_NAME) {
+ fullname = __la_win_permissive_name_w(path);
+ r = _wunlink(fullname);
+ free(fullname);
+ }
+ return (r);
+}
+
+static int
+disk_rmdir(wchar_t *path)
+{
+ wchar_t *fullname;
+ int r;
+
+ r = _wrmdir(path);
+ if (r != 0 && GetLastError() == ERROR_INVALID_NAME) {
+ fullname = __la_win_permissive_name_w(path);
+ r = _wrmdir(fullname);
+ free(fullname);
+ }
+ return (r);
+}
+
+/*
+ * The main restore function.
+ */
+static int
+restore_entry(struct archive_write_disk *a)
+{
+ int ret = ARCHIVE_OK, en;
+
+ if (a->flags & ARCHIVE_EXTRACT_UNLINK && !S_ISDIR(a->mode)) {
+ /*
+ * TODO: Fix this. Apparently, there are platforms
+ * that still allow root to hose the entire filesystem
+ * by unlinking a dir. The S_ISDIR() test above
+ * prevents us from using unlink() here if the new
+ * object is a dir, but that doesn't mean the old
+ * object isn't a dir.
+ */
+ if (disk_unlink(a->name) == 0) {
+ /* We removed it, reset cached stat. */
+ a->pst = NULL;
+ } else if (errno == ENOENT) {
+ /* File didn't exist, that's just as good. */
+ } else if (disk_rmdir(a->name) == 0) {
+ /* It was a dir, but now it's gone. */
+ a->pst = NULL;
+ } else {
+ /* We tried, but couldn't get rid of it. */
+ archive_set_error(&a->archive, errno,
+ "Could not unlink");
+ return(ARCHIVE_FAILED);
+ }
+ }
+
+ /* Try creating it first; if this fails, we'll try to recover. */
+ en = create_filesystem_object(a);
+
+ if ((en == ENOTDIR || en == ENOENT)
+ && !(a->flags & ARCHIVE_EXTRACT_NO_AUTODIR)) {
+ wchar_t *full;
+ /* If the parent dir doesn't exist, try creating it. */
+ create_parent_dir(a, a->name);
+ /* Now try to create the object again. */
+ full = __la_win_permissive_name_w(a->name);
+ if (full == NULL) {
+ en = EINVAL;
+ } else {
+ /* Remove multiple directories such as "a/../b../c" */
+ archive_wstrcpy(&(a->_name_data), full);
+ a->name = a->_name_data.s;
+ free(full);
+ en = create_filesystem_object(a);
+ }
+ }
+
+ if ((en == EISDIR || en == EEXIST)
+ && (a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE)) {
+ /* If we're not overwriting, we're done. */
+ archive_entry_unset_size(a->entry);
+ return (ARCHIVE_OK);
+ }
+
+ /*
+ * Some platforms return EISDIR if you call
+ * open(O_WRONLY | O_EXCL | O_CREAT) on a directory, some
+ * return EEXIST. POSIX is ambiguous, requiring EISDIR
+ * for open(O_WRONLY) on a dir and EEXIST for open(O_EXCL | O_CREAT)
+ * on an existing item.
+ */
+ if (en == EISDIR) {
+ /* A dir is in the way of a non-dir, rmdir it. */
+ if (disk_rmdir(a->name) != 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't remove already-existing dir");
+ return (ARCHIVE_FAILED);
+ }
+ a->pst = NULL;
+ /* Try again. */
+ en = create_filesystem_object(a);
+ } else if (en == EEXIST) {
+ mode_t st_mode;
+ /*
+ * We know something is in the way, but we don't know what;
+ * we need to find out before we go any further.
+ */
+ int r = 0;
+ /*
+ * The SECURE_SYMLINK logic has already removed a
+ * symlink to a dir if the client wants that. So
+ * follow the symlink if we're creating a dir.
+ */
+ if (S_ISDIR(a->mode))
+ r = file_information(a, a->name, &a->st, &st_mode, 0);
+ /*
+ * If it's not a dir (or it's a broken symlink),
+ * then don't follow it.
+ */
+ if (r != 0 || !S_ISDIR(a->mode))
+ r = file_information(a, a->name, &a->st, &st_mode, 1);
+ if (r != 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't stat existing object");
+ return (ARCHIVE_FAILED);
+ }
+
+ /*
+ * NO_OVERWRITE_NEWER doesn't apply to directories.
+ */
+ if ((a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER)
+ && !S_ISDIR(st_mode)) {
+ if (!older(&(a->st), a->entry)) {
+ archive_entry_unset_size(a->entry);
+ return (ARCHIVE_OK);
+ }
+ }
+
+ /* If it's our archive, we're done. */
+ if (a->skip_file_set &&
+ bhfi_dev(&a->st) == a->skip_file_dev &&
+ bhfi_ino(&a->st) == a->skip_file_ino) {
+ archive_set_error(&a->archive, 0, "Refusing to overwrite archive");
+ return (ARCHIVE_FAILED);
+ }
+
+ if (!S_ISDIR(st_mode)) {
+ /* A non-dir is in the way, unlink it. */
+ if (disk_unlink(a->name) != 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't unlink already-existing object");
+ return (ARCHIVE_FAILED);
+ }
+ a->pst = NULL;
+ /* Try again. */
+ en = create_filesystem_object(a);
+ } else if (!S_ISDIR(a->mode)) {
+ /* A dir is in the way of a non-dir, rmdir it. */
+ if (disk_rmdir(a->name) != 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't remove already-existing dir");
+ return (ARCHIVE_FAILED);
+ }
+ /* Try again. */
+ en = create_filesystem_object(a);
+ } else {
+ /*
+ * There's a dir in the way of a dir. Don't
+ * waste time with rmdir()/mkdir(), just fix
+ * up the permissions on the existing dir.
+ * Note that we don't change perms on existing
+ * dirs unless _EXTRACT_PERM is specified.
+ */
+ if ((a->mode != st_mode)
+ && (a->todo & TODO_MODE_FORCE))
+ a->deferred |= (a->todo & TODO_MODE);
+ /* Ownership doesn't need deferred fixup. */
+ en = 0; /* Forget the EEXIST. */
+ }
+ }
+
+ if (en) {
+ /* Everything failed; give up here. */
+ archive_set_error(&a->archive, en, "Can't create '%s'",
+ a->name);
+ return (ARCHIVE_FAILED);
+ }
+
+ a->pst = NULL; /* Cached stat data no longer valid. */
+ return (ret);
+}
+
+/*
+ * Returns 0 if creation succeeds, or else returns errno value from
+ * the failed system call. Note: This function should only ever perform
+ * a single system call.
+ */
+static int
+create_filesystem_object(struct archive_write_disk *a)
+{
+ /* Create the entry. */
+ const wchar_t *linkname;
+ wchar_t *fullname;
+ mode_t final_mode, mode;
+ int r;
+
+ /* We identify hard/symlinks according to the link names. */
+ /* Since link(2) and symlink(2) don't handle modes, we're done here. */
+ linkname = archive_entry_hardlink_w(a->entry);
+ if (linkname != NULL) {
+ wchar_t *linkfull, *namefull;
+
+ linkfull = __la_win_permissive_name_w(linkname);
+ namefull = __la_win_permissive_name_w(a->name);
+ if (linkfull == NULL || namefull == NULL) {
+ errno = EINVAL;
+ r = -1;
+ } else {
+ r = la_CreateHardLinkW(namefull, linkfull);
+ if (r == 0) {
+ la_dosmaperr(GetLastError());
+ r = errno;
+ } else
+ r = 0;
+ }
+ /*
+ * New cpio and pax formats allow hardlink entries
+ * to carry data, so we may have to open the file
+ * for hardlink entries.
+ *
+ * If the hardlink was successfully created and
+ * the archive doesn't have carry data for it,
+ * consider it to be non-authoritive for meta data.
+ * This is consistent with GNU tar and BSD pax.
+ * If the hardlink does carry data, let the last
+ * archive entry decide ownership.
+ */
+ if (r == 0 && a->filesize <= 0) {
+ a->todo = 0;
+ a->deferred = 0;
+ } else if (r == 0 && a->filesize > 0) {
+ a->fh = CreateFileW(namefull, GENERIC_WRITE, 0, NULL,
+ TRUNCATE_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (a->fh == INVALID_HANDLE_VALUE) {
+ la_dosmaperr(GetLastError());
+ r = errno;
+ }
+ }
+ free(linkfull);
+ free(namefull);
+ return (r);
+ }
+ linkname = archive_entry_symlink_w(a->entry);
+ if (linkname != NULL) {
+#if HAVE_SYMLINK
+ return symlink(linkname, a->name) ? errno : 0;
+#else
+ return (EPERM);
+#endif
+ }
+
+ /*
+ * The remaining system calls all set permissions, so let's
+ * try to take advantage of that to avoid an extra chmod()
+ * call. (Recall that umask is set to zero right now!)
+ */
+
+ /* Mode we want for the final restored object (w/o file type bits). */
+ final_mode = a->mode & 07777;
+ /*
+ * The mode that will actually be restored in this step. Note
+ * that SUID, SGID, etc, require additional work to ensure
+ * security, so we never restore them at this point.
+ */
+ mode = final_mode & 0777 & a->user_umask;
+
+ switch (a->mode & AE_IFMT) {
+ default:
+ /* POSIX requires that we fall through here. */
+ /* FALLTHROUGH */
+ case AE_IFREG:
+ fullname = a->name;
+ /* O_WRONLY | O_CREAT | O_EXCL */
+ a->fh = CreateFileW(fullname, GENERIC_WRITE, 0, NULL,
+ CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (a->fh == INVALID_HANDLE_VALUE &&
+ GetLastError() == ERROR_INVALID_NAME &&
+ fullname == a->name) {
+ fullname = __la_win_permissive_name_w(a->name);
+ a->fh = CreateFileW(fullname, GENERIC_WRITE, 0, NULL,
+ CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
+ }
+ if (a->fh == INVALID_HANDLE_VALUE) {
+ if (GetLastError() == ERROR_ACCESS_DENIED) {
+ DWORD attr;
+ /* Simulate an errno of POSIX system. */
+ attr = GetFileAttributesW(fullname);
+ if (attr == (DWORD)-1)
+ la_dosmaperr(GetLastError());
+ else if (attr & FILE_ATTRIBUTE_DIRECTORY)
+ errno = EISDIR;
+ else
+ errno = EACCES;
+ } else
+ la_dosmaperr(GetLastError());
+ r = 1;
+ } else
+ r = 0;
+ if (fullname != a->name)
+ free(fullname);
+ break;
+ case AE_IFCHR:
+ case AE_IFBLK:
+ /* TODO: Find a better way to warn about our inability
+ * to restore a block device node. */
+ return (EINVAL);
+ case AE_IFDIR:
+ mode = (mode | MINIMUM_DIR_MODE) & MAXIMUM_DIR_MODE;
+ fullname = a->name;
+ r = CreateDirectoryW(fullname, NULL);
+ if (r == 0 && GetLastError() == ERROR_INVALID_NAME &&
+ fullname == a->name) {
+ fullname = __la_win_permissive_name_w(a->name);
+ r = CreateDirectoryW(fullname, NULL);
+ }
+ if (r != 0) {
+ r = 0;
+ /* Defer setting dir times. */
+ a->deferred |= (a->todo & TODO_TIMES);
+ a->todo &= ~TODO_TIMES;
+ /* Never use an immediate chmod(). */
+ /* We can't avoid the chmod() entirely if EXTRACT_PERM
+ * because of SysV SGID inheritance. */
+ if ((mode != final_mode)
+ || (a->flags & ARCHIVE_EXTRACT_PERM))
+ a->deferred |= (a->todo & TODO_MODE);
+ a->todo &= ~TODO_MODE;
+ } else {
+ la_dosmaperr(GetLastError());
+ r = -1;
+ }
+ if (fullname != a->name)
+ free(fullname);
+ break;
+ case AE_IFIFO:
+ /* TODO: Find a better way to warn about our inability
+ * to restore a fifo. */
+ return (EINVAL);
+ }
+
+ /* All the system calls above set errno on failure. */
+ if (r)
+ return (errno);
+
+ /* If we managed to set the final mode, we've avoided a chmod(). */
+ if (mode == final_mode)
+ a->todo &= ~TODO_MODE;
+ return (0);
+}
+
+/*
+ * Cleanup function for archive_extract. Mostly, this involves processing
+ * the fixup list, which is used to address a number of problems:
+ * * Dir permissions might prevent us from restoring a file in that
+ * dir, so we restore the dir with minimum 0700 permissions first,
+ * then correct the mode at the end.
+ * * Similarly, the act of restoring a file touches the directory
+ * and changes the timestamp on the dir, so we have to touch-up dir
+ * timestamps at the end as well.
+ * * Some file flags can interfere with the restore by, for example,
+ * preventing the creation of hardlinks to those files.
+ * * Mac OS extended metadata includes ACLs, so must be deferred on dirs.
+ *
+ * Note that tar/cpio do not require that archives be in a particular
+ * order; there is no way to know when the last file has been restored
+ * within a directory, so there's no way to optimize the memory usage
+ * here by fixing up the directory any earlier than the
+ * end-of-archive.
+ *
+ * XXX TODO: Directory ACLs should be restored here, for the same
+ * reason we set directory perms here. XXX
+ */
+static int
+_archive_write_disk_close(struct archive *_a)
+{
+ struct archive_write_disk *a = (struct archive_write_disk *)_a;
+ struct fixup_entry *next, *p;
+ int ret;
+
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
+ "archive_write_disk_close");
+ ret = _archive_write_disk_finish_entry(&a->archive);
+
+ /* Sort dir list so directories are fixed up in depth-first order. */
+ p = sort_dir_list(a->fixup_list);
+
+ while (p != NULL) {
+ a->pst = NULL; /* Mark stat cache as out-of-date. */
+ if (p->fixup & TODO_TIMES) {
+ set_times(a, INVALID_HANDLE_VALUE, p->mode, p->name,
+ p->atime, p->atime_nanos,
+ p->birthtime, p->birthtime_nanos,
+ p->mtime, p->mtime_nanos,
+ p->ctime, p->ctime_nanos);
+ }
+ if (p->fixup & TODO_MODE_BASE)
+ la_chmod(p->name, p->mode);
+ if (p->fixup & TODO_ACLS)
+ set_acls(a, INVALID_HANDLE_VALUE, p->name, &p->acl);
+ next = p->next;
+ archive_acl_clear(&p->acl);
+ free(p->name);
+ free(p);
+ p = next;
+ }
+ a->fixup_list = NULL;
+ return (ret);
+}
+
+static int
+_archive_write_disk_free(struct archive *_a)
+{
+ struct archive_write_disk *a;
+ int ret;
+ if (_a == NULL)
+ return (ARCHIVE_OK);
+ archive_check_magic(_a, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_write_disk_free");
+ a = (struct archive_write_disk *)_a;
+ ret = _archive_write_disk_close(&a->archive);
+ archive_write_disk_set_group_lookup(&a->archive, NULL, NULL, NULL);
+ archive_write_disk_set_user_lookup(&a->archive, NULL, NULL, NULL);
+ if (a->entry)
+ archive_entry_free(a->entry);
+ archive_wstring_free(&a->_name_data);
+ archive_string_free(&a->archive.error_string);
+ archive_wstring_free(&a->path_safe);
+ a->archive.magic = 0;
+ __archive_clean(&a->archive);
+ free(a);
+ return (ret);
+}
+
+/*
+ * Simple O(n log n) merge sort to order the fixup list. In
+ * particular, we want to restore dir timestamps depth-first.
+ */
+static struct fixup_entry *
+sort_dir_list(struct fixup_entry *p)
+{
+ struct fixup_entry *a, *b, *t;
+
+ if (p == NULL)
+ return (NULL);
+ /* A one-item list is already sorted. */
+ if (p->next == NULL)
+ return (p);
+
+ /* Step 1: split the list. */
+ t = p;
+ a = p->next->next;
+ while (a != NULL) {
+ /* Step a twice, t once. */
+ a = a->next;
+ if (a != NULL)
+ a = a->next;
+ t = t->next;
+ }
+ /* Now, t is at the mid-point, so break the list here. */
+ b = t->next;
+ t->next = NULL;
+ a = p;
+
+ /* Step 2: Recursively sort the two sub-lists. */
+ a = sort_dir_list(a);
+ b = sort_dir_list(b);
+
+ /* Step 3: Merge the returned lists. */
+ /* Pick the first element for the merged list. */
+ if (wcscmp(a->name, b->name) > 0) {
+ t = p = a;
+ a = a->next;
+ } else {
+ t = p = b;
+ b = b->next;
+ }
+
+ /* Always put the later element on the list first. */
+ while (a != NULL && b != NULL) {
+ if (wcscmp(a->name, b->name) > 0) {
+ t->next = a;
+ a = a->next;
+ } else {
+ t->next = b;
+ b = b->next;
+ }
+ t = t->next;
+ }
+
+ /* Only one list is non-empty, so just splice it on. */
+ if (a != NULL)
+ t->next = a;
+ if (b != NULL)
+ t->next = b;
+
+ return (p);
+}
+
+/*
+ * Returns a new, initialized fixup entry.
+ *
+ * TODO: Reduce the memory requirements for this list by using a tree
+ * structure rather than a simple list of names.
+ */
+static struct fixup_entry *
+new_fixup(struct archive_write_disk *a, const wchar_t *pathname)
+{
+ struct fixup_entry *fe;
+
+ fe = (struct fixup_entry *)calloc(1, sizeof(struct fixup_entry));
+ if (fe == NULL)
+ return (NULL);
+ fe->next = a->fixup_list;
+ a->fixup_list = fe;
+ fe->fixup = 0;
+ fe->name = _wcsdup(pathname);
+ return (fe);
+}
+
+/*
+ * Returns a fixup structure for the current entry.
+ */
+static struct fixup_entry *
+current_fixup(struct archive_write_disk *a, const wchar_t *pathname)
+{
+ if (a->current_fixup == NULL)
+ a->current_fixup = new_fixup(a, pathname);
+ return (a->current_fixup);
+}
+
+/* TODO: Make this work. */
+/*
+ * TODO: The deep-directory support bypasses this; disable deep directory
+ * support if we're doing symlink checks.
+ */
+/*
+ * TODO: Someday, integrate this with the deep dir support; they both
+ * scan the path and both can be optimized by comparing against other
+ * recent paths.
+ */
+/* TODO: Extend this to support symlinks on Windows Vista and later. */
+static int
+check_symlinks(struct archive_write_disk *a)
+{
+ wchar_t *pn, *p;
+ wchar_t c;
+ int r;
+ BY_HANDLE_FILE_INFORMATION st;
+ mode_t st_mode;
+
+ /*
+ * Guard against symlink tricks. Reject any archive entry whose
+ * destination would be altered by a symlink.
+ */
+ /* Whatever we checked last time doesn't need to be re-checked. */
+ pn = a->name;
+ p = a->path_safe.s;
+ while ((*pn != '\0') && (*p == *pn))
+ ++p, ++pn;
+ c = pn[0];
+ /* Keep going until we've checked the entire name. */
+ while (pn[0] != '\0' && (pn[0] != '\\' || pn[1] != '\0')) {
+ /* Skip the next path element. */
+ while (*pn != '\0' && *pn != '\\')
+ ++pn;
+ c = pn[0];
+ pn[0] = '\0';
+ /* Check that we haven't hit a symlink. */
+ r = file_information(a, a->name, &st, &st_mode, 1);
+ if (r != 0) {
+ /* We've hit a dir that doesn't exist; stop now. */
+ if (errno == ENOENT)
+ break;
+ } else if (S_ISLNK(st_mode)) {
+ if (c == '\0') {
+ /*
+ * Last element is symlink; remove it
+ * so we can overwrite it with the
+ * item being extracted.
+ */
+ if (disk_unlink(a->name)) {
+ archive_set_error(&a->archive, errno,
+ "Could not remove symlink %s",
+ a->name);
+ pn[0] = c;
+ return (ARCHIVE_FAILED);
+ }
+ a->pst = NULL;
+ /*
+ * Even if we did remove it, a warning
+ * is in order. The warning is silly,
+ * though, if we're just replacing one
+ * symlink with another symlink.
+ */
+ if (!S_ISLNK(a->mode)) {
+ archive_set_error(&a->archive, 0,
+ "Removing symlink %s",
+ a->name);
+ }
+ /* Symlink gone. No more problem! */
+ pn[0] = c;
+ return (0);
+ } else if (a->flags & ARCHIVE_EXTRACT_UNLINK) {
+ /* User asked us to remove problems. */
+ if (disk_unlink(a->name) != 0) {
+ archive_set_error(&a->archive, 0,
+ "Cannot remove intervening symlink %s",
+ a->name);
+ pn[0] = c;
+ return (ARCHIVE_FAILED);
+ }
+ a->pst = NULL;
+ } else {
+ archive_set_error(&a->archive, 0,
+ "Cannot extract through symlink %s",
+ a->name);
+ pn[0] = c;
+ return (ARCHIVE_FAILED);
+ }
+ }
+ }
+ pn[0] = c;
+ /* We've checked and/or cleaned the whole path, so remember it. */
+ archive_wstrcpy(&a->path_safe, a->name);
+ return (ARCHIVE_OK);
+}
+
+static int
+guidword(wchar_t *p, int n)
+{
+ int i;
+
+ for (i = 0; i < n; i++) {
+ if ((*p >= L'0' && *p <= L'9') ||
+ (*p >= L'a' && *p <= L'f') ||
+ (*p >= L'A' && *p <= L'F'))
+ p++;
+ else
+ return (-1);
+ }
+ return (0);
+}
+
+/*
+ * 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.
+ */
+static int
+cleanup_pathname(struct archive_write_disk *a)
+{
+ wchar_t *dest, *src, *p, *top;
+ wchar_t separator = L'\0';
+
+ p = a->name;
+ if (*p == L'\0') {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Invalid empty pathname");
+ return (ARCHIVE_FAILED);
+ }
+
+ /* Replace '/' by '\' */
+ for (; *p != L'\0'; p++) {
+ if (*p == L'/')
+ *p = L'\\';
+ }
+ p = a->name;
+
+ /* Skip leading "\\.\" or "\\?\" or "\\?\UNC\" or
+ * "\\?\Volume{GUID}\"
+ * (absolute path prefixes used by Windows API) */
+ if (p[0] == L'\\' && p[1] == L'\\' &&
+ (p[2] == L'.' || p[2] == L'?') && p[3] == L'\\')
+ {
+ /* A path begin with "\\?\UNC\" */
+ if (p[2] == L'?' &&
+ (p[4] == L'U' || p[4] == L'u') &&
+ (p[5] == L'N' || p[5] == L'n') &&
+ (p[6] == L'C' || p[6] == L'c') &&
+ p[7] == L'\\')
+ p += 8;
+ /* A path begin with "\\?\Volume{GUID}\" */
+ else if (p[2] == L'?' &&
+ (p[4] == L'V' || p[4] == L'v') &&
+ (p[5] == L'O' || p[5] == L'o') &&
+ (p[6] == L'L' || p[6] == L'l') &&
+ (p[7] == L'U' || p[7] == L'u') &&
+ (p[8] == L'M' || p[8] == L'm') &&
+ (p[9] == L'E' || p[9] == L'e') &&
+ p[10] == L'{') {
+ if (guidword(p+11, 8) == 0 && p[19] == L'-' &&
+ guidword(p+20, 4) == 0 && p[24] == L'-' &&
+ guidword(p+25, 4) == 0 && p[29] == L'-' &&
+ guidword(p+30, 4) == 0 && p[34] == L'-' &&
+ guidword(p+35, 12) == 0 && p[47] == L'}' &&
+ p[48] == L'\\')
+ p += 49;
+ else
+ p += 4;
+ /* A path begin with "\\.\PhysicalDriveX" */
+ } else if (p[2] == L'.' &&
+ (p[4] == L'P' || p[4] == L'p') &&
+ (p[5] == L'H' || p[5] == L'h') &&
+ (p[6] == L'Y' || p[6] == L'y') &&
+ (p[7] == L'S' || p[7] == L's') &&
+ (p[8] == L'I' || p[8] == L'i') &&
+ (p[9] == L'C' || p[9] == L'c') &&
+ (p[9] == L'A' || p[9] == L'a') &&
+ (p[9] == L'L' || p[9] == L'l') &&
+ (p[9] == L'D' || p[9] == L'd') &&
+ (p[9] == L'R' || p[9] == L'r') &&
+ (p[9] == L'I' || p[9] == L'i') &&
+ (p[9] == L'V' || p[9] == L'v') &&
+ (p[9] == L'E' || p[9] == L'e') &&
+ (p[10] >= L'0' && p[10] <= L'9') &&
+ p[11] == L'\0') {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Path is a physical drive name");
+ return (ARCHIVE_FAILED);
+ } else
+ p += 4;
+ }
+
+ /* Skip leading drive letter from archives created
+ * on Windows. */
+ if (((p[0] >= L'a' && p[0] <= L'z') ||
+ (p[0] >= L'A' && p[0] <= L'Z')) &&
+ p[1] == L':') {
+ if (p[2] == L'\0') {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Path is a drive name");
+ return (ARCHIVE_FAILED);
+ }
+ if (p[2] == L'\\')
+ p += 2;
+ }
+
+ top = dest = src = p;
+ /* Rewrite the path name if its character is a unusable. */
+ for (; *p != L'\0'; p++) {
+ if (*p == L':' || *p == L'*' || *p == L'?' || *p == L'"' ||
+ *p == L'<' || *p == L'>' || *p == L'|')
+ *p = L'_';
+ }
+ /* Skip leading '\'. */
+ if (*src == L'\\')
+ separator = *src++;
+
+ /* Scan the pathname one element at a time. */
+ for (;;) {
+ /* src points to first char after '\' */
+ if (src[0] == L'\0') {
+ break;
+ } else if (src[0] == L'\\') {
+ /* Found '\\'('//'), ignore second one. */
+ src++;
+ continue;
+ } else if (src[0] == L'.') {
+ if (src[1] == L'\0') {
+ /* Ignore trailing '.' */
+ break;
+ } else if (src[1] == L'\\') {
+ /* Skip '.\'. */
+ src += 2;
+ continue;
+ } else if (src[1] == L'.') {
+ if (src[2] == L'\\' || src[2] == L'\0') {
+ /* Conditionally warn about '..' */
+ if (a->flags &
+ ARCHIVE_EXTRACT_SECURE_NODOTDOT) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Path contains '..'");
+ return (ARCHIVE_FAILED);
+ }
+ }
+ /*
+ * Note: Under no circumstances do we
+ * remove '..' elements. In
+ * particular, restoring
+ * '\foo\..\bar\' should create the
+ * 'foo' dir as a side-effect.
+ */
+ }
+ }
+
+ /* Copy current element, including leading '\'. */
+ if (separator)
+ *dest++ = L'\\';
+ while (*src != L'\0' && *src != L'\\') {
+ *dest++ = *src++;
+ }
+
+ if (*src == L'\0')
+ break;
+
+ /* Skip '\' separator. */
+ separator = *src++;
+ }
+ /*
+ * We've just copied zero or more path elements, not including the
+ * final '\'.
+ */
+ if (dest == top) {
+ /*
+ * Nothing got copied. The path must have been something
+ * like '.' or '\' or './' or '/././././/./'.
+ */
+ if (separator)
+ *dest++ = L'\\';
+ else
+ *dest++ = L'.';
+ }
+ /* Terminate the result. */
+ *dest = L'\0';
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Create the parent directory of the specified path, assuming path
+ * is already in mutable storage.
+ */
+static int
+create_parent_dir(struct archive_write_disk *a, wchar_t *path)
+{
+ wchar_t *slash;
+ int r;
+
+ /* Remove tail element to obtain parent name. */
+ slash = wcsrchr(path, L'\\');
+ if (slash == NULL)
+ return (ARCHIVE_OK);
+ *slash = L'\0';
+ r = create_dir(a, path);
+ *slash = L'\\';
+ return (r);
+}
+
+/*
+ * Create the specified dir, recursing to create parents as necessary.
+ *
+ * Returns ARCHIVE_OK if the path exists when we're done here.
+ * Otherwise, returns ARCHIVE_FAILED.
+ * Assumes path is in mutable storage; path is unchanged on exit.
+ */
+static int
+create_dir(struct archive_write_disk *a, wchar_t *path)
+{
+ BY_HANDLE_FILE_INFORMATION st;
+ struct fixup_entry *le;
+ wchar_t *slash, *base, *full;
+ mode_t mode_final, mode, st_mode;
+ int r;
+
+ /* Check for special names and just skip them. */
+ slash = wcsrchr(path, L'\\');
+ if (slash == NULL)
+ base = path;
+ else
+ base = slash + 1;
+
+ if (base[0] == L'\0' ||
+ (base[0] == L'.' && base[1] == L'\0') ||
+ (base[0] == L'.' && base[1] == L'.' && base[2] == L'\0')) {
+ /* Don't bother trying to create null path, '.', or '..'. */
+ if (slash != NULL) {
+ *slash = L'\0';
+ r = create_dir(a, path);
+ *slash = L'\\';
+ return (r);
+ }
+ return (ARCHIVE_OK);
+ }
+
+ /*
+ * Yes, this should be stat() and not lstat(). Using lstat()
+ * here loses the ability to extract through symlinks. Also note
+ * that this should not use the a->st cache.
+ */
+ if (file_information(a, path, &st, &st_mode, 0) == 0) {
+ if (S_ISDIR(st_mode))
+ return (ARCHIVE_OK);
+ if ((a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE)) {
+ archive_set_error(&a->archive, EEXIST,
+ "Can't create directory '%s'", path);
+ return (ARCHIVE_FAILED);
+ }
+ if (disk_unlink(path) != 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't create directory '%s': "
+ "Conflicting file cannot be removed",
+ path);
+ return (ARCHIVE_FAILED);
+ }
+ } else if (errno != ENOENT && errno != ENOTDIR) {
+ /* Stat failed? */
+ archive_set_error(&a->archive, errno, "Can't test directory '%s'", path);
+ return (ARCHIVE_FAILED);
+ } else if (slash != NULL) {
+ *slash = '\0';
+ r = create_dir(a, path);
+ *slash = '\\';
+ if (r != ARCHIVE_OK)
+ return (r);
+ }
+
+ /*
+ * Mode we want for the final restored directory. Per POSIX,
+ * implicitly-created dirs must be created obeying the umask.
+ * There's no mention whether this is different for privileged
+ * restores (which the rest of this code handles by pretending
+ * umask=0). I've chosen here to always obey the user's umask for
+ * implicit dirs, even if _EXTRACT_PERM was specified.
+ */
+ mode_final = DEFAULT_DIR_MODE & ~a->user_umask;
+ /* Mode we want on disk during the restore process. */
+ mode = mode_final;
+ mode |= MINIMUM_DIR_MODE;
+ mode &= MAXIMUM_DIR_MODE;
+ /*
+ * Apply __la_win_permissive_name_w to path in order to
+ * remove '../' path string.
+ */
+ full = __la_win_permissive_name_w(path);
+ if (full == NULL)
+ errno = EINVAL;
+ else if (CreateDirectoryW(full, NULL) != 0) {
+ if (mode != mode_final) {
+ le = new_fixup(a, path);
+ le->fixup |=TODO_MODE_BASE;
+ le->mode = mode_final;
+ }
+ free(full);
+ return (ARCHIVE_OK);
+ } else {
+ la_dosmaperr(GetLastError());
+ }
+ free(full);
+
+ /*
+ * Without the following check, a/b/../b/c/d fails at the
+ * second visit to 'b', so 'd' can't be created. Note that we
+ * don't add it to the fixup list here, as it's already been
+ * added.
+ */
+ if (file_information(a, path, &st, &st_mode, 0) == 0 && S_ISDIR(st_mode))
+ return (ARCHIVE_OK);
+
+ archive_set_error(&a->archive, errno, "Failed to create dir '%s'",
+ path);
+ return (ARCHIVE_FAILED);
+}
+
+/*
+ * Note: Although we can skip setting the user id if the desired user
+ * id matches the current user, we cannot skip setting the group, as
+ * many systems set the gid based on the containing directory. So
+ * we have to perform a chown syscall if we want to set the SGID
+ * bit. (The alternative is to stat() and then possibly chown(); it's
+ * more efficient to skip the stat() and just always chown().) Note
+ * that a successful chown() here clears the TODO_SGID_CHECK bit, which
+ * allows set_mode to skip the stat() check for the GID.
+ */
+static int
+set_ownership(struct archive_write_disk *a)
+{
+/* unfortunately, on win32 there is no 'root' user with uid 0,
+ so we just have to try the chown and see if it works */
+
+ /* If we know we can't change it, don't bother trying. */
+ if (a->user_uid != 0 && a->user_uid != a->uid) {
+ archive_set_error(&a->archive, errno,
+ "Can't set UID=%jd", (intmax_t)a->uid);
+ return (ARCHIVE_WARN);
+ }
+
+ archive_set_error(&a->archive, errno,
+ "Can't set user=%jd/group=%jd for %s",
+ (intmax_t)a->uid, (intmax_t)a->gid, a->name);
+ return (ARCHIVE_WARN);
+}
+
+static int
+set_times(struct archive_write_disk *a,
+ HANDLE h, int mode, const wchar_t *name,
+ time_t atime, long atime_nanos,
+ time_t birthtime, long birthtime_nanos,
+ time_t mtime, long mtime_nanos,
+ time_t ctime, long ctime_nanos)
+{
+#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
+#define WINTIME(sec, nsec) ((Int32x32To64(sec, 10000000) + EPOC_TIME)\
+ + (((nsec)/1000)*10))
+
+ HANDLE hw = 0;
+ ULARGE_INTEGER wintm;
+ FILETIME *pfbtime;
+ FILETIME fatime, fbtime, fmtime;
+
+ (void)ctime; /* UNUSED */
+ (void)ctime_nanos; /* UNUSED */
+
+ if (h != INVALID_HANDLE_VALUE) {
+ hw = NULL;
+ } else {
+ wchar_t *ws;
+
+ if (S_ISLNK(mode))
+ return (ARCHIVE_OK);
+ ws = __la_win_permissive_name_w(name);
+ if (ws == NULL)
+ goto settimes_failed;
+ hw = CreateFileW(ws, FILE_WRITE_ATTRIBUTES,
+ 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ free(ws);
+ if (hw == INVALID_HANDLE_VALUE)
+ goto settimes_failed;
+ h = hw;
+ }
+
+ wintm.QuadPart = WINTIME(atime, atime_nanos);
+ fatime.dwLowDateTime = wintm.LowPart;
+ fatime.dwHighDateTime = wintm.HighPart;
+ wintm.QuadPart = WINTIME(mtime, mtime_nanos);
+ fmtime.dwLowDateTime = wintm.LowPart;
+ fmtime.dwHighDateTime = wintm.HighPart;
+ /*
+ * SetFileTime() supports birthtime.
+ */
+ if (birthtime > 0 || birthtime_nanos > 0) {
+ wintm.QuadPart = WINTIME(birthtime, birthtime_nanos);
+ fbtime.dwLowDateTime = wintm.LowPart;
+ fbtime.dwHighDateTime = wintm.HighPart;
+ pfbtime = &fbtime;
+ } else
+ pfbtime = NULL;
+ if (SetFileTime(h, pfbtime, &fatime, &fmtime) == 0)
+ goto settimes_failed;
+ CloseHandle(hw);
+ return (ARCHIVE_OK);
+
+settimes_failed:
+ CloseHandle(hw);
+ archive_set_error(&a->archive, EINVAL, "Can't restore time");
+ return (ARCHIVE_WARN);
+}
+
+static int
+set_times_from_entry(struct archive_write_disk *a)
+{
+ time_t atime, birthtime, mtime, ctime;
+ long atime_nsec, birthtime_nsec, mtime_nsec, ctime_nsec;
+
+ /* Suitable defaults. */
+ atime = birthtime = mtime = ctime = a->start_time;
+ atime_nsec = birthtime_nsec = mtime_nsec = ctime_nsec = 0;
+
+ /* If no time was provided, we're done. */
+ if (!archive_entry_atime_is_set(a->entry)
+ && !archive_entry_birthtime_is_set(a->entry)
+ && !archive_entry_mtime_is_set(a->entry))
+ return (ARCHIVE_OK);
+
+ if (archive_entry_atime_is_set(a->entry)) {
+ atime = archive_entry_atime(a->entry);
+ atime_nsec = archive_entry_atime_nsec(a->entry);
+ }
+ if (archive_entry_birthtime_is_set(a->entry)) {
+ birthtime = archive_entry_birthtime(a->entry);
+ birthtime_nsec = archive_entry_birthtime_nsec(a->entry);
+ }
+ if (archive_entry_mtime_is_set(a->entry)) {
+ mtime = archive_entry_mtime(a->entry);
+ mtime_nsec = archive_entry_mtime_nsec(a->entry);
+ }
+ if (archive_entry_ctime_is_set(a->entry)) {
+ ctime = archive_entry_ctime(a->entry);
+ ctime_nsec = archive_entry_ctime_nsec(a->entry);
+ }
+
+ return set_times(a, a->fh, a->mode, a->name,
+ atime, atime_nsec,
+ birthtime, birthtime_nsec,
+ mtime, mtime_nsec,
+ ctime, ctime_nsec);
+}
+
+static int
+set_mode(struct archive_write_disk *a, int mode)
+{
+ int r = ARCHIVE_OK;
+ mode &= 07777; /* Strip off file type bits. */
+
+ if (a->todo & TODO_SGID_CHECK) {
+ /*
+ * If we don't know the GID is right, we must stat()
+ * to verify it. We can't just check the GID of this
+ * process, since systems sometimes set GID from
+ * the enclosing dir or based on ACLs.
+ */
+ if ((r = lazy_stat(a)) != ARCHIVE_OK)
+ return (r);
+ if (0 != a->gid) {
+ mode &= ~ S_ISGID;
+ }
+ /* While we're here, double-check the UID. */
+ if (0 != a->uid
+ && (a->todo & TODO_SUID)) {
+ mode &= ~ S_ISUID;
+ }
+ a->todo &= ~TODO_SGID_CHECK;
+ a->todo &= ~TODO_SUID_CHECK;
+ } else if (a->todo & TODO_SUID_CHECK) {
+ /*
+ * If we don't know the UID is right, we can just check
+ * the user, since all systems set the file UID from
+ * the process UID.
+ */
+ if (a->user_uid != a->uid) {
+ mode &= ~ S_ISUID;
+ }
+ a->todo &= ~TODO_SUID_CHECK;
+ }
+
+ if (S_ISLNK(a->mode)) {
+#ifdef HAVE_LCHMOD
+ /*
+ * If this is a symlink, use lchmod(). If the
+ * platform doesn't support lchmod(), just skip it. A
+ * platform that doesn't provide a way to set
+ * permissions on symlinks probably ignores
+ * permissions on symlinks, so a failure here has no
+ * 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;
+ }
+#endif
+ } else if (!S_ISDIR(a->mode)) {
+ /*
+ * If it's not a symlink and not a dir, then use
+ * fchmod() or chmod(), depending on whether we have
+ * an fd. Dirs get their perms set during the
+ * post-extract fixup, which is handled elsewhere.
+ */
+#ifdef HAVE_FCHMOD
+ if (a->fd >= 0) {
+ if (fchmod(a->fd, mode) != 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't set permissions to 0%o", (int)mode);
+ r = ARCHIVE_WARN;
+ }
+ } else
+#endif
+ /* If this platform lacks fchmod(), then
+ * we'll just use chmod(). */
+ if (la_chmod(a->name, mode) != 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't set permissions to 0%o", (int)mode);
+ r = ARCHIVE_WARN;
+ }
+ }
+ return (r);
+}
+
+static int
+set_fflags(struct archive_write_disk *a)
+{
+ (void)a; /* UNUSED */
+ return (ARCHIVE_OK);
+}
+
+/* Default empty function body to satisfy mainline code. */
+static int
+set_acls(struct archive_write_disk *a, HANDLE h, const wchar_t *name,
+ struct archive_acl *acl)
+{
+ (void)a; /* UNUSED */
+ (void)h; /* UNUSED */
+ (void)name; /* UNUSED */
+ (void)acl; /* UNUSED */
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Restore extended attributes - stub implementation for unsupported systems
+ */
+static int
+set_xattrs(struct archive_write_disk *a)
+{
+ static int warning_done = 0;
+
+ /* If there aren't any extended attributes, then it's okay not
+ * to extract them, otherwise, issue a single warning. */
+ if (archive_entry_xattr_count(a->entry) != 0 && !warning_done) {
+ warning_done = 1;
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Cannot restore extended attributes on this system");
+ return (ARCHIVE_WARN);
+ }
+ /* Warning was already emitted; suppress further warnings. */
+ return (ARCHIVE_OK);
+}
+
+static void
+fileTimeToUtc(const FILETIME *filetime, time_t *time, long *ns)
+{
+ ULARGE_INTEGER utc;
+
+ utc.HighPart = filetime->dwHighDateTime;
+ utc.LowPart = filetime->dwLowDateTime;
+ if (utc.QuadPart >= EPOC_TIME) {
+ utc.QuadPart -= EPOC_TIME;
+ /* milli seconds base */
+ *time = (time_t)(utc.QuadPart / 10000000);
+ /* nano seconds base */
+ *ns = (long)(utc.QuadPart % 10000000) * 100;
+ } else {
+ *time = 0;
+ *ns = 0;
+ }
+}
+/*
+ * Test if file on disk is older than entry.
+ */
+static int
+older(BY_HANDLE_FILE_INFORMATION *st, struct archive_entry *entry)
+{
+ time_t sec;
+ long nsec;
+
+ fileTimeToUtc(&st->ftLastWriteTime, &sec, &nsec);
+ /* First, test the seconds and return if we have a definite answer. */
+ /* Definitely older. */
+ if (sec < archive_entry_mtime(entry))
+ return (1);
+ /* Definitely younger. */
+ if (sec > archive_entry_mtime(entry))
+ return (0);
+ if (nsec < archive_entry_mtime_nsec(entry))
+ return (1);
+ /* Same age or newer, so not older. */
+ return (0);
+}
+
+#endif /* _WIN32 && !__CYGWIN__ */
+
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_filter.3 b/Utilities/cmlibarchive/libarchive/archive_write_filter.3
new file mode 100644
index 000000000..00438d405
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_filter.3
@@ -0,0 +1,98 @@
+.\" Copyright (c) 2003-2011 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 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 March 23, 2011
+.Dt ARCHIVE_WRITE_FILTER 3
+.Os
+.Sh NAME
+.Nm archive_write_add_filter_bzip2 ,
+.Nm archive_write_add_filter_compress ,
+.Nm archive_write_add_filter_gzip ,
+.Nm archive_write_add_filter_lzip ,
+.Nm archive_write_add_filter_lzma ,
+.Nm archive_write_add_filter_none ,
+.Nm archive_write_add_filter_program ,
+.Nm archive_write_add_filter_xz
+.Sh SYNOPSIS
+.In archive.h
+.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_lzip "struct archive *"
+.Ft int
+.Fn archive_write_add_filter_lzma "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_xz "struct archive *"
+.Sh DESCRIPTION
+.Bl -tag -width indent
+.It Xo
+.Fn archive_write_add_filter_bzip2 ,
+.Fn archive_write_add_filter_compress ,
+.Fn archive_write_add_filter_gzip ,
+.Fn archive_write_add_filter_lzip ,
+.Fn archive_write_add_filter_lzma ,
+.Fn archive_write_add_filter_xz ,
+.Xc
+The resulting archive will be compressed as specified.
+Note that the compressed output is always properly blocked.
+.It Fn archive_write_add_filter_none
+This is never necessary.
+It is provided only for backwards compatibility.
+.It Fn archive_write_add_filter_program
+The archive will be fed into the specified compression program.
+The output of that program is blocked and written to the client
+write callbacks.
+.El
+.Sh RETURN VALUES
+These functions return
+.Cm ARCHIVE_OK
+on success, or
+.Cm ARCHIVE_FATAL .
+.\"
+.Sh ERRORS
+Detailed error codes and textual descriptions are available from the
+.Fn archive_errno
+and
+.Fn archive_error_string
+functions.
+.\"
+.Sh SEE ALSO
+.Xr tar 1 ,
+.Xr libarchive 3 ,
+.Xr archive_write 3 ,
+.Xr archive_write_format 3 ,
+.Xr archive_write_set_options 3 ,
+.Xr cpio 5 ,
+.Xr mtree 5 ,
+.Xr tar 5
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_finish_entry.3 b/Utilities/cmlibarchive/libarchive/archive_write_finish_entry.3
new file mode 100644
index 000000000..3add60129
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_finish_entry.3
@@ -0,0 +1,74 @@
+.\" Copyright (c) 2003-2011 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 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: head/lib/libarchive/archive_write.3 201110 2009-12-28 03:31:29Z kientzle $
+.\"
+.Dd March 23, 2011
+.Dt ARCHIVE_WRITE_FINISH_ENTRY 3
+.Os
+.Sh NAME
+.Nm archive_write_finish_entry
+.Nd functions for creating archives
+.Sh SYNOPSIS
+.In archive.h
+.Ft int
+.Fn archive_write_finish_entry "struct archive *"
+.Sh DESCRIPTION
+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
+and
+.Fn archive_write_close
+as needed.
+.\" .Sh EXAMPLE
+.Sh RETURN VALUES
+This function returns
+.Cm ARCHIVE_OK
+on success, or one of several non-zero
+error codes for errors.
+Specific error codes include:
+.Cm ARCHIVE_RETRY
+for operations that might succeed if retried,
+.Cm ARCHIVE_WARN
+for unusual conditions that do not prevent further operations, and
+.Cm ARCHIVE_FATAL
+for serious errors that make remaining operations impossible.
+.\"
+.Sh ERRORS
+Detailed error codes and textual descriptions are available from the
+.Fn archive_errno
+and
+.Fn archive_error_string
+functions.
+.\"
+.Sh SEE ALSO
+.Xr tar 1 ,
+.Xr libarchive 3 ,
+.Xr archive_write_data 3 ,
+.Xr archive_write_set_options 3 ,
+.Xr cpio 5 ,
+.Xr mtree 5 ,
+.Xr tar 5
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_format.3 b/Utilities/cmlibarchive/libarchive/archive_write_format.3
new file mode 100644
index 000000000..e12e7d865
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_format.3
@@ -0,0 +1,98 @@
+.\" Copyright (c) 2003-2011 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 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 March 23, 2011
+.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_shar ,
+.Nm archive_write_set_format_shar_dump ,
+.Nm archive_write_set_format_ustar
+.Nd functions for creating archives
+.Sh SYNOPSIS
+.In archive.h
+.Ft int
+.Fn archive_write_set_format_cpio "struct archive *"
+.Ft int
+.Fn archive_write_set_format_pax "struct archive *"
+.Ft int
+.Fn archive_write_set_format_pax_restricted "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 *"
+.Sh DESCRIPTION
+These functions set the format that will be used for the archive.
+.Pp
+The library can write
+POSIX octet-oriented cpio format archives,
+POSIX-standard
+.Dq pax interchange
+format archives,
+traditional
+.Dq shar
+archives,
+enhanced
+.Dq dump
+shar archives that store a variety of file attributes and handle binary files,
+and
+POSIX-standard
+.Dq ustar
+archives.
+The pax interchange format is a backwards-compatible tar format that
+adds key/value attributes to each entry and supports arbitrary
+filenames, linknames, uids, sizes, etc.
+.Dq Restricted pax interchange format
+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.
+.\"
+.Sh RETURN VALUES
+These functions return
+.Cm ARCHIVE_OK
+on success, or
+.Cm ARCHIVE_FATAL .
+.\"
+.Sh ERRORS
+Detailed error codes and textual descriptions are available from the
+.Fn archive_errno
+and
+.Fn archive_error_string
+functions.
+.\"
+.Sh SEE ALSO
+.Xr tar 1 ,
+.Xr libarchive 3 ,
+.Xr archive_write 3 ,
+.Xr archive_write_set_options 3 ,
+.Xr cpio 5 ,
+.Xr mtree 5 ,
+.Xr tar 5
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_free.3 b/Utilities/cmlibarchive/libarchive/archive_write_free.3
new file mode 100644
index 000000000..27efe18b0
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_free.3
@@ -0,0 +1,81 @@
+.\" Copyright (c) 2003-2011 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 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 March 23, 2011
+.Dt ARCHIVE_WRITE_FREE 3
+.Os
+.Sh NAME
+.Nm archive_write_close ,
+.Nm archive_write_finish ,
+.Nm archive_write_free
+.Nd functions for creating archives
+.Sh SYNOPSIS
+.In archive.h
+.Ft int
+.Fn archive_write_close "struct archive *"
+.Ft int
+.Fn archive_write_finish "struct archive *"
+.Ft int
+.Fn archive_write_free "struct archive *"
+.Sh DESCRIPTION
+.Bl -tag -width indent
+.It Fn archive_write_close
+Complete the archive and invoke the close callback.
+.It Fn archive_write_finish
+This is a deprecated synonym for
+.Fn archive_write_free .
+.It Fn archive_write_free
+Invokes
+.Fn archive_write_close
+if necessary, then releases all resources.
+If you need detailed information about
+.Fn archive_write_close
+failures, you should be careful to call it separately, as
+you cannot obtain error information after
+.Fn archive_write_free
+returns.
+.El
+.\" .Sh EXAMPLE
+.Sh RETURN VALUES
+These functions return
+.Cm ARCHIVE_OK
+on success, or
+.Cm ARCHIVE_FATAL .
+.\"
+.Sh ERRORS
+Detailed error codes and textual descriptions are available from the
+.Fn archive_errno
+and
+.Fn archive_error_string
+functions.
+.\"
+.Sh SEE ALSO
+.Xr tar 1 ,
+.Xr libarchive 3 ,
+.Xr archive_write_set_options 3 ,
+.Xr cpio 5 ,
+.Xr mtree 5 ,
+.Xr tar 5
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_header.3 b/Utilities/cmlibarchive/libarchive/archive_write_header.3
new file mode 100644
index 000000000..423b38e46
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_header.3
@@ -0,0 +1,71 @@
+.\" Copyright (c) 2003-2011 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 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 March 23, 2011
+.Dt ARCHIVE_WRITE_HEADER 3
+.Os
+.Sh NAME
+.Nm archive_write_header
+.Nd functions for creating archives
+.Sh SYNOPSIS
+.In archive.h
+.Ft int
+.Fn archive_write_header "struct archive *" "struct archive_entry *"
+.Sh DESCRIPTION
+Build and write a header using the data in the provided
+.Tn struct archive_entry
+structure.
+See
+.Xr archive_entry 3
+for information on creating and populating
+.Tn struct archive_entry
+objects.
+.\" .Sh EXAMPLE
+.Sh RETURN VALUES
+This function returns
+.Cm ARCHIVE_OK
+on success, or one of the following on error:
+.Cm ARCHIVE_RETRY
+for operations that might succeed if retried,
+.Cm ARCHIVE_WARN
+for unusual conditions that do not prevent further operations, and
+.Cm ARCHIVE_FATAL
+for serious errors that make remaining operations impossible.
+.\"
+.Sh ERRORS
+Detailed error codes and textual descriptions are available from the
+.Fn archive_errno
+and
+.Fn archive_error_string
+functions.
+.\"
+.Sh SEE ALSO
+.Xr tar 1 ,
+.Xr libarchive 3 ,
+.Xr archive_write_set_options 3 ,
+.Xr cpio 5 ,
+.Xr mtree 5 ,
+.Xr tar 5
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_new.3 b/Utilities/cmlibarchive/libarchive/archive_write_new.3
new file mode 100644
index 000000000..d626ccb73
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_new.3
@@ -0,0 +1,56 @@
+.\" Copyright (c) 2003-2011 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 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 March 23, 2011
+.Dt ARCHIVE_WRITE_NEW 3
+.Os
+.Sh NAME
+.Nm archive_write_new
+.Nd functions for creating archives
+.Sh SYNOPSIS
+.In archive.h
+.Ft struct archive *
+.Fn archive_write_new "void"
+.Sh DESCRIPTION
+Allocates and initializes a
+.Tn struct archive
+object suitable for writing a tar archive.
+.Dv NULL
+is returned on error.
+.Pp
+A complete description of the
+.Tn struct archive
+object can be found in the overview manual page for
+.Xr libarchive 3 .
+.\" .Sh ERRORS
+.Sh SEE ALSO
+.Xr tar 1 ,
+.Xr libarchive 3 ,
+.Xr archive_write 3 ,
+.Xr archive_write_set_options 3 ,
+.Xr cpio 5 ,
+.Xr mtree 5 ,
+.Xr tar 5
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_open.3 b/Utilities/cmlibarchive/libarchive/archive_write_open.3
new file mode 100644
index 000000000..0d12cb3b3
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_open.3
@@ -0,0 +1,233 @@
+.\" Copyright (c) 2003-2011 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 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: head/lib/libarchive/archive_write.3 201110 2009-12-28 03:31:29Z kientzle $
+.\"
+.Dd March 23, 2011
+.Dt ARCHIVE_WRITE 3
+.Os
+.Sh NAME
+.Nm archive_write_open ,
+.Nm archive_write_open_fd ,
+.Nm archive_write_open_FILE ,
+.Nm archive_write_open_filename ,
+.Nm archive_write_open_memory
+.Nd functions for creating archives
+.Sh SYNOPSIS
+.In archive.h
+.Ft int
+.Fo archive_write_open
+.Fa "struct archive *"
+.Fa "void *client_data"
+.Fa "archive_open_callback *"
+.Fa "archive_write_callback *"
+.Fa "archive_close_callback *"
+.Fc
+.Ft int
+.Fn archive_write_open_fd "struct archive *" "int fd"
+.Ft int
+.Fn archive_write_open_FILE "struct archive *" "FILE *file"
+.Ft int
+.Fn archive_write_open_filename "struct archive *" "const char *filename"
+.Ft int
+.Fo archive_write_open_memory
+.Fa "struct archive *"
+.Fa "void *buffer"
+.Fa "size_t bufferSize"
+.Fa "size_t *outUsed"
+.Fc
+.Sh DESCRIPTION
+.Bl -tag -width indent
+.It Fn archive_write_open
+Freeze the settings, open the archive, and prepare for writing entries.
+This is the most generic form of this function, which accepts
+pointers to three callback functions which will be invoked by
+the compression layer to write the constructed archive.
+.It Fn archive_write_open_fd
+A convenience form of
+.Fn archive_write_open
+that accepts a file descriptor.
+The
+.Fn archive_write_open_fd
+function is safe for use with tape drives or other
+block-oriented devices.
+.It Fn archive_write_open_FILE
+A convenience form of
+.Fn archive_write_open
+that accepts a
+.Ft "FILE *"
+pointer.
+Note that
+.Fn archive_write_open_FILE
+is not safe for writing to tape drives or other devices
+that require correct blocking.
+.It Fn archive_write_open_file
+A deprecated synonym for
+.Fn archive_write_open_filename .
+.It Fn archive_write_open_filename
+A convenience form of
+.Fn archive_write_open
+that accepts a filename.
+A NULL argument indicates that the output should be written to standard output;
+an argument of
+.Dq -
+will open a file with that name.
+If you have not invoked
+.Fn archive_write_set_bytes_in_last_block ,
+then
+.Fn archive_write_open_filename
+will adjust the last-block padding depending on the file:
+it will enable padding when writing to standard output or
+to a character or block device node, it will disable padding otherwise.
+You can override this by manually invoking
+.Fn archive_write_set_bytes_in_last_block
+before calling
+.Fn archive_write_open .
+The
+.Fn archive_write_open_filename
+function is safe for use with tape drives or other
+block-oriented devices.
+.It Fn archive_write_open_memory
+A convenience form of
+.Fn archive_write_open
+that accepts a pointer to a block of memory that will receive
+the archive.
+The final
+.Ft "size_t *"
+argument points to a variable that will be updated
+after each write to reflect how much of the buffer
+is currently in use.
+You should be careful to ensure that this variable
+remains allocated until after the archive is
+closed.
+.El
+More information about the
+.Va struct archive
+object and the overall design of the library can be found in the
+.Xr libarchive 3
+overview.
+.\"
+.Sh CLIENT CALLBACKS
+To use this library, you will need to define and register
+callback functions that will be invoked to write data to the
+resulting archive.
+These functions are registered by calling
+.Fn archive_write_open :
+.Bl -item -offset indent
+.It
+.Ft typedef int
+.Fn archive_open_callback "struct archive *" "void *client_data"
+.El
+.Pp
+The open callback is invoked by
+.Fn archive_write_open .
+It should return
+.Cm ARCHIVE_OK
+if the underlying file or data source is successfully
+opened.
+If the open fails, it should call
+.Fn archive_set_error
+to register an error code and message and return
+.Cm ARCHIVE_FATAL .
+.Bl -item -offset indent
+.It
+.Ft typedef ssize_t
+.Fo archive_write_callback
+.Fa "struct archive *"
+.Fa "void *client_data"
+.Fa "const void *buffer"
+.Fa "size_t length"
+.Fc
+.El
+.Pp
+The write callback is invoked whenever the library
+needs to write raw bytes to the archive.
+For correct blocking, each call to the write callback function
+should translate into a single
+.Xr write 2
+system call.
+This is especially critical when writing archives to tape drives.
+On success, the write callback should return the
+number of bytes actually written.
+On error, the callback should invoke
+.Fn archive_set_error
+to register an error code and message and return -1.
+.Bl -item -offset indent
+.It
+.Ft typedef int
+.Fn archive_close_callback "struct archive *" "void *client_data"
+.El
+.Pp
+The close callback is invoked by archive_close when
+the archive processing is complete.
+The callback should return
+.Cm ARCHIVE_OK
+on success.
+On failure, the callback should invoke
+.Fn archive_set_error
+to register an error code and message and
+return
+.Cm ARCHIVE_FATAL.
+.Pp
+Note that if the client-provided write callback function
+returns a non-zero value, that error will be propagated back to the caller
+through whatever API function resulted in that call, which
+may include
+.Fn archive_write_header ,
+.Fn archive_write_data ,
+.Fn archive_write_close ,
+.Fn archive_write_finish ,
+or
+.Fn archive_write_free .
+The client callback can call
+.Fn archive_set_error
+to provide values that can then be retrieved by
+.Fn archive_errno
+and
+.Fn archive_error_string .
+.\" .Sh EXAMPLE
+.Sh RETURN VALUES
+These functions return
+.Cm ARCHIVE_OK
+on success, or
+.Cm ARCHIVE_FATAL .
+.\"
+.Sh ERRORS
+Detailed error codes and textual descriptions are available from the
+.Fn archive_errno
+and
+.Fn archive_error_string
+functions.
+.\"
+.Sh SEE ALSO
+.Xr tar 1 ,
+.Xr libarchive 3 ,
+.Xr archive_write 3 ,
+.Xr archive_write_filter 3 ,
+.Xr archive_write_format 3 ,
+.Xr archive_write_new 3 ,
+.Xr archive_write_set_options 3 ,
+.Xr cpio 5 ,
+.Xr mtree 5 ,
+.Xr tar 5
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_open_fd.c b/Utilities/cmlibarchive/libarchive/archive_write_open_fd.c
new file mode 100644
index 000000000..d5c426cf9
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_open_fd.c
@@ -0,0 +1,144 @@
+/*-
+ * 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: head/lib/libarchive/archive_write_open_fd.c 201093 2009-12-28 02:28:44Z kientzle $");
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "archive.h"
+
+struct write_fd_data {
+ int fd;
+};
+
+static int file_close(struct archive *, void *);
+static int file_open(struct archive *, void *);
+static ssize_t file_write(struct archive *, void *, const void *buff, size_t);
+
+int
+archive_write_open_fd(struct archive *a, int fd)
+{
+ struct write_fd_data *mine;
+
+ mine = (struct write_fd_data *)malloc(sizeof(*mine));
+ if (mine == NULL) {
+ archive_set_error(a, ENOMEM, "No memory");
+ return (ARCHIVE_FATAL);
+ }
+ mine->fd = fd;
+#if defined(__CYGWIN__) || defined(_WIN32)
+ setmode(mine->fd, O_BINARY);
+#endif
+ return (archive_write_open(a, mine,
+ file_open, file_write, file_close));
+}
+
+static int
+file_open(struct archive *a, void *client_data)
+{
+ struct write_fd_data *mine;
+ struct stat st;
+
+ mine = (struct write_fd_data *)client_data;
+
+ if (fstat(mine->fd, &st) != 0) {
+ archive_set_error(a, errno, "Couldn't stat fd %d", mine->fd);
+ return (ARCHIVE_FATAL);
+ }
+
+ /*
+ * If this is a regular file, don't add it to itself.
+ */
+ if (S_ISREG(st.st_mode))
+ archive_write_set_skip_file(a, st.st_dev, st.st_ino);
+
+ /*
+ * If client hasn't explicitly set the last block handling,
+ * then set it here.
+ */
+ if (archive_write_get_bytes_in_last_block(a) < 0) {
+ /* If the output is a block or character device, fifo,
+ * or stdout, pad the last block, otherwise leave it
+ * unpadded. */
+ if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode) ||
+ S_ISFIFO(st.st_mode) || (mine->fd == 1))
+ /* Last block will be fully padded. */
+ archive_write_set_bytes_in_last_block(a, 0);
+ else
+ archive_write_set_bytes_in_last_block(a, 1);
+ }
+
+ return (ARCHIVE_OK);
+}
+
+static ssize_t
+file_write(struct archive *a, void *client_data, const void *buff, size_t length)
+{
+ struct write_fd_data *mine;
+ ssize_t bytesWritten;
+
+ mine = (struct write_fd_data *)client_data;
+ for (;;) {
+ bytesWritten = write(mine->fd, buff, length);
+ if (bytesWritten <= 0) {
+ if (errno == EINTR)
+ continue;
+ archive_set_error(a, errno, "Write error");
+ return (-1);
+ }
+ return (bytesWritten);
+ }
+}
+
+static int
+file_close(struct archive *a, void *client_data)
+{
+ struct write_fd_data *mine = (struct write_fd_data *)client_data;
+
+ (void)a; /* UNUSED */
+ free(mine);
+ return (ARCHIVE_OK);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_open_file.c b/Utilities/cmlibarchive/libarchive/archive_write_open_file.c
new file mode 100644
index 000000000..f6b141239
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_open_file.c
@@ -0,0 +1,109 @@
+/*-
+ * 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_write_open_file.c,v 1.19 2007/01/09 08:05:56 kientzle Exp $");
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "archive.h"
+
+struct write_FILE_data {
+ FILE *f;
+};
+
+static int file_close(struct archive *, void *);
+static int file_open(struct archive *, void *);
+static ssize_t file_write(struct archive *, void *, const void *buff, size_t);
+
+int
+archive_write_open_FILE(struct archive *a, FILE *f)
+{
+ struct write_FILE_data *mine;
+
+ mine = (struct write_FILE_data *)malloc(sizeof(*mine));
+ if (mine == NULL) {
+ archive_set_error(a, ENOMEM, "No memory");
+ return (ARCHIVE_FATAL);
+ }
+ mine->f = f;
+ return (archive_write_open(a, mine,
+ file_open, file_write, file_close));
+}
+
+static int
+file_open(struct archive *a, void *client_data)
+{
+ (void)a; /* UNUSED */
+ (void)client_data; /* UNUSED */
+
+ return (ARCHIVE_OK);
+}
+
+static ssize_t
+file_write(struct archive *a, void *client_data, const void *buff, size_t length)
+{
+ struct write_FILE_data *mine;
+ size_t bytesWritten;
+
+ mine = client_data;
+ for (;;) {
+ bytesWritten = fwrite(buff, 1, length, mine->f);
+ if (bytesWritten <= 0) {
+ if (errno == EINTR)
+ continue;
+ archive_set_error(a, errno, "Write error");
+ return (-1);
+ }
+ return (bytesWritten);
+ }
+}
+
+static int
+file_close(struct archive *a, void *client_data)
+{
+ struct write_FILE_data *mine = client_data;
+
+ (void)a; /* UNUSED */
+ free(mine);
+ return (ARCHIVE_OK);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_open_filename.c b/Utilities/cmlibarchive/libarchive/archive_write_open_filename.c
new file mode 100644
index 000000000..868986631
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_open_filename.c
@@ -0,0 +1,248 @@
+/*-
+ * 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: head/lib/libarchive/archive_write_open_filename.c 191165 2009-04-17 00:39:35Z kientzle $");
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "archive.h"
+#include "archive_string.h"
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+struct write_file_data {
+ int fd;
+ char mbs_filename;
+ union {
+ char m[1];
+ wchar_t w[1];
+ } filename; /* Must be last! */
+};
+
+static int file_close(struct archive *, void *);
+static int file_open(struct archive *, void *);
+static ssize_t file_write(struct archive *, void *, const void *buff, size_t);
+
+int
+archive_write_open_file(struct archive *a, const char *filename)
+{
+ return (archive_write_open_filename(a, filename));
+}
+
+int
+archive_write_open_filename(struct archive *a, const char *filename)
+{
+ struct write_file_data *mine;
+
+ if (filename == NULL || filename[0] == '\0')
+ return (archive_write_open_fd(a, 1));
+
+ mine = (struct write_file_data *)malloc(sizeof(*mine) + strlen(filename));
+ if (mine == NULL) {
+ archive_set_error(a, ENOMEM, "No memory");
+ return (ARCHIVE_FATAL);
+ }
+ strcpy(mine->filename.m, filename);
+ mine->mbs_filename = 1;
+ mine->fd = -1;
+ return (archive_write_open(a, mine,
+ file_open, file_write, file_close));
+}
+
+int
+archive_write_open_filename_w(struct archive *a, const wchar_t *filename)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ struct write_file_data *mine;
+
+ if (filename == NULL || filename[0] == L'\0')
+ return (archive_write_open_fd(a, 1));
+
+ mine = malloc(sizeof(*mine) + wcslen(filename) * sizeof(wchar_t));
+ if (mine == NULL) {
+ archive_set_error(a, ENOMEM, "No memory");
+ return (ARCHIVE_FATAL);
+ }
+ wcscpy(mine->filename.w, filename);
+ mine->mbs_filename = 0;
+ mine->fd = -1;
+ return (archive_write_open(a, mine,
+ file_open, file_write, file_close));
+#else
+ /*
+ * POSIX system does not support a wchar_t interface for
+ * open() system call, so we have to translate a wchar_t
+ * filename to multi-byte one and use it.
+ */
+ struct archive_string fn;
+ int r;
+
+ if (filename == NULL || filename[0] == L'\0')
+ return (archive_write_open_fd(a, 1));
+
+ archive_string_init(&fn);
+ if (archive_string_append_from_wcs(&fn, filename,
+ wcslen(filename)) != 0) {
+ archive_set_error(a, EINVAL,
+ "Failed to convert a wide-character filename to"
+ " a multi-byte filename");
+ archive_string_free(&fn);
+ return (ARCHIVE_FATAL);
+ }
+ r = archive_write_open_filename(a, fn.s);
+ archive_string_free(&fn);
+ return (r);
+#endif
+}
+
+
+static int
+file_open(struct archive *a, void *client_data)
+{
+ int flags;
+ struct write_file_data *mine;
+ struct stat st;
+
+ mine = (struct write_file_data *)client_data;
+ flags = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY;
+
+ /*
+ * Open the file.
+ */
+ if (mine->mbs_filename) {
+ mine->fd = open(mine->filename.m, flags, 0666);
+ if (mine->fd < 0) {
+ archive_set_error(a, errno, "Failed to open '%s'",
+ mine->filename.m);
+ return (ARCHIVE_FATAL);
+ }
+
+ if (fstat(mine->fd, &st) != 0) {
+ archive_set_error(a, errno, "Couldn't stat '%s'",
+ mine->filename.m);
+ return (ARCHIVE_FATAL);
+ }
+ } else {
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ mine->fd = _wopen(mine->filename.w, flags, 0666);
+ if (mine->fd < 0 && errno == ENOENT) {
+ wchar_t *fullpath;
+ fullpath = __la_win_permissive_name_w(mine->filename.w);
+ if (fullpath != NULL) {
+ mine->fd = _wopen(fullpath, flags, 0666);
+ free(fullpath);
+ }
+ }
+ if (mine->fd < 0) {
+ archive_set_error(a, errno, "Failed to open '%S'",
+ mine->filename.w);
+ return (ARCHIVE_FATAL);
+ }
+
+ if (fstat(mine->fd, &st) != 0) {
+ archive_set_error(a, errno, "Couldn't stat '%S'",
+ mine->filename.w);
+ return (ARCHIVE_FATAL);
+ }
+#else
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Unexpedted operation in archive_write_open_filename");
+ return (ARCHIVE_FATAL);
+#endif
+ }
+
+ /*
+ * Set up default last block handling.
+ */
+ if (archive_write_get_bytes_in_last_block(a) < 0) {
+ if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode) ||
+ S_ISFIFO(st.st_mode))
+ /* Pad last block when writing to device or FIFO. */
+ archive_write_set_bytes_in_last_block(a, 0);
+ else
+ /* Don't pad last block otherwise. */
+ archive_write_set_bytes_in_last_block(a, 1);
+ }
+
+ /*
+ * If the output file is a regular file, don't add it to
+ * itself. If it's a device file, it's okay to add the device
+ * entry to the output archive.
+ */
+ if (S_ISREG(st.st_mode))
+ archive_write_set_skip_file(a, st.st_dev, st.st_ino);
+
+ return (ARCHIVE_OK);
+}
+
+static ssize_t
+file_write(struct archive *a, void *client_data, const void *buff, size_t length)
+{
+ struct write_file_data *mine;
+ ssize_t bytesWritten;
+
+ mine = (struct write_file_data *)client_data;
+ for (;;) {
+ bytesWritten = write(mine->fd, buff, length);
+ if (bytesWritten <= 0) {
+ if (errno == EINTR)
+ continue;
+ archive_set_error(a, errno, "Write error");
+ return (-1);
+ }
+ return (bytesWritten);
+ }
+}
+
+static int
+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);
+ free(mine);
+ return (ARCHIVE_OK);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_open_memory.c b/Utilities/cmlibarchive/libarchive/archive_write_open_memory.c
new file mode 100644
index 000000000..4f8d679e5
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_open_memory.c
@@ -0,0 +1,114 @@
+/*-
+ * 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_write_open_memory.c,v 1.3 2007/01/09 08:05:56 kientzle Exp $");
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "archive.h"
+
+struct write_memory_data {
+ size_t used;
+ size_t size;
+ size_t * client_size;
+ unsigned char * buff;
+};
+
+static int memory_write_close(struct archive *, void *);
+static int memory_write_open(struct archive *, void *);
+static ssize_t memory_write(struct archive *, void *, const void *buff, size_t);
+
+/*
+ * Client provides a pointer to a block of memory to receive
+ * the data. The 'size' param both tells us the size of the
+ * client buffer and lets us tell the client the final size.
+ */
+int
+archive_write_open_memory(struct archive *a, void *buff, size_t buffSize, size_t *used)
+{
+ struct write_memory_data *mine;
+
+ mine = (struct write_memory_data *)malloc(sizeof(*mine));
+ if (mine == NULL) {
+ archive_set_error(a, ENOMEM, "No memory");
+ return (ARCHIVE_FATAL);
+ }
+ memset(mine, 0, sizeof(*mine));
+ mine->buff = buff;
+ mine->size = buffSize;
+ mine->client_size = used;
+ return (archive_write_open(a, mine,
+ memory_write_open, memory_write, memory_write_close));
+}
+
+static int
+memory_write_open(struct archive *a, void *client_data)
+{
+ struct write_memory_data *mine;
+ mine = client_data;
+ mine->used = 0;
+ if (mine->client_size != NULL)
+ *mine->client_size = mine->used;
+ /* Disable padding if it hasn't been set explicitly. */
+ if (-1 == archive_write_get_bytes_in_last_block(a))
+ archive_write_set_bytes_in_last_block(a, 1);
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Copy the data into the client buffer.
+ * Note that we update mine->client_size on every write.
+ * In particular, this means the client can follow exactly
+ * how much has been written into their buffer at any time.
+ */
+static ssize_t
+memory_write(struct archive *a, void *client_data, const void *buff, size_t length)
+{
+ struct write_memory_data *mine;
+ mine = client_data;
+
+ if (mine->used + length > mine->size) {
+ archive_set_error(a, ENOMEM, "Buffer exhausted");
+ return (ARCHIVE_FATAL);
+ }
+ memcpy(mine->buff + mine->used, buff, length);
+ mine->used += length;
+ if (mine->client_size != NULL)
+ *mine->client_size = mine->used;
+ return (length);
+}
+
+static int
+memory_write_close(struct archive *a, void *client_data)
+{
+ struct write_memory_data *mine;
+ (void)a; /* UNUSED */
+ mine = client_data;
+ free(mine);
+ return (ARCHIVE_OK);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_private.h b/Utilities/cmlibarchive/libarchive/archive_write_private.h
new file mode 100644
index 000000000..91284cf1b
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_private.h
@@ -0,0 +1,136 @@
+/*-
+ * 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.
+ *
+ * $FreeBSD: head/lib/libarchive/archive_write_private.h 201155 2009-12-29 05:20:12Z kientzle $
+ */
+
+#ifndef __LIBARCHIVE_BUILD
+#error This header is only to be used internally to libarchive.
+#endif
+
+#ifndef ARCHIVE_WRITE_PRIVATE_H_INCLUDED
+#define ARCHIVE_WRITE_PRIVATE_H_INCLUDED
+
+#include "archive.h"
+#include "archive_string.h"
+#include "archive_private.h"
+
+struct archive_write;
+
+struct archive_write_filter {
+ int64_t bytes_written;
+ struct archive *archive; /* Associated archive. */
+ struct archive_write_filter *next_filter; /* Who I write to. */
+ int (*options)(struct archive_write_filter *,
+ const char *key, const char *value);
+ int (*open)(struct archive_write_filter *);
+ int (*write)(struct archive_write_filter *, const void *, size_t);
+ int (*close)(struct archive_write_filter *);
+ int (*free)(struct archive_write_filter *);
+ void *data;
+ const char *name;
+ int code;
+ int bytes_per_block;
+ int bytes_in_last_block;
+};
+
+#if ARCHIVE_VERSION < 4000000
+void __archive_write_filters_free(struct archive *);
+#endif
+
+struct archive_write_filter *__archive_write_allocate_filter(struct archive *);
+
+int __archive_write_output(struct archive_write *, const void *, size_t);
+int __archive_write_nulls(struct archive_write *, size_t);
+int __archive_write_filter(struct archive_write_filter *, const void *, size_t);
+int __archive_write_open_filter(struct archive_write_filter *);
+int __archive_write_close_filter(struct archive_write_filter *);
+
+struct archive_write {
+ struct archive archive;
+
+ /* Dev/ino of the archive being written. */
+ int skip_file_set;
+ dev_t skip_file_dev;
+ int64_t skip_file_ino;
+
+ /* Utility: Pointer to a block of nulls. */
+ const unsigned char *nulls;
+ size_t null_length;
+
+ /* Callbacks to open/read/write/close archive stream. */
+ archive_open_callback *client_opener;
+ archive_write_callback *client_writer;
+ archive_close_callback *client_closer;
+ void *client_data;
+
+ /*
+ * Blocking information. Note that bytes_in_last_block is
+ * misleadingly named; I should find a better name. These
+ * control the final output from all compressors, including
+ * compression_none.
+ */
+ int bytes_per_block;
+ int bytes_in_last_block;
+
+ /*
+ * First and last write filters in the pipeline.
+ */
+ struct archive_write_filter *filter_first;
+ struct archive_write_filter *filter_last;
+
+ /*
+ * Pointers to format-specific functions for writing. They're
+ * initialized by archive_write_set_format_XXX() calls.
+ */
+ void *format_data;
+ const char *format_name;
+ int (*format_init)(struct archive_write *);
+ int (*format_options)(struct archive_write *,
+ const char *key, const char *value);
+ int (*format_finish_entry)(struct archive_write *);
+ int (*format_write_header)(struct archive_write *,
+ struct archive_entry *);
+ ssize_t (*format_write_data)(struct archive_write *,
+ const void *buff, size_t);
+ int (*format_close)(struct archive_write *);
+ int (*format_free)(struct archive_write *);
+};
+
+/*
+ * Utility function to format a USTAR header into a buffer. If
+ * "strict" is set, this tries to create the absolutely most portable
+ * version of a ustar header. If "strict" is set to 0, then it will
+ * relax certain requirements.
+ *
+ * Generally, format-specific declarations don't belong in this
+ * header; this is a rare example of a function that is shared by
+ * two very similar formats (ustar and pax).
+ */
+int
+__archive_write_format_header_ustar(struct archive_write *, char buff[512],
+ struct archive_entry *, int tartype, int strict,
+ struct archive_string_conv *);
+
+#endif
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format.c
new file mode 100644
index 000000000..641d56f6c
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format.c
@@ -0,0 +1,76 @@
+/*-
+ * 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: head/lib/libarchive/archive_write_set_format.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
+
+#include "archive.h"
+#include "archive_private.h"
+
+/* A table that maps format codes to functions. */
+static
+struct { int code; int (*setter)(struct archive *); } codes[] =
+{
+ { ARCHIVE_FORMAT_7ZIP, archive_write_set_format_7zip },
+ { ARCHIVE_FORMAT_CPIO, archive_write_set_format_cpio },
+ { ARCHIVE_FORMAT_CPIO_POSIX, archive_write_set_format_cpio },
+ { 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_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 },
+ { ARCHIVE_FORMAT_TAR, archive_write_set_format_pax_restricted },
+ { ARCHIVE_FORMAT_TAR_GNUTAR, archive_write_set_format_gnutar },
+ { ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE, archive_write_set_format_pax },
+ { ARCHIVE_FORMAT_TAR_PAX_RESTRICTED,
+ archive_write_set_format_pax_restricted },
+ { ARCHIVE_FORMAT_TAR_USTAR, archive_write_set_format_ustar },
+ { ARCHIVE_FORMAT_XAR, archive_write_set_format_xar },
+ { ARCHIVE_FORMAT_ZIP, archive_write_set_format_zip },
+ { 0, NULL }
+};
+
+int
+archive_write_set_format(struct archive *a, int code)
+{
+ int i;
+
+ for (i = 0; codes[i].code != 0; i++) {
+ if (code == codes[i].code)
+ return ((codes[i].setter)(a));
+ }
+
+ archive_set_error(a, EINVAL, "No such format");
+ return (ARCHIVE_FATAL);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_7zip.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_7zip.c
new file mode 100644
index 000000000..5bb248c55
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_7zip.c
@@ -0,0 +1,2303 @@
+/*-
+ * 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"
+__FBSDID("$FreeBSD$");
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include <stdlib.h>
+#ifdef HAVE_BZLIB_H
+#include <cm_bzlib.h>
+#endif
+#if HAVE_LZMA_H
+#include <lzma.h>
+#endif
+#ifdef HAVE_ZLIB_H
+#include <cm_zlib.h>
+#endif
+
+#include "archive.h"
+#ifndef HAVE_ZLIB_H
+#include "archive_crc32.h"
+#endif
+#include "archive_endian.h"
+#include "archive_entry.h"
+#include "archive_entry_locale.h"
+#include "archive_ppmd7_private.h"
+#include "archive_private.h"
+#include "archive_rb.h"
+#include "archive_string.h"
+#include "archive_write_private.h"
+
+/*
+ * Codec ID
+ */
+#define _7Z_COPY 0
+#define _7Z_LZMA1 0x030101
+#define _7Z_LZMA2 0x21
+#define _7Z_DEFLATE 0x040108
+#define _7Z_BZIP2 0x040202
+#define _7Z_PPMD 0x030401
+
+/*
+ * 7-Zip header property IDs.
+ */
+#define kEnd 0x00
+#define kHeader 0x01
+#define kArchiveProperties 0x02
+#define kAdditionalStreamsInfo 0x03
+#define kMainStreamsInfo 0x04
+#define kFilesInfo 0x05
+#define kPackInfo 0x06
+#define kUnPackInfo 0x07
+#define kSubStreamsInfo 0x08
+#define kSize 0x09
+#define kCRC 0x0A
+#define kFolder 0x0B
+#define kCodersUnPackSize 0x0C
+#define kNumUnPackStream 0x0D
+#define kEmptyStream 0x0E
+#define kEmptyFile 0x0F
+#define kAnti 0x10
+#define kName 0x11
+#define kCTime 0x12
+#define kATime 0x13
+#define kMTime 0x14
+#define kAttributes 0x15
+#define kEncodedHeader 0x17
+
+enum la_zaction {
+ ARCHIVE_Z_FINISH,
+ ARCHIVE_Z_RUN
+};
+
+/*
+ * A stream object of universal compressor.
+ */
+struct la_zstream {
+ const uint8_t *next_in;
+ size_t avail_in;
+ uint64_t total_in;
+
+ uint8_t *next_out;
+ size_t avail_out;
+ uint64_t total_out;
+
+ uint32_t prop_size;
+ uint8_t *props;
+
+ int valid;
+ void *real_stream;
+ int (*code) (struct archive *a,
+ struct la_zstream *lastrm,
+ enum la_zaction action);
+ int (*end)(struct archive *a,
+ struct la_zstream *lastrm);
+};
+
+#define PPMD7_DEFAULT_ORDER 6
+#define PPMD7_DEFAULT_MEM_SIZE (1 << 24)
+
+struct ppmd_stream {
+ int stat;
+ CPpmd7 ppmd7_context;
+ CPpmd7z_RangeEnc range_enc;
+ IByteOut byteout;
+ uint8_t *buff;
+ uint8_t *buff_ptr;
+ uint8_t *buff_end;
+ size_t buff_bytes;
+};
+
+struct coder {
+ unsigned codec;
+ size_t prop_size;
+ uint8_t *props;
+};
+
+struct file {
+ struct archive_rb_node rbnode;
+
+ struct file *next;
+ unsigned name_len;
+ uint8_t *utf16name;/* UTF16-LE name. */
+ uint64_t size;
+ unsigned flg;
+#define MTIME_IS_SET (1<<0)
+#define ATIME_IS_SET (1<<1)
+#define CTIME_IS_SET (1<<2)
+#define CRC32_IS_SET (1<<3)
+#define HAS_STREAM (1<<4)
+
+ struct {
+ time_t time;
+ long time_ns;
+ } times[3];
+#define MTIME 0
+#define ATIME 1
+#define CTIME 2
+
+ mode_t mode;
+ uint32_t crc32;
+
+ int dir:1;
+};
+
+struct _7zip {
+ int temp_fd;
+ uint64_t temp_offset;
+
+ struct file *cur_file;
+ size_t total_number_entry;
+ size_t total_number_nonempty_entry;
+ size_t total_number_empty_entry;
+ size_t total_number_dir_entry;
+ size_t total_bytes_entry_name;
+ size_t total_number_time_defined[3];
+ uint64_t total_bytes_compressed;
+ uint64_t total_bytes_uncompressed;
+ uint64_t entry_bytes_remaining;
+ uint32_t entry_crc32;
+ uint32_t precode_crc32;
+ uint32_t encoded_crc32;
+ int crc32flg;
+#define PRECODE_CRC32 1
+#define ENCODED_CRC32 2
+
+ unsigned opt_compression;
+ int opt_compression_level;
+
+ struct la_zstream stream;
+ struct coder coder;
+
+ struct archive_string_conv *sconv;
+
+ /*
+ * Compressed data buffer.
+ */
+ unsigned char wbuff[1024 * 64];
+ size_t wbuff_remaining;
+
+ /*
+ * The list of the file entries which has its contents is used to
+ * manage struct file objects.
+ * We use 'next' a menber of struct file to chain.
+ */
+ struct {
+ struct file *first;
+ struct file **last;
+ } file_list, empty_list;
+ struct archive_rb_tree rbtree;/* for empty files */
+};
+
+static int _7z_options(struct archive_write *,
+ const char *, const char *);
+static int _7z_write_header(struct archive_write *,
+ struct archive_entry *);
+static ssize_t _7z_write_data(struct archive_write *,
+ const void *, size_t);
+static int _7z_finish_entry(struct archive_write *);
+static int _7z_close(struct archive_write *);
+static int _7z_free(struct archive_write *);
+static int file_cmp_node(const struct archive_rb_node *,
+ const struct archive_rb_node *);
+static int file_cmp_key(const struct archive_rb_node *, const void *);
+static int file_new(struct archive_write *a, struct archive_entry *,
+ struct file **);
+static void file_free(struct file *);
+static void file_register(struct _7zip *, struct file *);
+static void file_register_empty(struct _7zip *, struct file *);
+static void file_init_register(struct _7zip *);
+static void file_init_register_empty(struct _7zip *);
+static void file_free_register(struct _7zip *);
+static ssize_t compress_out(struct archive_write *, const void *, size_t ,
+ enum la_zaction);
+static int compression_init_encoder_copy(struct archive *,
+ struct la_zstream *);
+static int compression_code_copy(struct archive *,
+ struct la_zstream *, enum la_zaction);
+static int compression_end_copy(struct archive *, struct la_zstream *);
+static int compression_init_encoder_deflate(struct archive *,
+ struct la_zstream *, int, int);
+#ifdef HAVE_ZLIB_H
+static int compression_code_deflate(struct archive *,
+ struct la_zstream *, enum la_zaction);
+static int compression_end_deflate(struct archive *, struct la_zstream *);
+#endif
+static int compression_init_encoder_bzip2(struct archive *,
+ struct la_zstream *, int);
+#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
+static int compression_code_bzip2(struct archive *,
+ struct la_zstream *, enum la_zaction);
+static int compression_end_bzip2(struct archive *, struct la_zstream *);
+#endif
+static int compression_init_encoder_lzma1(struct archive *,
+ struct la_zstream *, int);
+static int compression_init_encoder_lzma2(struct archive *,
+ struct la_zstream *, int);
+#if defined(HAVE_LZMA_H)
+static int compression_code_lzma(struct archive *,
+ struct la_zstream *, enum la_zaction);
+static int compression_end_lzma(struct archive *, struct la_zstream *);
+#endif
+static int compression_init_encoder_ppmd(struct archive *,
+ struct la_zstream *, unsigned, uint32_t);
+static int compression_code_ppmd(struct archive *,
+ struct la_zstream *, enum la_zaction);
+static int compression_end_ppmd(struct archive *, struct la_zstream *);
+static int _7z_compression_init_encoder(struct archive_write *, unsigned,
+ int);
+static int compression_code(struct archive *,
+ struct la_zstream *, enum la_zaction);
+static int compression_end(struct archive *,
+ struct la_zstream *);
+static int enc_uint64(struct archive_write *, uint64_t);
+static int make_header(struct archive_write *, uint64_t, uint64_t,
+ uint64_t, int, struct coder *);
+static int make_streamsInfo(struct archive_write *, uint64_t, uint64_t,
+ uint64_t, int, struct coder *, int, uint32_t);
+
+int
+archive_write_set_format_7zip(struct archive *_a)
+{
+ static const struct archive_rb_tree_ops rb_ops = {
+ file_cmp_node, file_cmp_key
+ };
+ struct archive_write *a = (struct archive_write *)_a;
+ struct _7zip *zip;
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_7zip");
+
+ /* If another format was already registered, unregister it. */
+ if (a->format_free != NULL)
+ (a->format_free)(a);
+
+ zip = calloc(1, sizeof(*zip));
+ if (zip == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate 7-Zip data");
+ return (ARCHIVE_FATAL);
+ }
+ zip->temp_fd = -1;
+ __archive_rb_tree_init(&(zip->rbtree), &rb_ops);
+ file_init_register(zip);
+ file_init_register_empty(zip);
+
+ /* Set default compression type and its level. */
+#if HAVE_LZMA_H
+ zip->opt_compression = _7Z_LZMA1;
+#elif defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
+ zip->opt_compression = _7Z_BZIP2;
+#elif defined(HAVE_ZLIB_H)
+ zip->opt_compression = _7Z_DEFLATE;
+#else
+ zip->opt_compression = _7Z_COPY;
+#endif
+ zip->opt_compression_level = 6;
+
+ a->format_data = zip;
+
+ a->format_name = "7zip";
+ a->format_options = _7z_options;
+ a->format_write_header = _7z_write_header;
+ a->format_write_data = _7z_write_data;
+ a->format_finish_entry = _7z_finish_entry;
+ a->format_close = _7z_close;
+ a->format_free = _7z_free;
+ a->archive.archive_format = ARCHIVE_FORMAT_7ZIP;
+ a->archive.archive_format_name = "7zip";
+
+ return (ARCHIVE_OK);
+}
+
+static int
+_7z_options(struct archive_write *a, const char *key, const char *value)
+{
+ struct _7zip *zip;
+
+ zip = (struct _7zip *)a->format_data;
+
+ if (strcmp(key, "compression") == 0) {
+ const char *name = NULL;
+
+ if (value == NULL || strcmp(value, "copy") == 0 ||
+ strcmp(value, "COPY") == 0 ||
+ strcmp(value, "store") == 0 ||
+ strcmp(value, "STORE") == 0)
+ zip->opt_compression = _7Z_COPY;
+ else if (strcmp(value, "deflate") == 0 ||
+ strcmp(value, "DEFLATE") == 0)
+#if HAVE_ZLIB_H
+ zip->opt_compression = _7Z_DEFLATE;
+#else
+ name = "deflate";
+#endif
+ else if (strcmp(value, "bzip2") == 0 ||
+ strcmp(value, "BZIP2") == 0)
+#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
+ zip->opt_compression = _7Z_BZIP2;
+#else
+ name = "bzip2";
+#endif
+ else if (strcmp(value, "lzma1") == 0 ||
+ strcmp(value, "LZMA1") == 0)
+#if HAVE_LZMA_H
+ zip->opt_compression = _7Z_LZMA1;
+#else
+ name = "lzma1";
+#endif
+ else if (strcmp(value, "lzma2") == 0 ||
+ strcmp(value, "LZMA2") == 0)
+#if HAVE_LZMA_H
+ zip->opt_compression = _7Z_LZMA2;
+#else
+ name = "lzma2";
+#endif
+ else if (strcmp(value, "ppmd") == 0 ||
+ strcmp(value, "PPMD") == 0 ||
+ strcmp(value, "PPMd") == 0)
+ zip->opt_compression = _7Z_PPMD;
+ else {
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "Unkonwn compression name: `%s'",
+ value);
+ return (ARCHIVE_FAILED);
+ }
+ if (name != NULL) {
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "`%s' compression not supported "
+ "on this platform",
+ name);
+ return (ARCHIVE_FAILED);
+ }
+ return (ARCHIVE_OK);
+ }
+ if (strcmp(key, "compression-level") == 0) {
+ if (value == NULL ||
+ !(value[0] >= '0' && value[0] <= '9') ||
+ value[1] != '\0') {
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "Illeagal value `%s'",
+ value);
+ return (ARCHIVE_FAILED);
+ }
+ zip->opt_compression_level = value[0] - '0';
+ return (ARCHIVE_OK);
+ }
+
+ return (ARCHIVE_FAILED);
+}
+
+static int
+_7z_write_header(struct archive_write *a, struct archive_entry *entry)
+{
+ struct _7zip *zip;
+ struct file *file;
+ int r;
+
+ zip = (struct _7zip *)a->format_data;
+ zip->cur_file = NULL;
+ zip->entry_bytes_remaining = 0;
+
+ if (zip->sconv == NULL) {
+ zip->sconv = archive_string_conversion_to_charset(
+ &a->archive, "UTF-16LE", 1);
+ if (zip->sconv == NULL)
+ return (ARCHIVE_FATAL);
+ }
+
+ r = file_new(a, entry, &file);
+ if (r < ARCHIVE_WARN) {
+ file_free(file);
+ return (r);
+ }
+
+ if (file->flg & MTIME_IS_SET)
+ zip->total_number_time_defined[MTIME]++;
+ if (file->flg & CTIME_IS_SET)
+ zip->total_number_time_defined[CTIME]++;
+ if (file->flg & ATIME_IS_SET)
+ zip->total_number_time_defined[ATIME]++;
+
+ if (file->size == 0 && file->dir) {
+ if (!__archive_rb_tree_insert_node(&(zip->rbtree),
+ (struct archive_rb_node *)file))
+ file_free(file);
+ }
+ zip->total_number_entry++;
+ zip->total_bytes_entry_name += file->name_len + 2;
+ if (file->size == 0) {
+ /* Count up the number of empty files. */
+ zip->total_number_empty_entry++;
+ if (file->dir)
+ zip->total_number_dir_entry++;
+ else
+ file_register_empty(zip, file);
+ return (r);
+ }
+
+ /*
+ * Init compression.
+ */
+ if ((zip->total_number_entry - zip->total_number_empty_entry) == 1) {
+ r = _7z_compression_init_encoder(a, zip->opt_compression,
+ zip->opt_compression_level);
+ if (r < 0) {
+ file_free(file);
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ /* Register a non-empty file. */
+ file_register(zip, file);
+
+ /*
+ * Set the current file to cur_file to read its contents.
+ */
+ zip->cur_file = file;
+
+
+ /* Save a offset of current file in temporary file. */
+ zip->entry_bytes_remaining = file->size;
+ zip->entry_crc32 = 0;
+
+ /*
+ * Store a symbolic link name as file contents.
+ */
+ if (archive_entry_filetype(entry) == AE_IFLNK) {
+ ssize_t bytes;
+ const void *p = (const void *)archive_entry_symlink(entry);
+ bytes = compress_out(a, p, file->size, ARCHIVE_Z_RUN);
+ if (bytes < 0)
+ return ((int)bytes);
+ zip->entry_crc32 = crc32(zip->entry_crc32, p, bytes);
+ zip->entry_bytes_remaining -= bytes;
+ }
+
+ return (r);
+}
+
+/*
+ * Write data to a temporary file.
+ */
+static int
+write_to_temp(struct archive_write *a, const void *buff, size_t s)
+{
+ struct _7zip *zip;
+ unsigned char *p;
+ ssize_t ws;
+
+ zip = (struct _7zip *)a->format_data;
+
+ /*
+ * Open a temporary file.
+ */
+ if (zip->temp_fd == -1) {
+ zip->temp_offset = 0;
+ zip->temp_fd = __archive_mktemp(NULL);
+ if (zip->temp_fd < 0) {
+ archive_set_error(&a->archive, errno,
+ "Couldn't create temporary file");
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ p = (unsigned char *)buff;
+ while (s) {
+ ws = write(zip->temp_fd, p, s);
+ if (ws < 0) {
+ archive_set_error(&(a->archive), errno,
+ "fwrite function failed");
+ return (ARCHIVE_FATAL);
+ }
+ s -= ws;
+ p += ws;
+ zip->temp_offset += ws;
+ }
+ return (ARCHIVE_OK);
+}
+
+static ssize_t
+compress_out(struct archive_write *a, const void *buff, size_t s,
+ enum la_zaction run)
+{
+ struct _7zip *zip = (struct _7zip *)a->format_data;
+ int r;
+
+ if (run == ARCHIVE_Z_FINISH && zip->stream.total_in == 0 && s == 0)
+ return (0);
+
+ if ((zip->crc32flg & PRECODE_CRC32) && s)
+ zip->precode_crc32 = crc32(zip->precode_crc32, buff, s);
+ zip->stream.next_in = (const unsigned char *)buff;
+ zip->stream.avail_in = s;
+ do {
+ /* Compress file data. */
+ r = compression_code(&(a->archive), &(zip->stream), run);
+ if (r != ARCHIVE_OK && r != ARCHIVE_EOF)
+ return (ARCHIVE_FATAL);
+ if (zip->stream.avail_out == 0) {
+ if (write_to_temp(a, zip->wbuff, sizeof(zip->wbuff))
+ != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ zip->stream.next_out = zip->wbuff;
+ zip->stream.avail_out = sizeof(zip->wbuff);
+ if (zip->crc32flg & ENCODED_CRC32)
+ zip->encoded_crc32 = crc32(zip->encoded_crc32,
+ zip->wbuff, sizeof(zip->wbuff));
+ }
+ } while (zip->stream.avail_in);
+ if (run == ARCHIVE_Z_FINISH) {
+ uint64_t bytes = sizeof(zip->wbuff) - zip->stream.avail_out;
+ if (write_to_temp(a, zip->wbuff, bytes) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ if ((zip->crc32flg & ENCODED_CRC32) && bytes)
+ zip->encoded_crc32 = crc32(zip->encoded_crc32,
+ zip->wbuff, bytes);
+ }
+
+ return (s);
+}
+
+static ssize_t
+_7z_write_data(struct archive_write *a, const void *buff, size_t s)
+{
+ struct _7zip *zip;
+ ssize_t bytes;
+
+ zip = (struct _7zip *)a->format_data;
+
+ if (s > zip->entry_bytes_remaining)
+ s = zip->entry_bytes_remaining;
+ if (s == 0 || zip->cur_file == NULL)
+ return (0);
+ bytes = compress_out(a, buff, s, ARCHIVE_Z_RUN);
+ if (bytes < 0)
+ return (bytes);
+ zip->entry_crc32 = crc32(zip->entry_crc32, buff, bytes);
+ zip->entry_bytes_remaining -= bytes;
+ return (bytes);
+}
+
+static int
+_7z_finish_entry(struct archive_write *a)
+{
+ struct _7zip *zip;
+ size_t s;
+ ssize_t r;
+
+ zip = (struct _7zip *)a->format_data;
+ if (zip->cur_file == NULL)
+ return (ARCHIVE_OK);
+
+ while (zip->entry_bytes_remaining > 0) {
+ s = zip->entry_bytes_remaining;
+ if (s > a->null_length)
+ s = a->null_length;
+ r = _7z_write_data(a, a->nulls, s);
+ if (r < 0)
+ return (r);
+ }
+ zip->total_bytes_compressed += zip->stream.total_in;
+ zip->total_bytes_uncompressed += zip->stream.total_out;
+ zip->cur_file->crc32 = zip->entry_crc32;
+ zip->cur_file = NULL;
+
+ return (ARCHIVE_OK);
+}
+
+static int
+flush_wbuff(struct archive_write *a)
+{
+ struct _7zip *zip;
+ int r;
+ size_t s;
+
+ zip = (struct _7zip *)a->format_data;
+ s = sizeof(zip->wbuff) - zip->wbuff_remaining;
+ r = __archive_write_output(a, zip->wbuff, s);
+ if (r != ARCHIVE_OK)
+ return (r);
+ zip->wbuff_remaining = sizeof(zip->wbuff);
+ return (r);
+}
+
+static int
+copy_out(struct archive_write *a, uint64_t offset, uint64_t length)
+{
+ struct _7zip *zip;
+ int r;
+
+ zip = (struct _7zip *)a->format_data;
+ if (zip->temp_offset > 0 &&
+ lseek(zip->temp_fd, offset, SEEK_SET) < 0) {
+ archive_set_error(&(a->archive), errno, "lseek failed");
+ return (ARCHIVE_FATAL);
+ }
+ while (length) {
+ size_t rsize;
+ ssize_t rs;
+ unsigned char *wb;
+
+ if (length > zip->wbuff_remaining)
+ rsize = zip->wbuff_remaining;
+ else
+ rsize = (size_t)length;
+ wb = zip->wbuff + (sizeof(zip->wbuff) - zip->wbuff_remaining);
+ rs = read(zip->temp_fd, wb, rsize);
+ if (rs < 0) {
+ archive_set_error(&(a->archive), errno,
+ "Can't read temporary file(%jd)",
+ (intmax_t)rs);
+ return (ARCHIVE_FATAL);
+ }
+ if (rs == 0) {
+ archive_set_error(&(a->archive), 0,
+ "Truncated 7-Zip archive");
+ return (ARCHIVE_FATAL);
+ }
+ zip->wbuff_remaining -= rs;
+ length -= rs;
+ if (zip->wbuff_remaining == 0) {
+ r = flush_wbuff(a);
+ if (r != ARCHIVE_OK)
+ return (r);
+ }
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+_7z_close(struct archive_write *a)
+{
+ struct _7zip *zip;
+ unsigned char *wb;
+ uint64_t header_offset, header_size, header_unpacksize;
+ uint64_t length;
+ uint32_t header_crc32;
+ int r;
+
+ zip = (struct _7zip *)a->format_data;
+
+ if (zip->total_number_entry > 0) {
+ struct archive_rb_node *n;
+ uint64_t data_offset, data_size, data_unpacksize;
+ unsigned header_compression;
+
+ r = (int)compress_out(a, NULL, 0, ARCHIVE_Z_FINISH);
+ if (r < 0)
+ return (r);
+ data_offset = 0;
+ data_size = zip->stream.total_out;
+ data_unpacksize = zip->stream.total_in;
+ zip->coder.codec = zip->opt_compression;
+ zip->coder.prop_size = zip->stream.prop_size;
+ zip->coder.props = zip->stream.props;
+ zip->stream.prop_size = 0;
+ zip->stream.props = NULL;
+ zip->total_number_nonempty_entry =
+ zip->total_number_entry - zip->total_number_empty_entry;
+
+ /* Connect an empty file list. */
+ *zip->file_list.last = zip->empty_list.first;
+ zip->file_list.last = zip->empty_list.last;
+ /* Connect a directory file list. */
+ ARCHIVE_RB_TREE_FOREACH(n, &(zip->rbtree)) {
+ file_register(zip, (struct file *)n);
+ }
+
+ /*
+ * NOTE: 7z command supports just LZMA1, LZMA2 and COPY for
+ * the compression type for encoding the header.
+ */
+#if HAVE_LZMA_H
+ header_compression = _7Z_LZMA1;
+ /* If the stored file is only one, do not encode the header.
+ * This is the same way 7z command does. */
+ if (zip->total_number_entry == 1)
+ header_compression = _7Z_COPY;
+#else
+ header_compression = _7Z_COPY;
+#endif
+ r = _7z_compression_init_encoder(a, header_compression, 6);
+ if (r < 0)
+ return (r);
+ zip->crc32flg = PRECODE_CRC32;
+ zip->precode_crc32 = 0;
+ r = make_header(a, data_offset, data_size, data_unpacksize,
+ 1, &(zip->coder));
+ if (r < 0)
+ return (r);
+ r = (int)compress_out(a, NULL, 0, ARCHIVE_Z_FINISH);
+ if (r < 0)
+ return (r);
+ header_offset = data_offset + data_size;
+ header_size = zip->stream.total_out;
+ header_crc32 = zip->precode_crc32;
+ header_unpacksize = zip->stream.total_in;
+
+ if (header_compression != _7Z_COPY) {
+ /*
+ * Encode the header in order to reduce the size
+ * of the archive.
+ */
+ free(zip->coder.props);
+ zip->coder.codec = header_compression;
+ zip->coder.prop_size = zip->stream.prop_size;
+ zip->coder.props = zip->stream.props;
+ zip->stream.prop_size = 0;
+ zip->stream.props = NULL;
+
+ r = _7z_compression_init_encoder(a, _7Z_COPY, 0);
+ if (r < 0)
+ return (r);
+ zip->crc32flg = ENCODED_CRC32;
+ zip->encoded_crc32 = 0;
+
+ /*
+ * Make EncodedHeader.
+ */
+ r = enc_uint64(a, kEncodedHeader);
+ if (r < 0)
+ return (r);
+ r = make_streamsInfo(a, header_offset, header_size,
+ header_unpacksize, 1, &(zip->coder), 0,
+ header_crc32);
+ if (r < 0)
+ return (r);
+ r = (int)compress_out(a, NULL, 0, ARCHIVE_Z_FINISH);
+ if (r < 0)
+ return (r);
+ header_offset = header_offset + header_size;
+ header_size = zip->stream.total_out;
+ header_crc32 = zip->encoded_crc32;
+ }
+ zip->crc32flg = 0;
+ } else {
+ header_offset = header_size = 0;
+ header_crc32 = 0;
+ }
+
+ length = zip->temp_offset;
+
+ /*
+ * Make the zip header on wbuff(write buffer).
+ */
+ wb = zip->wbuff;
+ zip->wbuff_remaining = sizeof(zip->wbuff);
+ memcpy(&wb[0], "7z\xBC\xAF\x27\x1C", 6);
+ wb[6] = 0;/* Major version. */
+ wb[7] = 3;/* Minor version. */
+ archive_le64enc(&wb[12], header_offset);/* Next Header Offset */
+ archive_le64enc(&wb[20], header_size);/* Next Header Size */
+ archive_le32enc(&wb[28], header_crc32);/* Next Header CRC */
+ archive_le32enc(&wb[8], crc32(0, &wb[12], 20));/* Start Header CRC */
+ zip->wbuff_remaining -= 32;
+
+ /*
+ * Read all file contents and an encoded header from the temporary
+ * file and write out it.
+ */
+ r = copy_out(a, 0, length);
+ if (r != ARCHIVE_OK)
+ return (r);
+ r = flush_wbuff(a);
+ return (r);
+}
+
+/*
+ * Encode 64 bits value into 7-Zip's encoded UINT64 value.
+ */
+static int
+enc_uint64(struct archive_write *a, uint64_t val)
+{
+ unsigned mask = 0x80;
+ uint8_t numdata[9];
+ int i;
+
+ numdata[0] = 0;
+ for (i = 1; i < sizeof(numdata); i++) {
+ if (val < mask) {
+ numdata[0] |= (uint8_t)val;
+ break;
+ }
+ numdata[i] = (uint8_t)val;
+ val >>= 8;
+ numdata[0] |= mask;
+ mask >>= 1;
+ }
+ return (compress_out(a, numdata, i, ARCHIVE_Z_RUN));
+}
+
+static int
+make_substreamsInfo(struct archive_write *a, struct coder *coders)
+{
+ struct _7zip *zip = (struct _7zip *)a->format_data;
+ struct file *file;
+ int r;
+
+ /*
+ * Make SubStreamsInfo.
+ */
+ r = enc_uint64(a, kSubStreamsInfo);
+ if (r < 0)
+ return (r);
+
+ if (zip->total_number_nonempty_entry > 1 && coders->codec != _7Z_COPY) {
+ /*
+ * Make NumUnPackStream.
+ */
+ r = enc_uint64(a, kNumUnPackStream);
+ if (r < 0)
+ return (r);
+
+ /* Write numUnpackStreams */
+ r = enc_uint64(a, zip->total_number_nonempty_entry);
+ if (r < 0)
+ return (r);
+
+ /*
+ * Make kSize.
+ */
+ r = enc_uint64(a, kSize);
+ if (r < 0)
+ return (r);
+ file = zip->file_list.first;
+ for (;file != NULL; file = file->next) {
+ if (file->next == NULL ||
+ file->next->size == 0)
+ break;
+ r = enc_uint64(a, file->size);
+ if (r < 0)
+ return (r);
+ }
+ }
+
+ /*
+ * Make CRC.
+ */
+ r = enc_uint64(a, kCRC);
+ if (r < 0)
+ return (r);
+
+
+ /* All are defined */
+ r = enc_uint64(a, 1);
+ if (r < 0)
+ return (r);
+ file = zip->file_list.first;
+ for (;file != NULL; file = file->next) {
+ uint8_t crc[4];
+ if (file->size == 0)
+ break;
+ archive_le32enc(crc, file->crc32);
+ r = compress_out(a, crc, 4, ARCHIVE_Z_RUN);
+ if (r < 0)
+ return (r);
+ }
+
+ /* Write End. */
+ r = enc_uint64(a, kEnd);
+ if (r < 0)
+ return (r);
+ return (ARCHIVE_OK);
+}
+
+static int
+make_streamsInfo(struct archive_write *a, uint64_t offset, uint64_t pack_size,
+ uint64_t unpack_size, int num_coder, struct coder *coders, int substrm,
+ uint32_t header_crc)
+{
+ struct _7zip *zip = (struct _7zip *)a->format_data;
+ uint8_t codec_buff[8];
+ int numFolders, fi;
+ int codec_size;
+ int i, r;
+
+ if (coders->codec == _7Z_COPY)
+ numFolders = zip->total_number_nonempty_entry;
+ else
+ numFolders = 1;
+
+ /*
+ * Make PackInfo.
+ */
+ r = enc_uint64(a, kPackInfo);
+ if (r < 0)
+ return (r);
+
+ /* Write PackPos. */
+ r = enc_uint64(a, offset);
+ if (r < 0)
+ return (r);
+
+ /* Write NumPackStreams. */
+ r = enc_uint64(a, numFolders);
+ if (r < 0)
+ return (r);
+
+ /* Make Size. */
+ r = enc_uint64(a, kSize);
+ if (r < 0)
+ return (r);
+
+ if (numFolders > 1) {
+ struct file *file = zip->file_list.first;
+ for (;file != NULL; file = file->next) {
+ if (file->size == 0)
+ break;
+ r = enc_uint64(a, file->size);
+ if (r < 0)
+ return (r);
+ }
+ } else {
+ /* Write size. */
+ r = enc_uint64(a, pack_size);
+ if (r < 0)
+ return (r);
+ }
+
+ r = enc_uint64(a, kEnd);
+ if (r < 0)
+ return (r);
+
+ /*
+ * Make UnPackInfo.
+ */
+ r = enc_uint64(a, kUnPackInfo);
+ if (r < 0)
+ return (r);
+
+ /*
+ * Make Folder.
+ */
+ r = enc_uint64(a, kFolder);
+ if (r < 0)
+ return (r);
+
+ /* Write NumFolders. */
+ r = enc_uint64(a, numFolders);
+ if (r < 0)
+ return (r);
+
+ /* Write External. */
+ r = enc_uint64(a, 0);
+ if (r < 0)
+ return (r);
+
+ for (fi = 0; fi < numFolders; fi++) {
+ /* Write NumCoders. */
+ r = enc_uint64(a, num_coder);
+ if (r < 0)
+ return (r);
+
+ for (i = 0; i < num_coder; i++) {
+ unsigned codec_id = coders[i].codec;
+
+ /* Write Codec flag. */
+ archive_be64enc(codec_buff, codec_id);
+ for (codec_size = 8; codec_size > 0; codec_size--) {
+ if (codec_buff[8 - codec_size])
+ break;
+ }
+ if (codec_size == 0)
+ codec_size = 1;
+ if (coders[i].prop_size)
+ r = enc_uint64(a, codec_size | 0x20);
+ else
+ r = enc_uint64(a, codec_size);
+ if (r < 0)
+ return (r);
+
+ /* Write Codec ID. */
+ codec_size &= 0x0f;
+ r = compress_out(a, &codec_buff[8-codec_size],
+ codec_size, ARCHIVE_Z_RUN);
+ if (r < 0)
+ return (r);
+
+ if (coders[i].prop_size) {
+ /* Write Codec property size. */
+ r = enc_uint64(a, coders[i].prop_size);
+ if (r < 0)
+ return (r);
+
+ /* Write Codec properties. */
+ r = compress_out(a, coders[i].props,
+ coders[i].prop_size, ARCHIVE_Z_RUN);
+ if (r < 0)
+ return (r);
+ }
+ }
+ }
+
+ /*
+ * Make CodersUnPackSize.
+ */
+ r = enc_uint64(a, kCodersUnPackSize);
+ if (r < 0)
+ return (r);
+
+ if (numFolders > 1) {
+ struct file *file = zip->file_list.first;
+ for (;file != NULL; file = file->next) {
+ if (file->size == 0)
+ break;
+ r = enc_uint64(a, file->size);
+ if (r < 0)
+ return (r);
+ }
+
+ } else {
+ /* Write UnPackSize. */
+ r = enc_uint64(a, unpack_size);
+ if (r < 0)
+ return (r);
+ }
+
+ if (!substrm) {
+ uint8_t crc[4];
+ /*
+ * Make CRC.
+ */
+ r = enc_uint64(a, kCRC);
+ if (r < 0)
+ return (r);
+
+ /* All are defined */
+ r = enc_uint64(a, 1);
+ if (r < 0)
+ return (r);
+ archive_le32enc(crc, header_crc);
+ r = compress_out(a, crc, 4, ARCHIVE_Z_RUN);
+ if (r < 0)
+ return (r);
+ }
+
+ /* Write End. */
+ r = enc_uint64(a, kEnd);
+ if (r < 0)
+ return (r);
+
+ if (substrm) {
+ /*
+ * Make SubStreamsInfo.
+ */
+ r = make_substreamsInfo(a, coders);
+ if (r < 0)
+ return (r);
+ }
+
+
+ /* Write End. */
+ r = enc_uint64(a, kEnd);
+ if (r < 0)
+ return (r);
+
+ return (ARCHIVE_OK);
+}
+
+
+#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
+static uint64_t
+utcToFiletime(time_t time, long ns)
+{
+ uint64_t fileTime;
+
+ fileTime = time;
+ fileTime *= 10000000;
+ fileTime += ns / 100;
+ fileTime += EPOC_TIME;
+ return (fileTime);
+}
+
+static int
+make_time(struct archive_write *a, uint8_t type, unsigned flg, int ti)
+{
+ uint8_t filetime[8];
+ struct _7zip *zip = (struct _7zip *)a->format_data;
+ struct file *file;
+ int r;
+ uint8_t mask, byte;
+
+ /*
+ * Make Time Bools.
+ */
+ if (zip->total_number_time_defined[ti] == zip->total_number_entry) {
+ /* Write Time Type. */
+ r = enc_uint64(a, type);
+ if (r < 0)
+ return (r);
+ /* Write EmptyStream Size. */
+ r = enc_uint64(a, 2 + zip->total_number_entry * 8);
+ if (r < 0)
+ return (r);
+ /* All are defined. */
+ r = enc_uint64(a, 1);
+ if (r < 0)
+ return (r);
+ } else {
+ if (zip->total_number_time_defined[ti] == 0)
+ return (ARCHIVE_OK);
+
+ /* Write Time Type. */
+ r = enc_uint64(a, type);
+ if (r < 0)
+ return (r);
+ /* Write EmptyStream Size. */
+ r = enc_uint64(a, 2 + ((zip->total_number_entry + 7) >> 3)
+ + zip->total_number_time_defined[ti] * 8);
+ if (r < 0)
+ return (r);
+
+ /* All are not defined. */
+ r = enc_uint64(a, 0);
+ if (r < 0)
+ return (r);
+
+ byte = 0;
+ mask = 0x80;
+ file = zip->file_list.first;
+ for (;file != NULL; file = file->next) {
+ if (file->flg & flg)
+ byte |= mask;
+ mask >>= 1;
+ if (mask == 0) {
+ r = compress_out(a, &byte, 1, ARCHIVE_Z_RUN);
+ if (r < 0)
+ return (r);
+ mask = 0x80;
+ byte = 0;
+ }
+ }
+ if (mask != 0x80) {
+ r = compress_out(a, &byte, 1, ARCHIVE_Z_RUN);
+ if (r < 0)
+ return (r);
+ }
+ }
+
+ /* External. */
+ r = enc_uint64(a, 0);
+ if (r < 0)
+ return (r);
+
+
+ /*
+ * Make Times.
+ */
+ file = zip->file_list.first;
+ for (;file != NULL; file = file->next) {
+ if ((file->flg & flg) == 0)
+ continue;
+ archive_le64enc(filetime, utcToFiletime(file->times[ti].time,
+ file->times[ti].time_ns));
+ r = compress_out(a, filetime, 8, ARCHIVE_Z_RUN);
+ if (r < 0)
+ return (r);
+ }
+
+ return (ARCHIVE_OK);
+}
+
+static int
+make_header(struct archive_write *a, uint64_t offset, uint64_t pack_size,
+ uint64_t unpack_size, int codernum, struct coder *coders)
+{
+ struct _7zip *zip = (struct _7zip *)a->format_data;
+ struct file *file;
+ int r;
+ uint8_t mask, byte;
+
+ /*
+ * Make FilesInfo.
+ */
+ r = enc_uint64(a, kHeader);
+ if (r < 0)
+ return (r);
+
+ /*
+ * If there are empty files only, do not write MainStreamInfo.
+ */
+ if (zip->total_number_nonempty_entry) {
+ /*
+ * Make MainStreamInfo.
+ */
+ r = enc_uint64(a, kMainStreamsInfo);
+ if (r < 0)
+ return (r);
+ r = make_streamsInfo(a, offset, pack_size, unpack_size,
+ codernum, coders, 1, 0);
+ if (r < 0)
+ return (r);
+ }
+
+ /*
+ * Make FilesInfo.
+ */
+ r = enc_uint64(a, kFilesInfo);
+ if (r < 0)
+ return (r);
+
+ /* Write numFiles. */
+ r = enc_uint64(a, zip->total_number_entry);
+ if (r < 0)
+ return (r);
+
+ if (zip->total_number_empty_entry > 0) {
+ /* Make EmptyStream. */
+ r = enc_uint64(a, kEmptyStream);
+ if (r < 0)
+ return (r);
+
+ /* Write EmptyStream Size. */
+ r = enc_uint64(a, (zip->total_number_entry+7)>>3);
+ if (r < 0)
+ return (r);
+
+ byte = 0;
+ mask = 0x80;
+ file = zip->file_list.first;
+ for (;file != NULL; file = file->next) {
+ if (file->size == 0)
+ byte |= mask;
+ mask >>= 1;
+ if (mask == 0) {
+ r = compress_out(a, &byte, 1, ARCHIVE_Z_RUN);
+ if (r < 0)
+ return (r);
+ mask = 0x80;
+ byte = 0;
+ }
+ }
+ if (mask != 0x80) {
+ r = compress_out(a, &byte, 1, ARCHIVE_Z_RUN);
+ if (r < 0)
+ return (r);
+ }
+ }
+
+ if (zip->total_number_empty_entry > zip->total_number_dir_entry) {
+ /* Make EmptyFile. */
+ r = enc_uint64(a, kEmptyFile);
+ if (r < 0)
+ return (r);
+
+ /* Write EmptyFile Size. */
+ r = enc_uint64(a, (zip->total_number_empty_entry + 7) >> 3);
+ if (r < 0)
+ return (r);
+
+ byte = 0;
+ mask = 0x80;
+ file = zip->file_list.first;
+ for (;file != NULL; file = file->next) {
+ if (file->size)
+ continue;
+ if (!file->dir)
+ byte |= mask;
+ mask >>= 1;
+ if (mask == 0) {
+ r = compress_out(a, &byte, 1, ARCHIVE_Z_RUN);
+ if (r < 0)
+ return (r);
+ mask = 0x80;
+ byte = 0;
+ }
+ }
+ if (mask != 0x80) {
+ r = compress_out(a, &byte, 1, ARCHIVE_Z_RUN);
+ if (r < 0)
+ return (r);
+ }
+ }
+
+ /* Make Name. */
+ r = enc_uint64(a, kName);
+ if (r < 0)
+ return (r);
+
+ /* Write Nume size. */
+ r = enc_uint64(a, zip->total_bytes_entry_name+1);
+ if (r < 0)
+ return (r);
+
+ /* Write dmy byte. */
+ r = enc_uint64(a, 0);
+ if (r < 0)
+ return (r);
+
+ file = zip->file_list.first;
+ for (;file != NULL; file = file->next) {
+ r = compress_out(a, file->utf16name, file->name_len+2,
+ ARCHIVE_Z_RUN);
+ if (r < 0)
+ return (r);
+ }
+
+ /* Make MTime. */
+ r = make_time(a, kMTime, MTIME_IS_SET, MTIME);
+ if (r < 0)
+ return (r);
+
+ /* Make CTime. */
+ r = make_time(a, kCTime, CTIME_IS_SET, CTIME);
+ if (r < 0)
+ return (r);
+
+ /* Make ATime. */
+ r = make_time(a, kATime, ATIME_IS_SET, ATIME);
+ if (r < 0)
+ return (r);
+
+ /* Make Attributes. */
+ r = enc_uint64(a, kAttributes);
+ if (r < 0)
+ return (r);
+
+ /* Write Attributes size. */
+ r = enc_uint64(a, 2 + zip->total_number_entry * 4);
+ if (r < 0)
+ return (r);
+
+ /* Write "All Are Defined". */
+ r = enc_uint64(a, 1);
+ if (r < 0)
+ return (r);
+
+ /* Write dmy byte. */
+ r = enc_uint64(a, 0);
+ if (r < 0)
+ return (r);
+
+ file = zip->file_list.first;
+ for (;file != NULL; file = file->next) {
+ /*
+ * High 16bits is unix mode.
+ * Low 16bits is Windows attributes.
+ */
+ uint32_t encattr, attr;
+ if (file->dir)
+ attr = 0x8010;
+ else
+ attr = 0x8020;
+ if ((file->mode & 0222) == 0)
+ attr |= 1;/* Read Only. */
+ attr |= ((uint32_t)file->mode) << 16;
+ archive_le32enc(&encattr, attr);
+ r = compress_out(a, &encattr, 4, ARCHIVE_Z_RUN);
+ if (r < 0)
+ return (r);
+ }
+
+ /* Write End. */
+ r = enc_uint64(a, kEnd);
+ if (r < 0)
+ return (r);
+
+ /* Write End. */
+ r = enc_uint64(a, kEnd);
+ if (r < 0)
+ return (r);
+
+ return (ARCHIVE_OK);
+}
+
+
+static int
+_7z_free(struct archive_write *a)
+{
+ struct _7zip *zip = (struct _7zip *)a->format_data;
+
+ file_free_register(zip);
+ compression_end(&(a->archive), &(zip->stream));
+ free(zip->coder.props);
+ free(zip);
+
+ return (ARCHIVE_OK);
+}
+
+static int
+file_cmp_node(const struct archive_rb_node *n1,
+ const struct archive_rb_node *n2)
+{
+ struct file *f1 = (struct file *)n1;
+ struct file *f2 = (struct file *)n2;
+
+ if (f1->name_len == f2->name_len)
+ return (memcmp(f1->utf16name, f2->utf16name, f1->name_len));
+ return (f1->name_len > f2->name_len)?1:-1;
+}
+
+static int
+file_cmp_key(const struct archive_rb_node *n, const void *key)
+{
+ struct file *f = (struct file *)n;
+
+ return (f->name_len - *(const char *)key);
+}
+
+static int
+file_new(struct archive_write *a, struct archive_entry *entry,
+ struct file **newfile)
+{
+ struct _7zip *zip;
+ struct file *file;
+ const char *u16;
+ size_t u16len;
+ int ret = ARCHIVE_OK;
+
+ zip = (struct _7zip *)a->format_data;
+ *newfile = NULL;
+
+ file = calloc(1, sizeof(*file));
+ if (file == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+
+ if (0 > archive_entry_pathname_l(entry, &u16, &u16len, zip->sconv)) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for UTF-16LE");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "A filename cannot be converted to UTF-16LE;"
+ "You should disable making Joliet extension");
+ ret = ARCHIVE_WARN;
+ }
+ file->utf16name = malloc(u16len + 2);
+ if (file->utf16name == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Name");
+ return (ARCHIVE_FATAL);
+ }
+ memcpy(file->utf16name, u16, u16len);
+ file->utf16name[u16len+0] = 0;
+ file->utf16name[u16len+1] = 0;
+ file->name_len = u16len;
+ file->mode = archive_entry_mode(entry);
+ if (archive_entry_filetype(entry) == AE_IFREG)
+ file->size = archive_entry_size(entry);
+ else
+ archive_entry_set_size(entry, 0);
+ if (archive_entry_filetype(entry) == AE_IFDIR)
+ file->dir = 1;
+ else if (archive_entry_filetype(entry) == AE_IFLNK)
+ file->size = strlen(archive_entry_symlink(entry));
+ if (archive_entry_mtime_is_set(entry)) {
+ file->flg |= MTIME_IS_SET;
+ file->times[MTIME].time = archive_entry_mtime(entry);
+ file->times[MTIME].time_ns = archive_entry_mtime_nsec(entry);
+ }
+ if (archive_entry_atime_is_set(entry)) {
+ file->flg |= ATIME_IS_SET;
+ file->times[ATIME].time = archive_entry_atime(entry);
+ file->times[ATIME].time_ns = archive_entry_atime_nsec(entry);
+ }
+ if (archive_entry_ctime_is_set(entry)) {
+ file->flg |= CTIME_IS_SET;
+ file->times[CTIME].time = archive_entry_ctime(entry);
+ file->times[CTIME].time_ns = archive_entry_ctime_nsec(entry);
+ }
+
+ *newfile = file;
+ return (ret);
+}
+
+static void
+file_free(struct file *file)
+{
+ free(file->utf16name);
+ free(file);
+}
+
+static void
+file_register(struct _7zip *zip, struct file *file)
+{
+ file->next = NULL;
+ *zip->file_list.last = file;
+ zip->file_list.last = &(file->next);
+}
+
+static void
+file_init_register(struct _7zip *zip)
+{
+ zip->file_list.first = NULL;
+ zip->file_list.last = &(zip->file_list.first);
+}
+
+static void
+file_free_register(struct _7zip *zip)
+{
+ struct file *file, *file_next;
+
+ file = zip->file_list.first;
+ while (file != NULL) {
+ file_next = file->next;
+ file_free(file);
+ file = file_next;
+ }
+}
+
+static void
+file_register_empty(struct _7zip *zip, struct file *file)
+{
+ file->next = NULL;
+ *zip->empty_list.last = file;
+ zip->empty_list.last = &(file->next);
+}
+
+static void
+file_init_register_empty(struct _7zip *zip)
+{
+ zip->empty_list.first = NULL;
+ zip->empty_list.last = &(zip->empty_list.first);
+}
+
+#if !defined(HAVE_BZLIB_H) || !defined(BZ_CONFIG_ERROR) || !defined(HAVE_LZMA_H)
+static int
+compression_unsupported_encoder(struct archive *a,
+ struct la_zstream *lastrm, const char *name)
+{
+
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "%s compression not supported on this platform", name);
+ lastrm->valid = 0;
+ lastrm->real_stream = NULL;
+ return (ARCHIVE_FAILED);
+}
+#endif
+
+/*
+ * _7_COPY compressor.
+ */
+static int
+compression_init_encoder_copy(struct archive *a, struct la_zstream *lastrm)
+{
+
+ if (lastrm->valid)
+ compression_end(a, lastrm);
+ lastrm->valid = 1;
+ lastrm->code = compression_code_copy;
+ lastrm->end = compression_end_copy;
+ return (ARCHIVE_OK);
+}
+
+static int
+compression_code_copy(struct archive *a,
+ struct la_zstream *lastrm, enum la_zaction action)
+{
+ size_t bytes;
+
+ (void)a; /* UNUSED */
+ if (lastrm->avail_out > lastrm->avail_in)
+ bytes = lastrm->avail_in;
+ else
+ bytes = lastrm->avail_out;
+ if (bytes) {
+ memcpy(lastrm->next_out, lastrm->next_in, bytes);
+ lastrm->next_in += bytes;
+ lastrm->avail_in -= bytes;
+ lastrm->total_in += bytes;
+ lastrm->next_out += bytes;
+ lastrm->avail_out -= bytes;
+ lastrm->total_out += bytes;
+ }
+ if (action == ARCHIVE_Z_FINISH && lastrm->avail_in == 0)
+ return (ARCHIVE_EOF);
+ return (ARCHIVE_OK);
+}
+
+static int
+compression_end_copy(struct archive *a, struct la_zstream *lastrm)
+{
+ (void)a; /* UNUSED */
+ lastrm->valid = 0;
+ return (ARCHIVE_OK);
+}
+
+/*
+ * _7_DEFLATE compressor.
+ */
+#ifdef HAVE_ZLIB_H
+static int
+compression_init_encoder_deflate(struct archive *a,
+ struct la_zstream *lastrm, int level, int withheader)
+{
+ z_stream *strm;
+
+ if (lastrm->valid)
+ compression_end(a, lastrm);
+ strm = calloc(1, sizeof(*strm));
+ if (strm == NULL) {
+ archive_set_error(a, ENOMEM,
+ "Can't allocate memory for gzip stream");
+ return (ARCHIVE_FATAL);
+ }
+ /* zlib.h is not const-correct, so we need this one bit
+ * of ugly hackery to convert a const * pointer to
+ * a non-const pointer. */
+ strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in;
+ strm->avail_in = lastrm->avail_in;
+ strm->total_in = lastrm->total_in;
+ strm->next_out = lastrm->next_out;
+ strm->avail_out = lastrm->avail_out;
+ strm->total_out = lastrm->total_out;
+ if (deflateInit2(strm, level, Z_DEFLATED,
+ (withheader)?15:-15,
+ 8, Z_DEFAULT_STRATEGY) != Z_OK) {
+ free(strm);
+ lastrm->real_stream = NULL;
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Internal error initializing compression library");
+ return (ARCHIVE_FATAL);
+ }
+ lastrm->real_stream = strm;
+ lastrm->valid = 1;
+ lastrm->code = compression_code_deflate;
+ lastrm->end = compression_end_deflate;
+ return (ARCHIVE_OK);
+}
+
+static int
+compression_code_deflate(struct archive *a,
+ struct la_zstream *lastrm, enum la_zaction action)
+{
+ z_stream *strm;
+ int r;
+
+ strm = (z_stream *)lastrm->real_stream;
+ /* zlib.h is not const-correct, so we need this one bit
+ * of ugly hackery to convert a const * pointer to
+ * a non-const pointer. */
+ strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in;
+ strm->avail_in = lastrm->avail_in;
+ strm->total_in = lastrm->total_in;
+ strm->next_out = lastrm->next_out;
+ strm->avail_out = lastrm->avail_out;
+ strm->total_out = lastrm->total_out;
+ r = deflate(strm,
+ (action == ARCHIVE_Z_FINISH)? Z_FINISH: Z_NO_FLUSH);
+ lastrm->next_in = strm->next_in;
+ lastrm->avail_in = strm->avail_in;
+ lastrm->total_in = strm->total_in;
+ lastrm->next_out = strm->next_out;
+ lastrm->avail_out = strm->avail_out;
+ lastrm->total_out = strm->total_out;
+ switch (r) {
+ case Z_OK:
+ return (ARCHIVE_OK);
+ case Z_STREAM_END:
+ return (ARCHIVE_EOF);
+ default:
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "GZip compression failed:"
+ " deflate() call returned status %d", r);
+ return (ARCHIVE_FATAL);
+ }
+}
+
+static int
+compression_end_deflate(struct archive *a, struct la_zstream *lastrm)
+{
+ z_stream *strm;
+ int r;
+
+ strm = (z_stream *)lastrm->real_stream;
+ r = deflateEnd(strm);
+ free(strm);
+ lastrm->real_stream = NULL;
+ lastrm->valid = 0;
+ if (r != Z_OK) {
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Failed to clean up compressor");
+ return (ARCHIVE_FATAL);
+ }
+ return (ARCHIVE_OK);
+}
+#else
+static int
+compression_init_encoder_deflate(struct archive *a,
+ struct la_zstream *lastrm, int level, int withheader)
+{
+
+ (void) level; /* UNUSED */
+ (void) withheader; /* UNUSED */
+ if (lastrm->valid)
+ compression_end(a, lastrm);
+ return (compression_unsupported_encoder(a, lastrm, "deflate"));
+}
+#endif
+
+/*
+ * _7_BZIP2 compressor.
+ */
+#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
+static int
+compression_init_encoder_bzip2(struct archive *a,
+ struct la_zstream *lastrm, int level)
+{
+ bz_stream *strm;
+
+ if (lastrm->valid)
+ compression_end(a, lastrm);
+ strm = calloc(1, sizeof(*strm));
+ if (strm == NULL) {
+ archive_set_error(a, ENOMEM,
+ "Can't allocate memory for bzip2 stream");
+ return (ARCHIVE_FATAL);
+ }
+ /* bzlib.h is not const-correct, so we need this one bit
+ * of ugly hackery to convert a const * pointer to
+ * a non-const pointer. */
+ strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in;
+ strm->avail_in = lastrm->avail_in;
+ strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff);
+ strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32);
+ strm->next_out = (char *)lastrm->next_out;
+ strm->avail_out = lastrm->avail_out;
+ strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff);
+ strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32);
+ if (BZ2_bzCompressInit(strm, level, 0, 30) != BZ_OK) {
+ free(strm);
+ lastrm->real_stream = NULL;
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Internal error initializing compression library");
+ return (ARCHIVE_FATAL);
+ }
+ lastrm->real_stream = strm;
+ lastrm->valid = 1;
+ lastrm->code = compression_code_bzip2;
+ lastrm->end = compression_end_bzip2;
+ return (ARCHIVE_OK);
+}
+
+static int
+compression_code_bzip2(struct archive *a,
+ struct la_zstream *lastrm, enum la_zaction action)
+{
+ bz_stream *strm;
+ int r;
+
+ strm = (bz_stream *)lastrm->real_stream;
+ /* bzlib.h is not const-correct, so we need this one bit
+ * of ugly hackery to convert a const * pointer to
+ * a non-const pointer. */
+ strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in;
+ strm->avail_in = lastrm->avail_in;
+ strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff);
+ strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32);
+ strm->next_out = (char *)lastrm->next_out;
+ strm->avail_out = lastrm->avail_out;
+ strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff);
+ strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32);
+ r = BZ2_bzCompress(strm,
+ (action == ARCHIVE_Z_FINISH)? BZ_FINISH: BZ_RUN);
+ lastrm->next_in = (const unsigned char *)strm->next_in;
+ lastrm->avail_in = strm->avail_in;
+ lastrm->total_in =
+ (((uint64_t)(uint32_t)strm->total_in_hi32) << 32)
+ + (uint64_t)(uint32_t)strm->total_in_lo32;
+ lastrm->next_out = (unsigned char *)strm->next_out;
+ lastrm->avail_out = strm->avail_out;
+ lastrm->total_out =
+ (((uint64_t)(uint32_t)strm->total_out_hi32) << 32)
+ + (uint64_t)(uint32_t)strm->total_out_lo32;
+ switch (r) {
+ case BZ_RUN_OK: /* Non-finishing */
+ case BZ_FINISH_OK: /* Finishing: There's more work to do */
+ return (ARCHIVE_OK);
+ case BZ_STREAM_END: /* Finishing: all done */
+ /* Only occurs in finishing case */
+ return (ARCHIVE_EOF);
+ default:
+ /* Any other return value indicates an error */
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Bzip2 compression failed:"
+ " BZ2_bzCompress() call returned status %d", r);
+ return (ARCHIVE_FATAL);
+ }
+}
+
+static int
+compression_end_bzip2(struct archive *a, struct la_zstream *lastrm)
+{
+ bz_stream *strm;
+ int r;
+
+ strm = (bz_stream *)lastrm->real_stream;
+ r = BZ2_bzCompressEnd(strm);
+ free(strm);
+ lastrm->real_stream = NULL;
+ lastrm->valid = 0;
+ if (r != BZ_OK) {
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Failed to clean up compressor");
+ return (ARCHIVE_FATAL);
+ }
+ return (ARCHIVE_OK);
+}
+
+#else
+static int
+compression_init_encoder_bzip2(struct archive *a,
+ struct la_zstream *lastrm, int level)
+{
+
+ (void) level; /* UNUSED */
+ if (lastrm->valid)
+ compression_end(a, lastrm);
+ return (compression_unsupported_encoder(a, lastrm, "bzip2"));
+}
+#endif
+
+/*
+ * _7_LZMA1, _7_LZMA2 compressor.
+ */
+#if defined(HAVE_LZMA_H)
+static int
+compression_init_encoder_lzma(struct archive *a,
+ struct la_zstream *lastrm, int level, uint64_t filter_id)
+{
+ static const lzma_stream lzma_init_data = LZMA_STREAM_INIT;
+ lzma_stream *strm;
+ lzma_filter *lzmafilters;
+ lzma_options_lzma lzma_opt;
+ int r;
+
+ if (lastrm->valid)
+ compression_end(a, lastrm);
+ strm = calloc(1, sizeof(*strm) + sizeof(*lzmafilters) * 2);
+ if (strm == NULL) {
+ archive_set_error(a, ENOMEM,
+ "Can't allocate memory for lzma stream");
+ return (ARCHIVE_FATAL);
+ }
+ lzmafilters = (lzma_filter *)(strm+1);
+ if (level > 6)
+ level = 6;
+ if (lzma_lzma_preset(&lzma_opt, level)) {
+ lastrm->real_stream = NULL;
+ archive_set_error(a, ENOMEM,
+ "Internal error initializing compression library");
+ return (ARCHIVE_FATAL);
+ }
+ lzmafilters[0].id = filter_id;
+ lzmafilters[0].options = &lzma_opt;
+ lzmafilters[1].id = LZMA_VLI_UNKNOWN;/* Terminate */
+
+ r = lzma_properties_size(&(lastrm->prop_size), lzmafilters);
+ if (r != LZMA_OK) {
+ free(strm);
+ lastrm->real_stream = NULL;
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "lzma_properties_size failed");
+ return (ARCHIVE_FATAL);
+ }
+ if (lastrm->prop_size) {
+ lastrm->props = malloc(lastrm->prop_size);
+ if (lastrm->props == NULL) {
+ free(strm);
+ lastrm->real_stream = NULL;
+ archive_set_error(a, ENOMEM,
+ "Cannot allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+ r = lzma_properties_encode(lzmafilters, lastrm->props);
+ if (r != LZMA_OK) {
+ free(strm);
+ lastrm->real_stream = NULL;
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "lzma_properties_encode failed");
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ *strm = lzma_init_data;
+ r = lzma_raw_encoder(strm, lzmafilters);
+ switch (r) {
+ case LZMA_OK:
+ lastrm->real_stream = strm;
+ lastrm->valid = 1;
+ lastrm->code = compression_code_lzma;
+ lastrm->end = compression_end_lzma;
+ r = ARCHIVE_OK;
+ break;
+ case LZMA_MEM_ERROR:
+ free(strm);
+ lastrm->real_stream = NULL;
+ archive_set_error(a, ENOMEM,
+ "Internal error initializing compression library: "
+ "Cannot allocate memory");
+ r = ARCHIVE_FATAL;
+ break;
+ default:
+ free(strm);
+ lastrm->real_stream = NULL;
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Internal error initializing compression library: "
+ "It's a bug in liblzma");
+ r = ARCHIVE_FATAL;
+ break;
+ }
+ return (r);
+}
+
+static int
+compression_init_encoder_lzma1(struct archive *a,
+ struct la_zstream *lastrm, int level)
+{
+ return compression_init_encoder_lzma(a, lastrm, level,
+ LZMA_FILTER_LZMA1);
+}
+
+static int
+compression_init_encoder_lzma2(struct archive *a,
+ struct la_zstream *lastrm, int level)
+{
+ return compression_init_encoder_lzma(a, lastrm, level,
+ LZMA_FILTER_LZMA2);
+}
+
+static int
+compression_code_lzma(struct archive *a,
+ struct la_zstream *lastrm, enum la_zaction action)
+{
+ lzma_stream *strm;
+ int r;
+
+ strm = (lzma_stream *)lastrm->real_stream;
+ strm->next_in = lastrm->next_in;
+ strm->avail_in = lastrm->avail_in;
+ strm->total_in = lastrm->total_in;
+ strm->next_out = lastrm->next_out;
+ strm->avail_out = lastrm->avail_out;
+ strm->total_out = lastrm->total_out;
+ r = lzma_code(strm,
+ (action == ARCHIVE_Z_FINISH)? LZMA_FINISH: LZMA_RUN);
+ lastrm->next_in = strm->next_in;
+ lastrm->avail_in = strm->avail_in;
+ lastrm->total_in = strm->total_in;
+ lastrm->next_out = strm->next_out;
+ lastrm->avail_out = strm->avail_out;
+ lastrm->total_out = strm->total_out;
+ switch (r) {
+ case LZMA_OK:
+ /* Non-finishing case */
+ return (ARCHIVE_OK);
+ case LZMA_STREAM_END:
+ /* This return can only occur in finishing case. */
+ return (ARCHIVE_EOF);
+ case LZMA_MEMLIMIT_ERROR:
+ archive_set_error(a, ENOMEM,
+ "lzma compression error:"
+ " %ju MiB would have been needed",
+ (uintmax_t)((lzma_memusage(strm) + 1024 * 1024 -1)
+ / (1024 * 1024)));
+ return (ARCHIVE_FATAL);
+ default:
+ /* Any other return value indicates an error */
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "lzma compression failed:"
+ " lzma_code() call returned status %d", r);
+ return (ARCHIVE_FATAL);
+ }
+}
+
+static int
+compression_end_lzma(struct archive *a, struct la_zstream *lastrm)
+{
+ lzma_stream *strm;
+
+ (void)a; /* UNUSED */
+ strm = (lzma_stream *)lastrm->real_stream;
+ lzma_end(strm);
+ free(strm);
+ lastrm->valid = 0;
+ lastrm->real_stream = NULL;
+ return (ARCHIVE_OK);
+}
+#else
+static int
+compression_init_encoder_lzma1(struct archive *a,
+ struct la_zstream *lastrm, int level)
+{
+
+ (void) level; /* UNUSED */
+ if (lastrm->valid)
+ compression_end(a, lastrm);
+ return (compression_unsupported_encoder(a, lastrm, "lzma"));
+}
+static int
+compression_init_encoder_lzma2(struct archive *a,
+ struct la_zstream *lastrm, int level)
+{
+
+ (void) level; /* UNUSED */
+ if (lastrm->valid)
+ compression_end(a, lastrm);
+ return (compression_unsupported_encoder(a, lastrm, "lzma"));
+}
+#endif
+
+/*
+ * _7_PPMD compressor.
+ */
+static void *
+ppmd_alloc(void *p, size_t size)
+{
+ (void)p;
+ return malloc(size);
+}
+static void
+ppmd_free(void *p, void *address)
+{
+ (void)p;
+ free(address);
+}
+static ISzAlloc g_szalloc = { ppmd_alloc, ppmd_free };
+static void
+ppmd_write(void *p, Byte b)
+{
+ struct archive_write *a = ((IByteOut *)p)->a;
+ struct _7zip *zip = (struct _7zip *)(a->format_data);
+ struct la_zstream *lastrm = &(zip->stream);
+ struct ppmd_stream *strm;
+
+ if (lastrm->avail_out) {
+ *lastrm->next_out++ = b;
+ lastrm->avail_out--;
+ lastrm->total_out++;
+ return;
+ }
+ strm = (struct ppmd_stream *)lastrm->real_stream;
+ if (strm->buff_ptr < strm->buff_end) {
+ *strm->buff_ptr++ = b;
+ strm->buff_bytes++;
+ }
+}
+
+static int
+compression_init_encoder_ppmd(struct archive *a,
+ struct la_zstream *lastrm, unsigned maxOrder, uint32_t msize)
+{
+ struct ppmd_stream *strm;
+ uint8_t *props;
+ int r;
+
+ if (lastrm->valid)
+ compression_end(a, lastrm);
+ strm = calloc(1, sizeof(*strm));
+ if (strm == NULL) {
+ archive_set_error(a, ENOMEM,
+ "Can't allocate memory for PPMd");
+ return (ARCHIVE_FATAL);
+ }
+ strm->buff = malloc(32);
+ if (strm->buff == NULL) {
+ free(strm);
+ archive_set_error(a, ENOMEM,
+ "Can't allocate memory for PPMd");
+ return (ARCHIVE_FATAL);
+ }
+ strm->buff_ptr = strm->buff;
+ strm->buff_end = strm->buff + 32;
+
+ props = malloc(1+4);
+ if (props == NULL) {
+ free(strm->buff);
+ free(strm);
+ archive_set_error(a, ENOMEM,
+ "Coludn't allocate memory for PPMd");
+ return (ARCHIVE_FATAL);
+ }
+ props[0] = maxOrder;
+ archive_le32enc(props+1, msize);
+ __archive_ppmd7_functions.Ppmd7_Construct(&strm->ppmd7_context);
+ r = __archive_ppmd7_functions.Ppmd7_Alloc(
+ &strm->ppmd7_context, msize, &g_szalloc);
+ if (r == 0) {
+ free(strm->buff);
+ free(strm);
+ free(props);
+ archive_set_error(a, ENOMEM,
+ "Coludn't allocate memory for PPMd");
+ return (ARCHIVE_FATAL);
+ }
+ __archive_ppmd7_functions.Ppmd7_Init(&(strm->ppmd7_context), maxOrder);
+ strm->byteout.a = (struct archive_write *)a;
+ strm->byteout.Write = ppmd_write;
+ strm->range_enc.Stream = &(strm->byteout);
+ __archive_ppmd7_functions.Ppmd7z_RangeEnc_Init(&(strm->range_enc));
+ strm->stat = 0;
+
+ lastrm->real_stream = strm;
+ lastrm->valid = 1;
+ lastrm->code = compression_code_ppmd;
+ lastrm->end = compression_end_ppmd;
+ lastrm->prop_size = 5;
+ lastrm->props = props;
+ return (ARCHIVE_OK);
+}
+
+static int
+compression_code_ppmd(struct archive *a,
+ struct la_zstream *lastrm, enum la_zaction action)
+{
+ struct ppmd_stream *strm;
+
+ strm = (struct ppmd_stream *)lastrm->real_stream;
+
+ /* Copy encoded data if there are remaining bytes from previous call. */
+ if (strm->buff_bytes) {
+ uint8_t *p = strm->buff_ptr - strm->buff_bytes;
+ while (lastrm->avail_out && strm->buff_bytes) {
+ *lastrm->next_out++ = *p++;
+ lastrm->avail_out--;
+ lastrm->total_out++;
+ strm->buff_bytes--;
+ }
+ if (strm->buff_bytes)
+ return (ARCHIVE_OK);
+ if (strm->stat == 1)
+ return (ARCHIVE_EOF);
+ strm->buff_ptr = strm->buff;
+ }
+ while (lastrm->avail_in && lastrm->avail_out) {
+ __archive_ppmd7_functions.Ppmd7_EncodeSymbol(
+ &(strm->ppmd7_context), &(strm->range_enc),
+ *lastrm->next_in++);
+ lastrm->avail_in--;
+ lastrm->total_in++;
+ }
+ if (lastrm->avail_in == 0 && action == ARCHIVE_Z_FINISH) {
+ __archive_ppmd7_functions.Ppmd7z_RangeEnc_FlushData(
+ &(strm->range_enc));
+ strm->stat = 1;
+ /* Return EOF if there are no remaining bytes. */
+ if (strm->buff_bytes == 0)
+ return (ARCHIVE_EOF);
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+compression_end_ppmd(struct archive *a, struct la_zstream *lastrm)
+{
+ struct ppmd_stream *strm;
+
+ strm = (struct ppmd_stream *)lastrm->real_stream;
+ __archive_ppmd7_functions.Ppmd7_Free(&strm->ppmd7_context, &g_szalloc);
+ free(strm->buff);
+ free(strm);
+ lastrm->real_stream = NULL;
+ lastrm->valid = 0;
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Universal compressor initializer.
+ */
+static int
+_7z_compression_init_encoder(struct archive_write *a, unsigned compression,
+ int compression_level)
+{
+ struct _7zip *zip;
+ int r;
+
+ zip = (struct _7zip *)a->format_data;
+ switch (compression) {
+ case _7Z_DEFLATE:
+ r = compression_init_encoder_deflate(
+ &(a->archive), &(zip->stream),
+ compression_level, 0);
+ break;
+ case _7Z_BZIP2:
+ r = compression_init_encoder_bzip2(
+ &(a->archive), &(zip->stream),
+ compression_level);
+ break;
+ case _7Z_LZMA1:
+ r = compression_init_encoder_lzma1(
+ &(a->archive), &(zip->stream),
+ compression_level);
+ break;
+ case _7Z_LZMA2:
+ r = compression_init_encoder_lzma2(
+ &(a->archive), &(zip->stream),
+ compression_level);
+ break;
+ case _7Z_PPMD:
+ r = compression_init_encoder_ppmd(
+ &(a->archive), &(zip->stream),
+ PPMD7_DEFAULT_ORDER, PPMD7_DEFAULT_MEM_SIZE);
+ break;
+ case _7Z_COPY:
+ default:
+ r = compression_init_encoder_copy(
+ &(a->archive), &(zip->stream));
+ break;
+ }
+ if (r == ARCHIVE_OK) {
+ zip->stream.total_in = 0;
+ zip->stream.next_out = zip->wbuff;
+ zip->stream.avail_out = sizeof(zip->wbuff);
+ zip->stream.total_out = 0;
+ }
+
+ return (r);
+}
+
+static int
+compression_code(struct archive *a, struct la_zstream *lastrm,
+ enum la_zaction action)
+{
+ if (lastrm->valid)
+ return (lastrm->code(a, lastrm, action));
+ return (ARCHIVE_OK);
+}
+
+static int
+compression_end(struct archive *a, struct la_zstream *lastrm)
+{
+ if (lastrm->valid) {
+ lastrm->prop_size = 0;
+ free(lastrm->props);
+ lastrm->props = NULL;
+ return (lastrm->end(a, lastrm));
+ }
+ return (ARCHIVE_OK);
+}
+
+
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_ar.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_ar.c
new file mode 100644
index 000000000..956b93228
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_ar.c
@@ -0,0 +1,564 @@
+/*-
+ * Copyright (c) 2007 Kai Wang
+ * Copyright (c) 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
+ * in this position and unchanged.
+ * 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_ar.c 201108 2009-12-28 03:28:21Z kientzle $");
+
+#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_write_private.h"
+
+struct ar_w {
+ uint64_t entry_bytes_remaining;
+ uint64_t entry_padding;
+ int is_strtab;
+ int has_strtab;
+ char wrote_global_header;
+ char *strtab;
+};
+
+/*
+ * Define structure of the "ar" header.
+ */
+#define AR_name_offset 0
+#define AR_name_size 16
+#define AR_date_offset 16
+#define AR_date_size 12
+#define AR_uid_offset 28
+#define AR_uid_size 6
+#define AR_gid_offset 34
+#define AR_gid_size 6
+#define AR_mode_offset 40
+#define AR_mode_size 8
+#define AR_size_offset 48
+#define AR_size_size 10
+#define AR_fmag_offset 58
+#define AR_fmag_size 2
+
+static int archive_write_set_format_ar(struct archive_write *);
+static int archive_write_ar_header(struct archive_write *,
+ struct archive_entry *);
+static ssize_t archive_write_ar_data(struct archive_write *,
+ const void *buff, size_t s);
+static int archive_write_ar_free(struct archive_write *);
+static int archive_write_ar_close(struct archive_write *);
+static int archive_write_ar_finish_entry(struct archive_write *);
+static const char *ar_basename(const char *path);
+static int format_octal(int64_t v, char *p, int s);
+static int format_decimal(int64_t v, char *p, int s);
+
+int
+archive_write_set_format_ar_bsd(struct archive *_a)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ int r;
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_ar_bsd");
+ r = archive_write_set_format_ar(a);
+ if (r == ARCHIVE_OK) {
+ a->archive.archive_format = ARCHIVE_FORMAT_AR_BSD;
+ a->archive.archive_format_name = "ar (BSD)";
+ }
+ return (r);
+}
+
+int
+archive_write_set_format_ar_svr4(struct archive *_a)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ int r;
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_ar_svr4");
+ r = archive_write_set_format_ar(a);
+ if (r == ARCHIVE_OK) {
+ a->archive.archive_format = ARCHIVE_FORMAT_AR_GNU;
+ a->archive.archive_format_name = "ar (GNU/SVR4)";
+ }
+ return (r);
+}
+
+/*
+ * Generic initialization.
+ */
+static int
+archive_write_set_format_ar(struct archive_write *a)
+{
+ struct ar_w *ar;
+
+ /* If someone else was already registered, unregister them. */
+ if (a->format_free != NULL)
+ (a->format_free)(a);
+
+ ar = (struct ar_w *)malloc(sizeof(*ar));
+ if (ar == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Can't allocate ar data");
+ return (ARCHIVE_FATAL);
+ }
+ memset(ar, 0, sizeof(*ar));
+ a->format_data = ar;
+
+ a->format_name = "ar";
+ a->format_write_header = archive_write_ar_header;
+ a->format_write_data = archive_write_ar_data;
+ a->format_close = archive_write_ar_close;
+ a->format_free = archive_write_ar_free;
+ a->format_finish_entry = archive_write_ar_finish_entry;
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_write_ar_header(struct archive_write *a, struct archive_entry *entry)
+{
+ int ret, append_fn;
+ char buff[60];
+ char *ss, *se;
+ struct ar_w *ar;
+ const char *pathname;
+ const char *filename;
+ int64_t size;
+
+ append_fn = 0;
+ ar = (struct ar_w *)a->format_data;
+ ar->is_strtab = 0;
+ filename = NULL;
+ size = archive_entry_size(entry);
+
+
+ /*
+ * Reject files with empty name.
+ */
+ pathname = archive_entry_pathname(entry);
+ if (*pathname == '\0') {
+ archive_set_error(&a->archive, EINVAL,
+ "Invalid filename");
+ return (ARCHIVE_WARN);
+ }
+
+ /*
+ * If we are now at the beginning of the archive,
+ * we need first write the ar global header.
+ */
+ if (!ar->wrote_global_header) {
+ __archive_write_output(a, "!<arch>\n", 8);
+ ar->wrote_global_header = 1;
+ }
+
+ memset(buff, ' ', 60);
+ strncpy(&buff[AR_fmag_offset], "`\n", 2);
+
+ if (strcmp(pathname, "/") == 0 ) {
+ /* Entry is archive symbol table in GNU format */
+ buff[AR_name_offset] = '/';
+ goto stat;
+ }
+ if (strcmp(pathname, "__.SYMDEF") == 0) {
+ /* Entry is archive symbol table in BSD format */
+ strncpy(buff + AR_name_offset, "__.SYMDEF", 9);
+ goto stat;
+ }
+ if (strcmp(pathname, "//") == 0) {
+ /*
+ * Entry is archive filename table, inform that we should
+ * collect strtab in next _data call.
+ */
+ ar->is_strtab = 1;
+ buff[AR_name_offset] = buff[AR_name_offset + 1] = '/';
+ /*
+ * For archive string table, only ar_size field should
+ * be set.
+ */
+ goto size;
+ }
+
+ /*
+ * Otherwise, entry is a normal archive member.
+ * Strip leading paths from filenames, if any.
+ */
+ if ((filename = ar_basename(pathname)) == NULL) {
+ /* Reject filenames with trailing "/" */
+ archive_set_error(&a->archive, EINVAL,
+ "Invalid filename");
+ return (ARCHIVE_WARN);
+ }
+
+ if (a->archive.archive_format == ARCHIVE_FORMAT_AR_GNU) {
+ /*
+ * SVR4/GNU variant use a "/" to mark then end of the filename,
+ * make it possible to have embedded spaces in the filename.
+ * So, the longest filename here (without extension) is
+ * actually 15 bytes.
+ */
+ if (strlen(filename) <= 15) {
+ strncpy(&buff[AR_name_offset],
+ filename, strlen(filename));
+ buff[AR_name_offset + strlen(filename)] = '/';
+ } else {
+ /*
+ * For filename longer than 15 bytes, GNU variant
+ * makes use of a string table and instead stores the
+ * offset of the real filename to in the ar_name field.
+ * The string table should have been written before.
+ */
+ if (ar->has_strtab <= 0) {
+ archive_set_error(&a->archive, EINVAL,
+ "Can't find string table");
+ return (ARCHIVE_WARN);
+ }
+
+ se = (char *)malloc(strlen(filename) + 3);
+ if (se == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate filename buffer");
+ return (ARCHIVE_FATAL);
+ }
+
+ strncpy(se, filename, strlen(filename));
+ strcpy(se + strlen(filename), "/\n");
+
+ ss = strstr(ar->strtab, se);
+ free(se);
+
+ if (ss == NULL) {
+ archive_set_error(&a->archive, EINVAL,
+ "Invalid string table");
+ return (ARCHIVE_WARN);
+ }
+
+ /*
+ * GNU variant puts "/" followed by digits into
+ * ar_name field. These digits indicates the real
+ * filename string's offset to the string table.
+ */
+ buff[AR_name_offset] = '/';
+ if (format_decimal(ss - ar->strtab,
+ buff + AR_name_offset + 1,
+ AR_name_size - 1)) {
+ archive_set_error(&a->archive, ERANGE,
+ "string table offset too large");
+ return (ARCHIVE_WARN);
+ }
+ }
+ } else if (a->archive.archive_format == ARCHIVE_FORMAT_AR_BSD) {
+ /*
+ * BSD variant: for any file name which is more than
+ * 16 chars or contains one or more embedded space(s), the
+ * string "#1/" followed by the ASCII length of the name is
+ * put into the ar_name field. The file size (stored in the
+ * ar_size field) is incremented by the length of the name.
+ * The name is then written immediately following the
+ * archive header.
+ */
+ if (strlen(filename) <= 16 && strchr(filename, ' ') == NULL) {
+ strncpy(&buff[AR_name_offset], filename, strlen(filename));
+ buff[AR_name_offset + strlen(filename)] = ' ';
+ }
+ else {
+ strncpy(buff + AR_name_offset, "#1/", 3);
+ if (format_decimal(strlen(filename),
+ buff + AR_name_offset + 3,
+ AR_name_size - 3)) {
+ archive_set_error(&a->archive, ERANGE,
+ "File name too long");
+ return (ARCHIVE_WARN);
+ }
+ append_fn = 1;
+ size += strlen(filename);
+ }
+ }
+
+stat:
+ if (format_decimal(archive_entry_mtime(entry), buff + AR_date_offset, AR_date_size)) {
+ archive_set_error(&a->archive, ERANGE,
+ "File modification time too large");
+ return (ARCHIVE_WARN);
+ }
+ if (format_decimal(archive_entry_uid(entry), buff + AR_uid_offset, AR_uid_size)) {
+ archive_set_error(&a->archive, ERANGE,
+ "Numeric user ID too large");
+ return (ARCHIVE_WARN);
+ }
+ if (format_decimal(archive_entry_gid(entry), buff + AR_gid_offset, AR_gid_size)) {
+ archive_set_error(&a->archive, ERANGE,
+ "Numeric group ID too large");
+ return (ARCHIVE_WARN);
+ }
+ if (format_octal(archive_entry_mode(entry), buff + AR_mode_offset, AR_mode_size)) {
+ archive_set_error(&a->archive, ERANGE,
+ "Numeric mode too large");
+ return (ARCHIVE_WARN);
+ }
+ /*
+ * Sanity Check: A non-pseudo archive member should always be
+ * a regular file.
+ */
+ if (filename != NULL && archive_entry_filetype(entry) != AE_IFREG) {
+ archive_set_error(&a->archive, EINVAL,
+ "Regular file required for non-pseudo member");
+ return (ARCHIVE_WARN);
+ }
+
+size:
+ if (format_decimal(size, buff + AR_size_offset, AR_size_size)) {
+ archive_set_error(&a->archive, ERANGE,
+ "File size out of range");
+ return (ARCHIVE_WARN);
+ }
+
+ ret = __archive_write_output(a, buff, 60);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+
+ ar->entry_bytes_remaining = size;
+ ar->entry_padding = ar->entry_bytes_remaining % 2;
+
+ if (append_fn > 0) {
+ ret = __archive_write_output(a, filename, strlen(filename));
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ ar->entry_bytes_remaining -= strlen(filename);
+ }
+
+ return (ARCHIVE_OK);
+}
+
+static ssize_t
+archive_write_ar_data(struct archive_write *a, const void *buff, size_t s)
+{
+ struct ar_w *ar;
+ int ret;
+
+ ar = (struct ar_w *)a->format_data;
+ if (s > ar->entry_bytes_remaining)
+ s = ar->entry_bytes_remaining;
+
+ if (ar->is_strtab > 0) {
+ if (ar->has_strtab > 0) {
+ archive_set_error(&a->archive, EINVAL,
+ "More than one string tables exist");
+ return (ARCHIVE_WARN);
+ }
+
+ ar->strtab = (char *)malloc(s);
+ if (ar->strtab == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate strtab buffer");
+ return (ARCHIVE_FATAL);
+ }
+ strncpy(ar->strtab, buff, s);
+ ar->has_strtab = 1;
+ }
+
+ ret = __archive_write_output(a, buff, s);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+
+ ar->entry_bytes_remaining -= s;
+ return (s);
+}
+
+static int
+archive_write_ar_free(struct archive_write *a)
+{
+ struct ar_w *ar;
+
+ ar = (struct ar_w *)a->format_data;
+
+ if (ar == NULL)
+ return (ARCHIVE_OK);
+
+ if (ar->has_strtab > 0) {
+ free(ar->strtab);
+ ar->strtab = NULL;
+ }
+
+ free(ar);
+ a->format_data = NULL;
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_write_ar_close(struct archive_write *a)
+{
+ struct ar_w *ar;
+ int ret;
+
+ /*
+ * If we haven't written anything yet, we need to write
+ * the ar global header now to make it a valid ar archive.
+ */
+ ar = (struct ar_w *)a->format_data;
+ if (!ar->wrote_global_header) {
+ ar->wrote_global_header = 1;
+ ret = __archive_write_output(a, "!<arch>\n", 8);
+ return (ret);
+ }
+
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_write_ar_finish_entry(struct archive_write *a)
+{
+ struct ar_w *ar;
+ int ret;
+
+ ar = (struct ar_w *)a->format_data;
+
+ if (ar->entry_bytes_remaining != 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Entry remaining bytes larger than 0");
+ return (ARCHIVE_WARN);
+ }
+
+ if (ar->entry_padding == 0) {
+ return (ARCHIVE_OK);
+ }
+
+ if (ar->entry_padding != 1) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Padding wrong size: %ju should be 1 or 0",
+ (uintmax_t)ar->entry_padding);
+ return (ARCHIVE_WARN);
+ }
+
+ ret = __archive_write_output(a, "\n", 1);
+ return (ret);
+}
+
+/*
+ * Format a number into the specified field using base-8.
+ * NB: This version is slightly different from the one in
+ * _ustar.c
+ */
+static int
+format_octal(int64_t v, char *p, int s)
+{
+ int len;
+ char *h;
+
+ len = s;
+ h = p;
+
+ /* Octal values can't be negative, so use 0. */
+ if (v < 0) {
+ while (len-- > 0)
+ *p++ = '0';
+ return (-1);
+ }
+
+ p += s; /* Start at the end and work backwards. */
+ do {
+ *--p = (char)('0' + (v & 7));
+ v >>= 3;
+ } while (--s > 0 && v > 0);
+
+ if (v == 0) {
+ memmove(h, p, len - s);
+ p = h + len - s;
+ while (s-- > 0)
+ *p++ = ' ';
+ return (0);
+ }
+ /* If it overflowed, fill field with max value. */
+ while (len-- > 0)
+ *p++ = '7';
+
+ return (-1);
+}
+
+/*
+ * Format a number into the specified field using base-10.
+ */
+static int
+format_decimal(int64_t v, char *p, int s)
+{
+ int len;
+ char *h;
+
+ len = s;
+ h = p;
+
+ /* Negative values in ar header are meaningless, so use 0. */
+ if (v < 0) {
+ while (len-- > 0)
+ *p++ = '0';
+ return (-1);
+ }
+
+ p += s;
+ do {
+ *--p = (char)('0' + (v % 10));
+ v /= 10;
+ } while (--s > 0 && v > 0);
+
+ if (v == 0) {
+ memmove(h, p, len - s);
+ p = h + len - s;
+ while (s-- > 0)
+ *p++ = ' ';
+ return (0);
+ }
+ /* If it overflowed, fill field with max value. */
+ while (len-- > 0)
+ *p++ = '9';
+
+ return (-1);
+}
+
+static const char *
+ar_basename(const char *path)
+{
+ const char *endp, *startp;
+
+ endp = path + strlen(path) - 1;
+ /*
+ * For filename with trailing slash(es), we return
+ * NULL indicating an error.
+ */
+ if (*endp == '/')
+ return (NULL);
+
+ /* Find the start of the base */
+ startp = endp;
+ while (startp > path && *(startp - 1) != '/')
+ startp--;
+
+ return (startp);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_by_name.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_by_name.c
new file mode 100644
index 000000000..9671f60f8
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_by_name.c
@@ -0,0 +1,86 @@
+/*-
+ * 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: 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 (*setter)(struct archive *); } names[] =
+{
+ { "7zip", archive_write_set_format_7zip },
+ { "ar", archive_write_set_format_ar_bsd },
+ { "arbsd", archive_write_set_format_ar_bsd },
+ { "argnu", archive_write_set_format_ar_svr4 },
+ { "arsvr4", archive_write_set_format_ar_svr4 },
+ { "bsdtar", archive_write_set_format_pax_restricted },
+ { "cd9660", archive_write_set_format_iso9660 },
+ { "cpio", archive_write_set_format_cpio },
+ { "gnutar", archive_write_set_format_gnutar },
+ { "iso", archive_write_set_format_iso9660 },
+ { "iso9660", archive_write_set_format_iso9660 },
+ { "mtree", archive_write_set_format_mtree },
+ { "newc", archive_write_set_format_cpio_newc },
+ { "odc", archive_write_set_format_cpio },
+ { "pax", archive_write_set_format_pax },
+ { "paxr", archive_write_set_format_pax_restricted },
+ { "posix", archive_write_set_format_pax },
+ { "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 },
+ { "xar", archive_write_set_format_xar },
+ { "zip", archive_write_set_format_zip },
+ { NULL, NULL }
+};
+
+int
+archive_write_set_format_by_name(struct archive *a, const char *name)
+{
+ int i;
+
+ for (i = 0; names[i].name != NULL; i++) {
+ if (strcmp(name, names[i].name) == 0)
+ return ((names[i].setter)(a));
+ }
+
+ archive_set_error(a, EINVAL, "No such format '%s'", name);
+ a->state = ARCHIVE_STATE_FATAL;
+ return (ARCHIVE_FATAL);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio.c
new file mode 100644
index 000000000..92b9bfb0b
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio.c
@@ -0,0 +1,464 @@
+/*-
+ * 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: head/lib/libarchive/archive_write_set_format_cpio.c 201170 2009-12-29 06:34:23Z kientzle $");
+
+#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
+
+#include "archive.h"
+#include "archive_entry.h"
+#include "archive_entry_locale.h"
+#include "archive_private.h"
+#include "archive_write_private.h"
+
+static ssize_t archive_write_cpio_data(struct archive_write *,
+ const void *buff, size_t s);
+static int archive_write_cpio_close(struct archive_write *);
+static int archive_write_cpio_free(struct archive_write *);
+static int archive_write_cpio_finish_entry(struct archive_write *);
+static int archive_write_cpio_header(struct archive_write *,
+ struct archive_entry *);
+static int archive_write_cpio_options(struct archive_write *,
+ const char *, const char *);
+static int format_octal(int64_t, void *, int);
+static int64_t format_octal_recursive(int64_t, char *, int);
+static int write_header(struct archive_write *, struct archive_entry *);
+
+struct cpio {
+ uint64_t entry_bytes_remaining;
+
+ int64_t ino_next;
+
+ struct { int64_t old; int new;} *ino_list;
+ size_t ino_list_size;
+ size_t ino_list_next;
+
+ struct archive_string_conv *opt_sconv;
+ struct archive_string_conv *sconv_default;
+ int init_default_conversion;
+};
+
+#define c_magic_offset 0
+#define c_magic_size 6
+#define c_dev_offset 6
+#define c_dev_size 6
+#define c_ino_offset 12
+#define c_ino_size 6
+#define c_mode_offset 18
+#define c_mode_size 6
+#define c_uid_offset 24
+#define c_uid_size 6
+#define c_gid_offset 30
+#define c_gid_size 6
+#define c_nlink_offset 36
+#define c_nlink_size 6
+#define c_rdev_offset 42
+#define c_rdev_size 6
+#define c_mtime_offset 48
+#define c_mtime_size 11
+#define c_namesize_offset 59
+#define c_namesize_size 6
+#define c_filesize_offset 65
+#define c_filesize_size 11
+
+/*
+ * Set output format to 'cpio' format.
+ */
+int
+archive_write_set_format_cpio(struct archive *_a)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ struct cpio *cpio;
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_cpio");
+
+ /* If someone else was already registered, unregister them. */
+ if (a->format_free != NULL)
+ (a->format_free)(a);
+
+ cpio = (struct cpio *)calloc(1, sizeof(*cpio));
+ if (cpio == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Can't allocate cpio data");
+ return (ARCHIVE_FATAL);
+ }
+ a->format_data = cpio;
+ a->format_name = "cpio";
+ a->format_options = archive_write_cpio_options;
+ a->format_write_header = archive_write_cpio_header;
+ a->format_write_data = archive_write_cpio_data;
+ a->format_finish_entry = archive_write_cpio_finish_entry;
+ a->format_close = archive_write_cpio_close;
+ a->format_free = archive_write_cpio_free;
+ a->archive.archive_format = ARCHIVE_FORMAT_CPIO_POSIX;
+ a->archive.archive_format_name = "POSIX cpio";
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_write_cpio_options(struct archive_write *a, const char *key,
+ const char *val)
+{
+ struct cpio *cpio = (struct cpio *)a->format_data;
+ int ret = ARCHIVE_FAILED;
+
+ if (strcmp(key, "hdrcharset") == 0) {
+ if (val == NULL || val[0] == 0)
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "%s: hdrcharset option needs a character-set name",
+ a->format_name);
+ else {
+ cpio->opt_sconv = archive_string_conversion_to_charset(
+ &a->archive, val, 0);
+ if (cpio->opt_sconv != NULL)
+ ret = ARCHIVE_OK;
+ else
+ ret = ARCHIVE_FATAL;
+ }
+ } else
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "%s: unknown keyword ``%s''", a->format_name, key);
+
+ return (ret);
+}
+
+/*
+ * Ino values are as long as 64 bits on some systems; cpio format
+ * only allows 18 bits and relies on the ino values to identify hardlinked
+ * files. So, we can't merely "hash" the ino numbers since collisions
+ * would corrupt the archive. Instead, we generate synthetic ino values
+ * to store in the archive and maintain a map of original ino values to
+ * synthetic ones so we can preserve hardlink information.
+ *
+ * TODO: Make this more efficient. It's not as bad as it looks (most
+ * files don't have any hardlinks and we don't do any work here for those),
+ * but it wouldn't be hard to do better.
+ *
+ * TODO: Work with dev/ino pairs here instead of just ino values.
+ */
+static int
+synthesize_ino_value(struct cpio *cpio, struct archive_entry *entry)
+{
+ int64_t ino = archive_entry_ino64(entry);
+ int ino_new;
+ size_t i;
+
+ /*
+ * If no index number was given, don't assign one. In
+ * particular, this handles the end-of-archive marker
+ * correctly by giving it a zero index value. (This is also
+ * why we start our synthetic index numbers with one below.)
+ */
+ if (ino == 0)
+ return (0);
+
+ /* Don't store a mapping if we don't need to. */
+ if (archive_entry_nlink(entry) < 2) {
+ return ++cpio->ino_next;
+ }
+
+ /* Look up old ino; if we have it, this is a hardlink
+ * and we reuse the same value. */
+ for (i = 0; i < cpio->ino_list_next; ++i) {
+ if (cpio->ino_list[i].old == ino)
+ return (cpio->ino_list[i].new);
+ }
+
+ /* Assign a new index number. */
+ ino_new = ++cpio->ino_next;
+
+ /* Ensure space for the new mapping. */
+ if (cpio->ino_list_size <= cpio->ino_list_next) {
+ size_t newsize = cpio->ino_list_size < 512
+ ? 512 : cpio->ino_list_size * 2;
+ void *newlist = realloc(cpio->ino_list,
+ sizeof(cpio->ino_list[0]) * newsize);
+ if (newlist == NULL)
+ return (-1);
+
+ cpio->ino_list_size = newsize;
+ cpio->ino_list = newlist;
+ }
+
+ /* Record and return the new value. */
+ cpio->ino_list[cpio->ino_list_next].old = ino;
+ cpio->ino_list[cpio->ino_list_next].new = ino_new;
+ ++cpio->ino_list_next;
+ return (ino_new);
+}
+
+
+static struct archive_string_conv *
+get_sconv(struct archive_write *a)
+{
+ struct cpio *cpio;
+ struct archive_string_conv *sconv;
+
+ cpio = (struct cpio *)a->format_data;
+ sconv = cpio->opt_sconv;
+ if (sconv == NULL) {
+ if (!cpio->init_default_conversion) {
+ cpio->sconv_default =
+ archive_string_default_conversion_for_write(
+ &(a->archive));
+ cpio->init_default_conversion = 1;
+ }
+ sconv = cpio->sconv_default;
+ }
+ return (sconv);
+}
+
+static int
+archive_write_cpio_header(struct archive_write *a, struct archive_entry *entry)
+{
+ const char *path;
+ size_t len;
+
+ if (archive_entry_filetype(entry) == 0) {
+ archive_set_error(&a->archive, -1, "Filetype required");
+ return (ARCHIVE_FAILED);
+ }
+
+ if (archive_entry_pathname_l(entry, &path, &len, get_sconv(a)) != 0
+ && errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Pathname");
+ return (ARCHIVE_FATAL);
+ }
+ if (len == 0 || path == NULL || path[0] == '\0') {
+ archive_set_error(&a->archive, -1, "Pathname required");
+ return (ARCHIVE_FAILED);
+ }
+
+ if (!archive_entry_size_is_set(entry) || archive_entry_size(entry) < 0) {
+ archive_set_error(&a->archive, -1, "Size required");
+ return (ARCHIVE_FAILED);
+ }
+ return write_header(a, entry);
+}
+
+static int
+write_header(struct archive_write *a, struct archive_entry *entry)
+{
+ struct cpio *cpio;
+ const char *p, *path;
+ int pathlength, ret, ret_final;
+ int64_t ino;
+ char h[76];
+ struct archive_string_conv *sconv;
+ size_t len;
+
+ cpio = (struct cpio *)a->format_data;
+ ret_final = ARCHIVE_OK;
+ sconv = get_sconv(a);
+
+ ret = archive_entry_pathname_l(entry, &path, &len, sconv);
+ if (ret != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Pathname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate pathname '%s' to %s",
+ archive_entry_pathname(entry),
+ archive_string_conversion_charset_name(sconv));
+ ret_final = ARCHIVE_WARN;
+ }
+ /* Include trailing null. */
+ pathlength = (int)len + 1;
+
+ memset(h, 0, sizeof(h));
+ format_octal(070707, h + c_magic_offset, c_magic_size);
+ format_octal(archive_entry_dev(entry), h + c_dev_offset, c_dev_size);
+
+ ino = synthesize_ino_value(cpio, entry);
+ if (ino < 0) {
+ archive_set_error(&a->archive, ENOMEM,
+ "No memory for ino translation table");
+ return (ARCHIVE_FATAL);
+ } else if (ino > 0777777) {
+ archive_set_error(&a->archive, ERANGE,
+ "Too many files for this cpio format");
+ return (ARCHIVE_FATAL);
+ }
+ format_octal(ino & 0777777, h + c_ino_offset, c_ino_size);
+
+ /* TODO: Set ret_final to ARCHIVE_WARN if any of these overflow. */
+ format_octal(archive_entry_mode(entry), h + c_mode_offset, c_mode_size);
+ format_octal(archive_entry_uid(entry), h + c_uid_offset, c_uid_size);
+ format_octal(archive_entry_gid(entry), h + c_gid_offset, c_gid_size);
+ format_octal(archive_entry_nlink(entry), h + c_nlink_offset, c_nlink_size);
+ if (archive_entry_filetype(entry) == AE_IFBLK
+ || archive_entry_filetype(entry) == AE_IFCHR)
+ format_octal(archive_entry_dev(entry), h + c_rdev_offset, c_rdev_size);
+ else
+ format_octal(0, h + c_rdev_offset, c_rdev_size);
+ format_octal(archive_entry_mtime(entry), h + c_mtime_offset, c_mtime_size);
+ format_octal(pathlength, h + c_namesize_offset, c_namesize_size);
+
+ /* Non-regular files don't store bodies. */
+ if (archive_entry_filetype(entry) != AE_IFREG)
+ archive_entry_set_size(entry, 0);
+
+ /* Symlinks get the link written as the body of the entry. */
+ ret = archive_entry_symlink_l(entry, &p, &len, sconv);
+ if (ret != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Linkname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate linkname '%s' to %s",
+ archive_entry_symlink(entry),
+ archive_string_conversion_charset_name(sconv));
+ ret_final = ARCHIVE_WARN;
+ }
+ if (len > 0 && p != NULL && *p != '\0')
+ ret = format_octal(strlen(p), h + c_filesize_offset,
+ c_filesize_size);
+ else
+ ret = format_octal(archive_entry_size(entry),
+ h + c_filesize_offset, c_filesize_size);
+ if (ret) {
+ archive_set_error(&a->archive, ERANGE,
+ "File is too large for cpio format.");
+ return (ARCHIVE_FAILED);
+ }
+
+ ret = __archive_write_output(a, h, sizeof(h));
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ ret = __archive_write_output(a, path, pathlength);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ cpio->entry_bytes_remaining = archive_entry_size(entry);
+
+ /* Write the symlink now. */
+ if (p != NULL && *p != '\0') {
+ ret = __archive_write_output(a, p, strlen(p));
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
+ return (ret_final);
+}
+
+static ssize_t
+archive_write_cpio_data(struct archive_write *a, const void *buff, size_t s)
+{
+ struct cpio *cpio;
+ int ret;
+
+ cpio = (struct cpio *)a->format_data;
+ if (s > cpio->entry_bytes_remaining)
+ s = cpio->entry_bytes_remaining;
+
+ ret = __archive_write_output(a, buff, s);
+ cpio->entry_bytes_remaining -= s;
+ if (ret >= 0)
+ return (s);
+ else
+ return (ret);
+}
+
+/*
+ * Format a number into the specified field.
+ */
+static int
+format_octal(int64_t v, void *p, int digits)
+{
+ int64_t max;
+ int ret;
+
+ max = (((int64_t)1) << (digits * 3)) - 1;
+ if (v >= 0 && v <= max) {
+ format_octal_recursive(v, (char *)p, digits);
+ ret = 0;
+ } else {
+ format_octal_recursive(max, (char *)p, digits);
+ ret = -1;
+ }
+ return (ret);
+}
+
+static int64_t
+format_octal_recursive(int64_t v, char *p, int s)
+{
+ if (s == 0)
+ return (v);
+ v = format_octal_recursive(v, p+1, s-1);
+ *p = '0' + (v & 7);
+ return (v >> 3);
+}
+
+static int
+archive_write_cpio_close(struct archive_write *a)
+{
+ int er;
+ struct archive_entry *trailer;
+
+ trailer = archive_entry_new2(NULL);
+ /* nlink = 1 here for GNU cpio compat. */
+ archive_entry_set_nlink(trailer, 1);
+ archive_entry_set_size(trailer, 0);
+ archive_entry_set_pathname(trailer, "TRAILER!!!");
+ er = write_header(a, trailer);
+ archive_entry_free(trailer);
+ return (er);
+}
+
+static int
+archive_write_cpio_free(struct archive_write *a)
+{
+ struct cpio *cpio;
+
+ cpio = (struct cpio *)a->format_data;
+ free(cpio->ino_list);
+ free(cpio);
+ a->format_data = NULL;
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_write_cpio_finish_entry(struct archive_write *a)
+{
+ struct cpio *cpio;
+
+ cpio = (struct cpio *)a->format_data;
+ return (__archive_write_nulls(a, cpio->entry_bytes_remaining));
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio_newc.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio_newc.c
new file mode 100644
index 000000000..d06c391a8
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio_newc.c
@@ -0,0 +1,420 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2006 Rudolf Marek SYSGO s.r.o.
+ * 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_cpio_newc.c 201160 2009-12-29 05:41:57Z kientzle $");
+
+#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
+
+#include "archive.h"
+#include "archive_entry.h"
+#include "archive_entry_locale.h"
+#include "archive_private.h"
+#include "archive_write_private.h"
+
+static ssize_t archive_write_newc_data(struct archive_write *,
+ const void *buff, size_t s);
+static int archive_write_newc_close(struct archive_write *);
+static int archive_write_newc_free(struct archive_write *);
+static int archive_write_newc_finish_entry(struct archive_write *);
+static int archive_write_newc_header(struct archive_write *,
+ struct archive_entry *);
+static int archive_write_newc_options(struct archive_write *,
+ const char *, const char *);
+static int format_hex(int64_t, void *, int);
+static int64_t format_hex_recursive(int64_t, char *, int);
+static int write_header(struct archive_write *, struct archive_entry *);
+
+struct cpio {
+ uint64_t entry_bytes_remaining;
+ int padding;
+
+ struct archive_string_conv *opt_sconv;
+ struct archive_string_conv *sconv_default;
+ int init_default_conversion;
+};
+
+#define c_magic_offset 0
+#define c_magic_size 6
+#define c_ino_offset 6
+#define c_ino_size 8
+#define c_mode_offset 14
+#define c_mode_size 8
+#define c_uid_offset 22
+#define c_uid_size 8
+#define c_gid_offset 30
+#define c_gid_size 8
+#define c_nlink_offset 38
+#define c_nlink_size 8
+#define c_mtime_offset 46
+#define c_mtime_size 8
+#define c_filesize_offset 54
+#define c_filesize_size 8
+#define c_devmajor_offset 62
+#define c_devmajor_size 8
+#define c_devminor_offset 70
+#define c_devminor_size 8
+#define c_rdevmajor_offset 78
+#define c_rdevmajor_size 8
+#define c_rdevminor_offset 86
+#define c_rdevminor_size 8
+#define c_namesize_offset 94
+#define c_namesize_size 8
+#define c_checksum_offset 102
+#define c_checksum_size 8
+#define c_header_size 110
+
+/* Logic trick: difference between 'n' and next multiple of 4 */
+#define PAD4(n) (3 & (1 + ~(n)))
+
+/*
+ * Set output format to 'cpio' format.
+ */
+int
+archive_write_set_format_cpio_newc(struct archive *_a)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ struct cpio *cpio;
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_cpio_newc");
+
+ /* If someone else was already registered, unregister them. */
+ if (a->format_free != NULL)
+ (a->format_free)(a);
+
+ cpio = (struct cpio *)malloc(sizeof(*cpio));
+ if (cpio == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Can't allocate cpio data");
+ return (ARCHIVE_FATAL);
+ }
+ memset(cpio, 0, sizeof(*cpio));
+ a->format_data = cpio;
+ a->format_name = "cpio";
+ a->format_options = archive_write_newc_options;
+ a->format_write_header = archive_write_newc_header;
+ a->format_write_data = archive_write_newc_data;
+ a->format_finish_entry = archive_write_newc_finish_entry;
+ a->format_close = archive_write_newc_close;
+ a->format_free = archive_write_newc_free;
+ a->archive.archive_format = ARCHIVE_FORMAT_CPIO_SVR4_NOCRC;
+ a->archive.archive_format_name = "SVR4 cpio nocrc";
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_write_newc_options(struct archive_write *a, const char *key,
+ const char *val)
+{
+ struct cpio *cpio = (struct cpio *)a->format_data;
+ int ret = ARCHIVE_FAILED;
+
+ if (strcmp(key, "hdrcharset") == 0) {
+ if (val == NULL || val[0] == 0)
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "%s: hdrcharset option needs a character-set name",
+ a->format_name);
+ else {
+ cpio->opt_sconv = archive_string_conversion_to_charset(
+ &a->archive, val, 0);
+ if (cpio->opt_sconv != NULL)
+ ret = ARCHIVE_OK;
+ else
+ ret = ARCHIVE_FATAL;
+ }
+ } else
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "%s: unknown keyword ``%s''", a->format_name, key);
+
+ return (ret);
+}
+
+static struct archive_string_conv *
+get_sconv(struct archive_write *a)
+{
+ struct cpio *cpio;
+ struct archive_string_conv *sconv;
+
+ cpio = (struct cpio *)a->format_data;
+ sconv = cpio->opt_sconv;
+ if (sconv == NULL) {
+ if (!cpio->init_default_conversion) {
+ cpio->sconv_default =
+ archive_string_default_conversion_for_write(
+ &(a->archive));
+ cpio->init_default_conversion = 1;
+ }
+ sconv = cpio->sconv_default;
+ }
+ return (sconv);
+}
+
+static int
+archive_write_newc_header(struct archive_write *a, struct archive_entry *entry)
+{
+ const char *path;
+ size_t len;
+
+ if (archive_entry_filetype(entry) == 0) {
+ archive_set_error(&a->archive, -1, "Filetype required");
+ return (ARCHIVE_FAILED);
+ }
+
+ if (archive_entry_pathname_l(entry, &path, &len, get_sconv(a)) != 0
+ && errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Pathname");
+ return (ARCHIVE_FATAL);
+ }
+ if (len == 0 || path == NULL || path[0] == '\0') {
+ archive_set_error(&a->archive, -1, "Pathname required");
+ return (ARCHIVE_FAILED);
+ }
+
+ if (archive_entry_hardlink(entry) == NULL
+ && (!archive_entry_size_is_set(entry) || archive_entry_size(entry) < 0)) {
+ archive_set_error(&a->archive, -1, "Size required");
+ return (ARCHIVE_FAILED);
+ }
+ return write_header(a, entry);
+}
+
+static int
+write_header(struct archive_write *a, struct archive_entry *entry)
+{
+ int64_t ino;
+ struct cpio *cpio;
+ const char *p, *path;
+ int pathlength, ret, ret_final;
+ char h[c_header_size];
+ struct archive_string_conv *sconv;
+ size_t len;
+ int pad;
+
+ cpio = (struct cpio *)a->format_data;
+ ret_final = ARCHIVE_OK;
+ sconv = get_sconv(a);
+
+ ret = archive_entry_pathname_l(entry, &path, &len, sconv);
+ if (ret != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Pathname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate pathname '%s' to %s",
+ archive_entry_pathname(entry),
+ archive_string_conversion_charset_name(sconv));
+ ret_final = ARCHIVE_WARN;
+ }
+ pathlength = (int)len + 1; /* Include trailing null. */
+
+ memset(h, 0, c_header_size);
+ format_hex(0x070701, h + c_magic_offset, c_magic_size);
+ format_hex(archive_entry_devmajor(entry), h + c_devmajor_offset,
+ c_devmajor_size);
+ format_hex(archive_entry_devminor(entry), h + c_devminor_offset,
+ c_devminor_size);
+
+ ino = archive_entry_ino64(entry);
+ if (ino > 0xffffffff) {
+ archive_set_error(&a->archive, ERANGE,
+ "large inode number truncated");
+ ret_final = ARCHIVE_WARN;
+ }
+
+ /* TODO: Set ret_final to ARCHIVE_WARN if any of these overflow. */
+ format_hex(ino & 0xffffffff, h + c_ino_offset, c_ino_size);
+ format_hex(archive_entry_mode(entry), h + c_mode_offset, c_mode_size);
+ format_hex(archive_entry_uid(entry), h + c_uid_offset, c_uid_size);
+ format_hex(archive_entry_gid(entry), h + c_gid_offset, c_gid_size);
+ format_hex(archive_entry_nlink(entry), h + c_nlink_offset, c_nlink_size);
+ if (archive_entry_filetype(entry) == AE_IFBLK
+ || archive_entry_filetype(entry) == AE_IFCHR) {
+ format_hex(archive_entry_rdevmajor(entry), h + c_rdevmajor_offset, c_rdevmajor_size);
+ format_hex(archive_entry_rdevminor(entry), h + c_rdevminor_offset, c_rdevminor_size);
+ } else {
+ format_hex(0, h + c_rdevmajor_offset, c_rdevmajor_size);
+ format_hex(0, h + c_rdevminor_offset, c_rdevminor_size);
+ }
+ format_hex(archive_entry_mtime(entry), h + c_mtime_offset, c_mtime_size);
+ format_hex(pathlength, h + c_namesize_offset, c_namesize_size);
+ format_hex(0, h + c_checksum_offset, c_checksum_size);
+
+ /* Non-regular files don't store bodies. */
+ if (archive_entry_filetype(entry) != AE_IFREG)
+ archive_entry_set_size(entry, 0);
+
+ /* Symlinks get the link written as the body of the entry. */
+ ret = archive_entry_symlink_l(entry, &p, &len, sconv);
+ if (ret != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Likname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate linkname '%s' to %s",
+ archive_entry_symlink(entry),
+ archive_string_conversion_charset_name(sconv));
+ ret_final = ARCHIVE_WARN;
+ }
+ if (len > 0 && p != NULL && *p != '\0')
+ ret = format_hex(strlen(p), h + c_filesize_offset,
+ c_filesize_size);
+ else
+ ret = format_hex(archive_entry_size(entry),
+ h + c_filesize_offset, c_filesize_size);
+ if (ret) {
+ archive_set_error(&a->archive, ERANGE,
+ "File is too large for this format.");
+ return (ARCHIVE_FAILED);
+ }
+
+ ret = __archive_write_output(a, h, c_header_size);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ /* Pad pathname to even length. */
+ ret = __archive_write_output(a, path, pathlength);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ pad = PAD4(pathlength + c_header_size);
+ if (pad) {
+ ret = __archive_write_output(a, "\0\0\0", pad);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
+
+ cpio->entry_bytes_remaining = archive_entry_size(entry);
+ cpio->padding = PAD4(cpio->entry_bytes_remaining);
+
+ /* Write the symlink now. */
+ if (p != NULL && *p != '\0') {
+ ret = __archive_write_output(a, p, strlen(p));
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ pad = PAD4(strlen(p));
+ ret = __archive_write_output(a, "\0\0\0", pad);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
+ return (ret_final);
+}
+
+static ssize_t
+archive_write_newc_data(struct archive_write *a, const void *buff, size_t s)
+{
+ struct cpio *cpio;
+ int ret;
+
+ cpio = (struct cpio *)a->format_data;
+ if (s > cpio->entry_bytes_remaining)
+ s = cpio->entry_bytes_remaining;
+
+ ret = __archive_write_output(a, buff, s);
+ cpio->entry_bytes_remaining -= s;
+ if (ret >= 0)
+ return (s);
+ else
+ return (ret);
+}
+
+/*
+ * Format a number into the specified field.
+ */
+static int
+format_hex(int64_t v, void *p, int digits)
+{
+ int64_t max;
+ int ret;
+
+ max = (((int64_t)1) << (digits * 4)) - 1;
+ if (v >= 0 && v <= max) {
+ format_hex_recursive(v, (char *)p, digits);
+ ret = 0;
+ } else {
+ format_hex_recursive(max, (char *)p, digits);
+ ret = -1;
+ }
+ return (ret);
+}
+
+static int64_t
+format_hex_recursive(int64_t v, char *p, int s)
+{
+ if (s == 0)
+ return (v);
+ v = format_hex_recursive(v, p+1, s-1);
+ *p = "0123456789abcdef"[v & 0xf];
+ return (v >> 4);
+}
+
+static int
+archive_write_newc_close(struct archive_write *a)
+{
+ int er;
+ struct archive_entry *trailer;
+
+ trailer = archive_entry_new();
+ archive_entry_set_nlink(trailer, 1);
+ archive_entry_set_size(trailer, 0);
+ archive_entry_set_pathname(trailer, "TRAILER!!!");
+ /* Bypass the required data checks. */
+ er = write_header(a, trailer);
+ archive_entry_free(trailer);
+ return (er);
+}
+
+static int
+archive_write_newc_free(struct archive_write *a)
+{
+ struct cpio *cpio;
+
+ cpio = (struct cpio *)a->format_data;
+ free(cpio);
+ a->format_data = NULL;
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_write_newc_finish_entry(struct archive_write *a)
+{
+ struct cpio *cpio;
+
+ cpio = (struct cpio *)a->format_data;
+ return (__archive_write_nulls(a, cpio->entry_bytes_remaining + cpio->padding));
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_gnutar.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_gnutar.c
new file mode 100644
index 000000000..e091ed23f
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_gnutar.c
@@ -0,0 +1,684 @@
+/*-
+ * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ * Author: Jonas Gastal <jgastal@profusion.mobi>
+ * 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"
+__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_gnu_tar.c 191579 2009-04-27 18:35:03Z gastal $");
+
+
+#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
+
+#include "archive.h"
+#include "archive_entry.h"
+#include "archive_entry_locale.h"
+#include "archive_private.h"
+#include "archive_write_private.h"
+
+struct gnutar {
+ uint64_t entry_bytes_remaining;
+ uint64_t entry_padding;
+ const char * linkname;
+ size_t linkname_length;
+ const char * pathname;
+ size_t pathname_length;
+ const char * uname;
+ size_t uname_length;
+ const char * gname;
+ size_t gname_length;
+ struct archive_string_conv *opt_sconv;
+ struct archive_string_conv *sconv_default;
+ int init_default_conversion;
+};
+
+/*
+ * Define structure of GNU tar header.
+ */
+#define GNUTAR_name_offset 0
+#define GNUTAR_name_size 100
+#define GNUTAR_mode_offset 100
+#define GNUTAR_mode_size 7
+#define GNUTAR_mode_max_size 8
+#define GNUTAR_uid_offset 108
+#define GNUTAR_uid_size 7
+#define GNUTAR_uid_max_size 8
+#define GNUTAR_gid_offset 116
+#define GNUTAR_gid_size 7
+#define GNUTAR_gid_max_size 8
+#define GNUTAR_size_offset 124
+#define GNUTAR_size_size 11
+#define GNUTAR_size_max_size 12
+#define GNUTAR_mtime_offset 136
+#define GNUTAR_mtime_size 11
+#define GNUTAR_mtime_max_size 11
+#define GNUTAR_checksum_offset 148
+#define GNUTAR_checksum_size 8
+#define GNUTAR_typeflag_offset 156
+#define GNUTAR_typeflag_size 1
+#define GNUTAR_linkname_offset 157
+#define GNUTAR_linkname_size 100
+#define GNUTAR_magic_offset 257
+#define GNUTAR_magic_size 6
+#define GNUTAR_version_offset 263
+#define GNUTAR_version_size 2
+#define GNUTAR_uname_offset 265
+#define GNUTAR_uname_size 32
+#define GNUTAR_gname_offset 297
+#define GNUTAR_gname_size 32
+#define GNUTAR_rdevmajor_offset 329
+#define GNUTAR_rdevmajor_size 6
+#define GNUTAR_rdevmajor_max_size 8
+#define GNUTAR_rdevminor_offset 337
+#define GNUTAR_rdevminor_size 6
+#define GNUTAR_rdevminor_max_size 8
+
+/*
+ * A filled-in copy of the header for initialization.
+ */
+static const char template_header[] = {
+ /* name: 100 bytes */
+ 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,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,
+ /* Mode, null termination: 8 bytes */
+ '0','0','0','0','0','0', '0','\0',
+ /* uid, null termination: 8 bytes */
+ '0','0','0','0','0','0', '0','\0',
+ /* gid, null termination: 8 bytes */
+ '0','0','0','0','0','0', '0','\0',
+ /* size, space termation: 12 bytes */
+ '0','0','0','0','0','0','0','0','0','0','0', '\0',
+ /* mtime, space termation: 12 bytes */
+ '0','0','0','0','0','0','0','0','0','0','0', '\0',
+ /* Initial checksum value: 8 spaces */
+ ' ',' ',' ',' ',' ',' ',' ',' ',
+ /* Typeflag: 1 byte */
+ '0', /* '0' = regular file */
+ /* Linkname: 100 bytes */
+ 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,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,
+ /* Magic: 8 bytes */
+ 'u','s','t','a','r',' ', ' ','\0',
+ /* Uname: 32 bytes */
+ 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,
+ /* Gname: 32 bytes */
+ 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,
+ /* rdevmajor + null padding: 8 bytes */
+ '\0','\0','\0','\0','\0','\0', '\0','\0',
+ /* rdevminor + null padding: 8 bytes */
+ '\0','\0','\0','\0','\0','\0', '\0','\0',
+ /* Padding: 167 bytes */
+ 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,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,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
+};
+
+static int archive_write_gnutar_options(struct archive_write *,
+ const char *, const char *);
+static int archive_format_gnutar_header(struct archive_write *, char h[512],
+ struct archive_entry *, int tartype);
+static int archive_write_gnutar_header(struct archive_write *,
+ struct archive_entry *entry);
+static ssize_t archive_write_gnutar_data(struct archive_write *a, const void *buff,
+ size_t s);
+static int archive_write_gnutar_free(struct archive_write *);
+static int archive_write_gnutar_close(struct archive_write *);
+static int archive_write_gnutar_finish_entry(struct archive_write *);
+static int format_256(int64_t, char *, int);
+static int format_number(int64_t, char *, int size, int maxsize);
+static int format_octal(int64_t, char *, int);
+
+/*
+ * Set output format to 'GNU tar' format.
+ */
+int
+archive_write_set_format_gnutar(struct archive *_a)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ struct gnutar *gnutar;
+
+ gnutar = (struct gnutar *)calloc(1, sizeof(*gnutar));
+ if (gnutar == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Can't allocate gnutar data");
+ return (ARCHIVE_FATAL);
+ }
+ a->format_data = gnutar;
+ a->format_name = "gnutar";
+ a->format_options = archive_write_gnutar_options;
+ a->format_write_header = archive_write_gnutar_header;
+ a->format_write_data = archive_write_gnutar_data;
+ a->format_close = archive_write_gnutar_close;
+ a->format_free = archive_write_gnutar_free;
+ a->format_finish_entry = archive_write_gnutar_finish_entry;
+ a->archive.archive_format = ARCHIVE_FORMAT_TAR_GNUTAR;
+ a->archive.archive_format_name = "GNU tar";
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_write_gnutar_options(struct archive_write *a, const char *key,
+ const char *val)
+{
+ struct gnutar *gnutar = (struct gnutar *)a->format_data;
+ int ret = ARCHIVE_FAILED;
+
+ if (strcmp(key, "hdrcharset") == 0) {
+ if (val == NULL || val[0] == 0)
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "%s: hdrcharset option needs a character-set name",
+ a->format_name);
+ else {
+ gnutar->opt_sconv = archive_string_conversion_to_charset(
+ &a->archive, val, 0);
+ if (gnutar->opt_sconv != NULL)
+ ret = ARCHIVE_OK;
+ else
+ ret = ARCHIVE_FATAL;
+ }
+ } else
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "%s: unknown keyword ``%s''", a->format_name, key);
+
+ return (ret);
+}
+
+static int
+archive_write_gnutar_close(struct archive_write *a)
+{
+ return (__archive_write_nulls(a, 512*2));
+}
+
+static int
+archive_write_gnutar_free(struct archive_write *a)
+{
+ struct gnutar *gnutar;
+
+ gnutar = (struct gnutar *)a->format_data;
+ free(gnutar);
+ a->format_data = NULL;
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_write_gnutar_finish_entry(struct archive_write *a)
+{
+ struct gnutar *gnutar;
+ int ret;
+
+ gnutar = (struct gnutar *)a->format_data;
+ ret = __archive_write_nulls(a,
+ gnutar->entry_bytes_remaining + gnutar->entry_padding);
+ gnutar->entry_bytes_remaining = gnutar->entry_padding = 0;
+ return (ret);
+}
+
+static ssize_t
+archive_write_gnutar_data(struct archive_write *a, const void *buff, size_t s)
+{
+ struct gnutar *gnutar;
+ int ret;
+
+ gnutar = (struct gnutar *)a->format_data;
+ if (s > gnutar->entry_bytes_remaining)
+ s = gnutar->entry_bytes_remaining;
+ ret = __archive_write_output(a, buff, s);
+ gnutar->entry_bytes_remaining -= s;
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ return (s);
+}
+
+static int
+archive_write_gnutar_header(struct archive_write *a,
+ struct archive_entry *entry)
+{
+ char buff[512];
+ int r, ret, ret2 = ARCHIVE_OK;
+ int tartype;
+ struct gnutar *gnutar;
+ struct archive_string_conv *sconv;
+
+ gnutar = (struct gnutar *)a->format_data;
+
+ /* Setup default string conversion. */
+ if (gnutar->opt_sconv == NULL) {
+ if (!gnutar->init_default_conversion) {
+ gnutar->sconv_default =
+ archive_string_default_conversion_for_write(
+ &(a->archive));
+ gnutar->init_default_conversion = 1;
+ }
+ sconv = gnutar->sconv_default;
+ } else
+ sconv = gnutar->opt_sconv;
+
+ /* Only regular files (not hardlinks) have data. */
+ if (archive_entry_hardlink(entry) != NULL ||
+ archive_entry_symlink(entry) != NULL ||
+ !(archive_entry_filetype(entry) == AE_IFREG))
+ archive_entry_set_size(entry, 0);
+
+ if (AE_IFDIR == archive_entry_filetype(entry)) {
+ const char *p;
+ char *t;
+ /*
+ * Ensure a trailing '/'. Modify the entry so
+ * the client sees the change.
+ */
+ p = archive_entry_pathname(entry);
+ if (p[strlen(p) - 1] != '/') {
+ t = (char *)malloc(strlen(p) + 2);
+ if (t == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate gnutar data");
+ return(ARCHIVE_FATAL);
+ }
+ strcpy(t, p);
+ strcat(t, "/");
+ archive_entry_copy_pathname(entry, t);
+ free(t);
+ }
+ }
+
+ r = archive_entry_pathname_l(entry, &(gnutar->pathname),
+ &(gnutar->pathname_length), sconv);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Pathame");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate pathname '%s' to %s",
+ archive_entry_pathname(entry),
+ archive_string_conversion_charset_name(sconv));
+ ret2 = ARCHIVE_WARN;
+ }
+ r = archive_entry_uname_l(entry, &(gnutar->uname),
+ &(gnutar->uname_length), sconv);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Uname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate uname '%s' to %s",
+ archive_entry_uname(entry),
+ archive_string_conversion_charset_name(sconv));
+ ret2 = ARCHIVE_WARN;
+ }
+ r = archive_entry_gname_l(entry, &(gnutar->gname),
+ &(gnutar->gname_length), sconv);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Gname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate gname '%s' to %s",
+ archive_entry_gname(entry),
+ archive_string_conversion_charset_name(sconv));
+ ret2 = ARCHIVE_WARN;
+ }
+
+ /* If linkname is longer than 100 chars we need to add a 'K' header. */
+ r = archive_entry_hardlink_l(entry, &(gnutar->linkname),
+ &(gnutar->linkname_length), sconv);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Linkname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate linkname '%s' to %s",
+ archive_entry_hardlink(entry),
+ archive_string_conversion_charset_name(sconv));
+ ret2 = ARCHIVE_WARN;
+ }
+ if (gnutar->linkname_length == 0) {
+ r = archive_entry_symlink_l(entry, &(gnutar->linkname),
+ &(gnutar->linkname_length), sconv);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Linkname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate linkname '%s' to %s",
+ archive_entry_hardlink(entry),
+ archive_string_conversion_charset_name(sconv));
+ ret2 = ARCHIVE_WARN;
+ }
+ }
+ if (gnutar->linkname_length > GNUTAR_linkname_size) {
+ size_t todo = gnutar->linkname_length;
+ struct archive_entry *temp = archive_entry_new2(&a->archive);
+
+ /* Uname/gname here don't really matter since noone reads them;
+ * these are the values that GNU tar happens to use on FreeBSD. */
+ archive_entry_set_uname(temp, "root");
+ archive_entry_set_gname(temp, "wheel");
+
+ archive_entry_set_pathname(temp, "././@LongLink");
+ archive_entry_set_size(temp, gnutar->linkname_length + 1);
+ ret = archive_format_gnutar_header(a, buff, temp, 'K');
+ if (ret < ARCHIVE_WARN)
+ return (ret);
+ ret = __archive_write_output(a, buff, 512);
+ if(ret < ARCHIVE_WARN)
+ return (ret);
+ archive_entry_free(temp);
+ /* Write as many 512 bytes blocks as needed to write full name. */
+ ret = __archive_write_output(a, gnutar->linkname, todo);
+ if(ret < ARCHIVE_WARN)
+ return (ret);
+ ret = __archive_write_nulls(a, 0x1ff & (-(ssize_t)todo));
+ if (ret < ARCHIVE_WARN)
+ return (ret);
+ }
+
+ /* If pathname is longer than 100 chars we need to add an 'L' header. */
+ if (gnutar->pathname_length > GNUTAR_name_size) {
+ const char *pathname = gnutar->pathname;
+ size_t todo = gnutar->pathname_length;
+ struct archive_entry *temp = archive_entry_new2(&a->archive);
+
+ /* Uname/gname here don't really matter since noone reads them;
+ * these are the values that GNU tar happens to use on FreeBSD. */
+ archive_entry_set_uname(temp, "root");
+ archive_entry_set_gname(temp, "wheel");
+
+ archive_entry_set_pathname(temp, "././@LongLink");
+ archive_entry_set_size(temp, gnutar->pathname_length + 1);
+ ret = archive_format_gnutar_header(a, buff, temp, 'L');
+ if (ret < ARCHIVE_WARN)
+ return (ret);
+ ret = __archive_write_output(a, buff, 512);
+ if(ret < ARCHIVE_WARN)
+ return (ret);
+ archive_entry_free(temp);
+ /* Write as many 512 bytes blocks as needed to write full name. */
+ ret = __archive_write_output(a, pathname, todo);
+ if(ret < ARCHIVE_WARN)
+ return (ret);
+ ret = __archive_write_nulls(a, 0x1ff & (-(ssize_t)todo));
+ if (ret < ARCHIVE_WARN)
+ return (ret);
+ }
+
+ if (archive_entry_hardlink(entry) != NULL) {
+ tartype = '1';
+ } else
+ switch (archive_entry_filetype(entry)) {
+ case AE_IFREG: tartype = '0' ; break;
+ case AE_IFLNK: tartype = '2' ; break;
+ case AE_IFCHR: tartype = '3' ; break;
+ case AE_IFBLK: tartype = '4' ; break;
+ case AE_IFDIR: tartype = '5' ; break;
+ case AE_IFIFO: tartype = '6' ; break;
+ case AE_IFSOCK:
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "tar format cannot archive socket");
+ return (ARCHIVE_FAILED);
+ default:
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "tar format cannot archive this (mode=0%lo)",
+ (unsigned long)archive_entry_mode(entry));
+ return (ARCHIVE_FAILED);
+ }
+
+ ret = archive_format_gnutar_header(a, buff, entry, tartype);
+ if (ret < ARCHIVE_WARN)
+ return (ret);
+ if (ret2 < ret)
+ ret = ret2;
+ ret2 = __archive_write_output(a, buff, 512);
+ if (ret2 < ARCHIVE_WARN)
+ return (ret2);
+ if (ret2 < ret)
+ ret = ret2;
+
+ gnutar->entry_bytes_remaining = archive_entry_size(entry);
+ gnutar->entry_padding = 0x1ff & (-(int64_t)gnutar->entry_bytes_remaining);
+ return (ret);
+}
+
+static int
+archive_format_gnutar_header(struct archive_write *a, char h[512],
+ struct archive_entry *entry, int tartype)
+{
+ unsigned int checksum;
+ int i, ret;
+ size_t copy_length;
+ const char *p;
+ struct gnutar *gnutar;
+
+ gnutar = (struct gnutar *)a->format_data;
+
+ ret = 0;
+
+ /*
+ * The "template header" already includes the signature,
+ * various end-of-field markers, and other required elements.
+ */
+ memcpy(h, &template_header, 512);
+
+ /*
+ * Because the block is already null-filled, and strings
+ * are allowed to exactly fill their destination (without null),
+ * I use memcpy(dest, src, strlen()) here a lot to copy strings.
+ */
+
+ if (tartype == 'K' || tartype == 'L') {
+ p = archive_entry_pathname(entry);
+ copy_length = strlen(p);
+ } else {
+ p = gnutar->pathname;
+ copy_length = gnutar->pathname_length;
+ }
+ if (copy_length > GNUTAR_name_size)
+ copy_length = GNUTAR_name_size;
+ memcpy(h + GNUTAR_name_offset, p, copy_length);
+
+ if ((copy_length = gnutar->linkname_length) > 0) {
+ if (copy_length > GNUTAR_linkname_size)
+ copy_length = GNUTAR_linkname_size;
+ memcpy(h + GNUTAR_linkname_offset, gnutar->linkname,
+ copy_length);
+ }
+
+ /* TODO: How does GNU tar handle unames longer than GNUTAR_uname_size? */
+ if (tartype == 'K' || tartype == 'L') {
+ p = archive_entry_uname(entry);
+ copy_length = strlen(p);
+ } else {
+ p = gnutar->uname;
+ copy_length = gnutar->uname_length;
+ }
+ if (copy_length > 0) {
+ if (copy_length > GNUTAR_uname_size)
+ copy_length = GNUTAR_uname_size;
+ memcpy(h + GNUTAR_uname_offset, p, copy_length);
+ }
+
+ /* TODO: How does GNU tar handle gnames longer than GNUTAR_gname_size? */
+ if (tartype == 'K' || tartype == 'L') {
+ p = archive_entry_gname(entry);
+ copy_length = strlen(p);
+ } else {
+ p = gnutar->gname;
+ copy_length = gnutar->gname_length;
+ }
+ if (copy_length > 0) {
+ if (strlen(p) > GNUTAR_gname_size)
+ copy_length = GNUTAR_gname_size;
+ memcpy(h + GNUTAR_gname_offset, p, copy_length);
+ }
+
+ /* By truncating the mode here, we ensure it always fits. */
+ 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)) {
+ 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)) {
+ archive_set_error(&a->archive, ERANGE,
+ "Numeric group ID %jd too large",
+ (intmax_t)archive_entry_gid(entry));
+ ret = ARCHIVE_FAILED;
+ }
+
+ /* GNU tar supports base-256 here, so should never overflow. */
+ if (format_number(archive_entry_size(entry), h + GNUTAR_size_offset,
+ GNUTAR_size_size, GNUTAR_size_max_size)) {
+ archive_set_error(&a->archive, ERANGE,
+ "File size out of range");
+ ret = ARCHIVE_FAILED;
+ }
+
+ /* Shouldn't overflow before 2106, since mtime field is 33 bits. */
+ format_octal(archive_entry_mtime(entry),
+ h + GNUTAR_mtime_offset, GNUTAR_mtime_size);
+
+ if (archive_entry_filetype(entry) == AE_IFBLK
+ || archive_entry_filetype(entry) == AE_IFCHR) {
+ if (format_octal(archive_entry_rdevmajor(entry),
+ h + GNUTAR_rdevmajor_offset,
+ GNUTAR_rdevmajor_size)) {
+ archive_set_error(&a->archive, ERANGE,
+ "Major device number too large");
+ ret = ARCHIVE_FAILED;
+ }
+
+ if (format_octal(archive_entry_rdevminor(entry),
+ h + GNUTAR_rdevminor_offset,
+ GNUTAR_rdevminor_size)) {
+ archive_set_error(&a->archive, ERANGE,
+ "Minor device number too large");
+ ret = ARCHIVE_FAILED;
+ }
+ }
+
+ h[GNUTAR_typeflag_offset] = tartype;
+
+ checksum = 0;
+ for (i = 0; i < 512; i++)
+ checksum += 255 & (unsigned int)h[i];
+ h[GNUTAR_checksum_offset + 6] = '\0'; /* Can't be pre-set in the template. */
+ /* h[GNUTAR_checksum_offset + 7] = ' '; */ /* This is pre-set in the template. */
+ format_octal(checksum, h + GNUTAR_checksum_offset, 6);
+ return (ret);
+}
+
+/*
+ * Format a number into a field, falling back to base-256 if necessary.
+ */
+static int
+format_number(int64_t v, char *p, int s, int maxsize)
+{
+ int64_t limit = ((int64_t)1 << (s*3));
+
+ if (v < limit)
+ return (format_octal(v, p, s));
+ return (format_256(v, p, maxsize));
+}
+
+/*
+ * Format a number into the specified field using base-256.
+ */
+static int
+format_256(int64_t v, char *p, int s)
+{
+ p += s;
+ while (s-- > 0) {
+ *--p = (char)(v & 0xff);
+ v >>= 8;
+ }
+ *p |= 0x80; /* Set the base-256 marker bit. */
+ return (0);
+}
+
+/*
+ * Format a number into the specified field using octal.
+ */
+static int
+format_octal(int64_t v, char *p, int s)
+{
+ int len = s;
+
+ /* Octal values can't be negative, so use 0. */
+ if (v < 0)
+ v = 0;
+
+ p += s; /* Start at the end and work backwards. */
+ while (s-- > 0) {
+ *--p = (char)('0' + (v & 7));
+ v >>= 3;
+ }
+
+ if (v == 0)
+ return (0);
+
+ /* If it overflowed, fill field with max value. */
+ while (len-- > 0)
+ *p++ = '7';
+
+ return (-1);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_iso9660.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_iso9660.c
new file mode 100644
index 000000000..0b9aaf941
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_iso9660.c
@@ -0,0 +1,8114 @@
+/*-
+ * Copyright (c) 2009-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"
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_UTSNAME_H
+#include <sys/utsname.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#include <stdio.h>
+#include <stdarg.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <time.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_ZLIB_H
+#include <cm_zlib.h>
+#endif
+
+#include "archive.h"
+#include "archive_endian.h"
+#include "archive_entry.h"
+#include "archive_entry_locale.h"
+#include "archive_private.h"
+#include "archive_rb.h"
+#include "archive_write_private.h"
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#define getuid() 0
+#define getgid() 0
+#endif
+
+/*#define DEBUG 1*/
+#ifdef DEBUG
+/* To compare to the ISO image file made by mkisofs. */
+#define COMPAT_MKISOFS 1
+#endif
+
+#define LOGICAL_BLOCK_BITS 11
+#define LOGICAL_BLOCK_SIZE 2048
+#define PATH_TABLE_BLOCK_SIZE 4096
+
+#define SYSTEM_AREA_BLOCK 16
+#define PRIMARY_VOLUME_DESCRIPTOR_BLOCK 1
+#define SUPPLEMENTARY_VOLUME_DESCRIPTOR_BLOCK 1
+#define BOOT_RECORD_DESCRIPTOR_BLOCK 1
+#define VOLUME_DESCRIPTOR_SET_TERMINATOR_BLOCK 1
+#define NON_ISO_FILE_SYSTEM_INFORMATION_BLOCK 1
+#define RRIP_ER_BLOCK 1
+#define PADDING_BLOCK 150
+
+#define FD_1_2M_SIZE (1024 * 1200)
+#define FD_1_44M_SIZE (1024 * 1440)
+#define FD_2_88M_SIZE (1024 * 2880)
+#define MULTI_EXTENT_SIZE (ARCHIVE_LITERAL_LL(1) << 32) /* 4Gi bytes. */
+#define MAX_DEPTH 8
+#define RR_CE_SIZE 28 /* SUSP "CE" extension size */
+
+#define FILE_FLAG_EXISTENCE 0x01
+#define FILE_FLAG_DIRECTORY 0x02
+#define FILE_FLAG_ASSOCIATED 0x04
+#define FILE_FLAG_RECORD 0x08
+#define FILE_FLAG_PROTECTION 0x10
+#define FILE_FLAG_MULTI_EXTENT 0x80
+
+static const char rrip_identifier[] =
+ "RRIP_1991A";
+static const char rrip_descriptor[] =
+ "THE ROCK RIDGE INTERCHANGE PROTOCOL PROVIDES SUPPORT FOR "
+ "POSIX FILE SYSTEM SEMANTICS";
+static const char rrip_source[] =
+ "PLEASE CONTACT DISC PUBLISHER FOR SPECIFICATION SOURCE. "
+ "SEE PUBLISHER IDENTIFIER IN PRIMARY VOLUME DESCRIPTOR FOR "
+ "CONTACT INFORMATION.";
+#define RRIP_ER_ID_SIZE (sizeof(rrip_identifier)-1)
+#define RRIP_ER_DSC_SIZE (sizeof(rrip_descriptor)-1)
+#define RRIP_ER_SRC_SIZE (sizeof(rrip_source)-1)
+#define RRIP_ER_SIZE (8 + RRIP_ER_ID_SIZE + \
+ RRIP_ER_DSC_SIZE + RRIP_ER_SRC_SIZE)
+
+static const unsigned char zisofs_magic[8] = {
+ 0x37, 0xE4, 0x53, 0x96, 0xC9, 0xDB, 0xD6, 0x07
+};
+
+#define ZF_HEADER_SIZE 16 /* zisofs header size. */
+#define ZF_LOG2_BS 15 /* log2 block size; 32K bytes. */
+#define ZF_BLOCK_SIZE (1UL << ZF_LOG2_BS)
+
+/*
+ * Manage extra records.
+ */
+struct extr_rec {
+ int location;
+ int offset;
+ unsigned char buf[LOGICAL_BLOCK_SIZE];
+ struct extr_rec *next;
+};
+
+struct ctl_extr_rec {
+ int use_extr;
+ unsigned char *bp;
+ struct isoent *isoent;
+ unsigned char *ce_ptr;
+ int cur_len;
+ int dr_len;
+ int limit;
+ int extr_off;
+ int extr_loc;
+};
+#define DR_SAFETY RR_CE_SIZE
+#define DR_LIMIT (254 - DR_SAFETY)
+
+/*
+ * The relation of struct isofile and isoent and archive_entry.
+ *
+ * Primary volume tree --> struct isoent
+ * |
+ * v
+ * struct isofile --> archive_entry
+ * ^
+ * |
+ * Joliet volume tree --> struct isoent
+ *
+ * struct isoent has specific information for volume.
+ */
+
+struct isofile {
+ /* Used for managing struct isofile list. */
+ struct isofile *allnext;
+ struct isofile *datanext;
+ /* Used for managing a hardlined struct isofile list. */
+ struct isofile *hlnext;
+ struct isofile *hardlink_target;
+
+ struct archive_entry *entry;
+
+ /*
+ * Used for making a directory tree.
+ */
+ struct archive_string parentdir;
+ struct archive_string basename;
+ struct archive_string basename_utf16;
+ struct archive_string symlink;
+ int dircnt; /* The number of elements of
+ * its parent directory */
+
+ /*
+ * Used for a Directory Record.
+ */
+ struct content {
+ int64_t offset_of_temp;
+ int64_t size;
+ int blocks;
+ uint32_t location;
+ /*
+ * One extent equals one content.
+ * If this entry has multi extent, `next' variable points
+ * next content data.
+ */
+ struct content *next; /* next content */
+ } content, *cur_content;
+ int write_content;
+
+ enum {
+ NO = 0,
+ BOOT_CATALOG,
+ BOOT_IMAGE
+ } boot;
+
+ /*
+ * Used for a zisofs.
+ */
+ struct {
+ unsigned char header_size;
+ unsigned char log2_bs;
+ uint32_t uncompressed_size;
+ } zisofs;
+};
+
+struct isoent {
+ /* Keep `rbnode' at the first member of struct isoent. */
+ struct archive_rb_node rbnode;
+
+ struct isofile *file;
+
+ struct isoent *parent;
+ /* A list of children.(use chnext) */
+ struct {
+ struct isoent *first;
+ struct isoent **last;
+ int cnt;
+ } children;
+ struct archive_rb_tree rbtree;
+
+ /* A list of sub directories.(use drnext) */
+ struct {
+ struct isoent *first;
+ struct isoent **last;
+ int cnt;
+ } subdirs;
+ /* A sorted list of sub directories. */
+ struct isoent **children_sorted;
+ /* Used for managing struct isoent list. */
+ struct isoent *chnext;
+ struct isoent *drnext;
+ struct isoent *ptnext;
+
+ /*
+ * Used for making a Directory Record.
+ */
+ int dir_number;
+ struct {
+ int vd;
+ int self;
+ int parent;
+ int normal;
+ } dr_len;
+ uint32_t dir_location;
+ int dir_block;
+
+ /*
+ * Identifier:
+ * on primary, ISO9660 file/directory name.
+ * on joliet, UCS2 file/directory name.
+ * ext_off : offset of identifier extension.
+ * ext_len : length of identifier extension.
+ * id_len : byte size of identifier.
+ * on primary, this is ext_off + ext_len + version length.
+ * on joliet, this is ext_off + ext_len.
+ * mb_len : length of multibyte-character of identifier.
+ * on primary, mb_len and id_len are always the same.
+ * on joliet, mb_len and id_len are different.
+ */
+ char *identifier;
+ int ext_off;
+ int ext_len;
+ int id_len;
+ int mb_len;
+
+ /*
+ * Used for making a Rockridge extension.
+ * This is a part of Directory Records.
+ */
+ struct isoent *rr_parent;
+ struct isoent *rr_child;
+
+ /* Extra Record.(which we call in this source file)
+ * A maximum size of the Directory Record is 254.
+ * so, if generated RRIP data of a file cannot into a Directory
+ * Record because of its size, that surplus data relocate this
+ * Extra Record.
+ */
+ struct {
+ struct extr_rec *first;
+ struct extr_rec **last;
+ struct extr_rec *current;
+ } extr_rec_list;
+
+ int virtual:1;
+ /* If set to one, this file type is a directory.
+ * A convenience flag to be used as
+ * "archive_entry_filetype(isoent->file->entry) == AE_IFDIR".
+ */
+ int dir:1;
+};
+
+struct hardlink {
+ struct archive_rb_node rbnode;
+ int nlink;
+ struct {
+ struct isofile *first;
+ struct isofile **last;
+ } file_list;
+};
+
+/*
+ * ISO writer options
+ */
+struct iso_option {
+ /*
+ * Usage : abstract-file=<value>
+ * Type : string, max 37 bytes
+ * Default: Not specified
+ * COMPAT : mkisofs -abstract <value>
+ *
+ * Specifies Abstract Filename.
+ * This file shall be described in the Root Directory
+ * and containing a abstract statement.
+ */
+ unsigned int abstract_file:1;
+#define OPT_ABSTRACT_FILE_DEFAULT 0 /* Not specified */
+#define ABSTRACT_FILE_SIZE 37
+
+ /*
+ * Usage : application-id=<value>
+ * Type : string, max 128 bytes
+ * Default: Not specified
+ * COMPAT : mkisofs -A/-appid <value>.
+ *
+ * Specifies Application Identifier.
+ * If the first byte is set to '_'(5F), the remaining
+ * bytes of this option shall specify an identifier
+ * for a file containing the identification of the
+ * application.
+ * This file shall be described in the Root Directory.
+ */
+ unsigned int application_id:1;
+#define OPT_APPLICATION_ID_DEFAULT 0 /* Use default identifier */
+#define APPLICATION_IDENTIFIER_SIZE 128
+
+ /*
+ * Usage : !allow-vernum
+ * Type : boolean
+ * Default: Enabled
+ * : Violates the ISO9660 standard if disable.
+ * COMPAT: mkisofs -N
+ *
+ * Allow filenames to use version numbers.
+ */
+ unsigned int allow_vernum:1;
+#define OPT_ALLOW_VERNUM_DEFAULT 1 /* Enabled */
+
+ /*
+ * Usage : biblio-file=<value>
+ * Type : string, max 37 bytes
+ * Default: Not specified
+ * COMPAT : mkisofs -biblio <value>
+ *
+ * Specifies Bibliographic Filename.
+ * This file shall be described in the Root Directory
+ * and containing bibliographic records.
+ */
+ unsigned int biblio_file:1;
+#define OPT_BIBLIO_FILE_DEFAULT 0 /* Not specified */
+#define BIBLIO_FILE_SIZE 37
+
+ /*
+ * Usage : boot=<value>
+ * Type : string
+ * Default: Not specified
+ * COMPAT : mkisofs -b/-eltorito-boot <value>
+ *
+ * Specifies "El Torito" boot image file to make
+ * a bootable CD.
+ */
+ unsigned int boot:1;
+#define OPT_BOOT_DEFAULT 0 /* Not specified */
+
+ /*
+ * Usage : boot-catalog=<value>
+ * Type : string
+ * Default: "boot.catalog"
+ * COMPAT : mkisofs -c/-eltorito-catalog <value>
+ *
+ * Specifies a fullpath of El Torito boot catalog.
+ */
+ unsigned int boot_catalog:1;
+#define OPT_BOOT_CATALOG_DEFAULT 0 /* Not specified */
+
+ /*
+ * Usage : boot-info-table
+ * Type : boolean
+ * Default: Disabled
+ * COMPAT : mkisofs -boot-info-table
+ *
+ * Modify the boot image file specified by `boot'
+ * option; ISO writer stores boot file information
+ * into the boot file in ISO image at offset 8
+ * through offset 64.
+ */
+ unsigned int boot_info_table:1;
+#define OPT_BOOT_INFO_TABLE_DEFAULT 0 /* Disabled */
+
+ /*
+ * Usage : boot-load-seg=<value>
+ * Type : hexadecimal
+ * Default: Not specified
+ * COMPAT : mkisofs -boot-load-seg <value>
+ *
+ * Specifies a load segment for boot image.
+ * This is used with no-emulation mode.
+ */
+ unsigned int boot_load_seg:1;
+#define OPT_BOOT_LOAD_SEG_DEFAULT 0 /* Not specified */
+
+ /*
+ * Usage : boot-load-size=<value>
+ * Type : decimal
+ * Default: Not specified
+ * COMPAT : mkisofs -boot-load-size <value>
+ *
+ * Specifies a sector count for boot image.
+ * This is used with no-emulation mode.
+ */
+ unsigned int boot_load_size:1;
+#define OPT_BOOT_LOAD_SIZE_DEFAULT 0 /* Not specified */
+
+ /*
+ * Usage : boot-type=<boot-media-type>
+ * : 'no-emulation' : 'no emulation' image
+ * : 'fd' : floppy disk image
+ * : 'hard-disk' : hard disk image
+ * Type : string
+ * Default: Auto detect
+ * : We check a size of boot image;
+ * : If ths size is just 1.22M/1.44M/2.88M,
+ * : we assume boot_type is 'fd';
+ * : otherwise boot_type is 'no-emulation'.
+ * COMPAT :
+ * boot=no-emulation
+ * mkisofs -no-emul-boot
+ * boot=fd
+ * This is a default on the mkisofs.
+ * boot=hard-disk
+ * mkisofs -hard-disk-boot
+ *
+ * Specifies a type of "El Torito" boot image.
+ */
+ unsigned int boot_type:2;
+#define OPT_BOOT_TYPE_AUTO 0 /* auto detect */
+#define OPT_BOOT_TYPE_NO_EMU 1 /* ``no emulation'' image */
+#define OPT_BOOT_TYPE_FD 2 /* floppy disk image */
+#define OPT_BOOT_TYPE_HARD_DISK 3 /* hard disk image */
+#define OPT_BOOT_TYPE_DEFAULT OPT_BOOT_TYPE_AUTO
+
+ /*
+ * Usage : compression-level=<value>
+ * Type : decimal
+ * Default: Not specified
+ * COMPAT : NONE
+ *
+ * Specifies compression level for option zisofs=direct.
+ */
+ unsigned int compression_level:1;
+#define OPT_COMPRESSION_LEVEL_DEFAULT 0 /* Not specified */
+
+ /*
+ * Usage : copyright-file=<value>
+ * Type : string, max 37 bytes
+ * Default: Not specified
+ * COMPAT : mkisofs -copyright <value>
+ *
+ * Specifies Copyright Filename.
+ * This file shall be described in the Root Directory
+ * and containing a copyright statement.
+ */
+ unsigned int copyright_file:1;
+#define OPT_COPYRIGHT_FILE_DEFAULT 0 /* Not specified */
+#define COPYRIGHT_FILE_SIZE 37
+
+ /*
+ * Usage : gid=<value>
+ * Type : decimal
+ * Default: Not specified
+ * COMPAT : mkisofs -gid <value>
+ *
+ * Specifies a group id to rewrite the group id of all files.
+ */
+ unsigned int gid:1;
+#define OPT_GID_DEFAULT 0 /* Not specified */
+
+ /*
+ * Usage : iso-level=[1234]
+ * Type : decimal
+ * Default: 1
+ * COMPAT : mkisofs -iso-level <value>
+ *
+ * Specifies ISO9600 Level.
+ * Level 1: [DEFAULT]
+ * - limits each file size less than 4Gi bytes;
+ * - a File Name shall not contain more than eight
+ * d-characters or eight d1-characters;
+ * - a File Name Extension shall not contain more than
+ * three d-characters or three d1-characters;
+ * - a Directory Identifier shall not contain more
+ * than eight d-characters or eight d1-characters.
+ * Level 2:
+ * - limits each file size less than 4Giga bytes;
+ * - a File Name shall not contain more than thirty
+ * d-characters or thirty d1-characters;
+ * - a File Name Extension shall not contain more than
+ * thirty d-characters or thirty d1-characters;
+ * - a Directory Identifier shall not contain more
+ * than thirty-one d-characters or thirty-one
+ * d1-characters.
+ * Level 3:
+ * - no limit of file size; use multi extent.
+ * Level 4:
+ * - this level 4 simulates mkisofs option
+ * '-iso-level 4';
+ * - crate a enhanced volume as mkisofs doing;
+ * - allow a File Name to have leading dot;
+ * - allow a File Name to have all ASCII letters;
+ * - allow a File Name to have multiple dots;
+ * - allow more then 8 depths of directory trees;
+ * - disable a version number to a File Name;
+ * - disable a forced period to the tail of a File Name;
+ * - the maxinum length of files and directories is raised to 193.
+ * if rockridge option is disabled, raised to 207.
+ */
+ unsigned int iso_level:3;
+#define OPT_ISO_LEVEL_DEFAULT 1 /* ISO Level 1 */
+
+ /*
+ * Usage : joliet[=long]
+ * : !joliet
+ * : Do not generate Joliet Volume and Records.
+ * : joliet [DEFAULT]
+ * : Generates Joliet Volume and Directory Records.
+ * : [COMPAT: mkisofs -J/-joliet]
+ * : joliet=long
+ * : The joliet filenames are up to 103 Unicode
+ * : characters.
+ * : This option breaks the Joliet specification.
+ * : [COMPAT: mkisofs -J -joliet-long]
+ * Type : boolean/string
+ * Default: Enabled
+ * COMPAT : mkisofs -J / -joliet-long
+ *
+ * Generates Joliet Volume and Directory Records.
+ */
+ unsigned int joliet:2;
+#define OPT_JOLIET_DISABLE 0 /* Not generate Joliet Records. */
+#define OPT_JOLIET_ENABLE 1 /* Generate Joliet Records. */
+#define OPT_JOLIET_LONGNAME 2 /* Use long joliet filenames.*/
+#define OPT_JOLIET_DEFAULT OPT_JOLIET_ENABLE
+
+ /*
+ * Usage : !limit-depth
+ * Type : boolean
+ * Default: Enabled
+ * : Violates the ISO9660 standard if disable.
+ * COMPAT : mkisofs -D/-disable-deep-relocation
+ *
+ * The number of levels in hierarchy cannot exceed eight.
+ */
+ unsigned int limit_depth:1;
+#define OPT_LIMIT_DEPTH_DEFAULT 1 /* Enabled */
+
+ /*
+ * Usage : !limit-dirs
+ * Type : boolean
+ * Default: Enabled
+ * : Violates the ISO9660 standard if disable.
+ * COMPAT : mkisofs -no-limit-pathtables
+ *
+ * Limits the number of directories less than 65536 due
+ * to the size of the Parent Directory Number of Path
+ * Table.
+ */
+ unsigned int limit_dirs:1;
+#define OPT_LIMIT_DIRS_DEFAULT 1 /* Enabled */
+
+ /*
+ * Usage : !pad
+ * Type : boolean
+ * Default: Enabled
+ * COMPAT : -pad/-no-pad
+ *
+ * Pads the end of the ISO image by null of 300Ki bytes.
+ */
+ unsigned int pad:1;
+#define OPT_PAD_DEFAULT 1 /* Enabled */
+
+ /*
+ * Usage : publisher=<value>
+ * Type : string, max 128 bytes
+ * Default: Not specified
+ * COMPAT : mkisofs -publisher <value>
+ *
+ * Specifies Publisher Identifier.
+ * If the first byte is set to '_'(5F), the remaining
+ * bytes of this option shall specify an identifier
+ * for a file containing the identification of the user.
+ * This file shall be described in the Root Directory.
+ */
+ unsigned int publisher:1;
+#define OPT_PUBLISHER_DEFAULT 0 /* Not specified */
+#define PUBLISHER_IDENTIFIER_SIZE 128
+
+ /*
+ * Usage : rockridge
+ * : !rockridge
+ * : disable to generate SUSP and RR records.
+ * : rockridge
+ * : the same as 'rockridge=useful'.
+ * : rockridge=strict
+ * : generate SUSP and RR records.
+ * : [COMPAT: mkisofs -R]
+ * : rockridge=useful [DEFAULT]
+ * : generate SUSP and RR records.
+ * : [COMPAT: mkisofs -r]
+ * : NOTE Our rockridge=useful option does not set a zero
+ * : to uid and gid, you should use application
+ * : option such as --gid,--gname,--uid and --uname
+ * : badtar options instead.
+ * Type : boolean/string
+ * Default: Enabled as rockridge=useful
+ * COMPAT : mkisofs -r / -R
+ *
+ * Generates SUSP and RR records.
+ */
+ unsigned int rr:2;
+#define OPT_RR_DISABLED 0
+#define OPT_RR_STRICT 1
+#define OPT_RR_USEFUL 2
+#define OPT_RR_DEFAULT OPT_RR_USEFUL
+
+ /*
+ * Usage : volume-id=<value>
+ * Type : string, max 32 bytes
+ * Default: Not specified
+ * COMPAT : mkisofs -V <value>
+ *
+ * Specifies Volume Identifier.
+ */
+ unsigned int volume_id:1;
+#define OPT_VOLUME_ID_DEFAULT 0 /* Use default identifier */
+#define VOLUME_IDENTIFIER_SIZE 32
+
+ /*
+ * Usage : !zisofs [DEFAULT]
+ * : Disable to generate RRIP 'ZF' extension.
+ * : zisofs
+ * : Make files zisofs file and generate RRIP 'ZF'
+ * : extension. So you do not need mkzftree utility
+ * : for making zisofs.
+ * : When the file size is less than one Logical Block
+ * : size, that file will not zisofs'ed since it does
+ * : reduece an ISO-image size.
+ * :
+ * : When you specify option 'boot=<boot-image>', that
+ * : 'boot-image' file won't be converted to zisofs file.
+ * Type : boolean
+ * Default: Disabled
+ *
+ * Generates RRIP 'ZF' System Use Entry.
+ */
+ unsigned int zisofs:1;
+#define OPT_ZISOFS_DISABLED 0
+#define OPT_ZISOFS_DIRECT 1
+#define OPT_ZISOFS_DEFAULT OPT_ZISOFS_DISABLED
+
+};
+
+struct iso9660 {
+ /* The creation time of ISO image. */
+ time_t birth_time;
+ /* A file stream of a temporary file, which file contents
+ * save to until ISO iamge can be created. */
+ int temp_fd;
+
+ struct isofile *cur_file;
+ struct isoent *cur_dirent;
+ struct archive_string cur_dirstr;
+ uint64_t bytes_remaining;
+ int need_multi_extent;
+
+ /* Temporary string buffer for Joliet extension. */
+ struct archive_string utf16be;
+ struct archive_string mbs;
+
+ struct archive_string_conv *sconv_to_utf16be;
+ struct archive_string_conv *sconv_from_utf16be;
+
+ /* A list of all of struct isofile entries. */
+ struct {
+ struct isofile *first;
+ struct isofile **last;
+ } all_file_list;
+
+ /* A list of struct isofile entries which have its
+ * contents and are not a directory, a hardlined file
+ * and a symlink file. */
+ struct {
+ struct isofile *first;
+ struct isofile **last;
+ } data_file_list;
+
+ /* Used for managing to find hardlinking files. */
+ struct archive_rb_tree hardlink_rbtree;
+
+ /* Used for making the Path Table Record. */
+ struct vdd {
+ /* the root of entry tree. */
+ struct isoent *rootent;
+ enum vdd_type {
+ VDD_PRIMARY,
+ VDD_JOLIET,
+ VDD_ENHANCED
+ } vdd_type;
+
+ struct path_table {
+ struct isoent *first;
+ struct isoent **last;
+ struct isoent **sorted;
+ int cnt;
+ } *pathtbl;
+ int max_depth;
+
+ int path_table_block;
+ int path_table_size;
+ int location_type_L_path_table;
+ int location_type_M_path_table;
+ int total_dir_block;
+ } primary, joliet;
+
+ /* Used for making a Volume Descriptor. */
+ int volume_space_size;
+ int volume_sequence_number;
+ int total_file_block;
+ struct archive_string volume_identifier;
+ struct archive_string publisher_identifier;
+ struct archive_string data_preparer_identifier;
+ struct archive_string application_identifier;
+ struct archive_string copyright_file_identifier;
+ struct archive_string abstract_file_identifier;
+ struct archive_string bibliographic_file_identifier;
+
+ /* Used for making rockridge extensions. */
+ int location_rrip_er;
+
+ /* Used for making zisofs. */
+ struct {
+ int detect_magic:1;
+ int making:1;
+ int allzero:1;
+ unsigned char magic_buffer[64];
+ int magic_cnt;
+
+#ifdef HAVE_ZLIB_H
+ /*
+ * Copy a compressed file to iso9660.zisofs.temp_fd
+ * and also copy a uncompressed file(original file) to
+ * iso9660.temp_fd . If the number of logical block
+ * of the compressed file is less than the number of
+ * logical block of the uncompressed file, use it and
+ * remove the copy of the uncompressed file.
+ * but if not, we use uncompressed file and remove
+ * the copy of the compressed file.
+ */
+ uint32_t *block_pointers;
+ size_t block_pointers_allocated;
+ int block_pointers_cnt;
+ int block_pointers_idx;
+ int64_t total_size;
+ int64_t block_offset;
+
+ z_stream stream;
+ int stream_valid;
+ int64_t remaining;
+ int compression_level;
+#endif
+ } zisofs;
+
+ struct isoent *directories_too_deep;
+ int dircnt_max;
+
+ /* Write buffer. */
+#define wb_buffmax() (LOGICAL_BLOCK_SIZE * 32)
+#define wb_remaining(a) (((struct iso9660 *)(a)->format_data)->wbuff_remaining)
+#define wb_offset(a) (((struct iso9660 *)(a)->format_data)->wbuff_offset \
+ + wb_buffmax() - wb_remaining(a))
+ unsigned char wbuff[LOGICAL_BLOCK_SIZE * 32];
+ size_t wbuff_remaining;
+ enum {
+ WB_TO_STREAM,
+ WB_TO_TEMP
+ } wbuff_type;
+ int64_t wbuff_offset;
+ int64_t wbuff_written;
+ int64_t wbuff_tail;
+
+ /* 'El Torito' boot data. */
+ struct {
+ /* boot catalog file */
+ struct archive_string catalog_filename;
+ struct isoent *catalog;
+ /* boot image file */
+ struct archive_string boot_filename;
+ struct isoent *boot;
+
+ unsigned char platform_id;
+#define BOOT_PLATFORM_X86 0
+#define BOOT_PLATFORM_PPC 1
+#define BOOT_PLATFORM_MAC 2
+ struct archive_string id;
+ unsigned char media_type;
+#define BOOT_MEDIA_NO_EMULATION 0
+#define BOOT_MEDIA_1_2M_DISKETTE 1
+#define BOOT_MEDIA_1_44M_DISKETTE 2
+#define BOOT_MEDIA_2_88M_DISKETTE 3
+#define BOOT_MEDIA_HARD_DISK 4
+ unsigned char system_type;
+ uint16_t boot_load_seg;
+ uint16_t boot_load_size;
+#define BOOT_LOAD_SIZE 4
+ } el_torito;
+
+ struct iso_option opt;
+};
+
+/*
+ * Types of Volume Descriptor
+ */
+enum VD_type {
+ VDT_BOOT_RECORD=0, /* Boot Record Volume Descriptor */
+ VDT_PRIMARY=1, /* Primary Volume Descriptor */
+ VDT_SUPPLEMENTARY=2, /* Supplementary Volume Descriptor */
+ VDT_TERMINATOR=255 /* Volume Descriptor Set Terminator */
+};
+
+/*
+ * Types of Directory Record
+ */
+enum dir_rec_type {
+ DIR_REC_VD, /* Stored in Volume Descriptor. */
+ DIR_REC_SELF, /* Stored as Current Directory. */
+ DIR_REC_PARENT, /* Stored as Parent Directory. */
+ DIR_REC_NORMAL /* Stored as Child. */
+};
+
+/*
+ * Kinds of Volume Descriptor Character
+ */
+enum vdc {
+ VDC_STD,
+ VDC_LOWERCASE,
+ VDC_UCS2,
+ VDC_UCS2_DIRECT
+};
+
+/*
+ * IDentifier Resolver.
+ * Used for resolving duplicated filenames.
+ */
+struct idr {
+ struct idrent {
+ struct archive_rb_node rbnode;
+ /* Used in wait_list. */
+ struct idrent *wnext;
+ struct idrent *avail;
+
+ struct isoent *isoent;
+ int weight;
+ int noff;
+ int rename_num;
+ } *idrent_pool;
+
+ struct archive_rb_tree rbtree;
+
+ struct {
+ struct idrent *first;
+ struct idrent **last;
+ } wait_list;
+
+ int pool_size;
+ int pool_idx;
+ int num_size;
+ int null_size;
+
+ char char_map[0x80];
+};
+
+enum char_type {
+ A_CHAR,
+ D_CHAR
+};
+
+
+static int iso9660_options(struct archive_write *,
+ const char *, const char *);
+static int iso9660_write_header(struct archive_write *,
+ struct archive_entry *);
+static ssize_t iso9660_write_data(struct archive_write *,
+ const void *, size_t);
+static int iso9660_finish_entry(struct archive_write *);
+static int iso9660_close(struct archive_write *);
+static int iso9660_free(struct archive_write *);
+
+static void get_system_identitier(char *, size_t);
+static void set_str(unsigned char *, const char *, size_t, char,
+ const char *);
+static inline int joliet_allowed_char(unsigned char, unsigned char);
+static int set_str_utf16be(struct archive_write *, unsigned char *,
+ const char *, size_t, uint16_t, enum vdc);
+static int set_str_a_characters_bp(struct archive_write *,
+ unsigned char *, int, int, const char *, enum vdc);
+static int set_str_d_characters_bp(struct archive_write *,
+ unsigned char *, int, int, const char *, enum vdc);
+static void set_VD_bp(unsigned char *, enum VD_type, unsigned char);
+static inline void set_unused_field_bp(unsigned char *, int, int);
+
+static unsigned char *extra_open_record(unsigned char *, int,
+ struct isoent *, struct ctl_extr_rec *);
+static void extra_close_record(struct ctl_extr_rec *, int);
+static unsigned char * extra_next_record(struct ctl_extr_rec *, int);
+static unsigned char *extra_get_record(struct isoent *, int *, int *, int *);
+static void extra_tell_used_size(struct ctl_extr_rec *, int);
+static int extra_setup_location(struct isoent *, int);
+static int set_directory_record_rr(unsigned char *, int,
+ struct isoent *, struct iso9660 *, enum dir_rec_type);
+static int set_directory_record(unsigned char *, size_t,
+ struct isoent *, struct iso9660 *, enum dir_rec_type,
+ enum vdd_type);
+static inline int get_dir_rec_size(struct iso9660 *, struct isoent *,
+ enum dir_rec_type, enum vdd_type);
+static inline unsigned char *wb_buffptr(struct archive_write *);
+static int wb_write_out(struct archive_write *);
+static int wb_consume(struct archive_write *, size_t);
+#ifdef HAVE_ZLIB_H
+static int wb_set_offset(struct archive_write *, int64_t);
+#endif
+static int write_null(struct archive_write *, size_t);
+static int write_VD_terminator(struct archive_write *);
+static int set_file_identifier(unsigned char *, int, int, enum vdc,
+ struct archive_write *, struct vdd *,
+ struct archive_string *, const char *, int,
+ enum char_type);
+static int write_VD(struct archive_write *, struct vdd *);
+static int write_VD_boot_record(struct archive_write *);
+static int write_information_block(struct archive_write *);
+static int write_path_table(struct archive_write *, int,
+ struct vdd *);
+static int write_directory_descriptors(struct archive_write *,
+ struct vdd *);
+static int write_file_descriptors(struct archive_write *);
+static int write_rr_ER(struct archive_write *);
+static void calculate_path_table_size(struct vdd *);
+
+static void isofile_init_entry_list(struct iso9660 *);
+static void isofile_add_entry(struct iso9660 *, struct isofile *);
+static void isofile_free_all_entries(struct iso9660 *);
+static void isofile_init_entry_data_file_list(struct iso9660 *);
+static void isofile_add_data_file(struct iso9660 *, struct isofile *);
+static struct isofile * isofile_new(struct archive_write *,
+ struct archive_entry *);
+static void isofile_free(struct isofile *);
+static int isofile_gen_utility_names(struct archive_write *,
+ struct isofile *);
+static int isofile_register_hardlink(struct archive_write *,
+ struct isofile *);
+static void isofile_connect_hardlink_files(struct iso9660 *);
+static void isofile_init_hardlinks(struct iso9660 *);
+static void isofile_free_hardlinks(struct iso9660 *);
+
+static struct isoent *isoent_new(struct isofile *);
+static int isoent_clone_tree(struct archive_write *,
+ struct isoent **, struct isoent *);
+static void _isoent_free(struct isoent *isoent);
+static void isoent_free_all(struct isoent *);
+static struct isoent * isoent_create_virtual_dir(struct archive_write *,
+ struct iso9660 *, const char *);
+static int isoent_cmp_node(const struct archive_rb_node *,
+ const struct archive_rb_node *);
+static int isoent_cmp_key(const struct archive_rb_node *,
+ const void *);
+static int isoent_add_child_head(struct isoent *, struct isoent *);
+static int isoent_add_child_tail(struct isoent *, struct isoent *);
+static void isoent_remove_child(struct isoent *, struct isoent *);
+static void isoent_setup_directory_location(struct iso9660 *,
+ int, struct vdd *);
+static void isoent_setup_file_location(struct iso9660 *, int);
+static int get_path_component(char *, int, const char *);
+static int isoent_tree(struct archive_write *, struct isoent **);
+static struct isoent *isoent_find_child(struct isoent *, const char *);
+static struct isoent *isoent_find_entry(struct isoent *, const char *);
+static void idr_relaxed_filenames(char *);
+static void idr_init(struct iso9660 *, struct vdd *, struct idr *);
+static void idr_cleanup(struct idr *);
+static int idr_ensure_poolsize(struct archive_write *, struct idr *,
+ int);
+static int idr_start(struct archive_write *, struct idr *,
+ int, int, int, int, const struct archive_rb_tree_ops *);
+static void idr_register(struct idr *, struct isoent *, int,
+ int);
+static void idr_extend_identifier(struct idrent *, int, int);
+static void idr_resolve(struct idr *, void (*)(unsigned char *, int));
+static void idr_set_num(unsigned char *, int);
+static void idr_set_num_beutf16(unsigned char *, int);
+static int isoent_gen_iso9660_identifier(struct archive_write *,
+ struct isoent *, struct idr *);
+static int isoent_gen_joliet_identifier(struct archive_write *,
+ struct isoent *, struct idr *);
+static int isoent_cmp_iso9660_identifier(const struct isoent *,
+ const struct isoent *);
+static int isoent_cmp_node_iso9660(const struct archive_rb_node *,
+ const struct archive_rb_node *);
+static int isoent_cmp_key_iso9660(const struct archive_rb_node *,
+ const void *);
+static int isoent_cmp_joliet_identifier(const struct isoent *,
+ const struct isoent *);
+static int isoent_cmp_node_joliet(const struct archive_rb_node *,
+ const struct archive_rb_node *);
+static int isoent_cmp_key_joliet(const struct archive_rb_node *,
+ const void *);
+static inline void path_table_add_entry(struct path_table *, struct isoent *);
+static inline struct isoent * path_table_last_entry(struct path_table *);
+static int isoent_make_path_table(struct archive_write *);
+static int isoent_find_out_boot_file(struct archive_write *,
+ struct isoent *);
+static int isoent_create_boot_catalog(struct archive_write *,
+ struct isoent *);
+static size_t fd_boot_image_size(int);
+static int make_boot_catalog(struct archive_write *);
+static int setup_boot_information(struct archive_write *);
+
+static int zisofs_init(struct archive_write *, struct isofile *);
+static void zisofs_detect_magic(struct archive_write *,
+ const void *, size_t);
+static int zisofs_write_to_temp(struct archive_write *,
+ const void *, size_t);
+static int zisofs_finish_entry(struct archive_write *);
+static int zisofs_rewind_boot_file(struct archive_write *);
+static int zisofs_free(struct archive_write *);
+
+int
+archive_write_set_format_iso9660(struct archive *_a)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ struct iso9660 *iso9660;
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_iso9660");
+
+ /* If another format was already registered, unregister it. */
+ if (a->format_free != NULL)
+ (a->format_free)(a);
+
+ iso9660 = calloc(1, sizeof(*iso9660));
+ if (iso9660 == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate iso9660 data");
+ return (ARCHIVE_FATAL);
+ }
+ iso9660->birth_time = 0;
+ iso9660->temp_fd = -1;
+ iso9660->cur_file = NULL;
+ iso9660->primary.max_depth = 0;
+ iso9660->primary.vdd_type = VDD_PRIMARY;
+ iso9660->primary.pathtbl = NULL;
+ iso9660->joliet.rootent = NULL;
+ iso9660->joliet.max_depth = 0;
+ iso9660->joliet.vdd_type = VDD_JOLIET;
+ iso9660->joliet.pathtbl = NULL;
+ isofile_init_entry_list(iso9660);
+ isofile_init_entry_data_file_list(iso9660);
+ isofile_init_hardlinks(iso9660);
+ iso9660->directories_too_deep = NULL;
+ iso9660->dircnt_max = 1;
+ iso9660->wbuff_remaining = wb_buffmax();
+ iso9660->wbuff_type = WB_TO_TEMP;
+ iso9660->wbuff_offset = 0;
+ iso9660->wbuff_written = 0;
+ iso9660->wbuff_tail = 0;
+ archive_string_init(&(iso9660->utf16be));
+ archive_string_init(&(iso9660->mbs));
+
+ /*
+ * Init Identifiers used for PVD and SVD.
+ */
+ archive_string_init(&(iso9660->volume_identifier));
+ archive_strcpy(&(iso9660->volume_identifier), "CDROM");
+ archive_string_init(&(iso9660->publisher_identifier));
+ archive_string_init(&(iso9660->data_preparer_identifier));
+ archive_string_init(&(iso9660->application_identifier));
+ archive_strcpy(&(iso9660->application_identifier),
+ archive_version_string());
+ archive_string_init(&(iso9660->copyright_file_identifier));
+ archive_string_init(&(iso9660->abstract_file_identifier));
+ archive_string_init(&(iso9660->bibliographic_file_identifier));
+
+ /*
+ * Init El Torito bootable CD variables.
+ */
+ archive_string_init(&(iso9660->el_torito.catalog_filename));
+ iso9660->el_torito.catalog = NULL;
+ /* Set default file name of boot catalog */
+ archive_strcpy(&(iso9660->el_torito.catalog_filename),
+ "boot.catalog");
+ archive_string_init(&(iso9660->el_torito.boot_filename));
+ iso9660->el_torito.boot = NULL;
+ iso9660->el_torito.platform_id = BOOT_PLATFORM_X86;
+ archive_string_init(&(iso9660->el_torito.id));
+ iso9660->el_torito.boot_load_seg = 0;
+ iso9660->el_torito.boot_load_size = BOOT_LOAD_SIZE;
+
+ /*
+ * Init zisofs variables.
+ */
+#ifdef HAVE_ZLIB_H
+ iso9660->zisofs.block_pointers = NULL;
+ iso9660->zisofs.block_pointers_allocated = 0;
+ iso9660->zisofs.stream_valid = 0;
+ iso9660->zisofs.compression_level = 9;
+ memset(&(iso9660->zisofs.stream), 0,
+ sizeof(iso9660->zisofs.stream));
+#endif
+
+ /*
+ * Set default value of iso9660 options.
+ */
+ iso9660->opt.abstract_file = OPT_ABSTRACT_FILE_DEFAULT;
+ iso9660->opt.application_id = OPT_APPLICATION_ID_DEFAULT;
+ iso9660->opt.allow_vernum = OPT_ALLOW_VERNUM_DEFAULT;
+ iso9660->opt.biblio_file = OPT_BIBLIO_FILE_DEFAULT;
+ iso9660->opt.boot = OPT_BOOT_DEFAULT;
+ iso9660->opt.boot_catalog = OPT_BOOT_CATALOG_DEFAULT;
+ iso9660->opt.boot_info_table = OPT_BOOT_INFO_TABLE_DEFAULT;
+ iso9660->opt.boot_load_seg = OPT_BOOT_LOAD_SEG_DEFAULT;
+ iso9660->opt.boot_load_size = OPT_BOOT_LOAD_SIZE_DEFAULT;
+ iso9660->opt.boot_type = OPT_BOOT_TYPE_DEFAULT;
+ iso9660->opt.compression_level = OPT_COMPRESSION_LEVEL_DEFAULT;
+ iso9660->opt.copyright_file = OPT_COPYRIGHT_FILE_DEFAULT;
+ iso9660->opt.iso_level = OPT_ISO_LEVEL_DEFAULT;
+ iso9660->opt.joliet = OPT_JOLIET_DEFAULT;
+ iso9660->opt.limit_depth = OPT_LIMIT_DEPTH_DEFAULT;
+ iso9660->opt.limit_dirs = OPT_LIMIT_DIRS_DEFAULT;
+ iso9660->opt.pad = OPT_PAD_DEFAULT;
+ iso9660->opt.publisher = OPT_PUBLISHER_DEFAULT;
+ iso9660->opt.rr = OPT_RR_DEFAULT;
+ iso9660->opt.volume_id = OPT_VOLUME_ID_DEFAULT;
+ iso9660->opt.zisofs = OPT_ZISOFS_DEFAULT;
+
+ /* Create the root directory. */
+ iso9660->primary.rootent =
+ isoent_create_virtual_dir(a, iso9660, "");
+ if (iso9660->primary.rootent == NULL) {
+ free(iso9660);
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+ iso9660->primary.rootent->parent = iso9660->primary.rootent;
+ iso9660->cur_dirent = iso9660->primary.rootent;
+ archive_string_init(&(iso9660->cur_dirstr));
+ archive_string_ensure(&(iso9660->cur_dirstr), 1);
+ iso9660->cur_dirstr.s[0] = 0;
+ iso9660->sconv_to_utf16be = NULL;
+ iso9660->sconv_from_utf16be = NULL;
+
+ a->format_data = iso9660;
+ a->format_name = "iso9660";
+ a->format_options = iso9660_options;
+ a->format_write_header = iso9660_write_header;
+ a->format_write_data = iso9660_write_data;
+ a->format_finish_entry = iso9660_finish_entry;
+ a->format_close = iso9660_close;
+ a->format_free = iso9660_free;
+ a->archive.archive_format = ARCHIVE_FORMAT_ISO9660;
+ a->archive.archive_format_name = "ISO9660";
+
+ return (ARCHIVE_OK);
+}
+
+static int
+get_str_opt(struct archive_write *a, struct archive_string *s,
+ size_t maxsize, const char *key, const char *value)
+{
+
+ if (strlen(value) > maxsize) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Value is longer than %zu characters "
+ "for option ``%s''", maxsize, key);
+ return (ARCHIVE_FATAL);
+ }
+ archive_strcpy(s, value);
+ return (ARCHIVE_OK);
+}
+
+static int
+get_num_opt(struct archive_write *a, int *num, int high, int low,
+ const char *key, const char *value)
+{
+ const char *p = value;
+ int data = 0;
+ int neg = 0;
+
+ if (p == NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Invalid value(empty) for option ``%s''", key);
+ return (ARCHIVE_FATAL);
+ }
+ if (*p == '-') {
+ neg = 1;
+ p++;
+ }
+ while (*p) {
+ if (*p >= '0' && *p <= '9')
+ data = data * 10 + *p - '0';
+ else {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Invalid value for option ``%s''", key);
+ return (ARCHIVE_FATAL);
+ }
+ if (data > high) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Invalid value(over %d) for "
+ "option ``%s''", high, key);
+ return (ARCHIVE_FATAL);
+ }
+ if (data < low) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Invalid value(under %d) for "
+ "option ``%s''", low, key);
+ return (ARCHIVE_FATAL);
+ }
+ p++;
+ }
+ if (neg)
+ data *= -1;
+ *num = data;
+
+ return (ARCHIVE_OK);
+}
+
+static int
+iso9660_options(struct archive_write *a, const char *key, const char *value)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ const char *p;
+ int r;
+
+ switch (key[0]) {
+ case 'a':
+ if (strcmp(key, "abstract-file") == 0) {
+ r = get_str_opt(a,
+ &(iso9660->abstract_file_identifier),
+ ABSTRACT_FILE_SIZE, key, value);
+ iso9660->opt.abstract_file = r == ARCHIVE_OK;
+ return (r);
+ }
+ if (strcmp(key, "application-id") == 0) {
+ r = get_str_opt(a,
+ &(iso9660->application_identifier),
+ APPLICATION_IDENTIFIER_SIZE, key, value);
+ iso9660->opt.application_id = r == ARCHIVE_OK;
+ return (r);
+ }
+ if (strcmp(key, "allow-vernum") == 0) {
+ iso9660->opt.allow_vernum = value != NULL;
+ return (ARCHIVE_OK);
+ }
+ break;
+ case 'b':
+ if (strcmp(key, "biblio-file") == 0) {
+ r = get_str_opt(a,
+ &(iso9660->bibliographic_file_identifier),
+ BIBLIO_FILE_SIZE, key, value);
+ iso9660->opt.biblio_file = r == ARCHIVE_OK;
+ return (r);
+ }
+ if (strcmp(key, "boot") == 0) {
+ if (value == NULL)
+ iso9660->opt.boot = 0;
+ else {
+ iso9660->opt.boot = 1;
+ archive_strcpy(
+ &(iso9660->el_torito.boot_filename),
+ value);
+ }
+ return (ARCHIVE_OK);
+ }
+ if (strcmp(key, "boot-catalog") == 0) {
+ r = get_str_opt(a,
+ &(iso9660->el_torito.catalog_filename),
+ 1024, key, value);
+ iso9660->opt.boot_catalog = r == ARCHIVE_OK;
+ return (r);
+ }
+ if (strcmp(key, "boot-info-table") == 0) {
+ iso9660->opt.boot_info_table = value != NULL;
+ return (ARCHIVE_OK);
+ }
+ if (strcmp(key, "boot-load-seg") == 0) {
+ uint32_t seg;
+
+ iso9660->opt.boot_load_seg = 0;
+ if (value == NULL)
+ goto invalid_value;
+ seg = 0;
+ p = value;
+ if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X'))
+ p += 2;
+ while (*p) {
+ if (seg)
+ seg <<= 4;
+ if (*p >= 'A' && *p <= 'F')
+ seg += *p - 'A' + 0x0a;
+ else if (*p >= 'a' && *p <= 'f')
+ seg += *p - 'a' + 0x0a;
+ else if (*p >= '0' && *p <= '9')
+ seg += *p - '0';
+ else
+ goto invalid_value;
+ if (seg > 0xffff) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Invalid value(over 0xffff) for "
+ "option ``%s''", key);
+ return (ARCHIVE_FATAL);
+ }
+ p++;
+ }
+ iso9660->el_torito.boot_load_seg = (uint16_t)seg;
+ iso9660->opt.boot_load_seg = 1;
+ return (ARCHIVE_OK);
+ }
+ if (strcmp(key, "boot-load-size") == 0) {
+ int num = 0;
+ r = get_num_opt(a, &num, 0xffff, 1, key, value);
+ iso9660->opt.boot_load_size = r == ARCHIVE_OK;
+ if (r != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ iso9660->el_torito.boot_load_size = (uint16_t)num;
+ return (ARCHIVE_OK);
+ }
+ if (strcmp(key, "boot-type") == 0) {
+ if (value == NULL)
+ goto invalid_value;
+ if (strcmp(value, "no-emulation") == 0)
+ iso9660->opt.boot_type = OPT_BOOT_TYPE_NO_EMU;
+ else if (strcmp(value, "fd") == 0)
+ iso9660->opt.boot_type = OPT_BOOT_TYPE_FD;
+ else if (strcmp(value, "hard-disk") == 0)
+ iso9660->opt.boot_type = OPT_BOOT_TYPE_HARD_DISK;
+ else
+ goto invalid_value;
+ return (ARCHIVE_OK);
+ }
+ break;
+ case 'c':
+ if (strcmp(key, "compression-level") == 0) {
+#ifdef HAVE_ZLIB_H
+ if (value == NULL ||
+ !(value[0] >= '0' && value[0] <= '9') ||
+ value[1] != '\0')
+ goto invalid_value;
+ iso9660->zisofs.compression_level = value[0] - '0';
+ iso9660->opt.compression_level = 1;
+ return (ARCHIVE_OK);
+#else
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Option ``%s'' "
+ "is not supported on this platform.", key);
+ return (ARCHIVE_FATAL);
+#endif
+ }
+ if (strcmp(key, "copyright-file") == 0) {
+ r = get_str_opt(a,
+ &(iso9660->copyright_file_identifier),
+ COPYRIGHT_FILE_SIZE, key, value);
+ iso9660->opt.copyright_file = r == ARCHIVE_OK;
+ return (r);
+ }
+#ifdef DEBUG
+ /* Specifies Volume creation date and time;
+ * year(4),month(2),day(2),hour(2),minute(2),second(2).
+ * e.g. "20090929033757"
+ */
+ if (strcmp(key, "creation") == 0) {
+ struct tm tm;
+ char buf[5];
+
+ p = value;
+ if (p == NULL || strlen(p) < 14)
+ goto invalid_value;
+ memset(&tm, 0, sizeof(tm));
+ memcpy(buf, p, 4); buf[4] = '\0'; p += 4;
+ tm.tm_year = strtol(buf, NULL, 10) - 1900;
+ memcpy(buf, p, 2); buf[2] = '\0'; p += 2;
+ tm.tm_mon = strtol(buf, NULL, 10) - 1;
+ memcpy(buf, p, 2); buf[2] = '\0'; p += 2;
+ tm.tm_mday = strtol(buf, NULL, 10);
+ memcpy(buf, p, 2); buf[2] = '\0'; p += 2;
+ tm.tm_hour = strtol(buf, NULL, 10);
+ memcpy(buf, p, 2); buf[2] = '\0'; p += 2;
+ tm.tm_min = strtol(buf, NULL, 10);
+ memcpy(buf, p, 2); buf[2] = '\0';
+ tm.tm_sec = strtol(buf, NULL, 10);
+ iso9660->birth_time = mktime(&tm);
+ return (ARCHIVE_OK);
+ }
+#endif
+ break;
+ case 'i':
+ if (strcmp(key, "iso-level") == 0) {
+ if (value != NULL && value[1] == '\0' &&
+ (value[0] >= '1' && value[0] <= '4')) {
+ iso9660->opt.iso_level = value[0]-'0';
+ return (ARCHIVE_OK);
+ }
+ goto invalid_value;
+ }
+ break;
+ case 'j':
+ if (strcmp(key, "joliet") == 0) {
+ if (value == NULL)
+ iso9660->opt.joliet = OPT_JOLIET_DISABLE;
+ else if (strcmp(value, "1") == 0)
+ iso9660->opt.joliet = OPT_JOLIET_ENABLE;
+ else if (strcmp(value, "long") == 0)
+ iso9660->opt.joliet = OPT_JOLIET_LONGNAME;
+ else
+ goto invalid_value;
+ return (ARCHIVE_OK);
+ }
+ break;
+ case 'l':
+ if (strcmp(key, "limit-depth") == 0) {
+ iso9660->opt.limit_depth = value != NULL;
+ return (ARCHIVE_OK);
+ }
+ if (strcmp(key, "limit-dirs") == 0) {
+ iso9660->opt.limit_dirs = value != NULL;
+ return (ARCHIVE_OK);
+ }
+ break;
+ case 'p':
+ if (strcmp(key, "pad") == 0) {
+ iso9660->opt.pad = value != NULL;
+ return (ARCHIVE_OK);
+ }
+ if (strcmp(key, "publisher") == 0) {
+ r = get_str_opt(a,
+ &(iso9660->publisher_identifier),
+ PUBLISHER_IDENTIFIER_SIZE, key, value);
+ iso9660->opt.publisher = r == ARCHIVE_OK;
+ return (r);
+ }
+ break;
+ case 'r':
+ if (strcmp(key, "rockridge") == 0 ||
+ strcmp(key, "Rockridge") == 0) {
+ if (value == NULL)
+ iso9660->opt.rr = OPT_RR_DISABLED;
+ else if (strcmp(value, "1") == 0)
+ iso9660->opt.rr = OPT_RR_USEFUL;
+ else if (strcmp(value, "strict") == 0)
+ iso9660->opt.rr = OPT_RR_STRICT;
+ else if (strcmp(value, "useful") == 0)
+ iso9660->opt.rr = OPT_RR_USEFUL;
+ else
+ goto invalid_value;
+ return (ARCHIVE_OK);
+ }
+ break;
+ case 'v':
+ if (strcmp(key, "volume-id") == 0) {
+ r = get_str_opt(a, &(iso9660->volume_identifier),
+ VOLUME_IDENTIFIER_SIZE, key, value);
+ iso9660->opt.volume_id = r == ARCHIVE_OK;
+ return (r);
+ }
+ break;
+ case 'z':
+ if (strcmp(key, "zisofs") == 0) {
+ if (value == NULL)
+ iso9660->opt.zisofs = OPT_ZISOFS_DISABLED;
+ else {
+#ifdef HAVE_ZLIB_H
+ iso9660->opt.zisofs = OPT_ZISOFS_DIRECT;
+#else
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "``zisofs'' "
+ "is not supported on this platform.");
+ return (ARCHIVE_FATAL);
+#endif
+ }
+ return (ARCHIVE_OK);
+ }
+ break;
+ }
+
+invalid_value:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Invalid value for option ``%s''", key);
+ return (ARCHIVE_FAILED);
+}
+
+static int
+iso9660_write_header(struct archive_write *a, struct archive_entry *entry)
+{
+ struct iso9660 *iso9660;
+ struct isofile *file;
+ struct isoent *isoent;
+ int r, ret = ARCHIVE_OK;
+
+ iso9660 = a->format_data;
+
+ iso9660->cur_file = NULL;
+ iso9660->bytes_remaining = 0;
+ iso9660->need_multi_extent = 0;
+ if (archive_entry_filetype(entry) == AE_IFLNK
+ && iso9660->opt.rr == OPT_RR_DISABLED) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Ignore symlink file.");
+ iso9660->cur_file = NULL;
+ return (ARCHIVE_WARN);
+ }
+ if (archive_entry_filetype(entry) == AE_IFREG &&
+ archive_entry_size(entry) >= MULTI_EXTENT_SIZE) {
+ if (iso9660->opt.iso_level < 3) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Ignore over %lld bytes file. "
+ "This file too large.",
+ MULTI_EXTENT_SIZE);
+ iso9660->cur_file = NULL;
+ return (ARCHIVE_WARN);
+ }
+ iso9660->need_multi_extent = 1;
+ }
+
+ file = isofile_new(a, entry);
+ if (file == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate data");
+ return (ARCHIVE_FATAL);
+ }
+ r = isofile_gen_utility_names(a, file);
+ if (r < ARCHIVE_WARN) {
+ isofile_free(file);
+ return (r);
+ }
+ else if (r < ret)
+ ret = r;
+
+ /*
+ * Ignore a path which looks like the top of directory name
+ * since we have already made the root directory of an ISO image.
+ */
+ if (archive_strlen(&(file->parentdir)) == 0 &&
+ archive_strlen(&(file->basename)) == 0) {
+ isofile_free(file);
+ return (r);
+ }
+
+ isofile_add_entry(iso9660, file);
+ isoent = isoent_new(file);
+ if (isoent == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate data");
+ return (ARCHIVE_FATAL);
+ }
+ if (isoent->file->dircnt > iso9660->dircnt_max)
+ iso9660->dircnt_max = isoent->file->dircnt;
+
+ /* Add the current file into tree */
+ r = isoent_tree(a, &isoent);
+ if (r != ARCHIVE_OK)
+ return (r);
+
+ /* If there is the same file in tree and
+ * the current file is older than the file in tree.
+ * So we don't need the current file data anymore. */
+ if (isoent->file != file)
+ return (ARCHIVE_OK);
+
+ /* Non regular files contents are unneeded to be saved to
+ * temporary files. */
+ if (archive_entry_filetype(file->entry) != AE_IFREG)
+ return (ret);
+
+ /*
+ * Set the current file to cur_file to read its contents.
+ */
+ iso9660->cur_file = file;
+
+ if (archive_entry_nlink(file->entry) > 1) {
+ r = isofile_register_hardlink(a, file);
+ if (r != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
+
+ /*
+ * Prepare to save the contents of the file.
+ */
+ if (iso9660->temp_fd < 0) {
+ iso9660->temp_fd = __archive_mktemp(NULL);
+ if (iso9660->temp_fd < 0) {
+ archive_set_error(&a->archive, errno,
+ "Couldn't create temporary file");
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ /* Save an offset of current file in temporary file. */
+ file->content.offset_of_temp = wb_offset(a);
+ file->cur_content = &(file->content);
+ r = zisofs_init(a, file);
+ if (r < ret)
+ ret = r;
+ iso9660->bytes_remaining = archive_entry_size(file->entry);
+
+ return (ret);
+}
+
+static int
+write_to_temp(struct archive_write *a, const void *buff, size_t s)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ ssize_t written;
+ const unsigned char *b;
+
+ b = (const unsigned char *)buff;
+ while (s) {
+ written = write(iso9660->temp_fd, b, s);
+ if (written < 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't write to temporary file");
+ return (ARCHIVE_FATAL);
+ }
+ s -= written;
+ b += written;
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+wb_write_to_temp(struct archive_write *a, const void *buff, size_t s)
+{
+ const char *xp = buff;
+ size_t xs = s;
+
+ /*
+ * If a written data size is big enough to use system-call
+ * and there is no waiting data, this calls write_to_temp() in
+ * order to reduce a extra memory copy.
+ */
+ if (wb_remaining(a) == wb_buffmax() && s > (1024 * 16)) {
+ struct iso9660 *iso9660 = (struct iso9660 *)a->format_data;
+ xs = s % LOGICAL_BLOCK_SIZE;
+ iso9660->wbuff_offset += s - xs;
+ if (write_to_temp(a, buff, s - xs) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ if (xs == 0)
+ return (ARCHIVE_OK);
+ xp += s - xs;
+ }
+
+ while (xs) {
+ size_t size = xs;
+ if (size > wb_remaining(a))
+ size = wb_remaining(a);
+ memcpy(wb_buffptr(a), xp, size);
+ if (wb_consume(a, size) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ xs -= size;
+ xp += size;
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+wb_write_padding_to_temp(struct archive_write *a, int64_t csize)
+{
+ size_t ns;
+ int ret;
+
+ ns = csize % LOGICAL_BLOCK_SIZE;
+ if (ns != 0)
+ ret = write_null(a, LOGICAL_BLOCK_SIZE - ns);
+ else
+ ret = ARCHIVE_OK;
+ return (ret);
+}
+
+static ssize_t
+write_iso9660_data(struct archive_write *a, const void *buff, size_t s)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ size_t ws;
+
+ if (iso9660->temp_fd < 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Couldn't create temporary file");
+ return (ARCHIVE_FATAL);
+ }
+
+ ws = s;
+ if (iso9660->need_multi_extent &&
+ (iso9660->cur_file->cur_content->size + ws) >=
+ (MULTI_EXTENT_SIZE - LOGICAL_BLOCK_SIZE)) {
+ struct content *con;
+ size_t ts;
+
+ ts = MULTI_EXTENT_SIZE - LOGICAL_BLOCK_SIZE -
+ iso9660->cur_file->cur_content->size;
+
+ if (iso9660->zisofs.detect_magic)
+ zisofs_detect_magic(a, buff, ts);
+
+ if (iso9660->zisofs.making) {
+ if (zisofs_write_to_temp(a, buff, ts) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ } else {
+ if (wb_write_to_temp(a, buff, ts) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ iso9660->cur_file->cur_content->size += ts;
+ }
+
+ /* Write padding. */
+ if (wb_write_padding_to_temp(a,
+ iso9660->cur_file->cur_content->size) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ /* Compute the logical block number. */
+ iso9660->cur_file->cur_content->blocks =
+ (iso9660->cur_file->cur_content->size
+ + LOGICAL_BLOCK_SIZE -1) >> LOGICAL_BLOCK_BITS;
+
+ /*
+ * Make next extent.
+ */
+ ws -= ts;
+ buff = (const void *)(((const unsigned char *)buff) + ts);
+ /* Make a content for next extent. */
+ con = calloc(1, sizeof(*con));
+ if (con == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate content data");
+ return (ARCHIVE_FATAL);
+ }
+ con->offset_of_temp = wb_offset(a);
+ iso9660->cur_file->cur_content->next = con;
+ iso9660->cur_file->cur_content = con;
+#ifdef HAVE_ZLIB_H
+ iso9660->zisofs.block_offset = 0;
+#endif
+ }
+
+ if (iso9660->zisofs.detect_magic)
+ zisofs_detect_magic(a, buff, ws);
+
+ if (iso9660->zisofs.making) {
+ if (zisofs_write_to_temp(a, buff, ws) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ } else {
+ if (wb_write_to_temp(a, buff, ws) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ iso9660->cur_file->cur_content->size += ws;
+ }
+
+ return (s);
+}
+
+static ssize_t
+iso9660_write_data(struct archive_write *a, const void *buff, size_t s)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ ssize_t r;
+
+ if (iso9660->cur_file == NULL)
+ return (0);
+ if (archive_entry_filetype(iso9660->cur_file->entry) != AE_IFREG)
+ return (0);
+ if (s > iso9660->bytes_remaining)
+ s = iso9660->bytes_remaining;
+ if (s == 0)
+ return (0);
+
+ r = write_iso9660_data(a, buff, s);
+ if (r > 0)
+ iso9660->bytes_remaining -= r;
+ return (r);
+}
+
+static int
+iso9660_finish_entry(struct archive_write *a)
+{
+ struct iso9660 *iso9660 = a->format_data;
+
+ if (iso9660->cur_file == NULL)
+ return (ARCHIVE_OK);
+ if (archive_entry_filetype(iso9660->cur_file->entry) != AE_IFREG)
+ return (ARCHIVE_OK);
+ if (iso9660->cur_file->content.size == 0)
+ return (ARCHIVE_OK);
+
+ /* If there are unwritten data, write null data instead. */
+ while (iso9660->bytes_remaining > 0) {
+ size_t s;
+
+ s = (iso9660->bytes_remaining > a->null_length)?
+ a->null_length: (size_t)iso9660->bytes_remaining;
+ if (write_iso9660_data(a, a->nulls, s) < 0)
+ return (ARCHIVE_FATAL);
+ iso9660->bytes_remaining -= s;
+ }
+
+ if (iso9660->zisofs.making && zisofs_finish_entry(a) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ /* Write padding. */
+ if (wb_write_padding_to_temp(a, iso9660->cur_file->cur_content->size)
+ != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ /* Compute the logical block number. */
+ iso9660->cur_file->cur_content->blocks =
+ (iso9660->cur_file->cur_content->size
+ + LOGICAL_BLOCK_SIZE -1) >> LOGICAL_BLOCK_BITS;
+
+ /* Add the current file to data file list. */
+ isofile_add_data_file(iso9660, iso9660->cur_file);
+
+ return (ARCHIVE_OK);
+}
+
+static int
+iso9660_close(struct archive_write *a)
+{
+ struct iso9660 *iso9660;
+ int ret, blocks;
+
+ iso9660 = a->format_data;
+
+ /*
+ * Write remaining data out to the temprary file.
+ */
+ if (wb_remaining(a) > 0) {
+ ret = wb_write_out(a);
+ if (ret < 0)
+ return (ret);
+ }
+
+ /*
+ * Preparations...
+ */
+#ifdef DEBUG
+ if (iso9660->birth_time == 0)
+#endif
+ time(&(iso9660->birth_time));
+
+ /*
+ * Prepare a bootable ISO image.
+ */
+ if (iso9660->opt.boot) {
+ /* Find out the boot file entry. */
+ ret = isoent_find_out_boot_file(a, iso9660->primary.rootent);
+ if (ret < 0)
+ return (ret);
+ /* Reconvert the boot file from zisofs'ed form to
+ * plain form. */
+ ret = zisofs_rewind_boot_file(a);
+ if (ret < 0)
+ return (ret);
+ /* Write remaining data out to the temprary file. */
+ if (wb_remaining(a) > 0) {
+ ret = wb_write_out(a);
+ if (ret < 0)
+ return (ret);
+ }
+ /* Create the boot catalog. */
+ ret = isoent_create_boot_catalog(a, iso9660->primary.rootent);
+ if (ret < 0)
+ return (ret);
+ }
+
+ /*
+ * Prepare joliet extensions.
+ */
+ if (iso9660->opt.joliet) {
+ /* Make a new tree for joliet. */
+ ret = isoent_clone_tree(a, &(iso9660->joliet.rootent),
+ iso9660->primary.rootent);
+ if (ret < 0)
+ return (ret);
+ /* Make sure we have UTF-16BE convertors.
+ * if there is no file entry, convertors are still
+ * uninitilized. */
+ if (iso9660->sconv_to_utf16be == NULL) {
+ iso9660->sconv_to_utf16be =
+ archive_string_conversion_to_charset(
+ &(a->archive), "UTF-16BE", 1);
+ if (iso9660->sconv_to_utf16be == NULL)
+ /* Couldn't allocate memory */
+ return (ARCHIVE_FATAL);
+ iso9660->sconv_from_utf16be =
+ archive_string_conversion_from_charset(
+ &(a->archive), "UTF-16BE", 1);
+ if (iso9660->sconv_from_utf16be == NULL)
+ /* Couldn't allocate memory */
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ /*
+ * Make Path Tables.
+ */
+ ret = isoent_make_path_table(a);
+ if (ret < 0)
+ return (ret);
+
+ /*
+ * Calculate a total volume size and setup all locations of
+ * contents of an iso9660 image.
+ */
+ blocks = SYSTEM_AREA_BLOCK
+ + PRIMARY_VOLUME_DESCRIPTOR_BLOCK
+ + VOLUME_DESCRIPTOR_SET_TERMINATOR_BLOCK
+ + NON_ISO_FILE_SYSTEM_INFORMATION_BLOCK;
+ if (iso9660->opt.boot)
+ blocks += BOOT_RECORD_DESCRIPTOR_BLOCK;
+ if (iso9660->opt.joliet)
+ blocks += SUPPLEMENTARY_VOLUME_DESCRIPTOR_BLOCK;
+ if (iso9660->opt.iso_level == 4)
+ blocks += SUPPLEMENTARY_VOLUME_DESCRIPTOR_BLOCK;
+
+ /* Setup the locations of Path Table. */
+ iso9660->primary.location_type_L_path_table = blocks;
+ blocks += iso9660->primary.path_table_block;
+ iso9660->primary.location_type_M_path_table = blocks;
+ blocks += iso9660->primary.path_table_block;
+ if (iso9660->opt.joliet) {
+ iso9660->joliet.location_type_L_path_table = blocks;
+ blocks += iso9660->joliet.path_table_block;
+ iso9660->joliet.location_type_M_path_table = blocks;
+ blocks += iso9660->joliet.path_table_block;
+ }
+
+ /* Setup the locations of directories. */
+ isoent_setup_directory_location(iso9660, blocks,
+ &(iso9660->primary));
+ blocks += iso9660->primary.total_dir_block;
+ if (iso9660->opt.joliet) {
+ isoent_setup_directory_location(iso9660, blocks,
+ &(iso9660->joliet));
+ blocks += iso9660->joliet.total_dir_block;
+ }
+
+ if (iso9660->opt.rr) {
+ iso9660->location_rrip_er = blocks;
+ blocks += RRIP_ER_BLOCK;
+ }
+
+ /* Setup the locations of all file contents. */
+ isoent_setup_file_location(iso9660, blocks);
+ blocks += iso9660->total_file_block;
+ if (iso9660->opt.boot && iso9660->opt.boot_info_table) {
+ ret = setup_boot_information(a);
+ if (ret < 0)
+ return (ret);
+ }
+
+ /* Now we have a total volume size. */
+ iso9660->volume_space_size = blocks;
+ if (iso9660->opt.pad)
+ iso9660->volume_space_size += PADDING_BLOCK;
+ iso9660->volume_sequence_number = 1;
+
+
+ /*
+ * Write an ISO 9660 image.
+ */
+
+ /* Switc to start using wbuff as file buffer. */
+ iso9660->wbuff_remaining = wb_buffmax();
+ iso9660->wbuff_type = WB_TO_STREAM;
+ iso9660->wbuff_offset = 0;
+ iso9660->wbuff_written = 0;
+ iso9660->wbuff_tail = 0;
+
+ /* Write The System Area */
+ ret = write_null(a, SYSTEM_AREA_BLOCK * LOGICAL_BLOCK_SIZE);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ /* Write Primary Volume Descriptor */
+ ret = write_VD(a, &(iso9660->primary));
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ if (iso9660->opt.boot) {
+ /* Write Boot Record Volume Descriptor */
+ ret = write_VD_boot_record(a);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
+
+ if (iso9660->opt.iso_level == 4) {
+ /* Write Enhanced Volume Descriptor */
+ iso9660->primary.vdd_type = VDD_ENHANCED;
+ ret = write_VD(a, &(iso9660->primary));
+ iso9660->primary.vdd_type = VDD_PRIMARY;
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
+
+ if (iso9660->opt.joliet) {
+ ret = write_VD(a, &(iso9660->joliet));
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
+
+ /* Write Volume Descriptor Set Terminator */
+ ret = write_VD_terminator(a);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ /* Write Non-ISO File System Information */
+ ret = write_information_block(a);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ /* Write Type L Path Table */
+ ret = write_path_table(a, 0, &(iso9660->primary));
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ /* Write Type M Path Table */
+ ret = write_path_table(a, 1, &(iso9660->primary));
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ if (iso9660->opt.joliet) {
+ /* Write Type L Path Table */
+ ret = write_path_table(a, 0, &(iso9660->joliet));
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ /* Write Type M Path Table */
+ ret = write_path_table(a, 1, &(iso9660->joliet));
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
+
+ /* Write Directory Descriptors */
+ ret = write_directory_descriptors(a, &(iso9660->primary));
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ if (iso9660->opt.joliet) {
+ ret = write_directory_descriptors(a, &(iso9660->joliet));
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
+
+ if (iso9660->opt.rr) {
+ /* Write Rockridge ER(Extensions Reference) */
+ ret = write_rr_ER(a);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
+
+ /* Write File Descriptors */
+ ret = write_file_descriptors(a);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ /* Write Padding */
+ if (iso9660->opt.pad) {
+ ret = write_null(a, PADDING_BLOCK * LOGICAL_BLOCK_SIZE);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
+
+ if (iso9660->directories_too_deep != NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "%s: Directories too deep.",
+ archive_entry_pathname(
+ iso9660->directories_too_deep->file->entry));
+ return (ARCHIVE_WARN);
+ }
+
+ /* Write remaining data out. */
+ ret = wb_write_out(a);
+
+ return (ret);
+}
+
+static int
+iso9660_free(struct archive_write *a)
+{
+ struct iso9660 *iso9660;
+ int i, ret;
+
+ iso9660 = a->format_data;
+
+ /* Close the temporary file. */
+ if (iso9660->temp_fd >= 0)
+ close(iso9660->temp_fd);
+
+ /* Free some stuff for zisofs operations. */
+ ret = zisofs_free(a);
+
+ /* Remove directory entries in tree which includes file entries. */
+ isoent_free_all(iso9660->primary.rootent);
+ for (i = 0; i < iso9660->primary.max_depth; i++)
+ free(iso9660->primary.pathtbl[i].sorted);
+ free(iso9660->primary.pathtbl);
+
+ if (iso9660->opt.joliet) {
+ isoent_free_all(iso9660->joliet.rootent);
+ for (i = 0; i < iso9660->joliet.max_depth; i++)
+ free(iso9660->joliet.pathtbl[i].sorted);
+ free(iso9660->joliet.pathtbl);
+ }
+
+ /* Remove isofile entries. */
+ isofile_free_all_entries(iso9660);
+ isofile_free_hardlinks(iso9660);
+
+ archive_string_free(&(iso9660->cur_dirstr));
+ archive_string_free(&(iso9660->volume_identifier));
+ archive_string_free(&(iso9660->publisher_identifier));
+ archive_string_free(&(iso9660->data_preparer_identifier));
+ archive_string_free(&(iso9660->application_identifier));
+ archive_string_free(&(iso9660->copyright_file_identifier));
+ archive_string_free(&(iso9660->abstract_file_identifier));
+ archive_string_free(&(iso9660->bibliographic_file_identifier));
+ archive_string_free(&(iso9660->el_torito.catalog_filename));
+ archive_string_free(&(iso9660->el_torito.boot_filename));
+ archive_string_free(&(iso9660->el_torito.id));
+ archive_string_free(&(iso9660->utf16be));
+ archive_string_free(&(iso9660->mbs));
+
+ free(iso9660);
+ a->format_data = NULL;
+
+ return (ret);
+}
+
+/*
+ * Get the System Identifier
+ */
+static void
+get_system_identitier(char *system_id, size_t size)
+{
+#if defined(HAVE_SYS_UTSNAME_H)
+ struct utsname u;
+
+ uname(&u);
+ strncpy(system_id, u.sysname, size-1);
+ system_id[size-1] = '\0';
+#elif defined(_WIN32) && !defined(__CYGWIN__)
+ strncpy(system_id, "Windows", size-1);
+ system_id[size-1] = '\0';
+#else
+#error no way to get the system identifier on your platform.
+#endif
+}
+
+static void
+set_str(unsigned char *p, const char *s, size_t l, char f, const char *map)
+{
+ unsigned char c;
+
+ if (s == NULL)
+ s = "";
+ while ((c = *s++) != 0 && l > 0) {
+ if (c >= 0x80 || map[c] == 0)
+ {
+ /* illegal character */
+ if (c >= 'a' && c <= 'z') {
+ /* convert c from a-z to A-Z */
+ c -= 0x20;
+ } else
+ c = 0x5f;
+ }
+ *p++ = c;
+ l--;
+ }
+ /* If l isn't zero, fill p buffer by the character
+ * which indicated by f. */
+ if (l > 0)
+ memset(p , f, l);
+}
+
+static inline int
+joliet_allowed_char(unsigned char high, unsigned char low)
+{
+ int utf16 = (high << 8) | low;
+
+ if (utf16 <= 0x001F)
+ return (0);
+
+ switch (utf16) {
+ case 0x002A: /* '*' */
+ case 0x002F: /* '/' */
+ case 0x003A: /* ':' */
+ case 0x003B: /* ';' */
+ case 0x003F: /* '?' */
+ case 0x005C: /* '\' */
+ return (0);/* Not allowed. */
+ }
+ return (1);
+}
+
+static int
+set_str_utf16be(struct archive_write *a, unsigned char *p, const char *s,
+ size_t l, uint16_t uf, enum vdc vdc)
+{
+ size_t size, i;
+ int onepad;
+
+ if (s == NULL)
+ s = "";
+ if (l & 0x01) {
+ onepad = 1;
+ l &= ~1;
+ } else
+ onepad = 0;
+ if (vdc == VDC_UCS2) {
+ struct iso9660 *iso9660 = a->format_data;
+ if (archive_strncpy_in_locale(&iso9660->utf16be, s, strlen(s),
+ iso9660->sconv_to_utf16be) != 0 && errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for UTF-16BE");
+ return (ARCHIVE_FATAL);
+ }
+ size = iso9660->utf16be.length;
+ if (size > l)
+ size = l;
+ memcpy(p, iso9660->utf16be.s, size);
+ } else {
+ const uint16_t *u16 = (const uint16_t *)s;
+
+ size = 0;
+ while (*u16++)
+ size += 2;
+ if (size > l)
+ size = l;
+ memcpy(p, s, size);
+ }
+ for (i = 0; i < size; i += 2, p += 2) {
+ if (!joliet_allowed_char(p[0], p[1]))
+ archive_be16enc(p, 0x005F);/* '_' */
+ }
+ l -= size;
+ while (l > 0) {
+ archive_be16enc(p, uf);
+ p += 2;
+ l -= 2;
+ }
+ if (onepad)
+ *p = 0;
+ return (ARCHIVE_OK);
+}
+
+static const char a_characters_map[0x80] = {
+/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 00-0F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 10-1F */
+ 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 20-2F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 30-3F */
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40-4F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,/* 50-5F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 60-6F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 70-7F */
+};
+
+static const char a1_characters_map[0x80] = {
+/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 00-0F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 10-1F */
+ 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 20-2F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 30-3F */
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40-4F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,/* 50-5F */
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 60-6F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,/* 70-7F */
+};
+
+static const char d_characters_map[0x80] = {
+/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 00-0F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 10-1F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 20-2F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,/* 30-3F */
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40-4F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,/* 50-5F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 60-6F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 70-7F */
+};
+
+static const char d1_characters_map[0x80] = {
+/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 00-0F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 10-1F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 20-2F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,/* 30-3F */
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40-4F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,/* 50-5F */
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 60-6F */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,/* 70-7F */
+};
+
+static int
+set_str_a_characters_bp(struct archive_write *a, unsigned char *bp,
+ int from, int to, const char *s, enum vdc vdc)
+{
+ int r;
+
+ switch (vdc) {
+ case VDC_STD:
+ set_str(bp+from, s, to - from + 1, 0x20,
+ a_characters_map);
+ r = ARCHIVE_OK;
+ break;
+ case VDC_LOWERCASE:
+ set_str(bp+from, s, to - from + 1, 0x20,
+ a1_characters_map);
+ r = ARCHIVE_OK;
+ break;
+ case VDC_UCS2:
+ case VDC_UCS2_DIRECT:
+ r = set_str_utf16be(a, bp+from, s, to - from + 1,
+ 0x0020, vdc);
+ break;
+ default:
+ r = ARCHIVE_FATAL;
+ }
+ return (r);
+}
+
+static int
+set_str_d_characters_bp(struct archive_write *a, unsigned char *bp,
+ int from, int to, const char *s, enum vdc vdc)
+{
+ int r;
+
+ switch (vdc) {
+ case VDC_STD:
+ set_str(bp+from, s, to - from + 1, 0x20,
+ d_characters_map);
+ r = ARCHIVE_OK;
+ break;
+ case VDC_LOWERCASE:
+ set_str(bp+from, s, to - from + 1, 0x20,
+ d1_characters_map);
+ r = ARCHIVE_OK;
+ break;
+ case VDC_UCS2:
+ case VDC_UCS2_DIRECT:
+ r = set_str_utf16be(a, bp+from, s, to - from + 1,
+ 0x0020, vdc);
+ break;
+ default:
+ r = ARCHIVE_FATAL;
+ }
+ return (r);
+}
+
+static void
+set_VD_bp(unsigned char *bp, enum VD_type type, unsigned char ver)
+{
+
+ /* Volume Descriptor Type */
+ bp[1] = (unsigned char)type;
+ /* Standard Identifier */
+ memcpy(bp + 2, "CD001", 5);
+ /* Volume Descriptor Version */
+ bp[7] = ver;
+}
+
+static inline void
+set_unused_field_bp(unsigned char *bp, int from, int to)
+{
+ memset(bp + from, 0, to - from + 1);
+}
+
+/*
+ * 8-bit unsigned numerical values.
+ * ISO9660 Standard 7.1.1
+ */
+static inline void
+set_num_711(unsigned char *p, unsigned char value)
+{
+ *p = value;
+}
+
+/*
+ * 8-bit signed numerical values.
+ * ISO9660 Standard 7.1.2
+ */
+static inline void
+set_num_712(unsigned char *p, char value)
+{
+ *((char *)p) = value;
+}
+
+/*
+ * Least significant byte first.
+ * ISO9660 Standard 7.2.1
+ */
+static inline void
+set_num_721(unsigned char *p, uint16_t value)
+{
+ archive_le16enc(p, value);
+}
+
+/*
+ * Most significant byte first.
+ * ISO9660 Standard 7.2.2
+ */
+static inline void
+set_num_722(unsigned char *p, uint16_t value)
+{
+ archive_be16enc(p, value);
+}
+
+/*
+ * Both-byte orders.
+ * ISO9660 Standard 7.2.3
+ */
+static void
+set_num_723(unsigned char *p, uint16_t value)
+{
+ archive_le16enc(p, value);
+ archive_be16enc(p+2, value);
+}
+
+/*
+ * Least significant byte first.
+ * ISO9660 Standard 7.3.1
+ */
+static inline void
+set_num_731(unsigned char *p, uint32_t value)
+{
+ archive_le32enc(p, value);
+}
+
+/*
+ * Most significant byte first.
+ * ISO9660 Standard 7.3.2
+ */
+static inline void
+set_num_732(unsigned char *p, uint32_t value)
+{
+ archive_be32enc(p, value);
+}
+
+/*
+ * Both-byte orders.
+ * ISO9660 Standard 7.3.3
+ */
+static inline void
+set_num_733(unsigned char *p, uint32_t value)
+{
+ archive_le32enc(p, value);
+ archive_be32enc(p+4, value);
+}
+
+static void
+set_digit(unsigned char *p, size_t s, int value)
+{
+
+ while (s--) {
+ p[s] = '0' + (value % 10);
+ value /= 10;
+ }
+}
+
+#if defined(HAVE_STRUCT_TM_TM_GMTOFF)
+#define get_gmoffset(tm) ((tm)->tm_gmtoff)
+#elif defined(HAVE_STRUCT_TM___TM_GMTOFF)
+#define get_gmoffset(tm) ((tm)->__tm_gmtoff)
+#else
+static long
+get_gmoffset(struct tm *tm)
+{
+ long offset;
+
+#if defined(HAVE__GET_TIMEZONE)
+ _get_timezone(&offset);
+#elif defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__)
+ offset = _timezone;
+#else
+ offset = timezone;
+#endif
+ offset *= -1;
+ if (tm->tm_isdst)
+ offset += 3600;
+ return (offset);
+}
+#endif
+
+static void
+get_tmfromtime(struct tm *tm, time_t *t)
+{
+#if HAVE_LOCALTIME_R
+ tzset();
+ localtime_r(t, tm);
+#elif HAVE__LOCALTIME64_S
+ _localtime64_s(tm, t);
+#else
+ memcpy(tm, localtime(t), sizeof(*tm));
+#endif
+}
+
+/*
+ * Date and Time Format.
+ * ISO9660 Standard 8.4.26.1
+ */
+static void
+set_date_time(unsigned char *p, time_t t)
+{
+ struct tm tm;
+
+ get_tmfromtime(&tm, &t);
+ set_digit(p, 4, tm.tm_year + 1900);
+ set_digit(p+4, 2, tm.tm_mon + 1);
+ set_digit(p+6, 2, tm.tm_mday);
+ set_digit(p+8, 2, tm.tm_hour);
+ set_digit(p+10, 2, tm.tm_min);
+ set_digit(p+12, 2, tm.tm_sec);
+ set_digit(p+14, 2, 0);
+ set_num_712(p+16, get_gmoffset(&tm)/(60*15));
+}
+
+static void
+set_date_time_null(unsigned char *p)
+{
+ memset(p, '0', 16);
+ p[16] = 0;
+}
+
+static void
+set_time_915(unsigned char *p, time_t t)
+{
+ struct tm tm;
+
+ get_tmfromtime(&tm, &t);
+ set_num_711(p+0, tm.tm_year);
+ set_num_711(p+1, tm.tm_mon+1);
+ set_num_711(p+2, tm.tm_mday);
+ set_num_711(p+3, tm.tm_hour);
+ set_num_711(p+4, tm.tm_min);
+ set_num_711(p+5, tm.tm_sec);
+ set_num_712(p+6, get_gmoffset(&tm)/(60*15));
+}
+
+
+/*
+ * Write SUSP "CE" System Use Entry.
+ */
+static int
+set_SUSP_CE(unsigned char *p, int location, int offset, int size)
+{
+ unsigned char *bp = p -1;
+ /* Extend the System Use Area
+ * "CE" Format:
+ * len ver
+ * +----+----+----+----+-----------+-----------+
+ * | 'C'| 'E'| 1C | 01 | LOCATION1 | LOCATION2 |
+ * +----+----+----+----+-----------+-----------+
+ * 0 1 2 3 4 12 20
+ * +-----------+
+ * | LOCATION3 |
+ * +-----------+
+ * 20 28
+ * LOCATION1 : Location of Continuation of System Use Area.
+ * LOCATION2 : Offset to Start of Continuation.
+ * LOCATION3 : Length of the Continuation.
+ */
+
+ bp[1] = 'C';
+ bp[2] = 'E';
+ bp[3] = RR_CE_SIZE; /* length */
+ bp[4] = 1; /* version */
+ set_num_733(bp+5, location);
+ set_num_733(bp+13, offset);
+ set_num_733(bp+21, size);
+ return (RR_CE_SIZE);
+}
+
+/*
+ * The functions, which names are beginning with extra_, are used to
+ * control extra records.
+ * The maximum size of a Directory Record is 254. When a filename is
+ * very long, all of RRIP data of a file won't stored to the Directory
+ * Record and so remaining RRIP data store to an extra record instead.
+ */
+static unsigned char *
+extra_open_record(unsigned char *bp, int dr_len, struct isoent *isoent,
+ struct ctl_extr_rec *ctl)
+{
+ ctl->bp = bp;
+ if (bp != NULL)
+ bp += dr_len;
+ ctl->use_extr = 0;
+ ctl->isoent = isoent;
+ ctl->ce_ptr = NULL;
+ ctl->cur_len = ctl->dr_len = dr_len;
+ ctl->limit = DR_LIMIT;
+
+ return (bp);
+}
+
+static void
+extra_close_record(struct ctl_extr_rec *ctl, int ce_size)
+{
+ int padding = 0;
+
+ if (ce_size > 0)
+ extra_tell_used_size(ctl, ce_size);
+ /* Padding. */
+ if (ctl->cur_len & 0x01) {
+ ctl->cur_len++;
+ if (ctl->bp != NULL)
+ ctl->bp[ctl->cur_len] = 0;
+ padding = 1;
+ }
+ if (ctl->use_extr) {
+ if (ctl->ce_ptr != NULL)
+ set_SUSP_CE(ctl->ce_ptr, ctl->extr_loc,
+ ctl->extr_off, ctl->cur_len - padding);
+ } else
+ ctl->dr_len = ctl->cur_len;
+}
+
+#define extra_space(ctl) ((ctl)->limit - (ctl)->cur_len)
+
+static unsigned char *
+extra_next_record(struct ctl_extr_rec *ctl, int length)
+{
+ int cur_len = ctl->cur_len;/* save cur_len */
+
+ /* Close the current extra record or Directory Record. */
+ extra_close_record(ctl, RR_CE_SIZE);
+
+ /* Get a next extra record. */
+ ctl->use_extr = 1;
+ if (ctl->bp != NULL) {
+ /* Storing data into an extra record. */
+ unsigned char *p;
+
+ /* Save the pointer where a CE extension will be
+ * stored to. */
+ ctl->ce_ptr = &ctl->bp[cur_len+1];
+ p = extra_get_record(ctl->isoent,
+ &ctl->limit, &ctl->extr_off, &ctl->extr_loc);
+ ctl->bp = p - 1;/* the base of bp offset is 1. */
+ } else
+ /* Calculating the size of an extra record. */
+ (void)extra_get_record(ctl->isoent,
+ &ctl->limit, NULL, NULL);
+ ctl->cur_len = 0;
+ /* Check if an extra record is almost full.
+ * If so, get a next one. */
+ if (extra_space(ctl) < length)
+ (void)extra_next_record(ctl, length);
+
+ return (ctl->bp);
+}
+
+static inline struct extr_rec *
+extra_last_record(struct isoent *isoent)
+{
+ if (isoent->extr_rec_list.first == NULL)
+ return (NULL);
+ return ((struct extr_rec *)(void *)
+ ((char *)(isoent->extr_rec_list.last)
+ - offsetof(struct extr_rec, next)));
+}
+
+static unsigned char *
+extra_get_record(struct isoent *isoent, int *space, int *off, int *loc)
+{
+ struct extr_rec *rec;
+
+ isoent = isoent->parent;
+ if (off != NULL) {
+ /* Storing data into an extra record. */
+ rec = isoent->extr_rec_list.current;
+ if (DR_SAFETY > LOGICAL_BLOCK_SIZE - rec->offset)
+ rec = rec->next;
+ } else {
+ /* Calculating the size of an extra record. */
+ rec = extra_last_record(isoent);
+ if (rec == NULL ||
+ DR_SAFETY > LOGICAL_BLOCK_SIZE - rec->offset) {
+ rec = malloc(sizeof(*rec));
+ if (rec == NULL)
+ return (NULL);
+ rec->location = 0;
+ rec->offset = 0;
+ /* Insert `rec` into the tail of isoent->extr_rec_list */
+ rec->next = NULL;
+ *isoent->extr_rec_list.last = rec;
+ isoent->extr_rec_list.last = &(rec->next);
+ }
+ }
+ *space = LOGICAL_BLOCK_SIZE - rec->offset - DR_SAFETY;
+ if (*space & 0x01)
+ *space -= 1;/* Keep padding space. */
+ if (off != NULL)
+ *off = rec->offset;
+ if (loc != NULL)
+ *loc = rec->location;
+ isoent->extr_rec_list.current = rec;
+
+ return (&rec->buf[rec->offset]);
+}
+
+static void
+extra_tell_used_size(struct ctl_extr_rec *ctl, int size)
+{
+ struct isoent *isoent;
+ struct extr_rec *rec;
+
+ if (ctl->use_extr) {
+ isoent = ctl->isoent->parent;
+ rec = isoent->extr_rec_list.current;
+ if (rec != NULL)
+ rec->offset += size;
+ }
+ ctl->cur_len += size;
+}
+
+static int
+extra_setup_location(struct isoent *isoent, int location)
+{
+ struct extr_rec *rec;
+ int cnt;
+
+ cnt = 0;
+ rec = isoent->extr_rec_list.first;
+ isoent->extr_rec_list.current = rec;
+ while (rec) {
+ cnt++;
+ rec->location = location++;
+ rec->offset = 0;
+ rec = rec->next;
+ }
+ return (cnt);
+}
+
+/*
+ * Create the RRIP entries.
+ */
+static int
+set_directory_record_rr(unsigned char *bp, int dr_len,
+ struct isoent *isoent, struct iso9660 *iso9660, enum dir_rec_type t)
+{
+ /* Flags(BP 5) of the Rockridge "RR" System Use Field */
+ unsigned char rr_flag;
+#define RR_USE_PX 0x01
+#define RR_USE_PN 0x02
+#define RR_USE_SL 0x04
+#define RR_USE_NM 0x08
+#define RR_USE_CL 0x10
+#define RR_USE_PL 0x20
+#define RR_USE_RE 0x40
+#define RR_USE_TF 0x80
+ int length;
+ struct ctl_extr_rec ctl;
+ struct isoent *rr_parent, *pxent;
+ struct isofile *file;
+
+ bp = extra_open_record(bp, dr_len, isoent, &ctl);
+
+ if (t == DIR_REC_PARENT) {
+ rr_parent = isoent->rr_parent;
+ pxent = isoent->parent;
+ if (rr_parent != NULL)
+ isoent = rr_parent;
+ else
+ isoent = isoent->parent;
+ } else {
+ rr_parent = NULL;
+ pxent = isoent;
+ }
+ file = isoent->file;
+
+ if (t != DIR_REC_NORMAL) {
+ rr_flag = RR_USE_PX | RR_USE_TF;
+ if (rr_parent != NULL)
+ rr_flag |= RR_USE_PL;
+ } else {
+ rr_flag = RR_USE_PX | RR_USE_NM | RR_USE_TF;
+ if (archive_entry_filetype(file->entry) == AE_IFLNK)
+ rr_flag |= RR_USE_SL;
+ if (isoent->rr_parent != NULL)
+ rr_flag |= RR_USE_RE;
+ if (isoent->rr_child != NULL)
+ rr_flag |= RR_USE_CL;
+ if (archive_entry_filetype(file->entry) == AE_IFCHR ||
+ archive_entry_filetype(file->entry) == AE_IFBLK)
+ rr_flag |= RR_USE_PN;
+#ifdef COMPAT_MKISOFS
+ /*
+ * mkisofs 2.01.01a63 records "RE" extension to
+ * the entry of "rr_moved" directory.
+ * I don't understand this behavior.
+ */
+ if (isoent->virtual &&
+ isoent->parent == iso9660->primary.rootent &&
+ strcmp(isoent->file->basename.s, "rr_moved") == 0)
+ rr_flag |= RR_USE_RE;
+#endif
+ }
+
+ /* Write "SP" System Use Entry. */
+ if (t == DIR_REC_SELF && isoent == isoent->parent) {
+ length = 7;
+ if (bp != NULL) {
+ bp[1] = 'S';
+ bp[2] = 'P';
+ bp[3] = length;
+ bp[4] = 1; /* version */
+ bp[5] = 0xBE; /* Check Byte */
+ bp[6] = 0xEF; /* Check Byte */
+ bp[7] = 0;
+ bp += length;
+ }
+ extra_tell_used_size(&ctl, length);
+ }
+
+ /* Write "RR" System Use Entry. */
+ length = 5;
+ if (extra_space(&ctl) < length)
+ bp = extra_next_record(&ctl, length);
+ if (bp != NULL) {
+ bp[1] = 'R';
+ bp[2] = 'R';
+ bp[3] = length;
+ bp[4] = 1; /* version */
+ bp[5] = rr_flag;
+ bp += length;
+ }
+ extra_tell_used_size(&ctl, length);
+
+ /* Write "NM" System Use Entry. */
+ if (rr_flag & RR_USE_NM) {
+ /*
+ * "NM" Format:
+ * e.g. a basename is 'foo'
+ * len ver flg
+ * +----+----+----+----+----+----+----+----+
+ * | 'N'| 'M'| 08 | 01 | 00 | 'f'| 'o'| 'o'|
+ * +----+----+----+----+----+----+----+----+
+ * <----------------- len ----------------->
+ */
+ size_t nmlen = file->basename.length;
+ const char *nm = file->basename.s;
+ size_t nmmax;
+
+ if (extra_space(&ctl) < 6)
+ bp = extra_next_record(&ctl, 6);
+ if (bp != NULL) {
+ bp[1] = 'N';
+ bp[2] = 'M';
+ bp[4] = 1; /* version */
+ }
+ nmmax = extra_space(&ctl);
+ if (nmmax > 0xff)
+ nmmax = 0xff;
+ while (nmlen + 5 > nmmax) {
+ length = nmmax;
+ if (bp != NULL) {
+ bp[3] = length;
+ bp[5] = 0x01;/* Alternate Name continues
+ * in next "NM" field */
+ memcpy(bp+6, nm, length - 5);
+ bp += length;
+ }
+ nmlen -= length - 5;
+ nm += length - 5;
+ extra_tell_used_size(&ctl, length);
+ if (extra_space(&ctl) < 6) {
+ bp = extra_next_record(&ctl, 6);
+ nmmax = extra_space(&ctl);
+ if (nmmax > 0xff)
+ nmmax = 0xff;
+ }
+ if (bp != NULL) {
+ bp[1] = 'N';
+ bp[2] = 'M';
+ bp[4] = 1; /* version */
+ }
+ }
+ length = 5 + nmlen;
+ if (bp != NULL) {
+ bp[3] = length;
+ bp[5] = 0;
+ memcpy(bp+6, nm, nmlen);
+ bp += length;
+ }
+ extra_tell_used_size(&ctl, length);
+ }
+
+ /* Write "PX" System Use Entry. */
+ if (rr_flag & RR_USE_PX) {
+ /*
+ * "PX" Format:
+ * len ver
+ * +----+----+----+----+-----------+-----------+
+ * | 'P'| 'X'| 2C | 01 | FILE MODE | LINKS |
+ * +----+----+----+----+-----------+-----------+
+ * 0 1 2 3 4 12 20
+ * +-----------+-----------+------------------+
+ * | USER ID | GROUP ID |FILE SERIAL NUMBER|
+ * +-----------+-----------+------------------+
+ * 20 28 36 44
+ */
+ length = 44;
+ if (extra_space(&ctl) < length)
+ bp = extra_next_record(&ctl, length);
+ if (bp != NULL) {
+ mode_t mode;
+ uid_t uid;
+ gid_t gid;
+
+ mode = archive_entry_mode(file->entry);
+ uid = archive_entry_uid(file->entry);
+ gid = archive_entry_gid(file->entry);
+ if (iso9660->opt.rr == OPT_RR_USEFUL) {
+ /*
+ * This action is simular mkisofs -r option
+ * but our rockridge=useful option does not
+ * set a zero to uid and gid.
+ */
+ /* set all read bit ON */
+ mode |= 0444;
+#if !defined(_WIN32) && !defined(__CYGWIN__)
+ if (mode & 0111)
+#endif
+ /* set all exec bit ON */
+ mode |= 0111;
+ /* clear all write bits. */
+ mode &= ~0222;
+ /* clear setuid,setgid,sticky bits. */
+ mode &= ~07000;
+ }
+
+ bp[1] = 'P';
+ bp[2] = 'X';
+ bp[3] = length;
+ bp[4] = 1; /* version */
+ /* file mode */
+ set_num_733(bp+5, mode);
+ /* file links (stat.st_nlink) */
+ set_num_733(bp+13,
+ archive_entry_nlink(file->entry));
+ set_num_733(bp+21, uid);
+ set_num_733(bp+29, gid);
+ /* File Serial Number */
+ if (pxent->dir)
+ set_num_733(bp+37, pxent->dir_location);
+ else if (file->hardlink_target != NULL)
+ set_num_733(bp+37,
+ file->hardlink_target->cur_content->location);
+ else
+ set_num_733(bp+37,
+ file->cur_content->location);
+ bp += length;
+ }
+ extra_tell_used_size(&ctl, length);
+ }
+
+ /* Write "SL" System Use Entry. */
+ if (rr_flag & RR_USE_SL) {
+ /*
+ * "SL" Format:
+ * e.g. a symbolic name is 'foo/bar'
+ * len ver flg
+ * +----+----+----+----+----+------------+
+ * | 'S'| 'L'| 0F | 01 | 00 | components |
+ * +----+----+----+----+----+-----+------+
+ * 0 1 2 3 4 5 ...|... 15
+ * <----------------- len --------+------>
+ * components : |
+ * cflg clen |
+ * +----+----+----+----+----+ |
+ * | 00 | 03 | 'f'| 'o'| 'o'| <---+
+ * +----+----+----+----+----+ |
+ * 5 6 7 8 9 10 |
+ * cflg clen |
+ * +----+----+----+----+----+ |
+ * | 00 | 03 | 'b'| 'a'| 'r'| <---+
+ * +----+----+----+----+----+
+ * 10 11 12 13 14 15
+ *
+ * - cflg : flag of componet
+ * - clen : length of componet
+ */
+ const char *sl;
+ char sl_last;
+
+ if (extra_space(&ctl) < 7)
+ bp = extra_next_record(&ctl, 7);
+ sl = file->symlink.s;
+ sl_last = '\0';
+ if (bp != NULL) {
+ bp[1] = 'S';
+ bp[2] = 'L';
+ bp[4] = 1; /* version */
+ }
+ for (;;) {
+ unsigned char *nc, *cf, *cl, cldmy = 0;
+ int sllen, slmax;
+
+ slmax = extra_space(&ctl);
+ if (slmax > 0xff)
+ slmax = 0xff;
+ if (bp != NULL)
+ nc = &bp[6];
+ else
+ nc = NULL;
+ cf = cl = NULL;
+ sllen = 0;
+ while (*sl && sllen + 11 < slmax) {
+ if (sl_last == '\0' && sl[0] == '/') {
+ /*
+ * flg len
+ * +----+----+
+ * | 08 | 00 | ROOT component.
+ * +----+----+ ("/")
+ *
+ * Root component has to appear
+ * at the first component only.
+ */
+ if (nc != NULL) {
+ cf = nc++;
+ *cf = 0x08; /* ROOT */
+ *nc++ = 0;
+ }
+ sllen += 2;
+ sl++;
+ sl_last = '/';
+ cl = NULL;
+ continue;
+ }
+ if (((sl_last == '\0' || sl_last == '/') &&
+ sl[0] == '.' && sl[1] == '.' &&
+ (sl[2] == '/' || sl[2] == '\0')) ||
+ (sl[0] == '/' &&
+ sl[1] == '.' && sl[2] == '.' &&
+ (sl[3] == '/' || sl[3] == '\0'))) {
+ /*
+ * flg len
+ * +----+----+
+ * | 04 | 00 | PARENT component.
+ * +----+----+ ("..")
+ */
+ if (nc != NULL) {
+ cf = nc++;
+ *cf = 0x04; /* PARENT */
+ *nc++ = 0;
+ }
+ sllen += 2;
+ if (sl[0] == '/')
+ sl += 3;/* skip "/.." */
+ else
+ sl += 2;/* skip ".." */
+ sl_last = '.';
+ cl = NULL;
+ continue;
+ }
+ if (((sl_last == '\0' || sl_last == '/') &&
+ sl[0] == '.' &&
+ (sl[1] == '/' || sl[1] == '\0')) ||
+ (sl[0] == '/' && sl[1] == '.' &&
+ (sl[2] == '/' || sl[2] == '\0'))) {
+ /*
+ * flg len
+ * +----+----+
+ * | 02 | 00 | CURREENT component.
+ * +----+----+ (".")
+ */
+ if (nc != NULL) {
+ cf = nc++;
+ *cf = 0x02; /* CURRENT */
+ *nc++ = 0;
+ }
+ sllen += 2;
+ if (sl[0] == '/')
+ sl += 2;/* skip "/." */
+ else
+ sl ++; /* skip "." */
+ sl_last = '.';
+ cl = NULL;
+ continue;
+ }
+ if (sl[0] == '/' || cl == NULL) {
+ if (nc != NULL) {
+ cf = nc++;
+ *cf = 0;
+ cl = nc++;
+ *cl = 0;
+ } else
+ cl = &cldmy;
+ sllen += 2;
+ if (sl[0] == '/') {
+ sl_last = *sl++;
+ continue;
+ }
+ }
+ sl_last = *sl++;
+ if (nc != NULL) {
+ *nc++ = sl_last;
+ (*cl) ++;
+ }
+ sllen++;
+ }
+ if (*sl) {
+ length = 5 + sllen;
+ if (bp != NULL) {
+ /*
+ * Mark flg as CONTINUE component.
+ */
+ *cf |= 0x01;
+ /*
+ * len ver flg
+ * +----+----+----+----+----+-
+ * | 'S'| 'L'| XX | 01 | 01 |
+ * +----+----+----+----+----+-
+ * ^
+ * continues in next "SL"
+ */
+ bp[3] = length;
+ bp[5] = 0x01;/* This Symbolic Link
+ * continues in next
+ * "SL" field */
+ bp += length;
+ }
+ extra_tell_used_size(&ctl, length);
+ if (extra_space(&ctl) < 11)
+ bp = extra_next_record(&ctl, 11);
+ if (bp != NULL) {
+ /* Next 'SL' */
+ bp[1] = 'S';
+ bp[2] = 'L';
+ bp[4] = 1; /* version */
+ }
+ } else {
+ length = 5 + sllen;
+ if (bp != NULL) {
+ bp[3] = length;
+ bp[5] = 0;
+ bp += length;
+ }
+ extra_tell_used_size(&ctl, length);
+ break;
+ }
+ }
+ }
+
+ /* Write "TF" System Use Entry. */
+ if (rr_flag & RR_USE_TF) {
+ /*
+ * "TF" Format:
+ * len ver
+ * +----+----+----+----+-----+-------------+
+ * | 'T'| 'F'| XX | 01 |FLAGS| TIME STAMPS |
+ * +----+----+----+----+-----+-------------+
+ * 0 1 2 3 4 5 XX
+ * TIME STAMPS : ISO 9660 Standard 9.1.5.
+ * If TF_LONG_FORM FLAGS is set,
+ * use ISO9660 Standard 8.4.26.1.
+ */
+#define TF_CREATION 0x01 /* Creation time recorded */
+#define TF_MODIFY 0x02 /* Modification time recorded */
+#define TF_ACCESS 0x04 /* Last Access time recorded */
+#define TF_ATTRIBUTES 0x08 /* Last Attribute Change time recorded */
+#define TF_BACKUP 0x10 /* Last Backup time recorded */
+#define TF_EXPIRATION 0x20 /* Expiration time recorded */
+#define TF_EFFECTIVE 0x40 /* Effective time recorded */
+#define TF_LONG_FORM 0x80 /* ISO 9660 17-byte time format used */
+ unsigned char tf_flags;
+
+ length = 5;
+ tf_flags = 0;
+#ifndef COMPAT_MKISOFS
+ if (archive_entry_birthtime_is_set(file->entry) &&
+ archive_entry_birthtime(file->entry) <=
+ archive_entry_mtime(file->entry)) {
+ length += 7;
+ tf_flags |= TF_CREATION;
+ }
+#endif
+ if (archive_entry_mtime_is_set(file->entry)) {
+ length += 7;
+ tf_flags |= TF_MODIFY;
+ }
+ if (archive_entry_atime_is_set(file->entry)) {
+ length += 7;
+ tf_flags |= TF_ACCESS;
+ }
+ if (archive_entry_ctime_is_set(file->entry)) {
+ length += 7;
+ tf_flags |= TF_ATTRIBUTES;
+ }
+ if (extra_space(&ctl) < length)
+ bp = extra_next_record(&ctl, length);
+ if (bp != NULL) {
+ bp[1] = 'T';
+ bp[2] = 'F';
+ bp[3] = length;
+ bp[4] = 1; /* version */
+ bp[5] = tf_flags;
+ bp += 5;
+ /* Creation time */
+ if (tf_flags & TF_CREATION) {
+ set_time_915(bp+1,
+ archive_entry_birthtime(file->entry));
+ bp += 7;
+ }
+ /* Modification time */
+ if (tf_flags & TF_MODIFY) {
+ set_time_915(bp+1,
+ archive_entry_mtime(file->entry));
+ bp += 7;
+ }
+ /* Last Access time */
+ if (tf_flags & TF_ACCESS) {
+ set_time_915(bp+1,
+ archive_entry_atime(file->entry));
+ bp += 7;
+ }
+ /* Last Attribute Change time */
+ if (tf_flags & TF_ATTRIBUTES) {
+ set_time_915(bp+1,
+ archive_entry_ctime(file->entry));
+ bp += 7;
+ }
+ }
+ extra_tell_used_size(&ctl, length);
+ }
+
+ /* Write "RE" System Use Entry. */
+ if (rr_flag & RR_USE_RE) {
+ /*
+ * "RE" Format:
+ * len ver
+ * +----+----+----+----+
+ * | 'R'| 'E'| 04 | 01 |
+ * +----+----+----+----+
+ * 0 1 2 3 4
+ */
+ length = 4;
+ if (extra_space(&ctl) < length)
+ bp = extra_next_record(&ctl, length);
+ if (bp != NULL) {
+ bp[1] = 'R';
+ bp[2] = 'E';
+ bp[3] = length;
+ bp[4] = 1; /* version */
+ bp += length;
+ }
+ extra_tell_used_size(&ctl, length);
+ }
+
+ /* Write "PL" System Use Entry. */
+ if (rr_flag & RR_USE_PL) {
+ /*
+ * "PL" Format:
+ * len ver
+ * +----+----+----+----+------------+
+ * | 'P'| 'L'| 0C | 01 | *LOCATION |
+ * +----+----+----+----+------------+
+ * 0 1 2 3 4 12
+ * *LOCATION: location of parent directory
+ */
+ length = 12;
+ if (extra_space(&ctl) < length)
+ bp = extra_next_record(&ctl, length);
+ if (bp != NULL) {
+ bp[1] = 'P';
+ bp[2] = 'L';
+ bp[3] = length;
+ bp[4] = 1; /* version */
+ set_num_733(bp + 5,
+ rr_parent->dir_location);
+ bp += length;
+ }
+ extra_tell_used_size(&ctl, length);
+ }
+
+ /* Write "CL" System Use Entry. */
+ if (rr_flag & RR_USE_CL) {
+ /*
+ * "CL" Format:
+ * len ver
+ * +----+----+----+----+------------+
+ * | 'C'| 'L'| 0C | 01 | *LOCATION |
+ * +----+----+----+----+------------+
+ * 0 1 2 3 4 12
+ * *LOCATION: location of child directory
+ */
+ length = 12;
+ if (extra_space(&ctl) < length)
+ bp = extra_next_record(&ctl, length);
+ if (bp != NULL) {
+ bp[1] = 'C';
+ bp[2] = 'L';
+ bp[3] = length;
+ bp[4] = 1; /* version */
+ set_num_733(bp + 5,
+ isoent->rr_child->dir_location);
+ bp += length;
+ }
+ extra_tell_used_size(&ctl, length);
+ }
+
+ /* Write "PN" System Use Entry. */
+ if (rr_flag & RR_USE_PN) {
+ /*
+ * "PN" Format:
+ * len ver
+ * +----+----+----+----+------------+------------+
+ * | 'P'| 'N'| 14 | 01 | dev_t high | dev_t low |
+ * +----+----+----+----+------------+------------+
+ * 0 1 2 3 4 12 20
+ */
+ length = 20;
+ if (extra_space(&ctl) < length)
+ bp = extra_next_record(&ctl, length);
+ if (bp != NULL) {
+ uint64_t dev;
+
+ bp[1] = 'P';
+ bp[2] = 'N';
+ bp[3] = length;
+ bp[4] = 1; /* version */
+ dev = (uint64_t)archive_entry_rdev(file->entry);
+ set_num_733(bp + 5, dev >> 32);
+ set_num_733(bp + 13, dev & 0xFFFFFFFF);
+ bp += length;
+ }
+ extra_tell_used_size(&ctl, length);
+ }
+
+ /* Write "ZF" System Use Entry. */
+ if (file->zisofs.header_size) {
+ /*
+ * "ZF" Format:
+ * len ver
+ * +----+----+----+----+----+----+-------------+
+ * | 'Z'| 'F'| 10 | 01 | 'p'| 'z'| Header Size |
+ * +----+----+----+----+----+----+-------------+
+ * 0 1 2 3 4 5 6 7
+ * +--------------------+-------------------+
+ * | Log2 of block Size | Uncompressed Size |
+ * +--------------------+-------------------+
+ * 7 8 16
+ */
+ length = 16;
+ if (extra_space(&ctl) < length)
+ bp = extra_next_record(&ctl, length);
+ if (bp != NULL) {
+ bp[1] = 'Z';
+ bp[2] = 'F';
+ bp[3] = length;
+ bp[4] = 1; /* version */
+ bp[5] = 'p';
+ bp[6] = 'z';
+ bp[7] = file->zisofs.header_size;
+ bp[8] = file->zisofs.log2_bs;
+ set_num_733(bp + 9, file->zisofs.uncompressed_size);
+ bp += length;
+ }
+ extra_tell_used_size(&ctl, length);
+ }
+
+ /* Write "CE" System Use Entry. */
+ if (t == DIR_REC_SELF && isoent == isoent->parent) {
+ length = RR_CE_SIZE;
+ if (bp != NULL)
+ set_SUSP_CE(bp+1, iso9660->location_rrip_er,
+ 0, RRIP_ER_SIZE);
+ extra_tell_used_size(&ctl, length);
+ }
+
+ extra_close_record(&ctl, 0);
+
+ return (ctl.dr_len);
+}
+
+/*
+ * Write data of a Directory Record or calculate writing bytes itself.
+ * If parameter `p' is NULL, calculates the size of writing data, which
+ * a Directory Record needs to write, then it saved and return
+ * the calculated size.
+ * Parameter `n' is a remaining size of buffer. when parameter `p' is
+ * not NULL, check whether that `n' is not less than the saved size.
+ * if that `n' is small, return zero.
+ *
+ * This format of the Directory Record is according to
+ * ISO9660 Standard 9.1
+ */
+static int
+set_directory_record(unsigned char *p, size_t n, struct isoent *isoent,
+ struct iso9660 *iso9660, enum dir_rec_type t,
+ enum vdd_type vdd_type)
+{
+ unsigned char *bp;
+ size_t dr_len;
+ size_t fi_len;
+
+ if (p != NULL) {
+ /*
+ * Check whether a write buffer size is less than the
+ * saved size which is needed to write this Directory
+ * Record.
+ */
+ switch (t) {
+ case DIR_REC_VD:
+ dr_len = isoent->dr_len.vd; break;
+ case DIR_REC_SELF:
+ dr_len = isoent->dr_len.self; break;
+ case DIR_REC_PARENT:
+ dr_len = isoent->dr_len.parent; break;
+ case DIR_REC_NORMAL:
+ default:
+ dr_len = isoent->dr_len.normal; break;
+ }
+ if (dr_len > n)
+ return (0);/* Needs more buffer size. */
+ }
+
+ if (t == DIR_REC_NORMAL && isoent->identifier != NULL)
+ fi_len = isoent->id_len;
+ else
+ fi_len = 1;
+
+ if (p != NULL) {
+ struct isoent *xisoent;
+ struct isofile *file;
+ unsigned char flag;
+
+ if (t == DIR_REC_PARENT)
+ xisoent = isoent->parent;
+ else
+ xisoent = isoent;
+ file = isoent->file;
+ if (file->hardlink_target != NULL)
+ file = file->hardlink_target;
+ /* Make a file flag. */
+ if (xisoent->dir)
+ flag = FILE_FLAG_DIRECTORY;
+ else {
+ if (file->cur_content->next != NULL)
+ flag = FILE_FLAG_MULTI_EXTENT;
+ else
+ flag = 0;
+ }
+
+ bp = p -1;
+ /* Extended Attribute Record Length */
+ set_num_711(bp+2, 0);
+ /* Location of Extent */
+ if (xisoent->dir)
+ set_num_733(bp+3, xisoent->dir_location);
+ else
+ set_num_733(bp+3, file->cur_content->location);
+ /* Data Length */
+ if (xisoent->dir)
+ set_num_733(bp+11,
+ xisoent->dir_block * LOGICAL_BLOCK_SIZE);
+ else
+ set_num_733(bp+11, file->cur_content->size);
+ /* Recording Date and Time */
+ /* NOTE:
+ * If a file type is symbolic link, you are seeing this
+ * field value is different from a value mkisofs makes.
+ * libarchive uses lstat to get this one, but it
+ * seems mkisofs uses stat to get.
+ */
+ set_time_915(bp+19,
+ archive_entry_mtime(xisoent->file->entry));
+ /* File Flags */
+ bp[26] = flag;
+ /* File Unit Size */
+ set_num_711(bp+27, 0);
+ /* Interleave Gap Size */
+ set_num_711(bp+28, 0);
+ /* Volume Sequence Number */
+ set_num_723(bp+29, iso9660->volume_sequence_number);
+ /* Length of File Identifier */
+ set_num_711(bp+33, fi_len);
+ /* File Identifier */
+ switch (t) {
+ case DIR_REC_VD:
+ case DIR_REC_SELF:
+ set_num_711(bp+34, 0);
+ break;
+ case DIR_REC_PARENT:
+ set_num_711(bp+34, 1);
+ break;
+ case DIR_REC_NORMAL:
+ if (isoent->identifier != NULL)
+ memcpy(bp+34, isoent->identifier, fi_len);
+ else
+ set_num_711(bp+34, 0);
+ break;
+ }
+ } else
+ bp = NULL;
+ dr_len = 33 + fi_len;
+ /* Padding Field */
+ if (dr_len & 0x01) {
+ dr_len ++;
+ if (p != NULL)
+ bp[dr_len] = 0;
+ }
+
+ /* Volume Descriptor does not record extension. */
+ if (t == DIR_REC_VD) {
+ if (p != NULL)
+ /* Length of Directory Record */
+ set_num_711(p, dr_len);
+ else
+ isoent->dr_len.vd = dr_len;
+ return (dr_len);
+ }
+
+ /* Rockridge */
+ if (iso9660->opt.rr && vdd_type != VDD_JOLIET)
+ dr_len = set_directory_record_rr(bp, dr_len,
+ isoent, iso9660, t);
+
+ if (p != NULL)
+ /* Length of Directory Record */
+ set_num_711(p, dr_len);
+ else {
+ /*
+ * Save the size which is needed to write this
+ * Directory Record.
+ */
+ switch (t) {
+ case DIR_REC_VD:
+ /* This case does not come, but compiler
+ * complains that DIR_REC_VD not handled
+ * in switch .... */
+ break;
+ case DIR_REC_SELF:
+ isoent->dr_len.self = dr_len; break;
+ case DIR_REC_PARENT:
+ isoent->dr_len.parent = dr_len; break;
+ case DIR_REC_NORMAL:
+ isoent->dr_len.normal = dr_len; break;
+ }
+ }
+
+ return (dr_len);
+}
+
+/*
+ * Calculate the size of a directory record.
+ */
+static inline int
+get_dir_rec_size(struct iso9660 *iso9660, struct isoent *isoent,
+ enum dir_rec_type t, enum vdd_type vdd_type)
+{
+
+ return (set_directory_record(NULL, SIZE_MAX,
+ isoent, iso9660, t, vdd_type));
+}
+
+/*
+ * Manage to write ISO-image data with wbuff to reduce calling
+ * __archive_write_output() for performance.
+ */
+
+
+static inline unsigned char *
+wb_buffptr(struct archive_write *a)
+{
+ struct iso9660 *iso9660 = (struct iso9660 *)a->format_data;
+
+ return (&(iso9660->wbuff[sizeof(iso9660->wbuff)
+ - iso9660->wbuff_remaining]));
+}
+
+static int
+wb_write_out(struct archive_write *a)
+{
+ struct iso9660 *iso9660 = (struct iso9660 *)a->format_data;
+ size_t wsize, nw;
+ int r;
+
+ wsize = sizeof(iso9660->wbuff) - iso9660->wbuff_remaining;
+ nw = wsize % LOGICAL_BLOCK_SIZE;
+ if (iso9660->wbuff_type == WB_TO_STREAM)
+ r = __archive_write_output(a, iso9660->wbuff, wsize - nw);
+ else
+ r = write_to_temp(a, iso9660->wbuff, wsize - nw);
+ /* Increase the offset. */
+ iso9660->wbuff_offset += wsize - nw;
+ if (iso9660->wbuff_offset > iso9660->wbuff_written)
+ iso9660->wbuff_written = iso9660->wbuff_offset;
+ iso9660->wbuff_remaining = sizeof(iso9660->wbuff);
+ if (nw) {
+ iso9660->wbuff_remaining -= nw;
+ memmove(iso9660->wbuff, iso9660->wbuff + wsize - nw, nw);
+ }
+ return (r);
+}
+
+static int
+wb_consume(struct archive_write *a, size_t size)
+{
+ struct iso9660 *iso9660 = (struct iso9660 *)a->format_data;
+
+ if (size > iso9660->wbuff_remaining ||
+ iso9660->wbuff_remaining == 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Internal Programing error: iso9660:wb_consume()"
+ " size=%jd, wbuff_remaining=%jd",
+ (intmax_t)size, (intmax_t)iso9660->wbuff_remaining);
+ return (ARCHIVE_FATAL);
+ }
+ iso9660->wbuff_remaining -= size;
+ if (iso9660->wbuff_remaining < LOGICAL_BLOCK_SIZE)
+ return (wb_write_out(a));
+ return (ARCHIVE_OK);
+}
+
+#ifdef HAVE_ZLIB_H
+
+static int
+wb_set_offset(struct archive_write *a, int64_t off)
+{
+ struct iso9660 *iso9660 = (struct iso9660 *)a->format_data;
+ int64_t used, ext_bytes;
+
+ if (iso9660->wbuff_type != WB_TO_TEMP) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Internal Programing error: iso9660:wb_set_offset()");
+ return (ARCHIVE_FATAL);
+ }
+
+ used = sizeof(iso9660->wbuff) - iso9660->wbuff_remaining;
+ if (iso9660->wbuff_offset + used > iso9660->wbuff_tail)
+ iso9660->wbuff_tail = iso9660->wbuff_offset + used;
+ if (iso9660->wbuff_offset < iso9660->wbuff_written) {
+ if (used > 0 &&
+ write_to_temp(a, iso9660->wbuff, used) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ iso9660->wbuff_offset = iso9660->wbuff_written;
+ lseek(iso9660->temp_fd, iso9660->wbuff_offset, SEEK_SET);
+ iso9660->wbuff_remaining = sizeof(iso9660->wbuff);
+ used = 0;
+ }
+ if (off < iso9660->wbuff_offset) {
+ /*
+ * Write out waiting data.
+ */
+ if (used > 0) {
+ if (wb_write_out(a) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
+ lseek(iso9660->temp_fd, off, SEEK_SET);
+ iso9660->wbuff_offset = off;
+ iso9660->wbuff_remaining = sizeof(iso9660->wbuff);
+ } else if (off <= iso9660->wbuff_tail) {
+ iso9660->wbuff_remaining =
+ sizeof(iso9660->wbuff) - (off - iso9660->wbuff_offset);
+ } else {
+ ext_bytes = off - iso9660->wbuff_tail;
+ iso9660->wbuff_remaining = sizeof(iso9660->wbuff)
+ - (iso9660->wbuff_tail - iso9660->wbuff_offset);
+ while (ext_bytes >= iso9660->wbuff_remaining) {
+ if (write_null(a, (size_t)iso9660->wbuff_remaining)
+ != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ ext_bytes -= iso9660->wbuff_remaining;
+ }
+ if (ext_bytes > 0) {
+ if (write_null(a, (size_t)ext_bytes) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
+ }
+ return (ARCHIVE_OK);
+}
+
+#endif /* HAVE_ZLIB_H */
+
+static int
+write_null(struct archive_write *a, size_t size)
+{
+ size_t remaining;
+ unsigned char *p, *old;
+ int r;
+
+ remaining = wb_remaining(a);
+ p = wb_buffptr(a);
+ if (size <= remaining) {
+ memset(p, 0, size);
+ return (wb_consume(a, size));
+ }
+ memset(p, 0, remaining);
+ r = wb_consume(a, remaining);
+ if (r != ARCHIVE_OK)
+ return (r);
+ size -= remaining;
+ old = p;
+ p = wb_buffptr(a);
+ memset(p, 0, old - p);
+ remaining = wb_remaining(a);
+ while (size) {
+ size_t wsize = size;
+
+ if (wsize > remaining)
+ wsize = remaining;
+ r = wb_consume(a, wsize);
+ if (r != ARCHIVE_OK)
+ return (r);
+ size -= wsize;
+ }
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Write Volume Descriptor Set Terminator
+ */
+static int
+write_VD_terminator(struct archive_write *a)
+{
+ unsigned char *bp;
+
+ bp = wb_buffptr(a) -1;
+ set_VD_bp(bp, VDT_TERMINATOR, 1);
+ set_unused_field_bp(bp, 8, LOGICAL_BLOCK_SIZE);
+
+ return (wb_consume(a, LOGICAL_BLOCK_SIZE));
+}
+
+static int
+set_file_identifier(unsigned char *bp, int from, int to, enum vdc vdc,
+ struct archive_write *a, struct vdd *vdd, struct archive_string *id,
+ const char *label, int leading_under, enum char_type char_type)
+{
+ char identifier[256];
+ struct isoent *isoent;
+ const char *ids;
+ size_t len;
+ int r;
+
+ if (id->length > 0 && leading_under && id->s[0] != '_') {
+ if (char_type == A_CHAR)
+ r = set_str_a_characters_bp(a, bp, from, to, id->s, vdc);
+ else
+ r = set_str_d_characters_bp(a, bp, from, to, id->s, vdc);
+ } else if (id->length > 0) {
+ ids = id->s;
+ if (leading_under)
+ ids++;
+ isoent = isoent_find_entry(vdd->rootent, ids);
+ if (isoent == NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Not Found %s `%s'.",
+ label, ids);
+ return (ARCHIVE_FATAL);
+ }
+ len = isoent->ext_off + isoent->ext_len;
+ if (vdd->vdd_type == VDD_JOLIET) {
+ if (len > sizeof(identifier)-2)
+ len = sizeof(identifier)-2;
+ } else {
+ if (len > sizeof(identifier)-1)
+ len = sizeof(identifier)-1;
+ }
+ memcpy(identifier, isoent->identifier, len);
+ identifier[len] = '\0';
+ if (vdd->vdd_type == VDD_JOLIET) {
+ identifier[len+1] = 0;
+ vdc = VDC_UCS2_DIRECT;
+ }
+ if (char_type == A_CHAR)
+ r = set_str_a_characters_bp(a, bp, from, to,
+ identifier, vdc);
+ else
+ r = set_str_d_characters_bp(a, bp, from, to,
+ identifier, vdc);
+ } else {
+ if (char_type == A_CHAR)
+ r = set_str_a_characters_bp(a, bp, from, to, NULL, vdc);
+ else
+ r = set_str_d_characters_bp(a, bp, from, to, NULL, vdc);
+ }
+ return (r);
+}
+
+/*
+ * Write Primary/Supplementary Volume Descriptor
+ */
+static int
+write_VD(struct archive_write *a, struct vdd *vdd)
+{
+ struct iso9660 *iso9660;
+ unsigned char *bp;
+ uint16_t volume_set_size = 1;
+ char identifier[256];
+ enum VD_type vdt;
+ enum vdc vdc;
+ unsigned char vd_ver, fst_ver;
+ int r;
+
+ iso9660 = a->format_data;
+ switch (vdd->vdd_type) {
+ case VDD_JOLIET:
+ vdt = VDT_SUPPLEMENTARY;
+ vd_ver = fst_ver = 1;
+ vdc = VDC_UCS2;
+ break;
+ case VDD_ENHANCED:
+ vdt = VDT_SUPPLEMENTARY;
+ vd_ver = fst_ver = 2;
+ vdc = VDC_LOWERCASE;
+ break;
+ case VDD_PRIMARY:
+ default:
+ vdt = VDT_PRIMARY;
+ vd_ver = fst_ver = 1;
+#ifdef COMPAT_MKISOFS
+ vdc = VDC_LOWERCASE;
+#else
+ vdc = VDC_STD;
+#endif
+ break;
+ }
+
+ bp = wb_buffptr(a) -1;
+ /* Volume Descriptor Type */
+ set_VD_bp(bp, vdt, vd_ver);
+ /* Unused Field */
+ set_unused_field_bp(bp, 8, 8);
+ /* System Identifier */
+ get_system_identitier(identifier, sizeof(identifier));
+ r = set_str_a_characters_bp(a, bp, 9, 40, identifier, vdc);
+ if (r != ARCHIVE_OK)
+ return (r);
+ /* Volume Identifier */
+ r = set_str_d_characters_bp(a, bp, 41, 72,
+ iso9660->volume_identifier.s, vdc);
+ if (r != ARCHIVE_OK)
+ return (r);
+ /* Unused Field */
+ set_unused_field_bp(bp, 73, 80);
+ /* Volume Space Size */
+ set_num_733(bp+81, iso9660->volume_space_size);
+ if (vdd->vdd_type == VDD_JOLIET) {
+ /* Escape Sequences */
+ bp[89] = 0x25;/* UCS-2 Level 3 */
+ bp[90] = 0x2F;
+ bp[91] = 0x45;
+ memset(bp + 92, 0, 120 - 92 + 1);
+ } else {
+ /* Unused Field */
+ set_unused_field_bp(bp, 89, 120);
+ }
+ /* Volume Set Size */
+ set_num_723(bp+121, volume_set_size);
+ /* Volume Sequence Number */
+ set_num_723(bp+125, iso9660->volume_sequence_number);
+ /* Logical Block Size */
+ set_num_723(bp+129, LOGICAL_BLOCK_SIZE);
+ /* Path Table Size */
+ set_num_733(bp+133, vdd->path_table_size);
+ /* Location of Occurrence of Type L Path Table */
+ set_num_731(bp+141, vdd->location_type_L_path_table);
+ /* Location of Optional Occurrence of Type L Path Table */
+ set_num_731(bp+145, 0);
+ /* Location of Occurrence of Type M Path Table */
+ set_num_732(bp+149, vdd->location_type_M_path_table);
+ /* Location of Optional Occurrence of Type M Path Table */
+ set_num_732(bp+153, 0);
+ /* Directory Record for Root Directory(BP 157 to 190) */
+ set_directory_record(bp+157, 190-157+1, vdd->rootent,
+ iso9660, DIR_REC_VD, vdd->vdd_type);
+ /* Volume Set Identifier */
+ r = set_str_d_characters_bp(a, bp, 191, 318, "", vdc);
+ if (r != ARCHIVE_OK)
+ return (r);
+ /* Publisher Identifier */
+ r = set_file_identifier(bp, 319, 446, vdc, a, vdd,
+ &(iso9660->publisher_identifier),
+ "Publisher File", 1, A_CHAR);
+ if (r != ARCHIVE_OK)
+ return (r);
+ /* Data Preparer Identifier */
+ r = set_file_identifier(bp, 447, 574, vdc, a, vdd,
+ &(iso9660->data_preparer_identifier),
+ "Data Preparer File", 1, A_CHAR);
+ if (r != ARCHIVE_OK)
+ return (r);
+ /* Application Identifier */
+ r = set_file_identifier(bp, 575, 702, vdc, a, vdd,
+ &(iso9660->application_identifier),
+ "Application File", 1, A_CHAR);
+ if (r != ARCHIVE_OK)
+ return (r);
+ /* Copyright File Identifier */
+ r = set_file_identifier(bp, 703, 739, vdc, a, vdd,
+ &(iso9660->copyright_file_identifier),
+ "Copyright File", 0, D_CHAR);
+ if (r != ARCHIVE_OK)
+ return (r);
+ /* Abstract File Identifier */
+ r = set_file_identifier(bp, 740, 776, vdc, a, vdd,
+ &(iso9660->abstract_file_identifier),
+ "Abstract File", 0, D_CHAR);
+ if (r != ARCHIVE_OK)
+ return (r);
+ /* Bibliongraphic File Identifier */
+ r = set_file_identifier(bp, 777, 813, vdc, a, vdd,
+ &(iso9660->bibliographic_file_identifier),
+ "Bibliongraphic File", 0, D_CHAR);
+ if (r != ARCHIVE_OK)
+ return (r);
+ /* Volume Creation Date and Time */
+ set_date_time(bp+814, iso9660->birth_time);
+ /* Volume Modification Date and Time */
+ set_date_time(bp+831, iso9660->birth_time);
+ /* Volume Expiration Date and Time(obsolete) */
+ set_date_time_null(bp+848);
+ /* Volume Effective Date and Time */
+ set_date_time(bp+865, iso9660->birth_time);
+ /* File Structure Version */
+ bp[882] = fst_ver;
+ /* Reserved */
+ bp[883] = 0;
+ /* Application Use */
+ memset(bp + 884, 0x20, 1395 - 884 + 1);
+ /* Reserved */
+ set_unused_field_bp(bp, 1396, LOGICAL_BLOCK_SIZE);
+
+ return (wb_consume(a, LOGICAL_BLOCK_SIZE));
+}
+
+/*
+ * Write Boot Record Volume Descriptor
+ */
+static int
+write_VD_boot_record(struct archive_write *a)
+{
+ struct iso9660 *iso9660;
+ unsigned char *bp;
+
+ iso9660 = a->format_data;
+ bp = wb_buffptr(a) -1;
+ /* Volume Descriptor Type */
+ set_VD_bp(bp, VDT_BOOT_RECORD, 1);
+ /* Boot System Identifier */
+ memcpy(bp+8, "EL TORITO SPECIFICATION", 23);
+ set_unused_field_bp(bp, 8+23, 39);
+ /* Unused */
+ set_unused_field_bp(bp, 40, 71);
+ /* Absolute pointer to first sector of Boot Catalog */
+ set_num_731(bp+72,
+ iso9660->el_torito.catalog->file->content.location);
+ /* Unused */
+ set_unused_field_bp(bp, 76, LOGICAL_BLOCK_SIZE);
+
+ return (wb_consume(a, LOGICAL_BLOCK_SIZE));
+}
+
+enum keytype {
+ KEY_FLG,
+ KEY_STR,
+ KEY_INT,
+ KEY_HEX
+};
+static void
+set_option_info(struct archive_string *info, int *opt, const char *key,
+ enum keytype type, ...)
+{
+ va_list ap;
+ char prefix;
+ const char *s;
+ int d;
+
+ prefix = (*opt==0)? ' ':',';
+ va_start(ap, type);
+ switch (type) {
+ case KEY_FLG:
+ d = va_arg(ap, int);
+ archive_string_sprintf(info, "%c%s%s",
+ prefix, (d == 0)?"!":"", key);
+ break;
+ case KEY_STR:
+ s = va_arg(ap, const char *);
+ archive_string_sprintf(info, "%c%s=%s",
+ prefix, key, s);
+ break;
+ case KEY_INT:
+ d = va_arg(ap, int);
+ archive_string_sprintf(info, "%c%s=%d",
+ prefix, key, d);
+ break;
+ case KEY_HEX:
+ d = va_arg(ap, int);
+ archive_string_sprintf(info, "%c%s=%x",
+ prefix, key, d);
+ break;
+ }
+ va_end(ap);
+
+ *opt = 1;
+}
+
+/*
+ * Make Non-ISO File System Information
+ */
+static int
+write_information_block(struct archive_write *a)
+{
+ struct iso9660 *iso9660;
+ char buf[128];
+ const char *v;
+ int opt, r;
+ struct archive_string info;
+ size_t info_size = LOGICAL_BLOCK_SIZE *
+ NON_ISO_FILE_SYSTEM_INFORMATION_BLOCK;
+
+ iso9660 = (struct iso9660 *)a->format_data;
+ if (info_size > wb_remaining(a)) {
+ r = wb_write_out(a);
+ if (r != ARCHIVE_OK)
+ return (r);
+ }
+ archive_string_init(&info);
+ if (archive_string_ensure(&info, info_size) == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+ memset(info.s, 0, info_size);
+ opt = 0;
+#if defined(HAVE__CTIME64_S)
+ _ctime64_s(buf, sizeof(buf), &(iso9660->birth_time));
+#elif defined(HAVE_CTIME_R)
+ ctime_r(&(iso9660->birth_time), buf);
+#else
+ strncpy(buf, ctime(&(iso9660->birth_time)), sizeof(buf)-1);
+ buf[sizeof(buf)-1] = '\0';
+#endif
+ archive_string_sprintf(&info,
+ "INFO %s%s", buf, archive_version_string());
+ if (iso9660->opt.abstract_file != OPT_ABSTRACT_FILE_DEFAULT)
+ set_option_info(&info, &opt, "abstract-file",
+ KEY_STR, iso9660->abstract_file_identifier.s);
+ if (iso9660->opt.application_id != OPT_APPLICATION_ID_DEFAULT)
+ set_option_info(&info, &opt, "application-id",
+ KEY_STR, iso9660->application_identifier.s);
+ if (iso9660->opt.allow_vernum != OPT_ALLOW_VERNUM_DEFAULT)
+ set_option_info(&info, &opt, "allow-vernum",
+ KEY_FLG, iso9660->opt.allow_vernum);
+ if (iso9660->opt.biblio_file != OPT_BIBLIO_FILE_DEFAULT)
+ set_option_info(&info, &opt, "biblio-file",
+ KEY_STR, iso9660->bibliographic_file_identifier.s);
+ if (iso9660->opt.boot != OPT_BOOT_DEFAULT)
+ set_option_info(&info, &opt, "boot",
+ KEY_STR, iso9660->el_torito.boot_filename.s);
+ if (iso9660->opt.boot_catalog != OPT_BOOT_CATALOG_DEFAULT)
+ set_option_info(&info, &opt, "boot-catalog",
+ KEY_STR, iso9660->el_torito.catalog_filename.s);
+ if (iso9660->opt.boot_info_table != OPT_BOOT_INFO_TABLE_DEFAULT)
+ set_option_info(&info, &opt, "boot-info-table",
+ KEY_FLG, iso9660->opt.boot_info_table);
+ if (iso9660->opt.boot_load_seg != OPT_BOOT_LOAD_SEG_DEFAULT)
+ set_option_info(&info, &opt, "boot-load-seg",
+ KEY_HEX, iso9660->el_torito.boot_load_seg);
+ if (iso9660->opt.boot_load_size != OPT_BOOT_LOAD_SIZE_DEFAULT)
+ set_option_info(&info, &opt, "boot-load-size",
+ KEY_INT, iso9660->el_torito.boot_load_size);
+ if (iso9660->opt.boot_type != OPT_BOOT_TYPE_DEFAULT) {
+ v = "no-emulation";
+ if (iso9660->opt.boot_type == OPT_BOOT_TYPE_FD)
+ v = "fd";
+ if (iso9660->opt.boot_type == OPT_BOOT_TYPE_HARD_DISK)
+ v = "hard-disk";
+ set_option_info(&info, &opt, "boot-type",
+ KEY_STR, v);
+ }
+#ifdef HAVE_ZLIB_H
+ if (iso9660->opt.compression_level != OPT_COMPRESSION_LEVEL_DEFAULT)
+ set_option_info(&info, &opt, "compression-level",
+ KEY_INT, iso9660->zisofs.compression_level);
+#endif
+ if (iso9660->opt.copyright_file != OPT_COPYRIGHT_FILE_DEFAULT)
+ set_option_info(&info, &opt, "copyright-file",
+ KEY_STR, iso9660->copyright_file_identifier.s);
+ if (iso9660->opt.iso_level != OPT_ISO_LEVEL_DEFAULT)
+ set_option_info(&info, &opt, "iso-level",
+ KEY_INT, iso9660->opt.iso_level);
+ if (iso9660->opt.joliet != OPT_JOLIET_DEFAULT) {
+ if (iso9660->opt.joliet == OPT_JOLIET_LONGNAME)
+ set_option_info(&info, &opt, "joliet",
+ KEY_STR, "long");
+ else
+ set_option_info(&info, &opt, "joliet",
+ KEY_FLG, iso9660->opt.joliet);
+ }
+ if (iso9660->opt.limit_depth != OPT_LIMIT_DEPTH_DEFAULT)
+ set_option_info(&info, &opt, "limit-depth",
+ KEY_FLG, iso9660->opt.limit_depth);
+ if (iso9660->opt.limit_dirs != OPT_LIMIT_DIRS_DEFAULT)
+ set_option_info(&info, &opt, "limit-dirs",
+ KEY_FLG, iso9660->opt.limit_dirs);
+ if (iso9660->opt.pad != OPT_PAD_DEFAULT)
+ set_option_info(&info, &opt, "pad",
+ KEY_FLG, iso9660->opt.pad);
+ if (iso9660->opt.publisher != OPT_PUBLISHER_DEFAULT)
+ set_option_info(&info, &opt, "publisher",
+ KEY_STR, iso9660->publisher_identifier.s);
+ if (iso9660->opt.rr != OPT_RR_DEFAULT) {
+ if (iso9660->opt.rr == OPT_RR_DISABLED)
+ set_option_info(&info, &opt, "rockridge",
+ KEY_FLG, iso9660->opt.rr);
+ else if (iso9660->opt.rr == OPT_RR_STRICT)
+ set_option_info(&info, &opt, "rockridge",
+ KEY_STR, "strict");
+ else if (iso9660->opt.rr == OPT_RR_USEFUL)
+ set_option_info(&info, &opt, "rockridge",
+ KEY_STR, "useful");
+ }
+ if (iso9660->opt.volume_id != OPT_VOLUME_ID_DEFAULT)
+ set_option_info(&info, &opt, "volume-id",
+ KEY_STR, iso9660->volume_identifier.s);
+ if (iso9660->opt.zisofs != OPT_ZISOFS_DEFAULT)
+ set_option_info(&info, &opt, "zisofs",
+ KEY_FLG, iso9660->opt.zisofs);
+
+ memcpy(wb_buffptr(a), info.s, info_size);
+ archive_string_free(&info);
+ return (wb_consume(a, info_size));
+}
+
+static int
+write_rr_ER(struct archive_write *a)
+{
+ unsigned char *p;
+
+ p = wb_buffptr(a);
+
+ memset(p, 0, LOGICAL_BLOCK_SIZE);
+ p[0] = 'E';
+ p[1] = 'R';
+ p[3] = 0x01;
+ p[2] = RRIP_ER_SIZE;
+ p[4] = RRIP_ER_ID_SIZE;
+ p[5] = RRIP_ER_DSC_SIZE;
+ p[6] = RRIP_ER_SRC_SIZE;
+ p[7] = 0x01;
+ memcpy(&p[8], rrip_identifier, p[4]);
+ memcpy(&p[8+p[4]], rrip_descriptor, p[5]);
+ memcpy(&p[8+p[4]+p[5]], rrip_source, p[6]);
+
+ return (wb_consume(a, LOGICAL_BLOCK_SIZE));
+}
+
+static void
+calculate_path_table_size(struct vdd *vdd)
+{
+ int depth, size;
+ struct path_table *pt;
+
+ pt = vdd->pathtbl;
+ size = 0;
+ for (depth = 0; depth < vdd->max_depth; depth++) {
+ struct isoent **ptbl;
+ int i, cnt;
+
+ if ((cnt = pt[depth].cnt) == 0)
+ break;
+
+ ptbl = pt[depth].sorted;
+ for (i = 0; i < cnt; i++) {
+ int len;
+
+ if (ptbl[i]->identifier == NULL)
+ len = 1; /* root directory */
+ else
+ len = ptbl[i]->id_len;
+ if (len & 0x01)
+ len++; /* Padding Field */
+ size += 8 + len;
+ }
+ }
+ vdd->path_table_size = size;
+ vdd->path_table_block =
+ ((size + PATH_TABLE_BLOCK_SIZE -1) /
+ PATH_TABLE_BLOCK_SIZE) *
+ (PATH_TABLE_BLOCK_SIZE / LOGICAL_BLOCK_SIZE);
+}
+
+static int
+_write_path_table(struct archive_write *a, int type_m, int depth,
+ struct vdd *vdd)
+{
+ unsigned char *bp, *wb;
+ struct isoent **ptbl;
+ size_t wbremaining;
+ int i, r, wsize;
+
+ if (vdd->pathtbl[depth].cnt == 0)
+ return (0);
+
+ wsize = 0;
+ wb = wb_buffptr(a);
+ wbremaining = wb_remaining(a);
+ bp = wb - 1;
+ ptbl = vdd->pathtbl[depth].sorted;
+ for (i = 0; i < vdd->pathtbl[depth].cnt; i++) {
+ struct isoent *np;
+ size_t len;
+
+ np = ptbl[i];
+ if (np->identifier == NULL)
+ len = 1; /* root directory */
+ else
+ len = np->id_len;
+ if (wbremaining - ((bp+1) - wb) < (len + 1 + 8)) {
+ r = wb_consume(a, (bp+1) - wb);
+ if (r < 0)
+ return (r);
+ wb = wb_buffptr(a);
+ wbremaining = wb_remaining(a);
+ bp = wb -1;
+ }
+ /* Length of Directory Identifier */
+ set_num_711(bp+1, len);
+ /* Extended Attribute Record Length */
+ set_num_711(bp+2, 0);
+ /* Location of Extent */
+ if (type_m)
+ set_num_732(bp+3, np->dir_location);
+ else
+ set_num_731(bp+3, np->dir_location);
+ /* Parent Directory Number */
+ if (type_m)
+ set_num_722(bp+7, np->parent->dir_number);
+ else
+ set_num_721(bp+7, np->parent->dir_number);
+ /* Directory Identifier */
+ if (np->identifier == NULL)
+ bp[9] = 0;
+ else
+ memcpy(&bp[9], np->identifier, len);
+ if (len & 0x01) {
+ /* Padding Field */
+ bp[9+len] = 0;
+ len++;
+ }
+ wsize += 8 + len;
+ bp += 8 + len;
+ }
+ if ((bp + 1) > wb) {
+ r = wb_consume(a, (bp+1)-wb);
+ if (r < 0)
+ return (r);
+ }
+ return (wsize);
+}
+
+static int
+write_path_table(struct archive_write *a, int type_m, struct vdd *vdd)
+{
+ int depth, r;
+ size_t path_table_size;
+
+ r = ARCHIVE_OK;
+ path_table_size = 0;
+ for (depth = 0; depth < vdd->max_depth; depth++) {
+ r = _write_path_table(a, type_m, depth, vdd);
+ if (r < 0)
+ return (r);
+ path_table_size += r;
+ }
+
+ /* Write padding data. */
+ path_table_size = path_table_size % PATH_TABLE_BLOCK_SIZE;
+ if (path_table_size > 0)
+ r = write_null(a, PATH_TABLE_BLOCK_SIZE - path_table_size);
+ return (r);
+}
+
+static int
+calculate_directory_descriptors(struct iso9660 *iso9660, struct vdd *vdd,
+ struct isoent *isoent, int depth)
+{
+ struct isoent **enttbl;
+ int bs, block, i;
+
+ block = 1;
+ bs = get_dir_rec_size(iso9660, isoent, DIR_REC_SELF, vdd->vdd_type);
+ bs += get_dir_rec_size(iso9660, isoent, DIR_REC_PARENT, vdd->vdd_type);
+
+ if (isoent->children.cnt <= 0 || (vdd->vdd_type != VDD_JOLIET &&
+ !iso9660->opt.rr && depth + 1 >= vdd->max_depth))
+ return (block);
+
+ enttbl = isoent->children_sorted;
+ for (i = 0; i < isoent->children.cnt; i++) {
+ struct isoent *np = enttbl[i];
+ struct isofile *file;
+
+ file = np->file;
+ if (file->hardlink_target != NULL)
+ file = file->hardlink_target;
+ file->cur_content = &(file->content);
+ do {
+ int dr_l;
+
+ dr_l = get_dir_rec_size(iso9660, np, DIR_REC_NORMAL,
+ vdd->vdd_type);
+ if ((bs + dr_l) > LOGICAL_BLOCK_SIZE) {
+ block ++;
+ bs = dr_l;
+ } else
+ bs += dr_l;
+ file->cur_content = file->cur_content->next;
+ } while (file->cur_content != NULL);
+ }
+ return (block);
+}
+
+static int
+_write_directory_descriptors(struct archive_write *a, struct vdd *vdd,
+ struct isoent *isoent, int depth)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ struct isoent **enttbl;
+ unsigned char *p, *wb;
+ int i, r;
+ int dr_l;
+
+ p = wb = wb_buffptr(a);
+#define WD_REMAINING (LOGICAL_BLOCK_SIZE - (p - wb))
+ p += set_directory_record(p, WD_REMAINING, isoent,
+ iso9660, DIR_REC_SELF, vdd->vdd_type);
+ p += set_directory_record(p, WD_REMAINING, isoent,
+ iso9660, DIR_REC_PARENT, vdd->vdd_type);
+
+ if (isoent->children.cnt <= 0 || (vdd->vdd_type != VDD_JOLIET &&
+ !iso9660->opt.rr && depth + 1 >= vdd->max_depth)) {
+ memset(p, 0, WD_REMAINING);
+ return (wb_consume(a, LOGICAL_BLOCK_SIZE));
+ }
+
+ enttbl = isoent->children_sorted;
+ for (i = 0; i < isoent->children.cnt; i++) {
+ struct isoent *np = enttbl[i];
+ struct isofile *file = np->file;
+
+ if (file->hardlink_target != NULL)
+ file = file->hardlink_target;
+ file->cur_content = &(file->content);
+ do {
+ dr_l = set_directory_record(p, WD_REMAINING,
+ np, iso9660, DIR_REC_NORMAL,
+ vdd->vdd_type);
+ if (dr_l == 0) {
+ memset(p, 0, WD_REMAINING);
+ r = wb_consume(a, LOGICAL_BLOCK_SIZE);
+ if (r < 0)
+ return (r);
+ p = wb = wb_buffptr(a);
+ dr_l = set_directory_record(p,
+ WD_REMAINING, np, iso9660,
+ DIR_REC_NORMAL, vdd->vdd_type);
+ }
+ p += dr_l;
+ file->cur_content = file->cur_content->next;
+ } while (file->cur_content != NULL);
+ }
+ memset(p, 0, WD_REMAINING);
+ return (wb_consume(a, LOGICAL_BLOCK_SIZE));
+}
+
+static int
+write_directory_descriptors(struct archive_write *a, struct vdd *vdd)
+{
+ struct isoent *np;
+ int depth, r;
+
+ depth = 0;
+ np = vdd->rootent;
+ do {
+ struct extr_rec *extr;
+
+ r = _write_directory_descriptors(a, vdd, np, depth);
+ if (r < 0)
+ return (r);
+ if (vdd->vdd_type != VDD_JOLIET) {
+ /*
+ * This extract record is used by SUSP,RRIP.
+ * Not for joliet.
+ */
+ for (extr = np->extr_rec_list.first;
+ extr != NULL;
+ extr = extr->next) {
+ unsigned char *wb;
+
+ wb = wb_buffptr(a);
+ memcpy(wb, extr->buf, extr->offset);
+ memset(wb + extr->offset, 0,
+ LOGICAL_BLOCK_SIZE - extr->offset);
+ r = wb_consume(a, LOGICAL_BLOCK_SIZE);
+ if (r < 0)
+ return (r);
+ }
+ }
+
+ if (np->subdirs.first != NULL && depth + 1 < vdd->max_depth) {
+ /* Enter to sub directories. */
+ np = np->subdirs.first;
+ depth++;
+ continue;
+ }
+ while (np != np->parent) {
+ if (np->drnext == NULL) {
+ /* Return to the parent directory. */
+ np = np->parent;
+ depth--;
+ } else {
+ np = np->drnext;
+ break;
+ }
+ }
+ } while (np != np->parent);
+
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Read file contents from the temporary file, and write it.
+ */
+static int
+write_file_contents(struct archive_write *a, int64_t offset, int64_t size)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ int r;
+
+ lseek(iso9660->temp_fd, offset, SEEK_SET);
+
+ while (size) {
+ size_t rsize;
+ ssize_t rs;
+ unsigned char *wb;
+
+ wb = wb_buffptr(a);
+ rsize = wb_remaining(a);
+ if (rsize > (size_t)size)
+ rsize = (size_t)size;
+ rs = read(iso9660->temp_fd, wb, rsize);
+ if (rs <= 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't read temporary file(%jd)", (intmax_t)rs);
+ return (ARCHIVE_FATAL);
+ }
+ size -= rs;
+ r = wb_consume(a, rs);
+ if (r < 0)
+ return (r);
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+write_file_descriptors(struct archive_write *a)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ struct isofile *file;
+ int64_t blocks, offset;
+ int r;
+
+ blocks = 0;
+ offset = 0;
+
+ /* Make the boot catalog contents, and write it. */
+ if (iso9660->el_torito.catalog != NULL) {
+ r = make_boot_catalog(a);
+ if (r < 0)
+ return (r);
+ }
+
+ /* Write the boot file contents. */
+ if (iso9660->el_torito.boot != NULL) {
+ struct isofile *file = iso9660->el_torito.boot->file;
+
+ blocks = file->content.blocks;
+ offset = file->content.offset_of_temp;
+ if (offset != 0) {
+ r = write_file_contents(a, offset,
+ blocks << LOGICAL_BLOCK_BITS);
+ if (r < 0)
+ return (r);
+ blocks = 0;
+ offset = 0;
+ }
+ }
+
+ /* Write out all file contents. */
+ for (file = iso9660->data_file_list.first;
+ file != NULL; file = file->datanext) {
+
+ if (!file->write_content)
+ continue;
+
+ if ((offset + (blocks << LOGICAL_BLOCK_BITS)) <
+ file->content.offset_of_temp) {
+ if (blocks > 0) {
+ r = write_file_contents(a, offset,
+ blocks << LOGICAL_BLOCK_BITS);
+ if (r < 0)
+ return (r);
+ }
+ blocks = 0;
+ offset = file->content.offset_of_temp;
+ }
+
+ file->cur_content = &(file->content);
+ do {
+ blocks += file->cur_content->blocks;
+ /* Next fragument */
+ file->cur_content = file->cur_content->next;
+ } while (file->cur_content != NULL);
+ }
+
+ /* Flush out remaining blocks. */
+ if (blocks > 0) {
+ r = write_file_contents(a, offset,
+ blocks << LOGICAL_BLOCK_BITS);
+ if (r < 0)
+ return (r);
+ }
+
+ return (ARCHIVE_OK);
+}
+
+static void
+isofile_init_entry_list(struct iso9660 *iso9660)
+{
+ iso9660->all_file_list.first = NULL;
+ iso9660->all_file_list.last = &(iso9660->all_file_list.first);
+}
+
+static void
+isofile_add_entry(struct iso9660 *iso9660, struct isofile *file)
+{
+ file->allnext = NULL;
+ *iso9660->all_file_list.last = file;
+ iso9660->all_file_list.last = &(file->allnext);
+}
+
+static void
+isofile_free_all_entries(struct iso9660 *iso9660)
+{
+ struct isofile *file, *file_next;
+
+ file = iso9660->all_file_list.first;
+ while (file != NULL) {
+ file_next = file->allnext;
+ isofile_free(file);
+ file = file_next;
+ }
+}
+
+static void
+isofile_init_entry_data_file_list(struct iso9660 *iso9660)
+{
+ iso9660->data_file_list.first = NULL;
+ iso9660->data_file_list.last = &(iso9660->data_file_list.first);
+}
+
+static void
+isofile_add_data_file(struct iso9660 *iso9660, struct isofile *file)
+{
+ file->datanext = NULL;
+ *iso9660->data_file_list.last = file;
+ iso9660->data_file_list.last = &(file->datanext);
+}
+
+
+static struct isofile *
+isofile_new(struct archive_write *a, struct archive_entry *entry)
+{
+ struct isofile *file;
+
+ file = calloc(1, sizeof(*file));
+ if (file == NULL)
+ return (NULL);
+
+ if (entry != NULL)
+ file->entry = archive_entry_clone(entry);
+ else
+ file->entry = archive_entry_new2(&a->archive);
+ if (file->entry == NULL) {
+ free(file);
+ return (NULL);
+ }
+ archive_string_init(&(file->parentdir));
+ archive_string_init(&(file->basename));
+ archive_string_init(&(file->basename_utf16));
+ archive_string_init(&(file->symlink));
+ file->cur_content = &(file->content);
+
+ return (file);
+}
+
+static void
+isofile_free(struct isofile *file)
+{
+ struct content *con, *tmp;
+
+ con = file->content.next;
+ while (con != NULL) {
+ tmp = con;
+ con = con->next;
+ free(tmp);
+ }
+ archive_entry_free(file->entry);
+ archive_string_free(&(file->parentdir));
+ archive_string_free(&(file->basename));
+ archive_string_free(&(file->basename_utf16));
+ archive_string_free(&(file->symlink));
+ free(file);
+}
+
+#if defined(_WIN32) || defined(__CYGWIN__)
+static int
+cleanup_backslash_1(char *p)
+{
+ int mb, dos;
+
+ mb = dos = 0;
+ while (*p) {
+ if (*(unsigned char *)p > 127)
+ mb = 1;
+ if (*p == '\\') {
+ /* If we have not met any multi-byte characters,
+ * we can replace '\' with '/'. */
+ if (!mb)
+ *p = '/';
+ dos = 1;
+ }
+ p++;
+ }
+ if (!mb || !dos)
+ return (0);
+ return (-1);
+}
+
+static void
+cleanup_backslash_2(wchar_t *p)
+{
+
+ /* Convert a path-separator from '\' to '/' */
+ while (*p != L'\0') {
+ if (*p == L'\\')
+ *p = L'/';
+ p++;
+ }
+}
+#endif
+
+/*
+ * Generate a parent directory name and a base name from a pathname.
+ */
+static int
+isofile_gen_utility_names(struct archive_write *a, struct isofile *file)
+{
+ struct iso9660 *iso9660;
+ const char *pathname;
+ char *p, *dirname, *slash;
+ size_t len;
+ int ret = ARCHIVE_OK;
+
+ iso9660 = a->format_data;
+
+ archive_string_empty(&(file->parentdir));
+ archive_string_empty(&(file->basename));
+ archive_string_empty(&(file->basename_utf16));
+ archive_string_empty(&(file->symlink));
+
+ pathname = archive_entry_pathname(file->entry);
+ if (pathname == NULL || pathname[0] == '\0') {/* virtual root */
+ file->dircnt = 0;
+ return (ret);
+ }
+
+ /*
+ * Make a UTF-16BE basename if Joliet extension enabled.
+ */
+ if (iso9660->opt.joliet) {
+ const char *u16, *ulast;
+ size_t u16len, ulen_last;
+
+ if (iso9660->sconv_to_utf16be == NULL) {
+ iso9660->sconv_to_utf16be =
+ archive_string_conversion_to_charset(
+ &(a->archive), "UTF-16BE", 1);
+ if (iso9660->sconv_to_utf16be == NULL)
+ /* Couldn't allocate memory */
+ return (ARCHIVE_FATAL);
+ iso9660->sconv_from_utf16be =
+ archive_string_conversion_from_charset(
+ &(a->archive), "UTF-16BE", 1);
+ if (iso9660->sconv_from_utf16be == NULL)
+ /* Couldn't allocate memory */
+ return (ARCHIVE_FATAL);
+ }
+
+ /*
+ * Converte a filename to UTF-16BE.
+ */
+ if (0 > archive_entry_pathname_l(file->entry, &u16, &u16len,
+ iso9660->sconv_to_utf16be)) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for UTF-16BE");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "A filename cannot be converted to UTF-16BE;"
+ "You should disable making Joliet extension");
+ ret = ARCHIVE_WARN;
+ }
+
+ /*
+ * Make sure a path separator is not in the last;
+ * Remove trailing '/'.
+ */
+ while (u16len >= 2) {
+#if defined(_WIN32) || defined(__CYGWIN__)
+ if (u16[u16len-2] == 0 &&
+ (u16[u16len-1] == '/' || u16[u16len-1] == '\\'))
+#else
+ if (u16[u16len-2] == 0 && u16[u16len-1] == '/')
+#endif
+ {
+ u16len -= 2;
+ } else
+ break;
+ }
+
+ /*
+ * Find a basename in UTF-16BE.
+ */
+ ulast = u16;
+ u16len >>= 1;
+ ulen_last = u16len;
+ while (u16len > 0) {
+#if defined(_WIN32) || defined(__CYGWIN__)
+ if (u16[0] == 0 && (u16[1] == '/' || u16[1] == '\\'))
+#else
+ if (u16[0] == 0 && u16[1] == '/')
+#endif
+ {
+ ulast = u16 + 2;
+ ulen_last = u16len -1;
+ }
+ u16 += 2;
+ u16len --;
+ }
+ ulen_last <<= 1;
+ if (archive_string_ensure(&(file->basename_utf16),
+ ulen_last) == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for UTF-16BE");
+ return (ARCHIVE_FATAL);
+ }
+
+ /*
+ * Set UTF-16BE basename.
+ */
+ memcpy(file->basename_utf16.s, ulast, ulen_last);
+ file->basename_utf16.length = ulen_last;
+ }
+
+ archive_strcpy(&(file->parentdir), pathname);
+#if defined(_WIN32) || defined(__CYGWIN__)
+ /*
+ * Convert a path-separator from '\' to '/'
+ */
+ if (cleanup_backslash_1(file->parentdir.s) != 0) {
+ const wchar_t *wp = archive_entry_pathname_w(file->entry);
+ struct archive_wstring ws;
+
+ if (wp != NULL) {
+ archive_string_init(&ws);
+ archive_wstrcpy(&ws, wp);
+ cleanup_backslash_2(ws.s);
+ archive_string_empty(&(file->parentdir));
+ archive_string_append_from_wcs(&(file->parentdir),
+ ws.s, ws.length);
+ archive_wstring_free(&ws);
+ }
+ }
+#endif
+
+ len = file->parentdir.length;
+ p = dirname = file->parentdir.s;
+
+ /*
+ * Remove leading '/', '../' and './' elements
+ */
+ while (*p) {
+ if (p[0] == '/') {
+ p++;
+ len--;
+ } else if (p[0] != '.')
+ break;
+ else if (p[1] == '.' && p[2] == '/') {
+ p += 3;
+ len -= 3;
+ } else if (p[1] == '/' || (p[1] == '.' && p[2] == '\0')) {
+ p += 2;
+ len -= 2;
+ } else if (p[1] == '\0') {
+ p++;
+ len--;
+ } else
+ break;
+ }
+ if (p != dirname) {
+ memmove(dirname, p, len+1);
+ p = dirname;
+ }
+ /*
+ * Remove "/","/." and "/.." elements from tail.
+ */
+ while (len > 0) {
+ size_t ll = len;
+
+ if (len > 0 && p[len-1] == '/') {
+ p[len-1] = '\0';
+ len--;
+ }
+ if (len > 1 && p[len-2] == '/' && p[len-1] == '.') {
+ p[len-2] = '\0';
+ len -= 2;
+ }
+ if (len > 2 && p[len-3] == '/' && p[len-2] == '.' &&
+ p[len-1] == '.') {
+ p[len-3] = '\0';
+ len -= 3;
+ }
+ if (ll == len)
+ break;
+ }
+ while (*p) {
+ if (p[0] == '/') {
+ if (p[1] == '/')
+ /* Convert '//' --> '/' */
+ strcpy(p, p+1);
+ else if (p[1] == '.' && p[2] == '/')
+ /* Convert '/./' --> '/' */
+ strcpy(p, p+2);
+ else if (p[1] == '.' && p[2] == '.' && p[3] == '/') {
+ /* Convert 'dir/dir1/../dir2/'
+ * --> 'dir/dir2/'
+ */
+ char *rp = p -1;
+ while (rp >= dirname) {
+ if (*rp == '/')
+ break;
+ --rp;
+ }
+ if (rp > dirname) {
+ strcpy(rp, p+3);
+ p = rp;
+ } else {
+ strcpy(dirname, p+4);
+ p = dirname;
+ }
+ } else
+ p++;
+ } else
+ p++;
+ }
+ p = dirname;
+ len = strlen(p);
+
+ if (archive_entry_filetype(file->entry) == AE_IFLNK) {
+ /* Convert symlink name too. */
+ pathname = archive_entry_symlink(file->entry);
+ archive_strcpy(&(file->symlink), pathname);
+#if defined(_WIN32) || defined(__CYGWIN__)
+ /*
+ * Convert a path-separator from '\' to '/'
+ */
+ if (archive_strlen(&(file->symlink)) > 0 &&
+ cleanup_backslash_1(file->symlink.s) != 0) {
+ const wchar_t *wp =
+ archive_entry_symlink_w(file->entry);
+ struct archive_wstring ws;
+
+ if (wp != NULL) {
+ archive_string_init(&ws);
+ archive_wstrcpy(&ws, wp);
+ cleanup_backslash_2(ws.s);
+ archive_string_empty(&(file->symlink));
+ archive_string_append_from_wcs(
+ &(file->symlink),
+ ws.s, ws.length);
+ archive_wstring_free(&ws);
+ }
+ }
+#endif
+ }
+ /*
+ * - Count up directory elements.
+ * - Find out the position which points the last position of
+ * path separator('/').
+ */
+ slash = NULL;
+ file->dircnt = 0;
+ for (; *p != '\0'; p++)
+ if (*p == '/') {
+ slash = p;
+ file->dircnt++;
+ }
+ if (slash == NULL) {
+ /* The pathname doesn't have a parent directory. */
+ file->parentdir.length = len;
+ archive_string_copy(&(file->basename), &(file->parentdir));
+ archive_string_empty(&(file->parentdir));
+ *file->parentdir.s = '\0';
+ return (ret);
+ }
+
+ /* Make a basename from dirname and slash */
+ *slash = '\0';
+ file->parentdir.length = slash - dirname;
+ archive_strcpy(&(file->basename), slash + 1);
+ if (archive_entry_filetype(file->entry) == AE_IFDIR)
+ file->dircnt ++;
+ return (ret);
+}
+
+/*
+ * Register a entry to get a hardlink target.
+ */
+static int
+isofile_register_hardlink(struct archive_write *a, struct isofile *file)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ struct hardlink *hl;
+ const char *pathname;
+
+ archive_entry_set_nlink(file->entry, 1);
+ pathname = archive_entry_hardlink(file->entry);
+ if (pathname == NULL) {
+ /* This `file` is a hardlink target. */
+ hl = malloc(sizeof(*hl));
+ if (hl == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+ hl->nlink = 1;
+ /* A hardlink target must be the first position. */
+ file->hlnext = NULL;
+ hl->file_list.first = file;
+ hl->file_list.last = &(file->hlnext);
+ __archive_rb_tree_insert_node(&(iso9660->hardlink_rbtree),
+ (struct archive_rb_node *)hl);
+ } else {
+ hl = (struct hardlink *)__archive_rb_tree_find_node(
+ &(iso9660->hardlink_rbtree), pathname);
+ if (hl != NULL) {
+ /* Insert `file` entry into the tail. */
+ file->hlnext = NULL;
+ *hl->file_list.last = file;
+ hl->file_list.last = &(file->hlnext);
+ hl->nlink++;
+ }
+ archive_entry_unset_size(file->entry);
+ }
+
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Hardlinked files have to have the same location of extent.
+ * We have to find out hardlink target entries for the entries
+ * which have a hardlink target name.
+ */
+static void
+isofile_connect_hardlink_files(struct iso9660 *iso9660)
+{
+ struct archive_rb_node *n;
+ struct hardlink *hl;
+ struct isofile *target, *nf;
+
+ ARCHIVE_RB_TREE_FOREACH(n, &(iso9660->hardlink_rbtree)) {
+ hl = (struct hardlink *)n;
+
+ /* The first entry must be a hardlink target. */
+ target = hl->file_list.first;
+ archive_entry_set_nlink(target->entry, hl->nlink);
+ /* Set a hardlink target to reference entries. */
+ for (nf = target->hlnext;
+ nf != NULL; nf = nf->hlnext) {
+ nf->hardlink_target = target;
+ archive_entry_set_nlink(nf->entry, hl->nlink);
+ }
+ }
+}
+
+static int
+isofile_hd_cmp_node(const struct archive_rb_node *n1,
+ const struct archive_rb_node *n2)
+{
+ const struct hardlink *h1 = (const struct hardlink *)n1;
+ const struct hardlink *h2 = (const struct hardlink *)n2;
+
+ return (strcmp(archive_entry_pathname(h1->file_list.first->entry),
+ archive_entry_pathname(h2->file_list.first->entry)));
+}
+
+static int
+isofile_hd_cmp_key(const struct archive_rb_node *n, const void *key)
+{
+ const struct hardlink *h = (const struct hardlink *)n;
+
+ return (strcmp(archive_entry_pathname(h->file_list.first->entry),
+ (const char *)key));
+}
+
+static void
+isofile_init_hardlinks(struct iso9660 *iso9660)
+{
+ static const struct archive_rb_tree_ops rb_ops = {
+ isofile_hd_cmp_node, isofile_hd_cmp_key,
+ };
+
+ __archive_rb_tree_init(&(iso9660->hardlink_rbtree), &rb_ops);
+}
+
+static void
+isofile_free_hardlinks(struct iso9660 *iso9660)
+{
+ struct archive_rb_node *n, *next;
+
+ for (n = ARCHIVE_RB_TREE_MIN(&(iso9660->hardlink_rbtree)); n;) {
+ next = __archive_rb_tree_iterate(&(iso9660->hardlink_rbtree),
+ n, ARCHIVE_RB_DIR_RIGHT);
+ free(n);
+ n = next;
+ }
+}
+
+static struct isoent *
+isoent_new(struct isofile *file)
+{
+ struct isoent *isoent;
+ static const struct archive_rb_tree_ops rb_ops = {
+ isoent_cmp_node, isoent_cmp_key,
+ };
+
+ isoent = calloc(1, sizeof(*isoent));
+ if (isoent == NULL)
+ return (NULL);
+ isoent->file = file;
+ isoent->children.first = NULL;
+ isoent->children.last = &(isoent->children.first);
+ __archive_rb_tree_init(&(isoent->rbtree), &rb_ops);
+ isoent->subdirs.first = NULL;
+ isoent->subdirs.last = &(isoent->subdirs.first);
+ isoent->extr_rec_list.first = NULL;
+ isoent->extr_rec_list.last = &(isoent->extr_rec_list.first);
+ isoent->extr_rec_list.current = NULL;
+ if (archive_entry_filetype(file->entry) == AE_IFDIR)
+ isoent->dir = 1;
+
+ return (isoent);
+}
+
+static inline struct isoent *
+isoent_clone(struct isoent *src)
+{
+ return (isoent_new(src->file));
+}
+
+static void
+_isoent_free(struct isoent *isoent)
+{
+ struct extr_rec *er, *er_next;
+
+ free(isoent->children_sorted);
+ free(isoent->identifier);
+ er = isoent->extr_rec_list.first;
+ while (er != NULL) {
+ er_next = er->next;
+ free(er);
+ er = er_next;
+ }
+ free(isoent);
+}
+
+static void
+isoent_free_all(struct isoent *isoent)
+{
+ struct isoent *np, *np_temp;
+
+ if (isoent == NULL)
+ return;
+ np = isoent;
+ for (;;) {
+ if (np->dir) {
+ if (np->children.first != NULL) {
+ /* Enter to sub directories. */
+ np = np->children.first;
+ continue;
+ }
+ }
+ for (;;) {
+ np_temp = np;
+ if (np->chnext == NULL) {
+ /* Return to the parent directory. */
+ np = np->parent;
+ _isoent_free(np_temp);
+ if (np == np_temp)
+ return;
+ } else {
+ np = np->chnext;
+ _isoent_free(np_temp);
+ break;
+ }
+ }
+ }
+}
+
+static struct isoent *
+isoent_create_virtual_dir(struct archive_write *a, struct iso9660 *iso9660, const char *pathname)
+{
+ struct isofile *file;
+ struct isoent *isoent;
+
+ file = isofile_new(a, NULL);
+ if (file == NULL)
+ return (NULL);
+ archive_entry_set_pathname(file->entry, pathname);
+ archive_entry_unset_mtime(file->entry);
+ archive_entry_unset_atime(file->entry);
+ archive_entry_unset_ctime(file->entry);
+ archive_entry_set_uid(file->entry, getuid());
+ archive_entry_set_gid(file->entry, getgid());
+ archive_entry_set_mode(file->entry, 0555 | AE_IFDIR);
+ archive_entry_set_nlink(file->entry, 2);
+ if (isofile_gen_utility_names(a, file) < ARCHIVE_WARN) {
+ isofile_free(file);
+ return (NULL);
+ }
+ isofile_add_entry(iso9660, file);
+
+ isoent = isoent_new(file);
+ if (isoent == NULL)
+ return (NULL);
+ isoent->dir = 1;
+ isoent->virtual = 1;
+
+ return (isoent);
+}
+
+static int
+isoent_cmp_node(const struct archive_rb_node *n1,
+ const struct archive_rb_node *n2)
+{
+ const struct isoent *e1 = (const struct isoent *)n1;
+ const struct isoent *e2 = (const struct isoent *)n2;
+
+ return (strcmp(e1->file->basename.s, e2->file->basename.s));
+}
+
+static int
+isoent_cmp_key(const struct archive_rb_node *n, const void *key)
+{
+ const struct isoent *e = (const struct isoent *)n;
+
+ return (strcmp(e->file->basename.s, (const char *)key));
+}
+
+static int
+isoent_add_child_head(struct isoent *parent, struct isoent *child)
+{
+
+ if (!__archive_rb_tree_insert_node(
+ &(parent->rbtree), (struct archive_rb_node *)child))
+ return (0);
+ if ((child->chnext = parent->children.first) == NULL)
+ parent->children.last = &(child->chnext);
+ parent->children.first = child;
+ parent->children.cnt++;
+ child->parent = parent;
+
+ /* Add a child to a sub-directory chain */
+ if (child->dir) {
+ if ((child->drnext = parent->subdirs.first) == NULL)
+ parent->subdirs.last = &(child->drnext);
+ parent->subdirs.first = child;
+ parent->subdirs.cnt++;
+ child->parent = parent;
+ } else
+ child->drnext = NULL;
+ return (1);
+}
+
+static int
+isoent_add_child_tail(struct isoent *parent, struct isoent *child)
+{
+
+ if (!__archive_rb_tree_insert_node(
+ &(parent->rbtree), (struct archive_rb_node *)child))
+ return (0);
+ child->chnext = NULL;
+ *parent->children.last = child;
+ parent->children.last = &(child->chnext);
+ parent->children.cnt++;
+ child->parent = parent;
+
+ /* Add a child to a sub-directory chain */
+ child->drnext = NULL;
+ if (child->dir) {
+ *parent->subdirs.last = child;
+ parent->subdirs.last = &(child->drnext);
+ parent->subdirs.cnt++;
+ child->parent = parent;
+ }
+ return (1);
+}
+
+static void
+isoent_remove_child(struct isoent *parent, struct isoent *child)
+{
+ struct isoent *ent;
+
+ /* Remove a child entry from children chain. */
+ ent = parent->children.first;
+ while (ent->chnext != child)
+ ent = ent->chnext;
+ if ((ent->chnext = ent->chnext->chnext) == NULL)
+ parent->children.last = &(ent->chnext);
+ parent->children.cnt--;
+
+ if (child->dir) {
+ /* Remove a child entry from sub-directory chain. */
+ ent = parent->subdirs.first;
+ while (ent->drnext != child)
+ ent = ent->drnext;
+ if ((ent->drnext = ent->drnext->drnext) == NULL)
+ parent->subdirs.last = &(ent->drnext);
+ parent->subdirs.cnt--;
+ }
+
+ __archive_rb_tree_remove_node(&(parent->rbtree),
+ (struct archive_rb_node *)child);
+}
+
+static int
+isoent_clone_tree(struct archive_write *a, struct isoent **nroot,
+ struct isoent *root)
+{
+ struct isoent *np, *xroot, *newent;
+
+ np = root;
+ xroot = NULL;
+ do {
+ newent = isoent_clone(np);
+ if (newent == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+ if (xroot == NULL) {
+ *nroot = xroot = newent;
+ newent->parent = xroot;
+ } else
+ isoent_add_child_tail(xroot, newent);
+ if (np->dir && np->children.first != NULL) {
+ /* Enter to sub directories. */
+ np = np->children.first;
+ xroot = newent;
+ continue;
+ }
+ while (np != np->parent) {
+ if (np->chnext == NULL) {
+ /* Return to the parent directory. */
+ np = np->parent;
+ xroot = xroot->parent;
+ } else {
+ np = np->chnext;
+ break;
+ }
+ }
+ } while (np != np->parent);
+
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Setup directory locations.
+ */
+static void
+isoent_setup_directory_location(struct iso9660 *iso9660, int location,
+ struct vdd *vdd)
+{
+ struct isoent *np;
+ int depth;
+
+ vdd->total_dir_block = 0;
+ depth = 0;
+ np = vdd->rootent;
+ do {
+ int block;
+
+ np->dir_block = calculate_directory_descriptors(
+ iso9660, vdd, np, depth);
+ vdd->total_dir_block += np->dir_block;
+ np->dir_location = location;
+ location += np->dir_block;
+ block = extra_setup_location(np, location);
+ vdd->total_dir_block += block;
+ location += block;
+
+ if (np->subdirs.first != NULL && depth + 1 < vdd->max_depth) {
+ /* Enter to sub directories. */
+ np = np->subdirs.first;
+ depth++;
+ continue;
+ }
+ while (np != np->parent) {
+ if (np->drnext == NULL) {
+ /* Return to the parent directory. */
+ np = np->parent;
+ depth--;
+ } else {
+ np = np->drnext;
+ break;
+ }
+ }
+ } while (np != np->parent);
+}
+
+static void
+_isoent_file_location(struct iso9660 *iso9660, struct isoent *isoent,
+ int *symlocation)
+{
+ struct isoent **children;
+ int n;
+
+ if (isoent->children.cnt == 0)
+ return;
+
+ children = isoent->children_sorted;
+ for (n = 0; n < isoent->children.cnt; n++) {
+ struct isoent *np;
+ struct isofile *file;
+
+ np = children[n];
+ if (np->dir)
+ continue;
+ if (np == iso9660->el_torito.boot)
+ continue;
+ file = np->file;
+ if (file->boot || file->hardlink_target != NULL)
+ continue;
+ if (archive_entry_filetype(file->entry) == AE_IFLNK ||
+ file->content.size == 0) {
+ /*
+ * Do not point a valid location.
+ * Make sure entry is not hardlink file.
+ */
+ file->content.location = (*symlocation)--;
+ continue;
+ }
+
+ file->write_content = 1;
+ }
+}
+
+/*
+ * Setup file locations.
+ */
+static void
+isoent_setup_file_location(struct iso9660 *iso9660, int location)
+{
+ struct isoent *isoent;
+ struct isoent *np;
+ struct isofile *file;
+ size_t size;
+ int block;
+ int depth;
+ int joliet;
+ int symlocation;
+ int total_block;
+
+ iso9660->total_file_block = 0;
+ if ((isoent = iso9660->el_torito.catalog) != NULL) {
+ isoent->file->content.location = location;
+ block = (archive_entry_size(isoent->file->entry) +
+ LOGICAL_BLOCK_SIZE -1) >> LOGICAL_BLOCK_BITS;
+ location += block;
+ iso9660->total_file_block += block;
+ }
+ if ((isoent = iso9660->el_torito.boot) != NULL) {
+ isoent->file->content.location = location;
+ size = fd_boot_image_size(iso9660->el_torito.media_type);
+ if (size == 0)
+ size = archive_entry_size(isoent->file->entry);
+ block = (size + LOGICAL_BLOCK_SIZE -1) >> LOGICAL_BLOCK_BITS;
+ location += block;
+ iso9660->total_file_block += block;
+ isoent->file->content.blocks = block;
+ }
+
+ depth = 0;
+ symlocation = -16;
+ if (!iso9660->opt.rr && iso9660->opt.joliet) {
+ joliet = 1;
+ np = iso9660->joliet.rootent;
+ } else {
+ joliet = 0;
+ np = iso9660->primary.rootent;
+ }
+ do {
+ _isoent_file_location(iso9660, np, &symlocation);
+
+ if (np->subdirs.first != NULL &&
+ (joliet ||
+ ((iso9660->opt.rr == OPT_RR_DISABLED &&
+ depth + 2 < iso9660->primary.max_depth) ||
+ (iso9660->opt.rr &&
+ depth + 1 < iso9660->primary.max_depth)))) {
+ /* Enter to sub directories. */
+ np = np->subdirs.first;
+ depth++;
+ continue;
+ }
+ while (np != np->parent) {
+ if (np->drnext == NULL) {
+ /* Return to the parent directory. */
+ np = np->parent;
+ depth--;
+ } else {
+ np = np->drnext;
+ break;
+ }
+ }
+ } while (np != np->parent);
+
+ total_block = 0;
+ for (file = iso9660->data_file_list.first;
+ file != NULL; file = file->datanext) {
+
+ if (!file->write_content)
+ continue;
+
+ file->cur_content = &(file->content);
+ do {
+ file->cur_content->location = location;
+ location += file->cur_content->blocks;
+ total_block += file->cur_content->blocks;
+ /* Next fragument */
+ file->cur_content = file->cur_content->next;
+ } while (file->cur_content != NULL);
+ }
+ iso9660->total_file_block += total_block;
+}
+
+static int
+get_path_component(char *name, int n, const char *fn)
+{
+ char *p;
+ int l;
+
+ p = strchr(fn, '/');
+ if (p == NULL) {
+ if ((l = strlen(fn)) == 0)
+ return (0);
+ } else
+ l = p - fn;
+ if (l > n -1)
+ return (-1);
+ memcpy(name, fn, l);
+ name[l] = '\0';
+
+ return (l);
+}
+
+/*
+ * Add a new entry into the tree.
+ */
+static int
+isoent_tree(struct archive_write *a, struct isoent **isoentpp)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ char name[_MAX_FNAME];/* Included null terminator size. */
+#elif defined(NAME_MAX) && NAME_MAX >= 255
+ char name[NAME_MAX+1];
+#else
+ char name[256];
+#endif
+ struct iso9660 *iso9660 = a->format_data;
+ struct isoent *dent, *isoent, *np;
+ struct isofile *f1, *f2;
+ const char *fn, *p;
+ int l;
+
+ isoent = *isoentpp;
+ dent = iso9660->primary.rootent;
+ if (isoent->file->parentdir.length > 0)
+ fn = p = isoent->file->parentdir.s;
+ else
+ fn = p = "";
+
+ /*
+ * If the path of the parent directory of `isoent' entry is
+ * the same as the path of `cur_dirent', add isoent to
+ * `cur_dirent'.
+ */
+ if (archive_strlen(&(iso9660->cur_dirstr))
+ == archive_strlen(&(isoent->file->parentdir)) &&
+ strcmp(iso9660->cur_dirstr.s, fn) == 0) {
+ if (!isoent_add_child_tail(iso9660->cur_dirent, isoent)) {
+ np = (struct isoent *)__archive_rb_tree_find_node(
+ &(iso9660->cur_dirent->rbtree),
+ isoent->file->basename.s);
+ goto same_entry;
+ }
+ return (ARCHIVE_OK);
+ }
+
+ for (;;) {
+ l = get_path_component(name, sizeof(name), fn);
+ if (l == 0) {
+ np = NULL;
+ break;
+ }
+ if (l < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "A name buffer is too small");
+ _isoent_free(isoent);
+ return (ARCHIVE_FATAL);
+ }
+
+ np = isoent_find_child(dent, name);
+ if (np == NULL || fn[0] == '\0')
+ break;
+
+ /* Find next subdirectory. */
+ if (!np->dir) {
+ /* NOT Directory! */
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "`%s' is not directory, we cannot insert `%s' ",
+ archive_entry_pathname(np->file->entry),
+ archive_entry_pathname(isoent->file->entry));
+ _isoent_free(isoent);
+ *isoentpp = NULL;
+ return (ARCHIVE_FAILED);
+ }
+ fn += l;
+ if (fn[0] == '/')
+ fn++;
+ dent = np;
+ }
+ if (np == NULL) {
+ /*
+ * Create virtual parent directories.
+ */
+ while (fn[0] != '\0') {
+ struct isoent *vp;
+ struct archive_string as;
+
+ archive_string_init(&as);
+ archive_strncat(&as, p, fn - p + l);
+ if (as.s[as.length-1] == '/') {
+ as.s[as.length-1] = '\0';
+ as.length--;
+ }
+ vp = isoent_create_virtual_dir(a, iso9660, as.s);
+ if (vp == NULL) {
+ archive_string_free(&as);
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory");
+ _isoent_free(isoent);
+ *isoentpp = NULL;
+ return (ARCHIVE_FATAL);
+ }
+ archive_string_free(&as);
+
+ if (vp->file->dircnt > iso9660->dircnt_max)
+ iso9660->dircnt_max = vp->file->dircnt;
+ isoent_add_child_tail(dent, vp);
+ np = vp;
+
+ fn += l;
+ if (fn[0] == '/')
+ fn++;
+ l = get_path_component(name, sizeof(name), fn);
+ if (l < 0) {
+ archive_string_free(&as);
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "A name buffer is too small");
+ _isoent_free(isoent);
+ *isoentpp = NULL;
+ return (ARCHIVE_FATAL);
+ }
+ dent = np;
+ }
+
+ /* Found out the parent directory where isoent can be
+ * inserted. */
+ iso9660->cur_dirent = dent;
+ archive_string_empty(&(iso9660->cur_dirstr));
+ archive_string_ensure(&(iso9660->cur_dirstr),
+ archive_strlen(&(dent->file->parentdir)) +
+ archive_strlen(&(dent->file->basename)) + 2);
+ if (archive_strlen(&(dent->file->parentdir)) +
+ archive_strlen(&(dent->file->basename)) == 0)
+ iso9660->cur_dirstr.s[0] = 0;
+ else {
+ if (archive_strlen(&(dent->file->parentdir)) > 0) {
+ archive_string_copy(&(iso9660->cur_dirstr),
+ &(dent->file->parentdir));
+ archive_strappend_char(&(iso9660->cur_dirstr), '/');
+ }
+ archive_string_concat(&(iso9660->cur_dirstr),
+ &(dent->file->basename));
+ }
+
+ if (!isoent_add_child_tail(dent, isoent)) {
+ np = (struct isoent *)__archive_rb_tree_find_node(
+ &(dent->rbtree), isoent->file->basename.s);
+ goto same_entry;
+ }
+ return (ARCHIVE_OK);
+ }
+
+same_entry:
+ /*
+ * We have already has the entry the filename of which is
+ * the same.
+ */
+ f1 = np->file;
+ f2 = isoent->file;
+
+ /* If the file type of entries is different,
+ * we cannot handle it. */
+ if (archive_entry_filetype(f1->entry) !=
+ archive_entry_filetype(f2->entry)) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Found duplicate entries `%s' and its file type is "
+ "different",
+ archive_entry_pathname(f1->entry));
+ _isoent_free(isoent);
+ *isoentpp = NULL;
+ return (ARCHIVE_FAILED);
+ }
+
+ /* Swap file entries. */
+ np->file = f2;
+ isoent->file = f1;
+ np->virtual = 0;
+
+ _isoent_free(isoent);
+ *isoentpp = np;
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Find a entry from `isoent'
+ */
+static struct isoent *
+isoent_find_child(struct isoent *isoent, const char *child_name)
+{
+ struct isoent *np;
+
+ np = (struct isoent *)__archive_rb_tree_find_node(
+ &(isoent->rbtree), child_name);
+ return (np);
+}
+
+/*
+ * Find a entry full-path of which is specified by `fn' parameter,
+ * in the tree.
+ */
+static struct isoent *
+isoent_find_entry(struct isoent *rootent, const char *fn)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ char name[_MAX_FNAME];/* Included null terminator size. */
+#elif defined(NAME_MAX) && NAME_MAX >= 255
+ char name[NAME_MAX+1];
+#else
+ char name[256];
+#endif
+ struct isoent *isoent, *np;
+ int l;
+
+ isoent = rootent;
+ np = NULL;
+ for (;;) {
+ l = get_path_component(name, sizeof(name), fn);
+ if (l == 0)
+ break;
+ fn += l;
+ if (fn[0] == '/')
+ fn++;
+
+ np = isoent_find_child(isoent, name);
+ if (np == NULL)
+ break;
+ if (fn[0] == '\0')
+ break;/* We found out the entry */
+
+ /* Try sub directory. */
+ isoent = np;
+ np = NULL;
+ if (!isoent->dir)
+ break;/* Not directory */
+ }
+
+ return (np);
+}
+
+/*
+ * Following idr_* functions are used for resolving duplicated filenames
+ * and unreceivable filenames to generate ISO9660/Joliet Identifiers.
+ */
+
+static void
+idr_relaxed_filenames(char *map)
+{
+ int i;
+
+ for (i = 0x21; i <= 0x2F; i++)
+ map[i] = 1;
+ for (i = 0x3A; i <= 0x41; i++)
+ map[i] = 1;
+ for (i = 0x5B; i <= 0x5E; i++)
+ map[i] = 1;
+ map[0x60] = 1;
+ for (i = 0x7B; i <= 0x7E; i++)
+ map[i] = 1;
+}
+
+static void
+idr_init(struct iso9660 *iso9660, struct vdd *vdd, struct idr *idr)
+{
+
+ idr->idrent_pool = NULL;
+ idr->pool_size = 0;
+ if (vdd->vdd_type != VDD_JOLIET) {
+ if (iso9660->opt.iso_level <= 3) {
+ memcpy(idr->char_map, d_characters_map,
+ sizeof(idr->char_map));
+ } else {
+ memcpy(idr->char_map, d1_characters_map,
+ sizeof(idr->char_map));
+ idr_relaxed_filenames(idr->char_map);
+ }
+ }
+}
+
+static void
+idr_cleanup(struct idr *idr)
+{
+ free(idr->idrent_pool);
+}
+
+static int
+idr_ensure_poolsize(struct archive_write *a, struct idr *idr,
+ int cnt)
+{
+
+ if (idr->pool_size < cnt) {
+ const int bk = (1 << 7) - 1;
+ int psize;
+
+ psize = (cnt + bk) & ~bk;
+ idr->idrent_pool = realloc(idr->idrent_pool,
+ sizeof(struct idrent) * psize);
+ if (idr->idrent_pool == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+ idr->pool_size = psize;
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+idr_start(struct archive_write *a, struct idr *idr, int cnt, int ffmax,
+ int num_size, int null_size, const struct archive_rb_tree_ops *rbt_ops)
+{
+ int r;
+
+ (void)ffmax; /* UNUSED */
+
+ r = idr_ensure_poolsize(a, idr, cnt);
+ if (r != ARCHIVE_OK)
+ return (r);
+ __archive_rb_tree_init(&(idr->rbtree), rbt_ops);
+ idr->wait_list.first = NULL;
+ idr->wait_list.last = &(idr->wait_list.first);
+ idr->pool_idx = 0;
+ idr->num_size = num_size;
+ idr->null_size = null_size;
+ return (ARCHIVE_OK);
+}
+
+static void
+idr_register(struct idr *idr, struct isoent *isoent, int weight, int noff)
+{
+ struct idrent *idrent, *n;
+
+ idrent = &(idr->idrent_pool[idr->pool_idx++]);
+ idrent->wnext = idrent->avail = NULL;
+ idrent->isoent = isoent;
+ idrent->weight = weight;
+ idrent->noff = noff;
+ idrent->rename_num = 0;
+
+ if (!__archive_rb_tree_insert_node(&(idr->rbtree), &(idrent->rbnode))) {
+ n = (struct idrent *)__archive_rb_tree_find_node(
+ &(idr->rbtree), idrent->isoent);
+ if (n != NULL) {
+ /* this `idrent' needs to rename. */
+ idrent->avail = n;
+ *idr->wait_list.last = idrent;
+ idr->wait_list.last = &(idrent->wnext);
+ }
+ }
+}
+
+static void
+idr_extend_identifier(struct idrent *wnp, int numsize, int nullsize)
+{
+ unsigned char *p;
+ int wnp_ext_off;
+
+ wnp_ext_off = wnp->isoent->ext_off;
+ if (wnp->noff + numsize != wnp_ext_off) {
+ p = (unsigned char *)wnp->isoent->identifier;
+ /* Extend the filename; foo.c --> foo___.c */
+ memmove(p + wnp->noff + numsize, p + wnp_ext_off,
+ wnp->isoent->ext_len + nullsize);
+ wnp->isoent->ext_off = wnp_ext_off = wnp->noff + numsize;
+ wnp->isoent->id_len = wnp_ext_off + wnp->isoent->ext_len;
+ }
+}
+
+static void
+idr_resolve(struct idr *idr, void (*fsetnum)(unsigned char *p, int num))
+{
+ struct idrent *n;
+ unsigned char *p;
+
+ for (n = idr->wait_list.first; n != NULL; n = n->wnext) {
+ idr_extend_identifier(n, idr->num_size, idr->null_size);
+ p = (unsigned char *)n->isoent->identifier + n->noff;
+ do {
+ fsetnum(p, n->avail->rename_num++);
+ } while (!__archive_rb_tree_insert_node(
+ &(idr->rbtree), &(n->rbnode)));
+ }
+}
+
+static void
+idr_set_num(unsigned char *p, int num)
+{
+ static const char xdig[] = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
+ 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
+ 'U', 'V', 'W', 'X', 'Y', 'Z'
+ };
+
+ num %= sizeof(xdig) * sizeof(xdig) * sizeof(xdig);
+ p[0] = xdig[(num / (sizeof(xdig) * sizeof(xdig)))];
+ num %= sizeof(xdig) * sizeof(xdig);
+ p[1] = xdig[ (num / sizeof(xdig))];
+ num %= sizeof(xdig);
+ p[2] = xdig[num];
+}
+
+static void
+idr_set_num_beutf16(unsigned char *p, int num)
+{
+ static const uint16_t xdig[] = {
+ 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035,
+ 0x0036, 0x0037, 0x0038, 0x0039,
+ 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046,
+ 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C,
+ 0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052,
+ 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
+ 0x0059, 0x005A
+ };
+#define XDIG_CNT (sizeof(xdig)/sizeof(xdig[0]))
+
+ num %= XDIG_CNT * XDIG_CNT * XDIG_CNT;
+ archive_be16enc(p, xdig[(num / (XDIG_CNT * XDIG_CNT))]);
+ num %= XDIG_CNT * XDIG_CNT;
+ archive_be16enc(p+2, xdig[ (num / XDIG_CNT)]);
+ num %= XDIG_CNT;
+ archive_be16enc(p+4, xdig[num]);
+}
+
+/*
+ * Generate ISO9660 Identifier.
+ */
+static int
+isoent_gen_iso9660_identifier(struct archive_write *a, struct isoent *isoent,
+ struct idr *idr)
+{
+ struct iso9660 *iso9660;
+ struct isoent *np;
+ char *p;
+ int l, r;
+ const char *char_map;
+ char allow_ldots, allow_multidot, allow_period, allow_vernum;
+ int fnmax, ffmax, dnmax;
+ static const struct archive_rb_tree_ops rb_ops = {
+ isoent_cmp_node_iso9660, isoent_cmp_key_iso9660
+ };
+
+ if (isoent->children.cnt == 0)
+ return (0);
+
+ iso9660 = a->format_data;
+ char_map = idr->char_map;
+ if (iso9660->opt.iso_level <= 3) {
+ allow_ldots = 0;
+ allow_multidot = 0;
+ allow_period = 1;
+ allow_vernum = iso9660->opt.allow_vernum;
+ if (iso9660->opt.iso_level == 1) {
+ fnmax = 8;
+ ffmax = 12;/* fnmax + '.' + 3 */
+ dnmax = 8;
+ } else {
+ fnmax = 30;
+ ffmax = 31;
+ dnmax = 31;
+ }
+ } else {
+ allow_ldots = allow_multidot = 1;
+ allow_period = allow_vernum = 0;
+ if (iso9660->opt.rr)
+ /*
+ * MDR : The maximum size of Directory Record(254).
+ * DRL : A Directory Record Length(33).
+ * CE : A size of SUSP CE System Use Entry(28).
+ * MDR - DRL - CE = 254 - 33 - 28 = 193.
+ */
+ fnmax = ffmax = dnmax = 193;
+ else
+ /*
+ * XA : CD-ROM XA System Use Extension
+ * Information(14).
+ * MDR - DRL - XA = 254 - 33 -14 = 207.
+ */
+ fnmax = ffmax = dnmax = 207;
+ }
+
+ r = idr_start(a, idr, isoent->children.cnt, ffmax, 3, 1, &rb_ops);
+ if (r < 0)
+ return (r);
+
+ for (np = isoent->children.first; np != NULL; np = np->chnext) {
+ char *dot, *xdot;
+ int ext_off, noff, weight;
+
+ l = np->file->basename.length;
+ p = malloc(l+31+2+1);
+ if (p == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+ memcpy(p, np->file->basename.s, l);
+ p[l] = '\0';
+ np->identifier = p;
+
+ dot = xdot = NULL;
+ if (!allow_ldots) {
+ /*
+ * If there is a '.' character at the first byte,
+ * it has to be replaced by '_' character.
+ */
+ if (*p == '.')
+ *p++ = '_';
+ }
+ for (;*p; p++) {
+ if (*p & 0x80) {
+ *p = '_';
+ continue;
+ }
+ if (char_map[(unsigned char)*p]) {
+ /* if iso-level is '4', a character '.' is
+ * allowed by char_map. */
+ if (*p == '.') {
+ xdot = dot;
+ dot = p;
+ }
+ continue;
+ }
+ if (*p >= 'a' && *p <= 'z') {
+ *p -= 'a' - 'A';
+ continue;
+ }
+ if (*p == '.') {
+ xdot = dot;
+ dot = p;
+ if (allow_multidot)
+ continue;
+ }
+ *p = '_';
+ }
+ p = np->identifier;
+ weight = -1;
+ if (dot == NULL) {
+ int nammax;
+
+ if (np->dir)
+ nammax = dnmax;
+ else
+ nammax = fnmax;
+
+ if (l > nammax) {
+ p[nammax] = '\0';
+ weight = nammax;
+ ext_off = nammax;
+ } else
+ ext_off = l;
+ } else {
+ *dot = '.';
+ ext_off = dot - p;
+
+ if (iso9660->opt.iso_level == 1) {
+ if (dot - p <= 8) {
+ if (strlen(dot) > 4) {
+ /* A length of a file extension
+ * must be less than 4 */
+ dot[4] = '\0';
+ weight = 0;
+ }
+ } else {
+ p[8] = dot[0];
+ p[9] = dot[1];
+ p[10] = dot[2];
+ p[11] = dot[3];
+ p[12] = '\0';
+ weight = 8;
+ ext_off = 8;
+ }
+ } else if (np->dir) {
+ if (l > dnmax) {
+ p[dnmax] = '\0';
+ weight = dnmax;
+ if (ext_off > dnmax)
+ ext_off = dnmax;
+ }
+ } else if (l > ffmax) {
+ int extlen = strlen(dot);
+ int xdoff;
+
+ if (xdot != NULL)
+ xdoff = xdot - p;
+ else
+ xdoff = 0;
+
+ if (extlen > 1 && xdoff < fnmax-1) {
+ int off;
+
+ if (extlen > ffmax)
+ extlen = ffmax;
+ off = ffmax - extlen;
+ if (off == 0) {
+ /* A dot('.') character
+ * does't place to the first
+ * byte of identifier. */
+ off ++;
+ extlen --;
+ }
+ memmove(p+off, dot, extlen);
+ p[ffmax] = '\0';
+ ext_off = off;
+ weight = off;
+#ifdef COMPAT_MKISOFS
+ } else if (xdoff >= fnmax-1) {
+ /* Simulate a bug(?) of mkisofs. */
+ p[fnmax-1] = '\0';
+ ext_off = fnmax-1;
+ weight = fnmax-1;
+#endif
+ } else {
+ p[fnmax] = '\0';
+ ext_off = fnmax;
+ weight = fnmax;
+ }
+ }
+ }
+ /* Save an offset of a file name extension to sort files. */
+ np->ext_off = ext_off;
+ np->ext_len = strlen(&p[ext_off]);
+ np->id_len = l = ext_off + np->ext_len;
+
+ /* Make an offset of the number which is used to be set
+ * hexadecimal number to avoid duplicate identififier. */
+ if (iso9660->opt.iso_level == 1) {
+ if (ext_off >= 5)
+ noff = 5;
+ else
+ noff = ext_off;
+ } else {
+ if (l == ffmax)
+ noff = ext_off - 3;
+ else if (l == ffmax-1)
+ noff = ext_off - 2;
+ else if (l == ffmax-2)
+ noff = ext_off - 1;
+ else
+ noff = ext_off;
+ }
+ /* Register entry to the identifier resolver. */
+ idr_register(idr, np, weight, noff);
+ }
+
+ /* Resolve duplicate identifier. */
+ idr_resolve(idr, idr_set_num);
+
+ /* Add a period and a version number to identifiers. */
+ for (np = isoent->children.first; np != NULL; np = np->chnext) {
+ if (!np->dir && np->rr_child == NULL) {
+ p = np->identifier + np->ext_off + np->ext_len;
+ if (np->ext_len == 0 && allow_period) {
+ *p++ = '.';
+ np->ext_len = 1;
+ }
+ if (np->ext_len == 1 && !allow_period) {
+ *--p = '\0';
+ np->ext_len = 0;
+ }
+ np->id_len = np->ext_off + np->ext_len;
+ if (allow_vernum) {
+ *p++ = ';';
+ *p++ = '1';
+ np->id_len += 2;
+ }
+ *p = '\0';
+ } else
+ np->id_len = np->ext_off + np->ext_len;
+ np->mb_len = np->id_len;
+ }
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Generate Joliet Identifier.
+ */
+static int
+isoent_gen_joliet_identifier(struct archive_write *a, struct isoent *isoent,
+ struct idr *idr)
+{
+ struct iso9660 *iso9660;
+ struct isoent *np;
+ unsigned char *p;
+ size_t l;
+ int r;
+ int ffmax, parent_len;
+ static const struct archive_rb_tree_ops rb_ops = {
+ isoent_cmp_node_joliet, isoent_cmp_key_joliet
+ };
+
+ if (isoent->children.cnt == 0)
+ return (0);
+
+ iso9660 = a->format_data;
+ if (iso9660->opt.joliet == OPT_JOLIET_LONGNAME)
+ ffmax = 206;
+ else
+ ffmax = 128;
+
+ r = idr_start(a, idr, isoent->children.cnt, ffmax, 6, 2, &rb_ops);
+ if (r < 0)
+ return (r);
+
+ parent_len = 1;
+ for (np = isoent; np->parent != np; np = np->parent)
+ parent_len += np->mb_len + 1;
+
+ for (np = isoent->children.first; np != NULL; np = np->chnext) {
+ unsigned char *dot;
+ int ext_off, noff, weight;
+ size_t lt;
+
+ if ((int)(l = np->file->basename_utf16.length) > ffmax)
+ l = ffmax;
+
+ p = malloc((l+1)*2);
+ if (p == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+ memcpy(p, np->file->basename_utf16.s, l);
+ p[l] = 0;
+ p[l+1] = 0;
+
+ np->identifier = (char *)p;
+ lt = l;
+ dot = p + l;
+ weight = 0;
+ while (lt > 0) {
+ if (!joliet_allowed_char(p[0], p[1]))
+ archive_be16enc(p, 0x005F); /* '_' */
+ else if (p[0] == 0 && p[1] == 0x2E) /* '.' */
+ dot = p;
+ p += 2;
+ lt -= 2;
+ }
+ ext_off = dot - (unsigned char *)np->identifier;
+ np->ext_off = ext_off;
+ np->ext_len = l - ext_off;
+ np->id_len = l;
+
+ /*
+ * Get a length of MBS of a full-pathname.
+ */
+ if ((int)np->file->basename_utf16.length > ffmax) {
+ archive_strncpy_in_locale(&iso9660->mbs,
+ (const char *)np->identifier, l,
+ iso9660->sconv_from_utf16be);
+ np->mb_len = iso9660->mbs.length;
+ if (np->mb_len != (int)np->file->basename.length)
+ weight = np->mb_len;
+ } else
+ np->mb_len = np->file->basename.length;
+
+ /* If a length of full-pathname is longer than 240 bytes,
+ * it violates Joliet extensions regulation. */
+ if (parent_len + np->mb_len > 240) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "The regulation of Joliet extensions;"
+ " A lenght of a full-pathname of `%s' is "
+ "longer than 240 bytes, (p=%d, b=%d)",
+ archive_entry_pathname(np->file->entry),
+ (int)parent_len, (int)np->mb_len);
+ return (ARCHIVE_FATAL);
+ }
+
+ /* Make an offset of the number which is used to be set
+ * hexadecimal number to avoid duplicate identififier. */
+ if ((int)l == ffmax)
+ noff = ext_off - 6;
+ else if ((int)l == ffmax-2)
+ noff = ext_off - 4;
+ else if ((int)l == ffmax-4)
+ noff = ext_off - 2;
+ else
+ noff = ext_off;
+ /* Register entry to the identifier resolver. */
+ idr_register(idr, np, weight, noff);
+ }
+
+ /* Resolve duplicate identifier with Joliet Volume. */
+ idr_resolve(idr, idr_set_num_beutf16);
+
+ return (ARCHIVE_OK);
+}
+
+/*
+ * This comparing rule is acording to ISO9660 Standard 9.3
+ */
+static int
+isoent_cmp_iso9660_identifier(const struct isoent *p1, const struct isoent *p2)
+{
+ const char *s1, *s2;
+ int cmp;
+ int l;
+
+ s1 = p1->identifier;
+ s2 = p2->identifier;
+
+ /* Compare File Name */
+ l = p1->ext_off;
+ if (l > p2->ext_off)
+ l = p2->ext_off;
+ cmp = memcmp(s1, s2, l);
+ if (cmp != 0)
+ return (cmp);
+ if (p1->ext_off < p2->ext_off) {
+ s2 += l;
+ l = p2->ext_off - p1->ext_off;
+ while (l--)
+ if (0x20 != *s2++)
+ return (0x20
+ - *(const unsigned char *)(s2 - 1));
+ } else if (p1->ext_off > p2->ext_off) {
+ s1 += l;
+ l = p1->ext_off - p2->ext_off;
+ while (l--)
+ if (0x20 != *s1++)
+ return (*(const unsigned char *)(s1 - 1)
+ - 0x20);
+ }
+ /* Compare File Name Extension */
+ if (p1->ext_len == 0 && p2->ext_len == 0)
+ return (0);
+ if (p1->ext_len == 1 && p2->ext_len == 1)
+ return (0);
+ if (p1->ext_len <= 1)
+ return (-1);
+ if (p2->ext_len <= 1)
+ return (1);
+ l = p1->ext_len;
+ if (l > p2->ext_len)
+ l = p2->ext_len;
+ s1 = p1->identifier + p1->ext_off;
+ s2 = p2->identifier + p2->ext_off;
+ if (l > 1) {
+ cmp = memcmp(s1, s2, l);
+ if (cmp != 0)
+ return (cmp);
+ }
+ if (p1->ext_len < p2->ext_len) {
+ s2 += l;
+ l = p2->ext_len - p1->ext_len;
+ while (l--)
+ if (0x20 != *s2++)
+ return (0x20
+ - *(const unsigned char *)(s2 - 1));
+ } else if (p1->ext_len < p2->ext_len) {
+ s1 += l;
+ l = p1->ext_len - p2->ext_len;
+ while (l--)
+ if (0x20 != *s1++)
+ return (*(const unsigned char *)(s1 - 1)
+ - 0x20);
+ }
+ /* Compare File Version Number */
+ /* No operation. The File Version Number is always one. */
+
+ return (cmp);
+}
+
+static int
+isoent_cmp_node_iso9660(const struct archive_rb_node *n1,
+ const struct archive_rb_node *n2)
+{
+ const struct idrent *e1 = (const struct idrent *)n1;
+ const struct idrent *e2 = (const struct idrent *)n2;
+
+ return (isoent_cmp_iso9660_identifier(e2->isoent, e1->isoent));
+}
+
+static int
+isoent_cmp_key_iso9660(const struct archive_rb_node *node, const void *key)
+{
+ const struct isoent *isoent = (const struct isoent *)key;
+ const struct idrent *idrent = (const struct idrent *)node;
+
+ return (isoent_cmp_iso9660_identifier(isoent, idrent->isoent));
+}
+
+static int
+isoent_cmp_joliet_identifier(const struct isoent *p1, const struct isoent *p2)
+{
+ const unsigned char *s1, *s2;
+ int cmp;
+ int l;
+
+ s1 = (const unsigned char *)p1->identifier;
+ s2 = (const unsigned char *)p2->identifier;
+
+ /* Compare File Name */
+ l = p1->ext_off;
+ if (l > p2->ext_off)
+ l = p2->ext_off;
+ cmp = memcmp(s1, s2, l);
+ if (cmp != 0)
+ return (cmp);
+ if (p1->ext_off < p2->ext_off) {
+ s2 += l;
+ l = p2->ext_off - p1->ext_off;
+ while (l--)
+ if (0 != *s2++)
+ return (- *(const unsigned char *)(s2 - 1));
+ } else if (p1->ext_off > p2->ext_off) {
+ s1 += l;
+ l = p1->ext_off - p2->ext_off;
+ while (l--)
+ if (0 != *s1++)
+ return (*(const unsigned char *)(s1 - 1));
+ }
+ /* Compare File Name Extension */
+ if (p1->ext_len == 0 && p2->ext_len == 0)
+ return (0);
+ if (p1->ext_len == 2 && p2->ext_len == 2)
+ return (0);
+ if (p1->ext_len <= 2)
+ return (-1);
+ if (p2->ext_len <= 2)
+ return (1);
+ l = p1->ext_len;
+ if (l > p2->ext_len)
+ l = p2->ext_len;
+ s1 = (unsigned char *)(p1->identifier + p1->ext_off);
+ s2 = (unsigned char *)(p2->identifier + p2->ext_off);
+ if (l > 1) {
+ cmp = memcmp(s1, s2, l);
+ if (cmp != 0)
+ return (cmp);
+ }
+ if (p1->ext_len < p2->ext_len) {
+ s2 += l;
+ l = p2->ext_len - p1->ext_len;
+ while (l--)
+ if (0 != *s2++)
+ return (- *(const unsigned char *)(s2 - 1));
+ } else if (p1->ext_len < p2->ext_len) {
+ s1 += l;
+ l = p1->ext_len - p2->ext_len;
+ while (l--)
+ if (0 != *s1++)
+ return (*(const unsigned char *)(s1 - 1));
+ }
+ /* Compare File Version Number */
+ /* No operation. The File Version Number is always one. */
+
+ return (cmp);
+}
+
+static int
+isoent_cmp_node_joliet(const struct archive_rb_node *n1,
+ const struct archive_rb_node *n2)
+{
+ const struct idrent *e1 = (const struct idrent *)n1;
+ const struct idrent *e2 = (const struct idrent *)n2;
+
+ return (isoent_cmp_joliet_identifier(e2->isoent, e1->isoent));
+}
+
+static int
+isoent_cmp_key_joliet(const struct archive_rb_node *node, const void *key)
+{
+ const struct isoent *isoent = (const struct isoent *)key;
+ const struct idrent *idrent = (const struct idrent *)node;
+
+ return (isoent_cmp_joliet_identifier(isoent, idrent->isoent));
+}
+
+static int
+isoent_make_sorted_files(struct archive_write *a, struct isoent *isoent,
+ struct idr *idr)
+{
+ struct archive_rb_node *rn;
+ struct isoent **children;
+
+ children = malloc(isoent->children.cnt * sizeof(struct isoent *));
+ if (children == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+ isoent->children_sorted = children;
+
+ ARCHIVE_RB_TREE_FOREACH(rn, &(idr->rbtree)) {
+ struct idrent *idrent = (struct idrent *)rn;
+ *children ++ = idrent->isoent;
+ }
+ return (ARCHIVE_OK);
+}
+
+/*
+ * - Generate ISO9660 and Joliet identifiers from basenames.
+ * - Sort files by each directory.
+ */
+static int
+isoent_traverse_tree(struct archive_write *a, struct vdd* vdd)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ struct isoent *np;
+ struct idr idr;
+ int depth;
+ int r;
+ int (*genid)(struct archive_write *a, struct isoent *isoent,
+ struct idr *idr);
+
+ idr_init(iso9660, vdd, &idr);
+ np = vdd->rootent;
+ depth = 0;
+ if (vdd->vdd_type == VDD_JOLIET)
+ genid = isoent_gen_joliet_identifier;
+ else
+ genid = isoent_gen_iso9660_identifier;
+ do {
+ if (np->virtual &&
+ !archive_entry_mtime_is_set(np->file->entry)) {
+ /* Set properly times to virtual directory */
+ archive_entry_set_mtime(np->file->entry,
+ iso9660->birth_time, 0);
+ archive_entry_set_atime(np->file->entry,
+ iso9660->birth_time, 0);
+ archive_entry_set_ctime(np->file->entry,
+ iso9660->birth_time, 0);
+ }
+ if (np->children.first != NULL) {
+ if (vdd->vdd_type != VDD_JOLIET &&
+ !iso9660->opt.rr && depth + 1 >= vdd->max_depth) {
+ if (np->children.cnt > 0)
+ iso9660->directories_too_deep = np;
+ } else {
+ /* Generate Identifier */
+ r = genid(a, np, &idr);
+ if (r < 0)
+ goto exit_traverse_tree;
+ r = isoent_make_sorted_files(a, np, &idr);
+ if (r < 0)
+ goto exit_traverse_tree;
+
+ if (np->subdirs.first != NULL &&
+ depth + 1 < vdd->max_depth) {
+ /* Enter to sub directories. */
+ np = np->subdirs.first;
+ depth++;
+ continue;
+ }
+ }
+ }
+ while (np != np->parent) {
+ if (np->drnext == NULL) {
+ /* Return to the parent directory. */
+ np = np->parent;
+ depth--;
+ } else {
+ np = np->drnext;
+ break;
+ }
+ }
+ } while (np != np->parent);
+
+ r = ARCHIVE_OK;
+exit_traverse_tree:
+ idr_cleanup(&idr);
+
+ return (r);
+}
+
+/*
+ * Collect directory entries into path_table by a directory depth.
+ */
+static int
+isoent_collect_dirs(struct vdd *vdd, struct isoent *rootent, int depth)
+{
+ struct isoent *np;
+
+ if (rootent == NULL)
+ rootent = vdd->rootent;
+ np = rootent;
+ do {
+ /* Register current directory to pathtable. */
+ path_table_add_entry(&(vdd->pathtbl[depth]), np);
+
+ if (np->subdirs.first != NULL && depth + 1 < vdd->max_depth) {
+ /* Enter to sub directories. */
+ np = np->subdirs.first;
+ depth++;
+ continue;
+ }
+ while (np != rootent) {
+ if (np->drnext == NULL) {
+ /* Return to the parent directory. */
+ np = np->parent;
+ depth--;
+ } else {
+ np = np->drnext;
+ break;
+ }
+ }
+ } while (np != rootent);
+
+ return (ARCHIVE_OK);
+}
+
+/*
+ * The entry whose number of levels in a directory hierarchy is
+ * large than eight relocate to rr_move directory.
+ */
+static int
+isoent_rr_move_dir(struct archive_write *a, struct isoent **rr_moved,
+ struct isoent *curent, struct isoent **newent)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ struct isoent *rrmoved, *mvent, *np;
+
+ if ((rrmoved = *rr_moved) == NULL) {
+ struct isoent *rootent = iso9660->primary.rootent;
+ /* There isn't rr_move entry.
+ * Create rr_move entry and insert it into the root entry.
+ */
+ rrmoved = isoent_create_virtual_dir(a, iso9660, "rr_moved");
+ if (rrmoved == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+ /* Add "rr_moved" entry to the root entry. */
+ isoent_add_child_head(rootent, rrmoved);
+ archive_entry_set_nlink(rootent->file->entry,
+ archive_entry_nlink(rootent->file->entry) + 1);
+ /* Register "rr_moved" entry to second level pathtable. */
+ path_table_add_entry(&(iso9660->primary.pathtbl[1]), rrmoved);
+ /* Save rr_moved. */
+ *rr_moved = rrmoved;
+ }
+ /*
+ * Make a clone of curent which is going to be relocated
+ * to rr_moved.
+ */
+ mvent = isoent_clone(curent);
+ if (mvent == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+ /* linking.. and use for creating "CL", "PL" and "RE" */
+ mvent->rr_parent = curent->parent;
+ curent->rr_child = mvent;
+ /*
+ * Move subdirectories from the curent to mvent
+ */
+ if (curent->children.first != NULL) {
+ *mvent->children.last = curent->children.first;
+ mvent->children.last = curent->children.last;
+ }
+ for (np = mvent->children.first; np != NULL; np = np->chnext)
+ np->parent = mvent;
+ mvent->children.cnt = curent->children.cnt;
+ curent->children.cnt = 0;
+ curent->children.first = NULL;
+ curent->children.last = &curent->children.first;
+
+ if (curent->subdirs.first != NULL) {
+ *mvent->subdirs.last = curent->subdirs.first;
+ mvent->subdirs.last = curent->subdirs.last;
+ }
+ mvent->subdirs.cnt = curent->subdirs.cnt;
+ curent->subdirs.cnt = 0;
+ curent->subdirs.first = NULL;
+ curent->subdirs.last = &curent->subdirs.first;
+
+ /*
+ * The mvent becomes a child of the rr_moved entry.
+ */
+ isoent_add_child_tail(rrmoved, mvent);
+ archive_entry_set_nlink(rrmoved->file->entry,
+ archive_entry_nlink(rrmoved->file->entry) + 1);
+ /*
+ * This entry which relocated to the rr_moved directory
+ * has to set the flag as a file.
+ * See also RRIP 4.1.5.1 Description of the "CL" System Use Entry.
+ */
+ curent->dir = 0;
+
+ *newent = mvent;
+
+ return (ARCHIVE_OK);
+}
+
+static int
+isoent_rr_move(struct archive_write *a)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ struct path_table *pt;
+ struct isoent *rootent, *rr_moved;
+ struct isoent *np, *last;
+ int r;
+
+ pt = &(iso9660->primary.pathtbl[MAX_DEPTH-1]);
+ /* Theare aren't level 8 directories reaching a deepr level. */
+ if (pt->cnt == 0)
+ return (ARCHIVE_OK);
+
+ rootent = iso9660->primary.rootent;
+ /* If "rr_moved" directory is already existing,
+ * we have to use it. */
+ rr_moved = isoent_find_child(rootent, "rr_moved");
+ if (rr_moved != NULL &&
+ rr_moved != rootent->children.first) {
+ /*
+ * It's necessary that rr_move is the first entry
+ * of the root.
+ */
+ /* Remove "rr_moved" entry from children chain. */
+ isoent_remove_child(rootent, rr_moved);
+
+ /* Add "rr_moved" entry into the head of children chain. */
+ isoent_add_child_head(rootent, rr_moved);
+ }
+
+ /*
+ * Check level 8 path_table.
+ * If find out sub directory entries, that entries move to rr_move.
+ */
+ np = pt->first;
+ while (np != NULL) {
+ last = path_table_last_entry(pt);
+ for (; np != NULL; np = np->ptnext) {
+ struct isoent *mvent;
+ struct isoent *newent;
+
+ if (!np->dir)
+ continue;
+ for (mvent = np->subdirs.first;
+ mvent != NULL; mvent = mvent->drnext) {
+ r = isoent_rr_move_dir(a, &rr_moved,
+ mvent, &newent);
+ if (r < 0)
+ return (r);
+ isoent_collect_dirs(&(iso9660->primary),
+ newent, 2);
+ }
+ }
+ /* If new entries are added to level 8 path_talbe,
+ * its sub directory entries move to rr_move too.
+ */
+ np = last->ptnext;
+ }
+
+ return (ARCHIVE_OK);
+}
+
+/*
+ * This comparing rule is according to ISO9660 Standard 6.9.1
+ */
+static int
+_compare_path_table(const void *v1, const void *v2)
+{
+ const struct isoent *p1, *p2;
+ const char *s1, *s2;
+ int cmp, l;
+
+ p1 = *((const struct isoent **)(uintptr_t)v1);
+ p2 = *((const struct isoent **)(uintptr_t)v2);
+
+ /* Compare parent directory number */
+ cmp = p1->parent->dir_number - p2->parent->dir_number;
+ if (cmp != 0)
+ return (cmp);
+
+ /* Compare indetifier */
+ s1 = p1->identifier;
+ s2 = p2->identifier;
+ l = p1->ext_off;
+ if (l > p2->ext_off)
+ l = p2->ext_off;
+ cmp = strncmp(s1, s2, l);
+ if (cmp != 0)
+ return (cmp);
+ if (p1->ext_off < p2->ext_off) {
+ s2 += l;
+ l = p2->ext_off - p1->ext_off;
+ while (l--)
+ if (0x20 != *s2++)
+ return (0x20
+ - *(const unsigned char *)(s2 - 1));
+ } else if (p1->ext_off > p2->ext_off) {
+ s1 += l;
+ l = p1->ext_off - p2->ext_off;
+ while (l--)
+ if (0x20 != *s1++)
+ return (*(const unsigned char *)(s1 - 1)
+ - 0x20);
+ }
+ return (0);
+}
+
+static int
+_compare_path_table_joliet(const void *v1, const void *v2)
+{
+ const struct isoent *p1, *p2;
+ const unsigned char *s1, *s2;
+ int cmp, l;
+
+ p1 = *((const struct isoent **)(uintptr_t)v1);
+ p2 = *((const struct isoent **)(uintptr_t)v2);
+
+ /* Compare parent directory number */
+ cmp = p1->parent->dir_number - p2->parent->dir_number;
+ if (cmp != 0)
+ return (cmp);
+
+ /* Compare indetifier */
+ s1 = (const unsigned char *)p1->identifier;
+ s2 = (const unsigned char *)p2->identifier;
+ l = p1->ext_off;
+ if (l > p2->ext_off)
+ l = p2->ext_off;
+ cmp = memcmp(s1, s2, l);
+ if (cmp != 0)
+ return (cmp);
+ if (p1->ext_off < p2->ext_off) {
+ s2 += l;
+ l = p2->ext_off - p1->ext_off;
+ while (l--)
+ if (0 != *s2++)
+ return (- *(const unsigned char *)(s2 - 1));
+ } else if (p1->ext_off > p2->ext_off) {
+ s1 += l;
+ l = p1->ext_off - p2->ext_off;
+ while (l--)
+ if (0 != *s1++)
+ return (*(const unsigned char *)(s1 - 1));
+ }
+ return (0);
+}
+
+static inline void
+path_table_add_entry(struct path_table *pathtbl, struct isoent *ent)
+{
+ ent->ptnext = NULL;
+ *pathtbl->last = ent;
+ pathtbl->last = &(ent->ptnext);
+ pathtbl->cnt ++;
+}
+
+static inline struct isoent *
+path_table_last_entry(struct path_table *pathtbl)
+{
+ if (pathtbl->first == NULL)
+ return (NULL);
+ return (((struct isoent *)(void *)
+ ((char *)(pathtbl->last) - offsetof(struct isoent, ptnext))));
+}
+
+/*
+ * Sort directory entries in path_table
+ * and assign directory number to each entries.
+ */
+static int
+isoent_make_path_table_2(struct archive_write *a, struct vdd *vdd,
+ int depth, int *dir_number)
+{
+ struct isoent *np;
+ struct isoent **enttbl;
+ struct path_table *pt;
+ int i;
+
+ pt = &vdd->pathtbl[depth];
+ if (pt->cnt == 0) {
+ pt->sorted = NULL;
+ return (ARCHIVE_OK);
+ }
+ enttbl = malloc(pt->cnt * sizeof(struct isoent *));
+ if (enttbl == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+ pt->sorted = enttbl;
+ for (np = pt->first; np != NULL; np = np->ptnext)
+ *enttbl ++ = np;
+ enttbl = pt->sorted;
+
+ switch (vdd->vdd_type) {
+ case VDD_PRIMARY:
+ case VDD_ENHANCED:
+ qsort(enttbl, pt->cnt, sizeof(struct isoent *),
+ _compare_path_table);
+ break;
+ case VDD_JOLIET:
+ qsort(enttbl, pt->cnt, sizeof(struct isoent *),
+ _compare_path_table_joliet);
+ break;
+ }
+ for (i = 0; i < pt->cnt; i++)
+ enttbl[i]->dir_number = (*dir_number)++;
+
+ return (ARCHIVE_OK);
+}
+
+static int
+isoent_alloc_path_table(struct archive_write *a, struct vdd *vdd,
+ int max_depth)
+{
+ int i;
+
+ vdd->max_depth = max_depth;
+ vdd->pathtbl = malloc(sizeof(*vdd->pathtbl) * vdd->max_depth);
+ if (vdd->pathtbl == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+ for (i = 0; i < vdd->max_depth; i++) {
+ vdd->pathtbl[i].first = NULL;
+ vdd->pathtbl[i].last = &(vdd->pathtbl[i].first);
+ vdd->pathtbl[i].sorted = NULL;
+ vdd->pathtbl[i].cnt = 0;
+ }
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Make Path Tables
+ */
+static int
+isoent_make_path_table(struct archive_write *a)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ int depth, r;
+ int dir_number;
+
+ /*
+ * Init Path Table.
+ */
+ if (iso9660->dircnt_max >= MAX_DEPTH &&
+ (!iso9660->opt.limit_depth || iso9660->opt.iso_level == 4))
+ r = isoent_alloc_path_table(a, &(iso9660->primary),
+ iso9660->dircnt_max + 1);
+ else
+ /* The number of levels in the hierarchy cannot exceed
+ * eight. */
+ r = isoent_alloc_path_table(a, &(iso9660->primary),
+ MAX_DEPTH);
+ if (r < 0)
+ return (r);
+ if (iso9660->opt.joliet) {
+ r = isoent_alloc_path_table(a, &(iso9660->joliet),
+ iso9660->dircnt_max + 1);
+ if (r < 0)
+ return (r);
+ }
+
+ /* Step 0.
+ * - Collect directories for primary and joliet.
+ */
+ isoent_collect_dirs(&(iso9660->primary), NULL, 0);
+ if (iso9660->opt.joliet)
+ isoent_collect_dirs(&(iso9660->joliet), NULL, 0);
+ /*
+ * Rockridge; move deeper depth directories to rr_moved.
+ */
+ if (iso9660->opt.rr) {
+ r = isoent_rr_move(a);
+ if (r < 0)
+ return (r);
+ }
+
+ /* Update nlink. */
+ isofile_connect_hardlink_files(iso9660);
+
+ /* Step 1.
+ * - Renew a value of the depth of that directories.
+ * - Resolve hardlinks.
+ * - Convert pathnames to ISO9660 name or UCS2(joliet).
+ * - Sort files by each directory.
+ */
+ r = isoent_traverse_tree(a, &(iso9660->primary));
+ if (r < 0)
+ return (r);
+ if (iso9660->opt.joliet) {
+ r = isoent_traverse_tree(a, &(iso9660->joliet));
+ if (r < 0)
+ return (r);
+ }
+
+ /* Step 2.
+ * - Sort directories.
+ * - Assign all directory number.
+ */
+ dir_number = 1;
+ for (depth = 0; depth < iso9660->primary.max_depth; depth++) {
+ r = isoent_make_path_table_2(a, &(iso9660->primary),
+ depth, &dir_number);
+ if (r < 0)
+ return (r);
+ }
+ if (iso9660->opt.joliet) {
+ dir_number = 1;
+ for (depth = 0; depth < iso9660->joliet.max_depth; depth++) {
+ r = isoent_make_path_table_2(a, &(iso9660->joliet),
+ depth, &dir_number);
+ if (r < 0)
+ return (r);
+ }
+ }
+ if (iso9660->opt.limit_dirs && dir_number > 0xffff) {
+ /*
+ * Maximum number of directories is 65535(0xffff)
+ * doe to size(16bit) of Parent Directory Number of
+ * the Path Table.
+ * See also ISO9660 Standard 9.4.
+ */
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Too many directories(%d) over 65535.", dir_number);
+ return (ARCHIVE_FATAL);
+ }
+
+ /* Get the size of the Path Table. */
+ calculate_path_table_size(&(iso9660->primary));
+ if (iso9660->opt.joliet)
+ calculate_path_table_size(&(iso9660->joliet));
+
+ return (ARCHIVE_OK);
+}
+
+static int
+isoent_find_out_boot_file(struct archive_write *a, struct isoent *rootent)
+{
+ struct iso9660 *iso9660 = a->format_data;
+
+ /* Find a isoent of the boot file. */
+ iso9660->el_torito.boot = isoent_find_entry(rootent,
+ iso9660->el_torito.boot_filename.s);
+ if (iso9660->el_torito.boot == NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Can't find the boot image file ``%s''",
+ iso9660->el_torito.boot_filename.s);
+ return (ARCHIVE_FATAL);
+ }
+ iso9660->el_torito.boot->file->boot = BOOT_IMAGE;
+ return (ARCHIVE_OK);
+}
+
+static int
+isoent_create_boot_catalog(struct archive_write *a, struct isoent *rootent)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ struct isofile *file;
+ struct isoent *isoent;
+ struct archive_entry *entry;
+
+ (void)rootent; /* UNUSED */
+ /*
+ * Create the entry which is the "boot.catalog" file.
+ */
+ file = isofile_new(a, NULL);
+ if (file == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+ archive_entry_set_pathname(file->entry,
+ iso9660->el_torito.catalog_filename.s);
+ archive_entry_set_size(file->entry, LOGICAL_BLOCK_SIZE);
+ archive_entry_set_mtime(file->entry, iso9660->birth_time, 0);
+ archive_entry_set_atime(file->entry, iso9660->birth_time, 0);
+ archive_entry_set_ctime(file->entry, iso9660->birth_time, 0);
+ archive_entry_set_uid(file->entry, getuid());
+ archive_entry_set_gid(file->entry, getgid());
+ archive_entry_set_mode(file->entry, AE_IFREG | 0444);
+ archive_entry_set_nlink(file->entry, 1);
+
+ if (isofile_gen_utility_names(a, file) < ARCHIVE_WARN) {
+ isofile_free(file);
+ return (ARCHIVE_FATAL);
+ }
+ file->boot = BOOT_CATALOG;
+ file->content.size = LOGICAL_BLOCK_SIZE;
+ isofile_add_entry(iso9660, file);
+
+ isoent = isoent_new(file);
+ if (isoent == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+ isoent->virtual = 1;
+
+ /* Add the "boot.catalog" entry into tree */
+ if (isoent_tree(a, &isoent) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ iso9660->el_torito.catalog = isoent;
+ /*
+ * Get a boot medai type.
+ */
+ switch (iso9660->opt.boot_type) {
+ default:
+ case OPT_BOOT_TYPE_AUTO:
+ /* Try detecting a media type of the boot image. */
+ entry = iso9660->el_torito.boot->file->entry;
+ if (archive_entry_size(entry) == FD_1_2M_SIZE)
+ iso9660->el_torito.media_type =
+ BOOT_MEDIA_1_2M_DISKETTE;
+ else if (archive_entry_size(entry) == FD_1_44M_SIZE)
+ iso9660->el_torito.media_type =
+ BOOT_MEDIA_1_44M_DISKETTE;
+ else if (archive_entry_size(entry) == FD_2_88M_SIZE)
+ iso9660->el_torito.media_type =
+ BOOT_MEDIA_2_88M_DISKETTE;
+ else
+ /* We cannot decide whether the boot image is
+ * hard-disk. */
+ iso9660->el_torito.media_type =
+ BOOT_MEDIA_NO_EMULATION;
+ break;
+ case OPT_BOOT_TYPE_NO_EMU:
+ iso9660->el_torito.media_type = BOOT_MEDIA_NO_EMULATION;
+ break;
+ case OPT_BOOT_TYPE_HARD_DISK:
+ iso9660->el_torito.media_type = BOOT_MEDIA_HARD_DISK;
+ break;
+ case OPT_BOOT_TYPE_FD:
+ entry = iso9660->el_torito.boot->file->entry;
+ if (archive_entry_size(entry) <= FD_1_2M_SIZE)
+ iso9660->el_torito.media_type =
+ BOOT_MEDIA_1_2M_DISKETTE;
+ else if (archive_entry_size(entry) <= FD_1_44M_SIZE)
+ iso9660->el_torito.media_type =
+ BOOT_MEDIA_1_44M_DISKETTE;
+ else if (archive_entry_size(entry) <= FD_2_88M_SIZE)
+ iso9660->el_torito.media_type =
+ BOOT_MEDIA_2_88M_DISKETTE;
+ else {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Boot image file(``%s'') size is too big "
+ "for fd type.",
+ iso9660->el_torito.boot_filename.s);
+ return (ARCHIVE_FATAL);
+ }
+ break;
+ }
+
+ /*
+ * Get a system type.
+ * TODO: `El Torito' specification says "A copy of byte 5 from the
+ * Partition Table found in the boot image".
+ */
+ iso9660->el_torito.system_type = 0;
+
+ /*
+ * Get an ID.
+ */
+ if (iso9660->opt.publisher)
+ archive_string_copy(&(iso9660->el_torito.id),
+ &(iso9660->publisher_identifier));
+
+
+ return (ARCHIVE_OK);
+}
+
+/*
+ * If a media type is floppy, return its image size.
+ * otherwise return 0.
+ */
+static size_t
+fd_boot_image_size(int media_type)
+{
+ switch (media_type) {
+ case BOOT_MEDIA_1_2M_DISKETTE:
+ return (FD_1_2M_SIZE);
+ case BOOT_MEDIA_1_44M_DISKETTE:
+ return (FD_1_44M_SIZE);
+ case BOOT_MEDIA_2_88M_DISKETTE:
+ return (FD_2_88M_SIZE);
+ default:
+ return (0);
+ }
+}
+
+/*
+ * Make a boot catalog image data.
+ */
+static int
+make_boot_catalog(struct archive_write *a)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ unsigned char *block;
+ unsigned char *p;
+ uint16_t sum, *wp;
+
+ block = wb_buffptr(a);
+ memset(block, 0, LOGICAL_BLOCK_SIZE);
+ p = block;
+ /*
+ * Validation Entry
+ */
+ /* Header ID */
+ p[0] = 1;
+ /* Platform ID */
+ p[1] = iso9660->el_torito.platform_id;
+ /* Reserved */
+ p[2] = p[3] = 0;
+ /* ID */
+ if (archive_strlen(&(iso9660->el_torito.id)) > 0)
+ strncpy((char *)p+4, iso9660->el_torito.id.s, 23);
+ p[27] = 0;
+ /* Checksum */
+ p[28] = p[29] = 0;
+ /* Key */
+ p[30] = 0x55;
+ p[31] = 0xAA;
+
+ sum = 0;
+ wp = (uint16_t *)block;
+ while (wp < (uint16_t *)&block[32])
+ sum += archive_le16dec(wp++);
+ set_num_721(&block[28], (~sum) + 1);
+
+ /*
+ * Initial/Default Entry
+ */
+ p = &block[32];
+ /* Boot Indicator */
+ p[0] = 0x88;
+ /* Boot media type */
+ p[1] = iso9660->el_torito.media_type;
+ /* Load Segment */
+ if (iso9660->el_torito.media_type == BOOT_MEDIA_NO_EMULATION)
+ set_num_721(&p[2], iso9660->el_torito.boot_load_seg);
+ else
+ set_num_721(&p[2], 0);
+ /* System Type */
+ p[4] = iso9660->el_torito.system_type;
+ /* Unused */
+ p[5] = 0;
+ /* Sector Count */
+ if (iso9660->el_torito.media_type == BOOT_MEDIA_NO_EMULATION)
+ set_num_721(&p[6], iso9660->el_torito.boot_load_size);
+ else
+ set_num_721(&p[6], 1);
+ /* Load RBA */
+ set_num_731(&p[8],
+ iso9660->el_torito.boot->file->content.location);
+ /* Unused */
+ memset(&p[12], 0, 20);
+
+ return (wb_consume(a, LOGICAL_BLOCK_SIZE));
+}
+
+static int
+setup_boot_information(struct archive_write *a)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ struct isoent *np;
+ int64_t size;
+ uint32_t sum;
+ unsigned char buff[4096];
+
+ np = iso9660->el_torito.boot;
+ lseek(iso9660->temp_fd,
+ np->file->content.offset_of_temp + 64, SEEK_SET);
+ size = archive_entry_size(np->file->entry) - 64;
+ if (size <= 0) {
+ archive_set_error(&a->archive, errno,
+ "Boot file(%jd) is too small", (intmax_t)size + 64);
+ return (ARCHIVE_FATAL);
+ }
+ sum = 0;
+ while (size > 0) {
+ size_t rsize;
+ ssize_t i, rs;
+
+ if (size > sizeof(buff))
+ rsize = sizeof(buff);
+ else
+ rsize = (size_t)size;
+
+ rs = read(iso9660->temp_fd, buff, rsize);
+ if (rs <= 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't read temporary file(%jd)",
+ (intmax_t)rs);
+ return (ARCHIVE_FATAL);
+ }
+ for (i = 0; i < rs; i += 4)
+ sum += archive_le32dec(buff + i);
+ size -= rs;
+ }
+ /* Set the location of Primary Volume Descriptor. */
+ set_num_731(buff, SYSTEM_AREA_BLOCK);
+ /* Set the location of the boot file. */
+ set_num_731(buff+4, np->file->content.location);
+ /* Set the size of the boot file. */
+ size = fd_boot_image_size(iso9660->el_torito.media_type);
+ if (size == 0)
+ size = archive_entry_size(np->file->entry);
+ set_num_731(buff+8, (uint32_t)size);
+ /* Set the sum of the boot file. */
+ set_num_731(buff+12, sum);
+ /* Clear reserved bytes. */
+ memset(buff+16, 0, 40);
+
+ /* Overwrite the boot file. */
+ lseek(iso9660->temp_fd,
+ np->file->content.offset_of_temp + 8, SEEK_SET);
+ return (write_to_temp(a, buff, 56));
+}
+
+#ifdef HAVE_ZLIB_H
+
+static int
+zisofs_init_zstream(struct archive_write *a)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ int r;
+
+ iso9660->zisofs.stream.next_in = NULL;
+ iso9660->zisofs.stream.avail_in = 0;
+ iso9660->zisofs.stream.total_in = 0;
+ iso9660->zisofs.stream.total_out = 0;
+ if (iso9660->zisofs.stream_valid)
+ r = deflateReset(&(iso9660->zisofs.stream));
+ else {
+ r = deflateInit(&(iso9660->zisofs.stream),
+ iso9660->zisofs.compression_level);
+ iso9660->zisofs.stream_valid = 1;
+ }
+ switch (r) {
+ case Z_OK:
+ break;
+ default:
+ case Z_STREAM_ERROR:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Internal error initializing "
+ "compression library: invalid setup parameter");
+ return (ARCHIVE_FATAL);
+ case Z_MEM_ERROR:
+ archive_set_error(&a->archive, ENOMEM,
+ "Internal error initializing "
+ "compression library");
+ return (ARCHIVE_FATAL);
+ case Z_VERSION_ERROR:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Internal error initializing "
+ "compression library: invalid library version");
+ return (ARCHIVE_FATAL);
+ }
+ return (ARCHIVE_OK);
+}
+
+#endif /* HAVE_ZLIB_H */
+
+static int
+zisofs_init(struct archive_write *a, struct isofile *file)
+{
+ struct iso9660 *iso9660 = a->format_data;
+#ifdef HAVE_ZLIB_H
+ uint64_t tsize;
+ size_t ceil, bpsize;
+ int r;
+#endif
+
+ iso9660->zisofs.detect_magic = 0;
+ iso9660->zisofs.making = 0;
+
+ if (!iso9660->opt.rr || !iso9660->opt.zisofs)
+ return (ARCHIVE_OK);
+
+ if (archive_entry_size(file->entry) >= 24 &&
+ archive_entry_size(file->entry) < MULTI_EXTENT_SIZE) {
+ /* Acceptable file size for zisofs. */
+ iso9660->zisofs.detect_magic = 1;
+ iso9660->zisofs.magic_cnt = 0;
+ }
+ if (!iso9660->zisofs.detect_magic)
+ return (ARCHIVE_OK);
+
+#ifdef HAVE_ZLIB_H
+ /* The number of Logical Blocks which uncompressed data
+ * will use in iso-image file is the same as the number of
+ * Logical Blocks which zisofs(compressed) data will use
+ * in ISO-image file. It won't reduce iso-image file size. */
+ if (archive_entry_size(file->entry) <= LOGICAL_BLOCK_SIZE)
+ return (ARCHIVE_OK);
+
+ /* Initialize compression library */
+ r = zisofs_init_zstream(a);
+ if (r != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ /* Mark file->zisofs to create RRIP 'ZF' Use Entry. */
+ file->zisofs.header_size = ZF_HEADER_SIZE >> 2;
+ file->zisofs.log2_bs = ZF_LOG2_BS;
+ file->zisofs.uncompressed_size = archive_entry_size(file->entry);
+
+ /* Calculate a size of Block Pointers of zisofs. */
+ ceil = (file->zisofs.uncompressed_size + ZF_BLOCK_SIZE -1)
+ >> file->zisofs.log2_bs;
+ iso9660->zisofs.block_pointers_cnt = ceil + 1;
+ iso9660->zisofs.block_pointers_idx = 0;
+
+ /* Ensure a buffer size used for Block Pointers */
+ bpsize = iso9660->zisofs.block_pointers_cnt *
+ sizeof(iso9660->zisofs.block_pointers[0]);
+ if (iso9660->zisofs.block_pointers_allocated < bpsize) {
+ free(iso9660->zisofs.block_pointers);
+ iso9660->zisofs.block_pointers = malloc(bpsize);
+ if (iso9660->zisofs.block_pointers == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate data");
+ return (ARCHIVE_FATAL);
+ }
+ iso9660->zisofs.block_pointers_allocated = bpsize;
+ }
+
+ /*
+ * Skip zisofs header and Block Pointers, which we will write
+ * after all compressed data of a file written to the temporary
+ * file.
+ */
+ tsize = ZF_HEADER_SIZE + bpsize;
+ if (write_null(a, tsize) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ /*
+ * Initialize some variables to make zisofs.
+ */
+ archive_le32enc(&(iso9660->zisofs.block_pointers[0]), tsize);
+ iso9660->zisofs.remaining = file->zisofs.uncompressed_size;
+ iso9660->zisofs.making = 1;
+ iso9660->zisofs.allzero = 1;
+ iso9660->zisofs.block_offset = tsize;
+ iso9660->zisofs.total_size = tsize;
+ iso9660->cur_file->cur_content->size = tsize;
+#endif
+
+ return (ARCHIVE_OK);
+}
+
+static void
+zisofs_detect_magic(struct archive_write *a, const void *buff, size_t s)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ struct isofile *file = iso9660->cur_file;
+ const unsigned char *p, *endp;
+ const unsigned char *magic_buff;
+ uint32_t uncompressed_size;
+ unsigned char header_size;
+ unsigned char log2_bs;
+ size_t ceil, doff;
+ uint32_t bst, bed;
+ int magic_max;
+ int64_t entry_size;
+
+ entry_size = archive_entry_size(file->entry);
+ if (sizeof(iso9660->zisofs.magic_buffer) > entry_size)
+ magic_max = entry_size;
+ else
+ magic_max = sizeof(iso9660->zisofs.magic_buffer);
+
+ if (iso9660->zisofs.magic_cnt == 0 && s >= (size_t)magic_max)
+ /* It's unnecessary we copy buffer. */
+ magic_buff = buff;
+ else {
+ if (iso9660->zisofs.magic_cnt < magic_max) {
+ size_t l;
+
+ l = sizeof(iso9660->zisofs.magic_buffer)
+ - iso9660->zisofs.magic_cnt;
+ if (l > s)
+ l = s;
+ memcpy(iso9660->zisofs.magic_buffer
+ + iso9660->zisofs.magic_cnt, buff, l);
+ iso9660->zisofs.magic_cnt += l;
+ if (iso9660->zisofs.magic_cnt < magic_max)
+ return;
+ }
+ magic_buff = iso9660->zisofs.magic_buffer;
+ }
+ iso9660->zisofs.detect_magic = 0;
+ p = magic_buff;
+
+ /* Check the magic code of zisofs. */
+ if (memcmp(p, zisofs_magic, sizeof(zisofs_magic)) != 0)
+ /* This is not zisofs file which made by mkzftree. */
+ return;
+ p += sizeof(zisofs_magic);
+
+ /* Read a zisofs header. */
+ uncompressed_size = archive_le32dec(p);
+ header_size = p[4];
+ log2_bs = p[5];
+ if (uncompressed_size < 24 || header_size != 4 ||
+ log2_bs > 30 || log2_bs < 7)
+ return;/* Invalid or not supported header. */
+
+ /* Calculate a size of Block Pointers of zisofs. */
+ ceil = (uncompressed_size +
+ (ARCHIVE_LITERAL_LL(1) << log2_bs) -1) >> log2_bs;
+ doff = (ceil + 1) * 4 + 16;
+ if (entry_size < doff)
+ return;/* Invalid data. */
+
+ /* Check every Block Pointer has valid value. */
+ p = magic_buff + 16;
+ endp = magic_buff + magic_max;
+ while (ceil && p + 8 <= endp) {
+ bst = archive_le32dec(p);
+ if (bst != doff)
+ return;/* Invalid data. */
+ p += 4;
+ bed = archive_le32dec(p);
+ if (bed < bst || bed > entry_size)
+ return;/* Invalid data. */
+ doff += bed - bst;
+ ceil--;
+ }
+
+ file->zisofs.uncompressed_size = uncompressed_size;
+ file->zisofs.header_size = header_size;
+ file->zisofs.log2_bs = log2_bs;
+
+ /* Disable making a zisofs image. */
+ iso9660->zisofs.making = 0;
+}
+
+#ifdef HAVE_ZLIB_H
+
+/*
+ * Compress data and write it to a temporary file.
+ */
+static int
+zisofs_write_to_temp(struct archive_write *a, const void *buff, size_t s)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ struct isofile *file = iso9660->cur_file;
+ const unsigned char *b;
+ z_stream *zstrm;
+ size_t avail, csize;
+ int flush, r;
+
+ zstrm = &(iso9660->zisofs.stream);
+ zstrm->next_out = wb_buffptr(a);
+ zstrm->avail_out = wb_remaining(a);
+ b = (const unsigned char *)buff;
+ do {
+ avail = ZF_BLOCK_SIZE - zstrm->total_in;
+ if (s < avail) {
+ avail = s;
+ flush = Z_NO_FLUSH;
+ } else
+ flush = Z_FINISH;
+ iso9660->zisofs.remaining -= avail;
+ if (iso9660->zisofs.remaining <= 0)
+ flush = Z_FINISH;
+
+ zstrm->next_in = (Bytef *)(uintptr_t)(const void *)b;
+ zstrm->avail_in = avail;
+
+ /*
+ * Check if current data block are all zero.
+ */
+ if (iso9660->zisofs.allzero) {
+ const unsigned char *nonzero = b;
+ const unsigned char *nonzeroend = b + avail;
+
+ while (nonzero < nonzeroend)
+ if (*nonzero++) {
+ iso9660->zisofs.allzero = 0;
+ break;
+ }
+ }
+ b += avail;
+ s -= avail;
+
+ /*
+ * If current data block are all zero, we do not use
+ * compressed data.
+ */
+ if (flush == Z_FINISH && iso9660->zisofs.allzero &&
+ avail + zstrm->total_in == ZF_BLOCK_SIZE) {
+ if (iso9660->zisofs.block_offset !=
+ file->cur_content->size) {
+ int64_t diff;
+
+ r = wb_set_offset(a,
+ file->cur_content->offset_of_temp +
+ iso9660->zisofs.block_offset);
+ if (r != ARCHIVE_OK)
+ return (r);
+ diff = file->cur_content->size -
+ iso9660->zisofs.block_offset;
+ file->cur_content->size -= diff;
+ iso9660->zisofs.total_size -= diff;
+ }
+ zstrm->avail_in = 0;
+ }
+
+ /*
+ * Compress file data.
+ */
+ while (zstrm->avail_in > 0) {
+ csize = zstrm->total_out;
+ r = deflate(zstrm, flush);
+ switch (r) {
+ case Z_OK:
+ case Z_STREAM_END:
+ csize = zstrm->total_out - csize;
+ if (wb_consume(a, csize) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ iso9660->zisofs.total_size += csize;
+ iso9660->cur_file->cur_content->size += csize;
+ zstrm->next_out = wb_buffptr(a);
+ zstrm->avail_out = wb_remaining(a);
+ break;
+ default:
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Compression failed:"
+ " deflate() call returned status %d",
+ r);
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ if (flush == Z_FINISH) {
+ /*
+ * Save the information of one zisofs block.
+ */
+ iso9660->zisofs.block_pointers_idx ++;
+ archive_le32enc(&(iso9660->zisofs.block_pointers[
+ iso9660->zisofs.block_pointers_idx]),
+ iso9660->zisofs.total_size);
+ r = zisofs_init_zstream(a);
+ if (r != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ iso9660->zisofs.allzero = 1;
+ iso9660->zisofs.block_offset = file->cur_content->size;
+ }
+ } while (s);
+
+ return (ARCHIVE_OK);
+}
+
+static int
+zisofs_finish_entry(struct archive_write *a)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ struct isofile *file = iso9660->cur_file;
+ unsigned char buff[16];
+ size_t s;
+ int64_t tail;
+
+ /* Direct temp file stream to zisofs temp file stream. */
+ archive_entry_set_size(file->entry, iso9660->zisofs.total_size);
+
+ /*
+ * Save a file pointer which points the end of current zisofs data.
+ */
+ tail = wb_offset(a);
+
+ /*
+ * Make a header.
+ *
+ * +-----------------+----------------+-----------------+
+ * | Header 16 bytes | Block Pointers | Compressed data |
+ * +-----------------+----------------+-----------------+
+ * 0 16 +X
+ * Block Pointers :
+ * 4 * (((Uncompressed file size + block_size -1) / block_size) + 1)
+ *
+ * Write zisofs header.
+ * Magic number
+ * +----+----+----+----+----+----+----+----+
+ * | 37 | E4 | 53 | 96 | C9 | DB | D6 | 07 |
+ * +----+----+----+----+----+----+----+----+
+ * 0 1 2 3 4 5 6 7 8
+ *
+ * +------------------------+------------------+
+ * | Uncompressed file size | header_size >> 2 |
+ * +------------------------+------------------+
+ * 8 12 13
+ *
+ * +-----------------+----------------+
+ * | log2 block_size | Reserved(0000) |
+ * +-----------------+----------------+
+ * 13 14 16
+ */
+ memcpy(buff, zisofs_magic, 8);
+ set_num_731(buff+8, file->zisofs.uncompressed_size);
+ buff[12] = file->zisofs.header_size;
+ buff[13] = file->zisofs.log2_bs;
+ buff[14] = buff[15] = 0;/* Reserved */
+
+ /* Move to the right position to write the header. */
+ wb_set_offset(a, file->content.offset_of_temp);
+
+ /* Write the header. */
+ if (wb_write_to_temp(a, buff, 16) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ /*
+ * Write zisofs Block Pointers.
+ */
+ s = iso9660->zisofs.block_pointers_cnt *
+ sizeof(iso9660->zisofs.block_pointers[0]);
+ if (wb_write_to_temp(a, iso9660->zisofs.block_pointers, s)
+ != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ /* Set a file pointer back to the end of the temporary file. */
+ wb_set_offset(a, tail);
+
+ return (ARCHIVE_OK);
+}
+
+static int
+zisofs_free(struct archive_write *a)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ int ret = ARCHIVE_OK;
+
+ free(iso9660->zisofs.block_pointers);
+ if (iso9660->zisofs.stream_valid &&
+ deflateEnd(&(iso9660->zisofs.stream)) != Z_OK) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Failed to clean up compressor");
+ ret = ARCHIVE_FATAL;
+ }
+ iso9660->zisofs.block_pointers = NULL;
+ iso9660->zisofs.stream_valid = 0;
+ return (ret);
+}
+
+struct zisofs_extract {
+ int pz_log2_bs; /* Log2 of block size */
+ uint64_t pz_uncompressed_size;
+ size_t uncompressed_buffer_size;
+
+ int initialized:1;
+ int header_passed:1;
+
+ uint32_t pz_offset;
+ unsigned char *block_pointers;
+ size_t block_pointers_size;
+ size_t block_pointers_avail;
+ size_t block_off;
+ uint32_t block_avail;
+
+ z_stream stream;
+ int stream_valid;
+};
+
+static ssize_t
+zisofs_extract_init(struct archive_write *a, struct zisofs_extract *zisofs,
+ const unsigned char *p, size_t bytes)
+{
+ size_t avail = bytes;
+ size_t ceil, xsize;
+
+ /* Allocate block pointers buffer. */
+ ceil = (zisofs->pz_uncompressed_size +
+ (((int64_t)1) << zisofs->pz_log2_bs) - 1)
+ >> zisofs->pz_log2_bs;
+ xsize = (ceil + 1) * 4;
+ if (zisofs->block_pointers == NULL) {
+ size_t alloc = ((xsize >> 10) + 1) << 10;
+ zisofs->block_pointers = malloc(alloc);
+ if (zisofs->block_pointers == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "No memory for zisofs decompression");
+ return (ARCHIVE_FATAL);
+ }
+ }
+ zisofs->block_pointers_size = xsize;
+
+ /* Allocate uncompressed data buffer. */
+ zisofs->uncompressed_buffer_size = 1UL << zisofs->pz_log2_bs;
+
+ /*
+ * Read the file header, and check the magic code of zisofs.
+ */
+ if (!zisofs->header_passed) {
+ int err = 0;
+ if (avail < 16) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Illegal zisofs file body");
+ return (ARCHIVE_FATAL);
+ }
+
+ if (memcmp(p, zisofs_magic, sizeof(zisofs_magic)) != 0)
+ err = 1;
+ else if (archive_le32dec(p + 8) != zisofs->pz_uncompressed_size)
+ err = 1;
+ else if (p[12] != 4 || p[13] != zisofs->pz_log2_bs)
+ err = 1;
+ if (err) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Illegal zisofs file body");
+ return (ARCHIVE_FATAL);
+ }
+ avail -= 16;
+ p += 16;
+ zisofs->header_passed = 1;
+ }
+
+ /*
+ * Read block pointers.
+ */
+ if (zisofs->header_passed &&
+ zisofs->block_pointers_avail < zisofs->block_pointers_size) {
+ xsize = zisofs->block_pointers_size
+ - zisofs->block_pointers_avail;
+ if (avail < xsize)
+ xsize = avail;
+ memcpy(zisofs->block_pointers
+ + zisofs->block_pointers_avail, p, xsize);
+ zisofs->block_pointers_avail += xsize;
+ avail -= xsize;
+ if (zisofs->block_pointers_avail
+ == zisofs->block_pointers_size) {
+ /* We've got all block pointers and initialize
+ * related variables. */
+ zisofs->block_off = 0;
+ zisofs->block_avail = 0;
+ /* Complete a initialization */
+ zisofs->initialized = 1;
+ }
+ }
+ return ((ssize_t)avail);
+}
+
+static ssize_t
+zisofs_extract(struct archive_write *a, struct zisofs_extract *zisofs,
+ const unsigned char *p, size_t bytes)
+{
+ size_t avail;
+ int r;
+
+ if (!zisofs->initialized) {
+ ssize_t rs = zisofs_extract_init(a, zisofs, p, bytes);
+ if (rs < 0)
+ return (rs);
+ if (!zisofs->initialized) {
+ /* We need more data. */
+ zisofs->pz_offset += bytes;
+ return (bytes);
+ }
+ avail = rs;
+ p += bytes - avail;
+ } else
+ avail = bytes;
+
+ /*
+ * Get block offsets from block pointers.
+ */
+ if (zisofs->block_avail == 0) {
+ uint32_t bst, bed;
+
+ if (zisofs->block_off + 4 >= zisofs->block_pointers_size) {
+ /* There isn't a pair of offsets. */
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Illegal zisofs block pointers");
+ return (ARCHIVE_FATAL);
+ }
+ bst = archive_le32dec(
+ zisofs->block_pointers + zisofs->block_off);
+ if (bst != zisofs->pz_offset + (bytes - avail)) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Illegal zisofs block pointers(cannot seek)");
+ return (ARCHIVE_FATAL);
+ }
+ bed = archive_le32dec(
+ zisofs->block_pointers + zisofs->block_off + 4);
+ if (bed < bst) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Illegal zisofs block pointers");
+ return (ARCHIVE_FATAL);
+ }
+ zisofs->block_avail = bed - bst;
+ zisofs->block_off += 4;
+
+ /* Initialize compression library for new block. */
+ if (zisofs->stream_valid)
+ r = inflateReset(&zisofs->stream);
+ else
+ r = inflateInit(&zisofs->stream);
+ if (r != Z_OK) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Can't initialize zisofs decompression.");
+ return (ARCHIVE_FATAL);
+ }
+ zisofs->stream_valid = 1;
+ zisofs->stream.total_in = 0;
+ zisofs->stream.total_out = 0;
+ }
+
+ /*
+ * Make uncompressed data.
+ */
+ if (zisofs->block_avail == 0) {
+ /*
+ * It's basically 32K bytes NUL data.
+ */
+ unsigned char *wb;
+ size_t size, wsize;
+
+ size = zisofs->uncompressed_buffer_size;
+ while (size) {
+ wb = wb_buffptr(a);
+ if (size > wb_remaining(a))
+ wsize = wb_remaining(a);
+ else
+ wsize = size;
+ memset(wb, 0, wsize);
+ r = wb_consume(a, wsize);
+ if (r < 0)
+ return (r);
+ size -= wsize;
+ }
+ } else {
+ zisofs->stream.next_in = (Bytef *)(uintptr_t)(const void *)p;
+ if (avail > zisofs->block_avail)
+ zisofs->stream.avail_in = zisofs->block_avail;
+ else
+ zisofs->stream.avail_in = avail;
+ zisofs->stream.next_out = wb_buffptr(a);
+ zisofs->stream.avail_out = wb_remaining(a);
+
+ r = inflate(&zisofs->stream, 0);
+ switch (r) {
+ case Z_OK: /* Decompressor made some progress.*/
+ case Z_STREAM_END: /* Found end of stream. */
+ break;
+ default:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "zisofs decompression failed (%d)", r);
+ return (ARCHIVE_FATAL);
+ }
+ avail -= zisofs->stream.next_in - p;
+ zisofs->block_avail -= zisofs->stream.next_in - p;
+ r = wb_consume(a, wb_remaining(a) - zisofs->stream.avail_out);
+ if (r < 0)
+ return (r);
+ }
+ zisofs->pz_offset += bytes;
+ return (bytes - avail);
+}
+
+static int
+zisofs_rewind_boot_file(struct archive_write *a)
+{
+ struct iso9660 *iso9660 = a->format_data;
+ struct isofile *file;
+ unsigned char *rbuff;
+ ssize_t r;
+ size_t remaining, rbuff_size;
+ struct zisofs_extract zext;
+ int64_t read_offset, write_offset, new_offset;
+ int fd, ret = ARCHIVE_OK;
+
+ file = iso9660->el_torito.boot->file;
+ /*
+ * There is nothing to do if this boot file does not have
+ * zisofs header.
+ */
+ if (file->zisofs.header_size == 0)
+ return (ARCHIVE_OK);
+
+ /*
+ * Uncompress the zisofs'ed file contents.
+ */
+ memset(&zext, 0, sizeof(zext));
+ zext.pz_uncompressed_size = file->zisofs.uncompressed_size;
+ zext.pz_log2_bs = file->zisofs.log2_bs;
+
+ fd = iso9660->temp_fd;
+ new_offset = wb_offset(a);
+ read_offset = file->content.offset_of_temp;
+ remaining = file->content.size;
+ if (remaining > 1024 * 32)
+ rbuff_size = 1024 * 32;
+ else
+ rbuff_size = remaining;
+
+ rbuff = malloc(rbuff_size);
+ if (rbuff == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+ while (remaining) {
+ size_t rsize;
+ ssize_t rs;
+
+ /* Get the current file pointer. */
+ write_offset = lseek(fd, 0, SEEK_CUR);
+
+ /* Change the file pointer to read. */
+ lseek(fd, read_offset, SEEK_SET);
+
+ rsize = rbuff_size;
+ if (rsize > remaining)
+ rsize = remaining;
+ rs = read(iso9660->temp_fd, rbuff, rsize);
+ if (rs <= 0) {
+ archive_set_error(&a->archive, errno,
+ "Can't read temporary file(%jd)", (intmax_t)rs);
+ ret = ARCHIVE_FATAL;
+ break;
+ }
+ remaining -= rs;
+ read_offset += rs;
+
+ /* Put the file pointer back to write. */
+ lseek(fd, write_offset, SEEK_SET);
+
+ r = zisofs_extract(a, &zext, rbuff, rs);
+ if (r < 0) {
+ ret = (int)r;
+ break;
+ }
+ }
+
+ if (ret == ARCHIVE_OK) {
+ /*
+ * Change the boot file content from zisofs'ed data
+ * to plain data.
+ */
+ file->content.offset_of_temp = new_offset;
+ file->content.size = file->zisofs.uncompressed_size;
+ archive_entry_set_size(file->entry, file->content.size);
+ /* Set to be no zisofs. */
+ file->zisofs.header_size = 0;
+ file->zisofs.log2_bs = 0;
+ file->zisofs.uncompressed_size = 0;
+ r = wb_write_padding_to_temp(a, file->content.size);
+ if (r < 0)
+ ret = ARCHIVE_FATAL;
+ }
+
+ /*
+ * Free the resource we used in this function only.
+ */
+ free(rbuff);
+ free(zext.block_pointers);
+ if (zext.stream_valid && inflateEnd(&(zext.stream)) != Z_OK) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Failed to clean up compressor");
+ ret = ARCHIVE_FATAL;
+ }
+
+ return (ret);
+}
+
+#else
+
+static int
+zisofs_write_to_temp(struct archive_write *a, const void *buff, size_t s)
+{
+ (void)buff; /* UNUSED */
+ (void)s; /* UNUSED */
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Programing error");
+ return (ARCHIVE_FATAL);
+}
+
+static int
+zisofs_rewind_boot_file(struct archive_write *a)
+{
+ struct iso9660 *iso9660 = a->format_data;
+
+ if (iso9660->el_torito.boot->file->zisofs.header_size != 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "We cannot extract the zisofs imaged boot file;"
+ " this may not boot in being zisofs imaged");
+ return (ARCHIVE_FAILED);
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+zisofs_finish_entry(struct archive_write *a)
+{
+ (void)a; /* UNUSED */
+ return (ARCHIVE_OK);
+}
+
+static int
+zisofs_free(struct archive_write *a)
+{
+ (void)a; /* UNUSED */
+ return (ARCHIVE_OK);
+}
+
+#endif /* HAVE_ZLIB_H */
+
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_mtree.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_mtree.c
new file mode 100644
index 000000000..3802a25f3
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_mtree.c
@@ -0,0 +1,1468 @@
+/*-
+ * Copyright (c) 2009,2011 Michihiro NAKAJIMA
+ * Copyright (c) 2008 Joerg Sonnenberger
+ * 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_mtree.c 201171 2009-12-29 06:39:07Z kientzle $");
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "archive.h"
+#include "archive_crypto_private.h"
+#include "archive_entry.h"
+#include "archive_private.h"
+#include "archive_write_private.h"
+
+#define INDENTNAMELEN 15
+#define MAXLINELEN 80
+#define SET_KEYS \
+ (F_FLAGS | F_GID | F_GNAME | F_MODE | F_TYPE | F_UID | F_UNAME)
+
+struct mtree_entry {
+ struct mtree_entry *next;
+
+ char *pathname;
+ char *symlink;
+ unsigned int nlink;
+ mode_t filetype;
+ mode_t mode;
+ int64_t uid;
+ int64_t gid;
+ char *uname;
+ char *gname;
+ char *fflags_text;
+ unsigned long fflags_set;
+ unsigned long fflags_clear;
+ time_t mtime;
+ long mtime_nsec;
+ dev_t rdevmajor;
+ dev_t rdevminor;
+ int64_t size;
+
+ int compute_sum;
+ uint32_t crc;
+#ifdef ARCHIVE_HAS_MD5
+ unsigned char buf_md5[16];
+#endif
+#ifdef ARCHIVE_HAS_RMD160
+ unsigned char buf_rmd160[20];
+#endif
+#ifdef ARCHIVE_HAS_SHA1
+ unsigned char buf_sha1[20];
+#endif
+#ifdef ARCHIVE_HAS_SHA256
+ unsigned char buf_sha256[32];
+#endif
+#ifdef ARCHIVE_HAS_SHA384
+ unsigned char buf_sha384[48];
+#endif
+#ifdef ARCHIVE_HAS_SHA512
+ unsigned char buf_sha512[64];
+#endif
+};
+
+struct attr_counter {
+ struct attr_counter *prev;
+ struct attr_counter *next;
+ int count;
+ struct mtree_entry *m_entry;
+};
+
+struct mtree_writer {
+ struct mtree_entry *mtree_entry;
+ struct archive_string ebuf;
+ struct archive_string buf;
+ int first;
+ uint64_t entry_bytes_remaining;
+ struct {
+ int output;
+ int processed;
+ struct archive_string parent;
+ mode_t type;
+ int keys;
+ int64_t uid;
+ int64_t gid;
+ mode_t mode;
+ unsigned long fflags_set;
+ unsigned long fflags_clear;
+
+ struct attr_counter *uid_list;
+ struct attr_counter *gid_list;
+ struct attr_counter *mode_list;
+ struct attr_counter *flags_list;
+ struct mtree_entry *me_first;
+ struct mtree_entry **me_last;
+ } set;
+ /* check sum */
+ int compute_sum;
+ uint32_t crc;
+ uint64_t crc_len;
+#ifdef ARCHIVE_HAS_MD5
+ archive_md5_ctx md5ctx;
+#endif
+#ifdef ARCHIVE_HAS_RMD160
+ archive_rmd160_ctx rmd160ctx;
+#endif
+#ifdef ARCHIVE_HAS_SHA1
+ archive_sha1_ctx sha1ctx;
+#endif
+#ifdef ARCHIVE_HAS_SHA256
+ archive_sha256_ctx sha256ctx;
+#endif
+#ifdef ARCHIVE_HAS_SHA384
+ archive_sha384_ctx sha384ctx;
+#endif
+#ifdef ARCHIVE_HAS_SHA512
+ archive_sha512_ctx sha512ctx;
+#endif
+ /* Keyword options */
+ int keys;
+#define F_CKSUM 0x00000001 /* check sum */
+#define F_DEV 0x00000002 /* device type */
+#define F_DONE 0x00000004 /* directory done */
+#define F_FLAGS 0x00000008 /* file flags */
+#define F_GID 0x00000010 /* gid */
+#define F_GNAME 0x00000020 /* group name */
+#define F_IGN 0x00000040 /* ignore */
+#define F_MAGIC 0x00000080 /* name has magic chars */
+#define F_MD5 0x00000100 /* MD5 digest */
+#define F_MODE 0x00000200 /* mode */
+#define F_NLINK 0x00000400 /* number of links */
+#define F_NOCHANGE 0x00000800 /* If owner/mode "wrong", do
+ * not change */
+#define F_OPT 0x00001000 /* existence optional */
+#define F_RMD160 0x00002000 /* RIPEMD160 digest */
+#define F_SHA1 0x00004000 /* SHA-1 digest */
+#define F_SIZE 0x00008000 /* size */
+#define F_SLINK 0x00010000 /* symbolic link */
+#define F_TAGS 0x00020000 /* tags */
+#define F_TIME 0x00040000 /* modification time */
+#define F_TYPE 0x00080000 /* file type */
+#define F_UID 0x00100000 /* uid */
+#define F_UNAME 0x00200000 /* user name */
+#define F_VISIT 0x00400000 /* file visited */
+#define F_SHA256 0x00800000 /* SHA-256 digest */
+#define F_SHA384 0x01000000 /* SHA-384 digest */
+#define F_SHA512 0x02000000 /* SHA-512 digest */
+
+ /* Options */
+ int dironly; /* if the dironly is 1, ignore everything except
+ * directory type files. like mtree(8) -d option.
+ */
+ int indent; /* if the indent is 1, indent writing data. */
+};
+
+#define DEFAULT_KEYS (F_DEV | F_FLAGS | F_GID | F_GNAME | F_SLINK | F_MODE\
+ | F_NLINK | F_SIZE | F_TIME | F_TYPE | F_UID\
+ | F_UNAME)
+
+static struct attr_counter * new_attr_count(struct mtree_entry *,
+ struct attr_counter *);
+static void free_attr_count(struct attr_counter **);
+static int inc_attr_count(struct attr_counter **, struct attr_counter *,
+ struct attr_counter *, struct mtree_entry *);
+static int collect_set_values(struct mtree_writer *, struct mtree_entry *);
+static int get_keys(struct mtree_writer *, struct mtree_entry *);
+static void sum_init(struct mtree_writer *);
+static void sum_update(struct mtree_writer *, const void *, size_t);
+static void sum_final(struct mtree_writer *, struct mtree_entry *);
+static void sum_write(struct archive_string *, struct mtree_entry *);
+
+#define COMPUTE_CRC(var, ch) (var) = (var) << 8 ^ crctab[(var) >> 24 ^ (ch)]
+static const uint32_t crctab[] = {
+ 0x0,
+ 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
+ 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6,
+ 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
+ 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac,
+ 0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f,
+ 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a,
+ 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
+ 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58,
+ 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033,
+ 0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe,
+ 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
+ 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4,
+ 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
+ 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5,
+ 0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
+ 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07,
+ 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c,
+ 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1,
+ 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
+ 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b,
+ 0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698,
+ 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d,
+ 0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
+ 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f,
+ 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
+ 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80,
+ 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
+ 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a,
+ 0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629,
+ 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c,
+ 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
+ 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e,
+ 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65,
+ 0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8,
+ 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
+ 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2,
+ 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
+ 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74,
+ 0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
+ 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0x7b827d21,
+ 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a,
+ 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087,
+ 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
+ 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d,
+ 0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce,
+ 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb,
+ 0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
+ 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09,
+ 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
+ 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf,
+ 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
+};
+
+static int
+mtree_safe_char(char c)
+{
+ if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
+ return 1;
+ if (c >= '0' && c <= '9')
+ return 1;
+ if (c == 35 || c == 61 || c == 92)
+ return 0; /* #, = and \ are always quoted */
+
+ if (c >= 33 && c <= 47) /* !"$%&'()*+,-./ */
+ return 1;
+ if (c >= 58 && c <= 64) /* :;<>?@ */
+ return 1;
+ if (c >= 91 && c <= 96) /* []^_` */
+ return 1;
+ if (c >= 123 && c <= 126) /* {|}~ */
+ return 1;
+ return 0;
+}
+
+static void
+mtree_quote(struct archive_string *s, const char *str)
+{
+ const char *start;
+ char buf[4];
+ unsigned char c;
+
+ for (start = str; *str != '\0'; ++str) {
+ if (mtree_safe_char(*str))
+ continue;
+ if (start != str)
+ archive_strncat(s, start, str - start);
+ c = (unsigned char)*str;
+ buf[0] = '\\';
+ buf[1] = (c / 64) + '0';
+ buf[2] = (c / 8 % 8) + '0';
+ buf[3] = (c % 8) + '0';
+ archive_strncat(s, buf, 4);
+ start = str + 1;
+ }
+
+ if (start != str)
+ archive_strncat(s, start, str - start);
+}
+
+/*
+ * Indent a line as mtree utility to be readable for people.
+ */
+static void
+mtree_indent(struct mtree_writer *mtree)
+{
+ int i, fn;
+ const char *r, *s, *x;
+
+ fn = 1;
+ s = r = mtree->ebuf.s;
+ x = NULL;
+ while (*r == ' ')
+ r++;
+ while ((r = strchr(r, ' ')) != NULL) {
+ if (fn) {
+ fn = 0;
+ archive_strncat(&mtree->buf, s, r - s);
+ if (r -s > INDENTNAMELEN) {
+ archive_strncat(&mtree->buf, " \\\n", 3);
+ for (i = 0; i < (INDENTNAMELEN + 1); i++)
+ archive_strappend_char(&mtree->buf, ' ');
+ } else {
+ for (i = r -s; i < (INDENTNAMELEN + 1); i++)
+ archive_strappend_char(&mtree->buf, ' ');
+ }
+ s = ++r;
+ x = NULL;
+ continue;
+ }
+ if (r - s <= MAXLINELEN - 3 - INDENTNAMELEN)
+ x = r++;
+ else {
+ if (x == NULL)
+ x = r;
+ archive_strncat(&mtree->buf, s, x - s);
+ archive_strncat(&mtree->buf, " \\\n", 3);
+ for (i = 0; i < (INDENTNAMELEN + 1); i++)
+ archive_strappend_char(&mtree->buf, ' ');
+ s = r = ++x;
+ x = NULL;
+ }
+ }
+ if (x != NULL && strlen(s) > MAXLINELEN - 3 - INDENTNAMELEN) {
+ /* Last keyword is longer. */
+ archive_strncat(&mtree->buf, s, x - s);
+ archive_strncat(&mtree->buf, " \\\n", 3);
+ for (i = 0; i < (INDENTNAMELEN + 1); i++)
+ archive_strappend_char(&mtree->buf, ' ');
+ s = ++x;
+ }
+ archive_strcat(&mtree->buf, s);
+ archive_string_empty(&mtree->ebuf);
+}
+
+#if !defined(_WIN32) || defined(__CYGWIN__)
+static size_t
+dir_len(struct mtree_entry *me)
+{
+ const char *path, *r;
+
+ path = me->pathname;
+ r = strrchr(path, '/');
+ if (r == NULL)
+ return (0);
+ /* Include a separator size */
+ return (r - path + 1);
+}
+
+#else /* _WIN32 && !__CYGWIN__ */
+/*
+ * Note: We should use wide-character for findng '\' character,
+ * a directory separator on Windows, because some character-set have
+ * been using the '\' character for a part of its multibyte character
+ * code.
+ */
+static size_t
+dir_len(struct mtree_entry *me)
+{
+ wchar_t wc;
+ const char *path;
+ const char *p, *rp;
+ size_t al, l, size;
+
+ path = me->pathname;
+ al = l = -1;
+ for (p = path; *p != '\0'; ++p) {
+ if (*p == '\\')
+ al = l = p - path;
+ else if (*p == '/')
+ al = p - path;
+ }
+ if (l == -1)
+ goto alen;
+ size = p - path;
+ rp = p = path;
+ while (*p != '\0') {
+ l = mbtowc(&wc, p, size);
+ if (l == -1)
+ goto alen;
+ if (l == 1 && (wc == L'/' || wc == L'\\'))
+ rp = p;
+ p += l;
+ size -= l;
+ }
+ return (rp - path + 1);
+alen:
+ if (al == -1)
+ return (0);
+ return (al + 1);
+}
+#endif /* _WIN32 && !__CYGWIN__ */
+
+/*
+ * Test if a parent directory of the current entry is changed.
+ */
+static int
+parent_dir_changed(struct archive_string *dir, struct mtree_entry *me)
+{
+ const char *path;
+ size_t l;
+
+ l = dir_len(me);
+ path = me->pathname;
+ if (archive_strlen(dir) > 0) {
+ if (l == 0) {
+ archive_string_empty(dir);
+ return (1);
+ }
+ if (strncmp(dir->s, path, l) == 0)
+ return (0); /* The parent directory is the same. */
+ } else if (l == 0)
+ return (0); /* The parent directory is the same. */
+ archive_strncpy(dir, path, l);
+ return (1);
+}
+
+/*
+ * Write /set keyword.
+ * Set most used value of uid,gid,mode and fflags, which are
+ * collected by collect_set_values() function.
+ */
+static void
+write_global(struct mtree_writer *mtree)
+{
+ struct archive_string setstr;
+ struct archive_string unsetstr;
+ const char *name;
+ int keys, oldkeys, effkeys;
+ struct attr_counter *ac;
+
+ archive_string_init(&setstr);
+ archive_string_init(&unsetstr);
+ keys = mtree->keys & SET_KEYS;
+ oldkeys = mtree->set.keys;
+ effkeys = keys;
+ if (mtree->set.processed) {
+ /*
+ * Check if the global data needs updating.
+ */
+ effkeys &= ~F_TYPE;
+ if (oldkeys & (F_UNAME | F_UID)) {
+ ac = mtree->set.uid_list;
+ do {
+ if (mtree->set.uid == ac->m_entry->uid) {
+ effkeys &= ~(F_UNAME | F_UID);
+ break;
+ }
+ if (ac->next != NULL &&
+ ac->next->count == ac->count)
+ continue;
+ } while (0);
+ }
+ if (oldkeys & (F_GNAME | F_GID)) {
+ ac = mtree->set.gid_list;
+ do {
+ if (mtree->set.gid == ac->m_entry->gid) {
+ effkeys &= ~(F_GNAME | F_GID);
+ break;
+ }
+ if (ac->next != NULL &&
+ ac->next->count == ac->count)
+ continue;
+ } while (0);
+ }
+ if (oldkeys & F_MODE) {
+ ac = mtree->set.mode_list;
+ do {
+ if (mtree->set.mode == ac->m_entry->mode) {
+ effkeys &= ~F_MODE;
+ break;
+ }
+ if (ac->next != NULL &&
+ ac->next->count == ac->count)
+ continue;
+ } while (0);
+ }
+ if ((oldkeys & F_FLAGS) != 0) {
+ ac = mtree->set.flags_list;
+ do {
+ if (ac->m_entry->fflags_set ==
+ mtree->set.fflags_set &&
+ ac->m_entry->fflags_clear ==
+ mtree->set.fflags_clear) {
+ effkeys &= ~F_FLAGS;
+ break;
+ }
+ if (ac->next != NULL &&
+ ac->next->count == ac->count)
+ continue;
+ } while (0);
+ }
+ }
+ if ((keys & effkeys & F_TYPE) != 0) {
+ if (mtree->dironly) {
+ archive_strcat(&setstr, " type=dir");
+ mtree->set.type = AE_IFDIR;
+ } else {
+ archive_strcat(&setstr, " type=file");
+ mtree->set.type = AE_IFREG;
+ }
+ }
+ if ((keys & effkeys & F_UNAME) != 0) {
+ name = mtree->set.uid_list->m_entry->uname;
+ if (name != NULL) {
+ archive_strcat(&setstr, " uname=");
+ mtree_quote(&setstr, name);
+ } else {
+ keys &= ~F_UNAME;
+ if ((oldkeys & F_UNAME) != 0)
+ archive_strcat(&unsetstr, " uname");
+ }
+ }
+ if ((keys & effkeys & F_UID) != 0) {
+ mtree->set.uid = mtree->set.uid_list->m_entry->uid;
+ archive_string_sprintf(&setstr, " uid=%jd",
+ (intmax_t)mtree->set.uid);
+ }
+ if ((keys & effkeys & F_GNAME) != 0) {
+ name = mtree->set.gid_list->m_entry->gname;
+ if (name != NULL) {
+ archive_strcat(&setstr, " gname=");
+ mtree_quote(&setstr, name);
+ } else {
+ keys &= ~F_GNAME;
+ if ((oldkeys & F_GNAME) != 0)
+ archive_strcat(&unsetstr, " gname");
+ }
+ }
+ if ((keys & effkeys & F_GID) != 0) {
+ mtree->set.gid = mtree->set.gid_list->m_entry->gid;
+ archive_string_sprintf(&setstr, " gid=%jd",
+ (intmax_t)mtree->set.gid);
+ }
+ if ((keys & effkeys & F_MODE) != 0) {
+ mtree->set.mode = mtree->set.mode_list->m_entry->mode;
+ archive_string_sprintf(&setstr, " mode=%o",
+ (unsigned int)mtree->set.mode);
+ }
+ if ((keys & effkeys & F_FLAGS) != 0) {
+ name = mtree->set.flags_list->m_entry->fflags_text;
+ if (name != NULL) {
+ archive_strcat(&setstr, " flags=");
+ mtree_quote(&setstr, name);
+ mtree->set.fflags_set =
+ mtree->set.flags_list->m_entry->fflags_set;
+ mtree->set.fflags_clear =
+ mtree->set.flags_list->m_entry->fflags_clear;
+ } else {
+ keys &= ~F_FLAGS;
+ if ((oldkeys & F_FLAGS) != 0)
+ archive_strcat(&unsetstr, " flags");
+ }
+ }
+ if (unsetstr.length > 0)
+ archive_string_sprintf(&mtree->buf, "/unset%s\n", unsetstr.s);
+ archive_string_free(&unsetstr);
+ if (setstr.length > 0)
+ archive_string_sprintf(&mtree->buf, "/set%s\n", setstr.s);
+ archive_string_free(&setstr);
+ mtree->set.keys = keys;
+ mtree->set.processed = 1;
+
+ free_attr_count(&mtree->set.uid_list);
+ free_attr_count(&mtree->set.gid_list);
+ free_attr_count(&mtree->set.mode_list);
+ free_attr_count(&mtree->set.flags_list);
+}
+
+static struct attr_counter *
+new_attr_count(struct mtree_entry *me, struct attr_counter *prev)
+{
+ struct attr_counter *ac;
+
+ ac = malloc(sizeof(*ac));
+ if (ac != NULL) {
+ ac->prev = prev;
+ ac->next = NULL;
+ ac->count = 1;
+ ac->m_entry = me;
+ }
+ return (ac);
+}
+
+static void
+free_attr_count(struct attr_counter **top)
+{
+ struct attr_counter *ac, *tac;
+
+ if (*top == NULL)
+ return;
+ ac = *top;
+ while (ac != NULL) {
+ tac = ac->next;
+ free(ac);
+ ac = tac;
+ }
+ *top = NULL;
+}
+
+static int
+inc_attr_count(struct attr_counter **top, struct attr_counter *ac,
+ struct attr_counter *last, struct mtree_entry *me)
+{
+ struct attr_counter *pac;
+
+ if (ac != NULL) {
+ ac->count++;
+ if (*top == ac || ac->prev->count >= ac->count)
+ return (0);
+ for (pac = ac->prev; pac; pac = pac->prev) {
+ if (pac->count >= ac->count)
+ break;
+ }
+ ac->prev->next = ac->next;
+ if (ac->next != NULL)
+ ac->next->prev = ac->prev;
+ if (pac != NULL) {
+ ac->prev = pac;
+ ac->next = pac->next;
+ pac->next = ac;
+ if (ac->next != NULL)
+ ac->next->prev = ac;
+ } else {
+ ac->prev = NULL;
+ ac->next = *top;
+ *top = ac;
+ ac->next->prev = ac;
+ }
+ } else {
+ ac = new_attr_count(me, last);
+ if (ac == NULL)
+ return (-1);
+ last->next = ac;
+ }
+ return (0);
+}
+
+static int
+collect_set_values(struct mtree_writer *mtree, struct mtree_entry *me)
+{
+ int keys = mtree->keys;
+ struct attr_counter *ac, *last;
+
+ if (keys & (F_UNAME | F_UID)) {
+ if (mtree->set.uid_list == NULL) {
+ mtree->set.uid_list = new_attr_count(me, NULL);
+ if (mtree->set.uid_list == NULL)
+ return (-1);
+ } else {
+ last = NULL;
+ for (ac = mtree->set.uid_list; ac; ac = ac->next) {
+ if (ac->m_entry->uid == me->uid)
+ break;
+ last = ac;
+ }
+ if (inc_attr_count(
+ &mtree->set.uid_list, ac, last, me) < 0)
+ return (-1);
+ }
+ }
+ if (keys & (F_GNAME | F_GID)) {
+ if (mtree->set.gid_list == NULL) {
+ mtree->set.gid_list = new_attr_count(me, NULL);
+ if (mtree->set.gid_list == NULL)
+ return (-1);
+ } else {
+ last = NULL;
+ for (ac = mtree->set.gid_list; ac; ac = ac->next) {
+ if (ac->m_entry->gid == me->gid)
+ break;
+ last = ac;
+ }
+ if (inc_attr_count(
+ &mtree->set.gid_list, ac, last, me) < 0)
+ return (-1);
+ }
+ }
+ if (keys & F_MODE) {
+ if (mtree->set.mode_list == NULL) {
+ mtree->set.mode_list = new_attr_count(me, NULL);
+ if (mtree->set.mode_list == NULL)
+ return (-1);
+ } else {
+ last = NULL;
+ for (ac = mtree->set.mode_list; ac; ac = ac->next) {
+ if (ac->m_entry->mode == me->mode)
+ break;
+ last = ac;
+ }
+ if (inc_attr_count(
+ &mtree->set.mode_list, ac, last, me) < 0)
+ return (-1);
+ }
+ }
+ if (keys & F_FLAGS) {
+ if (mtree->set.flags_list == NULL) {
+ mtree->set.flags_list = new_attr_count(me, NULL);
+ if (mtree->set.flags_list == NULL)
+ return (-1);
+ } else {
+ last = NULL;
+ for (ac = mtree->set.flags_list; ac; ac = ac->next) {
+ if (ac->m_entry->fflags_set == me->fflags_set &&
+ ac->m_entry->fflags_clear == me->fflags_clear)
+ break;
+ last = ac;
+ }
+ if (inc_attr_count(
+ &mtree->set.flags_list, ac, last, me) < 0)
+ return (-1);
+ }
+ }
+
+ /*
+ * Save a entry.
+ */
+ me->next = NULL;
+ *mtree->set.me_last = me;
+ mtree->set.me_last = &me->next;
+ return (0);
+}
+
+static int
+get_keys(struct mtree_writer *mtree, struct mtree_entry *me)
+{
+ int keys;
+
+ keys = mtree->keys;
+
+ /*
+ * If a keyword has been set by /set, we do not need to
+ * output it.
+ */
+ if (mtree->set.keys == 0)
+ return (keys);/* /set is not used. */
+
+ if ((mtree->set.keys & (F_GNAME | F_GID)) != 0 &&
+ mtree->set.gid == me->gid)
+ keys &= ~(F_GNAME | F_GID);
+ if ((mtree->set.keys & (F_UNAME | F_UID)) != 0 &&
+ mtree->set.uid == me->uid)
+ keys &= ~(F_UNAME | F_UID);
+ if (mtree->set.keys & F_FLAGS) {
+ if (mtree->set.fflags_set == me->fflags_set &&
+ mtree->set.fflags_clear == me->fflags_clear)
+ keys &= ~F_FLAGS;
+ }
+ if ((mtree->set.keys & F_MODE) != 0 && mtree->set.mode == me->mode)
+ keys &= ~F_MODE;
+
+ switch (me->filetype) {
+ case AE_IFLNK: case AE_IFSOCK: case AE_IFCHR:
+ case AE_IFBLK: case AE_IFIFO:
+ break;
+ case AE_IFDIR:
+ if ((mtree->set.keys & F_TYPE) != 0 &&
+ mtree->set.type == AE_IFDIR)
+ keys &= ~F_TYPE;
+ break;
+ case AE_IFREG:
+ default: /* Handle unknown file types as regular files. */
+ if ((mtree->set.keys & F_TYPE) != 0 &&
+ mtree->set.type == AE_IFREG)
+ keys &= ~F_TYPE;
+ break;
+ }
+
+ return (keys);
+}
+
+static struct mtree_entry *
+new_mtree_entry(struct archive_entry *entry)
+{
+ struct mtree_entry *me;
+ const char *s;
+
+ me = calloc(1, sizeof(*me));
+ if (me == NULL)
+ return (NULL);
+ me->pathname = strdup(archive_entry_pathname(entry));
+ if ((s = archive_entry_symlink(entry)) != NULL)
+ me->symlink = strdup(s);
+ else
+ me->symlink = NULL;
+ me->nlink = archive_entry_nlink(entry);
+ me->filetype = archive_entry_filetype(entry);
+ me->mode = archive_entry_mode(entry) & 07777;
+ me->uid = archive_entry_uid(entry);
+ me->gid = archive_entry_gid(entry);
+ if ((s = archive_entry_uname(entry)) != NULL)
+ me->uname = strdup(s);
+ else
+ me->uname = NULL;
+ if ((s = archive_entry_gname(entry)) != NULL)
+ me->gname = strdup(s);
+ else
+ me->gname = NULL;
+ if ((s = archive_entry_fflags_text(entry)) != NULL)
+ me->fflags_text = strdup(s);
+ else
+ me->fflags_text = NULL;
+ 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->rdevminor = archive_entry_rdevminor(entry);
+ me->size = archive_entry_size(entry);
+ me->compute_sum = 0;
+
+ return (me);
+}
+
+static void
+free_mtree_entry(struct mtree_entry *me)
+{
+ free(me->pathname);
+ free(me->symlink);
+ free(me->uname);
+ free(me->gname);
+ free(me->fflags_text);
+ free(me);
+}
+
+static int
+archive_write_mtree_header(struct archive_write *a,
+ struct archive_entry *entry)
+{
+ struct mtree_writer *mtree= a->format_data;
+
+ if (mtree->first) {
+ mtree->first = 0;
+ archive_strcat(&mtree->buf, "#mtree\n");
+ if ((mtree->keys & SET_KEYS) == 0)
+ mtree->set.output = 0;/* Disalbed. */
+ }
+
+ mtree->entry_bytes_remaining = archive_entry_size(entry);
+ if (mtree->dironly && archive_entry_filetype(entry) != AE_IFDIR)
+ return (ARCHIVE_OK);
+
+ mtree->mtree_entry = new_mtree_entry(entry);
+ if (mtree->mtree_entry == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate mtree entry");
+ return (ARCHIVE_FATAL);
+ }
+
+ mtree->compute_sum = 0;
+
+ /* If current file is not a regular file, we do not have to
+ * compute the sum of its content. */
+ if (archive_entry_filetype(entry) != AE_IFREG)
+ return (ARCHIVE_OK);
+
+ /* Initialize a bunch of sum check context. */
+ sum_init(mtree);
+
+ return (ARCHIVE_OK);
+}
+
+static int
+write_entry(struct archive_write *a, struct mtree_entry *me)
+{
+ struct mtree_writer *mtree = a->format_data;
+ struct archive_string *str;
+ int keys, ret;
+
+ archive_string_empty(&mtree->ebuf);
+ str = (mtree->indent)? &mtree->ebuf : &mtree->buf;
+ mtree_quote(str, me->pathname);
+ keys = get_keys(mtree, me);
+ if ((keys & F_NLINK) != 0 &&
+ me->nlink != 1 && me->filetype != AE_IFDIR)
+ archive_string_sprintf(str, " nlink=%u", me->nlink);
+
+ if ((keys & F_GNAME) != 0 && me->gname != NULL) {
+ archive_strcat(str, " gname=");
+ mtree_quote(str, me->gname);
+ }
+ if ((keys & F_UNAME) != 0 && me->uname != NULL) {
+ archive_strcat(str, " uname=");
+ mtree_quote(str, me->uname);
+ }
+ if ((keys & F_FLAGS) != 0) {
+ if (me->fflags_text != NULL) {
+ archive_strcat(str, " flags=");
+ mtree_quote(str, me->fflags_text);
+ } else if (mtree->set.processed &&
+ (mtree->set.keys & F_FLAGS) != 0)
+ /* Overwrite the global parameter. */
+ archive_strcat(str, " flags=none");
+ }
+ if ((keys & F_TIME) != 0)
+ archive_string_sprintf(str, " time=%jd.%jd",
+ (intmax_t)me->mtime, (intmax_t)me->mtime_nsec);
+ if ((keys & F_MODE) != 0)
+ archive_string_sprintf(str, " mode=%o", (unsigned int)me->mode);
+ if ((keys & F_GID) != 0)
+ archive_string_sprintf(str, " gid=%jd", (intmax_t)me->gid);
+ if ((keys & F_UID) != 0)
+ archive_string_sprintf(str, " uid=%jd", (intmax_t)me->uid);
+
+ switch (me->filetype) {
+ case AE_IFLNK:
+ if ((keys & F_TYPE) != 0)
+ archive_strcat(str, " type=link");
+ if ((keys & F_SLINK) != 0) {
+ archive_strcat(str, " link=");
+ mtree_quote(str, me->symlink);
+ }
+ break;
+ case AE_IFSOCK:
+ if ((keys & F_TYPE) != 0)
+ archive_strcat(str, " type=socket");
+ break;
+ case AE_IFCHR:
+ if ((keys & F_TYPE) != 0)
+ archive_strcat(str, " type=char");
+ if ((keys & F_DEV) != 0) {
+ archive_string_sprintf(str,
+ " device=native,%ju,%ju",
+ (uintmax_t)me->rdevmajor,
+ (uintmax_t)me->rdevminor);
+ }
+ break;
+ case AE_IFBLK:
+ if ((keys & F_TYPE) != 0)
+ archive_strcat(str, " type=block");
+ if ((keys & F_DEV) != 0) {
+ archive_string_sprintf(str,
+ " device=native,%ju,%ju",
+ (uintmax_t)me->rdevmajor,
+ (uintmax_t)me->rdevminor);
+ }
+ break;
+ case AE_IFDIR:
+ if ((keys & F_TYPE) != 0)
+ archive_strcat(str, " type=dir");
+ break;
+ case AE_IFIFO:
+ if ((keys & F_TYPE) != 0)
+ archive_strcat(str, " type=fifo");
+ break;
+ case AE_IFREG:
+ default: /* Handle unknown file types as regular files. */
+ if ((keys & F_TYPE) != 0)
+ archive_strcat(str, " type=file");
+ if ((keys & F_SIZE) != 0)
+ archive_string_sprintf(str, " size=%jd",
+ (intmax_t)me->size);
+ break;
+ }
+
+ /* Write a bunch of sum. */
+ if (me->filetype == AE_IFREG)
+ sum_write(str, me);
+
+ archive_strcat(str, "\n");
+ if (mtree->indent)
+ mtree_indent(mtree);
+
+ if (mtree->buf.length > 32768) {
+ ret = __archive_write_output(a, mtree->buf.s, mtree->buf.length);
+ archive_string_empty(&mtree->buf);
+ } else
+ ret = ARCHIVE_OK;
+ return (ret);
+}
+
+/*
+ * Write mtree entries saved at collect_set_values() function.
+ */
+static int
+write_mtree_entries(struct archive_write *a)
+{
+ struct mtree_writer *mtree = a->format_data;
+ struct mtree_entry *me, *tme;
+ int ret;
+
+ for (me = mtree->set.me_first; me; me = me->next) {
+ ret = write_entry(a, me);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
+
+ me = mtree->set.me_first;
+ while (me != NULL) {
+ tme = me->next;
+ free_mtree_entry(me);
+ me = tme;
+ }
+ mtree->set.me_first = NULL;
+ mtree->set.me_last = &mtree->set.me_first;
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_write_mtree_finish_entry(struct archive_write *a)
+{
+ struct mtree_writer *mtree = a->format_data;
+ struct mtree_entry *me;
+ int ret;
+
+ if ((me = mtree->mtree_entry) == NULL)
+ return (ARCHIVE_OK);
+ mtree->mtree_entry = NULL;
+
+ if (me->filetype == AE_IFREG)
+ sum_final(mtree, me);
+
+ if (mtree->set.output) {
+ if (!mtree->dironly) {
+ if (archive_strlen(&mtree->set.parent) == 0)
+ parent_dir_changed(&mtree->set.parent, me);
+ if (parent_dir_changed(&mtree->set.parent, me)) {
+ /* Write /set keyword */
+ write_global(mtree);
+ /* Write entries saved by
+ * collect_set_values() function. */
+ ret = write_mtree_entries(a);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
+ }
+ /* Tabulate uid,gid,mode and fflags of a entry
+ * in order to be used for /set. and, at this time
+ * we do not write a entry. */
+ collect_set_values(mtree, me);
+ return (ARCHIVE_OK);
+ } else {
+ /* Write the current entry and free it. */
+ ret = write_entry(a, me);
+ free_mtree_entry(me);
+ }
+ return (ret == ARCHIVE_OK ? ret : ARCHIVE_FATAL);
+}
+
+static int
+archive_write_mtree_close(struct archive_write *a)
+{
+ struct mtree_writer *mtree= a->format_data;
+ int ret;
+
+ if (mtree->set.output && mtree->set.me_first != NULL) {
+ write_global(mtree);
+ ret = write_mtree_entries(a);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
+
+ archive_write_set_bytes_in_last_block(&a->archive, 1);
+
+ return __archive_write_output(a, mtree->buf.s, mtree->buf.length);
+}
+
+static ssize_t
+archive_write_mtree_data(struct archive_write *a, const void *buff, size_t n)
+{
+ struct mtree_writer *mtree= a->format_data;
+
+ if (n > mtree->entry_bytes_remaining)
+ n = mtree->entry_bytes_remaining;
+ mtree->entry_bytes_remaining -= n;
+
+ /* We don't need to compute a regular file sum */
+ if (mtree->mtree_entry == NULL)
+ return (n);
+
+ if (mtree->mtree_entry->filetype == AE_IFREG)
+ sum_update(mtree, buff, n);
+
+ return (n);
+}
+
+static int
+archive_write_mtree_free(struct archive_write *a)
+{
+ struct mtree_writer *mtree= a->format_data;
+ struct mtree_entry *me, *tme;
+
+ if (mtree == NULL)
+ return (ARCHIVE_OK);
+
+ /* Make sure we dot not leave any entries. */
+ me = mtree->set.me_first;
+ while (me != NULL) {
+ tme = me->next;
+ free_mtree_entry(me);
+ me = tme;
+ }
+ archive_string_free(&mtree->ebuf);
+ archive_string_free(&mtree->buf);
+ archive_string_free(&mtree->set.parent);
+ free_attr_count(&mtree->set.uid_list);
+ free_attr_count(&mtree->set.gid_list);
+ free_attr_count(&mtree->set.mode_list);
+ free_attr_count(&mtree->set.flags_list);
+ free(mtree);
+ a->format_data = NULL;
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_write_mtree_options(struct archive_write *a, const char *key,
+ const char *value)
+{
+ struct mtree_writer *mtree= a->format_data;
+ int keybit = 0;
+
+ switch (key[0]) {
+ case 'a':
+ if (strcmp(key, "all") == 0)
+ keybit = ~0;
+ break;
+ case 'c':
+ if (strcmp(key, "cksum") == 0)
+ keybit = F_CKSUM;
+ break;
+ case 'd':
+ if (strcmp(key, "device") == 0)
+ keybit = F_DEV;
+ else if (strcmp(key, "dironly") == 0) {
+ mtree->dironly = (value != NULL)? 1: 0;
+ return (ARCHIVE_OK);
+ }
+ break;
+ case 'f':
+ if (strcmp(key, "flags") == 0)
+ keybit = F_FLAGS;
+ break;
+ case 'g':
+ if (strcmp(key, "gid") == 0)
+ keybit = F_GID;
+ else if (strcmp(key, "gname") == 0)
+ keybit = F_GNAME;
+ break;
+ case 'i':
+ if (strcmp(key, "indent") == 0) {
+ mtree->indent = (value != NULL)? 1: 0;
+ return (ARCHIVE_OK);
+ }
+ break;
+ case 'l':
+ if (strcmp(key, "link") == 0)
+ keybit = F_SLINK;
+ break;
+ case 'm':
+ if (strcmp(key, "md5") == 0 ||
+ strcmp(key, "md5digest") == 0)
+ keybit = F_MD5;
+ if (strcmp(key, "mode") == 0)
+ keybit = F_MODE;
+ break;
+ case 'n':
+ if (strcmp(key, "nlink") == 0)
+ keybit = F_NLINK;
+ break;
+ case 'r':
+ if (strcmp(key, "ripemd160digest") == 0 ||
+ strcmp(key, "rmd160") == 0 ||
+ strcmp(key, "rmd160digest") == 0)
+ keybit = F_RMD160;
+ break;
+ case 's':
+ if (strcmp(key, "sha1") == 0 ||
+ strcmp(key, "sha1digest") == 0)
+ keybit = F_SHA1;
+ if (strcmp(key, "sha256") == 0 ||
+ strcmp(key, "sha256digest") == 0)
+ keybit = F_SHA256;
+ if (strcmp(key, "sha384") == 0 ||
+ strcmp(key, "sha384digest") == 0)
+ keybit = F_SHA384;
+ if (strcmp(key, "sha512") == 0 ||
+ strcmp(key, "sha512digest") == 0)
+ keybit = F_SHA512;
+ if (strcmp(key, "size") == 0)
+ keybit = F_SIZE;
+ break;
+ case 't':
+ if (strcmp(key, "time") == 0)
+ keybit = F_TIME;
+ else if (strcmp(key, "type") == 0)
+ keybit = F_TYPE;
+ break;
+ case 'u':
+ if (strcmp(key, "uid") == 0)
+ keybit = F_UID;
+ else if (strcmp(key, "uname") == 0)
+ keybit = F_UNAME;
+ else if (strcmp(key, "use-set") == 0) {
+ mtree->set.output = (value != NULL)? 1: 0;
+ return (ARCHIVE_OK);
+ }
+ break;
+ }
+ if (keybit != 0) {
+ if (value != NULL)
+ mtree->keys |= keybit;
+ else
+ mtree->keys &= ~keybit;
+ return (ARCHIVE_OK);
+ }
+
+ return (ARCHIVE_FAILED);
+}
+
+int
+archive_write_set_format_mtree(struct archive *_a)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ struct mtree_writer *mtree;
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_mtree");
+
+ if (a->format_free != NULL)
+ (a->format_free)(a);
+
+ if ((mtree = calloc(1, sizeof(*mtree))) == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate mtree data");
+ return (ARCHIVE_FATAL);
+ }
+
+ mtree->mtree_entry = NULL;
+ mtree->first = 1;
+ memset(&(mtree->set), 0, sizeof(mtree->set));
+ archive_string_init(&mtree->set.parent);
+ mtree->keys = DEFAULT_KEYS;
+ mtree->dironly = 0;
+ mtree->indent = 0;
+ archive_string_init(&mtree->ebuf);
+ archive_string_init(&mtree->buf);
+ mtree->set.me_first = NULL;
+ mtree->set.me_last = &mtree->set.me_first;
+ a->format_data = mtree;
+ a->format_free = archive_write_mtree_free;
+ a->format_name = "mtree";
+ a->format_options = archive_write_mtree_options;
+ a->format_write_header = archive_write_mtree_header;
+ a->format_close = archive_write_mtree_close;
+ a->format_write_data = archive_write_mtree_data;
+ a->format_finish_entry = archive_write_mtree_finish_entry;
+ a->archive.archive_format = ARCHIVE_FORMAT_MTREE;
+ a->archive.archive_format_name = "mtree";
+
+ return (ARCHIVE_OK);
+}
+
+static void
+sum_init(struct mtree_writer *mtree)
+{
+ if (mtree->keys & F_CKSUM) {
+ mtree->compute_sum |= F_CKSUM;
+ mtree->crc = 0;
+ mtree->crc_len = 0;
+ }
+#ifdef ARCHIVE_HAS_MD5
+ if (mtree->keys & F_MD5) {
+ if (archive_md5_init(&mtree->md5ctx) == ARCHIVE_OK)
+ mtree->compute_sum |= F_MD5;
+ else
+ mtree->keys &= ~F_MD5;/* Not supported. */
+ }
+#endif
+#ifdef ARCHIVE_HAS_RMD160
+ if (mtree->keys & F_RMD160) {
+ if (archive_rmd160_init(&mtree->rmd160ctx) == ARCHIVE_OK)
+ mtree->compute_sum |= F_RMD160;
+ else
+ mtree->keys &= ~F_RMD160;/* Not supported. */
+ }
+#endif
+#ifdef ARCHIVE_HAS_SHA1
+ if (mtree->keys & F_SHA1) {
+ if (archive_sha1_init(&mtree->sha1ctx) == ARCHIVE_OK)
+ mtree->compute_sum |= F_SHA1;
+ else
+ mtree->keys &= ~F_SHA1;/* Not supported. */
+ }
+#endif
+#ifdef ARCHIVE_HAS_SHA256
+ if (mtree->keys & F_SHA256) {
+ if (archive_sha256_init(&mtree->sha256ctx) == ARCHIVE_OK)
+ mtree->compute_sum |= F_SHA256;
+ else
+ mtree->keys &= ~F_SHA256;/* Not supported. */
+ }
+#endif
+#ifdef ARCHIVE_HAS_SHA384
+ if (mtree->keys & F_SHA384) {
+ if (archive_sha384_init(&mtree->sha384ctx) == ARCHIVE_OK)
+ mtree->compute_sum |= F_SHA384;
+ else
+ mtree->keys &= ~F_SHA384;/* Not supported. */
+ }
+#endif
+#ifdef ARCHIVE_HAS_SHA512
+ if (mtree->keys & F_SHA512) {
+ if (archive_sha512_init(&mtree->sha512ctx) == ARCHIVE_OK)
+ mtree->compute_sum |= F_SHA512;
+ else
+ mtree->keys &= ~F_SHA512;/* Not supported. */
+ }
+#endif
+}
+
+static void
+sum_update(struct mtree_writer *mtree, const void *buff, size_t n)
+{
+ if (mtree->compute_sum & F_CKSUM) {
+ /*
+ * Compute a POSIX 1003.2 checksum
+ */
+ const unsigned char *p;
+ size_t nn;
+
+ for (nn = n, p = buff; nn--; ++p)
+ COMPUTE_CRC(mtree->crc, *p);
+ mtree->crc_len += n;
+ }
+#ifdef ARCHIVE_HAS_MD5
+ if (mtree->compute_sum & F_MD5)
+ archive_md5_update(&mtree->md5ctx, buff, n);
+#endif
+#ifdef ARCHIVE_HAS_RMD160
+ if (mtree->compute_sum & F_RMD160)
+ archive_rmd160_update(&mtree->rmd160ctx, buff, n);
+#endif
+#ifdef ARCHIVE_HAS_SHA1
+ if (mtree->compute_sum & F_SHA1)
+ archive_sha1_update(&mtree->sha1ctx, buff, n);
+#endif
+#ifdef ARCHIVE_HAS_SHA256
+ if (mtree->compute_sum & F_SHA256)
+ archive_sha256_update(&mtree->sha256ctx, buff, n);
+#endif
+#ifdef ARCHIVE_HAS_SHA384
+ if (mtree->compute_sum & F_SHA384)
+ archive_sha384_update(&mtree->sha384ctx, buff, n);
+#endif
+#ifdef ARCHIVE_HAS_SHA512
+ if (mtree->compute_sum & F_SHA512)
+ archive_sha512_update(&mtree->sha512ctx, buff, n);
+#endif
+}
+
+static void
+sum_final(struct mtree_writer *mtree, struct mtree_entry *me)
+{
+
+ if (mtree->compute_sum & F_CKSUM) {
+ uint64_t len;
+ /* Include the length of the file. */
+ for (len = mtree->crc_len; len != 0; len >>= 8)
+ COMPUTE_CRC(mtree->crc, len & 0xff);
+ me->crc = ~mtree->crc;
+ }
+#ifdef ARCHIVE_HAS_MD5
+ if (mtree->compute_sum & F_MD5)
+ archive_md5_final(&mtree->md5ctx, me->buf_md5);
+#endif
+#ifdef ARCHIVE_HAS_RMD160
+ if (mtree->compute_sum & F_RMD160)
+ archive_rmd160_final(&mtree->rmd160ctx, me->buf_rmd160);
+#endif
+#ifdef ARCHIVE_HAS_SHA1
+ if (mtree->compute_sum & F_SHA1)
+ archive_sha1_final(&mtree->sha1ctx, me->buf_sha1);
+#endif
+#ifdef ARCHIVE_HAS_SHA256
+ if (mtree->compute_sum & F_SHA256)
+ archive_sha256_final(&mtree->sha256ctx, me->buf_sha256);
+#endif
+#ifdef ARCHIVE_HAS_SHA384
+ if (mtree->compute_sum & F_SHA384)
+ archive_sha384_final(&mtree->sha384ctx, me->buf_sha384);
+#endif
+#ifdef ARCHIVE_HAS_SHA512
+ if (mtree->compute_sum & F_SHA512)
+ archive_sha512_final(&mtree->sha512ctx, me->buf_sha512);
+#endif
+ /* Save what types of sum are computed. */
+ me->compute_sum = mtree->compute_sum;
+}
+
+#if defined(ARCHIVE_HAS_MD5) || defined(ARCHIVE_HAS_RMD160) || \
+ defined(ARCHIVE_HAS_SHA1) || defined(ARCHIVE_HAS_SHA256) || \
+ defined(ARCHIVE_HAS_SHA384) || defined(ARCHIVE_HAS_SHA512)
+static void
+strappend_bin(struct archive_string *s, const unsigned char *bin, int n)
+{
+ static const char hex[] = "0123456789abcdef";
+ int i;
+
+ for (i = 0; i < n; i++) {
+ archive_strappend_char(s, hex[bin[i] >> 4]);
+ archive_strappend_char(s, hex[bin[i] & 0x0f]);
+ }
+}
+#endif
+
+static void
+sum_write(struct archive_string *str, struct mtree_entry *me)
+{
+
+ if (me->compute_sum & F_CKSUM) {
+ archive_string_sprintf(str, " cksum=%ju",
+ (uintmax_t)me->crc);
+ }
+#ifdef ARCHIVE_HAS_MD5
+ if (me->compute_sum & F_MD5) {
+ archive_strcat(str, " md5digest=");
+ strappend_bin(str, me->buf_md5, sizeof(me->buf_md5));
+ }
+#endif
+#ifdef ARCHIVE_HAS_RMD160
+ if (me->compute_sum & F_RMD160) {
+ archive_strcat(str, " rmd160digest=");
+ strappend_bin(str, me->buf_rmd160, sizeof(me->buf_rmd160));
+ }
+#endif
+#ifdef ARCHIVE_HAS_SHA1
+ if (me->compute_sum & F_SHA1) {
+ archive_strcat(str, " sha1digest=");
+ strappend_bin(str, me->buf_sha1, sizeof(me->buf_sha1));
+ }
+#endif
+#ifdef ARCHIVE_HAS_SHA256
+ if (me->compute_sum & F_SHA256) {
+ archive_strcat(str, " sha256digest=");
+ strappend_bin(str, me->buf_sha256, sizeof(me->buf_sha256));
+ }
+#endif
+#ifdef ARCHIVE_HAS_SHA384
+ if (me->compute_sum & F_SHA384) {
+ archive_strcat(str, " sha384digest=");
+ strappend_bin(str, me->buf_sha384, sizeof(me->buf_sha384));
+ }
+#endif
+#ifdef ARCHIVE_HAS_SHA512
+ if (me->compute_sum & F_SHA512) {
+ archive_strcat(str, " sha512digest=");
+ strappend_bin(str, me->buf_sha512, sizeof(me->buf_sha512));
+ }
+#endif
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_pax.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_pax.c
new file mode 100644
index 000000000..8affb2c15
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_pax.c
@@ -0,0 +1,1833 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2010-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"
+__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_pax.c 201162 2009-12-29 05:47:46Z kientzle $");
+
+#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_entry_locale.h"
+#include "archive_private.h"
+#include "archive_write_private.h"
+
+struct sparse_block {
+ struct sparse_block *next;
+ int is_hole;
+ uint64_t offset;
+ uint64_t remaining;
+};
+
+struct pax {
+ uint64_t entry_bytes_remaining;
+ uint64_t entry_padding;
+ struct archive_string l_url_encoded_name;
+ struct archive_string pax_header;
+ struct archive_string sparse_map;
+ size_t sparse_map_padding;
+ struct sparse_block *sparse_list;
+ struct sparse_block *sparse_tail;
+ struct archive_string_conv *sconv_utf8;
+ int opt_binary;
+};
+
+static void add_pax_attr(struct archive_string *, const char *key,
+ const char *value);
+static void add_pax_attr_int(struct archive_string *,
+ const char *key, int64_t value);
+static void add_pax_attr_time(struct archive_string *,
+ const char *key, int64_t sec,
+ unsigned long nanos);
+static ssize_t archive_write_pax_data(struct archive_write *,
+ const void *, size_t);
+static int archive_write_pax_close(struct archive_write *);
+static int archive_write_pax_free(struct archive_write *);
+static int archive_write_pax_finish_entry(struct archive_write *);
+static int archive_write_pax_header(struct archive_write *,
+ struct archive_entry *);
+static int archive_write_pax_options(struct archive_write *,
+ const char *, const char *);
+static char *base64_encode(const char *src, size_t len);
+static char *build_gnu_sparse_name(char *dest, const char *src);
+static char *build_pax_attribute_name(char *dest, const char *src);
+static char *build_ustar_entry_name(char *dest, const char *src,
+ size_t src_length, const char *insert);
+static char *format_int(char *dest, int64_t);
+static int has_non_ASCII(const char *);
+static void sparse_list_clear(struct pax *);
+static int sparse_list_add(struct pax *, int64_t, int64_t);
+static char *url_encode(const char *in);
+
+/*
+ * Set output format to 'restricted pax' format.
+ *
+ * This is the same as normal 'pax', but tries to suppress
+ * the pax header whenever possible. This is the default for
+ * bsdtar, for instance.
+ */
+int
+archive_write_set_format_pax_restricted(struct archive *_a)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ int r;
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_pax_restricted");
+
+ r = archive_write_set_format_pax(&a->archive);
+ a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_RESTRICTED;
+ a->archive.archive_format_name = "restricted POSIX pax interchange";
+ return (r);
+}
+
+/*
+ * Set output format to 'pax' format.
+ */
+int
+archive_write_set_format_pax(struct archive *_a)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ struct pax *pax;
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_pax");
+
+ if (a->format_free != NULL)
+ (a->format_free)(a);
+
+ pax = (struct pax *)malloc(sizeof(*pax));
+ if (pax == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate pax data");
+ return (ARCHIVE_FATAL);
+ }
+ memset(pax, 0, sizeof(*pax));
+ a->format_data = pax;
+ a->format_name = "pax";
+ a->format_options = archive_write_pax_options;
+ a->format_write_header = archive_write_pax_header;
+ a->format_write_data = archive_write_pax_data;
+ a->format_close = archive_write_pax_close;
+ a->format_free = archive_write_pax_free;
+ a->format_finish_entry = archive_write_pax_finish_entry;
+ a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE;
+ a->archive.archive_format_name = "POSIX pax interchange";
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_write_pax_options(struct archive_write *a, const char *key,
+ const char *val)
+{
+ struct pax *pax = (struct pax *)a->format_data;
+ int ret = ARCHIVE_FAILED;
+
+ if (strcmp(key, "hdrcharset") == 0) {
+ /*
+ * The character-set we can use are defined in
+ * IEEE Std 1003.1-2001
+ */
+ if (val == NULL || val[0] == 0)
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "pax: hdrcharset option needs a character-set name");
+ else if (strcmp(val, "BINARY") == 0 ||
+ strcmp(val, "binary") == 0) {
+ /*
+ * Specify binary mode. We will not convert
+ * filenames, uname and gname to any charsets.
+ */
+ pax->opt_binary = 1;
+ ret = ARCHIVE_OK;
+ } else if (strcmp(val, "UTF-8") == 0) {
+ /*
+ * Specify UTF-8 character-set to be used for
+ * filenames. This is almost the test that
+ * running platform supports the string conversion.
+ * Especially libarchive_test needs this trick for
+ * its test.
+ */
+ pax->sconv_utf8 = archive_string_conversion_to_charset(
+ &(a->archive), "UTF-8", 0);
+ if (pax->sconv_utf8 == NULL)
+ ret = ARCHIVE_FATAL;
+ else
+ ret = ARCHIVE_OK;
+ } else
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "pax: invalid charset name");
+ } else
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "pax: unknown keyword ``%s''", key);
+
+ return (ret);
+}
+
+/*
+ * Note: This code assumes that 'nanos' has the same sign as 'sec',
+ * which implies that sec=-1, nanos=200000000 represents -1.2 seconds
+ * and not -0.8 seconds. This is a pretty pedantic point, as we're
+ * unlikely to encounter many real files created before Jan 1, 1970,
+ * much less ones with timestamps recorded to sub-second resolution.
+ */
+static void
+add_pax_attr_time(struct archive_string *as, const char *key,
+ int64_t sec, unsigned long nanos)
+{
+ int digit, i;
+ char *t;
+ /*
+ * Note that each byte contributes fewer than 3 base-10
+ * digits, so this will always be big enough.
+ */
+ char tmp[1 + 3*sizeof(sec) + 1 + 3*sizeof(nanos)];
+
+ tmp[sizeof(tmp) - 1] = 0;
+ t = tmp + sizeof(tmp) - 1;
+
+ /* Skip trailing zeros in the fractional part. */
+ for (digit = 0, i = 10; i > 0 && digit == 0; i--) {
+ digit = nanos % 10;
+ nanos /= 10;
+ }
+
+ /* Only format the fraction if it's non-zero. */
+ if (i > 0) {
+ while (i > 0) {
+ *--t = "0123456789"[digit];
+ digit = nanos % 10;
+ nanos /= 10;
+ i--;
+ }
+ *--t = '.';
+ }
+ t = format_int(t, sec);
+
+ add_pax_attr(as, key, t);
+}
+
+static char *
+format_int(char *t, int64_t i)
+{
+ uint64_t ui;
+
+ if (i < 0)
+ ui = (i == INT64_MIN) ? (uint64_t)(INT64_MAX) + 1 : (uint64_t)(-i);
+ else
+ ui = i;
+
+ do {
+ *--t = "0123456789"[ui % 10];
+ } while (ui /= 10);
+ if (i < 0)
+ *--t = '-';
+ return (t);
+}
+
+static void
+add_pax_attr_int(struct archive_string *as, const char *key, int64_t value)
+{
+ char tmp[1 + 3 * sizeof(value)];
+
+ tmp[sizeof(tmp) - 1] = 0;
+ add_pax_attr(as, key, format_int(tmp + sizeof(tmp) - 1, value));
+}
+
+/*
+ * Add a key/value attribute to the pax header. This function handles
+ * the length field and various other syntactic requirements.
+ */
+static void
+add_pax_attr(struct archive_string *as, const char *key, const char *value)
+{
+ int digits, i, len, next_ten;
+ char tmp[1 + 3 * sizeof(int)]; /* < 3 base-10 digits per byte */
+
+ /*-
+ * PAX attributes have the following layout:
+ * <len> <space> <key> <=> <value> <nl>
+ */
+ len = 1 + (int)strlen(key) + 1 + (int)strlen(value) + 1;
+
+ /*
+ * The <len> field includes the length of the <len> field, so
+ * computing the correct length is tricky. I start by
+ * counting the number of base-10 digits in 'len' and
+ * computing the next higher power of 10.
+ */
+ next_ten = 1;
+ digits = 0;
+ i = len;
+ while (i > 0) {
+ i = i / 10;
+ digits++;
+ next_ten = next_ten * 10;
+ }
+ /*
+ * For example, if string without the length field is 99
+ * chars, then adding the 2 digit length "99" will force the
+ * total length past 100, requiring an extra digit. The next
+ * statement adjusts for this effect.
+ */
+ if (len + digits >= next_ten)
+ digits++;
+
+ /* Now, we have the right length so we can build the line. */
+ tmp[sizeof(tmp) - 1] = 0; /* Null-terminate the work area. */
+ archive_strcat(as, format_int(tmp + sizeof(tmp) - 1, len + digits));
+ archive_strappend_char(as, ' ');
+ archive_strcat(as, key);
+ archive_strappend_char(as, '=');
+ archive_strcat(as, value);
+ archive_strappend_char(as, '\n');
+}
+
+static int
+archive_write_pax_header_xattrs(struct archive_write *a,
+ struct pax *pax, struct archive_entry *entry)
+{
+ struct archive_string s;
+ int i = archive_entry_xattr_reset(entry);
+
+ while (i--) {
+ const char *name;
+ const void *value;
+ char *encoded_value;
+ char *url_encoded_name = NULL, *encoded_name = NULL;
+ size_t size;
+ int r;
+
+ archive_entry_xattr_next(entry, &name, &value, &size);
+ url_encoded_name = url_encode(name);
+ if (url_encoded_name != NULL) {
+ /* Convert narrow-character to UTF-8. */
+ r = archive_strcpy_in_locale(
+ &(pax->l_url_encoded_name),
+ url_encoded_name, pax->sconv_utf8);
+ free(url_encoded_name); /* Done with this. */
+ if (r == 0)
+ encoded_name = pax->l_url_encoded_name.s;
+ else if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Linkname");
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ encoded_value = base64_encode((const char *)value, size);
+
+ if (encoded_name != NULL && encoded_value != NULL) {
+ archive_string_init(&s);
+ archive_strcpy(&s, "LIBARCHIVE.xattr.");
+ archive_strcat(&s, encoded_name);
+ add_pax_attr(&(pax->pax_header), s.s, encoded_value);
+ archive_string_free(&s);
+ }
+ free(encoded_value);
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+get_entry_hardlink(struct archive_write *a, struct archive_entry *entry,
+ const char **name, size_t *length, struct archive_string_conv *sc)
+{
+ int r;
+
+ r = archive_entry_hardlink_l(entry, name, length, sc);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Linkname");
+ return (ARCHIVE_FATAL);
+ }
+ return (ARCHIVE_WARN);
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+get_entry_pathname(struct archive_write *a, struct archive_entry *entry,
+ const char **name, size_t *length, struct archive_string_conv *sc)
+{
+ int r;
+
+ r = archive_entry_pathname_l(entry, name, length, sc);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Pathname");
+ return (ARCHIVE_FATAL);
+ }
+ return (ARCHIVE_WARN);
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+get_entry_uname(struct archive_write *a, struct archive_entry *entry,
+ const char **name, size_t *length, struct archive_string_conv *sc)
+{
+ int r;
+
+ r = archive_entry_uname_l(entry, name, length, sc);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Uname");
+ return (ARCHIVE_FATAL);
+ }
+ return (ARCHIVE_WARN);
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+get_entry_gname(struct archive_write *a, struct archive_entry *entry,
+ const char **name, size_t *length, struct archive_string_conv *sc)
+{
+ int r;
+
+ r = archive_entry_gname_l(entry, name, length, sc);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Gname");
+ return (ARCHIVE_FATAL);
+ }
+ return (ARCHIVE_WARN);
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+get_entry_symlink(struct archive_write *a, struct archive_entry *entry,
+ const char **name, size_t *length, struct archive_string_conv *sc)
+{
+ int r;
+
+ r = archive_entry_symlink_l(entry, name, length, sc);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Linkname");
+ return (ARCHIVE_FATAL);
+ }
+ return (ARCHIVE_WARN);
+ }
+ return (ARCHIVE_OK);
+}
+
+/*
+ * TODO: Consider adding 'comment' and 'charset' fields to
+ * archive_entry so that clients can specify them. Also, consider
+ * adding generic key/value tags so clients can add arbitrary
+ * key/value data.
+ *
+ * TODO: Break up this 700-line function!!!! Yowza!
+ */
+static int
+archive_write_pax_header(struct archive_write *a,
+ struct archive_entry *entry_original)
+{
+ struct archive_entry *entry_main;
+ const char *p;
+ char *t;
+ const char *suffix;
+ int need_extension, r, ret;
+ int sparse_count;
+ uint64_t sparse_total, real_size;
+ struct pax *pax;
+ const char *hardlink;
+ const char *path = NULL, *linkpath = NULL;
+ const char *uname = NULL, *gname = NULL;
+ const void *mac_metadata;
+ size_t mac_metadata_size;
+ struct archive_string_conv *sconv;
+ size_t hardlink_length, path_length, linkpath_length;
+ size_t uname_length, gname_length;
+
+ char paxbuff[512];
+ char ustarbuff[512];
+ char ustar_entry_name[256];
+ char pax_entry_name[256];
+ char gnu_sparse_name[256];
+ struct archive_string entry_name;
+
+ ret = ARCHIVE_OK;
+ need_extension = 0;
+ pax = (struct pax *)a->format_data;
+
+ /* Sanity check. */
+ if (archive_entry_pathname(entry_original) == NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Can't record entry in tar file without pathname");
+ return (ARCHIVE_FAILED);
+ }
+
+ /*
+ * Choose a header encoding.
+ */
+ if (pax->opt_binary)
+ sconv = NULL;/* Binary mode. */
+ else {
+ /* Header encoding is UTF-8. */
+ if (pax->sconv_utf8 == NULL) {
+ /* Initialize the string conversion object
+ * we must need */
+ pax->sconv_utf8 = archive_string_conversion_to_charset(
+ &(a->archive), "UTF-8", 1);
+ if (pax->sconv_utf8 == NULL)
+ /* Couldn't allocate memory */
+ return (ARCHIVE_FAILED);
+ }
+ sconv = pax->sconv_utf8;
+ }
+
+ r = get_entry_hardlink(a, entry_original, &hardlink,
+ &hardlink_length, sconv);
+ if (r == ARCHIVE_FATAL)
+ return (r);
+ else if (r != ARCHIVE_OK) {
+ r = get_entry_hardlink(a, entry_original, &hardlink,
+ &hardlink_length, NULL);
+ if (r == ARCHIVE_FATAL)
+ return (r);
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate linkname '%s' to %s", hardlink,
+ archive_string_conversion_charset_name(sconv));
+ ret = ARCHIVE_WARN;
+ sconv = NULL;/* The header charset switches to binary mode. */
+ }
+
+ /* Make sure this is a type of entry that we can handle here */
+ if (hardlink == NULL) {
+ switch (archive_entry_filetype(entry_original)) {
+ case AE_IFBLK:
+ case AE_IFCHR:
+ case AE_IFIFO:
+ case AE_IFLNK:
+ case AE_IFREG:
+ break;
+ case AE_IFDIR:
+ /*
+ * Ensure a trailing '/'. Modify the original
+ * entry so the client sees the change.
+ */
+ p = archive_entry_pathname(entry_original);
+ if (p[strlen(p) - 1] != '/') {
+ t = (char *)malloc(strlen(p) + 2);
+ if (t == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate pax data");
+ return(ARCHIVE_FATAL);
+ }
+ strcpy(t, p);
+ strcat(t, "/");
+ archive_entry_copy_pathname(entry_original, t);
+ free(t);
+ }
+ break;
+ case AE_IFSOCK:
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "tar format cannot archive socket");
+ return (ARCHIVE_FAILED);
+ default:
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "tar format cannot archive this (type=0%lo)",
+ (unsigned long)
+ archive_entry_filetype(entry_original));
+ return (ARCHIVE_FAILED);
+ }
+ }
+
+ /*
+ * If Mac OS metadata blob is here, recurse to write that
+ * as a separate entry. This is realy a pretty poor design:
+ * In particular, it doubles the overhead for long filenames.
+ * TODO: Help Apple folks design something better and figure
+ * out how to transition from this legacy format.
+ *
+ * Note that this code is present on every platform; clients
+ * on non-Mac are unlikely to ever provide this data, but
+ * applications that copy entries from one archive to another
+ * should not lose data just because the local filesystem
+ * can't store it.
+ */
+ mac_metadata =
+ archive_entry_mac_metadata(entry_original, &mac_metadata_size);
+ if (mac_metadata != NULL) {
+ const char *oname;
+ char *name, *bname;
+ size_t name_length;
+ struct archive_entry *extra = archive_entry_new2(&a->archive);
+
+ oname = archive_entry_pathname(entry_original);
+ name_length = strlen(oname);
+ name = malloc(name_length + 3);
+ if (name == NULL) {
+ /* XXX error message */
+ return (ARCHIVE_FAILED);
+ }
+ strcpy(name, oname);
+ /* Find last '/'; strip trailing '/' characters */
+ bname = strrchr(name, '/');
+ while (bname != NULL && bname[1] == '\0') {
+ *bname = '\0';
+ bname = strrchr(name, '/');
+ }
+ if (bname == NULL) {
+ memmove(name + 2, name, name_length + 1);
+ memmove(name, "._", 2);
+ } else {
+ bname += 1;
+ memmove(bname + 2, bname, strlen(bname) + 1);
+ memmove(bname, "._", 2);
+ }
+ archive_entry_copy_pathname(extra, name);
+ free(name);
+
+ archive_entry_set_size(extra, mac_metadata_size);
+ archive_entry_set_filetype(extra, AE_IFREG);
+ archive_entry_set_perm(extra,
+ archive_entry_perm(entry_original));
+ archive_entry_set_mtime(extra,
+ archive_entry_mtime(entry_original),
+ archive_entry_mtime_nsec(entry_original));
+ archive_entry_set_gid(extra,
+ archive_entry_gid(entry_original));
+ archive_entry_set_gname(extra,
+ archive_entry_gname(entry_original));
+ archive_entry_set_uid(extra,
+ archive_entry_uid(entry_original));
+ archive_entry_set_uname(extra,
+ archive_entry_uname(entry_original));
+
+ /* Recurse to write the special copyfile entry. */
+ r = archive_write_pax_header(a, extra);
+ if (r < ARCHIVE_WARN)
+ return (r);
+ if (r < ret)
+ ret = r;
+ r = archive_write_pax_data(a, mac_metadata, mac_metadata_size);
+ if (r < ARCHIVE_WARN)
+ return (r);
+ if (r < ret)
+ ret = r;
+ r = archive_write_pax_finish_entry(a);
+ if (r < ARCHIVE_WARN)
+ return (r);
+ if (r < ret)
+ ret = r;
+ }
+
+ /* Copy entry so we can modify it as needed. */
+ entry_main = archive_entry_clone(entry_original);
+ archive_string_empty(&(pax->pax_header)); /* Blank our work area. */
+ archive_string_empty(&(pax->sparse_map));
+ sparse_total = 0;
+ sparse_list_clear(pax);
+
+ if (hardlink == NULL &&
+ archive_entry_filetype(entry_main) == AE_IFREG)
+ sparse_count = archive_entry_sparse_reset(entry_main);
+ else
+ sparse_count = 0;
+ if (sparse_count) {
+ int64_t offset, length, last_offset = 0;
+ /* Get the last entry of sparse block. */
+ while (archive_entry_sparse_next(
+ entry_main, &offset, &length) == ARCHIVE_OK)
+ last_offset = offset + length;
+
+ /* If the last sparse block does not reach the end of file,
+ * We have to add a empty sparse block as the last entry to
+ * manage storing file data. */
+ if (last_offset < archive_entry_size(entry_main))
+ archive_entry_sparse_add_entry(entry_main,
+ archive_entry_size(entry_main), 0);
+ sparse_count = archive_entry_sparse_reset(entry_main);
+ }
+
+ /*
+ * First, check the name fields and see if any of them
+ * require binary coding. If any of them does, then all of
+ * them do.
+ */
+ r = get_entry_pathname(a, entry_main, &path, &path_length, sconv);
+ if (r == ARCHIVE_FATAL)
+ return (r);
+ else if (r != ARCHIVE_OK) {
+ r = get_entry_pathname(a, entry_main, &path,
+ &path_length, NULL);
+ if (r == ARCHIVE_FATAL)
+ return (r);
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate pathname '%s' to %s", path,
+ archive_string_conversion_charset_name(sconv));
+ ret = ARCHIVE_WARN;
+ sconv = NULL;/* The header charset switches to binary mode. */
+ }
+ r = get_entry_uname(a, entry_main, &uname, &uname_length, sconv);
+ if (r == ARCHIVE_FATAL)
+ return (r);
+ else if (r != ARCHIVE_OK) {
+ r = get_entry_uname(a, entry_main, &uname, &uname_length, NULL);
+ if (r == ARCHIVE_FATAL)
+ return (r);
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate uname '%s' to %s", uname,
+ archive_string_conversion_charset_name(sconv));
+ ret = ARCHIVE_WARN;
+ sconv = NULL;/* The header charset switches to binary mode. */
+ }
+ r = get_entry_gname(a, entry_main, &gname, &gname_length, sconv);
+ if (r == ARCHIVE_FATAL)
+ return (r);
+ else if (r != ARCHIVE_OK) {
+ r = get_entry_gname(a, entry_main, &gname, &gname_length, NULL);
+ if (r == ARCHIVE_FATAL)
+ return (r);
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate gname '%s' to %s", gname,
+ archive_string_conversion_charset_name(sconv));
+ ret = ARCHIVE_WARN;
+ sconv = NULL;/* The header charset switches to binary mode. */
+ }
+ linkpath = hardlink;
+ linkpath_length = hardlink_length;
+ if (linkpath == NULL) {
+ r = get_entry_symlink(a, entry_main, &linkpath,
+ &linkpath_length, sconv);
+ if (r == ARCHIVE_FATAL)
+ return (r);
+ else if (r != ARCHIVE_OK) {
+ r = get_entry_symlink(a, entry_main, &linkpath,
+ &linkpath_length, NULL);
+ if (r == ARCHIVE_FATAL)
+ return (r);
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate linkname '%s' to %s", linkpath,
+ archive_string_conversion_charset_name(sconv));
+ ret = ARCHIVE_WARN;
+ sconv = NULL;
+ }
+ }
+
+ /* If any string conversions failed, get all attributes
+ * in binary-mode. */
+ if (sconv == NULL && !pax->opt_binary) {
+ if (hardlink != NULL) {
+ r = get_entry_hardlink(a, entry_main, &hardlink,
+ &hardlink_length, NULL);
+ if (r == ARCHIVE_FATAL)
+ return (r);
+ linkpath = hardlink;
+ linkpath_length = hardlink_length;
+ }
+ r = get_entry_pathname(a, entry_main, &path,
+ &path_length, NULL);
+ if (r == ARCHIVE_FATAL)
+ return (r);
+ r = get_entry_uname(a, entry_main, &uname, &uname_length, NULL);
+ if (r == ARCHIVE_FATAL)
+ return (r);
+ r = get_entry_gname(a, entry_main, &gname, &gname_length, NULL);
+ if (r == ARCHIVE_FATAL)
+ return (r);
+ }
+
+ /* Store the header encoding first, to be nice to readers. */
+ if (sconv == NULL)
+ add_pax_attr(&(pax->pax_header), "hdrcharset", "BINARY");
+
+
+ /*
+ * If name is too long, or has non-ASCII characters, add
+ * 'path' to pax extended attrs. (Note that an unconvertible
+ * name must have non-ASCII characters.)
+ */
+ if (has_non_ASCII(path)) {
+ /* We have non-ASCII characters. */
+ add_pax_attr(&(pax->pax_header), "path", path);
+ archive_entry_set_pathname(entry_main,
+ build_ustar_entry_name(ustar_entry_name,
+ path, path_length, NULL));
+ need_extension = 1;
+ } else {
+ /* We have an all-ASCII path; we'd like to just store
+ * it in the ustar header if it will fit. Yes, this
+ * duplicates some of the logic in
+ * archive_write_set_format_ustar.c
+ */
+ if (path_length <= 100) {
+ /* Fits in the old 100-char tar name field. */
+ } else {
+ /* Find largest suffix that will fit. */
+ /* Note: strlen() > 100, so strlen() - 100 - 1 >= 0 */
+ suffix = strchr(path + path_length - 100 - 1, '/');
+ /* Don't attempt an empty prefix. */
+ if (suffix == path)
+ suffix = strchr(suffix + 1, '/');
+ /* We can put it in the ustar header if it's
+ * all ASCII and it's either <= 100 characters
+ * or can be split at a '/' into a prefix <=
+ * 155 chars and a suffix <= 100 chars. (Note
+ * the strchr() above will return NULL exactly
+ * when the path can't be split.)
+ */
+ if (suffix == NULL /* Suffix > 100 chars. */
+ || suffix[1] == '\0' /* empty suffix */
+ || suffix - path > 155) /* Prefix > 155 chars */
+ {
+ add_pax_attr(&(pax->pax_header), "path", path);
+ archive_entry_set_pathname(entry_main,
+ build_ustar_entry_name(ustar_entry_name,
+ path, path_length, NULL));
+ need_extension = 1;
+ }
+ }
+ }
+
+ if (linkpath != NULL) {
+ /* If link name is too long or has non-ASCII characters, add
+ * 'linkpath' to pax extended attrs. */
+ if (linkpath_length > 100 || has_non_ASCII(linkpath)) {
+ add_pax_attr(&(pax->pax_header), "linkpath", linkpath);
+ if (linkpath_length > 100) {
+ if (hardlink != NULL)
+ archive_entry_set_hardlink(entry_main,
+ "././@LongHardLink");
+ else
+ archive_entry_set_symlink(entry_main,
+ "././@LongSymLink");
+ }
+ need_extension = 1;
+ }
+ }
+ /* Save a pathname since it will be renamed if `entry_main` has
+ * sparse blocks. */
+ archive_string_init(&entry_name);
+ archive_strcpy(&entry_name, archive_entry_pathname(entry_main));
+
+ /* If file size is too large, add 'size' to pax extended attrs. */
+ if (archive_entry_size(entry_main) >= (((int64_t)1) << 33)) {
+ add_pax_attr_int(&(pax->pax_header), "size",
+ archive_entry_size(entry_main));
+ need_extension = 1;
+ }
+
+ /* If numeric GID is too large, add 'gid' to pax extended attrs. */
+ if ((unsigned int)archive_entry_gid(entry_main) >= (1 << 18)) {
+ add_pax_attr_int(&(pax->pax_header), "gid",
+ archive_entry_gid(entry_main));
+ need_extension = 1;
+ }
+
+ /* If group name is too large or has non-ASCII characters, add
+ * 'gname' to pax extended attrs. */
+ if (gname != NULL) {
+ if (gname_length > 31 || has_non_ASCII(gname)) {
+ add_pax_attr(&(pax->pax_header), "gname", gname);
+ need_extension = 1;
+ }
+ }
+
+ /* If numeric UID is too large, add 'uid' to pax extended attrs. */
+ if ((unsigned int)archive_entry_uid(entry_main) >= (1 << 18)) {
+ add_pax_attr_int(&(pax->pax_header), "uid",
+ archive_entry_uid(entry_main));
+ need_extension = 1;
+ }
+
+ /* Add 'uname' to pax extended attrs if necessary. */
+ if (uname != NULL) {
+ if (uname_length > 31 || has_non_ASCII(uname)) {
+ add_pax_attr(&(pax->pax_header), "uname", uname);
+ need_extension = 1;
+ }
+ }
+
+ /*
+ * POSIX/SUSv3 doesn't provide a standard key for large device
+ * numbers. I use the same keys here that Joerg Schilling
+ * used for 'star.' (Which, somewhat confusingly, are called
+ * "devXXX" even though they code "rdev" values.) No doubt,
+ * other implementations use other keys. Note that there's no
+ * reason we can't write the same information into a number of
+ * different keys.
+ *
+ * Of course, this is only needed for block or char device entries.
+ */
+ if (archive_entry_filetype(entry_main) == AE_IFBLK
+ || archive_entry_filetype(entry_main) == AE_IFCHR) {
+ /*
+ * If rdevmajor is too large, add 'SCHILY.devmajor' to
+ * extended attributes.
+ */
+ int rdevmajor, rdevminor;
+ rdevmajor = archive_entry_rdevmajor(entry_main);
+ rdevminor = archive_entry_rdevminor(entry_main);
+ if (rdevmajor >= (1 << 18)) {
+ add_pax_attr_int(&(pax->pax_header), "SCHILY.devmajor",
+ rdevmajor);
+ /*
+ * Non-strict formatting below means we don't
+ * have to truncate here. Not truncating improves
+ * the chance that some more modern tar archivers
+ * (such as GNU tar 1.13) can restore the full
+ * value even if they don't understand the pax
+ * extended attributes. See my rant below about
+ * file size fields for additional details.
+ */
+ /* archive_entry_set_rdevmajor(entry_main,
+ rdevmajor & ((1 << 18) - 1)); */
+ need_extension = 1;
+ }
+
+ /*
+ * If devminor is too large, add 'SCHILY.devminor' to
+ * extended attributes.
+ */
+ if (rdevminor >= (1 << 18)) {
+ add_pax_attr_int(&(pax->pax_header), "SCHILY.devminor",
+ rdevminor);
+ /* Truncation is not necessary here, either. */
+ /* archive_entry_set_rdevminor(entry_main,
+ rdevminor & ((1 << 18) - 1)); */
+ need_extension = 1;
+ }
+ }
+
+ /*
+ * Technically, the mtime field in the ustar header can
+ * support 33 bits, but many platforms use signed 32-bit time
+ * values. The cutoff of 0x7fffffff here is a compromise.
+ * Yes, this check is duplicated just below; this helps to
+ * avoid writing an mtime attribute just to handle a
+ * high-resolution timestamp in "restricted pax" mode.
+ */
+ if (!need_extension &&
+ ((archive_entry_mtime(entry_main) < 0)
+ || (archive_entry_mtime(entry_main) >= 0x7fffffff)))
+ need_extension = 1;
+
+ /* I use a star-compatible file flag attribute. */
+ p = archive_entry_fflags_text(entry_main);
+ if (!need_extension && p != NULL && *p != '\0')
+ need_extension = 1;
+
+ /* If there are non-trivial ACL entries, we need an extension. */
+ if (!need_extension && archive_entry_acl_count(entry_original,
+ ARCHIVE_ENTRY_ACL_TYPE_ACCESS) > 0)
+ need_extension = 1;
+
+ /* If there are non-trivial ACL entries, we need an extension. */
+ if (!need_extension && archive_entry_acl_count(entry_original,
+ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) > 0)
+ need_extension = 1;
+
+ /* If there are extended attributes, we need an extension */
+ if (!need_extension && archive_entry_xattr_count(entry_original) > 0)
+ need_extension = 1;
+
+ /* If there are sparse info, we need an extension */
+ if (!need_extension && sparse_count > 0)
+ need_extension = 1;
+
+ /*
+ * The following items are handled differently in "pax
+ * restricted" format. In particular, in "pax restricted"
+ * format they won't be added unless need_extension is
+ * already set (we're already generating an extended header, so
+ * may as well include these).
+ */
+ if (a->archive.archive_format != ARCHIVE_FORMAT_TAR_PAX_RESTRICTED ||
+ need_extension) {
+
+ if (archive_entry_mtime(entry_main) < 0 ||
+ archive_entry_mtime(entry_main) >= 0x7fffffff ||
+ archive_entry_mtime_nsec(entry_main) != 0)
+ add_pax_attr_time(&(pax->pax_header), "mtime",
+ archive_entry_mtime(entry_main),
+ archive_entry_mtime_nsec(entry_main));
+
+ if (archive_entry_ctime(entry_main) != 0 ||
+ archive_entry_ctime_nsec(entry_main) != 0)
+ add_pax_attr_time(&(pax->pax_header), "ctime",
+ archive_entry_ctime(entry_main),
+ archive_entry_ctime_nsec(entry_main));
+
+ if (archive_entry_atime(entry_main) != 0 ||
+ archive_entry_atime_nsec(entry_main) != 0)
+ add_pax_attr_time(&(pax->pax_header), "atime",
+ archive_entry_atime(entry_main),
+ archive_entry_atime_nsec(entry_main));
+
+ /* Store birth/creationtime only if it's earlier than mtime */
+ if (archive_entry_birthtime_is_set(entry_main) &&
+ archive_entry_birthtime(entry_main)
+ < archive_entry_mtime(entry_main))
+ add_pax_attr_time(&(pax->pax_header),
+ "LIBARCHIVE.creationtime",
+ archive_entry_birthtime(entry_main),
+ archive_entry_birthtime_nsec(entry_main));
+
+ /* I use a star-compatible file flag attribute. */
+ p = archive_entry_fflags_text(entry_main);
+ if (p != NULL && *p != '\0')
+ add_pax_attr(&(pax->pax_header), "SCHILY.fflags", p);
+
+ /* I use star-compatible ACL attributes. */
+ r = archive_entry_acl_text_l(entry_original,
+ ARCHIVE_ENTRY_ACL_TYPE_ACCESS |
+ ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID,
+ &p, NULL, pax->sconv_utf8);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for "
+ "ACL.access");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate ACL.access to UTF-8");
+ ret = ARCHIVE_WARN;
+ } else if (p != NULL && *p != '\0') {
+ add_pax_attr(&(pax->pax_header),
+ "SCHILY.acl.access", p);
+ }
+ r = archive_entry_acl_text_l(entry_original,
+ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT |
+ ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID,
+ &p, NULL, pax->sconv_utf8);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for "
+ "ACL.default");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate ACL.default to UTF-8");
+ ret = ARCHIVE_WARN;
+ } else if (p != NULL && *p != '\0') {
+ add_pax_attr(&(pax->pax_header),
+ "SCHILY.acl.default", p);
+ }
+
+ /* We use GNU-tar-compatible sparse attributes. */
+ if (sparse_count > 0) {
+ int64_t soffset, slength;
+
+ add_pax_attr_int(&(pax->pax_header),
+ "GNU.sparse.major", 1);
+ add_pax_attr_int(&(pax->pax_header),
+ "GNU.sparse.minor", 0);
+ add_pax_attr(&(pax->pax_header),
+ "GNU.sparse.name", entry_name.s);
+ add_pax_attr_int(&(pax->pax_header),
+ "GNU.sparse.realsize",
+ archive_entry_size(entry_main));
+
+ /* Rename the file name which will be used for
+ * ustar header to a special name, which GNU
+ * PAX Format 1.0 requires */
+ archive_entry_set_pathname(entry_main,
+ build_gnu_sparse_name(gnu_sparse_name,
+ entry_name.s));
+
+ /*
+ * - Make a sparse map, which will precede a file data.
+ * - Get the total size of available data of sparse.
+ */
+ archive_string_sprintf(&(pax->sparse_map), "%d\n",
+ sparse_count);
+ while (archive_entry_sparse_next(entry_main,
+ &soffset, &slength) == ARCHIVE_OK) {
+ archive_string_sprintf(&(pax->sparse_map),
+ "%jd\n%jd\n",
+ (intmax_t)soffset,
+ (intmax_t)slength);
+ sparse_total += slength;
+ if (sparse_list_add(pax, soffset, slength)
+ != ARCHIVE_OK) {
+ archive_set_error(&a->archive,
+ ENOMEM,
+ "Can't allocate memory");
+ archive_entry_free(entry_main);
+ archive_string_free(&entry_name);
+ return (ARCHIVE_FATAL);
+ }
+ }
+ }
+
+ /* Store extended attributes */
+ if (archive_write_pax_header_xattrs(a, pax, entry_original)
+ == ARCHIVE_FATAL) {
+ archive_entry_free(entry_main);
+ archive_string_free(&entry_name);
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ /* Only regular files have data. */
+ if (archive_entry_filetype(entry_main) != AE_IFREG)
+ archive_entry_set_size(entry_main, 0);
+
+ /*
+ * Pax-restricted does not store data for hardlinks, in order
+ * to improve compatibility with ustar.
+ */
+ if (a->archive.archive_format != ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE &&
+ hardlink != NULL)
+ archive_entry_set_size(entry_main, 0);
+
+ /*
+ * XXX Full pax interchange format does permit a hardlink
+ * entry to have data associated with it. I'm not supporting
+ * that here because the client expects me to tell them whether
+ * or not this format expects data for hardlinks. If I
+ * don't check here, then every pax archive will end up with
+ * duplicated data for hardlinks. Someday, there may be
+ * need to select this behavior, in which case the following
+ * will need to be revisited. XXX
+ */
+ if (hardlink != NULL)
+ archive_entry_set_size(entry_main, 0);
+
+ /* Save a real file size. */
+ real_size = archive_entry_size(entry_main);
+ /*
+ * Overwrite a file size by the total size of sparse blocks and
+ * the size of sparse map info. That file size is the length of
+ * the data, which we will exactly store into an archive file.
+ */
+ if (archive_strlen(&(pax->sparse_map))) {
+ size_t mapsize = archive_strlen(&(pax->sparse_map));
+ pax->sparse_map_padding = 0x1ff & (-(ssize_t)mapsize);
+ archive_entry_set_size(entry_main,
+ mapsize + pax->sparse_map_padding + sparse_total);
+ }
+
+ /* Format 'ustar' header for main entry.
+ *
+ * The trouble with file size: If the reader can't understand
+ * the file size, they may not be able to locate the next
+ * entry and the rest of the archive is toast. Pax-compliant
+ * readers are supposed to ignore the file size in the main
+ * header, so the question becomes how to maximize portability
+ * for readers that don't support pax attribute extensions.
+ * For maximum compatibility, I permit numeric extensions in
+ * the main header so that the file size stored will always be
+ * correct, even if it's in a format that only some
+ * implementations understand. The technique used here is:
+ *
+ * a) If possible, follow the standard exactly. This handles
+ * files up to 8 gigabytes minus 1.
+ *
+ * b) If that fails, try octal but omit the field terminator.
+ * That handles files up to 64 gigabytes minus 1.
+ *
+ * c) Otherwise, use base-256 extensions. That handles files
+ * up to 2^63 in this implementation, with the potential to
+ * go up to 2^94. That should hold us for a while. ;-)
+ *
+ * The non-strict formatter uses similar logic for other
+ * numeric fields, though they're less critical.
+ */
+ if (__archive_write_format_header_ustar(a, ustarbuff, entry_main, -1, 0,
+ NULL) == ARCHIVE_FATAL)
+ return (ARCHIVE_FATAL);
+
+ /* If we built any extended attributes, write that entry first. */
+ if (archive_strlen(&(pax->pax_header)) > 0) {
+ struct archive_entry *pax_attr_entry;
+ time_t s;
+ int64_t uid, gid;
+ int mode;
+
+ pax_attr_entry = archive_entry_new2(&a->archive);
+ p = entry_name.s;
+ archive_entry_set_pathname(pax_attr_entry,
+ build_pax_attribute_name(pax_entry_name, p));
+ archive_entry_set_size(pax_attr_entry,
+ archive_strlen(&(pax->pax_header)));
+ /* Copy uid/gid (but clip to ustar limits). */
+ uid = archive_entry_uid(entry_main);
+ if (uid >= 1 << 18)
+ uid = (1 << 18) - 1;
+ archive_entry_set_uid(pax_attr_entry, uid);
+ gid = archive_entry_gid(entry_main);
+ if (gid >= 1 << 18)
+ gid = (1 << 18) - 1;
+ archive_entry_set_gid(pax_attr_entry, gid);
+ /* Copy mode over (but not setuid/setgid bits) */
+ mode = archive_entry_mode(entry_main);
+#ifdef S_ISUID
+ mode &= ~S_ISUID;
+#endif
+#ifdef S_ISGID
+ mode &= ~S_ISGID;
+#endif
+#ifdef S_ISVTX
+ mode &= ~S_ISVTX;
+#endif
+ archive_entry_set_mode(pax_attr_entry, mode);
+
+ /* Copy uname/gname. */
+ archive_entry_set_uname(pax_attr_entry,
+ archive_entry_uname(entry_main));
+ archive_entry_set_gname(pax_attr_entry,
+ archive_entry_gname(entry_main));
+
+ /* Copy mtime, but clip to ustar limits. */
+ s = archive_entry_mtime(entry_main);
+ if (s < 0) { s = 0; }
+ if (s >= 0x7fffffff) { s = 0x7fffffff; }
+ archive_entry_set_mtime(pax_attr_entry, s, 0);
+
+ /* Standard ustar doesn't support atime. */
+ archive_entry_set_atime(pax_attr_entry, 0, 0);
+
+ /* Standard ustar doesn't support ctime. */
+ archive_entry_set_ctime(pax_attr_entry, 0, 0);
+
+ r = __archive_write_format_header_ustar(a, paxbuff,
+ pax_attr_entry, 'x', 1, NULL);
+
+ archive_entry_free(pax_attr_entry);
+
+ /* Note that the 'x' header shouldn't ever fail to format */
+ if (r < ARCHIVE_WARN) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "archive_write_pax_header: "
+ "'x' header failed?! This can't happen.\n");
+ return (ARCHIVE_FATAL);
+ } else if (r < ret)
+ ret = r;
+ r = __archive_write_output(a, paxbuff, 512);
+ if (r != ARCHIVE_OK) {
+ sparse_list_clear(pax);
+ pax->entry_bytes_remaining = 0;
+ pax->entry_padding = 0;
+ return (ARCHIVE_FATAL);
+ }
+
+ pax->entry_bytes_remaining = archive_strlen(&(pax->pax_header));
+ pax->entry_padding =
+ 0x1ff & (-(int64_t)pax->entry_bytes_remaining);
+
+ r = __archive_write_output(a, pax->pax_header.s,
+ archive_strlen(&(pax->pax_header)));
+ if (r != ARCHIVE_OK) {
+ /* If a write fails, we're pretty much toast. */
+ return (ARCHIVE_FATAL);
+ }
+ /* Pad out the end of the entry. */
+ r = __archive_write_nulls(a, pax->entry_padding);
+ if (r != ARCHIVE_OK) {
+ /* If a write fails, we're pretty much toast. */
+ return (ARCHIVE_FATAL);
+ }
+ pax->entry_bytes_remaining = pax->entry_padding = 0;
+ }
+
+ /* Write the header for main entry. */
+ r = __archive_write_output(a, ustarbuff, 512);
+ if (r != ARCHIVE_OK)
+ return (r);
+
+ /*
+ * Inform the client of the on-disk size we're using, so
+ * they can avoid unnecessarily writing a body for something
+ * that we're just going to ignore.
+ */
+ archive_entry_set_size(entry_original, real_size);
+ if (pax->sparse_list == NULL && real_size > 0) {
+ /* This is not a sparse file but we handle its data as
+ * a sparse block. */
+ sparse_list_add(pax, 0, real_size);
+ sparse_total = real_size;
+ }
+ pax->entry_padding = 0x1ff & (-(int64_t)sparse_total);
+ archive_entry_free(entry_main);
+ archive_string_free(&entry_name);
+
+ return (ret);
+}
+
+/*
+ * We need a valid name for the regular 'ustar' entry. This routine
+ * tries to hack something more-or-less reasonable.
+ *
+ * The approach here tries to preserve leading dir names. We do so by
+ * working with four sections:
+ * 1) "prefix" directory names,
+ * 2) "suffix" directory names,
+ * 3) inserted dir name (optional),
+ * 4) filename.
+ *
+ * These sections must satisfy the following requirements:
+ * * Parts 1 & 2 together form an initial portion of the dir name.
+ * * Part 3 is specified by the caller. (It should not contain a leading
+ * or trailing '/'.)
+ * * Part 4 forms an initial portion of the base filename.
+ * * The filename must be <= 99 chars to fit the ustar 'name' field.
+ * * Parts 2, 3, 4 together must be <= 99 chars to fit the ustar 'name' fld.
+ * * Part 1 must be <= 155 chars to fit the ustar 'prefix' field.
+ * * If the original name ends in a '/', the new name must also end in a '/'
+ * * Trailing '/.' sequences may be stripped.
+ *
+ * Note: Recall that the ustar format does not store the '/' separating
+ * parts 1 & 2, but does store the '/' separating parts 2 & 3.
+ */
+static char *
+build_ustar_entry_name(char *dest, const char *src, size_t src_length,
+ const char *insert)
+{
+ const char *prefix, *prefix_end;
+ const char *suffix, *suffix_end;
+ const char *filename, *filename_end;
+ char *p;
+ int need_slash = 0; /* Was there a trailing slash? */
+ size_t suffix_length = 99;
+ size_t insert_length;
+
+ /* Length of additional dir element to be added. */
+ if (insert == NULL)
+ insert_length = 0;
+ else
+ /* +2 here allows for '/' before and after the insert. */
+ insert_length = strlen(insert) + 2;
+
+ /* Step 0: Quick bailout in a common case. */
+ if (src_length < 100 && insert == NULL) {
+ strncpy(dest, src, src_length);
+ dest[src_length] = '\0';
+ return (dest);
+ }
+
+ /* Step 1: Locate filename and enforce the length restriction. */
+ filename_end = src + src_length;
+ /* Remove trailing '/' chars and '/.' pairs. */
+ for (;;) {
+ if (filename_end > src && filename_end[-1] == '/') {
+ filename_end --;
+ need_slash = 1; /* Remember to restore trailing '/'. */
+ continue;
+ }
+ if (filename_end > src + 1 && filename_end[-1] == '.'
+ && filename_end[-2] == '/') {
+ filename_end -= 2;
+ need_slash = 1; /* "foo/." will become "foo/" */
+ continue;
+ }
+ break;
+ }
+ if (need_slash)
+ suffix_length--;
+ /* Find start of filename. */
+ filename = filename_end - 1;
+ while ((filename > src) && (*filename != '/'))
+ filename --;
+ if ((*filename == '/') && (filename < filename_end - 1))
+ filename ++;
+ /* Adjust filename_end so that filename + insert fits in 99 chars. */
+ suffix_length -= insert_length;
+ if (filename_end > filename + suffix_length)
+ filename_end = filename + suffix_length;
+ /* Calculate max size for "suffix" section (#3 above). */
+ suffix_length -= filename_end - filename;
+
+ /* Step 2: Locate the "prefix" section of the dirname, including
+ * trailing '/'. */
+ prefix = src;
+ prefix_end = prefix + 155;
+ if (prefix_end > filename)
+ prefix_end = filename;
+ while (prefix_end > prefix && *prefix_end != '/')
+ prefix_end--;
+ if ((prefix_end < filename) && (*prefix_end == '/'))
+ prefix_end++;
+
+ /* Step 3: Locate the "suffix" section of the dirname,
+ * including trailing '/'. */
+ suffix = prefix_end;
+ suffix_end = suffix + suffix_length; /* Enforce limit. */
+ if (suffix_end > filename)
+ suffix_end = filename;
+ if (suffix_end < suffix)
+ suffix_end = suffix;
+ while (suffix_end > suffix && *suffix_end != '/')
+ suffix_end--;
+ if ((suffix_end < filename) && (*suffix_end == '/'))
+ suffix_end++;
+
+ /* Step 4: Build the new name. */
+ /* The OpenBSD strlcpy function is safer, but less portable. */
+ /* Rather than maintain two versions, just use the strncpy version. */
+ p = dest;
+ if (prefix_end > prefix) {
+ strncpy(p, prefix, prefix_end - prefix);
+ p += prefix_end - prefix;
+ }
+ if (suffix_end > suffix) {
+ strncpy(p, suffix, suffix_end - suffix);
+ p += suffix_end - suffix;
+ }
+ if (insert != NULL) {
+ /* Note: assume insert does not have leading or trailing '/' */
+ strcpy(p, insert);
+ p += strlen(insert);
+ *p++ = '/';
+ }
+ strncpy(p, filename, filename_end - filename);
+ p += filename_end - filename;
+ if (need_slash)
+ *p++ = '/';
+ *p = '\0';
+
+ return (dest);
+}
+
+/*
+ * The ustar header for the pax extended attributes must have a
+ * reasonable name: SUSv3 requires 'dirname'/PaxHeader.'pid'/'filename'
+ * where 'pid' is the PID of the archiving process. Unfortunately,
+ * that makes testing a pain since the output varies for each run,
+ * so I'm sticking with the simpler 'dirname'/PaxHeader/'filename'
+ * for now. (Someday, I'll make this settable. Then I can use the
+ * SUS recommendation as default and test harnesses can override it
+ * to get predictable results.)
+ *
+ * Joerg Schilling has argued that this is unnecessary because, in
+ * practice, if the pax extended attributes get extracted as regular
+ * files, noone is going to bother reading those attributes to
+ * manually restore them. Based on this, 'star' uses
+ * /tmp/PaxHeader/'basename' as the ustar header name. This is a
+ * tempting argument, in part because it's simpler than the SUSv3
+ * recommendation, but I'm not entirely convinced. I'm also
+ * uncomfortable with the fact that "/tmp" is a Unix-ism.
+ *
+ * The following routine leverages build_ustar_entry_name() above and
+ * so is simpler than you might think. It just needs to provide the
+ * additional path element and handle a few pathological cases).
+ */
+static char *
+build_pax_attribute_name(char *dest, const char *src)
+{
+ char buff[64];
+ const char *p;
+
+ /* Handle the null filename case. */
+ if (src == NULL || *src == '\0') {
+ strcpy(dest, "PaxHeader/blank");
+ return (dest);
+ }
+
+ /* Prune final '/' and other unwanted final elements. */
+ p = src + strlen(src);
+ for (;;) {
+ /* Ends in "/", remove the '/' */
+ if (p > src && p[-1] == '/') {
+ --p;
+ continue;
+ }
+ /* Ends in "/.", remove the '.' */
+ if (p > src + 1 && p[-1] == '.'
+ && p[-2] == '/') {
+ --p;
+ continue;
+ }
+ break;
+ }
+
+ /* Pathological case: After above, there was nothing left.
+ * This includes "/." "/./." "/.//./." etc. */
+ if (p == src) {
+ strcpy(dest, "/PaxHeader/rootdir");
+ return (dest);
+ }
+
+ /* Convert unadorned "." into a suitable filename. */
+ if (*src == '.' && p == src + 1) {
+ strcpy(dest, "PaxHeader/currentdir");
+ return (dest);
+ }
+
+ /*
+ * TODO: Push this string into the 'pax' structure to avoid
+ * recomputing it every time. That will also open the door
+ * to having clients override it.
+ */
+#if HAVE_GETPID && 0 /* Disable this for now; see above comment. */
+ sprintf(buff, "PaxHeader.%d", getpid());
+#else
+ /* If the platform can't fetch the pid, don't include it. */
+ strcpy(buff, "PaxHeader");
+#endif
+ /* General case: build a ustar-compatible name adding
+ * "/PaxHeader/". */
+ build_ustar_entry_name(dest, src, p - src, buff);
+
+ return (dest);
+}
+
+/*
+ * GNU PAX Format 1.0 requires the special name, which pattern is:
+ * <dir>/GNUSparseFile.<pid>/<original file name>
+ *
+ * This function is used for only Sparse file, a file type of which
+ * is regular file.
+ */
+static char *
+build_gnu_sparse_name(char *dest, const char *src)
+{
+ char buff[64];
+ const char *p;
+
+ /* Handle the null filename case. */
+ if (src == NULL || *src == '\0') {
+ strcpy(dest, "GNUSparseFile/blank");
+ return (dest);
+ }
+
+ /* Prune final '/' and other unwanted final elements. */
+ p = src + strlen(src);
+ for (;;) {
+ /* Ends in "/", remove the '/' */
+ if (p > src && p[-1] == '/') {
+ --p;
+ continue;
+ }
+ /* Ends in "/.", remove the '.' */
+ if (p > src + 1 && p[-1] == '.'
+ && p[-2] == '/') {
+ --p;
+ continue;
+ }
+ break;
+ }
+
+#if HAVE_GETPID && 0 /* Disable this as pax attribute name. */
+ sprintf(buff, "GNUSparseFile.%d", getpid());
+#else
+ /* If the platform can't fetch the pid, don't include it. */
+ strcpy(buff, "GNUSparseFile");
+#endif
+ /* General case: build a ustar-compatible name adding
+ * "/GNUSparseFile/". */
+ build_ustar_entry_name(dest, src, p - src, buff);
+
+ return (dest);
+}
+
+/* Write two null blocks for the end of archive */
+static int
+archive_write_pax_close(struct archive_write *a)
+{
+ return (__archive_write_nulls(a, 512 * 2));
+}
+
+static int
+archive_write_pax_free(struct archive_write *a)
+{
+ struct pax *pax;
+
+ pax = (struct pax *)a->format_data;
+ if (pax == NULL)
+ return (ARCHIVE_OK);
+
+ archive_string_free(&pax->pax_header);
+ archive_string_free(&pax->sparse_map);
+ archive_string_free(&pax->l_url_encoded_name);
+ sparse_list_clear(pax);
+ free(pax);
+ a->format_data = NULL;
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_write_pax_finish_entry(struct archive_write *a)
+{
+ struct pax *pax;
+ uint64_t remaining;
+ int ret;
+
+ pax = (struct pax *)a->format_data;
+ remaining = pax->entry_bytes_remaining;
+ if (remaining == 0) {
+ while (pax->sparse_list) {
+ struct sparse_block *sb;
+ remaining += pax->sparse_list->remaining;
+ sb = pax->sparse_list->next;
+ free(pax->sparse_list);
+ pax->sparse_list = sb;
+ }
+ }
+ ret = __archive_write_nulls(a, remaining + pax->entry_padding);
+ pax->entry_bytes_remaining = pax->entry_padding = 0;
+ return (ret);
+}
+
+static ssize_t
+archive_write_pax_data(struct archive_write *a, const void *buff, size_t s)
+{
+ struct pax *pax;
+ size_t ws;
+ size_t total;
+ int ret;
+
+ pax = (struct pax *)a->format_data;
+
+ /*
+ * According to GNU PAX format 1.0, write a sparse map
+ * before the body.
+ */
+ if (archive_strlen(&(pax->sparse_map))) {
+ ret = __archive_write_output(a, pax->sparse_map.s,
+ archive_strlen(&(pax->sparse_map)));
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ ret = __archive_write_nulls(a, pax->sparse_map_padding);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ archive_string_empty(&(pax->sparse_map));
+ }
+
+ total = 0;
+ while (total < s) {
+ const unsigned char *p;
+
+ while (pax->sparse_list != NULL &&
+ pax->sparse_list->remaining == 0) {
+ struct sparse_block *sb = pax->sparse_list->next;
+ free(pax->sparse_list);
+ pax->sparse_list = sb;
+ }
+
+ if (pax->sparse_list == NULL)
+ return (total);
+
+ p = ((const unsigned char *)buff) + total;
+ ws = s;
+ if (ws > pax->sparse_list->remaining)
+ ws = pax->sparse_list->remaining;
+
+ if (pax->sparse_list->is_hole) {
+ /* Current block is hole thus we do not write
+ * the body. */
+ pax->sparse_list->remaining -= ws;
+ total += ws;
+ continue;
+ }
+
+ ret = __archive_write_output(a, p, ws);
+ pax->sparse_list->remaining -= ws;
+ total += ws;
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ }
+ return (total);
+}
+
+static int
+has_non_ASCII(const char *_p)
+{
+ const unsigned char *p = (const unsigned char *)_p;
+
+ if (p == NULL)
+ return (1);
+ while (*p != '\0' && *p < 128)
+ p++;
+ return (*p != '\0');
+}
+
+/*
+ * Used by extended attribute support; encodes the name
+ * so that there will be no '=' characters in the result.
+ */
+static char *
+url_encode(const char *in)
+{
+ const char *s;
+ char *d;
+ int out_len = 0;
+ char *out;
+
+ for (s = in; *s != '\0'; s++) {
+ if (*s < 33 || *s > 126 || *s == '%' || *s == '=')
+ out_len += 3;
+ else
+ out_len++;
+ }
+
+ out = (char *)malloc(out_len + 1);
+ if (out == NULL)
+ return (NULL);
+
+ for (s = in, d = out; *s != '\0'; s++) {
+ /* encode any non-printable ASCII character or '%' or '=' */
+ if (*s < 33 || *s > 126 || *s == '%' || *s == '=') {
+ /* URL encoding is '%' followed by two hex digits */
+ *d++ = '%';
+ *d++ = "0123456789ABCDEF"[0x0f & (*s >> 4)];
+ *d++ = "0123456789ABCDEF"[0x0f & *s];
+ } else {
+ *d++ = *s;
+ }
+ }
+ *d = '\0';
+ return (out);
+}
+
+/*
+ * Encode a sequence of bytes into a C string using base-64 encoding.
+ *
+ * Returns a null-terminated C string allocated with malloc(); caller
+ * is responsible for freeing the result.
+ */
+static char *
+base64_encode(const char *s, size_t len)
+{
+ static const char digits[64] =
+ { 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O',
+ 'P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d',
+ 'e','f','g','h','i','j','k','l','m','n','o','p','q','r','s',
+ 't','u','v','w','x','y','z','0','1','2','3','4','5','6','7',
+ '8','9','+','/' };
+ int v;
+ char *d, *out;
+
+ /* 3 bytes becomes 4 chars, but round up and allow for trailing NUL */
+ out = (char *)malloc((len * 4 + 2) / 3 + 1);
+ if (out == NULL)
+ return (NULL);
+ d = out;
+
+ /* Convert each group of 3 bytes into 4 characters. */
+ while (len >= 3) {
+ v = (((int)s[0] << 16) & 0xff0000)
+ | (((int)s[1] << 8) & 0xff00)
+ | (((int)s[2]) & 0x00ff);
+ s += 3;
+ len -= 3;
+ *d++ = digits[(v >> 18) & 0x3f];
+ *d++ = digits[(v >> 12) & 0x3f];
+ *d++ = digits[(v >> 6) & 0x3f];
+ *d++ = digits[(v) & 0x3f];
+ }
+ /* Handle final group of 1 byte (2 chars) or 2 bytes (3 chars). */
+ switch (len) {
+ case 0: break;
+ case 1:
+ v = (((int)s[0] << 16) & 0xff0000);
+ *d++ = digits[(v >> 18) & 0x3f];
+ *d++ = digits[(v >> 12) & 0x3f];
+ break;
+ case 2:
+ v = (((int)s[0] << 16) & 0xff0000)
+ | (((int)s[1] << 8) & 0xff00);
+ *d++ = digits[(v >> 18) & 0x3f];
+ *d++ = digits[(v >> 12) & 0x3f];
+ *d++ = digits[(v >> 6) & 0x3f];
+ break;
+ }
+ /* Add trailing NUL character so output is a valid C string. */
+ *d = '\0';
+ return (out);
+}
+
+static void
+sparse_list_clear(struct pax *pax)
+{
+ while (pax->sparse_list != NULL) {
+ struct sparse_block *sb = pax->sparse_list;
+ pax->sparse_list = sb->next;
+ free(sb);
+ }
+ pax->sparse_tail = NULL;
+}
+
+static int
+_sparse_list_add_block(struct pax *pax, int64_t offset, int64_t length,
+ int is_hole)
+{
+ struct sparse_block *sb;
+
+ sb = (struct sparse_block *)malloc(sizeof(*sb));
+ if (sb == NULL)
+ return (ARCHIVE_FATAL);
+ sb->next = NULL;
+ sb->is_hole = is_hole;
+ sb->offset = offset;
+ sb->remaining = length;
+ if (pax->sparse_list == NULL)
+ pax->sparse_list = pax->sparse_tail = sb;
+ else {
+ pax->sparse_tail->next = sb;
+ pax->sparse_tail = sb;
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+sparse_list_add(struct pax *pax, int64_t offset, int64_t length)
+{
+ int64_t last_offset;
+ int r;
+
+ if (pax->sparse_tail == NULL)
+ last_offset = 0;
+ else {
+ last_offset = pax->sparse_tail->offset +
+ pax->sparse_tail->remaining;
+ }
+ if (last_offset < offset) {
+ /* Add a hole block. */
+ r = _sparse_list_add_block(pax, last_offset,
+ offset - last_offset, 1);
+ if (r != ARCHIVE_OK)
+ return (r);
+ }
+ /* Add data block. */
+ return (_sparse_list_add_block(pax, offset, length, 0));
+}
+
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_shar.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_shar.c
new file mode 100644
index 000000000..9ec15f915
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_shar.c
@@ -0,0 +1,642 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2008 Joerg Sonnenberger
+ * 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_shar.c 189438 2009-03-06 05:58:56Z kientzle $");
+
+#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
+
+#include "archive.h"
+#include "archive_entry.h"
+#include "archive_private.h"
+#include "archive_write_private.h"
+
+struct shar {
+ int dump;
+ int end_of_line;
+ struct archive_entry *entry;
+ int has_data;
+ char *last_dir;
+
+ /* Line buffer for uuencoded dump format */
+ char outbuff[45];
+ size_t outpos;
+
+ int wrote_header;
+ struct archive_string work;
+ struct archive_string quoted_name;
+};
+
+static int archive_write_shar_close(struct archive_write *);
+static int archive_write_shar_free(struct archive_write *);
+static int archive_write_shar_header(struct archive_write *,
+ struct archive_entry *);
+static ssize_t archive_write_shar_data_sed(struct archive_write *,
+ const void * buff, size_t);
+static ssize_t archive_write_shar_data_uuencode(struct archive_write *,
+ const void * buff, size_t);
+static int archive_write_shar_finish_entry(struct archive_write *);
+
+/*
+ * Copy the given string to the buffer, quoting all shell meta characters
+ * found.
+ */
+static void
+shar_quote(struct archive_string *buf, const char *str, int in_shell)
+{
+ static const char meta[] = "\n \t'`\";&<>()|*?{}[]\\$!#^~";
+ size_t len;
+
+ while (*str != '\0') {
+ if ((len = strcspn(str, meta)) != 0) {
+ archive_strncat(buf, str, len);
+ str += len;
+ } else if (*str == '\n') {
+ if (in_shell)
+ archive_strcat(buf, "\"\n\"");
+ else
+ archive_strcat(buf, "\\n");
+ ++str;
+ } else {
+ archive_strappend_char(buf, '\\');
+ archive_strappend_char(buf, *str);
+ ++str;
+ }
+ }
+}
+
+/*
+ * Set output format to 'shar' format.
+ */
+int
+archive_write_set_format_shar(struct archive *_a)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ struct shar *shar;
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_shar");
+
+ /* If someone else was already registered, unregister them. */
+ if (a->format_free != NULL)
+ (a->format_free)(a);
+
+ shar = (struct shar *)malloc(sizeof(*shar));
+ if (shar == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Can't allocate shar data");
+ return (ARCHIVE_FATAL);
+ }
+ memset(shar, 0, sizeof(*shar));
+ archive_string_init(&shar->work);
+ archive_string_init(&shar->quoted_name);
+ a->format_data = shar;
+ a->format_name = "shar";
+ a->format_write_header = archive_write_shar_header;
+ a->format_close = archive_write_shar_close;
+ a->format_free = archive_write_shar_free;
+ a->format_write_data = archive_write_shar_data_sed;
+ a->format_finish_entry = archive_write_shar_finish_entry;
+ a->archive.archive_format = ARCHIVE_FORMAT_SHAR_BASE;
+ a->archive.archive_format_name = "shar";
+ return (ARCHIVE_OK);
+}
+
+/*
+ * An alternate 'shar' that uses uudecode instead of 'sed' to encode
+ * file contents and can therefore be used to archive binary files.
+ * In addition, this variant also attempts to restore ownership, file modes,
+ * and other extended file information.
+ */
+int
+archive_write_set_format_shar_dump(struct archive *_a)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ struct shar *shar;
+
+ archive_write_set_format_shar(&a->archive);
+ shar = (struct shar *)a->format_data;
+ shar->dump = 1;
+ a->format_write_data = archive_write_shar_data_uuencode;
+ a->archive.archive_format = ARCHIVE_FORMAT_SHAR_DUMP;
+ a->archive.archive_format_name = "shar dump";
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_write_shar_header(struct archive_write *a, struct archive_entry *entry)
+{
+ const char *linkname;
+ const char *name;
+ char *p, *pp;
+ struct shar *shar;
+
+ shar = (struct shar *)a->format_data;
+ if (!shar->wrote_header) {
+ archive_strcat(&shar->work, "#!/bin/sh\n");
+ archive_strcat(&shar->work, "# This is a shell archive\n");
+ shar->wrote_header = 1;
+ }
+
+ /* Save the entry for the closing. */
+ if (shar->entry)
+ archive_entry_free(shar->entry);
+ shar->entry = archive_entry_clone(entry);
+ name = archive_entry_pathname(entry);
+
+ /* Handle some preparatory issues. */
+ switch(archive_entry_filetype(entry)) {
+ case AE_IFREG:
+ /* Only regular files have non-zero size. */
+ break;
+ case AE_IFDIR:
+ archive_entry_set_size(entry, 0);
+ /* Don't bother trying to recreate '.' */
+ if (strcmp(name, ".") == 0 || strcmp(name, "./") == 0)
+ return (ARCHIVE_OK);
+ break;
+ case AE_IFIFO:
+ case AE_IFCHR:
+ case AE_IFBLK:
+ /* All other file types have zero size in the archive. */
+ archive_entry_set_size(entry, 0);
+ break;
+ default:
+ archive_entry_set_size(entry, 0);
+ if (archive_entry_hardlink(entry) == NULL &&
+ archive_entry_symlink(entry) == NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "shar format cannot archive this");
+ return (ARCHIVE_WARN);
+ }
+ }
+
+ archive_string_empty(&shar->quoted_name);
+ shar_quote(&shar->quoted_name, name, 1);
+
+ /* Stock preparation for all file types. */
+ archive_string_sprintf(&shar->work, "echo x %s\n", shar->quoted_name.s);
+
+ if (archive_entry_filetype(entry) != AE_IFDIR) {
+ /* Try to create the dir. */
+ p = strdup(name);
+ pp = strrchr(p, '/');
+ /* If there is a / character, try to create the dir. */
+ if (pp != NULL) {
+ *pp = '\0';
+
+ /* Try to avoid a lot of redundant mkdir commands. */
+ if (strcmp(p, ".") == 0) {
+ /* Don't try to "mkdir ." */
+ free(p);
+ } else if (shar->last_dir == NULL) {
+ archive_strcat(&shar->work, "mkdir -p ");
+ shar_quote(&shar->work, p, 1);
+ archive_strcat(&shar->work,
+ " > /dev/null 2>&1\n");
+ shar->last_dir = p;
+ } else if (strcmp(p, shar->last_dir) == 0) {
+ /* We've already created this exact dir. */
+ free(p);
+ } else if (strlen(p) < strlen(shar->last_dir) &&
+ strncmp(p, shar->last_dir, strlen(p)) == 0) {
+ /* We've already created a subdir. */
+ free(p);
+ } else {
+ archive_strcat(&shar->work, "mkdir -p ");
+ shar_quote(&shar->work, p, 1);
+ archive_strcat(&shar->work,
+ " > /dev/null 2>&1\n");
+ shar->last_dir = p;
+ }
+ } else {
+ free(p);
+ }
+ }
+
+ /* Handle file-type specific issues. */
+ shar->has_data = 0;
+ if ((linkname = archive_entry_hardlink(entry)) != NULL) {
+ archive_strcat(&shar->work, "ln -f ");
+ shar_quote(&shar->work, linkname, 1);
+ archive_string_sprintf(&shar->work, " %s\n",
+ shar->quoted_name.s);
+ } else if ((linkname = archive_entry_symlink(entry)) != NULL) {
+ archive_strcat(&shar->work, "ln -fs ");
+ shar_quote(&shar->work, linkname, 1);
+ archive_string_sprintf(&shar->work, " %s\n",
+ shar->quoted_name.s);
+ } else {
+ switch(archive_entry_filetype(entry)) {
+ case AE_IFREG:
+ if (archive_entry_size(entry) == 0) {
+ /* More portable than "touch." */
+ archive_string_sprintf(&shar->work,
+ "test -e \"%s\" || :> \"%s\"\n",
+ shar->quoted_name.s, shar->quoted_name.s);
+ } else {
+ if (shar->dump) {
+ unsigned int mode = archive_entry_mode(entry) & 0777;
+ archive_string_sprintf(&shar->work,
+ "uudecode -p > %s << 'SHAR_END'\n",
+ shar->quoted_name.s);
+ archive_string_sprintf(&shar->work,
+ "begin %o ", mode);
+ shar_quote(&shar->work, name, 0);
+ archive_strcat(&shar->work, "\n");
+ } else {
+ archive_string_sprintf(&shar->work,
+ "sed 's/^X//' > %s << 'SHAR_END'\n",
+ shar->quoted_name.s);
+ }
+ shar->has_data = 1;
+ shar->end_of_line = 1;
+ shar->outpos = 0;
+ }
+ break;
+ case AE_IFDIR:
+ archive_string_sprintf(&shar->work,
+ "mkdir -p %s > /dev/null 2>&1\n",
+ shar->quoted_name.s);
+ /* Record that we just created this directory. */
+ if (shar->last_dir != NULL)
+ free(shar->last_dir);
+
+ shar->last_dir = strdup(name);
+ /* Trim a trailing '/'. */
+ pp = strrchr(shar->last_dir, '/');
+ if (pp != NULL && pp[1] == '\0')
+ *pp = '\0';
+ /*
+ * TODO: Put dir name/mode on a list to be fixed
+ * up at end of archive.
+ */
+ break;
+ case AE_IFIFO:
+ archive_string_sprintf(&shar->work,
+ "mkfifo %s\n", shar->quoted_name.s);
+ break;
+ case AE_IFCHR:
+ archive_string_sprintf(&shar->work,
+ "mknod %s c %ju %ju\n", shar->quoted_name.s,
+ (uintmax_t)archive_entry_rdevmajor(entry),
+ (uintmax_t)archive_entry_rdevminor(entry));
+ break;
+ case AE_IFBLK:
+ archive_string_sprintf(&shar->work,
+ "mknod %s b %ju %ju\n", shar->quoted_name.s,
+ (uintmax_t)archive_entry_rdevmajor(entry),
+ (uintmax_t)archive_entry_rdevminor(entry));
+ break;
+ default:
+ return (ARCHIVE_WARN);
+ }
+ }
+
+ return (ARCHIVE_OK);
+}
+
+static ssize_t
+archive_write_shar_data_sed(struct archive_write *a, const void *buff, size_t n)
+{
+ static const size_t ensured = 65533;
+ struct shar *shar;
+ const char *src;
+ char *buf, *buf_end;
+ int ret;
+ size_t written = n;
+
+ shar = (struct shar *)a->format_data;
+ if (!shar->has_data || n == 0)
+ return (0);
+
+ src = (const char *)buff;
+
+ /*
+ * ensure is the number of bytes in buffer before expanding the
+ * current character. Each operation writes the current character
+ * and optionally the start-of-new-line marker. This can happen
+ * twice before entering the loop, so make sure three additional
+ * bytes can be written.
+ */
+ if (archive_string_ensure(&shar->work, ensured + 3) == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
+
+ if (shar->work.length > ensured) {
+ ret = __archive_write_output(a, shar->work.s,
+ shar->work.length);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ archive_string_empty(&shar->work);
+ }
+ buf = shar->work.s + shar->work.length;
+ buf_end = shar->work.s + ensured;
+
+ if (shar->end_of_line) {
+ *buf++ = 'X';
+ shar->end_of_line = 0;
+ }
+
+ while (n-- != 0) {
+ if ((*buf++ = *src++) == '\n') {
+ if (n == 0)
+ shar->end_of_line = 1;
+ else
+ *buf++ = 'X';
+ }
+
+ if (buf >= buf_end) {
+ shar->work.length = buf - shar->work.s;
+ ret = __archive_write_output(a, shar->work.s,
+ shar->work.length);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ archive_string_empty(&shar->work);
+ buf = shar->work.s;
+ }
+ }
+
+ shar->work.length = buf - shar->work.s;
+
+ return (written);
+}
+
+#define UUENC(c) (((c)!=0) ? ((c) & 077) + ' ': '`')
+
+static void
+uuencode_group(const char _in[3], char out[4])
+{
+ const unsigned char *in = (const unsigned char *)_in;
+ int t;
+
+ t = (in[0] << 16) | (in[1] << 8) | in[2];
+ out[0] = UUENC( 0x3f & (t >> 18) );
+ out[1] = UUENC( 0x3f & (t >> 12) );
+ out[2] = UUENC( 0x3f & (t >> 6) );
+ out[3] = UUENC( 0x3f & t );
+}
+
+static int
+_uuencode_line(struct archive_write *a, struct shar *shar, const char *inbuf, size_t len)
+{
+ char *buf;
+ size_t alloc_len;
+
+ /* len <= 45 -> expanded to 60 + len byte + new line */
+ alloc_len = shar->work.length + 62;
+ if (archive_string_ensure(&shar->work, alloc_len) == NULL) {
+ archive_set_error(&a->archive, ENOMEM, "Out of memory");
+ return (ARCHIVE_FATAL);
+ }
+
+ buf = shar->work.s + shar->work.length;
+ *buf++ = UUENC(len);
+ while (len >= 3) {
+ uuencode_group(inbuf, buf);
+ len -= 3;
+ inbuf += 3;
+ buf += 4;
+ }
+ if (len != 0) {
+ char tmp_buf[3];
+ tmp_buf[0] = inbuf[0];
+ if (len == 1)
+ tmp_buf[1] = '\0';
+ else
+ tmp_buf[1] = inbuf[1];
+ tmp_buf[2] = '\0';
+ uuencode_group(tmp_buf, buf);
+ buf += 4;
+ }
+ *buf++ = '\n';
+ if ((buf - shar->work.s) > (ptrdiff_t)(shar->work.length + 62)) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC, "Buffer overflow");
+ return (ARCHIVE_FATAL);
+ }
+ shar->work.length = buf - shar->work.s;
+ return (ARCHIVE_OK);
+}
+
+#define uuencode_line(__a, __shar, __inbuf, __len) \
+ do { \
+ int r = _uuencode_line(__a, __shar, __inbuf, __len); \
+ if (r != ARCHIVE_OK) \
+ return (ARCHIVE_FATAL); \
+ } while (0)
+
+static ssize_t
+archive_write_shar_data_uuencode(struct archive_write *a, const void *buff,
+ size_t length)
+{
+ struct shar *shar;
+ const char *src;
+ size_t n;
+ int ret;
+
+ shar = (struct shar *)a->format_data;
+ if (!shar->has_data)
+ return (ARCHIVE_OK);
+ src = (const char *)buff;
+
+ if (shar->outpos != 0) {
+ n = 45 - shar->outpos;
+ if (n > length)
+ n = length;
+ memcpy(shar->outbuff + shar->outpos, src, n);
+ if (shar->outpos + n < 45) {
+ shar->outpos += n;
+ return length;
+ }
+ uuencode_line(a, shar, shar->outbuff, 45);
+ src += n;
+ n = length - n;
+ } else {
+ n = length;
+ }
+
+ while (n >= 45) {
+ uuencode_line(a, shar, src, 45);
+ src += 45;
+ n -= 45;
+
+ if (shar->work.length < 65536)
+ continue;
+ ret = __archive_write_output(a, shar->work.s,
+ shar->work.length);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ archive_string_empty(&shar->work);
+ }
+ if (n != 0) {
+ memcpy(shar->outbuff, src, n);
+ shar->outpos = n;
+ }
+ return (length);
+}
+
+static int
+archive_write_shar_finish_entry(struct archive_write *a)
+{
+ const char *g, *p, *u;
+ struct shar *shar;
+ int ret;
+
+ shar = (struct shar *)a->format_data;
+ if (shar->entry == NULL)
+ return (0);
+
+ if (shar->dump) {
+ /* Finish uuencoded data. */
+ if (shar->has_data) {
+ if (shar->outpos > 0)
+ uuencode_line(a, shar, shar->outbuff,
+ shar->outpos);
+ archive_strcat(&shar->work, "`\nend\n");
+ archive_strcat(&shar->work, "SHAR_END\n");
+ }
+ /* Restore file mode, owner, flags. */
+ /*
+ * TODO: Don't immediately restore mode for
+ * directories; defer that to end of script.
+ */
+ archive_string_sprintf(&shar->work, "chmod %o ",
+ (unsigned int)(archive_entry_mode(shar->entry) & 07777));
+ shar_quote(&shar->work, archive_entry_pathname(shar->entry), 1);
+ archive_strcat(&shar->work, "\n");
+
+ u = archive_entry_uname(shar->entry);
+ g = archive_entry_gname(shar->entry);
+ if (u != NULL || g != NULL) {
+ archive_strcat(&shar->work, "chown ");
+ if (u != NULL)
+ shar_quote(&shar->work, u, 1);
+ if (g != NULL) {
+ archive_strcat(&shar->work, ":");
+ shar_quote(&shar->work, g, 1);
+ }
+ shar_quote(&shar->work,
+ archive_entry_pathname(shar->entry), 1);
+ archive_strcat(&shar->work, "\n");
+ }
+
+ if ((p = archive_entry_fflags_text(shar->entry)) != NULL) {
+ archive_string_sprintf(&shar->work, "chflags %s ", p);
+ shar_quote(&shar->work,
+ archive_entry_pathname(shar->entry), 1);
+ archive_strcat(&shar->work, "\n");
+ }
+
+ /* TODO: restore ACLs */
+
+ } else {
+ if (shar->has_data) {
+ /* Finish sed-encoded data: ensure last line ends. */
+ if (!shar->end_of_line)
+ archive_strappend_char(&shar->work, '\n');
+ archive_strcat(&shar->work, "SHAR_END\n");
+ }
+ }
+
+ archive_entry_free(shar->entry);
+ shar->entry = NULL;
+
+ if (shar->work.length < 65536)
+ return (ARCHIVE_OK);
+
+ ret = __archive_write_output(a, shar->work.s, shar->work.length);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ archive_string_empty(&shar->work);
+
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_write_shar_close(struct archive_write *a)
+{
+ struct shar *shar;
+ int ret;
+
+ /*
+ * TODO: Accumulate list of directory names/modes and
+ * fix them all up at end-of-archive.
+ */
+
+ shar = (struct shar *)a->format_data;
+
+ /*
+ * Only write the end-of-archive markers if the archive was
+ * actually started. This avoids problems if someone sets
+ * shar format, then sets another format (which would invoke
+ * shar_finish to free the format-specific data).
+ */
+ if (shar->wrote_header == 0)
+ return (ARCHIVE_OK);
+
+ archive_strcat(&shar->work, "exit\n");
+
+ ret = __archive_write_output(a, shar->work.s, shar->work.length);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+
+ /* Shar output is never padded. */
+ archive_write_set_bytes_in_last_block(&a->archive, 1);
+ /*
+ * TODO: shar should also suppress padding of
+ * uncompressed data within gzip/bzip2 streams.
+ */
+
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_write_shar_free(struct archive_write *a)
+{
+ struct shar *shar;
+
+ shar = (struct shar *)a->format_data;
+ if (shar == NULL)
+ return (ARCHIVE_OK);
+
+ archive_entry_free(shar->entry);
+ free(shar->last_dir);
+ archive_string_free(&(shar->work));
+ archive_string_free(&(shar->quoted_name));
+ free(shar);
+ a->format_data = NULL;
+ return (ARCHIVE_OK);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_ustar.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_ustar.c
new file mode 100644
index 000000000..4b96ac23c
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_ustar.c
@@ -0,0 +1,692 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * 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"
+__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_ustar.c 191579 2009-04-27 18:35:03Z kientzle $");
+
+
+#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
+
+#include "archive.h"
+#include "archive_entry.h"
+#include "archive_entry_locale.h"
+#include "archive_private.h"
+#include "archive_write_private.h"
+
+struct ustar {
+ uint64_t entry_bytes_remaining;
+ uint64_t entry_padding;
+
+ struct archive_string_conv *opt_sconv;
+ struct archive_string_conv *sconv_default;
+ int init_default_conversion;
+};
+
+/*
+ * Define structure of POSIX 'ustar' tar header.
+ */
+#define USTAR_name_offset 0
+#define USTAR_name_size 100
+#define USTAR_mode_offset 100
+#define USTAR_mode_size 6
+#define USTAR_mode_max_size 8
+#define USTAR_uid_offset 108
+#define USTAR_uid_size 6
+#define USTAR_uid_max_size 8
+#define USTAR_gid_offset 116
+#define USTAR_gid_size 6
+#define USTAR_gid_max_size 8
+#define USTAR_size_offset 124
+#define USTAR_size_size 11
+#define USTAR_size_max_size 12
+#define USTAR_mtime_offset 136
+#define USTAR_mtime_size 11
+#define USTAR_mtime_max_size 11
+#define USTAR_checksum_offset 148
+#define USTAR_checksum_size 8
+#define USTAR_typeflag_offset 156
+#define USTAR_typeflag_size 1
+#define USTAR_linkname_offset 157
+#define USTAR_linkname_size 100
+#define USTAR_magic_offset 257
+#define USTAR_magic_size 6
+#define USTAR_version_offset 263
+#define USTAR_version_size 2
+#define USTAR_uname_offset 265
+#define USTAR_uname_size 32
+#define USTAR_gname_offset 297
+#define USTAR_gname_size 32
+#define USTAR_rdevmajor_offset 329
+#define USTAR_rdevmajor_size 6
+#define USTAR_rdevmajor_max_size 8
+#define USTAR_rdevminor_offset 337
+#define USTAR_rdevminor_size 6
+#define USTAR_rdevminor_max_size 8
+#define USTAR_prefix_offset 345
+#define USTAR_prefix_size 155
+#define USTAR_padding_offset 500
+#define USTAR_padding_size 12
+
+/*
+ * A filled-in copy of the header for initialization.
+ */
+static const char template_header[] = {
+ /* name: 100 bytes */
+ 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,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,
+ /* Mode, space-null termination: 8 bytes */
+ '0','0','0','0','0','0', ' ','\0',
+ /* uid, space-null termination: 8 bytes */
+ '0','0','0','0','0','0', ' ','\0',
+ /* gid, space-null termination: 8 bytes */
+ '0','0','0','0','0','0', ' ','\0',
+ /* size, space termation: 12 bytes */
+ '0','0','0','0','0','0','0','0','0','0','0', ' ',
+ /* mtime, space termation: 12 bytes */
+ '0','0','0','0','0','0','0','0','0','0','0', ' ',
+ /* Initial checksum value: 8 spaces */
+ ' ',' ',' ',' ',' ',' ',' ',' ',
+ /* Typeflag: 1 byte */
+ '0', /* '0' = regular file */
+ /* Linkname: 100 bytes */
+ 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,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,
+ /* Magic: 6 bytes, Version: 2 bytes */
+ 'u','s','t','a','r','\0', '0','0',
+ /* Uname: 32 bytes */
+ 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,
+ /* Gname: 32 bytes */
+ 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,
+ /* rdevmajor + space/null padding: 8 bytes */
+ '0','0','0','0','0','0', ' ','\0',
+ /* rdevminor + space/null padding: 8 bytes */
+ '0','0','0','0','0','0', ' ','\0',
+ /* Prefix: 155 bytes */
+ 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,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,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,
+ /* Padding: 12 bytes */
+ 0,0,0,0,0,0,0,0, 0,0,0,0
+};
+
+static ssize_t archive_write_ustar_data(struct archive_write *a, const void *buff,
+ size_t s);
+static int archive_write_ustar_free(struct archive_write *);
+static int archive_write_ustar_close(struct archive_write *);
+static int archive_write_ustar_finish_entry(struct archive_write *);
+static int archive_write_ustar_header(struct archive_write *,
+ struct archive_entry *entry);
+static int archive_write_ustar_options(struct archive_write *,
+ const char *, const char *);
+static int format_256(int64_t, char *, int);
+static int format_number(int64_t, char *, int size, int max, int strict);
+static int format_octal(int64_t, char *, int);
+
+/*
+ * Set output format to 'ustar' format.
+ */
+int
+archive_write_set_format_ustar(struct archive *_a)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ struct ustar *ustar;
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_ustar");
+
+ /* If someone else was already registered, unregister them. */
+ if (a->format_free != NULL)
+ (a->format_free)(a);
+
+ /* Basic internal sanity test. */
+ if (sizeof(template_header) != 512) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Internal: template_header wrong size: %zu should be 512",
+ sizeof(template_header));
+ return (ARCHIVE_FATAL);
+ }
+
+ ustar = (struct ustar *)malloc(sizeof(*ustar));
+ if (ustar == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate ustar data");
+ return (ARCHIVE_FATAL);
+ }
+ memset(ustar, 0, sizeof(*ustar));
+ a->format_data = ustar;
+ a->format_name = "ustar";
+ a->format_options = archive_write_ustar_options;
+ a->format_write_header = archive_write_ustar_header;
+ a->format_write_data = archive_write_ustar_data;
+ a->format_close = archive_write_ustar_close;
+ a->format_free = archive_write_ustar_free;
+ a->format_finish_entry = archive_write_ustar_finish_entry;
+ a->archive.archive_format = ARCHIVE_FORMAT_TAR_USTAR;
+ a->archive.archive_format_name = "POSIX ustar";
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_write_ustar_options(struct archive_write *a, const char *key,
+ const char *val)
+{
+ struct ustar *ustar = (struct ustar *)a->format_data;
+ int ret = ARCHIVE_FAILED;
+
+ if (strcmp(key, "hdrcharset") == 0) {
+ if (val == NULL || val[0] == 0)
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "%s: hdrcharset option needs a character-set name",
+ a->format_name);
+ else {
+ ustar->opt_sconv = archive_string_conversion_to_charset(
+ &a->archive, val, 0);
+ if (ustar->opt_sconv != NULL)
+ ret = ARCHIVE_OK;
+ else
+ ret = ARCHIVE_FATAL;
+ }
+ } else
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "%s: unknown keyword ``%s''", a->format_name, key);
+
+ return (ret);
+}
+
+static int
+archive_write_ustar_header(struct archive_write *a, struct archive_entry *entry)
+{
+ char buff[512];
+ int ret, ret2;
+ struct ustar *ustar;
+ struct archive_string_conv *sconv;
+
+ ustar = (struct ustar *)a->format_data;
+
+ /* Setup default string conversion. */
+ if (ustar->opt_sconv == NULL) {
+ if (!ustar->init_default_conversion) {
+ ustar->sconv_default =
+ archive_string_default_conversion_for_write(&(a->archive));
+ ustar->init_default_conversion = 1;
+ }
+ sconv = ustar->sconv_default;
+ } else
+ sconv = ustar->opt_sconv;
+
+ /* Sanity check. */
+ if (archive_entry_pathname(entry) == NULL) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Can't record entry in tar file without pathname");
+ return (ARCHIVE_FAILED);
+ }
+
+ /* Only regular files (not hardlinks) have data. */
+ if (archive_entry_hardlink(entry) != NULL ||
+ archive_entry_symlink(entry) != NULL ||
+ !(archive_entry_filetype(entry) == AE_IFREG))
+ archive_entry_set_size(entry, 0);
+
+ if (AE_IFDIR == archive_entry_filetype(entry)) {
+ const char *p;
+ char *t;
+ /*
+ * Ensure a trailing '/'. Modify the entry so
+ * the client sees the change.
+ */
+ p = archive_entry_pathname(entry);
+ if (p[strlen(p) - 1] != '/') {
+ t = (char *)malloc(strlen(p) + 2);
+ if (t == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate ustar data");
+ return(ARCHIVE_FATAL);
+ }
+ strcpy(t, p);
+ strcat(t, "/");
+ archive_entry_copy_pathname(entry, t);
+ free(t);
+ }
+ }
+
+ ret = __archive_write_format_header_ustar(a, buff, entry, -1, 1, sconv);
+ if (ret < ARCHIVE_WARN)
+ return (ret);
+ ret2 = __archive_write_output(a, buff, 512);
+ if (ret2 < ARCHIVE_WARN)
+ return (ret2);
+ if (ret2 < ret)
+ ret = ret2;
+
+ ustar->entry_bytes_remaining = archive_entry_size(entry);
+ ustar->entry_padding = 0x1ff & (-(int64_t)ustar->entry_bytes_remaining);
+ return (ret);
+}
+
+/*
+ * Format a basic 512-byte "ustar" header.
+ *
+ * Returns -1 if format failed (due to field overflow).
+ * Note that this always formats as much of the header as possible.
+ * If "strict" is set to zero, it will extend numeric fields as
+ * necessary (overwriting terminators or using base-256 extensions).
+ *
+ * This is exported so that other 'tar' formats can use it.
+ */
+int
+__archive_write_format_header_ustar(struct archive_write *a, char h[512],
+ struct archive_entry *entry, int tartype, int strict,
+ struct archive_string_conv *sconv)
+{
+ unsigned int checksum;
+ int i, r, ret;
+ size_t copy_length;
+ const char *p, *pp;
+ int mytartype;
+
+ ret = 0;
+ mytartype = -1;
+ /*
+ * The "template header" already includes the "ustar"
+ * signature, various end-of-field markers and other required
+ * elements.
+ */
+ memcpy(h, &template_header, 512);
+
+ /*
+ * Because the block is already null-filled, and strings
+ * are allowed to exactly fill their destination (without null),
+ * I use memcpy(dest, src, strlen()) here a lot to copy strings.
+ */
+ r = archive_entry_pathname_l(entry, &pp, &copy_length, sconv);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Pathname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate pathname '%s' to %s",
+ pp, archive_string_conversion_charset_name(sconv));
+ ret = ARCHIVE_WARN;
+ }
+ if (copy_length <= USTAR_name_size)
+ memcpy(h + USTAR_name_offset, pp, copy_length);
+ else {
+ /* Store in two pieces, splitting at a '/'. */
+ p = strchr(pp + copy_length - USTAR_name_size - 1, '/');
+ /*
+ * Look for the next '/' if we chose the first character
+ * as the separator. (ustar format doesn't permit
+ * an empty prefix.)
+ */
+ if (p == pp)
+ p = strchr(p + 1, '/');
+ /* Fail if the name won't fit. */
+ if (!p) {
+ /* No separator. */
+ archive_set_error(&a->archive, ENAMETOOLONG,
+ "Pathname too long");
+ ret = ARCHIVE_FAILED;
+ } else if (p[1] == '\0') {
+ /*
+ * The only feasible separator is a final '/';
+ * this would result in a non-empty prefix and
+ * an empty name, which POSIX doesn't
+ * explicitly forbid, but it just feels wrong.
+ */
+ archive_set_error(&a->archive, ENAMETOOLONG,
+ "Pathname too long");
+ ret = ARCHIVE_FAILED;
+ } else if (p > pp + USTAR_prefix_size) {
+ /* Prefix is too long. */
+ archive_set_error(&a->archive, ENAMETOOLONG,
+ "Pathname too long");
+ ret = ARCHIVE_FAILED;
+ } else {
+ /* Copy prefix and remainder to appropriate places */
+ memcpy(h + USTAR_prefix_offset, pp, p - pp);
+ memcpy(h + USTAR_name_offset, p + 1,
+ pp + copy_length - p - 1);
+ }
+ }
+
+ r = archive_entry_hardlink_l(entry, &p, &copy_length, sconv);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Linkname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate linkname '%s' to %s",
+ p, archive_string_conversion_charset_name(sconv));
+ ret = ARCHIVE_WARN;
+ }
+ if (copy_length > 0)
+ mytartype = '1';
+ else {
+ r = archive_entry_symlink_l(entry, &p, &copy_length, sconv);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Linkname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate linkname '%s' to %s",
+ p, archive_string_conversion_charset_name(sconv));
+ ret = ARCHIVE_WARN;
+ }
+ }
+ if (copy_length > 0) {
+ if (copy_length > USTAR_linkname_size) {
+ archive_set_error(&a->archive, ENAMETOOLONG,
+ "Link contents too long");
+ ret = ARCHIVE_FAILED;
+ copy_length = USTAR_linkname_size;
+ }
+ memcpy(h + USTAR_linkname_offset, p, copy_length);
+ }
+
+ r = archive_entry_uname_l(entry, &p, &copy_length, sconv);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Uname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate uname '%s' to %s",
+ p, archive_string_conversion_charset_name(sconv));
+ ret = ARCHIVE_WARN;
+ }
+ if (copy_length > 0) {
+ if (copy_length > USTAR_uname_size) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Username too long");
+ ret = ARCHIVE_FAILED;
+ copy_length = USTAR_uname_size;
+ }
+ memcpy(h + USTAR_uname_offset, p, copy_length);
+ }
+
+ r = archive_entry_gname_l(entry, &p, &copy_length, sconv);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Gname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate gname '%s' to %s",
+ p, archive_string_conversion_charset_name(sconv));
+ ret = ARCHIVE_WARN;
+ }
+ if (copy_length > 0) {
+ if (strlen(p) > USTAR_gname_size) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Group name too long");
+ ret = ARCHIVE_FAILED;
+ copy_length = USTAR_gname_size;
+ }
+ memcpy(h + USTAR_gname_offset, p, copy_length);
+ }
+
+ if (format_number(archive_entry_mode(entry) & 07777,
+ h + USTAR_mode_offset, USTAR_mode_size, USTAR_mode_max_size, strict)) {
+ archive_set_error(&a->archive, ERANGE,
+ "Numeric mode too large");
+ ret = ARCHIVE_FAILED;
+ }
+
+ if (format_number(archive_entry_uid(entry),
+ h + USTAR_uid_offset, USTAR_uid_size, USTAR_uid_max_size, strict)) {
+ archive_set_error(&a->archive, ERANGE,
+ "Numeric user ID too large");
+ ret = ARCHIVE_FAILED;
+ }
+
+ if (format_number(archive_entry_gid(entry),
+ h + USTAR_gid_offset, USTAR_gid_size, USTAR_gid_max_size, strict)) {
+ archive_set_error(&a->archive, ERANGE,
+ "Numeric group ID too large");
+ ret = ARCHIVE_FAILED;
+ }
+
+ if (format_number(archive_entry_size(entry),
+ h + USTAR_size_offset, USTAR_size_size, USTAR_size_max_size, strict)) {
+ archive_set_error(&a->archive, ERANGE,
+ "File size out of range");
+ ret = ARCHIVE_FAILED;
+ }
+
+ if (format_number(archive_entry_mtime(entry),
+ h + USTAR_mtime_offset, USTAR_mtime_size, USTAR_mtime_max_size, strict)) {
+ archive_set_error(&a->archive, ERANGE,
+ "File modification time too large");
+ ret = ARCHIVE_FAILED;
+ }
+
+ if (archive_entry_filetype(entry) == AE_IFBLK
+ || archive_entry_filetype(entry) == AE_IFCHR) {
+ if (format_number(archive_entry_rdevmajor(entry),
+ h + USTAR_rdevmajor_offset, USTAR_rdevmajor_size,
+ USTAR_rdevmajor_max_size, strict)) {
+ archive_set_error(&a->archive, ERANGE,
+ "Major device number too large");
+ ret = ARCHIVE_FAILED;
+ }
+
+ if (format_number(archive_entry_rdevminor(entry),
+ h + USTAR_rdevminor_offset, USTAR_rdevminor_size,
+ USTAR_rdevminor_max_size, strict)) {
+ archive_set_error(&a->archive, ERANGE,
+ "Minor device number too large");
+ ret = ARCHIVE_FAILED;
+ }
+ }
+
+ if (tartype >= 0) {
+ h[USTAR_typeflag_offset] = tartype;
+ } else if (mytartype >= 0) {
+ h[USTAR_typeflag_offset] = mytartype;
+ } else {
+ switch (archive_entry_filetype(entry)) {
+ case AE_IFREG: h[USTAR_typeflag_offset] = '0' ; break;
+ case AE_IFLNK: h[USTAR_typeflag_offset] = '2' ; break;
+ case AE_IFCHR: h[USTAR_typeflag_offset] = '3' ; break;
+ case AE_IFBLK: h[USTAR_typeflag_offset] = '4' ; break;
+ case AE_IFDIR: h[USTAR_typeflag_offset] = '5' ; break;
+ case AE_IFIFO: h[USTAR_typeflag_offset] = '6' ; break;
+ case AE_IFSOCK:
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "tar format cannot archive socket");
+ return (ARCHIVE_FAILED);
+ default:
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "tar format cannot archive this (mode=0%lo)",
+ (unsigned long)archive_entry_mode(entry));
+ ret = ARCHIVE_FAILED;
+ }
+ }
+
+ checksum = 0;
+ for (i = 0; i < 512; i++)
+ checksum += 255 & (unsigned int)h[i];
+ h[USTAR_checksum_offset + 6] = '\0'; /* Can't be pre-set in the template. */
+ /* h[USTAR_checksum_offset + 7] = ' '; */ /* This is pre-set in the template. */
+ format_octal(checksum, h + USTAR_checksum_offset, 6);
+ return (ret);
+}
+
+/*
+ * Format a number into a field, with some intelligence.
+ */
+static int
+format_number(int64_t v, char *p, int s, int maxsize, int strict)
+{
+ int64_t limit;
+
+ limit = ((int64_t)1 << (s*3));
+
+ /* "Strict" only permits octal values with proper termination. */
+ if (strict)
+ return (format_octal(v, p, s));
+
+ /*
+ * In non-strict mode, we allow the number to overwrite one or
+ * more bytes of the field termination. Even old tar
+ * implementations should be able to handle this with no
+ * problem.
+ */
+ if (v >= 0) {
+ while (s <= maxsize) {
+ if (v < limit)
+ return (format_octal(v, p, s));
+ s++;
+ limit <<= 3;
+ }
+ }
+
+ /* Base-256 can handle any number, positive or negative. */
+ return (format_256(v, p, maxsize));
+}
+
+/*
+ * Format a number into the specified field using base-256.
+ */
+static int
+format_256(int64_t v, char *p, int s)
+{
+ p += s;
+ while (s-- > 0) {
+ *--p = (char)(v & 0xff);
+ v >>= 8;
+ }
+ *p |= 0x80; /* Set the base-256 marker bit. */
+ return (0);
+}
+
+/*
+ * Format a number into the specified field.
+ */
+static int
+format_octal(int64_t v, char *p, int s)
+{
+ int len;
+
+ len = s;
+
+ /* Octal values can't be negative, so use 0. */
+ if (v < 0) {
+ while (len-- > 0)
+ *p++ = '0';
+ return (-1);
+ }
+
+ p += s; /* Start at the end and work backwards. */
+ while (s-- > 0) {
+ *--p = (char)('0' + (v & 7));
+ v >>= 3;
+ }
+
+ if (v == 0)
+ return (0);
+
+ /* If it overflowed, fill field with max value. */
+ while (len-- > 0)
+ *p++ = '7';
+
+ return (-1);
+}
+
+static int
+archive_write_ustar_close(struct archive_write *a)
+{
+ return (__archive_write_nulls(a, 512*2));
+}
+
+static int
+archive_write_ustar_free(struct archive_write *a)
+{
+ struct ustar *ustar;
+
+ ustar = (struct ustar *)a->format_data;
+ free(ustar);
+ a->format_data = NULL;
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_write_ustar_finish_entry(struct archive_write *a)
+{
+ struct ustar *ustar;
+ int ret;
+
+ ustar = (struct ustar *)a->format_data;
+ ret = __archive_write_nulls(a,
+ ustar->entry_bytes_remaining + ustar->entry_padding);
+ ustar->entry_bytes_remaining = ustar->entry_padding = 0;
+ return (ret);
+}
+
+static ssize_t
+archive_write_ustar_data(struct archive_write *a, const void *buff, size_t s)
+{
+ struct ustar *ustar;
+ int ret;
+
+ ustar = (struct ustar *)a->format_data;
+ if (s > ustar->entry_bytes_remaining)
+ s = ustar->entry_bytes_remaining;
+ ret = __archive_write_output(a, buff, s);
+ ustar->entry_bytes_remaining -= s;
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ return (s);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_xar.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_xar.c
new file mode 100644
index 000000000..96b7b2f92
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_xar.c
@@ -0,0 +1,3171 @@
+/*-
+ * Copyright (c) 2010-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"
+__FBSDID("$FreeBSD$");
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#include <stdlib.h>
+#if HAVE_LIBXML_XMLWRITER_H
+#include <libxml/xmlwriter.h>
+#endif
+#ifdef HAVE_BZLIB_H
+#include <cm_bzlib.h>
+#endif
+#if HAVE_LZMA_H
+#include <lzma.h>
+#endif
+#ifdef HAVE_ZLIB_H
+#include <cm_zlib.h>
+#endif
+
+#include "archive.h"
+#include "archive_crypto_private.h"
+#include "archive_endian.h"
+#include "archive_entry.h"
+#include "archive_entry_locale.h"
+#include "archive_private.h"
+#include "archive_rb.h"
+#include "archive_string.h"
+#include "archive_write_private.h"
+
+/*
+ * Differences to xar utility.
+ * - Subdocument is not supported yet.
+ * - ACL is not supported yet.
+ * - When writing an XML element <link type="<file-type>">, <file-type>
+ * which is a file type a symbolic link is referencing is always marked
+ * as "broken". Xar utility uses stat(2) to get the file type, but, in
+ * libarcive format writer, we should not use it; if it is needed, we
+ * should get about it at archive_read_disk.c.
+ * - It is possible to appear both <flags> and <ext2> elements.
+ * Xar utility generates <flags> on BSD platform and <ext2> on Linux
+ * platform.
+ *
+ */
+
+#if !(defined(HAVE_LIBXML_XMLWRITER_H) && defined(LIBXML_VERSION) &&\
+ LIBXML_VERSION >= 20703) ||\
+ !defined(HAVE_ZLIB_H) || \
+ !defined(ARCHIVE_HAS_MD5) || !defined(ARCHIVE_HAS_SHA1)
+/*
+ * xar needs several external libraries.
+ * o libxml2
+ * o openssl or MD5/SHA1 hash function
+ * o zlib
+ * o bzlib2 (option)
+ * o liblzma (option)
+ */
+int
+archive_write_set_format_xar(struct archive *_a)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Xar not supported on this platform");
+ return (ARCHIVE_WARN);
+}
+
+#else /* Support xar format */
+
+/*#define DEBUG_PRINT_TOC 1 */
+
+#define HEADER_MAGIC 0x78617221
+#define HEADER_SIZE 28
+#define HEADER_VERSION 1
+
+enum sumalg {
+ CKSUM_NONE = 0,
+ CKSUM_SHA1 = 1,
+ CKSUM_MD5 = 2
+};
+
+#define MD5_SIZE 16
+#define SHA1_SIZE 20
+#define MAX_SUM_SIZE 20
+#define MD5_NAME "md5"
+#define SHA1_NAME "sha1"
+
+enum enctype {
+ NONE,
+ GZIP,
+ BZIP2,
+ LZMA,
+ XZ,
+};
+
+struct chksumwork {
+ enum sumalg alg;
+#ifdef ARCHIVE_HAS_MD5
+ archive_md5_ctx md5ctx;
+#endif
+#ifdef ARCHIVE_HAS_SHA1
+ archive_sha1_ctx sha1ctx;
+#endif
+};
+
+enum la_zaction {
+ ARCHIVE_Z_FINISH,
+ ARCHIVE_Z_RUN
+};
+
+/*
+ * Universal zstream.
+ */
+struct la_zstream {
+ const unsigned char *next_in;
+ size_t avail_in;
+ uint64_t total_in;
+
+ unsigned char *next_out;
+ size_t avail_out;
+ uint64_t total_out;
+
+ int valid;
+ void *real_stream;
+ int (*code) (struct archive *a,
+ struct la_zstream *lastrm,
+ enum la_zaction action);
+ int (*end)(struct archive *a,
+ struct la_zstream *lastrm);
+};
+
+struct chksumval {
+ enum sumalg alg;
+ size_t len;
+ unsigned char val[MAX_SUM_SIZE];
+};
+
+struct heap_data {
+ int id;
+ struct heap_data *next;
+ uint64_t temp_offset;
+ uint64_t length; /* archived size. */
+ uint64_t size; /* extracted size. */
+ enum enctype compression;
+ struct chksumval a_sum; /* archived checksum. */
+ struct chksumval e_sum; /* extracted checksum. */
+};
+
+struct file {
+ struct archive_rb_node rbnode;
+
+ int id;
+ struct archive_entry *entry;
+
+ struct archive_rb_tree rbtree;
+ struct file *next;
+ struct file *chnext;
+ struct file *hlnext;
+ /* For hardlinked files.
+ * Use only when archive_entry_nlink() > 1 */
+ struct file *hardlink_target;
+ struct file *parent; /* parent directory entry */
+ /*
+ * To manage sub directory files.
+ * We use 'chnext' a menber of struct file to chain.
+ */
+ struct {
+ struct file *first;
+ struct file **last;
+ } children;
+
+ /* For making a directory tree. */
+ struct archive_string parentdir;
+ struct archive_string basename;
+ struct archive_string symlink;
+
+ int ea_idx;
+ struct {
+ struct heap_data *first;
+ struct heap_data **last;
+ } xattr;
+ struct heap_data data;
+ struct archive_string script;
+
+ int virtual:1;
+ int dir:1;
+};
+
+struct hardlink {
+ struct archive_rb_node rbnode;
+ int nlink;
+ struct {
+ struct file *first;
+ struct file **last;
+ } file_list;
+};
+
+struct xar {
+ int temp_fd;
+ uint64_t temp_offset;
+
+ int file_idx;
+ struct file *root;
+ struct file *cur_dirent;
+ struct archive_string cur_dirstr;
+ struct file *cur_file;
+ uint64_t bytes_remaining;
+ struct archive_string tstr;
+ struct archive_string vstr;
+
+ enum sumalg opt_toc_sumalg;
+ enum sumalg opt_sumalg;
+ enum enctype opt_compression;
+ int opt_compression_level;
+
+ struct chksumwork a_sumwrk; /* archived checksum. */
+ struct chksumwork e_sumwrk; /* extracted checksum. */
+ struct la_zstream stream;
+ struct archive_string_conv *sconv;
+ /*
+ * Compressed data buffer.
+ */
+ unsigned char wbuff[1024 * 64];
+ size_t wbuff_remaining;
+
+ struct heap_data toc;
+ /*
+ * The list of all file entries is used to manage struct file
+ * objects.
+ * We use 'next' a menber of struct file to chain.
+ */
+ struct {
+ struct file *first;
+ struct file **last;
+ } file_list;
+ /*
+ * The list of hard-linked file entries.
+ * We use 'hlnext' a menber of struct file to chain.
+ */
+ struct archive_rb_tree hardlink_rbtree;
+};
+
+static int xar_options(struct archive_write *,
+ const char *, const char *);
+static int xar_write_header(struct archive_write *,
+ struct archive_entry *);
+static ssize_t xar_write_data(struct archive_write *,
+ const void *, size_t);
+static int xar_finish_entry(struct archive_write *);
+static int xar_close(struct archive_write *);
+static int xar_free(struct archive_write *);
+
+static struct file *file_new(struct archive_write *a, struct archive_entry *);
+static void file_free(struct file *);
+static struct file *file_create_virtual_dir(struct archive_write *a, struct xar *,
+ const char *);
+static int file_add_child_tail(struct file *, struct file *);
+static struct file *file_find_child(struct file *, const char *);
+static int file_gen_utility_names(struct archive_write *,
+ struct file *);
+static int get_path_component(char *, int, const char *);
+static int file_tree(struct archive_write *, struct file **);
+static void file_register(struct xar *, struct file *);
+static void file_init_register(struct xar *);
+static void file_free_register(struct xar *);
+static int file_register_hardlink(struct archive_write *,
+ struct file *);
+static void file_connect_hardlink_files(struct xar *);
+static void file_init_hardlinks(struct xar *);
+static void file_free_hardlinks(struct xar *);
+
+static void checksum_init(struct chksumwork *, enum sumalg);
+static void checksum_update(struct chksumwork *, const void *, size_t);
+static void checksum_final(struct chksumwork *, struct chksumval *);
+static int compression_init_encoder_gzip(struct archive *,
+ struct la_zstream *, int, int);
+static int compression_code_gzip(struct archive *,
+ struct la_zstream *, enum la_zaction);
+static int compression_end_gzip(struct archive *, struct la_zstream *);
+static int compression_init_encoder_bzip2(struct archive *,
+ struct la_zstream *, int);
+#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
+static int compression_code_bzip2(struct archive *,
+ struct la_zstream *, enum la_zaction);
+static int compression_end_bzip2(struct archive *, struct la_zstream *);
+#endif
+static int compression_init_encoder_lzma(struct archive *,
+ struct la_zstream *, int);
+static int compression_init_encoder_xz(struct archive *,
+ struct la_zstream *, int);
+#if defined(HAVE_LZMA_H)
+static int compression_code_lzma(struct archive *,
+ struct la_zstream *, enum la_zaction);
+static int compression_end_lzma(struct archive *, struct la_zstream *);
+#endif
+static int xar_compression_init_encoder(struct archive_write *);
+static int compression_code(struct archive *,
+ struct la_zstream *, enum la_zaction);
+static int compression_end(struct archive *,
+ struct la_zstream *);
+static int save_xattrs(struct archive_write *, struct file *);
+static int getalgsize(enum sumalg);
+static const char *getalgname(enum sumalg);
+
+int
+archive_write_set_format_xar(struct archive *_a)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ struct xar *xar;
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_xar");
+
+ /* If another format was already registered, unregister it. */
+ if (a->format_free != NULL)
+ (a->format_free)(a);
+
+ xar = calloc(1, sizeof(*xar));
+ if (xar == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate xar data");
+ return (ARCHIVE_FATAL);
+ }
+ xar->temp_fd = -1;
+ file_init_register(xar);
+ file_init_hardlinks(xar);
+ archive_string_init(&(xar->tstr));
+ archive_string_init(&(xar->vstr));
+
+ /*
+ * Create the root directory.
+ */
+ xar->root = file_create_virtual_dir(a, xar, "");
+ if (xar->root == NULL) {
+ free(xar);
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate xar data");
+ return (ARCHIVE_FATAL);
+ }
+ xar->root->parent = xar->root;
+ file_register(xar, xar->root);
+ xar->cur_dirent = xar->root;
+ archive_string_init(&(xar->cur_dirstr));
+ archive_string_ensure(&(xar->cur_dirstr), 1);
+ xar->cur_dirstr.s[0] = 0;
+
+ /*
+ * Initialize option.
+ */
+ /* Set default checksum type. */
+ xar->opt_toc_sumalg = CKSUM_SHA1;
+ xar->opt_sumalg = CKSUM_SHA1;
+ /* Set default compression type and level. */
+ xar->opt_compression = GZIP;
+ xar->opt_compression_level = 6;
+
+ a->format_data = xar;
+
+ a->format_name = "xar";
+ a->format_options = xar_options;
+ a->format_write_header = xar_write_header;
+ a->format_write_data = xar_write_data;
+ a->format_finish_entry = xar_finish_entry;
+ a->format_close = xar_close;
+ a->format_free = xar_free;
+ a->archive.archive_format = ARCHIVE_FORMAT_XAR;
+ a->archive.archive_format_name = "xar";
+
+ return (ARCHIVE_OK);
+}
+
+static int
+xar_options(struct archive_write *a, const char *key, const char *value)
+{
+ struct xar *xar;
+
+ xar = (struct xar *)a->format_data;
+
+ if (strcmp(key, "checksum") == 0) {
+ if (value == NULL)
+ xar->opt_sumalg = CKSUM_NONE;
+ else if (strcmp(value, "sha1") == 0)
+ xar->opt_sumalg = CKSUM_SHA1;
+ else if (strcmp(value, "md5") == 0)
+ xar->opt_sumalg = CKSUM_MD5;
+ else {
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "Unkonwn checksum name: `%s'",
+ value);
+ return (ARCHIVE_FAILED);
+ }
+ return (ARCHIVE_OK);
+ }
+ if (strcmp(key, "compression") == 0) {
+ const char *name = NULL;
+
+ if (value == NULL)
+ xar->opt_compression = NONE;
+ else if (strcmp(value, "gzip") == 0)
+ xar->opt_compression = GZIP;
+ else if (strcmp(value, "bzip2") == 0)
+#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
+ xar->opt_compression = BZIP2;
+#else
+ name = "bzip2";
+#endif
+ else if (strcmp(value, "lzma") == 0)
+#if HAVE_LZMA_H
+ xar->opt_compression = LZMA;
+#else
+ name = "lzma";
+#endif
+ else if (strcmp(value, "xz") == 0)
+#if HAVE_LZMA_H
+ xar->opt_compression = XZ;
+#else
+ name = "xz";
+#endif
+ else {
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "Unkonwn compression name: `%s'",
+ value);
+ return (ARCHIVE_FAILED);
+ }
+ if (name != NULL) {
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "`%s' compression not supported "
+ "on this platform",
+ name);
+ return (ARCHIVE_FAILED);
+ }
+ return (ARCHIVE_OK);
+ }
+ if (strcmp(key, "compression-level") == 0) {
+ if (value == NULL ||
+ !(value[0] >= '0' && value[0] <= '9') ||
+ value[1] != '\0') {
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "Illeagal value `%s'",
+ value);
+ return (ARCHIVE_FAILED);
+ }
+ xar->opt_compression_level = value[0] - '0';
+ return (ARCHIVE_OK);
+ }
+ if (strcmp(key, "toc-checksum") == 0) {
+ if (value == NULL)
+ xar->opt_toc_sumalg = CKSUM_NONE;
+ else if (strcmp(value, "sha1") == 0)
+ xar->opt_toc_sumalg = CKSUM_SHA1;
+ else if (strcmp(value, "md5") == 0)
+ xar->opt_toc_sumalg = CKSUM_MD5;
+ else {
+ archive_set_error(&(a->archive),
+ ARCHIVE_ERRNO_MISC,
+ "Unkonwn checksum name: `%s'",
+ value);
+ return (ARCHIVE_FAILED);
+ }
+ return (ARCHIVE_OK);
+ }
+
+ return (ARCHIVE_FAILED);
+}
+
+static int
+xar_write_header(struct archive_write *a, struct archive_entry *entry)
+{
+ struct xar *xar;
+ struct file *file;
+ struct archive_entry *file_entry;
+ int r, r2;
+
+ xar = (struct xar *)a->format_data;
+ xar->cur_file = NULL;
+ xar->bytes_remaining = 0;
+
+ if (xar->sconv == NULL) {
+ xar->sconv = archive_string_conversion_to_charset(
+ &a->archive, "UTF-8", 1);
+ if (xar->sconv == NULL)
+ return (ARCHIVE_FATAL);
+ }
+
+ file = file_new(a, entry);
+ if (file == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate data");
+ return (ARCHIVE_FATAL);
+ }
+ r2 = file_gen_utility_names(a, file);
+ if (r2 < ARCHIVE_WARN)
+ return (r2);
+
+ /*
+ * Ignore a path which looks like the top of directory name
+ * since we have already made the root directory of an Xar archive.
+ */
+ if (archive_strlen(&(file->parentdir)) == 0 &&
+ archive_strlen(&(file->basename)) == 0) {
+ file_free(file);
+ return (r2);
+ }
+
+ /* Add entry into tree */
+ file_entry = file->entry;
+ r = file_tree(a, &file);
+ if (r != ARCHIVE_OK)
+ return (r);
+ /* There is the same file in tree and
+ * the current file is older than the file in tree.
+ * So we don't need the current file data anymore. */
+ if (file->entry != file_entry)
+ return (r2);
+ if (file->id == 0)
+ file_register(xar, file);
+
+ /* A virtual file, which is a directory, does not have
+ * any contents and we won't store it into a archive
+ * file other than its name. */
+ if (file->virtual)
+ return (r2);
+
+ /*
+ * Prepare to save the contents of the file.
+ */
+ if (xar->temp_fd == -1) {
+ int algsize;
+ xar->temp_offset = 0;
+ xar->temp_fd = __archive_mktemp(NULL);
+ if (xar->temp_fd < 0) {
+ archive_set_error(&a->archive, errno,
+ "Couldn't create temporary file");
+ return (ARCHIVE_FATAL);
+ }
+ algsize = getalgsize(xar->opt_toc_sumalg);
+ if (algsize > 0) {
+ if (lseek(xar->temp_fd, algsize, SEEK_SET) < 0) {
+ archive_set_error(&(a->archive), errno,
+ "lseek failed");
+ return (ARCHIVE_FATAL);
+ }
+ xar->temp_offset = algsize;
+ }
+ }
+
+ if (archive_entry_hardlink(file->entry) == NULL) {
+ r = save_xattrs(a, file);
+ if (r != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
+
+ /* Non regular files contents are unneeded to be saved to
+ * a temporary file. */
+ if (archive_entry_filetype(file->entry) != AE_IFREG)
+ return (r2);
+
+ /*
+ * Set the current file to cur_file to read its contents.
+ */
+ xar->cur_file = file;
+
+ if (archive_entry_nlink(file->entry) > 1) {
+ r = file_register_hardlink(a, file);
+ if (r != ARCHIVE_OK)
+ return (r);
+ if (archive_entry_hardlink(file->entry) != NULL) {
+ archive_entry_unset_size(file->entry);
+ return (r2);
+ }
+ }
+
+ /* Save a offset of current file in temporary file. */
+ file->data.temp_offset = xar->temp_offset;
+ file->data.size = archive_entry_size(file->entry);
+ file->data.compression = xar->opt_compression;
+ xar->bytes_remaining = archive_entry_size(file->entry);
+ checksum_init(&(xar->a_sumwrk), xar->opt_sumalg);
+ checksum_init(&(xar->e_sumwrk), xar->opt_sumalg);
+ r = xar_compression_init_encoder(a);
+
+ if (r != ARCHIVE_OK)
+ return (r);
+ else
+ return (r2);
+}
+
+static int
+write_to_temp(struct archive_write *a, const void *buff, size_t s)
+{
+ struct xar *xar;
+ unsigned char *p;
+ ssize_t ws;
+
+ xar = (struct xar *)a->format_data;
+ p = (unsigned char *)buff;
+ while (s) {
+ ws = write(xar->temp_fd, p, s);
+ if (ws < 0) {
+ archive_set_error(&(a->archive), errno,
+ "fwrite function failed");
+ return (ARCHIVE_FATAL);
+ }
+ s -= ws;
+ p += ws;
+ xar->temp_offset += ws;
+ }
+ return (ARCHIVE_OK);
+}
+
+static ssize_t
+xar_write_data(struct archive_write *a, const void *buff, size_t s)
+{
+ struct xar *xar;
+ enum la_zaction run;
+ size_t size, rsize;
+ int r;
+
+ xar = (struct xar *)a->format_data;
+
+ if (s > xar->bytes_remaining)
+ s = xar->bytes_remaining;
+ if (s == 0 || xar->cur_file == NULL)
+ return (0);
+ if (xar->cur_file->data.compression == NONE) {
+ checksum_update(&(xar->e_sumwrk), buff, s);
+ checksum_update(&(xar->a_sumwrk), buff, s);
+ size = rsize = s;
+ } else {
+ xar->stream.next_in = (const unsigned char *)buff;
+ xar->stream.avail_in = s;
+ if (xar->bytes_remaining > s)
+ run = ARCHIVE_Z_RUN;
+ else
+ run = ARCHIVE_Z_FINISH;
+ /* Compress file data. */
+ r = compression_code(&(a->archive), &(xar->stream), run);
+ if (r != ARCHIVE_OK && r != ARCHIVE_EOF)
+ return (ARCHIVE_FATAL);
+ rsize = s - xar->stream.avail_in;
+ checksum_update(&(xar->e_sumwrk), buff, rsize);
+ size = sizeof(xar->wbuff) - xar->stream.avail_out;
+ checksum_update(&(xar->a_sumwrk), xar->wbuff, size);
+ }
+#if !defined(_WIN32) || defined(__CYGWIN__)
+ if (xar->bytes_remaining ==
+ archive_entry_size(xar->cur_file->entry)) {
+ /*
+ * Get the path of a shell script if so.
+ */
+ const unsigned char *b = (const unsigned char *)buff;
+
+ archive_string_empty(&(xar->cur_file->script));
+ if (rsize > 2 && b[0] == '#' && b[1] == '!') {
+ size_t i, end, off;
+
+ off = 2;
+ if (b[off] == ' ')
+ off++;
+#ifdef PATH_MAX
+ if ((rsize - off) > PATH_MAX)
+ end = off + PATH_MAX;
+ else
+#endif
+ end = rsize;
+ /* Find the end of a script path. */
+ for (i = off; i < end && b[i] != '\0' &&
+ b[i] != '\n' && b[i] != '\r' &&
+ b[i] != ' ' && b[i] != '\t'; i++)
+ ;
+ archive_strncpy(&(xar->cur_file->script), b + off,
+ i - off);
+ }
+ }
+#endif
+
+ if (xar->cur_file->data.compression == NONE) {
+ if (write_to_temp(a, buff, size) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ } else {
+ if (write_to_temp(a, xar->wbuff, size) != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
+ xar->bytes_remaining -= rsize;
+ xar->cur_file->data.length += size;
+
+ return (rsize);
+}
+
+static int
+xar_finish_entry(struct archive_write *a)
+{
+ struct xar *xar;
+ struct file *file;
+ size_t s;
+ ssize_t w;
+
+ xar = (struct xar *)a->format_data;
+ if (xar->cur_file == NULL)
+ return (ARCHIVE_OK);
+
+ while (xar->bytes_remaining > 0) {
+ s = xar->bytes_remaining;
+ if (s > a->null_length)
+ s = a->null_length;
+ w = xar_write_data(a, a->nulls, s);
+ if (w > 0)
+ xar->bytes_remaining -= w;
+ else
+ return (w);
+ }
+ file = xar->cur_file;
+ checksum_final(&(xar->e_sumwrk), &(file->data.e_sum));
+ checksum_final(&(xar->a_sumwrk), &(file->data.a_sum));
+ xar->cur_file = NULL;
+
+ return (ARCHIVE_OK);
+}
+
+static int
+xmlwrite_string_attr(struct archive_write *a, xmlTextWriterPtr writer,
+ const char *key, const char *value,
+ const char *attrkey, const char *attrvalue)
+{
+ int r;
+
+ r = xmlTextWriterStartElement(writer, BAD_CAST(key));
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterStartElement() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+ if (attrkey != NULL && attrvalue != NULL) {
+ r = xmlTextWriterWriteAttribute(writer,
+ BAD_CAST(attrkey), BAD_CAST(attrvalue));
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterWriteAttribute() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+ }
+ if (value != NULL) {
+ r = xmlTextWriterWriteString(writer, BAD_CAST(value));
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterWriteString() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+ }
+ r = xmlTextWriterEndElement(writer);
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterEndElement() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+xmlwrite_string(struct archive_write *a, xmlTextWriterPtr writer,
+ const char *key, const char *value)
+{
+ int r;
+
+ if (value == NULL)
+ return (ARCHIVE_OK);
+
+ r = xmlTextWriterStartElement(writer, BAD_CAST(key));
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterStartElement() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+ if (value != NULL) {
+ r = xmlTextWriterWriteString(writer, BAD_CAST(value));
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterWriteString() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+ }
+ r = xmlTextWriterEndElement(writer);
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterEndElement() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+xmlwrite_fstring(struct archive_write *a, xmlTextWriterPtr writer,
+ const char *key, const char *fmt, ...)
+{
+ struct xar *xar;
+ va_list ap;
+
+ xar = (struct xar *)a->format_data;
+ va_start(ap, fmt);
+ archive_string_empty(&xar->vstr);
+ archive_string_vsprintf(&xar->vstr, fmt, ap);
+ va_end(ap);
+ return (xmlwrite_string(a, writer, key, xar->vstr.s));
+}
+
+static int
+xmlwrite_time(struct archive_write *a, xmlTextWriterPtr writer,
+ const char *key, time_t t, int z)
+{
+ char timestr[100];
+ struct tm tm;
+
+#if defined(HAVE_GMTIME_R)
+ gmtime_r(&t, &tm);
+#elif defined(HAVE__GMTIME64_S)
+ _gmtime64_s(&tm, &t);
+#else
+ memcpy(&tm, gmtime(&t), sizeof(tm));
+#endif
+ memset(&timestr, 0, sizeof(timestr));
+ /* Do not use %F and %T for portability. */
+ strftime(timestr, sizeof(timestr), "%Y-%m-%dT%H:%M:%S", &tm);
+ if (z)
+ strcat(timestr, "Z");
+ return (xmlwrite_string(a, writer, key, timestr));
+}
+
+static int
+xmlwrite_mode(struct archive_write *a, xmlTextWriterPtr writer,
+ const char *key, mode_t mode)
+{
+ char ms[5];
+
+ ms[0] = '0';
+ ms[1] = '0' + ((mode >> 6) & 07);
+ ms[2] = '0' + ((mode >> 3) & 07);
+ ms[3] = '0' + (mode & 07);
+ ms[4] = '\0';
+
+ return (xmlwrite_string(a, writer, key, ms));
+}
+
+static int
+xmlwrite_sum(struct archive_write *a, xmlTextWriterPtr writer,
+ const char *key, struct chksumval *sum)
+{
+ const char *algname;
+ int algsize;
+ char buff[MAX_SUM_SIZE*2 + 1];
+ char *p;
+ unsigned char *s;
+ int i, r;
+
+ if (sum->len > 0) {
+ algname = getalgname(sum->alg);
+ algsize = getalgsize(sum->alg);
+ if (algname != NULL) {
+ const char *hex = "0123456789abcdef";
+ p = buff;
+ s = sum->val;
+ for (i = 0; i < algsize; i++) {
+ *p++ = hex[(*s >> 4)];
+ *p++ = hex[(*s & 0x0f)];
+ s++;
+ }
+ *p = '\0';
+ r = xmlwrite_string_attr(a, writer,
+ key, buff,
+ "style", algname);
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ }
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+xmlwrite_heap(struct archive_write *a, xmlTextWriterPtr writer,
+ struct heap_data *heap)
+{
+ const char *encname;
+ int r;
+
+ r = xmlwrite_fstring(a, writer, "length", "%ju", heap->length);
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ r = xmlwrite_fstring(a, writer, "offset", "%ju", heap->temp_offset);
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ r = xmlwrite_fstring(a, writer, "size", "%ju", heap->size);
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ switch (heap->compression) {
+ case GZIP:
+ encname = "application/x-gzip"; break;
+ case BZIP2:
+ encname = "application/x-bzip2"; break;
+ case LZMA:
+ encname = "application/x-lzma"; break;
+ case XZ:
+ encname = "application/x-xz"; break;
+ default:
+ encname = "application/octet-stream"; break;
+ }
+ r = xmlwrite_string_attr(a, writer, "encoding", NULL,
+ "style", encname);
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ r = xmlwrite_sum(a, writer, "archived-checksum", &(heap->a_sum));
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ r = xmlwrite_sum(a, writer, "extracted-checksum", &(heap->e_sum));
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ return (ARCHIVE_OK);
+}
+
+/*
+ * xar utility records fflags as following xml elements:
+ * <flags>
+ * <UserNoDump/>
+ * .....
+ * </flags>
+ * or
+ * <ext2>
+ * <NoDump/>
+ * .....
+ * </ext2>
+ * If xar is running on BSD platform, records <flags>..</flags>;
+ * if xar is running on linux platform, records <ext2>..</ext2>;
+ * otherwise does not record.
+ *
+ * Our implements records both <flags> and <ext2> if it's necessary.
+ */
+static int
+make_fflags_entry(struct archive_write *a, xmlTextWriterPtr writer,
+ const char *element, const char *fflags_text)
+{
+ static const struct flagentry {
+ const char *name;
+ const char *xarname;
+ }
+ flagbsd[] = {
+ { "sappnd", "SystemAppend"},
+ { "sappend", "SystemAppend"},
+ { "arch", "SystemArchived"},
+ { "archived", "SystemArchived"},
+ { "schg", "SystemImmutable"},
+ { "schange", "SystemImmutable"},
+ { "simmutable", "SystemImmutable"},
+ { "nosunlnk", "SystemNoUnlink"},
+ { "nosunlink", "SystemNoUnlink"},
+ { "snapshot", "SystemSnapshot"},
+ { "uappnd", "UserAppend"},
+ { "uappend", "UserAppend"},
+ { "uchg", "UserImmutable"},
+ { "uchange", "UserImmutable"},
+ { "uimmutable", "UserImmutable"},
+ { "nodump", "UserNoDump"},
+ { "noopaque", "UserOpaque"},
+ { "nouunlnk", "UserNoUnlink"},
+ { "nouunlink", "UserNoUnlink"},
+ { NULL, NULL}
+ },
+ flagext2[] = {
+ { "sappnd", "AppendOnly"},
+ { "sappend", "AppendOnly"},
+ { "schg", "Immutable"},
+ { "schange", "Immutable"},
+ { "simmutable", "Immutable"},
+ { "nodump", "NoDump"},
+ { "nouunlnk", "Undelete"},
+ { "nouunlink", "Undelete"},
+ { "btree", "BTree"},
+ { "comperr", "CompError"},
+ { "compress", "Compress"},
+ { "noatime", "NoAtime"},
+ { "compdirty", "CompDirty"},
+ { "comprblk", "CompBlock"},
+ { "dirsync", "DirSync"},
+ { "hashidx", "HashIndexed"},
+ { "imagic", "iMagic"},
+ { "journal", "Journaled"},
+ { "securedeletion", "SecureDeletion"},
+ { "sync", "Synchronous"},
+ { "notail", "NoTail"},
+ { "topdir", "TopDir"},
+ { "reserved", "Reserved"},
+ { NULL, NULL}
+ };
+ const struct flagentry *fe, *flagentry;
+#define FLAGENTRY_MAXSIZE ((sizeof(flagbsd)+sizeof(flagext2))/sizeof(flagbsd))
+ const struct flagentry *avail[FLAGENTRY_MAXSIZE];
+ const char *p;
+ int i, n, r;
+
+ if (strcmp(element, "ext2") == 0)
+ flagentry = flagext2;
+ else
+ flagentry = flagbsd;
+ n = 0;
+ p = fflags_text;
+ do {
+ const char *cp;
+
+ cp = strchr(p, ',');
+ if (cp == NULL)
+ cp = p + strlen(p);
+
+ for (fe = flagentry; fe->name != NULL; fe++) {
+ if (fe->name[cp - p] != '\0'
+ || p[0] != fe->name[0])
+ continue;
+ if (strncmp(p, fe->name, cp - p) == 0) {
+ avail[n++] = fe;
+ break;
+ }
+ }
+ if (*cp == ',')
+ p = cp + 1;
+ else
+ p = NULL;
+ } while (p != NULL);
+
+ if (n > 0) {
+ r = xmlTextWriterStartElement(writer, BAD_CAST(element));
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterStartElement() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+ for (i = 0; i < n; i++) {
+ r = xmlwrite_string(a, writer,
+ avail[i]->xarname, NULL);
+ if (r != ARCHIVE_OK)
+ return (r);
+ }
+
+ r = xmlTextWriterEndElement(writer);
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterEndElement() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+make_file_entry(struct archive_write *a, xmlTextWriterPtr writer,
+ struct file *file)
+{
+ struct xar *xar;
+ const char *filetype, *filelink, *fflags;
+ struct archive_string linkto;
+ struct heap_data *heap;
+ unsigned char *tmp;
+ const char *p;
+ size_t len;
+ int r, r2, l, ll;
+
+ xar = (struct xar *)a->format_data;
+ r2 = ARCHIVE_OK;
+
+ /*
+ * Make a file name entry, "<name>".
+ */
+ l = ll = archive_strlen(&(file->basename));
+ tmp = malloc(l);
+ if (tmp == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+ r = UTF8Toisolat1(tmp, &l, BAD_CAST(file->basename.s), &ll);
+ free(tmp);
+ if (r < 0) {
+ r = xmlTextWriterStartElement(writer, BAD_CAST("name"));
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterStartElement() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+ r = xmlTextWriterWriteAttribute(writer,
+ BAD_CAST("enctype"), BAD_CAST("base64"));
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterWriteAttribute() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+ r = xmlTextWriterWriteBase64(writer, file->basename.s,
+ 0, archive_strlen(&(file->basename)));
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterWriteBase64() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+ r = xmlTextWriterEndElement(writer);
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterEndElement() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+ } else {
+ r = xmlwrite_string(a, writer, "name", file->basename.s);
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ }
+
+ /*
+ * Make a file type entry, "<type>".
+ */
+ filelink = NULL;
+ archive_string_init(&linkto);
+ switch (archive_entry_filetype(file->entry)) {
+ case AE_IFDIR:
+ filetype = "directory"; break;
+ case AE_IFLNK:
+ filetype = "symlink"; break;
+ case AE_IFCHR:
+ filetype = "character special"; break;
+ case AE_IFBLK:
+ filetype = "block special"; break;
+ case AE_IFSOCK:
+ filetype = "socket"; break;
+ case AE_IFIFO:
+ filetype = "fifo"; break;
+ case AE_IFREG:
+ default:
+ if (file->hardlink_target != NULL) {
+ filetype = "hardlink";
+ filelink = "link";
+ if (file->hardlink_target == file)
+ archive_strcpy(&linkto, "original");
+ else
+ archive_string_sprintf(&linkto, "%d",
+ file->hardlink_target->id);
+ } else
+ filetype = "file";
+ break;
+ }
+ r = xmlwrite_string_attr(a, writer, "type", filetype,
+ filelink, linkto.s);
+ archive_string_free(&linkto);
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+
+ /*
+ * On a virtual directory, we record "name" and "type" only.
+ */
+ if (file->virtual)
+ return (ARCHIVE_OK);
+
+ switch (archive_entry_filetype(file->entry)) {
+ case AE_IFLNK:
+ /*
+ * xar utility has checked a file type, which
+ * a symblic-link file has referenced.
+ * For example:
+ * <link type="directory">../ref/</link>
+ * The symlink target file is "../ref/" and its
+ * file type is a directory.
+ *
+ * <link type="file">../f</link>
+ * The symlink target file is "../f" and its
+ * file type is a regular file.
+ *
+ * But our implemention cannot do it, and then we
+ * always record that a attribute "type" is "borken",
+ * for example:
+ * <link type="broken">foo/bar</link>
+ * It means "foo/bar" is not reachable.
+ */
+ r = xmlwrite_string_attr(a, writer, "link",
+ file->symlink.s,
+ "type", "broken");
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ break;
+ case AE_IFCHR:
+ case AE_IFBLK:
+ r = xmlTextWriterStartElement(writer, BAD_CAST("device"));
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterStartElement() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+ r = xmlwrite_fstring(a, writer, "major",
+ "%d", archive_entry_rdevmajor(file->entry));
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ r = xmlwrite_fstring(a, writer, "minor",
+ "%d", archive_entry_rdevminor(file->entry));
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ r = xmlTextWriterEndElement(writer);
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterEndElement() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+ break;
+ default:
+ break;
+ }
+
+ /*
+ * Make a inode entry, "<inode>".
+ */
+ r = xmlwrite_fstring(a, writer, "inode",
+ "%jd", archive_entry_ino64(file->entry));
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ if (archive_entry_dev(file->entry) != 0) {
+ r = xmlwrite_fstring(a, writer, "deviceno",
+ "%d", archive_entry_dev(file->entry));
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ }
+
+ /*
+ * Make a file mode entry, "<mode>".
+ */
+ r = xmlwrite_mode(a, writer, "mode",
+ archive_entry_mode(file->entry));
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+
+ /*
+ * Make a user entry, "<uid>" and "<user>.
+ */
+ r = xmlwrite_fstring(a, writer, "uid",
+ "%d", archive_entry_uid(file->entry));
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ r = archive_entry_uname_l(file->entry, &p, &len, xar->sconv);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Uname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate uname '%s' to UTF-8",
+ archive_entry_uname(file->entry));
+ r2 = ARCHIVE_WARN;
+ }
+ if (len > 0) {
+ r = xmlwrite_string(a, writer, "user", p);
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ }
+
+ /*
+ * Make a group entry, "<gid>" and "<group>.
+ */
+ r = xmlwrite_fstring(a, writer, "gid",
+ "%d", archive_entry_gid(file->entry));
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ r = archive_entry_gname_l(file->entry, &p, &len, xar->sconv);
+ if (r != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Gname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate gname '%s' to UTF-8",
+ archive_entry_gname(file->entry));
+ r2 = ARCHIVE_WARN;
+ }
+ if (len > 0) {
+ r = xmlwrite_string(a, writer, "group", p);
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ }
+
+ /*
+ * Make a ctime entry, "<ctime>".
+ */
+ if (archive_entry_ctime_is_set(file->entry)) {
+ r = xmlwrite_time(a, writer, "ctime",
+ archive_entry_ctime(file->entry), 1);
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ }
+
+ /*
+ * Make a mtime entry, "<mtime>".
+ */
+ if (archive_entry_mtime_is_set(file->entry)) {
+ r = xmlwrite_time(a, writer, "mtime",
+ archive_entry_mtime(file->entry), 1);
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ }
+
+ /*
+ * Make a atime entry, "<atime>".
+ */
+ if (archive_entry_atime_is_set(file->entry)) {
+ r = xmlwrite_time(a, writer, "atime",
+ archive_entry_atime(file->entry), 1);
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ }
+
+ /*
+ * Make fflags entries, "<flags>" and "<ext2>".
+ */
+ fflags = archive_entry_fflags_text(file->entry);
+ if (fflags != NULL) {
+ r = make_fflags_entry(a, writer, "flags", fflags);
+ if (r < 0)
+ return (r);
+ r = make_fflags_entry(a, writer, "ext2", fflags);
+ if (r < 0)
+ return (r);
+ }
+
+ /*
+ * Make extended attribute entries, "<ea>".
+ */
+ archive_entry_xattr_reset(file->entry);
+ for (heap = file->xattr.first; heap != NULL; heap = heap->next) {
+ const char *name;
+ const void *value;
+ size_t size;
+
+ archive_entry_xattr_next(file->entry,
+ &name, &value, &size);
+ r = xmlTextWriterStartElement(writer, BAD_CAST("ea"));
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterStartElement() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+ r = xmlTextWriterWriteFormatAttribute(writer,
+ BAD_CAST("id"), "%d", heap->id);
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterWriteAttribute() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+ r = xmlwrite_heap(a, writer, heap);
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+ r = xmlwrite_string(a, writer, "name", name);
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+
+ r = xmlTextWriterEndElement(writer);
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterEndElement() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ /*
+ * Make a file data entry, "<data>".
+ */
+ if (file->data.length > 0) {
+ r = xmlTextWriterStartElement(writer, BAD_CAST("data"));
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterStartElement() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+
+ r = xmlwrite_heap(a, writer, &(file->data));
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+
+ r = xmlTextWriterEndElement(writer);
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterEndElement() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ if (archive_strlen(&file->script) > 0) {
+ r = xmlTextWriterStartElement(writer, BAD_CAST("content"));
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterStartElement() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+
+ r = xmlwrite_string(a, writer,
+ "interpreter", file->script.s);
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+
+ r = xmlwrite_string(a, writer, "type", "script");
+ if (r < 0)
+ return (ARCHIVE_FATAL);
+
+ r = xmlTextWriterEndElement(writer);
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterEndElement() failed: %d", r);
+ return (ARCHIVE_FATAL);
+ }
+ }
+
+ return (r2);
+}
+
+/*
+ * Make the TOC
+ */
+static int
+make_toc(struct archive_write *a)
+{
+ struct xar *xar;
+ struct file *np;
+ xmlBufferPtr bp;
+ xmlTextWriterPtr writer;
+ int algsize;
+ int r, ret;
+
+ xar = (struct xar *)a->format_data;
+
+ ret = ARCHIVE_FATAL;
+
+ /*
+ * Initialize xml writer.
+ */
+ writer = NULL;
+ bp = xmlBufferCreate();
+ if (bp == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "xmlBufferCreate() "
+ "couldn't create xml buffer");
+ goto exit_toc;
+ }
+ writer = xmlNewTextWriterMemory(bp, 0);
+ if (writer == NULL) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlNewTextWriterMemory() "
+ "couldn't create xml writer");
+ goto exit_toc;
+ }
+ r = xmlTextWriterStartDocument(writer, "1.0", "UTF-8", NULL);
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterStartDocument() failed: %d", r);
+ goto exit_toc;
+ }
+ r = xmlTextWriterSetIndent(writer, 4);
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterSetIndent() failed: %d", r);
+ goto exit_toc;
+ }
+
+ /*
+ * Start recoding TOC
+ */
+ r = xmlTextWriterStartElement(writer, BAD_CAST("xar"));
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterStartElement() failed: %d", r);
+ goto exit_toc;
+ }
+ r = xmlTextWriterStartElement(writer, BAD_CAST("toc"));
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterStartDocument() failed: %d", r);
+ goto exit_toc;
+ }
+
+ /*
+ * Record the creation time of the archive file.
+ */
+ r = xmlwrite_time(a, writer, "creation-time", time(NULL), 0);
+ if (r < 0)
+ goto exit_toc;
+
+ /*
+ * Record the checksum value of TOC
+ */
+ algsize = getalgsize(xar->opt_toc_sumalg);
+ if (algsize) {
+ /*
+ * Record TOC checksum
+ */
+ r = xmlTextWriterStartElement(writer, BAD_CAST("checksum"));
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterStartElement() failed: %d", r);
+ goto exit_toc;
+ }
+ r = xmlTextWriterWriteAttribute(writer, BAD_CAST("style"),
+ BAD_CAST(getalgname(xar->opt_toc_sumalg)));
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterWriteAttribute() failed: %d", r);
+ goto exit_toc;
+ }
+
+ /*
+ * Record the offset of the value of checksum of TOC
+ */
+ r = xmlwrite_string(a, writer, "offset", "0");
+ if (r < 0)
+ goto exit_toc;
+
+ /*
+ * Record the size of the value of checksum of TOC
+ */
+ r = xmlwrite_fstring(a, writer, "size", "%d", algsize);
+ if (r < 0)
+ goto exit_toc;
+
+ r = xmlTextWriterEndElement(writer);
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterEndElement() failed: %d", r);
+ goto exit_toc;
+ }
+ }
+
+ np = xar->root;
+ do {
+ if (np != np->parent) {
+ r = make_file_entry(a, writer, np);
+ if (r != ARCHIVE_OK)
+ goto exit_toc;
+ }
+
+ if (np->dir && np->children.first != NULL) {
+ /* Enter to sub directories. */
+ np = np->children.first;
+ r = xmlTextWriterStartElement(writer,
+ BAD_CAST("file"));
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterStartElement() "
+ "failed: %d", r);
+ goto exit_toc;
+ }
+ r = xmlTextWriterWriteFormatAttribute(
+ writer, BAD_CAST("id"), "%d", np->id);
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterWriteAttribute() "
+ "failed: %d", r);
+ goto exit_toc;
+ }
+ continue;
+ }
+ while (np != np->parent) {
+ r = xmlTextWriterEndElement(writer);
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterEndElement() "
+ "failed: %d", r);
+ goto exit_toc;
+ }
+ if (np->chnext == NULL) {
+ /* Return to the parent directory. */
+ np = np->parent;
+ } else {
+ np = np->chnext;
+ r = xmlTextWriterStartElement(writer,
+ BAD_CAST("file"));
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterStartElement() "
+ "failed: %d", r);
+ goto exit_toc;
+ }
+ r = xmlTextWriterWriteFormatAttribute(
+ writer, BAD_CAST("id"), "%d", np->id);
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterWriteAttribute() "
+ "failed: %d", r);
+ goto exit_toc;
+ }
+ break;
+ }
+ }
+ } while (np != np->parent);
+
+ r = xmlTextWriterEndDocument(writer);
+ if (r < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "xmlTextWriterEndDocument() failed: %d", r);
+ goto exit_toc;
+ }
+#if DEBUG_PRINT_TOC
+ fprintf(stderr, "\n---TOC-- %d bytes --\n%s\n",
+ strlen((const char *)bp->content), bp->content);
+#endif
+
+ /*
+ * Compress the TOC and calculate the sum of the TOC.
+ */
+ xar->toc.temp_offset = xar->temp_offset;
+ xar->toc.size = bp->use;
+ checksum_init(&(xar->a_sumwrk), xar->opt_toc_sumalg);
+
+ r = compression_init_encoder_gzip(&(a->archive),
+ &(xar->stream), 6, 1);
+ if (r != ARCHIVE_OK)
+ goto exit_toc;
+ xar->stream.next_in = bp->content;
+ xar->stream.avail_in = bp->use;
+ xar->stream.total_in = 0;
+ xar->stream.next_out = xar->wbuff;
+ xar->stream.avail_out = sizeof(xar->wbuff);
+ xar->stream.total_out = 0;
+ for (;;) {
+ size_t size;
+
+ r = compression_code(&(a->archive),
+ &(xar->stream), ARCHIVE_Z_FINISH);
+ if (r != ARCHIVE_OK && r != ARCHIVE_EOF)
+ goto exit_toc;
+ size = sizeof(xar->wbuff) - xar->stream.avail_out;
+ checksum_update(&(xar->a_sumwrk), xar->wbuff, size);
+ if (write_to_temp(a, xar->wbuff, size) != ARCHIVE_OK)
+ goto exit_toc;
+ if (r == ARCHIVE_EOF)
+ break;
+ xar->stream.next_out = xar->wbuff;
+ xar->stream.avail_out = sizeof(xar->wbuff);
+ }
+ r = compression_end(&(a->archive), &(xar->stream));
+ if (r != ARCHIVE_OK)
+ goto exit_toc;
+ xar->toc.length = xar->stream.total_out;
+ xar->toc.compression = GZIP;
+ checksum_final(&(xar->a_sumwrk), &(xar->toc.a_sum));
+
+ ret = ARCHIVE_OK;
+exit_toc:
+ if (writer)
+ xmlFreeTextWriter(writer);
+ if (bp)
+ xmlBufferFree(bp);
+
+ return (ret);
+}
+
+static int
+flush_wbuff(struct archive_write *a)
+{
+ struct xar *xar;
+ int r;
+ size_t s;
+
+ xar = (struct xar *)a->format_data;
+ s = sizeof(xar->wbuff) - xar->wbuff_remaining;
+ r = __archive_write_output(a, xar->wbuff, s);
+ if (r != ARCHIVE_OK)
+ return (r);
+ xar->wbuff_remaining = sizeof(xar->wbuff);
+ return (r);
+}
+
+static int
+copy_out(struct archive_write *a, uint64_t offset, uint64_t length)
+{
+ struct xar *xar;
+ int r;
+
+ xar = (struct xar *)a->format_data;
+ if (lseek(xar->temp_fd, offset, SEEK_SET) < 0) {
+ archive_set_error(&(a->archive), errno, "lseek failed");
+ return (ARCHIVE_FATAL);
+ }
+ while (length) {
+ size_t rsize;
+ ssize_t rs;
+ unsigned char *wb;
+
+ if (length > xar->wbuff_remaining)
+ rsize = xar->wbuff_remaining;
+ else
+ rsize = (size_t)length;
+ wb = xar->wbuff + (sizeof(xar->wbuff) - xar->wbuff_remaining);
+ rs = read(xar->temp_fd, wb, rsize);
+ if (rs < 0) {
+ archive_set_error(&(a->archive), errno,
+ "Can't read temporary file(%jd)",
+ (intmax_t)rs);
+ return (ARCHIVE_FATAL);
+ }
+ if (rs == 0) {
+ archive_set_error(&(a->archive), 0,
+ "Truncated xar archive");
+ return (ARCHIVE_FATAL);
+ }
+ xar->wbuff_remaining -= rs;
+ length -= rs;
+ if (xar->wbuff_remaining == 0) {
+ r = flush_wbuff(a);
+ if (r != ARCHIVE_OK)
+ return (r);
+ }
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+xar_close(struct archive_write *a)
+{
+ struct xar *xar;
+ unsigned char *wb;
+ uint64_t length;
+ int r;
+
+ xar = (struct xar *)a->format_data;
+
+ /* Empty! */
+ if (xar->root->children.first == NULL)
+ return (ARCHIVE_OK);
+
+ /* Save the length of all file extended attributes and contents. */
+ length = xar->temp_offset;
+
+ /* Connect hardlinked files */
+ file_connect_hardlink_files(xar);
+
+ /* Make the TOC */
+ r = make_toc(a);
+ if (r != ARCHIVE_OK)
+ return (r);
+ /*
+ * Make the xar header on wbuff(write buffer).
+ */
+ wb = xar->wbuff;
+ xar->wbuff_remaining = sizeof(xar->wbuff);
+ archive_be32enc(&wb[0], HEADER_MAGIC);
+ archive_be16enc(&wb[4], HEADER_SIZE);
+ archive_be16enc(&wb[6], HEADER_VERSION);
+ archive_be64enc(&wb[8], xar->toc.length);
+ archive_be64enc(&wb[16], xar->toc.size);
+ archive_be32enc(&wb[24], xar->toc.a_sum.alg);
+ xar->wbuff_remaining -= HEADER_SIZE;
+
+ /*
+ * Write the TOC
+ */
+ r = copy_out(a, xar->toc.temp_offset, xar->toc.length);
+ if (r != ARCHIVE_OK)
+ return (r);
+
+ /* Write the checksum value of the TOC. */
+ if (xar->toc.a_sum.len) {
+ if (xar->wbuff_remaining < xar->toc.a_sum.len) {
+ r = flush_wbuff(a);
+ if (r != ARCHIVE_OK)
+ return (r);
+ }
+ wb = xar->wbuff + (sizeof(xar->wbuff) - xar->wbuff_remaining);
+ memcpy(wb, xar->toc.a_sum.val, xar->toc.a_sum.len);
+ xar->wbuff_remaining -= xar->toc.a_sum.len;
+ }
+
+ /*
+ * Write all file extended attributes and contents.
+ */
+ r = copy_out(a, xar->toc.a_sum.len, length);
+ if (r != ARCHIVE_OK)
+ return (r);
+ r = flush_wbuff(a);
+ return (r);
+}
+
+static int
+xar_free(struct archive_write *a)
+{
+ struct xar *xar;
+
+ xar = (struct xar *)a->format_data;
+ archive_string_free(&(xar->cur_dirstr));
+ archive_string_free(&(xar->tstr));
+ archive_string_free(&(xar->vstr));
+ file_free_hardlinks(xar);
+ file_free_register(xar);
+ compression_end(&(a->archive), &(xar->stream));
+ free(xar);
+
+ return (ARCHIVE_OK);
+}
+
+static int
+file_cmp_node(const struct archive_rb_node *n1,
+ const struct archive_rb_node *n2)
+{
+ struct file *f1 = (struct file *)n1;
+ struct file *f2 = (struct file *)n2;
+
+ return (strcmp(f1->basename.s, f2->basename.s));
+}
+
+static int
+file_cmp_key(const struct archive_rb_node *n, const void *key)
+{
+ struct file *f = (struct file *)n;
+
+ return (strcmp(f->basename.s, (const char *)key));
+}
+
+static struct file *
+file_new(struct archive_write *a, struct archive_entry *entry)
+{
+ struct file *file;
+ static const struct archive_rb_tree_ops rb_ops = {
+ file_cmp_node, file_cmp_key
+ };
+
+ file = calloc(1, sizeof(*file));
+ if (file == NULL)
+ return (NULL);
+
+ if (entry != NULL)
+ file->entry = archive_entry_clone(entry);
+ else
+ file->entry = archive_entry_new2(&a->archive);
+ if (file->entry == NULL) {
+ free(file);
+ return (NULL);
+ }
+ __archive_rb_tree_init(&(file->rbtree), &rb_ops);
+ file->children.first = NULL;
+ file->children.last = &(file->children.first);
+ file->xattr.first = NULL;
+ file->xattr.last = &(file->xattr.first);
+ archive_string_init(&(file->parentdir));
+ archive_string_init(&(file->basename));
+ archive_string_init(&(file->symlink));
+ archive_string_init(&(file->script));
+ if (entry != NULL && archive_entry_filetype(entry) == AE_IFDIR)
+ file->dir = 1;
+
+ return (file);
+}
+
+static void
+file_free(struct file *file)
+{
+ struct heap_data *heap, *next_heap;
+
+ heap = file->xattr.first;
+ while (heap != NULL) {
+ next_heap = heap->next;
+ free(heap);
+ heap = next_heap;
+ }
+ archive_string_free(&(file->parentdir));
+ archive_string_free(&(file->basename));
+ archive_string_free(&(file->symlink));
+ archive_string_free(&(file->script));
+ free(file);
+}
+
+static struct file *
+file_create_virtual_dir(struct archive_write *a, struct xar *xar,
+ const char *pathname)
+{
+ struct file *file;
+
+ file = file_new(a, NULL);
+ if (file == NULL)
+ return (NULL);
+ archive_entry_set_pathname(file->entry, pathname);
+ archive_entry_set_mode(file->entry, 0555 | AE_IFDIR);
+
+ file->dir = 1;
+ file->virtual = 1;
+
+ return (file);
+}
+
+static int
+file_add_child_tail(struct file *parent, struct file *child)
+{
+ if (!__archive_rb_tree_insert_node(
+ &(parent->rbtree), (struct archive_rb_node *)child))
+ return (0);
+ child->chnext = NULL;
+ *parent->children.last = child;
+ parent->children.last = &(child->chnext);
+ child->parent = parent;
+ return (1);
+}
+
+/*
+ * Find a entry from `parent'
+ */
+static struct file *
+file_find_child(struct file *parent, const char *child_name)
+{
+ struct file *np;
+
+ np = (struct file *)__archive_rb_tree_find_node(
+ &(parent->rbtree), child_name);
+ return (np);
+}
+
+#if defined(_WIN32) || defined(__CYGWIN__)
+static void
+cleanup_backslash(char *utf8, size_t len)
+{
+
+ /* Convert a path-separator from '\' to '/' */
+ while (*utf8 != '\0' && len) {
+ if (*utf8 == '\\')
+ *utf8 = '/';
+ ++utf8;
+ --len;
+ }
+}
+#else
+#define cleanup_backslash(p, len) /* nop */
+#endif
+
+/*
+ * Generate a parent directory name and a base name from a pathname.
+ */
+static int
+file_gen_utility_names(struct archive_write *a, struct file *file)
+{
+ struct xar *xar;
+ const char *pp;
+ char *p, *dirname, *slash;
+ size_t len;
+ int r = ARCHIVE_OK;
+
+ xar = (struct xar *)a->format_data;
+ archive_string_empty(&(file->parentdir));
+ archive_string_empty(&(file->basename));
+ archive_string_empty(&(file->symlink));
+
+ if (file->parent == file)/* virtual root */
+ return (ARCHIVE_OK);
+
+ if (archive_entry_pathname_l(file->entry, &pp, &len, xar->sconv)
+ != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Pathname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate pathname '%s' to UTF-8",
+ archive_entry_pathname(file->entry));
+ r = ARCHIVE_WARN;
+ }
+ archive_strncpy(&(file->parentdir), pp, len);
+ len = file->parentdir.length;
+ p = dirname = file->parentdir.s;
+ /*
+ * Convert a path-separator from '\' to '/'
+ */
+ cleanup_backslash(p, len);
+
+ /*
+ * Remove leading '/', '../' and './' elements
+ */
+ while (*p) {
+ if (p[0] == '/') {
+ p++;
+ len--;
+ } else if (p[0] != '.')
+ break;
+ else if (p[1] == '.' && p[2] == '/') {
+ p += 3;
+ len -= 3;
+ } else if (p[1] == '/' || (p[1] == '.' && p[2] == '\0')) {
+ p += 2;
+ len -= 2;
+ } else if (p[1] == '\0') {
+ p++;
+ len--;
+ } else
+ break;
+ }
+ if (p != dirname) {
+ memmove(dirname, p, len+1);
+ p = dirname;
+ }
+ /*
+ * Remove "/","/." and "/.." elements from tail.
+ */
+ while (len > 0) {
+ size_t ll = len;
+
+ if (len > 0 && p[len-1] == '/') {
+ p[len-1] = '\0';
+ len--;
+ }
+ if (len > 1 && p[len-2] == '/' && p[len-1] == '.') {
+ p[len-2] = '\0';
+ len -= 2;
+ }
+ if (len > 2 && p[len-3] == '/' && p[len-2] == '.' &&
+ p[len-1] == '.') {
+ p[len-3] = '\0';
+ len -= 3;
+ }
+ if (ll == len)
+ break;
+ }
+ while (*p) {
+ if (p[0] == '/') {
+ if (p[1] == '/')
+ /* Convert '//' --> '/' */
+ strcpy(p, p+1);
+ else if (p[1] == '.' && p[2] == '/')
+ /* Convert '/./' --> '/' */
+ strcpy(p, p+2);
+ else if (p[1] == '.' && p[2] == '.' && p[3] == '/') {
+ /* Convert 'dir/dir1/../dir2/'
+ * --> 'dir/dir2/'
+ */
+ char *rp = p -1;
+ while (rp >= dirname) {
+ if (*rp == '/')
+ break;
+ --rp;
+ }
+ if (rp > dirname) {
+ strcpy(rp, p+3);
+ p = rp;
+ } else {
+ strcpy(dirname, p+4);
+ p = dirname;
+ }
+ } else
+ p++;
+ } else
+ p++;
+ }
+ p = dirname;
+ len = strlen(p);
+
+ if (archive_entry_filetype(file->entry) == AE_IFLNK) {
+ size_t len2;
+ /* Convert symlink name too. */
+ if (archive_entry_symlink_l(file->entry, &pp, &len2,
+ xar->sconv) != 0) {
+ if (errno == ENOMEM) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Linkname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate symlink '%s' to UTF-8",
+ archive_entry_symlink(file->entry));
+ r = ARCHIVE_WARN;
+ }
+ archive_strncpy(&(file->symlink), pp, len2);
+ cleanup_backslash(file->symlink.s, file->symlink.length);
+ }
+ /*
+ * - Count up directory elements.
+ * - Find out the position which points the last position of
+ * path separator('/').
+ */
+ slash = NULL;
+ for (; *p != '\0'; p++)
+ if (*p == '/')
+ slash = p;
+ if (slash == NULL) {
+ /* The pathname doesn't have a parent directory. */
+ file->parentdir.length = len;
+ archive_string_copy(&(file->basename), &(file->parentdir));
+ archive_string_empty(&(file->parentdir));
+ file->parentdir.s = '\0';
+ return (r);
+ }
+
+ /* Make a basename from dirname and slash */
+ *slash = '\0';
+ file->parentdir.length = slash - dirname;
+ archive_strcpy(&(file->basename), slash + 1);
+ return (r);
+}
+
+static int
+get_path_component(char *name, int n, const char *fn)
+{
+ char *p;
+ int l;
+
+ p = strchr(fn, '/');
+ if (p == NULL) {
+ if ((l = strlen(fn)) == 0)
+ return (0);
+ } else
+ l = p - fn;
+ if (l > n -1)
+ return (-1);
+ memcpy(name, fn, l);
+ name[l] = '\0';
+
+ return (l);
+}
+
+/*
+ * Add a new entry into the tree.
+ */
+static int
+file_tree(struct archive_write *a, struct file **filepp)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ char name[_MAX_FNAME];/* Included null terminator size. */
+#elif defined(NAME_MAX) && NAME_MAX >= 255
+ char name[NAME_MAX+1];
+#else
+ char name[256];
+#endif
+ struct xar *xar = (struct xar *)a->format_data;
+ struct file *dent, *file, *np;
+ struct archive_entry *ent;
+ const char *fn, *p;
+ int l;
+
+ file = *filepp;
+ dent = xar->root;
+ if (file->parentdir.length > 0)
+ fn = p = file->parentdir.s;
+ else
+ fn = p = "";
+
+ /*
+ * If the path of the parent directory of `file' entry is
+ * the same as the path of `cur_dirent', add isoent to
+ * `cur_dirent'.
+ */
+ if (archive_strlen(&(xar->cur_dirstr))
+ == archive_strlen(&(file->parentdir)) &&
+ strcmp(xar->cur_dirstr.s, fn) == 0) {
+ if (!file_add_child_tail(xar->cur_dirent, file)) {
+ np = (struct file *)__archive_rb_tree_find_node(
+ &(xar->cur_dirent->rbtree),
+ file->basename.s);
+ goto same_entry;
+ }
+ return (ARCHIVE_OK);
+ }
+
+ for (;;) {
+ l = get_path_component(name, sizeof(name), fn);
+ if (l == 0) {
+ np = NULL;
+ break;
+ }
+ if (l < 0) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "A name buffer is too small");
+ file_free(file);
+ *filepp = NULL;
+ return (ARCHIVE_FATAL);
+ }
+
+ np = file_find_child(dent, name);
+ if (np == NULL || fn[0] == '\0')
+ break;
+
+ /* Find next subdirectory. */
+ if (!np->dir) {
+ /* NOT Directory! */
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "`%s' is not directory, we cannot insert `%s' ",
+ archive_entry_pathname(np->entry),
+ archive_entry_pathname(file->entry));
+ file_free(file);
+ *filepp = NULL;
+ return (ARCHIVE_FAILED);
+ }
+ fn += l;
+ if (fn[0] == '/')
+ fn++;
+ dent = np;
+ }
+ if (np == NULL) {
+ /*
+ * Create virtual parent directories.
+ */
+ while (fn[0] != '\0') {
+ struct file *vp;
+ struct archive_string as;
+
+ archive_string_init(&as);
+ archive_strncat(&as, p, fn - p + l);
+ if (as.s[as.length-1] == '/') {
+ as.s[as.length-1] = '\0';
+ as.length--;
+ }
+ vp = file_create_virtual_dir(a, xar, as.s);
+ if (vp == NULL) {
+ archive_string_free(&as);
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory");
+ file_free(file);
+ *filepp = NULL;
+ return (ARCHIVE_FATAL);
+ }
+ archive_string_free(&as);
+ if (file_gen_utility_names(a, vp) <= ARCHIVE_FAILED)
+ return (ARCHIVE_FATAL);
+ file_add_child_tail(dent, vp);
+ file_register(xar, vp);
+ np = vp;
+
+ fn += l;
+ if (fn[0] == '/')
+ fn++;
+ l = get_path_component(name, sizeof(name), fn);
+ if (l < 0) {
+ archive_string_free(&as);
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "A name buffer is too small");
+ file_free(file);
+ *filepp = NULL;
+ return (ARCHIVE_FATAL);
+ }
+ dent = np;
+ }
+
+ /* Found out the parent directory where isoent can be
+ * inserted. */
+ xar->cur_dirent = dent;
+ archive_string_empty(&(xar->cur_dirstr));
+ archive_string_ensure(&(xar->cur_dirstr),
+ archive_strlen(&(dent->parentdir)) +
+ archive_strlen(&(dent->basename)) + 2);
+ if (archive_strlen(&(dent->parentdir)) +
+ archive_strlen(&(dent->basename)) == 0)
+ xar->cur_dirstr.s[0] = 0;
+ else {
+ if (archive_strlen(&(dent->parentdir)) > 0) {
+ archive_string_copy(&(xar->cur_dirstr),
+ &(dent->parentdir));
+ archive_strappend_char(&(xar->cur_dirstr), '/');
+ }
+ archive_string_concat(&(xar->cur_dirstr),
+ &(dent->basename));
+ }
+
+ if (!file_add_child_tail(dent, file)) {
+ np = (struct file *)__archive_rb_tree_find_node(
+ &(dent->rbtree), file->basename.s);
+ goto same_entry;
+ }
+ return (ARCHIVE_OK);
+ }
+
+same_entry:
+ /*
+ * We have already has the entry the filename of which is
+ * the same.
+ */
+ if (archive_entry_filetype(np->entry) !=
+ archive_entry_filetype(file->entry)) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Found duplicate entries `%s' and its file type is "
+ "different",
+ archive_entry_pathname(np->entry));
+ file_free(file);
+ *filepp = NULL;
+ return (ARCHIVE_FAILED);
+ }
+
+ /* Swap files. */
+ ent = np->entry;
+ np->entry = file->entry;
+ file->entry = ent;
+ np->virtual = 0;
+
+ file_free(file);
+ *filepp = np;
+ return (ARCHIVE_OK);
+}
+
+static void
+file_register(struct xar *xar, struct file *file)
+{
+ file->id = xar->file_idx++;
+ file->next = NULL;
+ *xar->file_list.last = file;
+ xar->file_list.last = &(file->next);
+}
+
+static void
+file_init_register(struct xar *xar)
+{
+ xar->file_list.first = NULL;
+ xar->file_list.last = &(xar->file_list.first);
+}
+
+static void
+file_free_register(struct xar *xar)
+{
+ struct file *file, *file_next;
+
+ file = xar->file_list.first;
+ while (file != NULL) {
+ file_next = file->next;
+ file_free(file);
+ file = file_next;
+ }
+}
+
+/*
+ * Register entry to get a hardlink target.
+ */
+static int
+file_register_hardlink(struct archive_write *a, struct file *file)
+{
+ struct xar *xar = (struct xar *)a->format_data;
+ struct hardlink *hl;
+ const char *pathname;
+
+ archive_entry_set_nlink(file->entry, 1);
+ pathname = archive_entry_hardlink(file->entry);
+ if (pathname == NULL) {
+ /* This `file` is a hardlink target. */
+ hl = malloc(sizeof(*hl));
+ if (hl == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory");
+ return (ARCHIVE_FATAL);
+ }
+ hl->nlink = 1;
+ /* A hardlink target must be the first position. */
+ file->hlnext = NULL;
+ hl->file_list.first = file;
+ hl->file_list.last = &(file->hlnext);
+ __archive_rb_tree_insert_node(&(xar->hardlink_rbtree),
+ (struct archive_rb_node *)hl);
+ } else {
+ hl = (struct hardlink *)__archive_rb_tree_find_node(
+ &(xar->hardlink_rbtree), pathname);
+ if (hl != NULL) {
+ /* Insert `file` entry into the tail. */
+ file->hlnext = NULL;
+ *hl->file_list.last = file;
+ hl->file_list.last = &(file->hlnext);
+ hl->nlink++;
+ }
+ archive_entry_unset_size(file->entry);
+ }
+
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Hardlinked files have to have the same location of extent.
+ * We have to find out hardlink target entries for entries which
+ * have a hardlink target name.
+ */
+static void
+file_connect_hardlink_files(struct xar *xar)
+{
+ struct archive_rb_node *n;
+ struct hardlink *hl;
+ struct file *target, *nf;
+
+ ARCHIVE_RB_TREE_FOREACH(n, &(xar->hardlink_rbtree)) {
+ hl = (struct hardlink *)n;
+
+ /* The first entry must be a hardlink target. */
+ target = hl->file_list.first;
+ archive_entry_set_nlink(target->entry, hl->nlink);
+ if (hl->nlink > 1)
+ /* It means this file is a hardlink
+ * targe itself. */
+ target->hardlink_target = target;
+ for (nf = target->hlnext;
+ nf != NULL; nf = nf->hlnext) {
+ nf->hardlink_target = target;
+ archive_entry_set_nlink(nf->entry, hl->nlink);
+ }
+ }
+}
+
+static int
+file_hd_cmp_node(const struct archive_rb_node *n1,
+ const struct archive_rb_node *n2)
+{
+ struct hardlink *h1 = (struct hardlink *)n1;
+ struct hardlink *h2 = (struct hardlink *)n2;
+
+ return (strcmp(archive_entry_pathname(h1->file_list.first->entry),
+ archive_entry_pathname(h2->file_list.first->entry)));
+}
+
+static int
+file_hd_cmp_key(const struct archive_rb_node *n, const void *key)
+{
+ struct hardlink *h = (struct hardlink *)n;
+
+ return (strcmp(archive_entry_pathname(h->file_list.first->entry),
+ (const char *)key));
+}
+
+
+static void
+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);
+}
+
+static void
+file_free_hardlinks(struct xar *xar)
+{
+ struct archive_rb_node *n, *next;
+
+ for (n = ARCHIVE_RB_TREE_MIN(&(xar->hardlink_rbtree)); n;) {
+ next = __archive_rb_tree_iterate(&(xar->hardlink_rbtree),
+ n, ARCHIVE_RB_DIR_RIGHT);
+ free(n);
+ n = next;
+ }
+}
+
+static void
+checksum_init(struct chksumwork *sumwrk, enum sumalg sum_alg)
+{
+ sumwrk->alg = sum_alg;
+ switch (sum_alg) {
+ case CKSUM_NONE:
+ break;
+ case CKSUM_SHA1:
+ archive_sha1_init(&(sumwrk->sha1ctx));
+ break;
+ case CKSUM_MD5:
+ archive_md5_init(&(sumwrk->md5ctx));
+ break;
+ }
+}
+
+static void
+checksum_update(struct chksumwork *sumwrk, const void *buff, size_t size)
+{
+
+ switch (sumwrk->alg) {
+ case CKSUM_NONE:
+ break;
+ case CKSUM_SHA1:
+ archive_sha1_update(&(sumwrk->sha1ctx), buff, size);
+ break;
+ case CKSUM_MD5:
+ archive_md5_update(&(sumwrk->md5ctx), buff, size);
+ break;
+ }
+}
+
+static void
+checksum_final(struct chksumwork *sumwrk, struct chksumval *sumval)
+{
+
+ switch (sumwrk->alg) {
+ case CKSUM_NONE:
+ sumval->len = 0;
+ break;
+ case CKSUM_SHA1:
+ archive_sha1_final(&(sumwrk->sha1ctx), sumval->val);
+ sumval->len = SHA1_SIZE;
+ break;
+ case CKSUM_MD5:
+ archive_md5_final(&(sumwrk->md5ctx), sumval->val);
+ sumval->len = MD5_SIZE;
+ break;
+ }
+ sumval->alg = sumwrk->alg;
+}
+
+#if !defined(HAVE_BZLIB_H) || !defined(BZ_CONFIG_ERROR) || !defined(HAVE_LZMA_H)
+static int
+compression_unsupported_encoder(struct archive *a,
+ struct la_zstream *lastrm, const char *name)
+{
+
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "%s compression not supported on this platform", name);
+ lastrm->valid = 0;
+ lastrm->real_stream = NULL;
+ return (ARCHIVE_FAILED);
+}
+#endif
+
+static int
+compression_init_encoder_gzip(struct archive *a,
+ struct la_zstream *lastrm, int level, int withheader)
+{
+ z_stream *strm;
+
+ if (lastrm->valid)
+ compression_end(a, lastrm);
+ strm = calloc(1, sizeof(*strm));
+ if (strm == NULL) {
+ archive_set_error(a, ENOMEM,
+ "Can't allocate memory for gzip stream");
+ return (ARCHIVE_FATAL);
+ }
+ /* zlib.h is not const-correct, so we need this one bit
+ * of ugly hackery to convert a const * pointer to
+ * a non-const pointer. */
+ strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in;
+ strm->avail_in = lastrm->avail_in;
+ strm->total_in = lastrm->total_in;
+ strm->next_out = lastrm->next_out;
+ strm->avail_out = lastrm->avail_out;
+ strm->total_out = lastrm->total_out;
+ if (deflateInit2(strm, level, Z_DEFLATED,
+ (withheader)?15:-15,
+ 8, Z_DEFAULT_STRATEGY) != Z_OK) {
+ free(strm);
+ lastrm->real_stream = NULL;
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Internal error initializing compression library");
+ return (ARCHIVE_FATAL);
+ }
+ lastrm->real_stream = strm;
+ lastrm->valid = 1;
+ lastrm->code = compression_code_gzip;
+ lastrm->end = compression_end_gzip;
+ return (ARCHIVE_OK);
+}
+
+static int
+compression_code_gzip(struct archive *a,
+ struct la_zstream *lastrm, enum la_zaction action)
+{
+ z_stream *strm;
+ int r;
+
+ strm = (z_stream *)lastrm->real_stream;
+ /* zlib.h is not const-correct, so we need this one bit
+ * of ugly hackery to convert a const * pointer to
+ * a non-const pointer. */
+ strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in;
+ strm->avail_in = lastrm->avail_in;
+ strm->total_in = lastrm->total_in;
+ strm->next_out = lastrm->next_out;
+ strm->avail_out = lastrm->avail_out;
+ strm->total_out = lastrm->total_out;
+ r = deflate(strm,
+ (action == ARCHIVE_Z_FINISH)? Z_FINISH: Z_NO_FLUSH);
+ lastrm->next_in = strm->next_in;
+ lastrm->avail_in = strm->avail_in;
+ lastrm->total_in = strm->total_in;
+ lastrm->next_out = strm->next_out;
+ lastrm->avail_out = strm->avail_out;
+ lastrm->total_out = strm->total_out;
+ switch (r) {
+ case Z_OK:
+ return (ARCHIVE_OK);
+ case Z_STREAM_END:
+ return (ARCHIVE_EOF);
+ default:
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "GZip compression failed:"
+ " deflate() call returned status %d", r);
+ return (ARCHIVE_FATAL);
+ }
+}
+
+static int
+compression_end_gzip(struct archive *a, struct la_zstream *lastrm)
+{
+ z_stream *strm;
+ int r;
+
+ strm = (z_stream *)lastrm->real_stream;
+ r = deflateEnd(strm);
+ free(strm);
+ lastrm->real_stream = NULL;
+ lastrm->valid = 0;
+ if (r != Z_OK) {
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Failed to clean up compressor");
+ return (ARCHIVE_FATAL);
+ }
+ return (ARCHIVE_OK);
+}
+
+#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
+static int
+compression_init_encoder_bzip2(struct archive *a,
+ struct la_zstream *lastrm, int level)
+{
+ bz_stream *strm;
+
+ if (lastrm->valid)
+ compression_end(a, lastrm);
+ strm = calloc(1, sizeof(*strm));
+ if (strm == NULL) {
+ archive_set_error(a, ENOMEM,
+ "Can't allocate memory for bzip2 stream");
+ return (ARCHIVE_FATAL);
+ }
+ /* bzlib.h is not const-correct, so we need this one bit
+ * of ugly hackery to convert a const * pointer to
+ * a non-const pointer. */
+ strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in;
+ strm->avail_in = lastrm->avail_in;
+ strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff);
+ strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32);
+ strm->next_out = (char *)lastrm->next_out;
+ strm->avail_out = lastrm->avail_out;
+ strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff);
+ strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32);
+ if (BZ2_bzCompressInit(strm, level, 0, 30) != BZ_OK) {
+ free(strm);
+ lastrm->real_stream = NULL;
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Internal error initializing compression library");
+ return (ARCHIVE_FATAL);
+ }
+ lastrm->real_stream = strm;
+ lastrm->valid = 1;
+ lastrm->code = compression_code_bzip2;
+ lastrm->end = compression_end_bzip2;
+ return (ARCHIVE_OK);
+}
+
+static int
+compression_code_bzip2(struct archive *a,
+ struct la_zstream *lastrm, enum la_zaction action)
+{
+ bz_stream *strm;
+ int r;
+
+ strm = (bz_stream *)lastrm->real_stream;
+ /* bzlib.h is not const-correct, so we need this one bit
+ * of ugly hackery to convert a const * pointer to
+ * a non-const pointer. */
+ strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in;
+ strm->avail_in = lastrm->avail_in;
+ strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff);
+ strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32);
+ strm->next_out = (char *)lastrm->next_out;
+ strm->avail_out = lastrm->avail_out;
+ strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff);
+ strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32);
+ r = BZ2_bzCompress(strm,
+ (action == ARCHIVE_Z_FINISH)? BZ_FINISH: BZ_RUN);
+ lastrm->next_in = (const unsigned char *)strm->next_in;
+ lastrm->avail_in = strm->avail_in;
+ lastrm->total_in =
+ (((uint64_t)(uint32_t)strm->total_in_hi32) << 32)
+ + (uint64_t)(uint32_t)strm->total_in_lo32;
+ lastrm->next_out = (unsigned char *)strm->next_out;
+ lastrm->avail_out = strm->avail_out;
+ lastrm->total_out =
+ (((uint64_t)(uint32_t)strm->total_out_hi32) << 32)
+ + (uint64_t)(uint32_t)strm->total_out_lo32;
+ switch (r) {
+ case BZ_RUN_OK: /* Non-finishing */
+ case BZ_FINISH_OK: /* Finishing: There's more work to do */
+ return (ARCHIVE_OK);
+ case BZ_STREAM_END: /* Finishing: all done */
+ /* Only occurs in finishing case */
+ return (ARCHIVE_EOF);
+ default:
+ /* Any other return value indicates an error */
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Bzip2 compression failed:"
+ " BZ2_bzCompress() call returned status %d", r);
+ return (ARCHIVE_FATAL);
+ }
+}
+
+static int
+compression_end_bzip2(struct archive *a, struct la_zstream *lastrm)
+{
+ bz_stream *strm;
+ int r;
+
+ strm = (bz_stream *)lastrm->real_stream;
+ r = BZ2_bzCompressEnd(strm);
+ free(strm);
+ lastrm->real_stream = NULL;
+ lastrm->valid = 0;
+ if (r != BZ_OK) {
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Failed to clean up compressor");
+ return (ARCHIVE_FATAL);
+ }
+ return (ARCHIVE_OK);
+}
+
+#else
+static int
+compression_init_encoder_bzip2(struct archive *a,
+ struct la_zstream *lastrm, int level)
+{
+
+ (void) level; /* UNUSED */
+ if (lastrm->valid)
+ compression_end(a, lastrm);
+ return (compression_unsupported_encoder(a, lastrm, "bzip2"));
+}
+#endif
+
+#if defined(HAVE_LZMA_H)
+static int
+compression_init_encoder_lzma(struct archive *a,
+ struct la_zstream *lastrm, int level)
+{
+ static const lzma_stream lzma_init_data = LZMA_STREAM_INIT;
+ lzma_stream *strm;
+ lzma_options_lzma lzma_opt;
+ int r;
+
+ if (lastrm->valid)
+ compression_end(a, lastrm);
+ if (lzma_lzma_preset(&lzma_opt, level)) {
+ lastrm->real_stream = NULL;
+ archive_set_error(a, ENOMEM,
+ "Internal error initializing compression library");
+ return (ARCHIVE_FATAL);
+ }
+ strm = calloc(1, sizeof(*strm));
+ if (strm == NULL) {
+ archive_set_error(a, ENOMEM,
+ "Can't allocate memory for lzma stream");
+ return (ARCHIVE_FATAL);
+ }
+ *strm = lzma_init_data;
+ r = lzma_alone_encoder(strm, &lzma_opt);
+ switch (r) {
+ case LZMA_OK:
+ lastrm->real_stream = strm;
+ lastrm->valid = 1;
+ lastrm->code = compression_code_lzma;
+ lastrm->end = compression_end_lzma;
+ r = ARCHIVE_OK;
+ break;
+ case LZMA_MEM_ERROR:
+ free(strm);
+ lastrm->real_stream = NULL;
+ archive_set_error(a, ENOMEM,
+ "Internal error initializing compression library: "
+ "Cannot allocate memory");
+ r = ARCHIVE_FATAL;
+ break;
+ default:
+ free(strm);
+ lastrm->real_stream = NULL;
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Internal error initializing compression library: "
+ "It's a bug in liblzma");
+ r = ARCHIVE_FATAL;
+ break;
+ }
+ return (r);
+}
+
+static int
+compression_init_encoder_xz(struct archive *a,
+ struct la_zstream *lastrm, int level)
+{
+ static const lzma_stream lzma_init_data = LZMA_STREAM_INIT;
+ lzma_stream *strm;
+ lzma_filter *lzmafilters;
+ lzma_options_lzma lzma_opt;
+ int r;
+
+ if (lastrm->valid)
+ compression_end(a, lastrm);
+ strm = calloc(1, sizeof(*strm) + sizeof(*lzmafilters) * 2);
+ if (strm == NULL) {
+ archive_set_error(a, ENOMEM,
+ "Can't allocate memory for xz stream");
+ return (ARCHIVE_FATAL);
+ }
+ lzmafilters = (lzma_filter *)(strm+1);
+ if (level > 6)
+ level = 6;
+ if (lzma_lzma_preset(&lzma_opt, level)) {
+ lastrm->real_stream = NULL;
+ archive_set_error(a, ENOMEM,
+ "Internal error initializing compression library");
+ return (ARCHIVE_FATAL);
+ }
+ lzmafilters[0].id = LZMA_FILTER_LZMA2;
+ lzmafilters[0].options = &lzma_opt;
+ lzmafilters[1].id = LZMA_VLI_UNKNOWN;/* Terminate */
+
+ *strm = lzma_init_data;
+ r = lzma_stream_encoder(strm, lzmafilters, LZMA_CHECK_CRC64);
+ switch (r) {
+ case LZMA_OK:
+ lastrm->real_stream = strm;
+ lastrm->valid = 1;
+ lastrm->code = compression_code_lzma;
+ lastrm->end = compression_end_lzma;
+ r = ARCHIVE_OK;
+ break;
+ case LZMA_MEM_ERROR:
+ free(strm);
+ lastrm->real_stream = NULL;
+ archive_set_error(a, ENOMEM,
+ "Internal error initializing compression library: "
+ "Cannot allocate memory");
+ r = ARCHIVE_FATAL;
+ break;
+ default:
+ free(strm);
+ lastrm->real_stream = NULL;
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "Internal error initializing compression library: "
+ "It's a bug in liblzma");
+ r = ARCHIVE_FATAL;
+ break;
+ }
+ return (r);
+}
+
+static int
+compression_code_lzma(struct archive *a,
+ struct la_zstream *lastrm, enum la_zaction action)
+{
+ lzma_stream *strm;
+ int r;
+
+ strm = (lzma_stream *)lastrm->real_stream;
+ strm->next_in = lastrm->next_in;
+ strm->avail_in = lastrm->avail_in;
+ strm->total_in = lastrm->total_in;
+ strm->next_out = lastrm->next_out;
+ strm->avail_out = lastrm->avail_out;
+ strm->total_out = lastrm->total_out;
+ r = lzma_code(strm,
+ (action == ARCHIVE_Z_FINISH)? LZMA_FINISH: LZMA_RUN);
+ lastrm->next_in = strm->next_in;
+ lastrm->avail_in = strm->avail_in;
+ lastrm->total_in = strm->total_in;
+ lastrm->next_out = strm->next_out;
+ lastrm->avail_out = strm->avail_out;
+ lastrm->total_out = strm->total_out;
+ switch (r) {
+ case LZMA_OK:
+ /* Non-finishing case */
+ return (ARCHIVE_OK);
+ case LZMA_STREAM_END:
+ /* This return can only occur in finishing case. */
+ return (ARCHIVE_EOF);
+ case LZMA_MEMLIMIT_ERROR:
+ archive_set_error(a, ENOMEM,
+ "lzma compression error:"
+ " %ju MiB would have been needed",
+ (uintmax_t)((lzma_memusage(strm) + 1024 * 1024 -1)
+ / (1024 * 1024)));
+ return (ARCHIVE_FATAL);
+ default:
+ /* Any other return value indicates an error */
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ "lzma compression failed:"
+ " lzma_code() call returned status %d", r);
+ return (ARCHIVE_FATAL);
+ }
+}
+
+static int
+compression_end_lzma(struct archive *a, struct la_zstream *lastrm)
+{
+ lzma_stream *strm;
+
+ (void)a; /* UNUSED */
+ strm = (lzma_stream *)lastrm->real_stream;
+ lzma_end(strm);
+ free(strm);
+ lastrm->valid = 0;
+ lastrm->real_stream = NULL;
+ return (ARCHIVE_OK);
+}
+#else
+static int
+compression_init_encoder_lzma(struct archive *a,
+ struct la_zstream *lastrm, int level)
+{
+
+ (void) level; /* UNUSED */
+ if (lastrm->valid)
+ compression_end(a, lastrm);
+ return (compression_unsupported_encoder(a, lastrm, "lzma"));
+}
+static int
+compression_init_encoder_xz(struct archive *a,
+ struct la_zstream *lastrm, int level)
+{
+
+ (void) level; /* UNUSED */
+ if (lastrm->valid)
+ compression_end(a, lastrm);
+ return (compression_unsupported_encoder(a, lastrm, "xz"));
+}
+#endif
+
+static int
+xar_compression_init_encoder(struct archive_write *a)
+{
+ struct xar *xar;
+ int r;
+
+ xar = (struct xar *)a->format_data;
+ switch (xar->opt_compression) {
+ case GZIP:
+ r = compression_init_encoder_gzip(
+ &(a->archive), &(xar->stream),
+ xar->opt_compression_level, 1);
+ break;
+ case BZIP2:
+ r = compression_init_encoder_bzip2(
+ &(a->archive), &(xar->stream),
+ xar->opt_compression_level);
+ break;
+ case LZMA:
+ r = compression_init_encoder_lzma(
+ &(a->archive), &(xar->stream),
+ xar->opt_compression_level);
+ break;
+ case XZ:
+ r = compression_init_encoder_xz(
+ &(a->archive), &(xar->stream),
+ xar->opt_compression_level);
+ break;
+ default:
+ r = ARCHIVE_OK;
+ break;
+ }
+ if (r == ARCHIVE_OK) {
+ xar->stream.total_in = 0;
+ xar->stream.next_out = xar->wbuff;
+ xar->stream.avail_out = sizeof(xar->wbuff);
+ xar->stream.total_out = 0;
+ }
+
+ return (r);
+}
+
+static int
+compression_code(struct archive *a, struct la_zstream *lastrm,
+ enum la_zaction action)
+{
+ if (lastrm->valid)
+ return (lastrm->code(a, lastrm, action));
+ return (ARCHIVE_OK);
+}
+
+static int
+compression_end(struct archive *a, struct la_zstream *lastrm)
+{
+ if (lastrm->valid)
+ return (lastrm->end(a, lastrm));
+ return (ARCHIVE_OK);
+}
+
+
+static int
+save_xattrs(struct archive_write *a, struct file *file)
+{
+ struct xar *xar;
+ const char *name;
+ const void *value;
+ struct heap_data *heap;
+ size_t size;
+ int count, r;
+
+ xar = (struct xar *)a->format_data;
+ count = archive_entry_xattr_reset(file->entry);
+ if (count == 0)
+ return (ARCHIVE_OK);
+ while (count--) {
+ archive_entry_xattr_next(file->entry,
+ &name, &value, &size);
+ checksum_init(&(xar->a_sumwrk), xar->opt_sumalg);
+ checksum_init(&(xar->e_sumwrk), xar->opt_sumalg);
+
+ heap = calloc(1, sizeof(*heap));
+ if (heap == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for xattr");
+ return (ARCHIVE_FATAL);
+ }
+ heap->id = file->ea_idx++;
+ heap->temp_offset = xar->temp_offset;
+ heap->size = size;/* save a extracted size */
+ heap->compression = xar->opt_compression;
+ /* Get a extracted sumcheck value. */
+ checksum_update(&(xar->e_sumwrk), value, size);
+ checksum_final(&(xar->e_sumwrk), &(heap->e_sum));
+
+ /*
+ * Not compression to xattr is simple way.
+ */
+ if (heap->compression == NONE) {
+ checksum_update(&(xar->a_sumwrk), value, size);
+ checksum_final(&(xar->a_sumwrk), &(heap->a_sum));
+ if (write_to_temp(a, value, size)
+ != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ heap->length = size;
+ /* Add heap to the tail of file->xattr. */
+ heap->next = NULL;
+ *file->xattr.last = heap;
+ file->xattr.last = &(heap->next);
+ /* Next xattr */
+ continue;
+ }
+
+ /*
+ * Init compression library.
+ */
+ r = xar_compression_init_encoder(a);
+ if (r != ARCHIVE_OK) {
+ free(heap);
+ return (ARCHIVE_FATAL);
+ }
+
+ xar->stream.next_in = (const unsigned char *)value;
+ xar->stream.avail_in = size;
+ for (;;) {
+ r = compression_code(&(a->archive),
+ &(xar->stream), ARCHIVE_Z_FINISH);
+ if (r != ARCHIVE_OK && r != ARCHIVE_EOF) {
+ free(heap);
+ return (ARCHIVE_FATAL);
+ }
+ size = sizeof(xar->wbuff) - xar->stream.avail_out;
+ checksum_update(&(xar->a_sumwrk),
+ xar->wbuff, size);
+ if (write_to_temp(a, xar->wbuff, size)
+ != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ if (r == ARCHIVE_OK) {
+ xar->stream.next_out = xar->wbuff;
+ xar->stream.avail_out = sizeof(xar->wbuff);
+ } else {
+ checksum_final(&(xar->a_sumwrk),
+ &(heap->a_sum));
+ heap->length = xar->stream.total_out;
+ /* Add heap to the tail of file->xattr. */
+ heap->next = NULL;
+ *file->xattr.last = heap;
+ file->xattr.last = &(heap->next);
+ break;
+ }
+ }
+ /* Clean up compression library. */
+ r = compression_end(&(a->archive), &(xar->stream));
+ if (r != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ }
+ return (ARCHIVE_OK);
+}
+
+static int
+getalgsize(enum sumalg sumalg)
+{
+ switch (sumalg) {
+ default:
+ case CKSUM_NONE:
+ return (0);
+ case CKSUM_SHA1:
+ return (SHA1_SIZE);
+ case CKSUM_MD5:
+ return (MD5_SIZE);
+ }
+}
+
+static const char *
+getalgname(enum sumalg sumalg)
+{
+ switch (sumalg) {
+ default:
+ case CKSUM_NONE:
+ return (NULL);
+ case CKSUM_SHA1:
+ return (SHA1_NAME);
+ case CKSUM_MD5:
+ return (MD5_NAME);
+ }
+}
+
+#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
new file mode 100644
index 000000000..11fbd45b5
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_zip.c
@@ -0,0 +1,820 @@
+/*-
+ * Copyright (c) 2008 Anselm Strauss
+ * Copyright (c) 2009 Joerg Sonnenberger
+ * 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.
+ */
+
+/*
+ * 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 $");
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_LANGINFO_H
+#include <langinfo.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_ZLIB_H
+#include <cm_zlib.h>
+#endif
+
+#include "archive.h"
+#include "archive_endian.h"
+#include "archive_entry.h"
+#include "archive_entry_locale.h"
+#include "archive_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)
+
+enum compression {
+ COMPRESSION_STORE = 0
+#ifdef HAVE_ZLIB_H
+ ,
+ COMPRESSION_DEFLATE = 8
+#endif
+};
+
+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 *);
+static int archive_write_zip_free(struct archive_write *);
+static int archive_write_zip_finish_entry(struct archive_write *);
+static int archive_write_zip_header(struct archive_write *,
+ struct archive_entry *);
+static int archive_write_zip_options(struct archive_write *,
+ const char *, const char *);
+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 *);
+
+struct zip_local_file_header {
+ char signature[4];
+ char version[2];
+ char flags[2];
+ char compression[2];
+ char timedate[4];
+ char crc32[4];
+ char compressed_size[4];
+ char uncompressed_size[4];
+ char filename_length[2];
+ char extra_length[2];
+};
+
+struct zip_file_header {
+ char signature[4];
+ char version_by[2];
+ char version_extract[2];
+ char flags[2];
+ char compression[2];
+ char timedate[4];
+ char crc32[4];
+ char compressed_size[4];
+ char uncompressed_size[4];
+ char filename_length[2];
+ char extra_length[2];
+ char comment_length[2];
+ char disk_number[2];
+ char attributes_internal[2];
+ char attributes_external[4];
+ char offset[4];
+};
+
+struct zip_data_descriptor {
+ char signature[4]; /* Not mandatory, but recommended by specification. */
+ char crc32[4];
+ char compressed_size[4];
+ char uncompressed_size[4];
+};
+
+struct zip_extra_data_local {
+ char time_id[2];
+ char time_size[2];
+ char time_flag[1];
+ char mtime[4];
+ char atime[4];
+ char ctime[4];
+ char unix_id[2];
+ char unix_size[2];
+ char unix_version;
+ char unix_uid_size;
+ char unix_uid[4];
+ char unix_gid_size;
+ char unix_gid[4];
+};
+
+struct zip_extra_data_central {
+ char time_id[2];
+ char time_size[2];
+ char time_flag[1];
+ char mtime[4];
+ char unix_id[2];
+ char unix_size[2];
+};
+
+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;
+};
+
+struct zip {
+ struct zip_data_descriptor 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;
+
+#ifdef HAVE_ZLIB_H
+ z_stream stream;
+ size_t len_buf;
+ unsigned char *buf;
+#endif
+};
+
+struct zip_central_directory_end {
+ char signature[4];
+ char disk[2];
+ char start_disk[2];
+ char entries_disk[2];
+ char entries[2];
+ char size[4];
+ char offset[4];
+ char comment_length[2];
+};
+
+static int
+archive_write_zip_options(struct archive_write *a, const char *key,
+ const char *val)
+{
+ struct zip *zip = a->format_data;
+ int ret = ARCHIVE_FAILED;
+
+ if (strcmp(key, "compression") == 0) {
+ 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;
+ 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;
+ ret = ARCHIVE_OK;
+ }
+ } else if (strcmp(key, "hdrcharset") == 0) {
+ if (val == NULL || val[0] == 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "%s: hdrcharset option needs a character-set name",
+ a->format_name);
+ } else {
+ zip->opt_sconv = archive_string_conversion_to_charset(
+ &a->archive, val, 0);
+ if (zip->opt_sconv != NULL)
+ ret = ARCHIVE_OK;
+ else
+ ret = ARCHIVE_FATAL;
+ }
+ } else
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "%s: unknown keyword ``%s''", a->format_name, key);
+ return (ret);
+}
+
+int
+archive_write_set_format_zip(struct archive *_a)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ struct zip *zip;
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_zip");
+
+ /* If another format was already registered, unregister it. */
+ if (a->format_free != NULL)
+ (a->format_free)(a);
+
+ zip = (struct zip *) calloc(1, sizeof(*zip));
+ if (zip == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "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;
+
+#ifdef HAVE_ZLIB_H
+ zip->compression = COMPRESSION_DEFLATE;
+ zip->len_buf = 65536;
+ zip->buf = malloc(zip->len_buf);
+ if (zip->buf == NULL) {
+ archive_set_error(&a->archive, ENOMEM,
+ "Can't allocate compression buffer");
+ return (ARCHIVE_FATAL);
+ }
+#else
+ zip->compression = COMPRESSION_STORE;
+#endif
+
+ a->format_data = zip;
+ a->format_name = "zip";
+ a->format_options = archive_write_zip_options;
+ a->format_write_header = archive_write_zip_header;
+ a->format_write_data = archive_write_zip_data;
+ a->format_finish_entry = archive_write_zip_finish_entry;
+ a->format_close = archive_write_zip_close;
+ a->format_free = archive_write_zip_free;
+ a->archive.archive_format = ARCHIVE_FORMAT_ZIP;
+ a->archive.archive_format_name = "ZIP";
+
+ archive_le32enc(&zip->data_descriptor.signature,
+ ZIP_SIGNATURE_DATA_DESCRIPTOR);
+
+ return (ARCHIVE_OK);
+}
+
+static int
+is_all_ascii(const char *p)
+{
+ const unsigned char *pp = (const unsigned char *)p;
+
+ while (*pp) {
+ if (*pp++ > 127)
+ return (0);
+ }
+ return (1);
+}
+
+static int
+archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
+{
+ struct zip *zip;
+ struct zip_local_file_header h;
+ struct zip_extra_data_local e;
+ struct zip_data_descriptor *d;
+ struct zip_file_header_link *l;
+ struct archive_string_conv *sconv;
+ int ret, ret2 = ARCHIVE_OK;
+ int64_t size;
+ mode_t type;
+
+ /* Entries other than a regular file or a folder are skipped. */
+ type = archive_entry_filetype(entry);
+ if (type != AE_IFREG && type != AE_IFDIR && type != AE_IFLNK) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Filetype not supported");
+ return ARCHIVE_FAILED;
+ };
+
+ /* Directory entries should have a size of 0. */
+ if (type == AE_IFDIR)
+ 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;
+ }
+
+ 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
+ }
+ }
+ 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);
+ }
+ l->entry = archive_entry_clone(entry);
+ 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_set_error(&a->archive, ENOMEM,
+ "Can't allocate memory for Pathname");
+ return (ARCHIVE_FATAL);
+ }
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Can't translate pathname '%s' to %s",
+ archive_entry_pathname(entry),
+ archive_string_conversion_charset_name(sconv));
+ ret2 = ARCHIVE_WARN;
+ }
+ if (len > 0)
+ archive_entry_set_pathname(l->entry, p);
+ }
+ /* If all character of a filename is 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;
+
+ /* Initialize the CRC variable and potentially the local crc32(). */
+ l->crc32 = crc32(0, NULL, 0);
+ if (type == AE_IFLNK) {
+ const char *p = archive_entry_symlink(l->entry);
+ if (p != NULL)
+ size = strlen(p);
+ else
+ size = 0;
+ zip->remaining_data_bytes = 0;
+ archive_entry_set_size(l->entry, size);
+ l->compression = COMPRESSION_STORE;
+ l->compressed_size = size;
+ } else {
+ l->compression = zip->compression;
+ l->compressed_size = 0;
+ }
+ l->next = NULL;
+ if (zip->central_directory == NULL) {
+ zip->central_directory = l;
+ } 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.signature, ZIP_SIGNATURE_LOCAL_FILE_HEADER);
+ archive_le16enc(&h.version, ZIP_VERSION_EXTRACT);
+ archive_le16enc(&h.flags, l->flags);
+ archive_le16enc(&h.compression, l->compression);
+ archive_le32enc(&h.timedate, dos_time(archive_entry_mtime(entry)));
+ archive_le16enc(&h.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.compressed_size, size);
+ archive_le32enc(&h.uncompressed_size, size);
+ break;
+#ifdef HAVE_ZLIB_H
+ case COMPRESSION_DEFLATE:
+ archive_le32enc(&h.uncompressed_size, size);
+
+ 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 = 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);
+ }
+ break;
+#endif
+ }
+
+ /* Formatting extra data. */
+ archive_le16enc(&h.extra_length, sizeof(e));
+ archive_le16enc(&e.time_id, ZIP_SIGNATURE_EXTRA_TIMESTAMP);
+ archive_le16enc(&e.time_size, sizeof(e.time_flag) +
+ sizeof(e.mtime) + sizeof(e.atime) + sizeof(e.ctime));
+ e.time_flag[0] = 0x07;
+ archive_le32enc(&e.mtime, archive_entry_mtime(entry));
+ archive_le32enc(&e.atime, archive_entry_atime(entry));
+ archive_le32enc(&e.ctime, archive_entry_ctime(entry));
+
+ archive_le16enc(&e.unix_id, ZIP_SIGNATURE_EXTRA_NEW_UNIX);
+ archive_le16enc(&e.unix_size, sizeof(e.unix_version) +
+ sizeof(e.unix_uid_size) + sizeof(e.unix_uid) +
+ sizeof(e.unix_gid_size) + sizeof(e.unix_gid));
+ e.unix_version = 1;
+ e.unix_uid_size = 4;
+ archive_le32enc(&e.unix_uid, archive_entry_uid(entry));
+ e.unix_gid_size = 4;
+ archive_le32enc(&e.unix_gid, archive_entry_gid(entry));
+
+ archive_le32enc(&d->uncompressed_size, size);
+
+ ret = __archive_write_output(a, &h, sizeof(h));
+ 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;
+
+ ret = __archive_write_output(a, &e, sizeof(e));
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ zip->written_bytes += sizeof(e);
+
+ if (type == AE_IFLNK) {
+ const unsigned char *p;
+
+ p = (const unsigned char *)archive_entry_symlink(l->entry);
+ ret = __archive_write_output(a, p, size);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ zip->written_bytes += size;
+ l->crc32 = crc32(l->crc32, p, size);
+ }
+
+ if (ret2 != ARCHIVE_OK)
+ return (ret2);
+ return (ARCHIVE_OK);
+}
+
+static ssize_t
+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 (s == 0) return 0;
+
+ switch (l->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, s);
+ return (s);
+#if HAVE_ZLIB_H
+ case COMPRESSION_DEFLATE:
+ zip->stream.next_in = (unsigned char*)(uintptr_t)buff;
+ zip->stream.avail_in = s;
+ do {
+ ret = deflate(&zip->stream, Z_NO_FLUSH);
+ if (ret == Z_STREAM_ERROR)
+ return (ARCHIVE_FATAL);
+ if (zip->stream.avail_out == 0) {
+ ret = __archive_write_output(a, zip->buf,
+ zip->len_buf);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ l->compressed_size += zip->len_buf;
+ zip->written_bytes += zip->len_buf;
+ zip->stream.next_out = zip->buf;
+ zip->stream.avail_out = 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, s);
+ return (s);
+#endif
+
+ default:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Invalid ZIP compression type");
+ return ARCHIVE_FATAL;
+ }
+}
+
+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;
+ struct zip_data_descriptor *d = &zip->data_descriptor;
+ struct zip_file_header_link *l = zip->central_directory_end;
+#if HAVE_ZLIB_H
+ size_t reminder;
+#endif
+
+ switch(l->compression) {
+ case COMPRESSION_STORE:
+ break;
+#if HAVE_ZLIB_H
+ case COMPRESSION_DEFLATE:
+ for (;;) {
+ 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);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+ l->compressed_size += reminder;
+ zip->written_bytes += reminder;
+ zip->stream.next_out = zip->buf;
+ if (zip->stream.avail_out != 0)
+ break;
+ zip->stream.avail_out = zip->len_buf;
+ }
+ deflateEnd(&zip->stream);
+ break;
+#endif
+ }
+
+ archive_le32enc(&d->crc32, l->crc32);
+ archive_le32enc(&d->compressed_size, l->compressed_size);
+ ret = __archive_write_output(a, d, sizeof(*d));
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ zip->written_bytes += sizeof(*d);
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_write_zip_close(struct archive_write *a)
+{
+ struct zip *zip;
+ struct zip_file_header_link *l;
+ struct zip_file_header h;
+ struct zip_central_directory_end end;
+ struct zip_extra_data_central e;
+ int64_t offset_start, offset_end;
+ int entries;
+ 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.signature, ZIP_SIGNATURE_FILE_HEADER);
+ archive_le16enc(&h.version_by, ZIP_VERSION_BY);
+ archive_le16enc(&h.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.flags, l->flags);
+ archive_le16enc(&h.compression, l->compression);
+ archive_le32enc(&h.timedate,
+ dos_time(archive_entry_mtime(l->entry)));
+ archive_le32enc(&h.crc32, l->crc32);
+ archive_le32enc(&h.compressed_size, l->compressed_size);
+ archive_le32enc(&h.uncompressed_size,
+ archive_entry_size(l->entry));
+ archive_le16enc(&h.filename_length,
+ (uint16_t)path_length(l->entry));
+ archive_le16enc(&h.extra_length, sizeof(e));
+ archive_le16enc(&h.attributes_external[2],
+ archive_entry_mode(l->entry));
+ archive_le32enc(&h.offset, l->offset);
+
+ /* Formatting extra data. */
+ archive_le16enc(&e.time_id, ZIP_SIGNATURE_EXTRA_TIMESTAMP);
+ archive_le16enc(&e.time_size,
+ sizeof(e.mtime) + sizeof(e.time_flag));
+ e.time_flag[0] = 0x07;
+ archive_le32enc(&e.mtime, archive_entry_mtime(l->entry));
+ archive_le16enc(&e.unix_id, ZIP_SIGNATURE_EXTRA_NEW_UNIX);
+ archive_le16enc(&e.unix_size, 0x0000);
+
+ ret = __archive_write_output(a, &h, sizeof(h));
+ 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;
+
+ ret = __archive_write_output(a, &e, sizeof(e));
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ zip->written_bytes += sizeof(e);
+
+ l = l->next;
+ entries++;
+ }
+ offset_end = zip->written_bytes;
+
+ /* Formatting end of central directory. */
+ memset(&end, 0, sizeof(end));
+ archive_le32enc(&end.signature, ZIP_SIGNATURE_CENTRAL_DIRECTORY_END);
+ archive_le16enc(&end.entries_disk, entries);
+ archive_le16enc(&end.entries, entries);
+ archive_le32enc(&end.size, offset_end - offset_start);
+ archive_le32enc(&end.offset, offset_start);
+
+ /* Writing end of central directory. */
+ ret = __archive_write_output(a, &end, sizeof(end));
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ zip->written_bytes += sizeof(end);
+ return (ARCHIVE_OK);
+}
+
+static int
+archive_write_zip_free(struct archive_write *a)
+{
+ struct zip *zip;
+ struct zip_file_header_link *l;
+
+ 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);
+ }
+#ifdef HAVE_ZLIB_H
+ free(zip->buf);
+#endif
+ free(zip);
+ a->format_data = NULL;
+ return (ARCHIVE_OK);
+}
+
+/* Convert into MSDOS-style date/time. */
+static unsigned int
+dos_time(const time_t unix_time)
+{
+ struct tm *t;
+ unsigned int dt;
+
+ /* This will not preserve time when creating/extracting the archive
+ * on two systems with different time zones. */
+ t = localtime(&unix_time);
+
+ /* MSDOS-style date/time is only between 1980-01-01 and 2107-12-31 */
+ if (t->tm_year < 1980 - 1900)
+ /* Set minimum date/time '1980-01-01 00:00:00'. */
+ dt = 0x00210000U;
+ else if (t->tm_year > 2107 - 1900)
+ /* Set maximum date/time '2107-12-31 23:59:58'. */
+ dt = 0xff9fbf7dU;
+ else {
+ dt = 0;
+ dt += ((t->tm_year - 80) & 0x7f) << 9;
+ dt += ((t->tm_mon + 1) & 0x0f) << 5;
+ dt += (t->tm_mday & 0x1f);
+ dt <<= 16;
+ dt += (t->tm_hour & 0x1f) << 11;
+ dt += (t->tm_min & 0x3f) << 5;
+ dt += (t->tm_sec & 0x3e) >> 1; /* Only counting every 2 seconds. */
+ }
+ return dt;
+}
+
+static size_t
+path_length(struct archive_entry *entry)
+{
+ mode_t type;
+ const char *path;
+
+ type = archive_entry_filetype(entry);
+ path = archive_entry_pathname(entry);
+
+ if ((type == AE_IFDIR) & (path[strlen(path) - 1] != '/')) {
+ return strlen(path) + 1;
+ } else {
+ return strlen(path);
+ }
+}
+
+static int
+write_path(struct archive_entry *entry, struct archive_write *archive)
+{
+ int ret;
+ const char *path;
+ mode_t type;
+ size_t written_bytes;
+
+ path = archive_entry_pathname(entry);
+ type = archive_entry_filetype(entry);
+ written_bytes = 0;
+
+ ret = __archive_write_output(archive, path, strlen(path));
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ written_bytes += strlen(path);
+
+ /* Folders are recognized by a traling slash. */
+ if ((type == AE_IFDIR) & (path[strlen(path) - 1] != '/')) {
+ ret = __archive_write_output(archive, "/", 1);
+ if (ret != ARCHIVE_OK)
+ return (ARCHIVE_FATAL);
+ written_bytes += 1;
+ }
+
+ return ((int)written_bytes);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_options.3 b/Utilities/cmlibarchive/libarchive/archive_write_set_options.3
new file mode 100644
index 000000000..9a8ea3dbf
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_options.3
@@ -0,0 +1,437 @@
+.\" Copyright (c) 2003-2010 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 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: head/lib/libarchive/archive_write.3 201110 2009-12-28 03:31:29Z kientzle $
+.\"
+.Dd Feb 27, 2010
+.Dt ARCHIVE_WRITE_OPTIONS 3
+.Os
+.Sh NAME
+.Nm archive_write_set_filter_option ,
+.Nm archive_write_set_format_option ,
+.Nm archive_write_set_option ,
+.Nm archive_write_set_options
+.Nd functions controlling options for reading archives
+.Sh SYNOPSIS
+.\"
+.Sh SYNOPSIS
+.Ft int
+.Fo archive_write_set_filter_option
+.Fa "struct archive *"
+.Fa "const char *module"
+.Fa "const char *option"
+.Fa "const char *value"
+.Fc
+.Ft int
+.Fo archive_write_set_format_option
+.Fa "struct archive *"
+.Fa "const char *module"
+.Fa "const char *option"
+.Fa "const char *value"
+.Fc
+.Ft int
+.Fo archive_write_set_option
+.Fa "struct archive *"
+.Fa "const char *module"
+.Fa "const char *option"
+.Fa "const char *value"
+.Fc
+.Ft int
+.Fo archive_write_set_options
+.Fa "struct archive *"
+.Fa "const char *options"
+.Fc
+.Sh DESCRIPTION
+These functions provide a way for libarchive clients to configure
+specific write modules.
+.Bl -tag -width indent
+.It Xo
+.Fn archive_write_set_filter_option ,
+.Fn archive_write_set_format_option
+.Xc
+Specifies an option that will be passed to currently-registered
+filters (including decompression filters) or format readers.
+.Pp
+If
+.Ar option
+and
+.Ar value
+are both
+.Dv NULL ,
+these functions will do nothing and
+.Cm ARCHIVE_OK
+will be returned.
+If
+.Ar option
+is
+.Dv NULL
+but
+.Ar value
+is not, these functions will do nothing and
+.Cm ARCHIVE_FAILED
+will be returned.
+.Pp
+If
+.Ar module
+is not
+.Dv NULL ,
+.Ar option
+and
+.Ar value
+will be provided to the filter or reader named
+.Ar module .
+The return value will be that of the module.
+If there is no such module,
+.Cm ARCHIVE_FAILED
+will be returned.
+.Pp
+If
+.Ar module
+is
+.Dv NULL ,
+.Ar option
+and
+.Ar value
+will be provided to every registered module.
+If any module returns
+.Cm ARCHIVE_FATAL ,
+this value will be returned immediately.
+Otherwise,
+.Cm ARCHIVE_OK
+will be returned if any module accepts the option, and
+.Cm ARCHIVE_FAILED
+in all other cases.
+.\"
+.It Xo
+.Fn archive_write_set_option
+.Xc
+Calls
+.Fn archive_write_set_format_option ,
+then
+.Fn archive_write_set_filter_option .
+If either function returns
+.Cm ARCHIVE_FATAL ,
+.Cm ARCHIVE_FATAL
+will be returned
+immediately.
+Otherwise, greater of the two values will be returned.
+.\"
+.It Xo
+.Fn archive_write_set_options
+.Xc
+.Ar options
+is a comma-separated list of options.
+If
+.Ar options
+is
+.Dv NULL
+or empty,
+.Cm ARCHIVE_OK
+will be returned immediately.
+.Pp
+Individual options have one of the following forms:
+.Bl -tag -compact -width indent
+.It Ar option=value
+The option/value pair will be provided to every module.
+Modules that do not accept an option with this name will ignore it.
+.It Ar option
+The option will be provided to every module with a value of
+.Dq 1 .
+.It Ar !option
+The option will be provided to every module with a NULL value.
+.It Ar module:option=value , Ar module:option , Ar module:!option
+As above, but the corresponding option and value will be provided
+only to modules whose name matches
+.Ar module .
+.El
+.El
+.\"
+.Sh OPTIONS
+.Bl -tag -compact -width indent
+.It Filter gzip
+.Bl -tag -compact -width indent
+.It Cm compression-level
+The value is interpreted as a decimal integer specifying the
+gzip compression level.
+.El
+.It Filter xz
+.Bl -tag -compact -width indent
+.It Cm compression-level
+The value is interpreted as a decimal integer specifying the
+compression level.
+.El
+.It Format mtree
+.Bl -tag -compact -width indent
+.It Cm cksum , Cm device , Cm flags , Cm gid , Cm gname , Cm indent , Cm link , Cm md5 , Cm mode , Cm nlink , Cm rmd160 , Cm sha1 , Cm sha256 , Cm sha384 , Cm sha512 , Cm size , Cm time , Cm uid , Cm uname
+Enable a particular keyword in the mtree output.
+Prefix with an exclamation mark to disable the corresponding keyword.
+The default is equivalent to
+.Dq device, flags, gid, gname, link, mode, nlink, size, time, type, uid, uname .
+.It Cm all
+Enables all of the above keywords.
+.It Cm use-set
+Enables generation of
+.Cm /set
+lines that specify default values for the following files and/or directories.
+.It Cm indent
+XXX needs explanation XXX
+.El
+.It Format iso9660 - volume metadata
+These options are used to set standard ISO9660 metadata.
+.Bl -tag -compact -width indent
+.It Cm abstract-file Ns = Ns Ar filename
+The file with the specified name will be identified in the ISO9660 metadata
+as holding the abstract for this volume. Default: none.
+.It Cm application-id Ns = Ns Ar filename
+The file with the specified name will be identified in the ISO9660 metadata
+as holding the application identifier for this volume. Default: none.
+.It Cm biblio-file Ns = Ns Ar filename
+The file with the specified name will be identified in the ISO9660 metadata
+as holding the bibliography for this volume. Default: none.
+.It Cm copyright-file Ns = Ns Ar filename
+The file with the specified name will be identified in the ISO9660 metadata
+as holding the copyright for this volume. Default: none.
+.It Cm publisher Ns = Ns Ar filename
+The file with the specified name will be identified in the ISO9660 metadata
+as holding the publisher information for this volume. Default: none.
+.It Cm volume-id Ns = Ns Ar string
+The specified string will be used as the Volume Identifier in the ISO9660 metadata.
+It is limited to 32 bytes. Default: none.
+.El
+.It Format iso9660 - boot support
+These options are used to make an ISO9660 image that can be directly
+booted on various systems.
+.Bl -tag -compact -width indent
+.It Cm boot Ns = Ns Ar filename
+The file matching this name will be used as the El Torito boot image file.
+.It Cm boot-catalog Ns = Ns Ar name
+The name that will be used for the El Torito boot catalog.
+Default:
+.Ar boot.catalog
+.It Cm boot-info-table
+The boot image file provided by the
+.Cm boot Ns = Ns Ar filename
+option will be edited with appropriate boot information in bytes 8 through 64.
+Default: disabled
+.It Cm boot-load-seg Ns = Ns Ar hexadecimal-number
+The load segment for a no-emulation boot image.
+.It Cm boot-load-size Ns = Ns Ar decimal-number
+The number of "virtual" 512-byte sectors to be loaded from a no-emulation boot image.
+Some very old BIOSes can only load very small images, setting this
+value to 4 will often allow such BIOSes to load the first part of
+the boot image (which will then need to be intelligent enough to
+load the rest of itself).
+This should not be needed unless you are trying to support systems with very old BIOSes.
+This defaults to the full size of the image.
+.It Cm boot-type Ns = Ns Ar value
+Specifies the boot semantics used by the El Torito boot image:
+If the
+.Ar value
+is
+.Cm fd ,
+then the boot image is assumed to be a bootable floppy image.
+If the
+.Ar value
+is
+.Cm hd ,
+then the the boot image is assumed to be a bootable hard disk image.
+If the
+.Ar value
+is
+.Cm no-emulation ,
+the boot image is used without floppy or hard disk emulation.
+If the boot image is exactly 1.2MB, 1.44MB, or 2.88MB, then
+the default is
+.Cm fd ,
+otherwise the default is
+.Cm no-emulation.
+.El
+.It Format iso9660 - filename and size extensions
+Various extensions to the base ISO9660 format.
+.Bl -tag -compact -width indent
+.It Cm allow-ldots
+If enabled, allows filenames to begin with a leading period.
+If disabled, filenames that begin with a leading period will have
+that period replaced by an underscore character in the standard ISO9660
+namespace.
+This does not impact names stored in the Rockridge or Joliet extension area.
+Default: disabled.
+.It Cm allow-lowercase
+If enabled, allows filenames to contain lowercase characters.
+If disabled, filenames will be forced to uppercase.
+This does not impact names stored in the Rockridge or Joliet extension area.
+Default: disabled.
+.It Cm allow-multidot
+If enabled, allows filenames to contain multiple period characters, in violation of the ISO9660 specification.
+If disabled, additional periods will be converted to underscore characters.
+This does not impact names stored in the Rockridge or Joliet extension area.
+Default: disabled.
+.It Cm allow-period
+If enabled, allows filenames to contain trailing period characters, in violation of the ISO9660 specification.
+If disabled,trailing periods will be converted to underscore characters.
+This does not impact names stored in the Rockridge or Joliet extension area.
+Default: disabled.
+.It Cm allow-pvd-lowercase
+If enabled, the Primary Volume Descriptor may contain lowercase ASCII characters, in violation of the ISO9660 specification.
+If disabled, characters will be converted to uppercase ASCII.
+Default: disabled.
+.It Cm allow-sharp-tilde
+If enabled, sharp and tilde characters will be permitted in filenames, in violation if the ISO9660 specification.
+If disabled, such characters will be converted to underscore characters.
+Default: disabled.
+.It Cm allow-vernum
+If enabled, version numbers will be included with files.
+If disabled, version numbers will be suppressed, in violation of the ISO9660 standard.
+This does not impact names stored in the Rockridge or Joliet extension area.
+Default: enabled.
+.It Cm iso-level
+This enables support for file size and file name extensions in the
+core ISO9660 area.
+The name extensions specified here do not affect the names stored in the Rockridge or Joliet extension areas.
+.Bl -tag -compact -width indent
+.It Cm iso-level=1
+The most compliant form of ISO9660 image.
+Filenames are limited to 8.3 uppercase format,
+directory names are limited to 8 uppercase characters,
+files are limited to 4 GiB,
+the complete ISO9660 image cannot exceed 4 GiB.
+.It Cm iso-level=2
+Filenames are limited to 30 uppercase characters with a 30-character extension,
+directory names are limited to 30 characters,
+files are limited to 4 GiB.
+.It Cm iso-level=3
+As with
+.Cm iso-level=2 ,
+except that files may exceed 4 GiB.
+.It Cm iso-level=4
+As with
+.Cm iso-level=3 ,
+except that filenames may be up to 193 characters
+and may include arbitrary 8-bit characters.
+.El
+.It Cm joliet
+Microsoft's Joliet extensions store a completely separate set of directory information about each file.
+In particular, this information includes Unicode filenames of up to 255 characters.
+Default: enabled.
+.It Cm limit-depth
+If enabled, libarchive will use directory relocation records to ensure that
+no pathname exceeds the ISO9660 limit of 8 directory levels.
+If disabled, no relocation will occur.
+Default: enabled.
+.It Cm limit-dirs
+If enabled, libarchive will cause an error if there are more than
+65536 directories.
+If disabled, there is no limit on the number of directories.
+Default: enabled
+.It Cm pad
+If enabled, 300 kiB of zero bytes will be appended to the end of the archive.
+Default: enabled
+.It Cm relaxed-filenames
+If enabled, all 7-bit ASCII characters are permitted in filenames
+(except lowercase characters unless
+.Cm allow-lowercase
+is also specified).
+This violates ISO9660 standards.
+This does not impact names stored in the Rockridge or Joliet extension area.
+Default: disabled.
+.It Cm rockridge
+The Rockridge extensions store an additional set of POSIX-style file
+information with each file, including mtime, atime, ctime, permissions,
+and long filenames with arbitrary 8-bit characters.
+These extensions also support symbolic links and other POSIX file types.
+Default: enabled.
+.El
+.It Format iso9660 - zisofs support
+The zisofs extensions permit each file to be independently compressed
+using a gzip-compatible compression.
+This can provide significant size savings, but requires the reading
+system to have support for these extensions.
+These extensions are disabled by default.
+.Bl -tag -compact -width indent
+.It Cm compression-level Ns = Ns number
+The compression level used by the deflate compressor.
+Ranges from 0 (least effort) to 9 (most effort).
+Default: 6
+.It Cm zisofs
+Synonym for
+.Cm zisofs=direct .
+.It Cm zisofs=direct
+Compress each file in the archive.
+Unlike
+.Cm zisofs=indirect ,
+this is handled entirely within libarchive and does not require a
+separate utility.
+For best results, libarchive tests each file and will store
+the file uncompressed if the compression does not actually save any space.
+In particular, files under 2k will never be compressed.
+Note that boot image files are never compressed.
+.It Cm zisofs=indirect
+Recognizes files that have already been compressed with the
+.Cm mkzftree
+utility and sets up the necessary file metadata so that
+readers will correctly identify these as zisofs-compressed files.
+.It Cm zisofs-exclude Ns = Ns Ar filename
+Specifies a filename that should not be compressed when using
+.Cm zisofs=direct .
+This option can be provided multiple times to suppress compression
+on many files.
+.El
+.El
+.Sh EXAMPLES
+The following example creates an archive write handle to
+create a gzip-compressed ISO9660 format image.
+The two options here specify that the ISO9660 archive will use
+.Ar kernel.img
+as the boot image for El Torito booting, and that the gzip
+compressor should use the maximum compression level.
+.Bd -literal -offset indent
+a = archive_write_new();
+archive_write_add_filter_gzip(a);
+archive_write_set_format_iso9660(a);
+archive_write_set_options(a, "boot=kernel.img,compression=9");
+archive_write_open_filename(a, filename, blocksize);
+.Ed
+.\"
+.Sh ERRORS
+Detailed error codes and textual descriptions are available from the
+.Fn archive_errno
+and
+.Fn archive_error_string
+functions.
+.\"
+.Sh SEE ALSO
+.Xr tar 1 ,
+.Xr libarchive 3 ,
+.Xr archive_read_set_options 3 ,
+.Xr archive_write 3
+.Sh HISTORY
+The
+.Nm libarchive
+library first appeared in
+.Fx 5.3 .
+.Sh AUTHORS
+.An -nosplit
+The options support for libarchive was originally implemented by
+.An Michihiro NAKAJIMA .
+.Sh BUGS
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_options.c b/Utilities/cmlibarchive/libarchive/archive_write_set_options.c
new file mode 100644
index 000000000..a8c2d23dd
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_options.c
@@ -0,0 +1,124 @@
+/*-
+ * Copyright (c) 2003-2010 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$");
+
+#include "archive_write_private.h"
+#include "archive_options_private.h"
+
+static int archive_set_format_option(struct archive *a,
+ const char *m, const char *o, const char *v);
+static int archive_set_filter_option(struct archive *a,
+ const char *m, const char *o, const char *v);
+static int archive_set_option(struct archive *a,
+ const char *m, const char *o, const char *v);
+
+int
+archive_write_set_format_option(struct archive *a, const char *m, const char *o,
+ const char *v)
+{
+ return _archive_set_option(a, m, o, v,
+ ARCHIVE_WRITE_MAGIC, "archive_write_set_format_option",
+ archive_set_format_option);
+}
+
+int
+archive_write_set_filter_option(struct archive *a, const char *m, const char *o,
+ const char *v)
+{
+ return _archive_set_option(a, m, o, v,
+ ARCHIVE_WRITE_MAGIC, "archive_write_set_filter_option",
+ archive_set_filter_option);
+}
+
+int
+archive_write_set_option(struct archive *a, const char *m, const char *o,
+ const char *v)
+{
+ return _archive_set_option(a, m, o, v,
+ ARCHIVE_WRITE_MAGIC, "archive_write_set_option",
+ archive_set_option);
+}
+
+int
+archive_write_set_options(struct archive *a, const char *options)
+{
+ return _archive_set_options(a, options,
+ ARCHIVE_WRITE_MAGIC, "archive_write_set_options",
+ archive_set_option);
+}
+
+static int
+archive_set_format_option(struct archive *_a, const char *m, const char *o,
+ const char *v)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+
+ if (a->format_name == NULL)
+ return (ARCHIVE_FAILED);
+ if (m != NULL && strcmp(m, a->format_name) != 0)
+ return (ARCHIVE_FAILED);
+ if (a->format_options == NULL)
+ return (ARCHIVE_FAILED);
+ return a->format_options(a, o, v);
+}
+
+static int
+archive_set_filter_option(struct archive *_a, const char *m, const char *o,
+ const char *v)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ struct archive_write_filter *filter;
+ int r, rv = ARCHIVE_FAILED;
+
+ for (filter = a->filter_first; filter != NULL; filter = filter->next_filter) {
+ if (filter->options == NULL)
+ continue;
+ if (m != NULL && strcmp(filter->name, m) != 0)
+ continue;
+
+ r = filter->options(filter, o, v);
+
+ if (r == ARCHIVE_FATAL)
+ return (ARCHIVE_FATAL);
+
+ if (m != NULL)
+ return (r);
+
+ if (r == ARCHIVE_OK)
+ rv = ARCHIVE_OK;
+ }
+ return (rv);
+}
+
+static int
+archive_set_option(struct archive *a, const char *m, const char *o,
+ const char *v)
+{
+ return _archive_set_either_option(a, m, o, v,
+ archive_set_format_option,
+ archive_set_filter_option);
+}
diff --git a/Utilities/cmlibarchive/libarchive/config_freebsd.h b/Utilities/cmlibarchive/libarchive/config_freebsd.h
new file mode 100644
index 000000000..207343163
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/config_freebsd.h
@@ -0,0 +1,160 @@
+/*-
+ * 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.
+ *
+ * $FreeBSD: head/lib/libarchive/config_freebsd.h 201079 2009-12-28 02:01:42Z kientzle $
+ */
+
+/* FreeBSD 5.0 and later have ACL and extattr support. */
+#if __FreeBSD__ > 4
+#define HAVE_ACL_CREATE_ENTRY 1
+#define HAVE_ACL_GET_LINK_NP 1
+#define HAVE_ACL_GET_PERM_NP 1
+#define HAVE_ACL_INIT 1
+#define HAVE_ACL_SET_FD 1
+#define HAVE_ACL_SET_FD_NP 1
+#define HAVE_ACL_SET_FILE 1
+#define HAVE_ACL_USER 1
+#define HAVE_EXTATTR_GET_FILE 1
+#define HAVE_EXTATTR_LIST_FILE 1
+#define HAVE_EXTATTR_SET_FD 1
+#define HAVE_EXTATTR_SET_FILE 1
+#define HAVE_SYS_ACL_H 1
+#define HAVE_SYS_EXTATTR_H 1
+#endif
+
+#ifdef WITH_OPENSSL
+#define HAVE_OPENSSL_MD5_H 1
+#define HAVE_OPENSSL_RIPEMD_H 1
+#define HAVE_OPENSSL_SHA_H 1
+#define HAVE_SHA384 1
+#define HAVE_SHA512 1
+#endif
+
+#define HAVE_BSDXML_H 1
+#define HAVE_BZLIB_H 1
+#define HAVE_CHFLAGS 1
+#define HAVE_CHOWN 1
+#define HAVE_DECL_INT64_MAX 1
+#define HAVE_DECL_INT64_MIN 1
+#define HAVE_DECL_SIZE_MAX 1
+#define HAVE_DECL_SSIZE_MAX 1
+#define HAVE_DECL_STRERROR_R 1
+#define HAVE_DECL_UINT32_MAX 1
+#define HAVE_DECL_UINT64_MAX 1
+#define HAVE_DIRENT_H 1
+#define HAVE_EFTYPE 1
+#define HAVE_EILSEQ 1
+#define HAVE_ERRNO_H 1
+#define HAVE_FCHDIR 1
+#define HAVE_FCHFLAGS 1
+#define HAVE_FCHMOD 1
+#define HAVE_FCHOWN 1
+#define HAVE_FCNTL 1
+#define HAVE_FCNTL_H 1
+#define HAVE_FSEEKO 1
+#define HAVE_FSTAT 1
+#define HAVE_FTRUNCATE 1
+#define HAVE_FUTIMES 1
+#define HAVE_GETEUID 1
+#define HAVE_GETGRGID_R 1
+#define HAVE_GETPID 1
+#define HAVE_GETPWUID_R 1
+#define HAVE_GRP_H 1
+#define HAVE_INTTYPES_H 1
+#define HAVE_LCHFLAGS 1
+#define HAVE_LCHMOD 1
+#define HAVE_LCHOWN 1
+#define HAVE_LIMITS_H 1
+#define HAVE_LINK 1
+#define HAVE_LSTAT 1
+#define HAVE_LUTIMES 1
+#define HAVE_MALLOC 1
+#define HAVE_MD5 1
+#define HAVE_MD5_H 1
+#define HAVE_MEMMOVE 1
+#define HAVE_MKDIR 1
+#define HAVE_MKFIFO 1
+#define HAVE_MKNOD 1
+#define HAVE_PIPE 1
+#define HAVE_POLL 1
+#define HAVE_POLL_H 1
+#define HAVE_PWD_H 1
+#define HAVE_READLINK 1
+#define HAVE_RMD160 1
+#define HAVE_SELECT 1
+#define HAVE_SETENV 1
+#define HAVE_SHA_H 1
+#define HAVE_SHA1 1
+#define HAVE_SHA256 1
+#define HAVE_SHA256_H 1
+#define HAVE_SIGNAL_H 1
+#define HAVE_STDINT_H 1
+#define HAVE_STDLIB_H 1
+#define HAVE_STRCHR 1
+#define HAVE_STRDUP 1
+#define HAVE_STRERROR 1
+#define HAVE_STRERROR_R 1
+#define HAVE_STRINGS_H 1
+#define HAVE_STRING_H 1
+#define HAVE_STRRCHR 1
+#define HAVE_STRUCT_STAT_ST_BLKSIZE 1
+#define HAVE_STRUCT_STAT_ST_BIRTHTIME 1
+#define HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC 1
+#define HAVE_STRUCT_STAT_ST_FLAGS 1
+#define HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC 1
+#define HAVE_STRUCT_TM_TM_GMTOFF 1
+#define HAVE_SYMLINK 1
+#define HAVE_SYS_CDEFS_H 1
+#define HAVE_SYS_IOCTL_H 1
+#define HAVE_SYS_MOUNT_H 1
+#define HAVE_SYS_PARAM_H 1
+#define HAVE_SYS_SELECT_H 1
+#define HAVE_SYS_STAT_H 1
+#define HAVE_SYS_TIME_H 1
+#define HAVE_SYS_TYPES_H 1
+#undef HAVE_SYS_UTIME_H
+#define HAVE_SYS_UTSNAME_H 1
+#define HAVE_SYS_WAIT_H 1
+#define HAVE_TIMEGM 1
+#define HAVE_TZSET 1
+#define HAVE_UNISTD_H 1
+#define HAVE_UNSETENV 1
+#define HAVE_UTIME 1
+#define HAVE_UTIMES 1
+#define HAVE_UTIME_H 1
+#define HAVE_VFORK 1
+#define HAVE_WCHAR_H 1
+#define HAVE_WCSCPY 1
+#define HAVE_WCSLEN 1
+#define HAVE_WCTOMB 1
+#define HAVE_WMEMCMP 1
+#define HAVE_WMEMCPY 1
+#define HAVE_ZLIB_H 1
+#define TIME_WITH_SYS_TIME 1
+
+/* FreeBSD 4 and earlier lack intmax_t/uintmax_t */
+#if __FreeBSD__ < 5
+#define intmax_t int64_t
+#define uintmax_t uint64_t
+#endif
diff --git a/Utilities/cmlibarchive/libarchive/cpio.5 b/Utilities/cmlibarchive/libarchive/cpio.5
new file mode 100644
index 000000000..13a4445b7
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/cpio.5
@@ -0,0 +1,325 @@
+.\" Copyright (c) 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 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: src/lib/libarchive/cpio.5,v 1.2 2008/05/26 17:00:23 kientzle Exp $
+.\"
+.Dd October 5, 2007
+.Dt CPIO 5
+.Os
+.Sh NAME
+.Nm cpio
+.Nd format of cpio archive files
+.Sh DESCRIPTION
+The
+.Nm
+archive format collects any number of files, directories, and other
+file system objects (symbolic links, device nodes, etc.) into a single
+stream of bytes.
+.Ss General Format
+Each file system object in a
+.Nm
+archive comprises a header record with basic numeric metadata
+followed by the full pathname of the entry and the file data.
+The header record stores a series of integer values that generally
+follow the fields in
+.Va struct stat .
+(See
+.Xr stat 2
+for details.)
+The variants differ primarily in how they store those integers
+(binary, octal, or hexadecimal).
+The header is followed by the pathname of the
+entry (the length of the pathname is stored in the header)
+and any file data.
+The end of the archive is indicated by a special record with
+the pathname
+.Dq TRAILER!!! .
+.Ss PWB format
+XXX Any documentation of the original PWB/UNIX 1.0 format? XXX
+.Ss Old Binary Format
+The old binary
+.Nm
+format stores numbers as 2-byte and 4-byte binary values.
+Each entry begins with a header in the following format:
+.Bd -literal -offset indent
+struct header_old_cpio {
+ unsigned short c_magic;
+ unsigned short c_dev;
+ unsigned short c_ino;
+ unsigned short c_mode;
+ unsigned short c_uid;
+ unsigned short c_gid;
+ unsigned short c_nlink;
+ unsigned short c_rdev;
+ unsigned short c_mtime[2];
+ unsigned short c_namesize;
+ unsigned short c_filesize[2];
+};
+.Ed
+.Pp
+The
+.Va unsigned short
+fields here are 16-bit integer values; the
+.Va unsigned int
+fields are 32-bit integer values.
+The fields are as follows
+.Bl -tag -width indent
+.It Va magic
+The integer value octal 070707.
+This value can be used to determine whether this archive is
+written with little-endian or big-endian integers.
+.It Va dev , Va ino
+The device and inode numbers from the disk.
+These are used by programs that read
+.Nm
+archives to determine when two entries refer to the same file.
+Programs that synthesize
+.Nm
+archives should be careful to set these to distinct values for each entry.
+.It Va mode
+The mode specifies both the regular permissions and the file type.
+It consists of several bit fields as follows:
+.Bl -tag -width "MMMMMMM" -compact
+.It 0170000
+This masks the file type bits.
+.It 0140000
+File type value for sockets.
+.It 0120000
+File type value for symbolic links.
+For symbolic links, the link body is stored as file data.
+.It 0100000
+File type value for regular files.
+.It 0060000
+File type value for block special devices.
+.It 0040000
+File type value for directories.
+.It 0020000
+File type value for character special devices.
+.It 0010000
+File type value for named pipes or FIFOs.
+.It 0004000
+SUID bit.
+.It 0002000
+SGID bit.
+.It 0001000
+Sticky bit.
+On some systems, this modifies the behavior of executables and/or directories.
+.It 0000777
+The lower 9 bits specify read/write/execute permissions
+for world, group, and user following standard POSIX conventions.
+.El
+.It Va uid , Va gid
+The numeric user id and group id of the owner.
+.It Va nlink
+The number of links to this file.
+Directories always have a value of at least two here.
+Note that hardlinked files include file data with every copy in the archive.
+.It Va rdev
+For block special and character special entries,
+this field contains the associated device number.
+For all other entry types, it should be set to zero by writers
+and ignored by readers.
+.It Va mtime
+Modification time of the file, indicated as the number
+of seconds since the start of the epoch,
+00:00:00 UTC January 1, 1970.
+The four-byte integer is stored with the most-significant 16 bits first
+followed by the least-significant 16 bits.
+Each of the two 16 bit values are stored in machine-native byte order.
+.It Va namesize
+The number of bytes in the pathname that follows the header.
+This count includes the trailing NUL byte.
+.It Va filesize
+The size of the file.
+Note that this archive format is limited to
+four gigabyte file sizes.
+See
+.Va mtime
+above for a description of the storage of four-byte integers.
+.El
+.Pp
+The pathname immediately follows the fixed header.
+If the
+.Cm namesize
+is odd, an additional NUL byte is added after the pathname.
+The file data is then appended, padded with NUL
+bytes to an even length.
+.Pp
+Hardlinked files are not given special treatment;
+the full file contents are included with each copy of the
+file.
+.Ss Portable ASCII Format
+.St -susv2
+standardized an ASCII variant that is portable across all
+platforms.
+It is commonly known as the
+.Dq old character
+format or as the
+.Dq odc
+format.
+It stores the same numeric fields as the old binary format, but
+represents them as 6-character or 11-character octal values.
+.Bd -literal -offset indent
+struct cpio_odc_header {
+ char c_magic[6];
+ char c_dev[6];
+ char c_ino[6];
+ char c_mode[6];
+ char c_uid[6];
+ char c_gid[6];
+ char c_nlink[6];
+ char c_rdev[6];
+ char c_mtime[11];
+ char c_namesize[6];
+ char c_filesize[11];
+};
+.Ed
+.Pp
+The fields are identical to those in the old binary format.
+The name and file body follow the fixed header.
+Unlike the old binary format, there is no additional padding
+after the pathname or file contents.
+If the files being archived are themselves entirely ASCII, then
+the resulting archive will be entirely ASCII, except for the
+NUL byte that terminates the name field.
+.Ss New ASCII Format
+The "new" ASCII format uses 8-byte hexadecimal fields for
+all numbers and separates device numbers into separate fields
+for major and minor numbers.
+.Bd -literal -offset indent
+struct cpio_newc_header {
+ char c_magic[6];
+ char c_ino[8];
+ char c_mode[8];
+ char c_uid[8];
+ char c_gid[8];
+ char c_nlink[8];
+ char c_mtime[8];
+ char c_filesize[8];
+ char c_devmajor[8];
+ char c_devminor[8];
+ char c_rdevmajor[8];
+ char c_rdevminor[8];
+ char c_namesize[8];
+ char c_check[8];
+};
+.Ed
+.Pp
+Except as specified below, the fields here match those specified
+for the old binary format above.
+.Bl -tag -width indent
+.It Va magic
+The string
+.Dq 070701 .
+.It Va check
+This field is always set to zero by writers and ignored by readers.
+See the next section for more details.
+.El
+.Pp
+The pathname is followed by NUL bytes so that the total size
+of the fixed header plus pathname is a multiple of four.
+Likewise, the file data is padded to a multiple of four bytes.
+Note that this format supports only 4 gigabyte files (unlike the
+older ASCII format, which supports 8 gigabyte files).
+.Pp
+In this format, hardlinked files are handled by setting the
+filesize to zero for each entry except the last one that
+appears in the archive.
+.Ss New CRC Format
+The CRC format is identical to the new ASCII format described
+in the previous section except that the magic field is set
+to
+.Dq 070702
+and the
+.Va check
+field is set to the sum of all bytes in the file data.
+This sum is computed treating all bytes as unsigned values
+and using unsigned arithmetic.
+Only the least-significant 32 bits of the sum are stored.
+.Ss HP variants
+The
+.Nm cpio
+implementation distributed with HPUX used XXXX but stored
+device numbers differently XXX.
+.Ss Other Extensions and Variants
+Sun Solaris uses additional file types to store extended file
+data, including ACLs and extended attributes, as special
+entries in cpio archives.
+.Pp
+XXX Others? XXX
+.Sh SEE ALSO
+.Xr cpio 1 ,
+.Xr tar 5
+.Sh STANDARDS
+The
+.Nm cpio
+utility is no longer a part of POSIX or the Single Unix Standard.
+It last appeared in
+.St -susv2 .
+It has been supplanted in subsequent standards by
+.Xr pax 1 .
+The portable ASCII format is currently part of the specification for the
+.Xr pax 1
+utility.
+.Sh HISTORY
+The original cpio utility was written by Dick Haight
+while working in AT&T's Unix Support Group.
+It appeared in 1977 as part of PWB/UNIX 1.0, the
+.Dq Programmer's Work Bench
+derived from
+.At v6
+that was used internally at AT&T.
+Both the old binary and old character formats were in use
+by 1980, according to the System III source released
+by SCO under their
+.Dq Ancient Unix
+license.
+The character format was adopted as part of
+.St -p1003.1-88 .
+XXX when did "newc" appear? Who invented it? When did HP come out with their variant? When did Sun introduce ACLs and extended attributes? XXX
+.Sh BUGS
+The
+.Dq CRC
+format is mis-named, as it uses a simple checksum and
+not a cyclic redundancy check.
+.Pp
+The old binary format is limited to 16 bits for user id,
+group id, device, and inode numbers.
+It is limited to 4 gigabyte file sizes.
+.Pp
+The old ASCII format is limited to 18 bits for
+the user id, group id, device, and inode numbers.
+It is limited to 8 gigabyte file sizes.
+.Pp
+The new ASCII format is limited to 4 gigabyte file sizes.
+.Pp
+None of the cpio formats store user or group names,
+which are essential when moving files between systems with
+dissimilar user or group numbering.
+.Pp
+Especially when writing older cpio variants, it may be necessary
+to map actual device/inode values to synthesized values that
+fit the available fields.
+With very large filesystems, this may be necessary even for
+the newer formats.
diff --git a/Utilities/cmlibarchive/libarchive/filter_fork.c b/Utilities/cmlibarchive/libarchive/filter_fork.c
new file mode 100644
index 000000000..d160524b0
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/filter_fork.c
@@ -0,0 +1,161 @@
+/*-
+ * Copyright (c) 2007 Joerg Sonnenberger
+ * 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"
+
+/* This capability is only available on POSIX systems. */
+#if defined(HAVE_PIPE) && defined(HAVE_FCNTL) && \
+ (defined(HAVE_FORK) || defined(HAVE_VFORK))
+
+__FBSDID("$FreeBSD: head/lib/libarchive/filter_fork.c 182958 2008-09-12 05:33:00Z kientzle $");
+
+#if defined(HAVE_POLL) && (defined(HAVE_POLL_H) || defined(HAVE_SYS_POLL_H))
+# if defined(HAVE_POLL_H)
+# include <poll.h>
+# elif defined(HAVE_SYS_POLL_H)
+# include <sys/poll.h>
+# endif
+#elif defined(HAVE_SELECT)
+# if defined(HAVE_SYS_SELECT_H)
+# include <sys/select.h>
+# elif defined(HAVE_UNISTD_H)
+# include <unistd.h>
+# endif
+#endif
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#include "filter_fork.h"
+
+pid_t
+__archive_create_child(const char *path, int *child_stdin, int *child_stdout)
+{
+ pid_t child;
+ int stdin_pipe[2], stdout_pipe[2], tmp;
+
+ if (pipe(stdin_pipe) == -1)
+ goto state_allocated;
+ if (stdin_pipe[0] == 1 /* stdout */) {
+ if ((tmp = dup(stdin_pipe[0])) == -1)
+ goto stdin_opened;
+ close(stdin_pipe[0]);
+ stdin_pipe[0] = tmp;
+ }
+ if (pipe(stdout_pipe) == -1)
+ goto stdin_opened;
+ if (stdout_pipe[1] == 0 /* stdin */) {
+ if ((tmp = dup(stdout_pipe[1])) == -1)
+ goto stdout_opened;
+ close(stdout_pipe[1]);
+ stdout_pipe[1] = tmp;
+ }
+
+#if HAVE_VFORK
+ switch ((child = vfork())) {
+#else
+ switch ((child = fork())) {
+#endif
+ case -1:
+ goto stdout_opened;
+ case 0:
+ close(stdin_pipe[1]);
+ close(stdout_pipe[0]);
+ if (dup2(stdin_pipe[0], 0 /* stdin */) == -1)
+ _exit(254);
+ if (stdin_pipe[0] != 0 /* stdin */)
+ close(stdin_pipe[0]);
+ if (dup2(stdout_pipe[1], 1 /* stdout */) == -1)
+ _exit(254);
+ if (stdout_pipe[1] != 1 /* stdout */)
+ close(stdout_pipe[1]);
+ execlp(path, path, (char *)NULL);
+ _exit(254);
+ default:
+ close(stdin_pipe[0]);
+ close(stdout_pipe[1]);
+
+ *child_stdin = stdin_pipe[1];
+ fcntl(*child_stdin, F_SETFL, O_NONBLOCK);
+ *child_stdout = stdout_pipe[0];
+ fcntl(*child_stdout, F_SETFL, O_NONBLOCK);
+ }
+
+ return child;
+
+stdout_opened:
+ close(stdout_pipe[0]);
+ close(stdout_pipe[1]);
+stdin_opened:
+ close(stdin_pipe[0]);
+ close(stdin_pipe[1]);
+state_allocated:
+ return -1;
+}
+
+void
+__archive_check_child(int in, int out)
+{
+#if defined(HAVE_POLL) && (defined(HAVE_POLL_H) || defined(HAVE_SYS_POLL_H))
+ struct pollfd fds[2];
+ int idx;
+
+ idx = 0;
+ if (in != -1) {
+ fds[idx].fd = in;
+ fds[idx].events = POLLOUT;
+ ++idx;
+ }
+ if (out != -1) {
+ fds[idx].fd = out;
+ fds[idx].events = POLLIN;
+ ++idx;
+ }
+
+ poll(fds, idx, -1); /* -1 == INFTIM, wait forever */
+#elif defined(HAVE_SELECT)
+ fd_set fds_in, fds_out, fds_error;
+
+ FD_ZERO(&fds_in);
+ FD_ZERO(&fds_out);
+ FD_ZERO(&fds_error);
+ if (out != -1) {
+ FD_SET(out, &fds_in);
+ FD_SET(out, &fds_error);
+ }
+ if (in != -1) {
+ FD_SET(in, &fds_out);
+ FD_SET(in, &fds_error);
+ }
+ select(in < out ? out + 1 : in + 1, &fds_in, &fds_out, &fds_error, NULL);
+#else
+ sleep(1);
+#endif
+}
+
+#endif /* defined(HAVE_PIPE) && defined(HAVE_VFORK) && defined(HAVE_FCNTL) */
diff --git a/Utilities/cmlibarchive/libarchive/filter_fork.h b/Utilities/cmlibarchive/libarchive/filter_fork.h
new file mode 100644
index 000000000..453d032d1
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/filter_fork.h
@@ -0,0 +1,41 @@
+/*-
+ * Copyright (c) 2007 Joerg Sonnenberger
+ * 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.
+ *
+ * $FreeBSD: head/lib/libarchive/filter_fork.h 201087 2009-12-28 02:18:26Z kientzle $
+ */
+
+#ifndef __LIBARCHIVE_BUILD
+#error This header is only to be used internally to libarchive.
+#endif
+
+#ifndef FILTER_FORK_H
+#define FILTER_FORK_H
+
+pid_t
+__archive_create_child(const char *path, int *child_stdin, int *child_stdout);
+
+void
+__archive_check_child(int in, int out);
+
+#endif
diff --git a/Utilities/cmlibarchive/libarchive/filter_fork_windows.c b/Utilities/cmlibarchive/libarchive/filter_fork_windows.c
new file mode 100644
index 000000000..272e56c6b
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/filter_fork_windows.c
@@ -0,0 +1,117 @@
+/*-
+ * Copyright (c) 2009 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"
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+
+#include "filter_fork.h"
+
+pid_t
+__archive_create_child(const char *path, int *child_stdin, int *child_stdout)
+{
+ HANDLE childStdout[2], childStdin[2],childStderr;
+ SECURITY_ATTRIBUTES secAtts;
+ STARTUPINFO staInfo;
+ PROCESS_INFORMATION childInfo;
+ char cmd[MAX_PATH];
+
+ secAtts.nLength = sizeof(SECURITY_ATTRIBUTES);
+ secAtts.bInheritHandle = TRUE;
+ secAtts.lpSecurityDescriptor = NULL;
+ if (CreatePipe(&childStdout[0], &childStdout[1], &secAtts, 0) == 0)
+ goto fail;
+ if (!SetHandleInformation(childStdout[0], HANDLE_FLAG_INHERIT, 0))
+ {
+ CloseHandle(childStdout[0]);
+ CloseHandle(childStdout[1]);
+ goto fail;
+ }
+ if (CreatePipe(&childStdin[0], &childStdin[1], &secAtts, 0) == 0) {
+ CloseHandle(childStdout[0]);
+ CloseHandle(childStdout[1]);
+ goto fail;
+ }
+ if (!SetHandleInformation(childStdin[1], HANDLE_FLAG_INHERIT, 0))
+ {
+ CloseHandle(childStdout[0]);
+ CloseHandle(childStdout[1]);
+ CloseHandle(childStdin[0]);
+ CloseHandle(childStdin[1]);
+ goto fail;
+ }
+ if (DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_ERROR_HANDLE),
+ GetCurrentProcess(), &childStderr, 0, TRUE,
+ DUPLICATE_SAME_ACCESS) == 0) {
+ CloseHandle(childStdout[0]);
+ CloseHandle(childStdout[1]);
+ CloseHandle(childStdin[0]);
+ CloseHandle(childStdin[1]);
+ goto fail;
+ }
+
+ memset(&staInfo, 0, sizeof(staInfo));
+ staInfo.cb = sizeof(staInfo);
+ staInfo.hStdError = childStderr;
+ staInfo.hStdOutput = childStdout[1];
+ staInfo.hStdInput = childStdin[0];
+ staInfo.wShowWindow = SW_HIDE;
+ staInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
+ strncpy(cmd, path, sizeof(cmd)-1);
+ cmd[sizeof(cmd)-1] = '\0';
+ if (CreateProcessA(NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL,
+ &staInfo, &childInfo) == 0) {
+ CloseHandle(childStdout[0]);
+ CloseHandle(childStdout[1]);
+ CloseHandle(childStdin[0]);
+ CloseHandle(childStdin[1]);
+ CloseHandle(childStderr);
+ goto fail;
+ }
+ WaitForInputIdle(childInfo.hProcess, INFINITE);
+ CloseHandle(childInfo.hProcess);
+ CloseHandle(childInfo.hThread);
+
+ *child_stdout = _open_osfhandle((intptr_t)childStdout[0], _O_RDONLY);
+ *child_stdin = _open_osfhandle((intptr_t)childStdin[1], _O_WRONLY);
+
+ CloseHandle(childStdout[1]);
+ CloseHandle(childStdin[0]);
+
+ return (childInfo.dwProcessId);
+
+fail:
+ return (-1);
+}
+
+void
+__archive_check_child(int in, int out)
+{
+ (void)in; /* UNSED */
+ (void)out; /* UNSED */
+ Sleep(100);
+}
+
+#endif /* _WIN32 && !__CYGWIN__ */
diff --git a/Utilities/cmlibarchive/libarchive/libarchive-formats.5 b/Utilities/cmlibarchive/libarchive/libarchive-formats.5
new file mode 100644
index 000000000..d223bf853
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/libarchive-formats.5
@@ -0,0 +1,361 @@
+.\" Copyright (c) 2003-2009 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 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: head/lib/libarchive/libarchive-formats.5 201077 2009-12-28 01:50:23Z kientzle $
+.\"
+.Dd December 27, 2009
+.Dt LIBARCHIVE-FORMATS 5
+.Os
+.Sh NAME
+.Nm libarchive-formats
+.Nd archive formats supported by the libarchive library
+.Sh DESCRIPTION
+The
+.Xr libarchive 3
+library reads and writes a variety of streaming archive formats.
+Generally speaking, all of these archive formats consist of a series of
+.Dq entries .
+Each entry stores a single file system object, such as a file, directory,
+or symbolic link.
+.Pp
+The following provides a brief description of each format supported
+by libarchive, with some information about recognized extensions or
+limitations of the current library support.
+Note that just because a format is supported by libarchive does not
+imply that a program that uses libarchive will support that format.
+Applications that use libarchive specify which formats they wish
+to support, though many programs do use libarchive convenience
+functions to enable all supported formats.
+.Ss Tar Formats
+The
+.Xr libarchive 3
+library can read most tar archives.
+However, it only writes POSIX-standard
+.Dq ustar
+and
+.Dq pax interchange
+formats.
+.Pp
+All tar formats store each entry in one or more 512-byte records.
+The first record is used for file metadata, including filename,
+timestamp, and mode information, and the file data is stored in
+subsequent records.
+Later variants have extended this by either appropriating undefined
+areas of the header record, extending the header to multiple records,
+or by storing special entries that modify the interpretation of
+subsequent entries.
+.Pp
+.Bl -tag -width indent
+.It Cm gnutar
+The
+.Xr libarchive 3
+library can read GNU-format tar archives.
+It currently supports the most popular GNU extensions, including
+modern long filename and linkname support, as well as atime and ctime data.
+The libarchive library does not support multi-volume
+archives, nor the old GNU long filename format.
+It can read GNU sparse file entries, including the new POSIX-based
+formats, but cannot write GNU sparse file entries.
+.It Cm pax
+The
+.Xr libarchive 3
+library can read and write POSIX-compliant pax interchange format
+archives.
+Pax interchange format archives are an extension of the older ustar
+format that adds a separate entry with additional attributes stored
+as key/value pairs immediately before each regular entry.
+The presence of these additional entries is the only difference between
+pax interchange format and the older ustar format.
+The extended attributes are of unlimited length and are stored
+as UTF-8 Unicode strings.
+Keywords defined in the standard are in all lowercase; vendors are allowed
+to define custom keys by preceding them with the vendor name in all uppercase.
+When writing pax archives, libarchive uses many of the SCHILY keys
+defined by Joerg Schilling's
+.Dq star
+archiver and a few LIBARCHIVE keys.
+The libarchive library can read most of the SCHILY keys
+and most of the GNU keys introduced by GNU tar.
+It silently ignores any keywords that it does not understand.
+.It Cm restricted pax
+The libarchive library can also write pax archives in which it
+attempts to suppress the extended attributes entry whenever
+possible.
+The result will be identical to a ustar archive unless the
+extended attributes entry is required to store a long file
+name, long linkname, extended ACL, file flags, or if any of the standard
+ustar data (user name, group name, UID, GID, etc) cannot be fully
+represented in the ustar header.
+In all cases, the result can be dearchived by any program that
+can read POSIX-compliant pax interchange format archives.
+Programs that correctly read ustar format (see below) will also be
+able to read this format; any extended attributes will be extracted as
+separate files stored in
+.Pa PaxHeader
+directories.
+.It Cm ustar
+The libarchive library can both read and write this format.
+This format has the following limitations:
+.Bl -bullet -compact
+.It
+Device major and minor numbers are limited to 21 bits.
+Nodes with larger numbers will not be added to the archive.
+.It
+Path names in the archive are limited to 255 bytes.
+(Shorter if there is no / character in exactly the right place.)
+.It
+Symbolic links and hard links are stored in the archive with
+the name of the referenced file.
+This name is limited to 100 bytes.
+.It
+Extended attributes, file flags, and other extended
+security information cannot be stored.
+.It
+Archive entries are limited to 8 gigabytes in size.
+.El
+Note that the pax interchange format has none of these restrictions.
+.El
+.Pp
+The libarchive library also reads a variety of commonly-used extensions to
+the basic tar format.
+These extensions are recognized automatically whenever they appear.
+.Bl -tag -width indent
+.It Numeric extensions.
+The POSIX standards require fixed-length numeric fields to be written with
+some character position reserved for terminators.
+Libarchive allows these fields to be written without terminator characters.
+This extends the allowable range; in particular, ustar archives with this
+extension can support entries up to 64 gigabytes in size.
+Libarchive also recognizes base-256 values in most numeric fields.
+This essentially removes all limitations on file size, modification time,
+and device numbers.
+.It Solaris extensions
+Libarchive recognizes ACL and extended attribute records written
+by Solaris tar.
+Currently, libarchive only has support for old-style ACLs; the
+newer NFSv4 ACLs are recognized but discarded.
+.El
+.Pp
+The first tar program appeared in Seventh Edition Unix in 1979.
+The first official standard for the tar file format was the
+.Dq ustar
+(Unix Standard Tar) format defined by POSIX in 1988.
+POSIX.1-2001 extended the ustar format to create the
+.Dq pax interchange
+format.
+.Ss Cpio Formats
+The libarchive library can read a number of common cpio variants and can write
+.Dq odc
+and
+.Dq newc
+format archives.
+A cpio archive stores each entry as a fixed-size header followed
+by a variable-length filename and variable-length data.
+Unlike the tar format, the cpio format does only minimal padding
+of the header or file data.
+There are several cpio variants, which differ primarily in
+how they store the initial header: some store the values as
+octal or hexadecimal numbers in ASCII, others as binary values of
+varying byte order and length.
+.Bl -tag -width indent
+.It Cm binary
+The libarchive library transparently reads both big-endian and little-endian
+variants of the original binary cpio format.
+This format used 32-bit binary values for file size and mtime,
+and 16-bit binary values for the other fields.
+.It Cm odc
+The libarchive library can both read and write this
+POSIX-standard format, which is officially known as the
+.Dq cpio interchange format
+or the
+.Dq octet-oriented cpio archive format
+and sometimes unofficially referred to as the
+.Dq old character format .
+This format stores the header contents as octal values in ASCII.
+It is standard, portable, and immune from byte-order confusion.
+File sizes and mtime are limited to 33 bits (8GB file size),
+other fields are limited to 18 bits.
+.It Cm SVR4
+The libarchive library can read both CRC and non-CRC variants of
+this format.
+The SVR4 format uses eight-digit hexadecimal values for
+all header fields.
+This limits file size to 4GB, and also limits the mtime and
+other fields to 32 bits.
+The SVR4 format can optionally include a CRC of the file
+contents, although libarchive does not currently verify this CRC.
+.El
+.Pp
+Cpio first appeared in PWB/UNIX 1.0, which was released within
+AT&T in 1977.
+PWB/UNIX 1.0 formed the basis of System III Unix, released outside
+of AT&T in 1981.
+This makes cpio older than tar, although cpio was not included
+in Version 7 AT&T Unix.
+As a result, the tar command became much better known in universities
+and research groups that used Version 7.
+The combination of the
+.Nm find
+and
+.Nm cpio
+utilities provided very precise control over file selection.
+Unfortunately, the format has many limitations that make it unsuitable
+for widespread use.
+Only the POSIX format permits files over 4GB, and its 18-bit
+limit for most other fields makes it unsuitable for modern systems.
+In addition, cpio formats only store numeric UID/GID values (not
+usernames and group names), which can make it very difficult to correctly
+transfer archives across systems with dissimilar user numbering.
+.Ss Shar Formats
+A
+.Dq shell archive
+is a shell script that, when executed on a POSIX-compliant
+system, will recreate a collection of file system objects.
+The libarchive library can write two different kinds of shar archives:
+.Bl -tag -width indent
+.It Cm shar
+The traditional shar format uses a limited set of POSIX
+commands, including
+.Xr echo 1 ,
+.Xr mkdir 1 ,
+and
+.Xr sed 1 .
+It is suitable for portably archiving small collections of plain text files.
+However, it is not generally well-suited for large archives
+(many implementations of
+.Xr sh 1
+have limits on the size of a script) nor should it be used with non-text files.
+.It Cm shardump
+This format is similar to shar but encodes files using
+.Xr uuencode 1
+so that the result will be a plain text file regardless of the file contents.
+It also includes additional shell commands that attempt to reproduce as
+many file attributes as possible, including owner, mode, and flags.
+The additional commands used to restore file attributes make
+shardump archives less portable than plain shar archives.
+.El
+.Ss ISO9660 format
+Libarchive can read and extract from files containing ISO9660-compliant
+CDROM images.
+In many cases, this can remove the need to burn a physical CDROM
+just in order to read the files contained in an ISO9660 image.
+It also avoids security and complexity issues that come with
+virtual mounts and loopback devices.
+Libarchive supports the most common Rockridge extensions and has partial
+support for Joliet extensions.
+If both extensions are present, the Joliet extensions will be
+used and the Rockridge extensions will be ignored.
+In particular, this can create problems with hardlinks and symlinks,
+which are supported by Rockridge but not by Joliet.
+.Ss Zip format
+Libarchive can read and write zip format archives that have
+uncompressed entries and entries compressed with the
+.Dq deflate
+algorithm.
+Older zip compression algorithms are not supported.
+It can extract jar archives, archives that use Zip64 extensions and many
+self-extracting zip archives.
+Libarchive reads Zip archives as they are being streamed,
+which allows it to read archives of arbitrary size.
+It currently does not use the central directory; this
+limits libarchive's ability to support some self-extracting
+archives and ones that have been modified in certain ways.
+.Ss Archive (library) file format
+The Unix archive format (commonly created by the
+.Xr ar 1
+archiver) is a general-purpose format which is
+used almost exclusively for object files to be
+read by the link editor
+.Xr ld 1 .
+The ar format has never been standardised.
+There are two common variants:
+the GNU format derived from SVR4,
+and the BSD format, which first appeared in 4.4BSD.
+The two differ primarily in their handling of filenames
+longer than 15 characters:
+the GNU/SVR4 variant writes a filename table at the beginning of the archive;
+the BSD format stores each long filename in an extension
+area adjacent to the entry.
+Libarchive can read both extensions,
+including archives that may include both types of long filenames.
+Programs using libarchive can write GNU/SVR4 format
+if they provide a filename table to be written into
+the archive before any of the entries.
+Any entries whose names are not in the filename table
+will be written using BSD-style long filenames.
+This can cause problems for programs such as
+GNU ld that do not support the BSD-style long filenames.
+.Ss mtree
+Libarchive can read and write files in
+.Xr mtree 5
+format.
+This format is not a true archive format, but rather a textual description
+of a file hierarchy in which each line specifies the name of a file and
+provides specific metadata about that file.
+Libarchive can read all of the keywords supported by both
+the NetBSD and FreeBSD versions of
+.Xr mtree 1 ,
+although many of the keywords cannot currently be stored in an
+.Tn archive_entry
+object.
+When writing, libarchive supports use of the
+.Xr archive_write_set_options 3
+interface to specify which keywords should be included in the
+output.
+If libarchive was compiled with access to suitable
+cryptographic libraries (such as the OpenSSL libraries),
+it can compute hash entries such as
+.Cm sha512
+or
+.Cm md5
+from file data being written to the mtree writer.
+.Pp
+When reading an mtree file, libarchive will locate the corresponding
+files on disk using the
+.Cm contents
+keyword if present or the regular filename.
+If it can locate and open the file on disk, it will use that
+to fill in any metadata that is missing from the mtree file
+and will read the file contents and return those to the program
+using libarchive.
+If it cannot locate and open the file on disk, libarchive
+will return an error for any attempt to read the entry
+body.
+.Ss RAR
+libarchive has limited support to read files in RAR format. Currently,
+libarchive can read single RAR files in RARv3 format which have been either
+created uncompressed, or compressed using any of the compression methods
+supported by the RARv3 format. libarchive can also extract RAR files which have
+been created as self-extracting RAR files.
+.Sh SEE ALSO
+.Xr ar 1 ,
+.Xr cpio 1 ,
+.Xr mkisofs 1 ,
+.Xr shar 1 ,
+.Xr tar 1 ,
+.Xr zip 1 ,
+.Xr zlib 3 ,
+.Xr cpio 5 ,
+.Xr mtree 5 ,
+.Xr tar 5
diff --git a/Utilities/cmlibarchive/libarchive/libarchive.3 b/Utilities/cmlibarchive/libarchive/libarchive.3
new file mode 100644
index 000000000..d655404b8
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/libarchive.3
@@ -0,0 +1,256 @@
+.\" 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 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: src/lib/libarchive/libarchive.3,v 1.11 2007/01/09 08:05:56 kientzle Exp $
+.\"
+.Dd February 6, 2010
+.Dt LIBARCHIVE 3
+.Os
+.Sh NAME
+.Nm libarchive
+.Nd functions for reading and writing streaming archives
+.Sh LIBRARY
+.Lb libarchive
+.Sh OVERVIEW
+The
+.Nm
+library provides a flexible interface for reading and writing
+archives in various formats such as tar and cpio.
+.Nm
+also supports reading and writing archives compressed using
+various compression filters such as gzip and bzip2.
+The library is inherently stream-oriented; readers serially iterate through
+the archive, writers serially add things to the archive.
+In particular, note that there is currently no built-in support for
+random access nor for in-place modification.
+.Pp
+When reading an archive, the library automatically detects the
+format and the compression.
+The library currently has read support for:
+.Bl -bullet -compact
+.It
+old-style tar archives,
+.It
+most variants of the POSIX
+.Dq ustar
+format,
+.It
+the POSIX
+.Dq pax interchange
+format,
+.It
+GNU-format tar archives,
+.It
+most common cpio archive formats,
+.It
+ISO9660 CD images (including RockRidge and Joliet extensions),
+.It
+Zip archives.
+.El
+The library automatically detects archives compressed with
+.Xr gzip 1 ,
+.Xr bzip2 1 ,
+.Xr xz 1 ,
+or
+.Xr compress 1
+and decompresses them transparently.
+.Pp
+When writing an archive, you can specify the compression
+to be used and the format to use.
+The library can write
+.Bl -bullet -compact
+.It
+POSIX-standard
+.Dq ustar
+archives,
+.It
+POSIX
+.Dq pax interchange format
+archives,
+.It
+POSIX octet-oriented cpio archives,
+.It
+Zip archive,
+.It
+two different variants of shar archives.
+.El
+Pax interchange format is an extension of the tar archive format that
+eliminates essentially all of the limitations of historic tar formats
+in a standard fashion that is supported
+by POSIX-compliant
+.Xr pax 1
+implementations on many systems as well as several newer implementations of
+.Xr tar 1 .
+Note that the default write format will suppress the pax extended
+attributes for most entries; explicitly requesting pax format will
+enable those attributes for all entries.
+.Pp
+The read and write APIs are accessed through the
+.Fn archive_read_XXX
+functions and the
+.Fn archive_write_XXX
+functions, respectively, and either can be used independently
+of the other.
+.Pp
+The rest of this manual page provides an overview of the library
+operation.
+More detailed information can be found in the individual manual
+pages for each API or utility function.
+.\"
+.Sh READING AN ARCHIVE
+See
+.Xr libarchive_read 3 .
+.\"
+.Sh WRITING AN ARCHIVE
+See
+.Xr libarchive_write 3 .
+.\"
+.Sh WRITING ENTRIES TO DISK
+The
+.Xr archive_write_disk 3
+API allows you to write
+.Xr archive_entry 3
+objects to disk using the same API used by
+.Xr archive_write 3 .
+The
+.Xr archive_write_disk 3
+API is used internally by
+.Fn archive_read_extract ;
+using it directly can provide greater control over how entries
+get written to disk.
+This API also makes it possible to share code between
+archive-to-archive copy and archive-to-disk extraction
+operations.
+.Sh READING ENTRIES FROM DISK
+The
+.Xr archive_read_disk 3
+provides some support for populating
+.Xr archive_entry 3
+objects from information in the filesystem.
+.Sh DESCRIPTION
+Detailed descriptions of each function are provided by the
+corresponding manual pages.
+.Pp
+All of the functions utilize an opaque
+.Tn struct archive
+datatype that provides access to the archive contents.
+.Pp
+The
+.Tn struct archive_entry
+structure contains a complete description of a single archive
+entry.
+It uses an opaque interface that is fully documented in
+.Xr archive_entry 3 .
+.Pp
+Users familiar with historic formats should be aware that the newer
+variants have eliminated most restrictions on the length of textual fields.
+Clients should not assume that filenames, link names, user names, or
+group names are limited in length.
+In particular, pax interchange format can easily accommodate pathnames
+in arbitrary character sets that exceed
+.Va PATH_MAX .
+.Sh RETURN VALUES
+Most functions return
+.Cm ARCHIVE_OK
+(zero) on success, non-zero on error.
+The return value indicates the general severity of the error, ranging
+from
+.Cm ARCHIVE_WARN ,
+which indicates a minor problem that should probably be reported
+to the user, to
+.Cm ARCHIVE_FATAL ,
+which indicates a serious problem that will prevent any further
+operations on this archive.
+On error, the
+.Fn archive_errno
+function can be used to retrieve a numeric error code (see
+.Xr errno 2 ) .
+The
+.Fn archive_error_string
+returns a textual error message suitable for display.
+.Pp
+.Fn archive_read_new
+and
+.Fn archive_write_new
+return pointers to an allocated and initialized
+.Tn struct archive
+object.
+.Pp
+.Fn archive_read_data
+and
+.Fn archive_write_data
+return a count of the number of bytes actually read or written.
+A value of zero indicates the end of the data for this entry.
+A negative value indicates an error, in which case the
+.Fn archive_errno
+and
+.Fn archive_error_string
+functions can be used to obtain more information.
+.Sh ENVIRONMENT
+There are character set conversions within the
+.Xr archive_entry 3
+functions that are impacted by the currently-selected locale.
+.Sh SEE ALSO
+.Xr tar 1 ,
+.Xr archive_entry 3 ,
+.Xr archive_read 3 ,
+.Xr archive_util 3 ,
+.Xr archive_write 3 ,
+.Xr tar 5
+.Sh HISTORY
+The
+.Nm libarchive
+library first appeared in
+.Fx 5.3 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm libarchive
+library was written by
+.An Tim Kientzle Aq kientzle@acm.org .
+.Sh BUGS
+Some archive formats support information that is not supported by
+.Tn struct archive_entry .
+Such information cannot be fully archived or restored using this library.
+This includes, for example, comments, character sets,
+or the arbitrary key/value pairs that can appear in
+pax interchange format archives.
+.Pp
+Conversely, of course, not all of the information that can be
+stored in an
+.Tn struct archive_entry
+is supported by all formats.
+For example, cpio formats do not support nanosecond timestamps;
+old tar formats do not support large device numbers.
+.Pp
+The
+.Xr archive_read_disk 3
+API should support iterating over filesystems;
+that would make it possible to share code among
+disk-to-archive, archive-to-archive, archive-to-disk,
+and disk-to-disk operations.
+Currently, it only supports reading the
+information for a single file.
+(Which is still quite useful, as it hides a lot
+of system-specific details.)
diff --git a/Utilities/cmlibarchive/libarchive/libarchive_changes.3 b/Utilities/cmlibarchive/libarchive/libarchive_changes.3
new file mode 100644
index 000000000..6ee6af245
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/libarchive_changes.3
@@ -0,0 +1,341 @@
+.\" Copyright (c) 2011 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 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 March 27, 2011
+.Dt LIBARCHIVE_CHANGES 3
+.Os
+.Sh NAME
+.Nm changes in libarchive interface
+.\"
+.Sh CHANGES IN LIBARCHIVE 3
+This page describes user-visible changes in libarchive3, and lists
+public functions and other symbols changed, deprecated or removed
+in libarchive3, along with their replacements if any.
+.Pp
+.\"
+.Ss Multiple Filters
+.\"
+Libarchive2 permitted a single (input or output) filter active
+on an archive.
+Libarchive3 extends this into a variable-length stack.
+Where
+.Fn archive_write_set_compression_XXX
+would replace any existing filter,
+.Fn archive_write_add_filter_XXX
+extends the write pipeline with another filter.
+.\"
+.Ss Character Set Handling
+.\"
+Libarchive2 assumed that the local platform uses
+.Tn Unicode
+as the native
+.Tn wchar_t
+encoding, which is true on
+.Tn Windows ,
+modern
+.Tn Linux ,
+and a few other systems, but is certainly not universal.
+As a result, pax format archives were written incorrectly on some
+systems, since pax format requires
+.Tn UTF-8
+and libarchive 2 incorrectly
+assumed that
+.Tn wchar_t
+strings can be easily converted to
+.Tn UTF-8 .
+.Pp
+Libarchive3 uses the standard iconv library to convert between character
+sets and is introducing the notion of a
+.Dq default character set for the archive .
+To support this,
+.Tn archive_entry
+objects can now be bound to a particular archive when they are created.
+The automatic character set conversions performed by
+.Tn archive_entry
+objects when reading and writing filenames, usernames, and other strings
+will now use an appropriate default character set:
+.Pp
+If the
+.Tn archive_entry
+object is bound to an archive, it will use the
+default character set for that archive.
+.Pp
+The platform default character encoding (as returned by
+.Fn nl_langinfo CHARSET )
+will be used if nothing else is specified.
+.Pp
+Libarchive3 also introduces charset options to many of the archive
+readers and writers to control the character set that will be used for
+filenames written in those archives.
+When possible, this will be set automatically based on information in
+the archive itself.
+Combining this with the notion of a default character set for the
+archive should allow you to configure libarchive to read archives from
+other platforms and have the filenames and other information
+transparently converted to the character encoding suitable for your
+application.
+.\"
+.Ss Prototype Changes
+.\"
+These changes break binary compatibility; libarchive3 has a new shared
+library version to reflect these changes.
+The library now uses portable wide types such as
+.Tn int64_t
+instead of less-portable types such as
+.Tn off_t ,
+.Tn gid_t ,
+.Tn uid_t ,
+and
+.Tn ino_t .
+.Pp
+There are a few cases where these changes will affect your source code:
+.Bl -bullet -width ind
+.It
+In some cases, libarchive's wider types will introduce the possibility
+of truncation: for example, on a system with a 16-bit
+.Tn uid_t , you risk having uid
+.Li 65536
+be truncated to uid
+.Li 0 ,
+which can cause serious security problems.
+.It
+Typedef function pointer types will be incompatible.
+For example, if you define custom skip callbacks, you may have to use
+code similar to the following if you want to support building against
+libarchive2 and libarchive3:
+.Bd -literal
+#if ARCHIVE_VERSION_NUMBER < 3000000
+typedef off_t myoff_t;
+#else
+typedef int64_t myoff_t;
+#endif
+
+myoff_t
+my_skip_function(struct archive *a, void *v, myoff_t o)
+{
+ ... implementation ...
+}
+.Ed
+.El
+.Pp
+Affected functions:
+.Pp
+.Bl -bullet -compact
+.It
+.Xo
+.Fn archive_entry_gid ,
+.Fn archive_entry_set_gid
+.Xc
+.It
+.Xo
+.Fn archive_entry_uid ,
+.Fn archive_entry_set_uid
+.Xc
+.It
+.Xo
+.Fn archive_entry_ino ,
+.Fn archive_entry_set_ino
+.Xc
+.It
+.Xo
+.Fn archive_read_data_block ,
+.Fn archive_write_data_block
+.Xc
+.It
+.Xo
+.Fn archive_read_disk_gname ,
+.Fn archive_read_disk_uname
+.Xc
+.It
+.Xo
+.Fn archive_read_disk_set_gname_lookup ,
+.Fn archive_read_disk_set_group_lookup ,
+.Fn archive_read_disk_set_uname_lookup ,
+.Fn archive_read_disk_set_user_lookup
+.Xc
+.It
+.Fn archive_skip_callback
+.It
+.Xo
+.Fn archive_read_extract_set_skip_file ,
+.Fn archive_write_disk_set_skip_file ,
+.Fn archive_write_set_skip_file
+.Xc
+.It
+.Xo
+.Fn archive_write_disk_set_group_lookup ,
+.Fn archive_write_disk_set_user_lookup
+.Xc
+.El
+.Pp
+Where these functions or their arguments took or returned
+.Tn gid_t ,
+.Tn ino_t ,
+.Tn off_t ,
+or
+.Tn uid_t
+they now take or return
+.Tn int64_t
+or equivalent.
+.\"
+.Ss Deprecated Symbols
+.\"
+Symbols deprecated in libarchive3 will be removed in libarchive4.
+These symbols, along with their replacements if any, are listed below:
+.\"
+.Bl -tag -width ind
+.It Fn archive_position_compressed , Fn archive_position_uncompressed
+.Fn archive_filter_bytes
+.It Fn archive_compression
+.Fn archive_filter_code
+.It Fn archive_compression_name
+.Fn archive_filter_name
+.It Fn archive_read_finish , Fn archive_write_finish
+.Fn archive_read_free ,
+.Fn archive_write_free
+.It Fn archive_read_open_file , Fn archive_write_open_file
+.Fn archive_read_open_filename ,
+.Fn archive_write_open_filename
+.It Fn archive_read_support_compression_all
+.\" archive_read_support_compression_* -> archive_read_support_filter_*
+.Fn archive_read_support_filter_all
+.It Fn archive_read_support_compression_bzip2
+.Fn archive_read_support_filter_bzip2
+.It Fn archive_read_support_compression_compress
+.Fn archive_read_support_filter_compress
+.It Fn archive_read_support_compression_gzip
+.Fn archive_read_support_filter_gzip
+.It Fn archive_read_support_compression_lzip
+.Fn archive_read_support_filter_lzip
+.It Fn archive_read_support_compression_lzma
+.Fn archive_read_support_filter_lzma
+.It Fn archive_read_support_compression_none
+.Fn archive_read_support_filter_none
+.It Fn archive_read_support_compression_program
+.Fn archive_read_support_filter_program
+.It Fn archive_read_support_compression_program_signature
+.Fn archive_read_support_filter_program_signature
+.It Fn archive_read_support_compression_rpm
+.Fn archive_read_support_filter_rpm
+.It Fn archive_read_support_compression_uu
+.Fn archive_read_support_filter_uu
+.It Fn archive_read_support_compression_xz
+.Fn archive_read_support_filter_xz
+.\" archive_write_set_compression_* -> archive_write_add_filter_*
+.It Fn archive_write_set_compression_bzip2
+.Fn archive_write_add_filter_bzip2
+.It Fn archive_write_set_compression_compress
+.Fn archive_write_add_filter_compress
+.It Fn archive_write_set_compression_gzip
+.Fn archive_write_add_filter_gzip
+.It Fn archive_write_set_compression_lzip
+.Fn archive_write_add_filter_lzip
+.It Fn archive_write_set_compression_lzma
+.Fn archive_write_add_filter_lzma
+.It Fn archive_write_set_compression_none
+.Fn archive_write_add_filter_none
+.It Fn archive_write_set_compression_program
+.Fn archive_write_add_filter_program
+.It Fn archive_write_set_compression_filter
+.Fn archive_write_add_filter_filter
+.El
+.\"
+.Ss Removed Symbols
+.\"
+These symbols, listed below along with their replacements if any,
+were deprecated in libarchive2, and are not part of libarchive3.
+.\"
+.Bl -tag -width ind
+.It Fn archive_api_feature
+.Fn archive_version_number
+.It Fn archive_api_version
+.Fn archive_version_number
+.It Fn archive_version
+.Fn archive_version_string
+.It Fn archive_version_stamp
+.Fn archive_version_number
+.It Fn archive_read_set_filter_options
+.Fn archive_read_set_options
+or
+.Fn archive_read_set_filter_option
+.It Fn archive_read_set_format_options
+.Fn archive_read_set_options
+or
+.Fn archive_read_set_format_option
+.It Fn archive_write_set_filter_options
+.Fn archive_write_set_options
+or
+.Fn archive_write_set_filter_option
+.It Fn archive_write_set_format_options
+.Fn archive_write_set_options
+or
+.Fn archive_write_set_format_option
+.It Dv ARCHIVE_API_FEATURE
+.Dv ARCHIVE_VERSION_NUMBER
+.It Dv ARCHIVE_API_VERSION
+.Dv ARCHIVE_VERSION_NUMBER
+.It Dv ARCHIVE_VERSION_STAMP
+.Dv ARCHIVE_VERSION_NUMBER
+.It Dv ARCHIVE_LIBRARY_VERSION
+.Dv ARCHIVE_VERSION_STRING
+.\"
+.It Dv ARCHIVE_COMPRESSION_NONE
+.Dv ARCHIVE_FILTER_NONE
+.It Dv ARCHIVE_COMPRESSION_GZIP
+.Dv ARCHIVE_FILTER_GZIP
+.It Dv ARCHIVE_COMPRESSION_BZIP2
+.Dv ARCHIVE_FILTER_BZIP2
+.It Dv ARCHIVE_COMPRESSION_COMPRESS
+.Dv ARCHIVE_FILTER_COMPRESS
+.It Dv ARCHIVE_COMPRESSION_PROGRAM
+.Dv ARCHIVE_FILTER_PROGRAM
+.It Dv ARCHIVE_COMPRESSION_LZMA
+.Dv ARCHIVE_FILTER_LZMA
+.It Dv ARCHIVE_COMPRESSION_XZ
+.Dv ARCHIVE_FILTER_XZ
+.It Dv ARCHIVE_COMPRESSION_UU
+.Dv ARCHIVE_FILTER_UU
+.It Dv ARCHIVE_COMPRESSION_RPM
+.Dv ARCHIVE_FILTER_RPM
+.It Dv ARCHIVE_COMPRESSION_LZIP
+.Dv ARCHIVE_FILTER_LZIP
+.\"
+.It Dv ARCHIVE_BYTES_PER_RECORD
+.Li 512
+.It Dv ARCHIVE_DEFAULT_BYTES_PER_BLOCK
+.Li 10240
+.El
+.Sh SEE ALSO
+.Xr libarchive 3 ,
+.Xr archive_read 3 ,
+.Xr archive_read_filter 3 ,
+.Xr archive_read_format 3 ,
+.Xr archive_read_set_options 3 ,
+.Xr archive_write 3 ,
+.Xr archive_write_filter 3 ,
+.Xr archive_write_format 3 ,
+.Xr archive_write_set_options 3 ,
+.Xr archive_util 3
diff --git a/Utilities/cmlibarchive/libarchive/libarchive_internals.3 b/Utilities/cmlibarchive/libarchive/libarchive_internals.3
new file mode 100644
index 000000000..776f4c351
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/libarchive_internals.3
@@ -0,0 +1,365 @@
+.\" 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 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: src/lib/libarchive/libarchive_internals.3,v 1.2 2007/12/30 04:58:22 kientzle Exp $
+.\"
+.Dd April 16, 2007
+.Dt LIBARCHIVE 3
+.Os
+.Sh NAME
+.Nm libarchive_internals
+.Nd description of libarchive internal interfaces
+.Sh OVERVIEW
+The
+.Nm libarchive
+library provides a flexible interface for reading and writing
+streaming archive files such as tar and cpio.
+Internally, it follows a modular layered design that should
+make it easy to add new archive and compression formats.
+.Sh GENERAL ARCHITECTURE
+Externally, libarchive exposes most operations through an
+opaque, object-style interface.
+The
+.Xr archive_entry 3
+objects store information about a single filesystem object.
+The rest of the library provides facilities to write
+.Xr archive_entry 3
+objects to archive files,
+read them from archive files,
+and write them to disk.
+(There are plans to add a facility to read
+.Xr archive_entry 3
+objects from disk as well.)
+.Pp
+The read and write APIs each have four layers: a public API
+layer, a format layer that understands the archive file format,
+a compression layer, and an I/O layer.
+The I/O layer is completely exposed to clients who can replace
+it entirely with their own functions.
+.Pp
+In order to provide as much consistency as possible for clients,
+some public functions are virtualized.
+Eventually, it should be possible for clients to open
+an archive or disk writer, and then use a single set of
+code to select and write entries, regardless of the target.
+.Sh READ ARCHITECTURE
+From the outside, clients use the
+.Xr archive_read 3
+API to manipulate an
+.Nm archive
+object to read entries and bodies from an archive stream.
+Internally, the
+.Nm archive
+object is cast to an
+.Nm archive_read
+object, which holds all read-specific data.
+The API has four layers:
+The lowest layer is the I/O layer.
+This layer can be overridden by clients, but most clients use
+the packaged I/O callbacks provided, for example, by
+.Xr archive_read_open_memory 3 ,
+and
+.Xr archive_read_open_fd 3 .
+The compression layer calls the I/O layer to
+read bytes and decompresses them for the format layer.
+The format layer unpacks a stream of uncompressed bytes and
+creates
+.Nm archive_entry
+objects from the incoming data.
+The API layer tracks overall state
+(for example, it prevents clients from reading data before reading a header)
+and invokes the format and compression layer operations
+through registered function pointers.
+In particular, the API layer drives the format-detection process:
+When opening the archive, it reads an initial block of data
+and offers it to each registered compression handler.
+The one with the highest bid is initialized with the first block.
+Similarly, the format handlers are polled to see which handler
+is the best for each archive.
+(Prior to 2.4.0, the format bidders were invoked for each
+entry, but this design hindered error recovery.)
+.Ss I/O Layer and Client Callbacks
+The read API goes to some lengths to be nice to clients.
+As a result, there are few restrictions on the behavior of
+the client callbacks.
+.Pp
+The client read callback is expected to provide a block
+of data on each call.
+A zero-length return does indicate end of file, but otherwise
+blocks may be as small as one byte or as large as the entire file.
+In particular, blocks may be of different sizes.
+.Pp
+The client skip callback returns the number of bytes actually
+skipped, which may be much smaller than the skip requested.
+The only requirement is that the skip not be larger.
+In particular, clients are allowed to return zero for any
+skip that they don't want to handle.
+The skip callback must never be invoked with a negative value.
+.Pp
+Keep in mind that not all clients are reading from disk:
+clients reading from networks may provide different-sized
+blocks on every request and cannot skip at all;
+advanced clients may use
+.Xr mmap 2
+to read the entire file into memory at once and return the
+entire file to libarchive as a single block;
+other clients may begin asynchronous I/O operations for the
+next block on each request.
+.Ss Decompresssion Layer
+The decompression layer not only handles decompression,
+it also buffers data so that the format handlers see a
+much nicer I/O model.
+The decompression API is a two stage peek/consume model.
+A read_ahead request specifies a minimum read amount;
+the decompression layer must provide a pointer to at least
+that much data.
+If more data is immediately available, it should return more:
+the format layer handles bulk data reads by asking for a minimum
+of one byte and then copying as much data as is available.
+.Pp
+A subsequent call to the
+.Fn consume
+function advances the read pointer.
+Note that data returned from a
+.Fn read_ahead
+call is guaranteed to remain in place until
+the next call to
+.Fn read_ahead .
+Intervening calls to
+.Fn consume
+should not cause the data to move.
+.Pp
+Skip requests must always be handled exactly.
+Decompression handlers that cannot seek forward should
+not register a skip handler;
+the API layer fills in a generic skip handler that reads and discards data.
+.Pp
+A decompression handler has a specific lifecycle:
+.Bl -tag -compact -width indent
+.It Registration/Configuration
+When the client invokes the public support function,
+the decompression handler invokes the internal
+.Fn __archive_read_register_compression
+function to provide bid and initialization functions.
+This function returns
+.Cm NULL
+on error or else a pointer to a
+.Cm struct decompressor_t .
+This structure contains a
+.Va void * config
+slot that can be used for storing any customization information.
+.It Bid
+The bid function is invoked with a pointer and size of a block of data.
+The decompressor can access its config data
+through the
+.Va decompressor
+element of the
+.Cm archive_read
+object.
+The bid function is otherwise stateless.
+In particular, it must not perform any I/O operations.
+.Pp
+The value returned by the bid function indicates its suitability
+for handling this data stream.
+A bid of zero will ensure that this decompressor is never invoked.
+Return zero if magic number checks fail.
+Otherwise, your initial implementation should return the number of bits
+actually checked.
+For example, if you verify two full bytes and three bits of another
+byte, bid 19.
+Note that the initial block may be very short;
+be careful to only inspect the data you are given.
+(The current decompressors require two bytes for correct bidding.)
+.It Initialize
+The winning bidder will have its init function called.
+This function should initialize the remaining slots of the
+.Va struct decompressor_t
+object pointed to by the
+.Va decompressor
+element of the
+.Va archive_read
+object.
+In particular, it should allocate any working data it needs
+in the
+.Va data
+slot of that structure.
+The init function is called with the block of data that
+was used for tasting.
+At this point, the decompressor is responsible for all I/O
+requests to the client callbacks.
+The decompressor is free to read more data as and when
+necessary.
+.It Satisfy I/O requests
+The format handler will invoke the
+.Va read_ahead ,
+.Va consume ,
+and
+.Va skip
+functions as needed.
+.It Finish
+The finish method is called only once when the archive is closed.
+It should release anything stored in the
+.Va data
+and
+.Va config
+slots of the
+.Va decompressor
+object.
+It should not invoke the client close callback.
+.El
+.Ss Format Layer
+The read formats have a similar lifecycle to the decompression handlers:
+.Bl -tag -compact -width indent
+.It Registration
+Allocate your private data and initialize your pointers.
+.It Bid
+Formats bid by invoking the
+.Fn read_ahead
+decompression method but not calling the
+.Fn consume
+method.
+This allows each bidder to look ahead in the input stream.
+Bidders should not look further ahead than necessary, as long
+look aheads put pressure on the decompression layer to buffer
+lots of data.
+Most formats only require a few hundred bytes of look ahead;
+look aheads of a few kilobytes are reasonable.
+(The ISO9660 reader sometimes looks ahead by 48k, which
+should be considered an upper limit.)
+.It Read header
+The header read is usually the most complex part of any format.
+There are a few strategies worth mentioning:
+For formats such as tar or cpio, reading and parsing the header is
+straightforward since headers alternate with data.
+For formats that store all header data at the beginning of the file,
+the first header read request may have to read all headers into
+memory and store that data, sorted by the location of the file
+data.
+Subsequent header read requests will skip forward to the
+beginning of the file data and return the corresponding header.
+.It Read Data
+The read data interface supports sparse files; this requires that
+each call return a block of data specifying the file offset and
+size.
+This may require you to carefully track the location so that you
+can return accurate file offsets for each read.
+Remember that the decompressor will return as much data as it has.
+Generally, you will want to request one byte,
+examine the return value to see how much data is available, and
+possibly trim that to the amount you can use.
+You should invoke consume for each block just before you return it.
+.It Skip All Data
+The skip data call should skip over all file data and trailing padding.
+This is called automatically by the API layer just before each
+header read.
+It is also called in response to the client calling the public
+.Fn data_skip
+function.
+.It Cleanup
+On cleanup, the format should release all of its allocated memory.
+.El
+.Ss API Layer
+XXX to do XXX
+.Sh WRITE ARCHITECTURE
+The write API has a similar set of four layers:
+an API layer, a format layer, a compression layer, and an I/O layer.
+The registration here is much simpler because only
+one format and one compression can be registered at a time.
+.Ss I/O Layer and Client Callbacks
+XXX To be written XXX
+.Ss Compression Layer
+XXX To be written XXX
+.Ss Format Layer
+XXX To be written XXX
+.Ss API Layer
+XXX To be written XXX
+.Sh WRITE_DISK ARCHITECTURE
+The write_disk API is intended to look just like the write API
+to clients.
+Since it does not handle multiple formats or compression, it
+is not layered internally.
+.Sh GENERAL SERVICES
+The
+.Nm archive_read ,
+.Nm archive_write ,
+and
+.Nm archive_write_disk
+objects all contain an initial
+.Nm archive
+object which provides common support for a set of standard services.
+(Recall that ANSI/ISO C90 guarantees that you can cast freely between
+a pointer to a structure and a pointer to the first element of that
+structure.)
+The
+.Nm archive
+object has a magic value that indicates which API this object
+is associated with,
+slots for storing error information,
+and function pointers for virtualized API functions.
+.Sh MISCELLANEOUS NOTES
+Connecting existing archiving libraries into libarchive is generally
+quite difficult.
+In particular, many existing libraries strongly assume that you
+are reading from a file; they seek forwards and backwards as necessary
+to locate various pieces of information.
+In contrast, libarchive never seeks backwards in its input, which
+sometimes requires very different approaches.
+.Pp
+For example, libarchive's ISO9660 support operates very differently
+from most ISO9660 readers.
+The libarchive support utilizes a work-queue design that
+keeps a list of known entries sorted by their location in the input.
+Whenever libarchive's ISO9660 implementation is asked for the next
+header, checks this list to find the next item on the disk.
+Directories are parsed when they are encountered and new
+items are added to the list.
+This design relies heavily on the ISO9660 image being optimized so that
+directories always occur earlier on the disk than the files they
+describe.
+.Pp
+Depending on the specific format, such approaches may not be possible.
+The ZIP format specification, for example, allows archivers to store
+key information only at the end of the file.
+In theory, it is possible to create ZIP archives that cannot
+be read without seeking.
+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
+.Sh HISTORY
+The
+.Nm libarchive
+library first appeared in
+.Fx 5.3 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm libarchive
+library was written by
+.An Tim Kientzle Aq kientzle@acm.org .
diff --git a/Utilities/cmlibarchive/libarchive/mtree.5 b/Utilities/cmlibarchive/libarchive/mtree.5
new file mode 100644
index 000000000..b6637d6f5
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/mtree.5
@@ -0,0 +1,269 @@
+.\" Copyright (c) 1989, 1990, 1993
+.\" The Regents of the University of California. 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.
+.\" 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+.\"
+.\" From: @(#)mtree.8 8.2 (Berkeley) 12/11/93
+.\" $FreeBSD$
+.\"
+.Dd August 20, 2007
+.Dt MTREE 5
+.Os
+.Sh NAME
+.Nm mtree
+.Nd format of mtree dir hierarchy files
+.Sh DESCRIPTION
+The
+.Nm
+format is a textual format that describes a collection of filesystem objects.
+Such files are typically used to create or verify directory hierarchies.
+.Ss General Format
+An
+.Nm
+file consists of a series of lines, each providing information
+about a single filesystem object.
+Leading whitespace is always ignored.
+.Pp
+When encoding file or pathnames, any backslash character or
+character outside of the 95 printable ASCII characters must be
+encoded as a a backslash followed by three
+octal digits.
+When reading mtree files, any appearance of a backslash
+followed by three octal digits should be converted into the
+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
+Lines beginning with
+.Cm #
+are ignored.
+.It Special
+Lines beginning with
+.Cm /
+are special commands that influence
+the interpretation of later lines.
+.It Relative
+If the first whitespace-delimited word has no
+.Cm /
+characters,
+it is the name of a file in the current directory.
+Any relative entry that describes a directory changes the
+current directory.
+.It dot-dot
+As a special case, a relative entry with the filename
+.Pa ..
+changes the current directory to the parent directory.
+Options on dot-dot entries are always ignored.
+.It Full
+If the first whitespace-delimited word has a
+.Cm /
+character after
+the first character, it is the pathname of a file relative to the
+starting directory.
+There can be multiple full entries describing the same file.
+.El
+.Pp
+Some tools that process
+.Nm
+files may require that multiple lines describing the same file
+occur consecutively.
+It is not permitted for the same file to be mentioned using
+both a relative and a full file specification.
+.Ss Special commands
+Two special commands are currently defined:
+.Bl -tag -width Cm
+.It Cm /set
+This command defines default values for one or more keywords.
+It is followed on the same line by one or more whitespace-separated
+keyword definitions.
+These definitions apply to all following files that do not specify
+a value for that keyword.
+.It Cm /unset
+This command removes any default value set by a previous
+.Cm /set
+command.
+It is followed on the same line by one or more keywords
+separated by whitespace.
+.El
+.Ss Keywords
+After the filename, a full or relative entry consists of zero
+or more whitespace-separated keyword definitions.
+Each such definition consists of a key from the following
+list immediately followed by an '=' sign
+and a value.
+Software programs reading mtree files should warn about
+unrecognized keywords.
+.Pp
+Currently supported keywords are as follows:
+.Bl -tag -width Cm
+.It Cm cksum
+The checksum of the file using the default algorithm specified by
+the
+.Xr cksum 1
+utility.
+.It Cm contents
+The full pathname of a file that holds the contents of this file.
+.It Cm flags
+The file flags as a symbolic name.
+See
+.Xr chflags 1
+for information on these names.
+If no flags are to be set the string
+.Dq none
+may be used to override the current default.
+.It Cm gid
+The file group as a numeric value.
+.It Cm gname
+The file group as a symbolic name.
+.It Cm ignore
+Ignore any file hierarchy below this file.
+.It Cm link
+The target of the symbolic link when type=link.
+.It Cm md5
+The MD5 message digest of the file.
+.It Cm md5digest
+A synonym for
+.Cm md5 .
+.It Cm mode
+The current file's permissions as a numeric (octal) or symbolic
+value.
+.It Cm nlink
+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 ripemd160digest
+The
+.Tn RIPEMD160
+message digest of the file.
+.It Cm rmd160
+A synonym for
+.Cm ripemd160digest .
+.It Cm rmd160digest
+A synonym for
+.Cm ripemd160digest .
+.It Cm sha1
+The
+.Tn FIPS
+160-1
+.Pq Dq Tn SHA-1
+message digest of the file.
+.It Cm sha1digest
+A synonym for
+.Cm sha1 .
+.It Cm sha256
+The
+.Tn FIPS
+180-2
+.Pq Dq Tn SHA-256
+message digest of the file.
+.It Cm sha256digest
+A synonym for
+.Cm sha256 .
+.It Cm size
+The size, in bytes, of the file.
+.It Cm time
+The last modification time of the file.
+.It Cm type
+The type of the file; may be set to any one of the following:
+.Pp
+.Bl -tag -width Cm -compact
+.It Cm block
+block special device
+.It Cm char
+character special device
+.It Cm dir
+directory
+.It Cm fifo
+fifo
+.It Cm file
+regular file
+.It Cm link
+symbolic link
+.It Cm socket
+socket
+.El
+.It Cm uid
+The file owner as a numeric value.
+.It Cm uname
+The file owner as a symbolic name.
+.El
+.Pp
+.Sh SEE ALSO
+.Xr cksum 1 ,
+.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
+utility appeared in
+.Bx 4.3 Reno .
+The
+.Tn MD5
+digest capability was added in
+.Fx 2.1 ,
+in response to the widespread use of programs which can spoof
+.Xr cksum 1 .
+The
+.Tn SHA-1
+and
+.Tn RIPEMD160
+digests were added in
+.Fx 4.0 ,
+as new attacks have demonstrated weaknesses in
+.Tn MD5 .
+The
+.Tn SHA-256
+digest was added in
+.Fx 6.0 .
+Support for file flags was added in
+.Fx 4.0 ,
+and mostly comes from
+.Nx .
+The
+.Dq full
+entry format was added by
+.Nx .
diff --git a/Utilities/cmlibarchive/libarchive/tar.5 b/Utilities/cmlibarchive/libarchive/tar.5
new file mode 100644
index 000000000..65875bd61
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/tar.5
@@ -0,0 +1,947 @@
+.\" Copyright (c) 2003-2009 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 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: head/lib/libarchive/tar.5 201077 2009-12-28 01:50:23Z kientzle $
+.\"
+.Dd December 27, 2009
+.Dt TAR 5
+.Os
+.Sh NAME
+.Nm tar
+.Nd format of tape archive files
+.Sh DESCRIPTION
+The
+.Nm
+archive format collects any number of files, directories, and other
+file system objects (symbolic links, device nodes, etc.) into a single
+stream of bytes.
+The format was originally designed to be used with
+tape drives that operate with fixed-size blocks, but is widely used as
+a general packaging mechanism.
+.Ss General Format
+A
+.Nm
+archive consists of a series of 512-byte records.
+Each file system object requires a header record which stores basic metadata
+(pathname, owner, permissions, etc.) and zero or more records containing any
+file data.
+The end of the archive is indicated by two records consisting
+entirely of zero bytes.
+.Pp
+For compatibility with tape drives that use fixed block sizes,
+programs that read or write tar files always read or write a fixed
+number of records with each I/O operation.
+These
+.Dq blocks
+are always a multiple of the record size.
+The maximum block size supported by early
+implementations was 10240 bytes or 20 records.
+This is still the default for most implementations
+although block sizes of 1MiB (2048 records) or larger are
+commonly used with modern high-speed tape drives.
+(Note: the terms
+.Dq block
+and
+.Dq record
+here are not entirely standard; this document follows the
+convention established by John Gilmore in documenting
+.Nm pdtar . )
+.Ss Old-Style Archive Format
+The original tar archive format has been extended many times to
+include additional information that various implementors found
+necessary.
+This section describes the variant implemented by the tar command
+included in
+.At v7 ,
+which seems to be the earliest widely-used version of the tar program.
+.Pp
+The header record for an old-style
+.Nm
+archive consists of the following:
+.Bd -literal -offset indent
+struct header_old_tar {
+ char name[100];
+ char mode[8];
+ char uid[8];
+ char gid[8];
+ char size[12];
+ char mtime[12];
+ char checksum[8];
+ char linkflag[1];
+ char linkname[100];
+ char pad[255];
+};
+.Ed
+All unused bytes in the header record are filled with nulls.
+.Bl -tag -width indent
+.It Va name
+Pathname, stored as a null-terminated string.
+Early tar implementations only stored regular files (including
+hardlinks to those files).
+One common early convention used a trailing "/" character to indicate
+a directory name, allowing directory permissions and owner information
+to be archived and restored.
+.It Va mode
+File mode, stored as an octal number in ASCII.
+.It Va uid , Va gid
+User id and group id of owner, as octal numbers in ASCII.
+.It Va size
+Size of file, as octal number in ASCII.
+For regular files only, this indicates the amount of data
+that follows the header.
+In particular, this field was ignored by early tar implementations
+when extracting hardlinks.
+Modern writers should always store a zero length for hardlink entries.
+.It Va mtime
+Modification time of file, as an octal number in ASCII.
+This indicates the number of seconds since the start of the epoch,
+00:00:00 UTC January 1, 1970.
+Note that negative values should be avoided
+here, as they are handled inconsistently.
+.It Va checksum
+Header checksum, stored as an octal number in ASCII.
+To compute the checksum, set the checksum field to all spaces,
+then sum all bytes in the header using unsigned arithmetic.
+This field should be stored as six octal digits followed by a null and a space
+character.
+Note that many early implementations of tar used signed arithmetic
+for the checksum field, which can cause interoperability problems
+when transferring archives between systems.
+Modern robust readers compute the checksum both ways and accept the
+header if either computation matches.
+.It Va linkflag , Va linkname
+In order to preserve hardlinks and conserve tape, a file
+with multiple links is only written to the archive the first
+time it is encountered.
+The next time it is encountered, the
+.Va linkflag
+is set to an ASCII
+.Sq 1
+and the
+.Va linkname
+field holds the first name under which this file appears.
+(Note that regular files have a null value in the
+.Va linkflag
+field.)
+.El
+.Pp
+Early tar implementations varied in how they terminated these fields.
+The tar command in
+.At v7
+used the following conventions (this is also documented in early BSD manpages):
+the pathname must be null-terminated;
+the mode, uid, and gid fields must end in a space and a null byte;
+the size and mtime fields must end in a space;
+the checksum is terminated by a null and a space.
+Early implementations filled the numeric fields with leading spaces.
+This seems to have been common practice until the
+.St -p1003.1-88
+standard was released.
+For best portability, modern implementations should fill the numeric
+fields with leading zeros.
+.Ss Pre-POSIX Archives
+An early draft of
+.St -p1003.1-88
+served as the basis for John Gilmore's
+.Nm pdtar
+program and many system implementations from the late 1980s
+and early 1990s.
+These archives generally follow the POSIX ustar
+format described below with the following variations:
+.Bl -bullet -compact -width indent
+.It
+The magic value consists of the five characters
+.Dq ustar
+followed by a space.
+The version field contains a space character followed by a null.
+.It
+The numeric fields are generally filled with leading spaces
+(not leading zeros as recommended in the final standard).
+.It
+The prefix field is often not used, limiting pathnames to
+the 100 characters of old-style archives.
+.El
+.Ss POSIX ustar Archives
+.St -p1003.1-88
+defined a standard tar file format to be read and written
+by compliant implementations of
+.Xr tar 1 .
+This format is often called the
+.Dq ustar
+format, after the magic value used
+in the header.
+(The name is an acronym for
+.Dq Unix Standard TAR . )
+It extends the historic format with new fields:
+.Bd -literal -offset indent
+struct header_posix_ustar {
+ char name[100];
+ char mode[8];
+ char uid[8];
+ char gid[8];
+ char size[12];
+ char mtime[12];
+ char checksum[8];
+ char typeflag[1];
+ char linkname[100];
+ char magic[6];
+ char version[2];
+ char uname[32];
+ char gname[32];
+ char devmajor[8];
+ char devminor[8];
+ char prefix[155];
+ char pad[12];
+};
+.Ed
+.Bl -tag -width indent
+.It Va typeflag
+Type of entry.
+POSIX extended the earlier
+.Va linkflag
+field with several new type values:
+.Bl -tag -width indent -compact
+.It Dq 0
+Regular file.
+NUL should be treated as a synonym, for compatibility purposes.
+.It Dq 1
+Hard link.
+.It Dq 2
+Symbolic link.
+.It Dq 3
+Character device node.
+.It Dq 4
+Block device node.
+.It Dq 5
+Directory.
+.It Dq 6
+FIFO node.
+.It Dq 7
+Reserved.
+.It Other
+A POSIX-compliant implementation must treat any unrecognized typeflag value
+as a regular file.
+In particular, writers should ensure that all entries
+have a valid filename so that they can be restored by readers that do not
+support the corresponding extension.
+Uppercase letters "A" through "Z" are reserved for custom extensions.
+Note that sockets and whiteout entries are not archivable.
+.El
+It is worth noting that the
+.Va size
+field, in particular, has different meanings depending on the type.
+For regular files, of course, it indicates the amount of data
+following the header.
+For directories, it may be used to indicate the total size of all
+files in the directory, for use by operating systems that pre-allocate
+directory space.
+For all other types, it should be set to zero by writers and ignored
+by readers.
+.It Va magic
+Contains the magic value
+.Dq ustar
+followed by a NUL byte to indicate that this is a POSIX standard archive.
+Full compliance requires the uname and gname fields be properly set.
+.It Va version
+Version.
+This should be
+.Dq 00
+(two copies of the ASCII digit zero) for POSIX standard archives.
+.It Va uname , Va gname
+User and group names, as null-terminated ASCII strings.
+These should be used in preference to the uid/gid values
+when they are set and the corresponding names exist on
+the system.
+.It Va devmajor , Va devminor
+Major and minor numbers for character device or block device entry.
+.It Va name , Va prefix
+If the pathname is too long to fit in the 100 bytes provided by the standard
+format, it can be split at any
+.Pa /
+character with the first portion going into the prefix field.
+If the prefix field is not empty, the reader will prepend
+the prefix value and a
+.Pa /
+character to the regular name field to obtain the full pathname.
+The standard does not require a trailing
+.Pa /
+character on directory names, though most implementations still
+include this for compatibility reasons.
+.El
+.Pp
+Note that all unused bytes must be set to
+.Dv NUL .
+.Pp
+Field termination is specified slightly differently by POSIX
+than by previous implementations.
+The
+.Va magic ,
+.Va uname ,
+and
+.Va gname
+fields must have a trailing
+.Dv NUL .
+The
+.Va pathname ,
+.Va linkname ,
+and
+.Va prefix
+fields must have a trailing
+.Dv NUL
+unless they fill the entire field.
+(In particular, it is possible to store a 256-character pathname if it
+happens to have a
+.Pa /
+as the 156th character.)
+POSIX requires numeric fields to be zero-padded in the front, and requires
+them to be terminated with either space or
+.Dv NUL
+characters.
+.Pp
+Currently, most tar implementations comply with the ustar
+format, occasionally extending it by adding new fields to the
+blank area at the end of the header record.
+.Ss Numeric Extensions
+There have been several attempts to extend the range of sizes
+or times supported by modifying how numbers are stored in the
+header.
+.Pp
+One obvious extension to increase the size of files is to
+eliminate the terminating characters from the various
+numeric fields.
+For example, the standard only allows the size field to contain
+11 octal digits, reserving the twelfth byte for a trailing
+NUL character.
+Allowing 12 octal digits allows file sizes up to 64 GB.
+.Pp
+Another extension, utilized by GNU tar, star, and other newer
+.Nm
+implementations, permits binary numbers in the standard numeric fields.
+This is flagged by setting the high bit of the first byte.
+The remainder of the field is treated as a signed twos-complement
+value.
+This permits 95-bit values for the length and time fields
+and 63-bit values for the uid, gid, and device numbers.
+In particular, this provides a consistent way to handle
+negative time values.
+GNU tar supports this extension for the
+length, mtime, ctime, and atime fields.
+Joerg Schilling's star program and the libarchive library support
+this extension for all numeric fields.
+Note that this extension is largely obsoleted by the extended
+attribute record provided by the pax interchange format.
+.Pp
+Another early GNU extension allowed base-64 values rather than octal.
+This extension was short-lived and is no longer supported by any
+implementation.
+.Ss Pax Interchange Format
+There are many attributes that cannot be portably stored in a
+POSIX ustar archive.
+.St -p1003.1-2001
+defined a
+.Dq pax interchange format
+that uses two new types of entries to hold text-formatted
+metadata that applies to following entries.
+Note that a pax interchange format archive is a ustar archive in every
+respect.
+The new data is stored in ustar-compatible archive entries that use the
+.Dq x
+or
+.Dq g
+typeflag.
+In particular, older implementations that do not fully support these
+extensions will extract the metadata into regular files, where the
+metadata can be examined as necessary.
+.Pp
+An entry in a pax interchange format archive consists of one or
+two standard ustar entries, each with its own header and data.
+The first optional entry stores the extended attributes
+for the following entry.
+This optional first entry has an "x" typeflag and a size field that
+indicates the total size of the extended attributes.
+The extended attributes themselves are stored as a series of text-format
+lines encoded in the portable UTF-8 encoding.
+Each line consists of a decimal number, a space, a key string, an equals
+sign, a value string, and a new line.
+The decimal number indicates the length of the entire line, including the
+initial length field and the trailing newline.
+An example of such a field is:
+.Dl 25 ctime=1084839148.1212\en
+Keys in all lowercase are standard keys.
+Vendors can add their own keys by prefixing them with an all uppercase
+vendor name and a period.
+Note that, unlike the historic header, numeric values are stored using
+decimal, not octal.
+A description of some common keys follows:
+.Bl -tag -width indent
+.It Cm atime , Cm ctime , Cm mtime
+File access, inode change, and modification times.
+These fields can be negative or include a decimal point and a fractional value.
+.It Cm hdrcharset
+The character set used by the pax extension values.
+By default, all textual values in the pax extended attributes
+are assumed to be in UTF-8, including pathnames, user names,
+and group names.
+In some cases, it is not possible to translate local
+conventions into UTF-8.
+If this key is present and the value is the six-character ASCII string
+.Dq BINARY ,
+then all textual values are assumed to be in a platform-dependent
+multi-byte encoding.
+Note that there are only two valid values for this key:
+.Dq BINARY
+or
+.Dq ISO-IR\ 10646\ 2000\ UTF-8 .
+No other values are permitted by the standard, and
+the latter value should generally not be used as it is the
+default when this key is not specified.
+In particular, this flag should not be used as a general
+mechanism to allow filenames to be stored in arbitrary
+encodings.
+.It Cm uname , Cm uid , Cm gname , Cm gid
+User name, group name, and numeric UID and GID values.
+The user name and group name stored here are encoded in UTF8
+and can thus include non-ASCII characters.
+The UID and GID fields can be of arbitrary length.
+.It Cm linkpath
+The full path of the linked-to file.
+Note that this is encoded in UTF8 and can thus include non-ASCII characters.
+.It Cm path
+The full pathname of the entry.
+Note that this is encoded in UTF8 and can thus include non-ASCII characters.
+.It Cm realtime.* , Cm security.*
+These keys are reserved and may be used for future standardization.
+.It Cm size
+The size of the file.
+Note that there is no length limit on this field, allowing conforming
+archives to store files much larger than the historic 8GB limit.
+.It Cm SCHILY.*
+Vendor-specific attributes used by Joerg Schilling's
+.Nm star
+implementation.
+.It Cm SCHILY.acl.access , Cm SCHILY.acl.default
+Stores the access and default ACLs as textual strings in a format
+that is an extension of the format specified by POSIX.1e draft 17.
+In particular, each user or group access specification can include a fourth
+colon-separated field with the numeric UID or GID.
+This allows ACLs to be restored on systems that may not have complete
+user or group information available (such as when NIS/YP or LDAP services
+are temporarily unavailable).
+.It Cm SCHILY.devminor , Cm SCHILY.devmajor
+The full minor and major numbers for device nodes.
+.It Cm SCHILY.fflags
+The file flags.
+.It Cm SCHILY.realsize
+The full size of the file on disk.
+XXX explain? XXX
+.It Cm SCHILY.dev, Cm SCHILY.ino , Cm SCHILY.nlinks
+The device number, inode number, and link count for the entry.
+In particular, note that a pax interchange format archive using Joerg
+Schilling's
+.Cm SCHILY.*
+extensions can store all of the data from
+.Va struct stat .
+.It Cm LIBARCHIVE.*
+Vendor-specific attributes used by the
+.Nm libarchive
+library and programs that use it.
+.It Cm LIBARCHIVE.creationtime
+The time when the file was created.
+(This should not be confused with the POSIX
+.Dq ctime
+attribute, which refers to the time when the file
+metadata was last changed.)
+.It Cm LIBARCHIVE.xattr. Ns Ar namespace Ns . Ns Ar key
+Libarchive stores POSIX.1e-style extended attributes using
+keys of this form.
+The
+.Ar key
+value is URL-encoded:
+All non-ASCII characters and the two special characters
+.Dq =
+and
+.Dq %
+are encoded as
+.Dq %
+followed by two uppercase hexadecimal digits.
+The value of this key is the extended attribute value
+encoded in base 64.
+XXX Detail the base-64 format here XXX
+.It Cm VENDOR.*
+XXX document other vendor-specific extensions XXX
+.El
+.Pp
+Any values stored in an extended attribute override the corresponding
+values in the regular tar header.
+Note that compliant readers should ignore the regular fields when they
+are overridden.
+This is important, as existing archivers are known to store non-compliant
+values in the standard header fields in this situation.
+There are no limits on length for any of these fields.
+In particular, numeric fields can be arbitrarily large.
+All text fields are encoded in UTF8.
+Compliant writers should store only portable 7-bit ASCII characters in
+the standard ustar header and use extended
+attributes whenever a text value contains non-ASCII characters.
+.Pp
+In addition to the
+.Cm x
+entry described above, the pax interchange format
+also supports a
+.Cm g
+entry.
+The
+.Cm g
+entry is identical in format, but specifies attributes that serve as
+defaults for all subsequent archive entries.
+The
+.Cm g
+entry is not widely used.
+.Pp
+Besides the new
+.Cm x
+and
+.Cm g
+entries, the pax interchange format has a few other minor variations
+from the earlier ustar format.
+The most troubling one is that hardlinks are permitted to have
+data following them.
+This allows readers to restore any hardlink to a file without
+having to rewind the archive to find an earlier entry.
+However, it creates complications for robust readers, as it is no longer
+clear whether or not they should ignore the size field for hardlink entries.
+.Ss GNU Tar Archives
+The GNU tar program started with a pre-POSIX format similar to that
+described earlier and has extended it using several different mechanisms:
+It added new fields to the empty space in the header (some of which was later
+used by POSIX for conflicting purposes);
+it allowed the header to be continued over multiple records;
+and it defined new entries that modify following entries
+(similar in principle to the
+.Cm x
+entry described above, but each GNU special entry is single-purpose,
+unlike the general-purpose
+.Cm x
+entry).
+As a result, GNU tar archives are not POSIX compatible, although
+more lenient POSIX-compliant readers can successfully extract most
+GNU tar archives.
+.Bd -literal -offset indent
+struct header_gnu_tar {
+ char name[100];
+ char mode[8];
+ char uid[8];
+ char gid[8];
+ char size[12];
+ char mtime[12];
+ char checksum[8];
+ char typeflag[1];
+ char linkname[100];
+ char magic[6];
+ char version[2];
+ char uname[32];
+ char gname[32];
+ char devmajor[8];
+ char devminor[8];
+ char atime[12];
+ char ctime[12];
+ char offset[12];
+ char longnames[4];
+ char unused[1];
+ struct {
+ char offset[12];
+ char numbytes[12];
+ } sparse[4];
+ char isextended[1];
+ char realsize[12];
+ char pad[17];
+};
+.Ed
+.Bl -tag -width indent
+.It Va typeflag
+GNU tar uses the following special entry types, in addition to
+those defined by POSIX:
+.Bl -tag -width indent
+.It "7"
+GNU tar treats type "7" records identically to type "0" records,
+except on one obscure RTOS where they are used to indicate the
+pre-allocation of a contiguous file on disk.
+.It "D"
+This indicates a directory entry.
+Unlike the POSIX-standard "5"
+typeflag, the header is followed by data records listing the names
+of files in this directory.
+Each name is preceded by an ASCII "Y"
+if the file is stored in this archive or "N" if the file is not
+stored in this archive.
+Each name is terminated with a null, and
+an extra null marks the end of the name list.
+The purpose of this
+entry is to support incremental backups; a program restoring from
+such an archive may wish to delete files on disk that did not exist
+in the directory when the archive was made.
+.Pp
+Note that the "D" typeflag specifically violates POSIX, which requires
+that unrecognized typeflags be restored as normal files.
+In this case, restoring the "D" entry as a file could interfere
+with subsequent creation of the like-named directory.
+.It "K"
+The data for this entry is a long linkname for the following regular entry.
+.It "L"
+The data for this entry is a long pathname for the following regular entry.
+.It "M"
+This is a continuation of the last file on the previous volume.
+GNU multi-volume archives guarantee that each volume begins with a valid
+entry header.
+To ensure this, a file may be split, with part stored at the end of one volume,
+and part stored at the beginning of the next volume.
+The "M" typeflag indicates that this entry continues an existing file.
+Such entries can only occur as the first or second entry
+in an archive (the latter only if the first entry is a volume label).
+The
+.Va size
+field specifies the size of this entry.
+The
+.Va offset
+field at bytes 369-380 specifies the offset where this file fragment
+begins.
+The
+.Va realsize
+field specifies the total size of the file (which must equal
+.Va size
+plus
+.Va offset ) .
+When extracting, GNU tar checks that the header file name is the one it is
+expecting, that the header offset is in the correct sequence, and that
+the sum of offset and size is equal to realsize.
+.It "N"
+Type "N" records are no longer generated by GNU tar.
+They contained a
+list of files to be renamed or symlinked after extraction; this was
+originally used to support long names.
+The contents of this record
+are a text description of the operations to be done, in the form
+.Dq Rename %s to %s\en
+or
+.Dq Symlink %s to %s\en ;
+in either case, both
+filenames are escaped using K&R C syntax.
+Due to security concerns, "N" records are now generally ignored
+when reading archives.
+.It "S"
+This is a
+.Dq sparse
+regular file.
+Sparse files are stored as a series of fragments.
+The header contains a list of fragment offset/length pairs.
+If more than four such entries are required, the header is
+extended as necessary with
+.Dq extra
+header extensions (an older format that is no longer used), or
+.Dq sparse
+extensions.
+.It "V"
+The
+.Va name
+field should be interpreted as a tape/volume header name.
+This entry should generally be ignored on extraction.
+.El
+.It Va magic
+The magic field holds the five characters
+.Dq ustar
+followed by a space.
+Note that POSIX ustar archives have a trailing null.
+.It Va version
+The version field holds a space character followed by a null.
+Note that POSIX ustar archives use two copies of the ASCII digit
+.Dq 0 .
+.It Va atime , Va ctime
+The time the file was last accessed and the time of
+last change of file information, stored in octal as with
+.Va mtime .
+.It Va longnames
+This field is apparently no longer used.
+.It Sparse Va offset / Va numbytes
+Each such structure specifies a single fragment of a sparse
+file.
+The two fields store values as octal numbers.
+The fragments are each padded to a multiple of 512 bytes
+in the archive.
+On extraction, the list of fragments is collected from the
+header (including any extension headers), and the data
+is then read and written to the file at appropriate offsets.
+.It Va isextended
+If this is set to non-zero, the header will be followed by additional
+.Dq sparse header
+records.
+Each such record contains information about as many as 21 additional
+sparse blocks as shown here:
+.Bd -literal -offset indent
+struct gnu_sparse_header {
+ struct {
+ char offset[12];
+ char numbytes[12];
+ } sparse[21];
+ char isextended[1];
+ char padding[7];
+};
+.Ed
+.It Va realsize
+A binary representation of the file's complete size, with a much larger range
+than the POSIX file size.
+In particular, with
+.Cm M
+type files, the current entry is only a portion of the file.
+In that case, the POSIX size field will indicate the size of this
+entry; the
+.Va realsize
+field will indicate the total size of the file.
+.El
+.Ss GNU tar pax archives
+GNU tar 1.14 (XXX check this XXX) and later will write
+pax interchange format archives when you specify the
+.Fl -posix
+flag.
+This format follows the pax interchange format closely,
+using some
+.Cm SCHILY
+tags and introducing new keywords to store sparse file information.
+There have been three iterations of the sparse file support, referred to
+as
+.Dq 0.0 ,
+.Dq 0.1 ,
+and
+.Dq 1.0 .
+.Bl -tag -width indent
+.It Cm GNU.sparse.numblocks , Cm GNU.sparse.offset , Cm GNU.sparse.numbytes , Cm GNU.sparse.size
+The
+.Dq 0.0
+format used an initial
+.Cm GNU.sparse.numblocks
+attribute to indicate the number of blocks in the file, a pair of
+.Cm GNU.sparse.offset
+and
+.Cm GNU.sparse.numbytes
+to indicate the offset and size of each block,
+and a single
+.Cm GNU.sparse.size
+to indicate the full size of the file.
+This is not the same as the size in the tar header because the
+latter value does not include the size of any holes.
+This format required that the order of attributes be preserved and
+relied on readers accepting multiple appearances of the same attribute
+names, which is not officially permitted by the standards.
+.It Cm GNU.sparse.map
+The
+.Dq 0.1
+format used a single attribute that stored a comma-separated
+list of decimal numbers.
+Each pair of numbers indicated the offset and size, respectively,
+of a block of data.
+This does not work well if the archive is extracted by an archiver
+that does not recognize this extension, since many pax implementations
+simply discard unrecognized attributes.
+.It Cm GNU.sparse.major , Cm GNU.sparse.minor , Cm GNU.sparse.name , Cm GNU.sparse.realsize
+The
+.Dq 1.0
+format stores the sparse block map in one or more 512-byte blocks
+prepended to the file data in the entry body.
+The pax attributes indicate the existence of this map
+(via the
+.Cm GNU.sparse.major
+and
+.Cm GNU.sparse.minor
+fields)
+and the full size of the file.
+The
+.Cm GNU.sparse.name
+holds the true name of the file.
+To avoid confusion, the name stored in the regular tar header
+is a modified name so that extraction errors will be apparent
+to users.
+.El
+.Ss Solaris Tar
+XXX More Details Needed XXX
+.Pp
+Solaris tar (beginning with SunOS XXX 5.7 ?? XXX) supports an
+.Dq extended
+format that is fundamentally similar to pax interchange format,
+with the following differences:
+.Bl -bullet -compact -width indent
+.It
+Extended attributes are stored in an entry whose type is
+.Cm X ,
+not
+.Cm x ,
+as used by pax interchange format.
+The detailed format of this entry appears to be the same
+as detailed above for the
+.Cm x
+entry.
+.It
+An additional
+.Cm A
+header is used to store an ACL for the following regular entry.
+The body of this entry contains a seven-digit octal number
+followed by a zero byte, followed by the
+textual ACL description.
+The octal value is the number of ACL entries
+plus a constant that indicates the ACL type: 01000000
+for POSIX.1e ACLs and 03000000 for NFSv4 ACLs.
+.El
+.Ss AIX Tar
+XXX More details needed XXX
+.Pp
+AIX Tar uses a ustar-formatted header with the type
+.Cm A
+for storing coded ACL information.
+Unlike the Solaris format, AIX tar writes this header after the
+regular file body to which it applies.
+The pathname in this header is either
+.Cm NFS4
+or
+.Cm AIXC
+to indicate the type of ACL stored.
+The actual ACL is stored in platform-specific binary format.
+.Ss Mac OS X Tar
+The tar distributed with Apple's Mac OS X stores most regular files
+as two separate files in the tar archive.
+The two files have the same name except that the first
+one has
+.Dq ._
+prepended to the last path element.
+This special file stores an AppleDouble-encoded
+binary blob with additional metadata about the second file,
+including ACL, extended attributes, and resources.
+To recreate the original file on disk, each
+separate file can be extracted and the Mac OS X
+.Fn copyfile
+function can be used to unpack the separate
+metadata file and apply it to th regular file.
+Conversely, the same function provides a
+.Dq pack
+option to encode the extended metadata from
+a file into a separate file whose contents
+can then be put into a tar archive.
+.Pp
+Note that the Apple extended attributes interact
+badly with long filenames.
+Since each file is stored with the full name,
+a separate set of extensions needs to be included
+in the archive for each one, doubling the overhead
+required for files with long names.
+.Ss Summary of tar type codes
+The following list is a condensed summary of the type codes
+used in tar header records generated by different tar implementations.
+More details about specific implementations can be found above:
+.Bl -tag -compact -width XXX
+.It NUL
+Early tar programs stored a zero byte for regular files.
+.It Cm 0
+POSIX standard type code for a regular file.
+.It Cm 1
+POSIX standard type code for a hard link description.
+.It Cm 2
+POSIX standard type code for a symbolic link description.
+.It Cm 3
+POSIX standard type code for a character device node.
+.It Cm 4
+POSIX standard type code for a block device node.
+.It Cm 5
+POSIX standard type code for a directory.
+.It Cm 6
+POSIX standard type code for a FIFO.
+.It Cm 7
+POSIX reserved.
+.It Cm 7
+GNU tar used for pre-allocated files on some systems.
+.It Cm A
+Solaris tar ACL description stored prior to a regular file header.
+.It Cm A
+AIX tar ACL description stored after the file body.
+.It Cm D
+GNU tar directory dump.
+.It Cm K
+GNU tar long linkname for the following header.
+.It Cm L
+GNU tar long pathname for the following header.
+.It Cm M
+GNU tar multivolume marker, indicating the file is a continuation of a file from the previous volume.
+.It Cm N
+GNU tar long filename support. Deprecated.
+.It Cm S
+GNU tar sparse regular file.
+.It Cm V
+GNU tar tape/volume header name.
+.It Cm X
+Solaris tar general-purpose extension header.
+.It Cm g
+POSIX pax interchange format global extensions.
+.It Cm x
+POSIX pax interchange format per-file extensions.
+.El
+.Sh SEE ALSO
+.Xr ar 1 ,
+.Xr pax 1 ,
+.Xr tar 1
+.Sh STANDARDS
+The
+.Nm tar
+utility is no longer a part of POSIX or the Single Unix Standard.
+It last appeared in
+.St -susv2 .
+It has been supplanted in subsequent standards by
+.Xr pax 1 .
+The ustar format is currently part of the specification for the
+.Xr pax 1
+utility.
+The pax interchange file format is new with
+.St -p1003.1-2001 .
+.Sh HISTORY
+A
+.Nm tar
+command appeared in Seventh Edition Unix, which was released in January, 1979.
+It replaced the
+.Nm tp
+program from Fourth Edition Unix which in turn replaced the
+.Nm tap
+program from First Edition Unix.
+John Gilmore's
+.Nm pdtar
+public-domain implementation (circa 1987) was highly influential
+and formed the basis of
+.Nm GNU tar
+(circa 1988).
+Joerg Shilling's
+.Nm star
+archiver is another open-source (GPL) archiver (originally developed
+circa 1985) which features complete support for pax interchange
+format.
+.Pp
+This documentation was written as part of the
+.Nm libarchive
+and
+.Nm bsdtar
+project by
+.An Tim Kientzle Aq kientzle@FreeBSD.org .
diff --git a/Utilities/cmzlib/.NoDartCoverage b/Utilities/cmzlib/.NoDartCoverage
new file mode 100644
index 000000000..3c9972938
--- /dev/null
+++ b/Utilities/cmzlib/.NoDartCoverage
@@ -0,0 +1 @@
+# do not do coverage in this directory
diff --git a/Utilities/cmzlib/CMakeLists.txt b/Utilities/cmzlib/CMakeLists.txt
new file mode 100644
index 000000000..c42a43485
--- /dev/null
+++ b/Utilities/cmzlib/CMakeLists.txt
@@ -0,0 +1,43 @@
+PROJECT(CMZLIB)
+
+INCLUDE_DIRECTORIES(
+ "${CMZLIB_SOURCE_DIR}"
+ "${CMZLIB_SOURCE_DIR}/.."
+ "${CMZLIB_BINARY_DIR}/.."
+ )
+
+# source files for zlib
+SET(ZLIB_SRCS
+ adler32.c compress.c crc32.c deflate.c gzio.c inffast.c
+ inflate.c inftrees.c trees.c uncompr.c zutil.c
+ )
+
+# for windows add the .def and .rc files to the source list
+# if building shared libs
+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)
+ ENDIF(BUILD_SHARED_LIBS)
+ENDIF(WIN32)
+
+CONFIGURE_FILE(${CMZLIB_SOURCE_DIR}/.NoDartCoverage
+ ${CMZLIB_BINARY_DIR}/.NoDartCoverage)
+CONFIGURE_FILE(${CMZLIB_SOURCE_DIR}/zlibDllConfig.h.in
+ ${CMZLIB_BINARY_DIR}/zlibDllConfig.h)
+
+FOREACH(name zlib zconf cm_zlib_mangle)
+ CONFIGURE_FILE(${CMZLIB_SOURCE_DIR}/${name}.h
+ ${CMZLIB_BINARY_DIR}/${name}.h COPYONLY)
+ENDFOREACH(name)
+
+
+ADD_LIBRARY(cmzlib ${ZLIB_SRCS})
+
+INSTALL(FILES Copyright.txt DESTINATION ${CMake_DOC_DEST}/cmzlib)
diff --git a/Utilities/cmzlib/ChangeLog b/Utilities/cmzlib/ChangeLog
new file mode 100644
index 000000000..7f6869d32
--- /dev/null
+++ b/Utilities/cmzlib/ChangeLog
@@ -0,0 +1,855 @@
+
+ ChangeLog file for zlib
+
+Changes in 1.2.3 (18 July 2005)
+- Apply security vulnerability fixes to contrib/infback9 as well
+- Clean up some text files (carriage returns, trailing space)
+- Update testzlib, vstudio, masmx64, and masmx86 in contrib [Vollant]
+
+Changes in 1.2.2.4 (11 July 2005)
+- Add inflatePrime() function for starting inflation at bit boundary
+- Avoid some Visual C warnings in deflate.c
+- Avoid more silly Visual C warnings in inflate.c and inftrees.c for 64-bit
+ compile
+- Fix some spelling errors in comments [Betts]
+- Correct inflateInit2() error return documentation in zlib.h
+- Added zran.c example of compressed data random access to examples
+ directory, shows use of inflatePrime()
+- Fix cast for assignments to strm->state in inflate.c and infback.c
+- Fix zlibCompileFlags() in zutil.c to use 1L for long shifts [Oberhumer]
+- Move declarations of gf2 functions to right place in crc32.c [Oberhumer]
+- Add cast in trees.c t avoid a warning [Oberhumer]
+- Avoid some warnings in fitblk.c, gun.c, gzjoin.c in examples [Oberhumer]
+- Update make_vms.com [Zinser]
+- Initialize state->write in inflateReset() since copied in inflate_fast()
+- Be more strict on incomplete code sets in inflate_table() and increase
+ ENOUGH and MAXD -- this repairs a possible security vulnerability for
+ invalid inflate input. Thanks to Tavis Ormandy and Markus Oberhumer for
+ discovering the vulnerability and providing test cases.
+- Add ia64 support to configure for HP-UX [Smith]
+- Add error return to gzread() for format or i/o error [Levin]
+- Use malloc.h for OS/2 [Necasek]
+
+Changes in 1.2.2.3 (27 May 2005)
+- Replace 1U constants in inflate.c and inftrees.c for 64-bit compile
+- Typecast fread() return values in gzio.c [Vollant]
+- Remove trailing space in minigzip.c outmode (VC++ can't deal with it)
+- Fix crc check bug in gzread() after gzungetc() [Heiner]
+- Add the deflateTune() function to adjust internal compression parameters
+- Add a fast gzip decompressor, gun.c, to examples (use of inflateBack)
+- Remove an incorrect assertion in examples/zpipe.c
+- Add C++ wrapper in infback9.h [Donais]
+- Fix bug in inflateCopy() when decoding fixed codes
+- Note in zlib.h how much deflateSetDictionary() actually uses
+- Remove USE_DICT_HEAD in deflate.c (would mess up inflate if used)
+- Add _WIN32_WCE to define WIN32 in zconf.in.h [Spencer]
+- Don't include stderr.h or errno.h for _WIN32_WCE in zutil.h [Spencer]
+- Add gzdirect() function to indicate transparent reads
+- Update contrib/minizip [Vollant]
+- Fix compilation of deflate.c when both ASMV and FASTEST [Oberhumer]
+- Add casts in crc32.c to avoid warnings [Oberhumer]
+- Add contrib/masmx64 [Vollant]
+- Update contrib/asm586, asm686, masmx86, testzlib, vstudio [Vollant]
+
+Changes in 1.2.2.2 (30 December 2004)
+- Replace structure assignments in deflate.c and inflate.c with zmemcpy to
+ avoid implicit memcpy calls (portability for no-library compilation)
+- Increase sprintf() buffer size in gzdopen() to allow for large numbers
+- Add INFLATE_STRICT to check distances against zlib header
+- Improve WinCE errno handling and comments [Chang]
+- Remove comment about no gzip header processing in FAQ
+- Add Z_FIXED strategy option to deflateInit2() to force fixed trees
+- Add updated make_vms.com [Coghlan], update README
+- Create a new "examples" directory, move gzappend.c there, add zpipe.c,
+ fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html.
+- Add FAQ entry and comments in deflate.c on uninitialized memory access
+- Add Solaris 9 make options in configure [Gilbert]
+- Allow strerror() usage in gzio.c for STDC
+- Fix DecompressBuf in contrib/delphi/ZLib.pas [ManChesTer]
+- Update contrib/masmx86/inffas32.asm and gvmat32.asm [Vollant]
+- Use z_off_t for adler32_combine() and crc32_combine() lengths
+- Make adler32() much faster for small len
+- Use OS_CODE in deflate() default gzip header
+
+Changes in 1.2.2.1 (31 October 2004)
+- Allow inflateSetDictionary() call for raw inflate
+- Fix inflate header crc check bug for file names and comments
+- Add deflateSetHeader() and gz_header structure for custom gzip headers
+- Add inflateGetheader() to retrieve gzip headers
+- Add crc32_combine() and adler32_combine() functions
+- Add alloc_func, free_func, in_func, out_func to Z_PREFIX list
+- Use zstreamp consistently in zlib.h (inflate_back functions)
+- Remove GUNZIP condition from definition of inflate_mode in inflate.h
+ and in contrib/inflate86/inffast.S [Truta, Anderson]
+- Add support for AMD64 in contrib/inflate86/inffas86.c [Anderson]
+- Update projects/README.projects and projects/visualc6 [Truta]
+- Update win32/DLL_FAQ.txt [Truta]
+- Avoid warning under NO_GZCOMPRESS in gzio.c; fix typo [Truta]
+- Deprecate Z_ASCII; use Z_TEXT instead [Truta]
+- Use a new algorithm for setting strm->data_type in trees.c [Truta]
+- Do not define an exit() prototype in zutil.c unless DEBUG defined
+- Remove prototype of exit() from zutil.c, example.c, minigzip.c [Truta]
+- Add comment in zlib.h for Z_NO_FLUSH parameter to deflate()
+- Fix Darwin build version identification [Peterson]
+
+Changes in 1.2.2 (3 October 2004)
+- Update zlib.h comments on gzip in-memory processing
+- Set adler to 1 in inflateReset() to support Java test suite [Walles]
+- Add contrib/dotzlib [Ravn]
+- Update win32/DLL_FAQ.txt [Truta]
+- Update contrib/minizip [Vollant]
+- Move contrib/visual-basic.txt to old/ [Truta]
+- Fix assembler builds in projects/visualc6/ [Truta]
+
+Changes in 1.2.1.2 (9 September 2004)
+- Update INDEX file
+- Fix trees.c to update strm->data_type (no one ever noticed!)
+- Fix bug in error case in inflate.c, infback.c, and infback9.c [Brown]
+- Add "volatile" to crc table flag declaration (for DYNAMIC_CRC_TABLE)
+- Add limited multitasking protection to DYNAMIC_CRC_TABLE
+- Add NO_vsnprintf for VMS in zutil.h [Mozilla]
+- Don't declare strerror() under VMS [Mozilla]
+- Add comment to DYNAMIC_CRC_TABLE to use get_crc_table() to initialize
+- Update contrib/ada [Anisimkov]
+- Update contrib/minizip [Vollant]
+- Fix configure to not hardcode directories for Darwin [Peterson]
+- Fix gzio.c to not return error on empty files [Brown]
+- Fix indentation; update version in contrib/delphi/ZLib.pas and
+ contrib/pascal/zlibpas.pas [Truta]
+- Update mkasm.bat in contrib/masmx86 [Truta]
+- Update contrib/untgz [Truta]
+- Add projects/README.projects [Truta]
+- Add project for MS Visual C++ 6.0 in projects/visualc6 [Cadieux, Truta]
+- Update win32/DLL_FAQ.txt [Truta]
+- Update list of Z_PREFIX symbols in zconf.h [Randers-Pehrson, Truta]
+- Remove an unnecessary assignment to curr in inftrees.c [Truta]
+- Add OS/2 to exe builds in configure [Poltorak]
+- Remove err dummy parameter in zlib.h [Kientzle]
+
+Changes in 1.2.1.1 (9 January 2004)
+- Update email address in README
+- Several FAQ updates
+- Fix a big fat bug in inftrees.c that prevented decoding valid
+ dynamic blocks with only literals and no distance codes --
+ Thanks to "Hot Emu" for the bug report and sample file
+- Add a note to puff.c on no distance codes case.
+
+Changes in 1.2.1 (17 November 2003)
+- Remove a tab in contrib/gzappend/gzappend.c
+- Update some interfaces in contrib for new zlib functions
+- Update zlib version number in some contrib entries
+- Add Windows CE definition for ptrdiff_t in zutil.h [Mai, Truta]
+- Support shared libraries on Hurd and KFreeBSD [Brown]
+- Fix error in NO_DIVIDE option of adler32.c
+
+Changes in 1.2.0.8 (4 November 2003)
+- Update version in contrib/delphi/ZLib.pas and contrib/pascal/zlibpas.pas
+- Add experimental NO_DIVIDE #define in adler32.c
+ - Possibly faster on some processors (let me know if it is)
+- Correct Z_BLOCK to not return on first inflate call if no wrap
+- Fix strm->data_type on inflate() return to correctly indicate EOB
+- Add deflatePrime() function for appending in the middle of a byte
+- Add contrib/gzappend for an example of appending to a stream
+- Update win32/DLL_FAQ.txt [Truta]
+- Delete Turbo C comment in README [Truta]
+- Improve some indentation in zconf.h [Truta]
+- Fix infinite loop on bad input in configure script [Church]
+- Fix gzeof() for concatenated gzip files [Johnson]
+- Add example to contrib/visual-basic.txt [Michael B.]
+- Add -p to mkdir's in Makefile.in [vda]
+- Fix configure to properly detect presence or lack of printf functions
+- Add AS400 support [Monnerat]
+- Add a little Cygwin support [Wilson]
+
+Changes in 1.2.0.7 (21 September 2003)
+- Correct some debug formats in contrib/infback9
+- Cast a type in a debug statement in trees.c
+- Change search and replace delimiter in configure from % to # [Beebe]
+- Update contrib/untgz to 0.2 with various fixes [Truta]
+- Add build support for Amiga [Nikl]
+- Remove some directories in old that have been updated to 1.2
+- Add dylib building for Mac OS X in configure and Makefile.in
+- Remove old distribution stuff from Makefile
+- Update README to point to DLL_FAQ.txt, and add comment on Mac OS X
+- Update links in README
+
+Changes in 1.2.0.6 (13 September 2003)
+- Minor FAQ updates
+- Update contrib/minizip to 1.00 [Vollant]
+- Remove test of gz functions in example.c when GZ_COMPRESS defined [Truta]
+- Update POSTINC comment for 68060 [Nikl]
+- Add contrib/infback9 with deflate64 decoding (unsupported)
+- For MVS define NO_vsnprintf and undefine FAR [van Burik]
+- Add pragma for fdopen on MVS [van Burik]
+
+Changes in 1.2.0.5 (8 September 2003)
+- Add OF to inflateBackEnd() declaration in zlib.h
+- Remember start when using gzdopen in the middle of a file
+- Use internal off_t counters in gz* functions to properly handle seeks
+- Perform more rigorous check for distance-too-far in inffast.c
+- Add Z_BLOCK flush option to return from inflate at block boundary
+- Set strm->data_type on return from inflate
+ - Indicate bits unused, if at block boundary, and if in last block
+- Replace size_t with ptrdiff_t in crc32.c, and check for correct size
+- Add condition so old NO_DEFLATE define still works for compatibility
+- FAQ update regarding the Windows DLL [Truta]
+- INDEX update: add qnx entry, remove aix entry [Truta]
+- Install zlib.3 into mandir [Wilson]
+- Move contrib/zlib_dll_FAQ.txt to win32/DLL_FAQ.txt; update [Truta]
+- Adapt the zlib interface to the new DLL convention guidelines [Truta]
+- Introduce ZLIB_WINAPI macro to allow the export of functions using
+ the WINAPI calling convention, for Visual Basic [Vollant, Truta]
+- Update msdos and win32 scripts and makefiles [Truta]
+- Export symbols by name, not by ordinal, in win32/zlib.def [Truta]
+- Add contrib/ada [Anisimkov]
+- Move asm files from contrib/vstudio/vc70_32 to contrib/asm386 [Truta]
+- Rename contrib/asm386 to contrib/masmx86 [Truta, Vollant]
+- Add contrib/masm686 [Truta]
+- Fix offsets in contrib/inflate86 and contrib/masmx86/inffas32.asm
+ [Truta, Vollant]
+- Update contrib/delphi; rename to contrib/pascal; add example [Truta]
+- Remove contrib/delphi2; add a new contrib/delphi [Truta]
+- Avoid inclusion of the nonstandard <memory.h> in contrib/iostream,
+ and fix some method prototypes [Truta]
+- Fix the ZCR_SEED2 constant to avoid warnings in contrib/minizip
+ [Truta]
+- Avoid the use of backslash (\) in contrib/minizip [Vollant]
+- Fix file time handling in contrib/untgz; update makefiles [Truta]
+- Update contrib/vstudio/vc70_32 to comply with the new DLL guidelines
+ [Vollant]
+- Remove contrib/vstudio/vc15_16 [Vollant]
+- Rename contrib/vstudio/vc70_32 to contrib/vstudio/vc7 [Truta]
+- Update README.contrib [Truta]
+- Invert the assignment order of match_head and s->prev[...] in
+ INSERT_STRING [Truta]
+- Compare TOO_FAR with 32767 instead of 32768, to avoid 16-bit warnings
+ [Truta]
+- Compare function pointers with 0, not with NULL or Z_NULL [Truta]
+- Fix prototype of syncsearch in inflate.c [Truta]
+- Introduce ASMINF macro to be enabled when using an ASM implementation
+ of inflate_fast [Truta]
+- Change NO_DEFLATE to NO_GZCOMPRESS [Truta]
+- Modify test_gzio in example.c to take a single file name as a
+ parameter [Truta]
+- Exit the example.c program if gzopen fails [Truta]
+- Add type casts around strlen in example.c [Truta]
+- Remove casting to sizeof in minigzip.c; give a proper type
+ to the variable compared with SUFFIX_LEN [Truta]
+- Update definitions of STDC and STDC99 in zconf.h [Truta]
+- Synchronize zconf.h with the new Windows DLL interface [Truta]
+- Use SYS16BIT instead of __32BIT__ to distinguish between
+ 16- and 32-bit platforms [Truta]
+- Use far memory allocators in small 16-bit memory models for
+ Turbo C [Truta]
+- Add info about the use of ASMV, ASMINF and ZLIB_WINAPI in
+ zlibCompileFlags [Truta]
+- Cygwin has vsnprintf [Wilson]
+- In Windows16, OS_CODE is 0, as in MSDOS [Truta]
+- In Cygwin, OS_CODE is 3 (Unix), not 11 (Windows32) [Wilson]
+
+Changes in 1.2.0.4 (10 August 2003)
+- Minor FAQ updates
+- Be more strict when checking inflateInit2's windowBits parameter
+- Change NO_GUNZIP compile option to NO_GZIP to cover deflate as well
+- Add gzip wrapper option to deflateInit2 using windowBits
+- Add updated QNX rule in configure and qnx directory [Bonnefoy]
+- Make inflate distance-too-far checks more rigorous
+- Clean up FAR usage in inflate
+- Add casting to sizeof() in gzio.c and minigzip.c
+
+Changes in 1.2.0.3 (19 July 2003)
+- Fix silly error in gzungetc() implementation [Vollant]
+- Update contrib/minizip and contrib/vstudio [Vollant]
+- Fix printf format in example.c
+- Correct cdecl support in zconf.in.h [Anisimkov]
+- Minor FAQ updates
+
+Changes in 1.2.0.2 (13 July 2003)
+- Add ZLIB_VERNUM in zlib.h for numerical preprocessor comparisons
+- Attempt to avoid warnings in crc32.c for pointer-int conversion
+- Add AIX to configure, remove aix directory [Bakker]
+- Add some casts to minigzip.c
+- Improve checking after insecure sprintf() or vsprintf() calls
+- Remove #elif's from crc32.c
+- Change leave label to inf_leave in inflate.c and infback.c to avoid
+ library conflicts
+- Remove inflate gzip decoding by default--only enable gzip decoding by
+ special request for stricter backward compatibility
+- Add zlibCompileFlags() function to return compilation information
+- More typecasting in deflate.c to avoid warnings
+- Remove leading underscore from _Capital #defines [Truta]
+- Fix configure to link shared library when testing
+- Add some Windows CE target adjustments [Mai]
+- Remove #define ZLIB_DLL in zconf.h [Vollant]
+- Add zlib.3 [Rodgers]
+- Update RFC URL in deflate.c and algorithm.txt [Mai]
+- Add zlib_dll_FAQ.txt to contrib [Truta]
+- Add UL to some constants [Truta]
+- Update minizip and vstudio [Vollant]
+- Remove vestigial NEED_DUMMY_RETURN from zconf.in.h
+- Expand use of NO_DUMMY_DECL to avoid all dummy structures
+- Added iostream3 to contrib [Schwardt]
+- Replace rewind() with fseek() for WinCE [Truta]
+- Improve setting of zlib format compression level flags
+ - Report 0 for huffman and rle strategies and for level == 0 or 1
+ - Report 2 only for level == 6
+- Only deal with 64K limit when necessary at compile time [Truta]
+- Allow TOO_FAR check to be turned off at compile time [Truta]
+- Add gzclearerr() function [Souza]
+- Add gzungetc() function
+
+Changes in 1.2.0.1 (17 March 2003)
+- Add Z_RLE strategy for run-length encoding [Truta]
+ - When Z_RLE requested, restrict matches to distance one
+ - Update zlib.h, minigzip.c, gzopen(), gzdopen() for Z_RLE
+- Correct FASTEST compilation to allow level == 0
+- Clean up what gets compiled for FASTEST
+- Incorporate changes to zconf.in.h [Vollant]
+ - Refine detection of Turbo C need for dummy returns
+ - Refine ZLIB_DLL compilation
+ - Include additional header file on VMS for off_t typedef
+- Try to use _vsnprintf where it supplants vsprintf [Vollant]
+- Add some casts in inffast.c
+- Enchance comments in zlib.h on what happens if gzprintf() tries to
+ write more than 4095 bytes before compression
+- Remove unused state from inflateBackEnd()
+- Remove exit(0) from minigzip.c, example.c
+- Get rid of all those darn tabs
+- Add "check" target to Makefile.in that does the same thing as "test"
+- Add "mostlyclean" and "maintainer-clean" targets to Makefile.in
+- Update contrib/inflate86 [Anderson]
+- Update contrib/testzlib, contrib/vstudio, contrib/minizip [Vollant]
+- Add msdos and win32 directories with makefiles [Truta]
+- More additions and improvements to the FAQ
+
+Changes in 1.2.0 (9 March 2003)
+- New and improved inflate code
+ - About 20% faster
+ - Does not allocate 32K window unless and until needed
+ - Automatically detects and decompresses gzip streams
+ - Raw inflate no longer needs an extra dummy byte at end
+ - Added inflateBack functions using a callback interface--even faster
+ than inflate, useful for file utilities (gzip, zip)
+ - Added inflateCopy() function to record state for random access on
+ externally generated deflate streams (e.g. in gzip files)
+ - More readable code (I hope)
+- New and improved crc32()
+ - About 50% faster, thanks to suggestions from Rodney Brown
+- Add deflateBound() and compressBound() functions
+- Fix memory leak in deflateInit2()
+- Permit setting dictionary for raw deflate (for parallel deflate)
+- Fix const declaration for gzwrite()
+- Check for some malloc() failures in gzio.c
+- Fix bug in gzopen() on single-byte file 0x1f
+- Fix bug in gzread() on concatenated file with 0x1f at end of buffer
+ and next buffer doesn't start with 0x8b
+- Fix uncompress() to return Z_DATA_ERROR on truncated input
+- Free memory at end of example.c
+- Remove MAX #define in trees.c (conflicted with some libraries)
+- Fix static const's in deflate.c, gzio.c, and zutil.[ch]
+- Declare malloc() and free() in gzio.c if STDC not defined
+- Use malloc() instead of calloc() in zutil.c if int big enough
+- Define STDC for AIX
+- Add aix/ with approach for compiling shared library on AIX
+- Add HP-UX support for shared libraries in configure
+- Add OpenUNIX support for shared libraries in configure
+- Use $cc instead of gcc to build shared library
+- Make prefix directory if needed when installing
+- Correct Macintosh avoidance of typedef Byte in zconf.h
+- Correct Turbo C memory allocation when under Linux
+- Use libz.a instead of -lz in Makefile (assure use of compiled library)
+- Update configure to check for snprintf or vsnprintf functions and their
+ return value, warn during make if using an insecure function
+- Fix configure problem with compile-time knowledge of HAVE_UNISTD_H that
+ is lost when library is used--resolution is to build new zconf.h
+- Documentation improvements (in zlib.h):
+ - Document raw deflate and inflate
+ - Update RFCs URL
+ - Point out that zlib and gzip formats are different
+ - Note that Z_BUF_ERROR is not fatal
+ - Document string limit for gzprintf() and possible buffer overflow
+ - Note requirement on avail_out when flushing
+ - Note permitted values of flush parameter of inflate()
+- Add some FAQs (and even answers) to the FAQ
+- Add contrib/inflate86/ for x86 faster inflate
+- Add contrib/blast/ for PKWare Data Compression Library decompression
+- Add contrib/puff/ simple inflate for deflate format description
+
+Changes in 1.1.4 (11 March 2002)
+- ZFREE was repeated on same allocation on some error conditions.
+ This creates a security problem described in
+ http://www.zlib.org/advisory-2002-03-11.txt
+- Returned incorrect error (Z_MEM_ERROR) on some invalid data
+- Avoid accesses before window for invalid distances with inflate window
+ less than 32K.
+- force windowBits > 8 to avoid a bug in the encoder for a window size
+ of 256 bytes. (A complete fix will be available in 1.1.5).
+
+Changes in 1.1.3 (9 July 1998)
+- fix "an inflate input buffer bug that shows up on rare but persistent
+ occasions" (Mark)
+- fix gzread and gztell for concatenated .gz files (Didier Le Botlan)
+- fix gzseek(..., SEEK_SET) in write mode
+- fix crc check after a gzeek (Frank Faubert)
+- fix miniunzip when the last entry in a zip file is itself a zip file
+ (J Lillge)
+- add contrib/asm586 and contrib/asm686 (Brian Raiter)
+ See http://www.muppetlabs.com/~breadbox/software/assembly.html
+- add support for Delphi 3 in contrib/delphi (Bob Dellaca)
+- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti)
+- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren)
+- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks)
+- added a FAQ file
+
+- Support gzdopen on Mac with Metrowerks (Jason Linhart)
+- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart)
+- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young)
+- avoid some warnings with Borland C (Tom Tanner)
+- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant)
+- emulate utime() for WIN32 in contrib/untgz (Gilles Vollant)
+- allow several arguments to configure (Tim Mooney, Frodo Looijaard)
+- use libdir and includedir in Makefile.in (Tim Mooney)
+- support shared libraries on OSF1 V4 (Tim Mooney)
+- remove so_locations in "make clean" (Tim Mooney)
+- fix maketree.c compilation error (Glenn, Mark)
+- Python interface to zlib now in Python 1.5 (Jeremy Hylton)
+- new Makefile.riscos (Rich Walker)
+- initialize static descriptors in trees.c for embedded targets (Nick Smith)
+- use "foo-gz" in example.c for RISCOS and VMS (Nick Smith)
+- add the OS/2 files in Makefile.in too (Andrew Zabolotny)
+- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane)
+- fix maketree.c to allow clean compilation of inffixed.h (Mark)
+- fix parameter check in deflateCopy (Gunther Nikl)
+- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler)
+- Many portability patches by Christian Spieler:
+ . zutil.c, zutil.h: added "const" for zmem*
+ . Make_vms.com: fixed some typos
+ . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists
+ . msdos/Makefile.msc: remove "default rtl link library" info from obj files
+ . msdos/Makefile.*: use model-dependent name for the built zlib library
+ . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc:
+ new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT)
+- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane)
+- replace __far with _far for better portability (Christian Spieler, Tom Lane)
+- fix test for errno.h in configure (Tim Newsham)
+
+Changes in 1.1.2 (19 March 98)
+- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant)
+ See http://www.winimage.com/zLibDll/unzip.html
+- preinitialize the inflate tables for fixed codes, to make the code
+ completely thread safe (Mark)
+- some simplifications and slight speed-up to the inflate code (Mark)
+- fix gzeof on non-compressed files (Allan Schrum)
+- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs)
+- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn)
+- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny)
+- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori)
+- do not wrap extern "C" around system includes (Tom Lane)
+- mention zlib binding for TCL in README (Andreas Kupries)
+- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert)
+- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson)
+- allow "configure --prefix $HOME" (Tim Mooney)
+- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson)
+- move Makefile.sas to amiga/Makefile.sas
+
+Changes in 1.1.1 (27 Feb 98)
+- fix macros _tr_tally_* in deflate.h for debug mode (Glenn Randers-Pehrson)
+- remove block truncation heuristic which had very marginal effect for zlib
+ (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the
+ compression ratio on some files. This also allows inlining _tr_tally for
+ matches in deflate_slow.
+- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier)
+
+Changes in 1.1.0 (24 Feb 98)
+- do not return STREAM_END prematurely in inflate (John Bowler)
+- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler)
+- compile with -DFASTEST to get compression code optimized for speed only
+- in minigzip, try mmap'ing the input file first (Miguel Albrecht)
+- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain
+ on Sun but significant on HP)
+
+- add a pointer to experimental unzip library in README (Gilles Vollant)
+- initialize variable gcc in configure (Chris Herborth)
+
+Changes in 1.0.9 (17 Feb 1998)
+- added gzputs and gzgets functions
+- do not clear eof flag in gzseek (Mark Diekhans)
+- fix gzseek for files in transparent mode (Mark Diekhans)
+- do not assume that vsprintf returns the number of bytes written (Jens Krinke)
+- replace EXPORT with ZEXPORT to avoid conflict with other programs
+- added compress2 in zconf.h, zlib.def, zlib.dnt
+- new asm code from Gilles Vollant in contrib/asm386
+- simplify the inflate code (Mark):
+ . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new()
+ . ZALLOC the length list in inflate_trees_fixed() instead of using stack
+ . ZALLOC the value area for huft_build() instead of using stack
+ . Simplify Z_FINISH check in inflate()
+
+- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8
+- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi)
+- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with
+ the declaration of FAR (Gilles VOllant)
+- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann)
+- read_buf buf parameter of type Bytef* instead of charf*
+- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout)
+- do not redeclare unlink in minigzip.c for WIN32 (John Bowler)
+- fix check for presence of directories in "make install" (Ian Willis)
+
+Changes in 1.0.8 (27 Jan 1998)
+- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant)
+- fix gzgetc and gzputc for big endian systems (Markus Oberhumer)
+- added compress2() to allow setting the compression level
+- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong)
+- use constant arrays for the static trees in trees.c instead of computing
+ them at run time (thanks to Ken Raeburn for this suggestion). To create
+ trees.h, compile with GEN_TREES_H and run "make test".
+- check return code of example in "make test" and display result
+- pass minigzip command line options to file_compress
+- simplifying code of inflateSync to avoid gcc 2.8 bug
+
+- support CC="gcc -Wall" in configure -s (QingLong)
+- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn)
+- fix test for shared library support to avoid compiler warnings
+- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant)
+- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit)
+- do not use fdopen for Metrowerks on Mac (Brad Pettit))
+- add checks for gzputc and gzputc in example.c
+- avoid warnings in gzio.c and deflate.c (Andreas Kleinert)
+- use const for the CRC table (Ken Raeburn)
+- fixed "make uninstall" for shared libraries
+- use Tracev instead of Trace in infblock.c
+- in example.c use correct compressed length for test_sync
+- suppress +vnocompatwarnings in configure for HPUX (not always supported)
+
+Changes in 1.0.7 (20 Jan 1998)
+- fix gzseek which was broken in write mode
+- return error for gzseek to negative absolute position
+- fix configure for Linux (Chun-Chung Chen)
+- increase stack space for MSC (Tim Wegner)
+- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant)
+- define EXPORTVA for gzprintf (Gilles Vollant)
+- added man page zlib.3 (Rick Rodgers)
+- for contrib/untgz, fix makedir() and improve Makefile
+
+- check gzseek in write mode in example.c
+- allocate extra buffer for seeks only if gzseek is actually called
+- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant)
+- add inflateSyncPoint in zconf.h
+- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def
+
+Changes in 1.0.6 (19 Jan 1998)
+- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and
+ gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code)
+- Fix a deflate bug occurring only with compression level 0 (thanks to
+ Andy Buckler for finding this one).
+- In minigzip, pass transparently also the first byte for .Z files.
+- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress()
+- check Z_FINISH in inflate (thanks to Marc Schluper)
+- Implement deflateCopy (thanks to Adam Costello)
+- make static libraries by default in configure, add --shared option.
+- move MSDOS or Windows specific files to directory msdos
+- suppress the notion of partial flush to simplify the interface
+ (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4)
+- suppress history buffer provided by application to simplify the interface
+ (this feature was not implemented anyway in 1.0.4)
+- next_in and avail_in must be initialized before calling inflateInit or
+ inflateInit2
+- add EXPORT in all exported functions (for Windows DLL)
+- added Makefile.nt (thanks to Stephen Williams)
+- added the unsupported "contrib" directory:
+ contrib/asm386/ by Gilles Vollant <info@winimage.com>
+ 386 asm code replacing longest_match().
+ contrib/iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>
+ A C++ I/O streams interface to the zlib gz* functions
+ contrib/iostream2/ by Tyge Løvset <Tyge.Lovset@cmr.no>
+ Another C++ I/O streams interface
+ contrib/untgz/ by "Pedro A. Aranda Guti\irrez" <paag@tid.es>
+ A very simple tar.gz file extractor using zlib
+ contrib/visual-basic.txt by Carlos Rios <c_rios@sonda.cl>
+ How to use compress(), uncompress() and the gz* functions from VB.
+- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression
+ level) in minigzip (thanks to Tom Lane)
+
+- use const for rommable constants in deflate
+- added test for gzseek and gztell in example.c
+- add undocumented function inflateSyncPoint() (hack for Paul Mackerras)
+- add undocumented function zError to convert error code to string
+ (for Tim Smithers)
+- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code.
+- Use default memcpy for Symantec MSDOS compiler.
+- Add EXPORT keyword for check_func (needed for Windows DLL)
+- add current directory to LD_LIBRARY_PATH for "make test"
+- create also a link for libz.so.1
+- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura)
+- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX)
+- added -soname for Linux in configure (Chun-Chung Chen,
+- assign numbers to the exported functions in zlib.def (for Windows DLL)
+- add advice in zlib.h for best usage of deflateSetDictionary
+- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn)
+- allow compilation with ANSI keywords only enabled for TurboC in large model
+- avoid "versionString"[0] (Borland bug)
+- add NEED_DUMMY_RETURN for Borland
+- use variable z_verbose for tracing in debug mode (L. Peter Deutsch).
+- allow compilation with CC
+- defined STDC for OS/2 (David Charlap)
+- limit external names to 8 chars for MVS (Thomas Lund)
+- in minigzip.c, use static buffers only for 16-bit systems
+- fix suffix check for "minigzip -d foo.gz"
+- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee)
+- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau)
+- added makelcc.bat for lcc-win32 (Tom St Denis)
+- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe)
+- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion.
+- check for unistd.h in configure (for off_t)
+- remove useless check parameter in inflate_blocks_free
+- avoid useless assignment of s->check to itself in inflate_blocks_new
+- do not flush twice in gzclose (thanks to Ken Raeburn)
+- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h
+- use NO_ERRNO_H instead of enumeration of operating systems with errno.h
+- work around buggy fclose on pipes for HP/UX
+- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson)
+- fix configure if CC is already equal to gcc
+
+Changes in 1.0.5 (3 Jan 98)
+- Fix inflate to terminate gracefully when fed corrupted or invalid data
+- Use const for rommable constants in inflate
+- Eliminate memory leaks on error conditions in inflate
+- Removed some vestigial code in inflate
+- Update web address in README
+
+Changes in 1.0.4 (24 Jul 96)
+- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF
+ bit, so the decompressor could decompress all the correct data but went
+ on to attempt decompressing extra garbage data. This affected minigzip too.
+- zlibVersion and gzerror return const char* (needed for DLL)
+- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno)
+- use z_error only for DEBUG (avoid problem with DLLs)
+
+Changes in 1.0.3 (2 Jul 96)
+- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS
+ small and medium models; this makes the library incompatible with previous
+ versions for these models. (No effect in large model or on other systems.)
+- return OK instead of BUF_ERROR if previous deflate call returned with
+ avail_out as zero but there is nothing to do
+- added memcmp for non STDC compilers
+- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly)
+- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO)
+- better check for 16-bit mode MSC (avoids problem with Symantec)
+
+Changes in 1.0.2 (23 May 96)
+- added Windows DLL support
+- added a function zlibVersion (for the DLL support)
+- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model)
+- Bytef is define's instead of typedef'd only for Borland C
+- avoid reading uninitialized memory in example.c
+- mention in README that the zlib format is now RFC1950
+- updated Makefile.dj2
+- added algorithm.doc
+
+Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion]
+- fix array overlay in deflate.c which sometimes caused bad compressed data
+- fix inflate bug with empty stored block
+- fix MSDOS medium model which was broken in 0.99
+- fix deflateParams() which could generated bad compressed data.
+- Bytef is define'd instead of typedef'ed (work around Borland bug)
+- added an INDEX file
+- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32),
+ Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas)
+- speed up adler32 for modern machines without auto-increment
+- added -ansi for IRIX in configure
+- static_init_done in trees.c is an int
+- define unlink as delete for VMS
+- fix configure for QNX
+- add configure branch for SCO and HPUX
+- avoid many warnings (unused variables, dead assignments, etc...)
+- no fdopen for BeOS
+- fix the Watcom fix for 32 bit mode (define FAR as empty)
+- removed redefinition of Byte for MKWERKS
+- work around an MWKERKS bug (incorrect merge of all .h files)
+
+Changes in 0.99 (27 Jan 96)
+- allow preset dictionary shared between compressor and decompressor
+- allow compression level 0 (no compression)
+- add deflateParams in zlib.h: allow dynamic change of compression level
+ and compression strategy.
+- test large buffers and deflateParams in example.c
+- add optional "configure" to build zlib as a shared library
+- suppress Makefile.qnx, use configure instead
+- fixed deflate for 64-bit systems (detected on Cray)
+- fixed inflate_blocks for 64-bit systems (detected on Alpha)
+- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2)
+- always return Z_BUF_ERROR when deflate() has nothing to do
+- deflateInit and inflateInit are now macros to allow version checking
+- prefix all global functions and types with z_ with -DZ_PREFIX
+- make falloc completely reentrant (inftrees.c)
+- fixed very unlikely race condition in ct_static_init
+- free in reverse order of allocation to help memory manager
+- use zlib-1.0/* instead of zlib/* inside the tar.gz
+- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith
+ -Wconversion -Wstrict-prototypes -Wmissing-prototypes"
+- allow gzread on concatenated .gz files
+- deflateEnd now returns Z_DATA_ERROR if it was premature
+- deflate is finally (?) fully deterministic (no matches beyond end of input)
+- Document Z_SYNC_FLUSH
+- add uninstall in Makefile
+- Check for __cpluplus in zlib.h
+- Better test in ct_align for partial flush
+- avoid harmless warnings for Borland C++
+- initialize hash_head in deflate.c
+- avoid warning on fdopen (gzio.c) for HP cc -Aa
+- include stdlib.h for STDC compilers
+- include errno.h for Cray
+- ignore error if ranlib doesn't exist
+- call ranlib twice for NeXTSTEP
+- use exec_prefix instead of prefix for libz.a
+- renamed ct_* as _tr_* to avoid conflict with applications
+- clear z->msg in inflateInit2 before any error return
+- initialize opaque in example.c, gzio.c, deflate.c and inflate.c
+- fixed typo in zconf.h (_GNUC__ => __GNUC__)
+- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode)
+- fix typo in Make_vms.com (f$trnlnm -> f$getsyi)
+- in fcalloc, normalize pointer if size > 65520 bytes
+- don't use special fcalloc for 32 bit Borland C++
+- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc...
+- use Z_BINARY instead of BINARY
+- document that gzclose after gzdopen will close the file
+- allow "a" as mode in gzopen.
+- fix error checking in gzread
+- allow skipping .gz extra-field on pipes
+- added reference to Perl interface in README
+- put the crc table in FAR data (I dislike more and more the medium model :)
+- added get_crc_table
+- added a dimension to all arrays (Borland C can't count).
+- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast
+- guard against multiple inclusion of *.h (for precompiled header on Mac)
+- Watcom C pretends to be Microsoft C small model even in 32 bit mode.
+- don't use unsized arrays to avoid silly warnings by Visual C++:
+ warning C4746: 'inflate_mask' : unsized array treated as '__far'
+ (what's wrong with far data in far model?).
+- define enum out of inflate_blocks_state to allow compilation with C++
+
+Changes in 0.95 (16 Aug 95)
+- fix MSDOS small and medium model (now easier to adapt to any compiler)
+- inlined send_bits
+- fix the final (:-) bug for deflate with flush (output was correct but
+ not completely flushed in rare occasions).
+- default window size is same for compression and decompression
+ (it's now sufficient to set MAX_WBITS in zconf.h).
+- voidp -> voidpf and voidnp -> voidp (for consistency with other
+ typedefs and because voidnp was not near in large model).
+
+Changes in 0.94 (13 Aug 95)
+- support MSDOS medium model
+- fix deflate with flush (could sometimes generate bad output)
+- fix deflateReset (zlib header was incorrectly suppressed)
+- added support for VMS
+- allow a compression level in gzopen()
+- gzflush now calls fflush
+- For deflate with flush, flush even if no more input is provided.
+- rename libgz.a as libz.a
+- avoid complex expression in infcodes.c triggering Turbo C bug
+- work around a problem with gcc on Alpha (in INSERT_STRING)
+- don't use inline functions (problem with some gcc versions)
+- allow renaming of Byte, uInt, etc... with #define.
+- avoid warning about (unused) pointer before start of array in deflate.c
+- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c
+- avoid reserved word 'new' in trees.c
+
+Changes in 0.93 (25 June 95)
+- temporarily disable inline functions
+- make deflate deterministic
+- give enough lookahead for PARTIAL_FLUSH
+- Set binary mode for stdin/stdout in minigzip.c for OS/2
+- don't even use signed char in inflate (not portable enough)
+- fix inflate memory leak for segmented architectures
+
+Changes in 0.92 (3 May 95)
+- don't assume that char is signed (problem on SGI)
+- Clear bit buffer when starting a stored block
+- no memcpy on Pyramid
+- suppressed inftest.c
+- optimized fill_window, put longest_match inline for gcc
+- optimized inflate on stored blocks.
+- untabify all sources to simplify patches
+
+Changes in 0.91 (2 May 95)
+- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h
+- Document the memory requirements in zconf.h
+- added "make install"
+- fix sync search logic in inflateSync
+- deflate(Z_FULL_FLUSH) now works even if output buffer too short
+- after inflateSync, don't scare people with just "lo world"
+- added support for DJGPP
+
+Changes in 0.9 (1 May 95)
+- don't assume that zalloc clears the allocated memory (the TurboC bug
+ was Mark's bug after all :)
+- let again gzread copy uncompressed data unchanged (was working in 0.71)
+- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented
+- added a test of inflateSync in example.c
+- moved MAX_WBITS to zconf.h because users might want to change that.
+- document explicitly that zalloc(64K) on MSDOS must return a normalized
+ pointer (zero offset)
+- added Makefiles for Microsoft C, Turbo C, Borland C++
+- faster crc32()
+
+Changes in 0.8 (29 April 95)
+- added fast inflate (inffast.c)
+- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this
+ is incompatible with previous versions of zlib which returned Z_OK.
+- work around a TurboC compiler bug (bad code for b << 0, see infutil.h)
+ (actually that was not a compiler bug, see 0.81 above)
+- gzread no longer reads one extra byte in certain cases
+- In gzio destroy(), don't reference a freed structure
+- avoid many warnings for MSDOS
+- avoid the ERROR symbol which is used by MS Windows
+
+Changes in 0.71 (14 April 95)
+- Fixed more MSDOS compilation problems :( There is still a bug with
+ TurboC large model.
+
+Changes in 0.7 (14 April 95)
+- Added full inflate support.
+- Simplified the crc32() interface. The pre- and post-conditioning
+ (one's complement) is now done inside crc32(). WARNING: this is
+ incompatible with previous versions; see zlib.h for the new usage.
+
+Changes in 0.61 (12 April 95)
+- workaround for a bug in TurboC. example and minigzip now work on MSDOS.
+
+Changes in 0.6 (11 April 95)
+- added minigzip.c
+- added gzdopen to reopen a file descriptor as gzFile
+- added transparent reading of non-gziped files in gzread.
+- fixed bug in gzread (don't read crc as data)
+- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose).
+- don't allocate big arrays in the stack (for MSDOS)
+- fix some MSDOS compilation problems
+
+Changes in 0.5:
+- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but
+ not yet Z_FULL_FLUSH.
+- support decompression but only in a single step (forced Z_FINISH)
+- added opaque object for zalloc and zfree.
+- added deflateReset and inflateReset
+- added a variable zlib_version for consistency checking.
+- renamed the 'filter' parameter of deflateInit2 as 'strategy'.
+ Added Z_FILTERED and Z_HUFFMAN_ONLY constants.
+
+Changes in 0.4:
+- avoid "zip" everywhere, use zlib instead of ziplib.
+- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush
+ if compression method == 8.
+- added adler32 and crc32
+- renamed deflateOptions as deflateInit2, call one or the other but not both
+- added the method parameter for deflateInit2.
+- added inflateInit2
+- simplied considerably deflateInit and inflateInit by not supporting
+ user-provided history buffer. This is supported only in deflateInit2
+ and inflateInit2.
+
+Changes in 0.3:
+- prefix all macro names with Z_
+- use Z_FINISH instead of deflateEnd to finish compression.
+- added Z_HUFFMAN_ONLY
+- added gzerror()
diff --git a/Utilities/cmzlib/Copyright.txt b/Utilities/cmzlib/Copyright.txt
new file mode 100644
index 000000000..db0beaea5
--- /dev/null
+++ b/Utilities/cmzlib/Copyright.txt
@@ -0,0 +1,23 @@
+'zlib' general purpose compression library
+version 1.2.3, July 18th, 2005
+
+Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+
+Jean-loup Gailly Mark Adler
+jloup@gzip.org madler@alumni.caltech.edu
diff --git a/Utilities/cmzlib/FAQ b/Utilities/cmzlib/FAQ
new file mode 100644
index 000000000..441d910da
--- /dev/null
+++ b/Utilities/cmzlib/FAQ
@@ -0,0 +1,339 @@
+
+ Frequently Asked Questions about zlib
+
+
+If your question is not there, please check the zlib home page
+http://www.zlib.org which may have more recent information.
+The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
+
+
+ 1. Is zlib Y2K-compliant?
+
+ Yes. zlib doesn't handle dates.
+
+ 2. Where can I get a Windows DLL version?
+
+ The zlib sources can be compiled without change to produce a DLL.
+ See the file win32/DLL_FAQ.txt in the zlib distribution.
+ Pointers to the precompiled DLL are found in the zlib web site at
+ http://www.zlib.org.
+
+ 3. Where can I get a Visual Basic interface to zlib?
+
+ See
+ * http://www.dogma.net/markn/articles/zlibtool/zlibtool.htm
+ * contrib/visual-basic.txt in the zlib distribution
+ * win32/DLL_FAQ.txt in the zlib distribution
+
+ 4. compress() returns Z_BUF_ERROR.
+
+ Make sure that before the call of compress, the length of the compressed
+ buffer is equal to the total size of the compressed buffer and not
+ zero. For Visual Basic, check that this parameter is passed by reference
+ ("as any"), not by value ("as long").
+
+ 5. deflate() or inflate() returns Z_BUF_ERROR.
+
+ Before making the call, make sure that avail_in and avail_out are not
+ zero. When setting the parameter flush equal to Z_FINISH, also make sure
+ that avail_out is big enough to allow processing all pending input.
+ Note that a Z_BUF_ERROR is not fatal--another call to deflate() or
+ inflate() can be made with more input or output space. A Z_BUF_ERROR
+ may in fact be unavoidable depending on how the functions are used, since
+ it is not possible to tell whether or not there is more output pending
+ when strm.avail_out returns with zero.
+
+ 6. Where's the zlib documentation (man pages, etc.)?
+
+ It's in zlib.h for the moment, and Francis S. Lin has converted it to a
+ web page zlib.html. Volunteers to transform this to Unix-style man pages,
+ please contact us (zlib@gzip.org). Examples of zlib usage are in the files
+ example.c and minigzip.c.
+
+ 7. Why don't you use GNU autoconf or libtool or ...?
+
+ Because we would like to keep zlib as a very small and simple
+ package. zlib is rather portable and doesn't need much configuration.
+
+ 8. I found a bug in zlib.
+
+ Most of the time, such problems are due to an incorrect usage of
+ zlib. Please try to reproduce the problem with a small program and send
+ the corresponding source to us at zlib@gzip.org . Do not send
+ multi-megabyte data files without prior agreement.
+
+ 9. Why do I get "undefined reference to gzputc"?
+
+ If "make test" produces something like
+
+ example.o(.text+0x154): undefined reference to `gzputc'
+
+ check that you don't have old files libz.* in /usr/lib, /usr/local/lib or
+ /usr/X11R6/lib. Remove any old versions, then do "make install".
+
+10. I need a Delphi interface to zlib.
+
+ See the contrib/delphi directory in the zlib distribution.
+
+11. Can zlib handle .zip archives?
+
+ Not by itself, no. See the directory contrib/minizip in the zlib
+ distribution.
+
+12. Can zlib handle .Z files?
+
+ No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt
+ the code of uncompress on your own.
+
+13. How can I make a Unix shared library?
+
+ make clean
+ ./configure -s
+ make
+
+14. How do I install a shared zlib library on Unix?
+
+ After the above, then:
+
+ make install
+
+ However, many flavors of Unix come with a shared zlib already installed.
+ Before going to the trouble of compiling a shared version of zlib and
+ trying to install it, you may want to check if it's already there! If you
+ can #include <zlib.h>, it's there. The -lz option will probably link to it.
+
+15. I have a question about OttoPDF.
+
+ We are not the authors of OttoPDF. The real author is on the OttoPDF web
+ site: Joel Hainley, jhainley@myndkryme.com.
+
+16. Can zlib decode Flate data in an Adobe PDF file?
+
+ Yes. See http://www.fastio.com/ (ClibPDF), or http://www.pdflib.com/ .
+ To modify PDF forms, see http://sourceforge.net/projects/acroformtool/ .
+
+17. Why am I getting this "register_frame_info not found" error on Solaris?
+
+ After installing zlib 1.1.4 on Solaris 2.6, running applications using zlib
+ generates an error such as:
+
+ ld.so.1: rpm: fatal: relocation error: file /usr/local/lib/libz.so:
+ symbol __register_frame_info: referenced symbol not found
+
+ The symbol __register_frame_info is not part of zlib, it is generated by
+ the C compiler (cc or gcc). You must recompile applications using zlib
+ which have this problem. This problem is specific to Solaris. See
+ http://www.sunfreeware.com for Solaris versions of zlib and applications
+ using zlib.
+
+18. Why does gzip give an error on a file I make with compress/deflate?
+
+ The compress and deflate functions produce data in the zlib format, which
+ is different and incompatible with the gzip format. The gz* functions in
+ zlib on the other hand use the gzip format. Both the zlib and gzip
+ formats use the same compressed data format internally, but have different
+ headers and trailers around the compressed data.
+
+19. Ok, so why are there two different formats?
+
+ The gzip format was designed to retain the directory information about
+ a single file, such as the name and last modification date. The zlib
+ format on the other hand was designed for in-memory and communication
+ channel applications, and has a much more compact header and trailer and
+ uses a faster integrity check than gzip.
+
+20. Well that's nice, but how do I make a gzip file in memory?
+
+ You can request that deflate write the gzip format instead of the zlib
+ format using deflateInit2(). You can also request that inflate decode
+ the gzip format using inflateInit2(). Read zlib.h for more details.
+
+21. Is zlib thread-safe?
+
+ Yes. However any library routines that zlib uses and any application-
+ provided memory allocation routines must also be thread-safe. zlib's gz*
+ functions use stdio library routines, and most of zlib's functions use the
+ library memory allocation routines by default. zlib's Init functions allow
+ for the application to provide custom memory allocation routines.
+
+ Of course, you should only operate on any given zlib or gzip stream from a
+ single thread at a time.
+
+22. Can I use zlib in my commercial application?
+
+ Yes. Please read the license in zlib.h.
+
+23. Is zlib under the GNU license?
+
+ No. Please read the license in zlib.h.
+
+24. The license says that altered source versions must be "plainly marked". So
+ what exactly do I need to do to meet that requirement?
+
+ You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In
+ particular, the final version number needs to be changed to "f", and an
+ identification string should be appended to ZLIB_VERSION. Version numbers
+ x.x.x.f are reserved for modifications to zlib by others than the zlib
+ maintainers. For example, if the version of the base zlib you are altering
+ is "1.2.3.4", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and
+ ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3". You can also
+ update the version strings in deflate.c and inftrees.c.
+
+ For altered source distributions, you should also note the origin and
+ nature of the changes in zlib.h, as well as in ChangeLog and README, along
+ with the dates of the alterations. The origin should include at least your
+ name (or your company's name), and an email address to contact for help or
+ issues with the library.
+
+ Note that distributing a compiled zlib library along with zlib.h and
+ zconf.h is also a source distribution, and so you should change
+ ZLIB_VERSION and ZLIB_VERNUM and note the origin and nature of the changes
+ in zlib.h as you would for a full source distribution.
+
+25. Will zlib work on a big-endian or little-endian architecture, and can I
+ exchange compressed data between them?
+
+ Yes and yes.
+
+26. Will zlib work on a 64-bit machine?
+
+ It should. It has been tested on 64-bit machines, and has no dependence
+ on any data types being limited to 32-bits in length. If you have any
+ difficulties, please provide a complete problem report to zlib@gzip.org
+
+27. Will zlib decompress data from the PKWare Data Compression Library?
+
+ No. The PKWare DCL uses a completely different compressed data format
+ than does PKZIP and zlib. However, you can look in zlib's contrib/blast
+ directory for a possible solution to your problem.
+
+28. Can I access data randomly in a compressed stream?
+
+ No, not without some preparation. If when compressing you periodically
+ use Z_FULL_FLUSH, carefully write all the pending data at those points,
+ and keep an index of those locations, then you can start decompression
+ at those points. You have to be careful to not use Z_FULL_FLUSH too
+ often, since it can significantly degrade compression.
+
+29. Does zlib work on MVS, OS/390, CICS, etc.?
+
+ We don't know for sure. We have heard occasional reports of success on
+ these systems. If you do use it on one of these, please provide us with
+ a report, instructions, and patches that we can reference when we get
+ these questions. Thanks.
+
+30. Is there some simpler, easier to read version of inflate I can look at
+ to understand the deflate format?
+
+ First off, you should read RFC 1951. Second, yes. Look in zlib's
+ contrib/puff directory.
+
+31. Does zlib infringe on any patents?
+
+ As far as we know, no. In fact, that was originally the whole point behind
+ zlib. Look here for some more information:
+
+ http://www.gzip.org/#faq11
+
+32. Can zlib work with greater than 4 GB of data?
+
+ Yes. inflate() and deflate() will process any amount of data correctly.
+ Each call of inflate() or deflate() is limited to input and output chunks
+ of the maximum value that can be stored in the compiler's "unsigned int"
+ type, but there is no limit to the number of chunks. Note however that the
+ strm.total_in and strm_total_out counters may be limited to 4 GB. These
+ counters are provided as a convenience and are not used internally by
+ inflate() or deflate(). The application can easily set up its own counters
+ updated after each call of inflate() or deflate() to count beyond 4 GB.
+ compress() and uncompress() may be limited to 4 GB, since they operate in a
+ single call. gzseek() and gztell() may be limited to 4 GB depending on how
+ zlib is compiled. See the zlibCompileFlags() function in zlib.h.
+
+ The word "may" appears several times above since there is a 4 GB limit
+ only if the compiler's "long" type is 32 bits. If the compiler's "long"
+ type is 64 bits, then the limit is 16 exabytes.
+
+33. Does zlib have any security vulnerabilities?
+
+ The only one that we are aware of is potentially in gzprintf(). If zlib
+ is compiled to use sprintf() or vsprintf(), then there is no protection
+ against a buffer overflow of a 4K string space, other than the caller of
+ gzprintf() assuring that the output will not exceed 4K. On the other
+ hand, if zlib is compiled to use snprintf() or vsnprintf(), which should
+ normally be the case, then there is no vulnerability. The ./configure
+ script will display warnings if an insecure variation of sprintf() will
+ be used by gzprintf(). Also the zlibCompileFlags() function will return
+ information on what variant of sprintf() is used by gzprintf().
+
+ If you don't have snprintf() or vsnprintf() and would like one, you can
+ find a portable implementation here:
+
+ http://www.ijs.si/software/snprintf/
+
+ Note that you should be using the most recent version of zlib. Versions
+ 1.1.3 and before were subject to a double-free vulnerability.
+
+34. Is there a Java version of zlib?
+
+ Probably what you want is to use zlib in Java. zlib is already included
+ as part of the Java SDK in the java.util.zip package. If you really want
+ a version of zlib written in the Java language, look on the zlib home
+ page for links: http://www.zlib.org/
+
+35. I get this or that compiler or source-code scanner warning when I crank it
+ up to maximally-pedantic. Can't you guys write proper code?
+
+ Many years ago, we gave up attempting to avoid warnings on every compiler
+ in the universe. It just got to be a waste of time, and some compilers
+ were downright silly. So now, we simply make sure that the code always
+ works.
+
+36. Valgrind (or some similar memory access checker) says that deflate is
+ performing a conditional jump that depends on an uninitialized value.
+ Isn't that a bug?
+
+ No. That is intentional for performance reasons, and the output of
+ deflate is not affected. This only started showing up recently since
+ zlib 1.2.x uses malloc() by default for allocations, whereas earlier
+ versions used calloc(), which zeros out the allocated memory.
+
+37. Will zlib read the (insert any ancient or arcane format here) compressed
+ data format?
+
+ Probably not. Look in the comp.compression FAQ for pointers to various
+ formats and associated software.
+
+38. How can I encrypt/decrypt zip files with zlib?
+
+ zlib doesn't support encryption. The original PKZIP encryption is very weak
+ and can be broken with freely available programs. To get strong encryption,
+ use GnuPG, http://www.gnupg.org/ , which already includes zlib compression.
+ For PKZIP compatible "encryption", look at http://www.info-zip.org/
+
+39. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings?
+
+ "gzip" is the gzip format, and "deflate" is the zlib format. They should
+ probably have called the second one "zlib" instead to avoid confusion
+ with the raw deflate compressed data format. While the HTTP 1.1 RFC 2616
+ correctly points to the zlib specification in RFC 1950 for the "deflate"
+ transfer encoding, there have been reports of servers and browsers that
+ incorrectly produce or expect raw deflate data per the deflate
+ specficiation in RFC 1951, most notably Microsoft. So even though the
+ "deflate" transfer encoding using the zlib format would be the more
+ efficient approach (and in fact exactly what the zlib format was designed
+ for), using the "gzip" transfer encoding is probably more reliable due to
+ an unfortunate choice of name on the part of the HTTP 1.1 authors.
+
+ Bottom line: use the gzip format for HTTP 1.1 encoding.
+
+40. Does zlib support the new "Deflate64" format introduced by PKWare?
+
+ No. PKWare has apparently decided to keep that format proprietary, since
+ they have not documented it as they have previous compression formats.
+ In any case, the compression improvements are so modest compared to other
+ more modern approaches, that it's not worth the effort to implement.
+
+41. Can you please sign these lengthy legal documents and fax them back to us
+ so that we can use your software in our product?
+
+ No. Go away. Shoo.
diff --git a/Utilities/cmzlib/INDEX b/Utilities/cmzlib/INDEX
new file mode 100644
index 000000000..0587e5902
--- /dev/null
+++ b/Utilities/cmzlib/INDEX
@@ -0,0 +1,51 @@
+ChangeLog history of changes
+FAQ Frequently Asked Questions about zlib
+INDEX this file
+Makefile makefile for Unix (generated by configure)
+Makefile.in makefile for Unix (template for configure)
+README guess what
+algorithm.txt description of the (de)compression algorithm
+configure configure script for Unix
+zconf.in.h template for zconf.h (used by configure)
+
+amiga/ makefiles for Amiga SAS C
+as400/ makefiles for IBM AS/400
+msdos/ makefiles for MSDOS
+old/ makefiles for various architectures and zlib documentation
+ files that have not yet been updated for zlib 1.2.x
+projects/ projects for various Integrated Development Environments
+qnx/ makefiles for QNX
+win32/ makefiles for Windows
+
+ zlib public header files (must be kept):
+zconf.h
+zlib.h
+
+ private source files used to build the zlib library:
+adler32.c
+compress.c
+crc32.c
+crc32.h
+deflate.c
+deflate.h
+gzio.c
+infback.c
+inffast.c
+inffast.h
+inffixed.h
+inflate.c
+inflate.h
+inftrees.c
+inftrees.h
+trees.c
+trees.h
+uncompr.c
+zutil.c
+zutil.h
+
+ source files for sample programs:
+example.c
+minigzip.c
+
+ unsupported contribution by third parties
+See contrib/README.contrib
diff --git a/Utilities/cmzlib/README b/Utilities/cmzlib/README
new file mode 100644
index 000000000..758cc5002
--- /dev/null
+++ b/Utilities/cmzlib/README
@@ -0,0 +1,125 @@
+ZLIB DATA COMPRESSION LIBRARY
+
+zlib 1.2.3 is a general purpose data compression library. All the code is
+thread safe. The data format used by the zlib library is described by RFCs
+(Request for Comments) 1950 to 1952 in the files
+http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format)
+and rfc1952.txt (gzip format). These documents are also available in other
+formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
+
+All functions of the compression library are documented in the file zlib.h
+(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example
+of the library is given in the file example.c which also tests that the library
+is working correctly. Another example is given in the file minigzip.c. The
+compression library itself is composed of all source files except example.c and
+minigzip.c.
+
+To compile all files and run the test program, follow the instructions given at
+the top of Makefile. In short "make test; make install" should work for most
+machines. For Unix: "./configure; make test; make install". For MSDOS, use one
+of the special makefiles such as Makefile.msc. For VMS, use make_vms.com.
+
+Questions about zlib should be sent to <zlib@gzip.org>, or to Gilles Vollant
+<info@winimage.com> for the Windows DLL version. The zlib home page is
+http://www.zlib.org or http://www.gzip.org/zlib/ Before reporting a problem,
+please check this site to verify that you have the latest version of zlib;
+otherwise get the latest version and check whether the problem still exists or
+not.
+
+PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html before asking
+for help.
+
+Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
+issue of Dr. Dobb's Journal; a copy of the article is available in
+http://dogma.net/markn/articles/zlibtool/zlibtool.htm
+
+The changes made in version 1.2.3 are documented in the file ChangeLog.
+
+Unsupported third party contributions are provided in directory "contrib".
+
+A Java implementation of zlib is available in the Java Development Kit
+http://java.sun.com/j2se/1.4.2/docs/api/java/util/zip/package-summary.html
+See the zlib home page http://www.zlib.org for details.
+
+A Perl interface to zlib written by Paul Marquess <pmqs@cpan.org> is in the
+CPAN (Comprehensive Perl Archive Network) sites
+http://www.cpan.org/modules/by-module/Compress/
+
+A Python interface to zlib written by A.M. Kuchling <amk@amk.ca> is
+available in Python 1.5 and later versions, see
+http://www.python.org/doc/lib/module-zlib.html
+
+A zlib binding for TCL written by Andreas Kupries <a.kupries@westend.com> is
+availlable at http://www.oche.de/~akupries/soft/trf/trf_zip.html
+
+An experimental package to read and write files in .zip format, written on top
+of zlib by Gilles Vollant <info@winimage.com>, is available in the
+contrib/minizip directory of zlib.
+
+
+Notes for some targets:
+
+- For Windows DLL versions, please see win32/DLL_FAQ.txt
+
+- For 64-bit Irix, deflate.c must be compiled without any optimization. With
+ -O, one libpng test fails. The test works in 32 bit mode (with the -n32
+ compiler flag). The compiler bug has been reported to SGI.
+
+- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works
+ when compiled with cc.
+
+- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is
+ necessary to get gzprintf working correctly. This is done by configure.
+
+- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with
+ other compilers. Use "make test" to check your compiler.
+
+- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers.
+
+- For PalmOs, see http://palmzlib.sourceforge.net/
+
+- When building a shared, i.e. dynamic library on Mac OS X, the library must be
+ installed before testing (do "make install" before "make test"), since the
+ library location is specified in the library.
+
+
+Acknowledgments:
+
+ The deflate format used by zlib was defined by Phil Katz. The deflate
+ and zlib specifications were written by L. Peter Deutsch. Thanks to all the
+ people who reported problems and suggested various improvements in zlib;
+ they are too numerous to cite here.
+
+Copyright notice:
+
+ (C) 1995-2004 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ jloup@gzip.org madler@alumni.caltech.edu
+
+If you use the zlib library in a product, we would appreciate *not*
+receiving lengthy legal documents to sign. The sources are provided
+for free but without warranty of any kind. The library has been
+entirely written by Jean-loup Gailly and Mark Adler; it does not
+include third-party code.
+
+If you redistribute modified sources, we would appreciate that you include
+in the file ChangeLog history information documenting your changes. Please
+read the FAQ for more information on the distribution of modified source
+versions.
diff --git a/Utilities/cmzlib/README.Kitware.txt b/Utilities/cmzlib/README.Kitware.txt
new file mode 100644
index 000000000..77a1e165f
--- /dev/null
+++ b/Utilities/cmzlib/README.Kitware.txt
@@ -0,0 +1,40 @@
+This directory contains a subset of the zlib library (1.2.3) and
+some custom changes.
+
+We only include enough of the distribution to provide the functionalities
+required.
+
+We would like to thank the zlib team for distributing this library.
+http://www.zlib.net
+
+Added Files
+-----------
+
+CMakeLists.txt
+ -Support building with CMake.
+
+zlib.rc
+ -For MS Windows only: provide a version resource in a dll build so that
+ when you look at the dll file in Windows explorer, it will show you the
+ version in the "Version" tab of the file's properties view.
+
+zlib.def
+ -For MS Windows only: used to explicitly list the exports from dll builds.
+
+cm_zlib_mangle.h
+ -Mangles symbols exported from the zlib library for use by CMake.
+
+zlibDllConfig.h.in
+ -Configures the correct value of the ZLIB_DLL define based on the
+ BUILD_SHARED_LIBS CMake option.
+
+Changed Files
+-------------
+You can search the code for "KITWARE_ZLIB_CHANGE" to find modifications
+vs the original zlib code
+
+zconf.h
+ -Include cm_zlib_mangle.h (at the top)
+ -Include cmzlib/zlibDllConfig.h (at the top)
+ -Changed an #if 0 to #ifdef HAVE_UNISTD_H (near middle)
+ -Suppress selected compiler warnings (at the bottom)
diff --git a/Utilities/cmzlib/adler32.c b/Utilities/cmzlib/adler32.c
new file mode 100644
index 000000000..007ba2627
--- /dev/null
+++ b/Utilities/cmzlib/adler32.c
@@ -0,0 +1,149 @@
+/* adler32.c -- compute the Adler-32 checksum of a data stream
+ * Copyright (C) 1995-2004 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+#define BASE 65521UL /* largest prime smaller than 65536 */
+#define NMAX 5552
+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
+
+#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
+#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
+#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
+#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
+#define DO16(buf) DO8(buf,0); DO8(buf,8);
+
+/* use NO_DIVIDE if your processor does not do division in hardware */
+#ifdef NO_DIVIDE
+# define MOD(a) \
+ do { \
+ if (a >= (BASE << 16)) a -= (BASE << 16); \
+ if (a >= (BASE << 15)) a -= (BASE << 15); \
+ if (a >= (BASE << 14)) a -= (BASE << 14); \
+ if (a >= (BASE << 13)) a -= (BASE << 13); \
+ if (a >= (BASE << 12)) a -= (BASE << 12); \
+ if (a >= (BASE << 11)) a -= (BASE << 11); \
+ if (a >= (BASE << 10)) a -= (BASE << 10); \
+ if (a >= (BASE << 9)) a -= (BASE << 9); \
+ if (a >= (BASE << 8)) a -= (BASE << 8); \
+ if (a >= (BASE << 7)) a -= (BASE << 7); \
+ if (a >= (BASE << 6)) a -= (BASE << 6); \
+ if (a >= (BASE << 5)) a -= (BASE << 5); \
+ if (a >= (BASE << 4)) a -= (BASE << 4); \
+ if (a >= (BASE << 3)) a -= (BASE << 3); \
+ if (a >= (BASE << 2)) a -= (BASE << 2); \
+ if (a >= (BASE << 1)) a -= (BASE << 1); \
+ if (a >= BASE) a -= BASE; \
+ } while (0)
+# define MOD4(a) \
+ do { \
+ if (a >= (BASE << 4)) a -= (BASE << 4); \
+ if (a >= (BASE << 3)) a -= (BASE << 3); \
+ if (a >= (BASE << 2)) a -= (BASE << 2); \
+ if (a >= (BASE << 1)) a -= (BASE << 1); \
+ if (a >= BASE) a -= BASE; \
+ } while (0)
+#else
+# define MOD(a) a %= BASE
+# define MOD4(a) a %= BASE
+#endif
+
+/* ========================================================================= */
+uLong ZEXPORT adler32(adler, buf, len)
+ uLong adler;
+ const Bytef *buf;
+ uInt len;
+{
+ unsigned long sum2;
+ unsigned n;
+
+ /* split Adler-32 into component sums */
+ sum2 = (adler >> 16) & 0xffff;
+ adler &= 0xffff;
+
+ /* in case user likes doing a byte at a time, keep it fast */
+ if (len == 1) {
+ adler += buf[0];
+ if (adler >= BASE)
+ adler -= BASE;
+ sum2 += adler;
+ if (sum2 >= BASE)
+ sum2 -= BASE;
+ return adler | (sum2 << 16);
+ }
+
+ /* initial Adler-32 value (deferred check for len == 1 speed) */
+ if (buf == Z_NULL)
+ return 1L;
+
+ /* in case short lengths are provided, keep it somewhat fast */
+ if (len < 16) {
+ while (len--) {
+ adler += *buf++;
+ sum2 += adler;
+ }
+ if (adler >= BASE)
+ adler -= BASE;
+ MOD4(sum2); /* only added so many BASE's */
+ return adler | (sum2 << 16);
+ }
+
+ /* do length NMAX blocks -- requires just one modulo operation */
+ while (len >= NMAX) {
+ len -= NMAX;
+ n = NMAX / 16; /* NMAX is divisible by 16 */
+ do {
+ DO16(buf); /* 16 sums unrolled */
+ buf += 16;
+ } while (--n);
+ MOD(adler);
+ MOD(sum2);
+ }
+
+ /* do remaining bytes (less than NMAX, still just one modulo) */
+ if (len) { /* avoid modulos if none remaining */
+ while (len >= 16) {
+ len -= 16;
+ DO16(buf);
+ buf += 16;
+ }
+ while (len--) {
+ adler += *buf++;
+ sum2 += adler;
+ }
+ MOD(adler);
+ MOD(sum2);
+ }
+
+ /* return recombined sums */
+ return adler | (sum2 << 16);
+}
+
+/* ========================================================================= */
+uLong ZEXPORT adler32_combine(adler1, adler2, len2)
+ uLong adler1;
+ uLong adler2;
+ z_off_t len2;
+{
+ unsigned long sum1;
+ unsigned long sum2;
+ unsigned rem;
+
+ /* the derivation of this formula is left as an exercise for the reader */
+ rem = (unsigned)(len2 % BASE);
+ sum1 = adler1 & 0xffff;
+ sum2 = rem * sum1;
+ MOD(sum2);
+ sum1 += (adler2 & 0xffff) + BASE - 1;
+ sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
+ if (sum1 > BASE) sum1 -= BASE;
+ if (sum1 > BASE) sum1 -= BASE;
+ if (sum2 > (BASE << 1)) sum2 -= (BASE << 1);
+ if (sum2 > BASE) sum2 -= BASE;
+ return sum1 | (sum2 << 16);
+}
diff --git a/Utilities/cmzlib/cm_zlib_mangle.h b/Utilities/cmzlib/cm_zlib_mangle.h
new file mode 100644
index 000000000..7f001a596
--- /dev/null
+++ b/Utilities/cmzlib/cm_zlib_mangle.h
@@ -0,0 +1,93 @@
+#ifndef cm_zlib_mangle_h
+#define cm_zlib_mangle_h
+
+/*
+
+This header file mangles all symbols exported from the zlib library.
+It is included in all files while building the zlib library. Due to
+namespace pollution, no zlib headers should be included in .h files in
+cm.
+
+The following command was used to obtain the symbol list:
+
+nm libcmzlib.so |grep " [TRD] "
+
+This is the way to recreate the whole list:
+
+nm libcmzlib.so |grep " [TRD] " | awk '{ print "#define "$3" cm_zlib_"$3 }'
+
+REMOVE the "_init" and "_fini" entries.
+
+*/
+
+#define adler32 cm_zlib_adler32
+#define adler32_combine cm_zlib_adler32_combine
+#define compress cm_zlib_compress
+#define compress2 cm_zlib_compress2
+#define compressBound cm_zlib_compressBound
+#define crc32 cm_zlib_crc32
+#define crc32_combine cm_zlib_crc32_combine
+#define get_crc_table cm_zlib_get_crc_table
+#define deflate cm_zlib_deflate
+#define deflateBound cm_zlib_deflateBound
+#define deflateCopy cm_zlib_deflateCopy
+#define deflateEnd cm_zlib_deflateEnd
+#define deflateInit2_ cm_zlib_deflateInit2_
+#define deflateInit_ cm_zlib_deflateInit_
+#define deflateParams cm_zlib_deflateParams
+#define deflatePrime cm_zlib_deflatePrime
+#define deflateReset cm_zlib_deflateReset
+#define deflateSetDictionary cm_zlib_deflateSetDictionary
+#define deflateSetHeader cm_zlib_deflateSetHeader
+#define deflateTune cm_zlib_deflateTune
+#define deflate_copyright cm_zlib_deflate_copyright
+#define gzclearerr cm_zlib_gzclearerr
+#define gzclose cm_zlib_gzclose
+#define gzdirect cm_zlib_gzdirect
+#define gzdopen cm_zlib_gzdopen
+#define gzeof cm_zlib_gzeof
+#define gzerror cm_zlib_gzerror
+#define gzflush cm_zlib_gzflush
+#define gzgetc cm_zlib_gzgetc
+#define gzgets cm_zlib_gzgets
+#define gzopen cm_zlib_gzopen
+#define gzprintf cm_zlib_gzprintf
+#define gzputc cm_zlib_gzputc
+#define gzputs cm_zlib_gzputs
+#define gzread cm_zlib_gzread
+#define gzrewind cm_zlib_gzrewind
+#define gzseek cm_zlib_gzseek
+#define gzsetparams cm_zlib_gzsetparams
+#define gztell cm_zlib_gztell
+#define gzungetc cm_zlib_gzungetc
+#define gzwrite cm_zlib_gzwrite
+#define inflate_fast cm_zlib_inflate_fast
+#define inflate cm_zlib_inflate
+#define inflateCopy cm_zlib_inflateCopy
+#define inflateEnd cm_zlib_inflateEnd
+#define inflateGetHeader cm_zlib_inflateGetHeader
+#define inflateInit2_ cm_zlib_inflateInit2_
+#define inflateInit_ cm_zlib_inflateInit_
+#define inflatePrime cm_zlib_inflatePrime
+#define inflateReset cm_zlib_inflateReset
+#define inflateSetDictionary cm_zlib_inflateSetDictionary
+#define inflateSync cm_zlib_inflateSync
+#define inflateSyncPoint cm_zlib_inflateSyncPoint
+#define inflate_copyright cm_zlib_inflate_copyright
+#define inflate_table cm_zlib_inflate_table
+#define _dist_code cm_zlib__dist_code
+#define _length_code cm_zlib__length_code
+#define _tr_align cm_zlib__tr_align
+#define _tr_flush_block cm_zlib__tr_flush_block
+#define _tr_init cm_zlib__tr_init
+#define _tr_stored_block cm_zlib__tr_stored_block
+#define _tr_tally cm_zlib__tr_tally
+#define uncompress cm_zlib_uncompress
+#define zError cm_zlib_zError
+#define z_errmsg cm_zlib_z_errmsg
+#define zcalloc cm_zlib_zcalloc
+#define zcfree cm_zlib_zcfree
+#define zlibCompileFlags cm_zlib_zlibCompileFlags
+#define zlibVersion cm_zlib_zlibVersion
+
+#endif
diff --git a/Utilities/cmzlib/compress.c b/Utilities/cmzlib/compress.c
new file mode 100644
index 000000000..df04f0148
--- /dev/null
+++ b/Utilities/cmzlib/compress.c
@@ -0,0 +1,79 @@
+/* compress.c -- compress a memory buffer
+ * Copyright (C) 1995-2003 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+/* ===========================================================================
+ Compresses the source buffer into the destination buffer. The level
+ parameter has the same meaning as in deflateInit. sourceLen is the byte
+ length of the source buffer. Upon entry, destLen is the total size of the
+ destination buffer, which must be at least 0.1% larger than sourceLen plus
+ 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
+
+ compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+ Z_STREAM_ERROR if the level parameter is invalid.
+*/
+int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
+ Bytef *dest;
+ uLongf *destLen;
+ const Bytef *source;
+ uLong sourceLen;
+ int level;
+{
+ z_stream stream;
+ int err;
+
+ stream.next_in = (Bytef*)source;
+ stream.avail_in = (uInt)sourceLen;
+#ifdef MAXSEG_64K
+ /* Check for source > 64K on 16-bit machine: */
+ if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
+#endif
+ stream.next_out = dest;
+ stream.avail_out = (uInt)*destLen;
+ if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+
+ stream.zalloc = (alloc_func)0;
+ stream.zfree = (free_func)0;
+ stream.opaque = (voidpf)0;
+
+ err = deflateInit(&stream, level);
+ if (err != Z_OK) return err;
+
+ err = deflate(&stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ deflateEnd(&stream);
+ return err == Z_OK ? Z_BUF_ERROR : err;
+ }
+ *destLen = stream.total_out;
+
+ err = deflateEnd(&stream);
+ return err;
+}
+
+/* ===========================================================================
+ */
+int ZEXPORT compress (dest, destLen, source, sourceLen)
+ Bytef *dest;
+ uLongf *destLen;
+ const Bytef *source;
+ uLong sourceLen;
+{
+ return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
+}
+
+/* ===========================================================================
+ If the default memLevel or windowBits for deflateInit() is changed, then
+ this function needs to be updated.
+ */
+uLong ZEXPORT compressBound (sourceLen)
+ uLong sourceLen;
+{
+ return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11;
+}
diff --git a/Utilities/cmzlib/crc32.c b/Utilities/cmzlib/crc32.c
new file mode 100644
index 000000000..f658a9ef5
--- /dev/null
+++ b/Utilities/cmzlib/crc32.c
@@ -0,0 +1,423 @@
+/* crc32.c -- compute the CRC-32 of a data stream
+ * Copyright (C) 1995-2005 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
+ * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
+ * tables for updating the shift register in one step with three exclusive-ors
+ * instead of four steps with four exclusive-ors. This results in about a
+ * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
+ */
+
+/* @(#) $Id$ */
+
+/*
+ Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
+ protection on the static variables used to control the first-use generation
+ of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
+ first call get_crc_table() to initialize the tables before allowing more than
+ one thread to use crc32().
+ */
+
+#ifdef MAKECRCH
+# include <stdio.h>
+# ifndef DYNAMIC_CRC_TABLE
+# define DYNAMIC_CRC_TABLE
+# endif /* !DYNAMIC_CRC_TABLE */
+#endif /* MAKECRCH */
+
+#include "zutil.h" /* for STDC and FAR definitions */
+
+#define local static
+
+/* Find a four-byte integer type for crc32_little() and crc32_big(). */
+#ifndef NOBYFOUR
+# ifdef STDC /* need ANSI C limits.h to determine sizes */
+# include <limits.h>
+# define BYFOUR
+# if (UINT_MAX == 0xffffffffUL)
+ typedef unsigned int u4;
+# else
+# if (ULONG_MAX == 0xffffffffUL)
+ typedef unsigned long u4;
+# else
+# if (USHRT_MAX == 0xffffffffUL)
+ typedef unsigned short u4;
+# else
+# undef BYFOUR /* can't find a four-byte integer type! */
+# endif
+# endif
+# endif
+# endif /* STDC */
+#endif /* !NOBYFOUR */
+
+/* Definitions for doing the crc four data bytes at a time. */
+#ifdef BYFOUR
+# define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \
+ (((w)&0xff00)<<8)+(((w)&0xff)<<24))
+ local unsigned long crc32_little OF((unsigned long,
+ const unsigned char FAR *, unsigned));
+ local unsigned long crc32_big OF((unsigned long,
+ const unsigned char FAR *, unsigned));
+# define TBLS 8
+#else
+# define TBLS 1
+#endif /* BYFOUR */
+
+/* Local functions for crc concatenation */
+local unsigned long gf2_matrix_times OF((unsigned long *mat,
+ unsigned long vec));
+local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
+
+#ifdef DYNAMIC_CRC_TABLE
+
+local volatile int crc_table_empty = 1;
+local unsigned long FAR crc_table[TBLS][256];
+local void make_crc_table OF((void));
+#ifdef MAKECRCH
+ local void write_table OF((FILE *, const unsigned long FAR *));
+#endif /* MAKECRCH */
+/*
+ Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
+ x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
+
+ Polynomials over GF(2) are represented in binary, one bit per coefficient,
+ with the lowest powers in the most significant bit. Then adding polynomials
+ is just exclusive-or, and multiplying a polynomial by x is a right shift by
+ one. If we call the above polynomial p, and represent a byte as the
+ polynomial q, also with the lowest power in the most significant bit (so the
+ byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
+ where a mod b means the remainder after dividing a by b.
+
+ This calculation is done using the shift-register method of multiplying and
+ taking the remainder. The register is initialized to zero, and for each
+ incoming bit, x^32 is added mod p to the register if the bit is a one (where
+ x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
+ x (which is shifting right by one and adding x^32 mod p if the bit shifted
+ out is a one). We start with the highest power (least significant bit) of
+ q and repeat for all eight bits of q.
+
+ The first table is simply the CRC of all possible eight bit values. This is
+ all the information needed to generate CRCs on data a byte at a time for all
+ combinations of CRC register values and incoming bytes. The remaining tables
+ allow for word-at-a-time CRC calculation for both big-endian and little-
+ endian machines, where a word is four bytes.
+*/
+local void make_crc_table()
+{
+ unsigned long c;
+ int n, k;
+ unsigned long poly; /* polynomial exclusive-or pattern */
+ /* terms of polynomial defining this crc (except x^32): */
+ static volatile int first = 1; /* flag to limit concurrent making */
+ static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
+
+ /* See if another task is already doing this (not thread-safe, but better
+ than nothing -- significantly reduces duration of vulnerability in
+ case the advice about DYNAMIC_CRC_TABLE is ignored) */
+ if (first) {
+ first = 0;
+
+ /* make exclusive-or pattern from polynomial (0xedb88320UL) */
+ poly = 0UL;
+ for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
+ poly |= 1UL << (31 - p[n]);
+
+ /* generate a crc for every 8-bit value */
+ for (n = 0; n < 256; n++) {
+ c = (unsigned long)n;
+ for (k = 0; k < 8; k++)
+ c = c & 1 ? poly ^ (c >> 1) : c >> 1;
+ crc_table[0][n] = c;
+ }
+
+#ifdef BYFOUR
+ /* generate crc for each value followed by one, two, and three zeros,
+ and then the byte reversal of those as well as the first table */
+ for (n = 0; n < 256; n++) {
+ c = crc_table[0][n];
+ crc_table[4][n] = REV(c);
+ for (k = 1; k < 4; k++) {
+ c = crc_table[0][c & 0xff] ^ (c >> 8);
+ crc_table[k][n] = c;
+ crc_table[k + 4][n] = REV(c);
+ }
+ }
+#endif /* BYFOUR */
+
+ crc_table_empty = 0;
+ }
+ else { /* not first */
+ /* wait for the other guy to finish (not efficient, but rare) */
+ while (crc_table_empty)
+ ;
+ }
+
+#ifdef MAKECRCH
+ /* write out CRC tables to crc32.h */
+ {
+ FILE *out;
+
+ out = fopen("crc32.h", "w");
+ if (out == NULL) return;
+ fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
+ fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
+ fprintf(out, "local const unsigned long FAR ");
+ fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
+ write_table(out, crc_table[0]);
+# ifdef BYFOUR
+ fprintf(out, "#ifdef BYFOUR\n");
+ for (k = 1; k < 8; k++) {
+ fprintf(out, " },\n {\n");
+ write_table(out, crc_table[k]);
+ }
+ fprintf(out, "#endif\n");
+# endif /* BYFOUR */
+ fprintf(out, " }\n};\n");
+ fclose(out);
+ }
+#endif /* MAKECRCH */
+}
+
+#ifdef MAKECRCH
+local void write_table(out, table)
+ FILE *out;
+ const unsigned long FAR *table;
+{
+ int n;
+
+ for (n = 0; n < 256; n++)
+ fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n],
+ n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
+}
+#endif /* MAKECRCH */
+
+#else /* !DYNAMIC_CRC_TABLE */
+/* ========================================================================
+ * Tables of CRC-32s of all single-byte values, made by make_crc_table().
+ */
+#include "crc32.h"
+#endif /* DYNAMIC_CRC_TABLE */
+
+/* =========================================================================
+ * This function can be used by asm versions of crc32()
+ */
+const unsigned long FAR * ZEXPORT get_crc_table()
+{
+#ifdef DYNAMIC_CRC_TABLE
+ if (crc_table_empty)
+ make_crc_table();
+#endif /* DYNAMIC_CRC_TABLE */
+ return (const unsigned long FAR *)crc_table;
+}
+
+/* ========================================================================= */
+#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
+#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
+
+/* ========================================================================= */
+unsigned long ZEXPORT crc32(crc, buf, len)
+ unsigned long crc;
+ const unsigned char FAR *buf;
+ unsigned len;
+{
+ if (buf == Z_NULL) return 0UL;
+
+#ifdef DYNAMIC_CRC_TABLE
+ if (crc_table_empty)
+ make_crc_table();
+#endif /* DYNAMIC_CRC_TABLE */
+
+#ifdef BYFOUR
+ if (sizeof(void *) == sizeof(ptrdiff_t)) {
+ u4 endian;
+
+ endian = 1;
+ if (*((unsigned char *)(&endian)))
+ return crc32_little(crc, buf, len);
+ else
+ return crc32_big(crc, buf, len);
+ }
+#endif /* BYFOUR */
+ crc = crc ^ 0xffffffffUL;
+ while (len >= 8) {
+ DO8;
+ len -= 8;
+ }
+ if (len) do {
+ DO1;
+ } while (--len);
+ return crc ^ 0xffffffffUL;
+}
+
+#ifdef BYFOUR
+
+/* ========================================================================= */
+#define DOLIT4 c ^= *buf4++; \
+ c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
+ crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
+#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
+
+/* ========================================================================= */
+local unsigned long crc32_little(crc, buf, len)
+ unsigned long crc;
+ const unsigned char FAR *buf;
+ unsigned len;
+{
+ register u4 c;
+ register const u4 FAR *buf4;
+
+ c = (u4)crc;
+ c = ~c;
+ while (len && ((ptrdiff_t)buf & 3)) {
+ c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
+ len--;
+ }
+
+ buf4 = (const u4 FAR *)(const void FAR *)buf;
+ while (len >= 32) {
+ DOLIT32;
+ len -= 32;
+ }
+ while (len >= 4) {
+ DOLIT4;
+ len -= 4;
+ }
+ buf = (const unsigned char FAR *)buf4;
+
+ if (len) do {
+ c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
+ } while (--len);
+ c = ~c;
+ return (unsigned long)c;
+}
+
+/* ========================================================================= */
+#define DOBIG4 c ^= *++buf4; \
+ c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
+ crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
+#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
+
+/* ========================================================================= */
+local unsigned long crc32_big(crc, buf, len)
+ unsigned long crc;
+ const unsigned char FAR *buf;
+ unsigned len;
+{
+ register u4 c;
+ register const u4 FAR *buf4;
+
+ c = REV((u4)crc);
+ c = ~c;
+ while (len && ((ptrdiff_t)buf & 3)) {
+ c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
+ len--;
+ }
+
+ buf4 = (const u4 FAR *)(const void FAR *)buf;
+ buf4--;
+ while (len >= 32) {
+ DOBIG32;
+ len -= 32;
+ }
+ while (len >= 4) {
+ DOBIG4;
+ len -= 4;
+ }
+ buf4++;
+ buf = (const unsigned char FAR *)buf4;
+
+ if (len) do {
+ c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
+ } while (--len);
+ c = ~c;
+ return (unsigned long)(REV(c));
+}
+
+#endif /* BYFOUR */
+
+#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */
+
+/* ========================================================================= */
+local unsigned long gf2_matrix_times(mat, vec)
+ unsigned long *mat;
+ unsigned long vec;
+{
+ unsigned long sum;
+
+ sum = 0;
+ while (vec) {
+ if (vec & 1)
+ sum ^= *mat;
+ vec >>= 1;
+ mat++;
+ }
+ return sum;
+}
+
+/* ========================================================================= */
+local void gf2_matrix_square(square, mat)
+ unsigned long *square;
+ unsigned long *mat;
+{
+ int n;
+
+ for (n = 0; n < GF2_DIM; n++)
+ square[n] = gf2_matrix_times(mat, mat[n]);
+}
+
+/* ========================================================================= */
+uLong ZEXPORT crc32_combine(crc1, crc2, len2)
+ uLong crc1;
+ uLong crc2;
+ z_off_t len2;
+{
+ int n;
+ unsigned long row;
+ unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */
+ unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */
+
+ /* degenerate case */
+ if (len2 == 0)
+ return crc1;
+
+ /* put operator for one zero bit in odd */
+ odd[0] = 0xedb88320L; /* CRC-32 polynomial */
+ row = 1;
+ for (n = 1; n < GF2_DIM; n++) {
+ odd[n] = row;
+ row <<= 1;
+ }
+
+ /* put operator for two zero bits in even */
+ gf2_matrix_square(even, odd);
+
+ /* put operator for four zero bits in odd */
+ gf2_matrix_square(odd, even);
+
+ /* apply len2 zeros to crc1 (first square will put the operator for one
+ zero byte, eight zero bits, in even) */
+ do {
+ /* apply zeros operator for this bit of len2 */
+ gf2_matrix_square(even, odd);
+ if (len2 & 1)
+ crc1 = gf2_matrix_times(even, crc1);
+ len2 >>= 1;
+
+ /* if no more bits set, then done */
+ if (len2 == 0)
+ break;
+
+ /* another iteration of the loop with odd and even swapped */
+ gf2_matrix_square(odd, even);
+ if (len2 & 1)
+ crc1 = gf2_matrix_times(odd, crc1);
+ len2 >>= 1;
+
+ /* if no more bits set, then done */
+ } while (len2 != 0);
+
+ /* return combined crc */
+ crc1 ^= crc2;
+ return crc1;
+}
diff --git a/Utilities/cmzlib/crc32.h b/Utilities/cmzlib/crc32.h
new file mode 100644
index 000000000..8053b6117
--- /dev/null
+++ b/Utilities/cmzlib/crc32.h
@@ -0,0 +1,441 @@
+/* crc32.h -- tables for rapid CRC calculation
+ * Generated automatically by crc32.c
+ */
+
+local const unsigned long FAR crc_table[TBLS][256] =
+{
+ {
+ 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
+ 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
+ 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
+ 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
+ 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
+ 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
+ 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
+ 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
+ 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
+ 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
+ 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
+ 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
+ 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
+ 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
+ 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
+ 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
+ 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
+ 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
+ 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
+ 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
+ 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
+ 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
+ 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
+ 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
+ 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
+ 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
+ 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
+ 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
+ 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
+ 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
+ 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
+ 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
+ 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
+ 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
+ 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
+ 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
+ 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
+ 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
+ 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
+ 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
+ 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
+ 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
+ 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
+ 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
+ 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
+ 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
+ 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
+ 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
+ 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
+ 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
+ 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
+ 0x2d02ef8dUL
+#ifdef BYFOUR
+ },
+ {
+ 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL,
+ 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL,
+ 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL,
+ 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL,
+ 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL,
+ 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL,
+ 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL,
+ 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL,
+ 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL,
+ 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL,
+ 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL,
+ 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL,
+ 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL,
+ 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL,
+ 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL,
+ 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL,
+ 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL,
+ 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL,
+ 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL,
+ 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL,
+ 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL,
+ 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL,
+ 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL,
+ 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL,
+ 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL,
+ 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL,
+ 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL,
+ 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL,
+ 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL,
+ 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL,
+ 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL,
+ 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL,
+ 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL,
+ 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL,
+ 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL,
+ 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL,
+ 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL,
+ 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL,
+ 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL,
+ 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL,
+ 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL,
+ 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL,
+ 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL,
+ 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL,
+ 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL,
+ 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL,
+ 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL,
+ 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL,
+ 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL,
+ 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL,
+ 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL,
+ 0x9324fd72UL
+ },
+ {
+ 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL,
+ 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL,
+ 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL,
+ 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL,
+ 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL,
+ 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL,
+ 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL,
+ 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL,
+ 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL,
+ 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL,
+ 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL,
+ 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL,
+ 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL,
+ 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL,
+ 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL,
+ 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL,
+ 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL,
+ 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL,
+ 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL,
+ 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL,
+ 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL,
+ 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL,
+ 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL,
+ 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL,
+ 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL,
+ 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL,
+ 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL,
+ 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL,
+ 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL,
+ 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL,
+ 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL,
+ 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL,
+ 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL,
+ 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL,
+ 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL,
+ 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL,
+ 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL,
+ 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL,
+ 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL,
+ 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL,
+ 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL,
+ 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL,
+ 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL,
+ 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL,
+ 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL,
+ 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL,
+ 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL,
+ 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL,
+ 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL,
+ 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL,
+ 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL,
+ 0xbe9834edUL
+ },
+ {
+ 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL,
+ 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL,
+ 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL,
+ 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL,
+ 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL,
+ 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL,
+ 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL,
+ 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL,
+ 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL,
+ 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL,
+ 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL,
+ 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL,
+ 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL,
+ 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL,
+ 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL,
+ 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL,
+ 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL,
+ 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL,
+ 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL,
+ 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL,
+ 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL,
+ 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL,
+ 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL,
+ 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL,
+ 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL,
+ 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL,
+ 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL,
+ 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL,
+ 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL,
+ 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL,
+ 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL,
+ 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL,
+ 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL,
+ 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL,
+ 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL,
+ 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL,
+ 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL,
+ 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL,
+ 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL,
+ 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL,
+ 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL,
+ 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL,
+ 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL,
+ 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL,
+ 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL,
+ 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL,
+ 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL,
+ 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL,
+ 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL,
+ 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL,
+ 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL,
+ 0xde0506f1UL
+ },
+ {
+ 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL,
+ 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL,
+ 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL,
+ 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL,
+ 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL,
+ 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL,
+ 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL,
+ 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL,
+ 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL,
+ 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL,
+ 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL,
+ 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL,
+ 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL,
+ 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL,
+ 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL,
+ 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL,
+ 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL,
+ 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL,
+ 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL,
+ 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL,
+ 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL,
+ 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL,
+ 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL,
+ 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL,
+ 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL,
+ 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL,
+ 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL,
+ 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL,
+ 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL,
+ 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL,
+ 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL,
+ 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL,
+ 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL,
+ 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL,
+ 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL,
+ 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL,
+ 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL,
+ 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL,
+ 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL,
+ 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL,
+ 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL,
+ 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL,
+ 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL,
+ 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL,
+ 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL,
+ 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL,
+ 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL,
+ 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL,
+ 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL,
+ 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL,
+ 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL,
+ 0x8def022dUL
+ },
+ {
+ 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL,
+ 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL,
+ 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL,
+ 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL,
+ 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL,
+ 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL,
+ 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL,
+ 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL,
+ 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL,
+ 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL,
+ 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL,
+ 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL,
+ 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL,
+ 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL,
+ 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL,
+ 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL,
+ 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL,
+ 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL,
+ 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL,
+ 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL,
+ 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL,
+ 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL,
+ 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL,
+ 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL,
+ 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL,
+ 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL,
+ 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL,
+ 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL,
+ 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL,
+ 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL,
+ 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL,
+ 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL,
+ 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL,
+ 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL,
+ 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL,
+ 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL,
+ 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL,
+ 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL,
+ 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL,
+ 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL,
+ 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL,
+ 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL,
+ 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL,
+ 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL,
+ 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL,
+ 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL,
+ 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL,
+ 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL,
+ 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL,
+ 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL,
+ 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL,
+ 0x72fd2493UL
+ },
+ {
+ 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL,
+ 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL,
+ 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL,
+ 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL,
+ 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL,
+ 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL,
+ 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL,
+ 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL,
+ 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL,
+ 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL,
+ 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL,
+ 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL,
+ 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL,
+ 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL,
+ 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL,
+ 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL,
+ 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL,
+ 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL,
+ 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL,
+ 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL,
+ 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL,
+ 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL,
+ 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL,
+ 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL,
+ 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL,
+ 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL,
+ 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL,
+ 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL,
+ 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL,
+ 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL,
+ 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL,
+ 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL,
+ 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL,
+ 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL,
+ 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL,
+ 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL,
+ 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL,
+ 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL,
+ 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL,
+ 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL,
+ 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL,
+ 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL,
+ 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL,
+ 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL,
+ 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL,
+ 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL,
+ 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL,
+ 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL,
+ 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL,
+ 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL,
+ 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL,
+ 0xed3498beUL
+ },
+ {
+ 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL,
+ 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL,
+ 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL,
+ 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL,
+ 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL,
+ 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL,
+ 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL,
+ 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL,
+ 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL,
+ 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL,
+ 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL,
+ 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL,
+ 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL,
+ 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL,
+ 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL,
+ 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL,
+ 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL,
+ 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL,
+ 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL,
+ 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL,
+ 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL,
+ 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL,
+ 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL,
+ 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL,
+ 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL,
+ 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL,
+ 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL,
+ 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL,
+ 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL,
+ 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL,
+ 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL,
+ 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL,
+ 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL,
+ 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL,
+ 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL,
+ 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL,
+ 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL,
+ 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL,
+ 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL,
+ 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL,
+ 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL,
+ 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL,
+ 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL,
+ 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL,
+ 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL,
+ 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL,
+ 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL,
+ 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL,
+ 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL,
+ 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL,
+ 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL,
+ 0xf10605deUL
+#endif
+ }
+};
diff --git a/Utilities/cmzlib/deflate.c b/Utilities/cmzlib/deflate.c
new file mode 100644
index 000000000..5ec837433
--- /dev/null
+++ b/Utilities/cmzlib/deflate.c
@@ -0,0 +1,1743 @@
+/* deflate.c -- compress data using the deflation algorithm
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * ALGORITHM
+ *
+ * The "deflation" process depends on being able to identify portions
+ * of the input text which are identical to earlier input (within a
+ * sliding window trailing behind the input currently being processed).
+ *
+ * The most straightforward technique turns out to be the fastest for
+ * most input files: try all possible matches and select the longest.
+ * The key feature of this algorithm is that insertions into the string
+ * dictionary are very simple and thus fast, and deletions are avoided
+ * completely. Insertions are performed at each input character, whereas
+ * string matches are performed only when the previous match ends. So it
+ * is preferable to spend more time in matches to allow very fast string
+ * insertions and avoid deletions. The matching algorithm for small
+ * strings is inspired from that of Rabin & Karp. A brute force approach
+ * is used to find longer strings when a small match has been found.
+ * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
+ * (by Leonid Broukhis).
+ * A previous version of this file used a more sophisticated algorithm
+ * (by Fiala and Greene) which is guaranteed to run in linear amortized
+ * time, but has a larger average cost, uses more memory and is patented.
+ * However the F&G algorithm may be faster for some highly redundant
+ * files if the parameter max_chain_length (described below) is too large.
+ *
+ * ACKNOWLEDGEMENTS
+ *
+ * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
+ * I found it in 'freeze' written by Leonid Broukhis.
+ * Thanks to many people for bug reports and testing.
+ *
+ * REFERENCES
+ *
+ * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
+ * Available in http://www.ietf.org/rfc/rfc1951.txt
+ *
+ * A description of the Rabin and Karp algorithm is given in the book
+ * "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
+ *
+ * Fiala,E.R., and Greene,D.H.
+ * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
+ *
+ */
+
+/* @(#) $Id$ */
+
+#include "deflate.h"
+
+const char deflate_copyright[] =
+ " deflate 1.2.3 Copyright 1995-2005 Jean-loup Gailly ";
+/*
+ If you use the zlib library in a product, an acknowledgment is welcome
+ in the documentation of your product. If for some reason you cannot
+ include such an acknowledgment, I would appreciate that you keep this
+ copyright string in the executable of your product.
+ */
+
+/* ===========================================================================
+ * Function prototypes.
+ */
+typedef enum {
+ need_more, /* block not completed, need more input or more output */
+ block_done, /* block flush performed */
+ finish_started, /* finish started, need only more output at next deflate */
+ finish_done /* finish done, accept no more input or output */
+} block_state;
+
+typedef block_state (*compress_func) OF((deflate_state *s, int flush));
+/* Compression function. Returns the block state after the call. */
+
+local void fill_window OF((deflate_state *s));
+local block_state deflate_stored OF((deflate_state *s, int flush));
+local block_state deflate_fast OF((deflate_state *s, int flush));
+#ifndef FASTEST
+local block_state deflate_slow OF((deflate_state *s, int flush));
+#endif
+local void lm_init OF((deflate_state *s));
+local void putShortMSB OF((deflate_state *s, uInt b));
+local void flush_pending OF((z_streamp strm));
+local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
+#ifndef FASTEST
+#ifdef ASMV
+ void match_init OF((void)); /* asm code initialization */
+ uInt longest_match OF((deflate_state *s, IPos cur_match));
+#else
+local uInt longest_match OF((deflate_state *s, IPos cur_match));
+#endif
+#endif
+local uInt longest_match_fast OF((deflate_state *s, IPos cur_match));
+
+#ifdef DEBUG
+local void check_match OF((deflate_state *s, IPos start, IPos match,
+ int length));
+#endif
+
+/* ===========================================================================
+ * Local data
+ */
+
+#define NIL 0
+/* Tail of hash chains */
+
+#ifndef TOO_FAR
+# define TOO_FAR 4096
+#endif
+/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+/* Values for max_lazy_match, good_match and max_chain_length, depending on
+ * the desired pack level (0..9). The values given below have been tuned to
+ * exclude worst case performance for pathological files. Better values may be
+ * found for specific files.
+ */
+typedef struct config_s {
+ ush good_length; /* reduce lazy search above this match length */
+ ush max_lazy; /* do not perform lazy search above this match length */
+ ush nice_length; /* quit search above this match length */
+ ush max_chain;
+ compress_func func;
+} config;
+
+#ifdef FASTEST
+local const config configuration_table[2] = {
+/* good lazy nice chain */
+/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
+/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */
+#else
+local const config configuration_table[10] = {
+/* good lazy nice chain */
+/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
+/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */
+/* 2 */ {4, 5, 16, 8, deflate_fast},
+/* 3 */ {4, 6, 32, 32, deflate_fast},
+
+/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */
+/* 5 */ {8, 16, 32, 32, deflate_slow},
+/* 6 */ {8, 16, 128, 128, deflate_slow},
+/* 7 */ {8, 32, 128, 256, deflate_slow},
+/* 8 */ {32, 128, 258, 1024, deflate_slow},
+/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */
+#endif
+
+/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
+ * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
+ * meaning.
+ */
+
+#define EQUAL 0
+/* result of memcmp for equal strings */
+
+#ifndef NO_DUMMY_DECL
+struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
+#endif
+
+/* ===========================================================================
+ * Update a hash value with the given input byte
+ * IN assertion: all calls to to UPDATE_HASH are made with consecutive
+ * input characters, so that a running hash key can be computed from the
+ * previous key instead of complete recalculation each time.
+ */
+#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
+
+
+/* ===========================================================================
+ * Insert string str in the dictionary and set match_head to the previous head
+ * of the hash chain (the most recent string with same hash key). Return
+ * the previous length of the hash chain.
+ * If this file is compiled with -DFASTEST, the compression level is forced
+ * to 1, and no hash chains are maintained.
+ * IN assertion: all calls to to INSERT_STRING are made with consecutive
+ * input characters and the first MIN_MATCH bytes of str are valid
+ * (except for the last MIN_MATCH-1 bytes of the input file).
+ */
+#ifdef FASTEST
+#define INSERT_STRING(s, str, match_head) \
+ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+ match_head = s->head[s->ins_h], \
+ s->head[s->ins_h] = (Pos)(str))
+#else
+#define INSERT_STRING(s, str, match_head) \
+ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+ match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \
+ s->head[s->ins_h] = (Pos)(str))
+#endif
+
+/* ===========================================================================
+ * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
+ * prev[] will be initialized on the fly.
+ */
+#define CLEAR_HASH(s) \
+ s->head[s->hash_size-1] = NIL; \
+ zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
+
+/* ========================================================================= */
+int ZEXPORT deflateInit_(strm, level, version, stream_size)
+ z_streamp strm;
+ int level;
+ const char *version;
+ int stream_size;
+{
+ return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
+ Z_DEFAULT_STRATEGY, version, stream_size);
+ /* To do: ignore strm->next_in if we use it as window */
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
+ version, stream_size)
+ z_streamp strm;
+ int level;
+ int method;
+ int windowBits;
+ int memLevel;
+ int strategy;
+ const char *version;
+ int stream_size;
+{
+ deflate_state *s;
+ int wrap = 1;
+ static const char my_version[] = ZLIB_VERSION;
+
+ ushf *overlay;
+ /* We overlay pending_buf and d_buf+l_buf. This works since the average
+ * output size for (length,distance) codes is <= 24 bits.
+ */
+
+ if (version == Z_NULL || version[0] != my_version[0] ||
+ stream_size != sizeof(z_stream)) {
+ return Z_VERSION_ERROR;
+ }
+ if (strm == Z_NULL) return Z_STREAM_ERROR;
+
+ strm->msg = Z_NULL;
+ if (strm->zalloc == (alloc_func)0) {
+ strm->zalloc = zcalloc;
+ strm->opaque = (voidpf)0;
+ }
+ if (strm->zfree == (free_func)0) strm->zfree = zcfree;
+
+#ifdef FASTEST
+ if (level != 0) level = 1;
+#else
+ if (level == Z_DEFAULT_COMPRESSION) level = 6;
+#endif
+
+ if (windowBits < 0) { /* suppress zlib wrapper */
+ wrap = 0;
+ windowBits = -windowBits;
+ }
+#ifdef GZIP
+ else if (windowBits > 15) {
+ wrap = 2; /* write gzip wrapper instead */
+ windowBits -= 16;
+ }
+#endif
+ if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
+ windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
+ strategy < 0 || strategy > Z_FIXED) {
+ return Z_STREAM_ERROR;
+ }
+ if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */
+ s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
+ if (s == Z_NULL) return Z_MEM_ERROR;
+ strm->state = (struct internal_state FAR *)s;
+ s->strm = strm;
+
+ s->wrap = wrap;
+ s->gzhead = Z_NULL;
+ s->w_bits = windowBits;
+ s->w_size = 1 << s->w_bits;
+ s->w_mask = s->w_size - 1;
+
+ s->hash_bits = memLevel + 7;
+ s->hash_size = 1 << s->hash_bits;
+ s->hash_mask = s->hash_size - 1;
+ s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
+
+ s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
+
+ /* The following memset eliminates the valgrind uninitialized warning
+ "swept under the carpet" here:
+ http://www.zlib.net/zlib_faq.html#faq36 */
+
+ memset(s->window, 0, s->w_size*2*sizeof(Byte));
+
+ s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
+ s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
+
+ s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
+
+ overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
+ s->pending_buf = (uchf *) overlay;
+ s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
+
+ if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
+ s->pending_buf == Z_NULL) {
+ s->status = FINISH_STATE;
+ strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
+ deflateEnd (strm);
+ return Z_MEM_ERROR;
+ }
+ s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
+ s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
+
+ s->level = level;
+ s->strategy = strategy;
+ s->method = (Byte)method;
+
+ return deflateReset(strm);
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
+ z_streamp strm;
+ const Bytef *dictionary;
+ uInt dictLength;
+{
+ deflate_state *s;
+ uInt length = dictLength;
+ uInt n;
+ IPos hash_head = 0;
+
+ if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
+ strm->state->wrap == 2 ||
+ (strm->state->wrap == 1 && strm->state->status != INIT_STATE))
+ return Z_STREAM_ERROR;
+
+ s = strm->state;
+ if (s->wrap)
+ strm->adler = adler32(strm->adler, dictionary, dictLength);
+
+ if (length < MIN_MATCH) return Z_OK;
+ if (length > MAX_DIST(s)) {
+ length = MAX_DIST(s);
+ dictionary += dictLength - length; /* use the tail of the dictionary */
+ }
+ zmemcpy(s->window, dictionary, length);
+ s->strstart = length;
+ s->block_start = (long)length;
+
+ /* Insert all strings in the hash table (except for the last two bytes).
+ * s->lookahead stays null, so s->ins_h will be recomputed at the next
+ * call of fill_window.
+ */
+ s->ins_h = s->window[0];
+ UPDATE_HASH(s, s->ins_h, s->window[1]);
+ for (n = 0; n <= length - MIN_MATCH; n++) {
+ INSERT_STRING(s, n, hash_head);
+ }
+ if (hash_head) hash_head = 0; /* to make compiler happy */
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateReset (strm)
+ z_streamp strm;
+{
+ deflate_state *s;
+
+ if (strm == Z_NULL || strm->state == Z_NULL ||
+ strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) {
+ return Z_STREAM_ERROR;
+ }
+
+ strm->total_in = strm->total_out = 0;
+ strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
+ strm->data_type = Z_UNKNOWN;
+
+ s = (deflate_state *)strm->state;
+ s->pending = 0;
+ s->pending_out = s->pending_buf;
+
+ if (s->wrap < 0) {
+ s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */
+ }
+ s->status = s->wrap ? INIT_STATE : BUSY_STATE;
+ strm->adler =
+#ifdef GZIP
+ s->wrap == 2 ? crc32(0L, Z_NULL, 0) :
+#endif
+ adler32(0L, Z_NULL, 0);
+ s->last_flush = Z_NO_FLUSH;
+
+ _tr_init(s);
+ lm_init(s);
+
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateSetHeader (strm, head)
+ z_streamp strm;
+ gz_headerp head;
+{
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ if (strm->state->wrap != 2) return Z_STREAM_ERROR;
+ strm->state->gzhead = head;
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflatePrime (strm, bits, value)
+ z_streamp strm;
+ int bits;
+ int value;
+{
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ strm->state->bi_valid = bits;
+ strm->state->bi_buf = (ush)(value & ((1 << bits) - 1));
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateParams(strm, level, strategy)
+ z_streamp strm;
+ int level;
+ int strategy;
+{
+ deflate_state *s;
+ compress_func func;
+ int err = Z_OK;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ s = strm->state;
+
+#ifdef FASTEST
+ if (level != 0) level = 1;
+#else
+ if (level == Z_DEFAULT_COMPRESSION) level = 6;
+#endif
+ if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) {
+ return Z_STREAM_ERROR;
+ }
+ func = configuration_table[s->level].func;
+
+ if (func != configuration_table[level].func && strm->total_in != 0) {
+ /* Flush the last buffer: */
+ err = deflate(strm, Z_PARTIAL_FLUSH);
+ }
+ if (s->level != level) {
+ s->level = level;
+ s->max_lazy_match = configuration_table[level].max_lazy;
+ s->good_match = configuration_table[level].good_length;
+ s->nice_match = configuration_table[level].nice_length;
+ s->max_chain_length = configuration_table[level].max_chain;
+ }
+ s->strategy = strategy;
+ return err;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
+ z_streamp strm;
+ int good_length;
+ int max_lazy;
+ int nice_length;
+ int max_chain;
+{
+ deflate_state *s;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ s = strm->state;
+ s->good_match = good_length;
+ s->max_lazy_match = max_lazy;
+ s->nice_match = nice_length;
+ s->max_chain_length = max_chain;
+ return Z_OK;
+}
+
+/* =========================================================================
+ * For the default windowBits of 15 and memLevel of 8, this function returns
+ * a close to exact, as well as small, upper bound on the compressed size.
+ * They are coded as constants here for a reason--if the #define's are
+ * changed, then this function needs to be changed as well. The return
+ * value for 15 and 8 only works for those exact settings.
+ *
+ * For any setting other than those defaults for windowBits and memLevel,
+ * the value returned is a conservative worst case for the maximum expansion
+ * resulting from using fixed blocks instead of stored blocks, which deflate
+ * can emit on compressed data for some combinations of the parameters.
+ *
+ * This function could be more sophisticated to provide closer upper bounds
+ * for every combination of windowBits and memLevel, as well as wrap.
+ * But even the conservative upper bound of about 14% expansion does not
+ * seem onerous for output buffer allocation.
+ */
+uLong ZEXPORT deflateBound(strm, sourceLen)
+ z_streamp strm;
+ uLong sourceLen;
+{
+ deflate_state *s;
+ uLong destLen;
+
+ /* conservative upper bound */
+ destLen = sourceLen +
+ ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11;
+
+ /* if can't get parameters, return conservative bound */
+ if (strm == Z_NULL || strm->state == Z_NULL)
+ return destLen;
+
+ /* if not default parameters, return conservative bound */
+ s = strm->state;
+ if (s->w_bits != 15 || s->hash_bits != 8 + 7)
+ return destLen;
+
+ /* default settings: return tight bound for that case */
+ return compressBound(sourceLen);
+}
+
+/* =========================================================================
+ * Put a short in the pending buffer. The 16-bit value is put in MSB order.
+ * IN assertion: the stream state is correct and there is enough room in
+ * pending_buf.
+ */
+local void putShortMSB (s, b)
+ deflate_state *s;
+ uInt b;
+{
+ put_byte(s, (Byte)(b >> 8));
+ put_byte(s, (Byte)(b & 0xff));
+}
+
+/* =========================================================================
+ * Flush as much pending output as possible. All deflate() output goes
+ * through this function so some applications may wish to modify it
+ * to avoid allocating a large strm->next_out buffer and copying into it.
+ * (See also read_buf()).
+ */
+local void flush_pending(strm)
+ z_streamp strm;
+{
+ unsigned len = strm->state->pending;
+
+ if (len > strm->avail_out) len = strm->avail_out;
+ if (len == 0) return;
+
+ zmemcpy(strm->next_out, strm->state->pending_out, len);
+ strm->next_out += len;
+ strm->state->pending_out += len;
+ strm->total_out += len;
+ strm->avail_out -= len;
+ strm->state->pending -= len;
+ if (strm->state->pending == 0) {
+ strm->state->pending_out = strm->state->pending_buf;
+ }
+}
+
+/* ========================================================================= */
+int ZEXPORT deflate (strm, flush)
+ z_streamp strm;
+ int flush;
+{
+ int old_flush; /* value of flush param for previous deflate call */
+ deflate_state *s;
+
+ if (strm == Z_NULL || strm->state == Z_NULL ||
+ flush > Z_FINISH || flush < 0) {
+ return Z_STREAM_ERROR;
+ }
+ s = strm->state;
+
+ if (strm->next_out == Z_NULL ||
+ (strm->next_in == Z_NULL && strm->avail_in != 0) ||
+ (s->status == FINISH_STATE && flush != Z_FINISH)) {
+ ERR_RETURN(strm, Z_STREAM_ERROR);
+ }
+ if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
+
+ s->strm = strm; /* just in case */
+ old_flush = s->last_flush;
+ s->last_flush = flush;
+
+ /* Write the header */
+ if (s->status == INIT_STATE) {
+#ifdef GZIP
+ if (s->wrap == 2) {
+ strm->adler = crc32(0L, Z_NULL, 0);
+ put_byte(s, 31);
+ put_byte(s, 139);
+ put_byte(s, 8);
+ if (s->gzhead == NULL) {
+ put_byte(s, 0);
+ put_byte(s, 0);
+ put_byte(s, 0);
+ put_byte(s, 0);
+ put_byte(s, 0);
+ put_byte(s, s->level == 9 ? 2 :
+ (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
+ 4 : 0));
+ put_byte(s, OS_CODE);
+ s->status = BUSY_STATE;
+ }
+ else {
+ put_byte(s, (s->gzhead->text ? 1 : 0) +
+ (s->gzhead->hcrc ? 2 : 0) +
+ (s->gzhead->extra == Z_NULL ? 0 : 4) +
+ (s->gzhead->name == Z_NULL ? 0 : 8) +
+ (s->gzhead->comment == Z_NULL ? 0 : 16)
+ );
+ put_byte(s, (Byte)(s->gzhead->time & 0xff));
+ put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff));
+ put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff));
+ put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff));
+ put_byte(s, s->level == 9 ? 2 :
+ (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
+ 4 : 0));
+ put_byte(s, s->gzhead->os & 0xff);
+ if (s->gzhead->extra != NULL) {
+ put_byte(s, s->gzhead->extra_len & 0xff);
+ put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);
+ }
+ if (s->gzhead->hcrc)
+ strm->adler = crc32(strm->adler, s->pending_buf,
+ s->pending);
+ s->gzindex = 0;
+ s->status = EXTRA_STATE;
+ }
+ }
+ else
+#endif
+ {
+ uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
+ uInt level_flags;
+
+ if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
+ level_flags = 0;
+ else if (s->level < 6)
+ level_flags = 1;
+ else if (s->level == 6)
+ level_flags = 2;
+ else
+ level_flags = 3;
+ header |= (level_flags << 6);
+ if (s->strstart != 0) header |= PRESET_DICT;
+ header += 31 - (header % 31);
+
+ s->status = BUSY_STATE;
+ putShortMSB(s, header);
+
+ /* Save the adler32 of the preset dictionary: */
+ if (s->strstart != 0) {
+ putShortMSB(s, (uInt)(strm->adler >> 16));
+ putShortMSB(s, (uInt)(strm->adler & 0xffff));
+ }
+ strm->adler = adler32(0L, Z_NULL, 0);
+ }
+ }
+#ifdef GZIP
+ if (s->status == EXTRA_STATE) {
+ if (s->gzhead->extra != NULL) {
+ uInt beg = s->pending; /* start of bytes to update crc */
+
+ while (s->gzindex < (s->gzhead->extra_len & 0xffff)) {
+ if (s->pending == s->pending_buf_size) {
+ if (s->gzhead->hcrc && s->pending > beg)
+ strm->adler = crc32(strm->adler, s->pending_buf + beg,
+ s->pending - beg);
+ flush_pending(strm);
+ beg = s->pending;
+ if (s->pending == s->pending_buf_size)
+ break;
+ }
+ put_byte(s, s->gzhead->extra[s->gzindex]);
+ s->gzindex++;
+ }
+ if (s->gzhead->hcrc && s->pending > beg)
+ strm->adler = crc32(strm->adler, s->pending_buf + beg,
+ s->pending - beg);
+ if (s->gzindex == s->gzhead->extra_len) {
+ s->gzindex = 0;
+ s->status = NAME_STATE;
+ }
+ }
+ else
+ s->status = NAME_STATE;
+ }
+ if (s->status == NAME_STATE) {
+ if (s->gzhead->name != NULL) {
+ uInt beg = s->pending; /* start of bytes to update crc */
+ int val;
+
+ do {
+ if (s->pending == s->pending_buf_size) {
+ if (s->gzhead->hcrc && s->pending > beg)
+ strm->adler = crc32(strm->adler, s->pending_buf + beg,
+ s->pending - beg);
+ flush_pending(strm);
+ beg = s->pending;
+ if (s->pending == s->pending_buf_size) {
+ val = 1;
+ break;
+ }
+ }
+ val = s->gzhead->name[s->gzindex++];
+ put_byte(s, val);
+ } while (val != 0);
+ if (s->gzhead->hcrc && s->pending > beg)
+ strm->adler = crc32(strm->adler, s->pending_buf + beg,
+ s->pending - beg);
+ if (val == 0) {
+ s->gzindex = 0;
+ s->status = COMMENT_STATE;
+ }
+ }
+ else
+ s->status = COMMENT_STATE;
+ }
+ if (s->status == COMMENT_STATE) {
+ if (s->gzhead->comment != NULL) {
+ uInt beg = s->pending; /* start of bytes to update crc */
+ int val;
+
+ do {
+ if (s->pending == s->pending_buf_size) {
+ if (s->gzhead->hcrc && s->pending > beg)
+ strm->adler = crc32(strm->adler, s->pending_buf + beg,
+ s->pending - beg);
+ flush_pending(strm);
+ beg = s->pending;
+ if (s->pending == s->pending_buf_size) {
+ val = 1;
+ break;
+ }
+ }
+ val = s->gzhead->comment[s->gzindex++];
+ put_byte(s, val);
+ } while (val != 0);
+ if (s->gzhead->hcrc && s->pending > beg)
+ strm->adler = crc32(strm->adler, s->pending_buf + beg,
+ s->pending - beg);
+ if (val == 0)
+ s->status = HCRC_STATE;
+ }
+ else
+ s->status = HCRC_STATE;
+ }
+ if (s->status == HCRC_STATE) {
+ if (s->gzhead->hcrc) {
+ if (s->pending + 2 > s->pending_buf_size)
+ flush_pending(strm);
+ if (s->pending + 2 <= s->pending_buf_size) {
+ put_byte(s, (Byte)(strm->adler & 0xff));
+ put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
+ strm->adler = crc32(0L, Z_NULL, 0);
+ s->status = BUSY_STATE;
+ }
+ }
+ else
+ s->status = BUSY_STATE;
+ }
+#endif
+
+ /* Flush as much pending output as possible */
+ if (s->pending != 0) {
+ flush_pending(strm);
+ if (strm->avail_out == 0) {
+ /* Since avail_out is 0, deflate will be called again with
+ * more output space, but possibly with both pending and
+ * avail_in equal to zero. There won't be anything to do,
+ * but this is not an error situation so make sure we
+ * return OK instead of BUF_ERROR at next call of deflate:
+ */
+ s->last_flush = -1;
+ return Z_OK;
+ }
+
+ /* Make sure there is something to do and avoid duplicate consecutive
+ * flushes. For repeated and useless calls with Z_FINISH, we keep
+ * returning Z_STREAM_END instead of Z_BUF_ERROR.
+ */
+ } else if (strm->avail_in == 0 && flush <= old_flush &&
+ flush != Z_FINISH) {
+ ERR_RETURN(strm, Z_BUF_ERROR);
+ }
+
+ /* User must not provide more input after the first FINISH: */
+ if (s->status == FINISH_STATE && strm->avail_in != 0) {
+ ERR_RETURN(strm, Z_BUF_ERROR);
+ }
+
+ /* Start a new block or continue the current one.
+ */
+ if (strm->avail_in != 0 || s->lookahead != 0 ||
+ (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
+ block_state bstate;
+
+ bstate = (*(configuration_table[s->level].func))(s, flush);
+
+ if (bstate == finish_started || bstate == finish_done) {
+ s->status = FINISH_STATE;
+ }
+ if (bstate == need_more || bstate == finish_started) {
+ if (strm->avail_out == 0) {
+ s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
+ }
+ return Z_OK;
+ /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
+ * of deflate should use the same flush parameter to make sure
+ * that the flush is complete. So we don't have to output an
+ * empty block here, this will be done at next call. This also
+ * ensures that for a very small output buffer, we emit at most
+ * one empty block.
+ */
+ }
+ if (bstate == block_done) {
+ if (flush == Z_PARTIAL_FLUSH) {
+ _tr_align(s);
+ } else { /* FULL_FLUSH or SYNC_FLUSH */
+ _tr_stored_block(s, (char*)0, 0L, 0);
+ /* For a full flush, this empty block will be recognized
+ * as a special marker by inflate_sync().
+ */
+ if (flush == Z_FULL_FLUSH) {
+ CLEAR_HASH(s); /* forget history */
+ }
+ }
+ flush_pending(strm);
+ if (strm->avail_out == 0) {
+ s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
+ return Z_OK;
+ }
+ }
+ }
+ Assert(strm->avail_out > 0, "bug2");
+
+ if (flush != Z_FINISH) return Z_OK;
+ if (s->wrap <= 0) return Z_STREAM_END;
+
+ /* Write the trailer */
+#ifdef GZIP
+ if (s->wrap == 2) {
+ put_byte(s, (Byte)(strm->adler & 0xff));
+ put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
+ put_byte(s, (Byte)((strm->adler >> 16) & 0xff));
+ put_byte(s, (Byte)((strm->adler >> 24) & 0xff));
+ put_byte(s, (Byte)(strm->total_in & 0xff));
+ put_byte(s, (Byte)((strm->total_in >> 8) & 0xff));
+ put_byte(s, (Byte)((strm->total_in >> 16) & 0xff));
+ put_byte(s, (Byte)((strm->total_in >> 24) & 0xff));
+ }
+ else
+#endif
+ {
+ putShortMSB(s, (uInt)(strm->adler >> 16));
+ putShortMSB(s, (uInt)(strm->adler & 0xffff));
+ }
+ flush_pending(strm);
+ /* If avail_out is zero, the application will call deflate again
+ * to flush the rest.
+ */
+ if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */
+ return s->pending != 0 ? Z_OK : Z_STREAM_END;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateEnd (strm)
+ z_streamp strm;
+{
+ int status;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+
+ status = strm->state->status;
+ if (status != INIT_STATE &&
+ status != EXTRA_STATE &&
+ status != NAME_STATE &&
+ status != COMMENT_STATE &&
+ status != HCRC_STATE &&
+ status != BUSY_STATE &&
+ status != FINISH_STATE) {
+ return Z_STREAM_ERROR;
+ }
+
+ /* Deallocate in reverse order of allocations: */
+ TRY_FREE(strm, strm->state->pending_buf);
+ TRY_FREE(strm, strm->state->head);
+ TRY_FREE(strm, strm->state->prev);
+ TRY_FREE(strm, strm->state->window);
+
+ ZFREE(strm, strm->state);
+ strm->state = Z_NULL;
+
+ return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
+}
+
+/* =========================================================================
+ * Copy the source state to the destination state.
+ * To simplify the source, this is not supported for 16-bit MSDOS (which
+ * doesn't have enough memory anyway to duplicate compression states).
+ */
+int ZEXPORT deflateCopy (dest, source)
+ z_streamp dest;
+ z_streamp source;
+{
+#ifdef MAXSEG_64K
+ return Z_STREAM_ERROR;
+#else
+ deflate_state *ds;
+ deflate_state *ss;
+ ushf *overlay;
+
+
+ if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
+ return Z_STREAM_ERROR;
+ }
+
+ ss = source->state;
+
+ zmemcpy(dest, source, sizeof(z_stream));
+
+ ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
+ if (ds == Z_NULL) return Z_MEM_ERROR;
+ dest->state = (struct internal_state FAR *) ds;
+ zmemcpy(ds, ss, sizeof(deflate_state));
+ ds->strm = dest;
+
+ ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
+ ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
+ ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
+ overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
+ ds->pending_buf = (uchf *) overlay;
+
+ if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
+ ds->pending_buf == Z_NULL) {
+ deflateEnd (dest);
+ return Z_MEM_ERROR;
+ }
+ /* following zmemcpy do not work for 16-bit MSDOS */
+ zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
+ zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
+ zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
+ zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
+
+ ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
+ ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
+ ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
+
+ ds->l_desc.dyn_tree = ds->dyn_ltree;
+ ds->d_desc.dyn_tree = ds->dyn_dtree;
+ ds->bl_desc.dyn_tree = ds->bl_tree;
+
+ return Z_OK;
+#endif /* MAXSEG_64K */
+}
+
+/* ===========================================================================
+ * Read a new buffer from the current input stream, update the adler32
+ * and total number of bytes read. All deflate() input goes through
+ * this function so some applications may wish to modify it to avoid
+ * allocating a large strm->next_in buffer and copying from it.
+ * (See also flush_pending()).
+ */
+local int read_buf(strm, buf, size)
+ z_streamp strm;
+ Bytef *buf;
+ unsigned size;
+{
+ unsigned len = strm->avail_in;
+
+ if (len > size) len = size;
+ if (len == 0) return 0;
+
+ strm->avail_in -= len;
+
+ if (strm->state->wrap == 1) {
+ strm->adler = adler32(strm->adler, strm->next_in, len);
+ }
+#ifdef GZIP
+ else if (strm->state->wrap == 2) {
+ strm->adler = crc32(strm->adler, strm->next_in, len);
+ }
+#endif
+ zmemcpy(buf, strm->next_in, len);
+ strm->next_in += len;
+ strm->total_in += len;
+
+ return (int)len;
+}
+
+/* ===========================================================================
+ * Initialize the "longest match" routines for a new zlib stream
+ */
+local void lm_init (s)
+ deflate_state *s;
+{
+ s->window_size = (ulg)2L*s->w_size;
+
+ CLEAR_HASH(s);
+
+ /* Set the default configuration parameters:
+ */
+ s->max_lazy_match = configuration_table[s->level].max_lazy;
+ s->good_match = configuration_table[s->level].good_length;
+ s->nice_match = configuration_table[s->level].nice_length;
+ s->max_chain_length = configuration_table[s->level].max_chain;
+
+ s->strstart = 0;
+ s->block_start = 0L;
+ s->lookahead = 0;
+ s->match_length = s->prev_length = MIN_MATCH-1;
+ s->match_available = 0;
+ s->ins_h = 0;
+#ifndef FASTEST
+#ifdef ASMV
+ match_init(); /* initialize the asm code */
+#endif
+#endif
+}
+
+#ifndef FASTEST
+/* ===========================================================================
+ * Set match_start to the longest match starting at the given string and
+ * return its length. Matches shorter or equal to prev_length are discarded,
+ * in which case the result is equal to prev_length and match_start is
+ * garbage.
+ * IN assertions: cur_match is the head of the hash chain for the current
+ * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
+ * OUT assertion: the match length is not greater than s->lookahead.
+ */
+#ifndef ASMV
+/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
+ * match.S. The code will be functionally equivalent.
+ */
+local uInt longest_match(s, cur_match)
+ deflate_state *s;
+ IPos cur_match; /* current match */
+{
+ unsigned chain_length = s->max_chain_length;/* max hash chain length */
+ register Bytef *scan = s->window + s->strstart; /* current string */
+ register Bytef *match; /* matched string */
+ register int len; /* length of current match */
+ int best_len = s->prev_length; /* best match length so far */
+ int nice_match = s->nice_match; /* stop if match long enough */
+ IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
+ s->strstart - (IPos)MAX_DIST(s) : NIL;
+ /* Stop when cur_match becomes <= limit. To simplify the code,
+ * we prevent matches with the string of window index 0.
+ */
+ Posf *prev = s->prev;
+ uInt wmask = s->w_mask;
+
+#ifdef UNALIGNED_OK
+ /* Compare two bytes at a time. Note: this is not always beneficial.
+ * Try with and without -DUNALIGNED_OK to check.
+ */
+ register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
+ register ush scan_start = *(ushf*)scan;
+ register ush scan_end = *(ushf*)(scan+best_len-1);
+#else
+ register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+ register Byte scan_end1 = scan[best_len-1];
+ register Byte scan_end = scan[best_len];
+#endif
+
+ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+ * It is easy to get rid of this optimization if necessary.
+ */
+ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+ /* Do not waste too much time if we already have a good match: */
+ if (s->prev_length >= s->good_match) {
+ chain_length >>= 2;
+ }
+ /* Do not look for matches beyond the end of the input. This is necessary
+ * to make deflate deterministic.
+ */
+ if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
+
+ Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+ do {
+ Assert(cur_match < s->strstart, "no future");
+ match = s->window + cur_match;
+
+ /* Skip to next match if the match length cannot increase
+ * or if the match length is less than 2. Note that the checks below
+ * for insufficient lookahead only occur occasionally for performance
+ * reasons. Therefore uninitialized memory will be accessed, and
+ * conditional jumps will be made that depend on those values.
+ * However the length of the match is limited to the lookahead, so
+ * the output of deflate is not affected by the uninitialized values.
+ */
+#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
+ /* This code assumes sizeof(unsigned short) == 2. Do not use
+ * UNALIGNED_OK if your compiler uses a different size.
+ */
+ if (*(ushf*)(match+best_len-1) != scan_end ||
+ *(ushf*)match != scan_start) continue;
+
+ /* It is not necessary to compare scan[2] and match[2] since they are
+ * always equal when the other bytes match, given that the hash keys
+ * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
+ * strstart+3, +5, ... up to strstart+257. We check for insufficient
+ * lookahead only every 4th comparison; the 128th check will be made
+ * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
+ * necessary to put more guard bytes at the end of the window, or
+ * to check more often for insufficient lookahead.
+ */
+ Assert(scan[2] == match[2], "scan[2]?");
+ scan++, match++;
+ do {
+ } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ scan < strend);
+ /* The funny "do {}" generates better code on most compilers */
+
+ /* Here, scan <= window+strstart+257 */
+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+ if (*scan == *match) scan++;
+
+ len = (MAX_MATCH - 1) - (int)(strend-scan);
+ scan = strend - (MAX_MATCH-1);
+
+#else /* UNALIGNED_OK */
+
+ if (match[best_len] != scan_end ||
+ match[best_len-1] != scan_end1 ||
+ *match != *scan ||
+ *++match != scan[1]) continue;
+
+ /* The check at best_len-1 can be removed because it will be made
+ * again later. (This heuristic is not always a win.)
+ * It is not necessary to compare scan[2] and match[2] since they
+ * are always equal when the other bytes match, given that
+ * the hash keys are equal and that HASH_BITS >= 8.
+ */
+ scan += 2, match++;
+ Assert(*scan == *match, "match[2]?");
+
+ /* We check for insufficient lookahead only every 8th comparison;
+ * the 256th check will be made at strstart+258.
+ */
+ do {
+ } while (*++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ scan < strend);
+
+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+ len = MAX_MATCH - (int)(strend - scan);
+ scan = strend - MAX_MATCH;
+
+#endif /* UNALIGNED_OK */
+
+ if (len > best_len) {
+ s->match_start = cur_match;
+ best_len = len;
+ if (len >= nice_match) break;
+#ifdef UNALIGNED_OK
+ scan_end = *(ushf*)(scan+best_len-1);
+#else
+ scan_end1 = scan[best_len-1];
+ scan_end = scan[best_len];
+#endif
+ }
+ } while ((cur_match = prev[cur_match & wmask]) > limit
+ && --chain_length != 0);
+
+ if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
+ return s->lookahead;
+}
+#endif /* ASMV */
+#endif /* FASTEST */
+
+/* ---------------------------------------------------------------------------
+ * Optimized version for level == 1 or strategy == Z_RLE only
+ */
+local uInt longest_match_fast(s, cur_match)
+ deflate_state *s;
+ IPos cur_match; /* current match */
+{
+ register Bytef *scan = s->window + s->strstart; /* current string */
+ register Bytef *match; /* matched string */
+ register int len; /* length of current match */
+ register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+
+ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+ * It is easy to get rid of this optimization if necessary.
+ */
+ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+ Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+ Assert(cur_match < s->strstart, "no future");
+
+ match = s->window + cur_match;
+
+ /* Return failure if the match length is less than 2:
+ */
+ if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
+
+ /* The check at best_len-1 can be removed because it will be made
+ * again later. (This heuristic is not always a win.)
+ * It is not necessary to compare scan[2] and match[2] since they
+ * are always equal when the other bytes match, given that
+ * the hash keys are equal and that HASH_BITS >= 8.
+ */
+ scan += 2, match += 2;
+ Assert(*scan == *match, "match[2]?");
+
+ /* We check for insufficient lookahead only every 8th comparison;
+ * the 256th check will be made at strstart+258.
+ */
+ do {
+ } while (*++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ scan < strend);
+
+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+ len = MAX_MATCH - (int)(strend - scan);
+
+ if (len < MIN_MATCH) return MIN_MATCH - 1;
+
+ s->match_start = cur_match;
+ return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead;
+}
+
+#ifdef DEBUG
+/* ===========================================================================
+ * Check that the match at match_start is indeed a match.
+ */
+local void check_match(s, start, match, length)
+ deflate_state *s;
+ IPos start, match;
+ int length;
+{
+ /* check that the match is indeed a match */
+ if (zmemcmp(s->window + match,
+ s->window + start, length) != EQUAL) {
+ fprintf(stderr, " start %u, match %u, length %d\n",
+ start, match, length);
+ do {
+ fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
+ } while (--length != 0);
+ z_error("invalid match");
+ }
+ if (z_verbose > 1) {
+ fprintf(stderr,"\\[%d,%d]", start-match, length);
+ do { putc(s->window[start++], stderr); } while (--length != 0);
+ }
+}
+#else
+# define check_match(s, start, match, length)
+#endif /* DEBUG */
+
+/* ===========================================================================
+ * Fill the window when the lookahead becomes insufficient.
+ * Updates strstart and lookahead.
+ *
+ * IN assertion: lookahead < MIN_LOOKAHEAD
+ * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
+ * At least one byte has been read, or avail_in == 0; reads are
+ * performed for at least two bytes (required for the zip translate_eol
+ * option -- not supported here).
+ */
+local void fill_window(s)
+ deflate_state *s;
+{
+ register unsigned n, m;
+ register Posf *p;
+ unsigned more; /* Amount of free space at the end of the window. */
+ uInt wsize = s->w_size;
+
+ do {
+ more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
+
+ /* Deal with !@#$% 64K limit: */
+ if (sizeof(int) <= 2) {
+ if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
+ more = wsize;
+
+ } else if (more == (unsigned)(-1)) {
+ /* Very unlikely, but possible on 16 bit machine if
+ * strstart == 0 && lookahead == 1 (input done a byte at time)
+ */
+ more--;
+ }
+ }
+
+ /* If the window is almost full and there is insufficient lookahead,
+ * move the upper half to the lower one to make room in the upper half.
+ */
+ if (s->strstart >= wsize+MAX_DIST(s)) {
+
+ zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
+ s->match_start -= wsize;
+ s->strstart -= wsize; /* we now have strstart >= MAX_DIST */
+ s->block_start -= (long) wsize;
+
+ /* Slide the hash table (could be avoided with 32 bit values
+ at the expense of memory usage). We slide even when level == 0
+ to keep the hash table consistent if we switch back to level > 0
+ later. (Using level 0 permanently is not an optimal usage of
+ zlib, so we don't care about this pathological case.)
+ */
+ /* %%% avoid this when Z_RLE */
+ n = s->hash_size;
+ p = &s->head[n];
+ do {
+ m = *--p;
+ *p = (Pos)(m >= wsize ? m-wsize : NIL);
+ } while (--n);
+
+ n = wsize;
+#ifndef FASTEST
+ p = &s->prev[n];
+ do {
+ m = *--p;
+ *p = (Pos)(m >= wsize ? m-wsize : NIL);
+ /* If n is not on any hash chain, prev[n] is garbage but
+ * its value will never be used.
+ */
+ } while (--n);
+#endif
+ more += wsize;
+ }
+ if (s->strm->avail_in == 0) return;
+
+ /* If there was no sliding:
+ * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
+ * more == window_size - lookahead - strstart
+ * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
+ * => more >= window_size - 2*WSIZE + 2
+ * In the BIG_MEM or MMAP case (not yet supported),
+ * window_size == input_size + MIN_LOOKAHEAD &&
+ * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
+ * Otherwise, window_size == 2*WSIZE so more >= 2.
+ * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
+ */
+ Assert(more >= 2, "more < 2");
+
+ n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
+ s->lookahead += n;
+
+ /* Initialize the hash value now that we have some input: */
+ if (s->lookahead >= MIN_MATCH) {
+ s->ins_h = s->window[s->strstart];
+ UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+#if MIN_MATCH != 3
+ Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+ }
+ /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
+ * but this is not important since only literal bytes will be emitted.
+ */
+
+ } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
+}
+
+/* ===========================================================================
+ * Flush the current block, with given end-of-file flag.
+ * IN assertion: strstart is set to the end of the current match.
+ */
+#define FLUSH_BLOCK_ONLY(s, eof) { \
+ _tr_flush_block(s, (s->block_start >= 0L ? \
+ (charf *)&s->window[(unsigned)s->block_start] : \
+ (charf *)Z_NULL), \
+ (ulg)((long)s->strstart - s->block_start), \
+ (eof)); \
+ s->block_start = s->strstart; \
+ flush_pending(s->strm); \
+ Tracev((stderr,"[FLUSH]")); \
+}
+
+/* Same but force premature exit if necessary. */
+#define FLUSH_BLOCK(s, eof) { \
+ FLUSH_BLOCK_ONLY(s, eof); \
+ if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
+}
+
+/* ===========================================================================
+ * Copy without compression as much as possible from the input stream, return
+ * the current block state.
+ * This function does not insert new strings in the dictionary since
+ * uncompressible data is probably not useful. This function is used
+ * only for the level=0 compression option.
+ * NOTE: this function should be optimized to avoid extra copying from
+ * window to pending_buf.
+ */
+local block_state deflate_stored(s, flush)
+ deflate_state *s;
+ int flush;
+{
+ /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
+ * to pending_buf_size, and each stored block has a 5 byte header:
+ */
+ ulg max_block_size = 0xffff;
+ ulg max_start;
+
+ if (max_block_size > s->pending_buf_size - 5) {
+ max_block_size = s->pending_buf_size - 5;
+ }
+
+ /* Copy as much as possible from input to output: */
+ for (;;) {
+ /* Fill the window as much as possible: */
+ if (s->lookahead <= 1) {
+
+ Assert(s->strstart < s->w_size+MAX_DIST(s) ||
+ s->block_start >= (long)s->w_size, "slide too late");
+
+ fill_window(s);
+ if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
+
+ if (s->lookahead == 0) break; /* flush the current block */
+ }
+ Assert(s->block_start >= 0L, "block gone");
+
+ s->strstart += s->lookahead;
+ s->lookahead = 0;
+
+ /* Emit a stored block if pending_buf will be full: */
+ max_start = s->block_start + max_block_size;
+ if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
+ /* strstart == 0 is possible when wraparound on 16-bit machine */
+ s->lookahead = (uInt)(s->strstart - max_start);
+ s->strstart = (uInt)max_start;
+ FLUSH_BLOCK(s, 0);
+ }
+ /* Flush if we may have to slide, otherwise block_start may become
+ * negative and the data will be gone:
+ */
+ if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
+ FLUSH_BLOCK(s, 0);
+ }
+ }
+ FLUSH_BLOCK(s, flush == Z_FINISH);
+ return flush == Z_FINISH ? finish_done : block_done;
+}
+
+/* ===========================================================================
+ * Compress as much as possible from the input stream, return the current
+ * block state.
+ * This function does not perform lazy evaluation of matches and inserts
+ * new strings in the dictionary only for unmatched strings or for short
+ * matches. It is used only for the fast compression options.
+ */
+local block_state deflate_fast(s, flush)
+ deflate_state *s;
+ int flush;
+{
+ IPos hash_head = NIL; /* head of the hash chain */
+ int bflush; /* set if current block must be flushed */
+
+ for (;;) {
+ /* Make sure that we always have enough lookahead, except
+ * at the end of the input file. We need MAX_MATCH bytes
+ * for the next match, plus MIN_MATCH bytes to insert the
+ * string following the next match.
+ */
+ if (s->lookahead < MIN_LOOKAHEAD) {
+ fill_window(s);
+ if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+ return need_more;
+ }
+ if (s->lookahead == 0) break; /* flush the current block */
+ }
+
+ /* Insert the string window[strstart .. strstart+2] in the
+ * dictionary, and set hash_head to the head of the hash chain:
+ */
+ if (s->lookahead >= MIN_MATCH) {
+ INSERT_STRING(s, s->strstart, hash_head);
+ }
+
+ /* Find the longest match, discarding those <= prev_length.
+ * At this point we have always match_length < MIN_MATCH
+ */
+ if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
+ /* To simplify the code, we prevent matches with the string
+ * of window index 0 (in particular we have to avoid a match
+ * of the string with itself at the start of the input file).
+ */
+#ifdef FASTEST
+ if ((s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) ||
+ (s->strategy == Z_RLE && s->strstart - hash_head == 1)) {
+ s->match_length = longest_match_fast (s, hash_head);
+ }
+#else
+ if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
+ s->match_length = longest_match (s, hash_head);
+ } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
+ s->match_length = longest_match_fast (s, hash_head);
+ }
+#endif
+ /* longest_match() or longest_match_fast() sets match_start */
+ }
+ if (s->match_length >= MIN_MATCH) {
+ check_match(s, s->strstart, s->match_start, s->match_length);
+
+ _tr_tally_dist(s, s->strstart - s->match_start,
+ s->match_length - MIN_MATCH, bflush);
+
+ s->lookahead -= s->match_length;
+
+ /* Insert new strings in the hash table only if the match length
+ * is not too large. This saves time but degrades compression.
+ */
+#ifndef FASTEST
+ if (s->match_length <= s->max_insert_length &&
+ s->lookahead >= MIN_MATCH) {
+ s->match_length--; /* string at strstart already in table */
+ do {
+ s->strstart++;
+ INSERT_STRING(s, s->strstart, hash_head);
+ /* strstart never exceeds WSIZE-MAX_MATCH, so there are
+ * always MIN_MATCH bytes ahead.
+ */
+ } while (--s->match_length != 0);
+ s->strstart++;
+ } else
+#endif
+ {
+ s->strstart += s->match_length;
+ s->match_length = 0;
+ s->ins_h = s->window[s->strstart];
+ UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+#if MIN_MATCH != 3
+ Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+ /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
+ * matter since it will be recomputed at next deflate call.
+ */
+ }
+ } else {
+ /* No match, output a literal byte */
+ Tracevv((stderr,"%c", s->window[s->strstart]));
+ _tr_tally_lit (s, s->window[s->strstart], bflush);
+ s->lookahead--;
+ s->strstart++;
+ }
+ if (bflush) FLUSH_BLOCK(s, 0);
+ }
+ FLUSH_BLOCK(s, flush == Z_FINISH);
+ return flush == Z_FINISH ? finish_done : block_done;
+}
+
+#ifndef FASTEST
+/* ===========================================================================
+ * Same as above, but achieves better compression. We use a lazy
+ * evaluation for matches: a match is finally adopted only if there is
+ * no better match at the next window position.
+ */
+local block_state deflate_slow(s, flush)
+ deflate_state *s;
+ int flush;
+{
+ IPos hash_head = NIL; /* head of hash chain */
+ int bflush; /* set if current block must be flushed */
+
+ /* Process the input block. */
+ for (;;) {
+ /* Make sure that we always have enough lookahead, except
+ * at the end of the input file. We need MAX_MATCH bytes
+ * for the next match, plus MIN_MATCH bytes to insert the
+ * string following the next match.
+ */
+ if (s->lookahead < MIN_LOOKAHEAD) {
+ fill_window(s);
+ if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+ return need_more;
+ }
+ if (s->lookahead == 0) break; /* flush the current block */
+ }
+
+ /* Insert the string window[strstart .. strstart+2] in the
+ * dictionary, and set hash_head to the head of the hash chain:
+ */
+ if (s->lookahead >= MIN_MATCH) {
+ INSERT_STRING(s, s->strstart, hash_head);
+ }
+
+ /* Find the longest match, discarding those <= prev_length.
+ */
+ s->prev_length = s->match_length, s->prev_match = s->match_start;
+ s->match_length = MIN_MATCH-1;
+
+ if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
+ s->strstart - hash_head <= MAX_DIST(s)) {
+ /* To simplify the code, we prevent matches with the string
+ * of window index 0 (in particular we have to avoid a match
+ * of the string with itself at the start of the input file).
+ */
+ if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
+ s->match_length = longest_match (s, hash_head);
+ } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
+ s->match_length = longest_match_fast (s, hash_head);
+ }
+ /* longest_match() or longest_match_fast() sets match_start */
+
+ if (s->match_length <= 5 && (s->strategy == Z_FILTERED
+#if TOO_FAR <= 32767
+ || (s->match_length == MIN_MATCH &&
+ s->strstart - s->match_start > TOO_FAR)
+#endif
+ )) {
+
+ /* If prev_match is also MIN_MATCH, match_start is garbage
+ * but we will ignore the current match anyway.
+ */
+ s->match_length = MIN_MATCH-1;
+ }
+ }
+ /* If there was a match at the previous step and the current
+ * match is not better, output the previous match:
+ */
+ if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
+ uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
+ /* Do not insert strings in hash table beyond this. */
+
+ check_match(s, s->strstart-1, s->prev_match, s->prev_length);
+
+ _tr_tally_dist(s, s->strstart -1 - s->prev_match,
+ s->prev_length - MIN_MATCH, bflush);
+
+ /* Insert in hash table all strings up to the end of the match.
+ * strstart-1 and strstart are already inserted. If there is not
+ * enough lookahead, the last two strings are not inserted in
+ * the hash table.
+ */
+ s->lookahead -= s->prev_length-1;
+ s->prev_length -= 2;
+ do {
+ if (++s->strstart <= max_insert) {
+ INSERT_STRING(s, s->strstart, hash_head);
+ }
+ } while (--s->prev_length != 0);
+ s->match_available = 0;
+ s->match_length = MIN_MATCH-1;
+ s->strstart++;
+
+ if (bflush) FLUSH_BLOCK(s, 0);
+
+ } else if (s->match_available) {
+ /* If there was no match at the previous position, output a
+ * single literal. If there was a match but the current match
+ * is longer, truncate the previous match to a single literal.
+ */
+ Tracevv((stderr,"%c", s->window[s->strstart-1]));
+ _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+ if (bflush) {
+ FLUSH_BLOCK_ONLY(s, 0);
+ }
+ s->strstart++;
+ s->lookahead--;
+ if (s->strm->avail_out == 0) return need_more;
+ } else {
+ /* There is no previous match to compare with, wait for
+ * the next step to decide.
+ */
+ s->match_available = 1;
+ s->strstart++;
+ s->lookahead--;
+ }
+ }
+ Assert (flush != Z_NO_FLUSH, "no flush?");
+ if (s->match_available) {
+ Tracevv((stderr,"%c", s->window[s->strstart-1]));
+ _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+ s->match_available = 0;
+ }
+ FLUSH_BLOCK(s, flush == Z_FINISH);
+ return flush == Z_FINISH ? finish_done : block_done;
+}
+#endif /* FASTEST */
+
+#if 0
+/* ===========================================================================
+ * For Z_RLE, simply look for runs of bytes, generate matches only of distance
+ * one. Do not maintain a hash table. (It will be regenerated if this run of
+ * deflate switches away from Z_RLE.)
+ */
+local block_state deflate_rle(s, flush)
+ deflate_state *s;
+ int flush;
+{
+ int bflush; /* set if current block must be flushed */
+ uInt run; /* length of run */
+ uInt max; /* maximum length of run */
+ uInt prev; /* byte at distance one to match */
+ Bytef *scan; /* scan for end of run */
+
+ for (;;) {
+ /* Make sure that we always have enough lookahead, except
+ * at the end of the input file. We need MAX_MATCH bytes
+ * for the longest encodable run.
+ */
+ if (s->lookahead < MAX_MATCH) {
+ fill_window(s);
+ if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) {
+ return need_more;
+ }
+ if (s->lookahead == 0) break; /* flush the current block */
+ }
+
+ /* See how many times the previous byte repeats */
+ run = 0;
+ if (s->strstart > 0) { /* if there is a previous byte, that is */
+ max = s->lookahead < MAX_MATCH ? s->lookahead : MAX_MATCH;
+ scan = s->window + s->strstart - 1;
+ prev = *scan++;
+ do {
+ if (*scan++ != prev)
+ break;
+ } while (++run < max);
+ }
+
+ /* Emit match if have run of MIN_MATCH or longer, else emit literal */
+ if (run >= MIN_MATCH) {
+ check_match(s, s->strstart, s->strstart - 1, run);
+ _tr_tally_dist(s, 1, run - MIN_MATCH, bflush);
+ s->lookahead -= run;
+ s->strstart += run;
+ } else {
+ /* No match, output a literal byte */
+ Tracevv((stderr,"%c", s->window[s->strstart]));
+ _tr_tally_lit (s, s->window[s->strstart], bflush);
+ s->lookahead--;
+ s->strstart++;
+ }
+ if (bflush) FLUSH_BLOCK(s, 0);
+ }
+ FLUSH_BLOCK(s, flush == Z_FINISH);
+ return flush == Z_FINISH ? finish_done : block_done;
+}
+#endif
diff --git a/Utilities/cmzlib/deflate.h b/Utilities/cmzlib/deflate.h
new file mode 100644
index 000000000..05a5ab3a2
--- /dev/null
+++ b/Utilities/cmzlib/deflate.h
@@ -0,0 +1,331 @@
+/* deflate.h -- internal compression state
+ * Copyright (C) 1995-2004 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id$ */
+
+#ifndef DEFLATE_H
+#define DEFLATE_H
+
+#include "zutil.h"
+
+/* define NO_GZIP when compiling if you want to disable gzip header and
+ trailer creation by deflate(). NO_GZIP would be used to avoid linking in
+ the crc code when it is not needed. For shared libraries, gzip encoding
+ should be left enabled. */
+#ifndef NO_GZIP
+# define GZIP
+#endif
+
+/* ===========================================================================
+ * Internal compression state.
+ */
+
+#define LENGTH_CODES 29
+/* number of length codes, not counting the special END_BLOCK code */
+
+#define LITERALS 256
+/* number of literal bytes 0..255 */
+
+#define L_CODES (LITERALS+1+LENGTH_CODES)
+/* number of Literal or Length codes, including the END_BLOCK code */
+
+#define D_CODES 30
+/* number of distance codes */
+
+#define BL_CODES 19
+/* number of codes used to transfer the bit lengths */
+
+#define HEAP_SIZE (2*L_CODES+1)
+/* maximum heap size */
+
+#define MAX_BITS 15
+/* All codes must not exceed MAX_BITS bits */
+
+#define INIT_STATE 42
+#define EXTRA_STATE 69
+#define NAME_STATE 73
+#define COMMENT_STATE 91
+#define HCRC_STATE 103
+#define BUSY_STATE 113
+#define FINISH_STATE 666
+/* Stream status */
+
+
+/* Data structure describing a single value and its code string. */
+typedef struct ct_data_s {
+ union {
+ ush freq; /* frequency count */
+ ush code; /* bit string */
+ } fc;
+ union {
+ ush dad; /* father node in Huffman tree */
+ ush len; /* length of bit string */
+ } dl;
+} FAR ct_data;
+
+#define Freq fc.freq
+#define Code fc.code
+#define Dad dl.dad
+#define Len dl.len
+
+typedef struct static_tree_desc_s static_tree_desc;
+
+typedef struct tree_desc_s {
+ ct_data *dyn_tree; /* the dynamic tree */
+ int max_code; /* largest code with non zero frequency */
+ static_tree_desc *stat_desc; /* the corresponding static tree */
+} FAR tree_desc;
+
+typedef ush Pos;
+typedef Pos FAR Posf;
+typedef unsigned IPos;
+
+/* A Pos is an index in the character window. We use short instead of int to
+ * save space in the various tables. IPos is used only for parameter passing.
+ */
+
+typedef struct internal_state {
+ z_streamp strm; /* pointer back to this zlib stream */
+ int status; /* as the name implies */
+ Bytef *pending_buf; /* output still pending */
+ ulg pending_buf_size; /* size of pending_buf */
+ Bytef *pending_out; /* next pending byte to output to the stream */
+ uInt pending; /* nb of bytes in the pending buffer */
+ int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
+ gz_headerp gzhead; /* gzip header information to write */
+ uInt gzindex; /* where in extra, name, or comment */
+ Byte method; /* STORED (for zip only) or DEFLATED */
+ int last_flush; /* value of flush param for previous deflate call */
+
+ /* used by deflate.c: */
+
+ uInt w_size; /* LZ77 window size (32K by default) */
+ uInt w_bits; /* log2(w_size) (8..16) */
+ uInt w_mask; /* w_size - 1 */
+
+ Bytef *window;
+ /* Sliding window. Input bytes are read into the second half of the window,
+ * and move to the first half later to keep a dictionary of at least wSize
+ * bytes. With this organization, matches are limited to a distance of
+ * wSize-MAX_MATCH bytes, but this ensures that IO is always
+ * performed with a length multiple of the block size. Also, it limits
+ * the window size to 64K, which is quite useful on MSDOS.
+ * To do: use the user input buffer as sliding window.
+ */
+
+ ulg window_size;
+ /* Actual size of window: 2*wSize, except when the user input buffer
+ * is directly used as sliding window.
+ */
+
+ Posf *prev;
+ /* Link to older string with same hash index. To limit the size of this
+ * array to 64K, this link is maintained only for the last 32K strings.
+ * An index in this array is thus a window index modulo 32K.
+ */
+
+ Posf *head; /* Heads of the hash chains or NIL. */
+
+ uInt ins_h; /* hash index of string to be inserted */
+ uInt hash_size; /* number of elements in hash table */
+ uInt hash_bits; /* log2(hash_size) */
+ uInt hash_mask; /* hash_size-1 */
+
+ uInt hash_shift;
+ /* Number of bits by which ins_h must be shifted at each input
+ * step. It must be such that after MIN_MATCH steps, the oldest
+ * byte no longer takes part in the hash key, that is:
+ * hash_shift * MIN_MATCH >= hash_bits
+ */
+
+ long block_start;
+ /* Window position at the beginning of the current output block. Gets
+ * negative when the window is moved backwards.
+ */
+
+ uInt match_length; /* length of best match */
+ IPos prev_match; /* previous match */
+ int match_available; /* set if previous match exists */
+ uInt strstart; /* start of string to insert */
+ uInt match_start; /* start of matching string */
+ uInt lookahead; /* number of valid bytes ahead in window */
+
+ uInt prev_length;
+ /* Length of the best match at previous step. Matches not greater than this
+ * are discarded. This is used in the lazy match evaluation.
+ */
+
+ uInt max_chain_length;
+ /* To speed up deflation, hash chains are never searched beyond this
+ * length. A higher limit improves compression ratio but degrades the
+ * speed.
+ */
+
+ uInt max_lazy_match;
+ /* Attempt to find a better match only when the current match is strictly
+ * smaller than this value. This mechanism is used only for compression
+ * levels >= 4.
+ */
+# define max_insert_length max_lazy_match
+ /* Insert new strings in the hash table only if the match length is not
+ * greater than this length. This saves time but degrades compression.
+ * max_insert_length is used only for compression levels <= 3.
+ */
+
+ int level; /* compression level (1..9) */
+ int strategy; /* favor or force Huffman coding*/
+
+ uInt good_match;
+ /* Use a faster search when the previous match is longer than this */
+
+ int nice_match; /* Stop searching when current match exceeds this */
+
+ /* used by trees.c: */
+ /* Didn't use ct_data typedef below to supress compiler warning */
+ struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
+ struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
+ struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
+
+ struct tree_desc_s l_desc; /* desc. for literal tree */
+ struct tree_desc_s d_desc; /* desc. for distance tree */
+ struct tree_desc_s bl_desc; /* desc. for bit length tree */
+
+ ush bl_count[MAX_BITS+1];
+ /* number of codes at each bit length for an optimal tree */
+
+ int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
+ int heap_len; /* number of elements in the heap */
+ int heap_max; /* element of largest frequency */
+ /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
+ * The same heap array is used to build all trees.
+ */
+
+ uch depth[2*L_CODES+1];
+ /* Depth of each subtree used as tie breaker for trees of equal frequency
+ */
+
+ uchf *l_buf; /* buffer for literals or lengths */
+
+ uInt lit_bufsize;
+ /* Size of match buffer for literals/lengths. There are 4 reasons for
+ * limiting lit_bufsize to 64K:
+ * - frequencies can be kept in 16 bit counters
+ * - if compression is not successful for the first block, all input
+ * data is still in the window so we can still emit a stored block even
+ * when input comes from standard input. (This can also be done for
+ * all blocks if lit_bufsize is not greater than 32K.)
+ * - if compression is not successful for a file smaller than 64K, we can
+ * even emit a stored file instead of a stored block (saving 5 bytes).
+ * This is applicable only for zip (not gzip or zlib).
+ * - creating new Huffman trees less frequently may not provide fast
+ * adaptation to changes in the input data statistics. (Take for
+ * example a binary file with poorly compressible code followed by
+ * a highly compressible string table.) Smaller buffer sizes give
+ * fast adaptation but have of course the overhead of transmitting
+ * trees more frequently.
+ * - I can't count above 4
+ */
+
+ uInt last_lit; /* running index in l_buf */
+
+ ushf *d_buf;
+ /* Buffer for distances. To simplify the code, d_buf and l_buf have
+ * the same number of elements. To use different lengths, an extra flag
+ * array would be necessary.
+ */
+
+ ulg opt_len; /* bit length of current block with optimal trees */
+ ulg static_len; /* bit length of current block with static trees */
+ uInt matches; /* number of string matches in current block */
+ int last_eob_len; /* bit length of EOB code for last block */
+
+#ifdef DEBUG
+ ulg compressed_len; /* total bit length of compressed file mod 2^32 */
+ ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
+#endif
+
+ ush bi_buf;
+ /* Output buffer. bits are inserted starting at the bottom (least
+ * significant bits).
+ */
+ int bi_valid;
+ /* Number of valid bits in bi_buf. All bits above the last valid bit
+ * are always zero.
+ */
+
+} FAR deflate_state;
+
+/* Output a byte on the stream.
+ * IN assertion: there is enough room in pending_buf.
+ */
+#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
+
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
+/* In order to simplify the code, particularly on 16 bit machines, match
+ * distances are limited to MAX_DIST instead of WSIZE.
+ */
+
+ /* in trees.c */
+void _tr_init OF((deflate_state *s));
+int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
+void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
+ int eof));
+void _tr_align OF((deflate_state *s));
+void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
+ int eof));
+
+#define d_code(dist) \
+ ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
+/* Mapping from a distance to a distance code. dist is the distance - 1 and
+ * must not have side effects. _dist_code[256] and _dist_code[257] are never
+ * used.
+ */
+
+#ifndef DEBUG
+/* Inline versions of _tr_tally for speed: */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+ extern uch _length_code[];
+ extern uch _dist_code[];
+#else
+ extern const uch _length_code[];
+ extern const uch _dist_code[];
+#endif
+
+# define _tr_tally_lit(s, c, flush) \
+ { uch cc = (c); \
+ s->d_buf[s->last_lit] = 0; \
+ s->l_buf[s->last_lit++] = cc; \
+ s->dyn_ltree[cc].Freq++; \
+ flush = (s->last_lit == s->lit_bufsize-1); \
+ }
+# define _tr_tally_dist(s, distance, length, flush) \
+ { uch len = (length); \
+ ush dist = (distance); \
+ s->d_buf[s->last_lit] = dist; \
+ s->l_buf[s->last_lit++] = len; \
+ dist--; \
+ s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
+ s->dyn_dtree[d_code(dist)].Freq++; \
+ flush = (s->last_lit == s->lit_bufsize-1); \
+ }
+#else
+# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
+# define _tr_tally_dist(s, distance, length, flush) \
+ flush = _tr_tally(s, distance, length)
+#endif
+
+#endif /* DEFLATE_H */
diff --git a/Utilities/cmzlib/gzio.c b/Utilities/cmzlib/gzio.c
new file mode 100644
index 000000000..7e90f4928
--- /dev/null
+++ b/Utilities/cmzlib/gzio.c
@@ -0,0 +1,1026 @@
+/* gzio.c -- IO on .gz files
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Compile this file with -DNO_GZCOMPRESS to avoid the compression code.
+ */
+
+/* @(#) $Id$ */
+
+#include <stdio.h>
+
+#include "zutil.h"
+
+#ifdef NO_DEFLATE /* for compatibility with old definition */
+# define NO_GZCOMPRESS
+#endif
+
+#ifndef NO_DUMMY_DECL
+struct internal_state {int dummy;}; /* for buggy compilers */
+#endif
+
+#ifndef Z_BUFSIZE
+# ifdef MAXSEG_64K
+# define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */
+# else
+# define Z_BUFSIZE 16384
+# endif
+#endif
+#ifndef Z_PRINTF_BUFSIZE
+# define Z_PRINTF_BUFSIZE 4096
+#endif
+
+#ifdef __MVS__
+# pragma map (fdopen , "\174\174FDOPEN")
+ FILE *fdopen(int, const char *);
+#endif
+
+#ifndef STDC
+extern voidp malloc OF((uInt size));
+extern void free OF((voidpf ptr));
+#endif
+
+#define ALLOC(size) malloc(size)
+#define TRYFREE(p) {if (p) free(p);}
+
+static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
+
+/* 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 */
+
+typedef struct gz_stream {
+ z_stream stream;
+ int z_err; /* error code for last stream operation */
+ int z_eof; /* set if end of input file */
+ FILE *file; /* .gz file */
+ Byte *inbuf; /* input buffer */
+ Byte *outbuf; /* output buffer */
+ uLong crc; /* crc32 of uncompressed data */
+ char *msg; /* error message */
+ char *path; /* path name for debugging only */
+ int transparent; /* 1 if input file is not a .gz file */
+ char mode; /* 'w' or 'r' */
+ z_off_t start; /* start of compressed data in file (header skipped) */
+ z_off_t in; /* bytes into deflate or inflate */
+ z_off_t out; /* bytes out of deflate or inflate */
+ int back; /* one character push-back */
+ int last; /* true if push-back is last character */
+} gz_stream;
+
+
+local gzFile gz_open OF((const char *path, const char *mode, int fd));
+local int do_flush OF((gzFile file, int flush));
+local int get_byte OF((gz_stream *s));
+local void check_header OF((gz_stream *s));
+local int destroy OF((gz_stream *s));
+local void putLong OF((FILE *file, uLong x));
+local uLong getLong OF((gz_stream *s));
+
+/* ===========================================================================
+ Opens a gzip (.gz) file for reading or writing. The mode parameter
+ is as in fopen ("rb" or "wb"). The file is given either by file descriptor
+ or path name (if fd == -1).
+ gz_open returns NULL if the file could not be opened or if there was
+ insufficient memory to allocate the (de)compression state; errno
+ can be checked to distinguish the two cases (if errno is zero, the
+ zlib error is Z_MEM_ERROR).
+*/
+local gzFile gz_open (path, mode, fd)
+ const char *path;
+ const char *mode;
+ int fd;
+{
+ int err;
+ int level = Z_DEFAULT_COMPRESSION; /* compression level */
+ int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */
+ char *p = (char*)mode;
+ gz_stream *s;
+ char fmode[80]; /* copy of mode, without the compression level */
+ char *m = fmode;
+
+ if (!path || !mode) return Z_NULL;
+
+ s = (gz_stream *)ALLOC(sizeof(gz_stream));
+ if (!s) return Z_NULL;
+
+ s->stream.zalloc = (alloc_func)0;
+ s->stream.zfree = (free_func)0;
+ s->stream.opaque = (voidpf)0;
+ s->stream.next_in = s->inbuf = Z_NULL;
+ s->stream.next_out = s->outbuf = Z_NULL;
+ s->stream.avail_in = s->stream.avail_out = 0;
+ s->file = NULL;
+ s->z_err = Z_OK;
+ s->z_eof = 0;
+ s->in = 0;
+ s->out = 0;
+ s->back = EOF;
+ s->crc = crc32(0L, Z_NULL, 0);
+ s->msg = NULL;
+ s->transparent = 0;
+
+ s->path = (char*)ALLOC(strlen(path)+1);
+ if (s->path == NULL) {
+ return destroy(s), (gzFile)Z_NULL;
+ }
+ strcpy(s->path, path); /* do this early for debugging */
+
+ s->mode = '\0';
+ do {
+ if (*p == 'r') s->mode = 'r';
+ if (*p == 'w' || *p == 'a') s->mode = 'w';
+ if (*p >= '0' && *p <= '9') {
+ level = *p - '0';
+ } else if (*p == 'f') {
+ strategy = Z_FILTERED;
+ } else if (*p == 'h') {
+ strategy = Z_HUFFMAN_ONLY;
+ } else if (*p == 'R') {
+ strategy = Z_RLE;
+ } else {
+ *m++ = *p; /* copy the mode */
+ }
+ } while (*p++ && m != fmode + sizeof(fmode));
+ if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL;
+
+ if (s->mode == 'w') {
+#ifdef NO_GZCOMPRESS
+ err = Z_STREAM_ERROR;
+#else
+ err = deflateInit2(&(s->stream), level,
+ Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy);
+ /* windowBits is passed < 0 to suppress zlib header */
+
+ s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
+#endif
+ if (err != Z_OK || s->outbuf == Z_NULL) {
+ return destroy(s), (gzFile)Z_NULL;
+ }
+ } else {
+ s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE);
+
+ err = inflateInit2(&(s->stream), -MAX_WBITS);
+ /* windowBits is passed < 0 to tell that there is no zlib header.
+ * Note that in this case inflate *requires* an extra "dummy" byte
+ * after the compressed stream in order to complete decompression and
+ * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are
+ * present after the compressed stream.
+ */
+ if (err != Z_OK || s->inbuf == Z_NULL) {
+ return destroy(s), (gzFile)Z_NULL;
+ }
+ }
+ s->stream.avail_out = Z_BUFSIZE;
+
+ errno = 0;
+ s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode);
+
+ if (s->file == NULL) {
+ return destroy(s), (gzFile)Z_NULL;
+ }
+ if (s->mode == 'w') {
+ /* Write a very simple .gz header:
+ */
+ fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
+ Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
+ s->start = 10L;
+ /* We use 10L instead of ftell(s->file) to because ftell causes an
+ * fflush on some systems. This version of the library doesn't use
+ * start anyway in write mode, so this initialization is not
+ * necessary.
+ */
+ } else {
+ check_header(s); /* skip the .gz header */
+ s->start = ftell(s->file) - s->stream.avail_in;
+ }
+
+ return (gzFile)s;
+}
+
+/* ===========================================================================
+ Opens a gzip (.gz) file for reading or writing.
+*/
+gzFile ZEXPORT gzopen (path, mode)
+ const char *path;
+ const char *mode;
+{
+ return gz_open (path, mode, -1);
+}
+
+/* ===========================================================================
+ Associate a gzFile with the file descriptor fd. fd is not dup'ed here
+ to mimic the behavio(u)r of fdopen.
+*/
+gzFile ZEXPORT gzdopen (fd, mode)
+ int fd;
+ const char *mode;
+{
+ char name[46]; /* allow for up to 128-bit integers */
+
+ if (fd < 0) return (gzFile)Z_NULL;
+ sprintf(name, "<fd:%d>", fd); /* for debugging */
+
+ return gz_open (name, mode, fd);
+}
+
+/* ===========================================================================
+ * Update the compression level and strategy
+ */
+int ZEXPORT gzsetparams (file, level, strategy)
+ gzFile file;
+ int level;
+ int strategy;
+{
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
+
+ /* Make room to allow flushing */
+ if (s->stream.avail_out == 0) {
+
+ s->stream.next_out = s->outbuf;
+ if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
+ s->z_err = Z_ERRNO;
+ }
+ s->stream.avail_out = Z_BUFSIZE;
+ }
+
+ return deflateParams (&(s->stream), level, strategy);
+}
+
+/* ===========================================================================
+ Read a byte from a gz_stream; update next_in and avail_in. Return EOF
+ for end of file.
+ IN assertion: the stream s has been sucessfully opened for reading.
+*/
+local int get_byte(s)
+ gz_stream *s;
+{
+ if (s->z_eof) return EOF;
+ if (s->stream.avail_in == 0) {
+ errno = 0;
+ s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
+ if (s->stream.avail_in == 0) {
+ s->z_eof = 1;
+ if (ferror(s->file)) s->z_err = Z_ERRNO;
+ return EOF;
+ }
+ s->stream.next_in = s->inbuf;
+ }
+ s->stream.avail_in--;
+ return *(s->stream.next_in)++;
+}
+
+/* ===========================================================================
+ Check the gzip header of a gz_stream opened for reading. Set the stream
+ mode to transparent if the gzip magic header is not present; set s->err
+ to Z_DATA_ERROR if the magic header is present but the rest of the header
+ is incorrect.
+ IN assertion: the stream s has already been created sucessfully;
+ s->stream.avail_in is zero for the first time, but may be non-zero
+ for concatenated .gz files.
+*/
+local void check_header(s)
+ gz_stream *s;
+{
+ int method; /* method byte */
+ int flags; /* flags byte */
+ uInt len;
+ int c;
+
+ /* Assure two bytes in the buffer so we can peek ahead -- handle case
+ where first byte of header is at the end of the buffer after the last
+ gzip segment */
+ len = s->stream.avail_in;
+ if (len < 2) {
+ if (len) s->inbuf[0] = s->stream.next_in[0];
+ errno = 0;
+ len = (uInt)fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file);
+ if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO;
+ s->stream.avail_in += len;
+ s->stream.next_in = s->inbuf;
+ if (s->stream.avail_in < 2) {
+ s->transparent = s->stream.avail_in;
+ return;
+ }
+ }
+
+ /* Peek ahead to check the gzip magic header */
+ if (s->stream.next_in[0] != gz_magic[0] ||
+ s->stream.next_in[1] != gz_magic[1]) {
+ s->transparent = 1;
+ return;
+ }
+ s->stream.avail_in -= 2;
+ s->stream.next_in += 2;
+
+ /* Check the rest of the gzip header */
+ method = get_byte(s);
+ flags = get_byte(s);
+ if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
+ s->z_err = Z_DATA_ERROR;
+ return;
+ }
+
+ /* Discard time, xflags and OS code: */
+ for (len = 0; len < 6; len++) (void)get_byte(s);
+
+ if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
+ len = (uInt)get_byte(s);
+ len += ((uInt)get_byte(s))<<8;
+ /* len is garbage if EOF but the loop below will quit anyway */
+ while (len-- != 0 && get_byte(s) != EOF) ;
+ }
+ if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
+ while ((c = get_byte(s)) != 0 && c != EOF) ;
+ }
+ if ((flags & COMMENT) != 0) { /* skip the .gz file comment */
+ while ((c = get_byte(s)) != 0 && c != EOF) ;
+ }
+ if ((flags & HEAD_CRC) != 0) { /* skip the header crc */
+ for (len = 0; len < 2; len++) (void)get_byte(s);
+ }
+ s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
+}
+
+ /* ===========================================================================
+ * Cleanup then free the given gz_stream. Return a zlib error code.
+ Try freeing in the reverse order of allocations.
+ */
+local int destroy (s)
+ gz_stream *s;
+{
+ int err = Z_OK;
+
+ if (!s) return Z_STREAM_ERROR;
+
+ TRYFREE(s->msg);
+
+ if (s->stream.state != NULL) {
+ if (s->mode == 'w') {
+#ifdef NO_GZCOMPRESS
+ err = Z_STREAM_ERROR;
+#else
+ err = deflateEnd(&(s->stream));
+#endif
+ } else if (s->mode == 'r') {
+ err = inflateEnd(&(s->stream));
+ }
+ }
+ if (s->file != NULL && fclose(s->file)) {
+#ifdef ESPIPE
+ if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */
+#endif
+ err = Z_ERRNO;
+ }
+ if (s->z_err < 0) err = s->z_err;
+
+ TRYFREE(s->inbuf);
+ TRYFREE(s->outbuf);
+ TRYFREE(s->path);
+ TRYFREE(s);
+ return err;
+}
+
+/* ===========================================================================
+ Reads the given number of uncompressed bytes from the compressed file.
+ gzread returns the number of bytes actually read (0 for end of file).
+*/
+int ZEXPORT gzread (file, buf, len)
+ gzFile file;
+ voidp buf;
+ unsigned len;
+{
+ gz_stream *s = (gz_stream*)file;
+ Bytef *start = (Bytef*)buf; /* starting point for crc computation */
+ Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */
+
+ if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR;
+
+ if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1;
+ if (s->z_err == Z_STREAM_END) return 0; /* EOF */
+
+ next_out = (Byte*)buf;
+ s->stream.next_out = (Bytef*)buf;
+ s->stream.avail_out = len;
+
+ if (s->stream.avail_out && s->back != EOF) {
+ *next_out++ = s->back;
+ s->stream.next_out++;
+ s->stream.avail_out--;
+ s->back = EOF;
+ s->out++;
+ start++;
+ if (s->last) {
+ s->z_err = Z_STREAM_END;
+ return 1;
+ }
+ }
+
+ while (s->stream.avail_out != 0) {
+
+ if (s->transparent) {
+ /* Copy first the lookahead bytes: */
+ uInt n = s->stream.avail_in;
+ if (n > s->stream.avail_out) n = s->stream.avail_out;
+ if (n > 0) {
+ zmemcpy(s->stream.next_out, s->stream.next_in, n);
+ next_out += n;
+ s->stream.next_out = next_out;
+ s->stream.next_in += n;
+ s->stream.avail_out -= n;
+ s->stream.avail_in -= n;
+ }
+ if (s->stream.avail_out > 0) {
+ s->stream.avail_out -=
+ (uInt)fread(next_out, 1, s->stream.avail_out, s->file);
+ }
+ len -= s->stream.avail_out;
+ s->in += len;
+ s->out += len;
+ if (len == 0) s->z_eof = 1;
+ return (int)len;
+ }
+ if (s->stream.avail_in == 0 && !s->z_eof) {
+
+ errno = 0;
+ s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
+ if (s->stream.avail_in == 0) {
+ s->z_eof = 1;
+ if (ferror(s->file)) {
+ s->z_err = Z_ERRNO;
+ break;
+ }
+ }
+ s->stream.next_in = s->inbuf;
+ }
+ s->in += s->stream.avail_in;
+ s->out += s->stream.avail_out;
+ s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
+ s->in -= s->stream.avail_in;
+ s->out -= s->stream.avail_out;
+
+ if (s->z_err == Z_STREAM_END) {
+ /* Check CRC and original size */
+ s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
+ start = s->stream.next_out;
+
+ if (getLong(s) != s->crc) {
+ s->z_err = Z_DATA_ERROR;
+ } else {
+ (void)getLong(s);
+ /* The uncompressed length returned by above getlong() may be
+ * different from s->out in case of concatenated .gz files.
+ * Check for such files:
+ */
+ check_header(s);
+ if (s->z_err == Z_OK) {
+ inflateReset(&(s->stream));
+ s->crc = crc32(0L, Z_NULL, 0);
+ }
+ }
+ }
+ if (s->z_err != Z_OK || s->z_eof) break;
+ }
+ s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
+
+ if (len == s->stream.avail_out &&
+ (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO))
+ return -1;
+ return (int)(len - s->stream.avail_out);
+}
+
+
+/* ===========================================================================
+ Reads one byte from the compressed file. gzgetc returns this byte
+ or -1 in case of end of file or error.
+*/
+int ZEXPORT gzgetc(file)
+ gzFile file;
+{
+ unsigned char c;
+
+ return gzread(file, &c, 1) == 1 ? c : -1;
+}
+
+
+/* ===========================================================================
+ Push one byte back onto the stream.
+*/
+int ZEXPORT gzungetc(c, file)
+ int c;
+ gzFile file;
+{
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL || s->mode != 'r' || c == EOF || s->back != EOF) return EOF;
+ s->back = c;
+ s->out--;
+ s->last = (s->z_err == Z_STREAM_END);
+ if (s->last) s->z_err = Z_OK;
+ s->z_eof = 0;
+ return c;
+}
+
+
+/* ===========================================================================
+ Reads bytes from the compressed file until len-1 characters are
+ read, or a newline character is read and transferred to buf, or an
+ end-of-file condition is encountered. The string is then terminated
+ with a null character.
+ gzgets returns buf, or Z_NULL in case of error.
+
+ The current implementation is not optimized at all.
+*/
+char * ZEXPORT gzgets(file, buf, len)
+ gzFile file;
+ char *buf;
+ int len;
+{
+ char *b = buf;
+ if (buf == Z_NULL || len <= 0) return Z_NULL;
+
+ while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ;
+ *buf = '\0';
+ return b == buf && len > 0 ? Z_NULL : b;
+}
+
+
+#ifndef NO_GZCOMPRESS
+/* ===========================================================================
+ Writes the given number of uncompressed bytes into the compressed file.
+ gzwrite returns the number of bytes actually written (0 in case of error).
+*/
+int ZEXPORT gzwrite (file, buf, len)
+ gzFile file;
+ voidpc buf;
+ unsigned len;
+{
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
+
+ s->stream.next_in = (Bytef*)buf;
+ s->stream.avail_in = len;
+
+ while (s->stream.avail_in != 0) {
+
+ if (s->stream.avail_out == 0) {
+
+ s->stream.next_out = s->outbuf;
+ if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
+ s->z_err = Z_ERRNO;
+ break;
+ }
+ s->stream.avail_out = Z_BUFSIZE;
+ }
+ s->in += s->stream.avail_in;
+ s->out += s->stream.avail_out;
+ s->z_err = deflate(&(s->stream), Z_NO_FLUSH);
+ s->in -= s->stream.avail_in;
+ s->out -= s->stream.avail_out;
+ if (s->z_err != Z_OK) break;
+ }
+ s->crc = crc32(s->crc, (const Bytef *)buf, len);
+
+ return (int)(len - s->stream.avail_in);
+}
+
+
+/* ===========================================================================
+ Converts, formats, and writes the args to the compressed file under
+ control of the format string, as in fprintf. gzprintf returns the number of
+ uncompressed bytes actually written (0 in case of error).
+*/
+#ifdef STDC
+#include <stdarg.h>
+
+int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...)
+{
+ char buf[Z_PRINTF_BUFSIZE];
+ va_list va;
+ int len;
+
+ buf[sizeof(buf) - 1] = 0;
+ va_start(va, format);
+#ifdef NO_vsnprintf
+# ifdef HAS_vsprintf_void
+ (void)vsprintf(buf, format, va);
+ va_end(va);
+ for (len = 0; len < sizeof(buf); len++)
+ if (buf[len] == 0) break;
+# else
+ len = vsprintf(buf, format, va);
+ va_end(va);
+# endif
+#else
+# ifdef HAS_vsnprintf_void
+ (void)vsnprintf(buf, sizeof(buf), format, va);
+ va_end(va);
+ len = strlen(buf);
+# else
+ len = vsnprintf(buf, sizeof(buf), format, va);
+ va_end(va);
+# endif
+#endif
+ if (len <= 0 || len >= (int)sizeof(buf) || buf[sizeof(buf) - 1] != 0)
+ return 0;
+ return gzwrite(file, buf, (unsigned)len);
+}
+#else /* not ANSI C */
+
+int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
+ a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
+ gzFile file;
+ const char *format;
+ int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
+ a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
+{
+ char buf[Z_PRINTF_BUFSIZE];
+ int len;
+
+ buf[sizeof(buf) - 1] = 0;
+#ifdef NO_snprintf
+# ifdef HAS_sprintf_void
+ sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
+ a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+ for (len = 0; len < sizeof(buf); len++)
+ if (buf[len] == 0) break;
+# else
+ len = sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
+ a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+# endif
+#else
+# ifdef HAS_snprintf_void
+ snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
+ a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+ len = strlen(buf);
+# else
+ len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
+ a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+# endif
+#endif
+ if (len <= 0 || len >= sizeof(buf) || buf[sizeof(buf) - 1] != 0)
+ return 0;
+ return gzwrite(file, buf, len);
+}
+#endif
+
+/* ===========================================================================
+ Writes c, converted to an unsigned char, into the compressed file.
+ gzputc returns the value that was written, or -1 in case of error.
+*/
+int ZEXPORT gzputc(file, c)
+ gzFile file;
+ int c;
+{
+ unsigned char cc = (unsigned char) c; /* required for big endian systems */
+
+ return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1;
+}
+
+
+/* ===========================================================================
+ Writes the given null-terminated string to the compressed file, excluding
+ the terminating null character.
+ gzputs returns the number of characters written, or -1 in case of error.
+*/
+int ZEXPORT gzputs(file, s)
+ gzFile file;
+ const char *s;
+{
+ return gzwrite(file, (char*)s, (unsigned)strlen(s));
+}
+
+
+/* ===========================================================================
+ Flushes all pending output into the compressed file. The parameter
+ flush is as in the deflate() function.
+*/
+local int do_flush (file, flush)
+ gzFile file;
+ int flush;
+{
+ uInt len;
+ int done = 0;
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
+
+ s->stream.avail_in = 0; /* should be zero already anyway */
+
+ for (;;) {
+ len = Z_BUFSIZE - s->stream.avail_out;
+
+ if (len != 0) {
+ if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) {
+ s->z_err = Z_ERRNO;
+ return Z_ERRNO;
+ }
+ s->stream.next_out = s->outbuf;
+ s->stream.avail_out = Z_BUFSIZE;
+ }
+ if (done) break;
+ s->out += s->stream.avail_out;
+ s->z_err = deflate(&(s->stream), flush);
+ s->out -= s->stream.avail_out;
+
+ /* Ignore the second of two consecutive flushes: */
+ if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK;
+
+ /* deflate has finished flushing only when it hasn't used up
+ * all the available space in the output buffer:
+ */
+ done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
+
+ if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break;
+ }
+ return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
+}
+
+int ZEXPORT gzflush (file, flush)
+ gzFile file;
+ int flush;
+{
+ gz_stream *s = (gz_stream*)file;
+ int err = do_flush (file, flush);
+
+ if (err) return err;
+ fflush(s->file);
+ return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
+}
+#endif /* NO_GZCOMPRESS */
+
+/* ===========================================================================
+ Sets the starting position for the next gzread or gzwrite on the given
+ compressed file. The offset represents a number of bytes in the
+ gzseek returns the resulting offset location as measured in bytes from
+ the beginning of the uncompressed stream, or -1 in case of error.
+ SEEK_END is not implemented, returns error.
+ In this version of the library, gzseek can be extremely slow.
+*/
+z_off_t ZEXPORT gzseek (file, offset, whence)
+ gzFile file;
+ z_off_t offset;
+ int whence;
+{
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL || whence == SEEK_END ||
+ s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) {
+ return -1L;
+ }
+
+ if (s->mode == 'w') {
+#ifdef NO_GZCOMPRESS
+ return -1L;
+#else
+ if (whence == SEEK_SET) {
+ offset -= s->in;
+ }
+ if (offset < 0) return -1L;
+
+ /* At this point, offset is the number of zero bytes to write. */
+ if (s->inbuf == Z_NULL) {
+ s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */
+ if (s->inbuf == Z_NULL) return -1L;
+ zmemzero(s->inbuf, Z_BUFSIZE);
+ }
+ while (offset > 0) {
+ uInt size = Z_BUFSIZE;
+ if (offset < Z_BUFSIZE) size = (uInt)offset;
+
+ size = gzwrite(file, s->inbuf, size);
+ if (size == 0) return -1L;
+
+ offset -= size;
+ }
+ return s->in;
+#endif
+ }
+ /* Rest of function is for reading only */
+
+ /* compute absolute position */
+ if (whence == SEEK_CUR) {
+ offset += s->out;
+ }
+ if (offset < 0) return -1L;
+
+ if (s->transparent) {
+ /* map to fseek */
+ s->back = EOF;
+ s->stream.avail_in = 0;
+ s->stream.next_in = s->inbuf;
+ if (fseek(s->file, offset, SEEK_SET) < 0) return -1L;
+
+ s->in = s->out = offset;
+ return offset;
+ }
+
+ /* For a negative seek, rewind and use positive seek */
+ if (offset >= s->out) {
+ offset -= s->out;
+ } else if (gzrewind(file) < 0) {
+ return -1L;
+ }
+ /* offset is now the number of bytes to skip. */
+
+ if (offset != 0 && s->outbuf == Z_NULL) {
+ s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
+ if (s->outbuf == Z_NULL) return -1L;
+ }
+ if (offset && s->back != EOF) {
+ s->back = EOF;
+ s->out++;
+ offset--;
+ if (s->last) s->z_err = Z_STREAM_END;
+ }
+ while (offset > 0) {
+ int size = Z_BUFSIZE;
+ if (offset < Z_BUFSIZE) size = (int)offset;
+
+ size = gzread(file, s->outbuf, (uInt)size);
+ if (size <= 0) return -1L;
+ offset -= size;
+ }
+ return s->out;
+}
+
+/* ===========================================================================
+ Rewinds input file.
+*/
+int ZEXPORT gzrewind (file)
+ gzFile file;
+{
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL || s->mode != 'r') return -1;
+
+ s->z_err = Z_OK;
+ s->z_eof = 0;
+ s->back = EOF;
+ s->stream.avail_in = 0;
+ s->stream.next_in = s->inbuf;
+ s->crc = crc32(0L, Z_NULL, 0);
+ if (!s->transparent) (void)inflateReset(&s->stream);
+ s->in = 0;
+ s->out = 0;
+ return fseek(s->file, s->start, SEEK_SET);
+}
+
+/* ===========================================================================
+ Returns the starting position for the next gzread or gzwrite on the
+ given compressed file. This position represents a number of bytes in the
+ uncompressed data stream.
+*/
+z_off_t ZEXPORT gztell (file)
+ gzFile file;
+{
+ return gzseek(file, 0L, SEEK_CUR);
+}
+
+/* ===========================================================================
+ Returns 1 when EOF has previously been detected reading the given
+ input stream, otherwise zero.
+*/
+int ZEXPORT gzeof (file)
+ gzFile file;
+{
+ gz_stream *s = (gz_stream*)file;
+
+ /* With concatenated compressed files that can have embedded
+ * crc trailers, z_eof is no longer the only/best indicator of EOF
+ * on a gz_stream. Handle end-of-stream error explicitly here.
+ */
+ if (s == NULL || s->mode != 'r') return 0;
+ if (s->z_eof) return 1;
+ return s->z_err == Z_STREAM_END;
+}
+
+/* ===========================================================================
+ Returns 1 if reading and doing so transparently, otherwise zero.
+*/
+int ZEXPORT gzdirect (file)
+ gzFile file;
+{
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL || s->mode != 'r') return 0;
+ return s->transparent;
+}
+
+/* ===========================================================================
+ Outputs a long in LSB order to the given file
+*/
+local void putLong (file, x)
+ FILE *file;
+ uLong x;
+{
+ int n;
+ for (n = 0; n < 4; n++) {
+ fputc((int)(x & 0xff), file);
+ x >>= 8;
+ }
+}
+
+/* ===========================================================================
+ Reads a long in LSB order from the given gz_stream. Sets z_err in case
+ of error.
+*/
+local uLong getLong (s)
+ gz_stream *s;
+{
+ uLong x = (uLong)get_byte(s);
+ int c;
+
+ x += ((uLong)get_byte(s))<<8;
+ x += ((uLong)get_byte(s))<<16;
+ c = get_byte(s);
+ if (c == EOF) s->z_err = Z_DATA_ERROR;
+ x += ((uLong)c)<<24;
+ return x;
+}
+
+/* ===========================================================================
+ Flushes all pending output if necessary, closes the compressed file
+ and deallocates all the (de)compression state.
+*/
+int ZEXPORT gzclose (file)
+ gzFile file;
+{
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL) return Z_STREAM_ERROR;
+
+ if (s->mode == 'w') {
+#ifdef NO_GZCOMPRESS
+ return Z_STREAM_ERROR;
+#else
+ if (do_flush (file, Z_FINISH) != Z_OK)
+ return destroy((gz_stream*)file);
+
+ putLong (s->file, s->crc);
+ putLong (s->file, (uLong)(s->in & 0xffffffff));
+#endif
+ }
+ return destroy((gz_stream*)file);
+}
+
+#ifdef STDC
+# define zstrerror(errnum) strerror(errnum)
+#else
+# define zstrerror(errnum) ""
+#endif
+
+/* ===========================================================================
+ Returns the error message for the last error which occurred on the
+ given compressed file. errnum is set to zlib error number. If an
+ error occurred in the file system and not in the compression library,
+ errnum is set to Z_ERRNO and the application may consult errno
+ to get the exact error code.
+*/
+const char * ZEXPORT gzerror (file, errnum)
+ gzFile file;
+ int *errnum;
+{
+ char *m;
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL) {
+ *errnum = Z_STREAM_ERROR;
+ return (const char*)ERR_MSG(Z_STREAM_ERROR);
+ }
+ *errnum = s->z_err;
+ if (*errnum == Z_OK) return (const char*)"";
+
+ m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg);
+
+ if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err);
+
+ TRYFREE(s->msg);
+ s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3);
+ if (s->msg == Z_NULL) return (const char*)ERR_MSG(Z_MEM_ERROR);
+ strcpy(s->msg, s->path);
+ strcat(s->msg, ": ");
+ strcat(s->msg, m);
+ return (const char*)s->msg;
+}
+
+/* ===========================================================================
+ Clear the error and end-of-file flags, and do the same for the real file.
+*/
+void ZEXPORT gzclearerr (file)
+ gzFile file;
+{
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL) return;
+ if (s->z_err != Z_STREAM_END) s->z_err = Z_OK;
+ s->z_eof = 0;
+ clearerr(s->file);
+}
diff --git a/Utilities/cmzlib/inffast.c b/Utilities/cmzlib/inffast.c
new file mode 100644
index 000000000..bbee92ed1
--- /dev/null
+++ b/Utilities/cmzlib/inffast.c
@@ -0,0 +1,318 @@
+/* inffast.c -- fast decoding
+ * Copyright (C) 1995-2004 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+#ifndef ASMINF
+
+/* Allow machine dependent optimization for post-increment or pre-increment.
+ Based on testing to date,
+ Pre-increment preferred for:
+ - PowerPC G3 (Adler)
+ - MIPS R5000 (Randers-Pehrson)
+ Post-increment preferred for:
+ - none
+ No measurable difference:
+ - Pentium III (Anderson)
+ - M68060 (Nikl)
+ */
+#ifdef POSTINC
+# define OFF 0
+# define PUP(a) *(a)++
+#else
+# define OFF 1
+# define PUP(a) *++(a)
+#endif
+
+/*
+ Decode literal, length, and distance codes and write out the resulting
+ literal and match bytes until either not enough input or output is
+ available, an end-of-block is encountered, or a data error is encountered.
+ When large enough input and output buffers are supplied to inflate(), for
+ example, a 16K input buffer and a 64K output buffer, more than 95% of the
+ inflate execution time is spent in this routine.
+
+ Entry assumptions:
+
+ state->mode == LEN
+ strm->avail_in >= 6
+ strm->avail_out >= 258
+ start >= strm->avail_out
+ state->bits < 8
+
+ On return, state->mode is one of:
+
+ LEN -- ran out of enough output space or enough available input
+ TYPE -- reached end of block code, inflate() to interpret next block
+ BAD -- error in block data
+
+ Notes:
+
+ - The maximum input bits used by a length/distance pair is 15 bits for the
+ length code, 5 bits for the length extra, 15 bits for the distance code,
+ and 13 bits for the distance extra. This totals 48 bits, or six bytes.
+ Therefore if strm->avail_in >= 6, then there is enough input to avoid
+ checking for available input while decoding.
+
+ - The maximum bytes that a single length/distance pair can output is 258
+ bytes, which is the maximum length that can be coded. inflate_fast()
+ requires strm->avail_out >= 258 for each loop to avoid checking for
+ output space.
+ */
+void inflate_fast(strm, start)
+z_streamp strm;
+unsigned start; /* inflate()'s starting value for strm->avail_out */
+{
+ struct inflate_state FAR *state;
+ unsigned char FAR *in; /* local strm->next_in */
+ unsigned char FAR *last; /* while in < last, enough input available */
+ unsigned char FAR *out; /* local strm->next_out */
+ unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
+ unsigned char FAR *end; /* while out < end, enough space available */
+#ifdef INFLATE_STRICT
+ unsigned dmax; /* maximum distance from zlib header */
+#endif
+ unsigned wsize; /* window size or zero if not using window */
+ unsigned whave; /* valid bytes in the window */
+ unsigned write; /* window write index */
+ unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */
+ unsigned long hold; /* local strm->hold */
+ unsigned bits; /* local strm->bits */
+ code const FAR *lcode; /* local strm->lencode */
+ code const FAR *dcode; /* local strm->distcode */
+ unsigned lmask; /* mask for first level of length codes */
+ unsigned dmask; /* mask for first level of distance codes */
+ code this; /* retrieved table entry */
+ unsigned op; /* code bits, operation, extra bits, or */
+ /* window position, window bytes to copy */
+ unsigned len; /* match length, unused bytes */
+ unsigned dist; /* match distance */
+ unsigned char FAR *from; /* where to copy match from */
+
+ /* copy state to local variables */
+ state = (struct inflate_state FAR *)strm->state;
+ in = strm->next_in - OFF;
+ last = in + (strm->avail_in - 5);
+ out = strm->next_out - OFF;
+ beg = out - (start - strm->avail_out);
+ end = out + (strm->avail_out - 257);
+#ifdef INFLATE_STRICT
+ dmax = state->dmax;
+#endif
+ wsize = state->wsize;
+ whave = state->whave;
+ write = state->write;
+ window = state->window;
+ hold = state->hold;
+ bits = state->bits;
+ lcode = state->lencode;
+ dcode = state->distcode;
+ lmask = (1U << state->lenbits) - 1;
+ dmask = (1U << state->distbits) - 1;
+
+ /* decode literals and length/distances until end-of-block or not enough
+ input data or output space */
+ do {
+ if (bits < 15) {
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ }
+ this = lcode[hold & lmask];
+ dolen:
+ op = (unsigned)(this.bits);
+ hold >>= op;
+ bits -= op;
+ op = (unsigned)(this.op);
+ if (op == 0) { /* literal */
+ Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
+ "inflate: literal '%c'\n" :
+ "inflate: literal 0x%02x\n", this.val));
+ PUP(out) = (unsigned char)(this.val);
+ }
+ else if (op & 16) { /* length base */
+ len = (unsigned)(this.val);
+ op &= 15; /* number of extra bits */
+ if (op) {
+ if (bits < op) {
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ }
+ len += (unsigned)hold & ((1U << op) - 1);
+ hold >>= op;
+ bits -= op;
+ }
+ Tracevv((stderr, "inflate: length %u\n", len));
+ if (bits < 15) {
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ }
+ this = dcode[hold & dmask];
+ dodist:
+ op = (unsigned)(this.bits);
+ hold >>= op;
+ bits -= op;
+ op = (unsigned)(this.op);
+ if (op & 16) { /* distance base */
+ dist = (unsigned)(this.val);
+ op &= 15; /* number of extra bits */
+ if (bits < op) {
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ if (bits < op) {
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ }
+ }
+ dist += (unsigned)hold & ((1U << op) - 1);
+#ifdef INFLATE_STRICT
+ if (dist > dmax) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+#endif
+ hold >>= op;
+ bits -= op;
+ Tracevv((stderr, "inflate: distance %u\n", dist));
+ op = (unsigned)(out - beg); /* max distance in output */
+ if (dist > op) { /* see if copy from window */
+ op = dist - op; /* distance back in window */
+ if (op > whave) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+ from = window - OFF;
+ if (write == 0) { /* very common case */
+ from += wsize - op;
+ if (op < len) { /* some from window */
+ len -= op;
+ do {
+ PUP(out) = PUP(from);
+ } while (--op);
+ from = out - dist; /* rest from output */
+ }
+ }
+ else if (write < op) { /* wrap around window */
+ from += wsize + write - op;
+ op -= write;
+ if (op < len) { /* some from end of window */
+ len -= op;
+ do {
+ PUP(out) = PUP(from);
+ } while (--op);
+ from = window - OFF;
+ if (write < len) { /* some from start of window */
+ op = write;
+ len -= op;
+ do {
+ PUP(out) = PUP(from);
+ } while (--op);
+ from = out - dist; /* rest from output */
+ }
+ }
+ }
+ else { /* contiguous in window */
+ from += write - op;
+ if (op < len) { /* some from window */
+ len -= op;
+ do {
+ PUP(out) = PUP(from);
+ } while (--op);
+ from = out - dist; /* rest from output */
+ }
+ }
+ while (len > 2) {
+ PUP(out) = PUP(from);
+ PUP(out) = PUP(from);
+ PUP(out) = PUP(from);
+ len -= 3;
+ }
+ if (len) {
+ PUP(out) = PUP(from);
+ if (len > 1)
+ PUP(out) = PUP(from);
+ }
+ }
+ else {
+ from = out - dist; /* copy direct from output */
+ do { /* minimum length is three */
+ PUP(out) = PUP(from);
+ PUP(out) = PUP(from);
+ PUP(out) = PUP(from);
+ len -= 3;
+ } while (len > 2);
+ if (len) {
+ PUP(out) = PUP(from);
+ if (len > 1)
+ PUP(out) = PUP(from);
+ }
+ }
+ }
+ else if ((op & 64) == 0) { /* 2nd level distance code */
+ this = dcode[this.val + (hold & ((1U << op) - 1))];
+ goto dodist;
+ }
+ else {
+ strm->msg = (char *)"invalid distance code";
+ state->mode = BAD;
+ break;
+ }
+ }
+ else if ((op & 64) == 0) { /* 2nd level length code */
+ this = lcode[this.val + (hold & ((1U << op) - 1))];
+ goto dolen;
+ }
+ else if (op & 32) { /* end-of-block */
+ Tracevv((stderr, "inflate: end of block\n"));
+ state->mode = TYPE;
+ break;
+ }
+ else {
+ strm->msg = (char *)"invalid literal/length code";
+ state->mode = BAD;
+ break;
+ }
+ } while (in < last && out < end);
+
+ /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
+ len = bits >> 3;
+ in -= len;
+ bits -= len << 3;
+ hold &= (1U << bits) - 1;
+
+ /* update state and return */
+ strm->next_in = in + OFF;
+ strm->next_out = out + OFF;
+ strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
+ strm->avail_out = (unsigned)(out < end ?
+ 257 + (end - out) : 257 - (out - end));
+ state->hold = hold;
+ state->bits = bits;
+ return;
+}
+
+/*
+ inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
+ - Using bit fields for code structure
+ - Different op definition to avoid & for extra bits (do & for table bits)
+ - Three separate decoding do-loops for direct, window, and write == 0
+ - Special case for distance > 1 copies to do overlapped load and store copy
+ - Explicit branch predictions (based on measured branch probabilities)
+ - Deferring match copy and interspersed it with decoding subsequent codes
+ - Swapping literal/length else
+ - Swapping window/direct else
+ - Larger unrolled copy loops (three is about right)
+ - Moving len -= 3 statement into middle of loop
+ */
+
+#endif /* !ASMINF */
diff --git a/Utilities/cmzlib/inffast.h b/Utilities/cmzlib/inffast.h
new file mode 100644
index 000000000..1e88d2d97
--- /dev/null
+++ b/Utilities/cmzlib/inffast.h
@@ -0,0 +1,11 @@
+/* inffast.h -- header to use inffast.c
+ * Copyright (C) 1995-2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+void inflate_fast OF((z_streamp strm, unsigned start));
diff --git a/Utilities/cmzlib/inffixed.h b/Utilities/cmzlib/inffixed.h
new file mode 100644
index 000000000..75ed4b597
--- /dev/null
+++ b/Utilities/cmzlib/inffixed.h
@@ -0,0 +1,94 @@
+ /* inffixed.h -- table for decoding fixed codes
+ * Generated automatically by makefixed().
+ */
+
+ /* WARNING: this file should *not* be used by applications. It
+ is part of the implementation of the compression library and
+ is subject to change. Applications should only use zlib.h.
+ */
+
+ static const code lenfix[512] = {
+ {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
+ {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
+ {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
+ {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
+ {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
+ {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
+ {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
+ {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
+ {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
+ {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
+ {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
+ {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
+ {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
+ {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
+ {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
+ {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
+ {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
+ {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
+ {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
+ {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
+ {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
+ {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
+ {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
+ {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
+ {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
+ {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
+ {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
+ {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
+ {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
+ {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
+ {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
+ {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
+ {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
+ {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
+ {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
+ {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
+ {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
+ {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
+ {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
+ {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
+ {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
+ {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
+ {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
+ {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
+ {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
+ {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
+ {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
+ {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
+ {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
+ {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
+ {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
+ {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
+ {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
+ {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
+ {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
+ {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
+ {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
+ {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
+ {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
+ {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
+ {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
+ {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
+ {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
+ {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
+ {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
+ {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
+ {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
+ {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
+ {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
+ {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
+ {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
+ {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
+ {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
+ {0,9,255}
+ };
+
+ static const code distfix[32] = {
+ {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
+ {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
+ {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
+ {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
+ {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
+ {22,5,193},{64,5,0}
+ };
diff --git a/Utilities/cmzlib/inflate.c b/Utilities/cmzlib/inflate.c
new file mode 100644
index 000000000..792fdee8e
--- /dev/null
+++ b/Utilities/cmzlib/inflate.c
@@ -0,0 +1,1368 @@
+/* inflate.c -- zlib decompression
+ * Copyright (C) 1995-2005 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * Change history:
+ *
+ * 1.2.beta0 24 Nov 2002
+ * - First version -- complete rewrite of inflate to simplify code, avoid
+ * creation of window when not needed, minimize use of window when it is
+ * needed, make inffast.c even faster, implement gzip decoding, and to
+ * improve code readability and style over the previous zlib inflate code
+ *
+ * 1.2.beta1 25 Nov 2002
+ * - Use pointers for available input and output checking in inffast.c
+ * - Remove input and output counters in inffast.c
+ * - Change inffast.c entry and loop from avail_in >= 7 to >= 6
+ * - Remove unnecessary second byte pull from length extra in inffast.c
+ * - Unroll direct copy to three copies per loop in inffast.c
+ *
+ * 1.2.beta2 4 Dec 2002
+ * - Change external routine names to reduce potential conflicts
+ * - Correct filename to inffixed.h for fixed tables in inflate.c
+ * - Make hbuf[] unsigned char to match parameter type in inflate.c
+ * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset)
+ * to avoid negation problem on Alphas (64 bit) in inflate.c
+ *
+ * 1.2.beta3 22 Dec 2002
+ * - Add comments on state->bits assertion in inffast.c
+ * - Add comments on op field in inftrees.h
+ * - Fix bug in reuse of allocated window after inflateReset()
+ * - Remove bit fields--back to byte structure for speed
+ * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths
+ * - Change post-increments to pre-increments in inflate_fast(), PPC biased?
+ * - Add compile time option, POSTINC, to use post-increments instead (Intel?)
+ * - Make MATCH copy in inflate() much faster for when inflate_fast() not used
+ * - Use local copies of stream next and avail values, as well as local bit
+ * buffer and bit count in inflate()--for speed when inflate_fast() not used
+ *
+ * 1.2.beta4 1 Jan 2003
+ * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings
+ * - Move a comment on output buffer sizes from inffast.c to inflate.c
+ * - Add comments in inffast.c to introduce the inflate_fast() routine
+ * - Rearrange window copies in inflate_fast() for speed and simplification
+ * - Unroll last copy for window match in inflate_fast()
+ * - Use local copies of window variables in inflate_fast() for speed
+ * - Pull out common write == 0 case for speed in inflate_fast()
+ * - Make op and len in inflate_fast() unsigned for consistency
+ * - Add FAR to lcode and dcode declarations in inflate_fast()
+ * - Simplified bad distance check in inflate_fast()
+ * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new
+ * source file infback.c to provide a call-back interface to inflate for
+ * programs like gzip and unzip -- uses window as output buffer to avoid
+ * window copying
+ *
+ * 1.2.beta5 1 Jan 2003
+ * - Improved inflateBack() interface to allow the caller to provide initial
+ * input in strm.
+ * - Fixed stored blocks bug in inflateBack()
+ *
+ * 1.2.beta6 4 Jan 2003
+ * - Added comments in inffast.c on effectiveness of POSTINC
+ * - Typecasting all around to reduce compiler warnings
+ * - Changed loops from while (1) or do {} while (1) to for (;;), again to
+ * make compilers happy
+ * - Changed type of window in inflateBackInit() to unsigned char *
+ *
+ * 1.2.beta7 27 Jan 2003
+ * - Changed many types to unsigned or unsigned short to avoid warnings
+ * - Added inflateCopy() function
+ *
+ * 1.2.0 9 Mar 2003
+ * - Changed inflateBack() interface to provide separate opaque descriptors
+ * for the in() and out() functions
+ * - Changed inflateBack() argument and in_func typedef to swap the length
+ * and buffer address return values for the input function
+ * - Check next_in and next_out for Z_NULL on entry to inflate()
+ *
+ * The history for versions after 1.2.0 are in ChangeLog in zlib distribution.
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+#ifdef MAKEFIXED
+# ifndef BUILDFIXED
+# define BUILDFIXED
+# endif
+#endif
+
+/* function prototypes */
+local void fixedtables OF((struct inflate_state FAR *state));
+local int updatewindow OF((z_streamp strm, unsigned out));
+#ifdef BUILDFIXED
+ void makefixed OF((void));
+#endif
+local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf,
+ unsigned len));
+
+int ZEXPORT inflateReset(strm)
+z_streamp strm;
+{
+ struct inflate_state FAR *state;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ strm->total_in = strm->total_out = state->total = 0;
+ strm->msg = Z_NULL;
+ strm->adler = 1; /* to support ill-conceived Java test suite */
+ state->mode = HEAD;
+ state->last = 0;
+ state->havedict = 0;
+ state->dmax = 32768U;
+ state->head = Z_NULL;
+ state->wsize = 0;
+ state->whave = 0;
+ state->write = 0;
+ state->hold = 0;
+ state->bits = 0;
+ state->lencode = state->distcode = state->next = state->codes;
+ Tracev((stderr, "inflate: reset\n"));
+ return Z_OK;
+}
+
+int ZEXPORT inflatePrime(strm, bits, value)
+z_streamp strm;
+int bits;
+int value;
+{
+ struct inflate_state FAR *state;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;
+ value &= (1L << bits) - 1;
+ state->hold += value << state->bits;
+ state->bits += bits;
+ return Z_OK;
+}
+
+int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
+z_streamp strm;
+int windowBits;
+const char *version;
+int stream_size;
+{
+ struct inflate_state FAR *state;
+
+ if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+ stream_size != (int)(sizeof(z_stream)))
+ return Z_VERSION_ERROR;
+ if (strm == Z_NULL) return Z_STREAM_ERROR;
+ strm->msg = Z_NULL; /* in case we return an error */
+ if (strm->zalloc == (alloc_func)0) {
+ strm->zalloc = zcalloc;
+ strm->opaque = (voidpf)0;
+ }
+ if (strm->zfree == (free_func)0) strm->zfree = zcfree;
+ state = (struct inflate_state FAR *)
+ ZALLOC(strm, 1, sizeof(struct inflate_state));
+ if (state == Z_NULL) return Z_MEM_ERROR;
+ Tracev((stderr, "inflate: allocated\n"));
+ strm->state = (struct internal_state FAR *)state;
+ if (windowBits < 0) {
+ state->wrap = 0;
+ windowBits = -windowBits;
+ }
+ else {
+ state->wrap = (windowBits >> 4) + 1;
+#ifdef GUNZIP
+ if (windowBits < 48) windowBits &= 15;
+#endif
+ }
+ if (windowBits < 8 || windowBits > 15) {
+ ZFREE(strm, state);
+ strm->state = Z_NULL;
+ return Z_STREAM_ERROR;
+ }
+ state->wbits = (unsigned)windowBits;
+ state->window = Z_NULL;
+ return inflateReset(strm);
+}
+
+int ZEXPORT inflateInit_(strm, version, stream_size)
+z_streamp strm;
+const char *version;
+int stream_size;
+{
+ return inflateInit2_(strm, DEF_WBITS, version, stream_size);
+}
+
+/*
+ Return state with length and distance decoding tables and index sizes set to
+ fixed code decoding. Normally this returns fixed tables from inffixed.h.
+ If BUILDFIXED is defined, then instead this routine builds the tables the
+ first time it's called, and returns those tables the first time and
+ thereafter. This reduces the size of the code by about 2K bytes, in
+ exchange for a little execution time. However, BUILDFIXED should not be
+ used for threaded applications, since the rewriting of the tables and virgin
+ may not be thread-safe.
+ */
+local void fixedtables(state)
+struct inflate_state FAR *state;
+{
+#ifdef BUILDFIXED
+ static int virgin = 1;
+ static code *lenfix, *distfix;
+ static code fixed[544];
+
+ /* build fixed huffman tables if first call (may not be thread safe) */
+ if (virgin) {
+ unsigned sym, bits;
+ static code *next;
+
+ /* literal/length table */
+ sym = 0;
+ while (sym < 144) state->lens[sym++] = 8;
+ while (sym < 256) state->lens[sym++] = 9;
+ while (sym < 280) state->lens[sym++] = 7;
+ while (sym < 288) state->lens[sym++] = 8;
+ next = fixed;
+ lenfix = next;
+ bits = 9;
+ inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
+
+ /* distance table */
+ sym = 0;
+ while (sym < 32) state->lens[sym++] = 5;
+ distfix = next;
+ bits = 5;
+ inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
+
+ /* do this just once */
+ virgin = 0;
+ }
+#else /* !BUILDFIXED */
+# include "inffixed.h"
+#endif /* BUILDFIXED */
+ state->lencode = lenfix;
+ state->lenbits = 9;
+ state->distcode = distfix;
+ state->distbits = 5;
+}
+
+#ifdef MAKEFIXED
+#include <stdio.h>
+
+/*
+ Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also
+ defines BUILDFIXED, so the tables are built on the fly. makefixed() writes
+ those tables to stdout, which would be piped to inffixed.h. A small program
+ can simply call makefixed to do this:
+
+ void makefixed(void);
+
+ int main(void)
+ {
+ makefixed();
+ return 0;
+ }
+
+ Then that can be linked with zlib built with MAKEFIXED defined and run:
+
+ a.out > inffixed.h
+ */
+void makefixed()
+{
+ unsigned low, size;
+ struct inflate_state state;
+
+ fixedtables(&state);
+ puts(" /* inffixed.h -- table for decoding fixed codes");
+ puts(" * Generated automatically by makefixed().");
+ puts(" */");
+ puts("");
+ puts(" /* WARNING: this file should *not* be used by applications.");
+ puts(" It is part of the implementation of this library and is");
+ puts(" subject to change. Applications should only use zlib.h.");
+ puts(" */");
+ puts("");
+ size = 1U << 9;
+ printf(" static const code lenfix[%u] = {", size);
+ low = 0;
+ for (;;) {
+ if ((low % 7) == 0) printf("\n ");
+ printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits,
+ state.lencode[low].val);
+ if (++low == size) break;
+ putchar(',');
+ }
+ puts("\n };");
+ size = 1U << 5;
+ printf("\n static const code distfix[%u] = {", size);
+ low = 0;
+ for (;;) {
+ if ((low % 6) == 0) printf("\n ");
+ printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits,
+ state.distcode[low].val);
+ if (++low == size) break;
+ putchar(',');
+ }
+ puts("\n };");
+}
+#endif /* MAKEFIXED */
+
+/*
+ Update the window with the last wsize (normally 32K) bytes written before
+ returning. If window does not exist yet, create it. This is only called
+ when a window is already in use, or when output has been written during this
+ inflate call, but the end of the deflate stream has not been reached yet.
+ It is also called to create a window for dictionary data when a dictionary
+ is loaded.
+
+ Providing output buffers larger than 32K to inflate() should provide a speed
+ advantage, since only the last 32K of output is copied to the sliding window
+ upon return from inflate(), and since all distances after the first 32K of
+ output will fall in the output data, making match copies simpler and faster.
+ The advantage may be dependent on the size of the processor's data caches.
+ */
+local int updatewindow(strm, out)
+z_streamp strm;
+unsigned out;
+{
+ struct inflate_state FAR *state;
+ unsigned copy, dist;
+
+ state = (struct inflate_state FAR *)strm->state;
+
+ /* if it hasn't been done already, allocate space for the window */
+ if (state->window == Z_NULL) {
+ state->window = (unsigned char FAR *)
+ ZALLOC(strm, 1U << state->wbits,
+ sizeof(unsigned char));
+ if (state->window == Z_NULL) return 1;
+ }
+
+ /* if window not in use yet, initialize */
+ if (state->wsize == 0) {
+ state->wsize = 1U << state->wbits;
+ state->write = 0;
+ state->whave = 0;
+ }
+
+ /* copy state->wsize or less output bytes into the circular window */
+ copy = out - strm->avail_out;
+ if (copy >= state->wsize) {
+ zmemcpy(state->window, strm->next_out - state->wsize, state->wsize);
+ state->write = 0;
+ state->whave = state->wsize;
+ }
+ else {
+ dist = state->wsize - state->write;
+ if (dist > copy) dist = copy;
+ zmemcpy(state->window + state->write, strm->next_out - copy, dist);
+ copy -= dist;
+ if (copy) {
+ zmemcpy(state->window, strm->next_out - copy, copy);
+ state->write = copy;
+ state->whave = state->wsize;
+ }
+ else {
+ state->write += dist;
+ if (state->write == state->wsize) state->write = 0;
+ if (state->whave < state->wsize) state->whave += dist;
+ }
+ }
+ return 0;
+}
+
+/* Macros for inflate(): */
+
+/* check function to use adler32() for zlib or crc32() for gzip */
+#ifdef GUNZIP
+# define UPDATE(check, buf, len) \
+ (state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
+#else
+# define UPDATE(check, buf, len) adler32(check, buf, len)
+#endif
+
+/* check macros for header crc */
+#ifdef GUNZIP
+# define CRC2(check, word) \
+ do { \
+ hbuf[0] = (unsigned char)(word); \
+ hbuf[1] = (unsigned char)((word) >> 8); \
+ check = crc32(check, hbuf, 2); \
+ } while (0)
+
+# define CRC4(check, word) \
+ do { \
+ hbuf[0] = (unsigned char)(word); \
+ hbuf[1] = (unsigned char)((word) >> 8); \
+ hbuf[2] = (unsigned char)((word) >> 16); \
+ hbuf[3] = (unsigned char)((word) >> 24); \
+ check = crc32(check, hbuf, 4); \
+ } while (0)
+#endif
+
+/* Load registers with state in inflate() for speed */
+#define LOAD() \
+ do { \
+ put = strm->next_out; \
+ left = strm->avail_out; \
+ next = strm->next_in; \
+ have = strm->avail_in; \
+ hold = state->hold; \
+ bits = state->bits; \
+ } while (0)
+
+/* Restore state from registers in inflate() */
+#define RESTORE() \
+ do { \
+ strm->next_out = put; \
+ strm->avail_out = left; \
+ strm->next_in = next; \
+ strm->avail_in = have; \
+ state->hold = hold; \
+ state->bits = bits; \
+ } while (0)
+
+/* Clear the input bit accumulator */
+#define INITBITS() \
+ do { \
+ hold = 0; \
+ bits = 0; \
+ } while (0)
+
+/* Get a byte of input into the bit accumulator, or return from inflate()
+ if there is no input available. */
+#define PULLBYTE() \
+ do { \
+ if (have == 0) goto inf_leave; \
+ have--; \
+ hold += (unsigned long)(*next++) << bits; \
+ bits += 8; \
+ } while (0)
+
+/* Assure that there are at least n bits in the bit accumulator. If there is
+ not enough available input to do that, then return from inflate(). */
+#define NEEDBITS(n) \
+ do { \
+ while (bits < (unsigned)(n)) \
+ PULLBYTE(); \
+ } while (0)
+
+/* Return the low n bits of the bit accumulator (n < 16) */
+#define BITS(n) \
+ ((unsigned)hold & ((1U << (n)) - 1))
+
+/* Remove n bits from the bit accumulator */
+#define DROPBITS(n) \
+ do { \
+ hold >>= (n); \
+ bits -= (unsigned)(n); \
+ } while (0)
+
+/* Remove zero to seven bits as needed to go to a byte boundary */
+#define BYTEBITS() \
+ do { \
+ hold >>= bits & 7; \
+ bits -= bits & 7; \
+ } while (0)
+
+/* Reverse the bytes in a 32-bit value */
+#define REVERSE(q) \
+ ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
+ (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
+
+/*
+ inflate() uses a state machine to process as much input data and generate as
+ much output data as possible before returning. The state machine is
+ structured roughly as follows:
+
+ for (;;) switch (state) {
+ ...
+ case STATEn:
+ if (not enough input data or output space to make progress)
+ return;
+ ... make progress ...
+ state = STATEm;
+ break;
+ ...
+ }
+
+ so when inflate() is called again, the same case is attempted again, and
+ if the appropriate resources are provided, the machine proceeds to the
+ next state. The NEEDBITS() macro is usually the way the state evaluates
+ whether it can proceed or should return. NEEDBITS() does the return if
+ the requested bits are not available. The typical use of the BITS macros
+ is:
+
+ NEEDBITS(n);
+ ... do something with BITS(n) ...
+ DROPBITS(n);
+
+ where NEEDBITS(n) either returns from inflate() if there isn't enough
+ input left to load n bits into the accumulator, or it continues. BITS(n)
+ gives the low n bits in the accumulator. When done, DROPBITS(n) drops
+ the low n bits off the accumulator. INITBITS() clears the accumulator
+ and sets the number of available bits to zero. BYTEBITS() discards just
+ enough bits to put the accumulator on a byte boundary. After BYTEBITS()
+ and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
+
+ NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
+ if there is no input available. The decoding of variable length codes uses
+ PULLBYTE() directly in order to pull just enough bytes to decode the next
+ code, and no more.
+
+ Some states loop until they get enough input, making sure that enough
+ state information is maintained to continue the loop where it left off
+ if NEEDBITS() returns in the loop. For example, want, need, and keep
+ would all have to actually be part of the saved state in case NEEDBITS()
+ returns:
+
+ case STATEw:
+ while (want < need) {
+ NEEDBITS(n);
+ keep[want++] = BITS(n);
+ DROPBITS(n);
+ }
+ state = STATEx;
+ case STATEx:
+
+ As shown above, if the next state is also the next case, then the break
+ is omitted.
+
+ A state may also return if there is not enough output space available to
+ complete that state. Those states are copying stored data, writing a
+ literal byte, and copying a matching string.
+
+ When returning, a "goto inf_leave" is used to update the total counters,
+ update the check value, and determine whether any progress has been made
+ during that inflate() call in order to return the proper return code.
+ Progress is defined as a change in either strm->avail_in or strm->avail_out.
+ When there is a window, goto inf_leave will update the window with the last
+ output written. If a goto inf_leave occurs in the middle of decompression
+ and there is no window currently, goto inf_leave will create one and copy
+ output to the window for the next call of inflate().
+
+ In this implementation, the flush parameter of inflate() only affects the
+ return code (per zlib.h). inflate() always writes as much as possible to
+ strm->next_out, given the space available and the provided input--the effect
+ documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers
+ the allocation of and copying into a sliding window until necessary, which
+ provides the effect documented in zlib.h for Z_FINISH when the entire input
+ stream available. So the only thing the flush parameter actually does is:
+ when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it
+ will return Z_BUF_ERROR if it has not reached the end of the stream.
+ */
+
+int ZEXPORT inflate(strm, flush)
+z_streamp strm;
+int flush;
+{
+ struct inflate_state FAR *state;
+ unsigned char FAR *next; /* next input */
+ unsigned char FAR *put; /* next output */
+ unsigned have, left; /* available input and output */
+ unsigned long hold; /* bit buffer */
+ unsigned bits; /* bits in bit buffer */
+ unsigned in, out; /* save starting available input and output */
+ unsigned copy; /* number of stored or match bytes to copy */
+ unsigned char FAR *from; /* where to copy match bytes from */
+ code this; /* current decoding table entry */
+ code last; /* parent table entry */
+ unsigned len; /* length to copy for repeats, bits to drop */
+ int ret; /* return code */
+#ifdef GUNZIP
+ unsigned char hbuf[4]; /* buffer for gzip header crc calculation */
+#endif
+ static const unsigned short order[19] = /* permutation of code lengths */
+ {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+ if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL ||
+ (strm->next_in == Z_NULL && strm->avail_in != 0))
+ return Z_STREAM_ERROR;
+
+ state = (struct inflate_state FAR *)strm->state;
+ if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */
+ LOAD();
+ in = have;
+ out = left;
+ ret = Z_OK;
+ for (;;)
+ switch (state->mode) {
+ case HEAD:
+ if (state->wrap == 0) {
+ state->mode = TYPEDO;
+ break;
+ }
+ NEEDBITS(16);
+#ifdef GUNZIP
+ if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */
+ state->check = crc32(0L, Z_NULL, 0);
+ CRC2(state->check, hold);
+ INITBITS();
+ state->mode = FLAGS;
+ break;
+ }
+ state->flags = 0; /* expect zlib header */
+ if (state->head != Z_NULL)
+ state->head->done = -1;
+ if (!(state->wrap & 1) || /* check if zlib header allowed */
+#else
+ if (
+#endif
+ ((BITS(8) << 8) + (hold >> 8)) % 31) {
+ strm->msg = (char *)"incorrect header check";
+ state->mode = BAD;
+ break;
+ }
+ if (BITS(4) != Z_DEFLATED) {
+ strm->msg = (char *)"unknown compression method";
+ state->mode = BAD;
+ break;
+ }
+ DROPBITS(4);
+ len = BITS(4) + 8;
+ if (len > state->wbits) {
+ strm->msg = (char *)"invalid window size";
+ state->mode = BAD;
+ break;
+ }
+ state->dmax = 1U << len;
+ Tracev((stderr, "inflate: zlib header ok\n"));
+ strm->adler = state->check = adler32(0L, Z_NULL, 0);
+ state->mode = hold & 0x200 ? DICTID : TYPE;
+ INITBITS();
+ break;
+#ifdef GUNZIP
+ case FLAGS:
+ NEEDBITS(16);
+ state->flags = (int)(hold);
+ if ((state->flags & 0xff) != Z_DEFLATED) {
+ strm->msg = (char *)"unknown compression method";
+ state->mode = BAD;
+ break;
+ }
+ if (state->flags & 0xe000) {
+ strm->msg = (char *)"unknown header flags set";
+ state->mode = BAD;
+ break;
+ }
+ if (state->head != Z_NULL)
+ state->head->text = (int)((hold >> 8) & 1);
+ if (state->flags & 0x0200) CRC2(state->check, hold);
+ INITBITS();
+ state->mode = TIME;
+ case TIME:
+ NEEDBITS(32);
+ if (state->head != Z_NULL)
+ state->head->time = hold;
+ if (state->flags & 0x0200) CRC4(state->check, hold);
+ INITBITS();
+ state->mode = OS;
+ case OS:
+ NEEDBITS(16);
+ if (state->head != Z_NULL) {
+ state->head->xflags = (int)(hold & 0xff);
+ state->head->os = (int)(hold >> 8);
+ }
+ if (state->flags & 0x0200) CRC2(state->check, hold);
+ INITBITS();
+ state->mode = EXLEN;
+ case EXLEN:
+ if (state->flags & 0x0400) {
+ NEEDBITS(16);
+ state->length = (unsigned)(hold);
+ if (state->head != Z_NULL)
+ state->head->extra_len = (unsigned)hold;
+ if (state->flags & 0x0200) CRC2(state->check, hold);
+ INITBITS();
+ }
+ else if (state->head != Z_NULL)
+ state->head->extra = Z_NULL;
+ state->mode = EXTRA;
+ case EXTRA:
+ if (state->flags & 0x0400) {
+ copy = state->length;
+ if (copy > have) copy = have;
+ if (copy) {
+ if (state->head != Z_NULL &&
+ state->head->extra != Z_NULL) {
+ len = state->head->extra_len - state->length;
+ zmemcpy(state->head->extra + len, next,
+ len + copy > state->head->extra_max ?
+ state->head->extra_max - len : copy);
+ }
+ if (state->flags & 0x0200)
+ state->check = crc32(state->check, next, copy);
+ have -= copy;
+ next += copy;
+ state->length -= copy;
+ }
+ if (state->length) goto inf_leave;
+ }
+ state->length = 0;
+ state->mode = NAME;
+ case NAME:
+ if (state->flags & 0x0800) {
+ if (have == 0) goto inf_leave;
+ copy = 0;
+ do {
+ len = (unsigned)(next[copy++]);
+ if (state->head != Z_NULL &&
+ state->head->name != Z_NULL &&
+ state->length < state->head->name_max)
+ state->head->name[state->length++] = len;
+ } while (len && copy < have);
+ if (state->flags & 0x0200)
+ state->check = crc32(state->check, next, copy);
+ have -= copy;
+ next += copy;
+ if (len) goto inf_leave;
+ }
+ else if (state->head != Z_NULL)
+ state->head->name = Z_NULL;
+ state->length = 0;
+ state->mode = COMMENT;
+ case COMMENT:
+ if (state->flags & 0x1000) {
+ if (have == 0) goto inf_leave;
+ copy = 0;
+ do {
+ len = (unsigned)(next[copy++]);
+ if (state->head != Z_NULL &&
+ state->head->comment != Z_NULL &&
+ state->length < state->head->comm_max)
+ state->head->comment[state->length++] = len;
+ } while (len && copy < have);
+ if (state->flags & 0x0200)
+ state->check = crc32(state->check, next, copy);
+ have -= copy;
+ next += copy;
+ if (len) goto inf_leave;
+ }
+ else if (state->head != Z_NULL)
+ state->head->comment = Z_NULL;
+ state->mode = HCRC;
+ case HCRC:
+ if (state->flags & 0x0200) {
+ NEEDBITS(16);
+ if (hold != (state->check & 0xffff)) {
+ strm->msg = (char *)"header crc mismatch";
+ state->mode = BAD;
+ break;
+ }
+ INITBITS();
+ }
+ if (state->head != Z_NULL) {
+ state->head->hcrc = (int)((state->flags >> 9) & 1);
+ state->head->done = 1;
+ }
+ strm->adler = state->check = crc32(0L, Z_NULL, 0);
+ state->mode = TYPE;
+ break;
+#endif
+ case DICTID:
+ NEEDBITS(32);
+ strm->adler = state->check = REVERSE(hold);
+ INITBITS();
+ state->mode = DICT;
+ case DICT:
+ if (state->havedict == 0) {
+ RESTORE();
+ return Z_NEED_DICT;
+ }
+ strm->adler = state->check = adler32(0L, Z_NULL, 0);
+ state->mode = TYPE;
+ case TYPE:
+ if (flush == Z_BLOCK) goto inf_leave;
+ case TYPEDO:
+ if (state->last) {
+ BYTEBITS();
+ state->mode = CHECK;
+ break;
+ }
+ NEEDBITS(3);
+ state->last = BITS(1);
+ DROPBITS(1);
+ switch (BITS(2)) {
+ case 0: /* stored block */
+ Tracev((stderr, "inflate: stored block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = STORED;
+ break;
+ case 1: /* fixed block */
+ fixedtables(state);
+ Tracev((stderr, "inflate: fixed codes block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = LEN; /* decode codes */
+ break;
+ case 2: /* dynamic block */
+ Tracev((stderr, "inflate: dynamic codes block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = TABLE;
+ break;
+ case 3:
+ strm->msg = (char *)"invalid block type";
+ state->mode = BAD;
+ }
+ DROPBITS(2);
+ break;
+ case STORED:
+ BYTEBITS(); /* go to byte boundary */
+ NEEDBITS(32);
+ if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
+ strm->msg = (char *)"invalid stored block lengths";
+ state->mode = BAD;
+ break;
+ }
+ state->length = (unsigned)hold & 0xffff;
+ Tracev((stderr, "inflate: stored length %u\n",
+ state->length));
+ INITBITS();
+ state->mode = COPY;
+ case COPY:
+ copy = state->length;
+ if (copy) {
+ if (copy > have) copy = have;
+ if (copy > left) copy = left;
+ if (copy == 0) goto inf_leave;
+ zmemcpy(put, next, copy);
+ have -= copy;
+ next += copy;
+ left -= copy;
+ put += copy;
+ state->length -= copy;
+ break;
+ }
+ Tracev((stderr, "inflate: stored end\n"));
+ state->mode = TYPE;
+ break;
+ case TABLE:
+ NEEDBITS(14);
+ state->nlen = BITS(5) + 257;
+ DROPBITS(5);
+ state->ndist = BITS(5) + 1;
+ DROPBITS(5);
+ state->ncode = BITS(4) + 4;
+ DROPBITS(4);
+#ifndef PKZIP_BUG_WORKAROUND
+ if (state->nlen > 286 || state->ndist > 30) {
+ strm->msg = (char *)"too many length or distance symbols";
+ state->mode = BAD;
+ break;
+ }
+#endif
+ Tracev((stderr, "inflate: table sizes ok\n"));
+ state->have = 0;
+ state->mode = LENLENS;
+ case LENLENS:
+ while (state->have < state->ncode) {
+ NEEDBITS(3);
+ state->lens[order[state->have++]] = (unsigned short)BITS(3);
+ DROPBITS(3);
+ }
+ while (state->have < 19)
+ state->lens[order[state->have++]] = 0;
+ state->next = state->codes;
+ state->lencode = (code const FAR *)(state->next);
+ state->lenbits = 7;
+ ret = inflate_table(CODES, state->lens, 19, &(state->next),
+ &(state->lenbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid code lengths set";
+ state->mode = BAD;
+ break;
+ }
+ Tracev((stderr, "inflate: code lengths ok\n"));
+ state->have = 0;
+ state->mode = CODELENS;
+ case CODELENS:
+ while (state->have < state->nlen + state->ndist) {
+ for (;;) {
+ this = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if (this.val < 16) {
+ NEEDBITS(this.bits);
+ DROPBITS(this.bits);
+ state->lens[state->have++] = this.val;
+ }
+ else {
+ if (this.val == 16) {
+ NEEDBITS(this.bits + 2);
+ DROPBITS(this.bits);
+ if (state->have == 0) {
+ strm->msg = (char *)"invalid bit length repeat";
+ state->mode = BAD;
+ break;
+ }
+ len = state->lens[state->have - 1];
+ copy = 3 + BITS(2);
+ DROPBITS(2);
+ }
+ else if (this.val == 17) {
+ NEEDBITS(this.bits + 3);
+ DROPBITS(this.bits);
+ len = 0;
+ copy = 3 + BITS(3);
+ DROPBITS(3);
+ }
+ else {
+ NEEDBITS(this.bits + 7);
+ DROPBITS(this.bits);
+ len = 0;
+ copy = 11 + BITS(7);
+ DROPBITS(7);
+ }
+ if (state->have + copy > state->nlen + state->ndist) {
+ strm->msg = (char *)"invalid bit length repeat";
+ state->mode = BAD;
+ break;
+ }
+ while (copy--)
+ state->lens[state->have++] = (unsigned short)len;
+ }
+ }
+
+ /* handle error breaks in while */
+ if (state->mode == BAD) break;
+
+ /* build code tables */
+ state->next = state->codes;
+ state->lencode = (code const FAR *)(state->next);
+ state->lenbits = 9;
+ ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
+ &(state->lenbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid literal/lengths set";
+ state->mode = BAD;
+ break;
+ }
+ state->distcode = (code const FAR *)(state->next);
+ state->distbits = 6;
+ ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
+ &(state->next), &(state->distbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid distances set";
+ state->mode = BAD;
+ break;
+ }
+ Tracev((stderr, "inflate: codes ok\n"));
+ state->mode = LEN;
+ case LEN:
+ if (have >= 6 && left >= 258) {
+ RESTORE();
+ inflate_fast(strm, out);
+ LOAD();
+ break;
+ }
+ for (;;) {
+ this = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if (this.op && (this.op & 0xf0) == 0) {
+ last = this;
+ for (;;) {
+ this = state->lencode[last.val +
+ (BITS(last.bits + last.op) >> last.bits)];
+ if ((unsigned)(last.bits + this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ DROPBITS(last.bits);
+ }
+ DROPBITS(this.bits);
+ state->length = (unsigned)this.val;
+ if ((int)(this.op) == 0) {
+ Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
+ "inflate: literal '%c'\n" :
+ "inflate: literal 0x%02x\n", this.val));
+ state->mode = LIT;
+ break;
+ }
+ if (this.op & 32) {
+ Tracevv((stderr, "inflate: end of block\n"));
+ state->mode = TYPE;
+ break;
+ }
+ if (this.op & 64) {
+ strm->msg = (char *)"invalid literal/length code";
+ state->mode = BAD;
+ break;
+ }
+ state->extra = (unsigned)(this.op) & 15;
+ state->mode = LENEXT;
+ case LENEXT:
+ if (state->extra) {
+ NEEDBITS(state->extra);
+ state->length += BITS(state->extra);
+ DROPBITS(state->extra);
+ }
+ Tracevv((stderr, "inflate: length %u\n", state->length));
+ state->mode = DIST;
+ case DIST:
+ for (;;) {
+ this = state->distcode[BITS(state->distbits)];
+ if ((unsigned)(this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if ((this.op & 0xf0) == 0) {
+ last = this;
+ for (;;) {
+ this = state->distcode[last.val +
+ (BITS(last.bits + last.op) >> last.bits)];
+ if ((unsigned)(last.bits + this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ DROPBITS(last.bits);
+ }
+ DROPBITS(this.bits);
+ if (this.op & 64) {
+ strm->msg = (char *)"invalid distance code";
+ state->mode = BAD;
+ break;
+ }
+ state->offset = (unsigned)this.val;
+ state->extra = (unsigned)(this.op) & 15;
+ state->mode = DISTEXT;
+ case DISTEXT:
+ if (state->extra) {
+ NEEDBITS(state->extra);
+ state->offset += BITS(state->extra);
+ DROPBITS(state->extra);
+ }
+#ifdef INFLATE_STRICT
+ if (state->offset > state->dmax) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+#endif
+ if (state->offset > state->whave + out - left) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+ Tracevv((stderr, "inflate: distance %u\n", state->offset));
+ state->mode = MATCH;
+ case MATCH:
+ if (left == 0) goto inf_leave;
+ copy = out - left;
+ if (state->offset > copy) { /* copy from window */
+ copy = state->offset - copy;
+ if (copy > state->write) {
+ copy -= state->write;
+ from = state->window + (state->wsize - copy);
+ }
+ else
+ from = state->window + (state->write - copy);
+ if (copy > state->length) copy = state->length;
+ }
+ else { /* copy from output */
+ from = put - state->offset;
+ copy = state->length;
+ }
+ if (copy > left) copy = left;
+ left -= copy;
+ state->length -= copy;
+ do {
+ *put++ = *from++;
+ } while (--copy);
+ if (state->length == 0) state->mode = LEN;
+ break;
+ case LIT:
+ if (left == 0) goto inf_leave;
+ *put++ = (unsigned char)(state->length);
+ left--;
+ state->mode = LEN;
+ break;
+ case CHECK:
+ if (state->wrap) {
+ NEEDBITS(32);
+ out -= left;
+ strm->total_out += out;
+ state->total += out;
+ if (out)
+ strm->adler = state->check =
+ UPDATE(state->check, put - out, out);
+ out = left;
+ if ((
+#ifdef GUNZIP
+ state->flags ? hold :
+#endif
+ REVERSE(hold)) != state->check) {
+ strm->msg = (char *)"incorrect data check";
+ state->mode = BAD;
+ break;
+ }
+ INITBITS();
+ Tracev((stderr, "inflate: check matches trailer\n"));
+ }
+#ifdef GUNZIP
+ state->mode = LENGTH;
+ case LENGTH:
+ if (state->wrap && state->flags) {
+ NEEDBITS(32);
+ if (hold != (state->total & 0xffffffffUL)) {
+ strm->msg = (char *)"incorrect length check";
+ state->mode = BAD;
+ break;
+ }
+ INITBITS();
+ Tracev((stderr, "inflate: length matches trailer\n"));
+ }
+#endif
+ state->mode = DONE;
+ case DONE:
+ ret = Z_STREAM_END;
+ goto inf_leave;
+ case BAD:
+ ret = Z_DATA_ERROR;
+ goto inf_leave;
+ case MEM:
+ return Z_MEM_ERROR;
+ case SYNC:
+ default:
+ return Z_STREAM_ERROR;
+ }
+
+ /*
+ Return from inflate(), updating the total counts and the check value.
+ If there was no progress during the inflate() call, return a buffer
+ error. Call updatewindow() to create and/or update the window state.
+ Note: a memory error from inflate() is non-recoverable.
+ */
+ inf_leave:
+ RESTORE();
+ if (state->wsize || (state->mode < CHECK && out != strm->avail_out))
+ if (updatewindow(strm, out)) {
+ state->mode = MEM;
+ return Z_MEM_ERROR;
+ }
+ in -= strm->avail_in;
+ out -= strm->avail_out;
+ strm->total_in += in;
+ strm->total_out += out;
+ state->total += out;
+ if (state->wrap && out)
+ strm->adler = state->check =
+ UPDATE(state->check, strm->next_out - out, out);
+ strm->data_type = state->bits + (state->last ? 64 : 0) +
+ (state->mode == TYPE ? 128 : 0);
+ if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
+ ret = Z_BUF_ERROR;
+ return ret;
+}
+
+int ZEXPORT inflateEnd(strm)
+z_streamp strm;
+{
+ struct inflate_state FAR *state;
+ if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
+ return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if (state->window != Z_NULL) ZFREE(strm, state->window);
+ ZFREE(strm, strm->state);
+ strm->state = Z_NULL;
+ Tracev((stderr, "inflate: end\n"));
+ return Z_OK;
+}
+
+int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
+z_streamp strm;
+const Bytef *dictionary;
+uInt dictLength;
+{
+ struct inflate_state FAR *state;
+ unsigned long id;
+
+ /* check state */
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if (state->wrap != 0 && state->mode != DICT)
+ return Z_STREAM_ERROR;
+
+ /* check for correct dictionary id */
+ if (state->mode == DICT) {
+ id = adler32(0L, Z_NULL, 0);
+ id = adler32(id, dictionary, dictLength);
+ if (id != state->check)
+ return Z_DATA_ERROR;
+ }
+
+ /* copy dictionary to window */
+ if (updatewindow(strm, strm->avail_out)) {
+ state->mode = MEM;
+ return Z_MEM_ERROR;
+ }
+ if (dictLength > state->wsize) {
+ zmemcpy(state->window, dictionary + dictLength - state->wsize,
+ state->wsize);
+ state->whave = state->wsize;
+ }
+ else {
+ zmemcpy(state->window + state->wsize - dictLength, dictionary,
+ dictLength);
+ state->whave = dictLength;
+ }
+ state->havedict = 1;
+ Tracev((stderr, "inflate: dictionary set\n"));
+ return Z_OK;
+}
+
+int ZEXPORT inflateGetHeader(strm, head)
+z_streamp strm;
+gz_headerp head;
+{
+ struct inflate_state FAR *state;
+
+ /* check state */
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;
+
+ /* save header structure */
+ state->head = head;
+ head->done = 0;
+ return Z_OK;
+}
+
+/*
+ Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found
+ or when out of input. When called, *have is the number of pattern bytes
+ found in order so far, in 0..3. On return *have is updated to the new
+ state. If on return *have equals four, then the pattern was found and the
+ return value is how many bytes were read including the last byte of the
+ pattern. If *have is less than four, then the pattern has not been found
+ yet and the return value is len. In the latter case, syncsearch() can be
+ called again with more data and the *have state. *have is initialized to
+ zero for the first call.
+ */
+local unsigned syncsearch(have, buf, len)
+unsigned FAR *have;
+unsigned char FAR *buf;
+unsigned len;
+{
+ unsigned got;
+ unsigned next;
+
+ got = *have;
+ next = 0;
+ while (next < len && got < 4) {
+ if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))
+ got++;
+ else if (buf[next])
+ got = 0;
+ else
+ got = 4 - got;
+ next++;
+ }
+ *have = got;
+ return next;
+}
+
+int ZEXPORT inflateSync(strm)
+z_streamp strm;
+{
+ unsigned len; /* number of bytes to look at or looked at */
+ unsigned long in, out; /* temporary to save total_in and total_out */
+ unsigned char buf[4]; /* to restore bit buffer to byte string */
+ struct inflate_state FAR *state;
+
+ /* check parameters */
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
+
+ /* if first time, start search in bit buffer */
+ if (state->mode != SYNC) {
+ state->mode = SYNC;
+ state->hold <<= state->bits & 7;
+ state->bits -= state->bits & 7;
+ len = 0;
+ while (state->bits >= 8) {
+ buf[len++] = (unsigned char)(state->hold);
+ state->hold >>= 8;
+ state->bits -= 8;
+ }
+ state->have = 0;
+ syncsearch(&(state->have), buf, len);
+ }
+
+ /* search available input */
+ len = syncsearch(&(state->have), strm->next_in, strm->avail_in);
+ strm->avail_in -= len;
+ strm->next_in += len;
+ strm->total_in += len;
+
+ /* return no joy or set up to restart inflate() on a new block */
+ if (state->have != 4) return Z_DATA_ERROR;
+ in = strm->total_in; out = strm->total_out;
+ inflateReset(strm);
+ strm->total_in = in; strm->total_out = out;
+ state->mode = TYPE;
+ return Z_OK;
+}
+
+/*
+ Returns true if inflate is currently at the end of a block generated by
+ Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
+ implementation to provide an additional safety check. PPP uses
+ Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
+ block. When decompressing, PPP checks that at the end of input packet,
+ inflate is waiting for these length bytes.
+ */
+int ZEXPORT inflateSyncPoint(strm)
+z_streamp strm;
+{
+ struct inflate_state FAR *state;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ return state->mode == STORED && state->bits == 0;
+}
+
+int ZEXPORT inflateCopy(dest, source)
+z_streamp dest;
+z_streamp source;
+{
+ struct inflate_state FAR *state;
+ struct inflate_state FAR *copy;
+ unsigned char FAR *window;
+ unsigned wsize;
+
+ /* check input */
+ if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL ||
+ source->zalloc == (alloc_func)0 || source->zfree == (free_func)0)
+ return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)source->state;
+
+ /* allocate space */
+ copy = (struct inflate_state FAR *)
+ ZALLOC(source, 1, sizeof(struct inflate_state));
+ if (copy == Z_NULL) return Z_MEM_ERROR;
+ window = Z_NULL;
+ if (state->window != Z_NULL) {
+ window = (unsigned char FAR *)
+ ZALLOC(source, 1U << state->wbits, sizeof(unsigned char));
+ if (window == Z_NULL) {
+ ZFREE(source, copy);
+ return Z_MEM_ERROR;
+ }
+ }
+
+ /* copy state */
+ zmemcpy(dest, source, sizeof(z_stream));
+ zmemcpy(copy, state, sizeof(struct inflate_state));
+ if (state->lencode >= state->codes &&
+ state->lencode <= state->codes + ENOUGH - 1) {
+ copy->lencode = copy->codes + (state->lencode - state->codes);
+ copy->distcode = copy->codes + (state->distcode - state->codes);
+ }
+ copy->next = copy->codes + (state->next - state->codes);
+ if (window != Z_NULL) {
+ wsize = 1U << state->wbits;
+ zmemcpy(window, state->window, wsize);
+ }
+ copy->window = window;
+ dest->state = (struct internal_state FAR *)copy;
+ return Z_OK;
+}
diff --git a/Utilities/cmzlib/inflate.h b/Utilities/cmzlib/inflate.h
new file mode 100644
index 000000000..07bd3e78a
--- /dev/null
+++ b/Utilities/cmzlib/inflate.h
@@ -0,0 +1,115 @@
+/* inflate.h -- internal inflate state definition
+ * Copyright (C) 1995-2004 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* define NO_GZIP when compiling if you want to disable gzip header and
+ trailer decoding by inflate(). NO_GZIP would be used to avoid linking in
+ the crc code when it is not needed. For shared libraries, gzip decoding
+ should be left enabled. */
+#ifndef NO_GZIP
+# define GUNZIP
+#endif
+
+/* Possible inflate modes between inflate() calls */
+typedef enum {
+ HEAD, /* i: waiting for magic header */
+ FLAGS, /* i: waiting for method and flags (gzip) */
+ TIME, /* i: waiting for modification time (gzip) */
+ OS, /* i: waiting for extra flags and operating system (gzip) */
+ EXLEN, /* i: waiting for extra length (gzip) */
+ EXTRA, /* i: waiting for extra bytes (gzip) */
+ NAME, /* i: waiting for end of file name (gzip) */
+ COMMENT, /* i: waiting for end of comment (gzip) */
+ HCRC, /* i: waiting for header crc (gzip) */
+ DICTID, /* i: waiting for dictionary check value */
+ DICT, /* waiting for inflateSetDictionary() call */
+ TYPE, /* i: waiting for type bits, including last-flag bit */
+ TYPEDO, /* i: same, but skip check to exit inflate on new block */
+ STORED, /* i: waiting for stored size (length and complement) */
+ COPY, /* i/o: waiting for input or output to copy stored block */
+ TABLE, /* i: waiting for dynamic block table lengths */
+ LENLENS, /* i: waiting for code length code lengths */
+ CODELENS, /* i: waiting for length/lit and distance code lengths */
+ LEN, /* i: waiting for length/lit code */
+ LENEXT, /* i: waiting for length extra bits */
+ DIST, /* i: waiting for distance code */
+ DISTEXT, /* i: waiting for distance extra bits */
+ MATCH, /* o: waiting for output space to copy string */
+ LIT, /* o: waiting for output space to write literal */
+ CHECK, /* i: waiting for 32-bit check value */
+ LENGTH, /* i: waiting for 32-bit length (gzip) */
+ DONE, /* finished check, done -- remain here until reset */
+ BAD, /* got a data error -- remain here until reset */
+ MEM, /* got an inflate() memory error -- remain here until reset */
+ SYNC /* looking for synchronization bytes to restart inflate() */
+} inflate_mode;
+
+/*
+ State transitions between above modes -
+
+ (most modes can go to the BAD or MEM mode -- not shown for clarity)
+
+ Process header:
+ HEAD -> (gzip) or (zlib)
+ (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME
+ NAME -> COMMENT -> HCRC -> TYPE
+ (zlib) -> DICTID or TYPE
+ DICTID -> DICT -> TYPE
+ Read deflate blocks:
+ TYPE -> STORED or TABLE or LEN or CHECK
+ STORED -> COPY -> TYPE
+ TABLE -> LENLENS -> CODELENS -> LEN
+ Read deflate codes:
+ LEN -> LENEXT or LIT or TYPE
+ LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
+ LIT -> LEN
+ Process trailer:
+ CHECK -> LENGTH -> DONE
+ */
+
+/* state maintained between inflate() calls. Approximately 7K bytes. */
+struct inflate_state {
+ inflate_mode mode; /* current inflate mode */
+ int last; /* true if processing last block */
+ int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
+ int havedict; /* true if dictionary provided */
+ int flags; /* gzip header method and flags (0 if zlib) */
+ unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
+ unsigned long check; /* protected copy of check value */
+ unsigned long total; /* protected copy of output count */
+ gz_headerp head; /* where to save gzip header information */
+ /* sliding window */
+ unsigned wbits; /* log base 2 of requested window size */
+ unsigned wsize; /* window size or zero if not using window */
+ unsigned whave; /* valid bytes in the window */
+ unsigned write; /* window write index */
+ unsigned char FAR *window; /* allocated sliding window, if needed */
+ /* bit accumulator */
+ unsigned long hold; /* input bit accumulator */
+ unsigned bits; /* number of bits in "in" */
+ /* for string and stored block copying */
+ unsigned length; /* literal or length of data to copy */
+ unsigned offset; /* distance back to copy string from */
+ /* for table and code decoding */
+ unsigned extra; /* extra bits needed */
+ /* fixed and dynamic code tables */
+ code const FAR *lencode; /* starting table for length/literal codes */
+ code const FAR *distcode; /* starting table for distance codes */
+ unsigned lenbits; /* index bits for lencode */
+ unsigned distbits; /* index bits for distcode */
+ /* dynamic table building */
+ unsigned ncode; /* number of code length code lengths */
+ unsigned nlen; /* number of length code lengths */
+ unsigned ndist; /* number of distance code lengths */
+ unsigned have; /* number of code lengths in lens[] */
+ code FAR *next; /* next available space in codes[] */
+ unsigned short lens[320]; /* temporary storage for code lengths */
+ unsigned short work[288]; /* work area for code table building */
+ code codes[ENOUGH]; /* space for code tables */
+};
diff --git a/Utilities/cmzlib/inftrees.c b/Utilities/cmzlib/inftrees.c
new file mode 100644
index 000000000..8a9c13ff0
--- /dev/null
+++ b/Utilities/cmzlib/inftrees.c
@@ -0,0 +1,329 @@
+/* inftrees.c -- generate Huffman trees for efficient decoding
+ * Copyright (C) 1995-2005 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+
+#define MAXBITS 15
+
+const char inflate_copyright[] =
+ " inflate 1.2.3 Copyright 1995-2005 Mark Adler ";
+/*
+ If you use the zlib library in a product, an acknowledgment is welcome
+ in the documentation of your product. If for some reason you cannot
+ include such an acknowledgment, I would appreciate that you keep this
+ copyright string in the executable of your product.
+ */
+
+/*
+ Build a set of tables to decode the provided canonical Huffman code.
+ The code lengths are lens[0..codes-1]. The result starts at *table,
+ whose indices are 0..2^bits-1. work is a writable array of at least
+ lens shorts, which is used as a work area. type is the type of code
+ to be generated, CODES, LENS, or DISTS. On return, zero is success,
+ -1 is an invalid code, and +1 means that ENOUGH isn't enough. table
+ on return points to the next available entry's address. bits is the
+ requested root table index bits, and on return it is the actual root
+ table index bits. It will differ if the request is greater than the
+ longest code or if it is less than the shortest code.
+ */
+int inflate_table(type, lens, codes, table, bits, work)
+codetype type;
+unsigned short FAR *lens;
+unsigned codes;
+code FAR * FAR *table;
+unsigned FAR *bits;
+unsigned short FAR *work;
+{
+ unsigned len; /* a code's length in bits */
+ unsigned sym; /* index of code symbols */
+ unsigned min, max; /* minimum and maximum code lengths */
+ unsigned root; /* number of index bits for root table */
+ unsigned curr; /* number of index bits for current table */
+ unsigned drop; /* code bits to drop for sub-table */
+ int left; /* number of prefix codes available */
+ unsigned used; /* code entries in table used */
+ unsigned huff; /* Huffman code */
+ unsigned incr; /* for incrementing code, index */
+ unsigned fill; /* index for replicating entries */
+ unsigned low; /* low bits for current root entry */
+ unsigned mask; /* mask for low root bits */
+ code this; /* table entry for duplication */
+ code FAR *next; /* next available space in table */
+ const unsigned short FAR *base; /* base value table to use */
+ const unsigned short FAR *extra; /* extra bits table to use */
+ int end; /* use base and extra for symbol > end */
+ unsigned short count[MAXBITS+1]; /* number of codes of each length */
+ unsigned short offs[MAXBITS+1]; /* offsets in table for each length */
+ static const unsigned short lbase[31] = { /* Length codes 257..285 base */
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+ 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
+ static const unsigned short lext[31] = { /* Length codes 257..285 extra */
+ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
+ 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196};
+ static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
+ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+ 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+ 8193, 12289, 16385, 24577, 0, 0};
+ static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
+ 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
+ 23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
+ 28, 28, 29, 29, 64, 64};
+
+ /*
+ Process a set of code lengths to create a canonical Huffman code. The
+ code lengths are lens[0..codes-1]. Each length corresponds to the
+ symbols 0..codes-1. The Huffman code is generated by first sorting the
+ symbols by length from short to long, and retaining the symbol order
+ for codes with equal lengths. Then the code starts with all zero bits
+ for the first code of the shortest length, and the codes are integer
+ increments for the same length, and zeros are appended as the length
+ increases. For the deflate format, these bits are stored backwards
+ from their more natural integer increment ordering, and so when the
+ decoding tables are built in the large loop below, the integer codes
+ are incremented backwards.
+
+ This routine assumes, but does not check, that all of the entries in
+ lens[] are in the range 0..MAXBITS. The caller must assure this.
+ 1..MAXBITS is interpreted as that code length. zero means that that
+ symbol does not occur in this code.
+
+ The codes are sorted by computing a count of codes for each length,
+ creating from that a table of starting indices for each length in the
+ sorted table, and then entering the symbols in order in the sorted
+ table. The sorted table is work[], with that space being provided by
+ the caller.
+
+ The length counts are used for other purposes as well, i.e. finding
+ the minimum and maximum length codes, determining if there are any
+ codes at all, checking for a valid set of lengths, and looking ahead
+ at length counts to determine sub-table sizes when building the
+ decoding tables.
+ */
+
+ /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
+ for (len = 0; len <= MAXBITS; len++)
+ count[len] = 0;
+ for (sym = 0; sym < codes; sym++)
+ count[lens[sym]]++;
+
+ /* bound code lengths, force root to be within code lengths */
+ root = *bits;
+ for (max = MAXBITS; max >= 1; max--)
+ if (count[max] != 0) break;
+ if (root > max) root = max;
+ if (max == 0) { /* no symbols to code at all */
+ this.op = (unsigned char)64; /* invalid code marker */
+ this.bits = (unsigned char)1;
+ this.val = (unsigned short)0;
+ *(*table)++ = this; /* make a table to force an error */
+ *(*table)++ = this;
+ *bits = 1;
+ return 0; /* no symbols, but wait for decoding to report error */
+ }
+ for (min = 1; min <= MAXBITS; min++)
+ if (count[min] != 0) break;
+ if (root < min) root = min;
+
+ /* check for an over-subscribed or incomplete set of lengths */
+ left = 1;
+ for (len = 1; len <= MAXBITS; len++) {
+ left <<= 1;
+ left -= count[len];
+ if (left < 0) return -1; /* over-subscribed */
+ }
+ if (left > 0 && (type == CODES || max != 1))
+ return -1; /* incomplete set */
+
+ /* generate offsets into symbol table for each length for sorting */
+ offs[1] = 0;
+ for (len = 1; len < MAXBITS; len++)
+ offs[len + 1] = offs[len] + count[len];
+
+ /* sort symbols by length, by symbol order within each length */
+ for (sym = 0; sym < codes; sym++)
+ if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
+
+ /*
+ Create and fill in decoding tables. In this loop, the table being
+ filled is at next and has curr index bits. The code being used is huff
+ with length len. That code is converted to an index by dropping drop
+ bits off of the bottom. For codes where len is less than drop + curr,
+ those top drop + curr - len bits are incremented through all values to
+ fill the table with replicated entries.
+
+ root is the number of index bits for the root table. When len exceeds
+ root, sub-tables are created pointed to by the root entry with an index
+ of the low root bits of huff. This is saved in low to check for when a
+ new sub-table should be started. drop is zero when the root table is
+ being filled, and drop is root when sub-tables are being filled.
+
+ When a new sub-table is needed, it is necessary to look ahead in the
+ code lengths to determine what size sub-table is needed. The length
+ counts are used for this, and so count[] is decremented as codes are
+ entered in the tables.
+
+ used keeps track of how many table entries have been allocated from the
+ provided *table space. It is checked when a LENS table is being made
+ against the space in *table, ENOUGH, minus the maximum space needed by
+ the worst case distance code, MAXD. This should never happen, but the
+ sufficiency of ENOUGH has not been proven exhaustively, hence the check.
+ This assumes that when type == LENS, bits == 9.
+
+ sym increments through all symbols, and the loop terminates when
+ all codes of length max, i.e. all codes, have been processed. This
+ routine permits incomplete codes, so another loop after this one fills
+ in the rest of the decoding tables with invalid code markers.
+ */
+
+ /* set up for code type */
+ switch (type) {
+ case CODES:
+ base = extra = work; /* dummy value--not used */
+ end = 19;
+ break;
+ case LENS:
+ base = lbase;
+ base -= 257;
+ extra = lext;
+ extra -= 257;
+ end = 256;
+ break;
+ default: /* DISTS */
+ base = dbase;
+ extra = dext;
+ end = -1;
+ }
+
+ /* initialize state for loop */
+ huff = 0; /* starting code */
+ sym = 0; /* starting code symbol */
+ len = min; /* starting code length */
+ next = *table; /* current table to fill in */
+ curr = root; /* current table index bits */
+ drop = 0; /* current bits to drop from code for index */
+ low = (unsigned)(-1); /* trigger new sub-table when len > root */
+ used = 1U << root; /* use root table entries */
+ mask = used - 1; /* mask for comparing low */
+
+ /* check available table space */
+ if (type == LENS && used >= ENOUGH - MAXD)
+ return 1;
+
+ /* process all codes and make table entries */
+ for (;;) {
+ /* create table entry */
+ this.bits = (unsigned char)(len - drop);
+ if ((int)(work[sym]) < end) {
+ this.op = (unsigned char)0;
+ this.val = work[sym];
+ }
+ else if ((int)(work[sym]) > end) {
+ this.op = (unsigned char)(extra[work[sym]]);
+ this.val = base[work[sym]];
+ }
+ else {
+ this.op = (unsigned char)(32 + 64); /* end of block */
+ this.val = 0;
+ }
+
+ /* replicate for those indices with low len bits equal to huff */
+ incr = 1U << (len - drop);
+ fill = 1U << curr;
+ min = fill; /* save offset to next table */
+ do {
+ fill -= incr;
+ next[(huff >> drop) + fill] = this;
+ } while (fill != 0);
+
+ /* backwards increment the len-bit code huff */
+ incr = 1U << (len - 1);
+ while (huff & incr)
+ incr >>= 1;
+ if (incr != 0) {
+ huff &= incr - 1;
+ huff += incr;
+ }
+ else
+ huff = 0;
+
+ /* go to next symbol, update count, len */
+ sym++;
+ if (--(count[len]) == 0) {
+ if (len == max) break;
+ len = lens[work[sym]];
+ }
+
+ /* create new sub-table if needed */
+ if (len > root && (huff & mask) != low) {
+ /* if first time, transition to sub-tables */
+ if (drop == 0)
+ drop = root;
+
+ /* increment past last table */
+ next += min; /* here min is 1 << curr */
+
+ /* determine length of next table */
+ curr = len - drop;
+ left = (int)(1 << curr);
+ while (curr + drop < max) {
+ left -= count[curr + drop];
+ if (left <= 0) break;
+ curr++;
+ left <<= 1;
+ }
+
+ /* check for enough space */
+ used += 1U << curr;
+ if (type == LENS && used >= ENOUGH - MAXD)
+ return 1;
+
+ /* point entry in root table to sub-table */
+ low = huff & mask;
+ (*table)[low].op = (unsigned char)curr;
+ (*table)[low].bits = (unsigned char)root;
+ (*table)[low].val = (unsigned short)(next - *table);
+ }
+ }
+
+ /*
+ Fill in rest of table for incomplete codes. This loop is similar to the
+ loop above in incrementing huff for table indices. It is assumed that
+ len is equal to curr + drop, so there is no loop needed to increment
+ through high index bits. When the current sub-table is filled, the loop
+ drops back to the root table to fill in any remaining entries there.
+ */
+ this.op = (unsigned char)64; /* invalid code marker */
+ this.bits = (unsigned char)(len - drop);
+ this.val = (unsigned short)0;
+ while (huff != 0) {
+ /* when done with sub-table, drop back to root table */
+ if (drop != 0 && (huff & mask) != low) {
+ drop = 0;
+ len = root;
+ next = *table;
+ this.bits = (unsigned char)len;
+ }
+
+ /* put invalid code marker in table */
+ next[huff >> drop] = this;
+
+ /* backwards increment the len-bit code huff */
+ incr = 1U << (len - 1);
+ while (huff & incr)
+ incr >>= 1;
+ if (incr != 0) {
+ huff &= incr - 1;
+ huff += incr;
+ }
+ else
+ huff = 0;
+ }
+
+ /* set return parameters */
+ *table += used;
+ *bits = root;
+ return 0;
+}
diff --git a/Utilities/cmzlib/inftrees.h b/Utilities/cmzlib/inftrees.h
new file mode 100644
index 000000000..b1104c87e
--- /dev/null
+++ b/Utilities/cmzlib/inftrees.h
@@ -0,0 +1,55 @@
+/* inftrees.h -- header to use inftrees.c
+ * Copyright (C) 1995-2005 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* Structure for decoding tables. Each entry provides either the
+ information needed to do the operation requested by the code that
+ indexed that table entry, or it provides a pointer to another
+ table that indexes more bits of the code. op indicates whether
+ the entry is a pointer to another table, a literal, a length or
+ distance, an end-of-block, or an invalid code. For a table
+ pointer, the low four bits of op is the number of index bits of
+ that table. For a length or distance, the low four bits of op
+ is the number of extra bits to get after the code. bits is
+ the number of bits in this code or part of the code to drop off
+ of the bit buffer. val is the actual byte to output in the case
+ of a literal, the base length or distance, or the offset from
+ the current table to the next table. Each entry is four bytes. */
+typedef struct {
+ unsigned char op; /* operation, extra bits, table bits */
+ unsigned char bits; /* bits in this part of the code */
+ unsigned short val; /* offset in table or code value */
+} code;
+
+/* op values as set by inflate_table():
+ 00000000 - literal
+ 0000tttt - table link, tttt != 0 is the number of table index bits
+ 0001eeee - length or distance, eeee is the number of extra bits
+ 01100000 - end of block
+ 01000000 - invalid code
+ */
+
+/* Maximum size of dynamic tree. The maximum found in a long but non-
+ exhaustive search was 1444 code structures (852 for length/literals
+ and 592 for distances, the latter actually the result of an
+ exhaustive search). The true maximum is not known, but the value
+ below is more than safe. */
+#define ENOUGH 2048
+#define MAXD 592
+
+/* Type of code to build for inftable() */
+typedef enum {
+ CODES,
+ LENS,
+ DISTS
+} codetype;
+
+extern int inflate_table OF((codetype type, unsigned short FAR *lens,
+ unsigned codes, code FAR * FAR *table,
+ unsigned FAR *bits, unsigned short FAR *work));
diff --git a/Utilities/cmzlib/trees.c b/Utilities/cmzlib/trees.c
new file mode 100644
index 000000000..395e4e168
--- /dev/null
+++ b/Utilities/cmzlib/trees.c
@@ -0,0 +1,1219 @@
+/* trees.c -- output deflated data using Huffman coding
+ * Copyright (C) 1995-2005 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * ALGORITHM
+ *
+ * The "deflation" process uses several Huffman trees. The more
+ * common source values are represented by shorter bit sequences.
+ *
+ * Each code tree is stored in a compressed form which is itself
+ * a Huffman encoding of the lengths of all the code strings (in
+ * ascending order by source values). The actual code strings are
+ * reconstructed from the lengths in the inflate process, as described
+ * in the deflate specification.
+ *
+ * REFERENCES
+ *
+ * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
+ * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
+ *
+ * Storer, James A.
+ * Data Compression: Methods and Theory, pp. 49-50.
+ * Computer Science Press, 1988. ISBN 0-7167-8156-5.
+ *
+ * Sedgewick, R.
+ * Algorithms, p290.
+ * Addison-Wesley, 1983. ISBN 0-201-06672-6.
+ */
+
+/* @(#) $Id$ */
+
+/* #define GEN_TREES_H */
+
+#include "deflate.h"
+
+#ifdef DEBUG
+# include <ctype.h>
+#endif
+
+/* ===========================================================================
+ * Constants
+ */
+
+#define MAX_BL_BITS 7
+/* Bit length codes must not exceed MAX_BL_BITS bits */
+
+#define END_BLOCK 256
+/* end of block literal code */
+
+#define REP_3_6 16
+/* repeat previous bit length 3-6 times (2 bits of repeat count) */
+
+#define REPZ_3_10 17
+/* repeat a zero length 3-10 times (3 bits of repeat count) */
+
+#define REPZ_11_138 18
+/* repeat a zero length 11-138 times (7 bits of repeat count) */
+
+local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
+ = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
+
+local const int extra_dbits[D_CODES] /* extra bits for each distance code */
+ = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
+
+local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
+ = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
+
+local const uch bl_order[BL_CODES]
+ = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
+/* The lengths of the bit length codes are sent in order of decreasing
+ * probability, to avoid transmitting the lengths for unused bit length codes.
+ */
+
+#define Buf_size (8 * 2*sizeof(char))
+/* Number of bits used within bi_buf. (bi_buf might be implemented on
+ * more than 16 bits on some systems.)
+ */
+
+/* ===========================================================================
+ * Local data. These are initialized only once.
+ */
+
+#define DIST_CODE_LEN 512 /* see definition of array dist_code below */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+/* non ANSI compilers may not accept trees.h */
+
+local ct_data static_ltree[L_CODES+2];
+/* The static literal tree. Since the bit lengths are imposed, there is no
+ * need for the L_CODES extra codes used during heap construction. However
+ * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
+ * below).
+ */
+
+local ct_data static_dtree[D_CODES];
+/* The static distance tree. (Actually a trivial tree since all codes use
+ * 5 bits.)
+ */
+
+uch _dist_code[DIST_CODE_LEN];
+/* Distance codes. The first 256 values correspond to the distances
+ * 3 .. 258, the last 256 values correspond to the top 8 bits of
+ * the 15 bit distances.
+ */
+
+uch _length_code[MAX_MATCH-MIN_MATCH+1];
+/* length code for each normalized match length (0 == MIN_MATCH) */
+
+local int base_length[LENGTH_CODES];
+/* First normalized length for each code (0 = MIN_MATCH) */
+
+local int base_dist[D_CODES];
+/* First normalized distance for each code (0 = distance of 1) */
+
+#else
+# include "trees.h"
+#endif /* GEN_TREES_H */
+
+struct static_tree_desc_s {
+ const ct_data *static_tree; /* static tree or NULL */
+ const intf *extra_bits; /* extra bits for each code or NULL */
+ int extra_base; /* base index for extra_bits */
+ int elems; /* max number of elements in the tree */
+ int max_length; /* max bit length for the codes */
+};
+
+local static_tree_desc static_l_desc =
+{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
+
+local static_tree_desc static_d_desc =
+{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS};
+
+local static_tree_desc static_bl_desc =
+{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS};
+
+/* ===========================================================================
+ * Local (static) routines in this file.
+ */
+
+local void tr_static_init OF((void));
+local void init_block OF((deflate_state *s));
+local void pqdownheap OF((deflate_state *s, ct_data *tree, int k));
+local void gen_bitlen OF((deflate_state *s, tree_desc *desc));
+local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count));
+local void build_tree OF((deflate_state *s, tree_desc *desc));
+local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code));
+local void send_tree OF((deflate_state *s, ct_data *tree, int max_code));
+local int build_bl_tree OF((deflate_state *s));
+local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
+ int blcodes));
+local void compress_block OF((deflate_state *s, ct_data *ltree,
+ ct_data *dtree));
+local void set_data_type OF((deflate_state *s));
+local unsigned bi_reverse OF((unsigned value, int length));
+local void bi_windup OF((deflate_state *s));
+local void bi_flush OF((deflate_state *s));
+local void copy_block OF((deflate_state *s, charf *buf, unsigned len,
+ int header));
+
+#ifdef GEN_TREES_H
+local void gen_trees_header OF((void));
+#endif
+
+#ifndef DEBUG
+# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
+ /* Send a code of the given tree. c and tree must not have side effects */
+
+#else /* DEBUG */
+# define send_code(s, c, tree) \
+ { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
+ send_bits(s, tree[c].Code, tree[c].Len); }
+#endif
+
+/* ===========================================================================
+ * Output a short LSB first on the stream.
+ * IN assertion: there is enough room in pendingBuf.
+ */
+#define put_short(s, w) { \
+ put_byte(s, (uch)((w) & 0xff)); \
+ put_byte(s, (uch)((ush)(w) >> 8)); \
+}
+
+/* ===========================================================================
+ * Send a value on a given number of bits.
+ * IN assertion: length <= 16 and value fits in length bits.
+ */
+#ifdef DEBUG
+local void send_bits OF((deflate_state *s, int value, int length));
+
+local void send_bits(s, value, length)
+ deflate_state *s;
+ int value; /* value to send */
+ int length; /* number of bits */
+{
+ Tracevv((stderr," l %2d v %4x ", length, value));
+ Assert(length > 0 && length <= 15, "invalid length");
+ s->bits_sent += (ulg)length;
+
+ /* If not enough room in bi_buf, use (valid) bits from bi_buf and
+ * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
+ * unused bits in value.
+ */
+ if (s->bi_valid > (int)Buf_size - length) {
+ s->bi_buf |= (value << s->bi_valid);
+ put_short(s, s->bi_buf);
+ s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
+ s->bi_valid += length - Buf_size;
+ } else {
+ s->bi_buf |= value << s->bi_valid;
+ s->bi_valid += length;
+ }
+}
+#else /* !DEBUG */
+
+#define send_bits(s, value, length) \
+{ int len = length;\
+ if (s->bi_valid > (int)Buf_size - len) {\
+ int val = value;\
+ s->bi_buf |= (val << s->bi_valid);\
+ put_short(s, s->bi_buf);\
+ s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
+ s->bi_valid += len - Buf_size;\
+ } else {\
+ s->bi_buf |= (value) << s->bi_valid;\
+ s->bi_valid += len;\
+ }\
+}
+#endif /* DEBUG */
+
+
+/* the arguments must not have side effects */
+
+/* ===========================================================================
+ * Initialize the various 'constant' tables.
+ */
+local void tr_static_init()
+{
+#if defined(GEN_TREES_H) || !defined(STDC)
+ static int static_init_done = 0;
+ int n; /* iterates over tree elements */
+ int bits; /* bit counter */
+ int length; /* length value */
+ int code; /* code value */
+ int dist; /* distance index */
+ ush bl_count[MAX_BITS+1];
+ /* number of codes at each bit length for an optimal tree */
+
+ if (static_init_done) return;
+
+ /* For some embedded targets, global variables are not initialized: */
+ static_l_desc.static_tree = static_ltree;
+ static_l_desc.extra_bits = extra_lbits;
+ static_d_desc.static_tree = static_dtree;
+ static_d_desc.extra_bits = extra_dbits;
+ static_bl_desc.extra_bits = extra_blbits;
+
+ /* Initialize the mapping length (0..255) -> length code (0..28) */
+ length = 0;
+ for (code = 0; code < LENGTH_CODES-1; code++) {
+ base_length[code] = length;
+ for (n = 0; n < (1<<extra_lbits[code]); n++) {
+ _length_code[length++] = (uch)code;
+ }
+ }
+ Assert (length == 256, "tr_static_init: length != 256");
+ /* Note that the length 255 (match length 258) can be represented
+ * in two different ways: code 284 + 5 bits or code 285, so we
+ * overwrite length_code[255] to use the best encoding:
+ */
+ _length_code[length-1] = (uch)code;
+
+ /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
+ dist = 0;
+ for (code = 0 ; code < 16; code++) {
+ base_dist[code] = dist;
+ for (n = 0; n < (1<<extra_dbits[code]); n++) {
+ _dist_code[dist++] = (uch)code;
+ }
+ }
+ Assert (dist == 256, "tr_static_init: dist != 256");
+ dist >>= 7; /* from now on, all distances are divided by 128 */
+ for ( ; code < D_CODES; code++) {
+ base_dist[code] = dist << 7;
+ for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
+ _dist_code[256 + dist++] = (uch)code;
+ }
+ }
+ Assert (dist == 256, "tr_static_init: 256+dist != 512");
+
+ /* Construct the codes of the static literal tree */
+ for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
+ n = 0;
+ while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
+ while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
+ while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
+ while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
+ /* Codes 286 and 287 do not exist, but we must include them in the
+ * tree construction to get a canonical Huffman tree (longest code
+ * all ones)
+ */
+ gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
+
+ /* The static distance tree is trivial: */
+ for (n = 0; n < D_CODES; n++) {
+ static_dtree[n].Len = 5;
+ static_dtree[n].Code = bi_reverse((unsigned)n, 5);
+ }
+ static_init_done = 1;
+
+# ifdef GEN_TREES_H
+ gen_trees_header();
+# endif
+#endif /* defined(GEN_TREES_H) || !defined(STDC) */
+}
+
+/* ===========================================================================
+ * Genererate the file trees.h describing the static trees.
+ */
+#ifdef GEN_TREES_H
+# ifndef DEBUG
+# include <stdio.h>
+# endif
+
+# define SEPARATOR(i, last, width) \
+ ((i) == (last)? "\n};\n\n" : \
+ ((i) % (width) == (width)-1 ? ",\n" : ", "))
+
+void gen_trees_header()
+{
+ FILE *header = fopen("trees.h", "w");
+ int i;
+
+ Assert (header != NULL, "Can't open trees.h");
+ fprintf(header,
+ "/* header created automatically with -DGEN_TREES_H */\n\n");
+
+ fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
+ for (i = 0; i < L_CODES+2; i++) {
+ fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
+ static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
+ }
+
+ fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
+ for (i = 0; i < D_CODES; i++) {
+ fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
+ static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
+ }
+
+ fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
+ for (i = 0; i < DIST_CODE_LEN; i++) {
+ fprintf(header, "%2u%s", _dist_code[i],
+ SEPARATOR(i, DIST_CODE_LEN-1, 20));
+ }
+
+ fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
+ for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
+ fprintf(header, "%2u%s", _length_code[i],
+ SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
+ }
+
+ fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
+ for (i = 0; i < LENGTH_CODES; i++) {
+ fprintf(header, "%1u%s", base_length[i],
+ SEPARATOR(i, LENGTH_CODES-1, 20));
+ }
+
+ fprintf(header, "local const int base_dist[D_CODES] = {\n");
+ for (i = 0; i < D_CODES; i++) {
+ fprintf(header, "%5u%s", base_dist[i],
+ SEPARATOR(i, D_CODES-1, 10));
+ }
+
+ fclose(header);
+}
+#endif /* GEN_TREES_H */
+
+/* ===========================================================================
+ * Initialize the tree data structures for a new zlib stream.
+ */
+void _tr_init(s)
+ deflate_state *s;
+{
+ tr_static_init();
+
+ s->l_desc.dyn_tree = s->dyn_ltree;
+ s->l_desc.stat_desc = &static_l_desc;
+
+ s->d_desc.dyn_tree = s->dyn_dtree;
+ s->d_desc.stat_desc = &static_d_desc;
+
+ s->bl_desc.dyn_tree = s->bl_tree;
+ s->bl_desc.stat_desc = &static_bl_desc;
+
+ s->bi_buf = 0;
+ s->bi_valid = 0;
+ s->last_eob_len = 8; /* enough lookahead for inflate */
+#ifdef DEBUG
+ s->compressed_len = 0L;
+ s->bits_sent = 0L;
+#endif
+
+ /* Initialize the first block of the first file: */
+ init_block(s);
+}
+
+/* ===========================================================================
+ * Initialize a new block.
+ */
+local void init_block(s)
+ deflate_state *s;
+{
+ int n; /* iterates over tree elements */
+
+ /* Initialize the trees. */
+ for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0;
+ for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0;
+ for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
+
+ s->dyn_ltree[END_BLOCK].Freq = 1;
+ s->opt_len = s->static_len = 0L;
+ s->last_lit = s->matches = 0;
+}
+
+#define SMALLEST 1
+/* Index within the heap array of least frequent node in the Huffman tree */
+
+
+/* ===========================================================================
+ * Remove the smallest element from the heap and recreate the heap with
+ * one less element. Updates heap and heap_len.
+ */
+#define pqremove(s, tree, top) \
+{\
+ top = s->heap[SMALLEST]; \
+ s->heap[SMALLEST] = s->heap[s->heap_len--]; \
+ pqdownheap(s, tree, SMALLEST); \
+}
+
+/* ===========================================================================
+ * Compares to subtrees, using the tree depth as tie breaker when
+ * the subtrees have equal frequency. This minimizes the worst case length.
+ */
+#define smaller(tree, n, m, depth) \
+ (tree[n].Freq < tree[m].Freq || \
+ (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
+
+/* ===========================================================================
+ * Restore the heap property by moving down the tree starting at node k,
+ * exchanging a node with the smallest of its two sons if necessary, stopping
+ * when the heap property is re-established (each father smaller than its
+ * two sons).
+ */
+local void pqdownheap(s, tree, k)
+ deflate_state *s;
+ ct_data *tree; /* the tree to restore */
+ int k; /* node to move down */
+{
+ int v = s->heap[k];
+ int j = k << 1; /* left son of k */
+ while (j <= s->heap_len) {
+ /* Set j to the smallest of the two sons: */
+ if (j < s->heap_len &&
+ smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
+ j++;
+ }
+ /* Exit if v is smaller than both sons */
+ if (smaller(tree, v, s->heap[j], s->depth)) break;
+
+ /* Exchange v with the smallest son */
+ s->heap[k] = s->heap[j]; k = j;
+
+ /* And continue down the tree, setting j to the left son of k */
+ j <<= 1;
+ }
+ s->heap[k] = v;
+}
+
+/* ===========================================================================
+ * Compute the optimal bit lengths for a tree and update the total bit length
+ * for the current block.
+ * IN assertion: the fields freq and dad are set, heap[heap_max] and
+ * above are the tree nodes sorted by increasing frequency.
+ * OUT assertions: the field len is set to the optimal bit length, the
+ * array bl_count contains the frequencies for each bit length.
+ * The length opt_len is updated; static_len is also updated if stree is
+ * not null.
+ */
+local void gen_bitlen(s, desc)
+ deflate_state *s;
+ tree_desc *desc; /* the tree descriptor */
+{
+ ct_data *tree = desc->dyn_tree;
+ int max_code = desc->max_code;
+ const ct_data *stree = desc->stat_desc->static_tree;
+ const intf *extra = desc->stat_desc->extra_bits;
+ int base = desc->stat_desc->extra_base;
+ int max_length = desc->stat_desc->max_length;
+ int h; /* heap index */
+ int n, m; /* iterate over the tree elements */
+ int bits; /* bit length */
+ int xbits; /* extra bits */
+ ush f; /* frequency */
+ int overflow = 0; /* number of elements with bit length too large */
+
+ for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
+
+ /* In a first pass, compute the optimal bit lengths (which may
+ * overflow in the case of the bit length tree).
+ */
+ tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
+
+ for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
+ n = s->heap[h];
+ bits = tree[tree[n].Dad].Len + 1;
+ if (bits > max_length) bits = max_length, overflow++;
+ tree[n].Len = (ush)bits;
+ /* We overwrite tree[n].Dad which is no longer needed */
+
+ if (n > max_code) continue; /* not a leaf node */
+
+ s->bl_count[bits]++;
+ xbits = 0;
+ if (n >= base) xbits = extra[n-base];
+ f = tree[n].Freq;
+ s->opt_len += (ulg)f * (bits + xbits);
+ if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
+ }
+ if (overflow == 0) return;
+
+ Trace((stderr,"\nbit length overflow\n"));
+ /* This happens for example on obj2 and pic of the Calgary corpus */
+
+ /* Find the first bit length which could increase: */
+ do {
+ bits = max_length-1;
+ while (s->bl_count[bits] == 0) bits--;
+ s->bl_count[bits]--; /* move one leaf down the tree */
+ s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
+ s->bl_count[max_length]--;
+ /* The brother of the overflow item also moves one step up,
+ * but this does not affect bl_count[max_length]
+ */
+ overflow -= 2;
+ } while (overflow > 0);
+
+ /* Now recompute all bit lengths, scanning in increasing frequency.
+ * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
+ * lengths instead of fixing only the wrong ones. This idea is taken
+ * from 'ar' written by Haruhiko Okumura.)
+ */
+ for (bits = max_length; bits != 0; bits--) {
+ n = s->bl_count[bits];
+ while (n != 0) {
+ m = s->heap[--h];
+ if (m > max_code) continue;
+ if ((unsigned) tree[m].Len != (unsigned) bits) {
+ Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
+ s->opt_len += ((long)bits - (long)tree[m].Len)
+ *(long)tree[m].Freq;
+ tree[m].Len = (ush)bits;
+ }
+ n--;
+ }
+ }
+}
+
+/* ===========================================================================
+ * Generate the codes for a given tree and bit counts (which need not be
+ * optimal).
+ * IN assertion: the array bl_count contains the bit length statistics for
+ * the given tree and the field len is set for all tree elements.
+ * OUT assertion: the field code is set for all tree elements of non
+ * zero code length.
+ */
+local void gen_codes (tree, max_code, bl_count)
+ ct_data *tree; /* the tree to decorate */
+ int max_code; /* largest code with non zero frequency */
+ ushf *bl_count; /* number of codes at each bit length */
+{
+ ush next_code[MAX_BITS+1]; /* next code value for each bit length */
+ ush code = 0; /* running code value */
+ int bits; /* bit index */
+ int n; /* code index */
+
+ /* The distribution counts are first used to generate the code values
+ * without bit reversal.
+ */
+ for (bits = 1; bits <= MAX_BITS; bits++) {
+ next_code[bits] = code = (code + bl_count[bits-1]) << 1;
+ }
+ /* Check that the bit counts in bl_count are consistent. The last code
+ * must be all ones.
+ */
+ Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
+ "inconsistent bit counts");
+ Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
+
+ for (n = 0; n <= max_code; n++) {
+ int len = tree[n].Len;
+ if (len == 0) continue;
+ /* Now reverse the bits */
+ tree[n].Code = bi_reverse(next_code[len]++, len);
+
+ Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
+ n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
+ }
+}
+
+/* ===========================================================================
+ * Construct one Huffman tree and assigns the code bit strings and lengths.
+ * Update the total bit length for the current block.
+ * IN assertion: the field freq is set for all tree elements.
+ * OUT assertions: the fields len and code are set to the optimal bit length
+ * and corresponding code. The length opt_len is updated; static_len is
+ * also updated if stree is not null. The field max_code is set.
+ */
+local void build_tree(s, desc)
+ deflate_state *s;
+ tree_desc *desc; /* the tree descriptor */
+{
+ ct_data *tree = desc->dyn_tree;
+ const ct_data *stree = desc->stat_desc->static_tree;
+ int elems = desc->stat_desc->elems;
+ int n, m; /* iterate over heap elements */
+ int max_code = -1; /* largest code with non zero frequency */
+ int node; /* new node being created */
+
+ /* Construct the initial heap, with least frequent element in
+ * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
+ * heap[0] is not used.
+ */
+ s->heap_len = 0, s->heap_max = HEAP_SIZE;
+
+ for (n = 0; n < elems; n++) {
+ if (tree[n].Freq != 0) {
+ s->heap[++(s->heap_len)] = max_code = n;
+ s->depth[n] = 0;
+ } else {
+ tree[n].Len = 0;
+ }
+ }
+
+ /* The pkzip format requires that at least one distance code exists,
+ * and that at least one bit should be sent even if there is only one
+ * possible code. So to avoid special checks later on we force at least
+ * two codes of non zero frequency.
+ */
+ while (s->heap_len < 2) {
+ node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
+ tree[node].Freq = 1;
+ s->depth[node] = 0;
+ s->opt_len--; if (stree) s->static_len -= stree[node].Len;
+ /* node is 0 or 1 so it does not have extra bits */
+ }
+ desc->max_code = max_code;
+
+ /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
+ * establish sub-heaps of increasing lengths:
+ */
+ for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
+
+ /* Construct the Huffman tree by repeatedly combining the least two
+ * frequent nodes.
+ */
+ node = elems; /* next internal node of the tree */
+ do {
+ pqremove(s, tree, n); /* n = node of least frequency */
+ m = s->heap[SMALLEST]; /* m = node of next least frequency */
+
+ s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
+ s->heap[--(s->heap_max)] = m;
+
+ /* Create a new node father of n and m */
+ tree[node].Freq = tree[n].Freq + tree[m].Freq;
+ s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ?
+ s->depth[n] : s->depth[m]) + 1);
+ tree[n].Dad = tree[m].Dad = (ush)node;
+#ifdef DUMP_BL_TREE
+ if (tree == s->bl_tree) {
+ fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
+ node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
+ }
+#endif
+ /* and insert the new node in the heap */
+ s->heap[SMALLEST] = node++;
+ pqdownheap(s, tree, SMALLEST);
+
+ } while (s->heap_len >= 2);
+
+ s->heap[--(s->heap_max)] = s->heap[SMALLEST];
+
+ /* At this point, the fields freq and dad are set. We can now
+ * generate the bit lengths.
+ */
+ gen_bitlen(s, (tree_desc *)desc);
+
+ /* The field len is now set, we can generate the bit codes */
+ gen_codes ((ct_data *)tree, max_code, s->bl_count);
+}
+
+/* ===========================================================================
+ * Scan a literal or distance tree to determine the frequencies of the codes
+ * in the bit length tree.
+ */
+local void scan_tree (s, tree, max_code)
+ deflate_state *s;
+ ct_data *tree; /* the tree to be scanned */
+ int max_code; /* and its largest code of non zero frequency */
+{
+ int n; /* iterates over all tree elements */
+ int prevlen = -1; /* last emitted length */
+ int curlen; /* length of current code */
+ int nextlen = tree[0].Len; /* length of next code */
+ int count = 0; /* repeat count of the current code */
+ int max_count = 7; /* max repeat count */
+ int min_count = 4; /* min repeat count */
+
+ if (nextlen == 0) max_count = 138, min_count = 3;
+ tree[max_code+1].Len = (ush)0xffff; /* guard */
+
+ for (n = 0; n <= max_code; n++) {
+ curlen = nextlen; nextlen = tree[n+1].Len;
+ if (++count < max_count && curlen == nextlen) {
+ continue;
+ } else if (count < min_count) {
+ s->bl_tree[curlen].Freq += count;
+ } else if (curlen != 0) {
+ if (curlen != prevlen) s->bl_tree[curlen].Freq++;
+ s->bl_tree[REP_3_6].Freq++;
+ } else if (count <= 10) {
+ s->bl_tree[REPZ_3_10].Freq++;
+ } else {
+ s->bl_tree[REPZ_11_138].Freq++;
+ }
+ count = 0; prevlen = curlen;
+ if (nextlen == 0) {
+ max_count = 138, min_count = 3;
+ } else if (curlen == nextlen) {
+ max_count = 6, min_count = 3;
+ } else {
+ max_count = 7, min_count = 4;
+ }
+ }
+}
+
+/* ===========================================================================
+ * Send a literal or distance tree in compressed form, using the codes in
+ * bl_tree.
+ */
+local void send_tree (s, tree, max_code)
+ deflate_state *s;
+ ct_data *tree; /* the tree to be scanned */
+ int max_code; /* and its largest code of non zero frequency */
+{
+ int n; /* iterates over all tree elements */
+ int prevlen = -1; /* last emitted length */
+ int curlen; /* length of current code */
+ int nextlen = tree[0].Len; /* length of next code */
+ int count = 0; /* repeat count of the current code */
+ int max_count = 7; /* max repeat count */
+ int min_count = 4; /* min repeat count */
+
+ /* tree[max_code+1].Len = -1; */ /* guard already set */
+ if (nextlen == 0) max_count = 138, min_count = 3;
+
+ for (n = 0; n <= max_code; n++) {
+ curlen = nextlen; nextlen = tree[n+1].Len;
+ if (++count < max_count && curlen == nextlen) {
+ continue;
+ } else if (count < min_count) {
+ do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
+
+ } else if (curlen != 0) {
+ if (curlen != prevlen) {
+ send_code(s, curlen, s->bl_tree); count--;
+ }
+ Assert(count >= 3 && count <= 6, " 3_6?");
+ send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
+
+ } else if (count <= 10) {
+ send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
+
+ } else {
+ send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
+ }
+ count = 0; prevlen = curlen;
+ if (nextlen == 0) {
+ max_count = 138, min_count = 3;
+ } else if (curlen == nextlen) {
+ max_count = 6, min_count = 3;
+ } else {
+ max_count = 7, min_count = 4;
+ }
+ }
+}
+
+/* ===========================================================================
+ * Construct the Huffman tree for the bit lengths and return the index in
+ * bl_order of the last bit length code to send.
+ */
+local int build_bl_tree(s)
+ deflate_state *s;
+{
+ int max_blindex; /* index of last bit length code of non zero freq */
+
+ /* Determine the bit length frequencies for literal and distance trees */
+ scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
+ scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
+
+ /* Build the bit length tree: */
+ build_tree(s, (tree_desc *)(&(s->bl_desc)));
+ /* opt_len now includes the length of the tree representations, except
+ * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
+ */
+
+ /* Determine the number of bit length codes to send. The pkzip format
+ * requires that at least 4 bit length codes be sent. (appnote.txt says
+ * 3 but the actual value used is 4.)
+ */
+ for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
+ if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
+ }
+ /* Update opt_len to include the bit length tree and counts */
+ s->opt_len += 3*(max_blindex+1) + 5+5+4;
+ Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
+ s->opt_len, s->static_len));
+
+ return max_blindex;
+}
+
+/* ===========================================================================
+ * Send the header for a block using dynamic Huffman trees: the counts, the
+ * lengths of the bit length codes, the literal tree and the distance tree.
+ * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
+ */
+local void send_all_trees(s, lcodes, dcodes, blcodes)
+ deflate_state *s;
+ int lcodes, dcodes, blcodes; /* number of codes for each tree */
+{
+ int rank; /* index in bl_order */
+
+ Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
+ Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
+ "too many codes");
+ Tracev((stderr, "\nbl counts: "));
+ send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
+ send_bits(s, dcodes-1, 5);
+ send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */
+ for (rank = 0; rank < blcodes; rank++) {
+ Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
+ send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
+ }
+ Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
+
+ send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
+ Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
+
+ send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
+ Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
+}
+
+/* ===========================================================================
+ * Send a stored block
+ */
+void _tr_stored_block(s, buf, stored_len, eof)
+ deflate_state *s;
+ charf *buf; /* input block */
+ ulg stored_len; /* length of input block */
+ int eof; /* true if this is the last block for a file */
+{
+ send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */
+#ifdef DEBUG
+ s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
+ s->compressed_len += (stored_len + 4) << 3;
+#endif
+ copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
+}
+
+/* ===========================================================================
+ * Send one empty static block to give enough lookahead for inflate.
+ * This takes 10 bits, of which 7 may remain in the bit buffer.
+ * The current inflate code requires 9 bits of lookahead. If the
+ * last two codes for the previous block (real code plus EOB) were coded
+ * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
+ * the last real code. In this case we send two empty static blocks instead
+ * of one. (There are no problems if the previous block is stored or fixed.)
+ * To simplify the code, we assume the worst case of last real code encoded
+ * on one bit only.
+ */
+void _tr_align(s)
+ deflate_state *s;
+{
+ send_bits(s, STATIC_TREES<<1, 3);
+ send_code(s, END_BLOCK, static_ltree);
+#ifdef DEBUG
+ s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
+#endif
+ bi_flush(s);
+ /* Of the 10 bits for the empty block, we have already sent
+ * (10 - bi_valid) bits. The lookahead for the last real code (before
+ * the EOB of the previous block) was thus at least one plus the length
+ * of the EOB plus what we have just sent of the empty static block.
+ */
+ if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
+ send_bits(s, STATIC_TREES<<1, 3);
+ send_code(s, END_BLOCK, static_ltree);
+#ifdef DEBUG
+ s->compressed_len += 10L;
+#endif
+ bi_flush(s);
+ }
+ s->last_eob_len = 7;
+}
+
+/* ===========================================================================
+ * Determine the best encoding for the current block: dynamic trees, static
+ * trees or store, and output the encoded block to the zip file.
+ */
+void _tr_flush_block(s, buf, stored_len, eof)
+ deflate_state *s;
+ charf *buf; /* input block, or NULL if too old */
+ ulg stored_len; /* length of input block */
+ int eof; /* true if this is the last block for a file */
+{
+ ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
+ int max_blindex = 0; /* index of last bit length code of non zero freq */
+
+ /* Build the Huffman trees unless a stored block is forced */
+ if (s->level > 0) {
+
+ /* Check if the file is binary or text */
+ if (stored_len > 0 && s->strm->data_type == Z_UNKNOWN)
+ set_data_type(s);
+
+ /* Construct the literal and distance trees */
+ build_tree(s, (tree_desc *)(&(s->l_desc)));
+ Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
+ s->static_len));
+
+ build_tree(s, (tree_desc *)(&(s->d_desc)));
+ Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
+ s->static_len));
+ /* At this point, opt_len and static_len are the total bit lengths of
+ * the compressed block data, excluding the tree representations.
+ */
+
+ /* Build the bit length tree for the above two trees, and get the index
+ * in bl_order of the last bit length code to send.
+ */
+ max_blindex = build_bl_tree(s);
+
+ /* Determine the best encoding. Compute the block lengths in bytes. */
+ opt_lenb = (s->opt_len+3+7)>>3;
+ static_lenb = (s->static_len+3+7)>>3;
+
+ Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
+ opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
+ s->last_lit));
+
+ if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
+
+ } else {
+ Assert(buf != (char*)0, "lost buf");
+ opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
+ }
+
+#ifdef FORCE_STORED
+ if (buf != (char*)0) { /* force stored block */
+#else
+ if (stored_len+4 <= opt_lenb && buf != (char*)0) {
+ /* 4: two words for the lengths */
+#endif
+ /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
+ * Otherwise we can't have processed more than WSIZE input bytes since
+ * the last block flush, because compression would have been
+ * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
+ * transform a block into a stored block.
+ */
+ _tr_stored_block(s, buf, stored_len, eof);
+
+#ifdef FORCE_STATIC
+ } else if (static_lenb >= 0) { /* force static trees */
+#else
+ } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {
+#endif
+ send_bits(s, (STATIC_TREES<<1)+eof, 3);
+ compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
+#ifdef DEBUG
+ s->compressed_len += 3 + s->static_len;
+#endif
+ } else {
+ send_bits(s, (DYN_TREES<<1)+eof, 3);
+ send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
+ max_blindex+1);
+ compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
+#ifdef DEBUG
+ s->compressed_len += 3 + s->opt_len;
+#endif
+ }
+ Assert (s->compressed_len == s->bits_sent, "bad compressed size");
+ /* The above check is made mod 2^32, for files larger than 512 MB
+ * and uLong implemented on 32 bits.
+ */
+ init_block(s);
+
+ if (eof) {
+ bi_windup(s);
+#ifdef DEBUG
+ s->compressed_len += 7; /* align on byte boundary */
+#endif
+ }
+ Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
+ s->compressed_len-7*eof));
+}
+
+/* ===========================================================================
+ * Save the match info and tally the frequency counts. Return true if
+ * the current block must be flushed.
+ */
+int _tr_tally (s, dist, lc)
+ deflate_state *s;
+ unsigned dist; /* distance of matched string */
+ unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
+{
+ s->d_buf[s->last_lit] = (ush)dist;
+ s->l_buf[s->last_lit++] = (uch)lc;
+ if (dist == 0) {
+ /* lc is the unmatched char */
+ s->dyn_ltree[lc].Freq++;
+ } else {
+ s->matches++;
+ /* Here, lc is the match length - MIN_MATCH */
+ dist--; /* dist = match distance - 1 */
+ Assert((ush)dist < (ush)MAX_DIST(s) &&
+ (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
+ (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
+
+ s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
+ s->dyn_dtree[d_code(dist)].Freq++;
+ }
+
+#ifdef TRUNCATE_BLOCK
+ /* Try to guess if it is profitable to stop the current block here */
+ if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
+ /* Compute an upper bound for the compressed length */
+ ulg out_length = (ulg)s->last_lit*8L;
+ ulg in_length = (ulg)((long)s->strstart - s->block_start);
+ int dcode;
+ for (dcode = 0; dcode < D_CODES; dcode++) {
+ out_length += (ulg)s->dyn_dtree[dcode].Freq *
+ (5L+extra_dbits[dcode]);
+ }
+ out_length >>= 3;
+ Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
+ s->last_lit, in_length, out_length,
+ 100L - out_length*100L/in_length));
+ if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
+ }
+#endif
+ return (s->last_lit == s->lit_bufsize-1);
+ /* We avoid equality with lit_bufsize because of wraparound at 64K
+ * on 16 bit machines and because stored blocks are restricted to
+ * 64K-1 bytes.
+ */
+}
+
+/* ===========================================================================
+ * Send the block data compressed using the given Huffman trees
+ */
+local void compress_block(s, ltree, dtree)
+ deflate_state *s;
+ ct_data *ltree; /* literal tree */
+ ct_data *dtree; /* distance tree */
+{
+ unsigned dist; /* distance of matched string */
+ int lc; /* match length or unmatched char (if dist == 0) */
+ unsigned lx = 0; /* running index in l_buf */
+ unsigned code; /* the code to send */
+ int extra; /* number of extra bits to send */
+
+ if (s->last_lit != 0) do {
+ dist = s->d_buf[lx];
+ lc = s->l_buf[lx++];
+ if (dist == 0) {
+ send_code(s, lc, ltree); /* send a literal byte */
+ Tracecv(isgraph(lc), (stderr," '%c' ", lc));
+ } else {
+ /* Here, lc is the match length - MIN_MATCH */
+ code = _length_code[lc];
+ send_code(s, code+LITERALS+1, ltree); /* send the length code */
+ extra = extra_lbits[code];
+ if (extra != 0) {
+ lc -= base_length[code];
+ send_bits(s, lc, extra); /* send the extra length bits */
+ }
+ dist--; /* dist is now the match distance - 1 */
+ code = d_code(dist);
+ Assert (code < D_CODES, "bad d_code");
+
+ send_code(s, code, dtree); /* send the distance code */
+ extra = extra_dbits[code];
+ if (extra != 0) {
+ dist -= base_dist[code];
+ send_bits(s, dist, extra); /* send the extra distance bits */
+ }
+ } /* literal or match pair ? */
+
+ /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
+ Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
+ "pendingBuf overflow");
+
+ } while (lx < s->last_lit);
+
+ send_code(s, END_BLOCK, ltree);
+ s->last_eob_len = ltree[END_BLOCK].Len;
+}
+
+/* ===========================================================================
+ * Set the data type to BINARY or TEXT, using a crude approximation:
+ * set it to Z_TEXT if all symbols are either printable characters (33 to 255)
+ * or white spaces (9 to 13, or 32); or set it to Z_BINARY otherwise.
+ * IN assertion: the fields Freq of dyn_ltree are set.
+ */
+local void set_data_type(s)
+ deflate_state *s;
+{
+ int n;
+
+ for (n = 0; n < 9; n++)
+ if (s->dyn_ltree[n].Freq != 0)
+ break;
+ if (n == 9)
+ for (n = 14; n < 32; n++)
+ if (s->dyn_ltree[n].Freq != 0)
+ break;
+ s->strm->data_type = (n == 32) ? Z_TEXT : Z_BINARY;
+}
+
+/* ===========================================================================
+ * Reverse the first len bits of a code, using straightforward code (a faster
+ * method would use a table)
+ * IN assertion: 1 <= len <= 15
+ */
+local unsigned bi_reverse(code, len)
+ unsigned code; /* the value to invert */
+ int len; /* its bit length */
+{
+ register unsigned res = 0;
+ do {
+ res |= code & 1;
+ code >>= 1, res <<= 1;
+ } while (--len > 0);
+ return res >> 1;
+}
+
+/* ===========================================================================
+ * Flush the bit buffer, keeping at most 7 bits in it.
+ */
+local void bi_flush(s)
+ deflate_state *s;
+{
+ if (s->bi_valid == 16) {
+ put_short(s, s->bi_buf);
+ s->bi_buf = 0;
+ s->bi_valid = 0;
+ } else if (s->bi_valid >= 8) {
+ put_byte(s, (Byte)s->bi_buf);
+ s->bi_buf >>= 8;
+ s->bi_valid -= 8;
+ }
+}
+
+/* ===========================================================================
+ * Flush the bit buffer and align the output on a byte boundary
+ */
+local void bi_windup(s)
+ deflate_state *s;
+{
+ if (s->bi_valid > 8) {
+ put_short(s, s->bi_buf);
+ } else if (s->bi_valid > 0) {
+ put_byte(s, (Byte)s->bi_buf);
+ }
+ s->bi_buf = 0;
+ s->bi_valid = 0;
+#ifdef DEBUG
+ s->bits_sent = (s->bits_sent+7) & ~7;
+#endif
+}
+
+/* ===========================================================================
+ * Copy a stored block, storing first the length and its
+ * one's complement if requested.
+ */
+local void copy_block(s, buf, len, header)
+ deflate_state *s;
+ charf *buf; /* the input data */
+ unsigned len; /* its length */
+ int header; /* true if block header must be written */
+{
+ bi_windup(s); /* align on byte boundary */
+ s->last_eob_len = 8; /* enough lookahead for inflate */
+
+ if (header) {
+ put_short(s, (ush)len);
+ put_short(s, (ush)~len);
+#ifdef DEBUG
+ s->bits_sent += 2*16;
+#endif
+ }
+#ifdef DEBUG
+ s->bits_sent += (ulg)len<<3;
+#endif
+ while (len--) {
+ put_byte(s, *buf++);
+ }
+}
diff --git a/Utilities/cmzlib/trees.h b/Utilities/cmzlib/trees.h
new file mode 100644
index 000000000..72facf900
--- /dev/null
+++ b/Utilities/cmzlib/trees.h
@@ -0,0 +1,128 @@
+/* header created automatically with -DGEN_TREES_H */
+
+local const ct_data static_ltree[L_CODES+2] = {
+{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}},
+{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}},
+{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}},
+{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}},
+{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}},
+{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}},
+{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}},
+{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}},
+{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}},
+{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}},
+{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}},
+{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}},
+{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}},
+{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}},
+{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}},
+{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}},
+{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}},
+{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}},
+{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}},
+{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}},
+{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}},
+{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}},
+{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}},
+{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}},
+{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}},
+{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}},
+{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}},
+{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}},
+{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}},
+{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}},
+{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}},
+{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}},
+{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}},
+{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}},
+{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}},
+{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}},
+{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}},
+{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}},
+{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}},
+{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}},
+{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}},
+{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}},
+{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}},
+{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}},
+{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}},
+{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}},
+{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}},
+{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}},
+{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}},
+{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}},
+{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}},
+{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}},
+{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}},
+{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}},
+{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}},
+{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}},
+{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}},
+{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}}
+};
+
+local const ct_data static_dtree[D_CODES] = {
+{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
+{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
+{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
+{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
+{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
+{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
+};
+
+const uch _dist_code[DIST_CODE_LEN] = {
+ 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, 0, 0, 16, 17,
+18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
+23, 23, 23, 23, 23, 23, 23, 23, 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,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
+};
+
+const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
+13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
+17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
+19, 19, 19, 19, 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, 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, 24, 24, 24, 24, 24, 24, 24, 24, 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, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
+};
+
+local const int base_length[LENGTH_CODES] = {
+0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
+64, 80, 96, 112, 128, 160, 192, 224, 0
+};
+
+local const int base_dist[D_CODES] = {
+ 0, 1, 2, 3, 4, 6, 8, 12, 16, 24,
+ 32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
+ 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
+};
+
diff --git a/Utilities/cmzlib/uncompr.c b/Utilities/cmzlib/uncompr.c
new file mode 100644
index 000000000..b59e3d0de
--- /dev/null
+++ b/Utilities/cmzlib/uncompr.c
@@ -0,0 +1,61 @@
+/* uncompr.c -- decompress a memory buffer
+ * Copyright (C) 1995-2003 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+/* ===========================================================================
+ Decompresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total
+ size of the destination buffer, which must be large enough to hold the
+ entire uncompressed data. (The size of the uncompressed data must have
+ been saved previously by the compressor and transmitted to the decompressor
+ by some mechanism outside the scope of this compression library.)
+ Upon exit, destLen is the actual size of the compressed buffer.
+ This function can be used to decompress a whole file at once if the
+ input file is mmap'ed.
+
+ uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer, or Z_DATA_ERROR if the input data was corrupted.
+*/
+int ZEXPORT uncompress (dest, destLen, source, sourceLen)
+ Bytef *dest;
+ uLongf *destLen;
+ const Bytef *source;
+ uLong sourceLen;
+{
+ z_stream stream;
+ int err;
+
+ stream.next_in = (Bytef*)source;
+ stream.avail_in = (uInt)sourceLen;
+ /* Check for source > 64K on 16-bit machine: */
+ if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
+
+ stream.next_out = dest;
+ stream.avail_out = (uInt)*destLen;
+ if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+
+ stream.zalloc = (alloc_func)0;
+ stream.zfree = (free_func)0;
+
+ err = inflateInit(&stream);
+ if (err != Z_OK) return err;
+
+ err = inflate(&stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ inflateEnd(&stream);
+ if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))
+ return Z_DATA_ERROR;
+ return err;
+ }
+ *destLen = stream.total_out;
+
+ err = inflateEnd(&stream);
+ return err;
+}
diff --git a/Utilities/cmzlib/zconf.h b/Utilities/cmzlib/zconf.h
new file mode 100644
index 000000000..6eb52d133
--- /dev/null
+++ b/Utilities/cmzlib/zconf.h
@@ -0,0 +1,351 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+
+/* KITWARE_ZLIB_CHANGE - Added to mangle function names */
+#include "cm_zlib_mangle.h"
+
+/* KITWARE_ZLIB_CHANGE - Added to get the correct definition of ZLIB_DLL */
+#include "cmzlib/zlibDllConfig.h"
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ */
+#ifdef Z_PREFIX
+# define deflateInit_ z_deflateInit_
+# define deflate z_deflate
+# define deflateEnd z_deflateEnd
+# define inflateInit_ z_inflateInit_
+# define inflate z_inflate
+# define inflateEnd z_inflateEnd
+# define deflateInit2_ z_deflateInit2_
+# define deflateSetDictionary z_deflateSetDictionary
+# define deflateCopy z_deflateCopy
+# define deflateReset z_deflateReset
+# define deflateParams z_deflateParams
+# define deflateBound z_deflateBound
+# define deflatePrime z_deflatePrime
+# define inflateInit2_ z_inflateInit2_
+# define inflateSetDictionary z_inflateSetDictionary
+# define inflateSync z_inflateSync
+# define inflateSyncPoint z_inflateSyncPoint
+# define inflateCopy z_inflateCopy
+# define inflateReset z_inflateReset
+# define inflateBack z_inflateBack
+# define inflateBackEnd z_inflateBackEnd
+# define compress z_compress
+# define compress2 z_compress2
+# define compressBound z_compressBound
+# define uncompress z_uncompress
+# define adler32 z_adler32
+# define crc32 z_crc32
+# define get_crc_table z_get_crc_table
+# define zError z_zError
+
+# define alloc_func z_alloc_func
+# define free_func z_free_func
+# define in_func z_in_func
+# define out_func z_out_func
+# define Byte z_Byte
+# define uInt z_uInt
+# define uLong z_uLong
+# define Bytef z_Bytef
+# define charf z_charf
+# define intf z_intf
+# define uIntf z_uIntf
+# define uLongf z_uLongf
+# define voidpf z_voidpf
+# define voidp z_voidp
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+# define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+# define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+# define WINDOWS
+#endif
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+# ifndef WIN32
+# define WIN32
+# endif
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+# ifndef SYS16BIT
+# define SYS16BIT
+# endif
+# endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+# define MAXSEG_64K
+#endif
+#ifdef MSDOS
+# define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+# ifndef STDC
+# define STDC
+# endif
+# if __STDC_VERSION__ >= 199901L
+# ifndef STDC99
+# define STDC99
+# endif
+# endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+# define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
+# define STDC
+#endif
+
+#ifndef STDC
+# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+# define const /* note: need a more gentle solution here */
+# endif
+#endif
+
+/* Some Mac compilers merge all .h files incorrectly: */
+#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
+# define NO_DUMMY_DECL
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+# ifdef MAXSEG_64K
+# define MAX_MEM_LEVEL 8
+# else
+# define MAX_MEM_LEVEL 9
+# endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+# define MAX_WBITS 15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+ (1 << (windowBits+2)) + (1 << (memLevel+9))
+ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+ The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+ /* Type declarations */
+
+#ifndef OF /* function prototypes */
+# ifdef STDC
+# define OF(args) args
+# else
+# define OF(args) ()
+# endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+# if defined(M_I86SM) || defined(M_I86MM)
+ /* MSC small or medium model */
+# define SMALL_MEDIUM
+# ifdef _MSC_VER
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+# if (defined(__SMALL__) || defined(__MEDIUM__))
+ /* Turbo C small or medium model */
+# define SMALL_MEDIUM
+# ifdef __BORLANDC__
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+ /* If building or using zlib as a DLL, define ZLIB_DLL.
+ * This is not mandatory, but it offers a little performance increase.
+ */
+# ifdef ZLIB_DLL
+# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+# ifdef ZLIB_INTERNAL
+# define ZEXTERN extern __declspec(dllexport)
+# else
+# define ZEXTERN extern __declspec(dllimport)
+# endif
+# endif
+# endif /* ZLIB_DLL */
+ /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+ * define ZLIB_WINAPI.
+ * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+ */
+# ifdef ZLIB_WINAPI
+# ifdef FAR
+# undef FAR
+# endif
+# include <windows.h>
+ /* No need for _export, use ZLIB.DEF instead. */
+ /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+# define ZEXPORT WINAPI
+# ifdef WIN32
+# define ZEXPORTVA WINAPIV
+# else
+# define ZEXPORTVA FAR CDECL
+# endif
+# endif
+#endif
+
+#if defined (__BEOS__) && !defined (__HAIKU__)
+# ifdef ZLIB_DLL
+# ifdef ZLIB_INTERNAL
+# define ZEXPORT __declspec(dllexport)
+# define ZEXPORTVA __declspec(dllexport)
+# else
+# define ZEXPORT __declspec(dllimport)
+# define ZEXPORTVA __declspec(dllimport)
+# endif
+# endif
+#endif
+
+#ifndef ZEXTERN
+# define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+# define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+# define ZEXPORTVA
+#endif
+
+#ifndef FAR
+# define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char Byte; /* 8 bits */
+#endif
+typedef unsigned int uInt; /* 16 bits or more */
+typedef unsigned long uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+ /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+# define Bytef Byte FAR
+#else
+ typedef Byte FAR Bytef;
+#endif
+typedef char FAR charf;
+typedef int FAR intf;
+typedef uInt FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+ typedef void const *voidpc;
+ typedef void FAR *voidpf;
+ typedef void *voidp;
+#else
+ typedef Byte const *voidpc;
+ typedef Byte FAR *voidpf;
+ typedef Byte *voidp;
+#endif
+
+/* KITWARE_ZLIB_CHANGE - Since VTK/ITK/CMake use CMake, not ./configure, we can go ahead and test HAVE_UNISTD_H */
+#ifdef HAVE_UNISTD_H
+# include <sys/types.h> /* for off_t */
+# include <unistd.h> /* for SEEK_* and off_t */
+# ifdef VMS
+# include <unixio.h> /* for off_t */
+# endif
+# define z_off_t off_t
+#endif
+#ifndef SEEK_SET
+# define SEEK_SET 0 /* Seek from beginning of file. */
+# define SEEK_CUR 1 /* Seek from current position. */
+# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
+#endif
+#ifndef z_off_t
+# define z_off_t long
+#endif
+
+#if defined(__OS400__)
+# define NO_vsnprintf
+#endif
+
+#if defined(__MVS__)
+# define NO_vsnprintf
+# ifdef FAR
+# undef FAR
+# endif
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+# pragma map(deflateInit_,"DEIN")
+# pragma map(deflateInit2_,"DEIN2")
+# pragma map(deflateEnd,"DEEND")
+# pragma map(deflateBound,"DEBND")
+# pragma map(inflateInit_,"ININ")
+# pragma map(inflateInit2_,"ININ2")
+# pragma map(inflateEnd,"INEND")
+# pragma map(inflateSync,"INSY")
+# pragma map(inflateSetDictionary,"INSEDI")
+# pragma map(compressBound,"CMBND")
+# pragma map(inflate_table,"INTABL")
+# pragma map(inflate_fast,"INFA")
+# pragma map(inflate_copyright,"INCOPY")
+#endif
+
+/* KITWARE_ZLIB_CHANGE - Added to suppress complier warnings */
+#if defined(_MSC_VER)
+#pragma warning ( disable : 4127 ) /* cond expr is constant */
+#pragma warning ( disable : 4131 ) /* old style declaration */
+#pragma warning ( disable : 4244 ) /* conversion loss of data */
+#endif
+#if defined(__BORLANDC__)
+#pragma warn -8004 /* assigned a value that is never used */
+#pragma warn -8008 /* condition is always true */
+#pragma warn -8066 /* unreachable code */
+#endif
+
+#endif /* ZCONF_H */
diff --git a/Utilities/cmzlib/zlib.def b/Utilities/cmzlib/zlib.def
new file mode 100644
index 000000000..e351899c8
--- /dev/null
+++ b/Utilities/cmzlib/zlib.def
@@ -0,0 +1,47 @@
+
+VERSION 1.23
+
+HEAPSIZE 1048576,4096
+
+EXPORTS
+ cm_zlib_adler32 @1
+ cm_zlib_compress @2
+ cm_zlib_crc32 @3
+ cm_zlib_deflate @4
+ cm_zlib_deflateCopy @5
+ cm_zlib_deflateEnd @6
+ cm_zlib_deflateInit2_ @7
+ cm_zlib_deflateInit_ @8
+ cm_zlib_deflateParams @9
+ cm_zlib_deflateReset @10
+ cm_zlib_deflateSetDictionary @11
+ cm_zlib_gzclose @12
+ cm_zlib_gzdopen @13
+ cm_zlib_gzerror @14
+ cm_zlib_gzflush @15
+ cm_zlib_gzopen @16
+ cm_zlib_gzread @17
+ cm_zlib_gzwrite @18
+ cm_zlib_inflate @19
+ cm_zlib_inflateEnd @20
+ cm_zlib_inflateInit2_ @21
+ cm_zlib_inflateInit_ @22
+ cm_zlib_inflateReset @23
+ cm_zlib_inflateSetDictionary @24
+ cm_zlib_inflateSync @25
+ cm_zlib_uncompress @26
+ cm_zlib_zlibVersion @27
+ cm_zlib_gzprintf @28
+ cm_zlib_gzputc @29
+ cm_zlib_gzgetc @30
+ cm_zlib_gzseek @31
+ cm_zlib_gzrewind @32
+ cm_zlib_gztell @33
+ cm_zlib_gzeof @34
+ cm_zlib_gzsetparams @35
+ cm_zlib_zError @36
+ cm_zlib_inflateSyncPoint @37
+ cm_zlib_get_crc_table @38
+ cm_zlib_compress2 @39
+ cm_zlib_gzputs @40
+ cm_zlib_gzgets @41
diff --git a/Utilities/cmzlib/zlib.h b/Utilities/cmzlib/zlib.h
new file mode 100644
index 000000000..022817927
--- /dev/null
+++ b/Utilities/cmzlib/zlib.h
@@ -0,0 +1,1357 @@
+/* zlib.h -- interface of the 'zlib' general purpose compression library
+ version 1.2.3, July 18th, 2005
+
+ Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ jloup@gzip.org madler@alumni.caltech.edu
+
+
+ The data format used by the zlib library is described by RFCs (Request for
+ Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
+ (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
+*/
+
+#ifndef ZLIB_H
+#define ZLIB_H
+
+#include "zconf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ZLIB_VERSION "1.2.3"
+#define ZLIB_VERNUM 0x1230
+
+/*
+ The 'zlib' compression library provides in-memory compression and
+ decompression functions, including integrity checks of the uncompressed
+ data. This version of the library supports only one compression method
+ (deflation) but other algorithms will be added later and will have the same
+ stream interface.
+
+ Compression can be done in a single step if the buffers are large
+ enough (for example if an input file is mmap'ed), or can be done by
+ repeated calls of the compression function. In the latter case, the
+ application must provide more input and/or consume the output
+ (providing more output space) before each call.
+
+ The compressed data format used by default by the in-memory functions is
+ the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
+ around a deflate stream, which is itself documented in RFC 1951.
+
+ The library also supports reading and writing files in gzip (.gz) format
+ with an interface similar to that of stdio using the functions that start
+ with "gz". The gzip format is different from the zlib format. gzip is a
+ gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
+
+ This library can optionally read and write gzip streams in memory as well.
+
+ The zlib format was designed to be compact and fast for use in memory
+ and on communications channels. The gzip format was designed for single-
+ file compression on file systems, has a larger header than zlib to maintain
+ directory information, and uses a different, slower check method than zlib.
+
+ The library does not install any signal handler. The decoder checks
+ the consistency of the compressed data, so the library should never
+ crash even in case of corrupted input.
+*/
+
+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
+typedef void (*free_func) OF((voidpf opaque, voidpf address));
+
+struct internal_state;
+
+typedef struct z_stream_s {
+ Bytef *next_in; /* next input byte */
+ uInt avail_in; /* number of bytes available at next_in */
+ uLong total_in; /* total nb of input bytes read so far */
+
+ Bytef *next_out; /* next output byte should be put there */
+ uInt avail_out; /* remaining free space at next_out */
+ uLong total_out; /* total nb of bytes output so far */
+
+ char *msg; /* last error message, NULL if no error */
+ struct internal_state FAR *state; /* not visible by applications */
+
+ alloc_func zalloc; /* used to allocate the internal state */
+ free_func zfree; /* used to free the internal state */
+ voidpf opaque; /* private data object passed to zalloc and zfree */
+
+ int data_type; /* best guess about the data type: binary or text */
+ uLong adler; /* adler32 value of the uncompressed data */
+ uLong reserved; /* reserved for future use */
+} z_stream;
+
+typedef z_stream FAR *z_streamp;
+
+/*
+ gzip header information passed to and from zlib routines. See RFC 1952
+ for more details on the meanings of these fields.
+*/
+typedef struct gz_header_s {
+ int text; /* true if compressed data believed to be text */
+ uLong time; /* modification time */
+ int xflags; /* extra flags (not used when writing a gzip file) */
+ int os; /* operating system */
+ Bytef *extra; /* pointer to extra field or Z_NULL if none */
+ uInt extra_len; /* extra field length (valid if extra != Z_NULL) */
+ uInt extra_max; /* space at extra (only when reading header) */
+ Bytef *name; /* pointer to zero-terminated file name or Z_NULL */
+ uInt name_max; /* space at name (only when reading header) */
+ Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */
+ uInt comm_max; /* space at comment (only when reading header) */
+ int hcrc; /* true if there was or will be a header crc */
+ int done; /* true when done reading gzip header (not used
+ when writing a gzip file) */
+} gz_header;
+
+typedef gz_header FAR *gz_headerp;
+
+/*
+ The application must update next_in and avail_in when avail_in has
+ dropped to zero. It must update next_out and avail_out when avail_out
+ has dropped to zero. The application must initialize zalloc, zfree and
+ opaque before calling the init function. All other fields are set by the
+ compression library and must not be updated by the application.
+
+ The opaque value provided by the application will be passed as the first
+ parameter for calls of zalloc and zfree. This can be useful for custom
+ memory management. The compression library attaches no meaning to the
+ opaque value.
+
+ zalloc must return Z_NULL if there is not enough memory for the object.
+ If zlib is used in a multi-threaded application, zalloc and zfree must be
+ thread safe.
+
+ On 16-bit systems, the functions zalloc and zfree must be able to allocate
+ exactly 65536 bytes, but will not be required to allocate more than this
+ if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
+ pointers returned by zalloc for objects of exactly 65536 bytes *must*
+ have their offset normalized to zero. The default allocation function
+ provided by this library ensures this (see zutil.c). To reduce memory
+ requirements and avoid any allocation of 64K objects, at the expense of
+ compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
+
+ The fields total_in and total_out can be used for statistics or
+ progress reports. After compression, total_in holds the total size of
+ the uncompressed data and may be saved for use in the decompressor
+ (particularly if the decompressor wants to decompress everything in
+ a single step).
+*/
+
+ /* constants */
+
+#define Z_NO_FLUSH 0
+#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
+#define Z_SYNC_FLUSH 2
+#define Z_FULL_FLUSH 3
+#define Z_FINISH 4
+#define Z_BLOCK 5
+/* Allowed flush values; see deflate() and inflate() below for details */
+
+#define Z_OK 0
+#define Z_STREAM_END 1
+#define Z_NEED_DICT 2
+#define Z_ERRNO (-1)
+#define Z_STREAM_ERROR (-2)
+#define Z_DATA_ERROR (-3)
+#define Z_MEM_ERROR (-4)
+#define Z_BUF_ERROR (-5)
+#define Z_VERSION_ERROR (-6)
+/* Return codes for the compression/decompression functions. Negative
+ * values are errors, positive values are used for special but normal events.
+ */
+
+#define Z_NO_COMPRESSION 0
+#define Z_BEST_SPEED 1
+#define Z_BEST_COMPRESSION 9
+#define Z_DEFAULT_COMPRESSION (-1)
+/* compression levels */
+
+#define Z_FILTERED 1
+#define Z_HUFFMAN_ONLY 2
+#define Z_RLE 3
+#define Z_FIXED 4
+#define Z_DEFAULT_STRATEGY 0
+/* compression strategy; see deflateInit2() below for details */
+
+#define Z_BINARY 0
+#define Z_TEXT 1
+#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */
+#define Z_UNKNOWN 2
+/* Possible values of the data_type field (though see inflate()) */
+
+#define Z_DEFLATED 8
+/* The deflate compression method (the only one supported in this version) */
+
+#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
+
+#define zlib_version zlibVersion()
+/* for compatibility with versions < 1.0.2 */
+
+ /* basic functions */
+
+ZEXTERN const char * ZEXPORT zlibVersion OF((void));
+/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
+ If the first character differs, the library code actually used is
+ not compatible with the zlib.h header file used by the application.
+ This check is automatically made by deflateInit and inflateInit.
+ */
+
+/*
+ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
+
+ Initializes the internal stream state for compression. The fields
+ zalloc, zfree and opaque must be initialized before by the caller.
+ If zalloc and zfree are set to Z_NULL, deflateInit updates them to
+ use default allocation functions.
+
+ The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
+ 1 gives best speed, 9 gives best compression, 0 gives no compression at
+ all (the input data is simply copied a block at a time).
+ Z_DEFAULT_COMPRESSION requests a default compromise between speed and
+ compression (currently equivalent to level 6).
+
+ deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_STREAM_ERROR if level is not a valid compression level,
+ Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
+ with the version assumed by the caller (ZLIB_VERSION).
+ msg is set to null if there is no error message. deflateInit does not
+ perform any compression: this will be done by deflate().
+*/
+
+
+ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
+/*
+ deflate compresses as much data as possible, and stops when the input
+ buffer becomes empty or the output buffer becomes full. It may introduce some
+ output latency (reading input without producing any output) except when
+ forced to flush.
+
+ The detailed semantics are as follows. deflate performs one or both of the
+ following actions:
+
+ - Compress more input starting at next_in and update next_in and avail_in
+ accordingly. If not all input can be processed (because there is not
+ enough room in the output buffer), next_in and avail_in are updated and
+ processing will resume at this point for the next call of deflate().
+
+ - Provide more output starting at next_out and update next_out and avail_out
+ accordingly. This action is forced if the parameter flush is non zero.
+ Forcing flush frequently degrades the compression ratio, so this parameter
+ should be set only when necessary (in interactive applications).
+ Some output may be provided even if flush is not set.
+
+ Before the call of deflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming
+ more output, and updating avail_in or avail_out accordingly; avail_out
+ should never be zero before the call. The application can consume the
+ compressed output when it wants, for example when the output buffer is full
+ (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
+ and with zero avail_out, it must be called again after making room in the
+ output buffer because there might be more output pending.
+
+ Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
+ decide how much data to accumualte before producing output, in order to
+ maximize compression.
+
+ If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
+ flushed to the output buffer and the output is aligned on a byte boundary, so
+ that the decompressor can get all input data available so far. (In particular
+ avail_in is zero after the call if enough output space has been provided
+ before the call.) Flushing may degrade compression for some compression
+ algorithms and so it should be used only when necessary.
+
+ If flush is set to Z_FULL_FLUSH, all output is flushed as with
+ Z_SYNC_FLUSH, and the compression state is reset so that decompression can
+ restart from this point if previous compressed data has been damaged or if
+ random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
+ compression.
+
+ If deflate returns with avail_out == 0, this function must be called again
+ with the same value of the flush parameter and more output space (updated
+ avail_out), until the flush is complete (deflate returns with non-zero
+ avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
+ avail_out is greater than six to avoid repeated flush markers due to
+ avail_out == 0 on return.
+
+ If the parameter flush is set to Z_FINISH, pending input is processed,
+ pending output is flushed and deflate returns with Z_STREAM_END if there
+ was enough output space; if deflate returns with Z_OK, this function must be
+ called again with Z_FINISH and more output space (updated avail_out) but no
+ more input data, until it returns with Z_STREAM_END or an error. After
+ deflate has returned Z_STREAM_END, the only possible operations on the
+ stream are deflateReset or deflateEnd.
+
+ Z_FINISH can be used immediately after deflateInit if all the compression
+ is to be done in a single step. In this case, avail_out must be at least
+ the value returned by deflateBound (see below). If deflate does not return
+ Z_STREAM_END, then it must be called again as described above.
+
+ deflate() sets strm->adler to the adler32 checksum of all input read
+ so far (that is, total_in bytes).
+
+ deflate() may update strm->data_type if it can make a good guess about
+ the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered
+ binary. This field is only for information purposes and does not affect
+ the compression algorithm in any manner.
+
+ deflate() returns Z_OK if some progress has been made (more input
+ processed or more output produced), Z_STREAM_END if all input has been
+ consumed and all output has been produced (only when flush is set to
+ Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
+ if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
+ (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not
+ fatal, and deflate() can be called again with more input and more output
+ space to continue compressing.
+*/
+
+
+ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
+/*
+ All dynamically allocated data structures for this stream are freed.
+ This function discards any unprocessed input and does not flush any
+ pending output.
+
+ deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
+ stream state was inconsistent, Z_DATA_ERROR if the stream was freed
+ prematurely (some input or output was discarded). In the error case,
+ msg may be set but then points to a static string (which must not be
+ deallocated).
+*/
+
+
+/*
+ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
+
+ Initializes the internal stream state for decompression. The fields
+ next_in, avail_in, zalloc, zfree and opaque must be initialized before by
+ the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
+ value depends on the compression method), inflateInit determines the
+ compression method from the zlib header and allocates all data structures
+ accordingly; otherwise the allocation will be deferred to the first call of
+ inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
+ use default allocation functions.
+
+ inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+ version assumed by the caller. msg is set to null if there is no error
+ message. inflateInit does not perform any decompression apart from reading
+ the zlib header if present: this will be done by inflate(). (So next_in and
+ avail_in may be modified, but next_out and avail_out are unchanged.)
+*/
+
+
+ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
+/*
+ inflate decompresses as much data as possible, and stops when the input
+ buffer becomes empty or the output buffer becomes full. It may introduce
+ some output latency (reading input without producing any output) except when
+ forced to flush.
+
+ The detailed semantics are as follows. inflate performs one or both of the
+ following actions:
+
+ - Decompress more input starting at next_in and update next_in and avail_in
+ accordingly. If not all input can be processed (because there is not
+ enough room in the output buffer), next_in is updated and processing
+ will resume at this point for the next call of inflate().
+
+ - Provide more output starting at next_out and update next_out and avail_out
+ accordingly. inflate() provides as much output as possible, until there
+ is no more input data or no more space in the output buffer (see below
+ about the flush parameter).
+
+ Before the call of inflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming
+ more output, and updating the next_* and avail_* values accordingly.
+ The application can consume the uncompressed output when it wants, for
+ example when the output buffer is full (avail_out == 0), or after each
+ call of inflate(). If inflate returns Z_OK and with zero avail_out, it
+ must be called again after making room in the output buffer because there
+ might be more output pending.
+
+ The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH,
+ Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much
+ output as possible to the output buffer. Z_BLOCK requests that inflate() stop
+ if and when it gets to the next deflate block boundary. When decoding the
+ zlib or gzip format, this will cause inflate() to return immediately after
+ the header and before the first block. When doing a raw inflate, inflate()
+ will go ahead and process the first block, and will return when it gets to
+ the end of that block, or when it runs out of data.
+
+ The Z_BLOCK option assists in appending to or combining deflate streams.
+ Also to assist in this, on return inflate() will set strm->data_type to the
+ number of unused bits in the last byte taken from strm->next_in, plus 64
+ if inflate() is currently decoding the last block in the deflate stream,
+ plus 128 if inflate() returned immediately after decoding an end-of-block
+ code or decoding the complete header up to just before the first byte of the
+ deflate stream. The end-of-block will not be indicated until all of the
+ uncompressed data from that block has been written to strm->next_out. The
+ number of unused bits may in general be greater than seven, except when
+ bit 7 of data_type is set, in which case the number of unused bits will be
+ less than eight.
+
+ inflate() should normally be called until it returns Z_STREAM_END or an
+ error. However if all decompression is to be performed in a single step
+ (a single call of inflate), the parameter flush should be set to
+ Z_FINISH. In this case all pending input is processed and all pending
+ output is flushed; avail_out must be large enough to hold all the
+ uncompressed data. (The size of the uncompressed data may have been saved
+ by the compressor for this purpose.) The next operation on this stream must
+ be inflateEnd to deallocate the decompression state. The use of Z_FINISH
+ is never required, but can be used to inform inflate that a faster approach
+ may be used for the single inflate() call.
+
+ In this implementation, inflate() always flushes as much output as
+ possible to the output buffer, and always uses the faster approach on the
+ first call. So the only effect of the flush parameter in this implementation
+ is on the return value of inflate(), as noted below, or when it returns early
+ because Z_BLOCK is used.
+
+ If a preset dictionary is needed after this call (see inflateSetDictionary
+ below), inflate sets strm->adler to the adler32 checksum of the dictionary
+ chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
+ strm->adler to the adler32 checksum of all output produced so far (that is,
+ total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
+ below. At the end of the stream, inflate() checks that its computed adler32
+ checksum is equal to that saved by the compressor and returns Z_STREAM_END
+ only if the checksum is correct.
+
+ inflate() will decompress and check either zlib-wrapped or gzip-wrapped
+ deflate data. The header type is detected automatically. Any information
+ contained in the gzip header is not retained, so applications that need that
+ information should instead use raw inflate, see inflateInit2() below, or
+ inflateBack() and perform their own processing of the gzip header and
+ trailer.
+
+ inflate() returns Z_OK if some progress has been made (more input processed
+ or more output produced), Z_STREAM_END if the end of the compressed data has
+ been reached and all uncompressed output has been produced, Z_NEED_DICT if a
+ preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
+ corrupted (input stream not conforming to the zlib format or incorrect check
+ value), Z_STREAM_ERROR if the stream structure was inconsistent (for example
+ if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory,
+ Z_BUF_ERROR if no progress is possible or if there was not enough room in the
+ output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
+ inflate() can be called again with more input and more output space to
+ continue decompressing. If Z_DATA_ERROR is returned, the application may then
+ call inflateSync() to look for a good compression block if a partial recovery
+ of the data is desired.
+*/
+
+
+ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
+/*
+ All dynamically allocated data structures for this stream are freed.
+ This function discards any unprocessed input and does not flush any
+ pending output.
+
+ inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
+ was inconsistent. In the error case, msg may be set but then points to a
+ static string (which must not be deallocated).
+*/
+
+ /* Advanced functions */
+
+/*
+ The following functions are needed only in some special applications.
+*/
+
+/*
+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
+ int level,
+ int method,
+ int windowBits,
+ int memLevel,
+ int strategy));
+
+ This is another version of deflateInit with more compression options. The
+ fields next_in, zalloc, zfree and opaque must be initialized before by
+ the caller.
+
+ The method parameter is the compression method. It must be Z_DEFLATED in
+ this version of the library.
+
+ The windowBits parameter is the base two logarithm of the window size
+ (the size of the history buffer). It should be in the range 8..15 for this
+ version of the library. Larger values of this parameter result in better
+ compression at the expense of memory usage. The default value is 15 if
+ deflateInit is used instead.
+
+ windowBits can also be -8..-15 for raw deflate. In this case, -windowBits
+ determines the window size. deflate() will then generate raw deflate data
+ with no zlib header or trailer, and will not compute an adler32 check value.
+
+ windowBits can also be greater than 15 for optional gzip encoding. Add
+ 16 to windowBits to write a simple gzip header and trailer around the
+ compressed data instead of a zlib wrapper. The gzip header will have no
+ file name, no extra data, no comment, no modification time (set to zero),
+ no header crc, and the operating system will be set to 255 (unknown). If a
+ gzip stream is being written, strm->adler is a crc32 instead of an adler32.
+
+ The memLevel parameter specifies how much memory should be allocated
+ for the internal compression state. memLevel=1 uses minimum memory but
+ is slow and reduces compression ratio; memLevel=9 uses maximum memory
+ for optimal speed. The default value is 8. See zconf.h for total memory
+ usage as a function of windowBits and memLevel.
+
+ The strategy parameter is used to tune the compression algorithm. Use the
+ value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
+ filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
+ string match), or Z_RLE to limit match distances to one (run-length
+ encoding). Filtered data consists mostly of small values with a somewhat
+ random distribution. In this case, the compression algorithm is tuned to
+ compress them better. The effect of Z_FILTERED is to force more Huffman
+ coding and less string matching; it is somewhat intermediate between
+ Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as
+ Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy
+ parameter only affects the compression ratio but not the correctness of the
+ compressed output even if it is not set appropriately. Z_FIXED prevents the
+ use of dynamic Huffman codes, allowing for a simpler decoder for special
+ applications.
+
+ deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
+ method). msg is set to null if there is no error message. deflateInit2 does
+ not perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
+ const Bytef *dictionary,
+ uInt dictLength));
+/*
+ Initializes the compression dictionary from the given byte sequence
+ without producing any compressed output. This function must be called
+ immediately after deflateInit, deflateInit2 or deflateReset, before any
+ call of deflate. The compressor and decompressor must use exactly the same
+ dictionary (see inflateSetDictionary).
+
+ The dictionary should consist of strings (byte sequences) that are likely
+ to be encountered later in the data to be compressed, with the most commonly
+ used strings preferably put towards the end of the dictionary. Using a
+ dictionary is most useful when the data to be compressed is short and can be
+ predicted with good accuracy; the data can then be compressed better than
+ with the default empty dictionary.
+
+ Depending on the size of the compression data structures selected by
+ deflateInit or deflateInit2, a part of the dictionary may in effect be
+ discarded, for example if the dictionary is larger than the window size in
+ deflate or deflate2. Thus the strings most likely to be useful should be
+ put at the end of the dictionary, not at the front. In addition, the
+ current implementation of deflate will use at most the window size minus
+ 262 bytes of the provided dictionary.
+
+ Upon return of this function, strm->adler is set to the adler32 value
+ of the dictionary; the decompressor may later use this value to determine
+ which dictionary has been used by the compressor. (The adler32 value
+ applies to the whole dictionary even if only a subset of the dictionary is
+ actually used by the compressor.) If a raw deflate was requested, then the
+ adler32 value is not computed and strm->adler is not set.
+
+ deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
+ parameter is invalid (such as NULL dictionary) or the stream state is
+ inconsistent (for example if deflate has already been called for this stream
+ or if the compression method is bsort). deflateSetDictionary does not
+ perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
+ z_streamp source));
+/*
+ Sets the destination stream as a complete copy of the source stream.
+
+ This function can be useful when several compression strategies will be
+ tried, for example when there are several ways of pre-processing the input
+ data with a filter. The streams that will be discarded should then be freed
+ by calling deflateEnd. Note that deflateCopy duplicates the internal
+ compression state which can be quite large, so this strategy is slow and
+ can consume lots of memory.
+
+ deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+ (such as zalloc being NULL). msg is left unchanged in both source and
+ destination.
+*/
+
+ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
+/*
+ This function is equivalent to deflateEnd followed by deflateInit,
+ but does not free and reallocate all the internal compression state.
+ The stream will keep the same compression level and any other attributes
+ that may have been set by deflateInit2.
+
+ deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being NULL).
+*/
+
+ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
+ int level,
+ int strategy));
+/*
+ Dynamically update the compression level and compression strategy. The
+ interpretation of level and strategy is as in deflateInit2. This can be
+ used to switch between compression and straight copy of the input data, or
+ to switch to a different kind of input data requiring a different
+ strategy. If the compression level is changed, the input available so far
+ is compressed with the old level (and may be flushed); the new level will
+ take effect only at the next call of deflate().
+
+ Before the call of deflateParams, the stream state must be set as for
+ a call of deflate(), since the currently available input may have to
+ be compressed and flushed. In particular, strm->avail_out must be non-zero.
+
+ deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
+ stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
+ if strm->avail_out was zero.
+*/
+
+ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
+ int good_length,
+ int max_lazy,
+ int nice_length,
+ int max_chain));
+/*
+ Fine tune deflate's internal compression parameters. This should only be
+ used by someone who understands the algorithm used by zlib's deflate for
+ searching for the best matching string, and even then only by the most
+ fanatic optimizer trying to squeeze out the last compressed bit for their
+ specific input data. Read the deflate.c source code for the meaning of the
+ max_lazy, good_length, nice_length, and max_chain parameters.
+
+ deflateTune() can be called after deflateInit() or deflateInit2(), and
+ returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
+ */
+
+ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
+ uLong sourceLen));
+/*
+ deflateBound() returns an upper bound on the compressed size after
+ deflation of sourceLen bytes. It must be called after deflateInit()
+ or deflateInit2(). This would be used to allocate an output buffer
+ for deflation in a single pass, and so would be called before deflate().
+*/
+
+ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
+ int bits,
+ int value));
+/*
+ deflatePrime() inserts bits in the deflate output stream. The intent
+ is that this function is used to start off the deflate output with the
+ bits leftover from a previous deflate stream when appending to it. As such,
+ this function can only be used for raw deflate, and must be used before the
+ first deflate() call after a deflateInit2() or deflateReset(). bits must be
+ less than or equal to 16, and that many of the least significant bits of
+ value will be inserted in the output.
+
+ deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
+ gz_headerp head));
+/*
+ deflateSetHeader() provides gzip header information for when a gzip
+ stream is requested by deflateInit2(). deflateSetHeader() may be called
+ after deflateInit2() or deflateReset() and before the first call of
+ deflate(). The text, time, os, extra field, name, and comment information
+ in the provided gz_header structure are written to the gzip header (xflag is
+ ignored -- the extra flags are set according to the compression level). The
+ caller must assure that, if not Z_NULL, name and comment are terminated with
+ a zero byte, and that if extra is not Z_NULL, that extra_len bytes are
+ available there. If hcrc is true, a gzip header crc is included. Note that
+ the current versions of the command-line version of gzip (up through version
+ 1.3.x) do not support header crc's, and will report that it is a "multi-part
+ gzip file" and give up.
+
+ If deflateSetHeader is not used, the default gzip header has text false,
+ the time set to zero, and os set to 255, with no extra, name, or comment
+ fields. The gzip header is returned to the default state by deflateReset().
+
+ deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
+ int windowBits));
+
+ This is another version of inflateInit with an extra parameter. The
+ fields next_in, avail_in, zalloc, zfree and opaque must be initialized
+ before by the caller.
+
+ The windowBits parameter is the base two logarithm of the maximum window
+ size (the size of the history buffer). It should be in the range 8..15 for
+ this version of the library. The default value is 15 if inflateInit is used
+ instead. windowBits must be greater than or equal to the windowBits value
+ provided to deflateInit2() while compressing, or it must be equal to 15 if
+ deflateInit2() was not used. If a compressed stream with a larger window
+ size is given as input, inflate() will return with the error code
+ Z_DATA_ERROR instead of trying to allocate a larger window.
+
+ windowBits can also be -8..-15 for raw inflate. In this case, -windowBits
+ determines the window size. inflate() will then process raw deflate data,
+ not looking for a zlib or gzip header, not generating a check value, and not
+ looking for any check values for comparison at the end of the stream. This
+ is for use with other formats that use the deflate compressed data format
+ such as zip. Those formats provide their own check values. If a custom
+ format is developed using the raw deflate format for compressed data, it is
+ recommended that a check value such as an adler32 or a crc32 be applied to
+ the uncompressed data as is done in the zlib, gzip, and zip formats. For
+ most applications, the zlib format should be used as is. Note that comments
+ above on the use in deflateInit2() applies to the magnitude of windowBits.
+
+ windowBits can also be greater than 15 for optional gzip decoding. Add
+ 32 to windowBits to enable zlib and gzip decoding with automatic header
+ detection, or add 16 to decode only the gzip format (the zlib format will
+ return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is
+ a crc32 instead of an adler32.
+
+ inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg
+ is set to null if there is no error message. inflateInit2 does not perform
+ any decompression apart from reading the zlib header if present: this will
+ be done by inflate(). (So next_in and avail_in may be modified, but next_out
+ and avail_out are unchanged.)
+*/
+
+ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
+ const Bytef *dictionary,
+ uInt dictLength));
+/*
+ Initializes the decompression dictionary from the given uncompressed byte
+ sequence. This function must be called immediately after a call of inflate,
+ if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
+ can be determined from the adler32 value returned by that call of inflate.
+ The compressor and decompressor must use exactly the same dictionary (see
+ deflateSetDictionary). For raw inflate, this function can be called
+ immediately after inflateInit2() or inflateReset() and before any call of
+ inflate() to set the dictionary. The application must insure that the
+ dictionary that was used for compression is provided.
+
+ inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
+ parameter is invalid (such as NULL dictionary) or the stream state is
+ inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
+ expected one (incorrect adler32 value). inflateSetDictionary does not
+ perform any decompression: this will be done by subsequent calls of
+ inflate().
+*/
+
+ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
+/*
+ Skips invalid compressed data until a full flush point (see above the
+ description of deflate with Z_FULL_FLUSH) can be found, or until all
+ available input is skipped. No output is provided.
+
+ inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
+ if no more input was provided, Z_DATA_ERROR if no flush point has been found,
+ or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
+ case, the application may save the current current value of total_in which
+ indicates where valid compressed data was found. In the error case, the
+ application may repeatedly call inflateSync, providing more input each time,
+ until success or end of the input data.
+*/
+
+ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
+ z_streamp source));
+/*
+ Sets the destination stream as a complete copy of the source stream.
+
+ This function can be useful when randomly accessing a large stream. The
+ first pass through the stream can periodically record the inflate state,
+ allowing restarting inflate at those points when randomly accessing the
+ stream.
+
+ inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+ (such as zalloc being NULL). msg is left unchanged in both source and
+ destination.
+*/
+
+ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
+/*
+ This function is equivalent to inflateEnd followed by inflateInit,
+ but does not free and reallocate all the internal decompression state.
+ The stream will keep attributes that may have been set by inflateInit2.
+
+ inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being NULL).
+*/
+
+ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
+ int bits,
+ int value));
+/*
+ This function inserts bits in the inflate input stream. The intent is
+ that this function is used to start inflating at a bit position in the
+ middle of a byte. The provided bits will be used before any bytes are used
+ from next_in. This function should only be used with raw inflate, and
+ should be used before the first inflate() call after inflateInit2() or
+ inflateReset(). bits must be less than or equal to 16, and that many of the
+ least significant bits of value will be inserted in the input.
+
+ inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
+ gz_headerp head));
+/*
+ inflateGetHeader() requests that gzip header information be stored in the
+ provided gz_header structure. inflateGetHeader() may be called after
+ inflateInit2() or inflateReset(), and before the first call of inflate().
+ As inflate() processes the gzip stream, head->done is zero until the header
+ is completed, at which time head->done is set to one. If a zlib stream is
+ being decoded, then head->done is set to -1 to indicate that there will be
+ no gzip header information forthcoming. Note that Z_BLOCK can be used to
+ force inflate() to return immediately after header processing is complete
+ and before any actual data is decompressed.
+
+ The text, time, xflags, and os fields are filled in with the gzip header
+ contents. hcrc is set to true if there is a header CRC. (The header CRC
+ was valid if done is set to one.) If extra is not Z_NULL, then extra_max
+ contains the maximum number of bytes to write to extra. Once done is true,
+ extra_len contains the actual extra field length, and extra contains the
+ extra field, or that field truncated if extra_max is less than extra_len.
+ If name is not Z_NULL, then up to name_max characters are written there,
+ terminated with a zero unless the length is greater than name_max. If
+ comment is not Z_NULL, then up to comm_max characters are written there,
+ terminated with a zero unless the length is greater than comm_max. When
+ any of extra, name, or comment are not Z_NULL and the respective field is
+ not present in the header, then that field is set to Z_NULL to signal its
+ absence. This allows the use of deflateSetHeader() with the returned
+ structure to duplicate the header. However if those fields are set to
+ allocated memory, then the application will need to save those pointers
+ elsewhere so that they can be eventually freed.
+
+ If inflateGetHeader is not used, then the header information is simply
+ discarded. The header is always checked for validity, including the header
+ CRC if present. inflateReset() will reset the process to discard the header
+ information. The application would need to call inflateGetHeader() again to
+ retrieve the header from the next gzip stream.
+
+ inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
+ unsigned char FAR *window));
+
+ Initialize the internal stream state for decompression using inflateBack()
+ calls. The fields zalloc, zfree and opaque in strm must be initialized
+ before the call. If zalloc and zfree are Z_NULL, then the default library-
+ derived memory allocation routines are used. windowBits is the base two
+ logarithm of the window size, in the range 8..15. window is a caller
+ supplied buffer of that size. Except for special applications where it is
+ assured that deflate was used with small window sizes, windowBits must be 15
+ and a 32K byte window must be supplied to be able to decompress general
+ deflate streams.
+
+ See inflateBack() for the usage of these routines.
+
+ inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
+ the paramaters are invalid, Z_MEM_ERROR if the internal state could not
+ be allocated, or Z_VERSION_ERROR if the version of the library does not
+ match the version of the header file.
+*/
+
+typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
+typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
+
+ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
+ in_func in, void FAR *in_desc,
+ out_func out, void FAR *out_desc));
+/*
+ inflateBack() does a raw inflate with a single call using a call-back
+ interface for input and output. This is more efficient than inflate() for
+ file i/o applications in that it avoids copying between the output and the
+ sliding window by simply making the window itself the output buffer. This
+ function trusts the application to not change the output buffer passed by
+ the output function, at least until inflateBack() returns.
+
+ inflateBackInit() must be called first to allocate the internal state
+ and to initialize the state with the user-provided window buffer.
+ inflateBack() may then be used multiple times to inflate a complete, raw
+ deflate stream with each call. inflateBackEnd() is then called to free
+ the allocated state.
+
+ A raw deflate stream is one with no zlib or gzip header or trailer.
+ This routine would normally be used in a utility that reads zip or gzip
+ files and writes out uncompressed files. The utility would decode the
+ header and process the trailer on its own, hence this routine expects
+ only the raw deflate stream to decompress. This is different from the
+ normal behavior of inflate(), which expects either a zlib or gzip header and
+ trailer around the deflate stream.
+
+ inflateBack() uses two subroutines supplied by the caller that are then
+ called by inflateBack() for input and output. inflateBack() calls those
+ routines until it reads a complete deflate stream and writes out all of the
+ uncompressed data, or until it encounters an error. The function's
+ parameters and return types are defined above in the in_func and out_func
+ typedefs. inflateBack() will call in(in_desc, &buf) which should return the
+ number of bytes of provided input, and a pointer to that input in buf. If
+ there is no input available, in() must return zero--buf is ignored in that
+ case--and inflateBack() will return a buffer error. inflateBack() will call
+ out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out()
+ should return zero on success, or non-zero on failure. If out() returns
+ non-zero, inflateBack() will return with an error. Neither in() nor out()
+ are permitted to change the contents of the window provided to
+ inflateBackInit(), which is also the buffer that out() uses to write from.
+ The length written by out() will be at most the window size. Any non-zero
+ amount of input may be provided by in().
+
+ For convenience, inflateBack() can be provided input on the first call by
+ setting strm->next_in and strm->avail_in. If that input is exhausted, then
+ in() will be called. Therefore strm->next_in must be initialized before
+ calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called
+ immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in
+ must also be initialized, and then if strm->avail_in is not zero, input will
+ initially be taken from strm->next_in[0 .. strm->avail_in - 1].
+
+ The in_desc and out_desc parameters of inflateBack() is passed as the
+ first parameter of in() and out() respectively when they are called. These
+ descriptors can be optionally used to pass any information that the caller-
+ supplied in() and out() functions need to do their job.
+
+ On return, inflateBack() will set strm->next_in and strm->avail_in to
+ pass back any unused input that was provided by the last in() call. The
+ return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
+ if in() or out() returned an error, Z_DATA_ERROR if there was a format
+ error in the deflate stream (in which case strm->msg is set to indicate the
+ nature of the error), or Z_STREAM_ERROR if the stream was not properly
+ initialized. In the case of Z_BUF_ERROR, an input or output error can be
+ distinguished using strm->next_in which will be Z_NULL only if in() returned
+ an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to
+ out() returning non-zero. (in() will always be called before out(), so
+ strm->next_in is assured to be defined if out() returns non-zero.) Note
+ that inflateBack() cannot return Z_OK.
+*/
+
+ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
+/*
+ All memory allocated by inflateBackInit() is freed.
+
+ inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream
+ state was inconsistent.
+*/
+
+ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
+/* Return flags indicating compile-time options.
+
+ Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
+ 1.0: size of uInt
+ 3.2: size of uLong
+ 5.4: size of voidpf (pointer)
+ 7.6: size of z_off_t
+
+ Compiler, assembler, and debug options:
+ 8: DEBUG
+ 9: ASMV or ASMINF -- use ASM code
+ 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
+ 11: 0 (reserved)
+
+ One-time table building (smaller code, but not thread-safe if true):
+ 12: BUILDFIXED -- build static block decoding tables when needed
+ 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed
+ 14,15: 0 (reserved)
+
+ Library content (indicates missing functionality):
+ 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking
+ deflate code when not needed)
+ 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect
+ and decode gzip streams (to avoid linking crc code)
+ 18-19: 0 (reserved)
+
+ Operation variations (changes in library functionality):
+ 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate
+ 21: FASTEST -- deflate algorithm with only one, lowest compression level
+ 22,23: 0 (reserved)
+
+ The sprintf variant used by gzprintf (zero is best):
+ 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format
+ 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!
+ 26: 0 = returns value, 1 = void -- 1 means inferred string length returned
+
+ Remainder:
+ 27-31: 0 (reserved)
+ */
+
+
+ /* utility functions */
+
+/*
+ The following utility functions are implemented on top of the
+ basic stream-oriented functions. To simplify the interface, some
+ default options are assumed (compression level and memory usage,
+ standard memory allocation functions). The source code of these
+ utility functions can easily be modified if you need special options.
+*/
+
+ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen));
+/*
+ Compresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total
+ size of the destination buffer, which must be at least the value returned
+ by compressBound(sourceLen). Upon exit, destLen is the actual size of the
+ compressed buffer.
+ This function can be used to compress a whole file at once if the
+ input file is mmap'ed.
+ compress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer.
+*/
+
+ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen,
+ int level));
+/*
+ Compresses the source buffer into the destination buffer. The level
+ parameter has the same meaning as in deflateInit. sourceLen is the byte
+ length of the source buffer. Upon entry, destLen is the total size of the
+ destination buffer, which must be at least the value returned by
+ compressBound(sourceLen). Upon exit, destLen is the actual size of the
+ compressed buffer.
+
+ compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+ Z_STREAM_ERROR if the level parameter is invalid.
+*/
+
+ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
+/*
+ compressBound() returns an upper bound on the compressed size after
+ compress() or compress2() on sourceLen bytes. It would be used before
+ a compress() or compress2() call to allocate the destination buffer.
+*/
+
+ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen));
+/*
+ Decompresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total
+ size of the destination buffer, which must be large enough to hold the
+ entire uncompressed data. (The size of the uncompressed data must have
+ been saved previously by the compressor and transmitted to the decompressor
+ by some mechanism outside the scope of this compression library.)
+ Upon exit, destLen is the actual size of the compressed buffer.
+ This function can be used to decompress a whole file at once if the
+ input file is mmap'ed.
+
+ uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.
+*/
+
+
+typedef voidp gzFile;
+
+ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
+/*
+ Opens a gzip (.gz) file for reading or writing. The mode parameter
+ is as in fopen ("rb" or "wb") but can also include a compression level
+ ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
+ Huffman only compression as in "wb1h", or 'R' for run-length encoding
+ as in "wb1R". (See the description of deflateInit2 for more information
+ about the strategy parameter.)
+
+ gzopen can be used to read a file which is not in gzip format; in this
+ case gzread will directly read from the file without decompression.
+
+ gzopen returns NULL if the file could not be opened or if there was
+ insufficient memory to allocate the (de)compression state; errno
+ can be checked to distinguish the two cases (if errno is zero, the
+ zlib error is Z_MEM_ERROR). */
+
+ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
+/*
+ gzdopen() associates a gzFile with the file descriptor fd. File
+ descriptors are obtained from calls like open, dup, creat, pipe or
+ fileno (in the file has been previously opened with fopen).
+ The mode parameter is as in gzopen.
+ The next call of gzclose on the returned gzFile will also close the
+ file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
+ descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
+ gzdopen returns NULL if there was insufficient memory to allocate
+ the (de)compression state.
+*/
+
+ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
+/*
+ Dynamically update the compression level or strategy. See the description
+ of deflateInit2 for the meaning of these parameters.
+ gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
+ opened for writing.
+*/
+
+ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
+/*
+ Reads the given number of uncompressed bytes from the compressed file.
+ If the input file was not in gzip format, gzread copies the given number
+ of bytes into the buffer.
+ gzread returns the number of uncompressed bytes actually read (0 for
+ end of file, -1 for error). */
+
+ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
+ voidpc buf, unsigned len));
+/*
+ Writes the given number of uncompressed bytes into the compressed file.
+ gzwrite returns the number of uncompressed bytes actually written
+ (0 in case of error).
+*/
+
+ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
+/*
+ Converts, formats, and writes the args to the compressed file under
+ control of the format string, as in fprintf. gzprintf returns the number of
+ uncompressed bytes actually written (0 in case of error). The number of
+ uncompressed bytes written is limited to 4095. The caller should assure that
+ this limit is not exceeded. If it is exceeded, then gzprintf() will return
+ return an error (0) with nothing written. In this case, there may also be a
+ buffer overflow with unpredictable consequences, which is possible only if
+ zlib was compiled with the insecure functions sprintf() or vsprintf()
+ because the secure snprintf() or vsnprintf() functions were not available.
+*/
+
+ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
+/*
+ Writes the given null-terminated string to the compressed file, excluding
+ the terminating null character.
+ gzputs returns the number of characters written, or -1 in case of error.
+*/
+
+ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
+/*
+ Reads bytes from the compressed file until len-1 characters are read, or
+ a newline character is read and transferred to buf, or an end-of-file
+ condition is encountered. The string is then terminated with a null
+ character.
+ gzgets returns buf, or Z_NULL in case of error.
+*/
+
+ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
+/*
+ Writes c, converted to an unsigned char, into the compressed file.
+ gzputc returns the value that was written, or -1 in case of error.
+*/
+
+ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
+/*
+ Reads one byte from the compressed file. gzgetc returns this byte
+ or -1 in case of end of file or error.
+*/
+
+ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
+/*
+ Push one character back onto the stream to be read again later.
+ Only one character of push-back is allowed. gzungetc() returns the
+ character pushed, or -1 on failure. gzungetc() will fail if a
+ character has been pushed but not read yet, or if c is -1. The pushed
+ character will be discarded if the stream is repositioned with gzseek()
+ or gzrewind().
+*/
+
+ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
+/*
+ Flushes all pending output into the compressed file. The parameter
+ flush is as in the deflate() function. The return value is the zlib
+ error number (see function gzerror below). gzflush returns Z_OK if
+ the flush parameter is Z_FINISH and all output could be flushed.
+ gzflush should be called only when strictly necessary because it can
+ degrade compression.
+*/
+
+ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
+ z_off_t offset, int whence));
+/*
+ Sets the starting position for the next gzread or gzwrite on the
+ given compressed file. The offset represents a number of bytes in the
+ uncompressed data stream. The whence parameter is defined as in lseek(2);
+ the value SEEK_END is not supported.
+ If the file is opened for reading, this function is emulated but can be
+ extremely slow. If the file is opened for writing, only forward seeks are
+ supported; gzseek then compresses a sequence of zeroes up to the new
+ starting position.
+
+ gzseek returns the resulting offset location as measured in bytes from
+ the beginning of the uncompressed stream, or -1 in case of error, in
+ particular if the file is opened for writing and the new starting position
+ would be before the current position.
+*/
+
+ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
+/*
+ Rewinds the given file. This function is supported only for reading.
+
+ gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
+*/
+
+ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
+/*
+ Returns the starting position for the next gzread or gzwrite on the
+ given compressed file. This position represents a number of bytes in the
+ uncompressed data stream.
+
+ gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
+*/
+
+ZEXTERN int ZEXPORT gzeof OF((gzFile file));
+/*
+ Returns 1 when EOF has previously been detected reading the given
+ input stream, otherwise zero.
+*/
+
+ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
+/*
+ Returns 1 if file is being read directly without decompression, otherwise
+ zero.
+*/
+
+ZEXTERN int ZEXPORT gzclose OF((gzFile file));
+/*
+ Flushes all pending output if necessary, closes the compressed file
+ and deallocates all the (de)compression state. The return value is the zlib
+ error number (see function gzerror below).
+*/
+
+ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
+/*
+ Returns the error message for the last error which occurred on the
+ given compressed file. errnum is set to zlib error number. If an
+ error occurred in the file system and not in the compression library,
+ errnum is set to Z_ERRNO and the application may consult errno
+ to get the exact error code.
+*/
+
+ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
+/*
+ Clears the error and end-of-file flags for file. This is analogous to the
+ clearerr() function in stdio. This is useful for continuing to read a gzip
+ file that is being written concurrently.
+*/
+
+ /* checksum functions */
+
+/*
+ These functions are not related to compression but are exported
+ anyway because they might be useful in applications using the
+ compression library.
+*/
+
+ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
+/*
+ Update a running Adler-32 checksum with the bytes buf[0..len-1] and
+ return the updated checksum. If buf is NULL, this function returns
+ the required initial value for the checksum.
+ An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
+ much faster. Usage example:
+
+ uLong adler = adler32(0L, Z_NULL, 0);
+
+ while (read_buffer(buffer, length) != EOF) {
+ adler = adler32(adler, buffer, length);
+ }
+ if (adler != original_adler) error();
+*/
+
+ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
+ z_off_t len2));
+/*
+ Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
+ and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
+ each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
+ seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.
+*/
+
+ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
+/*
+ Update a running CRC-32 with the bytes buf[0..len-1] and return the
+ updated CRC-32. If buf is NULL, this function returns the required initial
+ value for the for the crc. Pre- and post-conditioning (one's complement) is
+ performed within this function so it shouldn't be done by the application.
+ Usage example:
+
+ uLong crc = crc32(0L, Z_NULL, 0);
+
+ while (read_buffer(buffer, length) != EOF) {
+ crc = crc32(crc, buffer, length);
+ }
+ if (crc != original_crc) error();
+*/
+
+ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
+
+/*
+ Combine two CRC-32 check values into one. For two sequences of bytes,
+ seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
+ calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32
+ check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
+ len2.
+*/
+
+
+ /* various hacks, don't look :) */
+
+/* deflateInit and inflateInit are macros to allow checking the zlib version
+ * and the compiler's view of z_stream:
+ */
+ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
+ int windowBits, int memLevel,
+ int strategy, const char *version,
+ int stream_size));
+ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
+ unsigned char FAR *window,
+ const char *version,
+ int stream_size));
+#define deflateInit(strm, level) \
+ deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
+#define inflateInit(strm) \
+ inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
+#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
+ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
+ (strategy), ZLIB_VERSION, sizeof(z_stream))
+#define inflateInit2(strm, windowBits) \
+ inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
+#define inflateBackInit(strm, windowBits, window) \
+ inflateBackInit_((strm), (windowBits), (window), \
+ ZLIB_VERSION, sizeof(z_stream))
+
+
+#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
+ struct internal_state {int dummy;}; /* hack for buggy compilers */
+#endif
+
+ZEXTERN const char * ZEXPORT zError OF((int));
+ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z));
+ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ZLIB_H */
diff --git a/Utilities/cmzlib/zlib.rc b/Utilities/cmzlib/zlib.rc
new file mode 100644
index 000000000..aabc59b68
--- /dev/null
+++ b/Utilities/cmzlib/zlib.rc
@@ -0,0 +1,32 @@
+#include <windows.h>
+
+#define IDR_VERSION1 1
+IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE
+ FILEVERSION 1,2,3,0
+ PRODUCTVERSION 1,2,3,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0
+ FILEOS VOS_DOS_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE 0 // not used
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904E4"
+ //language ID = U.S. English, char set = Windows, Multilingual
+
+ BEGIN
+ VALUE "FileDescription", "zlib data compression library\0"
+ VALUE "FileVersion", "1.2.3\0"
+ VALUE "InternalName", "zlib\0"
+ VALUE "OriginalFilename", "zlib.dll\0"
+ VALUE "ProductName", "ZLib.DLL\0"
+ VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0"
+ VALUE "LegalCopyright", "(C) 1995-2005 Jean-loup Gailly & Mark Adler\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0409, 1252
+ END
+END
diff --git a/Utilities/cmzlib/zlibDllConfig.h.in b/Utilities/cmzlib/zlibDllConfig.h.in
new file mode 100644
index 000000000..3dceb8c5d
--- /dev/null
+++ b/Utilities/cmzlib/zlibDllConfig.h.in
@@ -0,0 +1,6 @@
+#ifndef _zlibDllConfig_h
+#define _zlibDllConfig_h
+
+#cmakedefine ZLIB_DLL
+
+#endif
diff --git a/Utilities/cmzlib/zutil.c b/Utilities/cmzlib/zutil.c
new file mode 100644
index 000000000..d55f5948a
--- /dev/null
+++ b/Utilities/cmzlib/zutil.c
@@ -0,0 +1,318 @@
+/* zutil.c -- target dependent utility functions for the compression library
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#include "zutil.h"
+
+#ifndef NO_DUMMY_DECL
+struct internal_state {int dummy;}; /* for buggy compilers */
+#endif
+
+const char * const z_errmsg[10] = {
+"need dictionary", /* Z_NEED_DICT 2 */
+"stream end", /* Z_STREAM_END 1 */
+"", /* Z_OK 0 */
+"file error", /* Z_ERRNO (-1) */
+"stream error", /* Z_STREAM_ERROR (-2) */
+"data error", /* Z_DATA_ERROR (-3) */
+"insufficient memory", /* Z_MEM_ERROR (-4) */
+"buffer error", /* Z_BUF_ERROR (-5) */
+"incompatible version",/* Z_VERSION_ERROR (-6) */
+""};
+
+
+const char * ZEXPORT zlibVersion()
+{
+ return ZLIB_VERSION;
+}
+
+uLong ZEXPORT zlibCompileFlags()
+{
+ uLong flags;
+
+ flags = 0;
+ switch (sizeof(uInt)) {
+ case 2: break;
+ case 4: flags += 1; break;
+ case 8: flags += 2; break;
+ default: flags += 3;
+ }
+ switch (sizeof(uLong)) {
+ case 2: break;
+ case 4: flags += 1 << 2; break;
+ case 8: flags += 2 << 2; break;
+ default: flags += 3 << 2;
+ }
+ switch (sizeof(voidpf)) {
+ case 2: break;
+ case 4: flags += 1 << 4; break;
+ case 8: flags += 2 << 4; break;
+ default: flags += 3 << 4;
+ }
+ switch (sizeof(z_off_t)) {
+ case 2: break;
+ case 4: flags += 1 << 6; break;
+ case 8: flags += 2 << 6; break;
+ default: flags += 3 << 6;
+ }
+#ifdef DEBUG
+ flags += 1 << 8;
+#endif
+#if defined(ASMV) || defined(ASMINF)
+ flags += 1 << 9;
+#endif
+#ifdef ZLIB_WINAPI
+ flags += 1 << 10;
+#endif
+#ifdef BUILDFIXED
+ flags += 1 << 12;
+#endif
+#ifdef DYNAMIC_CRC_TABLE
+ flags += 1 << 13;
+#endif
+#ifdef NO_GZCOMPRESS
+ flags += 1L << 16;
+#endif
+#ifdef NO_GZIP
+ flags += 1L << 17;
+#endif
+#ifdef PKZIP_BUG_WORKAROUND
+ flags += 1L << 20;
+#endif
+#ifdef FASTEST
+ flags += 1L << 21;
+#endif
+#ifdef STDC
+# ifdef NO_vsnprintf
+ flags += 1L << 25;
+# ifdef HAS_vsprintf_void
+ flags += 1L << 26;
+# endif
+# else
+# ifdef HAS_vsnprintf_void
+ flags += 1L << 26;
+# endif
+# endif
+#else
+ flags += 1L << 24;
+# ifdef NO_snprintf
+ flags += 1L << 25;
+# ifdef HAS_sprintf_void
+ flags += 1L << 26;
+# endif
+# else
+# ifdef HAS_snprintf_void
+ flags += 1L << 26;
+# endif
+# endif
+#endif
+ return flags;
+}
+
+#ifdef DEBUG
+
+# ifndef verbose
+# define verbose 0
+# endif
+int z_verbose = verbose;
+
+void z_error (m)
+ char *m;
+{
+ fprintf(stderr, "%s\n", m);
+ exit(1);
+}
+#endif
+
+/* exported to allow conversion of error code to string for compress() and
+ * uncompress()
+ */
+const char * ZEXPORT zError(err)
+ int err;
+{
+ return ERR_MSG(err);
+}
+
+#if defined(_WIN32_WCE)
+ /* The Microsoft C Run-Time Library for Windows CE doesn't have
+ * errno. We define it as a global variable to simplify porting.
+ * Its value is always 0 and should not be used.
+ */
+ int errno = 0;
+#endif
+
+#ifndef HAVE_MEMCPY
+
+void zmemcpy(dest, source, len)
+ Bytef* dest;
+ const Bytef* source;
+ uInt len;
+{
+ if (len == 0) return;
+ do {
+ *dest++ = *source++; /* ??? to be unrolled */
+ } while (--len != 0);
+}
+
+int zmemcmp(s1, s2, len)
+ const Bytef* s1;
+ const Bytef* s2;
+ uInt len;
+{
+ uInt j;
+
+ for (j = 0; j < len; j++) {
+ if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
+ }
+ return 0;
+}
+
+void zmemzero(dest, len)
+ Bytef* dest;
+ uInt len;
+{
+ if (len == 0) return;
+ do {
+ *dest++ = 0; /* ??? to be unrolled */
+ } while (--len != 0);
+}
+#endif
+
+
+#ifdef SYS16BIT
+
+#ifdef __TURBOC__
+/* Turbo C in 16-bit mode */
+
+# define MY_ZCALLOC
+
+/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
+ * and farmalloc(64K) returns a pointer with an offset of 8, so we
+ * must fix the pointer. Warning: the pointer must be put back to its
+ * original form in order to free it, use zcfree().
+ */
+
+#define MAX_PTR 10
+/* 10*64K = 640K */
+
+local int next_ptr = 0;
+
+typedef struct ptr_table_s {
+ voidpf org_ptr;
+ voidpf new_ptr;
+} ptr_table;
+
+local ptr_table table[MAX_PTR];
+/* This table is used to remember the original form of pointers
+ * to large buffers (64K). Such pointers are normalized with a zero offset.
+ * Since MSDOS is not a preemptive multitasking OS, this table is not
+ * protected from concurrent access. This hack doesn't work anyway on
+ * a protected system like OS/2. Use Microsoft C instead.
+ */
+
+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
+{
+ voidpf buf = opaque; /* just to make some compilers happy */
+ ulg bsize = (ulg)items*size;
+
+ /* If we allocate less than 65520 bytes, we assume that farmalloc
+ * will return a usable pointer which doesn't have to be normalized.
+ */
+ if (bsize < 65520L) {
+ buf = farmalloc(bsize);
+ if (*(ush*)&buf != 0) return buf;
+ } else {
+ buf = farmalloc(bsize + 16L);
+ }
+ if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
+ table[next_ptr].org_ptr = buf;
+
+ /* Normalize the pointer to seg:0 */
+ *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
+ *(ush*)&buf = 0;
+ table[next_ptr++].new_ptr = buf;
+ return buf;
+}
+
+void zcfree (voidpf opaque, voidpf ptr)
+{
+ int n;
+ if (*(ush*)&ptr != 0) { /* object < 64K */
+ farfree(ptr);
+ return;
+ }
+ /* Find the original pointer */
+ for (n = 0; n < next_ptr; n++) {
+ if (ptr != table[n].new_ptr) continue;
+
+ farfree(table[n].org_ptr);
+ while (++n < next_ptr) {
+ table[n-1] = table[n];
+ }
+ next_ptr--;
+ return;
+ }
+ ptr = opaque; /* just to make some compilers happy */
+ Assert(0, "zcfree: ptr not found");
+}
+
+#endif /* __TURBOC__ */
+
+
+#ifdef M_I86
+/* Microsoft C in 16-bit mode */
+
+# define MY_ZCALLOC
+
+#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
+# define _halloc halloc
+# define _hfree hfree
+#endif
+
+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
+{
+ if (opaque) opaque = 0; /* to make compiler happy */
+ return _halloc((long)items, size);
+}
+
+void zcfree (voidpf opaque, voidpf ptr)
+{
+ if (opaque) opaque = 0; /* to make compiler happy */
+ _hfree(ptr);
+}
+
+#endif /* M_I86 */
+
+#endif /* SYS16BIT */
+
+
+#ifndef MY_ZCALLOC /* Any system without a special alloc function */
+
+#ifndef STDC
+extern voidp malloc OF((uInt size));
+extern voidp calloc OF((uInt items, uInt size));
+extern void free OF((voidpf ptr));
+#endif
+
+voidpf zcalloc (opaque, items, size)
+ voidpf opaque;
+ unsigned items;
+ unsigned size;
+{
+ if (opaque) items += size - size; /* make compiler happy */
+ return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
+ (voidpf)calloc(items, size);
+}
+
+void zcfree (opaque, ptr)
+ voidpf opaque;
+ voidpf ptr;
+{
+ free(ptr);
+ if (opaque) return; /* make compiler happy */
+}
+
+#endif /* MY_ZCALLOC */
diff --git a/Utilities/cmzlib/zutil.h b/Utilities/cmzlib/zutil.h
new file mode 100644
index 000000000..74ef1f89f
--- /dev/null
+++ b/Utilities/cmzlib/zutil.h
@@ -0,0 +1,275 @@
+/* zutil.h -- internal interface and configuration of the compression library
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZUTIL_H
+#define ZUTIL_H
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+#ifdef STDC
+# ifndef _WIN32_WCE
+# include <stddef.h>
+# endif
+# include <string.h>
+# include <stdlib.h>
+#endif
+#ifdef NO_ERRNO_H
+# ifdef _WIN32_WCE
+ /* The Microsoft C Run-Time Library for Windows CE doesn't have
+ * errno. We define it as a global variable to simplify porting.
+ * Its value is always 0 and should not be used. We rename it to
+ * avoid conflict with other libraries that use the same workaround.
+ */
+# define errno z_errno
+# endif
+ extern int errno;
+#else
+# ifndef _WIN32_WCE
+# include <errno.h>
+# endif
+#endif
+
+#ifndef local
+# define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+typedef unsigned char uch;
+typedef uch FAR uchf;
+typedef unsigned short ush;
+typedef ush FAR ushf;
+typedef unsigned long ulg;
+
+extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
+/* (size given to avoid silly warnings with Visual C++) */
+
+#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
+
+#define ERR_RETURN(strm,err) \
+ return (strm->msg = (char*)ERR_MSG(err), (err))
+/* To be used only when the state is known to be valid */
+
+ /* common constants */
+
+#ifndef DEF_WBITS
+# define DEF_WBITS MAX_WBITS
+#endif
+/* default windowBits for decompression. MAX_WBITS is for compression only */
+
+#if MAX_MEM_LEVEL >= 8
+# define DEF_MEM_LEVEL 8
+#else
+# define DEF_MEM_LEVEL MAX_MEM_LEVEL
+#endif
+/* default memLevel */
+
+#define STORED_BLOCK 0
+#define STATIC_TREES 1
+#define DYN_TREES 2
+/* The three kinds of block type */
+
+#define MIN_MATCH 3
+#define MAX_MATCH 258
+/* The minimum and maximum match lengths */
+
+#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
+
+ /* target dependencies */
+
+#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
+# define OS_CODE 0x00
+# if defined(__TURBOC__) || defined(__BORLANDC__)
+# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
+ /* Allow compilation with ANSI keywords only enabled */
+ void _Cdecl farfree( void *block );
+ void *_Cdecl farmalloc( unsigned long nbytes );
+# else
+# include <alloc.h>
+# endif
+# else /* MSC or DJGPP */
+# include <malloc.h>
+# endif
+#endif
+
+#ifdef AMIGA
+# define OS_CODE 0x01
+#endif
+
+#if defined(VAXC) || defined(VMS)
+# define OS_CODE 0x02
+# define F_OPEN(name, mode) \
+ fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
+#endif
+
+#if defined(ATARI) || defined(atarist)
+# define OS_CODE 0x05
+#endif
+
+#ifdef OS2
+# define OS_CODE 0x06
+# ifdef M_I86
+ #include <malloc.h>
+# endif
+#endif
+
+#if defined(MACOS) || defined(TARGET_OS_MAC)
+# define OS_CODE 0x07
+# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
+# include <unix.h> /* for fdopen */
+# else
+# ifndef fdopen
+# define fdopen(fd,mode) NULL /* No fdopen() */
+# endif
+# endif
+#endif
+
+#ifdef TOPS20
+# define OS_CODE 0x0a
+#endif
+
+#ifdef WIN32
+# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */
+# define OS_CODE 0x0b
+# endif
+#endif
+
+#ifdef __50SERIES /* Prime/PRIMOS */
+# 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
+
+#if (defined(_MSC_VER) && (_MSC_VER > 600))
+# if defined(_WIN32_WCE)
+# define fdopen(fd,mode) NULL /* No fdopen() */
+# ifndef _PTRDIFF_T_DEFINED
+ typedef int ptrdiff_t;
+# define _PTRDIFF_T_DEFINED
+# endif
+# else
+# define fdopen(fd,type) _fdopen(fd,type)
+# endif
+#endif
+
+ /* common defaults */
+
+#ifndef OS_CODE
+# define OS_CODE 0x03 /* assume Unix */
+#endif
+
+#ifndef F_OPEN
+# define F_OPEN(name, mode) fopen((name), (mode))
+#endif
+
+ /* functions */
+
+#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
+# ifndef HAVE_VSNPRINTF
+# define HAVE_VSNPRINTF
+# endif
+#endif
+#if defined(__CYGWIN__)
+# ifndef HAVE_VSNPRINTF
+# define HAVE_VSNPRINTF
+# endif
+#endif
+#ifndef HAVE_VSNPRINTF
+# ifdef MSDOS
+ /* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
+ but for now we just assume it doesn't. */
+# define NO_vsnprintf
+# endif
+# ifdef __TURBOC__
+# define NO_vsnprintf
+# endif
+# ifdef WIN32
+ /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
+# if !defined(vsnprintf) && !defined(NO_vsnprintf)
+# define vsnprintf _vsnprintf
+# endif
+# endif
+# ifdef __SASC
+# define NO_vsnprintf
+# endif
+#endif
+#ifdef VMS
+# define NO_vsnprintf
+#endif
+
+#if defined(pyr)
+# define NO_MEMCPY
+#endif
+#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
+ /* Use our own functions for small and medium model with MSC <= 5.0.
+ * You may have to use the same strategy for Borland C (untested).
+ * The __SC__ check is for Symantec.
+ */
+# define NO_MEMCPY
+#endif
+#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
+# define HAVE_MEMCPY
+#endif
+#ifdef HAVE_MEMCPY
+# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
+# define zmemcpy _fmemcpy
+# define zmemcmp _fmemcmp
+# define zmemzero(dest, len) _fmemset(dest, 0, len)
+# else
+# define zmemcpy memcpy
+# define zmemcmp memcmp
+# define zmemzero(dest, len) memset(dest, 0, len)
+# endif
+#else
+ extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
+ extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
+ extern void zmemzero OF((Bytef* dest, uInt len));
+#endif
+
+/* Diagnostic functions */
+#ifdef DEBUG
+# include <stdio.h>
+ extern int z_verbose;
+ extern void z_error OF((char *m));
+# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
+# define Trace(x) {if (z_verbose>=0) fprintf x ;}
+# define Tracev(x) {if (z_verbose>0) fprintf x ;}
+# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
+# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
+# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
+#else
+# define Assert(cond,msg)
+# define Trace(x)
+# define Tracev(x)
+# define Tracevv(x)
+# define Tracec(c,x)
+# define Tracecv(c,x)
+#endif
+
+
+voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
+void zcfree OF((voidpf opaque, voidpf ptr));
+
+#define ZALLOC(strm, items, size) \
+ (*((strm)->zalloc))((strm)->opaque, (items), (size))
+#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
+#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
+
+#endif /* ZUTIL_H */
diff --git a/Utilities/xml/xhtml-lat1.ent b/Utilities/xml/xhtml-lat1.ent
new file mode 100644
index 000000000..ffee223eb
--- /dev/null
+++ b/Utilities/xml/xhtml-lat1.ent
@@ -0,0 +1,196 @@
+<!-- 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/xhtml-special.ent b/Utilities/xml/xhtml-special.ent
new file mode 100644
index 000000000..3a83fb656
--- /dev/null
+++ b/Utilities/xml/xhtml-special.ent
@@ -0,0 +1,80 @@
+<!-- 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/xhtml-symbol.ent b/Utilities/xml/xhtml-symbol.ent
new file mode 100644
index 000000000..d0c77eebc
--- /dev/null
+++ b/Utilities/xml/xhtml-symbol.ent
@@ -0,0 +1,237 @@
+<!-- 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-strict.dtd b/Utilities/xml/xhtml1-strict.dtd
new file mode 100644
index 000000000..e48fbea6e
--- /dev/null
+++ b/Utilities/xml/xhtml1-strict.dtd
@@ -0,0 +1,977 @@
+<!--
+ 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
new file mode 100755
index 000000000..801882d7a
--- /dev/null
+++ b/bootstrap
@@ -0,0 +1,1564 @@
+#!/bin/sh
+#=============================================================================
+# 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.
+#=============================================================================
+
+die() {
+ echo "$@" 1>&2 ; exit 1
+}
+
+# Version number extraction function.
+cmake_version_component()
+{
+ cat "${cmake_source_dir}/Source/CMakeVersion.cmake" | sed -n "
+/^SET(CMake_VERSION_${1}/ {s/SET(CMake_VERSION_${1} *\([0-9]*\))/\1/;p;}
+"
+}
+
+cmake_toupper()
+{
+ echo "$1" | sed 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'
+}
+
+# Detect system and directory information.
+cmake_system=`uname`
+cmake_source_dir=`cd "\`dirname \"$0\"\`";pwd`
+cmake_binary_dir=`pwd`
+
+# Load version information.
+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}"
+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_init_file=""
+cmake_bootstrap_system_libs=""
+cmake_bootstrap_qt_gui=""
+cmake_bootstrap_qt_qmake=""
+
+# Determine whether this is a Cygwin environment.
+if echo "${cmake_system}" | grep CYGWIN >/dev/null 2>&1; then
+ cmake_system_cygwin=true
+else
+ cmake_system_cygwin=false
+fi
+
+# Determine whether this is a MinGW environment.
+if echo "${cmake_system}" | grep MINGW >/dev/null 2>&1; then
+ cmake_system_mingw=true
+else
+ cmake_system_mingw=false
+fi
+
+# Determine whether this is OS X
+if echo "${cmake_system}" | grep Darwin >/dev/null 2>&1; then
+ cmake_system_darwin=true
+else
+ cmake_system_darwin=false
+fi
+
+# Determine whether this is BeOS
+if echo "${cmake_system}" | grep BeOS >/dev/null 2>&1; then
+ cmake_system_beos=true
+else
+ cmake_system_beos=false
+fi
+
+# Determine whether this is Haiku
+if echo "${cmake_system}" | grep Haiku >/dev/null 2>&1; then
+ cmake_system_haiku=true
+else
+ cmake_system_haiku=false
+fi
+
+# Determine whether this is OpenVMS
+if echo "${cmake_system}" | grep OpenVMS >/dev/null 2>&1; then
+ cmake_system_openvms=true
+else
+ cmake_system_openvms=false
+fi
+
+# Choose the generator to use for bootstrapping.
+if ${cmake_system_mingw}; then
+ # Bootstrapping from an MSYS prompt.
+ cmake_bootstrap_generator="MSYS Makefiles"
+else
+ # Bootstrapping from a standard UNIX prompt.
+ cmake_bootstrap_generator="Unix Makefiles"
+fi
+
+# Choose tools and extensions for this platform.
+if ${cmake_system_openvms}; then
+ _tmp="_tmp"
+ _cmk="_cmk"
+ _diff=`which diff`
+else
+ _tmp=".tmp"
+ _cmk=".cmk"
+ _diff="diff"
+fi
+
+# Construct bootstrap directory name.
+cmake_bootstrap_dir="${cmake_binary_dir}/Bootstrap${_cmk}"
+
+# Helper function to fix windows paths.
+case "${cmake_system}" in
+*MINGW*)
+ cmake_fix_slashes()
+ {
+ cmd //c echo "$(echo "$1" | sed 's/\\/\//g')" | sed 's/^"//;s/" *$//'
+ }
+ ;;
+*)
+ cmake_fix_slashes()
+ {
+ echo "$1" | sed 's/\\/\//g'
+ }
+ ;;
+esac
+
+# Choose the default install prefix.
+if ${cmake_system_mingw}; then
+ if [ "x${PROGRAMFILES}" != "x" ]; then
+ cmake_default_prefix=`cmake_fix_slashes "${PROGRAMFILES}/CMake"`
+ elif [ "x${ProgramFiles}" != "x" ]; then
+ cmake_default_prefix=`cmake_fix_slashes "${ProgramFiles}/CMake"`
+ elif [ "x${SYSTEMDRIVE}" != "x" ]; then
+ cmake_default_prefix=`cmake_fix_slashes "${SYSTEMDRIVE}/Program Files/CMake"`
+ elif [ "x${SystemDrive}" != "x" ]; then
+ cmake_default_prefix=`cmake_fix_slashes "${SystemDrive}/Program Files/CMake"`
+ else
+ cmake_default_prefix="c:/Program Files/CMake"
+ fi
+elif ${cmake_system_haiku}; then
+ cmake_default_prefix=`/bin/finddir B_COMMON_DIRECTORY`
+else
+ cmake_default_prefix="/usr/local"
+fi
+
+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"
+
+CMAKE_PROBLEMATIC_FILES="\
+ CMakeCache.txt \
+ CMakeSystem.cmake \
+ CMakeCCompiler.cmake \
+ CMakeCXXCompiler.cmake \
+ Source/cmConfigure.h \
+ Source/CTest/Curl/config.h \
+ Utilities/cmexpat/expatConfig.h \
+ Utilities/cmexpat/expatDllConfig.h \
+ "
+
+CMAKE_UNUSED_SOURCES="\
+ cmGlobalXCodeGenerator \
+ cmLocalXCodeGenerator \
+ cmXCodeObject \
+ cmXCode21Object \
+ cmSourceGroup \
+"
+
+CMAKE_CXX_SOURCES="\
+ cmStandardIncludes \
+ cmake \
+ cmakemain \
+ cmakewizard \
+ cmCommandArgumentLexer \
+ cmCommandArgumentParser \
+ cmCommandArgumentParserHelper \
+ cmDefinitions \
+ cmDepends \
+ cmDependsC \
+ cmDocumentationFormatter \
+ cmDocumentationFormatterText \
+ cmPolicies \
+ cmProperty \
+ cmPropertyMap \
+ cmPropertyDefinition \
+ cmPropertyDefinitionMap \
+ cmMakeDepend \
+ cmMakefile \
+ cmExportFileGenerator \
+ cmExportInstallFileGenerator \
+ cmInstallDirectoryGenerator \
+ cmGeneratedFileStream \
+ cmGeneratorTarget \
+ cmGeneratorExpression \
+ cmGlobalGenerator \
+ cmLocalGenerator \
+ cmInstallGenerator \
+ cmInstallExportGenerator \
+ cmInstallFilesGenerator \
+ cmInstallScriptGenerator \
+ cmInstallTargetGenerator \
+ cmScriptGenerator \
+ cmSourceFile \
+ cmSourceFileLocation \
+ cmSystemTools \
+ cmTestGenerator \
+ cmVersion \
+ cmFileTimeComparison \
+ cmGlobalUnixMakefileGenerator3 \
+ cmLocalUnixMakefileGenerator3 \
+ cmMakefileExecutableTargetGenerator \
+ cmMakefileLibraryTargetGenerator \
+ cmMakefileTargetGenerator \
+ cmMakefileUtilityTargetGenerator \
+ cmOSXBundleGenerator \
+ cmNewLineStyle \
+ cmBootstrapCommands \
+ cmCommands \
+ cmTarget \
+ cmTest \
+ cmCustomCommand \
+ cmCustomCommandGenerator \
+ cmDocumentVariables \
+ cmCacheManager \
+ cmListFileCache \
+ cmComputeLinkDepends \
+ cmComputeLinkInformation \
+ cmOrderDirectories \
+ cmComputeTargetDepends \
+ cmComputeComponentGraph \
+ cmExprLexer \
+ cmExprParser \
+ cmExprParserHelper \
+ cmGlobalNinjaGenerator \
+ cmLocalNinjaGenerator \
+ cmNinjaTargetGenerator \
+ cmNinjaNormalTargetGenerator \
+ cmNinjaUtilityTargetGenerator \
+"
+
+if ${cmake_system_mingw}; then
+ CMAKE_CXX_SOURCES="${CMAKE_CXX_SOURCES}\
+ cmGlobalMSYSMakefileGenerator \
+ cmGlobalMinGWMakefileGenerator \
+ cmWin32ProcessExecution"
+fi
+
+CMAKE_C_SOURCES="\
+ cmListFileLexer \
+ "
+
+if ${cmake_system_mingw}; then
+ KWSYS_C_SOURCES="\
+ ProcessWin32 \
+ String \
+ System"
+ KWSYS_C_MINGW_SOURCES="\
+ ProcessFwd9x \
+ EncodeExecutable"
+ KWSYS_C_GENERATED_SOURCES="\
+ cmsysProcessFwd9xEnc"
+else
+ KWSYS_C_SOURCES="\
+ ProcessUNIX \
+ String \
+ System"
+ KWSYS_C_MINGW_SOURCES=""
+ KWSYS_C_GENERATED_SOURCES=""
+fi
+
+KWSYS_CXX_SOURCES="\
+ Directory \
+ Glob \
+ RegularExpression \
+ SystemTools"
+
+KWSYS_FILES="\
+ auto_ptr.hxx \
+ Directory.hxx \
+ Glob.hxx \
+ Process.h \
+ RegularExpression.hxx \
+ String.h \
+ String.hxx \
+ System.h \
+ SystemTools.hxx"
+
+KWSYS_IOS_FILES="
+ fstream \
+ iosfwd \
+ iostream \
+ sstream"
+
+# Display CMake bootstrap usage
+cmake_usage()
+{
+echo '
+Usage: '"$0"' [<options>...] [-- <cmake-options>...]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --help print this message
+ --version only print version information
+ --verbose display more information
+ --parallel=n bootstrap cmake in parallel, where n is
+ number of nodes [1]
+ --enable-ccache Enable ccache when building cmake
+ --init=FILE load FILE as script to populate cache
+ --system-libs use all system-installed third-party libraries
+ (for use only by package maintainers)
+ --no-system-libs use all cmake-provided third-party libraries
+ (default)
+ --system-curl use system-installed curl library
+ --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-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-libarchive use system-installed libarchive library
+ --no-system-libarchive use cmake-provided libarchive library (default)
+
+ --qt-gui build the Qt-based GUI (requires Qt >= 4.2)
+ --no-qt-gui do not build the Qt-based GUI (default)
+ --qt-qmake=<qmake> use <qmake> as the qmake executable to find Qt
+
+Directory and file names:
+ --prefix=PREFIX install files in tree rooted at PREFIX
+ [${cmake_default_prefix}]
+ --datadir=DIR install data files in PREFIX/DIR
+ [/share/CMake]
+ --docdir=DIR install documentation files in PREFIX/DIR
+ [/doc/CMake]
+ --mandir=DIR install man pages files in PREFIX/DIR/manN
+ [/man]
+'
+ exit 10
+}
+
+# Display CMake bootstrap usage
+cmake_version_display()
+{
+ echo "CMake ${cmake_version}, Copyright 2000-2011 Kitware, Inc."
+}
+
+# Display CMake bootstrap error, display the log file and exit
+cmake_error()
+{
+ res=$1
+ shift 1
+ echo "---------------------------------------------"
+ echo "Error when bootstrapping CMake:"
+ echo "$*"
+ echo "---------------------------------------------"
+ if [ -f cmake_bootstrap.log ]; then
+ echo "Log of errors: `pwd`/cmake_bootstrap.log"
+ #cat cmake_bootstrap.log
+ echo "---------------------------------------------"
+ fi
+ exit ${res}
+}
+
+# Replace KWSYS_NAMESPACE with cmsys
+cmake_replace_string ()
+{
+ INFILE="$1"
+ OUTFILE="$2"
+ SEARCHFOR="$3"
+ REPLACEWITH="$4"
+ if [ -f "${INFILE}" ] || ${cmake_system_openvms}; then
+ cat "${INFILE}" |
+ sed "s/\@${SEARCHFOR}\@/${REPLACEWITH}/g" > "${OUTFILE}${_tmp}"
+ if [ -f "${OUTFILE}${_tmp}" ]; then
+ if "${_diff}" "${OUTFILE}" "${OUTFILE}${_tmp}" > /dev/null 2> /dev/null ; then
+ #echo "Files are the same"
+ rm -f "${OUTFILE}${_tmp}"
+ else
+ mv -f "${OUTFILE}${_tmp}" "${OUTFILE}"
+ fi
+ fi
+ else
+ cmake_error 1 "Cannot find file ${INFILE}"
+ fi
+}
+
+cmake_kwsys_config_replace_string ()
+{
+ INFILE="$1"
+ OUTFILE="$2"
+ shift 2
+ APPEND="$*"
+ if [ -f "${INFILE}" ] || ${cmake_system_openvms}; then
+ echo "${APPEND}" > "${OUTFILE}${_tmp}"
+ cat "${INFILE}" |
+ sed "/./ {s/\@KWSYS_NAMESPACE\@/cmsys/g;
+ s/@KWSYS_BUILD_SHARED@/${KWSYS_BUILD_SHARED}/g;
+ 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}"
+ if [ -f "${OUTFILE}${_tmp}" ]; then
+ if "${_diff}" "${OUTFILE}" "${OUTFILE}${_tmp}" > /dev/null 2> /dev/null ; then
+ #echo "Files are the same"
+ rm -f "${OUTFILE}${_tmp}"
+ else
+ mv -f "${OUTFILE}${_tmp}" "${OUTFILE}"
+ fi
+ fi
+ else
+ cmake_error 2 "Cannot find file ${INFILE}"
+ fi
+}
+# Write string into a file
+cmake_report ()
+{
+ FILE=$1
+ shift
+ echo "$*" >> ${FILE}
+}
+
+# Escape spaces in strings
+cmake_escape ()
+{
+ echo $1 | sed "s/ /\\\\ /g"
+}
+
+# Strip prefix from argument
+cmake_arg ()
+{
+ echo "$1" | sed "s/^${2-[^=]*=}//"
+}
+
+# Write message to the log
+cmake_log ()
+{
+ echo "$*" >> cmake_bootstrap.log
+}
+
+# Return temp file
+cmake_tmp_file ()
+{
+ echo "cmake_bootstrap_$$_test"
+}
+
+# Run a compiler test. First argument is compiler, second one are compiler
+# flags, third one is test source file to be compiled
+cmake_try_run ()
+{
+ COMPILER=$1
+ FLAGS=$2
+ TESTFILE=$3
+ if [ ! -f "${TESTFILE}" ]; then
+ echo "Test file ${TESTFILE} missing. Please verify your CMake source tree."
+ exit 4
+ fi
+ TMPFILE=`cmake_tmp_file`
+ echo "Try: ${COMPILER}"
+ echo "Line: ${COMPILER} ${FLAGS} ${TESTFILE} -o ${TMPFILE}"
+ echo "---------- file -----------------------"
+ cat "${TESTFILE}"
+ echo "------------------------------------------"
+ "${COMPILER}" ${FLAGS} "${TESTFILE}" -o "${TMPFILE}"
+ RES=$?
+ if [ "${RES}" -ne "0" ]; then
+ echo "Test failed to compile"
+ return 1
+ fi
+ if [ ! -f "${TMPFILE}" ] && [ ! -f "${TMPFILE}.exe" ]; then
+ echo "Test failed to produce executable"
+ return 2
+ fi
+ ./${TMPFILE}
+ RES=$?
+ rm -f "${TMPFILE}"
+ if [ "${RES}" -ne "0" ]; then
+ echo "Test produced non-zero return code"
+ return 3
+ fi
+ echo "Test succeded"
+ return 0
+}
+
+# Run a make test. First argument is the make interpreter.
+cmake_try_make ()
+{
+ MAKE_PROC="$1"
+ MAKE_FLAGS="$2"
+ echo "Try: ${MAKE_PROC}"
+ "${MAKE_PROC}" ${MAKE_FLAGS}
+ RES=$?
+ if [ "${RES}" -ne "0" ]; then
+ echo "${MAKE_PROC} does not work"
+ return 1
+ fi
+ if [ ! -f "test" ] && [ ! -f "test.exe" ]; then
+ echo "${COMPILER} does not produce output"
+ return 2
+ fi
+ ./test
+ RES=$?
+ rm -f "test"
+ if [ "${RES}" -ne "0" ]; then
+ echo "${MAKE_PROC} produces strange executable"
+ return 3
+ fi
+ echo "${MAKE_PROC} works"
+ return 0
+}
+
+# Parse arguments
+cmake_verbose=
+cmake_parallel_make=
+cmake_ccache_enabled=
+cmake_prefix_dir="${cmake_default_prefix}"
+while test $# != 0; do
+ case "$1" in
+ --prefix=*) dir=`cmake_arg "$1"`
+ cmake_prefix_dir=`cmake_fix_slashes "$dir"` ;;
+ --parallel=*) cmake_parallel_make=`cmake_arg "$1"` ;;
+ --datadir=*) cmake_data_dir=`cmake_arg "$1"` ;;
+ --docdir=*) cmake_doc_dir=`cmake_arg "$1"` ;;
+ --mandir=*) cmake_man_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)
+ 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)
+ 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"` ;;
+ --help) cmake_usage ;;
+ --version) cmake_version_display ; exit 2 ;;
+ --verbose) cmake_verbose=TRUE ;;
+ --enable-ccache) cmake_ccache_enabled=TRUE ;;
+ --) shift; break ;;
+ *) die "Unknown option: $1" ;;
+ esac
+ shift
+done
+
+# If verbose, display some information about bootstrap
+if [ -n "${cmake_verbose}" ]; then
+ echo "---------------------------------------------"
+ echo "Source directory: ${cmake_source_dir}"
+ echo "Binary directory: ${cmake_binary_dir}"
+ echo "Prefix directory: ${cmake_prefix_dir}"
+ echo "System: ${cmake_system}"
+ if [ "x${cmake_parallel_make}" != "x" ]; then
+ echo "Doing parallel make: ${cmake_parallel_make}"
+ fi
+ echo ""
+fi
+
+echo "---------------------------------------------"
+# Get CMake version
+echo "`cmake_version_display`"
+
+# Check for in-source build
+cmake_in_source_build=
+if [ -f "${cmake_binary_dir}/Source/cmake.cxx" -a \
+ -f "${cmake_binary_dir}/Source/cmake.h" ]; then
+ if [ -n "${cmake_verbose}" ]; then
+ echo "Warning: This is an in-source build"
+ fi
+ cmake_in_source_build=TRUE
+fi
+
+# If this is not an in-source build, then Bootstrap stuff should not exist.
+if [ -z "${cmake_in_source_build}" ]; then
+ # Did somebody bootstrap in the source tree?
+ if [ -d "${cmake_source_dir}/Bootstrap${_cmk}" ]; then
+ cmake_error 10 "Found directory \"${cmake_source_dir}/Bootstrap${_cmk}\".
+Looks like somebody did bootstrap CMake in the source tree, but now you are
+trying to do bootstrap in the binary tree. Please remove Bootstrap${_cmk}
+directory from the source tree."
+ fi
+ # Is there a cache in the source tree?
+ for cmake_problematic_file in ${CMAKE_PROBLEMATIC_FILES}; do
+ if [ -f "${cmake_source_dir}/${cmake_problematic_file}" ]; then
+ cmake_error 10 "Found \"${cmake_source_dir}/${cmake_problematic_file}\".
+Looks like somebody tried to build CMake in the source tree, but now you are
+trying to do bootstrap in the binary tree. Please remove \"${cmake_problematic_file}\"
+from the source tree."
+ fi
+ done
+fi
+
+# Make bootstrap directory
+[ -d "${cmake_bootstrap_dir}" ] || mkdir "${cmake_bootstrap_dir}"
+if [ ! -d "${cmake_bootstrap_dir}" ]; then
+ cmake_error 3 "Cannot create directory ${cmake_bootstrap_dir} to bootstrap CMake."
+fi
+cd "${cmake_bootstrap_dir}"
+
+[ -d "cmsys" ] || mkdir "cmsys"
+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}"
+rm -f "${cmake_bootstrap_dir}/cmVersionConfig.h${_tmp}"
+
+# If exist compiler flags, set them
+cmake_c_flags=${CFLAGS}
+cmake_cxx_flags=${CXXFLAGS}
+cmake_ld_flags=${LDFLAGS}
+
+# Add Cygwin-specific flags
+if ${cmake_system_cygwin}; then
+ cmake_ld_flags="${LDFLAGS} -Wl,--enable-auto-import"
+fi
+
+# Add CoreFoundation framework on Darwin
+if ${cmake_system_darwin}; then
+ cmake_ld_flags="${LDFLAGS} -framework CoreFoundation"
+fi
+
+# Add BeOS toolkits...
+if ${cmake_system_beos}; then
+ cmake_ld_flags="${LDFLAGS} -lroot -lbe"
+fi
+
+# Add Haiku toolkits...
+if ${cmake_system_haiku}; then
+ cmake_ld_flags="${LDFLAGS} -lroot -lbe"
+fi
+
+#-----------------------------------------------------------------------------
+# Detect known toolchains on some platforms.
+cmake_toolchains=''
+case "${cmake_system}" in
+ *AIX*) cmake_toolchains='XL GNU' ;;
+ *CYGWIN*) cmake_toolchains='GNU' ;;
+ *Darwin*) cmake_toolchains='GNU Clang' ;;
+ *Linux*) cmake_toolchains='GNU Clang XL PGI PathScale' ;;
+ *MINGW*) cmake_toolchains='GNU' ;;
+esac
+
+# Toolchain compiler name table.
+cmake_toolchain_Clang_CC='clang'
+cmake_toolchain_Clang_CXX='clang++'
+cmake_toolchain_GNU_CC='gcc'
+cmake_toolchain_GNU_CXX='g++'
+cmake_toolchain_PGI_CC='pgcc'
+cmake_toolchain_PGI_CXX='pgCC'
+cmake_toolchain_PathScale_CC='pathcc'
+cmake_toolchain_PathScale_CXX='pathCC'
+cmake_toolchain_XL_CC='xlc'
+cmake_toolchain_XL_CXX='xlC'
+
+cmake_toolchain_try()
+{
+ tc="$1"
+ TMPFILE=`cmake_tmp_file`
+
+ eval "tc_CC=\${cmake_toolchain_${tc}_CC}"
+ echo 'int main() { return 0; }' > "${TMPFILE}.c"
+ cmake_try_run "$tc_CC" "" "${TMPFILE}.c" >> cmake_bootstrap.log 2>&1
+ tc_result_CC="$?"
+ rm -f "${TMPFILE}.c"
+ test "${tc_result_CC}" = "0" || return 1
+
+ eval "tc_CXX=\${cmake_toolchain_${tc}_CXX}"
+ echo 'int main() { return 0; }' > "${TMPFILE}.cpp"
+ cmake_try_run "$tc_CXX" "" "${TMPFILE}.cpp" >> cmake_bootstrap.log 2>&1
+ tc_result_CXX="$?"
+ rm -f "${TMPFILE}.cpp"
+ test "${tc_result_CXX}" = "0" || return 1
+
+ cmake_toolchain="$tc"
+}
+
+cmake_toolchain_detect()
+{
+ cmake_toolchain=
+ for tc in ${cmake_toolchains}; do
+ echo "Checking for $tc toolchain" >> cmake_bootstrap.log 2>&1
+ cmake_toolchain_try "$tc" &&
+ echo "Found $tc toolchain" &&
+ break
+ done
+}
+
+if [ -z "${CC}" -a -z "${CXX}" ]; then
+ cmake_toolchain_detect
+fi
+
+#-----------------------------------------------------------------------------
+# Test C compiler
+cmake_c_compiler=
+
+# If CC is set, use that for compiler, otherwise use list of known compilers
+if [ -n "${cmake_toolchain}" ]; then
+ eval cmake_c_compilers="\${cmake_toolchain_${cmake_toolchain}_CC}"
+elif [ -n "${CC}" ]; then
+ cmake_c_compilers="${CC}"
+else
+ cmake_c_compilers="${CMAKE_KNOWN_C_COMPILERS}"
+fi
+
+# Check if C compiler works
+TMPFILE=`cmake_tmp_file`
+echo '
+#ifdef __cplusplus
+# error "The CMAKE_C_COMPILER is set to a C++ compiler"
+#endif
+
+#include<stdio.h>
+
+#if defined(__CLASSIC_C__)
+int main(argc, argv)
+ int argc;
+ char* argv[];
+#else
+int main(int argc, char* argv[])
+#endif
+{
+ printf("%d%c", (argv != 0), (char)0x0a);
+ return argc-1;
+}
+' > "${TMPFILE}.c"
+for a in ${cmake_c_compilers}; do
+ if [ -z "${cmake_c_compiler}" ] && \
+ cmake_try_run "${a}" "${cmake_c_flags}" "${TMPFILE}.c" >> cmake_bootstrap.log 2>&1; then
+ cmake_c_compiler="${a}"
+ fi
+done
+rm -f "${TMPFILE}.c"
+
+if [ -z "${cmake_c_compiler}" ]; then
+ cmake_error 6 "Cannot find appropriate C compiler on this system.
+Please specify one using environment variable CC.
+See cmake_bootstrap.log for compilers attempted.
+"
+fi
+echo "C compiler on this system is: ${cmake_c_compiler} ${cmake_c_flags}"
+
+#-----------------------------------------------------------------------------
+# Test CXX compiler
+cmake_cxx_compiler=
+
+# On Mac OSX, CC is the same as cc, so make sure not to try CC as c++ compiler.
+
+# If CC is set, use that for compiler, otherwise use list of known compilers
+if [ -n "${cmake_toolchain}" ]; then
+ eval cmake_cxx_compilers="\${cmake_toolchain_${cmake_toolchain}_CXX}"
+elif [ -n "${CXX}" ]; then
+ cmake_cxx_compilers="${CXX}"
+else
+ cmake_cxx_compilers="${CMAKE_KNOWN_CXX_COMPILERS}"
+fi
+
+# Check if C++ compiler works
+TMPFILE=`cmake_tmp_file`
+echo '
+#if defined(TEST1)
+# include <iostream>
+#else
+# include <iostream.h>
+#endif
+
+class NeedCXX
+{
+public:
+ NeedCXX() { this->Foo = 1; }
+ int GetFoo() { return this->Foo; }
+private:
+ int Foo;
+};
+int main()
+{
+ NeedCXX c;
+#ifdef TEST3
+ cout << c.GetFoo() << endl;
+#else
+ std::cout << c.GetFoo() << std::endl;
+#endif
+ return 0;
+}
+' > "${TMPFILE}.cxx"
+for a in ${cmake_cxx_compilers}; do
+ for b in 1 2 3; do
+ if [ -z "${cmake_cxx_compiler}" ] && \
+ cmake_try_run "${a}" "${cmake_cxx_flags} -DTEST${b}" "${TMPFILE}.cxx" >> cmake_bootstrap.log 2>&1; then
+ cmake_cxx_compiler="${a}"
+ fi
+ done
+done
+rm -f "${TMPFILE}.cxx"
+
+if [ -z "${cmake_cxx_compiler}" ]; then
+ cmake_error 7 "Cannot find appropriate C++ compiler on this system.
+Please specify one using environment variable CXX.
+See cmake_bootstrap.log for compilers attempted."
+fi
+echo "C++ compiler on this system is: ${cmake_cxx_compiler} ${cmake_cxx_flags}"
+
+#-----------------------------------------------------------------------------
+# Test Make
+
+cmake_make_processor=
+cmake_make_flags=
+
+# If MAKE is set, use that for make processor, otherwise use list of known make
+if [ -n "${MAKE}" ]; then
+ cmake_make_processors="${MAKE}"
+else
+ cmake_make_processors="${CMAKE_KNOWN_MAKE_PROCESSORS}"
+fi
+
+TMPFILE="`cmake_tmp_file`_dir"
+rm -rf "${cmake_bootstrap_dir}/${TMPFILE}"
+mkdir "${cmake_bootstrap_dir}/${TMPFILE}"
+cd "${cmake_bootstrap_dir}/${TMPFILE}"
+echo '
+test: test.c
+ "'"${cmake_c_compiler}"'" '"${cmake_ld_flags} ${cmake_c_flags}"' -o test test.c
+'>"Makefile"
+echo '
+#include <stdio.h>
+int main(){ printf("1%c", (char)0x0a); return 0; }
+' > "test.c"
+cmake_original_make_flags="${cmake_make_flags}"
+if [ "x${cmake_parallel_make}" != "x" ]; then
+ cmake_make_flags="${cmake_make_flags} -j ${cmake_parallel_make}"
+fi
+for a in ${cmake_make_processors}; do
+ if [ -z "${cmake_make_processor}" ] && cmake_try_make "${a}" "${cmake_make_flags}" >> ../cmake_bootstrap.log 2>&1; then
+ cmake_make_processor="${a}"
+ fi
+done
+cmake_full_make_flags="${cmake_make_flags}"
+if [ "x${cmake_original_make_flags}" != "x${cmake_make_flags}" ]; then
+ if [ -z "${cmake_make_processor}" ]; then
+ cmake_make_flags="${cmake_original_make_flags}"
+ for a in ${cmake_make_processors}; do
+ if [ -z "${cmake_make_processor}" ] && cmake_try_make "${a}" "${cmake_make_flags}" >> ../cmake_bootstrap.log 2>&1; then
+ cmake_make_processor="${a}"
+ fi
+ done
+ fi
+fi
+cd "${cmake_bootstrap_dir}"
+
+if [ -z "${cmake_make_processor}" ]; then
+ cmake_error 8 "Cannot find appropriate Makefile processor on this system.
+Please specify one using environment variable MAKE."
+fi
+rm -rf "${cmake_bootstrap_dir}/${TMPFILE}"
+echo "Makefile processor on this system is: ${cmake_make_processor}"
+if [ "x${cmake_full_make_flags}" != "x${cmake_make_flags}" ]; then
+ echo "---------------------------------------------"
+ echo "Makefile processor ${cmake_make_processor} does not support parallel build"
+ echo "---------------------------------------------"
+fi
+
+# Ok, we have CC, CXX, and MAKE.
+
+# Test C++ compiler features
+
+# Are we GCC?
+
+TMPFILE=`cmake_tmp_file`
+echo '
+#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
+#include <iostream>
+int main() { std::cout << "This is GNU" << std::endl; return 0;}
+#endif
+' > ${TMPFILE}.cxx
+cmake_cxx_compiler_is_gnu=0
+if cmake_try_run "${cmake_cxx_compiler}" \
+ "${cmake_cxx_flags}" "${TMPFILE}.cxx" >> cmake_bootstrap.log 2>&1; then
+ cmake_cxx_compiler_is_gnu=1
+fi
+if [ "x${cmake_cxx_compiler_is_gnu}" = "x1" ]; then
+ echo "${cmake_cxx_compiler} is GNU compiler"
+else
+ echo "${cmake_cxx_compiler} is not GNU compiler"
+fi
+rm -f "${TMPFILE}.cxx"
+
+if [ "x${cmake_cxx_compiler_is_gnu}" != "x1" ]; then
+ # Check for non-GNU compiler flags
+
+ # If we are on IRIX, check for -LANG:std
+ cmake_test_flags="-LANG:std"
+ if [ "x${cmake_system}" = "xIRIX64" ]; then
+ TMPFILE=`cmake_tmp_file`
+ echo '
+ #include <iostream>
+ int main() { std::cout << "No need for '"${cmake_test_flags}"'" << std::endl; return 0;}
+' > ${TMPFILE}.cxx
+ cmake_need_lang_std=0
+ 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_lang_std=1
+ fi
+ fi
+ if [ "x${cmake_need_lang_std}" = "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
+ rm -f "${TMPFILE}.cxx"
+ fi
+ cmake_test_flags=
+
+ # If we are on OSF, check for -timplicit_local -no_implicit_include
+ cmake_test_flags="-timplicit_local -no_implicit_include"
+ if [ "x${cmake_system}" = "xOSF1" ]; then
+ TMPFILE=`cmake_tmp_file`
+ echo '
+ #include <iostream>
+ int main() { std::cout << "We need '"${cmake_test_flags}"'" << std::endl; return 0;}
+' > ${TMPFILE}.cxx
+ cmake_need_flags=1
+ if cmake_try_run "${cmake_cxx_compiler}" \
+ "${cmake_cxx_flags} ${cmake_test_flags}" "${TMPFILE}.cxx" >> cmake_bootstrap.log 2>&1; then
+ :
+ else
+ cmake_need_flags=0
+ fi
+ if [ "x${cmake_need_flags}" = "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
+ rm -f "${TMPFILE}.cxx"
+ fi
+ cmake_test_flags=
+
+ # If we are on OSF, check for -std strict_ansi -nopure_cname
+ cmake_test_flags="-std strict_ansi -nopure_cname"
+ if [ "x${cmake_system}" = "xOSF1" ]; then
+ TMPFILE=`cmake_tmp_file`
+ echo '
+ #include <iostream>
+ int main() { std::cout << "We need '"${cmake_test_flags}"'" << std::endl; return 0;}
+' > ${TMPFILE}.cxx
+ cmake_need_flags=1
+ if cmake_try_run "${cmake_cxx_compiler}" \
+ "${cmake_cxx_flags} ${cmake_test_flags}" "${TMPFILE}.cxx" >> cmake_bootstrap.log 2>&1; then
+ :
+ else
+ cmake_need_flags=0
+ fi
+ if [ "x${cmake_need_flags}" = "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
+ rm -f "${TMPFILE}.cxx"
+ fi
+ 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
+ TMPFILE=`cmake_tmp_file`
+ echo '
+ int main(int argc, char** argv) { (void)argc; (void)argv; return 0; }
+' > ${TMPFILE}.c
+ cmake_need_Ae=0
+ if cmake_try_run "${cmake_c_compiler}" "${cmake_c_flags}" "${TMPFILE}.c" >> cmake_bootstrap.log 2>&1; then
+ :
+ else
+ if cmake_try_run "${cmake_c_compiler}" \
+ "${cmake_c_flags} ${cmake_test_flags}" "${TMPFILE}.c" >> cmake_bootstrap.log 2>&1; then
+ cmake_need_Ae=1
+ fi
+ fi
+ if [ "x${cmake_need_Ae}" = "x1" ]; then
+ cmake_c_flags="${cmake_c_flags} ${cmake_test_flags}"
+ echo "${cmake_c_compiler} needs ${cmake_test_flags}"
+ else
+ echo "${cmake_c_compiler} does not need ${cmake_test_flags}"
+ fi
+ rm -f "${TMPFILE}.c"
+ fi
+ cmake_test_flags=
+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_CXX_HAS_SETENV=0
+KWSYS_CXX_HAS_UNSETENV=0
+KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H=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" \
+ "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
+ KWSYS_CXX_HAS_SETENV=1
+ echo "${cmake_cxx_compiler} has setenv"
+else
+ echo "${cmake_cxx_compiler} does not have setenv"
+fi
+
+if cmake_try_run "${cmake_cxx_compiler}" \
+ "${cmake_cxx_flags} -DTEST_KWSYS_CXX_HAS_UNSETENV" \
+ "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
+ KWSYS_CXX_HAS_UNSETENV=1
+ echo "${cmake_cxx_compiler} has unsetenv"
+else
+ echo "${cmake_cxx_compiler} does not have unsetenv"
+fi
+
+if cmake_try_run "${cmake_cxx_compiler}" \
+ "${cmake_cxx_flags} -DTEST_KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H" \
+ "${cmake_source_dir}/Source/kwsys/kwsysPlatformTestsCXX.cxx" >> cmake_bootstrap.log 2>&1; then
+ KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H=1
+ echo "${cmake_cxx_compiler} has environ in stdlib.h"
+else
+ echo "${cmake_cxx_compiler} does not have environ in stdlib.h"
+fi
+
+if cmake_try_run "${cmake_cxx_compiler}" \
+ "${cmake_cxx_flags} -DTEST_KWSYS_STL_HAVE_STD" \
+ "${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"
+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"
+fi
+
+# Just to be safe, let us store compiler and flags to the header file
+
+cmake_bootstrap_version='$Revision$'
+cmake_compiler_settings_comment="/*
+ * Generated by ${cmake_source_dir}/bootstrap
+ * Version: ${cmake_bootstrap_version}
+ *
+ * Source directory: ${cmake_source_dir}
+ * Binary directory: ${cmake_bootstrap_dir}
+ *
+ * C compiler: ${cmake_c_compiler}
+ * C flags: ${cmake_c_flags}
+ *
+ * C++ compiler: ${cmake_cxx_compiler}
+ * C++ flags: ${cmake_cxx_flags}
+ *
+ * Make: ${cmake_make_processor}
+ *
+ * Sources:
+ * ${CMAKE_CXX_SOURCES} ${CMAKE_C_SOURCES}
+ * kwSys Sources:
+ * ${KWSYS_CXX_SOURCES} ${KWSYS_C_SOURCES} ${KWSYS_C_MINGW_SOURCES}
+ */
+"
+
+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`
+else
+ cmake_root_dir="${cmake_source_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"
+
+# Regenerate configured headers
+for h in Configure VersionConfig; do
+ if "${_diff}" cm${h}.h cm${h}.h${_tmp} > /dev/null 2> /dev/null; then
+ rm -f cm${h}.h${_tmp}
+ else
+ mv -f cm${h}.h${_tmp} cm${h}.h
+ fi
+done
+
+# Prepare KWSYS
+cmake_kwsys_config_replace_string \
+ "${cmake_source_dir}/Source/kwsys/Configure.hxx.in" \
+ "${cmake_bootstrap_dir}/cmsys/Configure.hxx" \
+ "${cmake_compiler_settings_comment}"
+cmake_kwsys_config_replace_string \
+ "${cmake_source_dir}/Source/kwsys/Configure.h.in" \
+ "${cmake_bootstrap_dir}/cmsys/Configure.h" \
+ "${cmake_compiler_settings_comment}"
+
+for a in ${KWSYS_FILES}; do
+ cmake_replace_string "${cmake_source_dir}/Source/kwsys/${a}.in" \
+ "${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
+
+# Generate Makefile
+dep="cmConfigure.h cmsys/*.hxx cmsys/*.h `cmake_escape \"${cmake_source_dir}\"`/Source/*.h"
+objs=""
+for a in ${CMAKE_CXX_SOURCES} ${CMAKE_C_SOURCES} ${KWSYS_CXX_SOURCES} ${KWSYS_C_SOURCES} ${KWSYS_C_GENERATED_SOURCES}; do
+ objs="${objs} ${a}.o"
+done
+
+# Generate dependencies for cmBootstrapCommands.cxx
+for file in `grep "#include.*cm[^.]*.cxx" "${cmake_source_dir}/Source/cmBootstrapCommands.cxx" | sed "s/.* \"\(.*\)\"/\1/"`; do
+ cmBootstrapCommandsDeps="${cmBootstrapCommandsDeps} `cmake_escape "${cmake_source_dir}/Source/$file"`"
+done
+cmBootstrapCommandsDeps=`echo $cmBootstrapCommandsDeps`
+
+if [ "x${cmake_ansi_cxx_flags}" != "x" ]; then
+ cmake_cxx_flags="${cmake_ansi_cxx_flags} ${cmake_cxx_flags}"
+fi
+
+if [ "x${cmake_c_flags}" != "x" ]; then
+ cmake_c_flags="${cmake_c_flags} "
+fi
+
+if [ "x${cmake_cxx_flags}" != "x" ]; then
+ cmake_cxx_flags="${cmake_cxx_flags} "
+fi
+
+cmake_c_flags_String="-DKWSYS_STRING_C"
+cmake_cxx_flags_SystemTools="-DKWSYS_CXX_HAS_SETENV=${KWSYS_CXX_HAS_SETENV} -DKWSYS_CXX_HAS_UNSETENV=${KWSYS_CXX_HAS_UNSETENV} -DKWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H=${KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H}"
+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}\"`"
+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}\"`"
+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
+ src=`cmake_escape "${cmake_source_dir}/Source/${a}.cxx"`
+ echo "${a}.o : ${src} ${dep}" >> "${cmake_bootstrap_dir}/Makefile"
+ echo " ${cmake_cxx_compiler} ${cmake_cxx_flags} -c ${src} -o ${a}.o" >> "${cmake_bootstrap_dir}/Makefile"
+done
+echo "cmBootstrapCommands.o : $cmBootstrapCommandsDeps" >> "${cmake_bootstrap_dir}/Makefile"
+for a in ${CMAKE_C_SOURCES}; do
+ src=`cmake_escape "${cmake_source_dir}/Source/${a}.c"`
+ echo "${a}.o : ${src} ${dep}" >> "${cmake_bootstrap_dir}/Makefile"
+ echo " ${cmake_c_compiler} ${cmake_c_flags} -c ${src} -o ${a}.o" >> "${cmake_bootstrap_dir}/Makefile"
+done
+for a in ${KWSYS_C_SOURCES} ${KWSYS_C_MINGW_SOURCES}; do
+ src=`cmake_escape "${cmake_source_dir}/Source/kwsys/${a}.c"`
+ src_flags=`eval echo \\${cmake_c_flags_\${a}}`
+ echo "${a}.o : ${src} ${dep}" >> "${cmake_bootstrap_dir}/Makefile"
+ echo " ${cmake_c_compiler} ${cmake_c_flags} -DKWSYS_NAMESPACE=cmsys ${src_flags} -c ${src} -o ${a}.o" >> "${cmake_bootstrap_dir}/Makefile"
+done
+for a in ${KWSYS_CXX_SOURCES}; do
+ src=`cmake_escape "${cmake_source_dir}/Source/kwsys/${a}.cxx"`
+ src_flags=`eval echo \\${cmake_cxx_flags_\${a}}`
+ echo "${a}.o : ${src} ${dep}" >> "${cmake_bootstrap_dir}/Makefile"
+ echo " ${cmake_cxx_compiler} ${cmake_cxx_flags} -DKWSYS_NAMESPACE=cmsys ${src_flags} -c ${src} -o ${a}.o" >> "${cmake_bootstrap_dir}/Makefile"
+done
+if ${cmake_system_mingw}; then
+ src=`cmake_escape "${cmake_bootstrap_dir}/cmsysProcessFwd9xEnc.c"`
+ in=`cmake_escape "${cmake_bootstrap_dir}/cmsysProcessFwd9x.exe"`
+ cmd=`cmake_escape "${cmake_bootstrap_dir}/cmsysEncodeExecutable.exe"`
+ a="cmsysProcessFwd9xEnc"
+ echo "${cmd} : EncodeExecutable.o" >> "${cmake_bootstrap_dir}/Makefile"
+ echo " ${cmake_c_compiler} ${cmake_ld_flags} ${cmake_c_flags} EncodeExecutable.o -o ${cmd}" >> "${cmake_bootstrap_dir}/Makefile"
+ echo "${in} : ProcessFwd9x.o" >> "${cmake_bootstrap_dir}/Makefile"
+ echo " ${cmake_c_compiler} ${cmake_ld_flags} ${cmake_c_flags} ProcessFwd9x.o -o ${in}" >> "${cmake_bootstrap_dir}/Makefile"
+ echo "${src} : ${cmd} ${in}" >> "${cmake_bootstrap_dir}/Makefile"
+ echo " ${cmd} ${in} ${src} cmsys ProcessFwd9x" >> "${cmake_bootstrap_dir}/Makefile"
+ echo "${a}.o : ${src} ${dep}" >> "${cmake_bootstrap_dir}/Makefile"
+ echo " ${cmake_c_compiler} ${cmake_c_flags} -I`cmake_escape \"${cmake_source_dir}/Source/kwsys\"` -DKWSYS_NAMESPACE=cmsys -c ${src} -o ${a}.o" >> "${cmake_bootstrap_dir}/Makefile"
+fi
+echo '
+rebuild_cache:
+ cd "${cmake_binary_dir}" && "${cmake_source_dir}/bootstrap"
+' >> "${cmake_bootstrap_dir}/Makefile"
+
+# Write our default settings to Bootstrap${_cmk}/InitialCacheFlags.cmake.
+echo '
+# Generated by '"${cmake_source_dir}"'/bootstrap
+# Default cmake settings. These may be overridden any settings below.
+SET (CMAKE_INSTALL_PREFIX "'"${cmake_prefix_dir}"'" CACHE PATH "Install path prefix, prepended onto install directories." FORCE)
+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)
+' > "${cmake_bootstrap_dir}/InitialCacheFlags.cmake"
+
+# Add configuration settings given as command-line options.
+if [ "x${cmake_bootstrap_qt_gui}" != "x" ]; then
+ echo '
+SET (BUILD_QtDialog '"${cmake_bootstrap_qt_gui}"' CACHE BOOL "Build Qt dialog for CMake" FORCE)
+' >> "${cmake_bootstrap_dir}/InitialCacheFlags.cmake"
+fi
+if [ "x${cmake_bootstrap_qt_qmake}" != "x" ]; then
+ echo '
+SET (QT_QMAKE_EXECUTABLE "'"${cmake_bootstrap_qt_qmake}"'" CACHE FILEPATH "Location of Qt qmake" FORCE)
+' >> "${cmake_bootstrap_dir}/InitialCacheFlags.cmake"
+fi
+
+# Add user-specified settings. Handle relative-path case for
+# specification of cmake_init_file.
+(
+cd "${cmake_binary_dir}"
+if [ -f "${cmake_init_file}" ]; then
+ cat "${cmake_init_file}" >> "${cmake_bootstrap_dir}/InitialCacheFlags.cmake"
+fi
+)
+
+echo "---------------------------------------------"
+
+# Run make to build bootstrap cmake
+if [ "x${cmake_parallel_make}" != "x" ]; then
+ ${cmake_make_processor} ${cmake_make_flags}
+else
+ ${cmake_make_processor}
+fi
+RES=$?
+if [ "${RES}" -ne "0" ]; then
+ cmake_error 9 "Problem while running ${cmake_make_processor}"
+fi
+cd "${cmake_binary_dir}"
+
+# Set C, CXX, and MAKE environment variables, so that real real cmake will be
+# build with same compiler and make
+CC="${cmake_c_compiler}"
+CXX="${cmake_cxx_compiler}"
+if [ -n "${cmake_ccache_enabled}" ]; then
+ CC="ccache ${CC}"
+ CXX="ccache ${CXX}"
+fi
+MAKE="${cmake_make_processor}"
+export CC
+export CXX
+export MAKE
+
+# Run bootstrap CMake to configure real CMake
+cmake_options="-DCMAKE_BOOTSTRAP=1"
+if [ -n "${cmake_verbose}" ]; then
+ cmake_options="${cmake_options} -DCMAKE_VERBOSE_MAKEFILE=1"
+fi
+"${cmake_bootstrap_dir}/cmake" "${cmake_source_dir}" "-C${cmake_bootstrap_dir}/InitialCacheFlags.cmake" "-G${cmake_bootstrap_generator}" ${cmake_options} ${cmake_bootstrap_system_libs} "$@"
+RES=$?
+if [ "${RES}" -ne "0" ]; then
+ cmake_error 11 "Problem while running initial CMake"
+fi
+
+echo "---------------------------------------------"
+
+# And we are done. Now just run make
+echo "CMake has bootstrapped. Now run ${cmake_make_processor}."
diff --git a/cmake_uninstall.cmake.in b/cmake_uninstall.cmake.in
new file mode 100644
index 000000000..03137d5af
--- /dev/null
+++ b/cmake_uninstall.cmake.in
@@ -0,0 +1,22 @@
+IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
+ MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"")
+ENDIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
+
+FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
+STRING(REGEX REPLACE "\n" ";" files "${files}")
+FOREACH(file ${files})
+ MESSAGE(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"")
+ IF(EXISTS "$ENV{DESTDIR}${file}")
+ EXEC_PROGRAM(
+ "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
+ OUTPUT_VARIABLE rm_out
+ RETURN_VALUE rm_retval
+ )
+ IF("${rm_retval}" STREQUAL 0)
+ ELSE("${rm_retval}" STREQUAL 0)
+ MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"")
+ ENDIF("${rm_retval}" STREQUAL 0)
+ ELSE(EXISTS "$ENV{DESTDIR}${file}")
+ MESSAGE(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.")
+ ENDIF(EXISTS "$ENV{DESTDIR}${file}")
+ENDFOREACH(file)
diff --git a/configure b/configure
new file mode 100755
index 000000000..116221602
--- /dev/null
+++ b/configure
@@ -0,0 +1,3 @@
+#!/bin/sh
+cmake_source_dir=`cd "\`dirname \"$0\"\`";pwd`
+exec "${cmake_source_dir}/bootstrap" "$@"
diff --git a/doxygen.config b/doxygen.config
new file mode 100644
index 000000000..c22f2650d
--- /dev/null
+++ b/doxygen.config
@@ -0,0 +1,697 @@
+# Doxyfile 1.1.4-20000625
+
+# This file describes the settings to be used by doxygen for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# General configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME = CMAKE
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER = 0.0.1
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = ./Doxygen
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Dutch, French, Italian, Czech, Swedish, German, Finnish, Japanese,
+# Spanish and Russian
+
+OUTPUT_LANGUAGE = English
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = YES
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSESS tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these class will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path.
+
+STRIP_FROM_PATH =
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a class diagram (in Html and LaTeX) for classes with base or
+# super classes. Setting the tag to NO turns the diagrams off.
+
+CLASS_DIAGRAMS = YES
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+
+SOURCE_BROWSER = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the CASE_SENSE_NAMES tag is set to NO (the default) then Doxygen
+# will only generate file names in lower case letters. If set to
+# YES upper case letters are also allowed. This is useful if you have
+# classes or files whose names only differ in case and if your file system
+# supports case sensitive file names.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = YES
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES (the default) then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the Javadoc-style will
+# behave just like the Qt-style comments.
+
+JAVADOC_AUTOBRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# reimplements.
+
+INHERIT_DOCS = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 8
+
+# The ENABLE_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text.
+
+WARN_FORMAT = "$file:$line: $text"
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT = "Source"
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+FILE_PATTERNS = *.h *.txx *.cxx
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE =
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+
+EXCLUDE_PATTERNS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS =
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output.
+
+INPUT_FILTER =
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 3
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet
+
+HTML_STYLESHEET =
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = YES
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# For now this is experimental and is disabled by default. The RTF output
+# is optimised for Word 97 and may not look too pretty with other readers
+# or editors.
+
+GENERATE_RTF = YES
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using a WORD or other.
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = YES
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed.
+
+MACRO_EXPANSION = YES
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = NO
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed.
+
+PREDEFINED = "itkNotUsed(x)="\
+ "itkSetMacro(name,type)= \
+ virtual void Set##name (type _arg);" \
+ "itkGetMacro(name,type)= \
+ virtual type Get##name ();" \
+ "itkGetConstMacro(name,type)= \
+ virtual type Get##name () const;" \
+ "itkSetStringMacro(name)= \
+ virtual void Set##name (const char* _arg);" \
+ "itkGetStringMacro(name)= \
+ virtual const char* Get##name () const;" \
+ "itkSetClampMacro(name,type,min,max)= \
+ virtual void Set##name (type _arg);" \
+ "itkSetObjectMacro(name,type)= \
+ virtual void Set##name (type* _arg);" \
+ "itkGetObjectMacro(name,type)= \
+ virtual type* Get##name ();" \
+ "itkBooleanMacro(name)= \
+ virtual void name##On (); \
+ virtual void name##Off ();" \
+ "itkSetVector2Macro(name,type)= \
+ virtual void Set##name (type _arg1, type _arg2) \
+ virtual void Set##name (type _arg[2]);" \
+ "itkGetVector2Macro(name,type)= \
+ virtual type* Get##name () const; \
+ virtual void Get##name (type& _arg1, type& _arg2) const; \
+ virtual void Get##name (type _arg[2]) const;" \
+ "itkSetVector3Macro(name,type)= \
+ virtual void Set##name (type _arg1, type _arg2, type _arg3) \
+ virtual void Set##name (type _arg[3]);" \
+ "itkGetVector3Macro(name,type)= \
+ virtual type* Get##name () const; \
+ virtual void Get##name (type& _arg1, type& _arg2, type& _arg3) const; \
+ virtual void Get##name (type _arg[3]) const;" \
+ "itkSetVector4Macro(name,type)= \
+ virtual void Set##name (type _arg1, type _arg2, type _arg3, type _arg4) \
+ virtual void Set##name (type _arg[4]);" \
+ "itkGetVector4Macro(name,type)= \
+ virtual type* Get##name () const; \
+ virtual void Get##name (type& _arg1, type& _arg2, type& _arg3, type& _arg4) const; \
+ virtual void Get##name (type _arg[4]) const;" \
+ "itkSetVector6Macro(name,type)= \
+ virtual void Set##name (type _arg1, type _arg2, type _arg3, type _arg4, type _arg5, type _arg6) \
+ virtual void Set##name (type _arg[6]);" \
+ "itkGetVector6Macro(name,type)= \
+ virtual type* Get##name () const; \
+ virtual void Get##name (type& _arg1, type& _arg2, type& _arg3, type& _arg4, type& _arg5, type& _arg6) const; \
+ virtual void Get##name (type _arg[6]) const;" \
+ "itkSetVectorMacro(name,type,count)= \
+ virtual void Set##name(type data[]);" \
+ "itkGetVectorMacro(name,type,count)= \
+ virtual type* Get##name () const;" \
+ "itkNewMacro(type)= \
+ static Pointer New();" \
+ "itkTypeMacro(thisClass,superclass)= \
+ virtual const char *GetClassName() const;" \
+ "ITK_NUMERIC_LIMITS= \
+ std::numeric_limits"
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED tag.
+
+EXPAND_ONLY_PREDEF = YES
+
+#---------------------------------------------------------------------------
+# Configuration::addtions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tagfiles.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = YES
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, INCLUDE_GRAPH, and HAVE_DOT tags are set to
+# YES then doxygen will generate a graph for each documented file showing
+# the direct and indirect include dependencies of the file with other
+# documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, INCLUDED_BY_GRAPH, and HAVE_DOT tags are set to
+# YES then doxygen will generate a graph for each documented header file showing
+# the documented files that directly or indirectly include this file
+
+INCLUDED_BY_GRAPH = YES
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found on the path.
+
+DOT_PATH =
+
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than
+# this value, doxygen will try to truncate the graph, so that it fits within
+# the specified constraint. Beware that most browsers cannot cope with very
+# large images.
+
+MAX_DOT_GRAPH_WIDTH = 1024
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than
+# this value, doxygen will try to truncate the graph, so that it fits within
+# the specified constraint. Beware that most browsers cannot cope with very
+# large images.
+
+MAX_DOT_GRAPH_HEIGHT = 1024
+
+#---------------------------------------------------------------------------
+# Configuration::addtions related to the search engine
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE = NO
+
+# The CGI_NAME tag should be the name of the CGI script that
+# starts the search engine (doxysearch) with the correct parameters.
+# A script with this name will be generated by doxygen.
+
+CGI_NAME = search.cgi
+
+# The CGI_URL tag should be the absolute URL to the directory where the
+# cgi binaries are located. See the documentation of your http daemon for
+# details.
+
+CGI_URL =
+
+# The DOC_URL tag should be the absolute URL to the directory where the
+# documentation is located. If left blank the absolute path to the
+# documentation, with file:// prepended to it, will be used.
+
+DOC_URL =
+
+# The DOC_ABSPATH tag should be the absolute path to the directory where the
+# documentation is located. If left blank the directory on the local machine
+# will be used.
+
+DOC_ABSPATH =
+
+# The BIN_ABSPATH tag must point to the directory where the doxysearch binary
+# is installed.
+
+BIN_ABSPATH = /usr/local/bin/
+
+# The EXT_DOC_PATHS tag can be used to specify one or more paths to
+# documentation generated for other projects. This allows doxysearch to search
+# the documentation for these projects as well.
+
+EXT_DOC_PATHS =